LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIENvcHlyaWdodCAoQykgMTk5Ni0xOTk5LCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqCiogRmlsZSB0Ymxjb2xsLmNwcAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCiogIDIvNS85NyAgICAgIGFsaXUgICAgICAgIEFkZGVkIHN0cmVhbUluIGFuZCBzdHJlYW1PdXQgbWV0aG9kcy4gIEFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIHdoaWNoIHJlYWRzIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdCBmcm9tCiogICAgICAgICAgICAgICAgICAgICAgICAgIGEgYmluYXJ5IGZpbGUuICBBZGRlZCB3cml0ZVRvRmlsZSBtZXRob2Qgd2hpY2ggc3RyZWFtcwoqICAgICAgICAgICAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciBvdXQgdG8gYSBiaW5hcnkgZmlsZS4gIFRoZSBzdHJlYW1JbgoqICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgc3RyZWFtT3V0IG1ldGhvZHMgdXNlIGlzdHJlYW0gYW5kIG9zdHJlYW0gb2JqZWN0cwoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbiBiaW5hcnkgbW9kZS4KKiAgMi8xMS85NyAgICAgYWxpdSAgICAgICAgTW92ZWQgZGVjbGFyYXRpb25zIG91dCBvZiBmb3IgbG9vcCBpbml0aWFsaXplci4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgTWFjIGNvbXBhdGliaWxpdHkgI2lmZGVmIGZvciBpb3M6Om5vY3JlYXRlLgoqICAyLzEyLzk3ICAgICBhbGl1ICAgICAgICBNb2RpZmllZCB0byB1c2UgVGFibGVDb2xsYXRpb25EYXRhIHN1Yi1vYmplY3QgdG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgaG9sZCBpbnZhcmlhbnQgZGF0YS4KKiAgMi8xMy85NyAgICAgYWxpdSAgICAgICAgTW92ZWQgc2V2ZXJhbCBtZXRob2RzIGludG8gdGhpcyBjbGFzcyBmcm9tIENvbGxhdGlvbi4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgYSBwcml2YXRlIFJ1bGVCYXNlZENvbGxhdG9yKExvY2FsZSYpIGNvbnN0cnVjdG9yLAoqICAgICAgICAgICAgICAgICAgICAgICAgICB0byBiZSB1c2VkIGJ5IENvbGxhdG9yOjpnZXRJbnN0YW5jZSgpLiAgR2VuZXJhbAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhbiB1cC4gIE1hZGUgdXNlIG9mIFVFcnJvckNvZGUgdmFyaWFibGVzIGNvbnNpc3RlbnQuCiogIDIvMjAvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNsb25lLCBvcGVyYXRvcj09LCBvcGVyYXRvciE9LCBvcGVyYXRvcj0sIGFuZCBjb3B5CiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIGFuZCBnZXREeW5hbWljQ2xhc3NJRC4KKiAgMy81Lzk3ICAgICAgYWxpdSAgICAgICAgQ2hhbmdlZCBjb21wYWN0aW9uIGN5Y2xlIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UuICBXZQoqICAgICAgICAgICAgICAgICAgICAgICAgICB1c2UgdGhlIG1heGltdW0gYWxsb3dhYmxlIHZhbHVlIHdoaWNoIGlzIGtCbG9ja0NvdW50LgoqICAgICAgICAgICAgICAgICAgICAgICAgICBNb2RpZmllZCBnZXRSdWxlcygpIHRvIGxvYWQgcnVsZXMgZHluYW1pY2FsbHkuICBDaGFuZ2VkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdEZyb21GaWxlKCkgY2FsbCB0byBhY2NvbW9kYXRlIHRoaXMgKGFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlciB0byBzcGVjaWZ5IHdoZXRoZXIgYmluYXJ5IGxvYWRpbmcgaXMgdG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGFrZSBwbGFjZSkuCiogMDUvMDYvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIG1lbW9yeSBhbGxvY2F0aW9uIGVycm9yIGNoZWNrLgoqICA2LzIwLzk3ICAgICBoZWxlbmEgICAgICBKYXZhIGNsYXNzIG5hbWUgY2hhbmdlLgoqICA2LzIzLzk3ICAgICBoZWxlbmEgICAgICBBZGRpbmcgY29tbWVudHMgdG8gbWFrZSBjb2RlIG1vcmUgcmVhZGFibGUuCiogMDkvMDMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNyZWF0ZUNvbGxhdGlvbktleVZhbHVlcygpLgoqIDA2LzI2Lzk4ICAgICBlcm0gICAgICAgICBDaGFuZ2VzIGZvciBDb2xsYXRpb25LZXlzIHVzaW5nIGJ5dGUgYXJyYXlzLgoqIDA4LzEwLzk4ICAgICBlcm0gICAgICAgICBTeW5jaGVkIHdpdGggMS4yIHZlcnNpb24gb2YgUnVsZUJhc2VkQ29sbGF0b3IuamF2YQoqIDA0LzIzLzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIEVEZWNvbXBvc2l0aW9uTW9kZSwgbWVyZ2VkIHdpdGgKKiAgICAgICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUKKiAwNi8xNC85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBrUmVzb3VyY2VCdW5kbGVTdWZmaXgKKiAwNi8yMi85OSAgICAgc3RlcGhlbiAgICAgRml4ZWQgbG9naWMgaW4gY29uc3RydWN0RnJvbUZpbGUoKSBzaW5jZSAuY3R4CiogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzIGFyZSBubyBsb25nZXIgdXNlZC4KKiAxMS8wMi85OSAgICAgaGVsZW5hICAgICAgQ29sbGF0b3IgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiAgU3BlY2lhbCBjYXNlCiogICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBOT19PUCBzaXR1YXRpb25zLiAKKiAxMS8xNy85OSAgICAgc3JsICAgICAgICAgTW9yZSBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuIElubGluZWQgc29tZSBpbnRlcm5hbCBmdW5jdGlvbnMuCiogMTIvMTUvOTkgICAgIGFsaXUgICAgICAgIFVwZGF0ZSB0byBzdXBwb3J0IFRoYWkgY29sbGF0aW9uLiAgTW92ZSBOb3JtYWxpemVySXRlcmF0b3IKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gaW1wbGVtZW50YXRpb24gZmlsZS4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKI2luY2x1ZGUgInVjbXAzMi5oIgojaW5jbHVkZSAidGNvbGRhdGEuaCIKCiNpbmNsdWRlICJ1bmljb2RlL3RibGNvbGwuaCIKCiNpbmNsdWRlICJ1bmljb2RlL2NvbGVpdHIuaCIKI2luY2x1ZGUgInVuaWNvZGUvbG9jaWQuaCIKI2luY2x1ZGUgInVuaWNvZGUvdW5pY29kZS5oIgojaW5jbHVkZSAidGFibGVzLmgiCiNpbmNsdWRlICJ1bmljb2RlL25vcm1senIuaCIKI2luY2x1ZGUgIm1lcmdlY29sLmgiCiNpbmNsdWRlICJ1bmljb2RlL3Jlc2J1bmQuaCIKI2luY2x1ZGUgImZpbGVzdHJtLmgiCiNpbmNsdWRlICJ1bWVtc3RybS5oIgoKI2lmZGVmIF9ERUJVRwojaW5jbHVkZSAidW5pc3RybS5oIgojZW5kaWYKCiNpbmNsdWRlICJjb21waXRyLmgiCgojaW5jbHVkZSA8c3RyaW5nLmg+CgojaW5jbHVkZSAidW5pY29kZS91c3RyaW5nLmgiCgojaW5jbHVkZSAiY21lbW9yeS5oIgoKY29uc3QgdWludDMyX3QgdGJsY29sbF9TdGFja0J1ZmZlckxlbiA9IDEwMjQ7CgpjbGFzcyBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyCnsKcHVibGljOgogICBzdGF0aWMgdm9pZCBzdHJlYW1JbihSdWxlQmFzZWRDb2xsYXRvciogY29sbGF0b3IsIEZpbGVTdHJlYW0qIGlzKTsKICAgc3RhdGljIHZvaWQgc3RyZWFtT3V0KGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yKiBjb2xsYXRvciwgRmlsZVN0cmVhbSogb3MpOwogICBzdGF0aWMgdm9pZCBzdHJlYW1JbihSdWxlQmFzZWRDb2xsYXRvciogY29sbGF0b3IsIFVNZW1vcnlTdHJlYW0qIGlzLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwogICBzdGF0aWMgdm9pZCBzdHJlYW1PdXQoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBVTWVtb3J5U3RyZWFtKiBvcyk7Cn07CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gIFRoZSBmb2xsb3dpbmcgZGlhZ3JhbSBzaG93cyB0aGUgZGF0YSBzdHJ1Y3R1cmUgb2YgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdC4KLy8gIFN1cHBvc2Ugd2UgaGF2ZSB0aGUgcnVsZSwgd2hlcmUgJ28tdW1sYXV0JyBpcyB0aGUgdW5pY29kZSBjaGFyIDB4MDBGNi4KLy8gICJhLCBBIDwgYiwgQiA8IGMsIEMsIGNoLCBjSCwgQ2gsIENIIDwgZCwgRCAuLi4gPCBvLCBPOyAnby11bWxhdXQnL0UsICdPLXVtbGF1dCcvRSAuLi4iLgovLyAgV2hhdCB0aGUgcnVsZSBzYXlzIGlzLCBzb3J0cyAnY2gnbGlnYXR1cmVzIGFuZCAnYycgb25seSB3aXRoIHRlcnRpYXJ5IGRpZmZlcmVuY2UgYW5kCi8vICBzb3J0cyAnby11bWxhdXQnIGFzIGlmIGl0J3MgYWx3YXlzIGV4cGFuZGVkIHdpdGggJ2UnLgovLwovLyBtYXBwaW5nIHRhYmxlICAgICAgICAgICAgICAgICAgICAgICBjb250cmFjdGluZyBsaXN0ICAgICAgICAgICAgICAgICAgZXhwYW5kaW5nIGxpc3QKLy8gKGNvbnRhaW5zIGFsbCB1bmljb2RlIGNoYXIKLy8gIGVudHJpZXMpICAgICAgICAgICAgICAgICAgICAgICAgIF9fXyAgICAgX19fX19fX19fX19fXyAgICAgICAgIF9fX19fX19fX19fX19fX19fX19fX19fX18KLy8gICBfX19fX19fXyAgICAgICAgICAgICAgICAgICB8PT0+fF8qX3wtLT58J2MnICB8dignYycpIHwgICB8PT0+fHYoJ28nKXx2KCd1bWxhdXQnKXx2KCdlJyl8Ci8vICB8X1x1MDAwMV98LS0+IHYoJ1x1MDAwMScpICAgfCAgIHxfOl98ICAgfC0tLS0tLS0tLS0tLS18ICAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAovLyAgfF9cdTAwMDJffC0tPiB2KCdcdTAwMDInKSAgIHwgICB8XzpffCAgIHwnY2gnIHx2KCdjaCcpfCAgIHwgICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKLy8gIHxfX19fOl9fX3wgICAgICAgICAgICAgICAgICB8ICAgfF86X3wgICB8LS0tLS0tLS0tLS0tLXwgICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgfCdjSCcgfHYoJ2NIJyl8ICAgfCAgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAovLyAgfF9fJ2EnX19ffC0tPiB2KCdhJykgICAgICAgIHwgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tfCAgIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKLy8gIHxfXydiJ19fX3wtLT4gdignYicpICAgICAgICB8ICAgICAgICAgICB8J0NoJyB8dignQ2gnKXwgICB8ICAgfCAgICAgICAgICAgICA6ICAgICAgICAgICB8Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgfC0tLS0tLS0tLS0tLS18ICAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAovLyAgfF9fX186X19ffCAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgIHwnQ0gnIHx2KCdDSCcpfCAgIHwgICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKLy8gIHxfX18nYydfX3wtLS0tLS0tLS0tLS0tLS0tLS0tICAgICAgICAgICAgLS0tLS0tLS0tLS0tLSAgICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAovLyAgfG8tdW1sYXV0fC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgICB8X19fX19fX19fX19fX19fX19fX19fX19fX3wKLy8gIHxfX19fOl9fX3wKLy8KLy8KLy8gTm90ZWQgYnkgSGVsZW5hIFNoaWggb24gNi8yMy85NyB3aXRoIHBlbmRpbmcgZGVzaWduIGNoYW5nZXMgKHNsaW1taW5nIGNvbGxhdGlvbikuCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkNIQVJJTkRFWCA9IDB4NzAwMDAwMDA7ICAgICAgICAgICAgIC8vIG5lZWQgbG9vayB1cCBpbiAuY29tbWl0KCkKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6RVhQQU5EQ0hBUklOREVYID0gMHg3RTAwMDAwMDsgICAgICAgLy8gRXhwYW5kIGluZGV4IGZvbGxvd3MKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Q09OVFJBQ1RDSEFSSU5ERVggPSAweDdGMDAwMDAwOyAgICAgLy8gY29udHJhY3QgaW5kZXhlcyBmb2xsb3dzCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlVOTUFQUEVEID0gMHhGRkZGRkZGRjsgICAgICAgICAgICAgIC8vIHVubWFwcGVkIGNoYXJhY3RlciB2YWx1ZXMKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAxMDAwMDsgLy8gcHJpbWFyeSBzdHJlbmd0aCBpbmNyZW1lbnQKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJJTkNSRU1FTlQgPSAweDAwMDAwMTAwOyAvLyBzZWNvbmRhcnkgc3RyZW5ndGggaW5jcmVtZW50CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJJTkNSRU1FTlQgPSAweDAwMDAwMDAxOyAvLyB0ZXJ0aWFyeSBzdHJlbmd0aCBpbmNyZW1lbnQKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6TUFYSUdOT1JBQkxFID0gMHgwMDAxMDAwMDsgICAgICAgICAgLy8gbWF4aW11bSBpZ25vcmFibGUgY2hhciBvcmRlciB2YWx1ZQpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJNQVNLID0gMHhmZmZmMDAwMDsgICAgICAvLyBtYXNrIG9mZiBhbnl0aGluZyBidXQgcHJpbWFyeSBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUk1BU0sgPSAweDAwMDBmZjAwOyAgICAvLyBtYXNrIG9mZiBhbnl0aGluZyBidXQgc2Vjb25kYXJ5IG9yZGVyCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJNQVNLID0gMHgwMDAwMDBmZjsgICAgIC8vIG1hc2sgb2ZmIGFueXRoaW5nIGJ1dCB0ZXJ0aWFyeSBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllSRVNFVE1BU0sgPSAweDAwMDBmZmZmOyAgICAvLyBtYXNrIG9mZiBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IG9yZGVyCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OklHTk9SQUJMRU1BU0sgPSAweDAwMDBmZmZmOyAgICAgICAgIC8vIG1hc2sgb2ZmIGlnbm9yYWJsZSBjaGFyIG9yZGVyCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllESUZGRVJFTkNFT05MWSA9IDB4ZmZmZjAwMDA7IC8vIHVzZSBvbmx5IHRoZSBwcmltYXJ5IGRpZmZlcmVuY2UKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZRElGRkVSRU5DRU9OTFkgPSAweGZmZmZmZjAwOyAgLy8gdXNlIG9ubHkgdGhlIHByaW1hcnkgYW5kIHNlY29uZGFyeSBkaWZmZXJlbmNlCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllPUkRFUlNISUZUID0gMTY7ICAgICAgICAgICAgIC8vIHByaW1hcnkgb3JkZXIgc2hpZnQKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJTSElGVCA9IDg7ICAgICAgICAgICAgLy8gc2Vjb25kYXJ5IG9yZGVyIHNoaWZ0CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNPUlRLRVlPRkZTRVQgPSAxOyAgICAgICAgICAgICAgICAgIC8vIG1pbmltdW0gc29ydCBrZXkgb2Zmc2V0CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkNPTlRSQUNUQ0hBUk9WRVJGTE9XID0gMHg3RkZGRkZGRjsgIC8vIEluZGljYXRlcyB0aGUgY2hhciBpcyBhIGNvbnRyYWN0IGNoYXIKCmNvbnN0IGludDE2X3QgUnVsZUJhc2VkQ29sbGF0b3I6OkZJTEVJRCA9IDB4NTQ0MzsgICAgICAgICAgICAgICAgICAgIC8vIHVuaXF1ZSBmaWxlIGlkIGZvciBwYXJpdHkgY2hlY2sKY29uc3QgY2hhciogUnVsZUJhc2VkQ29sbGF0b3I6OmtGaWxlbmFtZVN1ZmZpeCA9ICIuY29sIjsgICAgICAgICAgICAgLy8gYmluYXJ5IGNvbGxhdGlvbiBmaWxlIGV4dGVuc2lvbgpjaGFyICBSdWxlQmFzZWRDb2xsYXRvcjo6ZmdDbGFzc0lEID0gMDsgLy8gVmFsdWUgaXMgaXJyZWxldmFudCAgICAgICAvLyBjbGFzcyBpZAoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIE5vcm1hbGl6ZXJJdGVyYXRvcgovLwovLyBUaGlzIGNsYXNzIGlzIGVzc2VudGlhbGx5IGEgZHVwbGljYXRlIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciwKLy8gc3RyaXBwZWQgZG93biBmb3Igc3BlZWQuICBJdCBpcyBkZWNsYXJlZCBoZXJlIHNvIHdlIGNhbiBpbmNvcnBvcmF0ZQovLyBpbnRlcm5hbCBjbGFzc2VzIGFzIHN1Ym9iamVjdHMsIGFzIHdlbGwgYXMganVzdCB0byBoaWRlIGl0IGZyb20gdGhlCi8vIHB1YmxpYyBpbnRlcmZhY2UuCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKLyogSW50ZXJuYWwgY2xhc3MgZm9yIHF1aWNrIGl0ZXJhdGlvbiBvdmVyIHRoZSB0ZXh0LgogICAxMDAlIHB1cmUgaW5saW5lIGNvZGUKKi8KY2xhc3MgTm9ybWFsaXplckl0ZXJhdG9yIHsgCnB1YmxpYzoKICAgIE5vcm1hbGl6ZXIgKmN1cnNvcjsKICAgIFZlY3Rvck9mSW50ICpidWZmZXJBbGlhczsKICAgIFZlY3Rvck9mSW50ICpyZW9yZGVyQnVmZmVyOwogICAgVmVjdG9yT2ZJbnQgb3duQnVmZmVyOwogICAgVUNoYXIqICAgICAgdGV4dDsKICAgIGludDMyX3QgICAgIGV4cEluZGV4OwogICAgaW50MzJfdCAgICAgdGV4dExlbjsKICAgIFVUZXh0T2Zmc2V0ICBjdXJyZW50T2Zmc2V0OwogICAgCiAgICBOb3JtYWxpemVySXRlcmF0b3Iodm9pZCk7CiAgICBOb3JtYWxpemVySXRlcmF0b3IoY29uc3QgVUNoYXIqIHNvdXJjZSwgaW50MzJfdCBsZW5ndGgsIE5vcm1hbGl6ZXI6OkVNb2RlIG1vZGUpOwogICAgfk5vcm1hbGl6ZXJJdGVyYXRvcih2b2lkKTsKICAgIHZvaWQgc2V0VGV4dChjb25zdCBVQ2hhciogc291cmNlLCBpbnQzMl90IGxlbmd0aCwgVUVycm9yQ29kZSYgc3RhdHVzKTsKICAgIHZvaWQgc2V0TW9kZUFuZFRleHQoTm9ybWFsaXplcjo6RU1vZGUgbW9kZSwgY29uc3QgVUNoYXIqIHNvdXJjZSwgaW50MzJfdCBsZW5ndGgsIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgICAKICAgIFVDaGFyIGN1cnJlbnQodm9pZCkgY29uc3Q7CiAgICBVQ2hhciBuZXh0KHZvaWQpOwogICAgdm9pZCByZXNldCh2b2lkKTsKfTsKCmlubGluZQpOb3JtYWxpemVySXRlcmF0b3I6Ok5vcm1hbGl6ZXJJdGVyYXRvcigpIDoKICAgIGN1cnNvcigwKSwKICAgIGJ1ZmZlckFsaWFzKDApLAogICAgcmVvcmRlckJ1ZmZlcigwKSwKICAgIG93bkJ1ZmZlcigyKSwKICAgIHRleHQoMCksCiAgICBleHBJbmRleCgwKSwKICAgIHRleHRMZW4oMCksCiAgICBjdXJyZW50T2Zmc2V0KDApCnsKfQoKaW5saW5lCk5vcm1hbGl6ZXJJdGVyYXRvcjo6Tm9ybWFsaXplckl0ZXJhdG9yKGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3QgbGVuZ3RoLCBOb3JtYWxpemVyOjpFTW9kZSBtb2RlKSA6CiAgICBjdXJzb3IoMCksCiAgICBidWZmZXJBbGlhcygwKSwKICAgIHJlb3JkZXJCdWZmZXIoMCksCiAgICBvd25CdWZmZXIoMiksCiAgICB0ZXh0KDApLAogICAgZXhwSW5kZXgoMCksCiAgICB0ZXh0TGVuKDApLAogICAgY3VycmVudE9mZnNldCgwKQp7CiAgICBpZiAobW9kZSA9PSBOb3JtYWxpemVyOjpOT19PUCkgewogICAgICAgIHRleHQgPSAoVUNoYXIqKXNvdXJjZTsKICAgICAgICB0ZXh0TGVuID0gbGVuZ3RoOwogICAgICAgIGN1cnJlbnRPZmZzZXQgPSAwOwogICAgfSBlbHNlIHsKICAgICAgICBjdXJzb3IgPSBuZXcgTm9ybWFsaXplcihzb3VyY2UsIGxlbmd0aCwgbW9kZSk7CgogICAgfQp9CgppbmxpbmUKTm9ybWFsaXplckl0ZXJhdG9yOjp+Tm9ybWFsaXplckl0ZXJhdG9yKCkgCnsKICAgIGlmIChjdXJzb3IgIT0gMCkgewogICAgICAgIGRlbGV0ZSBjdXJzb3I7CiAgICAgICAgY3Vyc29yID0gMDsKICAgIH0KICAgIGlmIChyZW9yZGVyQnVmZmVyICE9IDApIHsKICAgICAgICBkZWxldGUgcmVvcmRlckJ1ZmZlcjsKICAgIH0KfQoKaW5saW5lCnZvaWQKTm9ybWFsaXplckl0ZXJhdG9yOjpzZXRUZXh0KGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3QgbGVuZ3RoLCBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmIChjdXJzb3IgPT0gMCkgewogICAgICAgIHRleHQgPSAoVUNoYXIqKXNvdXJjZTsKICAgICAgICB0ZXh0TGVuID0gbGVuZ3RoOwogICAgICAgIGN1cnJlbnRPZmZzZXQgPSAwOwoKICAgIH0gZWxzZSB7CiAgICAgICAgdGV4dCA9IDA7CiAgICAgICAgY3Vyc29yLT5zZXRUZXh0KHNvdXJjZSwgbGVuZ3RoLCBzdGF0dXMpOwogICAgfQogICAgYnVmZmVyQWxpYXMgPSAwOwogICAgY3VycmVudE9mZnNldCA9IDA7Cn0KCi8qIFlvdSBjYW4gb25seSBzZXQgbW9kZSBhZnRlciB0aGUgY29tcGFyaXNpb24gb2YgdHdvIHN0cmluZ3MgaXMgY29tcGxldGVkLgogICBTZXR0aW5nIHRoZSBtb2RlIGluIHRoZSBtaWRkbGUgb2YgYSBjb21wYXJpc29uIGlzIG5vdCBhbGxvd2VkLgogICAqLwppbmxpbmUKdm9pZAoKTm9ybWFsaXplckl0ZXJhdG9yOjpzZXRNb2RlQW5kVGV4dChOb3JtYWxpemVyOjpFTW9kZSBtb2RlLCBjb25zdCBVQ2hhciogc291cmNlLCBpbnQzMl90IGxlbmd0aCwgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICBpZihtb2RlICE9IE5vcm1hbGl6ZXI6Ok5PX09QKQogICAgewogICAgICAgIC8qIERPIGhhdmUgYSBtb2RlIC0gIHdpbGwgbmVlZCBhIG5vcm1hbGl6ZXIgb2JqZWN0ICovCiAgICAgICAgaWYoY3Vyc29yICE9IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICAvKiBKdXN0IG1vZGlmeSB0aGUgZXhpc3RpbmcgY3Vyc29yICovCiAgICAgICAgICAgIGN1cnNvci0+c2V0TW9kZShtb2RlKTsKICAgICAgICAgICAgY3Vyc29yLT5zZXRUZXh0KHNvdXJjZSwgbGVuZ3RoLCBzdGF0dXMpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBjdXJzb3IgPSBuZXcgTm9ybWFsaXplcihzb3VyY2UsIGxlbmd0aCwgbW9kZSk7CiAgICAgICAgfQoKICAgICAgICAvKiBSRVNFVCB0aGUgb2xkIGRhdGEgKi8KICAgICAgICB0ZXh0ID0gMDsKICAgICAgICB0ZXh0TGVuID0gMDsKICAgIH0KICAgIGVsc2UgCiAgICB7CiAgICAgICAgLyogTk9fT1AgbW9kZS4uICovCiAgICAgICAgaWYoY3Vyc29yICE9IE5VTEwpCiAgICAgICAgeyAvKiBnZXQgcmlkIG9mIHRoZSBvbGQgY3Vyc29yICovCiAgICAgICAgICAgIGRlbGV0ZSBjdXJzb3I7IAogICAgICAgICAgICBjdXJzb3IgPSAwOwogICAgICAgIH0KCiAgICAgICAgdGV4dCA9IChVQ2hhciopc291cmNlOwogICAgICAgIHRleHRMZW4gPSBsZW5ndGg7CiAgICB9CiAgICBjdXJyZW50T2Zmc2V0ID0gMDsgLyogYWx3YXlzICovCiAgIAogICAgYnVmZmVyQWxpYXMgPSAwOwp9CgppbmxpbmUKVUNoYXIKTm9ybWFsaXplckl0ZXJhdG9yOjpjdXJyZW50KHZvaWQpIGNvbnN0CnsKICAgIGlmICh0ZXh0ICE9IDApIHsKICAgICAgICBpZihjdXJyZW50T2Zmc2V0ID49IHRleHRMZW4pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gTm9ybWFsaXplcjo6RE9ORTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRleHRbY3VycmVudE9mZnNldF07CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAoVUNoYXIpY3Vyc29yLT5jdXJyZW50KCk7Cn0KCgppbmxpbmUKVUNoYXIKTm9ybWFsaXplckl0ZXJhdG9yOjpuZXh0KHZvaWQpCnsKICAgIGlmICh0ZXh0ICE9IDApIHsKICAgICAgICByZXR1cm4gKFVDaGFyKSgoY3VycmVudE9mZnNldCA8IHRleHRMZW4pID8gdGV4dFsrK2N1cnJlbnRPZmZzZXRdIDogTm9ybWFsaXplcjo6RE9ORSk7CiAgICB9CiAgICByZXR1cm4gKFVDaGFyKWN1cnNvci0+bmV4dCgpOwp9CgppbmxpbmUKdm9pZApOb3JtYWxpemVySXRlcmF0b3I6OnJlc2V0KHZvaWQpCnsKICAgIGN1cnJlbnRPZmZzZXQgPSAwOwogICAgaWYoY3Vyc29yKQogICAgewogICAgICAgIGN1cnNvci0+cmVzZXQoKTsKICAgIH0KfQoKLy89PT09PT09PT09PT09PT09IFNvbWUgaW5saW5lIGRlZmluaXRpb25zIG9mIGltcGxlbWVudGF0aW9uIGZ1bmN0aW9ucy4uLi4uLi4uID09PT09PT09Ci8qKgogKiBBIGNsb25lIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bWFrZVJlb3JkZXJlZEJ1ZmZlciwgdHJpbW1lZCBkb3duCiAqIHRvIG9ubHkgaGFuZGxlIGZvcndhcmQuCiAqLwppbmxpbmUgVmVjdG9yT2ZJbnQqClJ1bGVCYXNlZENvbGxhdG9yOjptYWtlUmVvcmRlcmVkQnVmZmVyKE5vcm1hbGl6ZXJJdGVyYXRvciogY3Vyc29yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ2hhciBjb2xGaXJzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsYXN0VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3Rvck9mSW50KiBsYXN0RXhwYW5zaW9uKSBjb25zdCB7CiAgICBWZWN0b3JPZkludCogcmVzdWx0OwoKICAgIGludDMyX3QgZmlyc3RWYWx1ZSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY29sRmlyc3QpOwogICAgaWYgKGZpcnN0VmFsdWUgPj0gQ09OVFJBQ1RDSEFSSU5ERVgpIHsKICAgICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAgICBmaXJzdFZhbHVlID0gbmV4dENvbnRyYWN0Q2hhcihjdXJzb3IsIGNvbEZpcnN0LCBzdGF0dXMpOwogICAgfQoKICAgIFZlY3Rvck9mSW50KiBmaXJzdEV4cGFuc2lvbiA9IE5VTEw7CiAgICBpZiAoZmlyc3RWYWx1ZSA+PSBFWFBBTkRDSEFSSU5ERVgpIHsKICAgICAgICBmaXJzdEV4cGFuc2lvbiA9IGdldEV4cGFuZFZhbHVlTGlzdChmaXJzdFZhbHVlKTsKICAgIH0KCiAgICBpZiAoZmlyc3RFeHBhbnNpb24gPT0gTlVMTCAmJiBsYXN0RXhwYW5zaW9uID09IE5VTEwpIHsKICAgICAgICBjdXJzb3ItPm93bkJ1ZmZlci5hdCgwKSA9IGZpcnN0VmFsdWU7CiAgICAgICAgY3Vyc29yLT5vd25CdWZmZXIuYXQoMSkgPSBsYXN0VmFsdWU7CiAgICAgICAgcmVzdWx0ID0gJmN1cnNvci0+b3duQnVmZmVyOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgaW50MzJfdCBmaXJzdExlbmd0aCA9IGZpcnN0RXhwYW5zaW9uPT1OVUxMPyAxIDogZmlyc3RFeHBhbnNpb24tPnNpemUoKTsKICAgICAgICBpbnQzMl90IGxhc3RMZW5ndGggPSBsYXN0RXhwYW5zaW9uPT1OVUxMPyAxIDogbGFzdEV4cGFuc2lvbi0+c2l6ZSgpOwogICAgICAgIGlmIChjdXJzb3ItPnJlb3JkZXJCdWZmZXIgPT0gTlVMTCkgewogICAgICAgICAgICBjdXJzb3ItPnJlb3JkZXJCdWZmZXIgPSBuZXcgVmVjdG9yT2ZJbnQoZmlyc3RMZW5ndGgrbGFzdExlbmd0aCk7CiAgICAgICAgfQogICAgICAgIC8vIHJlb3JkZXJkQnVmZmVyIGdldHMgcmV1c2VkIGZvciB0aGUgbGlmZSBvZiB0aGlzIG9iamVjdC4KICAgICAgICAvLyBTaW5jZSBpdHMgaW50ZXJuYWwgYnVmZmVyIG9ubHkgZ3Jvd3MsIHRoZXJlIGlzIGEgZGFuZ2VyCiAgICAgICAgLy8gdGhhdCBpdCB3aWxsIGdldCByZWFsbHksIHJlYWxseSBiaWcsIGFuZCBuZXZlciBzaHJpbmsuICBJZgogICAgICAgIC8vIHRoaXMgaXMgYWN0dWFsbHkgaGFwcGVuaW5nLCBpbnNlcnQgY29kZSBoZXJlIHRvIGNoZWNrIGZvcgogICAgICAgIC8vIHRoZSBjb25kaXRpb24uICBTb21ldGhpbmcgYWxvbmcgdGhlIGxpbmVzIG9mOgogICAgICAgIC8vISBlbHNlIGlmIChyZW9yZGVyQnVmZmVyLT5zaXplKCkgPj0gMjU2ICYmCiAgICAgICAgLy8hICAgICAgICAgIChmaXJzdExlbmd0aCtsYXN0TGVuZ3RoKSA8IDE2KSB7CiAgICAgICAgLy8hICAgICBkZWxldGUgcmVvcmRlckJ1ZmZlcjsKICAgICAgICAvLyEgICAgIHJlb3JkZXJCdWZmZXIgPSBuZXcgVmVjdG9yT2ZJbnQoZmlyc3RMZW5ndGgrbGFzdExlbmd0aCk7CiAgICAgICAgLy8hIH0KICAgICAgICAvLyBUaGUgc3BlY2lmaWMgbnVtZXJpYyB2YWx1ZXMgbmVlZCB0byBiZSBkZXRlcm1pbmVkCiAgICAgICAgLy8gZW1waXJpY2FsbHkuIFthbGl1XQogICAgICAgIHJlc3VsdCA9IGN1cnNvci0+cmVvcmRlckJ1ZmZlcjsKCiAgICAgICAgaWYgKGZpcnN0RXhwYW5zaW9uID09IE5VTEwpIHsKICAgICAgICAgICAgcmVzdWx0LT5hdFB1dCgwLCBmaXJzdFZhbHVlKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8vIFN5c3RlbS5hcnJheWNvcHkoZmlyc3RFeHBhbnNpb24sIDAsIHJlc3VsdCwgMCwgZmlyc3RMZW5ndGgpOwogICAgICAgICAgICAqcmVzdWx0ID0gKmZpcnN0RXhwYW5zaW9uOwogICAgICAgIH0KCiAgICAgICAgaWYgKGxhc3RFeHBhbnNpb24gPT0gTlVMTCkgewogICAgICAgICAgICByZXN1bHQtPmF0UHV0KGZpcnN0TGVuZ3RoLCBsYXN0VmFsdWUpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLy8gU3lzdGVtLmFycmF5Y29weShsYXN0RXhwYW5zaW9uLCAwLCByZXN1bHQsIGZpcnN0TGVuZ3RoLCBsYXN0TGVuZ3RoKTsKICAgICAgICAgICAgZm9yIChpbnQzMl90IGk9MDsgaTxsYXN0TGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIHJlc3VsdC0+YXRQdXQoZmlyc3RMZW5ndGggKyBpLCBsYXN0RXhwYW5zaW9uLT5hdChpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVzdWx0LT5zZXRTaXplKGZpcnN0TGVuZ3RoK2xhc3RMZW5ndGgpOwogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCgoKCgppbmxpbmUgaW50MzJfdApSdWxlQmFzZWRDb2xsYXRvcjo6c3RyZW5ndGhPcmRlcihpbnQzMl90IHZhbHVlKSBjb25zdAp7CiAgICBpZiAoZ2V0U3RyZW5ndGgoKSA9PSBQUklNQVJZKQogICAgewogICAgICAgIHJldHVybiAodmFsdWUgJiBQUklNQVJZRElGRkVSRU5DRU9OTFkpOwogICAgfSBlbHNlIGlmIChnZXRTdHJlbmd0aCgpID09IFNFQ09OREFSWSkKICAgIHsKICAgICAgICByZXR1cm4gKHZhbHVlICYgU0VDT05EQVJZRElGRkVSRU5DRU9OTFkpOwogICAgfQogICAgcmV0dXJuIHZhbHVlOwp9CgoKaW5saW5lIGludDMyX3QKUnVsZUJhc2VkQ29sbGF0b3I6OmdldFN0cmVuZ3RoT3JkZXIoTm9ybWFsaXplckl0ZXJhdG9yKiBjdXJzb3IsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlIHN0YXR1cykgY29uc3QKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUjsKICAgIH0KCiAgICBpZiAoY3Vyc29yLT5idWZmZXJBbGlhcyAhPSBOVUxMKQogICAgewogICAgICAgIC8vIGJ1ZmZlckFsaWFzIG5lZWRzIGEgYml0IG9mIGFuIGV4cGxhbmF0aW9uLgogICAgICAgIC8vIFdoZW4gd2UgaGl0IGFuIGV4cGFuZGluZyBjaGFyYWN0ZXIgaW4gdGhlIHRleHQsIHdlIGNhbGwgdGhlIG9yZGVyJ3MKICAgICAgICAvLyBnZXRFeHBhbmRWYWx1ZXMgbWV0aG9kIHRvIHJldHJpZXZlIGFuIGFycmF5IG9mIHRoZSBvcmRlcmluZ3MgZm9yIGFsbAogICAgICAgIC8vIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBleHBhbnNpb24gKHNlZSB0aGUgZW5kIG9mIHRoaXMgbWV0aG9kKS4KICAgICAgICAvLyBUaGUgZmlyc3Qgb3JkZXJpbmcgaXMgcmV0dXJuZWQsIGFuZCBhbiBhbGlhcyB0byB0aGUgb3JkZXJpbmdzIGFycmF5CiAgICAgICAgLy8gaXMgc2F2ZWQgc28gdGhhdCB0aGUgcmVtYWluaW5nIG9yZGVyaW5ncyBjYW4gYmUgcmV0dXJuZWQgb24gc3Vic2VxdWVudAogICAgICAgIC8vIGNhbGxzIHRvIG5leHQuICBTbywgaWYgdGhlIGV4cGFuZGluZyBidWZmZXIgaXMgbm90IGV4aGF1c3RlZCwgCiAgICAgICAgLy8gYWxsIHdlIGhhdmUgdG8gZG8gaGVyZSBpcyByZXR1cm4gdGhlIG5leHQgb3JkZXJpbmcgaW4gdGhlIGJ1ZmZlci4gIAogICAgICAgIGlmIChjdXJzb3ItPmV4cEluZGV4IDwgY3Vyc29yLT5idWZmZXJBbGlhcy0+c2l6ZSgpKQogICAgICAgIHsKICAgICAgICAgICAgLy9fTCgoc3RkZXJyLCAibmV4dCBmcm9tIFslMDhYXSBmcm9tIGJ1ZmZlckFsaWFzXG4iLCB0aGlzKSk7CiAgICAgICAgICAgIHJldHVybiBzdHJlbmd0aE9yZGVyKGN1cnNvci0+YnVmZmVyQWxpYXMtPmF0KGN1cnNvci0+ZXhwSW5kZXgrKykpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBjdXJzb3ItPmJ1ZmZlckFsaWFzID0gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgVUNoYXIgY2ggPSBjdXJzb3ItPmN1cnJlbnQoKTsKICAgIGN1cnNvci0+bmV4dCgpOwoKICAgIC8vX0woKHN0ZGVyciwgIk5leHQgZnJvbSBbJTA4WF0gPSBbJTA0WF0sIFslY11cbiIsIGN1cnNvciwgKGludCljaCAmIDB4RkZGRiwgKGNoYXIpKGNoICYgMHhGRikpKTsKICAgIAogICAgaWYgKGNoID09IE5vcm1hbGl6ZXI6OkRPTkUpIHsKICAgICAgICByZXR1cm4gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVI7CiAgICB9CiAgICAvLyBBc2sgdGhlIGNvbGxhdG9yIGZvciB0aGlzIGNoYXJhY3RlcidzIG9yZGVyaW5nLgogICAgaW50MzJfdCB2YWx1ZSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY2gpOwoKICAgIGlmICh2YWx1ZSA9PSBVTk1BUFBFRCkKICAgIHsKICAgICAgICAvLyBSZXR1cm5lZCBhbiAidW5tYXBwZWQiIGZsYWcgYW5kIHNhdmUgdGhlIGNoYXJhY3RlciBzbyBpdCBjYW4gYmUgCiAgICAgICAgLy8gcmV0dXJuZWQgbmV4dCB0aW1lIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC4KICAgICAgICBpZiAoY2ggPT0gMHgwMDAwKSByZXR1cm4gY2g7IC8vIFx1MDAwMCBpcyBub3QgdmFsaWQgaW4gQysrJ3MgVW5pY29kZVN0cmluZwogICAgICAgIGN1cnNvci0+b3duQnVmZmVyLmF0KDApID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpVTk1BUFBFRENIQVJWQUxVRTsKICAgICAgICBjdXJzb3ItPm93bkJ1ZmZlci5hdCgxKSA9IGNoIDw8IDE2OwogICAgICAgIGN1cnNvci0+YnVmZmVyQWxpYXMgPSAmY3Vyc29yLT5vd25CdWZmZXI7CgogICAgfSBlbHNlIHsKICAgICAgICAKICAgICAgICBpZiAodmFsdWUgPj0gQ09OVFJBQ1RDSEFSSU5ERVgpCiAgICAgICAgewogICAgICAgICAgICB2YWx1ZSA9IG5leHRDb250cmFjdENoYXIoY3Vyc29yLCBjaCwgc3RhdHVzKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKHZhbHVlID49IEVYUEFORENIQVJJTkRFWCkgewogICAgICAgICAgICBjdXJzb3ItPmJ1ZmZlckFsaWFzID0gZ2V0RXhwYW5kVmFsdWVMaXN0KHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6aXNUaGFpUHJlVm93ZWwoY2gpKSB7CiAgICAgICAgICAgIFVDaGFyIGNvbnNvbmFudCA9IGN1cnNvci0+Y3VycmVudCgpOwogICAgICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc1RoYWlCYXNlQ29uc29uYW50KGNvbnNvbmFudCkpIHsKICAgICAgICAgICAgICAgIGN1cnNvci0+bmV4dCgpOwogICAgICAgICAgICAgICAgY3Vyc29yLT5idWZmZXJBbGlhcyA9IG1ha2VSZW9yZGVyZWRCdWZmZXIoY3Vyc29yLCBjb25zb25hbnQsIHZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3Vyc29yLT5idWZmZXJBbGlhcyk7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChjdXJzb3ItPmJ1ZmZlckFsaWFzICE9IE5VTEwpIHsKICAgICAgICBjdXJzb3ItPmV4cEluZGV4ID0gMTsKICAgICAgICB2YWx1ZSA9IGN1cnNvci0+YnVmZmVyQWxpYXMtPmF0KDApOwogICAgfQoKICAgIHJldHVybiBzdHJlbmd0aE9yZGVyKHZhbHVlKTsKfQoKLy8gPT09PT09PT09PT09PT09PT09PT0gRW5kIGlubGluZXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcigpCiAgICA6IENvbGxhdG9yKCksCiAgICAgIGlzT3Zlcklnbm9yZShGQUxTRSksCiAgICAgIG1QYXR0ZXJuKDApLAogICAgICAvLyAgICAgIHNvdXJjZUN1cnNvcigwKSwKICAgICAgLy90YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICAgIGRhdGFJc093bmVkKEZBTFNFKSwKICAgICAgZGF0YSgwKQp7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgUnVsZUJhc2VkQ29sbGF0b3ImICB0aGF0KQogICAgOiBDb2xsYXRvcih0aGF0KSwKICAgICAgaXNPdmVySWdub3JlKHRoYXQuaXNPdmVySWdub3JlKSwKICAgICAgbVBhdHRlcm4oMCksCiAgICAgIC8vICAgICAgc291cmNlQ3Vyc29yKDApLAogICAgICAvL3RhcmdldEN1cnNvcigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpLAogICAgICBkYXRhKHRoYXQuZGF0YSkgLy8gQWxpYXMgdGhlIGRhdGEgcG9pbnRlcgp7Cn0KClVCb29sClJ1bGVCYXNlZENvbGxhdG9yOjpvcGVyYXRvcj09KGNvbnN0IENvbGxhdG9yJiB0aGF0KSBjb25zdAp7CiAgICBpZiAodGhpcyA9PSAmdGhhdCkKICAgIHsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIH0KCiAgICBpZiAodGhpcy0+Z2V0RHluYW1pY0NsYXNzSUQoKSAhPSB0aGF0LmdldER5bmFtaWNDbGFzc0lEKCkpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOyAgLy8gbm90IHRoZSBzYW1lIGNsYXNzCiAgICB9CgogICAgaWYgKCFDb2xsYXRvcjo6b3BlcmF0b3I9PSh0aGF0KSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgUnVsZUJhc2VkQ29sbGF0b3ImIHRoYXRBbGlhcyA9IChSdWxlQmFzZWRDb2xsYXRvciYpdGhhdDsKCiAgICBpZiAoaXNPdmVySWdub3JlICE9IHRoYXRBbGlhcy5pc092ZXJJZ25vcmUpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChkYXRhICE9IHRoYXRBbGlhcy5kYXRhKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKfQoKUnVsZUJhc2VkQ29sbGF0b3ImClJ1bGVCYXNlZENvbGxhdG9yOjpvcGVyYXRvcj0oY29uc3QgIFJ1bGVCYXNlZENvbGxhdG9yJiB0aGF0KQp7CiAgICBpZiAodGhpcyAhPSAmdGhhdCkKICAgIHsKICAgICAgICBDb2xsYXRvcjo6b3BlcmF0b3I9KHRoYXQpOwogICAgICAgIGlzT3Zlcklnbm9yZSA9IHRoYXQuaXNPdmVySWdub3JlOwoKICAgICAgICBpZiAoZGF0YUlzT3duZWQpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICB9CgogICAgICAgIGRhdGEgPSAwOwogICAgICAgIGRlbGV0ZSBtUGF0dGVybjsKICAgICAgICBtUGF0dGVybiA9IDA7CiAgICAgICAgZGF0YUlzT3duZWQgPSBGQUxTRTsKICAgICAgICBkYXRhID0gdGhhdC5kYXRhOwogICAgfQoKICAgIHJldHVybiAqdGhpczsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0ICBVbmljb2RlU3RyaW5nJiAgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykKICAgIDogQ29sbGF0b3IoKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgbVBhdHRlcm4oMCksCiAgICAgIC8vICAgICAgc291cmNlQ3Vyc29yKDApLAogICAgICAvLy8gICAgICB0YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICAgIGRhdGFJc093bmVkKEZBTFNFKSwKICAgICAgZGF0YSgwKQp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGNvbnN0cnVjdEZyb21SdWxlcyhydWxlcywgc3RhdHVzKTsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0ICBVbmljb2RlU3RyaW5nJiAgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgIEVDb2xsYXRpb25TdHJlbmd0aCBjb2xsYXRpb25TdHJlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCiAgOiBDb2xsYXRvcihjb2xsYXRpb25TdHJlbmd0aCwgTm9ybWFsaXplcjo6Tk9fT1ApLAogICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgIG1QYXR0ZXJuKDApLAogICAgLy8gICAgc291cmNlQ3Vyc29yKDApLAogICAgLy8gICAgdGFyZ2V0Q3Vyc29yKDApLAogICAgY3Vyc29yMSgwKSwKICAgIGN1cnNvcjIoMCksCiAgICBkYXRhSXNPd25lZChGQUxTRSksCiAgICBkYXRhKDApCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdHJ1Y3RGcm9tUnVsZXMocnVsZXMsIHN0YXR1cyk7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCiAgOiBDb2xsYXRvcihURVJUSUFSWSwgZGVjb21wb3NpdGlvbk1vZGUpLAogICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgIG1QYXR0ZXJuKDApLAogICAgLy8gICAgc291cmNlQ3Vyc29yKDApLAogICAgLy8gICAgdGFyZ2V0Q3Vyc29yKDApLAogICAgY3Vyc29yMSgwKSwKICAgIGN1cnNvcjIoMCksCiAgICBkYXRhSXNPd25lZChGQUxTRSksCiAgICBkYXRhKDApCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgIHJldHVybjsKICAgIH0KICAKICBjb25zdHJ1Y3RGcm9tUnVsZXMocnVsZXMsIHN0YXR1cyk7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykKICA6IENvbGxhdG9yKGNvbGxhdGlvblN0cmVuZ3RoLCBkZWNvbXBvc2l0aW9uTW9kZSksCiAgICAgIGlzT3Zlcklnbm9yZShGQUxTRSksCiAgICAgIG1QYXR0ZXJuKDApLAogICAgLy8gICAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAvL3RhcmdldEN1cnNvcigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpLAogICAgICBkYXRhKDApCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgY29uc3RydWN0RnJvbVJ1bGVzKHJ1bGVzLCBzdGF0dXMpOwp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tUnVsZXMoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIC8vIENvbnN0cnVjdCB0aGlzIGNvbGxhdG9yJ3MgcnVsZXNldCBmcm9tIGl0cyBzdHJpbmcgcmVwcmVzZW50YXRpb24KICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKHJ1bGVzLmlzQm9ndXMoKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IDA7CiAgICB9CgogICAgaXNPdmVySWdub3JlID0gRkFMU0U7CiAgICBzZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOwoKICAgIGRhdGEgPSBuZXcgVGFibGVDb2xsYXRpb25EYXRhOwogICAgaWYgKGRhdGEtPmlzQm9ndXMoKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBXZSBjb25zdHJ1Y3RlZCB0aGUgZGF0YSB1c2luZyB0aGUgYnVpbGQgbWV0aG9kLCBzbyB3ZSBvd24gaXQuCiAgICBkYXRhSXNPd25lZCA9IFRSVUU7CgogICAgLy8gTm93IHRoYXQgd2UndmUgZ290IGFsbCB0aGUgYnVmZmVycyBhbGxvY2F0ZWQsIGRvIHRoZSBhY3R1YWwgd29yawogICAgbVBhdHRlcm4gPSAwOwogICAgYnVpbGQocnVsZXMsIHN0YXR1cyk7Cn0KCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbnN0cnVjdEZyb21GaWxlKGNvbnN0IGNoYXIqIGZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICAvLyBUaGlzIG1ldGhvZCB0cmllcyB0byByZWFkIGluIGEgZmxhdHRlbmVkIFJ1bGVCYXNlZENvbGxhdG9yIHRoYXQKICAgIC8vIGhhcyBiZWVuIHByZXZpb3VzbHkgc3RyZWFtZWQgb3V0IHVzaW5nIHRoZSBzdHJlYW1PdXQoKSBtZXRob2QuCiAgICAvLyBUaGUgJ2ZpbGVOYW1lJyBwYXJhbWV0ZXIgc2hvdWxkIGNvbnRhaW4gYSBmdWxsIHBhdGhuYW1lIHZhbGlkIG9uCiAgICAvLyB0aGUgbG9jYWwgZW52aXJvbm1lbnQuCgogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IDA7CiAgICB9CgogICAgbVBhdHRlcm4gPSAwOwogICAgaXNPdmVySWdub3JlID0gRkFMU0U7CiAgICBzZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOyAvLyBUaGlzIGlzIHRoZSBkZWZhdWx0IHN0cmVuZ3RoCgogICAgRmlsZVN0cmVhbSogaWZzID0gVF9GaWxlU3RyZWFtX29wZW4oZmlsZU5hbWUsICJyYiIpOwogICAgaWYgKGlmcyA9PSAwKSB7CiAgICAgICAgc3RhdHVzID0gVV9GSUxFX0FDQ0VTU19FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gVGhlIHN0cmVhbUluIGZ1bmN0aW9uIGRvZXMgdGhlIGFjdHVhbCB3b3JrIGhlcmUuLi4KICAgIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbUluKHRoaXMsIGlmcyk7CgogICAgaWYgKCFUX0ZpbGVTdHJlYW1fZXJyb3IoaWZzKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICB9CiAgICBlbHNlIGlmIChkYXRhICYmIGRhdGEtPmlzQm9ndXMoKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHN0YXR1cyA9IFVfTUlTU0lOR19SRVNPVVJDRV9FUlJPUjsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgIH0KCiNpZmRlZiBDT0xMREVCVUcKICAgIGZwcmludGYoc3RkZXJyLCAiYmluYXJ5IHJlYWQgJXMgc2l6ZSAlZCwgJXNcbiIsIGZpbGVOYW1lLCBUX0ZpbGVTdHJlYW1fc2l6ZShpZnMpLCB1X2Vycm9yTmFtZShzdGF0dXMpKTsKI2VuZGlmCgogICAgLy8gV2UgY29uc3RydWN0ZWQgdGhlIGRhdGEgd2hlbiBzdHJlYW1pbmcgaXQgaW4sIHNvIHdlIG93biBpdAogICAgZGF0YUlzT3duZWQgPSBUUlVFOwoKICAgIFRfRmlsZVN0cmVhbV9jbG9zZShpZnMpOwp9Cgpjb25zdCBjaGFyICoKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbnN0cnVjdEZyb21CdW5kbGUoY29uc3QgTG9jYWxlICYgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogIC8vIFRoaXMgbWV0aG9kIHRyaWVzIHRvIGxvY2F0ZSBiaW5hcnkgY29sbGF0aW9uIGRhdGEgd2hpY2ggaGFzIGJlZW4gCiAgLy8gcHJldmlvdXNseSBzdHJlYW1lZCB0byBhIGJpbmFyeSBvYmplY3QgIiUlQ29sbGF0aW9uIiBpbiBhIAogIC8vIHJlc291cmNlIGJ1bmRsZS4gSWYgdGhlIGRhdGEgaXMgZm91bmQsIGl0IGlzIGNhY2hlZC4KICAvLyBjYWNoZSBpcyBjaGVja2VkIGJlZm9yZSBhY3R1YWxseSBzdHJlYW1pbmcgaW4gZGF0YQogIC8vIHJlc291cmNlIGJ1bmRsZSBmYWxsYmFjayBtZWNoYW5pc20gaXMgdXNlZC4KCiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKGRhdGFJc093bmVkKQogICAgewogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgfQogICAgY29uc3QgY2hhciogcmVhbE5hbWUgPSAwOwoKICAgIG1QYXR0ZXJuID0gMDsKICAgIGlzT3Zlcklnbm9yZSA9IEZBTFNFOwogICAgc2V0U3RyZW5ndGgoQ29sbGF0b3I6OlRFUlRJQVJZKTsgLy8gVGhpcyBpcyB0aGUgZGVmYXVsdCBzdHJlbmd0aAoKICAgIFJlc291cmNlQnVuZGxlIHJiKChjaGFyICopMCwgbmFtZSwgc3RhdHVzKTsKICAgIGlmKFVfU1VDQ0VTUyhzdGF0dXMpKSB7CiAgICAgIFJlc291cmNlQnVuZGxlIGJpbmFyeSA9IHJiLmdldCgiJSVDb2xsYXRpb24iLCBzdGF0dXMpOyAvL1RoaXMgaXMgdGhlIGJ1bmRsZSB0aGF0IGFjdHVhbGx5IGNvbnRhaW5zIHRoZSBjb2xsYXRpb24gZGF0YQogICAgICByZWFsTmFtZSA9IGJpbmFyeS5nZXROYW1lKCk7CiAgICAgIGlmKFVfU1VDQ0VTUyhzdGF0dXMpKSB7CiAgICAgICAgVUVycm9yQ29kZSBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgY29uc3RydWN0RnJvbUNhY2hlKHJlYWxOYW1lLCBpbnRTdGF0dXMpOyAvLyBjaGVjayB3aGV0aGVyIHdlIGFscmVhZHkgaGF2ZSB0aGlzIGRhdGEgaW4gY2FjaGUKICAgICAgICBpZihVX1NVQ0NFU1MoaW50U3RhdHVzKSkgewogICAgICAgICAgcmV0dXJuIHJlYWxOYW1lOwogICAgICAgIH0KICAgICAgICBpbnQzMl90IGluRGF0YUxlbiA9IDA7CiAgICAgICAgY29uc3QgdWludDhfdCAqaW5EYXRhID0gYmluYXJ5LmdldEJpbmFyeShpbkRhdGFMZW4sIHN0YXR1cyk7IC8vVGhpcyBnb3QgdXMgdGhlIHJlYWwgYmluYXJ5IGRhdGEKCiAgICAgICAgVU1lbW9yeVN0cmVhbSAqaWZzID0gdXBydl9tc3RybV9vcGVuQnVmZmVyKGluRGF0YSwgaW5EYXRhTGVuKTsKCiAgICAgICAgaWYgKGlmcyA9PSAwKSB7CiAgICAgICAgICBzdGF0dXMgPSBVX0ZJTEVfQUNDRVNTX0VSUk9SOwogICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvLyBUaGUgc3RyZWFtSW4gZnVuY3Rpb24gZG9lcyB0aGUgYWN0dWFsIHdvcmsgaGVyZS4uLgogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbUluKHRoaXMsIGlmcywgc3RhdHVzKTsKCiAgICAgICAgaWYgKCF1cHJ2X21zdHJtX2Vycm9yKGlmcykpIHsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoZGF0YSAmJiBkYXRhLT5pc0JvZ3VzKCkpIHsKICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICAgIGRhdGEgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CiAgICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICAgIGRhdGEgPSAwOwogICAgICAgIH0KCiAgICAgICAgLy8gV2UgY29uc3RydWN0ZWQgdGhlIGRhdGEgd2hlbiBzdHJlYW1pbmcgaXQgaW4sIHNvIHdlIG93biBpdAogICAgICAgIGRhdGFJc093bmVkID0gVFJVRTsKCiAgICAgICAgdXBydl9tc3RybV9jbG9zZShpZnMpOwogICAgICAgIGFkZFRvQ2FjaGUocmVhbE5hbWUpOyAvLyBhZGQgdGhlIG5ld2x5IGNvbnN0cnVjdGVkIGRhdGEgdG8gY2FjaGUKICAgICAgICByZXR1cm4gcmVhbE5hbWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RhdHVzID0gVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SOwogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAwOwogICAgfQp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoICAgY29uc3QgTG9jYWxlJiBkZXNpcmVkTG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKICAgIDogQ29sbGF0b3IoKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgLy8gICAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAgIC8vdGFyZ2V0Q3Vyc29yKDApLAogICAgICBtUGF0dGVybigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpLAogICAgICBkYXRhKDApCnsKCgogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgewogICAgcmV0dXJuOwogIH0KICAKICAvLyBUcnkgdG8gbG9hZCwgaW4gb3JkZXI6CiAgLy8gMS4gVGhlIGRlc2lyZWQgbG9jYWxlJ3MgY29sbGF0aW9uLgogIC8vIDIuIEEgZmFsbGJhY2sgb2YgdGhlIGRlc2lyZWQgbG9jYWxlLgogIC8vIDMuIFRoZSBkZWZhdWx0IGxvY2FsZSdzIGNvbGxhdGlvbi4KICAvLyA0LiBBIGZhbGxiYWNrIG9mIHRoZSBkZWZhdWx0IGxvY2FsZS4KICAvLyA1LiBUaGUgZGVmYXVsdCBjb2xsYXRpb24gcnVsZXMsIHdoaWNoIGNvbnRhaW5zIGVuX1VTIGNvbGxhdGlvbiBydWxlcy4KCiAgLy8gVG8gcmVpdGVyYXRlLCB3ZSB0cnk6CiAgLy8gU3BlY2lmaWM6CiAgLy8gIGxhbmd1YWdlK2NvdW50cnkrdmFyaWFudAogIC8vICBsYW5ndWFnZStjb3VudHJ5CiAgLy8gIGxhbmd1YWdlCiAgLy8gRGVmYXVsdDoKICAvLyAgbGFuZ3VhZ2UrY291bnRyeSt2YXJpYW50CiAgLy8gIGxhbmd1YWdlK2NvdW50cnkKICAvLyAgbGFuZ3VhZ2UKICAvLyBSb290OiAoYWthIERFRkFVTFRSVUxFUykKICAvLyBzdGVwcyAxLTUgYXJlIGhhbmRsZWQgYnkgcmVzb3VyY2UgYnVuZGxlIGZhbGxiYWNrIG1lY2hhbmlzbS4gCiAgLy8gaG93ZXZlciwgaW4gYSB2ZXJ5IHVucHJvYmFibGUgc2l0dWF0aW9uIHRoYXQgbm8gcmVzb3VyY2UgYnVuZGxlCiAgLy8gZGF0YSBleGlzdHMsIHN0ZXAgNSBpcyByZXBlYXRlZCB3aXRoIGhhcmRjb2RlZCBkZWZhdWx0IHJ1bGVzLgoKICBjb25zdCBjaGFyICpsb2NOYW1lID0gY29uc3RydWN0RnJvbUJ1bmRsZShkZXNpcmVkTG9jYWxlLCBzdGF0dXMpOyAgLyohKi8KICAKICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpIHsKICAgIGRhdGEtPmRlc2lyZWRMb2NhbGUgPSBkZXNpcmVkTG9jYWxlOwogICAgZGF0YS0+cmVhbExvY2FsZU5hbWUgPSBsb2NOYW1lOwogICAgaWYoc3RhdHVzICE9IFVfVVNJTkdfREVGQVVMVF9FUlJPUikgewogICAgICBzZXREZWNvbXBvc2l0aW9uKE5vcm1hbGl6ZXI6Ok5PX09QKTsKICAgIH0KICB9IGVsc2UgewogICAgVUVycm9yQ29kZSBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICBjb25zdHJ1Y3RGcm9tQ2FjaGUoUmVzb3VyY2VCdW5kbGU6OmtEZWZhdWx0RmlsZW5hbWUsIGludFN0YXR1cyk7CiAgICBpZihVX0ZBSUxVUkUoaW50U3RhdHVzKSkgewogICAgICBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICAgIGNvbnN0cnVjdEZyb21SdWxlcyhSdWxlQmFzZWRDb2xsYXRvcjo6REVGQVVMVFJVTEVTLCBpbnRTdGF0dXMpOwogICAgICBpZiAoaW50U3RhdHVzID09IFVfWkVST19FUlJPUikgewogICAgICAgIHN0YXR1cyA9IFVfVVNJTkdfREVGQVVMVF9FUlJPUjsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdGF0dXMgPSBpbnRTdGF0dXM7ICAgICAvLyBidWJibGUgYmFjawogICAgICB9CgogICAgICBpZiAoc3RhdHVzID09IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1IpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgIH0KICAgIGRhdGEtPnJlYWxMb2NhbGVOYW1lID0gUmVzb3VyY2VCdW5kbGU6OmtEZWZhdWx0RmlsZW5hbWU7CiAgICBzZXREZWNvbXBvc2l0aW9uKE5vcm1hbGl6ZXI6Ok5PX09QKTsKICAgIGFkZFRvQ2FjaGUoUmVzb3VyY2VCdW5kbGU6OmtEZWZhdWx0RmlsZW5hbWUpOwogIH0KICByZXR1cm47Cn0KCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbnN0cnVjdEZyb21GaWxlKCAgIGNvbnN0IExvY2FsZSYgICAgICAgICAgIGxvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgICAgbG9jYWxlRmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVCb29sICAgICAgICAgICAgICAgICAgdHJ5QmluYXJ5RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICAgICAgICAgIHN0YXR1cykKewogIC8vIGNvbnN0cnVjdEZyb21GaWxlIGNyZWF0ZXMgYSBjb2xsYXRpb24gb2JqZWN0IGJ5IHJlYWRpbmcgZnJvbSBhCiAgLy8gZmlsZS4gIEl0IGRvZXMgbm90IGVtcGxveSB0aGUgdXN1YWwgRklMRSBzZWFyY2ggbWVjaGFuaXNtIHdpdGgKICAvLyBsb2NhbGVzLCBkZWZhdWx0IGxvY2FsZXMsIGFuZCBiYXNlIGxvY2FsZXMuICBJbnN0ZWFkLCBpdCB0cmllcyB0bwogIC8vIGxvb2sgb25seSBpbiBmaWxlcyB3aXRoIHRoZSBnaXZlbiBsb2NhbEZpbGVOYW1lLiAgSXQgZG9lcywKICAvLyBob3dldmVyLCBlbXBsb3kgdGhlIExPQ0FMRSBzZWFyY2ggbWVjaGFuaXNtLgogIAogIC8vIFRoaXMgbWV0aG9kIG1haW50YWlucyB0aGUgYmluYXJ5IGNvbGxhdGlvbiBmaWxlcy4gIElmIGEgY29sbGF0aW9uCiAgLy8gaXMgbm90IHByZXNlbnQgaW4gYmluYXJ5IGZvcm0sIGJ1dCBpcyBwcmVzZW50IGluIHRleHQgZm9ybSAoaW4gYQogIC8vIHJlc291cmNlIGJ1bmRsZSBmaWxlKSwgaXQgd2lsbCBiZSBsb2FkZWQgaW4gdGV4dCBmb3JtLCBhbmQgdGhlbgogIC8vIHdyaXR0ZW4gdG8gZGlzay4KICAKICAvLyBJZiB0cnlCaW5hcnlGaWxlIGlzIHRydWUsIHRoZW4gdHJ5IHRvIGxvYWQgZnJvbSB0aGUgYmluYXJ5IGZpbGUgZmlyc3QuCgogIGlmKFVfRkFJTFVSRShzdGF0dXMpKSB7CiAgICByZXR1cm47CiAgfQogIAogIGlmKGRhdGFJc093bmVkKSB7CiAgICBkZWxldGUgZGF0YTsKICAgIGRhdGEgPSAwOwogIH0KCiAgICBpZih0cnlCaW5hcnlGaWxlKSB7CiAgICAgIGNoYXIgKmJpbmFyeUZpbGVQYXRoID0gY3JlYXRlUGF0aE5hbWUoVW5pY29kZVN0cmluZyh1X2dldERhdGFEaXJlY3RvcnkoKSwiIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlRmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyhrRmlsZW5hbWVTdWZmaXgsIiIpKTsKCiAgICAgICAgLy8gVHJ5IHRvIGxvYWQgdXAgdGhlIGNvbGxhdGlvbiBmcm9tIGEgYmluYXJ5IGZpbGUgZmlyc3QKICAgICAgICBjb25zdHJ1Y3RGcm9tRmlsZShiaW5hcnlGaWxlUGF0aCwgc3RhdHVzKTsKICAgICAgICAjaWZkZWYgQ09MTERFQlVHCiAgICAgICAgICAgIGNlcnIgPDwgbG9jYWxlRmlsZU5hbWUgIDw8IGtGaWxlbmFtZVN1ZmZpeCA8PCAiIGJpbmFyeSBsb2FkICIgPDwgdV9lcnJvck5hbWUoc3RhdHVzKSA8PCBlbmRsOwogICAgICAgICNlbmRpZgogICAgICAgIGlmKFVfU1VDQ0VTUyhzdGF0dXMpIHx8IHN0YXR1cyA9PSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SKSB7CiAgICAgICAgICAgIGRlbGV0ZSBbXSBiaW5hcnlGaWxlUGF0aDsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpZihzdGF0dXMgPT0gVV9GSUxFX0FDQ0VTU19FUlJPUikgewogICAgICAgICAgICBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgfQogICAgICAgIGRlbGV0ZSBbXSBiaW5hcnlGaWxlUGF0aDsKICAgIH0KCiAgLy8gTm93IHRyeSB0byBsb2FkIGl0IHVwIGZyb20gYSByZXNvdXJjZSBidW5kbGUgdGV4dCBzb3VyY2UgZmlsZQogIFVuaWNvZGVTdHJpbmcgZGF0YURpciA9IFVuaWNvZGVTdHJpbmcodV9nZXREYXRhRGlyZWN0b3J5KCksIiIpOwoKICAgIGNoYXIgKmNoOwogICAgY2ggPSBuZXcgY2hhcltsb2NhbGVGaWxlTmFtZS5zaXplKCkgKyAxXTsKICAgIGNoW2xvY2FsZUZpbGVOYW1lLmV4dHJhY3QoMCwgMHg3ZmZmZmZmZiwgY2gsICIiKV0gPSAwOwogICAgUmVzb3VyY2VCdW5kbGUgYnVuZGxlKGRhdGFEaXIsIGNoLCBzdGF0dXMpOwogIAogICAgZGVsZXRlIFtdIGNoOwogIAogIC8vIGlmIHRoZXJlIGlzIG5vIHJlc291cmNlIGJ1bmRsZSBmaWxlIGZvciB0aGUgZ2l2ZSBsb2NhbGUsIGJyZWFrIG91dAogIGlmKFVfRkFJTFVSRShzdGF0dXMpKQogIHsKICAgICAgcmV0dXJuOwogIH0KCiAgICAjaWZkZWYgQ09MTERFQlVHCiAgICAgICAgY2VyciA8PCBsb2NhbGVGaWxlTmFtZSA8PCAiIGFzY2lpIGxvYWQgIiA8PCB1X2Vycm9yTmFtZShzdGF0dXMpIDw8IGVuZGw7CiAgICAjZW5kaWYKCiAgICAvLyBjaGVjayBhbmQgc2VlIGlmIHRoaXMgcmVzb3VyY2UgYnVuZGxlIGNvbnRhaW5zIGNvbGxhdGlvbiBkYXRhCiAgCiAgICBVbmljb2RlU3RyaW5nIGNvbFN0cmluZzsKICAgIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwoKICAgIFJlc291cmNlQnVuZGxlIGNvbEVsZW1zID0gYnVuZGxlLmdldCgiQ29sbGF0aW9uRWxlbWVudHMiLCBpbnRTdGF0dXMpOwogICAgaWYgKFVfRkFJTFVSRShpbnRTdGF0dXMpKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfTUlTU0lOR19SRVNPVVJDRV9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjb2xTdHJpbmcgPSBjb2xFbGVtcy5nZXRTdHJpbmdFeCgiU2VxdWVuY2UiLCBpbnRTdGF0dXMpOwoKICAgIGlmKFVfRkFJTFVSRShpbnRTdGF0dXMpKSB7CiAgICAgICAgc3RhdHVzID0gVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZihjb2xTdHJpbmcuaXNCb2d1cygpKSB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogIC8vIEhhdmluZyBsb2FkZWQgdGhlIGNvbGxhdGlvbiBmcm9tIHRoZSByZXNvdXJjZSBidW5kbGUgdGV4dCBmaWxlLAogIC8vIG5vdyByZXRyaWV2ZSB0aGUgQ29sbGF0aW9uRWxlbWVudHMgdGFnZ2VkIGRhdGEsIG1lcmdlZCB3aXRoIHRoZQogIC8vIGRlZmF1bHQgcnVsZXMuICBJZiB0aGF0IGZhaWxzLCB1c2UgdGhlIGRlZmF1bHQgcnVsZXMgYWxvbmUuCgogIGNvbFN0cmluZy5pbnNlcnQoMCwgREVGQVVMVFJVTEVTKTsKICBpZihjb2xTdHJpbmcuaXNCb2d1cygpKSB7CiAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgcmV0dXJuOwogIH0KICAgIAogIGNvbnN0cnVjdEZyb21SdWxlcyhjb2xTdHJpbmcsIGludFN0YXR1cyk7CiAgaWYoaW50U3RhdHVzID09IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1IpIHsKICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICByZXR1cm47CiAgfQogIAogIGlmKGludFN0YXR1cyAhPSBVX1pFUk9fRVJST1IpICB7CiAgICBzdGF0dXMgPSBVX1VTSU5HX0RFRkFVTFRfRVJST1I7CiAgICAgIAogICAgLy8gcHJlZGVmaW5lZCB0YWJsZXMgc2hvdWxkIGNvbnRhaW4gY29ycmVjdCBncmFtbWFyCiAgICBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICBjb25zdHJ1Y3RGcm9tUnVsZXMoREVGQVVMVFJVTEVTLCBpbnRTdGF0dXMpOwogICAgaWYoaW50U3RhdHVzICE9IFVfWkVST19FUlJPUikgewogICAgICBzdGF0dXMgPSBpbnRTdGF0dXM7CiAgICB9CiAgfSAKICAKI2lmZGVmIENPTExERUJVRwogIGNlcnIgPDwgbG9jYWxlRmlsZU5hbWUgPDwgIiBhc2NpaSBsb2FkICIgPDwgKFVfU1VDQ0VTUyhzdGF0dXMpID8gIk9LIiA6ICJGYWlsZWQiKSA8PCAiIC0gdHJ5PSAiIDw8ICh0cnlCaW5hcnlGaWxlPyJ0cnVlIjoiZmFsc2UiKSA8PCBlbmRsOwojZW5kaWYKCn0KClJ1bGVCYXNlZENvbGxhdG9yOjp+UnVsZUJhc2VkQ29sbGF0b3IoKQp7CiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICB9CgogICAgZGF0YSA9IDA7CgogICAgLy8gICAgZGVsZXRlIHNvdXJjZUN1cnNvcjsKICAgIC8vICAgIHNvdXJjZUN1cnNvciA9IDA7CgogICAgLy8gICAgZGVsZXRlIHRhcmdldEN1cnNvcjsKICAgIC8vICAgIHRhcmdldEN1cnNvciA9IDA7CgogICAgaWYgKGN1cnNvcjEgIT0gTlVMTCkgewogICAgICAgIGRlbGV0ZSBjdXJzb3IxOwogICAgICAgIGN1cnNvcjEgPSAwOwogICAgfQogICAgaWYgKGN1cnNvcjIgIT0gTlVMTCkgewogICAgICAgIGRlbGV0ZSBjdXJzb3IyOwogICAgICAgIGN1cnNvcjIgPSAwOwogICAgfQoKICAgIGRlbGV0ZSBtUGF0dGVybjsKICAgIG1QYXR0ZXJuID0gMDsKfQoKQ29sbGF0b3IqClJ1bGVCYXNlZENvbGxhdG9yOjpjbG9uZSgpIGNvbnN0CnsKICAgIHJldHVybiBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoKnRoaXMpOwp9CgovLyBDcmVhdGUgYSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Igb2JqZWN0IHRoYXQgd2lsbCBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cwovLyBpbiBhIHN0cmluZywgdXNpbmcgdGhlIGNvbGxhdGlvbiBydWxlcyBkZWZpbmVkIGluIHRoaXMgUnVsZUJhc2VkQ29sbGF0b3IKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKgpSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSkgY29uc3QKewogICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgKm5ld0N1cnNvciA9IDA7CgogICAgbmV3Q3Vyc29yID0gbmV3IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihzb3VyY2UsIHRoaXMsIHN0YXR1cyk7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIG5ld0N1cnNvcjsKfQoKLy8gQ3JlYXRlIGEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIG9iamVjdCB0aGF0IHdpbGwgaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMKLy8gaW4gYSBzdHJpbmcsIHVzaW5nIHRoZSBjb2xsYXRpb24gcnVsZXMgZGVmaW5lZCBpbiB0aGlzIFJ1bGVCYXNlZENvbGxhdG9yCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcioKUnVsZUJhc2VkQ29sbGF0b3I6OmNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgc291cmNlKSBjb25zdAp7CiAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciAqbmV3Q3Vyc29yID0gMDsKCiAgICBuZXdDdXJzb3IgPSBuZXcgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKHNvdXJjZSwgdGhpcywgc3RhdHVzKTsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gbmV3Q3Vyc29yOwp9CgovLyBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBjb2xsYXRvcidzIHJ1bGVzLgovLyBUaGUgc3RyaW5nIGNhbiBsYXRlciBiZSBwYXNzZWQgdG8gdGhlIGNvbnN0cnVjdG9yIHRoYXQgdGFrZXMgYQovLyBVbmljb2RlU3RyaW5nIGFyZ3VtZW50LCB3aGljaCB3aWxsIGNvbnN0cnVjdCBhIGNvbGxhdG9yIHRoYXQncwovLyBmdW5jdGlvbmFsbHkgaWRlbnRpY2FsIHRvIHRoaXMgb25lLgovLyBZb3UgY2FuIGFsc28gYWxsb3cgdXNlcnMgdG8gZWRpdCB0aGUgc3RyaW5nIGluIG9yZGVyIHRvIGNoYW5nZQovLyB0aGUgY29sbGF0aW9uIGRhdGEsIG9yIHlvdSBjYW4gcHJpbnQgaXQgb3V0IGZvciBpbnNwZWN0aW9uLCBvciB3aGF0ZXZlci4KCmNvbnN0IFVuaWNvZGVTdHJpbmcmClJ1bGVCYXNlZENvbGxhdG9yOjpnZXRSdWxlcygpIGNvbnN0CnsKICAgIGlmIChtUGF0dGVybiAhPSAwKQogICAgewogICAgICAgIE1lcmdlQ29sbGF0aW9uKiYgbm9uQ29uc3RNUGF0dGVybiA9ICooTWVyZ2VDb2xsYXRpb24qKikmbVBhdHRlcm47CiAgICAgICAgbVBhdHRlcm4tPmVtaXRQYXR0ZXJuKGRhdGEtPnJ1bGVUYWJsZSk7CiAgICAgICAgZGF0YS0+aXNSdWxlVGFibGVMb2FkZWQgPSBUUlVFOwogICAgICAgIGRlbGV0ZSBub25Db25zdE1QYXR0ZXJuOwogICAgICAgIG5vbkNvbnN0TVBhdHRlcm4gPSAwOwogICAgfQogICAgZWxzZSBpZiAoIWRhdGEtPmlzUnVsZVRhYmxlTG9hZGVkKQogICAgewogICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgdGhlIGNhbGxlciB3YW50cyB0aGUgcnVsZXMsIGJ1dCB0aGUgcnVsZSB0YWJsZSBkYXRhCiAgICAgICAgLy8gaXMgbm90IGxvYWRlZC4gIEZ1cnRoZXJtb3JlLCB0aGVyZSBpcyBubyBtUGF0dGVybiBvYmplY3QgdG8gbG9hZAogICAgICAgIC8vIHRoZSBydWxlcyBmcm9tLiAgVGhlcmVmb3JlLCB3ZSBmZXRjaCB0aGUgcnVsZXMgb2ZmIHRoZSBkaXNrLgogICAgICAgIC8vIE5vdGljZSB0aGF0IHdlIHBhc3MgaW4gYSB0cnlCaW5hcnlGaWxlIHZhbHVlIG9mIEZBTFNFLCBzaW5jZQogICAgICAgIC8vIGJ5IGRlc2lnbiB0aGUgYmluYXJ5IGZpbGUgaGFzIE5PIHJ1bGVzIGluIGl0IQogICAgICAgIC8vVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgLy9SdWxlQmFzZWRDb2xsYXRvciB0ZW1wKGRhdGEtPnJlYWxMb2NhbGVOYW1lLCBzdGF0dXMpOwogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yIHRlbXA7CiAgICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgdGVtcC5jb25zdHJ1Y3RGcm9tRmlsZShkYXRhLT5kZXNpcmVkTG9jYWxlLCBkYXRhLT5yZWFsTG9jYWxlTmFtZSwgRkFMU0UsIHN0YXR1cyk7CgogICAgICAgIC8vIFdlIG11c3QgY2hlY2sgdGhhdCBtUGF0dGVybiBpcyBub256ZXJvIGhlcmUsIG9yIHdlIHJ1biB0aGUgcmlzawogICAgICAgIC8vIG9mIGFuIGluZmluaXRlIGxvb3AuCiAgICAgICAgaWYgKFVfU1VDQ0VTUyhzdGF0dXMpICYmIHRlbXAubVBhdHRlcm4gIT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIGRhdGEtPnJ1bGVUYWJsZSA9IHRlbXAuZ2V0UnVsZXMoKTsKICAgICAgICAgICAgZGF0YS0+aXNSdWxlVGFibGVMb2FkZWQgPSBUUlVFOwojaWZkZWYgX0RFQlVHCi8vICAgICAgICAgICAgICAvLyB0aGUgZm9sbG93aW5nIGlzIHVzZWZ1bCBmb3Igc3BlY2lmaWMgZGVidWdnaW5nIHB1cnBvc2VzCi8vICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBuYW1lOwovLyAgICAgICAgICAgICAgIGNlcnIgPDwgIlRhYmxlIGNvbGxhdGlvbiBydWxlcyBsb2FkZWQgZHluYW1pY2FsbHkgZm9yICIKLy8gICAgICAgICAgICAgICAgICAgPDwgZGF0YS0+ZGVzaXJlZExvY2FsZS5nZXROYW1lKG5hbWUpCi8vICAgICAgICAgICAgICAgICAgIDw8ICIgYXQgIgovLyAgICAgICAgICAgICAgICAgICA8PCBkYXRhLT5yZWFsTG9jYWxlTmFtZQovLyAgICAgICAgICAgICAgICAgICA8PCAiLCAiIDw8IGRlYyA8PCBkYXRhLT5ydWxlVGFibGUuc2l6ZSgpIDw8ICIgY2hhcmFjdGVycyIKLy8gICAgICAgICAgICAgICAgICAgPDwgZW5kbDsKI2VuZGlmCiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiNpZmRlZiBfREVCVUcKLy8gICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgbmFtZTsKLy8gICAgICAgICAgICAgIGNlcnIgPDwgIlVuYWJsZSB0byBsb2FkIHRhYmxlIGNvbGxhdGlvbiBydWxlcyBkeW5hbWljYWxseSBmb3IgIgovLyAgICAgICAgICAgICAgICAgIDw8IGRhdGEtPmRlc2lyZWRMb2NhbGUuZ2V0TmFtZShuYW1lKQovLyAgICAgICAgICAgICAgICAgIDw8ICIgYXQgIgovLyAgICAgICAgICAgICAgICAgIDw8IGRhdGEtPnJlYWxMb2NhbGVOYW1lCi8vICAgICAgICAgICAgICAgICAgPDwgZW5kbDsKLy8gICAgICAgICAgICAgIGNlcnIgPDwgIlN0YXR1cyAiIDw8IHVfZXJyb3JOYW1lKHN0YXR1cykgPDwgIiwgbVBhdHRlcm4gIiA8PCB0ZW1wLm1QYXR0ZXJuIDw8IGVuZGw7CiNlbmRpZgogICAgICAgICAgICAvKiBTUkwgaGF2ZSB0byBhZGQgdGhpcyBiZWNhdXNlIHdlIG5vdyBoYXZlIHRoZSBzaXR1YXRpb24gd2hlcmUKICAgICAgICAgICAgICAgREVGQVVMVCBpcyBsb2FkZWQgZnJvbSBhIGJpbmFyeSBmaWxlIHcvIG5vIHJ1bGVzLiAqLwogICAgICAgICAgICBVRXJyb3JDb2RlIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAgICAgICAgdGVtcC5jb25zdHJ1Y3RGcm9tUnVsZXMoUnVsZUJhc2VkQ29sbGF0b3I6OkRFRkFVTFRSVUxFUywgaW50U3RhdHVzKTsKCiAgICAgICAgICAgIGlmKFVfU1VDQ0VTUyhpbnRTdGF0dXMpICYmICh0ZW1wLm1QYXR0ZXJuICE9IDApKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRhdGEtPnJ1bGVUYWJsZSA9IHRlbXAuZ2V0UnVsZXMoKTsKICAgICAgICAgICAgICAgIGRhdGEtPmlzUnVsZVRhYmxlTG9hZGVkID0gVFJVRTsKICAgICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBkYXRhLT5ydWxlVGFibGU7Cn0KCgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbGVuZ3RoKSBjb25zdAp7CiAgICBVbmljb2RlU3RyaW5nIHNvdXJjZV90b2dvOwogICAgVW5pY29kZVN0cmluZyB0YXJnZXRfdG9nbzsKICAgIFVUZXh0T2Zmc2V0IGJlZ2luPTA7CgogICAgc291cmNlLmV4dHJhY3QoYmVnaW4sIHVwcnZfbWluKGxlbmd0aCxzb3VyY2UubGVuZ3RoKCkpLCBzb3VyY2VfdG9nbyk7CiAgICB0YXJnZXQuZXh0cmFjdChiZWdpbiwgdXBydl9taW4obGVuZ3RoLHRhcmdldC5sZW5ndGgoKSksIHRhcmdldF90b2dvKTsKICAgIHJldHVybiAoUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoc291cmNlX3RvZ28sIHRhcmdldF90b2dvKSk7Cn0KCkNvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCAgIApSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZShjb25zdCAgIFVDaGFyKiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCAgIFVDaGFyKiAgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCB0YXJnZXRMZW5ndGgpIGNvbnN0CnsKCVVDb2xsYXRpb25SZXN1bHQgc3RyY29sbF9yZXN1bHQgPSB1Y29sX3N0cmNvbGwoKFVDb2xsYXRvciAqKXRoaXMsIHNvdXJjZSwgc291cmNlTGVuZ3RoLCB0YXJnZXQsIHRhcmdldExlbmd0aCk7CgkKCWlmKHN0cmNvbGxfcmVzdWx0ID09IFVDT0xfTEVTUykgewoJCXJldHVybiBDb2xsYXRvcjo6TEVTUzsKCX0gZWxzZSBpZihzdHJjb2xsX3Jlc3VsdCA9PSBVQ09MX0dSRUFURVIpIHsKCQlyZXR1cm4gQ29sbGF0b3I6OkdSRUFURVI7Cgl9IGVsc2UgewoJCXJldHVybiBDb2xsYXRvcjo6RVFVQUw7Cgl9Cn0KCkNvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCAgIApSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZUV4KGNvbnN0ICAgVUNoYXIqIHNvdXJjZSwgCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVUNoYXIqICB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHRhcmdldExlbmd0aCkgY29uc3QKewoKICAgIC8vIGNoZWNrIGlmIHNvdXJjZSBhbmQgdGFyZ2V0IGFyZSB2YWxpZCBzdHJpbmdzCiAgICBpZiAoKChzb3VyY2UgPT0gMCkgJiYgKHRhcmdldCA9PSAwKSkgfHwKICAgICAgICAoKHNvdXJjZUxlbmd0aCA9PSAwKSAmJiAodGFyZ2V0TGVuZ3RoID09IDApKSkKICAgIHsKICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgfQoKICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBDb2xsYXRvcjo6RVFVQUw7CiAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKCiAgICBpZiAoY3Vyc29yMSA9PSBOVUxMKQogICAgewogICAgICAgICgoUnVsZUJhc2VkQ29sbGF0b3IgKil0aGlzKS0+Y3Vyc29yMSA9IG5ldyBOb3JtYWxpemVySXRlcmF0b3Ioc291cmNlLCBzb3VyY2VMZW5ndGgsIGdldERlY29tcG9zaXRpb24oKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgY3Vyc29yMS0+c2V0TW9kZUFuZFRleHQoZ2V0RGVjb21wb3NpdGlvbigpLCBzb3VyY2UsIHNvdXJjZUxlbmd0aCwgc3RhdHVzKTsKICAgIH0KCiAgICBpZiAoIC8qY3Vyc29yMS0+Y3Vyc29yID09IE5VTEwgfHwqLyBVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgfQoKICAgIGlmIChjdXJzb3IyID09IE5VTEwpCiAgICB7CiAgICAgICAgKChSdWxlQmFzZWRDb2xsYXRvciAqKXRoaXMpLT5jdXJzb3IyID0gbmV3IE5vcm1hbGl6ZXJJdGVyYXRvcih0YXJnZXQsIHRhcmdldExlbmd0aCwgZ2V0RGVjb21wb3NpdGlvbigpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBjdXJzb3IyLT5zZXRNb2RlQW5kVGV4dChnZXREZWNvbXBvc2l0aW9uKCksIHRhcmdldCwgdGFyZ2V0TGVuZ3RoLCBzdGF0dXMpOwogICAgfQoKICAgIGlmICgvKmN1cnNvcjIgPT0gTlVMTCB8fCovIFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7CiAgICB9CgogICAgaW50MzJfdCBzT3JkZXIsIHRPcmRlcjsKICAgIC8vICAgIGludDMyX3Qgc09yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIsIHRPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSOwogICAgVUJvb2wgZ2V0cyA9IFRSVUUsIGdldHQgPSBUUlVFOwogICAgVUJvb2wgaW5pdGlhbENoZWNrU2VjVGVyID0gZ2V0U3RyZW5ndGgoKSA+PSBDb2xsYXRvcjo6U0VDT05EQVJZOwogICAgVUJvb2wgY2hlY2tTZWNUZXIgPSBpbml0aWFsQ2hlY2tTZWNUZXI7CiAgICBVQm9vbCBjaGVja1RlcnRpYXJ5ID0gZ2V0U3RyZW5ndGgoKSA+PSBDb2xsYXRvcjo6VEVSVElBUlk7CiAgICBVQm9vbCBpc0ZyZW5jaFNlYyA9IGRhdGEtPmlzRnJlbmNoU2VjOwogICAgdWludDMyX3QgcFNPcmRlciwgcFRPcmRlcjsKCiAgICBmb3IoOzspCiAgICB7CiAgICAgICAgLy8gR2V0IHRoZSBuZXh0IGNvbGxhdGlvbiBlbGVtZW50IGluIGVhY2ggb2YgdGhlIHN0cmluZ3MsIHVubGVzcwogICAgICAgIC8vIHdlJ3ZlIGJlZW4gcmVxdWVzdGVkIHRvIHNraXAgaXQuCiAgICAgICAgaWYgKGdldHMpCiAgICAgICAgewogICAgICAgICAgICBzT3JkZXIgPSBnZXRTdHJlbmd0aE9yZGVyKChOb3JtYWxpemVySXRlcmF0b3IqKWN1cnNvcjEsIHN0YXR1cyk7CgogICAgICAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGdldHMgPSBUUlVFOwoKICAgICAgICBpZiAoZ2V0dCkKICAgICAgICB7CiAgICAgICAgICAgIHRPcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoKE5vcm1hbGl6ZXJJdGVyYXRvciopY3Vyc29yMiwgc3RhdHVzKTsKCiAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpFUVVBTDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBnZXR0ID0gVFJVRTsKCiAgICAgICAgLy8gSWYgd2UndmUgaGl0IHRoZSBlbmQgb2Ygb25lIG9mIHRoZSBzdHJpbmdzLCBqdW1wIG91dCBvZiB0aGUgbG9vcAogICAgICAgIGlmICgoc09yZGVyID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKXx8CiAgICAgICAgICAgICh0T3JkZXIgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpKQogICAgICAgIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICAvLyBJZiB0aGVyZSdzIG5vIGRpZmZlcmVuY2UgYXQgdGhpcyBwb3NpdGlvbiwgd2UgY2FuIHNraXAgdG8gdGhlCiAgICAgICAgLy8gbmV4dCBvbmUuCiAgICAgICAgcFNPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKHNPcmRlcik7CiAgICAgICAgcFRPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKHRPcmRlcik7CiAgICAgICAgaWYgKHNPcmRlciA9PSB0T3JkZXIpCiAgICAgICAgewogICAgICAgICAgICBpZiAoaXNGcmVuY2hTZWMgJiYgcFNPcmRlciAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIWNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIGluIGZyZW5jaCwgYSBzZWNvbmRhcnkgZGlmZmVyZW5jZSBtb3JlIHRvIHRoZSByaWdodCBpcyBzdHJvbmdlciwKICAgICAgICAgICAgICAgICAgICAvLyBzbyBhY2NlbnRzIGhhdmUgdG8gYmUgY2hlY2tlZCB3aXRoIGVhY2ggYmFzZSBlbGVtZW50CiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWNUZXIgPSBpbml0aWFsQ2hlY2tTZWNUZXI7CgogICAgICAgICAgICAgICAgICAgIC8vIGJ1dCB0ZXJ0aWFyeSBkaWZmZXJlbmNlcyBhcmUgbGVzcyBpbXBvcnRhbnQgdGhhbiB0aGUgZmlyc3QgCiAgICAgICAgICAgICAgICAgICAgLy8gc2Vjb25kYXJ5IGRpZmZlcmVuY2UsIHNvIGNoZWNraW5nIHRlcnRpYXJ5IHJlbWFpbnMgZGlzYWJsZWQKICAgICAgICAgICAgICAgICAgICBjaGVja1RlcnRpYXJ5ID0gRkFMU0U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29tcGFyZSBwcmltYXJ5IGRpZmZlcmVuY2VzIGZpcnN0LgogICAgICAgIGlmIChwU09yZGVyICE9IHBUT3JkZXIpCiAgICAgICAgewogICAgICAgICAgICBpZiAoc09yZGVyID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBlbnRpcmUgc291cmNlIGVsZW1lbnQgaXMgaWdub3JhYmxlLgogICAgICAgICAgICAgICAgLy8gU2tpcCB0byB0aGUgbmV4dCBzb3VyY2UgZWxlbWVudCwgYnV0IGRvbid0IGZldGNoIGFub3RoZXIgdGFyZ2V0IGVsZW1lbnQuCiAgICAgICAgICAgICAgICBnZXR0ID0gRkFMU0U7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRPcmRlciA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBnZXRzID0gRkFMU0U7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVGhlIHNvdXJjZSBhbmQgdGFyZ2V0IGVsZW1lbnRzIGFyZW4ndCBpZ25vcmFibGUsIGJ1dCBpdCdzIHN0aWxsIHBvc3NpYmxlCiAgICAgICAgICAgIC8vIGZvciB0aGUgcHJpbWFyeSBjb21wb25lbnQgb2Ygb25lIG9mIHRoZSBlbGVtZW50cyB0byBiZSBpZ25vcmFibGUuLi4uCiAgICAgICAgICAgIGlmIChwU09yZGVyID09IDApICAvLyBwcmltYXJ5IG9yZGVyIGluIHNvdXJjZSBpcyBpZ25vcmFibGUKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gVGhlIHNvdXJjZSdzIHByaW1hcnkgaXMgaWdub3JhYmxlLCBidXQgdGhlIHRhcmdldCdzIGlzbid0LiAgV2UgdHJlYXQgaWdub3JhYmxlcwogICAgICAgICAgICAgICAgLy8gYXMgYSBzZWNvbmRhcnkgZGlmZmVyZW5jZSwgc28gcmVtZW1iZXIgdGhhdCB3ZSBmb3VuZCBvbmUuCiAgICAgICAgICAgICAgICBpZiAoY2hlY2tTZWNUZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gQ29sbGF0b3I6OkdSRUFURVI7ICAvLyAoc3RyZW5ndGggaXMgU0VDT05EQVJZKQogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gRkFMU0U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gU2tpcCB0byB0aGUgbmV4dCBzb3VyY2UgZWxlbWVudCwgYnV0IGRvbid0IGZldGNoIGFub3RoZXIgdGFyZ2V0IGVsZW1lbnQuCiAgICAgICAgICAgICAgICBnZXR0ID0gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocFRPcmRlciA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyByZWNvcmQgZGlmZmVyZW5jZXMgLSBzZWUgdGhlIGNvbW1lbnQgYWJvdmUuCiAgICAgICAgICAgICAgICBpZiAoY2hlY2tTZWNUZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gQ29sbGF0b3I6OkxFU1M7ICAvLyAoc3RyZW5ndGggaXMgU0VDT05EQVJZKQogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gRkFMU0U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gU2tpcCB0byB0aGUgbmV4dCB0YXJnZXQgZWxlbWVudCwgYnV0IGRvbid0IGZldGNoIGFub3RoZXIgc291cmNlIGVsZW1lbnQuCiAgICAgICAgICAgICAgICBnZXRzID0gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBOZWl0aGVyIG9mIHRoZSBvcmRlcnMgaXMgaWdub3JhYmxlLCBhbmQgd2UgYWxyZWFkeSBrbm93IHRoYXQgdGhlIHByaW1hcnkKICAgICAgICAgICAgICAgIC8vIG9yZGVycyBhcmUgZGlmZmVyZW50IGJlY2F1c2Ugb2YgdGhlIChwU09yZGVyICE9IHBUT3JkZXIpIHRlc3QgYWJvdmUuCiAgICAgICAgICAgICAgICAvLyBSZWNvcmQgdGhlIGRpZmZlcmVuY2UgYW5kIHN0b3AgdGhlIGNvbXBhcmlzb24uCiAgICAgICAgICAgICAgICBpZiAocFNPcmRlciA8IHBUT3JkZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpMRVNTOyAgLy8gKHN0cmVuZ3RoIGlzIFBSSU1BUlkpCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpHUkVBVEVSOyAgLy8gKHN0cmVuZ3RoIGlzIFBSSU1BUlkpCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsgLy8gZWxzZSBvZiBpZiAoIHBTT3JkZXIgIT0gcFRPcmRlciApCiAgICAgICAgICAgIC8vIHByaW1hcnkgb3JkZXIgaXMgdGhlIHNhbWUsIGJ1dCBjb21wbGV0ZSBvcmRlciBpcyBkaWZmZXJlbnQuIFNvIHRoZXJlCiAgICAgICAgICAgIC8vIGFyZSBubyBiYXNlIGVsZW1lbnRzIGF0IHRoaXMgcG9pbnQsIG9ubHkgaWdub3JhYmxlcyAoU2luY2UgdGhlIHN0cmluZ3MgYXJlCiAgICAgICAgICAgIC8vIG5vcm1hbGl6ZWQpCgogICAgICAgICAgICBpZiAoY2hlY2tTZWNUZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGEgc2Vjb25kYXJ5IG9yIHRlcnRpYXJ5IGRpZmZlcmVuY2UgbWF5IHN0aWxsIG1hdHRlcgogICAgICAgICAgICAgICAgdWludDMyX3Qgc2VjU09yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcihzT3JkZXIpOwogICAgICAgICAgICAgICAgdWludDMyX3Qgc2VjVE9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcih0T3JkZXIpOwoKICAgICAgICAgICAgICAgIGlmIChzZWNTT3JkZXIgIT0gc2VjVE9yZGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIHRoZXJlIGlzIGEgc2Vjb25kYXJ5IGRpZmZlcmVuY2UKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAoc2VjU09yZGVyIDwgc2VjVE9yZGVyKSA/IENvbGxhdG9yOjpMRVNTIDogQ29sbGF0b3I6OkdSRUFURVI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOyAKICAgICAgICAgICAgICAgICAgICAvLyAoZXZlbiBpbiBmcmVuY2gsIG9ubHkgdGhlIGZpcnN0IHNlY29uZGFyeSBkaWZmZXJlbmNlIHdpdGhpbgogICAgICAgICAgICAgICAgICAgIC8vICBhIGJhc2UgY2hhcmFjdGVyIG1hdHRlcnMpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoZWNrVGVydGlhcnkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBhIHRlcnRpYXJ5IGRpZmZlcmVuY2UgbWF5IHN0aWxsIG1hdHRlcgogICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCB0ZXJTT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnRlcnRpYXJ5T3JkZXIoc09yZGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgdGVyVE9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp0ZXJ0aWFyeU9yZGVyKHRPcmRlcik7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVyU09yZGVyICE9IHRlclRPcmRlcikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlcmUgaXMgYSB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAodGVyU09yZGVyIDwgdGVyVE9yZGVyKSA/IENvbGxhdG9yOjpMRVNTIDogQ29sbGF0b3I6OkdSRUFURVI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKHN0cmVuZ3RoIGlzIFRFUlRJQVJZKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tUZXJ0aWFyeSA9IEZBTFNFOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IC8vIGlmIChjaGVja1NlY1RlcikKCiAgICAgICAgfSAgLy8gaWYgKCBwU09yZGVyICE9IHBUT3JkZXIgKQogICAgfSAvLyB3aGlsZSgpCgogICAgaWYgKHNPcmRlciAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUikKICAgIHsKICAgICAgICAvLyAodE9yZGVyIG11c3QgYmUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIsCiAgICAgICAgLy8gIHNpbmNlIHRoaXMgcG9pbnQgaXMgb25seSByZWFjaGVkIHdoZW4gc09yZGVyIG9yIHRPcmRlciBpcyBOVUxMT1JERVIuKQogICAgICAgIC8vIFRoZSBzb3VyY2Ugc3RyaW5nIGhhcyBtb3JlIGVsZW1lbnRzLCBidXQgdGhlIHRhcmdldCBzdHJpbmcgaGFzbid0LgogICAgICAgIGRvCiAgICAgICAgewogICAgICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIoc09yZGVyKSAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBXZSBmb3VuZCBhbiBhZGRpdGlvbmFsIG5vbi1pZ25vcmFibGUgYmFzZSBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgcHJpbWFyeSBkaWZmZXJlbmNlLCBzbyB0aGUgc291cmNlIGlzIGdyZWF0ZXIKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6R1JFQVRFUjsgLy8gKHN0cmVuZ3RoIGlzIFBSSU1BUlkpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKHNPcmRlcikgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gQWRkaXRpb25hbCBzZWNvbmRhcnkgZWxlbWVudHMgbWVhbiB0aGUgc291cmNlIHN0cmluZyBpcyBncmVhdGVyCiAgICAgICAgICAgICAgICBpZiAoY2hlY2tTZWNUZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gQ29sbGF0b3I6OkdSRUFURVI7ICAvLyAoc3RyZW5ndGggaXMgU0VDT05EQVJZKQogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gRkFMU0U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gCiAgICAgICAgfQogICAgICAgIHdoaWxlICgoc09yZGVyID0gZ2V0U3RyZW5ndGhPcmRlcihjdXJzb3IxLCBzdGF0dXMpKSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUik7CiAgICB9CiAgICBlbHNlIGlmICh0T3JkZXIgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpCiAgICB7CiAgICAgICAgLy8gVGhlIHRhcmdldCBzdHJpbmcgaGFzIG1vcmUgZWxlbWVudHMsIGJ1dCB0aGUgc291cmNlIHN0cmluZyBoYXNuJ3QuCiAgICAgICAgZG8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByaW1hcnlPcmRlcih0T3JkZXIpICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFdlIGZvdW5kIGFuIGFkZGl0aW9uYWwgbm9uLWlnbm9yYWJsZSBiYXNlIGNoYXJhY3RlciBpbiB0aGUgdGFyZ2V0IHN0cmluZy4KICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBwcmltYXJ5IGRpZmZlcmVuY2UsIHNvIHRoZSBzb3VyY2UgaXMgbGVzcwogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpMRVNTOyAvLyAoc3RyZW5ndGggaXMgUFJJTUFSWSkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIodE9yZGVyKSAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBBZGRpdGlvbmFsIHNlY29uZGFyeSBlbGVtZW50cyBpbiB0aGUgdGFyZ2V0IG1lYW4gdGhlIHNvdXJjZSBzdHJpbmcgaXMgbGVzcwogICAgICAgICAgICAgICAgaWYgKGNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpMRVNTOyAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IAogICAgICAgIH0KICAgICAgICB3aGlsZSAoKHRPcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoY3Vyc29yMiwgc3RhdHVzKSkgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpOwogICAgfQoKCiAgICAvLyBGb3IgSURFTlRJQ0FMIGNvbXBhcmlzb25zLCB3ZSB1c2UgYSBiaXR3aXNlIGNoYXJhY3RlciBjb21wYXJpc29uCiAgICAvLyBhcyBhIHRpZWJyZWFrZXIgaWYgYWxsIGVsc2UgaXMgZXF1YWwKICAgIC8vIE5PVEU6IFRoZSBqYXZhIGNvZGUgY29tcGFyZXMgcmVzdWx0IHdpdGggMCwgYW5kIAogICAgLy8gcHV0cyB0aGUgcmVzdWx0IG9mIHRoZSBzdHJpbmcgY29tcGFyaXNvbiBkaXJlY3RseSBpbnRvIHJlc3VsdAogICAgaWYgKHJlc3VsdCA9PSBDb2xsYXRvcjo6RVFVQUwgJiYgZ2V0U3RyZW5ndGgoKSA9PSBJREVOVElDQUwpCiAgICB7CiNpZiAwCiAgICAgIC8vICoqKioqKioqIGZvciB0aGUgIFVDaGFyIG5vcm1hbGl6YXRpb24gaW50ZXJmYWNlLgogICAgICAvLyBJdCBkb2Vzbid0IHdvcmsgbXVjaCBmYXN0ZXIsIGFuZCB0aGUgY29kZSB3YXMgYnJva2VuCiAgICAgIC8vIHNvIGl0J3MgY29tbWVudGVkIG91dC4gLS1zcmwKLy8gICAgICAgICAgVUNoYXIgc291cmNlRGVjb21wWzEwMjRdLCB0YXJnZXREZWNvbXBbMTAyNF07Ci8vICAgICAgICAgIGludDMyX3Qgc291cmNlRGVjb21wTGVuZ3RoID0gMTAyNDsKLy8gICAgICAgICAgaW50MzJfdCB0YXJnZXREZWNvbXBMZW5ndGggPSAxMDI0OwoKLy8gICAgICAgICAgaW50OF90IGNvbXBhcmlzb247Ci8vICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcE1vZGUgPSBnZXREZWNvbXBvc2l0aW9uKCk7CgovLyAgICAgICAgICBpZiAoZGVjb21wTW9kZSAhPSBOb3JtYWxpemVyOjpOT19PUCkKLy8gICAgICAgICAgICB7Ci8vICAgICAgICAgICAgICBOb3JtYWxpemVyOjpub3JtYWxpemUoc291cmNlLCBzb3VyY2VMZW5ndGgsIGRlY29tcE1vZGUsCi8vICAgICAgICAgICAgICAgICAgICAgICAgMCwgc291cmNlRGVjb21wLCBzb3VyY2VEZWNvbXBMZW5ndGgsIHN0YXR1cyk7CgovLyAgICAgICAgICAgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKHRhcmdldCwgdGFyZ2V0TGVuZ3RoLCBkZWNvbXBNb2RlLAovLyAgICAgICAgICAgICAgICAgICAgICAgIDAsIHRhcmdldERlY29tcCwgdGFyZ2V0RGVjb21wTGVuZ3RoLCBzdGF0dXMpOwoKLy8gICAgICAgICAgICAgIGNvbXBhcmlzb24gPSB1X3N0cmNtcChzb3VyY2VEZWNvbXAsdGFyZ2V0RGVjb21wKTsKLy8gICAgICAgICAgICB9Ci8vICAgICAgICAgIGVsc2UKLy8gICAgICAgICAgICB7Ci8vICAgICAgICAgICAgICBjb21wYXJpc29uID0gdV9zdHJjbXAoc291cmNlLCB0YXJnZXQpOyAvKiAhICovCi8vICAgICAgICAgICAgfQoKI2Vsc2UKCiAgICAgICAgVW5pY29kZVN0cmluZyBzb3VyY2VEZWNvbXAsIHRhcmdldERlY29tcDsKCiAgICAgICAgaW50OF90IGNvbXBhcmlzb247CiAgICAgICAgCiAgICAgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKFVuaWNvZGVTdHJpbmcoc291cmNlLCBzb3VyY2VMZW5ndGgpLCBnZXREZWNvbXBvc2l0aW9uKCksIAogICAgICAgICAgICAgICAgICAgICAgMCwgc291cmNlRGVjb21wLCAgc3RhdHVzKTsKCiAgICAgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKFVuaWNvZGVTdHJpbmcodGFyZ2V0LCB0YXJnZXRMZW5ndGgpLCBnZXREZWNvbXBvc2l0aW9uKCksIAogICAgICAgICAgICAgICAgICAgICAgMCwgdGFyZ2V0RGVjb21wLCAgc3RhdHVzKTsKICAgICAgICAKICAgICAgICBjb21wYXJpc29uID0gc291cmNlRGVjb21wLmNvbXBhcmUodGFyZ2V0RGVjb21wKTsKI2VuZGlmCgogICAgICAgIGlmIChjb21wYXJpc29uIDwgMCkKICAgICAgICB7CiAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpMRVNTOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChjb21wYXJpc29uID09IDApCiAgICAgICAgewogICAgICAgICAgICByZXN1bHQgPSBDb2xsYXRvcjo6RVFVQUw7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpHUkVBVEVSOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9CgppbnQzMl90ClJ1bGVCYXNlZENvbGxhdG9yOjpuZXh0Q29udHJhY3RDaGFyKE5vcm1hbGl6ZXJJdGVyYXRvciAqY3Vyc29yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNoYXIgY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QKewogICAgLy8gRmlyc3QgZ2V0IHRoZSBvcmRlcmluZyBvZiB0aGlzIHNpbmdsZSBjaGFyYWN0ZXIKICAgIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50ICpsaXN0ID0gZ2V0Q29udHJhY3RWYWx1ZXMoY2gpOwogICAgRW50cnlQYWlyICpwYWlyID0gKEVudHJ5UGFpciAqKWxpc3QtPmF0KDApOwogICAgaW50MzJfdCBvcmRlciA9IHBhaXItPnZhbHVlOwoKICAgIC8vIE5vdyBpdGVyYXRlIHRocm91Z2ggdGhlIGNoYXJzIGZvbGxvd2luZyBpdCBhbmQKICAgIC8vIGxvb2sgZm9yIHRoZSBsb25nZXN0IG1hdGNoCiAgICAoKFVuaWNvZGVTdHJpbmcmKWtleSkucmVtb3ZlKCk7CiAgICAoKFVuaWNvZGVTdHJpbmcmKWtleSkgKz0gY2g7CgogICAgd2hpbGUgKChjaCA9IGN1cnNvci0+Y3VycmVudCgpKSAhPSBOb3JtYWxpemVyOjpET05FKQogICAgewogICAgICAgICgoVW5pY29kZVN0cmluZyYpa2V5KSArPSBjaDsKCiAgICAgICAgaW50MzJfdCBuID0gZ2V0RW50cnkobGlzdCwga2V5LCBUUlVFKTsKCiAgICAgICAgaWYgKG4gPT0gVU5NQVBQRUQpCiAgICAgICAgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY3Vyc29yLT5uZXh0KCk7CgogICAgICAgIHBhaXIgPSAoRW50cnlQYWlyICopbGlzdC0+YXQobik7CiAgICAgICAgb3JkZXIgPSBwYWlyLT52YWx1ZTsKICAgIH0KCiAgICByZXR1cm4gb3JkZXI7Cn0KCi8vIENvbXBhcmUgdHdvIHN0cmluZ3MgdXNpbmcgdGhpcyBjb2xsYXRvcgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0CnsKCVVDaGFyIHVTc3RhcnRbdGJsY29sbF9TdGFja0J1ZmZlckxlbl07CglVQ2hhciB1VHN0YXJ0W3RibGNvbGxfU3RhY2tCdWZmZXJMZW5dOwoJVUNoYXIgKnVTb3VyY2UgPSB1U3N0YXJ0OwoJVUNoYXIgKnVUYXJnZXQgPSB1VHN0YXJ0OwoJdWludDMyX3Qgc291cmNlTGVuID0gc291cmNlLmxlbmd0aCgpOwoJdWludDMyX3QgdGFyZ2V0TGVuID0gdGFyZ2V0Lmxlbmd0aCgpOwoJaWYoc291cmNlTGVuID49IHRibGNvbGxfU3RhY2tCdWZmZXJMZW4pIHsKCQl1U291cmNlID0gbmV3IFVDaGFyW3NvdXJjZUxlbisxXTsKCX0KCWlmKHRhcmdldExlbiA+PSB0Ymxjb2xsX1N0YWNrQnVmZmVyTGVuKSB7CgkJdVRhcmdldCA9IG5ldyBVQ2hhclt0YXJnZXRMZW4rMV07Cgl9CiAgICBzb3VyY2UuZXh0cmFjdCgwLCBzb3VyY2VMZW4sIHVTb3VyY2UpOwogICAgdVNvdXJjZVtzb3VyY2VMZW5dID0gMDsKICAgIHRhcmdldC5leHRyYWN0KDAsIHRhcmdldExlbiwgdVRhcmdldCk7CiAgICB1VGFyZ2V0W3RhcmdldExlbl0gPSAwOwoJQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IHJlc3VsdCA9IGNvbXBhcmUodVNvdXJjZSwgc291cmNlTGVuLCB1VGFyZ2V0LCB0YXJnZXRMZW4pOwoKCWlmKHVTc3RhcnQgIT0gdVNvdXJjZSkgewoJCWRlbGV0ZVtdIHVTb3VyY2U7Cgl9CglpZih1VHN0YXJ0ICE9IHVUYXJnZXQpIHsKCQlkZWxldGVbXSB1VGFyZ2V0OwoJfQoJcmV0dXJuIHJlc3VsdDsKfQoKLy8gUmV0cmlldmUgYSBjb2xsYXRpb24ga2V5IGZvciB0aGUgc3BlY2lmaWVkIHN0cmluZwovLyBUaGUga2V5IGNhbiBiZSBjb21wYXJlZCB3aXRoIG90aGVyIGNvbGxhdGlvbiBrZXlzIHVzaW5nIGEgYml0d2lzZSBjb21wYXJpc29uCi8vIChlLmcuIG1lbWNtcCkgdG8gZmluZCB0aGUgb3JkZXJpbmcgb2YgdGhlaXIgcmVzcGVjdGl2ZSBzb3VyY2Ugc3RyaW5ncy4KLy8gVGhpcyBpcyBoYW5keSB3aGVuIGRvaW5nIGEgc29ydCwgd2hlcmUgZWFjaCBzb3J0IGtleSBtdXN0IGJlIGNvbXBhcmVkCi8vIG1hbnkgdGltZXMuCi8vCi8vIFRoZSBiYXNpYyBhbGdvcml0aG0gaGVyZSBpcyB0byBmaW5kIGFsbCBvZiB0aGUgY29sbGF0aW9uIGVsZW1lbnRzIGZvciBlYWNoCi8vIGNoYXJhY3RlciBpbiB0aGUgc291cmNlIHN0cmluZywgY29udmVydCB0aGVtIHRvIGFuIEFTQ0lJIHJlcHJlc2VudGF0aW9uLAovLyBhbmQgcHV0IHRoZW0gaW50byB0aGUgY29sbGF0aW9uIGtleS4gIEJ1dCBpdCdzIHRyaWNraWVyIHRoYW4gdGhhdC4KLy8gRWFjaCBjb2xsYXRpb24gZWxlbWVudCBpbiBhIHN0cmluZyBoYXMgdGhyZWUgY29tcG9uZW50czogcHJpbWFyeSAoJ0EnIHZzICdCJyksCi8vIHNlY29uZGFyeSAoJ3UnIHZzICf8JyksIGFuZCB0ZXJ0aWFyeSAoJ0EnIHZzICdhJyksIGFuZCBhIHByaW1hcnkgZGlmZmVyZW5jZQovLyBhdCB0aGUgZW5kIG9mIGEgc3RyaW5nIHRha2VzIHByZWNlZGVuY2Ugb3ZlciBhIHNlY29uZGFyeSBvciB0ZXJ0aWFyeQovLyBkaWZmZXJlbmNlIGVhcmxpZXIgaW4gdGhlIHN0cmluZy4KLy8KLy8gVG8gYWNjb3VudCBmb3IgdGhpcywgd2UgcHV0IGFsbCBvZiB0aGUgcHJpbWFyeSBvcmRlcnMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUKLy8gc3RyaW5nLCBmb2xsb3dlZCBieSB0aGUgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBvcmRlcnMuIEVhY2ggc2V0IG9mIG9yZGVycyBpcwovLyB0ZXJtaW5hdGVkIGJ5IG51bGxzIHNvIHRoYXQgYSBrZXkgZm9yIGEgc3RyaW5nIHdoaWNoIGlzIGEgaW5pdGlhbCBzdWJzdHJpbmcgb2YKLy8gYW5vdGhlciBrZXkgd2lsbCBjb21wYXJlIGxlc3Mgd2l0aG91dCBhbnkgc3BlY2lhbCBjYXNlLgovLwovLyBIZXJlJ3MgYSBoeXBvdGhldGljYWwgZXhhbXBsZSwgd2l0aCB0aGUgY29sbGF0aW9uIGVsZW1lbnQgcmVwcmVzZW50ZWQgYXMKLy8gYSB0aHJlZS1kaWdpdCBudW1iZXIsIG9uZSBkaWdpdCBmb3IgcHJpbWFyeSwgb25lIGZvciBzZWNvbmRhcnksIGV0Yy4KLy8KLy8gU3RyaW5nOiAgICAgICAgICAgICAgQSAgICAgYSAgICAgQiAgICDJCi8vIENvbGxhdGlvbiBFbGVtZW50czogMTAxICAgMTAwICAgMjAxICA1MTEKLy8gQ29sbGF0aW9uIEtleTogICAgICAxMTI1PG51bGw+MDAwMTxudWxsPjEwMTE8bnVsbD4KLy8KLy8gVG8gbWFrZSB0aGluZ3MgZXZlbiB0cmlja2llciwgc2Vjb25kYXJ5IGRpZmZlcmVuY2VzIChhY2NlbnQgbWFya3MpIGFyZSBjb21wYXJlZAovLyBzdGFydGluZyBhdCB0aGUgKmVuZCogb2YgdGhlIHN0cmluZyBpbiBsYW5ndWFnZXMgd2l0aCBGcmVuY2ggc2Vjb25kYXJ5IG9yZGVyaW5nLgovLyBCdXQgd2hlbiBjb21wYXJpbmcgdGhlIGFjY2VudCBtYXJrcyBvbiBhIHNpbmdsZSBiYXNlIGNoYXJhY3RlciwgdGhleSBhcmUgY29tcGFyZWQKLy8gZnJvbSB0aGUgYmVnaW5uaW5nLiAgVG8gaGFuZGxlIHRoaXMsIHdlIHJldmVyc2UgYWxsIG9mIHRoZSBhY2NlbnRzIHRoYXQgYmVsb25nCi8vIHRvIGVhY2ggYmFzZSBjaGFyYWN0ZXIsIHRoZW4gd2UgcmV2ZXJzZSB0aGUgZW50aXJlIHN0cmluZyBvZiBzZWNvbmRhcnkgb3JkZXJpbmdzCi8vIGF0IHRoZSBlbmQuCi8vCkNvbGxhdGlvbktleSYKUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbGxhdGlvbktleSggY29uc3QgICBVbmljb2RlU3RyaW5nJiAgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25LZXkmICAgc29ydGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpIGNvbnN0CnsKCVVDaGFyIHNTdGFydFt0Ymxjb2xsX1N0YWNrQnVmZmVyTGVuXTsKCVVDaGFyICp1U291cmNlID0gc1N0YXJ0OwoJdWludDMyX3Qgc291cmNlTGVuID0gc291cmNlLmxlbmd0aCgpOwoJaWYoc291cmNlTGVuID49IHRibGNvbGxfU3RhY2tCdWZmZXJMZW4pIHsKCQl1U291cmNlID0gbmV3IFVDaGFyW3NvdXJjZUxlbisxXTsKCX0KICAgIHNvdXJjZS5leHRyYWN0KDAsIHNvdXJjZUxlbiwgdVNvdXJjZSk7CiAgICB1U291cmNlW3NvdXJjZUxlbl0gPSAwOwoJQ29sbGF0aW9uS2V5JiByZXN1bHQgPSBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29sbGF0aW9uS2V5KHVTb3VyY2UsIHNvdXJjZUxlbiwgc29ydGtleSwgc3RhdHVzKTsKCWlmKHNTdGFydCAhPSB1U291cmNlKSB7CgkJZGVsZXRlW10gdVNvdXJjZTsKCX0KCXJldHVybiByZXN1bHQ7Cn0KCkNvbGxhdGlvbktleSYKUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbGxhdGlvbktleSggY29uc3QgICBVQ2hhciogIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYgICBzb3J0a2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykgY29uc3QKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsKICAgICAgICByZXR1cm4gc29ydGtleS5zZXRUb0JvZ3VzKCk7CiAgICB9CiAgICAKICAgIGlmICgoIXNvdXJjZSkgfHwgKHNvdXJjZUxlbiA9PSAwKSkKICAgIHsKICAgICAgICByZXR1cm4gc29ydGtleS5yZXNldCgpOwogICAgfQoKCXVpbnQ4X3QgcmVzdWx0W3RibGNvbGxfU3RhY2tCdWZmZXJMZW5dOwoJdWludDhfdCAqYWxsb2NSZXMgPSByZXN1bHQ7CglpbnQzMl90IHJlc0xlbiA9IHVjb2xfZ2V0U29ydEtleSgoVUNvbGxhdG9yICopdGhpcywgc291cmNlLCBzb3VyY2VMZW4sIGFsbG9jUmVzLCB0Ymxjb2xsX1N0YWNrQnVmZmVyTGVuKTsKCS8vIGlmIHRoZSByZXN1bHQgaXMgdG9vIGJpZwoJaWYocmVzTGVuID4gdGJsY29sbF9TdGFja0J1ZmZlckxlbikgewoJCWFsbG9jUmVzID0gbmV3IHVpbnQ4X3RbcmVzTGVuXTsKCQlyZXNMZW4gPSB1Y29sX2dldFNvcnRLZXkoKFVDb2xsYXRvciAqKXRoaXMsIHNvdXJjZSwgc291cmNlTGVuLCBhbGxvY1JlcywgdGJsY29sbF9TdGFja0J1ZmZlckxlbik7Cgl9Cglzb3J0a2V5ID0gQ29sbGF0aW9uS2V5KGFsbG9jUmVzLCByZXNMZW4pOwoJaWYoYWxsb2NSZXMgIT0gcmVzdWx0KSB7CgkJZGVsZXRlW10gYWxsb2NSZXM7Cgl9CgoJcmV0dXJuIHNvcnRrZXk7Cn0KCkNvbGxhdGlvbktleSYKUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbGxhdGlvbktleUV4KCBjb25zdCAgIFVDaGFyKiAgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiAgIHNvcnRrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKSBjb25zdAp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SOwogICAgICAgIHJldHVybiBzb3J0a2V5LnNldFRvQm9ndXMoKTsKICAgIH0KICAgIAogICAgaWYgKCghc291cmNlKSB8fCAoc291cmNlTGVuID09IDApKQogICAgewogICAgICAgIHJldHVybiBzb3J0a2V5LnJlc2V0KCk7CiAgICB9CgogICAgaWYgKGN1cnNvcjEgPT0gTlVMTCkKICAgIHsKICAgICAgKChSdWxlQmFzZWRDb2xsYXRvciAqKXRoaXMpLT5jdXJzb3IxID0gbmV3IE5vcm1hbGl6ZXJJdGVyYXRvcihzb3VyY2UsIHNvdXJjZUxlbiwgZ2V0RGVjb21wb3NpdGlvbigpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgY3Vyc29yMS0+c2V0TW9kZUFuZFRleHQoZ2V0RGVjb21wb3NpdGlvbigpLCBzb3VyY2Usc291cmNlTGVuLCBzdGF0dXMpOwogICAgfQoKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gc29ydGtleS5zZXRUb0JvZ3VzKCk7CiAgICB9CgogICAgVUJvb2wgIGNvbXBhcmVTZWMgICA9IChnZXRTdHJlbmd0aCgpID49IENvbGxhdG9yOjpTRUNPTkRBUlkpOwogICAgVUJvb2wgIGNvbXBhcmVUZXIgICA9IChnZXRTdHJlbmd0aCgpID49IENvbGxhdG9yOjpURVJUSUFSWSk7CiAgICBVQm9vbCAgY29tcGFyZUlkZW50ID0gKGdldFN0cmVuZ3RoKCkgPT0gQ29sbGF0b3I6OklERU5USUNBTCk7CiAgICBpbnQzMl90IG9yZGVyICAgICAgICA9IDA7CiAgICBpbnQzMl90IHRvdGFsUHJpbWFyeSA9IDA7CiAgICBpbnQzMl90IHRvdGFsU2VjICAgICA9IDA7CiAgICBpbnQzMl90IHRvdGFsVGVyICAgICA9IDA7CiAgICBpbnQzMl90IHRvdGFsSWRlbnQgICAgID0gMDsKICAgIFVuaWNvZGVTdHJpbmcgZGVjb21wOwoKICAgIC8vIGl0ZXJhdGUgb3ZlciB0aGUgc291cmNlLCBjb3VudGluZyBwcmltYXJ5LCBzZWNvbmRhcnksIGFuZCB0ZXJ0aWFyeSBlbnRyaWVzCiAgICB3aGlsZSgob3JkZXIgPSBnZXRTdHJlbmd0aE9yZGVyKChOb3JtYWxpemVySXRlcmF0b3IqKWN1cnNvcjEsIHN0YXR1cykpICE9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpCiAgICB7CiAgICAgICAgaW50MzJfdCBzZWNPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIob3JkZXIpOwogICAgICAgIGludDMyX3QgdGVyT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnRlcnRpYXJ5T3JkZXIob3JkZXIpOwoKICAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc29ydGtleS5zZXRUb0JvZ3VzKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OmlzSWdub3JhYmxlKG9yZGVyKSkKICAgICAgICB7CiAgICAgICAgICAgIHRvdGFsUHJpbWFyeSArPSAxOwoKICAgICAgICAgICAgaWYgKGNvbXBhcmVTZWMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRvdGFsU2VjICs9IDE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb21wYXJlVGVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0b3RhbFRlciArPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb21wYXJlU2VjICYmIHNlY09yZGVyICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRvdGFsU2VjICs9IDE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb21wYXJlVGVyICYmIHRlck9yZGVyICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRvdGFsVGVyICs9IDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gY291bnQgdGhlIG51bGwgYnl0ZXMgYWZ0ZXIgdGhlIGVudGlyZXMKICAgIHRvdGFsUHJpbWFyeSArPSAxOwoKICAgIGlmIChjb21wYXJlU2VjKQogICAgewogICAgICAgIHRvdGFsU2VjICs9IDE7CiAgICB9CgogICAgaWYgKGNvbXBhcmVUZXIpCiAgICB7CiAgICAgICAgdG90YWxUZXIgKz0gMTsKICAgIH0KCiAgICBpZiAoY29tcGFyZUlkZW50KQogICAgewogICAgICBOb3JtYWxpemVyOjpub3JtYWxpemUoc291cmNlLCBnZXREZWNvbXBvc2l0aW9uKCksIC8vIFNSTDogPz8KICAgICAgICAgICAgICAgIDAsIGRlY29tcCwgc3RhdHVzKTsKCiAgICAgICAgaWYgKFVfU1VDQ0VTUyhzdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgdG90YWxJZGVudCA9IGRlY29tcC5sZW5ndGgoKSArIDE7CiAgICAgICAgfQogICAgfQoKICAgIC8vIENvbXB1dGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHRvIGhvbGQgdGhlIGVudHJpZXMKICAgIC8vIGFuZCBtYWtlIHN1cmUgdGhlIGtleSBjYW4gaG9sZCB0aGVtCiAgICB1aW50MzJfdCBzaXplICAgPSAyICogKHRvdGFsUHJpbWFyeSArIHRvdGFsU2VjICsgdG90YWxUZXIgKyB0b3RhbElkZW50KTsKCiAgICBzb3J0a2V5LmVuc3VyZUNhcGFjaXR5KHNpemUpOwoKICAgIGlmIChzb3J0a2V5LmlzQm9ndXMoKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybiBzb3J0a2V5OwogICAgfQoKICAgIGludDMyX3QgcHJpbWFyeUN1cnNvciA9IDA7CiAgICBpbnQzMl90IHNlY0N1cnNvciAgICAgPSAyICogdG90YWxQcmltYXJ5OwogICAgaW50MzJfdCBzZWNCYXNlICAgICAgID0gc2VjQ3Vyc29yOwogICAgaW50MzJfdCBwcmVTZWNJZ25vcmUgID0gc2VjQmFzZTsKICAgIGludDMyX3QgdGVyQ3Vyc29yICAgICA9IHNlY0N1cnNvciArICgyICogdG90YWxTZWMpOwogICAgaW50MzJfdCBpZGVudEN1cnNvciAgICAgID0gdGVyQ3Vyc29yICsgKDIgKiB0b3RhbFRlcik7CgogICAgLy8gcmVzZXQgc291cmNlIHRvIHRoZSBiZWdpbm5pbmcKICAgIGN1cnNvcjEtPnJlc2V0KCk7CgogICAgLy8gbm93IGl0ZXJhdGUgb3ZlciB0aGUgc291cmNlIGNvbXB1dGluZyB0aGUgYWN0dWFsIGVudHJpZXMKICAgIHdoaWxlKChvcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoKE5vcm1hbGl6ZXJJdGVyYXRvciopY3Vyc29yMSwgc3RhdHVzKSkgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpCiAgICB7CiAgICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHNvcnRrZXkucmVzZXQoKTsKICAgICAgICB9CgogICAgICAgIGludDMyX3QgcHJpbWFyeU9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIob3JkZXIpOwogICAgICAgIGludDMyX3Qgc2VjT3JkZXIgICAgID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcihvcmRlcik7CiAgICAgICAgaW50MzJfdCB0ZXJPcmRlciAgICAgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnRlcnRpYXJ5T3JkZXIob3JkZXIpOwoKICAgICAgICBpZiAoISBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OmlzSWdub3JhYmxlKG9yZGVyKSkKICAgICAgICB7CiAgICAgICAgICAgIHByaW1hcnlDdXJzb3IgPSBzb3J0a2V5LnN0b3JlQnl0ZXMocHJpbWFyeUN1cnNvciwgcHJpbWFyeU9yZGVyICsgU09SVEtFWU9GRlNFVCk7CgogICAgICAgICAgICBpZiAoY29tcGFyZVNlYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGRhdGEtPmlzRnJlbmNoU2VjICYmIChwcmVTZWNJZ25vcmUgPCBzZWNDdXJzb3IpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNvcnRrZXkucmV2ZXJzZUJ5dGVzKHByZVNlY0lnbm9yZSwgc2VjQ3Vyc29yKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBzZWNDdXJzb3IgPSBzb3J0a2V5LnN0b3JlQnl0ZXMoc2VjQ3Vyc29yLCBzZWNPcmRlciArIFNPUlRLRVlPRkZTRVQpOwoKICAgICAgICAgICAgICAgIHByZVNlY0lnbm9yZSA9IHNlY0N1cnNvcjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNvbXBhcmVUZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRlckN1cnNvciA9IHNvcnRrZXkuc3RvcmVCeXRlcyh0ZXJDdXJzb3IsIHRlck9yZGVyICsgU09SVEtFWU9GRlNFVCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGNvbXBhcmVTZWMgJiYgc2VjT3JkZXIgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc2VjQ3Vyc29yID0gc29ydGtleS5zdG9yZUJ5dGVzKHNlY0N1cnNvciwgc2VjT3JkZXIgKyBkYXRhLT5tYXhTZWNPcmRlciArIFNPUlRLRVlPRkZTRVQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29tcGFyZVRlciAmJiB0ZXJPcmRlciAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0ZXJDdXJzb3IgPSBzb3J0a2V5LnN0b3JlQnl0ZXModGVyQ3Vyc29yLCB0ZXJPcmRlciArIGRhdGEtPm1heFRlck9yZGVyICsgU09SVEtFWU9GRlNFVCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gYXBwZW5kIDAgYXQgdGhlIGVuZCBvZiBlYWNoIHBvcnRpb24uCiAgICBzb3J0a2V5LnN0b3JlQnl0ZXMocHJpbWFyeUN1cnNvciwgMCk7CgogICAgaWYgKGNvbXBhcmVTZWMpCiAgICB7CiAgICAgICAgaWYgKGRhdGEtPmlzRnJlbmNoU2VjKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHByZVNlY0lnbm9yZSA8IHNlY0N1cnNvcikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc29ydGtleS5yZXZlcnNlQnl0ZXMocHJlU2VjSWdub3JlLCBzZWNDdXJzb3IpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzb3J0a2V5LnJldmVyc2VCeXRlcyhzZWNCYXNlLCBzZWNDdXJzb3IpOwogICAgICAgIH0KCiAgICAgICAgc29ydGtleS5zdG9yZUJ5dGVzKHNlY0N1cnNvciwgMCk7CiAgICB9CgogICAgaWYgKGNvbXBhcmVUZXIpCiAgICB7CiAgICAgICAgc29ydGtleS5zdG9yZUJ5dGVzKHRlckN1cnNvciwgMCk7CiAgICB9CgogICAgaWYgKGNvbXBhcmVJZGVudCkKICAgIHsKICAgICAgICBzb3J0a2V5LnN0b3JlVW5pY29kZVN0cmluZyhpZGVudEN1cnNvciwgZGVjb21wKTsKICAgIH0KCiAgICAvLyAgICBEZWJ1Z2dpbmcgLSBwcmludCBvdXQgdGhlIHNvcnRrZXkgWy0tc3JsXQovLyAgICAgIHsKLy8gICAgICAgIGNvbnN0IHVpbnQ4X3QgKmJ5dGVzOwovLyAgICAgICAgaW50MzJfdCB4Y291bnQ7Ci8vICAgICAgICBieXRlcyA9IHNvcnRrZXkuZ2V0Qnl0ZUFycmF5KHhjb3VudCk7Ci8vICAgICAgICAvLyAgICAgIGZwcmludGYoc3RkZXJyLCAiXG5cbi0gIFslMDJYXSBbJTAyWF1cblxuIiwgKGludCkoYnl0ZXNbMF0mMHhGRiksIChpbnQpKGJ5dGVzWzFdJjB4RkYpICk7Ci8vICAgICAgfQoKICAgIHJldHVybiBzb3J0a2V5Owp9CgoKLy8gQnVpbGQgdGhpcyBjb2xsYXRvcidzIHJ1bGUgdGFibGVzIGJhc2VkIG9uIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBydWxlcwovLyBTZWUgdGhlIGJpZyBkaWFncmFtIGF0IHRoZSB0b3Agb2YgdGhpcyBmaWxlIGZvciBhbiBvdmVydmlldyBvZiBob3cgdGhlIHRhYmxlcwovLyBhcmUgb3JnYW5pemVkLgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpidWlsZChjb25zdCBVbmljb2RlU3RyaW5nJiAgIHBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBUaGlzIGFycmF5IG1hcHMgVW5pY29kZSBjaGFyYWN0ZXJzIHRvIHRoZWlyIGNvbGxhdGlvbiBvcmRlcmluZwogICAgZGF0YS0+bWFwcGluZyA9IHVjbXAzMl9vcGVuKFVOTUFQUEVEKTsKCiAgICBpZiAoZGF0YS0+bWFwcGluZy0+ZkJvZ3VzKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGludDMyX3QgaSA9IDA7CiAgICBVbmljb2RlU3RyaW5nIGxhc3RHcm91cENoYXJzOwogICAgVW5pY29kZVN0cmluZyBleHBDaGFyczsKICAgIFVuaWNvZGVTdHJpbmcgZ3JvdXBDaGFyczsKCiAgICBpZiAocGF0dGVybi5sZW5ndGgoKSA9PSAwKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfSU5WQUxJRF9GT1JNQVRfRVJST1I7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIEJ1aWxkIHRoZSBtZXJnZWQgY29sbGF0aW9uIGVudHJpZXMKICAgIC8vIFNpbmNlIHJ1bGVzIGNhbiBiZSBzcGVjaWZpZWQgaW4gYW55IG9yZGVyIGluIHRoZSBzdHJpbmcKICAgIC8vIChlLmcuICJjICwgQyA8IGQgLCBEIDwgZSAsIEUgLi4uLiBDIDwgQ0giKQogICAgLy8gdGhpcyBzcGxpdHMgYWxsIG9mIHRoZSBydWxlcyBpbiB0aGUgc3RyaW5nIG91dCBpbnRvIHNlcGFyYXRlCiAgICAvLyBvYmplY3RzIGFuZCB0aGVuIHNvcnRzIHRoZW0uICBJbiB0aGUgYWJvdmUgZXhhbXBsZSwgaXQgbWVyZ2VzIHRoZQogICAgLy8gIkMgPCBDSCIgcnVsZSBpbiBqdXN0IGJlZm9yZSB0aGUgIkMgPCBEIiBydWxlLgoKICAgIG1QYXR0ZXJuID0gbmV3IE1lcmdlQ29sbGF0aW9uKHBhdHRlcm4sIGdldERlY29tcG9zaXRpb24oKSwgc3RhdHVzKTsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICB1Y21wMzJfY2xvc2UoZGF0YS0+bWFwcGluZyk7CiAgICAgICAgZGF0YS0+bWFwcGluZyA9IDA7CiAgICAgICAgZGVsZXRlIG1QYXR0ZXJuOwogICAgICAgIG1QYXR0ZXJuID0gMDsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaW50MzJfdCBvcmRlciA9IDA7CgogICAgLy8gV2FsayB0aHJvdWdoIGVhY2ggZW50cnkKICAgIGZvciAoaSA9IDA7IGkgPCBtUGF0dGVybi0+Z2V0Q291bnQoKTsgKytpKQogICAgewogICAgICAgIGNvbnN0IFBhdHRlcm5FbnRyeSogZW50cnkgPSBtUGF0dGVybi0+Z2V0SXRlbUF0KGkpOwogICAgICAgIGdyb3VwQ2hhcnMucmVtb3ZlKCk7CiAgICAgICAgZXhwQ2hhcnMucmVtb3ZlKCk7CgogICAgICAgIC8vIGlmIGVudHJ5IGlzIHZhbGlkCiAgICAgICAgaWYgKGVudHJ5ICE9IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICBlbnRyeS0+Z2V0Q2hhcnMoZ3JvdXBDaGFycyk7CgogICAgICAgICAgICAvLyBjaGVjayBpZiBmcmVuY2ggc2Vjb25kYXJ5IG5lZWRzIHRvIGJlIHR1cm5lZCBvbgogICAgICAgICAgICBpZiAoKGdyb3VwQ2hhcnMubGVuZ3RoKCkgPiAxKSAmJgogICAgICAgICAgICAgICAgKGdyb3VwQ2hhcnNbZ3JvdXBDaGFycy5sZW5ndGgoKS0xXSA9PSAweDAwNDApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkYXRhLT5pc0ZyZW5jaFNlYyA9IFRSVUU7CiAgICAgICAgICAgICAgICBncm91cENoYXJzLnJlbW92ZShncm91cENoYXJzLmxlbmd0aCgpLTEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBvcmRlciA9IGluY3JlbWVudCgoQ29sbGF0b3I6OkVDb2xsYXRpb25TdHJlbmd0aCllbnRyeS0+Z2V0U3RyZW5ndGgoKSwgb3JkZXIpOwoKICAgICAgICAgICAgaWYgKGVudHJ5LT5nZXRFeHRlbnNpb24oZXhwQ2hhcnMpLmxlbmd0aCgpICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGVuY291bnRlcmVkIGFuIGV4cGFuZGluZyBjaGFyYWN0ZXIsIHdoZXJlIG9uZSBjaGFyYWN0ZXIgb24gaW5wdXQKICAgICAgICAgICAgICAgIC8vIGV4cGFuZHMgdG8gc2V2ZXJhbCBzb3J0IGVsZW1lbnRzIChlLmcuICf2JyAtLT4gJ28nICdlJykKICAgICAgICAgICAgICAgIGFkZEV4cGFuZE9yZGVyKGdyb3VwQ2hhcnMsIGV4cENoYXJzLCBvcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoZ3JvdXBDaGFycy5sZW5ndGgoKSA+IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGVuY291bnRlcmVkIGEgY29udHJhY3RpbmcgY2hhcmFjdGVyLCB3aGVyZSBzZXZlcmFsIGNoYXJhY3RlcnMgb24gaW5wdXQKICAgICAgICAgICAgICAgIC8vIGNvbnRyYWN0IGludG8gb25lIHNvcnQgb3JkZXIuICBGb3IgZXhhbXBsZSwgImNoIiBpcyB0cmVhdGVkIGFzIGEgc2luZ2xlCiAgICAgICAgICAgICAgICAvLyBjaGFyYWN0ZXIgaW4gdHJhZGl0aW9uYWwgU3BhbmlzaCBzb3J0aW5nLgogICAgICAgICAgICAgICAgYWRkQ29udHJhY3RPcmRlcihncm91cENoYXJzLCBvcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBOb3RoaW5nIG91dCBvZiB0aGUgb3JkaW5hcnkgLS0gb25lIGNoYXJhY3RlciBtYXBzIHRvIG9uZSBzb3J0IG9yZGVyCiAgICAgICAgICAgICAgICBhZGRPcmRlcihncm91cENoYXJzWzBdLCBvcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gYWRkIGV4cGFuZGluZyBlbnRyaWVzIGZvciBwcmUtY29tcG9zZWQgY2hhcmFjdGVycwogICAgYWRkQ29tcG9zZWRDaGFycygpOwoKICAgIC8vIEZpbGwgaW4gYWxsIHRoZSBleHBhbmRpbmcgY2hhcnMgdmFsdWVzCiAgICBjb21taXQoKTsKCiAgICAvLyBDb21wYWN0IHRoZSBkYXRhIG1hcHBpbmcgdGFibGUKICAgIHVjbXAzMl9jb21wYWN0KGRhdGEtPm1hcHBpbmcsIDEpOwp9CgovKioKICogQWRkIGV4cGFuZGluZyBlbnRyaWVzIGZvciBwcmUtY29tcG9zZWQgdW5pY29kZSBjaGFyYWN0ZXJzIHNvIHRoYXQgdGhpcwogKiBjb2xsYXRvciBjYW4gYmUgdXNlZCByZWFzb25hYmx5IHdlbGwgd2l0aCBkZWNvbXBvc2l0aW9uIHR1cm5lZCBvZmYuCiAqLwogdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6YWRkQ29tcG9zZWRDaGFycygpCiB7CiAgICBVbmljb2RlU3RyaW5nIGJ1ZjsKICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwoKICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBhbGwgb2YgdGhlIHByZS1jb21wb3NlZCBjaGFyYWN0ZXJzIGluIFVuaWNvZGUKICAgIENvbXBvc2VkQ2hhckl0ZXIgaXRlcjsKICAgIFVuaWNvZGVTdHJpbmcgZGVjb21wOwoKICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkKICAgIHsKICAgICAgICBVQ2hhciBjID0gaXRlci5uZXh0KCk7CiAgICAgICAgCiAgICAgICAgaWYgKGdldENoYXJPcmRlcihjKSA9PSBVTk1BUFBFRCkKICAgICAgICB7CiAgICAgICAgICAgIC8vIAogICAgICAgICAgICAvLyBXZSBkb24ndCBhbHJlYWR5IGhhdmUgYW4gb3JkZXJpbmcgZm9yIHRoaXMgcHJlLWNvbXBvc2VkIGNoYXJhY3Rlci4KICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gRmlyc3QsIHNlZSBpZiB0aGUgZGVjb21wb3NlZCBzdHJpbmcgaXMgYWxyZWFkeSBpbiBvdXIKICAgICAgICAgICAgLy8gdGFibGVzIGFzIGEgc2luZ2xlIGNvbnRyYWN0aW5nLXN0cmluZyBvcmRlcmluZy4KICAgICAgICAgICAgLy8gSWYgc28sIGp1c3QgbWFwIHRoZSBwcmVjb21wb3NlZCBjaGFyYWN0ZXIgdG8gdGhhdCBvcmRlci4KICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gVE9ETzogV2hhdCB3ZSBzaG91bGQgcmVhbGx5IGJlIGRvaW5nIGhlcmUgaXMgdHJ5aW5nIHRvIGZpbmQgdGhlCiAgICAgICAgICAgIC8vIGxvbmdlc3QgaW5pdGlhbCBzdWJzdHJpbmcgb2YgdGhlIGRlY29tcG9zaXRpb24gdGhhdCBpcyBwcmVzZW50CiAgICAgICAgICAgIC8vIGluIHRoZSB0YWJsZXMgYXMgYSBjb250cmFjdGluZyBjaGFyYWN0ZXIgc2VxdWVuY2UsIGFuZCBmaW5kIGl0cwogICAgICAgICAgICAvLyBvcmRlcmluZy4gIFRoZW4gZG8gdGhpcyByZWN1cnNpdmVseSB3aXRoIHRoZSByZW1haW5pbmcgY2hhcnMKICAgICAgICAgICAgLy8gc28gdGhhdCB3ZSBidWlsZCBhIGxpc3Qgb2Ygb3JkZXJpbmdzLCBhbmQgYWRkIHRoYXQgbGlzdCB0bwogICAgICAgICAgICAvLyB0aGUgZXhwYW5zaW9uIHRhYmxlLiAKICAgICAgICAgICAgLy8gVGhhdCB3b3VsZCBiZSBtb3JlIGNvcnJlY3QgYnV0IGFsc28gc2lnbmlmaWNhbnRseSBzbG93ZXIsIHNvCiAgICAgICAgICAgIC8vIEknbSBub3QgdG90YWxseSBzdXJlIGl0J3Mgd29ydGggZG9pbmcuCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIGl0ZXIuZ2V0RGVjb21wb3NpdGlvbihkZWNvbXApOwogICAgICAgICAgICBpbnQgY29udHJhY3RPcmRlciA9IGdldENvbnRyYWN0T3JkZXIoZGVjb21wKTsKCiAgICAgICAgICAgIGlmIChjb250cmFjdE9yZGVyICE9IFVOTUFQUEVEKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhZGRPcmRlcihjLCBjb250cmFjdE9yZGVyLCBzdGF0dXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIC8vIFdlIGRvbid0IGhhdmUgYSBjb250cmFjdGluZyBvcmRlcmluZyBmb3IgdGhlIGVudGlyZSBzdHJpbmcKICAgICAgICAgICAgICAgIC8vIHRoYXQgcmVzdWx0cyBmcm9tIHRoZSBkZWNvbXBvc2l0aW9uLCBidXQgaWYgd2UgaGF2ZSBvcmRlcnMKICAgICAgICAgICAgICAgIC8vIGZvciBlYWNoIGluZGl2aWR1YWwgY2hhcmFjdGVyLCB3ZSBjYW4gYWRkIGFuIGV4cGFuZGluZwogICAgICAgICAgICAgICAgLy8gdGFibGUgZW50cnkgZm9yIHRoZSBwcmUtY29tcG9zZWQgY2hhcmFjdGVyIAogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIFVCb29sIGFsbFRoZXJlID0gVFJVRTsKICAgICAgICAgICAgICAgIGludDMyX3QgaTsKCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZGVjb21wLmxlbmd0aCgpOyBpICs9IDEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGdldENoYXJPcmRlcihkZWNvbXBbaV0pID09IFVOTUFQUEVEKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWxsVGhlcmUgPSBGQUxTRTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChhbGxUaGVyZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBidWYucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICAgICAgYnVmICs9IGM7CiAgICAgICAgICAgICAgICAgICAgYWRkRXhwYW5kT3JkZXIoYnVmLCBkZWNvbXAsIFVOTUFQUEVELCBzdGF0dXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CiAgICAKLy8gV2hlbiB0aGUgZXhwYW5kaW5nIGNoYXJhY3RlciB0YWJsZXMgYXJlIGJ1aWx0IGJ5IGFkZEV4cGFuZE9yZGVyLAovLyBpdCBkb2Vzbid0IGtub3cgd2hhdCB0aGUgZmluYWwgb3JkZXJpbmcgb2YgZWFjaCBjaGFyYWN0ZXIKLy8gaW4gdGhlIGV4cGFuc2lvbiB3aWxsIGJlLiAgSW5zdGVhZCwgaXQganVzdCBwdXRzIHRoZSByYXcgY2hhcmFjdGVyCi8vIGNvZGUgaW50byB0aGUgdGFibGUsIGFkZGluZyBDSEFSSU5ERVggYXMgYSBmbGFnLiAgTm93IHRoYXQgd2UndmUKLy8gZmluaXNoZWQgYnVpbGRpbmcgdGhlIG1hcHBpbmcgdGFibGUsIHdlIGNhbiBnbyBiYWNrIGFuZCBsb29rIHVwCi8vIHRoYXQgY2hhcmFjdGVyIHRvIHNlZSB3aGF0IGl0cyByZWFsIGNvbGxhdGlvbiBvcmRlciBpcyBhbmQKLy8gc3RpY2sgdGhhdCBpbnRvIHRoZSBleHBhbnNpb24gdGFibGUuICBUaGF0IGxldHMgdXMgYXZvaWQgZG9pbmcKLy8gYSB0d28tc3RhZ2UgbG9va3VwIGxhdGVyLgoKdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6Y29tbWl0KCkKewogICAgLy8gaWYgdGhlcmUgYXJlIGFueSBleHBhbmRpbmcgY2hhcmFjdGVycwogICAgaWYgKGRhdGEtPmV4cGFuZFRhYmxlICE9IE5VTEwpCiAgICB7CiAgICAgICAgaW50MzJfdCBpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBkYXRhLT5leHBhbmRUYWJsZS0+c2l6ZSgpOyBpICs9IDEpCiAgICAgICAgewogICAgICAgICAgICBWZWN0b3JPZkludCogdmFsdWVMaXN0ID0gZGF0YS0+ZXhwYW5kVGFibGUtPmF0KGkpOwogICAgICAgICAgICBpbnQzMl90IGo7CiAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCB2YWx1ZUxpc3QtPnNpemUoKTsgaisrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBmb3VuZCBhIGV4cGFuZGluZyBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgIC8vIHRoZSBleHBhbmRpbmcgY2hhciB2YWx1ZSBpcyBub3QgZmlsbGVkIGluIHlldAogICAgICAgICAgICAgICAgaWYgKCh2YWx1ZUxpc3QtPmF0KGopIDwgRVhQQU5EQ0hBUklOREVYKSAmJgogICAgICAgICAgICAgICAgICAgICh2YWx1ZUxpc3QtPmF0KGopID4gQ0hBUklOREVYKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIHJlYWwgdmFsdWVzIGZvciB0aGUgbm9uLWZpbGxlZCBlbnRyeQogICAgICAgICAgICAgICAgICAgIFVDaGFyIGNoID0gKFVDaGFyKSh2YWx1ZUxpc3QtPmF0KGopIC0gQ0hBUklOREVYKTsKICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHJlYWxWYWx1ZSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY2gpOwoKICAgICAgICAgICAgICAgICAgICBpZiAocmVhbFZhbHVlID09IFVOTUFQUEVEKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHJlYWwgdmFsdWUgaXMgc3RpbGwgdW5tYXBwZWQsIG1heWJlIGl0J3NpZ25vcmFibGUKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVMaXN0LT5hdFB1dChqLCBJR05PUkFCTEVNQVNLICYgY2gpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBmaWxsIGluIHRoZSB2YWx1ZQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlTGlzdC0+YXRQdXQoaiwgcmVhbFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiB9CgovKioKICogIEluY3JlbWVudCBvZiB0aGUgbGFzdCBvcmRlciBiYXNlZCBvbiB0aGUgY29tcGFyaXNvbiBsZXZlbC4KICovCmludDMyX3QKUnVsZUJhc2VkQ29sbGF0b3I6OmluY3JlbWVudChDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoIGFTdHJlbmd0aCwgaW50MzJfdCBsYXN0VmFsdWUpCnsKICAgIHN3aXRjaChhU3RyZW5ndGgpCiAgICB7CiAgICBjYXNlIENvbGxhdG9yOjpQUklNQVJZOgogICAgICAgIC8vIGluY3JlbWVudCBwcmlhbXJ5IG9yZGVyICBhbmQgbWFzayBvZmYgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgICAgICAgbGFzdFZhbHVlICs9IFBSSU1BUllPUkRFUklOQ1JFTUVOVDsKICAgICAgICBsYXN0VmFsdWUgJj0gUFJJTUFSWU9SREVSTUFTSzsKICAgICAgICBpc092ZXJJZ25vcmUgPSBUUlVFOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQ29sbGF0b3I6OlNFQ09OREFSWToKICAgICAgICAvLyBpbmNyZW1lbnQgc2Vjb25kYXJ5IG9yZGVyIGFuZCBtYXNrIG9mZiB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgICAgICAgbGFzdFZhbHVlICs9IFNFQ09OREFSWU9SREVSSU5DUkVNRU5UOwogICAgICAgIGxhc3RWYWx1ZSAmPSBTRUNPTkRBUllESUZGRVJFTkNFT05MWTsKCiAgICAgICAgLy8gcmVjb3JkIG1heCAjIG9mIGlnbm9yYWJsZSBjaGFycyB3aXRoIHNlY29uZGFyeSBkaWZmZXJlbmNlCiAgICAgICAgaWYgKGlzT3Zlcklnbm9yZSA9PSBGQUxTRSkKICAgICAgICB7CiAgICAgICAgICAgIGRhdGEtPm1heFNlY09yZGVyICs9IDE7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQ29sbGF0b3I6OlRFUlRJQVJZOgogICAgICAgIC8vIGluY3JlbWVudCB0ZXJ0aWFyeSBvcmRlcgogICAgICAgIGxhc3RWYWx1ZSArPSBURVJUSUFSWU9SREVSSU5DUkVNRU5UOwoKICAgICAgICAvLyByZWNvcmQgbWF4ICMgb2YgaWdub3JhYmxlIGNoYXJzIHdpdGggdGVydGlhcnkgZGlmZmVyZW5jZQogICAgICAgIGlmIChpc092ZXJJZ25vcmUgPT0gRkFMU0UpCiAgICAgICAgewogICAgICAgICAgICBkYXRhLT5tYXhUZXJPcmRlciArPSAxOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgLy8gY2FzZSBJREVOVElDQUw/ICAKICAgIH0KCiAgICByZXR1cm4gbGFzdFZhbHVlOwp9CgovLyBBZGRzIGEgY2hhcmFjdGVyIGFuZCBpdHMgZGVzaWduYXRlZCBvcmRlciBpbnRvIHRoZSBjb2xsYXRpb24gdGFibGUuCi8vIFRoaXMgaXMgdGhlIHNpbXBsZSBjYXNlLCB3aXRoIG5vIGV4cGFuc2lvbiBvciBjb250cmFjdGlvbgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjphZGRPcmRlcihVQ2hhciBjaCwKICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgYW5PcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyB0cnkgdG8gZmluZCB0aGUgb3JkZXIgb2YgdGhlIGNoYXIgaW4gdGhlIG1hcHBpbmcgdGFibGUKICAgIGludDMyX3Qgb3JkZXIgPSB1Y21wMzJfZ2V0KGRhdGEtPm1hcHBpbmcsIGNoKTsKCiAgICBpZiAob3JkZXIgPj0gQ09OVFJBQ1RDSEFSSU5ERVgpCiAgICB7CiAgICAgICAgLy8gVGhlcmUncyBhbHJlYWR5IGFuIGVudHJ5IGZvciB0aGlzIGNoYXJhY3RlciB0aGF0IHBvaW50cyB0byBhIGNvbnRyYWN0aW5nCiAgICAgICAgLy8gY2hhcmFjdGVyIHRhYmxlLiAgSW5zdGVhZCBvZiBhZGRpbmcgdGhlIGNoYXJhY3RlciBkaXJlY3RseSB0byB0aGUgbWFwcGluZwogICAgICAgIC8vIHRhYmxlLCB3ZSBtdXN0IGFkZCBpdCB0byB0aGUgY29udHJhY3QgdGFibGUgaW5zdGVhZC4KICAgICAgICBrZXkucmVtb3ZlKCk7CiAgICAgICAga2V5ICs9IGNoOwogICAgICAgIGlmIChrZXkuaXNCb2d1cygpKQogICAgICAgIHsKICAgICAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgYWRkQ29udHJhY3RPcmRlcihrZXksIGFuT3JkZXIsIHN0YXR1cyk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLy8gYWRkIHRoZSBlbnRyeSB0byB0aGUgbWFwcGluZyB0YWJsZSwgdGhlIHNhbWUgbGF0ZXIgZW50cnkgcmVwbGFjZXMgdGhlIHByZXZpb3VzIG9uZQogICAgICAgIHVjbXAzMl9zZXQoZGF0YS0+bWFwcGluZywgY2gsIGFuT3JkZXIpOwogICAgfQp9CgovLyBBZGQgYW4gZXhwYW5kaW5nLWNoYXJhY3RlciBlbnRyeSB0byB0aGUgdGFibGUuCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmFkZEV4cGFuZE9yZGVyKCAgY29uc3QgICBVbmljb2RlU3RyaW5nJiBjb250cmFjdENoYXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgZXhwYW5kQ2hhcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBhbk9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBDcmVhdGUgYW4gZXhwYW5zaW9uIHRhYmxlIGVudHJ5CiAgICBpbnQzMl90IHRhYmxlSW5kZXggPSBhZGRFeHBhbnNpb24oYW5PcmRlciwgZXhwYW5kQ2hhcnMpOwogICAgCiAgICAvLyBBbmQgYWRkIGl0cyBpbmRleCBpbnRvIHRoZSBtYWluIG1hcHBpbmcgdGFibGUKICAgIGlmIChjb250cmFjdENoYXJzLmxlbmd0aCgpID4gMSkKICAgIHsKICAgICAgICBhZGRDb250cmFjdE9yZGVyKGNvbnRyYWN0Q2hhcnMsIHRhYmxlSW5kZXgsIHN0YXR1cyk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgYWRkT3JkZXIoY29udHJhY3RDaGFyc1swXSwgdGFibGVJbmRleCwgc3RhdHVzKTsKICAgIH0KfQoKaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6YWRkRXhwYW5zaW9uKGludDMyX3QgYW5PcmRlciwgY29uc3QgVW5pY29kZVN0cmluZyAmZXhwYW5kQ2hhcnMpCnsKICAgIGlmIChkYXRhLT5leHBhbmRUYWJsZSA9PSBOVUxMKQogICAgewogICAgICAgIGRhdGEtPmV4cGFuZFRhYmxlID0gbmV3IFZlY3Rvck9mUFRvRXhwYW5kVGFibGUoKTsKCiAgICAgICAgaWYgKGRhdGEtPmV4cGFuZFRhYmxlID09IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8vIElmIGFuT3JkZXIgaXMgdmFsaWQsIHdlIHdhbnQgdG8gYWRkIGl0IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpc3QKICAgIGludDMyX3Qgb2Zmc2V0ID0gKGFuT3JkZXIgPT0gVU5NQVBQRUQpID8gMCA6IDE7CiAgICAKICAgIFZlY3Rvck9mSW50ICp2YWx1ZUxpc3QgPSBuZXcgVmVjdG9yT2ZJbnQoZXhwYW5kQ2hhcnMubGVuZ3RoKCkgKyBvZmZzZXQpOwoKICAgIGlmIChvZmZzZXQgPT0gMSkKICAgIHsKICAgICAgICB2YWx1ZUxpc3QtPmF0UHV0KDAsIGFuT3JkZXIpOwogICAgfQoKICAgIGludDMyX3QgaTsKICAgIGZvciAoaSA9IDA7IGkgPCBleHBhbmRDaGFycy5sZW5ndGgoKTsgaSArPSAxKQogICAgewogICAgICAgIFVDaGFyIGNoID0gZXhwYW5kQ2hhcnNbaV07CiAgICAgICAgaW50MzJfdCBtYXBWYWx1ZSA9IGdldENoYXJPcmRlcihjaCk7CiAgICAgICAgCiAgICAgICAgaWYgKG1hcFZhbHVlICE9IFVOTUFQUEVEKQogICAgICAgIHsKICAgICAgICAgICAgdmFsdWVMaXN0LT5hdFB1dChpICsgb2Zmc2V0LCBtYXBWYWx1ZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8vIGNhbid0IGZpbmQgaXQgaW4gdGhlIHRhYmxlLCB3aWxsIGJlIGZpbGxlZCBpbiBieSBjb21taXQoKS4KICAgICAgICAgICAgdmFsdWVMaXN0LT5hdFB1dChpICsgb2Zmc2V0LCBDSEFSSU5ERVggKyAoaW50MzJfdCljaCk7CiAgICAgICAgfQogICAgfQoKICAgIC8vIEFkZCB0aGUgZXhwYW5kaW5nIGNoYXIgbGlzdCBpbnRvIHRoZSBleHBhbnNpb24gdGFibGUuCiAgICBpbnQzMl90IHRhYmxlSW5kZXggPSBFWFBBTkRDSEFSSU5ERVggKyBkYXRhLT5leHBhbmRUYWJsZS0+c2l6ZSgpOwogICAgZGF0YS0+ZXhwYW5kVGFibGUtPmF0UHV0KGRhdGEtPmV4cGFuZFRhYmxlLT5zaXplKCksIHZhbHVlTGlzdCk7CiAgICAKICAgIHJldHVybiB0YWJsZUluZGV4Owp9CgovLyBBZGQgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyB0aGF0IGNvbnRyYWN0cyBpbnRvIGEgc2luZ2xlIG9yZGVyaW5nLgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjphZGRDb250cmFjdE9yZGVyKGNvbnN0ICAgVW5pY29kZVN0cmluZyYgZ3JvdXBDaGFycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBhbk9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQm9vbCBmd2QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoZGF0YS0+Y29udHJhY3RUYWJsZSA9PSBOVUxMKQogICAgewogICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBuZXcgVmVjdG9yT2ZQVG9Db250cmFjdFRhYmxlKCk7CiAgICAgICAgaWYgKGRhdGEtPmNvbnRyYWN0VGFibGUtPmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhLT5jb250cmFjdFRhYmxlOwogICAgICAgICAgICBkYXRhLT5jb250cmFjdFRhYmxlID0gTlVMTDsKICAgICAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBTZWUgaWYgdGhlIGluaXRpYWwgY2hhcmFjdGVyIG9mIHRoZSBzdHJpbmcgYWxyZWFkeSBoYXMgYSBjb250cmFjdCB0YWJsZS4KICAgIC8vIGUuZy4gZm9yICJjaCIsIGxvb2sgZm9yICdjJy4KICAgIGludDMyX3QgZW50cnkgPSB1Y21wMzJfZ2V0KGRhdGEtPm1hcHBpbmcsIGdyb3VwQ2hhcnNbMF0pOwogICAgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQgKmVudHJ5VGFibGUgPSBnZXRDb250cmFjdFZhbHVlcyhlbnRyeSAtIENPTlRSQUNUQ0hBUklOREVYKTsKCiAgICBpZiAoZW50cnlUYWJsZSA9PSBOVUxMKQogICAgewogICAgICAgIC8vIFdlIG5lZWQgdG8gY3JlYXRlIGEgbmV3IHRhYmxlIG9mIGNvbnRyYWN0IGVudHJpZXMgZm9yIHRoaXMgYmFzZSBjaGFyCiAgICAgICAgaW50MzJfdCB0YWJsZUluZGV4ID0gQ09OVFJBQ1RDSEFSSU5ERVggKyBkYXRhLT5jb250cmFjdFRhYmxlLT5zaXplKCk7CiAgICAgICAgRW50cnlQYWlyICpwYWlyID0gTlVMTDsKICAgICAgICBVbmljb2RlU3RyaW5nIHN1YnN0cmluZzsKCiAgICAgICAgZW50cnlUYWJsZSA9IG5ldyBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCgpOwogICAgICAgIGlmIChlbnRyeVRhYmxlLT5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZW50cnlUYWJsZTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBkYXRhLT5jb250cmFjdFRhYmxlLT5hdFB1dChkYXRhLT5jb250cmFjdFRhYmxlLT5zaXplKCksIGVudHJ5VGFibGUpOwogICAgICAgIGlmIChkYXRhLT5jb250cmFjdFRhYmxlLT5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZW50cnlUYWJsZTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgICAgICAKCiAgICAgICAgLy8gQWRkIHRoZSBpbml0aWFsIGNoYXJhY3RlcidzIGN1cnJlbnQgb3JkZXJpbmcgZmlyc3QuIHRoZW4KICAgICAgICAvLyB1cGRhdGUgaXRzIG1hcHBpbmcgdG8gcG9pbnQgdG8gdGhpcyBjb250cmFjdCB0YWJsZQogICAgICAgIGdyb3VwQ2hhcnMuZXh0cmFjdCgwLCAxLCBzdWJzdHJpbmcpOwogICAgICAgIGlmIChzdWJzdHJpbmcuaXNCb2d1cygpKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGVudHJ5VGFibGU7CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhLT5jb250cmFjdFRhYmxlOwogICAgICAgICAgICBkYXRhLT5jb250cmFjdFRhYmxlID0gTlVMTDsKICAgICAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgcGFpciA9IG5ldyBFbnRyeVBhaXIoc3Vic3RyaW5nLCBlbnRyeSk7CgogICAgICAgIGVudHJ5VGFibGUtPmF0UHV0KDAsIHBhaXIpOwogICAgICAgIGlmIChlbnRyeVRhYmxlLT5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZW50cnlUYWJsZTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICB1Y21wMzJfc2V0KGRhdGEtPm1hcHBpbmcsIGdyb3VwQ2hhcnNbMF0sIHRhYmxlSW5kZXgpOwogICAgfQoKICAgIC8vIE5vdyBhZGQgKG9yIHJlcGxhY2UpIHRoaXMgc3RyaW5nIGluIHRoZSB0YWJsZQogICAgaW50MzJfdCBpbmRleCA9IGdldEVudHJ5KGVudHJ5VGFibGUsIGdyb3VwQ2hhcnMsIGZ3ZCk7CgogICAgaWYgKGluZGV4ICE9IFVOTUFQUEVEKQogICAgewogICAgICAgIEVudHJ5UGFpciAqcGFpciA9IChFbnRyeVBhaXIgKikgZW50cnlUYWJsZS0+YXQoaW5kZXgpOwogICAgICAgIHBhaXItPnZhbHVlID0gYW5PcmRlcjsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBFbnRyeVBhaXIgKnBhaXIgPSBuZXcgRW50cnlQYWlyKGdyb3VwQ2hhcnMsIGFuT3JkZXIsIGZ3ZCk7CgogICAgICAgIGVudHJ5VGFibGUtPmF0UHV0KGVudHJ5VGFibGUtPnNpemUoKSwgcGFpcik7CiAgICB9CiAgICAKICAgIC8vIElmIHRoaXMgd2FzIGEgZm9yd2FyZCBtYXBwaW5nIGZvciBhIGNvbnRyYWN0aW5nIHN0cmluZywgYWxzbyBhZGQgYQogICAgLy8gcmV2ZXJzZSBtYXBwaW5nIGZvciBpdCwgc28gdGhhdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByZXZpb3VzCiAgICAvLyBjYW4gd29yayByaWdodAogICAgaWYgKGZ3ZCkKICAgIHsKICAgICAgICBVbmljb2RlU3RyaW5nIHJldmVyc2UoZ3JvdXBDaGFycyk7CgogICAgICAgIGlmIChyZXZlcnNlLmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBlbnRyeVRhYmxlOwogICAgICAgICAgICBkZWxldGUgZGF0YS0+Y29udHJhY3RUYWJsZTsKICAgICAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZSA9IE5VTEw7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGFkZENvbnRyYWN0T3JkZXIocmV2ZXJzZS5yZXZlcnNlKCksIGFuT3JkZXIsIEZBTFNFLCBzdGF0dXMpOwogICAgfQp9CgovKioKICogSWYgdGhlIGdpdmVuIHN0cmluZyBoYXMgYmVlbiBzcGVjaWZpZWQgYXMgYSBjb250cmFjdGluZyBzdHJpbmcKICogaW4gdGhpcyBjb2xsYXRpb24gdGFibGUsIHJldHVybiBpdHMgb3JkZXJpbmcuCiAqIE90aGVyd2lzZSByZXR1cm4gVU5NQVBQRUQuCiAqLwogaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29udHJhY3RPcmRlcihjb25zdCBVbmljb2RlU3RyaW5nICZncm91cENoYXJzKSBjb25zdAp7CiAgICBpbnQzMl90IHJlc3VsdCA9IFVOTUFQUEVEOwoKICAgIGlmIChkYXRhLT5jb250cmFjdFRhYmxlICE9IE5VTEwpCiAgICB7CiAgICAgICAgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQgKmVudHJ5VGFibGUgPSBnZXRDb250cmFjdFZhbHVlcyhncm91cENoYXJzWzBdKTsKCiAgICAgICAgaWYgKGVudHJ5VGFibGUgIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIGludDMyX3QgaW5kZXggPSBnZXRFbnRyeShlbnRyeVRhYmxlLCBncm91cENoYXJzLCBUUlVFKTsKCiAgICAgICAgICAgIGlmIChpbmRleCAhPSBVTk1BUFBFRCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRW50cnlQYWlyICpwYWlyID0gZW50cnlUYWJsZS0+YXQoaW5kZXgpOwoKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHBhaXItPnZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmdldENoYXJPcmRlcihVQ2hhciBjaCkgY29uc3QKewogICAgaW50MzJfdCBvcmRlciA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY2gpOwogICAgCiAgICBpZiAob3JkZXIgPj0gQ09OVFJBQ1RDSEFSSU5ERVgpCiAgICB7CiAgICAgICAgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQgKmdyb3VwTGlzdCA9IGdldENvbnRyYWN0VmFsdWVzKG9yZGVyIC0gQ09OVFJBQ1RDSEFSSU5ERVgpOwogICAgICAgIEVudHJ5UGFpciAqcGFpciA9IGdyb3VwTGlzdC0+YXQoMCk7CgogICAgICAgIG9yZGVyID0gcGFpci0+dmFsdWU7CiAgICB9CgogICAgcmV0dXJuIG9yZGVyOwp9CiAgICAKLy8gQ3JlYXRlIGEgaGFzaCBjb2RlIGZvciB0aGlzIGNvbGxhdGlvbi4gIEp1c3QgaGFzaCB0aGUgbWFpbiBydWxlIHRhYmxlIC0tCi8vIHRoYXQgc2hvdWxkIGJlIGdvb2QgZW5vdWdoIGZvciBhbG1vc3QgYW55IHVzZS4KaW50MzJfdApSdWxlQmFzZWRDb2xsYXRvcjo6aGFzaENvZGUoKSBjb25zdAp7CiAgICBpbnQzMl90ICAgICAgICAgdmFsdWUgPSAwOwogICAgaW50MzJfdCAgICAgICAgIGM7CiAgICBpbnQzMl90ICAgICAgICAgY291bnQgPSBnZXRSdWxlcygpLmxlbmd0aCgpOwogICAgVVRleHRPZmZzZXQgICAgICBwb3MgPSBjb3VudCAtIDE7CgogICAgaWYgKGNvdW50ID4gNjQpCiAgICB7CiAgICAgICAgY291bnQgPSA2NDsgLy8gb25seSBoYXNoIHVwdG8gbGltaXQKICAgIH0KCiAgICBpbnQxNl90IGkgPSAwOwoKICAgIHdoaWxlIChpIDwgY291bnQpCiAgICB7CiAgICAgICAgYyA9IGRhdGEtPnJ1bGVUYWJsZVtwb3NdOwogICAgICAgIHZhbHVlID0gKCh2YWx1ZSA8PCAoYyAmIDB4MGYpKSBeIChjIDw8IDgpKSArIChjIF4gdmFsdWUpOwogICAgICAgIGkgKz0gMTsKICAgICAgICBwb3MgLT0gMTsKICAgIH0KCiAgICBpZiAodmFsdWUgPT0gMCkKICAgIHsKICAgICAgICB2YWx1ZSA9IDE7CiAgICB9CgogICAgcmV0dXJuIHZhbHVlOwp9CgovLyBmaW5kIHRoZSBjb250cmFjdGluZyBjaGFyIGVudHJ5IGluIHRoZSBsaXN0CmludDMyX3QKUnVsZUJhc2VkQ29sbGF0b3I6OmdldEVudHJ5KFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KiBsaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgIFVCb29sIGZ3ZCkKewogICAgaW50MzJfdCBpOwoJCiAgICBpZiAobGlzdCAhPSBOVUxMKQogICAgewogICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0LT5zaXplKCk7IGkgKz0gMSkKICAgICAgICB7CiAgICAgICAgICAgIEVudHJ5UGFpciAqcGFpciA9IGxpc3QtPmF0KGkpOwoKICAgICAgICAgICAgaWYgKChwYWlyICE9IE5VTEwpICYmIChwYWlyLT5md2QgPT0gZndkKSAmJiAocGFpci0+Z2V0RW50cnlOYW1lKCkgPT0gbmFtZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBSdWxlQmFzZWRDb2xsYXRvcjo6VU5NQVBQRUQ7Cn0KCi8vIGxvb2sgZm9yIHRoZSBjb250cmFjdGluZyBsaXN0IGVudHJ5IHdpdGggdGhlIGJlZ2lubmluZyBjaGFyClZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KgpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29udHJhY3RWYWx1ZXMoVUNoYXIgY2gpIGNvbnN0CnsKICAgIGludDMyX3QgaW5kZXggPSB1Y21wMzJfZ2V0KGRhdGEtPm1hcHBpbmcsIGNoKTsKICAgIHJldHVybiBnZXRDb250cmFjdFZhbHVlcyhpbmRleCAtIENPTlRSQUNUQ0hBUklOREVYKTsKfQoKLy8gbG9vayBmb3IgdGhlIGNvbnRyYWN0aW5nIGxpc3QgZW50cnkgd2l0aCB0aGUgaW5kZXgKVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQqClJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb250cmFjdFZhbHVlcyhpbnQzMl90ICAgIGluZGV4KSBjb25zdAp7CiAgICBpZiAoZGF0YS0+Y29udHJhY3RUYWJsZSAhPSBOVUxMKQogICAgewogICAgICAgIGlmIChpbmRleCA+PSAwKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGRhdGEtPmNvbnRyYWN0VGFibGUtPmF0KGluZGV4KTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqCiAgKiBSZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFueSBleHBhbnNpb24gc2VxdWVuY2VzIHRoYXQgZW5kCiAgKiB3aXRoIHRoZSBzcGVjaWZpZWQgY29tcGFyaXNvbiBvcmRlci4KICAqCiAgKiBAcGFyYW0gb3JkZXIgYSBjb2xsYXRpb24gb3JkZXIgcmV0dXJuZWQgYnkgcHJldmlvdXMgb3IgbmV4dC4KICAqIEByZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFueSBleHBhbnNpb24gc2V1ZW5jZXMgZW5kaW5nCiAgKiAgICAgICAgIHdpdGggdGhlIHNwZWNpZmllZCBvcmRlci4KICAqCiAgKiBAc2VlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciNnZXRNYXhFeHBhbnNpb24KICAqLwppbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3QKewogICAgaW50MzJfdCByZXN1bHQgPSAxOwogICAgCiAgICBpZiAoZGF0YS0+ZXhwYW5kVGFibGUgIT0gTlVMTCkKICAgIHsKICAgICAgICAvLyBSaWdodCBub3cgdGhpcyBkb2VzIGEgbGluZWFyIHNlYXJjaCB0aHJvdWdoIHRoZSBlbnRpcmUKICAgICAgICAvLyBleHBhbmRzaW9uIHRhYmxlLiAgSWYgYSBjb2xsYXRvciBoYWQgYSBsYXJnZSBudW1iZXIgb2YgZXhwYW5zaW9ucywKICAgICAgICAvLyB0aGlzIGNvdWxkIGNhdXNlIGEgcGVyZm9ybWFuY2UgcHJvYmxlbSwgYnV0IGluIHByYWN0aWNlIHRoYXQKICAgICAgICAvLyByYXJlbHkgaGFwcGVucwogICAgICAgIGludDMyX3QgaTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZGF0YS0+ZXhwYW5kVGFibGUtPnNpemUoKTsgaSArPSAxKQogICAgICAgIHsKICAgICAgICAgICAgVmVjdG9yT2ZJbnQgKnZhbHVlTGlzdCA9IGRhdGEtPmV4cGFuZFRhYmxlLT5hdChpKTsKICAgICAgICAgICAgaW50MzJfdCBsZW5ndGggPSB2YWx1ZUxpc3QtPnNpemUoKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChsZW5ndGggPiByZXN1bHQgJiYgdmFsdWVMaXN0LT5hdChsZW5ndGgtMSkgPT0gb3JkZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IGxlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9CiAgICAKLyoqCiAqICBHZXQgdGhlIGVudHJ5IG9mIGhhc2ggdGFibGUgb2YgdGhlIGV4cGFuZGluZyBzdHJpbmcgaW4gdGhlIGNvbGxhdGlvbgogKiAgdGFibGUuCiAqICBAcGFyYW0gb2Zmc2V0IHRoZSBpbmRleCBvZiB0aGUgZXhwYW5kaW5nIHN0cmluZyB2YWx1ZSBsaXN0CiAqLwpWZWN0b3JPZkludCAqUnVsZUJhc2VkQ29sbGF0b3I6OmdldEV4cGFuZFZhbHVlTGlzdChpbnQzMl90IG9yZGVyKSBjb25zdAp7CiAgICByZXR1cm4gZGF0YS0+ZXhwYW5kVGFibGUtPmF0KG9yZGVyIC0gRVhQQU5EQ0hBUklOREVYKTsKfQoKCgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbUluKFJ1bGVCYXNlZENvbGxhdG9yKiBjb2xsYXRvciwgVU1lbW9yeVN0cmVhbSogaXMsIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgaWYgKCF1cHJ2X21zdHJtX2Vycm9yKGlzKSAmJiBVX1NVQ0NFU1Moc3RhdHVzKSkgewogICAgICAgIC8vIENoZWNrIHRoYXQgdGhpcyBpcyB0aGUgY29ycmVjdCBmaWxlIHR5cGUKICAgICAgICBpbnQxNl90IGlkOwoKICAgICAgICB1cHJ2X21zdHJtX3JlYWQoaXMsICZpZCwgc2l6ZW9mKGlkKSk7CiAgICAgICAgaWYgKGlkICE9IGNvbGxhdG9yLT5GSUxFSUQpCiAgICAgICAgewogICAgICAgICAgICAvLyBUaGlzIGlzbid0IHRoZSByaWdodCB0eXBlIG9mIGZpbGUuICBNYXJrIHRoZSBpb3MKICAgICAgICAgICAgLy8gYXMgZmFpbGluZyBhbmQgcmV0dXJuLgogICAgICAgICAgICB1cHJ2X21zdHJtX3NldEVycm9yKGlzKTsgLy8gZm9yY2UgdGhlIHN0cmVhbSB0byBzZXQgaXRzIGVycm9yIGZsYWcKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gU3RyZWFtIGluIGxhcmdlIG9iamVjdHMKICAgICAgICBjaGFyIGlzTnVsbDsKCiAgICAgICAgdXBydl9tc3RybV9yZWFkKGlzLCAmaXNOdWxsLCBzaXplb2YoaXNOdWxsKSk7CiAgICAgICAgaWYgKGlzTnVsbCkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBjb2xsYXRvci0+ZGF0YTsKICAgICAgICAgICAgY29sbGF0b3ItPmRhdGEgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb2xsYXRvci0+ZGF0YSA9PSBOVUxMKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb2xsYXRvci0+ZGF0YSA9IG5ldyBUYWJsZUNvbGxhdGlvbkRhdGE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGNvbGxhdG9yLT5kYXRhLT5zdHJlYW1Jbihpcywgc3RhdHVzKTsKICAgICAgICAgICAgaWYgKGNvbGxhdG9yLT5kYXRhLT5pc0JvZ3VzKCkpIHsKICAgICAgICAgICAgICAgIHVwcnZfbXN0cm1fc2V0RXJyb3IoaXMpOyAvLyBmb3JjZSB0aGUgc3RyZWFtIHRvIHNldCBpdHMgZXJyb3IgZmxhZwogICAgICAgICAgICAgICAgc3RhdHVzID0gVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgdGhhdCB0aGUgZW5kIG1hcmtlciBpcyBwcmVzZW50CiAgICAgICAgdXBydl9tc3RybV9yZWFkKGlzLCAmaWQsIHNpemVvZihpZCkpOwogICAgICAgIGlmIChpZCAhPSBjb2xsYXRvci0+RklMRUlEKQogICAgICAgIHsKICAgICAgICAgICAgLy8gVGhpcyBpc24ndCB0aGUgcmlnaHQgdHlwZSBvZiBmaWxlLiAgTWFyayB0aGUgaW9zCiAgICAgICAgICAgIC8vIGFzIGZhaWxpbmcgYW5kIHJldHVybi4KICAgICAgICAgICAgdXBydl9tc3RybV9zZXRFcnJvcihpcyk7IC8vIGZvcmNlIHRoZSBzdHJlYW0gdG8gc2V0IGl0cyBlcnJvciBmbGFnCiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUlTU0lOR19SRVNPVVJDRV9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gUmVzZXQgb3RoZXIgZGF0YSBtZW1iZXJzCiAgICAgICAgY29sbGF0b3ItPmlzT3Zlcklnbm9yZSA9IEZBTFNFOwogICAgICAgIGNvbGxhdG9yLT5sYXN0Q2hhciA9IDA7CiAgICAgICAgZGVsZXRlIGNvbGxhdG9yLT5tUGF0dGVybjsKICAgICAgICBjb2xsYXRvci0+bVBhdHRlcm4gPSAwOwogICAgICAgIGNvbGxhdG9yLT5rZXkucmVtb3ZlKCk7CiAgICAgICAgY29sbGF0b3ItPmRhdGFJc093bmVkID0gVFJVRTsKICAgIH0KfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1PdXQoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBVTWVtb3J5U3RyZWFtKiBvcykKewogICAgaWYgKCF1cHJ2X21zdHJtX2Vycm9yKG9zKSkKICAgIHsKICAgICAgICAvLyBXZSB1c2UgYSAxNi1iaXQgSUQgY29kZSB0byBpZGVudGlmeSB0aGlzIGZpbGUuCiAgICAgICAgaW50MTZfdCBpZCA9IGNvbGxhdG9yLT5GSUxFSUQ7CiAgICAgICAgdXBydl9tc3RybV93cml0ZShvcywgKHVpbnQ4X3QgKikmaWQsIHNpemVvZihpZCkpOwoKICAgICAgICAvLyBTdHJlYW0gb3V0IHRoZSBkYXRhCiAgICAgICAgY2hhciBpc051bGw7CiAgICAgICAgaXNOdWxsID0gKGNvbGxhdG9yLT5kYXRhID09IDApOwogICAgICAgIHVwcnZfbXN0cm1fd3JpdGUob3MsICh1aW50OF90KikmaXNOdWxsLCBzaXplb2YoaXNOdWxsKSk7CgogICAgICAgIGlmICghaXNOdWxsKQogICAgICAgIHsKICAgICAgICAgICAgY29sbGF0b3ItPmRhdGEtPnN0cmVhbU91dChvcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBXcml0ZSBvdXQgdGhlIElEIHRvIGluZGljYXRlIHRoZSBlbmQKICAgICAgICB1cHJ2X21zdHJtX3dyaXRlKG9zLCAodWludDhfdCAqKSZpZCwgc2l6ZW9mKGlkKSk7CiAgICB9Cn0KCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtSW4oUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBGaWxlU3RyZWFtKiBpcykKewogICAgaWYgKCFUX0ZpbGVTdHJlYW1fZXJyb3IoaXMpKQogICAgewogICAgICAgIC8vIENoZWNrIHRoYXQgdGhpcyBpcyB0aGUgY29ycmVjdCBmaWxlIHR5cGUKICAgICAgICBpbnQxNl90IGlkOwoKICAgICAgICBUX0ZpbGVTdHJlYW1fcmVhZChpcywgJmlkLCBzaXplb2YoaWQpKTsKICAgICAgICBpZiAoaWQgIT0gY29sbGF0b3ItPkZJTEVJRCkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFRoaXMgaXNuJ3QgdGhlIHJpZ2h0IHR5cGUgb2YgZmlsZS4gIE1hcmsgdGhlIGlvcwogICAgICAgICAgICAvLyBhcyBmYWlsaW5nIGFuZCByZXR1cm4uCiAgICAgICAgICAgIFRfRmlsZVN0cmVhbV9zZXRFcnJvcihpcyk7IC8vIGZvcmNlIHRoZSBzdHJlYW0gdG8gc2V0IGl0cyBlcnJvciBmbGFnCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIFN0cmVhbSBpbiBsYXJnZSBvYmplY3RzCiAgICAgICAgY2hhciBpc051bGw7CgogICAgICAgIFRfRmlsZVN0cmVhbV9yZWFkKGlzLCAmaXNOdWxsLCBzaXplb2YoaXNOdWxsKSk7CiAgICAgICAgaWYgKGlzTnVsbCkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBjb2xsYXRvci0+ZGF0YTsKICAgICAgICAgICAgY29sbGF0b3ItPmRhdGEgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBpZiAoY29sbGF0b3ItPmRhdGEgPT0gTlVMTCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29sbGF0b3ItPmRhdGEgPSBuZXcgVGFibGVDb2xsYXRpb25EYXRhOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBjb2xsYXRvci0+ZGF0YS0+c3RyZWFtSW4oaXMpOwogICAgICAgICAgICBpZiAoY29sbGF0b3ItPmRhdGEtPmlzQm9ndXMoKSkgewogICAgICAgICAgICAgICAgVF9GaWxlU3RyZWFtX3NldEVycm9yKGlzKTsgLy8gZm9yY2UgdGhlIHN0cmVhbSB0byBzZXQgaXRzIGVycm9yIGZsYWcKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGVuZCBtYXJrZXIgaXMgcHJlc2VudAogICAgICAgIFRfRmlsZVN0cmVhbV9yZWFkKGlzLCAmaWQsIHNpemVvZihpZCkpOwogICAgICAgIGlmIChpZCAhPSBjb2xsYXRvci0+RklMRUlEKQogICAgICAgIHsKICAgICAgICAgICAgLy8gVGhpcyBpc24ndCB0aGUgcmlnaHQgdHlwZSBvZiBmaWxlLiAgTWFyayB0aGUgaW9zCiAgICAgICAgICAgIC8vIGFzIGZhaWxpbmcgYW5kIHJldHVybi4KICAgICAgICAgICAgVF9GaWxlU3RyZWFtX3NldEVycm9yKGlzKTsgLy8gZm9yY2UgdGhlIHN0cmVhbSB0byBzZXQgaXRzIGVycm9yIGZsYWcKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gUmVzZXQgb3RoZXIgZGF0YSBtZW1iZXJzCiAgICAgICAgY29sbGF0b3ItPmlzT3Zlcklnbm9yZSA9IEZBTFNFOwogICAgICAgIGNvbGxhdG9yLT5sYXN0Q2hhciA9IDA7CiAgICAgICAgZGVsZXRlIGNvbGxhdG9yLT5tUGF0dGVybjsKICAgICAgICBjb2xsYXRvci0+bVBhdHRlcm4gPSAwOwogICAgICAgIGNvbGxhdG9yLT5rZXkucmVtb3ZlKCk7CiAgICAgICAgY29sbGF0b3ItPmRhdGFJc093bmVkID0gVFJVRTsKICAgIH0KfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1PdXQoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBGaWxlU3RyZWFtKiBvcykKewogICAgaWYgKCFUX0ZpbGVTdHJlYW1fZXJyb3Iob3MpKQogICAgewogICAgICAgIC8vIFdlIHVzZSBhIDE2LWJpdCBJRCBjb2RlIHRvIGlkZW50aWZ5IHRoaXMgZmlsZS4KICAgICAgICBpbnQxNl90IGlkID0gY29sbGF0b3ItPkZJTEVJRDsKICAgICAgICBUX0ZpbGVTdHJlYW1fd3JpdGUob3MsICZpZCwgc2l6ZW9mKGlkKSk7CgogICAgICAgIC8vIFN0cmVhbSBvdXQgdGhlIGRhdGEKICAgICAgICBjaGFyIGlzTnVsbDsKICAgICAgICBpc051bGwgPSAoY29sbGF0b3ItPmRhdGEgPT0gMCk7CiAgICAgICAgVF9GaWxlU3RyZWFtX3dyaXRlKG9zLCAmaXNOdWxsLCBzaXplb2YoaXNOdWxsKSk7CgogICAgICAgIGlmICghaXNOdWxsKQogICAgICAgIHsKICAgICAgICAgICAgY29sbGF0b3ItPmRhdGEtPnN0cmVhbU91dChvcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBXcml0ZSBvdXQgdGhlIElEIHRvIGluZGljYXRlIHRoZSBlbmQKICAgICAgICBUX0ZpbGVTdHJlYW1fd3JpdGUob3MsICZpZCwgc2l6ZW9mKGlkKSk7CiAgICB9Cn0KClVCb29sIFJ1bGVCYXNlZENvbGxhdG9yOjp3cml0ZVRvRmlsZShjb25zdCBjaGFyKiBmaWxlTmFtZSkgY29uc3QKewogICAgRmlsZVN0cmVhbSogb2ZzID0gVF9GaWxlU3RyZWFtX29wZW4oZmlsZU5hbWUsICJ3YiIpOwogICAgaWYgKG9mcyAhPSAwKQogICAgewogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbU91dCh0aGlzLCBvZnMpOwogICAgfQoKI2lmZGVmIENPTExERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJiaW5hcnkgd3JpdGUgJXMgc2l6ZSAlZCAlc1xuIiwgZmlsZU5hbWUsIFRfRmlsZVN0cmVhbV9zaXplKG9mcyksCiAgICAgICAgKCFUX0ZpbGVTdHJlYW1fZXJyb3Iob2ZzKSA/ICIsIE9LIiA6ICIsIEZBSUwiKSk7CiNlbmRpZgoKICAgIFVCb29sIGVyciA9IFRfRmlsZVN0cmVhbV9lcnJvcihvZnMpID09IDA7CgogICAgVF9GaWxlU3RyZWFtX2Nsb3NlKG9mcyk7CiAgICByZXR1cm4gZXJyOwp9Ci8qClVCb29sIFJ1bGVCYXNlZENvbGxhdG9yOjpwcmVwYXJlRm9yQnVuZGxlKCkgY29uc3QKewogICAgVU1lbW9yeVN0cmVhbSogb2ZzID0gdXBydl9tc3RybV9vcGVuTmV3KDApOwogICAgaWYgKG9mcyAhPSAwKQogICAgewogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbU91dCh0aGlzLCBvZnMpOwogICAgfQoKI2lmZGVmIENPTExERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJiaW5hcnkgd3JpdGUgJXMgc2l6ZSAlZCAlc1xuIiwgZmlsZU5hbWUsIFRfRmlsZVN0cmVhbV9zaXplKG9mcyksCiAgICAgICAgKCFUX0ZpbGVTdHJlYW1fZXJyb3Iob2ZzKSA/ICIsIE9LIiA6ICIsIEZBSUwiKSk7CiNlbmRpZgoKICAgIFVCb29sIGVyciA9IHVwcnZfbXN0cm1fZXJyb3Iob2ZzKSA9PSAwOwoKICAgIHVwcnZfbXN0cm1fY2xvc2Uob2ZzKTsKCiAgICByZXR1cm4gZXJyOwp9CiovCgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjphZGRUb0NhY2hlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIGtleSkKewogICAgLy8gVGhpcyBtZXRob2QgZG9lc24ndCBhZGQgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIGl0c2VsZiB0byB0aGUgY2FjaGUuICBJbnN0ZWFkLAogICAgLy8gaXQgYWRkcyB0aGUgZ2l2ZW4gUnVsZUJhc2VkQ29sbGF0b3IncyBkYXRhIG9iamVjdCB0byB0aGUgVGFibGVDb2xsYXRpb25EYXRhCiAgICAvLyBjYWNoZSwgYW5kIG1hcmtzIGl0IGFzIG5vbi1vd25lZCBpbiB0aGUgZ2l2ZW4gUnVsZUJhc2VkQ29sbGF0b3Igb2JqZWN0LgogICAgVGFibGVDb2xsYXRpb25EYXRhOjphZGRUb0NhY2hlKGtleSwgZGF0YSk7CiAgICBkYXRhSXNPd25lZCA9IEZBTFNFOwp9Cgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tQ2FjaGUoY29uc3QgVW5pY29kZVN0cmluZyYga2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgLy8gQXR0ZW1wdCB0byBjb25zdHJ1Y3QgdGhpcyBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QgZnJvbSBjYWNoZWQgVGFibGVDb2xsYXRpb25EYXRhLgogICAgLy8gSWYgbm8gc3VjaCBkYXRhIGlzIGluIHRoZSBjYWNoZSwgcmV0dXJuIGZhbHNlLgogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IE5VTEw7CiAgICB9CgogICAgaXNPdmVySWdub3JlID0gRkFMU0U7CiAgICBsYXN0Q2hhciA9IDA7CiAgICBtUGF0dGVybiA9IDA7CiAgICBzZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOwoKICAgIGRhdGFJc093bmVkID0gRkFMU0U7CiAgICBkYXRhID0gVGFibGVDb2xsYXRpb25EYXRhOjpmaW5kSW5DYWNoZShrZXkpOwogICAgaWYgKGRhdGEgPT0gTlVMTCkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CiAgICB9Cn0KCmNoYXIqClJ1bGVCYXNlZENvbGxhdG9yOjpjcmVhdGVQYXRoTmFtZSggIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIHByZWZpeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiAgICBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIHN1ZmZpeCkKewogICAgLy8gQ29uY2F0ZW5hdGUgdGhyZWUgZWxlbWVudHMgdG8gZm9ybSBhIGZpbGUgbmFtZSwgYW5kIHJldHVybiBpdC4KCiAgICBVbmljb2RlU3RyaW5nICAgd29ya2luZ05hbWUocHJlZml4KTsKICAgIGludDMyX3QgICAgICAgICBzaXplOwogICAgY2hhciogICAgICAgICAgIHJldHVyblZhbDsKCiAgICB3b3JraW5nTmFtZSArPSBuYW1lOwogICAgd29ya2luZ05hbWUgKz0gc3VmZml4OwoKICAgIHNpemUgPSB3b3JraW5nTmFtZS5sZW5ndGgoKTsKICAgIHJldHVyblZhbCA9IG5ldyBjaGFyW3NpemUgKyAxXTsKICAgIHdvcmtpbmdOYW1lLmV4dHJhY3QoMCwgc2l6ZSwgcmV0dXJuVmFsLCAiIik7CiAgICByZXR1cm5WYWxbc2l6ZV0gPSAwOwoKICAgIHJldHVybiByZXR1cm5WYWw7Cn0KCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmNob3BMb2NhbGUoVW5pY29kZVN0cmluZyYgbG9jYWxlTmFtZSkKewogICAgLy8gY2hvcExvY2FsZSByZW1vdmVzIHRoZSBmaW5hbCBlbGVtZW50IGZyb20gYSBsb2NhbGUgc3RyaW5nLgogICAgLy8gRm9yIGluc3RhbmNlLCAiZGVfQ0giIGJlY29tZXMgImRlIiwgYW5kICJkZSIgYmVjb21lcyAiIi4KICAgIC8vICIiIHJlbWFpbnMgIiIuCgogICAgaW50MzJfdCAgICAgc2l6ZSA9IGxvY2FsZU5hbWUubGVuZ3RoKCk7CiAgICBpbnQzMl90ICAgICBpOwoKICAgIGZvciAoaSA9IHNpemUgLSAxOyBpID4gMDsgaS0tKQogICAgewogICAgICAgIGlmIChsb2NhbGVOYW1lW2ldID09IDB4MDA1RikKICAgICAgICB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoaSA8IDApCiAgICB7CiAgICAgICBpID0gMDsKICAgIH0KCiAgICBsb2NhbGVOYW1lLnJlbW92ZShpLCBzaXplIC0gaSk7Cn0KCgp1aW50OF90ICoKUnVsZUJhc2VkQ29sbGF0b3I6OmNsb25lUnVsZURhdGEoaW50MzJfdCAmbGVuZ3RoLCBVRXJyb3JDb2RlICZzdGF0dXMpCnsKICAgIFVNZW1vcnlTdHJlYW0gKm1lbWRhdGEgPSAwOwogICAgdWludDhfdCAqZGF0YSA9IDA7CgogICAgaWYoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBtZW1kYXRhID0gdXBydl9tc3RybV9vcGVuTmV3KDApOwoKICAgIGlmIChtZW1kYXRhICE9IDApIHsKICAgICAgICBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1PdXQodGhpcywgbWVtZGF0YSk7CiAgICB9CgogICAgVUJvb2wgZXJyID0gdXBydl9tc3RybV9lcnJvcihtZW1kYXRhKSA9PSAwOwoKCiAgICBkYXRhID0gKHVpbnQ4X3QgKil1cHJ2X21hbGxvYyhtZW1kYXRhLT5mUG9zKTsKICAgIGlmKGRhdGEgPT0gMCkgewogICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgdXBydl9tc3RybV9jbG9zZShtZW1kYXRhKTsKICAgICAgICBsZW5ndGggPSAwOwogICAgICAgIHJldHVybiAwOwogICAgfSBlbHNlIHsKICAgICAgICB1cHJ2X21lbWNweShkYXRhLCBtZW1kYXRhLT5mU3RhcnQsIG1lbWRhdGEtPmZQb3MpOwogICAgICAgIGxlbmd0aCA9IG1lbWRhdGEtPmZQb3M7CiAgICAgICAgdXBydl9tc3RybV9jbG9zZShtZW1kYXRhKTsKICAgICAgICByZXR1cm4gZGF0YTsKICAgIH0KfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6c2V0QXR0cmlidXRlKFVDb2xBdHRyaWJ1dGUgYXR0ciwgVUNvbEF0dHJpYnV0ZVZhbHVlIHZhbHVlLCBVRXJyb3JDb2RlICZzdGF0dXMpIHsKCXN3aXRjaChhdHRyKSB7CgljYXNlIFVDT0xfRlJFTkNIX0NPTExBVElPTjogLyogYXR0cmlidXRlIGZvciBkaXJlY3Rpb24gb2Ygc2Vjb25kYXJ5IHdlaWdodHMqLwoJCWlmKHZhbHVlID09IFVDT0xfT04pIHsKCQkJZGF0YS0+aXNGcmVuY2hTZWMgPSBUUlVFOwoJCX0gZWxzZSBpZiAodmFsdWUgPT0gVUNPTF9PRkYpIHsKCQkJZGF0YS0+aXNGcmVuY2hTZWMgPSBGQUxTRTsKCQl9IGVsc2UgaWYgKHZhbHVlID09IFVDT0xfREVGQVVMVCkgewoJCX0gZWxzZSB7CgkJCXN0YXR1cyA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUiAgOwoJCX0KCQlicmVhazsKICAgIGNhc2UgVUNPTF9BTFRFUk5BVEVfSEFORExJTkc6IC8qIGF0dHJpYnV0ZSBmb3IgaGFuZGxpbmcgdmFyaWFibGUgZWxlbWVudHMqLwoJCXN0YXR1cyA9IFVfVU5TVVBQT1JURURfRVJST1I7CgkJYnJlYWs7CgljYXNlIFVDT0xfQ0FTRV9GSVJTVDogLyogd2hvIGdvZXMgZmlyc3QsIGxvd2VyIGNhc2Ugb3IgdXBwZXJjYXNlICovCgkJc3RhdHVzID0gVV9VTlNVUFBPUlRFRF9FUlJPUjsKCQlicmVhazsKCWNhc2UgVUNPTF9DQVNFX0xFVkVMOiAvKiBkbyB3ZSBoYXZlIGFuIGV4dHJhIGNhc2UgbGV2ZWwgKi8KCQlzdGF0dXMgPSBVX1VOU1VQUE9SVEVEX0VSUk9SOwoJCWJyZWFrOwoJY2FzZSBVQ09MX05PUk1BTElaQVRJT05fTU9ERTogLyogYXR0cmlidXRlIGZvciBub3JtYWxpemF0aW9uICovCgkJc3RhdHVzID0gVV9VTlNVUFBPUlRFRF9FUlJPUjsKCQlicmVhazsKCWNhc2UgVUNPTF9TVFJFTkdUSDogICAgICAgICAvKiBhdHRyaWJ1dGUgZm9yIHN0cmVuZ3RoICovCgkJc3RhdHVzID0gVV9VTlNVUFBPUlRFRF9FUlJPUjsKCQlicmVhazsKCWNhc2UgVUNPTF9BVFRSSUJVVEVfQ09VTlQ6CglkZWZhdWx0OgoJCXN0YXR1cyA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsKCQlicmVhazsKCX0KfQoKVUNvbEF0dHJpYnV0ZVZhbHVlIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLCBVRXJyb3JDb2RlICZzdGF0dXMpIHsKCXN3aXRjaChhdHRyKSB7CgljYXNlIFVDT0xfRlJFTkNIX0NPTExBVElPTjogLyogYXR0cmlidXRlIGZvciBkaXJlY3Rpb24gb2Ygc2Vjb25kYXJ5IHdlaWdodHMqLwoJCWlmKGRhdGEtPmlzRnJlbmNoU2VjID09IFRSVUUpIHsKCQkJcmV0dXJuIFVDT0xfT047CgkJfSBlbHNlIHsKCQkJcmV0dXJuIFVDT0xfT0ZGOwoJCX0KCQlicmVhazsKICAgIGNhc2UgVUNPTF9BTFRFUk5BVEVfSEFORExJTkc6IC8qIGF0dHJpYnV0ZSBmb3IgaGFuZGxpbmcgdmFyaWFibGUgZWxlbWVudHMqLwoJCXN0YXR1cyA9IFVfVU5TVVBQT1JURURfRVJST1I7CgkJYnJlYWs7CgljYXNlIFVDT0xfQ0FTRV9GSVJTVDogLyogd2hvIGdvZXMgZmlyc3QsIGxvd2VyIGNhc2Ugb3IgdXBwZXJjYXNlICovCgkJc3RhdHVzID0gVV9VTlNVUFBPUlRFRF9FUlJPUjsKCQlicmVhazsKCWNhc2UgVUNPTF9DQVNFX0xFVkVMOiAvKiBkbyB3ZSBoYXZlIGFuIGV4dHJhIGNhc2UgbGV2ZWwgKi8KCQlzdGF0dXMgPSBVX1VOU1VQUE9SVEVEX0VSUk9SOwoJCWJyZWFrOwoJY2FzZSBVQ09MX05PUk1BTElaQVRJT05fTU9ERTogLyogYXR0cmlidXRlIGZvciBub3JtYWxpemF0aW9uICovCgkJc3RhdHVzID0gVV9VTlNVUFBPUlRFRF9FUlJPUjsKCQlicmVhazsKCWNhc2UgVUNPTF9TVFJFTkdUSDogICAgICAgICAvKiBhdHRyaWJ1dGUgZm9yIHN0cmVuZ3RoICovCiAgICAgICAgc3dpdGNoKGdldFN0cmVuZ3RoKCkpIHsKICAgICAgICBjYXNlIFBSSU1BUlkgOgogICAgICAgICAgICAgICAgcmV0dXJuIFVDT0xfUFJJTUFSWTsKICAgICAgICBjYXNlIFNFQ09OREFSWSA6CiAgICAgICAgICAgICAgICByZXR1cm4gVUNPTF9TRUNPTkRBUlk7CiAgICAgICAgY2FzZSBURVJUSUFSWSA6CiAgICAgICAgICAgICAgICByZXR1cm4gVUNPTF9URVJUSUFSWTsKICAgICAgICBjYXNlIElERU5USUNBTCA6CiAgICAgICAgICAgICAgICByZXR1cm4gVUNPTF9JREVOVElDQUw7CiAgICAgICAgZGVmYXVsdCA6CiAgICAgICAgICAgIHN0YXR1cyA9IFVfSU5URVJOQUxfUFJPR1JBTV9FUlJPUjsgICAgICAgICAKICAgICAgICB9CgkJYnJlYWs7CgljYXNlIFVDT0xfQVRUUklCVVRFX0NPVU5UOgoJZGVmYXVsdDoKCQlzdGF0dXMgPSBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1I7CgkJYnJlYWs7Cgl9CglyZXR1cm4gVUNPTF9ERUZBVUxUOwp9CgpDb2xsYXRvciogUnVsZUJhc2VkQ29sbGF0b3I6OnNhZmVDbG9uZSh2b2lkKSB7CglyZXR1cm4gMDsKfQoKCkNvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCBSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZShGb3J3YXJkQ2hhcmFjdGVySXRlcmF0b3IgJnNvdXJjZSwKCQkJCQkJCQkJCQkgRm9yd2FyZENoYXJhY3Rlckl0ZXJhdG9yICZ0YXJnZXQpIHsKCXJldHVybiBFUVVBTDsKfQoKaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0U29ydEtleShjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzb3VyY2UsCgkJCQkJCSAgdWludDhfdCAqcmVzdWx0LAoJCQkJCQkgIGludDMyX3QgcmVzdWx0TGVuZ3RoKSBjb25zdCB7CglVQ2hhciBzU3RhcnRbdGJsY29sbF9TdGFja0J1ZmZlckxlbl07CglVQ2hhciAqdVNvdXJjZSA9IHNTdGFydDsKCXVpbnQzMl90IHNvdXJjZUxlbiA9IHNvdXJjZS5sZW5ndGgoKTsKCWlmKHNvdXJjZUxlbiA+PSB0Ymxjb2xsX1N0YWNrQnVmZmVyTGVuKSB7CgkJdVNvdXJjZSA9IG5ldyBVQ2hhcltzb3VyY2VMZW4rMV07Cgl9CiAgICBzb3VyY2UuZXh0cmFjdCgwLCBzb3VyY2VMZW4sIHVTb3VyY2UpOwogICAgdVNvdXJjZVtzb3VyY2VMZW5dID0gMDsKCWludDMyX3QgcmVzTGVuID0gdWNvbF9nZXRTb3J0S2V5KChVQ29sbGF0b3IgKil0aGlzLCB1U291cmNlLCBzb3VyY2VMZW4sIHJlc3VsdCwgcmVzdWx0TGVuZ3RoKTsKCWlmKHNTdGFydCAhPSB1U291cmNlKSB7CgkJZGVsZXRlW10gdVNvdXJjZTsKCX0KCXJldHVybiByZXNMZW47Cn0KCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmdldFNvcnRLZXkoY29uc3QgICBVQ2hhciAqc291cmNlLAoJCQkJCQkgIGludDMyX3Qgc291cmNlTGVuZ3RoLAoJCQkJCQkgIHVpbnQ4X3QgKnJlc3VsdCwKCQkJCQkJICBpbnQzMl90IHJlc3VsdExlbmd0aCkgY29uc3QgewoJaW50MzJfdCByZXNMZW4gPSB1Y29sX2dldFNvcnRLZXkoKFVDb2xsYXRvciAqKXRoaXMsIHNvdXJjZSwgc291cmNlTGVuZ3RoLCByZXN1bHQsIHJlc3VsdExlbmd0aCk7CglyZXR1cm4gcmVzTGVuOwp9CgovL2VvZgo=