LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIENvcHlyaWdodCAoQykgMTk5Ni0xOTk5LCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqCiogRmlsZSB0Ymxjb2xsLmNwcAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWggCioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICBEYXRlICAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgoqICAyLzUvOTcgICAgICBhbGl1ICAgICAgICBBZGRlZCBzdHJlYW1JbiBhbmQgc3RyZWFtT3V0IG1ldGhvZHMuICBBZGRlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciB3aGljaCByZWFkcyBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QgZnJvbQoqICAgICAgICAgICAgICAgICAgICAgICAgICBhIGJpbmFyeSBmaWxlLiAgQWRkZWQgd3JpdGVUb0ZpbGUgbWV0aG9kIHdoaWNoIHN0cmVhbXMKKiAgICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3Igb3V0IHRvIGEgYmluYXJ5IGZpbGUuICBUaGUgc3RyZWFtSW4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIHN0cmVhbU91dCBtZXRob2RzIHVzZSBpc3RyZWFtIGFuZCBvc3RyZWFtIG9iamVjdHMKKiAgICAgICAgICAgICAgICAgICAgICAgICAgaW4gYmluYXJ5IG1vZGUuCiogIDIvMTEvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIGRlY2xhcmF0aW9ucyBvdXQgb2YgZm9yIGxvb3AgaW5pdGlhbGl6ZXIuCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIE1hYyBjb21wYXRpYmlsaXR5ICNpZmRlZiBmb3IgaW9zOjpub2NyZWF0ZS4KKiAgMi8xMi85NyAgICAgYWxpdSAgICAgICAgTW9kaWZpZWQgdG8gdXNlIFRhYmxlQ29sbGF0aW9uRGF0YSBzdWItb2JqZWN0IHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIGhvbGQgaW52YXJpYW50IGRhdGEuCiogIDIvMTMvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIHNldmVyYWwgbWV0aG9kcyBpbnRvIHRoaXMgY2xhc3MgZnJvbSBDb2xsYXRpb24uCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIGEgcHJpdmF0ZSBSdWxlQmFzZWRDb2xsYXRvcihMb2NhbGUmKSBjb25zdHJ1Y3RvciwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gYmUgdXNlZCBieSBDb2xsYXRvcjo6Z2V0SW5zdGFuY2UoKS4gIEdlbmVyYWwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYW4gdXAuICBNYWRlIHVzZSBvZiBVRXJyb3JDb2RlIHZhcmlhYmxlcyBjb25zaXN0ZW50LgoqICAyLzIwLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjbG9uZSwgb3BlcmF0b3I9PSwgb3BlcmF0b3IhPSwgb3BlcmF0b3I9LCBhbmQgY29weQoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciBhbmQgZ2V0RHluYW1pY0NsYXNzSUQuCiogIDMvNS85NyAgICAgIGFsaXUgICAgICAgIENoYW5nZWQgY29tcGFjdGlvbiBjeWNsZSB0byBpbXByb3ZlIHBlcmZvcm1hbmNlLiAgV2UKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlIHRoZSBtYXhpbXVtIGFsbG93YWJsZSB2YWx1ZSB3aGljaCBpcyBrQmxvY2tDb3VudC4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgTW9kaWZpZWQgZ2V0UnVsZXMoKSB0byBsb2FkIHJ1bGVzIGR5bmFtaWNhbGx5LiAgQ2hhbmdlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RGcm9tRmlsZSgpIGNhbGwgdG8gYWNjb21vZGF0ZSB0aGlzIChhZGRlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgdG8gc3BlY2lmeSB3aGV0aGVyIGJpbmFyeSBsb2FkaW5nIGlzIHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIHRha2UgcGxhY2UpLgoqIDA1LzA2Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBtZW1vcnkgYWxsb2NhdGlvbiBlcnJvciBjaGVjay4KKiAgNi8yMC85NyAgICAgaGVsZW5hICAgICAgSmF2YSBjbGFzcyBuYW1lIGNoYW5nZS4KKiAgNi8yMy85NyAgICAgaGVsZW5hICAgICAgQWRkaW5nIGNvbW1lbnRzIHRvIG1ha2UgY29kZSBtb3JlIHJlYWRhYmxlLgoqIDA5LzAzLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjcmVhdGVDb2xsYXRpb25LZXlWYWx1ZXMoKS4KKiAwNi8yNi85OCAgICAgZXJtICAgICAgICAgQ2hhbmdlcyBmb3IgQ29sbGF0aW9uS2V5cyB1c2luZyBieXRlIGFycmF5cy4KKiAwOC8xMC85OCAgICAgZXJtICAgICAgICAgU3luY2hlZCB3aXRoIDEuMiB2ZXJzaW9uIG9mIFJ1bGVCYXNlZENvbGxhdG9yLmphdmEKKiAwNC8yMy85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBFRGVjb21wb3NpdGlvbk1vZGUsIG1lcmdlZCB3aXRoCiogICAgICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlCiogMDYvMTQvOTkgICAgIHN0ZXBoZW4gICAgIFJlbW92ZWQga1Jlc291cmNlQnVuZGxlU3VmZml4CiogMDYvMjIvOTkgICAgIHN0ZXBoZW4gICAgIEZpeGVkIGxvZ2ljIGluIGNvbnN0cnVjdEZyb21GaWxlKCkgc2luY2UgLmN0eAoqICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlcyBhcmUgbm8gbG9uZ2VyIHVzZWQuCiogMTEvMDIvOTkgICAgIGhlbGVuYSAgICAgIENvbGxhdG9yIHBlcmZvcm1hbmNlIGVuaGFuY2VtZW50cy4gIFNwZWNpYWwgY2FzZQoqICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgTk9fT1Agc2l0dWF0aW9ucy4gCiogMTEvMTcvOTkgICAgIHNybCAgICAgICAgIE1vcmUgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiBJbmxpbmVkIHNvbWUgaW50ZXJuYWwgZnVuY3Rpb25zLgoqIDEyLzE1Lzk5ICAgICBhbGl1ICAgICAgICBVcGRhdGUgdG8gc3VwcG9ydCBUaGFpIGNvbGxhdGlvbi4gIE1vdmUgTm9ybWFsaXplckl0ZXJhdG9yCiogICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGltcGxlbWVudGF0aW9uIGZpbGUuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCiNpbmNsdWRlICJ1Y21wMzIuaCIKI2luY2x1ZGUgInRjb2xkYXRhLmgiCgojaW5jbHVkZSAidWNvbGltcC5oIgoKI2luY2x1ZGUgInVuaWNvZGUvdGJsY29sbC5oIgoKI2luY2x1ZGUgInVuaWNvZGUvY29sZWl0ci5oIgojaW5jbHVkZSAidW5pY29kZS9sb2NpZC5oIgojaW5jbHVkZSAidW5pY29kZS91bmljb2RlLmgiCiNpbmNsdWRlICJ0YWJsZXMuaCIKI2luY2x1ZGUgInVuaWNvZGUvbm9ybWx6ci5oIgojaW5jbHVkZSAibWVyZ2Vjb2wuaCIKI2luY2x1ZGUgInVuaWNvZGUvcmVzYnVuZC5oIgojaW5jbHVkZSAiZmlsZXN0cm0uaCIKI2luY2x1ZGUgInVtZW1zdHJtLmgiCiNpbmNsdWRlICJ1bXV0ZXguaCIKI2luY2x1ZGUgImNtZW1vcnkuaCIKCiNpZmRlZiBfREVCVUcKI2luY2x1ZGUgInVuaXN0cm0uaCIKI2VuZGlmCgojaW5jbHVkZSAiY29tcGl0ci5oIgoKI2luY2x1ZGUgPHN0cmluZy5oPgoKI2luY2x1ZGUgInVuaWNvZGUvdXN0cmluZy5oIgoKI2luY2x1ZGUgImNtZW1vcnkuaCIKCmNvbnN0IHVpbnQzMl90IHRibGNvbGxfU3RhY2tCdWZmZXJMZW4gPSAxMDI0OwoKY2xhc3MgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcgp7CnB1YmxpYzoKICAgc3RhdGljIHZvaWQgc3RyZWFtSW4oUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBGaWxlU3RyZWFtKiBpcyk7CiAgIHN0YXRpYyB2b2lkIHN0cmVhbU91dChjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogY29sbGF0b3IsIEZpbGVTdHJlYW0qIG9zKTsKICAgc3RhdGljIHZvaWQgc3RyZWFtSW4oUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBVTWVtb3J5U3RyZWFtKiBpcywgVUVycm9yQ29kZSYgc3RhdHVzKTsKICAgc3RhdGljIHZvaWQgc3RyZWFtT3V0KGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yKiBjb2xsYXRvciwgVU1lbW9yeVN0cmVhbSogb3MpOwp9OwoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vICBUaGUgZm9sbG93aW5nIGRpYWdyYW0gc2hvd3MgdGhlIGRhdGEgc3RydWN0dXJlIG9mIHRoZSBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QuCi8vICBTdXBwb3NlIHdlIGhhdmUgdGhlIHJ1bGUsIHdoZXJlICdvLXVtbGF1dCcgaXMgdGhlIHVuaWNvZGUgY2hhciAweDAwRjYuCi8vICAiYSwgQSA8IGIsIEIgPCBjLCBDLCBjaCwgY0gsIENoLCBDSCA8IGQsIEQgLi4uIDwgbywgTzsgJ28tdW1sYXV0Jy9FLCAnTy11bWxhdXQnL0UgLi4uIi4KLy8gIFdoYXQgdGhlIHJ1bGUgc2F5cyBpcywgc29ydHMgJ2NoJ2xpZ2F0dXJlcyBhbmQgJ2MnIG9ubHkgd2l0aCB0ZXJ0aWFyeSBkaWZmZXJlbmNlIGFuZAovLyAgc29ydHMgJ28tdW1sYXV0JyBhcyBpZiBpdCdzIGFsd2F5cyBleHBhbmRlZCB3aXRoICdlJy4KLy8KLy8gbWFwcGluZyB0YWJsZSAgICAgICAgICAgICAgICAgICAgICAgY29udHJhY3RpbmcgbGlzdCAgICAgICAgICAgICAgICAgIGV4cGFuZGluZyBsaXN0Ci8vIChjb250YWlucyBhbGwgdW5pY29kZSBjaGFyCi8vICBlbnRyaWVzKSAgICAgICAgICAgICAgICAgICAgICAgICBfX18gICAgIF9fX19fX19fX19fX18gICAgICAgICBfX19fX19fX19fX19fX19fX19fX19fX19fCi8vICAgX19fX19fX18gICAgICAgICAgICAgICAgICAgfD09PnxfKl98LS0+fCdjJyAgfHYoJ2MnKSB8ICAgfD09Pnx2KCdvJyl8digndW1sYXV0Jyl8dignZScpfAovLyAgfF9cdTAwMDFffC0tPiB2KCdcdTAwMDEnKSAgIHwgICB8XzpffCAgIHwtLS0tLS0tLS0tLS0tfCAgIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKLy8gIHxfXHUwMDAyX3wtLT4gdignXHUwMDAyJykgICB8ICAgfF86X3wgICB8J2NoJyB8dignY2gnKXwgICB8ICAgfCAgICAgICAgICAgICA6ICAgICAgICAgICB8Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgfCAgIHxfOl98ICAgfC0tLS0tLS0tLS0tLS18ICAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAovLyAgfF9fX186X19ffCAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgIHwnY0gnIHx2KCdjSCcpfCAgIHwgICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKLy8gIHxfXydhJ19fX3wtLT4gdignYScpICAgICAgICB8ICAgICAgICAgICB8LS0tLS0tLS0tLS0tLXwgICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Ci8vICB8X18nYidfX198LS0+IHYoJ2InKSAgICAgICAgfCAgICAgICAgICAgfCdDaCcgfHYoJ0NoJyl8ICAgfCAgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAovLyAgfF9fX186X19ffCAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tfCAgIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKLy8gIHxfX19fOl9fX3wgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICB8J0NIJyB8dignQ0gnKXwgICB8ICAgfCAgICAgICAgICAgICA6ICAgICAgICAgICB8Ci8vICB8X19fJ2MnX198LS0tLS0tLS0tLS0tLS0tLS0tLSAgICAgICAgICAgIC0tLS0tLS0tLS0tLS0gICAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAovLyAgfF9fX186X19ffCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKLy8gIHxvLXVtbGF1dHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gICAgfF9fX19fX19fX19fX19fX19fX19fX19fX198Ci8vICB8X19fXzpfX198Ci8vCi8vCi8vIE5vdGVkIGJ5IEhlbGVuYSBTaGloIG9uIDYvMjMvOTcgd2l0aCBwZW5kaW5nIGRlc2lnbiBjaGFuZ2VzIChzbGltbWluZyBjb2xsYXRpb24pLgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Cgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDSEFSSU5ERVggPSAweDcwMDAwMDAwOyAgICAgICAgICAgICAvLyBuZWVkIGxvb2sgdXAgaW4gLmNvbW1pdCgpCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkVYUEFORENIQVJJTkRFWCA9IDB4N0UwMDAwMDA7ICAgICAgIC8vIEV4cGFuZCBpbmRleCBmb2xsb3dzCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkNPTlRSQUNUQ0hBUklOREVYID0gMHg3RjAwMDAwMDsgICAgIC8vIGNvbnRyYWN0IGluZGV4ZXMgZm9sbG93cwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpVTk1BUFBFRCA9IDB4RkZGRkZGRkY7ICAgICAgICAgICAgICAvLyB1bm1hcHBlZCBjaGFyYWN0ZXIgdmFsdWVzCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllPUkRFUklOQ1JFTUVOVCA9IDB4MDAwMTAwMDA7IC8vIHByaW1hcnkgc3RyZW5ndGggaW5jcmVtZW50CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAwMDEwMDsgLy8gc2Vjb25kYXJ5IHN0cmVuZ3RoIGluY3JlbWVudApjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpURVJUSUFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAwMDAwMTsgLy8gdGVydGlhcnkgc3RyZW5ndGggaW5jcmVtZW50CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6Ok1BWElHTk9SQUJMRSA9IDB4MDAwMTAwMDA7ICAgICAgICAgIC8vIG1heGltdW0gaWdub3JhYmxlIGNoYXIgb3JkZXIgdmFsdWUKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSTUFTSyA9IDB4ZmZmZjAwMDA7ICAgICAgLy8gbWFzayBvZmYgYW55dGhpbmcgYnV0IHByaW1hcnkgb3JkZXIKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJNQVNLID0gMHgwMDAwZmYwMDsgICAgLy8gbWFzayBvZmYgYW55dGhpbmcgYnV0IHNlY29uZGFyeSBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpURVJUSUFSWU9SREVSTUFTSyA9IDB4MDAwMDAwZmY7ICAgICAvLyBtYXNrIG9mZiBhbnl0aGluZyBidXQgdGVydGlhcnkgb3JkZXIKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZUkVTRVRNQVNLID0gMHgwMDAwZmZmZjsgICAgLy8gbWFzayBvZmYgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpJR05PUkFCTEVNQVNLID0gMHgwMDAwZmZmZjsgICAgICAgICAvLyBtYXNrIG9mZiBpZ25vcmFibGUgY2hhciBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZRElGRkVSRU5DRU9OTFkgPSAweGZmZmYwMDAwOyAvLyB1c2Ugb25seSB0aGUgcHJpbWFyeSBkaWZmZXJlbmNlCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWURJRkZFUkVOQ0VPTkxZID0gMHhmZmZmZmYwMDsgIC8vIHVzZSBvbmx5IHRoZSBwcmltYXJ5IGFuZCBzZWNvbmRhcnkgZGlmZmVyZW5jZQpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJTSElGVCA9IDE2OyAgICAgICAgICAgICAvLyBwcmltYXJ5IG9yZGVyIHNoaWZ0CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSU0hJRlQgPSA4OyAgICAgICAgICAgIC8vIHNlY29uZGFyeSBvcmRlciBzaGlmdApjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTT1JUS0VZT0ZGU0VUID0gMTsgICAgICAgICAgICAgICAgICAvLyBtaW5pbXVtIHNvcnQga2V5IG9mZnNldApjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDT05UUkFDVENIQVJPVkVSRkxPVyA9IDB4N0ZGRkZGRkY7ICAvLyBJbmRpY2F0ZXMgdGhlIGNoYXIgaXMgYSBjb250cmFjdCBjaGFyCgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDT0xFTEVNRU5UU1RBUlQgPSAweDAyMDIwMjAyOyAgICAgICAvLyBzdGFydGluZyB2YWx1ZSBmb3IgY29sbGF0aW9uIGVsZW1lbnRzCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllMT1daRVJPTUFTSyA9IDB4MDBGRjAwMDA7ICAgIC8vIHRlc3RpbmcgbWFzayBmb3IgcHJpbWFyeSBsb3cgZWxlbWVudApjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpSRVNFVFNFQ09OREFSWVRFUlRJQVJZID0gMHgwMDAwMDIwMjsvLyByZXNldGluZyB2YWx1ZSBmb3Igc2Vjb25kYXJpZXMgYW5kIHRlcnRpYXJpZXMKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UkVTRVRURVJUSUFSWSA9IDB4MDAwMDAwMDI7ICAgICAgICAgLy8gcmVzZXRpbmcgdmFsdWUgZm9yIHRlcnRpYXJpZXMKCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OklHTk9SQUJMRSA9IDB4MDIwMjAyMDI7CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1JR05PUkFCTEUgPSAweDAyMDI7CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ0lHTk9SQUJMRSA9IDB4MDI7CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlRFUklHTk9SQUJMRSA9IDB4MDI7Cgpjb25zdCBpbnQxNl90IFJ1bGVCYXNlZENvbGxhdG9yOjpGSUxFSUQgPSAweDU0NDM7ICAgICAgICAgICAgICAgICAgICAvLyB1bmlxdWUgZmlsZSBpZCBmb3IgcGFyaXR5IGNoZWNrCmNvbnN0IGNoYXIqIFJ1bGVCYXNlZENvbGxhdG9yOjprRmlsZW5hbWVTdWZmaXggPSAiLmNvbCI7ICAgICAgICAgICAgIC8vIGJpbmFyeSBjb2xsYXRpb24gZmlsZSBleHRlbnNpb24KY2hhciAgUnVsZUJhc2VkQ29sbGF0b3I6OmZnQ2xhc3NJRCA9IDA7IC8vIFZhbHVlIGlzIGlycmVsZXZhbnQgICAgICAgLy8gY2xhc3MgaWQKVUNoYXIgUnVsZUJhc2VkQ29sbGF0b3I6OmNhY2hlS2V5ID0gMDsKClVNVFggUnVsZUJhc2VkQ29sbGF0b3I6OmNvbGxNdXRleCA9IE5VTEw7ClVCb29sIFJ1bGVCYXNlZENvbGxhdG9yOjppc011dGV4SW5pdGVkID0gUnVsZUJhc2VkQ29sbGF0b3I6OmluaXRNdXRleCgpOwoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIE5vcm1hbGl6ZXJJdGVyYXRvcgovLwovLyBUaGlzIGNsYXNzIGlzIGVzc2VudGlhbGx5IGEgZHVwbGljYXRlIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciwKLy8gc3RyaXBwZWQgZG93biBmb3Igc3BlZWQuICBJdCBpcyBkZWNsYXJlZCBoZXJlIHNvIHdlIGNhbiBpbmNvcnBvcmF0ZQovLyBpbnRlcm5hbCBjbGFzc2VzIGFzIHN1Ym9iamVjdHMsIGFzIHdlbGwgYXMganVzdCB0byBoaWRlIGl0IGZyb20gdGhlCi8vIHB1YmxpYyBpbnRlcmZhY2UuCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKLyogSW50ZXJuYWwgY2xhc3MgZm9yIHF1aWNrIGl0ZXJhdGlvbiBvdmVyIHRoZSB0ZXh0LgogICAxMDAlIHB1cmUgaW5saW5lIGNvZGUKKi8KY2xhc3MgTm9ybWFsaXplckl0ZXJhdG9yIHsgCnB1YmxpYzoKICAgIE5vcm1hbGl6ZXIgKmN1cnNvcjsKICAgIFZlY3Rvck9mSW50ICpidWZmZXJBbGlhczsKICAgIFZlY3Rvck9mSW50ICpyZW9yZGVyQnVmZmVyOwogICAgVmVjdG9yT2ZJbnQgb3duQnVmZmVyOwogICAgVUNoYXIqICAgICAgdGV4dDsKICAgIGludDMyX3QgICAgIGV4cEluZGV4OwogICAgaW50MzJfdCAgICAgdGV4dExlbjsKICAgIFVUZXh0T2Zmc2V0ICBjdXJyZW50T2Zmc2V0OwogICAgCiAgICBOb3JtYWxpemVySXRlcmF0b3Iodm9pZCk7CiAgICBOb3JtYWxpemVySXRlcmF0b3IoY29uc3QgVUNoYXIqIHNvdXJjZSwgaW50MzJfdCBsZW5ndGgsIE5vcm1hbGl6ZXI6OkVNb2RlIG1vZGUpOwogICAgfk5vcm1hbGl6ZXJJdGVyYXRvcih2b2lkKTsKICAgIHZvaWQgc2V0VGV4dChjb25zdCBVQ2hhciogc291cmNlLCBpbnQzMl90IGxlbmd0aCwgVUVycm9yQ29kZSYgc3RhdHVzKTsKICAgIHZvaWQgc2V0TW9kZUFuZFRleHQoTm9ybWFsaXplcjo6RU1vZGUgbW9kZSwgY29uc3QgVUNoYXIqIHNvdXJjZSwgaW50MzJfdCBsZW5ndGgsIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgICAKICAgIFVDaGFyIGN1cnJlbnQodm9pZCkgY29uc3Q7CiAgICBVQ2hhciBuZXh0KHZvaWQpOwogICAgdm9pZCByZXNldCh2b2lkKTsKfTsKCmlubGluZQpOb3JtYWxpemVySXRlcmF0b3I6Ok5vcm1hbGl6ZXJJdGVyYXRvcigpIDoKICAgIGN1cnNvcigwKSwKICAgIGJ1ZmZlckFsaWFzKDApLAogICAgcmVvcmRlckJ1ZmZlcigwKSwKICAgIG93bkJ1ZmZlcigyKSwKICAgIHRleHQoMCksCiAgICBleHBJbmRleCgwKSwKICAgIHRleHRMZW4oMCksCiAgICBjdXJyZW50T2Zmc2V0KDApCnsKfQoKaW5saW5lCk5vcm1hbGl6ZXJJdGVyYXRvcjo6Tm9ybWFsaXplckl0ZXJhdG9yKGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3QgbGVuZ3RoLCBOb3JtYWxpemVyOjpFTW9kZSBtb2RlKSA6CiAgICBjdXJzb3IoMCksCiAgICBidWZmZXJBbGlhcygwKSwKICAgIHJlb3JkZXJCdWZmZXIoMCksCiAgICBvd25CdWZmZXIoMiksCiAgICB0ZXh0KDApLAogICAgZXhwSW5kZXgoMCksCiAgICB0ZXh0TGVuKDApLAogICAgY3VycmVudE9mZnNldCgwKQp7CiAgICBpZiAobW9kZSA9PSBOb3JtYWxpemVyOjpOT19PUCkgewogICAgICAgIHRleHQgPSAoVUNoYXIqKXNvdXJjZTsKICAgICAgICB0ZXh0TGVuID0gbGVuZ3RoOwogICAgICAgIGN1cnJlbnRPZmZzZXQgPSAwOwogICAgfSBlbHNlIHsKICAgICAgICBjdXJzb3IgPSBuZXcgTm9ybWFsaXplcihzb3VyY2UsIGxlbmd0aCwgbW9kZSk7CgogICAgfQp9CgppbmxpbmUKTm9ybWFsaXplckl0ZXJhdG9yOjp+Tm9ybWFsaXplckl0ZXJhdG9yKCkgCnsKICAgIGlmIChjdXJzb3IgIT0gMCkgewogICAgICAgIGRlbGV0ZSBjdXJzb3I7CiAgICAgICAgY3Vyc29yID0gMDsKICAgIH0KICAgIGlmIChyZW9yZGVyQnVmZmVyICE9IDApIHsKICAgICAgICBkZWxldGUgcmVvcmRlckJ1ZmZlcjsKICAgIH0KfQoKaW5saW5lCnZvaWQKTm9ybWFsaXplckl0ZXJhdG9yOjpzZXRUZXh0KGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3QgbGVuZ3RoLCBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmIChjdXJzb3IgPT0gMCkgewogICAgICAgIHRleHQgPSAoVUNoYXIqKXNvdXJjZTsKICAgICAgICB0ZXh0TGVuID0gbGVuZ3RoOwogICAgICAgIGN1cnJlbnRPZmZzZXQgPSAwOwoKICAgIH0gZWxzZSB7CiAgICAgICAgdGV4dCA9IDA7CiAgICAgICAgY3Vyc29yLT5zZXRUZXh0KHNvdXJjZSwgbGVuZ3RoLCBzdGF0dXMpOwogICAgfQogICAgYnVmZmVyQWxpYXMgPSAwOwogICAgY3VycmVudE9mZnNldCA9IDA7Cn0KCi8qIFlvdSBjYW4gb25seSBzZXQgbW9kZSBhZnRlciB0aGUgY29tcGFyaXNpb24gb2YgdHdvIHN0cmluZ3MgaXMgY29tcGxldGVkLgogICBTZXR0aW5nIHRoZSBtb2RlIGluIHRoZSBtaWRkbGUgb2YgYSBjb21wYXJpc29uIGlzIG5vdCBhbGxvd2VkLgogICAqLwppbmxpbmUKdm9pZAoKTm9ybWFsaXplckl0ZXJhdG9yOjpzZXRNb2RlQW5kVGV4dChOb3JtYWxpemVyOjpFTW9kZSBtb2RlLCBjb25zdCBVQ2hhciogc291cmNlLCBpbnQzMl90IGxlbmd0aCwgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICBpZihtb2RlICE9IE5vcm1hbGl6ZXI6Ok5PX09QKQogICAgewogICAgICAgIC8qIERPIGhhdmUgYSBtb2RlIC0gIHdpbGwgbmVlZCBhIG5vcm1hbGl6ZXIgb2JqZWN0ICovCiAgICAgICAgaWYoY3Vyc29yICE9IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICAvKiBKdXN0IG1vZGlmeSB0aGUgZXhpc3RpbmcgY3Vyc29yICovCiAgICAgICAgICAgIGN1cnNvci0+c2V0TW9kZShtb2RlKTsKICAgICAgICAgICAgY3Vyc29yLT5zZXRUZXh0KHNvdXJjZSwgbGVuZ3RoLCBzdGF0dXMpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBjdXJzb3IgPSBuZXcgTm9ybWFsaXplcihzb3VyY2UsIGxlbmd0aCwgbW9kZSk7CiAgICAgICAgfQoKICAgICAgICAvKiBSRVNFVCB0aGUgb2xkIGRhdGEgKi8KICAgICAgICB0ZXh0ID0gMDsKICAgICAgICB0ZXh0TGVuID0gMDsKICAgIH0KICAgIGVsc2UgCiAgICB7CiAgICAgICAgLyogTk9fT1AgbW9kZS4uICovCiAgICAgICAgaWYoY3Vyc29yICE9IE5VTEwpCiAgICAgICAgeyAvKiBnZXQgcmlkIG9mIHRoZSBvbGQgY3Vyc29yICovCiAgICAgICAgICAgIGRlbGV0ZSBjdXJzb3I7IAogICAgICAgICAgICBjdXJzb3IgPSAwOwogICAgICAgIH0KCiAgICAgICAgdGV4dCA9IChVQ2hhciopc291cmNlOwogICAgICAgIHRleHRMZW4gPSBsZW5ndGg7CiAgICB9CiAgICBjdXJyZW50T2Zmc2V0ID0gMDsgLyogYWx3YXlzICovCiAgIAogICAgYnVmZmVyQWxpYXMgPSAwOwp9CgppbmxpbmUKVUNoYXIKTm9ybWFsaXplckl0ZXJhdG9yOjpjdXJyZW50KHZvaWQpIGNvbnN0CnsKICAgIGlmICh0ZXh0ICE9IDApIHsKICAgICAgICBpZihjdXJyZW50T2Zmc2V0ID49IHRleHRMZW4pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gTm9ybWFsaXplcjo6RE9ORTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRleHRbY3VycmVudE9mZnNldF07CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAoVUNoYXIpY3Vyc29yLT5jdXJyZW50KCk7Cn0KCgppbmxpbmUKVUNoYXIKTm9ybWFsaXplckl0ZXJhdG9yOjpuZXh0KHZvaWQpCnsKICAgIGlmICh0ZXh0ICE9IDApIHsKICAgICAgICByZXR1cm4gKFVDaGFyKSgoY3VycmVudE9mZnNldCA8IHRleHRMZW4pID8gdGV4dFsrK2N1cnJlbnRPZmZzZXRdIDogTm9ybWFsaXplcjo6RE9ORSk7CiAgICB9CiAgICByZXR1cm4gKFVDaGFyKWN1cnNvci0+bmV4dCgpOwp9CgppbmxpbmUKdm9pZApOb3JtYWxpemVySXRlcmF0b3I6OnJlc2V0KHZvaWQpCnsKICAgIGN1cnJlbnRPZmZzZXQgPSAwOwogICAgaWYoY3Vyc29yKQogICAgewogICAgICAgIGN1cnNvci0+cmVzZXQoKTsKICAgIH0KfQoKLy89PT09PT09PT09PT09PT09IFNvbWUgaW5saW5lIGRlZmluaXRpb25zIG9mIGltcGxlbWVudGF0aW9uIGZ1bmN0aW9ucy4uLi4uLi4uID09PT09PT09Ci8qKgogKiBBIGNsb25lIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bWFrZVJlb3JkZXJlZEJ1ZmZlciwgdHJpbW1lZCBkb3duCiAqIHRvIG9ubHkgaGFuZGxlIGZvcndhcmQuCiAqLwppbmxpbmUgVmVjdG9yT2ZJbnQqClJ1bGVCYXNlZENvbGxhdG9yOjptYWtlUmVvcmRlcmVkQnVmZmVyKE5vcm1hbGl6ZXJJdGVyYXRvciogY3Vyc29yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ2hhciBjb2xGaXJzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsYXN0VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3Rvck9mSW50KiBsYXN0RXhwYW5zaW9uKSBjb25zdCB7CiAgICBWZWN0b3JPZkludCogcmVzdWx0OwoKICAgIGludDMyX3QgZmlyc3RWYWx1ZSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY29sRmlyc3QpOwogICAgaWYgKGZpcnN0VmFsdWUgPj0gQ09OVFJBQ1RDSEFSSU5ERVgpIHsKICAgICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAgICBmaXJzdFZhbHVlID0gbmV4dENvbnRyYWN0Q2hhcihjdXJzb3IsIGNvbEZpcnN0LCBzdGF0dXMpOwogICAgfQoKICAgIFZlY3Rvck9mSW50KiBmaXJzdEV4cGFuc2lvbiA9IE5VTEw7CiAgICBpZiAoZmlyc3RWYWx1ZSA+PSBFWFBBTkRDSEFSSU5ERVgpIHsKICAgICAgICBmaXJzdEV4cGFuc2lvbiA9IGdldEV4cGFuZFZhbHVlTGlzdChmaXJzdFZhbHVlKTsKICAgIH0KCiAgICBpZiAoZmlyc3RFeHBhbnNpb24gPT0gTlVMTCAmJiBsYXN0RXhwYW5zaW9uID09IE5VTEwpIHsKICAgICAgICBjdXJzb3ItPm93bkJ1ZmZlci5hdCgwKSA9IGZpcnN0VmFsdWU7CiAgICAgICAgY3Vyc29yLT5vd25CdWZmZXIuYXQoMSkgPSBsYXN0VmFsdWU7CiAgICAgICAgcmVzdWx0ID0gJmN1cnNvci0+b3duQnVmZmVyOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgaW50MzJfdCBmaXJzdExlbmd0aCA9IGZpcnN0RXhwYW5zaW9uPT1OVUxMPyAxIDogZmlyc3RFeHBhbnNpb24tPnNpemUoKTsKICAgICAgICBpbnQzMl90IGxhc3RMZW5ndGggPSBsYXN0RXhwYW5zaW9uPT1OVUxMPyAxIDogbGFzdEV4cGFuc2lvbi0+c2l6ZSgpOwogICAgICAgIGlmIChjdXJzb3ItPnJlb3JkZXJCdWZmZXIgPT0gTlVMTCkgewogICAgICAgICAgICBjdXJzb3ItPnJlb3JkZXJCdWZmZXIgPSBuZXcgVmVjdG9yT2ZJbnQoZmlyc3RMZW5ndGgrbGFzdExlbmd0aCk7CiAgICAgICAgfQogICAgICAgIC8vIHJlb3JkZXJkQnVmZmVyIGdldHMgcmV1c2VkIGZvciB0aGUgbGlmZSBvZiB0aGlzIG9iamVjdC4KICAgICAgICAvLyBTaW5jZSBpdHMgaW50ZXJuYWwgYnVmZmVyIG9ubHkgZ3Jvd3MsIHRoZXJlIGlzIGEgZGFuZ2VyCiAgICAgICAgLy8gdGhhdCBpdCB3aWxsIGdldCByZWFsbHksIHJlYWxseSBiaWcsIGFuZCBuZXZlciBzaHJpbmsuICBJZgogICAgICAgIC8vIHRoaXMgaXMgYWN0dWFsbHkgaGFwcGVuaW5nLCBpbnNlcnQgY29kZSBoZXJlIHRvIGNoZWNrIGZvcgogICAgICAgIC8vIHRoZSBjb25kaXRpb24uICBTb21ldGhpbmcgYWxvbmcgdGhlIGxpbmVzIG9mOgogICAgICAgIC8vISBlbHNlIGlmIChyZW9yZGVyQnVmZmVyLT5zaXplKCkgPj0gMjU2ICYmCiAgICAgICAgLy8hICAgICAgICAgIChmaXJzdExlbmd0aCtsYXN0TGVuZ3RoKSA8IDE2KSB7CiAgICAgICAgLy8hICAgICBkZWxldGUgcmVvcmRlckJ1ZmZlcjsKICAgICAgICAvLyEgICAgIHJlb3JkZXJCdWZmZXIgPSBuZXcgVmVjdG9yT2ZJbnQoZmlyc3RMZW5ndGgrbGFzdExlbmd0aCk7CiAgICAgICAgLy8hIH0KICAgICAgICAvLyBUaGUgc3BlY2lmaWMgbnVtZXJpYyB2YWx1ZXMgbmVlZCB0byBiZSBkZXRlcm1pbmVkCiAgICAgICAgLy8gZW1waXJpY2FsbHkuIFthbGl1XQogICAgICAgIHJlc3VsdCA9IGN1cnNvci0+cmVvcmRlckJ1ZmZlcjsKCiAgICAgICAgaWYgKGZpcnN0RXhwYW5zaW9uID09IE5VTEwpIHsKICAgICAgICAgICAgcmVzdWx0LT5hdFB1dCgwLCBmaXJzdFZhbHVlKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8vIFN5c3RlbS5hcnJheWNvcHkoZmlyc3RFeHBhbnNpb24sIDAsIHJlc3VsdCwgMCwgZmlyc3RMZW5ndGgpOwogICAgICAgICAgICAqcmVzdWx0ID0gKmZpcnN0RXhwYW5zaW9uOwogICAgICAgIH0KCiAgICAgICAgaWYgKGxhc3RFeHBhbnNpb24gPT0gTlVMTCkgewogICAgICAgICAgICByZXN1bHQtPmF0UHV0KGZpcnN0TGVuZ3RoLCBsYXN0VmFsdWUpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLy8gU3lzdGVtLmFycmF5Y29weShsYXN0RXhwYW5zaW9uLCAwLCByZXN1bHQsIGZpcnN0TGVuZ3RoLCBsYXN0TGVuZ3RoKTsKICAgICAgICAgICAgZm9yIChpbnQzMl90IGk9MDsgaTxsYXN0TGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIHJlc3VsdC0+YXRQdXQoZmlyc3RMZW5ndGggKyBpLCBsYXN0RXhwYW5zaW9uLT5hdChpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVzdWx0LT5zZXRTaXplKGZpcnN0TGVuZ3RoK2xhc3RMZW5ndGgpOwogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCgoKCgppbmxpbmUgaW50MzJfdApSdWxlQmFzZWRDb2xsYXRvcjo6c3RyZW5ndGhPcmRlcihpbnQzMl90IHZhbHVlKSBjb25zdAp7CiAgICBpZiAoZ2V0U3RyZW5ndGgoKSA9PSBQUklNQVJZKQogICAgewogICAgICAgIHJldHVybiAodmFsdWUgJiBQUklNQVJZRElGRkVSRU5DRU9OTFkpOwogICAgfSBlbHNlIGlmIChnZXRTdHJlbmd0aCgpID09IFNFQ09OREFSWSkKICAgIHsKICAgICAgICByZXR1cm4gKHZhbHVlICYgU0VDT05EQVJZRElGRkVSRU5DRU9OTFkpOwogICAgfQogICAgcmV0dXJuIHZhbHVlOwp9CgoKaW5saW5lIGludDMyX3QKUnVsZUJhc2VkQ29sbGF0b3I6OmdldFN0cmVuZ3RoT3JkZXIoTm9ybWFsaXplckl0ZXJhdG9yKiBjdXJzb3IsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlIHN0YXR1cykgY29uc3QKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUjsKICAgIH0KCiAgICBpZiAoY3Vyc29yLT5idWZmZXJBbGlhcyAhPSBOVUxMKQogICAgewogICAgICAgIC8vIGJ1ZmZlckFsaWFzIG5lZWRzIGEgYml0IG9mIGFuIGV4cGxhbmF0aW9uLgogICAgICAgIC8vIFdoZW4gd2UgaGl0IGFuIGV4cGFuZGluZyBjaGFyYWN0ZXIgaW4gdGhlIHRleHQsIHdlIGNhbGwgdGhlIG9yZGVyJ3MKICAgICAgICAvLyBnZXRFeHBhbmRWYWx1ZXMgbWV0aG9kIHRvIHJldHJpZXZlIGFuIGFycmF5IG9mIHRoZSBvcmRlcmluZ3MgZm9yIGFsbAogICAgICAgIC8vIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBleHBhbnNpb24gKHNlZSB0aGUgZW5kIG9mIHRoaXMgbWV0aG9kKS4KICAgICAgICAvLyBUaGUgZmlyc3Qgb3JkZXJpbmcgaXMgcmV0dXJuZWQsIGFuZCBhbiBhbGlhcyB0byB0aGUgb3JkZXJpbmdzIGFycmF5CiAgICAgICAgLy8gaXMgc2F2ZWQgc28gdGhhdCB0aGUgcmVtYWluaW5nIG9yZGVyaW5ncyBjYW4gYmUgcmV0dXJuZWQgb24gc3Vic2VxdWVudAogICAgICAgIC8vIGNhbGxzIHRvIG5leHQuICBTbywgaWYgdGhlIGV4cGFuZGluZyBidWZmZXIgaXMgbm90IGV4aGF1c3RlZCwgCiAgICAgICAgLy8gYWxsIHdlIGhhdmUgdG8gZG8gaGVyZSBpcyByZXR1cm4gdGhlIG5leHQgb3JkZXJpbmcgaW4gdGhlIGJ1ZmZlci4gIAogICAgICAgIGlmIChjdXJzb3ItPmV4cEluZGV4IDwgY3Vyc29yLT5idWZmZXJBbGlhcy0+c2l6ZSgpKQogICAgICAgIHsKICAgICAgICAgICAgLy9fTCgoc3RkZXJyLCAibmV4dCBmcm9tIFslMDhYXSBmcm9tIGJ1ZmZlckFsaWFzXG4iLCB0aGlzKSk7CiAgICAgICAgICAgIHJldHVybiBzdHJlbmd0aE9yZGVyKGN1cnNvci0+YnVmZmVyQWxpYXMtPmF0KGN1cnNvci0+ZXhwSW5kZXgrKykpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBjdXJzb3ItPmJ1ZmZlckFsaWFzID0gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgVUNoYXIgY2ggPSBjdXJzb3ItPmN1cnJlbnQoKTsKICAgIGN1cnNvci0+bmV4dCgpOwoKICAgIC8vX0woKHN0ZGVyciwgIk5leHQgZnJvbSBbJTA4WF0gPSBbJTA0WF0sIFslY11cbiIsIGN1cnNvciwgKGludCljaCAmIDB4RkZGRiwgKGNoYXIpKGNoICYgMHhGRikpKTsKICAgIAogICAgaWYgKGNoID09IE5vcm1hbGl6ZXI6OkRPTkUpIHsKICAgICAgICByZXR1cm4gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVI7CiAgICB9CiAgICAvLyBBc2sgdGhlIGNvbGxhdG9yIGZvciB0aGlzIGNoYXJhY3RlcidzIG9yZGVyaW5nLgogICAgaW50MzJfdCB2YWx1ZSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY2gpOwoKICAgIGlmICh2YWx1ZSA9PSBVTk1BUFBFRCkKICAgIHsKICAgICAgICAvLyBSZXR1cm5lZCBhbiAidW5tYXBwZWQiIGZsYWcgYW5kIHNhdmUgdGhlIGNoYXJhY3RlciBzbyBpdCBjYW4gYmUgCiAgICAgICAgLy8gcmV0dXJuZWQgbmV4dCB0aW1lIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC4KICAgICAgICBpZiAoY2ggPT0gMHgwMDAwKSByZXR1cm4gY2g7IC8vIFx1MDAwMCBpcyBub3QgdmFsaWQgaW4gQysrJ3MgVW5pY29kZVN0cmluZwogICAgICAgIGN1cnNvci0+b3duQnVmZmVyLmF0KDApID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpVTk1BUFBFRENIQVJWQUxVRTsKICAgICAgICBjdXJzb3ItPm93bkJ1ZmZlci5hdCgxKSA9IGNoIDw8IDE2OwogICAgICAgIGN1cnNvci0+YnVmZmVyQWxpYXMgPSAmY3Vyc29yLT5vd25CdWZmZXI7CgogICAgfSBlbHNlIHsKICAgICAgICAKICAgICAgICBpZiAodmFsdWUgPj0gQ09OVFJBQ1RDSEFSSU5ERVgpCiAgICAgICAgewogICAgICAgICAgICB2YWx1ZSA9IG5leHRDb250cmFjdENoYXIoY3Vyc29yLCBjaCwgc3RhdHVzKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKHZhbHVlID49IEVYUEFORENIQVJJTkRFWCkgewogICAgICAgICAgICBjdXJzb3ItPmJ1ZmZlckFsaWFzID0gZ2V0RXhwYW5kVmFsdWVMaXN0KHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6aXNUaGFpUHJlVm93ZWwoY2gpKSB7CiAgICAgICAgICAgIFVDaGFyIGNvbnNvbmFudCA9IGN1cnNvci0+Y3VycmVudCgpOwogICAgICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc1RoYWlCYXNlQ29uc29uYW50KGNvbnNvbmFudCkpIHsKICAgICAgICAgICAgICAgIGN1cnNvci0+bmV4dCgpOwogICAgICAgICAgICAgICAgY3Vyc29yLT5idWZmZXJBbGlhcyA9IG1ha2VSZW9yZGVyZWRCdWZmZXIoY3Vyc29yLCBjb25zb25hbnQsIHZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3Vyc29yLT5idWZmZXJBbGlhcyk7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChjdXJzb3ItPmJ1ZmZlckFsaWFzICE9IE5VTEwpIHsKICAgICAgICBjdXJzb3ItPmV4cEluZGV4ID0gMTsKICAgICAgICB2YWx1ZSA9IGN1cnNvci0+YnVmZmVyQWxpYXMtPmF0KDApOwogICAgfQoKICAgIHJldHVybiBzdHJlbmd0aE9yZGVyKHZhbHVlKTsKfQoKLy8gPT09PT09PT09PT09PT09PT09PT0gRW5kIGlubGluZXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KVUJvb2wgUnVsZUJhc2VkQ29sbGF0b3I6OmluaXRNdXRleCgpIHsKICAgIGlmKGlzTXV0ZXhJbml0ZWQgPT0gRkFMU0UpIHsKICAgICAgICB1bXR4X2xvY2soTlVMTCk7CiAgICAgICAgaWYoaXNNdXRleEluaXRlZCA9PSBGQUxTRSkgewogICAgICAgICAgdW10eF9pbml0KCZjb2xsTXV0ZXgpOwogICAgICAgICAgaXNNdXRleEluaXRlZCA9IFRSVUU7CiAgICAgICAgfQogICAgICAgIHVtdHhfdW5sb2NrKE5VTEwpOwogICAgfQogICAgcmV0dXJuIGlzTXV0ZXhJbml0ZWQ7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcigpCiAgICA6IENvbGxhdG9yKCksCiAgICAgIGlzT3Zlcklnbm9yZShGQUxTRSksCiAgICAgIG1QYXR0ZXJuKDApLAogICAgICAvLyAgICAgIHNvdXJjZUN1cnNvcigwKSwKICAgICAgLy90YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICAgIGRhdGFJc093bmVkKEZBTFNFKSwKICAgICAgZGF0YSgwKSwKICAgICAgZlNvbWVNZW1vcnkoTlVMTCkKewp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgIFJ1bGVCYXNlZENvbGxhdG9yJiAgdGhhdCkKICAgIDogQ29sbGF0b3IodGhhdCksCiAgICAgIGlzT3Zlcklnbm9yZSh0aGF0LmlzT3Zlcklnbm9yZSksCiAgICAgIG1QYXR0ZXJuKDApLAogICAgICAvLyAgICAgIHNvdXJjZUN1cnNvcigwKSwKICAgICAgLy90YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICAgIGRhdGFJc093bmVkKEZBTFNFKSwKICAgICAgZGF0YSh0aGF0LmRhdGEpICwvLyBBbGlhcyB0aGUgZGF0YSBwb2ludGVyCiAgICAgIGZTb21lTWVtb3J5KE5VTEwpCnsKfQoKVUJvb2wKUnVsZUJhc2VkQ29sbGF0b3I6Om9wZXJhdG9yPT0oY29uc3QgQ29sbGF0b3ImIHRoYXQpIGNvbnN0CnsKICAgIGlmICh0aGlzID09ICZ0aGF0KQogICAgewogICAgICAgIHJldHVybiBUUlVFOwogICAgfQoKICAgIGlmICh0aGlzLT5nZXREeW5hbWljQ2xhc3NJRCgpICE9IHRoYXQuZ2V0RHluYW1pY0NsYXNzSUQoKSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7ICAvLyBub3QgdGhlIHNhbWUgY2xhc3MKICAgIH0KCiAgICBpZiAoIUNvbGxhdG9yOjpvcGVyYXRvcj09KHRoYXQpKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBSdWxlQmFzZWRDb2xsYXRvciYgdGhhdEFsaWFzID0gKFJ1bGVCYXNlZENvbGxhdG9yJil0aGF0OwoKICAgIGlmIChpc092ZXJJZ25vcmUgIT0gdGhhdEFsaWFzLmlzT3Zlcklnbm9yZSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKGRhdGEgIT0gdGhhdEFsaWFzLmRhdGEpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgpSdWxlQmFzZWRDb2xsYXRvciYKUnVsZUJhc2VkQ29sbGF0b3I6Om9wZXJhdG9yPShjb25zdCAgUnVsZUJhc2VkQ29sbGF0b3ImIHRoYXQpCnsKICAgIGlmICh0aGlzICE9ICZ0aGF0KQogICAgewogICAgICAgIENvbGxhdG9yOjpvcGVyYXRvcj0odGhhdCk7CiAgICAgICAgaXNPdmVySWdub3JlID0gdGhhdC5pc092ZXJJZ25vcmU7CgogICAgICAgIGlmIChkYXRhSXNPd25lZCkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIH0KCiAgICAgICAgZGF0YSA9IDA7CiAgICAgICAgZGVsZXRlIG1QYXR0ZXJuOwogICAgICAgIG1QYXR0ZXJuID0gMDsKICAgICAgICBkYXRhSXNPd25lZCA9IEZBTFNFOwogICAgICAgIGRhdGEgPSB0aGF0LmRhdGE7CiAgICB9CgogICAgcmV0dXJuICp0aGlzOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKQogICAgOiBDb2xsYXRvcigpLAogICAgICBpc092ZXJJZ25vcmUoRkFMU0UpLAogICAgICBtUGF0dGVybigwKSwKICAgICAgLy8gICAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAgIC8vLyAgICAgIHRhcmdldEN1cnNvcigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpLAogICAgICBkYXRhKDApLAogICAgICBmU29tZU1lbW9yeShOVUxMKQoKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBjb25zdHJ1Y3RGcm9tUnVsZXMocnVsZXMsIHN0YXR1cyk7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKQogIDogQ29sbGF0b3IoY29sbGF0aW9uU3RyZW5ndGgsIE5vcm1hbGl6ZXI6Ok5PX09QKSwKICAgIGlzT3Zlcklnbm9yZShGQUxTRSksCiAgICBtUGF0dGVybigwKSwKICAgIC8vICAgIHNvdXJjZUN1cnNvcigwKSwKICAgIC8vICAgIHRhcmdldEN1cnNvcigwKSwKICAgIGN1cnNvcjEoMCksCiAgICBjdXJzb3IyKDApLAogICAgZGF0YUlzT3duZWQoRkFMU0UpLAogICAgZGF0YSgwKSwKICAgICAgZlNvbWVNZW1vcnkoTlVMTCkKCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdHJ1Y3RGcm9tUnVsZXMocnVsZXMsIHN0YXR1cyk7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCiAgOiBDb2xsYXRvcihURVJUSUFSWSwgZGVjb21wb3NpdGlvbk1vZGUpLAogICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgIG1QYXR0ZXJuKDApLAogICAgLy8gICAgc291cmNlQ3Vyc29yKDApLAogICAgLy8gICAgdGFyZ2V0Q3Vyc29yKDApLAogICAgY3Vyc29yMSgwKSwKICAgIGN1cnNvcjIoMCksCiAgICBkYXRhSXNPd25lZChGQUxTRSksCiAgICBkYXRhKDApLAogICAgICBmU29tZU1lbW9yeShOVUxMKQoKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgcmV0dXJuOwogICAgfQogIAogIGNvbnN0cnVjdEZyb21SdWxlcyhydWxlcywgc3RhdHVzKTsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0ICBVbmljb2RlU3RyaW5nJiAgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgIEVDb2xsYXRpb25TdHJlbmd0aCBjb2xsYXRpb25TdHJlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKQogIDogQ29sbGF0b3IoY29sbGF0aW9uU3RyZW5ndGgsIGRlY29tcG9zaXRpb25Nb2RlKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgbVBhdHRlcm4oMCksCiAgICAvLyAgICAgIHNvdXJjZUN1cnNvcigwKSwKICAgIC8vdGFyZ2V0Q3Vyc29yKDApLAogICAgICBjdXJzb3IxKDApLAogICAgICBjdXJzb3IyKDApLAogICAgICBkYXRhSXNPd25lZChGQUxTRSksCiAgICAgIGRhdGEoMCksCiAgICAgIGZTb21lTWVtb3J5KE5VTEwpCgp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGNvbnN0cnVjdEZyb21SdWxlcyhydWxlcywgc3RhdHVzKTsKfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6Y29uc3RydWN0RnJvbVJ1bGVzKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICAvLyBDb25zdHJ1Y3QgdGhpcyBjb2xsYXRvcidzIHJ1bGVzZXQgZnJvbSBpdHMgc3RyaW5nIHJlcHJlc2VudGF0aW9uCiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChydWxlcy5pc0JvZ3VzKCkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGRhdGFJc093bmVkKQogICAgewogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgfQoKICAgIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgIGlzT3Zlcklnbm9yZSA9IEZBTFNFOwogICAgc2V0U3RyZW5ndGgoQ29sbGF0b3I6OlRFUlRJQVJZKTsKCiAgICBkYXRhID0gbmV3IFRhYmxlQ29sbGF0aW9uRGF0YTsKICAgIGlmIChkYXRhLT5pc0JvZ3VzKCkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gV2UgY29uc3RydWN0ZWQgdGhlIGRhdGEgdXNpbmcgdGhlIGJ1aWxkIG1ldGhvZCwgc28gd2Ugb3duIGl0LgogICAgZGF0YUlzT3duZWQgPSBUUlVFOwoKICAgIC8vIE5vdyB0aGF0IHdlJ3ZlIGdvdCBhbGwgdGhlIGJ1ZmZlcnMgYWxsb2NhdGVkLCBkbyB0aGUgYWN0dWFsIHdvcmsKICAgIG1QYXR0ZXJuID0gMDsKICAgIGJ1aWxkKHJ1bGVzLCBzdGF0dXMpOwogICAgYWRkVG9DYWNoZShVbmljb2RlU3RyaW5nKGNhY2hlS2V5KyspKTsKfQoKdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6Y29uc3RydWN0RnJvbUZpbGUoY29uc3QgY2hhciogZmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIC8vIFRoaXMgbWV0aG9kIHRyaWVzIHRvIHJlYWQgaW4gYSBmbGF0dGVuZWQgUnVsZUJhc2VkQ29sbGF0b3IgdGhhdAogICAgLy8gaGFzIGJlZW4gcHJldmlvdXNseSBzdHJlYW1lZCBvdXQgdXNpbmcgdGhlIHN0cmVhbU91dCgpIG1ldGhvZC4KICAgIC8vIFRoZSAnZmlsZU5hbWUnIHBhcmFtZXRlciBzaG91bGQgY29udGFpbiBhIGZ1bGwgcGF0aG5hbWUgdmFsaWQgb24KICAgIC8vIHRoZSBsb2NhbCBlbnZpcm9ubWVudC4KCiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChkYXRhSXNPd25lZCkKICAgIHsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgIH0KCiAgICBtUGF0dGVybiA9IDA7CiAgICBpc092ZXJJZ25vcmUgPSBGQUxTRTsKICAgIHNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7IC8vIFRoaXMgaXMgdGhlIGRlZmF1bHQgc3RyZW5ndGgKCiAgICBGaWxlU3RyZWFtKiBpZnMgPSBUX0ZpbGVTdHJlYW1fb3BlbihmaWxlTmFtZSwgInJiIik7CiAgICBpZiAoaWZzID09IDApIHsKICAgICAgICBzdGF0dXMgPSBVX0ZJTEVfQUNDRVNTX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBUaGUgc3RyZWFtSW4gZnVuY3Rpb24gZG9lcyB0aGUgYWN0dWFsIHdvcmsgaGVyZS4uLgogICAgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtSW4odGhpcywgaWZzKTsKCiAgICBpZiAoIVRfRmlsZVN0cmVhbV9lcnJvcihpZnMpKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgIH0KICAgIGVsc2UgaWYgKGRhdGEgJiYgZGF0YS0+aXNCb2d1cygpKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IDA7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SOwogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgfQoKI2lmZGVmIENPTExERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJiaW5hcnkgcmVhZCAlcyBzaXplICVkLCAlc1xuIiwgZmlsZU5hbWUsIFRfRmlsZVN0cmVhbV9zaXplKGlmcyksIHVfZXJyb3JOYW1lKHN0YXR1cykpOwojZW5kaWYKCiAgICAvLyBXZSBjb25zdHJ1Y3RlZCB0aGUgZGF0YSB3aGVuIHN0cmVhbWluZyBpdCBpbiwgc28gd2Ugb3duIGl0CiAgICBkYXRhSXNPd25lZCA9IFRSVUU7CgogICAgVF9GaWxlU3RyZWFtX2Nsb3NlKGlmcyk7Cn0KCmNvbnN0IGNoYXIgKgpSdWxlQmFzZWRDb2xsYXRvcjo6Y29uc3RydWN0RnJvbUJ1bmRsZShjb25zdCBMb2NhbGUgJiBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgLy8gVGhpcyBtZXRob2QgdHJpZXMgdG8gbG9jYXRlIGJpbmFyeSBjb2xsYXRpb24gZGF0YSB3aGljaCBoYXMgYmVlbiAKICAvLyBwcmV2aW91c2x5IHN0cmVhbWVkIHRvIGEgYmluYXJ5IG9iamVjdCAiJSVDb2xsYXRpb24iIGluIGEgCiAgLy8gcmVzb3VyY2UgYnVuZGxlLiBJZiB0aGUgZGF0YSBpcyBmb3VuZCwgaXQgaXMgY2FjaGVkLgogIC8vIGNhY2hlIGlzIGNoZWNrZWQgYmVmb3JlIGFjdHVhbGx5IHN0cmVhbWluZyBpbiBkYXRhCiAgLy8gcmVzb3VyY2UgYnVuZGxlIGZhbGxiYWNrIG1lY2hhbmlzbSBpcyB1c2VkLgoKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IDA7CiAgICB9CiAgICBjb25zdCBjaGFyKiByZWFsTmFtZSA9IDA7CgogICAgbVBhdHRlcm4gPSAwOwogICAgaXNPdmVySWdub3JlID0gRkFMU0U7CiAgICBzZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOyAvLyBUaGlzIGlzIHRoZSBkZWZhdWx0IHN0cmVuZ3RoCgogICAgUmVzb3VyY2VCdW5kbGUgcmIoKGNoYXIgKikwLCBuYW1lLCBzdGF0dXMpOwogICAgaWYoVV9TVUNDRVNTKHN0YXR1cykpIHsKICAgICAgUmVzb3VyY2VCdW5kbGUgYmluYXJ5ID0gcmIuZ2V0KCIlJUNvbGxhdGlvbiIsIHN0YXR1cyk7IC8vVGhpcyBpcyB0aGUgYnVuZGxlIHRoYXQgYWN0dWFsbHkgY29udGFpbnMgdGhlIGNvbGxhdGlvbiBkYXRhCiAgICAgIHJlYWxOYW1lID0gYmluYXJ5LmdldE5hbWUoKTsKICAgICAgaWYoVV9TVUNDRVNTKHN0YXR1cykpIHsKICAgICAgICBVRXJyb3JDb2RlIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAgICBSZXNvdXJjZUJ1bmRsZSBjb2xFbGVtID0gcmIuZ2V0KCJDb2xsYXRpb25FbGVtZW50cyIsIGludFN0YXR1cyk7CiAgICAgICAgaWYoVV9TVUNDRVNTKGludFN0YXR1cykpIHsKICAgICAgICAgICAgVW5pY29kZVN0cmluZyBub3JtID0gY29sRWxlbS5nZXRTdHJpbmdFeCgiTm9ybWFsaXplIiwgaW50U3RhdHVzKTsKICAgICAgICAgICAgaWYoVV9TVUNDRVNTKGludFN0YXR1cykpIHsKICAgICAgICAgICAgICAgIHNldERlY29tcG9zaXRpb24oTm9ybWFsaXplcjo6REVDT01QKTsKICAgICAgICAgICAgICAgIGZEZWZhdWx0RGVjb21wID0gTm9ybWFsaXplcjo6REVDT01QOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2V0RGVjb21wb3NpdGlvbihOb3JtYWxpemVyOjpOT19PUCk7CiAgICAgICAgICAgICAgICBmRGVmYXVsdERlY29tcCA9IE5vcm1hbGl6ZXI6Ok5PX09QOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKCiAgICAgICAgY29uc3RydWN0RnJvbUNhY2hlKHJlYWxOYW1lLCBpbnRTdGF0dXMpOyAvLyBjaGVjayB3aGV0aGVyIHdlIGFscmVhZHkgaGF2ZSB0aGlzIGRhdGEgaW4gY2FjaGUKICAgICAgICBpZihVX1NVQ0NFU1MoaW50U3RhdHVzKSkgewogICAgICAgICAgcmV0dXJuIHJlYWxOYW1lOwogICAgICAgIH0KICAgICAgICBpbnQzMl90IGluRGF0YUxlbiA9IDA7CiAgICAgICAgY29uc3QgdWludDhfdCAqaW5EYXRhID0gYmluYXJ5LmdldEJpbmFyeShpbkRhdGFMZW4sIHN0YXR1cyk7IC8vVGhpcyBnb3QgdXMgdGhlIHJlYWwgYmluYXJ5IGRhdGEKCiAgICAgICAgVU1lbW9yeVN0cmVhbSAqaWZzID0gdXBydl9tc3RybV9vcGVuQnVmZmVyKGluRGF0YSwgaW5EYXRhTGVuKTsKCiAgICAgICAgaWYgKGlmcyA9PSAwKSB7CiAgICAgICAgICBzdGF0dXMgPSBVX0ZJTEVfQUNDRVNTX0VSUk9SOwogICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvLyBUaGUgc3RyZWFtSW4gZnVuY3Rpb24gZG9lcyB0aGUgYWN0dWFsIHdvcmsgaGVyZS4uLgogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbUluKHRoaXMsIGlmcywgc3RhdHVzKTsKCiAgICAgICAgaWYgKCF1cHJ2X21zdHJtX2Vycm9yKGlmcykpIHsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoZGF0YSAmJiBkYXRhLT5pc0JvZ3VzKCkpIHsKICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICAgIGRhdGEgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CiAgICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICAgIGRhdGEgPSAwOwogICAgICAgIH0KCiAgICAgICAgLy8gV2UgY29uc3RydWN0ZWQgdGhlIGRhdGEgd2hlbiBzdHJlYW1pbmcgaXQgaW4sIHNvIHdlIG93biBpdAogICAgICAgIGRhdGFJc093bmVkID0gVFJVRTsKCiAgICAgICAgdXBydl9tc3RybV9jbG9zZShpZnMpOwogICAgICAgIGFkZFRvQ2FjaGUocmVhbE5hbWUpOyAvLyBhZGQgdGhlIG5ld2x5IGNvbnN0cnVjdGVkIGRhdGEgdG8gY2FjaGUKICAgICAgICByZXR1cm4gcmVhbE5hbWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RhdHVzID0gVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SOwogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAwOwogICAgfQp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoICAgY29uc3QgTG9jYWxlJiBkZXNpcmVkTG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKICAgIDogQ29sbGF0b3IoKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgLy8gICAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAgIC8vdGFyZ2V0Q3Vyc29yKDApLAogICAgICBtUGF0dGVybigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpLAogICAgICBkYXRhKDApLAogICAgICBmU29tZU1lbW9yeShOVUxMKQoKewoKCiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CiAgICByZXR1cm47CiAgfQoKICAvLyBUcnkgdG8gbG9hZCwgaW4gb3JkZXI6CiAgLy8gMS4gVGhlIGRlc2lyZWQgbG9jYWxlJ3MgY29sbGF0aW9uLgogIC8vIDIuIEEgZmFsbGJhY2sgb2YgdGhlIGRlc2lyZWQgbG9jYWxlLgogIC8vIDMuIFRoZSBkZWZhdWx0IGxvY2FsZSdzIGNvbGxhdGlvbi4KICAvLyA0LiBBIGZhbGxiYWNrIG9mIHRoZSBkZWZhdWx0IGxvY2FsZS4KICAvLyA1LiBUaGUgZGVmYXVsdCBjb2xsYXRpb24gcnVsZXMsIHdoaWNoIGNvbnRhaW5zIGVuX1VTIGNvbGxhdGlvbiBydWxlcy4KCiAgLy8gVG8gcmVpdGVyYXRlLCB3ZSB0cnk6CiAgLy8gU3BlY2lmaWM6CiAgLy8gIGxhbmd1YWdlK2NvdW50cnkrdmFyaWFudAogIC8vICBsYW5ndWFnZStjb3VudHJ5CiAgLy8gIGxhbmd1YWdlCiAgLy8gRGVmYXVsdDoKICAvLyAgbGFuZ3VhZ2UrY291bnRyeSt2YXJpYW50CiAgLy8gIGxhbmd1YWdlK2NvdW50cnkKICAvLyAgbGFuZ3VhZ2UKICAvLyBSb290OiAoYWthIERFRkFVTFRSVUxFUykKICAvLyBzdGVwcyAxLTUgYXJlIGhhbmRsZWQgYnkgcmVzb3VyY2UgYnVuZGxlIGZhbGxiYWNrIG1lY2hhbmlzbS4gCiAgLy8gaG93ZXZlciwgaW4gYSB2ZXJ5IHVucHJvYmFibGUgc2l0dWF0aW9uIHRoYXQgbm8gcmVzb3VyY2UgYnVuZGxlCiAgLy8gZGF0YSBleGlzdHMsIHN0ZXAgNSBpcyByZXBlYXRlZCB3aXRoIGhhcmRjb2RlZCBkZWZhdWx0IHJ1bGVzLgoKICBjb25zdCBjaGFyICpsb2NOYW1lID0gY29uc3RydWN0RnJvbUJ1bmRsZShkZXNpcmVkTG9jYWxlLCBzdGF0dXMpOyAgLyohKi8KICAKICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpIHsKICAgIGRhdGEtPmRlc2lyZWRMb2NhbGUgPSBkZXNpcmVkTG9jYWxlOwogICAgZGF0YS0+cmVhbExvY2FsZU5hbWUgPSBsb2NOYW1lOwogIH0gZWxzZSB7CiAgICBVRXJyb3JDb2RlIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgIGNvbnN0cnVjdEZyb21DYWNoZShSZXNvdXJjZUJ1bmRsZTo6a0RlZmF1bHRGaWxlbmFtZSwgaW50U3RhdHVzKTsKICAgIGlmKFVfRkFJTFVSRShpbnRTdGF0dXMpKSB7CiAgICAgIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAgY29uc3RydWN0RnJvbVJ1bGVzKFJ1bGVCYXNlZENvbGxhdG9yOjpERUZBVUxUUlVMRVMsIGludFN0YXR1cyk7CiAgICAgIGlmIChpbnRTdGF0dXMgPT0gVV9aRVJPX0VSUk9SKSB7CiAgICAgICAgc3RhdHVzID0gVV9VU0lOR19ERUZBVUxUX0VSUk9SOwogICAgICB9IGVsc2UgewogICAgICAgIHN0YXR1cyA9IGludFN0YXR1czsgICAgIC8vIGJ1YmJsZSBiYWNrCiAgICAgIH0KCiAgICAgIGlmIChzdGF0dXMgPT0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUikgewogICAgICAgIHJldHVybjsKICAgICAgfQogICAgfQogICAgZGF0YS0+cmVhbExvY2FsZU5hbWUgPSBSZXNvdXJjZUJ1bmRsZTo6a0RlZmF1bHRGaWxlbmFtZTsKICAgIGFkZFRvQ2FjaGUoUmVzb3VyY2VCdW5kbGU6OmtEZWZhdWx0RmlsZW5hbWUpOwogIH0KICByZXR1cm47Cn0KCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbnN0cnVjdEZyb21GaWxlKCAgIGNvbnN0IExvY2FsZSYgICAgICAgICAgIGxvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgICAgbG9jYWxlRmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVCb29sICAgICAgICAgICAgICAgICAgdHJ5QmluYXJ5RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICAgICAgICAgIHN0YXR1cykKewogIC8vIGNvbnN0cnVjdEZyb21GaWxlIGNyZWF0ZXMgYSBjb2xsYXRpb24gb2JqZWN0IGJ5IHJlYWRpbmcgZnJvbSBhCiAgLy8gZmlsZS4gIEl0IGRvZXMgbm90IGVtcGxveSB0aGUgdXN1YWwgRklMRSBzZWFyY2ggbWVjaGFuaXNtIHdpdGgKICAvLyBsb2NhbGVzLCBkZWZhdWx0IGxvY2FsZXMsIGFuZCBiYXNlIGxvY2FsZXMuICBJbnN0ZWFkLCBpdCB0cmllcyB0bwogIC8vIGxvb2sgb25seSBpbiBmaWxlcyB3aXRoIHRoZSBnaXZlbiBsb2NhbEZpbGVOYW1lLiAgSXQgZG9lcywKICAvLyBob3dldmVyLCBlbXBsb3kgdGhlIExPQ0FMRSBzZWFyY2ggbWVjaGFuaXNtLgogIAogIC8vIFRoaXMgbWV0aG9kIG1haW50YWlucyB0aGUgYmluYXJ5IGNvbGxhdGlvbiBmaWxlcy4gIElmIGEgY29sbGF0aW9uCiAgLy8gaXMgbm90IHByZXNlbnQgaW4gYmluYXJ5IGZvcm0sIGJ1dCBpcyBwcmVzZW50IGluIHRleHQgZm9ybSAoaW4gYQogIC8vIHJlc291cmNlIGJ1bmRsZSBmaWxlKSwgaXQgd2lsbCBiZSBsb2FkZWQgaW4gdGV4dCBmb3JtLCBhbmQgdGhlbgogIC8vIHdyaXR0ZW4gdG8gZGlzay4KICAKICAvLyBJZiB0cnlCaW5hcnlGaWxlIGlzIHRydWUsIHRoZW4gdHJ5IHRvIGxvYWQgZnJvbSB0aGUgYmluYXJ5IGZpbGUgZmlyc3QuCgogIGlmKFVfRkFJTFVSRShzdGF0dXMpKSB7CiAgICByZXR1cm47CiAgfQogIAogIGlmKGRhdGFJc093bmVkKSB7CiAgICBkZWxldGUgZGF0YTsKICAgIGRhdGEgPSAwOwogIH0KCiAgICBpZih0cnlCaW5hcnlGaWxlKSB7CiAgICAgIGNoYXIgKmJpbmFyeUZpbGVQYXRoID0gY3JlYXRlUGF0aE5hbWUoVW5pY29kZVN0cmluZyh1X2dldERhdGFEaXJlY3RvcnkoKSwiIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlRmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyhrRmlsZW5hbWVTdWZmaXgsIiIpKTsKCiAgICAgICAgLy8gVHJ5IHRvIGxvYWQgdXAgdGhlIGNvbGxhdGlvbiBmcm9tIGEgYmluYXJ5IGZpbGUgZmlyc3QKICAgICAgICBjb25zdHJ1Y3RGcm9tRmlsZShiaW5hcnlGaWxlUGF0aCwgc3RhdHVzKTsKICAgICAgICAjaWZkZWYgQ09MTERFQlVHCiAgICAgICAgICAgIGNlcnIgPDwgbG9jYWxlRmlsZU5hbWUgIDw8IGtGaWxlbmFtZVN1ZmZpeCA8PCAiIGJpbmFyeSBsb2FkICIgPDwgdV9lcnJvck5hbWUoc3RhdHVzKSA8PCBlbmRsOwogICAgICAgICNlbmRpZgogICAgICAgIGlmKFVfU1VDQ0VTUyhzdGF0dXMpIHx8IHN0YXR1cyA9PSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SKSB7CiAgICAgICAgICAgIGRlbGV0ZSBbXSBiaW5hcnlGaWxlUGF0aDsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpZihzdGF0dXMgPT0gVV9GSUxFX0FDQ0VTU19FUlJPUikgewogICAgICAgICAgICBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgfQogICAgICAgIGRlbGV0ZSBbXSBiaW5hcnlGaWxlUGF0aDsKICAgIH0KCiAgLy8gTm93IHRyeSB0byBsb2FkIGl0IHVwIGZyb20gYSByZXNvdXJjZSBidW5kbGUgdGV4dCBzb3VyY2UgZmlsZQogIFVuaWNvZGVTdHJpbmcgZGF0YURpciA9IFVuaWNvZGVTdHJpbmcodV9nZXREYXRhRGlyZWN0b3J5KCksIiIpOwoKICAgIGNoYXIgKmNoOwogICAgY2ggPSBuZXcgY2hhcltsb2NhbGVGaWxlTmFtZS5zaXplKCkgKyAxXTsKICAgIGNoW2xvY2FsZUZpbGVOYW1lLmV4dHJhY3QoMCwgMHg3ZmZmZmZmZiwgY2gsICIiKV0gPSAwOwogICAgUmVzb3VyY2VCdW5kbGUgYnVuZGxlKGRhdGFEaXIsIGNoLCBzdGF0dXMpOwogIAogICAgZGVsZXRlIFtdIGNoOwogIAogIC8vIGlmIHRoZXJlIGlzIG5vIHJlc291cmNlIGJ1bmRsZSBmaWxlIGZvciB0aGUgZ2l2ZSBsb2NhbGUsIGJyZWFrIG91dAogIGlmKFVfRkFJTFVSRShzdGF0dXMpKQogIHsKICAgICAgcmV0dXJuOwogIH0KCiAgICAjaWZkZWYgQ09MTERFQlVHCiAgICAgICAgY2VyciA8PCBsb2NhbGVGaWxlTmFtZSA8PCAiIGFzY2lpIGxvYWQgIiA8PCB1X2Vycm9yTmFtZShzdGF0dXMpIDw8IGVuZGw7CiAgICAjZW5kaWYKCiAgICAvLyBjaGVjayBhbmQgc2VlIGlmIHRoaXMgcmVzb3VyY2UgYnVuZGxlIGNvbnRhaW5zIGNvbGxhdGlvbiBkYXRhCiAgCiAgICBVbmljb2RlU3RyaW5nIGNvbFN0cmluZzsKICAgIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwoKICAgIFJlc291cmNlQnVuZGxlIGNvbEVsZW1zID0gYnVuZGxlLmdldCgiQ29sbGF0aW9uRWxlbWVudHMiLCBpbnRTdGF0dXMpOwogICAgaWYgKFVfRkFJTFVSRShpbnRTdGF0dXMpKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfTUlTU0lOR19SRVNPVVJDRV9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjb2xTdHJpbmcgPSBjb2xFbGVtcy5nZXRTdHJpbmdFeCgiU2VxdWVuY2UiLCBpbnRTdGF0dXMpOwoKICAgIGlmKFVfRkFJTFVSRShpbnRTdGF0dXMpKSB7CiAgICAgICAgc3RhdHVzID0gVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZihjb2xTdHJpbmcuaXNCb2d1cygpKSB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogIC8vIEhhdmluZyBsb2FkZWQgdGhlIGNvbGxhdGlvbiBmcm9tIHRoZSByZXNvdXJjZSBidW5kbGUgdGV4dCBmaWxlLAogIC8vIG5vdyByZXRyaWV2ZSB0aGUgQ29sbGF0aW9uRWxlbWVudHMgdGFnZ2VkIGRhdGEsIG1lcmdlZCB3aXRoIHRoZQogIC8vIGRlZmF1bHQgcnVsZXMuICBJZiB0aGF0IGZhaWxzLCB1c2UgdGhlIGRlZmF1bHQgcnVsZXMgYWxvbmUuCgogIGNvbFN0cmluZy5pbnNlcnQoMCwgREVGQVVMVFJVTEVTKTsKICBpZihjb2xTdHJpbmcuaXNCb2d1cygpKSB7CiAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgcmV0dXJuOwogIH0KICAgIAogIGNvbnN0cnVjdEZyb21SdWxlcyhjb2xTdHJpbmcsIGludFN0YXR1cyk7CiAgaWYoaW50U3RhdHVzID09IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1IpIHsKICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICByZXR1cm47CiAgfQogIAogIGlmKGludFN0YXR1cyAhPSBVX1pFUk9fRVJST1IpICB7CiAgICBzdGF0dXMgPSBVX1VTSU5HX0RFRkFVTFRfRVJST1I7CiAgICAgIAogICAgLy8gcHJlZGVmaW5lZCB0YWJsZXMgc2hvdWxkIGNvbnRhaW4gY29ycmVjdCBncmFtbWFyCiAgICBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICBjb25zdHJ1Y3RGcm9tUnVsZXMoREVGQVVMVFJVTEVTLCBpbnRTdGF0dXMpOwogICAgaWYoaW50U3RhdHVzICE9IFVfWkVST19FUlJPUikgewogICAgICBzdGF0dXMgPSBpbnRTdGF0dXM7CiAgICB9CiAgfSAKICAKI2lmZGVmIENPTExERUJVRwogIGNlcnIgPDwgbG9jYWxlRmlsZU5hbWUgPDwgIiBhc2NpaSBsb2FkICIgPDwgKFVfU1VDQ0VTUyhzdGF0dXMpID8gIk9LIiA6ICJGYWlsZWQiKSA8PCAiIC0gdHJ5PSAiIDw8ICh0cnlCaW5hcnlGaWxlPyJ0cnVlIjoiZmFsc2UiKSA8PCBlbmRsOwojZW5kaWYKCn0KClJ1bGVCYXNlZENvbGxhdG9yOjp+UnVsZUJhc2VkQ29sbGF0b3IoKQp7CgogICAgaWYoZlNvbWVNZW1vcnkgIT0gTlVMTCkgewogICAgICAgIGludDMyX3QgaSA9IDA7CiAgICAgICAgZm9yKGkgPSAwOyBpPGZBdmFpbGFibGVNZW1vcnk7IGkrKykgewogICAgICAgICAgICBpZigqKGZTb21lTWVtb3J5K2kpIT0gTlVMTCkgewogICAgICAgICAgICAgICAgdXBydl9mcmVlKCooZlNvbWVNZW1vcnkraSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHVwcnZfZnJlZShmU29tZU1lbW9yeSk7CiAgICAgICAgZGVsZXRlW10gZlNpemVzOwogICAgfQoKICAgIGlmIChkYXRhSXNPd25lZCkKICAgIHsKICAgICAgICBkZWxldGUgZGF0YTsKICAgIH0KCiAgICBkYXRhID0gMDsKCiAgICAvLyAgICBkZWxldGUgc291cmNlQ3Vyc29yOwogICAgLy8gICAgc291cmNlQ3Vyc29yID0gMDsKCiAgICAvLyAgICBkZWxldGUgdGFyZ2V0Q3Vyc29yOwogICAgLy8gICAgdGFyZ2V0Q3Vyc29yID0gMDsKCiAgICBpZiAoY3Vyc29yMSAhPSBOVUxMKSB7CiAgICAgICAgZGVsZXRlIGN1cnNvcjE7CiAgICAgICAgY3Vyc29yMSA9IDA7CiAgICB9CiAgICBpZiAoY3Vyc29yMiAhPSBOVUxMKSB7CiAgICAgICAgZGVsZXRlIGN1cnNvcjI7CiAgICAgICAgY3Vyc29yMiA9IDA7CiAgICB9CgogICAgZGVsZXRlIG1QYXR0ZXJuOwogICAgbVBhdHRlcm4gPSAwOwp9CgpDb2xsYXRvcioKUnVsZUJhc2VkQ29sbGF0b3I6OmNsb25lKCkgY29uc3QKewogICAgcmV0dXJuIG5ldyBSdWxlQmFzZWRDb2xsYXRvcigqdGhpcyk7Cn0KCi8vIENyZWF0ZSBhIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBvYmplY3QgdGhhdCB3aWxsIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzCi8vIGluIGEgc3RyaW5nLCB1c2luZyB0aGUgY29sbGF0aW9uIHJ1bGVzIGRlZmluZWQgaW4gdGhpcyBSdWxlQmFzZWRDb2xsYXRvcgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IqClJ1bGVCYXNlZENvbGxhdG9yOjpjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlKSBjb25zdAp7CiAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciAqbmV3Q3Vyc29yID0gMDsKCiAgICBuZXdDdXJzb3IgPSBuZXcgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKHNvdXJjZSwgdGhpcywgc3RhdHVzKTsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gbmV3Q3Vyc29yOwp9CgovLyBDcmVhdGUgYSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Igb2JqZWN0IHRoYXQgd2lsbCBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cwovLyBpbiBhIHN0cmluZywgdXNpbmcgdGhlIGNvbGxhdGlvbiBydWxlcyBkZWZpbmVkIGluIHRoaXMgUnVsZUJhc2VkQ29sbGF0b3IKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKgpSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbnN0IENoYXJhY3Rlckl0ZXJhdG9yJiBzb3VyY2UpIGNvbnN0CnsKICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yICpuZXdDdXJzb3IgPSAwOwoKICAgIG5ld0N1cnNvciA9IG5ldyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Ioc291cmNlLCB0aGlzLCBzdGF0dXMpOwogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJldHVybiBuZXdDdXJzb3I7Cn0KCi8vIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGNvbGxhdG9yJ3MgcnVsZXMuCi8vIFRoZSBzdHJpbmcgY2FuIGxhdGVyIGJlIHBhc3NlZCB0byB0aGUgY29uc3RydWN0b3IgdGhhdCB0YWtlcyBhCi8vIFVuaWNvZGVTdHJpbmcgYXJndW1lbnQsIHdoaWNoIHdpbGwgY29uc3RydWN0IGEgY29sbGF0b3IgdGhhdCdzCi8vIGZ1bmN0aW9uYWxseSBpZGVudGljYWwgdG8gdGhpcyBvbmUuCi8vIFlvdSBjYW4gYWxzbyBhbGxvdyB1c2VycyB0byBlZGl0IHRoZSBzdHJpbmcgaW4gb3JkZXIgdG8gY2hhbmdlCi8vIHRoZSBjb2xsYXRpb24gZGF0YSwgb3IgeW91IGNhbiBwcmludCBpdCBvdXQgZm9yIGluc3BlY3Rpb24sIG9yIHdoYXRldmVyLgoKY29uc3QgVW5pY29kZVN0cmluZyYKUnVsZUJhc2VkQ29sbGF0b3I6OmdldFJ1bGVzKCkgY29uc3QKewogICAgaWYgKG1QYXR0ZXJuICE9IDApCiAgICB7CiAgICAgICAgTWVyZ2VDb2xsYXRpb24qJiBub25Db25zdE1QYXR0ZXJuID0gKihNZXJnZUNvbGxhdGlvbioqKSZtUGF0dGVybjsKICAgICAgICBtUGF0dGVybi0+ZW1pdFBhdHRlcm4oZGF0YS0+cnVsZVRhYmxlKTsKICAgICAgICBkYXRhLT5pc1J1bGVUYWJsZUxvYWRlZCA9IFRSVUU7CiAgICAgICAgZGVsZXRlIG5vbkNvbnN0TVBhdHRlcm47CiAgICAgICAgbm9uQ29uc3RNUGF0dGVybiA9IDA7CiAgICB9CiAgICBlbHNlIGlmICghZGF0YS0+aXNSdWxlVGFibGVMb2FkZWQpCiAgICB7CiAgICAgICAgLy8gQXQgdGhpcyBwb2ludCB0aGUgY2FsbGVyIHdhbnRzIHRoZSBydWxlcywgYnV0IHRoZSBydWxlIHRhYmxlIGRhdGEKICAgICAgICAvLyBpcyBub3QgbG9hZGVkLiAgRnVydGhlcm1vcmUsIHRoZXJlIGlzIG5vIG1QYXR0ZXJuIG9iamVjdCB0byBsb2FkCiAgICAgICAgLy8gdGhlIHJ1bGVzIGZyb20uICBUaGVyZWZvcmUsIHdlIGZldGNoIHRoZSBydWxlcyBvZmYgdGhlIGRpc2suCiAgICAgICAgLy8gTm90aWNlIHRoYXQgd2UgcGFzcyBpbiBhIHRyeUJpbmFyeUZpbGUgdmFsdWUgb2YgRkFMU0UsIHNpbmNlCiAgICAgICAgLy8gYnkgZGVzaWduIHRoZSBiaW5hcnkgZmlsZSBoYXMgTk8gcnVsZXMgaW4gaXQhCiAgICAgICAgLy9VRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAgICAvL1J1bGVCYXNlZENvbGxhdG9yIHRlbXAoZGF0YS0+cmVhbExvY2FsZU5hbWUsIHN0YXR1cyk7CiAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgdGVtcDsKICAgICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAgICB0ZW1wLmNvbnN0cnVjdEZyb21GaWxlKGRhdGEtPmRlc2lyZWRMb2NhbGUsIGRhdGEtPnJlYWxMb2NhbGVOYW1lLCBGQUxTRSwgc3RhdHVzKTsKCiAgICAgICAgLy8gV2UgbXVzdCBjaGVjayB0aGF0IG1QYXR0ZXJuIGlzIG5vbnplcm8gaGVyZSwgb3Igd2UgcnVuIHRoZSByaXNrCiAgICAgICAgLy8gb2YgYW4gaW5maW5pdGUgbG9vcC4KICAgICAgICBpZiAoVV9TVUNDRVNTKHN0YXR1cykgJiYgdGVtcC5tUGF0dGVybiAhPSAwKQogICAgICAgIHsKICAgICAgICAgICAgZGF0YS0+cnVsZVRhYmxlID0gdGVtcC5nZXRSdWxlcygpOwogICAgICAgICAgICBkYXRhLT5pc1J1bGVUYWJsZUxvYWRlZCA9IFRSVUU7CiNpZmRlZiBfREVCVUcKLy8gICAgICAgICAgICAgIC8vIHRoZSBmb2xsb3dpbmcgaXMgdXNlZnVsIGZvciBzcGVjaWZpYyBkZWJ1Z2dpbmcgcHVycG9zZXMKLy8gICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIG5hbWU7Ci8vICAgICAgICAgICAgICAgY2VyciA8PCAiVGFibGUgY29sbGF0aW9uIHJ1bGVzIGxvYWRlZCBkeW5hbWljYWxseSBmb3IgIgovLyAgICAgICAgICAgICAgICAgICA8PCBkYXRhLT5kZXNpcmVkTG9jYWxlLmdldE5hbWUobmFtZSkKLy8gICAgICAgICAgICAgICAgICAgPDwgIiBhdCAiCi8vICAgICAgICAgICAgICAgICAgIDw8IGRhdGEtPnJlYWxMb2NhbGVOYW1lCi8vICAgICAgICAgICAgICAgICAgIDw8ICIsICIgPDwgZGVjIDw8IGRhdGEtPnJ1bGVUYWJsZS5zaXplKCkgPDwgIiBjaGFyYWN0ZXJzIgovLyAgICAgICAgICAgICAgICAgICA8PCBlbmRsOwojZW5kaWYKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKI2lmZGVmIF9ERUJVRwovLyAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBuYW1lOwovLyAgICAgICAgICAgICAgY2VyciA8PCAiVW5hYmxlIHRvIGxvYWQgdGFibGUgY29sbGF0aW9uIHJ1bGVzIGR5bmFtaWNhbGx5IGZvciAiCi8vICAgICAgICAgICAgICAgICAgPDwgZGF0YS0+ZGVzaXJlZExvY2FsZS5nZXROYW1lKG5hbWUpCi8vICAgICAgICAgICAgICAgICAgPDwgIiBhdCAiCi8vICAgICAgICAgICAgICAgICAgPDwgZGF0YS0+cmVhbExvY2FsZU5hbWUKLy8gICAgICAgICAgICAgICAgICA8PCBlbmRsOwovLyAgICAgICAgICAgICAgY2VyciA8PCAiU3RhdHVzICIgPDwgdV9lcnJvck5hbWUoc3RhdHVzKSA8PCAiLCBtUGF0dGVybiAiIDw8IHRlbXAubVBhdHRlcm4gPDwgZW5kbDsKI2VuZGlmCiAgICAgICAgICAgIC8qIFNSTCBoYXZlIHRvIGFkZCB0aGlzIGJlY2F1c2Ugd2Ugbm93IGhhdmUgdGhlIHNpdHVhdGlvbiB3aGVyZQogICAgICAgICAgICAgICBERUZBVUxUIGlzIGxvYWRlZCBmcm9tIGEgYmluYXJ5IGZpbGUgdy8gbm8gcnVsZXMuICovCiAgICAgICAgICAgIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgICAgICAgICB0ZW1wLmNvbnN0cnVjdEZyb21SdWxlcyhSdWxlQmFzZWRDb2xsYXRvcjo6REVGQVVMVFJVTEVTLCBpbnRTdGF0dXMpOwoKICAgICAgICAgICAgaWYoVV9TVUNDRVNTKGludFN0YXR1cykgJiYgKHRlbXAubVBhdHRlcm4gIT0gMCkpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGF0YS0+cnVsZVRhYmxlID0gdGVtcC5nZXRSdWxlcygpOwogICAgICAgICAgICAgICAgZGF0YS0+aXNSdWxlVGFibGVMb2FkZWQgPSBUUlVFOwogICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIGRhdGEtPnJ1bGVUYWJsZTsKfQoKCkNvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdApSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZSggY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsZW5ndGgpIGNvbnN0CnsKICAgIFVuaWNvZGVTdHJpbmcgc291cmNlX3RvZ287CiAgICBVbmljb2RlU3RyaW5nIHRhcmdldF90b2dvOwogICAgVVRleHRPZmZzZXQgYmVnaW49MDsKCiAgICBzb3VyY2UuZXh0cmFjdChiZWdpbiwgdXBydl9taW4obGVuZ3RoLHNvdXJjZS5sZW5ndGgoKSksIHNvdXJjZV90b2dvKTsKICAgIHRhcmdldC5leHRyYWN0KGJlZ2luLCB1cHJ2X21pbihsZW5ndGgsdGFyZ2V0Lmxlbmd0aCgpKSwgdGFyZ2V0X3RvZ28pOwogICAgcmV0dXJuIChSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZShzb3VyY2VfdG9nbywgdGFyZ2V0X3RvZ28pKTsKfQoKQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0ICAgClJ1bGVCYXNlZENvbGxhdG9yOjpjb21wYXJlKGNvbnN0ICAgVUNoYXIqIHNvdXJjZSwgCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVUNoYXIqICB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHRhcmdldExlbmd0aCkgY29uc3QKewoJVUNvbGxhdGlvblJlc3VsdCBzdHJjb2xsX3Jlc3VsdCA9IHVjb2xfc3RyY29sbCgoVUNvbGxhdG9yICopdGhpcywgc291cmNlLCBzb3VyY2VMZW5ndGgsIHRhcmdldCwgdGFyZ2V0TGVuZ3RoKTsKCQoJaWYoc3RyY29sbF9yZXN1bHQgPT0gVUNPTF9MRVNTKSB7CgkJcmV0dXJuIENvbGxhdG9yOjpMRVNTOwoJfSBlbHNlIGlmKHN0cmNvbGxfcmVzdWx0ID09IFVDT0xfR1JFQVRFUikgewoJCXJldHVybiBDb2xsYXRvcjo6R1JFQVRFUjsKCX0gZWxzZSB7CgkJcmV0dXJuIENvbGxhdG9yOjpFUVVBTDsKCX0KfQoKQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0ICAgClJ1bGVCYXNlZENvbGxhdG9yOjpjb21wYXJlRXgoY29uc3QgICBVQ2hhciogc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgICBVQ2hhciogIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgdGFyZ2V0TGVuZ3RoKSBjb25zdAp7CgogICAgLy8gY2hlY2sgaWYgc291cmNlIGFuZCB0YXJnZXQgYXJlIHZhbGlkIHN0cmluZ3MKICAgIGlmICgoKHNvdXJjZSA9PSAwKSAmJiAodGFyZ2V0ID09IDApKSB8fAogICAgICAgICgoc291cmNlTGVuZ3RoID09IDApICYmICh0YXJnZXRMZW5ndGggPT0gMCkpKQogICAgewogICAgICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7CiAgICB9CgogICAgQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IHJlc3VsdCA9IENvbGxhdG9yOjpFUVVBTDsKICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwoKICAgIGlmIChjdXJzb3IxID09IE5VTEwpCiAgICB7CiAgICAgICAgKChSdWxlQmFzZWRDb2xsYXRvciAqKXRoaXMpLT5jdXJzb3IxID0gbmV3IE5vcm1hbGl6ZXJJdGVyYXRvcihzb3VyY2UsIHNvdXJjZUxlbmd0aCwgZ2V0RGVjb21wb3NpdGlvbigpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBjdXJzb3IxLT5zZXRNb2RlQW5kVGV4dChnZXREZWNvbXBvc2l0aW9uKCksIHNvdXJjZSwgc291cmNlTGVuZ3RoLCBzdGF0dXMpOwogICAgfQoKICAgIGlmICggLypjdXJzb3IxLT5jdXJzb3IgPT0gTlVMTCB8fCovIFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7CiAgICB9CgogICAgaWYgKGN1cnNvcjIgPT0gTlVMTCkKICAgIHsKICAgICAgICAoKFJ1bGVCYXNlZENvbGxhdG9yICopdGhpcyktPmN1cnNvcjIgPSBuZXcgTm9ybWFsaXplckl0ZXJhdG9yKHRhcmdldCwgdGFyZ2V0TGVuZ3RoLCBnZXREZWNvbXBvc2l0aW9uKCkpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGN1cnNvcjItPnNldE1vZGVBbmRUZXh0KGdldERlY29tcG9zaXRpb24oKSwgdGFyZ2V0LCB0YXJnZXRMZW5ndGgsIHN0YXR1cyk7CiAgICB9CgogICAgaWYgKC8qY3Vyc29yMiA9PSBOVUxMIHx8Ki8gVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpFUVVBTDsKICAgIH0KCiAgICBpbnQzMl90IHNPcmRlciwgdE9yZGVyOwogICAgLy8gICAgaW50MzJfdCBzT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUiwgdE9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVI7CiAgICBVQm9vbCBnZXRzID0gVFJVRSwgZ2V0dCA9IFRSVUU7CiAgICBVQm9vbCBpbml0aWFsQ2hlY2tTZWNUZXIgPSBnZXRTdHJlbmd0aCgpID49IENvbGxhdG9yOjpTRUNPTkRBUlk7CiAgICBVQm9vbCBjaGVja1NlY1RlciA9IGluaXRpYWxDaGVja1NlY1RlcjsKICAgIFVCb29sIGNoZWNrVGVydGlhcnkgPSBnZXRTdHJlbmd0aCgpID49IENvbGxhdG9yOjpURVJUSUFSWTsKICAgIFVCb29sIGlzRnJlbmNoU2VjID0gZGF0YS0+aXNGcmVuY2hTZWM7CiAgICB1aW50MzJfdCBwU09yZGVyLCBwVE9yZGVyOwoKICAgIGZvcig7OykKICAgIHsKICAgICAgICAvLyBHZXQgdGhlIG5leHQgY29sbGF0aW9uIGVsZW1lbnQgaW4gZWFjaCBvZiB0aGUgc3RyaW5ncywgdW5sZXNzCiAgICAgICAgLy8gd2UndmUgYmVlbiByZXF1ZXN0ZWQgdG8gc2tpcCBpdC4KICAgICAgICBpZiAoZ2V0cykKICAgICAgICB7CiAgICAgICAgICAgIHNPcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoKE5vcm1hbGl6ZXJJdGVyYXRvciopY3Vyc29yMSwgc3RhdHVzKTsKCiAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpFUVVBTDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZ2V0cyA9IFRSVUU7CgogICAgICAgIGlmIChnZXR0KQogICAgICAgIHsKICAgICAgICAgICAgdE9yZGVyID0gZ2V0U3RyZW5ndGhPcmRlcigoTm9ybWFsaXplckl0ZXJhdG9yKiljdXJzb3IyLCBzdGF0dXMpOwoKICAgICAgICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGdldHQgPSBUUlVFOwoKICAgICAgICAvLyBJZiB3ZSd2ZSBoaXQgdGhlIGVuZCBvZiBvbmUgb2YgdGhlIHN0cmluZ3MsIGp1bXAgb3V0IG9mIHRoZSBsb29wCiAgICAgICAgaWYgKChzT3JkZXIgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpfHwKICAgICAgICAgICAgKHRPcmRlciA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUikpCiAgICAgICAgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gZGlmZmVyZW5jZSBhdCB0aGlzIHBvc2l0aW9uLCB3ZSBjYW4gc2tpcCB0byB0aGUKICAgICAgICAvLyBuZXh0IG9uZS4KICAgICAgICBwU09yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIoc09yZGVyKTsKICAgICAgICBwVE9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIodE9yZGVyKTsKICAgICAgICBpZiAoc09yZGVyID09IHRPcmRlcikKICAgICAgICB7CiAgICAgICAgICAgIGlmIChpc0ZyZW5jaFNlYyAmJiBwU09yZGVyICE9IFNFQ0lHTk9SQUJMRSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFjaGVja1NlY1RlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBpbiBmcmVuY2gsIGEgc2Vjb25kYXJ5IGRpZmZlcmVuY2UgbW9yZSB0byB0aGUgcmlnaHQgaXMgc3Ryb25nZXIsCiAgICAgICAgICAgICAgICAgICAgLy8gc28gYWNjZW50cyBoYXZlIHRvIGJlIGNoZWNrZWQgd2l0aCBlYWNoIGJhc2UgZWxlbWVudAogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gaW5pdGlhbENoZWNrU2VjVGVyOwoKICAgICAgICAgICAgICAgICAgICAvLyBidXQgdGVydGlhcnkgZGlmZmVyZW5jZXMgYXJlIGxlc3MgaW1wb3J0YW50IHRoYW4gdGhlIGZpcnN0IAogICAgICAgICAgICAgICAgICAgIC8vIHNlY29uZGFyeSBkaWZmZXJlbmNlLCBzbyBjaGVja2luZyB0ZXJ0aWFyeSByZW1haW5zIGRpc2FibGVkCiAgICAgICAgICAgICAgICAgICAgY2hlY2tUZXJ0aWFyeSA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIC8vIENvbXBhcmUgcHJpbWFyeSBkaWZmZXJlbmNlcyBmaXJzdC4KICAgICAgICBpZiAocFNPcmRlciAhPSBwVE9yZGVyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHNPcmRlciA9PSBJR05PUkFCTEUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBlbnRpcmUgc291cmNlIGVsZW1lbnQgaXMgaWdub3JhYmxlLgogICAgICAgICAgICAgICAgLy8gU2tpcCB0byB0aGUgbmV4dCBzb3VyY2UgZWxlbWVudCwgYnV0IGRvbid0IGZldGNoIGFub3RoZXIgdGFyZ2V0IGVsZW1lbnQuCiAgICAgICAgICAgICAgICBnZXR0ID0gRkFMU0U7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRPcmRlciA9PSBJR05PUkFCTEUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGdldHMgPSBGQUxTRTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBUaGUgc291cmNlIGFuZCB0YXJnZXQgZWxlbWVudHMgYXJlbid0IGlnbm9yYWJsZSwgYnV0IGl0J3Mgc3RpbGwgcG9zc2libGUKICAgICAgICAgICAgLy8gZm9yIHRoZSBwcmltYXJ5IGNvbXBvbmVudCBvZiBvbmUgb2YgdGhlIGVsZW1lbnRzIHRvIGJlIGlnbm9yYWJsZS4uLi4KICAgICAgICAgICAgaWYgKHBTT3JkZXIgPT0gUFJJTUlHTk9SQUJMRSkgIC8vIHByaW1hcnkgb3JkZXIgaW4gc291cmNlIGlzIGlnbm9yYWJsZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBUaGUgc291cmNlJ3MgcHJpbWFyeSBpcyBpZ25vcmFibGUsIGJ1dCB0aGUgdGFyZ2V0J3MgaXNuJ3QuICBXZSB0cmVhdCBpZ25vcmFibGVzCiAgICAgICAgICAgICAgICAvLyBhcyBhIHNlY29uZGFyeSBkaWZmZXJlbmNlLCBzbyByZW1lbWJlciB0aGF0IHdlIGZvdW5kIG9uZS4KICAgICAgICAgICAgICAgIGlmIChjaGVja1NlY1RlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBDb2xsYXRvcjo6R1JFQVRFUjsgIC8vIChzdHJlbmd0aCBpcyBTRUNPTkRBUlkpCiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWNUZXIgPSBGQUxTRTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBTa2lwIHRvIHRoZSBuZXh0IHNvdXJjZSBlbGVtZW50LCBidXQgZG9uJ3QgZmV0Y2ggYW5vdGhlciB0YXJnZXQgZWxlbWVudC4KICAgICAgICAgICAgICAgIGdldHQgPSBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChwVE9yZGVyID09IFBSSU1JR05PUkFCTEUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIHJlY29yZCBkaWZmZXJlbmNlcyAtIHNlZSB0aGUgY29tbWVudCBhYm92ZS4KICAgICAgICAgICAgICAgIGlmIChjaGVja1NlY1RlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBDb2xsYXRvcjo6TEVTUzsgIC8vIChzdHJlbmd0aCBpcyBTRUNPTkRBUlkpCiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWNUZXIgPSBGQUxTRTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBTa2lwIHRvIHRoZSBuZXh0IHRhcmdldCBlbGVtZW50LCBidXQgZG9uJ3QgZmV0Y2ggYW5vdGhlciBzb3VyY2UgZWxlbWVudC4KICAgICAgICAgICAgICAgIGdldHMgPSBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIE5laXRoZXIgb2YgdGhlIG9yZGVycyBpcyBpZ25vcmFibGUsIGFuZCB3ZSBhbHJlYWR5IGtub3cgdGhhdCB0aGUgcHJpbWFyeQogICAgICAgICAgICAgICAgLy8gb3JkZXJzIGFyZSBkaWZmZXJlbnQgYmVjYXVzZSBvZiB0aGUgKHBTT3JkZXIgIT0gcFRPcmRlcikgdGVzdCBhYm92ZS4KICAgICAgICAgICAgICAgIC8vIFJlY29yZCB0aGUgZGlmZmVyZW5jZSBhbmQgc3RvcCB0aGUgY29tcGFyaXNvbi4KICAgICAgICAgICAgICAgIGlmIChwU09yZGVyIDwgcFRPcmRlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkxFU1M7ICAvLyAoc3RyZW5ndGggaXMgUFJJTUFSWSkKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkdSRUFURVI7ICAvLyAoc3RyZW5ndGggaXMgUFJJTUFSWSkKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgeyAvLyBlbHNlIG9mIGlmICggcFNPcmRlciAhPSBwVE9yZGVyICkKICAgICAgICAgICAgLy8gcHJpbWFyeSBvcmRlciBpcyB0aGUgc2FtZSwgYnV0IGNvbXBsZXRlIG9yZGVyIGlzIGRpZmZlcmVudC4gU28gdGhlcmUKICAgICAgICAgICAgLy8gYXJlIG5vIGJhc2UgZWxlbWVudHMgYXQgdGhpcyBwb2ludCwgb25seSBpZ25vcmFibGVzIChTaW5jZSB0aGUgc3RyaW5ncyBhcmUKICAgICAgICAgICAgLy8gbm9ybWFsaXplZCkKCiAgICAgICAgICAgIGlmIChjaGVja1NlY1RlcikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gYSBzZWNvbmRhcnkgb3IgdGVydGlhcnkgZGlmZmVyZW5jZSBtYXkgc3RpbGwgbWF0dGVyCiAgICAgICAgICAgICAgICB1aW50MzJfdCBzZWNTT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKHNPcmRlcik7CiAgICAgICAgICAgICAgICB1aW50MzJfdCBzZWNUT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKHRPcmRlcik7CgogICAgICAgICAgICAgICAgaWYgKHNlY1NPcmRlciAhPSBzZWNUT3JkZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy8gdGhlcmUgaXMgYSBzZWNvbmRhcnkgZGlmZmVyZW5jZQogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IChzZWNTT3JkZXIgPCBzZWNUT3JkZXIpID8gQ29sbGF0b3I6OkxFU1MgOiBDb2xsYXRvcjo6R1JFQVRFUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAoc3RyZW5ndGggaXMgU0VDT05EQVJZKQogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gRkFMU0U7IAogICAgICAgICAgICAgICAgICAgIC8vIChldmVuIGluIGZyZW5jaCwgb25seSB0aGUgZmlyc3Qgc2Vjb25kYXJ5IGRpZmZlcmVuY2Ugd2l0aGluCiAgICAgICAgICAgICAgICAgICAgLy8gIGEgYmFzZSBjaGFyYWN0ZXIgbWF0dGVycykKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY2hlY2tUZXJ0aWFyeSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGEgdGVydGlhcnkgZGlmZmVyZW5jZSBtYXkgc3RpbGwgbWF0dGVyCiAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHRlclNPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6dGVydGlhcnlPcmRlcihzT3JkZXIpOwogICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCB0ZXJUT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnRlcnRpYXJ5T3JkZXIodE9yZGVyKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZXJTT3JkZXIgIT0gdGVyVE9yZGVyKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZSBpcyBhIHRlcnRpYXJ5IGRpZmZlcmVuY2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9ICh0ZXJTT3JkZXIgPCB0ZXJUT3JkZXIpID8gQ29sbGF0b3I6OkxFU1MgOiBDb2xsYXRvcjo6R1JFQVRFUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAoc3RyZW5ndGggaXMgVEVSVElBUlkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja1RlcnRpYXJ5ID0gRkFMU0U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gLy8gaWYgKGNoZWNrU2VjVGVyKQoKICAgICAgICB9ICAvLyBpZiAoIHBTT3JkZXIgIT0gcFRPcmRlciApCiAgICB9IC8vIHdoaWxlKCkKCiAgICBpZiAoc09yZGVyICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIC8vICh0T3JkZXIgbXVzdCBiZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUiwKICAgICAgICAvLyAgc2luY2UgdGhpcyBwb2ludCBpcyBvbmx5IHJlYWNoZWQgd2hlbiBzT3JkZXIgb3IgdE9yZGVyIGlzIE5VTExPUkRFUi4pCiAgICAgICAgLy8gVGhlIHNvdXJjZSBzdHJpbmcgaGFzIG1vcmUgZWxlbWVudHMsIGJ1dCB0aGUgdGFyZ2V0IHN0cmluZyBoYXNuJ3QuCiAgICAgICAgZG8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByaW1hcnlPcmRlcihzT3JkZXIpICE9IFBSSU1JR05PUkFCTEUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFdlIGZvdW5kIGFuIGFkZGl0aW9uYWwgbm9uLWlnbm9yYWJsZSBiYXNlIGNoYXJhY3RlciBpbiB0aGUgc291cmNlIHN0cmluZy4KICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBwcmltYXJ5IGRpZmZlcmVuY2UsIHNvIHRoZSBzb3VyY2UgaXMgZ3JlYXRlcgogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpHUkVBVEVSOyAvLyAoc3RyZW5ndGggaXMgUFJJTUFSWSkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIoc09yZGVyKSAhPSBTRUNJR05PUkFCTEUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIEFkZGl0aW9uYWwgc2Vjb25kYXJ5IGVsZW1lbnRzIG1lYW4gdGhlIHNvdXJjZSBzdHJpbmcgaXMgZ3JlYXRlcgogICAgICAgICAgICAgICAgaWYgKGNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpHUkVBVEVSOyAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IAogICAgICAgIH0KICAgICAgICB3aGlsZSAoKHNPcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoY3Vyc29yMSwgc3RhdHVzKSkgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpOwogICAgfQogICAgZWxzZSBpZiAodE9yZGVyICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIC8vIFRoZSB0YXJnZXQgc3RyaW5nIGhhcyBtb3JlIGVsZW1lbnRzLCBidXQgdGhlIHNvdXJjZSBzdHJpbmcgaGFzbid0LgogICAgICAgIGRvCiAgICAgICAgewogICAgICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIodE9yZGVyKSAhPSBQUklNSUdOT1JBQkxFKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBXZSBmb3VuZCBhbiBhZGRpdGlvbmFsIG5vbi1pZ25vcmFibGUgYmFzZSBjaGFyYWN0ZXIgaW4gdGhlIHRhcmdldCBzdHJpbmcuCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgcHJpbWFyeSBkaWZmZXJlbmNlLCBzbyB0aGUgc291cmNlIGlzIGxlc3MKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6TEVTUzsgLy8gKHN0cmVuZ3RoIGlzIFBSSU1BUlkpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKHRPcmRlcikgIT0gU0VDSUdOT1JBQkxFKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBBZGRpdGlvbmFsIHNlY29uZGFyeSBlbGVtZW50cyBpbiB0aGUgdGFyZ2V0IG1lYW4gdGhlIHNvdXJjZSBzdHJpbmcgaXMgbGVzcwogICAgICAgICAgICAgICAgaWYgKGNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpMRVNTOyAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IAogICAgICAgIH0KICAgICAgICB3aGlsZSAoKHRPcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoY3Vyc29yMiwgc3RhdHVzKSkgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpOwogICAgfQoKCiAgICAvLyBGb3IgSURFTlRJQ0FMIGNvbXBhcmlzb25zLCB3ZSB1c2UgYSBiaXR3aXNlIGNoYXJhY3RlciBjb21wYXJpc29uCiAgICAvLyBhcyBhIHRpZWJyZWFrZXIgaWYgYWxsIGVsc2UgaXMgZXF1YWwKICAgIC8vIE5PVEU6IFRoZSBqYXZhIGNvZGUgY29tcGFyZXMgcmVzdWx0IHdpdGggMCwgYW5kIAogICAgLy8gcHV0cyB0aGUgcmVzdWx0IG9mIHRoZSBzdHJpbmcgY29tcGFyaXNvbiBkaXJlY3RseSBpbnRvIHJlc3VsdAogICAgaWYgKHJlc3VsdCA9PSBDb2xsYXRvcjo6RVFVQUwgJiYgZ2V0U3RyZW5ndGgoKSA9PSBJREVOVElDQUwpCiAgICB7CiNpZiAwCiAgICAgIC8vICoqKioqKioqIGZvciB0aGUgIFVDaGFyIG5vcm1hbGl6YXRpb24gaW50ZXJmYWNlLgogICAgICAvLyBJdCBkb2Vzbid0IHdvcmsgbXVjaCBmYXN0ZXIsIGFuZCB0aGUgY29kZSB3YXMgYnJva2VuCiAgICAgIC8vIHNvIGl0J3MgY29tbWVudGVkIG91dC4gLS1zcmwKLy8gICAgICAgICAgVUNoYXIgc291cmNlRGVjb21wWzEwMjRdLCB0YXJnZXREZWNvbXBbMTAyNF07Ci8vICAgICAgICAgIGludDMyX3Qgc291cmNlRGVjb21wTGVuZ3RoID0gMTAyNDsKLy8gICAgICAgICAgaW50MzJfdCB0YXJnZXREZWNvbXBMZW5ndGggPSAxMDI0OwoKLy8gICAgICAgICAgaW50OF90IGNvbXBhcmlzb247Ci8vICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcE1vZGUgPSBnZXREZWNvbXBvc2l0aW9uKCk7CgovLyAgICAgICAgICBpZiAoZGVjb21wTW9kZSAhPSBOb3JtYWxpemVyOjpOT19PUCkKLy8gICAgICAgICAgICB7Ci8vICAgICAgICAgICAgICBOb3JtYWxpemVyOjpub3JtYWxpemUoc291cmNlLCBzb3VyY2VMZW5ndGgsIGRlY29tcE1vZGUsCi8vICAgICAgICAgICAgICAgICAgICAgICAgMCwgc291cmNlRGVjb21wLCBzb3VyY2VEZWNvbXBMZW5ndGgsIHN0YXR1cyk7CgovLyAgICAgICAgICAgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKHRhcmdldCwgdGFyZ2V0TGVuZ3RoLCBkZWNvbXBNb2RlLAovLyAgICAgICAgICAgICAgICAgICAgICAgIDAsIHRhcmdldERlY29tcCwgdGFyZ2V0RGVjb21wTGVuZ3RoLCBzdGF0dXMpOwoKLy8gICAgICAgICAgICAgIGNvbXBhcmlzb24gPSB1X3N0cmNtcChzb3VyY2VEZWNvbXAsdGFyZ2V0RGVjb21wKTsKLy8gICAgICAgICAgICB9Ci8vICAgICAgICAgIGVsc2UKLy8gICAgICAgICAgICB7Ci8vICAgICAgICAgICAgICBjb21wYXJpc29uID0gdV9zdHJjbXAoc291cmNlLCB0YXJnZXQpOyAvKiAhICovCi8vICAgICAgICAgICAgfQoKI2Vsc2UKCiAgICAgICAgVW5pY29kZVN0cmluZyBzb3VyY2VEZWNvbXAsIHRhcmdldERlY29tcDsKCiAgICAgICAgaW50OF90IGNvbXBhcmlzb247CiAgICAgICAgCiAgICAgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKFVuaWNvZGVTdHJpbmcoc291cmNlLCBzb3VyY2VMZW5ndGgpLCBnZXREZWNvbXBvc2l0aW9uKCksIAogICAgICAgICAgICAgICAgICAgICAgMCwgc291cmNlRGVjb21wLCAgc3RhdHVzKTsKCiAgICAgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKFVuaWNvZGVTdHJpbmcodGFyZ2V0LCB0YXJnZXRMZW5ndGgpLCBnZXREZWNvbXBvc2l0aW9uKCksIAogICAgICAgICAgICAgICAgICAgICAgMCwgdGFyZ2V0RGVjb21wLCAgc3RhdHVzKTsKICAgICAgICAKICAgICAgICBjb21wYXJpc29uID0gc291cmNlRGVjb21wLmNvbXBhcmUodGFyZ2V0RGVjb21wKTsKI2VuZGlmCgogICAgICAgIGlmIChjb21wYXJpc29uIDwgMCkKICAgICAgICB7CiAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpMRVNTOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChjb21wYXJpc29uID09IDApCiAgICAgICAgewogICAgICAgICAgICByZXN1bHQgPSBDb2xsYXRvcjo6RVFVQUw7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpHUkVBVEVSOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9CgppbnQzMl90ClJ1bGVCYXNlZENvbGxhdG9yOjpuZXh0Q29udHJhY3RDaGFyKE5vcm1hbGl6ZXJJdGVyYXRvciAqY3Vyc29yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNoYXIgY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QKewogICAgLy8gRmlyc3QgZ2V0IHRoZSBvcmRlcmluZyBvZiB0aGlzIHNpbmdsZSBjaGFyYWN0ZXIKICAgIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50ICpsaXN0ID0gZ2V0Q29udHJhY3RWYWx1ZXMoY2gpOwogICAgRW50cnlQYWlyICpwYWlyID0gKEVudHJ5UGFpciAqKWxpc3QtPmF0KDApOwogICAgaW50MzJfdCBvcmRlciA9IHBhaXItPnZhbHVlOwoKICAgIC8vIE5vdyBpdGVyYXRlIHRocm91Z2ggdGhlIGNoYXJzIGZvbGxvd2luZyBpdCBhbmQKICAgIC8vIGxvb2sgZm9yIHRoZSBsb25nZXN0IG1hdGNoCiAgICAoKFVuaWNvZGVTdHJpbmcmKWtleSkucmVtb3ZlKCk7CiAgICAoKFVuaWNvZGVTdHJpbmcmKWtleSkgKz0gY2g7CgogICAgd2hpbGUgKChjaCA9IGN1cnNvci0+Y3VycmVudCgpKSAhPSBOb3JtYWxpemVyOjpET05FKQogICAgewogICAgICAgICgoVW5pY29kZVN0cmluZyYpa2V5KSArPSBjaDsKCiAgICAgICAgaW50MzJfdCBuID0gZ2V0RW50cnkobGlzdCwga2V5LCBUUlVFKTsKCiAgICAgICAgaWYgKG4gPT0gVU5NQVBQRUQpCiAgICAgICAgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY3Vyc29yLT5uZXh0KCk7CgogICAgICAgIHBhaXIgPSAoRW50cnlQYWlyICopbGlzdC0+YXQobik7CiAgICAgICAgb3JkZXIgPSBwYWlyLT52YWx1ZTsKICAgIH0KCiAgICByZXR1cm4gb3JkZXI7Cn0KCi8vIENvbXBhcmUgdHdvIHN0cmluZ3MgdXNpbmcgdGhpcyBjb2xsYXRvcgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0CnsKCVVDaGFyIHVTc3RhcnRbdGJsY29sbF9TdGFja0J1ZmZlckxlbl07CglVQ2hhciB1VHN0YXJ0W3RibGNvbGxfU3RhY2tCdWZmZXJMZW5dOwoJVUNoYXIgKnVTb3VyY2UgPSB1U3N0YXJ0OwoJVUNoYXIgKnVUYXJnZXQgPSB1VHN0YXJ0OwoJdWludDMyX3Qgc291cmNlTGVuID0gc291cmNlLmxlbmd0aCgpOwoJdWludDMyX3QgdGFyZ2V0TGVuID0gdGFyZ2V0Lmxlbmd0aCgpOwoJaWYoc291cmNlTGVuID49IHRibGNvbGxfU3RhY2tCdWZmZXJMZW4pIHsKCQl1U291cmNlID0gbmV3IFVDaGFyW3NvdXJjZUxlbisxXTsKCX0KCWlmKHRhcmdldExlbiA+PSB0Ymxjb2xsX1N0YWNrQnVmZmVyTGVuKSB7CgkJdVRhcmdldCA9IG5ldyBVQ2hhclt0YXJnZXRMZW4rMV07Cgl9CiAgICBzb3VyY2UuZXh0cmFjdCgwLCBzb3VyY2VMZW4sIHVTb3VyY2UpOwogICAgdVNvdXJjZVtzb3VyY2VMZW5dID0gMDsKICAgIHRhcmdldC5leHRyYWN0KDAsIHRhcmdldExlbiwgdVRhcmdldCk7CiAgICB1VGFyZ2V0W3RhcmdldExlbl0gPSAwOwoJQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IHJlc3VsdCA9IGNvbXBhcmUodVNvdXJjZSwgc291cmNlTGVuLCB1VGFyZ2V0LCB0YXJnZXRMZW4pOwoKCWlmKHVTc3RhcnQgIT0gdVNvdXJjZSkgewoJCWRlbGV0ZVtdIHVTb3VyY2U7Cgl9CglpZih1VHN0YXJ0ICE9IHVUYXJnZXQpIHsKCQlkZWxldGVbXSB1VGFyZ2V0OwoJfQoJcmV0dXJuIHJlc3VsdDsKfQoKLy8gUmV0cmlldmUgYSBjb2xsYXRpb24ga2V5IGZvciB0aGUgc3BlY2lmaWVkIHN0cmluZwovLyBUaGUga2V5IGNhbiBiZSBjb21wYXJlZCB3aXRoIG90aGVyIGNvbGxhdGlvbiBrZXlzIHVzaW5nIGEgYml0d2lzZSBjb21wYXJpc29uCi8vIChlLmcuIG1lbWNtcCkgdG8gZmluZCB0aGUgb3JkZXJpbmcgb2YgdGhlaXIgcmVzcGVjdGl2ZSBzb3VyY2Ugc3RyaW5ncy4KLy8gVGhpcyBpcyBoYW5keSB3aGVuIGRvaW5nIGEgc29ydCwgd2hlcmUgZWFjaCBzb3J0IGtleSBtdXN0IGJlIGNvbXBhcmVkCi8vIG1hbnkgdGltZXMuCi8vCi8vIFRoZSBiYXNpYyBhbGdvcml0aG0gaGVyZSBpcyB0byBmaW5kIGFsbCBvZiB0aGUgY29sbGF0aW9uIGVsZW1lbnRzIGZvciBlYWNoCi8vIGNoYXJhY3RlciBpbiB0aGUgc291cmNlIHN0cmluZywgY29udmVydCB0aGVtIHRvIGFuIEFTQ0lJIHJlcHJlc2VudGF0aW9uLAovLyBhbmQgcHV0IHRoZW0gaW50byB0aGUgY29sbGF0aW9uIGtleS4gIEJ1dCBpdCdzIHRyaWNraWVyIHRoYW4gdGhhdC4KLy8gRWFjaCBjb2xsYXRpb24gZWxlbWVudCBpbiBhIHN0cmluZyBoYXMgdGhyZWUgY29tcG9uZW50czogcHJpbWFyeSAoJ0EnIHZzICdCJyksCi8vIHNlY29uZGFyeSAoJ3UnIHZzICf8JyksIGFuZCB0ZXJ0aWFyeSAoJ0EnIHZzICdhJyksIGFuZCBhIHByaW1hcnkgZGlmZmVyZW5jZQovLyBhdCB0aGUgZW5kIG9mIGEgc3RyaW5nIHRha2VzIHByZWNlZGVuY2Ugb3ZlciBhIHNlY29uZGFyeSBvciB0ZXJ0aWFyeQovLyBkaWZmZXJlbmNlIGVhcmxpZXIgaW4gdGhlIHN0cmluZy4KLy8KLy8gVG8gYWNjb3VudCBmb3IgdGhpcywgd2UgcHV0IGFsbCBvZiB0aGUgcHJpbWFyeSBvcmRlcnMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUKLy8gc3RyaW5nLCBmb2xsb3dlZCBieSB0aGUgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBvcmRlcnMuIEVhY2ggc2V0IG9mIG9yZGVycyBpcwovLyB0ZXJtaW5hdGVkIGJ5IG51bGxzIHNvIHRoYXQgYSBrZXkgZm9yIGEgc3RyaW5nIHdoaWNoIGlzIGEgaW5pdGlhbCBzdWJzdHJpbmcgb2YKLy8gYW5vdGhlciBrZXkgd2lsbCBjb21wYXJlIGxlc3Mgd2l0aG91dCBhbnkgc3BlY2lhbCBjYXNlLgovLwovLyBIZXJlJ3MgYSBoeXBvdGhldGljYWwgZXhhbXBsZSwgd2l0aCB0aGUgY29sbGF0aW9uIGVsZW1lbnQgcmVwcmVzZW50ZWQgYXMKLy8gYSB0aHJlZS1kaWdpdCBudW1iZXIsIG9uZSBkaWdpdCBmb3IgcHJpbWFyeSwgb25lIGZvciBzZWNvbmRhcnksIGV0Yy4KLy8KLy8gU3RyaW5nOiAgICAgICAgICAgICAgQSAgICAgYSAgICAgQiAgICDJCi8vIENvbGxhdGlvbiBFbGVtZW50czogMTAxICAgMTAwICAgMjAxICA1MTEKLy8gQ29sbGF0aW9uIEtleTogICAgICAxMTI1PG51bGw+MDAwMTxudWxsPjEwMTE8bnVsbD4KLy8KLy8gVG8gbWFrZSB0aGluZ3MgZXZlbiB0cmlja2llciwgc2Vjb25kYXJ5IGRpZmZlcmVuY2VzIChhY2NlbnQgbWFya3MpIGFyZSBjb21wYXJlZAovLyBzdGFydGluZyBhdCB0aGUgKmVuZCogb2YgdGhlIHN0cmluZyBpbiBsYW5ndWFnZXMgd2l0aCBGcmVuY2ggc2Vjb25kYXJ5IG9yZGVyaW5nLgovLyBCdXQgd2hlbiBjb21wYXJpbmcgdGhlIGFjY2VudCBtYXJrcyBvbiBhIHNpbmdsZSBiYXNlIGNoYXJhY3RlciwgdGhleSBhcmUgY29tcGFyZWQKLy8gZnJvbSB0aGUgYmVnaW5uaW5nLiAgVG8gaGFuZGxlIHRoaXMsIHdlIHJldmVyc2UgYWxsIG9mIHRoZSBhY2NlbnRzIHRoYXQgYmVsb25nCi8vIHRvIGVhY2ggYmFzZSBjaGFyYWN0ZXIsIHRoZW4gd2UgcmV2ZXJzZSB0aGUgZW50aXJlIHN0cmluZyBvZiBzZWNvbmRhcnkgb3JkZXJpbmdzCi8vIGF0IHRoZSBlbmQuCi8vCkNvbGxhdGlvbktleSYKUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbGxhdGlvbktleSggY29uc3QgICBVbmljb2RlU3RyaW5nJiAgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25LZXkmICAgc29ydGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpIGNvbnN0CnsKCVVDaGFyIHNTdGFydFt0Ymxjb2xsX1N0YWNrQnVmZmVyTGVuXTsKCVVDaGFyICp1U291cmNlID0gc1N0YXJ0OwoJdWludDMyX3Qgc291cmNlTGVuID0gc291cmNlLmxlbmd0aCgpOwoJaWYoc291cmNlTGVuID49IHRibGNvbGxfU3RhY2tCdWZmZXJMZW4pIHsKCQl1U291cmNlID0gbmV3IFVDaGFyW3NvdXJjZUxlbisxXTsKCX0KICAgIHNvdXJjZS5leHRyYWN0KDAsIHNvdXJjZUxlbiwgdVNvdXJjZSk7CiAgICB1U291cmNlW3NvdXJjZUxlbl0gPSAwOwoJQ29sbGF0aW9uS2V5JiByZXN1bHQgPSBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29sbGF0aW9uS2V5KHVTb3VyY2UsIHNvdXJjZUxlbiwgc29ydGtleSwgc3RhdHVzKTsKCWlmKHNTdGFydCAhPSB1U291cmNlKSB7CgkJZGVsZXRlW10gdVNvdXJjZTsKCX0KCXJldHVybiByZXN1bHQ7Cn0KCkNvbGxhdGlvbktleSYKUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbGxhdGlvbktleSggY29uc3QgICBVQ2hhciogIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYgICBzb3J0a2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykgY29uc3QKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsKICAgICAgICByZXR1cm4gc29ydGtleS5zZXRUb0JvZ3VzKCk7CiAgICB9CiAgICAKICAgIGlmICgoIXNvdXJjZSkgfHwgKHNvdXJjZUxlbiA9PSAwKSkKICAgIHsKICAgICAgICByZXR1cm4gc29ydGtleS5yZXNldCgpOwogICAgfQoKICAgIHVpbnQ4X3QgKnJlc3VsdDsgIAoJaW50MzJfdCByZXNMZW4gPSAwOwogICAgcmVzdWx0ID0gdWNvbF9nZXRTb3J0S2V5V2l0aEFsbG9jYXRpb24oKFVDb2xsYXRvciAqKXRoaXMsIHNvdXJjZSwgc291cmNlTGVuLCAmcmVzTGVuKTsKCiAgICBzb3J0a2V5LmFkb3B0KHJlc3VsdCwgcmVzTGVuKTsKCglyZXR1cm4gc29ydGtleTsKfQoKQ29sbGF0aW9uS2V5JgpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29sbGF0aW9uS2V5RXgoIGNvbnN0ICAgVUNoYXIqICBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc291cmNlTGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25LZXkmICAgc29ydGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpIGNvbnN0CnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1I7CiAgICAgICAgcmV0dXJuIHNvcnRrZXkuc2V0VG9Cb2d1cygpOwogICAgfQogICAgCiAgICBpZiAoKCFzb3VyY2UpIHx8IChzb3VyY2VMZW4gPT0gMCkpCiAgICB7CiAgICAgICAgcmV0dXJuIHNvcnRrZXkucmVzZXQoKTsKICAgIH0KCiAgICBpZiAoY3Vyc29yMSA9PSBOVUxMKQogICAgewogICAgICAoKFJ1bGVCYXNlZENvbGxhdG9yICopdGhpcyktPmN1cnNvcjEgPSBuZXcgTm9ybWFsaXplckl0ZXJhdG9yKHNvdXJjZSwgc291cmNlTGVuLCBnZXREZWNvbXBvc2l0aW9uKCkpOwogICAgfQogICAgZWxzZQogICAgewogICAgICBjdXJzb3IxLT5zZXRNb2RlQW5kVGV4dChnZXREZWNvbXBvc2l0aW9uKCksIHNvdXJjZSxzb3VyY2VMZW4sIHN0YXR1cyk7CiAgICB9CgogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBzb3J0a2V5LnNldFRvQm9ndXMoKTsKICAgIH0KCiAgICBVQm9vbCAgY29tcGFyZVNlYyAgID0gKGdldFN0cmVuZ3RoKCkgPj0gQ29sbGF0b3I6OlNFQ09OREFSWSk7CiAgICBVQm9vbCAgY29tcGFyZVRlciAgID0gKGdldFN0cmVuZ3RoKCkgPj0gQ29sbGF0b3I6OlRFUlRJQVJZKTsKICAgIFVCb29sICBjb21wYXJlSWRlbnQgPSAoZ2V0U3RyZW5ndGgoKSA9PSBDb2xsYXRvcjo6SURFTlRJQ0FMKTsKICAgIGludDMyX3Qgb3JkZXIgICAgICAgID0gMDsKICAgIGludDMyX3QgdG90YWxQcmltYXJ5ID0gMDsKICAgIGludDMyX3QgdG90YWxTZWMgICAgID0gMDsKICAgIGludDMyX3QgdG90YWxUZXIgICAgID0gMDsKICAgIGludDMyX3QgdG90YWxJZGVudCAgICAgPSAwOwogICAgVW5pY29kZVN0cmluZyBkZWNvbXA7CgogICAgLy8gaXRlcmF0ZSBvdmVyIHRoZSBzb3VyY2UsIGNvdW50aW5nIHByaW1hcnksIHNlY29uZGFyeSwgYW5kIHRlcnRpYXJ5IGVudHJpZXMKICAgIHdoaWxlKChvcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoKE5vcm1hbGl6ZXJJdGVyYXRvciopY3Vyc29yMSwgc3RhdHVzKSkgIT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUikKICAgIHsKICAgICAgICBpbnQzMl90IHNlY09yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcihvcmRlcik7CiAgICAgICAgaW50MzJfdCB0ZXJPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6dGVydGlhcnlPcmRlcihvcmRlcik7CgogICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBzb3J0a2V5LnNldFRvQm9ndXMoKTsKICAgICAgICB9CgogICAgICAgIGlmICghIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6aXNJZ25vcmFibGUob3JkZXIpKQogICAgICAgIHsKICAgICAgICAgICAgdG90YWxQcmltYXJ5ICs9IDE7CgogICAgICAgICAgICBpZiAoY29tcGFyZVNlYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG90YWxTZWMgKz0gMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNvbXBhcmVUZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRvdGFsVGVyICs9IDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGNvbXBhcmVTZWMgJiYgc2VjT3JkZXIgIT0gU0VDSUdOT1JBQkxFKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0b3RhbFNlYyArPSAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29tcGFyZVRlciAmJiB0ZXJPcmRlciAhPSBURVJJR05PUkFCTEUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRvdGFsVGVyICs9IDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gY291bnQgdGhlIG51bGwgYnl0ZXMgYWZ0ZXIgdGhlIGVudGlyZXMKICAgIHRvdGFsUHJpbWFyeSArPSAxOwoKICAgIGlmIChjb21wYXJlU2VjKQogICAgewogICAgICAgIHRvdGFsU2VjICs9IDE7CiAgICB9CgogICAgaWYgKGNvbXBhcmVUZXIpCiAgICB7CiAgICAgICAgdG90YWxUZXIgKz0gMTsKICAgIH0KCiAgICBpZiAoY29tcGFyZUlkZW50KQogICAgewogICAgICBOb3JtYWxpemVyOjpub3JtYWxpemUoc291cmNlLCBnZXREZWNvbXBvc2l0aW9uKCksIC8vIFNSTDogPz8KICAgICAgICAgICAgICAgIDAsIGRlY29tcCwgc3RhdHVzKTsKCiAgICAgICAgaWYgKFVfU1VDQ0VTUyhzdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgdG90YWxJZGVudCA9IGRlY29tcC5sZW5ndGgoKSArIDE7CiAgICAgICAgfQogICAgfQoKICAgIC8vIENvbXB1dGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHRvIGhvbGQgdGhlIGVudHJpZXMKICAgIC8vIGFuZCBtYWtlIHN1cmUgdGhlIGtleSBjYW4gaG9sZCB0aGVtCiAgICB1aW50MzJfdCBzaXplICAgPSAyICogKHRvdGFsUHJpbWFyeSArIHRvdGFsU2VjICsgdG90YWxUZXIgKyB0b3RhbElkZW50KTsKCiAgICBzb3J0a2V5LmVuc3VyZUNhcGFjaXR5KHNpemUpOwoKICAgIGlmIChzb3J0a2V5LmlzQm9ndXMoKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybiBzb3J0a2V5OwogICAgfQoKICAgIGludDMyX3QgcHJpbWFyeUN1cnNvciA9IDA7CiAgICBpbnQzMl90IHNlY0N1cnNvciAgICAgPSAyICogdG90YWxQcmltYXJ5OwogICAgaW50MzJfdCBzZWNCYXNlICAgICAgID0gc2VjQ3Vyc29yOwogICAgaW50MzJfdCBwcmVTZWNJZ25vcmUgID0gc2VjQmFzZTsKICAgIGludDMyX3QgdGVyQ3Vyc29yICAgICA9IHNlY0N1cnNvciArICgyICogdG90YWxTZWMpOwogICAgaW50MzJfdCBpZGVudEN1cnNvciAgICAgID0gdGVyQ3Vyc29yICsgKDIgKiB0b3RhbFRlcik7CgogICAgLy8gcmVzZXQgc291cmNlIHRvIHRoZSBiZWdpbm5pbmcKICAgIGN1cnNvcjEtPnJlc2V0KCk7CgogICAgLy8gbm93IGl0ZXJhdGUgb3ZlciB0aGUgc291cmNlIGNvbXB1dGluZyB0aGUgYWN0dWFsIGVudHJpZXMKICAgIHdoaWxlKChvcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoKE5vcm1hbGl6ZXJJdGVyYXRvciopY3Vyc29yMSwgc3RhdHVzKSkgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpCiAgICB7CiAgICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHNvcnRrZXkucmVzZXQoKTsKICAgICAgICB9CgogICAgICAgIGludDMyX3QgcHJpbWFyeU9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIob3JkZXIpOwogICAgICAgIGludDMyX3Qgc2VjT3JkZXIgICAgID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcihvcmRlcik7CiAgICAgICAgaW50MzJfdCB0ZXJPcmRlciAgICAgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnRlcnRpYXJ5T3JkZXIob3JkZXIpOwoKICAgICAgICBpZiAoISBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OmlzSWdub3JhYmxlKG9yZGVyKSkKICAgICAgICB7CiAgICAgICAgICAgIHByaW1hcnlDdXJzb3IgPSBzb3J0a2V5LnN0b3JlQnl0ZXMocHJpbWFyeUN1cnNvciwgcHJpbWFyeU9yZGVyICsgU09SVEtFWU9GRlNFVCk7CgogICAgICAgICAgICBpZiAoY29tcGFyZVNlYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGRhdGEtPmlzRnJlbmNoU2VjICYmIChwcmVTZWNJZ25vcmUgPCBzZWNDdXJzb3IpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNvcnRrZXkucmV2ZXJzZUJ5dGVzKHByZVNlY0lnbm9yZSwgc2VjQ3Vyc29yKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBzZWNDdXJzb3IgPSBzb3J0a2V5LnN0b3JlQnl0ZXMoc2VjQ3Vyc29yLCBzZWNPcmRlciArIFNPUlRLRVlPRkZTRVQpOwoKICAgICAgICAgICAgICAgIHByZVNlY0lnbm9yZSA9IHNlY0N1cnNvcjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNvbXBhcmVUZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRlckN1cnNvciA9IHNvcnRrZXkuc3RvcmVCeXRlcyh0ZXJDdXJzb3IsIHRlck9yZGVyICsgU09SVEtFWU9GRlNFVCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGNvbXBhcmVTZWMgJiYgc2VjT3JkZXIgIT0gU0VDSUdOT1JBQkxFKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzZWNDdXJzb3IgPSBzb3J0a2V5LnN0b3JlQnl0ZXMoc2VjQ3Vyc29yLCBzZWNPcmRlciArIGRhdGEtPm1heFNlY09yZGVyICsgU09SVEtFWU9GRlNFVCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb21wYXJlVGVyICYmIHRlck9yZGVyICE9IFRFUklHTk9SQUJMRSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGVyQ3Vyc29yID0gc29ydGtleS5zdG9yZUJ5dGVzKHRlckN1cnNvciwgdGVyT3JkZXIgKyBkYXRhLT5tYXhUZXJPcmRlciArIFNPUlRLRVlPRkZTRVQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIGFwcGVuZCAwIGF0IHRoZSBlbmQgb2YgZWFjaCBwb3J0aW9uLgogICAgc29ydGtleS5zdG9yZUJ5dGVzKHByaW1hcnlDdXJzb3IsIDApOwoKICAgIGlmIChjb21wYXJlU2VjKQogICAgewogICAgICAgIGlmIChkYXRhLT5pc0ZyZW5jaFNlYykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwcmVTZWNJZ25vcmUgPCBzZWNDdXJzb3IpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNvcnRrZXkucmV2ZXJzZUJ5dGVzKHByZVNlY0lnbm9yZSwgc2VjQ3Vyc29yKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc29ydGtleS5yZXZlcnNlQnl0ZXMoc2VjQmFzZSwgc2VjQ3Vyc29yKTsKICAgICAgICB9CgogICAgICAgIHNvcnRrZXkuc3RvcmVCeXRlcyhzZWNDdXJzb3IsIDApOwogICAgfQoKICAgIGlmIChjb21wYXJlVGVyKQogICAgewogICAgICAgIHNvcnRrZXkuc3RvcmVCeXRlcyh0ZXJDdXJzb3IsIDApOwogICAgfQoKICAgIGlmIChjb21wYXJlSWRlbnQpCiAgICB7CiAgICAgICAgc29ydGtleS5zdG9yZVVuaWNvZGVTdHJpbmcoaWRlbnRDdXJzb3IsIGRlY29tcCk7CiAgICB9CgogICAgLy8gICAgRGVidWdnaW5nIC0gcHJpbnQgb3V0IHRoZSBzb3J0a2V5IFstLXNybF0KLy8gICAgICB7Ci8vICAgICAgICBjb25zdCB1aW50OF90ICpieXRlczsKLy8gICAgICAgIGludDMyX3QgeGNvdW50OwovLyAgICAgICAgYnl0ZXMgPSBzb3J0a2V5LmdldEJ5dGVBcnJheSh4Y291bnQpOwovLyAgICAgICAgLy8gICAgICBmcHJpbnRmKHN0ZGVyciwgIlxuXG4tICBbJTAyWF0gWyUwMlhdXG5cbiIsIChpbnQpKGJ5dGVzWzBdJjB4RkYpLCAoaW50KShieXRlc1sxXSYweEZGKSApOwovLyAgICAgIH0KCiAgICByZXR1cm4gc29ydGtleTsKfQoKCi8vIEJ1aWxkIHRoaXMgY29sbGF0b3IncyBydWxlIHRhYmxlcyBiYXNlZCBvbiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcnVsZXMKLy8gU2VlIHRoZSBiaWcgZGlhZ3JhbSBhdCB0aGUgdG9wIG9mIHRoaXMgZmlsZSBmb3IgYW4gb3ZlcnZpZXcgb2YgaG93IHRoZSB0YWJsZXMKLy8gYXJlIG9yZ2FuaXplZC4Kdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6YnVpbGQoY29uc3QgVW5pY29kZVN0cmluZyYgICBwYXR0ZXJuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gVGhpcyBhcnJheSBtYXBzIFVuaWNvZGUgY2hhcmFjdGVycyB0byB0aGVpciBjb2xsYXRpb24gb3JkZXJpbmcKICAgIGRhdGEtPm1hcHBpbmcgPSB1Y21wMzJfb3BlbihVTk1BUFBFRCk7CgogICAgaWYgKGRhdGEtPm1hcHBpbmctPmZCb2d1cykKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpbnQzMl90IGkgPSAwOwogICAgVW5pY29kZVN0cmluZyBsYXN0R3JvdXBDaGFyczsKICAgIFVuaWNvZGVTdHJpbmcgZXhwQ2hhcnM7CiAgICBVbmljb2RlU3RyaW5nIGdyb3VwQ2hhcnM7CgogICAgaWYgKHBhdHRlcm4ubGVuZ3RoKCkgPT0gMCkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX0lOVkFMSURfRk9STUFUX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBCdWlsZCB0aGUgbWVyZ2VkIGNvbGxhdGlvbiBlbnRyaWVzCiAgICAvLyBTaW5jZSBydWxlcyBjYW4gYmUgc3BlY2lmaWVkIGluIGFueSBvcmRlciBpbiB0aGUgc3RyaW5nCiAgICAvLyAoZS5nLiAiYyAsIEMgPCBkICwgRCA8IGUgLCBFIC4uLi4gQyA8IENIIikKICAgIC8vIHRoaXMgc3BsaXRzIGFsbCBvZiB0aGUgcnVsZXMgaW4gdGhlIHN0cmluZyBvdXQgaW50byBzZXBhcmF0ZQogICAgLy8gb2JqZWN0cyBhbmQgdGhlbiBzb3J0cyB0aGVtLiAgSW4gdGhlIGFib3ZlIGV4YW1wbGUsIGl0IG1lcmdlcyB0aGUKICAgIC8vICJDIDwgQ0giIHJ1bGUgaW4ganVzdCBiZWZvcmUgdGhlICJDIDwgRCIgcnVsZS4KCiAgICBtUGF0dGVybiA9IG5ldyBNZXJnZUNvbGxhdGlvbihwYXR0ZXJuLCBnZXREZWNvbXBvc2l0aW9uKCksIHN0YXR1cyk7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgdWNtcDMyX2Nsb3NlKGRhdGEtPm1hcHBpbmcpOwogICAgICAgIGRhdGEtPm1hcHBpbmcgPSAwOwogICAgICAgIGRlbGV0ZSBtUGF0dGVybjsKICAgICAgICBtUGF0dGVybiA9IDA7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGludDMyX3Qgb3JkZXIgPSBDT0xFTEVNRU5UU1RBUlQ7CgogICAgLy8gV2FsayB0aHJvdWdoIGVhY2ggZW50cnkKICAgIGZvciAoaSA9IDA7IGkgPCBtUGF0dGVybi0+Z2V0Q291bnQoKTsgKytpKQogICAgewogICAgICAgIGNvbnN0IFBhdHRlcm5FbnRyeSogZW50cnkgPSBtUGF0dGVybi0+Z2V0SXRlbUF0KGkpOwogICAgICAgIGdyb3VwQ2hhcnMucmVtb3ZlKCk7CiAgICAgICAgZXhwQ2hhcnMucmVtb3ZlKCk7CgogICAgICAgIC8vIGlmIGVudHJ5IGlzIHZhbGlkCiAgICAgICAgaWYgKGVudHJ5ICE9IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICBlbnRyeS0+Z2V0Q2hhcnMoZ3JvdXBDaGFycyk7CgogICAgICAgICAgICAvLyBjaGVjayBpZiBmcmVuY2ggc2Vjb25kYXJ5IG5lZWRzIHRvIGJlIHR1cm5lZCBvbgogICAgICAgICAgICBpZiAoKGdyb3VwQ2hhcnMubGVuZ3RoKCkgPiAxKSAmJgogICAgICAgICAgICAgICAgKGdyb3VwQ2hhcnNbZ3JvdXBDaGFycy5sZW5ndGgoKS0xXSA9PSAweDAwNDApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkYXRhLT5pc0ZyZW5jaFNlYyA9IFRSVUU7CiAgICAgICAgICAgICAgICBncm91cENoYXJzLnJlbW92ZShncm91cENoYXJzLmxlbmd0aCgpLTEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBvcmRlciA9IGluY3JlbWVudCgoQ29sbGF0b3I6OkVDb2xsYXRpb25TdHJlbmd0aCllbnRyeS0+Z2V0U3RyZW5ndGgoKSwgb3JkZXIpOwoKICAgICAgICAgICAgaWYgKGVudHJ5LT5nZXRFeHRlbnNpb24oZXhwQ2hhcnMpLmxlbmd0aCgpICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGVuY291bnRlcmVkIGFuIGV4cGFuZGluZyBjaGFyYWN0ZXIsIHdoZXJlIG9uZSBjaGFyYWN0ZXIgb24gaW5wdXQKICAgICAgICAgICAgICAgIC8vIGV4cGFuZHMgdG8gc2V2ZXJhbCBzb3J0IGVsZW1lbnRzIChlLmcuICf2JyAtLT4gJ28nICdlJykKICAgICAgICAgICAgICAgIGFkZEV4cGFuZE9yZGVyKGdyb3VwQ2hhcnMsIGV4cENoYXJzLCBvcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoZ3JvdXBDaGFycy5sZW5ndGgoKSA+IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGVuY291bnRlcmVkIGEgY29udHJhY3RpbmcgY2hhcmFjdGVyLCB3aGVyZSBzZXZlcmFsIGNoYXJhY3RlcnMgb24gaW5wdXQKICAgICAgICAgICAgICAgIC8vIGNvbnRyYWN0IGludG8gb25lIHNvcnQgb3JkZXIuICBGb3IgZXhhbXBsZSwgImNoIiBpcyB0cmVhdGVkIGFzIGEgc2luZ2xlCiAgICAgICAgICAgICAgICAvLyBjaGFyYWN0ZXIgaW4gdHJhZGl0aW9uYWwgU3BhbmlzaCBzb3J0aW5nLgogICAgICAgICAgICAgICAgYWRkQ29udHJhY3RPcmRlcihncm91cENoYXJzLCBvcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBOb3RoaW5nIG91dCBvZiB0aGUgb3JkaW5hcnkgLS0gb25lIGNoYXJhY3RlciBtYXBzIHRvIG9uZSBzb3J0IG9yZGVyCiAgICAgICAgICAgICAgICBhZGRPcmRlcihncm91cENoYXJzWzBdLCBvcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gYWRkIGV4cGFuZGluZyBlbnRyaWVzIGZvciBwcmUtY29tcG9zZWQgY2hhcmFjdGVycwogICAgYWRkQ29tcG9zZWRDaGFycygpOwoKICAgIC8vIEZpbGwgaW4gYWxsIHRoZSBleHBhbmRpbmcgY2hhcnMgdmFsdWVzCiAgICBjb21taXQoKTsKCiAgICAvLyBDb21wYWN0IHRoZSBkYXRhIG1hcHBpbmcgdGFibGUKICAgIHVjbXAzMl9jb21wYWN0KGRhdGEtPm1hcHBpbmcsIDEpOwp9CgovKioKICogQWRkIGV4cGFuZGluZyBlbnRyaWVzIGZvciBwcmUtY29tcG9zZWQgdW5pY29kZSBjaGFyYWN0ZXJzIHNvIHRoYXQgdGhpcwogKiBjb2xsYXRvciBjYW4gYmUgdXNlZCByZWFzb25hYmx5IHdlbGwgd2l0aCBkZWNvbXBvc2l0aW9uIHR1cm5lZCBvZmYuCiAqLwogdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6YWRkQ29tcG9zZWRDaGFycygpCiB7CiAgICBVbmljb2RlU3RyaW5nIGJ1ZjsKICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwoKICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBhbGwgb2YgdGhlIHByZS1jb21wb3NlZCBjaGFyYWN0ZXJzIGluIFVuaWNvZGUKICAgIENvbXBvc2VkQ2hhckl0ZXIgaXRlcjsKICAgIFVuaWNvZGVTdHJpbmcgZGVjb21wOwoKICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkKICAgIHsKICAgICAgICBVQ2hhciBjID0gaXRlci5uZXh0KCk7CiAgICAgICAgCiAgICAgICAgaWYgKGdldENoYXJPcmRlcihjKSA9PSBVTk1BUFBFRCkKICAgICAgICB7CiAgICAgICAgICAgIC8vIAogICAgICAgICAgICAvLyBXZSBkb24ndCBhbHJlYWR5IGhhdmUgYW4gb3JkZXJpbmcgZm9yIHRoaXMgcHJlLWNvbXBvc2VkIGNoYXJhY3Rlci4KICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gRmlyc3QsIHNlZSBpZiB0aGUgZGVjb21wb3NlZCBzdHJpbmcgaXMgYWxyZWFkeSBpbiBvdXIKICAgICAgICAgICAgLy8gdGFibGVzIGFzIGEgc2luZ2xlIGNvbnRyYWN0aW5nLXN0cmluZyBvcmRlcmluZy4KICAgICAgICAgICAgLy8gSWYgc28sIGp1c3QgbWFwIHRoZSBwcmVjb21wb3NlZCBjaGFyYWN0ZXIgdG8gdGhhdCBvcmRlci4KICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gVE9ETzogV2hhdCB3ZSBzaG91bGQgcmVhbGx5IGJlIGRvaW5nIGhlcmUgaXMgdHJ5aW5nIHRvIGZpbmQgdGhlCiAgICAgICAgICAgIC8vIGxvbmdlc3QgaW5pdGlhbCBzdWJzdHJpbmcgb2YgdGhlIGRlY29tcG9zaXRpb24gdGhhdCBpcyBwcmVzZW50CiAgICAgICAgICAgIC8vIGluIHRoZSB0YWJsZXMgYXMgYSBjb250cmFjdGluZyBjaGFyYWN0ZXIgc2VxdWVuY2UsIGFuZCBmaW5kIGl0cwogICAgICAgICAgICAvLyBvcmRlcmluZy4gIFRoZW4gZG8gdGhpcyByZWN1cnNpdmVseSB3aXRoIHRoZSByZW1haW5pbmcgY2hhcnMKICAgICAgICAgICAgLy8gc28gdGhhdCB3ZSBidWlsZCBhIGxpc3Qgb2Ygb3JkZXJpbmdzLCBhbmQgYWRkIHRoYXQgbGlzdCB0bwogICAgICAgICAgICAvLyB0aGUgZXhwYW5zaW9uIHRhYmxlLiAKICAgICAgICAgICAgLy8gVGhhdCB3b3VsZCBiZSBtb3JlIGNvcnJlY3QgYnV0IGFsc28gc2lnbmlmaWNhbnRseSBzbG93ZXIsIHNvCiAgICAgICAgICAgIC8vIEknbSBub3QgdG90YWxseSBzdXJlIGl0J3Mgd29ydGggZG9pbmcuCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIGl0ZXIuZ2V0RGVjb21wb3NpdGlvbihkZWNvbXApOwogICAgICAgICAgICBpbnQgY29udHJhY3RPcmRlciA9IGdldENvbnRyYWN0T3JkZXIoZGVjb21wKTsKCiAgICAgICAgICAgIGlmIChjb250cmFjdE9yZGVyICE9IFVOTUFQUEVEKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhZGRPcmRlcihjLCBjb250cmFjdE9yZGVyLCBzdGF0dXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIC8vIFdlIGRvbid0IGhhdmUgYSBjb250cmFjdGluZyBvcmRlcmluZyBmb3IgdGhlIGVudGlyZSBzdHJpbmcKICAgICAgICAgICAgICAgIC8vIHRoYXQgcmVzdWx0cyBmcm9tIHRoZSBkZWNvbXBvc2l0aW9uLCBidXQgaWYgd2UgaGF2ZSBvcmRlcnMKICAgICAgICAgICAgICAgIC8vIGZvciBlYWNoIGluZGl2aWR1YWwgY2hhcmFjdGVyLCB3ZSBjYW4gYWRkIGFuIGV4cGFuZGluZwogICAgICAgICAgICAgICAgLy8gdGFibGUgZW50cnkgZm9yIHRoZSBwcmUtY29tcG9zZWQgY2hhcmFjdGVyIAogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIFVCb29sIGFsbFRoZXJlID0gVFJVRTsKICAgICAgICAgICAgICAgIGludDMyX3QgaTsKCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZGVjb21wLmxlbmd0aCgpOyBpICs9IDEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGdldENoYXJPcmRlcihkZWNvbXBbaV0pID09IFVOTUFQUEVEKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWxsVGhlcmUgPSBGQUxTRTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChhbGxUaGVyZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBidWYucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICAgICAgYnVmICs9IGM7CiAgICAgICAgICAgICAgICAgICAgYWRkRXhwYW5kT3JkZXIoYnVmLCBkZWNvbXAsIFVOTUFQUEVELCBzdGF0dXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CiAgICAKLy8gV2hlbiB0aGUgZXhwYW5kaW5nIGNoYXJhY3RlciB0YWJsZXMgYXJlIGJ1aWx0IGJ5IGFkZEV4cGFuZE9yZGVyLAovLyBpdCBkb2Vzbid0IGtub3cgd2hhdCB0aGUgZmluYWwgb3JkZXJpbmcgb2YgZWFjaCBjaGFyYWN0ZXIKLy8gaW4gdGhlIGV4cGFuc2lvbiB3aWxsIGJlLiAgSW5zdGVhZCwgaXQganVzdCBwdXRzIHRoZSByYXcgY2hhcmFjdGVyCi8vIGNvZGUgaW50byB0aGUgdGFibGUsIGFkZGluZyBDSEFSSU5ERVggYXMgYSBmbGFnLiAgTm93IHRoYXQgd2UndmUKLy8gZmluaXNoZWQgYnVpbGRpbmcgdGhlIG1hcHBpbmcgdGFibGUsIHdlIGNhbiBnbyBiYWNrIGFuZCBsb29rIHVwCi8vIHRoYXQgY2hhcmFjdGVyIHRvIHNlZSB3aGF0IGl0cyByZWFsIGNvbGxhdGlvbiBvcmRlciBpcyBhbmQKLy8gc3RpY2sgdGhhdCBpbnRvIHRoZSBleHBhbnNpb24gdGFibGUuICBUaGF0IGxldHMgdXMgYXZvaWQgZG9pbmcKLy8gYSB0d28tc3RhZ2UgbG9va3VwIGxhdGVyLgoKdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6Y29tbWl0KCkKewogICAgLy8gaWYgdGhlcmUgYXJlIGFueSBleHBhbmRpbmcgY2hhcmFjdGVycwogICAgaWYgKGRhdGEtPmV4cGFuZFRhYmxlICE9IE5VTEwpCiAgICB7CiAgICAgICAgaW50MzJfdCBpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBkYXRhLT5leHBhbmRUYWJsZS0+c2l6ZSgpOyBpICs9IDEpCiAgICAgICAgewogICAgICAgICAgICBWZWN0b3JPZkludCogdmFsdWVMaXN0ID0gZGF0YS0+ZXhwYW5kVGFibGUtPmF0KGkpOwogICAgICAgICAgICBpbnQzMl90IGo7CiAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCB2YWx1ZUxpc3QtPnNpemUoKTsgaisrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBmb3VuZCBhIGV4cGFuZGluZyBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgIC8vIHRoZSBleHBhbmRpbmcgY2hhciB2YWx1ZSBpcyBub3QgZmlsbGVkIGluIHlldAogICAgICAgICAgICAgICAgaWYgKCh2YWx1ZUxpc3QtPmF0KGopIDwgRVhQQU5EQ0hBUklOREVYKSAmJgogICAgICAgICAgICAgICAgICAgICh2YWx1ZUxpc3QtPmF0KGopID4gQ0hBUklOREVYKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIHJlYWwgdmFsdWVzIGZvciB0aGUgbm9uLWZpbGxlZCBlbnRyeQogICAgICAgICAgICAgICAgICAgIFVDaGFyIGNoID0gKFVDaGFyKSh2YWx1ZUxpc3QtPmF0KGopIC0gQ0hBUklOREVYKTsKICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHJlYWxWYWx1ZSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY2gpOwoKICAgICAgICAgICAgICAgICAgICBpZiAocmVhbFZhbHVlID09IFVOTUFQUEVEKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHJlYWwgdmFsdWUgaXMgc3RpbGwgdW5tYXBwZWQsIG1heWJlIGl0J3NpZ25vcmFibGUKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVMaXN0LT5hdFB1dChqLCBJR05PUkFCTEVNQVNLICYgY2gpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBmaWxsIGluIHRoZSB2YWx1ZQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlTGlzdC0+YXRQdXQoaiwgcmVhbFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiB9CgovKioKICogIEluY3JlbWVudCBvZiB0aGUgbGFzdCBvcmRlciBiYXNlZCBvbiB0aGUgY29tcGFyaXNvbiBsZXZlbC4KICovCmludDMyX3QKUnVsZUJhc2VkQ29sbGF0b3I6OmluY3JlbWVudChDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoIGFTdHJlbmd0aCwgaW50MzJfdCBsYXN0VmFsdWUpCnsKICAgIHN3aXRjaChhU3RyZW5ndGgpCiAgICB7CiAgICBjYXNlIENvbGxhdG9yOjpQUklNQVJZOgogICAgICAgIC8vIGluY3JlbWVudCBwcmlhbXJ5IG9yZGVyICBhbmQgbWFzayBvZmYgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgICAgICAgbGFzdFZhbHVlICs9IFBSSU1BUllPUkRFUklOQ1JFTUVOVDsKICAgICAgICBpZigobGFzdFZhbHVlICYgUFJJTUFSWUxPV1pFUk9NQVNLKSA9PSAwKSB7CiAgICAgICAgICAgIGxhc3RWYWx1ZSArPSBQUklNQVJZT1JERVJJTkNSRU1FTlQ7CiAgICAgICAgICAgIGxhc3RWYWx1ZSArPSBQUklNQVJZT1JERVJJTkNSRU1FTlQ7CiAgICAgICAgfQogICAgICAgIGxhc3RWYWx1ZSAmPSBQUklNQVJZT1JERVJNQVNLOwoKICAgICAgICBsYXN0VmFsdWUgfD0gUkVTRVRTRUNPTkRBUllURVJUSUFSWTsgLy8gU3RhcnQgYWxsIHZhbHVlcyBmcm9tIDAyCiAgICAgICAgaXNPdmVySWdub3JlID0gVFJVRTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIENvbGxhdG9yOjpTRUNPTkRBUlk6CiAgICAgICAgLy8gaW5jcmVtZW50IHNlY29uZGFyeSBvcmRlciBhbmQgbWFzayBvZmYgdGVydGlhcnkgZGlmZmVyZW5jZQogICAgICAgIGxhc3RWYWx1ZSArPSBTRUNPTkRBUllPUkRFUklOQ1JFTUVOVDsKICAgICAgICBsYXN0VmFsdWUgJj0gU0VDT05EQVJZRElGRkVSRU5DRU9OTFk7CiAgICAgICAgbGFzdFZhbHVlIHw9IFJFU0VUVEVSVElBUlk7IC8vIFN0YXJ0IGFsbCB2YWx1ZXMgZnJvbSAwMgoKICAgICAgICAvLyByZWNvcmQgbWF4ICMgb2YgaWdub3JhYmxlIGNoYXJzIHdpdGggc2Vjb25kYXJ5IGRpZmZlcmVuY2UKICAgICAgICBpZiAoaXNPdmVySWdub3JlID09IEZBTFNFKQogICAgICAgIHsKICAgICAgICAgICAgZGF0YS0+bWF4U2VjT3JkZXIgKz0gMTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBDb2xsYXRvcjo6VEVSVElBUlk6CiAgICAgICAgLy8gaW5jcmVtZW50IHRlcnRpYXJ5IG9yZGVyCiAgICAgICAgbGFzdFZhbHVlICs9IFRFUlRJQVJZT1JERVJJTkNSRU1FTlQ7CgogICAgICAgIC8vIHJlY29yZCBtYXggIyBvZiBpZ25vcmFibGUgY2hhcnMgd2l0aCB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgICAgICAgaWYgKGlzT3Zlcklnbm9yZSA9PSBGQUxTRSkKICAgICAgICB7CiAgICAgICAgICAgIGRhdGEtPm1heFRlck9yZGVyICs9IDE7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAvLyBjYXNlIElERU5USUNBTD8gIAogICAgfQoKICAgIHJldHVybiBsYXN0VmFsdWU7Cn0KCi8vIEFkZHMgYSBjaGFyYWN0ZXIgYW5kIGl0cyBkZXNpZ25hdGVkIG9yZGVyIGludG8gdGhlIGNvbGxhdGlvbiB0YWJsZS4KLy8gVGhpcyBpcyB0aGUgc2ltcGxlIGNhc2UsIHdpdGggbm8gZXhwYW5zaW9uIG9yIGNvbnRyYWN0aW9uCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmFkZE9yZGVyKFVDaGFyIGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBhbk9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIHRyeSB0byBmaW5kIHRoZSBvcmRlciBvZiB0aGUgY2hhciBpbiB0aGUgbWFwcGluZyB0YWJsZQogICAgaW50MzJfdCBvcmRlciA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY2gpOwoKICAgIGlmIChvcmRlciA+PSBDT05UUkFDVENIQVJJTkRFWCkKICAgIHsKICAgICAgICAvLyBUaGVyZSdzIGFscmVhZHkgYW4gZW50cnkgZm9yIHRoaXMgY2hhcmFjdGVyIHRoYXQgcG9pbnRzIHRvIGEgY29udHJhY3RpbmcKICAgICAgICAvLyBjaGFyYWN0ZXIgdGFibGUuICBJbnN0ZWFkIG9mIGFkZGluZyB0aGUgY2hhcmFjdGVyIGRpcmVjdGx5IHRvIHRoZSBtYXBwaW5nCiAgICAgICAgLy8gdGFibGUsIHdlIG11c3QgYWRkIGl0IHRvIHRoZSBjb250cmFjdCB0YWJsZSBpbnN0ZWFkLgogICAgICAgIGtleS5yZW1vdmUoKTsKICAgICAgICBrZXkgKz0gY2g7CiAgICAgICAgaWYgKGtleS5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBhZGRDb250cmFjdE9yZGVyKGtleSwgYW5PcmRlciwgc3RhdHVzKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvLyBhZGQgdGhlIGVudHJ5IHRvIHRoZSBtYXBwaW5nIHRhYmxlLCB0aGUgc2FtZSBsYXRlciBlbnRyeSByZXBsYWNlcyB0aGUgcHJldmlvdXMgb25lCiAgICAgICAgdWNtcDMyX3NldChkYXRhLT5tYXBwaW5nLCBjaCwgYW5PcmRlcik7CiAgICB9Cn0KCi8vIEFkZCBhbiBleHBhbmRpbmctY2hhcmFjdGVyIGVudHJ5IHRvIHRoZSB0YWJsZS4Kdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6YWRkRXhwYW5kT3JkZXIoICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmIGNvbnRyYWN0Q2hhcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgICBVbmljb2RlU3RyaW5nJiBleHBhbmRDaGFycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGFuT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIENyZWF0ZSBhbiBleHBhbnNpb24gdGFibGUgZW50cnkKICAgIGludDMyX3QgdGFibGVJbmRleCA9IGFkZEV4cGFuc2lvbihhbk9yZGVyLCBleHBhbmRDaGFycyk7CiAgICAKICAgIC8vIEFuZCBhZGQgaXRzIGluZGV4IGludG8gdGhlIG1haW4gbWFwcGluZyB0YWJsZQogICAgaWYgKGNvbnRyYWN0Q2hhcnMubGVuZ3RoKCkgPiAxKQogICAgewogICAgICAgIGFkZENvbnRyYWN0T3JkZXIoY29udHJhY3RDaGFycywgdGFibGVJbmRleCwgc3RhdHVzKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBhZGRPcmRlcihjb250cmFjdENoYXJzWzBdLCB0YWJsZUluZGV4LCBzdGF0dXMpOwogICAgfQp9CgppbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjphZGRFeHBhbnNpb24oaW50MzJfdCBhbk9yZGVyLCBjb25zdCBVbmljb2RlU3RyaW5nICZleHBhbmRDaGFycykKewogICAgaWYgKGRhdGEtPmV4cGFuZFRhYmxlID09IE5VTEwpCiAgICB7CiAgICAgICAgZGF0YS0+ZXhwYW5kVGFibGUgPSBuZXcgVmVjdG9yT2ZQVG9FeHBhbmRUYWJsZSgpOwoKICAgICAgICBpZiAoZGF0YS0+ZXhwYW5kVGFibGUgPT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gSWYgYW5PcmRlciBpcyB2YWxpZCwgd2Ugd2FudCB0byBhZGQgaXQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgbGlzdAogICAgaW50MzJfdCBvZmZzZXQgPSAoYW5PcmRlciA9PSBVTk1BUFBFRCkgPyAwIDogMTsKICAgIAogICAgVmVjdG9yT2ZJbnQgKnZhbHVlTGlzdCA9IG5ldyBWZWN0b3JPZkludChleHBhbmRDaGFycy5sZW5ndGgoKSArIG9mZnNldCk7CgogICAgaWYgKG9mZnNldCA9PSAxKQogICAgewogICAgICAgIHZhbHVlTGlzdC0+YXRQdXQoMCwgYW5PcmRlcik7CiAgICB9CgogICAgaW50MzJfdCBpOwogICAgZm9yIChpID0gMDsgaSA8IGV4cGFuZENoYXJzLmxlbmd0aCgpOyBpICs9IDEpCiAgICB7CiAgICAgICAgVUNoYXIgY2ggPSBleHBhbmRDaGFyc1tpXTsKICAgICAgICBpbnQzMl90IG1hcFZhbHVlID0gZ2V0Q2hhck9yZGVyKGNoKTsKICAgICAgICAKICAgICAgICBpZiAobWFwVmFsdWUgIT0gVU5NQVBQRUQpCiAgICAgICAgewogICAgICAgICAgICB2YWx1ZUxpc3QtPmF0UHV0KGkgKyBvZmZzZXQsIG1hcFZhbHVlKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLy8gY2FuJ3QgZmluZCBpdCBpbiB0aGUgdGFibGUsIHdpbGwgYmUgZmlsbGVkIGluIGJ5IGNvbW1pdCgpLgogICAgICAgICAgICB2YWx1ZUxpc3QtPmF0UHV0KGkgKyBvZmZzZXQsIENIQVJJTkRFWCArIChpbnQzMl90KWNoKTsKICAgICAgICB9CiAgICB9CgogICAgLy8gQWRkIHRoZSBleHBhbmRpbmcgY2hhciBsaXN0IGludG8gdGhlIGV4cGFuc2lvbiB0YWJsZS4KICAgIGludDMyX3QgdGFibGVJbmRleCA9IEVYUEFORENIQVJJTkRFWCArIGRhdGEtPmV4cGFuZFRhYmxlLT5zaXplKCk7CiAgICBkYXRhLT5leHBhbmRUYWJsZS0+YXRQdXQoZGF0YS0+ZXhwYW5kVGFibGUtPnNpemUoKSwgdmFsdWVMaXN0KTsKICAgIAogICAgcmV0dXJuIHRhYmxlSW5kZXg7Cn0KCi8vIEFkZCBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIHRoYXQgY29udHJhY3RzIGludG8gYSBzaW5nbGUgb3JkZXJpbmcuCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmFkZENvbnRyYWN0T3JkZXIoY29uc3QgICBVbmljb2RlU3RyaW5nJiBncm91cENoYXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGFuT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVCb29sIGZ3ZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChkYXRhLT5jb250cmFjdFRhYmxlID09IE5VTEwpCiAgICB7CiAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZSA9IG5ldyBWZWN0b3JPZlBUb0NvbnRyYWN0VGFibGUoKTsKICAgICAgICBpZiAoZGF0YS0+Y29udHJhY3RUYWJsZS0+aXNCb2d1cygpKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIC8vIFNlZSBpZiB0aGUgaW5pdGlhbCBjaGFyYWN0ZXIgb2YgdGhlIHN0cmluZyBhbHJlYWR5IGhhcyBhIGNvbnRyYWN0IHRhYmxlLgogICAgLy8gZS5nLiBmb3IgImNoIiwgbG9vayBmb3IgJ2MnLgogICAgaW50MzJfdCBlbnRyeSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgZ3JvdXBDaGFyc1swXSk7CiAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCAqZW50cnlUYWJsZSA9IGdldENvbnRyYWN0VmFsdWVzKGVudHJ5IC0gQ09OVFJBQ1RDSEFSSU5ERVgpOwoKICAgIGlmIChlbnRyeVRhYmxlID09IE5VTEwpCiAgICB7CiAgICAgICAgLy8gV2UgbmVlZCB0byBjcmVhdGUgYSBuZXcgdGFibGUgb2YgY29udHJhY3QgZW50cmllcyBmb3IgdGhpcyBiYXNlIGNoYXIKICAgICAgICBpbnQzMl90IHRhYmxlSW5kZXggPSBDT05UUkFDVENIQVJJTkRFWCArIGRhdGEtPmNvbnRyYWN0VGFibGUtPnNpemUoKTsKICAgICAgICBFbnRyeVBhaXIgKnBhaXIgPSBOVUxMOwogICAgICAgIFVuaWNvZGVTdHJpbmcgc3Vic3RyaW5nOwoKICAgICAgICBlbnRyeVRhYmxlID0gbmV3IFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KCk7CiAgICAgICAgaWYgKGVudHJ5VGFibGUtPmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBlbnRyeVRhYmxlOwogICAgICAgICAgICBkZWxldGUgZGF0YS0+Y29udHJhY3RUYWJsZTsKICAgICAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZSA9IE5VTEw7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUtPmF0UHV0KGRhdGEtPmNvbnRyYWN0VGFibGUtPnNpemUoKSwgZW50cnlUYWJsZSk7CiAgICAgICAgaWYgKGRhdGEtPmNvbnRyYWN0VGFibGUtPmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBlbnRyeVRhYmxlOwogICAgICAgICAgICBkZWxldGUgZGF0YS0+Y29udHJhY3RUYWJsZTsKICAgICAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZSA9IE5VTEw7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgICAgIAoKICAgICAgICAvLyBBZGQgdGhlIGluaXRpYWwgY2hhcmFjdGVyJ3MgY3VycmVudCBvcmRlcmluZyBmaXJzdC4gdGhlbgogICAgICAgIC8vIHVwZGF0ZSBpdHMgbWFwcGluZyB0byBwb2ludCB0byB0aGlzIGNvbnRyYWN0IHRhYmxlCiAgICAgICAgZ3JvdXBDaGFycy5leHRyYWN0KDAsIDEsIHN1YnN0cmluZyk7CiAgICAgICAgaWYgKHN1YnN0cmluZy5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZW50cnlUYWJsZTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBwYWlyID0gbmV3IEVudHJ5UGFpcihzdWJzdHJpbmcsIGVudHJ5KTsKCiAgICAgICAgZW50cnlUYWJsZS0+YXRQdXQoMCwgcGFpcik7CiAgICAgICAgaWYgKGVudHJ5VGFibGUtPmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBlbnRyeVRhYmxlOwogICAgICAgICAgICBkZWxldGUgZGF0YS0+Y29udHJhY3RUYWJsZTsKICAgICAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZSA9IE5VTEw7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHVjbXAzMl9zZXQoZGF0YS0+bWFwcGluZywgZ3JvdXBDaGFyc1swXSwgdGFibGVJbmRleCk7CiAgICB9CgogICAgLy8gTm93IGFkZCAob3IgcmVwbGFjZSkgdGhpcyBzdHJpbmcgaW4gdGhlIHRhYmxlCiAgICBpbnQzMl90IGluZGV4ID0gZ2V0RW50cnkoZW50cnlUYWJsZSwgZ3JvdXBDaGFycywgZndkKTsKCiAgICBpZiAoaW5kZXggIT0gVU5NQVBQRUQpCiAgICB7CiAgICAgICAgRW50cnlQYWlyICpwYWlyID0gKEVudHJ5UGFpciAqKSBlbnRyeVRhYmxlLT5hdChpbmRleCk7CiAgICAgICAgcGFpci0+dmFsdWUgPSBhbk9yZGVyOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIEVudHJ5UGFpciAqcGFpciA9IG5ldyBFbnRyeVBhaXIoZ3JvdXBDaGFycywgYW5PcmRlciwgZndkKTsKCiAgICAgICAgZW50cnlUYWJsZS0+YXRQdXQoZW50cnlUYWJsZS0+c2l6ZSgpLCBwYWlyKTsKICAgIH0KICAgIAogICAgLy8gSWYgdGhpcyB3YXMgYSBmb3J3YXJkIG1hcHBpbmcgZm9yIGEgY29udHJhY3Rpbmcgc3RyaW5nLCBhbHNvIGFkZCBhCiAgICAvLyByZXZlcnNlIG1hcHBpbmcgZm9yIGl0LCBzbyB0aGF0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJldmlvdXMKICAgIC8vIGNhbiB3b3JrIHJpZ2h0CiAgICBpZiAoZndkKQogICAgewogICAgICAgIFVuaWNvZGVTdHJpbmcgcmV2ZXJzZShncm91cENoYXJzKTsKCiAgICAgICAgaWYgKHJldmVyc2UuaXNCb2d1cygpKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGVudHJ5VGFibGU7CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhLT5jb250cmFjdFRhYmxlOwogICAgICAgICAgICBkYXRhLT5jb250cmFjdFRhYmxlID0gTlVMTDsKICAgICAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgYWRkQ29udHJhY3RPcmRlcihyZXZlcnNlLnJldmVyc2UoKSwgYW5PcmRlciwgRkFMU0UsIHN0YXR1cyk7CiAgICB9Cn0KCi8qKgogKiBJZiB0aGUgZ2l2ZW4gc3RyaW5nIGhhcyBiZWVuIHNwZWNpZmllZCBhcyBhIGNvbnRyYWN0aW5nIHN0cmluZwogKiBpbiB0aGlzIGNvbGxhdGlvbiB0YWJsZSwgcmV0dXJuIGl0cyBvcmRlcmluZy4KICogT3RoZXJ3aXNlIHJldHVybiBVTk1BUFBFRC4KICovCiBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb250cmFjdE9yZGVyKGNvbnN0IFVuaWNvZGVTdHJpbmcgJmdyb3VwQ2hhcnMpIGNvbnN0CnsKICAgIGludDMyX3QgcmVzdWx0ID0gVU5NQVBQRUQ7CgogICAgaWYgKGRhdGEtPmNvbnRyYWN0VGFibGUgIT0gTlVMTCkKICAgIHsKICAgICAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCAqZW50cnlUYWJsZSA9IGdldENvbnRyYWN0VmFsdWVzKGdyb3VwQ2hhcnNbMF0pOwoKICAgICAgICBpZiAoZW50cnlUYWJsZSAhPSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgaW50MzJfdCBpbmRleCA9IGdldEVudHJ5KGVudHJ5VGFibGUsIGdyb3VwQ2hhcnMsIFRSVUUpOwoKICAgICAgICAgICAgaWYgKGluZGV4ICE9IFVOTUFQUEVEKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBFbnRyeVBhaXIgKnBhaXIgPSBlbnRyeVRhYmxlLT5hdChpbmRleCk7CgogICAgICAgICAgICAgICAgcmVzdWx0ID0gcGFpci0+dmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJlc3VsdDsKfQoKaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q2hhck9yZGVyKFVDaGFyIGNoKSBjb25zdAp7CiAgICBpbnQzMl90IG9yZGVyID0gdWNtcDMyX2dldChkYXRhLT5tYXBwaW5nLCBjaCk7CiAgICAKICAgIGlmIChvcmRlciA+PSBDT05UUkFDVENIQVJJTkRFWCkKICAgIHsKICAgICAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCAqZ3JvdXBMaXN0ID0gZ2V0Q29udHJhY3RWYWx1ZXMob3JkZXIgLSBDT05UUkFDVENIQVJJTkRFWCk7CiAgICAgICAgRW50cnlQYWlyICpwYWlyID0gZ3JvdXBMaXN0LT5hdCgwKTsKCiAgICAgICAgb3JkZXIgPSBwYWlyLT52YWx1ZTsKICAgIH0KCiAgICByZXR1cm4gb3JkZXI7Cn0KICAgIAovLyBDcmVhdGUgYSBoYXNoIGNvZGUgZm9yIHRoaXMgY29sbGF0aW9uLiAgSnVzdCBoYXNoIHRoZSBtYWluIHJ1bGUgdGFibGUgLS0KLy8gdGhhdCBzaG91bGQgYmUgZ29vZCBlbm91Z2ggZm9yIGFsbW9zdCBhbnkgdXNlLgppbnQzMl90ClJ1bGVCYXNlZENvbGxhdG9yOjpoYXNoQ29kZSgpIGNvbnN0CnsKICAgIGludDMyX3QgICAgICAgICB2YWx1ZSA9IDA7CiAgICBpbnQzMl90ICAgICAgICAgYzsKICAgIGludDMyX3QgICAgICAgICBjb3VudCA9IGdldFJ1bGVzKCkubGVuZ3RoKCk7CiAgICBVVGV4dE9mZnNldCAgICAgIHBvcyA9IGNvdW50IC0gMTsKCiAgICBpZiAoY291bnQgPiA2NCkKICAgIHsKICAgICAgICBjb3VudCA9IDY0OyAvLyBvbmx5IGhhc2ggdXB0byBsaW1pdAogICAgfQoKICAgIGludDE2X3QgaSA9IDA7CgogICAgd2hpbGUgKGkgPCBjb3VudCkKICAgIHsKICAgICAgICBjID0gZGF0YS0+cnVsZVRhYmxlW3Bvc107CiAgICAgICAgdmFsdWUgPSAoKHZhbHVlIDw8IChjICYgMHgwZikpIF4gKGMgPDwgOCkpICsgKGMgXiB2YWx1ZSk7CiAgICAgICAgaSArPSAxOwogICAgICAgIHBvcyAtPSAxOwogICAgfQoKICAgIGlmICh2YWx1ZSA9PSAwKQogICAgewogICAgICAgIHZhbHVlID0gMTsKICAgIH0KCiAgICByZXR1cm4gdmFsdWU7Cn0KCi8vIGZpbmQgdGhlIGNvbnRyYWN0aW5nIGNoYXIgZW50cnkgaW4gdGhlIGxpc3QKaW50MzJfdApSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0RW50cnkoVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQqIGxpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgVUJvb2wgZndkKQp7CiAgICBpbnQzMl90IGk7CgkKICAgIGlmIChsaXN0ICE9IE5VTEwpCiAgICB7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3QtPnNpemUoKTsgaSArPSAxKQogICAgICAgIHsKICAgICAgICAgICAgRW50cnlQYWlyICpwYWlyID0gbGlzdC0+YXQoaSk7CgogICAgICAgICAgICBpZiAoKHBhaXIgIT0gTlVMTCkgJiYgKHBhaXItPmZ3ZCA9PSBmd2QpICYmIChwYWlyLT5nZXRFbnRyeU5hbWUoKSA9PSBuYW1lKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFJ1bGVCYXNlZENvbGxhdG9yOjpVTk1BUFBFRDsKfQoKLy8gbG9vayBmb3IgdGhlIGNvbnRyYWN0aW5nIGxpc3QgZW50cnkgd2l0aCB0aGUgYmVnaW5uaW5nIGNoYXIKVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQqClJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb250cmFjdFZhbHVlcyhVQ2hhciBjaCkgY29uc3QKewogICAgaW50MzJfdCBpbmRleCA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY2gpOwogICAgcmV0dXJuIGdldENvbnRyYWN0VmFsdWVzKGluZGV4IC0gQ09OVFJBQ1RDSEFSSU5ERVgpOwp9CgovLyBsb29rIGZvciB0aGUgY29udHJhY3RpbmcgbGlzdCBlbnRyeSB3aXRoIHRoZSBpbmRleApWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCoKUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbnRyYWN0VmFsdWVzKGludDMyX3QgICAgaW5kZXgpIGNvbnN0CnsKICAgIGlmIChkYXRhLT5jb250cmFjdFRhYmxlICE9IE5VTEwpCiAgICB7CiAgICAgICAgaWYgKGluZGV4ID49IDApCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZGF0YS0+Y29udHJhY3RUYWJsZS0+YXQoaW5kZXgpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgovKioKICAqIFJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZXMgdGhhdCBlbmQKICAqIHdpdGggdGhlIHNwZWNpZmllZCBjb21wYXJpc29uIG9yZGVyLgogICoKICAqIEBwYXJhbSBvcmRlciBhIGNvbGxhdGlvbiBvcmRlciByZXR1cm5lZCBieSBwcmV2aW91cyBvciBuZXh0LgogICogQHJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXVlbmNlcyBlbmRpbmcKICAqICAgICAgICAgd2l0aCB0aGUgc3BlY2lmaWVkIG9yZGVyLgogICoKICAqIEBzZWUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yI2dldE1heEV4cGFuc2lvbgogICovCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmdldE1heEV4cGFuc2lvbihpbnQzMl90IG9yZGVyKSBjb25zdAp7CiAgICBpbnQzMl90IHJlc3VsdCA9IDE7CiAgICAKICAgIGlmIChkYXRhLT5leHBhbmRUYWJsZSAhPSBOVUxMKQogICAgewogICAgICAgIC8vIFJpZ2h0IG5vdyB0aGlzIGRvZXMgYSBsaW5lYXIgc2VhcmNoIHRocm91Z2ggdGhlIGVudGlyZQogICAgICAgIC8vIGV4cGFuZHNpb24gdGFibGUuICBJZiBhIGNvbGxhdG9yIGhhZCBhIGxhcmdlIG51bWJlciBvZiBleHBhbnNpb25zLAogICAgICAgIC8vIHRoaXMgY291bGQgY2F1c2UgYSBwZXJmb3JtYW5jZSBwcm9ibGVtLCBidXQgaW4gcHJhY3RpY2UgdGhhdAogICAgICAgIC8vIHJhcmVseSBoYXBwZW5zCiAgICAgICAgaW50MzJfdCBpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBkYXRhLT5leHBhbmRUYWJsZS0+c2l6ZSgpOyBpICs9IDEpCiAgICAgICAgewogICAgICAgICAgICBWZWN0b3JPZkludCAqdmFsdWVMaXN0ID0gZGF0YS0+ZXhwYW5kVGFibGUtPmF0KGkpOwogICAgICAgICAgICBpbnQzMl90IGxlbmd0aCA9IHZhbHVlTGlzdC0+c2l6ZSgpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKGxlbmd0aCA+IHJlc3VsdCAmJiB2YWx1ZUxpc3QtPmF0KGxlbmd0aC0xKSA9PSBvcmRlcikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzdWx0ID0gbGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KICAgIAovKioKICogIEdldCB0aGUgZW50cnkgb2YgaGFzaCB0YWJsZSBvZiB0aGUgZXhwYW5kaW5nIHN0cmluZyBpbiB0aGUgY29sbGF0aW9uCiAqICB0YWJsZS4KICogIEBwYXJhbSBvZmZzZXQgdGhlIGluZGV4IG9mIHRoZSBleHBhbmRpbmcgc3RyaW5nIHZhbHVlIGxpc3QKICovClZlY3Rvck9mSW50ICpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0RXhwYW5kVmFsdWVMaXN0KGludDMyX3Qgb3JkZXIpIGNvbnN0CnsKICAgIHJldHVybiBkYXRhLT5leHBhbmRUYWJsZS0+YXQob3JkZXIgLSBFWFBBTkRDSEFSSU5ERVgpOwp9CgoKCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtSW4oUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBVTWVtb3J5U3RyZWFtKiBpcywgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICBpZiAoIXVwcnZfbXN0cm1fZXJyb3IoaXMpICYmIFVfU1VDQ0VTUyhzdGF0dXMpKSB7CiAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGlzIGlzIHRoZSBjb3JyZWN0IGZpbGUgdHlwZQogICAgICAgIGludDE2X3QgaWQ7CgogICAgICAgIHVwcnZfbXN0cm1fcmVhZChpcywgJmlkLCBzaXplb2YoaWQpKTsKICAgICAgICBpZiAoaWQgIT0gY29sbGF0b3ItPkZJTEVJRCkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFRoaXMgaXNuJ3QgdGhlIHJpZ2h0IHR5cGUgb2YgZmlsZS4gIE1hcmsgdGhlIGlvcwogICAgICAgICAgICAvLyBhcyBmYWlsaW5nIGFuZCByZXR1cm4uCiAgICAgICAgICAgIHVwcnZfbXN0cm1fc2V0RXJyb3IoaXMpOyAvLyBmb3JjZSB0aGUgc3RyZWFtIHRvIHNldCBpdHMgZXJyb3IgZmxhZwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBTdHJlYW0gaW4gbGFyZ2Ugb2JqZWN0cwogICAgICAgIGNoYXIgaXNOdWxsOwoKICAgICAgICB1cHJ2X21zdHJtX3JlYWQoaXMsICZpc051bGwsIHNpemVvZihpc051bGwpKTsKICAgICAgICBpZiAoaXNOdWxsKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGNvbGxhdG9yLT5kYXRhOwogICAgICAgICAgICBjb2xsYXRvci0+ZGF0YSA9IE5VTEw7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUlTU0lOR19SRVNPVVJDRV9FUlJPUjsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGNvbGxhdG9yLT5kYXRhID09IE5VTEwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbGxhdG9yLT5kYXRhID0gbmV3IFRhYmxlQ29sbGF0aW9uRGF0YTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgY29sbGF0b3ItPmRhdGEtPnN0cmVhbUluKGlzLCBzdGF0dXMpOwogICAgICAgICAgICBpZiAoY29sbGF0b3ItPmRhdGEtPmlzQm9ndXMoKSkgewogICAgICAgICAgICAgICAgdXBydl9tc3RybV9zZXRFcnJvcihpcyk7IC8vIGZvcmNlIHRoZSBzdHJlYW0gdG8gc2V0IGl0cyBlcnJvciBmbGFnCiAgICAgICAgICAgICAgICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBlbmQgbWFya2VyIGlzIHByZXNlbnQKICAgICAgICB1cHJ2X21zdHJtX3JlYWQoaXMsICZpZCwgc2l6ZW9mKGlkKSk7CiAgICAgICAgaWYgKGlkICE9IGNvbGxhdG9yLT5GSUxFSUQpCiAgICAgICAgewogICAgICAgICAgICAvLyBUaGlzIGlzbid0IHRoZSByaWdodCB0eXBlIG9mIGZpbGUuICBNYXJrIHRoZSBpb3MKICAgICAgICAgICAgLy8gYXMgZmFpbGluZyBhbmQgcmV0dXJuLgogICAgICAgICAgICB1cHJ2X21zdHJtX3NldEVycm9yKGlzKTsgLy8gZm9yY2UgdGhlIHN0cmVhbSB0byBzZXQgaXRzIGVycm9yIGZsYWcKICAgICAgICAgICAgc3RhdHVzID0gVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBSZXNldCBvdGhlciBkYXRhIG1lbWJlcnMKICAgICAgICBjb2xsYXRvci0+aXNPdmVySWdub3JlID0gRkFMU0U7CiAgICAgICAgY29sbGF0b3ItPmxhc3RDaGFyID0gMDsKICAgICAgICBkZWxldGUgY29sbGF0b3ItPm1QYXR0ZXJuOwogICAgICAgIGNvbGxhdG9yLT5tUGF0dGVybiA9IDA7CiAgICAgICAgY29sbGF0b3ItPmtleS5yZW1vdmUoKTsKICAgICAgICBjb2xsYXRvci0+ZGF0YUlzT3duZWQgPSBUUlVFOwogICAgfQp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbU91dChjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogY29sbGF0b3IsIFVNZW1vcnlTdHJlYW0qIG9zKQp7CiAgICBpZiAoIXVwcnZfbXN0cm1fZXJyb3Iob3MpKQogICAgewogICAgICAgIC8vIFdlIHVzZSBhIDE2LWJpdCBJRCBjb2RlIHRvIGlkZW50aWZ5IHRoaXMgZmlsZS4KICAgICAgICBpbnQxNl90IGlkID0gY29sbGF0b3ItPkZJTEVJRDsKICAgICAgICB1cHJ2X21zdHJtX3dyaXRlKG9zLCAodWludDhfdCAqKSZpZCwgc2l6ZW9mKGlkKSk7CgogICAgICAgIC8vIFN0cmVhbSBvdXQgdGhlIGRhdGEKICAgICAgICBjaGFyIGlzTnVsbDsKICAgICAgICBpc051bGwgPSAoY29sbGF0b3ItPmRhdGEgPT0gMCk7CiAgICAgICAgdXBydl9tc3RybV93cml0ZShvcywgKHVpbnQ4X3QqKSZpc051bGwsIHNpemVvZihpc051bGwpKTsKCiAgICAgICAgaWYgKCFpc051bGwpCiAgICAgICAgewogICAgICAgICAgICBjb2xsYXRvci0+ZGF0YS0+c3RyZWFtT3V0KG9zKTsKICAgICAgICB9CgogICAgICAgIC8vIFdyaXRlIG91dCB0aGUgSUQgdG8gaW5kaWNhdGUgdGhlIGVuZAogICAgICAgIHVwcnZfbXN0cm1fd3JpdGUob3MsICh1aW50OF90ICopJmlkLCBzaXplb2YoaWQpKTsKICAgIH0KfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1JbihSdWxlQmFzZWRDb2xsYXRvciogY29sbGF0b3IsIEZpbGVTdHJlYW0qIGlzKQp7CiAgICBpZiAoIVRfRmlsZVN0cmVhbV9lcnJvcihpcykpCiAgICB7CiAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGlzIGlzIHRoZSBjb3JyZWN0IGZpbGUgdHlwZQogICAgICAgIGludDE2X3QgaWQ7CgogICAgICAgIFRfRmlsZVN0cmVhbV9yZWFkKGlzLCAmaWQsIHNpemVvZihpZCkpOwogICAgICAgIGlmIChpZCAhPSBjb2xsYXRvci0+RklMRUlEKQogICAgICAgIHsKICAgICAgICAgICAgLy8gVGhpcyBpc24ndCB0aGUgcmlnaHQgdHlwZSBvZiBmaWxlLiAgTWFyayB0aGUgaW9zCiAgICAgICAgICAgIC8vIGFzIGZhaWxpbmcgYW5kIHJldHVybi4KICAgICAgICAgICAgVF9GaWxlU3RyZWFtX3NldEVycm9yKGlzKTsgLy8gZm9yY2UgdGhlIHN0cmVhbSB0byBzZXQgaXRzIGVycm9yIGZsYWcKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gU3RyZWFtIGluIGxhcmdlIG9iamVjdHMKICAgICAgICBjaGFyIGlzTnVsbDsKCiAgICAgICAgVF9GaWxlU3RyZWFtX3JlYWQoaXMsICZpc051bGwsIHNpemVvZihpc051bGwpKTsKICAgICAgICBpZiAoaXNOdWxsKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGNvbGxhdG9yLT5kYXRhOwogICAgICAgICAgICBjb2xsYXRvci0+ZGF0YSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb2xsYXRvci0+ZGF0YSA9PSBOVUxMKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb2xsYXRvci0+ZGF0YSA9IG5ldyBUYWJsZUNvbGxhdGlvbkRhdGE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGNvbGxhdG9yLT5kYXRhLT5zdHJlYW1Jbihpcyk7CiAgICAgICAgICAgIGlmIChjb2xsYXRvci0+ZGF0YS0+aXNCb2d1cygpKSB7CiAgICAgICAgICAgICAgICBUX0ZpbGVTdHJlYW1fc2V0RXJyb3IoaXMpOyAvLyBmb3JjZSB0aGUgc3RyZWFtIHRvIHNldCBpdHMgZXJyb3IgZmxhZwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgdGhhdCB0aGUgZW5kIG1hcmtlciBpcyBwcmVzZW50CiAgICAgICAgVF9GaWxlU3RyZWFtX3JlYWQoaXMsICZpZCwgc2l6ZW9mKGlkKSk7CiAgICAgICAgaWYgKGlkICE9IGNvbGxhdG9yLT5GSUxFSUQpCiAgICAgICAgewogICAgICAgICAgICAvLyBUaGlzIGlzbid0IHRoZSByaWdodCB0eXBlIG9mIGZpbGUuICBNYXJrIHRoZSBpb3MKICAgICAgICAgICAgLy8gYXMgZmFpbGluZyBhbmQgcmV0dXJuLgogICAgICAgICAgICBUX0ZpbGVTdHJlYW1fc2V0RXJyb3IoaXMpOyAvLyBmb3JjZSB0aGUgc3RyZWFtIHRvIHNldCBpdHMgZXJyb3IgZmxhZwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBSZXNldCBvdGhlciBkYXRhIG1lbWJlcnMKICAgICAgICBjb2xsYXRvci0+aXNPdmVySWdub3JlID0gRkFMU0U7CiAgICAgICAgY29sbGF0b3ItPmxhc3RDaGFyID0gMDsKICAgICAgICBkZWxldGUgY29sbGF0b3ItPm1QYXR0ZXJuOwogICAgICAgIGNvbGxhdG9yLT5tUGF0dGVybiA9IDA7CiAgICAgICAgY29sbGF0b3ItPmtleS5yZW1vdmUoKTsKICAgICAgICBjb2xsYXRvci0+ZGF0YUlzT3duZWQgPSBUUlVFOwogICAgfQp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbU91dChjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogY29sbGF0b3IsIEZpbGVTdHJlYW0qIG9zKQp7CiAgICBpZiAoIVRfRmlsZVN0cmVhbV9lcnJvcihvcykpCiAgICB7CiAgICAgICAgLy8gV2UgdXNlIGEgMTYtYml0IElEIGNvZGUgdG8gaWRlbnRpZnkgdGhpcyBmaWxlLgogICAgICAgIGludDE2X3QgaWQgPSBjb2xsYXRvci0+RklMRUlEOwogICAgICAgIFRfRmlsZVN0cmVhbV93cml0ZShvcywgJmlkLCBzaXplb2YoaWQpKTsKCiAgICAgICAgLy8gU3RyZWFtIG91dCB0aGUgZGF0YQogICAgICAgIGNoYXIgaXNOdWxsOwogICAgICAgIGlzTnVsbCA9IChjb2xsYXRvci0+ZGF0YSA9PSAwKTsKICAgICAgICBUX0ZpbGVTdHJlYW1fd3JpdGUob3MsICZpc051bGwsIHNpemVvZihpc051bGwpKTsKCiAgICAgICAgaWYgKCFpc051bGwpCiAgICAgICAgewogICAgICAgICAgICBjb2xsYXRvci0+ZGF0YS0+c3RyZWFtT3V0KG9zKTsKICAgICAgICB9CgogICAgICAgIC8vIFdyaXRlIG91dCB0aGUgSUQgdG8gaW5kaWNhdGUgdGhlIGVuZAogICAgICAgIFRfRmlsZVN0cmVhbV93cml0ZShvcywgJmlkLCBzaXplb2YoaWQpKTsKICAgIH0KfQoKVUJvb2wgUnVsZUJhc2VkQ29sbGF0b3I6OndyaXRlVG9GaWxlKGNvbnN0IGNoYXIqIGZpbGVOYW1lKSBjb25zdAp7CiAgICBGaWxlU3RyZWFtKiBvZnMgPSBUX0ZpbGVTdHJlYW1fb3BlbihmaWxlTmFtZSwgIndiIik7CiAgICBpZiAob2ZzICE9IDApCiAgICB7CiAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtT3V0KHRoaXMsIG9mcyk7CiAgICB9CgojaWZkZWYgQ09MTERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgImJpbmFyeSB3cml0ZSAlcyBzaXplICVkICVzXG4iLCBmaWxlTmFtZSwgVF9GaWxlU3RyZWFtX3NpemUob2ZzKSwKICAgICAgICAoIVRfRmlsZVN0cmVhbV9lcnJvcihvZnMpID8gIiwgT0siIDogIiwgRkFJTCIpKTsKI2VuZGlmCgogICAgVUJvb2wgZXJyID0gVF9GaWxlU3RyZWFtX2Vycm9yKG9mcykgPT0gMDsKCiAgICBUX0ZpbGVTdHJlYW1fY2xvc2Uob2ZzKTsKICAgIHJldHVybiBlcnI7Cn0KLyoKVUJvb2wgUnVsZUJhc2VkQ29sbGF0b3I6OnByZXBhcmVGb3JCdW5kbGUoKSBjb25zdAp7CiAgICBVTWVtb3J5U3RyZWFtKiBvZnMgPSB1cHJ2X21zdHJtX29wZW5OZXcoMCk7CiAgICBpZiAob2ZzICE9IDApCiAgICB7CiAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtT3V0KHRoaXMsIG9mcyk7CiAgICB9CgojaWZkZWYgQ09MTERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgImJpbmFyeSB3cml0ZSAlcyBzaXplICVkICVzXG4iLCBmaWxlTmFtZSwgVF9GaWxlU3RyZWFtX3NpemUob2ZzKSwKICAgICAgICAoIVRfRmlsZVN0cmVhbV9lcnJvcihvZnMpID8gIiwgT0siIDogIiwgRkFJTCIpKTsKI2VuZGlmCgogICAgVUJvb2wgZXJyID0gdXBydl9tc3RybV9lcnJvcihvZnMpID09IDA7CgogICAgdXBydl9tc3RybV9jbG9zZShvZnMpOwoKICAgIHJldHVybiBlcnI7Cn0KKi8KCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OmFkZFRvQ2FjaGUoY29uc3QgVW5pY29kZVN0cmluZyYga2V5KQp7CiAgICAvLyBUaGlzIG1ldGhvZCBkb2Vzbid0IGFkZCB0aGUgUnVsZUJhc2VkQ29sbGF0b3IgaXRzZWxmIHRvIHRoZSBjYWNoZS4gIEluc3RlYWQsCiAgICAvLyBpdCBhZGRzIHRoZSBnaXZlbiBSdWxlQmFzZWRDb2xsYXRvcidzIGRhdGEgb2JqZWN0IHRvIHRoZSBUYWJsZUNvbGxhdGlvbkRhdGEKICAgIC8vIGNhY2hlLCBhbmQgbWFya3MgaXQgYXMgbm9uLW93bmVkIGluIHRoZSBnaXZlbiBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QuCiAgICBUYWJsZUNvbGxhdGlvbkRhdGE6OmFkZFRvQ2FjaGUoa2V5LCBkYXRhKTsKICAgIGRhdGFJc093bmVkID0gRkFMU0U7Cn0KCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbnN0cnVjdEZyb21DYWNoZShjb25zdCBVbmljb2RlU3RyaW5nJiBrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICAvLyBBdHRlbXB0IHRvIGNvbnN0cnVjdCB0aGlzIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdCBmcm9tIGNhY2hlZCBUYWJsZUNvbGxhdGlvbkRhdGEuCiAgICAvLyBJZiBubyBzdWNoIGRhdGEgaXMgaW4gdGhlIGNhY2hlLCByZXR1cm4gZmFsc2UuCiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHJldHVybjsKICAgIGlmIChkYXRhSXNPd25lZCkKICAgIHsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gTlVMTDsKICAgIH0KCiAgICBpc092ZXJJZ25vcmUgPSBGQUxTRTsKICAgIGxhc3RDaGFyID0gMDsKICAgIG1QYXR0ZXJuID0gMDsKICAgIHNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7CgogICAgZGF0YUlzT3duZWQgPSBGQUxTRTsKICAgIGRhdGEgPSBUYWJsZUNvbGxhdGlvbkRhdGE6OmZpbmRJbkNhY2hlKGtleSk7CiAgICBpZiAoZGF0YSA9PSBOVUxMKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfTUlTU0lOR19SRVNPVVJDRV9FUlJPUjsKICAgIH0KfQoKY2hhcioKUnVsZUJhc2VkQ29sbGF0b3I6OmNyZWF0ZVBhdGhOYW1lKCAgY29uc3QgVW5pY29kZVN0cmluZyYgICAgcHJlZml4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgICAgc3VmZml4KQp7CiAgICAvLyBDb25jYXRlbmF0ZSB0aHJlZSBlbGVtZW50cyB0byBmb3JtIGEgZmlsZSBuYW1lLCBhbmQgcmV0dXJuIGl0LgoKICAgIFVuaWNvZGVTdHJpbmcgICB3b3JraW5nTmFtZShwcmVmaXgpOwogICAgaW50MzJfdCAgICAgICAgIHNpemU7CiAgICBjaGFyKiAgICAgICAgICAgcmV0dXJuVmFsOwoKICAgIHdvcmtpbmdOYW1lICs9IG5hbWU7CiAgICB3b3JraW5nTmFtZSArPSBzdWZmaXg7CgogICAgc2l6ZSA9IHdvcmtpbmdOYW1lLmxlbmd0aCgpOwogICAgcmV0dXJuVmFsID0gbmV3IGNoYXJbc2l6ZSArIDFdOwogICAgd29ya2luZ05hbWUuZXh0cmFjdCgwLCBzaXplLCByZXR1cm5WYWwsICIiKTsKICAgIHJldHVyblZhbFtzaXplXSA9IDA7CgogICAgcmV0dXJuIHJldHVyblZhbDsKfQoKdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6Y2hvcExvY2FsZShVbmljb2RlU3RyaW5nJiBsb2NhbGVOYW1lKQp7CiAgICAvLyBjaG9wTG9jYWxlIHJlbW92ZXMgdGhlIGZpbmFsIGVsZW1lbnQgZnJvbSBhIGxvY2FsZSBzdHJpbmcuCiAgICAvLyBGb3IgaW5zdGFuY2UsICJkZV9DSCIgYmVjb21lcyAiZGUiLCBhbmQgImRlIiBiZWNvbWVzICIiLgogICAgLy8gIiIgcmVtYWlucyAiIi4KCiAgICBpbnQzMl90ICAgICBzaXplID0gbG9jYWxlTmFtZS5sZW5ndGgoKTsKICAgIGludDMyX3QgICAgIGk7CgogICAgZm9yIChpID0gc2l6ZSAtIDE7IGkgPiAwOyBpLS0pCiAgICB7CiAgICAgICAgaWYgKGxvY2FsZU5hbWVbaV0gPT0gMHgwMDVGKQogICAgICAgIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChpIDwgMCkKICAgIHsKICAgICAgIGkgPSAwOwogICAgfQoKICAgIGxvY2FsZU5hbWUucmVtb3ZlKGksIHNpemUgLSBpKTsKfQoKCnVpbnQ4X3QgKgpSdWxlQmFzZWRDb2xsYXRvcjo6Y2xvbmVSdWxlRGF0YShpbnQzMl90ICZsZW5ndGgsIFVFcnJvckNvZGUgJnN0YXR1cykKewogICAgVU1lbW9yeVN0cmVhbSAqbWVtZGF0YSA9IDA7CiAgICB1aW50OF90ICpkYXRhID0gMDsKCiAgICBpZihVX0ZBSUxVUkUoc3RhdHVzKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIG1lbWRhdGEgPSB1cHJ2X21zdHJtX29wZW5OZXcoMCk7CgogICAgaWYgKG1lbWRhdGEgIT0gMCkgewogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbU91dCh0aGlzLCBtZW1kYXRhKTsKICAgIH0KCiAgICBVQm9vbCBlcnIgPSB1cHJ2X21zdHJtX2Vycm9yKG1lbWRhdGEpID09IDA7CgoKICAgIGRhdGEgPSAodWludDhfdCAqKXVwcnZfbWFsbG9jKG1lbWRhdGEtPmZQb3MpOwogICAgaWYoZGF0YSA9PSAwKSB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICB1cHJ2X21zdHJtX2Nsb3NlKG1lbWRhdGEpOwogICAgICAgIGxlbmd0aCA9IDA7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9IGVsc2UgewogICAgICAgIHVwcnZfbWVtY3B5KGRhdGEsIG1lbWRhdGEtPmZTdGFydCwgbWVtZGF0YS0+ZlBvcyk7CiAgICAgICAgbGVuZ3RoID0gbWVtZGF0YS0+ZlBvczsKICAgICAgICB1cHJ2X21zdHJtX2Nsb3NlKG1lbWRhdGEpOwogICAgICAgIHJldHVybiBkYXRhOwogICAgfQp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpzZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLCBVQ29sQXR0cmlidXRlVmFsdWUgdmFsdWUsIFVFcnJvckNvZGUgJnN0YXR1cykgewoJc3dpdGNoKGF0dHIpIHsKCWNhc2UgVUNPTF9GUkVOQ0hfQ09MTEFUSU9OOiAvKiBhdHRyaWJ1dGUgZm9yIGRpcmVjdGlvbiBvZiBzZWNvbmRhcnkgd2VpZ2h0cyovCgkJaWYodmFsdWUgPT0gVUNPTF9PTikgewoJCQlkYXRhLT5pc0ZyZW5jaFNlYyA9IFRSVUU7CgkJfSBlbHNlIGlmICh2YWx1ZSA9PSBVQ09MX09GRikgewoJCQlkYXRhLT5pc0ZyZW5jaFNlYyA9IEZBTFNFOwoJCX0gZWxzZSBpZiAodmFsdWUgPT0gVUNPTF9ERUZBVUxUKSB7CgkJfSBlbHNlIHsKCQkJc3RhdHVzID0gVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SICA7CgkJfQoJCWJyZWFrOwogICAgY2FzZSBVQ09MX0FMVEVSTkFURV9IQU5ETElORzogLyogYXR0cmlidXRlIGZvciBoYW5kbGluZyB2YXJpYWJsZSBlbGVtZW50cyovCgkJc3RhdHVzID0gVV9VTlNVUFBPUlRFRF9FUlJPUjsKCQlicmVhazsKCWNhc2UgVUNPTF9DQVNFX0ZJUlNUOiAvKiB3aG8gZ29lcyBmaXJzdCwgbG93ZXIgY2FzZSBvciB1cHBlcmNhc2UgKi8KCQlzdGF0dXMgPSBVX1VOU1VQUE9SVEVEX0VSUk9SOwoJCWJyZWFrOwoJY2FzZSBVQ09MX0NBU0VfTEVWRUw6IC8qIGRvIHdlIGhhdmUgYW4gZXh0cmEgY2FzZSBsZXZlbCAqLwoJCXN0YXR1cyA9IFVfVU5TVVBQT1JURURfRVJST1I7CgkJYnJlYWs7CgljYXNlIFVDT0xfTk9STUFMSVpBVElPTl9NT0RFOiAvKiBhdHRyaWJ1dGUgZm9yIG5vcm1hbGl6YXRpb24gKi8KCQlpZih2YWx1ZSA9PSBVQ09MX09OKSB7CiAgICAgICAgICAgIHNldERlY29tcG9zaXRpb24oTm9ybWFsaXplcjo6REVDT01QKTsKCQl9IGVsc2UgaWYgKHZhbHVlID09IFVDT0xfT0ZGKSB7CiAgICAgICAgICAgIHNldERlY29tcG9zaXRpb24oTm9ybWFsaXplcjo6Tk9fT1ApOwoJCX0gZWxzZSBpZiAodmFsdWUgPT0gVUNPTF9ERUZBVUxUKSB7CiAgICAgICAgICAgIHNldERlY29tcG9zaXRpb24oZkRlZmF1bHREZWNvbXApOwoJCX0gZWxzZSB7CgkJCXN0YXR1cyA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUiAgOwoJCX0KCQlicmVhazsKCQlicmVhazsKCWNhc2UgVUNPTF9TVFJFTkdUSDogICAgICAgICAvKiBhdHRyaWJ1dGUgZm9yIHN0cmVuZ3RoICovCgkJc3RhdHVzID0gVV9VTlNVUFBPUlRFRF9FUlJPUjsKCQlicmVhazsKCWNhc2UgVUNPTF9BVFRSSUJVVEVfQ09VTlQ6CglkZWZhdWx0OgoJCXN0YXR1cyA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsKCQlicmVhazsKCX0KfQoKVUNvbEF0dHJpYnV0ZVZhbHVlIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLCBVRXJyb3JDb2RlICZzdGF0dXMpIHsKCXN3aXRjaChhdHRyKSB7CgljYXNlIFVDT0xfRlJFTkNIX0NPTExBVElPTjogLyogYXR0cmlidXRlIGZvciBkaXJlY3Rpb24gb2Ygc2Vjb25kYXJ5IHdlaWdodHMqLwoJCWlmKGRhdGEtPmlzRnJlbmNoU2VjID09IFRSVUUpIHsKCQkJcmV0dXJuIFVDT0xfT047CgkJfSBlbHNlIHsKCQkJcmV0dXJuIFVDT0xfT0ZGOwoJCX0KCQlicmVhazsKICAgIGNhc2UgVUNPTF9BTFRFUk5BVEVfSEFORExJTkc6IC8qIGF0dHJpYnV0ZSBmb3IgaGFuZGxpbmcgdmFyaWFibGUgZWxlbWVudHMqLwoJCXN0YXR1cyA9IFVfVU5TVVBQT1JURURfRVJST1I7CgkJYnJlYWs7CgljYXNlIFVDT0xfQ0FTRV9GSVJTVDogLyogd2hvIGdvZXMgZmlyc3QsIGxvd2VyIGNhc2Ugb3IgdXBwZXJjYXNlICovCgkJc3RhdHVzID0gVV9VTlNVUFBPUlRFRF9FUlJPUjsKCQlicmVhazsKCWNhc2UgVUNPTF9DQVNFX0xFVkVMOiAvKiBkbyB3ZSBoYXZlIGFuIGV4dHJhIGNhc2UgbGV2ZWwgKi8KCQlzdGF0dXMgPSBVX1VOU1VQUE9SVEVEX0VSUk9SOwoJCWJyZWFrOwoJY2FzZSBVQ09MX05PUk1BTElaQVRJT05fTU9ERTogLyogYXR0cmlidXRlIGZvciBub3JtYWxpemF0aW9uICovCiAgICAgICAgaWYoZ2V0RGVjb21wb3NpdGlvbigpID09IE5vcm1hbGl6ZXI6OkRFQ09NUCkgewogICAgICAgICAgICByZXR1cm4gVUNPTF9PTjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gVUNPTF9PRkY7CiAgICAgICAgfQoJCWJyZWFrOwoJY2FzZSBVQ09MX1NUUkVOR1RIOiAgICAgICAgIC8qIGF0dHJpYnV0ZSBmb3Igc3RyZW5ndGggKi8KICAgICAgICBzd2l0Y2goZ2V0U3RyZW5ndGgoKSkgewogICAgICAgIGNhc2UgUFJJTUFSWSA6CiAgICAgICAgICAgICAgICByZXR1cm4gVUNPTF9QUklNQVJZOwogICAgICAgIGNhc2UgU0VDT05EQVJZIDoKICAgICAgICAgICAgICAgIHJldHVybiBVQ09MX1NFQ09OREFSWTsKICAgICAgICBjYXNlIFRFUlRJQVJZIDoKICAgICAgICAgICAgICAgIHJldHVybiBVQ09MX1RFUlRJQVJZOwogICAgICAgIGNhc2UgSURFTlRJQ0FMIDoKICAgICAgICAgICAgICAgIHJldHVybiBVQ09MX0lERU5USUNBTDsKICAgICAgICBkZWZhdWx0IDoKICAgICAgICAgICAgc3RhdHVzID0gVV9JTlRFUk5BTF9QUk9HUkFNX0VSUk9SOyAgICAgICAgIAogICAgICAgIH0KCQlicmVhazsKCWNhc2UgVUNPTF9BVFRSSUJVVEVfQ09VTlQ6CglkZWZhdWx0OgoJCXN0YXR1cyA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsKCQlicmVhazsKCX0KCXJldHVybiBVQ09MX0RFRkFVTFQ7Cn0KCkNvbGxhdG9yKiBSdWxlQmFzZWRDb2xsYXRvcjo6c2FmZUNsb25lKHZvaWQpIHsKICAgIHJldHVybiBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoKnRoaXMpOwp9CgpVQ2hhciBmb3J3YXJkQ2hhckl0ZXJhdG9yR2x1ZSh2b2lkICppdGVyYXRvcikgewogICAgRm9yd2FyZENoYXJhY3Rlckl0ZXJhdG9yICppdGVyID0gKChGb3J3YXJkQ2hhcmFjdGVySXRlcmF0b3IgKilpdGVyYXRvcik7CiAgICBVQ2hhciByZXN1bHQgPSBpdGVyLT5uZXh0UG9zdEluYygpOwogICAgaWYocmVzdWx0ID09IEZvcndhcmRDaGFyYWN0ZXJJdGVyYXRvcjo6RE9ORSkgewogICAgICAgIHJldHVybiAweEZGRkY7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9Cn0KCgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoRm9yd2FyZENoYXJhY3Rlckl0ZXJhdG9yICZzb3VyY2UsCgkJCQkJCQkJCQkJIEZvcndhcmRDaGFyYWN0ZXJJdGVyYXRvciAmdGFyZ2V0KSB7CgoJVUNvbGxhdGlvblJlc3VsdCBzdHJjb2xsX3Jlc3VsdCA9IHVjb2xfc3RyY29sbGluYygoVUNvbGxhdG9yICopdGhpcywgZm9yd2FyZENoYXJJdGVyYXRvckdsdWUsICZzb3VyY2UsIGZvcndhcmRDaGFySXRlcmF0b3JHbHVlLCAmdGFyZ2V0KTsKCQoJaWYoc3RyY29sbF9yZXN1bHQgPT0gVUNPTF9MRVNTKSB7CgkJcmV0dXJuIENvbGxhdG9yOjpMRVNTOwoJfSBlbHNlIGlmKHN0cmNvbGxfcmVzdWx0ID09IFVDT0xfR1JFQVRFUikgewoJCXJldHVybiBDb2xsYXRvcjo6R1JFQVRFUjsKCX0gZWxzZSB7CgkJcmV0dXJuIENvbGxhdG9yOjpFUVVBTDsKCX0KfQoKaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0U29ydEtleShjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzb3VyY2UsCgkJCQkJCSAgdWludDhfdCAqcmVzdWx0LAoJCQkJCQkgIGludDMyX3QgcmVzdWx0TGVuZ3RoKSBjb25zdCB7CglVQ2hhciBzU3RhcnRbdGJsY29sbF9TdGFja0J1ZmZlckxlbl07CglVQ2hhciAqdVNvdXJjZSA9IHNTdGFydDsKCXVpbnQzMl90IHNvdXJjZUxlbiA9IHNvdXJjZS5sZW5ndGgoKTsKCWlmKHNvdXJjZUxlbiA+PSB0Ymxjb2xsX1N0YWNrQnVmZmVyTGVuKSB7CgkJdVNvdXJjZSA9IG5ldyBVQ2hhcltzb3VyY2VMZW4rMV07Cgl9CiAgICBzb3VyY2UuZXh0cmFjdCgwLCBzb3VyY2VMZW4sIHVTb3VyY2UpOwogICAgdVNvdXJjZVtzb3VyY2VMZW5dID0gMDsKCWludDMyX3QgcmVzTGVuID0gdWNvbF9nZXRTb3J0S2V5KChVQ29sbGF0b3IgKil0aGlzLCB1U291cmNlLCBzb3VyY2VMZW4sIHJlc3VsdCwgcmVzdWx0TGVuZ3RoKTsKCWlmKHNTdGFydCAhPSB1U291cmNlKSB7CgkJZGVsZXRlW10gdVNvdXJjZTsKCX0KCXJldHVybiByZXNMZW47Cn0KCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmdldFNvcnRLZXkoY29uc3QgICBVQ2hhciAqc291cmNlLAoJCQkJCQkgIGludDMyX3Qgc291cmNlTGVuZ3RoLAoJCQkJCQkgIHVpbnQ4X3QgKnJlc3VsdCwKCQkJCQkJICBpbnQzMl90IHJlc3VsdExlbmd0aCkgY29uc3QgewoJaW50MzJfdCByZXNMZW4gPSB1Y29sX2dldFNvcnRLZXkoKFVDb2xsYXRvciAqKXRoaXMsIHNvdXJjZSwgc291cmNlTGVuZ3RoLCByZXN1bHQsIHJlc3VsdExlbmd0aCk7CglyZXR1cm4gcmVzTGVuOwp9Cgp2b2lkICogUnVsZUJhc2VkQ29sbGF0b3I6OmdldFNvbWVNZW1vcnkoaW50MzJfdCBzaXplKSB7CiAgICBpbnQzMl90IHNpemVPZlN0dWZmID0gNTsKICAgIGlmKGZTb21lTWVtb3J5ID09IE5VTEwpIHsKICAgICAgICBmU29tZU1lbW9yeSA9ICh2b2lkICoqKXVwcnZfbWFsbG9jKHNpemVPZlN0dWZmKnNpemVvZih2b2lkKikpOwogICAgICAgIGZTaXplcyA9IG5ldyBpbnQzMl90W3NpemVPZlN0dWZmXTsKICAgICAgICBmVXNlZE1lbW9yeSA9IDA7CiAgICAgICAgZkF2YWlsYWJsZU1lbW9yeSA9IHNpemVPZlN0dWZmOwogICAgICAgIHVwcnZfbWVtc2V0KGZTb21lTWVtb3J5LCAwLCBzaXplT2ZTdHVmZipzaXplb2Yodm9pZCopKTsKICAgIH0gZWxzZSBpZihmVXNlZE1lbW9yeSA9PSBzaXplT2ZTdHVmZikgewogICAgICAgIGZVc2VkTWVtb3J5ID0gMDsKICAgIH0KCiAgICB2b2lkICpyZXN1bHQgPSBOVUxMOwogICAgaWYoKihmU29tZU1lbW9yeStmVXNlZE1lbW9yeSkgPT0gTlVMTCkgewogICAgICAgIHJlc3VsdCA9IHVwcnZfbWFsbG9jKHNpemUpOwogICAgICAgIGZTaXplc1tmVXNlZE1lbW9yeV0gPSBzaXplOwogICAgfSBlbHNlIHsKICAgICAgICBpZihmU2l6ZXNbZlVzZWRNZW1vcnldIDwgc2l6ZSkgewogICAgICAgICAgICByZXN1bHQgPSB1cHJ2X3JlYWxsb2MoKihmU29tZU1lbW9yeStmVXNlZE1lbW9yeSksIHNpemUpOwogICAgICAgICAgICBmU2l6ZXNbZlVzZWRNZW1vcnldID0gc2l6ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHQgPSAqKGZTb21lTWVtb3J5K2ZVc2VkTWVtb3J5KTsKICAgICAgICB9CiAgICB9CgogICAgaWYocmVzdWx0ID09IE5VTEwpIHsKICAgICAgICAvKmZyZWFrIG91dCovCiAgICB9CgogICAgKihmU29tZU1lbW9yeStmVXNlZE1lbW9yeSkgPSByZXN1bHQ7CiAgICBmVXNlZE1lbW9yeSsrOwoKICAgIHJldHVybiByZXN1bHQ7Cn0KCi8vZW9mCg==