LyoKICoJT0xFMzIgcHJveHkvc3R1YiBoYW5kbGVyCiAqCiAqICBDb3B5cmlnaHQgMjAwMiAgTWFyY3VzIE1laXNzbmVyCiAqICBDb3B5cmlnaHQgMjAwMSAgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKLyogRG9jdW1lbnRhdGlvbiBvbiBNU0ROOgogKgogKiAoVG9wIGxldmVsIENPTSBkb2N1bWVudGF0aW9uKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2RuYW5jaG9yL2h0bWwvY29tcG9uZW50ZGV2ZWxvcG1lbnRhbmsuYXNwCiAqCiAqIChDT00gUHJveHkpCiAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvY29tL2h0bS9jb21leHRfMXEwcC5hc3AKICoKICogKENPTSBTdHViKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG0vY29tZXh0XzFsaWEuYXNwCiAqCiAqIChNYXJzaGFsKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG0vY29tZXh0XzFnZm4uYXNwCiAqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KI2RlZmluZSBOT05BTUVMRVNTU1RSVUNUCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJvYmpiYXNlLmgiCiNpbmNsdWRlICJvbGUyLmgiCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgInd0eXBlcy5oIgoKI2luY2x1ZGUgImNvbXBvYmpfcHJpdmF0ZS5oIgojaW5jbHVkZSAibW9uaWtlci5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJVUnBjUHJveHlCdWZmZXJJbXBsX1JlbGVhc2UoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSk7CgovKiBGcm9tOiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZW4tdXMvY29tL2NtaV9tXzRsZGEuYXNwCiAqCiAqIFRoZSBmaXJzdCB0aW1lIGEgY2xpZW50IHJlcXVlc3RzIGEgcG9pbnRlciB0byBhbiBpbnRlcmZhY2Ugb24gYQogKiBwYXJ0aWN1bGFyIG9iamVjdCwgQ09NIGxvYWRzIGFuIElDbGFzc0ZhY3Rvcnkgc3R1YiBpbiB0aGUgc2VydmVyCiAqIHByb2Nlc3MgYW5kIHVzZXMgaXQgdG8gbWFyc2hhbCB0aGUgZmlyc3QgcG9pbnRlciBiYWNrIHRvIHRoZQogKiBjbGllbnQuIEluIHRoZSBjbGllbnQgcHJvY2VzcywgQ09NIGxvYWRzIHRoZSBnZW5lcmljIHByb3h5IGZvciB0aGUKICogY2xhc3MgZmFjdG9yeSBvYmplY3QgYW5kIGNhbGxzIGl0cyBpbXBsZW1lbnRhdGlvbiBvZiBJTWFyc2hhbCB0bwogKiB1bm1hcnNoYWwgdGhhdCBmaXJzdCBwb2ludGVyLiBDT00gdGhlbiBjcmVhdGVzIHRoZSBmaXJzdCBpbnRlcmZhY2UKICogcHJveHkgYW5kIGhhbmRzIGl0IGEgcG9pbnRlciB0byB0aGUgUlBDIGNoYW5uZWwuIEZpbmFsbHksIENPTSByZXR1cm5zCiAqIHRoZSBJQ2xhc3NGYWN0b3J5IHBvaW50ZXIgdG8gdGhlIGNsaWVudCwgd2hpY2ggdXNlcyBpdCB0byBjYWxsCiAqIElDbGFzc0ZhY3Rvcnk6OkNyZWF0ZUluc3RhbmNlLCBwYXNzaW5nIGl0IGEgcmVmZXJlbmNlIHRvIHRoZSBpbnRlcmZhY2UuCiAqCiAqIEJhY2sgaW4gdGhlIHNlcnZlciBwcm9jZXNzLCBDT00gbm93IGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlCiAqIG9iamVjdCwgYWxvbmcgd2l0aCBhIHN0dWIgZm9yIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlLiBUaGlzIHN0dWIgbWFyc2hhbHMKICogdGhlIGludGVyZmFjZSBwb2ludGVyIGJhY2sgdG8gdGhlIGNsaWVudCBwcm9jZXNzLCB3aGVyZSBhbm90aGVyIG9iamVjdAogKiBwcm94eSBpcyBjcmVhdGVkLCB0aGlzIHRpbWUgZm9yIHRoZSBvYmplY3QgaXRzZWxmLiBBbHNvIGNyZWF0ZWQgaXMgYQogKiBwcm94eSBmb3IgdGhlIHJlcXVlc3RlZCBpbnRlcmZhY2UsIGEgcG9pbnRlciB0byB3aGljaCBpcyByZXR1cm5lZCB0bwogKiB0aGUgY2xpZW50LiBXaXRoIHN1YnNlcXVlbnQgY2FsbHMgdG8gb3RoZXIgaW50ZXJmYWNlcyBvbiB0aGUgb2JqZWN0LAogKiBDT00gd2lsbCBsb2FkIHRoZSBhcHByb3ByaWF0ZSBpbnRlcmZhY2Ugc3R1YnMgYW5kIHByb3hpZXMgYXMgbmVlZGVkLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX0NGU3R1YiB7CiAgICBjb25zdCBJUnBjU3R1YkJ1ZmZlclZ0YmwgICAqbHB2dGJsOwogICAgTE9ORwkJCXJlZjsKCiAgICBMUFVOS05PV04JCQlwVW5rU2VydmVyOwp9IENGU3R1YjsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpDRlN0dWJfUXVlcnlJbnRlcmZhY2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpIHsKICAgIGlmIChJc0VxdWFsSUlEKCZJSURfSVVua25vd24scmlpZCl8fElzRXF1YWxJSUQoJklJRF9JUnBjU3R1YkJ1ZmZlcixyaWlkKSkgewoJKnBwdiA9IChMUFZPSUQpaWZhY2U7CglJVW5rbm93bl9BZGRSZWYoaWZhY2UpOwoJcmV0dXJuIFNfT0s7CiAgICB9CiAgICBGSVhNRSgiKCVzKSwgaW50ZXJmYWNlIG5vdCBzdXBwb3J0ZWQuXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKQ0ZTdHViX0FkZFJlZihMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpIHsKICAgIENGU3R1YiAqVGhpcyA9IChDRlN0dWIgKilpZmFjZTsKICAgIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpDRlN0dWJfUmVsZWFzZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpIHsKICAgIENGU3R1YiAqVGhpcyA9IChDRlN0dWIgKilpZmFjZTsKICAgIFVMT05HIHJlZjsKCiAgICByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKICAgIGlmICghcmVmKSB7CiAgICAgICAgSVJwY1N0dWJCdWZmZXJfRGlzY29ubmVjdChpZmFjZSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwogICAgfQogICAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCkNGU3R1Yl9Db25uZWN0KExQUlBDU1RVQkJVRkZFUiBpZmFjZSwgSVVua25vd24gKnBVbmtTZXJ2ZXIpIHsKICAgIENGU3R1YiAqVGhpcyA9IChDRlN0dWIgKilpZmFjZTsKCiAgICBUaGlzLT5wVW5rU2VydmVyID0gcFVua1NlcnZlcjsKICAgIElVbmtub3duX0FkZFJlZihwVW5rU2VydmVyKTsKICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkKQ0ZTdHViX0Rpc2Nvbm5lY3QoTFBSUENTVFVCQlVGRkVSIGlmYWNlKSB7CiAgICBDRlN0dWIgKlRoaXMgPSAoQ0ZTdHViICopaWZhY2U7CgogICAgaWYgKFRoaXMtPnBVbmtTZXJ2ZXIpIHsKICAgICAgICBJVW5rbm93bl9SZWxlYXNlKFRoaXMtPnBVbmtTZXJ2ZXIpOwogICAgICAgIFRoaXMtPnBVbmtTZXJ2ZXIgPSBOVUxMOwogICAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKQ0ZTdHViX0ludm9rZSgKICAgIExQUlBDU1RVQkJVRkZFUiBpZmFjZSxSUENPTEVNRVNTQUdFKiBtc2csSVJwY0NoYW5uZWxCdWZmZXIqIGNoYW5idWYKKSB7CiAgICBDRlN0dWIgKlRoaXMgPSAoQ0ZTdHViICopaWZhY2U7CiAgICBIUkVTVUxUIGhyZXM7CgogICAgaWYgKG1zZy0+aU1ldGhvZCA9PSAzKSB7IC8qIENyZWF0ZUluc3RhbmNlICovCglJSUQgaWlkOwoJSUNsYXNzRmFjdG9yeQkqY2xhc3NmYWM7CglJVW5rbm93bgkqcHB2OwoJSVN0cmVhbQkJKnBTdG07CglTVEFUU1RHCQlzdHN0ZzsKCVVMQVJHRV9JTlRFR0VSCW5ld3BvczsKCUxBUkdFX0lOVEVHRVIJc2Vla3RvOwoJVUxPTkcJCXJlczsKCglpZiAobXNnLT5jYkJ1ZmZlciA8IHNpemVvZihJSUQpKSB7CiAgICAgICAgICAgIEZJWE1FKCJOb3QgZW5vdWdoIGJ5dGVzIGluIGJ1ZmZlciAoJWQpP1xuIixtc2ctPmNiQnVmZmVyKTsKCSAgICByZXR1cm4gRV9GQUlMOwoJfQoJbWVtY3B5KCZpaWQsbXNnLT5CdWZmZXIsc2l6ZW9mKGlpZCkpOwoJVFJBQ0UoIi0+Q3JlYXRlSW5zdGFuY2UoJXMpXG4iLGRlYnVnc3RyX2d1aWQoJmlpZCkpOwoJaHJlcyA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKFRoaXMtPnBVbmtTZXJ2ZXIsJklJRF9JQ2xhc3NGYWN0b3J5LChMUFZPSUQqKSZjbGFzc2ZhYyk7CglpZiAoaHJlcykgewoJICAgIEZJWE1FKCJPbGUgc2VydmVyIGRvZXMgbm90IHByb3ZpZGUgYW4gSUNsYXNzRmFjdG9yeT9cbiIpOwoJICAgIHJldHVybiBocmVzOwoJfQoJaHJlcyA9IElDbGFzc0ZhY3RvcnlfQ3JlYXRlSW5zdGFuY2UoY2xhc3NmYWMsTlVMTCwmaWlkLChMUFZPSUQqKSZwcHYpOwoJSUNsYXNzRmFjdG9yeV9SZWxlYXNlKGNsYXNzZmFjKTsKCWlmIChocmVzKSB7CgkgICAgbXNnLT5jYkJ1ZmZlciA9IDA7CgkgICAgRklYTUUoIkZhaWxlZCB0byBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgJXNcbiIsZGVidWdzdHJfZ3VpZCgmaWlkKSk7CgkgICAgcmV0dXJuIGhyZXM7Cgl9CglocmVzID0gQ3JlYXRlU3RyZWFtT25IR2xvYmFsKDAsVFJVRSwmcFN0bSk7CglpZiAoaHJlcykgewoJICAgIEZJWE1FKCJGYWlsZWQgdG8gY3JlYXRlIHN0cmVhbSBvbiBoZ2xvYmFsXG4iKTsKCSAgICByZXR1cm4gaHJlczsKCX0KCWhyZXMgPSBDb01hcnNoYWxJbnRlcmZhY2UocFN0bSwmaWlkLHBwdiwwLE5VTEwsMCk7CglJVW5rbm93bl9SZWxlYXNlKChJVW5rbm93biopcHB2KTsKCWlmIChocmVzKSB7CiAgICAgICAgICAgIEZJWE1FKCJDb01hcnNoYWxJbnRlcmZhY2UgZmFpbGVkLCAleCFcbiIsaHJlcyk7CgkgICAgbXNnLT5jYkJ1ZmZlciA9IDA7CgkgICAgcmV0dXJuIGhyZXM7Cgl9CglocmVzID0gSVN0cmVhbV9TdGF0KHBTdG0sJnN0c3RnLDApOwoJaWYgKGhyZXMpIHsKCSAgICBGSVhNRSgiU3RhdCBmYWlsZWQuXG4iKTsKCSAgICByZXR1cm4gaHJlczsKCX0KCgltc2ctPmNiQnVmZmVyID0gc3RzdGcuY2JTaXplLnUuTG93UGFydDsKCiAgICAgICAgSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKGNoYW5idWYsIG1zZywgJklJRF9JQ2xhc3NGYWN0b3J5KTsKICAgICAgICBpZiAoaHJlcykgcmV0dXJuIGhyZXM7CgoJc2Vla3RvLnUuTG93UGFydCA9IDA7c2Vla3RvLnUuSGlnaFBhcnQgPSAwOwoJaHJlcyA9IElTdHJlYW1fU2VlayhwU3RtLHNlZWt0byxTRUVLX1NFVCwmbmV3cG9zKTsKCWlmIChocmVzKSB7CiAgICAgICAgICAgIEZJWE1FKCJJU3RyZWFtX1NlZWsgZmFpbGVkLCAleFxuIixocmVzKTsKCSAgICByZXR1cm4gaHJlczsKCX0KCWhyZXMgPSBJU3RyZWFtX1JlYWQocFN0bSxtc2ctPkJ1ZmZlcixtc2ctPmNiQnVmZmVyLCZyZXMpOwoJaWYgKGhyZXMpIHsKICAgICAgICAgICAgRklYTUUoIlN0cmVhbSBSZWFkIGZhaWxlZCwgJXhcbiIsaHJlcyk7CgkgICAgcmV0dXJuIGhyZXM7Cgl9CglJU3RyZWFtX1JlbGVhc2UocFN0bSk7CglyZXR1cm4gU19PSzsKICAgIH0KICAgIEZJWE1FKCIoJXAsJXApLCBzdHViIVxuIixtc2csY2hhbmJ1Zik7CiAgICBGSVhNRSgiaU1ldGhvZCBpcyAlZFxuIixtc2ctPmlNZXRob2QpOwogICAgRklYTUUoImNiQnVmZmVyIGlzICVkXG4iLG1zZy0+Y2JCdWZmZXIpOwogICAgcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIExQUlBDU1RVQkJVRkZFUiBXSU5BUEkKQ0ZTdHViX0lzSUlEU3VwcG9ydGVkKExQUlBDU1RVQkJVRkZFUiBpZmFjZSxSRUZJSUQgcmlpZCkgewogICAgRklYTUUoIiglcyksIHN0dWIhXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKQ0ZTdHViX0NvdW50UmVmcyhMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpIHsKICAgIEZJWE1FKCIoKSwgc3R1YiFcbiIpOwogICAgcmV0dXJuIDE7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpDRlN0dWJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2Usdm9pZCoqIHBwdikgewogICAgRklYTUUoIiglcCksIHN0dWIhXG4iLHBwdik7CiAgICByZXR1cm4gRV9GQUlMOwp9CnN0YXRpYyB2b2lkICAgIFdJTkFQSQpDRlN0dWJfRGVidWdTZXJ2ZXJSZWxlYXNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSx2b2lkICpwdikgewogICAgRklYTUUoIiglcCksIHN0dWIhXG4iLHB2KTsKfQoKc3RhdGljIGNvbnN0IElScGNTdHViQnVmZmVyVnRibCBjZnN0dWJ2dCA9IHsKICAgIENGU3R1Yl9RdWVyeUludGVyZmFjZSwKICAgIENGU3R1Yl9BZGRSZWYsCiAgICBDRlN0dWJfUmVsZWFzZSwKICAgIENGU3R1Yl9Db25uZWN0LAogICAgQ0ZTdHViX0Rpc2Nvbm5lY3QsCiAgICBDRlN0dWJfSW52b2tlLAogICAgQ0ZTdHViX0lzSUlEU3VwcG9ydGVkLAogICAgQ0ZTdHViX0NvdW50UmVmcywKICAgIENGU3R1Yl9EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlLAogICAgQ0ZTdHViX0RlYnVnU2VydmVyUmVsZWFzZQp9OwoKc3RhdGljIEhSRVNVTFQKQ0ZTdHViX0NvbnN0cnVjdChMUFJQQ1NUVUJCVUZGRVIgKnBwdikgewogICAgQ0ZTdHViICpjZnN0dWI7CiAgICBjZnN0dWIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZihDRlN0dWIpKTsKICAgIGlmICghY2ZzdHViKQoJcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICAqcHB2ID0gKExQUlBDU1RVQkJVRkZFUiljZnN0dWI7CiAgICBjZnN0dWItPmxwdnRibAk9ICZjZnN0dWJ2dDsKICAgIGNmc3R1Yi0+cmVmCQk9IDE7CiAgICByZXR1cm4gU19PSzsKfQoKLyogU2luY2Ugd2UgY3JlYXRlIHByb3h5IGJ1ZmZlcnMgYW5kIGNsYXNzZmFjdG9yeSBpbiBhIHBhaXIsIHRoZXJlIGlzCiAqIG5vIG5lZWQgZm9yIDIgc2VwYXJhdGUgc3RydWN0cy4gSnVzdCBwdXQgdGhlbSBpbiBvbmUsIGJ1dCByZW1lbWJlcgogKiB0aGUgcmVmY291bnQuCiAqLwp0eXBlZGVmIHN0cnVjdCBfQ0ZQcm94eSB7CiAgICBjb25zdCBJQ2xhc3NGYWN0b3J5VnRibAkJKmxwdnRibF9jZjsKICAgIGNvbnN0IElScGNQcm94eUJ1ZmZlclZ0YmwJKmxwdnRibF9wcm94eTsKICAgIExPTkcJCQkJcmVmOwoKICAgIElScGNDaGFubmVsQnVmZmVyCQkJKmNoYW5idWY7CiAgICBJVW5rbm93biAqb3V0ZXJfdW5rbm93bjsKfSBDRlByb3h5OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElScGNQcm94eUJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSxSRUZJSUQgcmlpZCxMUFZPSUQgKnBwdikgewogICAgKnBwdiA9IE5VTEw7CiAgICBpZiAoSXNFcXVhbElJRChyaWlkLCZJSURfSVJwY1Byb3h5QnVmZmVyKXx8SXNFcXVhbElJRChyaWlkLCZJSURfSVVua25vd24pKSB7CglJUnBjUHJveHlCdWZmZXJfQWRkUmVmKGlmYWNlKTsKCSpwcHYgPSAoTFBWT0lEKWlmYWNlOwoJcmV0dXJuIFNfT0s7CiAgICB9CiAgICBGSVhNRSgiKCVzKSwgbm8gaW50ZXJmYWNlLlxuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElScGNQcm94eUJ1ZmZlckltcGxfQWRkUmVmKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBpZiAoIXJlZikgewogICAgICAgIElScGNQcm94eUJ1ZmZlcl9EaXNjb25uZWN0KGlmYWNlKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CiAgICB9CiAgICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVJwY1Byb3h5QnVmZmVySW1wbF9Db25uZWN0KExQUlBDUFJPWFlCVUZGRVIgaWZhY2UsSVJwY0NoYW5uZWxCdWZmZXIqIHBScGNDaGFubmVsQnVmZmVyKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwoKICAgIFRoaXMtPmNoYW5idWYgPSBwUnBjQ2hhbm5lbEJ1ZmZlcjsKICAgIElScGNDaGFubmVsQnVmZmVyX0FkZFJlZihUaGlzLT5jaGFuYnVmKTsKICAgIHJldHVybiBTX09LOwp9CnN0YXRpYyB2b2lkIFdJTkFQSSBJUnBjUHJveHlCdWZmZXJJbXBsX0Rpc2Nvbm5lY3QoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX3Byb3h5LGlmYWNlKTsKICAgIGlmIChUaGlzLT5jaGFuYnVmKSB7CglJUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKFRoaXMtPmNoYW5idWYpOwoJVGhpcy0+Y2hhbmJ1ZiA9IE5VTEw7CiAgICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpDRlByb3h5X1F1ZXJ5SW50ZXJmYWNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlLFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX2NmLGlmYWNlKTsKICAgIGlmIChUaGlzLT5vdXRlcl91bmtub3duKSByZXR1cm4gSVVua25vd25fUXVlcnlJbnRlcmZhY2UoVGhpcy0+b3V0ZXJfdW5rbm93biwgcmlpZCwgcHB2KTsKICAgICpwcHYgPSBOVUxMOwogICAgaWYgKElzRXF1YWxJSUQoJklJRF9JQ2xhc3NGYWN0b3J5LHJpaWQpIHx8IElzRXF1YWxJSUQoJklJRF9JVW5rbm93bixyaWlkKSkgewoJKnBwdiA9IChMUFZPSUQpaWZhY2U7CglJQ2xhc3NGYWN0b3J5X0FkZFJlZihpZmFjZSk7CglyZXR1cm4gU19PSzsKICAgIH0KICAgIGlmIChJc0VxdWFsSUlEKHJpaWQsJklJRF9JTWFyc2hhbCkpIC8qIGp1c3QgdG8gYXZvaWQgZGVidWcgb3V0cHV0ICovCglyZXR1cm4gRV9OT0lOVEVSRkFDRTsKICAgIEZJWE1FKCJVbmhhbmRsZWQgaW50ZXJmYWNlOiAlc1xuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgQ0ZQcm94eV9BZGRSZWYoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9jZixpZmFjZSk7CiAgICBpZiAoVGhpcy0+b3V0ZXJfdW5rbm93bikgcmV0dXJuIElVbmtub3duX0FkZFJlZihUaGlzLT5vdXRlcl91bmtub3duKTsKICAgIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIENGUHJveHlfUmVsZWFzZShMUENMQVNTRkFDVE9SWSBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX2NmLGlmYWNlKTsKICAgIGlmIChUaGlzLT5vdXRlcl91bmtub3duKQogICAgICAgIHJldHVybiBJVW5rbm93bl9SZWxlYXNlKFRoaXMtPm91dGVyX3Vua25vd24pOwogICAgZWxzZQogICAgICAgIHJldHVybiBJUnBjUHJveHlCdWZmZXJJbXBsX1JlbGVhc2UoKElScGNQcm94eUJ1ZmZlciAqKSZUaGlzLT5scHZ0YmxfcHJveHkpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ0ZQcm94eV9DcmVhdGVJbnN0YW5jZSgKICAgIExQQ0xBU1NGQUNUT1JZIGlmYWNlLAogICAgTFBVTktOT1dOIHBVbmtPdXRlciwvKiBbaW5dICovCiAgICBSRUZJSUQgcmlpZCwJLyogW2luXSAqLwogICAgTFBWT0lEICpwcHYJCS8qIFtvdXRdICovCikgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX2NmLGlmYWNlKTsKICAgIEhSRVNVTFQJCWhyZXM7CiAgICBMUFNUUkVBTQkJcFN0cmVhbTsKICAgIEhHTE9CQUwJCWhHbG9iYWw7CiAgICBVTE9ORwkJc3JzdGF0dXM7CiAgICBSUENPTEVNRVNTQUdFCW1zZzsKCiAgICBUUkFDRSgiKCVwLCVzLCVwKVxuIixwVW5rT3V0ZXIsZGVidWdzdHJfZ3VpZChyaWlkKSxwcHYpOwoKICAgIC8qIFNlbmQgQ3JlYXRlSW5zdGFuY2UgdG8gdGhlIHJlbW90ZSBjbGFzc2ZhY3RvcnkuCiAgICAgKgogICAgICogRGF0YTogT25seSB0aGUgJ0lJRCcuCiAgICAgKi8KICAgIG1zZy5pTWV0aG9kICA9IDM7CiAgICBtc2cuY2JCdWZmZXIgPSBzaXplb2YoKnJpaWQpOwogICAgbXNnLkJ1ZmZlcgkgPSBOVUxMOwogICAgaHJlcyA9IElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihUaGlzLT5jaGFuYnVmLCZtc2csJklJRF9JQ2xhc3NGYWN0b3J5KTsKICAgIGlmIChocmVzKSB7CglGSVhNRSgiSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyIGZhaWxlZCB3aXRoICV4P1xuIixocmVzKTsKCXJldHVybiBocmVzOwogICAgfQogICAgbWVtY3B5KG1zZy5CdWZmZXIscmlpZCxzaXplb2YoKnJpaWQpKTsKICAgIGhyZXMgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShUaGlzLT5jaGFuYnVmLCZtc2csJnNyc3RhdHVzKTsKICAgIGlmIChocmVzKSB7CglGSVhNRSgiSVJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUgZmFpbGVkIHdpdGggJXg/XG4iLGhyZXMpOwoJcmV0dXJuIGhyZXM7CiAgICB9CgogICAgaWYgKCFtc2cuY2JCdWZmZXIpIC8qIGludGVyZmFjZSBub3QgZm91bmQgb24gcmVtb3RlICovCglyZXR1cm4gc3JzdGF0dXM7CgogICAgLyogV2UgZ290IGJhY2s6IFtNYXJzaGFsbGVkIEludGVyZmFjZSBkYXRhXSAqLwogICAgVFJBQ0UoImdvdCAlZCBieXRlcyBkYXRhLlxuIixtc2cuY2JCdWZmZXIpOwogICAgaEdsb2JhbCA9IEdsb2JhbEFsbG9jKEdNRU1fTU9WRUFCTEV8R01FTV9OT0RJU0NBUkR8R01FTV9TSEFSRSxtc2cuY2JCdWZmZXIpOwogICAgbWVtY3B5KEdsb2JhbExvY2soaEdsb2JhbCksbXNnLkJ1ZmZlcixtc2cuY2JCdWZmZXIpOwogICAgaHJlcyA9IENyZWF0ZVN0cmVhbU9uSEdsb2JhbChoR2xvYmFsLFRSVUUsJnBTdHJlYW0pOwogICAgaWYgKGhyZXMpIHsKCUZJWE1FKCJDcmVhdGVTdHJlYW1PbkhHbG9iYWwgZmFpbGVkIHdpdGggJXhcbiIsaHJlcyk7CglyZXR1cm4gaHJlczsKICAgIH0KICAgIGhyZXMgPSBDb1VubWFyc2hhbEludGVyZmFjZSgKCSAgICBwU3RyZWFtLAoJICAgIHJpaWQsCgkgICAgcHB2CiAgICApOwogICAgSVN0cmVhbV9SZWxlYXNlKHBTdHJlYW0pOyAvKiBEb2VzIEdsb2JhbEZyZWUgaEdsb2JhbCB0b28uICovCiAgICBpZiAoaHJlcykgewoJRklYTUUoIkNvTWFyc2hhbEludGVyZmFjZSBmYWlsZWQsICV4XG4iLGhyZXMpOwoJcmV0dXJuIGhyZXM7CiAgICB9CiAgICByZXR1cm4gU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENGUHJveHlfTG9ja1NlcnZlcihMUENMQVNTRkFDVE9SWSBpZmFjZSxCT09MIGZMb2NrKSB7CiAgICAvKklDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9jZixpZmFjZSk7Ki8KICAgIEZJWE1FKCIoJWQpLCBzdHViIVxuIixmTG9jayk7CiAgICAvKiBiYXNpY2FsbHk6IHdyaXRlIEJPT0wsIHJlYWQgZW1wdHkgKi8KICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgY29uc3QgSVJwY1Byb3h5QnVmZmVyVnRibCBwc3BidnRibCA9IHsKICAgIElScGNQcm94eUJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJUnBjUHJveHlCdWZmZXJJbXBsX0FkZFJlZiwKICAgIElScGNQcm94eUJ1ZmZlckltcGxfUmVsZWFzZSwKICAgIElScGNQcm94eUJ1ZmZlckltcGxfQ29ubmVjdCwKICAgIElScGNQcm94eUJ1ZmZlckltcGxfRGlzY29ubmVjdAp9OwpzdGF0aWMgY29uc3QgSUNsYXNzRmFjdG9yeVZ0YmwgY2Zwcm94eXZ0ID0gewogICAgQ0ZQcm94eV9RdWVyeUludGVyZmFjZSwKICAgIENGUHJveHlfQWRkUmVmLAogICAgQ0ZQcm94eV9SZWxlYXNlLAogICAgQ0ZQcm94eV9DcmVhdGVJbnN0YW5jZSwKICAgIENGUHJveHlfTG9ja1NlcnZlcgp9OwoKc3RhdGljIEhSRVNVTFQKQ0ZQcm94eV9Db25zdHJ1Y3QoSVVua25vd24gKnBVbmtPdXRlciwgTFBWT0lEICpwcHYsTFBWT0lEICpwcFByb3h5KSB7CiAgICBDRlByb3h5ICpjZjsKCiAgICBjZiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKENGUHJveHkpKTsKICAgIGlmICghY2YpCglyZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBjZi0+bHB2dGJsX2NmCT0gJmNmcHJveHl2dDsKICAgIGNmLT5scHZ0YmxfcHJveHkJPSAmcHNwYnZ0Ymw7CiAgICAvKiBvbmUgcmVmZXJlbmNlIGZvciB0aGUgcHJveHkgYnVmZmVyICovCiAgICBjZi0+cmVmCQk9IDE7CiAgICBjZi0+b3V0ZXJfdW5rbm93biA9IHBVbmtPdXRlcjsKICAgICpwcHYJCT0gJihjZi0+bHB2dGJsX2NmKTsKICAgICpwcFByb3h5CQk9ICYoY2YtPmxwdnRibF9wcm94eSk7CiAgICAvKiBhbmQgb25lIHJlZmVyZW5jZSBmb3IgdGhlIG9iamVjdCAqLwogICAgSVVua25vd25fQWRkUmVmKChJVW5rbm93biAqKSpwcHYpOwogICAgcmV0dXJuIFNfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqIElSZW1Vbmtub3duIFByb3h5L1N0dWIgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgp0eXBlZGVmIHN0cnVjdAp7CiAgICBjb25zdCBJUnBjU3R1YkJ1ZmZlclZ0YmwgKmxwVnRibDsKICAgIExPTkcgcmVmczsKICAgIElSZW1Vbmtub3duICppZmFjZTsKfSBSZW1VbmtTdHViOwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1N0dWJfUXVlcnlJbnRlcmZhY2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAoJCQkJCSAgICAgUkVGSUlEIHJpaWQsCgkJCQkJICAgICBMUFZPSUQgKm9iaikKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5RdWVyeUludGVyZmFjZSglcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLG9iaik7CiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24scmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JUnBjU3R1YkJ1ZmZlcixyaWlkKSkgewogICAgKm9iaiA9IFRoaXM7CiAgICByZXR1cm4gU19PSzsKICB9CiAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUmVtVW5rU3R1Yl9BZGRSZWYoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPkFkZFJlZigpXG4iLFRoaXMpOwogIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmcyk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUmVtVW5rU3R1Yl9SZWxlYXNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSkKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFVMT05HIHJlZnM7CiAgVFJBQ0UoIiglcCktPlJlbGVhc2UoKVxuIixUaGlzKTsKICByZWZzID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZnMpOwogIGlmICghcmVmcykKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwogIHJldHVybiByZWZzOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUmVtVW5rU3R1Yl9Db25uZWN0KExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKCQkJCSAgICAgIExQVU5LTk9XTiBscFVua1NlcnZlcikKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5Db25uZWN0KCVwKVxuIixUaGlzLGxwVW5rU2VydmVyKTsKICBUaGlzLT5pZmFjZSA9IChJUmVtVW5rbm93biopbHBVbmtTZXJ2ZXI7CiAgSVJlbVVua25vd25fQWRkUmVmKFRoaXMtPmlmYWNlKTsKICByZXR1cm4gU19PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIFJlbVVua1N0dWJfRGlzY29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+RGlzY29ubmVjdCgpXG4iLFRoaXMpOwogIElVbmtub3duX1JlbGVhc2UoVGhpcy0+aWZhY2UpOwogIFRoaXMtPmlmYWNlID0gTlVMTDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1N0dWJfSW52b2tlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKCQkJCSAgICAgUFJQQ09MRU1FU1NBR0UgcE1zZywKCQkJCSAgICAgTFBSUENDSEFOTkVMQlVGRkVSIHBDaGFubmVsKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVUxPTkcgaU1ldGhvZCA9IHBNc2ctPmlNZXRob2Q7CiAgTFBCWVRFIGJ1ZiA9IHBNc2ctPkJ1ZmZlcjsKICBIUkVTVUxUIGhyID0gUlBDX0VfSU5WQUxJRE1FVEhPRDsKCiAgVFJBQ0UoIiglcCktPkludm9rZSglcCwlcCkgbWV0aG9kICVkXG4iLCBUaGlzLCBwTXNnLCBwQ2hhbm5lbCwgaU1ldGhvZCk7CiAgc3dpdGNoIChpTWV0aG9kKQogIHsKICBjYXNlIDM6IC8qIFJlbVF1ZXJ5SW50ZXJmYWNlICovCiAgewogICAgSVBJRCBpcGlkOwogICAgVUxPTkcgY1JlZnM7CiAgICBVU0hPUlQgY0lpZHM7CiAgICBJSUQgKmlpZHM7CiAgICBSRU1RSVJFU1VMVCAqcFFJUmVzdWx0cyA9IE5VTEw7CgogICAgLyogaW4gKi8KICAgIG1lbWNweSgmaXBpZCwgYnVmLCBzaXplb2YoaXBpZCkpOwogICAgYnVmICs9IHNpemVvZihpcGlkKTsKICAgIG1lbWNweSgmY1JlZnMsIGJ1Ziwgc2l6ZW9mKGNSZWZzKSk7CiAgICBidWYgKz0gc2l6ZW9mKGNSZWZzKTsKICAgIG1lbWNweSgmY0lpZHMsIGJ1Ziwgc2l6ZW9mKGNJaWRzKSk7CiAgICBidWYgKz0gc2l6ZW9mKGNJaWRzKTsKICAgIGlpZHMgPSAoSUlEICopYnVmOwoKICAgIGhyID0gSVJlbVVua25vd25fUmVtUXVlcnlJbnRlcmZhY2UoVGhpcy0+aWZhY2UsICZpcGlkLCBjUmVmcywgY0lpZHMsIGlpZHMsICZwUUlSZXN1bHRzKTsKCiAgICAvKiBvdXQgKi8KICAgIHBNc2ctPmNiQnVmZmVyID0gY0lpZHMgKiBzaXplb2YoUkVNUUlSRVNVTFQpICsgc2l6ZW9mKEhSRVNVTFQpOwoKICAgIElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihwQ2hhbm5lbCwgcE1zZywgJklJRF9JUmVtVW5rbm93bik7CgogICAgYnVmID0gcE1zZy0+QnVmZmVyOwogICAgKihIUkVTVUxUICopYnVmID0gaHI7CiAgICBidWYgKz0gc2l6ZW9mKEhSRVNVTFQpOwogICAgCiAgICBpZiAoaHIpIHJldHVybiBocjsKICAgIC8qIEZJWE1FOiBwUUlSZXN1bHRzIGlzIGEgdW5pcXVlIHBvaW50ZXIgc28gcFFJUmVzdWx0cyBjYW4gYmUgTlVMTCEgKi8KICAgIG1lbWNweShidWYsIHBRSVJlc3VsdHMsIGNJaWRzICogc2l6ZW9mKFJFTVFJUkVTVUxUKSk7CgogICAgYnJlYWs7CiAgfQogIGNhc2UgNDogLyogUmVtQWRkUmVmICovCiAgewogICAgVVNIT1JUIGNJaWRzOwogICAgUkVNSU5URVJGQUNFUkVGICppcjsKICAgIEhSRVNVTFQgKnBSZXN1bHRzOwoKICAgIC8qIGluICovCiAgICBtZW1jcHkoJmNJaWRzLCBidWYsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIGlyID0gKFJFTUlOVEVSRkFDRVJFRiopYnVmOwogICAgcFJlc3VsdHMgPSBDb1Rhc2tNZW1BbGxvYyhjSWlkcyAqIHNpemVvZihIUkVTVUxUKSk7CiAgICBpZiAoIXBSZXN1bHRzKSByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBociA9IElSZW1Vbmtub3duX1JlbUFkZFJlZihUaGlzLT5pZmFjZSwgY0lpZHMsIGlyLCBwUmVzdWx0cyk7CgogICAgLyogb3V0ICovCiAgICBwTXNnLT5jYkJ1ZmZlciA9IGNJaWRzICogc2l6ZW9mKEhSRVNVTFQpOwoKICAgIElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihwQ2hhbm5lbCwgcE1zZywgJklJRF9JUmVtVW5rbm93bik7CiAgICBpZiAoIWhyKQogICAgewogICAgICAgIGJ1ZiA9IHBNc2ctPkJ1ZmZlcjsKICAgICAgICBtZW1jcHkoYnVmLCBwUmVzdWx0cywgY0lpZHMgKiBzaXplb2YoSFJFU1VMVCkpOwogICAgfQoKICAgIENvVGFza01lbUZyZWUocFJlc3VsdHMpOwoKICAgIGJyZWFrOwogIH0KICBjYXNlIDU6IC8qIFJlbVJlbGVhc2UgKi8KICB7CiAgICBVU0hPUlQgY0lpZHM7CiAgICBSRU1JTlRFUkZBQ0VSRUYgKmlyOwoKICAgIC8qIGluICovCiAgICBtZW1jcHkoJmNJaWRzLCBidWYsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIGlyID0gKFJFTUlOVEVSRkFDRVJFRiopYnVmOwoKICAgIGhyID0gSVJlbVVua25vd25fUmVtUmVsZWFzZShUaGlzLT5pZmFjZSwgY0lpZHMsIGlyKTsKCiAgICAvKiBvdXQgKi8KICAgIHBNc2ctPmNiQnVmZmVyID0gMDsKICAgIElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihwQ2hhbm5lbCwgcE1zZywgJklJRF9JUmVtVW5rbm93bik7CiAgICBicmVhazsKICB9CiAgfQogIHJldHVybiBocjsKfQoKc3RhdGljIExQUlBDU1RVQkJVRkZFUiBXSU5BUEkgUmVtVW5rU3R1Yl9Jc0lJRFN1cHBvcnRlZChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJCSAgICAgUkVGSUlEIHJpaWQpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+SXNJSURTdXBwb3J0ZWQoJXMpXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICByZXR1cm4gSXNFcXVhbEdVSUQoJklJRF9JUmVtVW5rbm93biwgcmlpZCkgPyBpZmFjZSA6IE5VTEw7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUmVtVW5rU3R1Yl9Db3VudFJlZnMoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgRklYTUUoIiglcCktPkNvdW50UmVmcygpXG4iLCBUaGlzKTsKICByZXR1cm4gMTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1N0dWJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJCQlMUFZPSUQgKnBwdikKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIEZJWE1FKCIoJXApLT5EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlKCVwKVxuIixUaGlzLHBwdik7CiAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBSZW1VbmtTdHViX0RlYnVnU2VydmVyUmVsZWFzZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkJICAgICAgTFBWT0lEIHB2KQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgRklYTUUoIiglcCktPkRlYnVnU2VydmVyUmVsZWFzZSglcClcbiIsIFRoaXMsIHB2KTsKfQoKc3RhdGljIGNvbnN0IElScGNTdHViQnVmZmVyVnRibCBSZW1VbmtTdHViX1ZUYWJsZSA9CnsKICBSZW1VbmtTdHViX1F1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1N0dWJfQWRkUmVmLAogIFJlbVVua1N0dWJfUmVsZWFzZSwKICBSZW1VbmtTdHViX0Nvbm5lY3QsCiAgUmVtVW5rU3R1Yl9EaXNjb25uZWN0LAogIFJlbVVua1N0dWJfSW52b2tlLAogIFJlbVVua1N0dWJfSXNJSURTdXBwb3J0ZWQsCiAgUmVtVW5rU3R1Yl9Db3VudFJlZnMsCiAgUmVtVW5rU3R1Yl9EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1N0dWJfRGVidWdTZXJ2ZXJSZWxlYXNlCn07CgpzdGF0aWMgSFJFU1VMVCBSZW1VbmtTdHViX0NvbnN0cnVjdChJUnBjU3R1YkJ1ZmZlciAqKnBwU3R1YikKewogICAgUmVtVW5rU3R1YiAqVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKlRoaXMpKTsKICAgIGlmICghVGhpcykgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICBUaGlzLT5scFZ0YmwgPSAmUmVtVW5rU3R1Yl9WVGFibGU7CiAgICBUaGlzLT5yZWZzID0gMTsKICAgIFRoaXMtPmlmYWNlID0gTlVMTDsKICAgICpwcFN0dWIgPSAoSVJwY1N0dWJCdWZmZXIqKVRoaXM7CiAgICByZXR1cm4gU19PSzsKfQoKCnR5cGVkZWYgc3RydWN0IF9SZW1VbmtQcm94eSB7CiAgICBjb25zdCBJUmVtVW5rbm93blZ0YmwJCSpscHZ0YmxfcmVtdW5rOwogICAgY29uc3QgSVJwY1Byb3h5QnVmZmVyVnRibAkqbHB2dGJsX3Byb3h5OwogICAgTE9ORwkJCQlyZWZzOwoKICAgIElScGNDaGFubmVsQnVmZmVyCQkJKmNoYW47CiAgICBJVW5rbm93biAqb3V0ZXJfdW5rbm93bjsKfSBSZW1VbmtQcm94eTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtQcm94eV9RdWVyeUludGVyZmFjZShMUFJFTVVOS05PV04gaWZhY2UsIFJFRklJRCByaWlkLCB2b2lkICoqcHB2KQp7CiAgICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogICAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pCiAgICAgICAgcmV0dXJuIElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKFRoaXMtPm91dGVyX3Vua25vd24sIHJpaWQsIHBwdik7CiAgICBpZiAoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lVbmtub3duKSB8fAogICAgICAgIElzRXF1YWxJSUQocmlpZCwgJklJRF9JUmVtVW5rbm93bikpCiAgICB7CiAgICAgICAgSVJlbVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICAqcHB2ID0gKExQVk9JRClpZmFjZTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJlbVVua1Byb3h5X0FkZFJlZihMUFJFTVVOS05PV04gaWZhY2UpCnsKICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogIFVMT05HIHJlZnM7CgogIFRSQUNFKCIoJXApLT5BZGRSZWYoKVxuIixUaGlzKTsKCiAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pCiAgICAgIHJlZnMgPSBJVW5rbm93bl9BZGRSZWYoVGhpcy0+b3V0ZXJfdW5rbm93bik7CiAgZWxzZQogICAgICByZWZzID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZnMpOwogIHJldHVybiByZWZzOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJlbVVua1Byb3h5X1JlbGVhc2UoTFBSRU1VTktOT1dOIGlmYWNlKQp7CiAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCktPlJlbGVhc2UoKVxuIixUaGlzKTsKICBpZiAoVGhpcy0+b3V0ZXJfdW5rbm93bikKICAgICAgcmV0dXJuIElVbmtub3duX1JlbGVhc2UoVGhpcy0+b3V0ZXJfdW5rbm93bik7CiAgZWxzZQogICAgICByZXR1cm4gSVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlKChJUnBjUHJveHlCdWZmZXIgKikmVGhpcy0+bHB2dGJsX3Byb3h5KTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1Byb3h5X1JlbVF1ZXJ5SW50ZXJmYWNlKExQUkVNVU5LTk9XTiBpZmFjZSwKCQkJCQkJIFJFRklQSUQgcmlwaWQsCgkJCQkJCSBVTE9ORyBjUmVmcywKCQkJCQkJIFVTSE9SVCBjSWlkcywKCQkJCQkJIElJRCogaWlkcywKCQkJCQkJIFJFTVFJUkVTVUxUKiogcHBRSVJlc3VsdHMpCnsKICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogIFJQQ09MRU1FU1NBR0UgbXNnOwogIEhSRVNVTFQgaHIgPSBTX09LOwogIFVMT05HIHN0YXR1czsKCiAgVFJBQ0UoIiglcCktPiglcywlZCwlZCwlcCwlcClcbiIsVGhpcywKCWRlYnVnc3RyX2d1aWQocmlwaWQpLGNSZWZzLGNJaWRzLGlpZHMscHBRSVJlc3VsdHMpOwoKICAqcHBRSVJlc3VsdHMgPSBOVUxMOwogIG1lbXNldCgmbXNnLCAwLCBzaXplb2YobXNnKSk7CiAgbXNnLmlNZXRob2QgPSAzOwogIG1zZy5jYkJ1ZmZlciA9IHNpemVvZihJUElEKSArIHNpemVvZihVTE9ORykgKwogICAgc2l6ZW9mKFVTSE9SVCkgKyBjSWlkcypzaXplb2YoSUlEKTsKICBociA9IElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihUaGlzLT5jaGFuLCAmbXNnLCAmSUlEX0lSZW1Vbmtub3duKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgTFBCWVRFIGJ1ZiA9IG1zZy5CdWZmZXI7CiAgICBtZW1jcHkoYnVmLCByaXBpZCwgc2l6ZW9mKElQSUQpKTsKICAgIGJ1ZiArPSBzaXplb2YoSVBJRCk7CiAgICBtZW1jcHkoYnVmLCAmY1JlZnMsIHNpemVvZihVTE9ORykpOwogICAgYnVmICs9IHNpemVvZihVTE9ORyk7CiAgICBtZW1jcHkoYnVmLCAmY0lpZHMsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIG1lbWNweShidWYsIGlpZHMsIGNJaWRzKnNpemVvZihJSUQpKTsKCiAgICBociA9IElScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlKFRoaXMtPmNoYW4sICZtc2csICZzdGF0dXMpOwoKICAgIGJ1ZiA9IG1zZy5CdWZmZXI7CgogICAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgICAgICBociA9ICooSFJFU1VMVCAqKWJ1ZjsKICAgICAgICBidWYgKz0gc2l6ZW9mKEhSRVNVTFQpOwogICAgfQoKICAgIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICAgICpwcFFJUmVzdWx0cyA9IENvVGFza01lbUFsbG9jKGNJaWRzKnNpemVvZihSRU1RSVJFU1VMVCkpOwogICAgICBtZW1jcHkoKnBwUUlSZXN1bHRzLCBidWYsIGNJaWRzKnNpemVvZihSRU1RSVJFU1VMVCkpOwogICAgfQoKICAgIElScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIoVGhpcy0+Y2hhbiwgJm1zZyk7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtQcm94eV9SZW1BZGRSZWYoTFBSRU1VTktOT1dOIGlmYWNlLAoJCQkJCSBVU0hPUlQgY0ludGVyZmFjZVJlZnMsCgkJCQkJIFJFTUlOVEVSRkFDRVJFRiogSW50ZXJmYWNlUmVmcywKCQkJCQkgSFJFU1VMVCogcFJlc3VsdHMpCnsKICBSZW1VbmtQcm94eSAqVGhpcyA9IChSZW1VbmtQcm94eSAqKWlmYWNlOwogIFJQQ09MRU1FU1NBR0UgbXNnOwogIEhSRVNVTFQgaHIgPSBTX09LOwogIFVMT05HIHN0YXR1czsKCiAgVFJBQ0UoIiglcCktPiglZCwlcCwlcClcbiIsVGhpcywKCWNJbnRlcmZhY2VSZWZzLEludGVyZmFjZVJlZnMscFJlc3VsdHMpOwoKICBtZW1zZXQoJm1zZywgMCwgc2l6ZW9mKG1zZykpOwogIG1zZy5pTWV0aG9kID0gNDsKICBtc2cuY2JCdWZmZXIgPSBzaXplb2YoVVNIT1JUKSArIGNJbnRlcmZhY2VSZWZzKnNpemVvZihSRU1JTlRFUkZBQ0VSRUYpOwogIGhyID0gSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKFRoaXMtPmNoYW4sICZtc2csICZJSURfSVJlbVVua25vd24pOwogIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICBMUEJZVEUgYnVmID0gbXNnLkJ1ZmZlcjsKICAgIG1lbWNweShidWYsICZjSW50ZXJmYWNlUmVmcywgc2l6ZW9mKFVTSE9SVCkpOwogICAgYnVmICs9IHNpemVvZihVU0hPUlQpOwogICAgbWVtY3B5KGJ1ZiwgSW50ZXJmYWNlUmVmcywgY0ludGVyZmFjZVJlZnMqc2l6ZW9mKFJFTUlOVEVSRkFDRVJFRikpOwoKICAgIGhyID0gSVJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUoVGhpcy0+Y2hhbiwgJm1zZywgJnN0YXR1cyk7CgogICAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgICAgYnVmID0gbXNnLkJ1ZmZlcjsKICAgICAgbWVtY3B5KHBSZXN1bHRzLCBidWYsIGNJbnRlcmZhY2VSZWZzKnNpemVvZihIUkVTVUxUKSk7CiAgICB9CgogICAgSVJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihUaGlzLT5jaGFuLCAmbXNnKTsKICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1Byb3h5X1JlbVJlbGVhc2UoTFBSRU1VTktOT1dOIGlmYWNlLAoJCQkJCSAgVVNIT1JUIGNJbnRlcmZhY2VSZWZzLAoJCQkJCSAgUkVNSU5URVJGQUNFUkVGKiBJbnRlcmZhY2VSZWZzKQp7CiAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKICBSUENPTEVNRVNTQUdFIG1zZzsKICBIUkVTVUxUIGhyID0gU19PSzsKICBVTE9ORyBzdGF0dXM7CgogIFRSQUNFKCIoJXApLT4oJWQsJXApXG4iLFRoaXMsCgljSW50ZXJmYWNlUmVmcyxJbnRlcmZhY2VSZWZzKTsKCiAgbWVtc2V0KCZtc2csIDAsIHNpemVvZihtc2cpKTsKICBtc2cuaU1ldGhvZCA9IDU7CiAgbXNnLmNiQnVmZmVyID0gc2l6ZW9mKFVTSE9SVCkgKyBjSW50ZXJmYWNlUmVmcypzaXplb2YoUkVNSU5URVJGQUNFUkVGKTsKICBociA9IElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihUaGlzLT5jaGFuLCAmbXNnLCAmSUlEX0lSZW1Vbmtub3duKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgTFBCWVRFIGJ1ZiA9IG1zZy5CdWZmZXI7CiAgICBtZW1jcHkoYnVmLCAmY0ludGVyZmFjZVJlZnMsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIG1lbWNweShidWYsIEludGVyZmFjZVJlZnMsIGNJbnRlcmZhY2VSZWZzKnNpemVvZihSRU1JTlRFUkZBQ0VSRUYpKTsKCiAgICBociA9IElScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlKFRoaXMtPmNoYW4sICZtc2csICZzdGF0dXMpOwoKICAgIElScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIoVGhpcy0+Y2hhbiwgJm1zZyk7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBjb25zdCBJUmVtVW5rbm93blZ0YmwgUmVtVW5rUHJveHlfVlRhYmxlID0KewogIFJlbVVua1Byb3h5X1F1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1Byb3h5X0FkZFJlZiwKICBSZW1VbmtQcm94eV9SZWxlYXNlLAogIFJlbVVua1Byb3h5X1JlbVF1ZXJ5SW50ZXJmYWNlLAogIFJlbVVua1Byb3h5X1JlbUFkZFJlZiwKICBSZW1VbmtQcm94eV9SZW1SZWxlYXNlCn07CgoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJVUnBjUHJveHlCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UsUkVGSUlEIHJpaWQsTFBWT0lEICpwcHYpIHsKICAgICpwcHYgPSBOVUxMOwogICAgaWYgKElzRXF1YWxJSUQocmlpZCwmSUlEX0lScGNQcm94eUJ1ZmZlcil8fElzRXF1YWxJSUQocmlpZCwmSUlEX0lVbmtub3duKSkgewoJSVJwY1Byb3h5QnVmZmVyX0FkZFJlZihpZmFjZSk7CgkqcHB2ID0gKExQVk9JRClpZmFjZTsKCXJldHVybiBTX09LOwogICAgfQogICAgRklYTUUoIiglcyksIG5vIGludGVyZmFjZS5cbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9BZGRSZWYoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKFJlbVVua1Byb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CiAgICBUUkFDRSgiJXAsICVkXG4iLCBpZmFjZSwgVGhpcy0+cmVmcyArIDEpOwogICAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWZzKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShSZW1VbmtQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZnMpOwogICAgVFJBQ0UoIiVwLCAlZFxuIiwgaWZhY2UsIHJlZik7CiAgICBpZiAoIXJlZikgewogICAgICAgIElScGNQcm94eUJ1ZmZlcl9EaXNjb25uZWN0KGlmYWNlKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CiAgICB9CiAgICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUlVScGNQcm94eUJ1ZmZlckltcGxfQ29ubmVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlLElScGNDaGFubmVsQnVmZmVyKiBwUnBjQ2hhbm5lbEJ1ZmZlcikgewogICAgSUNPTV9USElTX01VTFRJKFJlbVVua1Byb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CgogICAgVFJBQ0UoIiVwLCAlcFxuIiwgaWZhY2UsIHBScGNDaGFubmVsQnVmZmVyKTsKICAgIFRoaXMtPmNoYW4gPSBwUnBjQ2hhbm5lbEJ1ZmZlcjsKICAgIElScGNDaGFubmVsQnVmZmVyX0FkZFJlZihUaGlzLT5jaGFuKTsKICAgIHJldHVybiBTX09LOwp9CnN0YXRpYyB2b2lkIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9EaXNjb25uZWN0KExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShSZW1VbmtQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwogICAgVFJBQ0UoIiVwLCAlcFxuIiwgaWZhY2UsIFRoaXMtPmNoYW4pOwogICAgaWYgKFRoaXMtPmNoYW4pIHsKCUlScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UoVGhpcy0+Y2hhbik7CglUaGlzLT5jaGFuID0gTlVMTDsKICAgIH0KfQoKCnN0YXRpYyBjb25zdCBJUnBjUHJveHlCdWZmZXJWdGJsIFJVUnBjUHJveHlCdWZmZXJfVlRhYmxlID0gewogICAgUlVScGNQcm94eUJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBSVVJwY1Byb3h5QnVmZmVySW1wbF9BZGRSZWYsCiAgICBSVVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlLAogICAgUlVScGNQcm94eUJ1ZmZlckltcGxfQ29ubmVjdCwKICAgIFJVUnBjUHJveHlCdWZmZXJJbXBsX0Rpc2Nvbm5lY3QKfTsKCnN0YXRpYyBIUkVTVUxUClJlbVVua1Byb3h5X0NvbnN0cnVjdChJVW5rbm93biAqcFVua091dGVyLCBMUFZPSUQgKnBwdixMUFZPSUQgKnBwUHJveHkpIHsKICAgIFJlbVVua1Byb3h5ICpUaGlzOwoKICAgIFRoaXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZigqVGhpcykpOwogICAgaWYgKCFUaGlzKQoJcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgVGhpcy0+bHB2dGJsX3JlbXVuawk9ICZSZW1VbmtQcm94eV9WVGFibGU7CiAgICBUaGlzLT5scHZ0YmxfcHJveHkJPSAmUlVScGNQcm94eUJ1ZmZlcl9WVGFibGU7CiAgICAvKiBvbmx5IG9uZSByZWZlcmVuY2UgZm9yIHRoZSBwcm94eSBidWZmZXIgKi8KICAgIFRoaXMtPnJlZnMJCT0gMTsKICAgIFRoaXMtPm91dGVyX3Vua25vd24gPSBwVW5rT3V0ZXI7CiAgICAqcHB2CQk9ICYoVGhpcy0+bHB2dGJsX3JlbXVuayk7CiAgICAqcHBQcm94eQkJPSAmKFRoaXMtPmxwdnRibF9wcm94eSk7CiAgICAvKiBhbmQgb25lIHJlZmVyZW5jZSBmb3IgdGhlIG9iamVjdCAqLwogICAgSVVua25vd25fQWRkUmVmKChJVW5rbm93biAqKSpwcHYpOwogICAgcmV0dXJuIFNfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqIE9MRSBQcm94eS9TdHViIEZhY3RvcnkgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpQU0ZhY0J1Zl9RdWVyeUludGVyZmFjZShMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSwgUkVGSUlEIGlpZCwgTFBWT0lEICpwcHYpIHsKICAgIGlmIChJc0VxdWFsSUlEKGlpZCwmSUlEX0lQU0ZhY3RvcnlCdWZmZXIpfHxJc0VxdWFsSUlEKGlpZCwmSUlEX0lVbmtub3duKSkgewoJKnBwdiA9IChMUFZPSUQpaWZhY2U7CgkvKiBObyByZWYgY291bnRpbmcsIHN0YXRpYyBjbGFzcyAqLwoJcmV0dXJuIFNfT0s7CiAgICB9CiAgICBGSVhNRSgiKCVzKSB1bmtub3duIElJRD9cbiIsZGVidWdzdHJfZ3VpZChpaWQpKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFBTRmFjQnVmX0FkZFJlZihMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSkgeyByZXR1cm4gMjsgfQpzdGF0aWMgVUxPTkcgV0lOQVBJIFBTRmFjQnVmX1JlbGVhc2UoTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UpIHsgcmV0dXJuIDE7IH0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpQU0ZhY0J1Zl9DcmVhdGVQcm94eSgKICAgIExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlLCBJVW5rbm93biogcFVua091dGVyLCBSRUZJSUQgcmlpZCwKICAgIElScGNQcm94eUJ1ZmZlciAqKnBwUHJveHksIExQVk9JRCAqcHB2CikgewogICAgaWYgKElzRXF1YWxJSUQoJklJRF9JQ2xhc3NGYWN0b3J5LHJpaWQpKQoJcmV0dXJuIENGUHJveHlfQ29uc3RydWN0KHBVbmtPdXRlciwgcHB2LChMUFZPSUQqKXBwUHJveHkpOwogICAgZWxzZSBpZiAoSXNFcXVhbElJRCgmSUlEX0lSZW1Vbmtub3duLHJpaWQpKQoJcmV0dXJuIFJlbVVua1Byb3h5X0NvbnN0cnVjdChwVW5rT3V0ZXIsIHBwdiwoTFBWT0lEKilwcFByb3h5KTsKICAgIEZJWE1FKCJwcm94eWluZyBub3QgaW1wbGVtZW50ZWQgZm9yICglcykgeWV0IVxuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpQU0ZhY0J1Zl9DcmVhdGVTdHViKAogICAgTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UsIFJFRklJRCByaWlkLElVbmtub3duICpwVW5rU2VydmVyLAogICAgSVJwY1N0dWJCdWZmZXIqKiBwcFN0dWIKKSB7CiAgICBIUkVTVUxUIGhyZXM7CgogICAgVFJBQ0UoIiglcywlcCwlcClcbiIsZGVidWdzdHJfZ3VpZChyaWlkKSxwVW5rU2VydmVyLHBwU3R1Yik7CgogICAgaWYgKElzRXF1YWxJSUQoJklJRF9JQ2xhc3NGYWN0b3J5LCByaWlkKSB8fAogICAgICAgIElzRXF1YWxJSUQoJklJRF9JVW5rbm93biwgcmlpZCkgLyogRklYTUU6IGZpeHVwIHN0dWIgbWFuYWdlciBhbmQgcmVtb3ZlIHRoaXMqLykgewoJaHJlcyA9IENGU3R1Yl9Db25zdHJ1Y3QocHBTdHViKTsKCWlmICghaHJlcykKCSAgICBJUnBjU3R1YkJ1ZmZlcl9Db25uZWN0KCgqcHBTdHViKSxwVW5rU2VydmVyKTsKCXJldHVybiBocmVzOwogICAgfSBlbHNlIGlmIChJc0VxdWFsSUlEKCZJSURfSVJlbVVua25vd24scmlpZCkpIHsKCWhyZXMgPSBSZW1VbmtTdHViX0NvbnN0cnVjdChwcFN0dWIpOwoJaWYgKCFocmVzKQoJICAgIElScGNTdHViQnVmZmVyX0Nvbm5lY3QoKCpwcFN0dWIpLHBVbmtTZXJ2ZXIpOwoJcmV0dXJuIGhyZXM7CiAgICB9CiAgICBGSVhNRSgic3R1YmJpbmcgbm90IGltcGxlbWVudGVkIGZvciAoJXMpIHlldCFcbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgY29uc3QgSVBTRmFjdG9yeUJ1ZmZlclZ0YmwgcHNmYWNidWZ2dGJsID0gewogICAgUFNGYWNCdWZfUXVlcnlJbnRlcmZhY2UsCiAgICBQU0ZhY0J1Zl9BZGRSZWYsCiAgICBQU0ZhY0J1Zl9SZWxlYXNlLAogICAgUFNGYWNCdWZfQ3JlYXRlUHJveHksCiAgICBQU0ZhY0J1Zl9DcmVhdGVTdHViCn07CgovKiBUaGlzIGlzIHRoZSB3aG9sZSBQU0ZhY3RvcnlCdWZmZXIgb2JqZWN0LCBqdXN0IHRoZSB2dGFibGVwdHIgKi8Kc3RhdGljIGNvbnN0IElQU0ZhY3RvcnlCdWZmZXJWdGJsICpscHBzZmFjID0gJnBzZmFjYnVmdnRibDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRGxsR2V0Q2xhc3NPYmplY3QgW09MRTMyLkBdCiAqLwpIUkVTVUxUIFdJTkFQSSBEbGxHZXRDbGFzc09iamVjdChSRUZDTFNJRCByY2xzaWQsIFJFRklJRCBpaWQsTFBWT0lEICpwcHYpCnsKICAgICpwcHYgPSBOVUxMOwogICAgaWYgKElzRXF1YWxJSUQocmNsc2lkLCAmQ0xTSURfUFNGYWN0b3J5QnVmZmVyKSkKICAgICAgICByZXR1cm4gSVBTRmFjdG9yeUJ1ZmZlcl9RdWVyeUludGVyZmFjZSgoSVBTRmFjdG9yeUJ1ZmZlciAqKSZscHBzZmFjLCBpaWQsIHBwdik7CiAgICBpZiAoSXNFcXVhbElJRChyY2xzaWQsJkNMU0lEX0RmTWFyc2hhbCkmJigKCQlJc0VxdWFsSUlEKGlpZCwmSUlEX0lDbGFzc0ZhY3RvcnkpIHx8CgkJSXNFcXVhbElJRChpaWQsJklJRF9JVW5rbm93bikKCSkKICAgICkKCXJldHVybiBNQVJTSEFMX0dldFN0YW5kYXJkTWFyc2hhbENGKHBwdik7CiAgICBpZiAoSXNFcXVhbElJRChyY2xzaWQsJkNMU0lEX1N0ZEdsb2JhbEludGVyZmFjZVRhYmxlKSAmJiAoSXNFcXVhbElJRChpaWQsJklJRF9JQ2xhc3NGYWN0b3J5KSB8fCBJc0VxdWFsSUlEKGlpZCwmSUlEX0lVbmtub3duKSkpCiAgICAgICAgcmV0dXJuIFN0ZEdsb2JhbEludGVyZmFjZVRhYmxlX0dldEZhY3RvcnkocHB2KTsKICAgIGlmIChJc0VxdWFsQ0xTSUQocmNsc2lkLCAmQ0xTSURfRmlsZU1vbmlrZXIpKQogICAgICAgIHJldHVybiBGaWxlTW9uaWtlckNGX0NyZWF0ZShpaWQsIHBwdik7CiAgICBpZiAoSXNFcXVhbENMU0lEKHJjbHNpZCwgJkNMU0lEX0l0ZW1Nb25pa2VyKSkKICAgICAgICByZXR1cm4gSXRlbU1vbmlrZXJDRl9DcmVhdGUoaWlkLCBwcHYpOwogICAgaWYgKElzRXF1YWxDTFNJRChyY2xzaWQsICZDTFNJRF9BbnRpTW9uaWtlcikpCiAgICAgICAgcmV0dXJuIEFudGlNb25pa2VyQ0ZfQ3JlYXRlKGlpZCwgcHB2KTsKICAgIGlmIChJc0VxdWFsQ0xTSUQocmNsc2lkLCAmQ0xTSURfQ29tcG9zaXRlTW9uaWtlcikpCiAgICAgICAgcmV0dXJuIENvbXBvc2l0ZU1vbmlrZXJDRl9DcmVhdGUoaWlkLCBwcHYpOwogICAgaWYgKElzRXF1YWxDTFNJRChyY2xzaWQsICZDTFNJRF9DbGFzc01vbmlrZXIpKQogICAgICAgIHJldHVybiBDbGFzc01vbmlrZXJDRl9DcmVhdGUoaWlkLCBwcHYpOwoKICAgIEZJWE1FKCJcblx0Q0xTSUQ6XHQlcyxcblx0SUlEOlx0JXNcbiIsZGVidWdzdHJfZ3VpZChyY2xzaWQpLGRlYnVnc3RyX2d1aWQoaWlkKSk7CiAgICByZXR1cm4gQ0xBU1NfRV9DTEFTU05PVEFWQUlMQUJMRTsKfQo=