LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgQ29weXJpZ2h0IChDKSAxOTk2LTE5OTksIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMKKiAgIENvcnBvcmF0aW9uIGFuZCBvdGhlcnMuICBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gRmlsZSBjb2xsLmgKLy8KLy8gCi8vCi8vIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCi8vCi8vIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgovLwovLyAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KLy8gMDIvNS85NyAgICAgIGFsaXUgICAgICAgIE1vZGlmaWVkIGNyZWF0ZURlZmF1bHQgdG8gbG9hZCBjb2xsYXRpb24gZGF0YSBmcm9tCi8vICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5hcnkgZmlsZXMgd2hlbiBwb3NzaWJsZS4gIEFkZGVkIHJlbGF0ZWQgbWV0aG9kcwovLyAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlQ29sbGF0aW9uRnJvbUZpbGUsIGNob3BMb2NhbGUsIGNyZWF0ZVBhdGhOYW1lLgovLyAwMi8xMS85NyAgICAgYWxpdSAgICAgICAgQWRkZWQgbWVtYmVycyBhZGRUb0NhY2hlLCBmaW5kSW5DYWNoZSwgYW5kIGZnQ2FjaGUuCi8vIDAyLzEyLzk3ICAgICBhbGl1ICAgICAgICBNb2RpZmllZCB0byBjcmVhdGUgb2JqZWN0cyBmcm9tIFJ1bGVCYXNlZENvbGxhdG9yIGNhY2hlLgovLyAgICAgICAgICAgICAgICAgICAgICAgICAgTW92ZWQgY2FjaGUgb3V0IG9mIENvbGxhdGlvbiBjbGFzcy4KLy8gMDIvMTMvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIHNldmVyYWwgbWV0aG9kcyBvdXQgb2YgdGhpcyBjbGFzcyBhbmQgaW50bwovLyAgICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IsIHdpdGggbW9kaWZpY2F0aW9ucy4gIE1vZGlmaWVkCi8vICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVEZWZhdWx0KCkgdG8gY2FsbCBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoTG9jYWxlJikKLy8gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yLiAgR2VuZXJhbCBjbGVhbiB1cCBhbmQgZG9jdW1lbnRhdGlvbi4KLy8gMDIvMjAvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNsb25lLCBvcGVyYXRvcj09LCBvcGVyYXRvciE9LCBvcGVyYXRvcj0sIGNvcHkKLy8gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIGFuZCBnZXREeW5hbWljQ2xhc3NJRC4KLy8gMDMvMjUvOTcgICAgIGhlbGVuYSAgICAgIFVwZGF0ZWQgd2l0aCBwbGF0Zm9ybSBpbmRlcGVuZGVudCBkYXRhIHR5cGVzLgovLyAwNS8wNi85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgbWVtb3J5IGFsbG9jYXRpb24gZXJyb3IgZGV0ZWN0aW9uLgovLyAgNi8yMC85NyAgICAgaGVsZW5hICAgICAgSmF2YSBjbGFzcyBuYW1lIGNoYW5nZS4KLy8gMDkvMDMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNyZWF0ZUNvbGxhdGlvbktleVZhbHVlcygpLgovLyAwMi8xMC85OCAgICAgZGFtaWJhICAgICAgQWRkZWQgY29tcGFyZSgpIHdpdGggbGVuZ3RoIGFzIHBhcmFtZXRlci4KLy8gMDQvMjMvOTkgICAgIHN0ZXBoZW4gICAgIFJlbW92ZWQgRURlY29tcG9zaXRpb25Nb2RlLCBtZXJnZWQgd2l0aAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUuCi8vIDExLzAyLzk5ICAgICBoZWxlbmEgICAgICBDb2xsYXRvciBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuICBFbGltaW5hdGVzIHRoZSAKLy8gICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgY29uc3RydWN0aW9uIGFuZCBzcGVjaWFsIGNhc2UgZm9yIE5PX09QLgovLyAxMS8yMy85OSAgICAgc3JsICAgICAgICAgTW9yZSBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuIElubGluaW5nIG9mCi8vICAgICAgICAgICAgICAgICAgICAgICAgICBjcml0aWNhbCBhY2Nlc3NvcnMuCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpZm5kZWYgQ09MTF9ICiNkZWZpbmUgQ09MTF9ICgoKI2luY2x1ZGUgInVuaWNvZGUvbG9jaWQuaCIKI2luY2x1ZGUgInVuaWNvZGUvdXR5cGVzLmgiCiNpbmNsdWRlICJ1bmljb2RlL3VuaXN0ci5oIgojaW5jbHVkZSAidW5pY29kZS9ub3JtbHpyLmgiCgpjbGFzcyBDb2xsYXRpb25LZXk7CgovKioKICogVGhlIDxjb2RlPkNvbGxhdG9yPC9jb2RlPiBjbGFzcyBwZXJmb3JtcyBsb2NhbGUtc2Vuc2l0aXZlCiAqIDxjb2RlPlN0cmluZzwvY29kZT4gY29tcGFyaXNvbi4gWW91IHVzZSB0aGlzIGNsYXNzIHRvIGJ1aWxkCiAqIHNlYXJjaGluZyBhbmQgc29ydGluZyByb3V0aW5lcyBmb3IgbmF0dXJhbCBsYW5ndWFnZSB0ZXh0LgogKgogKiA8cD4KICogPGNvZGU+Q29sbGF0b3I8L2NvZGU+IGlzIGFuIGFic3RyYWN0IGJhc2UgY2xhc3MuIFN1YmNsYXNzZXMKICogaW1wbGVtZW50IHNwZWNpZmljIGNvbGxhdGlvbiBzdHJhdGVnaWVzLiBPbmUgc3ViY2xhc3MsCiAqIDxjb2RlPlJ1bGVCYXNlZENvbGxhdG9yPC9jb2RlPiwgaXMgY3VycmVudGx5IHByb3ZpZGVkCiAqIGFuZCBpcyBhcHBsaWNhYmxlIHRvIGEgd2lkZSBzZXQgb2YgbGFuZ3VhZ2VzLiBPdGhlcgogKiBzdWJjbGFzc2VzIG1heSBiZSBjcmVhdGVkIHRvIGhhbmRsZSBtb3JlIHNwZWNpYWxpemVkIG5lZWRzLgogKgogKiA8cD4KICogTGlrZSBvdGhlciBsb2NhbGUtc2Vuc2l0aXZlIGNsYXNzZXMsIHlvdSBjYW4gdXNlIHRoZSBzdGF0aWMKICogZmFjdG9yeSBtZXRob2QsIDxjb2RlPmdldEluc3RhbmNlPC9jb2RlPiwgdG8gb2J0YWluIHRoZSBhcHByb3ByaWF0ZQogKiA8Y29kZT5Db2xsYXRvcjwvY29kZT4gb2JqZWN0IGZvciBhIGdpdmVuIGxvY2FsZS4gWW91IHdpbGwgb25seSBuZWVkCiAqIHRvIGxvb2sgYXQgdGhlIHN1YmNsYXNzZXMgb2YgPGNvZGU+Q29sbGF0b3I8L2NvZGU+IGlmIHlvdSBuZWVkCiAqIHRvIHVuZGVyc3RhbmQgdGhlIGRldGFpbHMgb2YgYSBwYXJ0aWN1bGFyIGNvbGxhdGlvbiBzdHJhdGVneSBvcgogKiBpZiB5b3UgbmVlZCB0byBtb2RpZnkgdGhhdCBzdHJhdGVneS4KICoKICogPHA+CiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBzaG93cyBob3cgdG8gY29tcGFyZSB0d28gc3RyaW5ncyB1c2luZwogKiB0aGUgPGNvZGU+Q29sbGF0b3I8L2NvZGU+IGZvciB0aGUgZGVmYXVsdCBsb2NhbGUuCiAqIDxibG9ja3F1b3RlPgogKiA8cHJlPgogKiAvLyBDb21wYXJlIHR3byBzdHJpbmdzIGluIHRoZSBkZWZhdWx0IGxvY2FsZQogKiBVRXJyb3JDb2RlIHN1Y2Nlc3MgPSBVX1pFUk9fRVJST1I7CiAqIENvbGxhdG9yKiBteUNvbGxhdG9yID0gQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKHN1Y2Nlc3MpOwogKiBpZiggbXlDb2xsYXRvci0+Y29tcGFyZSgiYWJjIiwgIkFCQyIpICZsdDsgMCApIHsKICogICAgIGNvdXQgJmx0OyZsdDsgImFiYyBpcyBsZXNzIHRoYW4gQUJDIiAmbHQ7Jmx0OyBlbmRsOwogKiB9ZWxzZXsKICogICAgIGNvdXQgJmx0OyZsdDsgImFiYyBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gQUJDIiAmbHQ7Jmx0OyBlbmRsOwogKiB9CiAqIDwvcHJlPgogKiA8L2Jsb2NrcXVvdGU+CiAqCiAqIDxwPgogKiBZb3UgY2FuIHNldCBhIDxjb2RlPkNvbGxhdG9yPC9jb2RlPidzIDxlbT5zdHJlbmd0aDwvZW0+IHByb3BlcnR5CiAqIHRvIGRldGVybWluZSB0aGUgbGV2ZWwgb2YgZGlmZmVyZW5jZSBjb25zaWRlcmVkIHNpZ25pZmljYW50IGluCiAqIGNvbXBhcmlzb25zLiBGb3VyIHN0cmVuZ3RocyBhcmUgcHJvdmlkZWQ6IDxjb2RlPlBSSU1BUlk8L2NvZGU+LAogKiA8Y29kZT5TRUNPTkRBUlk8L2NvZGU+LCA8Y29kZT5URVJUSUFSWTwvY29kZT4sIGFuZCA8Y29kZT5JREVOVElDQUw8L2NvZGU+LgogKiBUaGUgZXhhY3QgYXNzaWdubWVudCBvZiBzdHJlbmd0aHMgdG8gbGFuZ3VhZ2UgZmVhdHVyZXMgaXMKICogbG9jYWxlIGRlcGVuZGFudC4gIEZvciBleGFtcGxlLCBpbiBDemVjaCwgImUiIGFuZCAiZiIgYXJlIGNvbnNpZGVyZWQKICogcHJpbWFyeSBkaWZmZXJlbmNlcywgd2hpbGUgImUiIGFuZCAiXHUwMEVBIiBhcmUgc2Vjb25kYXJ5IGRpZmZlcmVuY2VzLAogKiAiZSIgYW5kICJFIiBhcmUgdGVydGlhcnkgZGlmZmVyZW5jZXMgYW5kICJlIiBhbmQgImUiIGFyZSBpZGVudGljYWwuCiAqIFRoZSBmb2xsb3dpbmcgc2hvd3MgaG93IGJvdGggY2FzZSBhbmQgYWNjZW50cyBjb3VsZCBiZSBpZ25vcmVkIGZvcgogKiBVUyBFbmdsaXNoLgogKiA8YmxvY2txdW90ZT4KICogPHByZT4KICogLy9HZXQgdGhlIENvbGxhdG9yIGZvciBVUyBFbmdsaXNoIGFuZCBzZXQgaXRzIHN0cmVuZ3RoIHRvIFBSSU1BUlkKICogVUVycm9yQ29kZSBzdWNjZXNzID0gVV9aRVJPX0VSUk9SOwogKiBDb2xsYXRvciogdXNDb2xsYXRvciA9IENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZShMb2NhbGU6OlVTLCBzdWNjZXNzKTsKICogdXNDb2xsYXRvci0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlBSSU1BUlkpOwogKiBpZiggdXNDb2xsYXRvci0+Y29tcGFyZSgiYWJjIiwgIkFCQyIpID09IDAgKSB7CiAqICAgICBjb3V0ICZsdDsmbHQ7ICInYWJjJyBhbmQgJ0FCQycgc3RyaW5ncyBhcmUgZXF1aXZhbGVudCB3aXRoIHN0cmVuZ3RoIFBSSU1BUlkiICZsdDsmbHQ7IGVuZGw7CiAqIH0KICogPC9wcmU+CiAqIDwvYmxvY2txdW90ZT4KICogPHA+CiAqIEZvciBjb21wYXJpbmcgPGNvZGU+U3RyaW5nPC9jb2RlPnMgZXhhY3RseSBvbmNlLCB0aGUgPGNvZGU+Y29tcGFyZTwvY29kZT4KICogbWV0aG9kIHByb3ZpZGVzIHRoZSBiZXN0IHBlcmZvcm1hbmNlLiBXaGVuIHNvcnRpbmcgYSBsaXN0IG9mCiAqIDxjb2RlPlN0cmluZzwvY29kZT5zIGhvd2V2ZXIsIGl0IGlzIGdlbmVyYWxseSBuZWNlc3NhcnkgdG8gY29tcGFyZSBlYWNoCiAqIDxjb2RlPlN0cmluZzwvY29kZT4gbXVsdGlwbGUgdGltZXMuIEluIHRoaXMgY2FzZSwgPGNvZGU+Q29sbGF0aW9uS2V5PC9jb2RlPnMKICogcHJvdmlkZSBiZXR0ZXIgcGVyZm9ybWFuY2UuIFRoZSA8Y29kZT5Db2xsYXRpb25LZXk8L2NvZGU+IGNsYXNzIGNvbnZlcnRzCiAqIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBhIHNlcmllcyBvZiBiaXRzIHRoYXQgY2FuIGJlIGNvbXBhcmVkIGJpdHdpc2UKICogYWdhaW5zdCBvdGhlciA8Y29kZT5Db2xsYXRpb25LZXk8L2NvZGU+cy4gQSA8Y29kZT5Db2xsYXRpb25LZXk8L2NvZGU+IGlzCiAqIGNyZWF0ZWQgYnkgYSA8Y29kZT5Db2xsYXRvcjwvY29kZT4gb2JqZWN0IGZvciBhIGdpdmVuIDxjb2RlPlN0cmluZzwvY29kZT4uCiAqIDxwPgogKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IDxjb2RlPkNvbGxhdG9yPC9jb2RlPnMgd2l0aCBkaWZmZXJlbnQgTG9jYWxlLAogKiBDb2xsYXRpb25TdHJlbmd0aCBhbmQgRGVjb21wb3NpdGlvbk1vZGUgc2V0dGluZ3Mgd2lsbCByZXR1cm4gZGlmZmVyZW50CiAqIHNvcnQgb3JkZXJzIGZvciB0aGUgc2FtZSBzZXQgb2Ygc3RyaW5ncy4gTG9jYWxlcyBoYXZlIHNwZWNpZmljIAogKiBjb2xsYXRpb24gcnVsZXMsIGFuZCB0aGUgd2F5IGluIHdoaWNoIHNlY29uZGFyeSBhbmQgdGVydGlhcnkgZGlmZmVyZW5jZXMgCiAqIGFyZSB0YWtlbiBpbnRvIGFjY291bnQsIGZvciBleGFtcGxlLCB3aWxsIHJlc3VsdCBpbiBhIGRpZmZlcmVudCBzb3J0aW5nIG9yZGVyCiAqIGZvciBzYW1lIHN0cmluZ3MuCiAqIDxwPgogKiAKICogQHNlZSAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yCiAqIEBzZWUgICAgICAgICBDb2xsYXRpb25LZXkKICogQHNlZSAgICAgICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcgogKiBAc2VlICAgICAgICAgTG9jYWxlCiAqIEBzZWUgICAgICAgICBOb3JtYWxpemVyCiAqIEB2ZXJzaW9uICAgICAxLjcgMS8xNC85NwogKiBAYXV0aG9yICAgICAgSGVsZW5hIFNoaWgKICovCgpjbGFzcyBVX0kxOE5fQVBJIENvbGxhdG9yIHsKcHVibGljOgogIC8qKgogICAqIEJhc2UgbGV0dGVyIHJlcHJlc2VudHMgYSBwcmltYXJ5IGRpZmZlcmVuY2UuICBTZXQgY29tcGFyaXNvbgogICAqIGxldmVsIHRvIFBSSU1BUlkgdG8gaWdub3JlIHNlY29uZGFyeSBhbmQgdGVydGlhcnkgZGlmZmVyZW5jZXMuCiAgICogVXNlIHRoaXMgdG8gc2V0IHRoZSBzdHJlbmd0aCBvZiBhIENvbGxhdG9yIG9iamVjdC4KICAgKiBFeGFtcGxlIG9mIHByaW1hcnkgZGlmZmVyZW5jZSwgImFiYyIgJmx0OyAiYWJkIgogICAqIAogICAqIERpYWNyaXRpY2FsIGRpZmZlcmVuY2VzIG9uIHRoZSBzYW1lIGJhc2UgbGV0dGVyIHJlcHJlc2VudCBhIHNlY29uZGFyeQogICAqIGRpZmZlcmVuY2UuICBTZXQgY29tcGFyaXNvbiBsZXZlbCB0byBTRUNPTkRBUlkgdG8gaWdub3JlIHRlcnRpYXJ5CiAgICogZGlmZmVyZW5jZXMuIFVzZSB0aGlzIHRvIHNldCB0aGUgc3RyZW5ndGggb2YgYSBDb2xsYXRvciBvYmplY3QuCiAgICogRXhhbXBsZSBvZiBzZWNvbmRhcnkgZGlmZmVyZW5jZSwgIuQiID4+ICJhIi4KICAgKgogICAqIFVwcGVyY2FzZSBhbmQgbG93ZXJjYXNlIHZlcnNpb25zIG9mIHRoZSBzYW1lIGNoYXJhY3RlciByZXByZXNlbnRzIGEKICAgKiB0ZXJ0aWFyeSBkaWZmZXJlbmNlLiAgU2V0IGNvbXBhcmlzb24gbGV2ZWwgdG8gVEVSVElBUlkgdG8gaW5jbHVkZQogICAqIGFsbCBjb21wYXJpc29uIGRpZmZlcmVuY2VzLiBVc2UgdGhpcyB0byBzZXQgdGhlIHN0cmVuZ3RoIG9mIGEgQ29sbGF0b3IKICAgKiBvYmplY3QuCiAgICogRXhhbXBsZSBvZiB0ZXJ0aWFyeSBkaWZmZXJlbmNlLCAiYWJjIiAmbHQ7Jmx0OyZsdDsgIkFCQyIuCiAgICoKICAgKiBUd28gY2hhcmFjdGVycyBhcmUgY29uc2lkZXJlZCAiaWRlbnRpY2FsIiB3aGVuIHRoZXkgaGF2ZSB0aGUgc2FtZQogICAqIHVuaWNvZGUgc3BlbGxpbmdzLgogICAqIEZvciBleGFtcGxlLCAi5CIgPT0gIuQiLgogICAqCiAgICogRUNvbGxhdGlvblN0cmVuZ3RoIGlzIGFsc28gdXNlZCB0byBkZXRlcm1pbmUgdGhlIHN0cmVuZ3RoIG9mIHNvcnQga2V5cyAKICAgKiBnZW5lcmF0ZWQgZnJvbSBDb2xsYXRvciBvYmplY3RzLgogICAqLwogIGVudW0gRUNvbGxhdGlvblN0cmVuZ3RoIHsKICAgIFBSSU1BUlkgPSAwLAogICAgU0VDT05EQVJZID0gMSwgCiAgICBURVJUSUFSWSA9IDIsCiAgICBJREVOVElDQUwgPSAzCiAgfTsKCiAgLyoqCiAgICogTEVTUyBpcyByZXR1cm5lZCBpZiBzb3VyY2Ugc3RyaW5nIGlzIGNvbXBhcmVkIHRvIGJlIGxlc3MgdGhhbiB0YXJnZXQKICAgKiBzdHJpbmcgaW4gdGhlIGNvbXBhcmUoKSBtZXRob2QuCiAgICogRVFVQUwgaXMgcmV0dXJuZWQgaWYgc291cmNlIHN0cmluZyBpcyBjb21wYXJlZCB0byBiZSBlcXVhbCB0byB0YXJnZXQKICAgKiBzdHJpbmcgaW4gdGhlIGNvbXBhcmUoKSBtZXRob2QuCiAgICogR1JFQVRFUiBpcyByZXR1cm5lZCBpZiBzb3VyY2Ugc3RyaW5nIGlzIGNvbXBhcmVkIHRvIGJlIGdyZWF0ZXIgdGhhbgogICAqIHRhcmdldCBzdHJpbmcgaW4gdGhlIGNvbXBhcmUoKSBtZXRob2QuCiAgICogQHNlZSBDb2xsYXRvciNjb21wYXJlCiAgICovCiAgZW51bSBFQ29tcGFyaXNvblJlc3VsdCB7CiAgICBMRVNTID0gLTEsCiAgICBFUVVBTCA9IDAsCiAgICBHUkVBVEVSID0gMQogIH07CiAgCiAgLyoqCiAgICogRGVzdHJ1Y3RvcgogICAqIEBzdGFibGUKICAgKi8KICB2aXJ0dWFsICAgICAgICAgICAgICAgICAgICAgICAgIH5Db2xsYXRvcigpOwoKICAvKioKICAgKiBSZXR1cm5zIHRydWUgaWYgIm90aGVyIiBpcyB0aGUgc2FtZSBhcyAidGhpcyIKICAgKiBAc3RhYmxlCiAgICovCiAgdmlydHVhbCAgICAgYm9vbF90ICAgICAgICAgICAgICBvcGVyYXRvcj09KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3Q7CgogIC8qKgogICAqIFJldHVybnMgdHJ1ZSBpZiAib3RoZXIiIGlzIG5vdCB0aGUgc2FtZSBhcyAidGhpcyIuCiAgICogQHN0YWJsZQogICAqLwogIHZpcnR1YWwgICAgIGJvb2xfdCAgICAgICAgICAgICAgb3BlcmF0b3IhPShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0OwoKICAvKioKICAgKiBNYWtlcyBhIHNoYWxsb3cgY29weSBvZiB0aGUgY3VycmVudCBvYmplY3QuCiAgICogQHN0YWJsZQogICAqLwogIHZpcnR1YWwgICAgIENvbGxhdG9yKiAgICAgICAgICAgY2xvbmUodm9pZCkgY29uc3QgPSAwOwogIC8qKgogICAqIENyZWF0ZXMgdGhlIGNvbGxhdG9yIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgZGVmYXVsdCBsb2NhbGUuCiAgICogVGhlIGRlZmF1bHQgbG9jYWxlIGlzIGRldGVybWluZWQgYnkgTG9jYWxlOjpnZXREZWZhdWx0LgogICAqIEByZXR1cm4gdGhlIGNvbGxhdGlvbiBvYmplY3Qgb2YgdGhlIGRlZmF1bHQgbG9jYWxlLihmb3IgZXhhbXBsZSwgZW5fVVMpCiAgICogQHNlZSBMb2NhbGUjZ2V0RGVmYXVsdAogICAqIFRoZSBVRXJyb3JDb2RlJiBlcnIgcGFyYW1ldGVyIGlzIHVzZWQgdG8gcmV0dXJuIHN0YXR1cyBpbmZvcm1hdGlvbiB0byB0aGUgdXNlci4KICAgKiBUbyBjaGVjayB3aGV0aGVyIHRoZSBjb25zdHJ1Y3Rpb24gc3VjY2VlZGVkIG9yIG5vdCwgeW91IHNob3VsZCBjaGVjawogICAqIHRoZSB2YWx1ZSBvZiBVX1NVQ0NFU1MoZXJyKS4gIElmIHlvdSB3aXNoIG1vcmUgZGV0YWlsZWQgaW5mb3JtYXRpb24sIHlvdQogICAqIGNhbiBjaGVjayBmb3IgaW5mb3JtYXRpb25hbCBlcnJvciByZXN1bHRzIHdoaWNoIHN0aWxsIGluZGljYXRlIHN1Y2Nlc3MuCiAgICogVV9VU0lOR19GQUxMQkFDS19FUlJPUiBpbmRpY2F0ZXMgdGhhdCBhIGZhbGwgYmFjayBsb2NhbGUgd2FzIHVzZWQuICBGb3IKICAgKiBleGFtcGxlLCAnZGVfQ0gnIHdhcyByZXF1ZXN0ZWQsIGJ1dCBub3RoaW5nIHdhcyBmb3VuZCB0aGVyZSwgc28gJ2RlJyB3YXMKICAgKiB1c2VkLiAgVV9VU0lOR19ERUZBVUxUX0VSUk9SIGluZGljYXRlcyB0aGF0IHRoZSBkZWZhdWx0IGxvY2FsZSBkYXRhIHdhcwogICAqIHVzZWQ7IG5laXRoZXIgdGhlIHJlcXVlc3RlZCBsb2NhbGUgbm9yIGFueSBvZiBpdHMgZmFsbCBiYWNrIGxvY2FsZXMKICAgKiBjb3VsZCBiZSBmb3VuZC4KICAgKiBUaGUgY2FsbGVyIG93bnMgdGhlIHJldHVybmVkIG9iamVjdCBhbmQgaXMgcmVzcG9uc2libGUgZm9yIGRlbGV0aW5nIGl0LgogICAqIEBzdGFibGUKICAgKi8KICBzdGF0aWMgIENvbGxhdG9yKiAgICAgICAgICAgY3JlYXRlSW5zdGFuY2UoIFVFcnJvckNvZGUmICBlcnIpOwoKICAvKioKICAgKiBHZXRzIHRoZSB0YWJsZS1iYXNlZCBjb2xsYXRpb24gb2JqZWN0IGZvciB0aGUgZGVzaXJlZCBsb2NhbGUuICBUaGUKICAgKiByZXNvdXJjZSBvZiB0aGUgZGVzaXJlZCBsb2NhbGUgd2lsbCBiZSBsb2FkZWQgYnkgUmVzb3VyY2VMb2FkZXIuIAogICAqIExvY2FsZTo6RU5HTElTSCBpcyB0aGUgYmFzZSBjb2xsYXRpb24gdGFibGUgYW5kIGFsbCBvdGhlciBsYW5ndWFnZXMgYXJlIAogICAqIGJ1aWx0IG9uIHRvcCBvZiBpdCB3aXRoIGFkZGl0aW9uYWwgbGFuZ3VhZ2Utc3BlY2lmaWMgbW9kaWZpY2F0aW9ucy4KICAgKiBAcGFyYW0gZGVzaXJlZExvY2FsZSB0aGUgZGVzaXJlZCBsb2NhbGUgdG8gY3JlYXRlIHRoZSBjb2xsYXRpb24gdGFibGUKICAgKiB3aXRoLgogICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgdGFibGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdCBiYXNlZCBvbiB0aGUgZGVzaXJlZAogICAqIGxvY2FsZS4KICAgKiBAc2VlIExvY2FsZQogICAqIEBzZWUgUmVzb3VyY2VMb2FkZXIKICAgKiBUaGUgVUVycm9yQ29kZSYgZXJyIHBhcmFtZXRlciBpcyB1c2VkIHRvIHJldHVybiBzdGF0dXMgaW5mb3JtYXRpb24gdG8gdGhlIHVzZXIuCiAgICogVG8gY2hlY2sgd2hldGhlciB0aGUgY29uc3RydWN0aW9uIHN1Y2NlZWRlZCBvciBub3QsIHlvdSBzaG91bGQgY2hlY2sKICAgKiB0aGUgdmFsdWUgb2YgVV9TVUNDRVNTKGVycikuICBJZiB5b3Ugd2lzaCBtb3JlIGRldGFpbGVkIGluZm9ybWF0aW9uLCB5b3UKICAgKiBjYW4gY2hlY2sgZm9yIGluZm9ybWF0aW9uYWwgZXJyb3IgcmVzdWx0cyB3aGljaCBzdGlsbCBpbmRpY2F0ZSBzdWNjZXNzLgogICAqIFVfVVNJTkdfRkFMTEJBQ0tfRVJST1IgaW5kaWNhdGVzIHRoYXQgYSBmYWxsIGJhY2sgbG9jYWxlIHdhcyB1c2VkLiAgRm9yCiAgICogZXhhbXBsZSwgJ2RlX0NIJyB3YXMgcmVxdWVzdGVkLCBidXQgbm90aGluZyB3YXMgZm91bmQgdGhlcmUsIHNvICdkZScgd2FzCiAgICogdXNlZC4gIFVfVVNJTkdfREVGQVVMVF9FUlJPUiBpbmRpY2F0ZXMgdGhhdCB0aGUgZGVmYXVsdCBsb2NhbGUgZGF0YSB3YXMKICAgKiB1c2VkOyBuZWl0aGVyIHRoZSByZXF1ZXN0ZWQgbG9jYWxlIG5vciBhbnkgb2YgaXRzIGZhbGwgYmFjayBsb2NhbGVzCiAgICogY291bGQgYmUgZm91bmQuCiAgICogVGhlIGNhbGxlciBvd25zIHRoZSByZXR1cm5lZCBvYmplY3QgYW5kIGlzIHJlc3BvbnNpYmxlIGZvciBkZWxldGluZyBpdC4KICAgKiBAc3RhYmxlCiAgICovCiAgc3RhdGljICBDb2xsYXRvciogICAgICAgICAgIGNyZWF0ZUluc3RhbmNlKCBjb25zdCBMb2NhbGUmICAgbG9jLAogICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgZXJyKTsKCiAgLy8gY29tcGFyaXNvbgogIC8qKgogICAqIFRoZSBjb21wYXJpc29uIGZ1bmN0aW9uIGNvbXBhcmVzIHRoZSBjaGFyYWN0ZXIgZGF0YSBzdG9yZWQgaW4gdHdvCiAgICogZGlmZmVyZW50IHN0cmluZ3MuICBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcKICAgKiBpcyBsZXNzIHRoYW4sIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBhbm90aGVyIHN0cmluZy4KICAgKiA8cD5FeGFtcGxlIG9mIHVzZToKICAgKiA8cHJlPgogICAqIC4gICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICogLiAgICAgICBDb2xsYXRvciAqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICAgKiAuICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpQUklNQVJZKTsKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSBDb2xsYXRvcjo6RVFVQUwgKCJhYmMiID09ICJBQkMiKQogICAqIC4gICAgICAgLy8gKG5vIHByaW1hcnkgZGlmZmVyZW5jZSBiZXR3ZWVuICJhYmMiIGFuZCAiQUJDIikKICAgKiAuICAgICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBteUNvbGxhdGlvbi0+Y29tcGFyZSgiYWJjIiwgIkFCQyIpOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7CiAgICogLiAgICAgICAvLyByZXN1bHQgd291bGQgYmUgQ29sbGF0b3I6OkxFU1MgKGFiYyIgJmx0OyZsdDsmbHQ7ICJBQkMiKQogICAqIC4gICAgICAgLy8gKHdpdGggdGVydGlhcnkgZGlmZmVyZW5jZSBiZXR3ZWVuICJhYmMiIGFuZCAiQUJDIikKICAgKiAuICAgICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBteUNvbGxhdGlvbi0+Y29tcGFyZSgiYWJjIiwgIkFCQyIpOwogICAqIDwvcHJlPgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSBzdHJpbmcgdGhhdCBpcyB0byBiZSBjb21wYXJlZCB3aXRoIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEByZXR1cm4gUmV0dXJucyBhIGJ5dGUgdmFsdWUuIEdSRUFURVIgaWYgc291cmNlIGlzIGdyZWF0ZXIKICAgKiB0aGFuIHRhcmdldDsgRVFVQUwgaWYgc291cmNlIGlzIGVxdWFsIHRvIHRhcmdldDsgTEVTUyBpZiBzb3VyY2UgaXMgbGVzcwogICAqIHRoYW4gdGFyZ2V0CiAgICogQHN0YWJsZQogICAqKi8KICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0ICAgY29tcGFyZSggICAgY29uc3QgICBVbmljb2RlU3RyaW5nJiAgc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHRhcmdldCkgY29uc3QgPSAwOwoKICAvKioKICAgKiBEb2VzIHRoZSBzYW1lIHRoaW5nIGFzIGNvbXBhcmUgYnV0IGxpbWl0cyB0aGUgY29tcGFyaXNvbiB0byBhIHNwZWNpZmllZCBsZW5ndGgKICAgKiA8cD5FeGFtcGxlIG9mIHVzZToKICAgKiA8cHJlPgogICAqIC4gICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICogLiAgICAgICBDb2xsYXRvciAqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICAgKiAuICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpQUklNQVJZKTsKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSBDb2xsYXRvcjo6RVFVQUwgKCJhYmMiID09ICJBQkMiKQogICAqIC4gICAgICAgLy8gKG5vIHByaW1hcnkgZGlmZmVyZW5jZSBiZXR3ZWVuICJhYmMiIGFuZCAiQUJDIikKICAgKiAuICAgICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBteUNvbGxhdGlvbi0+Y29tcGFyZSgiYWJjIiwgIkFCQyIsMyk7CiAgICogLiAgICAgICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlRFUlRJQVJZKTsKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSBDb2xsYXRvcjo6TEVTUyAoYWJjIiAmbHQ7Jmx0OyZsdDsgIkFCQyIpCiAgICogLiAgICAgICAvLyAod2l0aCB0ZXJ0aWFyeSBkaWZmZXJlbmNlIGJldHdlZW4gImFiYyIgYW5kICJBQkMiKQogICAqIC4gICAgICAgQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IHJlc3VsdCA9IG15Q29sbGF0aW9uLT5jb21wYXJlKCJhYmMiLCAiQUJDIiwzKTsKICAgKiA8L3ByZT4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHBhcmFtIHRhcmdldCB0aGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggdGhlIGNvbXBhcmlzb24gaXMgbGltaXR0ZWQgdG8KICAgKiBAcmV0dXJuIFJldHVybnMgYSBieXRlIHZhbHVlLiBHUkVBVEVSIGlmIHNvdXJjZSAodXAgdG8gdGhlIHNwZWNpZmllZCBsZW5ndGgpIGlzIGdyZWF0ZXIKICAgKiB0aGFuIHRhcmdldDsgRVFVQUwgaWYgc291cmNlICh1cCB0byBzcGVjaWZpZWQgbGVuZ3RoKSBpcyBlcXVhbCB0byB0YXJnZXQ7IExFU1MgaWYgc291cmNlCiAgICogKHVwIHRvIHRoZSBzcGVjaWZpZWQgbGVuZ3RoKSBpcyBsZXNzICB0aGFuIHRhcmdldC4gICAKICAgKiBAZHJhZnQKICAgKiovCgogIHZpcnR1YWwgRUNvbXBhcmlzb25SZXN1bHQgICBjb21wYXJlKCAgICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGxlbmd0aCkgY29uc3QgPSAwOwogICAgCiAgICAKICAvKioKICAgKiBUaGUgY29tcGFyaXNvbiBmdW5jdGlvbiBjb21wYXJlcyB0aGUgY2hhcmFjdGVyIGRhdGEgc3RvcmVkIGluIHR3bwogICAqIGRpZmZlcmVudCBzdHJpbmcgYXJyYXlzLiAgUmV0dXJucyBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIGEgc3RyaW5nCiAgICogYXJyYXkgaXMgbGVzcyB0aGFuLCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYW5vdGhlciBzdHJpbmcgYXJyYXkuCiAgICogPHA+RXhhbXBsZSBvZiB1c2U6CiAgICogPHByZT4KICAgKiAuICAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAqIC4gICAgICAgQ29sbGF0b3IgKm15Q29sbGF0aW9uID0gQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKExvY2FsZTo6VVMsIHN0YXR1cyk7CiAgICogLiAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHJldHVybjsKICAgKiAuICAgICAgIG15Q29sbGF0aW9uLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6UFJJTUFSWSk7CiAgICogLiAgICAgICAvLyByZXN1bHQgd291bGQgYmUgQ29sbGF0b3I6OkVRVUFMICgiYWJjIiA9PSAiQUJDIikKICAgKiAuICAgICAgIC8vIChubyBwcmltYXJ5IGRpZmZlcmVuY2UgYmV0d2VlbiAiYWJjIiBhbmQgIkFCQyIpCiAgICogLiAgICAgICBDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gbXlDb2xsYXRpb24tPmNvbXBhcmUoTCJhYmMiLCAzLCBMIkFCQyIsIDMpOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7CiAgICogLiAgICAgICAvLyByZXN1bHQgd291bGQgYmUgQ29sbGF0b3I6OkxFU1MgKGFiYyIgJmx0OyZsdDsmbHQ7ICJBQkMiKQogICAqIC4gICAgICAgLy8gKHdpdGggdGVydGlhcnkgZGlmZmVyZW5jZSBiZXR3ZWVuICJhYmMiIGFuZCAiQUJDIikKICAgKiAuICAgICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBteUNvbGxhdGlvbi0+Y29tcGFyZShMImFiYyIsIDMsIEwiQUJDIiwgMyk7CiAgICogPC9wcmU+CiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyBhcnJheSB0byBiZSBjb21wYXJlZCB3aXRoLgogICAqIEBwYXJhbSBzb3VyY2VMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgc291cmNlIHN0cmluZyBhcnJheS4gIElmIHRoaXMgdmFsdWUKICAgKiAgICAgICAgaXMgZXF1YWwgdG8gLTEsIHRoZSBzdHJpbmcgYXJyYXkgaXMgbnVsbC10ZXJtaW5hdGVkLgogICAqIEBwYXJhbSB0YXJnZXQgdGhlIHN0cmluZyB0aGF0IGlzIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdHJpbmcuCiAgICogQHBhcmFtIHRhcmdldExlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSB0YXJnZXQgc3RyaW5nIGFycmF5LiAgSWYgdGhpcyB2YWx1ZQogICAqICAgICAgICBpcyBlcXVhbCB0byAtMSwgdGhlIHN0cmluZyBhcnJheSBpcyBudWxsLXRlcm1pbmF0ZWQuCiAgICogQHJldHVybiBSZXR1cm5zIGEgYnl0ZSB2YWx1ZS4gR1JFQVRFUiBpZiBzb3VyY2UgaXMgZ3JlYXRlcgogICAqIHRoYW4gdGFyZ2V0OyBFUVVBTCBpZiBzb3VyY2UgaXMgZXF1YWwgdG8gdGFyZ2V0OyBMRVNTIGlmIHNvdXJjZSBpcyBsZXNzCiAgICogdGhhbiB0YXJnZXQKICAgKiBAc3RhYmxlCiAgICoqLwogIHZpcnR1YWwgRUNvbXBhcmlzb25SZXN1bHQgICBjb21wYXJlKCAgICBjb25zdCAgIFVDaGFyKiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCAgIFVDaGFyKiAgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCB0YXJnZXRMZW5ndGgpIGNvbnN0ID0gMDsKCiAgLyoqIFRyYW5zZm9ybXMgdGhlIHN0cmluZyBpbnRvIGEgc2VyaWVzIG9mIGNoYXJhY3RlcnMgdGhhdCBjYW4gYmUgY29tcGFyZWQKICAgKiB3aXRoIENvbGxhdGlvbktleTo6Y29tcGFyZVRvLiBJdCBpcyBub3QgcG9zc2libGUgdG8gcmVzdG9yZSB0aGUgb3JpZ2luYWwKICAgKiBzdHJpbmcgZnJvbSB0aGUgY2hhcnMgaW4gdGhlIHNvcnQga2V5LiAgVGhlIGdlbmVyYXRlZCBzb3J0IGtleSBoYW5kbGVzIAogICAqIG9ubHkgYSBsaW1pdGVkIG51bWJlciBvZiBpZ25vcmFibGUgY2hhcmFjdGVycy4KICAgKiA8cD5Vc2UgQ29sbGF0aW9uS2V5OjplcXVhbHMgb3IgQ29sbGF0aW9uS2V5Ojpjb21wYXJlIHRvIGNvbXBhcmUgdGhlCiAgICogZ2VuZXJhdGVkIHNvcnQga2V5cy4KICAgKiA8cD5FeGFtcGxlIG9mIHVzZToKICAgKiA8cHJlPgogICAqIC4gICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICogLiAgICAgICBDb2xsYXRvciAqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICAgKiAuICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpQUklNQVJZKTsKICAgKiAuICAgICAgIFVFcnJvckNvZGUga2V5MVN0YXR1cywga2V5MlN0YXR1czsKICAgKiAuICAgICAgIENvbGxhdGlvbktleSBDb2xsYXRpb25LZXkxCiAgICogLiAgICAgICBDb2xsYXRpb25LZXkxID0gbXlDb2xsYXRpb24tPmdldENvbGxhdGlvbktleSgiYWJjIiwgQ29sbGF0aW9uS2V5MSwga2V5MVN0YXR1cyk7CiAgICogLiAgICAgICBDb2xsYXRpb25LZXkgQ29sbGF0aW9uS2V5MgogICAqIC4gICAgICAgQ29sbGF0aW9uS2V5MiA9IG15Q29sbGF0aW9uLT5nZXRDb2xsYXRpb25LZXkoIkFCQyIsIENvbGxhdGlvbktleTIsIGtleTJTdGF0dXMpOwogICAqIC4gICAgICAgaWYgKFVfRkFJTFVSRShrZXkxU3RhdHVzKSB8fCBVX0ZBSUxVUkUoa2V5MlN0YXR1cykpIHsgZGVsZXRlIG15Q29sbGF0aW9uOyByZXR1cm47IH0KICAgKiAuICAgICAgIC8vIFVzZSBDb2xsYXRpb25LZXk6OmNvbXBhcmUoKSB0byBjb21wYXJlIHRoZSBzb3J0IGtleXMKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSAwIChDb2xsYXRpb25LZXkxID09IENvbGxhdGlvbktleTIpCiAgICogLiAgICAgICBpbnQgcmVzdWx0ID0gQ29sbGF0aW9uS2V5MS5jb21wYXJlKENvbGxhdGlvbktleTIpOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7CiAgICogLiAgICAgICBDb2xsYXRpb25LZXkxID0gbXlDb2xsYXRpb24tPmdldENvbGxhdGlvbktleSgiYWJjIiwgQ29sbGF0aW9uS2V5MSwga2V5MVN0YXR1cyk7CiAgICogLiAgICAgICBDb2xsYXRpb25LZXkyID0gbXlDb2xsYXRpb24tPmdldENvbGxhdGlvbktleSgiQUJDIiwgQ29sbGF0aW9uS2V5Miwga2V5MlN0YXR1cyk7CiAgICogLiAgICAgICBpZiAoVV9GQUlMVVJFKGtleTFTdGF0dXMpIHx8IFVfRkFJTFVSRShrZXkyU3RhdHVzKSkgeyBkZWxldGUgbXlDb2xsYXRpb247IHJldHVybjsgfQogICAqIC4gICAgICAgLy8gVXNlIENvbGxhdGlvbktleTo6Y29tcGFyZVRvIHRvIGNvbXBhcmUgdGhlIGNvbGxhdGlvbiBrZXlzCiAgICogLiAgICAgICAvLyByZXN1bHQgd291bGQgYmUgLTEgKENvbGxhdGlvbktleTEgJmx0OyBDb2xsYXRpb25LZXkyKQogICAqIC4gICAgICAgcmVzdWx0ID0gQ29sbGF0aW9uS2V5MS5jb21wYXJlVG8oQ29sbGF0aW9uS2V5Mik7CiAgICogLiAgICAgICBkZWxldGUgbXlDb2xsYXRpb247CiAgICogPC9wcmU+CiAgICogPHA+SWYgdGhlIHNvdXJjZSBzdHJpbmcgaXMgbnVsbCwgYSBudWxsIGNvbGxhdGlvbiBrZXkgd2lsbCBiZSByZXR1cm5lZC4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHRyYW5zZm9ybWVkIGludG8gYSBzb3J0IGtleS4KICAgKiBAcGFyYW0ga2V5IHRoZSBjb2xsYXRpb24ga2V5IHRvIGJlIGZpbGxlZCBpbgogICAqIEByZXR1cm4gdGhlIGNvbGxhdGlvbiBrZXkgb2YgdGhlIHN0cmluZyBiYXNlZCBvbiB0aGUgY29sbGF0aW9uIHJ1bGVzLgogICAqIEBzZWUgQ29sbGF0aW9uS2V5I2NvbXBhcmUKICAgKiBAZHJhZnQKICAgKi8KICB2aXJ0dWFsIENvbGxhdGlvbktleSYgICAgICAgZ2V0Q29sbGF0aW9uS2V5KGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25LZXkmICAgICAgIGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykgY29uc3QgPSAwOwoKICAvKiogVHJhbnNmb3JtcyB0aGUgc3RyaW5nIGludG8gYSBzZXJpZXMgb2YgY2hhcmFjdGVycyB0aGF0IGNhbiBiZSBjb21wYXJlZAogICAqIHdpdGggQ29sbGF0aW9uS2V5Ojpjb21wYXJlVG8uIEl0IGlzIG5vdCBwb3NzaWJsZSB0byByZXN0b3JlIHRoZSBvcmlnaW5hbAogICAqIHN0cmluZyBmcm9tIHRoZSBjaGFycyBpbiB0aGUgc29ydCBrZXkuICBUaGUgZ2VuZXJhdGVkIHNvcnQga2V5IGhhbmRsZXMgCiAgICogb25seSBhIGxpbWl0ZWQgbnVtYmVyIG9mIGlnbm9yYWJsZSBjaGFyYWN0ZXJzLgogICAqIDxwPlVzZSBDb2xsYXRpb25LZXk6OmVxdWFscyBvciBDb2xsYXRpb25LZXk6OmNvbXBhcmUgdG8gY29tcGFyZSB0aGUKICAgKiBnZW5lcmF0ZWQgc29ydCBrZXlzLgogICAqIDxwPklmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIG51bGwsIGEgbnVsbCBjb2xsYXRpb24ga2V5IHdpbGwgYmUgcmV0dXJuZWQuCiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSB0cmFuc2Zvcm1lZCBpbnRvIGEgc29ydCBrZXkuCiAgICogQHBhcmFtIHNvdXJjZUxlbmd0aCBsZW5ndGggb2YgdGhlIGNvbGxhdGlvbiBrZXkKICAgKiBAcGFyYW0ga2V5IHRoZSBjb2xsYXRpb24ga2V5IHRvIGJlIGZpbGxlZCBpbgogICAqIEByZXR1cm4gdGhlIGNvbGxhdGlvbiBrZXkgb2YgdGhlIHN0cmluZyBiYXNlZCBvbiB0aGUgY29sbGF0aW9uIHJ1bGVzLgogICAqIEBzZWUgQ29sbGF0aW9uS2V5I2NvbXBhcmUKICAgKiBAZHJhZnQKICAgKi8KICB2aXJ0dWFsIENvbGxhdGlvbktleSYgICAgICAgZ2V0Q29sbGF0aW9uS2V5KGNvbnN0IFVDaGFyICpzb3VyY2UsCgkJCQkJICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCgkJCQkJICAgICAgQ29sbGF0aW9uS2V5JiAgICAgICBrZXksCgkJCQkJICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpIGNvbnN0ID0gMDsKICAvKioKICAgKiBHZW5lcmF0ZXMgdGhlIGhhc2ggY29kZSBmb3IgdGhlIGNvbGxhdGlvbiBvYmplY3QKICAgKiBAc3RhYmxlCiAgICovCiAgdmlydHVhbCBpbnQzMl90ICAgICAgICAgICAgIGhhc2hDb2RlKHZvaWQpIGNvbnN0ID0gMDsKCiAgLyoqCiAgICogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBjb21wYXJpbmcgdHdvIHN0cmluZ3MgYmFzZWQgb24KICAgKiB0aGUgY29sbGF0aW9uIHJ1bGVzLgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmaXJzdCBzdHJpbmcgaXMgZ3JlYXRlciB0aGFuIHRoZSBzZWNvbmQgb25lLAogICAqIGFjY29yZGluZyB0byB0aGUgY29sbGF0aW9uIHJ1bGVzLiBmYWxzZSwgb3RoZXJ3aXNlLgogICAqIEBzZWUgQ29sbGF0b3IjY29tcGFyZQogICAqIEBzdGFibGUKICAgKi8KICBib29sX3QgICAgICAgICAgICAgIGdyZWF0ZXIoICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgc291cmNlLCAKICAgICAgICAgICAgICAgICAgY29uc3QgICBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0OwogIC8qKgogICAqIENvbnZlbmllbmNlIG1ldGhvZCBmb3IgY29tcGFyaW5nIHR3byBzdHJpbmdzIGJhc2VkIG9uIHRoZSBjb2xsYXRpb24KICAgKiBydWxlcy4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHBhcmFtIHRhcmdldCB0aGUgdGFyZ2V0IHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoLgogICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZmlyc3Qgc3RyaW5nIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUKICAgKiBzZWNvbmQgb25lLCBhY2NvcmRpbmcgdG8gdGhlIGNvbGxhdGlvbiBydWxlcy4gZmFsc2UsIG90aGVyd2lzZS4KICAgKiBAc2VlIENvbGxhdG9yI2NvbXBhcmUKICAgKiBAc3RhYmxlCiAgICovCiAgYm9vbF90ICAgICAgICAgICAgICBncmVhdGVyT3JFcXVhbCggY29uc3QgICBVbmljb2RlU3RyaW5nJiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgICBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0OwogIC8qKgogICAqIENvbnZlbmllbmNlIG1ldGhvZCBmb3IgY29tcGFyaW5nIHR3byBzdHJpbmdzIGJhc2VkIG9uIHRoZSBjb2xsYXRpb24KICAgKiBydWxlcy4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHBhcmFtIHRhcmdldCB0aGUgdGFyZ2V0IHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoLgogICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3RyaW5ncyBhcmUgZXF1YWwgYWNjb3JkaW5nIHRvIHRoZSBjb2xsYXRpb24KICAgKiBydWxlcy4gIGZhbHNlLCBvdGhlcndpc2UuCiAgICogQHNlZSBDb2xsYXRvciNjb21wYXJlCiAgICogQHN0YWJsZQogICAqLwogIGJvb2xfdCAgICAgICAgICAgICAgZXF1YWxzKCBjb25zdCAgIFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwgCiAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdDsKICAgICAgICAKICAvLyBnZXR0ZXIvc2V0dGVyCiAgLyoqCiAgICogR2V0IHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgb2YgdGhlIGNvbGxhdG9yIG9iamVjdC4KICAgKiBAcmV0dXJuIHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUKICAgKiBAc2VlIENvbGxhdG9yI3NldERlY29tcG9zaXRpb24KICAgKiBAc3RhYmxlCiAgICovCiAgTm9ybWFsaXplcjo6RU1vZGUgIGdldERlY29tcG9zaXRpb24odm9pZCkgY29uc3Q7CiAgLyoqCiAgICogU2V0IHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgb2YgdGhlIGNvbGxhdG9yIG9iamVjdC4gc3VjY2VzcyBpcyBlcXVhbAogICAqIHRvIFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUiBpZiBlcnJvciBvY2N1cnMuCiAgICogQHBhcmFtIHRoZSBuZXcgZGVjb21wb3NpdGlvbiBtb2RlCiAgICogQHNlZSBDb2xsYXRvciNnZXREZWNvbXBvc2l0aW9uCiAgICogQHN0YWJsZQogICAqLwogIHZvaWQgICAgICAgICAgICAgICAgc2V0RGVjb21wb3NpdGlvbihOb3JtYWxpemVyOjpFTW9kZSAgbW9kZSk7CiAgLyoqCiAgICogRGV0ZXJtaW5lcyB0aGUgbWluaW11bSBzdHJlbmd0aCB0aGF0IHdpbGwgYmUgdXNlIGluIGNvbXBhcmlzb24gb3IKICAgKiB0cmFuc2Zvcm1hdGlvbi4KICAgKiA8cD5FLmcuIHdpdGggc3RyZW5ndGggPT0gU0VDT05EQVJZLCB0aGUgdGVydGlhcnkgZGlmZmVyZW5jZSBpcyBpZ25vcmVkCiAgICogPHA+RS5nLiB3aXRoIHN0cmVuZ3RoID09IFBSSU1BUlksIHRoZSBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IGRpZmZlcmVuY2UKICAgKiBhcmUgaWdub3JlZC4KICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGNvbXBhcmlzb24gbGV2ZWwuCiAgICogQHNlZSBDb2xsYXRvciNzZXRTdHJlbmd0aAogICAqIEBzdGFibGUKICAgKi8KICBFQ29sbGF0aW9uU3RyZW5ndGggIGdldFN0cmVuZ3RoKHZvaWQpIGNvbnN0OwogIC8qKgogICAqIFNldHMgdGhlIG1pbmltdW0gc3RyZW5ndGggdG8gYmUgdXNlZCBpbiBjb21wYXJpc29uIG9yIHRyYW5zZm9ybWF0aW9uLgogICAqIDxwPkV4YW1wbGUgb2YgdXNlOgogICAqIDxwcmU+CiAgICogLiAgICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgKiAuICAgICAgIENvbGxhdG9yICpteUNvbGxhdGlvbiA9IENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZShMb2NhbGU6OlVTLCBzdGF0dXMpOwogICAqIC4gICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgICogLiAgICAgICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlBSSU1BUlkpOwogICAqIC4gICAgICAgLy8gcmVzdWx0IHdpbGwgYmUgImFiYyIgPT0gIkFCQyIKICAgKiAuICAgICAgIC8vIHRlcnRpYXJ5IGRpZmZlcmVuY2VzIHdpbGwgYmUgaWdub3JlZAogICAqIC4gICAgICAgQ29sbGF0b3I6OkNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gbXlDb2xsYXRpb24tPmNvbXBhcmUoImFiYyIsICJBQkMiKTsKICAgKiA8L3ByZT4KICAgKiBAc2VlIENvbGxhdG9yI2dldFN0cmVuZ3RoCiAgICogQHBhcmFtIG5ld1N0cmVuZ3RoIHRoZSBuZXcgY29tcGFyaXNvbiBsZXZlbC4KICAgKiBAc3RhYmxlCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICBzZXRTdHJlbmd0aCggICAgRUNvbGxhdGlvblN0cmVuZ3RoICBuZXdTdHJlbmd0aCk7CiAgLyoqCiAgICogR2V0IG5hbWUgb2YgdGhlIG9iamVjdCBmb3IgdGhlIGRlc2lyZWQgTG9jYWxlLCBpbiB0aGUgZGVzaXJlZCBsYW5nYXVnZQogICAqIEBwYXJhbSBvYmplY3RMb2NhbGUgbXVzdCBiZSBmcm9tIGdldEF2YWlsYWJsZUxvY2FsZXMKICAgKiBAcGFyYW0gZGlzcGxheUxvY2FsZSBzcGVjaWZpZXMgdGhlIGRlc2lyZWQgbG9jYWxlIGZvciBvdXRwdXQKICAgKiBAcGFyYW0gbmFtZSB0aGUgZmlsbC1pbiBwYXJhbWV0ZXIgb2YgdGhlIHJldHVybiB2YWx1ZQogICAqIEByZXR1cm4gZGlzcGxheS1hYmxlIG5hbWUgb2YgdGhlIG9iamVjdCBmb3IgdGhlIG9iamVjdCBsb2NhbGUgaW4gdGhlCiAgICogZGVzaXJlZCBsYW5ndWFnZQogICAqIEBzdGFibGUKICAgKi8KICBzdGF0aWMgIFVuaWNvZGVTdHJpbmcmICAgICAgZ2V0RGlzcGxheU5hbWUoIGNvbnN0ICAgTG9jYWxlJiAgICAgb2JqZWN0TG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgTG9jYWxlJiAgICAgZGlzcGxheUxvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiBuYW1lKSA7CiAgLyoqCiAgICogR2V0IG5hbWUgb2YgdGhlIG9iamVjdCBmb3IgdGhlIGRlc2lyZWQgTG9jYWxlLCBpbiB0aGUgbGFuZ2F1Z2Ugb2YgdGhlCiAgICogZGVmYXVsdCBsb2NhbGUuCiAgICogQHBhcmFtIG9iamVjdExvY2FsZSBtdXN0IGJlIGZyb20gZ2V0QXZhaWxhYmxlTG9jYWxlcwogICAqIEBwYXJhbSBuYW1lIHRoZSBmaWxsLWluIHBhcmFtZXRlciBvZiB0aGUgcmV0dXJuIHZhbHVlCiAgICogQHJldHVybiBuYW1lIG9mIHRoZSBvYmplY3QgZm9yIHRoZSBkZXNpcmVkIGxvY2FsZSBpbiB0aGUgZGVmYXVsdAogICAqIGxhbmd1YWdlCiAgICogQHN0YWJsZQogICAqLwogIHN0YXRpYyAgVW5pY29kZVN0cmluZyYgICAgICBnZXREaXNwbGF5TmFtZSggY29uc3QgICBMb2NhbGUmICAgICAgICAgb2JqZWN0TG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmICBuYW1lKSA7CgogIC8qKgogICAqIEdldCB0aGUgc2V0IG9mIExvY2FsZXMgZm9yIHdoaWNoIENvbGxhdGlvbnMgYXJlIGluc3RhbGxlZAogICAqIEBwYXJhbSBjb3VudCB0aGUgb3V0cHV0IHBhcmFtZXRlciBvZiBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGxvY2FsZSBsaXN0CiAgICogQHJldHVybiB0aGUgbGlzdCBvZiBhdmFpbGFibGUgbG9jYWxlcyB3aGljaCBjb2xsYXRpb25zIGFyZSBpbnN0YWxsZWQKICAgKiBAc3RhYmxlCiAgICovCiAgc3RhdGljICBjb25zdCAgIExvY2FsZSogICAgIGdldEF2YWlsYWJsZUxvY2FsZXMoaW50MzJfdCYgY291bnQpOwoKICAvKioKICAgKiBSZXR1cm5zIGEgdW5pcXVlIGNsYXNzIElEIFBPTFlNT1JQSElDQUxMWS4gIFB1cmUgdmlydHVhbCBtZXRob2QuCiAgICogVGhpcyBtZXRob2QgaXMgdG8gaW1wbGVtZW50IGEgc2ltcGxlIHZlcnNpb24gb2YgUlRUSSwgc2luY2Ugbm90IGFsbAogICAqIEMrKyBjb21waWxlcnMgc3VwcG9ydCBnZW51aW5lIFJUVEkuICBQb2x5bW9ycGhpYyBvcGVyYXRvcj09KCkgYW5kCiAgICogY2xvbmUoKSBtZXRob2RzIGNhbGwgdGhpcyBtZXRob2QuCiAgICoKICAgKiBDb25jcmV0ZSBzdWJjbGFzc2VzIG9mIEZvcm1hdCBtdXN0IGltcGxlbWVudCBnZXREeW5hbWljQ2xhc3NJRCgpCiAgICogYW5kIGFsc28gYSBzdGF0aWMgbWV0aG9kIGFuZCBkYXRhIG1lbWJlcjoKICAgKgogICAqICAgICAgc3RhdGljIFVDbGFzc0lEIGdldFN0YXRpY0NsYXNzSUQoKSB7IHJldHVybiAoVUNsYXNzSUQpJmZnQ2xhc3NJRDsgfQogICAqICAgICAgc3RhdGljIGNoYXIgZmdDbGFzc0lEOwogICAqCiAgICogQHJldHVybiAgICAgICAgICBUaGUgY2xhc3MgSUQgZm9yIHRoaXMgb2JqZWN0LiBBbGwgb2JqZWN0cyBvZiBhCiAgICogICAgICAgICAgICAgICAgICBnaXZlbiBjbGFzcyBoYXZlIHRoZSBzYW1lIGNsYXNzIElELiAgT2JqZWN0cyBvZgogICAqICAgICAgICAgICAgICAgICAgb3RoZXIgY2xhc3NlcyBoYXZlIGRpZmZlcmVudCBjbGFzcyBJRHMuCiAgICogQHN0YWJsZQogICAqLwogIHZpcnR1YWwgVUNsYXNzSUQgZ2V0RHluYW1pY0NsYXNzSUQodm9pZCkgY29uc3QgPSAwOwoKcHJvdGVjdGVkOgogIC8qKgogICAqIENvbnN0cnVjdG9ycwogICAqLwogIENvbGxhdG9yKCk7CiAgQ29sbGF0b3IoRUNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wb3NpdGlvbk1vZGUpOwogIENvbGxhdG9yKGNvbnN0ICBDb2xsYXRvciYgICBvdGhlcik7CgogIC8qKgogICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IKICAgKi8KICBjb25zdCAgICAgICBDb2xsYXRvciYgICAgICAgb3BlcmF0b3I9KGNvbnN0IENvbGxhdG9yJiAgIG90aGVyKTsKCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpwcml2YXRlOgogICAgICAgICAgICAKICBFQ29sbGF0aW9uU3RyZW5ndGggIHN0cmVuZ3RoOwogIE5vcm1hbGl6ZXI6OkVNb2RlICBkZWNtcDsKfTsKCmlubGluZSBib29sX3QKQ29sbGF0b3I6Om9wZXJhdG9yPT0oY29uc3QgQ29sbGF0b3ImIG90aGVyKSBjb25zdAp7CiAgYm9vbF90IHJlc3VsdDsKICBpZiAodGhpcyA9PSAmb3RoZXIpIHJlc3VsdCA9IFRSVUU7CiAgZWxzZSByZXN1bHQgPSAoKHN0cmVuZ3RoID09IG90aGVyLnN0cmVuZ3RoKSAmJiAoZGVjbXAgPT0gb3RoZXIuZGVjbXApKTsKICByZXR1cm4gcmVzdWx0Owp9CgppbmxpbmUgYm9vbF90CkNvbGxhdG9yOjpvcGVyYXRvciE9KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3QKewogIGJvb2xfdCByZXN1bHQ7CiAgcmVzdWx0ID0gISgqdGhpcyA9PSBvdGhlcik7CiAgcmV0dXJuIHJlc3VsdDsKfQoKaW5saW5lIENvbGxhdG9yOjpFQ29sbGF0aW9uU3RyZW5ndGggCkNvbGxhdG9yOjpnZXRTdHJlbmd0aCgpIGNvbnN0CnsKICByZXR1cm4gc3RyZW5ndGg7Cn0KCmlubGluZSBOb3JtYWxpemVyOjpFTW9kZQpDb2xsYXRvcjo6Z2V0RGVjb21wb3NpdGlvbigpIGNvbnN0CnsKICByZXR1cm4gZGVjbXA7Cn0KCgojZW5kaWYK