LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogQ29weXJpZ2h0IChDKSB7MTk5Ni0yMDAxfSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCi8qKgoqIEZpbGUgdGJsY29sbC5jcHAKKgoqIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICBEYXRlICAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgoqICAyLzUvOTcgICAgICBhbGl1ICAgICAgICBBZGRlZCBzdHJlYW1JbiBhbmQgc3RyZWFtT3V0IG1ldGhvZHMuICBBZGRlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciB3aGljaCByZWFkcyBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QgZnJvbQoqICAgICAgICAgICAgICAgICAgICAgICAgICBhIGJpbmFyeSBmaWxlLiAgQWRkZWQgd3JpdGVUb0ZpbGUgbWV0aG9kIHdoaWNoIHN0cmVhbXMKKiAgICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3Igb3V0IHRvIGEgYmluYXJ5IGZpbGUuICBUaGUgc3RyZWFtSW4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIHN0cmVhbU91dCBtZXRob2RzIHVzZSBpc3RyZWFtIGFuZCBvc3RyZWFtIG9iamVjdHMKKiAgICAgICAgICAgICAgICAgICAgICAgICAgaW4gYmluYXJ5IG1vZGUuCiogIDIvMTEvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIGRlY2xhcmF0aW9ucyBvdXQgb2YgZm9yIGxvb3AgaW5pdGlhbGl6ZXIuCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIE1hYyBjb21wYXRpYmlsaXR5ICNpZmRlZiBmb3IgaW9zOjpub2NyZWF0ZS4KKiAgMi8xMi85NyAgICAgYWxpdSAgICAgICAgTW9kaWZpZWQgdG8gdXNlIFRhYmxlQ29sbGF0aW9uRGF0YSBzdWItb2JqZWN0IHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIGhvbGQgaW52YXJpYW50IGRhdGEuCiogIDIvMTMvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIHNldmVyYWwgbWV0aG9kcyBpbnRvIHRoaXMgY2xhc3MgZnJvbSBDb2xsYXRpb24uCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIGEgcHJpdmF0ZSBSdWxlQmFzZWRDb2xsYXRvcihMb2NhbGUmKSBjb25zdHJ1Y3RvciwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gYmUgdXNlZCBieSBDb2xsYXRvcjo6Z2V0SW5zdGFuY2UoKS4gIEdlbmVyYWwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYW4gdXAuICBNYWRlIHVzZSBvZiBVRXJyb3JDb2RlIHZhcmlhYmxlcyBjb25zaXN0ZW50LgoqICAyLzIwLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjbG9uZSwgb3BlcmF0b3I9PSwgb3BlcmF0b3IhPSwgb3BlcmF0b3I9LCBhbmQgY29weQoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciBhbmQgZ2V0RHluYW1pY0NsYXNzSUQuCiogIDMvNS85NyAgICAgIGFsaXUgICAgICAgIENoYW5nZWQgY29tcGFjdGlvbiBjeWNsZSB0byBpbXByb3ZlIHBlcmZvcm1hbmNlLiAgV2UKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlIHRoZSBtYXhpbXVtIGFsbG93YWJsZSB2YWx1ZSB3aGljaCBpcyBrQmxvY2tDb3VudC4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgTW9kaWZpZWQgZ2V0UnVsZXMoKSB0byBsb2FkIHJ1bGVzIGR5bmFtaWNhbGx5LiAgQ2hhbmdlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RGcm9tRmlsZSgpIGNhbGwgdG8gYWNjb21vZGF0ZSB0aGlzIChhZGRlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgdG8gc3BlY2lmeSB3aGV0aGVyIGJpbmFyeSBsb2FkaW5nIGlzIHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIHRha2UgcGxhY2UpLgoqIDA1LzA2Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBtZW1vcnkgYWxsb2NhdGlvbiBlcnJvciBjaGVjay4KKiAgNi8yMC85NyAgICAgaGVsZW5hICAgICAgSmF2YSBjbGFzcyBuYW1lIGNoYW5nZS4KKiAgNi8yMy85NyAgICAgaGVsZW5hICAgICAgQWRkaW5nIGNvbW1lbnRzIHRvIG1ha2UgY29kZSBtb3JlIHJlYWRhYmxlLgoqIDA5LzAzLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjcmVhdGVDb2xsYXRpb25LZXlWYWx1ZXMoKS4KKiAwNi8yNi85OCAgICAgZXJtICAgICAgICAgQ2hhbmdlcyBmb3IgQ29sbGF0aW9uS2V5cyB1c2luZyBieXRlIGFycmF5cy4KKiAwOC8xMC85OCAgICAgZXJtICAgICAgICAgU3luY2hlZCB3aXRoIDEuMiB2ZXJzaW9uIG9mIFJ1bGVCYXNlZENvbGxhdG9yLmphdmEKKiAwNC8yMy85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBFRGVjb21wb3NpdGlvbk1vZGUsIG1lcmdlZCB3aXRoCiogICAgICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlCiogMDYvMTQvOTkgICAgIHN0ZXBoZW4gICAgIFJlbW92ZWQga1Jlc291cmNlQnVuZGxlU3VmZml4CiogMDYvMjIvOTkgICAgIHN0ZXBoZW4gICAgIEZpeGVkIGxvZ2ljIGluIGNvbnN0cnVjdEZyb21GaWxlKCkgc2luY2UgLmN0eAoqICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlcyBhcmUgbm8gbG9uZ2VyIHVzZWQuCiogMTEvMDIvOTkgICAgIGhlbGVuYSAgICAgIENvbGxhdG9yIHBlcmZvcm1hbmNlIGVuaGFuY2VtZW50cy4gIFNwZWNpYWwgY2FzZQoqICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgTk9fT1Agc2l0dWF0aW9ucy4KKiAxMS8xNy85OSAgICAgc3JsICAgICAgICAgTW9yZSBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuIElubGluZWQgc29tZSBpbnRlcm5hbCBmdW5jdGlvbnMuCiogMTIvMTUvOTkgICAgIGFsaXUgICAgICAgIFVwZGF0ZSB0byBzdXBwb3J0IFRoYWkgY29sbGF0aW9uLiAgTW92ZSBOb3JtYWxpemVySXRlcmF0b3IKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gaW1wbGVtZW50YXRpb24gZmlsZS4KKiAwMS8yOS8wMSAgICAgc3lud2VlICAgICAgTW9kaWZpZWQgaW50byBhIEMrKyB3cmFwcGVyIGNhbGxpbmcgQyBBUElzICh1Y29sLmgpCiovCgojaW5jbHVkZSAidWNvbF9pbXAuaCIKI2luY2x1ZGUgInVyZXNpbXAuaCIKI2luY2x1ZGUgInVuaWNvZGUvdGJsY29sbC5oIgojaW5jbHVkZSAidW5pY29kZS9jb2xlaXRyLmgiCiNpbmNsdWRlICJ1aGFzaC5oIgojaW5jbHVkZSAidW5pY29kZS9yZXNidW5kLmgiCiNpbmNsdWRlICJjbWVtb3J5LmgiCgovKiBwdWJsaWMgUnVsZUJhc2VkQ29sbGF0b3IgY29uc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKVV9OQU1FU1BBQ0VfQkVHSU4KCi8qKgoqIENvcHkgY29uc3RydWN0b3IKKi8KUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yJiB0aGF0KSA6CiAgICAgICAgICAgICAgQ29sbGF0b3IodGhhdCksIGRhdGFJc093bmVkKEZBTFNFKSwgdWNvbGxhdG9yKHRoYXQudWNvbGxhdG9yKSwKICAgICAgICAgICAgICB1cnVsZXN0cmluZyh0aGF0LnVydWxlc3RyaW5nKQp7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICBjb25zdHJ1Y3QocnVsZXMsCiAgICAgICAgICAgIFVDT0xfREVGQVVMVF9TVFJFTkdUSCwKICAgICAgICAgICAgVUNPTF9ERUZBVUxULAogICAgICAgICAgICBzdGF0dXMpOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIDogZGF0YUlzT3duZWQoRkFMU0UpCnsKICBjb25zdHJ1Y3QocnVsZXMsCiAgICAgICAgICAgIGdldFVDb2xsYXRpb25TdHJlbmd0aChjb2xsYXRpb25TdHJlbmd0aCksCiAgICAgICAgICAgIFVDT0xfREVGQVVMVCwKICAgICAgICAgICAgc3RhdHVzKTsKfQoKLy8gVE9ETyB0aGlzIGlzIGEgZGVwcmVjYXRlZCBjb25zdHJ1Y3RvciwgcmVtb3ZlID4yMDAyLXNlcC0zMApSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICBjb25zdHJ1Y3QocnVsZXMsCiAgICAgICAgICAgIFVDT0xfREVGQVVMVF9TVFJFTkdUSCwKICAgICAgICAgICAgKFVDb2xBdHRyaWJ1dGVWYWx1ZSlOb3JtYWxpemVyOjpnZXRVTm9ybWFsaXphdGlvbk1vZGUoZGVjb21wb3NpdGlvbk1vZGUsIHN0YXR1cyksCiAgICAgICAgICAgIHN0YXR1cyk7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDb2xBdHRyaWJ1dGVWYWx1ZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICBjb25zdHJ1Y3QocnVsZXMsCiAgICAgICAgICAgIFVDT0xfREVGQVVMVF9TVFJFTkdUSCwKICAgICAgICAgICAgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgIHN0YXR1cyk7Cn0KCi8vIFRPRE8gdGhpcyBpcyBhIGRlcHJlY2F0ZWQgY29uc3RydWN0b3IsIHJlbW92ZSA+MjAwMi1zZXAtMzAKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICAgRUNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIDogZGF0YUlzT3duZWQoRkFMU0UpCnsKICBjb25zdHJ1Y3QocnVsZXMsCiAgICAgICAgICAgIGdldFVDb2xsYXRpb25TdHJlbmd0aChjb2xsYXRpb25TdHJlbmd0aCksCiAgICAgICAgICAgIChVQ29sQXR0cmlidXRlVmFsdWUpTm9ybWFsaXplcjo6Z2V0VU5vcm1hbGl6YXRpb25Nb2RlKGRlY29tcG9zaXRpb25Nb2RlLCBzdGF0dXMpLAogICAgICAgICAgICBzdGF0dXMpOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICBVQ29sQXR0cmlidXRlVmFsdWUgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIDogZGF0YUlzT3duZWQoRkFMU0UpCnsKICBjb25zdHJ1Y3QocnVsZXMsCiAgICAgICAgICAgIGdldFVDb2xsYXRpb25TdHJlbmd0aChjb2xsYXRpb25TdHJlbmd0aCksCiAgICAgICAgICAgIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICBzdGF0dXMpOwp9Cgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3QoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNvbEF0dHJpYnV0ZVZhbHVlIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDb2xBdHRyaWJ1dGVWYWx1ZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICB1Y29sbGF0b3IgPSB1Y29sX29wZW5SdWxlcyhydWxlcy5nZXRCdWZmZXIoKSwgcnVsZXMubGVuZ3RoKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjb21wb3NpdGlvbk1vZGUsIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsICZzdGF0dXMpOwogIGlmIChVX1NVQ0NFU1Moc3RhdHVzKSkKICB7CiAgICBpbnQzMl90IGxlbmd0aDsKICAgIGNvbnN0IFVDaGFyICpyID0gdWNvbF9nZXRSdWxlcyh1Y29sbGF0b3IsICZsZW5ndGgpOwogICAgaWYgKGxlbmd0aCA+IDApIHsKICAgICAgICAvLyBhbGlhcyB0aGUgcnVsZXMgc3RyaW5nCiAgICAgICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZyhUUlVFLCByLCBsZW5ndGgpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZygpOwogICAgfQogICAgZGF0YUlzT3duZWQgPSBUUlVFOwogIH0KfQoKLyogUnVsZUJhc2VkQ29sbGF0b3IgcHVibGljIGRlc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KClJ1bGVCYXNlZENvbGxhdG9yOjp+UnVsZUJhc2VkQ29sbGF0b3IoKQp7CiAgaWYgKGRhdGFJc093bmVkKQogIHsKICAgIHVjb2xfY2xvc2UodWNvbGxhdG9yKTsKICAgIGRlbGV0ZSB1cnVsZXN0cmluZzsKICB9CiAgdWNvbGxhdG9yID0gMDsKICB1cnVsZXN0cmluZyA9IDA7Cn0KCi8qIFJ1bGVCYXNlQ29sbGF0b3IgcHVibGljIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpVQm9vbCBSdWxlQmFzZWRDb2xsYXRvcjo6b3BlcmF0b3I9PShjb25zdCBDb2xsYXRvciYgdGhhdCkgY29uc3QKewogIC8qIG9ubHkgY2hlY2tzIGZvciBhZGRyZXNzIGVxdWFscyBoZXJlICovCiAgaWYgKENvbGxhdG9yOjpvcGVyYXRvcj09KHRoYXQpKQogICAgcmV0dXJuIFRSVUU7CgogIGlmIChnZXREeW5hbWljQ2xhc3NJRCgpICE9IHRoYXQuZ2V0RHluYW1pY0NsYXNzSUQoKSkKICAgIHJldHVybiBGQUxTRTsgIC8qIG5vdCB0aGUgc2FtZSBjbGFzcyAqLwoKICBSdWxlQmFzZWRDb2xsYXRvciYgdGhhdEFsaWFzID0gKFJ1bGVCYXNlZENvbGxhdG9yJil0aGF0OwoKICAvKgogIHN5bndlZSA6IG9yZ2luYWwgY29kZSBkb2VzIG5vdCBjaGVjayBmb3IgZGF0YSBjb21wYXRpYmlsaXR5CiAgKi8KICBpZiAodWNvbGxhdG9yICE9IHRoYXRBbGlhcy51Y29sbGF0b3IpCiAgICByZXR1cm4gRkFMU0U7CgogIHJldHVybiBUUlVFOwp9CgpSdWxlQmFzZWRDb2xsYXRvciYgUnVsZUJhc2VkQ29sbGF0b3I6Om9wZXJhdG9yPShjb25zdCBSdWxlQmFzZWRDb2xsYXRvciYgdGhhdCkKewogIGlmICh0aGlzICE9ICZ0aGF0KQogIHsKICAgIGlmIChkYXRhSXNPd25lZCkKICAgIHsKICAgICAgdWNvbF9jbG9zZSh1Y29sbGF0b3IpOwogICAgICB1Y29sbGF0b3IgPSBOVUxMOwogICAgICBkZWxldGUgdXJ1bGVzdHJpbmc7CiAgICB9CgogICAgZGF0YUlzT3duZWQgPSBGQUxTRTsKICAgIHVjb2xsYXRvciA9IHRoYXQudWNvbGxhdG9yOwogICAgdXJ1bGVzdHJpbmcgPSB0aGF0LnVydWxlc3RyaW5nOwogIH0KICByZXR1cm4gKnRoaXM7Cn0KCkNvbGxhdG9yKiBSdWxlQmFzZWRDb2xsYXRvcjo6Y2xvbmUoKSBjb25zdAp7CiAgcmV0dXJuIG5ldyBSdWxlQmFzZWRDb2xsYXRvcigqdGhpcyk7Cn0KCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciogUnVsZUJhc2VkQ29sbGF0b3I6OmNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSkgY29uc3QKewogIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciAqcmVzdWx0ID0gbmV3IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihzb3VyY2UsIHRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CiAgICBkZWxldGUgcmVzdWx0OwogICAgcmV0dXJuIE5VTEw7CiAgfQoKICByZXR1cm4gcmVzdWx0Owp9CgovKioKKiBDcmVhdGUgYSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Igb2JqZWN0IHRoYXQgd2lsbCBpdGVyYXRvciBvdmVyIHRoZQoqIGVsZW1lbnRzIGluIGEgc3RyaW5nLCB1c2luZyB0aGUgY29sbGF0aW9uIHJ1bGVzIGRlZmluZWQgaW4gdGhpcwoqIFJ1bGVCYXNlZENvbGxhdG9yCiovCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciogUnVsZUJhc2VkQ29sbGF0b3I6OmNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgQ2hhcmFjdGVySXRlcmF0b3ImIHNvdXJjZSkgY29uc3QKewogIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciAqcmVzdWx0ID0gbmV3IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihzb3VyY2UsIHRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CgogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgewogICAgZGVsZXRlIHJlc3VsdDsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiogUmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgY29sbGF0b3IncyBydWxlcy4gVGhlIHN0cmluZyBjYW4KKiBsYXRlciBiZSBwYXNzZWQgdG8gdGhlIGNvbnN0cnVjdG9yIHRoYXQgdGFrZXMgYSBVbmljb2RlU3RyaW5nIGFyZ3VtZW50LAoqIHdoaWNoIHdpbGwgY29uc3RydWN0IGEgY29sbGF0b3IgdGhhdCdzIGZ1bmN0aW9uYWxseSBpZGVudGljYWwgdG8gdGhpcyBvbmUuCiogWW91IGNhbiBhbHNvIGFsbG93IHVzZXJzIHRvIGVkaXQgdGhlIHN0cmluZyBpbiBvcmRlciB0byBjaGFuZ2UgdGhlIGNvbGxhdGlvbgoqIGRhdGEsIG9yIHlvdSBjYW4gcHJpbnQgaXQgb3V0IGZvciBpbnNwZWN0aW9uLCBvciB3aGF0ZXZlci4KKi8KY29uc3QgVW5pY29kZVN0cmluZyYgUnVsZUJhc2VkQ29sbGF0b3I6OmdldFJ1bGVzKCkgY29uc3QKewogIHJldHVybiAoKnVydWxlc3RyaW5nKTsKfQoKQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IFJ1bGVCYXNlZENvbGxhdG9yOjpjb21wYXJlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsZW5ndGgpIGNvbnN0CnsKICByZXR1cm4gY29tcGFyZShzb3VyY2UuZ2V0QnVmZmVyKCksIHVwcnZfbWluKGxlbmd0aCxzb3VyY2UubGVuZ3RoKCkpLCB0YXJnZXQuZ2V0QnVmZmVyKCksIHVwcnZfbWluKGxlbmd0aCx0YXJnZXQubGVuZ3RoKCkpKTsKfQoKQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IFJ1bGVCYXNlZENvbGxhdG9yOjpjb21wYXJlKGNvbnN0IFVDaGFyKiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDaGFyKiB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHRhcmdldExlbmd0aCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0CnsKICByZXR1cm4gZ2V0RUNvbXBhcmlzb25SZXN1bHQodWNvbF9zdHJjb2xsKHVjb2xsYXRvciwgc291cmNlLCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LCB0YXJnZXRMZW5ndGgpKTsKfQoKLyoqCiogQ29tcGFyZSB0d28gc3RyaW5ncyB1c2luZyB0aGlzIGNvbGxhdG9yCiovCkNvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCBSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0CnsKICByZXR1cm4gY29tcGFyZShzb3VyY2UuZ2V0QnVmZmVyKCksIHNvdXJjZS5sZW5ndGgoKSwgdGFyZ2V0LmdldEJ1ZmZlcigpLCB0YXJnZXQubGVuZ3RoKCkpOwp9CgovKioKKiBSZXRyaWV2ZSBhIGNvbGxhdGlvbiBrZXkgZm9yIHRoZSBzcGVjaWZpZWQgc3RyaW5nLiBUaGUga2V5IGNhbiBiZSBjb21wYXJlZAoqIHdpdGggb3RoZXIgY29sbGF0aW9uIGtleXMgdXNpbmcgYSBiaXR3aXNlIGNvbXBhcmlzb24gKGUuZy4gbWVtY21wKSB0byBmaW5kCiogdGhlIG9yZGVyaW5nIG9mIHRoZWlyIHJlc3BlY3RpdmUgc291cmNlIHN0cmluZ3MuIFRoaXMgaXMgaGFuZHkgd2hlbiBkb2luZyBhCiogc29ydCwgd2hlcmUgZWFjaCBzb3J0IGtleSBtdXN0IGJlIGNvbXBhcmVkIG1hbnkgdGltZXMuCioKKiBUaGUgYmFzaWMgYWxnb3JpdGhtIGhlcmUgaXMgdG8gZmluZCBhbGwgb2YgdGhlIGNvbGxhdGlvbiBlbGVtZW50cyBmb3IgZWFjaAoqIGNoYXJhY3RlciBpbiB0aGUgc291cmNlIHN0cmluZywgY29udmVydCB0aGVtIHRvIGFuIEFTQ0lJIHJlcHJlc2VudGF0aW9uLCBhbmQKKiBwdXQgdGhlbSBpbnRvIHRoZSBjb2xsYXRpb24ga2V5LiAgQnV0IGl0J3MgdHJpY2tpZXIgdGhhbiB0aGF0LiBFYWNoCiogY29sbGF0aW9uIGVsZW1lbnQgaW4gYSBzdHJpbmcgaGFzIHRocmVlIGNvbXBvbmVudHM6IHByaW1hcnkgKCdBJyB2cyAnQicpLAoqIHNlY29uZGFyeSAoJ3UnIHZzICf8JyksIGFuZCB0ZXJ0aWFyeSAoJ0EnIHZzICdhJyksIGFuZCBhIHByaW1hcnkgZGlmZmVyZW5jZQoqIGF0IHRoZSBlbmQgb2YgYSBzdHJpbmcgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIGEgc2Vjb25kYXJ5IG9yIHRlcnRpYXJ5CiogZGlmZmVyZW5jZSBlYXJsaWVyIGluIHRoZSBzdHJpbmcuCioKKiBUbyBhY2NvdW50IGZvciB0aGlzLCB3ZSBwdXQgYWxsIG9mIHRoZSBwcmltYXJ5IG9yZGVycyBhdCB0aGUgYmVnaW5uaW5nIG9mCiogdGhlIHN0cmluZywgZm9sbG93ZWQgYnkgdGhlIHNlY29uZGFyeSBhbmQgdGVydGlhcnkgb3JkZXJzLiBFYWNoIHNldCBvZgoqIG9yZGVycyBpcyB0ZXJtaW5hdGVkIGJ5IG51bGxzIHNvIHRoYXQgYSBrZXkgZm9yIGEgc3RyaW5nIHdoaWNoIGlzIGEgaW5pdGlhbAoqIHN1YnN0cmluZyBvZiBhbm90aGVyIGtleSB3aWxsIGNvbXBhcmUgbGVzcyB3aXRob3V0IGFueSBzcGVjaWFsIGNhc2UuCioKKiBIZXJlJ3MgYSBoeXBvdGhldGljYWwgZXhhbXBsZSwgd2l0aCB0aGUgY29sbGF0aW9uIGVsZW1lbnQgcmVwcmVzZW50ZWQgYXMgYQoqIHRocmVlLWRpZ2l0IG51bWJlciwgb25lIGRpZ2l0IGZvciBwcmltYXJ5LCBvbmUgZm9yIHNlY29uZGFyeSwgZXRjLgoqCiogU3RyaW5nOiAgICAgICAgICAgICAgQSAgICAgYSAgICAgQiAgICDJCiogQ29sbGF0aW9uIEVsZW1lbnRzOiAxMDEgICAxMDAgICAyMDEgIDUxMQoqIENvbGxhdGlvbiBLZXk6ICAgICAgMTEyNTxudWxsPjAwMDE8bnVsbD4xMDExPG51bGw+CioKKiBUbyBtYWtlIHRoaW5ncyBldmVuIHRyaWNraWVyLCBzZWNvbmRhcnkgZGlmZmVyZW5jZXMgKGFjY2VudCBtYXJrcykgYXJlCiogY29tcGFyZWQgc3RhcnRpbmcgYXQgdGhlICplbmQqIG9mIHRoZSBzdHJpbmcgaW4gbGFuZ3VhZ2VzIHdpdGggRnJlbmNoCiogc2Vjb25kYXJ5IG9yZGVyaW5nLiBCdXQgd2hlbiBjb21wYXJpbmcgdGhlIGFjY2VudCBtYXJrcyBvbiBhIHNpbmdsZSBiYXNlCiogY2hhcmFjdGVyLCB0aGV5IGFyZSBjb21wYXJlZCBmcm9tIHRoZSBiZWdpbm5pbmcuIFRvIGhhbmRsZSB0aGlzLCB3ZSByZXZlcnNlCiogYWxsIG9mIHRoZSBhY2NlbnRzIHRoYXQgYmVsb25nIHRvIGVhY2ggYmFzZSBjaGFyYWN0ZXIsIHRoZW4gd2UgcmV2ZXJzZSB0aGUKKiBlbnRpcmUgc3RyaW5nIG9mIHNlY29uZGFyeSBvcmRlcmluZ3MgYXQgdGhlIGVuZC4KKi8KQ29sbGF0aW9uS2V5JiBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29sbGF0aW9uS2V5KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25LZXkmIHNvcnRrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdAp7CiAgcmV0dXJuIGdldENvbGxhdGlvbktleShzb3VyY2UuZ2V0QnVmZmVyKCksIHNvdXJjZS5sZW5ndGgoKSwgc29ydGtleSwgc3RhdHVzKTsKfQoKQ29sbGF0aW9uS2V5JiBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29sbGF0aW9uS2V5KGNvbnN0IFVDaGFyKiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYgc29ydGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICB7CiAgICByZXR1cm4gc29ydGtleS5zZXRUb0JvZ3VzKCk7CiAgfQoKICBpZiAoKCFzb3VyY2UpIHx8IChzb3VyY2VMZW4gPT0gMCkpIHsKICAgIHJldHVybiBzb3J0a2V5LnJlc2V0KCk7CiAgfQoKICB1aW50OF90ICpyZXN1bHQ7CiAgaW50MzJfdCByZXN1bHRMZW4gPSB1Y29sX2dldFNvcnRLZXlXaXRoQWxsb2NhdGlvbih1Y29sbGF0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UsIHNvdXJjZUxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZyZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RhdHVzKTsKICBzb3J0a2V5LmFkb3B0KHJlc3VsdCwgcmVzdWx0TGVuKTsKICByZXR1cm4gc29ydGtleTsKfQoKLyoqCiAqIFJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZXMgdGhhdCBlbmQgd2l0aCB0aGUKICogc3BlY2lmaWVkIGNvbXBhcmlzb24gb3JkZXIuCiAqIEBwYXJhbSBvcmRlciBhIGNvbGxhdGlvbiBvcmRlciByZXR1cm5lZCBieSBwcmV2aW91cyBvciBuZXh0LgogKiBAcmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbnkgZXhwYW5zaW9uIHNldWVuY2VzIGVuZGluZyB3aXRoIHRoZQogKiAgICAgICAgIHNwZWNpZmllZCBvcmRlciBvciAxIGlmIGNvbGxhdGlvbiBvcmRlciBkb2VzIG5vdCBvY2N1ciBhdCB0aGUgZW5kIG9mIGFueQogKiAgICAgICAgIGV4cGFuc2lvbiBzZXF1ZW5jZS4KICogQHNlZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IjZ2V0TWF4RXhwYW5zaW9uCiAqLwppbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3QKewogIHVpbnQ4X3QgcmVzdWx0OwogIFVDT0xfR0VUTUFYRVhQQU5TSU9OKHVjb2xsYXRvciwgKHVpbnQzMl90KW9yZGVyLCByZXN1bHQpOwogIHJldHVybiByZXN1bHQ7Cn0KCnVpbnQ4X3QqIFJ1bGVCYXNlZENvbGxhdG9yOjpjbG9uZVJ1bGVEYXRhKGludDMyX3QgJmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cykKewogIHJldHVybiB1Y29sX2Nsb25lUnVsZURhdGEodWNvbGxhdG9yLCAmbGVuZ3RoLCAmc3RhdHVzKTsKfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6c2V0QXR0cmlidXRlKFVDb2xBdHRyaWJ1dGUgYXR0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDb2xBdHRyaWJ1dGVWYWx1ZSB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cykKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHJldHVybjsKICB1Y29sX3NldEF0dHJpYnV0ZSh1Y29sbGF0b3IsIGF0dHIsIHZhbHVlLCAmc3RhdHVzKTsKfQoKVUNvbEF0dHJpYnV0ZVZhbHVlIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICByZXR1cm4gVUNPTF9ERUZBVUxUOwogIHJldHVybiB1Y29sX2dldEF0dHJpYnV0ZSh1Y29sbGF0b3IsIGF0dHIsICZzdGF0dXMpOwp9Cgp1aW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6c2V0VmFyaWFibGVUb3AoY29uc3QgVUNoYXIgKnZhclRvcCwgaW50MzJfdCBsZW4sIFVFcnJvckNvZGUgJnN0YXR1cykgewogIHJldHVybiB1Y29sX3NldFZhcmlhYmxlVG9wKHVjb2xsYXRvciwgdmFyVG9wLCBsZW4sICZzdGF0dXMpOwp9Cgp1aW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6c2V0VmFyaWFibGVUb3AoY29uc3QgVW5pY29kZVN0cmluZyB2YXJUb3AsIFVFcnJvckNvZGUgJnN0YXR1cykgewogIHJldHVybiB1Y29sX3NldFZhcmlhYmxlVG9wKHVjb2xsYXRvciwgdmFyVG9wLmdldEJ1ZmZlcigpLCB2YXJUb3AubGVuZ3RoKCksICZzdGF0dXMpOwp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpzZXRWYXJpYWJsZVRvcChjb25zdCB1aW50MzJfdCB2YXJUb3AsIFVFcnJvckNvZGUgJnN0YXR1cykgewogIHVjb2xfcmVzdG9yZVZhcmlhYmxlVG9wKHVjb2xsYXRvciwgdmFyVG9wLCAmc3RhdHVzKTsKfQoKdWludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmdldFZhcmlhYmxlVG9wKFVFcnJvckNvZGUgJnN0YXR1cykgY29uc3QgewogIHJldHVybiB1Y29sX2dldFZhcmlhYmxlVG9wKHVjb2xsYXRvciwgJnN0YXR1cyk7Cn0KCkNvbGxhdG9yKiBSdWxlQmFzZWRDb2xsYXRvcjo6c2FmZUNsb25lKHZvaWQpCnsKICBVRXJyb3JDb2RlIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKICBpbnQzMl90IGJ1ZmZlcnNpemUgPSBVX0NPTF9TQUZFQ0xPTkVfQlVGRkVSU0laRTsKICBVQ29sbGF0b3IgKnVjb2wgPSB1Y29sX3NhZmVDbG9uZSh1Y29sbGF0b3IsIE5VTEwsICZidWZmZXJzaXplLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaW50U3RhdHVzKTsKICBpZiAoVV9GQUlMVVJFKGludFN0YXR1cykpIHsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgVW5pY29kZVN0cmluZyAqciA9IG5ldyBVbmljb2RlU3RyaW5nKCp1cnVsZXN0cmluZyk7CiAgUnVsZUJhc2VkQ29sbGF0b3IgKnJlc3VsdCA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvcih1Y29sLCByKTsKICByZXN1bHQtPmRhdGFJc093bmVkID0gVFJVRTsKICByZXR1cm4gcmVzdWx0Owp9CgoKaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0U29ydEtleShjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCAqcmVzdWx0LCBpbnQzMl90IHJlc3VsdExlbmd0aCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdAp7CiAgcmV0dXJuIHVjb2xfZ2V0U29ydEtleSh1Y29sbGF0b3IsIHNvdXJjZS5nZXRCdWZmZXIoKSwgc291cmNlLmxlbmd0aCgpLCByZXN1bHQsIHJlc3VsdExlbmd0aCk7Cn0KCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmdldFNvcnRLZXkoY29uc3QgVUNoYXIgKnNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbmd0aCwgdWludDhfdCAqcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgcmVzdWx0TGVuZ3RoKSBjb25zdAp7CiAgcmV0dXJuIHVjb2xfZ2V0U29ydEtleSh1Y29sbGF0b3IsIHNvdXJjZSwgc291cmNlTGVuZ3RoLCByZXN1bHQsIHJlc3VsdExlbmd0aCk7Cn0KCkNvbGxhdG9yOjpFQ29sbGF0aW9uU3RyZW5ndGggUnVsZUJhc2VkQ29sbGF0b3I6OmdldFN0cmVuZ3RoKHZvaWQpIGNvbnN0CnsKICBVRXJyb3JDb2RlIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKICByZXR1cm4gZ2V0RUNvbGxhdGlvblN0cmVuZ3RoKHVjb2xfZ2V0QXR0cmlidXRlKHVjb2xsYXRvciwgVUNPTF9TVFJFTkdUSCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZpbnRTdGF0dXMpKTsKfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6c2V0U3RyZW5ndGgoRUNvbGxhdGlvblN0cmVuZ3RoIG5ld1N0cmVuZ3RoKQp7CiAgVUVycm9yQ29kZSBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgVUNvbGxhdGlvblN0cmVuZ3RoIHN0cmVuZ3RoID0gZ2V0VUNvbGxhdGlvblN0cmVuZ3RoKG5ld1N0cmVuZ3RoKTsKICB1Y29sX3NldEF0dHJpYnV0ZSh1Y29sbGF0b3IsIFVDT0xfU1RSRU5HVEgsIHN0cmVuZ3RoLCAmaW50U3RhdHVzKTsKfQoKLyoqCiogQ3JlYXRlIGEgaGFzaCBjb2RlIGZvciB0aGlzIGNvbGxhdGlvbi4gSnVzdCBoYXNoIHRoZSBtYWluIHJ1bGUgdGFibGUgLS0gdGhhdAoqIHNob3VsZCBiZSBnb29kIGVub3VnaCBmb3IgYWxtb3N0IGFueSB1c2UuCiovCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6Omhhc2hDb2RlKCkgY29uc3QKewogIGludDMyX3QgbGVuZ3RoOwogIGNvbnN0IFVDaGFyICpydWxlcyA9IHVjb2xfZ2V0UnVsZXModWNvbGxhdG9yLCAmbGVuZ3RoKTsKICByZXR1cm4gdWhhc2hfaGFzaFVDaGFyc04ocnVsZXMsIGxlbmd0aCk7Cn0KCi8qKgoqIFNldCB0aGUgZGVjb21wb3NpdGlvbiBtb2RlIG9mIHRoZSBDb2xsYXRvciBvYmplY3QuCiogQHBhcmFtIHRoZSBuZXcgZGVjb21wb3NpdGlvbiBtb2RlCiogQHNlZSBDb2xsYXRvciNnZXREZWNvbXBvc2l0aW9uCiovCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OnNldERlY29tcG9zaXRpb24oTm9ybWFsaXplcjo6RU1vZGUgIG1vZGUpCnsKICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICB1Y29sX3NldE5vcm1hbGl6YXRpb24odWNvbGxhdG9yLCBOb3JtYWxpemVyOjpnZXRVTm9ybWFsaXphdGlvbk1vZGUobW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKSk7Cn0KCi8qKgoqIEdldCB0aGUgZGVjb21wb3NpdGlvbiBtb2RlIG9mIHRoZSBDb2xsYXRvciBvYmplY3QuCiogQHJldHVybiB0aGUgZGVjb21wb3NpdGlvbiBtb2RlCiogQHNlZSBDb2xsYXRvciNzZXREZWNvbXBvc2l0aW9uCiovCk5vcm1hbGl6ZXI6OkVNb2RlIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXREZWNvbXBvc2l0aW9uKHZvaWQpIGNvbnN0CnsKICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICByZXR1cm4gTm9ybWFsaXplcjo6Z2V0Tm9ybWFsaXplckVNb2RlKHVjb2xfZ2V0Tm9ybWFsaXphdGlvbih1Y29sbGF0b3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7Cn0KCi8vIFJ1bGVCYXNlQ29sbGF0b3JOZXcgcHJpdmF0ZSBjb25zdHJ1Y3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoKSA6IGRhdGFJc093bmVkKEZBTFNFKSwgdWNvbGxhdG9yKDApCnsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKFVDb2xsYXRvciAqY29sbGF0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nICpydWxlKSA6IGRhdGFJc093bmVkKEZBTFNFKQp7CiAgdWNvbGxhdG9yID0gY29sbGF0b3I7CiAgdXJ1bGVzdHJpbmcgPSBydWxlOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgTG9jYWxlJiBkZXNpcmVkTG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhSXNPd25lZChGQUxTRSksIHVjb2xsYXRvcigwKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuOwoKICAvKgogIFRyeSB0byBsb2FkLCBpbiBvcmRlcjoKICAgMS4gVGhlIGRlc2lyZWQgbG9jYWxlJ3MgY29sbGF0aW9uLgogICAyLiBBIGZhbGxiYWNrIG9mIHRoZSBkZXNpcmVkIGxvY2FsZS4KICAgMy4gVGhlIGRlZmF1bHQgbG9jYWxlJ3MgY29sbGF0aW9uLgogICA0LiBBIGZhbGxiYWNrIG9mIHRoZSBkZWZhdWx0IGxvY2FsZS4KICAgNS4gVGhlIGRlZmF1bHQgY29sbGF0aW9uIHJ1bGVzLCB3aGljaCBjb250YWlucyBlbl9VUyBjb2xsYXRpb24gcnVsZXMuCgogICBUbyByZWl0ZXJhdGUsIHdlIHRyeToKICAgU3BlY2lmaWM6CiAgICBsYW5ndWFnZStjb3VudHJ5K3ZhcmlhbnQKICAgIGxhbmd1YWdlK2NvdW50cnkKICAgIGxhbmd1YWdlCiAgIERlZmF1bHQ6CiAgICBsYW5ndWFnZStjb3VudHJ5K3ZhcmlhbnQKICAgIGxhbmd1YWdlK2NvdW50cnkKICAgIGxhbmd1YWdlCiAgIFJvb3Q6IChha2EgREVGQVVMVFJVTEVTKQogICBzdGVwcyAxLTUgYXJlIGhhbmRsZWQgYnkgcmVzb3VyY2UgYnVuZGxlIGZhbGxiYWNrIG1lY2hhbmlzbS4KICAgaG93ZXZlciwgaW4gYSB2ZXJ5IHVucHJvYmFibGUgc2l0dWF0aW9uIHRoYXQgbm8gcmVzb3VyY2UgYnVuZGxlCiAgIGRhdGEgZXhpc3RzLCBzdGVwIDUgaXMgcmVwZWF0ZWQgd2l0aCBoYXJkY29kZWQgZGVmYXVsdCBydWxlcy4KICAqLwoKICBzZXRVQ29sbGF0b3IoZGVzaXJlZExvY2FsZSwgc3RhdHVzKTsKCiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogIHsKICAgIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKCiAgICAvLyBUT0RPOiAKICAgIHNldFVDb2xsYXRvcihrUm9vdExvY2FsZU5hbWUsIHN0YXR1cyk7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKCiAgICAgIGlmIChzdGF0dXMgPT0gVV9aRVJPX0VSUk9SKQogICAgICAgIHN0YXR1cyA9IFVfVVNJTkdfREVGQVVMVF9FUlJPUjsKCiAgICAgIGlmIChzdGF0dXMgPT0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUikKICAgICAgICByZXR1cm47CiAgICB9CiAgfQoKICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpCiAgewogICAgaW50MzJfdCBsZW5ndGg7CiAgICBjb25zdCBVQ2hhciAqciA9IHVjb2xfZ2V0UnVsZXModWNvbGxhdG9yLCAmbGVuZ3RoKTsKICAgIGlmIChsZW5ndGggPiAwKSB7CiAgICAgICAgLy8gYWxpYXMgdGhlIHJ1bGVzIHN0cmluZwogICAgICAgIHVydWxlc3RyaW5nID0gbmV3IFVuaWNvZGVTdHJpbmcoVFJVRSwgciwgbGVuZ3RoKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHVydWxlc3RyaW5nID0gbmV3IFVuaWNvZGVTdHJpbmcoKTsKICAgIH0KICAgIGRhdGFJc093bmVkID0gVFJVRTsKICB9CgogIHJldHVybjsKfQoKLyogUnVsZUJhc2VkQ29sbGF0b3IgcHJpdmF0ZSBkYXRhIG1lbWJlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qCiAqIFRPRE86CiAqIFRoZXNlIHNob3VsZCBwcm9iYWJseSBiZSBlbnVtcyAoPD0weGZmZmYpIG9yICNkZWZpbmVzICg+MHhmZmZmKQogKiBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlLgogKiBJbmNsdWRlIHVjb2xfaW1wLmggYW5kIHVzZSBpdHMgY29uc3RhbnRzIGlmIHBvc3NpYmxlLgogKiBPbmx5IHVzZWQgaW4gY29sZWl0ci5oPyEKICogUmVtb3ZlIGZyb20gaGVyZSEKICovCgovKiBuZWVkIGxvb2sgdXAgaW4gLmNvbW1pdCgpICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkNIQVJJTkRFWCA9IDB4NzAwMDAwMDA7Ci8qIEV4cGFuZCBpbmRleCBmb2xsb3dzICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkVYUEFORENIQVJJTkRFWCA9IDB4N0UwMDAwMDA7Ci8qIGNvbnRyYWN0IGluZGV4ZXMgZm9sbG93cyAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDT05UUkFDVENIQVJJTkRFWCA9IDB4N0YwMDAwMDA7Ci8qIHVubWFwcGVkIGNoYXJhY3RlciB2YWx1ZXMgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6VU5NQVBQRUQgPSAweEZGRkZGRkZGOwovKiBwcmltYXJ5IHN0cmVuZ3RoIGluY3JlbWVudCAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJJTkNSRU1FTlQgPSAweDAwMDEwMDAwOwovKiBzZWNvbmRhcnkgc3RyZW5ndGggaW5jcmVtZW50ICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAwMDEwMDsKLyogdGVydGlhcnkgc3RyZW5ndGggaW5jcmVtZW50ICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJJTkNSRU1FTlQgPSAweDAwMDAwMDAxOwovKiBtYXNrIG9mZiBhbnl0aGluZyBidXQgcHJpbWFyeSBvcmRlciAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJNQVNLID0gMHhmZmZmMDAwMDsKLyogbWFzayBvZmYgYW55dGhpbmcgYnV0IHNlY29uZGFyeSBvcmRlciAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUk1BU0sgPSAweDAwMDBmZjAwOwovKiBtYXNrIG9mZiBhbnl0aGluZyBidXQgdGVydGlhcnkgb3JkZXIgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6VEVSVElBUllPUkRFUk1BU0sgPSAweDAwMDAwMGZmOwovKiBtYXNrIG9mZiBpZ25vcmFibGUgY2hhciBvcmRlciAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpJR05PUkFCTEVNQVNLID0gMHgwMDAwZmZmZjsKLyogdXNlIG9ubHkgdGhlIHByaW1hcnkgZGlmZmVyZW5jZSAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZRElGRkVSRU5DRU9OTFkgPSAweGZmZmYwMDAwOwovKiB1c2Ugb25seSB0aGUgcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IGRpZmZlcmVuY2UgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZRElGRkVSRU5DRU9OTFkgPSAweGZmZmZmZjAwOwovKiBwcmltYXJ5IG9yZGVyIHNoaWZ0ICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllPUkRFUlNISUZUID0gMTY7Ci8qIHNlY29uZGFyeSBvcmRlciBzaGlmdCAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUlNISUZUID0gODsKLyogc3RhcnRpbmcgdmFsdWUgZm9yIGNvbGxhdGlvbiBlbGVtZW50cyAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDT0xFTEVNRU5UU1RBUlQgPSAweDAyMDIwMjAyOwovKiB0ZXN0aW5nIG1hc2sgZm9yIHByaW1hcnkgbG93IGVsZW1lbnQgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWUxPV1pFUk9NQVNLID0gMHgwMEZGMDAwMDsKLyogcmVzZXRpbmcgdmFsdWUgZm9yIHNlY29uZGFyaWVzIGFuZCB0ZXJ0aWFyaWVzICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlJFU0VUU0VDT05EQVJZVEVSVElBUlkgPSAweDAwMDAwMjAyOwovKiByZXNldGluZyB2YWx1ZSBmb3IgdGVydGlhcmllcyAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpSRVNFVFRFUlRJQVJZID0gMHgwMDAwMDAwMjsKCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1JR05PUkFCTEUgPSAweDAyMDI7CgovKiB1bmlxdWUgZmlsZSBpZCBmb3IgcGFyaXR5IGNoZWNrICovCmNvbnN0IGludDE2X3QgUnVsZUJhc2VkQ29sbGF0b3I6OkZJTEVJRCA9IDB4NTQ0MzsKLyogYmluYXJ5IGNvbGxhdGlvbiBmaWxlIGV4dGVuc2lvbiAqLwpjb25zdCBjaGFyIFJ1bGVCYXNlZENvbGxhdG9yOjprRmlsZW5hbWVTdWZmaXhbXSA9ICIuY29sIjsKLyogY2xhc3MgaWQgPyBWYWx1ZSBpcyBpcnJlbGV2YW50ICovCmNvbnN0IGNoYXIgIFJ1bGVCYXNlZENvbGxhdG9yOjpmZ0NsYXNzSUQgPSAwOwoKVV9OQU1FU1BBQ0VfRU5ECg==