LyogRGlyZWN0M0QgVmVydGV4IEJ1ZmZlcgogKiBDb3B5cmlnaHQgKGMpIDIwMDIgTGlvbmVsIFVMTUVSCiAqIENvcHlyaWdodCAoYykgMjAwNiBTdGVmYW4gRNZTSU5HRVIKICoKICogVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBEaXJlY3QzRFZlcnRleEJ1ZmZlciBDT00gb2JqZWN0CiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCiNpbmNsdWRlICJleGNwdC5oIgoKI2luY2x1ZGUgImRkcmF3LmgiCiNpbmNsdWRlICJkM2QuaCIKCiNpbmNsdWRlICJkZHJhd19wcml2YXRlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkM2Q3KTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwoZGRyYXdfdGh1bmspOwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJVW5rbm93biBNZXRob2RzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3OjpRdWVyeUludGVyZmFjZQogKgogKiBUaGUgUXVlcnlJbnRlcmZhY2UgTWV0aG9kIGZvciBWZXJ0ZXggQnVmZmVycwogKiBGb3IgYSBsaW5rIHRvIFF1ZXJ5SW50ZXJmYWNlIHJ1bGVzLCBzZWUgSURpcmVjdERyYXc3OjpRdWVyeUludGVyZmFjZQogKgogKiBQYXJhbXMKICogIHJpaWQ6IFF1ZXJ5aWVkIEludGVyZmFjZSBpZAogKiAgb2JqOiBBZGRyZXNzIHRvIHJldHVybiB0aGUgaW50ZXJmYWNlIHBvaW50ZXIKICoKICogUmV0dXJuczoKICogIFNfT0sgb24gc3VjY2VzcwogKiAgRV9OT0lOVEVSRkFDRSBpZiB0aGUgaW50ZXJmYWNlIHdhc24ndCBmb3VuZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlKElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgICoqb2JqKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgb2JqKTsKCiAgICAvKiBCeSBkZWZhdWx0LCBzZXQgdGhlIG9iamVjdCBwb2ludGVyIHRvIE5VTEwgKi8KICAgICpvYmogPSBOVUxMOwoKICAgIGlmICggSXNFcXVhbEdVSUQoICZJSURfSVVua25vd24sICByaWlkICkgKQogICAgewogICAgICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjdfQWRkUmVmKElDT01fSU5URVJGQUNFKFRoaXMsSURpcmVjdDNEVmVydGV4QnVmZmVyNykpOwogICAgICAgICpvYmogPSBpZmFjZTsKICAgICAgICBUUkFDRSgiICBDcmVhdGluZyBJVW5rbm93biBpbnRlcmZhY2UgYXQgJXAuXG4iLCAqb2JqKTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEVmVydGV4QnVmZmVyLCByaWlkICkgKQogICAgewogICAgICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjdfQWRkUmVmKElDT01fSU5URVJGQUNFKFRoaXMsSURpcmVjdDNEVmVydGV4QnVmZmVyNykpOwogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXIpOwogICAgICAgIFRSQUNFKCIgIENyZWF0aW5nIElEaXJlY3QzRFZlcnRleEJ1ZmZlciBpbnRlcmZhY2UgJXBcbiIsICpvYmopOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQogICAgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3LCByaWlkICkgKQogICAgewogICAgICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjdfQWRkUmVmKElDT01fSU5URVJGQUNFKFRoaXMsSURpcmVjdDNEVmVydGV4QnVmZmVyNykpOwogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3KTsKICAgICAgICBUUkFDRSgiICBDcmVhdGluZyBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3IGludGVyZmFjZSAlcFxuIiwgKm9iaik7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CiAgICBGSVhNRSgiKCVwKTogaW50ZXJmYWNlIGZvciBJSUQgJXMgTk9UIGZvdW5kIVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGxfMV9RdWVyeUludGVyZmFjZShJRGlyZWN0M0RWZXJ0ZXhCdWZmZXIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICoqb2JqKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcywlcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNEVmVydGV4QnVmZmVyNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBvYmopOwoKICAgIHJldHVybiBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3X1F1ZXJ5SW50ZXJmYWNlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iaik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3OjpBZGRSZWYKICoKICogQWRkUmVmIGZvciBWZXJ0ZXggQnVmZmVycwogKgogKiBSZXR1cm5zOgogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbF9BZGRSZWYoSURpcmVjdDNEVmVydGV4QnVmZmVyNyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGwsIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcsIGlmYWNlKTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwoKICAgIFRSQUNFKCIoJXAvJXApLT4oKSBpbmNyZW1lbnRpbmcgZnJvbSAldS5cbiIsIFRoaXMsIGlmYWNlLCByZWYgLSAxKTsKCiAgICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJClRodW5rX0lEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGxfMV9BZGRSZWYoSURpcmVjdDNEVmVydGV4QnVmZmVyICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbCwgSURpcmVjdDNEVmVydGV4QnVmZmVyLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oKSB0aHVua2luZyB0byBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3IGludGVyZmFjZS5cbiIsIFRoaXMpOwoKICAgIHJldHVybiBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3X0FkZFJlZihJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3KSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNEVmVydGV4QnVmZmVyNzo6UmVsZWFzZQogKgogKiBSZWxlYXNlIGZvciBWZXJ0ZXggQnVmZmVycwogKgogKiBSZXR1cm5zOgogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbF9SZWxlYXNlKElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3LCBpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBUUkFDRSgiKCVwKS0+KCkgZGVjcmVtZW50aW5nIGZyb20gJXUuXG4iLCBUaGlzLCByZWYgKyAxKTsKCiAgICBpZiAocmVmID09IDApCiAgICB7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgKmN1clZCID0gTlVMTDsKICAgICAgICBVSU5UIG9mZnNldCwgc3RyaWRlOwoKICAgICAgICAvKiBEM0Q3IFZlcnRleCBidWZmZXJzIGRvbid0IHN0YXkgYm91bmQgaW4gdGhlIGRldmljZSwgdGhleSBhcmUgcGFzc2VkIGFzIGEgcGFyYW1ldGVyCiAgICAgICAgICogdG8gZHJhd1ByaW1pdGl2ZVZCLiBEcmF3UHJpbWl0aXZlVkIgc2V0cyB0aGVtIGFzIHRoZSBzdHJlYW0gc291cmNlIGluIHdpbmVkM2QsCiAgICAgICAgICogYW5kIHRoZXkgc2hvdWxkIGdldCB1bnNldCB0aGVyZSBiZWZvcmUgdGhleSBhcmUgZGVzdHJveWVkCiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VfR2V0U3RyZWFtU291cmNlKFRoaXMtPmRkcmF3LT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFN0cmVhbSBudW1iZXIgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjdXJWQiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0cmlkZSk7CiAgICAgICAgaWYoY3VyVkIgPT0gVGhpcy0+d2luZUQzRFZlcnRleEJ1ZmZlcikKICAgICAgICB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFN0cmVhbVNvdXJjZShUaGlzLT5kZHJhdy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogU3RlYW0gbnVtYmVyICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCAvKiBzdHJlYW0gZGF0YSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogT2Zmc2V0ICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBzdHJpZGUgKi8pOwogICAgICAgIH0KICAgICAgICBpZihjdXJWQikKICAgICAgICB7CiAgICAgICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVyX1JlbGVhc2UoY3VyVkIpOyAvKiBGb3IgdGhlIEdldFN0cmVhbVNvdXJjZSAqLwogICAgICAgIH0KCgogICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVyX1JlbGVhc2UoVGhpcy0+d2luZUQzRFZlcnRleEJ1ZmZlcik7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJClRodW5rX0lEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGxfMV9SZWxlYXNlKElEaXJlY3QzRFZlcnRleEJ1ZmZlciAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGwsIElEaXJlY3QzRFZlcnRleEJ1ZmZlciwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCkgdGh1bmtpbmcgdG8gSURpcmVjdDNEVmVydGV4QnVmZmVyNyBpbnRlcmZhY2UuXG4iLCBUaGlzKTsKCiAgICByZXR1cm4gSURpcmVjdDNEVmVydGV4QnVmZmVyN19SZWxlYXNlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRFZlcnRleEJ1ZmZlciBNZXRob2RzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3OjpMb2NrCiAqCiAqIExvY2tzIHRoZSB2ZXJ0ZXggYnVmZmVyIGFuZCByZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgdmVydGV4IGRhdGEKICogTG9ja2luZyB2ZXJ0ZXggYnVmZmVycyBpcyBzaW1pbGFyIHRvIGxvY2tpbmcgc3VyZmFjZXMsIGJlY2F1c2UgV2luZG93cwogKiB1c2VzIHN1cmZhY2VzIHRvIHN0b3JlIHZlcnRleCBkYXRhIGludGVybmFsbHkgKEFjY29yZGluZyB0byB0aGUgRFggc2RrKQogKgogKiBQYXJhbXM6CiAqICBGbGFnczogTG9ja2luZyBmbGFncy4gUmVsZXZhbnQgaGVyZSBhcmUgRERMT0NLX1JFQURPTkxZLCBERExPQ0tfV1JJVEVPTkxZLAogKiAgICAgICAgIERETE9DS19ESVNDQVJEQ09OVEVOVFMgYW5kIERETE9DS19OT09WRVJXUklURS4KICogIERhdGE6ICBSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgdmVydGV4IGRhdGEKICogIFNpemU6ICBSZXR1cm5zIHRoZSBzaXplIG9mIHRoZSBidWZmZXIgaWYgbm90IE5VTEwKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIERhdGEgaXMgTlVMTAogKiAgRDNERVJSX1ZFUlRFWEJVRkZFUk9QVElNSVpFRCBpZiBjYWxsZWQgb24gYW4gb3B0aW1pemVkIGJ1ZmZlcihXaW5lRDNEKQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsX0xvY2soSURpcmVjdDNEVmVydGV4QnVmZmVyNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlNpemUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGwsIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcsIGlmYWNlKTsKICAgIFdJTkVEM0RWRVJURVhCVUZGRVJfREVTQyBEZXNjOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcCwlcClcbiIsIFRoaXMsIEZsYWdzLCBEYXRhLCBTaXplKTsKCiAgICBpZihTaXplKQogICAgewogICAgICAgIC8qIEdldCB0aGUgc2l6ZSwgZm9yIHJldHVybmluZyBpdCwgYW5kIGZvciBsb2NraW5nICovCiAgICAgICAgaHIgPSBJV2luZUQzRFZlcnRleEJ1ZmZlcl9HZXREZXNjKFRoaXMtPndpbmVEM0RWZXJ0ZXhCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZEZXNjKTsKICAgICAgICBpZihociAhPSBEM0RfT0spCiAgICAgICAgewogICAgICAgICAgICBFUlIoIiglcCkgSVdpbmVEM0RWZXJ0ZXhCdWZmZXI6OkdldERlc2MgZmFpbGVkIHdpdGggaHI9JTA4eFxuIiwgVGhpcywgaHIpOwogICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgfQogICAgICAgICpTaXplID0gRGVzYy5TaXplOwogICAgfQoKICAgIHJldHVybiBJV2luZUQzRFZlcnRleEJ1ZmZlcl9Mb2NrKFRoaXMtPndpbmVEM0RWZXJ0ZXhCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIE9mZnNldFRvTG9jayAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogU2l6ZVRvTG9jaywgMCA9PSBGdWxsIGxvY2sgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQllURSAqKikgRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGxfMV9Mb2NrKElEaXJlY3QzRFZlcnRleEJ1ZmZlciAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICoqRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlNpemUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGwsIElEaXJlY3QzRFZlcnRleEJ1ZmZlciwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJXAsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcgaW50ZXJmYWNlLlxuIiwgVGhpcywgRmxhZ3MsIERhdGEsIFNpemUpOwoKICAgIHJldHVybiBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3X0xvY2soSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNEVmVydGV4QnVmZmVyNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjc6OlVubG9jawogKgogKiBVbmxvY2tzIGEgdmVydGV4IEJ1ZmZlcgogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbF9VbmxvY2soSURpcmVjdDNEVmVydGV4QnVmZmVyNyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGwsIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oKVxuIiwgVGhpcyk7CgogICAgLyogVGhpcyBpcyBlYXN5IDopICovCiAgICByZXR1cm4gSVdpbmVEM0RWZXJ0ZXhCdWZmZXJfVW5sb2NrKFRoaXMtPndpbmVEM0RWZXJ0ZXhCdWZmZXIpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbF8xX1VubG9jayhJRGlyZWN0M0RWZXJ0ZXhCdWZmZXIgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPigpIHRodW5raW5nIHRvIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcgaW50ZXJmYWNlLlxuIiwgVGhpcyk7CgogICAgcmV0dXJuIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjdfVW5sb2NrKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcpKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3OjpQcm9jZXNzVmVydGljZXMKICoKICogUHJvY2Vzc2VzIHVudHJhbnNmb3JtZWQgVmVydGljZXMgaW50byBhIHRyYW5zZm9ybWVkIG9yIG9wdGltaXplZCB2ZXJ0ZXgKICogYnVmZmVyLiBJdCBjYW4gYWxzbyBwZXJmb3JtIG90aGVyIG9wZXJhdGlvbnMsIHN1Y2ggYXMgbGlnaHRpbmcgb3IgY2xpcHBpbmcKICoKICogUGFyYW1zCiAqICBWZXJ0ZXhPcDogT3BlcmF0aW9uKHMpIHRvIHBlcmZvcm06IEQzRFZPUF9DTElQLCBfRVhURU5UUywgX0xJR0hULCBfVFJBTlNGT1JNCiAqICBEZXN0SW5kZXg6IEluZGV4IGluIHRoZSBkZXN0aW5hdGlvbiBidWZmZXIoVGhpcyksIHdoZXJlIHRoZSB2ZXJ0aWNlcyBhcmUKICogICAgICAgICAgICAgcGxhY2VkCiAqICBDb3VudDogTnVtYmVyIG9mIFZlcnRpY2VzIGluIHRoZSBTb3VyY2UgYnVmZmVyIHRvIHByb2Nlc3MKICogIFNyY0J1ZmZlcjogU291cmNlIHZlcnRleCBidWZmZXIKICogIFNyY0luZGV4OiBJbmRleCBvZiB0aGUgZmlyc3QgdmVydGV4IGluIHRoZSBzcmMgYnVmZmVyIHRvIHByb2Nlc3MKICogIEQzRERldmljZTogRGV2aWNlIHRvIHVzZSBmb3IgdHJhbnNmb3JtYXRpb24KICogIEZsYWdzOiAwIGZvciBkZWZhdWx0LCBEM0RQVl9ET05PVENPUFlEQVRBIHRvIHByZXZlbnQgY29weWluZwogKiAgICAgICAgIHVuY2hhbmVkIHZlcnRpY2VzCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBJZiBEM0RWT1BfVFJBTlNGT1JNIHdhc24ndCBwYXNzZWQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbF9Qcm9jZXNzVmVydGljZXMoSURpcmVjdDNEVmVydGV4QnVmZmVyNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleE9wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBEZXN0SW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3ICpTcmNCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFNyY0luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0REZXZpY2U3ICpEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3LCBpZmFjZSk7CiAgICBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsICpTcmMgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3LCBTcmNCdWZmZXIpOwogICAgSURpcmVjdDNERGV2aWNlSW1wbCAqRDNEID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgRDNERGV2aWNlKTsKICAgIEJPT0wgb2xkQ2xpcCwgZG9DbGlwOwogICAgSFJFU1VMVCBocjsKCiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJWQsJWQsJXAsJWQsJXAsJTA4eClcbiIsIFRoaXMsIFZlcnRleE9wLCBEZXN0SW5kZXgsIENvdW50LCBTcmMsIFNyY0luZGV4LCBEM0QsIEZsYWdzKTsKCiAgICAvKiBWZXJ0ZXggb3BlcmF0aW9uczoKICAgICAqIEQzRFZPUF9DTElQOiBDbGlwcyB2ZXJ0aWNlcyBvdXRzaWRlIHRoZSB2aWV3aW5nIGZydXN0cnVtLiBOZWVkcyBjbGlwcGluZyBpbmZvcm1hdGlvbgogICAgICogaW4gdGhlIHZlcnRleCBidWZmZXIgKEJ1ZmZlciBtYXkgbm90IGJlIGNyZWF0ZWQgd2l0aCBEM0RWQkNBUFNfRE9OT1RDTElQKQogICAgICogRDNEVk9QX0VYVEVOVFM6IENhdXNlcyB0aGUgc2NyZWVuIGV4dGVudHMgdG8gYmUgdXBkYXRlZCB3aGVuIHJlbmRlcmluZyB0aGUgdmVydGljZXMKICAgICAqIEQzRFZPUF9MSUdIVDogTGlnaHRzIHRoZSB2ZXJ0aWNlcwogICAgICogRDNEVk9QX1RSQU5TRk9STTogVHJhbnNmb3JtIHRoZSB2ZXJ0aWNlcy4gVGhpcyBmbGFnIGlzIG5lY2Vzc2FyeQogICAgICoKICAgICAqIFdpbmVEM0Qgb25seSB0cmFuc2Zvcm1zIGFuZCBjbGlwcyB0aGUgdmVydGljZXMgYnkgbm93LCBzbyBFWFRFTlRTIGFuZCBMSUdIVAogICAgICogYXJlIG5vdCBpbXBsZW1lbnRlZC4gQ2xpcHBpbmcgaXMgZGlzYWJsZWQgQVRNLCBiZWNhdXNlIG9mIHVuc3VyZSBjb25kaXRpb25zLgogICAgICovCiAgICBpZiggIShWZXJ0ZXhPcCAmIEQzRFZPUF9UUkFOU0ZPUk0pICkgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgLyogV2luZUQzRCBkb2Vzbid0IGtub3cgZDNkNyB2ZXJ0ZXggb3BlcmF0aW9uLCBpdCB1c2VzCiAgICAgKiByZW5kZXIgc3RhdGVzIGluc3RlYWQuIFNldCB0aGUgcmVuZGVyIHN0YXRlcyBhY2NvcmRpbmcgdG8KICAgICAqIHRoZSB2ZXJ0ZXggb3BzCiAgICAgKi8KICAgIGRvQ2xpcCA9IFZlcnRleE9wICYgRDNEVk9QX0NMSVAgPyBUUlVFIDogRkFMU0U7CiAgICBJV2luZUQzRERldmljZV9HZXRSZW5kZXJTdGF0ZShEM0QtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEUlNfQ0xJUFBJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRFdPUkQgKikgJm9sZENsaXApOwogICAgaWYoZG9DbGlwICE9IG9sZENsaXApCiAgICB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0UmVuZGVyU3RhdGUoRDNELT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RSU19DTElQUElORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb0NsaXApOwogICAgfQoKCiAgICBociA9IElXaW5lRDNERGV2aWNlX1Byb2Nlc3NWZXJ0aWNlcyhEM0QtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTcmNJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc3RJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+d2luZUQzRFZlcnRleEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNyYy0+d2luZUQzRFZlcnRleEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKCiAgICAvKiBSZXN0b3JlIHRoZSBzdGF0ZXMgaWYgbmVlZGVkICovCiAgICBpZihkb0NsaXAgIT0gb2xkQ2xpcCkKICAgICAgICBJV2luZUQzRERldmljZV9TZXRSZW5kZXJTdGF0ZShEM0QtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFJTX0NMSVBQSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZENsaXApOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbF8xX1Byb2Nlc3NWZXJ0aWNlcyhJRGlyZWN0M0RWZXJ0ZXhCdWZmZXIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleE9wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIERlc3RJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXIgKlNyY0J1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTcmNJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0REZXZpY2UzICpEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGwsIElEaXJlY3QzRFZlcnRleEJ1ZmZlciwgaWZhY2UpOwogICAgSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbCAqU3JjID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbCwgSURpcmVjdDNEVmVydGV4QnVmZmVyLCBTcmNCdWZmZXIpOwogICAgSURpcmVjdDNERGV2aWNlSW1wbCAqRDNEID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgRDNERGV2aWNlKTsKCiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlMDh4LCUwOHgsJXAsJTA4eCwlcCwlMDh4KSB0aHVua2luZyB0byBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3IGludGVyZmFjZS5cbiIsIFRoaXMsIFZlcnRleE9wLCBEZXN0SW5kZXgsIENvdW50LCBTcmMsIFNyY0luZGV4LCBEM0QsIEZsYWdzKTsKCiAgICByZXR1cm4gSURpcmVjdDNEVmVydGV4QnVmZmVyN19Qcm9jZXNzVmVydGljZXMoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNEVmVydGV4QnVmZmVyNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVydGV4T3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzdEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElDT01fSU5URVJGQUNFKFNyYywgSURpcmVjdDNEVmVydGV4QnVmZmVyNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3JjSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNPTV9JTlRFUkZBQ0UoRDNELCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3OjpHZXRWZXJ0ZXhCdWZmZXJEZXNjCiAqCiAqIFJldHVybnMgdGhlIGRlc2NyaXB0aW9uIG9mIGEgdmVydGV4IGJ1ZmZlcgogKgogKiBQYXJhbXM6CiAqICBEZXNjOiBBZGRyZXNzIHRvIHdyaXRlIHRoZSBkZXNjcmlwdGlvbiB0bwogKgogKiBSZXR1cm5zCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIERlc2MgaXMgTlVMTAogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbF9HZXRWZXJ0ZXhCdWZmZXJEZXNjKElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVkVSVEVYQlVGRkVSREVTQyAqRGVzYykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbCwgSURpcmVjdDNEVmVydGV4QnVmZmVyNywgaWZhY2UpOwogICAgV0lORUQzRFZFUlRFWEJVRkZFUl9ERVNDIFdEZXNjOwogICAgSFJFU1VMVCBocjsKICAgIERXT1JEIHNpemU7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgRGVzYyk7CgogICAgaWYoIURlc2MpIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIGhyID0gSVdpbmVEM0RWZXJ0ZXhCdWZmZXJfR2V0RGVzYyhUaGlzLT53aW5lRDNEVmVydGV4QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZXRGVzYyk7CiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgRVJSKCIoJXApIElXaW5lRDNEVmVydGV4QnVmZmVyOjpHZXREZXNjIGZhaWxlZCB3aXRoIGhyPSUwOHhcbiIsIFRoaXMsIGhyKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogQ2xlYXIgdGhlIHJldHVybiB2YWx1ZSBvZiBnYXJiYWdlICovCiAgICBzaXplID0gRGVzYy0+ZHdTaXplOwogICAgbWVtc2V0KERlc2MsIDAsIHNpemUpOwoKICAgIC8qIE5vdyBmaWxsIHRoZSBEZXNjIHN0cnVjdHVyZSAqLwogICAgRGVzYy0+ZHdTaXplID0gc2l6ZTsKICAgIERlc2MtPmR3Q2FwcyA9IFRoaXMtPkNhcHM7CiAgICBEZXNjLT5kd0ZWRiA9IFdEZXNjLkZWRjsKICAgIERlc2MtPmR3TnVtVmVydGljZXMgPSBXRGVzYy5TaXplIC8gZ2V0X2ZsZXhpYmxlX3ZlcnRleF9zaXplKFdEZXNjLkZWRik7CgogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGxfMV9HZXRWZXJ0ZXhCdWZmZXJEZXNjKElEaXJlY3QzRFZlcnRleEJ1ZmZlciAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZFUlRFWEJVRkZFUkRFU0MgKkRlc2MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGwsIElEaXJlY3QzRFZlcnRleEJ1ZmZlciwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3IGludGVyZmFjZS5cbiIsIFRoaXMsIERlc2MpOwoKICAgIHJldHVybiBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3X0dldFZlcnRleEJ1ZmZlckRlc2MoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNEVmVydGV4QnVmZmVyNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2MpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjc6Ok9wdGltaXplCiAqCiAqIENvbnZlcnRzIGFuIHVub3B0aW1pemVkIHZlcnRleCBidWZmZXIgaW50byBhbiBvcHRpbWl6ZWQgYnVmZmVyCiAqCiAqIFBhcmFtczoKICogIEQzRERldmljZTogRGV2aWNlIGZvciB3aGljaCB0aGlzIGJ1ZmZlciBpcyBvcHRpbWl6ZWQKICogIEZsYWdzOiBOb3QgdXNlZCwgc2hvdWxkIGJlIHNldCB0byAwCiAqCiAqIFJldHVybnMKICogIEQzRF9PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsX09wdGltaXplKElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRERldmljZTcgKkQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbCwgSURpcmVjdDNEVmVydGV4QnVmZmVyNywgaWZhY2UpOwogICAgSURpcmVjdDNERGV2aWNlSW1wbCAqRDNEID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgRDNERGV2aWNlKTsKICAgIEZJWE1FKCIoJXApLT4oJXAsJTA4eCk6IHN0dWIhXG4iLCBUaGlzLCBEM0QsIEZsYWdzKTsKCiAgICAvKiBXZSBjb3VsZCBmb3J3YXJkIHRoaXMgY2FsbCB0byBXaW5lRDNEIGFuZCB0YWtlIGFkdmFudGFnZQogICAgICogb2YgaXQgb25jZSB3ZSB1c2UgT3BlbkdMIHZlcnRleCBidWZmZXJzCiAgICAgKi8KICAgIFRoaXMtPkNhcHMgfD0gRDNEVkJDQVBTX09QVElNSVpFRDsKCiAgICByZXR1cm4gRERfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsXzFfT3B0aW1pemUoSURpcmVjdDNEVmVydGV4QnVmZmVyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRERldmljZTMgKkQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXIsIGlmYWNlKTsKICAgIElEaXJlY3QzRERldmljZUltcGwgKkQzRCA9IElDT01fT0JKRUNUKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIEQzRERldmljZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXAsJTA4eCkgdGh1bmtpbmcgdG8gSURpcmVjdDNEVmVydGV4QnVmZmVyNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBEM0QsIEZsYWdzKTsKCiAgICByZXR1cm4gSURpcmVjdDNEVmVydGV4QnVmZmVyN19PcHRpbWl6ZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElDT01fSU5URVJGQUNFKEQzRCwgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3OjpQcm9jZXNzVmVydGljZXNTdHJpZGVkCiAqCiAqIFRoaXMgbWV0aG9kIHByb2Nlc3NlcyB1bnRyYW5zZm9ybWVkIHN0cmlkZWQgdmVydGljZXMgaW50byBhIHByb2Nlc3NlZAogKiBvciBvcHRpbWl6ZWQgdmVydGV4IGJ1ZmZlci4KICoKICogRm9yIG1vcmUgZGV0YWlscyBvbiB0aGUgcGFyYW1ldGVycywgc2VlCiAqIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjc6OlByb2Nlc3NWZXJ0aWNlcwogKgogKiBQYXJhbXM6CiAqICBWZXJ0ZXhPcDogT3BlcmF0aW9ucyB0byBwZXJmb3JtCiAqICBEZXN0SW5kZXg6IERlc3RpbmF0aW9uIGluZGV4IHRvIHdyaXRlIHRoZSB2ZXJ0aWNlcyB0bwogKiAgQ291bnQ6IE51bWJlciBvZiBpbnB1dCB2ZXJ0aWNlcwogKiAgU3RyaWRlRGF0YTogQXJyYXkgY29udGFpbmluZyB0aGUgaW5wdXQgdmVydGljZXMKICogIFZlcnRleFR5cGVEZXNjOiBWZXJ0ZXggRGVzY3JpcHRpb24gb3Igc291cmNlIGluZGV4Pz8/Pz8/Pz8/CiAqICBEM0REZXZpY2U6IElEaXJlY3QzRERldmljZTcgdG8gdXNlIGZvciBwcm9jZXNzaW5nCiAqICBGbGFnczogQ2FuIGJlIEQzRFBWX0RPTk9UQ09QWURBVEEgdG8gYXZvaWQgY29weWluZyB1bm1vZGlmaWVkIHZlcnRpY2VzCiAqCiAqIFJldHVybnMKICogIEQzRF9PSyBvbiBzdWNjZXNzLCBvciBEREVSUl8qCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGxfUHJvY2Vzc1ZlcnRpY2VzU3RyaWRlZChJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleE9wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRGVzdEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0REUkFXUFJJTUlUSVZFU1RSSURFRERBVEEgKlN0cmlkZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhUeXBlRGVzYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRERldmljZTcgKkQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3LCBpZmFjZSk7CiAgICBJRGlyZWN0M0REZXZpY2VJbXBsICpEM0QgPSBJQ09NX09CSkVDVChJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBEM0REZXZpY2UpOwogICAgRklYTUUoIiglcCktPiglMDh4LCUwOHgsJTA4eCwlcCwlMDh4LCVwLCUwOHgpOiBzdHViIVxuIiwgVGhpcywgVmVydGV4T3AsIERlc3RJbmRleCwgQ291bnQsIFN0cmlkZURhdGEsIFZlcnRleFR5cGVEZXNjLCBEM0QsIEZsYWdzKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBWVGFibGVzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCmNvbnN0IElEaXJlY3QzRFZlcnRleEJ1ZmZlcjdWdGJsIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjdfVnRibCA9CnsKICAgIC8qKiogSVVua25vd24gTWV0aG9kcyAqKiovCiAgICBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbF9BZGRSZWYsCiAgICBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsX1JlbGVhc2UsCiAgICAvKioqIElEaXJlY3QzRFZlcnRleEJ1ZmZlciBNZXRob2RzICoqKi8KICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGxfTG9jaywKICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGxfVW5sb2NrLAogICAgSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbF9Qcm9jZXNzVmVydGljZXMsCiAgICBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsX0dldFZlcnRleEJ1ZmZlckRlc2MsCiAgICBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsX09wdGltaXplLAogICAgLyoqKiBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3IE1ldGhvZHMgKioqLwogICAgSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbF9Qcm9jZXNzVmVydGljZXNTdHJpZGVkCn07Cgpjb25zdCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJWdGJsIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjFfVnRibCA9CnsKICAgIC8qKiogSVVua25vd24gTWV0aG9kcyAqKiovCiAgICBUaHVua19JRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsXzFfUXVlcnlJbnRlcmZhY2UsCiAgICBUaHVua19JRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsXzFfQWRkUmVmLAogICAgVGh1bmtfSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbF8xX1JlbGVhc2UsCiAgICAvKioqIElEaXJlY3QzRFZlcnRleEJ1ZmZlciBNZXRob2RzICoqKi8KICAgIFRodW5rX0lEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGxfMV9Mb2NrLAogICAgVGh1bmtfSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbF8xX1VubG9jaywKICAgIFRodW5rX0lEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGxfMV9Qcm9jZXNzVmVydGljZXMsCiAgICBUaHVua19JRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsXzFfR2V0VmVydGV4QnVmZmVyRGVzYywKICAgIFRodW5rX0lEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGxfMV9PcHRpbWl6ZQp9Owo=