LyoKICoJT0xFMzIgcHJveHkvc3R1YiBoYW5kbGVyCiAqCiAqICBDb3B5cmlnaHQgMjAwMiAgTWFyY3VzIE1laXNzbmVyCiAqICBDb3B5cmlnaHQgMjAwMSAgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKLyogRG9jdW1lbnRhdGlvbiBvbiBNU0ROOgogKgogKiAoVG9wIGxldmVsIENPTSBkb2N1bWVudGF0aW9uKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2RuYW5jaG9yL2h0bWwvY29tcG9uZW50ZGV2ZWxvcG1lbnRhbmsuYXNwCiAqCiAqIChDT00gUHJveHkpCiAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvY29tL2h0bS9jb21leHRfMXEwcC5hc3AKICoKICogKENPTSBTdHViKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG0vY29tZXh0XzFsaWEuYXNwCiAqCiAqIChNYXJzaGFsKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG0vY29tZXh0XzFnZm4uYXNwCiAqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KI2RlZmluZSBOT05BTUVMRVNTU1RSVUNUCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJvYmpiYXNlLmgiCiNpbmNsdWRlICJvbGUyLmgiCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgInd0eXBlcy5oIgoKI2luY2x1ZGUgImNvbXBvYmpfcHJpdmF0ZS5oIgojaW5jbHVkZSAibW9uaWtlci5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7Cgpjb25zdCBDTFNJRCBDTFNJRF9EZk1hcnNoYWwgICAgICAgPSB7IDB4MDAwMDAzMGIsIDAsIDAsIHsweGMwLCAwLCAwLCAwLCAwLCAwLCAwLCAweDQ2fSB9Owpjb25zdCBDTFNJRCBDTFNJRF9QU0ZhY3RvcnlCdWZmZXIgPSB7IDB4MDAwMDAzMjAsIDAsIDAsIHsweGMwLCAwLCAwLCAwLCAwLCAwLCAwLCAweDQ2fSB9OwoKLyogRnJvbTogaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9saWJyYXJ5L2VuLXVzL2NvbS9jbWlfbV80bGRhLmFzcAogKgogKiBUaGUgZmlyc3QgdGltZSBhIGNsaWVudCByZXF1ZXN0cyBhIHBvaW50ZXIgdG8gYW4gaW50ZXJmYWNlIG9uIGEKICogcGFydGljdWxhciBvYmplY3QsIENPTSBsb2FkcyBhbiBJQ2xhc3NGYWN0b3J5IHN0dWIgaW4gdGhlIHNlcnZlcgogKiBwcm9jZXNzIGFuZCB1c2VzIGl0IHRvIG1hcnNoYWwgdGhlIGZpcnN0IHBvaW50ZXIgYmFjayB0byB0aGUKICogY2xpZW50LiBJbiB0aGUgY2xpZW50IHByb2Nlc3MsIENPTSBsb2FkcyB0aGUgZ2VuZXJpYyBwcm94eSBmb3IgdGhlCiAqIGNsYXNzIGZhY3Rvcnkgb2JqZWN0IGFuZCBjYWxscyBpdHMgaW1wbGVtZW50YXRpb24gb2YgSU1hcnNoYWwgdG8KICogdW5tYXJzaGFsIHRoYXQgZmlyc3QgcG9pbnRlci4gQ09NIHRoZW4gY3JlYXRlcyB0aGUgZmlyc3QgaW50ZXJmYWNlCiAqIHByb3h5IGFuZCBoYW5kcyBpdCBhIHBvaW50ZXIgdG8gdGhlIFJQQyBjaGFubmVsLiBGaW5hbGx5LCBDT00gcmV0dXJucwogKiB0aGUgSUNsYXNzRmFjdG9yeSBwb2ludGVyIHRvIHRoZSBjbGllbnQsIHdoaWNoIHVzZXMgaXQgdG8gY2FsbAogKiBJQ2xhc3NGYWN0b3J5OjpDcmVhdGVJbnN0YW5jZSwgcGFzc2luZyBpdCBhIHJlZmVyZW5jZSB0byB0aGUgaW50ZXJmYWNlLgogKgogKiBCYWNrIGluIHRoZSBzZXJ2ZXIgcHJvY2VzcywgQ09NIG5vdyBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZQogKiBvYmplY3QsIGFsb25nIHdpdGggYSBzdHViIGZvciB0aGUgcmVxdWVzdGVkIGludGVyZmFjZS4gVGhpcyBzdHViIG1hcnNoYWxzCiAqIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBiYWNrIHRvIHRoZSBjbGllbnQgcHJvY2Vzcywgd2hlcmUgYW5vdGhlciBvYmplY3QKICogcHJveHkgaXMgY3JlYXRlZCwgdGhpcyB0aW1lIGZvciB0aGUgb2JqZWN0IGl0c2VsZi4gQWxzbyBjcmVhdGVkIGlzIGEKICogcHJveHkgZm9yIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlLCBhIHBvaW50ZXIgdG8gd2hpY2ggaXMgcmV0dXJuZWQgdG8KICogdGhlIGNsaWVudC4gV2l0aCBzdWJzZXF1ZW50IGNhbGxzIHRvIG90aGVyIGludGVyZmFjZXMgb24gdGhlIG9iamVjdCwKICogQ09NIHdpbGwgbG9hZCB0aGUgYXBwcm9wcmlhdGUgaW50ZXJmYWNlIHN0dWJzIGFuZCBwcm94aWVzIGFzIG5lZWRlZC4KICovCnR5cGVkZWYgc3RydWN0IF9DRlN0dWIgewogICAgY29uc3QgSVJwY1N0dWJCdWZmZXJWdGJsICAgKmxwdnRibDsKICAgIExPTkcJCQlyZWY7CgogICAgTFBVTktOT1dOCQkJcFVua1NlcnZlcjsKfSBDRlN0dWI7CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKQ0ZTdHViX1F1ZXJ5SW50ZXJmYWNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KSB7CiAgICBpZiAoSXNFcXVhbElJRCgmSUlEX0lVbmtub3duLHJpaWQpfHxJc0VxdWFsSUlEKCZJSURfSVJwY1N0dWJCdWZmZXIscmlpZCkpIHsKCSpwcHYgPSAoTFBWT0lEKWlmYWNlOwoJSVVua25vd25fQWRkUmVmKGlmYWNlKTsKCXJldHVybiBTX09LOwogICAgfQogICAgRklYTUUoIiglcyksIGludGVyZmFjZSBub3Qgc3VwcG9ydGVkLlxuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCkNGU3R1Yl9BZGRSZWYoTFBSUENTVFVCQlVGRkVSIGlmYWNlKSB7CiAgICBDRlN0dWIgKlRoaXMgPSAoQ0ZTdHViICopaWZhY2U7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKQ0ZTdHViX1JlbGVhc2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlKSB7CiAgICBDRlN0dWIgKlRoaXMgPSAoQ0ZTdHViICopaWZhY2U7CiAgICBVTE9ORyByZWY7CgogICAgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CiAgICBpZiAoIXJlZikgewogICAgICAgIElScGNTdHViQnVmZmVyX0Rpc2Nvbm5lY3QoaWZhY2UpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKICAgIH0KICAgIHJldHVybiByZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpDRlN0dWJfQ29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsIElVbmtub3duICpwVW5rU2VydmVyKSB7CiAgICBDRlN0dWIgKlRoaXMgPSAoQ0ZTdHViICopaWZhY2U7CgogICAgVGhpcy0+cFVua1NlcnZlciA9IHBVbmtTZXJ2ZXI7CiAgICBJVW5rbm93bl9BZGRSZWYocFVua1NlcnZlcik7CiAgICByZXR1cm4gU19PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJCkNGU3R1Yl9EaXNjb25uZWN0KExQUlBDU1RVQkJVRkZFUiBpZmFjZSkgewogICAgQ0ZTdHViICpUaGlzID0gKENGU3R1YiAqKWlmYWNlOwoKICAgIGlmIChUaGlzLT5wVW5rU2VydmVyKSB7CiAgICAgICAgSVVua25vd25fUmVsZWFzZShUaGlzLT5wVW5rU2VydmVyKTsKICAgICAgICBUaGlzLT5wVW5rU2VydmVyID0gTlVMTDsKICAgIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCkNGU3R1Yl9JbnZva2UoCiAgICBMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsUlBDT0xFTUVTU0FHRSogbXNnLElScGNDaGFubmVsQnVmZmVyKiBjaGFuYnVmCikgewogICAgQ0ZTdHViICpUaGlzID0gKENGU3R1YiAqKWlmYWNlOwogICAgSFJFU1VMVCBocmVzOwoKICAgIGlmIChtc2ctPmlNZXRob2QgPT0gMykgeyAvKiBDcmVhdGVJbnN0YW5jZSAqLwoJSUlEIGlpZDsKCUlDbGFzc0ZhY3RvcnkJKmNsYXNzZmFjOwoJSVVua25vd24JKnBwdjsKCUlTdHJlYW0JCSpwU3RtOwoJU1RBVFNURwkJc3RzdGc7CglVTEFSR0VfSU5URUdFUgluZXdwb3M7CglMQVJHRV9JTlRFR0VSCXNlZWt0bzsKCVVMT05HCQlyZXM7CgoJaWYgKG1zZy0+Y2JCdWZmZXIgPCBzaXplb2YoSUlEKSkgewoJICAgIEZJWE1FKCJOb3QgZW5vdWdoIGJ5dGVzIGluIGJ1ZmZlciAoJWxkIGluc3RlYWQgb2YgJWQpP1xuIixtc2ctPmNiQnVmZmVyLHNpemVvZihJSUQpKTsKCSAgICByZXR1cm4gRV9GQUlMOwoJfQoJbWVtY3B5KCZpaWQsbXNnLT5CdWZmZXIsc2l6ZW9mKGlpZCkpOwoJVFJBQ0UoIi0+Q3JlYXRlSW5zdGFuY2UoJXMpXG4iLGRlYnVnc3RyX2d1aWQoJmlpZCkpOwoJaHJlcyA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKFRoaXMtPnBVbmtTZXJ2ZXIsJklJRF9JQ2xhc3NGYWN0b3J5LChMUFZPSUQqKSZjbGFzc2ZhYyk7CglpZiAoaHJlcykgewoJICAgIEZJWE1FKCJPbGUgc2VydmVyIGRvZXMgbm90IHByb3ZpZGUgYW4gSUNsYXNzRmFjdG9yeT9cbiIpOwoJICAgIHJldHVybiBocmVzOwoJfQoJaHJlcyA9IElDbGFzc0ZhY3RvcnlfQ3JlYXRlSW5zdGFuY2UoY2xhc3NmYWMsTlVMTCwmaWlkLChMUFZPSUQqKSZwcHYpOwoJSUNsYXNzRmFjdG9yeV9SZWxlYXNlKGNsYXNzZmFjKTsKCWlmIChocmVzKSB7CgkgICAgbXNnLT5jYkJ1ZmZlciA9IDA7CgkgICAgRklYTUUoIkZhaWxlZCB0byBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgJXNcbiIsZGVidWdzdHJfZ3VpZCgmaWlkKSk7CgkgICAgcmV0dXJuIGhyZXM7Cgl9CglocmVzID0gQ3JlYXRlU3RyZWFtT25IR2xvYmFsKDAsVFJVRSwmcFN0bSk7CglpZiAoaHJlcykgewoJICAgIEZJWE1FKCJGYWlsZWQgdG8gY3JlYXRlIHN0cmVhbSBvbiBoZ2xvYmFsXG4iKTsKCSAgICByZXR1cm4gaHJlczsKCX0KCWhyZXMgPSBDb01hcnNoYWxJbnRlcmZhY2UocFN0bSwmaWlkLHBwdiwwLE5VTEwsMCk7CglJVW5rbm93bl9SZWxlYXNlKChJVW5rbm93biopcHB2KTsKCWlmIChocmVzKSB7CgkgICAgRklYTUUoIkNvTWFyc2hhbEludGVyZmFjZSBmYWlsZWQsICVseCFcbiIsaHJlcyk7CgkgICAgbXNnLT5jYkJ1ZmZlciA9IDA7CgkgICAgcmV0dXJuIGhyZXM7Cgl9CglocmVzID0gSVN0cmVhbV9TdGF0KHBTdG0sJnN0c3RnLDApOwoJaWYgKGhyZXMpIHsKCSAgICBGSVhNRSgiU3RhdCBmYWlsZWQuXG4iKTsKCSAgICByZXR1cm4gaHJlczsKCX0KCgltc2ctPmNiQnVmZmVyID0gc3RzdGcuY2JTaXplLnUuTG93UGFydDsKCiAgICAgICAgSV9ScGNHZXRCdWZmZXIoKFJQQ19NRVNTQUdFICopbXNnKTsKICAgICAgICBpZiAoaHJlcykgcmV0dXJuIGhyZXM7CgoJc2Vla3RvLnUuTG93UGFydCA9IDA7c2Vla3RvLnUuSGlnaFBhcnQgPSAwOwoJaHJlcyA9IElTdHJlYW1fU2VlayhwU3RtLHNlZWt0byxTRUVLX1NFVCwmbmV3cG9zKTsKCWlmIChocmVzKSB7CgkgICAgRklYTUUoIklTdHJlYW1fU2VlayBmYWlsZWQsICVseFxuIixocmVzKTsKCSAgICByZXR1cm4gaHJlczsKCX0KCWhyZXMgPSBJU3RyZWFtX1JlYWQocFN0bSxtc2ctPkJ1ZmZlcixtc2ctPmNiQnVmZmVyLCZyZXMpOwoJaWYgKGhyZXMpIHsKCSAgICBGSVhNRSgiU3RyZWFtIFJlYWQgZmFpbGVkLCAlbHhcbiIsaHJlcyk7CgkgICAgcmV0dXJuIGhyZXM7Cgl9CglJU3RyZWFtX1JlbGVhc2UocFN0bSk7CglyZXR1cm4gU19PSzsKICAgIH0KICAgIEZJWE1FKCIoJXAsJXApLCBzdHViIVxuIixtc2csY2hhbmJ1Zik7CiAgICBGSVhNRSgiaU1ldGhvZCBpcyAlbGRcbiIsbXNnLT5pTWV0aG9kKTsKICAgIEZJWE1FKCJjYkJ1ZmZlciBpcyAlbGRcbiIsbXNnLT5jYkJ1ZmZlcik7CiAgICByZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgTFBSUENTVFVCQlVGRkVSIFdJTkFQSQpDRlN0dWJfSXNJSURTdXBwb3J0ZWQoTFBSUENTVFVCQlVGRkVSIGlmYWNlLFJFRklJRCByaWlkKSB7CiAgICBGSVhNRSgiKCVzKSwgc3R1YiFcbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpDRlN0dWJfQ291bnRSZWZzKExQUlBDU1RVQkJVRkZFUiBpZmFjZSkgewogICAgRklYTUUoIigpLCBzdHViIVxuIik7CiAgICByZXR1cm4gMTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCkNGU3R1Yl9EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSx2b2lkKiogcHB2KSB7CiAgICBGSVhNRSgiKCVwKSwgc3R1YiFcbiIscHB2KTsKICAgIHJldHVybiBFX0ZBSUw7Cn0Kc3RhdGljIHZvaWQgICAgV0lOQVBJCkNGU3R1Yl9EZWJ1Z1NlcnZlclJlbGVhc2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLHZvaWQgKnB2KSB7CiAgICBGSVhNRSgiKCVwKSwgc3R1YiFcbiIscHYpOwp9CgpzdGF0aWMgY29uc3QgSVJwY1N0dWJCdWZmZXJWdGJsIGNmc3R1YnZ0ID0gewogICAgQ0ZTdHViX1F1ZXJ5SW50ZXJmYWNlLAogICAgQ0ZTdHViX0FkZFJlZiwKICAgIENGU3R1Yl9SZWxlYXNlLAogICAgQ0ZTdHViX0Nvbm5lY3QsCiAgICBDRlN0dWJfRGlzY29ubmVjdCwKICAgIENGU3R1Yl9JbnZva2UsCiAgICBDRlN0dWJfSXNJSURTdXBwb3J0ZWQsCiAgICBDRlN0dWJfQ291bnRSZWZzLAogICAgQ0ZTdHViX0RlYnVnU2VydmVyUXVlcnlJbnRlcmZhY2UsCiAgICBDRlN0dWJfRGVidWdTZXJ2ZXJSZWxlYXNlCn07CgpzdGF0aWMgSFJFU1VMVApDRlN0dWJfQ29uc3RydWN0KExQUlBDU1RVQkJVRkZFUiAqcHB2KSB7CiAgICBDRlN0dWIgKmNmc3R1YjsKICAgIGNmc3R1YiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKENGU3R1YikpOwogICAgaWYgKCFjZnN0dWIpCglyZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgICpwcHYgPSAoTFBSUENTVFVCQlVGRkVSKWNmc3R1YjsKICAgIGNmc3R1Yi0+bHB2dGJsCT0gJmNmc3R1YnZ0OwogICAgY2ZzdHViLT5yZWYJCT0gMTsKICAgIHJldHVybiBTX09LOwp9CgovKiBTaW5jZSB3ZSBjcmVhdGUgcHJveHkgYnVmZmVycyBhbmQgY2xhc3NmYWN0b3J5IGluIGEgcGFpciwgdGhlcmUgaXMKICogbm8gbmVlZCBmb3IgMiBzZXBhcmF0ZSBzdHJ1Y3RzLiBKdXN0IHB1dCB0aGVtIGluIG9uZSwgYnV0IHJlbWVtYmVyCiAqIHRoZSByZWZjb3VudC4KICovCnR5cGVkZWYgc3RydWN0IF9DRlByb3h5IHsKICAgIGNvbnN0IElDbGFzc0ZhY3RvcnlWdGJsCQkqbHB2dGJsX2NmOwogICAgY29uc3QgSVJwY1Byb3h5QnVmZmVyVnRibAkqbHB2dGJsX3Byb3h5OwogICAgTE9ORwkJCQlyZWY7CgogICAgSVJwY0NoYW5uZWxCdWZmZXIJCQkqY2hhbmJ1ZjsKICAgIElVbmtub3duICpvdXRlcl91bmtub3duOwp9IENGUHJveHk7CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVJwY1Byb3h5QnVmZmVySW1wbF9RdWVyeUludGVyZmFjZShMUFJQQ1BST1hZQlVGRkVSIGlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHB2KSB7CiAgICAqcHB2ID0gTlVMTDsKICAgIGlmIChJc0VxdWFsSUlEKHJpaWQsJklJRF9JUnBjUHJveHlCdWZmZXIpfHxJc0VxdWFsSUlEKHJpaWQsJklJRF9JVW5rbm93bikpIHsKCUlScGNQcm94eUJ1ZmZlcl9BZGRSZWYoaWZhY2UpOwoJKnBwdiA9IChMUFZPSUQpaWZhY2U7CglyZXR1cm4gU19PSzsKICAgIH0KICAgIEZJWE1FKCIoJXMpLCBubyBpbnRlcmZhY2UuXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSVJwY1Byb3h5QnVmZmVySW1wbF9BZGRSZWYoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX3Byb3h5LGlmYWNlKTsKICAgIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJUnBjUHJveHlCdWZmZXJJbXBsX1JlbGVhc2UoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX3Byb3h5LGlmYWNlKTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICAgIGlmICghcmVmKSB7CiAgICAgICAgSVJwY1Byb3h5QnVmZmVyX0Rpc2Nvbm5lY3QoaWZhY2UpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKICAgIH0KICAgIHJldHVybiByZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUnBjUHJveHlCdWZmZXJJbXBsX0Nvbm5lY3QoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSxJUnBjQ2hhbm5lbEJ1ZmZlciogcFJwY0NoYW5uZWxCdWZmZXIpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CgogICAgVGhpcy0+Y2hhbmJ1ZiA9IHBScGNDaGFubmVsQnVmZmVyOwogICAgSVJwY0NoYW5uZWxCdWZmZXJfQWRkUmVmKFRoaXMtPmNoYW5idWYpOwogICAgcmV0dXJuIFNfT0s7Cn0Kc3RhdGljIHZvaWQgV0lOQVBJIElScGNQcm94eUJ1ZmZlckltcGxfRGlzY29ubmVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwogICAgaWYgKFRoaXMtPmNoYW5idWYpIHsKCUlScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UoVGhpcy0+Y2hhbmJ1Zik7CglUaGlzLT5jaGFuYnVmID0gTlVMTDsKICAgIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCkNGUHJveHlfUXVlcnlJbnRlcmZhY2UoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KSB7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfY2YsaWZhY2UpOwogICAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pIHJldHVybiBJVW5rbm93bl9RdWVyeUludGVyZmFjZShUaGlzLT5vdXRlcl91bmtub3duLCByaWlkLCBwcHYpOwogICAgKnBwdiA9IE5VTEw7CiAgICBpZiAoSXNFcXVhbElJRCgmSUlEX0lDbGFzc0ZhY3RvcnkscmlpZCkgfHwgSXNFcXVhbElJRCgmSUlEX0lVbmtub3duLHJpaWQpKSB7CgkqcHB2ID0gKExQVk9JRClpZmFjZTsKCUlDbGFzc0ZhY3RvcnlfQWRkUmVmKGlmYWNlKTsKCXJldHVybiBTX09LOwogICAgfQogICAgaWYgKElzRXF1YWxJSUQocmlpZCwmSUlEX0lNYXJzaGFsKSkgLyoganVzdCB0byBhdm9pZCBkZWJ1ZyBvdXRwdXQgKi8KCXJldHVybiBFX05PSU5URVJGQUNFOwogICAgRklYTUUoIlVuaGFuZGxlZCBpbnRlcmZhY2U6ICVzXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBDRlByb3h5X0FkZFJlZihMUENMQVNTRkFDVE9SWSBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX2NmLGlmYWNlKTsKICAgIGlmIChUaGlzLT5vdXRlcl91bmtub3duKSByZXR1cm4gSVVua25vd25fQWRkUmVmKFRoaXMtPm91dGVyX3Vua25vd24pOwogICAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgQ0ZQcm94eV9SZWxlYXNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlKSB7CiAgICBVTE9ORyByZWY7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfY2YsaWZhY2UpOwogICAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pCiAgICAgICAgcmVmID0gSVVua25vd25fUmVsZWFzZShUaGlzLT5vdXRlcl91bmtub3duKTsKICAgIGVsc2UgICAgCiAgICAgICAgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgaWYgKCFyZWYpIHsKICAgICAgCWlmIChUaGlzLT5jaGFuYnVmKSBJUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKFRoaXMtPmNoYW5idWYpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKICAgIH0KICAgIHJldHVybiByZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBDRlByb3h5X0NyZWF0ZUluc3RhbmNlKAogICAgTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsCiAgICBMUFVOS05PV04gcFVua091dGVyLC8qIFtpbl0gKi8KICAgIFJFRklJRCByaWlkLAkvKiBbaW5dICovCiAgICBMUFZPSUQgKnBwdgkJLyogW291dF0gKi8KKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfY2YsaWZhY2UpOwogICAgSFJFU1VMVAkJaHJlczsKICAgIExQU1RSRUFNCQlwU3RyZWFtOwogICAgSEdMT0JBTAkJaEdsb2JhbDsKICAgIFVMT05HCQlzcnN0YXR1czsKICAgIFJQQ09MRU1FU1NBR0UJbXNnOwoKICAgIFRSQUNFKCIoJXAsJXMsJXApXG4iLHBVbmtPdXRlcixkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwdik7CgogICAgLyogU2VuZCBDcmVhdGVJbnN0YW5jZSB0byB0aGUgcmVtb3RlIGNsYXNzZmFjdG9yeS4KICAgICAqCiAgICAgKiBEYXRhOiBPbmx5IHRoZSAnSUlEJy4KICAgICAqLwogICAgbXNnLmlNZXRob2QgID0gMzsKICAgIG1zZy5jYkJ1ZmZlciA9IHNpemVvZigqcmlpZCk7CiAgICBtc2cuQnVmZmVyCSA9IE5VTEw7CiAgICBocmVzID0gSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKFRoaXMtPmNoYW5idWYsJm1zZywmSUlEX0lDbGFzc0ZhY3RvcnkpOwogICAgaWYgKGhyZXMpIHsKCUZJWE1FKCJJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIgZmFpbGVkIHdpdGggJWx4P1xuIixocmVzKTsKCXJldHVybiBocmVzOwogICAgfQogICAgbWVtY3B5KG1zZy5CdWZmZXIscmlpZCxzaXplb2YoKnJpaWQpKTsKICAgIGhyZXMgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShUaGlzLT5jaGFuYnVmLCZtc2csJnNyc3RhdHVzKTsKICAgIGlmIChocmVzKSB7CglGSVhNRSgiSVJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUgZmFpbGVkIHdpdGggJWx4P1xuIixocmVzKTsKCXJldHVybiBocmVzOwogICAgfQoKICAgIGlmICghbXNnLmNiQnVmZmVyKSAvKiBpbnRlcmZhY2Ugbm90IGZvdW5kIG9uIHJlbW90ZSAqLwoJcmV0dXJuIHNyc3RhdHVzOwoKICAgIC8qIFdlIGdvdCBiYWNrOiBbTWFyc2hhbGxlZCBJbnRlcmZhY2UgZGF0YV0gKi8KICAgIFRSQUNFKCJnb3QgJWxkIGJ5dGVzIGRhdGEuXG4iLG1zZy5jYkJ1ZmZlcik7CiAgICBoR2xvYmFsID0gR2xvYmFsQWxsb2MoR01FTV9NT1ZFQUJMRXxHTUVNX05PRElTQ0FSRHxHTUVNX1NIQVJFLG1zZy5jYkJ1ZmZlcik7CiAgICBtZW1jcHkoR2xvYmFsTG9jayhoR2xvYmFsKSxtc2cuQnVmZmVyLG1zZy5jYkJ1ZmZlcik7CiAgICBocmVzID0gQ3JlYXRlU3RyZWFtT25IR2xvYmFsKGhHbG9iYWwsVFJVRSwmcFN0cmVhbSk7CiAgICBpZiAoaHJlcykgewoJRklYTUUoIkNyZWF0ZVN0cmVhbU9uSEdsb2JhbCBmYWlsZWQgd2l0aCAlbHhcbiIsaHJlcyk7CglyZXR1cm4gaHJlczsKICAgIH0KICAgIGhyZXMgPSBDb1VubWFyc2hhbEludGVyZmFjZSgKCSAgICBwU3RyZWFtLAoJICAgIHJpaWQsCgkgICAgcHB2CiAgICApOwogICAgSVN0cmVhbV9SZWxlYXNlKHBTdHJlYW0pOyAvKiBEb2VzIEdsb2JhbEZyZWUgaEdsb2JhbCB0b28uICovCiAgICBpZiAoaHJlcykgewoJRklYTUUoIkNvTWFyc2hhbEludGVyZmFjZSBmYWlsZWQsICVseFxuIixocmVzKTsKCXJldHVybiBocmVzOwogICAgfQogICAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBDRlByb3h5X0xvY2tTZXJ2ZXIoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsQk9PTCBmTG9jaykgewogICAgLypJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfY2YsaWZhY2UpOyovCiAgICBGSVhNRSgiKCVkKSwgc3R1YiFcbiIsZkxvY2spOwogICAgLyogYmFzaWNhbGx5OiB3cml0ZSBCT09MLCByZWFkIGVtcHR5ICovCiAgICByZXR1cm4gU19PSzsKfQoKc3RhdGljIGNvbnN0IElScGNQcm94eUJ1ZmZlclZ0YmwgcHNwYnZ0YmwgPSB7CiAgICBJUnBjUHJveHlCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSVJwY1Byb3h5QnVmZmVySW1wbF9BZGRSZWYsCiAgICBJUnBjUHJveHlCdWZmZXJJbXBsX1JlbGVhc2UsCiAgICBJUnBjUHJveHlCdWZmZXJJbXBsX0Nvbm5lY3QsCiAgICBJUnBjUHJveHlCdWZmZXJJbXBsX0Rpc2Nvbm5lY3QKfTsKc3RhdGljIGNvbnN0IElDbGFzc0ZhY3RvcnlWdGJsIGNmcHJveHl2dCA9IHsKICAgIENGUHJveHlfUXVlcnlJbnRlcmZhY2UsCiAgICBDRlByb3h5X0FkZFJlZiwKICAgIENGUHJveHlfUmVsZWFzZSwKICAgIENGUHJveHlfQ3JlYXRlSW5zdGFuY2UsCiAgICBDRlByb3h5X0xvY2tTZXJ2ZXIKfTsKCnN0YXRpYyBIUkVTVUxUCkNGUHJveHlfQ29uc3RydWN0KElVbmtub3duICpwVW5rT3V0ZXIsIExQVk9JRCAqcHB2LExQVk9JRCAqcHBQcm94eSkgewogICAgQ0ZQcm94eSAqY2Y7CgogICAgY2YgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZihDRlByb3h5KSk7CiAgICBpZiAoIWNmKQoJcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgY2YtPmxwdnRibF9jZgk9ICZjZnByb3h5dnQ7CiAgICBjZi0+bHB2dGJsX3Byb3h5CT0gJnBzcGJ2dGJsOwogICAgLyogb25lIHJlZmVyZW5jZSBmb3IgdGhlIHByb3h5IGJ1ZmZlciAqLwogICAgY2YtPnJlZgkJPSAxOwogICAgY2YtPm91dGVyX3Vua25vd24gPSBwVW5rT3V0ZXI7CiAgICAqcHB2CQk9ICYoY2YtPmxwdnRibF9jZik7CiAgICAqcHBQcm94eQkJPSAmKGNmLT5scHZ0YmxfcHJveHkpOwogICAgLyogYW5kIG9uZSByZWZlcmVuY2UgZm9yIHRoZSBvYmplY3QgKi8KICAgIElVbmtub3duX0FkZFJlZigoSVVua25vd24gKikqcHB2KTsKICAgIHJldHVybiBTX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKiBJUmVtVW5rbm93biBQcm94eS9TdHViICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgY29uc3QgSVJwY1N0dWJCdWZmZXJWdGJsICpscFZ0Ymw7CiAgICBMT05HIHJlZnM7CiAgICBJUmVtVW5rbm93biAqaWZhY2U7Cn0gUmVtVW5rU3R1YjsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtTdHViX1F1ZXJ5SW50ZXJmYWNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKCQkJCQkgICAgIFJFRklJRCByaWlkLAoJCQkJCSAgICAgTFBWT0lEICpvYmopCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+UXVlcnlJbnRlcmZhY2UoJXMsJXApXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxvYmopOwogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLHJpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSVJwY1N0dWJCdWZmZXIscmlpZCkpIHsKICAgICpvYmogPSBUaGlzOwogICAgcmV0dXJuIFNfT0s7CiAgfQogIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJlbVVua1N0dWJfQWRkUmVmKExQUlBDU1RVQkJVRkZFUiBpZmFjZSkKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5BZGRSZWYoKVxuIixUaGlzKTsKICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZnMpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJlbVVua1N0dWJfUmVsZWFzZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBVTE9ORyByZWZzOwogIFRSQUNFKCIoJXApLT5SZWxlYXNlKClcbiIsVGhpcyk7CiAgcmVmcyA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWZzKTsKICBpZiAoIXJlZnMpCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICByZXR1cm4gcmVmczsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1N0dWJfQ29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkgICAgICBMUFVOS05PV04gbHBVbmtTZXJ2ZXIpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+Q29ubmVjdCglcClcbiIsVGhpcyxscFVua1NlcnZlcik7CiAgVGhpcy0+aWZhY2UgPSAoSVJlbVVua25vd24qKWxwVW5rU2VydmVyOwogIElSZW1Vbmtub3duX0FkZFJlZihUaGlzLT5pZmFjZSk7CiAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBSZW1VbmtTdHViX0Rpc2Nvbm5lY3QoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPkRpc2Nvbm5lY3QoKVxuIixUaGlzKTsKICBJVW5rbm93bl9SZWxlYXNlKFRoaXMtPmlmYWNlKTsKICBUaGlzLT5pZmFjZSA9IE5VTEw7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtTdHViX0ludm9rZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkgICAgIFBSUENPTEVNRVNTQUdFIHBNc2csCgkJCQkgICAgIExQUlBDQ0hBTk5FTEJVRkZFUiBwQ2hhbm5lbCkKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFVMT05HIGlNZXRob2QgPSBwTXNnLT5pTWV0aG9kOwogIExQQllURSBidWYgPSBwTXNnLT5CdWZmZXI7CiAgSFJFU1VMVCBociA9IFJQQ19FX0lOVkFMSURNRVRIT0Q7CgogIFRSQUNFKCIoJXApLT5JbnZva2UoJXAsJXApIG1ldGhvZCAlbGRcbiIsIFRoaXMsIHBNc2csIHBDaGFubmVsLCBpTWV0aG9kKTsKICBzd2l0Y2ggKGlNZXRob2QpCiAgewogIGNhc2UgMzogLyogUmVtUXVlcnlJbnRlcmZhY2UgKi8KICB7CiAgICBJUElEIGlwaWQ7CiAgICBVTE9ORyBjUmVmczsKICAgIFVTSE9SVCBjSWlkczsKICAgIElJRCAqaWlkczsKICAgIFJFTVFJUkVTVUxUICpwUUlSZXN1bHRzID0gTlVMTDsKCiAgICAvKiBpbiAqLwogICAgbWVtY3B5KCZpcGlkLCBidWYsIHNpemVvZihpcGlkKSk7CiAgICBidWYgKz0gc2l6ZW9mKGlwaWQpOwogICAgbWVtY3B5KCZjUmVmcywgYnVmLCBzaXplb2YoY1JlZnMpKTsKICAgIGJ1ZiArPSBzaXplb2YoY1JlZnMpOwogICAgbWVtY3B5KCZjSWlkcywgYnVmLCBzaXplb2YoY0lpZHMpKTsKICAgIGJ1ZiArPSBzaXplb2YoY0lpZHMpOwogICAgaWlkcyA9IChJSUQgKilidWY7CgogICAgaHIgPSBJUmVtVW5rbm93bl9SZW1RdWVyeUludGVyZmFjZShUaGlzLT5pZmFjZSwgJmlwaWQsIGNSZWZzLCBjSWlkcywgaWlkcywgJnBRSVJlc3VsdHMpOwoKICAgIC8qIG91dCAqLwogICAgcE1zZy0+Y2JCdWZmZXIgPSBjSWlkcyAqIHNpemVvZihSRU1RSVJFU1VMVCkgKyBzaXplb2YoSFJFU1VMVCk7CgogICAgSV9ScGNHZXRCdWZmZXIoKFJQQ19NRVNTQUdFICopcE1zZyk7CgogICAgYnVmID0gcE1zZy0+QnVmZmVyOwogICAgKihIUkVTVUxUICopYnVmID0gaHI7CiAgICBidWYgKz0gc2l6ZW9mKEhSRVNVTFQpOwogICAgCiAgICBpZiAoaHIpIHJldHVybiBocjsKICAgIC8qIEZJWE1FOiBwUUlSZXN1bHRzIGlzIGEgdW5pcXVlIHBvaW50ZXIgc28gcFFJUmVzdWx0cyBjYW4gYmUgTlVMTCEgKi8KICAgIG1lbWNweShidWYsIHBRSVJlc3VsdHMsIGNJaWRzICogc2l6ZW9mKFJFTVFJUkVTVUxUKSk7CgogICAgYnJlYWs7CiAgfQogIGNhc2UgNDogLyogUmVtQWRkUmVmICovCiAgewogICAgVVNIT1JUIGNJaWRzOwogICAgUkVNSU5URVJGQUNFUkVGICppcjsKICAgIEhSRVNVTFQgKnBSZXN1bHRzOwoKICAgIC8qIGluICovCiAgICBtZW1jcHkoJmNJaWRzLCBidWYsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIGlyID0gKFJFTUlOVEVSRkFDRVJFRiopYnVmOwogICAgcFJlc3VsdHMgPSBDb1Rhc2tNZW1BbGxvYyhjSWlkcyAqIHNpemVvZihIUkVTVUxUKSk7CiAgICBpZiAoIXBSZXN1bHRzKSByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBociA9IElSZW1Vbmtub3duX1JlbUFkZFJlZihUaGlzLT5pZmFjZSwgY0lpZHMsIGlyLCBwUmVzdWx0cyk7CgogICAgLyogb3V0ICovCiAgICBwTXNnLT5jYkJ1ZmZlciA9IGNJaWRzICogc2l6ZW9mKEhSRVNVTFQpOwoKICAgIElfUnBjR2V0QnVmZmVyKChSUENfTUVTU0FHRSAqKXBNc2cpOwogICAgaWYgKCFocikKICAgIHsKICAgICAgICBidWYgPSBwTXNnLT5CdWZmZXI7CiAgICAgICAgbWVtY3B5KGJ1ZiwgcFJlc3VsdHMsIGNJaWRzICogc2l6ZW9mKEhSRVNVTFQpKTsKICAgIH0KCiAgICBDb1Rhc2tNZW1GcmVlKHBSZXN1bHRzKTsKCiAgICBicmVhazsKICB9CiAgY2FzZSA1OiAvKiBSZW1SZWxlYXNlICovCiAgewogICAgVVNIT1JUIGNJaWRzOwogICAgUkVNSU5URVJGQUNFUkVGICppcjsKCiAgICAvKiBpbiAqLwogICAgbWVtY3B5KCZjSWlkcywgYnVmLCBzaXplb2YoVVNIT1JUKSk7CiAgICBidWYgKz0gc2l6ZW9mKFVTSE9SVCk7CiAgICBpciA9IChSRU1JTlRFUkZBQ0VSRUYqKWJ1ZjsKCiAgICBociA9IElSZW1Vbmtub3duX1JlbVJlbGVhc2UoVGhpcy0+aWZhY2UsIGNJaWRzLCBpcik7CgogICAgLyogb3V0ICovCiAgICBwTXNnLT5jYkJ1ZmZlciA9IDA7CiAgICBicmVhazsKICB9CiAgfQogIHJldHVybiBocjsKfQoKc3RhdGljIExQUlBDU1RVQkJVRkZFUiBXSU5BUEkgUmVtVW5rU3R1Yl9Jc0lJRFN1cHBvcnRlZChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJCSAgICAgUkVGSUlEIHJpaWQpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+SXNJSURTdXBwb3J0ZWQoJXMpXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICByZXR1cm4gSXNFcXVhbEdVSUQoJklJRF9JUmVtVW5rbm93biwgcmlpZCkgPyBpZmFjZSA6IE5VTEw7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUmVtVW5rU3R1Yl9Db3VudFJlZnMoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgRklYTUUoIiglcCktPkNvdW50UmVmcygpXG4iLCBUaGlzKTsKICByZXR1cm4gMTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1N0dWJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJCQlMUFZPSUQgKnBwdikKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIEZJWE1FKCIoJXApLT5EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlKCVwKVxuIixUaGlzLHBwdik7CiAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBSZW1VbmtTdHViX0RlYnVnU2VydmVyUmVsZWFzZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJICAgICAgTFBWT0lEIHB2KQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgRklYTUUoIiglcCktPkRlYnVnU2VydmVyUmVsZWFzZSglcClcbiIsIFRoaXMsIHB2KTsKfQoKc3RhdGljIGNvbnN0IElScGNTdHViQnVmZmVyVnRibCBSZW1VbmtTdHViX1ZUYWJsZSA9CnsKICBSZW1VbmtTdHViX1F1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1N0dWJfQWRkUmVmLAogIFJlbVVua1N0dWJfUmVsZWFzZSwKICBSZW1VbmtTdHViX0Nvbm5lY3QsCiAgUmVtVW5rU3R1Yl9EaXNjb25uZWN0LAogIFJlbVVua1N0dWJfSW52b2tlLAogIFJlbVVua1N0dWJfSXNJSURTdXBwb3J0ZWQsCiAgUmVtVW5rU3R1Yl9Db3VudFJlZnMsCiAgUmVtVW5rU3R1Yl9EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1N0dWJfRGVidWdTZXJ2ZXJSZWxlYXNlCn07CgpzdGF0aWMgSFJFU1VMVCBSZW1VbmtTdHViX0NvbnN0cnVjdChJUnBjU3R1YkJ1ZmZlciAqKnBwU3R1YikKewogICAgUmVtVW5rU3R1YiAqVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKlRoaXMpKTsKICAgIGlmICghVGhpcykgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICBUaGlzLT5scFZ0YmwgPSAmUmVtVW5rU3R1Yl9WVGFibGU7CiAgICBUaGlzLT5yZWZzID0gMTsKICAgIFRoaXMtPmlmYWNlID0gTlVMTDsKICAgICpwcFN0dWIgPSAoSVJwY1N0dWJCdWZmZXIqKVRoaXM7CiAgICByZXR1cm4gU19PSzsKfQoKCnR5cGVkZWYgc3RydWN0IF9SZW1VbmtQcm94eSB7CiAgICBjb25zdCBJUmVtVW5rbm93blZ0YmwJCSpscHZ0YmxfcmVtdW5rOwogICAgY29uc3QgSVJwY1Byb3h5QnVmZmVyVnRibAkqbHB2dGJsX3Byb3h5OwogICAgTE9ORwkJCQlyZWZzOwoKICAgIElScGNDaGFubmVsQnVmZmVyCQkJKmNoYW47CiAgICBJVW5rbm93biAqb3V0ZXJfdW5rbm93bjsKfSBSZW1VbmtQcm94eTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtQcm94eV9RdWVyeUludGVyZmFjZShMUFJFTVVOS05PV04gaWZhY2UsIFJFRklJRCByaWlkLCB2b2lkICoqcHB2KQp7CiAgICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogICAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pCiAgICAgICAgcmV0dXJuIElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKFRoaXMtPm91dGVyX3Vua25vd24sIHJpaWQsIHBwdik7CiAgICBpZiAoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lVbmtub3duKSB8fAogICAgICAgIElzRXF1YWxJSUQocmlpZCwgJklJRF9JUmVtVW5rbm93bikpCiAgICB7CiAgICAgICAgSVJlbVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICAqcHB2ID0gKExQVk9JRClpZmFjZTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJlbVVua1Byb3h5X0FkZFJlZihMUFJFTVVOS05PV04gaWZhY2UpCnsKICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogIFVMT05HIHJlZnM7CgogIFRSQUNFKCIoJXApLT5BZGRSZWYoKVxuIixUaGlzKTsKCiAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pCiAgICAgIHJlZnMgPSBJVW5rbm93bl9BZGRSZWYoVGhpcy0+b3V0ZXJfdW5rbm93bik7CiAgZWxzZQogICAgICByZWZzID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZnMpOwogIHJldHVybiByZWZzOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJlbVVua1Byb3h5X1JlbGVhc2UoTFBSRU1VTktOT1dOIGlmYWNlKQp7CiAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKICBVTE9ORyByZWZzOwoKICBUUkFDRSgiKCVwKS0+UmVsZWFzZSgpXG4iLFRoaXMpOwogIGlmIChUaGlzLT5vdXRlcl91bmtub3duKQogICAgICByZWZzID0gSVVua25vd25fUmVsZWFzZShUaGlzLT5vdXRlcl91bmtub3duKTsKICBlbHNlICAgIAogICAgICByZWZzID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZnMpOwoKICBpZiAoIXJlZnMpIHsKICAgICAgaWYgKFRoaXMtPmNoYW4pIElScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UoVGhpcy0+Y2hhbik7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKICB9CiAgcmV0dXJuIHJlZnM7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtQcm94eV9SZW1RdWVyeUludGVyZmFjZShMUFJFTVVOS05PV04gaWZhY2UsCgkJCQkJCSBSRUZJUElEIHJpcGlkLAoJCQkJCQkgVUxPTkcgY1JlZnMsCgkJCQkJCSBVU0hPUlQgY0lpZHMsCgkJCQkJCSBJSUQqIGlpZHMsCgkJCQkJCSBSRU1RSVJFU1VMVCoqIHBwUUlSZXN1bHRzKQp7CiAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKICBSUENPTEVNRVNTQUdFIG1zZzsKICBIUkVTVUxUIGhyID0gU19PSzsKICBVTE9ORyBzdGF0dXM7CgogIFRSQUNFKCIoJXApLT4oJXMsJWxkLCVkLCVwLCVwKVxuIixUaGlzLAoJZGVidWdzdHJfZ3VpZChyaXBpZCksY1JlZnMsY0lpZHMsaWlkcyxwcFFJUmVzdWx0cyk7CgogICpwcFFJUmVzdWx0cyA9IE5VTEw7CiAgbWVtc2V0KCZtc2csIDAsIHNpemVvZihtc2cpKTsKICBtc2cuaU1ldGhvZCA9IDM7CiAgbXNnLmNiQnVmZmVyID0gc2l6ZW9mKElQSUQpICsgc2l6ZW9mKFVMT05HKSArCiAgICBzaXplb2YoVVNIT1JUKSArIGNJaWRzKnNpemVvZihJSUQpOwogIGhyID0gSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKFRoaXMtPmNoYW4sICZtc2csICZJSURfSVJlbVVua25vd24pOwogIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICBMUEJZVEUgYnVmID0gbXNnLkJ1ZmZlcjsKICAgIG1lbWNweShidWYsIHJpcGlkLCBzaXplb2YoSVBJRCkpOwogICAgYnVmICs9IHNpemVvZihJUElEKTsKICAgIG1lbWNweShidWYsICZjUmVmcywgc2l6ZW9mKFVMT05HKSk7CiAgICBidWYgKz0gc2l6ZW9mKFVMT05HKTsKICAgIG1lbWNweShidWYsICZjSWlkcywgc2l6ZW9mKFVTSE9SVCkpOwogICAgYnVmICs9IHNpemVvZihVU0hPUlQpOwogICAgbWVtY3B5KGJ1ZiwgaWlkcywgY0lpZHMqc2l6ZW9mKElJRCkpOwoKICAgIGhyID0gSVJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUoVGhpcy0+Y2hhbiwgJm1zZywgJnN0YXR1cyk7CgogICAgYnVmID0gbXNnLkJ1ZmZlcjsKCiAgICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgICAgIGhyID0gKihIUkVTVUxUICopYnVmOwogICAgICAgIGJ1ZiArPSBzaXplb2YoSFJFU1VMVCk7CiAgICB9CgogICAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgICAgKnBwUUlSZXN1bHRzID0gQ29UYXNrTWVtQWxsb2MoY0lpZHMqc2l6ZW9mKFJFTVFJUkVTVUxUKSk7CiAgICAgIG1lbWNweSgqcHBRSVJlc3VsdHMsIGJ1ZiwgY0lpZHMqc2l6ZW9mKFJFTVFJUkVTVUxUKSk7CiAgICB9CgogICAgSVJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihUaGlzLT5jaGFuLCAmbXNnKTsKICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1Byb3h5X1JlbUFkZFJlZihMUFJFTVVOS05PV04gaWZhY2UsCgkJCQkJIFVTSE9SVCBjSW50ZXJmYWNlUmVmcywKCQkJCQkgUkVNSU5URVJGQUNFUkVGKiBJbnRlcmZhY2VSZWZzLAoJCQkJCSBIUkVTVUxUKiBwUmVzdWx0cykKewogIFJlbVVua1Byb3h5ICpUaGlzID0gKFJlbVVua1Byb3h5ICopaWZhY2U7CiAgUlBDT0xFTUVTU0FHRSBtc2c7CiAgSFJFU1VMVCBociA9IFNfT0s7CiAgVUxPTkcgc3RhdHVzOwoKICBUUkFDRSgiKCVwKS0+KCVkLCVwLCVwKVxuIixUaGlzLAoJY0ludGVyZmFjZVJlZnMsSW50ZXJmYWNlUmVmcyxwUmVzdWx0cyk7CgogIG1lbXNldCgmbXNnLCAwLCBzaXplb2YobXNnKSk7CiAgbXNnLmlNZXRob2QgPSA0OwogIG1zZy5jYkJ1ZmZlciA9IHNpemVvZihVU0hPUlQpICsgY0ludGVyZmFjZVJlZnMqc2l6ZW9mKFJFTUlOVEVSRkFDRVJFRik7CiAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIoVGhpcy0+Y2hhbiwgJm1zZywgJklJRF9JUmVtVW5rbm93bik7CiAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgIExQQllURSBidWYgPSBtc2cuQnVmZmVyOwogICAgbWVtY3B5KGJ1ZiwgJmNJbnRlcmZhY2VSZWZzLCBzaXplb2YoVVNIT1JUKSk7CiAgICBidWYgKz0gc2l6ZW9mKFVTSE9SVCk7CiAgICBtZW1jcHkoYnVmLCBJbnRlcmZhY2VSZWZzLCBjSW50ZXJmYWNlUmVmcypzaXplb2YoUkVNSU5URVJGQUNFUkVGKSk7CgogICAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShUaGlzLT5jaGFuLCAmbXNnLCAmc3RhdHVzKTsKCiAgICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgICBidWYgPSBtc2cuQnVmZmVyOwogICAgICBtZW1jcHkocFJlc3VsdHMsIGJ1ZiwgY0ludGVyZmFjZVJlZnMqc2l6ZW9mKEhSRVNVTFQpKTsKICAgIH0KCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyKFRoaXMtPmNoYW4sICZtc2cpOwogIH0KCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUmVtVW5rUHJveHlfUmVtUmVsZWFzZShMUFJFTVVOS05PV04gaWZhY2UsCgkJCQkJICBVU0hPUlQgY0ludGVyZmFjZVJlZnMsCgkJCQkJICBSRU1JTlRFUkZBQ0VSRUYqIEludGVyZmFjZVJlZnMpCnsKICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogIFJQQ09MRU1FU1NBR0UgbXNnOwogIEhSRVNVTFQgaHIgPSBTX09LOwogIFVMT05HIHN0YXR1czsKCiAgVFJBQ0UoIiglcCktPiglZCwlcClcbiIsVGhpcywKCWNJbnRlcmZhY2VSZWZzLEludGVyZmFjZVJlZnMpOwoKICBtZW1zZXQoJm1zZywgMCwgc2l6ZW9mKG1zZykpOwogIG1zZy5pTWV0aG9kID0gNTsKICBtc2cuY2JCdWZmZXIgPSBzaXplb2YoVVNIT1JUKSArIGNJbnRlcmZhY2VSZWZzKnNpemVvZihSRU1JTlRFUkZBQ0VSRUYpOwogIGhyID0gSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKFRoaXMtPmNoYW4sICZtc2csICZJSURfSVJlbVVua25vd24pOwogIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICBMUEJZVEUgYnVmID0gbXNnLkJ1ZmZlcjsKICAgIG1lbWNweShidWYsICZjSW50ZXJmYWNlUmVmcywgc2l6ZW9mKFVTSE9SVCkpOwogICAgYnVmICs9IHNpemVvZihVU0hPUlQpOwogICAgbWVtY3B5KGJ1ZiwgSW50ZXJmYWNlUmVmcywgY0ludGVyZmFjZVJlZnMqc2l6ZW9mKFJFTUlOVEVSRkFDRVJFRikpOwoKICAgIGhyID0gSVJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUoVGhpcy0+Y2hhbiwgJm1zZywgJnN0YXR1cyk7CgogICAgSVJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihUaGlzLT5jaGFuLCAmbXNnKTsKICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIGNvbnN0IElSZW1Vbmtub3duVnRibCBSZW1VbmtQcm94eV9WVGFibGUgPQp7CiAgUmVtVW5rUHJveHlfUXVlcnlJbnRlcmZhY2UsCiAgUmVtVW5rUHJveHlfQWRkUmVmLAogIFJlbVVua1Byb3h5X1JlbGVhc2UsCiAgUmVtVW5rUHJveHlfUmVtUXVlcnlJbnRlcmZhY2UsCiAgUmVtVW5rUHJveHlfUmVtQWRkUmVmLAogIFJlbVVua1Byb3h5X1JlbVJlbGVhc2UKfTsKCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUlVScGNQcm94eUJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSxSRUZJSUQgcmlpZCxMUFZPSUQgKnBwdikgewogICAgKnBwdiA9IE5VTEw7CiAgICBpZiAoSXNFcXVhbElJRChyaWlkLCZJSURfSVJwY1Byb3h5QnVmZmVyKXx8SXNFcXVhbElJRChyaWlkLCZJSURfSVVua25vd24pKSB7CglJUnBjUHJveHlCdWZmZXJfQWRkUmVmKGlmYWNlKTsKCSpwcHYgPSAoTFBWT0lEKWlmYWNlOwoJcmV0dXJuIFNfT0s7CiAgICB9CiAgICBGSVhNRSgiKCVzKSwgbm8gaW50ZXJmYWNlLlxuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJVUnBjUHJveHlCdWZmZXJJbXBsX0FkZFJlZihMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoUmVtVW5rUHJveHksbHB2dGJsX3Byb3h5LGlmYWNlKTsKICAgIFRSQUNFKCIlcCwgJWxkXG4iLCBpZmFjZSwgVGhpcy0+cmVmcyArIDEpOwogICAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWZzKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShSZW1VbmtQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZnMpOwogICAgVFJBQ0UoIiVwLCAlbGRcbiIsIGlmYWNlLCByZWYpOwogICAgaWYgKCFyZWYpIHsKICAgICAgICBJUnBjUHJveHlCdWZmZXJfRGlzY29ubmVjdChpZmFjZSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwogICAgfQogICAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJVUnBjUHJveHlCdWZmZXJJbXBsX0Nvbm5lY3QoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSxJUnBjQ2hhbm5lbEJ1ZmZlciogcFJwY0NoYW5uZWxCdWZmZXIpIHsKICAgIElDT01fVEhJU19NVUxUSShSZW1VbmtQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwoKICAgIFRSQUNFKCIlcCwgJXBcbiIsIGlmYWNlLCBwUnBjQ2hhbm5lbEJ1ZmZlcik7CiAgICBUaGlzLT5jaGFuID0gcFJwY0NoYW5uZWxCdWZmZXI7CiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9BZGRSZWYoVGhpcy0+Y2hhbik7CiAgICByZXR1cm4gU19PSzsKfQpzdGF0aWMgdm9pZCBXSU5BUEkgUlVScGNQcm94eUJ1ZmZlckltcGxfRGlzY29ubmVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoUmVtVW5rUHJveHksbHB2dGJsX3Byb3h5LGlmYWNlKTsKICAgIFRSQUNFKCIlcCwgJXBcbiIsIGlmYWNlLCBUaGlzLT5jaGFuKTsKICAgIGlmIChUaGlzLT5jaGFuKSB7CglJUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKFRoaXMtPmNoYW4pOwoJVGhpcy0+Y2hhbiA9IE5VTEw7CiAgICB9Cn0KCgpzdGF0aWMgY29uc3QgSVJwY1Byb3h5QnVmZmVyVnRibCBSVVJwY1Byb3h5QnVmZmVyX1ZUYWJsZSA9IHsKICAgIFJVUnBjUHJveHlCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgUlVScGNQcm94eUJ1ZmZlckltcGxfQWRkUmVmLAogICAgUlVScGNQcm94eUJ1ZmZlckltcGxfUmVsZWFzZSwKICAgIFJVUnBjUHJveHlCdWZmZXJJbXBsX0Nvbm5lY3QsCiAgICBSVVJwY1Byb3h5QnVmZmVySW1wbF9EaXNjb25uZWN0Cn07CgpzdGF0aWMgSFJFU1VMVApSZW1VbmtQcm94eV9Db25zdHJ1Y3QoSVVua25vd24gKnBVbmtPdXRlciwgTFBWT0lEICpwcHYsTFBWT0lEICpwcFByb3h5KSB7CiAgICBSZW1VbmtQcm94eSAqVGhpczsKCiAgICBUaGlzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoKlRoaXMpKTsKICAgIGlmICghVGhpcykKCXJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIFRoaXMtPmxwdnRibF9yZW11bmsJPSAmUmVtVW5rUHJveHlfVlRhYmxlOwogICAgVGhpcy0+bHB2dGJsX3Byb3h5CT0gJlJVUnBjUHJveHlCdWZmZXJfVlRhYmxlOwogICAgLyogb25seSBvbmUgcmVmZXJlbmNlIGZvciB0aGUgcHJveHkgYnVmZmVyICovCiAgICBUaGlzLT5yZWZzCQk9IDE7CiAgICBUaGlzLT5vdXRlcl91bmtub3duID0gcFVua091dGVyOwogICAgKnBwdgkJPSAmKFRoaXMtPmxwdnRibF9yZW11bmspOwogICAgKnBwUHJveHkJCT0gJihUaGlzLT5scHZ0YmxfcHJveHkpOwogICAgLyogYW5kIG9uZSByZWZlcmVuY2UgZm9yIHRoZSBvYmplY3QgKi8KICAgIElVbmtub3duX0FkZFJlZigoSVVua25vd24gKikqcHB2KTsKICAgIHJldHVybiBTX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKiBPTEUgUHJveHkvU3R1YiBGYWN0b3J5ICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKUFNGYWNCdWZfUXVlcnlJbnRlcmZhY2UoTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UsIFJFRklJRCBpaWQsIExQVk9JRCAqcHB2KSB7CiAgICBpZiAoSXNFcXVhbElJRChpaWQsJklJRF9JUFNGYWN0b3J5QnVmZmVyKXx8SXNFcXVhbElJRChpaWQsJklJRF9JVW5rbm93bikpIHsKCSpwcHYgPSAoTFBWT0lEKWlmYWNlOwoJLyogTm8gcmVmIGNvdW50aW5nLCBzdGF0aWMgY2xhc3MgKi8KCXJldHVybiBTX09LOwogICAgfQogICAgRklYTUUoIiglcykgdW5rbm93biBJSUQ/XG4iLGRlYnVnc3RyX2d1aWQoaWlkKSk7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBQU0ZhY0J1Zl9BZGRSZWYoTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UpIHsgcmV0dXJuIDI7IH0Kc3RhdGljIFVMT05HIFdJTkFQSSBQU0ZhY0J1Zl9SZWxlYXNlKExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlKSB7IHJldHVybiAxOyB9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKUFNGYWNCdWZfQ3JlYXRlUHJveHkoCiAgICBMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSwgSVVua25vd24qIHBVbmtPdXRlciwgUkVGSUlEIHJpaWQsCiAgICBJUnBjUHJveHlCdWZmZXIgKipwcFByb3h5LCBMUFZPSUQgKnBwdgopIHsKICAgIGlmIChJc0VxdWFsSUlEKCZJSURfSUNsYXNzRmFjdG9yeSxyaWlkKSkKCXJldHVybiBDRlByb3h5X0NvbnN0cnVjdChwVW5rT3V0ZXIsIHBwdiwoTFBWT0lEKilwcFByb3h5KTsKICAgIGVsc2UgaWYgKElzRXF1YWxJSUQoJklJRF9JUmVtVW5rbm93bixyaWlkKSkKCXJldHVybiBSZW1VbmtQcm94eV9Db25zdHJ1Y3QocFVua091dGVyLCBwcHYsKExQVk9JRCopcHBQcm94eSk7CiAgICBGSVhNRSgicHJveHlpbmcgbm90IGltcGxlbWVudGVkIGZvciAoJXMpIHlldCFcbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKUFNGYWNCdWZfQ3JlYXRlU3R1YigKICAgIExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlLCBSRUZJSUQgcmlpZCxJVW5rbm93biAqcFVua1NlcnZlciwKICAgIElScGNTdHViQnVmZmVyKiogcHBTdHViCikgewogICAgSFJFU1VMVCBocmVzOwoKICAgIFRSQUNFKCIoJXMsJXAsJXApXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkscFVua1NlcnZlcixwcFN0dWIpOwoKICAgIGlmIChJc0VxdWFsSUlEKCZJSURfSUNsYXNzRmFjdG9yeSwgcmlpZCkgfHwKICAgICAgICBJc0VxdWFsSUlEKCZJSURfSVVua25vd24sIHJpaWQpIC8qIEZJWE1FOiBmaXh1cCBzdHViIG1hbmFnZXIgYW5kIHJlbW92ZSB0aGlzKi8pIHsKCWhyZXMgPSBDRlN0dWJfQ29uc3RydWN0KHBwU3R1Yik7CglpZiAoIWhyZXMpCgkgICAgSVJwY1N0dWJCdWZmZXJfQ29ubmVjdCgoKnBwU3R1YikscFVua1NlcnZlcik7CglyZXR1cm4gaHJlczsKICAgIH0gZWxzZSBpZiAoSXNFcXVhbElJRCgmSUlEX0lSZW1Vbmtub3duLHJpaWQpKSB7CglocmVzID0gUmVtVW5rU3R1Yl9Db25zdHJ1Y3QocHBTdHViKTsKCWlmICghaHJlcykKCSAgICBJUnBjU3R1YkJ1ZmZlcl9Db25uZWN0KCgqcHBTdHViKSxwVW5rU2VydmVyKTsKCXJldHVybiBocmVzOwogICAgfQogICAgRklYTUUoInN0dWJiaW5nIG5vdCBpbXBsZW1lbnRlZCBmb3IgKCVzKSB5ZXQhXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIGNvbnN0IElQU0ZhY3RvcnlCdWZmZXJWdGJsIHBzZmFjYnVmdnRibCA9IHsKICAgIFBTRmFjQnVmX1F1ZXJ5SW50ZXJmYWNlLAogICAgUFNGYWNCdWZfQWRkUmVmLAogICAgUFNGYWNCdWZfUmVsZWFzZSwKICAgIFBTRmFjQnVmX0NyZWF0ZVByb3h5LAogICAgUFNGYWNCdWZfQ3JlYXRlU3R1Ygp9OwoKLyogVGhpcyBpcyB0aGUgd2hvbGUgUFNGYWN0b3J5QnVmZmVyIG9iamVjdCwganVzdCB0aGUgdnRhYmxlcHRyICovCnN0YXRpYyBjb25zdCBJUFNGYWN0b3J5QnVmZmVyVnRibCAqbHBwc2ZhYyA9ICZwc2ZhY2J1ZnZ0Ymw7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIERsbEdldENsYXNzT2JqZWN0IFtPTEUzMi5AXQogKi8KSFJFU1VMVCBXSU5BUEkgRGxsR2V0Q2xhc3NPYmplY3QoUkVGQ0xTSUQgcmNsc2lkLCBSRUZJSUQgaWlkLExQVk9JRCAqcHB2KQp7CiAgICAqcHB2ID0gTlVMTDsKICAgIGlmIChJc0VxdWFsSUlEKHJjbHNpZCwgJkNMU0lEX1BTRmFjdG9yeUJ1ZmZlcikpCiAgICAgICAgcmV0dXJuIElQU0ZhY3RvcnlCdWZmZXJfUXVlcnlJbnRlcmZhY2UoKElQU0ZhY3RvcnlCdWZmZXIgKikmbHBwc2ZhYywgaWlkLCBwcHYpOwogICAgaWYgKElzRXF1YWxJSUQocmNsc2lkLCZDTFNJRF9EZk1hcnNoYWwpJiYoCgkJSXNFcXVhbElJRChpaWQsJklJRF9JQ2xhc3NGYWN0b3J5KSB8fAoJCUlzRXF1YWxJSUQoaWlkLCZJSURfSVVua25vd24pCgkpCiAgICApCglyZXR1cm4gTUFSU0hBTF9HZXRTdGFuZGFyZE1hcnNoYWxDRihwcHYpOwogICAgaWYgKElzRXF1YWxJSUQocmNsc2lkLCZDTFNJRF9TdGRHbG9iYWxJbnRlcmZhY2VUYWJsZSkgJiYgKElzRXF1YWxJSUQoaWlkLCZJSURfSUNsYXNzRmFjdG9yeSkgfHwgSXNFcXVhbElJRChpaWQsJklJRF9JVW5rbm93bikpKQogICAgICAgIHJldHVybiBTdGRHbG9iYWxJbnRlcmZhY2VUYWJsZV9HZXRGYWN0b3J5KHBwdik7CiAgICBpZiAoSXNFcXVhbENMU0lEKHJjbHNpZCwgJkNMU0lEX0ZpbGVNb25pa2VyKSkKICAgICAgICByZXR1cm4gRmlsZU1vbmlrZXJDRl9DcmVhdGUoaWlkLCBwcHYpOwogICAgaWYgKElzRXF1YWxDTFNJRChyY2xzaWQsICZDTFNJRF9JdGVtTW9uaWtlcikpCiAgICAgICAgcmV0dXJuIEl0ZW1Nb25pa2VyQ0ZfQ3JlYXRlKGlpZCwgcHB2KTsKICAgIGlmIChJc0VxdWFsQ0xTSUQocmNsc2lkLCAmQ0xTSURfQW50aU1vbmlrZXIpKQogICAgICAgIHJldHVybiBBbnRpTW9uaWtlckNGX0NyZWF0ZShpaWQsIHBwdik7CiAgICBpZiAoSXNFcXVhbENMU0lEKHJjbHNpZCwgJkNMU0lEX0NvbXBvc2l0ZU1vbmlrZXIpKQogICAgICAgIHJldHVybiBDb21wb3NpdGVNb25pa2VyQ0ZfQ3JlYXRlKGlpZCwgcHB2KTsKICAgIGlmIChJc0VxdWFsQ0xTSUQocmNsc2lkLCAmQ0xTSURfQ2xhc3NNb25pa2VyKSkKICAgICAgICByZXR1cm4gQ2xhc3NNb25pa2VyQ0ZfQ3JlYXRlKGlpZCwgcHB2KTsKCiAgICBGSVhNRSgiXG5cdENMU0lEOlx0JXMsXG5cdElJRDpcdCVzXG4iLGRlYnVnc3RyX2d1aWQocmNsc2lkKSxkZWJ1Z3N0cl9ndWlkKGlpZCkpOwogICAgcmV0dXJuIENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEU7Cn0K