LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqCiAqIE5vdGU6IFRoaXMgY29kZSBoYXNuJ3QgYmVlbiBjb21wbGV0ZWx5IGNsZWFuZWQgdXAgeWV0LgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaWZkZWYgSEFWRV9VTklTVERfSAojIGluY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2lmZGVmIEhBVkVfU1lTX1RJTUVfSAojIGluY2x1ZGUgPHN5cy90aW1lLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid293bnQzMi5oIgojaW5jbHVkZSAid2lubnQuaCIKI2luY2x1ZGUgIndpbmNvbi5oIgoKI2luY2x1ZGUgInRocmVhZC5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJkb3N2bS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAiZXhjcHQuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGludCk7CldJTkVfREVDTEFSRV9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CiNpZmRlZiBNWl9TVVBQT1JURUQKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVsYXkpOwojZW5kaWYKCldPUkQgRE9TVk1fcHNwID0gMDsKV09SRCBET1NWTV9yZXR2YWwgPSAwOwoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKCnR5cGVkZWYgc3RydWN0IF9ET1NFVkVOVCB7CiAgaW50IGlycSxwcmlvcml0eTsKICBET1NSRUxBWSByZWxheTsKICB2b2lkICpkYXRhOwogIHN0cnVjdCBfRE9TRVZFTlQgKm5leHQ7Cn0gRE9TRVZFTlQsICpMUERPU0VWRU5UOwoKc3RhdGljIHN0cnVjdCBfRE9TRVZFTlQgKnBlbmRpbmdfZXZlbnQsICpjdXJyZW50X2V2ZW50OwpzdGF0aWMgSEFORExFIGV2ZW50X25vdGlmaWVyOwoKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gcWNyaXQ7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGNyaXRzZWN0X2RlYnVnID0KewogICAgMCwgMCwgJnFjcml0LAogICAgeyAmY3JpdHNlY3RfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJmNyaXRzZWN0X2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAoRFdPUkRfUFRSKShfX0ZJTEVfXyAiOiBxY3JpdCIpIH0KfTsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gcWNyaXQgPSB7ICZjcml0c2VjdF9kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIERPU1ZNX0hhc1BlbmRpbmdFdmVudHMKICoKICogUmV0dXJuIHRydWUgaWYgdGhlcmUgYXJlIHBlbmRpbmcgZXZlbnRzIHRoYXQgYXJlIG5vdAogKiBibG9ja2VkIGJ5IGN1cnJlbnRseSBhY3RpdmUgZXZlbnQuCiAqLwpzdGF0aWMgQk9PTCBET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCB2b2lkICkKeyAgIAogICAgaWYgKCFwZW5kaW5nX2V2ZW50KQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAoIWN1cnJlbnRfZXZlbnQpCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgaWYgKHBlbmRpbmdfZXZlbnQtPnByaW9yaXR5IDwgY3VycmVudF9ldmVudC0+cHJpb3JpdHkpCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgcmV0dXJuIEZBTFNFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBET1NWTV9TZW5kT25lRXZlbnQKICoKICogUHJvY2VzcyBzaW5nbGUgcGVuZGluZyBldmVudC4KICoKICogVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgY2FsbGVkIHdpdGggcXVldWUgY3JpdGljYWwgc2VjdGlvbiBsb2NrZWQuIAogKiBUaGUgZnVuY3Rpb24gdGVtcG9yYXJpbHkgcmVsZWFzZXMgdGhlIGNyaXRpY2FsIHNlY3Rpb24gaWYgaXQgaXMgCiAqIHBvc3NpYmxlIHRoYXQgaW50ZXJuYWwgaW50ZXJydXB0IGhhbmRsZXIgb3IgdXNlciBwcm9jZWR1cmUgd2lsbCAKICogYmUgY2FsbGVkLiBUaGlzIGlzIGJlY2F1c2Ugd2UgbWF5IG90aGVyd2lzZSBnZXQgYSBkZWFkbG9jayBpZgogKiBhbm90aGVyIHRocmVhZCBpcyB3YWl0aW5nIGZvciB0aGUgc2FtZSBjcml0aWNhbCBzZWN0aW9uLgogKi8Kc3RhdGljIHZvaWQgRE9TVk1fU2VuZE9uZUV2ZW50KCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgICBMUERPU0VWRU5UIGV2ZW50ID0gcGVuZGluZ19ldmVudDsKCiAgICAvKiBSZW1vdmUgZnJvbSBwZW5kaW5nIGV2ZW50cyBsaXN0LiAqLwogICAgcGVuZGluZ19ldmVudCA9IGV2ZW50LT5uZXh0OwoKICAgIC8qIFByb2Nlc3MgYWN0aXZlIGV2ZW50LiAqLwogICAgaWYgKGV2ZW50LT5pcnEgPj0gMCkgCiAgICB7CiAgICAgICAgQllURSBpbnRudW0gPSAoZXZlbnQtPmlycSA8IDgpID8KICAgICAgICAgICAgKGV2ZW50LT5pcnEgKyA4KSA6IChldmVudC0+aXJxIC0gOCArIDB4NzApOwogICAgICAgICAgICAKICAgICAgICAvKiBFdmVudCBpcyBhbiBJUlEsIG1vdmUgaXQgdG8gY3VycmVudCBldmVudHMgbGlzdC4gKi8KICAgICAgICBldmVudC0+bmV4dCA9IGN1cnJlbnRfZXZlbnQ7CiAgICAgICAgY3VycmVudF9ldmVudCA9IGV2ZW50OwoKICAgICAgICBUUkFDRSggIkRpc3BhdGNoaW5nIElSUSAlZC5cbiIsIGV2ZW50LT5pcnEgKTsKCiAgICAgICAgaWYgKElTVjg2KGNvbnRleHQpKQogICAgICAgIHsKICAgICAgICAgICAgLyogCiAgICAgICAgICAgICAqIE5vdGUgdGhhdCBpZiBET1NWTV9IYXJkd2FyZUludGVycnVwdFJNIGNhbGxzIGFuIGludGVybmFsIAogICAgICAgICAgICAgKiBpbnRlcnJ1cHQgZGlyZWN0bHksIGN1cnJlbnRfZXZlbnQgbWlnaHQgYmUgY2xlYXJlZCAKICAgICAgICAgICAgICogKGFuZCBldmVudCBmcmVlZCkgaW4gdGhpcyBjYWxsLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgICAgICAgICAgRE9TVk1fSGFyZHdhcmVJbnRlcnJ1cHRSTSggY29udGV4dCwgaW50bnVtICk7CiAgICAgICAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZxY3JpdCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRoaXMgcm91dGluZSBvbmx5IG1vZGlmaWVzIGN1cnJlbnQgY29udGV4dCBzbyBpdCBpcwogICAgICAgICAgICAgKiBub3QgbmVjZXNzYXJ5IHRvIHJlbGVhc2UgY3JpdGljYWwgc2VjdGlvbi4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIERPU1ZNX0hhcmR3YXJlSW50ZXJydXB0UE0oIGNvbnRleHQsIGludG51bSApOwogICAgICAgIH0KICAgIH0gCiAgICBlbHNlIAogICAgewogICAgICAgIC8qIENhbGxiYWNrIGV2ZW50LiAqLwogICAgICAgIFRSQUNFKCAiRGlzcGF0Y2hpbmcgY2FsbGJhY2sgZXZlbnQuXG4iICk7CgogICAgICAgIGlmIChJU1Y4Nihjb250ZXh0KSkKICAgICAgICB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIENhbGwgcmVsYXkgaW1tZWRpYXRlbHkgaW4gcmVhbCBtb2RlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgICAgICAgICAgKCpldmVudC0+cmVsYXkpKCBjb250ZXh0LCBldmVudC0+ZGF0YSApOwogICAgICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBGb3JjZSByZXR1cm4gdG8gcmVsYXkgY29kZS4gV2UgZG8gbm90IHdhbnQgdG8KICAgICAgICAgICAgICogY2FsbCByZWxheSBkaXJlY3RseSBiZWNhdXNlIHdlIG1heSBiZSBpbnNpZGUgYSBzaWduYWwgaGFuZGxlci4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIERPU1ZNX0J1aWxkQ2FsbEZyYW1lKCBjb250ZXh0LCBldmVudC0+cmVsYXksIGV2ZW50LT5kYXRhICk7CiAgICAgICAgfQoKICAgICAgICBmcmVlKGV2ZW50KTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cwogKgogKiBBcyBsb25nIGFzIGNvbnRleHQgaW5zdHJ1Y3Rpb24gcG9pbnRlciBzdGF5cyB1bm1vZGlmaWVkLAogKiBwcm9jZXNzIGFsbCBwZW5kaW5nIGV2ZW50cyB0aGF0IGFyZSBub3QgYmxvY2tlZCBieSBjdXJyZW50bHkKICogYWN0aXZlIGV2ZW50LgogKgogKiBUaGlzIHJvdXRpbmUgYXNzdW1lcyB0aGF0IGNhbGxlciBoYXMgYWxyZWFkeSBjbGVhcmVkIFRFQi52bTg2X3BlbmRpbmcgCiAqIGFuZCBjaGVja2VkIHRoYXQgaW50ZXJydXB0cyBhcmUgZW5hYmxlZC4KICovCnZvaWQgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cyggQ09OVEVYVDg2ICpjb250ZXh0ICkKeyAgIAogICAgRFdPUkQgb2xkX2NzID0gY29udGV4dC0+U2VnQ3M7CiAgICBEV09SRCBvbGRfaXAgPSBjb250ZXh0LT5FaXA7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKCiAgICBUUkFDRSggIkNhbGxlZCBpbiAlcyBtb2RlICVzIGV2ZW50cyBwZW5kaW5nICh0aW1lPSVsZClcbiIsCiAgICAgICAgICAgSVNWODYoY29udGV4dCkgPyAicmVhbCIgOiAicHJvdGVjdGVkIiwKICAgICAgICAgICBET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCkgPyAid2l0aCIgOiAid2l0aG91dCIsCiAgICAgICAgICAgR2V0VGlja0NvdW50KCkgKTsKICAgIFRSQUNFKCAiY3M6aXA9JTA0bHg6JTA4bHgsIHNzOnNwPSUwNGx4OiUwOGx4XG4iLAogICAgICAgICAgIGNvbnRleHQtPlNlZ0NzLCBjb250ZXh0LT5FaXAsIGNvbnRleHQtPlNlZ1NzLCBjb250ZXh0LT5Fc3ApOwoKICAgIHdoaWxlIChjb250ZXh0LT5TZWdDcyA9PSBvbGRfY3MgJiYKICAgICAgICAgICBjb250ZXh0LT5FaXAgPT0gb2xkX2lwICYmCiAgICAgICAgICAgRE9TVk1fSGFzUGVuZGluZ0V2ZW50cygpKQogICAgewogICAgICAgIERPU1ZNX1NlbmRPbmVFdmVudChjb250ZXh0KTsKCiAgICAgICAgLyoKICAgICAgICAgKiBFdmVudCBoYW5kbGluZyBtYXkgaGF2ZSB0dXJuZWQgcGVuZGluZyBldmVudHMgZmxhZyBvbi4KICAgICAgICAgKiBXZSBkaXNhYmxlIGl0IGhlcmUgYmVjYXVzZSB0aGlzIHByZXZlbnRzIHNvbWUKICAgICAgICAgKiB1bm5lY2Vzc2FyeSBjYWxscyB0byB0aGlzIGZ1bmN0aW9uLgogICAgICAgICAqLwogICAgICAgIE50Q3VycmVudFRlYigpLT52bTg2X3BlbmRpbmcgPSAwOwogICAgfQoKI2lmZGVmIE1aX1NVUFBPUlRFRAoKICAgIGlmIChET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCkpCiAgICB7CiAgICAgICAgLyoKICAgICAgICAgKiBJbnRlcnJ1cHRzIGRpc2FibGVkLCBidXQgdGhlcmUgYXJlIHN0aWxsCiAgICAgICAgICogcGVuZGluZyBldmVudHMsIG1ha2Ugc3VyZSB0aGF0IHBlbmRpbmcgZmxhZyBpcyB0dXJuZWQgb24uCiAgICAgICAgICovCiAgICAgICAgVFJBQ0UoICJBbm90aGVyIGV2ZW50IGlzIHBlbmRpbmcsIHNldHRpbmcgVklQIGZsYWcuXG4iICk7CiAgICAgICAgTnRDdXJyZW50VGViKCktPnZtODZfcGVuZGluZyB8PSBWSVBfTUFTSzsKICAgIH0KCiNlbHNlCgogICAgRklYTUUoIk5vIERPUyAuZXhlIGZpbGUgc3VwcG9ydCBvbiB0aGlzIHBsYXRmb3JtICh5ZXQpXG4iKTsKCiNlbmRpZiAvKiBNWl9TVVBQT1JURUQgKi8KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwp9CgoKI2lmZGVmIE1aX1NVUFBPUlRFRAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVF1ZXVlRXZlbnQgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIERPU1ZNX1F1ZXVlRXZlbnQoIElOVCBpcnEsIElOVCBwcmlvcml0eSwgRE9TUkVMQVkgcmVsYXksIExQVk9JRCBkYXRhKQp7CiAgTFBET1NFVkVOVCBldmVudCwgY3VyLCBwcmV2OwogIEJPT0wgICAgICAgb2xkX3BlbmRpbmc7CgogIGlmIChNWl9DdXJyZW50KCkpIHsKICAgIGV2ZW50ID0gbWFsbG9jKHNpemVvZihET1NFVkVOVCkpOwogICAgaWYgKCFldmVudCkgewogICAgICBFUlIoIm91dCBvZiBtZW1vcnkgYWxsb2NhdGluZyBldmVudCBlbnRyeVxuIik7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGV2ZW50LT5pcnEgPSBpcnE7IGV2ZW50LT5wcmlvcml0eSA9IHByaW9yaXR5OwogICAgZXZlbnQtPnJlbGF5ID0gcmVsYXk7IGV2ZW50LT5kYXRhID0gZGF0YTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgb2xkX3BlbmRpbmcgPSBET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCk7CgogICAgLyogaW5zZXJ0IGV2ZW50IGludG8gbGlua2VkIGxpc3QsIGluIG9yZGVyICphZnRlcioKICAgICAqIGFsbCBlYXJsaWVyIGV2ZW50cyBvZiBoaWdoZXIgb3IgZXF1YWwgcHJpb3JpdHkgKi8KICAgIGN1ciA9IHBlbmRpbmdfZXZlbnQ7IHByZXYgPSBOVUxMOwogICAgd2hpbGUgKGN1ciAmJiBjdXItPnByaW9yaXR5PD1wcmlvcml0eSkgewogICAgICBwcmV2ID0gY3VyOwogICAgICBjdXIgPSBjdXItPm5leHQ7CiAgICB9CiAgICBldmVudC0+bmV4dCA9IGN1cjsKICAgIGlmIChwcmV2KSBwcmV2LT5uZXh0ID0gZXZlbnQ7CiAgICBlbHNlIHBlbmRpbmdfZXZlbnQgPSBldmVudDsKCiAgICBpZiAoIW9sZF9wZW5kaW5nICYmIERPU1ZNX0hhc1BlbmRpbmdFdmVudHMoKSkgewogICAgICBUUkFDRSgibmV3IGV2ZW50IHF1ZXVlZCwgc2lnbmFsbGluZyAodGltZT0lbGQpXG4iLCBHZXRUaWNrQ291bnQoKSk7CiAgICAgIAogICAgICAvKiBBbGVydCBWTTg2IHRocmVhZCBhYm91dCB0aGUgbmV3IGV2ZW50LiAqLwogICAgICBraWxsKGRvc3ZtX3BpZCxTSUdVU1IyKTsKCiAgICAgIC8qIFdha2UgdXAgRE9TVk1fV2FpdCBzbyB0aGF0IGl0IGNhbiBzZXJ2ZSBwZW5kaW5nIGV2ZW50cy4gKi8KICAgICAgU2V0RXZlbnQoZXZlbnRfbm90aWZpZXIpOwogICAgfSBlbHNlIHsKICAgICAgVFJBQ0UoIm5ldyBldmVudCBxdWV1ZWQgKHRpbWU9JWxkKVxuIiwgR2V0VGlja0NvdW50KCkpOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZxY3JpdCk7CiAgfSBlbHNlIHsKICAgIC8qIERPUyBzdWJzeXN0ZW0gbm90IHJ1bm5pbmcgKi8KICAgIC8qICh0aGlzIHByb2JhYmx5IG1lYW5zIHRoYXQgd2UncmUgcnVubmluZyBhIHdpbjE2IGFwcAogICAgICogIHdoaWNoIHVzZXMgRFBNSSB0byB0aHVuayBkb3duIHRvIERPUyBzZXJ2aWNlcykgKi8KICAgIGlmIChpcnE8MCkgewogICAgICAvKiBjYWxsYmFjayBldmVudCwgcGVyZm9ybSBpdCB3aXRoIGR1bW15IGNvbnRleHQgKi8KICAgICAgQ09OVEVYVDg2IGNvbnRleHQ7CiAgICAgIG1lbXNldCgmY29udGV4dCwwLHNpemVvZihjb250ZXh0KSk7CiAgICAgICgqcmVsYXkpKCZjb250ZXh0LGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgRVJSKCJJUlEgd2l0aG91dCBET1MgdGFzazogc2hvdWxkIG5vdCBoYXBwZW5cbiIpOwogICAgfQogIH0KfQoKc3RhdGljIHZvaWQgRE9TVk1fUHJvY2Vzc0NvbnNvbGUodm9pZCkKewogIElOUFVUX1JFQ09SRCBtc2c7CiAgRFdPUkQgcmVzOwogIEJZVEUgc2NhbiwgYXNjaWk7CgogIGlmIChSZWFkQ29uc29sZUlucHV0QShHZXRTdGRIYW5kbGUoU1REX0lOUFVUX0hBTkRMRSksJm1zZywxLCZyZXMpKSB7CiAgICBzd2l0Y2ggKG1zZy5FdmVudFR5cGUpIHsKICAgIGNhc2UgS0VZX0VWRU5UOgogICAgICBzY2FuID0gbXNnLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsU2NhbkNvZGU7CiAgICAgIGFzY2lpID0gbXNnLkV2ZW50LktleUV2ZW50LnVDaGFyLkFzY2lpQ2hhcjsKICAgICAgVFJBQ0UoInNjYW4gJTAyeCwgYXNjaWkgJTAyeFxuIiwgc2NhbiwgYXNjaWkpOwoKICAgICAgLyogc2V0IHRoZSAiYnJlYWsiIChyZWxlYXNlKSBmbGFnIGlmIGtleSByZWxlYXNlZCAqLwogICAgICBpZiAoIW1zZy5FdmVudC5LZXlFdmVudC5iS2V5RG93bikgc2NhbiB8PSAweDgwOwoKICAgICAgLyogY2hlY2sgd2hldGhlciBleHRlbmRlZCBiaXQgaXMgc2V0LAogICAgICAgKiBhbmQgaWYgc28sIHF1ZXVlIHRoZSBleHRlbnNpb24gcHJlZml4ICovCiAgICAgIGlmIChtc2cuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgJiBFTkhBTkNFRF9LRVkpIHsKICAgICAgICBET1NWTV9JbnQwOVNlbmRTY2FuKDB4RTAsMCk7CiAgICAgIH0KICAgICAgRE9TVk1fSW50MDlTZW5kU2NhbihzY2FuLCBhc2NpaSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSBNT1VTRV9FVkVOVDoKICAgICAgRE9TVk1fSW50MzNDb25zb2xlKCZtc2cuRXZlbnQuTW91c2VFdmVudCk7CiAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5ET1dfQlVGRkVSX1NJWkVfRVZFTlQ6CiAgICAgIEZJWE1FKCJ1bmhhbmRsZWQgV0lORE9XX0JVRkZFUl9TSVpFX0VWRU5ULlxuIik7CiAgICAgIGJyZWFrOwogICAgY2FzZSBNRU5VX0VWRU5UOgogICAgICBGSVhNRSgidW5oYW5kbGVkIE1FTlVfRVZFTlQuXG4iKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIEZPQ1VTX0VWRU5UOgogICAgICBGSVhNRSgidW5oYW5kbGVkIEZPQ1VTX0VWRU5ULlxuIik7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgRklYTUUoInVua25vd24gY29uc29sZSBldmVudDogJWRcbiIsIG1zZy5FdmVudFR5cGUpOwogICAgfQogIH0KfQoKc3RhdGljIHZvaWQgRE9TVk1fUHJvY2Vzc01lc3NhZ2UoTVNHICptc2cpCnsKICBCWVRFIHNjYW4gPSAwOwoKICBUUkFDRSgiZ290IG1lc3NhZ2UgJTA0eCwgd3BhcmFtPSUwOHgsIGxwYXJhbT0lMDhseFxuIixtc2ctPm1lc3NhZ2UsbXNnLT53UGFyYW0sbXNnLT5sUGFyYW0pOwogIGlmICgobXNnLT5tZXNzYWdlPj1XTV9NT1VTRUZJUlNUKSYmCiAgICAgIChtc2ctPm1lc3NhZ2U8PVdNX01PVVNFTEFTVCkpIHsKICAgIERPU1ZNX0ludDMzTWVzc2FnZShtc2ctPm1lc3NhZ2UsbXNnLT53UGFyYW0sbXNnLT5sUGFyYW0pOwogIH0gZWxzZSB7CiAgICBzd2l0Y2ggKG1zZy0+bWVzc2FnZSkgewogICAgY2FzZSBXTV9LRVlVUDoKICAgICAgc2NhbiA9IDB4ODA7CiAgICBjYXNlIFdNX0tFWURPV046CiAgICAgIHNjYW4gfD0gKG1zZy0+bFBhcmFtID4+IDE2KSAmIDB4N2Y7CgogICAgICAvKiBjaGVjayB3aGV0aGVyIGV4dGVuZGVkIGJpdCBpcyBzZXQsCiAgICAgICAqIGFuZCBpZiBzbywgcXVldWUgdGhlIGV4dGVuc2lvbiBwcmVmaXggKi8KICAgICAgaWYgKG1zZy0+bFBhcmFtICYgMHgxMDAwMDAwKSB7CgkvKiBGSVhNRTogc29tZSBrZXlzIChmdW5jdGlvbiBrZXlzKSBoYXZlCgkgKiBleHRlbmRlZCBiaXQgc2V0IGV2ZW4gd2hlbiB0aGV5IHNob3VsZG4ndCwKCSAqIHNob3VsZCBjaGVjayBmb3IgdGhlbSAqLwoJRE9TVk1fSW50MDlTZW5kU2NhbigweEUwLDApOwogICAgICB9CiAgICAgIERPU1ZNX0ludDA5U2VuZFNjYW4oc2NhbiwwKTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlET1NWTV9XYWl0CiAqCiAqIFdhaXQgZm9yIGFzeW5jaHJvbm91cyBldmVudHMuIFRoaXMgcm91dGluZSB0ZW1wb3JhcmlseSBlbmFibGVzCiAqIGludGVycnVwdHMgYW5kIHdhaXRzIHVudGlsIHNvbWUgYXN5bmNocm9ub3VzIGV2ZW50IGhhcyBiZWVuIAogKiBwcm9jZXNzZWQuCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9XYWl0KCBDT05URVhUODYgKndhaXRjdHggKQp7CiAgICBpZiAoRE9TVk1fSGFzUGVuZGluZ0V2ZW50cygpKQogICAgewogICAgICAgIENPTlRFWFQ4NiBjb250ZXh0ID0gKndhaXRjdHg7CiAgICAgICAgCiAgICAgICAgLyoKICAgICAgICAgKiBJZiBET1NWTV9XYWl0IGlzIGNhbGxlZCBmcm9tIHByb3RlY3RlZCBtb2RlIHdlIGVtdWxhdGUKICAgICAgICAgKiBpbnRlcnJ1cHQgcmVmbGVjdGlvbiBhbmQgY29udmVydCBjb250ZXh0IGludG8gcmVhbCBtb2RlIGNvbnRleHQuCiAgICAgICAgICogVGhpcyBpcyBhY3R1YWxseSB0aGUgY29ycmVjdCB0aGluZyB0byBkbyBhcyBsb25nIGFzIERPU1ZNX1dhaXQKICAgICAgICAgKiBpcyBvbmx5IGNhbGxlZCBmcm9tIHRob3NlIGludGVycnVwdCBmdW5jdGlvbnMgdGhhdCBEUE1JIHJlZmxlY3RzCiAgICAgICAgICogdG8gcmVhbCBtb2RlLgogICAgICAgICAqCiAgICAgICAgICogRklYTUU6IE5lZWQgdG8gdGhpbmsgYWJvdXQgd2hlcmUgdG8gcGxhY2UgcmVhbCBtb2RlIHN0YWNrLgogICAgICAgICAqIEZJWE1FOiBJZiBET1NWTV9XYWl0IGNhbGxzIGFyZSBuZXN0ZWQgc3RhY2sgZ2V0cyBjb3JydXB0ZWQuCiAgICAgICAgICogICAgICAgIENhbiB0aGlzIHJlYWxseSBoYXBwZW4/CiAgICAgICAgICovCiAgICAgICAgaWYgKCFJU1Y4NigmY29udGV4dCkpCiAgICAgICAgewogICAgICAgICAgICBjb250ZXh0LkVGbGFncyB8PSBWODZfRkxBRzsKICAgICAgICAgICAgY29udGV4dC5TZWdTcyA9IDB4ZmZmZjsKICAgICAgICAgICAgY29udGV4dC5Fc3AgPSAwOwogICAgICAgIH0KCiAgICAgICAgY29udGV4dC5FRmxhZ3MgfD0gVklGX01BU0s7CiAgICAgICAgY29udGV4dC5TZWdDcyA9IDA7CiAgICAgICAgY29udGV4dC5FaXAgPSAwOwoKICAgICAgICBET1NWTV9TZW5kUXVldWVkRXZlbnRzKCZjb250ZXh0KTsKCiAgICAgICAgaWYoY29udGV4dC5TZWdDcyB8fCBjb250ZXh0LkVpcCkKICAgICAgICAgICAgRFBNSV9DYWxsUk1Qcm9jKCAmY29udGV4dCwgTlVMTCwgMCwgVFJVRSApOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIEhBTkRMRSBvYmpzWzJdOwogICAgICAgIGludCAgICBvYmpjID0gRE9TVk1fSXNXaW4xNigpID8gMiA6IDE7CiAgICAgICAgRFdPUkQgIHdhaXRyZXQ7CgogICAgICAgIG9ianNbMF0gPSBldmVudF9ub3RpZmllcjsKICAgICAgICBvYmpzWzFdID0gR2V0U3RkSGFuZGxlKFNURF9JTlBVVF9IQU5ETEUpOwoKICAgICAgICB3YWl0cmV0ID0gTXNnV2FpdEZvck11bHRpcGxlT2JqZWN0cyggb2JqYywgb2JqcywgRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTkZJTklURSwgUVNfQUxMSU5QVVQgKTsKICAgICAgICAKICAgICAgICBpZiAod2FpdHJldCA9PSBXQUlUX09CSkVDVF8wKQogICAgICAgIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogTmV3IHBlbmRpbmcgZXZlbnQgaGFzIGJlZW4gcXVldWVkLCB3ZSBpZ25vcmUgaXQKICAgICAgICAgICAgICogaGVyZSBiZWNhdXNlIGl0IHdpbGwgYmUgcHJvY2Vzc2VkIG9uIG5leHQgY2FsbCB0bwogICAgICAgICAgICAgKiBET1NWTV9XYWl0LgogICAgICAgICAgICAgKi8KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAob2JqYyA9PSAyICYmIHdhaXRyZXQgPT0gV0FJVF9PQkpFQ1RfMCArIDEpCiAgICAgICAgewogICAgICAgICAgICBET1NWTV9Qcm9jZXNzQ29uc29sZSgpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICh3YWl0cmV0ID09IFdBSVRfT0JKRUNUXzAgKyBvYmpjKQogICAgICAgIHsKICAgICAgICAgICAgTVNHIG1zZzsKICAgICAgICAgICAgd2hpbGUgKFBlZWtNZXNzYWdlQSgmbXNnLDAsMCwwLFBNX1JFTU9WRXxQTV9OT1lJRUxEKSkgCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIGdvdCBhIG1lc3NhZ2UgKi8KICAgICAgICAgICAgICAgIERPU1ZNX1Byb2Nlc3NNZXNzYWdlKCZtc2cpOwogICAgICAgICAgICAgICAgLyogd2UgZG9uJ3QgbmVlZCBhIFRyYW5zbGF0ZU1lc3NhZ2UgaGVyZSAqLwogICAgICAgICAgICAgICAgRGlzcGF0Y2hNZXNzYWdlQSgmbXNnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBFUlJfKG1vZHVsZSkoICJkb3N2bSB3YWl0IGVycm9yPSVsZFxuIiwgR2V0TGFzdEVycm9yKCkgKTsKICAgICAgICB9CiAgICB9Cn0KCgpEV09SRCBXSU5BUEkgRE9TVk1fTG9vcCggSEFORExFIGhUaHJlYWQgKQp7CiAgSEFORExFIG9ianNbMl07CiAgTVNHIG1zZzsKICBEV09SRCB3YWl0cmV0OwoKICBvYmpzWzBdID0gR2V0U3RkSGFuZGxlKFNURF9JTlBVVF9IQU5ETEUpOwogIG9ianNbMV0gPSBoVGhyZWFkOwoKICBmb3IoOzspIHsKICAgICAgVFJBQ0VfKGludCkoIndhaXRpbmcgZm9yIGFjdGlvblxuIik7CiAgICAgIHdhaXRyZXQgPSBNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKDIsIG9ianMsIEZBTFNFLCBJTkZJTklURSwgUVNfQUxMSU5QVVQpOwogICAgICBpZiAod2FpdHJldCA9PSBXQUlUX09CSkVDVF8wKSB7CiAgICAgICAgICBET1NWTV9Qcm9jZXNzQ29uc29sZSgpOwogICAgICB9CiAgICAgIGVsc2UgaWYgKHdhaXRyZXQgPT0gV0FJVF9PQkpFQ1RfMCArIDEpIHsKICAgICAgICAgRFdPUkQgcnY7CiAgICAgICAgIGlmKCFHZXRFeGl0Q29kZVRocmVhZChoVGhyZWFkLCAmcnYpKSB7CiAgICAgICAgICAgICBFUlIoIkZhaWxlZCB0byBnZXQgdGhyZWFkIGV4aXQgY29kZSFcbiIpOwogICAgICAgICAgICAgcnYgPSAwOwogICAgICAgICB9CiAgICAgICAgIHJldHVybiBydjsKICAgICAgfQogICAgICBlbHNlIGlmICh3YWl0cmV0ID09IFdBSVRfT0JKRUNUXzAgKyAyKSB7CiAgICAgICAgICB3aGlsZSAoUGVla01lc3NhZ2VBKCZtc2csMCwwLDAsUE1fUkVNT1ZFKSkgewogICAgICAgICAgICAgIGlmIChtc2cuaHduZCkgewogICAgICAgICAgICAgICAgICAvKiBpdCdzIGEgd2luZG93IG1lc3NhZ2UgKi8KICAgICAgICAgICAgICAgICAgRE9TVk1fUHJvY2Vzc01lc3NhZ2UoJm1zZyk7CiAgICAgICAgICAgICAgICAgIERpc3BhdGNoTWVzc2FnZUEoJm1zZyk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgLyogaXQncyBhIHRocmVhZCBtZXNzYWdlICovCiAgICAgICAgICAgICAgICAgIHN3aXRjaCAobXNnLm1lc3NhZ2UpIHsKICAgICAgICAgICAgICAgICAgY2FzZSBXTV9RVUlUOgogICAgICAgICAgICAgICAgICAgICAgLyogc3RvcCB0aGlzIG1hZG5lc3MhISAqLwogICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICAgIGNhc2UgV01fVVNFUjoKICAgICAgICAgICAgICAgICAgICAgIC8qIHJ1biBwYXNzZWQgcHJvY2VkdXJlIGluIHRoaXMgdGhyZWFkICovCiAgICAgICAgICAgICAgICAgICAgICAvKiAoc29ydCBvZiBsaWtlIEFQQywgYnV0IHdlIHNpZ25hbCB0aGUgY29tcGxldGlvbikgKi8KICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBET1NfU1BDICpzcGMgPSAoRE9TX1NQQyAqKW1zZy5sUGFyYW07CiAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0VfKGludCkoImNhbGxpbmcgJXAgd2l0aCBhcmcgJTA4bHhcbiIsIHNwYy0+cHJvYywgc3BjLT5hcmcpOwogICAgICAgICAgICAgICAgICAgICAgICAgIChzcGMtPnByb2MpKHNwYy0+YXJnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRV8oaW50KSgiZG9uZSwgc2lnbmFsbGluZyBldmVudCAleFxuIiwgbXNnLndQYXJhbSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0RXZlbnQoIChIQU5ETEUpbXNnLndQYXJhbSApOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICBEaXNwYXRjaE1lc3NhZ2VBKCZtc2cpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgICAgRVJSXyhpbnQpKCJNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzIHJldHVybmVkIHVuZXhwZWN0ZWQgdmFsdWUuXG4iKTsKICAgICAgICAgIHJldHVybiAwOwogICAgICB9CiAgfQp9CgpzdGF0aWMgV0lORV9FWENFUFRJT05fRklMVEVSKGV4Y2VwdGlvbl9oYW5kbGVyKQp7CiAgRVhDRVBUSU9OX1JFQ09SRCAqcmVjID0gR2V0RXhjZXB0aW9uSW5mb3JtYXRpb24oKS0+RXhjZXB0aW9uUmVjb3JkOwogIENPTlRFWFQgKmNvbnRleHQgPSBHZXRFeGNlcHRpb25JbmZvcm1hdGlvbigpLT5Db250ZXh0UmVjb3JkOwogIGludCBhcmcgPSByZWMtPkV4Y2VwdGlvbkluZm9ybWF0aW9uWzBdOwogIEJPT0wgcmV0OwoKICBzd2l0Y2gocmVjLT5FeGNlcHRpb25Db2RlKSB7CiAgY2FzZSBFWENFUFRJT05fVk04Nl9JTlR4OgogICAgVFJBQ0VfKHJlbGF5KSgiQ2FsbCBET1MgaW50IDB4JTAyeCByZXQ9JTA0bHg6JTA0bHhcbiIKICAgICAgICAgICAgICAgICAgIiBlYXg9JTA4bHggZWJ4PSUwOGx4IGVjeD0lMDhseCBlZHg9JTA4bHggZXNpPSUwOGx4IGVkaT0lMDhseFxuIgogICAgICAgICAgICAgICAgICAiIGVicD0lMDhseCBlc3A9JTA4bHggZHM9JTA0bHggZXM9JTA0bHggZnM9JTA0bHggZ3M9JTA0bHggZmxhZ3M9JTA4bHhcbiIsCiAgICAgICAgICAgICAgICAgIGFyZywgY29udGV4dC0+U2VnQ3MsIGNvbnRleHQtPkVpcCwKICAgICAgICAgICAgICAgICAgY29udGV4dC0+RWF4LCBjb250ZXh0LT5FYngsIGNvbnRleHQtPkVjeCwgY29udGV4dC0+RWR4LCBjb250ZXh0LT5Fc2ksIGNvbnRleHQtPkVkaSwKICAgICAgICAgICAgICAgICAgY29udGV4dC0+RWJwLCBjb250ZXh0LT5Fc3AsIGNvbnRleHQtPlNlZ0RzLCBjb250ZXh0LT5TZWdFcywgY29udGV4dC0+U2VnRnMsIGNvbnRleHQtPlNlZ0dzLAogICAgICAgICAgICAgICAgICBjb250ZXh0LT5FRmxhZ3MgKTsKICAgIHJldCA9IERPU1ZNX0VtdWxhdGVJbnRlcnJ1cHRSTSggY29udGV4dCwgYXJnICk7CiAgICBUUkFDRV8ocmVsYXkpKCJSZXQgIERPUyBpbnQgMHglMDJ4IHJldD0lMDRseDolMDRseFxuIgogICAgICAgICAgICAgICAgICAiIGVheD0lMDhseCBlYng9JTA4bHggZWN4PSUwOGx4IGVkeD0lMDhseCBlc2k9JTA4bHggZWRpPSUwOGx4XG4iCiAgICAgICAgICAgICAgICAgICIgZWJwPSUwOGx4IGVzcD0lMDhseCBkcz0lMDRseCBlcz0lMDRseCBmcz0lMDRseCBncz0lMDRseCBmbGFncz0lMDhseFxuIiwKICAgICAgICAgICAgICAgICAgYXJnLCBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwLAogICAgICAgICAgICAgICAgICBjb250ZXh0LT5FYXgsIGNvbnRleHQtPkVieCwgY29udGV4dC0+RWN4LCBjb250ZXh0LT5FZHgsIGNvbnRleHQtPkVzaSwgY29udGV4dC0+RWRpLAogICAgICAgICAgICAgICAgICBjb250ZXh0LT5FYnAsIGNvbnRleHQtPkVzcCwgY29udGV4dC0+U2VnRHMsIGNvbnRleHQtPlNlZ0VzLAogICAgICAgICAgICAgICAgICBjb250ZXh0LT5TZWdGcywgY29udGV4dC0+U2VnR3MsIGNvbnRleHQtPkVGbGFncyApOwogICAgcmV0dXJuIHJldCA/IEVYQ0VQVElPTl9DT05USU5VRV9FWEVDVVRJT04gOiBFWENFUFRJT05fRVhFQ1VURV9IQU5ETEVSOwoKICBjYXNlIEVYQ0VQVElPTl9WTTg2X1NUSToKICAvKiBjYXNlIEVYQ0VQVElPTl9WTTg2X1BJQ1JFVFVSTjogKi8KICAgIGlmICghSVNWODYoY29udGV4dCkpCiAgICAgIEVSUiggIlByb3RlY3RlZCBtb2RlIFNUSSBjYXVnaHQgYnkgcmVhbCBtb2RlIGhhbmRsZXIhXG4iICk7CiAgICBET1NWTV9TZW5kUXVldWVkRXZlbnRzKGNvbnRleHQpOwogICAgcmV0dXJuIEVYQ0VQVElPTl9DT05USU5VRV9FWEVDVVRJT047CiAgCiAgY2FzZSBFWENFUFRJT05fU0lOR0xFX1NURVA6CiAgICByZXQgPSBET1NWTV9FbXVsYXRlSW50ZXJydXB0Uk0oIGNvbnRleHQsIDEgKTsKICAgIHJldHVybiByZXQgPyBFWENFUFRJT05fQ09OVElOVUVfRVhFQ1VUSU9OIDogRVhDRVBUSU9OX0VYRUNVVEVfSEFORExFUjsKICAKICBjYXNlIEVYQ0VQVElPTl9CUkVBS1BPSU5UOgogICAgcmV0ID0gRE9TVk1fRW11bGF0ZUludGVycnVwdFJNKCBjb250ZXh0LCAzICk7CiAgICByZXR1cm4gcmV0ID8gRVhDRVBUSU9OX0NPTlRJTlVFX0VYRUNVVElPTiA6IEVYQ0VQVElPTl9FWEVDVVRFX0hBTkRMRVI7CiAgCiAgfQogIHJldHVybiBFWENFUFRJT05fQ09OVElOVUVfU0VBUkNIOwp9CgppbnQgV0lOQVBJIERPU1ZNX0VudGVyKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgaWYgKCFJU1Y4Nihjb250ZXh0KSkKICAgICAgRVJSKCAiQ2FsbGVkIHdpdGggcHJvdGVjdGVkIG1vZGUgY29udGV4dCFcbiIgKTsKCiAgX19UUlkKICB7CiAgICAgIFdPV0NhbGxiYWNrMTZFeCggMCwgV0NCMTZfUkVHUywgMCwgTlVMTCwgKERXT1JEICopY29udGV4dCApOwogICAgICBUUkFDRV8obW9kdWxlKSggInZtODYgcmV0dXJuZWQ6ICVzXG4iLCBzdHJlcnJvcihlcnJubykgKTsKICB9CiAgX19FWENFUFQoZXhjZXB0aW9uX2hhbmRsZXIpCiAgewogICAgVFJBQ0VfKG1vZHVsZSkoICJsZWF2aW5nIHZtODYgbW9kZVxuIiApOwogIH0KICBfX0VORFRSWQoKICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlPdXRQSUMgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIERPU1ZNX1BJQ19pb3BvcnRfb3V0KCBXT1JEIHBvcnQsIEJZVEUgdmFsKQp7CiAgICBpZiAocG9ydCAhPSAweDIwKQogICAgewogICAgICAgIEZJWE1FKCAiVW5zdXBwb3J0ZWQgUElDIHBvcnQgJTA0eFxuIiwgcG9ydCApOwogICAgfQogICAgZWxzZSBpZiAodmFsID09IDB4MjAgfHwgKHZhbCA+PSAweDYwICYmIHZhbCA8PSAweDY3KSkgCiAgICB7CiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKCiAgICAgICAgaWYgKCFjdXJyZW50X2V2ZW50KQogICAgICAgIHsKICAgICAgICAgICAgV0FSTiggIiVzIHdpdGhvdXQgYWN0aXZlIElSUVxuIiwKICAgICAgICAgICAgICAgICAgdmFsID09IDB4MjAgPyAiRU9JIiA6ICJTcGVjaWZpYyBFT0kiICk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHZhbCAhPSAweDIwICYmIHZhbCAtIDB4NjAgIT0gY3VycmVudF9ldmVudC0+aXJxKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTiggIlNwZWNpZmljIEVPSSBidXQgY3VycmVudCBJUlEgJWQgaXMgbm90ICVkXG4iLCAKICAgICAgICAgICAgICAgICAgY3VycmVudF9ldmVudC0+aXJxLCB2YWwgLSAweDYwICk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIExQRE9TRVZFTlQgZXZlbnQgPSBjdXJyZW50X2V2ZW50OwoKICAgICAgICAgICAgVFJBQ0UoICJSZWNlaXZlZCAlcyBmb3IgY3VycmVudCBJUlEgJWQsIGNsZWFyaW5nIGV2ZW50XG4iLAogICAgICAgICAgICAgICAgICAgdmFsID09IDB4MjAgPyAiRU9JIiA6ICJTcGVjaWZpYyBFT0kiLCBldmVudC0+aXJxICk7CgogICAgICAgICAgICBjdXJyZW50X2V2ZW50ID0gZXZlbnQtPm5leHQ7CiAgICAgICAgICAgIGlmIChldmVudC0+cmVsYXkpCiAgICAgICAgICAgICAgICAoKmV2ZW50LT5yZWxheSkoTlVMTCxldmVudC0+ZGF0YSk7CiAgICAgICAgICAgIGZyZWUoZXZlbnQpOwoKICAgICAgICAgICAgaWYgKERPU1ZNX0hhc1BlbmRpbmdFdmVudHMoKSkgCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFRSQUNFKCAiQW5vdGhlciBldmVudCBwZW5kaW5nLCBzZXR0aW5nIHBlbmRpbmcgZmxhZ1xuIiApOwogICAgICAgICAgICAgICAgTnRDdXJyZW50VGViKCktPnZtODZfcGVuZGluZyB8PSBWSVBfTUFTSzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgIH0gCiAgICBlbHNlIAogICAgewogICAgICAgIEZJWE1FKCAiVW5yZWNvZ25pemVkIFBJQyBjb21tYW5kICUwMnhcbiIsIHZhbCApOwogICAgfQp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVudGVyIChXSU5FRE9TLkApCiAqLwpJTlQgV0lOQVBJIERPU1ZNX0VudGVyKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiBFUlJfKG1vZHVsZSkoIkRPUyByZWFsbW9kZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlIVxuIik7CiByZXR1cm4gLTE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV2FpdCAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fV2FpdCggQ09OVEVYVDg2ICp3YWl0Y3R4ICkgeyB9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU91dFBJQyAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUElDX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwpIHt9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVF1ZXVlRXZlbnQgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIERPU1ZNX1F1ZXVlRXZlbnQoIElOVCBpcnEsIElOVCBwcmlvcml0eSwgRE9TUkVMQVkgcmVsYXksIExQVk9JRCBkYXRhKQp7CiAgaWYgKGlycTwwKSB7CiAgICAvKiBjYWxsYmFjayBldmVudCwgcGVyZm9ybSBpdCB3aXRoIGR1bW15IGNvbnRleHQgKi8KICAgIENPTlRFWFQ4NiBjb250ZXh0OwogICAgbWVtc2V0KCZjb250ZXh0LDAsc2l6ZW9mKGNvbnRleHQpKTsKICAgICgqcmVsYXkpKCZjb250ZXh0LGRhdGEpOwogIH0gZWxzZSB7CiAgICBFUlIoIklSUSB3aXRob3V0IERPUyB0YXNrOiBzaG91bGQgbm90IGhhcHBlblxuIik7CiAgfQp9CgojZW5kaWYgLyogTVpfU1VQUE9SVEVEICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICBET1NWTV9BY2tub3dsZWRnZUlSUQogKgogKiBUaGlzIHJvdXRpbmUgc2hvdWxkIGJlIGNhbGxlZCBieSBhbGwgaW50ZXJuYWwgSVJRIGhhbmRsZXJzLgogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fQWNrbm93bGVkZ2VJUlEoIENPTlRFWFQ4NiAqY29udGV4dCApCnsKICAgIC8qCiAgICAgKiBTZW5kIEVPSSB0byBQSUMuCiAgICAgKi8KICAgIERPU1ZNX1BJQ19pb3BvcnRfb3V0KCAweDIwLCAweDIwICk7CgogICAgLyoKICAgICAqIFByb3RlY3RlZCBtb2RlIElSUSBoYW5kbGVycyBhcmUgc3VwcG9zZWQKICAgICAqIHRvIHR1cm4gVklGIGZsYWcgb24gYmVmb3JlIHRoZXkgcmV0dXJuLgogICAgICovCiAgICBpZiAoIUlTVjg2KGNvbnRleHQpKQogICAgICAgIE50Q3VycmVudFRlYigpLT5kcG1pX3ZpZiA9IDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkgICAgRGxsTWFpbiAgKERPU1ZNLjApCiAqLwpCT09MIFdJTkFQSSBEbGxNYWluKCBISU5TVEFOQ0UgaGluc3RETEwsIERXT1JEIGZkd1JlYXNvbiwgTFBWT0lEIGxwdlJlc2VydmVkICkKewogICAgVFJBQ0VfKG1vZHVsZSkoIiglcCwlbGQsJXApXG4iLCBoaW5zdERMTCwgZmR3UmVhc29uLCBscHZSZXNlcnZlZCk7CgogICAgaWYgKGZkd1JlYXNvbiA9PSBETExfUFJPQ0VTU19BVFRBQ0gpCiAgICB7CiAgICAgICAgRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyhoaW5zdERMTCk7CiAgICAgICAgaWYgKCFET1NNRU1fSW5pdERvc01lbW9yeSgpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgRE9TVk1fSW5pdFNlZ21lbnRzKCk7CgogICAgICAgIGV2ZW50X25vdGlmaWVyID0gQ3JlYXRlRXZlbnRXKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CiAgICAgICAgaWYoIWV2ZW50X25vdGlmaWVyKQogICAgICAgICAgRVJSKCJGYWlsZWQgdG8gY3JlYXRlIGV2ZW50IG9iamVjdCFcbiIpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0K