LyoKKiBDb3B5cmlnaHQgqSB7MTk5Ni0xOTk5fSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCioKKiBGaWxlIHRibGNvbGwuaAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCiogIDIvNS85NyAgICAgIGFsaXUgICAgICAgIEFkZGVkIHN0cmVhbUluIGFuZCBzdHJlYW1PdXQgbWV0aG9kcy4gIEFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIHdoaWNoIHJlYWRzIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdCBmcm9tCiogICAgICAgICAgICAgICAgICAgICAgICAgIGEgYmluYXJ5IGZpbGUuICBBZGRlZCB3cml0ZVRvRmlsZSBtZXRob2Qgd2hpY2ggc3RyZWFtcwoqICAgICAgICAgICAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciBvdXQgdG8gYSBiaW5hcnkgZmlsZS4gIFRoZSBzdHJlYW1JbgoqICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgc3RyZWFtT3V0IG1ldGhvZHMgdXNlIGlzdHJlYW0gYW5kIG9zdHJlYW0gb2JqZWN0cwoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbiBiaW5hcnkgbW9kZS4KKiAgMi8xMi85NyAgICAgYWxpdSAgICAgICAgTW9kaWZpZWQgdG8gdXNlIFRhYmxlQ29sbGF0aW9uRGF0YSBzdWItb2JqZWN0IHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIGhvbGQgaW52YXJpYW50IGRhdGEuCiogIDIvMTMvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIHNldmVyYWwgbWV0aG9kcyBpbnRvIHRoaXMgY2xhc3MgZnJvbSBDb2xsYXRpb24uCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIGEgcHJpdmF0ZSBSdWxlQmFzZWRDb2xsYXRvcihMb2NhbGUmKSBjb25zdHJ1Y3RvciwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gYmUgdXNlZCBieSBDb2xsYXRvcjo6Y3JlYXRlRGVmYXVsdCgpLiAgR2VuZXJhbAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhbiB1cC4KKiAgMi8yMC85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgY2xvbmUsIG9wZXJhdG9yPT0sIG9wZXJhdG9yIT0sIG9wZXJhdG9yPSwgYW5kIGNvcHkKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3IgYW5kIGdldER5bmFtaWNDbGFzc0lELgoqICAzLzUvOTcgICAgICBhbGl1ICAgICAgICBNb2RpZmllZCBjb25zdHJ1Y3RGcm9tRmlsZSgpIHRvIGFkZCBwYXJhbWV0ZXIKKiAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmeWluZyB3aGV0aGVyIG9yIG5vdCBiaW5hcnkgbG9hZGluZyBpcyB0byBiZQoqICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRlbXB0ZWQuICBUaGlzIGlzIHJlcXVpcmVkIGZvciBkeW5hbWljIHJ1bGUgbG9hZGluZy4KKiAwNS8wNy85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgbWVtb3J5IGFsbG9jYXRpb24gZXJyb3IgZGV0ZWN0aW9uLgoqICA2LzE3Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBJREVOVElDQUwgc3RyZW5ndGggZm9yIGNvbXBhcmUsIGNoYW5nZWQgZ2V0UnVsZXMgdG8gCiogICAgICAgICAgICAgICAgICAgICAgICAgIHVzZSBNZXJnZUNvbGxhdGlvbjo6Z2V0UGF0dGVybi4KKiAgNi8yMC85NyAgICAgaGVsZW5hICAgICAgSmF2YSBjbGFzcyBuYW1lIGNoYW5nZS4KKiAgOC8xOC85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgaW50ZXJuYWwgQVBJIGRvY3VtZW50YXRpb24uCiogMDkvMDMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNyZWF0ZUNvbGxhdGlvbktleVZhbHVlcygpLgoqIDAyLzEwLzk4ICAgICBkYW1pYmEgICAgICBBZGRlZCBjb21wYXJlIHdpdGggImxlbmd0aCIgcGFyYW1ldGVyCiogMDgvMDUvOTggICAgIGVybSAgICAgICAgIFN5bmNoZWQgd2l0aCAxLjIgdmVyc2lvbiBvZiBSdWxlQmFzZWRDb2xsYXRvci5qYXZhCiogMDQvMjMvOTkgICAgIHN0ZXBoZW4gICAgIFJlbW92ZWQgRURlY29tcG9zaXRpb25Nb2RlLCBtZXJnZWQgd2l0aAoqICAgICAgICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZQoqIDA2LzE0Lzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIGtSZXNvdXJjZUJ1bmRsZVN1ZmZpeAoqIDExLzAyLzk5ICAgICBoZWxlbmEgICAgICBDb2xsYXRvciBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuICBFbGltaW5hdGVzIHRoZSAKKiAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBjb25zdHJ1Y3Rpb24gYW5kIHNwZWNpYWwgY2FzZSBmb3IgTk9fT1AuCiogMTEvMjMvOTkgICAgIHNybCAgICAgICAgIE1vcmUgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiBVcGRhdGVzIHRvIE5vcm1hbGl6ZXJJdGVyYXRvcgoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcm5hbCBzdGF0ZSBtYW5hZ2VtZW50LgoqIDEyLzE1Lzk5ICAgICBhbGl1ICAgICAgICBVcGRhdGUgdG8gc3VwcG9ydCBUaGFpIGNvbGxhdGlvbi4gIE1vdmUgTm9ybWFsaXplckl0ZXJhdG9yCiogICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGltcGxlbWVudGF0aW9uIGZpbGUuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCiNpZm5kZWYgVEJMQ09MTF9ICiNkZWZpbmUgVEJMQ09MTF9ICgojaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKI2luY2x1ZGUgInVuaWNvZGUvY29sbC5oIgojaW5jbHVkZSAidW5pY29kZS9jaGFyaXRlci5oIgojaW5jbHVkZSAidW5pY29kZS91bmlzdHIuaCIKI2luY2x1ZGUgInVuaWNvZGUvc29ydGtleS5oIgojaW5jbHVkZSAidW5pY29kZS9ub3JtbHpyLmgiCgpjbGFzcyBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudDsKY2xhc3MgVmVjdG9yT2ZJbnQ7CmNsYXNzIFZlY3Rvck9mUFRvQ29udHJhY3RUYWJsZTsKY2xhc3MgVmVjdG9yT2ZQVG9FeHBhbmRUYWJsZTsKY2xhc3MgTWVyZ2VDb2xsYXRpb247CmNsYXNzIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjsKY2xhc3MgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjsKY2xhc3MgTm9ybWFsaXplckl0ZXJhdG9yOyAvLyBzZWUgdGJsY29sbC5jcHAKY2xhc3MgQ29sbGF0b3I7CmNsYXNzIFRhYmxlQ29sbGF0aW9uRGF0YTsKCi8qKgogKiBUaGUgUnVsZUJhc2VkQ29sbGF0b3IgY2xhc3MgcHJvdmlkZXMgdGhlIHNpbXBsZSBpbXBsZW1lbnRhdGlvbiBvZiBDb2xsYXRvciwKICogdXNpbmcgZGF0YS1kcml2ZW4gdGFibGVzLiAgVGhlIHVzZXIgY2FuIGNyZWF0ZSBhIGN1c3RvbWl6ZWQgdGFibGUtYmFzZWQKICogY29sbGF0aW9uLgogKiA8UD4KICogUnVsZUJhc2VkQ29sbGF0b3IgbWFwcyBjaGFyYWN0ZXJzIHRvIGNvbGxhdGlvbiBrZXlzLgogKiA8cD4KICogVGFibGUgQ29sbGF0aW9uIGhhcyB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9ucyBmb3IgZWZmaWNpZW5jeSAob3RoZXIKICogc3ViY2xhc3NlcyBtYXkgYmUgdXNlZCBmb3IgbW9yZSBjb21wbGV4IGxhbmd1YWdlcykgOgogKiAgICAgICA8cD4xLiBJZiB0aGUgRnJlbmNoIHNlY29uZGFyeSBvcmRlcmluZyBpcyBzcGVjaWZpZWQgaW4gYSBjb2xsYXRpb24gb2JqZWN0LCAKICogICAgICAgICAgICAgaXQgaXMgYXBwbGllZCB0byB0aGUgd2hvbGUgb2JqZWN0LgogKiAgICAgICA8cD4yLiBBbGwgbm9uLW1lbnRpb25lZCBVbmljb2RlIGNoYXJhY3RlcnMgYXJlIGF0IHRoZSBlbmQgb2YgdGhlCiAqICAgICAgICAgICAgIGNvbGxhdGlvbiBvcmRlci4KICogICAgICAgPHA+My4gUHJpdmF0ZSB1c2UgY2hhcmFjdGVycyBhcmUgdHJlYXRlZCBhcyBpZGVudGljYWwuICBUaGUgcHJpdmF0ZQogKiAgICAgICAgICAgICB1c2UgYXJlYSBpbiBVbmljb2RlIGlzIDB4RTgwMC0weEY4RkYuCiAqIDxwPlRoZSBjb2xsYXRpb24gdGFibGUgaXMgY29tcG9zZWQgb2YgYSBsaXN0IG9mIGNvbGxhdGlvbiBydWxlcywgd2hlcmUgZWFjaAogKiBydWxlIGlzIG9mIHRocmVlIGZvcm1zOgogKiA8cHJlPgogKiAuICAgICZsdDsgbW9kaWZpZXIgPgogKiAuICAgICZsdDsgcmVsYXRpb24gPiAmbHQ7IHRleHQtYXJndW1lbnQgPgogKiAuICAgICZsdDsgcmVzZXQgPiAmbHQ7IHRleHQtYXJndW1lbnQgPgogKiA8L3ByZT4KICogVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHRvIGNyZWF0ZSB5b3VyIG93biBjb2xsYXRpb24gcnVsZXM6CiAqIDxVTCBUeXBlPXJvdW5kPgogKiAgICA8TEk+PHN0cm9uZz5UZXh0IEFyZ3VtZW50PC9zdHJvbmc+OiBBIHRleHQgYXJndW1lbnQgaXMgYW55IHNlcXVlbmNlIG9mCiAqICAgICAgICBjaGFyYWN0ZXJzLCBleGNsdWRpbmcgc3BlY2lhbCBjaGFyYWN0ZXJzICh0aGF0IGlzLCB3aGl0ZXNwYWNlCiAqICAgICAgICBjaGFyYWN0ZXJzIGFuZCB0aGUgY2hhcmFjdGVycyB1c2VkIGluIG1vZGlmaWVyLCByZWxhdGlvbiBhbmQgcmVzZXQpLgogKiAgICAgICAgSWYgdGhvc2UgY2hhcmFjdGVycyBhcmUgZGVzaXJlZCwgeW91IGNhbiBwdXQgdGhlbSBpbiBzaW5nbGUgcXVvdGVzCiAqICAgICAgICAoZS5nLiBhbXBlcnNhbmQgPT4gJyYnKS48UD4KICogICAgPExJPjxzdHJvbmc+TW9kaWZpZXI8L3N0cm9uZz46IFRoZXJlIGlzIGEgc2luZ2xlIG1vZGlmaWVyLAogKiAgICAgICAgd2hpY2ggaXMgdXNlZCB0byBzcGVjaWZ5IHRoYXQgYWxsIHNlY29uZGFyeSBkaWZmZXJlbmNlcyBhcmUKICogICAgICAgIHNvcnRlZCBiYWNrd2FyZHMuCiAqICAgICAgICA8cD4nQCcgOiBJbmRpY2F0ZXMgdGhhdCBzZWNvbmRhcnkgZGlmZmVyZW5jZXMsIHN1Y2ggYXMgYWNjZW50cywgYXJlIAogKiAgICAgICAgICAgICAgICAgc29ydGVkIGJhY2t3YXJkcywgYXMgaW4gRnJlbmNoLjxQPgogKiAgICA8TEk+PHN0cm9uZz5SZWxhdGlvbjwvc3Ryb25nPjogVGhlIHJlbGF0aW9ucyBhcmUgdGhlIGZvbGxvd2luZzoKICogICAgICAgIDxVTCBUeXBlPXNxdWFyZT4KICogICAgICAgICAgICA8TEk+JyZsdDsnIDogR3JlYXRlciwgYXMgYSBsZXR0ZXIgZGlmZmVyZW5jZSAocHJpbWFyeSkKICogICAgICAgICAgICA8TEk+JzsnIDogR3JlYXRlciwgYXMgYW4gYWNjZW50IGRpZmZlcmVuY2UgKHNlY29uZGFyeSkKICogICAgICAgICAgICA8TEk+JywnIDogR3JlYXRlciwgYXMgYSBjYXNlIGRpZmZlcmVuY2UgKHRlcnRpYXJ5KQogKiAgICAgICAgICAgIDxMST4nPScgOiBFcXVhbAogKiAgICAgICAgPC9VTD48UD4KICogICAgPExJPjxzdHJvbmc+UmVzZXQ8L3N0cm9uZz46IFRoZXJlIGlzIGEgc2luZ2xlIHJlc2V0LAogKiAgICAgICAgd2hpY2ggaXMgdXNlZCBwcmltYXJpbHkgZm9yIGNvbnRyYWN0aW9ucyBhbmQgZXhwYW5zaW9ucywgYnV0IHdoaWNoCiAqICAgICAgICBjYW4gYWxzbyBiZSB1c2VkIHRvIGFkZCBhIG1vZGlmaWNhdGlvbiBhdCB0aGUgZW5kIG9mIGEgc2V0IG9mIHJ1bGVzLgogKiAgICAgICAgPHA+JyYnIDogSW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcnVsZSBmb2xsb3dzIHRoZSBwb3NpdGlvbiB0byB3aGVyZQogKiAgICAgICAgICAgIHRoZSByZXNldCB0ZXh0LWFyZ3VtZW50IHdvdWxkIGJlIHNvcnRlZC4KICoKICogPHA+CiAqIFRoaXMgc291bmRzIG1vcmUgY29tcGxpY2F0ZWQgdGhhbiBpdCBpcyBpbiBwcmFjdGljZS4gRm9yIGV4YW1wbGUsIHRoZQogKiBmb2xsb3dpbmcgYXJlIGVxdWl2YWxlbnQgd2F5cyBvZiBleHByZXNzaW5nIHRoZSBzYW1lIHRoaW5nOgogKiA8cHJlPgogKiAuICAgIGEgJmx0OyBiICZsdDsgYwogKiAuICAgIGEgJmx0OyBiICYgYiAmbHQ7IGMKICogLiAgICBhICZsdDsgYyAmIGEgJmx0OyBiCiAqIDwvcHJlPgogKiBOb3RpY2UgdGhhdCB0aGUgb3JkZXIgaXMgaW1wb3J0YW50LCBhcyB0aGUgc3Vic2VxdWVudCBpdGVtIGdvZXMgaW1tZWRpYXRlbHkKICogYWZ0ZXIgdGhlIHRleHQtYXJndW1lbnQuIFRoZSBmb2xsb3dpbmcgYXJlIG5vdCBlcXVpdmFsZW50OgogKiA8cHJlPgogKiAuICAgIGEgJmx0OyBiICYgYSAmbHQ7IGMKICogLiAgICBhICZsdDsgYyAmIGEgJmx0OyBiCiAqIDwvcHJlPgogKiBFaXRoZXIgdGhlIHRleHQtYXJndW1lbnQgbXVzdCBhbHJlYWR5IGJlIHByZXNlbnQgaW4gdGhlIHNlcXVlbmNlLCBvciBzb21lCiAqIGluaXRpYWwgc3Vic3RyaW5nIG9mIHRoZSB0ZXh0LWFyZ3VtZW50IG11c3QgYmUgcHJlc2VudC4gKGUuZy4gImEgJmx0OyBiICYgYWUgJmx0OwogKiBlIiBpcyB2YWxpZCBzaW5jZSAiYSIgaXMgcHJlc2VudCBpbiB0aGUgc2VxdWVuY2UgYmVmb3JlICJhZSIgaXMgcmVzZXQpLiBJbgogKiB0aGlzIGxhdHRlciBjYXNlLCAiYWUiIGlzIG5vdCBlbnRlcmVkIGFuZCB0cmVhdGVkIGFzIGEgc2luZ2xlIGNoYXJhY3RlcjsKICogaW5zdGVhZCwgImUiIGlzIHNvcnRlZCBhcyBpZiBpdCB3ZXJlIGV4cGFuZGVkIHRvIHR3byBjaGFyYWN0ZXJzOiAiYSIKICogZm9sbG93ZWQgYnkgYW4gImUiLiBUaGlzIGRpZmZlcmVuY2UgYXBwZWFycyBpbiBuYXR1cmFsIGxhbmd1YWdlczogaW4KICogdHJhZGl0aW9uYWwgU3BhbmlzaCAiY2giIGlzIHRyZWF0ZWQgYXMgdGhvdWdoIGl0IGNvbnRyYWN0cyB0byBhIHNpbmdsZQogKiBjaGFyYWN0ZXIgKGV4cHJlc3NlZCBhcyAiYyAmbHQ7IGNoICZsdDsgZCIpLCB3aGlsZSBpbiB0cmFkaXRpb25hbCBHZXJtYW4gIuQiCiAqIChhLXVtbGF1dCkgaXMgdHJlYXRlZCBhcyB0aG91Z2ggaXQgZXhwYW5kcyB0byB0d28gY2hhcmFjdGVycyAoZXhwcmVzc2VkIGFzCiAqICJhICYgYWUgOyDkICZsdDsgYiIpLgogKiA8cD48c3Ryb25nPklnbm9yYWJsZSBDaGFyYWN0ZXJzPC9zdHJvbmc+CiAqIDxwPkZvciBpZ25vcmFibGUgY2hhcmFjdGVycywgdGhlIGZpcnN0IHJ1bGUgbXVzdCBzdGFydCB3aXRoIGEgcmVsYXRpb24gKHRoZQogKiBleGFtcGxlcyB3ZSBoYXZlIHVzZWQgYWJvdmUgYXJlIHJlYWxseSBmcmFnbWVudHM7ICJhICZsdDsgYiIgcmVhbGx5IHNob3VsZCBiZQogKiAiJmx0OyBhICZsdDsgYiIpLiBJZiwgaG93ZXZlciwgdGhlIGZpcnN0IHJlbGF0aW9uIGlzIG5vdCAiJmx0OyIsIHRoZW4gYWxsIHRoZSAKICogdGV4dC1hcmd1bWVudHMgdXAgdG8gdGhlIGZpcnN0ICImbHQ7IiBhcmUgaWdub3JhYmxlLiBGb3IgZXhhbXBsZSwgIiwgLSAmbHQ7IGEgJmx0OyBiIgogKiBtYWtlcyAiLSIgYW4gaWdub3JhYmxlIGNoYXJhY3RlciwgYXMgd2Ugc2F3IGVhcmxpZXIgaW4gdGhlIHdvcmQKICogImJsYWNrLWJpcmRzIi4gSW4gdGhlIHNhbXBsZXMgZm9yIGRpZmZlcmVudCBsYW5ndWFnZXMsIHlvdSBzZWUgdGhhdCBtb3N0CiAqIGFjY2VudHMgYXJlIGlnbm9yYWJsZS4KICogPHA+PHN0cm9uZz5Ob3JtYWxpemF0aW9uIGFuZCBBY2NlbnRzPC9zdHJvbmc+CiAqIDxwPlRoZSBDb2xsYXRvciBvYmplY3QgYXV0b21hdGljYWxseSBub3JtYWxpemVzIHRleHQgaW50ZXJuYWxseSB0byBzZXBhcmF0ZQogKiBhY2NlbnRzIGZyb20gYmFzZSBjaGFyYWN0ZXJzIHdoZXJlIHBvc3NpYmxlLiBUaGlzIGlzIGRvbmUgYm90aCB3aGVuCiAqIHByb2Nlc3NpbmcgdGhlIHJ1bGVzLCBhbmQgd2hlbiBjb21wYXJpbmcgdHdvIHN0cmluZ3MuIENvbGxhdG9yIGFsc28gdXNlcwogKiB0aGUgVW5pY29kZSBjYW5vbmljYWwgbWFwcGluZyB0byBlbnN1cmUgdGhhdCBjb21iaW5pbmcgc2VxdWVuY2VzIGFyZSBzb3J0ZWQKICogcHJvcGVybHkgKGZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgPEEgSFJFRj0iaHR0cDovL3d3dy5hdy5jb20vZGV2cHJlc3MiPgogKiBUaGUgVW5pY29kZSBTdGFuZGFyZCwgVmVyc2lvbiAyLjA8L0E+Lik8L1A+CiAqIDxwPjxzdHJvbmc+RXJyb3JzPC9zdHJvbmc+CiAqIDxwPlRoZSBmb2xsb3dpbmcgYXJlIGVycm9yczoKICogPFVMIFR5cGU9cm91bmQ+CiAqICAgICA8TEk+QSB0ZXh0LWFyZ3VtZW50IGNvbnRhaW5zIHVucXVvdGVkIHB1bmN0dWF0aW9uIHN5bWJvbHMKICogICAgICAgIChlLmcuICJhICZsdDsgYi1jICZsdDsgZCIpLgogKiAgICAgPExJPkEgcmVsYXRpb24gb3IgcmVzZXQgY2hhcmFjdGVyIG5vdCBmb2xsb3dlZCBieSBhIHRleHQtYXJndW1lbnQKICogICAgICAgIChlLmcuICJhICZsdDsgLCBiIikuCiAqICAgICA8TEk+QSByZXNldCB3aGVyZSB0aGUgdGV4dC1hcmd1bWVudCAob3IgYW4gaW5pdGlhbCBzdWJzdHJpbmcgb2YgdGhlCiAqICAgICAgICAgdGV4dC1hcmd1bWVudCkgaXMgbm90IGFscmVhZHkgaW4gdGhlIHNlcXVlbmNlLgogKiAgICAgICAgIChlLmcuICJhICZsdDsgYiAmIGUgJmx0OyBmIikKICogPC9VTD4KICogPHByZT4KICogLiAgICBFeGFtcGxlczoKICogLiAgICBTaW1wbGU6ICAgICAiJmx0OyBhICZsdDsgYiAmbHQ7IGMgJmx0OyBkIgogKiAuICAgIE5vcndlZ2lhbjogICImbHQ7IGEsQSZsdDsgYixCJmx0OyBjLEMmbHQ7IGQsRCZsdDsgZSxFJmx0OyBmLEYmbHQ7IGcsRyZsdDsgaCxIJmx0OyBpLEkmbHQ7IGosSgogKiAuICAgICAgICAgICAgICAgICAmbHQ7IGssSyZsdDsgbCxMJmx0OyBtLE0mbHQ7IG4sTiZsdDsgbyxPJmx0OyBwLFAmbHQ7IHEsUSZsdDsgcixSJmx0OyBzLFMmbHQ7IHQsVAogKiAuICAgICAgICAgICAgICAgICAmbHQ7IHUsVSZsdDsgdixWJmx0OyB3LFcmbHQ7IHgsWCZsdDsgeSxZJmx0OyB6LFoKICogLiAgICAgICAgICAgICAgICAgJmx0OyDlPWGwLMU9QbAKICogLiAgICAgICAgICAgICAgICAgO2FhLEFBJmx0OyDmLMYmbHQ7IPgs2CIKICogPC9wcmU+CiAqIDxwPlRvIGNyZWF0ZSBhIHRhYmxlLWJhc2VkIGNvbGxhdGlvbiBvYmplY3QsIHNpbXBseSBzdXBwbHkgdGhlIGNvbGxhdGlvbgogKiBydWxlcyB0byB0aGUgUnVsZUJhc2VkQ29sbGF0b3IgY29udHJ1Y3Rvci4gIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAuICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAuICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteVNpbXBsZSA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvcihTaW1wbGUsIHN0YXR1cyk7CiAqIDwvcHJlPgogKiA8cD5Bbm90aGVyIGV4YW1wbGU6CiAqIDxwcmU+CiAqIC4gICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqIC4gICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15Tm9yd2VnaWFuID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKE5vcndlZ2lhbiwgc3RhdHVzKTsKICogPC9wcmU+CiAqIFRvIGFkZCBydWxlcyBvbiB0b3Agb2YgYW4gZXhpc3RpbmcgdGFibGUsIHNpbXBseSBzdXBwbHkgdGhlIG9yZ2luYWwgcnVsZXMKICogYW5kIG1vZGlmaWNhdGlvbnMgdG8gUnVsZUJhc2VkQ29sbGF0b3IgY29uc3RydWN0b3IuICBGb3IgZXhhbXBsZSwKICogPHByZT4KICogLiAgICAgVHJhZGl0aW9uYWwgU3BhbmlzaCAoZnJhZ21lbnQpOiAuLi4gJiBDICZsdDsgY2ggLCBjSCAsIENoICwgQ0ggLi4uCiAqIC4gICAgIEdlcm1hbiAoZnJhZ21lbnQpIDogLi4uJmx0OyB5ICwgWSAmbHQ7IHogLCBaCiAqIC4gICAgICAgICAgICAgICAgICAgICAgICAgJiBBRSwgxCAmIEFFLCDkIAogKiAuICAgICAgICAgICAgICAgICAgICAgICAgICYgT0UgLCDWICYgT0UsIPYgCiAqIC4gICAgICAgICAgICAgICAgICAgICAgICAgJiBVRSAsINwgJiBVRSwg/CAKICogLiAgICAgU3ltYm9scyAoZnJhZ21lbnQpOiAuLi4mbHQ7IHksIFkgJmx0OyB6ICwgWgogKiAuICAgICAgICAgICAgICAgICAgICAgICAgICYgUXVlc3Rpb24tbWFyayA7ICc/JwogKiAuICAgICAgICAgICAgICAgICAgICAgICAgICYgQW1wZXJzYW5kIDsgJyYnCiAqIC4gICAgICAgICAgICAgICAgICAgICAgICAgJiBEb2xsYXItc2lnbiA7ICckJwogKiA8cD5UbyBjcmVhdGUgYSBjb2xsYXRpb24gb2JqZWN0IGZvciB0cmFkaXRpb25hbCBTcGFuaXNoLCB0aGUgdXNlciBjYW4gdGFrZQogKiB0aGUgRW5nbGlzaCBjb2xsYXRpb24gcnVsZXMgYW5kIGFkZCB0aGUgYWRkaXRpb25hbCBydWxlcyB0byB0aGUgdGFibGUuCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAuICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICogLiAgICAgVW5pY29kZVN0cmluZyBydWxlcyhERUZBVUxUUlVMRVMpOwogKiAuICAgICBydWxlcyArPSAiJiBDICZsdDsgY2gsIGNILCBDaCwgQ0giOwogKiAuICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlTcGFuaXNoID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKHJ1bGVzLCBzdGF0dXMpOwogKiA8L3ByZT4KICogPHA+SW4gb3JkZXIgdG8gc29ydCBzeW1ib2xzIGluIHRoZSBzaW1pbGlhciBvcmRlciBvZiBzb3J0aW5nIHRoZWlyCiAqIGFscGhhYmV0aWMgZXF1aXZhbGVudHMsIHlvdSBjYW4gZG8gdGhlIGZvbGxvd2luZywKICogPHByZT4KICogLiAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqIC4gICAgIFVuaWNvZGVTdHJpbmcgcnVsZXMoREVGQVVMVFJVTEVTKTsKICogLiAgICAgcnVsZXMgKz0gIiYgUXVlc3Rpb24tbWFyayA7ICc/JyAmIEFtcGVyc2FuZCA7ICcmJyAmIERvbGxhci1zaWduIDsgJyQnICI7CiAqIC4gICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteVRhYmxlID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKHJ1bGVzLCBzdGF0dXMpOwogKiA8L3ByZT4KICogPHA+QW5vdGhlciB3YXkgb2YgY3JlYXRpbmcgdGhlIHRhYmxlLWJhc2VkIGNvbGxhdGlvbiBvYmplY3QsIG15U2ltcGxlLAogKiBpczoKICogPHByZT4KICogLiAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqIC4gICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteVNpbXBsZSA9IG5ldwogKiAuICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvcigiICZsdDsgYSAmbHQ7IGIgJiBiICZsdDsgYyAmIGMgJmx0OyBkIiwgc3RhdHVzKTsKICogPC9wcmU+CiAqIE9yLAogKiA8cHJlPgogKiAuICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICogLiAgICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15U2ltcGxlID0gbmV3CiAqIC4gICAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yKCIgJmx0OyBhICZsdDsgYiAmbHQ7IGQgJiBiICZsdDsgYyIsIHN0YXR1cyk7CiAqIDwvcHJlPgogKiBCZWNhdXNlICIgJmx0OyBhICZsdDsgYiAmbHQ7IGMgJmx0OyBkIiBpcyB0aGUgc2FtZSBhcyAiYSAmbHQ7IGIgJmx0OyBkICYgYiAmbHQ7IGMiIG9yCiAqICImbHQ7IGEgJmx0OyBiICYgYiAmbHQ7IGMgJiBjICZsdDsgZCIuCiAqCiAqIDxwPlRvIGNvbWJpbmUgY29sbGF0aW9ucyBmcm9tIHR3byBsb2NhbGVzLCAod2l0aG91dCBlcnJvciBoYW5kbGluZyBmb3IgY2xhcml0eSkKICogPHByZT4KICogLiAgICAvLyBDcmVhdGUgYW4gZW5fVVMgQ29sbGF0b3Igb2JqZWN0CiAqIC4gICAgTG9jYWxlIGxvY2FsZV9lbl9VUygiZW4iLCAiVVMiLCAiIik7CiAqIC4gICAgUnVsZUJhc2VkQ29sbGF0b3IqIGVuX1VTQ29sbGF0b3IgPSAoUnVsZUJhc2VkQ29sbGF0b3IqKQogKiAuICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoIGxvY2FsZV9lbl9VUywgc3VjY2VzcyApOwogKiAuCiAqIC4gICAgLy8gQ3JlYXRlIGEgZGFfREsgQ29sbGF0b3Igb2JqZWN0CiAqIC4gICAgTG9jYWxlIGxvY2FsZV9kYV9ESygiZGEiLCAiREsiLCAiIik7CiAqIC4gICAgUnVsZUJhc2VkQ29sbGF0b3IqIGRhX0RLQ29sbGF0b3IgPSAoUnVsZUJhc2VkQ29sbGF0b3IqKQogKiAuICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoIGxvY2FsZV9kYV9ESywgc3VjY2VzcyApOwogKiAuCiAqIC4gICAgLy8gQ29tYmluZSB0aGUgdHdvCiAqIC4gICAgLy8gRmlyc3QsIGdldCB0aGUgY29sbGF0aW9uIHJ1bGVzIGZyb20gZW5fVVNDb2xsYXRvcgogKiAuICAgIFVuaWNvZGVTdHJpbmcgcnVsZXMgPSBlbl9VU0NvbGxhdG9yLT5nZXRSdWxlcygpOwogKiAuICAgIC8vIFNlY29uZCwgZ2V0IHRoZSBjb2xsYXRpb24gcnVsZXMgZnJvbSBkYV9ES0NvbGxhdG9yCiAqIC4gICAgcnVsZXMgKz0gZGFfREtDb2xsYXRvci0+Z2V0UnVsZXMoKTsKICogLiAgICBSdWxlQmFzZWRDb2xsYXRvciogbmV3Q29sbGF0b3IgPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoIHJ1bGVzLCBzdWNjZXNzICk7CiAqIC4gICAgLy8gbmV3Q29sbGF0b3IgaGFzIHRoZSBjb21iaW5lZCBydWxlcwogKiA8L3ByZT4KICogPHA+QW5vdGhlciBtb3JlIGludGVyZXN0aW5nIGV4YW1wbGUgd291bGQgYmUgdG8gbWFrZSBjaGFuZ2VzIG9uIGFuIGV4aXN0aW5nCiAqIHRhYmxlIHRvIGNyZWF0ZSBhIG5ldyBjb2xsYXRpb24gb2JqZWN0LiAgRm9yIGV4YW1wbGUsIGFkZAogKiAiJiBDICZsdDsgY2gsIGNILCBDaCwgQ0giIHRvIHRoZSBlbl9VU0NvbGxhdGlvbiBvYmplY3QgdG8gY3JlYXRlIHlvdXIgb3duCiAqIEVuZ2xpc2ggY29sbGF0aW9uIG9iamVjdCwKICogPHByZT4KICogLiAgICAvLyBDcmVhdGUgYSBuZXcgQ29sbGF0b3Igb2JqZWN0IHdpdGggYWRkaXRpb25hbCBydWxlcwogKiAuICAgIHJ1bGVzID0gZW5fVVNDb2xsYXRvci0+Z2V0UnVsZXMoKTsKICogLiAgICBydWxlcyArPSAiJiBDIDwgY2gsIGNILCBDaCwgQ0giOwogKiAuICAgIFJ1bGVCYXNlZENvbGxhdG9yKiBteUNvbGxhdG9yID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKCBydWxlcywgc3VjY2VzcyApOwogKiAuICAgIC8vIG15Q29sbGF0b3IgY29udGFpbnMgdGhlIG5ldyBydWxlcwogKiA8L3ByZT4KICoKICogPHA+VGhlIGZvbGxvd2luZyBleGFtcGxlIGRlbW9uc3RyYXRlcyBob3cgdG8gY2hhbmdlIHRoZSBvcmRlciBvZgogKiBub24tc3BhY2luZyBhY2NlbnRzLAogKiA8cHJlPgogKiAuICAgICBVQ2hhciBjb250ZW50c1tdID0gewogKiAuICAgICAgICAgJz0nLCAweDAzMDEsICc7JywgMHgwMzAwLCAnOycsIDB4MDMwMiwKICogLiAgICAgICAgICc7JywgMHgwMzA4LCAnOycsIDB4MDMyNywgJywnLCAweDAzMDMsICAgIC8vIG1haW4gYWNjZW50cwogKiAuICAgICAgICAgJzsnLCAweDAzMDQsICc7JywgMHgwMzA1LCAnOycsIDB4MDMwNiwgICAgLy8gbWFpbiBhY2NlbnRzCiAqIC4gICAgICAgICAnOycsIDB4MDMwNywgJzsnLCAweDAzMDksICc7JywgMHgwMzBBLCAgICAvLyBtYWluIGFjY2VudHMKICogLiAgICAgICAgICc7JywgMHgwMzBCLCAnOycsIDB4MDMwQywgJzsnLCAweDAzMEQsICAgIC8vIG1haW4gYWNjZW50cwogKiAuICAgICAgICAgJzsnLCAweDAzMEUsICc7JywgMHgwMzBGLCAnOycsIDB4MDMxMCwgICAgLy8gbWFpbiBhY2NlbnRzCiAqIC4gICAgICAgICAnOycsIDB4MDMxMSwgJzsnLCAweDAzMTIsICAgICAgICAgICAgICAgICAvLyBtYWluIGFjY2VudHMKICogLiAgICAgICAgICcmbHQ7JywgJ2EnLCAnLCcsICdBJywgJzsnLCAnYScsICdlJywgJywnLCAnQScsICdFJywKICogLiAgICAgICAgICc7JywgMHgwMGU2LCAnLCcsIDB4MDBjNiwgJyZsdDsnLCAnYicsICcsJywgJ0InLAogKiAuICAgICAgICAgJyZsdDsnLCAnYycsICcsJywgJ0MnLCAnJmx0OycsICdlJywgJywnLCAnRScsICcmJywgCiAqIC4gICAgICAgICAnQycsICcmbHQ7JywgJ2QnLCAnLCcsICdEJywgMCB9OwogKiAuICAgICBVbmljb2RlU3RyaW5nIG9sZFJ1bGVzKGNvbnRlbnRzKTsKICogLiAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqIC4gICAgIC8vIGNoYW5nZSB0aGUgb3JkZXIgb2YgYWNjZW50IGNoYXJhY3RlcnMKICogLiAgICAgVUNoYXIgYWRkT25bXSA9IHsgJyYnLCAnLCcsIDB4MDMwMCwgJzsnLCAweDAzMDgsICc7JywgMHgwMzAyLCAwIH07CiAqIC4gICAgIG9sZFJ1bGVzICs9IGFkZE9uOwogKiAuICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlDb2xsYXRpb24gPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3Iob2xkUnVsZXMsIHN0YXR1cyk7CiAqIDwvcHJlPgogKgogKiA8cD4gVGhlIGxhc3QgZXhhbXBsZSBzaG93cyBob3cgdG8gcHV0IG5ldyBwcmltYXJ5IG9yZGVyaW5nIGluIGJlZm9yZSB0aGUKICogZGVmYXVsdCBzZXR0aW5nLiBGb3IgZXhhbXBsZSwgaW4gSmFwYW5lc2UgY29sbGF0aW9uLCB5b3UgY2FuIGVpdGhlciBzb3J0CiAqIEVuZ2xpc2ggY2hhcmFjdGVycyBiZWZvcmUgb3IgYWZ0ZXIgSmFwYW5lc2UgY2hhcmFjdGVycywKICogPHByZT4KICogLiAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqIC4gICAgIC8vIGdldCBlbl9VUyBjb2xsYXRpb24gcnVsZXMKICogLiAgICAgUnVsZUJhc2VkQ29sbGF0b3IqIGVuX1VTQ29sbGF0aW9uID0gCiAqIC4gICAgICAgICAoUnVsZUJhc2VkQ29sbGF0b3IqKSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICogLiAgICAgLy8gQWx3YXlzIGNoZWNrIHRoZSBlcnJvciBjb2RlIGFmdGVyIGVhY2ggY2FsbC4KICogLiAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAqIC4gICAgIC8vIGFkZCBhIGZldyBKYXBhbmVzZSBjaGFyYWN0ZXIgdG8gc29ydCBiZWZvcmUgRW5nbGlzaCBjaGFyYWN0ZXJzCiAqIC4gICAgIC8vIHN1cHBvc2UgdGhlIGxhc3QgY2hhcmFjdGVyIGJlZm9yZSB0aGUgZmlyc3QgYmFzZSBsZXR0ZXIgJ2EnIGluCiAqIC4gICAgIC8vIHRoZSBFbmdsaXNoIGNvbGxhdGlvbiBydWxlIGlzIDB4MjIxMgogKiAuICAgICBVQ2hhciBqYVN0cmluZ1tdID0geyAnJicsIDB4MjIxMiwgJyZsdDsnLCAweDMwNDEsICcsJywgMHgzMDQyLCAnJmx0OycsIDB4MzA0MywgJywnLCAweDMwNDQsIDAgfTsKICogLiAgICAgVW5pY29kZVN0cmluZyBydWxlcyggZW5fVVNDb2xsYXRpb24tPmdldFJ1bGVzKCkgKTsKICogLiAgICAgcnVsZXMgKz0gamFTdHJpbmc7CiAqIC4gICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteUphcGFuZXNlQ29sbGF0aW9uID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKHJ1bGVzLCBzdGF0dXMpOwogKiA8L3ByZT4KICogPHA+PHN0cm9uZz5OT1RFPC9zdHJvbmc+OiBUeXBpY2FsbHksIGEgY29sbGF0aW9uIG9iamVjdCBpcyBjcmVhdGVkIHdpdGgKICogQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKCkuCiAqIDxwPgogKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IDxjb2RlPlJ1bGVCYXNlZENvbGxhdG9yPC9jb2RlPnMgd2l0aCBkaWZmZXJlbnQgTG9jYWxlLAogKiBDb2xsYXRpb25TdHJlbmd0aCBhbmQgRGVjb21wb3NpdGlvbiBtb2RlIHNldHRpbmdzIHdpbGwgcmV0dXJuIGRpZmZlcmVudAogKiBzb3J0IG9yZGVycyBmb3IgdGhlIHNhbWUgc2V0IG9mIHN0cmluZ3MuIExvY2FsZXMgaGF2ZSBzcGVjaWZpYyAKICogY29sbGF0aW9uIHJ1bGVzLCBhbmQgdGhlIHdheSBpbiB3aGljaCBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IGRpZmZlcmVuY2VzIAogKiBhcmUgdGFrZW4gaW50byBhY2NvdW50LCBmb3IgZXhhbXBsZSwgd2lsbCByZXN1bHQgaW4gYSBkaWZmZXJlbnQgc29ydGluZyBvcmRlcgogKiBmb3Igc2FtZSBzdHJpbmdzLgogKiA8cD4KICogQHNlZSAgICAgICAgQ29sbGF0b3IKICogQHZlcnNpb24gICAgMS4yNyA0LzgvOTcKICogQGF1dGhvciAgICAgSGVsZW5hIFNoaWgKICovCmNsYXNzIFVfSTE4Tl9BUEkgUnVsZUJhc2VkQ29sbGF0b3IgOiBwdWJsaWMgQ29sbGF0b3IgCnsKcHVibGljOiAKCiAgLy8gY29uc3RydWN0b3IvZGVzdHJ1Y3RvcgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiAgVGhpcyB0YWtlcyB0aGUgdGFibGUgcnVsZXMgYW5kIGJ1aWxkcwogICAqIGEgY29sbGF0aW9uIHRhYmxlIG91dCBvZiB0aGVtLiAgUGxlYXNlIHNlZSBSdWxlQmFzZWRDb2xsYXRvciBjbGFzcwogICAqIGRlc2NyaXB0aW9uIGZvciBtb3JlIGRldGFpbHMgb24gdGhlIGNvbGxhdGlvbiBydWxlIHN5bnRheC4KICAgKiBAc2VlIExvY2FsZQogICAqIEBwYXJhbSBydWxlcyB0aGUgY29sbGF0aW9uIHJ1bGVzIHRvIGJ1aWxkIHRoZSBjb2xsYXRpb24gdGFibGUgZnJvbS4KICAgKiBAc3RhYmxlCiAgICovCglSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKCQkJVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgUnVsZUJhc2VkQ29sbGF0b3IoICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpOwoKICBSdWxlQmFzZWRDb2xsYXRvciggIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKTsKCiAgUnVsZUJhc2VkQ29sbGF0b3IoICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUgIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKTsKCiAgLyoqIERlc3RydWN0b3IuCiAgICogQHN0YWJsZQogICAqLwoJdmlydHVhbCB+UnVsZUJhc2VkQ29sbGF0b3IoKTsKCgogIC8qKiBDb3B5IGNvbnN0cnVjdG9yLgogICAqIEBzdGFibGUKICAgKi8KCVJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yJiBvdGhlcik7CgogIC8qKgogICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IuCiAgICogQHN0YWJsZQogICAqLwoJUnVsZUJhc2VkQ29sbGF0b3ImIG9wZXJhdG9yPShjb25zdCBSdWxlQmFzZWRDb2xsYXRvciYgb3RoZXIpOwogICAgCiAgLyoqCiAgICogUmV0dXJucyB0cnVlIGlmICJvdGhlciIgaXMgdGhlIHNhbWUgYXMgInRoaXMiLgogICAqIEBzdGFibGUKICAgKi8KICB2aXJ0dWFsIFVCb29sICAgICAgICAgICAgICAgICAgb3BlcmF0b3I9PShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0OwoKICAvKioKICAgKiBSZXR1cm5zIHRydWUgaWYgIm90aGVyIiBpcyBub3QgdGhlIHNhbWUgYXMgInRoaXMiLgogICAqIEBzdGFibGUKICAgKi8KICB2aXJ0dWFsIFVCb29sICAgICAgICAgICAgICAgICAgb3BlcmF0b3IhPShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0OwoKICAvKioKICAgKiBNYWtlcyBhIGRlZXAgY29weSBvZiB0aGUgb2JqZWN0LiAgVGhlIGNhbGxlciBvd25zIHRoZSByZXR1cm5lZCBvYmplY3QuCiAgICogQHJldHVybiB0aGUgY2xvbmVkIG9iamVjdC4KICAgKiBAc3RhYmxlCiAgICovCiAgdmlydHVhbCBDb2xsYXRvciogICAgICAgICAgICAgICBjbG9uZSh2b2lkKSBjb25zdDsKCiAgLyoqCiAgICogQ3JlYXRlcyBhIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIGZvciB0aGUgc291cmNlIHN0cmluZy4gIFRoZSAKICAgKiBjYWxsZXIgb2YgdGhpcyBtZXRob2QgaXMgcmVzcG9uc2libGUgZm9yIHRoZSBtZW1vcnkgbWFuYWdlbWVudCBvZiAKICAgKiB0aGUgcmV0dXJuIHBvaW50ZXIuCiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc3RyaW5nIG92ZXIgd2hpY2ggdGhlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciB3aWxsIGl0ZXJhdGUuCiAgICogQHJldHVybiB0aGUgY29sbGF0aW9uIGVsZW1lbnQgaXRlcmF0b3Igb2YgdGhlIHNvdXJjZSBzdHJpbmcgdXNpbmcgdGhpcyBhcwogICAqIHRoZSBiYXNlZCBjb2xsYXRvci4KICAgKiBAc3RhYmxlIAogICAqLwoJdmlydHVhbCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IqIGNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UpIGNvbnN0OwoKICAvKioKICAgKiBDcmVhdGVzIGEgY29sbGF0aW9uIGVsZW1lbnQgaXRlcmF0b3IgZm9yIHRoZSBzb3VyY2UuICBUaGUgCiAgICogY2FsbGVyIG9mIHRoaXMgbWV0aG9kIGlzIHJlc3BvbnNpYmxlIGZvciB0aGUgbWVtb3J5IG1hbmFnZW1lbnQgb2YgCiAgICogdGhlIHJldHVybmVkIHBvaW50ZXIuCiAgICogQHBhcmFtIHNvdXJjZSB0aGUgQ2hhcmFjdGVySXRlcmF0b3Igd2hpY2ggcHJvZHVjZXMgdGhlIGNoYXJhY3RlcnMgb3ZlciB3aGljaCB0aGUKICAgKiBDb2xsYXRpb25FbGVtZW50SXRnZXJhdG9yIHdpbGwgaXRlcmF0ZS4KICAgKiBAcmV0dXJuIHRoZSBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciBvZiB0aGUgc291cmNlIHVzaW5nIHRoaXMgYXMKICAgKiB0aGUgYmFzZWQgY29sbGF0b3IuCiAgICogQHN0YWJsZQogICAqLwogIHZpcnR1YWwgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiAgICAgICBjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgQ2hhcmFjdGVySXRlcmF0b3ImIHNvdXJjZSkgY29uc3Q7CgogIC8qKgogICAqIENvbXBhcmVzIGEgcmFuZ2Ugb2YgY2hhcmFjdGVyIGRhdGEgc3RvcmVkIGluIHR3byBkaWZmZXJlbnQgc3RyaW5ncwogICAqIGJhc2VkIG9uIHRoZSBjb2xsYXRpb24gcnVsZXMuICBSZXR1cm5zCiAgICogaW5mb3JtYXRpb24gYWJvdXQgd2hldGhlciBhIHN0cmluZyBpcyBsZXNzIHRoYW4sIGdyZWF0ZXIgdGhhbiBvcgogICAqIGVxdWFsIHRvIGFub3RoZXIgc3RyaW5nIGluIGEgbGFuZ3VhZ2UuCiAgICogVGhpcyBjYW4gYmUgb3ZlcnJpZGVuIGluIGEgc3ViY2xhc3MuCiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdGlybmcuCiAgICogQHJldHVybiB0aGUgY29tcGFyaXNvbiByZXN1bHQuICBHUkVBVEVSIGlmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGdyZWF0ZXIKICAgKiB0aGFuIHRoZSB0YXJnZXQgc3RyaW5nLCBMRVNTIGlmIHRoZSBzb3VyY2UgaXMgbGVzcyB0aGFuIHRoZSB0YXJnZXQuICBPdGhlcndpc2UsCiAgICogcmV0dXJucyBFUVVBTC4KICAgKiBAc3RhYmxlCiAgICovCiAgdmlydHVhbCAgICAgRUNvbXBhcmlzb25SZXN1bHQgICBjb21wYXJlKCAgICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHRhcmdldCkgY29uc3Q7CiAgICAgICAgCiAgICAgICAgCiAgLyoqCiAgICogQ29tcGFyZXMgYSByYW5nZSBvZiBjaGFyYWN0ZXIgZGF0YSBzdG9yZWQgaW4gdHdvIGRpZmZlcmVudCBzdHJpbmdzCiAgICogYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBydWxlcyB1cCB0byB0aGUgc3BlY2lmaWVkIGxlbmd0aC4gIFJldHVybnMKICAgKiBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIGEgc3RyaW5nIGlzIGxlc3MgdGhhbiwgZ3JlYXRlciB0aGFuIG9yCiAgICogZXF1YWwgdG8gYW5vdGhlciBzdHJpbmcgaW4gYSBsYW5ndWFnZS4KICAgKiBUaGlzIGNhbiBiZSBvdmVycmlkZW4gaW4gYSBzdWJjbGFzcy4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEBwYXJhbSB0YXJnZXQgdGhlIHRhcmdldCBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcGFyYW0gbGVuZ3RoIGNvbXBhcmVzIHVwIHRvIHRoZSBzcGVjaWZpZWQgbGVuZ3RoCiAgICogQHJldHVybiB0aGUgY29tcGFyaXNvbiByZXN1bHQuICBHUkVBVEVSIGlmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGdyZWF0ZXIKICAgKiB0aGFuIHRoZSB0YXJnZXQgc3RyaW5nLCBMRVNTIGlmIHRoZSBzb3VyY2UgaXMgbGVzcyB0aGFuIHRoZSB0YXJnZXQuICBPdGhlcndpc2UsCiAgICogcmV0dXJucyBFUVVBTC4KICAgKiBAZHJhZnQKICAgKi8gCiAgdmlydHVhbCAgICAgRUNvbXBhcmlzb25SZXN1bHQgICBjb21wYXJlKCAgICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGxlbmd0aCkgY29uc3Q7CgogIC8qKgogICAqIFRoZSBjb21wYXJpc29uIGZ1bmN0aW9uIGNvbXBhcmVzIHRoZSBjaGFyYWN0ZXIgZGF0YSBzdG9yZWQgaW4gdHdvCiAgICogZGlmZmVyZW50IHN0cmluZyBhcnJheXMuICBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcKICAgKiBhcnJheSBpcyBsZXNzIHRoYW4sIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBhbm90aGVyIHN0cmluZyBhcnJheS4KICAgKiA8cD5FeGFtcGxlIG9mIHVzZToKICAgKiA8cHJlPgogICAqIC4gICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICogLiAgICAgICBDb2xsYXRvciAqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICAgKiAuICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpQUklNQVJZKTsKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSBDb2xsYXRvcjo6RVFVQUwgKCJhYmMiID09ICJBQkMiKQogICAqIC4gICAgICAgLy8gKG5vIHByaW1hcnkgZGlmZmVyZW5jZSBiZXR3ZWVuICJhYmMiIGFuZCAiQUJDIikKICAgKiAuICAgICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBteUNvbGxhdGlvbi0+Y29tcGFyZShMImFiYyIsIDMsIEwiQUJDIiwgMyk7CiAgICogLiAgICAgICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlRFUlRJQVJZKTsKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSBDb2xsYXRvcjo6TEVTUyAoYWJjIiAmbHQ7Jmx0OyZsdDsgIkFCQyIpCiAgICogLiAgICAgICAvLyAod2l0aCB0ZXJ0aWFyeSBkaWZmZXJlbmNlIGJldHdlZW4gImFiYyIgYW5kICJBQkMiKQogICAqIC4gICAgICAgQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IHJlc3VsdCA9IG15Q29sbGF0aW9uLT5jb21wYXJlKEwiYWJjIiwgMywgTCJBQkMiLCAzKTsKICAgKiA8L3ByZT4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIGFycmF5IHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHBhcmFtIHNvdXJjZUxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBzb3VyY2Ugc3RyaW5nIGFycmF5LiAgSWYgdGhpcyB2YWx1ZQogICAqICAgICAgICBpcyBlcXVhbCB0byAtMSwgdGhlIHN0cmluZyBhcnJheSBpcyBudWxsLXRlcm1pbmF0ZWQuCiAgICogQHBhcmFtIHRhcmdldCB0aGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcGFyYW0gdGFyZ2V0TGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIHRhcmdldCBzdHJpbmcgYXJyYXkuICBJZiB0aGlzIHZhbHVlCiAgICogICAgICAgIGlzIGVxdWFsIHRvIC0xLCB0aGUgc3RyaW5nIGFycmF5IGlzIG51bGwtdGVybWluYXRlZC4KICAgKiBAcmV0dXJuIFJldHVybnMgYSBieXRlIHZhbHVlLiBHUkVBVEVSIGlmIHNvdXJjZSBpcyBncmVhdGVyCiAgICogdGhhbiB0YXJnZXQ7IEVRVUFMIGlmIHNvdXJjZSBpcyBlcXVhbCB0byB0YXJnZXQ7IExFU1MgaWYgc291cmNlIGlzIGxlc3MKICAgKiB0aGFuIHRhcmdldAogICAqIEBzdGFibGUKICAgKiovCiAgdmlydHVhbCBFQ29tcGFyaXNvblJlc3VsdCAgIGNvbXBhcmUoICAgIGNvbnN0ICAgVUNoYXIqIHNvdXJjZSwgCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVUNoYXIqICB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHRhcmdldExlbmd0aCkgY29uc3QgOwoKICAvKiogVHJhbnNmb3JtcyBhIHNwZWNpZmllZCByZWdpb24gb2YgdGhlIHN0cmluZyBpbnRvIGEgc2VyaWVzIG9mIGNoYXJhY3RlcnMKICAgICAqIHRoYXQgY2FuIGJlIGNvbXBhcmVkIHdpdGggQ29sbGF0aW9uS2V5LmNvbXBhcmUuIFVzZSBhIENvbGxhdGlvbktleSB3aGVuCiAgICAgKiB5b3UgbmVlZCB0byBkbyByZXBlYXRlZCBjb21wYXJpc2lvbnMgb24gdGhlIHNhbWUgc3RyaW5nLiBGb3IgYSBzaW5nbGUgY29tcGFyaXNvbgogICAgICogdGhlIGNvbXBhcmUgbWV0aG9kIHdpbGwgYmUgZmFzdGVyLgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZy4KICAgICAqIEBwYXJhbSBrZXkgdGhlIHRyYW5zZm9ybWVkIGtleSBvZiB0aGUgc291cmNlIHN0cmluZy4KICAgICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAgICogQHJldHVybiB0aGUgdHJhbnNmb3JtZWQga2V5LgogICAgICogQHNlZSBDb2xsYXRpb25LZXkKICAgICAqIEBkcmFmdAogICAgICovCiAgdmlydHVhbCAgICAgQ29sbGF0aW9uS2V5JiAgICAgICBnZXRDb2xsYXRpb25LZXkoICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiAgIGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgIHN0YXR1cykgY29uc3Q7CgogIC8qKiBUcmFuc2Zvcm1zIGEgc3BlY2lmaWVkIHJlZ2lvbiBvZiB0aGUgc3RyaW5nIGludG8gYSBzZXJpZXMgb2YgY2hhcmFjdGVycwogICAgICogdGhhdCBjYW4gYmUgY29tcGFyZWQgd2l0aCBDb2xsYXRpb25LZXkuY29tcGFyZS4gVXNlIGEgQ29sbGF0aW9uS2V5IHdoZW4KICAgICAqIHlvdSBuZWVkIHRvIGRvIHJlcGVhdGVkIGNvbXBhcmlzaW9ucyBvbiB0aGUgc2FtZSBzdHJpbmcuIEZvciBhIHNpbmdsZSBjb21wYXJpc29uCiAgICAgKiB0aGUgY29tcGFyZSBtZXRob2Qgd2lsbCBiZSBmYXN0ZXIuCiAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICogQHBhcmFtIGtleSB0aGUgdHJhbnNmb3JtZWQga2V5IG9mIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAgKiBAcmV0dXJuIHRoZSB0cmFuc2Zvcm1lZCBrZXkuCiAgICAgKiBAc2VlIENvbGxhdGlvbktleQogICAgICogQGRyYWZ0CiAgICAgKi8KICB2aXJ0dWFsIENvbGxhdGlvbktleSYgICAgICAgZ2V0Q29sbGF0aW9uS2V5KGNvbnN0IFVDaGFyICpzb3VyY2UsCgkJCQkJICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCgkJCQkJICAgICAgQ29sbGF0aW9uS2V5JiAgICAgICBrZXksCgkJCQkJICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpIGNvbnN0OwoKICAvKioKICAgKiBHZW5lcmF0ZXMgdGhlIGhhc2ggY29kZSBmb3IgdGhlIHJ1bGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdC4KICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUuCiAgICogQHN0YWJsZQogICAqLwogIHZpcnR1YWwgICAgIGludDMyX3QgICAgICAgICAgICAgaGFzaENvZGUodm9pZCkgY29uc3Q7CgogIC8qKgogICAqIEdldHMgdGhlIHRhYmxlLWJhc2VkIHJ1bGVzIGZvciB0aGUgY29sbGF0aW9uIG9iamVjdC4KICAgKiBAcmV0dXJuIHJldHVybnMgdGhlIGNvbGxhdGlvbiBydWxlcyB0aGF0IHRoZSB0YWJsZSBjb2xsYXRpb24gb2JqZWN0CiAgICogd2FzIGNyZWF0ZWQgZnJvbS4KICAgKiBAc3RhYmxlCiAgICovCiAgY29uc3QgICAgICAgVW5pY29kZVN0cmluZyYgICAgICBnZXRSdWxlcyh2b2lkKSBjb25zdDsKCiAgLyoqCiAgICogIFJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZXMgdGhhdCBlbmQKICAgKiAgd2l0aCB0aGUgc3BlY2lmaWVkIGNvbXBhcmlzb24gb3JkZXIuCiAgICogCiAgICogIEBwYXJhbSBvcmRlciBhIGNvbGxhdGlvbiBvcmRlciByZXR1cm5lZCBieSBwcmV2aW91cyBvciBuZXh0LgogICAqICBAcmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbnkgZXhwYW5zaW9uIHNldWVuY2VzIGVuZGluZwogICAqICAgICAgICAgIHdpdGggdGhlIHNwZWNpZmllZCBvcmRlci4KICAgKiAKICAgKiAgQHNlZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IjZ2V0TWF4RXhwYW5zaW9uCiAgICogQGRyYWZ0ID8gcGVuZGluZyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OmdldE1heEV4cGFuc2lvbgogICAqLwoJaW50MzJfdCBnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3Q7CgogIC8qKgogICAqIFJldHVybnMgYSB1bmlxdWUgY2xhc3MgSUQgUE9MWU1PUlBISUNBTExZLiAgUHVyZSB2aXJ0dWFsIG92ZXJyaWRlLgogICAqIFRoaXMgbWV0aG9kIGlzIHRvIGltcGxlbWVudCBhIHNpbXBsZSB2ZXJzaW9uIG9mIFJUVEksIHNpbmNlIG5vdCBhbGwKICAgKiBDKysgY29tcGlsZXJzIHN1cHBvcnQgZ2VudWluZSBSVFRJLiAgUG9seW1vcnBoaWMgb3BlcmF0b3I9PSgpIGFuZAogICAqIGNsb25lKCkgbWV0aG9kcyBjYWxsIHRoaXMgbWV0aG9kLgogICAqCiAgICogQHJldHVybiAgICAgICAgICBUaGUgY2xhc3MgSUQgZm9yIHRoaXMgb2JqZWN0LiBBbGwgb2JqZWN0cyBvZiBhCiAgICogICAgICAgICAgICAgICAgICBnaXZlbiBjbGFzcyBoYXZlIHRoZSBzYW1lIGNsYXNzIElELiAgT2JqZWN0cyBvZgogICAqICAgICAgICAgICAgICAgICAgb3RoZXIgY2xhc3NlcyBoYXZlIGRpZmZlcmVudCBjbGFzcyBJRHMuCiAgICovCiAgdmlydHVhbCBVQ2xhc3NJRCBnZXREeW5hbWljQ2xhc3NJRCh2b2lkKSBjb25zdAogICAgeyByZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3I6OmdldFN0YXRpY0NsYXNzSUQoKTsgfQoKCiAgLyoqCiAgICogUmV0dXJucyB0aGUgY2xhc3MgSUQgZm9yIHRoaXMgY2xhc3MuICBUaGlzIGlzIHVzZWZ1bCBvbmx5IGZvcgogICAqIGNvbXBhcmluZyB0byBhIHJldHVybiB2YWx1ZSBmcm9tIGdldER5bmFtaWNDbGFzc0lEKCkuICBGb3IgZXhhbXBsZToKICAgKgogICAqICAgICAgQmFzZSogcG9seW1vcnBoaWNfcG9pbnRlciA9IGNyZWF0ZVBvbHltb3JwaGljT2JqZWN0KCk7CiAgICogICAgICBpZiAocG9seW1vcnBoaWNfcG9pbnRlci0+Z2V0RHluYW1pY0NsYXNzSUQoKSA9PQogICAqICAgICAgICAgIERlcml2ZWQ6OmdldFN0YXRpY0NsYXNzSUQoKSkgLi4uCiAgICoKICAgKiBAcmV0dXJuICAgICAgICAgIFRoZSBjbGFzcyBJRCBmb3IgYWxsIG9iamVjdHMgb2YgdGhpcyBjbGFzcy4KICAgKi8KICBzdGF0aWMgVUNsYXNzSUQgZ2V0U3RhdGljQ2xhc3NJRCh2b2lkKSB7IHJldHVybiAoVUNsYXNzSUQpJmZnQ2xhc3NJRDsgfQoKCiAgLyoqCiAgICogUmV0dXJucyB0aGUgYmluYXJ5IGZvcm1hdCBvZiB0aGUgY2xhc3MncyBydWxlcy4gIFRoZSBmb3JtYXQgaXMKICAgKiB0aGF0IG9mIC5jb2wgZmlsZXMuICAKICAgKgogICAqIEBwYXJhbSBsZW5ndGggUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhLCBpbiBieXRlcwogICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAqIEByZXR1cm4gbWVtb3J5LCBvd25lZCBieSB0aGUgY2FsbGVyLCBvZiBzaXplICdsZW5ndGgnIGJ5dGVzLgogICAqIEBkcmFmdCBJTlRFUk5BTCBVU0UgT05MWQogICAqLwogIHVpbnQ4X3QgKmNsb25lUnVsZURhdGEoaW50MzJfdCAmbGVuZ3RoLCBVRXJyb3JDb2RlICZzdGF0dXMpOwoKIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQUklWQVRFCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcHJpdmF0ZToKICBzdGF0aWMgICAgICBjaGFyICAgICAgICAgICAgICAgIGZnQ2xhc3NJRDsKCiAgICAgICAgLy8gU3RyZWFtZXIgdXNlZCB0byByZWFkL3dyaXRlIGJpbmFyeSBjb2xsYXRpb24gZGF0YSBmaWxlcy4KICBmcmllbmQgICAgICAgIGNsYXNzICAgICAgICAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI7CgogIC8vIFVzZWQgdG8gaXRlcmF0ZSBvdmVyIGNvbGxhdGlvbiBlbGVtZW50cyBpbiBhIGNoYXJhY3RlciBzb3VyY2UuCiAgZnJpZW5kICAgICAgY2xhc3MgICAgICAgICAgICAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I7CiAgICAgICAgCiAgLy8gQ29sbGF0b3IgT05MWSBuZWVkcyBhY2Nlc3MgdG8gUnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgTG9jYWxlJiwgVUVycm9yQ29kZSYpCiAgZnJpZW5kIGNsYXNzIENvbGxhdG9yOwogICAgICAgIAogIC8vIFRhYmxlQ29sbGF0aW9uRGF0YSBPTkxZIG5lZWRzIGFjY2VzcyB0byBVTk1BUFBFRAogIGZyaWVuZCBjbGFzcyBUYWJsZUNvbGxhdGlvbkRhdGE7CgoKICAvKiogRGVmYXVsdCBjb25zdHJ1Y3RvcgogICAqLwogIFJ1bGVCYXNlZENvbGxhdG9yKCk7CgogIC8qKgogICAqIENyZWF0ZSBhIG5ldyBlbnRyeSBpbiB0aGUgZXhwYW5zaW9uIHRhYmxlIHRoYXQgY29udGFpbnMgdGhlIG9yZGVyaW5ncwogICAqIGZvciB0aGUgZ2l2ZW4gY2hhcmFjZXJzLiAgSWYgYW5PcmRlciBpcyB2YWxpZCwgaXQgaXMgYWRkZWQgdG8gdGhlCiAgICogYmVnaW5uaW5nIG9mIHRoZSBleHBhbmRlZCBsaXN0IG9mIG9yZGVycy4KICAgKi8KICBpbnQzMl90ICAgICAgICAgICAgICAgIGFkZEV4cGFuc2lvbihpbnQzMl90IGFuT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyAmZXhwYW5kQ2hhcnMpOwogIC8qKgogICAqIENyZWF0ZSBhIHRhYmxlLWJhc2VkIGNvbGxhdGlvbiBvYmplY3Qgd2l0aCB0aGUgZ2l2ZW4gcnVsZXMuCiAgICogQHNlZSBSdWxlQmFzZWRDb2xsYXRvciNSdWxlQmFzZWRDb2xsYXRvcgogICAqIEBleGNlcHRpb24gRm9ybWF0RXhjZXB0aW9uIElmIHRoZSBydWxlcyBmb3JtYXQgaXMgaW5jb3JyZWN0LgogICAqLwogIHZvaWQgICAgICAgICAgICAgICAgYnVpbGQoICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdWNjZXNzKTsKCiAgLyoqIEFkZCBleHBhbmRpbmcgZW50cmllcyBmb3IgcHJlLWNvbXBvc2VkIHVuaWNvZGUgY2hhcmFjdGVycyBzbyB0aGF0IHRoaXMKICAgKiBjb2xsYXRvciBjYW4gYmUgdXNlZCByZWFzb25hYmx5IHdlbGwgd2l0aCBkZWNvbXBvc2l0aW9uIHR1cm5lZCBvZmYuCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICBhZGRDb21wb3NlZENoYXJzKHZvaWQpOwoKICAvKioKICAgKiBMb29rIHVwIGZvciB1bm1hcHBlZCB2YWx1ZXMgaW4gdGhlIGV4cGFuZGVkIGNoYXJhY3RlciB0YWJsZS4KICAgKi8KICB2b2lkICAgICAgICAgICAgICAgIGNvbW1pdCh2b2lkKTsKICAvKioKICAgKiBJbmNyZW1lbnQgb2YgdGhlIGxhc3Qgb3JkZXIgYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBzdHJlbmd0aC4KICAgKiBAcGFyYW0gcyB0aGUgY29sbGF0aW9uIHN0cmVuZ3RoLgogICAqIEBwYXJhbSBsYXN0T3JkZXIgdGhlIGxhc3QgY29sbGF0aW9uIG9yZGVyLgogICAqIEByZXR1cm4gdGhlIG5ldyBjb2xsYXRpb24gb3JkZXIuCiAgICovCiAgaW50MzJfdCAgICAgICAgICAgICBpbmNyZW1lbnQoICBDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoICAgIHMsIAogICAgICAgICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RPcmRlcik7CiAgLyoqCiAgICogQWRkcyBhIGNoYXJhY3RlciBhbmQgaXRzIGRlc2lnbmF0ZWQgb3JkZXIgaW50byB0aGUgY29sbGF0aW9uIHRhYmxlLgogICAqIEBwYXJhbSBjaCB0aGUgVW5pY29kZSBjaGFyYWN0ZXIsCiAgICogQHBhcmFtIGFuT3JkZXIgdGhlIG9yZGVyLgogICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAqLwogIHZvaWQgICAgICAgICAgICAgICAgYWRkT3JkZXIoICAgVUNoYXIgICAgICAgIGNoLCAKICAgICAgICAgICAgICAgICAgaW50MzJfdCAgICAgICAgYW5PcmRlciwgCiAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICBzdGF0dXMpOwogIC8qKgogICAqIEFkZHMgdGhlIGV4cGFuZGluZyBzdHJpbmcgaW50byB0aGUgY29sbGF0aW9uIHRhYmxlLCBmb3IgZXhhbXBsZSwgYS11bWxhdXQgaW4gR2VybWFuLgogICAqIEBwYXJhbSBncm91cENoYXJzIHRoZSBjb250cmFjdGluZyBjaGFyYWN0ZXJzLgogICAqIEBwYXJhbSBleHBDaGFycyB0aGUgZXhwYW5kaW5nIGNoYXJhY3RlcnMuCiAgICogQHBhcmFtIGFuT3JkZXIgdGhlIG9yZGVyLgogICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAqLwogIHZvaWQgICAgICAgICAgICAgICAgYWRkRXhwYW5kT3JkZXIoY29uc3QgICAgVW5pY29kZVN0cmluZyYgICAgICAgICAgZ3JvdXBDaGFycywgCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgIFVuaWNvZGVTdHJpbmcmICAgICAgICAgIGV4cENoYXJzLCAKICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbk9yZGVyLAogICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKICAvKioKICAgKiBBZGRzIHRoZSBjb250cmFjdGluZyBzdHJpbmcgaW50byB0aGUgY29sbGF0aW9uIHRhYmxlLCBmb3IgZXhhbXBsZSwgY2ggaW4gU3BhbmlzaC4KICAgKiBAcGFyYW0gZ3JvdXBDaGFycyB0aGUgY29udHJhY3RpbmcgY2hhcmFjdGVycy4KICAgKiBAcGFyYW0gYW5PcmRlciB0aGUgb3JkZXIuCiAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICBhZGRDb250cmFjdE9yZGVyKGNvbnN0ICBVbmljb2RlU3RyaW5nJiAgICAgICAgICBncm91cENoYXJzLCAKICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgICAgICAgICAgICAgYW5PcmRlciwKICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CiAgLyoqCiAgICogQWRkcyB0aGUgY29udHJhY3Rpbmcgc3RyaW5nIGludG8gdGhlIGNvbGxhdGlvbiB0YWJsZSwgZm9yIGV4YW1wbGUsIGNoIGluIFNwYW5pc2guCiAgICogQHBhcmFtIGdyb3VwQ2hhcnMgdGhlIGNvbnRyYWN0aW5nIGNoYXJhY3RlcnMuCiAgICogQHBhcmFtIGFuT3JkZXIgdGhlIG9yZGVyLgogICAqIEBwYXJhbSBmd2QgVFJVRSBpZiB0aGlzIGlzIGZvciB0aGUgZm9yd2FyZCBkaXJlY3Rpb24KICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAgKi8KICB2b2lkICAgICAgICAgICAgICAgIGFkZENvbnRyYWN0T3JkZXIoY29uc3QgIFVuaWNvZGVTdHJpbmcmICAgICAgICAgIGdyb3VwQ2hhcnMsIAogICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgICAgICAgICBhbk9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgIFVCb29sICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ3ZCwKICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CiAgLyoqCiAgICogSWYgdGhlIGdpdmVuIHN0cmluZyBoYXMgYmVlbiBzcGVjaWZpZWQgYXMgYSBjb250cmFjdGluZyBzdHJpbmcKICAgKiBpbiB0aGlzIGNvbGxhdGlvbiB0YWJsZSwgcmV0dXJuIGl0cyBvcmRlcmluZywgb3RoZXJ3aXNlIHJldHVybiBVTk1BUFBFRC4KICAgKiBAcGFyYW0gZ3JvdXBDaGFycyB0aGUgc3RyaW5nCiAgICogQHJldHVybiB0aGUgb3JkZXIgb2YgdGhlIGNvbnRyYWN0ZWQgY2hhcmFjdGVyLCBvciBVTk1BUFBFRCBpZgogICAqIHRoZXJlIGlzbid0IG9uZS4KICAgKi8KICBpbnQzMl90ICAgICAgICAgICAgICAgIGdldENvbnRyYWN0T3JkZXIoY29uc3QgICAgVW5pY29kZVN0cmluZyAgICAgICAgICAgICZncm91cENoYXJzKSBjb25zdDsKICAvKioKICAgKiAgR2V0cyB0aGUgZW50cnkgb2YgbGlzdCBvZiB0aGUgY29udHJhY3Rpbmcgc3RyaW5nIGluIHRoZSBjb2xsYXRpb24KICAgKiAgdGFibGUuCiAgICogIEBwYXJhbSBjaCB0aGUgc3RhcnRpbmcgY2hhcmFjdGVyIG9mIHRoZSBjb250cmFjdGluZyBzdHJpbmcKICAgKiAgQHJldHVybiB0aGUgZW50cnkgb2YgY29udHJhY3RpbmcgZWxlbWVudCB3aGljaCBzdGFydHMgd2l0aCB0aGUgc3BlY2lmaWVkCiAgICogIGNoYXJhY3RlciBpbiB0aGUgbGlzdCBvZiBjb250cmFjdGluZyBlbGVtZW50cy4KICAgKi8KICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCogCiAgZ2V0Q29udHJhY3RWYWx1ZXMoVUNoYXIgICAgIGNoKSBjb25zdDsKICAvKioKICAgKiAgR2VzIHRoZSBlbnRyeSBvZiBsaXN0IG9mIHRoZSBjb250cmFjdGluZyBzdHJpbmcgaW4gdGhlIGNvbGxhdGlvbgogICAqICB0YWJsZS4KICAgKiAgQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgY29udHJhY3QgY2hhcmFjdGVyIGxpc3QKICAgKiAgQHJldHVybiB0aGUgZW50cnkgb2YgdGhlIGNvbnRyYWN0aW5nIGVsZW1lbnQgb2YgdGhlIHNwZWNpZmllZCBpbmRleCBpbiB0aGUKICAgKiAgbGlzdC4KICAgKi8KICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCogCiAgZ2V0Q29udHJhY3RWYWx1ZXMoaW50MzJfdCAgICAgaW5kZXgpIGNvbnN0OwogIC8qKgogICAqICBHZXRzIHRoZSBlbnRyeSBvZiB2YWx1ZSBsaXN0IG9mIHRoZSBleHBhbmRpbmcgc3RyaW5nIGluIHRoZSBjb2xsYXRpb24KICAgKiAgdGFibGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KICAgKiAgQHBhcmFtIG9yZGVyIHRoZSBvcmRlciBvZiB0aGUgZXhwYW5kaW5nIHN0cmluZyB2YWx1ZSBsaXN0CiAgICogIEByZXR1cm4gdGhlIGVudHJ5IG9mIHRoZSBleHBhbmRpbmctY2hhciBlbGVtZW50IG9mIHRoZSBzcGVjaWZpZWQgaW5kZXggaW4gCiAgICogIHRoZSBsaXN0LgogICAqLwogIFZlY3Rvck9mSW50KiAgICAgICAgZ2V0RXhwYW5kVmFsdWVMaXN0KGludDMyX3QgICAgIG9yZGVyKSBjb25zdDsKCiAgLyoqCiAgICogIEdldHMgdGhlIGNvbWFyaXNvbiBvcmRlciBvZiBhIGNoYXJhY3RlciBmcm9tIHRoZSBjb2xsYXRpb24gdGFibGUuCiAgICogIEBwYXJhbSBjaCB0aGUgVW5pY29kZSBjaGFyYWN0ZXIKICAgKiAgQHJldHVybiB0aGUgY29tcGFyaXNvbiBvcmRlciBvZiBhIGNoYXJhY3Rlci4KICAgKi8KICBpbnQzMl90ICAgICAgICAgICAgICAgIGdldENoYXJPcmRlcihVQ2hhciBjaCkgY29uc3Q7CgogIC8qKgogICAqICBHZXRzIHRoZSBjb21hcmlzb24gb3JkZXIgb2YgYSBjaGFyYWN0ZXIgZnJvbSB0aGUgY29sbGF0aW9uIHRhYmxlLgogICAqICBAcGFyYW0gbGlzdCB0aGUgY29udHJhY3RpbmcgZWxlbWVudCB0YWJsZS4KICAgKiAgQHBhcmFtIG5hbWUgdGhlIGNvbnRyYWN0aW5nIGNoYXIgc3RyaW5nLgogICAqICBAcmV0dXJuIHRoZSBjb21wYXJpc29uIG9yZGVyIG9mIHRoZSBjb250cmFjdGluZyBjaGFyYWN0ZXIuCiAgICovCiAgc3RhdGljICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIGdldEVudHJ5KCAgIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KiAgICAgbGlzdCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgICAgICAgICAgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgVUJvb2wgICAgICAgICAgICAgICAgICAgIGZ3ZCk7CgogIC8qKgogICAqIEZsYXR0ZW5zIHRoZSBnaXZlbiBvYmplY3QgcGVyc2lzdGVudGx5IHRvIGEgZmlsZS4gIFRoZSBmaWxlIG5hbWUKICAgKiBhcmd1bWVudCBzaG91bGQgYmUgYSBwYXRoIG5hbWUgdGhhdCBjYW4gYmUgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZQogICAqIHVuZGVybHlpbmcgT1MuICBPbmNlIGEgUnVsZUJhc2VkQ29sbGF0b3IgaGFzIGJlZW4gd3JpdHRlbiB0byBhIGZpbGUsCiAgICogaXQgY2FuIGJlIHJlc3VycmVjdGVkIGJ5IGNhbGxpbmcgdGhlIFJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IGNoYXIqKQogICAqIGNvbnN0cnVjdG9yLCB3aGljaCBvcGVyYXRlcyB2ZXJ5IHF1aWNrbHkuCiAgICogQHBhcmFtIGZpbGVOYW1lIHRoZSBvdXRwdXQgZmlsZSBuYW1lLgogICAqIEByZXR1cm4gVFJVRSBpZiB3cml0aW5nIHRvIHRoZSBmaWxlIHdhcyBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuCiAgICovCiAgVUJvb2wgICAgICAgICAgICAgIHdyaXRlVG9GaWxlKGNvbnN0IGNoYXIqIGZpbGVOYW1lKSBjb25zdDsgLy8gVHJ1ZSBvbiBzdWNjZXNzCiAgLyogIFVCb29sICAgICAgICAgICAgICBwcmVwYXJlRm9yQnVuZGxlKCkgY29uc3Q7Ki8KCiAgLyoqCiAgICogQWRkIHRoaXMgdGFibGUgY29sbGF0aW9uIHRvIHRoZSBjYWNoZS4gIFRoaXMgaW52b2x2ZXMgYWRkaW5nIHRoZQogICAqIGVuY2xvc2VkIFRhYmxlQ29sbGF0aW9uRGF0YSB0byB0aGUgY2FjaGUsIGFuZCB0aGVuIG1hcmtpbmcgb3VyCiAgICogcG9pbnRlciBhcyAibm90IG93bmVkIiBieSBzZXR0aW5nIGRhdGFJc093bmVkIHRvIGZhbHNlLgogICAqIEBwYXJhbSBrZXkgdGhlIHVuaXF1ZSB0aGF0IHJlcHJlc2VudHMgdGhpcyBjb2xsYXRpb24gZGF0YSBvYmplY3QuCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICBhZGRUb0NhY2hlKCAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGtleSk7CgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiAgVGhpcyBjb25zdHJ1Y3RvciB0YWtlcyBhIGxvY2FsZS4gIFRoZSBvbmx5CiAgICogY2FsbGVyIG9mIHRoaXMgY2xhc3Mgc2hvdWxkIGJlIENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZSgpLiAgSWYgY3JlYXRlSW5zdGFuY2UoKQogICAqIGhhcHBlbnMgdG8ga25vdyB0aGF0IHRoZSByZXF1ZXN0ZWQgbG9jYWxlJ3MgY29sbGF0aW9uIGlzIGltcGxlbWVudGVkIGFzCiAgICogYSBSdWxlQmFzZWRDb2xsYXRvciwgaXQgY2FuIHRoZW4gY2FsbCB0aGlzIGNvbnN0cnVjdG9yLiAgT1RIRVJXSVNFIElUIFNIT1VMRE4nVCwKICAgKiBzaW5jZSB0aGlzIGNvbnN0cnVjdG9yIEFMV0FZUyBSRVRVUk5TIEEgVkFMSUQgQ09MTEFUSU9OIFRBQkxFLiAgSXQgZG9lcyB0aGlzCiAgICogYnkgZmFsbGluZyBiYWNrIHRvIGRlZmF1bHRzLgogICAqLwogIFJ1bGVCYXNlZENvbGxhdG9yKCAgICAgIGNvbnN0IExvY2FsZSYgZGVzaXJlZExvY2FsZSwKICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwogIC8qKgogICAqIEludGVybmFsIGNvbnN0cnVjdEZyb21YeXgoKSBtZXRob2RzLiAgVGhlc2UgbWV0aG9kcyBkbyBvYmplY3QgY29uc3RydWN0aW9uCiAgICogZnJvbSB2YXJpb3VzIHNvdXJjZXMuICBUaGV5IGFjdCBsaWtlIGFzc2lnbm1lbnQgb3BlcmF0b3JzOyB3aGF0ZXZlciB1c2VkCiAgICogdG8gYmUgaW4gdGhpcyBvYmplY3QgaXMgZGlzY2FyZGVkLiAgPFA+RlJPTSBSVUxFUy4gIFRoaXMgY29uc3RydWN0b3IgdHVybnMKICAgKiBhcm91bmQgYW5kIGNhbGxzIGJ1aWxkKCkuICA8UD5GUk9NIENBQ0hFLiAgVGhpcyBjb25zdHJ1Y3RvciB0cmllcyB0byBnZXQgdGhlCiAgICogcmVxdWVzdGVkIGNhY2hlZCBUYWJsZUNvbGxhdGlvbkRhdGEgb2JqZWN0LCBhbmQgd3JhcCB1cyBhcm91bmQgaXQuICA8UD5GUk9NIEZJTEUuCiAgICogVGhlcmUgYXJlIHR3byBjb25zdHJ1Y3RvcnMgbmFtZWQgY29uc3RydWN0RnJvbUZpbGUoKS4gIE9uZSB0YWtlcyBhIGNvbnN0IGNoYXIqOgogICAqIHRoaXMgaXMgYSBwYXRoIG5hbWUgdG8gYmUgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZSBob3N0IE9TLCB3aGVyZSBhIGZsYXR0ZW5lZAogICAqIHRhYmxlIGNvbGxhdGlvbiAocHJvZHVjZWQgYnkgd3JpdGVUb0ZpbGUoKSkgcmVzaWRlcy4gIFRoZSBvdGhlciBtZXRob2QgdGFrZXMKICAgKiBhIExvY2FsZSwgYW5kIGEgVW5pY29kZVN0cmluZyBsb2NhbGUgZmlsZSBuYW1lLiAgVGhlIGRpc3RpbmN0aW9uIGlzIHRoaXM6CiAgICogdGhlIExvY2FsZSBpcyB0aGUgbG9jYWxlIHdlIGFyZSBzZWVraW5nLiAgVGhlIGZpbGUgbmFtZSBpcyB0aGUgbmFtZSBvZiB0aGUKICAgKiBkYXRhIGZpbGUgKGVpdGhlciBiaW5hcnksIGFzIHByb2R1Y2VkIGJ5IHdyaXRlVG9GaWxlKCksIG9yIEFTQ0lJLCBhcyByZWFkCiAgICogYnkgUmVzb3VyY2VCdW5kbGUpLiAgV2l0aGluIHRoZSBmaWxlLCBpZiBpdCBpcyBmb3VuZCwgdGhlIG1ldGhvZCB3aWxsIGxvb2sKICAgKiBmb3IgdGhlIGdpdmVuIExvY2FsZS4KICAgKi8KICB2b2lkICAgICAgICAgICAgICAgIGNvbnN0cnVjdEZyb21SdWxlcyggY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwogIHZvaWQgICAgICAgICAgICAgICAgY29uc3RydWN0RnJvbUZpbGUoICBjb25zdCBMb2NhbGUmICAgICAgICAgICBsb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiAgICBsb2NhbGVGaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgIFVCb29sICAgICAgICAgICAgICAgICAgdHJ5QmluYXJ5RmlsZSwKICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgICAgICAgICBzdGF0dXMpOwogIHZvaWQgICAgICAgICAgICAgICAgY29uc3RydWN0RnJvbUZpbGUoICBjb25zdCBjaGFyKiBmaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgdm9pZCAgICAgICAgICAgICAgICBjb25zdHJ1Y3RGcm9tQ2FjaGUoIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGtleSwKICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgY29uc3QgY2hhciogICAgICAgICBjb25zdHJ1Y3RGcm9tQnVuZGxlKGNvbnN0IExvY2FsZSYgZmlsZU5hbWUsCgkJCQkJICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIEludGVybmFsIFN0YXRpYyBVdGlsaXR5IE1ldGhvZHMKICAvKioKICAgKiBDcmVhdGVzIHRoZSBwYXRoIG5hbWUgd2l0aCBnaXZlbiBpbmZvcm1hdGlvbi4KICAgKiBAcGFyYW0gcHJlZml4IHRoZSBwcmVmaXggb2YgdGhlIGZpbGUgbmFtZS4KICAgKiBAcGFyYW0gbmFtZSB0aGUgYWN0dWFsIGZpbGUgbmFtZS4KICAgKiBAcGFyYW0gc3VmZml4IHRoZSBzdWZmaXggb2YgdGhlIGZpbGUgbmFtZS4KICAgKiBAcmV0dXJuIHRoZSBnZW5lcmF0ZWQgZmlsZSBuYW1lLgogICAqLwogIHN0YXRpYyAgY2hhciogICAgICAgICAgICAgICBjcmVhdGVQYXRoTmFtZSggY29uc3QgVW5pY29kZVN0cmluZyYgICAgcHJlZml4LAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgICAgc3VmZml4KTsKCiAgaW50MzJfdCBnZXRTdHJlbmd0aE9yZGVyKE5vcm1hbGl6ZXJJdGVyYXRvciogY3Vyc29yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSBzdGF0dXMpIGNvbnN0OwogIFZlY3Rvck9mSW50KiBtYWtlUmVvcmRlcmVkQnVmZmVyKE5vcm1hbGl6ZXJJdGVyYXRvciogY3Vyc29yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDaGFyIGNvbEZpcnN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbGFzdFZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3Rvck9mSW50KiBsYXN0RXhwYW5zaW9uKSBjb25zdDsKICBpbnQzMl90IHN0cmVuZ3RoT3JkZXIoaW50MzJfdCB2YWx1ZSkgY29uc3QgOwogIGludDMyX3QgbmV4dENvbnRyYWN0Q2hhcihOb3JtYWxpemVySXRlcmF0b3IgKmN1cnNvciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDaGFyIGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwogIC8qKgogICAgICogQ2hvcHMgb2ZmIHRoZSBsYXN0IHBvcnRpb24gb2YgdGhlIGxvY2FsZSBuYW1lLiAgRm9yIGV4YW1wbGUsIGZyb20gImVuX1VTX0NBIgogICAgICogdG8gImVuX1VTIiBhbmQgImVuX1VTIiB0byAiZW4iLgogICAgICogQHBhcmFtIGxvY2FsZU5hbWUgdGhlIGxvY2FsZSBuYW1lLgogICAgICovCiAgc3RhdGljICB2b2lkICAgICAgICAgICAgICAgIGNob3BMb2NhbGUoVW5pY29kZVN0cmluZyYgICBsb2NhbGVOYW1lKTsKCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIENvbnN0YW50cwoKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBVTk1BUFBFRDsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBDSEFSSU5ERVg7ICAvLyBuZWVkIGxvb2sgdXAgaW4gLmNvbW1pdCgpCiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgRVhQQU5EQ0hBUklOREVYOyAvLyBFeHBhbmQgaW5kZXggZm9sbG93cwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIENPTlRSQUNUQ0hBUklOREVYOyAgLy8gY29udHJhY3QgaW5kZXhlcyBmb2xsb3cKCiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgUFJJTUFSWU9SREVSSU5DUkVNRU5UOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIE1BWElHTk9SQUJMRTsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBTRUNPTkRBUllPUkRFUklOQ1JFTUVOVDsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBURVJUSUFSWU9SREVSSU5DUkVNRU5UOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFBSSU1BUllPUkRFUk1BU0s7CiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgU0VDT05EQVJZT1JERVJNQVNLOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFRFUlRJQVJZT1JERVJNQVNLOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFNFQ09OREFSWVJFU0VUTUFTSzsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBJR05PUkFCTEVNQVNLOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFBSSU1BUllESUZGRVJFTkNFT05MWTsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBTRUNPTkRBUllESUZGRVJFTkNFT05MWTsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBQUklNQVJZT1JERVJTSElGVDsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBTRUNPTkRBUllPUkRFUlNISUZUOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFNPUlRLRVlPRkZTRVQ7CiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgQ09OVFJBQ1RDSEFST1ZFUkZMT1c7CgogIHN0YXRpYyBjb25zdCBpbnQxNl90ICAgICAgICAgICAgICAgIEZJTEVJRDsKCiAgc3RhdGljICAgICAgIFVuaWNvZGVTdHJpbmcgICAgICBERUZBVUxUUlVMRVM7CgogIHN0YXRpYyAgY29uc3QgY2hhciogICAgICAgICAgICAga0ZpbGVuYW1lU3VmZml4OwoKICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgLy8gRGF0YSBNZW1iZXJzCgogIFVCb29sICAgICAgICAgICAgICBpc092ZXJJZ25vcmU7CiAgVUNoYXIgICAgICAgICAgICAgbGFzdENoYXI7CiAgTWVyZ2VDb2xsYXRpb24qICAgICBtUGF0dGVybjsKICBVbmljb2RlU3RyaW5nICAgICAgIHNidWZmZXI7CiAgVW5pY29kZVN0cmluZyAgICAgICB0YnVmZmVyOwogIFVuaWNvZGVTdHJpbmcgICAgICAga2V5OwogIE5vcm1hbGl6ZXJJdGVyYXRvciAgKmN1cnNvcjE7CiAgTm9ybWFsaXplckl0ZXJhdG9yICAqY3Vyc29yMjsKICBVQm9vbCAgICAgICAgICAgICAgZGF0YUlzT3duZWQ7CiAgVGFibGVDb2xsYXRpb25EYXRhKiBkYXRhOwp9OwoKaW5saW5lIFVCb29sClJ1bGVCYXNlZENvbGxhdG9yOjpvcGVyYXRvciE9KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3QKewogIHJldHVybiAhKCp0aGlzID09IG90aGVyKTsKfQoKaW5saW5lIHZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmFkZENvbnRyYWN0T3JkZXIoY29uc3QgVW5pY29kZVN0cmluZyAmZ3JvdXBDaGFycywKICAgICAgICAgICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgICAgIGFuT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAgICAgICAgICAgICZzdGF0dXMpCnsKICBhZGRDb250cmFjdE9yZGVyKGdyb3VwQ2hhcnMsIGFuT3JkZXIsIFRSVUUsIHN0YXR1cyk7Cn0KCgoKCiNlbmRpZgo=