LyoKICogQ29weXJpZ2h0IDE5OTctMjAwMCBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTgtMjAwMCBMaW9uZWwgVWxtZXIKICogQ29weXJpZ2h0IDIwMDAtMjAwMSBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMgSW5jLgogKiBDb3B5cmlnaHQgMjAwNiBTdGVmYW4gRPZzaW5nZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKI2luY2x1ZGUgImV4Y3B0LmgiCgojaW5jbHVkZSAiZGRyYXcuaCIKI2luY2x1ZGUgImQzZC5oIgoKI2luY2x1ZGUgImRkcmF3X3ByaXZhdGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRkcmF3KTsKCnN0YXRpYyBCT09MIElEaXJlY3REcmF3SW1wbF9ERFNEX01hdGNoKGNvbnN0IEREU1VSRkFDRURFU0MyKiByZXF1ZXN0ZWQsIGNvbnN0IEREU1VSRkFDRURFU0MyKiBwcm92aWRlZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0RHJhd0ltcGxfQXR0YWNoRDNERGV2aWNlKElEaXJlY3REcmF3SW1wbCAqVGhpcywgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqcHJpbWFyeSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZShJRGlyZWN0RHJhd0ltcGwgKlRoaXMsIEREU1VSRkFDRURFU0MyICpwRERTRCwgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqKnBwU3VyZiwgVUlOVCBsZXZlbCk7CgovKiBEZXZpY2UgaWRlbnRpZmllci4gRG9uJ3QgcmVsYXkgaXQgdG8gV2luZUQzRCAqLwpzdGF0aWMgY29uc3QgRERERVZJQ0VJREVOVElGSUVSMiBkZXZpY2VpZGVudGlmaWVyID0KewogICAgImRpc3BsYXkiLAogICAgIkRpcmVjdERyYXcgSEFMIiwKICAgIHsgeyAweDAwMDEwMDAxLCAweDAwMDEwMDAxIH0gfSwKICAgIDAsIDAsIDAsIDAsCiAgICAvKiBhODM3M2MxMC03YWM0LTRkZWItODQ5YS0wMDk4NDRkMDhiMmQgKi8KICAgIHsweGE4MzczYzEwLDB4N2FjNCwweDRkZWIsIHsweDg0LDB4OWEsMHgwMCwweDk4LDB4NDQsMHhkMCwweDhiLDB4MmR9fSwKICAgIDAKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJVW5rbm93biBNZXRob2RzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlF1ZXJ5SW50ZXJmYWNlCiAqCiAqIFF1ZXJpZXMgZGlmZmVyZW50IGludGVyZmFjZXMgb2YgdGhlIERpcmVjdERyYXcgb2JqZWN0LiBJdCBjYW4gcmV0dXJuCiAqIElEaXJlY3REcmF3IGludGVyZmFjZXMgaW4gdmVyc2lvbiAxLCAyLCA0IGFuZCA3LCBhbmQgSURpcmVjdDNEIGludGVyZmFjZXMKICogaW4gdmVyc2lvbiAxLCAyLCAzIGFuZCA3LiBBbiBJRGlyZWN0M0REZXZpY2UgY2FuIGJlIGNyZWF0ZWQgd2l0aCB0aGlzCiAqIG1ldGhvZC4KICogVGhlIHJldHVybmVkIGludGVyZmFjZSBpcyBBZGRSZWYoKS1lZCBiZWZvcmUgaXQncyByZXR1cm5lZAogKgogKiBSdWxlcyBmb3IgUXVlcnlJbnRlcmZhY2U6CiAqICBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/IFwKICogICAgdXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG1sLzZkYjE3ZWQ4LTA2ZTQtNGJhZS1iYzI2LTExMzE3NmNjN2UwZS5hc3AKICoKICogVXNlZCBmb3IgdmVyc2lvbiAxLCAyLCA0IGFuZCA3CiAqCiAqIFBhcmFtczoKICogIHJlZmlpZDogSW50ZXJmYWNlIElEIGFza2VkIGZvcgogKiAgb2JqOiBVc2VkIHRvIHJldHVybiB0aGUgaW50ZXJmYWNlIHBvaW50ZXIKICoKICogUmV0dXJuczoKICogIFNfT0sgaWYgYW4gaW50ZXJmYWNlIHdhcyBmb3VuZAogKiAgRV9OT0lOVEVSRkFDRSBpZiB0aGUgcmVxdWVzdGVkIGludGVyZmFjZSB3YXNuJ3QgZm91bmQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1F1ZXJ5SW50ZXJmYWNlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmVmaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqKm9iaikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwoKICAgIC8qIEFjY29yZGluZyB0byBDT00gZG9jcywgaWYgdGhlIFF1ZXJ5SW50ZXJmYWNlIGZhaWxzLCBvYmogc2hvdWxkIGJlIHNldCB0byBOVUxMICovCiAgICAqb2JqID0gTlVMTDsKCiAgICBpZighcmVmaWlkKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIC8qIENoZWNrIERpcmVjdERyYXcgSW50ZXJmYWNlcyAqLwogICAgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JVW5rbm93biwgcmVmaWlkICkgfHwKICAgICAgICAgSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdERyYXc3LCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3Nyk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3REcmF3NyBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3REcmF3NCwgcmVmaWlkICkgKQogICAgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzQpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0RHJhdzQgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgIH0KICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0RHJhdzIsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXcyKTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdERyYXcyIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdERyYXcsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXcpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0RHJhdyBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQoKICAgIC8qIERpcmVjdDNECiAgICAgKiBUaGUgcmVmY291bnQgdW5pdCB0ZXN0IHJldmVhbGVkIHRoYXQgYW4gSURpcmVjdDNENyBpbnRlcmZhY2UgY2FuIG9ubHkgYmUgcXVlcmllZAogICAgICogZnJvbSBhIERpcmVjdERyYXcgb2JqZWN0IHRoYXQgd2FzIGNyZWF0ZWQgYXMgYW4gSURpcmVjdERyYXc3IGludGVyZmFjZS4gTm8gaWRlYQogICAgICogd2hvIGhhZCB0aGlzIGlkZWEgYW5kIHdoeS4gVGhlIG9sZGVyIGludGVyZmFjZXMgY2FuIHF1ZXJ5IGFuZCBJRGlyZWN0M0QgdmVyc2lvbgogICAgICogYmVjYXVzZSB0aGV5IGFyZSBhbGwgY3JlYXRlZCBhcyBJRGlyZWN0RHJhdygxKS4gVGhpcyBpc24ndCByZWFsbHkgY3J1Y2lhbCBiZWhhdmlvciwKICAgICAqIGFuZCBtZXNzeSB0byBpbXBsZW1lbnQgd2l0aCB0aGUgY29tbW9uIGNyZWF0aW9uIGZ1bmN0aW9uLCBzbyBpdCBoYXMgYmVlbiBsZWZ0IG91dCBoZXJlLgogICAgICovCiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEICAsIHJlZmlpZCApIHx8CiAgICAgICAgICAgICAgSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEMiAsIHJlZmlpZCApIHx8CiAgICAgICAgICAgICAgSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEMyAsIHJlZmlpZCApIHx8CiAgICAgICAgICAgICAgSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNENyAsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAvKiBDaGVjayB0aGUgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbiAqLwogICAgICAgIGlmKFRoaXMtPkltcGxUeXBlID09IFNVUkZBQ0VfVU5LTk9XTikKICAgICAgICB7CiAgICAgICAgICAgIC8qIEFwcHMgbWF5IGNyZWF0ZSB0aGUgSURpcmVjdDNEIEludGVyZmFjZSBiZWZvcmUgdGhlIHByaW1hcnkgc3VyZmFjZS4KICAgICAgICAgICAgICogc2V0IHRoZSBzdXJmYWNlIGltcGxlbWVudGF0aW9uICovCiAgICAgICAgICAgIFRoaXMtPkltcGxUeXBlID0gU1VSRkFDRV9PUEVOR0w7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIENob29zaW5nIE9wZW5HTCBzdXJmYWNlcyBiZWNhdXNlIGEgRGlyZWN0M0QgaW50ZXJmYWNlIHdhcyByZXF1ZXN0ZWRcbiIsIFRoaXMpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKFRoaXMtPkltcGxUeXBlICE9IFNVUkZBQ0VfT1BFTkdMICYmIERlZmF1bHRTdXJmYWNlVHlwZSA9PSBTVVJGQUNFX1VOS05PV04pCiAgICAgICAgewogICAgICAgICAgICBFUlIoIiglcCkgVGhlIEFwcCBpcyByZXF1ZXN0aW5nIGEgRDNEIGRldmljZSwgYnV0IGEgbm9uLU9wZW5HTCBzdXJmYWNlIHR5cGUgd2FzIGNob29zZW4uIFByZXBhcmUgZm9yIHRyb3VibGUhXG4iLCBUaGlzKTsKICAgICAgICAgICAgRVJSKCIgKCVwKSBZb3UgbWF5IHdhbnQgdG8gY29udGFjdCB3aW5lLWRldmVsIGZvciBoZWxwXG4iLCBUaGlzKTsKICAgICAgICAgICAgLyogU2hvdWxkIEkgYXNzZXJ0KDApIGhlcmU/Pz8gKi8KICAgICAgICB9CiAgICAgICAgZWxzZSBpZihUaGlzLT5JbXBsVHlwZSAhPSBTVVJGQUNFX09QRU5HTCkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIlRoZSBhcHAgcmVxdWVzdHMgYSBEaXJlY3QzRCBpbnRlcmZhY2UsIGJ1dCBub24tb3BlbmdsIHN1cmZhY2VzIHdoZXJlIHNldCBpbiB3aW5lY2ZnXG4iKTsKICAgICAgICAgICAgLyogRG8gbm90IGFib3J0IGhlcmUsIG9ubHkgcmVqZWN0IDNEIERldmljZSBjcmVhdGlvbiAqLwogICAgICAgIH0KCiAgICAgICAgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0QgICwgcmVmaWlkICkgKQogICAgICAgIHsKICAgICAgICAgICAgVGhpcy0+ZDNkdmVyc2lvbiA9IDE7CiAgICAgICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0QpOwogICAgICAgICAgICBUUkFDRSgiIHJldHVybmluZyBEaXJlY3QzRCBpbnRlcmZhY2UgYXQgJXAuXG4iLCAqb2JqKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDIgICwgcmVmaWlkICkgKQogICAgICAgIHsKICAgICAgICAgICAgVGhpcy0+ZDNkdmVyc2lvbiA9IDI7CiAgICAgICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0QyKTsKICAgICAgICAgICAgVFJBQ0UoIiByZXR1cm5pbmcgRGlyZWN0M0QyIGludGVyZmFjZSBhdCAlcC5cbiIsICpvYmopOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEMyAgLCByZWZpaWQgKSApCiAgICAgICAgewogICAgICAgICAgICBUaGlzLT5kM2R2ZXJzaW9uID0gMzsKICAgICAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDMpOwogICAgICAgICAgICBUUkFDRSgiIHJldHVybmluZyBEaXJlY3QzRDMgaW50ZXJmYWNlIGF0ICVwLlxuIiwgKm9iaik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNENyAgLCByZWZpaWQgKSkKICAgICAgICB7CiAgICAgICAgICAgIFRoaXMtPmQzZHZlcnNpb24gPSA3OwogICAgICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNENyk7CiAgICAgICAgICAgIFRSQUNFKCIgcmV0dXJuaW5nIERpcmVjdDNENyBpbnRlcmZhY2UgYXQgJXAuXG4iLCAqb2JqKTsKICAgICAgICB9CiAgICB9CgogICAgLyogVW5rbm93biBpbnRlcmZhY2UgKi8KICAgIGVsc2UKICAgIHsKICAgICAgICBFUlIoIiglcCktPiglcywgJXApOiBObyBpbnRlcmZhY2UgZm91bmRcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKICAgICAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKICAgIH0KCiAgICBJVW5rbm93bl9BZGRSZWYoIChJVW5rbm93biAqKSAqb2JqICk7CiAgICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6QWRkUmVmCiAqCiAqIEluY3JlYXNlcyB0aGUgaW50ZXJmYWNlcyByZWZjb3VudCwgYmFzaWNhbGx5CiAqCiAqIEREcmF3IHJlZmNvdW50aW5nIGlzIGEgYml0IHRyaWNreS4gVGhlIGRpZmZlcmVudCBEaXJlY3REcmF3IGludGVyZmFjZQogKiB2ZXJzaW9ucyBoYXZlIGluZGl2aWR1YWwgcmVmY291bnRzLCBidXQgdGhlIElEaXJlY3QzRCBpbnRlcmZhY2VzIGRvIG5vdC4KICogQWxsIGludGVyZmFjZXMgYXJlIGZyb20gb25lIG9iamVjdCwgdGhhdCBtZWFucyBjYWxsaW5nIFF1ZXJ5SW50ZXJmYWNlIG9uIGFuCiAqIElEaXJlY3REcmF3NyBpbnRlcmZhY2UgZm9yIGFuIElEaXJlY3REcmF3NCBpbnRlcmZhY2UgZG9lcyBub3QgY3JlYXRlIGEgbmV3CiAqIElEaXJlY3REcmF3SW1wbCBvYmplY3QuCiAqCiAqIFRoYXQgbWVhbnMgYWxsIEFkZFJlZiBhbmQgUmVsZWFzZSBpbXBsZW1lbnRhdGlvbnMgb2YgSURpcmVjdERyYXdYIHdvcmsKICogd2l0aCB0aGVpciBvd24gY291bnRlciwgYW5kIElEaXJlY3QzRFg6OkFkZFJlZiB0aHVuayB0byBJRGlyZWN0RHJhdyAoMSksCiAqIGV4Y2VwdCBvZiBJRGlyZWN0M0Q3IHdoaWNoIHRodW5rcyB0byBJRGlyZWN0RHJhdzcKICoKICogUmV0dXJuczogVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0FkZFJlZihJRGlyZWN0RHJhdzcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZjcpOwoKICAgIFRSQUNFKCIoJXApIDogaW5jcmVtZW50aW5nIElEaXJlY3REcmF3NyByZWZjb3VudCBmcm9tICV1LlxuIiwgVGhpcywgcmVmIC0xKTsKCiAgICBpZihyZWYgPT0gMSkgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPm51bUlmYWNlcyk7CgogICAgcmV0dXJuIHJlZjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3SW1wbF9EZXN0cm95CiAqCiAqIERlc3Ryb3lzIGEgZGRyYXcgb2JqZWN0IGlmIGFsbCByZWZjb3VudHMgYXJlIDAuIFRoaXMgaXMgdG8gc2hhcmUgY29kZQogKiBiZXR3ZWVuIHRoZSBJRGlyZWN0RHJhd1g6OlJlbGVhc2UgZnVuY3Rpb25zCiAqCiAqIFBhcmFtczoKICogIFRoaXM6IERpcmVjdERyYXcgb2JqZWN0IHRvIGRlc3Ryb3kKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkCklEaXJlY3REcmF3SW1wbF9EZXN0cm95KElEaXJlY3REcmF3SW1wbCAqVGhpcykKewogICAgLyogQ2xlYXIgdGhlIGNvb3BsZXZlbCB0byByZXN0b3JlIHdpbmRvdyBhbmQgZGlzcGxheSBtb2RlICovCiAgICBJRGlyZWN0RHJhdzdfU2V0Q29vcGVyYXRpdmVMZXZlbChJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX05PUk1BTCk7CgogICAgLyogRGVzdHJveSB0aGUgZGV2aWNlIHdpbmRvdyBpZiB3ZSBjcmVhdGVkIG9uZSAqLwogICAgaWYoVGhpcy0+ZGV2aWNld2luZG93ICE9IDApCiAgICB7CiAgICAgICAgVFJBQ0UoIiAoJXApIERlc3Ryb3lpbmcgdGhlIGRldmljZSB3aW5kb3cgJXBcbiIsIFRoaXMsIFRoaXMtPmRldmljZXdpbmRvdyk7CiAgICAgICAgRGVzdHJveVdpbmRvdyhUaGlzLT5kZXZpY2V3aW5kb3cpOwogICAgICAgIFRoaXMtPmRldmljZXdpbmRvdyA9IDA7CiAgICB9CgogICAgLyogVW5yZWdpc3RlciB0aGUgd2luZG93IGNsYXNzICovCiAgICBVbnJlZ2lzdGVyQ2xhc3NBKFRoaXMtPmNsYXNzbmFtZSwgMCk7CgogICAgcmVtb3ZlX2RkcmF3X29iamVjdChUaGlzKTsKCiAgICAvKiBSZWxlYXNlIHRoZSBhdHRhY2hlZCBXaW5lRDNEIHN0dWZmICovCiAgICBJV2luZUQzRERldmljZV9SZWxlYXNlKFRoaXMtPndpbmVEM0REZXZpY2UpOwogICAgSVdpbmVEM0RfUmVsZWFzZShUaGlzLT53aW5lRDNEKTsKCiAgICAvKiBOb3cgZnJlZSB0aGUgb2JqZWN0ICovCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6UmVsZWFzZQogKgogKiBEZWNyZWFzZXMgdGhlIHJlZmNvdW50LiBJZiB0aGUgcmVmY291bnQgZmFsbHMgdG8gMCwgdGhlIG9iamVjdCBpcyBkZXN0cm95ZWQKICoKICogUmV0dXJuczogVGhlIG5ldyByZWZjb3VudAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1JlbGVhc2UoSURpcmVjdERyYXc3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWY3KTsKCiAgICBUUkFDRSgiKCVwKS0+KCkgZGVjcmVtZW50aW5nIElEaXJlY3REcmF3NyByZWZjb3VudCBmcm9tICV1LlxuIiwgVGhpcywgcmVmICsxKTsKCiAgICBpZihyZWYgPT0gMCkKICAgIHsKICAgICAgICBVTE9ORyBpZmFjZWNvdW50ID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPm51bUlmYWNlcyk7CiAgICAgICAgaWYoaWZhY2Vjb3VudCA9PSAwKSBJRGlyZWN0RHJhd0ltcGxfRGVzdHJveShUaGlzKTsKICAgIH0KCiAgICByZXR1cm4gcmVmOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXcgbWV0aG9kcwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdJbXBsX1NldHVwRXhjbHVzaXZlV2luZG93CiAqCiAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IG1vZGlmaWVzIGEgSFdORCdzIFN0eWxlIGFuZCBFeFN0eWxlIGZvciBwcm9wZXIKICogZnVsbHNjcmVlbiB1c2UuCiAqCiAqIFBhcmFtczoKICogIFRoaXM6IFBvaW50ZXIgdG8gdGhlIERpcmVjdERyYXcgaW1wbGVtZW50YXRpb24KICogIEhXTkQ6IFdpbmRvdyB0byBzZXR1cAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkCklEaXJlY3REcmF3SW1wbF9TZXR1cEZ1bGxzY3JlZW5XaW5kb3coSURpcmVjdERyYXdJbXBsICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhXTkQgd2luZG93KQp7CiAgICBMT05HIHN0eWxlLCBleFN0eWxlOwogICAgLyogRG9uJ3QgZG8gYW55dGhpbmcgaWYgYW4gb3JpZ2luYWwgc3R5bGUgaXMgc3RvcmVkLgogICAgICogVGhhdCBzaG91bGRuJ3QgaGFwcGVuCiAgICAgKi8KICAgIFRSQUNFKCIoJXApOiBTZXR0aW5nIHVwIHdpbmRvdyAlcCBmb3IgZXhjbHVzaXZlIG1vZGVcbiIsIFRoaXMsIHdpbmRvdyk7CiAgICBpZiggKFRoaXMtPnN0eWxlICE9IDApICYmIChUaGlzLT5leFN0eWxlICE9IDApICkKICAgIHsKICAgICAgICBFUlIoIiglcCkgV2FudCB0byBjaGFuZ2UgdGhlIHdpbmRvdyBwYXJhbWV0ZXJzIG9mIEhXTkQgJXAsIGJ1dCBcCiAgICAgICAgICAgICBhbm90aGVyIHN0eWxlIGlzIHN0b3JlZCBmb3IgcmVzdGF1cmF0aW9uIGFmdGVyd2FyZHNcbiIsIFRoaXMsIHdpbmRvdyk7CiAgICB9CgogICAgLyogR2V0IHRoZSBwYXJhbWV0ZXJzIGFuZCBzYXZlIHRoZW0gKi8KICAgIHN0eWxlID0gR2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfU1RZTEUpOwogICAgZXhTdHlsZSA9IEdldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX0VYU1RZTEUpOwogICAgVGhpcy0+c3R5bGUgPSBzdHlsZTsKICAgIFRoaXMtPmV4U3R5bGUgPSBleFN0eWxlOwoKICAgIC8qIEZpbHRlciBvdXQgd2luZG93IGRlY29yYXRpb25zICovCiAgICBzdHlsZSAmPSB+V1NfQ0FQVElPTjsKICAgIHN0eWxlICY9IH5XU19USElDS0ZSQU1FOwogICAgZXhTdHlsZSAmPSB+V1NfRVhfV0lORE9XRURHRTsKICAgIGV4U3R5bGUgJj0gfldTX0VYX0NMSUVOVEVER0U7CgogICAgLyogTWFrZSBzdXJlIHRoZSB3aW5kb3cgaXMgbWFuYWdlZCwgb3RoZXJ3aXNlIHdlIHdvbid0IGdldCBrZXlib2FyZCBpbnB1dCAqLwogICAgc3R5bGUgfD0gV1NfUE9QVVAgfCBXU19TWVNNRU5VOwoKICAgIFRSQUNFKCJPbGQgc3R5bGUgd2FzICUwOHgsJTA4eCwgc2V0dGluZyB0byAlMDh4LCUwOHhcbiIsCiAgICAgICAgICBUaGlzLT5zdHlsZSwgVGhpcy0+ZXhTdHlsZSwgc3R5bGUsIGV4U3R5bGUpOwoKICAgIFNldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX1NUWUxFLCBzdHlsZSk7CiAgICBTZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9FWFNUWUxFLCBleFN0eWxlKTsKCiAgICAvKiBJbmZvcm0gdGhlIHdpbmRvdyBhYm91dCB0aGUgdXBkYXRlLgogICAgICogVE9ETzogU2hvdWxkIEkgbW92ZSBpdCB0byAwLzAgdG9vPwogICAgICovCiAgICBTZXRXaW5kb3dQb3Mod2luZG93LCAwIC8qIEluc2VydEFmdGVyLCBpZ25vcmVkICovLAogICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIC8qIFBvcywgU2l6ZSwgaWdub3JlZCAqLwogICAgICAgICAgICAgICAgIFNXUF9GUkFNRUNIQU5HRUQgfCBTV1BfTk9TSVpFIHwgU1dQX05PTU9WRSB8IFNXUF9OT1pPUkRFUik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0ltcGxfUmVzdG9yZVdpbmRvdwogKgogKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCByZXN0b3JlcyBhIHdpbmRvd3MnIHByb3BlcnRpZXMgd2hlbiB0YWtpbmcgaXQgb3V0CiAqIG9mIGZ1bGxzY3JlZW4gbW9kZQogKgogKiBQYXJhbXM6CiAqICBUaGlzOiBQb2ludGVyIHRvIHRoZSBEaXJlY3REcmF3IGltcGxlbWVudGF0aW9uCiAqICBIV05EOiBXaW5kb3cgdG8gc2V0dXAKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZApJRGlyZWN0RHJhd0ltcGxfUmVzdG9yZVdpbmRvdyhJRGlyZWN0RHJhd0ltcGwgKlRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhXTkQgd2luZG93KQp7CiAgICBpZiggKFRoaXMtPnN0eWxlID09IDApICYmIChUaGlzLT5leFN0eWxlID09IDApICkKICAgIHsKICAgICAgICAvKiBUaGlzIGNvdWxkIGJlIGEgRERTQ0xfTk9STUFMIC0+IEREU0NMX05PUk1BTAogICAgICAgICAqIHN3aXRjaCwgZG8gbm90aGluZwogICAgICAgICAqLwogICAgICAgIHJldHVybjsKICAgIH0KICAgIFRSQUNFKCIoJXApOiBSZXN0b3Jpbmcgd2luZG93IHNldHRpbmdzIG9mIHdpbmRvdyAlcCB0byAlMDh4LCAlMDh4XG4iLAogICAgICAgICAgVGhpcywgd2luZG93LCBUaGlzLT5zdHlsZSwgVGhpcy0+ZXhTdHlsZSk7CgogICAgU2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfU1RZTEUsIFRoaXMtPnN0eWxlKTsKICAgIFNldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX0VYU1RZTEUsIFRoaXMtPmV4U3R5bGUpOwoKICAgIC8qIERlbGV0ZSB0aGUgb2xkIHZhbHVlcyAqLwogICAgVGhpcy0+c3R5bGUgPSAwOwogICAgVGhpcy0+ZXhTdHlsZSA9IDA7CgogICAgLyogSW5mb3JtIHRoZSB3aW5kb3cgYWJvdXQgdGhlIHVwZGF0ZSAqLwogICAgU2V0V2luZG93UG9zKHdpbmRvdywgMCAvKiBJbnNlcnRBZnRlciwgaWdub3JlZCAqLywKICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAvKiBQb3MsIFNpemUsIGlnbm9yZWQgKi8KICAgICAgICAgICAgICAgICBTV1BfRlJBTUVDSEFOR0VEIHwgU1dQX05PTU9WRSB8IFNXUF9OT1NJWkUgfCBTV1BfTk9aT1JERVIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpTZXRDb29wZXJhdGl2ZUxldmVsCiAqCiAqIFNldHMgdGhlIGNvb3BlcmF0aXZlIGxldmVsIGZvciB0aGUgRGlyZWN0RHJhdyBvYmplY3QsIGFuZCB0aGUgd2luZG93CiAqIGFzc2lnbmVkIHRvIGl0LiBUaGUgY29vcGVyYXRpdmUgbGV2ZWwgZGV0ZXJtaW5lcyB0aGUgZ2VuZXJhbCBiZWhhdmlvcgogKiBvZiB0aGUgRGlyZWN0RHJhdyBhcHBsaWNhdGlvbgogKgogKiBXYXJuaW5nOiBUaGlzIGlzIHF1aXRlIHRyaWNreSwgYXMgaXQncyBub3QgcmVhbGx5IGRvY3VtZW50ZWQgd2hpY2gKICogY29vcGVyYXRpdmUgbGV2ZWxzIGNhbiBiZSBjb21iaW5lZCB3aXRoIGVhY2ggb3RoZXIuIElmIGEgZ2FtZSBmYWlscwogKiBhZnRlciB0aGlzIGZ1bmN0aW9uLCB0cnkgdG8gY2hlY2sgdGhlIGNvb3BlcmF0aXZlIGxldmVscyBwYXNzZWQgb24KICogV2luZG93cywgYW5kIGlmIGl0IHJldHVybnMgc29tZXRoaW5nIGRpZmZlcmVudC4KICoKICogSWYgeW91IHRoaW5rIHRoYXQgdGhpcyBmdW5jdGlvbiBjYXVzZWQgdGhlIGZhaWx1cmUgYmVjYXVzZSBpdCB3cml0ZXMgYQogKiBmaXhtZSwgYmUgc3VyZSB0byBydW4gYWdhaW4gd2l0aCBhICtkZHJhdyB0cmFjZS4KICoKICogV2hhdCBpcyBrbm93biBhYm91dCBjb29wZXJhdGl2ZSBsZXZlbHMgKFNlZSB0aGUgZGRyYXcgbW9kZXMgdGVzdCk6CiAqIEREU0NMX0VYQ0xVU0lWRSBhbmQgRERTQ0xfRlVMTFNDUkVFTiBtdXN0IGJlIHVzZWQgd2l0aCBlYWNoIG90aGVyCiAqIEREU0NMX05PUk1BTCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIEREU0NMX0VYQ0xVU0lWRSBvciBERFNDTF9GVUxMU0NSRUVOCiAqIEREU0NMX1NFVEZPQ1VTV0lORE9XIGNhbiBiZSBwYXNzZWQgb25seSBpbiBERFNDTF9OT1JNQUwgbW9kZSwgYnV0IGFmdGVyIHRoYXQKICogRERTQ0xfRlVMTFNDUkVFTiBjYW4gYmUgYWN0aXZhdGVkCiAqIEREU0NMX1NFVEZPQ1VTV0lORE9XIG1heSBvbmx5IGJlIHVzZWQgd2l0aCBERFNDTF9OT1dJTkRPV0NIQU5HRVMKICoKICogSGFuZGxlZCBmbGFnczogRERTQ0xfTk9STUFMLCBERFNDTF9GVUxMU0NSRUVOLCBERFNDTF9FWENMVVNJVkUsCiAqICAgICAgICAgICAgICAgIEREU0NMX1NFVEZPQ1VTV0lORE9XIChwYXJ0aWFsbHkpCiAqCiAqIFVuaGFuZGxlZCBmbGFncywgd2hpY2ggc2hvdWxkIGJlIGltcGxlbWVudGVkCiAqICBERFNDTF9TRVRERVZJQ0VXSU5ET1c6IFNldHMgYSB3aW5kb3cgc3BlY2lhbGx5IHVzZWQgZm9yIHJlbmRlcmluZyAoSSBkb24ndAogKiAgZXhwZWN0IGFueSBkaWZmZXJlbmNlIHRvIGEgbm9ybWFsIHdpbmRvdyBmb3Igd2luZSkKICogIEREU0NMX0NSRUFURURFVklDRVdJTkRPVzogVGVsbHMgZGRyYXcgdG8gY3JlYXRlIGl0cyBvd24gd2luZG93IGZvcgogKiAgcmVuZGVyaW5nIChQb3NzaWJsZSB0ZXN0IGNhc2U6IEhhbGYtbGlmZSkKICoKICogVW5zdXJlIGFib3V0IHRoZXNlOiBERFNDTF9GUFVTRVRVUCBERFNDTF9GUFVSRVNFUlZFCiAqCiAqIFRoZXNlIHNlZW0gbm90IHJlYWxseSBpbXBvcmFudCBmb3Igd2luZQogKiAgRERTQ0xfQUxMT1dSRUJPT1QsIEREU0NMX05PV0lORE9XQ0hBTkdFUywgRERTQ0xfQUxMT1dNT0RFWCwKICogIEREU0NMX01VTFRJVEhSRURFRAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgaWYgdGhlIGNvb3BlcmF0aXZlIGxldmVsIHdhcyBzZXQgc3VjY2Vzc2Z1bGx5CiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIHRoZSBwYXNzZWQgY29vcGVyYXRpdmUgbGV2ZWwgY29tYmluYXRpb24gaXMgaW52YWxpZAogKiAgRERFUlJfSFdOREFMUkVBRFlTRVQgaWYgRERTQ0xfU0VURk9DVVNXSU5ET1cgaXMgcGFzc2VkIGluIGV4Y2x1c2l2ZSBtb2RlCiAqICAgKFByb2JhYmx5IG90aGVycyB0b28sIGhhdmUgdG8gaW52ZXN0aWdhdGUpCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9TZXRDb29wZXJhdGl2ZUxldmVsKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhXTkQgaHduZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgY29vcGxldmVsKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSFdORCB3aW5kb3c7CiAgICBIUkVTVUxUIGhyOwoKICAgIEZJWE1FKCIoJXApLT4oJXAsJTA4eClcbiIsVGhpcyxod25kLGNvb3BsZXZlbCk7CiAgICBERFJBV19kdW1wX2Nvb3BlcmF0aXZlbGV2ZWwoY29vcGxldmVsKTsKCiAgICAvKiBHZXQgdGhlIG9sZCB3aW5kb3cgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCAmd2luZG93KTsKICAgIGlmKGhyICE9IEQzRF9PSykKICAgIHsKICAgICAgICBFUlIoIklXaW5lRDNERGV2aWNlOjpHZXRIV05EIGZhaWxlZCwgaHIgPSAlMDh4XG4iLCBocik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIC8qIFRlc3RzIHN1Z2dlc3QgdGhhdCB3ZSBuZWVkIG9uZSBvZiB0aGVtOiAqLwogICAgaWYoIShjb29wbGV2ZWwgJiAoRERTQ0xfU0VURk9DVVNXSU5ET1cgfAogICAgICAgICAgICAgICAgICAgICAgRERTQ0xfTk9STUFMICAgICAgICAgfAogICAgICAgICAgICAgICAgICAgICAgRERTQ0xfRVhDTFVTSVZFICAgICAgKSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIkluY29ycmVjdCBjb29wbGV2ZWwgZmxhZ3MsIHJldHVybmluZyBEREVSUl9JTlZBTElEUEFSQU1TXG4iKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICAvKiBIYW5kbGUgdGhvc2UgbGV2ZWxzIGZpcnN0IHdoaWNoIHNldCB2YXJpb3VzIGh3bmRzICovCiAgICBpZihjb29wbGV2ZWwgJiBERFNDTF9TRVRGT0NVU1dJTkRPVykKICAgIHsKICAgICAgICAvKiBUaGlzIGlzbid0IGNvbXBhdGlibGUgd2l0aCBhIGxvdCBvZiBmbGFncyAqLwogICAgICAgIGlmKGNvb3BsZXZlbCAmICggRERTQ0xfTVVMVElUSFJFQURFRCAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX0ZQVVNFVFVQICAgICAgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9GUFVQUkVTRVJWRSAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfQUxMT1dSRUJPT1QgICAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX0FMTE9XTU9ERVggICAgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9TRVRERVZJQ0VXSU5ET1cgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfTk9STUFMICAgICAgICAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX0VYQ0xVU0lWRSAgICAgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9GVUxMU0NSRUVOICAgICAgKSApCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiQ2FsbGVkIHdpdGggaW5jb21wYXRpYmxlIGZsYWdzLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFBBUkFNU1xuIik7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKCAoVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJiBERFNDTF9GVUxMU0NSRUVOKSAmJiB3aW5kb3cpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiU2V0dGluZyBERFNDTF9TRVRGT0NVU1dJTkRPVyB3aXRoIGFuIGFscmVhZHkgc2V0IHdpbmRvdywgcmV0dXJuaW5nIERERVJSX0hXTkRBTFJFQURZU0VUXG4iKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0hXTkRBTFJFQURZU0VUOwogICAgICAgIH0KCiAgICAgICAgVGhpcy0+Zm9jdXN3aW5kb3cgPSBod25kOwogICAgICAgIC8qIFdvbid0IHVzZSB0aGUgaHduZCBwYXJhbSBmb3IgYW55dGhpbmcgZWxzZSAqLwogICAgICAgIGh3bmQgPSBOVUxMOwoKICAgICAgICAvKiBVc2UgdGhlIGZvY3VzIHdpbmRvdyBmb3IgZHJhd2luZyB0b28gKi8KICAgICAgICBJV2luZUQzRERldmljZV9TZXRIV05EKFRoaXMtPndpbmVEM0REZXZpY2UsIFRoaXMtPmZvY3Vzd2luZG93KTsKCiAgICAgICAgLyogRGVzdHJveSB0aGUgZGV2aWNlIHdpbmRvdywgaWYgd2UgaGF2ZSBvbmUgKi8KICAgICAgICBpZihUaGlzLT5kZXZpY2V3aW5kb3cpCiAgICAgICAgewogICAgICAgICAgICBEZXN0cm95V2luZG93KFRoaXMtPmRldmljZXdpbmRvdyk7CiAgICAgICAgICAgIFRoaXMtPmRldmljZXdpbmRvdyA9IE5VTEw7CiAgICAgICAgfQogICAgfQogICAgLyogRERTQ0xfTk9STUFMIG9yIEREU0NMX0ZVTExTQ1JFRU4gfCBERFNDTF9FWENMVVNJVkUgKi8KICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX05PUk1BTCkKICAgIHsKICAgICAgICAvKiBDYW4ndCBjb2V4aXN0IHdpdGggZnVsbHNjcmVlbiBvciBleGNsdXNpdmUgKi8KICAgICAgICBpZihjb29wbGV2ZWwgJiAoRERTQ0xfRlVMTFNDUkVFTiB8IEREU0NMX0VYQ0xVU0lWRSkgKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgRERTQ0xfTk9STUFMIGlzIG5vdCBjb21wYXRpdmUgd2l0aCBERFNDTF9GVUxMU0NSRUVOIG9yIEREU0NMX0VYQ0xVU0lWRVxuIiwgVGhpcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KCiAgICAgICAgLyogU3dpdGNoaW5nIGZyb20gZnVsbHNjcmVlbj8gKi8KICAgICAgICBpZihUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmIEREU0NMX0ZVTExTQ1JFRU4pCiAgICAgICAgewogICAgICAgICAgICAvKiBSZXN0b3JlIHRoZSBkaXNwbGF5IG1vZGUgKi8KICAgICAgICAgICAgSURpcmVjdERyYXc3X1Jlc3RvcmVEaXNwbGF5TW9kZShpZmFjZSk7CgogICAgICAgICAgICBpZih3aW5kb3cpCiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd0ltcGxfUmVzdG9yZVdpbmRvdyhUaGlzLCB3aW5kb3cpOwoKICAgICAgICAgICAgVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJj0gfkREU0NMX0ZVTExTQ1JFRU47CiAgICAgICAgICAgIFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICY9IH5ERFNDTF9FWENMVVNJVkU7CiAgICAgICAgICAgIFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICY9IH5ERFNDTF9BTExPV01PREVYOwogICAgICAgIH0KCiAgICAgICAgLyogRG9uJ3Qgb3ZlcnJpZGUgZm9jdXMgd2luZG93cyBvciBwcml2YXRlIGRldmljZSB3aW5kb3dzICovCiAgICAgICAgaWYoIGh3bmQgJiYKICAgICAgICAgICAgIShUaGlzLT5mb2N1c3dpbmRvdykgJiYKICAgICAgICAgICAgIShUaGlzLT5kZXZpY2V3aW5kb3cpICYmCiAgICAgICAgICAgIChod25kICE9IHdpbmRvdykgKQogICAgICAgIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCBod25kKTsKICAgICAgICB9CgogICAgICAgIElXaW5lRDNERGV2aWNlX1NldEZ1bGxzY3JlZW4oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZBTFNFKTsKICAgIH0KICAgIGVsc2UgaWYoY29vcGxldmVsICYgRERTQ0xfRlVMTFNDUkVFTikKICAgIHsKICAgICAgICAvKiBOZWVkcyBERFNDTF9FWENMVVNJVkUgKi8KICAgICAgICBpZighKGNvb3BsZXZlbCAmIEREU0NMX0VYQ0xVU0lWRSkgKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgRERTQ0xfRlVMTFNDUkVFTiBuZWVkcyBERFNDTF9FWENMVVNJVkVcbiIsIFRoaXMpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICAgICAgLyogTmVlZCBhIEhXTkQKICAgICAgICBpZihod25kID09IDApCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiKCVwKSBERFNDTF9GVUxMU0NSRUVOIG5lZWRzIGEgSFdORFxuIiwgVGhpcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KICAgICAgICAqLwoKICAgICAgICAvKiBTd2l0Y2ggZnJvbSBub3JtYWwgdG8gZnVsbCBzY3JlZW4gbW9kZT8gKi8KICAgICAgICBpZihUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmIEREU0NMX05PUk1BTCkKICAgICAgICB7CiAgICAgICAgICAgIFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICY9IH5ERFNDTF9OT1JNQUw7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldEZ1bGxzY3JlZW4oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFKTsKICAgICAgICB9CgogICAgICAgIC8qIERvbid0IG92ZXJyaWRlIGZvY3VzIHdpbmRvd3Mgb3IgcHJpdmF0ZSBkZXZpY2Ugd2luZG93cyAqLwogICAgICAgIGlmKCBod25kICYmCiAgICAgICAgICAgICEoVGhpcy0+Zm9jdXN3aW5kb3cpICYmCiAgICAgICAgICAgICEoVGhpcy0+ZGV2aWNld2luZG93KSAmJgogICAgICAgICAgICAoaHduZCAhPSB3aW5kb3cpICkKICAgICAgICB7CiAgICAgICAgICAgIC8qIE9uIGEgd2luZG93IGNoYW5nZSwgcmVzdG9yZSB0aGUgb2xkIHdpbmRvdyBhbmQgc2V0IHRoZSBuZXcgb25lICovCiAgICAgICAgICAgIGlmKHdpbmRvdyAhPSBod25kKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZih3aW5kb3cpCiAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdJbXBsX1Jlc3RvcmVXaW5kb3coVGhpcywgd2luZG93KTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3SW1wbF9TZXR1cEZ1bGxzY3JlZW5XaW5kb3coVGhpcywgaHduZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCBod25kKTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmKGNvb3BsZXZlbCAmIEREU0NMX0VYQ0xVU0lWRSkKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKSBERFNDTF9FWENMVVNJVkUgbmVlZHMgRERTQ0xfRlVMTFNDUkVFTlxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgaWYoY29vcGxldmVsICYgRERTQ0xfQ1JFQVRFREVWSUNFV0lORE9XKQogICAgewogICAgICAgIC8qIERvbid0IGNyZWF0ZSBhIGRldmljZSB3aW5kb3cgaWYgYSBmb2N1cyB3aW5kb3cgaXMgc2V0ICovCiAgICAgICAgaWYoICEoVGhpcy0+Zm9jdXN3aW5kb3cpICkKICAgICAgICB7CiAgICAgICAgICAgIEhXTkQgZGV2aWNld2luZG93ID0gQ3JlYXRlV2luZG93RXhBKDAsIFRoaXMtPmNsYXNzbmFtZSwgIkREcmF3IGRldmljZSB3aW5kb3ciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXU19QT1BVUCwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMLCBHZXRNb2R1bGVIYW5kbGVBKDApLCBOVUxMKTsKCiAgICAgICAgICAgIFNob3dXaW5kb3coZGV2aWNld2luZG93LCBTV19TSE9XKTsgICAvKiBKdXN0IHRvIGJlIHN1cmUgKi8KICAgICAgICAgICAgVFJBQ0UoIiglcCkgQ3JlYXRlZCBhIEREcmF3IGRldmljZSB3aW5kb3cuIEhXTkQ9JXBcbiIsIFRoaXMsIGRldmljZXdpbmRvdyk7CgogICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRIV05EKFRoaXMtPndpbmVEM0REZXZpY2UsIGRldmljZXdpbmRvdyk7CiAgICAgICAgICAgIFRoaXMtPmRldmljZXdpbmRvdyA9IGRldmljZXdpbmRvdzsKICAgICAgICB9CiAgICB9CgogICAgLyogVW5oYW5kbGVkIGZsYWdzICovCiAgICBpZihjb29wbGV2ZWwgJiBERFNDTF9BTExPV1JFQk9PVCkKICAgICAgICBXQVJOKCIoJXApIFVuaGFuZGxlZCBmbGFnIEREU0NMX0FMTE9XUkVCT09ULCBoYXJtbGVzc1xuIiwgVGhpcyk7CiAgICBpZihjb29wbGV2ZWwgJiBERFNDTF9BTExPV01PREVYKQogICAgICAgIFdBUk4oIiglcCkgVW5oYW5kbGVkIGZsYWcgRERTQ0xfQUxMT1dNT0RFWCwgaGFybWxlc3NcbiIsIFRoaXMpOwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfTVVMVElUSFJFQURFRCkKICAgICAgICBGSVhNRSgiKCVwKSBVbmhhbmRsZWQgZmxhZyBERFNDTF9NVUxUSVRIUkVBREVELCBVaCBPaC4uLlxuIiwgVGhpcyk7CiAgICBpZihjb29wbGV2ZWwgJiBERFNDTF9GUFVTRVRVUCkKICAgICAgICBXQVJOKCIoJXApIFVuaGFuZGxlZCBmbGFnIEREU0NMX0ZQVVNFVFVQLCBoYXJtbGVzc1xuIiwgVGhpcyk7CiAgICBpZihjb29wbGV2ZWwgJiBERFNDTF9GUFVQUkVTRVJWRSkKICAgICAgICBXQVJOKCIoJXApIFVuaGFuZGxlZCBmbGFnIEREU0NMX0ZQVVBSRVNFUlZFLCBoYXJtbGVzc1xuIiwgVGhpcyk7CgogICAgLyogU3RvcmUgdGhlIGNvb3BlcmF0aXZlX2xldmVsICovCiAgICBUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCB8PSBjb29wbGV2ZWw7CiAgICBUUkFDRSgiU2V0Q29vcGVyYXRpdmVMZXZlbCByZXR1bmluZyBERF9PS1xuIik7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlNldERpc3BsYXlNb2RlCiAqCiAqIFNldHMgdGhlIGRpc3BsYXkgc2NyZWVuIHJlc29sdXRpb24sIGNvbG9yIGRlcHRoIGFuZCByZWZyZXNoIGZyZXF1ZW5jeQogKiB3aGVuIGluIGZ1bGxzY3JlZW4gbW9kZSAoaW4gdGhlb3J5KS4KICogUG9zc2libGUgcmV0dXJuIHZhbHVlcyBsaXN0ZWQgaW4gdGhlIFNESyBzdWdnZXN0IHRoYXQgdGhpcyBtZXRob2QgZmFpbHMKICogd2hlbiBub3QgaW4gZnVsbHNjcmVlbiBtb2RlLCBidXQgdGhpcyBpcyB3cm9uZy4gV2luZG93cyAyMDAwIGhhcHBpbHkgc2V0cwogKiB0aGUgZGlzcGxheSBtb2RlIGluIEREU0NMX05PUk1BTCBtb2RlIHdpdGhvdXQgYW4gaHduZCBzcGVjaWZpZWQuCiAqIEl0IHNlZW1zIHRvIGJlIHZhbGlkIHRvIHBhc3MgMCBmb3IgV2l0aCBhbmQgSGVpZ2h0LCB0aGlzIGhhcyB0byBiZSB0ZXN0ZWQKICogSXQgY291bGQgbWVhbiB0aGF0IHRoZSBjdXJyZW50IHZpZGVvIG1vZGUgc2hvdWxkIGJlIGxlZnQgYXMtaXMuIChCdXQgd2h5CiAqIGNhbGwgaXQgdGhlbj8pCiAqCiAqIFBhcmFtczoKICogIEhlaWdodCwgV2lkdGg6IFNjcmVlbiBkaW1lbnNpb24KICogIEJQUDogQ29sb3IgZGVwdGggaW4gQml0cyBwZXIgcGl4ZWwKICogIFJlZnJlc2hyYXRlOiBTY3JlZW4gcmVmcmVzaCByYXRlCiAqICBGbGFnczogT3RoZXIgc3R1ZmYKICoKICogUmV0dXJucwogKiAgRERfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfU2V0RGlzcGxheU1vZGUoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQlBQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgUmVmcmVzaFJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSBNb2RlOwogICAgVFJBQ0UoIiglcCktPiglZCwlZCwlZCwlZCwleDogUmVsYXkhXG4iLCBUaGlzLCBXaWR0aCwgSGVpZ2h0LCBCUFAsIFJlZnJlc2hSYXRlLCBGbGFncyk7CgogICAgaWYoICFXaWR0aCB8fCAhSGVpZ2h0ICkKICAgIHsKICAgICAgICBFUlIoIldpZHRoPSVkLCBIZWlnaHQ9JWQsIHdoYXQgdG8gZG8/XG4iLCBXaWR0aCwgSGVpZ2h0KTsKICAgICAgICAvKiBJdCBsb29rcyBsaWtlIE5lZWQgZm9yIFNwZWVkIFBvcnNjaGUgVW5sZWFzaGVkIGV4cGVjdHMgRERfT0sgaGVyZSAqLwogICAgICAgIHJldHVybiBERF9PSzsKICAgIH0KCiAgICAvKiBDaGVjayB0aGUgZXhjbHVzaXZlIG1vZGUKICAgIGlmKCEoVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJiBERFNDTF9FWENMVVNJVkUpKQogICAgICAgIHJldHVybiBEREVSUl9OT0VYQ0xVU0lWRU1PREU7CiAgICAgKiBUaGlzIGlzIFdST05HLiBEb24ndCBrbm93IGlmIHRoZSBTREsgaXMgY29tcGxldGVseQogICAgICogd3JvbmcgYW5kIGlmIHRoZXJlIGFyZSBhbnkgY29uZGl0aW9ucyB3aGVuIERERVJSX05PRVhDTFVTSVZFCiAgICAgKiBpcyByZXR1cm5lZCwgYnV0IEhhbGYtTGlmZSAxLjEuMS4xIChTdGVhbSB2ZXJzaW9uKQogICAgICogZGVwZW5kcyBvbiB0aGlzCiAgICAgKi8KCiAgICBNb2RlLldpZHRoID0gV2lkdGg7CiAgICBNb2RlLkhlaWdodCA9IEhlaWdodDsKICAgIE1vZGUuUmVmcmVzaFJhdGUgPSBSZWZyZXNoUmF0ZTsKICAgIHN3aXRjaChCUFApCiAgICB7CiAgICAgICAgY2FzZSA4OiAgTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1A4OyAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE1OiBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfWDFSNUc1QjU7IGJyZWFrOwogICAgICAgIGNhc2UgMTY6IE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9SNUc2QjU7ICAgYnJlYWs7CiAgICAgICAgY2FzZSAyNDogTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1I4RzhCODsgICBicmVhazsKICAgICAgICBjYXNlIDMyOiBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfQThSOEc4Qjg7IGJyZWFrOwogICAgfQoKICAgIC8qIFRPRE86IFRoZSBwb3NzaWJsZSByZXR1cm4gdmFsdWVzIGZyb20gbXNkbiBzdWdnZXN0IHRoYXQKICAgICAqIHRoZSBzY3JlZW4gbW9kZSBjYW4ndCBiZSBjaGFuZ2VkIGlmIGEgc3VyZmFjZSBpcyBsb2NrZWQKICAgICAqIG9yIHNvbWUgZHJhd2luZyBpcyBpbiBwcm9ncmVzcwogICAgICovCgogICAgLyogVE9ETzogTG9zZSB0aGUgcHJpbWFyeSBzdXJmYWNlICovCiAgICByZXR1cm4gSVdpbmVEM0REZXZpY2VfU2V0RGlzcGxheU1vZGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiBGaXJzdCBzd2FwY2hhaW4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTW9kZSk7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpSZXN0b3JlRGlzcGxheU1vZGUKICoKICogUmVzdG9yZXMgdGhlIGRpc3BsYXkgbW9kZSB0byB3aGF0IGl0IHdhcyBhdCBjcmVhdGlvbiB0aW1lLiBCYXNpY2FsbHkuCiAqCiAqIEEgcHJvYmxlbSBhcmlzZXMgd2hlbiB0aGVyZSBhcmUgMiBEaXJlY3REcmF3IG9iamVjdHMgdXNpbmcgdGhlIHNhbWUgaHduZDoKICogIC0+IEREXzEgZmluZHMgdGhlIHNjcmVlbiBhdCAxNDAweDEwNTB4MzIgd2hlbiBjcmVhdGVkLCBzZXRzIGl0IHRvIDY0MHg0ODB4MTYKICogIC0+IEREXzIgaXMgY3JlYXRlZCwgZmluZHMgdGhlIHNjcmVlbiBhdCA2NDB4NDgweDE2LCBzZXRzIGl0IHRvIDEwMjR4NzY4eDMyCiAqICAtPiBERF8xIGlzIHJlbGVhc2VkLiBUaGUgc2NyZWVuIHNob3VsZCBiZSBsZWZ0IGF0IDEwMjR4NzY4eDMyLgogKiAgLT4gRERfMiBpcyByZWxlYXNlZC4gVGhlIHNjcmVlbiBzaG91bGQgYmUgc2V0IHRvIDE0MDB4MTA1MHgzMgogKiBUaGlzIGNhc2UgaXMgdW5oYW5kbGVkIHJpZ2h0IG5vdywgYnV0IEVtcGlyZSBFYXJ0aCBkb2VzIGl0IHRoaXMgd2F5LgogKiAoQnV0IHBlcmhhcHMgdGhlcmUgaXMgc29tZXRoaW5nIGluIFNldENvb3BlcmF0aXZlTGV2ZWwgdG8gcHJldmVudCB0aGlzKQogKgogKiBUaGUgbXNkbiBzYXlzIHRoYXQgdGhpcyBtZXRob2QgcmVzZXRzIHRoZSBkaXNwbGF5IG1vZGUgdG8gd2hhdCBpdCB3YXMgYmVmb3JlCiAqIFNldERpc3BsYXlNb2RlIHdhcyBjYWxsZWQuIFdoYXQgaWYgU2V0RGlzcGxheU1vZGVzIGlzIGNhbGxlZCAyIHRpbWVzPz8KICoKICogUmV0dXJucwogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfTk9FWENMVVNJVkUgbW9kZSBpZiB0aGUgZGV2aWNlIGlzbid0IGluIGZ1bGxzY3JlZW4gbW9kZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfUmVzdG9yZURpc3BsYXlNb2RlKElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgcmV0dXJuIElEaXJlY3REcmF3N19TZXREaXNwbGF5TW9kZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5vcmlnX3dpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5vcmlnX2hlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+b3JpZ19icHAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRDYXBzCiAqCiAqIFJldHVybnMgdGhlIGRyaXZlcyBjYXBhYmlsaXRpZXMKICoKICogVXNlZCBmb3IgdmVyc2lvbiAxLCAyLCA0IGFuZCA3CiAqCiAqIFBhcmFtczoKICogIERyaXZlckNhcHM6IFN0cnVjdHVyZSB0byB3cml0ZSB0aGUgSGFyZHdhcmUgYWNjZWxlcmF0ZWQgY2FwcyB0bwogKiAgSGVsQ2FwczogU3RydWN0dXJlIHRvIHdyaXRlIHRoZSBlbXVsYXRpb24gY2FwcyB0bwogKgogKiBSZXR1cm5zCiAqICBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMgRERfT0sgb25seQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0Q2FwcyhJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICBERENBUFMgKkRyaXZlckNhcHMsCiAgICAgICAgICAgICAgICAgICAgICAgIEREQ0FQUyAqSEVMQ2FwcykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLCBUaGlzLCBEcml2ZXJDYXBzLCBIRUxDYXBzKTsKCiAgICAvKiBPbmUgc3RydWN0dXJlIG11c3QgYmUgIT0gTlVMTCAqLwogICAgaWYoICghRHJpdmVyQ2FwcykgJiYgKCFIRUxDYXBzKSApCiAgICB7CiAgICAgICAgRVJSKCIoJXApIEludmFsaWQgcGFyYW1zIHRvIElEaXJlY3REcmF3SW1wbF9HZXRDYXBzXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICBpZihEcml2ZXJDYXBzKQogICAgewogICAgICAgIEREX1NUUlVDVF9DT1BZX0JZU0laRShEcml2ZXJDYXBzLCAmVGhpcy0+Y2Fwcyk7CiAgICAgICAgaWYgKFRSQUNFX09OKGRkcmF3KSkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJEcml2ZXIgQ2FwcyA6XG4iKTsKICAgICAgICAgICAgRERSQVdfZHVtcF9ERENBUFMoRHJpdmVyQ2Fwcyk7CiAgICAgICAgfQoKICAgIH0KICAgIGlmKEhFTENhcHMpCiAgICB7CiAgICAgICAgRERfU1RSVUNUX0NPUFlfQllTSVpFKEhFTENhcHMsICZUaGlzLT5jYXBzKTsKICAgICAgICBpZiAoVFJBQ0VfT04oZGRyYXcpKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIkhFTCBDYXBzIDpcbiIpOwogICAgICAgICAgICBERFJBV19kdW1wX0REQ0FQUyhIRUxDYXBzKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpDb21wYWN0CiAqCiAqIE5vIGlkZWEgd2hhdCBpdCBkb2VzLCBNU0ROIHNheXMgaXQncyBub3QgaW1wbGVtZW50ZWQuCiAqCiAqIFJldHVybnMKICogIEREX09LLCBidXQgdGhpcyBpcyB1bmNoZWNrZWQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0NvbXBhY3QoSURpcmVjdERyYXc3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldERpc3BsYXlNb2RlCiAqCiAqIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGN1cnJlbnQgZGlzcGxheSBtb2RlCiAqCiAqIEV4aXN0cyBpbiBWZXJzaW9uIDEsIDIsIDQgYW5kIDcKICoKICogUGFyYW1zOgogKiAgRERTRDogQWRkcmVzcyBvZiBhIHN1cmZhY2UgZGVzY3JpcHRpb24gc3RydWN0dXJlIHRvIHdyaXRlIHRoZSBpbmZvIHRvCiAqCiAqIFJldHVybnMKICogIEREX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9HZXREaXNwbGF5TW9kZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKkREU0QpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgV0lORUQzRERJU1BMQVlNT0RFIE1vZGU7CiAgICBEV09SRCBTaXplOwogICAgVFJBQ0UoIiglcCktPiglcCk6IFJlbGF5XG4iLCBUaGlzLCBERFNEKTsKCiAgICAvKiBUaGlzIHNlZW1zIHNhbmUgKi8KICAgIGlmKCFERFNEKSAKICAgIHsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICAvKiBUaGUgbmVjZXNzYXJ5IG1lbWJlcnMgb2YgTFBERFNVUkZBQ0VERVNDIGFuZCBMUEREU1VSRkFDRURFU0MyIGFyZSBlcXVhbCwKICAgICAqIHNvIG9uZSBtZXRob2QgY2FuIGJlIHVzZWQgZm9yIGFsbCB2ZXJzaW9ucyAoSG9wZWZ1bGx5KQogICAgICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldERpc3BsYXlNb2RlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBzd2FwY2hhaW4gMCAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTW9kZSk7CiAgICBpZiggaHIgIT0gRDNEX09LICkKICAgIHsKICAgICAgICBFUlIoIiAoJXApIElXaW5lRDNERGV2aWNlOjpHZXREaXNwbGF5TW9kZSByZXR1cm5lZCAlMDh4XG4iLCBUaGlzLCBocik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIFNpemUgPSBERFNELT5kd1NpemU7CiAgICBtZW1zZXQoRERTRCwgMCwgU2l6ZSk7CgogICAgRERTRC0+ZHdTaXplID0gU2l6ZTsKICAgIEREU0QtPmR3RmxhZ3MgfD0gRERTRF9IRUlHSFQgfCBERFNEX1dJRFRIIHwgRERTRF9QSVhFTEZPUk1BVCB8IEREU0RfUElUQ0ggfCBERFNEX1JFRlJFU0hSQVRFOwogICAgRERTRC0+ZHdXaWR0aCA9IE1vZGUuV2lkdGg7CiAgICBERFNELT5kd0hlaWdodCA9IE1vZGUuSGVpZ2h0OyAKICAgIEREU0QtPnUyLmR3UmVmcmVzaFJhdGUgPSA2MDsKICAgIEREU0QtPmRkc0NhcHMuZHdDYXBzID0gMDsKICAgIEREU0QtPnU0LmRkcGZQaXhlbEZvcm1hdC5kd1NpemUgPSBzaXplb2YoRERTRC0+dTQuZGRwZlBpeGVsRm9ybWF0KTsKICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQsIE1vZGUuRm9ybWF0KTsKICAgIEREU0QtPnUxLmxQaXRjaCA9IE1vZGUuV2lkdGggKiBERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQudTEuZHdSR0JCaXRDb3VudCAvIDg7CgogICAgaWYoVFJBQ0VfT04oZGRyYXcpKQogICAgewogICAgICAgIFRSQUNFKCJSZXR1cm5pbmcgc3VyZmFjZSBkZXNjIDpcbiIpOwogICAgICAgIEREUkFXX2R1bXBfc3VyZmFjZV9kZXNjKEREU0QpOwogICAgfQoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6R2V0Rm91ckNDQ29kZXMKICoKICogUmV0dXJucyBhbiBhcnJheSBvZiBzdXBwb3J0ZWQgRm91ckNDIGNvZGVzLgogKgogKiBFeGlzdHMgaW4gVmVyc2lvbiAxLCAyLCA0IGFuZCA3CiAqCiAqIFBhcmFtczoKICogIE51bUNvZGVzOiBDb250YWlucyB0aGUgbnVtYmVyIG9mIENvZGVzIHRoYXQgQ29kZXMgY2FuIGNhcnJ5LiBSZXR1cm5zIHRoZSBudW1iZXIKICogICAgICAgICAgICBvZiBlbnVtZXJhdGVkIGNvZGVzCiAqICBDb2RlczogUG9pbnRlciB0byBhbiBhcnJheSBvZiBEV09SRHMgd2hlcmUgdGhlIHN1cHBvcnRlZCBjb2RlcyBhcmUgd3JpdHRlbgogKiAgICAgICAgIHRvCiAqCiAqIFJldHVybnMKICogIEFsd2F5cyByZXR1cm5zIEREX09LLCBhcyBpdCdzIGEgc3R1YiBmb3Igbm93CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9HZXRGb3VyQ0NDb2RlcyhJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKk51bUNvZGVzLCBEV09SRCAqQ29kZXMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCVwLCAlcCk6IFN0dWIhXG4iLCBUaGlzLCBOdW1Db2RlcywgQ29kZXMpOwoKICAgIGlmKE51bUNvZGVzKSAqTnVtQ29kZXMgPSAwOwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6R2V0TW9uaXRvckZyZXF1ZW5jeQogKgogKiBSZXR1cm5zIHRoZSBtb25pdG9yJ3MgZnJlcXVlbmN5CiAqCiAqIEV4aXN0cyBpbiBWZXJzaW9uIDEsIDIsIDQgYW5kIDcKICoKICogUGFyYW1zOgogKiAgRnJlcTogUG9pbnRlciB0byBhIERXT1JEIHRvIHdyaXRlIHRoZSBmcmVxdWVuY3kgdG8KICoKICogUmV0dXJucwogKiAgQWx3YXlzIHJldHVybnMgRERfT0sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0dldE1vbml0b3JGcmVxdWVuY3koSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKkZyZXEpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgRnJlcSk7CgogICAgLyogSWRlYWxseSB0aGlzIHNob3VsZCBiZSBpbiBXaW5lRDNELCBhcyBpdCBjb25jZXJucyB0aGUgc2NyZWVuIHNldHVwLAogICAgICogYnV0IGZvciBub3cgdGhpcyBzaG91bGQgbWFrZSB0aGUgZ2FtZXMgaGFwcHkKICAgICAqLwogICAgKkZyZXEgPSA2MDsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6R2V0VmVydGljYWxCbGFua1N0YXR1cwogKgogKiBSZXR1cm5zIHRoZSBWZXJ0aWNhbCBibGFuayBzdGF0dXMgb2YgdGhlIG1vbml0b3IuIFRoaXMgc2hvdWxkIGJlIGluIFdpbmVEM0QKICogdG9vIGJhc2ljYWxseSwgYnV0IGFzIGl0J3MgYSBzZW1pIHN0dWIsIEkgZGlkbid0IGNyZWF0ZSBhIGZ1bmN0aW9uIHRoZXJlCiAqCiAqIFBhcmFtczoKICogIHN0YXR1czogUG9pbnRlciB0byBhIEJPT0wgdG8gYmUgZmlsbGVkIHdpdGggdGhlIHZlcnRpY2FsIGJsYW5rIHN0YXR1cwogKgogKiBSZXR1cm5zCiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIHN0YXR1cyBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9HZXRWZXJ0aWNhbEJsYW5rU3RhdHVzKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgKnN0YXR1cykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBzdGF0dXMpOwoKICAgIC8qIFRoaXMgbG9va3Mgc2FuZSwgdGhlIE1TRE4gc3VnZ2VzdHMgaXQgdG9vICovCiAgICBpZighc3RhdHVzKSByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAqc3RhdHVzID0gVGhpcy0+ZmFrZV92Ymxhbms7CiAgICBUaGlzLT5mYWtlX3ZibGFuayA9ICFUaGlzLT5mYWtlX3ZibGFuazsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6R2V0QXZhaWxhYmxlVmlkTWVtCiAqCiAqIFJldHVybnMgdGhlIHRvdGFsIGFuZCBmcmVlIHZpZGVvIG1lbW9yeQogKgogKiBQYXJhbXM6CiAqICBDYXBzOiBTcGVjaWZpZXMgdGhlIG1lbW9yeSB0eXBlIGFza2VkIGZvcgogKiAgdG90YWw6IFBvaW50ZXIgdG8gYSBEV09SRCB0byBiZSBmaWxsZWQgd2l0aCB0aGUgdG90YWwgbWVtb3J5CiAqICBmcmVlOiBQb2ludGVyIHRvIGEgRFdPUkQgdG8gYmUgZmlsbGVkIHdpdGggdGhlIGZyZWUgbWVtb3J5CiAqCiAqIFJldHVybnMKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgb2YgZnJlZSBhbmQgdG90YWwgYXJlIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0dldEF2YWlsYWJsZVZpZE1lbShJRGlyZWN0RHJhdzcgKmlmYWNlLCBERFNDQVBTMiAqQ2FwcywgRFdPUkQgKnRvdGFsLCBEV09SRCAqZnJlZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXAsICVwLCAlcClcbiIsIFRoaXMsIENhcHMsIHRvdGFsLCBmcmVlKTsKCiAgICBpZihUUkFDRV9PTihkZHJhdykpCiAgICB7CiAgICAgICAgVFJBQ0UoIiglcCkgQXNrZWQgZm9yIG1lbW9yeSB3aXRoIGRlc2NyaXB0aW9uOiAiLCBUaGlzKTsKICAgICAgICBERFJBV19kdW1wX0REU0NBUFMyKENhcHMpOwogICAgICAgIFRSQUNFKCJcbiIpOwogICAgfQoKICAgIC8qIFRvZG86IFN5c3RlbSBtZW1vcnkgdnMgbG9jYWwgdmlkZW8gbWVtb3J5IHZzIG5vbi1sb2NhbCB2aWRlbyBtZW1vcnkKICAgICAqIFRoZSBNU0ROIGFsc28gbWVudGlvbnMgZGlmZmVyZW5jZXMgYmV0d2VlbiB0ZXh0dXJlIG1lbW9yeSBhbmQgb3RoZXIKICAgICAqIHJlc291cmNlcywgYnV0IHRoYXQncyBub3QgaW1wb3J0YW50CiAgICAgKi8KCiAgICBpZiggKCF0b3RhbCkgJiYgKCFmcmVlKSApIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIGlmKHRvdGFsKSAqdG90YWwgPSBUaGlzLT50b3RhbF92aWRtZW07CiAgICBpZihmcmVlKSAqZnJlZSA9IElXaW5lRDNERGV2aWNlX0dldEF2YWlsYWJsZVRleHR1cmVNZW0oVGhpcy0+d2luZUQzRERldmljZSk7CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpJbml0aWFsaXplCiAqCiAqIEluaXRpYWxpemVzIGEgRGlyZWN0RHJhdyBpbnRlcmZhY2UuCiAqCiAqIFBhcmFtczoKICogIEdVSUQ6IEludGVyZmFjZSBpZGVudGlmaWVyLiBXZWxsLCBkb24ndCBrbm93IHdoYXQgdGhpcyBpcyByZWFsbHkgZ29vZAogKiAgIGZvcgogKgogKiBSZXR1cm5zCiAqICBSZXR1cm5zIEREX09LIG9uIHRoZSBmaXJzdCBjYWxsLAogKiAgRERFUlJfQUxSRUFEWUlOSVRJQUxJWkVEIG9uIHJlcGVhdGVkIGNhbGxzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9Jbml0aWFsaXplKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEdVSUQgKkd1aWQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVzKTogTm8tb3BcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQoR3VpZCkpOwoKICAgIGlmKFRoaXMtPmluaXRpYWxpemVkKQogICAgewogICAgICAgIHJldHVybiBEREVSUl9BTFJFQURZSU5JVElBTElaRUQ7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgcmV0dXJuIEREX09LOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpGbGlwVG9HRElTdXJmYWNlCiAqCiAqICJNYWtlcyB0aGUgc3VyZmFjZSB0aGF0IHRoZSBHREkgd3JpdGVzIHRvIHRoZSBwcmltYXJ5IHN1cmZhY2UiCiAqIExvb2tzIGxpa2Ugc29tZSB3aW5kb3dzIHNwZWNpZmljIHRoaW5nIHdlIGRvbid0IGhhdmUgdG8gY2FyZSBhYm91dC4KICogQWNjb3JkaW5nIHRvIE1TRE4gaXQgcGVybWl0cyBHREkgZGlhbG9nIGJveGVzIGluIEZVTExTQ1JFRU4gbW9kZS4gR29vZCB0bwogKiBzaG93IGVycm9yIGJveGVzIDspCiAqIFdlbGwsIGp1c3QgcmV0dXJuIEREX09LLgogKgogKiBSZXR1cm5zOgogKiAgQWx3YXlzIHJldHVybnMgRERfT0sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0ZsaXBUb0dESVN1cmZhY2UoSURpcmVjdERyYXc3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OldhaXRGb3JWZXJ0aWNhbEJsYW5rCiAqCiAqIFRoaXMgbWV0aG9kIGFsbG93cyBhcHBsaWNhdGlvbnMgdG8gZ2V0IGluIHN5bmMgd2l0aCB0aGUgdmVydGljYWwgYmxhbmsKICogaW50ZXJ2YWwuCiAqIFRoZSB3b3JtaG9sZSBkZW1vIGluIHRoZSBEaXJlY3RYIDcgc2RrIHVzZXMgdGhpcyBjYWxsLCBhbmQgaXQgZG9lc24ndAogKiByZWRyYXcgdGhlIHNjcmVlbiwgbW9zdCBsaWtlbHkgYmVjYXVzZSBvZiB0aGlzIHN0dWIKICoKICogUGFyYW1ldGVyczoKICogIEZsYWdzOiBvbmUgb2YgRERXQUlUVkJfQkxPQ0tCRUdJTiwgRERXQUlUVkJfQkxPQ0tCRUdJTkVWRU5UCiAqICAgICAgICAgb3IgRERXQUlUVkJfQkxPQ0tFTkQKICogIGg6IE5vdCB1c2VkLCBhY2NvcmRpbmcgdG8gTVNETgogKgogKiBSZXR1cm5zOgogKiAgQWx3YXlzIHJldHVybnMgRERfT0sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLyAKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9XYWl0Rm9yVmVydGljYWxCbGFuayhJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUgaCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEZJWE1FKCIoJXApLT4oJXgsJXApOiBTdHViXG4iLCBUaGlzLCBGbGFncywgaCk7CgogICAgLyogTVNETiBzYXlzIEREV0FJVFZCX0JMT0NLQkVHSU5FVkVOVCBpcyBub3Qgc3VwcG9ydGVkICovCiAgICBpZihGbGFncyAmIEREV0FJVFZCX0JMT0NLQkVHSU5FVkVOVCkKICAgICAgICByZXR1cm4gRERFUlJfVU5TVVBQT1JURUQ7IC8qIHVuY2hlY2tlZCAqLwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6R2V0U2NhbkxpbmUKICoKICogUmV0dXJucyB0aGUgc2NhbiBsaW5lIHRoYXQgaXMgYmVpbmcgZHJhd24gb24gdGhlIG1vbml0b3IKICoKICogUGFyYW1ldGVyczoKICogIFNjYW5saW5lOiBBZGRyZXNzIHRvIHdyaXRlIHRoZSBzY2FuIGxpbmUgdmFsdWUgdG8KICoKICogUmV0dXJuczoKICogIEFsd2F5cyByZXR1cm5zIEREX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8gCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0RHJhd0ltcGxfR2V0U2NhbkxpbmUoSURpcmVjdERyYXc3ICppZmFjZSwgRFdPUkQgKlNjYW5saW5lKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgc3RhdGljIEJPT0wgaGlkZSA9IEZBTFNFOwogICAgV0lORUQzRERJU1BMQVlNT0RFIE1vZGU7CgogICAgLyogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgb2Z0ZW4sIHNvIHByaW50IHRoZSBmaXhtZSBvbmx5IG9uY2UgKi8KICAgIGlmKCFoaWRlKQogICAgewogICAgICAgIEZJWE1FKCIoJXApLT4oJXApOiBTZW1pLVN0dWJcbiIsIFRoaXMsIFNjYW5saW5lKTsKICAgICAgICBoaWRlID0gVFJVRTsKICAgIH0KCiAgICBJV2luZUQzRERldmljZV9HZXREaXNwbGF5TW9kZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZNb2RlKTsKCiAgICAvKiBGYWtlIHRoZSBsaW5lIHN3ZWVwaW5nIG9mIHRoZSBtb25pdG9yICovCiAgICAvKiBGSVhNRTogV2Ugc2hvdWxkIHN5bmNocm9uaXplIHdpdGggYSBzb3VyY2UgdG8ga2VlcCB0aGUgcmVmcmVzaCByYXRlICovIAogICAgKlNjYW5saW5lID0gVGhpcy0+Y3VyX3NjYW5saW5lKys7CiAgICAvKiBBc3N1bWUgMjAgc2NhbiBsaW5lcyBpbiB0aGUgdmVydGljYWwgYmxhbmsgKi8KICAgIGlmIChUaGlzLT5jdXJfc2NhbmxpbmUgPj0gTW9kZS5IZWlnaHQgKyAyMCkKICAgICAgICBUaGlzLT5jdXJfc2NhbmxpbmUgPSAwOwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6VGVzdENvb3BlcmF0aXZlTGV2ZWwKICoKICogSW5mb3JtcyB0aGUgYXBwbGljYXRpb24gYWJvdXQgdGhlIHN0YXRlIG9mIHRoZSB2aWRlbyBhZGFwdGVyLCBkZXBlbmRpbmcKICogb24gdGhlIGNvb3BlcmF0aXZlIGxldmVsCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBpZiB0aGUgZGV2aWNlIGlzIGluIGEgc2FuZSBzdGF0ZQogKiAgRERFUlJfTk9FWENMVVNJVkVNT0RFIG9yIERERVJSX0VYQ0xVU0lWRU1PREVBTFJFQURZU0VUCiAqICBpZiB0aGUgc3RhdGUgaXMgbm90IGNvcnJlY3QoU2VlIGJlbG93KQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovIApzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1Rlc3RDb29wZXJhdGl2ZUxldmVsKElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIC8qIERlc2NyaXB0aW9uIGZyb20gTVNETjoKICAgICAqIEZvciBmdWxsc2NyZWVuIGFwcHMgcmV0dXJuIERERVJSX05PRVhDTFVTSVZFTU9ERSBpZiB0aGUgdXNlciBzd2l0Y2hlZAogICAgICogYXdheSBmcm9tIHRoZSBhcHAgd2l0aCBlLmcuIGFsdC10YWIuIFdpbmRvd2VkIGFwcHMgcmVjZWl2ZSAKICAgICAqIERERVJSX0VYQ0xVU0lWRU1PREVBTFJFQURZU0VUIGlmIGFub3RoZXIgYXBwbGljYXRpb24gY3JlYXRlZCBhIAogICAgICogRGlyZWN0RHJhdyBvYmplY3QgaW4gZXhjbHVzaXZlIG1vZGUuIERERVJSX1dST05HTU9ERSBpcyByZXR1cm5lZCwKICAgICAqIHdoZW4gdGhlIHZpZGVvIG1vZGUgaGFzIGNoYW5nZWQKICAgICAqLwoKICAgIGhyID0gIElXaW5lRDNERGV2aWNlX1Rlc3RDb29wZXJhdGl2ZUxldmVsKFRoaXMtPndpbmVEM0REZXZpY2UpOwoKICAgIC8qIEZpeCB0aGUgcmVzdWx0IHZhbHVlLiBUaGVzZSB2YWx1ZXMgYXJlIG1hcHBlZCBmcm9tIHRoZWlyCiAgICAgKiBkM2Q5IGNvdW50ZXJwYXJ0LgogICAgICovCiAgICBzd2l0Y2goaHIpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNERVJSX0RFVklDRUxPU1Q6CiAgICAgICAgICAgIGlmKFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICYgRERTQ0xfRVhDTFVTSVZFKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gRERFUlJfTk9FWENMVVNJVkVNT0RFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIERERVJSX0VYQ0xVU0lWRU1PREVBTFJFQURZU0VUOwogICAgICAgICAgICB9CgogICAgICAgIGNhc2UgV0lORUQzREVSUl9ERVZJQ0VOT1RSRVNFVDoKICAgICAgICAgICAgcmV0dXJuIEREX09LOwoKICAgICAgICBjYXNlIFdJTkVEM0RfT0s6CiAgICAgICAgICAgIHJldHVybiBERF9PSzsKCiAgICAgICAgY2FzZSBXSU5FRDNERVJSX0RSSVZFUklOVEVSTkFMRVJST1I6CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCIoJXApIFVuZXhwZWN0ZWQgcmV0dXJuIHZhbHVlICUwOHggZnJvbSB3aW5lRDNELCAiIFwKICAgICAgICAgICAgICAgICIgcmV0dXJuaW5nIEREX09LXG4iLCBUaGlzLCBocik7CiAgICB9CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRHRElTdXJmYWNlCiAqCiAqIFJldHVybnMgdGhlIHN1cmZhY2UgdGhhdCBHREkgaXMgdHJlYXRpbmcgYXMgdGhlIHByaW1hcnkgc3VyZmFjZS4KICogRm9yIFdpbmUgdGhpcyBpcyB0aGUgZnJvbnQgYnVmZmVyCiAqCiAqIFBhcmFtczoKICogIEdESVN1cmZhY2U6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIHN1cmZhY2UgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgaWYgdGhlIHN1cmZhY2Ugd2FzIGZvdW5kCiAqICBEREVSUl9OT1RGT1VORCBpZiB0aGUgR0RJIHN1cmZhY2Ugd2Fzbid0IGZvdW5kCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8gCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0R0RJU3VyZmFjZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICoqR0RJU3VyZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIElXaW5lRDNEU3VyZmFjZSAqU3VyZjsKICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKmRkc3VyZjsKICAgIEhSRVNVTFQgaHI7CiAgICBERFNDQVBTMiBkZHNDYXBzOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIEdESVN1cmZhY2UpOwoKICAgIC8qIEdldCB0aGUgYmFjayBidWZmZXIgZnJvbSB0aGUgd2luZUQzRERldmljZSBhbmQgc2VhcmNoIGl0cwogICAgICogYXR0YWNoZWQgc3VyZmFjZXMgZm9yIHRoZSBmcm9udCBidWZmZXIKICAgICAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRCYWNrQnVmZmVyKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogU3dhcENoYWluICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogZmlyc3QgYmFjayBidWZmZXIqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RCQUNLQlVGRkVSX1RZUEVfTU9OTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3VyZik7CgogICAgaWYoIChociAhPSBEM0RfT0spIHx8CiAgICAgICAgKCFTdXJmKSApCiAgICB7CiAgICAgICAgRVJSKCJJV2luZUQzRERldmljZTo6R2V0QmFja0J1ZmZlciBmYWlsZWRcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9OT1RGT1VORDsKICAgIH0KCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGFyZW50KFN1cmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biAqKikgJmRkc3VyZik7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoZGRzdXJmKTsgIC8qIEZvciB0aGUgR2V0UGFyZW50ICovCgogICAgLyogRmluZCB0aGUgZnJvbnQgYnVmZmVyICovCiAgICBkZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfRlJPTlRCVUZGRVI7CiAgICBociA9IElEaXJlY3REcmF3U3VyZmFjZTdfR2V0QXR0YWNoZWRTdXJmYWNlKGRkc3VyZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRkc0NhcHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdESVN1cmZhY2UpOwogICAgaWYoaHIgIT0gRERfT0spCiAgICB7CiAgICAgICAgRVJSKCJJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXRBdHRhY2hlZFN1cmZhY2UgZmFpbGVkLCBociA9ICV4XG4iLCBocik7CiAgICB9CgogICAgLyogVGhlIEFkZFJlZiBpcyBPSyB0aGlzIHRpbWUgKi8KICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3SW1wbF9FbnVtRGlzcGxheU1vZGVzQ0IKICoKICogQ2FsbGJhY2sgZnVuY3Rpb24gZm9yIElEaXJlY3REcmF3Nzo6RW51bURpc3BsYXlNb2Rlcy4gVHJhbnNsYXRlcwogKiB0aGUgd2luZUQzRCB2YWx1ZXMgdG8gZGRyYXcgdmFsdWVzIGFuZCBjYWxscyB0aGUgYXBwbGljYXRpb24gY2FsbGJhY2sKICoKICogUGFyYW1zOgogKiAgZGV2aWNlOiBUaGUgSURpcmVjdERyYXc3IGludGVyZmFjZSB0byB0aGUgY3VycmVudCBkZXZpY2UKICogIFdpdGgsIEhlaWdodCwgUGl4ZWxmb3JtYXQsIFJlZnJlc2g6IEVudW1lcmF0ZWQgZGlzcGxheSBtb2RlCiAqICBjb250ZXh0OiB0aGUgY29udGV4dCBwb2ludGVyIHBhc3NlZCB0byBJV2luZUQzRERldmljZTo6RW51bURpc3BsYXlNb2RlcwogKgogKiBSZXR1cm5zOgogKiAgVGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBhcHBsaWNhdGlvbiBjYWxsYmFjawogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovIApzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0VudW1EaXNwbGF5TW9kZXNDQihJVW5rbm93biAqcERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgUGl4ZWxmb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkxPQVQgUmVmcmVzaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjb250ZXh0KQp7CiAgICBERFNVUkZBQ0VERVNDMiBjYWxsYmFja19zZDsKICAgIEVudW1EaXNwbGF5TW9kZXNDQlMgKmNicyA9IChFbnVtRGlzcGxheU1vZGVzQ0JTICopIGNvbnRleHQ7CgogICAgbWVtc2V0KCZjYWxsYmFja19zZCwgMCwgc2l6ZW9mKGNhbGxiYWNrX3NkKSk7CiAgICBjYWxsYmFja19zZC5kd1NpemUgPSBzaXplb2YoY2FsbGJhY2tfc2QpOwogICAgY2FsbGJhY2tfc2QudTQuZGRwZlBpeGVsRm9ybWF0LmR3U2l6ZSA9IHNpemVvZihERFBJWEVMRk9STUFUKTsKCiAgICBjYWxsYmFja19zZC5kd0ZsYWdzID0gRERTRF9IRUlHSFR8RERTRF9XSURUSHxERFNEX1BJWEVMRk9STUFUfEREU0RfUElUQ0g7CiAgICBpZihSZWZyZXNoID4gMC4wKQogICAgewogICAgICAgIGNhbGxiYWNrX3NkLmR3RmxhZ3MgfD0gRERTRF9SRUZSRVNIUkFURTsKICAgICAgICBjYWxsYmFja19zZC51Mi5kd1JlZnJlc2hSYXRlID0gNjAuMDsKICAgIH0KCiAgICBjYWxsYmFja19zZC5kd0hlaWdodCA9IEhlaWdodDsKICAgIGNhbGxiYWNrX3NkLmR3V2lkdGggPSBXaWR0aDsKCiAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmY2FsbGJhY2tfc2QudTQuZGRwZlBpeGVsRm9ybWF0LCBQaXhlbGZvcm1hdCk7CiAgICByZXR1cm4gY2JzLT5jYWxsYmFjaygmY2FsbGJhY2tfc2QsIGNicy0+Y29udGV4dCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkVudW1EaXNwbGF5TW9kZXMKICoKICogRW51bWVyYXRlcyB0aGUgc3VwcG9ydGVkIERpc3BsYXkgbW9kZXMuIFRoZSBtb2RlcyBjYW4gYmUgZmlsdGVyZWQgd2l0aAogKiB0aGUgRERTRCBwYXJhbWV0ZXIuCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBjYW4gYmUgRERFRE1fUkVGUkVTSFJBVEVTIGFuZCBEREVETV9TVEFOREFSRFZHQU1PREVTCiAqICBERFNEOiBTdXJmYWNlIGRlc2NyaXB0aW9uIHRvIGZpbHRlciB0aGUgbW9kZXMKICogIENvbnRleHQ6IFBvaW50ZXIgcGFzc2VkIGJhY2sgdG8gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uCiAqICBjYjogQXBwbGljYXRpb24tcHJvdmlkZWQgY2FsbGJhY2sgZnVuY3Rpb24KICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgdGhlIGNhbGxiYWNrIHdhc24ndCBzZXQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLyAKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9FbnVtRGlzcGxheU1vZGVzKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqRERTRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEREVOVU1NT0RFU0NBTExCQUNLMiBjYikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFVJTlQgV2lkdGggPSAwLCBIZWlnaHQgPSAwOwogICAgV0lORUQzREZPUk1BVCBwaXhlbGZvcm1hdCA9IFdJTkVEM0RGTVRfVU5LTk9XTjsKICAgIEVudW1EaXNwbGF5TW9kZXNDQlMgY2JzOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXAsJXApOiBSZWxheVxuIiwgVGhpcywgRERTRCwgQ29udGV4dCwgY2IpOwoKICAgIC8qIFRoaXMgbG9va3Mgc2FuZSAqLwogICAgaWYoIWNiKSByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAvKiBUaGUgcHJpdmF0ZSBjYWxsYmFjayBzdHJ1Y3R1cmUgKi8KICAgIGNicy5jYWxsYmFjayA9IGNiOwogICAgY2JzLmNvbnRleHQgPSBDb250ZXh0OwoKICAgIGlmKEREU0QpCiAgICB7CiAgICAgICAgaWYgKEREU0QtPmR3RmxhZ3MgJiBERFNEX1dJRFRIKQogICAgICAgICAgICBXaWR0aCA9IEREU0QtPmR3V2lkdGg7CiAgICAgICAgaWYgKEREU0QtPmR3RmxhZ3MgJiBERFNEX0hFSUdIVCkKICAgICAgICAgICAgSGVpZ2h0ID0gRERTRC0+ZHdIZWlnaHQ7CiAgICAgICAgaWYgKChERFNELT5kd0ZsYWdzICYgRERTRF9QSVhFTEZPUk1BVCkgJiYgKEREU0QtPnU0LmRkcGZQaXhlbEZvcm1hdC5kd0ZsYWdzICYgRERQRl9SR0IpICkKICAgICAgICAgICAgcGl4ZWxmb3JtYXQgPSBQaXhlbEZvcm1hdF9ERDJXaW5lRDNEKCZERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQpOwogICAgfQoKICAgIHJldHVybiBJV2luZUQzRERldmljZV9FbnVtRGlzcGxheU1vZGVzKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdpZHRoLCBIZWlnaHQsIHBpeGVsZm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNicywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3SW1wbF9FbnVtRGlzcGxheU1vZGVzQ0IpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpFdmFsdWF0ZU1vZGUKICoKICogVXNlZCB3aXRoIElEaXJlY3REcmF3Nzo6U3RhcnRNb2RlVGVzdCB0byB0ZXN0IHZpZGVvIG1vZGVzLgogKiBFdmFsdWF0ZU1vZGUgaXMgdXNlZCB0byBwYXNzIG9yIGZhaWwgYSBtb2RlLCBhbmQgY29udGludWUgd2l0aCB0aGUgbmV4dAogKiBtb2RlCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBEREVNX01PREVQQVNTRUQgb3IgRERFTV9NT0RFRkFJTEVECiAqICBUaW1lb3V0OiBSZXR1cm5zIHRoZSBhbW91bnQgb2Ygc2Vjb25kcyBsZWZ0IGJlZm9yZSB0aGUgbW9kZSB3b3VsZCBoYXZlCiAqICAgICAgICAgICBiZWVuIGZhaWxlZCBhdXRvbWF0aWNhbGx5CiAqCiAqIFJldHVybnM6CiAqICBUaGlzIGltcGxlbWVudGF0aW9uIGFsd2F5cyBERF9PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfRXZhbHVhdGVNb2RlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlRpbWVvdXQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCVkLCVwKTogU3R1YiFcbiIsIFRoaXMsIEZsYWdzLCBUaW1lb3V0KTsKCiAgICAvKiBXaGVuIGltcGxlbWVudGluZyB0aGlzLCBpbXBsZW1lbnQgaXQgaW4gV2luZUQzRCAqLwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6R2V0RGV2aWNlSWRlbnRpZmllcgogKgogKiBSZXR1cm5zIHRoZSBkZXZpY2UgaWRlbnRpZmllciwgd2hpY2ggZ2l2ZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGRyaXZlcgogKiBPdXIgZGV2aWNlIGlkZW50aWZpZXIgaXMgZGVmaW5lZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoaXMgZmlsZS4KICoKICogUGFyYW1zOgogKiAgRERESTogQWRkcmVzcyBmb3IgdGhlIHJldHVybmVkIHN0cnVjdHVyZQogKiAgRmxhZ3M6IENhbiBiZSBEREdESV9HRVRIT1NUSURFTlRJRklFUgogKgogKiBSZXR1cm5zOgogKiAgT24gc3VjY2VzcyBpdCByZXR1cm5zIEREX09LCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEREREkgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0RGV2aWNlSWRlbnRpZmllcihJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERERFVklDRUlERU5USUZJRVIyICpERERJLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJTA4eClcbiIsIFRoaXMsIEREREksIEZsYWdzKTsKCiAgICBpZighRERESSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAvKiBUaGUgRERHRElfR0VUSE9TVElERU5USUZJRVIgcmV0dXJucyB0aGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIDJECiAgICAgKiBob3N0IGFkYXB0ZXIsIGlmIHRoZXJlJ3MgYSBzZWNvbmRhcnkgM0QgYWRhcHRlci4gVGhpcyBkb2Vzbid0IGFwcGx5CiAgICAgKiB0byBhbnkgbW9kZXJuIGhhcmR3YXJlLCBub3IgaXMgaXQgaW50ZXJlc3RpbmcgZm9yIFdpbmUsIHNvIGlnbm9yZSBpdAogICAgICovCgogICAgKkREREkgPSBkZXZpY2VpZGVudGlmaWVyOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRTdXJmYWNlRnJvbURDCiAqCiAqIFJldHVybnMgdGhlIFN1cmZhY2UgZm9yIGEgR0RJIGRldmljZSBjb250ZXh0IGhhbmRsZS4KICogSXMgdGhpcyByZWxhdGVkIHRvIElEaXJlY3REcmF3U3VyZmFjZTo6R2V0REMgPz8/CiAqCiAqIFBhcmFtczoKICogIGhkYzogaGRjIHRvIHJldHVybiB0aGUgc3VyZmFjZSBmb3IKICogIFN1cmZhY2U6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIHN1cmZhY2UgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgQWx3YXlzIHJldHVybnMgRERfT0sgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0U3VyZmFjZUZyb21EQyhJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIREMgaGRjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICoqU3VyZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEZJWE1FKCIoJXApLT4oJXAsJXApOiBTdHViIVxuIiwgVGhpcywgaGRjLCBTdXJmYWNlKTsKCiAgICAvKiBJbXBsZW1lbnRhdGlvbiBpZGVhIGlmIG5lZWRlZDogTG9vcCB0aHJvdWdoIGFsbCBzdXJmYWNlcyBhbmQgY29tcGFyZQogICAgICogdGhlaXIgaGRjIHdpdGggaGRjLiBJbXBsZW1lbnQgaXQgaW4gV2luZUQzRCEgKi8KICAgIHJldHVybiBEREVSUl9OT1RGT1VORDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6UmVzdG9yZUFsbFN1cmZhY2VzCiAqCiAqIENhbGxzIHRoZSByZXN0b3JlIG1ldGhvZCBvZiBhbGwgc3VyZmFjZXMKICoKICogUGFyYW1zOgogKgogKiBSZXR1cm5zOgogKiAgQWx3YXlzIHJldHVybnMgRERfT0sgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfUmVzdG9yZUFsbFN1cmZhY2VzKElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKTogU3R1YlxuIiwgVGhpcyk7CgogICAgLyogVGhpcyBpc24ndCBoYXJkIHRvIGltcGxlbWVudDogRW51bWVyYXRlIGFsbCBXaW5lRDNEIHN1cmZhY2VzLAogICAgICogZ2V0IHRoZWlyIHBhcmVudCBhbmQgY2FsbCB0aGVpciByZXN0b3JlIG1ldGhvZC4gRG8gbm90IGltcGxlbWVudAogICAgICogaXQgaW4gV2luZUQzRCwgYXMgcmVzdG9yaW5nIGEgc3VyZmFjZSBtZWFucyByZS1jcmVhdGluZyB0aGUKICAgICAqIFdpbmVEM0REU3VyZmFjZQogICAgICovCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlN0YXJ0TW9kZVRlc3QKICoKICogVGVzdHMgdGhlIHNwZWNpZmllZCB2aWRlbyBtb2RlcyB0byB1cGRhdGUgdGhlIHN5c3RlbSByZWdpc3RyeSB3aXRoCiAqIHJlZnJlc2ggcmF0ZSBpbmZvcm1hdGlvbi4gU3RhcnRNb2RlVGVzdCBzdGFydHMgdGhlIG1vZGUgdGVzdCwKICogRXZhbHVhdGVNb2RlIGlzIHVzZWQgdG8gZmFpbCBvciBwYXNzIGEgbW9kZS4gSWYgRXZhbHVhdGVNb2RlCiAqIGlzbid0IGNhbGxlZCB3aXRoaW4gMTUgc2Vjb25kcywgdGhlIG1vZGUgaXMgZmFpbGVkIGF1dG9tYXRpY2FsbHkKICoKICogQXMgcmVmcmVzaCByYXRlcyBhcmUgaGFuZGxlZCBieSB0aGUgWCBzZXJ2ZXIsIEkgZG9uJ3QgdGhpbmsgdGhpcwogKiBNZXRob2QgaXMgaW1wb3J0YW50CiAqCiAqIFBhcmFtczoKICogIE1vZGVzOiBBbiBhcnJheSBvZiBtb2RlIHNwZWNpZmljYXRpb25zCiAqICBOdW1Nb2RlczogVGhlIG51bWJlciBvZiBtb2RlcyBpbiBNb2RlcwogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MuLi4KICoKICogUmV0dXJuczoKICogIFJldHVybnMgRERFUlJfVEVTVEZJTklTSEVEIGlmIGZsYWdzIGNvbnRhaW5zIEREU01UX0lTVEVTVFJFUVVJUkVELAogKiAgaWYgbm8gbW9kZXMgYXJlIHBhc3NlZCwgRERFUlJfSU5WQUxJRFBBUkFNUyBpcyByZXR1cm5lZCwKICogIG90aGVyd2lzZSBERF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfU3RhcnRNb2RlVGVzdChJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTSVpFICpNb2RlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTnVtTW9kZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgV0FSTigiKCVwKS0+KCVwLCAlZCwgJXgpOiBTZW1pLVN0dWIsIG1vc3QgbGlrZWx5IGhhcm1sZXNzXG4iLCBUaGlzLCBNb2RlcywgTnVtTW9kZXMsIEZsYWdzKTsKCiAgICAvKiBUaGlzIGxvb2tzIHNhbmUgKi8KICAgIGlmKCAoIU1vZGVzKSB8fCAoTnVtTW9kZXMgPT0gMCkgKSByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAvKiBERFNNVF9JU1RFU1RSRVFVSVJFRCBhc2tzIGlmIGEgbW9kZSB0ZXN0IGlzIG5lY2Vzc2FyeS4KICAgICAqIEFzIGl0IGlzIG5vdCwgRERFUlJfVEVTVEZJTklTSEVEIGlzIHJldHVybmVkCiAgICAgKiAoaG9wZWZ1bGx5IHRoYXQncyBjb3JyZWN0CiAgICAgKgogICAgaWYoRmxhZ3MgJiBERFNNVF9JU1RFU1RSRVFVSVJFRCkgcmV0dXJuIERERVJSX1RFU1RGSU5JU0hFRDsKICAgICAqIHdlbGwsIHRoYXQgdmFsdWUgZG9lc24ndCAoeWV0KSBleGlzdCBpbiB0aGUgd2luZSBoZWFkZXJzLCBzbyBpZ25vcmUgaXQKICAgICAqLwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZVN1cmZhY2VzQ2FsbGJhY2sKICoKICogRW51bWVyYXRpb24gY2FsbGJhY2sgZm9yIElEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZUFsbFN1cmZhY2VzLgogKiBJdCByZS1yZWNyZWF0ZXMgdGhlIFdpbmVEM0RTdXJmYWNlLiBJdCdzIHByZXR0eSBzdHJhaWdodGZvcndhcmQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVTdXJmYWNlc0NhbGxiYWNrKElEaXJlY3REcmF3U3VyZmFjZTcgKnN1cmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKmRlc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQ29udGV4dCkKewogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZkltcGwgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJmKTsKICAgIElEaXJlY3REcmF3SW1wbCAqVGhpcyA9IHN1cmZJbXBsLT5kZHJhdzsKICAgIElVbmtub3duICpQYXJlbnQ7CiAgICBJUGFyZW50SW1wbCAqcGFySW1wbCA9IE5VTEw7CiAgICBJV2luZUQzRFN1cmZhY2UgKndpbmVEM0RTdXJmYWNlOwogICAgSFJFU1VMVCBocjsKICAgIHZvaWQgKnRtcDsKCiAgICBXSU5FRDNEU1VSRkFDRV9ERVNDICAgICBEZXNjOwogICAgV0lORUQzREZPUk1BVCAgICAgICAgICAgRm9ybWF0OwogICAgV0lORUQzRFJFU09VUkNFVFlQRSAgICAgVHlwZTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgIFVzYWdlOwogICAgV0lORUQzRFBPT0wgICAgICAgICAgICAgUG9vbDsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgIFNpemU7CgogICAgV0lORUQzRE1VTFRJU0FNUExFX1RZUEUgTXVsdGlTYW1wbGVUeXBlOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgTXVsdGlTYW1wbGVRdWFsaXR5OwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgV2lkdGg7CiAgICBVSU5UICAgICAgICAgICAgICAgICAgICBIZWlnaHQ7CgogICAgVFJBQ0UoIiglcCk6IEVudW1lcmF0ZWQgU3VyZmFjZSAlcFxuIiwgVGhpcywgc3VyZkltcGwpOwoKICAgIC8qIEZvciB0aGUgZW51bWVyYXRpb24gKi8KICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShzdXJmKTsKCiAgICBpZihzdXJmSW1wbC0+SW1wbFR5cGUgPT0gVGhpcy0+SW1wbFR5cGUpIHJldHVybiBEREVOVU1SRVRfT0s7IC8qIENvbnRpbnVlICovCgogICAgLyogR2V0IHRoZSBvYmplY3RzICovCiAgICB3aW5lRDNEU3VyZmFjZSA9IHN1cmZJbXBsLT5XaW5lRDNEU3VyZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRQYXJlbnQod2luZUQzRFN1cmZhY2UsICZQYXJlbnQpOwogICAgSVVua25vd25fUmVsZWFzZShQYXJlbnQpOyAvKiBGb3IgdGhlIGdldFBhcmVudCAqLwoKICAgIC8qIElzIHRoZSBwYXJlbnQgYW4gSVBhcmVudCBpbnRlcmZhY2U/ICovCiAgICBpZihJVW5rbm93bl9RdWVyeUludGVyZmFjZShQYXJlbnQsICZJSURfSVBhcmVudCwgJnRtcCkgPT0gU19PSykKICAgIHsKICAgICAgICAvKiBJdCBpcyBhIElQYXJlbnQgaW50ZXJmYWNlISAqLwogICAgICAgIElVbmtub3duX1JlbGVhc2UoUGFyZW50KTsgLyogRm9yIHRoZSBRdWVyeUludGVyZmFjZSAqLwogICAgICAgIHBhckltcGwgPSBJQ09NX09CSkVDVChJUGFyZW50SW1wbCwgSVBhcmVudCwgUGFyZW50KTsKICAgICAgICAvKiBSZWxlYXNlIHRoZSByZWZlcmVuY2UgdGhlIHBhcmVudCBpbnRlcmZhY2UgaXMgaG9sZGluZyAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKHdpbmVEM0RTdXJmYWNlKTsKICAgIH0KCgogICAgLyogR2V0IHRoZSBzdXJmYWNlIHByb3BlcnRpZXMgKi8KICAgIERlc2MuRm9ybWF0ID0gJkZvcm1hdDsKICAgIERlc2MuVHlwZSA9ICZUeXBlOwogICAgRGVzYy5Vc2FnZSA9ICZVc2FnZTsKICAgIERlc2MuUG9vbCA9ICZQb29sOwogICAgRGVzYy5TaXplID0gJlNpemU7CiAgICBEZXNjLk11bHRpU2FtcGxlVHlwZSA9ICZNdWx0aVNhbXBsZVR5cGU7CiAgICBEZXNjLk11bHRpU2FtcGxlUXVhbGl0eSA9ICZNdWx0aVNhbXBsZVF1YWxpdHk7CiAgICBEZXNjLldpZHRoID0gJldpZHRoOwogICAgRGVzYy5IZWlnaHQgPSAmSGVpZ2h0OwoKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldERlc2Mod2luZUQzRFN1cmZhY2UsICZEZXNjKTsKICAgIGlmKGhyICE9IEQzRF9PSykgcmV0dXJuIGhyOwoKICAgIC8qIENyZWF0ZSB0aGUgbmV3IHN1cmZhY2UgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlU3VyZmFjZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdpZHRoLCBIZWlnaHQsIEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIC8qIExvY2thYmxlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZBTFNFIC8qIERpc2NhcmQgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VyZkltcGwtPm1pcG1hcF9sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3VyZkltcGwtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXNhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNdWx0aVNhbXBsZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTXVsdGlTYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogU2hhcmVkSGFuZGxlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPkltcGxUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcmVudCk7CgogICAgaWYoaHIgIT0gRDNEX09LKQogICAgICAgIHJldHVybiBocjsKCiAgICAvKiBVcGRhdGUgdGhlIElQYXJlbnQgaWYgaXQgZXhpc3RzICovCiAgICBpZihwYXJJbXBsKQogICAgewogICAgICAgIHBhckltcGwtPmNoaWxkID0gKElVbmtub3duICopIHN1cmZJbXBsLT5XaW5lRDNEU3VyZmFjZTsKICAgICAgICAvKiBBZGQgYSByZWZlcmVuY2UgZm9yIHRoZSBJUGFyZW50ICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZihzdXJmSW1wbC0+V2luZUQzRFN1cmZhY2UpOwogICAgfQogICAgLyogVE9ETzogQ29weSB0aGUgc3VyZmFjZSBjb250ZW50LCBleGNlcHQgZm9yIHJlbmRlciB0YXJnZXRzICovCgogICAgaWYoSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2Uod2luZUQzRFN1cmZhY2UpID09IDApCiAgICAgICAgVFJBQ0UoIlN1cmZhY2UgcmVsZWFzZWQgc3VjY2Vzc2Z1bCwgbmV4dCBzdXJmYWNlXG4iKTsKICAgIGVsc2UKICAgICAgICBFUlIoIlNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIG9sZCBXaW5lRDNEU3VyZmFjZVxuIik7CgogICAgc3VyZkltcGwtPkltcGxUeXBlID0gVGhpcy0+SW1wbFR5cGU7CgogICAgcmV0dXJuIERERU5VTVJFVF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZUFsbFN1cmZhY2VzCiAqCiAqIEEgZnVuY3Rpb24sIHRoYXQgY29udmVydHMgYWxsIHdpbmVEM0RTdXJmYWNlcyB0byB0aGUgbmV3IGltcGxlbWVudGF0aW9uIHR5cGUKICogSXQgZW51bWVyYXRlcyBhbGwgc3VyZmFjZXMgd2l0aCBJV2luZUQzRERldmljZTo6RW51bVN1cmZhY2VzLCBjcmVhdGVzIGEKICogbmV3IFdpbmVEM0RTdXJmYWNlLCBjb3BpZXMgdGhlIGNvbnRlbnQgYW5kIHJlbGVhc2VzIHRoZSBvbGQgc3VyZmFjZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZUFsbFN1cmZhY2VzKElEaXJlY3REcmF3SW1wbCAqVGhpcykKewogICAgRERTVVJGQUNFREVTQzIgZGVzYzsKICAgIFRSQUNFKCIoJXApOiBTd2l0Y2ggdG8gaW1wbGVtZW50YXRpb24gJWRcbiIsIFRoaXMsIFRoaXMtPkltcGxUeXBlKTsKCiAgICBpZihUaGlzLT5JbXBsVHlwZSAhPSBTVVJGQUNFX09QRU5HTCAmJiBUaGlzLT5kM2RfaW5pdGlhbGl6ZWQpCiAgICB7CiAgICAgICAgLyogU2hvdWxkIGhhcHBlbiBhbG1vc3QgbmV2ZXIgKi8KICAgICAgICBGSVhNRSgiKCVwKSBTd2l0Y2hpbmcgdG8gbm9uLW9wZW5nbCBzdXJmYWNlcyB3aXRoIGQzZCBzdGFydGVkLiBJcyB0aGlzIGEgYnVnP1xuIiwgVGhpcyk7CiAgICAgICAgLyogU2h1dGRvd24gZDNkICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VfVW5pbml0M0QoVGhpcy0+d2luZUQzRERldmljZSk7CiAgICB9CiAgICAvKiBDb250cmFyeTogRDNEIHN0YXJ0aW5nIGlzIGhhbmRsZWQgYnkgdGhlIGNhbGxlciwgYmVjYXVzZSBpdCBrbm93cyB0aGUgcmVuZGVyIHRhcmdldCAqLwoKICAgIG1lbXNldCgmZGVzYywgMCwgc2l6ZW9mKGRlc2MpKTsKICAgIGRlc2MuZHdTaXplID0gc2l6ZW9mKGRlc2MpOwoKICAgIHJldHVybiBJRGlyZWN0RHJhdzdfRW51bVN1cmZhY2VzKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3NyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRlc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdJbXBsX1JlY3JlYXRlU3VyZmFjZXNDYWxsYmFjayk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEM0Q3Q0JfQ3JlYXRlU3VyZmFjZQogKgogKiBDYWxsYmFjayBmdW5jdGlvbiBmb3IgSURpcmVjdDNERGV2aWNlX0NyZWF0ZVRleHR1cmUuIEl0IHNlYXJjaGVzIGZvciB0aGUKICogY29ycmVjdCBtaXBtYXAgc3VibGV2ZWwsIGFuZCByZXR1cm5zIGl0IHRvIFdpbmVEM0QuCiAqIFRoZSBzdXJmYWNlcyBhcmUgY3JlYXRlZCBhbHJlYWR5IGJ5IElEaXJlY3REcmF3Nzo6Q3JlYXRlU3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBXaXRoLCBIZWlnaHQ6IFdpdGggYW5kIGhlaWdodCBvZiB0aGUgc3VyZmFjZQogKiAgRm9ybWF0OiBUaGUgcmVxdWVzdGVkIGZvcm1hdAogKiAgVXNhZ2UsIFBvb2w6IEQzRFVTQUdFIGFuZCBEM0RQT09MIG9mIHRoZSBzdXJmYWNlCiAqICBsZXZlbDogVGhlIG1pcG1hcCBsZXZlbAogKiAgU3VyZmFjZTogUG9pbnRlciB0byBwYXNzIHRoZSBjcmVhdGVkIHN1cmZhY2UgYmFjayBhdAogKiAgU2hhcmVkSGFuZGxlOiBOVUxMCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKRDNEN0NCX0NyZWF0ZVN1cmZhY2UoSVVua25vd24gKmRldmljZSwKICAgICAgICAgICAgICAgICAgICAgVUlOVCBXaWR0aCwgVUlOVCBIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICBEV09SRCBVc2FnZSwgV0lORUQzRFBPT0wgUG9vbCwgVUlOVCBsZXZlbCwKICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICoqU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgSEFORExFICpTaGFyZWRIYW5kbGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBkZXZpY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZiA9IFRoaXMtPnRleF9yb290OwogICAgaW50IGk7CiAgICBUUkFDRSgiKCVwKSBjYWxsIGJhY2suIHN1cmY9JXBcbiIsIGRldmljZSwgc3VyZik7CgogICAgLyogRmluZCB0aGUgd2FudGVkIG1pcG1hcC4gVGhlcmUgYXJlIGVub3VnaCBtaXBtYXBzIGluIHRoZSBjaGFpbiAqLwogICAgZm9yKGkgPSAwOyBpIDwgbGV2ZWw7IGkrKykKICAgICAgICBzdXJmID0gc3VyZi0+bmV4dF9jb21wbGV4OwoKICAgIC8qIFJldHVybiB0aGUgc3VyZmFjZSAqLwogICAgKlN1cmZhY2UgPSBzdXJmLT5XaW5lRDNEU3VyZmFjZTsKCiAgICBUUkFDRSgiUmV0dXJuaW5nIHdpbmVEM0RTdXJmYWNlICVwLCBpdCBiZWxvbmdzIHRvIHN1cmZhY2UgJXBcbiIsICpTdXJmYWNlLCBzdXJmKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZQogKgogKiBBIGhlbHBlciBmdW5jdGlvbiBmb3IgSURpcmVjdERyYXc3OjpDcmVhdGVTdXJmYWNlLiBJdCBjcmVhdGVzIGEgbmV3IHN1cmZhY2UKICogd2l0aCB0aGUgcGFzc2VkIHBhcmFtZXRlcnMuCiAqCiAqIFBhcmFtczoKICogIEREU0Q6IERlc2NyaXB0aW9uIG9mIHRoZSBzdXJmYWNlIHRvIGNyZWF0ZQogKiAgU3VyZjogQWRkcmVzcyB0byBzdG9yZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYXQKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0NyZWF0ZU5ld1N1cmZhY2UoSURpcmVjdERyYXdJbXBsICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqcEREU0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKipwcFN1cmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgbGV2ZWwpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBVSU5UIFdpZHRoID0gMCwgSGVpZ2h0ID0gMDsKICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0ID0gV0lORUQzREZNVF9VTktOT1dOOwogICAgV0lORUQzRFJFU09VUkNFVFlQRSBSZXNUeXBlID0gV0lORUQzRFJUWVBFX1NVUkZBQ0U7CiAgICBEV09SRCBVc2FnZSA9IDA7CiAgICBXSU5FRDNEU1VSRlRZUEUgSW1wbFR5cGUgPSBUaGlzLT5JbXBsVHlwZTsKICAgIFdJTkVEM0RTVVJGQUNFX0RFU0MgRGVzYzsKICAgIElVbmtub3duICpQYXJlbnQ7CiAgICBJUGFyZW50SW1wbCAqcGFySW1wbCA9IE5VTEw7CiAgICBXSU5FRDNEUE9PTCBQb29sID0gV0lORUQzRFBPT0xfREVGQVVMVDsKCiAgICAvKiBEdW1taWVzIGZvciBHZXREZXNjICovCiAgICBXSU5FRDNEUE9PTCBkdW1teV9kM2Rwb29sOwogICAgV0lORUQzRE1VTFRJU0FNUExFX1RZUEUgZHVtbXlfbXN0OwogICAgVUlOVCBkdW1teV91aW50OwogICAgRFdPUkQgZHVtbXlfZHdvcmQ7CgogICAgaWYgKFRSQUNFX09OKGRkcmF3KSkKICAgIHsKICAgICAgICBUUkFDRSgiICglcCkgUmVxdWVzdGluZyBzdXJmYWNlIGRlc2MgOlxuIiwgVGhpcyk7CiAgICAgICAgRERSQVdfZHVtcF9zdXJmYWNlX2Rlc2MocEREU0QpOwogICAgfQoKICAgIC8qIFNlbGVjdCB0aGUgc3VyZmFjZSB0eXBlLCBpZiBpdCB3YXNuJ3QgY2hvb3NlbiB5ZXQgKi8KICAgIGlmKEltcGxUeXBlID09IFNVUkZBQ0VfVU5LTk9XTikKICAgIHsKICAgICAgICAvKiBVc2UgR0wgU3VyZmFjZXMgaWYgYSBEM0RERVZJQ0UgU3VyZmFjZSBpcyByZXF1ZXN0ZWQgKi8KICAgICAgICBpZihwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTXzNEREVWSUNFKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgQ2hvb3NpbmcgR0wgc3VyZmFjZXMgYmVjYXVzZSBhIDNEREVWSUNFIFN1cmZhY2Ugd2FzIHJlcXVlc3RlZFxuIiwgVGhpcyk7CiAgICAgICAgICAgIEltcGxUeXBlID0gU1VSRkFDRV9PUEVOR0w7CiAgICAgICAgfQoKICAgICAgICAvKiBPdGhlcndpc2UgdXNlIEdESSBzdXJmYWNlcyBmb3Igbm93ICovCiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgQ2hvb3NpbmcgR0RJIHN1cmZhY2VzIGZvciAyRCByZW5kZXJpbmdcbiIsIFRoaXMpOwogICAgICAgICAgICBJbXBsVHlwZSA9IFNVUkZBQ0VfR0RJOwogICAgICAgIH0KCiAgICAgICAgLyogUG9saWN5IGlmIGFsbCBzdXJmYWNlIGltcGxlbWVudGF0aW9ucyBhcmUgYXZhaWxhYmxlOgogICAgICAgICAqIEZpcnN0LCBjaGVjayBpZiBhIGRlZmF1bHQgdHlwZSB3YXMgc2V0IHdpdGggd2luZWNmZy4gSWYgbm90LAogICAgICAgICAqIHRyeSBYcmVuZGVyIHN1cmZhY2VzLCBhbmQgdXNlIHRoZW0gaWYgdGhleSB3b3JrLiBOZXh0LCBjaGVjayBpZgogICAgICAgICAqIGFjY2VsZXJhdGVkIE9wZW5HTCBpcyBhdmFpbGFibGUsIGFuZCB1c2UgR0wgc3VyZmFjZXMgaW4gdGhpcwogICAgICAgICAqIGNhc2UuIElmIGFsbCBlbHNlIGZhaWxzLCB1c2UgR0RJIHN1cmZhY2VzLiBJZiBhIDNEREVWSUNFIHN1cmZhY2UKICAgICAgICAgKiB3YXMgY3JlYXRlZCwgYWx3YXlzIHVzZSBPcGVuR0wgc3VyZmFjZXMuCiAgICAgICAgICoKICAgICAgICAgKiAoTm90ZTogWHJlbmRlciBzdXJmYWNlcyBhcmUgbm90IGltcGxlbWVudGVkIGZvciBub3csIHRoZQogICAgICAgICAqIHVuYWNjZWxlcmF0ZWQgaW1wbGVtZW50YXRpb24gdXNlcyBHREkgdG8gcmVuZGVyIGluIFNvZnR3YXJlKQogICAgICAgICAqLwoKICAgICAgICAvKiBTdG9yZSB0aGUgdHlwZS4gSWYgaXQgbmVlZHMgdG8gYmUgY2hhbmdlZCwgYWxsIFdpbmVEM0RTdXJmYWNlcyBoYXZlIHRvCiAgICAgICAgICogYmUgcmUtY3JlYXRlZC4gVGhpcyBjb3VsZCBiZSBkb25lIHdpdGggSURpcmVjdERyYXdTdXJmYWNlNzo6UmVzdG9yZQogICAgICAgICAqLwogICAgICAgIFRoaXMtPkltcGxUeXBlID0gSW1wbFR5cGU7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgIGlmKChwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTXzNEREVWSUNFICkgJiYgCiAgICAgICAgICAgIChUaGlzLT5JbXBsVHlwZSAhPSBTVVJGQUNFX09QRU5HTCApICYmIERlZmF1bHRTdXJmYWNlVHlwZSA9PSBTVVJGQUNFX1VOS05PV04pCiAgICAgICAgewogICAgICAgICAgICAvKiBXZSBoYXZlIHRvIGNoYW5nZSB0byBPcGVuR0wsCiAgICAgICAgICAgICAqIGFuZCByZS1jcmVhdGUgYWxsIFdpbmVEM0RTdXJmYWNlcwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgSW1wbFR5cGUgPSBTVVJGQUNFX09QRU5HTDsKICAgICAgICAgICAgVGhpcy0+SW1wbFR5cGUgPSBJbXBsVHlwZTsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgUmUtY3JlYXRpbmcgYWxsIHN1cmZhY2VzXG4iLCBUaGlzKTsKICAgICAgICAgICAgSURpcmVjdERyYXdJbXBsX1JlY3JlYXRlQWxsU3VyZmFjZXMoVGhpcyk7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIERvbmUgcmVjcmVhdGluZyBhbGwgc3VyZmFjZXNcbiIsIFRoaXMpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKFRoaXMtPkltcGxUeXBlICE9IFNVUkZBQ0VfT1BFTkdMKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiVGhlIGFwcGxpY2F0aW9uIHJlcXVlc3RzIGEgM0QgY2FwYWJsZSBzdXJmYWNlLCBidXQgYSBub24tb3BlbmdsIHN1cmZhY2Ugd2FzIHNldCBpbiB0aGUgcmVnaXN0cnlcbiIpOwogICAgICAgICAgICAvKiBEbyBub3QgZmFpbCBzdXJmYWNlIGNyZWF0aW9uLCBvbmx5IGZhaWwgM0QgZGV2aWNlIGNyZWF0aW9uICovCiAgICAgICAgfQogICAgfQoKICAgIC8qIEdldCB0aGUgY29ycmVjdCB3aW5lZDNkIHVzYWdlICovCiAgICBpZiAocEREU0QtPmRkc0NhcHMuZHdDYXBzICYgKEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTX0JBQ0tCVUZGRVIgICAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU18zRERFVklDRSAgICAgICApICkKICAgIHsKICAgICAgICBVc2FnZSB8PSBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUOwoKICAgICAgICBwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU19WSURFT01FTU9SWSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfVklTSUJMRSAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTX0xPQ0FMVklETUVNOwogICAgfQogICAgaWYgKHBERFNELT5kZHNDYXBzLmR3Q2FwcyAmIChERFNDQVBTX09WRVJMQVkpKQogICAgewogICAgICAgIFVzYWdlIHw9IFdJTkVEM0RVU0FHRV9PVkVSTEFZOwogICAgfQogICAgaWYoVGhpcy0+ZGVwdGhzdGVuY2lsKQogICAgewogICAgICAgIC8qIFRoZSBkZXB0aCBzdGVuY2lsIGNyZWF0aW9uIGNhbGxiYWNrIHNldHMgdGhpcyBmbGFnLgogICAgICAgICAqIFNldCB0aGUgV2luZUQzRCB1c2FnZSB0byBsZXQgaXQga25vdyB0aGF0IGl0J3MgYSBkZXB0aAogICAgICAgICAqIFN0ZW5jaWwgc3VyZmFjZS4KICAgICAgICAgKi8KICAgICAgICBVc2FnZSB8PSBXSU5FRDNEVVNBR0VfREVQVEhTVEVOQ0lMOwogICAgfQogICAgaWYocEREU0QtPmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19TWVNURU1NRU1PUlkpCiAgICB7CiAgICAgICAgUG9vbCA9IFdJTkVEM0RQT09MX1NZU1RFTU1FTTsKICAgIH0KCiAgICBGb3JtYXQgPSBQaXhlbEZvcm1hdF9ERDJXaW5lRDNEKCZwRERTRC0+dTQuZGRwZlBpeGVsRm9ybWF0KTsKICAgIGlmKEZvcm1hdCA9PSBXSU5FRDNERk1UX1VOS05PV04pCiAgICB7CiAgICAgICAgRVJSKCJVbnN1cHBvcnRlZCAvIFVua25vd24gcGl4ZWxmb3JtYXRcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUElYRUxGT1JNQVQ7CiAgICB9CgogICAgLyogQ3JlYXRlIHRoZSBTdXJmYWNlIG9iamVjdCAqLwogICAgKnBwU3VyZiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSURpcmVjdERyYXdTdXJmYWNlSW1wbCkpOwogICAgaWYoISpwcFN1cmYpCiAgICB7CiAgICAgICAgRVJSKCIoJXApIEVycm9yIGFsbG9jYXRpbmcgbWVtb3J5IGZvciBhIHN1cmZhY2VcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBEREVSUl9PVVRPRlZJREVPTUVNT1JZOwogICAgfQogICAgSUNPTV9JTklUX0lOVEVSRkFDRSgqcHBTdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBJRGlyZWN0RHJhd1N1cmZhY2U3X1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRSgqcHBTdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2UzLCBJRGlyZWN0RHJhd1N1cmZhY2UzX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRSgqcHBTdXJmLCBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCwgSURpcmVjdERyYXdHYW1tYUNvbnRyb2xfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKCpwcFN1cmYsIElEaXJlY3QzRFRleHR1cmUyLCBJRGlyZWN0M0RUZXh0dXJlMl9WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoKnBwU3VyZiwgSURpcmVjdDNEVGV4dHVyZSwgSURpcmVjdDNEVGV4dHVyZTFfVnRibCk7CiAgICAoKnBwU3VyZiktPnJlZiA9IDE7CiAgICAoKnBwU3VyZiktPnZlcnNpb24gPSA3OwogICAgKCpwcFN1cmYpLT5kZHJhdyA9IFRoaXM7CiAgICAoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy5kd1NpemUgPSBzaXplb2YoRERTVVJGQUNFREVTQzIpOwogICAgKCpwcFN1cmYpLT5zdXJmYWNlX2Rlc2MudTQuZGRwZlBpeGVsRm9ybWF0LmR3U2l6ZSA9IHNpemVvZihERFBJWEVMRk9STUFUKTsKICAgIEREX1NUUlVDVF9DT1BZX0JZU0laRSgmKCpwcFN1cmYpLT5zdXJmYWNlX2Rlc2MsIHBERFNEKTsKCiAgICAvKiBTdXJmYWNlIGF0dGFjaG1lbnRzICovCiAgICAoKnBwU3VyZiktPm5leHRfYXR0YWNoZWQgPSBOVUxMOwogICAgKCpwcFN1cmYpLT5maXJzdF9hdHRhY2hlZCA9ICpwcFN1cmY7CgogICAgKCpwcFN1cmYpLT5uZXh0X2NvbXBsZXggPSBOVUxMOwogICAgKCpwcFN1cmYpLT5maXJzdF9jb21wbGV4ID0gKnBwU3VyZjsKCiAgICAvKiBOZWVkZWQgdG8gcmUtY3JlYXRlIHRoZSBzdXJmYWNlIG9uIGFuIGltcGxlbWVudGF0aW9uIGNoYW5nZSAqLwogICAgKCpwcFN1cmYpLT5JbXBsVHlwZSA9IEltcGxUeXBlOwoKICAgIC8qIEZvciBEM0REZXZpY2UgY3JlYXRpb24gKi8KICAgICgqcHBTdXJmKS0+aXNSZW5kZXJUYXJnZXQgPSBGQUxTRTsKCiAgICAvKiBBIHRyYWNlIG1lc3NhZ2UgZm9yIGRlYnVnZ2luZyAqLwogICAgVFJBQ0UoIiglcCkgQ3JlYXRlZCBJRGlyZWN0RHJhd1N1cmZhY2UgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlIGF0ICVwXG4iLCBUaGlzLCAqcHBTdXJmKTsKCiAgICBpZihwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiAoIEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UgfCBERFNDQVBTX1RFWFRVUkUgfCBERFNDQVBTXzNEREVWSUNFKSApCiAgICB7CiAgICAgICAgLyogUmVuZGVyIHRhcmdldHMgYW5kIHRleHR1cmVzIG5lZWQgYSBJUGFyZW50IGludGVyZmFjZSwKICAgICAgICAgKiBiZWNhdXNlIFdpbmVEM0Qgd2lsbCBkZXN0cm95IHRoZW0gd2hlbiB0aGUgc3dhcGNoYWluCiAgICAgICAgICogaXMgcmVsZWFzZWQKICAgICAgICAgKi8KICAgICAgICBwYXJJbXBsID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihJUGFyZW50SW1wbCkpOwogICAgICAgIGlmKCFwYXJJbXBsKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5IHdoZW4gYWxsb2NhdGluZyBtZW1vcnkgZm9yIGEgSVBhcmVudCBpbXBsZW1lbnRhdGlvblxuIik7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9PVVRPRk1FTU9SWTsKICAgICAgICB9CiAgICAgICAgcGFySW1wbC0+cmVmID0gMTsKICAgICAgICBJQ09NX0lOSVRfSU5URVJGQUNFKHBhckltcGwsIElQYXJlbnQsIElQYXJlbnRfVnRibCk7CiAgICAgICAgUGFyZW50ID0gKElVbmtub3duICopIElDT01fSU5URVJGQUNFKHBhckltcGwsIElQYXJlbnQpOwogICAgICAgIFRSQUNFKCJVc2luZyBJUGFyZW50IGludGVyZmFjZSAlcCBhcyBwYXJlbnRcbiIsIHBhckltcGwpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8qIFVzZSB0aGUgc3VyZmFjZSBhcyBwYXJlbnQgKi8KICAgICAgICBQYXJlbnQgPSAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0UoKnBwU3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNyk7CiAgICAgICAgVFJBQ0UoIlVzaW5nIFN1cmZhY2UgaW50ZXJmYWNlICVwIGFzIHBhcmVudFxuIiwgKnBwU3VyZik7CiAgICB9CgogICAgLyogTm93IGNyZWF0ZSB0aGUgV2luZUQzRCBTdXJmYWNlICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZVN1cmZhY2UoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRERTRC0+ZHdXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRERTRC0+ZHdIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgLyogTG9ja2FibGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkFMU0UgLyogRGlzY2FyZCAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNUeXBlLCBVc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RNVUxUSVNBTVBMRV9OT05FLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogTXVsdGlTYW1wbGVRdWFsaXR5ICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogU2hhcmVkSGFuZGxlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEltcGxUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcmVudCk7CgogICAgaWYoaHIgIT0gRDNEX09LKQogICAgewogICAgICAgIEVSUigiSVdpbmVEM0REZXZpY2U6OkNyZWF0ZVN1cmZhY2UgZmFpbGVkLiBociA9ICUwOHhcbiIsIGhyKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogU2V0IHRoZSBjaGlsZCBvZiB0aGUgcGFyZW50IGltcGxlbWVudGF0aW9uIGlmIGl0IGV4aXN0cyAqLwogICAgaWYocGFySW1wbCkKICAgIHsKICAgICAgICBwYXJJbXBsLT5jaGlsZCA9IChJVW5rbm93biAqKSAoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlOwogICAgICAgIC8qIFRoZSBJUGFyZW50IHJlbGVhc2VzIHRoZSBXaW5lRDNEU3VyZmFjZSwgYW5kCiAgICAgICAgICogdGhlIGRkcmF3IHN1cmZhY2UgZG9lcyB0aGF0IHRvby4gSG9sZCBhIHJlZmVyZW5jZQogICAgICAgICAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSk7CiAgICB9CgogICAgLyogSW5jcmVhc2UgdGhlIHN1cmZhY2UgY291bnRlciwgYW5kIGF0dGFjaCB0aGUgc3VyZmFjZSAqLwogICAgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnN1cmZhY2VzKTsKICAgIGxpc3RfYWRkX2hlYWQoJlRoaXMtPnN1cmZhY2VfbGlzdCwgJigqcHBTdXJmKS0+c3VyZmFjZV9saXN0X2VudHJ5KTsKCiAgICAvKiBIZXJlIHdlIGNvdWxkIHN0b3JlIGFsbCBjcmVhdGVkIHN1cmZhY2VzIGluIHRoZSBEaXJlY3REcmF3SW1wbCBzdHJ1Y3R1cmUsCiAgICAgKiBCdXQgdGhpcyBjb3VsZCBhbHNvIGJlIGRlbGVnYXRlZCB0byBXaW5lRERyYXcsIGFzIGl0IGtlZXBzIHRyYWNrIG9mIGFsbCBpdHMKICAgICAqIHJlc291cmNlcy4gTm90IGltcGxlbWVudGVkIGZvciBub3csIGFzIHRoZXJlIGFyZSBtb3JlIGltcG9ydGFudCB0aGluZ3MgOykKICAgICAqLwoKICAgIC8qIEdldCB0aGUgcGl4ZWwgZm9ybWF0IG9mIHRoZSBXaW5lRDNEU3VyZmFjZSBhbmQgc3RvcmUgaXQuCiAgICAgKiBEb24ndCB1c2UgdGhlIEZvcm1hdCBjaG9vc2VuIGFib3ZlLCBXaW5lRDNEIG1pZ2h0IGhhdmUKICAgICAqIGNoYW5nZWQgaXQKICAgICAqLwogICAgRGVzYy5Gb3JtYXQgPSAmRm9ybWF0OwogICAgRGVzYy5UeXBlID0gJlJlc1R5cGU7CiAgICBEZXNjLlVzYWdlID0gJlVzYWdlOwogICAgRGVzYy5Qb29sID0gJmR1bW15X2QzZHBvb2w7CiAgICBEZXNjLlNpemUgPSAmZHVtbXlfdWludDsKICAgIERlc2MuTXVsdGlTYW1wbGVUeXBlID0gJmR1bW15X21zdDsKICAgIERlc2MuTXVsdGlTYW1wbGVRdWFsaXR5ID0gJmR1bW15X2R3b3JkOwogICAgRGVzYy5XaWR0aCA9ICZXaWR0aDsKICAgIERlc2MuSGVpZ2h0ID0gJkhlaWdodDsKCiAgICAoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy5kd0ZsYWdzIHw9IEREU0RfUElYRUxGT1JNQVQ7CiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXREZXNjKCgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UsICZEZXNjKTsKICAgIGlmKGhyICE9IEQzRF9PSykKICAgIHsKICAgICAgICBFUlIoIklXaW5lRDNEU3VyZmFjZTo6R2V0RGVzYyBmYWlsZWRcbiIpOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZSggKElEaXJlY3REcmF3U3VyZmFjZTcgKikgKnBwU3VyZik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIGlmKEZvcm1hdCA9PSBXSU5FRDNERk1UX1VOS05PV04pCiAgICB7CiAgICAgICAgRklYTUUoIklXaW5lRDNEU3VyZmFjZTo6R2V0RGVzYyByZXR1cm5lZCBXSU5FRDNERk1UX1VOS05PV05cbiIpOwogICAgfQogICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoICYoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy51NC5kZHBmUGl4ZWxGb3JtYXQsIEZvcm1hdCk7CgogICAgLyogQW5ubyAxNjAyIHN0b3JlcyB0aGUgcGl0Y2ggcmlnaHQgYWZ0ZXIgc3VyZmFjZSBjcmVhdGlvbiwgc28gbWFrZSBzdXJlIGl0J3MgdGhlcmUuCiAgICAgKiBJIGNhbid0IExvY2tSZWN0KCkgdGhlIHN1cmZhY2UgaGVyZSBiZWNhdXNlIGlmIE9wZW5HTCBzdXJmYWNlcyBhcmUgaW4gdXNlLCB0aGUKICAgICAqIFdpbmVEM0REZXZpY2UgbWlnaHQgbm90IGJlIHVzZWFibGUgZm9yIDNEIHlldCwgc28gYW4gZXh0cmEgbWV0aG9kIHdhcyBjcmVhdGVkCiAgICAgKi8KICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgfD0gRERTRF9QSVRDSDsKICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLnUxLmxQaXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaCgoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlKTsKCiAgICAvKiBBcHBsaWNhdGlvbiBwYXNzZWQgYSBjb2xvciBrZXk/IFNldCBpdCEgKi8KICAgIGlmKHBERFNELT5kd0ZsYWdzICYgRERTRF9DS0RFU1RPVkVSTEFZKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleSgoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENLRVlfREVTVE9WRVJMQVksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwRERTRC0+dTMuZGRja0NLRGVzdE92ZXJsYXkpOwogICAgfQogICAgaWYocEREU0QtPmR3RmxhZ3MgJiBERFNEX0NLREVTVEJMVCkKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERDS0VZX0RFU1RCTFQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwRERTRC0+ZGRja0NLRGVzdEJsdCk7CiAgICB9CiAgICBpZihwRERTRC0+ZHdGbGFncyAmIEREU0RfQ0tTUkNPVkVSTEFZKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleSgoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENLRVlfU1JDT1ZFUkxBWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBERFNELT5kZGNrQ0tTcmNPdmVybGF5KTsKICAgIH0KICAgIGlmKHBERFNELT5kd0ZsYWdzICYgRERTRF9DS1NSQ0JMVCkKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERDS0VZX1NSQ0JMVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBERFNELT5kZGNrQ0tTcmNCbHQpOwogICAgfQogICAgaWYgKCBwRERTRC0+ZHdGbGFncyAmIEREU0RfTFBTVVJGQUNFKQogICAgewogICAgICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX1NldE1lbSgoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlLCBwRERTRC0+bHBTdXJmYWNlKTsKICAgICAgICBpZihociAhPSBXSU5FRDNEX09LKQogICAgICAgIHsKICAgICAgICAgICAgLyogTm8gbmVlZCBmb3IgYSB0cmFjZSBoZXJlLCB3aW5lZDNkIGRvZXMgdGhhdCBmb3IgdXMgKi8KICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKElDT01fSU5URVJGQUNFKCgqcHBTdXJmKSwgSURpcmVjdERyYXdTdXJmYWNlNykpOwogICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6Q3JlYXRlU3VyZmFjZQogKgogKiBDcmVhdGVzIGEgbmV3IElEaXJlY3REcmF3U3VyZmFjZSBvYmplY3QgYW5kIHJldHVybnMgaXRzIGludGVyZmFjZS4KICoKICogVGhlIHN1cmZhY2UgY29ubmVjdGlvbnMgd2l0aCB3aW5lZDNkIGFyZSBhIGJpdCB0cmlja3kuIEJhc2ljYWxseSBpdCB3b3JrcwogKiBsaWtlIHRoaXM6CiAqCiAqIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18ICAgICAgICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfAogKiB8IEREcmF3IHN1cmZhY2UgICAgICAgICAgfCAgICAgICAgICAgICAgIHwgV2luZUQzRFN1cmZhY2UgIHwKICogfCAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICB8CiAqIHwgICAgICAgIFdpbmVEM0RTdXJmYWNlICB8LS0tLS0tLS0tLS0tLS0+fCAgICAgICAgICAgICAgICAgfAogKiB8ICAgICAgICBDaGlsZCAgICAgICAgICAgfDwtLS0tLS0tLS0tLS0tPnwgUGFyZW50ICAgICAgICAgIHwKICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgICAgICAgICAgICAgICB8LS0tLS0tLS0tLS0tLS0tLS18CiAqCiAqIFRoZSBERHJhdyBzdXJmYWNlIGlzIHRoZSBwYXJlbnQgb2YgdGhlIHdpbmVkM2Qgc3VyZmFjZSwgYW5kIGl0IHJlbGVhc2VzCiAqIHRoZSBXaW5lRDNEU3VyZmFjZSB3aGVuIHRoZSBkZHJhdyBzdXJmYWNlIGlzIGRlc3Ryb3llZC4KICoKICogSG93ZXZlciwgZm9yIGFsbCBzdXJmYWNlcyB3aGljaCBjYW4gYmUgaW4gYSBjb250YWluZXIgaW4gV2luZUQzRCwKICogd2UgaGF2ZSB0byBkbyB0aGlzLiBUaGVzZSBzdXJmYWNlcyBhcmUgdXN1c2FsbHkgY29tcGxleCBzdXJmYWNlcywKICogc28gdGhpcyBjb25jZXJucyBwcmltYXJ5IHN1cmZhY2VzIHdpdGggYSBmcm9udCBhbmQgYSBiYWNrIGJ1ZmZlciwKICogYW5kIHRleHR1cmVzLgogKgogKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwKICogfCBERHJhdyBzdXJmYWNlICAgICAgICAgIHwgICAgICAgICAgICAgICB8IENvbnRhaW50ZXIgICAgICB8CiAqIHwgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgfAogKiB8ICAgICAgICAgICAgICAgICAgQ2hpbGQgfDwtLS0tLS0tLS0tLS0tPnwgUGFyZW50ICAgICAgICAgIHwKICogfCAgICAgICAgICAgICAgICBUZXh0dXJlIHw8LS0tLS0tLS0tLS0tLT58ICAgICAgICAgICAgICAgICB8CiAqIHwgICAgICAgICBXaW5lRDNEU3VyZmFjZSB8PC0tLS18ICAgICAgICAgfCAgICAgICAgICBMZXZlbHMgfDwtLXwKICogfCBDb21wbGV4IGNvbm5lY3Rpb24gICAgIHwgICAgIHwgICAgICAgICB8ICAgICAgICAgICAgICAgICB8ICAgfAogKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgfCAgICAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwgICB8CiAqICBeICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgIHwtLS0tLS0tLS0tLS0tLS0tLS18ICAgICB8ICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfCAgIHwKICogIHwgICAgfCBJUGFyZW50ICAgICAgICAgIHwgICAgIHwtLS0tLS0tLT58IFdpbmVEM0RTdXJmYWNlICB8ICAgfAogKiAgfCAgICB8ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgIHwgICB8CiAqICB8ICAgIHwgICAgICAgICAgICBDaGlsZCB8PC0tLS0tLS0tLS0tLS0+fCBQYXJlbnQgICAgICAgICAgfCAgIHwKICogIHwgICAgfCAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICB8ICAgICAgIENvbnRhaW5lciB8PC0tfAogKiAgfCAgICB8LS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwgICB8CiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgIHwgRERyYXcgc3VyZmFjZSAyICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgfCAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHw8LT58IENvbXBsZXggcm9vdCAgIENoaWxkIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgIHwgICAgICAgICAgICAgIFRleHR1cmUgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgfCAgICAgICBXaW5lRDNEU3VyZmFjZSB8PC0tLS18ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS18ICAgICB8ICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfCAgIHwKICogIHwgICAgfCBJUGFyZW50ICAgICAgICAgICAgIHwgICAgIHwtLS0tLT58IFdpbmVEM0RTdXJmYWNlICB8ICAgfAogKiAgfCAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgIHwgICB8CiAqICB8ICAgIHwgICAgICAgICAgICAgICBDaGlsZCB8PC0tLS0tLS0tLS0+fCBQYXJlbnQgICAgICAgICAgfCAgIHwKICogIHwgICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgICAgICAgICAgICB8ICAgICAgIENvbnRhaW5lciB8PC0tfAogKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwgICB8CiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICAgICAgICAgICAgLS0tTW9yZSBzdXJmYWNlcyBjYW4gZm9sbG93LS0tICAgICAgICAgICAgICAgICAgfAogKgogKiBUaGUgcmVhc29uIGlzIHRoYXQgdGhlIElXaW5lRDNEU3dhcGNoYWluKHJlbmRlciB0YXJnZXQgY29udGFpbmVyKQogKiBhbmQgdGhlIElXaW5lRDNEVGV4dXJlKFRleHR1cmUgY29udGFpbmVyKSByZWxlYXNlIHRoZSBwYXJlbnRzCiAqIG9mIHRoZWlyIHN1cmZhY2UncyBjaGlsZHJlbiwgYnV0IGJ5IHJlbGVhc2luZyB0aGUgY29tcGxleCByb290CiAqIHRoZSBzdXJmYWNlcyB3aGljaCBhcmUgY29tcGxleGx5IGF0dGFjaGVkIHRvIGl0IGFyZSBkZXN0cm95ZWQKICogdG9vLiBTZWUgSURpcmVjdERyYXdTdXJmYWNlOjpSZWxlYXNlIGZvciBhIG1vcmUgZGV0YWlsZWQKICogZXhwbGFuYXRpb24uCiAqCiAqIFBhcmFtczoKICogIEREU0Q6IERlc2NyaXB0aW9uIG9mIHRoZSBzdXJmYWNlIHRvIGNyZWF0ZQogKiAgU3VyZjogQWRkcmVzcyB0byBzdG9yZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYXQKICogIFVua091dGVyOiBCYXNpY2FsbHkgZm9yIGFnZ3JlZ2F0aW9uIHN1cHBvcnQsIGJ1dCBkZHJhdyBkb2Vzbid0IHN1cHBvcnQKICogICAgICAgICAgICBhZ2dyZWdhdGlvbiwgc28gaXQgaGFzIHRvIGJlIE5VTEwKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIENMQVNTX0VfTk9BR0dSRUdBVElPTiBpZiBVbmtPdXRlciAhPSBOVUxMCiAqICBEREVSUl8qIGlmIGFuIGVycm9yIG9jY3VycwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlU3VyZmFjZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqRERTRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqKlN1cmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlcikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKm9iamVjdCA9IE5VTEw7CiAgICBIUkVTVUxUIGhyOwogICAgTE9ORyBleHRyYV9zdXJmYWNlcyA9IDAsIGk7CiAgICBERFNVUkZBQ0VERVNDMiBkZXNjMjsKICAgIFVJTlQgbGV2ZWwgPSAwOwogICAgV0lORUQzRERJU1BMQVlNT0RFIE1vZGU7CgogICAgVFJBQ0UoIiglcCktPiglcCwlcCwlcClcbiIsIFRoaXMsIEREU0QsIFN1cmYsIFVua091dGVyKTsKCiAgICAvKiBTb21lIGNoZWNrcyBiZWZvcmUgd2Ugc3RhcnQgKi8KICAgIGlmIChUUkFDRV9PTihkZHJhdykpCiAgICB7CiAgICAgICAgVFJBQ0UoIiAoJXApIFJlcXVlc3Rpbmcgc3VyZmFjZSBkZXNjIDpcbiIsIFRoaXMpOwogICAgICAgIEREUkFXX2R1bXBfc3VyZmFjZV9kZXNjKEREU0QpOwogICAgfQoKICAgIGlmIChVbmtPdXRlciAhPSBOVUxMKQogICAgewogICAgICAgIEZJWE1FKCIoJXApIDogb3V0ZXIgIT0gTlVMTD9cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBDTEFTU19FX05PQUdHUkVHQVRJT047IC8qIHVuY2hlY2tlZCAqLwogICAgfQoKICAgIGlmICghKEREU0QtPmR3RmxhZ3MgJiBERFNEX0NBUFMpKQogICAgewogICAgICAgIC8qIERWSURFTy5ETEwgZG9lcyBmb3JnZXQgdGhlIEREU0RfQ0FQUyBmbGFnIC4uLiAqc2lnaCogKi8KICAgICAgICBERFNELT5kd0ZsYWdzIHw9IEREU0RfQ0FQUzsKICAgIH0KICAgIGlmIChERFNELT5kZHNDYXBzLmR3Q2FwcyA9PSAwKQogICAgewogICAgICAgIC8qIFRoaXMgaGFzIGJlZW4gY2hlY2tlZCBvbiByZWFsIFdpbmRvd3MgKi8KICAgICAgICBERFNELT5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfTE9DQUxWSURNRU0gfCBERFNDQVBTX1ZJREVPTUVNT1JZOwogICAgfQoKICAgIGlmIChERFNELT5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfQUxMT0NPTkxPQUQpCiAgICB7CiAgICAgICAgLyogSWYgdGhlIHN1cmZhY2UgaXMgb2YgdGhlICdhbGxvY29ubG9hZCcgdHlwZSwgaWdub3JlIHRoZSBMUFNVUkZBQ0UgZmllbGQgKi8KICAgICAgICBERFNELT5kd0ZsYWdzICY9IH5ERFNEX0xQU1VSRkFDRTsKICAgIH0KCiAgICBpZiAoKEREU0QtPmR3RmxhZ3MgJiBERFNEX0xQU1VSRkFDRSkgJiYgKEREU0QtPmxwU3VyZmFjZSA9PSBOVUxMKSkKICAgIHsKICAgICAgICAvKiBGcmFuayBIZXJiZXJ0J3MgRHVuZSBzcGVjaWZpZXMgYSBudWxsIHBvaW50ZXIgZm9yIHRoZSBzdXJmYWNlLCBpZ25vcmUgdGhlIExQU1VSRkFDRSBmaWVsZCAqLwogICAgICAgIFdBUk4oIiglcCkgTnVsbCBzdXJmYWNlIHBvaW50ZXIgc3BlY2lmaWVkLCBpZ25vcmUgaXQhXG4iLCBUaGlzKTsKICAgICAgICBERFNELT5kd0ZsYWdzICY9IH5ERFNEX0xQU1VSRkFDRTsKICAgIH0KCiAgICBpZigoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiAoRERTQ0FQU19GTElQIHwgRERTQ0FQU19QUklNQVJZU1VSRkFDRSkpID09IChERFNDQVBTX0ZMSVAgfCBERFNDQVBTX1BSSU1BUllTVVJGQUNFKSAmJgogICAgICAgIShUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmIEREU0NMX0VYQ0xVU0lWRSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIiglcCk6IEF0dGVtcHQgdG8gY3JlYXRlIGEgZmxpcGFibGUgcHJpbWFyeSBzdXJmYWNlIHdpdGhvdXQgRERTQ0xfRVhDTFVTSVZFIHNldFxuIiwgVGhpcyk7CiAgICAgICAgKlN1cmYgPSBOVUxMOwogICAgICAgIHJldHVybiBEREVSUl9OT0VYQ0xVU0lWRU1PREU7CiAgICB9CgogICAgaWYgKFN1cmYgPT0gTlVMTCkKICAgIHsKICAgICAgICBGSVhNRSgiKCVwKSBZb3Ugd2FudCB0byBnZXQgYmFjayBhIHN1cmZhY2U/IERvbid0IGdpdmUgTlVMTCBwdHJzIVxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIEVfUE9JTlRFUjsgLyogdW5jaGVja2VkICovCiAgICB9CgogICAgLyogQWNjb3JkaW5nIHRvIHRoZSBtc2RuIHRoaXMgZmxhZyBpcyBpZ25vcmVkIGJ5IENyZWF0ZVN1cmZhY2UgKi8KICAgIGlmIChERFNELT5kd1NpemUgPj0gc2l6ZW9mKEREU1VSRkFDRURFU0MyKSkKICAgICAgICBERFNELT5kZHNDYXBzLmR3Q2FwczIgJj0gfkREU0NBUFMyX01JUE1BUFNVQkxFVkVMOwoKICAgIC8qIE1vZGlmeSBzb21lIGZsYWdzICovCiAgICBtZW1zZXQoJmRlc2MyLCAwLCBzaXplb2YoZGVzYzIpKTsKICAgIGRlc2MyLmR3U2l6ZSA9IHNpemVvZihkZXNjMik7ICAgLyogRm9yIHRoZSBzdHJ1Y3QgY29weSAqLwogICAgRERfU1RSVUNUX0NPUFlfQllTSVpFKCZkZXNjMiwgRERTRCk7CiAgICBkZXNjMi5kd1NpemUgPSBzaXplb2YoZGVzYzIpOyAgIC8qIFRvIG92ZXJyaWRlIGEgcG9zc2libHkgc21hbGxlciBzaXplICovCiAgICBkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQuZHdTaXplPXNpemVvZihERFBJWEVMRk9STUFUKTsgLyogSnVzdCB0byBiZSBzdXJlICovCgogICAgLyogR2V0IHRoZSB2aWRlbyBtb2RlIGZyb20gV2luZUQzRCAtIHdlIHdpbGwgbmVlZCBpdCAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXREaXNwbGF5TW9kZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiBTd2FwY2hhaW4gMCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTW9kZSk7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIEVSUigiRmFpbGVkIHRvIHJlYWQgZGlzcGxheSBtb2RlIGZyb20gd2luZWQzZFxuIik7CiAgICAgICAgc3dpdGNoKFRoaXMtPm9yaWdfYnBwKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICAgICAgTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1A4OwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDE1OgogICAgICAgICAgICAgICAgTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1gxUjVHNUI1OwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDE2OgogICAgICAgICAgICAgICAgTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1I1RzZCNTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAyNDoKICAgICAgICAgICAgICAgIE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9SOEc4Qjg7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgMzI6CiAgICAgICAgICAgICAgICBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfWDhSOEc4Qjg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgTW9kZS5XaWR0aCA9IFRoaXMtPm9yaWdfd2lkdGg7CiAgICAgICAgTW9kZS5IZWlnaHQgPSBUaGlzLT5vcmlnX2hlaWdodDsKICAgIH0KCiAgICAvKiBObyBwaXhlbGZvcm1hdCBnaXZlbj8gVXNlIHRoZSBjdXJyZW50IHNjcmVlbiBmb3JtYXQgKi8KICAgIGlmKCEoZGVzYzIuZHdGbGFncyAmIEREU0RfUElYRUxGT1JNQVQpKQogICAgewogICAgICAgIGRlc2MyLmR3RmxhZ3MgfD0gRERTRF9QSVhFTEZPUk1BVDsKICAgICAgICBkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQuZHdTaXplPXNpemVvZihERFBJWEVMRk9STUFUKTsKCiAgICAgICAgLyogV2FpdDogSXQgY291bGQgYmUgYSBaIGJ1ZmZlciAqLwogICAgICAgIGlmKGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19aQlVGRkVSKQogICAgICAgIHsKICAgICAgICAgICAgc3dpdGNoKGRlc2MyLnUyLmR3TWlwTWFwQ291bnQpIC8qIFdobyBoYWQgdGhpcyBnbG9yaW91cyBpZGVhPyAqLwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIDE1OgogICAgICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQsIFdJTkVEM0RGTVRfRDE1UzEpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAxNjoKICAgICAgICAgICAgICAgICAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmZGVzYzIudTQuZGRwZlBpeGVsRm9ybWF0LCBXSU5FRDNERk1UX0QxNik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDI0OgogICAgICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQsIFdJTkVEM0RGTVRfRDI0WDgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAzMjoKICAgICAgICAgICAgICAgICAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmZGVzYzIudTQuZGRwZlBpeGVsRm9ybWF0LCBXSU5FRDNERk1UX0QzMik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEVSUigiVW5rbm93biBaIGJ1ZmZlciBiaXQgZGVwdGhcbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQsIE1vZGUuRm9ybWF0KTsKICAgICAgICB9CiAgICB9CgogICAgLyogTm8gV2lkdGggb3Igbm8gSGVpZ2h0PyBVc2UgdGhlIGN1cnJlbnQgd2luZG93IHNpemUgb3IKICAgICAqIHRoZSBvcmlnaW5hbCBzY3JlZW4gc2l6ZQogICAgICovCiAgICBpZighKGRlc2MyLmR3RmxhZ3MgJiBERFNEX1dJRFRIKSB8fAogICAgICAgIShkZXNjMi5kd0ZsYWdzICYgRERTRF9IRUlHSFQpICkKICAgIHsKICAgICAgICBIV05EIHdpbmRvdzsKCiAgICAgICAgLyogRmFsbGJhY2s6IEZyb20gV2luZUQzRCAvIG9yaWdpbmFsIG1vZGUgKi8KICAgICAgICBkZXNjMi5kd0ZsYWdzIHw9IEREU0RfV0lEVEggfCBERFNEX0hFSUdIVDsKICAgICAgICBkZXNjMi5kd1dpZHRoID0gTW9kZS5XaWR0aDsKICAgICAgICBkZXNjMi5kd0hlaWdodCA9IE1vZGUuSGVpZ2h0OwoKICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldEhXTkQoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJndpbmRvdyk7CiAgICAgICAgaWYoIChociA9PSBEM0RfT0spICYmICh3aW5kb3cgIT0gMCkgKQogICAgICAgIHsKICAgICAgICAgICAgUkVDVCByZWN0OwogICAgICAgICAgICBpZihHZXRXaW5kb3dSZWN0KHdpbmRvdywgJnJlY3QpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogVGhpcyBpcyBhIGhhY2sgdW50aWwgSSBmaW5kIGEgYmV0dGVyIHNvbHV0aW9uICovCiAgICAgICAgICAgICAgICBpZiggKHJlY3QucmlnaHQgLSByZWN0LmxlZnQpIDw9IDEgfHwKICAgICAgICAgICAgICAgICAgICAocmVjdC5ib3R0b20gLSByZWN0LnRvcCkgPD0gMSApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRklYTUUoIldhbnRlZCB0byBnZXQgc3VyZmFjZSBkaW1lbnNpb25zIGZyb20gd2luZG93ICVwLCBidXQgaXQgaGFzIG9ubHkgXAogICAgICAgICAgICAgICAgICAgICAgICAgICBhIHNpemUgb2YgJWR4JWQuIFVzaW5nIGZ1bGwgc2NyZWVuIGRpbWVuc2lvbnNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdywgcmVjdC5yaWdodCAtIHJlY3QubGVmdCwgcmVjdC5ib3R0b20gLSByZWN0LnRvcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogTm90IHN1cmUgaWYgdGhpcyBpcyBjb3JyZWN0ICovCiAgICAgICAgICAgICAgICAgICAgZGVzYzIuZHdXaWR0aCA9IHJlY3QucmlnaHQgLSByZWN0LmxlZnQ7CiAgICAgICAgICAgICAgICAgICAgZGVzYzIuZHdIZWlnaHQgPSByZWN0LmJvdHRvbSAtIHJlY3QudG9wOwogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJVc2luZyB3aW5kb3cgJXAncyBkaW1lbnNpb25zOiAlZHglZFxuIiwgd2luZG93LCBkZXNjMi5kd1dpZHRoLCBkZXNjMi5kd0hlaWdodCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyogTWlwbWFwIGNvdW50IGZpeGVzICovCiAgICBpZihkZXNjMi5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfTUlQTUFQKQogICAgewogICAgICAgIGlmKGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19DT01QTEVYKQogICAgICAgIHsKICAgICAgICAgICAgaWYoZGVzYzIuZHdGbGFncyAmIEREU0RfTUlQTUFQQ09VTlQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIE1pcG1hcCBjb3VudCBpcyBnaXZlbiwgbm90aGluZyB0byBkbyAqLwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogVW5kb2N1bWVudGVkIGZlYXR1cmU6IENyZWF0ZSBzdWJsZXZlbHMgdW50aWwKICAgICAgICAgICAgICAgICAqIGVpdGhlciB0aGUgd2lkdGggb3IgdGhlIGhlaWdodCBpcyAxCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIERXT1JEIG1pbiA9IGRlc2MyLmR3V2lkdGggPCBkZXNjMi5kd0hlaWdodCA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjMi5kd1dpZHRoIDogZGVzYzIuZHdIZWlnaHQ7CiAgICAgICAgICAgICAgICBkZXNjMi51Mi5kd01pcE1hcENvdW50ID0gMDsKICAgICAgICAgICAgICAgIHdoaWxlKCBtaW4gKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRlc2MyLnUyLmR3TWlwTWFwQ291bnQgKz0gMTsKICAgICAgICAgICAgICAgICAgICBtaW4gPj49IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLyogTm90LWNvbXBsZXggbWlwbWFwIC0+IE1pcG1hcGNvdW50ID0gMSAqLwogICAgICAgICAgICBkZXNjMi51Mi5kd01pcE1hcENvdW50ID0gMTsKICAgICAgICB9CiAgICAgICAgZXh0cmFfc3VyZmFjZXMgPSBkZXNjMi51Mi5kd01pcE1hcENvdW50IC0gMTsKCiAgICAgICAgLyogVGhlcmUncyBhIG1pcG1hcCBjb3VudCBpbiB0aGUgY3JlYXRlZCBzdXJmYWNlIGluIGFueSBjYXNlICovCiAgICAgICAgZGVzYzIuZHdGbGFncyB8PSBERFNEX01JUE1BUENPVU5UOwogICAgfQogICAgLyogSWYgbm8gbWlwbWFwIGlzIGdpdmVuLCB0aGUgdGV4dHVyZSBoYXMgb25seSBvbmUgbGV2ZWwgKi8KCiAgICAvKiBUaGUgZmlyc3Qgc3VyZmFjZSBpcyBhIGZyb250IGJ1ZmZlciwgdGhlIGJhY2sgYnVmZmVyIGlzIGNyZWF0ZWQgYWZ0ZXJ3YXJkcyAqLwogICAgaWYoIChkZXNjMi5kd0ZsYWdzICYgRERTRF9DQVBTKSAmJiAoZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1BSSU1BUllTVVJGQUNFKSApCiAgICB7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU19GUk9OVEJVRkZFUjsKICAgIH0KCiAgICAvKiBDcmVhdGUgdGhlIGZpcnN0IHN1cmZhY2UgKi8KICAgIGhyID0gSURpcmVjdERyYXdJbXBsX0NyZWF0ZU5ld1N1cmZhY2UoVGhpcywgJmRlc2MyLCAmb2JqZWN0LCAwKTsKICAgIGlmKCBociAhPSBERF9PSykKICAgIHsKICAgICAgICBFUlIoIklEaXJlY3REcmF3SW1wbF9DcmVhdGVOZXdTdXJmYWNlIGZhaWxlZCB3aXRoICUwOHhcbiIsIGhyKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgKlN1cmYgPSBJQ09NX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3REcmF3U3VyZmFjZTcpOwoKICAgIC8qIENyZWF0ZSBBZGRpdGlvbmFsIHN1cmZhY2VzIGlmIG5lY2Vzc2FyeQogICAgICogVGhpcyBhcHBsaWVzIHRvIFByaW1hcnkgc3VyZmFjZXMgd2hpY2ggaGF2ZSBhIGJhY2sgYnVmZmVyIGNvdW50CiAgICAgKiBzZXQsIGJ1dCBub3QgdG8gbWlwbWFwIHRleHR1cmVzLiBJbiBjYXNlIG9mIE1pcG1hcCB0ZXh0dXJlcywKICAgICAqIHdpbmVEM0QgdGFrZXMgY2FyZSBvZiB0aGUgY3JlYXRpb24gb2YgYWRkaXRpb25hbCBzdXJmYWNlcwogICAgICovCiAgICBpZihERFNELT5kd0ZsYWdzICYgRERTRF9CQUNLQlVGRkVSQ09VTlQpCiAgICB7CiAgICAgICAgZXh0cmFfc3VyZmFjZXMgPSBERFNELT5kd0JhY2tCdWZmZXJDb3VudDsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwcyAmPSB+RERTQ0FQU19GUk9OVEJVRkZFUjsgLyogSXQncyBub3QgYSBmcm9udCBidWZmZXIgKi8KICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwcyB8PSBERFNDQVBTX0JBQ0tCVUZGRVI7CiAgICB9CiAgICAvKiBTZXQgdGhlIEREU0NBUFMyX01JUE1BUFNVQkxFVkVMIGZsYWcgb24gbWlwbWFwIHN1YmxldmVscyBhY2NvcmRpbmcgdG8gdGhlIG1zZG4gKi8KICAgIGlmKEREU0QtPmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19NSVBNQVApCiAgICB7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyIHw9IEREU0NBUFMyX01JUE1BUFNVQkxFVkVMOwogICAgfQoKICAgIGZvcihpID0gMDsgaSA8IGV4dHJhX3N1cmZhY2VzOyBpKyspCiAgICB7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqb2JqZWN0MiA9IE5VTEw7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqaXRlcmF0b3I7CgogICAgICAgIC8qIGluY3JlYXNlIHRoZSBtaXBtYXAgbGV2ZWwsIGJ1dCBvbmx5IGlmIGEgbWlwbWFwIGlzIGNyZWF0ZWQKICAgICAgICAgKiBJbiB0aGlzIGNhc2UsIGFsc28gaGFsdmUgdGhlIHNpemUKICAgICAgICAgKi8KICAgICAgICBpZihERFNELT5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfTUlQTUFQKQogICAgICAgIHsKICAgICAgICAgICAgbGV2ZWwrKzsKICAgICAgICAgICAgaWYoZGVzYzIuZHdXaWR0aCA+IDEpIGRlc2MyLmR3V2lkdGggLz0gMjsKICAgICAgICAgICAgaWYoZGVzYzIuZHdIZWlnaHQgPiAxKSBkZXNjMi5kd0hlaWdodCAvPSAyOwogICAgICAgIH0KCiAgICAgICAgaHIgPSBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZShUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRlc2MyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm9iamVjdDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbCk7CiAgICAgICAgaWYoaHIgIT0gRERfT0spCiAgICAgICAgewogICAgICAgICAgICAvKiBUaGlzIGRlc3Ryb3lzIGFuZCBwb3NzaWJseSBjcmVhdGVkIHN1cmZhY2VzIHRvbyAqLwogICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VfUmVsZWFzZSggSUNPTV9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0RHJhd1N1cmZhY2U3KSApOwogICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgfQoKICAgICAgICAvKiBBZGQgdGhlIG5ldyBzdXJmYWNlIHRvIHRoZSBjb21wbGV4IGF0dGFjaG1lbnQgbGlzdCAqLwogICAgICAgIG9iamVjdDItPmZpcnN0X2NvbXBsZXggPSBvYmplY3Q7CiAgICAgICAgb2JqZWN0Mi0+bmV4dF9jb21wbGV4ID0gTlVMTDsKICAgICAgICBpdGVyYXRvciA9IG9iamVjdDsKICAgICAgICB3aGlsZShpdGVyYXRvci0+bmV4dF9jb21wbGV4KSBpdGVyYXRvciA9IGl0ZXJhdG9yLT5uZXh0X2NvbXBsZXg7CiAgICAgICAgaXRlcmF0b3ItPm5leHRfY29tcGxleCA9IG9iamVjdDI7CgogICAgICAgIC8qIFJlbW92ZSB0aGUgKHBvc3NpYmxlKSBiYWNrIGJ1ZmZlciBjYXAgZnJvbSB0aGUgbmV3IHN1cmZhY2UgZGVzY3JpcHRpb24sCiAgICAgICAgICogYmVjYXVzZSBvbmx5IG9uZSBzdXJmYWNlIGluIHRoZSBmbGlwcGluZyBjaGFpbiBpcyBhIGJhY2sgYnVmZmVyLCBvbmUKICAgICAgICAgKiBpcyBhIGZyb250IGJ1ZmZlciwgdGhlIG90aGVycyBhcmUganVzdCBwcmltYXJ5IHN1cmZhY2VzLgogICAgICAgICAqLwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzICY9IH5ERFNDQVBTX0JBQ0tCVUZGRVI7CiAgICB9CgogICAgLyogQWRkcmVmIHRoZSBkZHJhdyBpbnRlcmZhY2UgdG8ga2VlcCBhbiByZWZlcmVuY2UgZm9yIGVhY2ggc3VyZmFjZSAqLwogICAgSURpcmVjdERyYXc3X0FkZFJlZihpZmFjZSk7CiAgICBvYmplY3QtPmlmYWNlVG9SZWxlYXNlID0gKElVbmtub3duICopIGlmYWNlOwoKICAgIC8qIElmIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBPcGVuR0wgYW5kIHRoZXJlJ3Mgbm8gZDNkZGV2aWNlLCBhdHRhY2ggYSBkM2RkZXZpY2UKICAgICAqIEJ1dCBhdHRhY2ggdGhlIGQzZGRldmljZSBvbmx5IGlmIHRoZSBjdXJyZW50bHkgY3JlYXRlZCBzdXJmYWNlIHdhcwogICAgICogYSBwcmltYXJ5IHN1cmZhY2UgKDJEIGFwcCBpbiAzRCBtb2RlKSBvciBhIDNEREVWSUNFIHN1cmZhY2UgKDNEIGFwcCkKICAgICAqIFRoZSBvbmx5IGNhc2UgSSBjYW4gdGhpbmsgb2Ygd2hlcmUgdGhpcyBkb2Vzbid0IGFwcGx5IGlzIHdoZW4gYQogICAgICogMkQgYXBwIHdhcyBjb25maWd1cmVkIGJ5IHRoZSB1c2VyIHRvIHJ1biB3aXRoIE9wZW5HTCBhbmQgaXQgZGlkbid0IGNyZWF0ZQogICAgICogdGhlIHJlbmRlciB0YXJnZXQgYXMgZmlyc3Qgc3VyZmFjZS4gSW4gdGhpcyBjYXNlIHRoZSByZW5kZXIgdGFyZ2V0IGNyZWF0aW9uCiAgICAgKiB3aWxsIGNhdXNlIHRoZSAzRCBpbml0LgogICAgICovCiAgICBpZiggKFRoaXMtPkltcGxUeXBlID09IFNVUkZBQ0VfT1BFTkdMKSAmJiAhKFRoaXMtPmQzZF9pbml0aWFsaXplZCkgJiYKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwcyAmIChERFNDQVBTX1BSSU1BUllTVVJGQUNFIHwgRERTQ0FQU18zRERFVklDRSkgKQogICAgewogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnRhcmdldCA9IG9iamVjdCwgKnN1cmZhY2U7CiAgICAgICAgc3RydWN0IGxpc3QgKmVudHJ5OwoKICAgICAgICAvKiBTZWFyY2ggZm9yIHRoZSBwcmltYXJ5IHRvIHVzZSBhcyByZW5kZXIgdGFyZ2V0ICovCiAgICAgICAgTElTVF9GT1JfRUFDSChlbnRyeSwgJlRoaXMtPnN1cmZhY2VfbGlzdCkKICAgICAgICB7CiAgICAgICAgICAgIHN1cmZhY2UgPSBMSVNUX0VOVFJZKGVudHJ5LCBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBzdXJmYWNlX2xpc3RfZW50cnkpOwogICAgICAgICAgICBpZihzdXJmYWNlLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1BSSU1BUllTVVJGQUNFKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBmb3VuZCAqLwogICAgICAgICAgICAgICAgdGFyZ2V0ID0gc3VyZmFjZTsKICAgICAgICAgICAgICAgIFRSQUNFKCJVc2luZyBwcmltYXJ5ICVwIGFzIHJlbmRlciB0YXJnZXRcbiIsIHRhcmdldCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgVFJBQ0UoIiglcCkgQXR0YWNoaW5nIGEgRDNERGV2aWNlLCByZW5kZXJ0YXJnZXQgPSAlcFxuIiwgVGhpcywgdGFyZ2V0KTsKICAgICAgICBociA9IElEaXJlY3REcmF3SW1wbF9BdHRhY2hEM0REZXZpY2UoVGhpcywgdGFyZ2V0LT5maXJzdF9jb21wbGV4KTsKICAgICAgICBpZihociAhPSBEM0RfT0spCiAgICAgICAgewogICAgICAgICAgICBFUlIoIklEaXJlY3REcmF3SW1wbF9BdHRhY2hEM0REZXZpY2UgZmFpbGVkLCBociA9ICV4XG4iLCBocik7CiAgICAgICAgfQogICAgfQoKICAgIC8qIENyZWF0ZSBhIFdpbmVEM0RUZXh0dXJlIGlmIGEgdGV4dHVyZSB3YXMgcmVxdWVzdGVkICovCiAgICBpZihERFNELT5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfVEVYVFVSRSkKICAgIHsKICAgICAgICBVSU5UIGxldmVsczsKICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdDsKICAgICAgICBXSU5FRDNEUE9PTCBQb29sID0gV0lORUQzRFBPT0xfREVGQVVMVDsKCiAgICAgICAgVGhpcy0+dGV4X3Jvb3QgPSBvYmplY3Q7CgogICAgICAgIGlmKGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19NSVBNQVApCiAgICAgICAgewogICAgICAgICAgICAvKiBhIG1pcG1hcCBpcyBjcmVhdGVkLCBjcmVhdGUgZW5vdWdoIGxldmVscyAqLwogICAgICAgICAgICBsZXZlbHMgPSBkZXNjMi51Mi5kd01pcE1hcENvdW50OwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBObyBtaXBtYXAgaXMgY3JlYXRlZCwgY3JlYXRlIG9uZSBsZXZlbCAqLwogICAgICAgICAgICBsZXZlbHMgPSAxOwogICAgICAgIH0KCiAgICAgICAgLyogRERTQ0FQU19TWVNURU1NRU1PUlkgdGV4dHVyZXMgYXJlIGluIFdJTkVEM0RQT09MX1NZU1RFTU1FTSAqLwogICAgICAgIGlmKEREU0QtPmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19TWVNURU1NRU1PUlkpCiAgICAgICAgewogICAgICAgICAgICBQb29sID0gV0lORUQzRFBPT0xfU1lTVEVNTUVNOwogICAgICAgIH0KICAgICAgICAvKiBTaG91bGQgSSBmb3J3YXJkIHRoZSBNQU5FR0VEIGNhcCB0byB0aGUgbWFuYWdlZCBwb29sID8gKi8KCiAgICAgICAgLyogR2V0IHRoZSBmb3JtYXQuIEl0J3Mgc2V0IGFscmVhZHkgYnkgQ3JlYXRlTmV3U3VyZmFjZSAqLwogICAgICAgIEZvcm1hdCA9IFBpeGVsRm9ybWF0X0REMldpbmVEM0QoJm9iamVjdC0+c3VyZmFjZV9kZXNjLnU0LmRkcGZQaXhlbEZvcm1hdCk7CgogICAgICAgIC8qIFRoZSBzdXJmYWNlcyBhcmUgYWxyZWFkeSBjcmVhdGVkLCB0aGUgY2FsbGJhY2sgb25seQogICAgICAgICAqIHBhc3NlcyB0aGUgSVdpbmVEM0RTdXJmYWNlIHRvIFdpbmVEM0QKICAgICAgICAgKi8KICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZVRleHR1cmUoIFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNELT5kd1dpZHRoLCBERFNELT5kd0hlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscywgLyogTWlwTWFwQ291bnQgPSBMZXZlbHMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8qIHVzYWdlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm9iamVjdC0+d2luZUQzRFRleHR1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiBTaGFyZWRIYW5kbGUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biAqKSBJQ09NX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3REcmF3U3VyZmFjZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEN0NCX0NyZWF0ZVN1cmZhY2UgKTsKICAgICAgICBUaGlzLT50ZXhfcm9vdCA9IE5VTEw7CiAgICB9CgogICAgcmV0dXJuIGhyOwp9CgojZGVmaW5lIERERU5VTVNVUkZBQ0VTX1NFQVJDSFRZUEUgKERERU5VTVNVUkZBQ0VTX0NBTkJFQ1JFQVRFRHxEREVOVU1TVVJGQUNFU19ET0VTRVhJU1QpCiNkZWZpbmUgRERFTlVNU1VSRkFDRVNfTUFUQ0hUWVBFIChEREVOVU1TVVJGQUNFU19BTEx8RERFTlVNU1VSRkFDRVNfTUFUQ0h8RERFTlVNU1VSRkFDRVNfTk9NQVRDSCkKCnN0YXRpYyBCT09MCk1haW5fRGlyZWN0RHJhd19ERFBJWEVMRk9STUFUX01hdGNoKGNvbnN0IEREUElYRUxGT1JNQVQgKnJlcXVlc3RlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRERQSVhFTEZPUk1BVCAqcHJvdmlkZWQpCnsKICAgIC8qIFNvbWUgZmxhZ3MgbXVzdCBiZSBwcmVzZW50IGluIGJvdGggb3IgbmVpdGhlciBmb3IgYSBtYXRjaC4gKi8KICAgIHN0YXRpYyBjb25zdCBEV09SRCBtdXN0X21hdGNoID0gRERQRl9QQUxFVFRFSU5ERVhFRDEgfCBERFBGX1BBTEVUVEVJTkRFWEVEMgogICAgICAgIHwgRERQRl9QQUxFVFRFSU5ERVhFRDQgfCBERFBGX1BBTEVUVEVJTkRFWEVEOCB8IEREUEZfRk9VUkNDCiAgICAgICAgfCBERFBGX1pCVUZGRVIgfCBERFBGX1NURU5DSUxCVUZGRVI7CgogICAgaWYgKChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiBwcm92aWRlZC0+ZHdGbGFncykgIT0gcmVxdWVzdGVkLT5kd0ZsYWdzKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAoKHJlcXVlc3RlZC0+ZHdGbGFncyAmIG11c3RfbWF0Y2gpICE9IChwcm92aWRlZC0+ZHdGbGFncyAmIG11c3RfbWF0Y2gpKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgRERQRl9GT1VSQ0MpCiAgICAgICAgaWYgKHJlcXVlc3RlZC0+ZHdGb3VyQ0MgIT0gcHJvdmlkZWQtPmR3Rm91ckNDKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIChERFBGX1JHQnxERFBGX1lVVnxERFBGX1pCVUZGRVJ8RERQRl9BTFBIQQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8RERQRl9MVU1JTkFOQ0V8RERQRl9CVU1QRFVEVikpCiAgICAgICAgaWYgKHJlcXVlc3RlZC0+dTEuZHdSR0JCaXRDb3VudCAhPSBwcm92aWRlZC0+dTEuZHdSR0JCaXRDb3VudCkKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiAoRERQRl9SR0J8RERQRl9ZVVZ8RERQRl9TVEVOQ0lMQlVGRkVSCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxERFBGX0xVTUlOQU5DRXxERFBGX0JVTVBEVURWKSkKICAgICAgICBpZiAocmVxdWVzdGVkLT51Mi5kd1JCaXRNYXNrICE9IHByb3ZpZGVkLT51Mi5kd1JCaXRNYXNrKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIChERFBGX1JHQnxERFBGX1lVVnxERFBGX1pCVUZGRVJ8RERQRl9CVU1QRFVEVikpCiAgICAgICAgaWYgKHJlcXVlc3RlZC0+dTMuZHdHQml0TWFzayAhPSBwcm92aWRlZC0+dTMuZHdHQml0TWFzaykKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIC8qIEkgY291bGQgYmUgd3JvbmcgYWJvdXQgdGhlIGJ1bXBtYXBwaW5nLiBNU0ROIGRvY3MgYXJlIHZhZ3VlLiAqLwogICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIChERFBGX1JHQnxERFBGX1lVVnxERFBGX1NURU5DSUxCVUZGRVIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfEREUEZfQlVNUERVRFYpKQogICAgICAgIGlmIChyZXF1ZXN0ZWQtPnU0LmR3QkJpdE1hc2sgIT0gcHJvdmlkZWQtPnU0LmR3QkJpdE1hc2spCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgKEREUEZfQUxQSEFQSVhFTFN8RERQRl9aUElYRUxTKSkKICAgICAgICBpZiAocmVxdWVzdGVkLT51NS5kd1JHQkFscGhhQml0TWFzayAhPSBwcm92aWRlZC0+dTUuZHdSR0JBbHBoYUJpdE1hc2spCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wKSURpcmVjdERyYXdJbXBsX0REU0RfTWF0Y2goY29uc3QgRERTVVJGQUNFREVTQzIqIHJlcXVlc3RlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRERTVVJGQUNFREVTQzIqIHByb3ZpZGVkKQp7CiAgICBzdHJ1Y3QgY29tcGFyZV9pbmZvCiAgICB7CiAgICAgICAgRFdPUkQgZmxhZzsKICAgICAgICBwdHJkaWZmX3Qgb2Zmc2V0OwogICAgICAgIHNpemVfdCBzaXplOwogICAgfTsKCiNkZWZpbmUgQ01QKEZMQUcsIEZJRUxEKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIHsgRERTRF8jI0ZMQUcsIG9mZnNldG9mKEREU1VSRkFDRURFU0MyLCBGSUVMRCksIFwKICAgICAgICAgIHNpemVvZigoKEREU1VSRkFDRURFU0MyICopKE5VTEwpKS0+RklFTEQpIH0KCiAgICBzdGF0aWMgY29uc3Qgc3RydWN0IGNvbXBhcmVfaW5mbyBjb21wYXJlW10gPQogICAgewogICAgICAgIENNUChBTFBIQUJJVERFUFRILCBkd0FscGhhQml0RGVwdGgpLAogICAgICAgIENNUChCQUNLQlVGRkVSQ09VTlQsIGR3QmFja0J1ZmZlckNvdW50KSwKICAgICAgICBDTVAoQ0FQUywgZGRzQ2FwcyksCiAgICAgICAgQ01QKENLREVTVEJMVCwgZGRja0NLRGVzdEJsdCksCiAgICAgICAgQ01QKENLREVTVE9WRVJMQVksIHUzIC8qIGRkY2tDS0Rlc3RPdmVybGF5ICovKSwKICAgICAgICBDTVAoQ0tTUkNCTFQsIGRkY2tDS1NyY0JsdCksCiAgICAgICAgQ01QKENLU1JDT1ZFUkxBWSwgZGRja0NLU3JjT3ZlcmxheSksCiAgICAgICAgQ01QKEhFSUdIVCwgZHdIZWlnaHQpLAogICAgICAgIENNUChMSU5FQVJTSVpFLCB1MSAvKiBkd0xpbmVhclNpemUgKi8pLAogICAgICAgIENNUChMUFNVUkZBQ0UsIGxwU3VyZmFjZSksCiAgICAgICAgQ01QKE1JUE1BUENPVU5ULCB1MiAvKiBkd01pcE1hcENvdW50ICovKSwKICAgICAgICBDTVAoUElUQ0gsIHUxIC8qIGxQaXRjaCAqLyksCiAgICAgICAgLyogUElYRUxGT1JNQVQ6IG1hbnVhbCAqLwogICAgICAgIENNUChSRUZSRVNIUkFURSwgdTIgLyogZHdSZWZyZXNoUmF0ZSAqLyksCiAgICAgICAgQ01QKFRFWFRVUkVTVEFHRSwgZHdUZXh0dXJlU3RhZ2UpLAogICAgICAgIENNUChXSURUSCwgZHdXaWR0aCksCiAgICAgICAgLyogWkJVRkZFUkJJVERFUFRIOiAib2Jzb2xldGUiICovCiAgICB9OwoKI3VuZGVmIENNUAoKICAgIHVuc2lnbmVkIGludCBpOwoKICAgIGlmICgocmVxdWVzdGVkLT5kd0ZsYWdzICYgcHJvdmlkZWQtPmR3RmxhZ3MpICE9IHJlcXVlc3RlZC0+ZHdGbGFncykKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgZm9yIChpPTA7IGkgPCBzaXplb2YoY29tcGFyZSkvc2l6ZW9mKGNvbXBhcmVbMF0pOyBpKyspCiAgICB7CiAgICAgICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIGNvbXBhcmVbaV0uZmxhZwogICAgICAgICAgICAmJiBtZW1jbXAoKGNvbnN0IGNoYXIgKilwcm92aWRlZCArIGNvbXBhcmVbaV0ub2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgKGNvbnN0IGNoYXIgKilyZXF1ZXN0ZWQgKyBjb21wYXJlW2ldLm9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgIGNvbXBhcmVbaV0uc2l6ZSkgIT0gMCkKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiBERFNEX1BJWEVMRk9STUFUKQogICAgewogICAgICAgIGlmICghTWFpbl9EaXJlY3REcmF3X0REUElYRUxGT1JNQVRfTWF0Y2goJnJlcXVlc3RlZC0+dTQuZGRwZlBpeGVsRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcHJvdmlkZWQtPnU0LmRkcGZQaXhlbEZvcm1hdCkpCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKfQoKI3VuZGVmIERERU5VTVNVUkZBQ0VTX1NFQVJDSFRZUEUKI3VuZGVmIERERU5VTVNVUkZBQ0VTX01BVENIVFlQRQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6RW51bVN1cmZhY2VzCiAqCiAqIExvb3BzIHRocm91Z2ggYWxsIHN1cmZhY2VzIGF0dGFjaGVkIHRvIHRoaXMgZGV2aWNlIGFuZCBjYWxscyB0aGUKICogYXBwbGljYXRpb24gY2FsbGJhY2suIFRoaXMgY2FuJ3QgYmUgcmVsYXllZCB0byBXaW5lRDNERGV2aWNlLAogKiBiZWNhdXNlIHNvbWUgV2luZUQzRFN1cmZhY2VzJyBwYXJlbnRzIGFyZSBJUGFyZW50IG9iamVjdHMKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IFNvbWUgZmlsdGVyaW5nIGZsYWdzLiBTZWUgSURpcmVjdERyYXdJbXBsX0VudW1TdXJmYWNlc0NhbGxiYWNrCiAqICBERFNEOiBEZXNjcmlwdGlvbiB0byBmaWx0ZXIgZm9yCiAqICBDb250ZXh0OiBBcHBsaWNhdGlvbi1wcm92aWRlZCBwb2ludGVyLCBpdCdzIHBhc3NlZCB1bm1vZGlmaWVkIHRvIHRoZQogKiAgICAgICAgICAgQ2FsbGJhY2sgZnVuY3Rpb24KICogIENhbGxiYWNrOiBBZGRyZXNzIHRvIGNhbGwgZm9yIGVhY2ggc3VyZmFjZQogKgogKiBSZXR1cm5zOgogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiB0aGUgY2FsbGJhY2sgaXMgTlVMTAogKiAgRERfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfRW51bVN1cmZhY2VzKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKkREU0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERERU5VTVNVUkZBQ0VTQ0FMTEJBQ0s3IENhbGxiYWNrKQp7CiAgICAvKiBUaGUgc3VyZmFjZSBlbnVtZXJhdGlvbiBpcyBoYW5kbGVkIGJ5IFdpbmVERHJhdywKICAgICAqIGJlY2F1c2UgaXQga2VlcHMgdHJhY2sgb2YgYWxsIHN1cmZhY2VzIGF0dGFjaGVkIHRvCiAgICAgKiBpdC4gVGhlIGZpbHRlcmluZyBpcyBkb25lIGJ5IG91ciBjYWxsYmFjayBmdW5jdGlvbiwKICAgICAqIGJlY2F1c2UgV2luZUREcmF3IGRvZXNuJ3QgaGFuZGxlIGRkcmF3LWxpa2Ugc3VyZmFjZQogICAgICogY2FwcyBzdHJ1Y3R1cmVzCiAgICAgKi8KICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmOwogICAgQk9PTCBhbGwsIG5vbWF0Y2g7CiAgICBERFNVUkZBQ0VERVNDMiBkZXNjOwogICAgc3RydWN0IGxpc3QgKmVudHJ5LCAqZW50cnkyOwoKICAgIGFsbCA9IEZsYWdzICYgRERFTlVNU1VSRkFDRVNfQUxMOwogICAgbm9tYXRjaCA9IEZsYWdzICYgRERFTlVNU1VSRkFDRVNfTk9NQVRDSDsKCiAgICBUUkFDRSgiKCVwKS0+KCV4LCVwLCVwLCVwKVxuIiwgVGhpcywgRmxhZ3MsIEREU0QsIENvbnRleHQsIENhbGxiYWNrKTsKCiAgICBpZighQ2FsbGJhY2spCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgLyogVXNlIHRoZSBfU0FGRSBlbnVtZXJhdGlvbiwgdGhlIGFwcCBtYXkgZGVzdHJveSBlbnVtZXJhdGVkIHN1cmZhY2VzICovCiAgICBMSVNUX0ZPUl9FQUNIX1NBRkUoZW50cnksIGVudHJ5MiwgJlRoaXMtPnN1cmZhY2VfbGlzdCkKICAgIHsKICAgICAgICBzdXJmID0gTElTVF9FTlRSWShlbnRyeSwgSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgc3VyZmFjZV9saXN0X2VudHJ5KTsKICAgICAgICBpZiAoYWxsIHx8IChub21hdGNoICE9IElEaXJlY3REcmF3SW1wbF9ERFNEX01hdGNoKEREU0QsICZzdXJmLT5zdXJmYWNlX2Rlc2MpKSkKICAgICAgICB7CiAgICAgICAgICAgIGRlc2MgPSBzdXJmLT5zdXJmYWNlX2Rlc2M7CiAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfQWRkUmVmKElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKICAgICAgICAgICAgaWYoQ2FsbGJhY2soIElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpLCAmZGVzYywgQ29udGV4dCkgIT0gRERFTlVNUkVUX09LKQogICAgICAgICAgICAgICAgcmV0dXJuIEREX09LOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEQzRDdDQl9DcmVhdGVSZW5kZXJUYXJnZXQKICoKICogQ2FsbGJhY2sgY2FsbGVkIGJ5IFdpbmVEM0QgdG8gY3JlYXRlIFN1cmZhY2VzIGZvciByZW5kZXIgdGFyZ2V0IHVzYWdlCiAqIFRoaXMgZnVuY3Rpb24gdGFrZXMgdGhlIEQzRCB0YXJnZXQgZnJvbSB0aGUgSURpcmVjdERyYXdJbXBsIHN0cnVjdHVyZSwKICogYW5kIHJldHVybnMgdGhlIFdpbmVEM0RTdXJmYWNlLiBUbyBhdm9pZCBkb3VibGUgdXNhZ2UsIHRoZSBzdXJmYWNlCiAqIGlzIG1hcmtlZCBhcyByZW5kZXIgdGFyZ2V0IGFmdGVyd2FyZHMKICoKICogUGFyYW1zCiAqICBkZXZpY2U6IFRoZSBXaW5lRDNERGV2aWNlJ3MgcGFyZW50CiAqICBXaWR0aCwgSGVpZ2h0LCBGb3JtYXQ6IERpbWVuc2lvbnMgYW5kIHBpeGVsZm9ybWF0IG9mIHRoZSByZW5kZXIgdGFyZ2V0CiAqICAgICAgICAgICAgICAgICAgICAgICAgIElnbm9yZWQsIGJlY2F1c2UgdGhlIHN1cmZhY2UgYWxyZWFkeSBleGlzdHMKICogIE11bHRpU2FtcGxlLCBNdWx0aXNhbXBsZVF1YWxpdHksIExvY2thYmxlOiBJZ25vcmVkIGZvciB0aGUgc2FtZSByZWFzb24KICogIExvY2thYmxlOiBpZ25vcmVkCiAqICBwcFN1cmZhY2U6IEFkZHJlc3MgdG8gcGFzcyB0aGUgc3VyZmFjZSBwb2ludGVyIGJhY2sgYXQKICogIHBTaGFyZWRIYW5kbGU6IElnbm9yZWQKICoKICogUmV0dXJuczoKICogIEFsd2F5cyByZXR1cm5zIEQzRF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpEM0Q3Q0JfQ3JlYXRlUmVuZGVyVGFyZ2V0KElVbmtub3duICpkZXZpY2UsIFVJTlQgV2lkdGgsIFVJTlQgSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RNVUxUSVNBTVBMRV9UWVBFIE11bHRpU2FtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIE11bHRpc2FtcGxlUXVhbGl0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIExvY2thYmxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSoqIHBwU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUqIHBTaGFyZWRIYW5kbGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBkZXZpY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqZDNkU3VyZmFjZSA9IChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICopIFRoaXMtPmQzZF90YXJnZXQtPmZpcnN0X2NvbXBsZXg7CiAgICBUUkFDRSgiKCVwKSBjYWxsIGJhY2tcbiIsIGRldmljZSk7CgogICAgLyogTG9vcCB0aHJvdWdoIHRoZSBjb21wbGV4IGNoYWluIGFuZCB0cnkgdG8gZmluZCB1bnVzZWQgcHJpbWFyeSBzdXJmYWNlcyAqLwogICAgd2hpbGUoZDNkU3VyZmFjZS0+aXNSZW5kZXJUYXJnZXQpCiAgICB7CiAgICAgICAgZDNkU3VyZmFjZSA9IGQzZFN1cmZhY2UtPm5leHRfY29tcGxleDsKICAgICAgICBpZighZDNkU3VyZmFjZSkgYnJlYWs7CiAgICB9CiAgICBpZighZDNkU3VyZmFjZSkKICAgIHsKICAgICAgICBkM2RTdXJmYWNlID0gVGhpcy0+ZDNkX3RhcmdldDsKICAgICAgICBFUlIoIiAoJXApIDogTm8gRGlyZWN0RHJhd1N1cmZhY2UgZm91bmQgdG8gY3JlYXRlIHRoZSBiYWNrIGJ1ZmZlci4gVXNpbmcgdGhlIGZyb250IGJ1ZmZlciBhcyBiYWNrIGJ1ZmZlci4gVW5jZXJ0YWluIGNvbnNlcXVlbmNlc1xuIiwgVGhpcyk7CiAgICB9CgogICAgLyogVE9ETzogUmV0dXJuIGZhaWx1cmUgaWYgdGhlIGRpbWVuc2lvbnMgZG8gbm90IG1hdGNoLCBidXQgdGhpcyBzaG91bGRuJ3QgaGFwcGVuICovCgogICAgKnBwU3VyZmFjZSA9IGQzZFN1cmZhY2UtPldpbmVEM0RTdXJmYWNlOwogICAgZDNkU3VyZmFjZS0+aXNSZW5kZXJUYXJnZXQgPSBUUlVFOwogICAgVFJBQ0UoIlJldHVybmluZyB3aW5lRDNEU3VyZmFjZSAlcCwgaXQgYmVsb25ncyB0byBzdXJmYWNlICVwXG4iLCAqcHBTdXJmYWNlLCBkM2RTdXJmYWNlKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpEM0Q3Q0JfQ3JlYXRlRGVwdGhTdGVuY2lsU3VyZmFjZShJVW5rbm93biAqZGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIEhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREZPUk1BVCBGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RNVUxUSVNBTVBMRV9UWVBFIE11bHRpU2FtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBNdWx0aXNhbXBsZVF1YWxpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgRGlzY2FyZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlKiogcHBTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUqIHBTaGFyZWRIYW5kbGUpCnsKICAgIC8qIENyZWF0ZSBhIERlcHRoIFN0ZW5jaWwgc3VyZmFjZSB0byBtYWtlIFdpbmVEM0QgaGFwcHkgKi8KICAgIEhSRVNVTFQgaHIgPSBEM0RfT0s7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgZGV2aWNlKTsKICAgIEREU1VSRkFDRURFU0MyIGRkc2Q7CgogICAgVFJBQ0UoIiglcCkgY2FsbCBiYWNrXG4iLCBkZXZpY2UpOwoKICAgICpwcFN1cmZhY2UgPSBOVUxMOwoKICAgIC8qIENyZWF0ZSBhIERpcmVjdERyYXcgc3VyZmFjZSAqLwogICAgbWVtc2V0KCZkZHNkLCAwLCBzaXplb2YoZGRzZCkpOwogICAgZGRzZC5kd1NpemUgPSBzaXplb2YoZGRzZCk7CiAgICBkZHNkLnU0LmRkcGZQaXhlbEZvcm1hdC5kd1NpemUgPSBzaXplb2YoRERQSVhFTEZPUk1BVCk7CiAgICBkZHNkLmR3RmxhZ3MgPSBERFNEX1BJWEVMRk9STUFUIHwgRERTRF9XSURUSCB8IEREU0RfSEVJR0hUIHwgRERTRF9DQVBTOwogICAgZGRzZC5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfT0ZGU0NSRUVOUExBSU47CiAgICBkZHNkLmR3SGVpZ2h0ID0gSGVpZ2h0OwogICAgZGRzZC5kd1dpZHRoID0gV2lkdGg7CiAgICBpZihGb3JtYXQgIT0gMCkKICAgIHsKICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJmRkc2QudTQuZGRwZlBpeGVsRm9ybWF0LCBGb3JtYXQpOwogICAgfQogICAgZWxzZQogICAgewogICAgICBkZHNkLmR3RmxhZ3MgXj0gRERTRF9QSVhFTEZPUk1BVDsKICAgIH0KCiAgICBUaGlzLT5kZXB0aHN0ZW5jaWwgPSBUUlVFOwogICAgaHIgPSBJRGlyZWN0RHJhdzdfQ3JlYXRlU3VyZmFjZSgoSURpcmVjdERyYXc3ICopIFRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkZHNkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSURpcmVjdERyYXdTdXJmYWNlNyAqKikgJlRoaXMtPkRlcHRoU3RlbmNpbEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICBUaGlzLT5kZXB0aHN0ZW5jaWwgPSBGQUxTRTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgRVJSKCIgKCVwKSBDcmVhdGluZyBhIERlcHRoU3RlbmNpbCBTdXJmYWNlIGZhaWxlZCwgcmVzdWx0ID0gJXhcbiIsIFRoaXMsIGhyKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CiAgICAqcHBTdXJmYWNlID0gVGhpcy0+RGVwdGhTdGVuY2lsQnVmZmVyLT5XaW5lRDNEU3VyZmFjZTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEM0Q3Q0JfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbgogKgogKiBDYWxsYmFjayBmdW5jdGlvbiBmb3IgV2luZUQzRCB3aGljaCBjcmVhdGVzIGEgbmV3IFdpbmVEM0RTd2FwY2hhaW4KICogaW50ZXJmYWNlLiBJdCBhbHNvIGNyZWF0ZXMgYW4gSVBhcmVudCBpbnRlcmZhY2UgdG8gc3RvcmUgdGhhdCBwb2ludGVyLAogKiBzbyB0aGUgV2luZUQzRFN3YXBjaGFpbiBoYXMgYSBwYXJlbnQgYW5kIGNhbiBiZSByZWxlYXNlZCB3aGVuIHRoZSBEM0QKICogZGV2aWNlIGlzIGRlc3Ryb3llZAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpEM0Q3Q0JfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbihJVW5rbm93biAqZGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiBwUHJlc2VudGF0aW9uUGFyYW1ldGVycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW4gKiogcHBTd2FwQ2hhaW4pCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBkZXZpY2UpOwogICAgSVBhcmVudEltcGwgKm9iamVjdCA9IE5VTEw7CiAgICBIUkVTVUxUIHJlcyA9IEQzRF9PSzsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwY2hhaW47CiAgICBUUkFDRSgiKCVwKSBjYWxsIGJhY2tcbiIsIGRldmljZSk7CgogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksICBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVBhcmVudEltcGwpKTsKICAgIGlmIChOVUxMID09IG9iamVjdCkKICAgIHsKICAgICAgICBGSVhNRSgiQWxsb2NhdGlvbiBvZiBtZW1vcnkgZmFpbGVkXG4iKTsKICAgICAgICAqcHBTd2FwQ2hhaW4gPSBOVUxMOwogICAgICAgIHJldHVybiBEREVSUl9PVVRPRlZJREVPTUVNT1JZOwogICAgfQoKICAgIElDT01fSU5JVF9JTlRFUkZBQ0Uob2JqZWN0LCBJUGFyZW50LCBJUGFyZW50X1Z0YmwpOwogICAgb2JqZWN0LT5yZWYgPSAxOwoKICAgIHJlcyA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3dhcGNoYWluLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElVbmtub3duKikgSUNPTV9JTlRFUkZBQ0Uob2JqZWN0LCBJUGFyZW50KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEN0NCX0NyZWF0ZVJlbmRlclRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEN0NCX0NyZWF0ZURlcHRoU3RlbmNpbFN1cmZhY2UpOwogICAgaWYgKHJlcyAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgRklYTUUoIiglcCkgY2FsbCB0byBJV2luZUQzRERldmljZV9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluIGZhaWxlZFxuIiwgVGhpcyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCAsIG9iamVjdCk7CiAgICAgICAgKnBwU3dhcENoYWluID0gTlVMTDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAqcHBTd2FwQ2hhaW4gPSBzd2FwY2hhaW47CiAgICAgICAgb2JqZWN0LT5jaGlsZCA9IChJVW5rbm93biAqKSBzd2FwY2hhaW47CiAgICB9CgogICAgcmV0dXJuIHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3SW1wbF9BdHRhY2hEM0REZXZpY2UKICoKICogSW5pdGlhbGl6ZXMgdGhlIEQzRCBjYXBhYmlsaXRpZXMgb2YgV2luZUQzRAogKgogKiBQYXJhbXM6CiAqICBwcmltYXJ5OiBUaGUgcHJpbWFyeSBzdXJmYWNlIGZvciBEM0QKICoKICogUmV0dXJucwogKiAgRERfT0sgb24gc3VjY2VzcywKICogIERERVJSXyogb3RoZXJ3aXNlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9BdHRhY2hEM0REZXZpY2UoSURpcmVjdERyYXdJbXBsICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnByaW1hcnkpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBVSU5UICAgICAgICAgICAgICAgICAgQmFja0J1ZmZlckNvdW50ID0gMDsKICAgIEhXTkQgICAgICAgICAgICAgICAgICB3aW5kb3c7CgogICAgV0lORUQzRFBSRVNFTlRfUEFSQU1FVEVSUyBsb2NhbFBhcmFtZXRlcnM7CiAgICBCT09MIGlzV2luZG93ZWQsIEVuYWJsZUF1dG9EZXB0aFN0ZW5jaWw7CiAgICBXSU5FRDNERk9STUFUIEF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQ7CiAgICBXSU5FRDNETVVMVElTQU1QTEVfVFlQRSBNdWx0aVNhbXBsZVR5cGU7CiAgICBXSU5FRDNEU1dBUEVGRkVDVCAgU3dhcEVmZmVjdDsKICAgIERXT1JEIEZsYWdzLCBNdWx0aVNhbXBsZVF1YWxpdHk7CiAgICBVSU5UIEZ1bGxTY3JlZW5fUmVmcmVzaFJhdGVJbkh6LCBQcmVzZW50YXRpb25JbnRlcnZhbDsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSBNb2RlOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBwcmltYXJ5KTsKCiAgICAvKiBHZXQgdGhlIHdpbmRvdyAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRIV05EKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJndpbmRvdyk7CiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgRVJSKCJJV2luZUQzRERldmljZTo6R2V0SFdORCBmYWlsZWRcbiIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBJZiB0aGVyZSdzIG5vIHdpbmRvdywgY3JlYXRlIGEgaGlkZGVuIHdpbmRvdy4gV2luZUQzRCBuZWVkcyBpdCAqLwogICAgaWYod2luZG93ID09IDApCiAgICB7CiAgICAgICAgd2luZG93ID0gQ3JlYXRlV2luZG93RXhBKDAsIFRoaXMtPmNsYXNzbmFtZSwgIkhpZGRlbiBEM0QgV2luZG93IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1NfRElTQUJMRUQsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwgR2V0TW9kdWxlSGFuZGxlQSgwKSwgTlVMTCk7CgogICAgICAgIFNob3dXaW5kb3cod2luZG93LCBTV19ISURFKTsgICAvKiBKdXN0IHRvIGJlIHN1cmUgKi8KICAgICAgICBXQVJOKCIoJXApIE5vIHdpbmRvdyBmb3IgdGhlIERpcmVjdDNERGV2aWNlLCBjcmVhdGVkIGEgaGlkZGVuIHdpbmRvdy4gSFdORD0lcFxuIiwgVGhpcywgd2luZG93KTsKICAgICAgICBUaGlzLT5kM2Rfd2luZG93ID0gd2luZG93OwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIFRSQUNFKCIoJXApIFVzaW5nIGV4aXN0aW5nIHdpbmRvdyAlcCBmb3IgRGlyZWN0M0QgcmVuZGVyaW5nXG4iLCBUaGlzLCB3aW5kb3cpOwogICAgfQoKICAgIC8qIHVzZSB0aGUgc3VyZmFjZSBkZXNjcmlwdGlvbiBmb3IgdGhlIGRldmljZSBwYXJhbWV0ZXJzLCBub3QgdGhlCiAgICAgKiBEZXZpY2Ugc2V0dGluZ3MuIFRoZSBhcHAgbWlnaHQgcmVuZGVyIHRvIGFuIG9mZnNjcmVlbiBzdXJmYWNlCiAgICAgKi8KICAgIE1vZGUuV2lkdGggPSBwcmltYXJ5LT5zdXJmYWNlX2Rlc2MuZHdXaWR0aDsKICAgIE1vZGUuSGVpZ2h0ID0gcHJpbWFyeS0+c3VyZmFjZV9kZXNjLmR3SGVpZ2h0OwogICAgTW9kZS5Gb3JtYXQgPSBQaXhlbEZvcm1hdF9ERDJXaW5lRDNEKCZwcmltYXJ5LT5zdXJmYWNlX2Rlc2MudTQuZGRwZlBpeGVsRm9ybWF0KTsKCiAgICBpZihwcmltYXJ5LT5zdXJmYWNlX2Rlc2MuZHdGbGFncyAmIEREU0RfQkFDS0JVRkZFUkNPVU5UKQogICAgewogICAgICAgIEJhY2tCdWZmZXJDb3VudCA9IHByaW1hcnktPnN1cmZhY2VfZGVzYy5kd0JhY2tCdWZmZXJDb3VudDsKICAgIH0KCiAgICAvKiBTdG9yZSB0aGUgZnV0dXJlIFJlbmRlciBUYXJnZXQgc3VyZmFjZSAqLwogICAgVGhpcy0+ZDNkX3RhcmdldCA9IHByaW1hcnk7CgogICAgaXNXaW5kb3dlZCA9ICEoVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJiBERFNDTF9GVUxMU0NSRUVOKTsKICAgIEVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgPSBGQUxTRTsKICAgIEF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQgPSBXSU5FRDNERk1UX0QxNjsKICAgIE11bHRpU2FtcGxlVHlwZSA9IFdJTkVEM0RNVUxUSVNBTVBMRV9OT05FOwogICAgU3dhcEVmZmVjdCA9IFdJTkVEM0RTV0FQRUZGRUNUX0NPUFk7CiAgICBGbGFncyA9IDA7CiAgICBNdWx0aVNhbXBsZVF1YWxpdHkgPSAwOwogICAgRnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHogPSBXSU5FRDNEUFJFU0VOVF9SQVRFX0RFRkFVTFQ7IC8qIERlZmF1bHQgcmF0ZTogSXQncyBhbHJlYWR5IHNldCAqLwogICAgUHJlc2VudGF0aW9uSW50ZXJ2YWwgPSBXSU5FRDNEUFJFU0VOVF9JTlRFUlZBTF9ERUZBVUxUOwoKICAgIFRSQUNFKCJQYXNzaW5nIG1vZGUgJWRcbiIsIE1vZGUuRm9ybWF0KTsKCiAgICBsb2NhbFBhcmFtZXRlcnMuQmFja0J1ZmZlcldpZHRoICAgICAgICAgICAgICAgID0gJk1vZGUuV2lkdGg7CiAgICBsb2NhbFBhcmFtZXRlcnMuQmFja0J1ZmZlckhlaWdodCAgICAgICAgICAgICAgID0gJk1vZGUuSGVpZ2h0OwogICAgbG9jYWxQYXJhbWV0ZXJzLkJhY2tCdWZmZXJGb3JtYXQgICAgICAgICAgICAgICA9IChXSU5FRDNERk9STUFUICopICZNb2RlLkZvcm1hdDsKICAgIGxvY2FsUGFyYW1ldGVycy5CYWNrQnVmZmVyQ291bnQgICAgICAgICAgICAgICAgPSAoVUlOVCAqKSAmQmFja0J1ZmZlckNvdW50OwogICAgbG9jYWxQYXJhbWV0ZXJzLk11bHRpU2FtcGxlVHlwZSAgICAgICAgICAgICAgICA9ICZNdWx0aVNhbXBsZVR5cGU7CiAgICBsb2NhbFBhcmFtZXRlcnMuTXVsdGlTYW1wbGVRdWFsaXR5ICAgICAgICAgICAgID0gJk11bHRpU2FtcGxlUXVhbGl0eTsKICAgIGxvY2FsUGFyYW1ldGVycy5Td2FwRWZmZWN0ICAgICAgICAgICAgICAgICAgICAgPSAmU3dhcEVmZmVjdDsKICAgIGxvY2FsUGFyYW1ldGVycy5oRGV2aWNlV2luZG93ICAgICAgICAgICAgICAgICAgPSAmd2luZG93OwogICAgbG9jYWxQYXJhbWV0ZXJzLldpbmRvd2VkICAgICAgICAgICAgICAgICAgICAgICA9ICZpc1dpbmRvd2VkOwogICAgbG9jYWxQYXJhbWV0ZXJzLkVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgICAgICAgICA9ICZFbmFibGVBdXRvRGVwdGhTdGVuY2lsOwogICAgbG9jYWxQYXJhbWV0ZXJzLkF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQgICAgICAgICA9ICZBdXRvRGVwdGhTdGVuY2lsRm9ybWF0OwogICAgbG9jYWxQYXJhbWV0ZXJzLkZsYWdzICAgICAgICAgICAgICAgICAgICAgICAgICA9ICZGbGFnczsKICAgIGxvY2FsUGFyYW1ldGVycy5GdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5IeiAgICAgPSAmRnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHo7CiAgICBsb2NhbFBhcmFtZXRlcnMuUHJlc2VudGF0aW9uSW50ZXJ2YWwgICAgICAgICAgID0gJlByZXNlbnRhdGlvbkludGVydmFsOwoKICAgIC8qIFNldCB0aGlzIE5PVywgb3RoZXJ3aXNlIGNyZWF0aW5nIHRoZSBkZXB0aCBzdGVuY2lsIHN1cmZhY2Ugd2lsbCBjYXVzZSBhCiAgICAgKiByZWN1cnNpdmUgbG9vcCB1bnRpbCByYW0gb3IgZW11bGF0ZWQgdmlkZW8gbWVtb3J5IGlzIGZ1bGwKICAgICAqLwogICAgVGhpcy0+ZDNkX2luaXRpYWxpemVkID0gVFJVRTsKCiAgICBociA9IElXaW5lRDNERGV2aWNlX0luaXQzRChUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmxvY2FsUGFyYW1ldGVycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRDdDQl9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgVGhpcy0+d2luZUQzRERldmljZSA9IE5VTEw7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIC8qIENyZWF0ZSBhbiBJbmRleCBCdWZmZXIgcGFyZW50ICovCiAgICBUUkFDRSgiKCVwKSBTdWNjZXNzZnVsbHkgaW5pdGlhbGl6ZWQgM0RcbiIsIFRoaXMpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0NyZWF0ZUNsaXBwZXIgKEREUkFXLkApCiAqCiAqIENyZWF0ZXMgYSBuZXcgSURpcmVjdERyYXdDbGlwcGVyIG9iamVjdC4KICoKICogUGFyYW1zOgogKiAgQ2xpcHBlcjogQWRkcmVzcyB0byB3cml0ZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgdG8KICogIFVua091dGVyOiBGb3IgYWdncmVnYXRpb24gc3VwcG9ydCwgd2hpY2ggZGRyYXcgZG9lc24ndCBoYXZlLiBIYXMgdG8gYmUKICogICAgICAgICAgICBOVUxMCiAqCiAqIFJldHVybnM6CiAqICBDTEFTU19FX05PQUdHUkVHQVRJT04gaWYgVW5rT3V0ZXIgIT0gTlVMTAogKiAgRV9PVVRPRk1FTU9SWSBpZiBhbGxvY2F0aW5nIHRoZSBvYmplY3QgZmFpbGVkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKRGlyZWN0RHJhd0NyZWF0ZUNsaXBwZXIoRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3Q2xpcHBlciAqKkNsaXBwZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlcikKewogICAgSURpcmVjdERyYXdDbGlwcGVySW1wbCogb2JqZWN0OwogICAgVFJBQ0UoIiglMDh4LCVwLCVwKVxuIiwgRmxhZ3MsIENsaXBwZXIsIFVua091dGVyKTsKCiAgICBpZiAoVW5rT3V0ZXIgIT0gTlVMTCkgcmV0dXJuIENMQVNTX0VfTk9BR0dSRUdBVElPTjsKCiAgICBvYmplY3QgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwKICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKElEaXJlY3REcmF3Q2xpcHBlckltcGwpKTsKICAgIGlmIChvYmplY3QgPT0gTlVMTCkgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgSUNPTV9JTklUX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3REcmF3Q2xpcHBlciwgSURpcmVjdERyYXdDbGlwcGVyX1Z0YmwpOwogICAgb2JqZWN0LT5yZWYgPSAxOwogICAgb2JqZWN0LT5oV25kID0gMDsKICAgIG9iamVjdC0+ZGRyYXdfb3duZXIgPSBOVUxMOwoKICAgICpDbGlwcGVyID0gKElEaXJlY3REcmF3Q2xpcHBlciAqKSBvYmplY3Q7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkNyZWF0ZUNsaXBwZXIKICoKICogQ3JlYXRlcyBhIEREcmF3IGNsaXBwZXIuIFNlZSBEaXJlY3REcmF3Q3JlYXRlQ2xpcHBlciBmb3IgZGV0YWlscwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlQ2xpcHBlcihJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdDbGlwcGVyICoqQ2xpcHBlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24gKlVua091dGVyKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPigleCwlcCwlcClcbiIsIFRoaXMsIEZsYWdzLCBDbGlwcGVyLCBVbmtPdXRlcik7CiAgICByZXR1cm4gRGlyZWN0RHJhd0NyZWF0ZUNsaXBwZXIoRmxhZ3MsIENsaXBwZXIsIFVua091dGVyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6Q3JlYXRlUGFsZXR0ZQogKgogKiBDcmVhdGVzIGEgbmV3IElEaXJlY3REcmF3UGFsZXR0ZSBvYmplY3QKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IFRoZSBmbGFncyBmb3IgdGhlIG5ldyBjbGlwcGVyCiAqICBDb2xvclRhYmxlOiBDb2xvciB0YWJsZSB0byBhc3NpZ24gdG8gdGhlIG5ldyBjbGlwcGVyCiAqICBQYWxldHRlOiBBZGRyZXNzIHRvIHdyaXRlIHRoZSBpbnRlcmZhY2UgcG9pbnRlciB0bwogKiAgVW5rT3V0ZXI6IEZvciBhZ2dyZWdhdGlvbiBzdXBwb3J0LCB3aGljaCBkZHJhdyBkb2Vzbid0IGhhdmUuIEhhcyB0byBiZQogKiAgICAgICAgICAgIE5VTEwKICoKICogUmV0dXJuczoKICogIENMQVNTX0VfTk9BR0dSRUdBVElPTiBpZiBVbmtPdXRlciAhPSBOVUxMCiAqICBFX09VVE9GTUVNT1JZIGlmIGFsbG9jYXRpbmcgdGhlIG9iamVjdCBmYWlsZWQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0NyZWF0ZVBhbGV0dGUoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBTEVUVEVFTlRSWSAqQ29sb3JUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdQYWxldHRlICoqUGFsZXR0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24gKnBVbmtPdXRlcikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3UGFsZXR0ZUltcGwgKm9iamVjdDsKICAgIEhSRVNVTFQgaHIgPSBEREVSUl9HRU5FUklDOwogICAgVFJBQ0UoIiglcCktPigleCwlcCwlcCwlcClcbiIsIFRoaXMsIEZsYWdzLCBDb2xvclRhYmxlLCBQYWxldHRlLCBwVW5rT3V0ZXIpOwoKICAgIGlmKHBVbmtPdXRlciAhPSBOVUxMKQogICAgewogICAgICAgIFdBUk4oInBVbmtPdXRlciBpcyAlcCwgcmV0dXJuaW5nIENMQVNTX0VfTk9BR0dSRUdBVElPTlxuIiwgcFVua091dGVyKTsKICAgICAgICByZXR1cm4gQ0xBU1NfRV9OT0FHR1JFR0FUSU9OOwogICAgfQoKICAgIC8qIFRoZSByZWZjb3VudCB0ZXN0IHNob3dzIHRoYXQgYSBjb29wbGV2ZWwgaXMgcmVxdWlyZWQgZm9yIHRoaXMgKi8KICAgIGlmKCFUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCkKICAgIHsKICAgICAgICBXQVJOKCJObyBjb29wZXJhdGl2ZSBsZXZlbCBzZXQsIHJldHVybmluZyBEREVSUl9OT0NPT1BFUkFUSVZFTEVWRUxTRVRcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9OT0NPT1BFUkFUSVZFTEVWRUxTRVQ7CiAgICB9CgogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihJRGlyZWN0RHJhd1BhbGV0dGVJbXBsKSk7CiAgICBpZighb2JqZWN0KQogICAgewogICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSB3aGVuIGFsbG9jYXRpbmcgbWVtb3J5IGZvciBhIHBhbGV0dGUgaW1wbGVtZW50YXRpb25cbiIpOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQoKICAgIElDT01fSU5JVF9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0RHJhd1BhbGV0dGUsIElEaXJlY3REcmF3UGFsZXR0ZV9WdGJsKTsKICAgIG9iamVjdC0+cmVmID0gMTsKICAgIG9iamVjdC0+ZGRyYXdfb3duZXIgPSBUaGlzOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlUGFsZXR0ZShUaGlzLT53aW5lRDNERGV2aWNlLCBGbGFncywgQ29sb3JUYWJsZSwgJm9iamVjdC0+d2luZUQzRFBhbGV0dGUsIChJVW5rbm93biAqKSBJQ09NX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3REcmF3UGFsZXR0ZSkgKTsKICAgIGlmKGhyICE9IEREX09LKQogICAgewogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIElEaXJlY3REcmF3N19BZGRSZWYoaWZhY2UpOwogICAgb2JqZWN0LT5pZmFjZVRvUmVsZWFzZSA9IChJVW5rbm93biAqKSBpZmFjZTsKICAgICpQYWxldHRlID0gSUNPTV9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0RHJhd1BhbGV0dGUpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpEdXBsaWNhdGVTdXJmYWNlCiAqCiAqIER1cGxpY2F0ZXMgYSBzdXJmYWNlLiBUaGUgc3VyZmFjZSBtZW1vcnkgcG9pbnRzIHRvIHRoZSBzYW1lIG1lbW9yeSBhcwogKiB0aGUgb3JpZ2luYWwgc3VyZmFjZSwgYW5kIGl0J3MgcmVsZWFzZWQgd2hlbiB0aGUgbGFzdCBzdXJmYWNlIHJlZmVyZW5jaW5nCiAqIGl0IGlzIHJlbGVhc2VkLiBJIGd1ZXNzIHRoYXQncyBiZXlvbmQgV2luZSdzIHN1cmZhY2UgbWFuYWdlbWVudCByaWdodCBub3cKICogKElkZWE6IGNyZWF0ZSBhIG5ldyBERHJhdyBzdXJmYWNlIHdpdGggdGhlIHNhbWUgV2luZUQzRFN1cmZhY2UuIEkgbmVlZCBhCiAqIHRlc3QgYXBwbGljYXRpb24gdG8gaW1wbGVtZW50IHRoaXMpCiAqCiAqIFBhcmFtczoKICogIFNyYzogQWRkcmVzcyBvZiB0aGUgc291cmNlIHN1cmZhY2UKICogIERlc3Q6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIG5ldyBzdXJmYWNlIHBvaW50ZXIgdG8KICoKICogUmV0dXJuczoKICogIFNlZSBJRGlyZWN0RHJhdzc6OkNyZWF0ZVN1cmZhY2UKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0R1cGxpY2F0ZVN1cmZhY2UoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqU3JjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICoqRGVzdCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKlN1cmYgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBTcmMpOwoKICAgIEZJWE1FKCIoJXApLT4oJXAsJXApXG4iLCBUaGlzLCBTdXJmLCBEZXN0KTsKCiAgICAvKiBGb3Igbm93LCBzaW1wbHkgY3JlYXRlIGEgbmV3LCBpbmRlcGVuZGVudCBzdXJmYWNlICovCiAgICByZXR1cm4gSURpcmVjdERyYXc3X0NyZWF0ZVN1cmZhY2UoaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN1cmYtPnN1cmZhY2VfZGVzYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3IFZUYWJsZQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCmNvbnN0IElEaXJlY3REcmF3N1Z0YmwgSURpcmVjdERyYXc3X1Z0YmwgPQp7CiAgICAvKioqIElVbmtub3duICoqKi8KICAgIElEaXJlY3REcmF3SW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElEaXJlY3REcmF3SW1wbF9BZGRSZWYsCiAgICBJRGlyZWN0RHJhd0ltcGxfUmVsZWFzZSwKICAgIC8qKiogSURpcmVjdERyYXcgKioqLwogICAgSURpcmVjdERyYXdJbXBsX0NvbXBhY3QsCiAgICBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlQ2xpcHBlciwKICAgIElEaXJlY3REcmF3SW1wbF9DcmVhdGVQYWxldHRlLAogICAgSURpcmVjdERyYXdJbXBsX0NyZWF0ZVN1cmZhY2UsCiAgICBJRGlyZWN0RHJhd0ltcGxfRHVwbGljYXRlU3VyZmFjZSwKICAgIElEaXJlY3REcmF3SW1wbF9FbnVtRGlzcGxheU1vZGVzLAogICAgSURpcmVjdERyYXdJbXBsX0VudW1TdXJmYWNlcywKICAgIElEaXJlY3REcmF3SW1wbF9GbGlwVG9HRElTdXJmYWNlLAogICAgSURpcmVjdERyYXdJbXBsX0dldENhcHMsCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0RGlzcGxheU1vZGUsCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0Rm91ckNDQ29kZXMsCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0R0RJU3VyZmFjZSwKICAgIElEaXJlY3REcmF3SW1wbF9HZXRNb25pdG9yRnJlcXVlbmN5LAogICAgSURpcmVjdERyYXdJbXBsX0dldFNjYW5MaW5lLAogICAgSURpcmVjdERyYXdJbXBsX0dldFZlcnRpY2FsQmxhbmtTdGF0dXMsCiAgICBJRGlyZWN0RHJhd0ltcGxfSW5pdGlhbGl6ZSwKICAgIElEaXJlY3REcmF3SW1wbF9SZXN0b3JlRGlzcGxheU1vZGUsCiAgICBJRGlyZWN0RHJhd0ltcGxfU2V0Q29vcGVyYXRpdmVMZXZlbCwKICAgIElEaXJlY3REcmF3SW1wbF9TZXREaXNwbGF5TW9kZSwKICAgIElEaXJlY3REcmF3SW1wbF9XYWl0Rm9yVmVydGljYWxCbGFuaywKICAgIC8qKiogSURpcmVjdERyYXcyICoqKi8KICAgIElEaXJlY3REcmF3SW1wbF9HZXRBdmFpbGFibGVWaWRNZW0sCiAgICAvKioqIElEaXJlY3REcmF3NyAqKiovCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0U3VyZmFjZUZyb21EQywKICAgIElEaXJlY3REcmF3SW1wbF9SZXN0b3JlQWxsU3VyZmFjZXMsCiAgICBJRGlyZWN0RHJhd0ltcGxfVGVzdENvb3BlcmF0aXZlTGV2ZWwsCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0RGV2aWNlSWRlbnRpZmllciwKICAgIC8qKiogSURpcmVjdERyYXc3ICoqKi8KICAgIElEaXJlY3REcmF3SW1wbF9TdGFydE1vZGVUZXN0LAogICAgSURpcmVjdERyYXdJbXBsX0V2YWx1YXRlTW9kZQp9Owo=