LyoKICogSVdpbmVEM0REZXZpY2UgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDIgTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDMtMjAwNCBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpZmRlZiBIQVZFX0ZMT0FUX0gKIyBpbmNsdWRlIDxmbG9hdC5oPgojZW5kaWYKI2luY2x1ZGUgIndpbmVkM2RfcHJpdmF0ZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZDNkKTsKI2RlZmluZSBHTElORk9fTE9DQVRJT04gKChJV2luZUQzREltcGwgKikoVGhpcy0+d2luZUQzRCkpLT5nbF9pbmZvCgovKiB4MTFkcnYgR0RJIGVzY2FwZXMgKi8KI2RlZmluZSBYMTFEUlZfRVNDQVBFIDY3ODkKZW51bSB4MTFkcnZfZXNjYXBlX2NvZGVzCnsKICAgIFgxMURSVl9HRVRfRElTUExBWSwgICAvKiBnZXQgWDExIGRpc3BsYXkgZm9yIGEgREMgKi8KICAgIFgxMURSVl9HRVRfRFJBV0FCTEUsICAvKiBnZXQgY3VycmVudCBkcmF3YWJsZSBmb3IgYSBEQyAqLwogICAgWDExRFJWX0dFVF9GT05ULCAgICAgIC8qIGdldCBjdXJyZW50IFggZm9udCBmb3IgYSBEQyAqLwp9OwoKLyogcmV0cmlldmUgdGhlIFggZGlzcGxheSB0byB1c2Ugb24gYSBnaXZlbiBEQyAqLwppbmxpbmUgc3RhdGljIERpc3BsYXkgKmdldF9kaXNwbGF5KCBIREMgaGRjICkKewogICAgRGlzcGxheSAqZGlzcGxheTsKICAgIGVudW0geDExZHJ2X2VzY2FwZV9jb2RlcyBlc2NhcGUgPSBYMTFEUlZfR0VUX0RJU1BMQVk7CgogICAgaWYgKCFFeHRFc2NhcGUoIGhkYywgWDExRFJWX0VTQ0FQRSwgc2l6ZW9mKGVzY2FwZSksIChMUENTVFIpJmVzY2FwZSwKICAgICAgICAgICAgICAgICAgICBzaXplb2YoZGlzcGxheSksIChMUFNUUikmZGlzcGxheSApKSBkaXNwbGF5ID0gTlVMTDsKICAgIHJldHVybiBkaXNwbGF5Owp9CgovKiBNZW1vcnkgdHJhY2tpbmcgYW5kIG9iamVjdCBjb3VudGluZyAqLwpzdGF0aWMgdW5zaWduZWQgaW50IGVtdWxhdGVkX3RleHR1cmVyYW0gPSA2NCoxMDI0KjEwMjQ7CgovKiBUT0RPOiBzZXR1cCBzb21lIGZsYWdzIGluIHRoZSByZWdlc3RyeSB0byBlbmFibGUsIGRpc2FibGUgcGJ1ZmZlciBzdXBwb3J0ICovCi8qIGVuYWJsZSBwYnVmZmVyIHN1cHBvcnQgZm9yIG9mZnNjcmVlbiB0ZXh0dXJlcyAqLwpCT09MIHBidWZmZXJfc3VwcG9ydCAgICAgPSBGQUxTRTsKLyogYWxsb2NhdGUgb25lIHBidWZmZXIgcGVyIHN1cmZhY2UgKi8KQk9PTCBwYnVmZmVyX3Blcl9zdXJmYWNlID0gRkFMU0U7CgovKiBzdGF0aWMgZnVuY3Rpb24gZGVjbGFyYXRpb25zICovCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQWRkUmVzb3VyY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFJlc291cmNlICpyZXNvdXJjZSk7CgpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0FwcGx5VGV4dHVyZVVuaXRTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFN0YWdlLCBXSU5FRDNEVEVYVFVSRVNUQUdFU1RBVEVUWVBFIFR5cGUpOwoKLyogaGVscGVyIG1hY3JvcyAqLwojZGVmaW5lIEQzRE1FTUNIRUNLKG9iamVjdCwgcHBSZXN1bHQpIGlmKE5VTEwgPT0gb2JqZWN0KSB7ICpwcFJlc3VsdCA9IE5VTEw7IFdBUk4oIk91dCBvZiBtZW1vcnlcbiIpOyByZXR1cm4gV0lORUQzREVSUl9PVVRPRlZJREVPTUVNT1JZO30KCiNkZWZpbmUgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCB0eXBlKSB7IFwKICAgIG9iamVjdD1IZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElXaW5lRDNEIyN0eXBlIyNJbXBsKSk7IFwKICAgIEQzRE1FTUNIRUNLKG9iamVjdCwgcHAjI3R5cGUpOyBcCiAgICBvYmplY3QtPmxwVnRibCA9ICZJV2luZUQzRCMjdHlwZSMjX1Z0Ymw7ICBcCiAgICBvYmplY3QtPndpbmVEM0REZXZpY2UgPSBUaGlzOyBcCiAgICBvYmplY3QtPnBhcmVudCAgICAgICA9IHBhcmVudDsgXAogICAgb2JqZWN0LT5yZWYgICAgICAgICAgPSAxOyBcCiAgICAqcHAjI3R5cGUgPSAoSVdpbmVEM0QjI3R5cGUgKikgb2JqZWN0OyBcCn0KCiNkZWZpbmUgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCB0eXBlLCBkM2R0eXBlLCBfc2l6ZSl7IFwKICAgIG9iamVjdD1IZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElXaW5lRDNEIyN0eXBlIyNJbXBsKSk7IFwKICAgIEQzRE1FTUNIRUNLKG9iamVjdCwgcHAjI3R5cGUpOyBcCiAgICBvYmplY3QtPmxwVnRibCA9ICZJV2luZUQzRCMjdHlwZSMjX1Z0Ymw7ICBcCiAgICBvYmplY3QtPnJlc291cmNlLndpbmVEM0REZXZpY2UgICA9IFRoaXM7IFwKICAgIG9iamVjdC0+cmVzb3VyY2UucGFyZW50ICAgICAgICAgID0gcGFyZW50OyBcCiAgICBvYmplY3QtPnJlc291cmNlLnJlc291cmNlVHlwZSAgICA9IGQzZHR5cGU7IFwKICAgIG9iamVjdC0+cmVzb3VyY2UucmVmICAgICAgICAgICAgID0gMTsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS5wb29sICAgICAgICAgICAgPSBQb29sOyBcCiAgICBvYmplY3QtPnJlc291cmNlLmZvcm1hdCAgICAgICAgICA9IEZvcm1hdDsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS51c2FnZSAgICAgICAgICAgPSBVc2FnZTsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS5zaXplICAgICAgICAgICAgPSBfc2l6ZTsgXAogICAgLyogQ2hlY2sgdGhhdCB3ZSBoYXZlIGVub3VnaCB2aWRlbyByYW0gbGVmdCAqLyBcCiAgICBpZiAoUG9vbCA9PSBXSU5FRDNEUE9PTF9ERUZBVUxUKSB7IFwKICAgICAgICBpZiAoSVdpbmVEM0REZXZpY2VfR2V0QXZhaWxhYmxlVGV4dHVyZU1lbShpZmFjZSkgPD0gX3NpemUpIHsgXAogICAgICAgICAgICBXQVJOKCJPdXQgb2YgJ2JvZ3VzJyB2aWRlbyBtZW1vcnlcbiIpOyBcCiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7IFwKICAgICAgICAgICAgKnBwIyN0eXBlID0gTlVMTDsgXAogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9PVVRPRlZJREVPTUVNT1JZOyBcCiAgICAgICAgfSBcCiAgICAgICAgZ2xvYmFsQ2hhbmdlR2xSYW0oX3NpemUpOyBcCiAgICB9IFwKICAgIG9iamVjdC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gKDAgPT0gX3NpemUgPyBOVUxMIDogUG9vbCA9PSBXSU5FRDNEUE9PTF9ERUZBVUxUID8gTlVMTCA6IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBfc2l6ZSkpOyBcCiAgICBpZiAob2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPT0gTlVMTCAmJiBfc2l6ZSAhPSAwICYmIFBvb2wgIT0gV0lORUQzRFBPT0xfREVGQVVMVCkgeyBcCiAgICAgICAgRklYTUUoIk91dCBvZiBtZW1vcnkhXG4iKTsgXAogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7IFwKICAgICAgICAqcHAjI3R5cGUgPSBOVUxMOyBcCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfT1VUT0ZWSURFT01FTU9SWTsgXAogICAgfSBcCiAgICAqcHAjI3R5cGUgPSAoSVdpbmVEM0QjI3R5cGUgKikgb2JqZWN0OyBcCiAgICBJV2luZUQzRERldmljZUltcGxfQWRkUmVzb3VyY2UoaWZhY2UsIChJV2luZUQzRFJlc291cmNlICopb2JqZWN0KSA7XAogICAgVFJBQ0UoIiglcCkgOiBDcmVhdGVkIHJlc291cmNlICVwXG4iLCBUaGlzLCBvYmplY3QpOyBcCn0KCiNkZWZpbmUgRDNESU5JVElBTElaRUJBU0VURVhUVVJFKF9iYXNldGV4dHVyZSkgeyBcCiAgICBfYmFzZXRleHR1cmUubGV2ZWxzICAgICA9IExldmVsczsgXAogICAgX2Jhc2V0ZXh0dXJlLmZpbHRlclR5cGUgPSAoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfQVVUT0dFTk1JUE1BUCkgPyBXSU5FRDNEVEVYRl9MSU5FQVIgOiBXSU5FRDNEVEVYRl9OT05FOyBcCiAgICBfYmFzZXRleHR1cmUuTE9EICAgICAgICA9IDA7IFwKICAgIF9iYXNldGV4dHVyZS5kaXJ0eSAgICAgID0gVFJVRTsgXAp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBHbG9iYWwgdmFyaWFibGUgLyBDb25zdGFudHMgZm9sbG93CiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpjb25zdCBmbG9hdCBpZGVudGl0eVsxNl0gPSB7MSwwLDAsMCwgMCwxLDAsMCwgMCwwLDEsMCwgMCwwLDAsMX07ICAvKiBXaGVuIG5lZWRlZCBmb3IgY29tcGFyaXNvbnMgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFV0aWxpdHkgZnVuY3Rpb25zIGZvbGxvdwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogQ29udmVydCB0aGUgRDNETElHSFQgcHJvcGVydGllcyBpbnRvIGVxdWl2YWxlbnQgZ2wgbGlnaHRzICovCnN0YXRpYyB2b2lkIHNldHVwX2xpZ2h0KElXaW5lRDNERGV2aWNlICppZmFjZSwgTE9ORyBJbmRleCwgUExJR0hUSU5GT0VMICpsaWdodEluZm8pIHsKCiAgICBmbG9hdCBxdWFkX2F0dDsKICAgIGZsb2F0IGNvbFJHQkFbXSA9IHswLjAsIDAuMCwgMC4wLCAwLjB9OwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIC8qIExpZ2h0IHNldHRpbmdzIGFyZSBhZmZlY3RlZCBieSB0aGUgbW9kZWwgdmlldyBpbiBPcGVuR0wsIHRoZSBWaWV3IHRyYW5zZm9ybSBpbiBkaXJlY3QzZCovCiAgICBnbE1hdHJpeE1vZGUoR0xfTU9ERUxWSUVXKTsKICAgIGdsUHVzaE1hdHJpeCgpOwogICAgZ2xMb2FkTWF0cml4ZigoZmxvYXQgKikmVGhpcy0+c3RhdGVCbG9jay0+dHJhbnNmb3Jtc1tEM0RUU19WSUVXXS51Lm1bMF1bMF0pOwoKICAgIC8qIERpZmZ1c2U6ICovCiAgICBjb2xSR0JBWzBdID0gbGlnaHRJbmZvLT5PcmlnaW5hbFBhcm1zLkRpZmZ1c2UucjsKICAgIGNvbFJHQkFbMV0gPSBsaWdodEluZm8tPk9yaWdpbmFsUGFybXMuRGlmZnVzZS5nOwogICAgY29sUkdCQVsyXSA9IGxpZ2h0SW5mby0+T3JpZ2luYWxQYXJtcy5EaWZmdXNlLmI7CiAgICBjb2xSR0JBWzNdID0gbGlnaHRJbmZvLT5PcmlnaW5hbFBhcm1zLkRpZmZ1c2UuYTsKICAgIGdsTGlnaHRmdihHTF9MSUdIVDArSW5kZXgsIEdMX0RJRkZVU0UsIGNvbFJHQkEpOwogICAgY2hlY2tHTGNhbGwoImdsTGlnaHRmdiIpOwoKICAgIC8qIFNwZWN1bGFyICovCiAgICBjb2xSR0JBWzBdID0gbGlnaHRJbmZvLT5PcmlnaW5hbFBhcm1zLlNwZWN1bGFyLnI7CiAgICBjb2xSR0JBWzFdID0gbGlnaHRJbmZvLT5PcmlnaW5hbFBhcm1zLlNwZWN1bGFyLmc7CiAgICBjb2xSR0JBWzJdID0gbGlnaHRJbmZvLT5PcmlnaW5hbFBhcm1zLlNwZWN1bGFyLmI7CiAgICBjb2xSR0JBWzNdID0gbGlnaHRJbmZvLT5PcmlnaW5hbFBhcm1zLlNwZWN1bGFyLmE7CiAgICBnbExpZ2h0ZnYoR0xfTElHSFQwK0luZGV4LCBHTF9TUEVDVUxBUiwgY29sUkdCQSk7CiAgICBjaGVja0dMY2FsbCgiZ2xMaWdodGZ2Iik7CgogICAgLyogQW1iaWVudCAqLwogICAgY29sUkdCQVswXSA9IGxpZ2h0SW5mby0+T3JpZ2luYWxQYXJtcy5BbWJpZW50LnI7CiAgICBjb2xSR0JBWzFdID0gbGlnaHRJbmZvLT5PcmlnaW5hbFBhcm1zLkFtYmllbnQuZzsKICAgIGNvbFJHQkFbMl0gPSBsaWdodEluZm8tPk9yaWdpbmFsUGFybXMuQW1iaWVudC5iOwogICAgY29sUkdCQVszXSA9IGxpZ2h0SW5mby0+T3JpZ2luYWxQYXJtcy5BbWJpZW50LmE7CiAgICBnbExpZ2h0ZnYoR0xfTElHSFQwK0luZGV4LCBHTF9BTUJJRU5ULCBjb2xSR0JBKTsKICAgIGNoZWNrR0xjYWxsKCJnbExpZ2h0ZnYiKTsKCiAgICAvKiBBdHRlbnVhdGlvbiAtIEFyZSB0aGVzZSByaWdodD8gZ3Vlc3NpbmcuLi4gKi8KICAgIGdsTGlnaHRmKEdMX0xJR0hUMCtJbmRleCwgR0xfQ09OU1RBTlRfQVRURU5VQVRJT04sICBsaWdodEluZm8tPk9yaWdpbmFsUGFybXMuQXR0ZW51YXRpb24wKTsKICAgIGNoZWNrR0xjYWxsKCJnbExpZ2h0ZiIpOwogICAgZ2xMaWdodGYoR0xfTElHSFQwK0luZGV4LCBHTF9MSU5FQVJfQVRURU5VQVRJT04sICAgIGxpZ2h0SW5mby0+T3JpZ2luYWxQYXJtcy5BdHRlbnVhdGlvbjEpOwogICAgY2hlY2tHTGNhbGwoImdsTGlnaHRmIik7CgogICAgaWYgKChsaWdodEluZm8tPk9yaWdpbmFsUGFybXMuUmFuZ2UgKmxpZ2h0SW5mby0+T3JpZ2luYWxQYXJtcy5SYW5nZSkgPj0gRkxUX01JTikgewogICAgICAgIHF1YWRfYXR0ID0gMS40LyhsaWdodEluZm8tPk9yaWdpbmFsUGFybXMuUmFuZ2UgKmxpZ2h0SW5mby0+T3JpZ2luYWxQYXJtcy5SYW5nZSk7CiAgICB9IGVsc2UgewogICAgICAgIHF1YWRfYXR0ID0gMDsgLyogIDAgb3IgIE1BWD8gICgwIHNlZW1zIHRvIGJlIG9rKSAqLwogICAgfQoKICAgIGlmIChxdWFkX2F0dCA8IGxpZ2h0SW5mby0+T3JpZ2luYWxQYXJtcy5BdHRlbnVhdGlvbjIpIHF1YWRfYXR0ID0gbGlnaHRJbmZvLT5PcmlnaW5hbFBhcm1zLkF0dGVudWF0aW9uMjsKICAgIGdsTGlnaHRmKEdMX0xJR0hUMCtJbmRleCwgR0xfUVVBRFJBVElDX0FUVEVOVUFUSU9OLCBxdWFkX2F0dCk7CiAgICBjaGVja0dMY2FsbCgiZ2xMaWdodGYiKTsKCiAgICBzd2l0Y2ggKGxpZ2h0SW5mby0+T3JpZ2luYWxQYXJtcy5UeXBlKSB7CiAgICBjYXNlIEQzRExJR0hUX1BPSU5UOgogICAgICAgIC8qIFBvc2l0aW9uICovCiAgICAgICAgZ2xMaWdodGZ2KEdMX0xJR0hUMCtJbmRleCwgR0xfUE9TSVRJT04sICZsaWdodEluZm8tPmxpZ2h0UG9zblswXSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsTGlnaHRmdiIpOwogICAgICAgIGdsTGlnaHRmKEdMX0xJR0hUMCArIEluZGV4LCBHTF9TUE9UX0NVVE9GRiwgbGlnaHRJbmZvLT5jdXRvZmYpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbExpZ2h0ZiIpOwogICAgICAgIC8qIEZJWE1FOiBSYW5nZSAqLwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgRDNETElHSFRfU1BPVDoKICAgICAgICAvKiBQb3NpdGlvbiAqLwogICAgICAgIGdsTGlnaHRmdihHTF9MSUdIVDArSW5kZXgsIEdMX1BPU0lUSU9OLCAmbGlnaHRJbmZvLT5saWdodFBvc25bMF0pOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbExpZ2h0ZnYiKTsKICAgICAgICAvKiBEaXJlY3Rpb24gKi8KICAgICAgICBnbExpZ2h0ZnYoR0xfTElHSFQwK0luZGV4LCBHTF9TUE9UX0RJUkVDVElPTiwgJmxpZ2h0SW5mby0+bGlnaHREaXJuWzBdKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xMaWdodGZ2Iik7CiAgICAgICAgZ2xMaWdodGYoR0xfTElHSFQwICsgSW5kZXgsIEdMX1NQT1RfRVhQT05FTlQsIGxpZ2h0SW5mby0+ZXhwb25lbnQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbExpZ2h0ZiIpOwogICAgICAgIGdsTGlnaHRmKEdMX0xJR0hUMCArIEluZGV4LCBHTF9TUE9UX0NVVE9GRiwgbGlnaHRJbmZvLT5jdXRvZmYpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbExpZ2h0ZiIpOwogICAgICAgIC8qIEZJWE1FOiBSYW5nZSAqLwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgRDNETElHSFRfRElSRUNUSU9OQUw6CiAgICAgICAgLyogRGlyZWN0aW9uICovCiAgICAgICAgZ2xMaWdodGZ2KEdMX0xJR0hUMCtJbmRleCwgR0xfUE9TSVRJT04sICZsaWdodEluZm8tPmxpZ2h0UG9zblswXSk7IC8qIE5vdGUgZ2wgdXNlcyB3IHBvc2l0aW9uIG9mIDAgZm9yIGRpcmVjdGlvbiEgKi8KICAgICAgICBjaGVja0dMY2FsbCgiZ2xMaWdodGZ2Iik7CiAgICAgICAgZ2xMaWdodGYoR0xfTElHSFQwK0luZGV4LCBHTF9TUE9UX0NVVE9GRiwgbGlnaHRJbmZvLT5jdXRvZmYpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbExpZ2h0ZiIpOwogICAgICAgIGdsTGlnaHRmKEdMX0xJR0hUMCtJbmRleCwgR0xfU1BPVF9FWFBPTkVOVCwgMC4wZik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsTGlnaHRmIik7CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBGSVhNRSgiVW5yZWNvZ25pemVkIGxpZ2h0IHR5cGUgJWRcbiIsIGxpZ2h0SW5mby0+T3JpZ2luYWxQYXJtcy5UeXBlKTsKICAgIH0KCiAgICAvKiBSZXN0b3JlIHRoZSBtb2RlbHZpZXcgbWF0cml4ICovCiAgICBnbFBvcE1hdHJpeCgpOwp9CgovKiBBcHBseSB0aGUgY3VycmVudCB2YWx1ZXMgdG8gdGhlIHNwZWNpZmllZCB0ZXh0dXJlIHN0YWdlICovCnZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXR1cFRleHR1cmVTdGF0ZXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBTYW1wbGVyLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgZmxvYXQgY29sWzRdOwoKICAgIHVuaW9uIHsKICAgICAgICBmbG9hdCBmOwogICAgICAgIERXT1JEIGQ7CiAgICB9IHRtcHZhbHVlOwoKICAgIC8qIEluIGFkZGl0aW9uLCBJRGlyZWN0M0REZXZpY2U5OjpTZXRTYW1wbGVyU3RhdGUgd2lsbCBub3cgYmUgdXNlZCBmb3IgZmlsdGVyaW5nLCB0aWxpbmcsCiAgICBjbGFtcGluZywgTUlQTE9ELCBldGMuIFRoaXMgd2lsbCB3b3JrIGZvciB1cCB0byAxNiBzYW1wbGVycy4KICAgICovCiAgIAogICAgaWYgKFNhbXBsZXIgPj0gR0xfTElNSVRTKHNhbXBsZXJzKSkgewogICAgICAgIEZJWE1FKCJUcnlpbmcgdG8gc2V0IHRoZSBzdGF0ZSBvZiBtb3JlIHNhbXBsZXJzICVsZCB0aGFuIGFyZSBzdXBwb3J0ZWQgJWQgYnkgdGhpcyBvcGVuR0wgaW1wbGVtZW50YXRpb25cbiIsIFNhbXBsZXIsIEdMX0xJTUlUUyhzYW1wbGVycykpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIFZUUkFDRSgoIkFjdGl2YXRpbmcgYXBwcm9wcmlhdGUgdGV4dHVyZSBzdGF0ZSAlbGRcbiIsIFNhbXBsZXIpKTsKICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBHTEFDVElWRVRFWFRVUkUoU2FtcGxlcik7CiAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICAvKiBDb3VsZCB3ZSB1c2UgYmluZFRleHR1cmUgYW5kIHRoZW4gYXBwbHkgdGhlIHN0YXRlcyBpbnN0ZWFkIG9mIEdMQUNUSVZFVEVYVFVSRSAqLwogICAgfSBlbHNlIGlmIChTYW1wbGVyID4gMCkgewogICAgICAgIEZJWE1FKCJQcm9ncmFtIHVzaW5nIG11bHRpcGxlIGNvbmN1cnJlbnQgdGV4dHVyZXMgd2hpY2ggdGhpcyBvcGVuZ2wgaW1wbGVtZW50YXRpb24gZG9lc24ndCBzdXBwb3J0XG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLyogVE9ETzogY2hhbmdlIHRoaXMgdG8gYSBsb29rdXAgdGFibGUKICAgICAgICBMT09LVVBfVEVYVFVSRV9TVEFURVMgbGlzdHMgYWxsIHRleHR1cmUgc3RhdGVzIHRoYXQgc2hvdWxkIGJlIGFwcGxpZWQuCiAgICAgICAgTE9PS1VQX0NPTlRFWFRfU0FURVMgbGlzdCBhbGwgY29udGV4dCBhcHBsaWNhYmxlIHN0YXRlcyB0aGF0IGNhbiBiZSBhcHBsaWVkCiAgICAgICAgZXRjLi4uLiBpdCdzIGEgbG90IGNsZWFuZXIsIHF1aWNrZXIgYW5kIHBvc3NpYmx5IGVhc2llciB0byBtYWludGFpbiB0aGFuIHJ1bm5pbmcgYSBzd2l0Y2ggYW5kIHNldHRpbmcgYSBza2lwIGZsYWcuLi4KICAgICAgICBlc3BlY2lhbGx5IHdoZW4gdGhlcmUgYXJlIGEgbnVtYmVyIG9mIGdyb3VwcyBvZiBzdGF0ZXMuICovCgogICAgVFJBQ0UoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPiBVcGRhdGluZyB0aGUgdGV4dHVyZSBhdCBTYW1wbGVyICVsZCB0byBoYXZlIG5ldyB0ZXh0dXJlIHN0YXRlIGluZm9ybWF0aW9uXG4iLCBTYW1wbGVyKTsKCiAgICAvKiBUaGUgbGlzdCBvZiBzdGF0ZXMgbm90IHRvIGFwcGx5IGlzIGEgYmlnIGFzIHRoZSBsaXN0IG9mIHN0YXRlcyB0byBhcHBseSwgc28gaXQgbWFrZXMgc2Vuc2UgdG8gcHJvZHVjZSBhbiBpbmNsdXNpdmUgbGlzdCAgKi8KI2RlZmluZSBBUFBMWV9TVEFURShfc3RhdGUpICAgICBJV2luZUQzRERldmljZUltcGxfQXBwbHlUZXh0dXJlVW5pdFN0YXRlKGlmYWNlLCBTYW1wbGVyLCBfc3RhdGUpCi8qIHRoZXNlIGFyZSB0aGUgb25seSB0d28gc3VwcG9ydGVkIHN0YXRlcyB0aGF0IG5lZWQgdG8gYmUgYXBwbGllZCAqLwogICAgQVBQTFlfU1RBVEUoV0lORUQzRFRTU19URVhDT09SRElOREVYKTsKICAgIEFQUExZX1NUQVRFKFdJTkVEM0RUU1NfVEVYVFVSRVRSQU5TRk9STUZMQUdTKTsKI2lmIDAgLyogbm90IHN1cHBvcnRlZCBhdCB0aGUgbW9tZW50ICovCiAgICBBUFBMWV9TVEFURShXSU5FRDNEVFNTX0JVTVBFTlZNQVQwMCk7CiAgICBBUFBMWV9TVEFURShXSU5FRDNEVFNTX0JVTVBFTlZNQVQwMSk7CiAgICBBUFBMWV9TVEFURShXSU5FRDNEVFNTX0JVTVBFTlZNQVQxMCk7CiAgICBBUFBMWV9TVEFURShXSU5FRDNEVFNTX0JVTVBFTlZNQVQxMSk7CiAgICBBUFBMWV9TVEFURShXSU5FRDNEVFNTX0JVTVBFTlZMU0NBTEUpOwogICAgQVBQTFlfU1RBVEUoV0lORUQzRFRTU19CVU1QRU5WTE9GRlNFVCk7CiAgICBBUFBMWV9TVEFURShXSU5FRDNEVFNTX1JFU1VMVEFSRyk7CiAgICBBUFBMWV9TVEFURShXSU5FRDNEVFNTX0NPTlNUQU5UKTsKI2VuZGlmCiAgICAvKiBhIHF1aWNrIHNhbml0eSBjaGVjayBpbiBjYXNlIHNvbWVvbmUgZm9yZ290IHRvIHVwZGF0ZSB0aGlzIGZ1bmN0aW9uICovCiAgICBpZiAoV0lORUQzRF9ISUdIRVNUX1RFWFRVUkVfU1RBVEUgPiBXSU5FRDNEVFNTX0NPTlNUQU5UKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBUaGVyZSBhcmUgbW9yZSB0ZXh0dXJlIHN0YXRlcyB0aGFuIGV4cGVjdGVkLCB1cGRhdGUgZGV2aWNlLmMgdG8gbWF0Y2hcbiIsIFRoaXMpOwogICAgfQojdW5kZWYgQVBQTFlfU1RBVEUKCiAgICAvKiBhcHBseSBhbnkgc2FtcGxlciBzdGF0ZXMgdGhhdCBhbHdheXMgbmVlZCBhcHBseWluZyAqLwogICAgaWYgKEdMX1NVUFBPUlQoRVhUX1RFWFRVUkVfTE9EX0JJQVMpKSB7CiAgICAgICAgdG1wdmFsdWUuZCA9IFRoaXMtPnN0YXRlQmxvY2stPnNhbXBsZXJTdGF0ZVtTYW1wbGVyXVtXSU5FRDNEU0FNUF9NSVBNQVBMT0RCSUFTXTsKICAgICAgICBnbFRleEVudmYoR0xfVEVYVFVSRV9GSUxURVJfQ09OVFJPTF9FWFQsCiAgICAgICAgICAgICAgICBHTF9URVhUVVJFX0xPRF9CSUFTX0VYVCwKICAgICAgICAgICAgICAgIHRtcHZhbHVlLmYpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEVudmkgR0xfVEVYVFVSRV9MT0RfQklBU19FWFQgLi4uIik7CiAgICB9CgogICAgLyogTm90ZSB0aGUgRDNEUlMgdmFsdWUgYXBwbGllcyB0byBhbGwgdGV4dHVyZXMsIGJ1dCBHTCBoYXMgb25lCiAgICAgKiAgcGVyIHRleHR1cmUsIHNvIGFwcGx5IGl0IG5vdyByZWFkeSB0byBiZSB1c2VkIQogICAgICovCiAgICBEM0RDT0xPUlRPR0xGTE9BVDQoVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1RFWFRVUkVGQUNUT1JdLCBjb2wpOwogICAgLyogU2V0IHRoZSBkZWZhdWx0IGFscGhhIGJsZW5kIGNvbG9yICovCiAgICBnbEJsZW5kQ29sb3IoY29sWzBdLCBjb2xbMV0sIGNvbFsyXSwgY29sWzNdKTsKICAgIGNoZWNrR0xjYWxsKCJnbEJsZW5kQ29sb3IiKTsKCiAgICBEM0RDT0xPUlRPR0xGTE9BVDQoVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1RFWFRVUkVGQUNUT1JdLCBjb2wpOwogICAgZ2xUZXhFbnZmdihHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfQ09MT1IsICZjb2xbMF0pOwogICAgY2hlY2tHTGNhbGwoImdsVGV4RW52ZnYoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX0NPTE9SLCBjb2xvcik7Iik7CgogICAgLyogVE9ETzogTlZfUE9JTlRfU1BSSVRFICovCiAgICBpZiAoR0xfU1VQUE9SVChBUkJfUE9JTlRfU1BSSVRFKSkgewogICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfUE9JTlRTUFJJVEVFTkFCTEVdICE9IEZBTFNFKSB7CiAgICAgICAgICAgLyogRG9lc24ndCB3b3JrIHdpdGggR0xfUE9JTlRfU01PT1RIIG9uIG9uIG15IEFUSSA5NjAwLCBidXQgdGhlbiBBVEkgZHJpdmVycyBhcmUgYnVnZ2VyZWQhICovCiAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1BPSU5UX1NNT09USCk7CgogICAgICAgICAgIC8qIENlbnRyZSB0aGUgdGV4dHVyZSBvbiB0aGUgdmVydGV4ICovCiAgICAgICAgICAgVlRSQUNFKCgiZ2xUZXhFbnZmKCBHTF9QT0lOVF9TUFJJVEVfQVJCLCBHTF9DT09SRF9SRVBMQUNFX0FSQiwgR0xfVFJVRSlcbiIpKTsKICAgICAgICAgICBnbFRleEVudmYoIEdMX1BPSU5UX1NQUklURV9BUkIsIEdMX0NPT1JEX1JFUExBQ0VfQVJCLCBHTF9UUlVFKTsKCiAgICAgICAgICAgVlRSQUNFKCgiZ2xUZXhFbnZmKCBHTF9QT0lOVF9TUFJJVEVfQVJCLCBHTF9DT09SRF9SRVBMQUNFX0FSQiwgR0xfVFJVRSlcbiIpKTsKICAgICAgICAgICBnbFRleEVudmYoIEdMX1BPSU5UX1NQUklURV9BUkIsIEdMX0NPT1JEX1JFUExBQ0VfQVJCLCBHTF9UUlVFKTsKICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhFbnZmKC4uLikiKTsKICAgICAgICAgICBWVFJBQ0UoKCJnbEVuYWJsZSggR0xfUE9JTlRfU1BSSVRFX0FSQiApXG4iKSk7CiAgICAgICAgICAgZ2xFbmFibGUoIEdMX1BPSU5UX1NQUklURV9BUkIgKTsKICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoLi4uKSIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgVlRSQUNFKCgiZ2xEaXNhYmxlKCBHTF9QT0lOVF9TUFJJVEVfQVJCIClcbiIpKTsKICAgICAgICAgICBnbERpc2FibGUoIEdMX1BPSU5UX1NQUklURV9BUkIgKTsKICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoLi4uKSIpOwogICAgICAgIH0KICAgIH0KCiAgICBUUkFDRSgiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+IFVwZGF0ZWQgdGhlIHRleHR1cmUgYXQgU2FtcGxlciAlbGQgdG8gaGF2ZSBuZXcgdGV4dHVyZSBzdGF0ZSBpbmZvcm1hdGlvblxuIiwgU2FtcGxlcik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElVbmtub3duIHBhcnRzIGZvbGxvd3MKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUXVlcnlJbnRlcmZhY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmopCnsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCkscHBvYmopOwogICAgaWYgKElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVVua25vd24pCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JV2luZUQzREJhc2UpCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JV2luZUQzRERldmljZSkpIHsKICAgICAgICBJVW5rbm93bl9BZGRSZWYoaWZhY2UpOwogICAgICAgICpwcG9iaiA9IFRoaXM7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CiAgICAqcHBvYmogPSBOVUxMOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KClVMT05HIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQWRkUmVmKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmQ291bnQgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBUUkFDRSgiKCVwKSA6IEFkZFJlZiBpbmNyZWFzaW5nIGZyb20gJWxkXG4iLCBUaGlzLCByZWZDb3VudCAtIDEpOwogICAgcmV0dXJuIHJlZkNvdW50Owp9CgpVTE9ORyBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1JlbGVhc2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWZDb3VudCA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICAgIFRSQUNFKCIoJXApIDogUmVsZWFzaW5nIGZyb20gJWxkXG4iLCBUaGlzLCByZWZDb3VudCArIDEpOwoKICAgIGlmICghcmVmQ291bnQpIHsKICAgICAgICAvKiBUT0RPOiBDbGVhbiB1cCBhbGwgdGhlIHN1cmZhY2VzIGFuZCB0ZXh0dXJlcyEgKi8KICAgICAgICAvKiBOT1RFOiBZb3UgbXVzdCByZWxlYXNlIHRoZSBwYXJlbnQgaWYgdGhlIG9iamVjdCB3YXMgY3JlYXRlZCB2aWEgYSBjYWxsYmFjawogICAgICAgICoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAgICAgLyogUmVsZWFzZSB0aGUgdXBkYXRlIHN0YXRlYmxvY2sgKi8KICAgICAgICBpZihJV2luZUQzRFN0YXRlQmxvY2tfUmVsZWFzZSgoSVdpbmVEM0RTdGF0ZUJsb2NrICopVGhpcy0+dXBkYXRlU3RhdGVCbG9jaykgPiAwKXsKICAgICAgICAgICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jayAhPSBUaGlzLT5zdGF0ZUJsb2NrKQogICAgICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgVXBkYXRlIHN0YXRlYmxvY2tcbiIsVGhpcyk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgPSBOVUxMOwogICAgICAgIHsgLyogYmVjYXVzZSB3ZXJlIG5vdCBkb2luZyBwcm9wZXIgaW50ZXJuYWwgcmVmY291bnRzIHJlbGVhc2luZyB0aGUgcHJpbWFyeSBzdGF0ZSBibG9jawogICAgICAgICAgICBjYXVzZXMgcmVjdXJzaW9uIHdpdGggdGhlIGV4dHJhIGNoZWNrcyBpbiBSZXNvdXJjZVJlbGVhc2VkLCB0byBhdm9pZCB0aGlzIHdlIGhhdmUKICAgICAgICAgICAgdG8gc2V0IHRoaXMtPnN0YXRlQmxvY2sgPSBOVUxMOyBmaXJzdCAqLwogICAgICAgICAgICBJV2luZUQzRFN0YXRlQmxvY2sgKnN0YXRlQmxvY2sgPSAoSVdpbmVEM0RTdGF0ZUJsb2NrICopVGhpcy0+c3RhdGVCbG9jazsKICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jayA9IE5VTEw7CgogICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBzdGF0ZWJsb2NrICovCiAgICAgICAgICAgIGlmKElXaW5lRDNEU3RhdGVCbG9ja19SZWxlYXNlKHN0YXRlQmxvY2spID4gMCl7CiAgICAgICAgICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgVXBkYXRlIHN0YXRlYmxvY2tcbiIsVGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChUaGlzLT5yZXNvdXJjZXMgIT0gTlVMTCApIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgRGV2aWNlIHJlbGVhc2VkIHdpdGggcmVzb3VyY2VzIHN0aWxsIGJvdW5kLCBhY2NlcHRhYmxlIGJ1dCB1bmV4cGVjdGVkXG4iLCBUaGlzKTsKICAgICAgICAgICAgZHVtcFJlc291cmNlcyhUaGlzLT5yZXNvdXJjZXMpOwogICAgICAgIH0KCgogICAgICAgIElXaW5lRDNEX1JlbGVhc2UoVGhpcy0+d2luZUQzRCk7CiAgICAgICAgVGhpcy0+d2luZUQzRCA9IE5VTEw7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICAgICAgVFJBQ0UoIkZyZWVkIGRldmljZSAgJXBcbiIsIFRoaXMpOwogICAgICAgIFRoaXMgPSBOVUxMOwogICAgfQogICAgcmV0dXJuIHJlZkNvdW50Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRERldmljZSBpbXBsZW1lbnRhdGlvbiBmb2xsb3dzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0UGFyZW50KElXaW5lRDNERGV2aWNlICppZmFjZSwgSVVua25vd24gKipwUGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAqcFBhcmVudCA9IFRoaXMtPnBhcmVudDsKICAgIElVbmtub3duX0FkZFJlZihUaGlzLT5wYXJlbnQpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhCdWZmZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFNpemUsIERXT1JEIFVzYWdlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGVkYsIFdJTkVEM0RQT09MIFBvb2wsIElXaW5lRDNEVmVydGV4QnVmZmVyKiogcHBWZXJ0ZXhCdWZmZXIsIEhBTkRMRSAqc2hhcmVkSGFuZGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpwYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqb2JqZWN0OwogICAgV0lORUQzREZPUk1BVCBGb3JtYXQgPSBXSU5FRDNERk1UX1ZFUlRFWERBVEE7IC8qIER1bW15IGZvcm1hdCBmb3Igbm93ICovCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgVmVydGV4QnVmZmVyLCBXSU5FRDNEUlRZUEVfVkVSVEVYQlVGRkVSLCBTaXplKQogICAgCiAgICAvKlRPRE86IHVzZSBWQk8ncyAqLwogICAgaWYgKFBvb2wgPT0gV0lORUQzRFBPT0xfREVGQVVMVCApIHsgLyogQWxsb2NhdGUgc29tZSBzeXN0ZW0gbWVtb3J5IGZvciBub3cgKi8KICAgICAgICBvYmplY3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSAgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgb2JqZWN0LT5yZXNvdXJjZS5zaXplKTsKICAgIH0KICAgIG9iamVjdC0+ZnZmID0gRlZGOwoKICAgIFRSQUNFKCIoJXApIDogU2l6ZT0lZCwgVXNhZ2U9JWxkLCBGVkY9JWx4LCBQb29sPSVkIC0gTWVtb3J5QCVwLCBJZmFjZUAlcFxuIiwgVGhpcywgU2l6ZSwgVXNhZ2UsIEZWRiwgUG9vbCwgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIG9iamVjdCk7CiAgICAqcHBWZXJ0ZXhCdWZmZXIgPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgKilvYmplY3Q7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVJbmRleEJ1ZmZlcihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgTGVuZ3RoLCBEV09SRCBVc2FnZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwgV0lORUQzRFBPT0wgUG9vbCwgSVdpbmVEM0RJbmRleEJ1ZmZlcioqIHBwSW5kZXhCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUgKnNoYXJlZEhhbmRsZSwgSVVua25vd24gKnBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RJbmRleEJ1ZmZlckltcGwgKm9iamVjdDsKICAgIFRSQUNFKCIoJXApIENyZWF0aW5nIGluZGV4IGJ1ZmZlclxuIiwgVGhpcyk7CiAgICAKICAgIC8qIEFsbG9jYXRlIHRoZSBzdG9yYWdlIGZvciB0aGUgZGV2aWNlICovCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCxJbmRleEJ1ZmZlcixXSU5FRDNEUlRZUEVfSU5ERVhCVUZGRVIsIExlbmd0aCkKICAgIAogICAgLypUT0RPOiB1c2UgVkJPJ3MgKi8KICAgIGlmIChQb29sID09IFdJTkVEM0RQT09MX0RFRkFVTFQgKSB7IC8qIEFsbG9jYXRlIHNvbWUgc3lzdGVtIG1lbW9yeSBmb3Igbm93ICovCiAgICAgICAgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSxvYmplY3QtPnJlc291cmNlLnNpemUpOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogTGVuPSVkLCBVc2U9JWx4LCBGb3JtYXQ9KCV1LCVzKSwgUG9vbD0lZCAtIE1lbW9yeUAlcCwgSWZhY2VAJXBcbiIsIFRoaXMsIExlbmd0aCwgVXNhZ2UsIEZvcm1hdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnX2QzZGZvcm1hdChGb3JtYXQpLCBQb29sLCBvYmplY3QsIG9iamVjdC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICpwcEluZGV4QnVmZmVyID0gKElXaW5lRDNESW5kZXhCdWZmZXIgKikgb2JqZWN0OwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlU3RhdGVCbG9jayhJV2luZUQzRERldmljZSogaWZhY2UsIFdJTkVEM0RTVEFURUJMT0NLVFlQRSBUeXBlLCBJV2luZUQzRFN0YXRlQmxvY2sqKiBwcFN0YXRlQmxvY2ssIElVbmtub3duICpwYXJlbnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCAqb2JqZWN0OwogICAgaW50IGksIGo7CgogICAgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBTdGF0ZUJsb2NrKQogICAgb2JqZWN0LT5ibG9ja1R5cGUgICAgID0gVHlwZTsKCiAgICAvKiBTcGVjaWFsIGNhc2UgLSBVc2VkIGR1cmluZyBpbml0aWFsaXphdGlvbiB0byBwcm9kdWNlIGEgcGxhY2Vob2xkZXIgc3RhdGVibG9jawogICAgICAgICAgc28gb3RoZXIgZnVuY3Rpb25zIGNhbGxlZCBjYW4gdXBkYXRlIGEgc3RhdGUgYmxvY2sgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgIGlmIChUeXBlID09IFdJTkVEM0RTQlRfSU5JVCkgewogICAgICAgIC8qIERvbid0IGJvdGhlciBpbmNyZWFzaW5nIHRoZSByZWZlcmVuY2UgY291bnQgb3RoZXJ3aXNlIGEgZGV2aWNlIHdpbGwgbmV2ZXIKICAgICAgICAgICBiZSBmcmVlZCBkdWUgdG8gY2lyY3VsYXIgZGVwZW5kZW5jaWVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIE90aGVyd2lzZSwgbWlnaHQgYXMgd2VsbCBzZXQgdGhlIHdob2xlIHN0YXRlIGJsb2NrIHRvIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZXMgICovCiAgICBpZiAoIFRoaXMtPnN0YXRlQmxvY2sgIT0gTlVMTCkgewogICAgICAgbWVtY3B5KG9iamVjdCwgVGhpcy0+c3RhdGVCbG9jaywgc2l6ZW9mKElXaW5lRDNEU3RhdGVCbG9ja0ltcGwpKTsKICAgIH0gZWxzZSB7CiAgICAgICBtZW1zZXQob2JqZWN0LT5zdHJlYW1GcmVxLCAxLCBzaXplb2Yob2JqZWN0LT5zdHJlYW1GcmVxKSk7CiAgICB9CgogICAgLyogUmVzZXQgdGhlIHJlZiBhbmQgdHlwZSBhZnRlciBrbHVkZ2luZyBpdCAqLwogICAgb2JqZWN0LT53aW5lRDNERGV2aWNlID0gVGhpczsKICAgIG9iamVjdC0+cmVmICAgICAgICAgICA9IDE7CiAgICBvYmplY3QtPmJsb2NrVHlwZSAgICAgPSBUeXBlOwoKICAgIFRSQUNFKCJVcGRhdGluZyBjaGFuZ2VkIGZsYWdzIGFwcHJvcHJpYXRlIGZvciB0eXBlICVkXG4iLCBUeXBlKTsKCiAgICBpZiAoVHlwZSA9PSBXSU5FRDNEU0JUX0FMTCkgewoKICAgICAgICBUUkFDRSgiQUxMID0+IFByZXRlbmQgZXZlcnl0aGluZyBoYXMgY2hhbmdlZFxuIik7CiAgICAgICAgbWVtc2V0KCZvYmplY3QtPmNoYW5nZWQsIFRSVUUsIHNpemVvZihUaGlzLT5zdGF0ZUJsb2NrLT5jaGFuZ2VkKSk7CiAgICB9IGVsc2UgaWYgKFR5cGUgPT0gV0lORUQzRFNCVF9QSVhFTFNUQVRFKSB7CgogICAgICAgIFRSQUNFKCJQSVhFTFNUQVRFID0+IFByZXRlbmQgYWxsIHBpeGVsIHNoYXRlcyBoYXZlIGNoYW5nZWRcbiIpOwogICAgICAgIG1lbXNldCgmb2JqZWN0LT5jaGFuZ2VkLCBGQUxTRSwgc2l6ZW9mKFRoaXMtPnN0YXRlQmxvY2stPmNoYW5nZWQpKTsKCiAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnBpeGVsU2hhZGVyID0gVFJVRTsKCiAgICAgICAgLyogUGl4ZWwgU2hhZGVyIENvbnN0YW50cyAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfUFNIQURFUl9DT05TVEFOVFM7ICsraSkgewogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQucGl4ZWxTaGFkZXJDb25zdGFudHNbaV0gPSBUUlVFOwogICAgICAgIH0KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX1NBVkVEUElYRUxTVEFURVNfUjsgaSsrKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC5yZW5kZXJTdGF0ZVtTYXZlZFBpeGVsU3RhdGVzX1JbaV1dID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgZm9yIChqID0gMDsgaiA8IEdMX0xJTUlUUyh0ZXh0dXJlcyk7IGorKykgewogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX1NBVkVEUElYRUxTVEFURVNfVDsgaSsrKSB7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQudGV4dHVyZVN0YXRlW2pdW1NhdmVkUGl4ZWxTdGF0ZXNfVFtpXV0gPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvciAoaiA9IDAgOyBqIDwgMTY7IGorKykgewogICAgICAgICAgICBmb3IgKGkgPTA7IGkgPCBOVU1fU0FWRURQSVhFTFNUQVRFU19TO2krKykgewoKICAgICAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC5zYW1wbGVyU3RhdGVbal1bU2F2ZWRQaXhlbFN0YXRlc19TW2ldXSA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSBlbHNlIGlmIChUeXBlID09IFdJTkVEM0RTQlRfVkVSVEVYU1RBVEUpIHsKCiAgICAgICAgVFJBQ0UoIlZFUlRFWFNUQVRFID0+IFByZXRlbmQgYWxsIHZlcnRleCBzaGF0ZXMgaGF2ZSBjaGFuZ2VkXG4iKTsKICAgICAgICBtZW1zZXQoJm9iamVjdC0+Y2hhbmdlZCwgRkFMU0UsIHNpemVvZihUaGlzLT5zdGF0ZUJsb2NrLT5jaGFuZ2VkKSk7CgogICAgICAgIG9iamVjdC0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXIgPSBUUlVFOwoKICAgICAgICAvKiBWZXJ0ZXggU2hhZGVyIENvbnN0YW50cyAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfVlNIQURFUl9DT05TVEFOVFM7ICsraSkgewogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQudmVydGV4U2hhZGVyQ29uc3RhbnRzW2ldID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgZm9yIChpID0gMDsgaSA8IE5VTV9TQVZFRFZFUlRFWFNUQVRFU19SOyBpKyspIHsKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnJlbmRlclN0YXRlW1NhdmVkVmVydGV4U3RhdGVzX1JbaV1dID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgZm9yIChqID0gMDsgaiA8IEdMX0xJTUlUUyh0ZXh0dXJlcyk7IGorKykgewogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1Q7IGkrKykgewogICAgICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnRleHR1cmVTdGF0ZVtqXVtTYXZlZFZlcnRleFN0YXRlc19UW2ldXSA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChqID0gMCA7IGogPCAxNjsgaisrKXsKICAgICAgICAgICAgZm9yIChpID0wOyBpIDwgTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1M7aSsrKSB7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQuc2FtcGxlclN0YXRlW2pdW1NhdmVkVmVydGV4U3RhdGVzX1NbaV1dID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAvKiBEdXBsaWNhdGUgbGlnaHQgY2hhaW4gKi8KICAgIHsKICAgICAgICBQTElHSFRJTkZPRUwgKnNyYyA9IE5VTEw7CiAgICAgICAgUExJR0hUSU5GT0VMICpkc3QgPSBOVUxMOwogICAgICAgIFBMSUdIVElORk9FTCAqbmV3RWwgPSBOVUxMOwogICAgICAgIHNyYyA9IFRoaXMtPnN0YXRlQmxvY2stPmxpZ2h0czsKICAgICAgICBvYmplY3QtPmxpZ2h0cyA9IE5VTEw7CgoKICAgICAgICB3aGlsZSAoc3JjKSB7CiAgICAgICAgICAgIG5ld0VsID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihQTElHSFRJTkZPRUwpKTsKICAgICAgICAgICAgaWYgKG5ld0VsID09IE5VTEwpIHJldHVybiBXSU5FRDNERVJSX09VVE9GVklERU9NRU1PUlk7CiAgICAgICAgICAgIG1lbWNweShuZXdFbCwgc3JjLCBzaXplb2YoUExJR0hUSU5GT0VMKSk7CiAgICAgICAgICAgIG5ld0VsLT5wcmV2ID0gZHN0OwogICAgICAgICAgICBuZXdFbC0+Y2hhbmdlZCA9IFRSVUU7CiAgICAgICAgICAgIG5ld0VsLT5lbmFibGVkQ2hhbmdlZCA9IFRSVUU7CiAgICAgICAgICAgIGlmIChkc3QgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgb2JqZWN0LT5saWdodHMgPSBuZXdFbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGRzdC0+bmV4dCA9IG5ld0VsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRzdCA9IG5ld0VsOwogICAgICAgICAgICBzcmMgPSBzcmMtPm5leHQ7CiAgICAgICAgfQoKICAgICB9CgogICAgfSBlbHNlIHsKICAgICAgICBGSVhNRSgiVW5yZWNvZ25pemVkIHN0YXRlIGJsb2NrIHR5cGUgJWRcbiIsIFR5cGUpOwogICAgfQoKICAgIFRSQUNFKCIoJXApIHJldHVybmluZyB0b2tlbiAocHRyIHRvIHN0YXRlYmxvY2spIG9mICVwXG4iLCBUaGlzLCBvYmplY3QpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKTVNETjoKW2luXSBSZW5kZXIgdGFyZ2V0cyBhcmUgbm90IGxvY2thYmxlIHVubGVzcyB0aGUgYXBwbGljYXRpb24gc3BlY2lmaWVzIFRSVUUgZm9yIExvY2thYmxlLiBOb3RlIHRoYXQgbG9ja2FibGUgcmVuZGVyIHRhcmdldHMgcmVkdWNlIHBlcmZvcm1hbmNlIG9uIHNvbWUgZ3JhcGhpY3MgaGFyZHdhcmUuCgpEaXNjYXJkCiBbaW5dIFNldCB0aGlzIGZsYWcgdG8gVFJVRSB0byBlbmFibGUgei1idWZmZXIgZGlzY2FyZGluZywgYW5kIEZBTFNFIG90aGVyd2lzZS4gCgpJZiB0aGlzIGZsYWcgaXMgc2V0LCB0aGUgY29udGVudHMgb2YgdGhlIGRlcHRoIHN0ZW5jaWwgYnVmZmVyIHdpbGwgYmUgaW52YWxpZCBhZnRlciBjYWxsaW5nIGVpdGhlciBJRGlyZWN0M0REZXZpY2U5OjpQcmVzZW50IG9yIElEaXJlY3QzRERldmljZTk6OlNldERlcHRoU3RlbmNpbFN1cmZhY2Ugd2l0aCBhIGRpZmZlcmVudCBkZXB0aCBzdXJmYWNlLgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KIApIUkVTVUxUICBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVN1cmZhY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFdpZHRoLCBVSU5UIEhlaWdodCwgV0lORUQzREZPUk1BVCBGb3JtYXQsIEJPT0wgTG9ja2FibGUsIEJPT0wgRGlzY2FyZCwgVUlOVCBMZXZlbCwgSVdpbmVEM0RTdXJmYWNlICoqcHBTdXJmYWNlLFdJTkVEM0RSRVNPVVJDRVRZUEUgVHlwZSwgRFdPUkQgVXNhZ2UsIFdJTkVEM0RQT09MIFBvb2wsIFdJTkVEM0RNVUxUSVNBTVBMRV9UWVBFIE11bHRpU2FtcGxlICxEV09SRCBNdWx0aXNhbXBsZVF1YWxpdHksIEhBTkRMRSogcFNoYXJlZEhhbmRsZSwgV0lORUQzRFNVUkZUWVBFIEltcGwsIElVbmtub3duICpwYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7ICAgIAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqb2JqZWN0OyAvKk5PVEU6IGltcGwgcmVmIGFsbG93ZWQgc2luY2UgdGhpcyBpcyBhIGNyZWF0ZSBmdW5jdGlvbiAqLwogICAgdW5zaWduZWQgaW50IHBvdzJXaWR0aCwgcG93MkhlaWdodDsKICAgIHVuc2lnbmVkIGludCBTaXplICAgICAgID0gMTsKICAgIFRSQUNFKCIoJXApIENyZWF0ZSBzdXJmYWNlXG4iLFRoaXMpOwogICAgCiAgICAvKiogRklYTUU6IENoZWNrIHJhbmdlcyBvbiB0aGUgaW5wdXRzIGFyZSB2YWxpZCAKICAgICAqIE1TRE4KICAgICAqICAgTXVsdGlzYW1wbGVRdWFsaXR5CiAgICAgKiAgICBbaW5dIFF1YWxpdHkgbGV2ZWwuIFRoZSB2YWxpZCByYW5nZSBpcyBiZXR3ZWVuIHplcm8gYW5kIG9uZSBsZXNzIHRoYW4gdGhlIGxldmVsCiAgICAgKiAgICByZXR1cm5lZCBieSBwUXVhbGl0eUxldmVscyB1c2VkIGJ5IElEaXJlY3QzRDk6OkNoZWNrRGV2aWNlTXVsdGlTYW1wbGVUeXBlLiAKICAgICAqICAgIFBhc3NpbmcgYSBsYXJnZXIgdmFsdWUgcmV0dXJucyB0aGUgZXJyb3IgV0lORUQzREVSUl9JTlZBTElEQ0FMTC4gVGhlIE11bHRpc2FtcGxlUXVhbGl0eQogICAgICogICAgdmFsdWVzIG9mIHBhaXJlZCByZW5kZXIgdGFyZ2V0cywgZGVwdGggc3RlbmNpbCBzdXJmYWNlcywgYW5kIHRoZSBNdWx0aVNhbXBsZSB0eXBlCiAgICAgKiAgICBtdXN0IGFsbCBtYXRjaC4KICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgogICAgLyoqCiAgICAqIFRPRE86IERpc2NhcmQgTVNETgogICAgKiBbaW5dIFNldCB0aGlzIGZsYWcgdG8gVFJVRSB0byBlbmFibGUgei1idWZmZXIgZGlzY2FyZGluZywgYW5kIEZBTFNFIG90aGVyd2lzZS4KICAgICoKICAgICogSWYgdGhpcyBmbGFnIGlzIHNldCwgdGhlIGNvbnRlbnRzIG9mIHRoZSBkZXB0aCBzdGVuY2lsIGJ1ZmZlciB3aWxsIGJlCiAgICAqIGludmFsaWQgYWZ0ZXIgY2FsbGluZyBlaXRoZXIgSURpcmVjdDNERGV2aWNlOTo6UHJlc2VudCBvciAgKiBJRGlyZWN0M0REZXZpY2U5OjpTZXREZXB0aFN0ZW5jaWxTdXJmYWNlCiAgICAqIHdpdGggYSBkaWZmZXJlbnQgZGVwdGggc3VyZmFjZS4KICAgICoKICAgICpUaGlzIGZsYWcgaGFzIHRoZSBzYW1lIGJlaGF2aW9yIGFzIHRoZSBjb25zdGFudCwgRDNEUFJFU0VOVEZMQUdfRElTQ0FSRF9ERVBUSFNURU5DSUwsIGluIEQzRFBSRVNFTlRGTEFHLgogICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIGlmKE11bHRpc2FtcGxlUXVhbGl0eSA8IDApIHsKICAgICAgICBGSVhNRSgiSW52YWxpZCBtdWx0aXNhbXBsZSBsZXZlbCAlbGRcbiIsIE11bHRpc2FtcGxlUXVhbGl0eSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7IC8qIFRPRE86IENoZWNrIHRoYXQgdGhpcyBpcyB0aGUgY2FzZSEgKi8KICAgIH0KCiAgICBpZihNdWx0aXNhbXBsZVF1YWxpdHkgPiAwKSB7CiAgICAgICAgRklYTUUoIk11bHRpc2FtcGxlUXVhbGl0eSBzZXQgdG8gJWxkLCBzdWJzdGl0dXRpbmcgMFxuIiwgTXVsdGlzYW1wbGVRdWFsaXR5KTsKICAgICAgICBNdWx0aXNhbXBsZVF1YWxpdHk9MDsKICAgIH0KCiAgICAvKiogRklYTUU6IENoZWNrIHRoYXQgdGhlIGZvcm1hdCBpcyBzdXBwb3J0ZWQKICAgICogICAgYnkgdGhlIGRldmljZS4KICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiBOb24tcG93ZXIyIHN1cHBvcnQgKi8KCiAgICAvKiBGaW5kIHRoZSBuZWFyZXN0IHBvdzIgbWF0Y2ggKi8KICAgIHBvdzJXaWR0aCA9IHBvdzJIZWlnaHQgPSAxOwogICAgd2hpbGUgKHBvdzJXaWR0aCA8IFdpZHRoKSBwb3cyV2lkdGggPDw9IDE7CiAgICB3aGlsZSAocG93MkhlaWdodCA8IEhlaWdodCkgcG93MkhlaWdodCA8PD0gMTsKCiAgICBpZiAocG93MldpZHRoID4gV2lkdGggfHwgcG93MkhlaWdodCA+IEhlaWdodCkgewogICAgICAgICAvKiogVE9ETzogYWRkIHN1cHBvcnQgZm9yIG5vbiBwb3dlciB0d28gY29tcHJlc3NlZCB0ZXh0dXJlcyAoT3BlbkdMIDIgcHJvdmljZXMgc3VwcG9ydCBmb3IgKiBub24tcG93ZXItdHdvIHRleHR1cmVzIGdyYXRpcykgKiovCiAgICAgICAgaWYgKEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzCiAgICAgICAgICAgICAgIHx8IEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgICAgICBGSVhNRSgiKCVwKSBDb21wcmVzc2VkIG5vbi1wb3dlci10d28gdGV4dHVyZXMgYXJlIG5vdCBzdXBwb3J0ZWQgdyglZCkgaCglZClcbiIsCiAgICAgICAgICAgICAgICAgICAgVGhpcywgV2lkdGgsIEhlaWdodCk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIENoZWNrIGFnYWluc3QgdGhlIG1heGltdW0gdGV4dHVyZSBzaXplcyBzdXBwb3J0ZWQgYnkgdGhlIHZpZGVvIGNhcmQgKiovCiAgICBpZiAocG93MldpZHRoID4gR0xfTElNSVRTKHRleHR1cmVfc2l6ZSkgfHwgcG93MkhlaWdodCA+IEdMX0xJTUlUUyh0ZXh0dXJlX3NpemUpKSB7CiAgICAgICAgLyogb25lIG9mIHRocmVlIG9wdGlvbnMKICAgICAgICAxOiBEbyB0aGUgc2FtZSBhcyB3ZSBkbyB3aXRoIG5vbnBvdyAyIGFuZCBzY2FsZSB0aGUgdGV4dHVyZSwgKGFueSB0ZXh0dXJlIG9wcyB3b3VsZCByZXF1aXJlIHRoZSB0ZXh0dXJlIHRvIGJlIHNjYWxlZCB3aGljaCBpcyBwb3RlbnRpYWxseSBzbG93KQogICAgICAgIDI6IFNldCB0aGUgdGV4dHVyZSB0byB0aGUgbWF4aXVtIHNpemUgKGJhZCBpZGVhKQogICAgICAgIDM6ICAgIFdBUk4gYW5kIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICAqLwogICAgICAgIFdBUk4oIiglcCkgQXBwbGljYXRpb24gcmVxdWVzdGVkIGEgc3VyZmFjZSB3ICVkLCBoICVkLCBidXQgdGhlIGdyYXBoaWNzIGNhcmQgb25seSBzdXBwb3J0cyAlZFxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwgR0xfTElNSVRTKHRleHR1cmVfc2l6ZSkpOwogICAgICAgICByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICB9CgoKCiAgICAvKiogRFhUbiBtaXBtYXBzIHVzZSB0aGUgc2FtZSBudW1iZXIgb2YgJ2xldmVscycgZG93biB0byBlZy4gOHgxLCBidXQgc2luY2UKICAgICAqICBpdCBpcyBiYXNlZCBhcm91bmQgNHg0IHBpeGVsIGJsb2NrcyBpdCByZXF1aXJlcyBwYWRkaW5nLCBzbyBhbGxvY2F0ZSBlbm91Z2gKICAgICAqICBzcGFjZSEKICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgaWYgKFdJTkVEM0RGTVRfVU5LTk9XTiA9PSBGb3JtYXQpIHsKICAgICAgICBTaXplID0gMDsKICAgIH0gZWxzZSBpZiAoRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkgewogICAgICAgIC8qIERYVDEgaXMgaGFsZiBieXRlIHBlciBwaXhlbCAqLwogICAgICAgU2l6ZSA9ICgobWF4KHBvdzJXaWR0aCw0KSAqIEQzREZtdEdldEJwcChUaGlzLCBGb3JtYXQpKSAqIG1heChwb3cySGVpZ2h0LDQpKSA+PiAxOwoKICAgIH0gZWxzZSBpZiAoRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgICAgIEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgU2l6ZSA9ICgobWF4KHBvdzJXaWR0aCw0KSAqIEQzREZtdEdldEJwcChUaGlzLCBGb3JtYXQpKSAqIG1heChwb3cySGVpZ2h0LDQpKTsKICAgIH0gZWxzZSB7CiAgICAgICBTaXplID0gKHBvdzJXaWR0aCAqIEQzREZtdEdldEJwcChUaGlzLCBGb3JtYXQpKSAqIHBvdzJIZWlnaHQ7CiAgICB9CgogICAgLyoqIENyZWF0ZSBhbmQgaW5pdGlhbGlzZSB0aGUgc3VyZmFjZSByZXNvdXJjZSAqKi8KICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LFN1cmZhY2UsV0lORUQzRFJUWVBFX1NVUkZBQ0UsIFNpemUpCiAgICAvKiAiU3RhbmRhbG9uZSIgc3VyZmFjZSAqLwogICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcigoSVdpbmVEM0RTdXJmYWNlICopb2JqZWN0LCBOVUxMKTsKCiAgICBvYmplY3QtPmN1cnJlbnREZXNjLldpZHRoICAgICAgPSBXaWR0aDsKICAgIG9iamVjdC0+Y3VycmVudERlc2MuSGVpZ2h0ICAgICA9IEhlaWdodDsKICAgIG9iamVjdC0+Y3VycmVudERlc2MuTXVsdGlTYW1wbGVUeXBlICAgID0gTXVsdGlTYW1wbGU7CiAgICBvYmplY3QtPmN1cnJlbnREZXNjLk11bHRpU2FtcGxlUXVhbGl0eSA9IE11bHRpc2FtcGxlUXVhbGl0eTsKCiAgICAvKiBTZXR1cCBzb21lIGdsZm9ybWF0IGRlZmF1bHRzICovCiAgICBpZiAoV0lORUQzREZNVF9VTktOT1dOICE9IEZvcm1hdCkgewogICAgICAgIG9iamVjdC0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCAgICAgICAgID0gRDNERm10MkdMRm10KFRoaXMsIG9iamVjdC0+cmVzb3VyY2UuZm9ybWF0KTsKICAgICAgICBvYmplY3QtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXRJbnRlcm5hbCA9IEQzREZtdDJHTEludEZtdChUaGlzLCBvYmplY3QtPnJlc291cmNlLmZvcm1hdCk7CiAgICAgICAgb2JqZWN0LT5nbERlc2NyaXB0aW9uLmdsVHlwZSAgICAgICAgICAgPSBEM0RGbXQyR0xUeXBlKFRoaXMsIG9iamVjdC0+cmVzb3VyY2UuZm9ybWF0KTsKICAgIH0gZWxzZSB7CiAgICAgICAgb2JqZWN0LT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0ICAgICAgICAgPSAwOwogICAgICAgIG9iamVjdC0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsID0gMDsKICAgICAgICBvYmplY3QtPmdsRGVzY3JpcHRpb24uZ2xUeXBlICAgICAgICAgICA9IDA7CiAgICB9CgogICAgb2JqZWN0LT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lICAgICAgPSAwOwogICAgb2JqZWN0LT5nbERlc2NyaXB0aW9uLmxldmVsICAgICAgICAgICAgPSBMZXZlbDsKICAgIG9iamVjdC0+Z2xEZXNjcmlwdGlvbi50YXJnZXQgICAgICAgICAgID0gR0xfVEVYVFVSRV8yRDsKCiAgICAvKiBJbnRlcm5hbCBkYXRhICovCiAgICBvYmplY3QtPnBvdzJXaWR0aCAgPSBwb3cyV2lkdGg7CiAgICBvYmplY3QtPnBvdzJIZWlnaHQgPSBwb3cySGVpZ2h0OwoKICAgIC8qIEZsYWdzICovCiAgICBvYmplY3QtPkZsYWdzICAgICAgPSAwOyAvKiBXZSBzdGFydCB3aXRob3V0IGZsYWdzIHNldCAqLwogICAgb2JqZWN0LT5GbGFncyAgICAgfD0gKHBvdzJXaWR0aCAhPSBXaWR0aCB8fCBwb3cySGVpZ2h0ICE9IEhlaWdodCkgPyBTRkxBR19OT05QT1cyIDogMDsKICAgIG9iamVjdC0+RmxhZ3MgICAgIHw9IERpc2NhcmQgPyBTRkxBR19ESVNDQVJEIDogMDsKICAgIG9iamVjdC0+RmxhZ3MgICAgIHw9IChXSU5FRDNERk1UX0QxNl9MT0NLQUJMRSA9PSBGb3JtYXQpID8gU0ZMQUdfTE9DS0FCTEUgOiAwOwogICAgb2JqZWN0LT5GbGFncyAgICAgfD0gTG9ja2FibGUgPyBTRkxBR19MT0NLQUJMRSA6IDA7CgoKICAgIGlmIChXSU5FRDNERk1UX1VOS05PV04gIT0gRm9ybWF0KSB7CiAgICAgICAgb2JqZWN0LT5ieXRlc1BlclBpeGVsID0gRDNERm10R2V0QnBwKFRoaXMsIEZvcm1hdCk7CiAgICAgICAgb2JqZWN0LT5wb3cyU2l6ZSAgICAgID0gKHBvdzJXaWR0aCAqIG9iamVjdC0+Ynl0ZXNQZXJQaXhlbCkgKiBwb3cySGVpZ2h0OwogICAgfSBlbHNlIHsKICAgICAgICBvYmplY3QtPmJ5dGVzUGVyUGl4ZWwgPSAwOwogICAgICAgIG9iamVjdC0+cG93MlNpemUgICAgICA9IDA7CiAgICB9CgogICAgLyoqIFRPRE86IGNoYW5nZSB0aGlzIGludG8gYSB0ZXh0dXJlIHRyYW5zZm9ybSBtYXRyaXggc28gdGhhdCBpdCdzIHByb2Nlc3NlZCBpbiBoYXJkd2FyZSAqKi8KCiAgICBUUkFDRSgiUG9vbCAlZCAlZCAlZCAlZCIsUG9vbCwgV0lORUQzRFBPT0xfREVGQVVMVCwgV0lORUQzRFBPT0xfTUFOQUdFRCwgV0lORUQzRFBPT0xfU1lTVEVNTUVNKTsKCiAgICAvKiogUXVpY2sgbG9ja2FibGUgc2FuaXR5IGNoZWNrIFRPRE86IHJlbW92ZSB0aGlzIGFmdGVyIHN1cmZhY2VzLCB1c2FnZSBhbmQgbG9jYWJsaWxpdHkgaGF2ZSBiZWVuIGRlYnVnZ2VkIHByb3Blcmx5CiAgICAqIHRoaXMgZnVuY3Rpb24gaXMgdG9vIGRlYXAgdG8gbmVlZCB0byBjYXJlIGFib3V0IHRoaW5ncyBsaWtlIHRoaXMuCiAgICAqIExldmVscyBuZWVkIHRvIGJlIGNoZWNrZWQgdG9vLCBhbmQgcG9zc2libHkgVHlwZSB3aW5jZSB0aGV5IGFsbCBhZmZlY3Qgd2hhdCBjYW4gYmUgZG9uZS4KICAgICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIHN3aXRjaChQb29sKSB7CiAgICBjYXNlIFdJTkVEM0RQT09MX1NDUkFUQ0g6CiAgICAgICAgaWYoTG9ja2FibGUgPT0gRkFMU0UpCiAgICAgICAgICAgIEZJWE1FKCJDcmVhdGUgc3VmYWNlIGNhbGxlZCB3aXRoIGEgcG9vbCBvZiBTQ1JBVENIIGFuZCBhIExvY2thYmxlIG9mIEZBTFNFIFwKICAgICAgICAgICAgICAgIHdoaWNoIGFyZSBtdXR1YWxseSBleGNsdXNpdmUsIHNldHRpbmcgbG9ja2FibGUgdG8gdHJ1ZVxuIik7CiAgICAgICAgICAgICAgICBMb2NrYWJsZSA9IFRSVUU7CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFBPT0xfU1lTVEVNTUVNOgogICAgICAgIGlmKExvY2thYmxlID09IEZBTFNFKSBGSVhNRSgiQ3JlYXRlIHN1cmZhY2UgY2FsbGVkIHdpdGggYSBwb29sIG9mIFNZU1RFTU1FTSBhbmQgYSBMb2NrYWJsZSBvZiBGQUxTRSwgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGlzIGFjY2VwdGFibGUgYnV0IHVuZXhwZWN0ZWQgKEkgY2FuJ3Qga25vdyBob3cgdGhlIHN1cmZhY2UgY2FuIGJlIHVzYWJsZSEpXG4iKTsKICAgIGNhc2UgV0lORUQzRFBPT0xfTUFOQUdFRDoKICAgICAgICBpZihVc2FnZSA9PSBXSU5FRDNEVVNBR0VfRFlOQU1JQykgRklYTUUoIkNyZWF0ZSBzdXJmYWNlIGNhbGxlZCB3aXRoIGEgcG9vbCBvZiBNQU5BR0VEIGFuZCBhIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXNhZ2Ugb2YgRFlOQU1JQyB3aGljaCBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLCBub3QgZG9pbmcgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnl0aGluZyBqdXN0IHRlbGxpbmcgeW91LlxuIik7CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFBPT0xfREVGQVVMVDogLypUT0RPOiBDcmVhdGUgb2Zmc2NyZWVuIHBsYWluIGNhbiBjYXVzZSB0aGlzIGNoZWNrIHRvIGZhaWwuLi4sIGZpbmQgb3V0IGlmIGl0IHNob3VsZCAqLwogICAgICAgIGlmKCEoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfRFlOQU1JQykgJiYgIShVc2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpCiAgICAgICAgICAgJiYgIShVc2FnZSAmJiBXSU5FRDNEVVNBR0VfREVQVEhTVEVOQ0lMICkgJiYgTG9ja2FibGUgPT0gVFJVRSkKICAgICAgICAgICAgRklYTUUoIkNyZWF0aW5nIGEgc3VyZmFjZSB3aXRoIGEgUE9PTCBvZiBERUZBVUxUIHdpdGggTG9jYWJsZSB0cnVlLCB0aGF0IGRvZXNuJ3Qgc3BlY2lmeSBEWU5BTUlDIHVzYWdlLlxuIik7CiAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIiglcCkgVW5rbm93biBwb29sICVkXG4iLCBUaGlzLCBQb29sKTsKICAgIGJyZWFrOwogICAgfTsKCiAgICBpZiAoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUICYmIFBvb2wgIT0gV0lORUQzRFBPT0xfREVGQVVMVCkgewogICAgICAgIEZJWE1FKCJUcnlpbmcgdG8gY3JlYXRlIGEgcmVuZGVyIHRhcmdldCB0aGF0IGlzbid0IGluIHRoZSBkZWZhdWx0IHBvb2xcbiIpOwogICAgfQoKICAgIC8qIG1hcmsgdGhlIHRleHR1cmUgYXMgZGlydHkgc28gdGhhdCBpdCBnZXQncyBsb2FkZWQgZmlyc3QgdGltZSBhcm91bmQqLwogICAgSVdpbmVEM0RTdXJmYWNlX0FkZERpcnR5UmVjdCgqcHBTdXJmYWNlLCBOVUxMKTsKICAgIFRSQUNFKCIoJXApIDogdyglZCkgaCglZCkgZm10KCVkLCVzKSBsb2NrYWJsZSglZCkgc3VyZkAlcCwgc3VyZm1lbUAlcCwgJWQgYnl0ZXNcbiIsCiAgICAgICAgICAgVGhpcywgV2lkdGgsIEhlaWdodCwgRm9ybWF0LCBkZWJ1Z19kM2Rmb3JtYXQoRm9ybWF0KSwKICAgICAgICAgICAoV0lORUQzREZNVF9EMTZfTE9DS0FCTEUgPT0gRm9ybWF0KSwgKnBwU3VyZmFjZSwgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIG9iamVjdC0+cmVzb3VyY2Uuc2l6ZSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKCn0KCkhSRVNVTFQgIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVGV4dHVyZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgV2lkdGgsIFVJTlQgSGVpZ2h0LCBVSU5UIExldmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFVzYWdlLCBXSU5FRDNERk9STUFUIEZvcm1hdCwgV0lORUQzRFBPT0wgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVGV4dHVyZSoqIHBwVGV4dHVyZSwgSEFORExFKiBwU2hhcmVkSGFuZGxlLCBJVW5rbm93biAqcGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0JfQ1JFQVRFU1VSRkFDRUZOIEQzRENCX0NyZWF0ZVN1cmZhY2UpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFRleHR1cmVJbXBsICpvYmplY3Q7CiAgICB1bnNpZ25lZCBpbnQgaTsKICAgIFVJTlQgdG1wVzsKICAgIFVJTlQgdG1wSDsKICAgIEhSRVNVTFQgaHI7CiAgICB1bnNpZ25lZCBpbnQgcG93MldpZHRoICA9IFdpZHRoOwogICAgdW5zaWduZWQgaW50IHBvdzJIZWlnaHQgPSBIZWlnaHQ7CgoKICAgIFRSQUNFKCIoJXApLCBXaWR0aCglZCkgSGVpZ2h0KCVkKSBMZXZlbHMoJWQpIFVzYWdlKCVsZCkgLi4uLlxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwgTGV2ZWxzLCBVc2FnZSk7CgogICAgLyogVE9ETzogSXQgc2hvdWxkIG9ubHkgYmUgcG9zc2libGUgdG8gY3JlYXRlIHRleHR1cmVzIGZvciBmb3JtYXRzIAogICAgICAgICAgICAgdGhhdCBhcmUgcmVwb3J0ZWQgYXMgc3VwcG9ydGVkICovCiAgICBpZiAoV0lORUQzREZNVF9VTktOT1dOID49IEZvcm1hdCkgewogICAgICAgIFdBUk4oIiglcCkgOiBUZXh0dXJlIGNhbm5vdCBiZSBjcmVhdGVkIHdpdGggYSBmb3JtYXQgb2YgRDNERk1UX1VOS05PV05cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBUZXh0dXJlLCBXSU5FRDNEUlRZUEVfVEVYVFVSRSwgMCk7CiAgICBEM0RJTklUSUFMSVpFQkFTRVRFWFRVUkUob2JqZWN0LT5iYXNlVGV4dHVyZSk7ICAgIAogICAgb2JqZWN0LT53aWR0aCAgPSBXaWR0aDsKICAgIG9iamVjdC0+aGVpZ2h0ID0gSGVpZ2h0OwoKICAgIC8qKiBOb24tcG93ZXIyIHN1cHBvcnQgKiovCiAgICAvKiBGaW5kIHRoZSBuZWFyZXN0IHBvdzIgbWF0Y2ggKi8KICAgIHBvdzJXaWR0aCA9IHBvdzJIZWlnaHQgPSAxOwogICAgd2hpbGUgKHBvdzJXaWR0aCA8IFdpZHRoKSBwb3cyV2lkdGggPDw9IDE7CiAgICB3aGlsZSAocG93MkhlaWdodCA8IEhlaWdodCkgcG93MkhlaWdodCA8PD0gMTsKCiAgICAvKiogRklYTUU6IGFkZCBzdXBwb3J0IGZvciByZWFsIG5vbi1wb3dlci10d28gaWYgaXQncyBwcm92aWRlZCBieSB0aGUgdmlkZW8gY2FyZCAqKi8KICAgIC8qIFByZWNhbGN1bGF0ZWQgc2NhbGluZyBmb3IgJ2Zha2VkJyBub24gcG93ZXIgb2YgdHdvIHRleHR1cmUgY29vcmRzICovCiAgICBvYmplY3QtPnBvdzJzY2FsaW5nRmFjdG9yWCAgPSAgKCgoZmxvYXQpV2lkdGgpICAvICgoZmxvYXQpcG93MldpZHRoKSk7CiAgICBvYmplY3QtPnBvdzJzY2FsaW5nRmFjdG9yWSAgPSAgKCgoZmxvYXQpSGVpZ2h0KSAvICgoZmxvYXQpcG93MkhlaWdodCkpOwogICAgVFJBQ0UoIiB4ZiglZikgeWYoJWYpXG4iLCBvYmplY3QtPnBvdzJzY2FsaW5nRmFjdG9yWCwgb2JqZWN0LT5wb3cyc2NhbGluZ0ZhY3RvclkpOwoKICAgIC8qIENhbGN1bGF0ZSBsZXZlbHMgZm9yIG1pcCBtYXBwaW5nICovCiAgICBpZiAoTGV2ZWxzID09IDApIHsKICAgICAgICBUUkFDRSgiY2FsY3VsYXRpbmcgbGV2ZWxzICVkXG4iLCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscyk7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMrKzsKICAgICAgICB0bXBXID0gV2lkdGg7CiAgICAgICAgdG1wSCA9IEhlaWdodDsKICAgICAgICB3aGlsZSAodG1wVyA+IDEgfHwgdG1wSCA+IDEpIHsKICAgICAgICAgICAgdG1wVyA9IG1heCgxLCB0bXBXID4+IDEpOwogICAgICAgICAgICB0bXBIID0gbWF4KDEsIHRtcEggPj4gMSk7CiAgICAgICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKys7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDYWxjdWxhdGVkIGxldmVscyA9ICVkXG4iLCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscyk7CiAgICB9CgogICAgLyogR2VuZXJhdGUgYWxsIHRoZSBzdXJmYWNlcyAqLwogICAgdG1wVyA9IFdpZHRoOwogICAgdG1wSCA9IEhlaWdodDsKICAgIGZvciAoaSA9IDA7IGkgPCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVsczsgaSsrKQogICAgewogICAgICAgIC8qIHVzZSB0aGUgY2FsbGJhY2sgdG8gY3JlYXRlIHRoZSB0ZXh0dXJlIHN1cmZhY2UgKi8KICAgICAgICBociA9IEQzRENCX0NyZWF0ZVN1cmZhY2UoVGhpcy0+cGFyZW50LCB0bXBXLCB0bXBILCBGb3JtYXQsIFVzYWdlLCBQb29sLCBpLCAmb2JqZWN0LT5zdXJmYWNlc1tpXSxOVUxMKTsKICAgICAgICBpZiAoaHIhPSBXSU5FRDNEX09LKSB7CiAgICAgICAgICAgIGludCBqOwogICAgICAgICAgICBGSVhNRSgiRmFpbGVkIHRvIGNyZWF0ZSBzdXJmYWNlICAlcFxuIiwgb2JqZWN0KTsKICAgICAgICAgICAgLyogY2xlYW4gdXAgKi8KICAgICAgICAgICAgZm9yIChqID0gMCA7IGogPCBpIDsgaisrKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShvYmplY3QtPnN1cmZhY2VzW2pdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBoZWFwIGZyZWUgb2JqZWN0ICovCiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7CgogICAgICAgICAgICAqcHBUZXh0dXJlID0gTlVMTDsKICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgIH0KCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihvYmplY3QtPnN1cmZhY2VzW2ldLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKICAgICAgICBUUkFDRSgiQ3JlYXRlZCBzdXJmYWNlIGxldmVsICVkIEAgJXBcbiIsIGksIG9iamVjdC0+c3VyZmFjZXNbaV0pOwogICAgICAgIC8qIGNhbGN1bGF0ZSB0aGUgbmV4dCBtaXBtYXAgbGV2ZWwgKi8KICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgdG1wSCA9IG1heCgxLCB0bXBIID4+IDEpOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCAgdGV4dHVyZSAlcFxuIiwgVGhpcywgb2JqZWN0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVm9sdW1lVGV4dHVyZShJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgV2lkdGgsIFVJTlQgSGVpZ2h0LCBVSU5UIERlcHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIExldmVscywgRFdPUkQgVXNhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBXSU5FRDNEUE9PTCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZVRleHR1cmUgKipwcFZvbHVtZVRleHR1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSAqcFNoYXJlZEhhbmRsZSwgSVVua25vd24gKnBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0JfQ1JFQVRFVk9MVU1FRk4gRDNEQ0JfQ3JlYXRlVm9sdW1lKSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVm9sdW1lVGV4dHVyZUltcGwgKm9iamVjdDsKICAgIHVuc2lnbmVkIGludCAgICAgICAgICAgICAgIGk7CiAgICBVSU5UICAgICAgICAgICAgICAgICAgICAgICB0bXBXOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgICAgdG1wSDsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgIHRtcEQ7CgogICAgLyogVE9ETzogSXQgc2hvdWxkIG9ubHkgYmUgcG9zc2libGUgdG8gY3JlYXRlIHRleHR1cmVzIGZvciBmb3JtYXRzIAogICAgICAgICAgICAgdGhhdCBhcmUgcmVwb3J0ZWQgYXMgc3VwcG9ydGVkICovCiAgICBpZiAoV0lORUQzREZNVF9VTktOT1dOID49IEZvcm1hdCkgewogICAgICAgIFdBUk4oIiglcCkgOiBUZXh0dXJlIGNhbm5vdCBiZSBjcmVhdGVkIHdpdGggYSBmb3JtYXQgb2YgRDNERk1UX1VOS05PV05cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBWb2x1bWVUZXh0dXJlLCBXSU5FRDNEUlRZUEVfVk9MVU1FVEVYVFVSRSwgMCk7CiAgICBEM0RJTklUSUFMSVpFQkFTRVRFWFRVUkUob2JqZWN0LT5iYXNlVGV4dHVyZSk7CgogICAgVFJBQ0UoIiglcCkgOiBXKCVkKSBIKCVkKSBEKCVkKSwgTHZsKCVkKSBVc2FnZSglbGQpLCBGbXQoJXUsJXMpLCBQb29sKCVzKVxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwKICAgICAgICAgIERlcHRoLCBMZXZlbHMsIFVzYWdlLCBGb3JtYXQsIGRlYnVnX2QzZGZvcm1hdChGb3JtYXQpLCBkZWJ1Z19kM2Rwb29sKFBvb2wpKTsKCiAgICBvYmplY3QtPndpZHRoICA9IFdpZHRoOwogICAgb2JqZWN0LT5oZWlnaHQgPSBIZWlnaHQ7CiAgICBvYmplY3QtPmRlcHRoICA9IERlcHRoOwoKICAgIC8qIENhbGN1bGF0ZSBsZXZlbHMgZm9yIG1pcCBtYXBwaW5nICovCiAgICBpZiAoTGV2ZWxzID09IDApIHsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscysrOwogICAgICAgIHRtcFcgPSBXaWR0aDsKICAgICAgICB0bXBIID0gSGVpZ2h0OwogICAgICAgIHRtcEQgPSBEZXB0aDsKICAgICAgICB3aGlsZSAodG1wVyA+IDEgfHwgdG1wSCA+IDEgfHwgdG1wRCA+IDEpIHsKICAgICAgICAgICAgdG1wVyA9IG1heCgxLCB0bXBXID4+IDEpOwogICAgICAgICAgICB0bXBIID0gbWF4KDEsIHRtcEggPj4gMSk7CiAgICAgICAgICAgIHRtcEQgPSBtYXgoMSwgdG1wRCA+PiAxKTsKICAgICAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMrKzsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIkNhbGN1bGF0ZWQgbGV2ZWxzID0gJWRcbiIsIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKTsKICAgIH0KCiAgICAvKiBHZW5lcmF0ZSBhbGwgdGhlIHN1cmZhY2VzICovCiAgICB0bXBXID0gV2lkdGg7CiAgICB0bXBIID0gSGVpZ2h0OwogICAgdG1wRCA9IERlcHRoOwoKICAgIGZvciAoaSA9IDA7IGkgPCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVsczsgaSsrKQogICAgewogICAgICAgIC8qIENyZWF0ZSB0aGUgdm9sdW1lICovCiAgICAgICAgRDNEQ0JfQ3JlYXRlVm9sdW1lKFRoaXMtPnBhcmVudCwgV2lkdGgsIEhlaWdodCwgRGVwdGgsIEZvcm1hdCwgUG9vbCwgVXNhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIChJV2luZUQzRFZvbHVtZSAqKikmb2JqZWN0LT52b2x1bWVzW2ldLCBwU2hhcmVkSGFuZGxlKTsKCiAgICAgICAgLyogU2V0IGl0J3MgY29udGFpbmVyIHRvIHRoaXMgb2JqZWN0ICovCiAgICAgICAgSVdpbmVEM0RWb2x1bWVfU2V0Q29udGFpbmVyKG9iamVjdC0+dm9sdW1lc1tpXSwgKElXaW5lRDNEQmFzZSAqKW9iamVjdCk7CgogICAgICAgIC8qIGNhbGN1YWx0ZSB0aGUgbmV4dCBtaXBtYXAgbGV2ZWwgKi8KICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgdG1wSCA9IG1heCgxLCB0bXBIID4+IDEpOwogICAgICAgIHRtcEQgPSBtYXgoMSwgdG1wRCA+PiAxKTsKICAgIH0KCiAgICAqcHBWb2x1bWVUZXh0dXJlID0gKElXaW5lRDNEVm9sdW1lVGV4dHVyZSAqKSBvYmplY3Q7CiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgdm9sdW1lIHRleHR1cmUgJXBcbiIsIFRoaXMsIG9iamVjdCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZvbHVtZShJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBXaWR0aCwgVUlOVCBIZWlnaHQsIFVJTlQgRGVwdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVXNhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREZPUk1BVCBGb3JtYXQsIFdJTkVEM0RQT09MIFBvb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWUqKiBwcFZvbHVtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUqIHBTaGFyZWRIYW5kbGUsIElVbmtub3duICpwYXJlbnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgICAgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWb2x1bWVJbXBsICAgICAgICAqb2JqZWN0OyAvKiogTk9URTogaW1wbCByZWYgYWxsb3dlZCBzaW5jZSB0aGlzIGlzIGEgY3JlYXRlIGZ1bmN0aW9uICoqLwoKICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBWb2x1bWUsIFdJTkVEM0RSVFlQRV9WT0xVTUUsICgoV2lkdGggKiBEM0RGbXRHZXRCcHAoVGhpcywgRm9ybWF0KSkgKiBIZWlnaHQgKiBEZXB0aCkpCgogICAgVFJBQ0UoIiglcCkgOiBXKCVkKSBIKCVkKSBEKCVkKSwgVXNhZ2UoJWxkKSwgRm10KCV1LCVzKSwgUG9vbCglcylcbiIsIFRoaXMsIFdpZHRoLCBIZWlnaHQsCiAgICAgICAgICBEZXB0aCwgVXNhZ2UsIEZvcm1hdCwgZGVidWdfZDNkZm9ybWF0KEZvcm1hdCksIGRlYnVnX2QzZHBvb2woUG9vbCkpOwoKICAgIG9iamVjdC0+Y3VycmVudERlc2MuV2lkdGggICA9IFdpZHRoOwogICAgb2JqZWN0LT5jdXJyZW50RGVzYy5IZWlnaHQgID0gSGVpZ2h0OwogICAgb2JqZWN0LT5jdXJyZW50RGVzYy5EZXB0aCAgID0gRGVwdGg7CiAgICBvYmplY3QtPmJ5dGVzUGVyUGl4ZWwgICAgICAgPSBEM0RGbXRHZXRCcHAoVGhpcywgRm9ybWF0KTsKCiAgICAvKiogTm90ZTogVm9sdW1lIHRleHR1cmVzIGNhbm5vdCBiZSBkeHRuLCBoZW5jZSBubyBuZWVkIHRvIGNoZWNrIGhlcmUgKiovCiAgICBvYmplY3QtPmxvY2thYmxlICAgICAgICAgICAgPSBUUlVFOwogICAgb2JqZWN0LT5sb2NrZWQgICAgICAgICAgICAgID0gRkFMU0U7CiAgICBtZW1zZXQoJm9iamVjdC0+bG9ja2VkQm94LCAwLCBzaXplb2YoV0lORUQzREJPWCkpOwogICAgb2JqZWN0LT5kaXJ0eSAgICAgICAgICAgICAgID0gVFJVRTsKCiAgICByZXR1cm4gSVdpbmVEM0RWb2x1bWVfQWRkRGlydHlCb3goKElXaW5lRDNEVm9sdW1lICopIG9iamVjdCwgTlVMTCk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVDdWJlVGV4dHVyZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgRWRnZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgTGV2ZWxzLCBEV09SRCBVc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBXSU5FRDNEUE9PTCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RDdWJlVGV4dHVyZSAqKnBwQ3ViZVRleHR1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUgKnBTaGFyZWRIYW5kbGUsIElVbmtub3duICpwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDQl9DUkVBVEVTVVJGQUNFRk4gRDNEQ0JfQ3JlYXRlU3VyZmFjZSkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RDdWJlVGV4dHVyZUltcGwgKm9iamVjdDsgLyoqIE5PVEU6IGltcGwgcmVmIGFsbG93ZWQgc2luY2UgdGhpcyBpcyBhIGNyZWF0ZSBmdW5jdGlvbiAqKi8KICAgIHVuc2lnbmVkIGludCAgICAgICAgICAgICBpLCBqOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgIHRtcFc7CiAgICBIUkVTVUxUICAgICAgICAgICAgICAgICAgaHI7CiAgICB1bnNpZ25lZCBpbnQgcG93MkVkZ2VMZW5ndGggID0gRWRnZUxlbmd0aDsKCiAgICAvKiBUT0RPOiBJdCBzaG91bGQgb25seSBiZSBwb3NzaWJsZSB0byBjcmVhdGUgdGV4dHVyZXMgZm9yIGZvcm1hdHMgCiAgICAgICAgICAgICB0aGF0IGFyZSByZXBvcnRlZCBhcyBzdXBwb3J0ZWQgKi8KICAgIGlmIChXSU5FRDNERk1UX1VOS05PV04gPj0gRm9ybWF0KSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFRleHR1cmUgY2Fubm90IGJlIGNyZWF0ZWQgd2l0aCBhIGZvcm1hdCBvZiBEM0RGTVRfVU5LTk9XTlxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgRDNEQ1JFQVRFUkVTT1VSQ0VPQkpFQ1RJTlNUQU5DRShvYmplY3QsIEN1YmVUZXh0dXJlLCBXSU5FRDNEUlRZUEVfQ1VCRVRFWFRVUkUsIDApOwogICAgRDNESU5JVElBTElaRUJBU0VURVhUVVJFKG9iamVjdC0+YmFzZVRleHR1cmUpOwoKICAgIFRSQUNFKCIoJXApIENyZWF0ZSBDdWJlIFRleHR1cmVcbiIsIFRoaXMpOwoKICAgIC8qKiBOb24tcG93ZXIyIHN1cHBvcnQgKiovCgogICAgLyogRmluZCB0aGUgbmVhcmVzdCBwb3cyIG1hdGNoICovCiAgICBwb3cyRWRnZUxlbmd0aCA9IDE7CiAgICB3aGlsZSAocG93MkVkZ2VMZW5ndGggPCBFZGdlTGVuZ3RoKSBwb3cyRWRnZUxlbmd0aCA8PD0gMTsKCiAgICBvYmplY3QtPmVkZ2VMZW5ndGggICAgICAgICAgID0gRWRnZUxlbmd0aDsKICAgIC8qIFRPRE86IHN1cHBvcnQgZm9yIG5hdGl2ZSBub24tcG93ZXIgMiAqLwogICAgLyogUHJlY2FsY3VsYXRlZCBzY2FsaW5nIGZvciAnZmFrZWQnIG5vbiBwb3dlciBvZiB0d28gdGV4dHVyZSBjb29yZHMgKi8KICAgIG9iamVjdC0+cG93MnNjYWxpbmdGYWN0b3IgICAgPSAoKGZsb2F0KUVkZ2VMZW5ndGgpIC8gKChmbG9hdClwb3cyRWRnZUxlbmd0aCk7CgogICAgLyogQ2FsY3VsYXRlIGxldmVscyBmb3IgbWlwIG1hcHBpbmcgKi8KICAgIGlmIChMZXZlbHMgPT0gMCkgewogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKys7CiAgICAgICAgdG1wVyA9IEVkZ2VMZW5ndGg7CiAgICAgICAgd2hpbGUgKHRtcFcgPiAxKSB7CiAgICAgICAgICAgIHRtcFcgPSBtYXgoMSwgdG1wVyA+PiAxKTsKICAgICAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMrKzsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIkNhbGN1bGF0ZWQgbGV2ZWxzID0gJWRcbiIsIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKTsKICAgIH0KCiAgICAvKiBHZW5lcmF0ZSBhbGwgdGhlIHN1cmZhY2VzICovCiAgICB0bXBXID0gRWRnZUxlbmd0aDsKICAgIGZvciAoaSA9IDA7IGkgPCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVsczsgaSsrKSB7CgogICAgICAgIC8qIENyZWF0ZSB0aGUgNiBmYWNlcyAqLwogICAgICAgIGZvciAoaiA9IDA7IGogPCA2OyBqKyspIHsKCiAgICAgICAgICAgIGhyPUQzRENCX0NyZWF0ZVN1cmZhY2UoVGhpcy0+cGFyZW50LCB0bXBXLCB0bXBXLCBGb3JtYXQsIFVzYWdlLCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgLyogTGV2ZWwgKi8sICZvYmplY3QtPnN1cmZhY2VzW2pdW2ldLHBTaGFyZWRIYW5kbGUpOwoKICAgICAgICAgICAgaWYoaHIhPSBXSU5FRDNEX09LKSB7CiAgICAgICAgICAgICAgICAvKiBjbGVhbiB1cCAqLwogICAgICAgICAgICAgICAgaW50IGs7CiAgICAgICAgICAgICAgICBpbnQgbDsKICAgICAgICAgICAgICAgIGZvciAobCA9IDA7IGwgPCBqOyBsKyspIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShvYmplY3QtPnN1cmZhY2VzW2pdW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciAoayA9IDA7IGsgPCBpOyBrKyspIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKGwgPSAwOyBsIDwgNjsgbCsrKSB7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2Uob2JqZWN0LT5zdXJmYWNlc1tsXVtqXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIEZhaWxlZCB0byBjcmVhdGUgc3VyZmFjZVxuIixvYmplY3QpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLG9iamVjdCk7CiAgICAgICAgICAgICAgICAqcHBDdWJlVGV4dHVyZSA9IE5VTEw7CiAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihvYmplY3QtPnN1cmZhY2VzW2pdW2ldLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKICAgICAgICAgICAgVFJBQ0UoIkNyZWF0ZWQgc3VyZmFjZSBsZXZlbCAlZCBAICVwLFxuIiwgaSwgb2JqZWN0LT5zdXJmYWNlc1tqXVtpXSk7CiAgICAgICAgfQogICAgICAgIHRtcFcgPSBtYXgoMSwgdG1wVyA+PiAxKTsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgQ3ViZSBUZXh0dXJlICVwXG4iLCBUaGlzLCBvYmplY3QpOwogICAgKnBwQ3ViZVRleHR1cmUgPSAoSVdpbmVEM0RDdWJlVGV4dHVyZSAqKSBvYmplY3Q7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVF1ZXJ5KElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFFVRVJZVFlQRSBUeXBlLCBJV2luZUQzRFF1ZXJ5ICoqcHBRdWVyeSwgSVVua25vd24qIHBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RRdWVyeUltcGwgKm9iamVjdDsgLypOT1RFOiBpbXBsIHJlZiBhbGxvd2VkIHNpbmNlIHRoaXMgaXMgYSBjcmVhdGUgZnVuY3Rpb24gKi8KCiAgICBpZiAoTlVMTCA9PSBwcFF1ZXJ5KSB7CiAgICAgICAgLyogSnVzdCBhIGNoZWNrIHRvIHNlZSBpZiB3ZSBzdXBwb3J0IHRoaXMgdHlwZSBvZiBxdWVyeSAqLwogICAgICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICBzd2l0Y2goVHlwZSkgewogICAgICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9PQ0NMVVNJT046CiAgICAgICAgICAgIFRSQUNFKCIoJXApIG9jY2x1c2lvbiBxdWVyeVxuIiwgVGhpcyk7CiAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9PQ0NMVVNJT05fUVVFUlkpIHx8IEdMX1NVUFBPUlQoTlZfT0NDTFVTSU9OX1FVRVJZKSkKICAgICAgICAgICAgICAgIGhyID0gV0lORUQzRF9PSzsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgV0FSTigiVW5zdXBwb3J0ZWQgaW4gbG9jYWwgT3BlbkdMIGltcGxlbWVudGF0aW9uOiBBUkJfT0NDTFVTSU9OX1FVRVJZL05WX09DQ0xVU0lPTl9RVUVSWVxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WQ0FDSEU6CiAgICAgICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1JFU09VUkNFTUFOQUdFUjoKICAgICAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVkVSVEVYU1RBVFM6CiAgICAgICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0VWRU5UOgogICAgICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9USU1FU1RBTVA6CiAgICAgICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1RJTUVTVEFNUERJU0pPSU5UOgogICAgICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9USU1FU1RBTVBGUkVROgogICAgICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9QSVBFTElORVRJTUlOR1M6CiAgICAgICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0lOVEVSRkFDRVRJTUlOR1M6CiAgICAgICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1ZFUlRFWFRJTUlOR1M6CiAgICAgICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1BJWEVMVElNSU5HUzoKICAgICAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfQkFORFdJRFRIVElNSU5HUzoKICAgICAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfQ0FDSEVVVElMSVpBVElPTjoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiKCVwKSBVbmhhbmRsZWQgcXVlcnkgdHlwZSAlZFxuIiwgVGhpcywgVHlwZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBEM0RDUkVBVEVPQkpFQ1RJTlNUQU5DRShvYmplY3QsIFF1ZXJ5KQogICAgb2JqZWN0LT50eXBlICAgICAgICAgPSBUeXBlOwogICAgLyogYWxsb2NhdGVkIHRoZSAnZXh0ZW5kZWQnIGRhdGEgYmFzZWQgb24gdGhlIHR5cGUgb2YgcXVlcnkgcmVxdWVzdGVkICovCiAgICBzd2l0Y2goVHlwZSl7CiAgICBjYXNlIEQzRFFVRVJZVFlQRV9PQ0NMVVNJT046CiAgICAgICAgaWYoR0xfU1VQUE9SVChBUkJfT0NDTFVTSU9OX1FVRVJZKSB8fCBHTF9TVVBQT1JUKE5WX09DQ0xVU0lPTl9RVUVSWSkpIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgQWxsb2NhdGluZyBkYXRhIGZvciBhbiBvY2NsdXNpb24gcXVlcnlcbiIsIFRoaXMpOwogICAgICAgICAgICBvYmplY3QtPmV4dGVuZGVkRGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoV2luZVF1ZXJ5T2NjbHVzaW9uRGF0YSkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICBjYXNlIEQzRFFVRVJZVFlQRV9WQ0FDSEU6CiAgICBjYXNlIEQzRFFVRVJZVFlQRV9SRVNPVVJDRU1BTkFHRVI6CiAgICBjYXNlIEQzRFFVRVJZVFlQRV9WRVJURVhTVEFUUzoKICAgIGNhc2UgRDNEUVVFUllUWVBFX0VWRU5UOgogICAgY2FzZSBEM0RRVUVSWVRZUEVfVElNRVNUQU1QOgogICAgY2FzZSBEM0RRVUVSWVRZUEVfVElNRVNUQU1QRElTSk9JTlQ6CiAgICBjYXNlIEQzRFFVRVJZVFlQRV9USU1FU1RBTVBGUkVROgogICAgY2FzZSBEM0RRVUVSWVRZUEVfUElQRUxJTkVUSU1JTkdTOgogICAgY2FzZSBEM0RRVUVSWVRZUEVfSU5URVJGQUNFVElNSU5HUzoKICAgIGNhc2UgRDNEUVVFUllUWVBFX1ZFUlRFWFRJTUlOR1M6CiAgICBjYXNlIEQzRFFVRVJZVFlQRV9QSVhFTFRJTUlOR1M6CiAgICBjYXNlIEQzRFFVRVJZVFlQRV9CQU5EV0lEVEhUSU1JTkdTOgogICAgY2FzZSBEM0RRVUVSWVRZUEVfQ0FDSEVVVElMSVpBVElPTjoKICAgIGRlZmF1bHQ6CiAgICAgICAgb2JqZWN0LT5leHRlbmRlZERhdGEgPSAwOwogICAgICAgIEZJWE1FKCIoJXApIFVuaGFuZGxlZCBxdWVyeSB0eXBlICVkXG4iLFRoaXMgLCBUeXBlKTsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCBRdWVyeSAlcFxuIiwgVGhpcywgb2JqZWN0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBleGFtcGxlIGF0IGh0dHA6Ly93d3cuZmFpcnllbmdpbmUuY29tL2FydGljbGVzL2R4bXVsdGl2aWV3cy5odG0gKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4oSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluKiogcHBTd2FwQ2hhaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duKiBwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRENCX0NSRUFURVJFTkRFUlRBUkdFVEZOIEQzRENCX0NyZWF0ZVJlbmRlclRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0JfQ1JFQVRFREVQVEhTVEVOQ0lMU1VSRkFDRUZOIEQzRENCX0NyZWF0ZURlcHRoU3RlbmNpbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgSERDICAgICAgICAgICAgICAgICAgICAgaERjOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICAqb2JqZWN0OyAvKiogTk9URTogaW1wbCByZWYgYWxsb3dlZCBzaW5jZSB0aGlzIGlzIGEgY3JlYXRlIGZ1bmN0aW9uICoqLwogICAgaW50ICAgICAgICAgICAgICAgICAgICAgbnVtOwogICAgWFZpc3VhbEluZm8gICAgICAgICAgICAgdGVtcGxhdGU7CiAgICBHTFhDb250ZXh0ICAgICAgICAgICAgICBvbGRDb250ZXh0OwogICAgRHJhd2FibGUgICAgICAgICAgICAgICAgb2xkRHJhd2FibGU7CiAgICBIUkVTVUxUICAgICAgICAgICAgICAgICBociA9IFdJTkVEM0RfT0s7CgogICAgVFJBQ0UoIiglcCkgOiBDcmVhdGVkIEFkaXRpb25hbCBTd2FwIENoYWluXG4iLCBUaGlzKTsKCiAgIC8qKiBGSVhNRTogVGVzdCB1bmRlciB3aW5kb3dzIHRvIGZpbmQgb3V0IHdoYXQgdGhlIGxpZmUgY3ljbGUgb2YgYSBzd2FwIGNoYWluIGlzLAogICAqIGRvZXMgYSBkZXZpY2UgaG9sZCBhIHJlZmVyZW5jZSB0byBhIHN3YXAgY2hhaW4gZ2l2aW5nIHRoZW0gYSBsaWZldGltZSBvZiB0aGUgZGV2aWNlCiAgICogb3IgZG9lcyB0aGUgc3dhcCBjaGFpbiBub3RpZnkgdGhlIGRldmljZSBvZiBpdHMgZGVzdHJ1Y3Rpb24uCiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIEQzRENSRUFURU9CSkVDVElOU1RBTkNFKG9iamVjdCwgU3dhcENoYWluKQoKICAgIC8qIEluaXRpYWxpemUgb3RoZXIgdXNlZnVsIHZhbHVlcyAqLwogICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50ID0gMTsgLyogVE9ETzo/IHN1cHBvcnQgZm9yIGdsX2F1eCBidWZmZXJzICovCgogICAgLyoqKioqKioqKioqKioqKioqKioqKgogICAgKiBMb29rdXAgdGhlIHdpbmRvdyBIYW5kbGUgYW5kIHRoZSByZWxhdGluZyBYIHdpbmRvdyBoYW5kbGUKICAgICoqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qIFNldHVwIGh3bmQgd2UgYXJlIHVzaW5nLCBwbHVzIHdoaWNoIGRpc3BsYXkgdGhpcyBlcXVhdGVzIHRvICovCiAgICBvYmplY3QtPndpbl9oYW5kbGUgPSAqKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5oRGV2aWNlV2luZG93KTsKICAgIGlmICghb2JqZWN0LT53aW5faGFuZGxlKSB7CiAgICAgICAgb2JqZWN0LT53aW5faGFuZGxlID0gVGhpcy0+Y3JlYXRlUGFybXMuaEZvY3VzV2luZG93OwogICAgfQoKICAgIG9iamVjdC0+d2luX2hhbmRsZSA9IEdldEFuY2VzdG9yKG9iamVjdC0+d2luX2hhbmRsZSwgR0FfUk9PVCk7CiAgICBpZiAoICEoIG9iamVjdC0+d2luID0gKFdpbmRvdylHZXRQcm9wQShvYmplY3QtPndpbl9oYW5kbGUsICJfX3dpbmVfeDExX3dob2xlX3dpbmRvdyIpICkgKSB7CiAgICAgICAgRVJSKCJDYW4ndCBnZXQgZHJhd2FibGUgKHdpbmRvdyksIEhXTkQ6JXAgZG9lc24ndCBoYXZlIHRoZSBwcm9wZXJ0eSBfX3dpbmVfeDExX3dob2xlX3dpbmRvd1xuIiwgb2JqZWN0LT53aW5faGFuZGxlKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICB9CiAgICBoRGMgICAgICAgICAgICAgICAgPSBHZXREQyhvYmplY3QtPndpbl9oYW5kbGUpOwogICAgb2JqZWN0LT5kaXNwbGF5ICAgID0gZ2V0X2Rpc3BsYXkoaERjKTsKICAgIFJlbGVhc2VEQyhvYmplY3QtPndpbl9oYW5kbGUsIGhEYyk7CiAgICBUUkFDRSgiVXNpbmcgYSBkaXNwbGF5IG9mICVwICVwXG4iLCBvYmplY3QtPmRpc3BsYXksIGhEYyk7CgogICAgaWYgKE5VTEwgPT0gb2JqZWN0LT5kaXNwbGF5IHx8IE5VTEwgPT0gaERjKSB7CiAgICAgICAgV0FSTigiRmFpbGVkIHRvIGdldCBhIGRpc3BsYXkgYW5kIEhEYyBmb3IgV2luZG93ICVwXG4iLCBvYmplY3QtPndpbl9oYW5kbGUpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgIH0KCiAgICBpZiAob2JqZWN0LT53aW4gPT0gMCkgewogICAgICAgIFdBUk4oIkZhaWxlZCB0byBnZXQgYSB2YWxpZCBYVmlzdWlhbCBJRCBmb3IgdGhlIHdpbmRvdyAlcFxuIiwgb2JqZWN0LT53aW5faGFuZGxlKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICB9CiAgICAvKioKICAgICogQ3JlYXRlIGFuIG9wZW5nbCBjb250ZXh0IGZvciB0aGUgZGlzcGxheSB2aXN1YWwKICAgICogIE5PVEU6IHRoZSB2aXN1YWwgaXMgY2hvc2VuIGFzIHRoZSB3aW5kb3cgaXMgY3JlYXRlZCBhbmQgdGhlIGdsY29udGV4dCBjYW5ub3QKICAgICogICAgIHVzZSBkaWZmZXJlbnQgcHJvcGVydGllcyBhZnRlciB0aGF0IHBvaW50IGluIHRpbWUuIEZJWE1FOiBIb3cgdG8gaGFuZGxlIHdoZW4gcmVxdWVzdGVkIGZvcm1hdAogICAgKiAgICAgZG9lc24ndCBtYXRjaCBhY3R1YWwgdmlzdWFsPyBDYW5ub3QgY2hvb3NlIG9uZSBoZXJlIC0gY29kZSByZW1vdmVkIGFzIGl0IE9OTFkgd29ya3MgaWYgdGhlIG9uZQogICAgKiAgICAgaXQgY2hvb3NlcyBpcyBpZGVudGljYWwgdG8gdGhlIG9uZSBhbHJlYWR5IGJlaW5nIHVzZWQhCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogRklYTUU6IEhhbmRsZSBzdGVuY2lsIGFwcHJvcHJpYXRlbHkgdmlhIEVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgLyBBdXRvRGVwdGhTdGVuY2lsRm9ybWF0ICoqLwogICAgRU5URVJfR0woKTsKCiAgICAvKiBDcmVhdGUgYSBuZXcgY29udGV4dCBmb3IgdGhpcyBzd2FwY2hhaW4gKi8KICAgIHRlbXBsYXRlLnZpc3VhbGlkID0gKFZpc3VhbElEKUdldFByb3BBKEdldERlc2t0b3BXaW5kb3coKSwgIl9fd2luZV94MTFfdmlzdWFsX2lkIik7CiAgICAvKiBUT0RPOiBjaGFuZ2UgdGhpcyB0byBmaW5kIGEgc2ltaWxhciB2aXN1YWwsIGJ1dCBvbmUgd2l0aCBhIHN0ZW5jaWwvemJ1ZmZlciBidWZmZXIgdGhhdCBtYXRjaGVzIHRoZSByZXF1ZXN0CiAgICAob3IgdGhlIGJlc3QgcG9zc2libGUgaWYgbm9uZSBpcyByZXF1ZXN0ZWQpICovCiAgICBUUkFDRSgiRm91bmQgeCB2aXN1YWwgSUQgIDogJWxkXG4iLCB0ZW1wbGF0ZS52aXN1YWxpZCk7CgogICAgb2JqZWN0LT52aXNJbmZvICAgPSBYR2V0VmlzdWFsSW5mbyhvYmplY3QtPmRpc3BsYXksIFZpc3VhbElETWFzaywgJnRlbXBsYXRlLCAmbnVtKTsKICAgIGlmIChOVUxMID09IG9iamVjdC0+dmlzSW5mbykgewogICAgICAgIEVSUigiY2Fubm90IHJlYWxseSBnZXQgWFZpc3VhbFxuIik7CiAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICB9IGVsc2UgewogICAgICAgIGludCBuLCB2YWx1ZTsKICAgICAgICAvKiBXcml0ZSBvdXQgc29tZSBkZWJ1ZyBpbmZvIGFib3V0IHRoZSB2aXN1YWwvcyAqLwogICAgICAgIFRSQUNFKCJVc2luZyB4IHZpc3VhbCBJRCAgOiAlbGRcbiIsIHRlbXBsYXRlLnZpc3VhbGlkKTsKICAgICAgICBUUkFDRSgiICAgICAgICB2aXN1YWwgaW5mbzogJXBcbiIsIG9iamVjdC0+dmlzSW5mbyk7CiAgICAgICAgVFJBQ0UoIiAgICAgICAgbnVtIGl0ZW1zICA6ICVkXG4iLCBudW0pOwogICAgICAgIGZvciAobiA9IDA7biA8IG51bTsgbisrKSB7CiAgICAgICAgICAgIFRSQUNFKCI9PT09PWl0ZW09PT09PTogJWRcbiIsIG4gKyAxKTsKICAgICAgICAgICAgVFJBQ0UoIiAgIHZpc3VhbGlkICAgICAgOiAlbGRcbiIsIG9iamVjdC0+dmlzSW5mb1tuXS52aXN1YWxpZCk7CiAgICAgICAgICAgIFRSQUNFKCIgICBzY3JlZW4gICAgICAgIDogJWRcbiIsICBvYmplY3QtPnZpc0luZm9bbl0uc2NyZWVuKTsKICAgICAgICAgICAgVFJBQ0UoIiAgIGRlcHRoICAgICAgICAgOiAldVxuIiwgIG9iamVjdC0+dmlzSW5mb1tuXS5kZXB0aCk7CiAgICAgICAgICAgIFRSQUNFKCIgICBjbGFzcyAgICAgICAgIDogJWRcbiIsICBvYmplY3QtPnZpc0luZm9bbl0uY2xhc3MpOwogICAgICAgICAgICBUUkFDRSgiICAgcmVkX21hc2sgICAgICA6ICVsZFxuIiwgb2JqZWN0LT52aXNJbmZvW25dLnJlZF9tYXNrKTsKICAgICAgICAgICAgVFJBQ0UoIiAgIGdyZWVuX21hc2sgICAgOiAlbGRcbiIsIG9iamVjdC0+dmlzSW5mb1tuXS5ncmVlbl9tYXNrKTsKICAgICAgICAgICAgVFJBQ0UoIiAgIGJsdWVfbWFzayAgICAgOiAlbGRcbiIsIG9iamVjdC0+dmlzSW5mb1tuXS5ibHVlX21hc2spOwogICAgICAgICAgICBUUkFDRSgiICAgY29sb3JtYXBfc2l6ZSA6ICVkXG4iLCAgb2JqZWN0LT52aXNJbmZvW25dLmNvbG9ybWFwX3NpemUpOwogICAgICAgICAgICBUUkFDRSgiICAgYml0c19wZXJfcmdiICA6ICVkXG4iLCAgb2JqZWN0LT52aXNJbmZvW25dLmJpdHNfcGVyX3JnYik7CiAgICAgICAgICAgIC8qIGxvZyBzb21lIGV4dHJhIGdseCBpbmZvICovCiAgICAgICAgICAgIGdsWEdldENvbmZpZyhvYmplY3QtPmRpc3BsYXksIG9iamVjdC0+dmlzSW5mbywgR0xYX0FVWF9CVUZGRVJTLCAmdmFsdWUpOwogICAgICAgICAgICBUUkFDRSgiICAgZ2xfYXV4X2J1ZmZlcnMgIDogJWRcbiIsICB2YWx1ZSk7CiAgICAgICAgICAgIGdsWEdldENvbmZpZyhvYmplY3QtPmRpc3BsYXksIG9iamVjdC0+dmlzSW5mbywgR0xYX0JVRkZFUl9TSVpFICwmdmFsdWUpOwogICAgICAgICAgICBUUkFDRSgiICAgZ2xfYnVmZmVyX3NpemUgIDogJWRcbiIsICB2YWx1ZSk7CiAgICAgICAgICAgIGdsWEdldENvbmZpZyhvYmplY3QtPmRpc3BsYXksIG9iamVjdC0+dmlzSW5mbywgR0xYX1JFRF9TSVpFLCAmdmFsdWUpOwogICAgICAgICAgICBUUkFDRSgiICAgZ2xfcmVkX3NpemUgIDogJWRcbiIsICB2YWx1ZSk7CiAgICAgICAgICAgIGdsWEdldENvbmZpZyhvYmplY3QtPmRpc3BsYXksIG9iamVjdC0+dmlzSW5mbywgR0xYX0dSRUVOX1NJWkUsICZ2YWx1ZSk7CiAgICAgICAgICAgIFRSQUNFKCIgICBnbF9ncmVlbl9zaXplICA6ICVkXG4iLCAgdmFsdWUpOwogICAgICAgICAgICBnbFhHZXRDb25maWcob2JqZWN0LT5kaXNwbGF5LCBvYmplY3QtPnZpc0luZm8sIEdMWF9CTFVFX1NJWkUsICZ2YWx1ZSk7CiAgICAgICAgICAgIFRSQUNFKCIgICBnbF9ibHVlX3NpemUgIDogJWRcbiIsICB2YWx1ZSk7CiAgICAgICAgICAgIGdsWEdldENvbmZpZyhvYmplY3QtPmRpc3BsYXksIG9iamVjdC0+dmlzSW5mbywgR0xYX0FMUEhBX1NJWkUsICZ2YWx1ZSk7CiAgICAgICAgICAgIFRSQUNFKCIgICBnbF9hbHBoYV9zaXplICA6ICVkXG4iLCAgdmFsdWUpOwogICAgICAgICAgICBnbFhHZXRDb25maWcob2JqZWN0LT5kaXNwbGF5LCBvYmplY3QtPnZpc0luZm8sIEdMWF9ERVBUSF9TSVpFICwmdmFsdWUpOwogICAgICAgICAgICBUUkFDRSgiICAgZ2xfZGVwdGhfc2l6ZSAgOiAlZFxuIiwgIHZhbHVlKTsKICAgICAgICAgICAgZ2xYR2V0Q29uZmlnKG9iamVjdC0+ZGlzcGxheSwgb2JqZWN0LT52aXNJbmZvLCBHTFhfU1RFTkNJTF9TSVpFLCAmdmFsdWUpOwogICAgICAgICAgICBUUkFDRSgiICAgZ2xfc3RlbmNpbF9zaXplIDogJWRcbiIsICB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIC8qIE5vdyBjaG9vc2UgYSBzaW1pbGEgdmlzdWFsIElEKi8KICAgIH0KI2lmZGVmIFVTRV9DT05URVhUX01BTkFHRVIKCiAgICAvKiogVE9ETzogdXNlIGEgY29udGV4dCBtYW1hZ2VyICoqLwojZW5kaWYKCiAgICB7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW4gKmltcGxTd2FwQ2hhaW47CiAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gSVdpbmVEM0REZXZpY2VfR2V0U3dhcENoYWluKGlmYWNlLCAwLCAmaW1wbFN3YXBDaGFpbikpIHsKICAgICAgICAgICAgLyogVGhlIGZpcnN0IHRpbWUgYXJvdW5kIHdlIGNyZWF0ZSB0aGUgY29udGV4dCB0aGF0IGlzIHNoYXJlZCB3aXRoIGFsbCBvdGhlciBzd2FwY2hhaW5zIGFuZCByZW5kZXIgdGFyZ2V0cyAqLwogICAgICAgICAgICBvYmplY3QtPmdsQ3R4ID0gZ2xYQ3JlYXRlQ29udGV4dChvYmplY3QtPmRpc3BsYXksIG9iamVjdC0+dmlzSW5mbywgTlVMTCwgR0xfVFJVRSk7CiAgICAgICAgICAgIFRSQUNFKCJDcmVhdGluZyBpbXBsaWNpdCBjb250ZXh0IGZvciB2aXMgJXAsIGh3bmQgJXBcbiIsIG9iamVjdC0+ZGlzcGxheSwgb2JqZWN0LT52aXNJbmZvKTsKICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgVFJBQ0UoIkNyZWF0aW5nIGNvbnRleHQgZm9yIHZpcyAlcCwgaHduZCAlcFxuIiwgb2JqZWN0LT5kaXNwbGF5LCBvYmplY3QtPnZpc0luZm8pOwogICAgICAgICAgICAvKiBUT0RPOiBkb24ndCB1c2UgSW1wbCBzdHJ1Y3R1cmVzIG91dHNpZGUgb2YgY3JlYXRlIGZ1bmN0aW9ucyEgKGEgY29udGV4dCBtYW5hZ2VyIHdpbGwgcmVwbGFjZSB0aGUgLT5nbEN0eCkgKi8KICAgICAgICAgICAgLyogYW5kIGNyZWF0ZSBhIG5ldyBjb250ZXh0IHdpdGggdGhlIGltcGxpY2l0IHN3YXBjaGFpbnMgY29udGV4dCBhcyB0aGUgc2hhcmVkIGNvbnRleHQgKi8KICAgICAgICAgICAgb2JqZWN0LT5nbEN0eCA9IGdsWENyZWF0ZUNvbnRleHQob2JqZWN0LT5kaXNwbGF5LCBvYmplY3QtPnZpc0luZm8sICgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopaW1wbFN3YXBDaGFpbiktPmdsQ3R4LCBHTF9UUlVFKTsKICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShpbXBsU3dhcENoYWluKTsKICAgICAgICB9CiAgICB9CgogICAgLyogQ2xlYW51cCAqLwogICAgWEZyZWUob2JqZWN0LT52aXNJbmZvKTsKICAgIG9iamVjdC0+dmlzSW5mbyA9IE5VTEw7CgogICAgaWYgKE5VTEwgPT0gb2JqZWN0LT5nbEN0eCkgewogICAgICAgIEVSUigiY2Fubm90IGNyZWF0ZSBnbHhDb250ZXh0XG4iKTsKICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgIH0KCiAgICBMRUFWRV9HTCgpOwogICAgaWYgKG9iamVjdC0+Z2xDdHggPT0gTlVMTCkgewogICAgICAgIEVSUigiRXJyb3IgaW4gY29udGV4dCBjcmVhdGlvbiAhXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIkNvbnRleHQgY3JlYXRlZCAoSFdORD0lcCwgZ2xDb250ZXh0PSVwLCBXaW5kb3c9JWxkLCBWaXNJbmZvPSVwKVxuIiwKICAgICAgICAgICAgICAgIG9iamVjdC0+d2luX2hhbmRsZSwgb2JqZWN0LT5nbEN0eCwgb2JqZWN0LT53aW4sIG9iamVjdC0+dmlzSW5mbyk7CiAgICB9CgogICAvKioqKioqKioqKioqKioqKioqKioqCiAgICogV2luZG93ZWQgLyBGdWxsc2NyZWVuCiAgICoqKioqKioqKioqKioqKioqKiovCgogICAvKioKICAgKiBUT0RPOiBNU0ROIHNheXMgdGhhdCB3ZSBhcmUgb25seSBhbGxvd2VkIG9uZSBmdWxsc2NyZWVuIHN3YXBjaGFpbiBwZXIgZGV2aWNlLAogICAqIHNvIHdlIHNob3VsZCByZWFsbHkgY2hlY2sgdG8gc2VlIGlmIHRoZXJlIGlzIGEgZnVsbHNjcmVlbiBzd2FwY2hhaW4gYWxyZWFkeQogICAqIEkgdGhpbmsgV2luZG93cyBhbmQgWCBoYXZlIGRpZmZlcmVudCBpZGVhcyBhYm91dCBmdWxsc2NyZWVuLCBkb2VzIGEgc2luZ2xlIGhlYWQgY291bnQgYXMgZnVsbCBzY3JlZW4/CiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgIGlmICghKihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQpKSB7CgogICAgICAgIERFVk1PREVXIGRldm1vZGU7CiAgICAgICAgSERDICAgICAgaGRjOwogICAgICAgIGludCAgICAgIGJwcCA9IDA7CgogICAgICAgIC8qIEdldCBpbmZvIG9uIHRoZSBjdXJyZW50IGRpc3BsYXkgc2V0dXAgKi8KICAgICAgICBoZGMgPSBDcmVhdGVEQ0EoIkRJU1BMQVkiLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgICBicHAgPSBHZXREZXZpY2VDYXBzKGhkYywgQklUU1BJWEVMKTsKICAgICAgICBEZWxldGVEQyhoZGMpOwoKICAgICAgICAvKiBDaGFuZ2UgdGhlIGRpc3BsYXkgc2V0dGluZ3MgKi8KICAgICAgICBtZW1zZXQoJmRldm1vZGUsIDAsIHNpemVvZihERVZNT0RFVykpOwogICAgICAgIGRldm1vZGUuZG1GaWVsZHMgICAgID0gRE1fQklUU1BFUlBFTCB8IERNX1BFTFNXSURUSCB8IERNX1BFTFNIRUlHSFQ7CiAgICAgICAgZGV2bW9kZS5kbUJpdHNQZXJQZWwgPSAoYnBwID49IDI0KSA/IDMyIDogYnBwOyAvKiBTdHVwaWQgWFZpZE1vZGUgY2Fubm90IGNoYW5nZSBicHAgKi8KICAgICAgICBkZXZtb2RlLmRtUGVsc1dpZHRoICA9ICoocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCk7CiAgICAgICAgZGV2bW9kZS5kbVBlbHNIZWlnaHQgPSAqKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0KTsKICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgIkdhbWVycyBDRyIsIC0xLCBkZXZtb2RlLmRtRGV2aWNlTmFtZSwgQ0NIREVWSUNFTkFNRSk7CiAgICAgICAgQ2hhbmdlRGlzcGxheVNldHRpbmdzRXhXKGRldm1vZGUuZG1EZXZpY2VOYW1lLCAmZGV2bW9kZSwgb2JqZWN0LT53aW5faGFuZGxlLCBDRFNfRlVMTFNDUkVFTiwgTlVMTCk7CgogICAgICAgIC8qIE1ha2UgcG9wdXAgd2luZG93ICovCiAgICAgICAgU2V0V2luZG93TG9uZ0Eob2JqZWN0LT53aW5faGFuZGxlLCBHV0xfU1RZTEUsIFdTX1BPUFVQKTsKICAgICAgICBTZXRXaW5kb3dQb3Mob2JqZWN0LT53aW5faGFuZGxlLCBIV05EX1RPUCwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgKihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoKSwKICAgICAgICAgICAgICAgICAgICAgKihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCksIFNXUF9TSE9XV0lORE9XIHwgU1dQX0ZSQU1FQ0hBTkdFRCk7CgoKICAgIH0KCgogICAgLyoqIE1TRE46IElmIFdpbmRvd2VkIGlzIFRSVUUgYW5kIGVpdGhlciBvZiB0aGUgQmFja0J1ZmZlcldpZHRoL0hlaWdodCB2YWx1ZXMgaXMgemVybywKICAgICAqICB0aGVuIHRoZSBjb3JyZXNwb25kaW5nIGRpbWVuc2lvbiBvZiB0aGUgY2xpZW50IGFyZWEgb2YgdGhlIGhEZXZpY2VXaW5kb3cKICAgICAqICAob3IgdGhlIGZvY3VzIHdpbmRvdywgaWYgaERldmljZVdpbmRvdyBpcyBOVUxMKSBpcyB0YWtlbi4KICAgICAgKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBpZiAoKihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQpICYmCiAgICAgICAgKCgqKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGgpICA9PSAwKSB8fAogICAgICAgICAoKihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCkgPT0gMCkpKSB7CgogICAgICAgIFJFQ1QgUmVjdDsKICAgICAgICBHZXRDbGllbnRSZWN0KG9iamVjdC0+d2luX2hhbmRsZSwgJlJlY3QpOwoKICAgICAgICBpZiAoKihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoKSA9PSAwKSB7CiAgICAgICAgICAgKihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoKSA9IFJlY3QucmlnaHQ7CiAgICAgICAgICAgVFJBQ0UoIlVwZGF0aW5nIHdpZHRoIHRvICVkXG4iLCAqKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCoocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQpID09IDApIHsKICAgICAgICAgICAqKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0KSA9IFJlY3QuYm90dG9tOwogICAgICAgICAgIFRSQUNFKCJVcGRhdGluZyBoZWlnaHQgdG8gJWRcbiIsICoocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQpKTsKICAgICAgICB9CiAgICB9CgogICAvKioqKioqKioqKioqKioqKioqKioqCiAgICogZmluaXNoIG9mZiBwYXJhbWV0ZXIgaW5pdGlhbGl6YXRpb24KICAgKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiBQdXQgdGhlIGNvcnJlY3QgZmlndXJlcyBpbiB0aGUgcHJlc2VudGF0aW9uIHBhcmFtZXRlcnMgKi8KICAgIFRSQUNFKCJDb3BweWluZyBhY2Nyb3NzIHByZXNlbnRhaW9uIHBhcmFuZXRlcnNcbiIpOwogICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlcldpZHRoICAgICAgICAgICAgICAgID0gKihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoKTsKICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJIZWlnaHQgICAgICAgICAgICAgICA9ICoocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQpOwogICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckZvcm1hdCAgICAgICAgICAgICAgID0gKihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckZvcm1hdCk7CiAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQgICAgICAgICAgICAgICAgPSAqKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyQ291bnQpOwogICAgb2JqZWN0LT5wcmVzZW50UGFybXMuTXVsdGlTYW1wbGVUeXBlICAgICAgICAgICAgICAgID0gKihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+TXVsdGlTYW1wbGVUeXBlKTsKICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLk11bHRpU2FtcGxlUXVhbGl0eSAgICAgICAgICAgICA9IE5VTEwgPT0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPk11bHRpU2FtcGxlUXVhbGl0eSA/IDAgOiAqKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5NdWx0aVNhbXBsZVF1YWxpdHkpOwogICAgb2JqZWN0LT5wcmVzZW50UGFybXMuU3dhcEVmZmVjdCAgICAgICAgICAgICAgICAgICAgID0gKihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+U3dhcEVmZmVjdCk7CiAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5oRGV2aWNlV2luZG93ICAgICAgICAgICAgICAgICAgPSAqKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5oRGV2aWNlV2luZG93KTsKICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLldpbmRvd2VkICAgICAgICAgICAgICAgICAgICAgICA9ICoocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKTsKICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgICAgICAgICA9ICoocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwpOwogICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQXV0b0RlcHRoU3RlbmNpbEZvcm1hdCAgICAgICAgID0gKihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QXV0b0RlcHRoU3RlbmNpbEZvcm1hdCk7CiAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5GbGFncyAgICAgICAgICAgICAgICAgICAgICAgICAgPSAqKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5GbGFncyk7CiAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5GdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5IeiAgICAgPSAqKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5GdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5Ieik7CiAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5QcmVzZW50YXRpb25JbnRlcnZhbCAgICAgICAgICAgPSAqKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5QcmVzZW50YXRpb25JbnRlcnZhbCk7CgoKICAgLyoqKioqKioqKioqKioqKioqKioqKgogICAqIENyZWF0ZSB0aGUgYmFjaywgZnJvbnQgYW5kIHN0ZW5jaWwgYnVmZmVycwogICAqKioqKioqKioqKioqKioqKioqLwogICAgVFJBQ0UoImNhbGxpbmcgcmVuZGVydGFyZ2V0IENCXG4iKTsKICAgIGhyID0gRDNEQ0JfQ3JlYXRlUmVuZGVyVGFyZ2V0KChJVW5rbm93biAqKSBUaGlzLT5wYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlcldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5NdWx0aVNhbXBsZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuTXVsdGlTYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgLyogTG9ja2FibGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm9iamVjdC0+ZnJvbnRCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCAvKiBwU2hhcmVkIChhbHdheXMgbnVsbCkqLyk7CiAgICBpZiAob2JqZWN0LT5mcm9udEJ1ZmZlciAhPSBOVUxMKQogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIob2JqZWN0LT5mcm9udEJ1ZmZlciwgKElXaW5lRDNEQmFzZSAqKW9iamVjdCk7CiAgICBUUkFDRSgiY2FsbGluZyByZW5kZXJ0YXJnZXQgQ0JcbiIpOwogICAgaHIgPSBEM0RDQl9DcmVhdGVSZW5kZXJUYXJnZXQoKElVbmtub3duICopIFRoaXMtPnBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLk11bHRpU2FtcGxlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5NdWx0aVNhbXBsZVF1YWxpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAvKiBMb2NrYWJsZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmb2JqZWN0LT5iYWNrQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwgLyogcFNoYXJlZCAoYWx3YXlzIG51bGwpKi8pOwogICAgaWYgKG9iamVjdC0+YmFja0J1ZmZlciAhPSBOVUxMKQogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIob2JqZWN0LT5iYWNrQnVmZmVyLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKCiAgICAvKiBVbmRlciBkaXJlY3RYIHN3YXBjaGFpbnMgc2hhcmUgdGhlIGRlcHRoIHN0ZW5jaWwsIHNvIG9ubHkgY3JlYXRlIG9uZSBkZXB0aC1zdGVuY2lsICovCiAgICBpZiAocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwpIHsKICAgICAgICBUUkFDRSgiQ3JlYXRpbmcgZGVwdGggc3RlbmNpbCBidWZmZXJcbiIpOwogICAgICAgIGlmIChUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXIgPT0gTlVMTCApIHsKICAgICAgICAgICAgaHIgPSBEM0RDQl9DcmVhdGVEZXB0aFN0ZW5jaWwoKElVbmtub3duICopIFRoaXMtPnBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlcldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVySGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5BdXRvRGVwdGhTdGVuY2lsRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5NdWx0aVNhbXBsZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLk11bHRpU2FtcGxlUXVhbGl0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkFMU0UgLyogRklYTUU6IERpc2NhcmQgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwgLyogcFNoYXJlZCAoYWx3YXlzIG51bGwpKi8gICk7CiAgICAgICAgICAgIGlmIChUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXIgIT0gTlVMTCkKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIoVGhpcy0+ZGVwdGhTdGVuY2lsQnVmZmVyLCAwKTsKICAgICAgICB9CgogICAgICAgIC8qKiBUT0RPOiBBIGNoZWNrIG9uIHdpZHRoLCBoZWlnaHQgYW5kIG11bHRpc2FtcGxlIHR5cGVzCiAgICAgICAgKihzaW5jZSB0aGUgemJ1ZmZlciBtdXN0IGJlIGF0IGxlYXN0IGFzIGxhcmdlIGFzIHRoZSByZW5kZXIgdGFyZ2V0IGFuZCBoYXZlIHRoZSBzYW1lIG11bHRpc2FtcGxlIHBhcmFtZXRlcnMpCiAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICAgICAgb2JqZWN0LT53YW50c0RlcHRoU3RlbmNpbEJ1ZmZlciA9IFRSVUU7CiAgICB9IGVsc2UgewogICAgICAgIG9iamVjdC0+d2FudHNEZXB0aFN0ZW5jaWxCdWZmZXIgPSBGQUxTRTsKICAgIH0KCiAgICBUUkFDRSgiRnJvbnRCdWYgQCAlcCwgQmFja0J1ZiBAICVwLCBEZXB0aFN0ZW5jaWwgJWRcbiIsb2JqZWN0LT5mcm9udEJ1ZmZlciwgb2JqZWN0LT5iYWNrQnVmZmVyLCBvYmplY3QtPndhbnRzRGVwdGhTdGVuY2lsQnVmZmVyKTsKCgogICAvKioqKioqKioqKioqKioqKioqKioqCiAgICogaW5pdCB0aGUgZGVmYXVsdCByZW5kZXJUYXJnZXQgbWFuYWdlbWVudAogICAqKioqKioqKioqKioqKioqKioqLwogICAgb2JqZWN0LT5kcmF3YWJsZSAgICAgPSBvYmplY3QtPndpbjsKICAgIG9iamVjdC0+cmVuZGVyX2N0eCAgID0gb2JqZWN0LT5nbEN0eDsKCiAgICBpZiAoaHIgPT0gV0lORUQzRF9PSykgewogICAgICAgIC8qKioqKioqKioqKioqKioqKioqKioKICAgICAgICAgKiBTZXR1cCBzb21lIGRlZmF1bHRzIGFuZCBjbGVhciBkb3duIHRoZSBidWZmZXJzCiAgICAgICAgICoqKioqKioqKioqKioqKioqKiovCiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICAvKiogc2F2ZSBjdXJyZW50IGNvbnRleHQgYW5kIGRyYXdhYmxlICoqLwogICAgICAgIG9sZENvbnRleHQgID0gZ2xYR2V0Q3VycmVudENvbnRleHQoKTsKICAgICAgICBvbGREcmF3YWJsZSA9IGdsWEdldEN1cnJlbnREcmF3YWJsZSgpOwoKICAgICAgICBUUkFDRSgiQWN0aXZhdGluZyBjb250ZXh0IChkaXNwbGF5ICVwIGNvbnRleHQgJXAgZHJhd2FibGUgJWxkKSFcbiIsIG9iamVjdC0+ZGlzcGxheSwgb2JqZWN0LT5nbEN0eCwgb2JqZWN0LT53aW4pOwogICAgICAgIGlmIChnbFhNYWtlQ3VycmVudChvYmplY3QtPmRpc3BsYXksIG9iamVjdC0+d2luLCBvYmplY3QtPmdsQ3R4KSA9PSBGYWxzZSkgewogICAgICAgICAgICBFUlIoIkVycm9yIGluIHNldHRpbmcgY3VycmVudCBjb250ZXh0IChkaXNwbGF5ICVwIGNvbnRleHQgJXAgZHJhd2FibGUgJWxkKSFcbiIsIG9iamVjdC0+ZGlzcGxheSwgb2JqZWN0LT5nbEN0eCwgb2JqZWN0LT53aW4pOwogICAgICAgIH0KICAgICAgICBjaGVja0dMY2FsbCgiZ2xYTWFrZUN1cnJlbnQiKTsKCiAgICAgICAgVFJBQ0UoIlNldHRpbmcgdXAgdGhlIHNjcmVlblxuIik7CiAgICAgICAgLyogQ2xlYXIgdGhlIHNjcmVlbiAqLwogICAgICAgIGdsQ2xlYXJDb2xvcigxLjAsIDAuMCwgMC4wLCAwLjApOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbENsZWFyQ29sb3IiKTsKICAgICAgICBnbENsZWFySW5kZXgoMCk7CiAgICAgICAgZ2xDbGVhckRlcHRoKDEpOwogICAgICAgIGdsQ2xlYXJTdGVuY2lsKDB4ZmZmZik7CgogICAgICAgIGNoZWNrR0xjYWxsKCJnbENsZWFyIik7CgogICAgICAgIGdsQ29sb3IzZigxLjAsIDEuMCwgMS4wKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xDb2xvcjNmIik7CgogICAgICAgIGdsRW5hYmxlKEdMX0xJR0hUSU5HKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUiKTsKCiAgICAgICAgZ2xMaWdodE1vZGVsaShHTF9MSUdIVF9NT0RFTF9MT0NBTF9WSUVXRVIsIEdMX1RSVUUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbExpZ2h0TW9kZWxpKEdMX0xJR0hUX01PREVMX0xPQ0FMX1ZJRVdFUiwgR0xfVFJVRSk7Iik7CgogICAgICAgIGdsVGV4RW52ZihHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfTU9ERSwgR0xfQ09NQklORV9FWFQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEVudmYoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX0NPTUJJTkVfRVhUKTsiKTsKCiAgICAgICAgZ2xMaWdodE1vZGVsaShHTF9MSUdIVF9NT0RFTF9DT0xPUl9DT05UUk9MLCBHTF9TRVBBUkFURV9TUEVDVUxBUl9DT0xPUik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsTGlnaHRNb2RlbGkoR0xfTElHSFRfTU9ERUxfQ09MT1JfQ09OVFJPTCwgR0xfU0VQQVJBVEVfU1BFQ1VMQVJfQ09MT1IpOyIpOwoKICAgICAgICAvKiBzd2l0Y2ggYmFjayB0byB0aGUgb3JpZ2luYWwgY29udGV4dCAoaWYgdGhlcmUgd2FzIG9uZSkqLwogICAgICAgIGlmIChUaGlzLT5zd2FwY2hhaW5zICE9IE5VTEwpIHsKICAgICAgICAgICAgLyoqIFRPRE86IHJlc3RvcmUgdGhlIGNvbnRleHQgYW5kIGRyYXdhYmxlICoqLwogICAgICAgICAgICBnbFhNYWtlQ3VycmVudChvYmplY3QtPmRpc3BsYXksIG9sZERyYXdhYmxlLCBvbGRDb250ZXh0KTsKICAgICAgICB9CgogICAgICAgIExFQVZFX0dMKCk7CgogICAgICAgIHsgLyogRmluYWxseSBhZGQgdGhlIHN3YXBjaGFpbiB0byB0aGUgZW5kIG9mIHRoZSBkZXZpY2VzJyBzd2FwY2hhaW4gbGlzdCAqLwogICAgICAgICAgICBTd2FwQ2hhaW5MaXN0ICoqbmV4dFN3YXBjaGFpbjsKICAgICAgICAgICAgbmV4dFN3YXBjaGFpbiA9ICZUaGlzLT5zd2FwY2hhaW5zOwogICAgICAgICAgICB3aGlsZSAoKm5leHRTd2FwY2hhaW4gIT0gTlVMTCkgewogICAgICAgICAgICAgICAgbmV4dFN3YXBjaGFpbiA9ICYoKCpuZXh0U3dhcGNoYWluKS0+bmV4dCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKCpuZXh0U3dhcGNoYWluKSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKlRoaXMtPnN3YXBjaGFpbnMpKTsKICAgICAgICAgICAgKCpuZXh0U3dhcGNoYWluKS0+c3dhcGNoYWluID0gKElXaW5lRDNEU3dhcENoYWluICopb2JqZWN0OwogICAgICAgIH0KICAgICAgICBUUkFDRSgiU2V0IHN3YXBjaGFpbiB0byAlcFxuIiwgb2JqZWN0KTsKICAgIH0gZWxzZSB7IC8qIHNvbWV0aGluZyB3ZW50IHdyb25nIHNvIGNsZWFuIHVwICovCiAgICAgICAgSVVua25vd24qIGJ1ZmZlclBhcmVudDsKICAgICAgICBpZiAob2JqZWN0LT5mcm9udEJ1ZmZlcikgewoKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldFBhcmVudChvYmplY3QtPmZyb250QnVmZmVyLCAmYnVmZmVyUGFyZW50KTsKICAgICAgICAgICAgSVVua25vd25fUmVsZWFzZShidWZmZXJQYXJlbnQpOyAvKiBvbmNlIGZvciB0aGUgZ2V0IHBhcmVudCAqLwogICAgICAgICAgICBpZiAoSVVua25vd25fUmVsZWFzZShidWZmZXJQYXJlbnQpID4gMCkgewogICAgICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgZnJvbnQgYnVmZmVyXG4iLFRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChvYmplY3QtPmJhY2tCdWZmZXIpIHsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldFBhcmVudChvYmplY3QtPmJhY2tCdWZmZXIsICZidWZmZXJQYXJlbnQpOwogICAgICAgICAgICBJVW5rbm93bl9SZWxlYXNlKGJ1ZmZlclBhcmVudCk7IC8qIG9uY2UgZm9yIHRoZSBnZXQgcGFyZW50ICovCiAgICAgICAgICAgIGlmIChJVW5rbm93bl9SZWxlYXNlKGJ1ZmZlclBhcmVudCkgPiAwKSB7CiAgICAgICAgICAgICAgICBGSVhNRSgiKCVwKSBTb21ldGhpbmcncyBzdGlsbCBob2xkaW5nIHRoZSBiYWNrIGJ1ZmZlclxuIixUaGlzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKiBOT1RFOiBkb24ndCBjbGVhbiB1cCB0aGUgZGVwdGhzdGVuY2lsIGJ1ZmZlciBiZWNhdXNlIGl0IGJlbG9uZ3MgdG8gdGhlIGRldmljZSAqLwogICAgICAgIC8qIENsZWFuIHVwIHRoZSBjb250ZXh0ICovCiAgICAgICAgLyogY2hlY2sgdGhhdCB3ZSBhcmUgdGhlIGN1cnJlbnQgY29udGV4dCBmaXJzdCAod2Ugc2hvdWxkbid0IGJlIHRob3VnaCEpICovCiAgICAgICAgaWYgKG9iamVjdC0+Z2xDdHggIT0gMCkgewogICAgICAgICAgICBpZihnbFhHZXRDdXJyZW50Q29udGV4dCgpID09IG9iamVjdC0+Z2xDdHgpIHsKICAgICAgICAgICAgICAgIGdsWE1ha2VDdXJyZW50KG9iamVjdC0+ZGlzcGxheSwgTm9uZSwgTlVMTCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZ2xYRGVzdHJveUNvbnRleHQob2JqZWN0LT5kaXNwbGF5LCBvYmplY3QtPmdsQ3R4KTsKICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKCiAgICB9CgogICAgcmV0dXJuIGhyOwp9CgovKiogTk9URTogVGhlc2UgYXJlIGFoZWFkIG9mIHRoZSBvdGhlciBnZXR0ZXJzIGFuZCBzZXR0ZXJzIHRvIHNhdmUgdXNpbmcgYSBmb3J3YXJkIGRlY2xhcmF0aW9uICoqLwpVSU5UICAgICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXROdW1iZXJPZlN3YXBDaGFpbnMoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICB1bnNpZ25lZCBpbnQgbnVtYmVyT2ZTd2FwQ2hhaW5zID0gMDsKICAgIFN3YXBDaGFpbkxpc3QgICAgICAgICAgKnN3YXBjaGFpbjsKCiAgICBzd2FwY2hhaW4gPSBUaGlzLT5zd2FwY2hhaW5zOwogICAgLyogaXR0ZXJhdGUgdGhyb3VnaCB0aGUgbGlzdCB0byBnZXQgYSBjb3VudCAqLwogICAgd2hpbGUgKHN3YXBjaGFpbiAhPSBOVUxMKSB7CiAgICAgICAgc3dhcGNoYWluID0gc3dhcGNoYWluLT5uZXh0OwogICAgICAgIG51bWJlck9mU3dhcENoYWlucysrOwogICAgfQoKICAgIFRSQUNFKCIoJXApIHJldHVybmluZyAlZFxuIiwgVGhpcywgbnVtYmVyT2ZTd2FwQ2hhaW5zKTsKICAgIHJldHVybiBudW1iZXJPZlN3YXBDaGFpbnM7Cn0KCkhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgSVdpbmVEM0RTd2FwQ2hhaW4gKipwU3dhcENoYWluKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBTd2FwQ2hhaW5MaXN0ICpzd2FwY2hhaW47CiAgICBpbnQgaSA9IGlTd2FwQ2hhaW47CiAgICBIUkVTVUxUIGhyID0gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIHN3YXBjaGFpbiA9IFRoaXMtPnN3YXBjaGFpbnM7CiAgICBUUkFDRSgiKCVwKSA6IHN3YXBjaGFpbiAlZFxuIiwgVGhpcywgaVN3YXBDaGFpbik7CgoKICAgIFRSQUNFKCIoJXApIEZpbmRpbmcgc3dhcGNoYWluICVkXG4iLCBUaGlzLCBpU3dhcENoYWluKTsKICAgIHdoaWxlIChpID4gMCAmJiBzd2FwY2hhaW4gIT0gTlVMTCkgewogICAgICAgIHN3YXBjaGFpbiA9IHN3YXBjaGFpbi0+bmV4dDsKICAgICAgICAtLWk7CiAgICB9CgogICAgaWYgKGkgPiAwKSB7CiAgICAgICAgRklYTUUoIiglcCkgVW5hYmxlIHRvIGZpbmQgc3dhcGNoYWluICVkXG4iLCBUaGlzLCBpU3dhcENoYWluKTsKICAgICAgICAqcFN3YXBDaGFpbiA9IE5VTEw7CiAgICB9IGVsc2UgaWYgKHN3YXBjaGFpbiAhPSBOVUxMKSB7CiAgICAgICAgLyoqIFRPRE86IG1vdmUgb2ZmIHRvIGEgbGlua2VzTGlzdCBpbXBsZW1lbnRhdGlvbiAqKi8KICAgICAgICAqcFN3YXBDaGFpbiA9IHN3YXBjaGFpbi0+c3dhcGNoYWluOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX0FkZFJlZigqcFN3YXBDaGFpbik7CiAgICAgICAgaHIgPSBXSU5FRDNEX09LOwogICAgfQoKICAgIFRSQUNFKCIoJXApIHJldHVybmluZyAlcFxuIiwgVGhpcywgKnBTd2FwQ2hhaW4pOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioKICogVmVydGV4IERlY2xhcmF0aW9uCiAqKioqKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleERlY2xhcmF0aW9uKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgQ09OU1QgVk9JRCogcERlY2xhcmF0aW9uLCBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uKiogcHBWZXJ0ZXhEZWNsYXJhdGlvbiwgSVVua25vd24gKnBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICAgICAgKlRoaXMgICA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb25JbXBsICpvYmplY3QgPSBOVUxMOwogICAgSFJFU1VMVCBociA9IFdJTkVEM0RfT0s7CiAgICBUUkFDRSgiKCVwKSA6IGRpcmVjdFhWZXJzaW9uPSV1LCBwRnVuY3Rpb249JXAsIHBwRGVjbD0lcFxuIiwgVGhpcywgKChJV2luZUQzREltcGwgKilUaGlzLT53aW5lRDNEKS0+ZHhWZXJzaW9uLCBwRGVjbGFyYXRpb24sIHBwVmVydGV4RGVjbGFyYXRpb24pOwogICAgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBWZXJ0ZXhEZWNsYXJhdGlvbikKICAgIG9iamVjdC0+YWxsRlZGID0gMDsKCiAgICBociA9IElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb25fU2V0RGVjbGFyYXRpb24oKElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24gKilvYmplY3QsICh2b2lkICopcERlY2xhcmF0aW9uKTsKCiAgICByZXR1cm4gaHI7Cn0KCi8qIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vYXJjaGl2ZS9kZWZhdWx0LmFzcD91cmw9L2FyY2hpdmUvZW4tdXMvZGlyZWN0eDlfYy9kaXJlY3R4L2dyYXBoaWNzL3Byb2dyYW1taW5nZ3VpZGUvcHJvZ3JhbW1hYmxlL3ZlcnRleHNoYWRlcnMvdnNjcmVhdGUuYXNwICovCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhTaGFkZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBDT05TVCBEV09SRCAqcERlY2xhcmF0aW9uLCBDT05TVCBEV09SRCAqcEZ1bmN0aW9uLCBJV2luZUQzRFZlcnRleFNoYWRlciAqKnBwVmVydGV4U2hhZGVyLCBJVW5rbm93biAqcGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleFNoYWRlckltcGwgKm9iamVjdDsgIC8qIE5PVEU6IGltcGwgdXNhZ2UgaXMgb2ssIHRoaXMgaXMgYSBjcmVhdGUgKi8KICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNEX09LOwogICAgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBWZXJ0ZXhTaGFkZXIpCiAgICBvYmplY3QtPmJhc2VTaGFkZXIuc2hhZGVyX2lucyA9IElXaW5lRDNEVmVydGV4U2hhZGVySW1wbF9zaGFkZXJfaW5zOwoKICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCBWZXJ0ZXggc2hhZGVyICVwXG4iLCBUaGlzLCAqcHBWZXJ0ZXhTaGFkZXIpOwoKICAgIC8qIElmIGEgdmVydGV4IGRlY2xhcmF0aW9uIGhhcyBiZWVuIHBhc3NlZCwgc2F2ZSBpdCB0byB0aGUgdmVydGV4IHNoYWRlciwgdGhpcyBhZmZlY3RzIGQzZDggb25seS4gKi8KICAgIC8qIEZ1cnRoZXIgaXQgbmVlZHMgdG8gYmUgc2V0IGJlZm9yZSBjYWxsaW5nIFNldEZ1bmN0aW9uIGFzIFNldEZ1bmN0aW9uIG5lZWRzIHRoZSBkZWNsYXJhdGlvbi4gKi8KICAgIGlmIChwRGVjbGFyYXRpb24gIT0gTlVMTCkgewogICAgICAgIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24gKnZlcnRleERlY2xhcmF0aW9uOwogICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlVmVydGV4RGVjbGFyYXRpb24oaWZhY2UsIHBEZWNsYXJhdGlvbiwgJnZlcnRleERlY2xhcmF0aW9uICxOVUxMKTsKICAgICAgICBpZiAoV0lORUQzRF9PSyA9PSBocikgewogICAgICAgICAgICBUUkFDRSgiKCVwKSA6IFNldHRpbmcgdmVydGV4IGRlY2xhcmF0aW9uIHRvICVwXG4iLCBUaGlzLCB2ZXJ0ZXhEZWNsYXJhdGlvbik7CiAgICAgICAgICAgIG9iamVjdC0+dmVydGV4RGVjbGFyYXRpb24gPSB2ZXJ0ZXhEZWNsYXJhdGlvbjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBGSVhNRSgiKCVwKSA6IEZhaWxlZCB0byBzZXQgdGhlIGRlY2xhcmF0aW9uLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIiwgaWZhY2UpOwogICAgICAgICAgICBJV2luZUQzRFZlcnRleFNoYWRlcl9SZWxlYXNlKCpwcFZlcnRleFNoYWRlcik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgIH0KCiAgICBociA9IElXaW5lRDNEVmVydGV4U2hhZGVyX1NldEZ1bmN0aW9uKCpwcFZlcnRleFNoYWRlciwgcEZ1bmN0aW9uKTsKCiAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgIEZJWE1FKCIoJXApIDogRmFpbGVkIHRvIHNldCB0aGUgZnVuY3Rpb24sIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLCBpZmFjZSk7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXJfUmVsZWFzZSgqcHBWZXJ0ZXhTaGFkZXIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKI2lmIDAgLyogVE9ETzogSW4gRDNEKiBTVlAgaXMgYXRhdGNoZWQgdG8gdGhlIHNoYWRlciwgaW4gRDNEOSBpdCdzIGF0dGFjaGVkIHRvIHRoZSBkZXZpY2UgYW5kIGlzbid0IHN0b3JlZCBpbiB0aGUgc3RhdGVibG9jay4gKi8KICAgIGlmKFVzYWdlID09IFdJTkVEM0RVU0FHRV9TT0ZUV0FSRVZFUlRFWFBST0NFU1NJTkcpIHsKICAgICAgICAvKiBGb28gKi8KICAgIH0gZWxzZSB7CiAgICAgICAgLyogQmFyICovCiAgICB9CgojZW5kaWYKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVBpeGVsU2hhZGVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgQ09OU1QgRFdPUkQgKnBGdW5jdGlvbiwgSVdpbmVEM0RQaXhlbFNoYWRlciAqKnBwUGl4ZWxTaGFkZXIsIElVbmtub3duICpwYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICpvYmplY3Q7IC8qIE5PVEU6IGltcGwgYWxsb3dlZCwgdGhpcyBpcyBhIGNyZWF0ZSAqLwogICAgSFJFU1VMVCBociA9IFdJTkVEM0RfT0s7CgogICAgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBQaXhlbFNoYWRlcikKICAgIG9iamVjdC0+YmFzZVNoYWRlci5zaGFkZXJfaW5zID0gSVdpbmVEM0RQaXhlbFNoYWRlckltcGxfc2hhZGVyX2luczsKICAgIGhyID0gSVdpbmVEM0RQaXhlbFNoYWRlcl9TZXRGdW5jdGlvbigqcHBQaXhlbFNoYWRlciwgcEZ1bmN0aW9uKTsKICAgIGlmIChXSU5FRDNEX09LID09IGhyKSB7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBDcmVhdGVkIFBpeGVsIHNoYWRlciAlcFxuIiwgVGhpcywgKnBwUGl4ZWxTaGFkZXIpOwogICAgfSBlbHNlIHsKICAgICAgICBXQVJOKCIoJXApIDogRmFpbGVkIHRvIGNyZWF0ZSBwaXhlbCBzaGFkZXJcbiIsIFRoaXMpOwogICAgfQoKICAgIHJldHVybiBocjsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVBhbGV0dGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBGbGFncywgUEFMRVRURUVOVFJZICpQYWxFbnQsIElXaW5lRDNEUGFsZXR0ZSAqKlBhbGV0dGUsIElVbmtub3duICpQYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFBhbGV0dGVJbXBsICpvYmplY3Q7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglbHgsICVwLCAlcCwgJXApXG4iLCBUaGlzLCBGbGFncywgUGFsRW50LCBQYWxldHRlLCBQYXJlbnQpOwoKICAgIC8qIENyZWF0ZSB0aGUgbmV3IG9iamVjdCAqLwogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRFBhbGV0dGVJbXBsKSk7CiAgICBpZighb2JqZWN0KSB7CiAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5IHdoZW4gYWxsb2NhdGluZyBtZW1vcnkgZm9yIGEgSVdpbmVEM0RQYWxldHRlIGltcGxlbWVudGF0aW9uXG4iKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICBvYmplY3QtPmxwVnRibCA9ICZJV2luZUQzRFBhbGV0dGVfVnRibDsKICAgIG9iamVjdC0+cmVmID0gMTsKICAgIG9iamVjdC0+RmxhZ3MgPSBGbGFnczsKICAgIG9iamVjdC0+cGFyZW50ID0gUGFyZW50OwogICAgb2JqZWN0LT53aW5lRDNERGV2aWNlID0gVGhpczsKICAgIG9iamVjdC0+cGFsTnVtRW50cmllcyA9IElXaW5lRDNEUGFsZXR0ZUltcGxfU2l6ZShGbGFncyk7CgkKICAgIG9iamVjdC0+aHBhbCA9IENyZWF0ZVBhbGV0dGUoKGNvbnN0IExPR1BBTEVUVEUqKSYob2JqZWN0LT5wYWxWZXJzaW9uKSk7CgogICAgaWYoIW9iamVjdC0+aHBhbCkgewogICAgICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QpOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQoKICAgIGhyID0gSVdpbmVEM0RQYWxldHRlX1NldEVudHJpZXMoKElXaW5lRDNEUGFsZXR0ZSAqKSBvYmplY3QsIDAsIDAsIElXaW5lRDNEUGFsZXR0ZUltcGxfU2l6ZShGbGFncyksIFBhbEVudCk7CiAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgSVdpbmVEM0RQYWxldHRlX1JlbGVhc2UoKElXaW5lRDNEUGFsZXR0ZSAqKSBvYmplY3QpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAqUGFsZXR0ZSA9IChJV2luZUQzRFBhbGV0dGUgKikgb2JqZWN0OwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfSW5pdDNEKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFBSRVNFTlRfUEFSQU1FVEVSUyogcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsIEQzRENCX0NSRUFURUFERElUSU9OQUxTV0FQQ0hBSU4gRDNEQ0JfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLCBUaGlzLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycywgRDNEQ0JfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbik7CiAgICBpZihUaGlzLT5kM2RfaW5pdGlhbGl6ZWQpIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIC8qIFRPRE86IFRlc3QgaWYgT3BlbkdMIGlzIGNvbXBpbGVkIGluIGFuZCBsb2FkZWQgKi8KCiAgICAvKiBTZXR1cCB0aGUgaW1wbGljaXQgc3dhcGNoYWluICovCiAgICBUUkFDRSgiQ3JlYXRpbmcgaW1wbGljaXQgc3dhcGNoYWluXG4iKTsKICAgIGlmIChEM0RfT0sgIT0gRDNEQ0JfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbigoSVVua25vd24gKikgVGhpcy0+cGFyZW50LCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycywgKElXaW5lRDNEU3dhcENoYWluICoqKSZzd2FwY2hhaW4pIHx8IHN3YXBjaGFpbiA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiRmFpbGVkIHRvIGNyZWF0ZSBpbXBsaWNpdCBzd2FwY2hhaW5cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmKHN3YXBjaGFpbi0+YmFja0J1ZmZlcikgewogICAgICAgIFRSQUNFKCJTZXR0aW5nIHJlbmRlcnRhcmdldCB0byAlcFxuIiwgc3dhcGNoYWluLT5iYWNrQnVmZmVyKTsKICAgICAgICBUaGlzLT5yZW5kZXJUYXJnZXQgPSBzd2FwY2hhaW4tPmJhY2tCdWZmZXI7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBUUkFDRSgiU2V0dGluZyByZW5kZXJ0YXJnZXQgdG8gJXBcbiIsIHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpOwogICAgICAgIFRoaXMtPnJlbmRlclRhcmdldCA9IHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXI7CiAgICB9CiAgICBJV2luZUQzRFN1cmZhY2VfQWRkUmVmKFRoaXMtPnJlbmRlclRhcmdldCk7CiAgICAvKiBEZXB0aCBTdGVuY2lsIHN1cHBvcnQgKi8KICAgIFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgPSBUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXI7CiAgICBpZiAoTlVMTCAhPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZihUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KTsKICAgIH0KCiAgICAvKiBTZXQgdXAgc29tZSBzdGFydGluZyBHTCBzZXR1cCAqLwogICAgRU5URVJfR0woKTsKICAgIC8qCiAgICAqIEluaXRpYWxpemUgb3BlbkdMIGV4dGVuc2lvbiByZWxhdGVkIHZhcmlhYmxlcwogICAgKiAgd2l0aCBEZWZhdWx0IHZhbHVlcwogICAgKi8KCiAgICAoKElXaW5lRDNESW1wbCAqKSBUaGlzLT53aW5lRDNEKS0+aXNHTEluZm9WYWxpZCA9IElXaW5lRDNESW1wbF9GaWxsR0xDYXBzKCAmKChJV2luZUQzREltcGwgKikgVGhpcy0+d2luZUQzRCktPmdsX2luZm8sIHN3YXBjaGFpbi0+ZGlzcGxheSk7CiAgICAvKiBTZXR1cCBhbGwgdGhlIGRldmljZXMgZGVmYXVsdHMgKi8KICAgIElXaW5lRDNEU3RhdGVCbG9ja19Jbml0U3RhcnR1cFN0YXRlQmxvY2soKElXaW5lRDNEU3RhdGVCbG9jayAqKVRoaXMtPnN0YXRlQmxvY2spOwojaWYgMAogICAgSVdpbmVEM0RJbXBsX0NoZWNrR3JhcGhpY3NNZW1vcnkoKTsKI2VuZGlmCiAgICBMRUFWRV9HTCgpOwoKICAgIHsgLyogU2V0IGEgZGVmYXVsdCB2aWV3cG9ydCAqLwogICAgICAgIEQzRFZJRVdQT1JUOSB2cDsKICAgICAgICB2cC5YICAgICAgPSAwOwogICAgICAgIHZwLlkgICAgICA9IDA7CiAgICAgICAgdnAuV2lkdGggID0gKihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoKTsKICAgICAgICB2cC5IZWlnaHQgPSAqKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0KTsKICAgICAgICB2cC5NaW5aICAgPSAwLjBmOwogICAgICAgIHZwLk1heFogICA9IDEuMGY7CiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0Vmlld3BvcnQoKElXaW5lRDNERGV2aWNlICopVGhpcywgJnZwKTsKICAgIH0KCgogICAgLyogSW5pdGlhbGl6ZSB0aGUgY3VycmVudCB2aWV3IHN0YXRlICovCiAgICBUaGlzLT5tb2RlbHZpZXdfdmFsaWQgPSAxOwogICAgVGhpcy0+cHJval92YWxpZCA9IDA7CiAgICBUaGlzLT52aWV3X2lkZW50ID0gMTsKICAgIFRoaXMtPmxhc3Rfd2FzX3JodyA9IDA7CiAgICBnbEdldEludGVnZXJ2KEdMX01BWF9MSUdIVFMsICZUaGlzLT5tYXhDb25jdXJyZW50TGlnaHRzKTsKICAgIFRSQUNFKCIoJXApIEFsbCBkZWZhdWx0cyBub3cgc2V0IHVwLCBsZWF2aW5nIEluaXQzRCB3aXRoICVwXG4iLCBUaGlzLCBUaGlzKTsKCiAgICAvKiBDbGVhciB0aGUgc2NyZWVuICovCiAgICBJV2luZUQzRERldmljZV9DbGVhcigoSVdpbmVEM0REZXZpY2UgKikgVGhpcywgMCwgTlVMTCwgRDNEQ0xFQVJfU1RFTkNJTHxEM0RDTEVBUl9aQlVGRkVSfEQzRENMRUFSX1RBUkdFVCwgMHgwMCwgMS4wLCAwKTsKCiAgICBUaGlzLT5kM2RfaW5pdGlhbGl6ZWQgPSBUUlVFOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9VbmluaXQzRChJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBpbnQgdGV4c3RhZ2U7CiAgICBJVW5rbm93biogc3RlbmNpbEJ1ZmZlclBhcmVudDsKICAgIElVbmtub3duKiBzd2FwQ2hhaW5QYXJlbnQ7CiAgICBTd2FwQ2hhaW5MaXN0ICpuZXh0U3dhcGNoYWluOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIGlmKCFUaGlzLT5kM2RfaW5pdGlhbGl6ZWQpIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIGZvcih0ZXhzdGFnZSA9IDA7IHRleHN0YWdlIDwgR0xfTElNSVRTKHRleHR1cmVzKTsgdGV4c3RhZ2UrKykgewogICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmUoaWZhY2UsIHRleHN0YWdlLCBOVUxMKTsKICAgIH0KCiAgICAvKiBOT1RFOiBZb3UgbXVzdCByZWxlYXNlIHRoZSBwYXJlbnQgaWYgdGhlIG9iamVjdCB3YXMgY3JlYXRlZCB2aWEgYSBjYWxsYmFjawogICAgKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgLyogUmVsZWFzZSBhbGwgb2YgdGhlIHN3YXBjaGFpbnMsIGV4Y2VwdCB0aGUgaW1wbGljaXQgc3dhcGNoYWluICovCgogICAgLyogTk9URTogRG9uJ3QgcmVsZWFzZSBzd2FwY2hhaW4gMCBoZXJlLCBpdCdzICdzcGVjaWFsJyAqLwogICAgVFJBQ0UoIkZpbmRpbmcgaW1wbGljaXQgc3dhcGNoYWluXG4iKTsKICAgIG5leHRTd2FwY2hhaW4gPSBUaGlzLT5zd2FwY2hhaW5zOwogICAgaWYgKG5leHRTd2FwY2hhaW4gIT0gTlVMTCkgewogICAgICAgIG5leHRTd2FwY2hhaW4gPSBuZXh0U3dhcGNoYWluLT5uZXh0OwogICAgfSBlbHNlIHsKICAgICAgICBXQVJOKCJFeHBlY3RlZCB0byBmaW5kIHRoZSBpbXBsaWNpdCBzd2FwY2hhaW5cbiIpOwogICAgfQoKICAgIFRSQUNFKCJSZWxlYXNpbmcgc3dhcGNoYWlucy4gbmV4dFN3YXBjaGFpbiA9ICVwXG4iLCBuZXh0U3dhcGNoYWluKTsKICAgIC8qIHJlbGVhc2UgYWxsIHRoZSBvdGhlciBzd2FwY2hhaW5zICovCiAgICB3aGlsZSAobmV4dFN3YXBjaGFpbiAhPSBOVUxMKSB7CiAgICAgICAgU3dhcENoYWluTGlzdCAqcHJldlN3YXBjaGFpbiA9IG5leHRTd2FwY2hhaW47CiAgICAgICAgbmV4dFN3YXBjaGFpbiA9IG5leHRTd2FwY2hhaW4tPm5leHQ7CiAgICAgICAgVFJBQ0UoIlJlbGVhc2luZyBzd2FwY2hhaW4gJXBcbiIsIHByZXZTd2FwY2hhaW4tPnN3YXBjaGFpbik7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShwcmV2U3dhcGNoYWluLT5zd2FwY2hhaW4pOwogICAgICAgIC8qIE5PVEU6IG5vIG5lZWQgdG8gZnJlZSB0aGUgbGlzdCBlbGVtZW50LCBpdCB3aWxsIGJlIGRvbmUgYnkgdGhlIHJlbGVhc2UgY2FsbGJhY2sKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcHJldlN3YXBjaGFpbik7ICovCiAgICB9CiAgICAgIC8qIFJlbGVhc2UgdGhlIGJ1ZmZlcnMgKHdpdGggc2FuaXR5IGNoZWNrcykqLwogICAgVFJBQ0UoIlJlbGVhc2luZyB0aGUgZGVwdGggc3RlbmNpbCBidWZmZXIgYXQgJXBcbiIsIFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpOwogICAgaWYoVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCAhPSBOVUxMICYmIChJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSA+MCkpewogICAgICAgIGlmKFRoaXMtPmRlcHRoU3RlbmNpbEJ1ZmZlciAhPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KQogICAgICAgICAgICBGSVhNRSgiKCVwKSBTb21ldGhpbmcncyBzdGlsbCBob2xkaW5nIHRoZSBkZXB0aFN0ZW5jaWxCdWZmZXJcbiIsVGhpcyk7CiAgICB9CiAgICBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0ID0gTlVMTDsKCiAgICBUUkFDRSgiUmVsZWFzaW5nIHRoZSByZW5kZXIgdGFyZ2V0IGF0ICVwXG4iLCBUaGlzLT5yZW5kZXJUYXJnZXQpOwogICAgaWYoSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoVGhpcy0+cmVuZGVyVGFyZ2V0KSA+MCl7CiAgICAgICAgICAvKiBUaGlzIGNoZWNrIGlzIGEgYml0IHNpbGx5LCBpdHNob3VsZCBiZSBpbiBzd2FwY2hhaW5fcmVsZWFzZSBGSVhNRSgiKCVwKSBTb21ldGhpbmcncyBzdGlsbCBob2xkaW5nIHRoZSByZW5kZXJUYXJnZXRcbiIsVGhpcyk7ICovCiAgICB9CiAgICBUUkFDRSgiU2V0dGluZyByZW5kZXJ0YXJnZXQgdG8gTlVMTFxuIik7CiAgICBUaGlzLT5yZW5kZXJUYXJnZXQgPSBOVUxMOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRQYXJlbnQoVGhpcy0+ZGVwdGhTdGVuY2lsQnVmZmVyLCAmc3RlbmNpbEJ1ZmZlclBhcmVudCk7CiAgICBJVW5rbm93bl9SZWxlYXNlKHN0ZW5jaWxCdWZmZXJQYXJlbnQpOyAgICAgICAgICAvKiBvbmNlIGZvciB0aGUgZ2V0IHBhcmVudCAqLwogICAgaWYoSVVua25vd25fUmVsZWFzZShzdGVuY2lsQnVmZmVyUGFyZW50KSAgPjApeyAgLyogdGhlIHNlY29uZCB0aW1lIGZvciB3aGVuIGl0IHdhcyBjcmVhdGVkICovCiAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgZGVwdGhTdGVuY2lsQnVmZmVyXG4iLFRoaXMpOwogICAgfQogICAgVGhpcy0+ZGVwdGhTdGVuY2lsQnVmZmVyID0gTlVMTDsKCiAgICBUUkFDRSgiUmVsZWFzaW5nIHRoZSBpbXBsaWNpdCBzd2FwY2hhaW5cbiIpOwogICAgaWYgKFRoaXMtPnN3YXBjaGFpbnMgIT0gTlVMTCkgewogICAgICAgIC8qIFN3YXBjaGFpbiAwIGlzIHNwZWNpYWwgYmVjYXVzZSBpdCdzIGNyZWF0ZWQgaW4gc3RhcnR1cCB3aXRoIGEgaGFuZ2luZyBwYXJlbnQsIHNvIHdlIGhhdmUgdG8gcmVsZWFzZSBpdHMgcGFyZW50IG5vdyAqLwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX0dldFBhcmVudChUaGlzLT5zd2FwY2hhaW5zLT5zd2FwY2hhaW4sICZzd2FwQ2hhaW5QYXJlbnQpOwogICAgICAgIElVbmtub3duX1JlbGVhc2Uoc3dhcENoYWluUGFyZW50KTsgICAgICAgICAgIC8qIG9uY2UgZm9yIHRoZSBnZXQgcGFyZW50ICovCiAgICAgICAgaWYgKElVbmtub3duX1JlbGVhc2Uoc3dhcENoYWluUGFyZW50KSAgPiAwKSB7ICAvKiB0aGUgc2Vjb25kIHRpbWUgZm9yIHdoZW4gaXQgd2FzIGNyZWF0ZWQgKi8KICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgaW1wbGljaXQgc3dhcGNoYWluXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICB9CiAgICBUaGlzLT5zd2FwY2hhaW5zID0gTlVMTDsKCiAgICBUaGlzLT5kM2RfaW5pdGlhbGl6ZWQgPSBGQUxTRTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRW51bURpc3BsYXlNb2RlcyhJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEZsYWdzLCBVSU5UIFdpZHRoLCBVSU5UIEhlaWdodCwgV0lORUQzREZPUk1BVCBwaXhlbGZvcm1hdCwgTFBWT0lEIGNvbnRleHQsIEQzRENCX0VOVU1ESVNQTEFZTU9ERVNDQUxMQkFDSyBjYWxsYmFjaykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIERFVk1PREVXIERldk1vZGVXOwogICAgaW50IGk7CgogICAgVFJBQ0UoIiglcCktPiglbHgsJWQsJWQsJWQsJXAsJXApXG4iLCBUaGlzLCBGbGFncywgV2lkdGgsIEhlaWdodCwgcGl4ZWxmb3JtYXQsIGNvbnRleHQsIGNhbGxiYWNrKTsKCiAgICBmb3IgKGkgPSAwOyBFbnVtRGlzcGxheVNldHRpbmdzRXhXKE5VTEwsIGksICZEZXZNb2RlVywgMCk7IGkrKykgewogICAgICAgIC8qIElnbm9yZSBzb21lIG1vZGVzIGlmIGEgZGVzY3JpcHRpb24gd2FzIHBhc3NlZCAqLwogICAgICAgIGlmICggKFdpZHRoID4gMCkgICYmIChXaWR0aCAhPSBEZXZNb2RlVy5kbVBlbHNXaWR0aCkpIGNvbnRpbnVlOwogICAgICAgIGlmICggKEhlaWdodCA+IDApICAmJiAoSGVpZ2h0ICE9IERldk1vZGVXLmRtUGVsc0hlaWdodCkpIGNvbnRpbnVlOwogICAgICAgIGlmICggKHBpeGVsZm9ybWF0ICE9IFdJTkVEM0RGTVRfVU5LTk9XTikgJiYgKCBEM0RGbXRHZXRCcHAoTlVMTCwgcGl4ZWxmb3JtYXQpICE9IERldk1vZGVXLmRtQml0c1BlclBlbCkgKSBjb250aW51ZTsKCiAgICAgICAgVFJBQ0UoIkVudW1lcmF0aW5nICVsZHglbGRAJXNcbiIsIERldk1vZGVXLmRtUGVsc1dpZHRoLCBEZXZNb2RlVy5kbVBlbHNIZWlnaHQsIGRlYnVnX2QzZGZvcm1hdChwaXhlbGZvcm1hdF9mb3JfZGVwdGgoRGV2TW9kZVcuZG1CaXRzUGVyUGVsKSkpOwoKICAgICAgICBpZiAoY2FsbGJhY2soKElVbmtub3duICopIFRoaXMsIChVSU5UKSBEZXZNb2RlVy5kbVBlbHNXaWR0aCwgKFVJTlQpIERldk1vZGVXLmRtUGVsc0hlaWdodCwgcGl4ZWxmb3JtYXRfZm9yX2RlcHRoKERldk1vZGVXLmRtQml0c1BlclBlbCksIDYwLjAsIGNvbnRleHQpID09IERERU5VTVJFVF9DQU5DRUwpCiAgICAgICAgICAgIHJldHVybiBEM0RfT0s7CiAgICB9CgogICAgcmV0dXJuIEQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldERpc3BsYXlNb2RlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBXSU5FRDNERElTUExBWU1PREUqIHBNb2RlKSB7CiAgICBGSVhNRSgiVGhpcyBjYWxsIGlzIGEgZDNkNyBtZXJnZSBzdHViLiBJdCB3aWxsIGJlIGltcGxlbWVudGVkIGxhdGVyXG4iKTsKICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRW51bVpCdWZmZXJGb3JtYXRzKElXaW5lRDNERGV2aWNlICppZmFjZSwgRDNEQ0JfRU5VTVBJWEVMRk9STUFUUyBDYWxsYmFjaywgdm9pZCAqQ29udGV4dCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIEhSRVNVTFQgcmV0OwogICAgaW50IGkgPSAwOwogICAgV0lORUQzREZPUk1BVCBGb3JtYXRMaXN0W10gPSB7CiAgICAgICAgV0lORUQzREZNVF9EMTYsCiAgICAgICAgV0lORUQzREZNVF9EMzIsCiAgICAgICAgV0lORUQzREZNVF9EMjRYNFM0LAogICAgICAgIFdJTkVEM0RGTVRfRDI0UzgsCiAgICAgICAgV0lORUQzREZNVF9EMjRYOCwKICAgICAgICBXSU5FRDNERk1UX0QxNVMxLAogICAgICAgIFdJTkVEM0RGTVRfVU5LTk9XTiAgLyogVGVybWluYXRlIHRoZSBsaXN0ICovCiAgICB9OwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLCBUaGlzLCBDYWxsYmFjaywgQ29udGV4dCk7CgogICAgd2hpbGUoRm9ybWF0TGlzdFtpXSAhPSBXSU5FRDNERk1UX1VOS05PV04pIHsKICAgICAgICBUUkFDRSgiRW51bWVyYXRpbmcgJXNcbiIsIGRlYnVnX2QzZGZvcm1hdChGb3JtYXRMaXN0W2ldKSk7CiAgICAgICAgcmV0ID0gQ2FsbGJhY2soKElVbmtub3duICopIFRoaXMsIEZvcm1hdExpc3RbaV0sIENvbnRleHQpOwogICAgICAgIGlmKHJldCAhPSBEREVOVU1SRVRfT0spIHsKICAgICAgICAgICAgVFJBQ0UoIkVudW1lcmF0aW9uIGNhbmNlbGxlZCBieSBBcHBsaWNhdGlvblxuIik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgICAgIH0KICAgICAgICBpKys7CiAgICB9CgogICAgVFJBQ0UoIkVuZCBvZiBFbnVtZXJhdGlvblxuIik7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9FbnVtVGV4dHVyZUZvcm1hdHMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEM0RDQl9FTlVNUElYRUxGT1JNQVRTIENhbGxiYWNrLCB2b2lkICpDb250ZXh0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSFJFU1VMVCByZXQ7CiAgICBpbnQgaSA9IDA7CiAgICAKICAgIC8qIEZyb20gb2xkIGRkcmF3OgogICAgICogV0lORUQzREZNVF9BMVI1RzVCNSBuZWVkcyB0byBiZSB0aGUgZmlyc3QgMTYgYml0IGZvcm1hdCwgYXMgc29tZSBkdW1iIGFwcHMgZGVwZW5kIG9uIHRoaXMKICAgICAqCiAgICAgKiBEbyBub3QgZW51bWVyYXRlIFJHQkEgcGl4ZWwgZm9ybWF0czogInNvbWUgZ2FtZXMgY2hvb3NlIHRoZSBmaXJzdCAxNiBiaXQgdGV4dHVyZSBmb3JtYXQKICAgICAqIHdpdGggYWxwaGEgdGhleSBmaW5kIGVudW1lcmF0ZWQsIG90aGVycyB0aGUgbGFzdCBvbmUuIEFuZCBib3RoIHdhbnQgdG8gaGF2ZSB0aGUgQVJHQiBvbmUuIgogICAgICogQnV0IFdpbmVEM0QgZG9lc24ndCBzdXBwb3J0IFJHQkEgZm9ybWF0cyBhbnl3YXkuLi4KICAgICAqLwoKICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0TGlzdFtdID0gewogICAgICAgIC8qIDMyIGJpdCAqLwogICAgICAgIFdJTkVEM0RGTVRfQThSOEc4QjgsCiAgICAgICAgV0lORUQzREZNVF9YOFI4RzhCOCwKICAgICAgICAvKiAyNCBiaXQgKi8KICAgICAgICBXSU5FRDNERk1UX1I4RzhCOCwKICAgICAgICAvKiAxNiBCaXQgKi8KICAgICAgICBXSU5FRDNERk1UX0ExUjVHNUI1LAogICAgICAgIFdJTkVEM0RGTVRfQTRSNEc0QjQsCiAgICAgICAgV0lORUQzREZNVF9SNUc2QjUsCiAgICAgICAgV0lORUQzREZNVF9YMVI1RzVCNSwKICAgICAgICAvKiA4IEJpdCAqLwogICAgICAgIFdJTkVEM0RGTVRfUjNHM0IyLAogICAgICAgIFdJTkVEM0RGTVRfUDgsCiAgICAgICAgLyogRk9VUkNDIGNvZGVzICovCiAgICAgICAgV0lORUQzREZNVF9EWFQxLAogICAgICAgIFdJTkVEM0RGTVRfRFhUMywKICAgICAgICBXSU5FRDNERk1UX0RYVDUsCiAgICAgICAgIC8qIFRlcm1pbmF0ZSB0aGUgbGlzdCAqLwogICAgICAgIFdJTkVEM0RGTVRfVU5LTk9XTgogICAgfTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwKVxuIiwgVGhpcywgQ2FsbGJhY2ssIENvbnRleHQpOwoKICAgIHdoaWxlKEZvcm1hdExpc3RbaV0gIT0gV0lORUQzREZNVF9VTktOT1dOKSB7CiAgICAgICAgVFJBQ0UoIkVudW1lcmF0aW5nICVzXG4iLCBkZWJ1Z19kM2Rmb3JtYXQoRm9ybWF0TGlzdFtpXSkpOwogICAgICAgIHJldCA9IENhbGxiYWNrKChJVW5rbm93biAqKSBUaGlzLCBGb3JtYXRMaXN0W2ldLCBDb250ZXh0KTsKICAgICAgICBpZihyZXQgIT0gRERFTlVNUkVUX09LKSB7CiAgICAgICAgICAgIFRSQUNFKCJFbnVtZXJhdGlvbiBjYW5jZWxsZWQgYnkgQXBwbGljYXRpb25cbiIpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgICAgICB9CiAgICAgICAgaSsrOwogICAgfQoKICAgIFRSQUNFKCJFbmQgb2YgRW51bWVyYXRpb25cbiIpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0RGlyZWN0M0QoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRCAqKnBwRDNEKSB7CiAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgKnBwRDNEPSBUaGlzLT53aW5lRDNEOwogICBUUkFDRSgiKCVwKSA6IHdpbmVEM0QgcmV0dXJuaW5nICVwXG4iLCBUaGlzLCAgKnBwRDNEKTsKICAgSVdpbmVEM0RfQWRkUmVmKCpwcEQzRCk7CiAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpVSU5UIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0QXZhaWxhYmxlVGV4dHVyZU1lbShJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIC8qKiBOT1RFOiBUaGVyZSdzIGEgcHJvYmFibHkgIGEgaGFjay1hcm91bmQgZm9yIHRoaXMgb25lIGJ5IHB1dHRpbmcgYXMgbWFueSBwYnVmZmVycywgVkJPJ3MgKG9yIHdoYXRldmVyKQogICAgKiBJbnRvIHRoZSB2aWRlbyByYW0gYXMgcG9zc2libGUgYW5kIHNlZWluZyBob3cgbWFueSBmaXQKICAgICogeW91IGNhbiBhbHNvIGdldCB0aGUgY29ycmVjdCBpbml0aWFsIHZhbHVlIGZyb20gdmlhIFggYW5kIEFUSSdzIGRyaXZlcgogICAgKioqKioqKioqKioqKioqKioqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBCT09MIHNob3dmaXhtZXMgPSBUUlVFOwogICAgaWYgKHNob3dmaXhtZXMpIHsKICAgICAgICBGSVhNRSgiKCVwKSA6IHN0dWIsIGVtdWxhdGluZyAlZE1pYiBmb3Igbm93LCByZXR1cm5pbmcgJWRNaWJcbiIsIFRoaXMsIChlbXVsYXRlZF90ZXh0dXJlcmFtLygxMDI0KjEwMjQpKSwKICAgICAgICAgKChlbXVsYXRlZF90ZXh0dXJlcmFtIC0gd2luZUQzREdsb2JhbFN0YXRpc3RpY3MtPmdsc3VyZmFjZXJhbSkgLyAoMTAyNCoxMDI0KSkpOwogICAgICAgICBzaG93Zml4bWVzID0gRkFMU0U7CiAgICB9CiAgICBUUkFDRSgiKCVwKSA6ICBlbXVsYXRpbmcgJWRNaWIgZm9yIG5vdywgcmV0dXJuaW5nICVkTWliXG4iLCAgVGhpcywgKGVtdWxhdGVkX3RleHR1cmVyYW0vKDEwMjQqMTAyNCkpLAogICAgICAgICAoKGVtdWxhdGVkX3RleHR1cmVyYW0gLSB3aW5lRDNER2xvYmFsU3RhdGlzdGljcy0+Z2xzdXJmYWNlcmFtKSAvICgxMDI0KjEwMjQpKSk7CiAgICAvKiB2aWRlb21lbW9yeSBpcyBzaW11bGF0ZWQgdmlkZW9tZW1vcnkgKyBBR1AgbWVtb3J5IGxlZnQgKi8KICAgIHJldHVybiAoZW11bGF0ZWRfdGV4dHVyZXJhbSAtIHdpbmVEM0RHbG9iYWxTdGF0aXN0aWNzLT5nbHN1cmZhY2VyYW0pOwp9CgoKCi8qKioqKgogKiBHZXQgLyBTZXQgRlZGCiAqKioqKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZWRihJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIGZ2ZikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSFJFU1VMVCBociA9IFdJTkVEM0RfT0s7CgogICAgLyogVXBkYXRlIHRoZSBjdXJyZW50IHN0YXRlIGJsb2NrICovCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5mdmYgICAgICAgICAgICAgID0gZnZmOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5mdmYgICAgICA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQuZnZmICAgICAgICAgID0gVFJVRTsKCiAgICBUUkFDRSgiKCVwKSA6IEZWRiBTaGFkZXIgRlZGIHNldCB0byAlbHhcbiIsIFRoaXMsIGZ2Zik7CgogICAgaWYgKDAgIT0gZnZmKSB7CiAgICAgICAgLyogY2xlYXIgZG93biB0aGUgdmVydGV4IGRlY2xhcmF0aW9uCiAgICAgICAgIE5PVEU6IEF4aXMgYW5kIEFsbGllcyBkb2Vzbid0IHdvcmsgcHJvcGVybHkgb3RoZXJ3aXNlCiAgICAgICAgIChtYXkgYmUgYSBzdGF0ZWJsb2NrIHByb2JsZW0gdGhvdWdoISkKICAgICAgICAqLwogICAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFZlcnRleERlY2xhcmF0aW9uKGlmYWNlLCBOVUxMKTsKICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0RlZGKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgKnBmdmYpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogR2V0RlZGIHJldHVybmluZyAlbHhcbiIsIFRoaXMsIFRoaXMtPnN0YXRlQmxvY2stPmZ2Zik7CiAgICAqcGZ2ZiA9IFRoaXMtPnN0YXRlQmxvY2stPmZ2ZjsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IFN0cmVhbSBTb3VyY2UKICoqKioqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0U3RyZWFtU291cmNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBTdHJlYW1OdW1iZXIsSVdpbmVEM0RWZXJ0ZXhCdWZmZXIqIHBTdHJlYW1EYXRhLCBVSU5UIE9mZnNldEluQnl0ZXMsIFVJTlQgU3RyaWRlKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgICAgICpvbGRTcmM7CgogICAgLyoqVE9ETzogaW5zdGFuY2UgYW5kIGluZGV4IGRhdGEsIHNlZQogICAgaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9saWJyYXJ5L2RlZmF1bHQuYXNwP3VybD0vbGlicmFyeS9lbi11cy9kaXJlY3R4OV9jL2RpcmVjdHgvZ3JhcGhpY3MvcHJvZ3JhbW1pbmdndWlkZS9hZHZhbmNlZHRvcGljcy9EcmF3aW5nTXVsdGlwbGVJbnN0YW5jZXMuYXNwCiAgICBhbmQKICAgIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvZGlyZWN0eDlfYy9kaXJlY3R4L2dyYXBoaWNzL3JlZmVyZW5jZS9kM2QvaW50ZXJmYWNlcy9pZGlyZWN0M2RkZXZpY2U5L1NldFN0cmVhbVNvdXJjZUZyZXEuYXNwCiAgICAgKioqKioqKioqKioqKiovCgogICAgLyogRDNkOSBvbmx5LCBidXQgc2hvdWxkbid0ICBodXJ0IGQzZDggKi8KICAgIFVJTlQgc3RyZWFtRmxhZ3M7CgogICAgc3RyZWFtRmxhZ3MgPSBTdHJlYW1OdW1iZXIgJihEM0RTVFJFQU1TT1VSQ0VfSU5ERVhFRERBVEEgfCBEM0RTVFJFQU1TT1VSQ0VfSU5TVEFOQ0VEQVRBKTsKICAgIGlmIChzdHJlYW1GbGFncykgewogICAgICAgIGlmIChzdHJlYW1GbGFncyAmIEQzRFNUUkVBTVNPVVJDRV9JTkRFWEVEREFUQSkgewogICAgICAgICAgIEZJWE1FKCJzdHJlYW0gaW5kZXggZGF0YSBub3Qgc3VwcG9ydGVkXG4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKHN0cmVhbUZsYWdzICYgRDNEU1RSRUFNU09VUkNFX0lOREVYRUREQVRBKSB7CiAgICAgICAgICAgRklYTUUoInN0cmVhbSBpbnN0YW5jZSBkYXRhIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICBTdHJlYW1OdW1iZXImPSB+KEQzRFNUUkVBTVNPVVJDRV9JTkRFWEVEREFUQSB8IEQzRFNUUkVBTVNPVVJDRV9JTlNUQU5DRURBVEEpOwoKICAgIGlmIChTdHJlYW1OdW1iZXIgPj0gTUFYX1NUUkVBTVMpIHsKICAgICAgICBXQVJOKCJTdHJlYW0gb3V0IG9mIHJhbmdlICVkXG4iLCBTdHJlYW1OdW1iZXIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIG9sZFNyYyA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtTdHJlYW1OdW1iZXJdOwogICAgVFJBQ0UoIiglcCkgOiBTdHJlYW1ObzogJWQsIE9sZFN0cmVhbSAoJXApLCBOZXdTdHJlYW0gKCVwKSwgTmV3U3RyaWRlICVkXG4iLCBUaGlzLCBTdHJlYW1OdW1iZXIsIG9sZFNyYywgcFN0cmVhbURhdGEsIFN0cmlkZSk7CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXSA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQuc3RyZWFtU291cmNlW1N0cmVhbU51bWJlcl0gICAgID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVtTdHJlYW1OdW1iZXJdICAgICAgICAgPSBTdHJpZGU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXSAgICAgICAgID0gcFN0cmVhbURhdGE7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1PZmZzZXRbU3RyZWFtTnVtYmVyXSAgICAgICAgID0gT2Zmc2V0SW5CeXRlczsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZsYWdzW1N0cmVhbU51bWJlcl0gICAgICAgICAgPSBzdHJlYW1GbGFnczsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICAvKiBOb3QgcmVjb3JkaW5nLi4uICovCiAgICAvKiBOZWVkIHRvIGRvIGEgZ2V0UGFyZW50IGFuZCBwYXNzIHRoZSByZWZmcyB1cCAqLwogICAgLyogTVNETiBzYXlzIC4uLi4uIFdoZW4gYW4gYXBwbGljYXRpb24gbm8gbG9uZ2VyIGhvbGRzIGEgcmVmZXJlbmNlcyB0byB0aGlzIGludGVyZmFjZSwgdGhlIGludGVyZmFjZSB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgZnJlZWQuCiAgICB3aGljaCBzdWdnZXN0cyB0aGF0IHdlIHNob3VsZG4ndCBiZSByZWYgY291bnRpbmc/IGFuZCBkbyBuZWVkIGEgX3JlbGVhc2Ugb24gdGhlIHN0cmVhbSBzb3VyY2UgdG8gcmVzZXQgdGhlIHN0cmVhbSBzb3VyY2UKICAgIHNvIGZvciBub3csIGp1c3QgY291bnQgaW50ZXJuYWxseSAgICovCiAgICBpZiAocFN0cmVhbURhdGEgIT0gTlVMTCkgewogICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVyX0FkZFJlZihwU3RyZWFtRGF0YSk7CiAgICB9CiAgICBpZiAob2xkU3JjICE9IE5VTEwpIHsKICAgICAgICBJV2luZUQzRFZlcnRleEJ1ZmZlcl9SZWxlYXNlKG9sZFNyYyk7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTdHJlYW1Tb3VyY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFN0cmVhbU51bWJlcixJV2luZUQzRFZlcnRleEJ1ZmZlcioqIHBTdHJlYW0sIFVJTlQgKnBPZmZzZXQsIFVJTlQqIHBTdHJpZGUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFVJTlQgc3RyZWFtRmxhZ3M7CgogICAgVFJBQ0UoIiglcCkgOiBTdHJlYW1ObzogJWQsIFN0cmVhbSAoJXApLCBTdHJpZGUgJWRcbiIsIFRoaXMsIFN0cmVhbU51bWJlciwKICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXSwgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlW1N0cmVhbU51bWJlcl0pOwoKCiAgICBzdHJlYW1GbGFncyA9IFN0cmVhbU51bWJlciAmKEQzRFNUUkVBTVNPVVJDRV9JTkRFWEVEREFUQSB8IEQzRFNUUkVBTVNPVVJDRV9JTlNUQU5DRURBVEEpOwogICAgaWYgKHN0cmVhbUZsYWdzKSB7CiAgICAgICAgaWYgKHN0cmVhbUZsYWdzICYgRDNEU1RSRUFNU09VUkNFX0lOREVYRUREQVRBKSB7CiAgICAgICAgICAgRklYTUUoInN0cmVhbSBpbmRleCBkYXRhIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIH0KICAgICAgICBpZiAoc3RyZWFtRmxhZ3MgJiBEM0RTVFJFQU1TT1VSQ0VfSU5ERVhFRERBVEEpIHsKICAgICAgICAgICAgRklYTUUoInN0cmVhbSBpbnN0YW5jZSBkYXRhIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICBTdHJlYW1OdW1iZXImPSB+KEQzRFNUUkVBTVNPVVJDRV9JTkRFWEVEREFUQSB8IEQzRFNUUkVBTVNPVVJDRV9JTlNUQU5DRURBVEEpOwoKICAgIGlmIChTdHJlYW1OdW1iZXIgPj0gTUFYX1NUUkVBTVMpIHsKICAgICAgICBXQVJOKCJTdHJlYW0gb3V0IG9mIHJhbmdlICVkXG4iLCBTdHJlYW1OdW1iZXIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgKnBTdHJlYW0gPSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXTsKICAgICpwU3RyaWRlID0gVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlW1N0cmVhbU51bWJlcl07CiAgICAqcE9mZnNldCA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbU9mZnNldFtTdHJlYW1OdW1iZXJdOwoKICAgICBpZiAoKnBTdHJlYW0gPT0gTlVMTCkgewogICAgICAgIEZJWE1FKCJBdHRlbXB0aW5nIHRvIGdldCBhbiBlbXB0eSBzdHJlYW0gJWQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLCBTdHJlYW1OdW1iZXIpOwogICAgICAgIHJldHVybiAgV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBJV2luZUQzRFZlcnRleEJ1ZmZlcl9BZGRSZWYoKnBTdHJlYW0pOyAvKiBXZSBoYXZlIGNyZWF0ZWQgYSBuZXcgcmVmZXJlbmNlIHRvIHRoZSBWQiAqLwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qU2hvdWxkIGJlIHF1aXRlIGVhc3ksIGp1c3QgYW4gZXh0ZW5zaW9uIG9mIHZlcnRleGRhdGEKcmVmLi4uCmh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vYXJjaGl2ZS9kZWZhdWx0LmFzcD91cmw9L2FyY2hpdmUvZW4tdXMvZGlyZWN0eDlfY19TdW1tZXJfMDQvZGlyZWN0eC9ncmFwaGljcy9wcm9ncmFtbWluZ2d1aWRlL2FkdmFuY2VkdG9waWNzL0RyYXdpbmdNdWx0aXBsZUluc3RhbmNlcy5hc3AKClRoZSBkaXZpZGVyIGlzIGEgYml0IG9kZCB0aG91Z2gKClZlcnRleE9mZnNldCA9IFN0YXJ0VmVydGV4IC8gRGl2aWRlciAqIFN0cmVhbVN0cmlkZSArCiAgICAgICAgICAgICAgIFZlcnRleEluZGV4IC8gRGl2aWRlciAqIFN0cmVhbVN0cmlkZSArIFN0cmVhbU9mZnNldAoKKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFN0cmVhbVNvdXJjZUZyZXEoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCAgVUlOVCBTdHJlYW1OdW1iZXIsIFVJTlQgRGl2aWRlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIFN0cmVhbU51bWJlciglZCksIERpdmlkZXIoJWQpXG4iLCBUaGlzLCBTdHJlYW1OdW1iZXIsIERpdmlkZXIpOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtRmxhZ3NbU3RyZWFtTnVtYmVyXSA9IERpdmlkZXIgJiAoRDNEU1RSRUFNU09VUkNFX0lOU1RBTkNFREFUQSAgfCBEM0RTVFJFQU1TT1VSQ0VfSU5ERVhFRERBVEEgKTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnN0cmVhbUZyZXFbU3RyZWFtTnVtYmVyXSAgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnN0cmVhbUZyZXFbU3RyZWFtTnVtYmVyXSAgICAgID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZyZXFbU3RyZWFtTnVtYmVyXSAgICAgICAgICA9IERpdmlkZXIgJiAweDdGRkZGRjsKCiAgICBpZiAoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtRmxhZ3NbU3RyZWFtTnVtYmVyXSB8fCBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GcmVxW1N0cmVhbU51bWJlcl0gIT0gMSkgewogICAgICAgIEZJWE1FKCJTdHJlYW0gaW5kZXhpbmcgbm90IGZ1bGx5IHN1cHBvcnRlZFxuIik7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTdHJlYW1Tb3VyY2VGcmVxKElXaW5lRDNERGV2aWNlICppZmFjZSwgIFVJTlQgU3RyZWFtTnVtYmVyLCBVSU5UKiBEaXZpZGVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgU3RyZWFtTnVtYmVyKCVkKSwgRGl2aWRlciglcClcbiIsIFRoaXMsIFN0cmVhbU51bWJlciwgRGl2aWRlcik7CiAgICAqRGl2aWRlciA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZyZXFbU3RyZWFtTnVtYmVyXSB8IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZsYWdzW1N0cmVhbU51bWJlcl07CgogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmcgJWRcbiIsIFRoaXMsICpEaXZpZGVyKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCAmIE11bHRpcGx5IFRyYW5zZm9ybQogKioqKiovCkhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFRyYW5zZm9ybShJV2luZUQzRERldmljZSAqaWZhY2UsIEQzRFRSQU5TRk9STVNUQVRFVFlQRSBkM2R0cywgQ09OU1QgRDNETUFUUklYKiBscG1hdHJpeCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIC8qIE1vc3Qgb2YgdGhpcyByb3V0aW5lLCBjb21tZW50cyBpbmNsdWRlZCBjb3BpZWQgZnJvbSBkZHJhdyB0cmVlIGluaXRpYWxseTogKi8KICAgIFRSQUNFKCIoJXApIDogVHJhbnNmb3JtIFN0YXRlPSVkXG4iLCBUaGlzLCBkM2R0cyk7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC50cmFuc2Zvcm1bZDNkdHNdID0gVFJVRTsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQudHJhbnNmb3JtW2QzZHRzXSAgICAgPSBUUlVFOwogICAgICAgIG1lbWNweSgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dHJhbnNmb3Jtc1tkM2R0c10sIGxwbWF0cml4LCBzaXplb2YoRDNETUFUUklYKSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgLyoKICAgICAqIElmIHRoZSBuZXcgbWF0cml4IGlzIHRoZSBzYW1lIGFzIHRoZSBjdXJyZW50IG9uZSwKICAgICAqIHdlIGN1dCBvZmYgYW55IGZ1cnRoZXIgcHJvY2Vzc2luZy4gdGhpcyBzZWVtcyB0byBiZSBhIHJlYXNvbmFibGUKICAgICAqIG9wdGltaXphdGlvbiBiZWNhdXNlIGFzIHdhcyBub3RpY2VkLCBzb21lIGFwcHMgKHdhcmNyYWZ0MyBmb3IgZXhhbXBsZSkKICAgICAqIHRlbmQgdG93YXJkcyBzZXR0aW5nIHRoZSBzYW1lIG1hdHJpeCByZXBlYXRlZGx5IGZvciBzb21lIHJlYXNvbi4KICAgICAqCiAgICAgKiBGcm9tIGhlcmUgb24gd2UgYXNzdW1lIHRoYXQgdGhlIG5ldyBtYXRyaXggaXMgZGlmZmVyZW50LCB3aGVyZXZlciBpdCBtYXR0ZXJzLgogICAgICovCiAgICBpZiAoIW1lbWNtcCgmVGhpcy0+c3RhdGVCbG9jay0+dHJhbnNmb3Jtc1tkM2R0c10udS5tWzBdWzBdLCBscG1hdHJpeCwgc2l6ZW9mKEQzRE1BVFJJWCkpKSB7CiAgICAgICAgVFJBQ0UoIlRoZSBhcHAgaXMgc2V0dGluZyB0aGUgc2FtZSBtYXRyaXggb3ZlciBhZ2FpblxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UgewogICAgICAgIGNvbnZfbWF0KGxwbWF0cml4LCAmVGhpcy0+c3RhdGVCbG9jay0+dHJhbnNmb3Jtc1tkM2R0c10udS5tWzBdWzBdKTsKICAgIH0KCiAgICAvKgogICAgICAgU2NyZWVuQ29vcmQgPSBQcm9qZWN0aW9uTWF0ICogVmlld01hdCAqIFdvcmxkTWF0ICogT2JqZWN0Q29vcmQKICAgICAgIHdoZXJlIFZpZXdNYXQgPSBDYW1lcmEgc3BhY2UsIFdvcmxkTWF0ID0gd29ybGQgc3BhY2UuCgogICAgICAgSW4gT3BlbkdMLCBjYW1lcmEgYW5kIHdvcmxkIHNwYWNlIGlzIGNvbWJpbmVkIGludG8gR0xfTU9ERUxWSUVXCiAgICAgICBtYXRyaXguICBUaGUgUHJvamVjdGlvbiBtYXRyaXggc3RheSBwcm9qZWN0aW9uIG1hdHJpeC4KICAgICAqLwoKICAgIC8qIENhcHR1cmUgdGhlIHRpbWVzIHdlIGNhbiBqdXN0IGlnbm9yZSB0aGUgY2hhbmdlIGZvciBub3cgKi8KICAgIGlmIChkM2R0cyA9PSBEM0RUU19XT1JMRE1BVFJJWCgwKSkgewogICAgICAgIFRoaXMtPm1vZGVsdmlld192YWxpZCA9IEZBTFNFOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwoKICAgIH0gZWxzZSBpZiAoZDNkdHMgPT0gRDNEVFNfUFJPSkVDVElPTikgewogICAgICAgIFRoaXMtPnByb2pfdmFsaWQgPSBGQUxTRTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKCiAgICB9IGVsc2UgaWYgKGQzZHRzID49IEQzRFRTX1dPUkxETUFUUklYKDEpICYmIGQzZHRzIDw9IEQzRFRTX1dPUkxETUFUUklYKDI1NSkpIHsKICAgICAgICAvKiBJbmRleGVkIFZlcnRleCBCbGVuZGluZyBNYXRyaWNlcyAyNTYgLT4gNTExICAqLwogICAgICAgIC8qIFVzZSBhcmJfdmVydGV4X2JsZW5kIG9yIE5WX1ZFUlRFWF9XRUlHSFRJTkc/ICovCiAgICAgICAgRklYTUUoIkQzRFRTX1dPUkxETUFUUklYKDEuLjI1NSkgbm90IGhhbmRsZWRcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIE5vdyB3ZSByZWFsbHkgYXJlIGdvaW5nIHRvIGhhdmUgdG8gY2hhbmdlIGEgbWF0cml4ICovCiAgICBFTlRFUl9HTCgpOwoKICAgIGlmIChkM2R0cyA+PSBEM0RUU19URVhUVVJFMCAmJiBkM2R0cyA8PSBEM0RUU19URVhUVVJFNykgeyAvKiBoYW5kbGUgdGV4dHVyZSBtYXRyaWNlcyAqLwogICAgICAgIC8qIFRoaXMgaXMgbm93IHNldCB3aXRoIHRoZSB0ZXh0dXJlIHVuaXQgc3RhdGVzLCBpdCBtYXkgYmUgYSBnb29kIGlkZWEgdG8gZmxhZyB0aGUgY2hhbmdlIHRob3VnaCEgKi8KICAgIH0gZWxzZSBpZiAoZDNkdHMgPT0gRDNEVFNfVklFVykgeyAvKiBoYW5kbGUgdGhlIFZJRVcgbWF0cmljZSAqLwogICAgICAgIHVuc2lnbmVkIGludCBrOwoKICAgICAgICAvKiBJZiB3ZSBhcmUgY2hhbmdpbmcgdGhlIFZpZXcgbWF0cml4LCByZXNldCB0aGUgbGlnaHQgYW5kIGNsaXBwaW5nIHBsYW5lcyB0byB0aGUgbmV3IHZpZXcKICAgICAgICAgKiBOT1RFOiBXZSBoYXZlIHRvIHJlc2V0IHRoZSBwb3NpdGlvbnMgZXZlbiBpZiB0aGUgbGlnaHQvcGxhbmUgaXMgbm90IGN1cnJlbnRseQogICAgICAgICAqICAgICAgIGVuYWJsZWQsIHNpbmNlIHRoZSBjYWxsIHRvIGVuYWJsZSBpdCB3aWxsIG5vdCByZXNldCB0aGUgcG9zaXRpb24uCiAgICAgICAgICogTk9URTI6IEFwcGFyZW50bHkgdGV4dHVyZSB0cmFuc2Zvcm1zIGRvIE5PVCBuZWVkIHJlYXBwbHlpbmcKICAgICAgICAgKi8KCiAgICAgICAgUExJR0hUSU5GT0VMICpsaWdodENoYWluID0gTlVMTDsKICAgICAgICBUaGlzLT5tb2RlbHZpZXdfdmFsaWQgPSBGQUxTRTsKICAgICAgICBUaGlzLT52aWV3X2lkZW50ID0gIW1lbWNtcChscG1hdHJpeCwgaWRlbnRpdHksIDE2ICogc2l6ZW9mKGZsb2F0KSk7CgogICAgICAgIGdsTWF0cml4TW9kZShHTF9NT0RFTFZJRVcpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbE1hdHJpeE1vZGUoR0xfTU9ERUxWSUVXKSIpOwogICAgICAgIGdsUHVzaE1hdHJpeCgpOwogICAgICAgIGdsTG9hZE1hdHJpeGYoKGZsb2F0ICopbHBtYXRyaXgpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbExvYWRNYXRyaXhmKC4uLikiKTsKCiAgICAgICAgLyogUmVzZXQgbGlnaHRzICovCiAgICAgICAgbGlnaHRDaGFpbiA9IFRoaXMtPnN0YXRlQmxvY2stPmxpZ2h0czsKICAgICAgICB3aGlsZSAobGlnaHRDaGFpbiAmJiBsaWdodENoYWluLT5nbEluZGV4ICE9IC0xKSB7CiAgICAgICAgICAgIGdsTGlnaHRmdihHTF9MSUdIVDAgKyBsaWdodENoYWluLT5nbEluZGV4LCBHTF9QT1NJVElPTiwgbGlnaHRDaGFpbi0+bGlnaHRQb3NuKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsTGlnaHRmdiBwb3NuIik7CiAgICAgICAgICAgIGdsTGlnaHRmdihHTF9MSUdIVDAgKyBsaWdodENoYWluLT5nbEluZGV4LCBHTF9TUE9UX0RJUkVDVElPTiwgbGlnaHRDaGFpbi0+bGlnaHREaXJuKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsTGlnaHRmdiBkaXJuIik7CiAgICAgICAgICAgIGxpZ2h0Q2hhaW4gPSBsaWdodENoYWluLT5uZXh0OwogICAgICAgIH0KCiAgICAgICAgLyogUmVzZXQgQ2xpcHBpbmcgUGxhbmVzIGlmIGNsaXBwaW5nIGlzIGVuYWJsZWQgKi8KICAgICAgICBmb3IgKGsgPSAwOyBrIDwgR0xfTElNSVRTKGNsaXBwbGFuZXMpOyBrKyspIHsKICAgICAgICAgICAgZ2xDbGlwUGxhbmUoR0xfQ0xJUF9QTEFORTAgKyBrLCBUaGlzLT5zdGF0ZUJsb2NrLT5jbGlwcGxhbmVba10pOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xDbGlwUGxhbmUiKTsKICAgICAgICB9CiAgICAgICAgZ2xQb3BNYXRyaXgoKTsKCiAgICB9IGVsc2UgeyAvKiBXaGF0IHdhcyByZXF1ZXN0ZWQhPz8gKi8KICAgICAgICBXQVJOKCJpbnZhbGlkIG1hdHJpeCBzcGVjaWZpZWQ6ICVpXG4iLCBkM2R0cyk7CiAgICB9CgogICAgLyogUmVsZWFzZSBsb2NrLCBhbGwgZG9uZSAqLwogICAgTEVBVkVfR0woKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwoKfQpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VHJhbnNmb3JtKElXaW5lRDNERGV2aWNlICppZmFjZSwgRDNEVFJBTlNGT1JNU1RBVEVUWVBFIFN0YXRlLCBEM0RNQVRSSVgqIHBNYXRyaXgpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogZm9yIFRyYW5zZm9ybSBTdGF0ZSAlZFxuIiwgVGhpcywgU3RhdGUpOwogICAgbWVtY3B5KHBNYXRyaXgsICZUaGlzLT5zdGF0ZUJsb2NrLT50cmFuc2Zvcm1zW1N0YXRlXSwgc2l6ZW9mKEQzRE1BVFJJWCkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9NdWx0aXBseVRyYW5zZm9ybShJV2luZUQzRERldmljZSAqaWZhY2UsIEQzRFRSQU5TRk9STVNUQVRFVFlQRSBTdGF0ZSwgQ09OU1QgRDNETUFUUklYKiBwTWF0cml4KSB7CiAgICBEM0RNQVRSSVggKm1hdCA9IE5VTEw7CiAgICBEM0RNQVRSSVggdGVtcDsKCiAgICAvKiBOb3RlOiBVc2luZyAndXBkYXRlU3RhdGVCbG9jaycgcmF0aGVyIHRoYW4gJ3N0YXRlYmxvY2snIGluIHRoZSBjb2RlCiAgICAgKiBiZWxvdyBtZWFucyBpdCB3aWxsIGJlIHJlY29yZGVkIGluIGEgc3RhdGUgYmxvY2sgY2hhbmdlLCBidXQgaXQKICAgICAqIHdvcmtzIHJlZ2FyZGxlc3Mgd2hlcmUgaXQgaXMgcmVjb3JkZWQuCiAgICAgKiBJZiB0aGlzIGlzIGZvdW5kIHRvIGJlIHdyb25nLCBjaGFuZ2UgdG8gU3RhdGVCbG9jay4KICAgICAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBGb3Igc3RhdGUgJXVcbiIsIFRoaXMsIFN0YXRlKTsKCiAgICBpZiAoU3RhdGUgPCBISUdIRVNUX1RSQU5TRk9STVNUQVRFKQogICAgewogICAgICAgIG1hdCA9ICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50cmFuc2Zvcm1zW1N0YXRlXTsKICAgIH0gZWxzZSB7CiAgICAgICAgRklYTUUoIlVuaGFuZGxlZCB0cmFuc2Zvcm0gc3RhdGUhIVxuIik7CiAgICB9CgogICAgLyogQ29waWVkIGZyb20gZGRyYXcgY29kZTogICovCiAgICB0ZW1wLnUucy5fMTEgPSAobWF0LT51LnMuXzExICogcE1hdHJpeC0+dS5zLl8xMSkgKyAobWF0LT51LnMuXzIxICogcE1hdHJpeC0+dS5zLl8xMikgKwogICAgICAobWF0LT51LnMuXzMxICogcE1hdHJpeC0+dS5zLl8xMykgKyAobWF0LT51LnMuXzQxICogcE1hdHJpeC0+dS5zLl8xNCk7CiAgICB0ZW1wLnUucy5fMjEgPSAobWF0LT51LnMuXzExICogcE1hdHJpeC0+dS5zLl8yMSkgKyAobWF0LT51LnMuXzIxICogcE1hdHJpeC0+dS5zLl8yMikgKwogICAgICAobWF0LT51LnMuXzMxICogcE1hdHJpeC0+dS5zLl8yMykgKyAobWF0LT51LnMuXzQxICogcE1hdHJpeC0+dS5zLl8yNCk7CiAgICB0ZW1wLnUucy5fMzEgPSAobWF0LT51LnMuXzExICogcE1hdHJpeC0+dS5zLl8zMSkgKyAobWF0LT51LnMuXzIxICogcE1hdHJpeC0+dS5zLl8zMikgKwogICAgICAobWF0LT51LnMuXzMxICogcE1hdHJpeC0+dS5zLl8zMykgKyAobWF0LT51LnMuXzQxICogcE1hdHJpeC0+dS5zLl8zNCk7CiAgICB0ZW1wLnUucy5fNDEgPSAobWF0LT51LnMuXzExICogcE1hdHJpeC0+dS5zLl80MSkgKyAobWF0LT51LnMuXzIxICogcE1hdHJpeC0+dS5zLl80MikgKwogICAgICAobWF0LT51LnMuXzMxICogcE1hdHJpeC0+dS5zLl80MykgKyAobWF0LT51LnMuXzQxICogcE1hdHJpeC0+dS5zLl80NCk7CgogICAgdGVtcC51LnMuXzEyID0gKG1hdC0+dS5zLl8xMiAqIHBNYXRyaXgtPnUucy5fMTEpICsgKG1hdC0+dS5zLl8yMiAqIHBNYXRyaXgtPnUucy5fMTIpICsKICAgICAgKG1hdC0+dS5zLl8zMiAqIHBNYXRyaXgtPnUucy5fMTMpICsgKG1hdC0+dS5zLl80MiAqIHBNYXRyaXgtPnUucy5fMTQpOwogICAgdGVtcC51LnMuXzIyID0gKG1hdC0+dS5zLl8xMiAqIHBNYXRyaXgtPnUucy5fMjEpICsgKG1hdC0+dS5zLl8yMiAqIHBNYXRyaXgtPnUucy5fMjIpICsKICAgICAgKG1hdC0+dS5zLl8zMiAqIHBNYXRyaXgtPnUucy5fMjMpICsgKG1hdC0+dS5zLl80MiAqIHBNYXRyaXgtPnUucy5fMjQpOwogICAgdGVtcC51LnMuXzMyID0gKG1hdC0+dS5zLl8xMiAqIHBNYXRyaXgtPnUucy5fMzEpICsgKG1hdC0+dS5zLl8yMiAqIHBNYXRyaXgtPnUucy5fMzIpICsKICAgICAgKG1hdC0+dS5zLl8zMiAqIHBNYXRyaXgtPnUucy5fMzMpICsgKG1hdC0+dS5zLl80MiAqIHBNYXRyaXgtPnUucy5fMzQpOwogICAgdGVtcC51LnMuXzQyID0gKG1hdC0+dS5zLl8xMiAqIHBNYXRyaXgtPnUucy5fNDEpICsgKG1hdC0+dS5zLl8yMiAqIHBNYXRyaXgtPnUucy5fNDIpICsKICAgICAgKG1hdC0+dS5zLl8zMiAqIHBNYXRyaXgtPnUucy5fNDMpICsgKG1hdC0+dS5zLl80MiAqIHBNYXRyaXgtPnUucy5fNDQpOwoKICAgIHRlbXAudS5zLl8xMyA9IChtYXQtPnUucy5fMTMgKiBwTWF0cml4LT51LnMuXzExKSArIChtYXQtPnUucy5fMjMgKiBwTWF0cml4LT51LnMuXzEyKSArCiAgICAgIChtYXQtPnUucy5fMzMgKiBwTWF0cml4LT51LnMuXzEzKSArIChtYXQtPnUucy5fNDMgKiBwTWF0cml4LT51LnMuXzE0KTsKICAgIHRlbXAudS5zLl8yMyA9IChtYXQtPnUucy5fMTMgKiBwTWF0cml4LT51LnMuXzIxKSArIChtYXQtPnUucy5fMjMgKiBwTWF0cml4LT51LnMuXzIyKSArCiAgICAgIChtYXQtPnUucy5fMzMgKiBwTWF0cml4LT51LnMuXzIzKSArIChtYXQtPnUucy5fNDMgKiBwTWF0cml4LT51LnMuXzI0KTsKICAgIHRlbXAudS5zLl8zMyA9IChtYXQtPnUucy5fMTMgKiBwTWF0cml4LT51LnMuXzMxKSArIChtYXQtPnUucy5fMjMgKiBwTWF0cml4LT51LnMuXzMyKSArCiAgICAgIChtYXQtPnUucy5fMzMgKiBwTWF0cml4LT51LnMuXzMzKSArIChtYXQtPnUucy5fNDMgKiBwTWF0cml4LT51LnMuXzM0KTsKICAgIHRlbXAudS5zLl80MyA9IChtYXQtPnUucy5fMTMgKiBwTWF0cml4LT51LnMuXzQxKSArIChtYXQtPnUucy5fMjMgKiBwTWF0cml4LT51LnMuXzQyKSArCiAgICAgIChtYXQtPnUucy5fMzMgKiBwTWF0cml4LT51LnMuXzQzKSArIChtYXQtPnUucy5fNDMgKiBwTWF0cml4LT51LnMuXzQ0KTsKCiAgICB0ZW1wLnUucy5fMTQgPSAobWF0LT51LnMuXzE0ICogcE1hdHJpeC0+dS5zLl8xMSkgKyAobWF0LT51LnMuXzI0ICogcE1hdHJpeC0+dS5zLl8xMikgKwogICAgICAobWF0LT51LnMuXzM0ICogcE1hdHJpeC0+dS5zLl8xMykgKyAobWF0LT51LnMuXzQ0ICogcE1hdHJpeC0+dS5zLl8xNCk7CiAgICB0ZW1wLnUucy5fMjQgPSAobWF0LT51LnMuXzE0ICogcE1hdHJpeC0+dS5zLl8yMSkgKyAobWF0LT51LnMuXzI0ICogcE1hdHJpeC0+dS5zLl8yMikgKwogICAgICAobWF0LT51LnMuXzM0ICogcE1hdHJpeC0+dS5zLl8yMykgKyAobWF0LT51LnMuXzQ0ICogcE1hdHJpeC0+dS5zLl8yNCk7CiAgICB0ZW1wLnUucy5fMzQgPSAobWF0LT51LnMuXzE0ICogcE1hdHJpeC0+dS5zLl8zMSkgKyAobWF0LT51LnMuXzI0ICogcE1hdHJpeC0+dS5zLl8zMikgKwogICAgICAobWF0LT51LnMuXzM0ICogcE1hdHJpeC0+dS5zLl8zMykgKyAobWF0LT51LnMuXzQ0ICogcE1hdHJpeC0+dS5zLl8zNCk7CiAgICB0ZW1wLnUucy5fNDQgPSAobWF0LT51LnMuXzE0ICogcE1hdHJpeC0+dS5zLl80MSkgKyAobWF0LT51LnMuXzI0ICogcE1hdHJpeC0+dS5zLl80MikgKwogICAgICAobWF0LT51LnMuXzM0ICogcE1hdHJpeC0+dS5zLl80MykgKyAobWF0LT51LnMuXzQ0ICogcE1hdHJpeC0+dS5zLl80NCk7CgogICAgLyogQXBwbHkgY2hhbmdlIHZpYSBzZXQgdHJhbnNmb3JtIC0gd2lsbCByZWFwcGx5IHRvIGVnLiBsaWdodHMgdGhpcyB3YXkgKi8KICAgIHJldHVybiBJV2luZUQzRERldmljZUltcGxfU2V0VHJhbnNmb3JtKGlmYWNlLCBTdGF0ZSwgJnRlbXApOwp9CgovKioqKioKICogR2V0IC8gU2V0IExpZ2h0CiAqICAgV0FSTklORzogVGhpcyBjb2RlIHJlbGllcyBvbiB0aGUgZmFjdCB0aGF0IEQzRExJR0hUOCA9PSBEM0RMSUdIVDkKICoqKioqLwovKiBOb3RlIGxpZ2h0cyBhcmUgcmVhbCBzcGVjaWFsIGNhc2VzLiBBbHRob3VnaCB0aGUgZGV2aWNlIGNhcHMgc3RhdGUgb25seSBlZy4gOCBhcmUgc3VwcG9ydGVkLAogICB5b3UgY2FuIHJlZmVyZW5jZSBhbnkgaW5kZXhlcyB5b3Ugd2FudCBhcyBsb25nIGFzIHRoYXQgbnVtYmVyIG1heCBhcmUgZW5hYmxlZCBhdCBhbnkKICAgb25lIHBvaW50IGluIHRpbWUhIFRoZXJlZm9yZSBzaW5jZSB0aGUgaW5kZXhlcyBjYW4gYmUgYW55dGhpbmcsIHdlIG5lZWQgYSBsaW5rZWQgbGlzdCBvZiB0aGVtLgogICBIb3dldmVyLCB0aGlzIGNhdXNlcyBzdGF0ZWJsb2NrIHByb2JsZW1zLiBXaGVuIGNhcHR1cmluZyB0aGUgc3RhdGUgYmxvY2ssIEkgZHVwbGljYXRlIHRoZSBsaXN0LAogICBidXQgd2hlbiByZWNvcmRpbmcsIGp1c3QgYnVpbGQgYSBjaGFpbiBwcmV0dHkgbXVjaCBvZiBjb21tYW5kcyB0byBiZSByZXBsYXllZC4gICAgICAgICAgICAgICAgICAqLwoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldExpZ2h0KElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgSW5kZXgsIENPTlNUIFdJTkVEM0RMSUdIVCogcExpZ2h0KSB7CiAgICBmbG9hdCByaG87CiAgICBQTElHSFRJTkZPRUwgKm9iamVjdCwgKnRlbXA7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBJZHgoJWxkKSwgcExpZ2h0KCVwKVxuIiwgVGhpcywgSW5kZXgsIHBMaWdodCk7CgogICAgLyogSWYgcmVjb3JkaW5nIHN0YXRlIGJsb2NrLCBqdXN0IGFkZCB0byBlbmQgb2YgbGlnaHRzIGNoYWluICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUExJR0hUSU5GT0VMKSk7CiAgICAgICAgaWYgKE5VTEwgPT0gb2JqZWN0KSB7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX09VVE9GVklERU9NRU1PUlk7CiAgICAgICAgfQogICAgICAgIG1lbWNweSgmb2JqZWN0LT5PcmlnaW5hbFBhcm1zLCBwTGlnaHQsIHNpemVvZihEM0RMSUdIVDkpKTsKICAgICAgICBvYmplY3QtPk9yaWdpbmFsSW5kZXggPSBJbmRleDsKICAgICAgICBvYmplY3QtPmdsSW5kZXggPSAtMTsKICAgICAgICBvYmplY3QtPmNoYW5nZWQgPSBUUlVFOwoKICAgICAgICAvKiBBZGQgdG8gdGhlIEVORCBvZiB0aGUgY2hhaW4gb2YgbGlnaHRzIGNoYW5nZXMgdG8gYmUgcmVwbGF5ZWQgKi8KICAgICAgICBpZiAoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bGlnaHRzID09IE5VTEwpIHsKICAgICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bGlnaHRzID0gb2JqZWN0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRlbXAgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5saWdodHM7CiAgICAgICAgICAgIHdoaWxlICh0ZW1wLT5uZXh0ICE9IE5VTEwpIHRlbXA9dGVtcC0+bmV4dDsKICAgICAgICAgICAgdGVtcC0+bmV4dCA9IG9iamVjdDsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZyBtb3JlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICAvKiBPaywgbm90IHJlY29yZGluZyBhbnkgbG9uZ2VyIHNvIGRvIHJlYWwgd29yayAqLwogICAgb2JqZWN0ID0gVGhpcy0+c3RhdGVCbG9jay0+bGlnaHRzOwogICAgd2hpbGUgKG9iamVjdCAhPSBOVUxMICYmIG9iamVjdC0+T3JpZ2luYWxJbmRleCAhPSBJbmRleCkgb2JqZWN0ID0gb2JqZWN0LT5uZXh0OwoKICAgIC8qIElmIHdlIGRpZG4ndCBmaW5kIGl0IGluIHRoZSBsaXN0IG9mIGxpZ2h0cywgdGltZSB0byBhZGQgaXQgKi8KICAgIGlmIChvYmplY3QgPT0gTlVMTCkgewogICAgICAgIFBMSUdIVElORk9FTCAqaW5zZXJ0QXQsKnByZXZQb3M7CgogICAgICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUExJR0hUSU5GT0VMKSk7CiAgICAgICAgaWYgKE5VTEwgPT0gb2JqZWN0KSB7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX09VVE9GVklERU9NRU1PUlk7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+T3JpZ2luYWxJbmRleCA9IEluZGV4OwogICAgICAgIG9iamVjdC0+Z2xJbmRleCA9IC0xOwoKICAgICAgICAvKiBBZGQgaXQgdG8gdGhlIGZyb250IG9mIGxpc3Qgd2l0aCB0aGUgaWRlYSB0aGF0IGxpZ2h0cyB3aWxsIGJlIGNoYW5nZWQgYXMgbmVlZGVkCiAgICAgICAgICAgQlVUIGFmdGVyIGFueSBsaWdodHMgY3VycmVudGx5IGFzc2lnbmVkIEdMIGluZGV4ZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgaW5zZXJ0QXQgPSBUaGlzLT5zdGF0ZUJsb2NrLT5saWdodHM7CiAgICAgICAgcHJldlBvcyAgPSBOVUxMOwogICAgICAgIHdoaWxlIChpbnNlcnRBdCAhPSBOVUxMICYmIGluc2VydEF0LT5nbEluZGV4ICE9IC0xKSB7CiAgICAgICAgICAgIHByZXZQb3MgID0gaW5zZXJ0QXQ7CiAgICAgICAgICAgIGluc2VydEF0ID0gaW5zZXJ0QXQtPm5leHQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoaW5zZXJ0QXQgPT0gTlVMTCAmJiBwcmV2UG9zID09IE5VTEwpIHsgLyogU3RhcnQgb2YgbGlzdCAqLwogICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5saWdodHMgPSBvYmplY3Q7CiAgICAgICAgfSBlbHNlIGlmIChpbnNlcnRBdCA9PSBOVUxMKSB7IC8qIEVuZCBvZiBsaXN0ICovCiAgICAgICAgICAgIHByZXZQb3MtPm5leHQgPSBvYmplY3Q7CiAgICAgICAgICAgIG9iamVjdC0+cHJldiA9IHByZXZQb3M7CiAgICAgICAgfSBlbHNlIHsgLyogTWlkZGxlIG9mIGNoYWluICovCiAgICAgICAgICAgIGlmIChwcmV2UG9zID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPmxpZ2h0cyA9IG9iamVjdDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHByZXZQb3MtPm5leHQgPSBvYmplY3Q7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb2JqZWN0LT5wcmV2ID0gcHJldlBvczsKICAgICAgICAgICAgb2JqZWN0LT5uZXh0ID0gaW5zZXJ0QXQ7CiAgICAgICAgICAgIGluc2VydEF0LT5wcmV2ID0gb2JqZWN0OwogICAgICAgIH0KICAgIH0KCiAgICAvKiBJbml0aWFsaXplIHRoZSBvYmplY3QgKi8KICAgIFRSQUNFKCJMaWdodCAlbGQgc2V0dGluZyB0byB0eXBlICVkLCBEaWZmdXNlKCVmLCVmLCVmLCVmKSwgU3BlY3VsYXIoJWYsJWYsJWYsJWYpLCBBbWJpZW50KCVmLCVmLCVmLCVmKVxuIiwgSW5kZXgsIHBMaWdodC0+VHlwZSwKICAgICAgICAgIHBMaWdodC0+RGlmZnVzZS5yLCBwTGlnaHQtPkRpZmZ1c2UuZywgcExpZ2h0LT5EaWZmdXNlLmIsIHBMaWdodC0+RGlmZnVzZS5hLAogICAgICAgICAgcExpZ2h0LT5TcGVjdWxhci5yLCBwTGlnaHQtPlNwZWN1bGFyLmcsIHBMaWdodC0+U3BlY3VsYXIuYiwgcExpZ2h0LT5TcGVjdWxhci5hLAogICAgICAgICAgcExpZ2h0LT5BbWJpZW50LnIsIHBMaWdodC0+QW1iaWVudC5nLCBwTGlnaHQtPkFtYmllbnQuYiwgcExpZ2h0LT5BbWJpZW50LmEpOwogICAgVFJBQ0UoIi4uLiBQb3MoJWYsJWYsJWYpLCBEaXJuKCVmLCVmLCVmKVxuIiwgcExpZ2h0LT5Qb3NpdGlvbi54LCBwTGlnaHQtPlBvc2l0aW9uLnksIHBMaWdodC0+UG9zaXRpb24ueiwKICAgICAgICAgIHBMaWdodC0+RGlyZWN0aW9uLngsIHBMaWdodC0+RGlyZWN0aW9uLnksIHBMaWdodC0+RGlyZWN0aW9uLnopOwogICAgVFJBQ0UoIi4uLiBSYW5nZSglZiksIEZhbGxvZmYoJWYpLCBUaGV0YSglZiksIFBoaSglZilcbiIsIHBMaWdodC0+UmFuZ2UsIHBMaWdodC0+RmFsbG9mZiwgcExpZ2h0LT5UaGV0YSwgcExpZ2h0LT5QaGkpOwoKICAgIC8qIFNhdmUgYXdheSB0aGUgaW5mb3JtYXRpb24gKi8KICAgIG1lbWNweSgmb2JqZWN0LT5PcmlnaW5hbFBhcm1zLCBwTGlnaHQsIHNpemVvZihEM0RMSUdIVDkpKTsKCiAgICBzd2l0Y2ggKHBMaWdodC0+VHlwZSkgewogICAgY2FzZSBEM0RMSUdIVF9QT0lOVDoKICAgICAgICAvKiBQb3NpdGlvbiAqLwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzBdID0gcExpZ2h0LT5Qb3NpdGlvbi54OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzFdID0gcExpZ2h0LT5Qb3NpdGlvbi55OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzJdID0gcExpZ2h0LT5Qb3NpdGlvbi56OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzNdID0gMS4wZjsKICAgICAgICBvYmplY3QtPmN1dG9mZiA9IDE4MC4wZjsKICAgICAgICAvKiBGSVhNRTogUmFuZ2UgKi8KICAgICAgICBicmVhazsKCiAgICBjYXNlIEQzRExJR0hUX0RJUkVDVElPTkFMOgogICAgICAgIC8qIERpcmVjdGlvbiAqLwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzBdID0gLXBMaWdodC0+RGlyZWN0aW9uLng7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMV0gPSAtcExpZ2h0LT5EaXJlY3Rpb24ueTsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblsyXSA9IC1wTGlnaHQtPkRpcmVjdGlvbi56OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzNdID0gMC4wOwogICAgICAgIG9iamVjdC0+ZXhwb25lbnQgICAgID0gMC4wZjsKICAgICAgICBvYmplY3QtPmN1dG9mZiAgICAgICA9IDE4MC4wZjsKICAgICAgICBicmVhazsKCiAgICBjYXNlIEQzRExJR0hUX1NQT1Q6CiAgICAgICAgLyogUG9zaXRpb24gKi8KICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblswXSA9IHBMaWdodC0+UG9zaXRpb24ueDsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblsxXSA9IHBMaWdodC0+UG9zaXRpb24ueTsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblsyXSA9IHBMaWdodC0+UG9zaXRpb24uejsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblszXSA9IDEuMDsKCiAgICAgICAgLyogRGlyZWN0aW9uICovCiAgICAgICAgb2JqZWN0LT5saWdodERpcm5bMF0gPSBwTGlnaHQtPkRpcmVjdGlvbi54OwogICAgICAgIG9iamVjdC0+bGlnaHREaXJuWzFdID0gcExpZ2h0LT5EaXJlY3Rpb24ueTsKICAgICAgICBvYmplY3QtPmxpZ2h0RGlyblsyXSA9IHBMaWdodC0+RGlyZWN0aW9uLno7CiAgICAgICAgb2JqZWN0LT5saWdodERpcm5bM10gPSAxLjA7CgogICAgICAgIC8qCiAgICAgICAgICogb3BlbmdsLWlzaCBhbmQgZDNkLWlzaCBzcG90IGxpZ2h0cyB1c2UgdG9vIGRpZmZlcmVudCBtb2RlbHMgZm9yIHRoZQogICAgICAgICAqIGxpZ2h0ICJpbnRlbnNpdHkiIGFzIGEgZnVuY3Rpb24gb2YgdGhlIGFuZ2xlIHRvd2FyZHMgdGhlIG1haW4gbGlnaHQgZGlyZWN0aW9uLAogICAgICAgICAqIHNvIHdlIG9ubHkgY2FuIGFwcHJveGltYXRlIHZlcnkgcm91Z2hseS4KICAgICAgICAgKiBob3dldmVyIHNwb3QgbGlnaHRzIGFyZSByYXRoZXIgcmFyZWx5IHVzZWQgaW4gZ2FtZXMgKGlmIGV2ZXIgdXNlZCBhdCBhbGwpLgogICAgICAgICAqIGZ1cnRoZXJtb3JlIGlmIHN0aWxsIHVzZWQsIHByb2JhYmx5IG5vYm9keSBwYXlzIGF0dGVudGlvbiB0byBzdWNoIGRldGFpbHMuCiAgICAgICAgICovCiAgICAgICAgaWYgKHBMaWdodC0+RmFsbG9mZiA9PSAwKSB7CiAgICAgICAgICAgIHJobyA9IDYuMjhmOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJobyA9IHBMaWdodC0+VGhldGEgKyAocExpZ2h0LT5QaGkgLSBwTGlnaHQtPlRoZXRhKS8oMipwTGlnaHQtPkZhbGxvZmYpOwogICAgICAgIH0KICAgICAgICBpZiAocmhvIDwgMC4wMDAxKSByaG8gPSAwLjAwMDFmOwogICAgICAgIG9iamVjdC0+ZXhwb25lbnQgPSAtMC4zL2xvZyhjb3MocmhvLzIpKTsKICAgICAgICBvYmplY3QtPmN1dG9mZiA9IHBMaWdodC0+UGhpKjkwL01fUEk7CgogICAgICAgIC8qIEZJWE1FOiBSYW5nZSAqLwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIlVucmVjb2duaXplZCBsaWdodCB0eXBlICVkXG4iLCBwTGlnaHQtPlR5cGUpOwogICAgfQoKICAgIC8qIFVwZGF0ZSB0aGUgbGl2ZSBkZWZpbml0aW9ucyBpZiB0aGUgbGlnaHQgaXMgY3VycmVudGx5IGFzc2lnbmVkIGEgZ2xJbmRleCAqLwogICAgaWYgKG9iamVjdC0+Z2xJbmRleCAhPSAtMSkgewogICAgICAgIHNldHVwX2xpZ2h0KGlmYWNlLCBvYmplY3QtPmdsSW5kZXgsIG9iamVjdCk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldExpZ2h0KElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgSW5kZXgsIFdJTkVEM0RMSUdIVCogcExpZ2h0KSB7CiAgICBQTElHSFRJTkZPRUwgKmxpZ2h0SW5mbyA9IE5VTEw7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IElkeCglbGQpLCBwTGlnaHQoJXApXG4iLCBUaGlzLCBJbmRleCwgcExpZ2h0KTsKCiAgICAvKiBMb2NhdGUgdGhlIGxpZ2h0IGluIHRoZSBsaXZlIGxpZ2h0cyAqLwogICAgbGlnaHRJbmZvID0gVGhpcy0+c3RhdGVCbG9jay0+bGlnaHRzOwogICAgd2hpbGUgKGxpZ2h0SW5mbyAhPSBOVUxMICYmIGxpZ2h0SW5mby0+T3JpZ2luYWxJbmRleCAhPSBJbmRleCkgbGlnaHRJbmZvID0gbGlnaHRJbmZvLT5uZXh0OwoKICAgIGlmIChsaWdodEluZm8gPT0gTlVMTCkgewogICAgICAgIFRSQUNFKCJMaWdodCBpbmZvcm1hdGlvbiByZXF1ZXN0ZWQgYnV0IGxpZ2h0IG5vdCBkZWZpbmVkXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBtZW1jcHkocExpZ2h0LCAmbGlnaHRJbmZvLT5PcmlnaW5hbFBhcm1zLCBzaXplb2YoRDNETElHSFQ5KSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBMaWdodCBFbmFibGUKICogICAoTm90ZSBmb3IgY29uc2lzdGVuY3ksIHJlbmFtZWQgZDNkeCBmdW5jdGlvbiBieSBhZGRpbmcgdGhlICdzZXQnIHByZWZpeCkKICoqKioqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0TGlnaHRFbmFibGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBJbmRleCwgQk9PTCBFbmFibGUpIHsKICAgIFBMSUdIVElORk9FTCAqbGlnaHRJbmZvID0gTlVMTDsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogSWR4KCVsZCksIGVuYWJsZT8gJWRcbiIsIFRoaXMsIEluZGV4LCBFbmFibGUpOwoKICAgIC8qIElmIHJlY29yZGluZyBzdGF0ZSBibG9jaywganVzdCBhZGQgdG8gZW5kIG9mIGxpZ2h0cyBjaGFpbiB3aXRoIGNoYW5nZWRFbmFibGUgc2V0IHRvIHRydWUgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgbGlnaHRJbmZvID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihQTElHSFRJTkZPRUwpKTsKICAgICAgICBpZiAoTlVMTCA9PSBsaWdodEluZm8pIHsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfT1VUT0ZWSURFT01FTU9SWTsKICAgICAgICB9CiAgICAgICAgbGlnaHRJbmZvLT5PcmlnaW5hbEluZGV4ID0gSW5kZXg7CiAgICAgICAgbGlnaHRJbmZvLT5nbEluZGV4ID0gLTE7CiAgICAgICAgbGlnaHRJbmZvLT5lbmFibGVkQ2hhbmdlZCA9IFRSVUU7CgogICAgICAgIC8qIEFkZCB0byB0aGUgRU5EIG9mIHRoZSBjaGFpbiBvZiBsaWdodHMgY2hhbmdlcyB0byBiZSByZXBsYXllZCAqLwogICAgICAgIGlmIChUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5saWdodHMgPT0gTlVMTCkgewogICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5saWdodHMgPSBsaWdodEluZm87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUExJR0hUSU5GT0VMICp0ZW1wID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bGlnaHRzOwogICAgICAgICAgICB3aGlsZSAodGVtcC0+bmV4dCAhPSBOVUxMKSB0ZW1wPXRlbXAtPm5leHQ7CiAgICAgICAgICAgIHRlbXAtPm5leHQgPSBsaWdodEluZm87CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmcgbW9yZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgLyogTm90IHJlY29yZGluZy4uLiBTbywgbG9jYXRlIHRoZSBsaWdodCBpbiB0aGUgbGl2ZSBsaWdodHMgKi8KICAgIGxpZ2h0SW5mbyA9IFRoaXMtPnN0YXRlQmxvY2stPmxpZ2h0czsKICAgIHdoaWxlIChsaWdodEluZm8gIT0gTlVMTCAmJiBsaWdodEluZm8tPk9yaWdpbmFsSW5kZXggIT0gSW5kZXgpIGxpZ2h0SW5mbyA9IGxpZ2h0SW5mby0+bmV4dDsKCiAgICAvKiBTcGVjaWFsIGNhc2UgLSBlbmFibGluZyBhbiB1bmRlZmluZWQgbGlnaHQgY3JlYXRlcyBvbmUgd2l0aCBhIHN0cmljdCBzZXQgb2YgcGFybXMhICovCiAgICBpZiAobGlnaHRJbmZvID09IE5VTEwpIHsKICAgICAgICBEM0RMSUdIVDkgbGlnaHRQYXJtczsKICAgICAgICAvKiBXYXJuaW5nIC0gdW50ZXN0ZWQgY29kZSA6LSkgUHJvYiBzYWZlIHRvIGNoYW5nZSBmaXhtZSB0byBhIHRyYWNlIGJ1dAogICAgICAgICAgICAgd2FpdCB1bnRpbCBzb21lb25lIGNvbmZpcm1zIGl0IHNlZW1zIHRvIHdvcmshICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICBUUkFDRSgiTGlnaHQgZW5hYmxlZCByZXF1ZXN0ZWQgYnV0IGxpZ2h0IG5vdCBkZWZpbmVkLCBzbyBkZWZpbmluZyBvbmUhXG4iKTsKICAgICAgICBsaWdodFBhcm1zLlR5cGUgICAgICAgICA9IEQzRExJR0hUX0RJUkVDVElPTkFMOwogICAgICAgIGxpZ2h0UGFybXMuRGlmZnVzZS5yICAgID0gMS4wOwogICAgICAgIGxpZ2h0UGFybXMuRGlmZnVzZS5nICAgID0gMS4wOwogICAgICAgIGxpZ2h0UGFybXMuRGlmZnVzZS5iICAgID0gMS4wOwogICAgICAgIGxpZ2h0UGFybXMuRGlmZnVzZS5hICAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuU3BlY3VsYXIuciAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuU3BlY3VsYXIuZyAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuU3BlY3VsYXIuYiAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuU3BlY3VsYXIuYSAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuQW1iaWVudC5yICAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuQW1iaWVudC5nICAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuQW1iaWVudC5iICAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuQW1iaWVudC5hICAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuUG9zaXRpb24ueCAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuUG9zaXRpb24ueSAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuUG9zaXRpb24ueiAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuRGlyZWN0aW9uLnggID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuRGlyZWN0aW9uLnkgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuRGlyZWN0aW9uLnogID0gMS4wOwogICAgICAgIGxpZ2h0UGFybXMuUmFuZ2UgICAgICAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuRmFsbG9mZiAgICAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuQXR0ZW51YXRpb24wID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuQXR0ZW51YXRpb24xID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuQXR0ZW51YXRpb24yID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuVGhldGEgICAgICAgID0gMC4wOwogICAgICAgIGxpZ2h0UGFybXMuUGhpICAgICAgICAgID0gMC4wOwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRMaWdodChpZmFjZSwgSW5kZXgsICZsaWdodFBhcm1zKTsKCiAgICAgICAgLyogU2VhcmNoIGZvciBpdCBhZ2FpbiEgU2hvdWxkIGJlIGZhaXJseSBxdWljayBhcyBuZWFyIGhlYWQgb2YgbGlzdCAqLwogICAgICAgIGxpZ2h0SW5mbyA9IFRoaXMtPnN0YXRlQmxvY2stPmxpZ2h0czsKICAgICAgICB3aGlsZSAobGlnaHRJbmZvICE9IE5VTEwgJiYgbGlnaHRJbmZvLT5PcmlnaW5hbEluZGV4ICE9IEluZGV4KSBsaWdodEluZm8gPSBsaWdodEluZm8tPm5leHQ7CiAgICAgICAgaWYgKGxpZ2h0SW5mbyA9PSBOVUxMKSB7CiAgICAgICAgICAgIEZJWE1FKCJBZGRpbmcgZGVmYXVsdCBsaWdodHMgaGFzIGZhaWxlZCBkaXNtYWxseVxuIik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBPSywgd2Ugbm93IGhhdmUgYSBsaWdodC4uLiAqLwogICAgaWYgKEVuYWJsZSA9PSBGQUxTRSkgewoKICAgICAgICAvKiBJZiB3ZSBhcmUgZGlzYWJsaW5nIGl0LCBjaGVjayBpdCB3YXMgZW5hYmxlZCwgYW5kCiAgICAgICAgICAgc3RpbGwgb25seSBkbyBzb21ldGhpbmcgaWYgaXQgaGFzIGFzc2lnbmVkIGEgZ2xJbmRleCAod2hpY2ggaXQgc2hvdWxkIGhhdmUhKSAgICovCiAgICAgICAgaWYgKChsaWdodEluZm8tPmxpZ2h0RW5hYmxlZCkgJiYgKGxpZ2h0SW5mby0+Z2xJbmRleCAhPSAtMSkpIHsKICAgICAgICAgICAgVFJBQ0UoIkRpc2FibGluZyBsaWdodCBzZXQgdXAgYXQgZ2wgaWR4ICVsZFxuIiwgbGlnaHRJbmZvLT5nbEluZGV4KTsKICAgICAgICAgICAgRU5URVJfR0woKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0xJR0hUMCArIGxpZ2h0SW5mby0+Z2xJbmRleCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfTElHSFQwK0luZGV4Iik7CiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVFJBQ0UoIk5vdGhpbmcgdG8gZG8gYXMgbGlnaHQgd2FzIG5vdCBlbmFibGVkXG4iKTsKICAgICAgICB9CiAgICAgICAgbGlnaHRJbmZvLT5saWdodEVuYWJsZWQgPSBGQUxTRTsKICAgIH0gZWxzZSB7CgogICAgICAgIC8qIFdlIGFyZSBlbmFibGluZyBpdC4gSWYgaXQgaXMgZW5hYmxlZCwgaXQncyByZWFsbHkgc2ltcGxlICovCiAgICAgICAgaWYgKGxpZ2h0SW5mby0+bGlnaHRFbmFibGVkKSB7CiAgICAgICAgICAgIC8qIG5vcCAqLwogICAgICAgICAgICBUUkFDRSgiTm90aGluZyB0byBkbyBhcyBsaWdodCB3YXMgZW5hYmxlZFxuIik7CgogICAgICAgIC8qIElmIGl0IGFscmVhZHkgaGFzIGEgZ2xJbmRleCwgaXQncyBzdGlsbCBzaW1wbGUgKi8KICAgICAgICB9IGVsc2UgaWYgKGxpZ2h0SW5mby0+Z2xJbmRleCAhPSAtMSkgewogICAgICAgICAgICBUUkFDRSgiUmV1c2luZyBsaWdodCBhcyBhbHJlYWR5IHNldCB1cCBhdCBnbCBpZHggJWxkXG4iLCBsaWdodEluZm8tPmdsSW5kZXgpOwogICAgICAgICAgICBsaWdodEluZm8tPmxpZ2h0RW5hYmxlZCA9IFRSVUU7CiAgICAgICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgICAgIGdsRW5hYmxlKEdMX0xJR0hUMCArIGxpZ2h0SW5mby0+Z2xJbmRleCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9MSUdIVDArSW5kZXggYWxyZWFkeSBzZXR1cCIpOwogICAgICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAvKiBPdGhlcndpc2UgZ290IHRvIGZpbmQgc3BhY2UgLSBsaWdodHMgYXJlIG9yZGVyZWQgZ2wgaW5kZXhlcyBmaXJzdCAqLwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFBMSUdIVElORk9FTCAqYnNmICA9IE5VTEw7CiAgICAgICAgICAgIFBMSUdIVElORk9FTCAqcG9zICA9IFRoaXMtPnN0YXRlQmxvY2stPmxpZ2h0czsKICAgICAgICAgICAgUExJR0hUSU5GT0VMICpwcmV2ID0gTlVMTDsKICAgICAgICAgICAgaW50ICAgICAgICAgICBJbmRleD0gMDsKICAgICAgICAgICAgaW50ICAgICAgICAgICBnbEluZGV4ID0gLTE7CgogICAgICAgICAgICAvKiBUcnkgdG8gbWluaW1pemUgY2hhbmdlcyBhcyBtdWNoIGFzIHBvc3NpYmxlICovCiAgICAgICAgICAgIHdoaWxlIChwb3MgIT0gTlVMTCAmJiBwb3MtPmdsSW5kZXggIT0gLTEgJiYgSW5kZXggPCBUaGlzLT5tYXhDb25jdXJyZW50TGlnaHRzKSB7CgogICAgICAgICAgICAgICAgLyogVHJ5IHRvIHJlbWVtYmVyIHdoaWNoIGluZGV4IGNhbiBiZSByZXBsYWNlZCBpZiBuZWNlc3NhcnkgKi8KICAgICAgICAgICAgICAgIGlmIChic2Y9PU5VTEwgJiYgcG9zLT5saWdodEVuYWJsZWQgPT0gRkFMU0UpIHsKICAgICAgICAgICAgICAgICAgICAvKiBGb3VuZCBhIGxpZ2h0IHdlIGNhbiByZXBsYWNlLCBzYXZlIGFzIGJlc3QgcmVwbGFjZW1lbnQgKi8KICAgICAgICAgICAgICAgICAgICBic2YgPSBwb3M7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLyogU3RlcCB0byBuZXh0IHNwYWNlICovCiAgICAgICAgICAgICAgICBwcmV2ID0gcG9zOwogICAgICAgICAgICAgICAgcG9zID0gcG9zLT5uZXh0OwogICAgICAgICAgICAgICAgSW5kZXggKys7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIElmIHdlIGhhdmUgdG9vIG1hbnkgYWN0aXZlIGxpZ2h0cywgZmFpbCB0aGUgY2FsbCAqLwogICAgICAgICAgICBpZiAoKEluZGV4ID09IFRoaXMtPm1heENvbmN1cnJlbnRMaWdodHMpICYmIChic2YgPT0gTlVMTCkpIHsKICAgICAgICAgICAgICAgIEZJWE1FKCJQcm9ncmFtIHJlcXVlc3RzIHRvbyBtYW55IGNvbmN1cnJlbnQgbGlnaHRzXG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgICAgICAgICAgLyogSWYgd2UgaGF2ZSBhbGxvY2F0ZWQgYWxsIGxpZ2h0cywgYnV0IG5vdCBhbGwgYXJlIGVuYWJsZWQsCiAgICAgICAgICAgICAgIHJldXNlIG9uZSB3aGljaCBpcyBub3QgZW5hYmxlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgIH0gZWxzZSBpZiAoSW5kZXggPT0gVGhpcy0+bWF4Q29uY3VycmVudExpZ2h0cykgewogICAgICAgICAgICAgICAgLyogdXNlIGJzZiAtIFNpbXBseSBzd2FwIHRoZSBuZXcgbGlnaHQgYW5kIHRoZSBCU0Ygb25lICovCiAgICAgICAgICAgICAgICBQTElHSFRJTkZPRUwgKmJzZk5leHQgPSBic2YtPm5leHQ7CiAgICAgICAgICAgICAgICBQTElHSFRJTkZPRUwgKmJzZlByZXYgPSBic2YtPnByZXY7CgogICAgICAgICAgICAgICAgLyogU29ydCBvdXQgZW5kcyAqLwogICAgICAgICAgICAgICAgaWYgKGxpZ2h0SW5mby0+bmV4dCAhPSBOVUxMKSBsaWdodEluZm8tPm5leHQtPnByZXYgPSBic2Y7CiAgICAgICAgICAgICAgICBpZiAoYnNmLT5wcmV2ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBic2YtPnByZXYtPm5leHQgPSBsaWdodEluZm87CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPmxpZ2h0cyA9IGxpZ2h0SW5mbzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKiBJZiBub3Qgc2lkZSBieSBzaWRlLCBsb3RzIG9mIGNoYWlucyB0byB1cGRhdGUgKi8KICAgICAgICAgICAgICAgIGlmIChic2YtPm5leHQgIT0gbGlnaHRJbmZvKSB7CiAgICAgICAgICAgICAgICAgICAgbGlnaHRJbmZvLT5wcmV2LT5uZXh0ID0gYnNmOwogICAgICAgICAgICAgICAgICAgIGJzZi0+bmV4dC0+cHJldiA9IGxpZ2h0SW5mbzsKICAgICAgICAgICAgICAgICAgICBic2YtPm5leHQgICAgICAgPSBsaWdodEluZm8tPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgYnNmLT5wcmV2ICAgICAgID0gbGlnaHRJbmZvLT5wcmV2OwogICAgICAgICAgICAgICAgICAgIGxpZ2h0SW5mby0+bmV4dCA9IGJzZk5leHQ7CiAgICAgICAgICAgICAgICAgICAgbGlnaHRJbmZvLT5wcmV2ID0gYnNmUHJldjsKCiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qIFNpbXBsZSBzd2FwcyAqLwogICAgICAgICAgICAgICAgICAgIGJzZi0+cHJldiA9IGxpZ2h0SW5mbzsKICAgICAgICAgICAgICAgICAgICBic2YtPm5leHQgPSBsaWdodEluZm8tPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgbGlnaHRJbmZvLT5uZXh0ID0gYnNmOwogICAgICAgICAgICAgICAgICAgIGxpZ2h0SW5mby0+cHJldiA9IGJzZlByZXY7CiAgICAgICAgICAgICAgICB9CgoKICAgICAgICAgICAgICAgIC8qIFVwZGF0ZSBzdGF0ZXMgKi8KICAgICAgICAgICAgICAgIGdsSW5kZXggPSBic2YtPmdsSW5kZXg7CiAgICAgICAgICAgICAgICBic2YtPmdsSW5kZXggPSAtMTsKICAgICAgICAgICAgICAgIGxpZ2h0SW5mby0+Z2xJbmRleCA9IGdsSW5kZXg7CiAgICAgICAgICAgICAgICBsaWdodEluZm8tPmxpZ2h0RW5hYmxlZCA9IFRSVUU7CgogICAgICAgICAgICAgICAgLyogRmluYWxseSBzZXQgdXAgdGhlIGxpZ2h0IGluIGdsIGl0c2VsZiAqLwogICAgICAgICAgICAgICAgVFJBQ0UoIlJlcGxhY2luZyBsaWdodCB3aGljaCB3YXMgc2V0IHVwIGF0IGdsIGlkeCAlbGRcbiIsIGxpZ2h0SW5mby0+Z2xJbmRleCk7CiAgICAgICAgICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgICAgICAgICAgc2V0dXBfbGlnaHQoaWZhY2UsIGdsSW5kZXgsIGxpZ2h0SW5mbyk7CiAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9MSUdIVDAgKyBnbEluZGV4KTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9MSUdIVDAgbmV3IHNldHVwIik7CiAgICAgICAgICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAgICAgLyogSWYgd2UgcmVhY2hlZCB0aGUgZW5kIG9mIHRoZSBhbGxvY2F0ZWQgbGlnaHRzLCB3aXRoIHNwYWNlIGluIHRoZQogICAgICAgICAgICAgICBnbCBsaWdodHMsIHNldHVwIGEgbmV3IGxpZ2h0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgIH0gZWxzZSBpZiAocG9zLT5nbEluZGV4ID09IC0xKSB7CgogICAgICAgICAgICAgICAgLyogV2UgcmVhY2hlZCB0aGUgZW5kIG9mIHRoZSBhbGxvY2F0ZWQgZ2wgbGlnaHRzLCBzbyBhbHJlYWR5CiAgICAgICAgICAgICAgICAgICAga25vdyB0aGUgaW5kZXggb2YgdGhlIG5leHQgb25lISAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGdsSW5kZXggPSBJbmRleDsKICAgICAgICAgICAgICAgIGxpZ2h0SW5mby0+Z2xJbmRleCA9IGdsSW5kZXg7CiAgICAgICAgICAgICAgICBsaWdodEluZm8tPmxpZ2h0RW5hYmxlZCA9IFRSVUU7CgogICAgICAgICAgICAgICAgLyogSW4gYW4gaWRlYWwgd29ybGQsIGl0J3MgYWxyZWFkeSBpbiB0aGUgcmlnaHQgcGxhY2UgKi8KICAgICAgICAgICAgICAgIGlmIChsaWdodEluZm8tPnByZXYgPT0gTlVMTCB8fCBsaWdodEluZm8tPnByZXYtPmdsSW5kZXghPS0xKSB7CiAgICAgICAgICAgICAgICAgICAvKiBObyBuZWVkIHRvIG1vdmUgaXQgKi8KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyogUmVtb3ZlIHRoaXMgbGlnaHQgZnJvbSB0aGUgbGlzdCAqLwogICAgICAgICAgICAgICAgICAgIGxpZ2h0SW5mby0+cHJldi0+bmV4dCA9IGxpZ2h0SW5mby0+bmV4dDsKICAgICAgICAgICAgICAgICAgICBpZiAobGlnaHRJbmZvLT5uZXh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlnaHRJbmZvLT5uZXh0LT5wcmV2ID0gbGlnaHRJbmZvLT5wcmV2OwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLyogQWRkIGluIGF0IGFwcHJvcHJpYXRlIHBsYWNlIChpbmJldHdlZW4gcHJldiBhbmQgcG9zKSAqLwogICAgICAgICAgICAgICAgICAgIGxpZ2h0SW5mby0+cHJldiA9IHByZXY7CiAgICAgICAgICAgICAgICAgICAgbGlnaHRJbmZvLT5uZXh0ID0gcG9zOwogICAgICAgICAgICAgICAgICAgIGlmIChwcmV2ID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+bGlnaHRzID0gbGlnaHRJbmZvOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHByZXYtPm5leHQgPSBsaWdodEluZm87CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChwb3MgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBwb3MtPnByZXYgPSBsaWdodEluZm87CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIEZpbmFsbHkgc2V0IHVwIHRoZSBsaWdodCBpbiBnbCBpdHNlbGYgKi8KICAgICAgICAgICAgICAgIFRSQUNFKCJEZWZpbmluZyBuZXcgbGlnaHQgYXQgZ2wgaWR4ICVsZFxuIiwgbGlnaHRJbmZvLT5nbEluZGV4KTsKICAgICAgICAgICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgICAgICAgICBzZXR1cF9saWdodChpZmFjZSwgZ2xJbmRleCwgbGlnaHRJbmZvKTsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX0xJR0hUMCArIGdsSW5kZXgpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX0xJR0hUMCBuZXcgc2V0dXAiKTsKICAgICAgICAgICAgICAgIExFQVZFX0dMKCk7CgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRMaWdodEVuYWJsZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEluZGV4LEJPT0wqIHBFbmFibGUpIHsKCiAgICBQTElHSFRJTkZPRUwgKmxpZ2h0SW5mbyA9IE5VTEw7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IGZvciBpZHgoJWxkKVxuIiwgVGhpcywgSW5kZXgpOwoKICAgIC8qIExvY2F0ZSB0aGUgbGlnaHQgaW4gdGhlIGxpdmUgbGlnaHRzICovCiAgICBsaWdodEluZm8gPSBUaGlzLT5zdGF0ZUJsb2NrLT5saWdodHM7CiAgICB3aGlsZSAobGlnaHRJbmZvICE9IE5VTEwgJiYgbGlnaHRJbmZvLT5PcmlnaW5hbEluZGV4ICE9IEluZGV4KSBsaWdodEluZm8gPSBsaWdodEluZm8tPm5leHQ7CgogICAgaWYgKGxpZ2h0SW5mbyA9PSBOVUxMKSB7CiAgICAgICAgVFJBQ0UoIkxpZ2h0IGVuYWJsZWQgc3RhdGUgcmVxdWVzdGVkIGJ1dCBsaWdodCBub3QgZGVmaW5lZFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAqcEVuYWJsZSA9IGxpZ2h0SW5mby0+bGlnaHRFbmFibGVkOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgQ2xpcCBQbGFuZXMKICoqKioqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0Q2xpcFBsYW5lKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgSW5kZXgsIENPTlNUIGZsb2F0ICpwUGxhbmUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogZm9yIGlkeCAlbGQsICVwXG4iLCBUaGlzLCBJbmRleCwgcFBsYW5lKTsKCiAgICAvKiBWYWxpZGF0ZSBJbmRleCAqLwogICAgaWYgKEluZGV4ID49IEdMX0xJTUlUUyhjbGlwcGxhbmVzKSkgewogICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBoYXMgcmVxdWVzdGVkIGNsaXBwbGFuZSB0aGlzIGRldmljZSBkb2Vzbid0IHN1cHBvcnRcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQuY2xpcHBsYW5lW0luZGV4XSA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQuY2xpcHBsYW5lW0luZGV4XSA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzBdID0gcFBsYW5lWzBdOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVsxXSA9IHBQbGFuZVsxXTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMl0gPSBwUGxhbmVbMl07CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzNdID0gcFBsYW5lWzNdOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIEFwcGx5IGl0ICovCgogICAgRU5URVJfR0woKTsKCiAgICAvKiBDbGlwIFBsYW5lIHNldHRpbmdzIGFyZSBhZmZlY3RlZCBieSB0aGUgbW9kZWwgdmlldyBpbiBPcGVuR0wsIHRoZSBWaWV3IHRyYW5zZm9ybSBpbiBkaXJlY3QzZCAqLwogICAgZ2xNYXRyaXhNb2RlKEdMX01PREVMVklFVyk7CiAgICBnbFB1c2hNYXRyaXgoKTsKICAgIGdsTG9hZE1hdHJpeGYoKGZsb2F0ICopICZUaGlzLT5zdGF0ZUJsb2NrLT50cmFuc2Zvcm1zW0QzRFRTX1ZJRVddLnUubVswXVswXSk7CgogICAgVFJBQ0UoIkNsaXBwbGFuZSBbJWYsJWYsJWYsJWZdXG4iLAogICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVswXSwKICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMV0sCiAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzJdLAogICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVszXSk7CiAgICBnbENsaXBQbGFuZShHTF9DTElQX1BMQU5FMCArIEluZGV4LCBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdKTsKICAgIGNoZWNrR0xjYWxsKCJnbENsaXBQbGFuZSIpOwoKICAgIGdsUG9wTWF0cml4KCk7CiAgICBMRUFWRV9HTCgpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0Q2xpcFBsYW5lKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgSW5kZXgsIGZsb2F0ICpwUGxhbmUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogZm9yIGlkeCAlbGRcbiIsIFRoaXMsIEluZGV4KTsKCiAgICAvKiBWYWxpZGF0ZSBJbmRleCAqLwogICAgaWYgKEluZGV4ID49IEdMX0xJTUlUUyhjbGlwcGxhbmVzKSkgewogICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBoYXMgcmVxdWVzdGVkIGNsaXBwbGFuZSB0aGlzIGRldmljZSBkb2Vzbid0IHN1cHBvcnRcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIHBQbGFuZVswXSA9IFRoaXMtPnN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMF07CiAgICBwUGxhbmVbMV0gPSBUaGlzLT5zdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzFdOwogICAgcFBsYW5lWzJdID0gVGhpcy0+c3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVsyXTsKICAgIHBQbGFuZVszXSA9IFRoaXMtPnN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bM107CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBDbGlwIFBsYW5lIFN0YXR1cwogKiAgIFdBUk5JTkc6IFRoaXMgY29kZSByZWxpZXMgb24gdGhlIGZhY3QgdGhhdCBEM0RDTElQU1RBVFVTOCA9PSBEM0RDTElQU1RBVFVTOQogKioqKiovCkhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1NldENsaXBTdGF0dXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBDT05TVCBXSU5FRDNEQ0xJUFNUQVRVUyogcENsaXBTdGF0dXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEZJWE1FKCIoJXApIDogc3R1YlxuIiwgVGhpcyk7CiAgICBpZiAoTlVMTCA9PSBwQ2xpcFN0YXR1cykgewogICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBfc3RhdHVzLkNsaXBVbmlvbiA9IHBDbGlwU3RhdHVzLT5DbGlwVW5pb247CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwX3N0YXR1cy5DbGlwSW50ZXJzZWN0aW9uID0gcENsaXBTdGF0dXMtPkNsaXBJbnRlcnNlY3Rpb247CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0Q2xpcFN0YXR1cyhJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RDTElQU1RBVFVTKiBwQ2xpcFN0YXR1cykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgIGlmIChOVUxMID09IHBDbGlwU3RhdHVzKSB7CiAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgcENsaXBTdGF0dXMtPkNsaXBVbmlvbiA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBfc3RhdHVzLkNsaXBVbmlvbjsKICAgIHBDbGlwU3RhdHVzLT5DbGlwSW50ZXJzZWN0aW9uID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcF9zdGF0dXMuQ2xpcEludGVyc2VjdGlvbjsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IE1hdGVyaWFsCiAqICAgV0FSTklORzogVGhpcyBjb2RlIHJlbGllcyBvbiB0aGUgZmFjdCB0aGF0IEQzRE1BVEVSSUFMOCA9PSBEM0RNQVRFUklBTDkKICoqKioqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0TWF0ZXJpYWwoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBDT05TVCBXSU5FRDNETUFURVJJQUwqIHBNYXRlcmlhbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQubWF0ZXJpYWwgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0Lm1hdGVyaWFsID0gVFJVRTsKICAgIG1lbWNweSgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bWF0ZXJpYWwsIHBNYXRlcmlhbCwgc2l6ZW9mKFdJTkVEM0RNQVRFUklBTCkpOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIEVOVEVSX0dMKCk7CiAgICBUUkFDRSgiKCVwKSA6IERpZmZ1c2UgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5EaWZmdXNlLnIsIHBNYXRlcmlhbC0+RGlmZnVzZS5nLAogICAgICAgIHBNYXRlcmlhbC0+RGlmZnVzZS5iLCBwTWF0ZXJpYWwtPkRpZmZ1c2UuYSk7CiAgICBUUkFDRSgiKCVwKSA6IEFtYmllbnQgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5BbWJpZW50LnIsIHBNYXRlcmlhbC0+QW1iaWVudC5nLAogICAgICAgIHBNYXRlcmlhbC0+QW1iaWVudC5iLCBwTWF0ZXJpYWwtPkFtYmllbnQuYSk7CiAgICBUUkFDRSgiKCVwKSA6IFNwZWN1bGFyICglZiwlZiwlZiwlZilcbiIsIFRoaXMsIHBNYXRlcmlhbC0+U3BlY3VsYXIuciwgcE1hdGVyaWFsLT5TcGVjdWxhci5nLAogICAgICAgIHBNYXRlcmlhbC0+U3BlY3VsYXIuYiwgcE1hdGVyaWFsLT5TcGVjdWxhci5hKTsKICAgIFRSQUNFKCIoJXApIDogRW1pc3NpdmUgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5FbWlzc2l2ZS5yLCBwTWF0ZXJpYWwtPkVtaXNzaXZlLmcsCiAgICAgICAgcE1hdGVyaWFsLT5FbWlzc2l2ZS5iLCBwTWF0ZXJpYWwtPkVtaXNzaXZlLmEpOwogICAgVFJBQ0UoIiglcCkgOiBQb3dlciAoJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPlBvd2VyKTsKCiAgICBnbE1hdGVyaWFsZnYoR0xfRlJPTlRfQU5EX0JBQ0ssIEdMX0FNQklFTlQsIChmbG9hdCopICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5tYXRlcmlhbC5BbWJpZW50KTsKICAgIGNoZWNrR0xjYWxsKCJnbE1hdGVyaWFsZnYoR0xfQU1CSUVOVCkiKTsKICAgIGdsTWF0ZXJpYWxmdihHTF9GUk9OVF9BTkRfQkFDSywgR0xfRElGRlVTRSwgKGZsb2F0KikgJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPm1hdGVyaWFsLkRpZmZ1c2UpOwogICAgY2hlY2tHTGNhbGwoImdsTWF0ZXJpYWxmdihHTF9ESUZGVVNFKSIpOwoKICAgIC8qIE9ubHkgY2hhbmdlIG1hdGVyaWFsIGNvbG9yIGlmIHNwZWN1bGFyIGlzIGVuYWJsZWQsIG90aGVyd2lzZSBpdCBpcyBzZXQgdG8gYmxhY2sgKi8KICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfU1BFQ1VMQVJFTkFCTEVdKSB7CiAgICAgICBnbE1hdGVyaWFsZnYoR0xfRlJPTlRfQU5EX0JBQ0ssIEdMX1NQRUNVTEFSLCAoZmxvYXQqKSAmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bWF0ZXJpYWwuU3BlY3VsYXIpOwogICAgICAgY2hlY2tHTGNhbGwoImdsTWF0ZXJpYWxmdihHTF9TUEVDVUxBUiIpOwogICAgfSBlbHNlIHsKICAgICAgIGZsb2F0IGJsYWNrWzRdID0gezAuMGYsIDAuMGYsIDAuMGYsIDAuMGZ9OwogICAgICAgZ2xNYXRlcmlhbGZ2KEdMX0ZST05UX0FORF9CQUNLLCBHTF9TUEVDVUxBUiwgJmJsYWNrWzBdKTsKICAgICAgIGNoZWNrR0xjYWxsKCJnbE1hdGVyaWFsZnYoR0xfU1BFQ1VMQVIiKTsKICAgIH0KICAgIGdsTWF0ZXJpYWxmdihHTF9GUk9OVF9BTkRfQkFDSywgR0xfRU1JU1NJT04sIChmbG9hdCopICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5tYXRlcmlhbC5FbWlzc2l2ZSk7CiAgICBjaGVja0dMY2FsbCgiZ2xNYXRlcmlhbGZ2KEdMX0VNSVNTSU9OKSIpOwogICAgZ2xNYXRlcmlhbGYoR0xfRlJPTlRfQU5EX0JBQ0ssIEdMX1NISU5JTkVTUywgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bWF0ZXJpYWwuUG93ZXIpOwogICAgY2hlY2tHTGNhbGwoImdsTWF0ZXJpYWxmKEdMX1NISU5JTkVTUyIpOwoKICAgIExFQVZFX0dMKCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldE1hdGVyaWFsKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRE1BVEVSSUFMKiBwTWF0ZXJpYWwpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIG1lbWNweShwTWF0ZXJpYWwsICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5tYXRlcmlhbCwgc2l6ZW9mIChXSU5FRDNETUFURVJJQUwpKTsKICAgIFRSQUNFKCIoJXApIDogRGlmZnVzZSAoJWYsJWYsJWYsJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPkRpZmZ1c2UuciwgcE1hdGVyaWFsLT5EaWZmdXNlLmcsCiAgICAgICAgcE1hdGVyaWFsLT5EaWZmdXNlLmIsIHBNYXRlcmlhbC0+RGlmZnVzZS5hKTsKICAgIFRSQUNFKCIoJXApIDogQW1iaWVudCAoJWYsJWYsJWYsJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPkFtYmllbnQuciwgcE1hdGVyaWFsLT5BbWJpZW50LmcsCiAgICAgICAgcE1hdGVyaWFsLT5BbWJpZW50LmIsIHBNYXRlcmlhbC0+QW1iaWVudC5hKTsKICAgIFRSQUNFKCIoJXApIDogU3BlY3VsYXIgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5TcGVjdWxhci5yLCBwTWF0ZXJpYWwtPlNwZWN1bGFyLmcsCiAgICAgICAgcE1hdGVyaWFsLT5TcGVjdWxhci5iLCBwTWF0ZXJpYWwtPlNwZWN1bGFyLmEpOwogICAgVFJBQ0UoIiglcCkgOiBFbWlzc2l2ZSAoJWYsJWYsJWYsJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPkVtaXNzaXZlLnIsIHBNYXRlcmlhbC0+RW1pc3NpdmUuZywKICAgICAgICBwTWF0ZXJpYWwtPkVtaXNzaXZlLmIsIHBNYXRlcmlhbC0+RW1pc3NpdmUuYSk7CiAgICBUUkFDRSgiKCVwKSA6IFBvd2VyICglZilcbiIsIFRoaXMsIHBNYXRlcmlhbC0+UG93ZXIpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IEluZGljZXMKICoqKioqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0SW5kaWNlcyhJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNESW5kZXhCdWZmZXIqIHBJbmRleERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgQmFzZVZlcnRleEluZGV4KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RJbmRleEJ1ZmZlciAqb2xkSWR4czsKCiAgICBUUkFDRSgiKCVwKSA6IFNldHRpbmcgdG8gJXAsIGJhc2UgJWRcbiIsIFRoaXMsIHBJbmRleERhdGEsIEJhc2VWZXJ0ZXhJbmRleCk7CiAgICBvbGRJZHhzID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cEluZGV4RGF0YTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLmluZGljZXMgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LmluZGljZXMgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cEluZGV4RGF0YSA9IHBJbmRleERhdGE7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXggPSBCYXNlVmVydGV4SW5kZXg7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYgKE5VTEwgIT0gcEluZGV4RGF0YSkgewogICAgICAgIElXaW5lRDNESW5kZXhCdWZmZXJfQWRkUmVmKHBJbmRleERhdGEpOwogICAgfQogICAgaWYgKE5VTEwgIT0gb2xkSWR4cykgewogICAgICAgIElXaW5lRDNESW5kZXhCdWZmZXJfUmVsZWFzZShvbGRJZHhzKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0SW5kaWNlcyhJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNESW5kZXhCdWZmZXIqKiBwcEluZGV4RGF0YSwgVUlOVCogcEJhc2VWZXJ0ZXhJbmRleCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgICpwcEluZGV4RGF0YSA9IFRoaXMtPnN0YXRlQmxvY2stPnBJbmRleERhdGE7CgogICAgLyogdXAgcmVmIGNvdW50IG9uIHBwaW5kZXhkYXRhICovCiAgICBpZiAoKnBwSW5kZXhEYXRhKSB7CiAgICAgICAgSVdpbmVEM0RJbmRleEJ1ZmZlcl9BZGRSZWYoKnBwSW5kZXhEYXRhKTsKICAgICAgICAqcEJhc2VWZXJ0ZXhJbmRleCA9IFRoaXMtPnN0YXRlQmxvY2stPmJhc2VWZXJ0ZXhJbmRleDsKICAgICAgICBUUkFDRSgiKCVwKSBpbmRleCBkYXRhIHNldCB0byAlcCArICV1XG4iLCBUaGlzLCBwcEluZGV4RGF0YSwgVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4KTsKICAgIH1lbHNlewogICAgICAgIFRSQUNFKCIoJXApIE5vIGluZGV4IGRhdGEgc2V0XG4iLCBUaGlzKTsKICAgIH0KICAgIFRSQUNFKCJSZXR1cm5pbmcgJXAgJWRcbiIsICpwcEluZGV4RGF0YSwgKnBCYXNlVmVydGV4SW5kZXgpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IFZpZXdwb3J0cwogKioqKiovCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWaWV3cG9ydChJV2luZUQzRERldmljZSAqaWZhY2UsIENPTlNUIFdJTkVEM0RWSUVXUE9SVCogcFZpZXdwb3J0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC52aWV3cG9ydCA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQudmlld3BvcnQgPSBUUlVFOwogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52aWV3cG9ydCwgcFZpZXdwb3J0LCBzaXplb2YoV0lORUQzRFZJRVdQT1JUKSk7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CiAgICBUaGlzLT52aWV3cG9ydF9jaGFuZ2VkID0gVFJVRTsKCiAgICBFTlRFUl9HTCgpOwoKICAgIFRSQUNFKCIoJXApIDogeD0lbGQsIHk9JWxkLCB3aWQ9JWxkLCBoZWk9JWxkLCBtaW56PSVmLCBtYXh6PSVmXG4iLCBUaGlzLAogICAgICAgICAgcFZpZXdwb3J0LT5YLCBwVmlld3BvcnQtPlksIHBWaWV3cG9ydC0+V2lkdGgsIHBWaWV3cG9ydC0+SGVpZ2h0LCBwVmlld3BvcnQtPk1pblosIHBWaWV3cG9ydC0+TWF4Wik7CgogICAgZ2xEZXB0aFJhbmdlKHBWaWV3cG9ydC0+TWluWiwgcFZpZXdwb3J0LT5NYXhaKTsKICAgIGNoZWNrR0xjYWxsKCJnbERlcHRoUmFuZ2UiKTsKICAgIC8qIE5vdGU6IEdMIHJlcXVpcmVzIGxvd2VyIGxlZnQsIERpcmVjdFggc3VwcGxpZXMgdXBwZXIgbGVmdCAqLwogICAgLyogVE9ETzogcmVwbGFjZSB1c2FnZSBvZiByZW5kZXJUYXJnZXQgd2l0aCBjb250ZXh0IG1hbmFnZW1lbnQgKi8KICAgIGdsVmlld3BvcnQocFZpZXdwb3J0LT5YLAogICAgICAgICAgICAgICAoKChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+cmVuZGVyVGFyZ2V0KS0+Y3VycmVudERlc2MuSGVpZ2h0IC0gKHBWaWV3cG9ydC0+WSArIHBWaWV3cG9ydC0+SGVpZ2h0KSksCiAgICAgICAgICAgICAgIHBWaWV3cG9ydC0+V2lkdGgsIHBWaWV3cG9ydC0+SGVpZ2h0KTsKCiAgICBjaGVja0dMY2FsbCgiZ2xWaWV3cG9ydCIpOwoKICAgIExFQVZFX0dMKCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cgp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0Vmlld3BvcnQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEVklFV1BPUlQqIHBWaWV3cG9ydCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwogICAgbWVtY3B5KHBWaWV3cG9ydCwgJlRoaXMtPnN0YXRlQmxvY2stPnZpZXdwb3J0LCBzaXplb2YoV0lORUQzRFZJRVdQT1JUKSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBSZW5kZXIgU3RhdGVzCiAqIFRPRE86IFZlcmlmeSBhZ2FpbnN0IGR4OSBkZWZpbml0aW9ucwogKioqKiovCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRSZW5kZXJTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIEQzRFJFTkRFUlNUQVRFVFlQRSBTdGF0ZSwgRFdPUkQgVmFsdWUpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgICpUaGlzICAgICA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIERXT1JEICAgICAgICAgICAgICAgIE9sZFZhbHVlID0gVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbU3RhdGVdOwoKICAgIC8qIFNpbXBsZSB3YXkgb2YgcmVmZXJyaW5nIHRvIGVpdGhlciBhIERXT1JEIG9yIGEgNCBieXRlIGZsb2F0ICovCiAgICB1bmlvbiB7CiAgICAgICAgRFdPUkQgZDsKICAgICAgICBmbG9hdCBmOwogICAgfSB0bXB2YWx1ZTsKCiAgICBUUkFDRSgiKCVwKS0+c3RhdGUgPSAlcyglZCksIHZhbHVlID0gJWxkXG4iLCBUaGlzLCBkZWJ1Z19kM2RyZW5kZXJzdGF0ZShTdGF0ZSksIFN0YXRlLCBWYWx1ZSk7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnJlbmRlclN0YXRlW1N0YXRlXSA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQucmVuZGVyU3RhdGVbU3RhdGVdID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1N0YXRlXSA9IFZhbHVlOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIEVOVEVSX0dMKCk7CgogICAgc3dpdGNoIChTdGF0ZSkgewogICAgY2FzZSBXSU5FRDNEUlNfRklMTE1PREUgICAgICAgICAgICAgICAgICA6CiAgICAgICAgc3dpdGNoICgoRDNERklMTE1PREUpIFZhbHVlKSB7CiAgICAgICAgY2FzZSBEM0RGSUxMX1BPSU5UICAgICAgICAgICAgICAgOiBnbFBvbHlnb25Nb2RlKEdMX0ZST05UX0FORF9CQUNLLCBHTF9QT0lOVCk7IGJyZWFrOwogICAgICAgIGNhc2UgRDNERklMTF9XSVJFRlJBTUUgICAgICAgICAgIDogZ2xQb2x5Z29uTW9kZShHTF9GUk9OVF9BTkRfQkFDSywgR0xfTElORSk7IGJyZWFrOwogICAgICAgIGNhc2UgRDNERklMTF9TT0xJRCAgICAgICAgICAgICAgIDogZ2xQb2x5Z29uTW9kZShHTF9GUk9OVF9BTkRfQkFDSywgR0xfRklMTCk7IGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEZJWE1FKCJVbnJlY29nbml6ZWQgV0lORUQzRFJTX0ZJTExNT0RFIHZhbHVlICVsZFxuIiwgVmFsdWUpOwogICAgICAgIH0KICAgICAgICBjaGVja0dMY2FsbCgiZ2xQb2x5Z29uTW9kZSAoZmlsbG1vZGUpIik7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUlNfTElHSFRJTkcgICAgICAgICAgICAgICAgICA6CiAgICAgICAgaWYgKFZhbHVlKSB7CiAgICAgICAgICAgIGdsRW5hYmxlKEdMX0xJR0hUSU5HKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX0xJR0hUSU5HIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0xJR0hUSU5HKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9MSUdIVElORyIpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19aRU5BQkxFICAgICAgICAgICAgICAgICAgIDoKICAgICAgICBzd2l0Y2ggKChEM0RaQlVGRkVSVFlQRSkgVmFsdWUpIHsKICAgICAgICBjYXNlIEQzRFpCX0ZBTFNFOgogICAgICAgICAgICBnbERpc2FibGUoR0xfREVQVEhfVEVTVCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfREVQVEhfVEVTVCIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEQzRFpCX1RSVUU6CiAgICAgICAgICAgIGdsRW5hYmxlKEdMX0RFUFRIX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfREVQVEhfVEVTVCIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEQzRFpCX1VTRVc6CiAgICAgICAgICAgIGdsRW5hYmxlKEdMX0RFUFRIX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfREVQVEhfVEVTVCIpOwogICAgICAgICAgICBGSVhNRSgiVyBidWZmZXIgaXMgbm90IHdlbGwgaGFuZGxlZFxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEZJWE1FKCJVbnJlY29nbml6ZWQgRDNEWkJVRkZFUlRZUEUgdmFsdWUgJWxkXG4iLCBWYWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFJTX0NVTExNT0RFICAgICAgICAgICAgICAgICAgOgoKICAgICAgICAvKiBJZiB3ZSBhcmUgY3VsbGluZyAiYmFjayBmYWNlcyB3aXRoIGNsb2Nrd2lzZSB2ZXJ0aWNlcyIgdGhlbgogICAgICAgICAgIHNldCBmcm9udCBmYWNlcyB0byBiZSBjb3VudGVyIGNsb2Nrd2lzZSBhbmQgZW5hYmxlIGN1bGxpbmcKICAgICAgICAgICBvZiBiYWNrIGZhY2VzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgIHN3aXRjaCAoKEQzRENVTEwpIFZhbHVlKSB7CiAgICAgICAgY2FzZSBEM0RDVUxMX05PTkU6CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9DVUxMX0ZBQ0UpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0NVTExfRkFDRSIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEQzRENVTExfQ1c6CiAgICAgICAgICAgIGdsRW5hYmxlKEdMX0NVTExfRkFDRSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9DVUxMX0ZBQ0UiKTsKICAgICAgICAgICAgaWYgKFRoaXMtPnJlbmRlclVwc2lkZURvd24pIHsKICAgICAgICAgICAgICAgIGdsRnJvbnRGYWNlKEdMX0NXKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEZyb250RmFjZSBHTF9DVyIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ2xGcm9udEZhY2UoR0xfQ0NXKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEZyb250RmFjZSBHTF9DQ1ciKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBnbEN1bGxGYWNlKEdMX0JBQ0spOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEQzRENVTExfQ0NXOgogICAgICAgICAgICBnbEVuYWJsZShHTF9DVUxMX0ZBQ0UpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfQ1VMTF9GQUNFIik7CiAgICAgICAgICAgIGlmIChUaGlzLT5yZW5kZXJVcHNpZGVEb3duKSB7CiAgICAgICAgICAgICAgICBnbEZyb250RmFjZShHTF9DQ1cpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRnJvbnRGYWNlIEdMX0NDVyIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ2xGcm9udEZhY2UoR0xfQ1cpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRnJvbnRGYWNlIEdMX0NXIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZ2xDdWxsRmFjZShHTF9CQUNLKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIlVucmVjb2duaXplZC9VbmhhbmRsZWQgRDNEQ1VMTCB2YWx1ZSAlbGRcbiIsIFZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUlNfU0hBREVNT0RFICAgICAgICAgICAgICAgICA6CiAgICAgICAgc3dpdGNoICgoRDNEU0hBREVNT0RFKSBWYWx1ZSkgewogICAgICAgIGNhc2UgRDNEU0hBREVfRkxBVDoKICAgICAgICAgICAgZ2xTaGFkZU1vZGVsKEdMX0ZMQVQpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xTaGFkZU1vZGVsIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRDNEU0hBREVfR09VUkFVRDoKICAgICAgICAgICAgZ2xTaGFkZU1vZGVsKEdMX1NNT09USCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFNoYWRlTW9kZWwiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBEM0RTSEFERV9QSE9ORzoKICAgICAgICAgICAgRklYTUUoIkQzRFNIQURFX1BIT05HIGlzbid0IHN1cHBvcnRlZD9cbiIpOwoKICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIlVucmVjb2duaXplZC9VbmhhbmRsZWQgRDNEU0hBREVNT0RFIHZhbHVlICVsZFxuIiwgVmFsdWUpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19ESVRIRVJFTkFCTEUgICAgICAgICAgICAgIDoKICAgICAgICBpZiAoVmFsdWUpIHsKICAgICAgICAgICAgZ2xFbmFibGUoR0xfRElUSEVSKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX0RJVEhFUiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9ESVRIRVIpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0RJVEhFUiIpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19aV1JJVEVFTkFCTEUgICAgICAgICAgICAgIDoKICAgICAgICBpZiAoVmFsdWUpIHsKICAgICAgICAgICAgZ2xEZXB0aE1hc2soMSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERlcHRoTWFzayIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsRGVwdGhNYXNrKDApOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEZXB0aE1hc2siKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUlNfWkZVTkMgICAgICAgICAgICAgICAgICAgICA6CiAgICAgICAgewogICAgICAgICAgICBpbnQgZ2xQYXJtID0gR0xfTEVTUzsKCiAgICAgICAgICAgIHN3aXRjaCAoKEQzRENNUEZVTkMpIFZhbHVlKSB7CiAgICAgICAgICAgIGNhc2UgRDNEQ01QX05FVkVSOiAgICAgICAgIGdsUGFybT1HTF9ORVZFUjsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRDNEQ01QX0xFU1M6ICAgICAgICAgIGdsUGFybT1HTF9MRVNTOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RDTVBfRVFVQUw6ICAgICAgICAgZ2xQYXJtPUdMX0VRVUFMOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RDTVBfTEVTU0VRVUFMOiAgICAgZ2xQYXJtPUdMX0xFUVVBTDsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRDNEQ01QX0dSRUFURVI6ICAgICAgIGdsUGFybT1HTF9HUkVBVEVSOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RDTVBfTk9URVFVQUw6ICAgICAgZ2xQYXJtPUdMX05PVEVRVUFMOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RDTVBfR1JFQVRFUkVRVUFMOiAgZ2xQYXJtPUdMX0dFUVVBTDsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRDNEQ01QX0FMV0FZUzogICAgICAgIGdsUGFybT1HTF9BTFdBWVM7IGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUUoIlVucmVjb2duaXplZC9VbmhhbmRsZWQgRDNEQ01QRlVOQyB2YWx1ZSAlbGRcbiIsIFZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBnbERlcHRoRnVuYyhnbFBhcm0pOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEZXB0aEZ1bmMiKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUlNfQU1CSUVOVCAgICAgICAgICAgICAgICAgICA6CiAgICAgICAgewogICAgICAgICAgICBmbG9hdCBjb2xbNF07CiAgICAgICAgICAgIEQzRENPTE9SVE9HTEZMT0FUNChWYWx1ZSwgY29sKTsKICAgICAgICAgICAgVFJBQ0UoIlNldHRpbmcgYW1iaWVudCB0byAoJWYsJWYsJWYsJWYpXG4iLCBjb2xbMF0sIGNvbFsxXSwgY29sWzJdLCBjb2xbM10pOwogICAgICAgICAgICBnbExpZ2h0TW9kZWxmdihHTF9MSUdIVF9NT0RFTF9BTUJJRU5ULCBjb2wpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xMaWdodE1vZGVsIGZvciBNT0RFTF9BTUJJRU5UIik7CgogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19BTFBIQUJMRU5ERU5BQkxFICAgICAgICAgIDoKICAgICAgICBpZiAoVmFsdWUpIHsKICAgICAgICAgICAgZ2xFbmFibGUoR0xfQkxFTkQpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfQkxFTkQiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBnbERpc2FibGUoR0xfQkxFTkQpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0JMRU5EIik7CiAgICAgICAgfTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19TUkNCTEVORCAgICAgICAgICAgICAgICAgIDoKICAgIGNhc2UgV0lORUQzRFJTX0RFU1RCTEVORCAgICAgICAgICAgICAgICAgOgogICAgICAgIHsKICAgICAgICAgICAgaW50IG5ld1ZhbCA9IEdMX1pFUk87CiAgICAgICAgICAgIHN3aXRjaCAoVmFsdWUpIHsKICAgICAgICAgICAgY2FzZSBEM0RCTEVORF9aRVJPICAgICAgICAgICAgICAgOiBuZXdWYWwgPSBHTF9aRVJPOyAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRDNEQkxFTkRfT05FICAgICAgICAgICAgICAgIDogbmV3VmFsID0gR0xfT05FOyAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRDNEQkxFTkRfU1JDQ09MT1IgICAgICAgICAgIDogbmV3VmFsID0gR0xfU1JDX0NPTE9SOyAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRDNEQkxFTkRfSU5WU1JDQ09MT1IgICAgICAgIDogbmV3VmFsID0gR0xfT05FX01JTlVTX1NSQ19DT0xPUjsgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzREJMRU5EX1NSQ0FMUEhBICAgICAgICAgICA6IG5ld1ZhbCA9IEdMX1NSQ19BTFBIQTsgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzREJMRU5EX0lOVlNSQ0FMUEhBICAgICAgICA6IG5ld1ZhbCA9IEdMX09ORV9NSU5VU19TUkNfQUxQSEE7ICBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RCTEVORF9ERVNUQUxQSEEgICAgICAgICAgOiBuZXdWYWwgPSBHTF9EU1RfQUxQSEE7ICBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RCTEVORF9JTlZERVNUQUxQSEEgICAgICAgOiBuZXdWYWwgPSBHTF9PTkVfTUlOVVNfRFNUX0FMUEhBOyAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRDNEQkxFTkRfREVTVENPTE9SICAgICAgICAgIDogbmV3VmFsID0gR0xfRFNUX0NPTE9SOyAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRDNEQkxFTkRfSU5WREVTVENPTE9SICAgICAgIDogbmV3VmFsID0gR0xfT05FX01JTlVTX0RTVF9DT0xPUjsgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzREJMRU5EX1NSQ0FMUEhBU0FUICAgICAgICA6IG5ld1ZhbCA9IEdMX1NSQ19BTFBIQV9TQVRVUkFURTsgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBEM0RCTEVORF9CT1RIU1JDQUxQSEEgICAgICAgOiBuZXdWYWwgPSBHTF9TUkNfQUxQSEE7CiAgICAgICAgICAgICAgICBUaGlzLT5zcmNCbGVuZCA9IG5ld1ZhbDsKICAgICAgICAgICAgICAgIFRoaXMtPmRzdEJsZW5kID0gbmV3VmFsOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEQzREJMRU5EX0JPVEhJTlZTUkNBTFBIQSAgICA6IG5ld1ZhbCA9IEdMX09ORV9NSU5VU19TUkNfQUxQSEE7CiAgICAgICAgICAgICAgICBUaGlzLT5zcmNCbGVuZCA9IG5ld1ZhbDsKICAgICAgICAgICAgICAgIFRoaXMtPmRzdEJsZW5kID0gbmV3VmFsOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBGSVhNRSgiVW5yZWNvZ25pemVkIHNyYy9kZXN0IGJsZW5kIHZhbHVlICVsZCAoJWQpXG4iLCBWYWx1ZSwgU3RhdGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoU3RhdGUgPT0gV0lORUQzRFJTX1NSQ0JMRU5EKSBUaGlzLT5zcmNCbGVuZCA9IG5ld1ZhbDsKICAgICAgICAgICAgaWYgKFN0YXRlID09IFdJTkVEM0RSU19ERVNUQkxFTkQpIFRoaXMtPmRzdEJsZW5kID0gbmV3VmFsOwogICAgICAgICAgICBUUkFDRSgiZ2xCbGVuZEZ1bmMgc3JjPSV4LCBkc3Q9JXhcbiIsIFRoaXMtPnNyY0JsZW5kLCBUaGlzLT5kc3RCbGVuZCk7CiAgICAgICAgICAgIGdsQmxlbmRGdW5jKFRoaXMtPnNyY0JsZW5kLCBUaGlzLT5kc3RCbGVuZCk7CgogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCbGVuZEZ1bmMiKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUlNfQUxQSEFURVNURU5BQkxFICAgICAgICAgICA6CiAgICAgICAgaWYgKFZhbHVlKSB7CiAgICAgICAgICAgIGdsRW5hYmxlKEdMX0FMUEhBX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfQUxQSEFfVEVTVCIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9BTFBIQV9URVNUKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9BTFBIQV9URVNUIik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFJTX0FMUEhBRlVOQyAgICAgICAgICAgICAgICAgOgogICAgICAgIHsKICAgICAgICAgICAgaW50IGdsUGFybSA9IEdMX0xFU1M7CiAgICAgICAgICAgIGZsb2F0IHJlZiA9ICgoZmxvYXQpIFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19BTFBIQVJFRl0pIC8gMjU1LjBmOwoKICAgICAgICAgICAgc3dpdGNoICgoRDNEQ01QRlVOQykgVmFsdWUpIHsKICAgICAgICAgICAgY2FzZSBEM0RDTVBfTkVWRVI6ICAgICAgICAgZ2xQYXJtID0gR0xfTkVWRVI7IGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRENNUF9MRVNTOiAgICAgICAgICBnbFBhcm0gPSBHTF9MRVNTOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RDTVBfRVFVQUw6ICAgICAgICAgZ2xQYXJtID0gR0xfRVFVQUw7IGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRENNUF9MRVNTRVFVQUw6ICAgICBnbFBhcm0gPSBHTF9MRVFVQUw7IGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRENNUF9HUkVBVEVSOiAgICAgICBnbFBhcm0gPSBHTF9HUkVBVEVSOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RDTVBfTk9URVFVQUw6ICAgICAgZ2xQYXJtID0gR0xfTk9URVFVQUw7IGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRENNUF9HUkVBVEVSRVFVQUw6ICBnbFBhcm0gPSBHTF9HRVFVQUw7IGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRENNUF9BTFdBWVM6ICAgICAgICBnbFBhcm0gPSBHTF9BTFdBWVM7IGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUUoIlVucmVjb2duaXplZC9VbmhhbmRsZWQgRDNEQ01QRlVOQyB2YWx1ZSAlbGRcbiIsIFZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBUUkFDRSgiZ2xBbHBoYUZ1bmMgd2l0aCBQYXJtPSV4LCByZWY9JWZcbiIsIGdsUGFybSwgcmVmKTsKICAgICAgICAgICAgZ2xBbHBoYUZ1bmMoZ2xQYXJtLCByZWYpOwogICAgICAgICAgICBUaGlzLT5hbHBoYWZ1bmMgPSBnbFBhcm07CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFscGhhRnVuYyIpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19BTFBIQVJFRiAgICAgICAgICAgICAgICAgIDoKICAgICAgICB7CiAgICAgICAgICAgIGludCBnbFBhcm0gPSBUaGlzLT5hbHBoYWZ1bmM7CiAgICAgICAgICAgIGZsb2F0IHJlZiA9IDEuMGY7CgogICAgICAgICAgICByZWYgPSAoKGZsb2F0KSBWYWx1ZSkgLyAyNTUuMGY7CiAgICAgICAgICAgIFRSQUNFKCJnbEFscGhhRnVuYyB3aXRoIFBhcm09JXgsIHJlZj0lZlxuIiwgZ2xQYXJtLCByZWYpOwogICAgICAgICAgICBnbEFscGhhRnVuYyhnbFBhcm0sIHJlZik7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFscGhhRnVuYyIpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19DTElQUExBTkVFTkFCTEUgICAgICAgICAgIDoKICAgIGNhc2UgV0lORUQzRFJTX0NMSVBQSU5HICAgICAgICAgICAgICAgICAgOgogICAgICAgIHsKICAgICAgICAgICAgLyogRW5zdXJlIHdlIG9ubHkgZG8gdGhlIGNoYW5nZWQgY2xpcCBwbGFuZXMgKi8KICAgICAgICAgICAgRFdPUkQgZW5hYmxlICA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIERXT1JEIGRpc2FibGUgPSAweDAwMDAwMDAwOwoKICAgICAgICAgICAgLyogSWYgZW5hYmxpbmcgLyBkaXNhYmxpbmcgYWxsICovCiAgICAgICAgICAgIGlmIChTdGF0ZSA9PSBXSU5FRDNEUlNfQ0xJUFBJTkcpIHsKICAgICAgICAgICAgICAgIGlmIChWYWx1ZSkgewogICAgICAgICAgICAgICAgICAgIGVuYWJsZSAgPSBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfQ0xJUFBMQU5FRU5BQkxFXTsKICAgICAgICAgICAgICAgICAgICBkaXNhYmxlID0gMHgwMDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZSA9IFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19DTElQUExBTkVFTkFCTEVdOwogICAgICAgICAgICAgICAgICAgIGVuYWJsZSAgPSAweDAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZW5hYmxlID0gICBWYWx1ZSAmIH5PbGRWYWx1ZTsKICAgICAgICAgICAgICAgIGRpc2FibGUgPSB+VmFsdWUgJiAgT2xkVmFsdWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChlbmFibGUgJiBEM0RDTElQUExBTkUwKSAgeyBnbEVuYWJsZShHTF9DTElQX1BMQU5FMCk7ICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoY2xpcCBwbGFuZSAwKSIpOyB9CiAgICAgICAgICAgIGlmIChlbmFibGUgJiBEM0RDTElQUExBTkUxKSAgeyBnbEVuYWJsZShHTF9DTElQX1BMQU5FMSk7ICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoY2xpcCBwbGFuZSAxKSIpOyB9CiAgICAgICAgICAgIGlmIChlbmFibGUgJiBEM0RDTElQUExBTkUyKSAgeyBnbEVuYWJsZShHTF9DTElQX1BMQU5FMik7ICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoY2xpcCBwbGFuZSAyKSIpOyB9CiAgICAgICAgICAgIGlmIChlbmFibGUgJiBEM0RDTElQUExBTkUzKSAgeyBnbEVuYWJsZShHTF9DTElQX1BMQU5FMyk7ICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoY2xpcCBwbGFuZSAzKSIpOyB9CiAgICAgICAgICAgIGlmIChlbmFibGUgJiBEM0RDTElQUExBTkU0KSAgeyBnbEVuYWJsZShHTF9DTElQX1BMQU5FNCk7ICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoY2xpcCBwbGFuZSA0KSIpOyB9CiAgICAgICAgICAgIGlmIChlbmFibGUgJiBEM0RDTElQUExBTkU1KSAgeyBnbEVuYWJsZShHTF9DTElQX1BMQU5FNSk7ICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoY2xpcCBwbGFuZSA1KSIpOyB9CgogICAgICAgICAgICBpZiAoZGlzYWJsZSAmIEQzRENMSVBQTEFORTApIHsgZ2xEaXNhYmxlKEdMX0NMSVBfUExBTkUwKTsgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShjbGlwIHBsYW5lIDApIik7IH0KICAgICAgICAgICAgaWYgKGRpc2FibGUgJiBEM0RDTElQUExBTkUxKSB7IGdsRGlzYWJsZShHTF9DTElQX1BMQU5FMSk7IGNoZWNrR0xjYWxsKCJnbERpc2FibGUoY2xpcCBwbGFuZSAxKSIpOyB9CiAgICAgICAgICAgIGlmIChkaXNhYmxlICYgRDNEQ0xJUFBMQU5FMikgeyBnbERpc2FibGUoR0xfQ0xJUF9QTEFORTIpOyBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKGNsaXAgcGxhbmUgMikiKTsgfQogICAgICAgICAgICBpZiAoZGlzYWJsZSAmIEQzRENMSVBQTEFORTMpIHsgZ2xEaXNhYmxlKEdMX0NMSVBfUExBTkUzKTsgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShjbGlwIHBsYW5lIDMpIik7IH0KICAgICAgICAgICAgaWYgKGRpc2FibGUgJiBEM0RDTElQUExBTkU0KSB7IGdsRGlzYWJsZShHTF9DTElQX1BMQU5FNCk7IGNoZWNrR0xjYWxsKCJnbERpc2FibGUoY2xpcCBwbGFuZSA0KSIpOyB9CiAgICAgICAgICAgIGlmIChkaXNhYmxlICYgRDNEQ0xJUFBMQU5FNSkgeyBnbERpc2FibGUoR0xfQ0xJUF9QTEFORTUpOyBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKGNsaXAgcGxhbmUgNSkiKTsgfQoKICAgICAgICAgICAgLyoqIHVwZGF0ZSBjbGlwcGluZyBzdGF0dXMgKi8KICAgICAgICAgICAgaWYgKGVuYWJsZSkgewogICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPmNsaXBfc3RhdHVzLkNsaXBVbmlvbiA9IDA7CiAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+Y2xpcF9zdGF0dXMuQ2xpcEludGVyc2VjdGlvbiA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+Y2xpcF9zdGF0dXMuQ2xpcFVuaW9uID0gMDsKICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5jbGlwX3N0YXR1cy5DbGlwSW50ZXJzZWN0aW9uID0gMDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19CTEVORE9QICAgICAgICAgICAgICAgICAgIDoKICAgICAgICB7CiAgICAgICAgICAgIGludCBnbFBhcm0gPSBHTF9GVU5DX0FERDsKCiAgICAgICAgICAgIHN3aXRjaCAoKEQzREJMRU5ET1ApIFZhbHVlKSB7CiAgICAgICAgICAgIGNhc2UgRDNEQkxFTkRPUF9BREQgICAgICAgICAgICAgIDogZ2xQYXJtID0gR0xfRlVOQ19BREQ7ICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RCTEVORE9QX1NVQlRSQUNUICAgICAgICAgOiBnbFBhcm0gPSBHTF9GVU5DX1NVQlRSQUNUOyAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzREJMRU5ET1BfUkVWU1VCVFJBQ1QgICAgICA6IGdsUGFybSA9IEdMX0ZVTkNfUkVWRVJTRV9TVUJUUkFDVDsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRDNEQkxFTkRPUF9NSU4gICAgICAgICAgICAgIDogZ2xQYXJtID0gR0xfTUlOOyAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RCTEVORE9QX01BWCAgICAgICAgICAgICAgOiBnbFBhcm0gPSBHTF9NQVg7ICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUUoIlVucmVjb2duaXplZC9VbmhhbmRsZWQgRDNEQkxFTkRPUCB2YWx1ZSAlbGRcbiIsIFZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBUUkFDRSgiZ2xCbGVuZEVxdWF0aW9uKCV4KVxuIiwgZ2xQYXJtKTsKICAgICAgICAgICAgZ2xCbGVuZEVxdWF0aW9uKGdsUGFybSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJsZW5kRXF1YXRpb24iKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUlNfVEVYVFVSRUZBQ1RPUiAgICAgICAgICAgICA6CiAgICAgICAgewogICAgICAgICAgICB1bnNpZ25lZCBpbnQgaTsKCiAgICAgICAgICAgIC8qIE5vdGUgdGhlIHRleHR1cmUgY29sb3IgYXBwbGllcyB0byBhbGwgdGV4dHVyZXMgd2hlcmVhcwogICAgICAgICAgICAgICBHTF9URVhUVVJFX0VOVl9DT0xPUiBhcHBsaWVzIHRvIGFjdGl2ZSBvbmx5ICovCiAgICAgICAgICAgIGZsb2F0IGNvbFs0XTsKICAgICAgICAgICAgRDNEQ09MT1JUT0dMRkxPQVQ0KFZhbHVlLCBjb2wpOwogICAgICAgICAgICAvKiBTZXQgdGhlIGRlZmF1bHQgYWxwaGEgYmxlbmQgY29sb3IgKi8KICAgICAgICAgICAgZ2xCbGVuZENvbG9yKGNvbFswXSwgY29sWzFdLCBjb2xbMl0sIGNvbFszXSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJsZW5kQ29sb3IiKTsKCiAgICAgICAgICAgIC8qIEFuZCBub3cgdGhlIGRlZmF1bHQgdGV4dHVyZSBjb2xvciBhcyB3ZWxsICovCiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFModGV4dHVyZXMpOyBpKyspIHsKCiAgICAgICAgICAgICAgICAvKiBOb3RlIHRoZSBEM0RSUyB2YWx1ZSBhcHBsaWVzIHRvIGFsbCB0ZXh0dXJlcywgYnV0IEdMIGhhcyBvbmUKICAgICAgICAgICAgICAgICAgIHBlciB0ZXh0dXJlLCBzbyBhcHBseSBpdCBub3cgcmVhZHkgdG8gYmUgdXNlZCEgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKEdMX1NVUFBPUlQoQVJCX01VTFRJVEVYVFVSRSkpIHsKICAgICAgICAgICAgICAgICAgICBHTEFDVElWRVRFWFRVUkUoaSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGk+MCkgewogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJQcm9ncmFtIHVzaW5nIG11bHRpcGxlIGNvbmN1cnJlbnQgdGV4dHVyZXMgd2hpY2ggdGhpcyBvcGVuZ2wgaW1wbGVtZW50YXRpb24gZG9lc24ndCBzdXBwb3J0XG4iKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBnbFRleEVudmZ2KEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9DT0xPUiwgJmNvbFswXSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhFbnZmdihHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfQ09MT1IsIGNvbG9yKTsiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19TUEVDVUxBUkVOQUJMRSAgICAgICAgICAgIDoKICAgICAgICB7CiAgICAgICAgICAgIC8qIE9yaWdpbmFsbHkgdGhpcyB1c2VkIGdsTGlnaHRNb2RlbGkoR0xfTElHSFRfTU9ERUxfQ09MT1JfQ09OVFJPTCxHTF9TRVBBUkFURV9TUEVDVUxBUl9DT0xPUikKICAgICAgICAgICAgICAgYW5kIChHTF9MSUdIVF9NT0RFTF9DT0xPUl9DT05UUk9MLEdMX1NJTkdMRV9DT0xPUikgdG8gc3dhcCBiZXR3ZWVuIGVuYWJsZWQvZGlzYWJsZWQKICAgICAgICAgICAgICAgc3BlY3VsYXIgY29sb3IuIFRoaXMgaXMgd3Jvbmc6CiAgICAgICAgICAgICAgIFNlcGFyYXRlIHNwZWN1bGFyIGNvbG9yIG1lYW5zIHRoZSBzcGVjdWxhciBjb2xvdXIgaXMgbWFpbnRhaW5lZCBzZXBhcmF0ZWx5LCB3aGVyZWFzCiAgICAgICAgICAgICAgIHNpbmdsZSBjb2xvciBtZWFucyBpdCBpcyBtZXJnZWQgaW4uIEhvd2V2ZXIgaW4gYm90aCBjYXNlcyB0aGV5IGFyZSBiZWluZyB1c2VkIHRvCiAgICAgICAgICAgICAgIHNvbWUgZXh0ZW50LgogICAgICAgICAgICAgICBUbyBkaXNhYmxlIHNwZWN1bGFyIGNvbG9yLCBzZXQgaXQgZXhwbGljaXRseSB0byBibGFjayBhbmQgdHVybiBvZmYgR0xfQ09MT1JfU1VNX0VYVAogICAgICAgICAgICAgICBOT1RFOiBJZiBub3Qgc3VwcG9ydGVkIGRvbid0IGdpdmUgRklYTUVzIHRoZSBpbXBhY3QgaXMgcmVhbGx5IG1pbmltYWwgYW5kIHZlcnkgZmV3IHBlb3BsZSBhcmUKICAgICAgICAgICAgICAgICAgcnVubmluZyAxLjQgeWV0IQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgICBpZiAoVmFsdWUpIHsKICAgICAgICAgICAgICAgIGdsTWF0ZXJpYWxmdihHTF9GUk9OVF9BTkRfQkFDSywgR0xfU1BFQ1VMQVIsIChmbG9hdCopICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5tYXRlcmlhbC5TcGVjdWxhcik7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xNYXRlcmlhbGZ2Iik7CiAgICAgICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChFWFRfU0VDT05EQVJZX0NPTE9SKSkgewogICAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9DT0xPUl9TVU1fRVhUKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIFRSQUNFKCJTcGVjdWxhciBjb2xvcnMgY2Fubm90IGJlIGVuYWJsZWQgaW4gdGhpcyB2ZXJzaW9uIG9mIG9wZW5nbFxuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfQ09MT1JfU1VNKSIpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmbG9hdCBibGFja1s0XSA9IHswLjBmLCAwLjBmLCAwLjBmLCAwLjBmfTsKCiAgICAgICAgICAgICAgICAvKiBmb3IgdGhlIGNhc2Ugb2YgZW5hYmxlZCBsaWdodGluZzogKi8KICAgICAgICAgICAgICAgIGdsTWF0ZXJpYWxmdihHTF9GUk9OVF9BTkRfQkFDSywgR0xfU1BFQ1VMQVIsICZibGFja1swXSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xNYXRlcmlhbGZ2Iik7CgogICAgICAgICAgICAgICAgLyogZm9yIHRoZSBjYXNlIG9mIGRpc2FibGVkIGxpZ2h0aW5nOiAqLwogICAgICAgICAgICAgICAgaWYgKEdMX1NVUFBPUlQoRVhUX1NFQ09OREFSWV9DT0xPUikpIHsKICAgICAgICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0NPTE9SX1NVTV9FWFQpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgVFJBQ0UoIlNwZWN1bGFyIGNvbG9ycyBjYW5ub3QgYmUgZGlzYWJsZWQgaW4gdGhpcyB2ZXJzaW9uIG9mIG9wZW5nbFxuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKEdMX0NPTE9SX1NVTSkiKTsKICAgICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFJTX1NURU5DSUxFTkFCTEUgICAgICAgICAgICAgOgogICAgICAgIGlmIChWYWx1ZSkgewogICAgICAgICAgICBnbEVuYWJsZShHTF9TVEVOQ0lMX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfU1RFTkNJTF9URVNUIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1NURU5DSUxfVEVTVCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfU1RFTkNJTF9URVNUIik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFJTX1NURU5DSUxGVU5DIDoKICAgIHsKICAgICAgICBHTGludCBmdW5jOwogICAgICAgIEdMaW50IHJlZiA9IFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TVEVOQ0lMUkVGXTsKICAgICAgICBHTHVpbnQgbWFzayA9IFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TVEVOQ0lMTUFTS107CgogICAgICAgIGZ1bmMgPSBHTF9BTFdBWVM7CiAgICAgICAgc3dpdGNoICgoRDNEQ01QRlVOQylWYWx1ZSkgewogICAgICAgICAgICBjYXNlIEQzRENNUF9ORVZFUjogZnVuYyA9IEdMX05FVkVSOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RDTVBfTEVTUzogZnVuYyA9IEdMX0xFU1M7IGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRENNUF9FUVVBTDogZnVuYyA9IEdMX0VRVUFMOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RDTVBfTEVTU0VRVUFMOiBmdW5jID0gR0xfTEVRVUFMOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RDTVBfR1JFQVRFUjogZnVuYyA9IEdMX0dSRUFURVI7IGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRENNUF9OT1RFUVVBTDogZnVuYyA9IEdMX05PVEVRVUFMOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RDTVBfR1JFQVRFUkVRVUFMOiBmdW5jID0gR0xfR0VRVUFMOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RDTVBfQUxXQVlTOiBmdW5jID0gR0xfQUxXQVlTOyBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIEZJWE1FKCJVbnJlY29nbml6ZWQvVW5oYW5kbGVkIEQzRENNUEZVTkMgdmFsdWUgJWxkXG4iLCBWYWx1ZSk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPnN0ZW5jaWxmdW5jID0gZnVuYzsKICAgICAgICBpZighVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1RXT1NJREVEU1RFTkNJTE1PREVdKSB7CiNpZiAwIC8qIERvbid0IHVzZSBPcGVuR0wgMi4wIGNhbGxzIGZvciBub3cgKi8KICAgICAgICAgICAgaWYoR0xfRVhUQ0FMTChnbFN0ZW5jaWxGdW5jU2VwYXJhdGUpKSB7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsU3RlbmNpbEZ1bmNTZXBhcmF0ZShHTF9GUk9OVCwgZnVuYywgcmVmLCBtYXNrKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xTdGVuY2lsRnVuY1NlcGFyYXRlKEdMX0ZST05ULC4uLikiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiNlbmRpZgoJICAgIGlmKEdMX1NVUFBPUlQoRVhUX1NURU5DSUxfVFdPX1NJREUpKSB7CiAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9TVEVOQ0lMX1RFU1RfVFdPX1NJREVfRVhUKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9TVEVOQ0lMX1RFU1RfVFdPX1NJREVfRVhUKSIpOwogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEFjdGl2ZVN0ZW5jaWxGYWNlRVhUKEdMX0ZST05UKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xBY3RpdmVTdGVuY2lsRmFjZUVYVChHTF9GUk9OVCkiKTsKICAgICAgICAgICAgICAgIGdsU3RlbmNpbEZ1bmMoZnVuYywgcmVmLCBtYXNrKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFN0ZW5jaWxGdW5jKC4uLikiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKEdMX1NVUFBPUlQoQVRJX1NFUEFSQVRFX1NURU5DSUwpKSB7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsU3RlbmNpbEZ1bmNTZXBhcmF0ZUFUSShHTF9GUk9OVCwgZnVuYywgcmVmLCBtYXNrKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xTdGVuY2lsRnVuY1NlcGFyYXRlQVRJKEdMX0ZST05ULC4uLikiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJTZXBhcmF0ZSBzdGVuY2lsIGZ1bmN0aW9uIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyB2ZXJzaW9uIG9mIG9wZW5nbCIpOwogICAgICAgICAgICAgICAgZ2xTdGVuY2lsRnVuYyhmdW5jLCByZWYsIG1hc2spOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsU3RlbmNpbEZ1bmMoLi4uKSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xTdGVuY2lsRnVuYyhmdW5jLCByZWYsIG1hc2spOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xTdGVuY2lsRnVuYyguLi4pIik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgY2FzZSBXSU5FRDNEUlNfU1RFTkNJTFJFRiAgICAgICAgICAgICAgICA6CiAgICAgICAgewogICAgICAgICAgIGludCBnbFBhcm0gPSBUaGlzLT5zdGVuY2lsZnVuYzsKICAgICAgICAgICBpbnQgcmVmID0gMDsKICAgICAgICAgICBHTHVpbnQgbWFzayA9IFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TVEVOQ0lMTUFTS107CgogICAgICAgICAgIHJlZiA9IFZhbHVlOwogICAgICAgICAgIFRSQUNFKCJnbFN0ZW5jaWxGdW5jIHdpdGggUGFybT0leCwgcmVmPSVkLCBtYXNrPSV4XG4iLCBnbFBhcm0sIHJlZiwgbWFzayk7CiAgICAgICAgICAgZ2xTdGVuY2lsRnVuYyhnbFBhcm0sIHJlZiwgbWFzayk7CiAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsU3RlbmNpbEZ1bmMiKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUlNfU1RFTkNJTE1BU0sgICAgICAgICAgICAgICA6CiAgICAgICAgewogICAgICAgICAgIGludCBnbFBhcm0gPSBUaGlzLT5zdGVuY2lsZnVuYzsKICAgICAgICAgICBpbnQgcmVmID0gVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1NURU5DSUxSRUZdOwogICAgICAgICAgIEdMdWludCBtYXNrID0gVmFsdWU7CgogICAgICAgICAgIFRSQUNFKCJnbFN0ZW5jaWxGdW5jIHdpdGggUGFybT0leCwgcmVmPSVkLCBtYXNrPSV4XG4iLCBnbFBhcm0sIHJlZiwgbWFzayk7CiAgICAgICAgICAgZ2xTdGVuY2lsRnVuYyhnbFBhcm0sIHJlZiwgbWFzayk7CiAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsU3RlbmNpbEZ1bmMiKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUlNfU1RFTkNJTEZBSUwgICAgICAgICAgICAgICA6CiAgICBjYXNlIFdJTkVEM0RSU19TVEVOQ0lMWkZBSUwgICAgICAgICAgICAgIDoKICAgIGNhc2UgV0lORUQzRFJTX1NURU5DSUxQQVNTICAgICAgICAgICAgICAgOgogICAgewogICAgICAgIEdMaW50IHN0ZW5jaWxGYWlsOwogICAgICAgIEdMaW50IGRlcHRoRmFpbDsKICAgICAgICBHTGludCBzdGVuY2lsUGFzczsKCiAgICAgICAgR0xpbnQgYWN0aW9uID0gU3RlbmNpbE9wKFZhbHVlKTsKCiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9TVEVOQ0lMX0ZBSUwsICZzdGVuY2lsRmFpbCk7CiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9TVEVOQ0lMX1BBU1NfREVQVEhfRkFJTCwgJmRlcHRoRmFpbCk7CiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9TVEVOQ0lMX1BBU1NfREVQVEhfUEFTUywgJnN0ZW5jaWxQYXNzKTsKCiAgICAgICAgaWYoV0lORUQzRFJTX1NURU5DSUxGQUlMID09IFN0YXRlKSB7CiAgICAgICAgICAgIHN0ZW5jaWxGYWlsID0gYWN0aW9uOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKFdJTkVEM0RSU19TVEVOQ0lMWkZBSUwgPT0gU3RhdGUpIHsKICAgICAgICAgICAgZGVwdGhGYWlsID0gYWN0aW9uOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKFdJTkVEM0RSU19TVEVOQ0lMUEFTUyA9PSBTdGF0ZSkgewogICAgICAgICAgICBzdGVuY2lsUGFzcyA9IGFjdGlvbjsKICAgICAgICB9CgogICAgICAgIGlmKCFUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfVFdPU0lERURTVEVOQ0lMTU9ERV0pIHsKI2lmIDAgLyogRG9uJ3QgdXNlIE9wZW5HTCAyLjAgY2FsbHMgZm9yIG5vdyAqLwogICAgICAgICAgICBpZihHTF9FWFRDQUxMKGdsU3RlbmNpbE9wU2VwYXJhdGUpKSB7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsU3RlbmNpbE9wU2VwYXJhdGUoR0xfRlJPTlQsIHN0ZW5jaWxGYWlsLCBkZXB0aEZhaWwsIHN0ZW5jaWxQYXNzKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xTdGVuY2lsT3BTZXBhcmF0ZShHTF9GUk9OVCwuLi4pIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQojZW5kaWYKCSAgICBpZihHTF9TVVBQT1JUKEVYVF9TVEVOQ0lMX1RXT19TSURFKSkgewogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfU1RFTkNJTF9URVNUX1RXT19TSURFX0VYVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfU1RFTkNJTF9URVNUX1RXT19TSURFX0VYVCkiKTsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVTdGVuY2lsRmFjZUVYVChHTF9GUk9OVCkpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQWN0aXZlU3RlbmNpbEZhY2VFWFQoR0xfRlJPTlQpIik7CiAgICAgICAgICAgICAgICBnbFN0ZW5jaWxPcChzdGVuY2lsRmFpbCwgZGVwdGhGYWlsLCBzdGVuY2lsUGFzcyk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xTdGVuY2lsT3AoLi4uKSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYoR0xfU1VQUE9SVChBVElfU0VQQVJBVEVfU1RFTkNJTCkpIHsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xTdGVuY2lsT3BTZXBhcmF0ZUFUSShHTF9GUk9OVCwgc3RlbmNpbEZhaWwsIGRlcHRoRmFpbCwgc3RlbmNpbFBhc3MpKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFN0ZW5jaWxPcFNlcGFyYXRlQVRJKEdMX0ZST05ULC4uLikiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJTZXBhcmF0ZSBzdGVuY2lsIG9wZXJhdGlvbiBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgdmVyc2lvbiBvZiBvcGVuZ2wiKTsKICAgICAgICAgICAgICAgIGdsU3RlbmNpbE9wKHN0ZW5jaWxGYWlsLCBkZXB0aEZhaWwsIHN0ZW5jaWxQYXNzKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFN0ZW5jaWxPcCguLi4pIik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBnbFN0ZW5jaWxPcChzdGVuY2lsRmFpbCwgZGVwdGhGYWlsLCBzdGVuY2lsUGFzcyk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFN0ZW5jaWxPcCguLi4pIik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgY2FzZSBXSU5FRDNEUlNfU1RFTkNJTFdSSVRFTUFTSyAgICAgICAgICA6CiAgICAgICAgewogICAgICAgICAgICBnbFN0ZW5jaWxNYXNrKFZhbHVlKTsKICAgICAgICAgICAgVFJBQ0UoImdsU3RlbmNpbE1hc2soJWx1KVxuIiwgVmFsdWUpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xTdGVuY2lsTWFzayIpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19GT0dFTkFCTEUgICAgICAgICAgICAgICAgIDoKICAgICAgICB7CiAgICAgICAgICBpZiAoVmFsdWUvKiAmJiBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfRk9HVEFCTEVNT0RFXSAhPSBEM0RGT0dfTk9ORSovKSB7CiAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX0ZPRyk7CiAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9GT0ciKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0ZPRyk7CiAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfRk9HIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUlNfUkFOR0VGT0dFTkFCTEUgICAgICAgICAgICA6CiAgICAgICAgewogICAgICAgICAgICBpZiAoVmFsdWUpIHsKICAgICAgICAgICAgICBUUkFDRSgiRW5hYmxlZCBSQU5HRUZPRyIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIFRSQUNFKCJEaXNhYmxlZCBSQU5HRUZPRyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFJTX0ZPR0NPTE9SICAgICAgICAgICAgICAgICAgOgogICAgICAgIHsKICAgICAgICAgICAgZmxvYXQgY29sWzRdOwogICAgICAgICAgICBEM0RDT0xPUlRPR0xGTE9BVDQoVmFsdWUsIGNvbCk7CiAgICAgICAgICAgIC8qIFNldCB0aGUgZGVmYXVsdCBhbHBoYSBibGVuZCBjb2xvciAqLwogICAgICAgICAgICBnbEZvZ2Z2KEdMX0ZPR19DT0xPUiwgJmNvbFswXSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEZvZyBHTF9GT0dfQ09MT1IiKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUlNfRk9HVEFCTEVNT0RFICAgICAgICAgICAgICA6CiAgICAgICAgewogICAgICAgICAgZ2xIaW50KEdMX0ZPR19ISU5ULCBHTF9OSUNFU1QpOwogICAgICAgICAgc3dpdGNoIChWYWx1ZSkgewogICAgICAgICAgY2FzZSBEM0RGT0dfTk9ORTogICAgLyogSSBkb24ndCBrbm93IHdoYXQgdG8gZG8gaGVyZSAqLyBjaGVja0dMY2FsbCgiZ2xGb2dpKEdMX0ZPR19NT0RFLCBHTF9FWFAiKTsgYnJlYWs7CiAgICAgICAgICBjYXNlIEQzREZPR19FWFA6ICAgICBnbEZvZ2koR0xfRk9HX01PREUsIEdMX0VYUCk7IGNoZWNrR0xjYWxsKCJnbEZvZ2koR0xfRk9HX01PREUsIEdMX0VYUCIpOyBicmVhazsKICAgICAgICAgIGNhc2UgRDNERk9HX0VYUDI6ICAgIGdsRm9naShHTF9GT0dfTU9ERSwgR0xfRVhQMik7IGNoZWNrR0xjYWxsKCJnbEZvZ2koR0xfRk9HX01PREUsIEdMX0VYUDIiKTsgYnJlYWs7CiAgICAgICAgICBjYXNlIEQzREZPR19MSU5FQVI6ICBnbEZvZ2koR0xfRk9HX01PREUsIEdMX0xJTkVBUik7IGNoZWNrR0xjYWxsKCJnbEZvZ2koR0xfRk9HX01PREUsIEdMX0xJTkVBUiIpOyBicmVhazsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCBWYWx1ZSglbHUpIGZvciBXSU5FRDNEUlNfRk9HVEFCTEVNT0RFIVxuIiwgVmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKEdMX1NVUFBPUlQoTlZfRk9HX0RJU1RBTkNFKSkgewogICAgICAgICAgICBnbEZvZ2koR0xfRk9HX0RJU1RBTkNFX01PREVfTlYsIEdMX0VZRV9QTEFORV9BQlNPTFVURV9OVik7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFJTX0ZPR1ZFUlRFWE1PREUgICAgICAgICAgICAgOgogICAgICAgIHsKICAgICAgICAgIGdsSGludChHTF9GT0dfSElOVCwgR0xfRkFTVEVTVCk7CiAgICAgICAgICBzd2l0Y2ggKFZhbHVlKSB7CiAgICAgICAgICBjYXNlIEQzREZPR19OT05FOiAgICAvKiBJIGRvbid0IGtub3cgd2hhdCB0byBkbyBoZXJlICovIGNoZWNrR0xjYWxsKCJnbEZvZ2koR0xfRk9HX01PREUsIEdMX0VYUCIpOyBicmVhazsKICAgICAgICAgIGNhc2UgRDNERk9HX0VYUDogICAgIGdsRm9naShHTF9GT0dfTU9ERSwgR0xfRVhQKTsgY2hlY2tHTGNhbGwoImdsRm9naShHTF9GT0dfTU9ERSwgR0xfRVhQIik7IGJyZWFrOwogICAgICAgICAgY2FzZSBEM0RGT0dfRVhQMjogICAgZ2xGb2dpKEdMX0ZPR19NT0RFLCBHTF9FWFAyKTsgY2hlY2tHTGNhbGwoImdsRm9naShHTF9GT0dfTU9ERSwgR0xfRVhQMiIpOyBicmVhazsKICAgICAgICAgIGNhc2UgRDNERk9HX0xJTkVBUjogIGdsRm9naShHTF9GT0dfTU9ERSwgR0xfTElORUFSKTsgY2hlY2tHTGNhbGwoImdsRm9naShHTF9GT0dfTU9ERSwgR0xfTElORUFSIik7IGJyZWFrOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIFZhbHVlKCVsdSkgZm9yIFdJTkVEM0RSU19GT0dUQUJMRU1PREUhXG4iLCBWYWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoR0xfU1VQUE9SVChOVl9GT0dfRElTVEFOQ0UpKSB7CiAgICAgICAgICAgIGdsRm9naShHTF9GT0dfRElTVEFOQ0VfTU9ERV9OViwgVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1JBTkdFRk9HRU5BQkxFXSA/IEdMX0VZRV9SQURJQUxfTlYgOiBHTF9FWUVfUExBTkVfQUJTT0xVVEVfTlYpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19GT0dTVEFSVCAgICAgICAgICAgICAgICAgIDoKICAgICAgICB7CiAgICAgICAgICAgIHRtcHZhbHVlLmQgPSBWYWx1ZTsKICAgICAgICAgICAgZ2xGb2dmdihHTF9GT0dfU1RBUlQsICZ0bXB2YWx1ZS5mKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRm9nZihHTF9GT0dfU1RBUlQsIChmbG9hdCkgVmFsdWUpIik7CiAgICAgICAgICAgIFRSQUNFKCJGb2cgU3RhcnQgPT0gJWZcbiIsIHRtcHZhbHVlLmYpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19GT0dFTkQgICAgICAgICAgICAgICAgICAgIDoKICAgICAgICB7CiAgICAgICAgICAgIHRtcHZhbHVlLmQgPSBWYWx1ZTsKICAgICAgICAgICAgZ2xGb2dmdihHTF9GT0dfRU5ELCAmdG1wdmFsdWUuZik7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEZvZ2YoR0xfRk9HX0VORCwgKGZsb2F0KSBWYWx1ZSkiKTsKICAgICAgICAgICAgVFJBQ0UoIkZvZyBFbmQgPT0gJWZcbiIsIHRtcHZhbHVlLmYpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19GT0dERU5TSVRZICAgICAgICAgICAgICAgIDoKICAgICAgICB7CiAgICAgICAgICAgIHRtcHZhbHVlLmQgPSBWYWx1ZTsKICAgICAgICAgICAgZ2xGb2dmdihHTF9GT0dfREVOU0lUWSwgJnRtcHZhbHVlLmYpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xGb2dmKEdMX0ZPR19ERU5TSVRZLCAoZmxvYXQpIFZhbHVlKSIpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19WRVJURVhCTEVORCAgICAgICAgICAgICAgIDoKICAgICAgICB7CiAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhfYmxlbmQgPSAoRDNEVkVSVEVYQkxFTkRGTEFHUykgVmFsdWU7CiAgICAgICAgICBUUkFDRSgiVmVydGV4IEJsZW5kaW5nIHN0YXRlIHRvICVsZFxuIiwgIFZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUlNfVFdFRU5GQUNUT1IgICAgICAgICAgICAgICA6CiAgICAgICAgewogICAgICAgICAgdG1wdmFsdWUuZCA9IFZhbHVlOwogICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dHdlZW5fZmFjdG9yID0gdG1wdmFsdWUuZjsKICAgICAgICAgIFRSQUNFKCJWZXJ0ZXggQmxlbmRpbmcgVHdlZW4gRmFjdG9yIHRvICVmXG4iLCBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50d2Vlbl9mYWN0b3IpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19JTkRFWEVEVkVSVEVYQkxFTkRFTkFCTEUgIDoKICAgICAgICB7CiAgICAgICAgICBUUkFDRSgiSW5kZXhlZCBWZXJ0ZXggQmxlbmQgRW5hYmxlIHRvICV1bFxuIiwgKEJPT0wpIFZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUlNfQ09MT1JWRVJURVggICAgICAgICAgICAgICA6CiAgICBjYXNlIFdJTkVEM0RSU19ESUZGVVNFTUFURVJJQUxTT1VSQ0UgICAgIDoKICAgIGNhc2UgV0lORUQzRFJTX1NQRUNVTEFSTUFURVJJQUxTT1VSQ0UgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfQU1CSUVOVE1BVEVSSUFMU09VUkNFICAgICA6CiAgICBjYXNlIFdJTkVEM0RSU19FTUlTU0lWRU1BVEVSSUFMU09VUkNFICAgIDoKICAgICAgICB7CiAgICAgICAgICAgIEdMZW51bSBQYXJtID0gR0xfQU1CSUVOVF9BTkRfRElGRlVTRTsKCiAgICAgICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfQ09MT1JWRVJURVhdKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiZGlmZiAlbGQsIGFtYiAlbGQsIGVtaXMgJWxkLCBzcGVjICVsZFxuIiwKICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19ESUZGVVNFTUFURVJJQUxTT1VSQ0VdLAogICAgICAgICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX0FNQklFTlRNQVRFUklBTFNPVVJDRV0sCiAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfRU1JU1NJVkVNQVRFUklBTFNPVVJDRV0sCiAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfU1BFQ1VMQVJNQVRFUklBTFNPVVJDRV0pOwoKICAgICAgICAgICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfRElGRlVTRU1BVEVSSUFMU09VUkNFXSA9PSBEM0RNQ1NfQ09MT1IxKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19BTUJJRU5UTUFURVJJQUxTT1VSQ0VdID09IEQzRE1DU19DT0xPUjEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgUGFybSA9IEdMX0FNQklFTlRfQU5EX0RJRkZVU0U7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgUGFybSA9IEdMX0RJRkZVU0U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfQU1CSUVOVE1BVEVSSUFMU09VUkNFXSA9PSBEM0RNQ1NfQ09MT1IxKSB7CiAgICAgICAgICAgICAgICAgICAgUGFybSA9IEdMX0FNQklFTlQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19FTUlTU0lWRU1BVEVSSUFMU09VUkNFXSA9PSBEM0RNQ1NfQ09MT1IxKSB7CiAgICAgICAgICAgICAgICAgICAgUGFybSA9IEdMX0VNSVNTSU9OOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfU1BFQ1VMQVJNQVRFUklBTFNPVVJDRV0gPT0gRDNETUNTX0NPTE9SMSkgewogICAgICAgICAgICAgICAgICAgIFBhcm0gPSBHTF9TUEVDVUxBUjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgUGFybSA9IC0xOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChQYXJtID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKFRoaXMtPnRyYWNraW5nX2NvbG9yICE9IERJU0FCTEVEX1RSQUNLSU5HKSBUaGlzLT50cmFja2luZ19jb2xvciA9IE5FRURTX0RJU0FCTEU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIFRoaXMtPnRyYWNraW5nX2NvbG9yID0gTkVFRFNfVFJBQ0tJTkc7CiAgICAgICAgICAgICAgICAgICAgVGhpcy0+dHJhY2tpbmdfcGFybSAgPSBQYXJtOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChUaGlzLT50cmFja2luZ19jb2xvciAhPSBESVNBQkxFRF9UUkFDS0lORykgVGhpcy0+dHJhY2tpbmdfY29sb3IgPSBORUVEU19ESVNBQkxFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFJTX0xJTkVQQVRURVJOICAgICAgICAgICAgICAgOgogICAgICAgIHsKICAgICAgICAgICAgdW5pb24gewogICAgICAgICAgICAgICAgRFdPUkQgICAgICAgICAgICAgICAgIGQ7CiAgICAgICAgICAgICAgICBEM0RMSU5FUEFUVEVSTiAgICAgICAgbHA7CiAgICAgICAgICAgIH0gdG1wcGF0dGVybjsKICAgICAgICAgICAgdG1wcGF0dGVybi5kID0gVmFsdWU7CgogICAgICAgICAgICBUUkFDRSgiTGluZSBwYXR0ZXJuOiByZXBlYXQgJWQgYml0cyAleFxuIiwgdG1wcGF0dGVybi5scC53UmVwZWF0RmFjdG9yLCB0bXBwYXR0ZXJuLmxwLndMaW5lUGF0dGVybik7CgogICAgICAgICAgICBpZiAodG1wcGF0dGVybi5scC53UmVwZWF0RmFjdG9yKSB7CiAgICAgICAgICAgICAgICBnbExpbmVTdGlwcGxlKHRtcHBhdHRlcm4ubHAud1JlcGVhdEZhY3RvciwgdG1wcGF0dGVybi5scC53TGluZVBhdHRlcm4pOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsTGluZVN0aXBwbGUocmVwZWF0LCBsaW5lcGF0dGVybikiKTsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX0xJTkVfU1RJUFBMRSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfTElORV9TVElQUExFKTsiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGdsRGlzYWJsZShHTF9MSU5FX1NUSVBQTEUpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9MSU5FX1NUSVBQTEUpOyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFJTX1pCSUFTICAgICAgICAgICAgICAgICAgICAgOiAvKiBEM0Q4IG9ubHkgKi8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChWYWx1ZSkgewogICAgICAgICAgICAgICAgdG1wdmFsdWUuZCA9IFZhbHVlOwogICAgICAgICAgICAgICAgVFJBQ0UoIlpCaWFzIHZhbHVlICVmXG4iLCB0bXB2YWx1ZS5mKTsKICAgICAgICAgICAgICAgIGdsUG9seWdvbk9mZnNldCgwLCAtdG1wdmFsdWUuZik7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xQb2x5Z29uT2Zmc2V0KDAsIC1WYWx1ZSkiKTsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX1BPTFlHT05fT0ZGU0VUX0ZJTEwpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1BPTFlHT05fT0ZGU0VUX0ZJTEwpOyIpOwogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfUE9MWUdPTl9PRkZTRVRfTElORSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfUE9MWUdPTl9PRkZTRVRfTElORSk7Iik7CiAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9QT0xZR09OX09GRlNFVF9QT0lOVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfUE9MWUdPTl9PRkZTRVRfUE9JTlQpOyIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1BPTFlHT05fT0ZGU0VUX0ZJTEwpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9QT0xZR09OX09GRlNFVF9GSUxMKTsiKTsKICAgICAgICAgICAgICAgIGdsRGlzYWJsZShHTF9QT0xZR09OX09GRlNFVF9MSU5FKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUoR0xfUE9MWUdPTl9PRkZTRVRfTElORSk7Iik7CiAgICAgICAgICAgICAgICBnbERpc2FibGUoR0xfUE9MWUdPTl9PRkZTRVRfUE9JTlQpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9QT0xZR09OX09GRlNFVF9QT0lOVCk7Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUlNfTk9STUFMSVpFTk9STUFMUyAgICAgICAgICA6CiAgICAgICAgaWYgKFZhbHVlKSB7CiAgICAgICAgICAgIGdsRW5hYmxlKEdMX05PUk1BTElaRSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9OT1JNQUxJWkUpOyIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9OT1JNQUxJWkUpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKEdMX05PUk1BTElaRSk7Iik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFJTX1BPSU5UU0laRSAgICAgICAgICAgICAgICAgOgogICAgICAgIC8qIEZJWE1FOiBjaGVjayB0aGF0IHBvaW50U2l6ZSBpc24ndCBvdXRzaWRlIGdsR2V0RmxvYXR2KCBHTF9QT0lOVF9TSVpFX01BWF9BUkIsICZtYXhTaXplICk7IG9yIC12ZSAqLwogICAgICAgIHRtcHZhbHVlLmQgPSBWYWx1ZTsKICAgICAgICBUUkFDRSgiU2V0IHBvaW50IHNpemUgdG8gJWZcbiIsIHRtcHZhbHVlLmYpOwogICAgICAgIGdsUG9pbnRTaXplKHRtcHZhbHVlLmYpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFBvaW50U2l6ZSguLi4pOyIpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFJTX1BPSU5UU0laRV9NSU4gICAgICAgICAgICAgOgogICAgICAgIGlmIChHTF9TVVBQT1JUKEVYVF9QT0lOVF9QQVJBTUVURVJTKSkgewogICAgICAgICAgdG1wdmFsdWUuZCA9IFZhbHVlOwogICAgICAgICAgR0xfRVhUQ0FMTChnbFBvaW50UGFyYW1ldGVyZkVYVCkoR0xfUE9JTlRfU0laRV9NSU5fRVhULCB0bXB2YWx1ZS5mKTsKICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFBvaW50UGFyYW1ldGVyZkVYVCguLi4pOyIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBGSVhNRSgiV0lORUQzRFJTX1BPSU5UU0laRV9NSU4gbm90IHN1cHBvcnRlZCBvbiB0aGlzIG9wZW5nbFxuIik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFJTX1BPSU5UU0laRV9NQVggICAgICAgICAgICAgOgogICAgICAgIGlmIChHTF9TVVBQT1JUKEVYVF9QT0lOVF9QQVJBTUVURVJTKSkgewogICAgICAgICAgdG1wdmFsdWUuZCA9IFZhbHVlOwogICAgICAgICAgR0xfRVhUQ0FMTChnbFBvaW50UGFyYW1ldGVyZkVYVCkoR0xfUE9JTlRfU0laRV9NQVhfRVhULCB0bXB2YWx1ZS5mKTsKICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFBvaW50UGFyYW1ldGVyZkVYVCguLi4pOyIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBGSVhNRSgiV0lORUQzRFJTX1BPSU5UU0laRV9NQVggbm90IHN1cHBvcnRlZCBvbiB0aGlzIG9wZW5nbFxuIik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFJTX1BPSU5UU0NBTEVfQSAgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfUE9JTlRTQ0FMRV9CICAgICAgICAgICAgICA6CiAgICBjYXNlIFdJTkVEM0RSU19QT0lOVFNDQUxFX0MgICAgICAgICAgICAgIDoKICAgIGNhc2UgV0lORUQzRFJTX1BPSU5UU0NBTEVFTkFCTEUgICAgICAgICAgOgogICAgewogICAgICAgIC8qCiAgICAgICAgICogUE9JTlRTQ0FMRUVOQUJMRSBjb250cm9scyBob3cgcG9pbnQgc2l6ZSB2YWx1ZSBpcyB0cmVhdGVkLiBJZiBzZXQgdG8KICAgICAgICAgKiB0cnVlLCB0aGUgcG9pbnQgc2l6ZSBpcyBzY2FsZWQgd2l0aCByZXNwZWN0IHRvIGhlaWdodCBvZiB2aWV3cG9ydC4KICAgICAgICAgKiBXaGVuIHNldCB0byBmYWxzZSBwb2ludCBzaXplIGlzIGluIHBpeGVscy4KICAgICAgICAgKgogICAgICAgICAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9lbi11cy9kaXJlY3R4OV9jL3BvaW50X3Nwcml0ZXMuYXNwCiAgICAgICAgICovCgogICAgICAgIC8qIERlZmF1bHQgdmFsdWVzICovCiAgICAgICAgR0xmbG9hdCBhdHRbM10gPSB7MS4wZiwgMC4wZiwgMC4wZn07CgogICAgICAgIC8qCiAgICAgICAgICogTWluaW11bSB2YWxpZCBwb2ludCBzaXplIGZvciBPcGVuR0wgaXMgMS4wZi4gRm9yIERpcmVjdDNEIGl0IGlzIDAuMGYuCiAgICAgICAgICogVGhpcyBtZWFucyB0aGF0IE9wZW5HTCB3aWxsIGNsYW1wIHJlYWxseSBzbWFsbCBwb2ludCBzaXplcyB0byAxLjBmLgogICAgICAgICAqIFRvIGNvcnJlY3QgZm9yIHRoaXMgd2UgbmVlZCB0byBtdWx0aXBseSBieSB0aGUgc2NhbGUgZmFjdG9yIHdoZW4gc2l6ZXMKICAgICAgICAgKiBhcmUgbGVzcyB0aGFuIDEuMGYuIHNjYWxlX2ZhY3RvciA9ICAxLjBmIC8gcG9pbnRfc2l6ZS4KICAgICAgICAgKi8KICAgICAgICBHTGZsb2F0IHBvaW50U2l6ZSA9ICooKGZsb2F0KikmVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1BPSU5UU0laRV0pOwogICAgICAgIGlmKHBvaW50U2l6ZSA+IDAuMGYpIHsKICAgICAgICAgICAgR0xmbG9hdCBzY2FsZUZhY3RvcjsKCiAgICAgICAgICAgIGlmKHBvaW50U2l6ZSA8IDEuMGYpIHsKICAgICAgICAgICAgICAgIHNjYWxlRmFjdG9yID0gcG9pbnRTaXplICogcG9pbnRTaXplOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2NhbGVGYWN0b3IgPSAxLjBmOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfUE9JTlRTQ0FMRUVOQUJMRV0pIHsKICAgICAgICAgICAgICAgIGF0dFswXSA9ICooKGZsb2F0KikmVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1BPSU5UU0NBTEVfQV0pIC8KICAgICAgICAgICAgICAgICAgICAoVGhpcy0+c3RhdGVCbG9jay0+dmlld3BvcnQuSGVpZ2h0ICogVGhpcy0+c3RhdGVCbG9jay0+dmlld3BvcnQuSGVpZ2h0ICogc2NhbGVGYWN0b3IpOwogICAgICAgICAgICAgICAgYXR0WzFdID0gKigoZmxvYXQqKSZUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfUE9JTlRTQ0FMRV9CXSkgLwogICAgICAgICAgICAgICAgICAgIChUaGlzLT5zdGF0ZUJsb2NrLT52aWV3cG9ydC5IZWlnaHQgKiBUaGlzLT5zdGF0ZUJsb2NrLT52aWV3cG9ydC5IZWlnaHQgKiBzY2FsZUZhY3Rvcik7CiAgICAgICAgICAgICAgICBhdHRbMl0gPSAqKChmbG9hdCopJlRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19QT0lOVFNDQUxFX0NdKSAvCiAgICAgICAgICAgICAgICAgICAgKFRoaXMtPnN0YXRlQmxvY2stPnZpZXdwb3J0LkhlaWdodCAqIFRoaXMtPnN0YXRlQmxvY2stPnZpZXdwb3J0LkhlaWdodCAqIHNjYWxlRmFjdG9yKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYoR0xfU1VQUE9SVChBUkJfUE9JTlRfUEFSQU1FVEVSUykpIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFBvaW50UGFyYW1ldGVyZnZBUkIpKEdMX1BPSU5UX0RJU1RBTkNFX0FUVEVOVUFUSU9OX0FSQiwgYXR0KTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsUG9pbnRQYXJhbWV0ZXJmdkFSQihHTF9ESVNUQU5DRV9BVFRFTlVBVElPTl9BUkIsIC4uLiIpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKEdMX1NVUFBPUlQoRVhUX1BPSU5UX1BBUkFNRVRFUlMpKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xQb2ludFBhcmFtZXRlcmZ2RVhUKShHTF9ESVNUQU5DRV9BVFRFTlVBVElPTl9FWFQsIGF0dCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFBvaW50UGFyYW1ldGVyZnZFWFQoR0xfRElTVEFOQ0VfQVRURU5VQVRJT05fRVhULCAuLi4iKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBUUkFDRSgiUE9JTlRfUEFSQU1FVEVSUyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgdmVyc2lvbiBvZiBvcGVuZ2xcbiIpOwogICAgICAgIH0KCWJyZWFrOwogICAgfQogICAgY2FzZSBXSU5FRDNEUlNfQ09MT1JXUklURUVOQUJMRSAgICAgICAgICA6CiAgICAgIHsKICAgICAgICBUUkFDRSgiQ29sb3IgbWFzazogciglZCkgZyglZCkgYiglZCkgYSglZClcbiIsCiAgICAgICAgICAgICAgVmFsdWUgJiBEM0RDT0xPUldSSVRFRU5BQkxFX1JFRCAgID8gMSA6IDAsCiAgICAgICAgICAgICAgVmFsdWUgJiBEM0RDT0xPUldSSVRFRU5BQkxFX0dSRUVOID8gMSA6IDAsCiAgICAgICAgICAgICAgVmFsdWUgJiBEM0RDT0xPUldSSVRFRU5BQkxFX0JMVUUgID8gMSA6IDAsCiAgICAgICAgICAgICAgVmFsdWUgJiBEM0RDT0xPUldSSVRFRU5BQkxFX0FMUEhBID8gMSA6IDApOwogICAgICAgIGdsQ29sb3JNYXNrKFZhbHVlICYgRDNEQ09MT1JXUklURUVOQUJMRV9SRUQgICA/IEdMX1RSVUUgOiBHTF9GQUxTRSwKICAgICAgICAgICAgICAgICAgICBWYWx1ZSAmIEQzRENPTE9SV1JJVEVFTkFCTEVfR1JFRU4gPyBHTF9UUlVFIDogR0xfRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgVmFsdWUgJiBEM0RDT0xPUldSSVRFRU5BQkxFX0JMVUUgID8gR0xfVFJVRSA6IEdMX0ZBTFNFLAogICAgICAgICAgICAgICAgICAgIFZhbHVlICYgRDNEQ09MT1JXUklURUVOQUJMRV9BTFBIQSA/IEdMX1RSVUUgOiBHTF9GQUxTRSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQ29sb3JNYXNrKC4uLikiKTsKICAgICAgfQogICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19MT0NBTFZJRVdFUiAgICAgICAgICAgICAgIDoKICAgICAgewogICAgICAgIEdMaW50IHN0YXRlID0gKFZhbHVlKSA/IDEgOiAwOwogICAgICAgIFRSQUNFKCJMb2NhbCBWaWV3ZXIgRW5hYmxlIHRvICV1bFxuIiwgKEJPT0wpIFZhbHVlKTsKICAgICAgICBnbExpZ2h0TW9kZWxpKEdMX0xJR0hUX01PREVMX0xPQ0FMX1ZJRVdFUiwgc3RhdGUpOwogICAgICB9CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFJTX0xBU1RQSVhFTCAgICAgICAgICAgICAgICAgOgogICAgICB7CiAgICAgICAgaWYgKFZhbHVlKSB7CiAgICAgICAgICBUUkFDRSgiTGFzdCBQaXhlbCBEcmF3aW5nIEVuYWJsZWRcbiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBGSVhNRSgiTGFzdCBQaXhlbCBEcmF3aW5nIERpc2FibGVkLCBub3QgaGFuZGxlZCB5ZXRcbiIpOwogICAgICAgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RSU19TT0ZUV0FSRVZFUlRFWFBST0NFU1NJTkcgIDoKICAgICAgewogICAgICAgIGlmIChWYWx1ZSkgewogICAgICAgICAgVFJBQ0UoIlNvZnR3YXJlIFByb2Nlc3NpbmcgRW5hYmxlZFxuIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIFRSQUNFKCJTb2Z0d2FyZSBQcm9jZXNzaW5nIERpc2FibGVkXG4iKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgYnJlYWs7CgogICAgICAvKiogbm90IHN1cHBvcnRlZCAqLwogICAgY2FzZSBXSU5FRDNEUlNfWlZJU0lCTEUgICAgICAgICAgICAgICAgICA6CiAgICAgIHsKICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICB9CiAgICBjYXNlIFdJTkVEM0RSU19QT0lOVFNQUklURUVOQUJMRSAgICAgICAgIDoKICAgIHsKICAgICAgICAvKiBUT0RPOiBOVl9QT0lOVF9TUFJJVEUgKi8KICAgICAgICBpZiAoIUdMX1NVUFBPUlQoQVJCX1BPSU5UX1NQUklURSkpIHsKICAgICAgICAgICAgVFJBQ0UoIlBvaW50IHNwcml0ZXMgbm90IHN1cHBvcnRlZFxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBQb2ludCBzcHJpdGVzIGFyZSBhbHdheXMgZW5hYmxlZC4gVmFsdWUgY29udHJvbHMgdGV4dHVyZSBjb29yZGluYXRlCiAgICAgICAgICogcmVwbGFjZW1lbnQgbW9kZS4gTXVzdCBiZSBzZXQgdHJ1ZSBmb3IgcG9pbnQgc3ByaXRlcyB0byB1c2UKICAgICAgICAgKiB0ZXh0dXJlcy4KICAgICAgICAgKi8KICAgICAgICBnbEVuYWJsZShHTF9QT0lOVF9TUFJJVEVfQVJCKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfUE9JTlRfU1BSSVRFX0FSQikiKTsKCiAgICAgICAgaWYgKFZhbHVlKSB7CiAgICAgICAgICAgIGdsVGV4RW52ZihHTF9QT0lOVF9TUFJJVEVfQVJCLCBHTF9DT09SRF9SRVBMQUNFX0FSQiwgVFJVRSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEVudmYoR0xfUE9JTlRfU1BSSVRFLCBHTF9DT09SRF9SRVBMQUNFLCBUUlVFKSIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsVGV4RW52ZihHTF9QT0lOVF9TUFJJVEVfQVJCLCBHTF9DT09SRF9SRVBMQUNFX0FSQiwgRkFMU0UpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhFbnZmKEdMX1BPSU5UX1NQUklURSwgR0xfQ09PUkRfUkVQTEFDRSwgRkFMU0UpIik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgY2FzZSBXSU5FRDNEUlNfRURHRUFOVElBTElBUyAgICAgICAgICAgICA6CiAgICB7CiAgICAgICAgaWYoVmFsdWUpIHsKICAgICAgICAgICAgZ2xCbGVuZEZ1bmMoR0xfU1JDX0FMUEhBLCBHTF9PTkVfTUlOVVNfU1JDX0FMUEhBKTsKICAgICAgICAgICAgZ2xFbmFibGUoR0xfQkxFTkQpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfQkxFTkQpIik7CiAgICAgICAgICAgIGdsRW5hYmxlKEdMX0xJTkVfU01PT1RIKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX0xJTkVfU01PT1RIKSIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9CTEVORCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUoR0xfQkxFTkQpIik7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9MSU5FX1NNT09USCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUoR0xfTElORV9TTU9PVEgpIik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgY2FzZSBXSU5FRDNEUlNfV1JBUDAgICAgICAgICAgICAgICAgICAgICA6CiAgICBjYXNlIFdJTkVEM0RSU19XUkFQMSAgICAgICAgICAgICAgICAgICAgIDoKICAgIGNhc2UgV0lORUQzRFJTX1dSQVAyICAgICAgICAgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfV1JBUDMgICAgICAgICAgICAgICAgICAgICA6CiAgICBjYXNlIFdJTkVEM0RSU19XUkFQNCAgICAgICAgICAgICAgICAgICAgIDoKICAgIGNhc2UgV0lORUQzRFJTX1dSQVA1ICAgICAgICAgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfV1JBUDYgICAgICAgICAgICAgICAgICAgICA6CiAgICBjYXNlIFdJTkVEM0RSU19XUkFQNyAgICAgICAgICAgICAgICAgICAgIDoKICAgIGNhc2UgV0lORUQzRFJTX1dSQVA4ICAgICAgICAgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfV1JBUDkgICAgICAgICAgICAgICAgICAgICA6CiAgICBjYXNlIFdJTkVEM0RSU19XUkFQMTAgICAgICAgICAgICAgICAgICAgIDoKICAgIGNhc2UgV0lORUQzRFJTX1dSQVAxMSAgICAgICAgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfV1JBUDEyICAgICAgICAgICAgICAgICAgICA6CiAgICBjYXNlIFdJTkVEM0RSU19XUkFQMTMgICAgICAgICAgICAgICAgICAgIDoKICAgIGNhc2UgV0lORUQzRFJTX1dSQVAxNCAgICAgICAgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfV1JBUDE1ICAgICAgICAgICAgICAgICAgICA6CiAgICAvKioKICAgIGh0dHA6Ly93d3cuY29zYy5icm9ja3UuY2EvT2ZmZXJpbmdzLzNQOTgvY291cnNlL2xlY3R1cmVzL3RleHR1cmUvCiAgICBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2FyY2hpdmUvZGVmYXVsdC5hc3A/dXJsPS9hcmNoaXZlL2VuLXVzL2RpcmVjdHg5X2MvZGlyZWN0eC9ncmFwaGljcy9wcm9ncmFtbWluZ2d1aWRlL0ZpeGVkRnVuY3Rpb24vVGV4dHVyZXMvdGV4dHVyZXdyYXBwaW5nLmFzcAogICAgaHR0cDovL3d3dy5nYW1lZGV2Lm5ldC9yZWZlcmVuY2UvcHJvZ3JhbW1pbmcvZmVhdHVyZXMvcmVuZGVyZXJkbGwzL3BhZ2UyLmFzcAogICAgRGVzY3Vzc2lvbiB0aGF0IHdheXMgdG8gdHVybiBvbiBXUkFQaW5nIHRvIHNvbHZlIGFuIG9wZW5nbCBjb252ZXJzaW9uIHByb2JsZW0uCiAgICBodHRwOi8vd3d3LmZsaXBjb2RlLm9yZy9jZ2ktYmluL2ZjbXNnLmNnaT90aHJlYWRfc2hvdz0xMDI0OAoKICAgIHNvIGZhciBhcyBJIGNhbiB0ZWxsLCB3cmFwcGluZyBhbmQgdGV4dHVyZS1jb29yZGluYXRlIGdlbmVyYXRlIGdvIGhhbmQgaW4gaGFuZCwKICAgICovCiAgICAgICAgVFJBQ0UoIiglcCktPiglcywlbGQpIFRleHR1cmUgd3JhcGluZyBub3QgeWV0IHN1cHBvcnRlZFxuIixUaGlzLCBkZWJ1Z19kM2RyZW5kZXJzdGF0ZShTdGF0ZSksIFZhbHVlKTsKICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEUlNfTVVMVElTQU1QTEVBTlRJQUxJQVMgICAgICA6CiAgICB7CiAgICAgICAgaWYgKCFHTF9TVVBQT1JUKEFSQl9NVUxUSVNBTVBMRSkpIHsKICAgICAgICAgICAgVFJBQ0UoIk11bHRpc2FtcGxlIGFudGlhbGlhc2luZyBub3Qgc3VwcG9ydGVkXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZihWYWx1ZSkgewogICAgICAgICAgICBnbEVuYWJsZShHTF9NVUxUSVNBTVBMRV9BUkIpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfTVVMVElTQU1QTEVfQVJCKSIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9NVUxUSVNBTVBMRV9BUkIpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKEdMX01VTFRJU0FNUExFX0FSQikiKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBjYXNlIFdJTkVEM0RSU19TQ0lTU09SVEVTVEVOQUJMRSA6CiAgICB7CiAgICAgICAgaWYoVmFsdWUpIHsKICAgICAgICAgICAgZ2xFbmFibGUoR0xfU0NJU1NPUl9URVNUKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1NDSVNTT1JfVEVTVCkiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBnbERpc2FibGUoR0xfU0NJU1NPUl9URVNUKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9TQ0lTU09SX1RFU1QpIik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgY2FzZSBXSU5FRDNEUlNfU0xPUEVTQ0FMRURFUFRIQklBUyA6CiAgICB7CiAgICAgICAgaWYoVmFsdWUpIHsKICAgICAgICAgICAgdG1wdmFsdWUuZCA9IFZhbHVlOwogICAgICAgICAgICBnbEVuYWJsZShHTF9QT0xZR09OX09GRlNFVF9GSUxMKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1BPTFlHT05fT0ZGU0VUX0ZJTEwpIik7CiAgICAgICAgICAgIGdsUG9seWdvbk9mZnNldCh0bXB2YWx1ZS5mLCAqKChmbG9hdCopJlRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19ERVBUSEJJQVNdKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFBvbHlnb25PZmZzZXQoLi4uKSIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9QT0xZR09OX09GRlNFVF9GSUxMKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9QT0xZR09OX09GRlNFVF9GSUxMKSIpOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KICAgIGNhc2UgV0lORUQzRFJTX0FOVElBTElBU0VETElORUVOQUJMRSA6CiAgICB7CiAgICAgICAgaWYoVmFsdWUpIHsKICAgICAgICAgICAgZ2xCbGVuZEZ1bmMoR0xfU1JDX0FMUEhBLCBHTF9PTkVfTUlOVVNfU1JDX0FMUEhBKTsKICAgICAgICAgICAgZ2xFbmFibGUoR0xfQkxFTkQpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfQkxFTkQpIik7CiAgICAgICAgICAgIGdsRW5hYmxlKEdMX0xJTkVfU01PT1RIKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX0xJTkVfU01PT1RIKSIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9CTEVORCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUoR0xfQkxFTkQpIik7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9MSU5FX1NNT09USCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUoR0xfTElORV9TTU9PVEgpIik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgY2FzZSBXSU5FRDNEUlNfVFdPU0lERURTVEVOQ0lMTU9ERSA6CiAgICB7CiAgICAgICAgaWYoVmFsdWUpIHsKICAgICAgICAgICAgVFJBQ0UoIlR3by1zaWRlZCBzdGVuY2lsIG1vZGUgZW5hYmxlZFxuIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVFJBQ0UoIlR3by1zaWRlZCBzdGVuY2lsIG1vZGUgZGlzYWJsZWRcbiIpOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KICAgIGNhc2UgV0lORUQzRFJTX0NDV19TVEVOQ0lMRkFJTCA6CiAgICBjYXNlIFdJTkVEM0RSU19DQ1dfU1RFTkNJTFpGQUlMIDoKICAgIGNhc2UgV0lORUQzRFJTX0NDV19TVEVOQ0lMUEFTUyA6CiAgICB7CiAgICAgICAgR0xpbnQgc3RlbmNpbEZhaWw7CiAgICAgICAgR0xpbnQgZGVwdGhGYWlsOwogICAgICAgIEdMaW50IHN0ZW5jaWxQYXNzOwoKICAgICAgICBHTGludCBhY3Rpb24gPSBTdGVuY2lsT3AoVmFsdWUpOwoKICAgICAgICBnbEdldEludGVnZXJ2KEdMX1NURU5DSUxfQkFDS19GQUlMLCAmc3RlbmNpbEZhaWwpOwogICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfU1RFTkNJTF9CQUNLX1BBU1NfREVQVEhfRkFJTCwgJmRlcHRoRmFpbCk7CiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9TVEVOQ0lMX0JBQ0tfUEFTU19ERVBUSF9QQVNTLCAmc3RlbmNpbFBhc3MpOwoKICAgICAgICBpZihXSU5FRDNEUlNfQ0NXX1NURU5DSUxGQUlMID09IFN0YXRlKSB7CiAgICAgICAgICAgIHN0ZW5jaWxGYWlsID0gYWN0aW9uOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKFdJTkVEM0RSU19DQ1dfU1RFTkNJTFpGQUlMID09IFN0YXRlKSB7CiAgICAgICAgICAgIGRlcHRoRmFpbCA9IGFjdGlvbjsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZihXSU5FRDNEUlNfQ0NXX1NURU5DSUxQQVNTID09IFN0YXRlKSB7CiAgICAgICAgICAgIHN0ZW5jaWxQYXNzID0gYWN0aW9uOwogICAgICAgIH0KCiAgICAgICAgaWYoIVRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19UV09TSURFRFNURU5DSUxNT0RFXSkgewojaWYgMCAvKiBEb24ndCB1c2UgT3BlbkdMIDIuMCBjYWxscyBmb3Igbm93ICovCiAgICAgICAgICAgIGlmKEdMX0VYVENBTEwoZ2xTdGVuY2lsT3BTZXBhcmF0ZSkpIHsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xTdGVuY2lsT3BTZXBhcmF0ZShHTF9CQUNLLCBzdGVuY2lsRmFpbCwgZGVwdGhGYWlsLCBzdGVuY2lsUGFzcykpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsU3RlbmNpbE9wU2VwYXJhdGUoR0xfQkFDSywuLi4pIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQojZW5kaWYKCSAgICBpZihHTF9TVVBQT1JUKEVYVF9TVEVOQ0lMX1RXT19TSURFKSkgewogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfU1RFTkNJTF9URVNUX1RXT19TSURFX0VYVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfU1RFTkNJTF9URVNUX1RXT19TSURFX0VYVCkiKTsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVTdGVuY2lsRmFjZUVYVChHTF9CQUNLKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xBY3RpdmVTdGVuY2lsRmFjZUVYVChHTF9CQUNLKSIpOwogICAgICAgICAgICAgICAgZ2xTdGVuY2lsT3Aoc3RlbmNpbEZhaWwsIGRlcHRoRmFpbCwgc3RlbmNpbFBhc3MpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsU3RlbmNpbE9wKC4uLikiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKEdMX1NVUFBPUlQoQVRJX1NFUEFSQVRFX1NURU5DSUwpKSB7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsU3RlbmNpbE9wU2VwYXJhdGVBVEkoR0xfQkFDSywgc3RlbmNpbEZhaWwsIGRlcHRoRmFpbCwgc3RlbmNpbFBhc3MpKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFN0ZW5jaWxPcFNlcGFyYXRlQVRJKEdMX0JBQ0ssLi4uKSIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVFJBQ0UoIlNlcGFyYXRlIHN0ZW5jaWwgb3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyB2ZXJzaW9uIG9mIG9wZW5nbCIpOwogICAgICAgICAgICAgICAgZ2xTdGVuY2lsT3Aoc3RlbmNpbEZhaWwsIGRlcHRoRmFpbCwgc3RlbmNpbFBhc3MpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsU3RlbmNpbE9wKC4uLikiKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsU3RlbmNpbE9wKHN0ZW5jaWxGYWlsLCBkZXB0aEZhaWwsIHN0ZW5jaWxQYXNzKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsU3RlbmNpbE9wKC4uLikiKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBjYXNlIFdJTkVEM0RSU19DQ1dfU1RFTkNJTEZVTkMgOgogICAgewogICAgICAgIEdMaW50IGZ1bmM7CiAgICAgICAgR0xpbnQgcmVmID0gVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1NURU5DSUxSRUZdOwogICAgICAgIEdMdWludCBtYXNrID0gVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1NURU5DSUxNQVNLXTsKCiAgICAgICAgZnVuYyA9IEdMX0FMV0FZUzsKICAgICAgICBzd2l0Y2ggKChEM0RDTVBGVU5DKVZhbHVlKSB7CiAgICAgICAgICAgIGNhc2UgRDNEQ01QX05FVkVSOiBmdW5jID0gR0xfTkVWRVI7IGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRENNUF9MRVNTOiBmdW5jID0gR0xfTEVTUzsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRDNEQ01QX0VRVUFMOiBmdW5jID0gR0xfRVFVQUw7IGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRENNUF9MRVNTRVFVQUw6IGZ1bmMgPSBHTF9MRVFVQUw7IGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRENNUF9HUkVBVEVSOiBmdW5jID0gR0xfR1JFQVRFUjsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRDNEQ01QX05PVEVRVUFMOiBmdW5jID0gR0xfTk9URVFVQUw7IGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRENNUF9HUkVBVEVSRVFVQUw6IGZ1bmMgPSBHTF9HRVFVQUw7IGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRENNUF9BTFdBWVM6IGZ1bmMgPSBHTF9BTFdBWVM7IGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUUoIlVucmVjb2duaXplZC9VbmhhbmRsZWQgRDNEQ01QRlVOQyB2YWx1ZSAlbGRcbiIsIFZhbHVlKTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+c3RlbmNpbGZ1bmMgPSBmdW5jOwogICAgICAgIGlmKCFUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfVFdPU0lERURTVEVOQ0lMTU9ERV0pIHsKI2lmIDAgLyogRG9uJ3QgdXNlIE9wZW5HTCAyLjAgY2FsbHMgZm9yIG5vdyAqLwogICAgICAgICAgICBpZihHTF9FWFRDQUxMKGdsU3RlbmNpbEZ1bmNTZXBhcmF0ZSkpIHsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xTdGVuY2lsRnVuY1NlcGFyYXRlKEdMX0JBQ0ssIGZ1bmMsIHJlZiwgbWFzaykpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsU3RlbmNpbEZ1bmNTZXBhcmF0ZShHTF9CQUNLLC4uLikiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiNlbmRpZgoJICAgIGlmKEdMX1NVUFBPUlQoRVhUX1NURU5DSUxfVFdPX1NJREUpKSB7CiAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9TVEVOQ0lMX1RFU1RfVFdPX1NJREVfRVhUKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9TVEVOQ0lMX1RFU1RfVFdPX1NJREVfRVhUKSIpOwogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEFjdGl2ZVN0ZW5jaWxGYWNlRVhUKEdMX0JBQ0spKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVN0ZW5jaWxGYWNlRVhUKEdMX0JBQ0spIik7CiAgICAgICAgICAgICAgICBnbFN0ZW5jaWxGdW5jKGZ1bmMsIHJlZiwgbWFzayk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xTdGVuY2lsRnVuYyguLi4pIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZihHTF9TVVBQT1JUKEFUSV9TRVBBUkFURV9TVEVOQ0lMKSkgewogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFN0ZW5jaWxGdW5jU2VwYXJhdGVBVEkoR0xfQkFDSywgZnVuYywgcmVmLCBtYXNrKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xTdGVuY2lsRnVuY1NlcGFyYXRlQVRJKEdMX0JBQ0ssLi4uKSIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVFJBQ0UoIlNlcGFyYXRlIHN0ZW5jaWwgZnVuY3Rpb24gbm90IHN1cHBvcnRlZCBvbiB0aGlzIHZlcnNpb24gb2Ygb3BlbmdsIik7CiAgICAgICAgICAgICAgICBnbFN0ZW5jaWxGdW5jKGZ1bmMsIHJlZiwgbWFzayk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xTdGVuY2lsRnVuYyguLi4pIik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBnbFN0ZW5jaWxGdW5jKGZ1bmMsIHJlZiwgbWFzayk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFN0ZW5jaWxGdW5jKC4uLikiKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBjYXNlIFdJTkVEM0RSU19ERVBUSEJJQVMgOgogICAgewogICAgICAgIGlmKFZhbHVlKSB7CiAgICAgICAgICAgIHRtcHZhbHVlLmQgPSBWYWx1ZTsKICAgICAgICAgICAgZ2xFbmFibGUoR0xfUE9MWUdPTl9PRkZTRVRfRklMTCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9QT0xZR09OX09GRlNFVF9GSUxMKSIpOwogICAgICAgICAgICBnbFBvbHlnb25PZmZzZXQoKigoZmxvYXQqKSZUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfU0xPUEVTQ0FMRURFUFRIQklBU10pLCB0bXB2YWx1ZS5mKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsUG9seWdvbk9mZnNldCguLi4pIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1BPTFlHT05fT0ZGU0VUX0ZJTEwpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKEdMX1BPTFlHT05fT0ZGU0VUX0ZJTEwpIik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgY2FzZSBXSU5FRDNEUlNfU0VQQVJBVEVBTFBIQUJMRU5ERU5BQkxFICAgOgogICAgY2FzZSBXSU5FRDNEUlNfU1JDQkxFTkRBTFBIQSAgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfREVTVEJMRU5EQUxQSEEgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfQkxFTkRPUEFMUEhBICAgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfTVVMVElTQU1QTEVNQVNLICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfUEFUQ0hFREdFU1RZTEUgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfUEFUQ0hTRUdNRU5UUyAgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfREVCVUdNT05JVE9SVE9LRU4gICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfUE9TSVRJT05PUkRFUiAgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfTk9STUFMT1JERVIgICAgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfTUlOVEVTU0VMTEFUSU9OTEVWRUwgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfTUFYVEVTU0VMTEFUSU9OTEVWRUwgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfQURBUFRJVkVURVNTX1ggICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfQURBUFRJVkVURVNTX1kgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfQURBUFRJVkVURVNTX1ogICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfQURBUFRJVkVURVNTX1cgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfRU5BQkxFQURBUFRJVkVURVNTRUxMQVRJT04gOgogICAgY2FzZSBXSU5FRDNEUlNfQ09MT1JXUklURUVOQUJMRTEgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfQ09MT1JXUklURUVOQUJMRTIgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfQ09MT1JXUklURUVOQUJMRTMgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfQkxFTkRGQUNUT1IgICAgICAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEUlNfU1JHQldSSVRFRU5BQkxFICAgICAgICAgICAgOgogICAgICAgIEZJWE1FKCIoJXApLT4oJXMsJWxkKSBub3QgaGFuZGxlZCB5ZXRcbiIsIFRoaXMsIGRlYnVnX2QzZHJlbmRlcnN0YXRlKFN0YXRlKSwgVmFsdWUpOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBGSVhNRSgiKCVwKS0+KCVkLCVsZCkgdW5yZWNvZ25pemVkXG4iLCBUaGlzLCBTdGF0ZSwgVmFsdWUpOwogICAgfQoKICAgIExFQVZFX0dMKCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSZW5kZXJTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIEQzRFJFTkRFUlNUQVRFVFlQRSBTdGF0ZSwgRFdPUkQgKnBWYWx1ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgZm9yIFN0YXRlICVkID0gJWxkXG4iLCBUaGlzLCBTdGF0ZSwgVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbU3RhdGVdKTsKICAgICpwVmFsdWUgPSBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtTdGF0ZV07CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBTYW1wbGVyIFN0YXRlcwogKiBUT0RPOiBWZXJpZnkgYWdhaW5zdCBkeDkgZGVmaW5pdGlvbnMKICoqKioqLwoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFNhbXBsZXJTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFNhbXBsZXIsIFdJTkVEM0RTQU1QTEVSU1RBVEVUWVBFIFR5cGUsIERXT1JEIFZhbHVlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAvKioKICAgICogU2V0U2FtcGxlciBpcyBkZXNpZ25lZCB0byBhbGxvdyBmb3IgbW9yZSB0aGFuIHRoZSBzdGFuZGFyZCB1cCB0byA4IHRleHR1cmVzCiAgICAqICBhbmQgR2Vmb3JjZSBoYXMgc3RvcHBlZCBzdXBwb3J0aW5nIG1vcmUgdGhhbiA2IHN0YW5kYXJkIHRleHR1cmVzIGluIG9wZW5HTC4KICAgICogU28gSSBoYXZlIHRvIHVzZSBBUkIgZm9yIEdmb3JjZS4gKG1heWJlIGlmIHRoZSBzYW1wbGVyID4gNCB0aGVuIHVzZSBBUkI/KQogICAgKgogICAgKiBodHRwOi8vZGV2ZWxvcGVyLm52aWRpYS5jb20vb2JqZWN0L0dlbmVyYWxfRkFRLmh0bWwjdDYKICAgICoKICAgICogVGhlcmUgYXJlIHR3byBuZXcgc2V0dGluZ3MgZm9yIEdGb3JjZQogICAgKiB0aGUgc2FtcGxlciBvbmU6CiAgICAqIEdMX01BWF9URVhUVVJFX0lNQUdFX1VOSVRTX0FSQgogICAgKiBhbmQgdGhlIHRleHR1cmUgb25lOgogICAgKiBHTF9NQVhfVEVYVFVSRV9DT09SRFNfQVJCLgogICAgKiBPayBHRm9yY2Ugc2F5IGl0J3Mgb2sgdG8gdXNlIGdsVGV4UGFyYW1ldGVyL2dsR2V0VGV4UGFyYW1ldGVyKC4uLikuCiAgICAgKioqKioqKioqKioqKioqKioqLwogICAgLyoqIE5PVEU6IFN0YXRlcyBhcmUgYXBwbGVkIGluIElXaW5lRDNEQmFzZVRleHRyZSBBcHBseVN0YXRlQ2hhbmdlcyBhbmQgSVdpbmVEM0REZXZpY2UgU2V0dXBUZXh0dXJlU3RhdGVzKiovCiAgICBUUkFDRSgiKCVwKSBTYW1wbGVyKCVsZCksIFR5cGUoJWQpIFZhbHVlKCVsZClcbiIsVGhpcywgU2FtcGxlciAsVHlwZSwgVmFsdWUpOwoKICAgIGlmKFNhbXBsZXIgPiAgR0xfTElNSVRTKHNhbXBsZXJzKSB8fCBTYW1wbGVyIDwgMCB8fCBUeXBlID4gV0lORUQzRF9ISUdIRVNUX1NBTVBMRVJfU1RBVEUgfHwgVHlwZSA8IDApIHsKICAgICAgICAgRklYTUUoIm91dCBvZiByYW5nZSAlZCAlZCBzYW1wbGVyICVsZCB0eXBlICV1XG4iLCBHTF9MSU1JVFMoc2FtcGxlcnMpLCBXSU5FRDNEX0hJR0hFU1RfU0FNUExFUl9TVEFURSwgU2FtcGxlciwgVHlwZSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBUUkFDRSgiU2V0dGluZyBzYW1wbGVyICVsZCAlZCB0byAlbGRcbiIsIFNhbXBsZXIsIFR5cGUsIFZhbHVlKTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNhbXBsZXJTdGF0ZVtTYW1wbGVyXVtUeXBlXSAgICAgICAgID0gVmFsdWU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQuc2FtcGxlclN0YXRlW1NhbXBsZXJdW1R5cGVdICAgICA9IFZhbHVlOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5zYW1wbGVyU3RhdGVbU2FtcGxlcl1bVHlwZV0gPSBWYWx1ZTsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFNhbXBsZXJTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFNhbXBsZXIsIFdJTkVEM0RTQU1QTEVSU1RBVEVUWVBFIFR5cGUsIERXT1JEKiBWYWx1ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgLyoqIFRPRE86IGNoZWNrIHRoYXQgc2FtcGxlciBpcyBpbiAgcmFuZ2UgKiovCiAgICAqVmFsdWUgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zYW1wbGVyU3RhdGVbU2FtcGxlcl1bVHlwZV07CiAgICBUUkFDRSgiKCVwKSA6IFNhbXBsZXIgJWxkIFR5cGUgJXUgUmV0dXJuaW5nICVsZFxuIiwgVGhpcywgU2FtcGxlciwgVHlwZSwgKlZhbHVlKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFNjaXNzb3JSZWN0KElXaW5lRDNERGV2aWNlICppZmFjZSwgQ09OU1QgUkVDVCogcFJlY3QpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEVOVEVSX0dMKCk7CgogICAgLyoqIEZJWE1FOiBXaW5kb3dzIHVzZXMgYSB0b3AsbGVmdCBvcmlnaW4gb3BlbkdMIHVzZXMgYSBib3R0b20gUmlnaHQ/ICoqLwogICAgVFJBQ0UoIiglcClTZXR0aW5nIG5ldyBTY2lzc29yIFJlY3QgdG8gJWxkOiVsZC0lbGQ6JWxkXG4iLCBUaGlzLCBwUmVjdC0+bGVmdCwgcFJlY3QtPnRvcCwgcFJlY3QtPnJpZ2h0LCBwUmVjdC0+Ym90dG9tKTsKICAgIGdsU2Npc3NvcihwUmVjdC0+bGVmdCwgcFJlY3QtPnRvcCwgcFJlY3QtPnJpZ2h0IC0gcFJlY3QtPmxlZnQsIHBSZWN0LT5ib3R0b20gLSBwUmVjdC0+dG9wKTsKICAgIExFQVZFX0dMKCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTY2lzc29yUmVjdChJV2luZUQzRERldmljZSAqaWZhY2UsIFJFQ1QqIHBSZWN0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBHTGludCBzY2lzc29yQm94WzRdOwoKICAgIEVOVEVSX0dMKCk7CiAgICAvKiogRklYTUU6IFdpbmRvd3MgdXNlcyBhIHRvcCxsZWZ0IG9yaWdpbiBvcGVuR0wgdXNlcyBhIGJvdHRvbSBSaWdodD8gKiovCiAgICBnbEdldEludGVnZXJ2KEdMX1NDSVNTT1JfQk9YLCBzY2lzc29yQm94KTsKICAgIHBSZWN0LT5sZWZ0ID0gc2Npc3NvckJveFsxXTsKICAgIHBSZWN0LT50b3AgPSBzY2lzc29yQm94WzJdOwogICAgcFJlY3QtPnJpZ2h0ID0gc2Npc3NvckJveFsxXSArIHNjaXNzb3JCb3hbM107CiAgICBwUmVjdC0+Ym90dG9tID0gc2Npc3NvckJveFsyXSArIHNjaXNzb3JCb3hbNF07CiAgICBUUkFDRSgiKCVwKVJldHVybmluZyBhIFNjaXNzb3IgUmVjdCBvZiAlbGQ6JWxkLSVsZDolbGRcbiIsIFRoaXMsIHBSZWN0LT5sZWZ0LCBwUmVjdC0+dG9wLCBwUmVjdC0+cmlnaHQsIHBSZWN0LT5ib3R0b20pOwogICAgTEVBVkVfR0woKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4RGVjbGFyYXRpb24oSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uKiBwRGVjbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24gKm9sZERlY2wgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhEZWNsOwoKICAgIFRSQUNFKCIoJXApIDogcERlY2w9JXBcbiIsIFRoaXMsIHBEZWNsKTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhEZWNsID0gcERlY2w7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleERlY2wgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnZlcnRleERlY2wgPSBUUlVFOwoKICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICB9CgogICAgaWYgKE5VTEwgIT0gcERlY2wpIHsKICAgICAgICBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uX0FkZFJlZihwRGVjbCk7CiAgICB9CiAgICBpZiAoTlVMTCAhPSBvbGREZWNsKSB7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbl9SZWxlYXNlKG9sZERlY2wpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhEZWNsYXJhdGlvbihJV2luZUQzRERldmljZSogaWZhY2UsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24qKiBwcERlY2wpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IHBwRGVjbD0lcFxuIiwgVGhpcywgcHBEZWNsKTsKCiAgICAqcHBEZWNsID0gVGhpcy0+c3RhdGVCbG9jay0+dmVydGV4RGVjbDsKICAgIGlmIChOVUxMICE9ICpwcERlY2wpIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb25fQWRkUmVmKCpwcERlY2wpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFZlcnRleFNoYWRlciogcFNoYWRlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzICAgICAgICA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4U2hhZGVyKiBvbGRTaGFkZXIgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXI7CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dmVydGV4U2hhZGVyICAgICAgICAgPSBwU2hhZGVyOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXIgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnZlcnRleFNoYWRlciAgICAgPSBUUlVFOwoKICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICB9CgogICAgaWYgKE5VTEwgIT0gcFNoYWRlcikgewogICAgICAgIElXaW5lRDNEVmVydGV4U2hhZGVyX0FkZFJlZihwU2hhZGVyKTsKICAgIH0KICAgIGlmIChOVUxMICE9IG9sZFNoYWRlcikgewogICAgICAgIElXaW5lRDNEVmVydGV4U2hhZGVyX1JlbGVhc2Uob2xkU2hhZGVyKTsKICAgIH0KCiAgICBpZiAocFNoYWRlciAhPSBOVUxMICYmICgoSVdpbmVEM0RWZXJ0ZXhTaGFkZXJJbXBsICopcFNoYWRlciktPnZlcnRleERlY2xhcmF0aW9uICE9IE5VTEwpIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IHNldHRpbmcgdmVydGV4RGVjbGFyYXRpb24oJXApXG4iLCBUaGlzLCAoKElXaW5lRDNEVmVydGV4U2hhZGVySW1wbCAqKXBTaGFkZXIpLT52ZXJ0ZXhEZWNsYXJhdGlvbik7CiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VmVydGV4RGVjbGFyYXRpb24oaWZhY2UsICgoSVdpbmVEM0RWZXJ0ZXhTaGFkZXJJbXBsICopcFNoYWRlciktPnZlcnRleERlY2xhcmF0aW9uKTsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IHNldHRpbmcgcFNoYWRlciglcClcbiIsIFRoaXMsIHBTaGFkZXIpOwogICAgLyoqCiAgICAgKiBUT0RPOiBtZXJnZSBIQUwgc2hhZGVycyBjb250ZXh0IHN3aXRjaGluZyBmcm9tIHByb3RvdHlwZQogICAgICovCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlcihJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEVmVydGV4U2hhZGVyKiogcHBTaGFkZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBpZiAoTlVMTCA9PSBwcFNoYWRlcikgewogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgKnBwU2hhZGVyID0gVGhpcy0+c3RhdGVCbG9jay0+dmVydGV4U2hhZGVyOwogICAgaWYoIE5VTEwgIT0gKnBwU2hhZGVyKQogICAgICAgIElXaW5lRDNEVmVydGV4U2hhZGVyX0FkZFJlZigqcHBTaGFkZXIpOwoKICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nICVwXG4iLCBUaGlzLCAqcHBTaGFkZXIpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudChJV2luZUQzRERldmljZSAqaWZhY2UsIHZvaWQgKmRzdERhdGEsIGNvbnN0IHZvaWQgKnNyY0RhdGEsIFVJTlQgdHlwZSwgVUlOVCBzdGFydCwgVUlOVCBjb3VudCwgVUlOVCByZWdpc3RlcnNpemUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBpbnQgaTsKICAgIGludCBjbnQgPSBtaW4oY291bnQsIE1BWF9WU0hBREVSX0NPTlNUQU5UUyAtIChzdGFydCArIDEpKTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBkc3REYXRhICVwLCBzcmNEYXRhICVwLCB0eXBlICVkLCBzdGFydCAlZCwgY291bnQgJWQsIHJlZ2lzdGVyc2l6ZSAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBkc3REYXRhLCBzcmNEYXRhLCB0eXBlLCBzdGFydCwgY291bnQsIHJlZ2lzdGVyc2l6ZSk7CgogICAgaWYgKHR5cGUgIT0gV0lORVNIQURFUkNOU1RfTk9ORSkgewogICAgICAgIGlmIChzcmNEYXRhID09IE5VTEwgfHwgY250IDwgMCkgewogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CgogICAgICAgIENvcHlNZW1vcnkoKGNoYXIgKilkc3REYXRhICsgKHN0YXJ0ICogcmVnaXN0ZXJzaXplKSwgc3JjRGF0YSwgY250ICogcmVnaXN0ZXJzaXplKTsKICAgIH0KCiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGNudCArIHN0YXJ0OyArK2kpIHsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c1tpXSA9IFRSVUU7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnZlcnRleFNoYWRlckNvbnN0YW50c1tpXSAgICAgPSBUUlVFOwogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50VFtpXSAgICAgICAgID0gdHlwZTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50KElXaW5lRDNERGV2aWNlICppZmFjZSwgdm9pZCAqZHN0RGF0YSwgY29uc3Qgdm9pZCAqc3JjRGF0YSwgVUlOVCB0eXBlLCBVSU5UIHN0YXJ0LCBVSU5UIGNvdW50LCBVSU5UIHJlZ2lzdGVyc2l6ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIGludCBpOwogICAgaW50IGNudCA9IG1pbihjb3VudCwgTUFYX1ZTSEFERVJfQ09OU1RBTlRTIC0gKHN0YXJ0ICsgMSkpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIGRzdERhdGEgJXAsIHNyY0RhdGEgJXAsIHR5cGUgJWQsIHN0YXJ0ICVkLCBjb3VudCAlZCwgcmVnaXN0ZXJzaXplICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIGRzdERhdGEsIHNyY0RhdGEsIHR5cGUsIHN0YXJ0LCBjb3VudCwgcmVnaXN0ZXJzaXplKTsKCiAgICAvKiBWZXJpZnkgdGhhdCB0aGUgcmVxdWVzdGVkIHNoYWRlciBjb25zdGFudCB3YXMgcG9wdWxhdGVkIHdpdGggdGhlIGNvcnJlY3QgdHlwZSAqLwogICAgZm9yIChpID0gc3RhcnQ7IGkgPCBjbnQgKyBzdGFydDsgKytpKSB7CiAgICAgICAgaWYgKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50VFtpXSAhPSB0eXBlKSB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGVyIHJlcXVlc3RlZCAweCV4IHdoaWxlIHR5cGUgaXMgMHgleC4gUmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIsIAogICAgICAgICAgICAgICAgICAgIFRoaXMsIHR5cGUsIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50VFtpXSk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoZHN0RGF0YSA9PSBOVUxMIHx8IGNudCA8IDApIHsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBDb3B5TWVtb3J5KGRzdERhdGEsIChjaGFyICopc3JjRGF0YSArIChzdGFydCAqIHJlZ2lzdGVyc2l6ZSksIGNudCAqIHJlZ2lzdGVyc2l6ZSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFN0YXJ0UmVnaXN0ZXIsIENPTlNUIEJPT0wgICpwQ29uc3RhbnREYXRhLCBVSU5UIEJvb2xDb3VudCl7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAKICAgIHJldHVybiBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnQoaWZhY2UsIAogICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudEIsIAogICAgICAgICAgICBwQ29uc3RhbnREYXRhLCAKICAgICAgICAgICAgV0lORVNIQURFUkNOU1RfQk9PTCwgCiAgICAgICAgICAgIFN0YXJ0UmVnaXN0ZXIsIAogICAgICAgICAgICBCb29sQ291bnQsIAogICAgICAgICAgICBzaXplb2YoKnBDb25zdGFudERhdGEpKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50QihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgU3RhcnRSZWdpc3RlciwgQk9PTCAqcENvbnN0YW50RGF0YSwgVUlOVCBCb29sQ291bnQpewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgCiAgICByZXR1cm4gSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50KGlmYWNlLCAKICAgICAgICAgICAgcENvbnN0YW50RGF0YSwgCiAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50QiwgCiAgICAgICAgICAgIFdJTkVTSEFERVJDTlNUX0JPT0wsIAogICAgICAgICAgICBTdGFydFJlZ2lzdGVyLCAKICAgICAgICAgICAgQm9vbENvdW50LCAKICAgICAgICAgICAgc2l6ZW9mKCpwQ29uc3RhbnREYXRhKSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEkoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFN0YXJ0UmVnaXN0ZXIsIENPTlNUIGludCAqcENvbnN0YW50RGF0YSwgVUlOVCBWZWN0b3I0aUNvdW50KXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIAogICAgcmV0dXJuIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudChpZmFjZSwgCiAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50SSwgCiAgICAgICAgICAgIHBDb25zdGFudERhdGEsIAogICAgICAgICAgICBXSU5FU0hBREVSQ05TVF9JTlRFR0VSLCAKICAgICAgICAgICAgU3RhcnRSZWdpc3RlciwgCiAgICAgICAgICAgIFZlY3RvcjRpQ291bnQsIAogICAgICAgICAgICA0ICogc2l6ZW9mKCpwQ29uc3RhbnREYXRhKSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEkoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFN0YXJ0UmVnaXN0ZXIsIGludCAgICAgICAgICpwQ29uc3RhbnREYXRhLCBVSU5UIFZlY3RvcjRpQ291bnQpewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgCiAgICByZXR1cm4gSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50KGlmYWNlLCAKICAgICAgICAgICAgcENvbnN0YW50RGF0YSwgCiAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50SSwgCiAgICAgICAgICAgIFdJTkVTSEFERVJDTlNUX0lOVEVHRVIsIAogICAgICAgICAgICBTdGFydFJlZ2lzdGVyLCAKICAgICAgICAgICAgVmVjdG9yNGlDb3VudCwgCiAgICAgICAgICAgIDQgKiBzaXplb2YoKnBDb25zdGFudERhdGEpKTsKfQoKCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEYoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFN0YXJ0UmVnaXN0ZXIsIENPTlNUIGZsb2F0ICpwQ29uc3RhbnREYXRhLCBVSU5UIFZlY3RvcjRmQ291bnQpewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIHJldHVybiBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnQoaWZhY2UsIAogICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudEYsIAogICAgICAgICAgICBwQ29uc3RhbnREYXRhLCAKICAgICAgICAgICAgV0lORVNIQURFUkNOU1RfRkxPQVQsIAogICAgICAgICAgICBTdGFydFJlZ2lzdGVyLCAKICAgICAgICAgICAgVmVjdG9yNGZDb3VudCwgCiAgICAgICAgICAgIDQgKiBzaXplb2YoKnBDb25zdGFudERhdGEpKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50RihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgU3RhcnRSZWdpc3RlciwgZmxvYXQgICAgICAgKnBDb25zdGFudERhdGEsIFVJTlQgVmVjdG9yNGZDb3VudCl7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgcmV0dXJuIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXJDb25zdGFudChpZmFjZSwgCiAgICAgICAgICAgIHBDb25zdGFudERhdGEsIAogICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudEYsIAogICAgICAgICAgICBXSU5FU0hBREVSQ05TVF9GTE9BVCwgCiAgICAgICAgICAgIFN0YXJ0UmVnaXN0ZXIsIAogICAgICAgICAgICBWZWN0b3I0ZkNvdW50LCAKICAgICAgICAgICAgNCAqIHNpemVvZigqcENvbnN0YW50RGF0YSkpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnROKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBTdGFydFJlZ2lzdGVyLCBVSU5UIFZlY3Rvck5Db3VudCl7CiAgICByZXR1cm4gSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlckNvbnN0YW50KGlmYWNlLCAKICAgICAgICAgICAgTlVMTCwgCiAgICAgICAgICAgIE5VTEwsIAogICAgICAgICAgICBXSU5FU0hBREVSQ05TVF9OT05FLCAKICAgICAgICAgICAgU3RhcnRSZWdpc3RlciwgCiAgICAgICAgICAgIFZlY3Rvck5Db3VudCwgCiAgICAgICAgICAgIDApOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFBpeGVsU2hhZGVyICpwU2hhZGVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgICAgICAgID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RQaXhlbFNoYWRlciAqb2xkU2hhZGVyICA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBpeGVsU2hhZGVyOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cGl4ZWxTaGFkZXIgICAgICAgICA9IHBTaGFkZXI7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnBpeGVsU2hhZGVyID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC5waXhlbFNoYWRlciAgICAgPSBUUlVFOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgfQoKICAgIGlmIChOVUxMICE9IHBTaGFkZXIpIHsKICAgICAgICBJV2luZUQzRFBpeGVsU2hhZGVyX0FkZFJlZihwU2hhZGVyKTsKICAgIH0KICAgIGlmIChOVUxMICE9IG9sZFNoYWRlcikgewogICAgICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJfUmVsZWFzZShvbGRTaGFkZXIpOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogc2V0dGluZyBwU2hhZGVyKCVwKVxuIiwgVGhpcywgcFNoYWRlcik7CiAgICAvKioKICAgICAqIFRPRE86IG1lcmdlIEhBTCBzaGFkZXJzIGNvbnRleHQgc3dpdGNoaW5nIGZyb20gcHJvdG90eXBlCiAgICAgKi8KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFBpeGVsU2hhZGVyICoqcHBTaGFkZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBpZiAoTlVMTCA9PSBwcFNoYWRlcikgewogICAgICAgIFdBUk4oIiglcCkgOiBQU2hhZGVyIGlzIE5VTEwsIHJldHVybmluZyBJTlZBTElEQ0FMTFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgKnBwU2hhZGVyID0gIFRoaXMtPnN0YXRlQmxvY2stPnBpeGVsU2hhZGVyOwogICAgaWYgKE5VTEwgIT0gKnBwU2hhZGVyKSB7CiAgICAgICAgSVdpbmVEM0RQaXhlbFNoYWRlcl9BZGRSZWYoKnBwU2hhZGVyKTsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nICVwXG4iLCBUaGlzLCAqcHBTaGFkZXIpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50KElXaW5lRDNERGV2aWNlICppZmFjZSwgdm9pZCAqZHN0RGF0YSwgY29uc3Qgdm9pZCAqc3JjRGF0YSwgVUlOVCB0eXBlLCBVSU5UIHN0YXJ0LCBVSU5UIGNvdW50LCBVSU5UIHJlZ2lzdGVyc2l6ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIGludCBpOwogICAgaW50IGNudCA9IG1pbihjb3VudCwgTUFYX1BTSEFERVJfQ09OU1RBTlRTIC0gKHN0YXJ0ICsgMSkpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIGRzdERhdGEgJXAsIHNyY0RhdGEgJXAsIHR5cGUgJWQsIHN0YXJ0ICVkLCBjb3VudCAlZCwgcmVnaXN0ZXJzaXplICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIGRzdERhdGEsIHNyY0RhdGEsIHR5cGUsIHN0YXJ0LCBjb3VudCwgcmVnaXN0ZXJzaXplKTsKCiAgICBpZiAodHlwZSAhPSBXSU5FU0hBREVSQ05TVF9OT05FKSB7CiAgICAgICAgaWYgKHNyY0RhdGEgPT0gTlVMTCB8fCBjbnQgPCAwKSB7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KCiAgICAgICAgQ29weU1lbW9yeSgoY2hhciAqKWRzdERhdGEgKyAoc3RhcnQgKiByZWdpc3RlcnNpemUpLCBzcmNEYXRhLCBjbnQgKiByZWdpc3RlcnNpemUpOwogICAgfQoKICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgY250ICsgc3RhcnQ7ICsraSkgewogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQucGl4ZWxTaGFkZXJDb25zdGFudHNbaV0gPSBUUlVFOwogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC5waXhlbFNoYWRlckNvbnN0YW50c1tpXSAgICAgPSBUUlVFOwogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRUW2ldICAgICAgICAgPSB0eXBlOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudChJV2luZUQzRERldmljZSAqaWZhY2UsIHZvaWQgKmRzdERhdGEsIGNvbnN0IHZvaWQgKnNyY0RhdGEsIFVJTlQgdHlwZSwgVUlOVCBzdGFydCwgVUlOVCBjb3VudCwgVUlOVCByZWdpc3RlcnNpemUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBpbnQgaTsKICAgIGludCBjbnQgPSBtaW4oY291bnQsIE1BWF9QU0hBREVSX0NPTlNUQU5UUyAtIChzdGFydCArIDEpKTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBkc3REYXRhICVwLCBzcmNEYXRhICVwLCB0eXBlICVkLCBzdGFydCAlZCwgY291bnQgJWQsIHJlZ2lzdGVyc2l6ZSAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBkc3REYXRhLCBzcmNEYXRhLCB0eXBlLCBzdGFydCwgY291bnQsIHJlZ2lzdGVyc2l6ZSk7CgogICAgLyogVmVyaWZ5IHRoYXQgdGhlIHJlcXVlc3RlZCBzaGFkZXIgY29uc3RhbnQgd2FzIHBvcHVsYXRlZCB3aXRoIHRoZSBjb3JyZWN0IHR5cGUgKi8KICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgY250ICsgc3RhcnQ7ICsraSkgewogICAgICAgIGlmIChUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50VFtpXSAhPSB0eXBlKSB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGVyIHJlcXVlc3RlZCAweCV4IHdoaWxlIHR5cGUgaXMgMHgleC4gUmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIsIAogICAgICAgICAgICAgICAgICAgIFRoaXMsIHR5cGUsIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRUW2ldKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChkc3REYXRhID09IE5VTEwgfHwgY250IDwgMCkgewogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIENvcHlNZW1vcnkoZHN0RGF0YSwgKGNoYXIgKilzcmNEYXRhICsgKHN0YXJ0ICogcmVnaXN0ZXJzaXplKSwgY250ICogcmVnaXN0ZXJzaXplKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyQ29uc3RhbnRCKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBTdGFydFJlZ2lzdGVyLCBDT05TVCBCT09MICAgKnBDb25zdGFudERhdGEsIFVJTlQgQm9vbENvdW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAKICAgIHJldHVybiBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudChpZmFjZSwgCiAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRCLCAKICAgICAgICAgICAgcENvbnN0YW50RGF0YSwgCiAgICAgICAgICAgIFdJTkVTSEFERVJDTlNUX0JPT0wsIAogICAgICAgICAgICBTdGFydFJlZ2lzdGVyLCAKICAgICAgICAgICAgQm9vbENvdW50LCAKICAgICAgICAgICAgc2l6ZW9mKCpwQ29uc3RhbnREYXRhKSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50QihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgU3RhcnRSZWdpc3RlciwgQk9PTCAgICAgICAgICpwQ29uc3RhbnREYXRhLCBVSU5UIEJvb2xDb3VudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIHJldHVybiBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudChpZmFjZSwgCiAgICAgICAgICAgIHBDb25zdGFudERhdGEsIAogICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50QiwgCiAgICAgICAgICAgIFdJTkVTSEFERVJDTlNUX0JPT0wsIAogICAgICAgICAgICBTdGFydFJlZ2lzdGVyLCAKICAgICAgICAgICAgQm9vbENvdW50LCAKICAgICAgICAgICAgc2l6ZW9mKCpwQ29uc3RhbnREYXRhKSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50SShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgU3RhcnRSZWdpc3RlciwgQ09OU1QgaW50ICAgICpwQ29uc3RhbnREYXRhLCBVSU5UIFZlY3RvcjRpQ291bnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICByZXR1cm4gSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyQ29uc3RhbnQoaWZhY2UsIAogICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50SSwgCiAgICAgICAgICAgIHBDb25zdGFudERhdGEsIAogICAgICAgICAgICBXSU5FU0hBREVSQ05TVF9JTlRFR0VSLCAKICAgICAgICAgICAgU3RhcnRSZWdpc3RlciwgCiAgICAgICAgICAgIFZlY3RvcjRpQ291bnQsIAogICAgICAgICAgICA0ICogc2l6ZW9mKCpwQ29uc3RhbnREYXRhKSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50SShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgU3RhcnRSZWdpc3RlciwgaW50ICAgICAgICAgICpwQ29uc3RhbnREYXRhLCBVSU5UIFZlY3RvcjRpQ291bnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIAogICAgcmV0dXJuIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50KGlmYWNlLCAKICAgICAgICAgICAgcENvbnN0YW50RGF0YSwgCiAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRJLCAKICAgICAgICAgICAgV0lORVNIQURFUkNOU1RfSU5URUdFUiwgCiAgICAgICAgICAgIFN0YXJ0UmVnaXN0ZXIsIAogICAgICAgICAgICBWZWN0b3I0aUNvdW50LCAKICAgICAgICAgICAgNCAqIHNpemVvZigqcENvbnN0YW50RGF0YSkpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEYoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFN0YXJ0UmVnaXN0ZXIsIENPTlNUIGZsb2F0ICAqcENvbnN0YW50RGF0YSwgVUlOVCBWZWN0b3I0ZkNvdW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAKICAgIHJldHVybiBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudChpZmFjZSwgCiAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRGLCAKICAgICAgICAgICAgcENvbnN0YW50RGF0YSwgCiAgICAgICAgICAgIFdJTkVTSEFERVJDTlNUX0ZMT0FULCAKICAgICAgICAgICAgU3RhcnRSZWdpc3RlciwgCiAgICAgICAgICAgIFZlY3RvcjRmQ291bnQsIAogICAgICAgICAgICA0ICogc2l6ZW9mKCpwQ29uc3RhbnREYXRhKSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50RihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgU3RhcnRSZWdpc3RlciwgZmxvYXQgICAgICAgICpwQ29uc3RhbnREYXRhLCBVSU5UIFZlY3RvcjRmQ291bnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICByZXR1cm4gSVdpbmVEM0REZXZpY2VJbXBsX0dldFBpeGVsU2hhZGVyQ29uc3RhbnQoaWZhY2UsIAogICAgICAgICAgICBwQ29uc3RhbnREYXRhLCAKICAgICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cGl4ZWxTaGFkZXJDb25zdGFudEYsIAogICAgICAgICAgICBXSU5FU0hBREVSQ05TVF9GTE9BVCwgCiAgICAgICAgICAgIFN0YXJ0UmVnaXN0ZXIsIAogICAgICAgICAgICBWZWN0b3I0ZkNvdW50LCAKICAgICAgICAgICAgNCAqIHNpemVvZigqcENvbnN0YW50RGF0YSkpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudE4oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFN0YXJ0UmVnaXN0ZXIsIFVJTlQgVmVjdG9yTkNvdW50KXsKICAgIHJldHVybiBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudChpZmFjZSwgCiAgICAgICAgICAgIE5VTEwsIAogICAgICAgICAgICBOVUxMLCAKICAgICAgICAgICAgV0lORVNIQURFUkNOU1RfTk9ORSwgCiAgICAgICAgICAgIFN0YXJ0UmVnaXN0ZXIsIAogICAgICAgICAgICBWZWN0b3JOQ291bnQsIAogICAgICAgICAgICAwKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1Byb2Nlc3NWZXJ0aWNlcyhJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgU3JjU3RhcnRJbmRleCwgVUlOVCBEZXN0SW5kZXgsIFVJTlQgVmVydGV4Q291bnQsIElXaW5lRDNEVmVydGV4QnVmZmVyKiBwRGVzdEJ1ZmZlciwgSVdpbmVEM0RWZXJ0ZXhCdWZmZXIqIHBWZXJ0ZXhEZWNsLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogQXBwbHkgLyBHZXQgLyBTZXQgVGV4dHVyZSBTdGFnZSBTdGF0ZXMKICogVE9ETzogVmVyaWZ5IGFnYWluc3QgZHg5IGRlZmluaXRpb25zCiAqKioqKi8KCi8qIE5PVEU6IEl0J3MgZXhwZWN0ZWQgdGhhdCB0aGlzIGZ1bmN0aW9uIGlzIGdvaW5nIHRvIGJlIGNhbGxlZCBsb3RzIG9mIHRpbWVzIHdpdGggdGhlIHNhbWUgc3RhZ2UgYWN0aXZlLCBzbyBtYWtlIGl0IHRoZSBjYWxsZXJzIHJlc3BvbnNpYmlsaXR5IHRvIEdMQUNUSVZFVEVYVFVSRShTdGFnZSkgZm9yIGJldHRlciBzdGF0ZSBtYW5hZ2VtZW50LiBTZXQgdGhlIGNvcnJlY3QgVGV4dHVyZSB1bml0IGFjdGl2ZSBiZWZvcmUgY2FsbGluZyBBcHBseVRleHR1cmVTdGFnZVN0YXRlICovCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQXBwbHlUZXh0dXJlVW5pdFN0YXRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgU3RhZ2UsIFdJTkVEM0RURVhUVVJFU1RBR0VTVEFURVRZUEUgVHlwZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRFdPUkQgVmFsdWUgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdOwogICAgLyogRklYTUU6IEhhbmRsZSAzZCB0ZXh0dXJlcz8gV2hhdCBpZiBUU1MgdmFsdWUgc2V0IGJlZm9yZSBzZXQgdGV4dHVyZT8gTmVlZCB0byByZWFwcGx5IGFsbCB2YWx1ZXM/ICovCgogICAgVFJBQ0UoIiglcCkgOiBTdGFnZT0lbGQsIFR5cGU9JXMoJWQpLCBWYWx1ZT0lbGRcbiIsIFRoaXMsIFN0YWdlLCBkZWJ1Z19kM2R0ZXh0dXJlc3RhdGUoVHlwZSksIFR5cGUsIFZhbHVlKTsKCiAgICAvKiBDaGVjayB0aGF0IHRoZSBzdGFnZSBpcyB3aXRoaW4gbGltaXRzICAqLwogICAgaWYgKFN0YWdlID49IEdMX0xJTUlUUyh0ZXh0dXJlcykgfHwgU3RhZ2UgPCAwKSB7CiAgICAgICAgVFJBQ0UoIkF0dGVtcHQgdG8gYWNjZXNzIGludmFsaWQgdGV4dHVyZSByZWplY3RlZFxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIEVOVEVSX0dMKCk7CgogICAgc3dpdGNoIChUeXBlKSB7CiAgICBjYXNlIFdJTkVEM0RUU1NfQUxQSEFPUCAgICAgICAgICAgICAgIDoKICAgIGNhc2UgV0lORUQzRFRTU19DT0xPUk9QICAgICAgICAgICAgICAgOgogICAgICAgIC8qIG5vdGhpbmcgdG8gZG8gYXMgbW92ZWQgdG8gZHJhd3ByaW0gZm9yIG5vdyAqLwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEVFNTX0FERFJFU1NXICAgICAgICAgICAgICA6CiNpZiAwIC8qIEknbSBub3Qgc3VyZSB3aGF0IEQzRCBkb2VzIGFib3V0IEFERFJFU1NXIGFwcGVhcmluZyB0d2ljZSAqLwogICAgICAgICAgICBpZiAoVmFsdWUgPCBtaW5Mb29rdXBbV0lORUxPT0tVUF9XQVJQUEFSQU1dIHx8IFZhbHVlID4gbWF4TG9va3VwW1dJTkVMT09LVVBfV0FSUFBBUkFNXSkgewogICAgICAgICAgICAgICAgRklYTUUoIlVucmVjb2duaXplZCBvciB1bnN1cHBvcnRlZCBEM0RUQUREUkVTU18qIHZhbHVlICVsZCwgc3RhdGUgJWRcbiIsIFZhbHVlLCBUeXBlKTsKCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBHTGludCB3cmFwUGFybSA9IHN0YXRlTG9va3VwW1dJTkVMT09LVVBfV0FSUFBBUkFNXVtWYWx1ZSAtIG1pbkxvb2t1cFtXSU5FTE9PS1VQX1dBUlBQQVJBTV1dOwogICAgICAgICAgICAgICAgVFJBQ0UoIlNldHRpbmcgV1JBUF9SIHRvICVkIGZvciAleFxuIiwgd3JhcFBhcm0sIFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVEaW1lbnNpb25zW1N0YWdlXSk7CiAgICAgICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkoVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZURpbWVuc2lvbnNbU3RhZ2VdLCBHTF9URVhUVVJFX1dSQVBfUiwgd3JhcFBhcm0pOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSguLi4sIEdMX1RFWFRVUkVfV1JBUF9SLCB3cmFwUGFybSkiKTsKICAgICAgICAgICAgfQojZW5kaWYKICAgIGNhc2UgV0lORUQzRFRTU19URVhDT09SRElOREVYICAgICAgICAgOgogICAgICAgIHsKICAgICAgICAgICAgLyogVmFsdWVzIDAtNyBhcmUgaW5kZXhlcyBpbnRvIHRoZSBGVkYgdGV4IGNvb3JkcyAtIFNlZSBjb21tZW50cyBpbiBEcmF3UHJpbWl0aXZlICovCgogICAgICAgICAgICAvKiBGSVhNRTogRnJvbSBNU0ROOiBUaGUgV0lORUQzRFRTU19UQ0lfKiBmbGFncyBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLiBJZiB5b3UgaW5jbHVkZQogICAgICAgICAgICAgICAgICBvbmUgZmxhZywgeW91IGNhbiBzdGlsbCBzcGVjaWZ5IGFuIGluZGV4IHZhbHVlLCB3aGljaCB0aGUgc3lzdGVtIHVzZXMgdG8KICAgICAgICAgICAgICAgICAgZGV0ZXJtaW5lIHRoZSB0ZXh0dXJlIHdyYXBwaW5nIG1vZGUuCiAgICAgICAgICAgICAgICAgIGVnLiBTZXRUZXh0dXJlU3RhZ2VTdGF0ZSggMCwgRDNEVFNTX1RFWENPT1JESU5ERVgsIEQzRFRTU19UQ0lfQ0FNRVJBU1BBQ0VQT1NJVElPTiB8IDEgKTsKICAgICAgICAgICAgICAgICAgbWVhbnMgdXNlIHRoZSB2ZXJ0ZXggcG9zaXRpb24gKGNhbWVyYS1zcGFjZSkgYXMgdGhlIGlucHV0IHRleHR1cmUgY29vcmRpbmF0ZXMKICAgICAgICAgICAgICAgICAgZm9yIHRoaXMgdGV4dHVyZSBzdGFnZSwgYW5kIHRoZSB3cmFwIG1vZGUgc2V0IGluIHRoZSBXSU5FRDNEUlNfV1JBUDEgcmVuZGVyCiAgICAgICAgICAgICAgICAgIHN0YXRlLiBXZSBkbyBub3QgKHlldCkgc3VwcG9ydCB0aGUgRDNEUkVOREVSU1RBVEVfV1JBUHggdmFsdWVzLCBub3IgdGllIHRoZW0gdXAKICAgICAgICAgICAgICAgICAgdG8gdGhlIFRFWENPT1JESU5ERVggdmFsdWUgKi8KCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBCZSBjYXJlZnVsIHRoZSB2YWx1ZSBvZiB0aGUgbWFzayAweEYwMDAwIGNvbWUgZnJvbSBkM2Q4dHlwZXMuaCBpbmZvcwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3dpdGNoIChWYWx1ZSAmIDB4RkZGRjAwMDApIHsKICAgICAgICAgICAgY2FzZSBEM0RUU1NfVENJX1BBU1NUSFJVOgogICAgICAgICAgICAgICAgLypVc2UgdGhlIHNwZWNpZmllZCB0ZXh0dXJlIGNvb3JkaW5hdGVzIGNvbnRhaW5lZCB3aXRoaW4gdGhlIHZlcnRleCBmb3JtYXQuIFRoaXMgdmFsdWUgcmVzb2x2ZXMgdG8gemVyby4qLwogICAgICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfR0VOX1MpOwogICAgICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfR0VOX1QpOwogICAgICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfR0VOX1IpOwogICAgICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfR0VOX1EpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9URVhUVVJFX0dFTl9TLFQsUixRKSIpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEQzRFRTU19UQ0lfQ0FNRVJBU1BBQ0VQT1NJVElPTjoKICAgICAgICAgICAgICAgIC8qIENhbWVyYVNwYWNlUG9zaXRpb24gbWVhbnMgdXNlIHRoZSB2ZXJ0ZXggcG9zaXRpb24sIHRyYW5zZm9ybWVkIHRvIGNhbWVyYSBzcGFjZSwKICAgICAgICAgICAgICAgICAgICBhcyB0aGUgaW5wdXQgdGV4dHVyZSBjb29yZGluYXRlcyBmb3IgdGhpcyBzdGFnZSdzIHRleHR1cmUgdHJhbnNmb3JtYXRpb24uIFRoaXMKICAgICAgICAgICAgICAgICAgICBlcXVhdGVzIHJvdWdobHkgdG8gRVlFX0xJTkVBUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmbG9hdCBzX3BsYW5lW10gPSB7IDEuMCwgMC4wLCAwLjAsIDAuMCB9OwogICAgICAgICAgICAgICAgICAgIGZsb2F0IHRfcGxhbmVbXSA9IHsgMC4wLCAxLjAsIDAuMCwgMC4wIH07CiAgICAgICAgICAgICAgICAgICAgZmxvYXQgcl9wbGFuZVtdID0geyAwLjAsIDAuMCwgMS4wLCAwLjAgfTsKICAgICAgICAgICAgICAgICAgICBmbG9hdCBxX3BsYW5lW10gPSB7IDAuMCwgMC4wLCAwLjAsIDEuMCB9OwogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJXSU5FRDNEVFNTX1RDSV9DQU1FUkFTUEFDRVBPU0lUSU9OIC0gU2V0IGV5ZSBwbGFuZVxuIik7CiAgICAKICAgICAgICAgICAgICAgICAgICBnbE1hdHJpeE1vZGUoR0xfTU9ERUxWSUVXKTsKICAgICAgICAgICAgICAgICAgICBnbFB1c2hNYXRyaXgoKTsKICAgICAgICAgICAgICAgICAgICBnbExvYWRJZGVudGl0eSgpOwogICAgICAgICAgICAgICAgICAgIGdsVGV4R2VuZnYoR0xfUywgR0xfRVlFX1BMQU5FLCBzX3BsYW5lKTsKICAgICAgICAgICAgICAgICAgICBnbFRleEdlbmZ2KEdMX1QsIEdMX0VZRV9QTEFORSwgdF9wbGFuZSk7CiAgICAgICAgICAgICAgICAgICAgZ2xUZXhHZW5mdihHTF9SLCBHTF9FWUVfUExBTkUsIHJfcGxhbmUpOwogICAgICAgICAgICAgICAgICAgIGdsVGV4R2VuZnYoR0xfUSwgR0xfRVlFX1BMQU5FLCBxX3BsYW5lKTsKICAgICAgICAgICAgICAgICAgICBnbFBvcE1hdHJpeCgpOwogICAgCiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIldJTkVEM0RUU1NfVENJX0NBTUVSQVNQQUNFUE9TSVRJT04gLSBTZXQgR0xfVEVYVFVSRV9HRU5feCBhbmQgR0xfeCwgR0xfVEVYVFVSRV9HRU5fTU9ERSwgR0xfRVlFX0xJTkVBUlxuIik7CiAgICAgICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV9HRU5fUyk7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1RFWFRVUkVfR0VOX1MpOyIpOwogICAgICAgICAgICAgICAgICAgIGdsVGV4R2VuaShHTF9TLCBHTF9URVhUVVJFX0dFTl9NT0RFLCBHTF9FWUVfTElORUFSKTsKICAgICAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhHZW5pKEdMX1MsIEdMX1RFWFRVUkVfR0VOX01PREUsIEdMX0VZRV9MSU5FQVIpIik7CiAgICAgICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV9HRU5fVCk7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1RFWFRVUkVfR0VOX1QpOyIpOwogICAgICAgICAgICAgICAgICAgIGdsVGV4R2VuaShHTF9ULCBHTF9URVhUVVJFX0dFTl9NT0RFLCBHTF9FWUVfTElORUFSKTsKICAgICAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhHZW5pKEdMX1QsIEdMX1RFWFRVUkVfR0VOX01PREUsIEdMX0VZRV9MSU5FQVIpIik7CiAgICAgICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV9HRU5fUik7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1RFWFRVUkVfR0VOX1IpOyIpOwogICAgICAgICAgICAgICAgICAgIGdsVGV4R2VuaShHTF9SLCBHTF9URVhUVVJFX0dFTl9NT0RFLCBHTF9FWUVfTElORUFSKTsKICAgICAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhHZW5pKEdMX1IsIEdMX1RFWFRVUkVfR0VOX01PREUsIEdMX0VZRV9MSU5FQVIpIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgRDNEVFNTX1RDSV9DQU1FUkFTUEFDRU5PUk1BTDoKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChOVl9URVhHRU5fUkVGTEVDVElPTikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgc19wbGFuZVtdID0geyAxLjAsIDAuMCwgMC4wLCAwLjAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgdF9wbGFuZVtdID0geyAwLjAsIDEuMCwgMC4wLCAwLjAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgcl9wbGFuZVtdID0geyAwLjAsIDAuMCwgMS4wLCAwLjAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgcV9wbGFuZVtdID0geyAwLjAsIDAuMCwgMC4wLCAxLjAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIldJTkVEM0RUU1NfVENJX0NBTUVSQVNQQUNFTk9STUFMIC0gU2V0IGV5ZSBwbGFuZVxuIik7CiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGdsTWF0cml4TW9kZShHTF9NT0RFTFZJRVcpOwogICAgICAgICAgICAgICAgICAgICAgICBnbFB1c2hNYXRyaXgoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZ2xMb2FkSWRlbnRpdHkoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZ2xUZXhHZW5mdihHTF9TLCBHTF9FWUVfUExBTkUsIHNfcGxhbmUpOwogICAgICAgICAgICAgICAgICAgICAgICBnbFRleEdlbmZ2KEdMX1QsIEdMX0VZRV9QTEFORSwgdF9wbGFuZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGdsVGV4R2VuZnYoR0xfUiwgR0xfRVlFX1BMQU5FLCByX3BsYW5lKTsKICAgICAgICAgICAgICAgICAgICAgICAgZ2xUZXhHZW5mdihHTF9RLCBHTF9FWUVfUExBTkUsIHFfcGxhbmUpOwogICAgICAgICAgICAgICAgICAgICAgICBnbFBvcE1hdHJpeCgpOwogICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9URVhUVVJFX0dFTl9TKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1RFWFRVUkVfR0VOX1MpOyIpOwogICAgICAgICAgICAgICAgICAgICAgICBnbFRleEdlbmkoR0xfUywgR0xfVEVYVFVSRV9HRU5fTU9ERSwgR0xfTk9STUFMX01BUF9OVik7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEdlbmkoR0xfUywgR0xfVEVYVFVSRV9HRU5fTU9ERSwgR0xfTk9STUFMX01BUF9OVikiKTsKICAgICAgICAgICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV9HRU5fVCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9URVhUVVJFX0dFTl9UKTsiKTsKICAgICAgICAgICAgICAgICAgICAgICAgZ2xUZXhHZW5pKEdMX1QsIEdMX1RFWFRVUkVfR0VOX01PREUsIEdMX05PUk1BTF9NQVBfTlYpOwogICAgICAgICAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhHZW5pKEdMX1QsIEdMX1RFWFRVUkVfR0VOX01PREUsIEdMX05PUk1BTF9NQVBfTlYpIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfR0VOX1IpOwogICAgICAgICAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfVEVYVFVSRV9HRU5fUik7Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIGdsVGV4R2VuaShHTF9SLCBHTF9URVhUVVJFX0dFTl9NT0RFLCBHTF9OT1JNQUxfTUFQX05WKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4R2VuaShHTF9SLCBHTF9URVhUVVJFX0dFTl9NT0RFLCBHTF9OT1JNQUxfTUFQX05WKSIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBEM0RUU1NfVENJX0NBTUVSQVNQQUNFUkVGTEVDVElPTlZFQ1RPUjoKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChOVl9URVhHRU5fUkVGTEVDVElPTikpIHsKICAgICAgICAgICAgICAgICAgICBmbG9hdCBzX3BsYW5lW10gPSB7IDEuMCwgMC4wLCAwLjAsIDAuMCB9OwogICAgICAgICAgICAgICAgICAgIGZsb2F0IHRfcGxhbmVbXSA9IHsgMC4wLCAxLjAsIDAuMCwgMC4wIH07CiAgICAgICAgICAgICAgICAgICAgZmxvYXQgcl9wbGFuZVtdID0geyAwLjAsIDAuMCwgMS4wLCAwLjAgfTsKICAgICAgICAgICAgICAgICAgICBmbG9hdCBxX3BsYW5lW10gPSB7IDAuMCwgMC4wLCAwLjAsIDEuMCB9OwogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJXSU5FRDNEVFNTX1RDSV9DQU1FUkFTUEFDRVJFRkxFQ1RJT05WRUNUT1IgLSBTZXQgZXllIHBsYW5lXG4iKTsKICAgIAogICAgICAgICAgICAgICAgICAgIGdsTWF0cml4TW9kZShHTF9NT0RFTFZJRVcpOwogICAgICAgICAgICAgICAgICAgIGdsUHVzaE1hdHJpeCgpOwogICAgICAgICAgICAgICAgICAgIGdsTG9hZElkZW50aXR5KCk7CiAgICAgICAgICAgICAgICAgICAgZ2xUZXhHZW5mdihHTF9TLCBHTF9FWUVfUExBTkUsIHNfcGxhbmUpOwogICAgICAgICAgICAgICAgICAgIGdsVGV4R2VuZnYoR0xfVCwgR0xfRVlFX1BMQU5FLCB0X3BsYW5lKTsKICAgICAgICAgICAgICAgICAgICBnbFRleEdlbmZ2KEdMX1IsIEdMX0VZRV9QTEFORSwgcl9wbGFuZSk7CiAgICAgICAgICAgICAgICAgICAgZ2xUZXhHZW5mdihHTF9RLCBHTF9FWUVfUExBTkUsIHFfcGxhbmUpOwogICAgICAgICAgICAgICAgICAgIGdsUG9wTWF0cml4KCk7CiAgICAKICAgICAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9URVhUVVJFX0dFTl9TKTsKICAgICAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfVEVYVFVSRV9HRU5fUyk7Iik7CiAgICAgICAgICAgICAgICAgICAgZ2xUZXhHZW5pKEdMX1MsIEdMX1RFWFRVUkVfR0VOX01PREUsIEdMX1JFRkxFQ1RJT05fTUFQX05WKTsKICAgICAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhHZW5pKEdMX1MsIEdMX1RFWFRVUkVfR0VOX01PREUsIEdMX1JFRkxFQ1RJT05fTUFQX05WKSIpOwogICAgICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfR0VOX1QpOwogICAgICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9URVhUVVJFX0dFTl9UKTsiKTsKICAgICAgICAgICAgICAgICAgICBnbFRleEdlbmkoR0xfVCwgR0xfVEVYVFVSRV9HRU5fTU9ERSwgR0xfUkVGTEVDVElPTl9NQVBfTlYpOwogICAgICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEdlbmkoR0xfVCwgR0xfVEVYVFVSRV9HRU5fTU9ERSwgR0xfUkVGTEVDVElPTl9NQVBfTlYpIik7CiAgICAgICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV9HRU5fUik7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1RFWFRVUkVfR0VOX1IpOyIpOwogICAgICAgICAgICAgICAgICAgIGdsVGV4R2VuaShHTF9SLCBHTF9URVhUVVJFX0dFTl9NT0RFLCBHTF9SRUZMRUNUSU9OX01BUF9OVik7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4R2VuaShHTF9SLCBHTF9URVhUVVJFX0dFTl9NT0RFLCBHTF9SRUZMRUNUSU9OX01BUF9OVikiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIC8qIFVuaGFuZGxlZCB0eXBlczogKi8KICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIC8qIFRvZG86ICovCiAgICAgICAgICAgICAgICAvKiA/IGRpc2FibGUgR0xfVEVYVFVSRV9HRU5fbiA/ICovCiAgICAgICAgICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV9HRU5fUyk7CiAgICAgICAgICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV9HRU5fVCk7CiAgICAgICAgICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV9HRU5fUik7CiAgICAgICAgICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV9HRU5fUSk7CiAgICAgICAgICAgICAgICBGSVhNRSgiVW5oYW5kbGVkIFdJTkVEM0RUU1NfVEVYQ09PUkRJTkRFWCAlbHhcbiIsIFZhbHVlKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICAvKiBVbmhhbmRsZWQgKi8KICAgIGNhc2UgV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1MgOgogICAgICAgIHNldF90ZXh0dXJlX21hdHJpeCgoZmxvYXQgKikmVGhpcy0+c3RhdGVCbG9jay0+dHJhbnNmb3Jtc1tEM0RUU19URVhUVVJFMCArIFN0YWdlXS51Lm1bMF1bMF0sIFZhbHVlLCAoVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW1N0YWdlXVtXSU5FRDNEVFNTX1RFWENPT1JESU5ERVhdICYgMHhGRkZGMDAwMCkgIT0gRDNEVFNTX1RDSV9QQVNTVEhSVSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEVFNTX0JVTVBFTlZNQVQwMCAgICAgICAgICA6CiAgICBjYXNlIFdJTkVEM0RUU1NfQlVNUEVOVk1BVDAxICAgICAgICAgIDoKICAgICAgICBUUkFDRSgiQlVNUEVOVk1BVDAldSBTdGFnZT0lbGQsIFR5cGU9JWQsIFZhbHVlID0lbGRcbiIsIFR5cGUgLSBXSU5FRDNEVFNTX0JVTVBFTlZNQVQwMCwgU3RhZ2UsIFR5cGUsIFZhbHVlKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFRTU19CVU1QRU5WTUFUMTAgICAgICAgICAgOgogICAgY2FzZSBXSU5FRDNEVFNTX0JVTVBFTlZNQVQxMSAgICAgICAgICA6CiAgICAgICAgVFJBQ0UoIkJVTVBFTlZNQVQxJXUgU3RhZ2U9JWxkLCBUeXBlPSVkLCBWYWx1ZSA9JWxkXG4iLCBUeXBlIC0gV0lORUQzRFRTU19CVU1QRU5WTUFUMTAsIFN0YWdlLCBUeXBlLCBWYWx1ZSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEVFNTX0JVTVBFTlZMU0NBTEUgICAgICAgICA6CiAgICAgIFRSQUNFKCJCVU1QRU5WTFNDQUxFIFN0YWdlPSVsZCwgVHlwZT0lZCwgVmFsdWUgPSVsZFxuIiwgU3RhZ2UsIFR5cGUsIFZhbHVlKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEVFNTX0JVTVBFTlZMT0ZGU0VUICAgICAgICA6CiAgICAgIFRSQUNFKCJCVU1QRU5WTE9GRlNFVCBTdGFnZT0lbGQsIFR5cGU9JWQsIFZhbHVlID0lbGRcbiIsIFN0YWdlLCBUeXBlLCBWYWx1ZSk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFRTU19SRVNVTFRBUkcgICAgICAgICAgICAgOgogICAgICBUUkFDRSgiUkVTVUxUQVJHIFN0aWxsIGEgc3R1YiwgU3RhZ2U9JWxkLCBUeXBlPSVkLCBWYWx1ZSA9JWxkXG4iLCBTdGFnZSwgVHlwZSwgVmFsdWUpOwogICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIC8qIFB1dCBiYWNrIGxhdGVyOiBGSVhNRSgiKCVwKSA6IHN0dWIsIFN0YWdlPSVsZCwgVHlwZT0lZCwgVmFsdWUgPSVsZFxuIiwgVGhpcywgU3RhZ2UsIFR5cGUsIFZhbHVlKTsgKi8KICAgICAgICBUUkFDRSgiU3RpbGwgYSBzdHViLCBTdGFnZT0lbGQsIFR5cGU9JWQsIFZhbHVlID0lbGRcbiIsIFN0YWdlLCBUeXBlLCBWYWx1ZSk7CiAgICB9CgogICAgTEVBVkVfR0woKTsKCiAgICByZXR1cm47Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgVGV4dHVyZSBTdGFnZSBTdGF0ZXMKICogVE9ETzogVmVyaWZ5IGFnYWluc3QgZHg5IGRlZmluaXRpb25zCiAqKioqKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFRleHR1cmVTdGFnZVN0YXRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgU3RhZ2UsIFdJTkVEM0RURVhUVVJFU1RBR0VTVEFURVRZUEUgVHlwZSwgRFdPUkQgVmFsdWUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICAvKiBGSVhNRTogSGFuZGxlIDNkIHRleHR1cmVzPyBXaGF0IGlmIFRTUyB2YWx1ZSBzZXQgYmVmb3JlIHNldCB0ZXh0dXJlPyBOZWVkIHRvIHJlYXBwbHkgYWxsIHZhbHVlcz8gKi8KCiAgICBUUkFDRSgiKCVwKSA6IFN0YWdlPSVsZCwgVHlwZT0lcyglZCksIFZhbHVlPSVsZFxuIiwgVGhpcywgU3RhZ2UsIGRlYnVnX2QzZHRleHR1cmVzdGF0ZShUeXBlKSwgVHlwZSwgVmFsdWUpOwoKICAgIC8qIFJlamVjdCBpbnZhbGlkIHRleHR1cmUgdW5pdHMgKi8KICAgIGlmIChTdGFnZSA+PSBHTF9MSU1JVFModGV4dHVyZXMpKSB7CiAgICAgICAgVFJBQ0UoIkF0dGVtcHQgdG8gYWNjZXNzIGludmFsaWQgdGV4dHVyZSByZWplY3RlZFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdICAgICA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdICAgICAgICAgPSBWYWx1ZTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFRleHR1cmVTdGFnZVN0YXRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgU3RhZ2UsIFdJTkVEM0RURVhUVVJFU1RBR0VTVEFURVRZUEUgVHlwZSwgRFdPUkQqIHBWYWx1ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiByZXF1ZXN0aW5nIFN0YWdlICVsZCwgVHlwZSAlZCBnZXR0aW5nICVsZFxuIiwgVGhpcywgU3RhZ2UsIFR5cGUsIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtTdGFnZV1bVHlwZV0pOwogICAgKnBWYWx1ZSA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtTdGFnZV1bVHlwZV07CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBUZXh0dXJlCiAqKioqKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFRleHR1cmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBTdGFnZSwgSVdpbmVEM0RCYXNlVGV4dHVyZSogcFRleHR1cmUpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlICAgKm9sZFRleHR1cmU7CgogICAgb2xkVGV4dHVyZSA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW1N0YWdlXTsKICAgIFRSQUNFKCIoJXApIDogU3RhZ2UoJWxkKSwgVGV4dHVyZSAoJXApXG4iLCBUaGlzLCBTdGFnZSwgcFRleHR1cmUpOwoKI2lmIDAgLyogVE9ETzogY2hlY2sgc28gdmVydGV4IHRleHR1cmVzICovCiAgICBpZiAoU3RhZ2UgPj0gRDNEVkVSVEVYVEVYVFVSRVNBTVBMRVIgJiYgU3RhZ2UgPD0gRDNEVkVSVEVYVEVYVFVSRVNBTVBMRVIzKXsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhUZXh0dXJlc1tTdGFnZSAtIEQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSXSA9IHBUZXh0dXJlOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQojZW5kaWYKCiAgICAvKiBSZWplY3QgaW52YWxpZCB0ZXh0dXJlIHVuaXRzICovCiAgICBpZiAoU3RhZ2UgPj0gR0xfTElNSVRTKHRleHR1cmVzKSB8fCBTdGFnZSA8IDApIHsKICAgICAgICBXQVJOKCJBdHRlbXB0IHRvIGFjY2VzcyBpbnZhbGlkIHRleHR1cmUgcmVqZWN0ZWRcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmKHBUZXh0dXJlICE9IE5VTEwpIHsKICAgICAgICAvKiBTZXRUZXh0dXJlIGlzbid0IGFsbG93ZWQgb24gdGV4dHVyZXMgaW4gV0lORUQzRFBPT0xfU0NSQVRDSDsgVGhlIHNhbWUgaXMKICAgICAgICAqICB0aGUgY2FzZSBmb3IgV0lORUQzRFBPT0xfU1lTVEVNTUVNIHRleHR1cmVzIHVubGVzcyBXSU5FRDNEREVWQ0FQU19URVhUVVJFU1lTVEVNTU9SWSBpcyBzZXQuCiAgICAgICAgKiAgV2UgZG9uJ3QgY2hlY2sgdGhlIGNhcHMgYXMgR2V0RGV2aWNlQ2FwcyBpcyBpbmVmZmljaWVudCBhbmQgd2UgZG9uJ3Qgc2V0IHRoZSBjYXAgYW55d2F5LgogICAgICAgICovCiAgICAgICAgaWYoKChJV2luZUQzRFRleHR1cmVJbXBsKilwVGV4dHVyZSktPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfU0NSQVRDSCB8fCAoKElXaW5lRDNEVGV4dHVyZUltcGwqKXBUZXh0dXJlKS0+cmVzb3VyY2UucG9vbCA9PSBXSU5FRDNEUE9PTF9TWVNURU1NRU0pIHsKICAgICAgICAgICAgV0FSTigiKCVwKSBBdHRlbXB0IHRvIHNldCBzY3JhdGNoIHRleHR1cmUgcmVqZWN0ZWRcbiIsIHBUZXh0dXJlKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgfQoKICAgIG9sZFRleHR1cmUgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tTdGFnZV07CiAgICBUUkFDRSgiR0xfTElNSVRTICVkXG4iLEdMX0xJTUlUUyh0ZXh0dXJlcykpOwogICAgVFJBQ0UoIiglcCkgOiBvbGR0ZXh0dXJlKCVwKVxuIiwgVGhpcyxvbGRUZXh0dXJlKTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQudGV4dHVyZXNbU3RhZ2VdICAgICA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnRleHR1cmVzW1N0YWdlXSA9IFRSVUU7CiAgICBUUkFDRSgiKCVwKSA6IHNldHRpbmcgbmV3IHRleHR1cmUgdG8gJXBcbiIsIFRoaXMsIHBUZXh0dXJlKTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW1N0YWdlXSAgICAgICAgID0gcFRleHR1cmU7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgLyoqIE5PVEU6IE1TRE4gc2F5cyB0aGF0IHNldFRleHR1cmUgaW5jcmVhc2VzIHRoZSByZWZlcmVuY2UgY291bnQsCiAgICAqIGFuZCB0aGUgdGhlIGFwcGxpY2F0aW9uIG51c3Qgc2V0IHRoZSB0ZXh0dXJlIGJhY2sgdG8gbnVsbCAob3IgaGF2ZSBhIGxlYWt5IGFwcGxpY2F0aW9uKSwKICAgICogVGhpcyBtZWFucyB3ZSBzaG91bGQgcGFzcyB0aGUgcmVmY291bnQgdXAgdG8gdGhlIHBhcmVudAogICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICBpZiAoTlVMTCAhPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tTdGFnZV0pIHsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX0FkZFJlZihUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tTdGFnZV0pOwogICAgfQoKICAgIGlmIChOVUxMICE9IG9sZFRleHR1cmUpIHsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2Uob2xkVGV4dHVyZSk7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRUZXh0dXJlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgU3RhZ2UsIElXaW5lRDNEQmFzZVRleHR1cmUqKiBwcFRleHR1cmUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogKCVsZCAvKiBTdGFnZSAqLywlcCAvKiBwcFRleHR1cmUgKi8pXG4iLCBUaGlzLCBTdGFnZSwgcHBUZXh0dXJlKTsKCiAgICAvKiBSZWplY3QgaW52YWxpZCB0ZXh0dXJlIHVuaXRzICovCiAgICBpZiAoU3RhZ2UgPj0gR0xfTElNSVRTKHRleHR1cmVzKSkgewogICAgICAgIFRSQUNFKCJBdHRlbXB0IHRvIGFjY2VzcyBpbnZhbGlkIHRleHR1cmUgcmVqZWN0ZWRcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgKnBwVGV4dHVyZT1UaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tTdGFnZV07CiAgICBpZiAoKnBwVGV4dHVyZSkKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX0FkZFJlZigqcHBUZXh0dXJlKTsKICAgIGVsc2UKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IEJhY2sgQnVmZmVyCiAqKioqKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldEJhY2tCdWZmZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIGlTd2FwQ2hhaW4sIFVJTlQgQmFja0J1ZmZlciwgV0lORUQzREJBQ0tCVUZGRVJfVFlQRSBUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKipwcEJhY2tCdWZmZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwQ2hhaW47CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApIDogQmFja0J1ZiAlZCBUeXBlICVkIFN3YXBDaGFpbiAlZCByZXR1cm5pbmcgJXBcbiIsIFRoaXMsIEJhY2tCdWZmZXIsIFR5cGUsIGlTd2FwQ2hhaW4sICpwcEJhY2tCdWZmZXIpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgIGlTd2FwQ2hhaW4sICZzd2FwQ2hhaW4pOwogICAgaWYgKGhyID09IFdJTkVEM0RfT0spIHsKICAgICAgICBociA9IElXaW5lRDNEU3dhcENoYWluX0dldEJhY2tCdWZmZXIoc3dhcENoYWluLCBCYWNrQnVmZmVyLCBUeXBlLCBwcEJhY2tCdWZmZXIpOwogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBDaGFpbik7CiAgICB9IGVsc2UgewogICAgICAgICpwcEJhY2tCdWZmZXIgPSBOVUxMOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0RGV2aWNlQ2FwcyhJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RDQVBTKiBwQ2FwcykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV0FSTigiKCVwKSA6IHN0dWIsIGNhbGxpbmcgaWRpcmVjdDNkIGZvciBub3dcbiIsIFRoaXMpOwogICAgcmV0dXJuIElXaW5lRDNEX0dldERldmljZUNhcHMoVGhpcy0+d2luZUQzRCwgVGhpcy0+YWRhcHRlck5vLCBUaGlzLT5kZXZUeXBlLCBwQ2Fwcyk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXREaXNwbGF5TW9kZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgV0lORUQzRERJU1BMQVlNT0RFKiBwTW9kZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBDaGFpbjsKICAgIEhSRVNVTFQgaHI7CgogICAgaHIgPSBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKGlmYWNlLCAgaVN3YXBDaGFpbiwgKElXaW5lRDNEU3dhcENoYWluICoqKSZzd2FwQ2hhaW4pOwogICAgaWYgKGhyID09IFdJTkVEM0RfT0spIHsKICAgICAgICBociA9IElXaW5lRDNEU3dhcENoYWluX0dldERpc3BsYXlNb2RlKHN3YXBDaGFpbiwgcE1vZGUpOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcENoYWluKTsKICAgIH0gZWxzZSB7CiAgICAgICAgRklYTUUoIiglcCkgRXJyb3IgZ2V0dGluZyBkaXNwbGF5IG1vZGVcbiIsIFRoaXMpOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0SFdORChJV2luZUQzRERldmljZSAqaWZhY2UsIEhXTkQgaFduZCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIGhXbmQpOwoKICAgIFRoaXMtPmRkcmF3X3dpbmRvdyA9IGhXbmQ7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldEhXTkQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBIV05EICpoV25kKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgaFduZCk7CgogICAgKmhXbmQgPSBUaGlzLT5kZHJhd193aW5kb3c7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIFN0YXRlYmxvY2sgcmVsYXRlZCBmdW5jdGlvbnMKICoqKioqLwoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0JlZ2luU3RhdGVCbG9jayhJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3RhdGVCbG9ja0ltcGwgKm9iamVjdDsKICAgIFRSQUNFKCIoJXApIiwgVGhpcyk7CiAgICAKICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAKICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCkpOwogICAgaWYgKE5VTEwgPT0gb2JqZWN0ICkgewogICAgICAgIEZJWE1FKCIoJXApRXJyb3IgYWxsb2NhdGluZyBtZW1vcnkgZm9yIHN0YXRlYmxvY2tcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQogICAgVFJBQ0UoIiglcCkgY3JldGVkIG9iamVjdCAlcFxuIiwgVGhpcywgb2JqZWN0KTsKICAgIG9iamVjdC0+d2luZUQzRERldmljZT0gVGhpczsKICAgIC8qKiBGSVhNRTogb2JqZWN0LT5wYXJlbnQgICAgICAgPSBwYXJlbnQ7ICoqLwogICAgb2JqZWN0LT5wYXJlbnQgICAgICAgPSBOVUxMOwogICAgb2JqZWN0LT5ibG9ja1R5cGUgICAgPSBXSU5FRDNEU0JUX0FMTDsKICAgIG9iamVjdC0+cmVmICAgICAgICAgID0gMTsKICAgIG9iamVjdC0+bHBWdGJsICAgICAgID0gJklXaW5lRDNEU3RhdGVCbG9ja19WdGJsOwoKICAgIElXaW5lRDNEU3RhdGVCbG9ja19SZWxlYXNlKChJV2luZUQzRFN0YXRlQmxvY2sqKVRoaXMtPnVwZGF0ZVN0YXRlQmxvY2spOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jayA9IG9iamVjdDsKICAgIFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUgPSBUUlVFOwoKICAgIFRSQUNFKCIoJXApIHJlY29yZGluZyBzdGF0ZWJsb2NrICVwXG4iLFRoaXMgLCBvYmplY3QpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9FbmRTdGF0ZUJsb2NrKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdGF0ZUJsb2NrKiogcHBTdGF0ZUJsb2NrKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgaWYgKCFUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgRklYTUUoIiglcCkgbm90IHJlY29yZGluZyEgcmV0dXJuaW5nIGVycm9yXG4iLCBUaGlzKTsKICAgICAgICAqcHBTdGF0ZUJsb2NrID0gTlVMTDsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAqcHBTdGF0ZUJsb2NrID0gKElXaW5lRDNEU3RhdGVCbG9jayopVGhpcy0+dXBkYXRlU3RhdGVCbG9jazsKICAgIFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUgPSBGQUxTRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgPSBUaGlzLT5zdGF0ZUJsb2NrOwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrX0FkZFJlZigoSVdpbmVEM0RTdGF0ZUJsb2NrKilUaGlzLT51cGRhdGVTdGF0ZUJsb2NrKTsKICAgIC8qIElXaW5lRDNEU3RhdGVCbG9ja19BZGRSZWYoKnBwU3RhdGVCbG9jayk7IGRvbid0IG5lZWQgdG8gZG8gdGhpcywgc2luY2Ugd2Ugc2hvdWxkIHJlYWxseSBqdXN0IHJlbGVhc2UgVXBkYXRlU3RhdGVCbG9jayBmaXJzdCAqLwogICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nIHRva2VuIChwdHIgdG8gc3RhdGVibG9jaykgb2YgJXBcbiIsIFRoaXMsICpwcFN0YXRlQmxvY2spOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBTY2VuZSByZWxhdGVkIGZ1bmN0aW9ucwogKioqKiovCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9CZWdpblNjZW5lKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgLyogQXQgdGhlIG1vbWVudCB3ZSBoYXZlIG5vIG5lZWQgZm9yIGFueSBmdW5jdGlvbmFsaXR5IGF0IHRoZSBiZWdpbm5pbmcKICAgICAgIG9mIGEgc2NlbmUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogc3R1YlxuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0VuZFNjZW5lKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwogICAgRU5URVJfR0woKTsKICAgIC8qIFdlIG9ubHkgaGF2ZSB0byBkbyB0aGlzIGlmIHdlIG5lZWQgdG8gcmVhZCB0aGUsIHN3YXBidWZmZXJzIHBlcmZvcm1zIGEgZmx1c2ggZm9yIHVzICovCiAgICBnbEZsdXNoKCk7CiAgICBjaGVja0dMY2FsbCgiZ2xGbHVzaCIpOwoKICAgIFRSQUNFKCJFbmQgU2NlbmVcbiIpOwogICAgaWYoVGhpcy0+cmVuZGVyVGFyZ2V0ICE9IE5VTEwpIHsKCiAgICAgICAgLyogSWYgdGhlIGNvbnRhaW5lciBvZiB0aGUgcmVuZGVydGFyZ2V0IGlzIGEgdGV4dHVyZSB0aGVuIHdlIG5lZWQgdG8gc2F2ZSB0aGUgZGF0YSBmcm9tIHRoZSBwYnVmZmVyICovCiAgICAgICAgSVVua25vd24gKnRhcmdldENvbnRhaW5lciA9IE5VTEw7CiAgICAgICAgaWYgKFdJTkVEM0RfT0sgPT0gSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihUaGlzLT5yZW5kZXJUYXJnZXQsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJnRhcmdldENvbnRhaW5lcikKICAgICAgICAgICAgfHwgV0lORUQzRF9PSyA9PSBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKFRoaXMtPnJlbmRlclRhcmdldCwgJklJRF9JV2luZUQzRERldmljZSwgKHZvaWQgKiopJnRhcmdldENvbnRhaW5lcikpIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgOiBUZXh0dXJlIHJlbmRlcnRhcmdldCAlcFxuIiwgVGhpcyAsVGhpcy0+cmVuZGVyVGFyZ2V0KTsKICAgICAgICAgICAgLyoqIGFsd2F5cyBkaXJ0aWZ5IGZvciBub3cuIHdlIG11c3QgZmluZCBhIGJldHRlciB3YXkgdG8gc2VlIHRoYXQgc3VyZmFjZSBoYXZlIGJlZW4gbW9kaWZpZWQKICAgICAgICAgICAgKE1vZGlmaWNhdGlvbnMgc2hvdWxkIHdpbGwgb25seSBvY2N1ciB2aWEgZHJhdy1wcmltaXRpdmUsIGJ1dCB3ZSBkbyBuZWVkIGJldHRlciBsb2NraW5nCiAgICAgICAgICAgIHN3aXRjaGluZyB0byByZW5kZXItdG8tdGV4dHVyZSBzaG91bGQgcmVtb3ZlIHRoZSBvdmVyaGVhZCB0aG91Z2guCiAgICAgICAgICAgICovCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRQQnVmZmVyU3RhdGUoVGhpcy0+cmVuZGVyVGFyZ2V0LCBUUlVFIC8qIGluUEJ1ZmZlciAqLywgRkFMU0UgLyogaW5UZXh0dXJlICovKTsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZERpcnR5UmVjdChUaGlzLT5yZW5kZXJUYXJnZXQsIE5VTEwpOwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChUaGlzLT5yZW5kZXJUYXJnZXQpOwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0UEJ1ZmZlclN0YXRlKFRoaXMtPnJlbmRlclRhcmdldCwgRkFMU0UgLyogaW5QQnVmZmVyICovLCBGQUxTRSAvKiBpblRleHR1cmUgKi8pOwogICAgICAgICAgICBJVW5rbm93bl9SZWxlYXNlKHRhcmdldENvbnRhaW5lcik7CiAgICAgICAgfQogICAgfQogICAgVGhpcy0+c2NlbmVFbmRlZCA9IFRSVUU7CiAgICBMRUFWRV9HTCgpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9QcmVzZW50KElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09OU1QgUkVDVCogcFNvdXJjZVJlY3QsIENPTlNUIFJFQ1QqIHBEZXN0UmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSFdORCBoRGVzdFdpbmRvd092ZXJyaWRlLCBDT05TVCBSR05EQVRBKiBwRGlydHlSZWdpb24pIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwQ2hhaW4gPSBOVUxMOwogICAgaW50IGk7CiAgICBpbnQgc3dhcGNoYWlucyA9IElXaW5lRDNERGV2aWNlSW1wbF9HZXROdW1iZXJPZlN3YXBDaGFpbnMoaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApIFByZXNlbnRpbmcgdGhlIGZyYW1lXG4iLCBUaGlzKTsKCiAgICBmb3IoaSA9IDAgOyBpIDwgc3dhcGNoYWlucyA7IGkgKyspIHsKCiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgaSAsIChJV2luZUQzRFN3YXBDaGFpbiAqKikmc3dhcENoYWluKTsKICAgICAgICBUUkFDRSgicHJlc2VudGlubmcgY2hhaW4gJWQsICVwXG4iLCBpLCBzd2FwQ2hhaW4pOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1ByZXNlbnQoc3dhcENoYWluLCBwU291cmNlUmVjdCwgcERlc3RSZWN0LCBoRGVzdFdpbmRvd092ZXJyaWRlLCBwRGlydHlSZWdpb24sIDApOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcENoYWluKTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NsZWFyKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgQ291bnQsIENPTlNUIEQzRFJFQ1QqIHBSZWN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLCBEM0RDT0xPUiBDb2xvciwgZmxvYXQgWiwgRFdPUkQgU3RlbmNpbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIC8qIFRPRE86IEZyb20gTVNETiBUaGlzIG1ldGhvZCBmYWlscyBpZiB5b3Ugc3BlY2lmeSB0aGUgRDNEQ0xFQVJfWkJVRkZFUiBvciBEM0RDTEVBUl9TVEVOQ0lMIGZsYWdzIHdoZW4gdGhlCiAgICAgIHJlbmRlciB0YXJnZXQgZG9lcyBub3QgaGF2ZSBhbiBhdHRhY2hlZCBkZXB0aCBidWZmZXIuIFNpbWlsYXJseSwgaWYgeW91IHNwZWNpZnkgdGhlIEQzRENMRUFSX1NURU5DSUwgZmxhZwogICAgICB3aGVuIHRoZSBkZXB0aC1idWZmZXIgZm9ybWF0IGRvZXMgbm90IGNvbnRhaW4gc3RlbmNpbCBidWZmZXIgaW5mb3JtYXRpb24sIHRoaXMgbWV0aG9kIGZhaWxzLiAqLwogICAgR0xiaXRmaWVsZCAgICAgZ2xNYXNrID0gMDsKICAgIEdMYm9vbGVhbiAgICAgIG9sZF96dGVzdDsKICAgIEdMZmxvYXQgICAgICAgIG9sZF96X2NsZWFyX3ZhbHVlOwogICAgR0xpbnQgICAgICAgICAgb2xkX3N0ZW5jaWxfY2xlYXJfdmFsdWU7CiAgICBHTGZsb2F0ICAgICAgICBvbGRfY29sb3JfY2xlYXJfdmFsdWVbNF07CiAgICB1bnNpZ25lZCBpbnQgICBpOwogICAgQ09OU1QgRDNEUkVDVCogY3VyUmVjdDsKCiAgICBUUkFDRSgiKCVwKSBDb3VudCAoJWxkKSwgcFJlY3RzICglcCksIEZsYWdzICglbHgpLCBaICglZiksIFN0ZW5jaWwgKCVsZClcbiIsIFRoaXMsCiAgICAgICAgICBDb3VudCwgcFJlY3RzLCBGbGFncywgWiwgU3RlbmNpbCk7CgogICAgRU5URVJfR0woKTsKCiAgICBnbEVuYWJsZShHTF9TQ0lTU09SX1RFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX1NDSVNTT1JfVEVTVCIpOwoKICAgIGlmIChDb3VudCA+IDAgJiYgcFJlY3RzKSB7CiAgICAgICAgY3VyUmVjdCA9IHBSZWN0czsKICAgIH0gZWxzZSB7CiAgICAgICAgY3VyUmVjdCA9IE5VTEw7CiAgICB9CgogICAgLyogT25seSBzZXQgdGhlIHZhbHVlcyB1cCBvbmNlLCBhcyB0aGV5IGFyZSBub3QgY2hhbmdpbmcgKi8KICAgIGlmIChGbGFncyAmIEQzRENMRUFSX1NURU5DSUwpIHsKICAgICAgICBnbEdldEludGVnZXJ2KEdMX1NURU5DSUxfQ0xFQVJfVkFMVUUsICZvbGRfc3RlbmNpbF9jbGVhcl92YWx1ZSk7CiAgICAgICAgZ2xDbGVhclN0ZW5jaWwoU3RlbmNpbCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQ2xlYXJTdGVuY2lsIik7CiAgICAgICAgZ2xNYXNrID0gZ2xNYXNrIHwgR0xfU1RFTkNJTF9CVUZGRVJfQklUOwogICAgICAgIGdsU3RlbmNpbE1hc2soMHhGRkZGRkZGRik7CiAgICB9CgogICAgaWYgKEZsYWdzICYgRDNEQ0xFQVJfWkJVRkZFUikgewogICAgICAgIGdsR2V0Qm9vbGVhbnYoR0xfREVQVEhfV1JJVEVNQVNLLCAmb2xkX3p0ZXN0KTsKICAgICAgICBnbERlcHRoTWFzayhHTF9UUlVFKTsKICAgICAgICBnbEdldEZsb2F0dihHTF9ERVBUSF9DTEVBUl9WQUxVRSwgJm9sZF96X2NsZWFyX3ZhbHVlKTsKICAgICAgICBnbENsZWFyRGVwdGgoWik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQ2xlYXJEZXB0aCIpOwogICAgICAgIGdsTWFzayA9IGdsTWFzayB8IEdMX0RFUFRIX0JVRkZFUl9CSVQ7CiAgICB9CgogICAgaWYgKEZsYWdzICYgRDNEQ0xFQVJfVEFSR0VUKSB7CiAgICAgICAgVFJBQ0UoIkNsZWFyaW5nIHNjcmVlbiB3aXRoIGdsQ2xlYXIgdG8gY29sb3IgJWx4XG4iLCBDb2xvcik7CiAgICAgICAgZ2xHZXRGbG9hdHYoR0xfQ09MT1JfQ0xFQVJfVkFMVUUsIG9sZF9jb2xvcl9jbGVhcl92YWx1ZSk7CiAgICAgICAgZ2xDbGVhckNvbG9yKEQzRENPTE9SX1IoQ29sb3IpLAogICAgICAgICAgICAgICAgICAgICBEM0RDT0xPUl9HKENvbG9yKSwKICAgICAgICAgICAgICAgICAgICAgRDNEQ09MT1JfQihDb2xvciksCiAgICAgICAgICAgICAgICAgICAgIEQzRENPTE9SX0EoQ29sb3IpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xDbGVhckNvbG9yIik7CgogICAgICAgIC8qIENsZWFyIEFMTCBjb2xvcnMhICovCiAgICAgICAgZ2xDb2xvck1hc2soR0xfVFJVRSwgR0xfVFJVRSwgR0xfVFJVRSwgR0xfVFJVRSk7CiAgICAgICAgZ2xNYXNrID0gZ2xNYXNrIHwgR0xfQ09MT1JfQlVGRkVSX0JJVDsKICAgIH0KCiAgICAvKiBOb3cgcHJvY2VzcyBlYWNoIHJlY3QgaW4gdHVybiAqLwogICAgZm9yIChpID0gMDsgaSA8IENvdW50IHx8IGkgPT0gMDsgaSsrKSB7CgogICAgICAgIGlmIChjdXJSZWN0KSB7CiAgICAgICAgICAgIC8qIE5vdGUgZ2wgdXNlcyBsb3dlciBsZWZ0LCB3aWR0aC9oZWlnaHQgKi8KICAgICAgICAgICAgVFJBQ0UoIiglcCkgJXAgUmVjdD0oJWxkLCVsZCktPiglbGQsJWxkKSBnbFJlY3Q9KCVsZCwlbGQpLCBsZW49JWxkLCBoZWk9JWxkXG4iLCBUaGlzLCBjdXJSZWN0LAogICAgICAgICAgICAgICAgICBjdXJSZWN0LT54MSwgY3VyUmVjdC0+eTEsIGN1clJlY3QtPngyLCBjdXJSZWN0LT55MiwKICAgICAgICAgICAgICAgICAgY3VyUmVjdC0+eDEsICgoKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5yZW5kZXJUYXJnZXQpLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBjdXJSZWN0LT55MiksCiAgICAgICAgICAgICAgICAgIGN1clJlY3QtPngyIC0gY3VyUmVjdC0+eDEsIGN1clJlY3QtPnkyIC0gY3VyUmVjdC0+eTEpOwogICAgICAgICAgICBnbFNjaXNzb3IoY3VyUmVjdC0+eDEsICgoKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5yZW5kZXJUYXJnZXQpLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBjdXJSZWN0LT55MiksCiAgICAgICAgICAgICAgICAgICAgICBjdXJSZWN0LT54MiAtIGN1clJlY3QtPngxLCBjdXJSZWN0LT55MiAtIGN1clJlY3QtPnkxKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsU2Npc3NvciIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsU2Npc3NvcihUaGlzLT5zdGF0ZUJsb2NrLT52aWV3cG9ydC5YLAogICAgICAgICAgICAgICAgICAgICAgKCgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPnJlbmRlclRhcmdldCktPmN1cnJlbnREZXNjLkhlaWdodCAtIAogICAgICAgICAgICAgICAgICAgICAgKFRoaXMtPnN0YXRlQmxvY2stPnZpZXdwb3J0LlkgKyBUaGlzLT5zdGF0ZUJsb2NrLT52aWV3cG9ydC5IZWlnaHQpKSwKICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnZpZXdwb3J0LldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+dmlld3BvcnQuSGVpZ2h0KTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsU2Npc3NvciIpOwogICAgICAgIH0KCiAgICAgICAgLyogQ2xlYXIgdGhlIHNlbGVjdGVkIHJlY3RhbmdsZSAob3IgZnVsbCBzY3JlZW4pICovCiAgICAgICAgZ2xDbGVhcihnbE1hc2spOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbENsZWFyIik7CgogICAgICAgIC8qIFN0ZXAgdG8gdGhlIG5leHQgcmVjdGFuZ2xlICovCiAgICAgICAgaWYgKGN1clJlY3QpIGN1clJlY3QgPSBjdXJSZWN0ICsgc2l6ZW9mKEQzRFJFQ1QpOwogICAgfQoKICAgIC8qIFJlc3RvcmUgdGhlIG9sZCB2YWx1ZXMgKHdoeS4uPykgKi8KICAgIGlmIChGbGFncyAmIEQzRENMRUFSX1NURU5DSUwpIHsKICAgICAgICBnbENsZWFyU3RlbmNpbChvbGRfc3RlbmNpbF9jbGVhcl92YWx1ZSk7CiAgICAgICAgZ2xTdGVuY2lsTWFzayhUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfU1RFTkNJTFdSSVRFTUFTS10pOwogICAgfQogICAgaWYgKEZsYWdzICYgRDNEQ0xFQVJfWkJVRkZFUikgewogICAgICAgIGdsRGVwdGhNYXNrKG9sZF96dGVzdCk7CiAgICAgICAgZ2xDbGVhckRlcHRoKG9sZF96X2NsZWFyX3ZhbHVlKTsKICAgIH0KICAgIGlmIChGbGFncyAmIEQzRENMRUFSX1RBUkdFVCkgewogICAgICAgIGdsQ2xlYXJDb2xvcihvbGRfY29sb3JfY2xlYXJfdmFsdWVbMF0sCiAgICAgICAgICAgICAgICAgICAgIG9sZF9jb2xvcl9jbGVhcl92YWx1ZVsxXSwKICAgICAgICAgICAgICAgICAgICAgb2xkX2NvbG9yX2NsZWFyX3ZhbHVlWzJdLAogICAgICAgICAgICAgICAgICAgICBvbGRfY29sb3JfY2xlYXJfdmFsdWVbM10pOwogICAgICAgIGdsQ29sb3JNYXNrKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19DT0xPUldSSVRFRU5BQkxFXSAmIEQzRENPTE9SV1JJVEVFTkFCTEVfUkVEID8gR0xfVFJVRSA6IEdMX0ZBTFNFLAogICAgICAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19DT0xPUldSSVRFRU5BQkxFXSAmIEQzRENPTE9SV1JJVEVFTkFCTEVfR1JFRU4gPyBHTF9UUlVFIDogR0xfRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX0NPTE9SV1JJVEVFTkFCTEVdICYgRDNEQ09MT1JXUklURUVOQUJMRV9CTFVFICA/IEdMX1RSVUUgOiBHTF9GQUxTRSwKICAgICAgICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfQ09MT1JXUklURUVOQUJMRV0gJiBEM0RDT0xPUldSSVRFRU5BQkxFX0FMUEhBID8gR0xfVFJVRSA6IEdMX0ZBTFNFKTsKICAgIH0KCiAgICBnbERpc2FibGUoR0xfU0NJU1NPUl9URVNUKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUiKTsKICAgIExFQVZFX0dMKCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBEcmF3aW5nIGZ1bmN0aW9ucwogKioqKiovCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UHJpbWl0aXZlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLCBVSU5UIFN0YXJ0VmVydGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFByaW1pdGl2ZUNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IEZBTFNFOwoKICAgIFRSQUNFKCIoJXApIDogVHlwZT0oJWQsJXMpLCBTdGFydD0lZCwgQ291bnQ9JWRcbiIsIFRoaXMsIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1Z19kM2RwcmltaXRpdmV0eXBlKFByaW1pdGl2ZVR5cGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhcnRWZXJ0ZXgsIFByaW1pdGl2ZUNvdW50KTsKICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIFByaW1pdGl2ZUNvdW50LCBTdGFydFZlcnRleCwgMC8qIE51bVZlcnRpY2VzICovLCAtMSAvKiBpbmR4U3RhcnQgKi8sCiAgICAgICAgICAgICAgICAgIDAgLyogaW5keFNpemUgKi8sIE5VTEwgLyogaW5keERhdGEgKi8sIDAgLyogbWluSW5kZXggKi8sIE5VTEwpOwoKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogVE9ETzogYmFzZVZJbmRleCBuZWVkcyB0byBiZSBwcm92aWRlZCBmcm9tIFRoaXMtPnN0YXRlQmxvY2stPmJhc2VWZXJ0ZXhJbmRleCB3aGVuIGNhbGxlZCBmcm9tIGQzZDggKi8KSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfRHJhd0luZGV4ZWRQcmltaXRpdmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgYmFzZVZJbmRleCwgVUlOVCBtaW5JbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIE51bVZlcnRpY2VzLCBVSU5UIHN0YXJ0SW5kZXgsIFVJTlQgcHJpbUNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFVJTlQgICAgICAgICAgICAgICAgIGlkeFN0cmlkZSA9IDI7CiAgICBJV2luZUQzREluZGV4QnVmZmVyICpwSUI7CiAgICBXSU5FRDNESU5ERVhCVUZGRVJfREVTQyAgSWR4QnVmRHNjOwoKICAgIHBJQiA9IFRoaXMtPnN0YXRlQmxvY2stPnBJbmRleERhdGE7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQID0gRkFMU0U7CgogICAgVFJBQ0UoIiglcCkgOiBUeXBlPSglZCwlcyksIG1pbj0lZCwgQ291bnRWPSVkLCBzdGFydElkeD0lZCwgYmFzZVZpZHg9JWQsIGNvdW50UD0lZFxuIiwgVGhpcywKICAgICAgICAgIFByaW1pdGl2ZVR5cGUsIGRlYnVnX2QzZHByaW1pdGl2ZXR5cGUoUHJpbWl0aXZlVHlwZSksCiAgICAgICAgICBtaW5JbmRleCwgTnVtVmVydGljZXMsIHN0YXJ0SW5kZXgsIGJhc2VWSW5kZXgsIHByaW1Db3VudCk7CgogICAgSVdpbmVEM0RJbmRleEJ1ZmZlcl9HZXREZXNjKHBJQiwgJklkeEJ1ZkRzYyk7CiAgICBpZiAoSWR4QnVmRHNjLkZvcm1hdCA9PSBXSU5FRDNERk1UX0lOREVYMTYpIHsKICAgICAgICBpZHhTdHJpZGUgPSAyOwogICAgfSBlbHNlIHsKICAgICAgICBpZHhTdHJpZGUgPSA0OwogICAgfQoKICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIHByaW1Db3VudCwgYmFzZVZJbmRleCwgTnVtVmVydGljZXMsIHN0YXJ0SW5kZXgsCiAgICAgICAgICAgICAgICAgICBpZHhTdHJpZGUsICgoSVdpbmVEM0RJbmRleEJ1ZmZlckltcGwgKikgcElCKS0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5LCBtaW5JbmRleCwgTlVMTCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UHJpbWl0aXZlVVAoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFByaW1pdGl2ZUNvdW50LCBDT05TVCB2b2lkKiBwVmVydGV4U3RyZWFtWmVyb0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IFR5cGU9KCVkLCVzKSwgcENvdW50PSVkLCBwVnR4RGF0YT0lcCwgU3RyaWRlPSVkXG4iLCBUaGlzLCBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgZGVidWdfZDNkcHJpbWl0aXZldHlwZShQcmltaXRpdmVUeXBlKSwKICAgICAgICAgICAgIFByaW1pdGl2ZUNvdW50LCBwVmVydGV4U3RyZWFtWmVyb0RhdGEsIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpOwoKICAgIC8qIHJlbGVhc2UgdGhlIHN0cmVhbSBzb3VyY2UgKi8KICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF0gIT0gTlVMTCkgewogICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVyX1JlbGVhc2UoVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlWzBdKTsKICAgIH0KCiAgICAvKiBOb3RlIGluIHRoZSBmb2xsb3dpbmcsIGl0J3Mgbm90IHRoaXMgdHlwZSwgYnV0IHRoYXQncyB0aGUgcHVycG9zZSBvZiBzdHJlYW1Jc1VQICovCiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF0gPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgKilwVmVydGV4U3RyZWFtWmVyb0RhdGE7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbMF0gPSBWZXJ0ZXhTdHJlYW1aZXJvU3RyaWRlOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IFRSVUU7CgogICAgZHJhd1ByaW1pdGl2ZShpZmFjZSwgUHJpbWl0aXZlVHlwZSwgUHJpbWl0aXZlQ291bnQsIDAgLyogc3RhcnQgdmVydGV4ICovLCAwICAvKiBOdW1WZXJ0aWNlcyAqLywKICAgICAgICAgICAgICAgICAgMCAvKiBpbmR4U3RhcnQqLywgMCAvKiBpbmR4U2l6ZSovLCBOVUxMIC8qIGluZHhEYXRhICovLCAwIC8qIGluZHhNaW4gKi8sIE5VTEwpOwoKICAgIC8qIE1TRE4gc3BlY2lmaWVzIHN0cmVhbSB6ZXJvIHNldHRpbmdzIG11c3QgYmUgc2V0IHRvIE5VTEwgKi8KICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVswXSA9IDA7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF0gPSBOVUxMOwoKICAgIC8qc3RyZWFtIHplcm8gc2V0dGluZ3Mgc2V0IHRvIG51bGwgYXQgZW5kLCBhcyBwZXIgdGhlIG1zZG4gKi8KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRHJhd0luZGV4ZWRQcmltaXRpdmVVUChJV2luZUQzRERldmljZSAqaWZhY2UsIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgTWluVmVydGV4SW5kZXgsIFVJTlQgTnVtVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFByaW1pdGl2ZUNvdW50LCBDT05TVCB2b2lkKiBwSW5kZXhEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREZPUk1BVCBJbmRleERhdGFGb3JtYXQsQ09OU1Qgdm9pZCogcFZlcnRleFN0cmVhbVplcm9EYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBWZXJ0ZXhTdHJlYW1aZXJvU3RyaWRlKSB7CiAgICBpbnQgICAgICAgICAgICAgICAgIGlkeFN0cmlkZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IFR5cGU9KCVkLCVzKSwgTWluVnR4SWR4PSVkLCBOdW1WSWR4PSVkLCBQQ291bnQ9JWQsIHBpZHhkYXRhPSVwLCBJZHhGbXQ9JWQsIHBWdHhkYXRhPSVwLCBzdHJpZGU9JWRcbiIsCiAgICAgICAgICAgICBUaGlzLCBQcmltaXRpdmVUeXBlLCBkZWJ1Z19kM2RwcmltaXRpdmV0eXBlKFByaW1pdGl2ZVR5cGUpLAogICAgICAgICAgICAgTWluVmVydGV4SW5kZXgsIE51bVZlcnRpY2VzLCBQcmltaXRpdmVDb3VudCwgcEluZGV4RGF0YSwKICAgICAgICAgICAgIEluZGV4RGF0YUZvcm1hdCwgcFZlcnRleFN0cmVhbVplcm9EYXRhLCBWZXJ0ZXhTdHJlYW1aZXJvU3RyaWRlKTsKCiAgICBpZiAoSW5kZXhEYXRhRm9ybWF0ID09IFdJTkVEM0RGTVRfSU5ERVgxNikgewogICAgICAgIGlkeFN0cmlkZSA9IDI7CiAgICB9IGVsc2UgewogICAgICAgIGlkeFN0cmlkZSA9IDQ7CiAgICB9CgogICAgLyogcmVsZWFzZSB0aGUgc3RyZWFtIGFuZCBpbmRleCBkYXRhICovCiAgICBpZiAoVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlWzBdICE9IE5VTEwpIHsKICAgICAgICBJV2luZUQzRFZlcnRleEJ1ZmZlcl9SZWxlYXNlKFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXSk7CiAgICB9CiAgICBpZiAoVGhpcy0+c3RhdGVCbG9jay0+cEluZGV4RGF0YSkgewogICAgICAgIElXaW5lRDNESW5kZXhCdWZmZXJfUmVsZWFzZShUaGlzLT5zdGF0ZUJsb2NrLT5wSW5kZXhEYXRhKTsKICAgIH0KCiAgICAvKiBOb3RlIGluIHRoZSBmb2xsb3dpbmcsIGl0J3Mgbm90IHRoaXMgdHlwZSwgYnV0IHRoYXQncyB0aGUgcHVycG9zZSBvZiBzdHJlYW1Jc1VQICovCiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF0gPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgKilwVmVydGV4U3RyZWFtWmVyb0RhdGE7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQID0gVFJVRTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVswXSA9IFZlcnRleFN0cmVhbVplcm9TdHJpZGU7CgogICAgZHJhd1ByaW1pdGl2ZShpZmFjZSwgUHJpbWl0aXZlVHlwZSwgUHJpbWl0aXZlQ291bnQsIDAgLyogdmVydGV4U3RhcnQgKi8sIE51bVZlcnRpY2VzLCAwIC8qIGluZHhTdGFydCAqLywgaWR4U3RyaWRlLCBwSW5kZXhEYXRhLCBNaW5WZXJ0ZXhJbmRleCwgTlVMTCk7CgogICAgLyogTVNETiBzcGVjaWZpZXMgc3RyZWFtIHplcm8gc2V0dGluZ3MgYW5kIGluZGV4IGJ1ZmZlciBtdXN0IGJlIHNldCB0byBOVUxMICovCiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF0gPSBOVUxMOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlWzBdID0gMDsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnBJbmRleERhdGEgPSBOVUxMOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRHJhd1ByaW1pdGl2ZVN0cmlkZWQgKElXaW5lRDNERGV2aWNlICppZmFjZSwgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLCBVSU5UIFByaW1pdGl2ZUNvdW50LCBXaW5lRGlyZWN0M0RWZXJ0ZXhTdHJpZGVkRGF0YSAqRHJhd1ByaW1TdHJpZGVEYXRhKSB7CgogICAgZHJhd1ByaW1pdGl2ZShpZmFjZSwgUHJpbWl0aXZlVHlwZSwgUHJpbWl0aXZlQ291bnQsIDAsIDAsIDAsIDAsIE5VTEwsIDAsIERyYXdQcmltU3RyaWRlRGF0YSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQogLyogWWV0IGFub3RoZXIgd2F5IHRvIHVwZGF0ZSBhIHRleHR1cmUsIHNvbWUgYXBwcyB1c2UgdGhpcyB0byBsb2FkIGRlZmF1bHQgdGV4dHVyZXMgaW5zdGVhZCBvZiB1c2luZyBzdXJmYWNlL3RleHR1cmUgbG9jay91bmxvY2sgKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1VwZGF0ZVRleHR1cmUgKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RCYXNlVGV4dHVyZSAqcFNvdXJjZVRleHR1cmUsICBJV2luZUQzREJhc2VUZXh0dXJlICpwRGVzdGluYXRpb25UZXh0dXJlKXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNEX09LOwogICAgV0lORUQzRFJFU09VUkNFVFlQRSBzb3VyY2VUeXBlOwogICAgV0lORUQzRFJFU09VUkNFVFlQRSBkZXN0aW5hdGlvblR5cGU7CiAgICBpbnQgaSAsbGV2ZWxzOwoKICAgIC8qIFRPRE86IHRoaW5rIGFib3V0IG1vdmluZyB0aGUgY29kZSBpbnRvIElXaW5lRDNEQmFzZVRleHR1cmUgICovCgogICAgVFJBQ0UoIiglcCkgU291cmNlICVwIERlc3RpbmF0aW9uICVwXG4iLCBUaGlzLCBwU291cmNlVGV4dHVyZSwgcERlc3RpbmF0aW9uVGV4dHVyZSk7CgogICAgLyogdmVyaWZ5IHRoYXQgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gdGV4dHVyZXMgYXJlbid0IE5VTEwgKi8KICAgIGlmIChOVUxMID09IHBTb3VyY2VUZXh0dXJlIHx8IE5VTEwgPT0gcERlc3RpbmF0aW9uVGV4dHVyZSkgewogICAgICAgIFdBUk4oIiglcCkgOiBzb3VyY2UgKCVwKSBhbmQgZGVzdGluYXRpb24gKCVwKSB0ZXh0dXJlcyBtdXN0IG5vdCBiZSBOVUxMLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIiwKICAgICAgICAgICAgIFRoaXMsIHBTb3VyY2VUZXh0dXJlLCBwRGVzdGluYXRpb25UZXh0dXJlKTsKICAgICAgICBociA9IFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKHBTb3VyY2VUZXh0dXJlID09IHBEZXN0aW5hdGlvblRleHR1cmUpIHsKICAgICAgICBXQVJOKCIoJXApIDogc291cmNlICglcCkgYW5kIGRlc3RpbmF0aW9uICglcCkgdGV4dHVyZXMgbXVzdCBiZSBkaWZmZXJlbnQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLAogICAgICAgICAgICAgVGhpcywgcFNvdXJjZVRleHR1cmUsIHBEZXN0aW5hdGlvblRleHR1cmUpOwogICAgICAgIGhyID0gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIC8qIFZlcmlmeSB0aGF0IHRoZSBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIHRleHR1cmVzIGFyZSB0aGUgc2FtZSB0eXBlICovCiAgICBzb3VyY2VUeXBlICAgICAgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldFR5cGUocFNvdXJjZVRleHR1cmUpOwogICAgZGVzdGluYXRpb25UeXBlID0gSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUeXBlKHBEZXN0aW5hdGlvblRleHR1cmUpOwoKICAgIGlmIChzb3VyY2VUeXBlICE9IGRlc3RpbmF0aW9uVHlwZSkgewogICAgICAgIFdBUk4oIiglcCkgU29yY2UgYW5kIGRlc3RpbmF0aW9uIHR5cGVzIG11c3QgbWF0Y2gsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLAogICAgICAgICAgICAgVGhpcyk7CiAgICAgICAgaHIgPSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIGNoZWNrIHRoYXQgYm90aCB0ZXh0dXJlcyBoYXZlIHRoZSBpZGVudGljYWwgbnVtYmVycyBvZiBsZXZlbHMgICovCiAgICBpZiAoSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRMZXZlbENvdW50KHBEZXN0aW5hdGlvblRleHR1cmUpICAhPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldExldmVsQ291bnQocFNvdXJjZVRleHR1cmUpKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IHNvdXJjZSAoJXApIGFuZCBkZXN0aW5hdGlvbiAoJXApIHRleHR1cmVzIG11c3QgaGF2ZSBpZGVudGljbGUgbnVtYmVycyBvZiBsZXZlbHMsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLCBUaGlzLCBwU291cmNlVGV4dHVyZSwgcERlc3RpbmF0aW9uVGV4dHVyZSk7CiAgICAgICAgaHIgPSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmIChXSU5FRDNEX09LID09IGhyKSB7CgogICAgICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHRoZSBkZXN0aW5hdGlvbiB0ZXh0dXJlIGlzIGxvYWRlZCAqLwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUHJlTG9hZChwRGVzdGluYXRpb25UZXh0dXJlKTsKCiAgICAgICAgLyogVXBkYXRlIGV2ZXJ5IHN1cmZhY2UgbGV2ZWwgb2YgdGhlIHRleHR1cmUgKi8KICAgICAgICBsZXZlbHMgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldExldmVsQ291bnQocERlc3RpbmF0aW9uVGV4dHVyZSk7CgogICAgICAgIHN3aXRjaCAoc291cmNlVHlwZSkgewogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX1RFWFRVUkU6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqc3JjU3VyZmFjZTsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqZGVzdFN1cmZhY2U7CgogICAgICAgICAgICAgICAgZm9yIChpID0gMCA7IGkgPCBsZXZlbHMgOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFRleHR1cmVfR2V0U3VyZmFjZUxldmVsKChJV2luZUQzRFRleHR1cmUgKilwU291cmNlVGV4dHVyZSwgICAgICBpLCAmc3JjU3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlX0dldFN1cmZhY2VMZXZlbCgoSVdpbmVEM0RUZXh0dXJlICopcERlc3RpbmF0aW9uVGV4dHVyZSwgaSwgJmRlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1VwZGF0ZVN1cmZhY2UoaWZhY2UsIHNyY1N1cmZhY2UsIE5VTEwsIGRlc3RTdXJmYWNlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShkZXN0U3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiKCVwKSA6IENhbGwgdG8gdXBkYXRlIHN1cmZhY2UgZmFpbGVkXG4iLCBUaGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9DVUJFVEVYVFVSRToKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpzcmNTdXJmYWNlOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpkZXN0U3VyZmFjZTsKICAgICAgICAgICAgICAgIFdJTkVEM0RDVUJFTUFQX0ZBQ0VTIGZhY2VUeXBlOwoKICAgICAgICAgICAgICAgIGZvciAoaSA9IDAgOyBpIDwgbGV2ZWxzIDsgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgLyogVXBkYXRlIGVhY2ggY3ViZSBmYWNlICovCiAgICAgICAgICAgICAgICAgICAgZm9yIChmYWNlVHlwZSA9IEQzRENVQkVNQVBfRkFDRV9QT1NJVElWRV9YOyBmYWNlVHlwZSA8PSBEM0RDVUJFTUFQX0ZBQ0VfTkVHQVRJVkVfWjsgKytmYWNlVHlwZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIGhyID0gSVdpbmVEM0RDdWJlVGV4dHVyZV9HZXRDdWJlTWFwU3VyZmFjZSgoSVdpbmVEM0RDdWJlVGV4dHVyZSAqKXBTb3VyY2VUZXh0dXJlLCAgICAgIGZhY2VUeXBlLCBpLCAmc3JjU3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChXSU5FRDNEX09LICE9IGhyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiKCVwKSA6IEZhaWxlZCB0byBnZXQgc3JjIGN1YmUgc3VyZmFjZSBmYWNldHlwZSAlZCwgbGV2ZWwgJWRcbiIsIFRoaXMsIGZhY2VUeXBlLCBpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJHb3Qgc3JjU3VyZmFjZSAlcFxuIiwgc3JjU3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaHIgPSBJV2luZUQzREN1YmVUZXh0dXJlX0dldEN1YmVNYXBTdXJmYWNlKChJV2luZUQzREN1YmVUZXh0dXJlICopcERlc3RpbmF0aW9uVGV4dHVyZSwgZmFjZVR5cGUsIGksICZkZXN0U3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChXSU5FRDNEX09LICE9IGhyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiKCVwKSA6IEZhaWxlZCB0byBnZXQgc3JjIGN1YmUgc3VyZmFjZSBmYWNldHlwZSAlZCwgbGV2ZWwgJWRcbiIsIFRoaXMsIGZhY2VUeXBlLCBpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJHb3QgZGVzclN1cmZhY2UgJXBcbiIsIGRlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1VwZGF0ZVN1cmZhY2UoaWZhY2UsIHNyY1N1cmZhY2UsIE5VTEwsIGRlc3RTdXJmYWNlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2Uoc3JjU3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKGRlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdBUk4oIiglcCkgOiBDYWxsIHRvIHVwZGF0ZSBzdXJmYWNlIGZhaWxlZFxuIiwgVGhpcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiNpZiAwIC8qIFRPRE86IEFkZCBzdXBwb3J0IGZvciB2b2x1bWUgdGV4dHVyZXMgKi8KICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9WT0xVTUVURVhUVVJFOgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZSAgc3JjVm9sdW1lICA9IE5VTEw7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgZGVzdFZvbHVtZSA9IE5VTEw7CgogICAgICAgICAgICAgICAgZm9yIChpID0gMCA7IGkgPCBsZXZlbHMgOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZVRleHR1cmVfR2V0Vm9sdW1lKChJV2luZUQzRFZvbHVtZVRleHR1cmUgKilwU291cmNlVGV4dHVyZSwgICAgICBpLCAmc3JjVm9sdW1lKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZVRleHR1cmVfR2V0Vm9sdW1lKChJV2luZUQzRFZvbHVtZVRleHR1cmUgKilwRGVzdGluYXRpb25UZXh0dXJlLCBpLCAmZGVzdFZvbHVtZSk7CiAgICAgICAgICAgICAgICAgICAgaHIgPSAgSVdpbmVEM0RGb29fVXBkYXRlVm9sdW1lKGlmYWNlLCBzcmNWb2x1bWUsIE5VTEwsIGRlc3RWb2x1bWUsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lX1JlbGVhc2Uoc3JjU3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWVfUmVsZWFzZShkZXN0U3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiKCVwKSA6IENhbGwgdG8gdXBkYXRlIHZvbHVtZSBmYWlsZWRcbiIsIFRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwojZW5kaWYKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiKCVwKSA6IFVuc3VwcG9ydGVkIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gdHlwZVxuIiwgVGhpcyk7CiAgICAgICAgICAgIGhyID0gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIGhyOwp9CgpIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TdHJldGNoUmVjdChJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqcFNvdXJjZVN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlNUIFJFQ1QqIHBTb3VyY2VSZWN0LCBJV2luZUQzRFN1cmZhY2UgKnBEZXN0aW5hdGlvblN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlNUIFJFQ1QqIHBEZXN0UmVjdCwgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIEZpbHRlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIDogc3R1YlxuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQpIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSZW5kZXJUYXJnZXREYXRhKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpwUmVuZGVyVGFyZ2V0LCBJV2luZUQzRFN1cmZhY2UgKnBTdXJmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAvKiogVE9ETzogcmVtb3ZlIHJlbW92ZSBjYXN0cyB0byBJV2luZUQzRFN1cmZhY2VJbXBsICoKICAgICogIE5PVEUgSXQgbWF5IGJlIGJlc3QgdG8gbW92ZSB0aGUgY29kZSBpbnRvIHN1cmZhY2UgdG8gb2Njb21wbGlzaCB0aGlzCiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIFdJTkVEM0RTVVJGQUNFX0RFU0Mgc3VyZmFjZURlc2M7CiAgICB1bnNpZ25lZCBpbnQgc3VyZmFjZVdpZHRoLCBzdXJmYWNlSGVpZ2h0OwogICAgZ2xEZXNjcmlwdG9yICp0YXJnZXRHbERlc2NyaXB0aW9uICA9IE5VTEw7CiAgICBnbERlc2NyaXB0b3IgKnN1cmZhY2VHbERlc2NyaXB0aW9uID0gTlVMTDsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqY29udGFpbmVyID0gTlVMTDsKICAgIAogICAgSVdpbmVEM0RTdXJmYWNlX0dldEdsRGVzYyhwUmVuZGVyVGFyZ2V0LCAmdGFyZ2V0R2xEZXNjcmlwdGlvbik7CiAgICBJV2luZUQzRFN1cmZhY2VfR2V0R2xEZXNjKHBTdXJmYWNlLCAgICAgICZzdXJmYWNlR2xEZXNjcmlwdGlvbik7CiAgICBtZW1zZXQoJnN1cmZhY2VEZXNjLCAwLCBzaXplb2Yoc3VyZmFjZURlc2MpKTsKCiAgICBzdXJmYWNlRGVzYy5XaWR0aCAgPSAmc3VyZmFjZVdpZHRoOwogICAgc3VyZmFjZURlc2MuSGVpZ2h0ID0gJnN1cmZhY2VIZWlnaHQ7CiAgICBJV2luZUQzRFN1cmZhY2VfR2V0RGVzYyhwU3VyZmFjZSwgJnN1cmZhY2VEZXNjKTsKICAgLyogY2hlY2sgdG8gc2VlIGlmIGl0J3MgdGhlIGJhY2tidWZmZXIgb3IgdGhlIGZyb250YnVmZmVyIGJlaW5nIHJlcXVlc3RlZCAodG8gbWFrZSBzdXJlIHRoZSBkYXRhIGlzIHVwIHRvIGRhdGUpKi8KCiAgICAvKiBPaywgSSBtYXkgbmVlZCB0byBzZXR1cCBzb21lIGtpbmQgb2YgYWN0aXZlIHN3YXBjaGFpbiByZWZlcmVuY2Ugb24gdGhlIGRldmljZSAqLwogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihwUmVuZGVyVGFyZ2V0LCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmY29udGFpbmVyKTsKICAgIEVOVEVSX0dMKCk7CiAgICAvKiBUT0RPOiBvcGVuZ2wgQ29udGV4dCBzd2l0Y2hpbmcgZm9yIHN3YXBjaGFpbnMgZXRjLi4uICovCiAgICBpZiAoTlVMTCAhPSBjb250YWluZXIgIHx8IHBSZW5kZXJUYXJnZXQgPT0gVGhpcy0+cmVuZGVyVGFyZ2V0IHx8IHBSZW5kZXJUYXJnZXQgPT0gVGhpcy0+ZGVwdGhTdGVuY2lsQnVmZmVyKSB7CiAgICAgICAgaWYgKE5VTEwgIT0gY29udGFpbmVyICAmJiAocFJlbmRlclRhcmdldCA9PSBjb250YWluZXItPmJhY2tCdWZmZXIpKSB7CiAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIoR0xfQkFDSykiKTsKICAgICAgICB9IGVsc2UgaWYgKChOVUxMICE9IGNvbnRhaW5lciAgJiYgKHBSZW5kZXJUYXJnZXQgPT0gY29udGFpbmVyLT5mcm9udEJ1ZmZlcikpIHx8IChwUmVuZGVyVGFyZ2V0ID09IFRoaXMtPnJlbmRlclRhcmdldCkpIHsKICAgICAgICAgICAgZ2xSZWFkQnVmZmVyKEdMX0ZST05UKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIoR0xfRlJPTlQpIik7CiAgICAgICAgfSBlbHNlIGlmIChwUmVuZGVyVGFyZ2V0ID09IFRoaXMtPmRlcHRoU3RlbmNpbEJ1ZmZlcikgewogICAgICAgICAgICBGSVhNRSgiUmVhZGluZyBvZiBkZXB0aHN0ZW5jaWwgbm90IHlldCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIH0KCiAgICAgICAgZ2xSZWFkUGl4ZWxzKHN1cmZhY2VHbERlc2NyaXB0aW9uLT50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgc3VyZmFjZUdsRGVzY3JpcHRpb24tPmxldmVsLAogICAgICAgICAgICAgICAgICAgIHN1cmZhY2VXaWR0aCwKICAgICAgICAgICAgICAgICAgICBzdXJmYWNlSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgIHN1cmZhY2VHbERlc2NyaXB0aW9uLT5nbEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICBzdXJmYWNlR2xEZXNjcmlwdGlvbi0+Z2xUeXBlLAogICAgICAgICAgICAgICAgICAgICh2b2lkICopSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFN1cmZhY2UpKTsKICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUmVhZFBpeGVscyguLi4pIik7CiAgICAgICAgaWYoTlVMTCAhPSBjb250YWluZXIgKXsKICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4qKSBjb250YWluZXIpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqY29udGFpbmVyOwogICAgICAgIEdMZW51bSB0ZXh0dXJlRGltZW5zaW9ucyA9IEdMX1RFWFRVUkVfMkQ7CgogICAgICAgIGlmIChXSU5FRDNEX09LID09IElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIocFN1cmZhY2UsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJmNvbnRhaW5lcikpIHsKICAgICAgICAgICAgdGV4dHVyZURpbWVuc2lvbnMgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldFRleHR1cmVEaW1lbnNpb25zKGNvbnRhaW5lcik7CiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZShjb250YWluZXIpOwogICAgICAgIH0KICAgICAgICAvKiBUT0RPOiAyRCAtPiBDdWJlIHN1cmZhY2UgY29wcGllcyBldGMuLiAqLwogICAgICAgIGlmIChzdXJmYWNlR2xEZXNjcmlwdGlvbi0+dGFyZ2V0ICE9IHRleHR1cmVEaW1lbnNpb25zKSB7CiAgICAgICAgICAgIEZJWE1FKCIoJXApIDogVGV4dHVyZSBkaW1lbnNpb24gbWlzbWF0Y2hcbiIsIFRoaXMpOwogICAgICAgIH0KICAgICAgICBnbEVuYWJsZSh0ZXh0dXJlRGltZW5zaW9ucyk7CiAgICAgICAgdmNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9URVhUVVJFXy4uLikiKTsKICAgICAgICAvKiBGSVhNRTogdGhpcyBpc24ndCBjb3JyZWN0LCBpdCBuZWVkIHRvIGFkZCBhIGRpcnR5IHJlY3QgaWYgbm90aGluZyBlbHNlLi4uICovCiAgICAgICAgZ2xCaW5kVGV4dHVyZSh0YXJnZXRHbERlc2NyaXB0aW9uLT50YXJnZXQsIHRhcmdldEdsRGVzY3JpcHRpb24tPnRleHR1cmVOYW1lKTsKICAgICAgICB2Y2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUiKTsKICAgICAgICBnbEdldFRleEltYWdlKHN1cmZhY2VHbERlc2NyaXB0aW9uLT50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1cmZhY2VHbERlc2NyaXB0aW9uLT5sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgc3VyZmFjZUdsRGVzY3JpcHRpb24tPmdsRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICBzdXJmYWNlR2xEZXNjcmlwdGlvbi0+Z2xUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKUlXaW5lRDNEU3VyZmFjZV9HZXREYXRhKHBTdXJmYWNlKSk7CiAgICAgICAgZ2xEaXNhYmxlKHRleHR1cmVEaW1lbnNpb25zKTsKICAgICAgICB2Y2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9URVhUVVJFXy4uLikiKTsKCiAgICB9CiAgICBMRUFWRV9HTCgpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEZyb250QnVmZmVyRGF0YShJV2luZUQzRERldmljZSAqaWZhY2UsVUlOVCBpU3dhcENoYWluLCBJV2luZUQzRFN1cmZhY2UgKnBEZXN0U3VyZmFjZSkgewogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBDaGFpbjsKICAgIEhSRVNVTFQgaHI7CiAgICBociA9IElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4oaWZhY2UsICBpU3dhcENoYWluLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopJnN3YXBDaGFpbik7CiAgICBpZihociA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgaHIgPSBJV2luZUQzRFN3YXBDaGFpbl9HZXRGcm9udEJ1ZmZlckRhdGEoc3dhcENoYWluLCBwRGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgpIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9WYWxpZGF0ZURldmljZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEKiBwTnVtUGFzc2VzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAvKiByZXR1cm4gYSBzZW5zaWJsZSBkZWZhdWx0ICovCiAgICAqcE51bVBhc3NlcyA9IDE7CiAgICAvKiBUT0RPOiBJZiB0aGUgd2luZG93IGlzIG1pbmltaXplZCB0aGVuIHZhbGlkYXRlIGRldmljZSBzaG91bGQgcmV0dXJuIHNvbWV0aGluZyBvdGhlciB0aGFuIFdJTkVEM0RfT0sgKi8KICAgIEZJWE1FKCIoJXApIDogc3R1YlxuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0UGFsZXR0ZUVudHJpZXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFBhbGV0dGVOdW1iZXIsIENPTlNUIFBBTEVUVEVFTlRSWSogcEVudHJpZXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBqOwogICAgVFJBQ0UoIiglcCkgOiBQYWxldHRlTnVtYmVyICV1XG4iLCBUaGlzLCBQYWxldHRlTnVtYmVyKTsKICAgIGlmICggUGFsZXR0ZU51bWJlciA8IDAgfHwgUGFsZXR0ZU51bWJlciA+PSBNQVhfUEFMRVRURVMpIHsKICAgICAgICBXQVJOKCIoJXApIDogKCV1KSBPdXQgb2YgcmFuZ2UgMC0ldSwgcmV0dXJuaW5nIEludmFsaWQgQ2FsbFxuIiwgVGhpcywgUGFsZXR0ZU51bWJlciwgTUFYX1BBTEVUVEVTKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIGZvciAoaiA9IDA7IGogPCAyNTY7ICsraikgewogICAgICAgIFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlUmVkICAgPSBwRW50cmllc1tqXS5wZVJlZDsKICAgICAgICBUaGlzLT5wYWxldHRlc1tQYWxldHRlTnVtYmVyXVtqXS5wZUdyZWVuID0gcEVudHJpZXNbal0ucGVHcmVlbjsKICAgICAgICBUaGlzLT5wYWxldHRlc1tQYWxldHRlTnVtYmVyXVtqXS5wZUJsdWUgID0gcEVudHJpZXNbal0ucGVCbHVlOwogICAgICAgIFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlRmxhZ3MgPSBwRW50cmllc1tqXS5wZUZsYWdzOwogICAgfQogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmdcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBhbGV0dGVFbnRyaWVzKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBQYWxldHRlTnVtYmVyLCBQQUxFVFRFRU5UUlkqIHBFbnRyaWVzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgajsKICAgIFRSQUNFKCIoJXApIDogUGFsZXR0ZU51bWJlciAldVxuIiwgVGhpcywgUGFsZXR0ZU51bWJlcik7CiAgICBpZiAoIFBhbGV0dGVOdW1iZXIgPCAwIHx8IFBhbGV0dGVOdW1iZXIgPj0gTUFYX1BBTEVUVEVTKSB7CiAgICAgICAgV0FSTigiKCVwKSA6ICgldSkgT3V0IG9mIHJhbmdlIDAtJXUsIHJldHVybmluZyBJbnZhbGlkIENhbGxcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIsIE1BWF9QQUxFVFRFUyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBmb3IgKGogPSAwOyBqIDwgMjU2OyArK2opIHsKICAgICAgICBwRW50cmllc1tqXS5wZVJlZCAgID0gVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl1bal0ucGVSZWQ7CiAgICAgICAgcEVudHJpZXNbal0ucGVHcmVlbiA9IFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlR3JlZW47CiAgICAgICAgcEVudHJpZXNbal0ucGVCbHVlICA9IFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlQmx1ZTsKICAgICAgICBwRW50cmllc1tqXS5wZUZsYWdzID0gVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl1bal0ucGVGbGFnczsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDdXJyZW50VGV4dHVyZVBhbGV0dGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFBhbGV0dGVOdW1iZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogUGFsZXR0ZU51bWJlciAldVxuIiwgVGhpcywgUGFsZXR0ZU51bWJlcik7CiAgICBpZiAoIFBhbGV0dGVOdW1iZXIgPCAwIHx8IFBhbGV0dGVOdW1iZXIgPj0gTUFYX1BBTEVUVEVTKSB7CiAgICAgICAgV0FSTigiKCVwKSA6ICgldSkgT3V0IG9mIHJhbmdlIDAtJXUsIHJldHVybmluZyBJbnZhbGlkIENhbGxcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIsIE1BWF9QQUxFVFRFUyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAvKlRPRE86IHN0YXRlYmxvY2tzICovCiAgICBUaGlzLT5jdXJyZW50UGFsZXR0ZSA9IFBhbGV0dGVOdW1iZXI7CiAgICBUUkFDRSgiKCVwKSA6IHJldHVybmluZ1xuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0Q3VycmVudFRleHR1cmVQYWxldHRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCogUGFsZXR0ZU51bWJlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaWYgKFBhbGV0dGVOdW1iZXIgPT0gTlVMTCkgewogICAgICAgIFdBUk4oIiglcCkgOiByZXR1cm5pbmcgSW52YWxpZCBDYWxsXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIC8qVE9ETzogc3RhdGVibG9ja3MgKi8KICAgICpQYWxldHRlTnVtYmVyID0gVGhpcy0+Y3VycmVudFBhbGV0dGU7CiAgICBUUkFDRSgiKCVwKSA6IHJldHVybmluZyAgJXVcbiIsIFRoaXMsICpQYWxldHRlTnVtYmVyKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTb2Z0d2FyZVZlcnRleFByb2Nlc3NpbmcoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBCT09MIGJTb2Z0d2FyZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgc3RhdGljIEJPT0wgc2hvd0ZpeG1lcyA9IFRSVUU7CiAgICBpZiAoc2hvd0ZpeG1lcykgewogICAgICAgIEZJWE1FKCIoJXApIDogc3R1YlxuIiwgVGhpcyk7CiAgICAgICAgc2hvd0ZpeG1lcyA9IEZBTFNFOwogICAgfQoKICAgIFRoaXMtPnNvZnR3YXJlVmVydGV4UHJvY2Vzc2luZyA9IGJTb2Z0d2FyZTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgoKQk9PTCAgICAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0U29mdHdhcmVWZXJ0ZXhQcm9jZXNzaW5nKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgc3RhdGljIEJPT0wgc2hvd0ZpeG1lcyA9IFRSVUU7CiAgICBpZiAoc2hvd0ZpeG1lcykgewogICAgICAgIEZJWE1FKCIoJXApIDogc3R1YlxuIiwgVGhpcyk7CiAgICAgICAgc2hvd0ZpeG1lcyA9IEZBTFNFOwogICAgfQogICAgcmV0dXJuIFRoaXMtPnNvZnR3YXJlVmVydGV4UHJvY2Vzc2luZzsKfQoKCkhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFJhc3RlclN0YXR1cyhJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgV0lORUQzRFJBU1RFUl9TVEFUVVMqIHBSYXN0ZXJTdGF0dXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwQ2hhaW47CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApIDogIFN3YXBDaGFpbiAlZCByZXR1cm5pbmcgJXBcbiIsIFRoaXMsIGlTd2FwQ2hhaW4sIHBSYXN0ZXJTdGF0dXMpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgIGlTd2FwQ2hhaW4sIChJV2luZUQzRFN3YXBDaGFpbiAqKikmc3dhcENoYWluKTsKICAgIGlmKGhyID09IFdJTkVEM0RfT0spewogICAgICAgIGhyID0gSVdpbmVEM0RTd2FwQ2hhaW5fR2V0UmFzdGVyU3RhdHVzKHN3YXBDaGFpbiwgcFJhc3RlclN0YXR1cyk7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgfWVsc2V7CiAgICAgICAgRklYTUUoIiglcCkgSVdpbmVEM0RTd2FwQ2hhaW5fR2V0UmFzdGVyU3RhdHVzIHJldHVybmVkIGluIGVycm9yXG4iLCBUaGlzKTsKICAgIH0KICAgIHJldHVybiBocjsKfQoKCkhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1NldE5QYXRjaE1vZGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBmbG9hdCBuU2VnbWVudHMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBCT09MIHNob3dmaXhtZXMgPSBUUlVFOwogICAgaWYoblNlZ21lbnRzICE9IDAuMGYpIHsKICAgICAgICBpZiggc2hvd2ZpeG1lcykgewogICAgICAgICAgICBGSVhNRSgiKCVwKSA6IHN0dWIgblNlZ21lbnRzKCVmKVxuIiwgVGhpcywgblNlZ21lbnRzKTsKICAgICAgICAgICAgc2hvd2ZpeG1lcyA9IEZBTFNFOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpmbG9hdCAgICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXROUGF0Y2hNb2RlKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgc3RhdGljIEJPT0wgc2hvd2ZpeG1lcyA9IFRSVUU7CiAgICBpZiggc2hvd2ZpeG1lcykgewogICAgICAgIEZJWE1FKCIoJXApIDogc3R1YiByZXR1cm5pbmcoJWYpXG4iLCBUaGlzLCAwLjBmKTsKICAgICAgICBzaG93Zml4bWVzID0gRkFMU0U7CiAgICB9CiAgICByZXR1cm4gMC4wZjsKfQoKSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfVXBkYXRlU3VyZmFjZShJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqcFNvdXJjZVN1cmZhY2UsIENPTlNUIFJFQ1QqIHBTb3VyY2VSZWN0LCBJV2luZUQzRFN1cmZhY2UgKnBEZXN0aW5hdGlvblN1cmZhY2UsIENPTlNUIFBPSU5UKiBwRGVzdFBvaW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgICpUaGlzICAgICAgICAgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgLyoqIFRPRE86IHJlbW92ZSBjYXN0cyB0byBJV2luZUQzRFN1cmZhY2VJbXBsCiAgICAgKiAgICAgICBOT1RFOiBtb3ZlIGNvZGUgdG8gc3VyZmFjZSB0byBhY2NvbXBsaXNoIHRoaXMKICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKnBTcmNTdXJmYWNlICA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopcFNvdXJjZVN1cmZhY2U7CiAgICBpbnQgc3JjV2lkdGgsIHNyY0hlaWdodDsKICAgIHVuc2lnbmVkIGludCAgc3JjU3VyZmFjZVdpZHRoLCBzcmNTdXJmYWNlSGVpZ2h0LCBkZXN0U3VyZmFjZVdpZHRoLCBkZXN0U3VyZmFjZUhlaWdodDsKICAgIFdJTkVEM0RGT1JNQVQgZGVzdEZvcm1hdCwgc3JjRm9ybWF0OwogICAgVUlOVCAgICAgICAgICBkZXN0U2l6ZTsKICAgIGludCBkZXN0TGVmdCwgZGVzdFRvcDsKICAgIFdJTkVEM0RQT09MICAgICAgIHNyY1Bvb2wsIGRlc3RQb29sOwogICAgaW50IG9mZnNldCAgICA9IDA7CiAgICBpbnQgcm93b2Zmc2V0ID0gMDsgLyogaG93IG1hbnkgYnl0ZXMgdG8gYWRkIG9udG8gdGhlIGVuZCBvZiBhIHJvdyB0byB3cmFwYXJvdW5kIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIG5leHQgKi8KICAgIGdsRGVzY3JpcHRvciAqZ2xEZXNjcmlwdGlvbiA9IE5VTEw7CiAgICBHTGVudW0gdGV4dHVyZURpbWVuc2lvbnMgPSBHTF9URVhUVVJFXzJEOwogICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqYmFzZVRleHR1cmU7CgogICAgV0lORUQzRFNVUkZBQ0VfREVTQyAgd2luZWRlc2M7CgogICAgVFJBQ0UoIiglcCkgOiBTb3VyY2UgKCVwKSAgUmVjdCAoJXApIERlc3RpbmF0aW9uICglcCkgUG9pbnQoJXApXG4iLCBUaGlzLCBwU291cmNlU3VyZmFjZSwgcFNvdXJjZVJlY3QsIHBEZXN0aW5hdGlvblN1cmZhY2UsIHBEZXN0UG9pbnQpOwogICAgbWVtc2V0KCZ3aW5lZGVzYywgMCwgc2l6ZW9mKHdpbmVkZXNjKSk7CiAgICB3aW5lZGVzYy5XaWR0aCAgPSAmc3JjU3VyZmFjZVdpZHRoOwogICAgd2luZWRlc2MuSGVpZ2h0ID0gJnNyY1N1cmZhY2VIZWlnaHQ7CiAgICB3aW5lZGVzYy5Qb29sICAgPSAmc3JjUG9vbDsKICAgIHdpbmVkZXNjLkZvcm1hdCA9ICZzcmNGb3JtYXQ7CgogICAgSVdpbmVEM0RTdXJmYWNlX0dldERlc2MocFNvdXJjZVN1cmZhY2UsICZ3aW5lZGVzYyk7CgogICAgd2luZWRlc2MuV2lkdGggID0gJmRlc3RTdXJmYWNlV2lkdGg7CiAgICB3aW5lZGVzYy5IZWlnaHQgPSAmZGVzdFN1cmZhY2VIZWlnaHQ7CiAgICB3aW5lZGVzYy5Qb29sICAgPSAmZGVzdFBvb2w7CiAgICB3aW5lZGVzYy5Gb3JtYXQgPSAmZGVzdEZvcm1hdDsKICAgIHdpbmVkZXNjLlNpemUgICA9ICZkZXN0U2l6ZTsKCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0RGVzYyhwRGVzdGluYXRpb25TdXJmYWNlLCAmd2luZWRlc2MpOwoKICAgIGlmKHNyY1Bvb2wgIT0gV0lORUQzRFBPT0xfU1lTVEVNTUVNICB8fCBkZXN0UG9vbCAhPSBXSU5FRDNEUE9PTF9ERUZBVUxUKXsKICAgICAgICBXQVJOKCJzb3VyY2UgJXAgbXVzdCBiZSBTWVNURU1NRU0gYW5kIGRlc3QgJXAgbXVzdCBiZSBERUZBVUxULCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIiwgcFNvdXJjZVN1cmZhY2UsIHBEZXN0aW5hdGlvblN1cmZhY2UpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmIChkZXN0Rm9ybWF0ID09IFdJTkVEM0RGTVRfVU5LTk9XTikgewogICAgICAgIFRSQUNFKCIoJXApIDogQ29udmVydGluZyBkZXN0aW5hdGlvbiBzdXJmYWNlIGZyb20gV0lORUQzREZNVF9VTktOT1dOIHRvIHRoZSBzb3VyY2UgZm9ybWF0XG4iLCBUaGlzKTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Rm9ybWF0KHBEZXN0aW5hdGlvblN1cmZhY2UsIHNyY0Zvcm1hdCk7CgogICAgICAgIC8qIEdldCB0aGUgdXBkYXRlIHN1cmZhY2UgZGVzY3JpcHRpb24gKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0RGVzYyhwRGVzdGluYXRpb25TdXJmYWNlLCAmd2luZWRlc2MpOwogICAgfQoKICAgIC8qIE1ha2Ugc3VyZSB0aGUgc3VyZmFjZSBpcyBsb2FkZWQgYW5kIHVwIHRvIGRhdGUgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKHBEZXN0aW5hdGlvblN1cmZhY2UpOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRHbERlc2MocERlc3RpbmF0aW9uU3VyZmFjZSwgJmdsRGVzY3JpcHRpb24pOwoKICAgIEVOVEVSX0dMKCk7CgogICAgLyogdGhpcyBuZWVkcyB0byBiZSBkb25lIGluIGxpbmVzIGlmIHRoZSBzb3VyY2VSZWN0ICE9IHRoZSBzb3VyY2VXaWR0aCAqLwogICAgc3JjV2lkdGggICA9IHBTb3VyY2VSZWN0ID8gcFNvdXJjZVJlY3QtPnJpZ2h0IC0gcFNvdXJjZVJlY3QtPmxlZnQgICA6IHNyY1N1cmZhY2VXaWR0aDsKICAgIHNyY0hlaWdodCAgPSBwU291cmNlUmVjdCA/IHBTb3VyY2VSZWN0LT50b3AgICAtIHBTb3VyY2VSZWN0LT5ib3R0b20gOiBzcmNTdXJmYWNlSGVpZ2h0OwogICAgZGVzdExlZnQgICA9IHBEZXN0UG9pbnQgID8gcERlc3RQb2ludC0+eCA6IDA7CiAgICBkZXN0VG9wICAgID0gcERlc3RQb2ludCAgPyBwRGVzdFBvaW50LT55IDogMDsKCgogICAgLyogVGhpcyBmdW5jdGlvbiBkb2Vzbid0IHN1cHBvcnQgY29tcHJlc3NlZCB0ZXh0dXJlcwogICAgdGhlIHBpdGNoIGlzIGp1c3QgYnl0ZXNQZXJQaXhlbCAqIHdpZHRoICovCiAgICBpZihzcmNXaWR0aCAhPSBzcmNTdXJmYWNlV2lkdGggIHx8IChwU291cmNlUmVjdCAhPSBOVUxMICYmIHBTb3VyY2VSZWN0LT5sZWZ0ICE9IDApICl7CiAgICAgICAgcm93b2Zmc2V0ID0gKHNyY1N1cmZhY2VXaWR0aCAtIHNyY1dpZHRoKSAqIHBTcmNTdXJmYWNlLT5ieXRlc1BlclBpeGVsOwogICAgICAgIG9mZnNldCAgICs9IHBTb3VyY2VSZWN0LT5sZWZ0ICogcFNyY1N1cmZhY2UtPmJ5dGVzUGVyUGl4ZWw7CiAgICAgICAgLyogVE9ETzogZG8gd2UgZXZlciBnZXQgM2JwcD8sIHdvdWxkIGEgc2hpZnQgYW5kIGFuIGFkZCBiZSBxdWlja2VyIHRoYW4gYSBtdWwgKHdlbGwgbWF5YmUgYSBjeWNsZSBvciB0d28pICovCiAgICB9CiAgICAvKiBUT0RPIERYVCBmb3JtYXRzICovCgogICAgaWYocFNvdXJjZVJlY3QgIT0gTlVMTCAmJiBwU291cmNlUmVjdC0+dG9wICE9IDApewogICAgICAgb2Zmc2V0ICs9ICBwU291cmNlUmVjdC0+dG9wICogc3JjV2lkdGggKiBwU3JjU3VyZmFjZS0+Ynl0ZXNQZXJQaXhlbDsKICAgIH0KICAgIFRSQUNFKCIoJXApIGdsVGV4U3ViSW1hZ2UyRCwgTGV2ZWwgJWQsIGxlZnQgJWQsIHRvcCAlZCwgd2lkdGggJWQsIGhlaWdodCAlZCAsIGZ0bSAlZCwgdHlwZSAlZCwgbWVtb3J5ICVwXG4iCiAgICAsVGhpcwogICAgLGdsRGVzY3JpcHRpb24tPmxldmVsCiAgICAsZGVzdExlZnQKICAgICxkZXN0VG9wCiAgICAsc3JjV2lkdGgKICAgICxzcmNIZWlnaHQKICAgICxnbERlc2NyaXB0aW9uLT5nbEZvcm1hdAogICAgLGdsRGVzY3JpcHRpb24tPmdsVHlwZQogICAgLElXaW5lRDNEU3VyZmFjZV9HZXREYXRhKHBTb3VyY2VTdXJmYWNlKQogICAgKTsKCiAgICAvKiBTYW5pdHkgY2hlY2sgKi8KICAgIGlmIChJV2luZUQzRFN1cmZhY2VfR2V0RGF0YShwU291cmNlU3VyZmFjZSkgPT0gTlVMTCkgewoKICAgICAgICAvKiBuZWVkIHRvIGxvY2sgdGhlIHN1cmZhY2UgdG8gZ2V0IHRoZSBkYXRhICovCiAgICAgICAgRklYTUUoIlN1cmZhY2VzIGhhcyBubyBhbGxvY2F0ZWQgbWVtb3J5LCBidXQgc2hvdWxkIGJlIGFuIGluIG1lbW9yeSBvbmx5IHN1cmZhY2VcbiIpOwogICAgfQoKICAgIC8qIFRPRE86IEN1YmUgYW5kIHZvbHVtZSBzdXBwb3J0ICovCiAgICBpZihyb3dvZmZzZXQgIT0gMCl7CiAgICAgICAgLyogbm90IGEgd2hvbGUgcm93IHNvIHdlIGhhdmUgdG8gZG8gaXQgYSBsaW5lIGF0IGEgdGltZSAqLwogICAgICAgIGludCBqOwoKICAgICAgICAvKiBob3BlZnVsbHkgdXNpbmcgcG9pbnRlciBhZGR0aW9uIHdpbGwgYmUgcXVpY2tlciB0aGFuIHVzaW5nIGEgcG9pbnQgKyBqICogcm93b2Zmc2V0ICovCiAgICAgICAgdW5zaWduZWQgY2hhciogZGF0YSA9KCh1bnNpZ25lZCBjaGFyICopSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpKSArIG9mZnNldDsKCiAgICAgICAgZm9yKGogPSBkZXN0VG9wIDsgaiA8IChzcmNIZWlnaHQgKyBkZXN0VG9wKSA7IGorKyl7CgogICAgICAgICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKGdsRGVzY3JpcHRpb24tPnRhcmdldAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5sZXZlbAogICAgICAgICAgICAgICAgICAgICxkZXN0TGVmdAogICAgICAgICAgICAgICAgICAgICxqCiAgICAgICAgICAgICAgICAgICAgLHNyY1dpZHRoCiAgICAgICAgICAgICAgICAgICAgLDEKICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xGb3JtYXQKICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xUeXBlCiAgICAgICAgICAgICAgICAgICAgLGRhdGEgLyogY291bGQgYmUgcXVpY2tlciB1c2luZyAqLwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgZGF0YSArPSByb3dvZmZzZXQ7CiAgICAgICAgfQoKICAgIH0gZWxzZSB7IC8qIEZ1bGwgd2lkdGgsIHNvIGp1c3Qgd3JpdGUgb3V0IHRoZSB3aG9sZSB0ZXh0dXJlICovCgogICAgICAgIGlmIChXSU5FRDNERk1UX0RYVDEgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDIgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDMgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDQgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDUgPT0gZGVzdEZvcm1hdCkgewogICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChFWFRfVEVYVFVSRV9DT01QUkVTU0lPTl9TM1RDKSkgewogICAgICAgICAgICAgICAgaWYgKGRlc3RTdXJmYWNlSGVpZ2h0ICE9IHNyY0hlaWdodCB8fCBkZXN0U3VyZmFjZVdpZHRoICE9IHNyY1dpZHRoKSB7CiAgICAgICAgICAgICAgICAgICAgLyogRklYTUU6IFRoZSBlYXN5IHdheSB0byBkbyB0aGlzIGlzIGxvY2sgdGhlIGRlc3RpbmF0aW9uLCBhbmQgY29weSB0aGUgYml0cyBhY2Nyb3NzICovCiAgICAgICAgICAgICAgICAgICAgRklYTUUoIlVwZGF0aW5nIHBhcnQgb2YgYSBjb21wcmVzc2VkIHRleHR1cmUgaXMgbm90IHN1cHBvcnRlZCBhdCB0aGUgbW9tZW50XG4iKTsKICAgICAgICAgICAgICAgIH0gaWYgKGRlc3RGb3JtYXQgIT0gc3JjRm9ybWF0KSB7CiAgICAgICAgICAgICAgICAgICAgRklYTUUoIlVwZGF0aW5nIG1peGVkIGZvcm1hdCBjb21wcmVzc2VkIHRleHR1cmUgaXMgbm90IGN1cnJldGx5IHN1cHBvcnRcbiIpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsQ29tcHJlc3NlZFRleEltYWdlMkRBUkIpKGdsRGVzY3JpcHRpb24tPnRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbERlc2NyaXB0aW9uLT5sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbERlc2NyaXB0aW9uLT5nbEZvcm1hdEludGVybmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyY1dpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyY0hlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3RTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXREYXRhKHBTb3VyY2VTdXJmYWNlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBGSVhNRSgiQXR0ZW1wdGluZyB0byB1cGRhdGUgYSBEWFQgY29tcHJlc3NlZCB0ZXh0dXJlIHdpdGhvdXQgaGFyZHdhcmUgc3VwcG9ydFxuIik7CiAgICAgICAgICAgIH0KCgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChOUDJfUkVQQUNLID09IHdpbmVkM2Rfc2V0dGluZ3Mubm9ucG93ZXIyX21vZGUpIHsKCiAgICAgICAgICAgICAgICAvKiBzb21lIGFwcGxpY2F0aW9ucyBjYW5ub3QgaGFuZGxlIG9kZCBwaXRjaGVzIHJldHVybmVkIGJ5IHNvZnQgbm9uLXBvd2VyMiwgc28gd2UgaGF2ZQogICAgICAgICAgICAgICAgdG8gcmVwYWNrIHRoZSBkYXRhIGZyb20gcG93MldpZHRoL0hlaWdodCB0byBleHBlY3RlZCBXaWR0aCxIZWlnaHQsIHRoaXMgbWFrZXMgdGhlCiAgICAgICAgICAgICAgICBkYXRhIHJldHVybmVkIGJ5IEdldERhdGEgbm9uLXBvd2VyMiB3aWR0aC9oZWlnaHQgd2l0aCBoYXJkd2FyZSBub24tcG93ZXIyCiAgICAgICAgICAgICAgICBwb3cyV2lkdGgvaGVpZ2h0IGFyZSBzZXQgdG8gc3VyZmFjZSB3aWR0aCBoZWlnaHQsIHJlcGFja2luZyBpc24ndCBuZWVkZWQgc28gaXQKICAgICAgICAgICAgICAgIGRvZXNuJ3QgbWF0dGVyIHdoaWNoIGZ1bmN0aW9uIGdldHMgY2FsbGVkLiAqLwogICAgICAgICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKGdsRGVzY3JpcHRpb24tPnRhcmdldAogICAgICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+bGV2ZWwKICAgICAgICAgICAgICAgICAgICAgICAgLGRlc3RMZWZ0CiAgICAgICAgICAgICAgICAgICAgICAgICxkZXN0VG9wCiAgICAgICAgICAgICAgICAgICAgICAgICxzcmNXaWR0aAogICAgICAgICAgICAgICAgICAgICAgICAsc3JjSGVpZ2h0CiAgICAgICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5nbEZvcm1hdAogICAgICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xUeXBlCiAgICAgICAgICAgICAgICAgICAgICAgICxJV2luZUQzRFN1cmZhY2VfR2V0RGF0YShwU291cmNlU3VyZmFjZSkKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgICAgIC8qIG5vdCByZXBhY2tlZCwgdGhlIGRhdGEgcmV0dXJuZWQgYnkgSVdpbmVEM0RTdXJmYWNlX0dldERhdGEgaXMgcG93MldpZHRoIHggcG93MkhlaWdodCAqLwogICAgICAgICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKGdsRGVzY3JpcHRpb24tPnRhcmdldAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5sZXZlbAogICAgICAgICAgICAgICAgICAgICxkZXN0TGVmdAogICAgICAgICAgICAgICAgICAgICxkZXN0VG9wCiAgICAgICAgICAgICAgICAgICAgLCgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXBTb3VyY2VTdXJmYWNlKS0+cG93MldpZHRoCiAgICAgICAgICAgICAgICAgICAgLCgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXBTb3VyY2VTdXJmYWNlKS0+cG93MkhlaWdodAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5nbEZvcm1hdAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5nbFR5cGUKICAgICAgICAgICAgICAgICAgICAsSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CgogICAgICAgIH0KICAgICB9CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhTdWJJbWFnZTJEIik7CgogICAgLyogSSBvbmx5IG5lZWQgdG8gbG9vayB1cCBiYXNlVGV4dHVyZSBoZXJlLCBzbyBpdCBtYXkgYmUgYSBnb29kIGlkZWEgdG8gaGF2YSBhIEdMX1RBUkdFVCAtPgogICAgICogR0xfRElNRU5TSU9OUyBsb29rdXAsIG9yIG1heWJlIHN0b3JlIHRoZSBkaW1lbnNpb25zIG9uIHRoZSBzdXJmYWNlIChidXQgdGhhdCdzIG1ha2luZyB0aGUKICAgICAqIHN1cmZhY2UgYmlnZ2VyIHRoYW4gaXQgbmVlZHMgdG8gYmUgaG1tLi4gKi8KICAgIGlmIChXSU5FRDNEX09LID09IElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIocERlc3RpbmF0aW9uU3VyZmFjZSwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmYmFzZVRleHR1cmUpKSB7CiAgICAgICAgdGV4dHVyZURpbWVuc2lvbnMgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldFRleHR1cmVEaW1lbnNpb25zKGJhc2VUZXh0dXJlKTsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2UoYmFzZVRleHR1cmUpOwogICAgfQoKICAgIGdsRGlzYWJsZSh0ZXh0dXJlRGltZW5zaW9ucyk7IC8qIFRoaXMgbmVlZHMgdG8gYmUgbWFuYWdlZCBiZXR0ZXIuLi4uICovCiAgICBMRUFWRV9HTCgpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBVc2VkIGJ5IERpcmVjdFggOCAqLwpIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9Db3B5UmVjdHMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UqIHBTb3VyY2VTdXJmYWNlLCAgICAgIENPTlNUIFJFQ1QqIHBTb3VyY2VSZWN0c0FycmF5LCBVSU5UIGNSZWN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlKiBwRGVzdGluYXRpb25TdXJmYWNlLCBDT05TVCBQT0lOVCogcERlc3RQb2ludHNBcnJheSkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBIUkVTVUxUICAgICAgICAgICAgICBociA9IFdJTkVEM0RfT0s7CiAgICBXSU5FRDNERk9STUFUICAgICAgICBzcmNGb3JtYXQsIGRlc3RGb3JtYXQ7CiAgICBVSU5UICAgICAgICAgICAgICAgICBzcmNXaWR0aCwgIGRlc3RXaWR0aDsKICAgIFVJTlQgICAgICAgICAgICAgICAgIHNyY0hlaWdodCwgZGVzdEhlaWdodDsKICAgIFVJTlQgICAgICAgICAgICAgICAgIHNyY1NpemU7CiAgICBXSU5FRDNEU1VSRkFDRV9ERVNDICB3aW5lZGVzYzsKCiAgICBUUkFDRSgiKCVwKSBwU3JjU3VyPSVwLCBwU291cmNlUmVjdHM9JXAsIGNSZWN0cz0lZCwgcERzdFN1cj0lcCwgcERlc3RQdHNBcnI9JXBcbiIsIFRoaXMsCiAgICAgICAgICBwU291cmNlU3VyZmFjZSwgcFNvdXJjZVJlY3RzQXJyYXksIGNSZWN0cywgcERlc3RpbmF0aW9uU3VyZmFjZSwgcERlc3RQb2ludHNBcnJheSk7CgoKICAgIC8qIENoZWNrIHRoYXQgdGhlIHNvdXJjZSB0ZXh0dXJlIGlzIGluIFdJTkVEM0RQT09MX1NZU1RFTU1FTSBhbmQgdGhlIGRlc3RpbmF0aW9uIHRleHR1cmUgaXMgaW4gV0lORUQzRFBPT0xfREVGQVVMVCAqLwogICAgbWVtc2V0KCZ3aW5lZGVzYywgMCwgc2l6ZW9mKHdpbmVkZXNjKSk7CgogICAgd2luZWRlc2MuRm9ybWF0ID0gJnNyY0Zvcm1hdDsKICAgIHdpbmVkZXNjLldpZHRoICA9ICZzcmNXaWR0aDsKICAgIHdpbmVkZXNjLkhlaWdodCA9ICZzcmNIZWlnaHQ7CiAgICB3aW5lZGVzYy5TaXplICAgPSAmc3JjU2l6ZTsKICAgIElXaW5lRDNEU3VyZmFjZV9HZXREZXNjKHBTb3VyY2VTdXJmYWNlLCAmd2luZWRlc2MpOwoKICAgIHdpbmVkZXNjLkZvcm1hdCA9ICZkZXN0Rm9ybWF0OwogICAgd2luZWRlc2MuV2lkdGggID0gJmRlc3RXaWR0aDsKICAgIHdpbmVkZXNjLkhlaWdodCA9ICZkZXN0SGVpZ2h0OwogICAgd2luZWRlc2MuU2l6ZSAgID0gTlVMTDsKICAgIElXaW5lRDNEU3VyZmFjZV9HZXREZXNjKHBEZXN0aW5hdGlvblN1cmZhY2UsICZ3aW5lZGVzYyk7CgogICAgLyogQ2hlY2sgdGhhdCB0aGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBmb3JtYXRzIG1hdGNoICovCiAgICBpZiAoc3JjRm9ybWF0ICE9IGRlc3RGb3JtYXQgJiYgV0lORUQzREZNVF9VTktOT1dOICE9IGRlc3RGb3JtYXQpIHsKICAgICAgICBXQVJOKCIoJXApIHNvdXJjZSAlcCBmb3JtYXQgbXVzdCBtYXRjaCB0aGUgZGVzdCAlcCBmb3JtYXQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLCBUaGlzLCBwU291cmNlU3VyZmFjZSwgcERlc3RpbmF0aW9uU3VyZmFjZSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9IGVsc2UgaWYgKFdJTkVEM0RGTVRfVU5LTk9XTiA9PSBkZXN0Rm9ybWF0KSB7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBDb252ZXJ0aW5nIGRlc3RpbmF0aW9uIHN1cmZhY2UgZnJvbSBXSU5FRDNERk1UX1VOS05PV04gdG8gdGhlIHNvdXJjZSBmb3JtYXRcbiIsIFRoaXMpOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRGb3JtYXQocERlc3RpbmF0aW9uU3VyZmFjZSwgc3JjRm9ybWF0KTsKICAgICAgICBkZXN0Rm9ybWF0ID0gc3JjRm9ybWF0OwogICAgfQoKICAgIC8qIFF1aWNrIGlmIGNvbXBsZXRlIGNvcHkgLi4uICovCiAgICBpZiAoY1JlY3RzID09IDAgJiYgcFNvdXJjZVJlY3RzQXJyYXkgPT0gTlVMTCAmJiBwRGVzdFBvaW50c0FycmF5ID09IE5VTEwpIHsKCiAgICAgICAgaWYgKHNyY1dpZHRoID09IGRlc3RXaWR0aCAmJiBzcmNIZWlnaHQgPT0gZGVzdEhlaWdodCkgewogICAgICAgICAgICBXSU5FRDNETE9DS0VEX1JFQ1QgbHJTcmM7CiAgICAgICAgICAgIFdJTkVEM0RMT0NLRURfUkVDVCBsckRzdDsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KHBTb3VyY2VTdXJmYWNlLCAgICAgICZsclNyYywgTlVMTCwgV0lORUQzRExPQ0tfUkVBRE9OTFkpOwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QocERlc3RpbmF0aW9uU3VyZmFjZSwgJmxyRHN0LCBOVUxMLCAwTCk7CiAgICAgICAgICAgIFRSQUNFKCJMb2NrZWQgc3JjIGFuZCBkc3QsIERpcmVjdCBjb3B5IGFzIHN1cmZhY2VzIGFyZSBlcXVhbCwgdz0lZCwgaD0lZFxuIiwgc3JjV2lkdGgsIHNyY0hlaWdodCk7CgogICAgICAgICAgICBtZW1jcHkobHJEc3QucEJpdHMsIGxyU3JjLnBCaXRzLCBzcmNTaXplKTsKCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KHBTb3VyY2VTdXJmYWNlKTsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QocERlc3RpbmF0aW9uU3VyZmFjZSk7CiAgICAgICAgICAgIFRSQUNFKCJVbmxvY2tlZCBzcmMgYW5kIGRzdFxuIik7CgogICAgICAgIH0gZWxzZSB7CgogICAgICAgICAgICBGSVhNRSgiV2FudGVkIHRvIGNvcHkgYWxsIHN1cmZhY2VzIGJ1dCBzaXplIG5vdCBjb21wYXRpYmxlLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgICAgIGhyID0gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICAgfQoKICAgIH0gZWxzZSB7CgogICAgICAgIGlmIChOVUxMICE9IHBTb3VyY2VSZWN0c0FycmF5ICYmIE5VTEwgIT0gcERlc3RQb2ludHNBcnJheSkgewoKICAgICAgICAgICAgaW50IGJ5dGVzUGVyUGl4ZWwgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKikgcFNvdXJjZVN1cmZhY2UpLT5ieXRlc1BlclBpeGVsOwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgaTsKCiAgICAgICAgICAgIC8qIENvcHkgcmVjdCBieSByZWN0ICovCiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjUmVjdHM7ICsraSkgewogICAgICAgICAgICAgICAgQ09OU1QgUkVDVCogIHIgPSAmcFNvdXJjZVJlY3RzQXJyYXlbaV07CiAgICAgICAgICAgICAgICBDT05TVCBQT0lOVCogcCA9ICZwRGVzdFBvaW50c0FycmF5W2ldOwogICAgICAgICAgICAgICAgaW50IGNvcHlwZXJsaW5lOwogICAgICAgICAgICAgICAgaW50IGo7CiAgICAgICAgICAgICAgICBXSU5FRDNETE9DS0VEX1JFQ1QgbHJTcmM7CiAgICAgICAgICAgICAgICBXSU5FRDNETE9DS0VEX1JFQ1QgbHJEc3Q7CiAgICAgICAgICAgICAgICBSRUNUIGRlc3RfcmVjdDsKCiAgICAgICAgICAgICAgICBUUkFDRSgiQ29weWluZyByZWN0ICVkICglbGQsJWxkKSwoJWxkLCVsZCkgLT4gKCVsZCwlbGQpXG4iLCBpLCByLT5sZWZ0LCByLT50b3AsIHItPnJpZ2h0LCByLT5ib3R0b20sIHAtPngsIHAtPnkpOwogICAgICAgICAgICAgICAgaWYgKHNyY0Zvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpIHsKICAgICAgICAgICAgICAgICAgICBjb3B5cGVybGluZSA9ICgoci0+cmlnaHQgLSByLT5sZWZ0KSAqIGJ5dGVzUGVyUGl4ZWwpIC8gMjsgLyogRFhUMSBpcyBoYWxmIGJ5dGUgcGVyIHBpeGVsICovCiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNvcHlwZXJsaW5lID0gKChyLT5yaWdodCAtIHItPmxlZnQpICogYnl0ZXNQZXJQaXhlbCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KHBTb3VyY2VTdXJmYWNlLCAmbHJTcmMsIHIsIFdJTkVEM0RMT0NLX1JFQURPTkxZKTsKICAgICAgICAgICAgICAgIGRlc3RfcmVjdC5sZWZ0ICA9IHAtPng7CiAgICAgICAgICAgICAgICBkZXN0X3JlY3QudG9wICAgPSBwLT55OwogICAgICAgICAgICAgICAgZGVzdF9yZWN0LnJpZ2h0ID0gcC0+eCArIChyLT5yaWdodCAtIHItPmxlZnQpOwogICAgICAgICAgICAgICAgZGVzdF9yZWN0LmJvdHRvbT0gcC0+eSArIChyLT5ib3R0b20gLSByLT50b3ApOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KHBEZXN0aW5hdGlvblN1cmZhY2UsICZsckRzdCwgJmRlc3RfcmVjdCwgMEwpOwogICAgICAgICAgICAgICAgVFJBQ0UoIkxvY2tlZCBzcmMgYW5kIGRzdFxuIik7CgogICAgICAgICAgICAgICAgLyogRmluZCB3aGVyZSB0byBzdGFydCAqLwogICAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IChyLT5ib3R0b20gLSByLT50b3AgLSAxKTsgKytqKSB7CiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KChjaGFyKikgbHJEc3QucEJpdHMgKyAoaiAqIGxyRHN0LlBpdGNoKSwgKGNoYXIqKSBsclNyYy5wQml0cyArIChqICogbHJTcmMuUGl0Y2gpLCBjb3B5cGVybGluZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChwU291cmNlU3VyZmFjZSk7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChwRGVzdGluYXRpb25TdXJmYWNlKTsKICAgICAgICAgICAgICAgIFRSQUNFKCJVbmxvY2tlZCBzcmMgYW5kIGRzdFxuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBGSVhNRSgiV2FudGVkIHRvIGNvcHkgcGFydGlhbCBzdXJmYWNlcyBub3QgaW1wbGVtZW50ZWQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAgICAgaHIgPSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCi8qIEltcGxlbWVudGF0aW9uIGRldGFpbHMgYXQgaHR0cDovL2RldmVsb3Blci5udmlkaWEuY29tL2F0dGFjaC82NDk0CmFuZApodHRwOi8vb3NzLnNnaS5jb20vcHJvamVjdHMvb2dsLXNhbXBsZS9yZWdpc3RyeS9OVi9ldmFsdWF0b3JzLnR4dApobW0uLiBubyBsb25nZXIgc3VwcG9ydGVkIHVzZQpPcGVuR0wgZXZhbHVhdG9ycyBvciAgdGVzc2VsbGF0ZSBzdXJmYWNlcyB3aXRoaW4geW91ciBhcHBsaWNhdGlvbi4KKi8KCi8qIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvZGlyZWN0eDlfYy9kaXJlY3R4L2dyYXBoaWNzL3JlZmVyZW5jZS9kM2QvaW50ZXJmYWNlcy9pZGlyZWN0M2RkZXZpY2U5L0RyYXdSZWN0UGF0Y2guYXNwICovCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UmVjdFBhdGNoKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBIYW5kbGUsIENPTlNUIGZsb2F0KiBwTnVtU2VncywgQ09OU1QgV0lORUQzRFJFQ1RQQVRDSF9JTkZPKiBwUmVjdFBhdGNoSW5mbykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgSGFuZGxlKCVkKSBub1NlZ3MoJXApIHJlY3RwYXRjaCglcClcbiIsIFRoaXMsIEhhbmRsZSwgcE51bVNlZ3MsIHBSZWN0UGF0Y2hJbmZvKTsKICAgIEZJWE1FKCIoJXApIDogU3R1YlxuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKCn0KCi8qIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvZGlyZWN0eDlfYy9kaXJlY3R4L2dyYXBoaWNzL3JlZmVyZW5jZS9kM2QvaW50ZXJmYWNlcy9pZGlyZWN0M2RkZXZpY2U5L0RyYXdUcmlQYXRjaC5hc3AgKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdUcmlQYXRjaChJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgSGFuZGxlLCBDT05TVCBmbG9hdCogcE51bVNlZ3MsIENPTlNUIFdJTkVEM0RUUklQQVRDSF9JTkZPKiBwVHJpUGF0Y2hJbmZvKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSBIYW5kbGUoJWQpIG5vU2VncyglcCkgdHJpcGF0Y2goJXApXG4iLCBUaGlzLCBIYW5kbGUsIHBOdW1TZWdzLCBwVHJpUGF0Y2hJbmZvKTsKICAgIEZJWE1FKCIoJXApIDogU3R1YlxuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RlbGV0ZVBhdGNoKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBIYW5kbGUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIEhhbmRsZSglZClcbiIsIFRoaXMsIEhhbmRsZSk7CiAgICBGSVhNRSgiKCVwKSA6IFN0dWJcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9Db2xvckZpbGwoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKnBTdXJmYWNlLCBDT05TVCBEM0RSRUNUKiBwUmVjdCwgRDNEQ09MT1IgY29sb3IpIHsKICAgIC8qIEkgY291bGRuJ3QgZmluZCBhICdyZWFsbHknIHF1aWNrIHdheSBvZiBkb2luZyB0aGlzIGluIG9wZW5HbCBzbyBoZXJlIGdvZXMKICAgIGZpbGwgYSBzdXJmYWNlIHdpdGggYSBibG9jayBvZiBjb2xvciEgICovCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAvKiBUT0RPOiBnZXQgcmlkIG9mIHRoZSB1c2Ugb2YgSVdpbmVEM0RTdXJmYWNlSW1wbCwgbW92ZSBjb2RlIGludG8gc3VyZmFjZS5jICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpzdXJmYWNlID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilwU3VyZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqY29udGFpbmVyID0gTlVMTDsKICAgIEJPT0wgaXNSZW5kZXJUYXJnZXQgPSBGQUxTRTsKICAgIHVuc2lnbmVkIGludCB3aWR0aCwgaGVpZ2h0OwogICAgdW5zaWduZWQgaW50IHRvcCwgbGVmdDsKICAgIHVuc2lnbmVkIGludCB1LCB2OwogICAgRFdPUkQgICAgICAgKmRhdGE7CiAgICBUUkFDRSgiKCVwKSBDb2xvdXIgZmlsbCBTdXJmYWNlOiAlcCByZWN0OiAlcCBjb2xvcjogJWxkXG4iLCBUaGlzLCBwU3VyZmFjZSwgcFJlY3QsIGNvbG9yKTsKCiAgICBpZiAoc3VyZmFjZS0+cmVzb3VyY2UucG9vbCAhPSBXSU5FRDNEUE9PTF9ERUZBVUxUKSB7CiAgICAgICAgRklYTUUoImNhbGwgdG8gY29sb3JmaWxsIHdpdGggbm9uIFdJTkVEM0RQT09MX0RFRkFVTFQgc3VyZmFjZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogVE9ETzogZ2V0IHJpZCBvZiBJV2luZUQzRFN3YXBDaGFpbkltcGwgcmVmZXJlbmNlLCBhICdjb250ZXh0JyBtYW5hZ2VyIG1heSBoZWxwIHdpdGggdGhpcyAqLwogICAgaWYgKFdJTkVEM0RfT0sgPT0gSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihwU3VyZmFjZSwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJmNvbnRhaW5lcikgfHwgcFN1cmZhY2UgPT0gVGhpcy0+cmVuZGVyVGFyZ2V0KSB7CiAgICAgICAgaWYgKFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQgJiBzdXJmYWNlLT5yZXNvdXJjZS51c2FnZSkgewogICAgICAgICAgICAvKiBUT0RPOiBtYWtlIHN1cmUgd2Ugc2V0IGV2ZXJ5dGhpbmcgYmFjayB0byB0aGUgd2F5IGl0IHdhcywgYW5kIGNvbnRleHQgbWFuYWdlbWVudCEKICAgICAgICAgICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfUkVBRF9CVUZGRVIsICZwcmV2X3JlYWQpOwogICAgICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbEludGVnZXJ2Iik7CiAgICAgICAgICAgICAgICBnbEdldEludGVnZXJ2KEdMX1BBQ0tfU1dBUF9CWVRFUywgJnByZXZfc3RvcmUpOwogICAgICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbEludGVnZXJ2Iik7CiAgICAgICAgICAgICovCiAgICAgICAgICAgIFRSQUNFKCJDb2xvciBmaWxsIHRvIHJlbmRlciB0YXJnZXRzIG1heSBjYXVzZSBzb21lIGdyYXBoaWNzIGlzc3Vlc1xuIik7CiAgICAgICAgICAgIGlmIChwU3VyZmFjZSA9PSBjb250YWluZXItPmZyb250QnVmZmVyKSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKFdJTkVEM0RVU0FHRV9ERVBUSFNURU5DSUwgJiBzdXJmYWNlLT5yZXNvdXJjZS51c2FnZSkgewogICAgICAgICAgICAgICAgRklYTUUoImNvbG91cmluZyBvZiBkZXB0aF9zdGVuY2lsPyAlcCBidWZmZXJzIGlzIG5vdCB5ZXQgc3VwcG9ydGVkPyAlbGRcbiIsIHN1cmZhY2UsIHN1cmZhY2UtPnJlc291cmNlLnVzYWdlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIDogUmVncmVzc2lvbiAlbGQgJXAgJXBcbiIsIFRoaXMsIHN1cmZhY2UtPnJlc291cmNlLnVzYWdlLCBwU3VyZmFjZSwgVGhpcy0+cmVuZGVyVGFyZ2V0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY29udGFpbmVyICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopY29udGFpbmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiB3ZSBjYW4gdXNlIEdMX1NURU5DSUxfSU5ERVggZXRjLi4uKi8KICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICAgICAgfQogICAgICAgIGlmIChjb250YWluZXIgIT0gTlVMTCkgewogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKWNvbnRhaW5lcik7CiAgICAgICAgfQogICAgICAgIGlzUmVuZGVyVGFyZ2V0ID0gVFJVRTsKICAgIH0KICAgIC8qIFRPRE86IGRyYXdpbmcgdG8gR0xfRlJPTlQgYW5kIEdMX0JBQ0sgKi8KICAgIC8qIFRPRE86IHNlZSBpZiB0aGluZ3MgY2FuIGJlIHNwZWVkZWQgdXAgYnkgdXNpbmcgdGhlIGNvcnJlY3QKICAgICAqIGNvbG91ciBtb2RlbCBvZiB0aGUgdGFyZ2V0IHRleHR1cmUgZnJvbSB0aGUgc3RhcnQgKDE2IGJpdCBncmFwaGljcyBvbiAzMiBYIGFyZSBzbG93IGFueXdheSEpICovCiAgICBpZiAocFJlY3QgPT0gTlVMTCkgewogICAgICAgIHRvcCAgICA9IDA7CiAgICAgICAgbGVmdCAgID0gMDsKICAgICAgICB3aWR0aCAgPSBzdXJmYWNlLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBoZWlnaHQgPSBzdXJmYWNlLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICB9IGVsc2UgewogICAgICAgIGxlZnQgICA9IHBSZWN0LT54MTsKICAgICAgICB0b3AgICAgPSBwUmVjdC0+eTE7CiAgICAgICAgd2lkdGggID0gcFJlY3QtPngyIC0gbGVmdDsKICAgICAgICBoZWlnaHQgPSBwUmVjdC0+eTIgLSB0b3A7CiAgICB9CgogICAgZGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCA0ICogd2lkdGgpOwogICAgLyogQ3JlYXRlIGEgJ2xpbmUnIG9mIGNvbG9yIGNvbG9yLCBpbiB0aGUgY29ycmVjdCBmb3JtYXQgZm9yIHRoZSBzdXJmYWNlICovCiAgICBmb3IgKHUgPSAwIDsgdSA8IHdpZHRoIDsgdSArKykgewogICAgICAgICAgICBkYXRhW3VdID0gY29sb3I7CiAgICB9CgogICAgRU5URVJfR0woKTsKICAgIGlmIChpc1JlbmRlclRhcmdldCA9PSBGQUxTRSkgewogICAgICAgIGdsRGVzY3JpcHRvciAqZ2xEZXNjOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKHBTdXJmYWNlKTsKCiAgICAgICAgLyogZHJhdyBhIGJsb2NrIG9mIHRoZSBjb2xvdXJlZCBsaW5lIG9uIHRoZSBzdWZyYWNlICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldEdsRGVzYyhwU3VyZmFjZSwgJmdsRGVzYyk7CiAgICAgICAgZm9yICh2ID0gMCA7IHY8IGhlaWdodDt2KyspIHsKICAgICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKGdsRGVzYy0+dGFyZ2V0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjLT5sZXZlbCAvKiBsZXZlbCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLGxlZnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICx0b3AgKyB2CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAsd2lkdGgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICwxIC8qIGhlaWdodCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLEdMX1JHQkEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICxHTF9VTlNJR05FRF9CWVRFCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAsZGF0YQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4U3ViSW1hZ2UyRCIpOwogICAgICAgIC8qIGNsZWFuIHVwICovCiAgICAgICAgZ2xEaXNhYmxlKGdsRGVzYy0+dGFyZ2V0KTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyoqIEZJWE1FOiBVc2luZyBHTENsZWFyIG1heSBiZSBmYXN0ZXIgKiovCiAgICAgICAgZ2xSYXN0ZXJQb3MyaShsZWZ0LCB0b3ApOwogICAgICAgIGdsUGl4ZWxab29tKChmbG9hdCl3aWR0aCAsKGZsb2F0KWhlaWdodCk7CiAgICAgICAgZ2xEcmF3UGl4ZWxzKDEsIDEsIEdMX1JHQkEsIEdMX1VOU0lHTkVEX0JZVEUsIGRhdGEpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdQaXhlbHMiKTsKICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRhdGEpOwogICAgTEVBVkVfR0woKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwoKfQoKLyogcmVuZGVydGFyZ2V0IGFuZCBkZXB0dGggc3RlbmNpbCBmdW5jdGlvbnMgKi8KSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0UmVuZGVyVGFyZ2V0KElXaW5lRDNERGV2aWNlKiBpZmFjZSxEV09SRCBSZW5kZXJUYXJnZXRJbmRleCwgSVdpbmVEM0RTdXJmYWNlICoqcHBSZW5kZXJUYXJnZXQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICAvKiBGSVhNRTogSW1wbGVsZW50IFJlbmRlclRhcmdldEluZGV4ID4wICovCiAgICBpZihSZW5kZXJUYXJnZXRJbmRleCA+IDApCiAgICAgICAgRklYTUUoIiglcCkgOiBSZW5kZXJUYXJnZXRJbmRleCAlbGQgPjAgbm90IGN1cnJlbnRseSBzdXBwb3J0ZWRcbiIsIFRoaXMsIFJlbmRlclRhcmdldEluZGV4KTsKCiAgICAqcHBSZW5kZXJUYXJnZXQgPSBUaGlzLT5yZW5kZXJUYXJnZXQ7CiAgICBUUkFDRSgiKCVwKSA6IFJlbmRlclRhcmdldCAlbGQgSW5kZXggcmV0dXJuaW5nICVwXG4iLCBUaGlzLCBSZW5kZXJUYXJnZXRJbmRleCwgKnBwUmVuZGVyVGFyZ2V0KTsKICAgIC8qIE5vdGUgaW5jIHJlZiBvbiByZXR1cm5lZCBzdXJmYWNlICovCiAgICBpZigqcHBSZW5kZXJUYXJnZXQgIT0gTlVMTCkKICAgICAgICBJV2luZUQzRFN1cmZhY2VfQWRkUmVmKCpwcFJlbmRlclRhcmdldCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZyb250QmFja0J1ZmZlcnMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKkZyb250LCBJV2luZUQzRFN1cmZhY2UgKkJhY2spIHsKICAgIEZJWE1FKCJUaGlzIGNhbGwgaXMgYSBkM2Q3IG1lcmdlIHN0dWIuIEl0IHdpbGwgYmUgaW1wbGVtZW50ZWQgbGF0ZXJcbiIpOwogICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7Cn0KCkhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldERlcHRoU3RlbmNpbFN1cmZhY2UoSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKipwcFpTdGVuY2lsU3VyZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgKnBwWlN0ZW5jaWxTdXJmYWNlID0gVGhpcy0+ZGVwdGhTdGVuY2lsQnVmZmVyOwogICAgVFJBQ0UoIiglcCkgOiB6U3RlbmNpbFN1cmZhY2UgIHJldHVybmluZyAlcFxuIiwgVGhpcywgICpwcFpTdGVuY2lsU3VyZmFjZSk7CgogICAgaWYoKnBwWlN0ZW5jaWxTdXJmYWNlICE9IE5VTEwpIHsKICAgICAgICAvKiBOb3RlIGluYyByZWYgb24gcmV0dXJuZWQgc3VyZmFjZSAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoKnBwWlN0ZW5jaWxTdXJmYWNlKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBpbnRlcm5hbCBzdGF0aWMgaGVscGVyIGZ1bmN0aW9ucyAqLwpIUkVTVUxUIFdJTkFQSSBzdGF0aWMgSVdpbmVEM0REZXZpY2VJbXBsX0FjdGl2ZVJlbmRlcihJV2luZUQzRERldmljZSogaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqUmVuZGVyU3VyZmFjZSk7CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UmVuZGVyVGFyZ2V0KElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgUmVuZGVyVGFyZ2V0SW5kZXgsIElXaW5lRDNEU3VyZmFjZSAqcFJlbmRlclRhcmdldCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSFJFU1VMVCAgaHIgPSBXSU5FRDNEX09LOwogICAgV0lORUQzRFZJRVdQT1JUIHZpZXdwb3J0OwoKICAgIFRSQUNFKCIoJXApIFN3YXBwaW5nIHJlbmRlcnRhcmdldFxuIixUaGlzKTsKICAgIGlmIChSZW5kZXJUYXJnZXRJbmRleCA+IDApIHsKICAgICAgICBGSVhNRSgiKCVwKSBSZW5kZXIgdGFyZ2V0cyBvdGhlciB0aGFuIHRoZSBmaXJzdCBhcmUgbm90IHN1cHBvcnRlZFxuIixUaGlzKTsKICAgICAgICBSZW5kZXJUYXJnZXRJbmRleCA9IDA7CiAgICB9CgogICAgLyogTVNETiBzYXlzIHRoYXQgbnVsbCBkaXNhYmxlcyB0aGUgcmVuZGVyIHRhcmdldAogICAgYnV0IGEgZGV2aWNlIG11c3QgYWx3YXlzIGJlIGFzc29jaWF0ZWQgd2l0aCBhIHJlbmRlciB0YXJnZXQKICAgIG5vcGUgTVNETiBzYXlzIHRoYXQgd2UgcmV0dXJuIGludmFsaWQgY2FsbCB0byBhIG51bGwgcmVuZGVydGFyZ2V0IHdpdGggYW4gaW5kZXggb2YgMAoKICAgIHNlZSBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2RpcmVjdHg5X2MvZGlyZWN0eC9ncmFwaGljcy9wcm9ncmFtbWluZ2d1aWRlL0FkdmFuY2VkVG9waWNzL1BpeGVsUGlwZS9NdWx0aXBsZVJlbmRlclRhcmdldC5hc3AKICAgIGZvciBtb3JlIGRldGFpbHMKICAgICovCiAgICBpZiAoUmVuZGVyVGFyZ2V0SW5kZXggPT0gMCAmJiBwUmVuZGVyVGFyZ2V0ID09IE5VTEwpIHsKICAgICAgICBGSVhNRSgiVHJ5aW5nIHRvIHNldCByZW5kZXIgdGFyZ2V0IDAgdG8gTlVMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAvKiBUT0RPOiByZXBsYWNlIEltcGwqIHVzYWdlIHdpdGggaW50ZXJmYWNlIHVzYWdlICovCiAgICBpZiAoISgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXBSZW5kZXJUYXJnZXQpLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpIHsKICAgICAgICBGSVhNRSgiKCVwKVRyeWluZyB0byBzZXQgdGhlIHJlbmRlciB0YXJnZXQgdG8gYSBzdXJmYWNlKCVwKSB0aGF0IHdhc24ndCBjcmVhdGVkIHdpdGggYSB1c2FnZSBvZiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUXG4iLFRoaXMgLHBSZW5kZXJUYXJnZXQpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgLyoqIFRPRE86IGNoZWNrIHRoYXQgdGhlIGRlcHRoIHN0ZW5jaWwgZm9ybWF0IG1hdGNoZXMgdGhlIHJlbmRlciB0YXJnZXQsIHRoaXMgaXMgb25seSBkb25lIGluIGRlYnVnCiAgICAgKiAgICAgICAgYnVpbGRzLCBidXQgSSB0aGluayB3aW5lIGNvdW50cyBhcyBhICdkZWJ1ZycgYnVpbGQgZm9yIG5vdy4KICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgLyogSWYgd2UgYXJlIHRyeWluZyB0byBzZXQgd2hhdCB3ZSBhbHJlYWR5IGhhdmUsIGRvbid0IGJvdGhlciAqLwogICAgaWYgKHBSZW5kZXJUYXJnZXQgPT0gVGhpcy0+cmVuZGVyVGFyZ2V0KSB7CiAgICAgICAgVFJBQ0UoIlRyeWluZyB0byBkbyBhIE5PUCBTZXRSZW5kZXJUYXJnZXQgb3BlcmF0aW9uXG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogT3RoZXJ3aXNlLCBzZXQgdGhlIHJlbmRlciB0YXJnZXQgdXAgKi8KCiAgICAgICAgaWYgKEZBTFNFID09IFRoaXMtPnNjZW5lRW5kZWQpIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfRW5kU2NlbmUoaWZhY2UpOwogICAgICAgIH0KICAgICAgICBUUkFDRSgiY2xlYXJpbmcgcmVuZGVyZXJcbiIpOwogICAgICAgIC8qIElXaW5lRDNERGV2aWNlSW1wbF9DbGVhblJlbmRlcihpZmFjZSk7ICovCiAgICAgICAgLyogT3BlbkdMIGRvZXNuJ3Qgc3VwcG9ydCAnc2hhcmluZycgb2YgdGhlIHN0ZW5jaWxCdWZmZXIgc28gd2UgbWF5IGluY3VyZSBhbiBleHRyYSBtZW1vcnkgb3ZlcmhlYWQKICAgICAgICBkZXBlbmRpbmcgb24gdGhlIHJlbnRlciB0YXJnZXQgaW1wbGVtZW50YXRpb24gYmVpbmcgdXNlZC4KICAgICAgICBBIHNoYXJlZCBjb250ZXh0IGltcGxlbWVudGF0aW9uIHdpbGwgc2hhcmUgYWxsIGJ1ZmZlcnMgYmV0d2VlbiBhbGwgcmVuZGVydGFyZ2V0cyAoaW5jbHVkaW5nIHN3YXBjaGFpbnMpLAogICAgICAgIGltcGxlbWVudGF0aW9ucyB0aGF0IHVzZSBzZXBhcmF0ZSBwYnVmZmVycyBmb3IgZGlmZmVyZW50IHN3YXBjaGFpbnMgb3IgcmVuZGVydGFyZ2V0cyB3aWxsIGhhdmUgdG8gZHVwbGljYXRlIHRoZQogICAgICAgIHN0ZW5jaWwgYnVmZmVyIGFuZCBpbmN1cmUgYW4gZXh0cmEgbWVtb3J5IG92ZXJoZWFkICovCiAgICAgICAgaHIgPSBJV2luZUQzRERldmljZUltcGxfQWN0aXZlUmVuZGVyKGlmYWNlLCBwUmVuZGVyVGFyZ2V0KTsKICAgIH0KCiAgICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgICAgIC8qIEZpbmFsbHksIHJlc2V0IHRoZSB2aWV3cG9ydCBhcyB0aGUgTVNETiBzdGF0ZXMuICovCiAgICAgICAgLyogVE9ETzogUmVwbGFjZSBpbXBsIHVzYWdlICovCiAgICAgICAgdmlld3BvcnQuSGVpZ2h0ID0gKChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+cmVuZGVyVGFyZ2V0KS0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgIHZpZXdwb3J0LldpZHRoICA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPnJlbmRlclRhcmdldCktPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIHZpZXdwb3J0LlggICAgICA9IDA7CiAgICAgICAgdmlld3BvcnQuWSAgICAgID0gMDsKICAgICAgICB2aWV3cG9ydC5NYXhaICAgPSAxLjBmOwogICAgICAgIHZpZXdwb3J0Lk1pblogICA9IDAuMGY7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZpZXdwb3J0KGlmYWNlLCAmdmlld3BvcnQpOwogICAgfSBlbHNlIHsKICAgICAgICBGSVhNRSgiVW5rbm93biBlcnJvciBzZXR0aW5nIHRoZSByZW5kZXIgdGFyZ2V0XG4iKTsKICAgIH0KICAgIFRoaXMtPnNjZW5lRW5kZWQgPSBGQUxTRTsKICAgIHJldHVybiBocjsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldERlcHRoU3RlbmNpbFN1cmZhY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKnBOZXdaU3RlbmNpbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSFJFU1VMVCAgaHIgPSBXSU5FRDNEX09LOwogICAgSVdpbmVEM0RTdXJmYWNlICp0bXA7CgogICAgVFJBQ0UoIiglcCkgU3dhcHBpbmcgei1idWZmZXJcbiIsVGhpcyk7CgogICAgaWYgKHBOZXdaU3RlbmNpbCA9PSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSB7CiAgICAgICAgVFJBQ0UoIlRyeWluZyB0byBkbyBhIE5PUCBTZXRSZW5kZXJUYXJnZXQgb3BlcmF0aW9uXG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyoqIE9wZW5HTCBkb2Vzbid0IHN1cHBvcnQgJ3NoYXJpbmcnIG9mIHRoZSBzdGVuY2lsQnVmZmVyIHNvIHdlIG1heSBpbmN1cmUgYW4gZXh0cmEgbWVtb3J5IG92ZXJoZWFkCiAgICAgICAgKiBkZXBlbmRpbmcgb24gdGhlIHJlbnRlciB0YXJnZXQgaW1wbGVtZW50YXRpb24gYmVpbmcgdXNlZC4KICAgICAgICAqIEEgc2hhcmVkIGNvbnRleHQgaW1wbGVtZW50YXRpb24gd2lsbCBzaGFyZSBhbGwgYnVmZmVycyBiZXR3ZWVuIGFsbCByZW5kZXJ0YXJnZXRzIChpbmNsdWRpbmcgc3dhcGNoYWlucyksCiAgICAgICAgKiBpbXBsZW1lbnRhdGlvbnMgdGhhdCB1c2Ugc2VwYXJhdGUgcGJ1ZmZlcnMgZm9yIGRpZmZlcmVudCBzd2FwY2hhaW5zIG9yIHJlbmRlcnRhcmdldHMgd2lsbCBoYXZlIHRvIGR1cGxpY2F0ZSB0aGUKICAgICAgICAqIHN0ZW5jaWwgYnVmZmVyIGFuZCBpbmN1cmUgYW4gZXh0cmEgbWVtb3J5IG92ZXJoZWFkCiAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgogICAgICAgIHRtcCA9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQ7CiAgICAgICAgVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCA9IHBOZXdaU3RlbmNpbDsKICAgICAgICAvKiBzaG91bGQgd2UgYmUgY2FsbGluZyB0aGUgcGFyZW50IG9yIHRoZSB3aW5lZDNkIHN1cmZhY2U/ICovCiAgICAgICAgaWYgKE5VTEwgIT0gVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZihUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KTsKICAgICAgICBpZiAoTlVMTCAhPSB0bXApIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKHRtcCk7CiAgICAgICAgaHIgPSBXSU5FRDNEX09LOwogICAgICAgIC8qKiBUT0RPOiBnbEVuYWJsZS9nbERpc2FibGUgb24gZGVwdGgvc3RlbmNpbCAgICBkZXBlbmRpbmcgb24KICAgICAgICAgKiAgIHBOZXdaU3RlbmNpbCBpcyBOVUxMIGFuZCB0aGUgZGVwdGgvc3RlbmNpbCBpcyBlbmFibGVkIGluIGQzZAogICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCgojaWZkZWYgR0xfVkVSU0lPTl8xXzMKLyogSW50ZXJuYWwgZnVuY3Rpb25zIG5vdCBpbiBEaXJlY3RYICovCiAvKiogVE9ETzogbW92ZSB0aGlzIG9mZiB0byB0aGUgb3BlbmdsIGNvbnRleHQgbWFuYWdlcgogKih0aGUgc3dhcGNoYWluIGRvZXNuJ3QgbmVlZCB0byBrbm93IGFueXRoaW5nIGFib3V0IG9mZnNjcmVlbiByZW5kZXJpbmchKQogICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ2xlYW5SZW5kZXIoSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbikKewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApLCAlcFxuIiwgVGhpcywgc3dhcGNoYWluKTsKCiAgICBpZiAoc3dhcGNoYWluLT53aW4gIT0gc3dhcGNoYWluLT5kcmF3YWJsZSkgewogICAgICAgIC8qIFNldCBldmVyeXRoaW5nIGJhY2sgdGhlIHdheSBpdCB3cyAqLwogICAgICAgIHN3YXBjaGFpbi0+cmVuZGVyX2N0eCA9IHN3YXBjaGFpbi0+Z2xDdHg7CiAgICAgICAgc3dhcGNoYWluLT5kcmF3YWJsZSAgID0gc3dhcGNoYWluLT53aW47CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogVE9ETzogbW92ZSB0aGlzIG9mZiBpbnRvIGEgY29udGV4dCBtYW5hZ2VyIHNvIHRoYXQgR0xYX0FUSV9yZW5kZXJfdGV4dHVyZSBhbmQgb3RoZXIgdHlwZXMgb2Ygc3VyZmFjZSBjYW4gYmUgdXNlZC4gKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0ZpbmRHTENvbnRleHQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKnBTdXJmYWNlLCBnbENvbnRleHQgKipjb250ZXh0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgaTsKICAgIHVuc2lnbmVkIGludCB3aWR0aDsKICAgIHVuc2lnbmVkIGludCBoZWlnaHQ7CiAgICBXSU5FRDNERk9STUFUIGZvcm1hdDsKICAgIFdJTkVEM0RTVVJGQUNFX0RFU0Mgc3VyZmFjZURlc2M7CiAgICBtZW1zZXQoJnN1cmZhY2VEZXNjLCAwLCBzaXplb2Yoc3VyZmFjZURlc2MpKTsKICAgIHN1cmZhY2VEZXNjLldpZHRoICA9ICZ3aWR0aDsKICAgIHN1cmZhY2VEZXNjLkhlaWdodCA9ICZoZWlnaHQ7CiAgICBzdXJmYWNlRGVzYy5Gb3JtYXQgPSAmZm9ybWF0OwogICAgSVdpbmVEM0RTdXJmYWNlX0dldERlc2MocFN1cmZhY2UsICZzdXJmYWNlRGVzYyk7CiAgICAqY29udGV4dCA9IE5VTEw7CiAgICAvKiBJIG5lZWQgYSBnZXQgd2lkdGgvaGVpZ2h0IGZ1bmN0aW9uIChhbmQgc2hvdWxkIGRvIHNvbWV0aGluZyB3aXRoIHRoZSBmb3JtYXQpICovCiAgICBmb3IgKGkgPSAwOyBpIDwgQ09OVEVYVF9DQUNIRTsgKytpKSB7CiAgICAgICAgLyoqIE5PVEU6IHRoZSBjb250ZXh0Q2FjaGVbaV0ucFN1cmZhY2UgPT0gcFN1cmZhY2UgY2hlY2sgY2VhdGVzIG9uZXBidWZmZXIgcGVyIHN1cmZhY2UKICAgICAgICBBVEkgY2FyZHMgZG9uJ3QgZGVzdHJveSBwYnVmZmVycywgYnV0IGFzIHNvb24gYXMgcmVzb3VyY2UgcmVsZWFzaW5nIGNhbGxiYWNrcyBhcmUgaW5wbGFjZQogICAgICAgIHRoZSBwU3VyZmFjZSBjYW4gYmUgc2V0IHRvIDAgYWxsb3dpbmcgaXQgdG8gYmUgcmV1c2VkIGZyb20gY2FjaGUgKiovCiAgICAgICAgaWYgKFRoaXMtPmNvbnRleHRDYWNoZVtpXS5XaWR0aCA9PSB3aWR0aCAmJiBUaGlzLT5jb250ZXh0Q2FjaGVbaV0uSGVpZ2h0ID09IGhlaWdodAogICAgICAgICAgJiYgKHBidWZmZXJfcGVyX3N1cmZhY2UgPT0gRkFMU0UgfHwgVGhpcy0+Y29udGV4dENhY2hlW2ldLnBTdXJmYWNlID09IHBTdXJmYWNlIHx8IFRoaXMtPmNvbnRleHRDYWNoZVtpXS5wU3VyZmFjZSA9PSBOVUxMKSkgewogICAgICAgICAgICAqY29udGV4dCA9ICZUaGlzLT5jb250ZXh0Q2FjaGVbaV07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoVGhpcy0+Y29udGV4dENhY2hlW2ldLldpZHRoID09IDApIHsKICAgICAgICAgICAgVGhpcy0+Y29udGV4dENhY2hlW2ldLnBTdXJmYWNlID0gcFN1cmZhY2U7CiAgICAgICAgICAgIFRoaXMtPmNvbnRleHRDYWNoZVtpXS5XaWR0aCAgICA9IHdpZHRoOwogICAgICAgICAgICBUaGlzLT5jb250ZXh0Q2FjaGVbaV0uSGVpZ2h0ICAgPSBoZWlnaHQ7CiAgICAgICAgICAgICpjb250ZXh0ID0gJlRoaXMtPmNvbnRleHRDYWNoZVtpXTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgaWYgKGkgPT0gQ09OVEVYVF9DQUNIRSkgewogICAgICAgIGludCBtaW5Vc2FnZSA9IDB4N0ZGRkZGRkY7IC8qIE1BWF9JTlQgKi8KICAgICAgICBnbENvbnRleHQgKmRyb3BDb250ZXh0ID0gMDsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgQ09OVEVYVF9DQUNIRTsgaSsrKSB7CiAgICAgICAgICAgIGlmIChUaGlzLT5jb250ZXh0Q2FjaGVbaV0udXNlZGNvdW50IDwgbWluVXNhZ2UpIHsKICAgICAgICAgICAgICAgIGRyb3BDb250ZXh0ID0gJlRoaXMtPmNvbnRleHRDYWNoZVtpXTsKICAgICAgICAgICAgICAgIG1pblVzYWdlID0gVGhpcy0+Y29udGV4dENhY2hlW2ldLnVzZWRjb3VudDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKiBjbGVhbiB1cCB0aGUgY29udGV4dCAodGhpcyBkb2Vzbid0IHdvcmsgZm9yIEFUSSBhdCB0aGUgbW9tZW50ICovCiNpZiAwCiAgICAgICAgZ2xYRGVzdHJveUNvbnRleHQoc3dhcGNoYWluLT5kaXNwbGF5LCBkcm9wQ29udGV4dC0+Y29udGV4dCk7CiAgICAgICAgZ2xYRGVzdHJveVBidWZmZXIoc3dhcGNoYWluLT5kaXNwbGF5LCBkcm9wQ29udGV4dC0+ZHJhd2FibGUpOwojZW5kaWYKICAgICAgICBGSVhNRSgiTGVha1xuIik7CiAgICAgICAgZHJvcENvbnRleHQtPldpZHRoID0gMDsKICAgICAgICBkcm9wQ29udGV4dC0+cFN1cmZhY2UgPSBwU3VyZmFjZTsKICAgICAgICAqY29udGV4dCA9IGRyb3BDb250ZXh0OwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoKytUaGlzLT5jb250ZXh0Q2FjaGVbaV0udXNlZGNvdW50ID09IDB4N0ZGRkZGRkYgLyogTUFYX0lOVCAqLyAtIDEgKSB7CiAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgQ09OVEVYVF9DQUNIRTsgaSsrKSB7CiAgICAgICAgICAgICBUaGlzLT5jb250ZXh0Q2FjaGVbaV0udXNlZGNvdW50ID0gbWF4KDAsIFRoaXMtPmNvbnRleHRDYWNoZVtpXS51c2VkY291bnQgLSAoMHg3RkZGRkZGRiAvKiBNQVhfSU5UICovID4+IDEpKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBpZiAoKmNvbnRleHQgIT0gTlVMTCkKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIGVsc2UKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKfQojZW5kaWYKCi8qKiBGSVhNRTogVGhpcyBpcyBjdXJyZW50bHkgdXNlZCBjYWxsZWQgd2hlbmV2ZXIgU2V0UmVuZGVyVGFyZ2V0IG9yIFNldFN0ZW5jaWxCdWZmZXIgYXJlIGNhbGxlZAoqIHRoZSBmdW5jdGlvbmFsaXR5IG5lZWRzIHNwbGl0dGluZyB1cCBzbyB0aGF0IHdlIGRvbid0IGRvIG1vcmUgdGhhbiB3ZSBzaG91bGQgZG8uCiogdGhpcyBvbmx5IHNlZW1zIHRvIGltcGFjdCBwZXJmb3JtYW5jZSBhIGxpdHRsZS4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0FjdGl2ZVJlbmRlcihJV2luZUQzRERldmljZSogaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpSZW5kZXJTdXJmYWNlKSB7CiAgICBIUkVTVUxUIHJldCA9ICBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIC8qKgogICAgKiBDdXJyZW50bHkgb25seSBhY3RpdmUgZm9yIEdMWCA+PSAxLjMKICAgICogZm9yIG90aGVycyB2ZXJzaW9ucyB3ZSdsbCBoYXZlIHRvIHVzZSBHTFhQaXhtYXBzCiAgICAqCiAgICAqIG5vcm1hbGx5IHdlIG11c3QgdGVzdCBHTFhfVkVSU0lPTl8xXzMgYnV0IG52aWRpYSBoZWFkZXJzIGFyZSBub3QgY29ycmVjdAogICAgKiBhcyB0aGV5IGltcGxlbWVudCBHTFggMS4zIGJ1dCBvbmx5IGRlZmluZSBHTFhfVkVSU0lPTl8xXzIKICAgICogc28gb25seSBjaGVjayBPcGVuR0wgdmVyc2lvbgogICAgKiAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLgogICAgKiBJIGRvbid0IGJlbGlldmUgdGhhdCBpdCBpcyBhIHByb2JsZW0gd2l0aCBOVmlkaWEgaGVhZGVycywKICAgICogWEZyZWUgb25seSBzdXBwb3J0cyBHTFgxLjIsIG5WaWRpYSAoYW5kIEFUSSB0byBzb21lIGV4dGVudCkgcHJvdmlkZSAxLjMgZnVuY3Rpb25zCiAgICAqIGluIEdMWCAxLjIsIHRoZXJlIGlzIG5vIG1lbnRpb24gb2YgdGhlIGNvcnJlY3Qgd2F5IHRvIHRlbGwgaWYgdGhlIGV4dGVuc2lvbnMgYXJlIHByb3ZpZGVkLgogICAgKiBBVEkgTm90ZToKICAgICogWW91ciBhcHBsaWNhdGlvbiB3aWxsIHJlcG9ydCBHTFggdmVyc2lvbiAxLjIgb24gZ2xYUXVlcnlWZXJzaW9uLgogICAgKiBIb3dldmVyLCBpdCBpcyBzYWZlIHRvIGNhbGwgdGhlIEdMWCAxLjMgZnVuY3Rpb25zIGFzIGRlc2NyaWJlZCBiZWxvdy4KICAgICovCiNpZiBkZWZpbmVkKEdMX1ZFUlNJT05fMV8zKQoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZSAqU3RlbmNpbFN1cmZhY2UgPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0OwogICAgSVdpbmVEM0RTdXJmYWNlICp0bXA7CiAgICAvKiogVE9ETzogd2Ugb25seSBuZWVkIHRvIGxvb2sgdXAgdGhlIGNvbmZpZ3VyYXRpb24gIUlGISB3ZSBhcmUgc2V0dGluZyB0aGUgdGFyZ2V0IHRvIGEgdGV4dHVyZSAqKi8KICAgIEdMWEZCQ29uZmlnKiBjZmdzID0gTlVMTDsKICAgIGludCBuQ2ZncyA9IDA7CiAgICBpbnQgYXR0cmlic1syNTZdOwogICAgaW50IG5BdHRyaWJzID0gMDsKICAgIElXaW5lRDNEU3dhcENoYWluICAgICAqY3VycmVudFN3YXBjaGFpbjsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluOwogICAgLyoqIFRPRE86IGdldCByaWQgb2YgSW1wbCB1c2FnZSB3ZSBzaG91bGQgYWx3YXlzIGNyZWF0ZSBhIHpidWZmZXIvc3RlbmNpbCB3aXRoIG91ciBjb250ZXh0cyBpZiBwb3NzaWJsZSwKICAgICogYnV0IHN3aXRjaCB0aGVtIG9mZiBpZiB0aGUgU3RlbmNpbFN1cmZhY2UgaXMgc2V0IHRvIE5VTEwKICAgICoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIEQzREZPUk1BVCBCYWNrQnVmZmVyRm9ybWF0ID0gKChJV2luZUQzRFN1cmZhY2VJbXBsICopIFJlbmRlclN1cmZhY2UpLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICBEM0RGT1JNQVQgU3RlbmNpbEJ1ZmZlckZvcm1hdCA9IChOVUxMICE9IFN0ZW5jaWxTdXJmYWNlKSA/ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTdGVuY2lsU3VyZmFjZSktPnJlc291cmNlLmZvcm1hdCA6IDA7CgogICAgLyoqVE9ETzoKICAgICAgICBpZiBTdGVuY2lsU3VyZmFjZSA9PSBOVUxMICYmIHpCdWZmZXJUYXJnZXQgIT0gTlVMTCB0aGVuIHN3aXRjaCB0aGUgemJ1ZmZlciBvZmYsCiAgICAgICAgaXQgU3RlbmNpbFN1cmZhY2UgIT0gTlVMTCAmJiB6QnVmZmVyVGFyZ2V0ID09IE5VTEwgc3dpdGNoIGl0IG9uCiAgICAqLwoKI2RlZmluZSBQVVNIMShhdHQpICAgICAgICBhdHRyaWJzW25BdHRyaWJzKytdID0gKGF0dCk7CiNkZWZpbmUgUFVTSDIoYXR0LHZhbHVlKSAgYXR0cmlic1tuQXR0cmlicysrXSA9IChhdHQpOyBhdHRyaWJzW25BdHRyaWJzKytdID0gKHZhbHVlKTsKCiAgICAvKiBQVVNIMihHTFhfQklORF9UT19URVhUVVJFX1JHQkFfQVRJLCBUcnVlKTsgZXhhbXBsZXMgb2YgdGhpcyBhcmUgZmV3IGFuZCBmYXIgYmV0d2VlbiAoYnV0IEkndmUgZ290IGEgbmljZSB3b3JraW5nIG9uZSEpKi8KCiAgICAvKiogVE9ETzogcmVtb3ZlIHRoZSByZWZmIHRvIEltcGwgKGNvbnRleHQgbWFuYWdlciBzaG91bGQgZml4IHRoaXMhKSAqKi8KICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqaW1wU3dhcENoYWluOwogICAgSVdpbmVEM0REZXZpY2VfR2V0U3dhcENoYWluKGlmYWNlLCAwLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopJmltcFN3YXBDaGFpbik7CiAgICBpZiAoTlVMTCA9PSBpbXBTd2FwQ2hhaW4pIHsgLyogTk9URTogVGhpcyBzaG91bGQgTkVWRVIgZmFpbCAqLwogICAgICAgIEVSUigiKCVwKSBGYWlsZWQgdG8gZ2V0IGEgdGhlIGltcGxpY2l0IHN3YXBjaGFpblxuIiwgaWZhY2UpOwogICAgfQoKICAgIEVOVEVSX0dMKCk7CgogICAgUFVTSDIoR0xYX0RSQVdBQkxFX1RZUEUsIEdMWF9QQlVGRkVSX0JJVCk7CiAgICBQVVNIMihHTFhfWF9SRU5ERVJBQkxFLCAgVFJVRSk7CiAgICBQVVNIMihHTFhfRE9VQkxFQlVGRkVSLCAgVFJVRSk7CiAgICBUUkFDRSgiY2FsbGluZyBtYWtlZ2xjZmdcbiIpOwogICAgRDNERm10TWFrZUdsQ2ZnKEJhY2tCdWZmZXJGb3JtYXQsIFN0ZW5jaWxCdWZmZXJGb3JtYXQsIGF0dHJpYnMsICZuQXR0cmlicywgRkFMU0UgLyogYWx0ZXJuYXRlICovKTsKICAgIFBVU0gxKE5vbmUpOwoKICAgIFRSQUNFKCJjYWxsaW5nIGNob29zZUZHQ29uZmlnXG4iKTsKICAgIGNmZ3MgPSBnbFhDaG9vc2VGQkNvbmZpZyhpbXBTd2FwQ2hhaW4tPmRpc3BsYXksIERlZmF1bHRTY3JlZW4oaW1wU3dhcENoYWluLT5kaXNwbGF5KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJzLCAmbkNmZ3MpOwoKICAgIGlmICghY2ZncykgeyAvKiBPSyB3ZSBkaWRuJ3QgZmluZCB0aGUgZXhhY3QgY29uZmlnLCBzbyB1c2UgYW55IHJlYXNvbmFibGUgbWF0Y2ggKi8KICAgICAgICAvKiBUT0RPOiBmaWxsIGluIHRoZSAncmVxdWVzdGVkJyBhbmQgJ2N1cnJlbnQnIGRlcHRocywgYWxzbyBtYWtlIHN1cmUgdGhhdCdzCiAgICAgICAgICAgd2h5IHdlIGZhaWxlZCBhbmQgb25seSBzaG93IHRoaXMgbWVzc2FnZSBvbmNlISAqLwogICAgICAgIE1FU1NBR0UoIkZhaWxlZCB0byBmaW5kIGV4YWN0IG1hdGNoLCBmaW5kaW5nIGFsdGVybmF0aXZlIGJ1dCB5b3UgbWF5IHN1ZmZlciBwZXJmb3JtYW5jZSBpc3N1ZXMsIHRyeSBjaGFuZ2luZyB4ZnJlZSdzIGRlcHRoIHRvIG1hdGNoIHRoZSByZXF1ZXN0ZWQgZGVwdGhcbiIpOyAvKiovCiAgICAgICAgbkF0dHJpYnMgPSAwOwogICAgICAgIFBVU0gyKEdMWF9EUkFXQUJMRV9UWVBFLCBHTFhfUEJVRkZFUl9CSVQgfCBHTFhfV0lORE9XX0JJVCk7CiAgICAgICAvKiBQVVNIMihHTFhfWF9SRU5ERVJBQkxFLCAgVFJVRSk7ICovCiAgICAgICAgUFVTSDIoR0xYX1JFTkRFUl9UWVBFLCAgIEdMWF9SR0JBX0JJVCk7CiAgICAgICAgUFVTSDIoR0xYX0RPVUJMRUJVRkZFUiwgRkFMU0UpOwogICAgICAgIFRSQUNFKCJjYWxsaW5nIG1ha2VnbGNmZ1xuIik7CiAgICAgICAgRDNERm10TWFrZUdsQ2ZnKEJhY2tCdWZmZXJGb3JtYXQsIFN0ZW5jaWxCdWZmZXJGb3JtYXQsIGF0dHJpYnMsICZuQXR0cmlicywgVFJVRSAvKiBhbHRlcm5hdGUgKi8pOwogICAgICAgIFBVU0gxKE5vbmUpOwogICAgICAgIGNmZ3MgPSBnbFhDaG9vc2VGQkNvbmZpZyhpbXBTd2FwQ2hhaW4tPmRpc3BsYXksIERlZmF1bHRTY3JlZW4oaW1wU3dhcENoYWluLT5kaXNwbGF5KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJzLCAmbkNmZ3MpOwogICAgfQoKICAgIGlmIChOVUxMICE9IGNmZ3MpIHsKI2lmZGVmIEVYVFJBX1RSQUNFUwogICAgICAgIGludCBpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBuQ2ZnczsgKytpKSB7CiAgICAgICAgICAgIFRSQUNFKCJmb3IgKCV1LCVzKS8oJXUsJXMpIGZvdW5kIGNvbmZpZ1slZF1AJXBcbiIsIEJhY2tCdWZmZXJGb3JtYXQsCiAgICAgICAgICAgIGRlYnVnX2QzZGZvcm1hdChCYWNrQnVmZmVyRm9ybWF0KSwgU3RlbmNpbEJ1ZmZlckZvcm1hdCwKICAgICAgICAgICAgZGVidWdfZDNkZm9ybWF0KFN0ZW5jaWxCdWZmZXJGb3JtYXQpLCBpLCBjZmdzW2ldKTsKICAgICAgICB9CgogICAgICAgIGlmIChOVUxMICE9IFRoaXMtPnJlbmRlclRhcmdldCkgewogICAgICAgICAgICBnbEZsdXNoKCk7CiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xGbHVzaCIpOwogICAgICAgICAgICAvKiogVGhpcyBpcyBvbmx5IHVzZWZ1bCBpZiB0aGUgb2xkIHJlbmRlciB0YXJnZXQgd2FzIGEgc3dhcGNoYWluLAogICAgICAgICAgICAqIHdlIG5lZWQgdG8gc3VwZXJjZWRlIHRoaXMgd2l0aCBhIGZ1bmN0aW9uIHRoYXQgZGlzcGxheXMKICAgICAgICAgICAgKiB0aGUgY3VycmVudCBidWZmZXIgb24gdGhlIHNjcmVlbi4gVGhpcyBpcyBlYXN5IHRvIGRvIGluIGdseDEuMyBidXQKICAgICAgICAgICAgKiB3ZSBuZWVkIHRvIGRvIGNvcHktd3JpdGUgcGl4ZWxzIGluIGdseCAxLjIuCiAgICAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgICAgICAgICAgZ2xYU3dhcEJ1ZmZlcnMoaW1wU3dhcENoYWluLT5kaXNwbGF5LCBpbXBTd2FwQ2hhaW4tPmRyYXdhYmxlKTsKCiAgICAgICAgICAgIHByaW50ZigiSGl0IEVudGVyIHRvIGdldCBuZXh0IGZyYW1lIC4uLlxuIik7CiAgICAgICAgICAgIGdldGNoYXIoKTsKICAgICAgICB9CiNlbmRpZgogICAgfQoKICAgIGlmIChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKFRoaXMtPnJlbmRlclRhcmdldCwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJmN1cnJlbnRTd2FwY2hhaW4pICE9IFdJTkVEM0RfT0spIHsKICAgICAgICAvKiB0aGUgc2VsZWN0ZWQgcmVuZGVyIHRhcmdldCBkb2Vzbid0IGJlbG9uZyB0byBhIHN3YXBjaGFpbiwgc28gdXNlIHRoZSBkZXZpY2VzIGltcGxpY2l0IHN3YXBjaGFpbiAqLwogICAgICAgIElXaW5lRDNERGV2aWNlX0dldFN3YXBDaGFpbihpZmFjZSwgMCwgJmN1cnJlbnRTd2FwY2hhaW4pOwogICAgfQoKICAgIC8qKgogICAgKiBUT0RPOiByZW1vdmUgdGhlIHVzZSBvZiBJV2luZUQzRFN3YXBDaGFpbkltcGwsIGEgY29udGV4dCBtYW5hZ2VyIHdpbGwgaGVscCBzaW5jZSBpdCB3aWxsIHJlcGxhY2UgdGhlCiAgICAqICByZW5kZXJUYXJnZXQgPSBzd2FwY2hhaW4tPmJhY2tCdWZmZXIgYml0IGFuZCBhbnl0aGluZyB0byBkbyB3aXRoICpnbENvbnRleHRzCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIGlmIChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKFJlbmRlclN1cmZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwY2hhaW4pID09IFdJTkVEM0RfT0spIHsKICAgICAgICAvKiBXZSBhbHNvIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIGxpZ2h0cyAmY28gYXJlIGFsc28gaW4gdGhlIGNvbnRleHQgb2YgdGhlIHN3YXBjaGFpbnMgKi8KICAgICAgICAvKiBGSVhNRTogSWYgdGhlIHJlbmRlciB0YXJnZXQgZ2V0cyBzZW50IHRvIHRoZSBmcm9udEJ1ZmZlciBzaG91bGQgYmUgYmUgcHJlc2VudGluZyBpdCByYXc/ICovCiAgICAgICAgVFJBQ0UoIm1ha2luZyBzd2FwY2hhaW4gYWN0aXZlXG4iKTsKICAgICAgICBpZiAoUmVuZGVyU3VyZmFjZSAhPSBUaGlzLT5yZW5kZXJUYXJnZXQpIHsKICAgICAgICAgICAgaWYgKFJlbmRlclN1cmZhY2UgPT0gIHN3YXBjaGFpbi0+YmFja0J1ZmZlcikgewogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyogVGhpcyBjb3VsZCBiZSBmbGFnZ2VkIHNvIHRoYXQgc29tZSBvcGVyYXRpb25zIHdvcmsgZGlyZWN0bHkgd2l0aCB0aGUgZnJvbnQgYnVmZmVyICovCiAgICAgICAgICAgICAgICBGSVhNRSgiQXR0ZW1wdGluZyB0byBzZXQgdGhlICByZW5kZXJUYXJnZXQgdG8gdGhlIGZyb250QnVmZmVyXG4iKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZ2xYTWFrZUN1cnJlbnQoc3dhcGNoYWluLT5kaXNwbGF5LCBzd2FwY2hhaW4tPndpbiwgc3dhcGNoYWluLT5nbEN0eCkKICAgICAgICAgICAgPT0gRmFsc2UpIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJFcnJvciBpbiBzZXR0aW5nIGN1cnJlbnQgY29udGV4dDogY29udGV4dCAlcCBkcmF3YWJsZSAlbGQgIVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBpbXBTd2FwQ2hhaW4tPmdsQ3R4LCBpbXBTd2FwQ2hhaW4tPndpbik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9DbGVhblJlbmRlcihpZmFjZSwgKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKWN1cnJlbnRTd2FwY2hhaW4pOwogICAgICAgIH0KICAgICAgICBjaGVja0dMY2FsbCgiZ2xYTWFrZUNvbnRleHRDdXJyZW50Iik7CgogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopc3dhcGNoYWluKTsKICAgIH0KICAgIGVsc2UgaWYgKHBidWZmZXJfc3VwcG9ydCA9PSBUUlVFICYmIGNmZ3MgIT0gTlVMTCAvKiAmJiBzb21lIHRlc3QgdG8gbWFrZSBzdXJlIHRoYXQgb3BlbmdsIHN1cHBvcnRzIHBidWZmZXJzICovKSB7CgogICAgICAgIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICAgICAgICogVGhpcyBpcyBhIHF1aWNrbHkgaGFja2VkIG91dCBpbXBsZW1lbnRhdGlvbiBvZiBvZmZzY3JlZW4gdGV4dHVyZXMuCiAgICAgICAgKiBJdCB3aWxsIHdvcmsgaW4gbW9zdCBjYXNlcyBidXQgdGhlcmUgbWF5IGJlIHByb2JsZW1zIGlmIHRoZSBjbGllbnQKICAgICAgICAqIG1vZGlmaWVzIHRoZSB0ZXh0dXJlIGRpcmVjdGx5LCBvciBleHBlY3RzIHRoZSBjb250ZW50cyBvZiB0aGUgcmVuZGVydGFyZ2V0CiAgICAgICAgKiB0byBiZSBwZXJzaXN0ZW50LgogICAgICAgICoKICAgICAgICAqIFRoZXJlIGFyZSBzb21lIHJlYWwgc3BlZWQgdnMgY29tcGF0aWJpbGl0eSBpc3N1ZXMgaGVyZToKICAgICAgICAqICAgIHdlIHNob3VsZCByZWFsbHkgdXNlIGEgbmV3IGNvbnRleHQgZm9yIGV2ZXJ5IHRleHR1cmUsIGJ1dCB0aGF0IGVhdHMgcmFtLgogICAgICAgICogICAgd2Ugc2hvdWxkIGFsc28gYmUgcmVzdG9yaW5nIHRoZSB0ZXh0dXJlIHRvIHRoZSBwYnVmZmVyIGJ1dCB0aGF0IGVhdHMgQ1BVCiAgICAgICAgKiAgICB3ZSBjYW4gYWxzbyAncmV1c2UnIHRoZSBjdXJyZW50IHBidWZmZXIgaWYgdGhlIHNpemUgaXMgbGFyZ2VyIHRoYW4gdGhlIHJlcXVlc3RlZCBidWZmZXIsCiAgICAgICAgKiAgICBidXQgaWYgdGhpcyBtZWFucyByZXVzaW5nIHRoZSBkaXNwbGF5IGJhY2tidWZmZXIgdGhlbiB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0CiAgICAgICAgKiAgICBzdGF0ZXMgYXJlIGNvcnJlY3RseSBwcmVzZXJ2ZWQuCiAgICAgICAgKiBJbiBtYW55IGNhc2VzIEkgd291bGQgZXhwZWN0IHRoYXQgd2UgY2FuICdza2lwJyBzb21lIGZ1bmN0aW9ucywgc3VjaCBhcyBwcmVzZXJ2aW5nIHN0YXRlcywKICAgICAgICAqIGFuZCBnYWluIGEgZ29vZCBwZXJmb3JtYW5jZSBpbmNyZWFzZSBhdCB0aGUgY29zdCBvZiBjb21wYXRpYmlsaXR5LgogICAgICAgICogSSB3b3VsZCBzdWdnZXN0IHRoYXQsIHdoZW4gdGhpcyBpcyB0aGUgY2FzZSwgYSB1c2VyIGNvbmZpZ3VyYWJsZSBmbGFnIGJlIG1hZGUKICAgICAgICAqIGF2YWlsYWJsZSwgYWxsb3dpbmcgdGhlIHVzZXIgdG8gY2hvb3NlIHRoZSBiZXN0IGVtdWxhdGVkIGV4cGVyaWVuY2UgZm9yIHRoZW0uCiAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAgICAgWFZpc3VhbEluZm8gKnZpc2luZm87CiAgICAgICAgZ2xDb250ZXh0ICAgKm5ld0NvbnRleHQ7CgogICAgICAgIC8qIEhlcmUgd2VyZSB1c2luZyBhIHNoYXJlZCBjb250ZXh0IG1vZGVsICovCiAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gSVdpbmVEM0REZXZpY2VJbXBsX0ZpbmRHTENvbnRleHQoaWZhY2UsIFJlbmRlclN1cmZhY2UsICZuZXdDb250ZXh0KSkgewogICAgICAgICAgICBGSVhNRSgiKCVwKSA6IEZhaWxlZCB0byBmaW5kIGEgY29udGV4dCBmb3Igc3VyZmFjZSAlcFxuIiwgaWZhY2UsIFJlbmRlclN1cmZhY2UpOwogICAgICAgIH0KCiAgICAgICAgLyogSWYgdGhlIGNvbnRleHQgZG9lc24ndCBleGlzdCB0aGVuIGNyZWF0ZSBhIG5ldyBvbmUgKi8KICAgICAgICAvKiBUT0RPOiBUaGlzIHNob3VsZCByZWFsbHkgYmUgcGFydCBvZiBmaW5kR2xDb250ZXh0ICovCiAgICAgICAgaWYgKE5VTEwgPT0gbmV3Q29udGV4dC0+Y29udGV4dCkgewoKICAgICAgICAgICAgVFJBQ0UoIm1ha2luZyBuZXcgYnVmZmVyXG4iKTsKICAgICAgICAgICAgbkF0dHJpYnMgPSAwOwogICAgICAgICAgICBQVVNIMihHTFhfUEJVRkZFUl9XSURUSCwgIG5ld0NvbnRleHQtPldpZHRoKTsKICAgICAgICAgICAgUFVTSDIoR0xYX1BCVUZGRVJfSEVJR0hULCBuZXdDb250ZXh0LT5IZWlnaHQpOwogICAgICAgICAgICBQVVNIMShOb25lKTsKCiAgICAgICAgICAgIG5ld0NvbnRleHQtPmRyYXdhYmxlICA9IGdsWENyZWF0ZVBidWZmZXIoaW1wU3dhcENoYWluLT5kaXNwbGF5LCBjZmdzWzBdLCBhdHRyaWJzKTsKCiAgICAgICAgICAgIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgICAgICAgICpHTFgxLjMgaXNuJ3Qgc3VwcG9ydGVkIGJ5IFhGcmVlICd5ZXQnIHVudGlsIHRoYXQgcG9pbnQgQVRJIGVtdWxhdGVzIHBCdWZmZXJzCiAgICAgICAgICAgICp0aGV5IG5vdGU6CiAgICAgICAgICAgICogICBJbiBmdXR1cmUgcmVsZWFzZXMsIHdlIG1heSBwcm92aWRlIHRoZSBjYWxscyBnbFhDcmVhdGVOZXdDb250ZXh0LAogICAgICAgICAgICAqICAgZ2xYUXVlcnlEcmF3YWJsZSBhbmQgZ2xYTWFrZUNvbnRleHRDdXJyZW50LgogICAgICAgICAgICAqICAgIHNvIHVudGlsIHRoZW4gd2UgaGF2ZSB0byB1c2UgZ2xYR2V0VmlzdWFsRnJvbUZCQ29uZmlnICZjby4uCiAgICAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCiAgICAgICAgICAgIHZpc2luZm8gPSBnbFhHZXRWaXN1YWxGcm9tRkJDb25maWcoaW1wU3dhcENoYWluLT5kaXNwbGF5LCBjZmdzWzBdKTsKICAgICAgICAgICAgaWYgKCF2aXNpbmZvKSB7CiAgICAgICAgICAgICAgICBFUlIoIkVycm9yOiBjb3VsZG4ndCBnZXQgYW4gUkdCQSwgZG91YmxlLWJ1ZmZlcmVkIHZpc3VhbFxuIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBuZXdDb250ZXh0LT5jb250ZXh0ID0gZ2xYQ3JlYXRlQ29udGV4dChpbXBTd2FwQ2hhaW4tPmRpc3BsYXksIHZpc2luZm8sIGltcFN3YXBDaGFpbi0+Z2xDdHgsICBHTF9UUlVFKTsKICAgICAgICAgICAgICAgIFhGcmVlKHZpc2luZm8pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChOVUxMID09IG5ld0NvbnRleHQgfHwgTlVMTCA9PSBuZXdDb250ZXh0LT5jb250ZXh0KSB7CiAgICAgICAgICAgIEVSUigiKCVwKSA6IEZhaWxlZCB0byBmaW5kIGEgY29udGV4dCBmb3Igc3VyZmFjZSAlcFxuIiwgaWZhY2UsIFJlbmRlclN1cmZhY2UpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIERlYnVnIGxvZ2dpbmcsICh0aGlzIGZ1bmN0aW9uIGxlYWtzKSwgY2hhbmdlIHRvIGEgVFJBQ0Ugd2hlbiB0aGUgbGVhayBpcyBwbHVnZ2VkICovCiAgICAgICAgICAgIGlmIChnbFhNYWtlQ3VycmVudChpbXBTd2FwQ2hhaW4tPmRpc3BsYXksIG5ld0NvbnRleHQtPmRyYXdhYmxlLCBuZXdDb250ZXh0LT5jb250ZXh0KSA9PSBGYWxzZSkgewogICAgICAgICAgICAgICAgVFJBQ0UoIkVycm9yIGluIHNldHRpbmcgY3VycmVudCBjb250ZXh0OiBjb250ZXh0ICVwIGRyYXdhYmxlICVsZFxuIiwgbmV3Q29udGV4dC0+Y29udGV4dCwgbmV3Q29udGV4dC0+ZHJhd2FibGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBDbGVhbiB1cCB0aGUgb2xkIGNvbnRleHQgKi8KICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX0NsZWFuUmVuZGVyKGlmYWNlLCAoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopY3VycmVudFN3YXBjaGFpbik7CiAgICAgICAgICAgIC8qIFNldCB0aGUgY3VycmVudCBjb250ZXh0IG9mIHRoZSBzd2FwY2hhaW4gdG8gdGhlIG5ldyBjb250ZXh0ICovCiAgICAgICAgICAgIGltcFN3YXBDaGFpbi0+ZHJhd2FibGUgICA9IG5ld0NvbnRleHQtPmRyYXdhYmxlOwogICAgICAgICAgICBpbXBTd2FwQ2hhaW4tPnJlbmRlcl9jdHggPSBuZXdDb250ZXh0LT5jb250ZXh0OwogICAgICAgIH0KICAgIH0KCiNpZiAxIC8qIEFwcGx5IHRoZSBzdGF0ZWJsb2NrIHRvIHRoZSBuZXcgY29udGV4dApGSVhNRTogVGhpcyBpcyBhIGJpdCBvZiBhIGhhY2ssIGVhY2ggY29udGV4dCBzaG91bGQga25vdyBpdCdzIG93biBzdGF0ZSwKdGhlIGRpcmVjdFggY3VycmVudCBkaXJlY3RYIHN0YXRlIHNob3VsZCB0aGVuIGJlIGFwcGxpZWQgdG8gdGhlIGNvbnRleHQgKi8KICAgIHsKICAgICAgICBCT09MIG9sZFJlY29yZGluZzsKICAgICAgICBJV2luZUQzRFN0YXRlQmxvY2tJbXBsICpvbGRVcGRhdGVTdGF0ZUJsb2NrOwogICAgICAgIG9sZFVwZGF0ZVN0YXRlQmxvY2sgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrOwogICAgICAgIG9sZFJlY29yZGluZz0gVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZTsKICAgICAgICBUaGlzLT5pc1JlY29yZGluZ1N0YXRlID0gRkFMU0U7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jayA9IFRoaXMtPnN0YXRlQmxvY2s7CiAgICAgICAgSVdpbmVEM0RTdGF0ZUJsb2NrX0FwcGx5KChJV2luZUQzRFN0YXRlQmxvY2sgKilUaGlzLT5zdGF0ZUJsb2NrKTsKCiAgICAgICAgVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSA9IG9sZFJlY29yZGluZzsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrID0gb2xkVXBkYXRlU3RhdGVCbG9jazsKICAgIH0KI2VuZGlmCgoKICAgIC8qIGNsZWFuIHVwIHRoZSBjdXJyZW50IHJlbmRlcnRhcmdldHMgc3dhcGNoYWluIChpZiBpdCBiZWxvbmdlZCB0byBvbmUpICovCiAgICBpZiAoY3VycmVudFN3YXBjaGFpbiAhPSBOVUxMKSB7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKiljdXJyZW50U3dhcGNoYWluKTsKICAgIH0KCiAgICAvKiBXZXJlIGRvbmUgd2l0aCB0aGUgb3BlbmdsIGNvbnRleHQgbWFuYWdlbWVudCwgc2V0dXAgdGhlIHJlbmRlcnRhcmdldHMgKi8KCiAgICB0bXAgPSBUaGlzLT5yZW5kZXJUYXJnZXQ7CiAgICBUaGlzLT5yZW5kZXJUYXJnZXQgPSBSZW5kZXJTdXJmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZihUaGlzLT5yZW5kZXJUYXJnZXQpOwogICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UodG1wKTsKCgoKICAgIHsKICAgICAgICBEV09SRCB2YWx1ZTsKICAgICAgICAvKiBUaGUgc3VyZmFjZSBtdXN0IGJlIHJlbmRlcmVkIHVwc2lkZSBkb3duIHRvIGNhbmNlbCB0aGUgZmxpcCBwcm9kdWNlIGJ5IGdsQ29weVRleEltYWdlICovCiAgICAgICAgLyogQ2hlY2sgdGhhdCB0aGUgY29udGFpbmVyIGlzIG5vdCBhIHN3YXBjaGFpbiBtZW1iZXIgKi8KCiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnRtcFN3YXBDaGFpbjsKICAgICAgICBpZiAoV0lORUQzRF9PSyAhPSBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKFRoaXMtPnJlbmRlclRhcmdldCwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnRtcFN3YXBDaGFpbikpIHsKICAgICAgICAgICAgVGhpcy0+cmVuZGVyVXBzaWRlRG93biA9IFRSVUU7CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIFRoaXMtPnJlbmRlclVwc2lkZURvd24gPSBGQUxTRTsKICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSh0bXBTd2FwQ2hhaW4pOwogICAgICAgIH0KICAgICAgICAvKiBGb3JjZSB1cGRhdGluZyB0aGUgY3VsbCBtb2RlICovCiAgICAgICAgVFJBQ0UoInNldHRpbmcgcmVuZGVyIHN0YXRlXG4iKTsKICAgICAgICBJV2luZUQzRERldmljZV9HZXRSZW5kZXJTdGF0ZShpZmFjZSwgV0lORUQzRFJTX0NVTExNT0RFLCAmdmFsdWUpOwogICAgICAgIElXaW5lRDNERGV2aWNlX1NldFJlbmRlclN0YXRlKGlmYWNlLCBXSU5FRDNEUlNfQ1VMTE1PREUsIHZhbHVlKTsKCiAgICAgICAgLyogRm9yY2UgdXBkYXRpbmcgcHJvamVjdGlvbiBtYXRyaXggKi8KICAgICAgICBUaGlzLT5sYXN0X3dhc19yaHcgPSBGQUxTRTsKICAgICAgICBUaGlzLT5wcm9qX3ZhbGlkID0gRkFMU0U7CiAgICB9CgogICAgcmV0ID0gV0lORUQzRF9PSzsKCiAgICBpZiAoY2ZncyAhPSBOVUxMKSB7CiAgICAgICAgWEZyZWUoY2Zncyk7CiAgICB9IGVsc2UgewogICAgICAgIEVSUigiY2Fubm90IGdldCB2YWxpZGVzIEdMWEZCQ29uZmlnIGZvciAoJXUsJXMpLygldSwlcylcbiIsIEJhY2tCdWZmZXJGb3JtYXQsCiAgICAgICAgICAgIGRlYnVnX2QzZGZvcm1hdChCYWNrQnVmZmVyRm9ybWF0KSwgU3RlbmNpbEJ1ZmZlckZvcm1hdCwgZGVidWdfZDNkZm9ybWF0KFN0ZW5jaWxCdWZmZXJGb3JtYXQpKTsKICAgIH0KCiN1bmRlZiBQVVNIMQojdW5kZWYgUFVTSDIKICAgIGlmICggTlVMTCAhPSBpbXBTd2FwQ2hhaW4pIHsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKWltcFN3YXBDaGFpbik7CiAgICB9CiAgICBMRUFWRV9HTCgpOwoKI2VuZGlmCiAgICByZXR1cm4gcmV0Owp9CgpIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDdXJzb3JQcm9wZXJ0aWVzKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgVUlOVCBYSG90U3BvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFlIb3RTcG90LCBJV2luZUQzRFN1cmZhY2UgKnBDdXJzb3JCaXRtYXApIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICAvKiBUT0RPOiB0aGUgdXNlIG9mIEltcGwgaXMgZGVwcmVjYXRlZC4gKi8KICAgIC8qIHNvbWUgYmFzaWMgdmFsaWRhdGlvbiBjaGVja3MgKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKiBwU3VyID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgcEN1cnNvckJpdG1hcDsKCiAgICBUUkFDRSgiKCVwKSA6IFNwb3QgUG9zKCV1LCV1KVxuIiwgVGhpcywgWEhvdFNwb3QsIFlIb3RTcG90KTsKCiAgICBpZiAoV0lORUQzREZNVF9BOFI4RzhCOCAhPSBwU3VyLT5yZXNvdXJjZS5mb3JtYXQpIHsKICAgICAgRVJSKCIoJXApIDogc3VyZmFjZSglcCkgaGFzIGFuIGludmFsaWQgZm9ybWF0XG4iLCBUaGlzLCBwQ3Vyc29yQml0bWFwKTsKICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBpZiAoMzIgIT0gcFN1ci0+Y3VycmVudERlc2MuSGVpZ2h0IHx8IDMyICE9IHBTdXItPmN1cnJlbnREZXNjLldpZHRoKSB7CiAgICAgIEVSUigiKCVwKSA6IHN1cmZhY2UoJXApIGhhcyBhbiBpbnZhbGlkIHNpemVcbiIsIFRoaXMsIHBDdXJzb3JCaXRtYXApOwogICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIC8qIFRPRE86IG1ha2UgdGhlIGN1cnNvciAncmVhbCcgKi8KCiAgICBUaGlzLT54SG90U3BvdCA9IFhIb3RTcG90OwogICAgVGhpcy0+eUhvdFNwb3QgPSBZSG90U3BvdDsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKdm9pZCAgICAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0Q3Vyc29yUG9zaXRpb24oSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBpbnQgWFNjcmVlblNwYWNlLCBpbnQgWVNjcmVlblNwYWNlLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogU2V0UG9zIHRvICgldSwldSlcbiIsIFRoaXMsIFhTY3JlZW5TcGFjZSwgWVNjcmVlblNwYWNlKTsKCiAgICBUaGlzLT54U2NyZWVuU3BhY2UgPSBYU2NyZWVuU3BhY2U7CiAgICBUaGlzLT55U2NyZWVuU3BhY2UgPSBZU2NyZWVuU3BhY2U7CgogICAgcmV0dXJuOwoKfQoKQk9PTCAgICAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2hvd0N1cnNvcihJV2luZUQzRERldmljZSogaWZhY2UsIEJPT0wgYlNob3cpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IHZpc2libGUoJWQpXG4iLCBUaGlzLCBiU2hvdyk7CgogICAgVGhpcy0+YkN1cnNvclZpc2libGUgPSBiU2hvdzsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfVGVzdENvb3BlcmF0aXZlTGV2ZWwoSVdpbmVEM0REZXZpY2UqIGlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBzdGF0ZSAoJWx1KVxuIiwgVGhpcywgVGhpcy0+c3RhdGUpOwogICAgLyogVE9ETzogSW1wbGVtZW50IHdyYXBwaW5nIG9mIHRoZSBXbmRQcm9jIHNvIHRoYXQgbWltaW1pemUgYW5kIG1heGFtaXNlIGNhbiBiZSBtb25pdG9yZWQgYW5kIHRoZSBzdGF0ZXMgYWRqdXN0ZWQuICovCiAgICBzd2l0Y2ggKFRoaXMtPnN0YXRlKSB7CiAgICBjYXNlIFdJTkVEM0RfT0s6CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICBjYXNlIFdJTkVEM0RFUlJfREVWSUNFTE9TVDoKICAgICAgICB7CiAgICAgICAgICAgIFJlc291cmNlTGlzdCAqcmVzb3VyY2VMaXN0ICA9IFRoaXMtPnJlc291cmNlczsKICAgICAgICAgICAgd2hpbGUgKE5VTEwgIT0gcmVzb3VyY2VMaXN0KSB7CiAgICAgICAgICAgICAgICBpZiAoKChJV2luZUQzRFJlc291cmNlSW1wbCAqKXJlc291cmNlTGlzdC0+cmVzb3VyY2UpLT5yZXNvdXJjZS5wb29sID09IFdJTkVEM0RQT09MX0RFRkFVTFQgLyogVE9ETzogSVdpbmVEM0RSZXNvdXJjZV9HZXRQb29sKHJlc291cmNlTGlzdC0+cmVzb3VyY2UpKi8pCiAgICAgICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9ERVZJQ0VOT1RSRVNFVDsKICAgICAgICAgICAgICAgIHJlc291cmNlTGlzdCA9IHJlc291cmNlTGlzdC0+bmV4dDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9ERVZJQ0VMT1NUOwogICAgICAgIH0KICAgIGNhc2UgV0lORUQzREVSUl9EUklWRVJJTlRFUk5BTEVSUk9SOgogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0RSSVZFUklOVEVSTkFMRVJST1I7CiAgICB9CgogICAgLyogVW5rbm93biBzdGF0ZSAqLwogICAgcmV0dXJuIFdJTkVEM0RFUlJfRFJJVkVSSU5URVJOQUxFUlJPUjsKfQoKCkhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0V2aWN0TWFuYWdlZFJlc291cmNlcyhJV2luZUQzRERldmljZSogaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICAvKiogRklYTUU6IFJlc291cmNlIHRyYWNraW5nIG5lZWRzIHRvIGJlIGRvbmUsCiAgICAqIFRoZSBjbG9zZXMgd2UgY2FuIGRvIHRvIHRoaXMgaXMgc2V0IHRoZSBwcmlvcml0aWVzIG9mIGFsbCBtYW5hZ2VkIHRleHR1cmVzIGxvdwogICAgKiBhbmQgdGhlbiByZXNldCB0aGVtLgogICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUmVzZXQoSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiBwUHJlc2VudGF0aW9uUGFyYW1ldGVycykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIC8qKiBGSVhNRTogUmVzb3VyY2UgdHJhc2NraW5nIG5lZWRzIHRvIGJlIGRvbmUuCiAgICAqIGluIGVmZmVjdCB0aGlzIHB1bGxzIGFsbCBub24gb25seSBkZWZhdWx0CiAgICAqIHRleHR1cmVzIG91dCBvZiB2aWRlbyBtZW1vcnkgYW5kIGRlbGV0ZXMgYWxsIGdsVGV4dHVyZXMgKGdsRGVsZXRlVGV4dHVyZXMpCiAgICAqIGFuZCBzaG91bGQgY2xlYXIgZG93biB0aGUgY29udGV4dCBhbmQgc2V0IGl0IHVwIGFjY29yZGluZyB0byBwUHJlc2VudGF0aW9uUGFyYW1ldGVycwogICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0RGlhbG9nQm94TW9kZShJV2luZUQzRERldmljZSAqaWZhY2UsIEJPT0wgYkVuYWJsZURpYWxvZ3MpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIC8qKiBGSVhNRTogYWx3YXlzIHRydWUgYXQgdGhlIG1vbWVudCAqKi8KICAgIGlmKGJFbmFibGVEaWFsb2dzID09IEZBTFNFKSB7CiAgICAgICAgRklYTUUoIiglcCkgRGlhbG9ncyBjYW5ub3QgYmUgZGlzYWJsZWQgeWV0XG4iLCBUaGlzKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgoKSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0Q3JlYXRpb25QYXJhbWV0ZXJzKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRERFVklDRV9DUkVBVElPTl9QQVJBTUVURVJTICpwUGFyYW1ldGVycykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogcFBhcmFtZXRlcnMgJXBcbiIsIFRoaXMsIHBQYXJhbWV0ZXJzKTsKCiAgICAqcFBhcmFtZXRlcnMgPSBUaGlzLT5jcmVhdGVQYXJtczsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9Cgp2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0R2FtbWFSYW1wKElXaW5lRDNERGV2aWNlICogaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgRFdPUkQgRmxhZ3MsIENPTlNUIFdJTkVEM0RHQU1NQVJBTVAqIHBSYW1wKSB7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluOwogICAgSFJFU1VMVCBocmMgPSBXSU5FRDNEX09LOwoKICAgIFRSQUNFKCJSZWxheWluZyAgdG8gc3dhcGNoYWluXG4iKTsKCiAgICBpZiAoKGhyYyA9IElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4oaWZhY2UsIGlTd2FwQ2hhaW4sICZzd2FwY2hhaW4pKSA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fU2V0R2FtbWFSYW1wKHN3YXBjaGFpbiwgRmxhZ3MsIChXSU5FRDNER0FNTUFSQU1QICopcFJhbXApOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcGNoYWluKTsKICAgIH0KICAgIHJldHVybjsKfQoKdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldEdhbW1hUmFtcChJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgV0lORUQzREdBTU1BUkFNUCogcFJhbXApIHsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwY2hhaW47CiAgICBIUkVTVUxUIGhyYyA9IFdJTkVEM0RfT0s7CgogICAgVFJBQ0UoIlJlbGF5aW5nICB0byBzd2FwY2hhaW5cbiIpOwoKICAgIGlmICgoaHJjID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgaVN3YXBDaGFpbiwgJnN3YXBjaGFpbikpID09IFdJTkVEM0RfT0spIHsKICAgICAgICBocmMgPUlXaW5lRDNEU3dhcENoYWluX0dldEdhbW1hUmFtcChzd2FwY2hhaW4sIHBSYW1wKTsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBjaGFpbik7CiAgICB9CiAgICByZXR1cm47Cn0KCgovKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiAgIE5vdGlmaWNhdGlvbiBmdW5jdGlvbnMKKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKiBUaGlzIGZ1bmN0aW9uIG11c3QgYmUgY2FsbGVkIGluIHRoZSByZWxlYXNlIG9mIGEgcmVzb3VyY2Ugd2hlbiByZWYgPT0gMCwKKiB0aGUgY29udGVudHMgb2YgcmVzb3VyY2UgbXVzdCBzdGlsbCBiZSBjb3JyZWN0LAoqIGFueSBoYW5kZWxzIHRvIG90aGVyIHJlc291cmNlIGhlbGQgYnkgdGhlIGNhbGxlciBtdXN0IGJlIGNsb3NlZAoqIChlLmcuIGEgdGV4dHVyZSBzaG91bGQgcmVsZWFzZSBhbGwgaGVsZCBzdXJmYWNlcyBiZWNhdXNlIHRlbGxpbmcgdGhlIGRldmljZSB0aGF0IGl0J3MgYmVlbiByZWxlYXNlZC4pCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9BZGRSZXNvdXJjZShJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEUmVzb3VyY2UgKnJlc291cmNlKXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFJlc291cmNlTGlzdCogcmVzb3VyY2VMaXN0OwoKICAgIFRSQUNFKCIoJXApIDogcmVzb3VyY2UgJXBcbiIsIFRoaXMsIHJlc291cmNlKTsKI2lmIDAKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZyZXNvdXJjZVN0b3JlQ3JpdGljYWxTZWN0aW9uKTsKI2VuZGlmCiAgICAvKiBhZGQgYSBuZXcgdGV4dHVyZSB0byB0aGUgZnJvdCBvZiB0aGUgbGlua2VkIGxpc3QgKi8KICAgIHJlc291cmNlTGlzdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUmVzb3VyY2VMaXN0KSk7CiAgICByZXNvdXJjZUxpc3QtPnJlc291cmNlID0gcmVzb3VyY2U7CgogICAgLyogR2V0IHRoZSBvbGQgaGVhZCAqLwogICAgcmVzb3VyY2VMaXN0LT5uZXh0ID0gVGhpcy0+cmVzb3VyY2VzOwoKICAgIFRoaXMtPnJlc291cmNlcyA9IHJlc291cmNlTGlzdDsKICAgIFRSQUNFKCJBZGRlZCByZXNvdXJjZSAlcCB3aXRoIGVsZW1lbnQgJXAgcG9pbnRpbmcgdG8gJXBcbiIsIHJlc291cmNlLCByZXNvdXJjZUxpc3QsIHJlc291cmNlTGlzdC0+bmV4dCk7CgojaWYgMAogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnJlc291cmNlU3RvcmVDcml0aWNhbFNlY3Rpb24pOwojZW5kaWYKICAgIHJldHVybjsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9SZW1vdmVSZXNvdXJjZShJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEUmVzb3VyY2UgKnJlc291cmNlKXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFJlc291cmNlTGlzdCogcmVzb3VyY2VMaXN0ID0gTlVMTDsKICAgIFJlc291cmNlTGlzdCogcHJldmlvdXNSZXNvdXJjZUxpc3QgPSBOVUxMOwogICAgCiAgICBUUkFDRSgiKCVwKSA6IHJlc291cmNlICVwXG4iLCBUaGlzLCByZXNvdXJjZSk7CgojaWYgMAogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnJlc291cmNlU3RvcmVDcml0aWNhbFNlY3Rpb24pOwojZW5kaWYKICAgIHJlc291cmNlTGlzdCA9IFRoaXMtPnJlc291cmNlczsKCiAgICB3aGlsZSAocmVzb3VyY2VMaXN0ICE9IE5VTEwpIHsKICAgICAgICBpZihyZXNvdXJjZUxpc3QtPnJlc291cmNlID09IHJlc291cmNlKSBicmVhazsKICAgICAgICBwcmV2aW91c1Jlc291cmNlTGlzdCA9IHJlc291cmNlTGlzdDsKICAgICAgICByZXNvdXJjZUxpc3QgPSByZXNvdXJjZUxpc3QtPm5leHQ7CiAgICB9CgogICAgaWYgKHJlc291cmNlTGlzdCA9PSBOVUxMKSB7CiAgICAgICAgRklYTUUoIkF0dGVtcHRlZCB0byByZW1vdmUgcmVzb3VyY2UgJXAgdGhhdCBoYXNuJ3QgYmVlbiBzdG9yZWRcbiIsIHJlc291cmNlKTsKI2lmIDAKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcmVzb3VyY2VTdG9yZUNyaXRpY2FsU2VjdGlvbik7CiNlbmRpZgogICAgICAgIHJldHVybjsKICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRSQUNFKCJGb3VuZCByZXNvdXJjZSAgJXAgd2l0aCBlbGVtZW50ICVwIHBvaW50aW5nIHRvICVwIChwcmV2aW91cyAlcClcbiIsIHJlc291cmNlTGlzdC0+cmVzb3VyY2UsIHJlc291cmNlTGlzdCwgcmVzb3VyY2VMaXN0LT5uZXh0LCBwcmV2aW91c1Jlc291cmNlTGlzdCk7CiAgICB9CiAgICAvKiBtYWtlIHN1cmUgd2UgZG9uJ3QgbGVhdmUgYSBob2xlIGluIHRoZSBsaXN0ICovCiAgICBpZiAocHJldmlvdXNSZXNvdXJjZUxpc3QgIT0gTlVMTCkgewogICAgICAgIHByZXZpb3VzUmVzb3VyY2VMaXN0LT5uZXh0ID0gcmVzb3VyY2VMaXN0LT5uZXh0OwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5yZXNvdXJjZXMgPSByZXNvdXJjZUxpc3QtPm5leHQ7CiAgICB9CgojaWYgMAogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnJlc291cmNlU3RvcmVDcml0aWNhbFNlY3Rpb24pOwojZW5kaWYKICAgIHJldHVybjsKfQoKCnZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9SZXNvdXJjZVJlbGVhc2VkKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RSZXNvdXJjZSAqcmVzb3VyY2UpewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIGludCBjb3VudGVyOwoKICAgIFRSQUNFKCIoJXApIDogcmVzb3VyY2UgJXBcbiIsIFRoaXMsIHJlc291cmNlKTsKICAgIHN3aXRjaChJV2luZUQzRFJlc291cmNlX0dldFR5cGUocmVzb3VyY2UpKXsKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9TVVJGQUNFOgogICAgICAgIC8qIFRPRE86IGNoZWNrIGZyb250IGFuZCBiYWNrIGJ1ZmZlcnMsIHJlbmRlcnRhcmdldHMgZXRjLi4gIHBvc3NpYmx5IHN3YXBjaGFpbnM/ICovCiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVEVYVFVSRToKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9DVUJFVEVYVFVSRToKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9WT0xVTUVURVhUVVJFOgogICAgICAgICAgICAgICAgZm9yIChjb3VudGVyID0gMDsgY291bnRlciA8IEdMX0xJTUlUUyh0ZXh0dXJlcyk7IGNvdW50ZXIrKykgewogICAgICAgICAgICAgICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrICE9IE5VTEwgJiYgVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbY291bnRlcl0gPT0gKElXaW5lRDNEQmFzZVRleHR1cmUgKilyZXNvdXJjZSkgewogICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCJUZXh0dXJlIGJlaW5nIHJlbGVhc2VkIGlzIHN0aWxsIGJ5IGEgc3RhdGVibG9jaywgU3RhZ2UgPSAldSBUZXh0dXJlID0gJXBcbiIsIGNvdW50ZXIsIHJlc291cmNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbY291bnRlcl0gPSBOVUxMOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoVGhpcy0+dXBkYXRlU3RhdGVCbG9jayAhPSBUaGlzLT5zdGF0ZUJsb2NrICl7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tjb3VudGVyXSA9PSAoSVdpbmVEM0RCYXNlVGV4dHVyZSAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCJUZXh0dXJlIGJlaW5nIHJlbGVhc2VkIGlzIHN0aWxsIGJ5IGEgc3RhdGVibG9jaywgU3RhZ2UgPSAldSBUZXh0dXJlID0gJXBcbiIsIGNvdW50ZXIsIHJlc291cmNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW2NvdW50ZXJdID0gTlVMTDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9WT0xVTUU6CiAgICAgICAgLyogVE9ETzogbm90aGluZyByZWFsbHk/ICovCiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVkVSVEVYQlVGRkVSOgogICAgICAgIC8qIE1TRE46IFdoZW4gYW4gYXBwbGljYXRpb24gbm8gbG9uZ2VyIGhvbGRzIGEgcmVmZXJlbmNlcyB0byB0aGlzIGludGVyZmFjZSwgdGhlIGludGVyZmFjZSB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgZnJlZWQuICovCiAgICAgICAgewogICAgICAgICAgICBpbnQgc3RyZWFtTnVtYmVyOwogICAgICAgICAgICBUUkFDRSgiQ2xlYW5pbmcgdXAgc3RyZWFtIHBvaW50ZXJzXG4iKTsKCiAgICAgICAgICAgIGZvcihzdHJlYW1OdW1iZXIgPSAwOyBzdHJlYW1OdW1iZXIgPCBNQVhfU1RSRUFNUzsgc3RyZWFtTnVtYmVyICsrKXsKICAgICAgICAgICAgICAgIC8qIEZJTkRPVVQ6IHNob3VsZCBhIHdhcm4gYmUgZ2VuZXJhdGVkIGlmIHdlcmUgcmVjb3JkaW5nIGFuZCB1cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2UgaXMgbG9zdD8KICAgICAgICAgICAgICAgIEZJTkRPVVQ6IHNob3VsZCBjaGFuZ2VzLnN0cmVhbVNvdXJjZVtTdHJlYW1OdW1iZXJdIGJlIHNldCA/CiAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgIT0gTlVMTCApIHsgLyogPT1OVUxMIHdoZW4gZGV2aWNlIGlzIGJlaW5nIGRlc3Ryb3llZCAqLwogICAgICAgICAgICAgICAgICAgIGlmICgoSVdpbmVEM0RSZXNvdXJjZSAqKVRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzdHJlYW1OdW1iZXJdID09IHJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJWZXJ0ZXggYnVmZmVyIHJlbGVhc2VkIHdobHN0IGJvdW5kIHRvIGEgc3RhdGUgYmxvY2sgIHN0cmVhbSAlZFxuIiwgc3RyZWFtTnVtYmVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3N0cmVhbU51bWJlcl0gPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBTZXQgY2hhbmdlZCBmbGFnPyAqLwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrICE9IE5VTEwgKSB7IC8qIG9ubHkgaGFwcGVucyBpZiB0aGVyZSBpcyBhbiBlcnJvciBpbiB0aGUgYXBwbGljYXRpb24sIG9yIG9uIHJlc2V0L3JlbGVhc2UgKGJlY2F1c2Ugd2UgZG9uJ3QgbWFuYWdlIGludGVybmFsIHRyYWNraW5nIHByb3Blcmx5KSAqLwogICAgICAgICAgICAgICAgICAgIGlmICgoSVdpbmVEM0RSZXNvdXJjZSAqKVRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzdHJlYW1OdW1iZXJdID09IHJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJWZXJ0ZXggYnVmZmVyIHJlbGVhc2VkIHdobHN0IGJvdW5kIHRvIGEgc3RhdGUgYmxvY2sgIHN0cmVhbSAlZFxuIiwgc3RyZWFtTnVtYmVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3N0cmVhbU51bWJlcl0gPSAwOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KI2lmIDAgICAvKiBUT0RPOiBNYW5hZ2UgaW50ZXJuYWwgdHJhY2tpbmcgcHJvcGVybHkgc28gdGhhdCAndGhpcyBzaG91bGRuJ3QgaGFwcGVuJyAqLwogICAgICAgICAgICAgICAgIGVsc2UgeyAvKiBUaGlzIHNob3VsZG4ndCBoYXBwZW4gKi8KICAgICAgICAgICAgICAgICAgICBGSVhNRSgiQ2FsbGluZyBhcHBsaWNhdGlvbiBoYXMgcmVsZWFzZWQgdGhlIGRldmljZSBiZWZvcmUgcmVsYXNpbmcgYWxsIHRoZSByZXNvdXJjZXMgYm91bmQgdG8gdGhlIGRldmljZVxuIik7CiAgICAgICAgICAgICAgICB9CiNlbmRpZgoKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9JTkRFWEJVRkZFUjoKICAgICAgICAvKiBNU0ROOiBXaGVuIGFuIGFwcGxpY2F0aW9uIG5vIGxvbmdlciBob2xkcyBhIHJlZmVyZW5jZXMgdG8gdGhpcyBpbnRlcmZhY2UsIHRoZSBpbnRlcmZhY2Ugd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGZyZWVkLiovCiAgICAgICAgaWYgKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgIT0gTlVMTCApIHsgLyogPT1OVUxMIHdoZW4gZGV2aWNlIGlzIGJlaW5nIGRlc3Ryb3llZCAqLwogICAgICAgICAgICBpZiAoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cEluZGV4RGF0YSA9PSAoSVdpbmVEM0RJbmRleEJ1ZmZlciAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5wSW5kZXhEYXRhID0gIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKFRoaXMtPnN0YXRlQmxvY2sgIT0gTlVMTCApIHsgLyogPT1OVUxMIHdoZW4gZGV2aWNlIGlzIGJlaW5nIGRlc3Ryb3llZCAqLwogICAgICAgICAgICBpZiAoVGhpcy0+c3RhdGVCbG9jay0+cEluZGV4RGF0YSA9PSAoSVdpbmVEM0RJbmRleEJ1ZmZlciAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5wSW5kZXhEYXRhID0gIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIiglcCkgdW5rbm93biByZXNvdXJjZSB0eXBlICVwICV1XG4iLCBUaGlzLCByZXNvdXJjZSwgSVdpbmVEM0RSZXNvdXJjZV9HZXRUeXBlKHJlc291cmNlKSk7CiAgICAgICAgYnJlYWs7CiAgICB9CgoKICAgIC8qIFJlbW92ZSB0aGUgcmVzb3J1Y2UgZnJvbSB0aGUgcmVzb3VyY2VTdG9yZSAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX1JlbW92ZVJlc291cmNlKGlmYWNlLCByZXNvdXJjZSk7CgogICAgVFJBQ0UoIlJlc291cmNlIHJlbGVhc2VkXG4iKTsKCn0KCgovKiogVGhpcyBmdW5jdGlvbiBpcyB0byBiZSBjYWxsZWQgYnkgdGhlIHN3YXBjaGFpbiB3aGVuIGl0IGlzIHJlbGVhc2VkIGFuZCBpdCdzIHJlZiA9IDAKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU3dhcENoYWluUmVsZWFzZWQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluKXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBTd2FwQ2hhaW5MaXN0ICoqbmV4dFN3YXBjaGFpbjsKICAgIG5leHRTd2FwY2hhaW4gPSAmVGhpcy0+c3dhcGNoYWluczsKCiAgICAvKiBDaGVjayB0byBzZWUgaWYgdGhlIHN3YXBjaGlhbiBpcyBiZWluZyB1c2VkIGFzIHRoZSByZW5kZXIgdGFyZ2V0ICovCiAgICBpZiAoVGhpcy0+cmVuZGVyVGFyZ2V0ICE9IE5VTEwpIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2UgKnN3YXBjaGFpbkJhY2tCdWZmZXI7CgogICAgICAgIElXaW5lRDNEU3dhcENoYWluX0dldEJhY2tCdWZmZXIoc3dhcENoYWluLCAwICwoIEQzREJBQ0tCVUZGRVJfVFlQRSkgMCwgJnN3YXBjaGFpbkJhY2tCdWZmZXIpOwogICAgICAgIGlmIChUaGlzLT5yZW5kZXJUYXJnZXQgPT0gc3dhcGNoYWluQmFja0J1ZmZlcikgewogICAgICAgICAgICAvKiBEb24ndCBrbm93IHdoYXQgdG8gZG8sIHNvIHdhcm4gYW5kIGNhcnJ5IG9uIGFzIHVzdWFsICh3aGljaCBpbiB0aGlzIGNhc2UgbGVhdmVzIHRoZSByZW5kZXJ0ZXJnZXQgaW4gbGltYm8pICovCiAgICAgICAgICAgIEZJWE1FKCJBdGVtcHRpbmcgdG8gcmVsZWFzZSBhIHN3YXBjaGFpbiB0aGF0IGlzIGN1cnJlbnRseSBiZXVpbmcgdXNlZCBhcyBhIHJlbmRlciB0YXJnZXQsIGJlaGF2aW91ciBpcyB1bmRlZmluZWRcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBHbyB0aHJvdWdoIHRoZSBzd2FwY2hhaW4gbGlzdCBhbmQgdHJ5IHRvIGZpbmQgdGhlIHN3YXBjaGFpbiBiZWluZyByZWxlYXNlZCAqLwogICAgd2hpbGUoKm5leHRTd2FwY2hhaW4gIT0gTlVMTCAmJiAoKm5leHRTd2FwY2hhaW4pLT5zd2FwY2hhaW4gIT0gc3dhcENoYWluKSB7CiAgICAgICAgbmV4dFN3YXBjaGFpbiA9ICYoKm5leHRTd2FwY2hhaW4pLT5uZXh0OwogICAgfQoKICAgIC8qIENoZWNrIHRvIHNlZSBpZiB3ZSBmb3VuZCB0aGUgc3dhcGNoYWluICovCiAgICBpZiAoTlVMTCAhPSAqbmV4dFN3YXBjaGFpbikgewogICAgICAgIC8qIFdlIGZvdW5kIHRoZSBzd2FwY2hhaW4gc28gcmVtb3ZlIGl0IGZyb20gdGhlIGxpc3QgKi8KICAgICAgICBUUkFDRSgiKCVwKSByZWxlYXNpbmcgc3dhcGNoYWluKCVwKVxuIiwgaWZhY2UsIHN3YXBDaGFpbik7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCAsICpuZXh0U3dhcGNoYWluKTsKICAgICAgICAqbmV4dFN3YXBjaGFpbiA9ICgqbmV4dFN3YXBjaGFpbiktPm5leHQ7CiAgICB9IGVsc2UgewogICAgICAgIC8qIFdlIGRpZG4ndCBmaW5kIHRoZSBzd2FwY2hhaW4gb24gdGhlIGxpc3QsIHRoaXMgY2FuIG9ubHkgaGVwcGVuIGJlY2F1c2Ugb2YgYSBwcm9ncmFtbWluZyBlcnJvciBpbiB3aW5lZDNkICovCiAgICAgICAgRklYTUUoIiglcCkgQXR0ZW1wdGluZyB0byByZWxlYXNlIGEgc3dhcGNoYWluICglcCkgdGhhdCBoYXNuJ3QgYmVlbiBzdG9yZWRcbiIsIGlmYWNlLCBzd2FwQ2hhaW4pOwogICAgfQoKICAgIFRSQUNFKCJzd2FwY2hhaW4gKCVwKSByZWxlYXNlZFxuIiwgc3dhcENoYWluKTsKICAgIHJldHVybjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0REZXZpY2UgVlRibCBmb2xsb3dzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKY29uc3QgSVdpbmVEM0REZXZpY2VWdGJsIElXaW5lRDNERGV2aWNlX1Z0YmwgPQp7CiAgICAvKioqIElVbmtub3duIG1ldGhvZHMgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0FkZFJlZiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9SZWxlYXNlLAogICAgLyoqKiBJV2luZUQzRERldmljZSBtZXRob2RzICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQYXJlbnQsCiAgICAvKioqIENyZWF0aW9uIG1ldGhvZHMqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhCdWZmZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlSW5kZXhCdWZmZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlU3RhdGVCbG9jaywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVTdXJmYWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVm9sdW1lVGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWb2x1bWUsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlQ3ViZVRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUXVlcnksCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhEZWNsYXJhdGlvbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUGl4ZWxTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUGFsZXR0ZSwKICAgIC8qKiogT2RkIGZ1bmN0aW9ucyAqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9Jbml0M0QsCiAgICBJV2luZUQzRERldmljZUltcGxfVW5pbml0M0QsCiAgICBJV2luZUQzRERldmljZUltcGxfRW51bURpc3BsYXlNb2RlcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9FdmljdE1hbmFnZWRSZXNvdXJjZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0QXZhaWxhYmxlVGV4dHVyZU1lbSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRCYWNrQnVmZmVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldENyZWF0aW9uUGFyYW1ldGVycywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXREZXZpY2VDYXBzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldERpcmVjdDNELAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldERpc3BsYXlNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldERpc3BsYXlNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEhXTkQsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0SFdORCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXROdW1iZXJPZlN3YXBDaGFpbnMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UmFzdGVyU3RhdHVzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9SZXNldCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXREaWFsb2dCb3hNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnNvclByb3BlcnRpZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Q3Vyc29yUG9zaXRpb24sCiAgICBJV2luZUQzRERldmljZUltcGxfU2hvd0N1cnNvciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9UZXN0Q29vcGVyYXRpdmVMZXZlbCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9FbnVtWkJ1ZmZlckZvcm1hdHMsCiAgICBJV2luZUQzRERldmljZUltcGxfRW51bVRleHR1cmVGb3JtYXRzLAogICAgLyoqKiBHZXR0ZXJzIGFuZCBzZXR0ZXJzICoqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldENsaXBQbGFuZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDbGlwUGxhbmUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Q2xpcFN0YXR1cywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDbGlwU3RhdHVzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnJlbnRUZXh0dXJlUGFsZXR0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDdXJyZW50VGV4dHVyZVBhbGV0dGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0RGVwdGhTdGVuY2lsU3VyZmFjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXREZXB0aFN0ZW5jaWxTdXJmYWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZWRiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRGVkYsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0R2FtbWFSYW1wLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEdhbW1hUmFtcCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRJbmRpY2VzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEluZGljZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0TGlnaHQsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0TGlnaHQsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0TGlnaHRFbmFibGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0TGlnaHRFbmFibGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0TWF0ZXJpYWwsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0TWF0ZXJpYWwsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0TlBhdGNoTW9kZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXROUGF0Y2hNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBhbGV0dGVFbnRyaWVzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBhbGV0dGVFbnRyaWVzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBpeGVsU2hhZGVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyQ29uc3RhbnQsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50QiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50QiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50SSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50SSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50RiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50RiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50TiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRSZW5kZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSZW5kZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRSZW5kZXJUYXJnZXQsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UmVuZGVyVGFyZ2V0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZyb250QmFja0J1ZmZlcnMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0U2FtcGxlclN0YXRlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFNhbXBsZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTY2lzc29yUmVjdCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTY2lzc29yUmVjdCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTb2Z0d2FyZVZlcnRleFByb2Nlc3NpbmcsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U29mdHdhcmVWZXJ0ZXhQcm9jZXNzaW5nLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFN0cmVhbVNvdXJjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTdHJlYW1Tb3VyY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0U3RyZWFtU291cmNlRnJlcSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTdHJlYW1Tb3VyY2VGcmVxLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUZXh0dXJlU3RhZ2VTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRUZXh0dXJlU3RhZ2VTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUcmFuc2Zvcm0sCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VHJhbnNmb3JtLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleERlY2xhcmF0aW9uLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleERlY2xhcmF0aW9uLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnQsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyQ29uc3RhbnQsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnRCLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50QiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEksCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyQ29uc3RhbnRJLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlckNvbnN0YW50RiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEYsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnROLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZpZXdwb3J0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZpZXdwb3J0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX011bHRpcGx5VHJhbnNmb3JtLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1ZhbGlkYXRlRGV2aWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1Byb2Nlc3NWZXJ0aWNlcywKICAgIC8qKiogU3RhdGUgYmxvY2sgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0JlZ2luU3RhdGVCbG9jaywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9FbmRTdGF0ZUJsb2NrLAogICAgLyoqKiBTY2VuZSBtYW5hZ2VtZW50ICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9CZWdpblNjZW5lLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0VuZFNjZW5lLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1ByZXNlbnQsCiAgICBJV2luZUQzRERldmljZUltcGxfQ2xlYXIsCiAgICAvKioqIERyYXdpbmcgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmUsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd0luZGV4ZWRQcmltaXRpdmUsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd1ByaW1pdGl2ZVVQLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdJbmRleGVkUHJpbWl0aXZlVVAsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd1ByaW1pdGl2ZVN0cmlkZWQsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd1JlY3RQYXRjaCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3VHJpUGF0Y2gsCiAgICBJV2luZUQzRERldmljZUltcGxfRGVsZXRlUGF0Y2gsCiAgICBJV2luZUQzRERldmljZUltcGxfQ29sb3JGaWxsLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1VwZGF0ZVRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfVXBkYXRlU3VyZmFjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9Db3B5UmVjdHMsCiAgICBJV2luZUQzRERldmljZUltcGxfU3RyZXRjaFJlY3QsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UmVuZGVyVGFyZ2V0RGF0YSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRGcm9udEJ1ZmZlckRhdGEsCiAgICAvKioqIEludGVybmFsIHVzZSBJV2luZUQzRERldmljZSBtZXRob2RzICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXR1cFRleHR1cmVTdGF0ZXMsCiAgICAvKioqIG9iamVjdCB0cmFja2luZyAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfU3dhcENoYWluUmVsZWFzZWQsCiAgICBJV2luZUQzRERldmljZUltcGxfUmVzb3VyY2VSZWxlYXNlZAp9OwoKCmNvbnN0IERXT1JEIFNhdmVkUGl4ZWxTdGF0ZXNfUltOVU1fU0FWRURQSVhFTFNUQVRFU19SXSA9IHsKICAgIFdJTkVEM0RSU19BTFBIQUJMRU5ERU5BQkxFICAgLAogICAgV0lORUQzRFJTX0FMUEhBRlVOQyAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfQUxQSEFSRUYgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19BTFBIQVRFU1RFTkFCTEUgICAgLAogICAgV0lORUQzRFJTX0JMRU5ET1AgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfQ09MT1JXUklURUVOQUJMRSAgICwKICAgIFdJTkVEM0RSU19ERVNUQkxFTkQgICAgICAgICAgLAogICAgV0lORUQzRFJTX0RJVEhFUkVOQUJMRSAgICAgICAsCiAgICBXSU5FRDNEUlNfRklMTE1PREUgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dERU5TSVRZICAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR0VORCAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HU1RBUlQgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19MQVNUUElYRUwgICAgICAgICAgLAogICAgV0lORUQzRFJTX1NIQURFTU9ERSAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfU1JDQkxFTkQgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMRU5BQkxFICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxGQUlMICAgICAgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTEZVTkMgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMTUFTSyAgICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxQQVNTICAgICAgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTFJFRiAgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMV1JJVEVNQVNLICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxaRkFJTCAgICAgICAsCiAgICBXSU5FRDNEUlNfVEVYVFVSRUZBQ1RPUiAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQMCAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVAxICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDIgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQMyAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVA0ICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDUgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQNiAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVA3ICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfWkVOQUJMRSAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19aRlVOQyAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1pXUklURUVOQUJMRQp9OwoKY29uc3QgRFdPUkQgU2F2ZWRQaXhlbFN0YXRlc19UW05VTV9TQVZFRFBJWEVMU1RBVEVTX1RdID0gewogICAgV0lORUQzRFRTU19BRERSRVNTVyAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19BTFBIQUFSRzAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19BTFBIQUFSRzEgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19BTFBIQUFSRzIgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19BTFBIQU9QICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTE9GRlNFVCAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTFNDQUxFICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTUFUMDAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTUFUMDEgICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTUFUMTAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTUFUMTEgICAgICAgICAgLAogICAgV0lORUQzRFRTU19DT0xPUkFSRzAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19DT0xPUkFSRzEgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19DT0xPUkFSRzIgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19DT0xPUk9QICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19SRVNVTFRBUkcgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19URVhDT09SRElOREVYICAgICAgICAgLAogICAgV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1MKfTsKCmNvbnN0IERXT1JEIFNhdmVkUGl4ZWxTdGF0ZXNfU1tOVU1fU0FWRURQSVhFTFNUQVRFU19TXSA9IHsKICAgIFdJTkVEM0RTQU1QX0FERFJFU1NVICAgICAgICAgLAogICAgV0lORUQzRFNBTVBfQUREUkVTU1YgICAgICAgICAsCiAgICBXSU5FRDNEU0FNUF9BRERSRVNTVyAgICAgICAgICwKICAgIFdJTkVEM0RTQU1QX0JPUkRFUkNPTE9SICAgICAgLAogICAgV0lORUQzRFNBTVBfTUFHRklMVEVSICAgICAgICAsCiAgICBXSU5FRDNEU0FNUF9NSU5GSUxURVIgICAgICAgICwKICAgIFdJTkVEM0RTQU1QX01JUEZJTFRFUiAgICAgICAgLAogICAgV0lORUQzRFNBTVBfTUlQTUFQTE9EQklBUyAgICAsCiAgICBXSU5FRDNEU0FNUF9NQVhNSVBMRVZFTCAgICAgICwKICAgIFdJTkVEM0RTQU1QX01BWEFOSVNPVFJPUFkgICAgLAogICAgV0lORUQzRFNBTVBfU1JHQlRFWFRVUkUgICAgICAsCiAgICBXSU5FRDNEU0FNUF9FTEVNRU5USU5ERVgKfTsKCmNvbnN0IERXT1JEIFNhdmVkVmVydGV4U3RhdGVzX1JbTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1JdID0gewogICAgV0lORUQzRFJTX0FNQklFTlQgICAgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19BTUJJRU5UTUFURVJJQUxTT1VSQ0UgICAgICAgICAsCiAgICBXSU5FRDNEUlNfQ0xJUFBJTkcgICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0NMSVBQTEFORUVOQUJMRSAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19DT0xPUlZFUlRFWCAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRElGRlVTRU1BVEVSSUFMU09VUkNFICAgICAgICAgLAogICAgV0lORUQzRFJTX0VNSVNTSVZFTUFURVJJQUxTT1VSQ0UgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dERU5TSVRZICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HRU5EICAgICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR1NUQVJUICAgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dUQUJMRU1PREUgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HVkVSVEVYTU9ERSAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0lOREVYRURWRVJURVhCTEVOREVOQUJMRSAgICAgICwKICAgIFdJTkVEM0RSU19MSUdIVElORyAgICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfTE9DQUxWSUVXRVIgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX01VTFRJU0FNUExFQU5USUFMSUFTICAgICAgICAgICwKICAgIFdJTkVEM0RSU19NVUxUSVNBTVBMRU1BU0sgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfTk9STUFMSVpFTk9STUFMUyAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BBVENIRURHRVNUWUxFICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNDQUxFX0EgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTQ0FMRV9CICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0NBTEVfQyAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNDQUxFRU5BQkxFICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTSVpFICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0laRV9NQVggICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNJWkVfTUlOICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTUFJJVEVFTkFCTEUgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1JBTkdFRk9HRU5BQkxFICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19TUEVDVUxBUk1BVEVSSUFMU09VUkNFICAgICAgICAsCiAgICBXSU5FRDNEUlNfVFdFRU5GQUNUT1IgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1ZFUlRFWEJMRU5ECn07Cgpjb25zdCBEV09SRCBTYXZlZFZlcnRleFN0YXRlc19UW05VTV9TQVZFRFZFUlRFWFNUQVRFU19UXSA9IHsKICAgIFdJTkVEM0RUU1NfVEVYQ09PUkRJTkRFWCAgICAgICAgICwKICAgIFdJTkVEM0RUU1NfVEVYVFVSRVRSQU5TRk9STUZMQUdTCn07Cgpjb25zdCBEV09SRCBTYXZlZFZlcnRleFN0YXRlc19TW05VTV9TQVZFRFZFUlRFWFNUQVRFU19TXSA9IHsKICAgIFdJTkVEM0RTQU1QX0RNQVBPRkZTRVQKfTsK