LyoKICogMkQgU3VyZmFjZSBpbXBsZW1lbnRhdGlvbiB3aXRob3V0IE9wZW5HTAogKgogKiBDb3B5cmlnaHQgMTk5Ny0yMDAwIE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgMTk5OC0yMDAwIExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYtMjAwOCBTdGVmYW4gRPZzaW5nZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CgovKiBVc2UgdGhlIGQzZF9zdXJmYWNlIGRlYnVnIGNoYW5uZWwgdG8gaGF2ZSBvbmUgY2hhbm5lbCBmb3IgYWxsIHN1cmZhY2VzICovCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZF9zdXJmYWNlKTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwoZnBzKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiB4MTFfY29weV90b19zY3JlZW4KICoKICogSGVscGVyIGZ1bmN0aW9uIHRoYXQgYmx0cyB0aGUgZnJvbnQgYnVmZmVyIGNvbnRlbnRzIHRvIHRoZSB0YXJnZXQgd2luZG93CiAqCiAqIFBhcmFtczoKICogIFRoaXM6IFN1cmZhY2UgdG8gY29weSBmcm9tCiAqICByYzogUmVjdGFuZ2xlIHRvIGNvcHkKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZAp4MTFfY29weV90b19zY3JlZW4oSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywKICAgICAgICAgICAgICAgICAgIExQUkVDVCByYykKewogICAgaWYoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKQogICAgewogICAgICAgIFBPSU5UIG9mZnNldCA9IHswLDB9OwogICAgICAgIEhXTkQgaERpc3BsYXlXbmQ7CiAgICAgICAgSERDIGhEaXNwbGF5REM7CiAgICAgICAgSERDIGhTdXJmYWNlREMgPSAwOwogICAgICAgIFJFQ1QgZHJhd3JlY3Q7CiAgICAgICAgVFJBQ0UoIiglcCktPiglcCk6IENvcHlpbmcgdG8gc2NyZWVuXG4iLCBUaGlzLCByYyk7CgogICAgICAgIGhTdXJmYWNlREMgPSBUaGlzLT5oREM7CgogICAgICAgIGhEaXNwbGF5V25kID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZS0+ZGRyYXdfd2luZG93OwogICAgICAgIGhEaXNwbGF5REMgPSBHZXREQ0V4KGhEaXNwbGF5V25kLCAwLCBEQ1hfQ0xJUFNJQkxJTkdTfERDWF9DQUNIRSk7CiAgICAgICAgaWYocmMpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiIGNvcHlpbmcgcmVjdCAoJWQsJWQpLT4oJWQsJWQpLCBvZmZzZXQgKCVkLCVkKVxuIiwKICAgICAgICAgICAgcmMtPmxlZnQsIHJjLT50b3AsIHJjLT5yaWdodCwgcmMtPmJvdHRvbSwgb2Zmc2V0LngsIG9mZnNldC55KTsKICAgICAgICB9CgogICAgICAgIC8qIEZyb250IGJ1ZmZlciBjb29yZGluYXRlcyBhcmUgc2NyZWVuIGNvb3JkaW5hdGVzLiBNYXAgdGhlbSB0byB0aGUgZGVzdGluYXRpb24KICAgICAgICAgKiB3aW5kb3cgaWYgbm90IGZ1bGxzY3JlZW5lZAogICAgICAgICAqLwogICAgICAgIGlmKCFUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5kZHJhd19mdWxsc2NyZWVuKSB7CiAgICAgICAgICAgIENsaWVudFRvU2NyZWVuKGhEaXNwbGF5V25kLCAmb2Zmc2V0KTsKICAgICAgICB9CiNpZiAwCiAgICAgICAgLyogRklYTUU6IHRoaXMgZG9lc24ndCB3b3JrLi4uIGlmIHVzZXJzIHJlYWxseSB3YW50IHRvIHJ1bgogICAgICAgICogWCBpbiA4YnBwLCB0aGVuIHdlIG5lZWQgdG8gY2FsbCBkaXJlY3RseSBpbnRvIGRpc3BsYXkuZHJ2CiAgICAgICAgKiAob3IgV2luZSdzIGVxdWl2YWxlbnQpLCBhbmQgZm9yY2UgYSBwcml2YXRlIGNvbG9ybWFwCiAgICAgICAgKiB3aXRob3V0IGRlZmF1bHQgZW50cmllcy4gKi8KICAgICAgICBpZiAoVGhpcy0+cGFsZXR0ZSkgewogICAgICAgICAgICBTZWxlY3RQYWxldHRlKGhEaXNwbGF5REMsIFRoaXMtPnBhbGV0dGUtPmhwYWwsIEZBTFNFKTsKICAgICAgICAgICAgUmVhbGl6ZVBhbGV0dGUoaERpc3BsYXlEQyk7IC8qIHNlbmRzIG1lc3NhZ2VzID0+IGRlYWRsb2NrcyAqLwogICAgICAgIH0KI2VuZGlmCiAgICAgICAgZHJhd3JlY3QubGVmdAk9IDA7CiAgICAgICAgZHJhd3JlY3QucmlnaHQJPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBkcmF3cmVjdC50b3AJPSAwOwogICAgICAgIGRyYXdyZWN0LmJvdHRvbQk9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKCiNpZiAwCiAgICAgICAgLyogVE9ETzogU3VwcG9ydCBjbGlwcGVycyAqLwogICAgICAgIGlmIChUaGlzLT5jbGlwcGVyKQogICAgICAgIHsKICAgICAgICAgICAgUkVDVCB4cmM7CiAgICAgICAgICAgIEhXTkQgaHduZCA9ICgoSVdpbmVEM0RDbGlwcGVySW1wbCAqKSBUaGlzLT5jbGlwcGVyKS0+aFduZDsKICAgICAgICAgICAgaWYgKGh3bmQgJiYgR2V0Q2xpZW50UmVjdChod25kLCZ4cmMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBPZmZzZXRSZWN0KCZ4cmMsb2Zmc2V0Lngsb2Zmc2V0LnkpOwogICAgICAgICAgICAgICAgSW50ZXJzZWN0UmVjdCgmZHJhd3JlY3QsJmRyYXdyZWN0LCZ4cmMpOwogICAgICAgICAgICB9CiAgICAgICAgfQojZW5kaWYKICAgICAgICBpZiAocmMpCiAgICAgICAgewogICAgICAgICAgICBJbnRlcnNlY3RSZWN0KCZkcmF3cmVjdCwmZHJhd3JlY3QscmMpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBPbmx5IHVzZSB0aGlzIGlmIHRoZSBjYWxsZXIgZGlkIG5vdCBwYXNzIGEgcmVjdGFuZ2xlLCBzaW5jZQogICAgICAgICAgICAgKiBkdWUgdG8gZG91YmxlIGxvY2tpbmcgdGhpcyBjb3VsZCBiZSB0aGUgd3Jvbmcgb25lIC4uLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKFRoaXMtPmxvY2tlZFJlY3QubGVmdCAhPSBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJbnRlcnNlY3RSZWN0KCZkcmF3cmVjdCwmZHJhd3JlY3QsJlRoaXMtPmxvY2tlZFJlY3QpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBCaXRCbHQoaERpc3BsYXlEQywKICAgICAgICAgICAgICAgZHJhd3JlY3QubGVmdC1vZmZzZXQueCwgZHJhd3JlY3QudG9wLW9mZnNldC55LAogICAgICAgICAgICAgICBkcmF3cmVjdC5yaWdodC1kcmF3cmVjdC5sZWZ0LCBkcmF3cmVjdC5ib3R0b20tZHJhd3JlY3QudG9wLAogICAgICAgICAgICAgICBoU3VyZmFjZURDLAogICAgICAgICAgICAgICBkcmF3cmVjdC5sZWZ0LCBkcmF3cmVjdC50b3AsCiAgICAgICAgICAgICAgIFNSQ0NPUFkpOwogICAgICAgIFJlbGVhc2VEQyhoRGlzcGxheVduZCwgaERpc3BsYXlEQyk7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OlJlbGVhc2UsIEdESSB2ZXJzaW9uCiAqCiAqIEluIGdlbmVyYWwgYSBub3JtYWwgQ09NIFJlbGVhc2UgbWV0aG9kLCBidXQgdGhlIEdESSB2ZXJzaW9uIGRvZXNuJ3QgaGF2ZQogKiB0byBkZXN0cm95IGFsbCB0aGUgR0wgdGhpbmdzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovClVMT05HIFdJTkFQSSBJV2luZUdESVN1cmZhY2VJbXBsX1JlbGVhc2UoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVzb3VyY2UucmVmKTsKICAgIFRSQUNFKCIoJXApIDogUmVsZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIHJlZiArIDEpOwogICAgaWYgKHJlZiA9PSAwKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBjbGVhbmluZyB1cFxuIiwgVGhpcyk7CgogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfRElCU0VDVElPTikgewogICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBEQyAqLwogICAgICAgICAgICBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgICAgIERlbGV0ZURDKFRoaXMtPmhEQyk7CiAgICAgICAgICAgIC8qIFJlbGVhc2UgdGhlIERJQiBzZWN0aW9uICovCiAgICAgICAgICAgIERlbGV0ZU9iamVjdChUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgICAgIFRoaXMtPmRpYi5iaXRtYXBfZGF0YSA9IE5VTEw7CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikgSVdpbmVEM0RTdXJmYWNlX1NldE1lbShpZmFjZSwgTlVMTCk7CgogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnBhbGV0dGU5KTsKCiAgICAgICAgSVdpbmVEM0RSZXNvdXJjZUltcGxfQ2xlYW5VcCgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlKTsKICAgICAgICBpZihpZmFjZSA9PSBkZXZpY2UtPmRkcmF3X3ByaW1hcnkpCiAgICAgICAgICAgIGRldmljZS0+ZGRyYXdfcHJpbWFyeSA9IE5VTEw7CgogICAgICAgIFRSQUNFKCIoJXApIFJlbGVhc2VkXG4iLCBUaGlzKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKCiAgICB9CiAgICByZXR1cm4gcmVmOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpQcmVMb2FkLCBHREkgdmVyc2lvbgogKgogKiBUaGlzIGNhbGwgaXMgdW5zdXBwb3J0ZWQgb24gR0RJIHN1cmZhY2VzLCBpZiBpdCdzIGNhbGxlZCBzb21ldGhpbmcgd2VudAogKiB3cm9uZyBpbiB0aGUgcGFyZW50IGxpYnJhcnkuIFdyaXRlIGFuIGluZm9ybWF0aXZlIHdhcm5pbmcKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9QcmVMb2FkKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpCnsKICAgIEVSUigiKCVwKTogUHJlTG9hZCBpcyBub3Qgc3VwcG9ydGVkIG9uIFgxMSBzdXJmYWNlcyFcbiIsIGlmYWNlKTsKICAgIEVSUigiKCVwKTogTW9zdCBsaWtlbHkgdGhlIHBhcmVudCBsaWJyYXJ5IGRpZCBzb21ldGhpbmcgd3JvbmcuXG4iLCBpZmFjZSk7CiAgICBFUlIoIiglcCk6IFBsZWFzZSByZXBvcnQgdG8gd2luZS1kZXZlbFxuIiwgaWZhY2UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpMb2NrUmVjdCwgR0RJIHZlcnNpb24KICoKICogTG9ja3MgdGhlIHN1cmZhY2UgYW5kIHJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBzdXJmYWNlIG1lbW9yeQogKgogKiBQYXJhbXM6CiAqICBwTG9ja2VkUmVjdDogQWRkcmVzcyB0byByZXR1cm4gdGhlIGxvY2tpbmcgaW5mbyBhdAogKiAgcFJlY3Q6IFJlY3RhbmdsZSB0byBsb2NrCiAqICBGbGFnczogU29tZSBmbGFncwogKgogKiBSZXR1cm5zOgogKiAgV0lORUQzRF9PSyBvbiBzdWNjZXNzCiAqICBXSU5FRDNERVJSX0lOVkFMSURDQUxMIG9uIGVycm9ycwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJV2luZUdESVN1cmZhY2VJbXBsX0xvY2tSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRExPQ0tFRF9SRUNUKiBwTG9ja2VkUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05TVCBSRUNUKiBwUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgLyogQWxyZWFkeSBsb2NrZWQ/ICovCiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkKICAgIHsKICAgICAgICBFUlIoIiglcCkgU3VyZmFjZSBhbHJlYWR5IGxvY2tlZFxuIiwgVGhpcyk7CiAgICAgICAgLyogV2hhdCBzaG91bGQgSSByZXR1cm4gaGVyZT8gKi8KICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0xPQ0tFRDsKCiAgICBpZighVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgLyogVGhpcyBoYXBwZW5zIG9uIGdkaSBzdXJmYWNlcyBpZiB0aGUgYXBwbGljYXRpb24gc2V0IGEgdXNlciBwb2ludGVyIGFuZCByZXNldHMgaXQuCiAgICAgICAgICogUmVjcmVhdGUgdGhlIERJQiBzZWN0aW9uCiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfQ3JlYXRlRElCU2VjdGlvbihpZmFjZSk7CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gVGhpcy0+ZGliLmJpdG1hcF9kYXRhOwogICAgfQoKICAgIHJldHVybiBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9Mb2NrUmVjdChpZmFjZSwgcExvY2tlZFJlY3QsIHBSZWN0LCBGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OlVubG9ja1JlY3QsIEdESSB2ZXJzaW9uCiAqCiAqIFVubG9ja3MgYSBzdXJmYWNlLiBUaGlzIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgZG8gbXVjaCwgZXhjZXB0IHVwZGF0aW5nCiAqIHRoZSB3aW5kb3cgaWYgdGhlIGZyb250IGJ1ZmZlciBpcyB1bmxvY2tlZAogKgogKiBSZXR1cm5zOgogKiAgV0lORUQzRF9PSyBvbiBzdWNjZXNzCiAqICBXSU5FRDNERVJSX0lOVkFMSURDQUxMIG9uIGZhaWx1cmUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9VbmxvY2tSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXYgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpKQogICAgewogICAgICAgIFdBUk4oInRyeWluZyB0byBVbmxvY2sgYW4gdW5sb2NrZWQgc3VyZkAlcFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogQ2FuIGJlIHVzZWZ1bCBmb3IgZGVidWdnaW5nICovCiNpZiAwCiAgICAgICAgewogICAgICAgICAgICBzdGF0aWMgdW5zaWduZWQgaW50IGdlbiA9IDA7CiAgICAgICAgICAgIGNoYXIgYnVmZmVyWzQwOTZdOwogICAgICAgICAgICArK2dlbjsKICAgICAgICAgICAgaWYgKChnZW4gJSAxMCkgPT0gMCkgewogICAgICAgICAgICAgICAgc25wcmludGYoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgIi90bXAvc3VyZmFjZSVwX3R5cGUldV9sZXZlbCV1XyV1LnBwbSIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBnZW4pOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QoaWZhY2UsIGJ1ZmZlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogZGVidWdnaW5nIGNyYXNoIGNvZGUKICAgICAgICAgICAgaWYgKGdlbiA9PSAyNTApIHsKICAgICAgICAgICAgICB2b2lkKiogdGVzdCA9IE5VTEw7CiAgICAgICAgICAgICAgKnRlc3QgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgICovCiAgICAgICAgfQojZW5kaWYKCiAgICAvKiBVcGRhdGUgdGhlIHNjcmVlbiAqLwogICAgaWYoVGhpcyA9PSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBkZXYtPmRkcmF3X3ByaW1hcnkpCiAgICB7CiAgICAgICAgeDExX2NvcHlfdG9fc2NyZWVuKFRoaXMsICZUaGlzLT5sb2NrZWRSZWN0KTsKICAgIH0KCiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfTE9DS0VEOwogICAgbWVtc2V0KCZUaGlzLT5sb2NrZWRSZWN0LCAwLCBzaXplb2YoUkVDVCkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OkZsaXAsIEdESSB2ZXJzaW9uCiAqCiAqIEZsaXBzIDIgZmxpcHBpbmcgZW5hYmxlZCBzdXJmYWNlcy4gRGV0ZXJtaW5pbmcgdGhlIDIgdGFyZ2V0cyBpcyBkb25lIGJ5CiAqIHRoZSBwYXJlbnQgbGlicmFyeS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBjaGFuZ2VzIHRoZSBkYXRhIHBvaW50ZXJzIG9mIHRoZQogKiBzdXJmYWNlcyBhbmQgY29waWVzIHRoZSBuZXcgZnJvbnQgYnVmZmVyIGNvbnRlbnQgdG8gdGhlIHNjcmVlbgogKgogKiBQYXJhbXM6CiAqICBvdmVycmlkZTogRmxpcHBpbmcgdGFyZ2V0KGUuZy4gYmFjayBidWZmZXIpCiAqCiAqIFJldHVybnM6CiAqICBXSU5FRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9GbGlwKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKm92ZXJyaWRlLAogICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRhcmdldCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIG92ZXJyaWRlOwogICAgVFJBQ0UoIiglcCktPiglcCwleClcbiIsIFRoaXMsIG92ZXJyaWRlLCBGbGFncyk7CgogICAgVFJBQ0UoIiglcCkgRmxpcHBpbmcgdG8gc3VyZmFjZSAlcFxuIiwgVGhpcywgVGFyZ2V0KTsKCiAgICBpZihUYXJnZXQgPT0gTlVMTCkKICAgIHsKICAgICAgICBFUlIoIiglcCk6IENhbid0IGZsaXAgd2l0aG91dCBhIHRhcmdldFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogRmxpcCB0aGUgREMgKi8KICAgIHsKICAgICAgICBIREMgdG1wOwogICAgICAgIHRtcCA9IFRoaXMtPmhEQzsKICAgICAgICBUaGlzLT5oREMgPSBUYXJnZXQtPmhEQzsKICAgICAgICBUYXJnZXQtPmhEQyA9IHRtcDsKICAgIH0KCiAgICAvKiBGbGlwIHRoZSBESUJzZWN0aW9uICovCiAgICB7CiAgICAgICAgSEJJVE1BUCB0bXA7CiAgICAgICAgdG1wID0gVGhpcy0+ZGliLkRJQnNlY3Rpb247CiAgICAgICAgVGhpcy0+ZGliLkRJQnNlY3Rpb24gPSBUYXJnZXQtPmRpYi5ESUJzZWN0aW9uOwogICAgICAgIFRhcmdldC0+ZGliLkRJQnNlY3Rpb24gPSB0bXA7CiAgICB9CgogICAgLyogRmxpcCB0aGUgc3VyZmFjZSBkYXRhICovCiAgICB7CiAgICAgICAgdm9pZCogdG1wOwoKICAgICAgICB0bXAgPSBUaGlzLT5kaWIuYml0bWFwX2RhdGE7CiAgICAgICAgVGhpcy0+ZGliLmJpdG1hcF9kYXRhID0gVGFyZ2V0LT5kaWIuYml0bWFwX2RhdGE7CiAgICAgICAgVGFyZ2V0LT5kaWIuYml0bWFwX2RhdGEgPSB0bXA7CgogICAgICAgIHRtcCA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBUYXJnZXQtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICBUYXJnZXQtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IHRtcDsKCiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UuaGVhcE1lbW9yeSkgewogICAgICAgICAgICBFUlIoIkdESSBTdXJmYWNlICVwIGhhcyBoZWFwIG1lbW9yeSBhbGxvY2F0ZWRcbiIsIFRoaXMpOwogICAgICAgIH0KICAgICAgICBpZihUYXJnZXQtPnJlc291cmNlLmhlYXBNZW1vcnkpIHsKICAgICAgICAgICAgRVJSKCJHREkgU3VyZmFjZSAlcCBoYXMgaGVhcCBtZW1vcnkgYWxsb2NhdGVkXG4iLCBUYXJnZXQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBjbGllbnRfbWVtb3J5IHNob3VsZCBub3QgYmUgZGlmZmVyZW50LCBidXQganVzdCBpbiBjYXNlICovCiAgICB7CiAgICAgICAgQk9PTCB0bXA7CiAgICAgICAgdG1wID0gVGhpcy0+ZGliLmNsaWVudF9tZW1vcnk7CiAgICAgICAgVGhpcy0+ZGliLmNsaWVudF9tZW1vcnkgPSBUYXJnZXQtPmRpYi5jbGllbnRfbWVtb3J5OwogICAgICAgIFRhcmdldC0+ZGliLmNsaWVudF9tZW1vcnkgPSB0bXA7CiAgICB9CgogICAgLyogVXNlZnVsIGZvciBkZWJ1Z2dpbmcgKi8KI2lmIDAKICAgICAgICB7CiAgICAgICAgICAgIHN0YXRpYyB1bnNpZ25lZCBpbnQgZ2VuID0gMDsKICAgICAgICAgICAgY2hhciBidWZmZXJbNDA5Nl07CiAgICAgICAgICAgICsrZ2VuOwogICAgICAgICAgICBpZiAoKGdlbiAlIDEwKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBzbnByaW50ZihidWZmZXIsIHNpemVvZihidWZmZXIpLCAiL3RtcC9zdXJmYWNlJXBfdHlwZSV1X2xldmVsJXVfJXUucHBtIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGdlbik7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdChpZmFjZSwgYnVmZmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBkZWJ1Z2dpbmcgY3Jhc2ggY29kZQogICAgICAgICAgICBpZiAoZ2VuID09IDI1MCkgewogICAgICAgICAgICAgIHZvaWQqKiB0ZXN0ID0gTlVMTDsKICAgICAgICAgICAgICAqdGVzdCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKi8KICAgICAgICB9CiNlbmRpZgoKICAgIC8qIFVwZGF0ZSB0aGUgc2NyZWVuICovCiAgICB4MTFfY29weV90b19zY3JlZW4oVGhpcywgTlVMTCk7CgogICAgLyogRlBTIHN1cHBvcnQgKi8KICAgIGlmIChUUkFDRV9PTihmcHMpKQogICAgewogICAgICAgIHN0YXRpYyBsb25nIHByZXZfdGltZSwgZnJhbWVzOwoKICAgICAgICBEV09SRCB0aW1lID0gR2V0VGlja0NvdW50KCk7CiAgICAgICAgZnJhbWVzKys7CiAgICAgICAgLyogZXZlcnkgMS41IHNlY29uZHMgKi8KICAgICAgICBpZiAodGltZSAtIHByZXZfdGltZSA+IDE1MDApIHsKICAgICAgICAgICAgVFJBQ0VfKGZwcykoIkAgYXBwcm94ICUuMmZmcHNcbiIsIDEwMDAuMCpmcmFtZXMvKHRpbWUgLSBwcmV2X3RpbWUpKTsKICAgICAgICAgICAgcHJldl90aW1lID0gdGltZTsKICAgICAgICAgICAgZnJhbWVzID0gMDsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OkxvYWRUZXh0dXJlLCBHREkgdmVyc2lvbgogKgogKiBUaGlzIGlzIG11dHVhbGx5IHVuc3VwcG9ydGVkIGJ5IEdESSBzdXJmYWNlcwogKgogKiBSZXR1cm5zOgogKiAgRDNERVJSX0lOVkFMSURDQUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9Mb2FkVGV4dHVyZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBCT09MIHNyZ2JfbW9kZSkKewogICAgRVJSKCJVbnN1cHBvcnRlZCBvbiBYMTEgc3VyZmFjZXNcbiIpOwogICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OlNhdmVTbmFwc2hvdCwgR0RJIHZlcnNpb24KICoKICogVGhpcyBtZXRob2Qgd3JpdGVzIHRoZSBzdXJmYWNlJ3MgY29udGVudHMgdG8gdGhlIGluIHRnYSBmb3JtYXQgdG8gdGhlCiAqIGZpbGUgc3BlY2lmaWVkIGluIGZpbGVuYW1lLgogKgogKiBQYXJhbXM6CiAqICBmaWxlbmFtZTogRmlsZSB0byB3cml0ZSB0bwogKgogKiBSZXR1cm5zOgogKiAgV0lORUQzREVSUl9JTlZBTElEQ0FMTCBpZiB0aGUgZmlsZSBjb3VsZG4ndCBiZSBvcGVuZWQKICogIFdJTkVEM0RfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBpbnQgZ2V0X3NoaWZ0KERXT1JEIGNvbG9yX21hc2spIHsKICAgIGludCBzaGlmdCA9IDA7CiAgICB3aGlsZSAoY29sb3JfbWFzayA+IDB4RkYpIHsKICAgICAgICBjb2xvcl9tYXNrID4+PSAxOwogICAgICAgIHNoaWZ0ICs9IDE7CiAgICB9CiAgICB3aGlsZSAoKGNvbG9yX21hc2sgJiAweDgwKSA9PSAwKSB7CiAgICAgICAgY29sb3JfbWFzayA8PD0gMTsKICAgICAgICBzaGlmdCAtPSAxOwogICAgfQogICAgcmV0dXJuIHNoaWZ0Owp9CgoKSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwKY29uc3QgY2hhciogZmlsZW5hbWUpCnsKICAgIEZJTEUqIGYgPSBOVUxMOwogICAgVUlOVCB5ID0gMCwgeCA9IDA7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBjaGFyICpvdXRwdXQgPSBOVUxMOwogICAgc3RhdGljIGludCBzaXplID0gMDsKICAgIGNvbnN0IFN0YXRpY1BpeGVsRm9ybWF0RGVzYyAqZm9ybWF0RW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoVGhpcy0+cmVzb3VyY2UuZm9ybWF0LCBOVUxMLCBOVUxMKTsKCiAgICBpZiAoVGhpcy0+cG93MldpZHRoID4gc2l6ZSkgewogICAgICAgIG91dHB1dCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5wb3cyV2lkdGggKiAzKTsKICAgICAgICBzaXplID0gVGhpcy0+cG93MldpZHRoOwogICAgfQoKCiAgICBmID0gZm9wZW4oZmlsZW5hbWUsICJ3KyIpOwogICAgaWYgKE5VTEwgPT0gZikgewogICAgICAgIEVSUigib3BlbmluZyBvZiAlcyBmYWlsZWQgd2l0aFxuIiwgZmlsZW5hbWUpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgZnByaW50ZihmLCAiUDZcbiVkICVkXG4yNTVcbiIsIFRoaXMtPnBvdzJXaWR0aCwgVGhpcy0+cG93MkhlaWdodCk7CgogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4KSB7CiAgICAgICAgdW5zaWduZWQgY2hhciB0YWJsZVsyNTZdWzNdOwogICAgICAgIGludCBpOwoKICAgICAgICBpZiAoVGhpcy0+cGFsZXR0ZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIGZjbG9zZShmKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICB0YWJsZVtpXVswXSA9IFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbaV0ucGVSZWQ7CiAgICAgICAgICAgIHRhYmxlW2ldWzFdID0gVGhpcy0+cGFsZXR0ZS0+cGFsZW50c1tpXS5wZUdyZWVuOwogICAgICAgICAgICB0YWJsZVtpXVsyXSA9IFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbaV0ucGVCbHVlOwogICAgICAgIH0KICAgICAgICBmb3IgKHkgPSAwOyB5IDwgVGhpcy0+cG93MkhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKnNyYyA9ICh1bnNpZ25lZCBjaGFyICopIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArICh5ICogMSAqIElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSkpOwogICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgVGhpcy0+cG93MldpZHRoOyB4KyspIHsKICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgY29sb3IgPSAqc3JjOwogICAgICAgICAgICAgICAgc3JjICs9IDE7CgogICAgICAgICAgICAgICAgb3V0cHV0WzMgKiB4ICsgMF0gPSB0YWJsZVtjb2xvcl1bMF07CiAgICAgICAgICAgICAgICBvdXRwdXRbMyAqIHggKyAxXSA9IHRhYmxlW2NvbG9yXVsxXTsKICAgICAgICAgICAgICAgIG91dHB1dFszICogeCArIDJdID0gdGFibGVbY29sb3JdWzJdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZ3cml0ZShvdXRwdXQsIDMgKiBUaGlzLT5wb3cyV2lkdGgsIDEsIGYpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgaW50IHJlZF9zaGlmdCwgZ3JlZW5fc2hpZnQsIGJsdWVfc2hpZnQsIHBpeF93aWR0aDsKCiAgICAgICAgcGl4X3dpZHRoID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbDsKCiAgICAgICAgcmVkX3NoaWZ0ID0gZ2V0X3NoaWZ0KGZvcm1hdEVudHJ5LT5yZWRNYXNrKTsKICAgICAgICBncmVlbl9zaGlmdCA9IGdldF9zaGlmdChmb3JtYXRFbnRyeS0+Z3JlZW5NYXNrKTsKICAgICAgICBibHVlX3NoaWZ0ID0gZ2V0X3NoaWZ0KGZvcm1hdEVudHJ5LT5ibHVlTWFzayk7CgogICAgICAgIGZvciAoeSA9IDA7IHkgPCBUaGlzLT5wb3cySGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqc3JjID0gKHVuc2lnbmVkIGNoYXIgKikgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgKHkgKiAxICogSVdpbmVEM0RTdXJmYWNlX0dldFBpdGNoKGlmYWNlKSk7CiAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCBUaGlzLT5wb3cyV2lkdGg7IHgrKykgewkgICAgCiAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgY29sb3I7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgY29tcDsKICAgICAgICAgICAgICAgIGludCBpOwoKICAgICAgICAgICAgICAgIGNvbG9yID0gMDsKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBwaXhfd2lkdGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIGNvbG9yIHw9IHNyY1tpXSA8PCAoOCAqIGkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc3JjICs9IDEgKiBwaXhfd2lkdGg7CgogICAgICAgICAgICAgICAgY29tcCA9IGNvbG9yICYgZm9ybWF0RW50cnktPnJlZE1hc2s7CiAgICAgICAgICAgICAgICBvdXRwdXRbMyAqIHggKyAwXSA9IHJlZF9zaGlmdCA+IDAgPyBjb21wID4+IHJlZF9zaGlmdCA6IGNvbXAgPDwgLXJlZF9zaGlmdDsKICAgICAgICAgICAgICAgIGNvbXAgPSBjb2xvciAmIGZvcm1hdEVudHJ5LT5ncmVlbk1hc2s7CiAgICAgICAgICAgICAgICBvdXRwdXRbMyAqIHggKyAxXSA9IGdyZWVuX3NoaWZ0ID4gMCA/IGNvbXAgPj4gZ3JlZW5fc2hpZnQgOiBjb21wIDw8IC1ncmVlbl9zaGlmdDsKICAgICAgICAgICAgICAgIGNvbXAgPSBjb2xvciAmIGZvcm1hdEVudHJ5LT5ibHVlTWFzazsKICAgICAgICAgICAgICAgIG91dHB1dFszICogeCArIDJdID0gYmx1ZV9zaGlmdCA+IDAgPyBjb21wID4+IGJsdWVfc2hpZnQgOiBjb21wIDw8IC1ibHVlX3NoaWZ0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZ3cml0ZShvdXRwdXQsIDMgKiBUaGlzLT5wb3cyV2lkdGgsIDEsIGYpOwogICAgICAgIH0KICAgIH0KICAgIGZjbG9zZShmKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUdESVN1cmZhY2VJbXBsX0dldERDKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIEhEQyAqcEhEQykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBXSU5FRDNETE9DS0VEX1JFQ1QgbG9jazsKICAgIEhSRVNVTFQgaHI7CiAgICBSR0JRVUFEIGNvbFsyNTZdOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMscEhEQyk7CgogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19VU0VSUFRSKSB7CiAgICAgICAgRVJSKCJOb3Qgc3VwcG9ydGVkIG9uIHN1cmZhY2VzIHdpdGggYW4gYXBwbGljYXRpb24tcHJvdmlkZWQgc3VyZmFjZXNcbiIpOwogICAgICAgIHJldHVybiBXSU5FRERFUlJfTk9EQzsKICAgIH0KCiAgICAvKiBHaXZlIG1vcmUgZGV0YWlsZWQgaW5mbyBmb3IgZGRyYXcgKi8KICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0RDSU5VU0UpCiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9EQ0FMUkVBRFlDUkVBVEVEOwoKICAgIC8qIENhbid0IEdldERDIGlmIHRoZSBzdXJmYWNlIGlzIGxvY2tlZCAqLwogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbXNldCgmbG9jaywgMCwgc2l6ZW9mKGxvY2spKTsgLyogVG8gYmUgc3VyZSAqLwoKICAgIC8qIFNob3VsZCBoYXZlIGEgRElCIHNlY3Rpb24gYWxyZWFkeSAqLwoKICAgIC8qIExvY2sgdGhlIHN1cmZhY2UgKi8KICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmxvY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCk7CiAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgRVJSKCJJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QgZmFpbGVkIHdpdGggaHIgPSAlMDh4XG4iLCBocik7CiAgICAgICAgLyoga2VlcCB0aGUgZGliIHNlY3Rpb24gKi8KICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgaWYoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggfHwKICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0E4UDgpIHsKICAgICAgICB1bnNpZ25lZCBpbnQgbjsKICAgICAgICBpZihUaGlzLT5wYWxldHRlKSB7CiAgICAgICAgICAgIFBBTEVUVEVFTlRSWSBlbnRbMjU2XTsKCiAgICAgICAgICAgIEdldFBhbGV0dGVFbnRyaWVzKFRoaXMtPnBhbGV0dGUtPmhwYWwsIDAsIDI1NiwgZW50KTsKICAgICAgICAgICAgZm9yIChuPTA7IG48MjU2OyBuKyspIHsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IGVudFtuXS5wZVJlZDsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IGVudFtuXS5wZUdyZWVuOwogICAgICAgICAgICAgICAgY29sW25dLnJnYkJsdWUgID0gZW50W25dLnBlQmx1ZTsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZXNlcnZlZCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgICAgICAgICBmb3IgKG49MDsgbjwyNTY7IG4rKykgewogICAgICAgICAgICAgICAgY29sW25dLnJnYlJlZCAgID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtuXS5wZVJlZDsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVHcmVlbjsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JCbHVlICA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVCbHVlOwogICAgICAgICAgICAgICAgY29sW25dLnJnYlJlc2VydmVkID0gMDsKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgU2V0RElCQ29sb3JUYWJsZShUaGlzLT5oREMsIDAsIDI1NiwgY29sKTsKICAgIH0KCiAgICAqcEhEQyA9IFRoaXMtPmhEQzsKICAgIFRSQUNFKCJyZXR1cm5pbmcgJXBcbiIsKnBIREMpOwogICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfRENJTlVTRTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVHRElTdXJmYWNlSW1wbF9SZWxlYXNlREMoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSERDIGhEQykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxoREMpOwoKICAgIGlmICghKFRoaXMtPkZsYWdzICYgU0ZMQUdfRENJTlVTRSkpCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgaWYgKFRoaXMtPmhEQyAhPWhEQykgewogICAgICAgIFdBUk4oIkFwcGxpY2F0aW9uIHRyaWVzIHRvIHJlbGVhc2UgYW4gaW52YWxpZCBEQyglcCksIHN1cmZhY2UgZGMgaXMgJXBcbiIsIGhEQywgVGhpcy0+aERDKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAvKiB3ZSBsb2NrZWQgZmlyc3QsIHNvIHVubG9jayBub3cgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KGlmYWNlKTsKCiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfRENJTlVTRTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6UHJpdmF0ZVNldHVwLCBHREkgdmVyc2lvbgogKgogKiBJbml0aWFsaXplcyB0aGUgR0RJIHN1cmZhY2UsIGFrYSBjcmVhdGVzIHRoZSBESUIgc2VjdGlvbiB3ZSByZW5kZXIgdG8KICogVGhlIERJQiBzZWN0aW9uIGNyZWF0aW9uIGlzIGRvbmUgYnkgY2FsbGluZyBHZXREQywgd2hpY2ggd2lsbCBjcmVhdGUgdGhlCiAqIHNlY3Rpb24gYW5kIHJlbGVhc2luZyB0aGUgZGMgdG8gYWxsb3cgdGhlIGFwcCB0byB1c2UgaXQuIFRoZSBkaWIgc2VjdGlvbgogKiB3aWxsIHN0YXkgdW50aWwgdGhlIHN1cmZhY2UgaXMgcmVsZWFzZWQKICoKICogR0RJIHN1cmZhY2VzIGRvIG5vdCBuZWVkIHRvIGJlIGEgcG93ZXIgb2YgMiBpbiBzaXplLCBzbyB0aGUgcG93MiBzaXplcwogKiBhcmUgc2V0IHRvIHRoZSByZWFsIHNpemVzIHRvIHNhdmUgbWVtb3J5LiBUaGUgTk9OUE9XMiBmbGFnIGlzIHVuc2V0IHRvCiAqIGF2b2lkIGNvbmZ1c2lvbiBpbiB0aGUgc2hhcmVkIHN1cmZhY2UgY29kZS4KICoKICogUmV0dXJuczoKICogIFdJTkVEM0RfT0sgb24gc3VjY2VzcwogKiAgVGhlIHJldHVybiB2YWx1ZXMgb2YgY2FsbGVkIG1ldGhvZHMgb24gZmFpbHVyZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCklXaW5lR0RJU3VyZmFjZUltcGxfUHJpdmF0ZVNldHVwKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKCiAgICBpZihUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9PVkVSTEFZKQogICAgewogICAgICAgIEVSUigiKCVwKSBPdmVybGF5cyBub3QgeWV0IHN1cHBvcnRlZCBieSBHREkgc3VyZmFjZXNcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgLyogU3lzbWVtIHRleHR1cmVzIGhhdmUgbWVtb3J5IGFscmVhZHkgYWxsb2NhdGVkIC0KICAgICAqIHJlbGVhc2UgaXQsIHRoaXMgYXZvaWRzIGFuIHVubmVjZXNzYXJ5IG1lbWNweQogICAgICovCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5KTsKICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5ID0gTlVMTDsKCiAgICAvKiBXZSBkb24ndCBtaW5kIHRoZSBub25wb3cyIHN0dWZmIGluIEdESSAqLwogICAgVGhpcy0+cG93MldpZHRoID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICBUaGlzLT5wb3cySGVpZ2h0ID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwoKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0NyZWF0ZURJQlNlY3Rpb24oaWZhY2UpOwogICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gVGhpcy0+ZGliLmJpdG1hcF9kYXRhOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9Cgp2b2lkIFdJTkFQSSBJV2luZUdESVN1cmZhY2VJbXBsX1NldEdsVGV4dHVyZURlc2MoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgVUlOVCB0ZXh0dXJlTmFtZSwgaW50IHRhcmdldCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgLyogSWdub3JlIDAgdGV4dHVyZU5hbWUgYW5kIHRhcmdldC4gRDNEIHRleHR1cmVzIGNhbiBiZSBjcmVhdGVkIHdpdGggZ2RpIHN1cmZhY2VzIGFzIHBsYWluCiAgICAgKiBjb250YWluZXJzLCBidXQgdGhleSdyZSB1c2VsZXNzIHVudGlsIHRoZSBhcHAgY3JlYXRlcyBhIGQzZCBkZXZpY2UgZnJvbSBhIGQzZCBwb2ludCBvZgogICAgICogdmlldywgaXQncyBub3QgYW4gaW1wbGVtZW50YXRpb24gbGltaXRhdGlvbi4gVGhpcyBhdm9pZHMgZmFsc2Ugd2FybmluZ3Mgd2hlbiB0aGUgdGV4dHVyZQogICAgICogaXMgZGVzdHJveWVkIGFuZCBzZXRzIHRoZSBkZXNjcmlwdGlvbiBiYWNrIHRvIDAvMAogICAgICovCiAgICBpZih0ZXh0dXJlTmFtZSAhPSAwIHx8IHRhcmdldCAhPSAwKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBTaG91bGQgbm90IGJlIGNhbGxlZCBvbiBhIEdESSBzdXJmYWNlLiB0ZXh0dXJlTmFtZSAldSwgdGFyZ2V0ICVpXG4iLCBUaGlzLCB0ZXh0dXJlTmFtZSwgdGFyZ2V0KTsKICAgICAgICBEZWJ1Z0JyZWFrKCk7CiAgICB9Cn0KCnZvaWQgV0lOQVBJIElXaW5lR0RJU3VyZmFjZUltcGxfR2V0R2xEZXNjKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIGdsRGVzY3JpcHRvciAqKmdsRGVzY3JpcHRpb24pIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgRklYTUUoIiglcCkgOiBTaG91bGQgbm90IGJlIGNhbGxlZCBvbiBhIEdESSBzdXJmYWNlXG4iLCBUaGlzKTsKICAgICpnbERlc2NyaXB0aW9uID0gTlVMTDsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVHRElTdXJmYWNlSW1wbF9BZGREaXJ0eVJlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgQ09OU1QgUkVDVCogcERpcnR5UmVjdCkgewogICAgLyogR0RJIHN1cmZhY2UgZGF0YSBjYW4gb25seSBiZSBpbiBvbmUgbG9jYXRpb24sIHRoZSBzeXN0ZW0gbWVtb3J5IGRpYiBzZWN0aW9uLiBTbyB0aGV5IGFyZQogICAgICogYWx3YXlzIGNsZWFuIGJ5IGRlZmluaXRpb24uCiAgICAgKi8KICAgIFRSQUNFKCJObyBkaXJ0aWZpY2F0aW9uIGluIEdESSBzdXJmYWNlc1xuIik7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVHRElTdXJmYWNlSW1wbF9TZXRNZW0oSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgdm9pZCAqTWVtKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CgogICAgLyogUmVuZGVyIHRhcmdldHMgZGVwZW5kIG9uIHRoZWlyIGhkYywgYW5kIHdlIGNhbid0IGNyZWF0ZSBhbiBoZGMgb24gYSB1c2VyIHBvaW50ZXIgKi8KICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgIEVSUigiTm90IHN1cHBvcnRlZCBvbiByZW5kZXIgdGFyZ2V0c1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoVGhpcy0+RmxhZ3MgJiAoU0ZMQUdfTE9DS0VEIHwgU0ZMQUdfRENJTlVTRSkpIHsKICAgICAgICBXQVJOKCJTdXJmYWNlIGlzIGxvY2tlZCBvciB0aGUgSERDIGlzIGluIHVzZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoTWVtICYmIE1lbSAhPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpIHsKICAgICAgICB2b2lkICpyZWxlYXNlID0gTlVMTDsKCiAgICAgICAgLyogRG8gSSBoYXZlIHRvIGNvcHkgdGhlIG9sZCBzdXJmYWNlIGNvbnRlbnQ/ICovCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBEQy4gTm8gbmVlZCB0byBob2xkIHRoZSBjcml0aWNhbCBzZWN0aW9uIGZvciB0aGUgdXBkYXRlCiAgICAgICAgICAgICogVGhyZWFkIGJlY2F1c2UgdGhpcyB0aHJlYWQgcnVucyBvbmx5IG9uIGZyb250IGJ1ZmZlcnMsIGJ1dCB0aGlzIG1ldGhvZAogICAgICAgICAgICAqIGZhaWxzIGZvciByZW5kZXIgdGFyZ2V0cyBpbiB0aGUgY2hlY2sgYWJvdmUuCiAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgICAgIERlbGV0ZURDKFRoaXMtPmhEQyk7CiAgICAgICAgICAgIC8qIFJlbGVhc2UgdGhlIERJQiBzZWN0aW9uICovCiAgICAgICAgICAgIERlbGV0ZU9iamVjdChUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgICAgIFRoaXMtPmRpYi5iaXRtYXBfZGF0YSA9IE5VTEw7CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgICAgIFRoaXMtPmhEQyA9IE5VTEw7CiAgICAgICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19ESUJTRUNUSU9OOwogICAgICAgIH0gZWxzZSBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikpIHsKICAgICAgICAgICAgcmVsZWFzZSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTWVtOwogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX1VTRVJQVFIgfCBTRkxBR19JTlNZU01FTTsKCiAgICAgICAgLyogTm93IGZyZWUgdGhlIG9sZCBtZW1vcnkgaWYgYW55ICovCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmVsZWFzZSk7CiAgICB9IGVsc2UgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19VU0VSUFRSKSB7CiAgICAgICAgLyogTG9ja3JlY3QgYW5kIEdldERDIHdpbGwgcmUtY3JlYXRlIHRoZSBkaWIgc2VjdGlvbiBhbmQgYWxsb2NhdGVkIG1lbW9yeSAqLwogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX1VTRVJQVFI7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVHRElTdXJmYWNlSW1wbF9Nb2RpZnlMb2NhdGlvbihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBmbGFnLCBCT09MIHBlcnNpc3RlbnQpIHsKICAgIFRSQUNFKCIoJXApLT4oJXMsICVzKVxuIiwgaWZhY2UsCiAgICAgICAgICBmbGFnID09IFNGTEFHX0lOU1lTTUVNID8gIlNGTEFHX0lOU1lTTUVNIiA6IGZsYWcgPT0gU0ZMQUdfSU5EUkFXQUJMRSA/ICJTRkxBR19JTkRSQVdBQkxFIiA6ICJTRkxBR19JTlRFWFRVUkUiLAogICAgICAgICAgcGVyc2lzdGVudCA/ICJUUlVFIiA6ICJGQUxTRSIpOwogICAgLyogR0RJIHN1cmZhY2VzIGNhbiBiZSBpbiBzeXN0ZW0gbWVtb3J5IG9ubHkgKi8KICAgIGlmKGZsYWcgIT0gU0ZMQUdfSU5TWVNNRU0pIHsKICAgICAgICBFUlIoIkdESSBTdXJmYWNlIHJlcXVlc3RlZCBpbiBnbCAlcyBtZW1vcnlcbiIsIGZsYWcgPT0gU0ZMQUdfSU5EUkFXQUJMRSA/ICJkcmF3YWJsZSIgOiAidGV4dHVyZSIpOwogICAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVHRElTdXJmYWNlSW1wbF9Mb2FkTG9jYXRpb24oSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgZmxhZywgY29uc3QgUkVDVCAqcmVjdCkgewogICAgaWYoZmxhZyAhPSBTRkxBR19JTlNZU01FTSkgewogICAgICAgIEVSUigiR0RJIFN1cmZhY2UgcmVxdWVzdGVkIHRvIGJlIGNvcGllZCB0byBnbCAlc1xuIiwgZmxhZyA9PSBTRkxBR19JTlRFWFRVUkUgPyAidGV4dHVyZSIgOiAiZHJhd2FibGUiKTsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIlN1cmZhY2UgcmVxdWVzdGVkIGluIHN1cmZhY2UgbWVtb3J5XG4iKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBGSVhNRTogVGhpcyB2dGFibGUgc2hvdWxkIG5vdCB1c2UgYW55IElXaW5lRDNEU3VyZmFjZSogaW1wbGVtZW50YXRpb24gZnVuY3Rpb25zLAogKiBvbmx5IElXaW5lRDNEQmFzZVN1cmZhY2UgYW5kIElXaW5lR0RJU3VyZmFjZSBvbmVzLgogKi8KY29uc3QgSVdpbmVEM0RTdXJmYWNlVnRibCBJV2luZUdESVN1cmZhY2VfVnRibCA9CnsKICAgIC8qIElVbmtub3duICovCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0FkZFJlZiwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfUmVsZWFzZSwKICAgIC8qIElXaW5lRDNEUmVzb3VyY2UgKi8KICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFBhcmVudCwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldERldmljZSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldFByaXZhdGVEYXRhLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0UHJpdmF0ZURhdGEsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9GcmVlUHJpdmF0ZURhdGEsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRQcmlvcml0eSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFByaW9yaXR5LAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9QcmVMb2FkLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0VHlwZSwKICAgIC8qIElXaW5lRDNEU3VyZmFjZSAqLwogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0Q29udGFpbmVyLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0RGVzYywKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfTG9ja1JlY3QsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX1VubG9ja1JlY3QsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX0dldERDLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9SZWxlYXNlREMsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX0ZsaXAsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9CbHQsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRCbHRTdGF0dXMsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRGbGlwU3RhdHVzLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfSXNMb3N0LAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfUmVzdG9yZSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0JsdEZhc3QsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRQYWxldHRlLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0UGFsZXR0ZSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1JlYWxpemVQYWxldHRlLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0Q29sb3JLZXksCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRQaXRjaCwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfU2V0TWVtLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0T3ZlcmxheVBvc2l0aW9uLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0T3ZlcmxheVBvc2l0aW9uLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheVpPcmRlciwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXksCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRDbGlwcGVyLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0Q2xpcHBlciwKICAgIC8qIEludGVybmFsIHVzZTogKi8KICAgIElXaW5lR0RJU3VyZmFjZUltcGxfQWRkRGlydHlSZWN0LAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9Mb2FkVGV4dHVyZSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0JpbmRUZXh0dXJlLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRDb250YWluZXIsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX1NldEdsVGV4dHVyZURlc2MsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX0dldEdsRGVzYywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RGF0YSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldEZvcm1hdCwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfUHJpdmF0ZVNldHVwLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9Nb2RpZnlMb2NhdGlvbiwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfTG9hZExvY2F0aW9uCn07Cg==