ZGlmZiAtLWdpdCBhLy5naXRhdHRyaWJ1dGVzIGIvLmdpdGF0dHJpYnV0ZXMKaW5kZXggMTFiNjU4OC4uYzc3MmMzMiAxMDA2NDQKLS0tIGEvLmdpdGF0dHJpYnV0ZXMKKysrIGIvLmdpdGF0dHJpYnV0ZXMKQEAgLTEsMiArMSwyNiBAQAorIyBGb3JjZSBMRiBjaGVja291dCBmb3IgYWxsIHNvdXJjZSBmaWxlcworKi5iaW4gYmluYXJ5CisqLmMgdGV4dCBlb2w9bGYKKyouY2MgdGV4dCBlb2w9bGYKKyouY3BwIHRleHQgZW9sPWxmCisqLmduIHRleHQgZW9sPWxmCisqLmduaSB0ZXh0IGVvbD1sZgorKi5oIHRleHQgZW9sPWxmCisqLmluIHRleHQgZW9sPWxmCisqLmpzIHRleHQgZW9sPWxmCisqLm1kIHRleHQgZW9sPWxmCisqLm1tIHRleHQgZW9sPWxmCisqLnNoIHRleHQgZW9sPWxmCisqLnR4dCB0ZXh0IGVvbD1sZgorKi54bWwgdGV4dCBlb2w9bGYKKy5jbGFuZy1mb3JtYXQgdGV4dCBlb2w9bGYKKy5naXRhdHRyaWJ1dGVzIHRleHQgZW9sPWxmCisuZ2l0aWdub3JlIHRleHQgZW9sPWxmCisudnB5dGhvbiB0ZXh0IGVvbD1sZgorY29kZXJldmlldy5zZXR0aW5ncyB0ZXh0IGVvbD1sZgorREVQUyB0ZXh0IGVvbD1sZgorTElDRU5TRSB0ZXh0IGVvbD1sZgorT1dORVJTIHRleHQgZW9sPWxmCisKICMgU2tpcCBUcmljaXVtIG9uIGV4cGVjdGF0aW9uIGZpbGVzLgogKl9leHBlY3RlZC50eHQgLXRyaWNpdW0KZGlmZiAtLWdpdCBhL3Rlc3RpbmcvcmVzb3VyY2VzL2J1Z180NTk1ODAuaW4gYi90ZXN0aW5nL3Jlc291cmNlcy9idWdfNDU5NTgwLmluCmluZGV4IGYyMGMxNDEuLjNjNDM2M2YgMTAwNjQ0Ci0tLSBhL3Rlc3RpbmcvcmVzb3VyY2VzL2J1Z180NTk1ODAuaW4KKysrIGIvdGVzdGluZy9yZXNvdXJjZXMvYnVnXzQ1OTU4MC5pbgpAQCAtMSw0NyArMSw0NyBAQAote3toZWFkZXJ9fQ0KLXt7b2JqZWN0IDEgMH19IDw8DQotICAvVHlwZSAvQ2F0YWxvZw0KLSAgL1BhZ2VzIDIgMCBSDQotPj4NCi17e29iamVjdCAyIDB9fSA8PA0KLSAgL1R5cGUgL1BhZ2VzDQotICAvTWVkaWFCb3ggWyAwIDAgNjAwIDYwMCBdDQotICAvQ291bnQgMQ0KLSAgL0tpZHMgWyAzIDAgUiBdDQotPj4NCi1lbmRvYmoNCi17e29iamVjdCAzIDB9fSA8PA0KLSAgL1R5cGUgL1BhZ2UNCi0gIC9QYXJlbnQgMiAwIFINCi0gIC9SZXNvdXJjZXMgPDwNCi0gICAgL0ZvbnQgPDwNCi0gICAgICAvRjEgNCAwIFINCi0gICAgPj4NCi0gID4+DQotICAvQ29udGVudHMgNiAwIFINCi0+Pg0KLWVuZG9iag0KLXt7b2JqZWN0IDQgMH19IDw8DQotICAvVHlwZSAvRm9udA0KLSAgL1N1YnR5cGUgL1R5cGUxDQotICAvQmFzZUZvbnQgL1RpbWVzLVJvbWFuDQotPj4NCi1lbmRvYmoNCi0NCi17e29iamVjdCA2IDB9fSA8PA0KLT4+DQotc3RyZWFtDQotQlQNCi0vRjEgMTIgVGYNCi0yMDAgNTAwIFRkDQotKEhlbGxvLCB3b3JsZCEgVGhpcyBpcyBhIHRlc3QgcGRmIGZvciBidWcgNDU5NTgwLikgVGoNCi1FVA0KLWVuZHN0cmVhbQ0KLWVuZG9iag0KLXt7eHJlZn19DQotdHJhaWxlciA8PA0KLSAgLyQkemUgNg0KLSAgL1Jvb3QgMSAwIFINCi0+Pg0KLXt7c3RhcnR4cmVmfX0NCi0lJUVPRg0KK3t7aGVhZGVyfX0KK3t7b2JqZWN0IDEgMH19IDw8CisgIC9UeXBlIC9DYXRhbG9nCisgIC9QYWdlcyAyIDAgUgorPj4KK3t7b2JqZWN0IDIgMH19IDw8CisgIC9UeXBlIC9QYWdlcworICAvTWVkaWFCb3ggWyAwIDAgNjAwIDYwMCBdCisgIC9Db3VudCAxCisgIC9LaWRzIFsgMyAwIFIgXQorPj4KK2VuZG9iagore3tvYmplY3QgMyAwfX0gPDwKKyAgL1R5cGUgL1BhZ2UKKyAgL1BhcmVudCAyIDAgUgorICAvUmVzb3VyY2VzIDw8CisgICAgL0ZvbnQgPDwKKyAgICAgIC9GMSA0IDAgUgorICAgID4+CisgID4+CisgIC9Db250ZW50cyA2IDAgUgorPj4KK2VuZG9iagore3tvYmplY3QgNCAwfX0gPDwKKyAgL1R5cGUgL0ZvbnQKKyAgL1N1YnR5cGUgL1R5cGUxCisgIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KKz4+CitlbmRvYmoKKwore3tvYmplY3QgNiAwfX0gPDwKKz4+CitzdHJlYW0KK0JUCisvRjEgMTIgVGYKKzIwMCA1MDAgVGQKKyhIZWxsbywgd29ybGQhIFRoaXMgaXMgYSB0ZXN0IHBkZiBmb3IgYnVnIDQ1OTU4MC4pIFRqCitFVAorZW5kc3RyZWFtCitlbmRvYmoKK3t7eHJlZn19Cit0cmFpbGVyIDw8CisgIC8kJHplIDYKKyAgL1Jvb3QgMSAwIFIKKz4+Cit7e3N0YXJ0eHJlZn19CislJUVPRgpkaWZmIC0tZ2l0IGEvdGVzdGluZy9yZXNvdXJjZXMvYnVnXzQ1OTU4MC5wZGYgYi90ZXN0aW5nL3Jlc291cmNlcy9idWdfNDU5NTgwLnBkZgppbmRleCBhZjMzZWZjLi42NmE1NjQxIDEwMDY0NAotLS0gYS90ZXN0aW5nL3Jlc291cmNlcy9idWdfNDU5NTgwLnBkZgorKysgYi90ZXN0aW5nL3Jlc291cmNlcy9idWdfNDU5NTgwLnBkZgpAQCAtMSw1NyArMSw1NyBAQAotJVBERi0xLjcNCi0loPKk9A0KLTEgMCBvYmogPDwNCi0gIC9UeXBlIC9DYXRhbG9nDQotICAvUGFnZXMgMiAwIFINCi0+Pg0KLTIgMCBvYmogPDwNCi0gIC9UeXBlIC9QYWdlcw0KLSAgL01lZGlhQm94IFsgMCAwIDYwMCA2MDAgXQ0KLSAgL0NvdW50IDENCi0gIC9LaWRzIFsgMyAwIFIgXQ0KLT4+DQotZW5kb2JqDQotMyAwIG9iaiA8PA0KLSAgL1R5cGUgL1BhZ2UNCi0gIC9QYXJlbnQgMiAwIFINCi0gIC9SZXNvdXJjZXMgPDwNCi0gICAgL0ZvbnQgPDwNCi0gICAgICAvRjEgNCAwIFINCi0gICAgPj4NCi0gID4+DQotICAvQ29udGVudHMgNiAwIFINCi0+Pg0KLWVuZG9iag0KLTQgMCBvYmogPDwNCi0gIC9UeXBlIC9Gb250DQotICAvU3VidHlwZSAvVHlwZTENCi0gIC9CYXNlRm9udCAvVGltZXMtUm9tYW4NCi0+Pg0KLWVuZG9iag0KLQ0KLTYgMCBvYmogPDwNCi0+Pg0KLXN0cmVhbQ0KLUJUDQotL0YxIDEyIFRmDQotMjAwIDUwMCBUZA0KLShIZWxsbywgd29ybGQhIFRoaXMgaXMgYSB0ZXN0IHBkZiBmb3IgYnVnIDQ1OTU4MC4pIFRqDQotRVQNCi1lbmRzdHJlYW0NCi1lbmRvYmoNCi14cmVmDQotMCA3DQotMDAwMDAwMDAwMCA2NTUzNSBmIA0KLTAwMDAwMDAwMTUgMDAwMDAgbiANCi0wMDAwMDAwMDYxIDAwMDAwIG4gDQotMDAwMDAwMDE1NCAwMDAwMCBuIA0KLTAwMDAwMDAzNzQgMDAwMDAgbiANCi0wMDAwMDAwMDAwIDY1NTM1IGYgDQotMDAwMDAwMDQ1MCAwMDAwMCBuIA0KLXRyYWlsZXIgPDwNCi0gIC8kJHplIDYNCi0gIC9Sb290IDEgMCBSDQotPj4NCi1zdGFydHhyZWYNCi05NjMNCi0lJUVPRg0KKyVQREYtMS43CisloPKk9AorMSAwIG9iaiA8PAorICAvVHlwZSAvQ2F0YWxvZworICAvUGFnZXMgMiAwIFIKKz4+CisyIDAgb2JqIDw8CisgIC9UeXBlIC9QYWdlcworICAvTWVkaWFCb3ggWyAwIDAgNjAwIDYwMCBdCisgIC9Db3VudCAxCisgIC9LaWRzIFsgMyAwIFIgXQorPj4KK2VuZG9iagorMyAwIG9iaiA8PAorICAvVHlwZSAvUGFnZQorICAvUGFyZW50IDIgMCBSCisgIC9SZXNvdXJjZXMgPDwKKyAgICAvRm9udCA8PAorICAgICAgL0YxIDQgMCBSCisgICAgPj4KKyAgPj4KKyAgL0NvbnRlbnRzIDYgMCBSCis+PgorZW5kb2JqCis0IDAgb2JqIDw8CisgIC9UeXBlIC9Gb250CisgIC9TdWJ0eXBlIC9UeXBlMQorICAvQmFzZUZvbnQgL1RpbWVzLVJvbWFuCis+PgorZW5kb2JqCisKKzYgMCBvYmogPDwKKz4+CitzdHJlYW0KK0JUCisvRjEgMTIgVGYKKzIwMCA1MDAgVGQKKyhIZWxsbywgd29ybGQhIFRoaXMgaXMgYSB0ZXN0IHBkZiBmb3IgYnVnIDQ1OTU4MC4pIFRqCitFVAorZW5kc3RyZWFtCitlbmRvYmoKK3hyZWYKKzAgNworMDAwMDAwMDAwMCA2NTUzNSBmIAorMDAwMDAwMDAxNSAwMDAwMCBuIAorMDAwMDAwMDA2MSAwMDAwMCBuIAorMDAwMDAwMDE1NCAwMDAwMCBuIAorMDAwMDAwMDI4MCAwMDAwMCBuIAorMDAwMDAwMDAwMCA2NTUzNSBmIAorMDAwMDAwMDM1OSAwMDAwMCBuIAordHJhaWxlciA8PAorICAvJCR6ZSA2CisgIC9Sb290IDEgMCBSCis+Pgorc3RhcnR4cmVmCis0NzgKKyUlRU9GCmRpZmYgLS1naXQgYS90aGlyZF9wYXJ0eS9iYXNlL3dpbi93aW5fdXRpbC5jYyBiL3RoaXJkX3BhcnR5L2Jhc2Uvd2luL3dpbl91dGlsLmNjCmluZGV4IDljOTBiOWQuLmFlMmRiYTggMTAwNjQ0Ci0tLSBhL3RoaXJkX3BhcnR5L2Jhc2Uvd2luL3dpbl91dGlsLmNjCisrKyBiL3RoaXJkX3BhcnR5L2Jhc2Uvd2luL3dpbl91dGlsLmNjCkBAIC0xLDQxICsxLDQxIEBACi0vLyBDb3B5cmlnaHQgMjAxOSBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0NCi0jaW5jbHVkZSAidGhpcmRfcGFydHkvYmFzZS93aW4vd2luX3V0aWwuaCINCi0NCi0jaW5jbHVkZSA8d2luZG93cy5oPg0KLSNpbmNsdWRlIDxwcm9jZXNzdGhyZWFkc2FwaS5oPg0KLQ0KLW5hbWVzcGFjZSBwZGZpdW0gew0KLW5hbWVzcGFjZSBiYXNlIHsNCi1uYW1lc3BhY2Ugd2luIHsNCi0NCi1ib29sIElzVXNlcjMyQW5kR2RpMzJBdmFpbGFibGUoKSB7DQotICBzdGF0aWMgYXV0byBpc191c2VyMzJfYW5kX2dkaTMyX2F2YWlsYWJsZSA9IFtdKCkgew0KLSAgICAvLyBJZiB3aW4zMmsgc3lzY2FsbHMgYXJlbid0IGRpc2FibGVkLCB0aGVuIHVzZXIzMiBhbmQgZ2RpMzIgYXJlIGF2YWlsYWJsZS4NCi0NCi0gICAgdHlwZWRlZiBkZWNsdHlwZSgNCi0gICAgICAgIEdldFByb2Nlc3NNaXRpZ2F0aW9uUG9saWN5KSogR2V0UHJvY2Vzc01pdGlnYXRpb25Qb2xpY3lUeXBlOw0KLSAgICBHZXRQcm9jZXNzTWl0aWdhdGlvblBvbGljeVR5cGUgZ2V0X3Byb2Nlc3NfbWl0aWdhdGlvbl9wb2xpY3lfZnVuYyA9DQotICAgICAgICByZWludGVycHJldF9jYXN0PEdldFByb2Nlc3NNaXRpZ2F0aW9uUG9saWN5VHlwZT4oR2V0UHJvY0FkZHJlc3MoDQotICAgICAgICAgICAgR2V0TW9kdWxlSGFuZGxlKEwia2VybmVsMzIuZGxsIiksICJHZXRQcm9jZXNzTWl0aWdhdGlvblBvbGljeSIpKTsNCi0NCi0gICAgaWYgKCFnZXRfcHJvY2Vzc19taXRpZ2F0aW9uX3BvbGljeV9mdW5jKQ0KLSAgICAgIHJldHVybiB0cnVlOw0KLQ0KLSAgICBQUk9DRVNTX01JVElHQVRJT05fU1lTVEVNX0NBTExfRElTQUJMRV9QT0xJQ1kgcG9saWN5ID0ge307DQotICAgIGlmIChnZXRfcHJvY2Vzc19taXRpZ2F0aW9uX3BvbGljeV9mdW5jKEdldEN1cnJlbnRQcm9jZXNzKCksDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByb2Nlc3NTeXN0ZW1DYWxsRGlzYWJsZVBvbGljeSwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBvbGljeSwgc2l6ZW9mKHBvbGljeSkpKSB7DQotICAgICAgcmV0dXJuIHBvbGljeS5EaXNhbGxvd1dpbjMya1N5c3RlbUNhbGxzID09IDA7DQotICAgIH0NCi0NCi0gICAgcmV0dXJuIHRydWU7DQotICB9KCk7DQotICByZXR1cm4gaXNfdXNlcjMyX2FuZF9nZGkzMl9hdmFpbGFibGU7DQotfQ0KLQ0KLX0gIC8vIG5hbWVzcGFjZSB3aW4NCi19ICAvLyBuYW1lc3BhY2UgYmFzZQ0KLX0gIC8vIG5hbWVzcGFjZSBwZGZpdW0NCisvLyBDb3B5cmlnaHQgMjAxOSBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisKKyNpbmNsdWRlICJ0aGlyZF9wYXJ0eS9iYXNlL3dpbi93aW5fdXRpbC5oIgorCisjaW5jbHVkZSA8d2luZG93cy5oPgorI2luY2x1ZGUgPHByb2Nlc3N0aHJlYWRzYXBpLmg+CisKK25hbWVzcGFjZSBwZGZpdW0geworbmFtZXNwYWNlIGJhc2UgeworbmFtZXNwYWNlIHdpbiB7CisKK2Jvb2wgSXNVc2VyMzJBbmRHZGkzMkF2YWlsYWJsZSgpIHsKKyAgc3RhdGljIGF1dG8gaXNfdXNlcjMyX2FuZF9nZGkzMl9hdmFpbGFibGUgPSBbXSgpIHsKKyAgICAvLyBJZiB3aW4zMmsgc3lzY2FsbHMgYXJlbid0IGRpc2FibGVkLCB0aGVuIHVzZXIzMiBhbmQgZ2RpMzIgYXJlIGF2YWlsYWJsZS4KKworICAgIHR5cGVkZWYgZGVjbHR5cGUoCisgICAgICAgIEdldFByb2Nlc3NNaXRpZ2F0aW9uUG9saWN5KSogR2V0UHJvY2Vzc01pdGlnYXRpb25Qb2xpY3lUeXBlOworICAgIEdldFByb2Nlc3NNaXRpZ2F0aW9uUG9saWN5VHlwZSBnZXRfcHJvY2Vzc19taXRpZ2F0aW9uX3BvbGljeV9mdW5jID0KKyAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxHZXRQcm9jZXNzTWl0aWdhdGlvblBvbGljeVR5cGU+KEdldFByb2NBZGRyZXNzKAorICAgICAgICAgICAgR2V0TW9kdWxlSGFuZGxlKEwia2VybmVsMzIuZGxsIiksICJHZXRQcm9jZXNzTWl0aWdhdGlvblBvbGljeSIpKTsKKworICAgIGlmICghZ2V0X3Byb2Nlc3NfbWl0aWdhdGlvbl9wb2xpY3lfZnVuYykKKyAgICAgIHJldHVybiB0cnVlOworCisgICAgUFJPQ0VTU19NSVRJR0FUSU9OX1NZU1RFTV9DQUxMX0RJU0FCTEVfUE9MSUNZIHBvbGljeSA9IHt9OworICAgIGlmIChnZXRfcHJvY2Vzc19taXRpZ2F0aW9uX3BvbGljeV9mdW5jKEdldEN1cnJlbnRQcm9jZXNzKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvY2Vzc1N5c3RlbUNhbGxEaXNhYmxlUG9saWN5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwb2xpY3ksIHNpemVvZihwb2xpY3kpKSkgeworICAgICAgcmV0dXJuIHBvbGljeS5EaXNhbGxvd1dpbjMya1N5c3RlbUNhbGxzID09IDA7CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7CisgIH0oKTsKKyAgcmV0dXJuIGlzX3VzZXIzMl9hbmRfZ2RpMzJfYXZhaWxhYmxlOworfQorCit9ICAvLyBuYW1lc3BhY2Ugd2luCit9ICAvLyBuYW1lc3BhY2UgYmFzZQorfSAgLy8gbmFtZXNwYWNlIHBkZml1bQpkaWZmIC0tZ2l0IGEvdGhpcmRfcGFydHkvYmFzZS93aW4vd2luX3V0aWwuaCBiL3RoaXJkX3BhcnR5L2Jhc2Uvd2luL3dpbl91dGlsLmgKaW5kZXggYTVjNjAyNy4uYjI3ZjJmMSAxMDA2NDQKLS0tIGEvdGhpcmRfcGFydHkvYmFzZS93aW4vd2luX3V0aWwuaAorKysgYi90aGlyZF9wYXJ0eS9iYXNlL3dpbi93aW5fdXRpbC5oCkBAIC0xLDIzICsxLDIzIEBACi0vLyBDb3B5cmlnaHQgMjAxOSBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0NCi0jaWZuZGVmIFRISVJEX1BBUlRZX0JBU0VfV0lOX1dJTl9VVElMX0hfDQotI2RlZmluZSBUSElSRF9QQVJUWV9CQVNFX1dJTl9XSU5fVVRJTF9IXw0KLQ0KLW5hbWVzcGFjZSBwZGZpdW0gew0KLW5hbWVzcGFjZSBiYXNlIHsNCi1uYW1lc3BhY2Ugd2luIHsNCi0NCi0vLyBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnJlbnQgcHJvY2VzcyBjYW4gbWFrZSBVU0VSMzIgb3IgR0RJMzIgY2FsbHMgc3VjaCBhcw0KLS8vIENyZWF0ZVdpbmRvdyBhbmQgQ3JlYXRlREMuIFdpbmRvd3MgOCBhbmQgYWJvdmUgYWxsb3cgdGhlIGtlcm5lbCBjb21wb25lbnQNCi0vLyBvZiB0aGVzZSBjYWxscyB0byBiZSBkaXNhYmxlZCB3aGljaCBjYW4gY2F1c2UgdW5kZWZpbmVkIGJlaGF2aW91ciBzdWNoIGFzDQotLy8gY3Jhc2hlcy4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBndWFyZCBhcmVhcyBvZiBjb2RlIHVzaW5nIHRoZXNlIGNhbGxzDQotLy8gYW5kIHByb3ZpZGUgYSBmYWxsYmFjayBwYXRoIGlmIG5lY2Vzc2FyeS4NCi1ib29sIElzVXNlcjMyQW5kR2RpMzJBdmFpbGFibGUoKTsNCi0NCi19ICAvLyBuYW1lc3BhY2Ugd2luDQotfSAgLy8gbmFtZXNwYWNlIGJhc2UNCi19ICAvLyBuYW1lc3BhY2UgcGRmaXVtDQotDQotI2VuZGlmICAvLyBUSElSRF9QQVJUWV9CQVNFX1dJTl9XSU5fVVRJTF9IXw0KKy8vIENvcHlyaWdodCAyMDE5IFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKworI2lmbmRlZiBUSElSRF9QQVJUWV9CQVNFX1dJTl9XSU5fVVRJTF9IXworI2RlZmluZSBUSElSRF9QQVJUWV9CQVNFX1dJTl9XSU5fVVRJTF9IXworCituYW1lc3BhY2UgcGRmaXVtIHsKK25hbWVzcGFjZSBiYXNlIHsKK25hbWVzcGFjZSB3aW4geworCisvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnJlbnQgcHJvY2VzcyBjYW4gbWFrZSBVU0VSMzIgb3IgR0RJMzIgY2FsbHMgc3VjaCBhcworLy8gQ3JlYXRlV2luZG93IGFuZCBDcmVhdGVEQy4gV2luZG93cyA4IGFuZCBhYm92ZSBhbGxvdyB0aGUga2VybmVsIGNvbXBvbmVudAorLy8gb2YgdGhlc2UgY2FsbHMgdG8gYmUgZGlzYWJsZWQgd2hpY2ggY2FuIGNhdXNlIHVuZGVmaW5lZCBiZWhhdmlvdXIgc3VjaCBhcworLy8gY3Jhc2hlcy4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBndWFyZCBhcmVhcyBvZiBjb2RlIHVzaW5nIHRoZXNlIGNhbGxzCisvLyBhbmQgcHJvdmlkZSBhIGZhbGxiYWNrIHBhdGggaWYgbmVjZXNzYXJ5LgorYm9vbCBJc1VzZXIzMkFuZEdkaTMyQXZhaWxhYmxlKCk7CisKK30gIC8vIG5hbWVzcGFjZSB3aW4KK30gIC8vIG5hbWVzcGFjZSBiYXNlCit9ICAvLyBuYW1lc3BhY2UgcGRmaXVtCisKKyNlbmRpZiAgLy8gVEhJUkRfUEFSVFlfQkFTRV9XSU5fV0lOX1VUSUxfSF8KZGlmZiAtLWdpdCBhL3RoaXJkX3BhcnR5L2xjbXMvc3JjL2Ntc2dtdC5jIGIvdGhpcmRfcGFydHkvbGNtcy9zcmMvY21zZ210LmMKaW5kZXggNWQ3YTMyMC4uMDI3ZjIwMSAxMDA2NDQKLS0tIGEvdGhpcmRfcGFydHkvbGNtcy9zcmMvY21zZ210LmMKKysrIGIvdGhpcmRfcGFydHkvbGNtcy9zcmMvY21zZ210LmMKQEAgLTEsNTkwICsxLDU5MCBAQAotLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCi0vLw0KLS8vICBMaXR0bGUgQ29sb3IgTWFuYWdlbWVudCBTeXN0ZW0NCi0vLyAgQ29weXJpZ2h0IChjKSAxOTk4LTIwMTcgTWFydGkgTWFyaWEgU2FndWVyDQotLy8NCi0vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcNCi0vLyBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksDQotLy8gdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbg0KLS8vIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLA0KLS8vIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZQ0KLS8vIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6DQotLy8NCi0vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbg0KLS8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLg0KLS8vDQotLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsDQotLy8gRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPDQotLy8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQNCi0vLyBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFDQotLy8gTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTg0KLS8vIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTg0KLS8vIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLg0KLS8vDQotLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCi0vLw0KLQ0KLSNpbmNsdWRlICJsY21zMl9pbnRlcm5hbC5oIg0KLQ0KLQ0KLS8vIEF1eGlsaWFyeTogYXBwZW5kIGEgTGFiIGlkZW50aXR5IGFmdGVyIHRoZSBnaXZlbiBzZXF1ZW5jZSBvZiBwcm9maWxlcw0KLS8vIGFuZCByZXR1cm4gdGhlIHRyYW5zZm9ybS4gTGFiIHByb2ZpbGUgaXMgY2xvc2VkLCByZXN0IG9mIHByb2ZpbGVzIGFyZSBrZXB0IG9wZW4uDQotY21zSFRSQU5TRk9STSBfY21zQ2hhaW4yTGFiKGNtc0NvbnRleHQgICAgICAgICAgICBDb250ZXh0SUQsDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciAgICAgICAgblByb2ZpbGVzLA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgICAgICAgIElucHV0Rm9ybWF0LA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgICAgICAgIE91dHB1dEZvcm1hdCwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY21zVUludDMyTnVtYmVyICBJbnRlbnRzW10sDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNtc0hQUk9GSUxFICAgICAgaFByb2ZpbGVzW10sDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNtc0Jvb2wgICAgICAgICAgQlBDW10sDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNtc0Zsb2F0NjROdW1iZXIgQWRhcHRhdGlvblN0YXRlc1tdLA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgICAgICAgIGR3RmxhZ3MpDQotew0KLSAgICBjbXNIVFJBTlNGT1JNIHhmb3JtOw0KLSAgICBjbXNIUFJPRklMRSAgIGhMYWI7DQotICAgIGNtc0hQUk9GSUxFICAgUHJvZmlsZUxpc3RbMjU2XTsNCi0gICAgY21zQm9vbCAgICAgICBCUENMaXN0WzI1Nl07DQotICAgIGNtc0Zsb2F0NjROdW1iZXIgQWRhcHRhdGlvbkxpc3RbMjU2XTsNCi0gICAgY21zVUludDMyTnVtYmVyIEludGVudExpc3RbMjU2XTsNCi0gICAgY21zVUludDMyTnVtYmVyIGk7DQotDQotICAgIC8vIFRoaXMgaXMgYSByYXRoZXIgYmlnIG51bWJlciBhbmQgdGhlcmUgaXMgbm8gbmVlZCBvZiBkeW5hbWljIG1lbW9yeQ0KLSAgICAvLyBzaW5jZSB3ZSBhcmUgYWRkaW5nIGEgcHJvZmlsZSwgMjU0ICsgMSA9IDI1NSBhbmQgdGhpcyBpcyB0aGUgbGltaXQNCi0gICAgaWYgKG5Qcm9maWxlcyA+IDI1NCkgcmV0dXJuIE5VTEw7DQotDQotICAgIC8vIFRoZSBvdXRwdXQgc3BhY2UNCi0gICAgaExhYiA9IGNtc0NyZWF0ZUxhYjRQcm9maWxlVEhSKENvbnRleHRJRCwgTlVMTCk7DQotICAgIGlmIChoTGFiID09IE5VTEwpIHJldHVybiBOVUxMOw0KLQ0KLSAgICAvLyBDcmVhdGUgYSBjb3B5IG9mIHBhcmFtZXRlcnMNCi0gICAgZm9yIChpPTA7IGkgPCBuUHJvZmlsZXM7IGkrKykgew0KLQ0KLSAgICAgICAgUHJvZmlsZUxpc3RbaV0gICAgPSBoUHJvZmlsZXNbaV07DQotICAgICAgICBCUENMaXN0W2ldICAgICAgICA9IEJQQ1tpXTsNCi0gICAgICAgIEFkYXB0YXRpb25MaXN0W2ldID0gQWRhcHRhdGlvblN0YXRlc1tpXTsNCi0gICAgICAgIEludGVudExpc3RbaV0gICAgID0gSW50ZW50c1tpXTsNCi0gICAgfQ0KLQ0KLSAgICAvLyBQbGFjZSBMYWIgaWRlbnRpdHkgYXQgY2hhaW4ncyBlbmQuDQotICAgIFByb2ZpbGVMaXN0W25Qcm9maWxlc10gICAgPSBoTGFiOw0KLSAgICBCUENMaXN0W25Qcm9maWxlc10gICAgICAgID0gMDsNCi0gICAgQWRhcHRhdGlvbkxpc3RbblByb2ZpbGVzXSA9IDEuMDsNCi0gICAgSW50ZW50TGlzdFtuUHJvZmlsZXNdICAgICA9IElOVEVOVF9SRUxBVElWRV9DT0xPUklNRVRSSUM7DQotDQotICAgIC8vIENyZWF0ZSB0aGUgdHJhbnNmb3JtDQotICAgIHhmb3JtID0gY21zQ3JlYXRlRXh0ZW5kZWRUcmFuc2Zvcm0oQ29udGV4dElELCBuUHJvZmlsZXMgKyAxLCBQcm9maWxlTGlzdCwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCUENMaXN0LA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVudExpc3QsDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWRhcHRhdGlvbkxpc3QsDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgMCwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnB1dEZvcm1hdCwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPdXRwdXRGb3JtYXQsDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdGbGFncyk7DQotDQotICAgIGNtc0Nsb3NlUHJvZmlsZShoTGFiKTsNCi0NCi0gICAgcmV0dXJuIHhmb3JtOw0KLX0NCi0NCi0NCi0vLyBDb21wdXRlIEsgLT4gTCogcmVsYXRpb25zaGlwLiBGbGFncyBtYXkgaW5jbHVkZSBibGFjayBwb2ludCBjb21wZW5zYXRpb24uIEluIHRoaXMgY2FzZSwNCi0vLyB0aGUgcmVsYXRpb25zaGlwIGlzIGFzc3VtZWQgZnJvbSB0aGUgcHJvZmlsZSB3aXRoIEJQQyB0byBhIGJsYWNrIHBvaW50IHplcm8uDQotc3RhdGljDQotY21zVG9uZUN1cnZlKiBDb21wdXRlS1RvTHN0YXIoY21zQ29udGV4dCAgICAgICAgICAgIENvbnRleHRJRCwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyICAgICAgIG5Qb2ludHMsDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciAgICAgICBuUHJvZmlsZXMsDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNtc1VJbnQzMk51bWJlciBJbnRlbnRzW10sDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNtc0hQUk9GSUxFICAgICBoUHJvZmlsZXNbXSwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY21zQm9vbCAgICAgICAgIEJQQ1tdLA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjbXNGbG9hdDY0TnVtYmVyIEFkYXB0YXRpb25TdGF0ZXNbXSwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIGR3RmxhZ3MpDQotew0KLSAgICBjbXNUb25lQ3VydmUqIG91dCA9IE5VTEw7DQotICAgIGNtc1VJbnQzMk51bWJlciBpOw0KLSAgICBjbXNIVFJBTlNGT1JNIHhmb3JtOw0KLSAgICBjbXNDSUVMYWIgTGFiOw0KLSAgICBjbXNGbG9hdDMyTnVtYmVyIGNteWtbNF07DQotICAgIGNtc0Zsb2F0MzJOdW1iZXIqIFNhbXBsZWRQb2ludHM7DQotDQotICAgIHhmb3JtID0gX2Ntc0NoYWluMkxhYihDb250ZXh0SUQsIG5Qcm9maWxlcywgVFlQRV9DTVlLX0ZMVCwgVFlQRV9MYWJfREJMLCBJbnRlbnRzLCBoUHJvZmlsZXMsIEJQQywgQWRhcHRhdGlvblN0YXRlcywgZHdGbGFncyk7DQotICAgIGlmICh4Zm9ybSA9PSBOVUxMKSByZXR1cm4gTlVMTDsNCi0NCi0gICAgU2FtcGxlZFBvaW50cyA9IChjbXNGbG9hdDMyTnVtYmVyKikgX2Ntc0NhbGxvYyhDb250ZXh0SUQsIG5Qb2ludHMsIHNpemVvZihjbXNGbG9hdDMyTnVtYmVyKSk7DQotICAgIGlmIChTYW1wbGVkUG9pbnRzICA9PSBOVUxMKSBnb3RvIEVycm9yOw0KLQ0KLSAgICBmb3IgKGk9MDsgaSA8IG5Qb2ludHM7IGkrKykgew0KLQ0KLSAgICAgICAgY215a1swXSA9IDA7DQotICAgICAgICBjbXlrWzFdID0gMDsNCi0gICAgICAgIGNteWtbMl0gPSAwOw0KLSAgICAgICAgY215a1szXSA9IChjbXNGbG9hdDMyTnVtYmVyKSAoKGkgKiAxMDAuMCkgLyAoblBvaW50cy0xKSk7DQotDQotICAgICAgICBjbXNEb1RyYW5zZm9ybSh4Zm9ybSwgY215aywgJkxhYiwgMSk7DQotICAgICAgICBTYW1wbGVkUG9pbnRzW2ldPSAoY21zRmxvYXQzMk51bWJlcikgKDEuMCAtIExhYi5MIC8gMTAwLjApOyAvLyBOZWdhdGUgSyBmb3IgZWFzaWVyIG9wZXJhdGlvbg0KLSAgICB9DQotDQotICAgIG91dCA9IGNtc0J1aWxkVGFidWxhdGVkVG9uZUN1cnZlRmxvYXQoQ29udGV4dElELCBuUG9pbnRzLCBTYW1wbGVkUG9pbnRzKTsNCi0NCi1FcnJvcjoNCi0NCi0gICAgY21zRGVsZXRlVHJhbnNmb3JtKHhmb3JtKTsNCi0gICAgaWYgKFNhbXBsZWRQb2ludHMpIF9jbXNGcmVlKENvbnRleHRJRCwgU2FtcGxlZFBvaW50cyk7DQotDQotICAgIHJldHVybiBvdXQ7DQotfQ0KLQ0KLQ0KLS8vIENvbXB1dGUgQmxhY2sgdG9uZSBjdXJ2ZSBvbiBhIENNWUsgLT4gQ01ZSyB0cmFuc2Zvcm0uIFRoaXMgaXMgZG9uZSBieQ0KLS8vIHVzaW5nIHRoZSBwcm9vZiBkaXJlY3Rpb24gb24gYm90aCBwcm9maWxlcyB0byBmaW5kIEstPkwqIHJlbGF0aW9uc2hpcA0KLS8vIHRoZW4gam9pbmluZyBib3RoIGN1cnZlcy4gZHdGbGFncyBtYXkgaW5jbHVkZSBibGFjayBwb2ludCBjb21wZW5zYXRpb24uDQotY21zVG9uZUN1cnZlKiBfY21zQnVpbGRLVG9uZUN1cnZlKGNtc0NvbnRleHQgICAgICAgIENvbnRleHRJRCwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciAgIG5Qb2ludHMsDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgICBuUHJvZmlsZXMsDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjbXNVSW50MzJOdW1iZXIgSW50ZW50c1tdLA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY21zSFBST0ZJTEUgaFByb2ZpbGVzW10sDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjbXNCb29sICAgICBCUENbXSwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNtc0Zsb2F0NjROdW1iZXIgQWRhcHRhdGlvblN0YXRlc1tdLA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyICAgZHdGbGFncykNCi17DQotICAgIGNtc1RvbmVDdXJ2ZSAqaW4sICpvdXQsICpLVG9uZTsNCi0NCi0gICAgLy8gTWFrZSBzdXJlIENNWUsgLT4gQ01ZSw0KLSAgICBpZiAoY21zR2V0Q29sb3JTcGFjZShoUHJvZmlsZXNbMF0pICE9IGNtc1NpZ0NteWtEYXRhIHx8DQotICAgICAgICBjbXNHZXRDb2xvclNwYWNlKGhQcm9maWxlc1tuUHJvZmlsZXMtMV0pIT0gY21zU2lnQ215a0RhdGEpIHJldHVybiBOVUxMOw0KLQ0KLQ0KLSAgICAvLyBNYWtlIHN1cmUgbGFzdCBpcyBhbiBvdXRwdXQgcHJvZmlsZQ0KLSAgICBpZiAoY21zR2V0RGV2aWNlQ2xhc3MoaFByb2ZpbGVzW25Qcm9maWxlcyAtIDFdKSAhPSBjbXNTaWdPdXRwdXRDbGFzcykgcmV0dXJuIE5VTEw7DQotDQotICAgIC8vIENyZWF0ZSBpbmRpdmlkdWFsIGN1cnZlcy4gQlBDIHdvcmtzIGFsc28gYXMgZWFjaCBLIHRvIEwqIGlzDQotICAgIC8vIGNvbXB1dGVkIGFzIGEgQlBDIHRvIHplcm8gYmxhY2sgcG9pbnQgaW4gY2FzZSBvZiBMKg0KLSAgICBpbiAgPSBDb21wdXRlS1RvTHN0YXIoQ29udGV4dElELCBuUG9pbnRzLCBuUHJvZmlsZXMgLSAxLCBJbnRlbnRzLCBoUHJvZmlsZXMsIEJQQywgQWRhcHRhdGlvblN0YXRlcywgZHdGbGFncyk7DQotICAgIGlmIChpbiA9PSBOVUxMKSByZXR1cm4gTlVMTDsNCi0NCi0gICAgb3V0ID0gQ29tcHV0ZUtUb0xzdGFyKENvbnRleHRJRCwgblBvaW50cywgMSwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZW50cyArIChuUHJvZmlsZXMgLSAxKSwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgJmhQcm9maWxlcyBbblByb2ZpbGVzIC0gMV0sDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJQQyArIChuUHJvZmlsZXMgLSAxKSwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQWRhcHRhdGlvblN0YXRlcyArIChuUHJvZmlsZXMgLSAxKSwNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdGbGFncyk7DQotICAgIGlmIChvdXQgPT0gTlVMTCkgew0KLSAgICAgICAgY21zRnJlZVRvbmVDdXJ2ZShpbik7DQotICAgICAgICByZXR1cm4gTlVMTDsNCi0gICAgfQ0KLQ0KLSAgICAvLyBCdWlsZCB0aGUgcmVsYXRpb25zaGlwLiBUaGlzIGVmZmVjdGl2ZWx5IGxpbWl0cyB0aGUgbWF4aW11bSBhY2N1cmFjeSB0byAxNiBiaXRzLCBidXQNCi0gICAgLy8gc2luY2UgdGhpcyBpcyB1c2VkIG9uIGJsYWNrLXByZXNlcnZpbmcgTFVUcywgd2UgYXJlIG5vdCBsb3NpbmcgIGFjY3VyYWN5IGluIGFueSBjYXNlDQotICAgIEtUb25lID0gY21zSm9pblRvbmVDdXJ2ZShDb250ZXh0SUQsIGluLCBvdXQsIG5Qb2ludHMpOw0KLQ0KLSAgICAvLyBHZXQgcmlkIG9mIGNvbXBvbmVudHMNCi0gICAgY21zRnJlZVRvbmVDdXJ2ZShpbik7IGNtc0ZyZWVUb25lQ3VydmUob3V0KTsNCi0NCi0gICAgLy8gU29tZXRoaW5nIHdlbnQgd3JvbmcuLi4NCi0gICAgaWYgKEtUb25lID09IE5VTEwpIHJldHVybiBOVUxMOw0KLQ0KLSAgICAvLyBNYWtlIHN1cmUgaXQgaXMgbW9ub3RvbmljDQotICAgIGlmICghY21zSXNUb25lQ3VydmVNb25vdG9uaWMoS1RvbmUpKSB7DQotICAgICAgICBjbXNGcmVlVG9uZUN1cnZlKEtUb25lKTsNCi0gICAgICAgIHJldHVybiBOVUxMOw0KLSAgICB9DQotDQotICAgIHJldHVybiBLVG9uZTsNCi19DQotDQotDQotLy8gR2FtdXQgTFVUIENyZWF0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQotDQotLy8gVXNlZCBieSBnYW11dCAmIHNvZnRwcm9vZmluZw0KLQ0KLXR5cGVkZWYgc3RydWN0IHsNCi0NCi0gICAgY21zSFRSQU5TRk9STSBoSW5wdXQ7ICAgICAgICAgICAgICAgLy8gRnJvbSB3aGF0ZXZlciBpbnB1dCBjb2xvciBzcGFjZS4gMTYgYml0cyB0byBEQkwNCi0gICAgY21zSFRSQU5TRk9STSBoRm9yd2FyZCwgaFJldmVyc2U7ICAgLy8gVHJhbnNmb3JtcyBnb2luZyBmcm9tIExhYiB0byBjb2xvcmFudCBhbmQgYmFjaw0KLSAgICBjbXNGbG9hdDY0TnVtYmVyIFRoZXJlc2hvbGQ7ICAgICAgICAvLyBUaGUgdGhlcmVzaG9sZCBhZnRlciB3aGljaCBpcyBjb25zaWRlcmVkIG91dCBvZiBnYW11dA0KLQ0KLSAgICB9IEdBTVVUQ0hBSU47DQotDQotLy8gVGhpcyBzYW1wbGVyIGRvZXMgY29tcHV0ZSBnYW11dCBib3VuZGFyaWVzIGJ5IGNvbXBhcmluZyBvcmlnaW5hbA0KLS8vIHZhbHVlcyB3aXRoIGEgdHJhbnNmb3JtIGdvaW5nIGJhY2sgYW5kIGZvcnRoLiBWYWx1ZXMgYWJvdmUgRVJSX1RIRVJFU0hPTEQNCi0vLyBvZiBtYXhpbXVtIGFyZSBjb25zaWRlcmVkIG91dCBvZiBnYW11dC4NCi0NCi0jZGVmaW5lIEVSUl9USEVSRVNIT0xEICAgICAgNQ0KLQ0KLQ0KLXN0YXRpYw0KLWludCBHYW11dFNhbXBsZXIocmVnaXN0ZXIgY29uc3QgY21zVUludDE2TnVtYmVyIEluW10sIHJlZ2lzdGVyIGNtc1VJbnQxNk51bWJlciBPdXRbXSwgcmVnaXN0ZXIgdm9pZCogQ2FyZ28pDQotew0KLSAgICBHQU1VVENIQUlOKiAgdCA9IChHQU1VVENIQUlOKiApIENhcmdvOw0KLSAgICBjbXNDSUVMYWIgTGFiSW4xLCBMYWJPdXQxOw0KLSAgICBjbXNDSUVMYWIgTGFiSW4yLCBMYWJPdXQyOw0KLSAgICBjbXNVSW50MTZOdW1iZXIgUHJvb2ZbY21zTUFYQ0hBTk5FTFNdLCBQcm9vZjJbY21zTUFYQ0hBTk5FTFNdOw0KLSAgICBjbXNGbG9hdDY0TnVtYmVyIGRFMSwgZEUyLCBFcnJvclJhdGlvOw0KLQ0KLSAgICAvLyBBc3N1bWUgaW4tZ2FtdXQgYnkgZGVmYXVsdC4NCi0gICAgRXJyb3JSYXRpbyA9IDEuMDsNCi0NCi0gICAgLy8gQ29udmVydCBpbnB1dCB0byBMYWINCi0gICAgY21zRG9UcmFuc2Zvcm0odCAtPiBoSW5wdXQsIEluLCAmTGFiSW4xLCAxKTsNCi0NCi0gICAgLy8gY29udmVydHMgZnJvbSBQQ1MgdG8gY29sb3JhbnQuIFRoaXMgYWx3YXlzDQotICAgIC8vIGRvZXMgcmV0dXJuIGluLWdhbXV0IHZhbHVlcywNCi0gICAgY21zRG9UcmFuc2Zvcm0odCAtPiBoRm9yd2FyZCwgJkxhYkluMSwgUHJvb2YsIDEpOw0KLQ0KLSAgICAvLyBOb3csIGRvIHRoZSBpbnZlcnNlLCBmcm9tIGNvbG9yYW50IHRvIFBDUy4NCi0gICAgY21zRG9UcmFuc2Zvcm0odCAtPiBoUmV2ZXJzZSwgUHJvb2YsICZMYWJPdXQxLCAxKTsNCi0NCi0gICAgbWVtbW92ZSgmTGFiSW4yLCAmTGFiT3V0MSwgc2l6ZW9mKGNtc0NJRUxhYikpOw0KLQ0KLSAgICAvLyBUcnkgYWdhaW4sIGJ1dCB0aGlzIHRpbWUgdGFraW5nIENoZWNrIGFzIGlucHV0DQotICAgIGNtc0RvVHJhbnNmb3JtKHQgLT4gaEZvcndhcmQsICZMYWJPdXQxLCBQcm9vZjIsIDEpOw0KLSAgICBjbXNEb1RyYW5zZm9ybSh0IC0+IGhSZXZlcnNlLCBQcm9vZjIsICZMYWJPdXQyLCAxKTsNCi0NCi0gICAgLy8gVGFrZSBkaWZmZXJlbmNlIG9mIGRpcmVjdCB2YWx1ZQ0KLSAgICBkRTEgPSBjbXNEZWx0YUUoJkxhYkluMSwgJkxhYk91dDEpOw0KLQ0KLSAgICAvLyBUYWtlIGRpZmZlcmVuY2Ugb2YgY29udmVydGVkIHZhbHVlDQotICAgIGRFMiA9IGNtc0RlbHRhRSgmTGFiSW4yLCAmTGFiT3V0Mik7DQotDQotDQotICAgIC8vIGlmIGRFMSBpcyBzbWFsbCBhbmQgZEUyIGlzIHNtYWxsLCB2YWx1ZSBpcyBsaWtlbHkgdG8gYmUgaW4gZ2FtdXQNCi0gICAgaWYgKGRFMSA8IHQtPlRoZXJlc2hvbGQgJiYgZEUyIDwgdC0+VGhlcmVzaG9sZCkNCi0gICAgICAgIE91dFswXSA9IDA7DQotICAgIGVsc2Ugew0KLQ0KLSAgICAgICAgLy8gaWYgZEUxIGlzIHNtYWxsIGFuZCBkRTIgaXMgYmlnLCB1bmRlZmluZWQuIEFzc3VtZSBpbiBnYW11dA0KLSAgICAgICAgaWYgKGRFMSA8IHQtPlRoZXJlc2hvbGQgJiYgZEUyID4gdC0+VGhlcmVzaG9sZCkNCi0gICAgICAgICAgICBPdXRbMF0gPSAwOw0KLSAgICAgICAgZWxzZQ0KLSAgICAgICAgICAgIC8vIGRFMSBpcyBiaWcgYW5kIGRFMiBpcyBzbWFsbCwgY2xlYXJseSBvdXQgb2YgZ2FtdXQNCi0gICAgICAgICAgICBpZiAoZEUxID4gdC0+VGhlcmVzaG9sZCAmJiBkRTIgPCB0LT5UaGVyZXNob2xkKQ0KLSAgICAgICAgICAgICAgICBPdXRbMF0gPSAoY21zVUludDE2TnVtYmVyKSBfY21zUXVpY2tGbG9vcigoZEUxIC0gdC0+VGhlcmVzaG9sZCkgKyAuNSk7DQotICAgICAgICAgICAgZWxzZSAgew0KLQ0KLSAgICAgICAgICAgICAgICAvLyBkRTEgaXMgYmlnIGFuZCBkRTIgaXMgYWxzbyBiaWcsIGNvdWxkIGJlIGR1ZSB0byBwZXJjZXB0dWFsIG1hcHBpbmcNCi0gICAgICAgICAgICAgICAgLy8gc28gdGFrZSBlcnJvciByYXRpbw0KLSAgICAgICAgICAgICAgICBpZiAoZEUyID09IDAuMCkNCi0gICAgICAgICAgICAgICAgICAgIEVycm9yUmF0aW8gPSBkRTE7DQotICAgICAgICAgICAgICAgIGVsc2UNCi0gICAgICAgICAgICAgICAgICAgIEVycm9yUmF0aW8gPSBkRTEgLyBkRTI7DQotDQotICAgICAgICAgICAgICAgIGlmIChFcnJvclJhdGlvID4gdC0+VGhlcmVzaG9sZCkNCi0gICAgICAgICAgICAgICAgICAgIE91dFswXSA9IChjbXNVSW50MTZOdW1iZXIpICBfY21zUXVpY2tGbG9vcigoRXJyb3JSYXRpbyAtIHQtPlRoZXJlc2hvbGQpICsgLjUpOw0KLSAgICAgICAgICAgICAgICBlbHNlDQotICAgICAgICAgICAgICAgICAgICBPdXRbMF0gPSAwOw0KLSAgICAgICAgICAgIH0NCi0gICAgfQ0KLQ0KLQ0KLSAgICByZXR1cm4gVFJVRTsNCi19DQotDQotLy8gRG9lcyBjb21wdXRlIGEgZ2FtdXQgTFVUIGdvaW5nIGJhY2sgYW5kIGZvcnRoIGFjcm9zcyBwY3MgLT4gcmVsYXRpdi4gY29sb3JpbWV0cmljIGludGVudCAtPiBwY3MNCi0vLyB0aGUgZEUgb2J0YWluZWQgaXMgdGhlbiBhbm5vdGF0ZWQgb24gdGhlIExVVC4gVmFsdWVzIHRydWx5IG91dCBvZiBnYW11dCBhcmUgY2xpcHBlZCB0byBkRSA9IDB4RkZGRQ0KLS8vIGFuZCB2YWx1ZXMgY2hhbmdlZCBhcmUgc3VwcG9zZWQgdG8gYmUgaGFuZGxlZCBieSBhbnkgZ2FtdXQgcmVtYXBwaW5nLCBzbywgYXJlIG91dCBvZiBnYW11dCBhcyB3ZWxsLg0KLS8vDQotLy8gKipXQVJOSU5HOiBUaGlzIGFsZ29yaXRobSBkb2VzIGFzc3VtZSB0aGF0IGdhbXV0IHJlbWFwcGluZyBhbGdvcml0aG1zIGRvZXMgTk9UIG1vdmUgaW4tZ2FtdXQgY29sb3JzLA0KLS8vIG9mIGNvdXJzZSwgbWFueSBwZXJjZXB0dWFsIGFuZCBzYXR1cmF0aW9uIGludGVudHMgZG9lcyBub3Qgd29yayBpbiBzdWNoIHdheSwgYnV0IHJlbGF0aXYuIG9uZXMgc2hvdWxkLg0KLQ0KLWNtc1BpcGVsaW5lKiBfY21zQ3JlYXRlR2FtdXRDaGVja1BpcGVsaW5lKGNtc0NvbnRleHQgQ29udGV4dElELA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc0hQUk9GSUxFIGhQcm9maWxlc1tdLA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc0Jvb2wgIEJQQ1tdLA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBJbnRlbnRzW10sDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zRmxvYXQ2NE51bWJlciBBZGFwdGF0aW9uU3RhdGVzW10sDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIG5HYW11dFBDU3Bvc2l0aW9uLA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc0hQUk9GSUxFIGhHYW11dCkNCi17DQotICAgIGNtc0hQUk9GSUxFIGhMYWI7DQotICAgIGNtc1BpcGVsaW5lKiBHYW11dDsNCi0gICAgY21zU3RhZ2UqIENMVVQ7DQotICAgIGNtc1VJbnQzMk51bWJlciBkd0Zvcm1hdDsNCi0gICAgR0FNVVRDSEFJTiBDaGFpbjsNCi0gICAgY21zVUludDMyTnVtYmVyIG5DaGFubmVscywgbkdyaWRwb2ludHM7DQotICAgIGNtc0NvbG9yU3BhY2VTaWduYXR1cmUgQ29sb3JTcGFjZTsNCi0gICAgY21zVUludDMyTnVtYmVyIGk7DQotICAgIGNtc0hQUk9GSUxFIFByb2ZpbGVMaXN0WzI1Nl07DQotICAgIGNtc0Jvb2wgICAgIEJQQ0xpc3RbMjU2XTsNCi0gICAgY21zRmxvYXQ2NE51bWJlciBBZGFwdGF0aW9uTGlzdFsyNTZdOw0KLSAgICBjbXNVSW50MzJOdW1iZXIgSW50ZW50TGlzdFsyNTZdOw0KLQ0KLSAgICBtZW1zZXQoJkNoYWluLCAwLCBzaXplb2YoR0FNVVRDSEFJTikpOw0KLQ0KLQ0KLSAgICBpZiAobkdhbXV0UENTcG9zaXRpb24gPD0gMCB8fCBuR2FtdXRQQ1Nwb3NpdGlvbiA+IDI1NSkgew0KLSAgICAgICAgY21zU2lnbmFsRXJyb3IoQ29udGV4dElELCBjbXNFUlJPUl9SQU5HRSwgIldyb25nIHBvc2l0aW9uIG9mIFBDUy4gMS4uMjU1IGV4cGVjdGVkLCAlZCBmb3VuZC4iLCBuR2FtdXRQQ1Nwb3NpdGlvbik7DQotICAgICAgICByZXR1cm4gTlVMTDsNCi0gICAgfQ0KLQ0KLSAgICBoTGFiID0gY21zQ3JlYXRlTGFiNFByb2ZpbGVUSFIoQ29udGV4dElELCBOVUxMKTsNCi0gICAgaWYgKGhMYWIgPT0gTlVMTCkgcmV0dXJuIE5VTEw7DQotDQotDQotICAgIC8vIFRoZSBmaWd1cmUgb2YgbWVyaXQuIE9uIG1hdHJpeC1zaGFwZXIgcHJvZmlsZXMsIHNob3VsZCBiZSBhbG1vc3QgemVybyBhcw0KLSAgICAvLyB0aGUgY29udmVyc2lvbiBpcyBwcmV0dHkgZXhhY3QuIE9uIExVVCBiYXNlZCBwcm9maWxlcywgZGlmZmVyZW50IHJlc29sdXRpb25zDQotICAgIC8vIG9mIGlucHV0IGFuZCBvdXRwdXQgQ0xVVCBtYXkgcmVzdWx0IGluIGRpZmZlcmVuY2VzLg0KLQ0KLSAgICBpZiAoY21zSXNNYXRyaXhTaGFwZXIoaEdhbXV0KSkgew0KLQ0KLSAgICAgICAgQ2hhaW4uVGhlcmVzaG9sZCA9IDEuMDsNCi0gICAgfQ0KLSAgICBlbHNlIHsNCi0gICAgICAgIENoYWluLlRoZXJlc2hvbGQgPSBFUlJfVEhFUkVTSE9MRDsNCi0gICAgfQ0KLQ0KLQ0KLSAgICAvLyBDcmVhdGUgYSBjb3B5IG9mIHBhcmFtZXRlcnMNCi0gICAgZm9yIChpPTA7IGkgPCBuR2FtdXRQQ1Nwb3NpdGlvbjsgaSsrKSB7DQotICAgICAgICBQcm9maWxlTGlzdFtpXSAgICA9IGhQcm9maWxlc1tpXTsNCi0gICAgICAgIEJQQ0xpc3RbaV0gICAgICAgID0gQlBDW2ldOw0KLSAgICAgICAgQWRhcHRhdGlvbkxpc3RbaV0gPSBBZGFwdGF0aW9uU3RhdGVzW2ldOw0KLSAgICAgICAgSW50ZW50TGlzdFtpXSAgICAgPSBJbnRlbnRzW2ldOw0KLSAgICB9DQotDQotICAgIC8vIEZpbGwgTGFiIGlkZW50aXR5DQotICAgIFByb2ZpbGVMaXN0W25HYW11dFBDU3Bvc2l0aW9uXSA9IGhMYWI7DQotICAgIEJQQ0xpc3RbbkdhbXV0UENTcG9zaXRpb25dID0gMDsNCi0gICAgQWRhcHRhdGlvbkxpc3RbbkdhbXV0UENTcG9zaXRpb25dID0gMS4wOw0KLSAgICBJbnRlbnRMaXN0W25HYW11dFBDU3Bvc2l0aW9uXSA9IElOVEVOVF9SRUxBVElWRV9DT0xPUklNRVRSSUM7DQotDQotDQotICAgIENvbG9yU3BhY2UgID0gY21zR2V0Q29sb3JTcGFjZShoR2FtdXQpOw0KLQ0KLSAgICBuQ2hhbm5lbHMgICA9IGNtc0NoYW5uZWxzT2YoQ29sb3JTcGFjZSk7DQotICAgIG5HcmlkcG9pbnRzID0gX2Ntc1JlYXNvbmFibGVHcmlkcG9pbnRzQnlDb2xvcnNwYWNlKENvbG9yU3BhY2UsIGNtc0ZMQUdTX0hJR0hSRVNQUkVDQUxDKTsNCi0gICAgZHdGb3JtYXQgICAgPSAoQ0hBTk5FTFNfU0gobkNoYW5uZWxzKXxCWVRFU19TSCgyKSk7DQotDQotICAgIC8vIDE2IGJpdHMgdG8gTGFiIGRvdWJsZQ0KLSAgICBDaGFpbi5oSW5wdXQgPSBjbXNDcmVhdGVFeHRlbmRlZFRyYW5zZm9ybShDb250ZXh0SUQsDQotICAgICAgICBuR2FtdXRQQ1Nwb3NpdGlvbiArIDEsDQotICAgICAgICBQcm9maWxlTGlzdCwNCi0gICAgICAgIEJQQ0xpc3QsDQotICAgICAgICBJbnRlbnRMaXN0LA0KLSAgICAgICAgQWRhcHRhdGlvbkxpc3QsDQotICAgICAgICBOVUxMLCAwLA0KLSAgICAgICAgZHdGb3JtYXQsIFRZUEVfTGFiX0RCTCwNCi0gICAgICAgIGNtc0ZMQUdTX05PQ0FDSEUpOw0KLQ0KLQ0KLSAgICAvLyBEb2VzIGNyZWF0ZSB0aGUgZm9yd2FyZCBzdGVwLiBMYWIgZG91YmxlIHRvIGRldmljZQ0KLSAgICBkd0Zvcm1hdCAgICA9IChDSEFOTkVMU19TSChuQ2hhbm5lbHMpfEJZVEVTX1NIKDIpKTsNCi0gICAgQ2hhaW4uaEZvcndhcmQgPSBjbXNDcmVhdGVUcmFuc2Zvcm1USFIoQ29udGV4dElELA0KLSAgICAgICAgaExhYiwgVFlQRV9MYWJfREJMLA0KLSAgICAgICAgaEdhbXV0LCBkd0Zvcm1hdCwNCi0gICAgICAgIElOVEVOVF9SRUxBVElWRV9DT0xPUklNRVRSSUMsDQotICAgICAgICBjbXNGTEFHU19OT0NBQ0hFKTsNCi0NCi0gICAgLy8gRG9lcyBjcmVhdGUgdGhlIGJhY2t3YXJkcyBzdGVwDQotICAgIENoYWluLmhSZXZlcnNlID0gY21zQ3JlYXRlVHJhbnNmb3JtVEhSKENvbnRleHRJRCwgaEdhbXV0LCBkd0Zvcm1hdCwNCi0gICAgICAgIGhMYWIsIFRZUEVfTGFiX0RCTCwNCi0gICAgICAgIElOVEVOVF9SRUxBVElWRV9DT0xPUklNRVRSSUMsDQotICAgICAgICBjbXNGTEFHU19OT0NBQ0hFKTsNCi0NCi0NCi0gICAgLy8gQWxsIG9rPw0KLSAgICBpZiAoQ2hhaW4uaElucHV0ICYmIENoYWluLmhGb3J3YXJkICYmIENoYWluLmhSZXZlcnNlKSB7DQotDQotICAgICAgICAvLyBHbyBvbiwgdHJ5IHRvIGNvbXB1dGUgZ2FtdXQgTFVUIGZyb20gUENTLiBUaGlzIGNvbnNpc3Qgb24gYSBzaW5nbGUgY2hhbm5lbCBjb250YWluaW5nDQotICAgICAgICAvLyBkRSB3aGVuIGRvaW5nIGEgdHJhbnNmb3JtIGJhY2sgYW5kIGZvcnRoIG9uIHRoZSBjb2xvcmltZXRyaWMgaW50ZW50Lg0KLQ0KLSAgICAgICAgR2FtdXQgPSBjbXNQaXBlbGluZUFsbG9jKENvbnRleHRJRCwgMywgMSk7DQotICAgICAgICBpZiAoR2FtdXQgIT0gTlVMTCkgew0KLQ0KLSAgICAgICAgICAgIENMVVQgPSBjbXNTdGFnZUFsbG9jQ0x1dDE2Yml0KENvbnRleHRJRCwgbkdyaWRwb2ludHMsIG5DaGFubmVscywgMSwgTlVMTCk7DQotICAgICAgICAgICAgaWYgKCFjbXNQaXBlbGluZUluc2VydFN0YWdlKEdhbXV0LCBjbXNBVF9CRUdJTiwgQ0xVVCkpIHsNCi0gICAgICAgICAgICAgICAgY21zUGlwZWxpbmVGcmVlKEdhbXV0KTsNCi0gICAgICAgICAgICAgICAgR2FtdXQgPSBOVUxMOw0KLSAgICAgICAgICAgIH0gDQotICAgICAgICAgICAgZWxzZSB7DQotICAgICAgICAgICAgICAgIGNtc1N0YWdlU2FtcGxlQ0x1dDE2Yml0KENMVVQsIEdhbXV0U2FtcGxlciwgKHZvaWQqKSAmQ2hhaW4sIDApOw0KLSAgICAgICAgICAgIH0NCi0gICAgICAgIH0NCi0gICAgfQ0KLSAgICBlbHNlDQotICAgICAgICBHYW11dCA9IE5VTEw7ICAgLy8gRGlkbid0IHdvcmsuLi4NCi0NCi0gICAgLy8gRnJlZSBhbGwgbmVlZGVkIHN0dWZmLg0KLSAgICBpZiAoQ2hhaW4uaElucHV0KSAgIGNtc0RlbGV0ZVRyYW5zZm9ybShDaGFpbi5oSW5wdXQpOw0KLSAgICBpZiAoQ2hhaW4uaEZvcndhcmQpIGNtc0RlbGV0ZVRyYW5zZm9ybShDaGFpbi5oRm9yd2FyZCk7DQotICAgIGlmIChDaGFpbi5oUmV2ZXJzZSkgY21zRGVsZXRlVHJhbnNmb3JtKENoYWluLmhSZXZlcnNlKTsNCi0gICAgaWYgKGhMYWIpIGNtc0Nsb3NlUHJvZmlsZShoTGFiKTsNCi0NCi0gICAgLy8gQW5kIHJldHVybiBjb21wdXRlZCBodWxsDQotICAgIHJldHVybiBHYW11dDsNCi19DQotDQotLy8gVG90YWwgQXJlYSBDb3ZlcmFnZSBlc3RpbWF0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCi0NCi10eXBlZGVmIHN0cnVjdCB7DQotICAgIGNtc1VJbnQzMk51bWJlciAgbk91dHB1dENoYW5zOw0KLSAgICBjbXNIVFJBTlNGT1JNICAgIGhSb3VuZFRyaXA7DQotICAgIGNtc0Zsb2F0MzJOdW1iZXIgTWF4VEFDOw0KLSAgICBjbXNGbG9hdDMyTnVtYmVyIE1heElucHV0W2Ntc01BWENIQU5ORUxTXTsNCi0NCi19IGNtc1RBQ2VzdGltYXRvcjsNCi0NCi0NCi0vLyBUaGlzIGNhbGxiYWNrIGp1c3QgYWNjb3VudHMgdGhlIG1heGltdW0gaW5rIGRyb3BwZWQgaW4gdGhlIGdpdmVuIG5vZGUuIEl0IGRvZXMgbm90IHBvcHVsYXRlIGFueQ0KLS8vIG1lbW9yeSwgYXMgdGhlIGRlc3RpbmF0aW9uIHRhYmxlIGlzIE5VTEwuIEl0cyBvbmx5IHB1cnBvc2UgaXQgdG8ga25vdyB0aGUgZ2xvYmFsIG1heGltdW0uDQotc3RhdGljDQotaW50IEVzdGltYXRlVEFDKHJlZ2lzdGVyIGNvbnN0IGNtc1VJbnQxNk51bWJlciBJbltdLCByZWdpc3RlciBjbXNVSW50MTZOdW1iZXIgT3V0W10sIHJlZ2lzdGVyIHZvaWQgKiBDYXJnbykNCi17DQotICAgIGNtc1RBQ2VzdGltYXRvciogYnAgPSAoY21zVEFDZXN0aW1hdG9yKikgQ2FyZ287DQotICAgIGNtc0Zsb2F0MzJOdW1iZXIgUm91bmRUcmlwW2Ntc01BWENIQU5ORUxTXTsNCi0gICAgY21zVUludDMyTnVtYmVyIGk7DQotICAgIGNtc0Zsb2F0MzJOdW1iZXIgU3VtOw0KLQ0KLQ0KLSAgICAvLyBFdmFsdWF0ZSB0aGUgeGZvcm0NCi0gICAgY21zRG9UcmFuc2Zvcm0oYnAtPmhSb3VuZFRyaXAsIEluLCBSb3VuZFRyaXAsIDEpOw0KLQ0KLSAgICAvLyBBbGwgYWxsIGFtb3VudHMgb2YgaW5rDQotICAgIGZvciAoU3VtPTAsIGk9MDsgaSA8IGJwIC0+bk91dHB1dENoYW5zOyBpKyspDQotICAgICAgICAgICAgU3VtICs9IFJvdW5kVHJpcFtpXTsNCi0NCi0gICAgLy8gSWYgYWJvdmUgbWF4aW11bSwga2VlcCB0cmFjayBvZiBpbnB1dCB2YWx1ZXMNCi0gICAgaWYgKFN1bSA+IGJwIC0+TWF4VEFDKSB7DQotDQotICAgICAgICAgICAgYnAgLT5NYXhUQUMgPSBTdW07DQotDQotICAgICAgICAgICAgZm9yIChpPTA7IGkgPCBicCAtPm5PdXRwdXRDaGFuczsgaSsrKSB7DQotICAgICAgICAgICAgICAgIGJwIC0+TWF4SW5wdXRbaV0gPSBJbltpXTsNCi0gICAgICAgICAgICB9DQotICAgIH0NCi0NCi0gICAgcmV0dXJuIFRSVUU7DQotDQotICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoT3V0KTsNCi19DQotDQotDQotLy8gRGV0ZWN0IFRvdGFsIGFyZWEgY292ZXJhZ2Ugb2YgdGhlIHByb2ZpbGUNCi1jbXNGbG9hdDY0TnVtYmVyIENNU0VYUE9SVCBjbXNEZXRlY3RUQUMoY21zSFBST0ZJTEUgaFByb2ZpbGUpDQotew0KLSAgICBjbXNUQUNlc3RpbWF0b3IgYnA7DQotICAgIGNtc1VJbnQzMk51bWJlciBkd0Zvcm1hdHRlcjsNCi0gICAgY21zVUludDMyTnVtYmVyIEdyaWRQb2ludHNbTUFYX0lOUFVUX0RJTUVOU0lPTlNdOw0KLSAgICBjbXNIUFJPRklMRSBoTGFiOw0KLSAgICBjbXNDb250ZXh0IENvbnRleHRJRCA9IGNtc0dldFByb2ZpbGVDb250ZXh0SUQoaFByb2ZpbGUpOw0KLQ0KLSAgICAvLyBUQUMgb25seSB3b3JrcyBvbiBvdXRwdXQgcHJvZmlsZXMNCi0gICAgaWYgKGNtc0dldERldmljZUNsYXNzKGhQcm9maWxlKSAhPSBjbXNTaWdPdXRwdXRDbGFzcykgew0KLSAgICAgICAgcmV0dXJuIDA7DQotICAgIH0NCi0NCi0gICAgLy8gQ3JlYXRlIGEgZmFrZSBmb3JtYXR0ZXIgZm9yIHJlc3VsdA0KLSAgICBkd0Zvcm1hdHRlciA9IGNtc0Zvcm1hdHRlckZvckNvbG9yc3BhY2VPZlByb2ZpbGUoaFByb2ZpbGUsIDQsIFRSVUUpOw0KLQ0KLSAgICBicC5uT3V0cHV0Q2hhbnMgPSBUX0NIQU5ORUxTKGR3Rm9ybWF0dGVyKTsNCi0gICAgYnAuTWF4VEFDID0gMDsgICAgLy8gSW5pdGlhbCBUQUMgaXMgMA0KLQ0KLSAgICAvLyAgZm9yIHNhZmV0eQ0KLSAgICBpZiAoYnAubk91dHB1dENoYW5zID49IGNtc01BWENIQU5ORUxTKSByZXR1cm4gMDsNCi0NCi0gICAgaExhYiA9IGNtc0NyZWF0ZUxhYjRQcm9maWxlVEhSKENvbnRleHRJRCwgTlVMTCk7DQotICAgIGlmIChoTGFiID09IE5VTEwpIHJldHVybiAwOw0KLSAgICAvLyBTZXR1cCBhIHJvdW5kdHJpcCBvbiBwZXJjZXB0dWFsIGludGVudCBpbiBvdXRwdXQgcHJvZmlsZSBmb3IgVEFDIGVzdGltYXRpb24NCi0gICAgYnAuaFJvdW5kVHJpcCA9IGNtc0NyZWF0ZVRyYW5zZm9ybVRIUihDb250ZXh0SUQsIGhMYWIsIFRZUEVfTGFiXzE2LA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhQcm9maWxlLCBkd0Zvcm1hdHRlciwgSU5URU5UX1BFUkNFUFRVQUwsIGNtc0ZMQUdTX05PT1BUSU1JWkV8Y21zRkxBR1NfTk9DQUNIRSk7DQotDQotICAgIGNtc0Nsb3NlUHJvZmlsZShoTGFiKTsNCi0gICAgaWYgKGJwLmhSb3VuZFRyaXAgPT0gTlVMTCkgcmV0dXJuIDA7DQotDQotICAgIC8vIEZvciBMKiB3ZSBvbmx5IG5lZWQgYmxhY2sgYW5kIHdoaXRlLiBGb3IgQyogd2UgbmVlZCBtYW55IHBvaW50cw0KLSAgICBHcmlkUG9pbnRzWzBdID0gNjsNCi0gICAgR3JpZFBvaW50c1sxXSA9IDc0Ow0KLSAgICBHcmlkUG9pbnRzWzJdID0gNzQ7DQotDQotDQotICAgIGlmICghY21zU2xpY2VTcGFjZTE2KDMsIEdyaWRQb2ludHMsIEVzdGltYXRlVEFDLCAmYnApKSB7DQotICAgICAgICBicC5NYXhUQUMgPSAwOw0KLSAgICB9DQotDQotICAgIGNtc0RlbGV0ZVRyYW5zZm9ybShicC5oUm91bmRUcmlwKTsNCi0NCi0gICAgLy8gUmVzdWx0cyBpbiAlDQotICAgIHJldHVybiBicC5NYXhUQUM7DQotfQ0KLQ0KLQ0KLS8vIENhcmVmdWxseSwgIGNsYW1wIG9uIENJRUxhYiBzcGFjZS4NCi0NCi1jbXNCb29sIENNU0VYUE9SVCBjbXNEZXNhdHVyYXRlTGFiKGNtc0NJRUxhYiogTGFiLA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIGFtYXgsIGRvdWJsZSBhbWluLA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIGJtYXgsIGRvdWJsZSBibWluKQ0KLXsNCi0NCi0gICAgLy8gV2hvbGUgTHVtYSBzdXJmYWNlIHRvIHplcm8NCi0NCi0gICAgaWYgKExhYiAtPiBMIDwgMCkgew0KLQ0KLSAgICAgICAgTGFiLT4gTCA9IExhYi0+YSA9IExhYi0+IGIgPSAwLjA7DQotICAgICAgICByZXR1cm4gRkFMU0U7DQotICAgIH0NCi0NCi0gICAgLy8gQ2xhbXAgd2hpdGUsIERJU0NBUkQgSElHSExJR0hUUy4gVGhpcyBpcyBkb25lDQotICAgIC8vIGluIHN1Y2ggd2F5IGJlY2F1c2UgaWNjIHNwZWMgZG9lc24ndCBhbGxvdyB0aGUNCi0gICAgLy8gdXNlIG9mIEw+MTAwIGFzIGEgaGlnaGxpZ2h0IG1lYW5zLg0KLQ0KLSAgICBpZiAoTGFiLT5MID4gMTAwKQ0KLSAgICAgICAgTGFiIC0+IEwgPSAxMDA7DQotDQotICAgIC8vIENoZWNrIG91dCBnYW11dCBwcmlzbSwgb24gYSwgYiBmYWNlcw0KLQ0KLSAgICBpZiAoTGFiIC0+IGEgPCBhbWluIHx8IExhYi0+YSA+IGFtYXh8fA0KLSAgICAgICAgTGFiIC0+IGIgPCBibWluIHx8IExhYi0+YiA+IGJtYXgpIHsNCi0NCi0gICAgICAgICAgICBjbXNDSUVMQ2ggTENoOw0KLSAgICAgICAgICAgIGRvdWJsZSBoLCBzbG9wZTsNCi0NCi0gICAgICAgICAgICAvLyBGYWxscyBvdXRzaWRlIGEsIGIgbGltaXRzLiBUcmFuc3BvcnRzIHRvIExDaCBzcGFjZSwNCi0gICAgICAgICAgICAvLyBhbmQgdGhlbiBkbyB0aGUgY2xpcHBpbmcNCi0NCi0NCi0gICAgICAgICAgICBpZiAoTGFiIC0+IGEgPT0gMC4wKSB7IC8vIElzIGh1ZSBleGFjdGx5IDkwPw0KLQ0KLSAgICAgICAgICAgICAgICAvLyBhdGFuIHdpbGwgbm90IHdvcmssIHNvIGNsYW1wIGhlcmUNCi0gICAgICAgICAgICAgICAgTGFiIC0+IGIgPSBMYWItPmIgPCAwID8gYm1pbiA6IGJtYXg7DQotICAgICAgICAgICAgICAgIHJldHVybiBUUlVFOw0KLSAgICAgICAgICAgIH0NCi0NCi0gICAgICAgICAgICBjbXNMYWIyTENoKCZMQ2gsIExhYik7DQotDQotICAgICAgICAgICAgc2xvcGUgPSBMYWIgLT4gYiAvIExhYiAtPiBhOw0KLSAgICAgICAgICAgIGggPSBMQ2guaDsNCi0NCi0gICAgICAgICAgICAvLyBUaGVyZSBhcmUgNCB6b25lcw0KLQ0KLSAgICAgICAgICAgIGlmICgoaCA+PSAwLiAmJiBoIDwgNDUuKSB8fA0KLSAgICAgICAgICAgICAgICAoaCA+PSAzMTUgJiYgaCA8PSAzNjAuKSkgew0KLQ0KLSAgICAgICAgICAgICAgICAgICAgLy8gY2xpcCBieSBhbWF4DQotICAgICAgICAgICAgICAgICAgICBMYWIgLT4gYSA9IGFtYXg7DQotICAgICAgICAgICAgICAgICAgICBMYWIgLT4gYiA9IGFtYXggKiBzbG9wZTsNCi0gICAgICAgICAgICB9DQotICAgICAgICAgICAgZWxzZQ0KLSAgICAgICAgICAgICAgICBpZiAoaCA+PSA0NS4gJiYgaCA8IDEzNS4pDQotICAgICAgICAgICAgICAgIHsNCi0gICAgICAgICAgICAgICAgICAgIC8vIGNsaXAgYnkgYm1heA0KLSAgICAgICAgICAgICAgICAgICAgTGFiIC0+IGIgPSBibWF4Ow0KLSAgICAgICAgICAgICAgICAgICAgTGFiIC0+IGEgPSBibWF4IC8gc2xvcGU7DQotICAgICAgICAgICAgICAgIH0NCi0gICAgICAgICAgICAgICAgZWxzZQ0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGggPj0gMTM1LiAmJiBoIDwgMjI1Likgew0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsaXAgYnkgYW1pbg0KLSAgICAgICAgICAgICAgICAgICAgICAgIExhYiAtPiBhID0gYW1pbjsNCi0gICAgICAgICAgICAgICAgICAgICAgICBMYWIgLT4gYiA9IGFtaW4gKiBzbG9wZTsNCi0NCi0gICAgICAgICAgICAgICAgICAgIH0NCi0gICAgICAgICAgICAgICAgICAgIGVsc2UNCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaCA+PSAyMjUuICYmIGggPCAzMTUuKSB7DQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsaXAgYnkgYm1pbg0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYWIgLT4gYiA9IGJtaW47DQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhYiAtPiBhID0gYm1pbiAvIHNsb3BlOw0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0NCi0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlICB7DQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1NpZ25hbEVycm9yKDAsIGNtc0VSUk9SX1JBTkdFLCAiSW52YWxpZCBhbmdsZSIpOw0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7DQotICAgICAgICAgICAgICAgICAgICAgICAgfQ0KLQ0KLSAgICB9DQotDQotICAgIHJldHVybiBUUlVFOw0KLX0NCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICBMaXR0bGUgQ29sb3IgTWFuYWdlbWVudCBTeXN0ZW0KKy8vICBDb3B5cmlnaHQgKGMpIDE5OTgtMjAxNyBNYXJ0aSBNYXJpYSBTYWd1ZXIKKy8vCisvLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcKKy8vIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwKKy8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24KKy8vIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAorLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlCisvLyBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgorLy8KKy8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCisvLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KKy8vCisvLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKKy8vIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTworLy8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQKKy8vIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUKKy8vIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04KKy8vIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTgorLy8gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCisvLworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisKKyNpbmNsdWRlICJsY21zMl9pbnRlcm5hbC5oIgorCisKKy8vIEF1eGlsaWFyeTogYXBwZW5kIGEgTGFiIGlkZW50aXR5IGFmdGVyIHRoZSBnaXZlbiBzZXF1ZW5jZSBvZiBwcm9maWxlcworLy8gYW5kIHJldHVybiB0aGUgdHJhbnNmb3JtLiBMYWIgcHJvZmlsZSBpcyBjbG9zZWQsIHJlc3Qgb2YgcHJvZmlsZXMgYXJlIGtlcHQgb3Blbi4KK2Ntc0hUUkFOU0ZPUk0gX2Ntc0NoYWluMkxhYihjbXNDb250ZXh0ICAgICAgICAgICAgQ29udGV4dElELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciAgICAgICAgblByb2ZpbGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciAgICAgICAgSW5wdXRGb3JtYXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyICAgICAgICBPdXRwdXRGb3JtYXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY21zVUludDMyTnVtYmVyICBJbnRlbnRzW10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY21zSFBST0ZJTEUgICAgICBoUHJvZmlsZXNbXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjbXNCb29sICAgICAgICAgIEJQQ1tdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNtc0Zsb2F0NjROdW1iZXIgQWRhcHRhdGlvblN0YXRlc1tdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciAgICAgICAgZHdGbGFncykKK3sKKyAgICBjbXNIVFJBTlNGT1JNIHhmb3JtOworICAgIGNtc0hQUk9GSUxFICAgaExhYjsKKyAgICBjbXNIUFJPRklMRSAgIFByb2ZpbGVMaXN0WzI1Nl07CisgICAgY21zQm9vbCAgICAgICBCUENMaXN0WzI1Nl07CisgICAgY21zRmxvYXQ2NE51bWJlciBBZGFwdGF0aW9uTGlzdFsyNTZdOworICAgIGNtc1VJbnQzMk51bWJlciBJbnRlbnRMaXN0WzI1Nl07CisgICAgY21zVUludDMyTnVtYmVyIGk7CisKKyAgICAvLyBUaGlzIGlzIGEgcmF0aGVyIGJpZyBudW1iZXIgYW5kIHRoZXJlIGlzIG5vIG5lZWQgb2YgZHluYW1pYyBtZW1vcnkKKyAgICAvLyBzaW5jZSB3ZSBhcmUgYWRkaW5nIGEgcHJvZmlsZSwgMjU0ICsgMSA9IDI1NSBhbmQgdGhpcyBpcyB0aGUgbGltaXQKKyAgICBpZiAoblByb2ZpbGVzID4gMjU0KSByZXR1cm4gTlVMTDsKKworICAgIC8vIFRoZSBvdXRwdXQgc3BhY2UKKyAgICBoTGFiID0gY21zQ3JlYXRlTGFiNFByb2ZpbGVUSFIoQ29udGV4dElELCBOVUxMKTsKKyAgICBpZiAoaExhYiA9PSBOVUxMKSByZXR1cm4gTlVMTDsKKworICAgIC8vIENyZWF0ZSBhIGNvcHkgb2YgcGFyYW1ldGVycworICAgIGZvciAoaT0wOyBpIDwgblByb2ZpbGVzOyBpKyspIHsKKworICAgICAgICBQcm9maWxlTGlzdFtpXSAgICA9IGhQcm9maWxlc1tpXTsKKyAgICAgICAgQlBDTGlzdFtpXSAgICAgICAgPSBCUENbaV07CisgICAgICAgIEFkYXB0YXRpb25MaXN0W2ldID0gQWRhcHRhdGlvblN0YXRlc1tpXTsKKyAgICAgICAgSW50ZW50TGlzdFtpXSAgICAgPSBJbnRlbnRzW2ldOworICAgIH0KKworICAgIC8vIFBsYWNlIExhYiBpZGVudGl0eSBhdCBjaGFpbidzIGVuZC4KKyAgICBQcm9maWxlTGlzdFtuUHJvZmlsZXNdICAgID0gaExhYjsKKyAgICBCUENMaXN0W25Qcm9maWxlc10gICAgICAgID0gMDsKKyAgICBBZGFwdGF0aW9uTGlzdFtuUHJvZmlsZXNdID0gMS4wOworICAgIEludGVudExpc3RbblByb2ZpbGVzXSAgICAgPSBJTlRFTlRfUkVMQVRJVkVfQ09MT1JJTUVUUklDOworCisgICAgLy8gQ3JlYXRlIHRoZSB0cmFuc2Zvcm0KKyAgICB4Zm9ybSA9IGNtc0NyZWF0ZUV4dGVuZGVkVHJhbnNmb3JtKENvbnRleHRJRCwgblByb2ZpbGVzICsgMSwgUHJvZmlsZUxpc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCUENMaXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZW50TGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFkYXB0YXRpb25MaXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElucHV0Rm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3V0cHV0Rm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdGbGFncyk7CisKKyAgICBjbXNDbG9zZVByb2ZpbGUoaExhYik7CisKKyAgICByZXR1cm4geGZvcm07Cit9CisKKworLy8gQ29tcHV0ZSBLIC0+IEwqIHJlbGF0aW9uc2hpcC4gRmxhZ3MgbWF5IGluY2x1ZGUgYmxhY2sgcG9pbnQgY29tcGVuc2F0aW9uLiBJbiB0aGlzIGNhc2UsCisvLyB0aGUgcmVsYXRpb25zaGlwIGlzIGFzc3VtZWQgZnJvbSB0aGUgcHJvZmlsZSB3aXRoIEJQQyB0byBhIGJsYWNrIHBvaW50IHplcm8uCitzdGF0aWMKK2Ntc1RvbmVDdXJ2ZSogQ29tcHV0ZUtUb0xzdGFyKGNtc0NvbnRleHQgICAgICAgICAgICBDb250ZXh0SUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyICAgICAgIG5Qb2ludHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyICAgICAgIG5Qcm9maWxlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjbXNVSW50MzJOdW1iZXIgSW50ZW50c1tdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNtc0hQUk9GSUxFICAgICBoUHJvZmlsZXNbXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjbXNCb29sICAgICAgICAgQlBDW10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY21zRmxvYXQ2NE51bWJlciBBZGFwdGF0aW9uU3RhdGVzW10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIGR3RmxhZ3MpCit7CisgICAgY21zVG9uZUN1cnZlKiBvdXQgPSBOVUxMOworICAgIGNtc1VJbnQzMk51bWJlciBpOworICAgIGNtc0hUUkFOU0ZPUk0geGZvcm07CisgICAgY21zQ0lFTGFiIExhYjsKKyAgICBjbXNGbG9hdDMyTnVtYmVyIGNteWtbNF07CisgICAgY21zRmxvYXQzMk51bWJlciogU2FtcGxlZFBvaW50czsKKworICAgIHhmb3JtID0gX2Ntc0NoYWluMkxhYihDb250ZXh0SUQsIG5Qcm9maWxlcywgVFlQRV9DTVlLX0ZMVCwgVFlQRV9MYWJfREJMLCBJbnRlbnRzLCBoUHJvZmlsZXMsIEJQQywgQWRhcHRhdGlvblN0YXRlcywgZHdGbGFncyk7CisgICAgaWYgKHhmb3JtID09IE5VTEwpIHJldHVybiBOVUxMOworCisgICAgU2FtcGxlZFBvaW50cyA9IChjbXNGbG9hdDMyTnVtYmVyKikgX2Ntc0NhbGxvYyhDb250ZXh0SUQsIG5Qb2ludHMsIHNpemVvZihjbXNGbG9hdDMyTnVtYmVyKSk7CisgICAgaWYgKFNhbXBsZWRQb2ludHMgID09IE5VTEwpIGdvdG8gRXJyb3I7CisKKyAgICBmb3IgKGk9MDsgaSA8IG5Qb2ludHM7IGkrKykgeworCisgICAgICAgIGNteWtbMF0gPSAwOworICAgICAgICBjbXlrWzFdID0gMDsKKyAgICAgICAgY215a1syXSA9IDA7CisgICAgICAgIGNteWtbM10gPSAoY21zRmxvYXQzMk51bWJlcikgKChpICogMTAwLjApIC8gKG5Qb2ludHMtMSkpOworCisgICAgICAgIGNtc0RvVHJhbnNmb3JtKHhmb3JtLCBjbXlrLCAmTGFiLCAxKTsKKyAgICAgICAgU2FtcGxlZFBvaW50c1tpXT0gKGNtc0Zsb2F0MzJOdW1iZXIpICgxLjAgLSBMYWIuTCAvIDEwMC4wKTsgLy8gTmVnYXRlIEsgZm9yIGVhc2llciBvcGVyYXRpb24KKyAgICB9CisKKyAgICBvdXQgPSBjbXNCdWlsZFRhYnVsYXRlZFRvbmVDdXJ2ZUZsb2F0KENvbnRleHRJRCwgblBvaW50cywgU2FtcGxlZFBvaW50cyk7CisKK0Vycm9yOgorCisgICAgY21zRGVsZXRlVHJhbnNmb3JtKHhmb3JtKTsKKyAgICBpZiAoU2FtcGxlZFBvaW50cykgX2Ntc0ZyZWUoQ29udGV4dElELCBTYW1wbGVkUG9pbnRzKTsKKworICAgIHJldHVybiBvdXQ7Cit9CisKKworLy8gQ29tcHV0ZSBCbGFjayB0b25lIGN1cnZlIG9uIGEgQ01ZSyAtPiBDTVlLIHRyYW5zZm9ybS4gVGhpcyBpcyBkb25lIGJ5CisvLyB1c2luZyB0aGUgcHJvb2YgZGlyZWN0aW9uIG9uIGJvdGggcHJvZmlsZXMgdG8gZmluZCBLLT5MKiByZWxhdGlvbnNoaXAKKy8vIHRoZW4gam9pbmluZyBib3RoIGN1cnZlcy4gZHdGbGFncyBtYXkgaW5jbHVkZSBibGFjayBwb2ludCBjb21wZW5zYXRpb24uCitjbXNUb25lQ3VydmUqIF9jbXNCdWlsZEtUb25lQ3VydmUoY21zQ29udGV4dCAgICAgICAgQ29udGV4dElELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgICBuUG9pbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgICBuUHJvZmlsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNtc1VJbnQzMk51bWJlciBJbnRlbnRzW10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNtc0hQUk9GSUxFIGhQcm9maWxlc1tdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjbXNCb29sICAgICBCUENbXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY21zRmxvYXQ2NE51bWJlciBBZGFwdGF0aW9uU3RhdGVzW10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciAgIGR3RmxhZ3MpCit7CisgICAgY21zVG9uZUN1cnZlICppbiwgKm91dCwgKktUb25lOworCisgICAgLy8gTWFrZSBzdXJlIENNWUsgLT4gQ01ZSworICAgIGlmIChjbXNHZXRDb2xvclNwYWNlKGhQcm9maWxlc1swXSkgIT0gY21zU2lnQ215a0RhdGEgfHwKKyAgICAgICAgY21zR2V0Q29sb3JTcGFjZShoUHJvZmlsZXNbblByb2ZpbGVzLTFdKSE9IGNtc1NpZ0NteWtEYXRhKSByZXR1cm4gTlVMTDsKKworCisgICAgLy8gTWFrZSBzdXJlIGxhc3QgaXMgYW4gb3V0cHV0IHByb2ZpbGUKKyAgICBpZiAoY21zR2V0RGV2aWNlQ2xhc3MoaFByb2ZpbGVzW25Qcm9maWxlcyAtIDFdKSAhPSBjbXNTaWdPdXRwdXRDbGFzcykgcmV0dXJuIE5VTEw7CisKKyAgICAvLyBDcmVhdGUgaW5kaXZpZHVhbCBjdXJ2ZXMuIEJQQyB3b3JrcyBhbHNvIGFzIGVhY2ggSyB0byBMKiBpcworICAgIC8vIGNvbXB1dGVkIGFzIGEgQlBDIHRvIHplcm8gYmxhY2sgcG9pbnQgaW4gY2FzZSBvZiBMKgorICAgIGluICA9IENvbXB1dGVLVG9Mc3RhcihDb250ZXh0SUQsIG5Qb2ludHMsIG5Qcm9maWxlcyAtIDEsIEludGVudHMsIGhQcm9maWxlcywgQlBDLCBBZGFwdGF0aW9uU3RhdGVzLCBkd0ZsYWdzKTsKKyAgICBpZiAoaW4gPT0gTlVMTCkgcmV0dXJuIE5VTEw7CisKKyAgICBvdXQgPSBDb21wdXRlS1RvTHN0YXIoQ29udGV4dElELCBuUG9pbnRzLCAxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVudHMgKyAoblByb2ZpbGVzIC0gMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmhQcm9maWxlcyBbblByb2ZpbGVzIC0gMV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQlBDICsgKG5Qcm9maWxlcyAtIDEpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFkYXB0YXRpb25TdGF0ZXMgKyAoblByb2ZpbGVzIC0gMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdGbGFncyk7CisgICAgaWYgKG91dCA9PSBOVUxMKSB7CisgICAgICAgIGNtc0ZyZWVUb25lQ3VydmUoaW4pOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvLyBCdWlsZCB0aGUgcmVsYXRpb25zaGlwLiBUaGlzIGVmZmVjdGl2ZWx5IGxpbWl0cyB0aGUgbWF4aW11bSBhY2N1cmFjeSB0byAxNiBiaXRzLCBidXQKKyAgICAvLyBzaW5jZSB0aGlzIGlzIHVzZWQgb24gYmxhY2stcHJlc2VydmluZyBMVVRzLCB3ZSBhcmUgbm90IGxvc2luZyAgYWNjdXJhY3kgaW4gYW55IGNhc2UKKyAgICBLVG9uZSA9IGNtc0pvaW5Ub25lQ3VydmUoQ29udGV4dElELCBpbiwgb3V0LCBuUG9pbnRzKTsKKworICAgIC8vIEdldCByaWQgb2YgY29tcG9uZW50cworICAgIGNtc0ZyZWVUb25lQ3VydmUoaW4pOyBjbXNGcmVlVG9uZUN1cnZlKG91dCk7CisKKyAgICAvLyBTb21ldGhpbmcgd2VudCB3cm9uZy4uLgorICAgIGlmIChLVG9uZSA9PSBOVUxMKSByZXR1cm4gTlVMTDsKKworICAgIC8vIE1ha2Ugc3VyZSBpdCBpcyBtb25vdG9uaWMKKyAgICBpZiAoIWNtc0lzVG9uZUN1cnZlTW9ub3RvbmljKEtUb25lKSkgeworICAgICAgICBjbXNGcmVlVG9uZUN1cnZlKEtUb25lKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgcmV0dXJuIEtUb25lOworfQorCisKKy8vIEdhbXV0IExVVCBDcmVhdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBVc2VkIGJ5IGdhbXV0ICYgc29mdHByb29maW5nCisKK3R5cGVkZWYgc3RydWN0IHsKKworICAgIGNtc0hUUkFOU0ZPUk0gaElucHV0OyAgICAgICAgICAgICAgIC8vIEZyb20gd2hhdGV2ZXIgaW5wdXQgY29sb3Igc3BhY2UuIDE2IGJpdHMgdG8gREJMCisgICAgY21zSFRSQU5TRk9STSBoRm9yd2FyZCwgaFJldmVyc2U7ICAgLy8gVHJhbnNmb3JtcyBnb2luZyBmcm9tIExhYiB0byBjb2xvcmFudCBhbmQgYmFjaworICAgIGNtc0Zsb2F0NjROdW1iZXIgVGhlcmVzaG9sZDsgICAgICAgIC8vIFRoZSB0aGVyZXNob2xkIGFmdGVyIHdoaWNoIGlzIGNvbnNpZGVyZWQgb3V0IG9mIGdhbXV0CisKKyAgICB9IEdBTVVUQ0hBSU47CisKKy8vIFRoaXMgc2FtcGxlciBkb2VzIGNvbXB1dGUgZ2FtdXQgYm91bmRhcmllcyBieSBjb21wYXJpbmcgb3JpZ2luYWwKKy8vIHZhbHVlcyB3aXRoIGEgdHJhbnNmb3JtIGdvaW5nIGJhY2sgYW5kIGZvcnRoLiBWYWx1ZXMgYWJvdmUgRVJSX1RIRVJFU0hPTEQKKy8vIG9mIG1heGltdW0gYXJlIGNvbnNpZGVyZWQgb3V0IG9mIGdhbXV0LgorCisjZGVmaW5lIEVSUl9USEVSRVNIT0xEICAgICAgNQorCisKK3N0YXRpYworaW50IEdhbXV0U2FtcGxlcihyZWdpc3RlciBjb25zdCBjbXNVSW50MTZOdW1iZXIgSW5bXSwgcmVnaXN0ZXIgY21zVUludDE2TnVtYmVyIE91dFtdLCByZWdpc3RlciB2b2lkKiBDYXJnbykKK3sKKyAgICBHQU1VVENIQUlOKiAgdCA9IChHQU1VVENIQUlOKiApIENhcmdvOworICAgIGNtc0NJRUxhYiBMYWJJbjEsIExhYk91dDE7CisgICAgY21zQ0lFTGFiIExhYkluMiwgTGFiT3V0MjsKKyAgICBjbXNVSW50MTZOdW1iZXIgUHJvb2ZbY21zTUFYQ0hBTk5FTFNdLCBQcm9vZjJbY21zTUFYQ0hBTk5FTFNdOworICAgIGNtc0Zsb2F0NjROdW1iZXIgZEUxLCBkRTIsIEVycm9yUmF0aW87CisKKyAgICAvLyBBc3N1bWUgaW4tZ2FtdXQgYnkgZGVmYXVsdC4KKyAgICBFcnJvclJhdGlvID0gMS4wOworCisgICAgLy8gQ29udmVydCBpbnB1dCB0byBMYWIKKyAgICBjbXNEb1RyYW5zZm9ybSh0IC0+IGhJbnB1dCwgSW4sICZMYWJJbjEsIDEpOworCisgICAgLy8gY29udmVydHMgZnJvbSBQQ1MgdG8gY29sb3JhbnQuIFRoaXMgYWx3YXlzCisgICAgLy8gZG9lcyByZXR1cm4gaW4tZ2FtdXQgdmFsdWVzLAorICAgIGNtc0RvVHJhbnNmb3JtKHQgLT4gaEZvcndhcmQsICZMYWJJbjEsIFByb29mLCAxKTsKKworICAgIC8vIE5vdywgZG8gdGhlIGludmVyc2UsIGZyb20gY29sb3JhbnQgdG8gUENTLgorICAgIGNtc0RvVHJhbnNmb3JtKHQgLT4gaFJldmVyc2UsIFByb29mLCAmTGFiT3V0MSwgMSk7CisKKyAgICBtZW1tb3ZlKCZMYWJJbjIsICZMYWJPdXQxLCBzaXplb2YoY21zQ0lFTGFiKSk7CisKKyAgICAvLyBUcnkgYWdhaW4sIGJ1dCB0aGlzIHRpbWUgdGFraW5nIENoZWNrIGFzIGlucHV0CisgICAgY21zRG9UcmFuc2Zvcm0odCAtPiBoRm9yd2FyZCwgJkxhYk91dDEsIFByb29mMiwgMSk7CisgICAgY21zRG9UcmFuc2Zvcm0odCAtPiBoUmV2ZXJzZSwgUHJvb2YyLCAmTGFiT3V0MiwgMSk7CisKKyAgICAvLyBUYWtlIGRpZmZlcmVuY2Ugb2YgZGlyZWN0IHZhbHVlCisgICAgZEUxID0gY21zRGVsdGFFKCZMYWJJbjEsICZMYWJPdXQxKTsKKworICAgIC8vIFRha2UgZGlmZmVyZW5jZSBvZiBjb252ZXJ0ZWQgdmFsdWUKKyAgICBkRTIgPSBjbXNEZWx0YUUoJkxhYkluMiwgJkxhYk91dDIpOworCisKKyAgICAvLyBpZiBkRTEgaXMgc21hbGwgYW5kIGRFMiBpcyBzbWFsbCwgdmFsdWUgaXMgbGlrZWx5IHRvIGJlIGluIGdhbXV0CisgICAgaWYgKGRFMSA8IHQtPlRoZXJlc2hvbGQgJiYgZEUyIDwgdC0+VGhlcmVzaG9sZCkKKyAgICAgICAgT3V0WzBdID0gMDsKKyAgICBlbHNlIHsKKworICAgICAgICAvLyBpZiBkRTEgaXMgc21hbGwgYW5kIGRFMiBpcyBiaWcsIHVuZGVmaW5lZC4gQXNzdW1lIGluIGdhbXV0CisgICAgICAgIGlmIChkRTEgPCB0LT5UaGVyZXNob2xkICYmIGRFMiA+IHQtPlRoZXJlc2hvbGQpCisgICAgICAgICAgICBPdXRbMF0gPSAwOworICAgICAgICBlbHNlCisgICAgICAgICAgICAvLyBkRTEgaXMgYmlnIGFuZCBkRTIgaXMgc21hbGwsIGNsZWFybHkgb3V0IG9mIGdhbXV0CisgICAgICAgICAgICBpZiAoZEUxID4gdC0+VGhlcmVzaG9sZCAmJiBkRTIgPCB0LT5UaGVyZXNob2xkKQorICAgICAgICAgICAgICAgIE91dFswXSA9IChjbXNVSW50MTZOdW1iZXIpIF9jbXNRdWlja0Zsb29yKChkRTEgLSB0LT5UaGVyZXNob2xkKSArIC41KTsKKyAgICAgICAgICAgIGVsc2UgIHsKKworICAgICAgICAgICAgICAgIC8vIGRFMSBpcyBiaWcgYW5kIGRFMiBpcyBhbHNvIGJpZywgY291bGQgYmUgZHVlIHRvIHBlcmNlcHR1YWwgbWFwcGluZworICAgICAgICAgICAgICAgIC8vIHNvIHRha2UgZXJyb3IgcmF0aW8KKyAgICAgICAgICAgICAgICBpZiAoZEUyID09IDAuMCkKKyAgICAgICAgICAgICAgICAgICAgRXJyb3JSYXRpbyA9IGRFMTsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIEVycm9yUmF0aW8gPSBkRTEgLyBkRTI7CisKKyAgICAgICAgICAgICAgICBpZiAoRXJyb3JSYXRpbyA+IHQtPlRoZXJlc2hvbGQpCisgICAgICAgICAgICAgICAgICAgIE91dFswXSA9IChjbXNVSW50MTZOdW1iZXIpICBfY21zUXVpY2tGbG9vcigoRXJyb3JSYXRpbyAtIHQtPlRoZXJlc2hvbGQpICsgLjUpOworICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgT3V0WzBdID0gMDsKKyAgICAgICAgICAgIH0KKyAgICB9CisKKworICAgIHJldHVybiBUUlVFOworfQorCisvLyBEb2VzIGNvbXB1dGUgYSBnYW11dCBMVVQgZ29pbmcgYmFjayBhbmQgZm9ydGggYWNyb3NzIHBjcyAtPiByZWxhdGl2LiBjb2xvcmltZXRyaWMgaW50ZW50IC0+IHBjcworLy8gdGhlIGRFIG9idGFpbmVkIGlzIHRoZW4gYW5ub3RhdGVkIG9uIHRoZSBMVVQuIFZhbHVlcyB0cnVseSBvdXQgb2YgZ2FtdXQgYXJlIGNsaXBwZWQgdG8gZEUgPSAweEZGRkUKKy8vIGFuZCB2YWx1ZXMgY2hhbmdlZCBhcmUgc3VwcG9zZWQgdG8gYmUgaGFuZGxlZCBieSBhbnkgZ2FtdXQgcmVtYXBwaW5nLCBzbywgYXJlIG91dCBvZiBnYW11dCBhcyB3ZWxsLgorLy8KKy8vICoqV0FSTklORzogVGhpcyBhbGdvcml0aG0gZG9lcyBhc3N1bWUgdGhhdCBnYW11dCByZW1hcHBpbmcgYWxnb3JpdGhtcyBkb2VzIE5PVCBtb3ZlIGluLWdhbXV0IGNvbG9ycywKKy8vIG9mIGNvdXJzZSwgbWFueSBwZXJjZXB0dWFsIGFuZCBzYXR1cmF0aW9uIGludGVudHMgZG9lcyBub3Qgd29yayBpbiBzdWNoIHdheSwgYnV0IHJlbGF0aXYuIG9uZXMgc2hvdWxkLgorCitjbXNQaXBlbGluZSogX2Ntc0NyZWF0ZUdhbXV0Q2hlY2tQaXBlbGluZShjbXNDb250ZXh0IENvbnRleHRJRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc0hQUk9GSUxFIGhQcm9maWxlc1tdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zQm9vbCAgQlBDW10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgSW50ZW50c1tdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zRmxvYXQ2NE51bWJlciBBZGFwdGF0aW9uU3RhdGVzW10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgbkdhbXV0UENTcG9zaXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNIUFJPRklMRSBoR2FtdXQpCit7CisgICAgY21zSFBST0ZJTEUgaExhYjsKKyAgICBjbXNQaXBlbGluZSogR2FtdXQ7CisgICAgY21zU3RhZ2UqIENMVVQ7CisgICAgY21zVUludDMyTnVtYmVyIGR3Rm9ybWF0OworICAgIEdBTVVUQ0hBSU4gQ2hhaW47CisgICAgY21zVUludDMyTnVtYmVyIG5DaGFubmVscywgbkdyaWRwb2ludHM7CisgICAgY21zQ29sb3JTcGFjZVNpZ25hdHVyZSBDb2xvclNwYWNlOworICAgIGNtc1VJbnQzMk51bWJlciBpOworICAgIGNtc0hQUk9GSUxFIFByb2ZpbGVMaXN0WzI1Nl07CisgICAgY21zQm9vbCAgICAgQlBDTGlzdFsyNTZdOworICAgIGNtc0Zsb2F0NjROdW1iZXIgQWRhcHRhdGlvbkxpc3RbMjU2XTsKKyAgICBjbXNVSW50MzJOdW1iZXIgSW50ZW50TGlzdFsyNTZdOworCisgICAgbWVtc2V0KCZDaGFpbiwgMCwgc2l6ZW9mKEdBTVVUQ0hBSU4pKTsKKworCisgICAgaWYgKG5HYW11dFBDU3Bvc2l0aW9uIDw9IDAgfHwgbkdhbXV0UENTcG9zaXRpb24gPiAyNTUpIHsKKyAgICAgICAgY21zU2lnbmFsRXJyb3IoQ29udGV4dElELCBjbXNFUlJPUl9SQU5HRSwgIldyb25nIHBvc2l0aW9uIG9mIFBDUy4gMS4uMjU1IGV4cGVjdGVkLCAlZCBmb3VuZC4iLCBuR2FtdXRQQ1Nwb3NpdGlvbik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGhMYWIgPSBjbXNDcmVhdGVMYWI0UHJvZmlsZVRIUihDb250ZXh0SUQsIE5VTEwpOworICAgIGlmIChoTGFiID09IE5VTEwpIHJldHVybiBOVUxMOworCisKKyAgICAvLyBUaGUgZmlndXJlIG9mIG1lcml0LiBPbiBtYXRyaXgtc2hhcGVyIHByb2ZpbGVzLCBzaG91bGQgYmUgYWxtb3N0IHplcm8gYXMKKyAgICAvLyB0aGUgY29udmVyc2lvbiBpcyBwcmV0dHkgZXhhY3QuIE9uIExVVCBiYXNlZCBwcm9maWxlcywgZGlmZmVyZW50IHJlc29sdXRpb25zCisgICAgLy8gb2YgaW5wdXQgYW5kIG91dHB1dCBDTFVUIG1heSByZXN1bHQgaW4gZGlmZmVyZW5jZXMuCisKKyAgICBpZiAoY21zSXNNYXRyaXhTaGFwZXIoaEdhbXV0KSkgeworCisgICAgICAgIENoYWluLlRoZXJlc2hvbGQgPSAxLjA7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBDaGFpbi5UaGVyZXNob2xkID0gRVJSX1RIRVJFU0hPTEQ7CisgICAgfQorCisKKyAgICAvLyBDcmVhdGUgYSBjb3B5IG9mIHBhcmFtZXRlcnMKKyAgICBmb3IgKGk9MDsgaSA8IG5HYW11dFBDU3Bvc2l0aW9uOyBpKyspIHsKKyAgICAgICAgUHJvZmlsZUxpc3RbaV0gICAgPSBoUHJvZmlsZXNbaV07CisgICAgICAgIEJQQ0xpc3RbaV0gICAgICAgID0gQlBDW2ldOworICAgICAgICBBZGFwdGF0aW9uTGlzdFtpXSA9IEFkYXB0YXRpb25TdGF0ZXNbaV07CisgICAgICAgIEludGVudExpc3RbaV0gICAgID0gSW50ZW50c1tpXTsKKyAgICB9CisKKyAgICAvLyBGaWxsIExhYiBpZGVudGl0eQorICAgIFByb2ZpbGVMaXN0W25HYW11dFBDU3Bvc2l0aW9uXSA9IGhMYWI7CisgICAgQlBDTGlzdFtuR2FtdXRQQ1Nwb3NpdGlvbl0gPSAwOworICAgIEFkYXB0YXRpb25MaXN0W25HYW11dFBDU3Bvc2l0aW9uXSA9IDEuMDsKKyAgICBJbnRlbnRMaXN0W25HYW11dFBDU3Bvc2l0aW9uXSA9IElOVEVOVF9SRUxBVElWRV9DT0xPUklNRVRSSUM7CisKKworICAgIENvbG9yU3BhY2UgID0gY21zR2V0Q29sb3JTcGFjZShoR2FtdXQpOworCisgICAgbkNoYW5uZWxzICAgPSBjbXNDaGFubmVsc09mKENvbG9yU3BhY2UpOworICAgIG5HcmlkcG9pbnRzID0gX2Ntc1JlYXNvbmFibGVHcmlkcG9pbnRzQnlDb2xvcnNwYWNlKENvbG9yU3BhY2UsIGNtc0ZMQUdTX0hJR0hSRVNQUkVDQUxDKTsKKyAgICBkd0Zvcm1hdCAgICA9IChDSEFOTkVMU19TSChuQ2hhbm5lbHMpfEJZVEVTX1NIKDIpKTsKKworICAgIC8vIDE2IGJpdHMgdG8gTGFiIGRvdWJsZQorICAgIENoYWluLmhJbnB1dCA9IGNtc0NyZWF0ZUV4dGVuZGVkVHJhbnNmb3JtKENvbnRleHRJRCwKKyAgICAgICAgbkdhbXV0UENTcG9zaXRpb24gKyAxLAorICAgICAgICBQcm9maWxlTGlzdCwKKyAgICAgICAgQlBDTGlzdCwKKyAgICAgICAgSW50ZW50TGlzdCwKKyAgICAgICAgQWRhcHRhdGlvbkxpc3QsCisgICAgICAgIE5VTEwsIDAsCisgICAgICAgIGR3Rm9ybWF0LCBUWVBFX0xhYl9EQkwsCisgICAgICAgIGNtc0ZMQUdTX05PQ0FDSEUpOworCisKKyAgICAvLyBEb2VzIGNyZWF0ZSB0aGUgZm9yd2FyZCBzdGVwLiBMYWIgZG91YmxlIHRvIGRldmljZQorICAgIGR3Rm9ybWF0ICAgID0gKENIQU5ORUxTX1NIKG5DaGFubmVscyl8QllURVNfU0goMikpOworICAgIENoYWluLmhGb3J3YXJkID0gY21zQ3JlYXRlVHJhbnNmb3JtVEhSKENvbnRleHRJRCwKKyAgICAgICAgaExhYiwgVFlQRV9MYWJfREJMLAorICAgICAgICBoR2FtdXQsIGR3Rm9ybWF0LAorICAgICAgICBJTlRFTlRfUkVMQVRJVkVfQ09MT1JJTUVUUklDLAorICAgICAgICBjbXNGTEFHU19OT0NBQ0hFKTsKKworICAgIC8vIERvZXMgY3JlYXRlIHRoZSBiYWNrd2FyZHMgc3RlcAorICAgIENoYWluLmhSZXZlcnNlID0gY21zQ3JlYXRlVHJhbnNmb3JtVEhSKENvbnRleHRJRCwgaEdhbXV0LCBkd0Zvcm1hdCwKKyAgICAgICAgaExhYiwgVFlQRV9MYWJfREJMLAorICAgICAgICBJTlRFTlRfUkVMQVRJVkVfQ09MT1JJTUVUUklDLAorICAgICAgICBjbXNGTEFHU19OT0NBQ0hFKTsKKworCisgICAgLy8gQWxsIG9rPworICAgIGlmIChDaGFpbi5oSW5wdXQgJiYgQ2hhaW4uaEZvcndhcmQgJiYgQ2hhaW4uaFJldmVyc2UpIHsKKworICAgICAgICAvLyBHbyBvbiwgdHJ5IHRvIGNvbXB1dGUgZ2FtdXQgTFVUIGZyb20gUENTLiBUaGlzIGNvbnNpc3Qgb24gYSBzaW5nbGUgY2hhbm5lbCBjb250YWluaW5nCisgICAgICAgIC8vIGRFIHdoZW4gZG9pbmcgYSB0cmFuc2Zvcm0gYmFjayBhbmQgZm9ydGggb24gdGhlIGNvbG9yaW1ldHJpYyBpbnRlbnQuCisKKyAgICAgICAgR2FtdXQgPSBjbXNQaXBlbGluZUFsbG9jKENvbnRleHRJRCwgMywgMSk7CisgICAgICAgIGlmIChHYW11dCAhPSBOVUxMKSB7CisKKyAgICAgICAgICAgIENMVVQgPSBjbXNTdGFnZUFsbG9jQ0x1dDE2Yml0KENvbnRleHRJRCwgbkdyaWRwb2ludHMsIG5DaGFubmVscywgMSwgTlVMTCk7CisgICAgICAgICAgICBpZiAoIWNtc1BpcGVsaW5lSW5zZXJ0U3RhZ2UoR2FtdXQsIGNtc0FUX0JFR0lOLCBDTFVUKSkgeworICAgICAgICAgICAgICAgIGNtc1BpcGVsaW5lRnJlZShHYW11dCk7CisgICAgICAgICAgICAgICAgR2FtdXQgPSBOVUxMOworICAgICAgICAgICAgfSAKKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIGNtc1N0YWdlU2FtcGxlQ0x1dDE2Yml0KENMVVQsIEdhbXV0U2FtcGxlciwgKHZvaWQqKSAmQ2hhaW4sIDApOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgR2FtdXQgPSBOVUxMOyAgIC8vIERpZG4ndCB3b3JrLi4uCisKKyAgICAvLyBGcmVlIGFsbCBuZWVkZWQgc3R1ZmYuCisgICAgaWYgKENoYWluLmhJbnB1dCkgICBjbXNEZWxldGVUcmFuc2Zvcm0oQ2hhaW4uaElucHV0KTsKKyAgICBpZiAoQ2hhaW4uaEZvcndhcmQpIGNtc0RlbGV0ZVRyYW5zZm9ybShDaGFpbi5oRm9yd2FyZCk7CisgICAgaWYgKENoYWluLmhSZXZlcnNlKSBjbXNEZWxldGVUcmFuc2Zvcm0oQ2hhaW4uaFJldmVyc2UpOworICAgIGlmIChoTGFiKSBjbXNDbG9zZVByb2ZpbGUoaExhYik7CisKKyAgICAvLyBBbmQgcmV0dXJuIGNvbXB1dGVkIGh1bGwKKyAgICByZXR1cm4gR2FtdXQ7Cit9CisKKy8vIFRvdGFsIEFyZWEgQ292ZXJhZ2UgZXN0aW1hdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3R5cGVkZWYgc3RydWN0IHsKKyAgICBjbXNVSW50MzJOdW1iZXIgIG5PdXRwdXRDaGFuczsKKyAgICBjbXNIVFJBTlNGT1JNICAgIGhSb3VuZFRyaXA7CisgICAgY21zRmxvYXQzMk51bWJlciBNYXhUQUM7CisgICAgY21zRmxvYXQzMk51bWJlciBNYXhJbnB1dFtjbXNNQVhDSEFOTkVMU107CisKK30gY21zVEFDZXN0aW1hdG9yOworCisKKy8vIFRoaXMgY2FsbGJhY2sganVzdCBhY2NvdW50cyB0aGUgbWF4aW11bSBpbmsgZHJvcHBlZCBpbiB0aGUgZ2l2ZW4gbm9kZS4gSXQgZG9lcyBub3QgcG9wdWxhdGUgYW55CisvLyBtZW1vcnksIGFzIHRoZSBkZXN0aW5hdGlvbiB0YWJsZSBpcyBOVUxMLiBJdHMgb25seSBwdXJwb3NlIGl0IHRvIGtub3cgdGhlIGdsb2JhbCBtYXhpbXVtLgorc3RhdGljCitpbnQgRXN0aW1hdGVUQUMocmVnaXN0ZXIgY29uc3QgY21zVUludDE2TnVtYmVyIEluW10sIHJlZ2lzdGVyIGNtc1VJbnQxNk51bWJlciBPdXRbXSwgcmVnaXN0ZXIgdm9pZCAqIENhcmdvKQoreworICAgIGNtc1RBQ2VzdGltYXRvciogYnAgPSAoY21zVEFDZXN0aW1hdG9yKikgQ2FyZ287CisgICAgY21zRmxvYXQzMk51bWJlciBSb3VuZFRyaXBbY21zTUFYQ0hBTk5FTFNdOworICAgIGNtc1VJbnQzMk51bWJlciBpOworICAgIGNtc0Zsb2F0MzJOdW1iZXIgU3VtOworCisKKyAgICAvLyBFdmFsdWF0ZSB0aGUgeGZvcm0KKyAgICBjbXNEb1RyYW5zZm9ybShicC0+aFJvdW5kVHJpcCwgSW4sIFJvdW5kVHJpcCwgMSk7CisKKyAgICAvLyBBbGwgYWxsIGFtb3VudHMgb2YgaW5rCisgICAgZm9yIChTdW09MCwgaT0wOyBpIDwgYnAgLT5uT3V0cHV0Q2hhbnM7IGkrKykKKyAgICAgICAgICAgIFN1bSArPSBSb3VuZFRyaXBbaV07CisKKyAgICAvLyBJZiBhYm92ZSBtYXhpbXVtLCBrZWVwIHRyYWNrIG9mIGlucHV0IHZhbHVlcworICAgIGlmIChTdW0gPiBicCAtPk1heFRBQykgeworCisgICAgICAgICAgICBicCAtPk1heFRBQyA9IFN1bTsKKworICAgICAgICAgICAgZm9yIChpPTA7IGkgPCBicCAtPm5PdXRwdXRDaGFuczsgaSsrKSB7CisgICAgICAgICAgICAgICAgYnAgLT5NYXhJbnB1dFtpXSA9IEluW2ldOworICAgICAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBUUlVFOworCisgICAgY21zVU5VU0VEX1BBUkFNRVRFUihPdXQpOworfQorCisKKy8vIERldGVjdCBUb3RhbCBhcmVhIGNvdmVyYWdlIG9mIHRoZSBwcm9maWxlCitjbXNGbG9hdDY0TnVtYmVyIENNU0VYUE9SVCBjbXNEZXRlY3RUQUMoY21zSFBST0ZJTEUgaFByb2ZpbGUpCit7CisgICAgY21zVEFDZXN0aW1hdG9yIGJwOworICAgIGNtc1VJbnQzMk51bWJlciBkd0Zvcm1hdHRlcjsKKyAgICBjbXNVSW50MzJOdW1iZXIgR3JpZFBvaW50c1tNQVhfSU5QVVRfRElNRU5TSU9OU107CisgICAgY21zSFBST0ZJTEUgaExhYjsKKyAgICBjbXNDb250ZXh0IENvbnRleHRJRCA9IGNtc0dldFByb2ZpbGVDb250ZXh0SUQoaFByb2ZpbGUpOworCisgICAgLy8gVEFDIG9ubHkgd29ya3Mgb24gb3V0cHV0IHByb2ZpbGVzCisgICAgaWYgKGNtc0dldERldmljZUNsYXNzKGhQcm9maWxlKSAhPSBjbXNTaWdPdXRwdXRDbGFzcykgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvLyBDcmVhdGUgYSBmYWtlIGZvcm1hdHRlciBmb3IgcmVzdWx0CisgICAgZHdGb3JtYXR0ZXIgPSBjbXNGb3JtYXR0ZXJGb3JDb2xvcnNwYWNlT2ZQcm9maWxlKGhQcm9maWxlLCA0LCBUUlVFKTsKKworICAgIGJwLm5PdXRwdXRDaGFucyA9IFRfQ0hBTk5FTFMoZHdGb3JtYXR0ZXIpOworICAgIGJwLk1heFRBQyA9IDA7ICAgIC8vIEluaXRpYWwgVEFDIGlzIDAKKworICAgIC8vICBmb3Igc2FmZXR5CisgICAgaWYgKGJwLm5PdXRwdXRDaGFucyA+PSBjbXNNQVhDSEFOTkVMUykgcmV0dXJuIDA7CisKKyAgICBoTGFiID0gY21zQ3JlYXRlTGFiNFByb2ZpbGVUSFIoQ29udGV4dElELCBOVUxMKTsKKyAgICBpZiAoaExhYiA9PSBOVUxMKSByZXR1cm4gMDsKKyAgICAvLyBTZXR1cCBhIHJvdW5kdHJpcCBvbiBwZXJjZXB0dWFsIGludGVudCBpbiBvdXRwdXQgcHJvZmlsZSBmb3IgVEFDIGVzdGltYXRpb24KKyAgICBicC5oUm91bmRUcmlwID0gY21zQ3JlYXRlVHJhbnNmb3JtVEhSKENvbnRleHRJRCwgaExhYiwgVFlQRV9MYWJfMTYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoUHJvZmlsZSwgZHdGb3JtYXR0ZXIsIElOVEVOVF9QRVJDRVBUVUFMLCBjbXNGTEFHU19OT09QVElNSVpFfGNtc0ZMQUdTX05PQ0FDSEUpOworCisgICAgY21zQ2xvc2VQcm9maWxlKGhMYWIpOworICAgIGlmIChicC5oUm91bmRUcmlwID09IE5VTEwpIHJldHVybiAwOworCisgICAgLy8gRm9yIEwqIHdlIG9ubHkgbmVlZCBibGFjayBhbmQgd2hpdGUuIEZvciBDKiB3ZSBuZWVkIG1hbnkgcG9pbnRzCisgICAgR3JpZFBvaW50c1swXSA9IDY7CisgICAgR3JpZFBvaW50c1sxXSA9IDc0OworICAgIEdyaWRQb2ludHNbMl0gPSA3NDsKKworCisgICAgaWYgKCFjbXNTbGljZVNwYWNlMTYoMywgR3JpZFBvaW50cywgRXN0aW1hdGVUQUMsICZicCkpIHsKKyAgICAgICAgYnAuTWF4VEFDID0gMDsKKyAgICB9CisKKyAgICBjbXNEZWxldGVUcmFuc2Zvcm0oYnAuaFJvdW5kVHJpcCk7CisKKyAgICAvLyBSZXN1bHRzIGluICUKKyAgICByZXR1cm4gYnAuTWF4VEFDOworfQorCisKKy8vIENhcmVmdWxseSwgIGNsYW1wIG9uIENJRUxhYiBzcGFjZS4KKworY21zQm9vbCBDTVNFWFBPUlQgY21zRGVzYXR1cmF0ZUxhYihjbXNDSUVMYWIqIExhYiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIGFtYXgsIGRvdWJsZSBhbWluLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgYm1heCwgZG91YmxlIGJtaW4pCit7CisKKyAgICAvLyBXaG9sZSBMdW1hIHN1cmZhY2UgdG8gemVybworCisgICAgaWYgKExhYiAtPiBMIDwgMCkgeworCisgICAgICAgIExhYi0+IEwgPSBMYWItPmEgPSBMYWItPiBiID0gMC4wOworICAgICAgICByZXR1cm4gRkFMU0U7CisgICAgfQorCisgICAgLy8gQ2xhbXAgd2hpdGUsIERJU0NBUkQgSElHSExJR0hUUy4gVGhpcyBpcyBkb25lCisgICAgLy8gaW4gc3VjaCB3YXkgYmVjYXVzZSBpY2Mgc3BlYyBkb2Vzbid0IGFsbG93IHRoZQorICAgIC8vIHVzZSBvZiBMPjEwMCBhcyBhIGhpZ2hsaWdodCBtZWFucy4KKworICAgIGlmIChMYWItPkwgPiAxMDApCisgICAgICAgIExhYiAtPiBMID0gMTAwOworCisgICAgLy8gQ2hlY2sgb3V0IGdhbXV0IHByaXNtLCBvbiBhLCBiIGZhY2VzCisKKyAgICBpZiAoTGFiIC0+IGEgPCBhbWluIHx8IExhYi0+YSA+IGFtYXh8fAorICAgICAgICBMYWIgLT4gYiA8IGJtaW4gfHwgTGFiLT5iID4gYm1heCkgeworCisgICAgICAgICAgICBjbXNDSUVMQ2ggTENoOworICAgICAgICAgICAgZG91YmxlIGgsIHNsb3BlOworCisgICAgICAgICAgICAvLyBGYWxscyBvdXRzaWRlIGEsIGIgbGltaXRzLiBUcmFuc3BvcnRzIHRvIExDaCBzcGFjZSwKKyAgICAgICAgICAgIC8vIGFuZCB0aGVuIGRvIHRoZSBjbGlwcGluZworCisKKyAgICAgICAgICAgIGlmIChMYWIgLT4gYSA9PSAwLjApIHsgLy8gSXMgaHVlIGV4YWN0bHkgOTA/CisKKyAgICAgICAgICAgICAgICAvLyBhdGFuIHdpbGwgbm90IHdvcmssIHNvIGNsYW1wIGhlcmUKKyAgICAgICAgICAgICAgICBMYWIgLT4gYiA9IExhYi0+YiA8IDAgPyBibWluIDogYm1heDsKKyAgICAgICAgICAgICAgICByZXR1cm4gVFJVRTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY21zTGFiMkxDaCgmTENoLCBMYWIpOworCisgICAgICAgICAgICBzbG9wZSA9IExhYiAtPiBiIC8gTGFiIC0+IGE7CisgICAgICAgICAgICBoID0gTENoLmg7CisKKyAgICAgICAgICAgIC8vIFRoZXJlIGFyZSA0IHpvbmVzCisKKyAgICAgICAgICAgIGlmICgoaCA+PSAwLiAmJiBoIDwgNDUuKSB8fAorICAgICAgICAgICAgICAgIChoID49IDMxNSAmJiBoIDw9IDM2MC4pKSB7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gY2xpcCBieSBhbWF4CisgICAgICAgICAgICAgICAgICAgIExhYiAtPiBhID0gYW1heDsKKyAgICAgICAgICAgICAgICAgICAgTGFiIC0+IGIgPSBhbWF4ICogc2xvcGU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgaWYgKGggPj0gNDUuICYmIGggPCAxMzUuKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gY2xpcCBieSBibWF4CisgICAgICAgICAgICAgICAgICAgIExhYiAtPiBiID0gYm1heDsKKyAgICAgICAgICAgICAgICAgICAgTGFiIC0+IGEgPSBibWF4IC8gc2xvcGU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgaWYgKGggPj0gMTM1LiAmJiBoIDwgMjI1LikgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2xpcCBieSBhbWluCisgICAgICAgICAgICAgICAgICAgICAgICBMYWIgLT4gYSA9IGFtaW47CisgICAgICAgICAgICAgICAgICAgICAgICBMYWIgLT4gYiA9IGFtaW4gKiBzbG9wZTsKKworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoID49IDIyNS4gJiYgaCA8IDMxNS4pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjbGlwIGJ5IGJtaW4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYWIgLT4gYiA9IGJtaW47CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGFiIC0+IGEgPSBibWluIC8gc2xvcGU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBlbHNlICB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zU2lnbmFsRXJyb3IoMCwgY21zRVJST1JfUkFOR0UsICJJbnZhbGlkIGFuZ2xlIik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgfQorCisgICAgcmV0dXJuIFRSVUU7Cit9Cg==