LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogQ29weXJpZ2h0IChDKSB7MTk5Ni0yMDAxfSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCi8qKgoqIEZpbGUgdGJsY29sbC5jcHAKKgoqIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICBEYXRlICAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgoqICAyLzUvOTcgICAgICBhbGl1ICAgICAgICBBZGRlZCBzdHJlYW1JbiBhbmQgc3RyZWFtT3V0IG1ldGhvZHMuICBBZGRlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciB3aGljaCByZWFkcyBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QgZnJvbQoqICAgICAgICAgICAgICAgICAgICAgICAgICBhIGJpbmFyeSBmaWxlLiAgQWRkZWQgd3JpdGVUb0ZpbGUgbWV0aG9kIHdoaWNoIHN0cmVhbXMKKiAgICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3Igb3V0IHRvIGEgYmluYXJ5IGZpbGUuICBUaGUgc3RyZWFtSW4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIHN0cmVhbU91dCBtZXRob2RzIHVzZSBpc3RyZWFtIGFuZCBvc3RyZWFtIG9iamVjdHMKKiAgICAgICAgICAgICAgICAgICAgICAgICAgaW4gYmluYXJ5IG1vZGUuCiogIDIvMTEvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIGRlY2xhcmF0aW9ucyBvdXQgb2YgZm9yIGxvb3AgaW5pdGlhbGl6ZXIuCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIE1hYyBjb21wYXRpYmlsaXR5ICNpZmRlZiBmb3IgaW9zOjpub2NyZWF0ZS4KKiAgMi8xMi85NyAgICAgYWxpdSAgICAgICAgTW9kaWZpZWQgdG8gdXNlIFRhYmxlQ29sbGF0aW9uRGF0YSBzdWItb2JqZWN0IHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIGhvbGQgaW52YXJpYW50IGRhdGEuCiogIDIvMTMvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIHNldmVyYWwgbWV0aG9kcyBpbnRvIHRoaXMgY2xhc3MgZnJvbSBDb2xsYXRpb24uCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIGEgcHJpdmF0ZSBSdWxlQmFzZWRDb2xsYXRvcihMb2NhbGUmKSBjb25zdHJ1Y3RvciwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gYmUgdXNlZCBieSBDb2xsYXRvcjo6Z2V0SW5zdGFuY2UoKS4gIEdlbmVyYWwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYW4gdXAuICBNYWRlIHVzZSBvZiBVRXJyb3JDb2RlIHZhcmlhYmxlcyBjb25zaXN0ZW50LgoqICAyLzIwLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjbG9uZSwgb3BlcmF0b3I9PSwgb3BlcmF0b3IhPSwgb3BlcmF0b3I9LCBhbmQgY29weQoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciBhbmQgZ2V0RHluYW1pY0NsYXNzSUQuCiogIDMvNS85NyAgICAgIGFsaXUgICAgICAgIENoYW5nZWQgY29tcGFjdGlvbiBjeWNsZSB0byBpbXByb3ZlIHBlcmZvcm1hbmNlLiAgV2UKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlIHRoZSBtYXhpbXVtIGFsbG93YWJsZSB2YWx1ZSB3aGljaCBpcyBrQmxvY2tDb3VudC4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgTW9kaWZpZWQgZ2V0UnVsZXMoKSB0byBsb2FkIHJ1bGVzIGR5bmFtaWNhbGx5LiAgQ2hhbmdlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RGcm9tRmlsZSgpIGNhbGwgdG8gYWNjb21vZGF0ZSB0aGlzIChhZGRlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgdG8gc3BlY2lmeSB3aGV0aGVyIGJpbmFyeSBsb2FkaW5nIGlzIHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIHRha2UgcGxhY2UpLgoqIDA1LzA2Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBtZW1vcnkgYWxsb2NhdGlvbiBlcnJvciBjaGVjay4KKiAgNi8yMC85NyAgICAgaGVsZW5hICAgICAgSmF2YSBjbGFzcyBuYW1lIGNoYW5nZS4KKiAgNi8yMy85NyAgICAgaGVsZW5hICAgICAgQWRkaW5nIGNvbW1lbnRzIHRvIG1ha2UgY29kZSBtb3JlIHJlYWRhYmxlLgoqIDA5LzAzLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjcmVhdGVDb2xsYXRpb25LZXlWYWx1ZXMoKS4KKiAwNi8yNi85OCAgICAgZXJtICAgICAgICAgQ2hhbmdlcyBmb3IgQ29sbGF0aW9uS2V5cyB1c2luZyBieXRlIGFycmF5cy4KKiAwOC8xMC85OCAgICAgZXJtICAgICAgICAgU3luY2hlZCB3aXRoIDEuMiB2ZXJzaW9uIG9mIFJ1bGVCYXNlZENvbGxhdG9yLmphdmEKKiAwNC8yMy85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBFRGVjb21wb3NpdGlvbk1vZGUsIG1lcmdlZCB3aXRoCiogICAgICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlCiogMDYvMTQvOTkgICAgIHN0ZXBoZW4gICAgIFJlbW92ZWQga1Jlc291cmNlQnVuZGxlU3VmZml4CiogMDYvMjIvOTkgICAgIHN0ZXBoZW4gICAgIEZpeGVkIGxvZ2ljIGluIGNvbnN0cnVjdEZyb21GaWxlKCkgc2luY2UgLmN0eAoqICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlcyBhcmUgbm8gbG9uZ2VyIHVzZWQuCiogMTEvMDIvOTkgICAgIGhlbGVuYSAgICAgIENvbGxhdG9yIHBlcmZvcm1hbmNlIGVuaGFuY2VtZW50cy4gIFNwZWNpYWwgY2FzZQoqICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgTk9fT1Agc2l0dWF0aW9ucy4KKiAxMS8xNy85OSAgICAgc3JsICAgICAgICAgTW9yZSBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuIElubGluZWQgc29tZSBpbnRlcm5hbCBmdW5jdGlvbnMuCiogMTIvMTUvOTkgICAgIGFsaXUgICAgICAgIFVwZGF0ZSB0byBzdXBwb3J0IFRoYWkgY29sbGF0aW9uLiAgTW92ZSBOb3JtYWxpemVySXRlcmF0b3IKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gaW1wbGVtZW50YXRpb24gZmlsZS4KKiAwMS8yOS8wMSAgICAgc3lud2VlICAgICAgTW9kaWZpZWQgaW50byBhIEMrKyB3cmFwcGVyIGNhbGxpbmcgQyBBUElzICh1Y29sLmgpCiovCgojaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKCiNpZiAhVUNPTkZJR19OT19DT0xMQVRJT04KCiNpbmNsdWRlICJ1bmljb2RlL3RibGNvbGwuaCIKI2luY2x1ZGUgInVuaWNvZGUvY29sZWl0ci5oIgojaW5jbHVkZSAidW5pY29kZS9yZXNidW5kLmgiCiNpbmNsdWRlICJ1bmljb2RlL3VzZXQuaCIKI2luY2x1ZGUgInVjb2xfaW1wLmgiCiNpbmNsdWRlICJ1cmVzaW1wLmgiCiNpbmNsdWRlICJ1aGFzaC5oIgojaW5jbHVkZSAiY21lbW9yeS5oIgoKLyogcHVibGljIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KClVfTkFNRVNQQUNFX0JFR0lOCgovKioKKiBDb3B5IGNvbnN0cnVjdG9yCiovClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBSdWxlQmFzZWRDb2xsYXRvciYgdGhhdCkgOgogICAgICAgICAgICAgIENvbGxhdG9yKHRoYXQpLCBkYXRhSXNPd25lZChGQUxTRSksIHVjb2xsYXRvcih0aGF0LnVjb2xsYXRvciksCiAgICAgICAgICAgICAgdXJ1bGVzdHJpbmcodGhhdC51cnVsZXN0cmluZykKewp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFJc093bmVkKEZBTFNFKQp7CiAgY29uc3RydWN0KHJ1bGVzLAogICAgICAgICAgICBVQ09MX0RFRkFVTFRfU1RSRU5HVEgsCiAgICAgICAgICAgIFVDT0xfREVGQVVMVCwKICAgICAgICAgICAgc3RhdHVzKTsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICAgRUNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSA6IGRhdGFJc093bmVkKEZBTFNFKQp7CiAgY29uc3RydWN0KHJ1bGVzLAogICAgICAgICAgICBnZXRVQ29sbGF0aW9uU3RyZW5ndGgoY29sbGF0aW9uU3RyZW5ndGgpLAogICAgICAgICAgICBVQ09MX0RFRkFVTFQsCiAgICAgICAgICAgIHN0YXR1cyk7Cn0KCiNpZmRlZiBJQ1VfTk9STUFMSVpFUl9VU0VfREVQUkVDQVRFUwovLyBUT0RPIHRoaXMgaXMgYSBkZXByZWNhdGVkIGNvbnN0cnVjdG9yLCByZW1vdmUgPjIwMDItc2VwLTMwClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhSXNPd25lZChGQUxTRSkKewogIGNvbnN0cnVjdChydWxlcywKICAgICAgICAgICAgVUNPTF9ERUZBVUxUX1NUUkVOR1RILAogICAgICAgICAgICAoVUNvbEF0dHJpYnV0ZVZhbHVlKU5vcm1hbGl6ZXI6OmdldFVOb3JtYWxpemF0aW9uTW9kZShkZWNvbXBvc2l0aW9uTW9kZSwgc3RhdHVzKSwKICAgICAgICAgICAgc3RhdHVzKTsKfQoKLy8gVE9ETyB0aGlzIGlzIGEgZGVwcmVjYXRlZCBjb25zdHJ1Y3RvciwgcmVtb3ZlID4yMDAyLXNlcC0zMApSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgOiBkYXRhSXNPd25lZChGQUxTRSkKewogIGNvbnN0cnVjdChydWxlcywKICAgICAgICAgICAgZ2V0VUNvbGxhdGlvblN0cmVuZ3RoKGNvbGxhdGlvblN0cmVuZ3RoKSwKICAgICAgICAgICAgKFVDb2xBdHRyaWJ1dGVWYWx1ZSlOb3JtYWxpemVyOjpnZXRVTm9ybWFsaXphdGlvbk1vZGUoZGVjb21wb3NpdGlvbk1vZGUsIHN0YXR1cyksCiAgICAgICAgICAgIHN0YXR1cyk7Cn0KCi8qKgoqIFNldCB0aGUgZGVjb21wb3NpdGlvbiBtb2RlIG9mIHRoZSBDb2xsYXRvciBvYmplY3QuCiogQHBhcmFtIHRoZSBuZXcgZGVjb21wb3NpdGlvbiBtb2RlCiogQHNlZSBDb2xsYXRvciNnZXREZWNvbXBvc2l0aW9uCiovCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OnNldERlY29tcG9zaXRpb24oTm9ybWFsaXplcjo6RU1vZGUgIG1vZGUpCnsKICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICB1Y29sX3NldE5vcm1hbGl6YXRpb24odWNvbGxhdG9yLCBOb3JtYWxpemVyOjpnZXRVTm9ybWFsaXphdGlvbk1vZGUobW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKSk7Cn0KCi8qKgoqIEdldCB0aGUgZGVjb21wb3NpdGlvbiBtb2RlIG9mIHRoZSBDb2xsYXRvciBvYmplY3QuCiogQHJldHVybiB0aGUgZGVjb21wb3NpdGlvbiBtb2RlCiogQHNlZSBDb2xsYXRvciNzZXREZWNvbXBvc2l0aW9uCiovCk5vcm1hbGl6ZXI6OkVNb2RlIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXREZWNvbXBvc2l0aW9uKHZvaWQpIGNvbnN0CnsKICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICByZXR1cm4gTm9ybWFsaXplcjo6Z2V0Tm9ybWFsaXplckVNb2RlKHVjb2xfZ2V0Tm9ybWFsaXphdGlvbih1Y29sbGF0b3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7Cn0KCiNlbmRpZiAvKiBJQ1VfTk9STUFMSVpFUl9VU0VfREVQUkVDQVRFUyAqLwoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNvbEF0dHJpYnV0ZVZhbHVlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhSXNPd25lZChGQUxTRSkKewogIGNvbnN0cnVjdChydWxlcywKICAgICAgICAgICAgVUNPTF9ERUZBVUxUX1NUUkVOR1RILAogICAgICAgICAgICBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgc3RhdHVzKTsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICAgRUNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgVUNvbEF0dHJpYnV0ZVZhbHVlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSA6IGRhdGFJc093bmVkKEZBTFNFKQp7CiAgY29uc3RydWN0KHJ1bGVzLAogICAgICAgICAgICBnZXRVQ29sbGF0aW9uU3RyZW5ndGgoY29sbGF0aW9uU3RyZW5ndGgpLAogICAgICAgICAgICBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgc3RhdHVzKTsKfQoKdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6Y29uc3RydWN0KGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDb2xBdHRyaWJ1dGVWYWx1ZSBjb2xsYXRpb25TdHJlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ29sQXR0cmlidXRlVmFsdWUgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgdWNvbGxhdG9yID0gdWNvbF9vcGVuUnVsZXMocnVsZXMuZ2V0QnVmZmVyKCksIHJ1bGVzLmxlbmd0aCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY29tcG9zaXRpb25Nb2RlLCBjb2xsYXRpb25TdHJlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAmc3RhdHVzKTsKICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpCiAgewogICAgaW50MzJfdCBsZW5ndGg7CiAgICBjb25zdCBVQ2hhciAqciA9IHVjb2xfZ2V0UnVsZXModWNvbGxhdG9yLCAmbGVuZ3RoKTsKICAgIGlmIChsZW5ndGggPiAwKSB7CiAgICAgICAgLy8gYWxpYXMgdGhlIHJ1bGVzIHN0cmluZwogICAgICAgIHVydWxlc3RyaW5nID0gbmV3IFVuaWNvZGVTdHJpbmcoVFJVRSwgciwgbGVuZ3RoKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHVydWxlc3RyaW5nID0gbmV3IFVuaWNvZGVTdHJpbmcoKTsKICAgIH0KICAgIC8qIHRlc3QgZm9yIE5VTEwgKi8KICAgIGlmICh1cnVsZXN0cmluZyA9PSAwKSB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBkYXRhSXNPd25lZCA9IFRSVUU7CiAgfQp9CgovKiBSdWxlQmFzZWRDb2xsYXRvciBwdWJsaWMgZGVzdHJ1Y3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKUnVsZUJhc2VkQ29sbGF0b3I6On5SdWxlQmFzZWRDb2xsYXRvcigpCnsKICBpZiAoZGF0YUlzT3duZWQpCiAgewogICAgdWNvbF9jbG9zZSh1Y29sbGF0b3IpOwogICAgZGVsZXRlIHVydWxlc3RyaW5nOwogIH0KICB1Y29sbGF0b3IgPSAwOwogIHVydWxlc3RyaW5nID0gMDsKfQoKLyogUnVsZUJhc2VDb2xsYXRvciBwdWJsaWMgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KClVCb29sIFJ1bGVCYXNlZENvbGxhdG9yOjpvcGVyYXRvcj09KGNvbnN0IENvbGxhdG9yJiB0aGF0KSBjb25zdAp7CiAgLyogb25seSBjaGVja3MgZm9yIGFkZHJlc3MgZXF1YWxzIGhlcmUgKi8KICBpZiAoQ29sbGF0b3I6Om9wZXJhdG9yPT0odGhhdCkpCiAgICByZXR1cm4gVFJVRTsKCiAgaWYgKGdldER5bmFtaWNDbGFzc0lEKCkgIT0gdGhhdC5nZXREeW5hbWljQ2xhc3NJRCgpKQogICAgcmV0dXJuIEZBTFNFOyAgLyogbm90IHRoZSBzYW1lIGNsYXNzICovCgogIFJ1bGVCYXNlZENvbGxhdG9yJiB0aGF0QWxpYXMgPSAoUnVsZUJhc2VkQ29sbGF0b3ImKXRoYXQ7CgogIC8qCiAgc3lud2VlIDogb3JnaW5hbCBjb2RlIGRvZXMgbm90IGNoZWNrIGZvciBkYXRhIGNvbXBhdGliaWxpdHkKICAqLwogIGlmICh1Y29sbGF0b3IgIT0gdGhhdEFsaWFzLnVjb2xsYXRvcikKICAgIHJldHVybiBGQUxTRTsKCiAgcmV0dXJuIFRSVUU7Cn0KClJ1bGVCYXNlZENvbGxhdG9yJiBSdWxlQmFzZWRDb2xsYXRvcjo6b3BlcmF0b3I9KGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yJiB0aGF0KQp7CiAgaWYgKHRoaXMgIT0gJnRoYXQpCiAgewogICAgaWYgKGRhdGFJc093bmVkKQogICAgewogICAgICB1Y29sX2Nsb3NlKHVjb2xsYXRvcik7CiAgICAgIHVjb2xsYXRvciA9IE5VTEw7CiAgICAgIGRlbGV0ZSB1cnVsZXN0cmluZzsKICAgIH0KCiAgICBkYXRhSXNPd25lZCA9IEZBTFNFOwogICAgdWNvbGxhdG9yID0gdGhhdC51Y29sbGF0b3I7CiAgICB1cnVsZXN0cmluZyA9IHRoYXQudXJ1bGVzdHJpbmc7CiAgfQogIHJldHVybiAqdGhpczsKfQoKQ29sbGF0b3IqIFJ1bGVCYXNlZENvbGxhdG9yOjpjbG9uZSgpIGNvbnN0CnsKICByZXR1cm4gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKCp0aGlzKTsKfQoKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlKSBjb25zdAp7CiAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yICpyZXN1bHQgPSBuZXcgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKHNvdXJjZSwgdGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgIGRlbGV0ZSByZXN1bHQ7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgoqIENyZWF0ZSBhIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBvYmplY3QgdGhhdCB3aWxsIGl0ZXJhdG9yIG92ZXIgdGhlCiogZWxlbWVudHMgaW4gYSBzdHJpbmcsIHVzaW5nIHRoZSBjb2xsYXRpb24gcnVsZXMgZGVmaW5lZCBpbiB0aGlzCiogUnVsZUJhc2VkQ29sbGF0b3IKKi8KQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgc291cmNlKSBjb25zdAp7CiAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yICpyZXN1bHQgPSBuZXcgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKHNvdXJjZSwgdGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKCiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CiAgICBkZWxldGUgcmVzdWx0OwogICAgcmV0dXJuIE5VTEw7CiAgfQoKICByZXR1cm4gcmVzdWx0Owp9CgovKioKKiBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBjb2xsYXRvcidzIHJ1bGVzLiBUaGUgc3RyaW5nIGNhbgoqIGxhdGVyIGJlIHBhc3NlZCB0byB0aGUgY29uc3RydWN0b3IgdGhhdCB0YWtlcyBhIFVuaWNvZGVTdHJpbmcgYXJndW1lbnQsCiogd2hpY2ggd2lsbCBjb25zdHJ1Y3QgYSBjb2xsYXRvciB0aGF0J3MgZnVuY3Rpb25hbGx5IGlkZW50aWNhbCB0byB0aGlzIG9uZS4KKiBZb3UgY2FuIGFsc28gYWxsb3cgdXNlcnMgdG8gZWRpdCB0aGUgc3RyaW5nIGluIG9yZGVyIHRvIGNoYW5nZSB0aGUgY29sbGF0aW9uCiogZGF0YSwgb3IgeW91IGNhbiBwcmludCBpdCBvdXQgZm9yIGluc3BlY3Rpb24sIG9yIHdoYXRldmVyLgoqLwpjb25zdCBVbmljb2RlU3RyaW5nJiBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0UnVsZXMoKSBjb25zdAp7CiAgICByZXR1cm4gKCp1cnVsZXN0cmluZyk7Cn0KCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OmdldFJ1bGVzKFVDb2xSdWxlT3B0aW9uIGRlbHRhLCBVbmljb2RlU3RyaW5nICZidWZmZXIpCnsKICAgIGludDMyX3QgcnVsZXNpemUgPSB1Y29sX2dldFJ1bGVzRXgodWNvbGxhdG9yLCBkZWx0YSwgTlVMTCwgLTEpOwoKICAgIGlmIChydWxlc2l6ZSA+IDApIHsKICAgICAgICBVQ2hhciAqcnVsZXMgPSAoVUNoYXIqKSB1cHJ2X21hbGxvYyggc2l6ZW9mKFVDaGFyKSAqIChydWxlc2l6ZSkgKTsKICAgICAgICBpZihydWxlcyAhPSBOVUxMKSB7CiAgICAgICAgICB1Y29sX2dldFJ1bGVzRXgodWNvbGxhdG9yLCBkZWx0YSwgcnVsZXMsIHJ1bGVzaXplKTsKICAgICAgICAgIGJ1ZmZlci5zZXRUbyhydWxlcywgcnVsZXNpemUpOwogICAgICAgICAgdXBydl9mcmVlKHJ1bGVzKTsKICAgICAgICB9IGVsc2UgeyAvLyBjb3VsZG4ndCBhbGxvY2F0ZSAKICAgICAgICAgIGJ1ZmZlci5yZW1vdmUoKTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBidWZmZXIucmVtb3ZlKCk7CiAgICB9Cn0KClVuaWNvZGVTZXQgKgpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0VGFpbG9yZWRTZXQoVUVycm9yQ29kZSAmc3RhdHVzKSBjb25zdAp7CiAgaWYoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgIHJldHVybiBOVUxMOwogIH0KICByZXR1cm4gKFVuaWNvZGVTZXQgKil1Y29sX2dldFRhaWxvcmVkU2V0KHRoaXMtPnVjb2xsYXRvciwgJnN0YXR1cyk7Cn0KCgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRWZXJzaW9uKFVWZXJzaW9uSW5mbyB2ZXJzaW9uSW5mbykgY29uc3QKewogICAgaWYgKHZlcnNpb25JbmZvIT1OVUxMKXsKICAgICAgICB1Y29sX2dldFZlcnNpb24odWNvbGxhdG9yLCB2ZXJzaW9uSW5mbyk7CiAgICB9Cn0KCkNvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCBSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbGVuZ3RoKSBjb25zdAp7CiAgcmV0dXJuIGNvbXBhcmUoc291cmNlLmdldEJ1ZmZlcigpLCB1cHJ2X21pbihsZW5ndGgsc291cmNlLmxlbmd0aCgpKSwgdGFyZ2V0LmdldEJ1ZmZlcigpLCB1cHJ2X21pbihsZW5ndGgsdGFyZ2V0Lmxlbmd0aCgpKSk7Cn0KCkNvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCBSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZShjb25zdCBVQ2hhciogc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ2hhciogdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCB0YXJnZXRMZW5ndGgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdAp7CiAgcmV0dXJuIGdldEVDb21wYXJpc29uUmVzdWx0KHVjb2xfc3RyY29sbCh1Y29sbGF0b3IsIHNvdXJjZSwgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCwgdGFyZ2V0TGVuZ3RoKSk7Cn0KCi8qKgoqIENvbXBhcmUgdHdvIHN0cmluZ3MgdXNpbmcgdGhpcyBjb2xsYXRvcgoqLwpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdAp7CiAgcmV0dXJuIGNvbXBhcmUoc291cmNlLmdldEJ1ZmZlcigpLCBzb3VyY2UubGVuZ3RoKCksIHRhcmdldC5nZXRCdWZmZXIoKSwgdGFyZ2V0Lmxlbmd0aCgpKTsKfQoKLyoqCiogUmV0cmlldmUgYSBjb2xsYXRpb24ga2V5IGZvciB0aGUgc3BlY2lmaWVkIHN0cmluZy4gVGhlIGtleSBjYW4gYmUgY29tcGFyZWQKKiB3aXRoIG90aGVyIGNvbGxhdGlvbiBrZXlzIHVzaW5nIGEgYml0d2lzZSBjb21wYXJpc29uIChlLmcuIG1lbWNtcCkgdG8gZmluZAoqIHRoZSBvcmRlcmluZyBvZiB0aGVpciByZXNwZWN0aXZlIHNvdXJjZSBzdHJpbmdzLiBUaGlzIGlzIGhhbmR5IHdoZW4gZG9pbmcgYQoqIHNvcnQsIHdoZXJlIGVhY2ggc29ydCBrZXkgbXVzdCBiZSBjb21wYXJlZCBtYW55IHRpbWVzLgoqCiogVGhlIGJhc2ljIGFsZ29yaXRobSBoZXJlIGlzIHRvIGZpbmQgYWxsIG9mIHRoZSBjb2xsYXRpb24gZWxlbWVudHMgZm9yIGVhY2gKKiBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBzdHJpbmcsIGNvbnZlcnQgdGhlbSB0byBhbiBBU0NJSSByZXByZXNlbnRhdGlvbiwgYW5kCiogcHV0IHRoZW0gaW50byB0aGUgY29sbGF0aW9uIGtleS4gIEJ1dCBpdCdzIHRyaWNraWVyIHRoYW4gdGhhdC4gRWFjaAoqIGNvbGxhdGlvbiBlbGVtZW50IGluIGEgc3RyaW5nIGhhcyB0aHJlZSBjb21wb25lbnRzOiBwcmltYXJ5ICgnQScgdnMgJ0InKSwKKiBzZWNvbmRhcnkgKCd1JyB2cyAn/CcpLCBhbmQgdGVydGlhcnkgKCdBJyB2cyAnYScpLCBhbmQgYSBwcmltYXJ5IGRpZmZlcmVuY2UKKiBhdCB0aGUgZW5kIG9mIGEgc3RyaW5nIHRha2VzIHByZWNlZGVuY2Ugb3ZlciBhIHNlY29uZGFyeSBvciB0ZXJ0aWFyeQoqIGRpZmZlcmVuY2UgZWFybGllciBpbiB0aGUgc3RyaW5nLgoqCiogVG8gYWNjb3VudCBmb3IgdGhpcywgd2UgcHV0IGFsbCBvZiB0aGUgcHJpbWFyeSBvcmRlcnMgYXQgdGhlIGJlZ2lubmluZyBvZgoqIHRoZSBzdHJpbmcsIGZvbGxvd2VkIGJ5IHRoZSBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IG9yZGVycy4gRWFjaCBzZXQgb2YKKiBvcmRlcnMgaXMgdGVybWluYXRlZCBieSBudWxscyBzbyB0aGF0IGEga2V5IGZvciBhIHN0cmluZyB3aGljaCBpcyBhIGluaXRpYWwKKiBzdWJzdHJpbmcgb2YgYW5vdGhlciBrZXkgd2lsbCBjb21wYXJlIGxlc3Mgd2l0aG91dCBhbnkgc3BlY2lhbCBjYXNlLgoqCiogSGVyZSdzIGEgaHlwb3RoZXRpY2FsIGV4YW1wbGUsIHdpdGggdGhlIGNvbGxhdGlvbiBlbGVtZW50IHJlcHJlc2VudGVkIGFzIGEKKiB0aHJlZS1kaWdpdCBudW1iZXIsIG9uZSBkaWdpdCBmb3IgcHJpbWFyeSwgb25lIGZvciBzZWNvbmRhcnksIGV0Yy4KKgoqIFN0cmluZzogICAgICAgICAgICAgIEEgICAgIGEgICAgIEIgICAgyQoqIENvbGxhdGlvbiBFbGVtZW50czogMTAxICAgMTAwICAgMjAxICA1MTEKKiBDb2xsYXRpb24gS2V5OiAgICAgIDExMjU8bnVsbD4wMDAxPG51bGw+MTAxMTxudWxsPgoqCiogVG8gbWFrZSB0aGluZ3MgZXZlbiB0cmlja2llciwgc2Vjb25kYXJ5IGRpZmZlcmVuY2VzIChhY2NlbnQgbWFya3MpIGFyZQoqIGNvbXBhcmVkIHN0YXJ0aW5nIGF0IHRoZSAqZW5kKiBvZiB0aGUgc3RyaW5nIGluIGxhbmd1YWdlcyB3aXRoIEZyZW5jaAoqIHNlY29uZGFyeSBvcmRlcmluZy4gQnV0IHdoZW4gY29tcGFyaW5nIHRoZSBhY2NlbnQgbWFya3Mgb24gYSBzaW5nbGUgYmFzZQoqIGNoYXJhY3RlciwgdGhleSBhcmUgY29tcGFyZWQgZnJvbSB0aGUgYmVnaW5uaW5nLiBUbyBoYW5kbGUgdGhpcywgd2UgcmV2ZXJzZQoqIGFsbCBvZiB0aGUgYWNjZW50cyB0aGF0IGJlbG9uZyB0byBlYWNoIGJhc2UgY2hhcmFjdGVyLCB0aGVuIHdlIHJldmVyc2UgdGhlCiogZW50aXJlIHN0cmluZyBvZiBzZWNvbmRhcnkgb3JkZXJpbmdzIGF0IHRoZSBlbmQuCiovCkNvbGxhdGlvbktleSYgUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbGxhdGlvbktleSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiBzb3J0a2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QKewogIHJldHVybiBnZXRDb2xsYXRpb25LZXkoc291cmNlLmdldEJ1ZmZlcigpLCBzb3VyY2UubGVuZ3RoKCksIHNvcnRrZXksIHN0YXR1cyk7Cn0KCkNvbGxhdGlvbktleSYgUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbGxhdGlvbktleShjb25zdCBVQ2hhciogc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25LZXkmIHNvcnRrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0CnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgewogICAgcmV0dXJuIHNvcnRrZXkuc2V0VG9Cb2d1cygpOwogIH0KCiAgaWYgKCghc291cmNlKSB8fCAoc291cmNlTGVuID09IDApKSB7CiAgICByZXR1cm4gc29ydGtleS5yZXNldCgpOwogIH0KCiAgdWludDhfdCAqcmVzdWx0OwogIGludDMyX3QgcmVzdWx0TGVuID0gdWNvbF9nZXRTb3J0S2V5V2l0aEFsbG9jYXRpb24odWNvbGxhdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLCBzb3VyY2VMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXR1cyk7CiAgc29ydGtleS5hZG9wdChyZXN1bHQsIHJlc3VsdExlbik7CiAgcmV0dXJuIHNvcnRrZXk7Cn0KCi8qKgogKiBSZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFueSBleHBhbnNpb24gc2VxdWVuY2VzIHRoYXQgZW5kIHdpdGggdGhlCiAqIHNwZWNpZmllZCBjb21wYXJpc29uIG9yZGVyLgogKiBAcGFyYW0gb3JkZXIgYSBjb2xsYXRpb24gb3JkZXIgcmV0dXJuZWQgYnkgcHJldmlvdXMgb3IgbmV4dC4KICogQHJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXVlbmNlcyBlbmRpbmcgd2l0aCB0aGUKICogICAgICAgICBzcGVjaWZpZWQgb3JkZXIgb3IgMSBpZiBjb2xsYXRpb24gb3JkZXIgZG9lcyBub3Qgb2NjdXIgYXQgdGhlIGVuZCBvZiBhbnkKICogICAgICAgICBleHBhbnNpb24gc2VxdWVuY2UuCiAqIEBzZWUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yI2dldE1heEV4cGFuc2lvbgogKi8KaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0TWF4RXhwYW5zaW9uKGludDMyX3Qgb3JkZXIpIGNvbnN0CnsKICB1aW50OF90IHJlc3VsdDsKICBVQ09MX0dFVE1BWEVYUEFOU0lPTih1Y29sbGF0b3IsICh1aW50MzJfdClvcmRlciwgcmVzdWx0KTsKICByZXR1cm4gcmVzdWx0Owp9Cgp1aW50OF90KiBSdWxlQmFzZWRDb2xsYXRvcjo6Y2xvbmVSdWxlRGF0YShpbnQzMl90ICZsZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpCnsKICByZXR1cm4gdWNvbF9jbG9uZVJ1bGVEYXRhKHVjb2xsYXRvciwgJmxlbmd0aCwgJnN0YXR1cyk7Cn0KCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OnNldEF0dHJpYnV0ZShVQ29sQXR0cmlidXRlIGF0dHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ29sQXR0cmlidXRlVmFsdWUgdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICByZXR1cm47CiAgdWNvbF9zZXRBdHRyaWJ1dGUodWNvbGxhdG9yLCBhdHRyLCB2YWx1ZSwgJnN0YXR1cyk7Cn0KClVDb2xBdHRyaWJ1dGVWYWx1ZSBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0QXR0cmlidXRlKFVDb2xBdHRyaWJ1dGUgYXR0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuIFVDT0xfREVGQVVMVDsKICByZXR1cm4gdWNvbF9nZXRBdHRyaWJ1dGUodWNvbGxhdG9yLCBhdHRyLCAmc3RhdHVzKTsKfQoKdWludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OnNldFZhcmlhYmxlVG9wKGNvbnN0IFVDaGFyICp2YXJUb3AsIGludDMyX3QgbGVuLCBVRXJyb3JDb2RlICZzdGF0dXMpIHsKICByZXR1cm4gdWNvbF9zZXRWYXJpYWJsZVRvcCh1Y29sbGF0b3IsIHZhclRvcCwgbGVuLCAmc3RhdHVzKTsKfQoKdWludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OnNldFZhcmlhYmxlVG9wKGNvbnN0IFVuaWNvZGVTdHJpbmcgdmFyVG9wLCBVRXJyb3JDb2RlICZzdGF0dXMpIHsKICByZXR1cm4gdWNvbF9zZXRWYXJpYWJsZVRvcCh1Y29sbGF0b3IsIHZhclRvcC5nZXRCdWZmZXIoKSwgdmFyVG9wLmxlbmd0aCgpLCAmc3RhdHVzKTsKfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6c2V0VmFyaWFibGVUb3AoY29uc3QgdWludDMyX3QgdmFyVG9wLCBVRXJyb3JDb2RlICZzdGF0dXMpIHsKICB1Y29sX3Jlc3RvcmVWYXJpYWJsZVRvcCh1Y29sbGF0b3IsIHZhclRvcCwgJnN0YXR1cyk7Cn0KCnVpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRWYXJpYWJsZVRvcChVRXJyb3JDb2RlICZzdGF0dXMpIGNvbnN0IHsKICByZXR1cm4gdWNvbF9nZXRWYXJpYWJsZVRvcCh1Y29sbGF0b3IsICZzdGF0dXMpOwp9CgpDb2xsYXRvciogUnVsZUJhc2VkQ29sbGF0b3I6OnNhZmVDbG9uZSh2b2lkKQp7CiAgVUVycm9yQ29kZSBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgaW50MzJfdCBidWZmZXJzaXplID0gVV9DT0xfU0FGRUNMT05FX0JVRkZFUlNJWkU7CiAgVUNvbGxhdG9yICp1Y29sID0gdWNvbF9zYWZlQ2xvbmUodWNvbGxhdG9yLCBOVUxMLCAmYnVmZmVyc2l6ZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmludFN0YXR1cyk7CiAgaWYgKFVfRkFJTFVSRShpbnRTdGF0dXMpKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFVuaWNvZGVTdHJpbmcgKnIgPSBuZXcgVW5pY29kZVN0cmluZygqdXJ1bGVzdHJpbmcpOwogIFJ1bGVCYXNlZENvbGxhdG9yICpyZXN1bHQgPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3IodWNvbCwgcik7CiAgcmVzdWx0LT5kYXRhSXNPd25lZCA9IFRSVUU7CiAgcmV0dXJuIHJlc3VsdDsKfQoKCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmdldFNvcnRLZXkoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgKnJlc3VsdCwgaW50MzJfdCByZXN1bHRMZW5ndGgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QKewogIHJldHVybiB1Y29sX2dldFNvcnRLZXkodWNvbGxhdG9yLCBzb3VyY2UuZ2V0QnVmZmVyKCksIHNvdXJjZS5sZW5ndGgoKSwgcmVzdWx0LCByZXN1bHRMZW5ndGgpOwp9CgppbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRTb3J0S2V5KGNvbnN0IFVDaGFyICpzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsIHVpbnQ4X3QgKnJlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHJlc3VsdExlbmd0aCkgY29uc3QKewogIHJldHVybiB1Y29sX2dldFNvcnRLZXkodWNvbGxhdG9yLCBzb3VyY2UsIHNvdXJjZUxlbmd0aCwgcmVzdWx0LCByZXN1bHRMZW5ndGgpOwp9CgpDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRTdHJlbmd0aCh2b2lkKSBjb25zdAp7CiAgVUVycm9yQ29kZSBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgcmV0dXJuIGdldEVDb2xsYXRpb25TdHJlbmd0aCh1Y29sX2dldEF0dHJpYnV0ZSh1Y29sbGF0b3IsIFVDT0xfU1RSRU5HVEgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaW50U3RhdHVzKSk7Cn0KCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OnNldFN0cmVuZ3RoKEVDb2xsYXRpb25TdHJlbmd0aCBuZXdTdHJlbmd0aCkKewogIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIFVDb2xsYXRpb25TdHJlbmd0aCBzdHJlbmd0aCA9IGdldFVDb2xsYXRpb25TdHJlbmd0aChuZXdTdHJlbmd0aCk7CiAgdWNvbF9zZXRBdHRyaWJ1dGUodWNvbGxhdG9yLCBVQ09MX1NUUkVOR1RILCBzdHJlbmd0aCwgJmludFN0YXR1cyk7Cn0KCi8qKgoqIENyZWF0ZSBhIGhhc2ggY29kZSBmb3IgdGhpcyBjb2xsYXRpb24uIEp1c3QgaGFzaCB0aGUgbWFpbiBydWxlIHRhYmxlIC0tIHRoYXQKKiBzaG91bGQgYmUgZ29vZCBlbm91Z2ggZm9yIGFsbW9zdCBhbnkgdXNlLgoqLwppbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpoYXNoQ29kZSgpIGNvbnN0CnsKICBpbnQzMl90IGxlbmd0aDsKICBjb25zdCBVQ2hhciAqcnVsZXMgPSB1Y29sX2dldFJ1bGVzKHVjb2xsYXRvciwgJmxlbmd0aCk7CiAgcmV0dXJuIHVoYXNoX2hhc2hVQ2hhcnNOKHJ1bGVzLCBsZW5ndGgpOwp9CgovKioKKiByZXR1cm4gdGhlIGxvY2FsZSBvZiB0aGlzIGNvbGxhdG9yCiovCmNvbnN0IExvY2FsZSBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0TG9jYWxlKFVMb2NEYXRhTG9jYWxlVHlwZSB0eXBlLCBVRXJyb3JDb2RlICZzdGF0dXMpIGNvbnN0IHsKICBjb25zdCBjaGFyICpyZXN1bHQgPSB1Y29sX2dldExvY2FsZSh1Y29sbGF0b3IsIHR5cGUsICZzdGF0dXMpOwogIGlmKHJlc3VsdCA9PSBOVUxMKSB7CiAgICBMb2NhbGUgcmVzKCIiKTsKICAgIHJlcy5zZXRUb0JvZ3VzKCk7CiAgICByZXR1cm4gcmVzOwogIH0gZWxzZSB7CiAgICByZXR1cm4gTG9jYWxlKHJlc3VsdCk7CiAgfQp9CgovLyBSdWxlQmFzZUNvbGxhdG9yTmV3IHByaXZhdGUgY29uc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKCkgOiBkYXRhSXNPd25lZChGQUxTRSksIHVjb2xsYXRvcigwKQp7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihVQ29sbGF0b3IgKmNvbGxhdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyAqcnVsZSkgOiBkYXRhSXNPd25lZChGQUxTRSkKewogIHVjb2xsYXRvciA9IGNvbGxhdG9yOwogIHVydWxlc3RyaW5nID0gcnVsZTsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IExvY2FsZSYgZGVzaXJlZExvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUlzT3duZWQoRkFMU0UpLCB1Y29sbGF0b3IoMCkKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHJldHVybjsKCiAgLyoKICBUcnkgdG8gbG9hZCwgaW4gb3JkZXI6CiAgIDEuIFRoZSBkZXNpcmVkIGxvY2FsZSdzIGNvbGxhdGlvbi4KICAgMi4gQSBmYWxsYmFjayBvZiB0aGUgZGVzaXJlZCBsb2NhbGUuCiAgIDMuIFRoZSBkZWZhdWx0IGxvY2FsZSdzIGNvbGxhdGlvbi4KICAgNC4gQSBmYWxsYmFjayBvZiB0aGUgZGVmYXVsdCBsb2NhbGUuCiAgIDUuIFRoZSBkZWZhdWx0IGNvbGxhdGlvbiBydWxlcywgd2hpY2ggY29udGFpbnMgZW5fVVMgY29sbGF0aW9uIHJ1bGVzLgoKICAgVG8gcmVpdGVyYXRlLCB3ZSB0cnk6CiAgIFNwZWNpZmljOgogICAgbGFuZ3VhZ2UrY291bnRyeSt2YXJpYW50CiAgICBsYW5ndWFnZStjb3VudHJ5CiAgICBsYW5ndWFnZQogICBEZWZhdWx0OgogICAgbGFuZ3VhZ2UrY291bnRyeSt2YXJpYW50CiAgICBsYW5ndWFnZStjb3VudHJ5CiAgICBsYW5ndWFnZQogICBSb290OiAoYWthIERFRkFVTFRSVUxFUykKICAgc3RlcHMgMS01IGFyZSBoYW5kbGVkIGJ5IHJlc291cmNlIGJ1bmRsZSBmYWxsYmFjayBtZWNoYW5pc20uCiAgIGhvd2V2ZXIsIGluIGEgdmVyeSB1bnByb2JhYmxlIHNpdHVhdGlvbiB0aGF0IG5vIHJlc291cmNlIGJ1bmRsZQogICBkYXRhIGV4aXN0cywgc3RlcCA1IGlzIHJlcGVhdGVkIHdpdGggaGFyZGNvZGVkIGRlZmF1bHQgcnVsZXMuCiAgKi8KCiAgc2V0VUNvbGxhdG9yKGRlc2lyZWRMb2NhbGUsIHN0YXR1cyk7CgogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICB7CiAgICBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CgogICAgc2V0VUNvbGxhdG9yKGtSb290TG9jYWxlTmFtZSwgc3RhdHVzKTsKICAgIGlmIChzdGF0dXMgPT0gVV9aRVJPX0VSUk9SKSB7CiAgICAgICAgc3RhdHVzID0gVV9VU0lOR19ERUZBVUxUX1dBUk5JTkc7CiAgICB9CiAgfQoKICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpCiAgewogICAgaW50MzJfdCBsZW5ndGg7CiAgICBjb25zdCBVQ2hhciAqciA9IHVjb2xfZ2V0UnVsZXModWNvbGxhdG9yLCAmbGVuZ3RoKTsKICAgIGlmIChsZW5ndGggPiAwKSB7CiAgICAgICAgLy8gYWxpYXMgdGhlIHJ1bGVzIHN0cmluZwogICAgICAgIHVydWxlc3RyaW5nID0gbmV3IFVuaWNvZGVTdHJpbmcoVFJVRSwgciwgbGVuZ3RoKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHVydWxlc3RyaW5nID0gbmV3IFVuaWNvZGVTdHJpbmcoKTsKICAgIH0KICAgIC8qIHRlc3QgZm9yIE5VTEwgKi8KICAgIGlmICh1cnVsZXN0cmluZyA9PSAwKSB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBkYXRhSXNPd25lZCA9IFRSVUU7CiAgfQoKICByZXR1cm47Cn0KCi8qIFJ1bGVCYXNlZENvbGxhdG9yIHByaXZhdGUgZGF0YSBtZW1iZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKgogKiBUT0RPOgogKiBUaGVzZSBzaG91bGQgcHJvYmFibHkgYmUgZW51bXMgKDw9MHhmZmZmKSBvciAjZGVmaW5lcyAoPjB4ZmZmZikKICogZm9yIGJldHRlciBwZXJmb3JtYW5jZS4KICogSW5jbHVkZSB1Y29sX2ltcC5oIGFuZCB1c2UgaXRzIGNvbnN0YW50cyBpZiBwb3NzaWJsZS4KICogT25seSB1c2VkIGluIGNvbGVpdHIuaD8hCiAqIFJlbW92ZSBmcm9tIGhlcmUhCiAqLwoKLyogbmVlZCBsb29rIHVwIGluIC5jb21taXQoKSAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDSEFSSU5ERVggPSAweDcwMDAwMDAwOwovKiBFeHBhbmQgaW5kZXggZm9sbG93cyAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpFWFBBTkRDSEFSSU5ERVggPSAweDdFMDAwMDAwOwovKiBjb250cmFjdCBpbmRleGVzIGZvbGxvd3MgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Q09OVFJBQ1RDSEFSSU5ERVggPSAweDdGMDAwMDAwOwovKiB1bm1hcHBlZCBjaGFyYWN0ZXIgdmFsdWVzICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlVOTUFQUEVEID0gMHhGRkZGRkZGRjsKLyogcHJpbWFyeSBzdHJlbmd0aCBpbmNyZW1lbnQgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAxMDAwMDsKLyogc2Vjb25kYXJ5IHN0cmVuZ3RoIGluY3JlbWVudCAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUklOQ1JFTUVOVCA9IDB4MDAwMDAxMDA7Ci8qIHRlcnRpYXJ5IHN0cmVuZ3RoIGluY3JlbWVudCAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpURVJUSUFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAwMDAwMTsKLyogbWFzayBvZmYgYW55dGhpbmcgYnV0IHByaW1hcnkgb3JkZXIgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSTUFTSyA9IDB4ZmZmZjAwMDA7Ci8qIG1hc2sgb2ZmIGFueXRoaW5nIGJ1dCBzZWNvbmRhcnkgb3JkZXIgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJNQVNLID0gMHgwMDAwZmYwMDsKLyogbWFzayBvZmYgYW55dGhpbmcgYnV0IHRlcnRpYXJ5IG9yZGVyICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJNQVNLID0gMHgwMDAwMDBmZjsKLyogbWFzayBvZmYgaWdub3JhYmxlIGNoYXIgb3JkZXIgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6SUdOT1JBQkxFTUFTSyA9IDB4MDAwMGZmZmY7Ci8qIHVzZSBvbmx5IHRoZSBwcmltYXJ5IGRpZmZlcmVuY2UgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWURJRkZFUkVOQ0VPTkxZID0gMHhmZmZmMDAwMDsKLyogdXNlIG9ubHkgdGhlIHByaW1hcnkgYW5kIHNlY29uZGFyeSBkaWZmZXJlbmNlICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWURJRkZFUkVOQ0VPTkxZID0gMHhmZmZmZmYwMDsKLyogcHJpbWFyeSBvcmRlciBzaGlmdCAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJTSElGVCA9IDE2OwovKiBzZWNvbmRhcnkgb3JkZXIgc2hpZnQgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJTSElGVCA9IDg7Ci8qIHN0YXJ0aW5nIHZhbHVlIGZvciBjb2xsYXRpb24gZWxlbWVudHMgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Q09MRUxFTUVOVFNUQVJUID0gMHgwMjAyMDIwMjsKLyogdGVzdGluZyBtYXNrIGZvciBwcmltYXJ5IGxvdyBlbGVtZW50ICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllMT1daRVJPTUFTSyA9IDB4MDBGRjAwMDA7Ci8qIHJlc2V0aW5nIHZhbHVlIGZvciBzZWNvbmRhcmllcyBhbmQgdGVydGlhcmllcyAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpSRVNFVFNFQ09OREFSWVRFUlRJQVJZID0gMHgwMDAwMDIwMjsKLyogcmVzZXRpbmcgdmFsdWUgZm9yIHRlcnRpYXJpZXMgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UkVTRVRURVJUSUFSWSA9IDB4MDAwMDAwMDI7Cgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNSUdOT1JBQkxFID0gMHgwMjAyOwoKLyogdW5pcXVlIGZpbGUgaWQgZm9yIHBhcml0eSBjaGVjayAqLwpjb25zdCBpbnQxNl90IFJ1bGVCYXNlZENvbGxhdG9yOjpGSUxFSUQgPSAweDU0NDM7Ci8qIGJpbmFyeSBjb2xsYXRpb24gZmlsZSBleHRlbnNpb24gKi8KY29uc3QgY2hhciBSdWxlQmFzZWRDb2xsYXRvcjo6a0ZpbGVuYW1lU3VmZml4W10gPSAiLmNvbCI7Ci8qIGNsYXNzIGlkID8gVmFsdWUgaXMgaXJyZWxldmFudCAqLwpjb25zdCBjaGFyICBSdWxlQmFzZWRDb2xsYXRvcjo6ZmdDbGFzc0lEID0gMDsKClVfTkFNRVNQQUNFX0VORAoKI2VuZGlmIC8qICNpZiAhVUNPTkZJR19OT19DT0xMQVRJT04gKi8K