LyoKICoJT0xFMzIgcHJveHkvc3R1YiBoYW5kbGVyCiAqCiAqICBDb3B5cmlnaHQgMjAwMiAgTWFyY3VzIE1laXNzbmVyCiAqICBDb3B5cmlnaHQgMjAwMSAgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KI2RlZmluZSBOT05BTUVMRVNTU1RSVUNUCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJvYmpiYXNlLmgiCiNpbmNsdWRlICJvbGUyLmgiCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3dHlwZXMuaCIKCiNpbmNsdWRlICJjb21wb2JqX3ByaXZhdGUuaCIKI2luY2x1ZGUgIm1vbmlrZXIuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKc3RhdGljIFVMT05HIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpOwoKLyogRnJvbSBtc2RuOgogKgogKiBUaGUgZmlyc3QgdGltZSBhIGNsaWVudCByZXF1ZXN0cyBhIHBvaW50ZXIgdG8gYW4gaW50ZXJmYWNlIG9uIGEKICogcGFydGljdWxhciBvYmplY3QsIENPTSBsb2FkcyBhbiBJQ2xhc3NGYWN0b3J5IHN0dWIgaW4gdGhlIHNlcnZlcgogKiBwcm9jZXNzIGFuZCB1c2VzIGl0IHRvIG1hcnNoYWwgdGhlIGZpcnN0IHBvaW50ZXIgYmFjayB0byB0aGUKICogY2xpZW50LiBJbiB0aGUgY2xpZW50IHByb2Nlc3MsIENPTSBsb2FkcyB0aGUgZ2VuZXJpYyBwcm94eSBmb3IgdGhlCiAqIGNsYXNzIGZhY3Rvcnkgb2JqZWN0IGFuZCBjYWxscyBpdHMgaW1wbGVtZW50YXRpb24gb2YgSU1hcnNoYWwgdG8KICogdW5tYXJzaGFsIHRoYXQgZmlyc3QgcG9pbnRlci4gQ09NIHRoZW4gY3JlYXRlcyB0aGUgZmlyc3QgaW50ZXJmYWNlCiAqIHByb3h5IGFuZCBoYW5kcyBpdCBhIHBvaW50ZXIgdG8gdGhlIFJQQyBjaGFubmVsLiBGaW5hbGx5LCBDT00gcmV0dXJucwogKiB0aGUgSUNsYXNzRmFjdG9yeSBwb2ludGVyIHRvIHRoZSBjbGllbnQsIHdoaWNoIHVzZXMgaXQgdG8gY2FsbAogKiBJQ2xhc3NGYWN0b3J5OjpDcmVhdGVJbnN0YW5jZSwgcGFzc2luZyBpdCBhIHJlZmVyZW5jZSB0byB0aGUgaW50ZXJmYWNlLgogKgogKiBCYWNrIGluIHRoZSBzZXJ2ZXIgcHJvY2VzcywgQ09NIG5vdyBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZQogKiBvYmplY3QsIGFsb25nIHdpdGggYSBzdHViIGZvciB0aGUgcmVxdWVzdGVkIGludGVyZmFjZS4gVGhpcyBzdHViIG1hcnNoYWxzCiAqIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBiYWNrIHRvIHRoZSBjbGllbnQgcHJvY2Vzcywgd2hlcmUgYW5vdGhlciBvYmplY3QKICogcHJveHkgaXMgY3JlYXRlZCwgdGhpcyB0aW1lIGZvciB0aGUgb2JqZWN0IGl0c2VsZi4gQWxzbyBjcmVhdGVkIGlzIGEKICogcHJveHkgZm9yIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlLCBhIHBvaW50ZXIgdG8gd2hpY2ggaXMgcmV0dXJuZWQgdG8KICogdGhlIGNsaWVudC4gV2l0aCBzdWJzZXF1ZW50IGNhbGxzIHRvIG90aGVyIGludGVyZmFjZXMgb24gdGhlIG9iamVjdCwKICogQ09NIHdpbGwgbG9hZCB0aGUgYXBwcm9wcmlhdGUgaW50ZXJmYWNlIHN0dWJzIGFuZCBwcm94aWVzIGFzIG5lZWRlZC4KICovCnR5cGVkZWYgc3RydWN0IF9DRlN0dWIgewogICAgY29uc3QgSVJwY1N0dWJCdWZmZXJWdGJsICAgKmxwdnRibDsKICAgIExPTkcJCQlyZWY7CgogICAgTFBVTktOT1dOCQkJcFVua1NlcnZlcjsKfSBDRlN0dWI7CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKQ0ZTdHViX1F1ZXJ5SW50ZXJmYWNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KSB7CiAgICBpZiAoSXNFcXVhbElJRCgmSUlEX0lVbmtub3duLHJpaWQpfHxJc0VxdWFsSUlEKCZJSURfSVJwY1N0dWJCdWZmZXIscmlpZCkpIHsKCSpwcHYgPSAoTFBWT0lEKWlmYWNlOwoJSVVua25vd25fQWRkUmVmKGlmYWNlKTsKCXJldHVybiBTX09LOwogICAgfQogICAgRklYTUUoIiglcyksIGludGVyZmFjZSBub3Qgc3VwcG9ydGVkLlxuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCkNGU3R1Yl9BZGRSZWYoTFBSUENTVFVCQlVGRkVSIGlmYWNlKSB7CiAgICBDRlN0dWIgKlRoaXMgPSAoQ0ZTdHViICopaWZhY2U7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKQ0ZTdHViX1JlbGVhc2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlKSB7CiAgICBDRlN0dWIgKlRoaXMgPSAoQ0ZTdHViICopaWZhY2U7CiAgICBVTE9ORyByZWY7CgogICAgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CiAgICBpZiAoIXJlZikgewogICAgICAgIElScGNTdHViQnVmZmVyX0Rpc2Nvbm5lY3QoaWZhY2UpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKICAgIH0KICAgIHJldHVybiByZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpDRlN0dWJfQ29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsIElVbmtub3duICpwVW5rU2VydmVyKSB7CiAgICBDRlN0dWIgKlRoaXMgPSAoQ0ZTdHViICopaWZhY2U7CgogICAgVGhpcy0+cFVua1NlcnZlciA9IHBVbmtTZXJ2ZXI7CiAgICBJVW5rbm93bl9BZGRSZWYocFVua1NlcnZlcik7CiAgICByZXR1cm4gU19PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJCkNGU3R1Yl9EaXNjb25uZWN0KExQUlBDU1RVQkJVRkZFUiBpZmFjZSkgewogICAgQ0ZTdHViICpUaGlzID0gKENGU3R1YiAqKWlmYWNlOwoKICAgIGlmIChUaGlzLT5wVW5rU2VydmVyKSB7CiAgICAgICAgSVVua25vd25fUmVsZWFzZShUaGlzLT5wVW5rU2VydmVyKTsKICAgICAgICBUaGlzLT5wVW5rU2VydmVyID0gTlVMTDsKICAgIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCkNGU3R1Yl9JbnZva2UoCiAgICBMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsUlBDT0xFTUVTU0FHRSogbXNnLElScGNDaGFubmVsQnVmZmVyKiBjaGFuYnVmCikgewogICAgQ0ZTdHViICpUaGlzID0gKENGU3R1YiAqKWlmYWNlOwogICAgSFJFU1VMVCBocmVzOwoKICAgIGlmIChtc2ctPmlNZXRob2QgPT0gMykgeyAvKiBDcmVhdGVJbnN0YW5jZSAqLwoJSUlEIGlpZDsKCUlDbGFzc0ZhY3RvcnkJKmNsYXNzZmFjOwoJSVVua25vd24JKnBwdjsKCUlTdHJlYW0JCSpwU3RtOwoJU1RBVFNURwkJc3RzdGc7CglVTEFSR0VfSU5URUdFUgluZXdwb3M7CglMQVJHRV9JTlRFR0VSCXNlZWt0bzsKCVVMT05HCQlyZXM7CgoJaWYgKG1zZy0+Y2JCdWZmZXIgPCBzaXplb2YoSUlEKSkgewogICAgICAgICAgICBGSVhNRSgiTm90IGVub3VnaCBieXRlcyBpbiBidWZmZXIgKCVkKT9cbiIsbXNnLT5jYkJ1ZmZlcik7CgkgICAgcmV0dXJuIEVfRkFJTDsKCX0KCW1lbWNweSgmaWlkLG1zZy0+QnVmZmVyLHNpemVvZihpaWQpKTsKCVRSQUNFKCItPkNyZWF0ZUluc3RhbmNlKCVzKVxuIixkZWJ1Z3N0cl9ndWlkKCZpaWQpKTsKCWhyZXMgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShUaGlzLT5wVW5rU2VydmVyLCZJSURfSUNsYXNzRmFjdG9yeSwoTFBWT0lEKikmY2xhc3NmYWMpOwoJaWYgKGhyZXMpIHsKCSAgICBGSVhNRSgiT2xlIHNlcnZlciBkb2VzIG5vdCBwcm92aWRlIGFuIElDbGFzc0ZhY3Rvcnk/XG4iKTsKCSAgICByZXR1cm4gaHJlczsKCX0KCWhyZXMgPSBJQ2xhc3NGYWN0b3J5X0NyZWF0ZUluc3RhbmNlKGNsYXNzZmFjLE5VTEwsJmlpZCwoTFBWT0lEKikmcHB2KTsKCUlDbGFzc0ZhY3RvcnlfUmVsZWFzZShjbGFzc2ZhYyk7Cgltc2ctPmNiQnVmZmVyID0gMDsKCWlmIChocmVzKSB7CgkgICAgRklYTUUoIkZhaWxlZCB0byBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgJXNcbiIsZGVidWdzdHJfZ3VpZCgmaWlkKSk7CgkgICAgZ290byBnZXRidWZmZXI7Cgl9CglocmVzID0gQ3JlYXRlU3RyZWFtT25IR2xvYmFsKDAsVFJVRSwmcFN0bSk7CglpZiAoaHJlcykgewoJICAgIEZJWE1FKCJGYWlsZWQgdG8gY3JlYXRlIHN0cmVhbSBvbiBoZ2xvYmFsXG4iKTsKCSAgICBnb3RvIGdldGJ1ZmZlcjsKCX0KCWhyZXMgPSBJU3RyZWFtX1dyaXRlKHBTdG0sICZwcHYsIHNpemVvZihwcHYpLCBOVUxMKTsKCWlmIChocmVzKSB7CgkgICBFUlIoIklTdHJlYW1fV3JpdGUgZmFpbGVkLCAweCUwOHhcbiIsIGhyZXMpOwoJICAgZ290byBnZXRidWZmZXI7Cgl9CglpZiAocHB2KSB7CiAgICAgICAgaHJlcyA9IENvTWFyc2hhbEludGVyZmFjZShwU3RtLCZpaWQscHB2LDAsTlVMTCwwKTsKICAgICAgICBJVW5rbm93bl9SZWxlYXNlKHBwdik7CiAgICAgICAgaWYgKGhyZXMpIHsKICAgICAgICAgICAgRklYTUUoIkNvTWFyc2hhbEludGVyZmFjZSBmYWlsZWQsICV4IVxuIixocmVzKTsKICAgICAgICAgICAgZ290byBnZXRidWZmZXI7CiAgICAgICAgfQogICAgfQoJaHJlcyA9IElTdHJlYW1fU3RhdChwU3RtLCZzdHN0ZywwKTsKCWlmIChocmVzKSB7CgkgICAgRklYTUUoIlN0YXQgZmFpbGVkLlxuIik7CgkgICAgZ290byBnZXRidWZmZXI7Cgl9CgoJbXNnLT5jYkJ1ZmZlciA9IHN0c3RnLmNiU2l6ZS51Lkxvd1BhcnQ7CgpnZXRidWZmZXI6CiAgICAgICAgSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKGNoYW5idWYsIG1zZywgJklJRF9JQ2xhc3NGYWN0b3J5KTsKICAgICAgICBpZiAoaHJlcykgcmV0dXJuIGhyZXM7CgoJc2Vla3RvLnUuTG93UGFydCA9IDA7c2Vla3RvLnUuSGlnaFBhcnQgPSAwOwoJaHJlcyA9IElTdHJlYW1fU2VlayhwU3RtLHNlZWt0byxTVFJFQU1fU0VFS19TRVQsJm5ld3Bvcyk7CglpZiAoaHJlcykgewogICAgICAgICAgICBGSVhNRSgiSVN0cmVhbV9TZWVrIGZhaWxlZCwgJXhcbiIsaHJlcyk7CgkgICAgcmV0dXJuIGhyZXM7Cgl9CglocmVzID0gSVN0cmVhbV9SZWFkKHBTdG0sbXNnLT5CdWZmZXIsbXNnLT5jYkJ1ZmZlciwmcmVzKTsKCWlmIChocmVzKSB7CiAgICAgICAgICAgIEZJWE1FKCJTdHJlYW0gUmVhZCBmYWlsZWQsICV4XG4iLGhyZXMpOwoJICAgIHJldHVybiBocmVzOwoJfQoJSVN0cmVhbV9SZWxlYXNlKHBTdG0pOwoJcmV0dXJuIFNfT0s7CiAgICB9CiAgICBGSVhNRSgiKCVwLCVwKSwgc3R1YiFcbiIsbXNnLGNoYW5idWYpOwogICAgRklYTUUoImlNZXRob2QgaXMgJWRcbiIsbXNnLT5pTWV0aG9kKTsKICAgIEZJWE1FKCJjYkJ1ZmZlciBpcyAlZFxuIixtc2ctPmNiQnVmZmVyKTsKICAgIHJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBMUFJQQ1NUVUJCVUZGRVIgV0lOQVBJCkNGU3R1Yl9Jc0lJRFN1cHBvcnRlZChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsUkVGSUlEIHJpaWQpIHsKICAgIEZJWE1FKCIoJXMpLCBzdHViIVxuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBOVUxMOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCkNGU3R1Yl9Db3VudFJlZnMoTFBSUENTVFVCQlVGRkVSIGlmYWNlKSB7CiAgICBGSVhNRSgiKCksIHN0dWIhXG4iKTsKICAgIHJldHVybiAxOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKQ0ZTdHViX0RlYnVnU2VydmVyUXVlcnlJbnRlcmZhY2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLHZvaWQqKiBwcHYpIHsKICAgIEZJWE1FKCIoJXApLCBzdHViIVxuIixwcHYpOwogICAgcmV0dXJuIEVfRkFJTDsKfQpzdGF0aWMgdm9pZCAgICBXSU5BUEkKQ0ZTdHViX0RlYnVnU2VydmVyUmVsZWFzZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2Usdm9pZCAqcHYpIHsKICAgIEZJWE1FKCIoJXApLCBzdHViIVxuIixwdik7Cn0KCnN0YXRpYyBjb25zdCBJUnBjU3R1YkJ1ZmZlclZ0YmwgY2ZzdHVidnQgPSB7CiAgICBDRlN0dWJfUXVlcnlJbnRlcmZhY2UsCiAgICBDRlN0dWJfQWRkUmVmLAogICAgQ0ZTdHViX1JlbGVhc2UsCiAgICBDRlN0dWJfQ29ubmVjdCwKICAgIENGU3R1Yl9EaXNjb25uZWN0LAogICAgQ0ZTdHViX0ludm9rZSwKICAgIENGU3R1Yl9Jc0lJRFN1cHBvcnRlZCwKICAgIENGU3R1Yl9Db3VudFJlZnMsCiAgICBDRlN0dWJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZSwKICAgIENGU3R1Yl9EZWJ1Z1NlcnZlclJlbGVhc2UKfTsKCnN0YXRpYyBIUkVTVUxUCkNGU3R1Yl9Db25zdHJ1Y3QoTFBSUENTVFVCQlVGRkVSICpwcHYpIHsKICAgIENGU3R1YiAqY2ZzdHViOwogICAgY2ZzdHViID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoQ0ZTdHViKSk7CiAgICBpZiAoIWNmc3R1YikKCXJldHVybiBFX09VVE9GTUVNT1JZOwogICAgKnBwdiA9IChMUFJQQ1NUVUJCVUZGRVIpY2ZzdHViOwogICAgY2ZzdHViLT5scHZ0YmwJPSAmY2ZzdHVidnQ7CiAgICBjZnN0dWItPnJlZgkJPSAxOwogICAgcmV0dXJuIFNfT0s7Cn0KCi8qIFNpbmNlIHdlIGNyZWF0ZSBwcm94eSBidWZmZXJzIGFuZCBjbGFzc2ZhY3RvcnkgaW4gYSBwYWlyLCB0aGVyZSBpcwogKiBubyBuZWVkIGZvciAyIHNlcGFyYXRlIHN0cnVjdHMuIEp1c3QgcHV0IHRoZW0gaW4gb25lLCBidXQgcmVtZW1iZXIKICogdGhlIHJlZmNvdW50LgogKi8KdHlwZWRlZiBzdHJ1Y3QgX0NGUHJveHkgewogICAgY29uc3QgSUNsYXNzRmFjdG9yeVZ0YmwJCSpscHZ0YmxfY2Y7CiAgICBjb25zdCBJUnBjUHJveHlCdWZmZXJWdGJsCSpscHZ0YmxfcHJveHk7CiAgICBMT05HCQkJCXJlZjsKCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcgkJCSpjaGFuYnVmOwogICAgSVVua25vd24gKm91dGVyX3Vua25vd247Cn0gQ0ZQcm94eTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUnBjUHJveHlCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UsUkVGSUlEIHJpaWQsTFBWT0lEICpwcHYpIHsKICAgICpwcHYgPSBOVUxMOwogICAgaWYgKElzRXF1YWxJSUQocmlpZCwmSUlEX0lScGNQcm94eUJ1ZmZlcil8fElzRXF1YWxJSUQocmlpZCwmSUlEX0lVbmtub3duKSkgewoJSVJwY1Byb3h5QnVmZmVyX0FkZFJlZihpZmFjZSk7CgkqcHB2ID0gKExQVk9JRClpZmFjZTsKCXJldHVybiBTX09LOwogICAgfQogICAgRklYTUUoIiglcyksIG5vIGludGVyZmFjZS5cbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJUnBjUHJveHlCdWZmZXJJbXBsX0FkZFJlZihMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwogICAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElScGNQcm94eUJ1ZmZlckltcGxfUmVsZWFzZShMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgaWYgKCFyZWYpIHsKICAgICAgICBJUnBjUHJveHlCdWZmZXJfRGlzY29ubmVjdChpZmFjZSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwogICAgfQogICAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElScGNQcm94eUJ1ZmZlckltcGxfQ29ubmVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlLElScGNDaGFubmVsQnVmZmVyKiBwUnBjQ2hhbm5lbEJ1ZmZlcikgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX3Byb3h5LGlmYWNlKTsKCiAgICBUaGlzLT5jaGFuYnVmID0gcFJwY0NoYW5uZWxCdWZmZXI7CiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9BZGRSZWYoVGhpcy0+Y2hhbmJ1Zik7CiAgICByZXR1cm4gU19PSzsKfQpzdGF0aWMgdm9pZCBXSU5BUEkgSVJwY1Byb3h5QnVmZmVySW1wbF9EaXNjb25uZWN0KExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CiAgICBpZiAoVGhpcy0+Y2hhbmJ1ZikgewoJSVJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZShUaGlzLT5jaGFuYnVmKTsKCVRoaXMtPmNoYW5idWYgPSBOVUxMOwogICAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKQ0ZQcm94eV9RdWVyeUludGVyZmFjZShMUENMQVNTRkFDVE9SWSBpZmFjZSxSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9jZixpZmFjZSk7CiAgICBpZiAoVGhpcy0+b3V0ZXJfdW5rbm93bikgcmV0dXJuIElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKFRoaXMtPm91dGVyX3Vua25vd24sIHJpaWQsIHBwdik7CiAgICAqcHB2ID0gTlVMTDsKICAgIGlmIChJc0VxdWFsSUlEKCZJSURfSUNsYXNzRmFjdG9yeSxyaWlkKSB8fCBJc0VxdWFsSUlEKCZJSURfSVVua25vd24scmlpZCkpIHsKCSpwcHYgPSAoTFBWT0lEKWlmYWNlOwoJSUNsYXNzRmFjdG9yeV9BZGRSZWYoaWZhY2UpOwoJcmV0dXJuIFNfT0s7CiAgICB9CiAgICBpZiAoSXNFcXVhbElJRChyaWlkLCZJSURfSU1hcnNoYWwpKSAvKiBqdXN0IHRvIGF2b2lkIGRlYnVnIG91dHB1dCAqLwoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CiAgICBGSVhNRSgiVW5oYW5kbGVkIGludGVyZmFjZTogJXNcbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIENGUHJveHlfQWRkUmVmKExQQ0xBU1NGQUNUT1JZIGlmYWNlKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfY2YsaWZhY2UpOwogICAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pIHJldHVybiBJVW5rbm93bl9BZGRSZWYoVGhpcy0+b3V0ZXJfdW5rbm93bik7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBDRlByb3h5X1JlbGVhc2UoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9jZixpZmFjZSk7CiAgICBpZiAoVGhpcy0+b3V0ZXJfdW5rbm93bikKICAgICAgICByZXR1cm4gSVVua25vd25fUmVsZWFzZShUaGlzLT5vdXRlcl91bmtub3duKTsKICAgIGVsc2UKICAgICAgICByZXR1cm4gSVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlKChJUnBjUHJveHlCdWZmZXIgKikmVGhpcy0+bHB2dGJsX3Byb3h5KTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENGUHJveHlfQ3JlYXRlSW5zdGFuY2UoCiAgICBMUENMQVNTRkFDVE9SWSBpZmFjZSwKICAgIExQVU5LTk9XTiBwVW5rT3V0ZXIsLyogW2luXSAqLwogICAgUkVGSUlEIHJpaWQsCS8qIFtpbl0gKi8KICAgIExQVk9JRCAqcHB2CQkvKiBbb3V0XSAqLwopIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9jZixpZmFjZSk7CiAgICBIUkVTVUxUCQlocmVzOwogICAgTFBTVFJFQU0JCXBTdHJlYW07CiAgICBIR0xPQkFMCQloR2xvYmFsOwogICAgVUxPTkcJCXNyc3RhdHVzOwogICAgUlBDT0xFTUVTU0FHRQltc2c7CgogICAgVFJBQ0UoIiglcCwlcywlcClcbiIscFVua091dGVyLGRlYnVnc3RyX2d1aWQocmlpZCkscHB2KTsKCiAgICAvKiBTZW5kIENyZWF0ZUluc3RhbmNlIHRvIHRoZSByZW1vdGUgY2xhc3NmYWN0b3J5LgogICAgICoKICAgICAqIERhdGE6IE9ubHkgdGhlICdJSUQnLgogICAgICovCiAgICBtZW1zZXQoJm1zZywgMCwgc2l6ZW9mKG1zZykpOwogICAgbXNnLmlNZXRob2QgID0gMzsKICAgIG1zZy5jYkJ1ZmZlciA9IHNpemVvZigqcmlpZCk7CiAgICBocmVzID0gSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKFRoaXMtPmNoYW5idWYsJm1zZywmSUlEX0lDbGFzc0ZhY3RvcnkpOwogICAgaWYgKGhyZXMpIHsKCUZJWE1FKCJJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIgZmFpbGVkIHdpdGggJXg/XG4iLGhyZXMpOwoJcmV0dXJuIGhyZXM7CiAgICB9CiAgICBtZW1jcHkobXNnLkJ1ZmZlcixyaWlkLHNpemVvZigqcmlpZCkpOwogICAgaHJlcyA9IElScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlKFRoaXMtPmNoYW5idWYsJm1zZywmc3JzdGF0dXMpOwogICAgaWYgKGhyZXMpIHsKCUZJWE1FKCJJUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZSBmYWlsZWQgd2l0aCAleD9cbiIsaHJlcyk7CglJUnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyKFRoaXMtPmNoYW5idWYsJm1zZyk7CglyZXR1cm4gaHJlczsKICAgIH0KCiAgICBpZiAoIW1zZy5jYkJ1ZmZlcikgeyAvKiBpbnRlcmZhY2Ugbm90IGZvdW5kIG9uIHJlbW90ZSAqLwoJSVJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihUaGlzLT5jaGFuYnVmLCZtc2cpOwoJcmV0dXJuIHNyc3RhdHVzOwogICAgfQoKICAgIC8qIFdlIGdvdCBiYWNrOiBbTWFyc2hhbGxlZCBJbnRlcmZhY2UgZGF0YV0gKi8KICAgIFRSQUNFKCJnb3QgJWQgYnl0ZXMgZGF0YS5cbiIsbXNnLmNiQnVmZmVyKTsKICAgIGhHbG9iYWwgPSBHbG9iYWxBbGxvYyhHTUVNX01PVkVBQkxFfEdNRU1fTk9ESVNDQVJEfEdNRU1fU0hBUkUsbXNnLmNiQnVmZmVyKTsKICAgIG1lbWNweShHbG9iYWxMb2NrKGhHbG9iYWwpLG1zZy5CdWZmZXIsbXNnLmNiQnVmZmVyKTsKICAgIGhyZXMgPSBDcmVhdGVTdHJlYW1PbkhHbG9iYWwoaEdsb2JhbCxUUlVFLCZwU3RyZWFtKTsKICAgIGlmIChocmVzICE9IFNfT0spIHsKCUZJWE1FKCJDcmVhdGVTdHJlYW1PbkhHbG9iYWwgZmFpbGVkIHdpdGggJXhcbiIsaHJlcyk7CglJUnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyKFRoaXMtPmNoYW5idWYsJm1zZyk7CiAgICAgICAgR2xvYmFsRnJlZShoR2xvYmFsKTsKCXJldHVybiBocmVzOwogICAgfQogICAgaHJlcyA9IElTdHJlYW1fUmVhZChwU3RyZWFtLCBwcHYsIHNpemVvZigqcHB2KSwgTlVMTCk7CiAgICBpZiAoaHJlcyAhPSBTX09LKQogICAgICAgIGhyZXMgPSBFX0ZBSUw7CiAgICBlbHNlIGlmICgqcHB2KSB7CiAgICAgICAgaHJlcyA9IENvVW5tYXJzaGFsSW50ZXJmYWNlKAoJICAgICAgIHBTdHJlYW0sCgkgICAgICAgcmlpZCwKCSAgICAgICBwcHYKICAgICAgICApOwogICAgfQogICAgSVN0cmVhbV9SZWxlYXNlKHBTdHJlYW0pOyAvKiBEb2VzIEdsb2JhbEZyZWUgaEdsb2JhbCB0b28uICovCgogICAgSVJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihUaGlzLT5jaGFuYnVmLCZtc2cpOwoKICAgIGlmIChocmVzKSB7CglGSVhNRSgiQ29NYXJzaGFsSW50ZXJmYWNlIGZhaWxlZCwgJXhcbiIsaHJlcyk7CglyZXR1cm4gaHJlczsKICAgIH0KICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ0ZQcm94eV9Mb2NrU2VydmVyKExQQ0xBU1NGQUNUT1JZIGlmYWNlLEJPT0wgZkxvY2spIHsKICAgIC8qSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX2NmLGlmYWNlKTsqLwogICAgRklYTUUoIiglZCksIHN0dWIhXG4iLGZMb2NrKTsKICAgIC8qIGJhc2ljYWxseTogd3JpdGUgQk9PTCwgcmVhZCBlbXB0eSAqLwogICAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBjb25zdCBJUnBjUHJveHlCdWZmZXJWdGJsIHBzcGJ2dGJsID0gewogICAgSVJwY1Byb3h5QnVmZmVySW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElScGNQcm94eUJ1ZmZlckltcGxfQWRkUmVmLAogICAgSVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlLAogICAgSVJwY1Byb3h5QnVmZmVySW1wbF9Db25uZWN0LAogICAgSVJwY1Byb3h5QnVmZmVySW1wbF9EaXNjb25uZWN0Cn07CnN0YXRpYyBjb25zdCBJQ2xhc3NGYWN0b3J5VnRibCBjZnByb3h5dnQgPSB7CiAgICBDRlByb3h5X1F1ZXJ5SW50ZXJmYWNlLAogICAgQ0ZQcm94eV9BZGRSZWYsCiAgICBDRlByb3h5X1JlbGVhc2UsCiAgICBDRlByb3h5X0NyZWF0ZUluc3RhbmNlLAogICAgQ0ZQcm94eV9Mb2NrU2VydmVyCn07CgpzdGF0aWMgSFJFU1VMVApDRlByb3h5X0NvbnN0cnVjdChJVW5rbm93biAqcFVua091dGVyLCBMUFZPSUQgKnBwdixMUFZPSUQgKnBwUHJveHkpIHsKICAgIENGUHJveHkgKmNmOwoKICAgIGNmID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoQ0ZQcm94eSkpOwogICAgaWYgKCFjZikKCXJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIGNmLT5scHZ0YmxfY2YJPSAmY2Zwcm94eXZ0OwogICAgY2YtPmxwdnRibF9wcm94eQk9ICZwc3BidnRibDsKICAgIC8qIG9uZSByZWZlcmVuY2UgZm9yIHRoZSBwcm94eSBidWZmZXIgKi8KICAgIGNmLT5yZWYJCT0gMTsKICAgIGNmLT5vdXRlcl91bmtub3duID0gcFVua091dGVyOwogICAgKnBwdgkJPSAmKGNmLT5scHZ0YmxfY2YpOwogICAgKnBwUHJveHkJCT0gJihjZi0+bHB2dGJsX3Byb3h5KTsKICAgIC8qIGFuZCBvbmUgcmVmZXJlbmNlIGZvciB0aGUgb2JqZWN0ICovCiAgICBJVW5rbm93bl9BZGRSZWYoKElVbmtub3duICopKnBwdik7CiAgICByZXR1cm4gU19PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKiogSVJlbVVua25vd24gUHJveHkvU3R1YiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnR5cGVkZWYgc3RydWN0CnsKICAgIGNvbnN0IElScGNTdHViQnVmZmVyVnRibCAqbHBWdGJsOwogICAgTE9ORyByZWZzOwogICAgSVJlbVVua25vd24gKmlmYWNlOwp9IFJlbVVua1N0dWI7CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUmVtVW5rU3R1Yl9RdWVyeUludGVyZmFjZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJICAgICBSRUZJSUQgcmlpZCwKCQkJCQkgICAgIExQVk9JRCAqb2JqKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPlF1ZXJ5SW50ZXJmYWNlKCVzLCVwKVxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCksb2JqKTsKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93bixyaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lScGNTdHViQnVmZmVyLHJpaWQpKSB7CiAgICAqb2JqID0gVGhpczsKICAgIHJldHVybiBTX09LOwogIH0KICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSZW1VbmtTdHViX0FkZFJlZihMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+QWRkUmVmKClcbiIsVGhpcyk7CiAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWZzKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSZW1VbmtTdHViX1JlbGVhc2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVUxPTkcgcmVmczsKICBUUkFDRSgiKCVwKS0+UmVsZWFzZSgpXG4iLFRoaXMpOwogIHJlZnMgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmcyk7CiAgaWYgKCFyZWZzKQogIHsKICAgIElScGNTdHViQnVmZmVyX0Rpc2Nvbm5lY3QoaWZhY2UpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgfQogIHJldHVybiByZWZzOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUmVtVW5rU3R1Yl9Db25uZWN0KExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKCQkJCSAgICAgIExQVU5LTk9XTiBscFVua1NlcnZlcikKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5Db25uZWN0KCVwKVxuIixUaGlzLGxwVW5rU2VydmVyKTsKICBUaGlzLT5pZmFjZSA9IChJUmVtVW5rbm93biopbHBVbmtTZXJ2ZXI7CiAgSVJlbVVua25vd25fQWRkUmVmKFRoaXMtPmlmYWNlKTsKICByZXR1cm4gU19PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIFJlbVVua1N0dWJfRGlzY29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+RGlzY29ubmVjdCgpXG4iLFRoaXMpOwogIElVbmtub3duX1JlbGVhc2UoVGhpcy0+aWZhY2UpOwogIFRoaXMtPmlmYWNlID0gTlVMTDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1N0dWJfSW52b2tlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKCQkJCSAgICAgUFJQQ09MRU1FU1NBR0UgcE1zZywKCQkJCSAgICAgTFBSUENDSEFOTkVMQlVGRkVSIHBDaGFubmVsKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVUxPTkcgaU1ldGhvZCA9IHBNc2ctPmlNZXRob2Q7CiAgTFBCWVRFIGJ1ZiA9IHBNc2ctPkJ1ZmZlcjsKICBIUkVTVUxUIGhyID0gUlBDX0VfSU5WQUxJRE1FVEhPRDsKCiAgVFJBQ0UoIiglcCktPkludm9rZSglcCwlcCkgbWV0aG9kICVkXG4iLCBUaGlzLCBwTXNnLCBwQ2hhbm5lbCwgaU1ldGhvZCk7CiAgc3dpdGNoIChpTWV0aG9kKQogIHsKICBjYXNlIDM6IC8qIFJlbVF1ZXJ5SW50ZXJmYWNlICovCiAgewogICAgSVBJRCBpcGlkOwogICAgVUxPTkcgY1JlZnM7CiAgICBVU0hPUlQgY0lpZHM7CiAgICBJSUQgKmlpZHM7CiAgICBSRU1RSVJFU1VMVCAqcFFJUmVzdWx0cyA9IE5VTEw7CgogICAgLyogaW4gKi8KICAgIG1lbWNweSgmaXBpZCwgYnVmLCBzaXplb2YoaXBpZCkpOwogICAgYnVmICs9IHNpemVvZihpcGlkKTsKICAgIG1lbWNweSgmY1JlZnMsIGJ1Ziwgc2l6ZW9mKGNSZWZzKSk7CiAgICBidWYgKz0gc2l6ZW9mKGNSZWZzKTsKICAgIG1lbWNweSgmY0lpZHMsIGJ1Ziwgc2l6ZW9mKGNJaWRzKSk7CiAgICBidWYgKz0gc2l6ZW9mKGNJaWRzKTsKICAgIGlpZHMgPSAoSUlEICopYnVmOwoKICAgIGhyID0gSVJlbVVua25vd25fUmVtUXVlcnlJbnRlcmZhY2UoVGhpcy0+aWZhY2UsICZpcGlkLCBjUmVmcywgY0lpZHMsIGlpZHMsICZwUUlSZXN1bHRzKTsKCiAgICAvKiBvdXQgKi8KICAgIHBNc2ctPmNiQnVmZmVyID0gY0lpZHMgKiBzaXplb2YoUkVNUUlSRVNVTFQpICsgc2l6ZW9mKEhSRVNVTFQpOwoKICAgIElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihwQ2hhbm5lbCwgcE1zZywgJklJRF9JUmVtVW5rbm93bik7CgogICAgYnVmID0gcE1zZy0+QnVmZmVyOwogICAgKihIUkVTVUxUICopYnVmID0gaHI7CiAgICBidWYgKz0gc2l6ZW9mKEhSRVNVTFQpOwogICAgCiAgICBpZiAoaHIgPT0gU19PSykKICAgICAgLyogRklYTUU6IHBRSVJlc3VsdHMgaXMgYSB1bmlxdWUgcG9pbnRlciBzbyBwUUlSZXN1bHRzIGNhbiBiZSBOVUxMISAqLwogICAgICBtZW1jcHkoYnVmLCBwUUlSZXN1bHRzLCBjSWlkcyAqIHNpemVvZihSRU1RSVJFU1VMVCkpOwoKICAgIENvVGFza01lbUZyZWUocFFJUmVzdWx0cyk7CgogICAgYnJlYWs7CiAgfQogIGNhc2UgNDogLyogUmVtQWRkUmVmICovCiAgewogICAgVVNIT1JUIGNJaWRzOwogICAgUkVNSU5URVJGQUNFUkVGICppcjsKICAgIEhSRVNVTFQgKnBSZXN1bHRzOwoKICAgIC8qIGluICovCiAgICBtZW1jcHkoJmNJaWRzLCBidWYsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIGlyID0gKFJFTUlOVEVSRkFDRVJFRiopYnVmOwogICAgcFJlc3VsdHMgPSBDb1Rhc2tNZW1BbGxvYyhjSWlkcyAqIHNpemVvZihIUkVTVUxUKSk7CiAgICBpZiAoIXBSZXN1bHRzKSByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBociA9IElSZW1Vbmtub3duX1JlbUFkZFJlZihUaGlzLT5pZmFjZSwgY0lpZHMsIGlyLCBwUmVzdWx0cyk7CgogICAgLyogb3V0ICovCiAgICBwTXNnLT5jYkJ1ZmZlciA9IGNJaWRzICogc2l6ZW9mKEhSRVNVTFQpOwoKICAgIElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihwQ2hhbm5lbCwgcE1zZywgJklJRF9JUmVtVW5rbm93bik7CiAgICBpZiAoIWhyKQogICAgewogICAgICAgIGJ1ZiA9IHBNc2ctPkJ1ZmZlcjsKICAgICAgICBtZW1jcHkoYnVmLCBwUmVzdWx0cywgY0lpZHMgKiBzaXplb2YoSFJFU1VMVCkpOwogICAgfQoKICAgIENvVGFza01lbUZyZWUocFJlc3VsdHMpOwoKICAgIGJyZWFrOwogIH0KICBjYXNlIDU6IC8qIFJlbVJlbGVhc2UgKi8KICB7CiAgICBVU0hPUlQgY0lpZHM7CiAgICBSRU1JTlRFUkZBQ0VSRUYgKmlyOwoKICAgIC8qIGluICovCiAgICBtZW1jcHkoJmNJaWRzLCBidWYsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIGlyID0gKFJFTUlOVEVSRkFDRVJFRiopYnVmOwoKICAgIGhyID0gSVJlbVVua25vd25fUmVtUmVsZWFzZShUaGlzLT5pZmFjZSwgY0lpZHMsIGlyKTsKCiAgICAvKiBvdXQgKi8KICAgIHBNc2ctPmNiQnVmZmVyID0gMDsKICAgIElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihwQ2hhbm5lbCwgcE1zZywgJklJRF9JUmVtVW5rbm93bik7CiAgICBicmVhazsKICB9CiAgfQogIHJldHVybiBocjsKfQoKc3RhdGljIExQUlBDU1RVQkJVRkZFUiBXSU5BUEkgUmVtVW5rU3R1Yl9Jc0lJRFN1cHBvcnRlZChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJCSAgICAgUkVGSUlEIHJpaWQpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+SXNJSURTdXBwb3J0ZWQoJXMpXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICByZXR1cm4gSXNFcXVhbEdVSUQoJklJRF9JUmVtVW5rbm93biwgcmlpZCkgPyBpZmFjZSA6IE5VTEw7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUmVtVW5rU3R1Yl9Db3VudFJlZnMoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgRklYTUUoIiglcCktPkNvdW50UmVmcygpXG4iLCBUaGlzKTsKICByZXR1cm4gMTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1N0dWJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJCQlMUFZPSUQgKnBwdikKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIEZJWE1FKCIoJXApLT5EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlKCVwKVxuIixUaGlzLHBwdik7CiAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBSZW1VbmtTdHViX0RlYnVnU2VydmVyUmVsZWFzZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJICAgICAgTFBWT0lEIHB2KQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgRklYTUUoIiglcCktPkRlYnVnU2VydmVyUmVsZWFzZSglcClcbiIsIFRoaXMsIHB2KTsKfQoKc3RhdGljIGNvbnN0IElScGNTdHViQnVmZmVyVnRibCBSZW1VbmtTdHViX1ZUYWJsZSA9CnsKICBSZW1VbmtTdHViX1F1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1N0dWJfQWRkUmVmLAogIFJlbVVua1N0dWJfUmVsZWFzZSwKICBSZW1VbmtTdHViX0Nvbm5lY3QsCiAgUmVtVW5rU3R1Yl9EaXNjb25uZWN0LAogIFJlbVVua1N0dWJfSW52b2tlLAogIFJlbVVua1N0dWJfSXNJSURTdXBwb3J0ZWQsCiAgUmVtVW5rU3R1Yl9Db3VudFJlZnMsCiAgUmVtVW5rU3R1Yl9EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1N0dWJfRGVidWdTZXJ2ZXJSZWxlYXNlCn07CgpzdGF0aWMgSFJFU1VMVCBSZW1VbmtTdHViX0NvbnN0cnVjdChJUnBjU3R1YkJ1ZmZlciAqKnBwU3R1YikKewogICAgUmVtVW5rU3R1YiAqVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKlRoaXMpKTsKICAgIGlmICghVGhpcykgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICBUaGlzLT5scFZ0YmwgPSAmUmVtVW5rU3R1Yl9WVGFibGU7CiAgICBUaGlzLT5yZWZzID0gMTsKICAgIFRoaXMtPmlmYWNlID0gTlVMTDsKICAgICpwcFN0dWIgPSAoSVJwY1N0dWJCdWZmZXIqKVRoaXM7CiAgICByZXR1cm4gU19PSzsKfQoKCnR5cGVkZWYgc3RydWN0IF9SZW1VbmtQcm94eSB7CiAgICBjb25zdCBJUmVtVW5rbm93blZ0YmwJCSpscHZ0YmxfcmVtdW5rOwogICAgY29uc3QgSVJwY1Byb3h5QnVmZmVyVnRibAkqbHB2dGJsX3Byb3h5OwogICAgTE9ORwkJCQlyZWZzOwoKICAgIElScGNDaGFubmVsQnVmZmVyCQkJKmNoYW47CiAgICBJVW5rbm93biAqb3V0ZXJfdW5rbm93bjsKfSBSZW1VbmtQcm94eTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtQcm94eV9RdWVyeUludGVyZmFjZShMUFJFTVVOS05PV04gaWZhY2UsIFJFRklJRCByaWlkLCB2b2lkICoqcHB2KQp7CiAgICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogICAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pCiAgICAgICAgcmV0dXJuIElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKFRoaXMtPm91dGVyX3Vua25vd24sIHJpaWQsIHBwdik7CiAgICBpZiAoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lVbmtub3duKSB8fAogICAgICAgIElzRXF1YWxJSUQocmlpZCwgJklJRF9JUmVtVW5rbm93bikpCiAgICB7CiAgICAgICAgSVJlbVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICAqcHB2ID0gKExQVk9JRClpZmFjZTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJlbVVua1Byb3h5X0FkZFJlZihMUFJFTVVOS05PV04gaWZhY2UpCnsKICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogIFVMT05HIHJlZnM7CgogIFRSQUNFKCIoJXApLT5BZGRSZWYoKVxuIixUaGlzKTsKCiAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pCiAgICAgIHJlZnMgPSBJVW5rbm93bl9BZGRSZWYoVGhpcy0+b3V0ZXJfdW5rbm93bik7CiAgZWxzZQogICAgICByZWZzID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZnMpOwogIHJldHVybiByZWZzOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJlbVVua1Byb3h5X1JlbGVhc2UoTFBSRU1VTktOT1dOIGlmYWNlKQp7CiAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCktPlJlbGVhc2UoKVxuIixUaGlzKTsKICBpZiAoVGhpcy0+b3V0ZXJfdW5rbm93bikKICAgICAgcmV0dXJuIElVbmtub3duX1JlbGVhc2UoVGhpcy0+b3V0ZXJfdW5rbm93bik7CiAgZWxzZQogICAgICByZXR1cm4gSVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlKChJUnBjUHJveHlCdWZmZXIgKikmVGhpcy0+bHB2dGJsX3Byb3h5KTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1Byb3h5X1JlbVF1ZXJ5SW50ZXJmYWNlKExQUkVNVU5LTk9XTiBpZmFjZSwKCQkJCQkJIFJFRklQSUQgcmlwaWQsCgkJCQkJCSBVTE9ORyBjUmVmcywKCQkJCQkJIFVTSE9SVCBjSWlkcywKCQkJCQkJIElJRCogaWlkcywKCQkJCQkJIFJFTVFJUkVTVUxUKiogcHBRSVJlc3VsdHMpCnsKICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogIFJQQ09MRU1FU1NBR0UgbXNnOwogIEhSRVNVTFQgaHIgPSBTX09LOwogIFVMT05HIHN0YXR1czsKCiAgVFJBQ0UoIiglcCktPiglcywlZCwlZCwlcCwlcClcbiIsVGhpcywKCWRlYnVnc3RyX2d1aWQocmlwaWQpLGNSZWZzLGNJaWRzLGlpZHMscHBRSVJlc3VsdHMpOwoKICAqcHBRSVJlc3VsdHMgPSBOVUxMOwogIG1lbXNldCgmbXNnLCAwLCBzaXplb2YobXNnKSk7CiAgbXNnLmlNZXRob2QgPSAzOwogIG1zZy5jYkJ1ZmZlciA9IHNpemVvZihJUElEKSArIHNpemVvZihVTE9ORykgKwogICAgc2l6ZW9mKFVTSE9SVCkgKyBjSWlkcypzaXplb2YoSUlEKTsKICBociA9IElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihUaGlzLT5jaGFuLCAmbXNnLCAmSUlEX0lSZW1Vbmtub3duKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgTFBCWVRFIGJ1ZiA9IG1zZy5CdWZmZXI7CiAgICBtZW1jcHkoYnVmLCByaXBpZCwgc2l6ZW9mKElQSUQpKTsKICAgIGJ1ZiArPSBzaXplb2YoSVBJRCk7CiAgICBtZW1jcHkoYnVmLCAmY1JlZnMsIHNpemVvZihVTE9ORykpOwogICAgYnVmICs9IHNpemVvZihVTE9ORyk7CiAgICBtZW1jcHkoYnVmLCAmY0lpZHMsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIG1lbWNweShidWYsIGlpZHMsIGNJaWRzKnNpemVvZihJSUQpKTsKCiAgICBociA9IElScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlKFRoaXMtPmNoYW4sICZtc2csICZzdGF0dXMpOwoKICAgIGJ1ZiA9IG1zZy5CdWZmZXI7CgogICAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgICAgICBociA9ICooSFJFU1VMVCAqKWJ1ZjsKICAgICAgICBidWYgKz0gc2l6ZW9mKEhSRVNVTFQpOwogICAgfQoKICAgIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICAgICpwcFFJUmVzdWx0cyA9IENvVGFza01lbUFsbG9jKGNJaWRzKnNpemVvZihSRU1RSVJFU1VMVCkpOwogICAgICBtZW1jcHkoKnBwUUlSZXN1bHRzLCBidWYsIGNJaWRzKnNpemVvZihSRU1RSVJFU1VMVCkpOwogICAgfQoKICAgIElScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIoVGhpcy0+Y2hhbiwgJm1zZyk7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtQcm94eV9SZW1BZGRSZWYoTFBSRU1VTktOT1dOIGlmYWNlLAoJCQkJCSBVU0hPUlQgY0ludGVyZmFjZVJlZnMsCgkJCQkJIFJFTUlOVEVSRkFDRVJFRiogSW50ZXJmYWNlUmVmcywKCQkJCQkgSFJFU1VMVCogcFJlc3VsdHMpCnsKICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogIFJQQ09MRU1FU1NBR0UgbXNnOwogIEhSRVNVTFQgaHIgPSBTX09LOwogIFVMT05HIHN0YXR1czsKCiAgVFJBQ0UoIiglcCktPiglZCwlcCwlcClcbiIsVGhpcywKCWNJbnRlcmZhY2VSZWZzLEludGVyZmFjZVJlZnMscFJlc3VsdHMpOwoKICBtZW1zZXQoJm1zZywgMCwgc2l6ZW9mKG1zZykpOwogIG1zZy5pTWV0aG9kID0gNDsKICBtc2cuY2JCdWZmZXIgPSBzaXplb2YoVVNIT1JUKSArIGNJbnRlcmZhY2VSZWZzKnNpemVvZihSRU1JTlRFUkZBQ0VSRUYpOwogIGhyID0gSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKFRoaXMtPmNoYW4sICZtc2csICZJSURfSVJlbVVua25vd24pOwogIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICBMUEJZVEUgYnVmID0gbXNnLkJ1ZmZlcjsKICAgIG1lbWNweShidWYsICZjSW50ZXJmYWNlUmVmcywgc2l6ZW9mKFVTSE9SVCkpOwogICAgYnVmICs9IHNpemVvZihVU0hPUlQpOwogICAgbWVtY3B5KGJ1ZiwgSW50ZXJmYWNlUmVmcywgY0ludGVyZmFjZVJlZnMqc2l6ZW9mKFJFTUlOVEVSRkFDRVJFRikpOwoKICAgIGhyID0gSVJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUoVGhpcy0+Y2hhbiwgJm1zZywgJnN0YXR1cyk7CgogICAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgICAgYnVmID0gbXNnLkJ1ZmZlcjsKICAgICAgbWVtY3B5KHBSZXN1bHRzLCBidWYsIGNJbnRlcmZhY2VSZWZzKnNpemVvZihIUkVTVUxUKSk7CiAgICB9CgogICAgSVJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihUaGlzLT5jaGFuLCAmbXNnKTsKICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1Byb3h5X1JlbVJlbGVhc2UoTFBSRU1VTktOT1dOIGlmYWNlLAoJCQkJCSAgVVNIT1JUIGNJbnRlcmZhY2VSZWZzLAoJCQkJCSAgUkVNSU5URVJGQUNFUkVGKiBJbnRlcmZhY2VSZWZzKQp7CiAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKICBSUENPTEVNRVNTQUdFIG1zZzsKICBIUkVTVUxUIGhyID0gU19PSzsKICBVTE9ORyBzdGF0dXM7CgogIFRSQUNFKCIoJXApLT4oJWQsJXApXG4iLFRoaXMsCgljSW50ZXJmYWNlUmVmcyxJbnRlcmZhY2VSZWZzKTsKCiAgbWVtc2V0KCZtc2csIDAsIHNpemVvZihtc2cpKTsKICBtc2cuaU1ldGhvZCA9IDU7CiAgbXNnLmNiQnVmZmVyID0gc2l6ZW9mKFVTSE9SVCkgKyBjSW50ZXJmYWNlUmVmcypzaXplb2YoUkVNSU5URVJGQUNFUkVGKTsKICBociA9IElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihUaGlzLT5jaGFuLCAmbXNnLCAmSUlEX0lSZW1Vbmtub3duKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgTFBCWVRFIGJ1ZiA9IG1zZy5CdWZmZXI7CiAgICBtZW1jcHkoYnVmLCAmY0ludGVyZmFjZVJlZnMsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIG1lbWNweShidWYsIEludGVyZmFjZVJlZnMsIGNJbnRlcmZhY2VSZWZzKnNpemVvZihSRU1JTlRFUkZBQ0VSRUYpKTsKCiAgICBociA9IElScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlKFRoaXMtPmNoYW4sICZtc2csICZzdGF0dXMpOwoKICAgIElScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIoVGhpcy0+Y2hhbiwgJm1zZyk7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBjb25zdCBJUmVtVW5rbm93blZ0YmwgUmVtVW5rUHJveHlfVlRhYmxlID0KewogIFJlbVVua1Byb3h5X1F1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1Byb3h5X0FkZFJlZiwKICBSZW1VbmtQcm94eV9SZWxlYXNlLAogIFJlbVVua1Byb3h5X1JlbVF1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1Byb3h5X1JlbUFkZFJlZiwKICBSZW1VbmtQcm94eV9SZW1SZWxlYXNlCn07CgoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJVUnBjUHJveHlCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UsUkVGSUlEIHJpaWQsTFBWT0lEICpwcHYpIHsKICAgICpwcHYgPSBOVUxMOwogICAgaWYgKElzRXF1YWxJSUQocmlpZCwmSUlEX0lScGNQcm94eUJ1ZmZlcil8fElzRXF1YWxJSUQocmlpZCwmSUlEX0lVbmtub3duKSkgewoJSVJwY1Byb3h5QnVmZmVyX0FkZFJlZihpZmFjZSk7CgkqcHB2ID0gKExQVk9JRClpZmFjZTsKCXJldHVybiBTX09LOwogICAgfQogICAgRklYTUUoIiglcyksIG5vIGludGVyZmFjZS5cbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9BZGRSZWYoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKFJlbVVua1Byb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CiAgICBUUkFDRSgiJXAsICVkXG4iLCBpZmFjZSwgVGhpcy0+cmVmcyArIDEpOwogICAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWZzKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShSZW1VbmtQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZnMpOwogICAgVFJBQ0UoIiVwLCAlZFxuIiwgaWZhY2UsIHJlZik7CiAgICBpZiAoIXJlZikgewogICAgICAgIElScGNQcm94eUJ1ZmZlcl9EaXNjb25uZWN0KGlmYWNlKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CiAgICB9CiAgICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUlVScGNQcm94eUJ1ZmZlckltcGxfQ29ubmVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlLElScGNDaGFubmVsQnVmZmVyKiBwUnBjQ2hhbm5lbEJ1ZmZlcikgewogICAgSUNPTV9USElTX01VTFRJKFJlbVVua1Byb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CgogICAgVFJBQ0UoIiVwLCAlcFxuIiwgaWZhY2UsIHBScGNDaGFubmVsQnVmZmVyKTsKICAgIFRoaXMtPmNoYW4gPSBwUnBjQ2hhbm5lbEJ1ZmZlcjsKICAgIElScGNDaGFubmVsQnVmZmVyX0FkZFJlZihUaGlzLT5jaGFuKTsKICAgIHJldHVybiBTX09LOwp9CnN0YXRpYyB2b2lkIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9EaXNjb25uZWN0KExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShSZW1VbmtQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwogICAgVFJBQ0UoIiVwLCAlcFxuIiwgaWZhY2UsIFRoaXMtPmNoYW4pOwogICAgaWYgKFRoaXMtPmNoYW4pIHsKCUlScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UoVGhpcy0+Y2hhbik7CglUaGlzLT5jaGFuID0gTlVMTDsKICAgIH0KfQoKCnN0YXRpYyBjb25zdCBJUnBjUHJveHlCdWZmZXJWdGJsIFJVUnBjUHJveHlCdWZmZXJfVlRhYmxlID0gewogICAgUlVScGNQcm94eUJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBSVVJwY1Byb3h5QnVmZmVySW1wbF9BZGRSZWYsCiAgICBSVVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlLAogICAgUlVScGNQcm94eUJ1ZmZlckltcGxfQ29ubmVjdCwKICAgIFJVUnBjUHJveHlCdWZmZXJJbXBsX0Rpc2Nvbm5lY3QKfTsKCnN0YXRpYyBIUkVTVUxUClJlbVVua1Byb3h5X0NvbnN0cnVjdChJVW5rbm93biAqcFVua091dGVyLCBMUFZPSUQgKnBwdixMUFZPSUQgKnBwUHJveHkpIHsKICAgIFJlbVVua1Byb3h5ICpUaGlzOwoKICAgIFRoaXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZigqVGhpcykpOwogICAgaWYgKCFUaGlzKQoJcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgVGhpcy0+bHB2dGJsX3JlbXVuawk9ICZSZW1VbmtQcm94eV9WVGFibGU7CiAgICBUaGlzLT5scHZ0YmxfcHJveHkJPSAmUlVScGNQcm94eUJ1ZmZlcl9WVGFibGU7CiAgICAvKiBvbmx5IG9uZSByZWZlcmVuY2UgZm9yIHRoZSBwcm94eSBidWZmZXIgKi8KICAgIFRoaXMtPnJlZnMJCT0gMTsKICAgIFRoaXMtPm91dGVyX3Vua25vd24gPSBwVW5rT3V0ZXI7CiAgICAqcHB2CQk9ICYoVGhpcy0+bHB2dGJsX3JlbXVuayk7CiAgICAqcHBQcm94eQkJPSAmKFRoaXMtPmxwdnRibF9wcm94eSk7CiAgICAvKiBhbmQgb25lIHJlZmVyZW5jZSBmb3IgdGhlIG9iamVjdCAqLwogICAgSVVua25vd25fQWRkUmVmKChJVW5rbm93biAqKSpwcHYpOwogICAgcmV0dXJuIFNfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqIE9MRSBQcm94eS9TdHViIEZhY3RvcnkgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpQU0ZhY0J1Zl9RdWVyeUludGVyZmFjZShMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSwgUkVGSUlEIGlpZCwgTFBWT0lEICpwcHYpIHsKICAgIGlmIChJc0VxdWFsSUlEKGlpZCwmSUlEX0lQU0ZhY3RvcnlCdWZmZXIpfHxJc0VxdWFsSUlEKGlpZCwmSUlEX0lVbmtub3duKSkgewoJKnBwdiA9IChMUFZPSUQpaWZhY2U7CgkvKiBObyByZWYgY291bnRpbmcsIHN0YXRpYyBjbGFzcyAqLwoJcmV0dXJuIFNfT0s7CiAgICB9CiAgICBGSVhNRSgiKCVzKSB1bmtub3duIElJRD9cbiIsZGVidWdzdHJfZ3VpZChpaWQpKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFBTRmFjQnVmX0FkZFJlZihMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSkgeyByZXR1cm4gMjsgfQpzdGF0aWMgVUxPTkcgV0lOQVBJIFBTRmFjQnVmX1JlbGVhc2UoTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UpIHsgcmV0dXJuIDE7IH0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpQU0ZhY0J1Zl9DcmVhdGVQcm94eSgKICAgIExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlLCBJVW5rbm93biogcFVua091dGVyLCBSRUZJSUQgcmlpZCwKICAgIElScGNQcm94eUJ1ZmZlciAqKnBwUHJveHksIExQVk9JRCAqcHB2CikgewogICAgaWYgKElzRXF1YWxJSUQoJklJRF9JQ2xhc3NGYWN0b3J5LHJpaWQpKQoJcmV0dXJuIENGUHJveHlfQ29uc3RydWN0KHBVbmtPdXRlciwgcHB2LChMUFZPSUQqKXBwUHJveHkpOwogICAgZWxzZSBpZiAoSXNFcXVhbElJRCgmSUlEX0lSZW1Vbmtub3duLHJpaWQpKQoJcmV0dXJuIFJlbVVua1Byb3h5X0NvbnN0cnVjdChwVW5rT3V0ZXIsIHBwdiwoTFBWT0lEKilwcFByb3h5KTsKICAgIEZJWE1FKCJwcm94eWluZyBub3QgaW1wbGVtZW50ZWQgZm9yICglcykgeWV0IVxuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpQU0ZhY0J1Zl9DcmVhdGVTdHViKAogICAgTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UsIFJFRklJRCByaWlkLElVbmtub3duICpwVW5rU2VydmVyLAogICAgSVJwY1N0dWJCdWZmZXIqKiBwcFN0dWIKKSB7CiAgICBIUkVTVUxUIGhyZXM7CgogICAgVFJBQ0UoIiglcywlcCwlcClcbiIsZGVidWdzdHJfZ3VpZChyaWlkKSxwVW5rU2VydmVyLHBwU3R1Yik7CgogICAgaWYgKElzRXF1YWxJSUQoJklJRF9JQ2xhc3NGYWN0b3J5LCByaWlkKSB8fAogICAgICAgIElzRXF1YWxJSUQoJklJRF9JVW5rbm93biwgcmlpZCkgLyogRklYTUU6IGZpeHVwIHN0dWIgbWFuYWdlciBhbmQgcmVtb3ZlIHRoaXMqLykgewoJaHJlcyA9IENGU3R1Yl9Db25zdHJ1Y3QocHBTdHViKTsKCWlmICghaHJlcykKCSAgICBJUnBjU3R1YkJ1ZmZlcl9Db25uZWN0KCgqcHBTdHViKSxwVW5rU2VydmVyKTsKCXJldHVybiBocmVzOwogICAgfSBlbHNlIGlmIChJc0VxdWFsSUlEKCZJSURfSVJlbVVua25vd24scmlpZCkpIHsKCWhyZXMgPSBSZW1VbmtTdHViX0NvbnN0cnVjdChwcFN0dWIpOwoJaWYgKCFocmVzKQoJICAgIElScGNTdHViQnVmZmVyX0Nvbm5lY3QoKCpwcFN0dWIpLHBVbmtTZXJ2ZXIpOwoJcmV0dXJuIGhyZXM7CiAgICB9CiAgICBGSVhNRSgic3R1YmJpbmcgbm90IGltcGxlbWVudGVkIGZvciAoJXMpIHlldCFcbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgY29uc3QgSVBTRmFjdG9yeUJ1ZmZlclZ0YmwgcHNmYWNidWZ2dGJsID0gewogICAgUFNGYWNCdWZfUXVlcnlJbnRlcmZhY2UsCiAgICBQU0ZhY0J1Zl9BZGRSZWYsCiAgICBQU0ZhY0J1Zl9SZWxlYXNlLAogICAgUFNGYWNCdWZfQ3JlYXRlUHJveHksCiAgICBQU0ZhY0J1Zl9DcmVhdGVTdHViCn07CgovKiBUaGlzIGlzIHRoZSB3aG9sZSBQU0ZhY3RvcnlCdWZmZXIgb2JqZWN0LCBqdXN0IHRoZSB2dGFibGVwdHIgKi8Kc3RhdGljIGNvbnN0IElQU0ZhY3RvcnlCdWZmZXJWdGJsICpscHBzZmFjID0gJnBzZmFjYnVmdnRibDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRGxsR2V0Q2xhc3NPYmplY3QgW09MRTMyLkBdCiAqLwpIUkVTVUxUIFdJTkFQSSBEbGxHZXRDbGFzc09iamVjdChSRUZDTFNJRCByY2xzaWQsIFJFRklJRCBpaWQsTFBWT0lEICpwcHYpCnsKICAgICpwcHYgPSBOVUxMOwogICAgaWYgKElzRXF1YWxJSUQocmNsc2lkLCAmQ0xTSURfUFNGYWN0b3J5QnVmZmVyKSkKICAgICAgICByZXR1cm4gSVBTRmFjdG9yeUJ1ZmZlcl9RdWVyeUludGVyZmFjZSgoSVBTRmFjdG9yeUJ1ZmZlciAqKSZscHBzZmFjLCBpaWQsIHBwdik7CiAgICBpZiAoSXNFcXVhbElJRChyY2xzaWQsJkNMU0lEX0RmTWFyc2hhbCkmJigKCQlJc0VxdWFsSUlEKGlpZCwmSUlEX0lDbGFzc0ZhY3RvcnkpIHx8CgkJSXNFcXVhbElJRChpaWQsJklJRF9JVW5rbm93bikKCSkKICAgICkKCXJldHVybiBNQVJTSEFMX0dldFN0YW5kYXJkTWFyc2hhbENGKHBwdik7CiAgICBpZiAoSXNFcXVhbElJRChyY2xzaWQsJkNMU0lEX1N0ZEdsb2JhbEludGVyZmFjZVRhYmxlKSAmJiAoSXNFcXVhbElJRChpaWQsJklJRF9JQ2xhc3NGYWN0b3J5KSB8fCBJc0VxdWFsSUlEKGlpZCwmSUlEX0lVbmtub3duKSkpCiAgICAgICAgcmV0dXJuIFN0ZEdsb2JhbEludGVyZmFjZVRhYmxlX0dldEZhY3RvcnkocHB2KTsKICAgIGlmIChJc0VxdWFsQ0xTSUQocmNsc2lkLCAmQ0xTSURfRmlsZU1vbmlrZXIpKQogICAgICAgIHJldHVybiBGaWxlTW9uaWtlckNGX0NyZWF0ZShpaWQsIHBwdik7CiAgICBpZiAoSXNFcXVhbENMU0lEKHJjbHNpZCwgJkNMU0lEX0l0ZW1Nb25pa2VyKSkKICAgICAgICByZXR1cm4gSXRlbU1vbmlrZXJDRl9DcmVhdGUoaWlkLCBwcHYpOwogICAgaWYgKElzRXF1YWxDTFNJRChyY2xzaWQsICZDTFNJRF9BbnRpTW9uaWtlcikpCiAgICAgICAgcmV0dXJuIEFudGlNb25pa2VyQ0ZfQ3JlYXRlKGlpZCwgcHB2KTsKICAgIGlmIChJc0VxdWFsQ0xTSUQocmNsc2lkLCAmQ0xTSURfQ29tcG9zaXRlTW9uaWtlcikpCiAgICAgICAgcmV0dXJuIENvbXBvc2l0ZU1vbmlrZXJDRl9DcmVhdGUoaWlkLCBwcHYpOwogICAgaWYgKElzRXF1YWxDTFNJRChyY2xzaWQsICZDTFNJRF9DbGFzc01vbmlrZXIpKQogICAgICAgIHJldHVybiBDbGFzc01vbmlrZXJDRl9DcmVhdGUoaWlkLCBwcHYpOwogICAgaWYgKElzRXF1YWxDTFNJRChyY2xzaWQsICZDTFNJRF9Qb2ludGVyTW9uaWtlcikpCiAgICAgICAgcmV0dXJuIFBvaW50ZXJNb25pa2VyQ0ZfQ3JlYXRlKGlpZCwgcHB2KTsKCiAgICBGSVhNRSgiXG5cdENMU0lEOlx0JXMsXG5cdElJRDpcdCVzXG4iLGRlYnVnc3RyX2d1aWQocmNsc2lkKSxkZWJ1Z3N0cl9ndWlkKGlpZCkpOwogICAgcmV0dXJuIENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEU7Cn0K