LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiogQ09QWVJJR0hUOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiAgIChDKSBDb3B5cmlnaHQgVGFsaWdlbnQsIEluYy4sICAxOTk2ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgoqICAgKEMpIENvcHlyaWdodCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uLCAgMTk5Ni0xOTk5ICAgICAqCiogICBMaWNlbnNlZCBNYXRlcmlhbCAtIFByb2dyYW0tUHJvcGVydHkgb2YgSUJNIC0gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICoKKiAgIFVTIEdvdmVybm1lbnQgVXNlcnMgUmVzdHJpY3RlZCBSaWdodHMgLSBVc2UsIGR1cGxpY2F0aW9uLCBvciBkaXNjbG9zdXJlICAgKgoqICAgcmVzdHJpY3RlZCBieSBHU0EgQURQIFNjaGVkdWxlIENvbnRyYWN0IHdpdGggSUJNIENvcnAuICAgICAgICAgICAgICAgICAgICAqCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqCiogRmlsZSB0Ymxjb2xsLmNwcAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCiogIDIvNS85NyAgICAgIGFsaXUgICAgICAgIEFkZGVkIHN0cmVhbUluIGFuZCBzdHJlYW1PdXQgbWV0aG9kcy4gIEFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIHdoaWNoIHJlYWRzIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdCBmcm9tCiogICAgICAgICAgICAgICAgICAgICAgICAgIGEgYmluYXJ5IGZpbGUuICBBZGRlZCB3cml0ZVRvRmlsZSBtZXRob2Qgd2hpY2ggc3RyZWFtcwoqICAgICAgICAgICAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciBvdXQgdG8gYSBiaW5hcnkgZmlsZS4gIFRoZSBzdHJlYW1JbgoqICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgc3RyZWFtT3V0IG1ldGhvZHMgdXNlIGlzdHJlYW0gYW5kIG9zdHJlYW0gb2JqZWN0cwoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbiBiaW5hcnkgbW9kZS4KKiAgMi8xMS85NyAgICAgYWxpdSAgICAgICAgTW92ZWQgZGVjbGFyYXRpb25zIG91dCBvZiBmb3IgbG9vcCBpbml0aWFsaXplci4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgTWFjIGNvbXBhdGliaWxpdHkgI2lmZGVmIGZvciBpb3M6Om5vY3JlYXRlLgoqICAyLzEyLzk3ICAgICBhbGl1ICAgICAgICBNb2RpZmllZCB0byB1c2UgVGFibGVDb2xsYXRpb25EYXRhIHN1Yi1vYmplY3QgdG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgaG9sZCBpbnZhcmlhbnQgZGF0YS4KKiAgMi8xMy85NyAgICAgYWxpdSAgICAgICAgTW92ZWQgc2V2ZXJhbCBtZXRob2RzIGludG8gdGhpcyBjbGFzcyBmcm9tIENvbGxhdGlvbi4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgYSBwcml2YXRlIFJ1bGVCYXNlZENvbGxhdG9yKExvY2FsZSYpIGNvbnN0cnVjdG9yLAoqICAgICAgICAgICAgICAgICAgICAgICAgICB0byBiZSB1c2VkIGJ5IENvbGxhdG9yOjpnZXRJbnN0YW5jZSgpLiAgR2VuZXJhbAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhbiB1cC4gIE1hZGUgdXNlIG9mIFVFcnJvckNvZGUgdmFyaWFibGVzIGNvbnNpc3RlbnQuCiogIDIvMjAvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNsb25lLCBvcGVyYXRvcj09LCBvcGVyYXRvciE9LCBvcGVyYXRvcj0sIGFuZCBjb3B5CiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIGFuZCBnZXREeW5hbWljQ2xhc3NJRC4KKiAgMy81Lzk3ICAgICAgYWxpdSAgICAgICAgQ2hhbmdlZCBjb21wYWN0aW9uIGN5Y2xlIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UuICBXZQoqICAgICAgICAgICAgICAgICAgICAgICAgICB1c2UgdGhlIG1heGltdW0gYWxsb3dhYmxlIHZhbHVlIHdoaWNoIGlzIGtCbG9ja0NvdW50LgoqICAgICAgICAgICAgICAgICAgICAgICAgICBNb2RpZmllZCBnZXRSdWxlcygpIHRvIGxvYWQgcnVsZXMgZHluYW1pY2FsbHkuICBDaGFuZ2VkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdEZyb21GaWxlKCkgY2FsbCB0byBhY2NvbW9kYXRlIHRoaXMgKGFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlciB0byBzcGVjaWZ5IHdoZXRoZXIgYmluYXJ5IGxvYWRpbmcgaXMgdG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGFrZSBwbGFjZSkuCiogMDUvMDYvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIG1lbW9yeSBhbGxvY2F0aW9uIGVycm9yIGNoZWNrLgoqICA2LzIwLzk3ICAgICBoZWxlbmEgICAgICBKYXZhIGNsYXNzIG5hbWUgY2hhbmdlLgoqICA2LzIzLzk3ICAgICBoZWxlbmEgICAgICBBZGRpbmcgY29tbWVudHMgdG8gbWFrZSBjb2RlIG1vcmUgcmVhZGFibGUuCiogMDkvMDMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNyZWF0ZUNvbGxhdGlvbktleVZhbHVlcygpLgoqIDA2LzI2Lzk4ICAgICBlcm0gICAgICAgICBDaGFuZ2VzIGZvciBDb2xsYXRpb25LZXlzIHVzaW5nIGJ5dGUgYXJyYXlzLgoqIDA4LzEwLzk4ICAgICBlcm0gICAgICAgICBTeW5jaGVkIHdpdGggMS4yIHZlcnNpb24gb2YgUnVsZUJhc2VkQ29sbGF0b3IuamF2YQoqIDA0LzIzLzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIEVEZWNvbXBvc2l0aW9uTW9kZSwgbWVyZ2VkIHdpdGgKKiAgICAgICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUKKiAwNi8xNC85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBrUmVzb3VyY2VCdW5kbGVTdWZmaXgKKiAwNi8yMi85OSAgICAgc3RlcGhlbiAgICAgRml4ZWQgbG9naWMgaW4gY29uc3RydWN0RnJvbUZpbGUoKSBzaW5jZSAuY3R4CiogICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlcyBhcmUgbm8gbG9uZ2VyIHVzZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCiNpbmNsdWRlICJ1Y21wMzIuaCIKI2luY2x1ZGUgInRjb2xkYXRhLmgiCgojaW5jbHVkZSAidGJsY29sbC5oIgoKI2luY2x1ZGUgImNvbGVpdHIuaCIKI2luY2x1ZGUgImxvY2lkLmgiCiNpbmNsdWRlICJ1bmljb2RlLmgiCiNpbmNsdWRlICJ0YWJsZXMuaCIKI2luY2x1ZGUgIm5vcm1senIuaCIKI2luY2x1ZGUgIm1lcmdlY29sLmgiCiNpbmNsdWRlICJyZXNidW5kLmgiCiNpbmNsdWRlICJmaWxlc3RybS5oIgoKI2lmZGVmIF9ERUJVRwojaW5jbHVkZSAidW5pc3RybS5oIgojZW5kaWYKCiNpbmNsdWRlICJjb21waXRyLmgiCgojaW5jbHVkZSA8c3RyaW5nLmg+CgoKY2xhc3MgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcgp7CnB1YmxpYzoKICAgIHN0YXRpYyB2b2lkIHN0cmVhbUluKFJ1bGVCYXNlZENvbGxhdG9yKiBjb2xsYXRvciwgRmlsZVN0cmVhbSogaXMpOwogICAgc3RhdGljIHZvaWQgc3RyZWFtT3V0KGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yKiBjb2xsYXRvciwgRmlsZVN0cmVhbSogb3MpOwp9OwoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vICBUaGUgZm9sbG93aW5nIGRpYWdyYW0gc2hvd3MgdGhlIGRhdGEgc3RydWN0dXJlIG9mIHRoZSBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QuCi8vICBTdXBwb3NlIHdlIGhhdmUgdGhlIHJ1bGUsIHdoZXJlICdvLXVtbGF1dCcgaXMgdGhlIHVuaWNvZGUgY2hhciAweDAwRjYuCi8vICAiYSwgQSA8IGIsIEIgPCBjLCBDLCBjaCwgY0gsIENoLCBDSCA8IGQsIEQgLi4uIDwgbywgTzsgJ28tdW1sYXV0Jy9FLCAnTy11bWxhdXQnL0UgLi4uIi4KLy8gIFdoYXQgdGhlIHJ1bGUgc2F5cyBpcywgc29ydHMgJ2NoJ2xpZ2F0dXJlcyBhbmQgJ2MnIG9ubHkgd2l0aCB0ZXJ0aWFyeSBkaWZmZXJlbmNlIGFuZAovLyAgc29ydHMgJ28tdW1sYXV0JyBhcyBpZiBpdCdzIGFsd2F5cyBleHBhbmRlZCB3aXRoICdlJy4KLy8KLy8gbWFwcGluZyB0YWJsZSAgICAgICAgICAgICAgICAgICAgICAgY29udHJhY3RpbmcgbGlzdCAgICAgICAgICAgICAgICAgIGV4cGFuZGluZyBsaXN0Ci8vIChjb250YWlucyBhbGwgdW5pY29kZSBjaGFyCi8vICBlbnRyaWVzKSAgICAgICAgICAgICAgICAgICAgICAgICBfX18gICAgIF9fX19fX19fX19fX18gICAgICAgICBfX19fX19fX19fX19fX19fX19fX19fX19fCi8vICAgX19fX19fX18gICAgICAgICAgICAgICAgICAgfD09PnxfKl98LS0+fCdjJyAgfHYoJ2MnKSB8ICAgfD09Pnx2KCdvJyl8digndW1sYXV0Jyl8dignZScpfAovLyAgfF9cdTAwMDFffC0tPiB2KCdcdTAwMDEnKSAgIHwgICB8XzpffCAgIHwtLS0tLS0tLS0tLS0tfCAgIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKLy8gIHxfXHUwMDAyX3wtLT4gdignXHUwMDAyJykgICB8ICAgfF86X3wgICB8J2NoJyB8dignY2gnKXwgICB8ICAgfCAgICAgICAgICAgICA6ICAgICAgICAgICB8Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgfCAgIHxfOl98ICAgfC0tLS0tLS0tLS0tLS18ICAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAovLyAgfF9fX186X19ffCAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgIHwnY0gnIHx2KCdjSCcpfCAgIHwgICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKLy8gIHxfXydhJ19fX3wtLT4gdignYScpICAgICAgICB8ICAgICAgICAgICB8LS0tLS0tLS0tLS0tLXwgICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Ci8vICB8X18nYidfX198LS0+IHYoJ2InKSAgICAgICAgfCAgICAgICAgICAgfCdDaCcgfHYoJ0NoJyl8ICAgfCAgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAovLyAgfF9fX186X19ffCAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tfCAgIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKLy8gIHxfX19fOl9fX3wgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICB8J0NIJyB8dignQ0gnKXwgICB8ICAgfCAgICAgICAgICAgICA6ICAgICAgICAgICB8Ci8vICB8X19fJ2MnX198LS0tLS0tLS0tLS0tLS0tLS0tLSAgICAgICAgICAgIC0tLS0tLS0tLS0tLS0gICAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAovLyAgfF9fX186X19ffCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKLy8gIHxvLXVtbGF1dHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gICAgfF9fX19fX19fX19fX19fX19fX19fX19fX198Ci8vICB8X19fXzpfX198Ci8vCi8vCi8vIE5vdGVkIGJ5IEhlbGVuYSBTaGloIG9uIDYvMjMvOTcgd2l0aCBwZW5kaW5nIGRlc2lnbiBjaGFuZ2VzIChzbGltbWluZyBjb2xsYXRpb24pLgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Cgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDSEFSSU5ERVggPSAweDcwMDAwMDAwOyAgICAgICAgICAgICAvLyBuZWVkIGxvb2sgdXAgaW4gLmNvbW1pdCgpCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkVYUEFORENIQVJJTkRFWCA9IDB4N0UwMDAwMDA7ICAgICAgIC8vIEV4cGFuZCBpbmRleCBmb2xsb3dzCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkNPTlRSQUNUQ0hBUklOREVYID0gMHg3RjAwMDAwMDsgICAgIC8vIGNvbnRyYWN0IGluZGV4ZXMgZm9sbG93cwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpVTk1BUFBFRCA9IDB4RkZGRkZGRkY7ICAgICAgICAgICAgICAvLyB1bm1hcHBlZCBjaGFyYWN0ZXIgdmFsdWVzCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllPUkRFUklOQ1JFTUVOVCA9IDB4MDAwMTAwMDA7IC8vIHByaW1hcnkgc3RyZW5ndGggaW5jcmVtZW50CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAwMDEwMDsgLy8gc2Vjb25kYXJ5IHN0cmVuZ3RoIGluY3JlbWVudApjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpURVJUSUFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAwMDAwMTsgLy8gdGVydGlhcnkgc3RyZW5ndGggaW5jcmVtZW50CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6Ok1BWElHTk9SQUJMRSA9IDB4MDAwMTAwMDA7ICAgICAgICAgIC8vIG1heGltdW0gaWdub3JhYmxlIGNoYXIgb3JkZXIgdmFsdWUKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSTUFTSyA9IDB4ZmZmZjAwMDA7ICAgICAgLy8gbWFzayBvZmYgYW55dGhpbmcgYnV0IHByaW1hcnkgb3JkZXIKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJNQVNLID0gMHgwMDAwZmYwMDsgICAgLy8gbWFzayBvZmYgYW55dGhpbmcgYnV0IHNlY29uZGFyeSBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpURVJUSUFSWU9SREVSTUFTSyA9IDB4MDAwMDAwZmY7ICAgICAvLyBtYXNrIG9mZiBhbnl0aGluZyBidXQgdGVydGlhcnkgb3JkZXIKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZUkVTRVRNQVNLID0gMHgwMDAwZmZmZjsgICAgLy8gbWFzayBvZmYgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpJR05PUkFCTEVNQVNLID0gMHgwMDAwZmZmZjsgICAgICAgICAvLyBtYXNrIG9mZiBpZ25vcmFibGUgY2hhciBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZRElGRkVSRU5DRU9OTFkgPSAweGZmZmYwMDAwOyAvLyB1c2Ugb25seSB0aGUgcHJpbWFyeSBkaWZmZXJlbmNlCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWURJRkZFUkVOQ0VPTkxZID0gMHhmZmZmZmYwMDsgIC8vIHVzZSBvbmx5IHRoZSBwcmltYXJ5IGFuZCBzZWNvbmRhcnkgZGlmZmVyZW5jZQpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJTSElGVCA9IDE2OyAgICAgICAgICAgICAvLyBwcmltYXJ5IG9yZGVyIHNoaWZ0CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSU0hJRlQgPSA4OyAgICAgICAgICAgIC8vIHNlY29uZGFyeSBvcmRlciBzaGlmdApjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTT1JUS0VZT0ZGU0VUID0gMTsgICAgICAgICAgICAgICAgICAvLyBtaW5pbXVtIHNvcnQga2V5IG9mZnNldApjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDT05UUkFDVENIQVJPVkVSRkxPVyA9IDB4N0ZGRkZGRkY7ICAvLyBJbmRpY2F0ZXMgdGhlIGNoYXIgaXMgYSBjb250cmFjdCBjaGFyCgpjb25zdCBpbnQxNl90IFJ1bGVCYXNlZENvbGxhdG9yOjpGSUxFSUQgPSAweDU0NDM7ICAgICAgICAgICAgICAgICAgICAvLyB1bmlxdWUgZmlsZSBpZCBmb3IgcGFyaXR5IGNoZWNrCmNvbnN0IGNoYXIqIFJ1bGVCYXNlZENvbGxhdG9yOjprRmlsZW5hbWVTdWZmaXggPSAiLmNvbCI7ICAgICAgICAgICAgIC8vIGJpbmFyeSBjb2xsYXRpb24gZmlsZSBleHRlbnNpb24KY2hhciAgUnVsZUJhc2VkQ29sbGF0b3I6OmZnQ2xhc3NJRCA9IDA7IC8vIFZhbHVlIGlzIGlycmVsZXZhbnQgICAgICAgLy8gY2xhc3MgaWQKCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKCkKICAgIDogQ29sbGF0b3IoKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgbVBhdHRlcm4oMCksCiAgICAgIHNvdXJjZUN1cnNvcigwKSwKICAgICAgdGFyZ2V0Q3Vyc29yKDApLAogICAgICBkYXRhKDApLAogICAgICBkYXRhSXNPd25lZChGQUxTRSkKewp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgIFJ1bGVCYXNlZENvbGxhdG9yJiAgdGhhdCkKICAgIDogQ29sbGF0b3IodGhhdCksCiAgICAgIGlzT3Zlcklnbm9yZSh0aGF0LmlzT3Zlcklnbm9yZSksCiAgICAgIG1QYXR0ZXJuKDApLAogICAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAgIHRhcmdldEN1cnNvcigwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpLAogICAgICBkYXRhKHRoYXQuZGF0YSkgLy8gQWxpYXMgdGhlIGRhdGEgcG9pbnRlcgp7Cn0KCmJvb2xfdApSdWxlQmFzZWRDb2xsYXRvcjo6b3BlcmF0b3I9PShjb25zdCBDb2xsYXRvciYgdGhhdCkgY29uc3QKewogICAgaWYgKHRoaXMgPT0gJnRoYXQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgaWYgKHRoaXMtPmdldER5bmFtaWNDbGFzc0lEKCkgIT0gdGhhdC5nZXREeW5hbWljQ2xhc3NJRCgpKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsgIC8vIG5vdCB0aGUgc2FtZSBjbGFzcwogICAgfQoKICAgIGlmICghQ29sbGF0b3I6Om9wZXJhdG9yPT0odGhhdCkpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIFJ1bGVCYXNlZENvbGxhdG9yJiB0aGF0QWxpYXMgPSAoUnVsZUJhc2VkQ29sbGF0b3ImKXRoYXQ7CgogICAgaWYgKGlzT3Zlcklnbm9yZSAhPSB0aGF0QWxpYXMuaXNPdmVySWdub3JlKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoZGF0YSAhPSB0aGF0QWxpYXMuZGF0YSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KClJ1bGVCYXNlZENvbGxhdG9yJgpSdWxlQmFzZWRDb2xsYXRvcjo6b3BlcmF0b3I9KGNvbnN0ICBSdWxlQmFzZWRDb2xsYXRvciYgdGhhdCkKewogICAgaWYgKHRoaXMgIT0gJnRoYXQpCiAgICB7CiAgICAgICAgQ29sbGF0b3I6Om9wZXJhdG9yPSh0aGF0KTsKICAgICAgICBpc092ZXJJZ25vcmUgPSB0aGF0LmlzT3Zlcklnbm9yZTsKCiAgICAgICAgaWYgKGRhdGFJc093bmVkKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgfQoKICAgICAgICBkYXRhID0gMDsKICAgICAgICBkZWxldGUgbVBhdHRlcm47CiAgICAgICAgbVBhdHRlcm4gPSAwOwogICAgICAgIGRhdGFJc093bmVkID0gRkFMU0U7CiAgICAgICAgZGF0YSA9IHRoYXQuZGF0YTsKICAgIH0KCiAgICByZXR1cm4gKnRoaXM7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCiAgICA6IENvbGxhdG9yKCksCiAgICAgIGlzT3Zlcklnbm9yZShGQUxTRSksCiAgICAgIG1QYXR0ZXJuKDApLAogICAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAgIHRhcmdldEN1cnNvcigwKSwKICAgICAgZGF0YSgwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICAgIGlmIChGQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGNvbnN0cnVjdEZyb21SdWxlcyhydWxlcywgc3RhdHVzKTsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0ICBVbmljb2RlU3RyaW5nJiAgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgIEVDb2xsYXRpb25TdHJlbmd0aCBjb2xsYXRpb25TdHJlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCiAgOiBDb2xsYXRvcihjb2xsYXRpb25TdHJlbmd0aCwgTm9ybWFsaXplcjo6Tk9fT1ApLAogICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgIG1QYXR0ZXJuKDApLAogICAgc291cmNlQ3Vyc29yKDApLAogICAgdGFyZ2V0Q3Vyc29yKDApLAogICAgZGF0YSgwKSwKICAgIGRhdGFJc093bmVkKEZBTFNFKQp7CiAgICBpZiAoRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBjb25zdHJ1Y3RGcm9tUnVsZXMocnVsZXMsIHN0YXR1cyk7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCiAgOiBDb2xsYXRvcihURVJUSUFSWSwgZGVjb21wb3NpdGlvbk1vZGUpLAogICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgIG1QYXR0ZXJuKDApLAogICAgc291cmNlQ3Vyc29yKDApLAogICAgdGFyZ2V0Q3Vyc29yKDApLAogICAgZGF0YSgwKSwKICAgIGRhdGFJc093bmVkKEZBTFNFKQp7CiAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgcmV0dXJuOwogICAgfQogIAogIGNvbnN0cnVjdEZyb21SdWxlcyhydWxlcywgc3RhdHVzKTsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0ICBVbmljb2RlU3RyaW5nJiAgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgIEVDb2xsYXRpb25TdHJlbmd0aCBjb2xsYXRpb25TdHJlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKQogIDogQ29sbGF0b3IoY29sbGF0aW9uU3RyZW5ndGgsIGRlY29tcG9zaXRpb25Nb2RlKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgbVBhdHRlcm4oMCksCiAgICAgIHNvdXJjZUN1cnNvcigwKSwKICAgICAgdGFyZ2V0Q3Vyc29yKDApLAogICAgICBkYXRhKDApLAogICAgICBkYXRhSXNPd25lZChGQUxTRSkKewogICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgY29uc3RydWN0RnJvbVJ1bGVzKHJ1bGVzLCBzdGF0dXMpOwp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tUnVsZXMoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIC8vIENvbnN0cnVjdCB0aGlzIGNvbGxhdG9yJ3MgcnVsZXNldCBmcm9tIGl0cyBzdHJpbmcgcmVwcmVzZW50YXRpb24KICAgIGlmIChGQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChydWxlcy5pc0JvZ3VzKCkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChkYXRhSXNPd25lZCkKICAgIHsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgIH0KCiAgICBpc092ZXJJZ25vcmUgPSBGQUxTRTsKICAgIHNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7CgogICAgZGF0YSA9IG5ldyBUYWJsZUNvbGxhdGlvbkRhdGE7CiAgICBpZiAoZGF0YS0+aXNCb2d1cygpKQogICAgewogICAgICAgIHN0YXR1cyA9IE1FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBXZSBjb25zdHJ1Y3RlZCB0aGUgZGF0YSB1c2luZyB0aGUgYnVpbGQgbWV0aG9kLCBzbyB3ZSBvd24gaXQuCiAgICBkYXRhSXNPd25lZCA9IFRSVUU7CgogICAgLy8gTm93IHRoYXQgd2UndmUgZ290IGFsbCB0aGUgYnVmZmVycyBhbGxvY2F0ZWQsIGRvIHRoZSBhY3R1YWwgd29yawogICAgbVBhdHRlcm4gPSAwOwogICAgYnVpbGQocnVsZXMsIHN0YXR1cyk7Cn0KCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbnN0cnVjdEZyb21GaWxlKGNvbnN0IGNoYXIqIGZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICAvLyBUaGlzIG1ldGhvZCB0cmllcyB0byByZWFkIGluIGEgZmxhdHRlbmVkIFJ1bGVCYXNlZENvbGxhdG9yIHRoYXQKICAgIC8vIGhhcyBiZWVuIHByZXZpb3VzbHkgc3RyZWFtZWQgb3V0IHVzaW5nIHRoZSBzdHJlYW1PdXQoKSBtZXRob2QuCiAgICAvLyBUaGUgJ2ZpbGVOYW1lJyBwYXJhbWV0ZXIgc2hvdWxkIGNvbnRhaW4gYSBmdWxsIHBhdGhuYW1lIHZhbGlkIG9uCiAgICAvLyB0aGUgbG9jYWwgZW52aXJvbm1lbnQuCgogICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGRhdGFJc093bmVkKQogICAgewogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgfQoKICAgIG1QYXR0ZXJuID0gMDsKICAgIGlzT3Zlcklnbm9yZSA9IEZBTFNFOwogICAgc2V0U3RyZW5ndGgoQ29sbGF0b3I6OlRFUlRJQVJZKTsgLy8gVGhpcyBpcyB0aGUgZGVmYXVsdCBzdHJlbmd0aAoKICAgIEZpbGVTdHJlYW0qIGlmcyA9IFRfRmlsZVN0cmVhbV9vcGVuKGZpbGVOYW1lLCAicmIiKTsKICAgIGlmIChpZnMgPT0gMCkgewogICAgICAgIHN0YXR1cyA9IEZJTEVfQUNDRVNTX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBUaGUgc3RyZWFtSW4gZnVuY3Rpb24gZG9lcyB0aGUgYWN0dWFsIHdvcmsgaGVyZS4uLgogICAgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtSW4odGhpcywgaWZzKTsKCiAgICBpZiAoIVRfRmlsZVN0cmVhbV9lcnJvcihpZnMpKQogICAgewogICAgICAgIHN0YXR1cyA9IFpFUk9fRVJST1I7CiAgICB9CiAgICBlbHNlIGlmIChkYXRhICYmIGRhdGEtPmlzQm9ndXMoKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBNRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzdGF0dXMgPSBNSVNTSU5HX1JFU09VUkNFX0VSUk9SOwogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgfQoKI2lmZGVmIENPTExERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJiaW5hcnkgcmVhZCAlcyBzaXplICVkLCAlc1xuIiwgZmlsZU5hbWUsIFRfRmlsZVN0cmVhbV9zaXplKGlmcyksIGVycm9yTmFtZShzdGF0dXMpKTsKI2VuZGlmCgogICAgLy8gV2UgY29uc3RydWN0ZWQgdGhlIGRhdGEgd2hlbiBzdHJlYW1pbmcgaXQgaW4sIHNvIHdlIG93biBpdAogICAgZGF0YUlzT3duZWQgPSBUUlVFOwoKICAgIFRfRmlsZVN0cmVhbV9jbG9zZShpZnMpOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoICAgY29uc3QgTG9jYWxlJiBkZXNpcmVkTG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKICAgIDogQ29sbGF0b3IoKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpLAogICAgICBkYXRhKDApLAogICAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAgIHRhcmdldEN1cnNvcigwKSwKICAgICAgbVBhdHRlcm4oMCkKewogIGlmIChGQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgIHJldHVybjsKICAgIH0KICAKICAvLyBUcnkgdG8gbG9hZCwgaW4gb3JkZXI6CiAgLy8gMS4gVGhlIGRlc2lyZWQgbG9jYWxlJ3MgY29sbGF0aW9uLgogIC8vIDIuIEEgZmFsbGJhY2sgb2YgdGhlIGRlc2lyZWQgbG9jYWxlLgogIC8vIDMuIFRoZSBkZWZhdWx0IGxvY2FsZSdzIGNvbGxhdGlvbi4KICAvLyA0LiBBIGZhbGxiYWNrIG9mIHRoZSBkZWZhdWx0IGxvY2FsZS4KICAvLyA1LiBUaGUgZGVmYXVsdCBjb2xsYXRpb24gcnVsZXMsIHdoaWNoIGNvbnRhaW5zIGVuX1VTIGNvbGxhdGlvbiBydWxlcy4KCiAgLy8gVG8gcmVpdGVyYXRlLCB3ZSB0cnk6CiAgLy8gU3BlY2lmaWM6CiAgLy8gIGxhbmd1YWdlK2NvdW50cnkrdmFyaWFudAogIC8vICBsYW5ndWFnZStjb3VudHJ5CiAgLy8gIGxhbmd1YWdlCiAgLy8gRGVmYXVsdDoKICAvLyAgbGFuZ3VhZ2UrY291bnRyeSt2YXJpYW50CiAgLy8gIGxhbmd1YWdlK2NvdW50cnkKICAvLyAgbGFuZ3VhZ2UKICAvLyBSb290OiAoYWthIERFRkFVTFRSVUxFUykKCiAgVW5pY29kZVN0cmluZyBsb2NhbGVOYW1lOwogIGRlc2lyZWRMb2NhbGUuZ2V0TmFtZShsb2NhbGVOYW1lKTsKICBlbnVtIHsgZVRyeURlZmF1bHRMb2NhbGUsIGVUcnlEZWZhdWx0Q29sbGF0aW9uLCBlRG9uZSB9IG5leHQgPSBlVHJ5RGVmYXVsdExvY2FsZTsKICAgIAogIGZvciAoOzspCiAgICB7CiAgICAgIGlmIChsb2NhbGVOYW1lLnNpemUoKSA9PSAwKQogICAgewogICAgICBpZiAobmV4dCA9PSBlRG9uZSkKICAgICAgICAgICAgewogICAgICAgICAgLy8gV2UndmUgZmFpbGVkIHRvIGxvYWQgYSBsb2NhbGUsIGJ1dCBzaG91bGQgbmV2ZXIgcmV0dXJuIE1JU1NJTkdfUkVTT1VSQ0VfRVJST1IKICAgICAgICAgIFVFcnJvckNvZGUgaW50U3RhdHVzID0gWkVST19FUlJPUjsKCiAgICAgICAgICBjb25zdHJ1Y3RGcm9tUnVsZXMoUnVsZUJhc2VkQ29sbGF0b3I6OkRFRkFVTFRSVUxFUywgaW50U3RhdHVzKTsKICAgICAgICAgIGlmIChpbnRTdGF0dXMgPT0gWkVST19FUlJPUikKICAgICAgICB7CiAgICAgICAgICBzdGF0dXMgPSBVU0lOR19ERUZBVUxUX0VSUk9SOwogICAgICAgIH0KICAgICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICBzdGF0dXMgPSBpbnRTdGF0dXM7ICAgICAvLyBidWJibGUgYmFjawogICAgICAgIH0KCiAgICAgICAgICBpZiAoc3RhdHVzID09IE1FTU9SWV9BTExPQ0FUSU9OX0VSUk9SKQogICAgICAgIHsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICAgZGF0YS0+ZGVzaXJlZExvY2FsZSA9IGRlc2lyZWRMb2NhbGU7CiAgICAgICAgICBkZXNpcmVkTG9jYWxlLmdldE5hbWUobG9jYWxlTmFtZSk7CiAgICAgICAgICBkYXRhLT5yZWFsTG9jYWxlTmFtZSA9IGxvY2FsZU5hbWU7CiAgICAgICAgICBhZGRUb0NhY2hlKGxvY2FsZU5hbWUpOwoKICAgICAgICAgIHNldERlY29tcG9zaXRpb24oTm9ybWFsaXplcjo6Tk9fT1ApOwoKICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzID0gZ2V0UnVsZXMoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAvLyBXZSd2ZSBleGhhdXN0ZWQgb3VyIGluaGVyaXRhbmNlIGF0dGVtcHRzIHdpdGggdGhpcyBsb2NhbGUuCiAgICAgIC8vIFRyeSB0aGUgbmV4dCBzdGVwLgogICAgICBzd2l0Y2ggKG5leHQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBlVHJ5RGVmYXVsdExvY2FsZToKICAgICAgICAgIHN0YXR1cyA9IFVTSU5HX0RFRkFVTFRfRVJST1I7CiAgICAgICAgICBMb2NhbGU6OmdldERlZmF1bHQoKS5nZXROYW1lKGxvY2FsZU5hbWUpOwogICAgICAgICAgbmV4dCA9IGVUcnlEZWZhdWx0Q29sbGF0aW9uOwogICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIGVUcnlEZWZhdWx0Q29sbGF0aW9uOgogICAgICAgICAgLy8gVGhlcmUgaXMgbm8gZGlzdGluY3Rpb24gYmV0d2VlbiB0aGlzIGNvbmRpdGlvbiBvZgogICAgICAgICAgLy8gdXNpbmcgYSBkZWZhdWx0IGNvbGxhdGlvbiBvYmplY3QgYW5kIHRoZSBjb25kaXRpb24gb2YKICAgICAgICAgIC8vIHVzaW5nIGEgZGVmYXVsdCBsb2NhbGUgdG8gZ2V0IGEgY29sbGF0aW9uIG9iamVjdCBjdXJyZW50bHkuCiAgICAgICAgICAvLyBUaGF0IGlzLCB0aGUgY2FsbGVyIGNhbid0IGRpc3Rpbmd1aXNoIGJhc2VkIG9uIFVFcnJvckNvZGUuCiAgICAgICAgICBzdGF0dXMgPSBVU0lOR19ERUZBVUxUX0VSUk9SOwogICAgICAgICAgbG9jYWxlTmFtZSA9IFJlc291cmNlQnVuZGxlOjprRGVmYXVsdEZpbGVuYW1lOwogICAgICAgICAgbmV4dCA9IGVEb25lOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAvLyBGaXJzdCB0cnkgdG8gbG9hZCB0aGUgY29sbGF0aW9uIGZyb20gdGhlIGluLW1lbW9yeSBzdGF0aWMgY2FjaGUuCiAgICAgIC8vIE5vdGUgdGhhdCBhbGwgb2YgdGhlIGNhY2hpbmcgbG9naWMgaXMgaGFuZGxlZCBoZXJlLCBhbmQgaW4gdGhlCiAgICAgIC8vIGNhbGwgdG8gUnVsZUJhc2VkQ29sbGF0b3I6OmFkZFRvQ2FjaGUsIGJlbG93LgogICAgICBVRXJyb3JDb2RlIGludFN0YXR1cyA9IFpFUk9fRVJST1I7CgogICAgICBjb25zdHJ1Y3RGcm9tQ2FjaGUobG9jYWxlTmFtZSwgaW50U3RhdHVzKTsKICAgICAgaWYgKFNVQ0NFU1MoaW50U3RhdHVzKSkKICAgIHsKICAgICAgYnJlYWs7IC8vIERvbmUhCiAgICB9CgogICAgICAvLyBUaGUgY29sbGF0aW9uIHdlIHdhbnQgaXMgbm90IGluIHRoZSBjYWNoZS4gIFRoZSBzZWNvbmQgdGhpbmcKICAgICAgLy8gdG8gdHJ5IGlzIGxvYWRpbmcgZnJvbSBhIGZpbGUsIGVpdGhlciBiaW5hcnkgb3IgQVNDSUkuICBTbzoKICAgICAgLy8gVHJ5IHRvIGxvYWQgdGhlIGxvY2FsZSdzIGNvbGxhdGlvbiBkYXRhLiAgVGhpcyB3aWxsIHRyeSB0byBsb2FkCiAgICAgIC8vIGEgYmluYXJ5IGNvbGxhdGlvbiBmaWxlLCBvciBpZiB0aGF0IGlzIHVuYXZhaWxhYmxlLCBpdCB3aWxsIGdvCiAgICAgIC8vIHRvIHRoZSB0ZXh0IHJlc291cmNlIGJ1bmRsZSBmaWxlICh3aXRoIHRoZSBjb3JyZXNwb25kaW5nIG5hbWUpCiAgICAgIC8vIGFuZCB0cnkgdG8gZ2V0IHRoZSBjb2xsYXRpb24gdGFibGUgdGhlcmUuCiAgICAgIGludFN0YXR1cyA9IFpFUk9fRVJST1I7CiAgICAgIGNvbnN0cnVjdEZyb21GaWxlKGRlc2lyZWRMb2NhbGUsIGxvY2FsZU5hbWUsIFRSVUUsIGludFN0YXR1cyk7CiAgICAgIGlmIChTVUNDRVNTKGludFN0YXR1cykpCiAgICAgICAgewogICAgICAvLyBJZiB3ZSBzdWNjZWVkZWQgaW4gbG9hZGluZyB0aGUgY29sbGF0aW9uIGZyb20gYSBmaWxlLCBub3cgaXMgdGhlCiAgICAgIC8vIHRpbWUgdG8gYWRkIGl0IHRvIHRoZSBpbi1tZW1vcnkgY2FjaGUuICBXZSByZWNvcmQgdGhlIHJlYWwKICAgICAgLy8gbG9jYXRpb24gYXQgd2hpY2ggdGhlIGNvbGxhdGlvbiBkYXRhIHdhcyBmb3VuZCwgc28gd2UgY2FuIHJlbG9hZAogICAgICAvLyB0aGUgcnVsZSB0YWJsZSBxdWlja2x5LCBpZiBpdCBpcyByZXF1ZXN0ZWQsIGluIHRoZSBmdXR1cmUuCiAgICAgIC8vIFNlZSBnZXRSdWxlcygpLgogICAgICBkYXRhLT5kZXNpcmVkTG9jYWxlID0gZGVzaXJlZExvY2FsZTsKICAgICAgZGF0YS0+cmVhbExvY2FsZU5hbWUgPSBsb2NhbGVOYW1lOwogICAgICBhZGRUb0NhY2hlKGxvY2FsZU5hbWUpOwoKICAgICAgc2V0RGVjb21wb3NpdGlvbihOb3JtYWxpemVyOjpOT19PUCk7CiAgICAgIGJyZWFrOyAvLyBEb25lIQogICAgICAgIH0KICAgICAgaWYgKGludFN0YXR1cyA9PSBNRU1PUllfQUxMT0NBVElPTl9FUlJPUikKICAgIHsKICAgICAgc3RhdHVzID0gaW50U3RhdHVzOwogICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgLy8gSGF2aW5nIGZhaWxlZCwgY2hvcCBvZmYgdGhlIGVuZCBvZiB0aGUgbG9jYWxlIG5hbWUsIG1ha2luZwogICAgICAvLyBpdCBsZXNzIHNwZWNpZmljLCBhbmQgdHJ5IGFnYWluLiAgSW5kaWNhdGUgdGhlIHVzZSBvZiBhCiAgICAgIC8vIGZhbGxiYWNrIGxvY2FsZSwgdW5sZXNzIHdlJ3ZlIGFscmVhZHkgZmFsbGVuIHRocm91Z2ggdG8KICAgICAgLy8gYSBkZWZhdWx0IGxvY2FsZSAtLSB0aGVuIGxlYXZlIHRoZSBzdGF0dXMgYXMgaXMuCiAgICAgIGlmIChzdGF0dXMgPT0gWkVST19FUlJPUikKICAgIHsKICAgICAgc3RhdHVzID0gVVNJTkdfRkFMTEJBQ0tfRVJST1I7CiAgICB9CgogICAgICBjaG9wTG9jYWxlKGxvY2FsZU5hbWUpOwogICAgfQp9Cgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tRmlsZSggICBjb25zdCBMb2NhbGUmICAgICAgICAgICBsb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIGxvY2FsZUZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sX3QgICAgICAgICAgICAgICAgICB0cnlCaW5hcnlGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgICAgICAgICAgc3RhdHVzKQp7CiAgLy8gY29uc3RydWN0RnJvbUZpbGUgY3JlYXRlcyBhIGNvbGxhdGlvbiBvYmplY3QgYnkgcmVhZGluZyBmcm9tIGEKICAvLyBmaWxlLiAgSXQgZG9lcyBub3QgZW1wbG95IHRoZSB1c3VhbCBGSUxFIHNlYXJjaCBtZWNoYW5pc20gd2l0aAogIC8vIGxvY2FsZXMsIGRlZmF1bHQgbG9jYWxlcywgYW5kIGJhc2UgbG9jYWxlcy4gIEluc3RlYWQsIGl0IHRyaWVzIHRvCiAgLy8gbG9vayBvbmx5IGluIGZpbGVzIHdpdGggdGhlIGdpdmVuIGxvY2FsRmlsZU5hbWUuICBJdCBkb2VzLAogIC8vIGhvd2V2ZXIsIGVtcGxveSB0aGUgTE9DQUxFIHNlYXJjaCBtZWNoYW5pc20uCiAgCiAgLy8gVGhpcyBtZXRob2QgbWFpbnRhaW5zIHRoZSBiaW5hcnkgY29sbGF0aW9uIGZpbGVzLiAgSWYgYSBjb2xsYXRpb24KICAvLyBpcyBub3QgcHJlc2VudCBpbiBiaW5hcnkgZm9ybSwgYnV0IGlzIHByZXNlbnQgaW4gdGV4dCBmb3JtIChpbiBhCiAgLy8gcmVzb3VyY2UgYnVuZGxlIGZpbGUpLCBpdCB3aWxsIGJlIGxvYWRlZCBpbiB0ZXh0IGZvcm0sIGFuZCB0aGVuCiAgLy8gd3JpdHRlbiB0byBkaXNrLgogIAogIC8vIElmIHRyeUJpbmFyeUZpbGUgaXMgdHJ1ZSwgdGhlbiB0cnkgdG8gbG9hZCBmcm9tIHRoZSBiaW5hcnkgZmlsZSBmaXJzdC4KCiAgaWYoRkFJTFVSRShzdGF0dXMpKSB7CiAgICByZXR1cm47CiAgfQogIAogIGlmKGRhdGFJc093bmVkKSB7CiAgICBkZWxldGUgZGF0YTsKICAgIGRhdGEgPSAwOwogIH0KICAKICBjaGFyICpiaW5hcnlGaWxlUGF0aCA9IGNyZWF0ZVBhdGhOYW1lKExvY2FsZTo6Z2V0RGF0YURpcmVjdG9yeSgpLCAKCQkJCQlsb2NhbGVGaWxlTmFtZSwga0ZpbGVuYW1lU3VmZml4KTsKICAKICBpZih0cnlCaW5hcnlGaWxlKSB7CiAgICAvLyBUcnkgdG8gbG9hZCB1cCB0aGUgY29sbGF0aW9uIGZyb20gYSBiaW5hcnkgZmlsZSBmaXJzdAogICAgY29uc3RydWN0RnJvbUZpbGUoYmluYXJ5RmlsZVBhdGgsIHN0YXR1cyk7CiNpZmRlZiBDT0xMREVCVUcKICAgIGNlcnIgPDwgbG9jYWxlRmlsZU5hbWUgPDwgIiBiaW5hcnkgbG9hZCAiIDw8IGVycm9yTmFtZShzdGF0dXMpIDw8IGVuZGw7CiNlbmRpZgogICAgaWYoU1VDQ0VTUyhzdGF0dXMpIHx8IHN0YXR1cyA9PSBNRU1PUllfQUxMT0NBVElPTl9FUlJPUikgCiAgICAgIHJldHVybjsKICAgIH0KCiAgLy8gTm93IHRyeSB0byBsb2FkIGl0IHVwIGZyb20gYSByZXNvdXJjZSBidW5kbGUgdGV4dCBzb3VyY2UgZmlsZQogIFJlc291cmNlQnVuZGxlIGJ1bmRsZShMb2NhbGU6OmdldERhdGFEaXJlY3RvcnkoKSwgbG9jYWxlRmlsZU5hbWUsIHN0YXR1cyk7CgogIC8vIGlmIHRoZXJlIGlzIG5vIHJlc291cmNlIGJ1bmRsZSBmaWxlIGZvciB0aGUgZ2l2ZSBsb2NhbGUsIGJyZWFrIG91dAogIGlmKEZBSUxVUkUoc3RhdHVzKSkKICAgIHJldHVybjsKCiNpZmRlZiBDT0xMREVCVUcKICBjZXJyIDw8IGxvY2FsZUZpbGVOYW1lIDw8ICIgYXNjaWkgbG9hZCAiIDw8IGVycm9yTmFtZShzdGF0dXMpIDw8IGVuZGw7CiNlbmRpZgoKICAvLyBjaGVjayBhbmQgc2VlIGlmIHRoaXMgcmVzb3VyY2UgYnVuZGxlIGNvbnRhaW5zIGNvbGxhdGlvbiBkYXRhCiAgCiAgVW5pY29kZVN0cmluZyBjb2xTdHJpbmc7CiAgVUVycm9yQ29kZSBpbnRTdGF0dXMgPSBaRVJPX0VSUk9SOwoKICBidW5kbGUuZ2V0U3RyaW5nKCJDb2xsYXRpb25FbGVtZW50cyIsIGNvbFN0cmluZywgaW50U3RhdHVzKTsKICBpZihjb2xTdHJpbmcuaXNCb2d1cygpKSB7CiAgICBzdGF0dXMgPSBNRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgIHJldHVybjsKICB9CgogIC8vIGlmIHRoaXMgYnVuZGxlIGRvZXNuJ3QgY29udGFpbiBjb2xsYXRpb24gZGF0YSwgYnJlYWsgb3V0CiAgaWYoRkFJTFVSRShpbnRTdGF0dXMpKSB7CiAgICBzdGF0dXMgPSBNSVNTSU5HX1JFU09VUkNFX0VSUk9SOwogICAgcmV0dXJuOwogIH0KCiAgLy8gSGF2aW5nIGxvYWRlZCB0aGUgY29sbGF0aW9uIGZyb20gdGhlIHJlc291cmNlIGJ1bmRsZSB0ZXh0IGZpbGUsCiAgLy8gbm93IHJldHJpZXZlIHRoZSBDb2xsYXRpb25FbGVtZW50cyB0YWdnZWQgZGF0YSwgbWVyZ2VkIHdpdGggdGhlCiAgLy8gZGVmYXVsdCBydWxlcy4gIElmIHRoYXQgZmFpbHMsIHVzZSB0aGUgZGVmYXVsdCBydWxlcyBhbG9uZS4KCiAgY29sU3RyaW5nLmluc2VydCgwLCBERUZBVUxUUlVMRVMpOwogIGlmKGNvbFN0cmluZy5pc0JvZ3VzKCkpIHsKICAgIHN0YXR1cyA9IE1FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgcmV0dXJuOwogIH0KICAgIAogIGNvbnN0cnVjdEZyb21SdWxlcyhjb2xTdHJpbmcsIGludFN0YXR1cyk7CiAgaWYoaW50U3RhdHVzID09IE1FTU9SWV9BTExPQ0FUSU9OX0VSUk9SKSB7CiAgICBzdGF0dXMgPSBNRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgIHJldHVybjsKICB9CiAgCiAgaWYoaW50U3RhdHVzICE9IFpFUk9fRVJST1IpICB7CiAgICBzdGF0dXMgPSBVU0lOR19ERUZBVUxUX0VSUk9SOwogICAgICAKICAgIC8vIHByZWRlZmluZWQgdGFibGVzIHNob3VsZCBjb250YWluIGNvcnJlY3QgZ3JhbW1hcgogICAgaW50U3RhdHVzID0gWkVST19FUlJPUjsKICAgIGNvbnN0cnVjdEZyb21SdWxlcyhERUZBVUxUUlVMRVMsIGludFN0YXR1cyk7CiAgICBpZihpbnRTdGF0dXMgIT0gWkVST19FUlJPUikgewogICAgICBzdGF0dXMgPSBpbnRTdGF0dXM7CiAgICB9CiAgfSAKICAKI2lmZGVmIENPTExERUJVRwogIGNlcnIgPDwgbG9jYWxlRmlsZU5hbWUgPDwgIiBhc2NpaSBsb2FkICIgPDwgKFNVQ0NFU1Moc3RhdHVzKSA/ICJPSyIgOiAiRmFpbGVkIikgPDwgZW5kbDsKI2VuZGlmCiAgCiAgaWYoU1VDQ0VTUyhzdGF0dXMpICYmIHRyeUJpbmFyeUZpbGUpIHsKICAgIC8vIElmIHdlIGdldCBhIFJ1bGVCYXNlZENvbGxhdG9yIHJlc3VsdCwgZXZlbiBpZiBpdCBpcyBkZXJpdmVkCiAgICAvLyBmcm9tIGEgZGVmYXVsdCBvciBhIGZhbGxiYWNrLCB0aGVuIHdlIHdyaXRlIGl0IG91dCBhcyBhCiAgICAvLyBiaW5hcnkgZmlsZSB0byB0aGUgZGlzay4gIFRoZSBuZXh0IHRpbWUgdGhlIHN5c3RlbSB3YW50cyB0bwogICAgLy8gZ2V0IHRoaXMgY29sbGF0aW9uLCBpdCB3aWxsIGxvYWQgdXAgdmVyeSBxdWlja2x5IGZyb20gdGhlCiAgICAvLyBiaW5hcnkgZmlsZS4KICAgIGJvb2xfdCBvayA9IHdyaXRlVG9GaWxlKGJpbmFyeUZpbGVQYXRoKTsKICAgIGRlbGV0ZSBbXSBiaW5hcnlGaWxlUGF0aDsKI2lmZGVmIENPTExERUJVRwogICAgY2VyciA8PCBsb2NhbGVGaWxlTmFtZSA8PCAiIGJpbmFyeSB3cml0ZSAiIDw8IChvaz8gIk9LIiA6ICJGYWlsZWQiKSA8PCBlbmRsOwojZW5kaWYKICB9Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjp+UnVsZUJhc2VkQ29sbGF0b3IoKQp7CiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICB9CgogICAgZGF0YSA9IDA7CgogICAgZGVsZXRlIHNvdXJjZUN1cnNvcjsKICAgIHNvdXJjZUN1cnNvciA9IDA7CgogICAgZGVsZXRlIHRhcmdldEN1cnNvcjsKICAgIHRhcmdldEN1cnNvciA9IDA7CgogICAgZGVsZXRlIG1QYXR0ZXJuOwogICAgbVBhdHRlcm4gPSAwOwp9CgpDb2xsYXRvcioKUnVsZUJhc2VkQ29sbGF0b3I6OmNsb25lKCkgY29uc3QKewogICAgcmV0dXJuIG5ldyBSdWxlQmFzZWRDb2xsYXRvcigqdGhpcyk7Cn0KCi8vIENyZWF0ZSBhIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBvYmplY3QgdGhhdCB3aWxsIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzCi8vIGluIGEgc3RyaW5nLCB1c2luZyB0aGUgY29sbGF0aW9uIHJ1bGVzIGRlZmluZWQgaW4gdGhpcyBSdWxlQmFzZWRDb2xsYXRvcgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IqClJ1bGVCYXNlZENvbGxhdG9yOjpjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlKSBjb25zdAp7CiAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFpFUk9fRVJST1I7CiAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgKm5ld0N1cnNvciA9IDA7CgogICAgbmV3Q3Vyc29yID0gbmV3IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihzb3VyY2UsIHRoaXMsIHN0YXR1cyk7CiAgICBpZiAoRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJldHVybiBuZXdDdXJzb3I7Cn0KCi8vIENyZWF0ZSBhIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBvYmplY3QgdGhhdCB3aWxsIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzCi8vIGluIGEgc3RyaW5nLCB1c2luZyB0aGUgY29sbGF0aW9uIHJ1bGVzIGRlZmluZWQgaW4gdGhpcyBSdWxlQmFzZWRDb2xsYXRvcgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IqClJ1bGVCYXNlZENvbGxhdG9yOjpjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgQ2hhcmFjdGVySXRlcmF0b3ImIHNvdXJjZSkgY29uc3QKewogICAgVUVycm9yQ29kZSBzdGF0dXMgPSBaRVJPX0VSUk9SOwogICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yICpuZXdDdXJzb3IgPSAwOwoKICAgIG5ld0N1cnNvciA9IG5ldyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Ioc291cmNlLCB0aGlzLCBzdGF0dXMpOwogICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gbmV3Q3Vyc29yOwp9CgovLyBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBjb2xsYXRvcidzIHJ1bGVzLgovLyBUaGUgc3RyaW5nIGNhbiBsYXRlciBiZSBwYXNzZWQgdG8gdGhlIGNvbnN0cnVjdG9yIHRoYXQgdGFrZXMgYQovLyBVbmljb2RlU3RyaW5nIGFyZ3VtZW50LCB3aGljaCB3aWxsIGNvbnN0cnVjdCBhIGNvbGxhdG9yIHRoYXQncwovLyBmdW5jdGlvbmFsbHkgaWRlbnRpY2FsIHRvIHRoaXMgb25lLgovLyBZb3UgY2FuIGFsc28gYWxsb3cgdXNlcnMgdG8gZWRpdCB0aGUgc3RyaW5nIGluIG9yZGVyIHRvIGNoYW5nZQovLyB0aGUgY29sbGF0aW9uIGRhdGEsIG9yIHlvdSBjYW4gcHJpbnQgaXQgb3V0IGZvciBpbnNwZWN0aW9uLCBvciB3aGF0ZXZlci4KCmNvbnN0IFVuaWNvZGVTdHJpbmcmClJ1bGVCYXNlZENvbGxhdG9yOjpnZXRSdWxlcygpIGNvbnN0CnsKICAgIGlmIChtUGF0dGVybiAhPSAwKQogICAgewogICAgICAgIE1lcmdlQ29sbGF0aW9uKiYgbm9uQ29uc3RNUGF0dGVybiA9ICooTWVyZ2VDb2xsYXRpb24qKikmbVBhdHRlcm47CiAgICAgICAgbVBhdHRlcm4tPmVtaXRQYXR0ZXJuKGRhdGEtPnJ1bGVUYWJsZSk7CiAgICAgICAgZGF0YS0+aXNSdWxlVGFibGVMb2FkZWQgPSBUUlVFOwogICAgICAgIGRlbGV0ZSBub25Db25zdE1QYXR0ZXJuOwogICAgICAgIG5vbkNvbnN0TVBhdHRlcm4gPSAwOwogICAgfQogICAgZWxzZSBpZiAoIWRhdGEtPmlzUnVsZVRhYmxlTG9hZGVkKQogICAgewogICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgdGhlIGNhbGxlciB3YW50cyB0aGUgcnVsZXMsIGJ1dCB0aGUgcnVsZSB0YWJsZSBkYXRhCiAgICAgICAgLy8gaXMgbm90IGxvYWRlZC4gIEZ1cnRoZXJtb3JlLCB0aGVyZSBpcyBubyBtUGF0dGVybiBvYmplY3QgdG8gbG9hZAogICAgICAgIC8vIHRoZSBydWxlcyBmcm9tLiAgVGhlcmVmb3JlLCB3ZSBmZXRjaCB0aGUgcnVsZXMgb2ZmIHRoZSBkaXNrLgogICAgICAgIC8vIE5vdGljZSB0aGF0IHdlIHBhc3MgaW4gYSB0cnlCaW5hcnlGaWxlIHZhbHVlIG9mIEZBTFNFLCBzaW5jZQogICAgICAgIC8vIGJ5IGRlc2lnbiB0aGUgYmluYXJ5IGZpbGUgaGFzIE5PIHJ1bGVzIGluIGl0IQogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yIHRlbXA7CiAgICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBaRVJPX0VSUk9SOwogICAgICAgIHRlbXAuY29uc3RydWN0RnJvbUZpbGUoZGF0YS0+ZGVzaXJlZExvY2FsZSwgZGF0YS0+cmVhbExvY2FsZU5hbWUsIEZBTFNFLCBzdGF0dXMpOwoKICAgICAgICAvLyBXZSBtdXN0IGNoZWNrIHRoYXQgbVBhdHRlcm4gaXMgbm9uemVybyBoZXJlLCBvciB3ZSBydW4gdGhlIHJpc2sKICAgICAgICAvLyBvZiBhbiBpbmZpbml0ZSBsb29wLgogICAgICAgIGlmIChTVUNDRVNTKHN0YXR1cykgJiYgdGVtcC5tUGF0dGVybiAhPSAwKQogICAgICAgIHsKICAgICAgICAgICAgZGF0YS0+cnVsZVRhYmxlID0gdGVtcC5nZXRSdWxlcygpOwogICAgICAgICAgICBkYXRhLT5pc1J1bGVUYWJsZUxvYWRlZCA9IFRSVUU7CiNpZmRlZiBfREVCVUcKICAgICAgICAgICAgLy8gdGhlIGZvbGxvd2luZyBpcyB1c2VmdWwgZm9yIHNwZWNpZmljIGRlYnVnZ2luZyBwdXJwb3NlcwogICAgICAgICAgICAvLyBVbmljb2RlU3RyaW5nIG5hbWU7CiAgICAgICAgICAgIC8vIGNlcnIgPDwgIlRhYmxlIGNvbGxhdGlvbiBydWxlcyBsb2FkZWQgZHluYW1pY2FsbHkgZm9yICIKICAgICAgICAgICAgLy8gICAgIDw8IGRhdGEtPmRlc2lyZWRMb2NhbGUuZ2V0TmFtZShuYW1lKQogICAgICAgICAgICAvLyAgICAgPDwgIiBhdCAiCiAgICAgICAgICAgIC8vICAgICA8PCBkYXRhLT5yZWFsTG9jYWxlTmFtZQogICAgICAgICAgICAvLyAgICAgPDwgIiwgIiA8PCBkZWMgPDwgZGF0YS0+cnVsZVRhYmxlLnNpemUoKSA8PCAiIGNoYXJhY3RlcnMiCiAgICAgICAgICAgIC8vICAgICA8PCBlbmRsOwojZW5kaWYKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKI2lmZGVmIF9ERUJVRwogICAgICAgICAgICBVbmljb2RlU3RyaW5nIG5hbWU7CiAgICAgICAgICAgIGNlcnIgPDwgIlVuYWJsZSB0byBsb2FkIHRhYmxlIGNvbGxhdGlvbiBydWxlcyBkeW5hbWljYWxseSBmb3IgIgogICAgICAgICAgICAgICAgPDwgZGF0YS0+ZGVzaXJlZExvY2FsZS5nZXROYW1lKG5hbWUpCiAgICAgICAgICAgICAgICA8PCAiIGF0ICIKICAgICAgICAgICAgICAgIDw8IGRhdGEtPnJlYWxMb2NhbGVOYW1lCiAgICAgICAgICAgICAgICA8PCBlbmRsOwogICAgICAgICAgICBjZXJyIDw8ICJTdGF0dXMgIiA8PCBlcnJvck5hbWUoc3RhdHVzKSA8PCAiLCBtUGF0dGVybiAiIDw8IHRlbXAubVBhdHRlcm4gPDwgZW5kbDsKI2VuZGlmCiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBkYXRhLT5ydWxlVGFibGU7Cn0KCgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbGVuZ3RoKSBjb25zdAp7CiAgICBVbmljb2RlU3RyaW5nIHNvdXJjZV90b2dvOwogICAgVW5pY29kZVN0cmluZyB0YXJnZXRfdG9nbzsKICAgIFVUZXh0T2Zmc2V0IGJlZ2luPTA7CgogICAgc291cmNlLmV4dHJhY3QoYmVnaW4sIGljdV9taW4obGVuZ3RoLHNvdXJjZS5zaXplKCkpLCBzb3VyY2VfdG9nbyk7CiAgICB0YXJnZXQuZXh0cmFjdChiZWdpbiwgaWN1X21pbihsZW5ndGgsdGFyZ2V0LnNpemUoKSksIHRhcmdldF90b2dvKTsKICAgIHJldHVybiAoUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoc291cmNlX3RvZ28sIHRhcmdldF90b2dvKSk7Cn0KCgovLyBDb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nIHRoaXMgY29sbGF0b3IKQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0ClJ1bGVCYXNlZENvbGxhdG9yOjpjb21wYXJlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdAp7CiAgICAvLyBjaGVjayBpZiBzb3VyY2UgYW5kIHRhcmdldCBhcmUgdmFsaWQgc3RyaW5ncwogICAgaWYgKHNvdXJjZS5pc0JvZ3VzKCkgfHwgdGFyZ2V0LmlzQm9ndXMoKSkKICAgIHsKICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgfQoKICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBDb2xsYXRvcjo6RVFVQUw7CiAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFpFUk9fRVJST1I7CgogICAgLy8gVGhlIGJhc2ljIGFsZ29yaXRobSBoZXJlIGlzIHRoYXQgd2UgdXNlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcnMKICAgIC8vIHRvIHN0ZXAgdGhyb3VnaCBib3RoIHRoZSBzb3VyY2UgYW5kIHRhcmdldCBzdHJpbmdzLiAgV2UgY29tcGFyZSBlYWNoCiAgICAvLyBjb2xsYXRpb24gZWxlbWVudCBpbiB0aGUgc291cmNlIHN0cmluZyBhZ2FpbnN0IHRoZSBjb3JyZXNwb25kaW5nIG9uZQogICAgLy8gaW4gdGhlIHRhcmdldCwgY2hlY2tpbmcgZm9yIGRpZmZlcmVuY2VzLgogICAgLy8KICAgIC8vIElmIGEgZGlmZmVyZW5jZSBpcyBmb3VuZCwgd2Ugc2V0IDxyZXN1bHQ+IHRvIExFU1Mgb3IgR1JFQVRFUiB0bwogICAgLy8gaW5kaWNhdGUgd2hldGhlciB0aGUgc291cmNlIHN0cmluZyBpcyBsZXNzIG9yIGdyZWF0ZXIgdGhhbiB0aGUgdGFyZ2V0LgogICAgLy8KICAgIC8vIEhvd2V2ZXIsIGl0J3Mgbm90IHRoYXQgc2ltcGxlLiAgSWYgd2UgZmluZCBhIHRlcnRpYXJ5IGRpZmZlcmVuY2UKICAgIC8vIChlLmcuICdBJyB2cy4gJ2EnKSBuZWFyIHRoZSBiZWdpbm5pbmcgb2YgYSBzdHJpbmcsIGl0IGNhbiBiZQogICAgLy8gb3ZlcnJpZGRlbiBieSBhIHByaW1hcnkgZGlmZmVyZW5jZSAoZS5nLiAiQSIgdnMuICJCIikgbGF0ZXIgaW4gCiAgICAvLyB0aGUgc3RyaW5nLiAgRm9yIGV4YW1wbGUsICJBQSIgPCAiYUIiLCBldmVuIHRob3VnaCAnQScgPiAnYScuCiAgICAvLwogICAgLy8gVG8ga2VlcCB0cmFjayBvZiB0aGlzLCB3ZSB1c2UgY2hlY2tTZWNUZXIgYW5kIGNoZWNrVGVydGlhcnkgdG8ga2VlcAogICAgLy8gdHJhY2sgb2YgdGhlIHN0cmVuZ3RoIG9mIHRoZSBtb3N0IHNpZ25pZmljYW50IGRpZmZlcmVuY2UgdGhhdCBoYXMgYmVlbgogICAgLy8gZm91bmQgc28gZmFyLiAgV2hlbiB3ZSBmaW5kIGEgZGlmZmVyZW5jZSB3aG9zZSBzdHJlbmd0aCBpcyBncmVhdGVyIHRoYW4KICAgIC8vIHRoZSBwcmV2aW91cyBvbmVzLCBpdCBvdmVycmlkZXMgdGhlIGxhc3QgZGlmZmVyZW5jZSAoaWYgYW55KSB0aGF0CiAgICAvLyB3YXMgZm91bmQuCiAgICAvLwoKICAgIGlmIChzb3VyY2VDdXJzb3IgPT0gTlVMTCkKICAgIHsKICAgICAgICAoKFJ1bGVCYXNlZENvbGxhdG9yICopdGhpcyktPnNvdXJjZUN1cnNvciA9IGNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihzb3VyY2UpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHNvdXJjZUN1cnNvci0+c2V0VGV4dChzb3VyY2UsIHN0YXR1cyk7CiAgICB9CgogICAgaWYgKHNvdXJjZUN1cnNvciA9PSBOVUxMIHx8IEZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgfQoKICAgIGlmICh0YXJnZXRDdXJzb3IgPT0gTlVMTCkKICAgIHsKICAgICAgICAoKFJ1bGVCYXNlZENvbGxhdG9yICopdGhpcyktPnRhcmdldEN1cnNvciA9IGNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcih0YXJnZXQpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHRhcmdldEN1cnNvci0+c2V0VGV4dCh0YXJnZXQsIHN0YXR1cyk7CiAgICB9CgogICAgaWYgKHRhcmdldEN1cnNvciA9PSBOVUxMIHx8IEZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgfQoKICAgIGludDMyX3Qgc09yZGVyLCB0T3JkZXI7CiAgICBib29sX3QgZ2V0cyA9IFRSVUUsIGdldHQgPSBUUlVFOwogICAgYm9vbF90IGluaXRpYWxDaGVja1NlY1RlciA9IGdldFN0cmVuZ3RoKCkgPj0gQ29sbGF0b3I6OlNFQ09OREFSWTsKICAgIGJvb2xfdCBjaGVja1NlY1RlciA9IGluaXRpYWxDaGVja1NlY1RlcjsKICAgIGJvb2xfdCBjaGVja1RlcnRpYXJ5ID0gZ2V0U3RyZW5ndGgoKSA+PSBDb2xsYXRvcjo6VEVSVElBUlk7CiAgICBib29sX3QgaXNGcmVuY2hTZWMgPSBkYXRhLT5pc0ZyZW5jaFNlYzsKICAgIHVpbnQzMl90IHBTT3JkZXIsIHBUT3JkZXI7CgogICAgd2hpbGUoVFJVRSkKICAgIHsKICAgICAgICAvLyBHZXQgdGhlIG5leHQgY29sbGF0aW9uIGVsZW1lbnQgaW4gZWFjaCBvZiB0aGUgc3RyaW5ncywgdW5sZXNzCiAgICAgICAgLy8gd2UndmUgYmVlbiByZXF1ZXN0ZWQgdG8gc2tpcCBpdC4KICAgICAgICBpZiAoZ2V0cykKICAgICAgICB7CiAgICAgICAgICAgIHNPcmRlciA9IHNvdXJjZUN1cnNvci0+bmV4dChzdGF0dXMpOwoKICAgICAgICAgICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpFUVVBTDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZ2V0cyA9IFRSVUU7CgogICAgICAgIGlmIChnZXR0KQogICAgICAgIHsKICAgICAgICAgICAgdE9yZGVyID0gdGFyZ2V0Q3Vyc29yLT5uZXh0KHN0YXR1cyk7CgogICAgICAgICAgICBpZiAoRkFJTFVSRShzdGF0dXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGdldHQgPSBUUlVFOwoKICAgICAgICAvLyBJZiB3ZSd2ZSBoaXQgdGhlIGVuZCBvZiBvbmUgb2YgdGhlIHN0cmluZ3MsIGp1bXAgb3V0IG9mIHRoZSBsb29wCiAgICAgICAgaWYgKChzT3JkZXIgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpfHwKICAgICAgICAgICAgKHRPcmRlciA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUikpCiAgICAgICAgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gZGlmZmVyZW5jZSBhdCB0aGlzIHBvc2l0aW9uLCB3ZSBjYW4gc2tpcCB0byB0aGUKICAgICAgICAvLyBuZXh0IG9uZS4KICAgICAgICBwU09yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIoc09yZGVyKTsKICAgICAgICBwVE9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIodE9yZGVyKTsKICAgICAgICBpZiAoc09yZGVyID09IHRPcmRlcikKICAgICAgICB7CiAgICAgICAgICAgIGlmIChpc0ZyZW5jaFNlYyAmJiBwU09yZGVyICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghY2hlY2tTZWNUZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy8gaW4gZnJlbmNoLCBhIHNlY29uZGFyeSBkaWZmZXJlbmNlIG1vcmUgdG8gdGhlIHJpZ2h0IGlzIHN0cm9uZ2VyLAogICAgICAgICAgICAgICAgICAgIC8vIHNvIGFjY2VudHMgaGF2ZSB0byBiZSBjaGVja2VkIHdpdGggZWFjaCBiYXNlIGVsZW1lbnQKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IGluaXRpYWxDaGVja1NlY1RlcjsKCiAgICAgICAgICAgICAgICAgICAgLy8gYnV0IHRlcnRpYXJ5IGRpZmZlcmVuY2VzIGFyZSBsZXNzIGltcG9ydGFudCB0aGFuIHRoZSBmaXJzdCAKICAgICAgICAgICAgICAgICAgICAvLyBzZWNvbmRhcnkgZGlmZmVyZW5jZSwgc28gY2hlY2tpbmcgdGVydGlhcnkgcmVtYWlucyBkaXNhYmxlZAogICAgICAgICAgICAgICAgICAgIGNoZWNrVGVydGlhcnkgPSBGQUxTRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICAvLyBDb21wYXJlIHByaW1hcnkgZGlmZmVyZW5jZXMgZmlyc3QuCiAgICAgICAgaWYgKHBTT3JkZXIgIT0gcFRPcmRlcikKICAgICAgICB7CiAgICAgICAgICAgIGlmIChzT3JkZXIgPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gVGhlIGVudGlyZSBzb3VyY2UgZWxlbWVudCBpcyBpZ25vcmFibGUuCiAgICAgICAgICAgICAgICAvLyBTa2lwIHRvIHRoZSBuZXh0IHNvdXJjZSBlbGVtZW50LCBidXQgZG9uJ3QgZmV0Y2ggYW5vdGhlciB0YXJnZXQgZWxlbWVudC4KICAgICAgICAgICAgICAgIGdldHQgPSBGQUxTRTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodE9yZGVyID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGdldHMgPSBGQUxTRTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBUaGUgc291cmNlIGFuZCB0YXJnZXQgZWxlbWVudHMgYXJlbid0IGlnbm9yYWJsZSwgYnV0IGl0J3Mgc3RpbGwgcG9zc2libGUKICAgICAgICAgICAgLy8gZm9yIHRoZSBwcmltYXJ5IGNvbXBvbmVudCBvZiBvbmUgb2YgdGhlIGVsZW1lbnRzIHRvIGJlIGlnbm9yYWJsZS4uLi4KICAgICAgICAgICAgaWYgKHBTT3JkZXIgPT0gMCkgIC8vIHByaW1hcnkgb3JkZXIgaW4gc291cmNlIGlzIGlnbm9yYWJsZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBUaGUgc291cmNlJ3MgcHJpbWFyeSBpcyBpZ25vcmFibGUsIGJ1dCB0aGUgdGFyZ2V0J3MgaXNuJ3QuICBXZSB0cmVhdCBpZ25vcmFibGVzCiAgICAgICAgICAgICAgICAvLyBhcyBhIHNlY29uZGFyeSBkaWZmZXJlbmNlLCBzbyByZW1lbWJlciB0aGF0IHdlIGZvdW5kIG9uZS4KICAgICAgICAgICAgICAgIGlmIChjaGVja1NlY1RlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBDb2xsYXRvcjo6R1JFQVRFUjsgIC8vIChzdHJlbmd0aCBpcyBTRUNPTkRBUlkpCiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWNUZXIgPSBGQUxTRTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBTa2lwIHRvIHRoZSBuZXh0IHNvdXJjZSBlbGVtZW50LCBidXQgZG9uJ3QgZmV0Y2ggYW5vdGhlciB0YXJnZXQgZWxlbWVudC4KICAgICAgICAgICAgICAgIGdldHQgPSBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChwVE9yZGVyID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIHJlY29yZCBkaWZmZXJlbmNlcyAtIHNlZSB0aGUgY29tbWVudCBhYm92ZS4KICAgICAgICAgICAgICAgIGlmIChjaGVja1NlY1RlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBDb2xsYXRvcjo6TEVTUzsgIC8vIChzdHJlbmd0aCBpcyBTRUNPTkRBUlkpCiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWNUZXIgPSBGQUxTRTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBTa2lwIHRvIHRoZSBuZXh0IHRhcmdldCBlbGVtZW50LCBidXQgZG9uJ3QgZmV0Y2ggYW5vdGhlciBzb3VyY2UgZWxlbWVudC4KICAgICAgICAgICAgICAgIGdldHMgPSBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIE5laXRoZXIgb2YgdGhlIG9yZGVycyBpcyBpZ25vcmFibGUsIGFuZCB3ZSBhbHJlYWR5IGtub3cgdGhhdCB0aGUgcHJpbWFyeQogICAgICAgICAgICAgICAgLy8gb3JkZXJzIGFyZSBkaWZmZXJlbnQgYmVjYXVzZSBvZiB0aGUgKHBTT3JkZXIgIT0gcFRPcmRlcikgdGVzdCBhYm92ZS4KICAgICAgICAgICAgICAgIC8vIFJlY29yZCB0aGUgZGlmZmVyZW5jZSBhbmQgc3RvcCB0aGUgY29tcGFyaXNvbi4KICAgICAgICAgICAgICAgIGlmIChwU09yZGVyIDwgcFRPcmRlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkxFU1M7ICAvLyAoc3RyZW5ndGggaXMgUFJJTUFSWSkKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkdSRUFURVI7ICAvLyAoc3RyZW5ndGggaXMgUFJJTUFSWSkKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgeyAvLyBlbHNlIG9mIGlmICggcFNPcmRlciAhPSBwVE9yZGVyICkKICAgICAgICAgICAgLy8gcHJpbWFyeSBvcmRlciBpcyB0aGUgc2FtZSwgYnV0IGNvbXBsZXRlIG9yZGVyIGlzIGRpZmZlcmVudC4gU28gdGhlcmUKICAgICAgICAgICAgLy8gYXJlIG5vIGJhc2UgZWxlbWVudHMgYXQgdGhpcyBwb2ludCwgb25seSBpZ25vcmFibGVzIChTaW5jZSB0aGUgc3RyaW5ncyBhcmUKICAgICAgICAgICAgLy8gbm9ybWFsaXplZCkKCiAgICAgICAgICAgIGlmIChjaGVja1NlY1RlcikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gYSBzZWNvbmRhcnkgb3IgdGVydGlhcnkgZGlmZmVyZW5jZSBtYXkgc3RpbGwgbWF0dGVyCiAgICAgICAgICAgICAgICB1aW50MzJfdCBzZWNTT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKHNPcmRlcik7CiAgICAgICAgICAgICAgICB1aW50MzJfdCBzZWNUT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKHRPcmRlcik7CgogICAgICAgICAgICAgICAgaWYgKHNlY1NPcmRlciAhPSBzZWNUT3JkZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy8gdGhlcmUgaXMgYSBzZWNvbmRhcnkgZGlmZmVyZW5jZQogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IChzZWNTT3JkZXIgPCBzZWNUT3JkZXIpID8gQ29sbGF0b3I6OkxFU1MgOiBDb2xsYXRvcjo6R1JFQVRFUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAoc3RyZW5ndGggaXMgU0VDT05EQVJZKQogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gRkFMU0U7IAogICAgICAgICAgICAgICAgICAgIC8vIChldmVuIGluIGZyZW5jaCwgb25seSB0aGUgZmlyc3Qgc2Vjb25kYXJ5IGRpZmZlcmVuY2Ugd2l0aGluCiAgICAgICAgICAgICAgICAgICAgLy8gIGEgYmFzZSBjaGFyYWN0ZXIgbWF0dGVycykKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY2hlY2tUZXJ0aWFyeSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGEgdGVydGlhcnkgZGlmZmVyZW5jZSBtYXkgc3RpbGwgbWF0dGVyCiAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHRlclNPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6dGVydGlhcnlPcmRlcihzT3JkZXIpOwogICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCB0ZXJUT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnRlcnRpYXJ5T3JkZXIodE9yZGVyKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZXJTT3JkZXIgIT0gdGVyVE9yZGVyKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZSBpcyBhIHRlcnRpYXJ5IGRpZmZlcmVuY2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9ICh0ZXJTT3JkZXIgPCB0ZXJUT3JkZXIpID8gQ29sbGF0b3I6OkxFU1MgOiBDb2xsYXRvcjo6R1JFQVRFUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAoc3RyZW5ndGggaXMgVEVSVElBUlkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja1RlcnRpYXJ5ID0gRkFMU0U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gLy8gaWYgKGNoZWNrU2VjVGVyKQoKICAgICAgICB9ICAvLyBpZiAoIHBTT3JkZXIgIT0gcFRPcmRlciApCiAgICB9IC8vIHdoaWxlKCkKCiAgICBpZiAoc09yZGVyICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIC8vICh0T3JkZXIgbXVzdCBiZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUiwKICAgICAgICAvLyAgc2luY2UgdGhpcyBwb2ludCBpcyBvbmx5IHJlYWNoZWQgd2hlbiBzT3JkZXIgb3IgdE9yZGVyIGlzIE5VTExPUkRFUi4pCiAgICAgICAgLy8gVGhlIHNvdXJjZSBzdHJpbmcgaGFzIG1vcmUgZWxlbWVudHMsIGJ1dCB0aGUgdGFyZ2V0IHN0cmluZyBoYXNuJ3QuCiAgICAgICAgZG8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByaW1hcnlPcmRlcihzT3JkZXIpICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFdlIGZvdW5kIGFuIGFkZGl0aW9uYWwgbm9uLWlnbm9yYWJsZSBiYXNlIGNoYXJhY3RlciBpbiB0aGUgc291cmNlIHN0cmluZy4KICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBwcmltYXJ5IGRpZmZlcmVuY2UsIHNvIHRoZSBzb3VyY2UgaXMgZ3JlYXRlcgogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpHUkVBVEVSOyAvLyAoc3RyZW5ndGggaXMgUFJJTUFSWSkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIoc09yZGVyKSAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBBZGRpdGlvbmFsIHNlY29uZGFyeSBlbGVtZW50cyBtZWFuIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGdyZWF0ZXIKICAgICAgICAgICAgICAgIGlmIChjaGVja1NlY1RlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBDb2xsYXRvcjo6R1JFQVRFUjsgIC8vIChzdHJlbmd0aCBpcyBTRUNPTkRBUlkpCiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWNUZXIgPSBGQUxTRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSAKICAgICAgICB9CiAgICAgICAgd2hpbGUgKChzT3JkZXIgPSBzb3VyY2VDdXJzb3ItPm5leHQoc3RhdHVzKSkgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpOwogICAgfQogICAgZWxzZSBpZiAodE9yZGVyICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIC8vIFRoZSB0YXJnZXQgc3RyaW5nIGhhcyBtb3JlIGVsZW1lbnRzLCBidXQgdGhlIHNvdXJjZSBzdHJpbmcgaGFzbid0LgogICAgICAgIGRvCiAgICAgICAgewogICAgICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIodE9yZGVyKSAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBXZSBmb3VuZCBhbiBhZGRpdGlvbmFsIG5vbi1pZ25vcmFibGUgYmFzZSBjaGFyYWN0ZXIgaW4gdGhlIHRhcmdldCBzdHJpbmcuCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgcHJpbWFyeSBkaWZmZXJlbmNlLCBzbyB0aGUgc291cmNlIGlzIGxlc3MKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6TEVTUzsgLy8gKHN0cmVuZ3RoIGlzIFBSSU1BUlkpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKHRPcmRlcikgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gQWRkaXRpb25hbCBzZWNvbmRhcnkgZWxlbWVudHMgaW4gdGhlIHRhcmdldCBtZWFuIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGxlc3MKICAgICAgICAgICAgICAgIGlmIChjaGVja1NlY1RlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBDb2xsYXRvcjo6TEVTUzsgIC8vIChzdHJlbmd0aCBpcyBTRUNPTkRBUlkpCiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWNUZXIgPSBGQUxTRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSAKICAgICAgICB9CiAgICAgICAgd2hpbGUgKCh0T3JkZXIgPSB0YXJnZXRDdXJzb3ItPm5leHQoc3RhdHVzKSkgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpOwogICAgfQoKCiAgICAvLyBGb3IgSURFTlRJQ0FMIGNvbXBhcmlzb25zLCB3ZSB1c2UgYSBiaXR3aXNlIGNoYXJhY3RlciBjb21wYXJpc29uCiAgICAvLyBhcyBhIHRpZWJyZWFrZXIgaWYgYWxsIGVsc2UgaXMgZXF1YWwKICAgIC8vIE5PVEU6IFRoZSBqYXZhIGNvZGUgY29tcGFyZXMgcmVzdWx0IHdpdGggMCwgYW5kIAogICAgLy8gcHV0cyB0aGUgcmVzdWx0IG9mIHRoZSBzdHJpbmcgY29tcGFyaXNvbiBkaXJlY3RseSBpbnRvIHJlc3VsdAogICAgaWYgKHJlc3VsdCA9PSBDb2xsYXRvcjo6RVFVQUwgJiYgZ2V0U3RyZW5ndGgoKSA9PSBJREVOVElDQUwpCiAgICB7CiAgICAgICAgVW5pY29kZVN0cmluZyBzb3VyY2VEZWNvbXAsIHRhcmdldERlY29tcDsKICAgICAgICBpbnQ4X3QgY29tcGFyaXNvbjsKICAgICAgICAKICAgICAgICBOb3JtYWxpemVyOjpub3JtYWxpemUoc291cmNlLCBnZXREZWNvbXBvc2l0aW9uKCksIAogICAgICAgICAgICAgICAgICAgICAgMCwgc291cmNlRGVjb21wLCBzdGF0dXMpOwogICAgICAgIE5vcm1hbGl6ZXI6Om5vcm1hbGl6ZSh0YXJnZXQsIGdldERlY29tcG9zaXRpb24oKSwgCiAgICAgICAgICAgICAgICAgICAgICAwLCB0YXJnZXREZWNvbXAsIHN0YXR1cyk7CiAgICAgICAgCiAgICAgICAgY29tcGFyaXNvbiA9IHNvdXJjZURlY29tcC5jb21wYXJlKHRhcmdldERlY29tcCk7CgogICAgICAgIGlmIChjb21wYXJpc29uIDwgMCkKICAgICAgICB7CiAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpMRVNTOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChjb21wYXJpc29uID09IDApCiAgICAgICAgewogICAgICAgICAgICByZXN1bHQgPSBDb2xsYXRvcjo6RVFVQUw7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpHUkVBVEVSOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9CgovLyBSZXRyaWV2ZSBhIGNvbGxhdGlvbiBrZXkgZm9yIHRoZSBzcGVjaWZpZWQgc3RyaW5nCi8vIFRoZSBrZXkgY2FuIGJlIGNvbXBhcmVkIHdpdGggb3RoZXIgY29sbGF0aW9uIGtleXMgdXNpbmcgYSBiaXR3aXNlIGNvbXBhcmlzb24KLy8gKGUuZy4gbWVtY21wKSB0byBmaW5kIHRoZSBvcmRlcmluZyBvZiB0aGVpciByZXNwZWN0aXZlIHNvdXJjZSBzdHJpbmdzLgovLyBUaGlzIGlzIGhhbmR5IHdoZW4gZG9pbmcgYSBzb3J0LCB3aGVyZSBlYWNoIHNvcnQga2V5IG11c3QgYmUgY29tcGFyZWQKLy8gbWFueSB0aW1lcy4KLy8KLy8gVGhlIGJhc2ljIGFsZ29yaXRobSBoZXJlIGlzIHRvIGZpbmQgYWxsIG9mIHRoZSBjb2xsYXRpb24gZWxlbWVudHMgZm9yIGVhY2gKLy8gY2hhcmFjdGVyIGluIHRoZSBzb3VyY2Ugc3RyaW5nLCBjb252ZXJ0IHRoZW0gdG8gYW4gQVNDSUkgcmVwcmVzZW50YXRpb24sCi8vIGFuZCBwdXQgdGhlbSBpbnRvIHRoZSBjb2xsYXRpb24ga2V5LiAgQnV0IGl0J3MgdHJpY2tpZXIgdGhhbiB0aGF0LgovLyBFYWNoIGNvbGxhdGlvbiBlbGVtZW50IGluIGEgc3RyaW5nIGhhcyB0aHJlZSBjb21wb25lbnRzOiBwcmltYXJ5ICgnQScgdnMgJ0InKSwKLy8gc2Vjb25kYXJ5ICgndScgdnMgJ/wnKSwgYW5kIHRlcnRpYXJ5ICgnQScgdnMgJ2EnKSwgYW5kIGEgcHJpbWFyeSBkaWZmZXJlbmNlCi8vIGF0IHRoZSBlbmQgb2YgYSBzdHJpbmcgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIGEgc2Vjb25kYXJ5IG9yIHRlcnRpYXJ5Ci8vIGRpZmZlcmVuY2UgZWFybGllciBpbiB0aGUgc3RyaW5nLgovLwovLyBUbyBhY2NvdW50IGZvciB0aGlzLCB3ZSBwdXQgYWxsIG9mIHRoZSBwcmltYXJ5IG9yZGVycyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZQovLyBzdHJpbmcsIGZvbGxvd2VkIGJ5IHRoZSBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IG9yZGVycy4gRWFjaCBzZXQgb2Ygb3JkZXJzIGlzCi8vIHRlcm1pbmF0ZWQgYnkgbnVsbHMgc28gdGhhdCBhIGtleSBmb3IgYSBzdHJpbmcgd2hpY2ggaXMgYSBpbml0aWFsIHN1YnN0cmluZyBvZgovLyBhbm90aGVyIGtleSB3aWxsIGNvbXBhcmUgbGVzcyB3aXRob3V0IGFueSBzcGVjaWFsIGNhc2UuCi8vCi8vIEhlcmUncyBhIGh5cG90aGV0aWNhbCBleGFtcGxlLCB3aXRoIHRoZSBjb2xsYXRpb24gZWxlbWVudCByZXByZXNlbnRlZCBhcwovLyBhIHRocmVlLWRpZ2l0IG51bWJlciwgb25lIGRpZ2l0IGZvciBwcmltYXJ5LCBvbmUgZm9yIHNlY29uZGFyeSwgZXRjLgovLwovLyBTdHJpbmc6ICAgICAgICAgICAgICBBICAgICBhICAgICBCICAgIMkKLy8gQ29sbGF0aW9uIEVsZW1lbnRzOiAxMDEgICAxMDAgICAyMDEgIDUxMQovLyBDb2xsYXRpb24gS2V5OiAgICAgIDExMjU8bnVsbD4wMDAxPG51bGw+MTAxMTxudWxsPgovLwovLyBUbyBtYWtlIHRoaW5ncyBldmVuIHRyaWNraWVyLCBzZWNvbmRhcnkgZGlmZmVyZW5jZXMgKGFjY2VudCBtYXJrcykgYXJlIGNvbXBhcmVkCi8vIHN0YXJ0aW5nIGF0IHRoZSAqZW5kKiBvZiB0aGUgc3RyaW5nIGluIGxhbmd1YWdlcyB3aXRoIEZyZW5jaCBzZWNvbmRhcnkgb3JkZXJpbmcuCi8vIEJ1dCB3aGVuIGNvbXBhcmluZyB0aGUgYWNjZW50IG1hcmtzIG9uIGEgc2luZ2xlIGJhc2UgY2hhcmFjdGVyLCB0aGV5IGFyZSBjb21wYXJlZAovLyBmcm9tIHRoZSBiZWdpbm5pbmcuICBUbyBoYW5kbGUgdGhpcywgd2UgcmV2ZXJzZSBhbGwgb2YgdGhlIGFjY2VudHMgdGhhdCBiZWxvbmcKLy8gdG8gZWFjaCBiYXNlIGNoYXJhY3RlciwgdGhlbiB3ZSByZXZlcnNlIHRoZSBlbnRpcmUgc3RyaW5nIG9mIHNlY29uZGFyeSBvcmRlcmluZ3MKLy8gYXQgdGhlIGVuZC4KLy8KQ29sbGF0aW9uS2V5JgpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29sbGF0aW9uS2V5KCBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYgICBzb3J0a2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykgY29uc3QKewogICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBJTExFR0FMX0FSR1VNRU5UX0VSUk9SOwogICAgICAgIHJldHVybiBzb3J0a2V5LnNldFRvQm9ndXMoKTsKICAgIH0KICAgIAogICAgaWYgKHNvdXJjZS5pc0JvZ3VzKCkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgcmV0dXJuIHNvcnRrZXkuc2V0VG9Cb2d1cygpOwogICAgfQoKICAgIGlmIChzb3VyY2Uuc2l6ZSgpID09IDApCiAgICB7CiAgICAgICAgcmV0dXJuIHNvcnRrZXkucmVzZXQoKTsKICAgIH0KCiAgICBpZiAoc291cmNlQ3Vyc29yID09IE5VTEwpCiAgICB7CiAgICAgICAgKChSdWxlQmFzZWRDb2xsYXRvciAqKXRoaXMpLT5zb3VyY2VDdXJzb3IgPSBjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Ioc291cmNlKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzb3VyY2VDdXJzb3ItPnNldFRleHQoc291cmNlLCBzdGF0dXMpOwogICAgfQoKICAgIGlmIChzb3VyY2VDdXJzb3IgPT0gTlVMTCB8fCBGQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIHNvcnRrZXkuc2V0VG9Cb2d1cygpOwogICAgfQoKICAgIGJvb2xfdCAgY29tcGFyZVNlYyAgID0gKGdldFN0cmVuZ3RoKCkgPj0gQ29sbGF0b3I6OlNFQ09OREFSWSk7CiAgICBib29sX3QgIGNvbXBhcmVUZXIgICA9IChnZXRTdHJlbmd0aCgpID49IENvbGxhdG9yOjpURVJUSUFSWSk7CiAgICBib29sX3QgIGNvbXBhcmVJZGVudCA9IChnZXRTdHJlbmd0aCgpID09IENvbGxhdG9yOjpJREVOVElDQUwpOwogICAgaW50MzJfdCBvcmRlciAgICAgICAgPSAwOwogICAgaW50MzJfdCB0b3RhbFByaW1hcnkgPSAwOwogICAgaW50MzJfdCB0b3RhbFNlYyAgICAgPSAwOwogICAgaW50MzJfdCB0b3RhbFRlciAgICAgPSAwOwogICAgaW50MzJfdCB0b3RhbElkZW50ICAgICA9IDA7CiAgICBVbmljb2RlU3RyaW5nIGRlY29tcDsKCiAgICAvLyBpdGVyYXRlIG92ZXIgdGhlIHNvdXJjZSwgY291bnRpbmcgcHJpbWFyeSwgc2Vjb25kYXJ5LCBhbmQgdGVydGlhcnkgZW50cmllcwogICAgd2hpbGUoKG9yZGVyID0gc291cmNlQ3Vyc29yLT5uZXh0KHN0YXR1cykpICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIGludDMyX3Qgc2VjT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKG9yZGVyKTsKICAgICAgICBpbnQzMl90IHRlck9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp0ZXJ0aWFyeU9yZGVyKG9yZGVyKTsKCiAgICAgICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBzb3J0a2V5LnNldFRvQm9ndXMoKTsKICAgICAgICB9CgogICAgICAgIGlmICghIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6aXNJZ25vcmFibGUob3JkZXIpKQogICAgICAgIHsKICAgICAgICAgICAgdG90YWxQcmltYXJ5ICs9IDE7CgogICAgICAgICAgICBpZiAoY29tcGFyZVNlYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG90YWxTZWMgKz0gMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNvbXBhcmVUZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRvdGFsVGVyICs9IDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGNvbXBhcmVTZWMgJiYgc2VjT3JkZXIgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG90YWxTZWMgKz0gMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNvbXBhcmVUZXIgJiYgdGVyT3JkZXIgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG90YWxUZXIgKz0gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvLyBjb3VudCB0aGUgbnVsbCBieXRlcyBhZnRlciB0aGUgZW50aXJlcwogICAgdG90YWxQcmltYXJ5ICs9IDE7CgogICAgaWYgKGNvbXBhcmVTZWMpCiAgICB7CiAgICAgICAgdG90YWxTZWMgKz0gMTsKICAgIH0KCiAgICBpZiAoY29tcGFyZVRlcikKICAgIHsKICAgICAgICB0b3RhbFRlciArPSAxOwogICAgfQoKICAgIGlmIChjb21wYXJlSWRlbnQpCiAgICB7CiAgICAgIE5vcm1hbGl6ZXI6Om5vcm1hbGl6ZShzb3VyY2UsIGdldERlY29tcG9zaXRpb24oKSwKICAgICAgICAgICAgICAgIDAsIGRlY29tcCwgc3RhdHVzKTsKCiAgICAgICAgaWYgKFNVQ0NFU1Moc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHRvdGFsSWRlbnQgPSBkZWNvbXAuc2l6ZSgpICsgMTsKICAgICAgICB9CiAgICB9CgogICAgLy8gQ29tcHV0ZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgdG8gaG9sZCB0aGUgZW50cmllcwogICAgLy8gYW5kIG1ha2Ugc3VyZSB0aGUga2V5IGNhbiBob2xkIHRoZW0KICAgIHVpbnQzMl90IHNpemUgICA9IDIgKiAodG90YWxQcmltYXJ5ICsgdG90YWxTZWMgKyB0b3RhbFRlciArIHRvdGFsSWRlbnQpOwoKICAgIHNvcnRrZXkuZW5zdXJlQ2FwYWNpdHkoc2l6ZSk7CgogICAgaWYgKHNvcnRrZXkuaXNCb2d1cygpKQogICAgewogICAgICAgIHN0YXR1cyA9IE1FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybiBzb3J0a2V5OwogICAgfQoKICAgIGludDMyX3QgcHJpbWFyeUN1cnNvciA9IDA7CiAgICBpbnQzMl90IHNlY0N1cnNvciAgICAgPSAyICogdG90YWxQcmltYXJ5OwogICAgaW50MzJfdCBzZWNCYXNlICAgICAgID0gc2VjQ3Vyc29yOwogICAgaW50MzJfdCBwcmVTZWNJZ25vcmUgID0gc2VjQmFzZTsKICAgIGludDMyX3QgdGVyQ3Vyc29yICAgICA9IHNlY0N1cnNvciArICgyICogdG90YWxTZWMpOwogICAgaW50MzJfdCBpZGVudEN1cnNvciAgICAgID0gdGVyQ3Vyc29yICsgKDIgKiB0b3RhbFRlcik7CgogICAgLy8gcmVzZXQgc291cmNlIHRvIHRoZSBiZWdpbm5pbmcKICAgIHNvdXJjZUN1cnNvci0+cmVzZXQoKTsKCiAgICAvLyBub3cgaXRlcmF0ZSBvdmVyIHRoZSBzb3VyY2UgY29tcHV0aW5nIHRoZSBhY3R1YWwgZW50cmllcwogICAgd2hpbGUoKG9yZGVyID0gc291cmNlQ3Vyc29yLT5uZXh0KHN0YXR1cykpICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIGlmIChGQUlMVVJFKHN0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc29ydGtleS5yZXNldCgpOwogICAgICAgIH0KCiAgICAgICAgaW50MzJfdCBwcmltYXJ5T3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByaW1hcnlPcmRlcihvcmRlcik7CiAgICAgICAgaW50MzJfdCBzZWNPcmRlciAgICAgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKG9yZGVyKTsKICAgICAgICBpbnQzMl90IHRlck9yZGVyICAgICA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6dGVydGlhcnlPcmRlcihvcmRlcik7CgogICAgICAgIGlmICghIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6aXNJZ25vcmFibGUob3JkZXIpKQogICAgICAgIHsKICAgICAgICAgICAgcHJpbWFyeUN1cnNvciA9IHNvcnRrZXkuc3RvcmVCeXRlcyhwcmltYXJ5Q3Vyc29yLCBwcmltYXJ5T3JkZXIgKyBTT1JUS0VZT0ZGU0VUKTsKCiAgICAgICAgICAgIGlmIChjb21wYXJlU2VjKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZGF0YS0+aXNGcmVuY2hTZWMgJiYgKHByZVNlY0lnbm9yZSA8IHNlY0N1cnNvcikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc29ydGtleS5yZXZlcnNlQnl0ZXMocHJlU2VjSWdub3JlLCBzZWNDdXJzb3IpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHNlY0N1cnNvciA9IHNvcnRrZXkuc3RvcmVCeXRlcyhzZWNDdXJzb3IsIHNlY09yZGVyICsgU09SVEtFWU9GRlNFVCk7CgogICAgICAgICAgICAgICAgcHJlU2VjSWdub3JlID0gc2VjQ3Vyc29yOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29tcGFyZVRlcikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGVyQ3Vyc29yID0gc29ydGtleS5zdG9yZUJ5dGVzKHRlckN1cnNvciwgdGVyT3JkZXIgKyBTT1JUS0VZT0ZGU0VUKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBpZiAoY29tcGFyZVNlYyAmJiBzZWNPcmRlciAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzZWNDdXJzb3IgPSBzb3J0a2V5LnN0b3JlQnl0ZXMoc2VjQ3Vyc29yLCBzZWNPcmRlciArIGRhdGEtPm1heFNlY09yZGVyICsgU09SVEtFWU9GRlNFVCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb21wYXJlVGVyICYmIHRlck9yZGVyICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRlckN1cnNvciA9IHNvcnRrZXkuc3RvcmVCeXRlcyh0ZXJDdXJzb3IsIHRlck9yZGVyICsgZGF0YS0+bWF4VGVyT3JkZXIgKyBTT1JUS0VZT0ZGU0VUKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvLyBhcHBlbmQgMCBhdCB0aGUgZW5kIG9mIGVhY2ggcG9ydGlvbi4KICAgIHNvcnRrZXkuc3RvcmVCeXRlcyhwcmltYXJ5Q3Vyc29yLCAwKTsKCiAgICBpZiAoY29tcGFyZVNlYykKICAgIHsKICAgICAgICBpZiAoZGF0YS0+aXNGcmVuY2hTZWMpCiAgICAgICAgewogICAgICAgICAgICBpZiAocHJlU2VjSWdub3JlIDwgc2VjQ3Vyc29yKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzb3J0a2V5LnJldmVyc2VCeXRlcyhwcmVTZWNJZ25vcmUsIHNlY0N1cnNvcik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNvcnRrZXkucmV2ZXJzZUJ5dGVzKHNlY0Jhc2UsIHNlY0N1cnNvcik7CiAgICAgICAgfQoKICAgICAgICBzb3J0a2V5LnN0b3JlQnl0ZXMoc2VjQ3Vyc29yLCAwKTsKICAgIH0KCiAgICBpZiAoY29tcGFyZVRlcikKICAgIHsKICAgICAgICBzb3J0a2V5LnN0b3JlQnl0ZXModGVyQ3Vyc29yLCAwKTsKICAgIH0KCiAgICBpZiAoY29tcGFyZUlkZW50KQogICAgewogICAgICAgIHNvcnRrZXkuc3RvcmVVbmljb2RlU3RyaW5nKGlkZW50Q3Vyc29yLCBkZWNvbXApOwogICAgfQoKICAgIHJldHVybiBzb3J0a2V5Owp9CgoKLy8gQnVpbGQgdGhpcyBjb2xsYXRvcidzIHJ1bGUgdGFibGVzIGJhc2VkIG9uIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBydWxlcwovLyBTZWUgdGhlIGJpZyBkaWFncmFtIGF0IHRoZSB0b3Agb2YgdGhpcyBmaWxlIGZvciBhbiBvdmVydmlldyBvZiBob3cgdGhlIHRhYmxlcwovLyBhcmUgb3JnYW5pemVkLgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpidWlsZChjb25zdCBVbmljb2RlU3RyaW5nJiAgIHBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykKewogICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gVGhpcyBhcnJheSBtYXBzIFVuaWNvZGUgY2hhcmFjdGVycyB0byB0aGVpciBjb2xsYXRpb24gb3JkZXJpbmcKICAgIGRhdGEtPm1hcHBpbmcgPSB1Y21wMzJfb3BlbihVTk1BUFBFRCk7CgogICAgaWYgKGRhdGEtPm1hcHBpbmctPmZCb2d1cykKICAgIHsKICAgICAgICBzdGF0dXMgPSBNRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgQ29sbGF0b3I6OkVDb2xsYXRpb25TdHJlbmd0aCBhU3RyZW5ndGggPSBDb2xsYXRvcjo6SURFTlRJQ0FMOwogICAgYm9vbF90IGlzU291cmNlID0gVFJVRTsKICAgIGludDMyX3QgaSA9IDA7CiAgICBVbmljb2RlU3RyaW5nIGxhc3RHcm91cENoYXJzOwogICAgVW5pY29kZVN0cmluZyBleHBDaGFyczsKICAgIFVuaWNvZGVTdHJpbmcgZ3JvdXBDaGFyczsKCiAgICBpZiAocGF0dGVybi5zaXplKCkgPT0gMCkKICAgIHsKICAgICAgICBzdGF0dXMgPSBJTlZBTElEX0ZPUk1BVF9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gQnVpbGQgdGhlIG1lcmdlZCBjb2xsYXRpb24gZW50cmllcwogICAgLy8gU2luY2UgcnVsZXMgY2FuIGJlIHNwZWNpZmllZCBpbiBhbnkgb3JkZXIgaW4gdGhlIHN0cmluZwogICAgLy8gKGUuZy4gImMgLCBDIDwgZCAsIEQgPCBlICwgRSAuLi4uIEMgPCBDSCIpCiAgICAvLyB0aGlzIHNwbGl0cyBhbGwgb2YgdGhlIHJ1bGVzIGluIHRoZSBzdHJpbmcgb3V0IGludG8gc2VwYXJhdGUKICAgIC8vIG9iamVjdHMgYW5kIHRoZW4gc29ydHMgdGhlbS4gIEluIHRoZSBhYm92ZSBleGFtcGxlLCBpdCBtZXJnZXMgdGhlCiAgICAvLyAiQyA8IENIIiBydWxlIGluIGp1c3QgYmVmb3JlIHRoZSAiQyA8IEQiIHJ1bGUuCgogICAgbVBhdHRlcm4gPSBuZXcgTWVyZ2VDb2xsYXRpb24ocGF0dGVybiwgZ2V0RGVjb21wb3NpdGlvbigpLCBzdGF0dXMpOwogICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICB1Y21wMzJfY2xvc2UoZGF0YS0+bWFwcGluZyk7CiAgICAgICAgZGF0YS0+bWFwcGluZyA9IDA7CiAgICAgICAgZGVsZXRlIG1QYXR0ZXJuOwogICAgICAgIG1QYXR0ZXJuID0gMDsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaW50MzJfdCBvcmRlciA9IDA7CgogICAgLy8gV2FsayB0aHJvdWdoIGVhY2ggZW50cnkKICAgIGZvciAoaSA9IDA7IGkgPCBtUGF0dGVybi0+Z2V0Q291bnQoKTsgKytpKQogICAgewogICAgICAgIGNvbnN0IFBhdHRlcm5FbnRyeSogZW50cnkgPSBtUGF0dGVybi0+Z2V0SXRlbUF0KGkpOwogICAgICAgIGdyb3VwQ2hhcnMucmVtb3ZlKCk7CiAgICAgICAgZXhwQ2hhcnMucmVtb3ZlKCk7CgogICAgICAgIC8vIGlmIGVudHJ5IGlzIHZhbGlkCiAgICAgICAgaWYgKGVudHJ5ICE9IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICBlbnRyeS0+Z2V0Q2hhcnMoZ3JvdXBDaGFycyk7CgogICAgICAgICAgICAvLyBjaGVjayBpZiBmcmVuY2ggc2Vjb25kYXJ5IG5lZWRzIHRvIGJlIHR1cm5lZCBvbgogICAgICAgICAgICBpZiAoKGdyb3VwQ2hhcnMuc2l6ZSgpID4gMSkgJiYKICAgICAgICAgICAgICAgIChncm91cENoYXJzW2dyb3VwQ2hhcnMuc2l6ZSgpLShUX0lOVDMyKDEpKV0gPT0gJ0AnKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGF0YS0+aXNGcmVuY2hTZWMgPSBUUlVFOwogICAgICAgICAgICAgICAgZ3JvdXBDaGFycy5yZW1vdmUoZ3JvdXBDaGFycy5zaXplKCktKFRfSU5UMzIoMSkpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgb3JkZXIgPSBpbmNyZW1lbnQoKENvbGxhdG9yOjpFQ29sbGF0aW9uU3RyZW5ndGgpZW50cnktPmdldFN0cmVuZ3RoKCksIG9yZGVyKTsKCiAgICAgICAgICAgIGlmIChlbnRyeS0+Z2V0RXh0ZW5zaW9uKGV4cENoYXJzKS5zaXplKCkgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gZW5jb3VudGVyZWQgYW4gZXhwYW5kaW5nIGNoYXJhY3Rlciwgd2hlcmUgb25lIGNoYXJhY3RlciBvbiBpbnB1dAogICAgICAgICAgICAgICAgLy8gZXhwYW5kcyB0byBzZXZlcmFsIHNvcnQgZWxlbWVudHMgKGUuZy4gJ/YnIC0tPiAnbycgJ2UnKQogICAgICAgICAgICAgICAgYWRkRXhwYW5kT3JkZXIoZ3JvdXBDaGFycywgZXhwQ2hhcnMsIG9yZGVyLCBzdGF0dXMpOwogICAgICAgICAgICAgICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoZ3JvdXBDaGFycy5zaXplKCkgPiAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBlbmNvdW50ZXJlZCBhIGNvbnRyYWN0aW5nIGNoYXJhY3Rlciwgd2hlcmUgc2V2ZXJhbCBjaGFyYWN0ZXJzIG9uIGlucHV0CiAgICAgICAgICAgICAgICAvLyBjb250cmFjdCBpbnRvIG9uZSBzb3J0IG9yZGVyLiAgRm9yIGV4YW1wbGUsICJjaCIgaXMgdHJlYXRlZCBhcyBhIHNpbmdsZQogICAgICAgICAgICAgICAgLy8gY2hhcmFjdGVyIGluIHRyYWRpdGlvbmFsIFNwYW5pc2ggc29ydGluZy4KICAgICAgICAgICAgICAgIGFkZENvbnRyYWN0T3JkZXIoZ3JvdXBDaGFycywgb3JkZXIsIHN0YXR1cyk7CiAgICAgICAgICAgICAgICBpZiAoRkFJTFVSRShzdGF0dXMpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIE5vdGhpbmcgb3V0IG9mIHRoZSBvcmRpbmFyeSAtLSBvbmUgY2hhcmFjdGVyIG1hcHMgdG8gb25lIHNvcnQgb3JkZXIKICAgICAgICAgICAgICAgIGFkZE9yZGVyKGdyb3VwQ2hhcnNbMF0sIG9yZGVyLCBzdGF0dXMpOwogICAgICAgICAgICAgICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gYWRkIGV4cGFuZGluZyBlbnRyaWVzIGZvciBwcmUtY29tcG9zZWQgY2hhcmFjdGVycwogICAgYWRkQ29tcG9zZWRDaGFycygpOwoKICAgIC8vIEZpbGwgaW4gYWxsIHRoZSBleHBhbmRpbmcgY2hhcnMgdmFsdWVzCiAgICBjb21taXQoKTsKCiAgICAvLyBDb21wYWN0IHRoZSBkYXRhIG1hcHBpbmcgdGFibGUKICAgIHVjbXAzMl9jb21wYWN0KGRhdGEtPm1hcHBpbmcsIDEpOwp9CgovKioKICogQWRkIGV4cGFuZGluZyBlbnRyaWVzIGZvciBwcmUtY29tcG9zZWQgdW5pY29kZSBjaGFyYWN0ZXJzIHNvIHRoYXQgdGhpcwogKiBjb2xsYXRvciBjYW4gYmUgdXNlZCByZWFzb25hYmx5IHdlbGwgd2l0aCBkZWNvbXBvc2l0aW9uIHR1cm5lZCBvZmYuCiAqLwogdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6YWRkQ29tcG9zZWRDaGFycygpCiB7CiAgICBVbmljb2RlU3RyaW5nIGJ1ZjsKICAgIFVFcnJvckNvZGUgc3RhdHVzID0gWkVST19FUlJPUjsKCiAgICAvLyBJdGVyYXRlIHRocm91Z2ggYWxsIG9mIHRoZSBwcmUtY29tcG9zZWQgY2hhcmFjdGVycyBpbiBVbmljb2RlCiAgICBDb21wb3NlZENoYXJJdGVyIGl0ZXI7CiAgICBVbmljb2RlU3RyaW5nIGRlY29tcDsKCiAgICB3aGlsZSAoaXRlci5oYXNOZXh0KCkpCiAgICB7CiAgICAgICAgVUNoYXIgYyA9IGl0ZXIubmV4dCgpOwogICAgICAgIAogICAgICAgIGlmIChnZXRDaGFyT3JkZXIoYykgPT0gVU5NQVBQRUQpCiAgICAgICAgewogICAgICAgICAgICAvLyAKICAgICAgICAgICAgLy8gV2UgZG9uJ3QgYWxyZWFkeSBoYXZlIGFuIG9yZGVyaW5nIGZvciB0aGlzIHByZS1jb21wb3NlZCBjaGFyYWN0ZXIuCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIEZpcnN0LCBzZWUgaWYgdGhlIGRlY29tcG9zZWQgc3RyaW5nIGlzIGFscmVhZHkgaW4gb3VyCiAgICAgICAgICAgIC8vIHRhYmxlcyBhcyBhIHNpbmdsZSBjb250cmFjdGluZy1zdHJpbmcgb3JkZXJpbmcuCiAgICAgICAgICAgIC8vIElmIHNvLCBqdXN0IG1hcCB0aGUgcHJlY29tcG9zZWQgY2hhcmFjdGVyIHRvIHRoYXQgb3JkZXIuCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIFRPRE86IFdoYXQgd2Ugc2hvdWxkIHJlYWxseSBiZSBkb2luZyBoZXJlIGlzIHRyeWluZyB0byBmaW5kIHRoZQogICAgICAgICAgICAvLyBsb25nZXN0IGluaXRpYWwgc3Vic3RyaW5nIG9mIHRoZSBkZWNvbXBvc2l0aW9uIHRoYXQgaXMgcHJlc2VudAogICAgICAgICAgICAvLyBpbiB0aGUgdGFibGVzIGFzIGEgY29udHJhY3RpbmcgY2hhcmFjdGVyIHNlcXVlbmNlLCBhbmQgZmluZCBpdHMKICAgICAgICAgICAgLy8gb3JkZXJpbmcuICBUaGVuIGRvIHRoaXMgcmVjdXJzaXZlbHkgd2l0aCB0aGUgcmVtYWluaW5nIGNoYXJzCiAgICAgICAgICAgIC8vIHNvIHRoYXQgd2UgYnVpbGQgYSBsaXN0IG9mIG9yZGVyaW5ncywgYW5kIGFkZCB0aGF0IGxpc3QgdG8KICAgICAgICAgICAgLy8gdGhlIGV4cGFuc2lvbiB0YWJsZS4gCiAgICAgICAgICAgIC8vIFRoYXQgd291bGQgYmUgbW9yZSBjb3JyZWN0IGJ1dCBhbHNvIHNpZ25pZmljYW50bHkgc2xvd2VyLCBzbwogICAgICAgICAgICAvLyBJJ20gbm90IHRvdGFsbHkgc3VyZSBpdCdzIHdvcnRoIGRvaW5nLgogICAgICAgICAgICAvLwogICAgICAgICAgICBpdGVyLmdldERlY29tcG9zaXRpb24oZGVjb21wKTsKICAgICAgICAgICAgaW50IGNvbnRyYWN0T3JkZXIgPSBnZXRDb250cmFjdE9yZGVyKGRlY29tcCk7CgogICAgICAgICAgICBpZiAoY29udHJhY3RPcmRlciAhPSBVTk1BUFBFRCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYWRkT3JkZXIoYywgY29udHJhY3RPcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAvLyBXZSBkb24ndCBoYXZlIGEgY29udHJhY3Rpbmcgb3JkZXJpbmcgZm9yIHRoZSBlbnRpcmUgc3RyaW5nCiAgICAgICAgICAgICAgICAvLyB0aGF0IHJlc3VsdHMgZnJvbSB0aGUgZGVjb21wb3NpdGlvbiwgYnV0IGlmIHdlIGhhdmUgb3JkZXJzCiAgICAgICAgICAgICAgICAvLyBmb3IgZWFjaCBpbmRpdmlkdWFsIGNoYXJhY3Rlciwgd2UgY2FuIGFkZCBhbiBleHBhbmRpbmcKICAgICAgICAgICAgICAgIC8vIHRhYmxlIGVudHJ5IGZvciB0aGUgcHJlLWNvbXBvc2VkIGNoYXJhY3RlciAKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICBib29sX3QgYWxsVGhlcmUgPSBUUlVFOwogICAgICAgICAgICAgICAgaW50MzJfdCBpOwoKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBkZWNvbXAuc2l6ZSgpOyBpICs9IDEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGdldENoYXJPcmRlcihkZWNvbXBbaV0pID09IFVOTUFQUEVEKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWxsVGhlcmUgPSBGQUxTRTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChhbGxUaGVyZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBidWYucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICAgICAgYnVmICs9IGM7CiAgICAgICAgICAgICAgICAgICAgYWRkRXhwYW5kT3JkZXIoYnVmLCBkZWNvbXAsIFVOTUFQUEVELCBzdGF0dXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CiAgICAKLy8gV2hlbiB0aGUgZXhwYW5kaW5nIGNoYXJhY3RlciB0YWJsZXMgYXJlIGJ1aWx0IGJ5IGFkZEV4cGFuZE9yZGVyLAovLyBpdCBkb2Vzbid0IGtub3cgd2hhdCB0aGUgZmluYWwgb3JkZXJpbmcgb2YgZWFjaCBjaGFyYWN0ZXIKLy8gaW4gdGhlIGV4cGFuc2lvbiB3aWxsIGJlLiAgSW5zdGVhZCwgaXQganVzdCBwdXRzIHRoZSByYXcgY2hhcmFjdGVyCi8vIGNvZGUgaW50byB0aGUgdGFibGUsIGFkZGluZyBDSEFSSU5ERVggYXMgYSBmbGFnLiAgTm93IHRoYXQgd2UndmUKLy8gZmluaXNoZWQgYnVpbGRpbmcgdGhlIG1hcHBpbmcgdGFibGUsIHdlIGNhbiBnbyBiYWNrIGFuZCBsb29rIHVwCi8vIHRoYXQgY2hhcmFjdGVyIHRvIHNlZSB3aGF0IGl0cyByZWFsIGNvbGxhdGlvbiBvcmRlciBpcyBhbmQKLy8gc3RpY2sgdGhhdCBpbnRvIHRoZSBleHBhbnNpb24gdGFibGUuICBUaGF0IGxldHMgdXMgYXZvaWQgZG9pbmcKLy8gYSB0d28tc3RhZ2UgbG9va3VwIGxhdGVyLgoKdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6Y29tbWl0KCkKewogICAgLy8gaWYgdGhlcmUgYXJlIGFueSBleHBhbmRpbmcgY2hhcmFjdGVycwogICAgaWYgKGRhdGEtPmV4cGFuZFRhYmxlICE9IE5VTEwpCiAgICB7CiAgICAgICAgaW50MzJfdCBpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBkYXRhLT5leHBhbmRUYWJsZS0+c2l6ZSgpOyBpICs9IDEpCiAgICAgICAgewogICAgICAgICAgICBWZWN0b3JPZkludCogdmFsdWVMaXN0ID0gZGF0YS0+ZXhwYW5kVGFibGUtPmF0KGkpOwogICAgICAgICAgICBpbnQzMl90IGo7CiAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCB2YWx1ZUxpc3QtPnNpemUoKTsgaisrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBmb3VuZCBhIGV4cGFuZGluZyBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgIC8vIHRoZSBleHBhbmRpbmcgY2hhciB2YWx1ZSBpcyBub3QgZmlsbGVkIGluIHlldAogICAgICAgICAgICAgICAgaWYgKCh2YWx1ZUxpc3QtPmF0KGopIDwgRVhQQU5EQ0hBUklOREVYKSAmJgogICAgICAgICAgICAgICAgICAgICh2YWx1ZUxpc3QtPmF0KGopID4gQ0hBUklOREVYKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIHJlYWwgdmFsdWVzIGZvciB0aGUgbm9uLWZpbGxlZCBlbnRyeQogICAgICAgICAgICAgICAgICAgIFVDaGFyIGNoID0gKFVDaGFyKSh2YWx1ZUxpc3QtPmF0KGopIC0gQ0hBUklOREVYKTsKICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHJlYWxWYWx1ZSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY2gpOwoKICAgICAgICAgICAgICAgICAgICBpZiAocmVhbFZhbHVlID09IFVOTUFQUEVEKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHJlYWwgdmFsdWUgaXMgc3RpbGwgdW5tYXBwZWQsIG1heWJlIGl0J3NpZ25vcmFibGUKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVMaXN0LT5hdFB1dChqLCBJR05PUkFCTEVNQVNLICYgY2gpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBmaWxsIGluIHRoZSB2YWx1ZQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlTGlzdC0+YXRQdXQoaiwgcmVhbFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiB9CgovKioKICogIEluY3JlbWVudCBvZiB0aGUgbGFzdCBvcmRlciBiYXNlZCBvbiB0aGUgY29tcGFyaXNvbiBsZXZlbC4KICovCmludDMyX3QKUnVsZUJhc2VkQ29sbGF0b3I6OmluY3JlbWVudChDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoIGFTdHJlbmd0aCwgaW50MzJfdCBsYXN0VmFsdWUpCnsKICAgIHN3aXRjaChhU3RyZW5ndGgpCiAgICB7CiAgICBjYXNlIENvbGxhdG9yOjpQUklNQVJZOgogICAgICAgIC8vIGluY3JlbWVudCBwcmlhbXJ5IG9yZGVyICBhbmQgbWFzayBvZmYgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgICAgICAgbGFzdFZhbHVlICs9IFBSSU1BUllPUkRFUklOQ1JFTUVOVDsKICAgICAgICBsYXN0VmFsdWUgJj0gUFJJTUFSWU9SREVSTUFTSzsKICAgICAgICBpc092ZXJJZ25vcmUgPSBUUlVFOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQ29sbGF0b3I6OlNFQ09OREFSWToKICAgICAgICAvLyBpbmNyZW1lbnQgc2Vjb25kYXJ5IG9yZGVyIGFuZCBtYXNrIG9mZiB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgICAgICAgbGFzdFZhbHVlICs9IFNFQ09OREFSWU9SREVSSU5DUkVNRU5UOwogICAgICAgIGxhc3RWYWx1ZSAmPSBTRUNPTkRBUllESUZGRVJFTkNFT05MWTsKCiAgICAgICAgLy8gcmVjb3JkIG1heCAjIG9mIGlnbm9yYWJsZSBjaGFycyB3aXRoIHNlY29uZGFyeSBkaWZmZXJlbmNlCiAgICAgICAgaWYgKGlzT3Zlcklnbm9yZSA9PSBGQUxTRSkKICAgICAgICB7CiAgICAgICAgICAgIGRhdGEtPm1heFNlY09yZGVyICs9IDE7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQ29sbGF0b3I6OlRFUlRJQVJZOgogICAgICAgIC8vIGluY3JlbWVudCB0ZXJ0aWFyeSBvcmRlcgogICAgICAgIGxhc3RWYWx1ZSArPSBURVJUSUFSWU9SREVSSU5DUkVNRU5UOwoKICAgICAgICAvLyByZWNvcmQgbWF4ICMgb2YgaWdub3JhYmxlIGNoYXJzIHdpdGggdGVydGlhcnkgZGlmZmVyZW5jZQogICAgICAgIGlmIChpc092ZXJJZ25vcmUgPT0gRkFMU0UpCiAgICAgICAgewogICAgICAgICAgICBkYXRhLT5tYXhUZXJPcmRlciArPSAxOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KCiAgICByZXR1cm4gbGFzdFZhbHVlOwp9CgovLyBBZGRzIGEgY2hhcmFjdGVyIGFuZCBpdHMgZGVzaWduYXRlZCBvcmRlciBpbnRvIHRoZSBjb2xsYXRpb24gdGFibGUuCi8vIFRoaXMgaXMgdGhlIHNpbXBsZSBjYXNlLCB3aXRoIG5vIGV4cGFuc2lvbiBvciBjb250cmFjdGlvbgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjphZGRPcmRlcihVQ2hhciBjaCwKICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgYW5PcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gdHJ5IHRvIGZpbmQgdGhlIG9yZGVyIG9mIHRoZSBjaGFyIGluIHRoZSBtYXBwaW5nIHRhYmxlCiAgICBpbnQzMl90IG9yZGVyID0gdWNtcDMyX2dldChkYXRhLT5tYXBwaW5nLCBjaCk7CgogICAgaWYgKG9yZGVyID49IENPTlRSQUNUQ0hBUklOREVYKQogICAgewogICAgICAgIC8vIFRoZXJlJ3MgYWxyZWFkeSBhbiBlbnRyeSBmb3IgdGhpcyBjaGFyYWN0ZXIgdGhhdCBwb2ludHMgdG8gYSBjb250cmFjdGluZwogICAgICAgIC8vIGNoYXJhY3RlciB0YWJsZS4gIEluc3RlYWQgb2YgYWRkaW5nIHRoZSBjaGFyYWN0ZXIgZGlyZWN0bHkgdG8gdGhlIG1hcHBpbmcKICAgICAgICAvLyB0YWJsZSwgd2UgbXVzdCBhZGQgaXQgdG8gdGhlIGNvbnRyYWN0IHRhYmxlIGluc3RlYWQuCiAgICAgICAga2V5LnJlbW92ZSgpOwogICAgICAgIGtleSArPSBjaDsKICAgICAgICBpZiAoa2V5LmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIHN0YXR1cyA9IE1FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBhZGRDb250cmFjdE9yZGVyKGtleSwgYW5PcmRlciwgc3RhdHVzKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvLyBhZGQgdGhlIGVudHJ5IHRvIHRoZSBtYXBwaW5nIHRhYmxlLCB0aGUgc2FtZSBsYXRlciBlbnRyeSByZXBsYWNlcyB0aGUgcHJldmlvdXMgb25lCiAgICAgICAgdWNtcDMyX3NldChkYXRhLT5tYXBwaW5nLCBjaCwgYW5PcmRlcik7CiAgICB9Cn0KCi8vIEFkZCBhbiBleHBhbmRpbmctY2hhcmFjdGVyIGVudHJ5IHRvIHRoZSB0YWJsZS4Kdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6YWRkRXhwYW5kT3JkZXIoICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmIGNvbnRyYWN0Q2hhcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgICBVbmljb2RlU3RyaW5nJiBleHBhbmRDaGFycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGFuT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICBpZiAoRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBDcmVhdGUgYW4gZXhwYW5zaW9uIHRhYmxlIGVudHJ5CiAgICBpbnQzMl90IHRhYmxlSW5kZXggPSBhZGRFeHBhbnNpb24oYW5PcmRlciwgZXhwYW5kQ2hhcnMpOwogICAgCiAgICAvLyBBbmQgYWRkIGl0cyBpbmRleCBpbnRvIHRoZSBtYWluIG1hcHBpbmcgdGFibGUKICAgIGlmIChjb250cmFjdENoYXJzLnNpemUoKSA+IDEpCiAgICB7CiAgICAgICAgYWRkQ29udHJhY3RPcmRlcihjb250cmFjdENoYXJzLCB0YWJsZUluZGV4LCBzdGF0dXMpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGFkZE9yZGVyKGNvbnRyYWN0Q2hhcnNbMF0sIHRhYmxlSW5kZXgsIHN0YXR1cyk7CiAgICB9Cn0KCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmFkZEV4cGFuc2lvbihpbnQzMl90IGFuT3JkZXIsIGNvbnN0IFVuaWNvZGVTdHJpbmcgJmV4cGFuZENoYXJzKQp7CiAgICBpZiAoZGF0YS0+ZXhwYW5kVGFibGUgPT0gTlVMTCkKICAgIHsKICAgICAgICBkYXRhLT5leHBhbmRUYWJsZSA9IG5ldyBWZWN0b3JPZlBUb0V4cGFuZFRhYmxlKCk7CgogICAgICAgIGlmIChkYXRhLT5leHBhbmRUYWJsZSA9PSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvLyBJZiBhbk9yZGVyIGlzIHZhbGlkLCB3ZSB3YW50IHRvIGFkZCBpdCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0CiAgICBpbnQzMl90IG9mZnNldCA9IChhbk9yZGVyID09IFVOTUFQUEVEKSA/IDAgOiAxOwogICAgCiAgICBWZWN0b3JPZkludCAqdmFsdWVMaXN0ID0gbmV3IFZlY3Rvck9mSW50KGV4cGFuZENoYXJzLnNpemUoKSArIG9mZnNldCk7CgogICAgaWYgKG9mZnNldCA9PSAxKQogICAgewogICAgICAgIHZhbHVlTGlzdC0+YXRQdXQoMCwgYW5PcmRlcik7CiAgICB9CgogICAgaW50MzJfdCBpOwogICAgZm9yIChpID0gMDsgaSA8IGV4cGFuZENoYXJzLnNpemUoKTsgaSArPSAxKQogICAgewogICAgICAgIFVDaGFyIGNoID0gZXhwYW5kQ2hhcnNbaV07CiAgICAgICAgaW50MzJfdCBtYXBWYWx1ZSA9IGdldENoYXJPcmRlcihjaCk7CiAgICAgICAgCiAgICAgICAgaWYgKG1hcFZhbHVlICE9IFVOTUFQUEVEKQogICAgICAgIHsKICAgICAgICAgICAgdmFsdWVMaXN0LT5hdFB1dChpICsgb2Zmc2V0LCBtYXBWYWx1ZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8vIGNhbid0IGZpbmQgaXQgaW4gdGhlIHRhYmxlLCB3aWxsIGJlIGZpbGxlZCBpbiBieSBjb21taXQoKS4KICAgICAgICAgICAgdmFsdWVMaXN0LT5hdFB1dChpICsgb2Zmc2V0LCBDSEFSSU5ERVggKyAoaW50MzJfdCljaCk7CiAgICAgICAgfQogICAgfQoKICAgIC8vIEFkZCB0aGUgZXhwYW5kaW5nIGNoYXIgbGlzdCBpbnRvIHRoZSBleHBhbnNpb24gdGFibGUuCiAgICBpbnQzMl90IHRhYmxlSW5kZXggPSBFWFBBTkRDSEFSSU5ERVggKyBkYXRhLT5leHBhbmRUYWJsZS0+c2l6ZSgpOwogICAgZGF0YS0+ZXhwYW5kVGFibGUtPmF0UHV0KGRhdGEtPmV4cGFuZFRhYmxlLT5zaXplKCksIHZhbHVlTGlzdCk7CiAgICAKICAgIHJldHVybiB0YWJsZUluZGV4Owp9CgovLyBBZGQgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyB0aGF0IGNvbnRyYWN0cyBpbnRvIGEgc2luZ2xlIG9yZGVyaW5nLgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjphZGRDb250cmFjdE9yZGVyKGNvbnN0ICAgVW5pY29kZVN0cmluZyYgZ3JvdXBDaGFycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBhbk9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sX3QgZndkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmIChGQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChkYXRhLT5jb250cmFjdFRhYmxlID09IE5VTEwpCiAgICB7CiAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZSA9IG5ldyBWZWN0b3JPZlBUb0NvbnRyYWN0VGFibGUoKTsKICAgICAgICBpZiAoZGF0YS0+Y29udHJhY3RUYWJsZS0+aXNCb2d1cygpKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBNRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBTZWUgaWYgdGhlIGluaXRpYWwgY2hhcmFjdGVyIG9mIHRoZSBzdHJpbmcgYWxyZWFkeSBoYXMgYSBjb250cmFjdCB0YWJsZS4KICAgIC8vIGUuZy4gZm9yICJjaCIsIGxvb2sgZm9yICdjJy4KICAgIGludDMyX3QgZW50cnkgPSB1Y21wMzJfZ2V0KGRhdGEtPm1hcHBpbmcsIGdyb3VwQ2hhcnNbMF0pOwogICAgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQgKmVudHJ5VGFibGUgPSBnZXRDb250cmFjdFZhbHVlcyhlbnRyeSAtIENPTlRSQUNUQ0hBUklOREVYKTsKCiAgICBpZiAoZW50cnlUYWJsZSA9PSBOVUxMKQogICAgewogICAgICAgIC8vIFdlIG5lZWQgdG8gY3JlYXRlIGEgbmV3IHRhYmxlIG9mIGNvbnRyYWN0IGVudHJpZXMgZm9yIHRoaXMgYmFzZSBjaGFyCiAgICAgICAgaW50MzJfdCB0YWJsZUluZGV4ID0gQ09OVFJBQ1RDSEFSSU5ERVggKyBkYXRhLT5jb250cmFjdFRhYmxlLT5zaXplKCk7CiAgICAgICAgRW50cnlQYWlyICpwYWlyID0gTlVMTDsKICAgICAgICBVbmljb2RlU3RyaW5nIHN1YnN0cmluZzsKCiAgICAgICAgZW50cnlUYWJsZSA9IG5ldyBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCgpOwogICAgICAgIGlmIChlbnRyeVRhYmxlLT5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZW50cnlUYWJsZTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBNRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZS0+YXRQdXQoZGF0YS0+Y29udHJhY3RUYWJsZS0+c2l6ZSgpLCBlbnRyeVRhYmxlKTsKICAgICAgICBpZiAoZGF0YS0+Y29udHJhY3RUYWJsZS0+aXNCb2d1cygpKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGVudHJ5VGFibGU7CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhLT5jb250cmFjdFRhYmxlOwogICAgICAgICAgICBkYXRhLT5jb250cmFjdFRhYmxlID0gTlVMTDsKICAgICAgICAgICAgc3RhdHVzID0gTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgICAgIAoKICAgICAgICAvLyBBZGQgdGhlIGluaXRpYWwgY2hhcmFjdGVyJ3MgY3VycmVudCBvcmRlcmluZyBmaXJzdC4gdGhlbgogICAgICAgIC8vIHVwZGF0ZSBpdHMgbWFwcGluZyB0byBwb2ludCB0byB0aGlzIGNvbnRyYWN0IHRhYmxlCiAgICAgICAgZ3JvdXBDaGFycy5leHRyYWN0KDAsIDEsIHN1YnN0cmluZyk7CiAgICAgICAgaWYgKHN1YnN0cmluZy5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZW50cnlUYWJsZTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBNRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgcGFpciA9IG5ldyBFbnRyeVBhaXIoc3Vic3RyaW5nLCBlbnRyeSk7CgogICAgICAgIGVudHJ5VGFibGUtPmF0UHV0KDAsIHBhaXIpOwogICAgICAgIGlmIChlbnRyeVRhYmxlLT5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZW50cnlUYWJsZTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBNRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdWNtcDMyX3NldChkYXRhLT5tYXBwaW5nLCBncm91cENoYXJzWzBdLCB0YWJsZUluZGV4KTsKICAgIH0KCiAgICAvLyBOb3cgYWRkIChvciByZXBsYWNlKSB0aGlzIHN0cmluZyBpbiB0aGUgdGFibGUKICAgIGludDMyX3QgaW5kZXggPSBnZXRFbnRyeShlbnRyeVRhYmxlLCBncm91cENoYXJzLCBmd2QpOwoKICAgIGlmIChpbmRleCAhPSBVTk1BUFBFRCkKICAgIHsKICAgICAgICBFbnRyeVBhaXIgKnBhaXIgPSAoRW50cnlQYWlyICopIGVudHJ5VGFibGUtPmF0KGluZGV4KTsKICAgICAgICBwYWlyLT52YWx1ZSA9IGFuT3JkZXI7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgRW50cnlQYWlyICpwYWlyID0gbmV3IEVudHJ5UGFpcihncm91cENoYXJzLCBhbk9yZGVyLCBmd2QpOwoKICAgICAgICBlbnRyeVRhYmxlLT5hdFB1dChlbnRyeVRhYmxlLT5zaXplKCksIHBhaXIpOwogICAgfQogICAgCiAgICAvLyBJZiB0aGlzIHdhcyBhIGZvcndhcmQgbWFwcGluZyBmb3IgYSBjb250cmFjdGluZyBzdHJpbmcsIGFsc28gYWRkIGEKICAgIC8vIHJldmVyc2UgbWFwcGluZyBmb3IgaXQsIHNvIHRoYXQgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmV2aW91cwogICAgLy8gY2FuIHdvcmsgcmlnaHQKICAgIGlmIChmd2QpCiAgICB7CiAgICAgICAgVW5pY29kZVN0cmluZyByZXZlcnNlKGdyb3VwQ2hhcnMpOwoKICAgICAgICBpZiAocmV2ZXJzZS5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZW50cnlUYWJsZTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBNRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgYWRkQ29udHJhY3RPcmRlcihyZXZlcnNlLnJldmVyc2UoKSwgYW5PcmRlciwgRkFMU0UsIHN0YXR1cyk7CiAgICB9Cn0KCi8qKgogKiBJZiB0aGUgZ2l2ZW4gc3RyaW5nIGhhcyBiZWVuIHNwZWNpZmllZCBhcyBhIGNvbnRyYWN0aW5nIHN0cmluZwogKiBpbiB0aGlzIGNvbGxhdGlvbiB0YWJsZSwgcmV0dXJuIGl0cyBvcmRlcmluZy4KICogT3RoZXJ3aXNlIHJldHVybiBVTk1BUFBFRC4KICovCiBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb250cmFjdE9yZGVyKGNvbnN0IFVuaWNvZGVTdHJpbmcgJmdyb3VwQ2hhcnMpIGNvbnN0CnsKICAgIGludDMyX3QgcmVzdWx0ID0gVU5NQVBQRUQ7CgogICAgaWYgKGRhdGEtPmNvbnRyYWN0VGFibGUgIT0gTlVMTCkKICAgIHsKICAgICAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCAqZW50cnlUYWJsZSA9IGdldENvbnRyYWN0VmFsdWVzKGdyb3VwQ2hhcnNbMF0pOwoKICAgICAgICBpZiAoZW50cnlUYWJsZSAhPSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgaW50MzJfdCBpbmRleCA9IGdldEVudHJ5KGVudHJ5VGFibGUsIGdyb3VwQ2hhcnMsIFRSVUUpOwoKICAgICAgICAgICAgaWYgKGluZGV4ICE9IFVOTUFQUEVEKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBFbnRyeVBhaXIgKnBhaXIgPSBlbnRyeVRhYmxlLT5hdChpbmRleCk7CgogICAgICAgICAgICAgICAgcmVzdWx0ID0gcGFpci0+dmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJlc3VsdDsKfQoKaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q2hhck9yZGVyKFVDaGFyIGNoKSBjb25zdAp7CiAgICBpbnQzMl90IG9yZGVyID0gdWNtcDMyX2dldChkYXRhLT5tYXBwaW5nLCBjaCk7CiAgICAKICAgIGlmIChvcmRlciA+PSBDT05UUkFDVENIQVJJTkRFWCkKICAgIHsKICAgICAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCAqZ3JvdXBMaXN0ID0gZ2V0Q29udHJhY3RWYWx1ZXMob3JkZXIgLSBDT05UUkFDVENIQVJJTkRFWCk7CiAgICAgICAgRW50cnlQYWlyICpwYWlyID0gZ3JvdXBMaXN0LT5hdCgwKTsKCiAgICAgICAgb3JkZXIgPSBwYWlyLT52YWx1ZTsKICAgIH0KCiAgICByZXR1cm4gb3JkZXI7Cn0KICAgIAovLyBDcmVhdGUgYSBoYXNoIGNvZGUgZm9yIHRoaXMgY29sbGF0aW9uLiAgSnVzdCBoYXNoIHRoZSBtYWluIHJ1bGUgdGFibGUgLS0KLy8gdGhhdCBzaG91bGQgYmUgZ29vZCBlbm91Z2ggZm9yIGFsbW9zdCBhbnkgdXNlLgppbnQzMl90ClJ1bGVCYXNlZENvbGxhdG9yOjpoYXNoQ29kZSgpIGNvbnN0CnsKICAgIGludDMyX3QgICAgICAgICB2YWx1ZSA9IDA7CiAgICBpbnQzMl90ICAgICAgICAgYzsKICAgIGludDMyX3QgICAgICAgICBjb3VudCA9IGdldFJ1bGVzKCkuc2l6ZSgpOwogICAgVVRleHRPZmZzZXQgICAgICBwb3MgPSBjb3VudCAtIDE7CgogICAgaWYgKGNvdW50ID4gNjQpCiAgICB7CiAgICAgICAgY291bnQgPSA2NDsgLy8gb25seSBoYXNoIHVwdG8gbGltaXQKICAgIH0KCiAgICBpbnQxNl90IGkgPSAwOwoKICAgIHdoaWxlIChpIDwgY291bnQpCiAgICB7CiAgICAgICAgYyA9IGRhdGEtPnJ1bGVUYWJsZVtwb3NdOwogICAgICAgIHZhbHVlID0gKCh2YWx1ZSA8PCAoYyAmIDB4MGYpKSBeIChjIDw8IDgpKSArIChjIF4gdmFsdWUpOwogICAgICAgIGkgKz0gMTsKICAgICAgICBwb3MgLT0gMTsKICAgIH0KCiAgICBpZiAodmFsdWUgPT0gMCkKICAgIHsKICAgICAgICB2YWx1ZSA9IDE7CiAgICB9CgogICAgcmV0dXJuIHZhbHVlOwp9CgovLyBmaW5kIHRoZSBjb250cmFjdGluZyBjaGFyIGVudHJ5IGluIHRoZSBsaXN0CmludDMyX3QKUnVsZUJhc2VkQ29sbGF0b3I6OmdldEVudHJ5KFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KiBsaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xfdCBmd2QpCnsKICAgIGludDMyX3QgaTsKCiAgICBpZiAobGlzdCAhPSBOVUxMKQogICAgewogICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0LT5zaXplKCk7IGkgKz0gMSkKICAgICAgICB7CiAgICAgICAgICAgIEVudHJ5UGFpciAqcGFpciA9IGxpc3QtPmF0KGkpOwoKICAgICAgICAgICAgaWYgKChwYWlyICE9IE5VTEwpICYmIChwYWlyLT5md2QgPT0gZndkKSAmJiAocGFpci0+ZW50cnlOYW1lID09IG5hbWUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3I6OlVOTUFQUEVEOwp9CgovLyBsb29rIGZvciB0aGUgY29udHJhY3RpbmcgbGlzdCBlbnRyeSB3aXRoIHRoZSBiZWdpbm5pbmcgY2hhcgpWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCoKUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbnRyYWN0VmFsdWVzKFVDaGFyIGNoKSBjb25zdAp7CiAgICBpbnQzMl90IGluZGV4ID0gdWNtcDMyX2dldChkYXRhLT5tYXBwaW5nLCBjaCk7CiAgICByZXR1cm4gZ2V0Q29udHJhY3RWYWx1ZXMoaW5kZXggLSBDT05UUkFDVENIQVJJTkRFWCk7Cn0KCi8vIGxvb2sgZm9yIHRoZSBjb250cmFjdGluZyBsaXN0IGVudHJ5IHdpdGggdGhlIGluZGV4ClZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KgpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29udHJhY3RWYWx1ZXMoaW50MzJfdCAgICBpbmRleCkgY29uc3QKewogICAgaWYgKGRhdGEtPmNvbnRyYWN0VGFibGUgIT0gTlVMTCkKICAgIHsKICAgICAgICBpZiAoaW5kZXggPj0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBkYXRhLT5jb250cmFjdFRhYmxlLT5hdChpbmRleCk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKgogICogUmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbnkgZXhwYW5zaW9uIHNlcXVlbmNlcyB0aGF0IGVuZAogICogd2l0aCB0aGUgc3BlY2lmaWVkIGNvbXBhcmlzb24gb3JkZXIuCiAgKgogICogQHBhcmFtIG9yZGVyIGEgY29sbGF0aW9uIG9yZGVyIHJldHVybmVkIGJ5IHByZXZpb3VzIG9yIG5leHQuCiAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbnkgZXhwYW5zaW9uIHNldWVuY2VzIGVuZGluZwogICogICAgICAgICB3aXRoIHRoZSBzcGVjaWZpZWQgb3JkZXIuCiAgKgogICogQHNlZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IjZ2V0TWF4RXhwYW5zaW9uCiAgKi8KaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0TWF4RXhwYW5zaW9uKGludDMyX3Qgb3JkZXIpIGNvbnN0CnsKICAgIGludDMyX3QgcmVzdWx0ID0gMTsKICAgIAogICAgaWYgKGRhdGEtPmV4cGFuZFRhYmxlICE9IE5VTEwpCiAgICB7CiAgICAgICAgLy8gUmlnaHQgbm93IHRoaXMgZG9lcyBhIGxpbmVhciBzZWFyY2ggdGhyb3VnaCB0aGUgZW50aXJlCiAgICAgICAgLy8gZXhwYW5kc2lvbiB0YWJsZS4gIElmIGEgY29sbGF0b3IgaGFkIGEgbGFyZ2UgbnVtYmVyIG9mIGV4cGFuc2lvbnMsCiAgICAgICAgLy8gdGhpcyBjb3VsZCBjYXVzZSBhIHBlcmZvcm1hbmNlIHByb2JsZW0sIGJ1dCBpbiBwcmFjdGljZSB0aGF0CiAgICAgICAgLy8gcmFyZWx5IGhhcHBlbnMKICAgICAgICBpbnQzMl90IGk7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IGRhdGEtPmV4cGFuZFRhYmxlLT5zaXplKCk7IGkgKz0gMSkKICAgICAgICB7CiAgICAgICAgICAgIFZlY3Rvck9mSW50ICp2YWx1ZUxpc3QgPSBkYXRhLT5leHBhbmRUYWJsZS0+YXQoaSk7CiAgICAgICAgICAgIGludDMyX3QgbGVuZ3RoID0gdmFsdWVMaXN0LT5zaXplKCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAobGVuZ3RoID4gcmVzdWx0ICYmIHZhbHVlTGlzdC0+YXQobGVuZ3RoLTEpID09IG9yZGVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBsZW5ndGg7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJlc3VsdDsKfQogICAgCi8qKgogKiAgR2V0IHRoZSBlbnRyeSBvZiBoYXNoIHRhYmxlIG9mIHRoZSBleHBhbmRpbmcgc3RyaW5nIGluIHRoZSBjb2xsYXRpb24KICogIHRhYmxlLgogKiAgQHBhcmFtIGlkeCB0aGUgaW5kZXggb2YgdGhlIGV4cGFuZGluZyBzdHJpbmcgdmFsdWUgbGlzdAogKi8KVmVjdG9yT2ZJbnQgKlJ1bGVCYXNlZENvbGxhdG9yOjpnZXRFeHBhbmRWYWx1ZUxpc3QoaW50MzJfdCBvcmRlcikgY29uc3QKewogICAgcmV0dXJuIGRhdGEtPmV4cGFuZFRhYmxlLT5hdChvcmRlciAtIEVYUEFORENIQVJJTkRFWCk7Cn0KCi8vIEdldCB0aGUgY2hhcmFjdGVyIG9yZGVyIGluIHRoZSBtYXBwaW5nIHRhYmxlCmludDMyX3QKUnVsZUJhc2VkQ29sbGF0b3I6OmdldFVuaWNvZGVPcmRlcihVQ2hhciBjaCkgY29uc3QKewogICAgcmV0dXJuIHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY2gpOwp9CgoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1JbihSdWxlQmFzZWRDb2xsYXRvciogY29sbGF0b3IsIEZpbGVTdHJlYW0qIGlzKQp7CiAgICBpZiAoIVRfRmlsZVN0cmVhbV9lcnJvcihpcykpCiAgICB7CiAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGlzIGlzIHRoZSBjb3JyZWN0IGZpbGUgdHlwZQogICAgICAgIGludDE2X3QgaWQ7CgogICAgICAgIFRfRmlsZVN0cmVhbV9yZWFkKGlzLCAmaWQsIHNpemVvZihpZCkpOwogICAgICAgIGlmIChpZCAhPSBjb2xsYXRvci0+RklMRUlEKQogICAgICAgIHsKICAgICAgICAgICAgLy8gVGhpcyBpc24ndCB0aGUgcmlnaHQgdHlwZSBvZiBmaWxlLiAgTWFyayB0aGUgaW9zCiAgICAgICAgICAgIC8vIGFzIGZhaWxpbmcgYW5kIHJldHVybi4KICAgICAgICAgICAgVF9GaWxlU3RyZWFtX3NldEVycm9yKGlzKTsgLy8gZm9yY2UgdGhlIHN0cmVhbSB0byBzZXQgaXRzIGVycm9yIGZsYWcKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gU3RyZWFtIGluIGxhcmdlIG9iamVjdHMKICAgICAgICBjaGFyIGlzTnVsbDsKCiAgICAgICAgVF9GaWxlU3RyZWFtX3JlYWQoaXMsICZpc051bGwsIHNpemVvZihpc051bGwpKTsKICAgICAgICBpZiAoaXNOdWxsKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGNvbGxhdG9yLT5kYXRhOwogICAgICAgICAgICBjb2xsYXRvci0+ZGF0YSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb2xsYXRvci0+ZGF0YSA9PSBOVUxMKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb2xsYXRvci0+ZGF0YSA9IG5ldyBUYWJsZUNvbGxhdGlvbkRhdGE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGNvbGxhdG9yLT5kYXRhLT5zdHJlYW1Jbihpcyk7CiAgICAgICAgICAgIGlmIChjb2xsYXRvci0+ZGF0YS0+aXNCb2d1cygpKSB7CiAgICAgICAgICAgICAgICBUX0ZpbGVTdHJlYW1fc2V0RXJyb3IoaXMpOyAvLyBmb3JjZSB0aGUgc3RyZWFtIHRvIHNldCBpdHMgZXJyb3IgZmxhZwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgdGhhdCB0aGUgZW5kIG1hcmtlciBpcyBwcmVzZW50CiAgICAgICAgVF9GaWxlU3RyZWFtX3JlYWQoaXMsICZpZCwgc2l6ZW9mKGlkKSk7CiAgICAgICAgaWYgKGlkICE9IGNvbGxhdG9yLT5GSUxFSUQpCiAgICAgICAgewogICAgICAgICAgICAvLyBUaGlzIGlzbid0IHRoZSByaWdodCB0eXBlIG9mIGZpbGUuICBNYXJrIHRoZSBpb3MKICAgICAgICAgICAgLy8gYXMgZmFpbGluZyBhbmQgcmV0dXJuLgogICAgICAgICAgICBUX0ZpbGVTdHJlYW1fc2V0RXJyb3IoaXMpOyAvLyBmb3JjZSB0aGUgc3RyZWFtIHRvIHNldCBpdHMgZXJyb3IgZmxhZwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBSZXNldCBvdGhlciBkYXRhIG1lbWJlcnMKICAgICAgICBjb2xsYXRvci0+aXNPdmVySWdub3JlID0gRkFMU0U7CiAgICAgICAgY29sbGF0b3ItPmxhc3RDaGFyID0gMDsKICAgICAgICBkZWxldGUgY29sbGF0b3ItPm1QYXR0ZXJuOwogICAgICAgIGNvbGxhdG9yLT5tUGF0dGVybiA9IDA7CiAgICAgICAgY29sbGF0b3ItPmtleS5yZW1vdmUoKTsKICAgICAgICBjb2xsYXRvci0+ZGF0YUlzT3duZWQgPSBUUlVFOwogICAgfQp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbU91dChjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogY29sbGF0b3IsIEZpbGVTdHJlYW0qIG9zKQp7CiAgICBpZiAoIVRfRmlsZVN0cmVhbV9lcnJvcihvcykpCiAgICB7CiAgICAgICAgLy8gV2UgdXNlIGEgMTYtYml0IElEIGNvZGUgdG8gaWRlbnRpZnkgdGhpcyBmaWxlLgogICAgICAgIGludDE2X3QgaWQgPSBjb2xsYXRvci0+RklMRUlEOwogICAgICAgIFRfRmlsZVN0cmVhbV93cml0ZShvcywgJmlkLCBzaXplb2YoaWQpKTsKCiAgICAgICAgLy8gU3RyZWFtIG91dCB0aGUgZGF0YQogICAgICAgIGNoYXIgaXNOdWxsOwogICAgICAgIGlzTnVsbCA9IChjb2xsYXRvci0+ZGF0YSA9PSAwKTsKICAgICAgICBUX0ZpbGVTdHJlYW1fd3JpdGUob3MsICZpc051bGwsIHNpemVvZihpc051bGwpKTsKCiAgICAgICAgaWYgKCFpc051bGwpCiAgICAgICAgewogICAgICAgICAgICBjb2xsYXRvci0+ZGF0YS0+c3RyZWFtT3V0KG9zKTsKICAgICAgICB9CgogICAgICAgIC8vIFdyaXRlIG91dCB0aGUgSUQgdG8gaW5kaWNhdGUgdGhlIGVuZAogICAgICAgIFRfRmlsZVN0cmVhbV93cml0ZShvcywgJmlkLCBzaXplb2YoaWQpKTsKICAgIH0KfQoKYm9vbF90IFJ1bGVCYXNlZENvbGxhdG9yOjp3cml0ZVRvRmlsZShjb25zdCBjaGFyKiBmaWxlTmFtZSkgY29uc3QKewogICAgRmlsZVN0cmVhbSogb2ZzID0gVF9GaWxlU3RyZWFtX29wZW4oZmlsZU5hbWUsICJ3YiIpOwogICAgaWYgKG9mcyAhPSAwKQogICAgewogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbU91dCh0aGlzLCBvZnMpOwogICAgfQoKI2lmZGVmIENPTExERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJiaW5hcnkgd3JpdGUgJXMgc2l6ZSAlZCAlc1xuIiwgZmlsZU5hbWUsIFRfRmlsZVN0cmVhbV9zaXplKG9mcyksCiAgICAgICAgKCFUX0ZpbGVTdHJlYW1fZXJyb3Iob2ZzKSA/ICIsIE9LIiA6ICIsIEZBSUwiKTsKI2VuZGlmCgogICAgYm9vbF90IGVyciA9IFRfRmlsZVN0cmVhbV9lcnJvcihvZnMpID09IDA7CgogICAgVF9GaWxlU3RyZWFtX2Nsb3NlKG9mcyk7CiAgICByZXR1cm4gZXJyOwp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjphZGRUb0NhY2hlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIGtleSkKewogICAgLy8gVGhpcyBtZXRob2QgZG9lc24ndCBhZGQgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIGl0c2VsZiB0byB0aGUgY2FjaGUuICBJbnN0ZWFkLAogICAgLy8gaXQgYWRkcyB0aGUgZ2l2ZW4gUnVsZUJhc2VkQ29sbGF0b3IncyBkYXRhIG9iamVjdCB0byB0aGUgVGFibGVDb2xsYXRpb25EYXRhCiAgICAvLyBjYWNoZSwgYW5kIG1hcmtzIGl0IGFzIG5vbi1vd25lZCBpbiB0aGUgZ2l2ZW4gUnVsZUJhc2VkQ29sbGF0b3Igb2JqZWN0LgogICAgVGFibGVDb2xsYXRpb25EYXRhOjphZGRUb0NhY2hlKGtleSwgZGF0YSk7CiAgICBkYXRhSXNPd25lZCA9IEZBTFNFOwp9Cgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tQ2FjaGUoY29uc3QgVW5pY29kZVN0cmluZyYga2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgLy8gQXR0ZW1wdCB0byBjb25zdHJ1Y3QgdGhpcyBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QgZnJvbSBjYWNoZWQgVGFibGVDb2xsYXRpb25EYXRhLgogICAgLy8gSWYgbm8gc3VjaCBkYXRhIGlzIGluIHRoZSBjYWNoZSwgcmV0dXJuIGZhbHNlLgogICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogICAgaWYgKGRhdGFJc093bmVkKQogICAgewogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSBOVUxMOwogICAgfQoKICAgIGlzT3Zlcklnbm9yZSA9IEZBTFNFOwogICAgbGFzdENoYXIgPSAwOwogICAgbVBhdHRlcm4gPSAwOwogICAgc2V0U3RyZW5ndGgoQ29sbGF0b3I6OlRFUlRJQVJZKTsKCiAgICBkYXRhSXNPd25lZCA9IEZBTFNFOwogICAgZGF0YSA9IFRhYmxlQ29sbGF0aW9uRGF0YTo6ZmluZEluQ2FjaGUoa2V5KTsKICAgIGlmIChkYXRhID09IE5VTEwpCiAgICB7CiAgICAgICAgc3RhdHVzID0gTUlTU0lOR19SRVNPVVJDRV9FUlJPUjsKICAgIH0KfQoKY2hhcioKUnVsZUJhc2VkQ29sbGF0b3I6OmNyZWF0ZVBhdGhOYW1lKCAgY29uc3QgVW5pY29kZVN0cmluZyYgICAgcHJlZml4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgICAgc3VmZml4KQp7CiAgICAvLyBDb25jYXRlbmF0ZSB0aHJlZSBlbGVtZW50cyB0byBmb3JtIGEgZmlsZSBuYW1lLCBhbmQgcmV0dXJuIGl0LgoKICAgIFVuaWNvZGVTdHJpbmcgICB3b3JraW5nTmFtZShwcmVmaXgpOwogICAgaW50MzJfdCAgICAgICAgIHNpemU7CiAgICBjaGFyKiAgICAgICAgICAgcmV0dXJuVmFsOwoKICAgIHdvcmtpbmdOYW1lICs9IG5hbWU7CiAgICB3b3JraW5nTmFtZSArPSBzdWZmaXg7CgogICAgc2l6ZSA9IHdvcmtpbmdOYW1lLnNpemUoKTsKICAgIHJldHVyblZhbCA9IG5ldyBjaGFyW3NpemUgKyAxXTsKICAgIHdvcmtpbmdOYW1lLmV4dHJhY3QoMCwgc2l6ZSwgcmV0dXJuVmFsKTsKICAgIHJldHVyblZhbFtzaXplXSA9IDA7CgogICAgcmV0dXJuIHJldHVyblZhbDsKfQoKdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6Y2hvcExvY2FsZShVbmljb2RlU3RyaW5nJiBsb2NhbGVOYW1lKQp7CiAgICAvLyBjaG9wTG9jYWxlIHJlbW92ZXMgdGhlIGZpbmFsIGVsZW1lbnQgZnJvbSBhIGxvY2FsZSBzdHJpbmcuCiAgICAvLyBGb3IgaW5zdGFuY2UsICJkZV9DSCIgYmVjb21lcyAiZGUiLCBhbmQgImRlIiBiZWNvbWVzICIiLgogICAgLy8gIiIgcmVtYWlucyAiIi4KCiAgICBpbnQzMl90ICAgICBzaXplID0gbG9jYWxlTmFtZS5zaXplKCk7CiAgICBpbnQzMl90ICAgICBpOwoKICAgIGZvciAoaSA9IHNpemUgLSAxOyBpID4gMDsgaS0tKQogICAgewogICAgICAgIGlmIChsb2NhbGVOYW1lW2ldID09ICdfJykKICAgICAgICB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoaSA8IDApCiAgICB7CiAgICAgICAgaSA9IDA7CiAgICB9CgogICAgbG9jYWxlTmFtZS5yZW1vdmUoaSwgc2l6ZSAtIGkpOwp9CgovL2VvZgo=