LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIENvcHlyaWdodCAoQykgMTk5Ni0xOTk5LCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqCiogRmlsZSB0Ymxjb2xsLmNwcAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCiogIDIvNS85NyAgICAgIGFsaXUgICAgICAgIEFkZGVkIHN0cmVhbUluIGFuZCBzdHJlYW1PdXQgbWV0aG9kcy4gIEFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIHdoaWNoIHJlYWRzIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdCBmcm9tCiogICAgICAgICAgICAgICAgICAgICAgICAgIGEgYmluYXJ5IGZpbGUuICBBZGRlZCB3cml0ZVRvRmlsZSBtZXRob2Qgd2hpY2ggc3RyZWFtcwoqICAgICAgICAgICAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciBvdXQgdG8gYSBiaW5hcnkgZmlsZS4gIFRoZSBzdHJlYW1JbgoqICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgc3RyZWFtT3V0IG1ldGhvZHMgdXNlIGlzdHJlYW0gYW5kIG9zdHJlYW0gb2JqZWN0cwoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbiBiaW5hcnkgbW9kZS4KKiAgMi8xMS85NyAgICAgYWxpdSAgICAgICAgTW92ZWQgZGVjbGFyYXRpb25zIG91dCBvZiBmb3IgbG9vcCBpbml0aWFsaXplci4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgTWFjIGNvbXBhdGliaWxpdHkgI2lmZGVmIGZvciBpb3M6Om5vY3JlYXRlLgoqICAyLzEyLzk3ICAgICBhbGl1ICAgICAgICBNb2RpZmllZCB0byB1c2UgVGFibGVDb2xsYXRpb25EYXRhIHN1Yi1vYmplY3QgdG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgaG9sZCBpbnZhcmlhbnQgZGF0YS4KKiAgMi8xMy85NyAgICAgYWxpdSAgICAgICAgTW92ZWQgc2V2ZXJhbCBtZXRob2RzIGludG8gdGhpcyBjbGFzcyBmcm9tIENvbGxhdGlvbi4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgYSBwcml2YXRlIFJ1bGVCYXNlZENvbGxhdG9yKExvY2FsZSYpIGNvbnN0cnVjdG9yLAoqICAgICAgICAgICAgICAgICAgICAgICAgICB0byBiZSB1c2VkIGJ5IENvbGxhdG9yOjpnZXRJbnN0YW5jZSgpLiAgR2VuZXJhbAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhbiB1cC4gIE1hZGUgdXNlIG9mIFVFcnJvckNvZGUgdmFyaWFibGVzIGNvbnNpc3RlbnQuCiogIDIvMjAvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNsb25lLCBvcGVyYXRvcj09LCBvcGVyYXRvciE9LCBvcGVyYXRvcj0sIGFuZCBjb3B5CiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIGFuZCBnZXREeW5hbWljQ2xhc3NJRC4KKiAgMy81Lzk3ICAgICAgYWxpdSAgICAgICAgQ2hhbmdlZCBjb21wYWN0aW9uIGN5Y2xlIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UuICBXZQoqICAgICAgICAgICAgICAgICAgICAgICAgICB1c2UgdGhlIG1heGltdW0gYWxsb3dhYmxlIHZhbHVlIHdoaWNoIGlzIGtCbG9ja0NvdW50LgoqICAgICAgICAgICAgICAgICAgICAgICAgICBNb2RpZmllZCBnZXRSdWxlcygpIHRvIGxvYWQgcnVsZXMgZHluYW1pY2FsbHkuICBDaGFuZ2VkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdEZyb21GaWxlKCkgY2FsbCB0byBhY2NvbW9kYXRlIHRoaXMgKGFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlciB0byBzcGVjaWZ5IHdoZXRoZXIgYmluYXJ5IGxvYWRpbmcgaXMgdG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGFrZSBwbGFjZSkuCiogMDUvMDYvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIG1lbW9yeSBhbGxvY2F0aW9uIGVycm9yIGNoZWNrLgoqICA2LzIwLzk3ICAgICBoZWxlbmEgICAgICBKYXZhIGNsYXNzIG5hbWUgY2hhbmdlLgoqICA2LzIzLzk3ICAgICBoZWxlbmEgICAgICBBZGRpbmcgY29tbWVudHMgdG8gbWFrZSBjb2RlIG1vcmUgcmVhZGFibGUuCiogMDkvMDMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNyZWF0ZUNvbGxhdGlvbktleVZhbHVlcygpLgoqIDA2LzI2Lzk4ICAgICBlcm0gICAgICAgICBDaGFuZ2VzIGZvciBDb2xsYXRpb25LZXlzIHVzaW5nIGJ5dGUgYXJyYXlzLgoqIDA4LzEwLzk4ICAgICBlcm0gICAgICAgICBTeW5jaGVkIHdpdGggMS4yIHZlcnNpb24gb2YgUnVsZUJhc2VkQ29sbGF0b3IuamF2YQoqIDA0LzIzLzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIEVEZWNvbXBvc2l0aW9uTW9kZSwgbWVyZ2VkIHdpdGgKKiAgICAgICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUKKiAwNi8xNC85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBrUmVzb3VyY2VCdW5kbGVTdWZmaXgKKiAwNi8yMi85OSAgICAgc3RlcGhlbiAgICAgRml4ZWQgbG9naWMgaW4gY29uc3RydWN0RnJvbUZpbGUoKSBzaW5jZSAuY3R4CiogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzIGFyZSBubyBsb25nZXIgdXNlZC4KKiAxMS8wMi85OSAgICAgaGVsZW5hICAgICAgQ29sbGF0b3IgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiAgU3BlY2lhbCBjYXNlCiogICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBOT19PUCBzaXR1YXRpb25zLiAKKiAxMS8xNy85OSAgICAgc3JsICAgICAgICAgTW9yZSBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuIElubGluZWQgc29tZSBpbnRlcm5hbCBmdW5jdGlvbnMuCiogMTIvMTUvOTkgICAgIGFsaXUgICAgICAgIFVwZGF0ZSB0byBzdXBwb3J0IFRoYWkgY29sbGF0aW9uLiAgTW92ZSBOb3JtYWxpemVySXRlcmF0b3IKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gaW1wbGVtZW50YXRpb24gZmlsZS4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKI2luY2x1ZGUgInVjbXAzMi5oIgojaW5jbHVkZSAidGNvbGRhdGEuaCIKCiNpbmNsdWRlICJ1bmljb2RlL3RibGNvbGwuaCIKCiNpbmNsdWRlICJ1bmljb2RlL2NvbGVpdHIuaCIKI2luY2x1ZGUgInVuaWNvZGUvbG9jaWQuaCIKI2luY2x1ZGUgInVuaWNvZGUvdW5pY29kZS5oIgojaW5jbHVkZSAidGFibGVzLmgiCiNpbmNsdWRlICJ1bmljb2RlL25vcm1senIuaCIKI2luY2x1ZGUgIm1lcmdlY29sLmgiCiNpbmNsdWRlICJ1bmljb2RlL3Jlc2J1bmQuaCIKI2luY2x1ZGUgImZpbGVzdHJtLmgiCgojaWZkZWYgX0RFQlVHCiNpbmNsdWRlICJ1bmlzdHJtLmgiCiNlbmRpZgoKI2luY2x1ZGUgImNvbXBpdHIuaCIKCiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJ1bmljb2RlL3VzdHJpbmcuaCIKCgpjbGFzcyBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyCnsKcHVibGljOgogICAgc3RhdGljIHZvaWQgc3RyZWFtSW4oUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBGaWxlU3RyZWFtKiBpcyk7CiAgICBzdGF0aWMgdm9pZCBzdHJlYW1PdXQoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBGaWxlU3RyZWFtKiBvcyk7Cn07CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gIFRoZSBmb2xsb3dpbmcgZGlhZ3JhbSBzaG93cyB0aGUgZGF0YSBzdHJ1Y3R1cmUgb2YgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdC4KLy8gIFN1cHBvc2Ugd2UgaGF2ZSB0aGUgcnVsZSwgd2hlcmUgJ28tdW1sYXV0JyBpcyB0aGUgdW5pY29kZSBjaGFyIDB4MDBGNi4KLy8gICJhLCBBIDwgYiwgQiA8IGMsIEMsIGNoLCBjSCwgQ2gsIENIIDwgZCwgRCAuLi4gPCBvLCBPOyAnby11bWxhdXQnL0UsICdPLXVtbGF1dCcvRSAuLi4iLgovLyAgV2hhdCB0aGUgcnVsZSBzYXlzIGlzLCBzb3J0cyAnY2gnbGlnYXR1cmVzIGFuZCAnYycgb25seSB3aXRoIHRlcnRpYXJ5IGRpZmZlcmVuY2UgYW5kCi8vICBzb3J0cyAnby11bWxhdXQnIGFzIGlmIGl0J3MgYWx3YXlzIGV4cGFuZGVkIHdpdGggJ2UnLgovLwovLyBtYXBwaW5nIHRhYmxlICAgICAgICAgICAgICAgICAgICAgICBjb250cmFjdGluZyBsaXN0ICAgICAgICAgICAgICAgICAgZXhwYW5kaW5nIGxpc3QKLy8gKGNvbnRhaW5zIGFsbCB1bmljb2RlIGNoYXIKLy8gIGVudHJpZXMpICAgICAgICAgICAgICAgICAgICAgICAgIF9fXyAgICAgX19fX19fX19fX19fXyAgICAgICAgIF9fX19fX19fX19fX19fX19fX19fX19fX18KLy8gICBfX19fX19fXyAgICAgICAgICAgICAgICAgICB8PT0+fF8qX3wtLT58J2MnICB8dignYycpIHwgICB8PT0+fHYoJ28nKXx2KCd1bWxhdXQnKXx2KCdlJyl8Ci8vICB8X1x1MDAwMV98LS0+IHYoJ1x1MDAwMScpICAgfCAgIHxfOl98ICAgfC0tLS0tLS0tLS0tLS18ICAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAovLyAgfF9cdTAwMDJffC0tPiB2KCdcdTAwMDInKSAgIHwgICB8XzpffCAgIHwnY2gnIHx2KCdjaCcpfCAgIHwgICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKLy8gIHxfX19fOl9fX3wgICAgICAgICAgICAgICAgICB8ICAgfF86X3wgICB8LS0tLS0tLS0tLS0tLXwgICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgfCdjSCcgfHYoJ2NIJyl8ICAgfCAgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAovLyAgfF9fJ2EnX19ffC0tPiB2KCdhJykgICAgICAgIHwgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tfCAgIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKLy8gIHxfXydiJ19fX3wtLT4gdignYicpICAgICAgICB8ICAgICAgICAgICB8J0NoJyB8dignQ2gnKXwgICB8ICAgfCAgICAgICAgICAgICA6ICAgICAgICAgICB8Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgfC0tLS0tLS0tLS0tLS18ICAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAovLyAgfF9fX186X19ffCAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgIHwnQ0gnIHx2KCdDSCcpfCAgIHwgICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKLy8gIHxfX18nYydfX3wtLS0tLS0tLS0tLS0tLS0tLS0tICAgICAgICAgICAgLS0tLS0tLS0tLS0tLSAgICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAovLyAgfG8tdW1sYXV0fC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgICB8X19fX19fX19fX19fX19fX19fX19fX19fX3wKLy8gIHxfX19fOl9fX3wKLy8KLy8KLy8gTm90ZWQgYnkgSGVsZW5hIFNoaWggb24gNi8yMy85NyB3aXRoIHBlbmRpbmcgZGVzaWduIGNoYW5nZXMgKHNsaW1taW5nIGNvbGxhdGlvbikuCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkNIQVJJTkRFWCA9IDB4NzAwMDAwMDA7ICAgICAgICAgICAgIC8vIG5lZWQgbG9vayB1cCBpbiAuY29tbWl0KCkKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6RVhQQU5EQ0hBUklOREVYID0gMHg3RTAwMDAwMDsgICAgICAgLy8gRXhwYW5kIGluZGV4IGZvbGxvd3MKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Q09OVFJBQ1RDSEFSSU5ERVggPSAweDdGMDAwMDAwOyAgICAgLy8gY29udHJhY3QgaW5kZXhlcyBmb2xsb3dzCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlVOTUFQUEVEID0gMHhGRkZGRkZGRjsgICAgICAgICAgICAgIC8vIHVubWFwcGVkIGNoYXJhY3RlciB2YWx1ZXMKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAxMDAwMDsgLy8gcHJpbWFyeSBzdHJlbmd0aCBpbmNyZW1lbnQKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJJTkNSRU1FTlQgPSAweDAwMDAwMTAwOyAvLyBzZWNvbmRhcnkgc3RyZW5ndGggaW5jcmVtZW50CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJJTkNSRU1FTlQgPSAweDAwMDAwMDAxOyAvLyB0ZXJ0aWFyeSBzdHJlbmd0aCBpbmNyZW1lbnQKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6TUFYSUdOT1JBQkxFID0gMHgwMDAxMDAwMDsgICAgICAgICAgLy8gbWF4aW11bSBpZ25vcmFibGUgY2hhciBvcmRlciB2YWx1ZQpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJNQVNLID0gMHhmZmZmMDAwMDsgICAgICAvLyBtYXNrIG9mZiBhbnl0aGluZyBidXQgcHJpbWFyeSBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUk1BU0sgPSAweDAwMDBmZjAwOyAgICAvLyBtYXNrIG9mZiBhbnl0aGluZyBidXQgc2Vjb25kYXJ5IG9yZGVyCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJNQVNLID0gMHgwMDAwMDBmZjsgICAgIC8vIG1hc2sgb2ZmIGFueXRoaW5nIGJ1dCB0ZXJ0aWFyeSBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllSRVNFVE1BU0sgPSAweDAwMDBmZmZmOyAgICAvLyBtYXNrIG9mZiBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IG9yZGVyCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OklHTk9SQUJMRU1BU0sgPSAweDAwMDBmZmZmOyAgICAgICAgIC8vIG1hc2sgb2ZmIGlnbm9yYWJsZSBjaGFyIG9yZGVyCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllESUZGRVJFTkNFT05MWSA9IDB4ZmZmZjAwMDA7IC8vIHVzZSBvbmx5IHRoZSBwcmltYXJ5IGRpZmZlcmVuY2UKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZRElGRkVSRU5DRU9OTFkgPSAweGZmZmZmZjAwOyAgLy8gdXNlIG9ubHkgdGhlIHByaW1hcnkgYW5kIHNlY29uZGFyeSBkaWZmZXJlbmNlCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllPUkRFUlNISUZUID0gMTY7ICAgICAgICAgICAgIC8vIHByaW1hcnkgb3JkZXIgc2hpZnQKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJTSElGVCA9IDg7ICAgICAgICAgICAgLy8gc2Vjb25kYXJ5IG9yZGVyIHNoaWZ0CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNPUlRLRVlPRkZTRVQgPSAxOyAgICAgICAgICAgICAgICAgIC8vIG1pbmltdW0gc29ydCBrZXkgb2Zmc2V0CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkNPTlRSQUNUQ0hBUk9WRVJGTE9XID0gMHg3RkZGRkZGRjsgIC8vIEluZGljYXRlcyB0aGUgY2hhciBpcyBhIGNvbnRyYWN0IGNoYXIKCmNvbnN0IGludDE2X3QgUnVsZUJhc2VkQ29sbGF0b3I6OkZJTEVJRCA9IDB4NTQ0MzsgICAgICAgICAgICAgICAgICAgIC8vIHVuaXF1ZSBmaWxlIGlkIGZvciBwYXJpdHkgY2hlY2sKY29uc3QgY2hhciogUnVsZUJhc2VkQ29sbGF0b3I6OmtGaWxlbmFtZVN1ZmZpeCA9ICIuY29sIjsgICAgICAgICAgICAgLy8gYmluYXJ5IGNvbGxhdGlvbiBmaWxlIGV4dGVuc2lvbgpjaGFyICBSdWxlQmFzZWRDb2xsYXRvcjo6ZmdDbGFzc0lEID0gMDsgLy8gVmFsdWUgaXMgaXJyZWxldmFudCAgICAgICAvLyBjbGFzcyBpZAoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIE5vcm1hbGl6ZXJJdGVyYXRvcgovLwovLyBUaGlzIGNsYXNzIGlzIGVzc2VudGlhbGx5IGEgZHVwbGljYXRlIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciwKLy8gc3RyaXBwZWQgZG93biBmb3Igc3BlZWQuICBJdCBpcyBkZWNsYXJlZCBoZXJlIHNvIHdlIGNhbiBpbmNvcnBvcmF0ZQovLyBpbnRlcm5hbCBjbGFzc2VzIGFzIHN1Ym9iamVjdHMsIGFzIHdlbGwgYXMganVzdCB0byBoaWRlIGl0IGZyb20gdGhlCi8vIHB1YmxpYyBpbnRlcmZhY2UuCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKLyogSW50ZXJuYWwgY2xhc3MgZm9yIHF1aWNrIGl0ZXJhdGlvbiBvdmVyIHRoZSB0ZXh0LgogICAxMDAlIHB1cmUgaW5saW5lIGNvZGUKKi8KY2xhc3MgTm9ybWFsaXplckl0ZXJhdG9yIHsgCnB1YmxpYzoKICAgIE5vcm1hbGl6ZXIgKmN1cnNvcjsKICAgIFZlY3Rvck9mSW50ICpidWZmZXJBbGlhczsKICAgIFZlY3Rvck9mSW50ICpyZW9yZGVyQnVmZmVyOwogICAgVmVjdG9yT2ZJbnQgb3duQnVmZmVyOwogICAgVUNoYXIqICAgICAgdGV4dDsKICAgIGludDMyX3QgICAgIGV4cEluZGV4OwogICAgaW50MzJfdCAgICAgdGV4dExlbjsKICAgIFVUZXh0T2Zmc2V0ICBjdXJyZW50T2Zmc2V0OwogICAgCiAgICBOb3JtYWxpemVySXRlcmF0b3Iodm9pZCk7CiAgICBOb3JtYWxpemVySXRlcmF0b3IoY29uc3QgVUNoYXIqIHNvdXJjZSwgaW50MzJfdCBsZW5ndGgsIE5vcm1hbGl6ZXI6OkVNb2RlIG1vZGUpOwogICAgfk5vcm1hbGl6ZXJJdGVyYXRvcih2b2lkKTsKICAgIHZvaWQgc2V0VGV4dChjb25zdCBVQ2hhciogc291cmNlLCBpbnQzMl90IGxlbmd0aCwgVUVycm9yQ29kZSYgc3RhdHVzKTsKICAgIHZvaWQgc2V0TW9kZUFuZFRleHQoTm9ybWFsaXplcjo6RU1vZGUgbW9kZSwgY29uc3QgVUNoYXIqIHNvdXJjZSwgaW50MzJfdCBsZW5ndGgsIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgICAKICAgIFVDaGFyIGN1cnJlbnQodm9pZCkgY29uc3Q7CiAgICBVQ2hhciBuZXh0KHZvaWQpOwogICAgdm9pZCByZXNldCh2b2lkKTsKfTsKCmlubGluZQpOb3JtYWxpemVySXRlcmF0b3I6Ok5vcm1hbGl6ZXJJdGVyYXRvcigpIDoKICAgIGN1cnNvcigwKSwKICAgIGJ1ZmZlckFsaWFzKDApLAogICAgcmVvcmRlckJ1ZmZlcigwKSwKICAgIG93bkJ1ZmZlcigyKSwKICAgIHRleHQoMCksCiAgICB0ZXh0TGVuKDApLAogICAgY3VycmVudE9mZnNldCgwKSwKICAgIGV4cEluZGV4KDApCnsKfQoKaW5saW5lCk5vcm1hbGl6ZXJJdGVyYXRvcjo6Tm9ybWFsaXplckl0ZXJhdG9yKGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3QgbGVuZ3RoLCBOb3JtYWxpemVyOjpFTW9kZSBtb2RlKSA6CiAgICBjdXJzb3IoMCksCiAgICBidWZmZXJBbGlhcygwKSwKICAgIHJlb3JkZXJCdWZmZXIoMCksCiAgICBvd25CdWZmZXIoMiksCiAgICB0ZXh0KDApLAogICAgdGV4dExlbigwKSwKICAgIGN1cnJlbnRPZmZzZXQoMCksCiAgICBleHBJbmRleCgwKQp7CiAgICBpZiAobW9kZSA9PSBOb3JtYWxpemVyOjpOT19PUCkgewogICAgICAgIHRleHQgPSAoVUNoYXIqKXNvdXJjZTsKICAgICAgICB0ZXh0TGVuID0gbGVuZ3RoOwogICAgICAgIGN1cnJlbnRPZmZzZXQgPSAwOwogICAgfSBlbHNlIHsKICAgICAgICBjdXJzb3IgPSBuZXcgTm9ybWFsaXplcihzb3VyY2UsIGxlbmd0aCwgbW9kZSk7CgogICAgfQp9CgppbmxpbmUKTm9ybWFsaXplckl0ZXJhdG9yOjp+Tm9ybWFsaXplckl0ZXJhdG9yKCkgCnsKICAgIGlmIChjdXJzb3IgIT0gMCkgewogICAgICAgIGRlbGV0ZSBjdXJzb3I7CiAgICAgICAgY3Vyc29yID0gMDsKICAgIH0KICAgIGlmIChyZW9yZGVyQnVmZmVyICE9IDApIHsKICAgICAgICBkZWxldGUgcmVvcmRlckJ1ZmZlcjsKICAgIH0KfQoKaW5saW5lCnZvaWQKTm9ybWFsaXplckl0ZXJhdG9yOjpzZXRUZXh0KGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3QgbGVuZ3RoLCBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmIChjdXJzb3IgPT0gMCkgewogICAgICAgIHRleHQgPSAoVUNoYXIqKXNvdXJjZTsKICAgICAgICB0ZXh0TGVuID0gbGVuZ3RoOwogICAgICAgIGN1cnJlbnRPZmZzZXQgPSAwOwoKICAgIH0gZWxzZSB7CiAgICAgICAgdGV4dCA9IDA7CiAgICAgICAgY3Vyc29yLT5zZXRUZXh0KHNvdXJjZSwgbGVuZ3RoLCBzdGF0dXMpOwogICAgfQogICAgYnVmZmVyQWxpYXMgPSAwOwogICAgY3VycmVudE9mZnNldCA9IDA7Cn0KCi8qIFlvdSBjYW4gb25seSBzZXQgbW9kZSBhZnRlciB0aGUgY29tcGFyaXNpb24gb2YgdHdvIHN0cmluZ3MgaXMgY29tcGxldGVkLgogICBTZXR0aW5nIHRoZSBtb2RlIGluIHRoZSBtaWRkbGUgb2YgYSBjb21wYXJpc29uIGlzIG5vdCBhbGxvd2VkLgogICAqLwppbmxpbmUKdm9pZAoKTm9ybWFsaXplckl0ZXJhdG9yOjpzZXRNb2RlQW5kVGV4dChOb3JtYWxpemVyOjpFTW9kZSBtb2RlLCBjb25zdCBVQ2hhciogc291cmNlLCBpbnQzMl90IGxlbmd0aCwgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICBpZihtb2RlICE9IE5vcm1hbGl6ZXI6Ok5PX09QKQogICAgewogICAgICAgIC8qIERPIGhhdmUgYSBtb2RlIC0gIHdpbGwgbmVlZCBhIG5vcm1hbGl6ZXIgb2JqZWN0ICovCiAgICAgICAgaWYoY3Vyc29yICE9IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICAvKiBKdXN0IG1vZGlmeSB0aGUgZXhpc3RpbmcgY3Vyc29yICovCiAgICAgICAgICAgIGN1cnNvci0+c2V0TW9kZShtb2RlKTsKICAgICAgICAgICAgY3Vyc29yLT5zZXRUZXh0KHNvdXJjZSwgbGVuZ3RoLCBzdGF0dXMpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBjdXJzb3IgPSBuZXcgTm9ybWFsaXplcihzb3VyY2UsIGxlbmd0aCwgbW9kZSk7CiAgICAgICAgfQoKICAgICAgICAvKiBSRVNFVCB0aGUgb2xkIGRhdGEgKi8KICAgICAgICB0ZXh0ID0gMDsKICAgICAgICB0ZXh0TGVuID0gMDsKICAgIH0KICAgIGVsc2UgCiAgICB7CiAgICAgICAgLyogTk9fT1AgbW9kZS4uICovCiAgICAgICAgaWYoY3Vyc29yICE9IE5VTEwpCiAgICAgICAgeyAvKiBnZXQgcmlkIG9mIHRoZSBvbGQgY3Vyc29yICovCiAgICAgICAgICAgIGRlbGV0ZSBjdXJzb3I7IAogICAgICAgICAgICBjdXJzb3IgPSAwOwogICAgICAgIH0KCiAgICAgICAgdGV4dCA9IChVQ2hhciopc291cmNlOwogICAgICAgIHRleHRMZW4gPSBsZW5ndGg7CiAgICB9CiAgICBjdXJyZW50T2Zmc2V0ID0gMDsgLyogYWx3YXlzICovCiAgIAogICAgYnVmZmVyQWxpYXMgPSAwOwp9CgppbmxpbmUKVUNoYXIKTm9ybWFsaXplckl0ZXJhdG9yOjpjdXJyZW50KHZvaWQpIGNvbnN0CnsKICAgIGlmICh0ZXh0ICE9IDApIHsKICAgICAgICBpZihjdXJyZW50T2Zmc2V0ID49IHRleHRMZW4pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gTm9ybWFsaXplcjo6RE9ORTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRleHRbY3VycmVudE9mZnNldF07CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBjdXJzb3ItPmN1cnJlbnQoKTsKfQoKCmlubGluZQpVQ2hhcgpOb3JtYWxpemVySXRlcmF0b3I6Om5leHQodm9pZCkKewogICAgaWYgKHRleHQgIT0gMCkgewogICAgICAgIHJldHVybiAoKGN1cnJlbnRPZmZzZXQgPCB0ZXh0TGVuKSA/IHRleHRbKytjdXJyZW50T2Zmc2V0XSA6IE5vcm1hbGl6ZXI6OkRPTkUpOwogICAgfQogICAgcmV0dXJuIGN1cnNvci0+bmV4dCgpOwp9CgppbmxpbmUKdm9pZApOb3JtYWxpemVySXRlcmF0b3I6OnJlc2V0KHZvaWQpCnsKICAgIGN1cnJlbnRPZmZzZXQgPSAwOwogICAgaWYoY3Vyc29yKQogICAgewogICAgICAgIGN1cnNvci0+cmVzZXQoKTsKICAgIH0KfQoKLy89PT09PT09PT09PT09PT09IFNvbWUgaW5saW5lIGRlZmluaXRpb25zIG9mIGltcGxlbWVudGF0aW9uIGZ1bmN0aW9ucy4uLi4uLi4uID09PT09PT09Ci8qKgogKiBBIGNsb25lIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bWFrZVJlb3JkZXJlZEJ1ZmZlciwgdHJpbW1lZCBkb3duCiAqIHRvIG9ubHkgaGFuZGxlIGZvcndhcmQuCiAqLwppbmxpbmUgVmVjdG9yT2ZJbnQqClJ1bGVCYXNlZENvbGxhdG9yOjptYWtlUmVvcmRlcmVkQnVmZmVyKE5vcm1hbGl6ZXJJdGVyYXRvciogY3Vyc29yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ2hhciBjb2xGaXJzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsYXN0VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3Rvck9mSW50KiBsYXN0RXhwYW5zaW9uKSBjb25zdCB7CiAgICBWZWN0b3JPZkludCogcmVzdWx0OwoKICAgIGludDMyX3QgZmlyc3RWYWx1ZSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY29sRmlyc3QpOwogICAgaWYgKGZpcnN0VmFsdWUgPj0gQ09OVFJBQ1RDSEFSSU5ERVgpIHsKICAgICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAgICBmaXJzdFZhbHVlID0gbmV4dENvbnRyYWN0Q2hhcihjdXJzb3IsIGNvbEZpcnN0LCBzdGF0dXMpOwogICAgfQoKICAgIFZlY3Rvck9mSW50KiBmaXJzdEV4cGFuc2lvbiA9IE5VTEw7CiAgICBpZiAoZmlyc3RWYWx1ZSA+PSBFWFBBTkRDSEFSSU5ERVgpIHsKICAgICAgICBmaXJzdEV4cGFuc2lvbiA9IGdldEV4cGFuZFZhbHVlTGlzdChmaXJzdFZhbHVlKTsKICAgIH0KCiAgICBpZiAoZmlyc3RFeHBhbnNpb24gPT0gTlVMTCAmJiBsYXN0RXhwYW5zaW9uID09IE5VTEwpIHsKICAgICAgICBjdXJzb3ItPm93bkJ1ZmZlci5hdCgwKSA9IGZpcnN0VmFsdWU7CiAgICAgICAgY3Vyc29yLT5vd25CdWZmZXIuYXQoMSkgPSBsYXN0VmFsdWU7CiAgICAgICAgcmVzdWx0ID0gJmN1cnNvci0+b3duQnVmZmVyOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgaW50MzJfdCBmaXJzdExlbmd0aCA9IGZpcnN0RXhwYW5zaW9uPT1OVUxMPyAxIDogZmlyc3RFeHBhbnNpb24tPnNpemUoKTsKICAgICAgICBpbnQzMl90IGxhc3RMZW5ndGggPSBsYXN0RXhwYW5zaW9uPT1OVUxMPyAxIDogbGFzdEV4cGFuc2lvbi0+c2l6ZSgpOwogICAgICAgIGlmIChjdXJzb3ItPnJlb3JkZXJCdWZmZXIgPT0gTlVMTCkgewogICAgICAgICAgICBjdXJzb3ItPnJlb3JkZXJCdWZmZXIgPSBuZXcgVmVjdG9yT2ZJbnQoZmlyc3RMZW5ndGgrbGFzdExlbmd0aCk7CiAgICAgICAgfQogICAgICAgIC8vIHJlb3JkZXJkQnVmZmVyIGdldHMgcmV1c2VkIGZvciB0aGUgbGlmZSBvZiB0aGlzIG9iamVjdC4KICAgICAgICAvLyBTaW5jZSBpdHMgaW50ZXJuYWwgYnVmZmVyIG9ubHkgZ3Jvd3MsIHRoZXJlIGlzIGEgZGFuZ2VyCiAgICAgICAgLy8gdGhhdCBpdCB3aWxsIGdldCByZWFsbHksIHJlYWxseSBiaWcsIGFuZCBuZXZlciBzaHJpbmsuICBJZgogICAgICAgIC8vIHRoaXMgaXMgYWN0dWFsbHkgaGFwcGVuaW5nLCBpbnNlcnQgY29kZSBoZXJlIHRvIGNoZWNrIGZvcgogICAgICAgIC8vIHRoZSBjb25kaXRpb24uICBTb21ldGhpbmcgYWxvbmcgdGhlIGxpbmVzIG9mOgogICAgICAgIC8vISBlbHNlIGlmIChyZW9yZGVyQnVmZmVyLT5zaXplKCkgPj0gMjU2ICYmCiAgICAgICAgLy8hICAgICAgICAgIChmaXJzdExlbmd0aCtsYXN0TGVuZ3RoKSA8IDE2KSB7CiAgICAgICAgLy8hICAgICBkZWxldGUgcmVvcmRlckJ1ZmZlcjsKICAgICAgICAvLyEgICAgIHJlb3JkZXJCdWZmZXIgPSBuZXcgVmVjdG9yT2ZJbnQoZmlyc3RMZW5ndGgrbGFzdExlbmd0aCk7CiAgICAgICAgLy8hIH0KICAgICAgICAvLyBUaGUgc3BlY2lmaWMgbnVtZXJpYyB2YWx1ZXMgbmVlZCB0byBiZSBkZXRlcm1pbmVkCiAgICAgICAgLy8gZW1waXJpY2FsbHkuIFthbGl1XQogICAgICAgIHJlc3VsdCA9IGN1cnNvci0+cmVvcmRlckJ1ZmZlcjsKCiAgICAgICAgaWYgKGZpcnN0RXhwYW5zaW9uID09IE5VTEwpIHsKICAgICAgICAgICAgcmVzdWx0LT5hdFB1dCgwLCBmaXJzdFZhbHVlKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8vIFN5c3RlbS5hcnJheWNvcHkoZmlyc3RFeHBhbnNpb24sIDAsIHJlc3VsdCwgMCwgZmlyc3RMZW5ndGgpOwogICAgICAgICAgICAqcmVzdWx0ID0gKmZpcnN0RXhwYW5zaW9uOwogICAgICAgIH0KCiAgICAgICAgaWYgKGxhc3RFeHBhbnNpb24gPT0gTlVMTCkgewogICAgICAgICAgICByZXN1bHQtPmF0UHV0KGZpcnN0TGVuZ3RoLCBsYXN0VmFsdWUpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLy8gU3lzdGVtLmFycmF5Y29weShsYXN0RXhwYW5zaW9uLCAwLCByZXN1bHQsIGZpcnN0TGVuZ3RoLCBsYXN0TGVuZ3RoKTsKICAgICAgICAgICAgZm9yIChpbnQzMl90IGk9MDsgaTxsYXN0TGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIHJlc3VsdC0+YXRQdXQoZmlyc3RMZW5ndGggKyBpLCBsYXN0RXhwYW5zaW9uLT5hdChpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVzdWx0LT5zZXRTaXplKGZpcnN0TGVuZ3RoK2xhc3RMZW5ndGgpOwogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCgoKCgppbmxpbmUgaW50MzJfdApSdWxlQmFzZWRDb2xsYXRvcjo6c3RyZW5ndGhPcmRlcihpbnQzMl90IHZhbHVlKSBjb25zdAp7CiAgICBpZiAoZ2V0U3RyZW5ndGgoKSA9PSBQUklNQVJZKQogICAgewogICAgICAgIHJldHVybiAodmFsdWUgJiBQUklNQVJZRElGRkVSRU5DRU9OTFkpOwogICAgfSBlbHNlIGlmIChnZXRTdHJlbmd0aCgpID09IFNFQ09OREFSWSkKICAgIHsKICAgICAgICByZXR1cm4gKHZhbHVlICYgU0VDT05EQVJZRElGRkVSRU5DRU9OTFkpOwogICAgfQogICAgcmV0dXJuIHZhbHVlOwp9CgoKaW5saW5lIGludDMyX3QKUnVsZUJhc2VkQ29sbGF0b3I6OmdldFN0cmVuZ3RoT3JkZXIoTm9ybWFsaXplckl0ZXJhdG9yKiBjdXJzb3IsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlIHN0YXR1cykgY29uc3QKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUjsKICAgIH0KCiAgICBpZiAoY3Vyc29yLT5idWZmZXJBbGlhcyAhPSBOVUxMKQogICAgewogICAgICAgIC8vIGJ1ZmZlckFsaWFzIG5lZWRzIGEgYml0IG9mIGFuIGV4cGxhbmF0aW9uLgogICAgICAgIC8vIFdoZW4gd2UgaGl0IGFuIGV4cGFuZGluZyBjaGFyYWN0ZXIgaW4gdGhlIHRleHQsIHdlIGNhbGwgdGhlIG9yZGVyJ3MKICAgICAgICAvLyBnZXRFeHBhbmRWYWx1ZXMgbWV0aG9kIHRvIHJldHJpZXZlIGFuIGFycmF5IG9mIHRoZSBvcmRlcmluZ3MgZm9yIGFsbAogICAgICAgIC8vIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBleHBhbnNpb24gKHNlZSB0aGUgZW5kIG9mIHRoaXMgbWV0aG9kKS4KICAgICAgICAvLyBUaGUgZmlyc3Qgb3JkZXJpbmcgaXMgcmV0dXJuZWQsIGFuZCBhbiBhbGlhcyB0byB0aGUgb3JkZXJpbmdzIGFycmF5CiAgICAgICAgLy8gaXMgc2F2ZWQgc28gdGhhdCB0aGUgcmVtYWluaW5nIG9yZGVyaW5ncyBjYW4gYmUgcmV0dXJuZWQgb24gc3Vic2VxdWVudAogICAgICAgIC8vIGNhbGxzIHRvIG5leHQuICBTbywgaWYgdGhlIGV4cGFuZGluZyBidWZmZXIgaXMgbm90IGV4aGF1c3RlZCwgCiAgICAgICAgLy8gYWxsIHdlIGhhdmUgdG8gZG8gaGVyZSBpcyByZXR1cm4gdGhlIG5leHQgb3JkZXJpbmcgaW4gdGhlIGJ1ZmZlci4gIAogICAgICAgIGlmIChjdXJzb3ItPmV4cEluZGV4IDwgY3Vyc29yLT5idWZmZXJBbGlhcy0+c2l6ZSgpKQogICAgICAgIHsKICAgICAgICAgICAgLy9fTCgoc3RkZXJyLCAibmV4dCBmcm9tIFslMDhYXSBmcm9tIGJ1ZmZlckFsaWFzXG4iLCB0aGlzKSk7CiAgICAgICAgICAgIHJldHVybiBzdHJlbmd0aE9yZGVyKGN1cnNvci0+YnVmZmVyQWxpYXMtPmF0KGN1cnNvci0+ZXhwSW5kZXgrKykpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBjdXJzb3ItPmJ1ZmZlckFsaWFzID0gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgVUNoYXIgY2ggPSBjdXJzb3ItPmN1cnJlbnQoKTsKICAgIGN1cnNvci0+bmV4dCgpOwoKICAgIC8vX0woKHN0ZGVyciwgIk5leHQgZnJvbSBbJTA4WF0gPSBbJTA0WF0sIFslY11cbiIsIGN1cnNvciwgKGludCljaCAmIDB4RkZGRiwgKGNoYXIpKGNoICYgMHhGRikpKTsKICAgIAogICAgaWYgKGNoID09IE5vcm1hbGl6ZXI6OkRPTkUpIHsKICAgICAgICByZXR1cm4gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVI7CiAgICB9CiAgICAvLyBBc2sgdGhlIGNvbGxhdG9yIGZvciB0aGlzIGNoYXJhY3RlcidzIG9yZGVyaW5nLgogICAgaW50MzJfdCB2YWx1ZSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY2gpOwoKICAgIGlmICh2YWx1ZSA9PSBVTk1BUFBFRCkKICAgIHsKICAgICAgICAvLyBSZXR1cm5lZCBhbiAidW5tYXBwZWQiIGZsYWcgYW5kIHNhdmUgdGhlIGNoYXJhY3RlciBzbyBpdCBjYW4gYmUgCiAgICAgICAgLy8gcmV0dXJuZWQgbmV4dCB0aW1lIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC4KICAgICAgICBpZiAoY2ggPT0gMHgwMDAwKSByZXR1cm4gY2g7IC8vIFx1MDAwMCBpcyBub3QgdmFsaWQgaW4gQysrJ3MgVW5pY29kZVN0cmluZwogICAgICAgIGN1cnNvci0+b3duQnVmZmVyLmF0KDApID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpVTk1BUFBFRENIQVJWQUxVRTsKICAgICAgICBjdXJzb3ItPm93bkJ1ZmZlci5hdCgxKSA9IGNoIDw8IDE2OwogICAgICAgIGN1cnNvci0+YnVmZmVyQWxpYXMgPSAmY3Vyc29yLT5vd25CdWZmZXI7CgogICAgfSBlbHNlIHsKICAgICAgICAKICAgICAgICBpZiAodmFsdWUgPj0gQ09OVFJBQ1RDSEFSSU5ERVgpCiAgICAgICAgewogICAgICAgICAgICB2YWx1ZSA9IG5leHRDb250cmFjdENoYXIoY3Vyc29yLCBjaCwgc3RhdHVzKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKHZhbHVlID49IEVYUEFORENIQVJJTkRFWCkgewogICAgICAgICAgICBjdXJzb3ItPmJ1ZmZlckFsaWFzID0gZ2V0RXhwYW5kVmFsdWVMaXN0KHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6aXNUaGFpUHJlVm93ZWwoY2gpKSB7CiAgICAgICAgICAgIFVDaGFyIGNvbnNvbmFudCA9IGN1cnNvci0+Y3VycmVudCgpOwogICAgICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc1RoYWlCYXNlQ29uc29uYW50KGNvbnNvbmFudCkpIHsKICAgICAgICAgICAgICAgIGN1cnNvci0+bmV4dCgpOwogICAgICAgICAgICAgICAgY3Vyc29yLT5idWZmZXJBbGlhcyA9IG1ha2VSZW9yZGVyZWRCdWZmZXIoY3Vyc29yLCBjb25zb25hbnQsIHZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3Vyc29yLT5idWZmZXJBbGlhcyk7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChjdXJzb3ItPmJ1ZmZlckFsaWFzICE9IE5VTEwpIHsKICAgICAgICBjdXJzb3ItPmV4cEluZGV4ID0gMTsKICAgICAgICB2YWx1ZSA9IGN1cnNvci0+YnVmZmVyQWxpYXMtPmF0KDApOwogICAgfQoKICAgIHJldHVybiBzdHJlbmd0aE9yZGVyKHZhbHVlKTsKfQoKLy8gPT09PT09PT09PT09PT09PT09PT0gRW5kIGlubGluZXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcigpCiAgICA6IENvbGxhdG9yKCksCiAgICAgIGlzT3Zlcklnbm9yZShGQUxTRSksCiAgICAgIG1QYXR0ZXJuKDApLAogICAgICAvLyAgICAgIHNvdXJjZUN1cnNvcigwKSwKICAgICAgLy90YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICAgIGRhdGEoMCksCiAgICAgIGRhdGFJc093bmVkKEZBTFNFKQp7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgUnVsZUJhc2VkQ29sbGF0b3ImICB0aGF0KQogICAgOiBDb2xsYXRvcih0aGF0KSwKICAgICAgaXNPdmVySWdub3JlKHRoYXQuaXNPdmVySWdub3JlKSwKICAgICAgbVBhdHRlcm4oMCksCiAgICAgIC8vICAgICAgc291cmNlQ3Vyc29yKDApLAogICAgICAvL3RhcmdldEN1cnNvcigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpLAogICAgICBkYXRhKHRoYXQuZGF0YSkgLy8gQWxpYXMgdGhlIGRhdGEgcG9pbnRlcgp7Cn0KCmJvb2xfdApSdWxlQmFzZWRDb2xsYXRvcjo6b3BlcmF0b3I9PShjb25zdCBDb2xsYXRvciYgdGhhdCkgY29uc3QKewogICAgaWYgKHRoaXMgPT0gJnRoYXQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgaWYgKHRoaXMtPmdldER5bmFtaWNDbGFzc0lEKCkgIT0gdGhhdC5nZXREeW5hbWljQ2xhc3NJRCgpKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsgIC8vIG5vdCB0aGUgc2FtZSBjbGFzcwogICAgfQoKICAgIGlmICghQ29sbGF0b3I6Om9wZXJhdG9yPT0odGhhdCkpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIFJ1bGVCYXNlZENvbGxhdG9yJiB0aGF0QWxpYXMgPSAoUnVsZUJhc2VkQ29sbGF0b3ImKXRoYXQ7CgogICAgaWYgKGlzT3Zlcklnbm9yZSAhPSB0aGF0QWxpYXMuaXNPdmVySWdub3JlKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoZGF0YSAhPSB0aGF0QWxpYXMuZGF0YSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KClJ1bGVCYXNlZENvbGxhdG9yJgpSdWxlQmFzZWRDb2xsYXRvcjo6b3BlcmF0b3I9KGNvbnN0ICBSdWxlQmFzZWRDb2xsYXRvciYgdGhhdCkKewogICAgaWYgKHRoaXMgIT0gJnRoYXQpCiAgICB7CiAgICAgICAgQ29sbGF0b3I6Om9wZXJhdG9yPSh0aGF0KTsKICAgICAgICBpc092ZXJJZ25vcmUgPSB0aGF0LmlzT3Zlcklnbm9yZTsKCiAgICAgICAgaWYgKGRhdGFJc093bmVkKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgfQoKICAgICAgICBkYXRhID0gMDsKICAgICAgICBkZWxldGUgbVBhdHRlcm47CiAgICAgICAgbVBhdHRlcm4gPSAwOwogICAgICAgIGRhdGFJc093bmVkID0gRkFMU0U7CiAgICAgICAgZGF0YSA9IHRoYXQuZGF0YTsKICAgIH0KCiAgICByZXR1cm4gKnRoaXM7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCiAgICA6IENvbGxhdG9yKCksCiAgICAgIGlzT3Zlcklnbm9yZShGQUxTRSksCiAgICAgIG1QYXR0ZXJuKDApLAogICAgICAvLyAgICAgIHNvdXJjZUN1cnNvcigwKSwKICAgICAgLy8vICAgICAgdGFyZ2V0Q3Vyc29yKDApLAogICAgICBjdXJzb3IxKDApLAogICAgICBjdXJzb3IyKDApLAogICAgICBkYXRhKDApLAogICAgICBkYXRhSXNPd25lZChGQUxTRSkKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBjb25zdHJ1Y3RGcm9tUnVsZXMocnVsZXMsIHN0YXR1cyk7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKQogIDogQ29sbGF0b3IoY29sbGF0aW9uU3RyZW5ndGgsIE5vcm1hbGl6ZXI6Ok5PX09QKSwKICAgIGlzT3Zlcklnbm9yZShGQUxTRSksCiAgICBtUGF0dGVybigwKSwKICAgIC8vICAgIHNvdXJjZUN1cnNvcigwKSwKICAgIC8vICAgIHRhcmdldEN1cnNvcigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgIGRhdGEoMCksCiAgICBkYXRhSXNPd25lZChGQUxTRSkKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0cnVjdEZyb21SdWxlcyhydWxlcywgc3RhdHVzKTsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0ICBVbmljb2RlU3RyaW5nJiAgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykKICA6IENvbGxhdG9yKFRFUlRJQVJZLCBkZWNvbXBvc2l0aW9uTW9kZSksCiAgICBpc092ZXJJZ25vcmUoRkFMU0UpLAogICAgbVBhdHRlcm4oMCksCiAgICAvLyAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAvLyAgICB0YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICBkYXRhKDApLAogICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgIHJldHVybjsKICAgIH0KICAKICBjb25zdHJ1Y3RGcm9tUnVsZXMocnVsZXMsIHN0YXR1cyk7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykKICA6IENvbGxhdG9yKGNvbGxhdGlvblN0cmVuZ3RoLCBkZWNvbXBvc2l0aW9uTW9kZSksCiAgICAgIGlzT3Zlcklnbm9yZShGQUxTRSksCiAgICAgIG1QYXR0ZXJuKDApLAogICAgLy8gICAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAvL3RhcmdldEN1cnNvcigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgICAgZGF0YSgwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgY29uc3RydWN0RnJvbVJ1bGVzKHJ1bGVzLCBzdGF0dXMpOwp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tUnVsZXMoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIC8vIENvbnN0cnVjdCB0aGlzIGNvbGxhdG9yJ3MgcnVsZXNldCBmcm9tIGl0cyBzdHJpbmcgcmVwcmVzZW50YXRpb24KICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKHJ1bGVzLmlzQm9ndXMoKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IDA7CiAgICB9CgogICAgaXNPdmVySWdub3JlID0gRkFMU0U7CiAgICBzZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOwoKICAgIGRhdGEgPSBuZXcgVGFibGVDb2xsYXRpb25EYXRhOwogICAgaWYgKGRhdGEtPmlzQm9ndXMoKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBXZSBjb25zdHJ1Y3RlZCB0aGUgZGF0YSB1c2luZyB0aGUgYnVpbGQgbWV0aG9kLCBzbyB3ZSBvd24gaXQuCiAgICBkYXRhSXNPd25lZCA9IFRSVUU7CgogICAgLy8gTm93IHRoYXQgd2UndmUgZ290IGFsbCB0aGUgYnVmZmVycyBhbGxvY2F0ZWQsIGRvIHRoZSBhY3R1YWwgd29yawogICAgbVBhdHRlcm4gPSAwOwogICAgYnVpbGQocnVsZXMsIHN0YXR1cyk7Cn0KCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbnN0cnVjdEZyb21GaWxlKGNvbnN0IGNoYXIqIGZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICAvLyBUaGlzIG1ldGhvZCB0cmllcyB0byByZWFkIGluIGEgZmxhdHRlbmVkIFJ1bGVCYXNlZENvbGxhdG9yIHRoYXQKICAgIC8vIGhhcyBiZWVuIHByZXZpb3VzbHkgc3RyZWFtZWQgb3V0IHVzaW5nIHRoZSBzdHJlYW1PdXQoKSBtZXRob2QuCiAgICAvLyBUaGUgJ2ZpbGVOYW1lJyBwYXJhbWV0ZXIgc2hvdWxkIGNvbnRhaW4gYSBmdWxsIHBhdGhuYW1lIHZhbGlkIG9uCiAgICAvLyB0aGUgbG9jYWwgZW52aXJvbm1lbnQuCgogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IDA7CiAgICB9CgogICAgbVBhdHRlcm4gPSAwOwogICAgaXNPdmVySWdub3JlID0gRkFMU0U7CiAgICBzZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOyAvLyBUaGlzIGlzIHRoZSBkZWZhdWx0IHN0cmVuZ3RoCgogICAgRmlsZVN0cmVhbSogaWZzID0gVF9GaWxlU3RyZWFtX29wZW4oZmlsZU5hbWUsICJyYiIpOwogICAgaWYgKGlmcyA9PSAwKSB7CiAgICAgICAgc3RhdHVzID0gVV9GSUxFX0FDQ0VTU19FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gVGhlIHN0cmVhbUluIGZ1bmN0aW9uIGRvZXMgdGhlIGFjdHVhbCB3b3JrIGhlcmUuLi4KICAgIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbUluKHRoaXMsIGlmcyk7CgogICAgaWYgKCFUX0ZpbGVTdHJlYW1fZXJyb3IoaWZzKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICB9CiAgICBlbHNlIGlmIChkYXRhICYmIGRhdGEtPmlzQm9ndXMoKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHN0YXR1cyA9IFVfTUlTU0lOR19SRVNPVVJDRV9FUlJPUjsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgIH0KCiNpZmRlZiBDT0xMREVCVUcKICAgIGZwcmludGYoc3RkZXJyLCAiYmluYXJ5IHJlYWQgJXMgc2l6ZSAlZCwgJXNcbiIsIGZpbGVOYW1lLCBUX0ZpbGVTdHJlYW1fc2l6ZShpZnMpLCB1X2Vycm9yTmFtZShzdGF0dXMpKTsKI2VuZGlmCgogICAgLy8gV2UgY29uc3RydWN0ZWQgdGhlIGRhdGEgd2hlbiBzdHJlYW1pbmcgaXQgaW4sIHNvIHdlIG93biBpdAogICAgZGF0YUlzT3duZWQgPSBUUlVFOwoKICAgIFRfRmlsZVN0cmVhbV9jbG9zZShpZnMpOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoICAgY29uc3QgTG9jYWxlJiBkZXNpcmVkTG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKICAgIDogQ29sbGF0b3IoKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpLAogICAgICBkYXRhKDApLAogICAgICAvLyAgICAgIHNvdXJjZUN1cnNvcigwKSwKICAgICAgLy90YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICAgIG1QYXR0ZXJuKDApCnsKCgogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgcmV0dXJuOwogICAgfQogIAogIC8vIFRyeSB0byBsb2FkLCBpbiBvcmRlcjoKICAvLyAxLiBUaGUgZGVzaXJlZCBsb2NhbGUncyBjb2xsYXRpb24uCiAgLy8gMi4gQSBmYWxsYmFjayBvZiB0aGUgZGVzaXJlZCBsb2NhbGUuCiAgLy8gMy4gVGhlIGRlZmF1bHQgbG9jYWxlJ3MgY29sbGF0aW9uLgogIC8vIDQuIEEgZmFsbGJhY2sgb2YgdGhlIGRlZmF1bHQgbG9jYWxlLgogIC8vIDUuIFRoZSBkZWZhdWx0IGNvbGxhdGlvbiBydWxlcywgd2hpY2ggY29udGFpbnMgZW5fVVMgY29sbGF0aW9uIHJ1bGVzLgoKICAvLyBUbyByZWl0ZXJhdGUsIHdlIHRyeToKICAvLyBTcGVjaWZpYzoKICAvLyAgbGFuZ3VhZ2UrY291bnRyeSt2YXJpYW50CiAgLy8gIGxhbmd1YWdlK2NvdW50cnkKICAvLyAgbGFuZ3VhZ2UKICAvLyBEZWZhdWx0OgogIC8vICBsYW5ndWFnZStjb3VudHJ5K3ZhcmlhbnQKICAvLyAgbGFuZ3VhZ2UrY291bnRyeQogIC8vICBsYW5ndWFnZQogIC8vIFJvb3Q6IChha2EgREVGQVVMVFJVTEVTKQoKICBVbmljb2RlU3RyaW5nIGxvY2FsZU5hbWU7CiAgZGVzaXJlZExvY2FsZS5nZXROYW1lKGxvY2FsZU5hbWUpOwogIGVudW0geyBlVHJ5RGVmYXVsdExvY2FsZSwgZVRyeURlZmF1bHRDb2xsYXRpb24sIGVEb25lIH0gbmV4dCA9IGVUcnlEZWZhdWx0TG9jYWxlOwogICAgCiAgZm9yICg7OykKICAgIHsKICAgICAgaWYgKGxvY2FsZU5hbWUubGVuZ3RoKCkgPT0gMCkKICAgIHsKICAgICAgaWYgKG5leHQgPT0gZURvbmUpCiAgICAgICAgICAgIHsKICAgICAgICAgIC8vIFdlJ3ZlIGZhaWxlZCB0byBsb2FkIGEgbG9jYWxlLCBidXQgc2hvdWxkIG5ldmVyIHJldHVybiBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1IKICAgICAgICAgIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwoKICAgICAgICAgIGNvbnN0cnVjdEZyb21SdWxlcyhSdWxlQmFzZWRDb2xsYXRvcjo6REVGQVVMVFJVTEVTLCBpbnRTdGF0dXMpOwogICAgICAgICAgaWYgKGludFN0YXR1cyA9PSBVX1pFUk9fRVJST1IpCiAgICAgICAgewogICAgICAgICAgc3RhdHVzID0gVV9VU0lOR19ERUZBVUxUX0VSUk9SOwogICAgICAgIH0KICAgICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICBzdGF0dXMgPSBpbnRTdGF0dXM7ICAgICAvLyBidWJibGUgYmFjawogICAgICAgIH0KCiAgICAgICAgICBpZiAoc3RhdHVzID09IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1IpCiAgICAgICAgewogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCgkgIC8vIHNybCB3cml0ZSBvdXQgZGVmYXVsdC5jb2wKCSAgewoJICAgIFVuaWNvZGVTdHJpbmcgZGVmTG9jYWxlTmFtZSA9IFVuaWNvZGVTdHJpbmcoUmVzb3VyY2VCdW5kbGU6OmtEZWZhdWx0RmlsZW5hbWUsIiIpOyAKCSAgICBjaGFyICpiaW5hcnlGaWxlUGF0aCA9IGNyZWF0ZVBhdGhOYW1lKFVuaWNvZGVTdHJpbmcoTG9jYWxlOjpnZXREYXRhRGlyZWN0b3J5KCksIiIpLCAKCQkJCQkJICBkZWZMb2NhbGVOYW1lLCBVbmljb2RlU3RyaW5nKGtGaWxlbmFtZVN1ZmZpeCwiIikpOwoJICAgIGJvb2xfdCBvayA9IHdyaXRlVG9GaWxlKGJpbmFyeUZpbGVQYXRoKTsKCSAgICBkZWxldGUgW10gYmluYXJ5RmlsZVBhdGg7CiNpZmRlZiBDT0xMREVCVUcKCSAgICBjZXJyIDw8IGRlZkxvY2FsZU5hbWUgPDwgIiBbZGVmYXVsdF0gYmluYXJ5IHdyaXRlICIgPDwgKG9rPyAiT0siIDogIkZhaWxlZCIpIDw8IGVuZGw7CiNlbmRpZgoJICB9CgogICAgICAgICAgZGF0YS0+ZGVzaXJlZExvY2FsZSA9IGRlc2lyZWRMb2NhbGU7CiAgICAgICAgICBkZXNpcmVkTG9jYWxlLmdldE5hbWUobG9jYWxlTmFtZSk7CiAgICAgICAgICBkYXRhLT5yZWFsTG9jYWxlTmFtZSA9IGxvY2FsZU5hbWU7CiAgICAgICAgICBhZGRUb0NhY2hlKGxvY2FsZU5hbWUpOwoKICAgICAgICAgIHNldERlY29tcG9zaXRpb24oTm9ybWFsaXplcjo6Tk9fT1ApOwoKICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzID0gZ2V0UnVsZXMoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAvLyBXZSd2ZSBleGhhdXN0ZWQgb3VyIGluaGVyaXRhbmNlIGF0dGVtcHRzIHdpdGggdGhpcyBsb2NhbGUuCiAgICAgIC8vIFRyeSB0aGUgbmV4dCBzdGVwLgogICAgICBzd2l0Y2ggKG5leHQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBlVHJ5RGVmYXVsdExvY2FsZToKICAgICAgICAgIHN0YXR1cyA9IFVfVVNJTkdfREVGQVVMVF9FUlJPUjsKICAgICAgICAgIExvY2FsZTo6Z2V0RGVmYXVsdCgpLmdldE5hbWUobG9jYWxlTmFtZSk7CiAgICAgICAgICBuZXh0ID0gZVRyeURlZmF1bHRDb2xsYXRpb247CiAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgZVRyeURlZmF1bHRDb2xsYXRpb246CiAgICAgICAgICAvLyBUaGVyZSBpcyBubyBkaXN0aW5jdGlvbiBiZXR3ZWVuIHRoaXMgY29uZGl0aW9uIG9mCiAgICAgICAgICAvLyB1c2luZyBhIGRlZmF1bHQgY29sbGF0aW9uIG9iamVjdCBhbmQgdGhlIGNvbmRpdGlvbiBvZgogICAgICAgICAgLy8gdXNpbmcgYSBkZWZhdWx0IGxvY2FsZSB0byBnZXQgYSBjb2xsYXRpb24gb2JqZWN0IGN1cnJlbnRseS4KICAgICAgICAgIC8vIFRoYXQgaXMsIHRoZSBjYWxsZXIgY2FuJ3QgZGlzdGluZ3Vpc2ggYmFzZWQgb24gVUVycm9yQ29kZS4KICAgICAgICAgIHN0YXR1cyA9IFVfVVNJTkdfREVGQVVMVF9FUlJPUjsKICAgICAgICAgIGxvY2FsZU5hbWUgPSBSZXNvdXJjZUJ1bmRsZTo6a0RlZmF1bHRGaWxlbmFtZTsKICAgICAgICAgIG5leHQgPSBlRG9uZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgLy8gRmlyc3QgdHJ5IHRvIGxvYWQgdGhlIGNvbGxhdGlvbiBmcm9tIHRoZSBpbi1tZW1vcnkgc3RhdGljIGNhY2hlLgogICAgICAvLyBOb3RlIHRoYXQgYWxsIG9mIHRoZSBjYWNoaW5nIGxvZ2ljIGlzIGhhbmRsZWQgaGVyZSwgYW5kIGluIHRoZQogICAgICAvLyBjYWxsIHRvIFJ1bGVCYXNlZENvbGxhdG9yOjphZGRUb0NhY2hlLCBiZWxvdy4KICAgICAgVUVycm9yQ29kZSBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CgogICAgICBjb25zdHJ1Y3RGcm9tQ2FjaGUobG9jYWxlTmFtZSwgaW50U3RhdHVzKTsKICAgICAgaWYgKFVfU1VDQ0VTUyhpbnRTdGF0dXMpKQogICAgewogICAgICBicmVhazsgLy8gRG9uZSEKICAgIH0KCiAgICAgIC8vIFRoZSBjb2xsYXRpb24gd2Ugd2FudCBpcyBub3QgaW4gdGhlIGNhY2hlLiAgVGhlIHNlY29uZCB0aGluZwogICAgICAvLyB0byB0cnkgaXMgbG9hZGluZyBmcm9tIGEgZmlsZSwgZWl0aGVyIGJpbmFyeSBvciBBU0NJSS4gIFNvOgogICAgICAvLyBUcnkgdG8gbG9hZCB0aGUgbG9jYWxlJ3MgY29sbGF0aW9uIGRhdGEuICBUaGlzIHdpbGwgdHJ5IHRvIGxvYWQKICAgICAgLy8gYSBiaW5hcnkgY29sbGF0aW9uIGZpbGUsIG9yIGlmIHRoYXQgaXMgdW5hdmFpbGFibGUsIGl0IHdpbGwgZ28KICAgICAgLy8gdG8gdGhlIHRleHQgcmVzb3VyY2UgYnVuZGxlIGZpbGUgKHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgbmFtZSkKICAgICAgLy8gYW5kIHRyeSB0byBnZXQgdGhlIGNvbGxhdGlvbiB0YWJsZSB0aGVyZS4KICAgICAgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgICBjb25zdHJ1Y3RGcm9tRmlsZShkZXNpcmVkTG9jYWxlLCBsb2NhbGVOYW1lLCBUUlVFLCBpbnRTdGF0dXMpOwogICAgICBpZiAoVV9TVUNDRVNTKGludFN0YXR1cykpCiAgICAgICAgewogICAgICAvLyBJZiB3ZSBzdWNjZWVkZWQgaW4gbG9hZGluZyB0aGUgY29sbGF0aW9uIGZyb20gYSBmaWxlLCBub3cgaXMgdGhlCiAgICAgIC8vIHRpbWUgdG8gYWRkIGl0IHRvIHRoZSBpbi1tZW1vcnkgY2FjaGUuICBXZSByZWNvcmQgdGhlIHJlYWwKICAgICAgLy8gbG9jYXRpb24gYXQgd2hpY2ggdGhlIGNvbGxhdGlvbiBkYXRhIHdhcyBmb3VuZCwgc28gd2UgY2FuIHJlbG9hZAogICAgICAvLyB0aGUgcnVsZSB0YWJsZSBxdWlja2x5LCBpZiBpdCBpcyByZXF1ZXN0ZWQsIGluIHRoZSBmdXR1cmUuCiAgICAgIC8vIFNlZSBnZXRSdWxlcygpLgogICAgICBkYXRhLT5kZXNpcmVkTG9jYWxlID0gZGVzaXJlZExvY2FsZTsKICAgICAgZGF0YS0+cmVhbExvY2FsZU5hbWUgPSBsb2NhbGVOYW1lOwogICAgICBhZGRUb0NhY2hlKGxvY2FsZU5hbWUpOwoKICAgICAgc2V0RGVjb21wb3NpdGlvbihOb3JtYWxpemVyOjpOT19PUCk7CiAgICAgIGJyZWFrOyAvLyBEb25lIQogICAgICAgIH0KICAgICAgaWYgKGludFN0YXR1cyA9PSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SKQogICAgewogICAgICBzdGF0dXMgPSBpbnRTdGF0dXM7CiAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAvLyBIYXZpbmcgZmFpbGVkLCBjaG9wIG9mZiB0aGUgZW5kIG9mIHRoZSBsb2NhbGUgbmFtZSwgbWFraW5nCiAgICAgIC8vIGl0IGxlc3Mgc3BlY2lmaWMsIGFuZCB0cnkgYWdhaW4uICBJbmRpY2F0ZSB0aGUgdXNlIG9mIGEKICAgICAgLy8gZmFsbGJhY2sgbG9jYWxlLCB1bmxlc3Mgd2UndmUgYWxyZWFkeSBmYWxsZW4gdGhyb3VnaCB0bwogICAgICAvLyBhIGRlZmF1bHQgbG9jYWxlIC0tIHRoZW4gbGVhdmUgdGhlIHN0YXR1cyBhcyBpcy4KICAgICAgaWYgKHN0YXR1cyA9PSBVX1pFUk9fRVJST1IpCiAgICB7CiAgICAgIHN0YXR1cyA9IFVfVVNJTkdfRkFMTEJBQ0tfRVJST1I7CiAgICB9CgogICAgICBjaG9wTG9jYWxlKGxvY2FsZU5hbWUpOwogICAgfQp9Cgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tRmlsZSggICBjb25zdCBMb2NhbGUmICAgICAgICAgICBsb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIGxvY2FsZUZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sX3QgICAgICAgICAgICAgICAgICB0cnlCaW5hcnlGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgICAgICAgICAgc3RhdHVzKQp7CiAgLy8gY29uc3RydWN0RnJvbUZpbGUgY3JlYXRlcyBhIGNvbGxhdGlvbiBvYmplY3QgYnkgcmVhZGluZyBmcm9tIGEKICAvLyBmaWxlLiAgSXQgZG9lcyBub3QgZW1wbG95IHRoZSB1c3VhbCBGSUxFIHNlYXJjaCBtZWNoYW5pc20gd2l0aAogIC8vIGxvY2FsZXMsIGRlZmF1bHQgbG9jYWxlcywgYW5kIGJhc2UgbG9jYWxlcy4gIEluc3RlYWQsIGl0IHRyaWVzIHRvCiAgLy8gbG9vayBvbmx5IGluIGZpbGVzIHdpdGggdGhlIGdpdmVuIGxvY2FsRmlsZU5hbWUuICBJdCBkb2VzLAogIC8vIGhvd2V2ZXIsIGVtcGxveSB0aGUgTE9DQUxFIHNlYXJjaCBtZWNoYW5pc20uCiAgCiAgLy8gVGhpcyBtZXRob2QgbWFpbnRhaW5zIHRoZSBiaW5hcnkgY29sbGF0aW9uIGZpbGVzLiAgSWYgYSBjb2xsYXRpb24KICAvLyBpcyBub3QgcHJlc2VudCBpbiBiaW5hcnkgZm9ybSwgYnV0IGlzIHByZXNlbnQgaW4gdGV4dCBmb3JtIChpbiBhCiAgLy8gcmVzb3VyY2UgYnVuZGxlIGZpbGUpLCBpdCB3aWxsIGJlIGxvYWRlZCBpbiB0ZXh0IGZvcm0sIGFuZCB0aGVuCiAgLy8gd3JpdHRlbiB0byBkaXNrLgogIAogIC8vIElmIHRyeUJpbmFyeUZpbGUgaXMgdHJ1ZSwgdGhlbiB0cnkgdG8gbG9hZCBmcm9tIHRoZSBiaW5hcnkgZmlsZSBmaXJzdC4KCiAgaWYoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgIHJldHVybjsKICB9CiAgCiAgaWYoZGF0YUlzT3duZWQpIHsKICAgIGRlbGV0ZSBkYXRhOwogICAgZGF0YSA9IDA7CiAgfQogIAogIGNoYXIgKmJpbmFyeUZpbGVQYXRoID0gY3JlYXRlUGF0aE5hbWUoVW5pY29kZVN0cmluZyhMb2NhbGU6OmdldERhdGFEaXJlY3RvcnkoKSwiIiksIAoJCQkJCWxvY2FsZUZpbGVOYW1lLCBVbmljb2RlU3RyaW5nKGtGaWxlbmFtZVN1ZmZpeCwiIikpOwogIAogIGlmKHRyeUJpbmFyeUZpbGUpIHsKICAgIC8vIFRyeSB0byBsb2FkIHVwIHRoZSBjb2xsYXRpb24gZnJvbSBhIGJpbmFyeSBmaWxlIGZpcnN0CiAgICBjb25zdHJ1Y3RGcm9tRmlsZShiaW5hcnlGaWxlUGF0aCwgc3RhdHVzKTsKI2lmZGVmIENPTExERUJVRwogICAgY2VyciA8PCBsb2NhbGVGaWxlTmFtZSAgPDwga0ZpbGVuYW1lU3VmZml4IDw8ICIgYmluYXJ5IGxvYWQgIiA8PCB1X2Vycm9yTmFtZShzdGF0dXMpIDw8IGVuZGw7CiNlbmRpZgogICAgaWYoVV9TVUNDRVNTKHN0YXR1cykgfHwgc3RhdHVzID09IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1IpIAogICAgICB7CiAgICAgICAgICBkZWxldGUgW10gYmluYXJ5RmlsZVBhdGg7CiAgICAgICAgICByZXR1cm47CiAgICAgIH0KICAgIH0KCiAgLy8gTm93IHRyeSB0byBsb2FkIGl0IHVwIGZyb20gYSByZXNvdXJjZSBidW5kbGUgdGV4dCBzb3VyY2UgZmlsZQogIFVuaWNvZGVTdHJpbmcgZGF0YURpciA9IFVuaWNvZGVTdHJpbmcoTG9jYWxlOjpnZXREYXRhRGlyZWN0b3J5KCksIiIpOwoKICBSZXNvdXJjZUJ1bmRsZSBidW5kbGUoZGF0YURpciwgbG9jYWxlRmlsZU5hbWUsIHN0YXR1cyk7CgogIC8vIGlmIHRoZXJlIGlzIG5vIHJlc291cmNlIGJ1bmRsZSBmaWxlIGZvciB0aGUgZ2l2ZSBsb2NhbGUsIGJyZWFrIG91dAogIGlmKFVfRkFJTFVSRShzdGF0dXMpKQogIHsKICAgICAgZGVsZXRlIFtdIGJpbmFyeUZpbGVQYXRoOwogICAgICByZXR1cm47CiAgfQoKI2lmZGVmIENPTExERUJVRwogIGNlcnIgPDwgbG9jYWxlRmlsZU5hbWUgPDwgIiBhc2NpaSBsb2FkICIgPDwgdV9lcnJvck5hbWUoc3RhdHVzKSA8PCBlbmRsOwojZW5kaWYKCiAgLy8gY2hlY2sgYW5kIHNlZSBpZiB0aGlzIHJlc291cmNlIGJ1bmRsZSBjb250YWlucyBjb2xsYXRpb24gZGF0YQogIAogIFVuaWNvZGVTdHJpbmcgY29sU3RyaW5nOwogIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwoKICBidW5kbGUuZ2V0U3RyaW5nKCJDb2xsYXRpb25FbGVtZW50cyIsIGNvbFN0cmluZywgaW50U3RhdHVzKTsKICBpZihjb2xTdHJpbmcuaXNCb2d1cygpKSB7CiAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgZGVsZXRlIFtdIGJpbmFyeUZpbGVQYXRoOwogICAgcmV0dXJuOwogIH0KCiAgLy8gaWYgdGhpcyBidW5kbGUgZG9lc24ndCBjb250YWluIGNvbGxhdGlvbiBkYXRhLCBicmVhayBvdXQKICBpZihVX0ZBSUxVUkUoaW50U3RhdHVzKSkgewogICAgc3RhdHVzID0gVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SOwogICAgZGVsZXRlIFtdIGJpbmFyeUZpbGVQYXRoOwogICAgcmV0dXJuOwogIH0KCiAgLy8gSGF2aW5nIGxvYWRlZCB0aGUgY29sbGF0aW9uIGZyb20gdGhlIHJlc291cmNlIGJ1bmRsZSB0ZXh0IGZpbGUsCiAgLy8gbm93IHJldHJpZXZlIHRoZSBDb2xsYXRpb25FbGVtZW50cyB0YWdnZWQgZGF0YSwgbWVyZ2VkIHdpdGggdGhlCiAgLy8gZGVmYXVsdCBydWxlcy4gIElmIHRoYXQgZmFpbHMsIHVzZSB0aGUgZGVmYXVsdCBydWxlcyBhbG9uZS4KCiAgY29sU3RyaW5nLmluc2VydCgwLCBERUZBVUxUUlVMRVMpOwogIGlmKGNvbFN0cmluZy5pc0JvZ3VzKCkpIHsKICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICBkZWxldGUgW10gYmluYXJ5RmlsZVBhdGg7CiAgICByZXR1cm47CiAgfQogICAgCiAgY29uc3RydWN0RnJvbVJ1bGVzKGNvbFN0cmluZywgaW50U3RhdHVzKTsKICBpZihpbnRTdGF0dXMgPT0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUikgewogICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgIGRlbGV0ZSBbXSBiaW5hcnlGaWxlUGF0aDsKICAgIHJldHVybjsKICB9CiAgCiAgaWYoaW50U3RhdHVzICE9IFVfWkVST19FUlJPUikgIHsKICAgIHN0YXR1cyA9IFVfVVNJTkdfREVGQVVMVF9FUlJPUjsKICAgICAgCiAgICAvLyBwcmVkZWZpbmVkIHRhYmxlcyBzaG91bGQgY29udGFpbiBjb3JyZWN0IGdyYW1tYXIKICAgIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgIGNvbnN0cnVjdEZyb21SdWxlcyhERUZBVUxUUlVMRVMsIGludFN0YXR1cyk7CiAgICBpZihpbnRTdGF0dXMgIT0gVV9aRVJPX0VSUk9SKSB7CiAgICAgIHN0YXR1cyA9IGludFN0YXR1czsKICAgIH0KICB9IAogIAojaWZkZWYgQ09MTERFQlVHCiAgY2VyciA8PCBsb2NhbGVGaWxlTmFtZSA8PCAiIGFzY2lpIGxvYWQgIiA8PCAoVV9TVUNDRVNTKHN0YXR1cykgPyAiT0siIDogIkZhaWxlZCIpIDw8ICIgLSB0cnk9ICIgPDwgKHRyeUJpbmFyeUZpbGU/InRydWUiOiJmYWxzZSIpIDw8IGVuZGw7CiNlbmRpZgogIAogIGlmKFVfU1VDQ0VTUyhzdGF0dXMpICYmIHRyeUJpbmFyeUZpbGUpIHsKICAgIC8vIElmIHdlIGdldCBhIFJ1bGVCYXNlZENvbGxhdG9yIHJlc3VsdCwgZXZlbiBpZiBpdCBpcyBkZXJpdmVkCiAgICAvLyBmcm9tIGEgZGVmYXVsdCBvciBhIGZhbGxiYWNrLCB0aGVuIHdlIHdyaXRlIGl0IG91dCBhcyBhCiAgICAvLyBiaW5hcnkgZmlsZSB0byB0aGUgZGlzay4gIFRoZSBuZXh0IHRpbWUgdGhlIHN5c3RlbSB3YW50cyB0bwogICAgLy8gZ2V0IHRoaXMgY29sbGF0aW9uLCBpdCB3aWxsIGxvYWQgdXAgdmVyeSBxdWlja2x5IGZyb20gdGhlCiAgICAvLyBiaW5hcnkgZmlsZS4KICAgIGJvb2xfdCBvayA9IHdyaXRlVG9GaWxlKGJpbmFyeUZpbGVQYXRoKTsKICAgIGRlbGV0ZSBbXSBiaW5hcnlGaWxlUGF0aDsKI2lmZGVmIENPTExERUJVRwogICAgY2VyciA8PCBsb2NhbGVGaWxlTmFtZSA8PCAiIGJpbmFyeSB3cml0ZSAiIDw8IChvaz8gIk9LIiA6ICJGYWlsZWQiKSA8PCBlbmRsOwojZW5kaWYKICB9Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjp+UnVsZUJhc2VkQ29sbGF0b3IoKQp7CiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICB9CgogICAgZGF0YSA9IDA7CgogICAgLy8gICAgZGVsZXRlIHNvdXJjZUN1cnNvcjsKICAgIC8vICAgIHNvdXJjZUN1cnNvciA9IDA7CgogICAgLy8gICAgZGVsZXRlIHRhcmdldEN1cnNvcjsKICAgIC8vICAgIHRhcmdldEN1cnNvciA9IDA7CgogICAgaWYgKGN1cnNvcjEgIT0gTlVMTCkgewogICAgICAgIGRlbGV0ZSBjdXJzb3IxOwogICAgICAgIGN1cnNvcjEgPSAwOwogICAgfQogICAgaWYgKGN1cnNvcjIgIT0gTlVMTCkgewogICAgICAgIGRlbGV0ZSBjdXJzb3IyOwogICAgICAgIGN1cnNvcjIgPSAwOwogICAgfQoKICAgIGRlbGV0ZSBtUGF0dGVybjsKICAgIG1QYXR0ZXJuID0gMDsKfQoKQ29sbGF0b3IqClJ1bGVCYXNlZENvbGxhdG9yOjpjbG9uZSgpIGNvbnN0CnsKICAgIHJldHVybiBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoKnRoaXMpOwp9CgovLyBDcmVhdGUgYSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Igb2JqZWN0IHRoYXQgd2lsbCBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cwovLyBpbiBhIHN0cmluZywgdXNpbmcgdGhlIGNvbGxhdGlvbiBydWxlcyBkZWZpbmVkIGluIHRoaXMgUnVsZUJhc2VkQ29sbGF0b3IKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKgpSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSkgY29uc3QKewogICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgKm5ld0N1cnNvciA9IDA7CgogICAgbmV3Q3Vyc29yID0gbmV3IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihzb3VyY2UsIHRoaXMsIHN0YXR1cyk7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIG5ld0N1cnNvcjsKfQoKLy8gQ3JlYXRlIGEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIG9iamVjdCB0aGF0IHdpbGwgaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMKLy8gaW4gYSBzdHJpbmcsIHVzaW5nIHRoZSBjb2xsYXRpb24gcnVsZXMgZGVmaW5lZCBpbiB0aGlzIFJ1bGVCYXNlZENvbGxhdG9yCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcioKUnVsZUJhc2VkQ29sbGF0b3I6OmNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgc291cmNlKSBjb25zdAp7CiAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciAqbmV3Q3Vyc29yID0gMDsKCiAgICBuZXdDdXJzb3IgPSBuZXcgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKHNvdXJjZSwgdGhpcywgc3RhdHVzKTsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gbmV3Q3Vyc29yOwp9CgovLyBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBjb2xsYXRvcidzIHJ1bGVzLgovLyBUaGUgc3RyaW5nIGNhbiBsYXRlciBiZSBwYXNzZWQgdG8gdGhlIGNvbnN0cnVjdG9yIHRoYXQgdGFrZXMgYQovLyBVbmljb2RlU3RyaW5nIGFyZ3VtZW50LCB3aGljaCB3aWxsIGNvbnN0cnVjdCBhIGNvbGxhdG9yIHRoYXQncwovLyBmdW5jdGlvbmFsbHkgaWRlbnRpY2FsIHRvIHRoaXMgb25lLgovLyBZb3UgY2FuIGFsc28gYWxsb3cgdXNlcnMgdG8gZWRpdCB0aGUgc3RyaW5nIGluIG9yZGVyIHRvIGNoYW5nZQovLyB0aGUgY29sbGF0aW9uIGRhdGEsIG9yIHlvdSBjYW4gcHJpbnQgaXQgb3V0IGZvciBpbnNwZWN0aW9uLCBvciB3aGF0ZXZlci4KCmNvbnN0IFVuaWNvZGVTdHJpbmcmClJ1bGVCYXNlZENvbGxhdG9yOjpnZXRSdWxlcygpIGNvbnN0CnsKICAgIGlmIChtUGF0dGVybiAhPSAwKQogICAgewogICAgICAgIE1lcmdlQ29sbGF0aW9uKiYgbm9uQ29uc3RNUGF0dGVybiA9ICooTWVyZ2VDb2xsYXRpb24qKikmbVBhdHRlcm47CiAgICAgICAgbVBhdHRlcm4tPmVtaXRQYXR0ZXJuKGRhdGEtPnJ1bGVUYWJsZSk7CiAgICAgICAgZGF0YS0+aXNSdWxlVGFibGVMb2FkZWQgPSBUUlVFOwogICAgICAgIGRlbGV0ZSBub25Db25zdE1QYXR0ZXJuOwogICAgICAgIG5vbkNvbnN0TVBhdHRlcm4gPSAwOwogICAgfQogICAgZWxzZSBpZiAoIWRhdGEtPmlzUnVsZVRhYmxlTG9hZGVkKQogICAgewogICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgdGhlIGNhbGxlciB3YW50cyB0aGUgcnVsZXMsIGJ1dCB0aGUgcnVsZSB0YWJsZSBkYXRhCiAgICAgICAgLy8gaXMgbm90IGxvYWRlZC4gIEZ1cnRoZXJtb3JlLCB0aGVyZSBpcyBubyBtUGF0dGVybiBvYmplY3QgdG8gbG9hZAogICAgICAgIC8vIHRoZSBydWxlcyBmcm9tLiAgVGhlcmVmb3JlLCB3ZSBmZXRjaCB0aGUgcnVsZXMgb2ZmIHRoZSBkaXNrLgogICAgICAgIC8vIE5vdGljZSB0aGF0IHdlIHBhc3MgaW4gYSB0cnlCaW5hcnlGaWxlIHZhbHVlIG9mIEZBTFNFLCBzaW5jZQogICAgICAgIC8vIGJ5IGRlc2lnbiB0aGUgYmluYXJ5IGZpbGUgaGFzIE5PIHJ1bGVzIGluIGl0IQogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yIHRlbXA7CiAgICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgdGVtcC5jb25zdHJ1Y3RGcm9tRmlsZShkYXRhLT5kZXNpcmVkTG9jYWxlLCBkYXRhLT5yZWFsTG9jYWxlTmFtZSwgRkFMU0UsIHN0YXR1cyk7CgogICAgICAgIC8vIFdlIG11c3QgY2hlY2sgdGhhdCBtUGF0dGVybiBpcyBub256ZXJvIGhlcmUsIG9yIHdlIHJ1biB0aGUgcmlzawogICAgICAgIC8vIG9mIGFuIGluZmluaXRlIGxvb3AuCiAgICAgICAgaWYgKFVfU1VDQ0VTUyhzdGF0dXMpICYmIHRlbXAubVBhdHRlcm4gIT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIGRhdGEtPnJ1bGVUYWJsZSA9IHRlbXAuZ2V0UnVsZXMoKTsKICAgICAgICAgICAgZGF0YS0+aXNSdWxlVGFibGVMb2FkZWQgPSBUUlVFOwojaWZkZWYgX0RFQlVHCi8vICAgICAgICAgICAgICAvLyB0aGUgZm9sbG93aW5nIGlzIHVzZWZ1bCBmb3Igc3BlY2lmaWMgZGVidWdnaW5nIHB1cnBvc2VzCi8vICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBuYW1lOwovLyAgICAgICAgICAgICAgIGNlcnIgPDwgIlRhYmxlIGNvbGxhdGlvbiBydWxlcyBsb2FkZWQgZHluYW1pY2FsbHkgZm9yICIKLy8gICAgICAgICAgICAgICAgICAgPDwgZGF0YS0+ZGVzaXJlZExvY2FsZS5nZXROYW1lKG5hbWUpCi8vICAgICAgICAgICAgICAgICAgIDw8ICIgYXQgIgovLyAgICAgICAgICAgICAgICAgICA8PCBkYXRhLT5yZWFsTG9jYWxlTmFtZQovLyAgICAgICAgICAgICAgICAgICA8PCAiLCAiIDw8IGRlYyA8PCBkYXRhLT5ydWxlVGFibGUuc2l6ZSgpIDw8ICIgY2hhcmFjdGVycyIKLy8gICAgICAgICAgICAgICAgICAgPDwgZW5kbDsKI2VuZGlmCiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiNpZmRlZiBfREVCVUcKLy8gICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgbmFtZTsKLy8gICAgICAgICAgICAgIGNlcnIgPDwgIlVuYWJsZSB0byBsb2FkIHRhYmxlIGNvbGxhdGlvbiBydWxlcyBkeW5hbWljYWxseSBmb3IgIgovLyAgICAgICAgICAgICAgICAgIDw8IGRhdGEtPmRlc2lyZWRMb2NhbGUuZ2V0TmFtZShuYW1lKQovLyAgICAgICAgICAgICAgICAgIDw8ICIgYXQgIgovLyAgICAgICAgICAgICAgICAgIDw8IGRhdGEtPnJlYWxMb2NhbGVOYW1lCi8vICAgICAgICAgICAgICAgICAgPDwgZW5kbDsKLy8gICAgICAgICAgICAgIGNlcnIgPDwgIlN0YXR1cyAiIDw8IHVfZXJyb3JOYW1lKHN0YXR1cykgPDwgIiwgbVBhdHRlcm4gIiA8PCB0ZW1wLm1QYXR0ZXJuIDw8IGVuZGw7CiNlbmRpZgoJICAgIC8qIFNSTCBoYXZlIHRvIGFkZCB0aGlzIGJlY2F1c2Ugd2Ugbm93IGhhdmUgdGhlIHNpdHVhdGlvbiB3aGVyZQoJICAgICAgIERFRkFVTFQgaXMgbG9hZGVkIGZyb20gYSBiaW5hcnkgZmlsZSB3LyBubyBydWxlcy4gKi8KCSAgICBVRXJyb3JDb2RlIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKCSAgICB0ZW1wLmNvbnN0cnVjdEZyb21SdWxlcyhSdWxlQmFzZWRDb2xsYXRvcjo6REVGQVVMVFJVTEVTLCBpbnRTdGF0dXMpOwoJICAgIAoJICAgIGlmKFVfU1VDQ0VTUyhpbnRTdGF0dXMpICYmICh0ZW1wLm1QYXR0ZXJuICE9IDApKQoJICAgICAgewoJCWRhdGEtPnJ1bGVUYWJsZSA9IHRlbXAuZ2V0UnVsZXMoKTsKCQlkYXRhLT5pc1J1bGVUYWJsZUxvYWRlZCA9IFRSVUU7CgkgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBkYXRhLT5ydWxlVGFibGU7Cn0KCgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbGVuZ3RoKSBjb25zdAp7CiAgICBVbmljb2RlU3RyaW5nIHNvdXJjZV90b2dvOwogICAgVW5pY29kZVN0cmluZyB0YXJnZXRfdG9nbzsKICAgIFVUZXh0T2Zmc2V0IGJlZ2luPTA7CgogICAgc291cmNlLmV4dHJhY3QoYmVnaW4sIHVwcnZfbWluKGxlbmd0aCxzb3VyY2UubGVuZ3RoKCkpLCBzb3VyY2VfdG9nbyk7CiAgICB0YXJnZXQuZXh0cmFjdChiZWdpbiwgdXBydl9taW4obGVuZ3RoLHRhcmdldC5sZW5ndGgoKSksIHRhcmdldF90b2dvKTsKICAgIHJldHVybiAoUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoc291cmNlX3RvZ28sIHRhcmdldF90b2dvKSk7Cn0KCkNvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCAgIApSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZShjb25zdCAgIFVDaGFyKiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCAgIFVDaGFyKiAgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCB0YXJnZXRMZW5ndGgpIGNvbnN0CnsKICAgIC8vIGNoZWNrIGlmIHNvdXJjZSBhbmQgdGFyZ2V0IGFyZSB2YWxpZCBzdHJpbmdzCiAgICBpZiAoKChzb3VyY2UgPT0gMCkgJiYgKHRhcmdldCA9PSAwKSkgfHwKICAgICAgICAoKHNvdXJjZUxlbmd0aCA9PSAwKSAmJiAodGFyZ2V0TGVuZ3RoID09IDApKSkKICAgIHsKICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgfQoKICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBDb2xsYXRvcjo6RVFVQUw7CiAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKCiAgICBpZiAoY3Vyc29yMSA9PSBOVUxMKQogICAgewogICAgICAgICgoUnVsZUJhc2VkQ29sbGF0b3IgKil0aGlzKS0+Y3Vyc29yMSA9IG5ldyBOb3JtYWxpemVySXRlcmF0b3Ioc291cmNlLCBzb3VyY2VMZW5ndGgsIGdldERlY29tcG9zaXRpb24oKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgY3Vyc29yMS0+c2V0TW9kZUFuZFRleHQoZ2V0RGVjb21wb3NpdGlvbigpLCBzb3VyY2UsIHNvdXJjZUxlbmd0aCwgc3RhdHVzKTsKICAgIH0KCiAgICBpZiAoIC8qY3Vyc29yMS0+Y3Vyc29yID09IE5VTEwgfHwqLyBVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgfQoKICAgIGlmIChjdXJzb3IyID09IE5VTEwpCiAgICB7CiAgICAgICAgKChSdWxlQmFzZWRDb2xsYXRvciAqKXRoaXMpLT5jdXJzb3IyID0gbmV3IE5vcm1hbGl6ZXJJdGVyYXRvcih0YXJnZXQsIHRhcmdldExlbmd0aCwgZ2V0RGVjb21wb3NpdGlvbigpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBjdXJzb3IyLT5zZXRNb2RlQW5kVGV4dChnZXREZWNvbXBvc2l0aW9uKCksIHRhcmdldCwgdGFyZ2V0TGVuZ3RoLCBzdGF0dXMpOwogICAgfQoKICAgIGlmICgvKmN1cnNvcjIgPT0gTlVMTCB8fCovIFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7CiAgICB9CgogICAgaW50MzJfdCBzT3JkZXIsIHRPcmRlcjsKICAgIC8vICAgIGludDMyX3Qgc09yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIsIHRPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSOwogICAgYm9vbF90IGdldHMgPSBUUlVFLCBnZXR0ID0gVFJVRTsKICAgIGJvb2xfdCBpbml0aWFsQ2hlY2tTZWNUZXIgPSBnZXRTdHJlbmd0aCgpID49IENvbGxhdG9yOjpTRUNPTkRBUlk7CiAgICBib29sX3QgY2hlY2tTZWNUZXIgPSBpbml0aWFsQ2hlY2tTZWNUZXI7CiAgICBib29sX3QgY2hlY2tUZXJ0aWFyeSA9IGdldFN0cmVuZ3RoKCkgPj0gQ29sbGF0b3I6OlRFUlRJQVJZOwogICAgYm9vbF90IGlzRnJlbmNoU2VjID0gZGF0YS0+aXNGcmVuY2hTZWM7CiAgICB1aW50MzJfdCBwU09yZGVyLCBwVE9yZGVyOwoKICAgIHdoaWxlKFRSVUUpCiAgICB7CiAgICAgICAgLy8gR2V0IHRoZSBuZXh0IGNvbGxhdGlvbiBlbGVtZW50IGluIGVhY2ggb2YgdGhlIHN0cmluZ3MsIHVubGVzcwogICAgICAgIC8vIHdlJ3ZlIGJlZW4gcmVxdWVzdGVkIHRvIHNraXAgaXQuCiAgICAgICAgaWYgKGdldHMpCiAgICAgICAgewogICAgICAgICAgICBzT3JkZXIgPSBnZXRTdHJlbmd0aE9yZGVyKChOb3JtYWxpemVySXRlcmF0b3IqKWN1cnNvcjEsIHN0YXR1cyk7CgogICAgICAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGdldHMgPSBUUlVFOwoKICAgICAgICBpZiAoZ2V0dCkKICAgICAgICB7CiAgICAgICAgICAgIHRPcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoKE5vcm1hbGl6ZXJJdGVyYXRvciopY3Vyc29yMiwgc3RhdHVzKTsKCiAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpFUVVBTDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBnZXR0ID0gVFJVRTsKCiAgICAgICAgLy8gSWYgd2UndmUgaGl0IHRoZSBlbmQgb2Ygb25lIG9mIHRoZSBzdHJpbmdzLCBqdW1wIG91dCBvZiB0aGUgbG9vcAogICAgICAgIGlmICgoc09yZGVyID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKXx8CiAgICAgICAgICAgICh0T3JkZXIgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpKQogICAgICAgIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICAvLyBJZiB0aGVyZSdzIG5vIGRpZmZlcmVuY2UgYXQgdGhpcyBwb3NpdGlvbiwgd2UgY2FuIHNraXAgdG8gdGhlCiAgICAgICAgLy8gbmV4dCBvbmUuCiAgICAgICAgcFNPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKHNPcmRlcik7CiAgICAgICAgcFRPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKHRPcmRlcik7CiAgICAgICAgaWYgKHNPcmRlciA9PSB0T3JkZXIpCiAgICAgICAgewogICAgICAgICAgICBpZiAoaXNGcmVuY2hTZWMgJiYgcFNPcmRlciAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIWNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIGluIGZyZW5jaCwgYSBzZWNvbmRhcnkgZGlmZmVyZW5jZSBtb3JlIHRvIHRoZSByaWdodCBpcyBzdHJvbmdlciwKICAgICAgICAgICAgICAgICAgICAvLyBzbyBhY2NlbnRzIGhhdmUgdG8gYmUgY2hlY2tlZCB3aXRoIGVhY2ggYmFzZSBlbGVtZW50CiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWNUZXIgPSBpbml0aWFsQ2hlY2tTZWNUZXI7CgogICAgICAgICAgICAgICAgICAgIC8vIGJ1dCB0ZXJ0aWFyeSBkaWZmZXJlbmNlcyBhcmUgbGVzcyBpbXBvcnRhbnQgdGhhbiB0aGUgZmlyc3QgCiAgICAgICAgICAgICAgICAgICAgLy8gc2Vjb25kYXJ5IGRpZmZlcmVuY2UsIHNvIGNoZWNraW5nIHRlcnRpYXJ5IHJlbWFpbnMgZGlzYWJsZWQKICAgICAgICAgICAgICAgICAgICBjaGVja1RlcnRpYXJ5ID0gRkFMU0U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29tcGFyZSBwcmltYXJ5IGRpZmZlcmVuY2VzIGZpcnN0LgogICAgICAgIGlmIChwU09yZGVyICE9IHBUT3JkZXIpCiAgICAgICAgewogICAgICAgICAgICBpZiAoc09yZGVyID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBlbnRpcmUgc291cmNlIGVsZW1lbnQgaXMgaWdub3JhYmxlLgogICAgICAgICAgICAgICAgLy8gU2tpcCB0byB0aGUgbmV4dCBzb3VyY2UgZWxlbWVudCwgYnV0IGRvbid0IGZldGNoIGFub3RoZXIgdGFyZ2V0IGVsZW1lbnQuCiAgICAgICAgICAgICAgICBnZXR0ID0gRkFMU0U7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRPcmRlciA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBnZXRzID0gRkFMU0U7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVGhlIHNvdXJjZSBhbmQgdGFyZ2V0IGVsZW1lbnRzIGFyZW4ndCBpZ25vcmFibGUsIGJ1dCBpdCdzIHN0aWxsIHBvc3NpYmxlCiAgICAgICAgICAgIC8vIGZvciB0aGUgcHJpbWFyeSBjb21wb25lbnQgb2Ygb25lIG9mIHRoZSBlbGVtZW50cyB0byBiZSBpZ25vcmFibGUuLi4uCiAgICAgICAgICAgIGlmIChwU09yZGVyID09IDApICAvLyBwcmltYXJ5IG9yZGVyIGluIHNvdXJjZSBpcyBpZ25vcmFibGUKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gVGhlIHNvdXJjZSdzIHByaW1hcnkgaXMgaWdub3JhYmxlLCBidXQgdGhlIHRhcmdldCdzIGlzbid0LiAgV2UgdHJlYXQgaWdub3JhYmxlcwogICAgICAgICAgICAgICAgLy8gYXMgYSBzZWNvbmRhcnkgZGlmZmVyZW5jZSwgc28gcmVtZW1iZXIgdGhhdCB3ZSBmb3VuZCBvbmUuCiAgICAgICAgICAgICAgICBpZiAoY2hlY2tTZWNUZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gQ29sbGF0b3I6OkdSRUFURVI7ICAvLyAoc3RyZW5ndGggaXMgU0VDT05EQVJZKQogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gRkFMU0U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gU2tpcCB0byB0aGUgbmV4dCBzb3VyY2UgZWxlbWVudCwgYnV0IGRvbid0IGZldGNoIGFub3RoZXIgdGFyZ2V0IGVsZW1lbnQuCiAgICAgICAgICAgICAgICBnZXR0ID0gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocFRPcmRlciA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyByZWNvcmQgZGlmZmVyZW5jZXMgLSBzZWUgdGhlIGNvbW1lbnQgYWJvdmUuCiAgICAgICAgICAgICAgICBpZiAoY2hlY2tTZWNUZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gQ29sbGF0b3I6OkxFU1M7ICAvLyAoc3RyZW5ndGggaXMgU0VDT05EQVJZKQogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gRkFMU0U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gU2tpcCB0byB0aGUgbmV4dCB0YXJnZXQgZWxlbWVudCwgYnV0IGRvbid0IGZldGNoIGFub3RoZXIgc291cmNlIGVsZW1lbnQuCiAgICAgICAgICAgICAgICBnZXRzID0gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBOZWl0aGVyIG9mIHRoZSBvcmRlcnMgaXMgaWdub3JhYmxlLCBhbmQgd2UgYWxyZWFkeSBrbm93IHRoYXQgdGhlIHByaW1hcnkKICAgICAgICAgICAgICAgIC8vIG9yZGVycyBhcmUgZGlmZmVyZW50IGJlY2F1c2Ugb2YgdGhlIChwU09yZGVyICE9IHBUT3JkZXIpIHRlc3QgYWJvdmUuCiAgICAgICAgICAgICAgICAvLyBSZWNvcmQgdGhlIGRpZmZlcmVuY2UgYW5kIHN0b3AgdGhlIGNvbXBhcmlzb24uCiAgICAgICAgICAgICAgICBpZiAocFNPcmRlciA8IHBUT3JkZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpMRVNTOyAgLy8gKHN0cmVuZ3RoIGlzIFBSSU1BUlkpCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpHUkVBVEVSOyAgLy8gKHN0cmVuZ3RoIGlzIFBSSU1BUlkpCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsgLy8gZWxzZSBvZiBpZiAoIHBTT3JkZXIgIT0gcFRPcmRlciApCiAgICAgICAgICAgIC8vIHByaW1hcnkgb3JkZXIgaXMgdGhlIHNhbWUsIGJ1dCBjb21wbGV0ZSBvcmRlciBpcyBkaWZmZXJlbnQuIFNvIHRoZXJlCiAgICAgICAgICAgIC8vIGFyZSBubyBiYXNlIGVsZW1lbnRzIGF0IHRoaXMgcG9pbnQsIG9ubHkgaWdub3JhYmxlcyAoU2luY2UgdGhlIHN0cmluZ3MgYXJlCiAgICAgICAgICAgIC8vIG5vcm1hbGl6ZWQpCgogICAgICAgICAgICBpZiAoY2hlY2tTZWNUZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGEgc2Vjb25kYXJ5IG9yIHRlcnRpYXJ5IGRpZmZlcmVuY2UgbWF5IHN0aWxsIG1hdHRlcgogICAgICAgICAgICAgICAgdWludDMyX3Qgc2VjU09yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcihzT3JkZXIpOwogICAgICAgICAgICAgICAgdWludDMyX3Qgc2VjVE9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcih0T3JkZXIpOwoKICAgICAgICAgICAgICAgIGlmIChzZWNTT3JkZXIgIT0gc2VjVE9yZGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIHRoZXJlIGlzIGEgc2Vjb25kYXJ5IGRpZmZlcmVuY2UKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAoc2VjU09yZGVyIDwgc2VjVE9yZGVyKSA/IENvbGxhdG9yOjpMRVNTIDogQ29sbGF0b3I6OkdSRUFURVI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOyAKICAgICAgICAgICAgICAgICAgICAvLyAoZXZlbiBpbiBmcmVuY2gsIG9ubHkgdGhlIGZpcnN0IHNlY29uZGFyeSBkaWZmZXJlbmNlIHdpdGhpbgogICAgICAgICAgICAgICAgICAgIC8vICBhIGJhc2UgY2hhcmFjdGVyIG1hdHRlcnMpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoZWNrVGVydGlhcnkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBhIHRlcnRpYXJ5IGRpZmZlcmVuY2UgbWF5IHN0aWxsIG1hdHRlcgogICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCB0ZXJTT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnRlcnRpYXJ5T3JkZXIoc09yZGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgdGVyVE9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp0ZXJ0aWFyeU9yZGVyKHRPcmRlcik7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVyU09yZGVyICE9IHRlclRPcmRlcikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlcmUgaXMgYSB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAodGVyU09yZGVyIDwgdGVyVE9yZGVyKSA/IENvbGxhdG9yOjpMRVNTIDogQ29sbGF0b3I6OkdSRUFURVI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKHN0cmVuZ3RoIGlzIFRFUlRJQVJZKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tUZXJ0aWFyeSA9IEZBTFNFOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IC8vIGlmIChjaGVja1NlY1RlcikKCiAgICAgICAgfSAgLy8gaWYgKCBwU09yZGVyICE9IHBUT3JkZXIgKQogICAgfSAvLyB3aGlsZSgpCgogICAgaWYgKHNPcmRlciAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUikKICAgIHsKICAgICAgICAvLyAodE9yZGVyIG11c3QgYmUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIsCiAgICAgICAgLy8gIHNpbmNlIHRoaXMgcG9pbnQgaXMgb25seSByZWFjaGVkIHdoZW4gc09yZGVyIG9yIHRPcmRlciBpcyBOVUxMT1JERVIuKQogICAgICAgIC8vIFRoZSBzb3VyY2Ugc3RyaW5nIGhhcyBtb3JlIGVsZW1lbnRzLCBidXQgdGhlIHRhcmdldCBzdHJpbmcgaGFzbid0LgogICAgICAgIGRvCiAgICAgICAgewogICAgICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIoc09yZGVyKSAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBXZSBmb3VuZCBhbiBhZGRpdGlvbmFsIG5vbi1pZ25vcmFibGUgYmFzZSBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgcHJpbWFyeSBkaWZmZXJlbmNlLCBzbyB0aGUgc291cmNlIGlzIGdyZWF0ZXIKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6R1JFQVRFUjsgLy8gKHN0cmVuZ3RoIGlzIFBSSU1BUlkpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKHNPcmRlcikgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gQWRkaXRpb25hbCBzZWNvbmRhcnkgZWxlbWVudHMgbWVhbiB0aGUgc291cmNlIHN0cmluZyBpcyBncmVhdGVyCiAgICAgICAgICAgICAgICBpZiAoY2hlY2tTZWNUZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gQ29sbGF0b3I6OkdSRUFURVI7ICAvLyAoc3RyZW5ndGggaXMgU0VDT05EQVJZKQogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gRkFMU0U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gCiAgICAgICAgfQogICAgICAgIHdoaWxlICgoc09yZGVyID0gZ2V0U3RyZW5ndGhPcmRlcihjdXJzb3IxLCBzdGF0dXMpKSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUik7CiAgICB9CiAgICBlbHNlIGlmICh0T3JkZXIgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpCiAgICB7CiAgICAgICAgLy8gVGhlIHRhcmdldCBzdHJpbmcgaGFzIG1vcmUgZWxlbWVudHMsIGJ1dCB0aGUgc291cmNlIHN0cmluZyBoYXNuJ3QuCiAgICAgICAgZG8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByaW1hcnlPcmRlcih0T3JkZXIpICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFdlIGZvdW5kIGFuIGFkZGl0aW9uYWwgbm9uLWlnbm9yYWJsZSBiYXNlIGNoYXJhY3RlciBpbiB0aGUgdGFyZ2V0IHN0cmluZy4KICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBwcmltYXJ5IGRpZmZlcmVuY2UsIHNvIHRoZSBzb3VyY2UgaXMgbGVzcwogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpMRVNTOyAvLyAoc3RyZW5ndGggaXMgUFJJTUFSWSkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIodE9yZGVyKSAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBBZGRpdGlvbmFsIHNlY29uZGFyeSBlbGVtZW50cyBpbiB0aGUgdGFyZ2V0IG1lYW4gdGhlIHNvdXJjZSBzdHJpbmcgaXMgbGVzcwogICAgICAgICAgICAgICAgaWYgKGNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpMRVNTOyAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IAogICAgICAgIH0KICAgICAgICB3aGlsZSAoKHRPcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoY3Vyc29yMiwgc3RhdHVzKSkgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpOwogICAgfQoKCiAgICAvLyBGb3IgSURFTlRJQ0FMIGNvbXBhcmlzb25zLCB3ZSB1c2UgYSBiaXR3aXNlIGNoYXJhY3RlciBjb21wYXJpc29uCiAgICAvLyBhcyBhIHRpZWJyZWFrZXIgaWYgYWxsIGVsc2UgaXMgZXF1YWwKICAgIC8vIE5PVEU6IFRoZSBqYXZhIGNvZGUgY29tcGFyZXMgcmVzdWx0IHdpdGggMCwgYW5kIAogICAgLy8gcHV0cyB0aGUgcmVzdWx0IG9mIHRoZSBzdHJpbmcgY29tcGFyaXNvbiBkaXJlY3RseSBpbnRvIHJlc3VsdAogICAgaWYgKHJlc3VsdCA9PSBDb2xsYXRvcjo6RVFVQUwgJiYgZ2V0U3RyZW5ndGgoKSA9PSBJREVOVElDQUwpCiAgICB7CiNpZiAwCiAgICAgIC8vICoqKioqKioqIGZvciB0aGUgIFVDaGFyIG5vcm1hbGl6YXRpb24gaW50ZXJmYWNlLgogICAgICAvLyBJdCBkb2Vzbid0IHdvcmsgbXVjaCBmYXN0ZXIsIGFuZCB0aGUgY29kZSB3YXMgYnJva2VuCiAgICAgIC8vIHNvIGl0J3MgY29tbWVudGVkIG91dC4gLS1zcmwKLy8gICAgICAgICAgVUNoYXIgc291cmNlRGVjb21wWzEwMjRdLCB0YXJnZXREZWNvbXBbMTAyNF07Ci8vICAJaW50MzJfdCBzb3VyY2VEZWNvbXBMZW5ndGggPSAxMDI0OwovLyAgCWludDMyX3QgdGFyZ2V0RGVjb21wTGVuZ3RoID0gMTAyNDsKCQovLyAgICAgICAgICBpbnQ4X3QgY29tcGFyaXNvbjsKLy8gIAlOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBNb2RlID0gZ2V0RGVjb21wb3NpdGlvbigpOwogICAgICAgIAovLyAgCWlmIChkZWNvbXBNb2RlICE9IE5vcm1hbGl6ZXI6Ok5PX09QKQovLyAgCSAgewovLyAgCSAgICBOb3JtYWxpemVyOjpub3JtYWxpemUoc291cmNlLCBzb3VyY2VMZW5ndGgsIGRlY29tcE1vZGUsCi8vICAJCQkJICAwLCBzb3VyY2VEZWNvbXAsIHNvdXJjZURlY29tcExlbmd0aCwgc3RhdHVzKTsKCSAgICAKLy8gIAkgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKHRhcmdldCwgdGFyZ2V0TGVuZ3RoLCBkZWNvbXBNb2RlLAovLyAgCQkJCSAgMCwgdGFyZ2V0RGVjb21wLCB0YXJnZXREZWNvbXBMZW5ndGgsIHN0YXR1cyk7CgkgICAgCi8vICAJICAgIGNvbXBhcmlzb24gPSB1X3N0cmNtcChzb3VyY2VEZWNvbXAsdGFyZ2V0RGVjb21wKTsKLy8gIAkgIH0KLy8gIAllbHNlCi8vICAJICB7Ci8vICAJICAgIGNvbXBhcmlzb24gPSB1X3N0cmNtcChzb3VyY2UsIHRhcmdldCk7IC8qICEgKi8KLy8gIAkgIH0KCiNlbHNlCgoJVW5pY29kZVN0cmluZyBzb3VyY2VEZWNvbXAsIHRhcmdldERlY29tcDsKCiAgICAgICAgaW50OF90IGNvbXBhcmlzb247CiAgICAgICAgCiAgICAgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKHNvdXJjZSwgZ2V0RGVjb21wb3NpdGlvbigpLCAKICAgICAgICAgICAgICAgICAgICAgIDAsIHNvdXJjZURlY29tcCwgIHN0YXR1cyk7CgogICAgICAgIE5vcm1hbGl6ZXI6Om5vcm1hbGl6ZSh0YXJnZXQsIGdldERlY29tcG9zaXRpb24oKSwgCiAgICAgICAgICAgICAgICAgICAgICAwLCB0YXJnZXREZWNvbXAsICBzdGF0dXMpOwogICAgICAgIAogICAgICAgIGNvbXBhcmlzb24gPSBzb3VyY2VEZWNvbXAuY29tcGFyZSh0YXJnZXREZWNvbXApOwojZW5kaWYKCiAgICAgICAgaWYgKGNvbXBhcmlzb24gPCAwKQogICAgICAgIHsKICAgICAgICAgICAgcmVzdWx0ID0gQ29sbGF0b3I6OkxFU1M7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGNvbXBhcmlzb24gPT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpFUVVBTDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcmVzdWx0ID0gQ29sbGF0b3I6OkdSRUFURVI7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCgppbnQzMl90ClJ1bGVCYXNlZENvbGxhdG9yOjpuZXh0Q29udHJhY3RDaGFyKE5vcm1hbGl6ZXJJdGVyYXRvciAqY3Vyc29yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNoYXIgY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QKewogICAgLy8gRmlyc3QgZ2V0IHRoZSBvcmRlcmluZyBvZiB0aGlzIHNpbmdsZSBjaGFyYWN0ZXIKICAgIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50ICpsaXN0ID0gZ2V0Q29udHJhY3RWYWx1ZXMoY2gpOwogICAgRW50cnlQYWlyICpwYWlyID0gKEVudHJ5UGFpciAqKWxpc3QtPmF0KDApOwogICAgaW50MzJfdCBvcmRlciA9IHBhaXItPnZhbHVlOwoKICAgIC8vIE5vdyBpdGVyYXRlIHRocm91Z2ggdGhlIGNoYXJzIGZvbGxvd2luZyBpdCBhbmQKICAgIC8vIGxvb2sgZm9yIHRoZSBsb25nZXN0IG1hdGNoCiAgICAoKFVuaWNvZGVTdHJpbmcmKWtleSkucmVtb3ZlKCk7CiAgICAoKFVuaWNvZGVTdHJpbmcmKWtleSkgKz0gY2g7CgogICAgd2hpbGUgKChjaCA9IGN1cnNvci0+Y3VycmVudCgpKSAhPSBOb3JtYWxpemVyOjpET05FKQogICAgewogICAgICAgICgoVW5pY29kZVN0cmluZyYpa2V5KSArPSBjaDsKCiAgICAgICAgaW50MzJfdCBuID0gZ2V0RW50cnkobGlzdCwga2V5LCBUUlVFKTsKCiAgICAgICAgaWYgKG4gPT0gVU5NQVBQRUQpCiAgICAgICAgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY3Vyc29yLT5uZXh0KCk7CgogICAgICAgIHBhaXIgPSAoRW50cnlQYWlyICopbGlzdC0+YXQobik7CiAgICAgICAgb3JkZXIgPSBwYWlyLT52YWx1ZTsKICAgIH0KCiAgICByZXR1cm4gb3JkZXI7Cn0KCi8vIENvbXBhcmUgdHdvIHN0cmluZ3MgdXNpbmcgdGhpcyBjb2xsYXRvcgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0CnsKICAgIHJldHVybiBjb21wYXJlKHNvdXJjZS5nZXRVQ2hhcnMoKSwgc291cmNlLmxlbmd0aCgpLCB0YXJnZXQuZ2V0VUNoYXJzKCksIHRhcmdldC5sZW5ndGgoKSk7Cn0KCi8vIFJldHJpZXZlIGEgY29sbGF0aW9uIGtleSBmb3IgdGhlIHNwZWNpZmllZCBzdHJpbmcKLy8gVGhlIGtleSBjYW4gYmUgY29tcGFyZWQgd2l0aCBvdGhlciBjb2xsYXRpb24ga2V5cyB1c2luZyBhIGJpdHdpc2UgY29tcGFyaXNvbgovLyAoZS5nLiBtZW1jbXApIHRvIGZpbmQgdGhlIG9yZGVyaW5nIG9mIHRoZWlyIHJlc3BlY3RpdmUgc291cmNlIHN0cmluZ3MuCi8vIFRoaXMgaXMgaGFuZHkgd2hlbiBkb2luZyBhIHNvcnQsIHdoZXJlIGVhY2ggc29ydCBrZXkgbXVzdCBiZSBjb21wYXJlZAovLyBtYW55IHRpbWVzLgovLwovLyBUaGUgYmFzaWMgYWxnb3JpdGhtIGhlcmUgaXMgdG8gZmluZCBhbGwgb2YgdGhlIGNvbGxhdGlvbiBlbGVtZW50cyBmb3IgZWFjaAovLyBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBzdHJpbmcsIGNvbnZlcnQgdGhlbSB0byBhbiBBU0NJSSByZXByZXNlbnRhdGlvbiwKLy8gYW5kIHB1dCB0aGVtIGludG8gdGhlIGNvbGxhdGlvbiBrZXkuICBCdXQgaXQncyB0cmlja2llciB0aGFuIHRoYXQuCi8vIEVhY2ggY29sbGF0aW9uIGVsZW1lbnQgaW4gYSBzdHJpbmcgaGFzIHRocmVlIGNvbXBvbmVudHM6IHByaW1hcnkgKCdBJyB2cyAnQicpLAovLyBzZWNvbmRhcnkgKCd1JyB2cyAn/CcpLCBhbmQgdGVydGlhcnkgKCdBJyB2cyAnYScpLCBhbmQgYSBwcmltYXJ5IGRpZmZlcmVuY2UKLy8gYXQgdGhlIGVuZCBvZiBhIHN0cmluZyB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgYSBzZWNvbmRhcnkgb3IgdGVydGlhcnkKLy8gZGlmZmVyZW5jZSBlYXJsaWVyIGluIHRoZSBzdHJpbmcuCi8vCi8vIFRvIGFjY291bnQgZm9yIHRoaXMsIHdlIHB1dCBhbGwgb2YgdGhlIHByaW1hcnkgb3JkZXJzIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlCi8vIHN0cmluZywgZm9sbG93ZWQgYnkgdGhlIHNlY29uZGFyeSBhbmQgdGVydGlhcnkgb3JkZXJzLiBFYWNoIHNldCBvZiBvcmRlcnMgaXMKLy8gdGVybWluYXRlZCBieSBudWxscyBzbyB0aGF0IGEga2V5IGZvciBhIHN0cmluZyB3aGljaCBpcyBhIGluaXRpYWwgc3Vic3RyaW5nIG9mCi8vIGFub3RoZXIga2V5IHdpbGwgY29tcGFyZSBsZXNzIHdpdGhvdXQgYW55IHNwZWNpYWwgY2FzZS4KLy8KLy8gSGVyZSdzIGEgaHlwb3RoZXRpY2FsIGV4YW1wbGUsIHdpdGggdGhlIGNvbGxhdGlvbiBlbGVtZW50IHJlcHJlc2VudGVkIGFzCi8vIGEgdGhyZWUtZGlnaXQgbnVtYmVyLCBvbmUgZGlnaXQgZm9yIHByaW1hcnksIG9uZSBmb3Igc2Vjb25kYXJ5LCBldGMuCi8vCi8vIFN0cmluZzogICAgICAgICAgICAgIEEgICAgIGEgICAgIEIgICAgyQovLyBDb2xsYXRpb24gRWxlbWVudHM6IDEwMSAgIDEwMCAgIDIwMSAgNTExCi8vIENvbGxhdGlvbiBLZXk6ICAgICAgMTEyNTxudWxsPjAwMDE8bnVsbD4xMDExPG51bGw+Ci8vCi8vIFRvIG1ha2UgdGhpbmdzIGV2ZW4gdHJpY2tpZXIsIHNlY29uZGFyeSBkaWZmZXJlbmNlcyAoYWNjZW50IG1hcmtzKSBhcmUgY29tcGFyZWQKLy8gc3RhcnRpbmcgYXQgdGhlICplbmQqIG9mIHRoZSBzdHJpbmcgaW4gbGFuZ3VhZ2VzIHdpdGggRnJlbmNoIHNlY29uZGFyeSBvcmRlcmluZy4KLy8gQnV0IHdoZW4gY29tcGFyaW5nIHRoZSBhY2NlbnQgbWFya3Mgb24gYSBzaW5nbGUgYmFzZSBjaGFyYWN0ZXIsIHRoZXkgYXJlIGNvbXBhcmVkCi8vIGZyb20gdGhlIGJlZ2lubmluZy4gIFRvIGhhbmRsZSB0aGlzLCB3ZSByZXZlcnNlIGFsbCBvZiB0aGUgYWNjZW50cyB0aGF0IGJlbG9uZwovLyB0byBlYWNoIGJhc2UgY2hhcmFjdGVyLCB0aGVuIHdlIHJldmVyc2UgdGhlIGVudGlyZSBzdHJpbmcgb2Ygc2Vjb25kYXJ5IG9yZGVyaW5ncwovLyBhdCB0aGUgZW5kLgovLwpDb2xsYXRpb25LZXkmClJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb2xsYXRpb25LZXkoIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiAgIHNvcnRrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKSBjb25zdAp7CiAgICByZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbGxhdGlvbktleShzb3VyY2UuZ2V0VUNoYXJzKCksIHNvdXJjZS5sZW5ndGgoKSwgc29ydGtleSwgc3RhdHVzKTsKfQoKQ29sbGF0aW9uS2V5JgpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29sbGF0aW9uS2V5KCBjb25zdCAgIFVDaGFyKiAgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiAgIHNvcnRrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKSBjb25zdAp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SOwogICAgICAgIHJldHVybiBzb3J0a2V5LnNldFRvQm9ndXMoKTsKICAgIH0KICAgIAogICAgaWYgKCghc291cmNlKSB8fCAoc291cmNlTGVuID09IDApKQogICAgewogICAgICAgIHJldHVybiBzb3J0a2V5LnJlc2V0KCk7CiAgICB9CgogICAgaWYgKGN1cnNvcjEgPT0gTlVMTCkKICAgIHsKICAgICAgKChSdWxlQmFzZWRDb2xsYXRvciAqKXRoaXMpLT5jdXJzb3IxID0gbmV3IE5vcm1hbGl6ZXJJdGVyYXRvcihzb3VyY2UsIHNvdXJjZUxlbiwgZ2V0RGVjb21wb3NpdGlvbigpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgY3Vyc29yMS0+c2V0TW9kZUFuZFRleHQoZ2V0RGVjb21wb3NpdGlvbigpLCBzb3VyY2Usc291cmNlTGVuLCBzdGF0dXMpOwogICAgfQoKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gc29ydGtleS5zZXRUb0JvZ3VzKCk7CiAgICB9CgogICAgYm9vbF90ICBjb21wYXJlU2VjICAgPSAoZ2V0U3RyZW5ndGgoKSA+PSBDb2xsYXRvcjo6U0VDT05EQVJZKTsKICAgIGJvb2xfdCAgY29tcGFyZVRlciAgID0gKGdldFN0cmVuZ3RoKCkgPj0gQ29sbGF0b3I6OlRFUlRJQVJZKTsKICAgIGJvb2xfdCAgY29tcGFyZUlkZW50ID0gKGdldFN0cmVuZ3RoKCkgPT0gQ29sbGF0b3I6OklERU5USUNBTCk7CiAgICBpbnQzMl90IG9yZGVyICAgICAgICA9IDA7CiAgICBpbnQzMl90IHRvdGFsUHJpbWFyeSA9IDA7CiAgICBpbnQzMl90IHRvdGFsU2VjICAgICA9IDA7CiAgICBpbnQzMl90IHRvdGFsVGVyICAgICA9IDA7CiAgICBpbnQzMl90IHRvdGFsSWRlbnQgICAgID0gMDsKICAgIFVuaWNvZGVTdHJpbmcgZGVjb21wOwoKICAgIC8vIGl0ZXJhdGUgb3ZlciB0aGUgc291cmNlLCBjb3VudGluZyBwcmltYXJ5LCBzZWNvbmRhcnksIGFuZCB0ZXJ0aWFyeSBlbnRyaWVzCiAgICB3aGlsZSgob3JkZXIgPSBnZXRTdHJlbmd0aE9yZGVyKChOb3JtYWxpemVySXRlcmF0b3IqKWN1cnNvcjEsIHN0YXR1cykpICE9CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIGludDMyX3Qgc2VjT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKG9yZGVyKTsKICAgICAgICBpbnQzMl90IHRlck9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp0ZXJ0aWFyeU9yZGVyKG9yZGVyKTsKCiAgICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHNvcnRrZXkuc2V0VG9Cb2d1cygpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc0lnbm9yYWJsZShvcmRlcikpCiAgICAgICAgewogICAgICAgICAgICB0b3RhbFByaW1hcnkgKz0gMTsKCiAgICAgICAgICAgIGlmIChjb21wYXJlU2VjKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0b3RhbFNlYyArPSAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29tcGFyZVRlcikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG90YWxUZXIgKz0gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBpZiAoY29tcGFyZVNlYyAmJiBzZWNPcmRlciAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0b3RhbFNlYyArPSAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29tcGFyZVRlciAmJiB0ZXJPcmRlciAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0b3RhbFRlciArPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIGNvdW50IHRoZSBudWxsIGJ5dGVzIGFmdGVyIHRoZSBlbnRpcmVzCiAgICB0b3RhbFByaW1hcnkgKz0gMTsKCiAgICBpZiAoY29tcGFyZVNlYykKICAgIHsKICAgICAgICB0b3RhbFNlYyArPSAxOwogICAgfQoKICAgIGlmIChjb21wYXJlVGVyKQogICAgewogICAgICAgIHRvdGFsVGVyICs9IDE7CiAgICB9CgogICAgaWYgKGNvbXBhcmVJZGVudCkKICAgIHsKICAgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKHNvdXJjZSwgZ2V0RGVjb21wb3NpdGlvbigpLCAvLyBTUkw6ID8/CiAgICAgICAgICAgICAgICAwLCBkZWNvbXAsIHN0YXR1cyk7CgogICAgICAgIGlmIChVX1NVQ0NFU1Moc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHRvdGFsSWRlbnQgPSBkZWNvbXAubGVuZ3RoKCkgKyAxOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBDb21wdXRlIHRvdGFsIG51bWJlciBvZiBieXRlcyB0byBob2xkIHRoZSBlbnRyaWVzCiAgICAvLyBhbmQgbWFrZSBzdXJlIHRoZSBrZXkgY2FuIGhvbGQgdGhlbQogICAgdWludDMyX3Qgc2l6ZSAgID0gMiAqICh0b3RhbFByaW1hcnkgKyB0b3RhbFNlYyArIHRvdGFsVGVyICsgdG90YWxJZGVudCk7CgogICAgc29ydGtleS5lbnN1cmVDYXBhY2l0eShzaXplKTsKCiAgICBpZiAoc29ydGtleS5pc0JvZ3VzKCkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm4gc29ydGtleTsKICAgIH0KCiAgICBpbnQzMl90IHByaW1hcnlDdXJzb3IgPSAwOwogICAgaW50MzJfdCBzZWNDdXJzb3IgICAgID0gMiAqIHRvdGFsUHJpbWFyeTsKICAgIGludDMyX3Qgc2VjQmFzZSAgICAgICA9IHNlY0N1cnNvcjsKICAgIGludDMyX3QgcHJlU2VjSWdub3JlICA9IHNlY0Jhc2U7CiAgICBpbnQzMl90IHRlckN1cnNvciAgICAgPSBzZWNDdXJzb3IgKyAoMiAqIHRvdGFsU2VjKTsKICAgIGludDMyX3QgaWRlbnRDdXJzb3IgICAgICA9IHRlckN1cnNvciArICgyICogdG90YWxUZXIpOwoKICAgIC8vIHJlc2V0IHNvdXJjZSB0byB0aGUgYmVnaW5uaW5nCiAgICBjdXJzb3IxLT5yZXNldCgpOwoKICAgIC8vIG5vdyBpdGVyYXRlIG92ZXIgdGhlIHNvdXJjZSBjb21wdXRpbmcgdGhlIGFjdHVhbCBlbnRyaWVzCiAgICB3aGlsZSgob3JkZXIgPSBnZXRTdHJlbmd0aE9yZGVyKChOb3JtYWxpemVySXRlcmF0b3IqKWN1cnNvcjEsIHN0YXR1cykpICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBzb3J0a2V5LnJlc2V0KCk7CiAgICAgICAgfQoKICAgICAgICBpbnQzMl90IHByaW1hcnlPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKG9yZGVyKTsKICAgICAgICBpbnQzMl90IHNlY09yZGVyICAgICA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIob3JkZXIpOwogICAgICAgIGludDMyX3QgdGVyT3JkZXIgICAgID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp0ZXJ0aWFyeU9yZGVyKG9yZGVyKTsKCiAgICAgICAgaWYgKCEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc0lnbm9yYWJsZShvcmRlcikpCiAgICAgICAgewogICAgICAgICAgICBwcmltYXJ5Q3Vyc29yID0gc29ydGtleS5zdG9yZUJ5dGVzKHByaW1hcnlDdXJzb3IsIHByaW1hcnlPcmRlciArIFNPUlRLRVlPRkZTRVQpOwoKICAgICAgICAgICAgaWYgKGNvbXBhcmVTZWMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChkYXRhLT5pc0ZyZW5jaFNlYyAmJiAocHJlU2VjSWdub3JlIDwgc2VjQ3Vyc29yKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzb3J0a2V5LnJldmVyc2VCeXRlcyhwcmVTZWNJZ25vcmUsIHNlY0N1cnNvcik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgc2VjQ3Vyc29yID0gc29ydGtleS5zdG9yZUJ5dGVzKHNlY0N1cnNvciwgc2VjT3JkZXIgKyBTT1JUS0VZT0ZGU0VUKTsKCiAgICAgICAgICAgICAgICBwcmVTZWNJZ25vcmUgPSBzZWNDdXJzb3I7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb21wYXJlVGVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0ZXJDdXJzb3IgPSBzb3J0a2V5LnN0b3JlQnl0ZXModGVyQ3Vyc29yLCB0ZXJPcmRlciArIFNPUlRLRVlPRkZTRVQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb21wYXJlU2VjICYmIHNlY09yZGVyICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNlY0N1cnNvciA9IHNvcnRrZXkuc3RvcmVCeXRlcyhzZWNDdXJzb3IsIHNlY09yZGVyICsgZGF0YS0+bWF4U2VjT3JkZXIgKyBTT1JUS0VZT0ZGU0VUKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNvbXBhcmVUZXIgJiYgdGVyT3JkZXIgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGVyQ3Vyc29yID0gc29ydGtleS5zdG9yZUJ5dGVzKHRlckN1cnNvciwgdGVyT3JkZXIgKyBkYXRhLT5tYXhUZXJPcmRlciArIFNPUlRLRVlPRkZTRVQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIGFwcGVuZCAwIGF0IHRoZSBlbmQgb2YgZWFjaCBwb3J0aW9uLgogICAgc29ydGtleS5zdG9yZUJ5dGVzKHByaW1hcnlDdXJzb3IsIDApOwoKICAgIGlmIChjb21wYXJlU2VjKQogICAgewogICAgICAgIGlmIChkYXRhLT5pc0ZyZW5jaFNlYykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwcmVTZWNJZ25vcmUgPCBzZWNDdXJzb3IpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNvcnRrZXkucmV2ZXJzZUJ5dGVzKHByZVNlY0lnbm9yZSwgc2VjQ3Vyc29yKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc29ydGtleS5yZXZlcnNlQnl0ZXMoc2VjQmFzZSwgc2VjQ3Vyc29yKTsKICAgICAgICB9CgogICAgICAgIHNvcnRrZXkuc3RvcmVCeXRlcyhzZWNDdXJzb3IsIDApOwogICAgfQoKICAgIGlmIChjb21wYXJlVGVyKQogICAgewogICAgICAgIHNvcnRrZXkuc3RvcmVCeXRlcyh0ZXJDdXJzb3IsIDApOwogICAgfQoKICAgIGlmIChjb21wYXJlSWRlbnQpCiAgICB7CiAgICAgICAgc29ydGtleS5zdG9yZVVuaWNvZGVTdHJpbmcoaWRlbnRDdXJzb3IsIGRlY29tcCk7CiAgICB9CgogICAgLy8gICAgRGVidWdnaW5nIC0gcHJpbnQgb3V0IHRoZSBzb3J0a2V5IFstLXNybF0KLy8gICAgICB7Ci8vICAgICAgICBjb25zdCB1aW50OF90ICpieXRlczsKLy8gICAgICAgIGludDMyX3QgeGNvdW50OwovLyAgICAgICAgYnl0ZXMgPSBzb3J0a2V5LmdldEJ5dGVBcnJheSh4Y291bnQpOwovLyAgICAgICAgLy8gICAgICBmcHJpbnRmKHN0ZGVyciwgIlxuXG4tICBbJTAyWF0gWyUwMlhdXG5cbiIsIChpbnQpKGJ5dGVzWzBdJjB4RkYpLCAoaW50KShieXRlc1sxXSYweEZGKSApOwovLyAgICAgIH0KCiAgICByZXR1cm4gc29ydGtleTsKfQoKCi8vIEJ1aWxkIHRoaXMgY29sbGF0b3IncyBydWxlIHRhYmxlcyBiYXNlZCBvbiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcnVsZXMKLy8gU2VlIHRoZSBiaWcgZGlhZ3JhbSBhdCB0aGUgdG9wIG9mIHRoaXMgZmlsZSBmb3IgYW4gb3ZlcnZpZXcgb2YgaG93IHRoZSB0YWJsZXMKLy8gYXJlIG9yZ2FuaXplZC4Kdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6YnVpbGQoY29uc3QgVW5pY29kZVN0cmluZyYgICBwYXR0ZXJuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gVGhpcyBhcnJheSBtYXBzIFVuaWNvZGUgY2hhcmFjdGVycyB0byB0aGVpciBjb2xsYXRpb24gb3JkZXJpbmcKICAgIGRhdGEtPm1hcHBpbmcgPSB1Y21wMzJfb3BlbihVTk1BUFBFRCk7CgogICAgaWYgKGRhdGEtPm1hcHBpbmctPmZCb2d1cykKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoIGFTdHJlbmd0aCA9IENvbGxhdG9yOjpJREVOVElDQUw7CiAgICBib29sX3QgaXNTb3VyY2UgPSBUUlVFOwogICAgaW50MzJfdCBpID0gMDsKICAgIFVuaWNvZGVTdHJpbmcgbGFzdEdyb3VwQ2hhcnM7CiAgICBVbmljb2RlU3RyaW5nIGV4cENoYXJzOwogICAgVW5pY29kZVN0cmluZyBncm91cENoYXJzOwoKICAgIGlmIChwYXR0ZXJuLmxlbmd0aCgpID09IDApCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9JTlZBTElEX0ZPUk1BVF9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gQnVpbGQgdGhlIG1lcmdlZCBjb2xsYXRpb24gZW50cmllcwogICAgLy8gU2luY2UgcnVsZXMgY2FuIGJlIHNwZWNpZmllZCBpbiBhbnkgb3JkZXIgaW4gdGhlIHN0cmluZwogICAgLy8gKGUuZy4gImMgLCBDIDwgZCAsIEQgPCBlICwgRSAuLi4uIEMgPCBDSCIpCiAgICAvLyB0aGlzIHNwbGl0cyBhbGwgb2YgdGhlIHJ1bGVzIGluIHRoZSBzdHJpbmcgb3V0IGludG8gc2VwYXJhdGUKICAgIC8vIG9iamVjdHMgYW5kIHRoZW4gc29ydHMgdGhlbS4gIEluIHRoZSBhYm92ZSBleGFtcGxlLCBpdCBtZXJnZXMgdGhlCiAgICAvLyAiQyA8IENIIiBydWxlIGluIGp1c3QgYmVmb3JlIHRoZSAiQyA8IEQiIHJ1bGUuCgogICAgbVBhdHRlcm4gPSBuZXcgTWVyZ2VDb2xsYXRpb24ocGF0dGVybiwgZ2V0RGVjb21wb3NpdGlvbigpLCBzdGF0dXMpOwogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHVjbXAzMl9jbG9zZShkYXRhLT5tYXBwaW5nKTsKICAgICAgICBkYXRhLT5tYXBwaW5nID0gMDsKICAgICAgICBkZWxldGUgbVBhdHRlcm47CiAgICAgICAgbVBhdHRlcm4gPSAwOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpbnQzMl90IG9yZGVyID0gMDsKCiAgICAvLyBXYWxrIHRocm91Z2ggZWFjaCBlbnRyeQogICAgZm9yIChpID0gMDsgaSA8IG1QYXR0ZXJuLT5nZXRDb3VudCgpOyArK2kpCiAgICB7CiAgICAgICAgY29uc3QgUGF0dGVybkVudHJ5KiBlbnRyeSA9IG1QYXR0ZXJuLT5nZXRJdGVtQXQoaSk7CiAgICAgICAgZ3JvdXBDaGFycy5yZW1vdmUoKTsKICAgICAgICBleHBDaGFycy5yZW1vdmUoKTsKCiAgICAgICAgLy8gaWYgZW50cnkgaXMgdmFsaWQKICAgICAgICBpZiAoZW50cnkgIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIGVudHJ5LT5nZXRDaGFycyhncm91cENoYXJzKTsKCiAgICAgICAgICAgIC8vIGNoZWNrIGlmIGZyZW5jaCBzZWNvbmRhcnkgbmVlZHMgdG8gYmUgdHVybmVkIG9uCiAgICAgICAgICAgIGlmICgoZ3JvdXBDaGFycy5sZW5ndGgoKSA+IDEpICYmCiAgICAgICAgICAgICAgICAoZ3JvdXBDaGFyc1tncm91cENoYXJzLmxlbmd0aCgpLShUX0lOVDMyKDEpKV0gPT0gMHgwMDQwKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGF0YS0+aXNGcmVuY2hTZWMgPSBUUlVFOwogICAgICAgICAgICAgICAgZ3JvdXBDaGFycy5yZW1vdmUoZ3JvdXBDaGFycy5sZW5ndGgoKS0oVF9JTlQzMigxKSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBvcmRlciA9IGluY3JlbWVudCgoQ29sbGF0b3I6OkVDb2xsYXRpb25TdHJlbmd0aCllbnRyeS0+Z2V0U3RyZW5ndGgoKSwgb3JkZXIpOwoKICAgICAgICAgICAgaWYgKGVudHJ5LT5nZXRFeHRlbnNpb24oZXhwQ2hhcnMpLmxlbmd0aCgpICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGVuY291bnRlcmVkIGFuIGV4cGFuZGluZyBjaGFyYWN0ZXIsIHdoZXJlIG9uZSBjaGFyYWN0ZXIgb24gaW5wdXQKICAgICAgICAgICAgICAgIC8vIGV4cGFuZHMgdG8gc2V2ZXJhbCBzb3J0IGVsZW1lbnRzIChlLmcuICf2JyAtLT4gJ28nICdlJykKICAgICAgICAgICAgICAgIGFkZEV4cGFuZE9yZGVyKGdyb3VwQ2hhcnMsIGV4cENoYXJzLCBvcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoZ3JvdXBDaGFycy5sZW5ndGgoKSA+IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGVuY291bnRlcmVkIGEgY29udHJhY3RpbmcgY2hhcmFjdGVyLCB3aGVyZSBzZXZlcmFsIGNoYXJhY3RlcnMgb24gaW5wdXQKICAgICAgICAgICAgICAgIC8vIGNvbnRyYWN0IGludG8gb25lIHNvcnQgb3JkZXIuICBGb3IgZXhhbXBsZSwgImNoIiBpcyB0cmVhdGVkIGFzIGEgc2luZ2xlCiAgICAgICAgICAgICAgICAvLyBjaGFyYWN0ZXIgaW4gdHJhZGl0aW9uYWwgU3BhbmlzaCBzb3J0aW5nLgogICAgICAgICAgICAgICAgYWRkQ29udHJhY3RPcmRlcihncm91cENoYXJzLCBvcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBOb3RoaW5nIG91dCBvZiB0aGUgb3JkaW5hcnkgLS0gb25lIGNoYXJhY3RlciBtYXBzIHRvIG9uZSBzb3J0IG9yZGVyCiAgICAgICAgICAgICAgICBhZGRPcmRlcihncm91cENoYXJzWzBdLCBvcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gYWRkIGV4cGFuZGluZyBlbnRyaWVzIGZvciBwcmUtY29tcG9zZWQgY2hhcmFjdGVycwogICAgYWRkQ29tcG9zZWRDaGFycygpOwoKICAgIC8vIEZpbGwgaW4gYWxsIHRoZSBleHBhbmRpbmcgY2hhcnMgdmFsdWVzCiAgICBjb21taXQoKTsKCiAgICAvLyBDb21wYWN0IHRoZSBkYXRhIG1hcHBpbmcgdGFibGUKICAgIHVjbXAzMl9jb21wYWN0KGRhdGEtPm1hcHBpbmcsIDEpOwp9CgovKioKICogQWRkIGV4cGFuZGluZyBlbnRyaWVzIGZvciBwcmUtY29tcG9zZWQgdW5pY29kZSBjaGFyYWN0ZXJzIHNvIHRoYXQgdGhpcwogKiBjb2xsYXRvciBjYW4gYmUgdXNlZCByZWFzb25hYmx5IHdlbGwgd2l0aCBkZWNvbXBvc2l0aW9uIHR1cm5lZCBvZmYuCiAqLwogdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6YWRkQ29tcG9zZWRDaGFycygpCiB7CiAgICBVbmljb2RlU3RyaW5nIGJ1ZjsKICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwoKICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBhbGwgb2YgdGhlIHByZS1jb21wb3NlZCBjaGFyYWN0ZXJzIGluIFVuaWNvZGUKICAgIENvbXBvc2VkQ2hhckl0ZXIgaXRlcjsKICAgIFVuaWNvZGVTdHJpbmcgZGVjb21wOwoKICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkKICAgIHsKICAgICAgICBVQ2hhciBjID0gaXRlci5uZXh0KCk7CiAgICAgICAgCiAgICAgICAgaWYgKGdldENoYXJPcmRlcihjKSA9PSBVTk1BUFBFRCkKICAgICAgICB7CiAgICAgICAgICAgIC8vIAogICAgICAgICAgICAvLyBXZSBkb24ndCBhbHJlYWR5IGhhdmUgYW4gb3JkZXJpbmcgZm9yIHRoaXMgcHJlLWNvbXBvc2VkIGNoYXJhY3Rlci4KICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gRmlyc3QsIHNlZSBpZiB0aGUgZGVjb21wb3NlZCBzdHJpbmcgaXMgYWxyZWFkeSBpbiBvdXIKICAgICAgICAgICAgLy8gdGFibGVzIGFzIGEgc2luZ2xlIGNvbnRyYWN0aW5nLXN0cmluZyBvcmRlcmluZy4KICAgICAgICAgICAgLy8gSWYgc28sIGp1c3QgbWFwIHRoZSBwcmVjb21wb3NlZCBjaGFyYWN0ZXIgdG8gdGhhdCBvcmRlci4KICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gVE9ETzogV2hhdCB3ZSBzaG91bGQgcmVhbGx5IGJlIGRvaW5nIGhlcmUgaXMgdHJ5aW5nIHRvIGZpbmQgdGhlCiAgICAgICAgICAgIC8vIGxvbmdlc3QgaW5pdGlhbCBzdWJzdHJpbmcgb2YgdGhlIGRlY29tcG9zaXRpb24gdGhhdCBpcyBwcmVzZW50CiAgICAgICAgICAgIC8vIGluIHRoZSB0YWJsZXMgYXMgYSBjb250cmFjdGluZyBjaGFyYWN0ZXIgc2VxdWVuY2UsIGFuZCBmaW5kIGl0cwogICAgICAgICAgICAvLyBvcmRlcmluZy4gIFRoZW4gZG8gdGhpcyByZWN1cnNpdmVseSB3aXRoIHRoZSByZW1haW5pbmcgY2hhcnMKICAgICAgICAgICAgLy8gc28gdGhhdCB3ZSBidWlsZCBhIGxpc3Qgb2Ygb3JkZXJpbmdzLCBhbmQgYWRkIHRoYXQgbGlzdCB0bwogICAgICAgICAgICAvLyB0aGUgZXhwYW5zaW9uIHRhYmxlLiAKICAgICAgICAgICAgLy8gVGhhdCB3b3VsZCBiZSBtb3JlIGNvcnJlY3QgYnV0IGFsc28gc2lnbmlmaWNhbnRseSBzbG93ZXIsIHNvCiAgICAgICAgICAgIC8vIEknbSBub3QgdG90YWxseSBzdXJlIGl0J3Mgd29ydGggZG9pbmcuCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIGl0ZXIuZ2V0RGVjb21wb3NpdGlvbihkZWNvbXApOwogICAgICAgICAgICBpbnQgY29udHJhY3RPcmRlciA9IGdldENvbnRyYWN0T3JkZXIoZGVjb21wKTsKCiAgICAgICAgICAgIGlmIChjb250cmFjdE9yZGVyICE9IFVOTUFQUEVEKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhZGRPcmRlcihjLCBjb250cmFjdE9yZGVyLCBzdGF0dXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIC8vIFdlIGRvbid0IGhhdmUgYSBjb250cmFjdGluZyBvcmRlcmluZyBmb3IgdGhlIGVudGlyZSBzdHJpbmcKICAgICAgICAgICAgICAgIC8vIHRoYXQgcmVzdWx0cyBmcm9tIHRoZSBkZWNvbXBvc2l0aW9uLCBidXQgaWYgd2UgaGF2ZSBvcmRlcnMKICAgICAgICAgICAgICAgIC8vIGZvciBlYWNoIGluZGl2aWR1YWwgY2hhcmFjdGVyLCB3ZSBjYW4gYWRkIGFuIGV4cGFuZGluZwogICAgICAgICAgICAgICAgLy8gdGFibGUgZW50cnkgZm9yIHRoZSBwcmUtY29tcG9zZWQgY2hhcmFjdGVyIAogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIGJvb2xfdCBhbGxUaGVyZSA9IFRSVUU7CiAgICAgICAgICAgICAgICBpbnQzMl90IGk7CgogICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGRlY29tcC5sZW5ndGgoKTsgaSArPSAxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChnZXRDaGFyT3JkZXIoZGVjb21wW2ldKSA9PSBVTk1BUFBFRCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFsbFRoZXJlID0gRkFMU0U7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoYWxsVGhlcmUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYnVmLnJlbW92ZSgpOwogICAgICAgICAgICAgICAgICAgIGJ1ZiArPSBjOwogICAgICAgICAgICAgICAgICAgIGFkZEV4cGFuZE9yZGVyKGJ1ZiwgZGVjb21wLCBVTk1BUFBFRCwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQogICAgCi8vIFdoZW4gdGhlIGV4cGFuZGluZyBjaGFyYWN0ZXIgdGFibGVzIGFyZSBidWlsdCBieSBhZGRFeHBhbmRPcmRlciwKLy8gaXQgZG9lc24ndCBrbm93IHdoYXQgdGhlIGZpbmFsIG9yZGVyaW5nIG9mIGVhY2ggY2hhcmFjdGVyCi8vIGluIHRoZSBleHBhbnNpb24gd2lsbCBiZS4gIEluc3RlYWQsIGl0IGp1c3QgcHV0cyB0aGUgcmF3IGNoYXJhY3RlcgovLyBjb2RlIGludG8gdGhlIHRhYmxlLCBhZGRpbmcgQ0hBUklOREVYIGFzIGEgZmxhZy4gIE5vdyB0aGF0IHdlJ3ZlCi8vIGZpbmlzaGVkIGJ1aWxkaW5nIHRoZSBtYXBwaW5nIHRhYmxlLCB3ZSBjYW4gZ28gYmFjayBhbmQgbG9vayB1cAovLyB0aGF0IGNoYXJhY3RlciB0byBzZWUgd2hhdCBpdHMgcmVhbCBjb2xsYXRpb24gb3JkZXIgaXMgYW5kCi8vIHN0aWNrIHRoYXQgaW50byB0aGUgZXhwYW5zaW9uIHRhYmxlLiAgVGhhdCBsZXRzIHVzIGF2b2lkIGRvaW5nCi8vIGEgdHdvLXN0YWdlIGxvb2t1cCBsYXRlci4KCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbW1pdCgpCnsKICAgIC8vIGlmIHRoZXJlIGFyZSBhbnkgZXhwYW5kaW5nIGNoYXJhY3RlcnMKICAgIGlmIChkYXRhLT5leHBhbmRUYWJsZSAhPSBOVUxMKQogICAgewogICAgICAgIGludDMyX3QgaTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZGF0YS0+ZXhwYW5kVGFibGUtPnNpemUoKTsgaSArPSAxKQogICAgICAgIHsKICAgICAgICAgICAgVmVjdG9yT2ZJbnQqIHZhbHVlTGlzdCA9IGRhdGEtPmV4cGFuZFRhYmxlLT5hdChpKTsKICAgICAgICAgICAgaW50MzJfdCBqOwogICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgdmFsdWVMaXN0LT5zaXplKCk7IGorKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gZm91bmQgYSBleHBhbmRpbmcgY2hhcmFjdGVyCiAgICAgICAgICAgICAgICAvLyB0aGUgZXhwYW5kaW5nIGNoYXIgdmFsdWUgaXMgbm90IGZpbGxlZCBpbiB5ZXQKICAgICAgICAgICAgICAgIGlmICgodmFsdWVMaXN0LT5hdChqKSA8IEVYUEFORENIQVJJTkRFWCkgJiYKICAgICAgICAgICAgICAgICAgICAodmFsdWVMaXN0LT5hdChqKSA+IENIQVJJTkRFWCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy8gR2V0IHRoZSByZWFsIHZhbHVlcyBmb3IgdGhlIG5vbi1maWxsZWQgZW50cnkKICAgICAgICAgICAgICAgICAgICBVQ2hhciBjaCA9IChVQ2hhcikodmFsdWVMaXN0LT5hdChqKSAtIENIQVJJTkRFWCk7CiAgICAgICAgICAgICAgICAgICAgaW50MzJfdCByZWFsVmFsdWUgPSB1Y21wMzJfZ2V0KGRhdGEtPm1hcHBpbmcsIGNoKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHJlYWxWYWx1ZSA9PSBVTk1BUFBFRCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSByZWFsIHZhbHVlIGlzIHN0aWxsIHVubWFwcGVkLCBtYXliZSBpdCdzaWdub3JhYmxlCiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlTGlzdC0+YXRQdXQoaiwgSUdOT1JBQkxFTUFTSyAmIGNoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gZmlsbCBpbiB0aGUgdmFsdWUKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZUxpc3QtPmF0UHV0KGosIHJlYWxWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogfQoKLyoqCiAqICBJbmNyZW1lbnQgb2YgdGhlIGxhc3Qgb3JkZXIgYmFzZWQgb24gdGhlIGNvbXBhcmlzb24gbGV2ZWwuCiAqLwppbnQzMl90ClJ1bGVCYXNlZENvbGxhdG9yOjppbmNyZW1lbnQoQ29sbGF0b3I6OkVDb2xsYXRpb25TdHJlbmd0aCBhU3RyZW5ndGgsIGludDMyX3QgbGFzdFZhbHVlKQp7CiAgICBzd2l0Y2goYVN0cmVuZ3RoKQogICAgewogICAgY2FzZSBDb2xsYXRvcjo6UFJJTUFSWToKICAgICAgICAvLyBpbmNyZW1lbnQgcHJpYW1yeSBvcmRlciAgYW5kIG1hc2sgb2ZmIHNlY29uZGFyeSBhbmQgdGVydGlhcnkgZGlmZmVyZW5jZQogICAgICAgIGxhc3RWYWx1ZSArPSBQUklNQVJZT1JERVJJTkNSRU1FTlQ7CiAgICAgICAgbGFzdFZhbHVlICY9IFBSSU1BUllPUkRFUk1BU0s7CiAgICAgICAgaXNPdmVySWdub3JlID0gVFJVRTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIENvbGxhdG9yOjpTRUNPTkRBUlk6CiAgICAgICAgLy8gaW5jcmVtZW50IHNlY29uZGFyeSBvcmRlciBhbmQgbWFzayBvZmYgdGVydGlhcnkgZGlmZmVyZW5jZQogICAgICAgIGxhc3RWYWx1ZSArPSBTRUNPTkRBUllPUkRFUklOQ1JFTUVOVDsKICAgICAgICBsYXN0VmFsdWUgJj0gU0VDT05EQVJZRElGRkVSRU5DRU9OTFk7CgogICAgICAgIC8vIHJlY29yZCBtYXggIyBvZiBpZ25vcmFibGUgY2hhcnMgd2l0aCBzZWNvbmRhcnkgZGlmZmVyZW5jZQogICAgICAgIGlmIChpc092ZXJJZ25vcmUgPT0gRkFMU0UpCiAgICAgICAgewogICAgICAgICAgICBkYXRhLT5tYXhTZWNPcmRlciArPSAxOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIENvbGxhdG9yOjpURVJUSUFSWToKICAgICAgICAvLyBpbmNyZW1lbnQgdGVydGlhcnkgb3JkZXIKICAgICAgICBsYXN0VmFsdWUgKz0gVEVSVElBUllPUkRFUklOQ1JFTUVOVDsKCiAgICAgICAgLy8gcmVjb3JkIG1heCAjIG9mIGlnbm9yYWJsZSBjaGFycyB3aXRoIHRlcnRpYXJ5IGRpZmZlcmVuY2UKICAgICAgICBpZiAoaXNPdmVySWdub3JlID09IEZBTFNFKQogICAgICAgIHsKICAgICAgICAgICAgZGF0YS0+bWF4VGVyT3JkZXIgKz0gMTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogIC8vIGNhc2UgSURFTlRJQ0FMPyAgCiAgICB9CgogICAgcmV0dXJuIGxhc3RWYWx1ZTsKfQoKLy8gQWRkcyBhIGNoYXJhY3RlciBhbmQgaXRzIGRlc2lnbmF0ZWQgb3JkZXIgaW50byB0aGUgY29sbGF0aW9uIHRhYmxlLgovLyBUaGlzIGlzIHRoZSBzaW1wbGUgY2FzZSwgd2l0aCBubyBleHBhbnNpb24gb3IgY29udHJhY3Rpb24Kdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6YWRkT3JkZXIoVUNoYXIgY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGFuT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gdHJ5IHRvIGZpbmQgdGhlIG9yZGVyIG9mIHRoZSBjaGFyIGluIHRoZSBtYXBwaW5nIHRhYmxlCiAgICBpbnQzMl90IG9yZGVyID0gdWNtcDMyX2dldChkYXRhLT5tYXBwaW5nLCBjaCk7CgogICAgaWYgKG9yZGVyID49IENPTlRSQUNUQ0hBUklOREVYKQogICAgewogICAgICAgIC8vIFRoZXJlJ3MgYWxyZWFkeSBhbiBlbnRyeSBmb3IgdGhpcyBjaGFyYWN0ZXIgdGhhdCBwb2ludHMgdG8gYSBjb250cmFjdGluZwogICAgICAgIC8vIGNoYXJhY3RlciB0YWJsZS4gIEluc3RlYWQgb2YgYWRkaW5nIHRoZSBjaGFyYWN0ZXIgZGlyZWN0bHkgdG8gdGhlIG1hcHBpbmcKICAgICAgICAvLyB0YWJsZSwgd2UgbXVzdCBhZGQgaXQgdG8gdGhlIGNvbnRyYWN0IHRhYmxlIGluc3RlYWQuCiAgICAgICAga2V5LnJlbW92ZSgpOwogICAgICAgIGtleSArPSBjaDsKICAgICAgICBpZiAoa2V5LmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGFkZENvbnRyYWN0T3JkZXIoa2V5LCBhbk9yZGVyLCBzdGF0dXMpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8vIGFkZCB0aGUgZW50cnkgdG8gdGhlIG1hcHBpbmcgdGFibGUsIHRoZSBzYW1lIGxhdGVyIGVudHJ5IHJlcGxhY2VzIHRoZSBwcmV2aW91cyBvbmUKICAgICAgICB1Y21wMzJfc2V0KGRhdGEtPm1hcHBpbmcsIGNoLCBhbk9yZGVyKTsKICAgIH0KfQoKLy8gQWRkIGFuIGV4cGFuZGluZy1jaGFyYWN0ZXIgZW50cnkgdG8gdGhlIHRhYmxlLgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjphZGRFeHBhbmRPcmRlciggIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgY29udHJhY3RDaGFycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmIGV4cGFuZENoYXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgYW5PcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gQ3JlYXRlIGFuIGV4cGFuc2lvbiB0YWJsZSBlbnRyeQogICAgaW50MzJfdCB0YWJsZUluZGV4ID0gYWRkRXhwYW5zaW9uKGFuT3JkZXIsIGV4cGFuZENoYXJzKTsKICAgIAogICAgLy8gQW5kIGFkZCBpdHMgaW5kZXggaW50byB0aGUgbWFpbiBtYXBwaW5nIHRhYmxlCiAgICBpZiAoY29udHJhY3RDaGFycy5sZW5ndGgoKSA+IDEpCiAgICB7CiAgICAgICAgYWRkQ29udHJhY3RPcmRlcihjb250cmFjdENoYXJzLCB0YWJsZUluZGV4LCBzdGF0dXMpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGFkZE9yZGVyKGNvbnRyYWN0Q2hhcnNbMF0sIHRhYmxlSW5kZXgsIHN0YXR1cyk7CiAgICB9Cn0KCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmFkZEV4cGFuc2lvbihpbnQzMl90IGFuT3JkZXIsIGNvbnN0IFVuaWNvZGVTdHJpbmcgJmV4cGFuZENoYXJzKQp7CiAgICBpZiAoZGF0YS0+ZXhwYW5kVGFibGUgPT0gTlVMTCkKICAgIHsKICAgICAgICBkYXRhLT5leHBhbmRUYWJsZSA9IG5ldyBWZWN0b3JPZlBUb0V4cGFuZFRhYmxlKCk7CgogICAgICAgIGlmIChkYXRhLT5leHBhbmRUYWJsZSA9PSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvLyBJZiBhbk9yZGVyIGlzIHZhbGlkLCB3ZSB3YW50IHRvIGFkZCBpdCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0CiAgICBpbnQzMl90IG9mZnNldCA9IChhbk9yZGVyID09IFVOTUFQUEVEKSA/IDAgOiAxOwogICAgCiAgICBWZWN0b3JPZkludCAqdmFsdWVMaXN0ID0gbmV3IFZlY3Rvck9mSW50KGV4cGFuZENoYXJzLmxlbmd0aCgpICsgb2Zmc2V0KTsKCiAgICBpZiAob2Zmc2V0ID09IDEpCiAgICB7CiAgICAgICAgdmFsdWVMaXN0LT5hdFB1dCgwLCBhbk9yZGVyKTsKICAgIH0KCiAgICBpbnQzMl90IGk7CiAgICBmb3IgKGkgPSAwOyBpIDwgZXhwYW5kQ2hhcnMubGVuZ3RoKCk7IGkgKz0gMSkKICAgIHsKICAgICAgICBVQ2hhciBjaCA9IGV4cGFuZENoYXJzW2ldOwogICAgICAgIGludDMyX3QgbWFwVmFsdWUgPSBnZXRDaGFyT3JkZXIoY2gpOwogICAgICAgIAogICAgICAgIGlmIChtYXBWYWx1ZSAhPSBVTk1BUFBFRCkKICAgICAgICB7CiAgICAgICAgICAgIHZhbHVlTGlzdC0+YXRQdXQoaSArIG9mZnNldCwgbWFwVmFsdWUpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvLyBjYW4ndCBmaW5kIGl0IGluIHRoZSB0YWJsZSwgd2lsbCBiZSBmaWxsZWQgaW4gYnkgY29tbWl0KCkuCiAgICAgICAgICAgIHZhbHVlTGlzdC0+YXRQdXQoaSArIG9mZnNldCwgQ0hBUklOREVYICsgKGludDMyX3QpY2gpOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBBZGQgdGhlIGV4cGFuZGluZyBjaGFyIGxpc3QgaW50byB0aGUgZXhwYW5zaW9uIHRhYmxlLgogICAgaW50MzJfdCB0YWJsZUluZGV4ID0gRVhQQU5EQ0hBUklOREVYICsgZGF0YS0+ZXhwYW5kVGFibGUtPnNpemUoKTsKICAgIGRhdGEtPmV4cGFuZFRhYmxlLT5hdFB1dChkYXRhLT5leHBhbmRUYWJsZS0+c2l6ZSgpLCB2YWx1ZUxpc3QpOwogICAgCiAgICByZXR1cm4gdGFibGVJbmRleDsKfQoKLy8gQWRkIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgdGhhdCBjb250cmFjdHMgaW50byBhIHNpbmdsZSBvcmRlcmluZy4Kdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6YWRkQ29udHJhY3RPcmRlcihjb25zdCAgIFVuaWNvZGVTdHJpbmcmIGdyb3VwQ2hhcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgYW5PcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbF90IGZ3ZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChkYXRhLT5jb250cmFjdFRhYmxlID09IE5VTEwpCiAgICB7CiAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZSA9IG5ldyBWZWN0b3JPZlBUb0NvbnRyYWN0VGFibGUoKTsKICAgICAgICBpZiAoZGF0YS0+Y29udHJhY3RUYWJsZS0+aXNCb2d1cygpKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIC8vIFNlZSBpZiB0aGUgaW5pdGlhbCBjaGFyYWN0ZXIgb2YgdGhlIHN0cmluZyBhbHJlYWR5IGhhcyBhIGNvbnRyYWN0IHRhYmxlLgogICAgLy8gZS5nLiBmb3IgImNoIiwgbG9vayBmb3IgJ2MnLgogICAgaW50MzJfdCBlbnRyeSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgZ3JvdXBDaGFyc1swXSk7CiAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCAqZW50cnlUYWJsZSA9IGdldENvbnRyYWN0VmFsdWVzKGVudHJ5IC0gQ09OVFJBQ1RDSEFSSU5ERVgpOwoKICAgIGlmIChlbnRyeVRhYmxlID09IE5VTEwpCiAgICB7CiAgICAgICAgLy8gV2UgbmVlZCB0byBjcmVhdGUgYSBuZXcgdGFibGUgb2YgY29udHJhY3QgZW50cmllcyBmb3IgdGhpcyBiYXNlIGNoYXIKICAgICAgICBpbnQzMl90IHRhYmxlSW5kZXggPSBDT05UUkFDVENIQVJJTkRFWCArIGRhdGEtPmNvbnRyYWN0VGFibGUtPnNpemUoKTsKICAgICAgICBFbnRyeVBhaXIgKnBhaXIgPSBOVUxMOwogICAgICAgIFVuaWNvZGVTdHJpbmcgc3Vic3RyaW5nOwoKICAgICAgICBlbnRyeVRhYmxlID0gbmV3IFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KCk7CiAgICAgICAgaWYgKGVudHJ5VGFibGUtPmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBlbnRyeVRhYmxlOwogICAgICAgICAgICBkZWxldGUgZGF0YS0+Y29udHJhY3RUYWJsZTsKICAgICAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZSA9IE5VTEw7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUtPmF0UHV0KGRhdGEtPmNvbnRyYWN0VGFibGUtPnNpemUoKSwgZW50cnlUYWJsZSk7CiAgICAgICAgaWYgKGRhdGEtPmNvbnRyYWN0VGFibGUtPmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBlbnRyeVRhYmxlOwogICAgICAgICAgICBkZWxldGUgZGF0YS0+Y29udHJhY3RUYWJsZTsKICAgICAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZSA9IE5VTEw7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgICAgIAoKICAgICAgICAvLyBBZGQgdGhlIGluaXRpYWwgY2hhcmFjdGVyJ3MgY3VycmVudCBvcmRlcmluZyBmaXJzdC4gdGhlbgogICAgICAgIC8vIHVwZGF0ZSBpdHMgbWFwcGluZyB0byBwb2ludCB0byB0aGlzIGNvbnRyYWN0IHRhYmxlCiAgICAgICAgZ3JvdXBDaGFycy5leHRyYWN0KDAsIDEsIHN1YnN0cmluZyk7CiAgICAgICAgaWYgKHN1YnN0cmluZy5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZW50cnlUYWJsZTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBwYWlyID0gbmV3IEVudHJ5UGFpcihzdWJzdHJpbmcsIGVudHJ5KTsKCiAgICAgICAgZW50cnlUYWJsZS0+YXRQdXQoMCwgcGFpcik7CiAgICAgICAgaWYgKGVudHJ5VGFibGUtPmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBlbnRyeVRhYmxlOwogICAgICAgICAgICBkZWxldGUgZGF0YS0+Y29udHJhY3RUYWJsZTsKICAgICAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZSA9IE5VTEw7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHVjbXAzMl9zZXQoZGF0YS0+bWFwcGluZywgZ3JvdXBDaGFyc1swXSwgdGFibGVJbmRleCk7CiAgICB9CgogICAgLy8gTm93IGFkZCAob3IgcmVwbGFjZSkgdGhpcyBzdHJpbmcgaW4gdGhlIHRhYmxlCiAgICBpbnQzMl90IGluZGV4ID0gZ2V0RW50cnkoZW50cnlUYWJsZSwgZ3JvdXBDaGFycywgZndkKTsKCiAgICBpZiAoaW5kZXggIT0gVU5NQVBQRUQpCiAgICB7CiAgICAgICAgRW50cnlQYWlyICpwYWlyID0gKEVudHJ5UGFpciAqKSBlbnRyeVRhYmxlLT5hdChpbmRleCk7CiAgICAgICAgcGFpci0+dmFsdWUgPSBhbk9yZGVyOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIEVudHJ5UGFpciAqcGFpciA9IG5ldyBFbnRyeVBhaXIoZ3JvdXBDaGFycywgYW5PcmRlciwgZndkKTsKCiAgICAgICAgZW50cnlUYWJsZS0+YXRQdXQoZW50cnlUYWJsZS0+c2l6ZSgpLCBwYWlyKTsKICAgIH0KICAgIAogICAgLy8gSWYgdGhpcyB3YXMgYSBmb3J3YXJkIG1hcHBpbmcgZm9yIGEgY29udHJhY3Rpbmcgc3RyaW5nLCBhbHNvIGFkZCBhCiAgICAvLyByZXZlcnNlIG1hcHBpbmcgZm9yIGl0LCBzbyB0aGF0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJldmlvdXMKICAgIC8vIGNhbiB3b3JrIHJpZ2h0CiAgICBpZiAoZndkKQogICAgewogICAgICAgIFVuaWNvZGVTdHJpbmcgcmV2ZXJzZShncm91cENoYXJzKTsKCiAgICAgICAgaWYgKHJldmVyc2UuaXNCb2d1cygpKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGVudHJ5VGFibGU7CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhLT5jb250cmFjdFRhYmxlOwogICAgICAgICAgICBkYXRhLT5jb250cmFjdFRhYmxlID0gTlVMTDsKICAgICAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgYWRkQ29udHJhY3RPcmRlcihyZXZlcnNlLnJldmVyc2UoKSwgYW5PcmRlciwgRkFMU0UsIHN0YXR1cyk7CiAgICB9Cn0KCi8qKgogKiBJZiB0aGUgZ2l2ZW4gc3RyaW5nIGhhcyBiZWVuIHNwZWNpZmllZCBhcyBhIGNvbnRyYWN0aW5nIHN0cmluZwogKiBpbiB0aGlzIGNvbGxhdGlvbiB0YWJsZSwgcmV0dXJuIGl0cyBvcmRlcmluZy4KICogT3RoZXJ3aXNlIHJldHVybiBVTk1BUFBFRC4KICovCiBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb250cmFjdE9yZGVyKGNvbnN0IFVuaWNvZGVTdHJpbmcgJmdyb3VwQ2hhcnMpIGNvbnN0CnsKICAgIGludDMyX3QgcmVzdWx0ID0gVU5NQVBQRUQ7CgogICAgaWYgKGRhdGEtPmNvbnRyYWN0VGFibGUgIT0gTlVMTCkKICAgIHsKICAgICAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCAqZW50cnlUYWJsZSA9IGdldENvbnRyYWN0VmFsdWVzKGdyb3VwQ2hhcnNbMF0pOwoKICAgICAgICBpZiAoZW50cnlUYWJsZSAhPSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgaW50MzJfdCBpbmRleCA9IGdldEVudHJ5KGVudHJ5VGFibGUsIGdyb3VwQ2hhcnMsIFRSVUUpOwoKICAgICAgICAgICAgaWYgKGluZGV4ICE9IFVOTUFQUEVEKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBFbnRyeVBhaXIgKnBhaXIgPSBlbnRyeVRhYmxlLT5hdChpbmRleCk7CgogICAgICAgICAgICAgICAgcmVzdWx0ID0gcGFpci0+dmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJlc3VsdDsKfQoKaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q2hhck9yZGVyKFVDaGFyIGNoKSBjb25zdAp7CiAgICBpbnQzMl90IG9yZGVyID0gdWNtcDMyX2dldChkYXRhLT5tYXBwaW5nLCBjaCk7CiAgICAKICAgIGlmIChvcmRlciA+PSBDT05UUkFDVENIQVJJTkRFWCkKICAgIHsKICAgICAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCAqZ3JvdXBMaXN0ID0gZ2V0Q29udHJhY3RWYWx1ZXMob3JkZXIgLSBDT05UUkFDVENIQVJJTkRFWCk7CiAgICAgICAgRW50cnlQYWlyICpwYWlyID0gZ3JvdXBMaXN0LT5hdCgwKTsKCiAgICAgICAgb3JkZXIgPSBwYWlyLT52YWx1ZTsKICAgIH0KCiAgICByZXR1cm4gb3JkZXI7Cn0KICAgIAovLyBDcmVhdGUgYSBoYXNoIGNvZGUgZm9yIHRoaXMgY29sbGF0aW9uLiAgSnVzdCBoYXNoIHRoZSBtYWluIHJ1bGUgdGFibGUgLS0KLy8gdGhhdCBzaG91bGQgYmUgZ29vZCBlbm91Z2ggZm9yIGFsbW9zdCBhbnkgdXNlLgppbnQzMl90ClJ1bGVCYXNlZENvbGxhdG9yOjpoYXNoQ29kZSgpIGNvbnN0CnsKICAgIGludDMyX3QgICAgICAgICB2YWx1ZSA9IDA7CiAgICBpbnQzMl90ICAgICAgICAgYzsKICAgIGludDMyX3QgICAgICAgICBjb3VudCA9IGdldFJ1bGVzKCkubGVuZ3RoKCk7CiAgICBVVGV4dE9mZnNldCAgICAgIHBvcyA9IGNvdW50IC0gMTsKCiAgICBpZiAoY291bnQgPiA2NCkKICAgIHsKICAgICAgICBjb3VudCA9IDY0OyAvLyBvbmx5IGhhc2ggdXB0byBsaW1pdAogICAgfQoKICAgIGludDE2X3QgaSA9IDA7CgogICAgd2hpbGUgKGkgPCBjb3VudCkKICAgIHsKICAgICAgICBjID0gZGF0YS0+cnVsZVRhYmxlW3Bvc107CiAgICAgICAgdmFsdWUgPSAoKHZhbHVlIDw8IChjICYgMHgwZikpIF4gKGMgPDwgOCkpICsgKGMgXiB2YWx1ZSk7CiAgICAgICAgaSArPSAxOwogICAgICAgIHBvcyAtPSAxOwogICAgfQoKICAgIGlmICh2YWx1ZSA9PSAwKQogICAgewogICAgICAgIHZhbHVlID0gMTsKICAgIH0KCiAgICByZXR1cm4gdmFsdWU7Cn0KCi8vIGZpbmQgdGhlIGNvbnRyYWN0aW5nIGNoYXIgZW50cnkgaW4gdGhlIGxpc3QKaW50MzJfdApSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0RW50cnkoVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQqIGxpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgYm9vbF90IGZ3ZCkKewogICAgaW50MzJfdCBpOwoKICAgIGlmIChsaXN0ICE9IE5VTEwpCiAgICB7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3QtPnNpemUoKTsgaSArPSAxKQogICAgICAgIHsKICAgICAgICAgICAgRW50cnlQYWlyICpwYWlyID0gbGlzdC0+YXQoaSk7CgogICAgICAgICAgICBpZiAoKHBhaXIgIT0gTlVMTCkgJiYgKHBhaXItPmZ3ZCA9PSBmd2QpICYmIChwYWlyLT5lbnRyeU5hbWUgPT0gbmFtZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBSdWxlQmFzZWRDb2xsYXRvcjo6VU5NQVBQRUQ7Cn0KCi8vIGxvb2sgZm9yIHRoZSBjb250cmFjdGluZyBsaXN0IGVudHJ5IHdpdGggdGhlIGJlZ2lubmluZyBjaGFyClZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KgpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29udHJhY3RWYWx1ZXMoVUNoYXIgY2gpIGNvbnN0CnsKICAgIGludDMyX3QgaW5kZXggPSB1Y21wMzJfZ2V0KGRhdGEtPm1hcHBpbmcsIGNoKTsKICAgIHJldHVybiBnZXRDb250cmFjdFZhbHVlcyhpbmRleCAtIENPTlRSQUNUQ0hBUklOREVYKTsKfQoKLy8gbG9vayBmb3IgdGhlIGNvbnRyYWN0aW5nIGxpc3QgZW50cnkgd2l0aCB0aGUgaW5kZXgKVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQqClJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb250cmFjdFZhbHVlcyhpbnQzMl90ICAgIGluZGV4KSBjb25zdAp7CiAgICBpZiAoZGF0YS0+Y29udHJhY3RUYWJsZSAhPSBOVUxMKQogICAgewogICAgICAgIGlmIChpbmRleCA+PSAwKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGRhdGEtPmNvbnRyYWN0VGFibGUtPmF0KGluZGV4KTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqCiAgKiBSZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFueSBleHBhbnNpb24gc2VxdWVuY2VzIHRoYXQgZW5kCiAgKiB3aXRoIHRoZSBzcGVjaWZpZWQgY29tcGFyaXNvbiBvcmRlci4KICAqCiAgKiBAcGFyYW0gb3JkZXIgYSBjb2xsYXRpb24gb3JkZXIgcmV0dXJuZWQgYnkgcHJldmlvdXMgb3IgbmV4dC4KICAqIEByZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFueSBleHBhbnNpb24gc2V1ZW5jZXMgZW5kaW5nCiAgKiAgICAgICAgIHdpdGggdGhlIHNwZWNpZmllZCBvcmRlci4KICAqCiAgKiBAc2VlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciNnZXRNYXhFeHBhbnNpb24KICAqLwppbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3QKewogICAgaW50MzJfdCByZXN1bHQgPSAxOwogICAgCiAgICBpZiAoZGF0YS0+ZXhwYW5kVGFibGUgIT0gTlVMTCkKICAgIHsKICAgICAgICAvLyBSaWdodCBub3cgdGhpcyBkb2VzIGEgbGluZWFyIHNlYXJjaCB0aHJvdWdoIHRoZSBlbnRpcmUKICAgICAgICAvLyBleHBhbmRzaW9uIHRhYmxlLiAgSWYgYSBjb2xsYXRvciBoYWQgYSBsYXJnZSBudW1iZXIgb2YgZXhwYW5zaW9ucywKICAgICAgICAvLyB0aGlzIGNvdWxkIGNhdXNlIGEgcGVyZm9ybWFuY2UgcHJvYmxlbSwgYnV0IGluIHByYWN0aWNlIHRoYXQKICAgICAgICAvLyByYXJlbHkgaGFwcGVucwogICAgICAgIGludDMyX3QgaTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZGF0YS0+ZXhwYW5kVGFibGUtPnNpemUoKTsgaSArPSAxKQogICAgICAgIHsKICAgICAgICAgICAgVmVjdG9yT2ZJbnQgKnZhbHVlTGlzdCA9IGRhdGEtPmV4cGFuZFRhYmxlLT5hdChpKTsKICAgICAgICAgICAgaW50MzJfdCBsZW5ndGggPSB2YWx1ZUxpc3QtPnNpemUoKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChsZW5ndGggPiByZXN1bHQgJiYgdmFsdWVMaXN0LT5hdChsZW5ndGgtMSkgPT0gb3JkZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IGxlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9CiAgICAKLyoqCiAqICBHZXQgdGhlIGVudHJ5IG9mIGhhc2ggdGFibGUgb2YgdGhlIGV4cGFuZGluZyBzdHJpbmcgaW4gdGhlIGNvbGxhdGlvbgogKiAgdGFibGUuCiAqICBAcGFyYW0gaWR4IHRoZSBpbmRleCBvZiB0aGUgZXhwYW5kaW5nIHN0cmluZyB2YWx1ZSBsaXN0CiAqLwpWZWN0b3JPZkludCAqUnVsZUJhc2VkQ29sbGF0b3I6OmdldEV4cGFuZFZhbHVlTGlzdChpbnQzMl90IG9yZGVyKSBjb25zdAp7CiAgICByZXR1cm4gZGF0YS0+ZXhwYW5kVGFibGUtPmF0KG9yZGVyIC0gRVhQQU5EQ0hBUklOREVYKTsKfQoKCgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbUluKFJ1bGVCYXNlZENvbGxhdG9yKiBjb2xsYXRvciwgRmlsZVN0cmVhbSogaXMpCnsKICAgIGlmICghVF9GaWxlU3RyZWFtX2Vycm9yKGlzKSkKICAgIHsKICAgICAgICAvLyBDaGVjayB0aGF0IHRoaXMgaXMgdGhlIGNvcnJlY3QgZmlsZSB0eXBlCiAgICAgICAgaW50MTZfdCBpZDsKCiAgICAgICAgVF9GaWxlU3RyZWFtX3JlYWQoaXMsICZpZCwgc2l6ZW9mKGlkKSk7CiAgICAgICAgaWYgKGlkICE9IGNvbGxhdG9yLT5GSUxFSUQpCiAgICAgICAgewogICAgICAgICAgICAvLyBUaGlzIGlzbid0IHRoZSByaWdodCB0eXBlIG9mIGZpbGUuICBNYXJrIHRoZSBpb3MKICAgICAgICAgICAgLy8gYXMgZmFpbGluZyBhbmQgcmV0dXJuLgogICAgICAgICAgICBUX0ZpbGVTdHJlYW1fc2V0RXJyb3IoaXMpOyAvLyBmb3JjZSB0aGUgc3RyZWFtIHRvIHNldCBpdHMgZXJyb3IgZmxhZwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBTdHJlYW0gaW4gbGFyZ2Ugb2JqZWN0cwogICAgICAgIGNoYXIgaXNOdWxsOwoKICAgICAgICBUX0ZpbGVTdHJlYW1fcmVhZChpcywgJmlzTnVsbCwgc2l6ZW9mKGlzTnVsbCkpOwogICAgICAgIGlmIChpc051bGwpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgY29sbGF0b3ItPmRhdGE7CiAgICAgICAgICAgIGNvbGxhdG9yLT5kYXRhID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGNvbGxhdG9yLT5kYXRhID09IE5VTEwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbGxhdG9yLT5kYXRhID0gbmV3IFRhYmxlQ29sbGF0aW9uRGF0YTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgY29sbGF0b3ItPmRhdGEtPnN0cmVhbUluKGlzKTsKICAgICAgICAgICAgaWYgKGNvbGxhdG9yLT5kYXRhLT5pc0JvZ3VzKCkpIHsKICAgICAgICAgICAgICAgIFRfRmlsZVN0cmVhbV9zZXRFcnJvcihpcyk7IC8vIGZvcmNlIHRoZSBzdHJlYW0gdG8gc2V0IGl0cyBlcnJvciBmbGFnCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBlbmQgbWFya2VyIGlzIHByZXNlbnQKICAgICAgICBUX0ZpbGVTdHJlYW1fcmVhZChpcywgJmlkLCBzaXplb2YoaWQpKTsKICAgICAgICBpZiAoaWQgIT0gY29sbGF0b3ItPkZJTEVJRCkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFRoaXMgaXNuJ3QgdGhlIHJpZ2h0IHR5cGUgb2YgZmlsZS4gIE1hcmsgdGhlIGlvcwogICAgICAgICAgICAvLyBhcyBmYWlsaW5nIGFuZCByZXR1cm4uCiAgICAgICAgICAgIFRfRmlsZVN0cmVhbV9zZXRFcnJvcihpcyk7IC8vIGZvcmNlIHRoZSBzdHJlYW0gdG8gc2V0IGl0cyBlcnJvciBmbGFnCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIFJlc2V0IG90aGVyIGRhdGEgbWVtYmVycwogICAgICAgIGNvbGxhdG9yLT5pc092ZXJJZ25vcmUgPSBGQUxTRTsKICAgICAgICBjb2xsYXRvci0+bGFzdENoYXIgPSAwOwogICAgICAgIGRlbGV0ZSBjb2xsYXRvci0+bVBhdHRlcm47CiAgICAgICAgY29sbGF0b3ItPm1QYXR0ZXJuID0gMDsKICAgICAgICBjb2xsYXRvci0+a2V5LnJlbW92ZSgpOwogICAgICAgIGNvbGxhdG9yLT5kYXRhSXNPd25lZCA9IFRSVUU7CiAgICB9Cn0KCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtT3V0KGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yKiBjb2xsYXRvciwgRmlsZVN0cmVhbSogb3MpCnsKICAgIGlmICghVF9GaWxlU3RyZWFtX2Vycm9yKG9zKSkKICAgIHsKICAgICAgICAvLyBXZSB1c2UgYSAxNi1iaXQgSUQgY29kZSB0byBpZGVudGlmeSB0aGlzIGZpbGUuCiAgICAgICAgaW50MTZfdCBpZCA9IGNvbGxhdG9yLT5GSUxFSUQ7CiAgICAgICAgVF9GaWxlU3RyZWFtX3dyaXRlKG9zLCAmaWQsIHNpemVvZihpZCkpOwoKICAgICAgICAvLyBTdHJlYW0gb3V0IHRoZSBkYXRhCiAgICAgICAgY2hhciBpc051bGw7CiAgICAgICAgaXNOdWxsID0gKGNvbGxhdG9yLT5kYXRhID09IDApOwogICAgICAgIFRfRmlsZVN0cmVhbV93cml0ZShvcywgJmlzTnVsbCwgc2l6ZW9mKGlzTnVsbCkpOwoKICAgICAgICBpZiAoIWlzTnVsbCkKICAgICAgICB7CiAgICAgICAgICAgIGNvbGxhdG9yLT5kYXRhLT5zdHJlYW1PdXQob3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gV3JpdGUgb3V0IHRoZSBJRCB0byBpbmRpY2F0ZSB0aGUgZW5kCiAgICAgICAgVF9GaWxlU3RyZWFtX3dyaXRlKG9zLCAmaWQsIHNpemVvZihpZCkpOwogICAgfQp9Cgpib29sX3QgUnVsZUJhc2VkQ29sbGF0b3I6OndyaXRlVG9GaWxlKGNvbnN0IGNoYXIqIGZpbGVOYW1lKSBjb25zdAp7CiAgICBGaWxlU3RyZWFtKiBvZnMgPSBUX0ZpbGVTdHJlYW1fb3BlbihmaWxlTmFtZSwgIndiIik7CiAgICBpZiAob2ZzICE9IDApCiAgICB7CiAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtT3V0KHRoaXMsIG9mcyk7CiAgICB9CgojaWZkZWYgQ09MTERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgImJpbmFyeSB3cml0ZSAlcyBzaXplICVkICVzXG4iLCBmaWxlTmFtZSwgVF9GaWxlU3RyZWFtX3NpemUob2ZzKSwKICAgICAgICAoIVRfRmlsZVN0cmVhbV9lcnJvcihvZnMpID8gIiwgT0siIDogIiwgRkFJTCIpKTsKI2VuZGlmCgogICAgYm9vbF90IGVyciA9IFRfRmlsZVN0cmVhbV9lcnJvcihvZnMpID09IDA7CgogICAgVF9GaWxlU3RyZWFtX2Nsb3NlKG9mcyk7CiAgICByZXR1cm4gZXJyOwp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjphZGRUb0NhY2hlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIGtleSkKewogICAgLy8gVGhpcyBtZXRob2QgZG9lc24ndCBhZGQgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIGl0c2VsZiB0byB0aGUgY2FjaGUuICBJbnN0ZWFkLAogICAgLy8gaXQgYWRkcyB0aGUgZ2l2ZW4gUnVsZUJhc2VkQ29sbGF0b3IncyBkYXRhIG9iamVjdCB0byB0aGUgVGFibGVDb2xsYXRpb25EYXRhCiAgICAvLyBjYWNoZSwgYW5kIG1hcmtzIGl0IGFzIG5vbi1vd25lZCBpbiB0aGUgZ2l2ZW4gUnVsZUJhc2VkQ29sbGF0b3Igb2JqZWN0LgogICAgVGFibGVDb2xsYXRpb25EYXRhOjphZGRUb0NhY2hlKGtleSwgZGF0YSk7CiAgICBkYXRhSXNPd25lZCA9IEZBTFNFOwp9Cgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tQ2FjaGUoY29uc3QgVW5pY29kZVN0cmluZyYga2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgLy8gQXR0ZW1wdCB0byBjb25zdHJ1Y3QgdGhpcyBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QgZnJvbSBjYWNoZWQgVGFibGVDb2xsYXRpb25EYXRhLgogICAgLy8gSWYgbm8gc3VjaCBkYXRhIGlzIGluIHRoZSBjYWNoZSwgcmV0dXJuIGZhbHNlLgogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IE5VTEw7CiAgICB9CgogICAgaXNPdmVySWdub3JlID0gRkFMU0U7CiAgICBsYXN0Q2hhciA9IDA7CiAgICBtUGF0dGVybiA9IDA7CiAgICBzZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOwoKICAgIGRhdGFJc093bmVkID0gRkFMU0U7CiAgICBkYXRhID0gVGFibGVDb2xsYXRpb25EYXRhOjpmaW5kSW5DYWNoZShrZXkpOwogICAgaWYgKGRhdGEgPT0gTlVMTCkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CiAgICB9Cn0KCmNoYXIqClJ1bGVCYXNlZENvbGxhdG9yOjpjcmVhdGVQYXRoTmFtZSggIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIHByZWZpeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiAgICBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIHN1ZmZpeCkKewogICAgLy8gQ29uY2F0ZW5hdGUgdGhyZWUgZWxlbWVudHMgdG8gZm9ybSBhIGZpbGUgbmFtZSwgYW5kIHJldHVybiBpdC4KCiAgICBVbmljb2RlU3RyaW5nICAgd29ya2luZ05hbWUocHJlZml4KTsKICAgIGludDMyX3QgICAgICAgICBzaXplOwogICAgY2hhciogICAgICAgICAgIHJldHVyblZhbDsKCiAgICB3b3JraW5nTmFtZSArPSBuYW1lOwogICAgd29ya2luZ05hbWUgKz0gc3VmZml4OwoKICAgIHNpemUgPSB3b3JraW5nTmFtZS5sZW5ndGgoKTsKICAgIHJldHVyblZhbCA9IG5ldyBjaGFyW3NpemUgKyAxXTsKICAgIHdvcmtpbmdOYW1lLmV4dHJhY3QoMCwgc2l6ZSwgcmV0dXJuVmFsLCAiIik7CiAgICByZXR1cm5WYWxbc2l6ZV0gPSAwOwoKICAgIHJldHVybiByZXR1cm5WYWw7Cn0KCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmNob3BMb2NhbGUoVW5pY29kZVN0cmluZyYgbG9jYWxlTmFtZSkKewogICAgLy8gY2hvcExvY2FsZSByZW1vdmVzIHRoZSBmaW5hbCBlbGVtZW50IGZyb20gYSBsb2NhbGUgc3RyaW5nLgogICAgLy8gRm9yIGluc3RhbmNlLCAiZGVfQ0giIGJlY29tZXMgImRlIiwgYW5kICJkZSIgYmVjb21lcyAiIi4KICAgIC8vICIiIHJlbWFpbnMgIiIuCgogICAgaW50MzJfdCAgICAgc2l6ZSA9IGxvY2FsZU5hbWUubGVuZ3RoKCk7CiAgICBpbnQzMl90ICAgICBpOwoKICAgIGZvciAoaSA9IHNpemUgLSAxOyBpID4gMDsgaS0tKQogICAgewogICAgICAgIGlmIChsb2NhbGVOYW1lW2ldID09IDB4MDA1RikKICAgICAgICB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoaSA8IDApCiAgICB7CiAgICAgICAgaSA9IDA7CiAgICB9CgogICAgbG9jYWxlTmFtZS5yZW1vdmUoaSwgc2l6ZSAtIGkpOwp9CgovL2VvZgo=