LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogQ29weXJpZ2h0IKkgezE5OTYtMjAwMX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kICAgKgoqIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogICAgIAoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCi8qKgoqIEZpbGUgdGJsY29sbC5jcHAKKgoqIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloIAoqCiogTW9kaWZpY2F0aW9uIEhpc3Rvcnk6CioKKiAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgMi81Lzk3ICAgICAgYWxpdSAgICAgICAgQWRkZWQgc3RyZWFtSW4gYW5kIHN0cmVhbU91dCBtZXRob2RzLiAgQWRkZWQKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3Igd2hpY2ggcmVhZHMgUnVsZUJhc2VkQ29sbGF0b3Igb2JqZWN0IGZyb20KKiAgICAgICAgICAgICAgICAgICAgICAgICAgYSBiaW5hcnkgZmlsZS4gIEFkZGVkIHdyaXRlVG9GaWxlIG1ldGhvZCB3aGljaCBzdHJlYW1zCiogICAgICAgICAgICAgICAgICAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yIG91dCB0byBhIGJpbmFyeSBmaWxlLiAgVGhlIHN0cmVhbUluCiogICAgICAgICAgICAgICAgICAgICAgICAgIGFuZCBzdHJlYW1PdXQgbWV0aG9kcyB1c2UgaXN0cmVhbSBhbmQgb3N0cmVhbSBvYmplY3RzCiogICAgICAgICAgICAgICAgICAgICAgICAgIGluIGJpbmFyeSBtb2RlLgoqICAyLzExLzk3ICAgICBhbGl1ICAgICAgICBNb3ZlZCBkZWNsYXJhdGlvbnMgb3V0IG9mIGZvciBsb29wIGluaXRpYWxpemVyLgoqICAgICAgICAgICAgICAgICAgICAgICAgICBBZGRlZCBNYWMgY29tcGF0aWJpbGl0eSAjaWZkZWYgZm9yIGlvczo6bm9jcmVhdGUuCiogIDIvMTIvOTcgICAgIGFsaXUgICAgICAgIE1vZGlmaWVkIHRvIHVzZSBUYWJsZUNvbGxhdGlvbkRhdGEgc3ViLW9iamVjdCB0bwoqICAgICAgICAgICAgICAgICAgICAgICAgICBob2xkIGludmFyaWFudCBkYXRhLgoqICAyLzEzLzk3ICAgICBhbGl1ICAgICAgICBNb3ZlZCBzZXZlcmFsIG1ldGhvZHMgaW50byB0aGlzIGNsYXNzIGZyb20gQ29sbGF0aW9uLgoqICAgICAgICAgICAgICAgICAgICAgICAgICBBZGRlZCBhIHByaXZhdGUgUnVsZUJhc2VkQ29sbGF0b3IoTG9jYWxlJikgY29uc3RydWN0b3IsCiogICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGJlIHVzZWQgYnkgQ29sbGF0b3I6OmdldEluc3RhbmNlKCkuICBHZW5lcmFsCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFuIHVwLiAgTWFkZSB1c2Ugb2YgVUVycm9yQ29kZSB2YXJpYWJsZXMgY29uc2lzdGVudC4KKiAgMi8yMC85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgY2xvbmUsIG9wZXJhdG9yPT0sIG9wZXJhdG9yIT0sIG9wZXJhdG9yPSwgYW5kIGNvcHkKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3IgYW5kIGdldER5bmFtaWNDbGFzc0lELgoqICAzLzUvOTcgICAgICBhbGl1ICAgICAgICBDaGFuZ2VkIGNvbXBhY3Rpb24gY3ljbGUgdG8gaW1wcm92ZSBwZXJmb3JtYW5jZS4gIFdlCiogICAgICAgICAgICAgICAgICAgICAgICAgIHVzZSB0aGUgbWF4aW11bSBhbGxvd2FibGUgdmFsdWUgd2hpY2ggaXMga0Jsb2NrQ291bnQuCiogICAgICAgICAgICAgICAgICAgICAgICAgIE1vZGlmaWVkIGdldFJ1bGVzKCkgdG8gbG9hZCBydWxlcyBkeW5hbWljYWxseS4gIENoYW5nZWQKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0RnJvbUZpbGUoKSBjYWxsIHRvIGFjY29tb2RhdGUgdGhpcyAoYWRkZWQKKiAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyIHRvIHNwZWNpZnkgd2hldGhlciBiaW5hcnkgbG9hZGluZyBpcyB0bwoqICAgICAgICAgICAgICAgICAgICAgICAgICB0YWtlIHBsYWNlKS4KKiAwNS8wNi85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgbWVtb3J5IGFsbG9jYXRpb24gZXJyb3IgY2hlY2suCiogIDYvMjAvOTcgICAgIGhlbGVuYSAgICAgIEphdmEgY2xhc3MgbmFtZSBjaGFuZ2UuCiogIDYvMjMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGluZyBjb21tZW50cyB0byBtYWtlIGNvZGUgbW9yZSByZWFkYWJsZS4KKiAwOS8wMy85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgY3JlYXRlQ29sbGF0aW9uS2V5VmFsdWVzKCkuCiogMDYvMjYvOTggICAgIGVybSAgICAgICAgIENoYW5nZXMgZm9yIENvbGxhdGlvbktleXMgdXNpbmcgYnl0ZSBhcnJheXMuCiogMDgvMTAvOTggICAgIGVybSAgICAgICAgIFN5bmNoZWQgd2l0aCAxLjIgdmVyc2lvbiBvZiBSdWxlQmFzZWRDb2xsYXRvci5qYXZhCiogMDQvMjMvOTkgICAgIHN0ZXBoZW4gICAgIFJlbW92ZWQgRURlY29tcG9zaXRpb25Nb2RlLCBtZXJnZWQgd2l0aAoqICAgICAgICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZQoqIDA2LzE0Lzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIGtSZXNvdXJjZUJ1bmRsZVN1ZmZpeAoqIDA2LzIyLzk5ICAgICBzdGVwaGVuICAgICBGaXhlZCBsb2dpYyBpbiBjb25zdHJ1Y3RGcm9tRmlsZSgpIHNpbmNlIC5jdHgKKiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXMgYXJlIG5vIGxvbmdlciB1c2VkLgoqIDExLzAyLzk5ICAgICBoZWxlbmEgICAgICBDb2xsYXRvciBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuICBTcGVjaWFsIGNhc2UKKiAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIE5PX09QIHNpdHVhdGlvbnMuIAoqIDExLzE3Lzk5ICAgICBzcmwgICAgICAgICBNb3JlIHBlcmZvcm1hbmNlIGVuaGFuY2VtZW50cy4gSW5saW5lZCBzb21lIGludGVybmFsIGZ1bmN0aW9ucy4KKiAxMi8xNS85OSAgICAgYWxpdSAgICAgICAgVXBkYXRlIHRvIHN1cHBvcnQgVGhhaSBjb2xsYXRpb24uICBNb3ZlIE5vcm1hbGl6ZXJJdGVyYXRvcgoqICAgICAgICAgICAgICAgICAgICAgICAgICB0byBpbXBsZW1lbnRhdGlvbiBmaWxlLgoqIDAxLzI5LzAxICAgICBzeW53ZWUgICAgICBNb2RpZmllZCBpbnRvIGEgQysrIHdyYXBwZXIgY2FsbGluZyBDIEFQSXMgKHVjb2wuaCkKKi8KCiNpbmNsdWRlICJ1Y29sX2ltcC5oIgojaW5jbHVkZSAidW5pY29kZS90Ymxjb2xsLmgiCiNpbmNsdWRlICJ1bmljb2RlL2NvbGVpdHIuaCIKI2luY2x1ZGUgInVoYXNoLmgiCiNpbmNsdWRlICJ1bmljb2RlL3Jlc2J1bmQuaCIKI2luY2x1ZGUgImNtZW1vcnkuaCIKCiNpZmRlZiBfREVCVUcKICAjaW5jbHVkZSAidW5pc3RybS5oIgojZW5kaWYKCi8qIGdsb2JhbCB2YXJpYWJsZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKgpzeW53ZWUgOiB1c2luZyBhbm90aGVyIG5hbWUgZm9yIHRoaXMKY29uc3QgdWludDMyX3QgdGJsY29sbF9TVEFDS19CVUZGRVJfTEVOR1RIXyA9IDEwMjQ7CiovCiNkZWZpbmUgU1RBQ0tfQlVGRkVSX0xFTkdUSF8gMTAyNAoKLyogZm9yd2FyZCBkZWNsYXJhdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KClVfQ0FQSSBVQ2hhciBmb3J3YXJkQ2hhckl0ZXJhdG9yR2x1ZSh2b2lkICppdGVyYXRvcik7CgovKiBSdWxlQmFzZWRDb2xsYXRvciBkZWNsYXJhdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClRoZSBmb2xsb3dpbmcgZGlhZ3JhbSBzaG93cyB0aGUgZGF0YSBzdHJ1Y3R1cmUgb2YgdGhlIFJ1bGVCYXNlZENvbGxhdG9yICBvYmplY3QuIApTdXBwb3NlIHdlIGhhdmUgdGhlIHJ1bGUsIHdoZXJlICdvLXVtbGF1dCcgaXMgdGhlIHVuaWNvZGUgY2hhciAweDAwRjYuIAoiYSwgQSA8IGIsIEIgPCBjLCBDLCBjaCwgY0gsIENoLCBDSCA8IGQsIEQgLi4uIDwgbywgTzsgCidvLXVtbGF1dCcvRSwgJ08tdW1sYXV0Jy9FIC4uLiIuCldoYXQgdGhlIHJ1bGUgc2F5cyBpcywgc29ydHMgJ2NoJ2xpZ2F0dXJlcyBhbmQgJ2MnIG9ubHkgd2l0aCB0ZXJ0aWFyeSAKZGlmZmVyZW5jZSBhbmQgc29ydHMgJ28tdW1sYXV0JyBhcyBpZiBpdCdzIGFsd2F5cyBleHBhbmRlZCB3aXRoICdlJy4KCm1hcHBpbmcgdGFibGUgICAgICAgICAgICAgICAgIGNvbnRyYWN0aW5nIGxpc3QgICAgICAgICAgICAgZXhwYW5kaW5nIGxpc3QKKGNvbnRhaW5zIGFsbCB1bmljb2RlIApjaGFyIGVudHJpZXMpICAgICAgICAgICAgICAgX19fICAgIF9fX19fX19fX19fXyAgICAgIF9fX19fX19fX19fX19fX19fX19fX19fX18KIF9fX19fX19fICAgICAgICAgICAgICAgIHw9PnxfKl98LT58J2MnIHx2KCdjJykgfCB8PT58dignbycpfHYoJ3VtbGF1dCcpfHYoJ2UnKXwKfF9cdTAwMDFffC0+IHYoJ1x1MDAwMScpIHwgIHxfOl98ICB8LS0tLS0tLS0tLS0tfCB8ICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKfF9cdTAwMDJffC0+IHYoJ1x1MDAwMicpIHwgIHxfOl98ICB8J2NoJ3x2KCdjaCcpfCB8ICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKfF9fX186X19ffCAgICAgICAgICAgICAgIHwgIHxfOl98ICB8LS0tLS0tLS0tLS0tfCB8ICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKfF9fX186X19ffCAgICAgICAgICAgICAgIHwgICAgICAgICB8J2NIJ3x2KCdjSCcpfCB8ICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKfF9fJ2EnX19ffC0+IHYoJ2EnKSAgICAgIHwgICAgICAgICB8LS0tLS0tLS0tLS0tfCB8ICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKfF9fJ2InX19ffC0+IHYoJ2InKSAgICAgIHwgICAgICAgICB8J0NoJ3x2KCdDaCcpfCB8ICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKfF9fX186X19ffCAgICAgICAgICAgICAgIHwgICAgICAgICB8LS0tLS0tLS0tLS0tfCB8ICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKfF9fX186X19ffCAgICAgICAgICAgICAgIHwgICAgICAgICB8J0NIJ3x2KCdDSCcpfCB8ICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKfF9fXydjJ19ffC0tLS0tLS0tLS0tLS0tLS0gICAgICAgICAgLS0tLS0tLS0tLS0tICB8ICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKfF9fX186X19ffCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKfG8tdW1sYXV0fC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gICB8X19fX19fX19fX19fX19fX19fX19fX19fX3wKfF9fX186X19ffAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiBwdWJsaWMgUnVsZUJhc2VkQ29sbGF0b3IgY29uc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKLyoqCiogQ29weSBjb25zdHJ1Y3RvcgoqLwpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3ImIHRoYXQpIDogCiAgICAgICAgICAgICAgQ29sbGF0b3IodGhhdCksIGRhdGFJc093bmVkKEZBTFNFKSwgdWNvbGxhdG9yKHRoYXQudWNvbGxhdG9yKSwKICAgICAgICAgICAgICB1cnVsZXN0cmluZyh0aGF0LnVydWxlc3RyaW5nKQp7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgOiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFJc093bmVkKEZBTFNFKSAKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHJldHVybjsKIAogIGludDMyX3QgbGVuZ3RoID0gcnVsZXMubGVuZ3RoKCk7CgoJVUNoYXIgdWNoYXJydWxlc1tTVEFDS19CVUZGRVJfTEVOR1RIX107CglVQ2hhciAqcHVjaGFycnVsZXMgPSB1Y2hhcnJ1bGVzOwoJCiAgaWYgKGxlbmd0aCA+PSBTVEFDS19CVUZGRVJfTEVOR1RIXykKCQlwdWNoYXJydWxlcyA9IG5ldyBVQ2hhcltsZW5ndGggKyAxXTsKCQoJcnVsZXMuZXh0cmFjdCgwLCBsZW5ndGgsIHB1Y2hhcnJ1bGVzKTsKICBwdWNoYXJydWxlc1tsZW5ndGhdID0gMDsKCiAgdWNvbGxhdG9yID0gdWNvbF9vcGVuUnVsZXMocHVjaGFycnVsZXMsIGxlbmd0aCwgVUNPTF9ERUZBVUxUX05PUk1BTElaQVRJT04sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDT0xfREVGQVVMVF9TVFJFTkdUSCwgJnN0YXR1cyk7CiAgCiAgaWYgKFVfU1VDQ0VTUyhzdGF0dXMpKQogIHsKICAgIGNvbnN0IFVDaGFyICpyID0gdWNvbF9nZXRSdWxlcyh1Y29sbGF0b3IsICZsZW5ndGgpOwogICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZyhyLCBsZW5ndGgpOwogICAgCiAgICBkYXRhSXNPd25lZCA9IFRSVUU7CiAgfQogIAoJaWYgKHB1Y2hhcnJ1bGVzICE9IHVjaGFycnVsZXMpCgkJZGVsZXRlW10gcHVjaGFycnVsZXM7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICAgIEVDb2xsYXRpb25TdHJlbmd0aCBjb2xsYXRpb25TdHJlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgOiBkYXRhSXNPd25lZChGQUxTRSkKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHJldHVybjsKIAogIGludDMyX3QgbGVuZ3RoID0gcnVsZXMubGVuZ3RoKCk7CgoJVUNoYXIgdWNoYXJydWxlc1tTVEFDS19CVUZGRVJfTEVOR1RIX107CglVQ2hhciAqcHVjaGFycnVsZXMgPSB1Y2hhcnJ1bGVzOwoJCiAgaWYgKGxlbmd0aCA+PSBTVEFDS19CVUZGRVJfTEVOR1RIXykKCQlwdWNoYXJydWxlcyA9IG5ldyBVQ2hhcltsZW5ndGggKyAxXTsKCQoJcnVsZXMuZXh0cmFjdCgwLCBsZW5ndGgsIHB1Y2hhcnJ1bGVzKTsKICBwdWNoYXJydWxlc1tsZW5ndGhdID0gMDsKCiAgVUNvbGxhdGlvblN0cmVuZ3RoIHN0cmVuZ3RoID0gZ2V0VUNvbGxhdGlvblN0cmVuZ3RoKGNvbGxhdGlvblN0cmVuZ3RoKTsKICB1Y29sbGF0b3IgPSB1Y29sX29wZW5SdWxlcyhwdWNoYXJydWxlcywgbGVuZ3RoLCBVQ09MX0RFRkFVTFRfTk9STUFMSVpBVElPTiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZW5ndGgsICZzdGF0dXMpOwoKICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpCiAgewogICAgY29uc3QgVUNoYXIgKnIgPSB1Y29sX2dldFJ1bGVzKHVjb2xsYXRvciwgJmxlbmd0aCk7CiAgICB1cnVsZXN0cmluZyA9IG5ldyBVbmljb2RlU3RyaW5nKHIsIGxlbmd0aCk7CiAgICBkYXRhSXNPd25lZCA9IFRSVUU7CiAgfQogIAoJaWYgKHB1Y2hhcnJ1bGVzICE9IHVjaGFycnVsZXMpCgkJZGVsZXRlW10gcHVjaGFycnVsZXM7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSA6IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICByZXR1cm47CiAKICBpbnQzMl90IGxlbmd0aCA9IHJ1bGVzLmxlbmd0aCgpOwoKCVVDaGFyIHVjaGFycnVsZXNbU1RBQ0tfQlVGRkVSX0xFTkdUSF9dOwoJVUNoYXIgKnB1Y2hhcnJ1bGVzID0gdWNoYXJydWxlczsKCQogIGlmIChsZW5ndGggPj0gU1RBQ0tfQlVGRkVSX0xFTkdUSF8pCgkJcHVjaGFycnVsZXMgPSBuZXcgVUNoYXJbbGVuZ3RoICsgMV07CgkKCXJ1bGVzLmV4dHJhY3QoMCwgbGVuZ3RoLCBwdWNoYXJydWxlcyk7CiAgcHVjaGFycnVsZXNbbGVuZ3RoXSA9IDA7CgogIFVOb3JtYWxpemF0aW9uTW9kZSBtb2RlID0gTm9ybWFsaXplcjo6Z2V0VU5vcm1hbGl6YXRpb25Nb2RlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNvbXBvc2l0aW9uTW9kZSwgc3RhdHVzKTsKICB1Y29sbGF0b3IgPSB1Y29sX29wZW5SdWxlcyhwdWNoYXJydWxlcywgbGVuZ3RoLCBtb2RlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ09MX0RFRkFVTFRfU1RSRU5HVEgsICZzdGF0dXMpOwoKICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpCiAgewogICAgY29uc3QgVUNoYXIgKnIgPSB1Y29sX2dldFJ1bGVzKHVjb2xsYXRvciwgJmxlbmd0aCk7CiAgICB1cnVsZXN0cmluZyA9IG5ldyBVbmljb2RlU3RyaW5nKHIsIGxlbmd0aCk7CiAgICBkYXRhSXNPd25lZCA9IFRSVUU7CiAgfQogIAoJaWYgKHB1Y2hhcnJ1bGVzICE9IHVjaGFycnVsZXMpCgkJZGVsZXRlW10gcHVjaGFycnVsZXM7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICAgIEVDb2xsYXRpb25TdHJlbmd0aCBjb2xsYXRpb25TdHJlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSA6IGRhdGFJc093bmVkKEZBTFNFKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuOwoKICBpbnQzMl90IGxlbmd0aCA9IHJ1bGVzLmxlbmd0aCgpOwoKCVVDaGFyIHVjaGFycnVsZXNbU1RBQ0tfQlVGRkVSX0xFTkdUSF9dOwoJVUNoYXIgKnB1Y2hhcnJ1bGVzID0gdWNoYXJydWxlczsKCQogIGlmIChsZW5ndGggPj0gU1RBQ0tfQlVGRkVSX0xFTkdUSF8pCgkJcHVjaGFycnVsZXMgPSBuZXcgVUNoYXJbbGVuZ3RoICsgMV07CgkKCXJ1bGVzLmV4dHJhY3QoMCwgbGVuZ3RoLCBwdWNoYXJydWxlcyk7CiAgcHVjaGFycnVsZXNbbGVuZ3RoXSA9IDA7CgogIFVDb2xsYXRpb25TdHJlbmd0aCBzdHJlbmd0aCA9IGdldFVDb2xsYXRpb25TdHJlbmd0aChjb2xsYXRpb25TdHJlbmd0aCk7CiAgVU5vcm1hbGl6YXRpb25Nb2RlIG1vZGUgPSBOb3JtYWxpemVyOjpnZXRVTm9ybWFsaXphdGlvbk1vZGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY29tcG9zaXRpb25Nb2RlLCBzdGF0dXMpOwogIHVjb2xsYXRvciA9IHVjb2xfb3BlblJ1bGVzKHB1Y2hhcnJ1bGVzLCBsZW5ndGgsIG1vZGUsIHN0cmVuZ3RoLCAmc3RhdHVzKTsKICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpCiAgewogICAgY29uc3QgVUNoYXIgKnIgPSB1Y29sX2dldFJ1bGVzKHVjb2xsYXRvciwgJmxlbmd0aCk7CiAgICB1cnVsZXN0cmluZyA9IG5ldyBVbmljb2RlU3RyaW5nKHIsIGxlbmd0aCk7CiAgICBkYXRhSXNPd25lZCA9IFRSVUU7CiAgfQoKCWlmIChwdWNoYXJydWxlcyAhPSB1Y2hhcnJ1bGVzKQoJCWRlbGV0ZVtdIHB1Y2hhcnJ1bGVzOwp9CgoKCi8qIFJ1bGVCYXNlZENvbGxhdG9yIHB1YmxpYyBkZXN0cnVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpSdWxlQmFzZWRDb2xsYXRvcjo6flJ1bGVCYXNlZENvbGxhdG9yKCkKewogIGlmIChkYXRhSXNPd25lZCkKICB7CiAgICB1Y29sX2Nsb3NlKHVjb2xsYXRvcik7CiAgICBkZWxldGUgdXJ1bGVzdHJpbmc7CiAgfQogIHVjb2xsYXRvciA9IE5VTEw7Cn0KCi8qIFJ1bGVCYXNlQ29sbGF0b3IgcHVibGljIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpVQm9vbCBSdWxlQmFzZWRDb2xsYXRvcjo6b3BlcmF0b3I9PShjb25zdCBDb2xsYXRvciYgdGhhdCkgY29uc3QKewogIC8qIG9ubHkgY2hlY2tzIGZvciBhZGRyZXNzIGVxdWFscyBoZXJlICovCiAgaWYgKENvbGxhdG9yOjpvcGVyYXRvcj09KHRoYXQpKQogICAgcmV0dXJuIFRSVUU7CiAgICAKICBpZiAoZ2V0RHluYW1pY0NsYXNzSUQoKSAhPSB0aGF0LmdldER5bmFtaWNDbGFzc0lEKCkpCiAgICByZXR1cm4gRkFMU0U7ICAvKiBub3QgdGhlIHNhbWUgY2xhc3MgKi8KICAgICAgIAogIFJ1bGVCYXNlZENvbGxhdG9yJiB0aGF0QWxpYXMgPSAoUnVsZUJhc2VkQ29sbGF0b3ImKXRoYXQ7CgogIC8qCiAgc3lud2VlIDogb3JnaW5hbCBjb2RlIGRvZXMgbm90IGNoZWNrIGZvciBkYXRhIGNvbXBhdGliaWxpdHkKICAqLwogIGlmICh1Y29sbGF0b3IgIT0gdGhhdEFsaWFzLnVjb2xsYXRvcikKICAgIHJldHVybiBGQUxTRTsKICAgIAogIHJldHVybiBUUlVFOwp9CgpSdWxlQmFzZWRDb2xsYXRvciYgUnVsZUJhc2VkQ29sbGF0b3I6Om9wZXJhdG9yPSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yJiB0aGF0KQp7CiAgaWYgKHRoaXMgIT0gJnRoYXQpCiAgewogICAgaWYgKGRhdGFJc093bmVkKQogICAgewogICAgICB1Y29sX2Nsb3NlKHVjb2xsYXRvcik7CiAgICAgIHVjb2xsYXRvciA9IE5VTEw7CiAgICAgIGRlbGV0ZSB1cnVsZXN0cmluZzsKICAgIH0KICAgIAogICAgZGF0YUlzT3duZWQgPSBGQUxTRTsKICAgIHVjb2xsYXRvciA9IHRoYXQudWNvbGxhdG9yOwogICAgdXJ1bGVzdHJpbmcgPSB0aGF0LnVydWxlc3RyaW5nOwogIH0KICByZXR1cm4gKnRoaXM7Cn0KCkNvbGxhdG9yKiBSdWxlQmFzZWRDb2xsYXRvcjo6Y2xvbmUoKSBjb25zdAp7CiAgcmV0dXJuIG5ldyBSdWxlQmFzZWRDb2xsYXRvcigqdGhpcyk7Cn0KCi8qKiAKKiBDcmVhdGUgYSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Igb2JqZWN0IHRoYXQgd2lsbCBpdGVyYXRvciBvdmVyIHRoZSAKKiBlbGVtZW50cyBpbiBhIHN0cmluZywgdXNpbmcgdGhlIGNvbGxhdGlvbiBydWxlcyBkZWZpbmVkIGluIHRoaXMgCiogUnVsZUJhc2VkQ29sbGF0b3IKKi8KQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlKSBjb25zdAp7CiAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yICpyZXN1bHQgPSBuZXcgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKHNvdXJjZSwgdGhpcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CiAgCiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuIE5VTEw7CiAgICAKICByZXR1cm4gcmVzdWx0Owp9CgovKiogCiogQ3JlYXRlIGEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIG9iamVjdCB0aGF0IHdpbGwgaXRlcmF0b3Igb3ZlciB0aGUgCiogZWxlbWVudHMgaW4gYSBzdHJpbmcsIHVzaW5nIHRoZSBjb2xsYXRpb24gcnVsZXMgZGVmaW5lZCBpbiB0aGlzIAoqIFJ1bGVCYXNlZENvbGxhdG9yCiovCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciogUnVsZUJhc2VkQ29sbGF0b3I6OmNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgQ2hhcmFjdGVySXRlcmF0b3ImIHNvdXJjZSkgY29uc3QKewogIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciAqcmVzdWx0ID0gbmV3IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihzb3VyY2UsIHRoaXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMpOwogIAogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHJldHVybiBOVUxMOwogICAgCiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIAoqIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGNvbGxhdG9yJ3MgcnVsZXMuIFRoZSBzdHJpbmcgY2FuIAoqIGxhdGVyIGJlIHBhc3NlZCB0byB0aGUgY29uc3RydWN0b3IgdGhhdCB0YWtlcyBhIFVuaWNvZGVTdHJpbmcgYXJndW1lbnQsIAoqIHdoaWNoIHdpbGwgY29uc3RydWN0IGEgY29sbGF0b3IgdGhhdCdzIGZ1bmN0aW9uYWxseSBpZGVudGljYWwgdG8gdGhpcyBvbmUuIAoqIFlvdSBjYW4gYWxzbyBhbGxvdyB1c2VycyB0byBlZGl0IHRoZSBzdHJpbmcgaW4gb3JkZXIgdG8gY2hhbmdlIHRoZSBjb2xsYXRpb24gCiogZGF0YSwgb3IgeW91IGNhbiBwcmludCBpdCBvdXQgZm9yIGluc3BlY3Rpb24sIG9yIHdoYXRldmVyLgoqLwpjb25zdCBVbmljb2RlU3RyaW5nJiBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0UnVsZXMoKSBjb25zdAp7CiAgcmV0dXJuICgqdXJ1bGVzdHJpbmcpOwp9CgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGxlbmd0aCkgY29uc3QKewogIFVuaWNvZGVTdHJpbmcgc291cmNlX3RvZ287CiAgVW5pY29kZVN0cmluZyB0YXJnZXRfdG9nbzsKICBVVGV4dE9mZnNldCBiZWdpbj0wOwoKICBzb3VyY2UuZXh0cmFjdChiZWdpbiwgdXBydl9taW4obGVuZ3RoLHNvdXJjZS5sZW5ndGgoKSksIHNvdXJjZV90b2dvKTsKICB0YXJnZXQuZXh0cmFjdChiZWdpbiwgdXBydl9taW4obGVuZ3RoLHRhcmdldC5sZW5ndGgoKSksIHRhcmdldF90b2dvKTsKICByZXR1cm4gY29tcGFyZShzb3VyY2VfdG9nbywgdGFyZ2V0X3RvZ28pOwp9CgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoY29uc3QgVUNoYXIqIHNvdXJjZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDaGFyKiB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHRhcmdldExlbmd0aCkgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdAp7CiAgcmV0dXJuIGdldEVDb21wYXJpc29uUmVzdWx0KHVjb2xfc3RyY29sbCh1Y29sbGF0b3IsIHNvdXJjZSwgc291cmNlTGVuZ3RoLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQsIHRhcmdldExlbmd0aCkpOwp9CgovKioKKiBDb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nIHRoaXMgY29sbGF0b3IKKi8KQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IFJ1bGVCYXNlZENvbGxhdG9yOjpjb21wYXJlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRhcmdldCkgY29uc3QKewogIFVDaGFyIHVTc3RhcnRbU1RBQ0tfQlVGRkVSX0xFTkdUSF9dOwoJVUNoYXIgdVRzdGFydFtTVEFDS19CVUZGRVJfTEVOR1RIX107CglVQ2hhciAqdVNvdXJjZSA9IHVTc3RhcnQ7CglVQ2hhciAqdVRhcmdldCA9IHVUc3RhcnQ7Cgl1aW50MzJfdCBzb3VyY2VMZW4gPSBzb3VyY2UubGVuZ3RoKCk7Cgl1aW50MzJfdCB0YXJnZXRMZW4gPSB0YXJnZXQubGVuZ3RoKCk7CgoJaWYoc291cmNlTGVuID49IFNUQUNLX0JVRkZFUl9MRU5HVEhfKQoJCXVTb3VyY2UgPSBuZXcgVUNoYXJbc291cmNlTGVuKzFdOwoJCglpZih0YXJnZXRMZW4gPj0gU1RBQ0tfQlVGRkVSX0xFTkdUSF8pCgkJdVRhcmdldCA9IG5ldyBVQ2hhclt0YXJnZXRMZW4rMV07CgkKICBzb3VyY2UuZXh0cmFjdCgwLCBzb3VyY2VMZW4sIHVTb3VyY2UpOwogIHVTb3VyY2Vbc291cmNlTGVuXSA9IDA7CiAgdGFyZ2V0LmV4dHJhY3QoMCwgdGFyZ2V0TGVuLCB1VGFyZ2V0KTsKICB1VGFyZ2V0W3RhcmdldExlbl0gPSAwOwoJRUNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gY29tcGFyZSh1U291cmNlLCBzb3VyY2VMZW4sIHVUYXJnZXQsIHRhcmdldExlbik7CgoJaWYodVNzdGFydCAhPSB1U291cmNlKQoJCWRlbGV0ZVtdIHVTb3VyY2U7CgkKCWlmKHVUc3RhcnQgIT0gdVRhcmdldCkKCQlkZWxldGVbXSB1VGFyZ2V0OwoJCglyZXR1cm4gcmVzdWx0Owp9CgovKioKKiBSZXRyaWV2ZSBhIGNvbGxhdGlvbiBrZXkgZm9yIHRoZSBzcGVjaWZpZWQgc3RyaW5nLiBUaGUga2V5IGNhbiBiZSBjb21wYXJlZCAKKiB3aXRoIG90aGVyIGNvbGxhdGlvbiBrZXlzIHVzaW5nIGEgYml0d2lzZSBjb21wYXJpc29uIChlLmcuIG1lbWNtcCkgdG8gZmluZCAKKiB0aGUgb3JkZXJpbmcgb2YgdGhlaXIgcmVzcGVjdGl2ZSBzb3VyY2Ugc3RyaW5ncy4gVGhpcyBpcyBoYW5keSB3aGVuIGRvaW5nIGEgCiogc29ydCwgd2hlcmUgZWFjaCBzb3J0IGtleSBtdXN0IGJlIGNvbXBhcmVkIG1hbnkgdGltZXMuCioKKiBUaGUgYmFzaWMgYWxnb3JpdGhtIGhlcmUgaXMgdG8gZmluZCBhbGwgb2YgdGhlIGNvbGxhdGlvbiBlbGVtZW50cyBmb3IgZWFjaAoqIGNoYXJhY3RlciBpbiB0aGUgc291cmNlIHN0cmluZywgY29udmVydCB0aGVtIHRvIGFuIEFTQ0lJIHJlcHJlc2VudGF0aW9uLCBhbmQgCiogcHV0IHRoZW0gaW50byB0aGUgY29sbGF0aW9uIGtleS4gIEJ1dCBpdCdzIHRyaWNraWVyIHRoYW4gdGhhdC4gRWFjaCAKKiBjb2xsYXRpb24gZWxlbWVudCBpbiBhIHN0cmluZyBoYXMgdGhyZWUgY29tcG9uZW50czogcHJpbWFyeSAoJ0EnIHZzICdCJyksIAoqIHNlY29uZGFyeSAoJ3UnIHZzICf8JyksIGFuZCB0ZXJ0aWFyeSAoJ0EnIHZzICdhJyksIGFuZCBhIHByaW1hcnkgZGlmZmVyZW5jZQoqIGF0IHRoZSBlbmQgb2YgYSBzdHJpbmcgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIGEgc2Vjb25kYXJ5IG9yIHRlcnRpYXJ5IAoqIGRpZmZlcmVuY2UgZWFybGllciBpbiB0aGUgc3RyaW5nLgoqCiogVG8gYWNjb3VudCBmb3IgdGhpcywgd2UgcHV0IGFsbCBvZiB0aGUgcHJpbWFyeSBvcmRlcnMgYXQgdGhlIGJlZ2lubmluZyBvZiAKKiB0aGUgc3RyaW5nLCBmb2xsb3dlZCBieSB0aGUgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBvcmRlcnMuIEVhY2ggc2V0IG9mIAoqIG9yZGVycyBpcyB0ZXJtaW5hdGVkIGJ5IG51bGxzIHNvIHRoYXQgYSBrZXkgZm9yIGEgc3RyaW5nIHdoaWNoIGlzIGEgaW5pdGlhbCAKKiBzdWJzdHJpbmcgb2YgYW5vdGhlciBrZXkgd2lsbCBjb21wYXJlIGxlc3Mgd2l0aG91dCBhbnkgc3BlY2lhbCBjYXNlLgoqCiogSGVyZSdzIGEgaHlwb3RoZXRpY2FsIGV4YW1wbGUsIHdpdGggdGhlIGNvbGxhdGlvbiBlbGVtZW50IHJlcHJlc2VudGVkIGFzIGEgCiogdGhyZWUtZGlnaXQgbnVtYmVyLCBvbmUgZGlnaXQgZm9yIHByaW1hcnksIG9uZSBmb3Igc2Vjb25kYXJ5LCBldGMuCioKKiBTdHJpbmc6ICAgICAgICAgICAgICBBICAgICBhICAgICBCICAgIMkKKiBDb2xsYXRpb24gRWxlbWVudHM6IDEwMSAgIDEwMCAgIDIwMSAgNTExCiogQ29sbGF0aW9uIEtleTogICAgICAxMTI1PG51bGw+MDAwMTxudWxsPjEwMTE8bnVsbD4KKgoqIFRvIG1ha2UgdGhpbmdzIGV2ZW4gdHJpY2tpZXIsIHNlY29uZGFyeSBkaWZmZXJlbmNlcyAoYWNjZW50IG1hcmtzKSBhcmUgCiogY29tcGFyZWQgc3RhcnRpbmcgYXQgdGhlICplbmQqIG9mIHRoZSBzdHJpbmcgaW4gbGFuZ3VhZ2VzIHdpdGggRnJlbmNoIAoqIHNlY29uZGFyeSBvcmRlcmluZy4gQnV0IHdoZW4gY29tcGFyaW5nIHRoZSBhY2NlbnQgbWFya3Mgb24gYSBzaW5nbGUgYmFzZSAKKiBjaGFyYWN0ZXIsIHRoZXkgYXJlIGNvbXBhcmVkIGZyb20gdGhlIGJlZ2lubmluZy4gVG8gaGFuZGxlIHRoaXMsIHdlIHJldmVyc2UgCiogYWxsIG9mIHRoZSBhY2NlbnRzIHRoYXQgYmVsb25nIHRvIGVhY2ggYmFzZSBjaGFyYWN0ZXIsIHRoZW4gd2UgcmV2ZXJzZSB0aGUgCiogZW50aXJlIHN0cmluZyBvZiBzZWNvbmRhcnkgb3JkZXJpbmdzIGF0IHRoZSBlbmQuCiovCkNvbGxhdGlvbktleSYgUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbGxhdGlvbktleSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiBzb3J0a2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QKewoJVUNoYXIgc1N0YXJ0W1NUQUNLX0JVRkZFUl9MRU5HVEhfXTsKCVVDaGFyICp1U291cmNlID0gc1N0YXJ0OwoJdWludDMyX3Qgc291cmNlTGVuID0gc291cmNlLmxlbmd0aCgpOwoKCWlmKHNvdXJjZUxlbiA+PSBTVEFDS19CVUZGRVJfTEVOR1RIXykKCQl1U291cmNlID0gbmV3IFVDaGFyW3NvdXJjZUxlbisxXTsKCQogIHNvdXJjZS5leHRyYWN0KDAsIHNvdXJjZUxlbiwgdVNvdXJjZSk7CiAgdVNvdXJjZVtzb3VyY2VMZW5dID0gMDsKCUNvbGxhdGlvbktleSYgcmVzdWx0ID0gZ2V0Q29sbGF0aW9uS2V5KHVTb3VyY2UsIHNvdXJjZUxlbiwgc29ydGtleSwgc3RhdHVzKTsKCWlmKHNTdGFydCAhPSB1U291cmNlKQoJCWRlbGV0ZVtdIHVTb3VyY2U7CgoJcmV0dXJuIHJlc3VsdDsKfQoKQ29sbGF0aW9uS2V5JiBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29sbGF0aW9uS2V5KGNvbnN0IFVDaGFyKiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYgc29ydGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICB7CiAgICBzdGF0dXMgPSBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1I7CiAgICByZXR1cm4gc29ydGtleS5zZXRUb0JvZ3VzKCk7CiAgfQogICAgCiAgaWYgKCghc291cmNlKSB8fCAoc291cmNlTGVuID09IDApKQogICAgcmV0dXJuIHNvcnRrZXkucmVzZXQoKTsKCiAgLyogCiAgKiBoYXZlIHRvIHVzZSBtYWxsb2MsIGxvd2VzdCBkZW5vbWluYXRpb24sIHNpbmNlIGFkb3B0IGNhbiBiZSB1c2VkIGJ5IAogICogYSBjIHJldHVybiB2YWx1ZS4KICAqLwogIHVpbnQ4X3QgKnJlc3VsdCA9ICh1aW50OF90ICopdXBydl9tYWxsb2MoVUNPTF9NQVhfQlVGRkVSICogc2l6ZW9mKHVpbnQ4X3QpKTsKICB1aW50OF90IHJlc0xlbiA9IHVjb2xfZ2V0U29ydEtleSh1Y29sbGF0b3IsIHNvdXJjZSwgc291cmNlTGVuLCByZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNPTF9NQVhfQlVGRkVSKTsKICBzb3J0a2V5LmFkb3B0KHJlc3VsdCwgcmVzTGVuKTsKICAKICByZXR1cm4gc29ydGtleTsKfQoKLyoqCiAqIFJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZXMgdGhhdCBlbmQgd2l0aCB0aGUgCiAqIHNwZWNpZmllZCBjb21wYXJpc29uIG9yZGVyLgogKiBAcGFyYW0gb3JkZXIgYSBjb2xsYXRpb24gb3JkZXIgcmV0dXJuZWQgYnkgcHJldmlvdXMgb3IgbmV4dC4KICogQHJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXVlbmNlcyBlbmRpbmcgd2l0aCB0aGUgCiAqICAgICAgICAgc3BlY2lmaWVkIG9yZGVyIG9yIDEgaWYgY29sbGF0aW9uIG9yZGVyIGRvZXMgbm90IG9jY3VyIGF0IHRoZSBlbmQgb2YgYW55IAogKiAgICAgICAgIGV4cGFuc2lvbiBzZXF1ZW5jZS4KICogQHNlZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IjZ2V0TWF4RXhwYW5zaW9uCiAqLwppbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3QKewogIHVpbnQ4X3QgcmVzdWx0OwogIFVDT0xfR0VUTUFYRVhQQU5TSU9OKHVjb2xsYXRvciwgKHVpbnQzMl90KW9yZGVyLCByZXN1bHQpOwogIHJldHVybiByZXN1bHQ7Cn0KCnVpbnQ4X3QqIFJ1bGVCYXNlZENvbGxhdG9yOjpjbG9uZVJ1bGVEYXRhKGludDMyX3QgJmxlbmd0aCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpCnsKICByZXR1cm4gdWNvbF9jbG9uZVJ1bGVEYXRhKHVjb2xsYXRvciwgJmxlbmd0aCwgJnN0YXR1cyk7Cn0KCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OnNldEF0dHJpYnV0ZShVQ29sQXR0cmlidXRlIGF0dHIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNvbEF0dHJpYnV0ZVZhbHVlIHZhbHVlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cykgCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICByZXR1cm47CiAgdWNvbF9zZXRBdHRyaWJ1dGUodWNvbGxhdG9yLCBhdHRyLCB2YWx1ZSwgJnN0YXR1cyk7Cn0KClVDb2xBdHRyaWJ1dGVWYWx1ZSBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0QXR0cmlidXRlKFVDb2xBdHRyaWJ1dGUgYXR0ciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cykgCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICByZXR1cm4gVUNPTF9ERUZBVUxUOwogIHJldHVybiB1Y29sX2dldEF0dHJpYnV0ZSh1Y29sbGF0b3IsIGF0dHIsICZzdGF0dXMpOwp9CgpDb2xsYXRvciogUnVsZUJhc2VkQ29sbGF0b3I6OnNhZmVDbG9uZSh2b2lkKSAKewogIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIFVDb2xsYXRvciAqdWNvbCA9IHVjb2xfc2FmZUNsb25lKHVjb2xsYXRvciwgTlVMTCwgMCwgJmludFN0YXR1cyk7CiAgaWYgKFVfRkFJTFVSRShpbnRTdGF0dXMpKQogICAgcmV0dXJuIE5VTEw7CiAgaW50MzJfdCBsZW5ndGggPSAwOwogIFVuaWNvZGVTdHJpbmcgKnIgPSBuZXcgVW5pY29kZVN0cmluZyh1Y29sX2dldFJ1bGVzKHVjb2xsYXRvciwgJmxlbmd0aCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGgpOwogIFJ1bGVCYXNlZENvbGxhdG9yICpyZXN1bHQgPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3IodWNvbCwgcik7CiAgcmVzdWx0LT5kYXRhSXNPd25lZCA9IFRSVUU7CiAgcmV0dXJuIHJlc3VsdDsKfQoKQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IFJ1bGVCYXNlZENvbGxhdG9yOjpjb21wYXJlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9yd2FyZENoYXJhY3Rlckl0ZXJhdG9yICZzb3VyY2UsCgkJCQkJCQkJCQkJICAgICAgICAgICAgICAgICAgICAgICAgRm9yd2FyZENoYXJhY3Rlckl0ZXJhdG9yICZ0YXJnZXQpIAp7CiAgcmV0dXJuIGdldEVDb21wYXJpc29uUmVzdWx0KAogICAgdWNvbF9zdHJjb2xsaW5jKHVjb2xsYXRvciwgZm9yd2FyZENoYXJJdGVyYXRvckdsdWUsICZzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgIGZvcndhcmRDaGFySXRlcmF0b3JHbHVlLCAmdGFyZ2V0KSk7Cn0KCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmdldFNvcnRLZXkoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90ICpyZXN1bHQsIGludDMyX3QgcmVzdWx0TGVuZ3RoKSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCAKewoJVUNoYXIgc1N0YXJ0W1NUQUNLX0JVRkZFUl9MRU5HVEhfXTsKCVVDaGFyICp1U291cmNlID0gc1N0YXJ0OwoJdWludDMyX3Qgc291cmNlTGVuID0gc291cmNlLmxlbmd0aCgpOwoJaWYoc291cmNlTGVuID49IFNUQUNLX0JVRkZFUl9MRU5HVEhfKQoJCXVTb3VyY2UgPSBuZXcgVUNoYXJbc291cmNlTGVuKzFdOwoJCiAgc291cmNlLmV4dHJhY3QoMCwgc291cmNlTGVuLCB1U291cmNlKTsKICB1U291cmNlW3NvdXJjZUxlbl0gPSAwOwoKCXVpbnQ4X3QgcmVzTGVuID0gdWNvbF9nZXRTb3J0S2V5KHVjb2xsYXRvciwgdVNvdXJjZSwgc291cmNlTGVuLCByZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0TGVuZ3RoKTsKCWlmKHNTdGFydCAhPSB1U291cmNlKQoJCWRlbGV0ZVtdIHVTb3VyY2U7CgoJcmV0dXJuIHJlc0xlbjsKfQoKaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0U29ydEtleShjb25zdCBVQ2hhciAqc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbmd0aCwgdWludDhfdCAqcmVzdWx0LAoJCQkJCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgcmVzdWx0TGVuZ3RoKSBjb25zdCAKewoJcmV0dXJuIHVjb2xfZ2V0U29ydEtleSh1Y29sbGF0b3IsIHNvdXJjZSwgc291cmNlTGVuZ3RoLCByZXN1bHQsIHJlc3VsdExlbmd0aCk7Cn0KCkNvbGxhdG9yOjpFQ29sbGF0aW9uU3RyZW5ndGggUnVsZUJhc2VkQ29sbGF0b3I6OmdldFN0cmVuZ3RoKHZvaWQpIGNvbnN0CnsKICBVRXJyb3JDb2RlIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKICByZXR1cm4gZ2V0RUNvbGxhdGlvblN0cmVuZ3RoKHVjb2xfZ2V0QXR0cmlidXRlKHVjb2xsYXRvciwgVUNPTF9TVFJFTkdUSCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaW50U3RhdHVzKSk7Cn0KCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OnNldFN0cmVuZ3RoKEVDb2xsYXRpb25TdHJlbmd0aCBuZXdTdHJlbmd0aCkKewogIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIFVDb2xsYXRpb25TdHJlbmd0aCBzdHJlbmd0aCA9IGdldFVDb2xsYXRpb25TdHJlbmd0aChuZXdTdHJlbmd0aCk7CiAgdWNvbF9zZXRBdHRyaWJ1dGUodWNvbGxhdG9yLCBVQ09MX1NUUkVOR1RILCBzdHJlbmd0aCwgJmludFN0YXR1cyk7Cn0KCi8qKiAKKiBDcmVhdGUgYSBoYXNoIGNvZGUgZm9yIHRoaXMgY29sbGF0aW9uLiBKdXN0IGhhc2ggdGhlIG1haW4gcnVsZSB0YWJsZSAtLSB0aGF0IAoqIHNob3VsZCBiZSBnb29kIGVub3VnaCBmb3IgYWxtb3N0IGFueSB1c2UuCiovCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6Omhhc2hDb2RlKCkgY29uc3QKewogIGludDMyX3QgbGVuZ3RoOwogIGNvbnN0IFVDaGFyICpydWxlcyA9IHVjb2xfZ2V0UnVsZXModWNvbGxhdG9yLCAmbGVuZ3RoKTsKICByZXR1cm4gdWhhc2hfaGFzaFVDaGFyc04ocnVsZXMsIGxlbmd0aCk7Cn0KCi8qKgoqIFNldCB0aGUgZGVjb21wb3NpdGlvbiBtb2RlIG9mIHRoZSBDb2xsYXRvciBvYmplY3QuIHN1Y2Nlc3MgaXMgZXF1YWwgdG8gCiogVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SIGlmIGVycm9yIG9jY3Vycy4KKiBAcGFyYW0gdGhlIG5ldyBkZWNvbXBvc2l0aW9uIG1vZGUKKiBAc2VlIENvbGxhdG9yI2dldERlY29tcG9zaXRpb24KKi8Kdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6c2V0RGVjb21wb3NpdGlvbihOb3JtYWxpemVyOjpFTW9kZSAgbW9kZSkKewogIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIHVjb2xfc2V0Tm9ybWFsaXphdGlvbih1Y29sbGF0b3IsIE5vcm1hbGl6ZXI6OmdldFVOb3JtYWxpemF0aW9uTW9kZShtb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMpKTsKfQoKLyoqCiogR2V0IHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgb2YgdGhlIENvbGxhdG9yIG9iamVjdC4KKiBAcmV0dXJuIHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUKKiBAc2VlIENvbGxhdG9yI3NldERlY29tcG9zaXRpb24KKi8KTm9ybWFsaXplcjo6RU1vZGUgUnVsZUJhc2VkQ29sbGF0b3I6OmdldERlY29tcG9zaXRpb24odm9pZCkgY29uc3QKewogIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIHJldHVybiBOb3JtYWxpemVyOjpnZXROb3JtYWxpemVyRU1vZGUodWNvbF9nZXROb3JtYWxpemF0aW9uKHVjb2xsYXRvciksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7Cn0KCi8vIFJ1bGVCYXNlQ29sbGF0b3JOZXcgcHJpdmF0ZSBjb25zdHJ1Y3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoKSA6IGRhdGFJc093bmVkKEZBTFNFKSwgdWNvbGxhdG9yKDApCnsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKFVDb2xsYXRvciAqY29sbGF0b3IsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyAqcnVsZSkgOiBkYXRhSXNPd25lZChGQUxTRSkKewogIHVjb2xsYXRvciA9IGNvbGxhdG9yOwogIHVydWxlc3RyaW5nID0gcnVsZTsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IExvY2FsZSYgZGVzaXJlZExvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgOiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFJc093bmVkKEZBTFNFKSwgdWNvbGxhdG9yKDApCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICByZXR1cm47CgogIC8qIAogIFRyeSB0byBsb2FkLCBpbiBvcmRlcjoKICAgMS4gVGhlIGRlc2lyZWQgbG9jYWxlJ3MgY29sbGF0aW9uLgogICAyLiBBIGZhbGxiYWNrIG9mIHRoZSBkZXNpcmVkIGxvY2FsZS4KICAgMy4gVGhlIGRlZmF1bHQgbG9jYWxlJ3MgY29sbGF0aW9uLgogICA0LiBBIGZhbGxiYWNrIG9mIHRoZSBkZWZhdWx0IGxvY2FsZS4KICAgNS4gVGhlIGRlZmF1bHQgY29sbGF0aW9uIHJ1bGVzLCB3aGljaCBjb250YWlucyBlbl9VUyBjb2xsYXRpb24gcnVsZXMuCgogICBUbyByZWl0ZXJhdGUsIHdlIHRyeToKICAgU3BlY2lmaWM6CiAgICBsYW5ndWFnZStjb3VudHJ5K3ZhcmlhbnQKICAgIGxhbmd1YWdlK2NvdW50cnkKICAgIGxhbmd1YWdlCiAgIERlZmF1bHQ6CiAgICBsYW5ndWFnZStjb3VudHJ5K3ZhcmlhbnQKICAgIGxhbmd1YWdlK2NvdW50cnkKICAgIGxhbmd1YWdlCiAgIFJvb3Q6IChha2EgREVGQVVMVFJVTEVTKQogICBzdGVwcyAxLTUgYXJlIGhhbmRsZWQgYnkgcmVzb3VyY2UgYnVuZGxlIGZhbGxiYWNrIG1lY2hhbmlzbS4gCiAgIGhvd2V2ZXIsIGluIGEgdmVyeSB1bnByb2JhYmxlIHNpdHVhdGlvbiB0aGF0IG5vIHJlc291cmNlIGJ1bmRsZQogICBkYXRhIGV4aXN0cywgc3RlcCA1IGlzIHJlcGVhdGVkIHdpdGggaGFyZGNvZGVkIGRlZmF1bHQgcnVsZXMuCiAgKi8KCiAgc2V0VUNvbGxhdG9yKGRlc2lyZWRMb2NhbGUsIHN0YXR1cyk7CgogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgCiAgewogICAgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAKICAgIHNldFVDb2xsYXRvcihSZXNvdXJjZUJ1bmRsZTo6a0RlZmF1bHRGaWxlbmFtZSwgc3RhdHVzKTsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgCiAgICB7CiAgICAgIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKCiAgICAgIGlmIChzdGF0dXMgPT0gVV9aRVJPX0VSUk9SKQogICAgICAgIHN0YXR1cyA9IFVfVVNJTkdfREVGQVVMVF9FUlJPUjsKICAgICAgCiAgICAgIGlmIChzdGF0dXMgPT0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUikKICAgICAgICByZXR1cm47CiAgICB9CiAgfQoKICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpCiAgewogICAgaW50MzJfdCBsZW5ndGg7CiAgICBjb25zdCBVQ2hhciAqciA9IHVjb2xfZ2V0UnVsZXModWNvbGxhdG9yLCAmbGVuZ3RoKTsKICAgIHVydWxlc3RyaW5nID0gbmV3IFVuaWNvZGVTdHJpbmcociwgbGVuZ3RoKTsKICAgIGRhdGFJc093bmVkID0gVFJVRTsKICB9CiAgCiAgcmV0dXJuOwp9CgovKiBSdWxlQmFzZWRDb2xsYXRvciBwcml2YXRlIGRhdGEgbWVtYmVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKLyogbmVlZCBsb29rIHVwIGluIC5jb21taXQoKSAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDSEFSSU5ERVggPSAweDcwMDAwMDAwOyAgICAgICAgICAgICAKLyogRXhwYW5kIGluZGV4IGZvbGxvd3MgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6RVhQQU5EQ0hBUklOREVYID0gMHg3RTAwMDAwMDsgICAgICAgCi8qIGNvbnRyYWN0IGluZGV4ZXMgZm9sbG93cyAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDT05UUkFDVENIQVJJTkRFWCA9IDB4N0YwMDAwMDA7ICAgICAKLyogdW5tYXBwZWQgY2hhcmFjdGVyIHZhbHVlcyAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpVTk1BUFBFRCA9IDB4RkZGRkZGRkY7ICAgICAgICAgICAgICAKLyogcHJpbWFyeSBzdHJlbmd0aCBpbmNyZW1lbnQgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAxMDAwMDsgCi8qIHNlY29uZGFyeSBzdHJlbmd0aCBpbmNyZW1lbnQgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJJTkNSRU1FTlQgPSAweDAwMDAwMTAwOwovKiB0ZXJ0aWFyeSBzdHJlbmd0aCBpbmNyZW1lbnQgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6VEVSVElBUllPUkRFUklOQ1JFTUVOVCA9IDB4MDAwMDAwMDE7Ci8qIG1hc2sgb2ZmIGFueXRoaW5nIGJ1dCBwcmltYXJ5IG9yZGVyICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllPUkRFUk1BU0sgPSAweGZmZmYwMDAwOyAgICAgIAovKiBtYXNrIG9mZiBhbnl0aGluZyBidXQgc2Vjb25kYXJ5IG9yZGVyICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSTUFTSyA9IDB4MDAwMGZmMDA7ICAgIAovKiBtYXNrIG9mZiBhbnl0aGluZyBidXQgdGVydGlhcnkgb3JkZXIgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6VEVSVElBUllPUkRFUk1BU0sgPSAweDAwMDAwMGZmOyAgICAgCi8qIG1hc2sgb2ZmIGlnbm9yYWJsZSBjaGFyIG9yZGVyICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OklHTk9SQUJMRU1BU0sgPSAweDAwMDBmZmZmOyAgICAgICAgIAovKiB1c2Ugb25seSB0aGUgcHJpbWFyeSBkaWZmZXJlbmNlICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllESUZGRVJFTkNFT05MWSA9IDB4ZmZmZjAwMDA7IAovKiB1c2Ugb25seSB0aGUgcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IGRpZmZlcmVuY2UgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZRElGRkVSRU5DRU9OTFkgPSAweGZmZmZmZjAwOyAgCi8qIHByaW1hcnkgb3JkZXIgc2hpZnQgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSU0hJRlQgPSAxNjsgICAgICAgICAgICAgCi8qIHNlY29uZGFyeSBvcmRlciBzaGlmdCAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUlNISUZUID0gODsgICAgICAgICAgICAKLyogc3RhcnRpbmcgdmFsdWUgZm9yIGNvbGxhdGlvbiBlbGVtZW50cyAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDT0xFTEVNRU5UU1RBUlQgPSAweDAyMDIwMjAyOyAgICAgICAKLyogdGVzdGluZyBtYXNrIGZvciBwcmltYXJ5IGxvdyBlbGVtZW50ICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllMT1daRVJPTUFTSyA9IDB4MDBGRjAwMDA7ICAgIAovKiByZXNldGluZyB2YWx1ZSBmb3Igc2Vjb25kYXJpZXMgYW5kIHRlcnRpYXJpZXMgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UkVTRVRTRUNPTkRBUllURVJUSUFSWSA9IDB4MDAwMDAyMDI7Ci8qIHJlc2V0aW5nIHZhbHVlIGZvciB0ZXJ0aWFyaWVzICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlJFU0VUVEVSVElBUlkgPSAweDAwMDAwMDAyOyAgICAgICAgIAoKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUlHTk9SQUJMRSA9IDB4MDIwMjsKCi8qIHVuaXF1ZSBmaWxlIGlkIGZvciBwYXJpdHkgY2hlY2sgKi8KY29uc3QgaW50MTZfdCBSdWxlQmFzZWRDb2xsYXRvcjo6RklMRUlEID0gMHg1NDQzOyAgICAgICAgICAgICAgICAgICAgCi8qIGJpbmFyeSBjb2xsYXRpb24gZmlsZSBleHRlbnNpb24gKi8KY29uc3QgY2hhciogUnVsZUJhc2VkQ29sbGF0b3I6OmtGaWxlbmFtZVN1ZmZpeCA9ICIuY29sIjsgICAgICAgICAgICAgCi8qIGNsYXNzIGlkID8gVmFsdWUgaXMgaXJyZWxldmFudCAqLyAKY2hhciAgUnVsZUJhc2VkQ29sbGF0b3I6OmZnQ2xhc3NJRCA9IDA7IAoKLyogb3RoZXIgbWV0aG9kcyBub3QgYmVsb25naW5nIHRvIGFueSBjbGFzc2VzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KClVfQ0FQSSBVQ2hhciBmb3J3YXJkQ2hhckl0ZXJhdG9yR2x1ZSh2b2lkICppdGVyYXRvcikgCnsKICBGb3J3YXJkQ2hhcmFjdGVySXRlcmF0b3IgKml0ZXIgPSAoKEZvcndhcmRDaGFyYWN0ZXJJdGVyYXRvciAqKWl0ZXJhdG9yKTsKICBVQ2hhciByZXN1bHQgPSBpdGVyLT5uZXh0UG9zdEluYygpOwogIGlmIChyZXN1bHQgPT0gRm9yd2FyZENoYXJhY3Rlckl0ZXJhdG9yOjpET05FKQogICAgcmV0dXJuIDB4RkZGRjsKICBlbHNlCiAgICByZXR1cm4gcmVzdWx0Owp9Cg==