LyoKICogRGlyZWN0M0Qgd2luZSBpbnRlcm5hbCBpbnRlcmZhY2UgbWFpbgogKgogKiBDb3B5cmlnaHQgMjAwMi0yMDAzIFRoZSB3aW5lLWQzZCB0ZWFtCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgUmFwaGFlbCBKdW5xdWVpcmEKICogQ29weXJpZ2h0IDIwMDQgICAgICBKYXNvbiBFZG1lYWRlcwogKiBDb3B5cmlnaHQgMjAwNy0yMDA4IFN0ZWZhbiBE9nNpbmdlciBmb3IgQ29kZVdlYXZlcnMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgImluaXRndWlkLmgiCiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHdpbmVfZDNkKTsKCmludCBudW1fbG9jayA9IDA7CnZvaWQgKCp3aW5lX3RzeDExX2xvY2tfcHRyKSh2b2lkKSA9IE5VTEw7CnZvaWQgKCp3aW5lX3RzeDExX3VubG9ja19wdHIpKHZvaWQpID0gTlVMTDsKCgovKiBXaGVuIHVwZGF0aW5nIGRlZmF1bHQgdmFsdWUgaGVyZSwgbWFrZSBzdXJlIHRvIHVwZGF0ZSB3aW5lY2ZnIGFzIHdlbGwsCiAqIHdoZXJlIGFwcHJvcHJpYXRlLiAqLwp3aW5lZDNkX3NldHRpbmdzX3Qgd2luZWQzZF9zZXR0aW5ncyA9IAp7CiAgICBWU19IVywgICAgICAgICAgLyogSGFyZHdhcmUgYnkgZGVmYXVsdCAqLwogICAgUFNfSFcsICAgICAgICAgIC8qIEhhcmR3YXJlIGJ5IGRlZmF1bHQgKi8KICAgIFZCT19IVywgICAgICAgICAvKiBIYXJkd2FyZSBieSBkZWZhdWx0ICovCiAgICBUUlVFLCAgICAgICAgICAgLyogVXNlIG9mIEdMU0wgZW5hYmxlZCBieSBkZWZhdWx0ICovCiAgICBPUk1fQkFDS0JVRkZFUiwgLyogVXNlIHRoZSBiYWNrYnVmZmVyIHRvIGRvIG9mZnNjcmVlbiByZW5kZXJpbmcgKi8KICAgIFJUTF9BVVRPLCAgICAgICAvKiBBdXRvbWF0aWNhbGx5IGRldGVybWluZSBiZXN0IGxvY2tpbmcgbWV0aG9kICovCiAgICAwLCAgICAgICAgICAgICAgLyogVGhlIGRlZmF1bHQgb2YgbWVtb3J5IGlzIHNldCBpbiBGaWxsR0xDYXBzICovCiAgICBOVUxMICAgICAgICAgICAgLyogTm8gd2luZSBsb2dvIGJ5IGRlZmF1bHQgKi8KfTsKCklXaW5lRDNEKiBXSU5BUEkgV2luZURpcmVjdDNEQ3JlYXRlKFVJTlQgU0RLVmVyc2lvbiwgVUlOVCBkeFZlcnNpb24sIElVbmtub3duICpwYXJlbnQpIHsKICAgIElXaW5lRDNESW1wbCogb2JqZWN0OwoKICAgIGlmICghSW5pdEFkYXB0ZXJzKCkpIHsKICAgICAgICBXQVJOKCJGYWlsZWQgdG8gaW5pdGlhbGl6ZSBkaXJlY3QzZCBhZGFwdGVycywgRGlyZWN0M0Qgd2lsbCBub3QgYmUgYXZhaWxhYmxlXG4iKTsKICAgICAgICBpZihkeFZlcnNpb24gPiA3KSB7CiAgICAgICAgICAgIEVSUigiRGlyZWN0M0QlZCBpcyBub3QgYXZhaWxhYmxlIHdpdGhvdXQgb3BlbmdsXG4iLCBkeFZlcnNpb24pOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzREltcGwpKTsKICAgIG9iamVjdC0+bHBWdGJsID0gJklXaW5lRDNEX1Z0Ymw7CiAgICBvYmplY3QtPmR4VmVyc2lvbiA9IGR4VmVyc2lvbjsKICAgIG9iamVjdC0+cmVmID0gMTsKICAgIG9iamVjdC0+cGFyZW50ID0gcGFyZW50OwoKICAgIFRSQUNFKCJDcmVhdGVkIFdpbmVEM0Qgb2JqZWN0IEAgJXAgZm9yIGQzZCVkIHN1cHBvcnRcbiIsIG9iamVjdCwgZHhWZXJzaW9uKTsKCiAgICByZXR1cm4gKElXaW5lRDNEICopb2JqZWN0Owp9CgpzdGF0aWMgaW5saW5lIERXT1JEIGdldF9jb25maWdfa2V5KEhLRVkgZGVma2V5LCBIS0VZIGFwcGtleSwgY29uc3QgY2hhciogbmFtZSwgY2hhciogYnVmZmVyLCBEV09SRCBzaXplKQp7CiAgICBpZiAoMCAhPSBhcHBrZXkgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoIGFwcGtleSwgbmFtZSwgMCwgTlVMTCwgKExQQllURSkgYnVmZmVyLCAmc2l6ZSApKSByZXR1cm4gMDsKICAgIGlmICgwICE9IGRlZmtleSAmJiAhUmVnUXVlcnlWYWx1ZUV4QSggZGVma2V5LCBuYW1lLCAwLCBOVUxMLCAoTFBCWVRFKSBidWZmZXIsICZzaXplICkpIHJldHVybiAwOwogICAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwp9CgpzdGF0aWMgdm9pZCB3aW5lZDNkX2RvX25vdGhpbmcodm9pZCkKewp9CgovKiBBdCBwcm9jZXNzIGF0dGFjaCAqLwpCT09MIFdJTkFQSSBEbGxNYWluKEhJTlNUQU5DRSBoSW5zdERMTCwgRFdPUkQgZmR3UmVhc29uLCBMUFZPSUQgbHB2KQp7CiAgICBUUkFDRSgiV2luZUQzRCBETExNYWluIFJlYXNvbj0lZFxuIiwgZmR3UmVhc29uKTsKICAgIGlmIChmZHdSZWFzb24gPT0gRExMX1BST0NFU1NfQVRUQUNIKQogICAgewogICAgICAgSE1PRFVMRSBtb2Q7CiAgICAgICBjaGFyIGJ1ZmZlcltNQVhfUEFUSCsxMF07CiAgICAgICBEV09SRCBzaXplID0gc2l6ZW9mKGJ1ZmZlcik7CiAgICAgICBIS0VZIGhrZXkgPSAwOwogICAgICAgSEtFWSBhcHBrZXkgPSAwOwogICAgICAgRFdPUkQgbGVuOwogICAgICAgV05EQ0xBU1NBIHdjOwoKICAgICAgIGF0aWZzX3NoYWRlcl9iYWNrZW5kLnNoYWRlcl9kbGxfbG9hZF9pbml0KCk7CiAgICAgICBnbHNsX3NoYWRlcl9iYWNrZW5kLnNoYWRlcl9kbGxfbG9hZF9pbml0KCk7CiAgICAgICBhcmJfcHJvZ3JhbV9zaGFkZXJfYmFja2VuZC5zaGFkZXJfZGxsX2xvYWRfaW5pdCgpOwogICAgICAgbm9uZV9zaGFkZXJfYmFja2VuZC5zaGFkZXJfZGxsX2xvYWRfaW5pdCgpOwoKICAgICAgIC8qIFdlIG5lZWQgb3VyIG93biB3aW5kb3cgY2xhc3MgZm9yIGEgZmFrZSB3aW5kb3cgd2hpY2ggd2UgdXNlIHRvIHJldHJpZXZlIEdMIGNhcGFiaWxpdGllcyAqLwogICAgICAgLyogV2UgbWlnaHQgbmVlZCBDU19PV05EQyBpbiB0aGUgZnV0dXJlIGlmIHdlIG5vdGljZSBzdHJhbmdlIHRoaW5ncyBvbiBXaW5kb3dzLgogICAgICAgICogVmFyaW91cyBhcnRpY2xlcy9wb3N0cyBhYm91dCBPcGVuR0wgcHJvYmxlbXMgb24gV2luZG93cyByZWNvbW1lbmQgdGhpcy4gKi8KICAgICAgIHdjLnN0eWxlICAgICAgICAgICAgICAgID0gQ1NfSFJFRFJBVyB8IENTX1ZSRURSQVc7CiAgICAgICB3Yy5scGZuV25kUHJvYyAgICAgICAgICA9IERlZldpbmRvd1Byb2NBOwogICAgICAgd2MuY2JDbHNFeHRyYSAgICAgICAgICAgPSAwOwogICAgICAgd2MuY2JXbmRFeHRyYSAgICAgICAgICAgPSAwOwogICAgICAgd2MuaEluc3RhbmNlICAgICAgICAgICAgPSBoSW5zdERMTDsKICAgICAgIHdjLmhJY29uICAgICAgICAgICAgICAgID0gTG9hZEljb25BKE5VTEwsIChMUENTVFIpSURJX1dJTkxPR08pOwogICAgICAgd2MuaEN1cnNvciAgICAgICAgICAgICAgPSBMb2FkQ3Vyc29yQShOVUxMLCAoTFBDU1RSKUlEQ19BUlJPVyk7CiAgICAgICB3Yy5oYnJCYWNrZ3JvdW5kICAgICAgICA9IE5VTEw7CiAgICAgICB3Yy5scHN6TWVudU5hbWUgICAgICAgICA9IE5VTEw7CiAgICAgICB3Yy5scHN6Q2xhc3NOYW1lICAgICAgICA9ICJXaW5lRDNEX09wZW5HTCI7CgogICAgICAgaWYgKCFSZWdpc3RlckNsYXNzQSgmd2MpICYmIEdldExhc3RFcnJvcigpICE9IEVSUk9SX0NMQVNTX0FMUkVBRFlfRVhJU1RTKQogICAgICAgewogICAgICAgICAgIEVSUigiRmFpbGVkIHRvIHJlZ2lzdGVyIHdpbmRvdyBjbGFzcyAnV2luZUQzRF9PcGVuR0wnIVxuIik7CiAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgfQoKICAgICAgIERpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMoaEluc3RETEwpOwoKICAgICAgIG1vZCA9IEdldE1vZHVsZUhhbmRsZUEoICJ3aW5leDExLmRydiIgKTsKICAgICAgIGlmIChtb2QpCiAgICAgICB7CiAgICAgICAgICAgd2luZV90c3gxMV9sb2NrX3B0ciAgID0gKHZvaWQgKilHZXRQcm9jQWRkcmVzcyggbW9kLCAid2luZV90c3gxMV9sb2NrIiApOwogICAgICAgICAgIHdpbmVfdHN4MTFfdW5sb2NrX3B0ciA9ICh2b2lkICopR2V0UHJvY0FkZHJlc3MoIG1vZCwgIndpbmVfdHN4MTFfdW5sb2NrIiApOwogICAgICAgfQogICAgICAgZWxzZSAvKiBXZSBhcmUgbW9zdCBsaWtlbHkgb24gV2luZG93cyAqLwogICAgICAgewogICAgICAgICAgIHdpbmVfdHN4MTFfbG9ja19wdHIgICA9IHdpbmVkM2RfZG9fbm90aGluZzsKICAgICAgICAgICB3aW5lX3RzeDExX3VubG9ja19wdHIgPSB3aW5lZDNkX2RvX25vdGhpbmc7CiAgICAgICB9CiAgICAgICAvKiBAQCBXaW5lIHJlZ2lzdHJ5IGtleTogSEtDVVxTb2Z0d2FyZVxXaW5lXERpcmVjdDNEICovCiAgICAgICBpZiAoIFJlZ09wZW5LZXlBKCBIS0VZX0NVUlJFTlRfVVNFUiwgIlNvZnR3YXJlXFxXaW5lXFxEaXJlY3QzRCIsICZoa2V5ICkgKSBoa2V5ID0gMDsKCiAgICAgICBsZW4gPSBHZXRNb2R1bGVGaWxlTmFtZUEoIDAsIGJ1ZmZlciwgTUFYX1BBVEggKTsKICAgICAgIGlmIChsZW4gJiYgbGVuIDwgTUFYX1BBVEgpCiAgICAgICB7CiAgICAgICAgICAgIEhLRVkgdG1wa2V5OwogICAgICAgICAgICAvKiBAQCBXaW5lIHJlZ2lzdHJ5IGtleTogSEtDVVxTb2Z0d2FyZVxXaW5lXEFwcERlZmF1bHRzXGFwcC5leGVcRGlyZWN0M0QgKi8KICAgICAgICAgICAgaWYgKCFSZWdPcGVuS2V5QSggSEtFWV9DVVJSRU5UX1VTRVIsICJTb2Z0d2FyZVxcV2luZVxcQXBwRGVmYXVsdHMiLCAmdG1wa2V5ICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNoYXIgKnAsICphcHBuYW1lID0gYnVmZmVyOwogICAgICAgICAgICAgICAgaWYgKChwID0gc3RycmNociggYXBwbmFtZSwgJy8nICkpKSBhcHBuYW1lID0gcCArIDE7CiAgICAgICAgICAgICAgICBpZiAoKHAgPSBzdHJyY2hyKCBhcHBuYW1lLCAnXFwnICkpKSBhcHBuYW1lID0gcCArIDE7CiAgICAgICAgICAgICAgICBzdHJjYXQoIGFwcG5hbWUsICJcXERpcmVjdDNEIiApOwogICAgICAgICAgICAgICAgVFJBQ0UoImFwcG5hbWUgPSBbJXNdXG4iLCBhcHBuYW1lKTsKICAgICAgICAgICAgICAgIGlmIChSZWdPcGVuS2V5QSggdG1wa2V5LCBhcHBuYW1lLCAmYXBwa2V5ICkpIGFwcGtleSA9IDA7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleSggdG1wa2V5ICk7CiAgICAgICAgICAgIH0KICAgICAgIH0KCiAgICAgICBpZiAoIDAgIT0gaGtleSB8fCAwICE9IGFwcGtleSApCiAgICAgICB7CiAgICAgICAgICAgIGlmICggIWdldF9jb25maWdfa2V5KCBoa2V5LCBhcHBrZXksICJWZXJ0ZXhTaGFkZXJNb2RlIiwgYnVmZmVyLCBzaXplKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghc3RyY21wKGJ1ZmZlciwibm9uZSIpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJEaXNhYmxlIHZlcnRleCBzaGFkZXJzXG4iKTsKICAgICAgICAgICAgICAgICAgICB3aW5lZDNkX3NldHRpbmdzLnZzX21vZGUgPSBWU19OT05FOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICggIWdldF9jb25maWdfa2V5KCBoa2V5LCBhcHBrZXksICJQaXhlbFNoYWRlck1vZGUiLCBidWZmZXIsIHNpemUpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFzdHJjbXAoYnVmZmVyLCJlbmFibGVkIikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkFsbG93IHBpeGVsIHNoYWRlcnNcbiIpOwogICAgICAgICAgICAgICAgICAgIHdpbmVkM2Rfc2V0dGluZ3MucHNfbW9kZSA9IFBTX0hXOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFzdHJjbXAoYnVmZmVyLCJkaXNhYmxlZCIpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJEaXNhYmxlIHBpeGVsIHNoYWRlcnNcbiIpOwogICAgICAgICAgICAgICAgICAgIHdpbmVkM2Rfc2V0dGluZ3MucHNfbW9kZSA9IFBTX05PTkU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCAhZ2V0X2NvbmZpZ19rZXkoIGhrZXksIGFwcGtleSwgIlZlcnRleEJ1ZmZlck1vZGUiLCBidWZmZXIsIHNpemUpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFzdHJjbXAoYnVmZmVyLCJub25lIikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkRpc2FibGUgVmVydGV4IEJ1ZmZlciBIYXJkd2FyZSBzdXBwb3J0XG4iKTsKICAgICAgICAgICAgICAgICAgICB3aW5lZDNkX3NldHRpbmdzLnZib19tb2RlID0gVkJPX05PTkU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICghc3RyY21wKGJ1ZmZlciwiaGFyZHdhcmUiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiQWxsb3cgVmVydGV4IEJ1ZmZlciBIYXJkd2FyZSBzdXBwb3J0XG4iKTsKICAgICAgICAgICAgICAgICAgICB3aW5lZDNkX3NldHRpbmdzLnZib19tb2RlID0gVkJPX0hXOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICggIWdldF9jb25maWdfa2V5KCBoa2V5LCBhcHBrZXksICJVc2VHTFNMIiwgYnVmZmVyLCBzaXplKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghc3RyY21wKGJ1ZmZlciwiZGlzYWJsZWQiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiVXNlIG9mIEdMIFNoYWRpbmcgTGFuZ3VhZ2UgZGlzYWJsZWRcbiIpOwogICAgICAgICAgICAgICAgICAgIHdpbmVkM2Rfc2V0dGluZ3MuZ2xzbFJlcXVlc3RlZCA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICggIWdldF9jb25maWdfa2V5KCBoa2V5LCBhcHBrZXksICJPZmZzY3JlZW5SZW5kZXJpbmdNb2RlIiwgYnVmZmVyLCBzaXplKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghc3RyY21wKGJ1ZmZlciwiYmFja2J1ZmZlciIpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJVc2luZyB0aGUgYmFja2J1ZmZlciBmb3Igb2Zmc2NyZWVuIHJlbmRlcmluZ1xuIik7CiAgICAgICAgICAgICAgICAgICAgd2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPSBPUk1fQkFDS0JVRkZFUjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJjbXAoYnVmZmVyLCJwYnVmZmVyIikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlVzaW5nIFBCdWZmZXJzIGZvciBvZmZzY3JlZW4gcmVuZGVyaW5nXG4iKTsKICAgICAgICAgICAgICAgICAgICB3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9IE9STV9QQlVGRkVSOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoIXN0cmNtcChidWZmZXIsImZibyIpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJVc2luZyBGQk9zIGZvciBvZmZzY3JlZW4gcmVuZGVyaW5nXG4iKTsKICAgICAgICAgICAgICAgICAgICB3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9IE9STV9GQk87CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCAhZ2V0X2NvbmZpZ19rZXkoIGhrZXksIGFwcGtleSwgIlJlbmRlclRhcmdldExvY2tNb2RlIiwgYnVmZmVyLCBzaXplKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghc3RyY21wKGJ1ZmZlciwiZGlzYWJsZWQiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiRGlzYWJsaW5nIHJlbmRlciB0YXJnZXQgbG9ja2luZ1xuIik7CiAgICAgICAgICAgICAgICAgICAgd2luZWQzZF9zZXR0aW5ncy5yZW5kZXJ0YXJnZXRsb2NrX21vZGUgPSBSVExfRElTQUJMRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJjbXAoYnVmZmVyLCJyZWFkZHJhdyIpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJVc2luZyBnbFJlYWRQaXhlbHMgZm9yIHJlbmRlciB0YXJnZXQgcmVhZGluZyBhbmQgZ2xEcmF3UGl4ZWxzIGZvciB3cml0aW5nXG4iKTsKICAgICAgICAgICAgICAgICAgICB3aW5lZDNkX3NldHRpbmdzLnJlbmRlcnRhcmdldGxvY2tfbW9kZSA9IFJUTF9SRUFERFJBVzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJjbXAoYnVmZmVyLCJyZWFkdGV4IikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlVzaW5nIGdsUmVhZFBpeGVscyBmb3IgcmVuZGVyIHRhcmdldCByZWFkaW5nIGFuZCB0ZXh0dXJlcyBmb3Igd3JpdGluZ1xuIik7CiAgICAgICAgICAgICAgICAgICAgd2luZWQzZF9zZXR0aW5ncy5yZW5kZXJ0YXJnZXRsb2NrX21vZGUgPSBSVExfUkVBRFRFWDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJjbXAoYnVmZmVyLCJ0ZXhkcmF3IikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlVzaW5nIHRleHR1cmVzIGZvciByZW5kZXIgdGFyZ2V0IHJlYWRpbmcgYW5kIGdsRHJhd1BpeGVscyBmb3Igd3JpdGluZ1xuIik7CiAgICAgICAgICAgICAgICAgICAgd2luZWQzZF9zZXR0aW5ncy5yZW5kZXJ0YXJnZXRsb2NrX21vZGUgPSBSVExfVEVYRFJBVzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJjbXAoYnVmZmVyLCJ0ZXh0ZXgiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiUmVhZGluZyByZW5kZXIgdGFyZ2V0cyB2aWEgdGV4dHVyZXMgYW5kIHdyaXRpbmcgdmlhIHRleHR1cmVzXG4iKTsKICAgICAgICAgICAgICAgICAgICB3aW5lZDNkX3NldHRpbmdzLnJlbmRlcnRhcmdldGxvY2tfbW9kZSA9IFJUTF9URVhURVg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCAhZ2V0X2NvbmZpZ19rZXkoIGhrZXksIGFwcGtleSwgIlZpZGVvTWVtb3J5U2l6ZSIsIGJ1ZmZlciwgc2l6ZSkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgVG1wVmlkZW9NZW1vcnlTaXplID0gYXRvaShidWZmZXIpOwogICAgICAgICAgICAgICAgaWYoVG1wVmlkZW9NZW1vcnlTaXplID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB3aW5lZDNkX3NldHRpbmdzLmVtdWxhdGVkX3RleHR1cmVyYW0gPSBUbXBWaWRlb01lbW9yeVNpemUgKjEwMjQqMTAyNDsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiVXNlICVpTUIgPSAlZCBieXRlIGZvciBlbXVsYXRlZF90ZXh0dXJlcmFtXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVG1wVmlkZW9NZW1vcnlTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZWQzZF9zZXR0aW5ncy5lbXVsYXRlZF90ZXh0dXJlcmFtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBFUlIoIlZpZGVvTWVtb3J5U2l6ZSBpcyAlaSBidXQgbXVzdCBiZSA+MFxuIiwgVG1wVmlkZW9NZW1vcnlTaXplKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoICFnZXRfY29uZmlnX2tleSggaGtleSwgYXBwa2V5LCAiV2luZUxvZ28iLCBidWZmZXIsIHNpemUpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgd2luZWQzZF9zZXR0aW5ncy5sb2dvID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihidWZmZXIpICsgMSk7CiAgICAgICAgICAgICAgICBpZih3aW5lZDNkX3NldHRpbmdzLmxvZ28pIHN0cmNweSh3aW5lZDNkX3NldHRpbmdzLmxvZ28sIGJ1ZmZlcik7CiAgICAgICAgICAgIH0KICAgICAgIH0KICAgICAgIGlmICh3aW5lZDNkX3NldHRpbmdzLnZzX21vZGUgPT0gVlNfSFcpCiAgICAgICAgICAgVFJBQ0UoIkFsbG93IEhXIHZlcnRleCBzaGFkZXJzXG4iKTsKICAgICAgIGlmICh3aW5lZDNkX3NldHRpbmdzLnBzX21vZGUgPT0gUFNfTk9ORSkKICAgICAgICAgICBUUkFDRSgiRGlzYWJsZSBwaXhlbCBzaGFkZXJzXG4iKTsKICAgICAgIGlmICh3aW5lZDNkX3NldHRpbmdzLnZib19tb2RlID09IFZCT19OT05FKQogICAgICAgICAgIFRSQUNFKCJEaXNhYmxlIFZlcnRleCBCdWZmZXIgSGFyZHdhcmUgc3VwcG9ydFxuIik7CiAgICAgICBpZiAod2luZWQzZF9zZXR0aW5ncy5nbHNsUmVxdWVzdGVkKQogICAgICAgICAgIFRSQUNFKCJJZiBzdXBwb3J0ZWQgYnkgeW91ciBzeXN0ZW0sIEdMIFNoYWRpbmcgTGFuZ3VhZ2Ugd2lsbCBiZSB1c2VkXG4iKTsKCiAgICAgICBpZiAoYXBwa2V5KSBSZWdDbG9zZUtleSggYXBwa2V5ICk7CiAgICAgICBpZiAoaGtleSkgUmVnQ2xvc2VLZXkoIGhrZXkgKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9Cg==