LyoKICoJT0xFMzIgcHJveHkvc3R1YiBoYW5kbGVyCiAqCiAqICBDb3B5cmlnaHQgMjAwMiAgTWFyY3VzIE1laXNzbmVyCiAqICBDb3B5cmlnaHQgMjAwMSAgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKLyogRG9jdW1lbnRhdGlvbiBvbiBNU0ROOgogKgogKiAoVG9wIGxldmVsIENPTSBkb2N1bWVudGF0aW9uKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2RuYW5jaG9yL2h0bWwvY29tcG9uZW50ZGV2ZWxvcG1lbnRhbmsuYXNwCiAqCiAqIChDT00gUHJveHkpCiAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvY29tL2h0bS9jb21leHRfMXEwcC5hc3AKICoKICogKENPTSBTdHViKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG0vY29tZXh0XzFsaWEuYXNwCiAqCiAqIChNYXJzaGFsKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG0vY29tZXh0XzFnZm4uYXNwCiAqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KI2RlZmluZSBOT05BTUVMRVNTU1RSVUNUCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJvYmpiYXNlLmgiCiNpbmNsdWRlICJvbGUyLmgiCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgInd0eXBlcy5oIgoKI2luY2x1ZGUgImNvbXBvYmpfcHJpdmF0ZS5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7Cgpjb25zdCBDTFNJRCBDTFNJRF9EZk1hcnNoYWwgICAgICAgPSB7IDB4MDAwMDAzMGIsIDAsIDAsIHsweGMwLCAwLCAwLCAwLCAwLCAwLCAwLCAweDQ2fSB9Owpjb25zdCBDTFNJRCBDTFNJRF9QU0ZhY3RvcnlCdWZmZXIgPSB7IDB4MDAwMDAzMjAsIDAsIDAsIHsweGMwLCAwLCAwLCAwLCAwLCAwLCAwLCAweDQ2fSB9OwoKLyogRnJvbTogaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9saWJyYXJ5L2VuLXVzL2NvbS9jbWlfbV80bGRhLmFzcAogKgogKiBUaGUgZmlyc3QgdGltZSBhIGNsaWVudCByZXF1ZXN0cyBhIHBvaW50ZXIgdG8gYW4gaW50ZXJmYWNlIG9uIGEKICogcGFydGljdWxhciBvYmplY3QsIENPTSBsb2FkcyBhbiBJQ2xhc3NGYWN0b3J5IHN0dWIgaW4gdGhlIHNlcnZlcgogKiBwcm9jZXNzIGFuZCB1c2VzIGl0IHRvIG1hcnNoYWwgdGhlIGZpcnN0IHBvaW50ZXIgYmFjayB0byB0aGUKICogY2xpZW50LiBJbiB0aGUgY2xpZW50IHByb2Nlc3MsIENPTSBsb2FkcyB0aGUgZ2VuZXJpYyBwcm94eSBmb3IgdGhlCiAqIGNsYXNzIGZhY3Rvcnkgb2JqZWN0IGFuZCBjYWxscyBpdHMgaW1wbGVtZW50YXRpb24gb2YgSU1hcnNoYWwgdG8KICogdW5tYXJzaGFsIHRoYXQgZmlyc3QgcG9pbnRlci4gQ09NIHRoZW4gY3JlYXRlcyB0aGUgZmlyc3QgaW50ZXJmYWNlCiAqIHByb3h5IGFuZCBoYW5kcyBpdCBhIHBvaW50ZXIgdG8gdGhlIFJQQyBjaGFubmVsLiBGaW5hbGx5LCBDT00gcmV0dXJucwogKiB0aGUgSUNsYXNzRmFjdG9yeSBwb2ludGVyIHRvIHRoZSBjbGllbnQsIHdoaWNoIHVzZXMgaXQgdG8gY2FsbAogKiBJQ2xhc3NGYWN0b3J5OjpDcmVhdGVJbnN0YW5jZSwgcGFzc2luZyBpdCBhIHJlZmVyZW5jZSB0byB0aGUgaW50ZXJmYWNlLgogKgogKiBCYWNrIGluIHRoZSBzZXJ2ZXIgcHJvY2VzcywgQ09NIG5vdyBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZQogKiBvYmplY3QsIGFsb25nIHdpdGggYSBzdHViIGZvciB0aGUgcmVxdWVzdGVkIGludGVyZmFjZS4gVGhpcyBzdHViIG1hcnNoYWxzCiAqIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBiYWNrIHRvIHRoZSBjbGllbnQgcHJvY2Vzcywgd2hlcmUgYW5vdGhlciBvYmplY3QKICogcHJveHkgaXMgY3JlYXRlZCwgdGhpcyB0aW1lIGZvciB0aGUgb2JqZWN0IGl0c2VsZi4gQWxzbyBjcmVhdGVkIGlzIGEKICogcHJveHkgZm9yIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlLCBhIHBvaW50ZXIgdG8gd2hpY2ggaXMgcmV0dXJuZWQgdG8KICogdGhlIGNsaWVudC4gV2l0aCBzdWJzZXF1ZW50IGNhbGxzIHRvIG90aGVyIGludGVyZmFjZXMgb24gdGhlIG9iamVjdCwKICogQ09NIHdpbGwgbG9hZCB0aGUgYXBwcm9wcmlhdGUgaW50ZXJmYWNlIHN0dWJzIGFuZCBwcm94aWVzIGFzIG5lZWRlZC4KICovCnR5cGVkZWYgc3RydWN0IF9DRlN0dWIgewogICAgSVJwY1N0dWJCdWZmZXJWdGJsCSpscHZ0Ymw7CiAgICBEV09SRAkJCXJlZjsKCiAgICBMUFVOS05PV04JCQlwVW5rU2VydmVyOwp9IENGU3R1YjsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpDRlN0dWJfUXVlcnlJbnRlcmZhY2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpIHsKICAgIGlmIChJc0VxdWFsSUlEKCZJSURfSVVua25vd24scmlpZCl8fElzRXF1YWxJSUQoJklJRF9JUnBjU3R1YkJ1ZmZlcixyaWlkKSkgewoJKnBwdiA9IChMUFZPSUQpaWZhY2U7CglJVW5rbm93bl9BZGRSZWYoaWZhY2UpOwoJcmV0dXJuIFNfT0s7CiAgICB9CiAgICBGSVhNRSgiKCVzKSwgaW50ZXJmYWNlIG5vdCBzdXBwb3J0ZWQuXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKQ0ZTdHViX0FkZFJlZihMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpIHsKICAgIENGU3R1YiAqVGhpcyA9IChDRlN0dWIgKilpZmFjZTsKICAgIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpDRlN0dWJfUmVsZWFzZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpIHsKICAgIENGU3R1YiAqVGhpcyA9IChDRlN0dWIgKilpZmFjZTsKICAgIFVMT05HIHJlZjsKCiAgICByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKICAgIGlmICghcmVmKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CiAgICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKQ0ZTdHViX0Nvbm5lY3QoTFBSUENTVFVCQlVGRkVSIGlmYWNlLCBJVW5rbm93biAqcFVua1NlcnZlcikgewogICAgQ0ZTdHViICpUaGlzID0gKENGU3R1YiAqKWlmYWNlOwoKICAgIFRoaXMtPnBVbmtTZXJ2ZXIgPSBwVW5rU2VydmVyOwogICAgSVVua25vd25fQWRkUmVmKHBVbmtTZXJ2ZXIpOwogICAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSQpDRlN0dWJfRGlzY29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpIHsKICAgIENGU3R1YiAqVGhpcyA9IChDRlN0dWIgKilpZmFjZTsKCiAgICBJVW5rbm93bl9SZWxlYXNlKFRoaXMtPnBVbmtTZXJ2ZXIpOwogICAgVGhpcy0+cFVua1NlcnZlciA9IE5VTEw7Cn0Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCkNGU3R1Yl9JbnZva2UoCiAgICBMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsUlBDT0xFTUVTU0FHRSogbXNnLElScGNDaGFubmVsQnVmZmVyKiBjaGFuYnVmCikgewogICAgQ0ZTdHViICpUaGlzID0gKENGU3R1YiAqKWlmYWNlOwogICAgSFJFU1VMVCBocmVzOwoKICAgIGlmIChtc2ctPmlNZXRob2QgPT0gMykgeyAvKiBDcmVhdGVJbnN0YW5jZSAqLwoJSUlEIGlpZDsKCUlDbGFzc0ZhY3RvcnkJKmNsYXNzZmFjOwoJSVVua25vd24JKnBwdjsKCUlTdHJlYW0JCSpwU3RtOwoJU1RBVFNURwkJc3RzdGc7CglVTEFSR0VfSU5URUdFUgluZXdwb3M7CglMQVJHRV9JTlRFR0VSCXNlZWt0bzsKCVVMT05HCQlyZXM7CgoJaWYgKG1zZy0+Y2JCdWZmZXIgPCBzaXplb2YoSUlEKSkgewoJICAgIEZJWE1FKCJOb3QgZW5vdWdoIGJ5dGVzIGluIGJ1ZmZlciAoJWxkIGluc3RlYWQgb2YgJWQpP1xuIixtc2ctPmNiQnVmZmVyLHNpemVvZihJSUQpKTsKCSAgICByZXR1cm4gRV9GQUlMOwoJfQoJbWVtY3B5KCZpaWQsbXNnLT5CdWZmZXIsc2l6ZW9mKGlpZCkpOwoJVFJBQ0UoIi0+Q3JlYXRlSW5zdGFuY2UoJXMpXG4iLGRlYnVnc3RyX2d1aWQoJmlpZCkpOwoJaHJlcyA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKFRoaXMtPnBVbmtTZXJ2ZXIsJklJRF9JQ2xhc3NGYWN0b3J5LChMUFZPSUQqKSZjbGFzc2ZhYyk7CglpZiAoaHJlcykgewoJICAgIEZJWE1FKCJPbGUgc2VydmVyIGRvZXMgbm90IHByb3ZpZGUgYSBJQ2xhc3NGYWN0b3J5P1xuIik7CgkgICAgcmV0dXJuIGhyZXM7Cgl9CglocmVzID0gSUNsYXNzRmFjdG9yeV9DcmVhdGVJbnN0YW5jZShjbGFzc2ZhYyxOVUxMLCZpaWQsKExQVk9JRCopJnBwdik7CglJQ2xhc3NGYWN0b3J5X1JlbGVhc2UoY2xhc3NmYWMpOwoJaWYgKGhyZXMpIHsKCSAgICBtc2ctPmNiQnVmZmVyID0gMDsKCSAgICBGSVhNRSgiRmFpbGVkIHRvIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiAlc1xuIixkZWJ1Z3N0cl9ndWlkKCZpaWQpKTsKCSAgICByZXR1cm4gaHJlczsKCX0KCWhyZXMgPSBDcmVhdGVTdHJlYW1PbkhHbG9iYWwoMCxUUlVFLCZwU3RtKTsKCWlmIChocmVzKSB7CgkgICAgRklYTUUoIkZhaWxlZCB0byBjcmVhdGUgc3RyZWFtIG9uIGhnbG9iYWxcbiIpOwoJICAgIHJldHVybiBocmVzOwoJfQoJaHJlcyA9IENvTWFyc2hhbEludGVyZmFjZShwU3RtLCZpaWQscHB2LDAsTlVMTCwwKTsKCUlVbmtub3duX1JlbGVhc2UoKElVbmtub3duKilwcHYpOwoJaWYgKGhyZXMpIHsKCSAgICBGSVhNRSgiQ29NYXJzaGFsSW50ZXJmYWNlIGZhaWxlZCwgJWx4IVxuIixocmVzKTsKCSAgICBtc2ctPmNiQnVmZmVyID0gMDsKCSAgICByZXR1cm4gaHJlczsKCX0KCWhyZXMgPSBJU3RyZWFtX1N0YXQocFN0bSwmc3RzdGcsMCk7CglpZiAoaHJlcykgewoJICAgIEZJWE1FKCJTdGF0IGZhaWxlZC5cbiIpOwoJICAgIHJldHVybiBocmVzOwoJfQoKCW1zZy0+Y2JCdWZmZXIgPSBzdHN0Zy5jYlNpemUudS5Mb3dQYXJ0OwoKICAgICAgICBJX1JwY0dldEJ1ZmZlcigoUlBDX01FU1NBR0UgKiltc2cpOwogICAgICAgIGlmIChocmVzKSByZXR1cm4gaHJlczsKCglzZWVrdG8udS5Mb3dQYXJ0ID0gMDtzZWVrdG8udS5IaWdoUGFydCA9IDA7CglocmVzID0gSVN0cmVhbV9TZWVrKHBTdG0sc2Vla3RvLFNFRUtfU0VULCZuZXdwb3MpOwoJaWYgKGhyZXMpIHsKCSAgICBGSVhNRSgiSVN0cmVhbV9TZWVrIGZhaWxlZCwgJWx4XG4iLGhyZXMpOwoJICAgIHJldHVybiBocmVzOwoJfQoJaHJlcyA9IElTdHJlYW1fUmVhZChwU3RtLG1zZy0+QnVmZmVyLG1zZy0+Y2JCdWZmZXIsJnJlcyk7CglpZiAoaHJlcykgewoJICAgIEZJWE1FKCJTdHJlYW0gUmVhZCBmYWlsZWQsICVseFxuIixocmVzKTsKCSAgICByZXR1cm4gaHJlczsKCX0KCUlTdHJlYW1fUmVsZWFzZShwU3RtKTsKCXJldHVybiBTX09LOwogICAgfQogICAgRklYTUUoIiglcCwlcCksIHN0dWIhXG4iLG1zZyxjaGFuYnVmKTsKICAgIEZJWE1FKCJpTWV0aG9kIGlzICVsZFxuIixtc2ctPmlNZXRob2QpOwogICAgRklYTUUoImNiQnVmZmVyIGlzICVsZFxuIixtc2ctPmNiQnVmZmVyKTsKICAgIHJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBMUFJQQ1NUVUJCVUZGRVIgV0lOQVBJCkNGU3R1Yl9Jc0lJRFN1cHBvcnRlZChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsUkVGSUlEIHJpaWQpIHsKICAgIEZJWE1FKCIoJXMpLCBzdHViIVxuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBOVUxMOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCkNGU3R1Yl9Db3VudFJlZnMoTFBSUENTVFVCQlVGRkVSIGlmYWNlKSB7CiAgICBGSVhNRSgiKCksIHN0dWIhXG4iKTsKICAgIHJldHVybiAxOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKQ0ZTdHViX0RlYnVnU2VydmVyUXVlcnlJbnRlcmZhY2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLHZvaWQqKiBwcHYpIHsKICAgIEZJWE1FKCIoJXApLCBzdHViIVxuIixwcHYpOwogICAgcmV0dXJuIEVfRkFJTDsKfQpzdGF0aWMgdm9pZCAgICBXSU5BUEkKQ0ZTdHViX0RlYnVnU2VydmVyUmVsZWFzZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2Usdm9pZCAqcHYpIHsKICAgIEZJWE1FKCIoJXApLCBzdHViIVxuIixwdik7Cn0KCnN0YXRpYyBJUnBjU3R1YkJ1ZmZlclZ0YmwgY2ZzdHVidnQgPSB7CiAgICBDRlN0dWJfUXVlcnlJbnRlcmZhY2UsCiAgICBDRlN0dWJfQWRkUmVmLAogICAgQ0ZTdHViX1JlbGVhc2UsCiAgICBDRlN0dWJfQ29ubmVjdCwKICAgIENGU3R1Yl9EaXNjb25uZWN0LAogICAgQ0ZTdHViX0ludm9rZSwKICAgIENGU3R1Yl9Jc0lJRFN1cHBvcnRlZCwKICAgIENGU3R1Yl9Db3VudFJlZnMsCiAgICBDRlN0dWJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZSwKICAgIENGU3R1Yl9EZWJ1Z1NlcnZlclJlbGVhc2UKfTsKCnN0YXRpYyBIUkVTVUxUCkNGU3R1Yl9Db25zdHJ1Y3QoTFBSUENTVFVCQlVGRkVSICpwcHYpIHsKICAgIENGU3R1YiAqY2ZzdHViOwogICAgY2ZzdHViID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoQ0ZTdHViKSk7CiAgICBpZiAoIWNmc3R1YikKCXJldHVybiBFX09VVE9GTUVNT1JZOwogICAgKnBwdiA9IChMUFJQQ1NUVUJCVUZGRVIpY2ZzdHViOwogICAgY2ZzdHViLT5scHZ0YmwJPSAmY2ZzdHVidnQ7CiAgICBjZnN0dWItPnJlZgkJPSAxOwogICAgcmV0dXJuIFNfT0s7Cn0KCi8qIFNpbmNlIHdlIGNyZWF0ZSBwcm94eSBidWZmZXJzIGFuZCBjbGFzc2ZhY3RvcnkgaW4gYSBwYWlyLCB0aGVyZSBpcwogKiBubyBuZWVkIGZvciAyIHNlcGFyYXRlIHN0cnVjdHMuIEp1c3QgcHV0IHRoZW0gaW4gb25lLCBidXQgcmVtZW1iZXIKICogdGhlIHJlZmNvdW50LgogKi8KdHlwZWRlZiBzdHJ1Y3QgX0NGUHJveHkgewogICAgY29uc3QgSUNsYXNzRmFjdG9yeVZ0YmwJCSpscHZ0YmxfY2Y7CiAgICBjb25zdCBJUnBjUHJveHlCdWZmZXJWdGJsCSpscHZ0YmxfcHJveHk7CiAgICBEV09SRAkJCQlyZWY7CgogICAgSVJwY0NoYW5uZWxCdWZmZXIJCQkqY2hhbmJ1ZjsKICAgIElVbmtub3duICpvdXRlcl91bmtub3duOwp9IENGUHJveHk7CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVJwY1Byb3h5QnVmZmVySW1wbF9RdWVyeUludGVyZmFjZShMUFJQQ1BST1hZQlVGRkVSIGlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHB2KSB7CiAgICAqcHB2ID0gTlVMTDsKICAgIGlmIChJc0VxdWFsSUlEKHJpaWQsJklJRF9JUnBjUHJveHlCdWZmZXIpfHxJc0VxdWFsSUlEKHJpaWQsJklJRF9JVW5rbm93bikpIHsKCUlScGNQcm94eUJ1ZmZlcl9BZGRSZWYoaWZhY2UpOwoJKnBwdiA9IChMUFZPSUQpaWZhY2U7CglyZXR1cm4gU19PSzsKICAgIH0KICAgIEZJWE1FKCIoJXMpLCBubyBpbnRlcmZhY2UuXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSVJwY1Byb3h5QnVmZmVySW1wbF9BZGRSZWYoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX3Byb3h5LGlmYWNlKTsKICAgIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJUnBjUHJveHlCdWZmZXJJbXBsX1JlbGVhc2UoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX3Byb3h5LGlmYWNlKTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICAgIGlmICghcmVmKSB7CglJUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKFRoaXMtPmNoYW5idWYpO1RoaXMtPmNoYW5idWYgPSBOVUxMOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwogICAgfQogICAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElScGNQcm94eUJ1ZmZlckltcGxfQ29ubmVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlLElScGNDaGFubmVsQnVmZmVyKiBwUnBjQ2hhbm5lbEJ1ZmZlcikgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX3Byb3h5LGlmYWNlKTsKCiAgICBUaGlzLT5jaGFuYnVmID0gcFJwY0NoYW5uZWxCdWZmZXI7CiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9BZGRSZWYoVGhpcy0+Y2hhbmJ1Zik7CiAgICByZXR1cm4gU19PSzsKfQpzdGF0aWMgdm9pZCBXSU5BUEkgSVJwY1Byb3h5QnVmZmVySW1wbF9EaXNjb25uZWN0KExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CiAgICBpZiAoVGhpcy0+Y2hhbmJ1ZikgewoJSVJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZShUaGlzLT5jaGFuYnVmKTsKCVRoaXMtPmNoYW5idWYgPSBOVUxMOwogICAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKQ0ZQcm94eV9RdWVyeUludGVyZmFjZShMUENMQVNTRkFDVE9SWSBpZmFjZSxSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9jZixpZmFjZSk7CiAgICBpZiAoVGhpcy0+b3V0ZXJfdW5rbm93bikgcmV0dXJuIElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKFRoaXMtPm91dGVyX3Vua25vd24sIHJpaWQsIHBwdik7CiAgICAqcHB2ID0gTlVMTDsKICAgIGlmIChJc0VxdWFsSUlEKCZJSURfSUNsYXNzRmFjdG9yeSxyaWlkKSB8fCBJc0VxdWFsSUlEKCZJSURfSVVua25vd24scmlpZCkpIHsKCSpwcHYgPSAoTFBWT0lEKWlmYWNlOwoJSUNsYXNzRmFjdG9yeV9BZGRSZWYoaWZhY2UpOwoJcmV0dXJuIFNfT0s7CiAgICB9CiAgICBpZiAoSXNFcXVhbElJRChyaWlkLCZJSURfSU1hcnNoYWwpKSAvKiBqdXN0IHRvIGF2b2lkIGRlYnVnIG91dHB1dCAqLwoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CiAgICBGSVhNRSgiVW5oYW5kbGVkIGludGVyZmFjZTogJXNcbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIENGUHJveHlfQWRkUmVmKExQQ0xBU1NGQUNUT1JZIGlmYWNlKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfY2YsaWZhY2UpOwogICAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pIHJldHVybiBJVW5rbm93bl9BZGRSZWYoVGhpcy0+b3V0ZXJfdW5rbm93bik7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBDRlByb3h5X1JlbGVhc2UoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpIHsKICAgIFVMT05HIHJlZjsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9jZixpZmFjZSk7CiAgICBpZiAoVGhpcy0+b3V0ZXJfdW5rbm93bikKICAgICAgICByZWYgPSBJVW5rbm93bl9SZWxlYXNlKFRoaXMtPm91dGVyX3Vua25vd24pOwogICAgZWxzZSAgICAKICAgICAgICByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBpZiAoIXJlZikgewogICAgICAJaWYgKFRoaXMtPmNoYW5idWYpIElScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UoVGhpcy0+Y2hhbmJ1Zik7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwogICAgfQogICAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENGUHJveHlfQ3JlYXRlSW5zdGFuY2UoCiAgICBMUENMQVNTRkFDVE9SWSBpZmFjZSwKICAgIExQVU5LTk9XTiBwVW5rT3V0ZXIsLyogW2luXSAqLwogICAgUkVGSUlEIHJpaWQsCS8qIFtpbl0gKi8KICAgIExQVk9JRCAqcHB2CQkvKiBbb3V0XSAqLwopIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9jZixpZmFjZSk7CiAgICBIUkVTVUxUCQlocmVzOwogICAgTFBTVFJFQU0JCXBTdHJlYW07CiAgICBIR0xPQkFMCQloR2xvYmFsOwogICAgVUxPTkcJCXNyc3RhdHVzOwogICAgUlBDT0xFTUVTU0FHRQltc2c7CgogICAgVFJBQ0UoIiglcCwlcywlcClcbiIscFVua091dGVyLGRlYnVnc3RyX2d1aWQocmlpZCkscHB2KTsKCiAgICAvKiBTZW5kIENyZWF0ZUluc3RhbmNlIHRvIHRoZSByZW1vdGUgY2xhc3NmYWN0b3J5LgogICAgICoKICAgICAqIERhdGE6IE9ubHkgdGhlICdJSUQnLgogICAgICovCiAgICBtc2cuaU1ldGhvZCAgPSAzOwogICAgbXNnLmNiQnVmZmVyID0gc2l6ZW9mKCpyaWlkKTsKICAgIG1zZy5CdWZmZXIJID0gTlVMTDsKICAgIGhyZXMgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIoVGhpcy0+Y2hhbmJ1ZiwmbXNnLCZJSURfSUNsYXNzRmFjdG9yeSk7CiAgICBpZiAoaHJlcykgewoJRklYTUUoIklScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlciBmYWlsZWQgd2l0aCAlbHg/XG4iLGhyZXMpOwoJcmV0dXJuIGhyZXM7CiAgICB9CiAgICBtZW1jcHkobXNnLkJ1ZmZlcixyaWlkLHNpemVvZigqcmlpZCkpOwogICAgaHJlcyA9IElScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlKFRoaXMtPmNoYW5idWYsJm1zZywmc3JzdGF0dXMpOwogICAgaWYgKGhyZXMpIHsKCUZJWE1FKCJJUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZSBmYWlsZWQgd2l0aCAlbHg/XG4iLGhyZXMpOwoJcmV0dXJuIGhyZXM7CiAgICB9CgogICAgaWYgKCFtc2cuY2JCdWZmZXIpIC8qIGludGVyZmFjZSBub3QgZm91bmQgb24gcmVtb3RlICovCglyZXR1cm4gc3JzdGF0dXM7CgogICAgLyogV2UgZ290IGJhY2s6IFtNYXJzaGFsbGVkIEludGVyZmFjZSBkYXRhXSAqLwogICAgVFJBQ0UoImdvdCAlbGQgYnl0ZXMgZGF0YS5cbiIsbXNnLmNiQnVmZmVyKTsKICAgIGhHbG9iYWwgPSBHbG9iYWxBbGxvYyhHTUVNX01PVkVBQkxFfEdNRU1fTk9ESVNDQVJEfEdNRU1fU0hBUkUsbXNnLmNiQnVmZmVyKTsKICAgIG1lbWNweShHbG9iYWxMb2NrKGhHbG9iYWwpLG1zZy5CdWZmZXIsbXNnLmNiQnVmZmVyKTsKICAgIGhyZXMgPSBDcmVhdGVTdHJlYW1PbkhHbG9iYWwoaEdsb2JhbCxUUlVFLCZwU3RyZWFtKTsKICAgIGlmIChocmVzKSB7CglGSVhNRSgiQ3JlYXRlU3RyZWFtT25IR2xvYmFsIGZhaWxlZCB3aXRoICVseFxuIixocmVzKTsKCXJldHVybiBocmVzOwogICAgfQogICAgaHJlcyA9IENvVW5tYXJzaGFsSW50ZXJmYWNlKAoJICAgIHBTdHJlYW0sCgkgICAgcmlpZCwKCSAgICBwcHYKICAgICk7CiAgICBJU3RyZWFtX1JlbGVhc2UocFN0cmVhbSk7IC8qIERvZXMgR2xvYmFsRnJlZSBoR2xvYmFsIHRvby4gKi8KICAgIGlmIChocmVzKSB7CglGSVhNRSgiQ29NYXJzaGFsSW50ZXJmYWNlIGZhaWxlZCwgJWx4XG4iLGhyZXMpOwoJcmV0dXJuIGhyZXM7CiAgICB9CiAgICByZXR1cm4gU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENGUHJveHlfTG9ja1NlcnZlcihMUENMQVNTRkFDVE9SWSBpZmFjZSxCT09MIGZMb2NrKSB7CiAgICAvKklDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9jZixpZmFjZSk7Ki8KICAgIEZJWE1FKCIoJWQpLCBzdHViIVxuIixmTG9jayk7CiAgICAvKiBiYXNpY2FsbHk6IHdyaXRlIEJPT0wsIHJlYWQgZW1wdHkgKi8KICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgSVJwY1Byb3h5QnVmZmVyVnRibCBwc3BidnRibCA9IHsKICAgIElScGNQcm94eUJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJUnBjUHJveHlCdWZmZXJJbXBsX0FkZFJlZiwKICAgIElScGNQcm94eUJ1ZmZlckltcGxfUmVsZWFzZSwKICAgIElScGNQcm94eUJ1ZmZlckltcGxfQ29ubmVjdCwKICAgIElScGNQcm94eUJ1ZmZlckltcGxfRGlzY29ubmVjdAp9OwpzdGF0aWMgSUNsYXNzRmFjdG9yeVZ0YmwgY2Zwcm94eXZ0ID0gewogICAgQ0ZQcm94eV9RdWVyeUludGVyZmFjZSwKICAgIENGUHJveHlfQWRkUmVmLAogICAgQ0ZQcm94eV9SZWxlYXNlLAogICAgQ0ZQcm94eV9DcmVhdGVJbnN0YW5jZSwKICAgIENGUHJveHlfTG9ja1NlcnZlcgp9OwoKc3RhdGljIEhSRVNVTFQKQ0ZQcm94eV9Db25zdHJ1Y3QoSVVua25vd24gKnBVbmtPdXRlciwgTFBWT0lEICpwcHYsTFBWT0lEICpwcFByb3h5KSB7CiAgICBDRlByb3h5ICpjZjsKCiAgICBjZiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKENGUHJveHkpKTsKICAgIGlmICghY2YpCglyZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBjZi0+bHB2dGJsX2NmCT0gJmNmcHJveHl2dDsKICAgIGNmLT5scHZ0YmxfcHJveHkJPSAmcHNwYnZ0Ymw7CiAgICAvKiBvbmx5IG9uZSByZWZlcmVuY2UgZm9yIHRoZSBwcm94eSBidWZmZXIgKi8KICAgIGNmLT5yZWYJCT0gMTsKICAgIGNmLT5vdXRlcl91bmtub3duID0gcFVua091dGVyOwogICAgKnBwdgkJPSAmKGNmLT5scHZ0YmxfY2YpOwogICAgKnBwUHJveHkJCT0gJihjZi0+bHB2dGJsX3Byb3h5KTsKICAgIHJldHVybiBTX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKiBJUmVtVW5rbm93biBQcm94eS9TdHViICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgY29uc3QgSVJwY1N0dWJCdWZmZXJWdGJsICpscFZ0Ymw7CiAgICBVTE9ORyByZWZzOwogICAgSVJlbVVua25vd24gKmlmYWNlOwp9IFJlbVVua1N0dWI7CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUmVtVW5rU3R1Yl9RdWVyeUludGVyZmFjZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJICAgICBSRUZJSUQgcmlpZCwKCQkJCQkgICAgIExQVk9JRCAqb2JqKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPlF1ZXJ5SW50ZXJmYWNlKCVzLCVwKVxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCksb2JqKTsKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93bixyaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lScGNTdHViQnVmZmVyLHJpaWQpKSB7CiAgICAqb2JqID0gVGhpczsKICAgIHJldHVybiBTX09LOwogIH0KICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSZW1VbmtTdHViX0FkZFJlZihMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+QWRkUmVmKClcbiIsVGhpcyk7CiAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWZzKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSZW1VbmtTdHViX1JlbGVhc2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVUxPTkcgcmVmczsKICBUUkFDRSgiKCVwKS0+UmVsZWFzZSgpXG4iLFRoaXMpOwogIHJlZnMgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmcyk7CiAgaWYgKCFyZWZzKQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgcmV0dXJuIHJlZnM7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtTdHViX0Nvbm5lY3QoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAoJCQkJICAgICAgTFBVTktOT1dOIGxwVW5rU2VydmVyKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPkNvbm5lY3QoJXApXG4iLFRoaXMsbHBVbmtTZXJ2ZXIpOwogIFRoaXMtPmlmYWNlID0gKElSZW1Vbmtub3duKilscFVua1NlcnZlcjsKICBJUmVtVW5rbm93bl9BZGRSZWYoVGhpcy0+aWZhY2UpOwogIHJldHVybiBTX09LOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgUmVtVW5rU3R1Yl9EaXNjb25uZWN0KExQUlBDU1RVQkJVRkZFUiBpZmFjZSkKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5EaXNjb25uZWN0KClcbiIsVGhpcyk7CiAgSVVua25vd25fUmVsZWFzZShUaGlzLT5pZmFjZSk7CiAgVGhpcy0+aWZhY2UgPSBOVUxMOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUmVtVW5rU3R1Yl9JbnZva2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAoJCQkJICAgICBQUlBDT0xFTUVTU0FHRSBwTXNnLAoJCQkJICAgICBMUFJQQ0NIQU5ORUxCVUZGRVIgcENoYW5uZWwpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBVTE9ORyBpTWV0aG9kID0gcE1zZy0+aU1ldGhvZDsKICBMUEJZVEUgYnVmID0gcE1zZy0+QnVmZmVyOwogIEhSRVNVTFQgaHIgPSBSUENfRV9JTlZBTElETUVUSE9EOwoKICBUUkFDRSgiKCVwKS0+SW52b2tlKCVwLCVwKSBtZXRob2QgJWxkXG4iLCBUaGlzLCBwTXNnLCBwQ2hhbm5lbCwgaU1ldGhvZCk7CiAgc3dpdGNoIChpTWV0aG9kKQogIHsKICBjYXNlIDM6IC8qIFJlbVF1ZXJ5SW50ZXJmYWNlICovCiAgewogICAgSVBJRCBpcGlkOwogICAgVUxPTkcgY1JlZnM7CiAgICBVU0hPUlQgY0lpZHM7CiAgICBJSUQgKmlpZHM7CiAgICBSRU1RSVJFU1VMVCAqcFFJUmVzdWx0cyA9IE5VTEw7CgogICAgLyogaW4gKi8KICAgIG1lbWNweSgmaXBpZCwgYnVmLCBzaXplb2YoaXBpZCkpOwogICAgYnVmICs9IHNpemVvZihpcGlkKTsKICAgIG1lbWNweSgmY1JlZnMsIGJ1Ziwgc2l6ZW9mKGNSZWZzKSk7CiAgICBidWYgKz0gc2l6ZW9mKGNSZWZzKTsKICAgIG1lbWNweSgmY0lpZHMsIGJ1Ziwgc2l6ZW9mKGNJaWRzKSk7CiAgICBidWYgKz0gc2l6ZW9mKGNJaWRzKTsKICAgIGlpZHMgPSAoSUlEICopYnVmOwoKICAgIGhyID0gSVJlbVVua25vd25fUmVtUXVlcnlJbnRlcmZhY2UoVGhpcy0+aWZhY2UsICZpcGlkLCBjUmVmcywgY0lpZHMsIGlpZHMsICZwUUlSZXN1bHRzKTsKCiAgICAvKiBvdXQgKi8KICAgIHBNc2ctPmNiQnVmZmVyID0gY0lpZHMgKiBzaXplb2YoUkVNUUlSRVNVTFQpOwoKICAgIElfUnBjR2V0QnVmZmVyKChSUENfTUVTU0FHRSAqKXBNc2cpOwogICAgaWYgKGhyKSByZXR1cm4gaHI7CgogICAgYnVmID0gcE1zZy0+QnVmZmVyOwogICAgLyogRklYTUU6IHBRSVJlc3VsdHMgaXMgYSB1bmlxdWUgcG9pbnRlciBzbyBwUUlSZXN1bHRzIGNhbiBiZSBOVUxMISAqLwogICAgbWVtY3B5KGJ1ZiwgcFFJUmVzdWx0cywgY0lpZHMgKiBzaXplb2YoUkVNUUlSRVNVTFQpKTsKCiAgICBicmVhazsKICB9CiAgY2FzZSA0OiAvKiBSZW1BZGRSZWYgKi8KICB7CiAgICBVU0hPUlQgY0lpZHM7CiAgICBSRU1JTlRFUkZBQ0VSRUYgKmlyOwogICAgSFJFU1VMVCAqcFJlc3VsdHM7CgogICAgLyogaW4gKi8KICAgIG1lbWNweSgmY0lpZHMsIGJ1Ziwgc2l6ZW9mKFVTSE9SVCkpOwogICAgYnVmICs9IHNpemVvZihVU0hPUlQpOwogICAgaXIgPSAoUkVNSU5URVJGQUNFUkVGKilidWY7CiAgICBwUmVzdWx0cyA9IENvVGFza01lbUFsbG9jKGNJaWRzICogc2l6ZW9mKEhSRVNVTFQpKTsKICAgIGlmICghcFJlc3VsdHMpIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIGhyID0gSVJlbVVua25vd25fUmVtQWRkUmVmKFRoaXMtPmlmYWNlLCBjSWlkcywgaXIsIHBSZXN1bHRzKTsKCiAgICAvKiBvdXQgKi8KICAgIHBNc2ctPmNiQnVmZmVyID0gY0lpZHMgKiBzaXplb2YoSFJFU1VMVCk7CgogICAgSV9ScGNHZXRCdWZmZXIoKFJQQ19NRVNTQUdFICopcE1zZyk7CiAgICBpZiAoIWhyKQogICAgewogICAgICAgIGJ1ZiA9IHBNc2ctPkJ1ZmZlcjsKICAgICAgICBtZW1jcHkoYnVmLCBwUmVzdWx0cywgY0lpZHMgKiBzaXplb2YoSFJFU1VMVCkpOwogICAgfQoKICAgIENvVGFza01lbUZyZWUocFJlc3VsdHMpOwoKICAgIGJyZWFrOwogIH0KICBjYXNlIDU6IC8qIFJlbVJlbGVhc2UgKi8KICB7CiAgICBVU0hPUlQgY0lpZHM7CiAgICBSRU1JTlRFUkZBQ0VSRUYgKmlyOwoKICAgIC8qIGluICovCiAgICBtZW1jcHkoJmNJaWRzLCBidWYsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIGlyID0gKFJFTUlOVEVSRkFDRVJFRiopYnVmOwoKICAgIGhyID0gSVJlbVVua25vd25fUmVtUmVsZWFzZShUaGlzLT5pZmFjZSwgY0lpZHMsIGlyKTsKCiAgICAvKiBvdXQgKi8KICAgIHBNc2ctPmNiQnVmZmVyID0gMDsKICAgIGJyZWFrOwogIH0KICB9CiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgTFBSUENTVFVCQlVGRkVSIFdJTkFQSSBSZW1VbmtTdHViX0lzSUlEU3VwcG9ydGVkKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKCQkJCQkJICAgICBSRUZJSUQgcmlpZCkKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5Jc0lJRFN1cHBvcnRlZCglcylcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmlpZCkpOwogIHJldHVybiBJc0VxdWFsR1VJRCgmSUlEX0lSZW1Vbmtub3duLCByaWlkKSA/IGlmYWNlIDogTlVMTDsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSZW1VbmtTdHViX0NvdW50UmVmcyhMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBGSVhNRSgiKCVwKS0+Q291bnRSZWZzKClcbiIsIFRoaXMpOwogIHJldHVybiAxOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUmVtVW5rU3R1Yl9EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKCQkJCQkJCUxQVk9JRCAqcHB2KQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgRklYTUUoIiglcCktPkRlYnVnU2VydmVyUXVlcnlJbnRlcmZhY2UoJXApXG4iLFRoaXMscHB2KTsKICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIFJlbVVua1N0dWJfRGVidWdTZXJ2ZXJSZWxlYXNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKCQkJCQkgICAgICBMUFZPSUQgcHYpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBGSVhNRSgiKCVwKS0+RGVidWdTZXJ2ZXJSZWxlYXNlKCVwKVxuIiwgVGhpcywgcHYpOwp9CgpzdGF0aWMgY29uc3QgSVJwY1N0dWJCdWZmZXJWdGJsIFJlbVVua1N0dWJfVlRhYmxlID0KewogIFJlbVVua1N0dWJfUXVlcnlJbnRlcmZhY2UsCiAgUmVtVW5rU3R1Yl9BZGRSZWYsCiAgUmVtVW5rU3R1Yl9SZWxlYXNlLAogIFJlbVVua1N0dWJfQ29ubmVjdCwKICBSZW1VbmtTdHViX0Rpc2Nvbm5lY3QsCiAgUmVtVW5rU3R1Yl9JbnZva2UsCiAgUmVtVW5rU3R1Yl9Jc0lJRFN1cHBvcnRlZCwKICBSZW1VbmtTdHViX0NvdW50UmVmcywKICBSZW1VbmtTdHViX0RlYnVnU2VydmVyUXVlcnlJbnRlcmZhY2UsCiAgUmVtVW5rU3R1Yl9EZWJ1Z1NlcnZlclJlbGVhc2UKfTsKCnN0YXRpYyBIUkVTVUxUIFJlbVVua1N0dWJfQ29uc3RydWN0KElScGNTdHViQnVmZmVyICoqcHBTdHViKQp7CiAgICBSZW1VbmtTdHViICpUaGlzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqVGhpcykpOwogICAgaWYgKCFUaGlzKSByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIFRoaXMtPmxwVnRibCA9ICZSZW1VbmtTdHViX1ZUYWJsZTsKICAgIFRoaXMtPnJlZnMgPSAwOwogICAgVGhpcy0+aWZhY2UgPSBOVUxMOwogICAgKnBwU3R1YiA9IChJUnBjU3R1YkJ1ZmZlciopVGhpczsKICAgIHJldHVybiBTX09LOwp9CgoKdHlwZWRlZiBzdHJ1Y3QgX1JlbVVua1Byb3h5IHsKICAgIGNvbnN0IElSZW1Vbmtub3duVnRibAkJKmxwdnRibF9yZW11bms7CiAgICBjb25zdCBJUnBjUHJveHlCdWZmZXJWdGJsCSpscHZ0YmxfcHJveHk7CiAgICBEV09SRAkJCQlyZWZzOwoKICAgIElScGNDaGFubmVsQnVmZmVyCQkJKmNoYW47CiAgICBJVW5rbm93biAqb3V0ZXJfdW5rbm93bjsKfSBSZW1VbmtQcm94eTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtQcm94eV9RdWVyeUludGVyZmFjZShMUFJFTVVOS05PV04gaWZhY2UsIFJFRklJRCByaWlkLCB2b2lkICoqcHB2KQp7CiAgICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogICAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pCiAgICAgICAgcmV0dXJuIElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKFRoaXMtPm91dGVyX3Vua25vd24sIHJpaWQsIHBwdik7CiAgICBpZiAoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lVbmtub3duKSB8fAogICAgICAgIElzRXF1YWxJSUQocmlpZCwgJklJRF9JUmVtVW5rbm93bikpCiAgICB7CiAgICAgICAgSVJlbVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICAqcHB2ID0gKExQVk9JRClpZmFjZTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJlbVVua1Byb3h5X0FkZFJlZihMUFJFTVVOS05PV04gaWZhY2UpCnsKICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKS0+QWRkUmVmKClcbiIsVGhpcyk7CiAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWZzKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSZW1VbmtQcm94eV9SZWxlYXNlKExQUkVNVU5LTk9XTiBpZmFjZSkKewogIFJlbVVua1Byb3h5ICpUaGlzID0gKFJlbVVua1Byb3h5ICopaWZhY2U7CiAgVUxPTkcgcmVmczsKCiAgVFJBQ0UoIiglcCktPlJlbGVhc2UoKVxuIixUaGlzKTsKICBpZiAoVGhpcy0+b3V0ZXJfdW5rbm93bikKICAgICAgcmVmcyA9IElVbmtub3duX1JlbGVhc2UoVGhpcy0+b3V0ZXJfdW5rbm93bik7CiAgZWxzZSAgICAKICAgICAgcmVmcyA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWZzKTsKCiAgaWYgKCFyZWZzKSB7CiAgICAgIGlmIChUaGlzLT5jaGFuKSBJUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKFRoaXMtPmNoYW4pOwogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CiAgfQogIHJldHVybiByZWZzOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUmVtVW5rUHJveHlfUmVtUXVlcnlJbnRlcmZhY2UoTFBSRU1VTktOT1dOIGlmYWNlLAoJCQkJCQkgUkVGSVBJRCByaXBpZCwKCQkJCQkJIFVMT05HIGNSZWZzLAoJCQkJCQkgVVNIT1JUIGNJaWRzLAoJCQkJCQkgSUlEKiBpaWRzLAoJCQkJCQkgUkVNUUlSRVNVTFQqKiBwcFFJUmVzdWx0cykKewogIFJlbVVua1Byb3h5ICpUaGlzID0gKFJlbVVua1Byb3h5ICopaWZhY2U7CiAgUlBDT0xFTUVTU0FHRSBtc2c7CiAgSFJFU1VMVCBociA9IFNfT0s7CiAgVUxPTkcgc3RhdHVzOwoKICBUUkFDRSgiKCVwKS0+KCVzLCVsZCwlZCwlcCwlcClcbiIsVGhpcywKCWRlYnVnc3RyX2d1aWQocmlwaWQpLGNSZWZzLGNJaWRzLGlpZHMscHBRSVJlc3VsdHMpOwoKICAqcHBRSVJlc3VsdHMgPSBOVUxMOwogIG1lbXNldCgmbXNnLCAwLCBzaXplb2YobXNnKSk7CiAgbXNnLmlNZXRob2QgPSAzOwogIG1zZy5jYkJ1ZmZlciA9IHNpemVvZihJUElEKSArIHNpemVvZihVTE9ORykgKwogICAgc2l6ZW9mKFVTSE9SVCkgKyBjSWlkcypzaXplb2YoSUlEKTsKICBociA9IElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihUaGlzLT5jaGFuLCAmbXNnLCAmSUlEX0lSZW1Vbmtub3duKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgTFBCWVRFIGJ1ZiA9IG1zZy5CdWZmZXI7CiAgICBtZW1jcHkoYnVmLCByaXBpZCwgc2l6ZW9mKElQSUQpKTsKICAgIGJ1ZiArPSBzaXplb2YoSVBJRCk7CiAgICBtZW1jcHkoYnVmLCAmY1JlZnMsIHNpemVvZihVTE9ORykpOwogICAgYnVmICs9IHNpemVvZihVTE9ORyk7CiAgICBtZW1jcHkoYnVmLCAmY0lpZHMsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIG1lbWNweShidWYsIGlpZHMsIGNJaWRzKnNpemVvZihJSUQpKTsKCiAgICBociA9IElScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlKFRoaXMtPmNoYW4sICZtc2csICZzdGF0dXMpOwoKICAgIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICAgIGJ1ZiA9IG1zZy5CdWZmZXI7CiAgICAgICpwcFFJUmVzdWx0cyA9IENvVGFza01lbUFsbG9jKGNJaWRzKnNpemVvZihSRU1RSVJFU1VMVCkpOwogICAgICBtZW1jcHkoKnBwUUlSZXN1bHRzLCBidWYsIGNJaWRzKnNpemVvZihSRU1RSVJFU1VMVCkpOwogICAgfQoKICAgIElScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIoVGhpcy0+Y2hhbiwgJm1zZyk7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtQcm94eV9SZW1BZGRSZWYoTFBSRU1VTktOT1dOIGlmYWNlLAoJCQkJCSBVU0hPUlQgY0ludGVyZmFjZVJlZnMsCgkJCQkJIFJFTUlOVEVSRkFDRVJFRiogSW50ZXJmYWNlUmVmcywKCQkJCQkgSFJFU1VMVCogcFJlc3VsdHMpCnsKICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogIFJQQ09MRU1FU1NBR0UgbXNnOwogIEhSRVNVTFQgaHIgPSBTX09LOwogIFVMT05HIHN0YXR1czsKCiAgVFJBQ0UoIiglcCktPiglZCwlcCwlcClcbiIsVGhpcywKCWNJbnRlcmZhY2VSZWZzLEludGVyZmFjZVJlZnMscFJlc3VsdHMpOwoKICBtZW1zZXQoJm1zZywgMCwgc2l6ZW9mKG1zZykpOwogIG1zZy5pTWV0aG9kID0gNDsKICBtc2cuY2JCdWZmZXIgPSBzaXplb2YoVVNIT1JUKSArIGNJbnRlcmZhY2VSZWZzKnNpemVvZihSRU1JTlRFUkZBQ0VSRUYpOwogIGhyID0gSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKFRoaXMtPmNoYW4sICZtc2csICZJSURfSVJlbVVua25vd24pOwogIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICBMUEJZVEUgYnVmID0gbXNnLkJ1ZmZlcjsKICAgIG1lbWNweShidWYsICZjSW50ZXJmYWNlUmVmcywgc2l6ZW9mKFVTSE9SVCkpOwogICAgYnVmICs9IHNpemVvZihVU0hPUlQpOwogICAgbWVtY3B5KGJ1ZiwgSW50ZXJmYWNlUmVmcywgY0ludGVyZmFjZVJlZnMqc2l6ZW9mKFJFTUlOVEVSRkFDRVJFRikpOwoKICAgIGhyID0gSVJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUoVGhpcy0+Y2hhbiwgJm1zZywgJnN0YXR1cyk7CgogICAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgICAgYnVmID0gbXNnLkJ1ZmZlcjsKICAgICAgbWVtY3B5KHBSZXN1bHRzLCBidWYsIGNJbnRlcmZhY2VSZWZzKnNpemVvZihIUkVTVUxUKSk7CiAgICB9CgogICAgSVJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihUaGlzLT5jaGFuLCAmbXNnKTsKICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1Byb3h5X1JlbVJlbGVhc2UoTFBSRU1VTktOT1dOIGlmYWNlLAoJCQkJCSAgVVNIT1JUIGNJbnRlcmZhY2VSZWZzLAoJCQkJCSAgUkVNSU5URVJGQUNFUkVGKiBJbnRlcmZhY2VSZWZzKQp7CiAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKICBSUENPTEVNRVNTQUdFIG1zZzsKICBIUkVTVUxUIGhyID0gU19PSzsKICBVTE9ORyBzdGF0dXM7CgogIFRSQUNFKCIoJXApLT4oJWQsJXApXG4iLFRoaXMsCgljSW50ZXJmYWNlUmVmcyxJbnRlcmZhY2VSZWZzKTsKCiAgbWVtc2V0KCZtc2csIDAsIHNpemVvZihtc2cpKTsKICBtc2cuaU1ldGhvZCA9IDU7CiAgbXNnLmNiQnVmZmVyID0gc2l6ZW9mKFVTSE9SVCkgKyBjSW50ZXJmYWNlUmVmcypzaXplb2YoUkVNSU5URVJGQUNFUkVGKTsKICBociA9IElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihUaGlzLT5jaGFuLCAmbXNnLCAmSUlEX0lSZW1Vbmtub3duKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgTFBCWVRFIGJ1ZiA9IG1zZy5CdWZmZXI7CiAgICBtZW1jcHkoYnVmLCAmY0ludGVyZmFjZVJlZnMsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIG1lbWNweShidWYsIEludGVyZmFjZVJlZnMsIGNJbnRlcmZhY2VSZWZzKnNpemVvZihSRU1JTlRFUkZBQ0VSRUYpKTsKCiAgICBociA9IElScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlKFRoaXMtPmNoYW4sICZtc2csICZzdGF0dXMpOwoKICAgIElScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIoVGhpcy0+Y2hhbiwgJm1zZyk7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBjb25zdCBJUmVtVW5rbm93blZ0YmwgUmVtVW5rUHJveHlfVlRhYmxlID0KewogIFJlbVVua1Byb3h5X1F1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1Byb3h5X0FkZFJlZiwKICBSZW1VbmtQcm94eV9SZWxlYXNlLAogIFJlbVVua1Byb3h5X1JlbVF1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1Byb3h5X1JlbUFkZFJlZiwKICBSZW1VbmtQcm94eV9SZW1SZWxlYXNlCn07CgoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJVUnBjUHJveHlCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UsUkVGSUlEIHJpaWQsTFBWT0lEICpwcHYpIHsKICAgICpwcHYgPSBOVUxMOwogICAgaWYgKElzRXF1YWxJSUQocmlpZCwmSUlEX0lScGNQcm94eUJ1ZmZlcil8fElzRXF1YWxJSUQocmlpZCwmSUlEX0lVbmtub3duKSkgewoJSVJwY1Byb3h5QnVmZmVyX0FkZFJlZihpZmFjZSk7CgkqcHB2ID0gKExQVk9JRClpZmFjZTsKCXJldHVybiBTX09LOwogICAgfQogICAgRklYTUUoIiglcyksIG5vIGludGVyZmFjZS5cbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9BZGRSZWYoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKFJlbVVua1Byb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZnMpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJVUnBjUHJveHlCdWZmZXJJbXBsX1JlbGVhc2UoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKFJlbVVua1Byb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmcyk7CgogICAgaWYgKCFyZWYpIHsKCUlScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UoVGhpcy0+Y2hhbik7VGhpcy0+Y2hhbiA9IE5VTEw7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CiAgICB9CiAgICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUlVScGNQcm94eUJ1ZmZlckltcGxfQ29ubmVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlLElScGNDaGFubmVsQnVmZmVyKiBwUnBjQ2hhbm5lbEJ1ZmZlcikgewogICAgSUNPTV9USElTX01VTFRJKFJlbVVua1Byb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CgogICAgVGhpcy0+Y2hhbiA9IHBScGNDaGFubmVsQnVmZmVyOwogICAgSVJwY0NoYW5uZWxCdWZmZXJfQWRkUmVmKFRoaXMtPmNoYW4pOwogICAgcmV0dXJuIFNfT0s7Cn0Kc3RhdGljIHZvaWQgV0lOQVBJIFJVUnBjUHJveHlCdWZmZXJJbXBsX0Rpc2Nvbm5lY3QoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKFJlbVVua1Byb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CiAgICBpZiAoVGhpcy0+Y2hhbikgewoJSVJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZShUaGlzLT5jaGFuKTsKCVRoaXMtPmNoYW4gPSBOVUxMOwogICAgfQp9CgoKc3RhdGljIGNvbnN0IElScGNQcm94eUJ1ZmZlclZ0YmwgUlVScGNQcm94eUJ1ZmZlcl9WVGFibGUgPSB7CiAgICBSVVJwY1Byb3h5QnVmZmVySW1wbF9RdWVyeUludGVyZmFjZSwKICAgIFJVUnBjUHJveHlCdWZmZXJJbXBsX0FkZFJlZiwKICAgIFJVUnBjUHJveHlCdWZmZXJJbXBsX1JlbGVhc2UsCiAgICBSVVJwY1Byb3h5QnVmZmVySW1wbF9Db25uZWN0LAogICAgUlVScGNQcm94eUJ1ZmZlckltcGxfRGlzY29ubmVjdAp9OwoKc3RhdGljIEhSRVNVTFQKUmVtVW5rUHJveHlfQ29uc3RydWN0KElVbmtub3duICpwVW5rT3V0ZXIsIExQVk9JRCAqcHB2LExQVk9JRCAqcHBQcm94eSkgewogICAgUmVtVW5rUHJveHkgKlRoaXM7CgogICAgVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKCpUaGlzKSk7CiAgICBpZiAoIVRoaXMpCglyZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBUaGlzLT5scHZ0YmxfcmVtdW5rCT0gJlJlbVVua1Byb3h5X1ZUYWJsZTsKICAgIFRoaXMtPmxwdnRibF9wcm94eQk9ICZSVVJwY1Byb3h5QnVmZmVyX1ZUYWJsZTsKICAgIC8qIG9ubHkgb25lIHJlZmVyZW5jZSBmb3IgdGhlIHByb3h5IGJ1ZmZlciAqLwogICAgVGhpcy0+cmVmcwkJPSAxOwogICAgVGhpcy0+b3V0ZXJfdW5rbm93biA9IHBVbmtPdXRlcjsKICAgICpwcHYJCT0gJihUaGlzLT5scHZ0YmxfcmVtdW5rKTsKICAgICpwcFByb3h5CQk9ICYoVGhpcy0+bHB2dGJsX3Byb3h5KTsKICAgIHJldHVybiBTX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKiBPTEUgUHJveHkvU3R1YiBGYWN0b3J5ICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKUFNGYWNCdWZfUXVlcnlJbnRlcmZhY2UoTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UsIFJFRklJRCBpaWQsIExQVk9JRCAqcHB2KSB7CiAgICBpZiAoSXNFcXVhbElJRChpaWQsJklJRF9JUFNGYWN0b3J5QnVmZmVyKXx8SXNFcXVhbElJRChpaWQsJklJRF9JVW5rbm93bikpIHsKCSpwcHYgPSAoTFBWT0lEKWlmYWNlOwoJLyogTm8gcmVmIGNvdW50aW5nLCBzdGF0aWMgY2xhc3MgKi8KCXJldHVybiBTX09LOwogICAgfQogICAgRklYTUUoIiglcykgdW5rbm93biBJSUQ/XG4iLGRlYnVnc3RyX2d1aWQoaWlkKSk7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBQU0ZhY0J1Zl9BZGRSZWYoTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UpIHsgcmV0dXJuIDI7IH0Kc3RhdGljIFVMT05HIFdJTkFQSSBQU0ZhY0J1Zl9SZWxlYXNlKExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlKSB7IHJldHVybiAxOyB9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKUFNGYWNCdWZfQ3JlYXRlUHJveHkoCiAgICBMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSwgSVVua25vd24qIHBVbmtPdXRlciwgUkVGSUlEIHJpaWQsCiAgICBJUnBjUHJveHlCdWZmZXIgKipwcFByb3h5LCBMUFZPSUQgKnBwdgopIHsKICAgIGlmIChJc0VxdWFsSUlEKCZJSURfSUNsYXNzRmFjdG9yeSxyaWlkKSkKCXJldHVybiBDRlByb3h5X0NvbnN0cnVjdChwVW5rT3V0ZXIsIHBwdiwoTFBWT0lEKilwcFByb3h5KTsKICAgIGVsc2UgaWYgKElzRXF1YWxJSUQoJklJRF9JUmVtVW5rbm93bixyaWlkKSkKCXJldHVybiBSZW1VbmtQcm94eV9Db25zdHJ1Y3QocFVua091dGVyLCBwcHYsKExQVk9JRCopcHBQcm94eSk7CiAgICBGSVhNRSgicHJveHlpbmcgbm90IGltcGxlbWVudGVkIGZvciAoJXMpIHlldCFcbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKUFNGYWNCdWZfQ3JlYXRlU3R1YigKICAgIExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlLCBSRUZJSUQgcmlpZCxJVW5rbm93biAqcFVua1NlcnZlciwKICAgIElScGNTdHViQnVmZmVyKiogcHBTdHViCikgewogICAgSFJFU1VMVCBocmVzOwoKICAgIFRSQUNFKCIoJXMsJXAsJXApXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkscFVua1NlcnZlcixwcFN0dWIpOwoKICAgIGlmIChJc0VxdWFsSUlEKCZJSURfSUNsYXNzRmFjdG9yeSwgcmlpZCkgfHwKICAgICAgICBJc0VxdWFsSUlEKCZJSURfSVVua25vd24sIHJpaWQpIC8qIEZJWE1FOiBmaXh1cCBzdHViIG1hbmFnZXIgYW5kIHJlbW92ZSB0aGlzKi8pIHsKCWhyZXMgPSBDRlN0dWJfQ29uc3RydWN0KHBwU3R1Yik7CglpZiAoIWhyZXMpCgkgICAgSVJwY1N0dWJCdWZmZXJfQ29ubmVjdCgoKnBwU3R1YikscFVua1NlcnZlcik7CglyZXR1cm4gaHJlczsKICAgIH0gZWxzZSBpZiAoSXNFcXVhbElJRCgmSUlEX0lSZW1Vbmtub3duLHJpaWQpKSB7CglocmVzID0gUmVtVW5rU3R1Yl9Db25zdHJ1Y3QocHBTdHViKTsKCWlmICghaHJlcykKCSAgICBJUnBjU3R1YkJ1ZmZlcl9Db25uZWN0KCgqcHBTdHViKSxwVW5rU2VydmVyKTsKCXJldHVybiBocmVzOwogICAgfQogICAgRklYTUUoInN0dWJiaW5nIG5vdCBpbXBsZW1lbnRlZCBmb3IgKCVzKSB5ZXQhXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIElQU0ZhY3RvcnlCdWZmZXJWdGJsIHBzZmFjYnVmdnRibCA9IHsKICAgIFBTRmFjQnVmX1F1ZXJ5SW50ZXJmYWNlLAogICAgUFNGYWNCdWZfQWRkUmVmLAogICAgUFNGYWNCdWZfUmVsZWFzZSwKICAgIFBTRmFjQnVmX0NyZWF0ZVByb3h5LAogICAgUFNGYWNCdWZfQ3JlYXRlU3R1Ygp9OwoKLyogVGhpcyBpcyB0aGUgd2hvbGUgUFNGYWN0b3J5QnVmZmVyIG9iamVjdCwganVzdCB0aGUgdnRhYmxlcHRyICovCnN0YXRpYyBJUFNGYWN0b3J5QnVmZmVyVnRibCAqbHBwc2ZhYyA9ICZwc2ZhY2J1ZnZ0Ymw7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIERsbEdldENsYXNzT2JqZWN0IFtPTEUzMi5AXQogKi8KSFJFU1VMVCBXSU5BUEkgT0xFMzJfRGxsR2V0Q2xhc3NPYmplY3QoUkVGQ0xTSUQgcmNsc2lkLCBSRUZJSUQgaWlkLExQVk9JRCAqcHB2KQp7CiAgICAqcHB2ID0gTlVMTDsKICAgIGlmIChJc0VxdWFsSUlEKHJjbHNpZCwmQ0xTSURfUFNGYWN0b3J5QnVmZmVyKSkgewoJKnBwdiA9ICZscHBzZmFjOwoJcmV0dXJuIFNfT0s7CiAgICB9CiAgICBpZiAoSXNFcXVhbElJRChyY2xzaWQsJkNMU0lEX0RmTWFyc2hhbCkmJigKCQlJc0VxdWFsSUlEKGlpZCwmSUlEX0lDbGFzc0ZhY3RvcnkpIHx8CgkJSXNFcXVhbElJRChpaWQsJklJRF9JVW5rbm93bikKCSkKICAgICkKCXJldHVybiBNQVJTSEFMX0dldFN0YW5kYXJkTWFyc2hhbENGKHBwdik7CiAgICBpZiAoSXNFcXVhbElJRChyY2xzaWQsJkNMU0lEX1N0ZEdsb2JhbEludGVyZmFjZVRhYmxlKSAmJiAoSXNFcXVhbElJRChpaWQsJklJRF9JQ2xhc3NGYWN0b3J5KSB8fCBJc0VxdWFsSUlEKGlpZCwmSUlEX0lVbmtub3duKSkpCiAgICAgICAgcmV0dXJuIFN0ZEdsb2JhbEludGVyZmFjZVRhYmxlX0dldEZhY3RvcnkocHB2KTsKCiAgICBGSVhNRSgiXG5cdENMU0lEOlx0JXMsXG5cdElJRDpcdCVzXG4iLGRlYnVnc3RyX2d1aWQocmNsc2lkKSxkZWJ1Z3N0cl9ndWlkKGlpZCkpOwogICAgcmV0dXJuIENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEU7Cn0K