LyoKICoJT0xFMzIgcHJveHkvc3R1YiBoYW5kbGVyCiAqCiAqICBDb3B5cmlnaHQgMjAwMiAgTWFyY3VzIE1laXNzbmVyCiAqICBDb3B5cmlnaHQgMjAwMSAgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKLyogRG9jdW1lbnRhdGlvbiBvbiBNU0ROOgogKgogKiAoVG9wIGxldmVsIENPTSBkb2N1bWVudGF0aW9uKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2RuYW5jaG9yL2h0bWwvY29tcG9uZW50ZGV2ZWxvcG1lbnRhbmsuYXNwCiAqCiAqIChDT00gUHJveHkpCiAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvY29tL2h0bS9jb21leHRfMXEwcC5hc3AKICoKICogKENPTSBTdHViKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG0vY29tZXh0XzFsaWEuYXNwCiAqCiAqIChNYXJzaGFsKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG0vY29tZXh0XzFnZm4uYXNwCiAqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KI2RlZmluZSBOT05BTUVMRVNTU1RSVUNUCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJvYmpiYXNlLmgiCiNpbmNsdWRlICJvbGUyLmgiCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgInd0eXBlcy5oIgoKI2luY2x1ZGUgImNvbXBvYmpfcHJpdmF0ZS5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7Cgpjb25zdCBDTFNJRCBDTFNJRF9EZk1hcnNoYWwgICAgICAgPSB7IDB4MDAwMDAzMGIsIDAsIDAsIHsweGMwLCAwLCAwLCAwLCAwLCAwLCAwLCAweDQ2fSB9Owpjb25zdCBDTFNJRCBDTFNJRF9QU0ZhY3RvcnlCdWZmZXIgPSB7IDB4MDAwMDAzMjAsIDAsIDAsIHsweGMwLCAwLCAwLCAwLCAwLCAwLCAwLCAweDQ2fSB9OwoKLyogRnJvbTogaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9saWJyYXJ5L2VuLXVzL2NvbS9jbWlfbV80bGRhLmFzcAogKgogKiBUaGUgZmlyc3QgdGltZSBhIGNsaWVudCByZXF1ZXN0cyBhIHBvaW50ZXIgdG8gYW4gaW50ZXJmYWNlIG9uIGEKICogcGFydGljdWxhciBvYmplY3QsIENPTSBsb2FkcyBhbiBJQ2xhc3NGYWN0b3J5IHN0dWIgaW4gdGhlIHNlcnZlcgogKiBwcm9jZXNzIGFuZCB1c2VzIGl0IHRvIG1hcnNoYWwgdGhlIGZpcnN0IHBvaW50ZXIgYmFjayB0byB0aGUKICogY2xpZW50LiBJbiB0aGUgY2xpZW50IHByb2Nlc3MsIENPTSBsb2FkcyB0aGUgZ2VuZXJpYyBwcm94eSBmb3IgdGhlCiAqIGNsYXNzIGZhY3Rvcnkgb2JqZWN0IGFuZCBjYWxscyBpdHMgaW1wbGVtZW50YXRpb24gb2YgSU1hcnNoYWwgdG8KICogdW5tYXJzaGFsIHRoYXQgZmlyc3QgcG9pbnRlci4gQ09NIHRoZW4gY3JlYXRlcyB0aGUgZmlyc3QgaW50ZXJmYWNlCiAqIHByb3h5IGFuZCBoYW5kcyBpdCBhIHBvaW50ZXIgdG8gdGhlIFJQQyBjaGFubmVsLiBGaW5hbGx5LCBDT00gcmV0dXJucwogKiB0aGUgSUNsYXNzRmFjdG9yeSBwb2ludGVyIHRvIHRoZSBjbGllbnQsIHdoaWNoIHVzZXMgaXQgdG8gY2FsbAogKiBJQ2xhc3NGYWN0b3J5OjpDcmVhdGVJbnN0YW5jZSwgcGFzc2luZyBpdCBhIHJlZmVyZW5jZSB0byB0aGUgaW50ZXJmYWNlLgogKgogKiBCYWNrIGluIHRoZSBzZXJ2ZXIgcHJvY2VzcywgQ09NIG5vdyBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZQogKiBvYmplY3QsIGFsb25nIHdpdGggYSBzdHViIGZvciB0aGUgcmVxdWVzdGVkIGludGVyZmFjZS4gVGhpcyBzdHViIG1hcnNoYWxzCiAqIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBiYWNrIHRvIHRoZSBjbGllbnQgcHJvY2Vzcywgd2hlcmUgYW5vdGhlciBvYmplY3QKICogcHJveHkgaXMgY3JlYXRlZCwgdGhpcyB0aW1lIGZvciB0aGUgb2JqZWN0IGl0c2VsZi4gQWxzbyBjcmVhdGVkIGlzIGEKICogcHJveHkgZm9yIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlLCBhIHBvaW50ZXIgdG8gd2hpY2ggaXMgcmV0dXJuZWQgdG8KICogdGhlIGNsaWVudC4gV2l0aCBzdWJzZXF1ZW50IGNhbGxzIHRvIG90aGVyIGludGVyZmFjZXMgb24gdGhlIG9iamVjdCwKICogQ09NIHdpbGwgbG9hZCB0aGUgYXBwcm9wcmlhdGUgaW50ZXJmYWNlIHN0dWJzIGFuZCBwcm94aWVzIGFzIG5lZWRlZC4KICovCnR5cGVkZWYgc3RydWN0IF9DRlN0dWIgewogICAgSVJwY1N0dWJCdWZmZXJWdGJsCSpscHZ0Ymw7CiAgICBEV09SRAkJCXJlZjsKCiAgICBMUFVOS05PV04JCQlwVW5rU2VydmVyOwp9IENGU3R1YjsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpDRlN0dWJfUXVlcnlJbnRlcmZhY2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpIHsKICAgIGlmIChJc0VxdWFsSUlEKCZJSURfSVVua25vd24scmlpZCl8fElzRXF1YWxJSUQoJklJRF9JUnBjU3R1YkJ1ZmZlcixyaWlkKSkgewoJKnBwdiA9IChMUFZPSUQpaWZhY2U7CglJVW5rbm93bl9BZGRSZWYoaWZhY2UpOwoJcmV0dXJuIFNfT0s7CiAgICB9CiAgICBGSVhNRSgiKCVzKSwgaW50ZXJmYWNlIG5vdCBzdXBwb3J0ZWQuXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKQ0ZTdHViX0FkZFJlZihMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpIHsKICAgIENGU3R1YiAqVGhpcyA9IChDRlN0dWIgKilpZmFjZTsKICAgIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpDRlN0dWJfUmVsZWFzZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpIHsKICAgIENGU3R1YiAqVGhpcyA9IChDRlN0dWIgKilpZmFjZTsKICAgIFVMT05HIHJlZjsKCiAgICByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKICAgIGlmICghcmVmKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CiAgICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKQ0ZTdHViX0Nvbm5lY3QoTFBSUENTVFVCQlVGRkVSIGlmYWNlLCBJVW5rbm93biAqcFVua1NlcnZlcikgewogICAgQ0ZTdHViICpUaGlzID0gKENGU3R1YiAqKWlmYWNlOwoKICAgIFRoaXMtPnBVbmtTZXJ2ZXIgPSBwVW5rU2VydmVyOwogICAgSVVua25vd25fQWRkUmVmKHBVbmtTZXJ2ZXIpOwogICAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSQpDRlN0dWJfRGlzY29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpIHsKICAgIENGU3R1YiAqVGhpcyA9IChDRlN0dWIgKilpZmFjZTsKCiAgICBJVW5rbm93bl9SZWxlYXNlKFRoaXMtPnBVbmtTZXJ2ZXIpOwogICAgVGhpcy0+cFVua1NlcnZlciA9IE5VTEw7Cn0Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCkNGU3R1Yl9JbnZva2UoCiAgICBMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsUlBDT0xFTUVTU0FHRSogbXNnLElScGNDaGFubmVsQnVmZmVyKiBjaGFuYnVmCikgewogICAgQ0ZTdHViICpUaGlzID0gKENGU3R1YiAqKWlmYWNlOwogICAgSFJFU1VMVCBocmVzOwoKICAgIGlmIChtc2ctPmlNZXRob2QgPT0gMykgeyAvKiBDcmVhdGVJbnN0YW5jZSAqLwoJSUlEIGlpZDsKCUlDbGFzc0ZhY3RvcnkJKmNsYXNzZmFjOwoJSVVua25vd24JKnBwdjsKCUlTdHJlYW0JCSpwU3RtOwoJU1RBVFNURwkJc3RzdGc7CglVTEFSR0VfSU5URUdFUgluZXdwb3M7CglMQVJHRV9JTlRFR0VSCXNlZWt0bzsKCVVMT05HCQlyZXM7CgoJaWYgKG1zZy0+Y2JCdWZmZXIgPCBzaXplb2YoSUlEKSkgewoJICAgIEZJWE1FKCJOb3QgZW5vdWdoIGJ5dGVzIGluIGJ1ZmZlciAoJWxkIGluc3RlYWQgb2YgJWQpP1xuIixtc2ctPmNiQnVmZmVyLHNpemVvZihJSUQpKTsKCSAgICByZXR1cm4gRV9GQUlMOwoJfQoJbWVtY3B5KCZpaWQsbXNnLT5CdWZmZXIsc2l6ZW9mKGlpZCkpOwoJVFJBQ0UoIi0+Q3JlYXRlSW5zdGFuY2UoJXMpXG4iLGRlYnVnc3RyX2d1aWQoJmlpZCkpOwoJaHJlcyA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKFRoaXMtPnBVbmtTZXJ2ZXIsJklJRF9JQ2xhc3NGYWN0b3J5LChMUFZPSUQqKSZjbGFzc2ZhYyk7CglpZiAoaHJlcykgewoJICAgIEZJWE1FKCJPbGUgc2VydmVyIGRvZXMgbm90IHByb3ZpZGUgYSBJQ2xhc3NGYWN0b3J5P1xuIik7CgkgICAgcmV0dXJuIGhyZXM7Cgl9CglocmVzID0gSUNsYXNzRmFjdG9yeV9DcmVhdGVJbnN0YW5jZShjbGFzc2ZhYyxOVUxMLCZpaWQsKExQVk9JRCopJnBwdik7CglJQ2xhc3NGYWN0b3J5X1JlbGVhc2UoY2xhc3NmYWMpOwoJaWYgKGhyZXMpIHsKCSAgICBtc2ctPmNiQnVmZmVyID0gMDsKCSAgICBGSVhNRSgiRmFpbGVkIHRvIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiAlc1xuIixkZWJ1Z3N0cl9ndWlkKCZpaWQpKTsKCSAgICByZXR1cm4gaHJlczsKCX0KCWhyZXMgPSBDcmVhdGVTdHJlYW1PbkhHbG9iYWwoMCxUUlVFLCZwU3RtKTsKCWlmIChocmVzKSB7CgkgICAgRklYTUUoIkZhaWxlZCB0byBjcmVhdGUgc3RyZWFtIG9uIGhnbG9iYWxcbiIpOwoJICAgIHJldHVybiBocmVzOwoJfQoJaHJlcyA9IENvTWFyc2hhbEludGVyZmFjZShwU3RtLCZpaWQscHB2LDAsTlVMTCwwKTsKCUlVbmtub3duX1JlbGVhc2UoKElVbmtub3duKilwcHYpOwoJaWYgKGhyZXMpIHsKCSAgICBGSVhNRSgiQ29NYXJzaGFsSW50ZXJmYWNlIGZhaWxlZCwgJWx4IVxuIixocmVzKTsKCSAgICBtc2ctPmNiQnVmZmVyID0gMDsKCSAgICByZXR1cm4gaHJlczsKCX0KCWhyZXMgPSBJU3RyZWFtX1N0YXQocFN0bSwmc3RzdGcsMCk7CglpZiAoaHJlcykgewoJICAgIEZJWE1FKCJTdGF0IGZhaWxlZC5cbiIpOwoJICAgIHJldHVybiBocmVzOwoJfQoKCW1zZy0+Y2JCdWZmZXIgPSBzdHN0Zy5jYlNpemUudS5Mb3dQYXJ0OwoKCWlmIChtc2ctPkJ1ZmZlcikKCSAgICBtc2ctPkJ1ZmZlciA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxtc2ctPkJ1ZmZlcixzdHN0Zy5jYlNpemUudS5Mb3dQYXJ0KTsKCWVsc2UKCSAgICBtc2ctPkJ1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc3RzdGcuY2JTaXplLnUuTG93UGFydCk7CgoJc2Vla3RvLnUuTG93UGFydCA9IDA7c2Vla3RvLnUuSGlnaFBhcnQgPSAwOwoJaHJlcyA9IElTdHJlYW1fU2VlayhwU3RtLHNlZWt0byxTRUVLX1NFVCwmbmV3cG9zKTsKCWlmIChocmVzKSB7CgkgICAgRklYTUUoIklTdHJlYW1fU2VlayBmYWlsZWQsICVseFxuIixocmVzKTsKCSAgICByZXR1cm4gaHJlczsKCX0KCWhyZXMgPSBJU3RyZWFtX1JlYWQocFN0bSxtc2ctPkJ1ZmZlcixtc2ctPmNiQnVmZmVyLCZyZXMpOwoJaWYgKGhyZXMpIHsKCSAgICBGSVhNRSgiU3RyZWFtIFJlYWQgZmFpbGVkLCAlbHhcbiIsaHJlcyk7CgkgICAgcmV0dXJuIGhyZXM7Cgl9CglJU3RyZWFtX1JlbGVhc2UocFN0bSk7CglyZXR1cm4gU19PSzsKICAgIH0KICAgIEZJWE1FKCIoJXAsJXApLCBzdHViIVxuIixtc2csY2hhbmJ1Zik7CiAgICBGSVhNRSgiaU1ldGhvZCBpcyAlbGRcbiIsbXNnLT5pTWV0aG9kKTsKICAgIEZJWE1FKCJjYkJ1ZmZlciBpcyAlbGRcbiIsbXNnLT5jYkJ1ZmZlcik7CiAgICByZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgTFBSUENTVFVCQlVGRkVSIFdJTkFQSQpDRlN0dWJfSXNJSURTdXBwb3J0ZWQoTFBSUENTVFVCQlVGRkVSIGlmYWNlLFJFRklJRCByaWlkKSB7CiAgICBGSVhNRSgiKCVzKSwgc3R1YiFcbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpDRlN0dWJfQ291bnRSZWZzKExQUlBDU1RVQkJVRkZFUiBpZmFjZSkgewogICAgRklYTUUoIigpLCBzdHViIVxuIik7CiAgICByZXR1cm4gMTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCkNGU3R1Yl9EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSx2b2lkKiogcHB2KSB7CiAgICBGSVhNRSgiKCVwKSwgc3R1YiFcbiIscHB2KTsKICAgIHJldHVybiBFX0ZBSUw7Cn0Kc3RhdGljIHZvaWQgICAgV0lOQVBJCkNGU3R1Yl9EZWJ1Z1NlcnZlclJlbGVhc2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLHZvaWQgKnB2KSB7CiAgICBGSVhNRSgiKCVwKSwgc3R1YiFcbiIscHYpOwp9CgpzdGF0aWMgSVJwY1N0dWJCdWZmZXJWdGJsIGNmc3R1YnZ0ID0gewogICAgQ0ZTdHViX1F1ZXJ5SW50ZXJmYWNlLAogICAgQ0ZTdHViX0FkZFJlZiwKICAgIENGU3R1Yl9SZWxlYXNlLAogICAgQ0ZTdHViX0Nvbm5lY3QsCiAgICBDRlN0dWJfRGlzY29ubmVjdCwKICAgIENGU3R1Yl9JbnZva2UsCiAgICBDRlN0dWJfSXNJSURTdXBwb3J0ZWQsCiAgICBDRlN0dWJfQ291bnRSZWZzLAogICAgQ0ZTdHViX0RlYnVnU2VydmVyUXVlcnlJbnRlcmZhY2UsCiAgICBDRlN0dWJfRGVidWdTZXJ2ZXJSZWxlYXNlCn07CgpzdGF0aWMgSFJFU1VMVApDRlN0dWJfQ29uc3RydWN0KExQUlBDU1RVQkJVRkZFUiAqcHB2KSB7CiAgICBDRlN0dWIgKmNmc3R1YjsKICAgIGNmc3R1YiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKENGU3R1YikpOwogICAgaWYgKCFjZnN0dWIpCglyZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgICpwcHYgPSAoTFBSUENTVFVCQlVGRkVSKWNmc3R1YjsKICAgIGNmc3R1Yi0+bHB2dGJsCT0gJmNmc3R1YnZ0OwogICAgY2ZzdHViLT5yZWYJCT0gMTsKICAgIHJldHVybiBTX09LOwp9CgovKiBTaW5jZSB3ZSBjcmVhdGUgcHJveHkgYnVmZmVycyBhbmQgY2xhc3NmYWN0b3J5IGluIGEgcGFpciwgdGhlcmUgaXMKICogbm8gbmVlZCBmb3IgMiBzZXBhcmF0ZSBzdHJ1Y3RzLiBKdXN0IHB1dCB0aGVtIGluIG9uZSwgYnV0IHJlbWVtYmVyCiAqIHRoZSByZWZjb3VudC4KICovCnR5cGVkZWYgc3RydWN0IF9DRlByb3h5IHsKICAgIGNvbnN0IElDbGFzc0ZhY3RvcnlWdGJsCQkqbHB2dGJsX2NmOwogICAgY29uc3QgSVJwY1Byb3h5QnVmZmVyVnRibAkqbHB2dGJsX3Byb3h5OwogICAgRFdPUkQJCQkJcmVmOwoKICAgIElScGNDaGFubmVsQnVmZmVyCQkJKmNoYW5idWY7CiAgICBJVW5rbm93biAqb3V0ZXJfdW5rbm93bjsKfSBDRlByb3h5OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElScGNQcm94eUJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSxSRUZJSUQgcmlpZCxMUFZPSUQgKnBwdikgewogICAgKnBwdiA9IE5VTEw7CiAgICBpZiAoSXNFcXVhbElJRChyaWlkLCZJSURfSVJwY1Byb3h5QnVmZmVyKXx8SXNFcXVhbElJRChyaWlkLCZJSURfSVVua25vd24pKSB7CglJUnBjUHJveHlCdWZmZXJfQWRkUmVmKGlmYWNlKTsKCSpwcHYgPSAoTFBWT0lEKWlmYWNlOwoJcmV0dXJuIFNfT0s7CiAgICB9CiAgICBGSVhNRSgiKCVzKSwgbm8gaW50ZXJmYWNlLlxuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElScGNQcm94eUJ1ZmZlckltcGxfQWRkUmVmKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBpZiAoIXJlZikgewoJSVJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZShUaGlzLT5jaGFuYnVmKTtUaGlzLT5jaGFuYnVmID0gTlVMTDsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKICAgIH0KICAgIHJldHVybiByZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUnBjUHJveHlCdWZmZXJJbXBsX0Nvbm5lY3QoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSxJUnBjQ2hhbm5lbEJ1ZmZlciogcFJwY0NoYW5uZWxCdWZmZXIpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CgogICAgVGhpcy0+Y2hhbmJ1ZiA9IHBScGNDaGFubmVsQnVmZmVyOwogICAgSVJwY0NoYW5uZWxCdWZmZXJfQWRkUmVmKFRoaXMtPmNoYW5idWYpOwogICAgcmV0dXJuIFNfT0s7Cn0Kc3RhdGljIHZvaWQgV0lOQVBJIElScGNQcm94eUJ1ZmZlckltcGxfRGlzY29ubmVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwogICAgaWYgKFRoaXMtPmNoYW5idWYpIHsKCUlScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UoVGhpcy0+Y2hhbmJ1Zik7CglUaGlzLT5jaGFuYnVmID0gTlVMTDsKICAgIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCkNGUHJveHlfUXVlcnlJbnRlcmZhY2UoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KSB7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfY2YsaWZhY2UpOwogICAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pIHJldHVybiBJVW5rbm93bl9RdWVyeUludGVyZmFjZShUaGlzLT5vdXRlcl91bmtub3duLCByaWlkLCBwcHYpOwogICAgKnBwdiA9IE5VTEw7CiAgICBpZiAoSXNFcXVhbElJRCgmSUlEX0lDbGFzc0ZhY3RvcnkscmlpZCkgfHwgSXNFcXVhbElJRCgmSUlEX0lVbmtub3duLHJpaWQpKSB7CgkqcHB2ID0gKExQVk9JRClpZmFjZTsKCUlDbGFzc0ZhY3RvcnlfQWRkUmVmKGlmYWNlKTsKCXJldHVybiBTX09LOwogICAgfQogICAgaWYgKElzRXF1YWxJSUQocmlpZCwmSUlEX0lNYXJzaGFsKSkgLyoganVzdCB0byBhdm9pZCBkZWJ1ZyBvdXRwdXQgKi8KCXJldHVybiBFX05PSU5URVJGQUNFOwogICAgRklYTUUoIlVuaGFuZGxlZCBpbnRlcmZhY2U6ICVzXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBDRlByb3h5X0FkZFJlZihMUENMQVNTRkFDVE9SWSBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX2NmLGlmYWNlKTsKICAgIGlmIChUaGlzLT5vdXRlcl91bmtub3duKSByZXR1cm4gSVVua25vd25fQWRkUmVmKFRoaXMtPm91dGVyX3Vua25vd24pOwogICAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgQ0ZQcm94eV9SZWxlYXNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlKSB7CiAgICBVTE9ORyByZWY7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfY2YsaWZhY2UpOwogICAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pCiAgICAgICAgcmVmID0gSVVua25vd25fUmVsZWFzZShUaGlzLT5vdXRlcl91bmtub3duKTsKICAgIGVsc2UgICAgCiAgICAgICAgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgaWYgKCFyZWYpIHsKICAgICAgCWlmIChUaGlzLT5jaGFuYnVmKSBJUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKFRoaXMtPmNoYW5idWYpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKICAgIH0KICAgIHJldHVybiByZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBDRlByb3h5X0NyZWF0ZUluc3RhbmNlKAogICAgTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsCiAgICBMUFVOS05PV04gcFVua091dGVyLC8qIFtpbl0gKi8KICAgIFJFRklJRCByaWlkLAkvKiBbaW5dICovCiAgICBMUFZPSUQgKnBwdgkJLyogW291dF0gKi8KKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfY2YsaWZhY2UpOwogICAgSFJFU1VMVAkJaHJlczsKICAgIExQU1RSRUFNCQlwU3RyZWFtOwogICAgSEdMT0JBTAkJaEdsb2JhbDsKICAgIFVMT05HCQlzcnN0YXR1czsKICAgIFJQQ09MRU1FU1NBR0UJbXNnOwoKICAgIFRSQUNFKCIoJXAsJXMsJXApXG4iLHBVbmtPdXRlcixkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwdik7CgogICAgLyogU2VuZCBDcmVhdGVJbnN0YW5jZSB0byB0aGUgcmVtb3RlIGNsYXNzZmFjdG9yeS4KICAgICAqCiAgICAgKiBEYXRhOiBPbmx5IHRoZSAnSUlEJy4KICAgICAqLwogICAgbXNnLmlNZXRob2QgID0gMzsKICAgIG1zZy5jYkJ1ZmZlciA9IHNpemVvZigqcmlpZCk7CiAgICBtc2cuQnVmZmVyCSA9IE5VTEw7CiAgICBocmVzID0gSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKFRoaXMtPmNoYW5idWYsJm1zZywmSUlEX0lDbGFzc0ZhY3RvcnkpOwogICAgaWYgKGhyZXMpIHsKCUZJWE1FKCJJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIgZmFpbGVkIHdpdGggJWx4P1xuIixocmVzKTsKCXJldHVybiBocmVzOwogICAgfQogICAgbWVtY3B5KG1zZy5CdWZmZXIscmlpZCxzaXplb2YoKnJpaWQpKTsKICAgIGhyZXMgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShUaGlzLT5jaGFuYnVmLCZtc2csJnNyc3RhdHVzKTsKICAgIGlmIChocmVzKSB7CglGSVhNRSgiSVJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUgZmFpbGVkIHdpdGggJWx4P1xuIixocmVzKTsKCXJldHVybiBocmVzOwogICAgfQoKICAgIGlmICghbXNnLmNiQnVmZmVyKSAvKiBpbnRlcmZhY2Ugbm90IGZvdW5kIG9uIHJlbW90ZSAqLwoJcmV0dXJuIHNyc3RhdHVzOwoKICAgIC8qIFdlIGdvdCBiYWNrOiBbTWFyc2hhbGxlZCBJbnRlcmZhY2UgZGF0YV0gKi8KICAgIFRSQUNFKCJnb3QgJWxkIGJ5dGVzIGRhdGEuXG4iLG1zZy5jYkJ1ZmZlcik7CiAgICBoR2xvYmFsID0gR2xvYmFsQWxsb2MoR01FTV9NT1ZFQUJMRXxHTUVNX05PRElTQ0FSRHxHTUVNX1NIQVJFLG1zZy5jYkJ1ZmZlcik7CiAgICBtZW1jcHkoR2xvYmFsTG9jayhoR2xvYmFsKSxtc2cuQnVmZmVyLG1zZy5jYkJ1ZmZlcik7CiAgICBocmVzID0gQ3JlYXRlU3RyZWFtT25IR2xvYmFsKGhHbG9iYWwsVFJVRSwmcFN0cmVhbSk7CiAgICBpZiAoaHJlcykgewoJRklYTUUoIkNyZWF0ZVN0cmVhbU9uSEdsb2JhbCBmYWlsZWQgd2l0aCAlbHhcbiIsaHJlcyk7CglyZXR1cm4gaHJlczsKICAgIH0KICAgIGhyZXMgPSBDb1VubWFyc2hhbEludGVyZmFjZSgKCSAgICBwU3RyZWFtLAoJICAgIHJpaWQsCgkgICAgcHB2CiAgICApOwogICAgSVN0cmVhbV9SZWxlYXNlKHBTdHJlYW0pOyAvKiBEb2VzIEdsb2JhbEZyZWUgaEdsb2JhbCB0b28uICovCiAgICBpZiAoaHJlcykgewoJRklYTUUoIkNvTWFyc2hhbEludGVyZmFjZSBmYWlsZWQsICVseFxuIixocmVzKTsKCXJldHVybiBocmVzOwogICAgfQogICAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBDRlByb3h5X0xvY2tTZXJ2ZXIoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsQk9PTCBmTG9jaykgewogICAgLypJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfY2YsaWZhY2UpOyovCiAgICBGSVhNRSgiKCVkKSwgc3R1YiFcbiIsZkxvY2spOwogICAgLyogYmFzaWNhbGx5OiB3cml0ZSBCT09MLCByZWFkIGVtcHR5ICovCiAgICByZXR1cm4gU19PSzsKfQoKc3RhdGljIElScGNQcm94eUJ1ZmZlclZ0YmwgcHNwYnZ0YmwgPSB7CiAgICBJUnBjUHJveHlCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSVJwY1Byb3h5QnVmZmVySW1wbF9BZGRSZWYsCiAgICBJUnBjUHJveHlCdWZmZXJJbXBsX1JlbGVhc2UsCiAgICBJUnBjUHJveHlCdWZmZXJJbXBsX0Nvbm5lY3QsCiAgICBJUnBjUHJveHlCdWZmZXJJbXBsX0Rpc2Nvbm5lY3QKfTsKc3RhdGljIElDbGFzc0ZhY3RvcnlWdGJsIGNmcHJveHl2dCA9IHsKICAgIENGUHJveHlfUXVlcnlJbnRlcmZhY2UsCiAgICBDRlByb3h5X0FkZFJlZiwKICAgIENGUHJveHlfUmVsZWFzZSwKICAgIENGUHJveHlfQ3JlYXRlSW5zdGFuY2UsCiAgICBDRlByb3h5X0xvY2tTZXJ2ZXIKfTsKCnN0YXRpYyBIUkVTVUxUCkNGUHJveHlfQ29uc3RydWN0KElVbmtub3duICpwVW5rT3V0ZXIsIExQVk9JRCAqcHB2LExQVk9JRCAqcHBQcm94eSkgewogICAgQ0ZQcm94eSAqY2Y7CgogICAgY2YgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZihDRlByb3h5KSk7CiAgICBpZiAoIWNmKQoJcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgY2YtPmxwdnRibF9jZgk9ICZjZnByb3h5dnQ7CiAgICBjZi0+bHB2dGJsX3Byb3h5CT0gJnBzcGJ2dGJsOwogICAgLyogb25seSBvbmUgcmVmZXJlbmNlIGZvciB0aGUgcHJveHkgYnVmZmVyICovCiAgICBjZi0+cmVmCQk9IDE7CiAgICBjZi0+b3V0ZXJfdW5rbm93biA9IHBVbmtPdXRlcjsKICAgICpwcHYJCT0gJihjZi0+bHB2dGJsX2NmKTsKICAgICpwcFByb3h5CQk9ICYoY2YtPmxwdnRibF9wcm94eSk7CiAgICByZXR1cm4gU19PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKiogSVJlbVVua25vd24gUHJveHkvU3R1YiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnR5cGVkZWYgc3RydWN0CnsKICAgIGNvbnN0IElScGNTdHViQnVmZmVyVnRibCAqbHBWdGJsOwogICAgVUxPTkcgcmVmczsKICAgIElSZW1Vbmtub3duICppZmFjZTsKfSBSZW1VbmtTdHViOwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1N0dWJfUXVlcnlJbnRlcmZhY2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAoJCQkJCSAgICAgUkVGSUlEIHJpaWQsCgkJCQkJICAgICBMUFZPSUQgKm9iaikKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5RdWVyeUludGVyZmFjZSglcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLG9iaik7CiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24scmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JUnBjU3R1YkJ1ZmZlcixyaWlkKSkgewogICAgKm9iaiA9IFRoaXM7CiAgICByZXR1cm4gU19PSzsKICB9CiAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUmVtVW5rU3R1Yl9BZGRSZWYoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPkFkZFJlZigpXG4iLFRoaXMpOwogIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmcyk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUmVtVW5rU3R1Yl9SZWxlYXNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSkKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFVMT05HIHJlZnM7CiAgVFJBQ0UoIiglcCktPlJlbGVhc2UoKVxuIixUaGlzKTsKICByZWZzID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZnMpOwogIGlmICghcmVmcykKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwogIHJldHVybiByZWZzOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUmVtVW5rU3R1Yl9Db25uZWN0KExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKCQkJCSAgICAgIExQVU5LTk9XTiBscFVua1NlcnZlcikKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5Db25uZWN0KCVwKVxuIixUaGlzLGxwVW5rU2VydmVyKTsKICBUaGlzLT5pZmFjZSA9IChJUmVtVW5rbm93biopbHBVbmtTZXJ2ZXI7CiAgSVJlbVVua25vd25fQWRkUmVmKFRoaXMtPmlmYWNlKTsKICByZXR1cm4gU19PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIFJlbVVua1N0dWJfRGlzY29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+RGlzY29ubmVjdCgpXG4iLFRoaXMpOwogIElVbmtub3duX1JlbGVhc2UoVGhpcy0+aWZhY2UpOwogIFRoaXMtPmlmYWNlID0gTlVMTDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1N0dWJfSW52b2tlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKCQkJCSAgICAgUFJQQ09MRU1FU1NBR0UgcE1zZywKCQkJCSAgICAgTFBSUENDSEFOTkVMQlVGRkVSIHBDaGFubmVsKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVUxPTkcgaU1ldGhvZCA9IHBNc2ctPmlNZXRob2Q7CiAgTFBCWVRFIGJ1ZiA9IHBNc2ctPkJ1ZmZlcjsKICBIUkVTVUxUIGhyID0gUlBDX0VfSU5WQUxJRE1FVEhPRDsKCiAgVFJBQ0UoIiglcCktPkludm9rZSglcCwlcCkgbWV0aG9kICVsZFxuIiwgVGhpcywgcE1zZywgcENoYW5uZWwsIGlNZXRob2QpOwogIHN3aXRjaCAoaU1ldGhvZCkKICB7CiAgY2FzZSAzOiAvKiBSZW1RdWVyeUludGVyZmFjZSAqLwogIHsKICAgIElQSUQgaXBpZDsKICAgIFVMT05HIGNSZWZzOwogICAgVVNIT1JUIGNJaWRzOwogICAgSUlEICppaWRzOwogICAgUkVNUUlSRVNVTFQgKnBRSVJlc3VsdHMgPSBOVUxMOwoKICAgIC8qIGluICovCiAgICBtZW1jcHkoJmlwaWQsIGJ1Ziwgc2l6ZW9mKGlwaWQpKTsKICAgIGJ1ZiArPSBzaXplb2YoaXBpZCk7CiAgICBtZW1jcHkoJmNSZWZzLCBidWYsIHNpemVvZihjUmVmcykpOwogICAgYnVmICs9IHNpemVvZihjUmVmcyk7CiAgICBtZW1jcHkoJmNJaWRzLCBidWYsIHNpemVvZihjSWlkcykpOwogICAgYnVmICs9IHNpemVvZihjSWlkcyk7CiAgICBpaWRzID0gKElJRCAqKWJ1ZjsKCiAgICBociA9IElSZW1Vbmtub3duX1JlbVF1ZXJ5SW50ZXJmYWNlKFRoaXMtPmlmYWNlLCAmaXBpZCwgY1JlZnMsIGNJaWRzLCBpaWRzLCAmcFFJUmVzdWx0cyk7CgogICAgLyogb3V0ICovCiAgICBwTXNnLT5jYkJ1ZmZlciA9IGNJaWRzICogc2l6ZW9mKFJFTVFJUkVTVUxUKTsKICAgIGlmIChwTXNnLT5CdWZmZXIpCiAgICAgICAgcE1zZy0+QnVmZmVyID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcE1zZy0+QnVmZmVyLCBwTXNnLT5jYkJ1ZmZlcik7CgllbHNlCiAgICAgICAgcE1zZy0+QnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHBNc2ctPmNiQnVmZmVyKTsKICAgIGJ1ZiA9IHBNc2ctPkJ1ZmZlcjsKICAgIC8qIEZJWE1FOiBwUUlSZXN1bHRzIGlzIGEgdW5pcXVlIHBvaW50ZXIgc28gcFFJUmVzdWx0cyBjYW4gYmUgTlVMTCEgKi8KICAgIG1lbWNweShidWYsIHBRSVJlc3VsdHMsIGNJaWRzICogc2l6ZW9mKFJFTVFJUkVTVUxUKSk7CgogICAgYnJlYWs7CiAgfQogIGNhc2UgNDogLyogUmVtQWRkUmVmICovCiAgewogICAgVVNIT1JUIGNJaWRzOwogICAgUkVNSU5URVJGQUNFUkVGICppcjsKICAgIEhSRVNVTFQgKnBSZXN1bHRzOwoKICAgIC8qIGluICovCiAgICBtZW1jcHkoJmNJaWRzLCBidWYsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIGlyID0gKFJFTUlOVEVSRkFDRVJFRiopYnVmOwogICAgcFJlc3VsdHMgPSBDb1Rhc2tNZW1BbGxvYyhjSWlkcyAqIHNpemVvZihIUkVTVUxUKSk7CiAgICBpZiAoIXBSZXN1bHRzKSByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBociA9IElSZW1Vbmtub3duX1JlbUFkZFJlZihUaGlzLT5pZmFjZSwgY0lpZHMsIGlyLCBwUmVzdWx0cyk7CgogICAgLyogb3V0ICovCiAgICBwTXNnLT5jYkJ1ZmZlciA9IGNJaWRzICogc2l6ZW9mKEhSRVNVTFQpOwogICAgaWYgKHBNc2ctPkJ1ZmZlcikKICAgICAgICBwTXNnLT5CdWZmZXIgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBwTXNnLT5CdWZmZXIsIHBNc2ctPmNiQnVmZmVyKTsKCWVsc2UKICAgICAgICBwTXNnLT5CdWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcE1zZy0+Y2JCdWZmZXIpOwogICAgYnVmID0gcE1zZy0+QnVmZmVyOwogICAgbWVtY3B5KGJ1ZiwgcFJlc3VsdHMsIGNJaWRzICogc2l6ZW9mKEhSRVNVTFQpKTsKCiAgICBDb1Rhc2tNZW1GcmVlKHBSZXN1bHRzKTsKCiAgICBicmVhazsKICB9CiAgY2FzZSA1OiAvKiBSZW1SZWxlYXNlICovCiAgewogICAgVVNIT1JUIGNJaWRzOwogICAgUkVNSU5URVJGQUNFUkVGICppcjsKCiAgICAvKiBpbiAqLwogICAgbWVtY3B5KCZjSWlkcywgYnVmLCBzaXplb2YoVVNIT1JUKSk7CiAgICBidWYgKz0gc2l6ZW9mKFVTSE9SVCk7CiAgICBpciA9IChSRU1JTlRFUkZBQ0VSRUYqKWJ1ZjsKCiAgICBociA9IElSZW1Vbmtub3duX1JlbVJlbGVhc2UoVGhpcy0+aWZhY2UsIGNJaWRzLCBpcik7CgogICAgLyogb3V0ICovCiAgICBwTXNnLT5jYkJ1ZmZlciA9IDA7CiAgICBicmVhazsKICB9CiAgfQogIHJldHVybiBocjsKfQoKc3RhdGljIExQUlBDU1RVQkJVRkZFUiBXSU5BUEkgUmVtVW5rU3R1Yl9Jc0lJRFN1cHBvcnRlZChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJCSAgICAgUkVGSUlEIHJpaWQpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+SXNJSURTdXBwb3J0ZWQoJXMpXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICByZXR1cm4gSXNFcXVhbEdVSUQoJklJRF9JUmVtVW5rbm93biwgcmlpZCkgPyBpZmFjZSA6IE5VTEw7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUmVtVW5rU3R1Yl9Db3VudFJlZnMoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgRklYTUUoIiglcCktPkNvdW50UmVmcygpXG4iLCBUaGlzKTsKICByZXR1cm4gMTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1N0dWJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJCQlMUFZPSUQgKnBwdikKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIEZJWE1FKCIoJXApLT5EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlKCVwKVxuIixUaGlzLHBwdik7CiAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBSZW1VbmtTdHViX0RlYnVnU2VydmVyUmVsZWFzZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJICAgICAgTFBWT0lEIHB2KQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgRklYTUUoIiglcCktPkRlYnVnU2VydmVyUmVsZWFzZSglcClcbiIsIFRoaXMsIHB2KTsKfQoKc3RhdGljIGNvbnN0IElScGNTdHViQnVmZmVyVnRibCBSZW1VbmtTdHViX1ZUYWJsZSA9CnsKICBSZW1VbmtTdHViX1F1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1N0dWJfQWRkUmVmLAogIFJlbVVua1N0dWJfUmVsZWFzZSwKICBSZW1VbmtTdHViX0Nvbm5lY3QsCiAgUmVtVW5rU3R1Yl9EaXNjb25uZWN0LAogIFJlbVVua1N0dWJfSW52b2tlLAogIFJlbVVua1N0dWJfSXNJSURTdXBwb3J0ZWQsCiAgUmVtVW5rU3R1Yl9Db3VudFJlZnMsCiAgUmVtVW5rU3R1Yl9EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1N0dWJfRGVidWdTZXJ2ZXJSZWxlYXNlCn07CgpzdGF0aWMgSFJFU1VMVCBSZW1VbmtTdHViX0NvbnN0cnVjdChJUnBjU3R1YkJ1ZmZlciAqKnBwU3R1YikKewogICAgUmVtVW5rU3R1YiAqVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKlRoaXMpKTsKICAgIGlmICghVGhpcykgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICBUaGlzLT5scFZ0YmwgPSAmUmVtVW5rU3R1Yl9WVGFibGU7CiAgICBUaGlzLT5yZWZzID0gMDsKICAgIFRoaXMtPmlmYWNlID0gTlVMTDsKICAgICpwcFN0dWIgPSAoSVJwY1N0dWJCdWZmZXIqKVRoaXM7CiAgICByZXR1cm4gU19PSzsKfQoKCnR5cGVkZWYgc3RydWN0IF9SZW1VbmtQcm94eSB7CiAgICBjb25zdCBJUmVtVW5rbm93blZ0YmwJCSpscHZ0YmxfcmVtdW5rOwogICAgY29uc3QgSVJwY1Byb3h5QnVmZmVyVnRibAkqbHB2dGJsX3Byb3h5OwogICAgRFdPUkQJCQkJcmVmczsKCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcgkJCSpjaGFuOwogICAgSVVua25vd24gKm91dGVyX3Vua25vd247Cn0gUmVtVW5rUHJveHk7CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUmVtVW5rUHJveHlfUXVlcnlJbnRlcmZhY2UoTFBSRU1VTktOT1dOIGlmYWNlLCBSRUZJSUQgcmlpZCwgdm9pZCAqKnBwdikKewogICAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKICAgIGlmIChUaGlzLT5vdXRlcl91bmtub3duKQogICAgICAgIHJldHVybiBJVW5rbm93bl9RdWVyeUludGVyZmFjZShUaGlzLT5vdXRlcl91bmtub3duLCByaWlkLCBwcHYpOwogICAgaWYgKElzRXF1YWxJSUQocmlpZCwgJklJRF9JVW5rbm93bikgfHwKICAgICAgICBJc0VxdWFsSUlEKHJpaWQsICZJSURfSVJlbVVua25vd24pKQogICAgewogICAgICAgIElSZW1Vbmtub3duX0FkZFJlZihpZmFjZSk7CiAgICAgICAgKnBwdiA9IChMUFZPSUQpaWZhY2U7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSZW1VbmtQcm94eV9BZGRSZWYoTFBSRU1VTktOT1dOIGlmYWNlKQp7CiAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCktPkFkZFJlZigpXG4iLFRoaXMpOwogIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmcyk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUmVtVW5rUHJveHlfUmVsZWFzZShMUFJFTVVOS05PV04gaWZhY2UpCnsKICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogIFVMT05HIHJlZnM7CgogIFRSQUNFKCIoJXApLT5SZWxlYXNlKClcbiIsVGhpcyk7CiAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pCiAgICAgIHJlZnMgPSBJVW5rbm93bl9SZWxlYXNlKFRoaXMtPm91dGVyX3Vua25vd24pOwogIGVsc2UgICAgCiAgICAgIHJlZnMgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmcyk7CgogIGlmICghcmVmcykgewogICAgICBpZiAoVGhpcy0+Y2hhbikgSVJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZShUaGlzLT5jaGFuKTsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwogIH0KICByZXR1cm4gcmVmczsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1Byb3h5X1JlbVF1ZXJ5SW50ZXJmYWNlKExQUkVNVU5LTk9XTiBpZmFjZSwKCQkJCQkJIFJFRklQSUQgcmlwaWQsCgkJCQkJCSBVTE9ORyBjUmVmcywKCQkJCQkJIFVTSE9SVCBjSWlkcywKCQkJCQkJIElJRCogaWlkcywKCQkJCQkJIFJFTVFJUkVTVUxUKiogcHBRSVJlc3VsdHMpCnsKICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogIFJQQ09MRU1FU1NBR0UgbXNnOwogIEhSRVNVTFQgaHIgPSBTX09LOwogIFVMT05HIHN0YXR1czsKCiAgVFJBQ0UoIiglcCktPiglcywlbGQsJWQsJXAsJXApXG4iLFRoaXMsCglkZWJ1Z3N0cl9ndWlkKHJpcGlkKSxjUmVmcyxjSWlkcyxpaWRzLHBwUUlSZXN1bHRzKTsKCiAgKnBwUUlSZXN1bHRzID0gTlVMTDsKICBtZW1zZXQoJm1zZywgMCwgc2l6ZW9mKG1zZykpOwogIG1zZy5pTWV0aG9kID0gMzsKICBtc2cuY2JCdWZmZXIgPSBzaXplb2YoSVBJRCkgKyBzaXplb2YoVUxPTkcpICsKICAgIHNpemVvZihVU0hPUlQpICsgY0lpZHMqc2l6ZW9mKElJRCk7CiAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIoVGhpcy0+Y2hhbiwgJm1zZywgJklJRF9JUmVtVW5rbm93bik7CiAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgIExQQllURSBidWYgPSBtc2cuQnVmZmVyOwogICAgbWVtY3B5KGJ1ZiwgcmlwaWQsIHNpemVvZihJUElEKSk7CiAgICBidWYgKz0gc2l6ZW9mKElQSUQpOwogICAgbWVtY3B5KGJ1ZiwgJmNSZWZzLCBzaXplb2YoVUxPTkcpKTsKICAgIGJ1ZiArPSBzaXplb2YoVUxPTkcpOwogICAgbWVtY3B5KGJ1ZiwgJmNJaWRzLCBzaXplb2YoVVNIT1JUKSk7CiAgICBidWYgKz0gc2l6ZW9mKFVTSE9SVCk7CiAgICBtZW1jcHkoYnVmLCBpaWRzLCBjSWlkcypzaXplb2YoSUlEKSk7CgogICAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShUaGlzLT5jaGFuLCAmbXNnLCAmc3RhdHVzKTsKCiAgICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgICBidWYgPSBtc2cuQnVmZmVyOwogICAgICAqcHBRSVJlc3VsdHMgPSBDb1Rhc2tNZW1BbGxvYyhjSWlkcypzaXplb2YoUkVNUUlSRVNVTFQpKTsKICAgICAgbWVtY3B5KCpwcFFJUmVzdWx0cywgYnVmLCBjSWlkcypzaXplb2YoUkVNUUlSRVNVTFQpKTsKICAgIH0KCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyKFRoaXMtPmNoYW4sICZtc2cpOwogIH0KCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUmVtVW5rUHJveHlfUmVtQWRkUmVmKExQUkVNVU5LTk9XTiBpZmFjZSwKCQkJCQkgVVNIT1JUIGNJbnRlcmZhY2VSZWZzLAoJCQkJCSBSRU1JTlRFUkZBQ0VSRUYqIEludGVyZmFjZVJlZnMsCgkJCQkJIEhSRVNVTFQqIHBSZXN1bHRzKQp7CiAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKICBSUENPTEVNRVNTQUdFIG1zZzsKICBIUkVTVUxUIGhyID0gU19PSzsKICBVTE9ORyBzdGF0dXM7CgogIFRSQUNFKCIoJXApLT4oJWQsJXAsJXApXG4iLFRoaXMsCgljSW50ZXJmYWNlUmVmcyxJbnRlcmZhY2VSZWZzLHBSZXN1bHRzKTsKCiAgbWVtc2V0KCZtc2csIDAsIHNpemVvZihtc2cpKTsKICBtc2cuaU1ldGhvZCA9IDQ7CiAgbXNnLmNiQnVmZmVyID0gc2l6ZW9mKFVTSE9SVCkgKyBjSW50ZXJmYWNlUmVmcypzaXplb2YoUkVNSU5URVJGQUNFUkVGKTsKICBociA9IElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihUaGlzLT5jaGFuLCAmbXNnLCAmSUlEX0lSZW1Vbmtub3duKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgTFBCWVRFIGJ1ZiA9IG1zZy5CdWZmZXI7CiAgICBtZW1jcHkoYnVmLCAmY0ludGVyZmFjZVJlZnMsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIG1lbWNweShidWYsIEludGVyZmFjZVJlZnMsIGNJbnRlcmZhY2VSZWZzKnNpemVvZihSRU1JTlRFUkZBQ0VSRUYpKTsKCiAgICBociA9IElScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlKFRoaXMtPmNoYW4sICZtc2csICZzdGF0dXMpOwoKICAgIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICAgIGJ1ZiA9IG1zZy5CdWZmZXI7CiAgICAgIG1lbWNweShwUmVzdWx0cywgYnVmLCBjSW50ZXJmYWNlUmVmcypzaXplb2YoSFJFU1VMVCkpOwogICAgfQoKICAgIElScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIoVGhpcy0+Y2hhbiwgJm1zZyk7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtQcm94eV9SZW1SZWxlYXNlKExQUkVNVU5LTk9XTiBpZmFjZSwKCQkJCQkgIFVTSE9SVCBjSW50ZXJmYWNlUmVmcywKCQkJCQkgIFJFTUlOVEVSRkFDRVJFRiogSW50ZXJmYWNlUmVmcykKewogIFJlbVVua1Byb3h5ICpUaGlzID0gKFJlbVVua1Byb3h5ICopaWZhY2U7CiAgUlBDT0xFTUVTU0FHRSBtc2c7CiAgSFJFU1VMVCBociA9IFNfT0s7CiAgVUxPTkcgc3RhdHVzOwoKICBUUkFDRSgiKCVwKS0+KCVkLCVwKVxuIixUaGlzLAoJY0ludGVyZmFjZVJlZnMsSW50ZXJmYWNlUmVmcyk7CgogIG1lbXNldCgmbXNnLCAwLCBzaXplb2YobXNnKSk7CiAgbXNnLmlNZXRob2QgPSA1OwogIG1zZy5jYkJ1ZmZlciA9IHNpemVvZihVU0hPUlQpICsgY0ludGVyZmFjZVJlZnMqc2l6ZW9mKFJFTUlOVEVSRkFDRVJFRik7CiAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIoVGhpcy0+Y2hhbiwgJm1zZywgJklJRF9JUmVtVW5rbm93bik7CiAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgIExQQllURSBidWYgPSBtc2cuQnVmZmVyOwogICAgbWVtY3B5KGJ1ZiwgJmNJbnRlcmZhY2VSZWZzLCBzaXplb2YoVVNIT1JUKSk7CiAgICBidWYgKz0gc2l6ZW9mKFVTSE9SVCk7CiAgICBtZW1jcHkoYnVmLCBJbnRlcmZhY2VSZWZzLCBjSW50ZXJmYWNlUmVmcypzaXplb2YoUkVNSU5URVJGQUNFUkVGKSk7CgogICAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShUaGlzLT5jaGFuLCAmbXNnLCAmc3RhdHVzKTsKCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyKFRoaXMtPmNoYW4sICZtc2cpOwogIH0KCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgY29uc3QgSVJlbVVua25vd25WdGJsIFJlbVVua1Byb3h5X1ZUYWJsZSA9CnsKICBSZW1VbmtQcm94eV9RdWVyeUludGVyZmFjZSwKICBSZW1VbmtQcm94eV9BZGRSZWYsCiAgUmVtVW5rUHJveHlfUmVsZWFzZSwKICBSZW1VbmtQcm94eV9SZW1RdWVyeUludGVyZmFjZSwKICBSZW1VbmtQcm94eV9SZW1BZGRSZWYsCiAgUmVtVW5rUHJveHlfUmVtUmVsZWFzZQp9OwoKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9RdWVyeUludGVyZmFjZShMUFJQQ1BST1hZQlVGRkVSIGlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHB2KSB7CiAgICAqcHB2ID0gTlVMTDsKICAgIGlmIChJc0VxdWFsSUlEKHJpaWQsJklJRF9JUnBjUHJveHlCdWZmZXIpfHxJc0VxdWFsSUlEKHJpaWQsJklJRF9JVW5rbm93bikpIHsKCUlScGNQcm94eUJ1ZmZlcl9BZGRSZWYoaWZhY2UpOwoJKnBwdiA9IChMUFZPSUQpaWZhY2U7CglyZXR1cm4gU19PSzsKICAgIH0KICAgIEZJWE1FKCIoJXMpLCBubyBpbnRlcmZhY2UuXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUlVScGNQcm94eUJ1ZmZlckltcGxfQWRkUmVmKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShSZW1VbmtQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwogICAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWZzKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShSZW1VbmtQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZnMpOwoKICAgIGlmICghcmVmKSB7CglJUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKFRoaXMtPmNoYW4pO1RoaXMtPmNoYW4gPSBOVUxMOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwogICAgfQogICAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJVUnBjUHJveHlCdWZmZXJJbXBsX0Nvbm5lY3QoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSxJUnBjQ2hhbm5lbEJ1ZmZlciogcFJwY0NoYW5uZWxCdWZmZXIpIHsKICAgIElDT01fVEhJU19NVUxUSShSZW1VbmtQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwoKICAgIFRoaXMtPmNoYW4gPSBwUnBjQ2hhbm5lbEJ1ZmZlcjsKICAgIElScGNDaGFubmVsQnVmZmVyX0FkZFJlZihUaGlzLT5jaGFuKTsKICAgIHJldHVybiBTX09LOwp9CnN0YXRpYyB2b2lkIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9EaXNjb25uZWN0KExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShSZW1VbmtQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwogICAgaWYgKFRoaXMtPmNoYW4pIHsKCUlScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UoVGhpcy0+Y2hhbik7CglUaGlzLT5jaGFuID0gTlVMTDsKICAgIH0KfQoKCnN0YXRpYyBjb25zdCBJUnBjUHJveHlCdWZmZXJWdGJsIFJVUnBjUHJveHlCdWZmZXJfVlRhYmxlID0gewogICAgUlVScGNQcm94eUJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBSVVJwY1Byb3h5QnVmZmVySW1wbF9BZGRSZWYsCiAgICBSVVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlLAogICAgUlVScGNQcm94eUJ1ZmZlckltcGxfQ29ubmVjdCwKICAgIFJVUnBjUHJveHlCdWZmZXJJbXBsX0Rpc2Nvbm5lY3QKfTsKCnN0YXRpYyBIUkVTVUxUClJlbVVua1Byb3h5X0NvbnN0cnVjdChJVW5rbm93biAqcFVua091dGVyLCBMUFZPSUQgKnBwdixMUFZPSUQgKnBwUHJveHkpIHsKICAgIFJlbVVua1Byb3h5ICpUaGlzOwoKICAgIFRoaXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZigqVGhpcykpOwogICAgaWYgKCFUaGlzKQoJcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgVGhpcy0+bHB2dGJsX3JlbXVuawk9ICZSZW1VbmtQcm94eV9WVGFibGU7CiAgICBUaGlzLT5scHZ0YmxfcHJveHkJPSAmUlVScGNQcm94eUJ1ZmZlcl9WVGFibGU7CiAgICAvKiBvbmx5IG9uZSByZWZlcmVuY2UgZm9yIHRoZSBwcm94eSBidWZmZXIgKi8KICAgIFRoaXMtPnJlZnMJCT0gMTsKICAgIFRoaXMtPm91dGVyX3Vua25vd24gPSBwVW5rT3V0ZXI7CiAgICAqcHB2CQk9ICYoVGhpcy0+bHB2dGJsX3JlbXVuayk7CiAgICAqcHBQcm94eQkJPSAmKFRoaXMtPmxwdnRibF9wcm94eSk7CiAgICByZXR1cm4gU19PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKiogT0xFIFByb3h5L1N0dWIgRmFjdG9yeSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJClBTRmFjQnVmX1F1ZXJ5SW50ZXJmYWNlKExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlLCBSRUZJSUQgaWlkLCBMUFZPSUQgKnBwdikgewogICAgaWYgKElzRXF1YWxJSUQoaWlkLCZJSURfSVBTRmFjdG9yeUJ1ZmZlcil8fElzRXF1YWxJSUQoaWlkLCZJSURfSVVua25vd24pKSB7CgkqcHB2ID0gKExQVk9JRClpZmFjZTsKCS8qIE5vIHJlZiBjb3VudGluZywgc3RhdGljIGNsYXNzICovCglyZXR1cm4gU19PSzsKICAgIH0KICAgIEZJWE1FKCIoJXMpIHVua25vd24gSUlEP1xuIixkZWJ1Z3N0cl9ndWlkKGlpZCkpOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUFNGYWNCdWZfQWRkUmVmKExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlKSB7IHJldHVybiAyOyB9CnN0YXRpYyBVTE9ORyBXSU5BUEkgUFNGYWNCdWZfUmVsZWFzZShMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSkgeyByZXR1cm4gMTsgfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClBTRmFjQnVmX0NyZWF0ZVByb3h5KAogICAgTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UsIElVbmtub3duKiBwVW5rT3V0ZXIsIFJFRklJRCByaWlkLAogICAgSVJwY1Byb3h5QnVmZmVyICoqcHBQcm94eSwgTFBWT0lEICpwcHYKKSB7CiAgICBpZiAoSXNFcXVhbElJRCgmSUlEX0lDbGFzc0ZhY3RvcnkscmlpZCkpCglyZXR1cm4gQ0ZQcm94eV9Db25zdHJ1Y3QocFVua091dGVyLCBwcHYsKExQVk9JRCopcHBQcm94eSk7CiAgICBlbHNlIGlmIChJc0VxdWFsSUlEKCZJSURfSVJlbVVua25vd24scmlpZCkpCglyZXR1cm4gUmVtVW5rUHJveHlfQ29uc3RydWN0KHBVbmtPdXRlciwgcHB2LChMUFZPSUQqKXBwUHJveHkpOwogICAgRklYTUUoInByb3h5aW5nIG5vdCBpbXBsZW1lbnRlZCBmb3IgKCVzKSB5ZXQhXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClBTRmFjQnVmX0NyZWF0ZVN0dWIoCiAgICBMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSwgUkVGSUlEIHJpaWQsSVVua25vd24gKnBVbmtTZXJ2ZXIsCiAgICBJUnBjU3R1YkJ1ZmZlcioqIHBwU3R1YgopIHsKICAgIEhSRVNVTFQgaHJlczsKCiAgICBUUkFDRSgiKCVzLCVwLCVwKVxuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBVbmtTZXJ2ZXIscHBTdHViKTsKCiAgICBpZiAoSXNFcXVhbElJRCgmSUlEX0lDbGFzc0ZhY3RvcnksIHJpaWQpIHx8CiAgICAgICAgSXNFcXVhbElJRCgmSUlEX0lVbmtub3duLCByaWlkKSAvKiBGSVhNRTogZml4dXAgc3R1YiBtYW5hZ2VyIGFuZCByZW1vdmUgdGhpcyovKSB7CglocmVzID0gQ0ZTdHViX0NvbnN0cnVjdChwcFN0dWIpOwoJaWYgKCFocmVzKQoJICAgIElScGNTdHViQnVmZmVyX0Nvbm5lY3QoKCpwcFN0dWIpLHBVbmtTZXJ2ZXIpOwoJcmV0dXJuIGhyZXM7CiAgICB9IGVsc2UgaWYgKElzRXF1YWxJSUQoJklJRF9JUmVtVW5rbm93bixyaWlkKSkgewoJaHJlcyA9IFJlbVVua1N0dWJfQ29uc3RydWN0KHBwU3R1Yik7CglpZiAoIWhyZXMpCgkgICAgSVJwY1N0dWJCdWZmZXJfQ29ubmVjdCgoKnBwU3R1YikscFVua1NlcnZlcik7CglyZXR1cm4gaHJlczsKICAgIH0KICAgIEZJWE1FKCJzdHViYmluZyBub3QgaW1wbGVtZW50ZWQgZm9yICglcykgeWV0IVxuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBJUFNGYWN0b3J5QnVmZmVyVnRibCBwc2ZhY2J1ZnZ0YmwgPSB7CiAgICBQU0ZhY0J1Zl9RdWVyeUludGVyZmFjZSwKICAgIFBTRmFjQnVmX0FkZFJlZiwKICAgIFBTRmFjQnVmX1JlbGVhc2UsCiAgICBQU0ZhY0J1Zl9DcmVhdGVQcm94eSwKICAgIFBTRmFjQnVmX0NyZWF0ZVN0dWIKfTsKCi8qIFRoaXMgaXMgdGhlIHdob2xlIFBTRmFjdG9yeUJ1ZmZlciBvYmplY3QsIGp1c3QgdGhlIHZ0YWJsZXB0ciAqLwpzdGF0aWMgSVBTRmFjdG9yeUJ1ZmZlclZ0YmwgKmxwcHNmYWMgPSAmcHNmYWNidWZ2dGJsOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBEbGxHZXRDbGFzc09iamVjdCBbT0xFMzIuQF0KICovCkhSRVNVTFQgV0lOQVBJIE9MRTMyX0RsbEdldENsYXNzT2JqZWN0KFJFRkNMU0lEIHJjbHNpZCwgUkVGSUlEIGlpZCxMUFZPSUQgKnBwdikKewogICAgKnBwdiA9IE5VTEw7CiAgICBpZiAoSXNFcXVhbElJRChyY2xzaWQsJkNMU0lEX1BTRmFjdG9yeUJ1ZmZlcikpIHsKCSpwcHYgPSAmbHBwc2ZhYzsKCXJldHVybiBTX09LOwogICAgfQogICAgaWYgKElzRXF1YWxJSUQocmNsc2lkLCZDTFNJRF9EZk1hcnNoYWwpJiYoCgkJSXNFcXVhbElJRChpaWQsJklJRF9JQ2xhc3NGYWN0b3J5KSB8fAoJCUlzRXF1YWxJSUQoaWlkLCZJSURfSVVua25vd24pCgkpCiAgICApCglyZXR1cm4gTUFSU0hBTF9HZXRTdGFuZGFyZE1hcnNoYWxDRihwcHYpOwogICAgaWYgKElzRXF1YWxJSUQocmNsc2lkLCZDTFNJRF9TdGRHbG9iYWxJbnRlcmZhY2VUYWJsZSkgJiYgKElzRXF1YWxJSUQoaWlkLCZJSURfSUNsYXNzRmFjdG9yeSkgfHwgSXNFcXVhbElJRChpaWQsJklJRF9JVW5rbm93bikpKQogICAgICAgIHJldHVybiBTdGRHbG9iYWxJbnRlcmZhY2VUYWJsZV9HZXRGYWN0b3J5KHBwdik7CgogICAgRklYTUUoIlxuXHRDTFNJRDpcdCVzLFxuXHRJSUQ6XHQlc1xuIixkZWJ1Z3N0cl9ndWlkKHJjbHNpZCksZGVidWdzdHJfZ3VpZChpaWQpKTsKICAgIHJldHVybiBDTEFTU19FX0NMQVNTTk9UQVZBSUxBQkxFOwp9Cg==