LyoKICogRGlyZWN0UGxheTggVGhyZWFkUG9vbAogKgogKiBDb3B5cmlnaHQgMjAwNCBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwOCBBbGV4YW5kZXIgTi4gU/hybmVzIDxhbGV4QHRoZWhhbmRvZmFnb255LmNvbT4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgImRwbGF5OC5oIgojaW5jbHVkZSAiZHBuZXRfcHJpdmF0ZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZHBuZXQpOwoKLyogSVVua25vd24gaW50ZXJmYWNlIGZvbGxvd3MgKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0UGxheThUaHJlYWRQb29sSW1wbF9RdWVyeUludGVyZmFjZShQRElSRUNUUExBWThUSFJFQURQT09MIGlmYWNlLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcG9iaikKewogICAgSURpcmVjdFBsYXk4VGhyZWFkUG9vbEltcGwgKlRoaXMgPSAoSURpcmVjdFBsYXk4VGhyZWFkUG9vbEltcGwqKWlmYWNlOwoKICAgIGlmKElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVVua25vd24pIHx8CiAgICAgICBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lEaXJlY3RQbGF5OFRocmVhZFBvb2wpKQogICAgewogICAgICAgIElVbmtub3duX0FkZFJlZihpZmFjZSk7CiAgICAgICAgKnBwb2JqID0gVGhpczsKICAgICAgICByZXR1cm4gRFBOX09LOwogICAgfQoKICAgIFdBUk4oIiglcCktPiglcywlcCk6IG5vdCBmb3VuZFxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHBvYmopOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURpcmVjdFBsYXk4VGhyZWFkUG9vbEltcGxfQWRkUmVmKFBESVJFQ1RQTEFZOFRIUkVBRFBPT0wgaWZhY2UpCnsKICAgIElEaXJlY3RQbGF5OFRocmVhZFBvb2xJbXBsKiBUaGlzID0gKElEaXJlY3RQbGF5OFRocmVhZFBvb2xJbXBsKilpZmFjZTsKICAgIFVMT05HIFJlZkNvdW50ID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgcmV0dXJuIFJlZkNvdW50Owp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElEaXJlY3RQbGF5OFRocmVhZFBvb2xJbXBsX1JlbGVhc2UoUERJUkVDVFBMQVk4VEhSRUFEUE9PTCBpZmFjZSkKewogICAgSURpcmVjdFBsYXk4VGhyZWFkUG9vbEltcGwqIFRoaXMgPSAoSURpcmVjdFBsYXk4VGhyZWFkUG9vbEltcGwqKWlmYWNlOwogICAgVUxPTkcgUmVmQ291bnQgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBpZighUmVmQ291bnQpCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CgogICAgcmV0dXJuIFJlZkNvdW50Owp9CgovKiBJRGlyZWN0UGxheThUaHJlYWRQb29sIGludGVyZmFjZSBmb2xsb3dzICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0UGxheThUaHJlYWRQb29sSW1wbF9Jbml0aWFsaXplKFBESVJFQ1RQTEFZOFRIUkVBRFBPT0wgaWZhY2UsIFBWT0lEIENPTlNUIHB2VXNlckNvbnRleHQsIENPTlNUIFBGTkRQTk1FU1NBR0VIQU5ETEVSIHBmbiwgQ09OU1QgRFdPUkQgZHdGbGFncykKewogICAgRklYTUUoIiglcCktPiglcCwlcCwleCk6IHN0dWJcbiIsIGlmYWNlLCBwdlVzZXJDb250ZXh0LCBwZm4sIGR3RmxhZ3MpOwogICAgcmV0dXJuIERQTl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RQbGF5OFRocmVhZFBvb2xJbXBsX0Nsb3NlKFBESVJFQ1RQTEFZOFRIUkVBRFBPT0wgaWZhY2UsIENPTlNUIERXT1JEIGR3RmxhZ3MpCnsKICAgIHJldHVybiBEUE5fT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0UGxheThUaHJlYWRQb29sSW1wbF9HZXRUaHJlYWRDb3VudChQRElSRUNUUExBWThUSFJFQURQT09MIGlmYWNlLCBDT05TVCBEV09SRCBkd1Byb2Nlc3Nvck51bSwgRFdPUkQqIENPTlNUIHBkd051bVRocmVhZHMsIENPTlNUIERXT1JEIGR3RmxhZ3MpCnsKICAgIEZJWE1FKCIoJXApLT4oJXgsJXAsJXgpOiBzdHViXG4iLCBpZmFjZSwgZHdQcm9jZXNzb3JOdW0sIHBkd051bVRocmVhZHMsIGR3RmxhZ3MpOwogICAgKnBkd051bVRocmVhZHMgPSAwOwogICAgcmV0dXJuIERQTl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RQbGF5OFRocmVhZFBvb2xJbXBsX1NldFRocmVhZENvdW50KFBESVJFQ1RQTEFZOFRIUkVBRFBPT0wgaWZhY2UsIENPTlNUIERXT1JEIGR3UHJvY2Vzc29yTnVtLCBDT05TVCBEV09SRCBkd051bVRocmVhZHMsIENPTlNUIERXT1JEIGR3RmxhZ3MpCnsKICAgIEZJWE1FKCIoJXApLT4oJXgsJXgsJXgpOiBzdHViXG4iLCBpZmFjZSwgZHdQcm9jZXNzb3JOdW0sIGR3TnVtVGhyZWFkcywgZHdGbGFncyk7CiAgICByZXR1cm4gRFBOX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFBsYXk4VGhyZWFkUG9vbEltcGxfRG9Xb3JrKFBESVJFQ1RQTEFZOFRIUkVBRFBPT0wgaWZhY2UsIENPTlNUIERXT1JEIGR3QWxsb3dlZFRpbWVTbGljZSwgQ09OU1QgRFdPUkQgZHdGbGFncykKewogICAgc3RhdGljIEJPT0wgUnVuID0gRkFMU0U7CgogICAgaWYoIVJ1bikKICAgICAgICBGSVhNRSgiKCVwKS0+KCV4LCV4KTogc3R1YlxuIiwgaWZhY2UsIGR3QWxsb3dlZFRpbWVTbGljZSwgZHdGbGFncyk7CgogICAgUnVuID0gVFJVRTsKCiAgICByZXR1cm4gRFBOX09LOwp9CgpzdGF0aWMgY29uc3QgSURpcmVjdFBsYXk4VGhyZWFkUG9vbFZ0YmwgRGlyZWN0UGxheThUaHJlYWRQb29sX1Z0YmwgPQp7CiAgICBJRGlyZWN0UGxheThUaHJlYWRQb29sSW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElEaXJlY3RQbGF5OFRocmVhZFBvb2xJbXBsX0FkZFJlZiwKICAgIElEaXJlY3RQbGF5OFRocmVhZFBvb2xJbXBsX1JlbGVhc2UsCiAgICBJRGlyZWN0UGxheThUaHJlYWRQb29sSW1wbF9Jbml0aWFsaXplLAogICAgSURpcmVjdFBsYXk4VGhyZWFkUG9vbEltcGxfQ2xvc2UsCiAgICBJRGlyZWN0UGxheThUaHJlYWRQb29sSW1wbF9HZXRUaHJlYWRDb3VudCwKICAgIElEaXJlY3RQbGF5OFRocmVhZFBvb2xJbXBsX1NldFRocmVhZENvdW50LAogICAgSURpcmVjdFBsYXk4VGhyZWFkUG9vbEltcGxfRG9Xb3JrCn07CgpIUkVTVUxUIERQTkVUX0NyZWF0ZURpcmVjdFBsYXk4VGhyZWFkUG9vbChMUENMQVNTRkFDVE9SWSBpZmFjZSwgTFBVTktOT1dOIHB1bmtPdXRlciwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHBvYmopCnsKICAgIElEaXJlY3RQbGF5OFRocmVhZFBvb2xJbXBsKiBDbGllbnQ7CgogICAgQ2xpZW50ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJRGlyZWN0UGxheThUaHJlYWRQb29sSW1wbCkpOwoKICAgIGlmKENsaWVudCA9PSBOVUxMKQogICAgewogICAgICAgICpwcG9iaiA9IE5VTEw7CiAgICAgICAgV0FSTigiTm90IGVub3VnaCBtZW1vcnlcbiIpOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQoKICAgIENsaWVudC0+bHBWdGJsID0gJkRpcmVjdFBsYXk4VGhyZWFkUG9vbF9WdGJsOwogICAgQ2xpZW50LT5yZWYgPSAwOwoKICAgIHJldHVybiBJRGlyZWN0UGxheThUaHJlYWRQb29sSW1wbF9RdWVyeUludGVyZmFjZSgoUERJUkVDVFBMQVk4VEhSRUFEUE9PTClDbGllbnQsIHJpaWQsIHBwb2JqKTsKfQo=