LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqCiAqIE5vdGU6IFRoaXMgY29kZSBoYXNuJ3QgYmVlbiBjb21wbGV0ZWx5IGNsZWFuZWQgdXAgeWV0LgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaWZkZWYgSEFWRV9VTklTVERfSAojIGluY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2lmZGVmIEhBVkVfU1lTX1RJTUVfSAojIGluY2x1ZGUgPHN5cy90aW1lLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid293bnQzMi5oIgojaW5jbHVkZSAid2lubnQuaCIKI2luY2x1ZGUgIndpbmNvbi5oIgoKI2luY2x1ZGUgInRocmVhZC5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJkb3N2bS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAiZXhjcHQuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGludCk7CldJTkVfREVDTEFSRV9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CiNpZmRlZiBNWl9TVVBQT1JURUQKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVsYXkpOwojZW5kaWYKCldPUkQgRE9TVk1fcHNwID0gMDsKV09SRCBET1NWTV9yZXR2YWwgPSAwOwoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKCnR5cGVkZWYgc3RydWN0IF9ET1NFVkVOVCB7CiAgaW50IGlycSxwcmlvcml0eTsKICBET1NSRUxBWSByZWxheTsKICB2b2lkICpkYXRhOwogIHN0cnVjdCBfRE9TRVZFTlQgKm5leHQ7Cn0gRE9TRVZFTlQsICpMUERPU0VWRU5UOwoKc3RhdGljIHN0cnVjdCBfRE9TRVZFTlQgKnBlbmRpbmdfZXZlbnQsICpjdXJyZW50X2V2ZW50OwpzdGF0aWMgSEFORExFIGV2ZW50X25vdGlmaWVyOwoKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gcWNyaXQ7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGNyaXRzZWN0X2RlYnVnID0KewogICAgMCwgMCwgJnFjcml0LAogICAgeyAmY3JpdHNlY3RfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJmNyaXRzZWN0X2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAoRFdPUkRfUFRSKShfX0ZJTEVfXyAiOiBxY3JpdCIpIH0KfTsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gcWNyaXQgPSB7ICZjcml0c2VjdF9kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIERPU1ZNX0hhc1BlbmRpbmdFdmVudHMKICoKICogUmV0dXJuIHRydWUgaWYgdGhlcmUgYXJlIHBlbmRpbmcgZXZlbnRzIHRoYXQgYXJlIG5vdAogKiBibG9ja2VkIGJ5IGN1cnJlbnRseSBhY3RpdmUgZXZlbnQuCiAqLwpzdGF0aWMgQk9PTCBET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCB2b2lkICkKeyAgIAogICAgaWYgKCFwZW5kaW5nX2V2ZW50KQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAoIWN1cnJlbnRfZXZlbnQpCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgaWYgKHBlbmRpbmdfZXZlbnQtPnByaW9yaXR5IDwgY3VycmVudF9ldmVudC0+cHJpb3JpdHkpCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgcmV0dXJuIEZBTFNFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBET1NWTV9TZW5kT25lRXZlbnQKICoKICogUHJvY2VzcyBzaW5nbGUgcGVuZGluZyBldmVudC4KICoKICogVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgY2FsbGVkIHdpdGggcXVldWUgY3JpdGljYWwgc2VjdGlvbiBsb2NrZWQuIAogKiBUaGUgZnVuY3Rpb24gdGVtcG9yYXJpbHkgcmVsZWFzZXMgdGhlIGNyaXRpY2FsIHNlY3Rpb24gaWYgaXQgaXMgCiAqIHBvc3NpYmxlIHRoYXQgaW50ZXJuYWwgaW50ZXJydXB0IGhhbmRsZXIgb3IgdXNlciBwcm9jZWR1cmUgd2lsbCAKICogYmUgY2FsbGVkLiBUaGlzIGlzIGJlY2F1c2Ugd2UgbWF5IG90aGVyd2lzZSBnZXQgYSBkZWFkbG9jayBpZgogKiBhbm90aGVyIHRocmVhZCBpcyB3YWl0aW5nIGZvciB0aGUgc2FtZSBjcml0aWNhbCBzZWN0aW9uLgogKi8Kc3RhdGljIHZvaWQgRE9TVk1fU2VuZE9uZUV2ZW50KCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgICBMUERPU0VWRU5UIGV2ZW50ID0gcGVuZGluZ19ldmVudDsKCiAgICAvKiBSZW1vdmUgZnJvbSBwZW5kaW5nIGV2ZW50cyBsaXN0LiAqLwogICAgcGVuZGluZ19ldmVudCA9IGV2ZW50LT5uZXh0OwoKICAgIC8qIFByb2Nlc3MgYWN0aXZlIGV2ZW50LiAqLwogICAgaWYgKGV2ZW50LT5pcnEgPj0gMCkgCiAgICB7CiAgICAgICAgQllURSBpbnRudW0gPSAoZXZlbnQtPmlycSA8IDgpID8KICAgICAgICAgICAgKGV2ZW50LT5pcnEgKyA4KSA6IChldmVudC0+aXJxIC0gOCArIDB4NzApOwogICAgICAgICAgICAKICAgICAgICAvKiBFdmVudCBpcyBhbiBJUlEsIG1vdmUgaXQgdG8gY3VycmVudCBldmVudHMgbGlzdC4gKi8KICAgICAgICBldmVudC0+bmV4dCA9IGN1cnJlbnRfZXZlbnQ7CiAgICAgICAgY3VycmVudF9ldmVudCA9IGV2ZW50OwoKICAgICAgICBUUkFDRSggIkRpc3BhdGNoaW5nIElSUSAlZC5cbiIsIGV2ZW50LT5pcnEgKTsKCiAgICAgICAgaWYgKElTVjg2KGNvbnRleHQpKQogICAgICAgIHsKICAgICAgICAgICAgLyogCiAgICAgICAgICAgICAqIE5vdGUgdGhhdCBpZiBET1NWTV9IYXJkd2FyZUludGVycnVwdFJNIGNhbGxzIGFuIGludGVybmFsIAogICAgICAgICAgICAgKiBpbnRlcnJ1cHQgZGlyZWN0bHksIGN1cnJlbnRfZXZlbnQgbWlnaHQgYmUgY2xlYXJlZCAKICAgICAgICAgICAgICogKGFuZCBldmVudCBmcmVlZCkgaW4gdGhpcyBjYWxsLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgICAgICAgICAgRE9TVk1fSGFyZHdhcmVJbnRlcnJ1cHRSTSggY29udGV4dCwgaW50bnVtICk7CiAgICAgICAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZxY3JpdCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRoaXMgcm91dGluZSBvbmx5IG1vZGlmaWVzIGN1cnJlbnQgY29udGV4dCBzbyBpdCBpcwogICAgICAgICAgICAgKiBub3QgbmVjZXNzYXJ5IHRvIHJlbGVhc2UgY3JpdGljYWwgc2VjdGlvbi4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIERPU1ZNX0hhcmR3YXJlSW50ZXJydXB0UE0oIGNvbnRleHQsIGludG51bSApOwogICAgICAgIH0KICAgIH0gCiAgICBlbHNlIAogICAgewogICAgICAgIC8qIENhbGxiYWNrIGV2ZW50LiAqLwogICAgICAgIFRSQUNFKCAiRGlzcGF0Y2hpbmcgY2FsbGJhY2sgZXZlbnQuXG4iICk7CgogICAgICAgIGlmIChJU1Y4Nihjb250ZXh0KSkKICAgICAgICB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIENhbGwgcmVsYXkgaW1tZWRpYXRlbHkgaW4gcmVhbCBtb2RlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgICAgICAgICAgKCpldmVudC0+cmVsYXkpKCBjb250ZXh0LCBldmVudC0+ZGF0YSApOwogICAgICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBGb3JjZSByZXR1cm4gdG8gcmVsYXkgY29kZS4gV2UgZG8gbm90IHdhbnQgdG8KICAgICAgICAgICAgICogY2FsbCByZWxheSBkaXJlY3RseSBiZWNhdXNlIHdlIG1heSBiZSBpbnNpZGUgYSBzaWduYWwgaGFuZGxlci4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIERPU1ZNX0J1aWxkQ2FsbEZyYW1lKCBjb250ZXh0LCBldmVudC0+cmVsYXksIGV2ZW50LT5kYXRhICk7CiAgICAgICAgfQoKICAgICAgICBmcmVlKGV2ZW50KTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cwogKgogKiBBcyBsb25nIGFzIGNvbnRleHQgaW5zdHJ1Y3Rpb24gcG9pbnRlciBzdGF5cyB1bm1vZGlmaWVkLAogKiBwcm9jZXNzIGFsbCBwZW5kaW5nIGV2ZW50cyB0aGF0IGFyZSBub3QgYmxvY2tlZCBieSBjdXJyZW50bHkKICogYWN0aXZlIGV2ZW50LgogKgogKiBUaGlzIHJvdXRpbmUgYXNzdW1lcyB0aGF0IGNhbGxlciBoYXMgYWxyZWFkeSBjbGVhcmVkIFRFQi52bTg2X3BlbmRpbmcgCiAqIGFuZCBjaGVja2VkIHRoYXQgaW50ZXJydXB0cyBhcmUgZW5hYmxlZC4KICovCnZvaWQgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cyggQ09OVEVYVDg2ICpjb250ZXh0ICkKeyAgIAogICAgRFdPUkQgb2xkX2NzID0gY29udGV4dC0+U2VnQ3M7CiAgICBEV09SRCBvbGRfaXAgPSBjb250ZXh0LT5FaXA7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKCiAgICBUUkFDRSggIkNhbGxlZCBpbiAlcyBtb2RlICVzIGV2ZW50cyBwZW5kaW5nICh0aW1lPSVkKVxuIiwKICAgICAgICAgICBJU1Y4Nihjb250ZXh0KSA/ICJyZWFsIiA6ICJwcm90ZWN0ZWQiLAogICAgICAgICAgIERPU1ZNX0hhc1BlbmRpbmdFdmVudHMoKSA/ICJ3aXRoIiA6ICJ3aXRob3V0IiwKICAgICAgICAgICBHZXRUaWNrQ291bnQoKSApOwogICAgVFJBQ0UoICJjczppcD0lMDR4OiUwOHgsIHNzOnNwPSUwNHg6JTA4eFxuIiwKICAgICAgICAgICBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwLCBjb250ZXh0LT5TZWdTcywgY29udGV4dC0+RXNwKTsKCiAgICB3aGlsZSAoY29udGV4dC0+U2VnQ3MgPT0gb2xkX2NzICYmCiAgICAgICAgICAgY29udGV4dC0+RWlwID09IG9sZF9pcCAmJgogICAgICAgICAgIERPU1ZNX0hhc1BlbmRpbmdFdmVudHMoKSkKICAgIHsKICAgICAgICBET1NWTV9TZW5kT25lRXZlbnQoY29udGV4dCk7CgogICAgICAgIC8qCiAgICAgICAgICogRXZlbnQgaGFuZGxpbmcgbWF5IGhhdmUgdHVybmVkIHBlbmRpbmcgZXZlbnRzIGZsYWcgb24uCiAgICAgICAgICogV2UgZGlzYWJsZSBpdCBoZXJlIGJlY2F1c2UgdGhpcyBwcmV2ZW50cyBzb21lCiAgICAgICAgICogdW5uZWNlc3NhcnkgY2FsbHMgdG8gdGhpcyBmdW5jdGlvbi4KICAgICAgICAgKi8KICAgICAgICBOdEN1cnJlbnRUZWIoKS0+dm04Nl9wZW5kaW5nID0gMDsKICAgIH0KCiNpZmRlZiBNWl9TVVBQT1JURUQKCiAgICBpZiAoRE9TVk1fSGFzUGVuZGluZ0V2ZW50cygpKQogICAgewogICAgICAgIC8qCiAgICAgICAgICogSW50ZXJydXB0cyBkaXNhYmxlZCwgYnV0IHRoZXJlIGFyZSBzdGlsbAogICAgICAgICAqIHBlbmRpbmcgZXZlbnRzLCBtYWtlIHN1cmUgdGhhdCBwZW5kaW5nIGZsYWcgaXMgdHVybmVkIG9uLgogICAgICAgICAqLwogICAgICAgIFRSQUNFKCAiQW5vdGhlciBldmVudCBpcyBwZW5kaW5nLCBzZXR0aW5nIFZJUCBmbGFnLlxuIiApOwogICAgICAgIE50Q3VycmVudFRlYigpLT52bTg2X3BlbmRpbmcgfD0gVklQX01BU0s7CiAgICB9CgojZWxzZQoKICAgIEZJWE1FKCJObyBET1MgLmV4ZSBmaWxlIHN1cHBvcnQgb24gdGhpcyBwbGF0Zm9ybSAoeWV0KVxuIik7CgojZW5kaWYgLyogTVpfU1VQUE9SVEVEICovCgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKfQoKCiNpZmRlZiBNWl9TVVBQT1JURUQKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlRdWV1ZUV2ZW50IChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9RdWV1ZUV2ZW50KCBJTlQgaXJxLCBJTlQgcHJpb3JpdHksIERPU1JFTEFZIHJlbGF5LCBMUFZPSUQgZGF0YSkKewogIExQRE9TRVZFTlQgZXZlbnQsIGN1ciwgcHJldjsKICBCT09MICAgICAgIG9sZF9wZW5kaW5nOwoKICBpZiAoTVpfQ3VycmVudCgpKSB7CiAgICBldmVudCA9IG1hbGxvYyhzaXplb2YoRE9TRVZFTlQpKTsKICAgIGlmICghZXZlbnQpIHsKICAgICAgRVJSKCJvdXQgb2YgbWVtb3J5IGFsbG9jYXRpbmcgZXZlbnQgZW50cnlcbiIpOwogICAgICByZXR1cm47CiAgICB9CiAgICBldmVudC0+aXJxID0gaXJxOyBldmVudC0+cHJpb3JpdHkgPSBwcmlvcml0eTsKICAgIGV2ZW50LT5yZWxheSA9IHJlbGF5OyBldmVudC0+ZGF0YSA9IGRhdGE7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgIG9sZF9wZW5kaW5nID0gRE9TVk1fSGFzUGVuZGluZ0V2ZW50cygpOwoKICAgIC8qIGluc2VydCBldmVudCBpbnRvIGxpbmtlZCBsaXN0LCBpbiBvcmRlciAqYWZ0ZXIqCiAgICAgKiBhbGwgZWFybGllciBldmVudHMgb2YgaGlnaGVyIG9yIGVxdWFsIHByaW9yaXR5ICovCiAgICBjdXIgPSBwZW5kaW5nX2V2ZW50OyBwcmV2ID0gTlVMTDsKICAgIHdoaWxlIChjdXIgJiYgY3VyLT5wcmlvcml0eTw9cHJpb3JpdHkpIHsKICAgICAgcHJldiA9IGN1cjsKICAgICAgY3VyID0gY3VyLT5uZXh0OwogICAgfQogICAgZXZlbnQtPm5leHQgPSBjdXI7CiAgICBpZiAocHJldikgcHJldi0+bmV4dCA9IGV2ZW50OwogICAgZWxzZSBwZW5kaW5nX2V2ZW50ID0gZXZlbnQ7CgogICAgaWYgKCFvbGRfcGVuZGluZyAmJiBET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCkpIHsKICAgICAgVFJBQ0UoIm5ldyBldmVudCBxdWV1ZWQsIHNpZ25hbGxpbmcgKHRpbWU9JWQpXG4iLCBHZXRUaWNrQ291bnQoKSk7CiAgICAgIAogICAgICAvKiBBbGVydCBWTTg2IHRocmVhZCBhYm91dCB0aGUgbmV3IGV2ZW50LiAqLwogICAgICBraWxsKGRvc3ZtX3BpZCxTSUdVU1IyKTsKCiAgICAgIC8qIFdha2UgdXAgRE9TVk1fV2FpdCBzbyB0aGF0IGl0IGNhbiBzZXJ2ZSBwZW5kaW5nIGV2ZW50cy4gKi8KICAgICAgU2V0RXZlbnQoZXZlbnRfbm90aWZpZXIpOwogICAgfSBlbHNlIHsKICAgICAgVFJBQ0UoIm5ldyBldmVudCBxdWV1ZWQgKHRpbWU9JWQpXG4iLCBHZXRUaWNrQ291bnQoKSk7CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICB9IGVsc2UgewogICAgLyogRE9TIHN1YnN5c3RlbSBub3QgcnVubmluZyAqLwogICAgLyogKHRoaXMgcHJvYmFibHkgbWVhbnMgdGhhdCB3ZSdyZSBydW5uaW5nIGEgd2luMTYgYXBwCiAgICAgKiAgd2hpY2ggdXNlcyBEUE1JIHRvIHRodW5rIGRvd24gdG8gRE9TIHNlcnZpY2VzKSAqLwogICAgaWYgKGlycTwwKSB7CiAgICAgIC8qIGNhbGxiYWNrIGV2ZW50LCBwZXJmb3JtIGl0IHdpdGggZHVtbXkgY29udGV4dCAqLwogICAgICBDT05URVhUODYgY29udGV4dDsKICAgICAgbWVtc2V0KCZjb250ZXh0LDAsc2l6ZW9mKGNvbnRleHQpKTsKICAgICAgKCpyZWxheSkoJmNvbnRleHQsZGF0YSk7CiAgICB9IGVsc2UgewogICAgICBFUlIoIklSUSB3aXRob3V0IERPUyB0YXNrOiBzaG91bGQgbm90IGhhcHBlblxuIik7CiAgICB9CiAgfQp9CgpzdGF0aWMgdm9pZCBET1NWTV9Qcm9jZXNzQ29uc29sZSh2b2lkKQp7CiAgSU5QVVRfUkVDT1JEIG1zZzsKICBEV09SRCByZXM7CiAgQllURSBzY2FuLCBhc2NpaTsKCiAgaWYgKFJlYWRDb25zb2xlSW5wdXRBKEdldFN0ZEhhbmRsZShTVERfSU5QVVRfSEFORExFKSwmbXNnLDEsJnJlcykpIHsKICAgIHN3aXRjaCAobXNnLkV2ZW50VHlwZSkgewogICAgY2FzZSBLRVlfRVZFTlQ6CiAgICAgIHNjYW4gPSBtc2cuRXZlbnQuS2V5RXZlbnQud1ZpcnR1YWxTY2FuQ29kZTsKICAgICAgYXNjaWkgPSBtc2cuRXZlbnQuS2V5RXZlbnQudUNoYXIuQXNjaWlDaGFyOwogICAgICBUUkFDRSgic2NhbiAlMDJ4LCBhc2NpaSAlMDJ4XG4iLCBzY2FuLCBhc2NpaSk7CgogICAgICAvKiBzZXQgdGhlICJicmVhayIgKHJlbGVhc2UpIGZsYWcgaWYga2V5IHJlbGVhc2VkICovCiAgICAgIGlmICghbXNnLkV2ZW50LktleUV2ZW50LmJLZXlEb3duKSBzY2FuIHw9IDB4ODA7CgogICAgICAvKiBjaGVjayB3aGV0aGVyIGV4dGVuZGVkIGJpdCBpcyBzZXQsCiAgICAgICAqIGFuZCBpZiBzbywgcXVldWUgdGhlIGV4dGVuc2lvbiBwcmVmaXggKi8KICAgICAgaWYgKG1zZy5FdmVudC5LZXlFdmVudC5kd0NvbnRyb2xLZXlTdGF0ZSAmIEVOSEFOQ0VEX0tFWSkgewogICAgICAgIERPU1ZNX0ludDA5U2VuZFNjYW4oMHhFMCwwKTsKICAgICAgfQogICAgICBET1NWTV9JbnQwOVNlbmRTY2FuKHNjYW4sIGFzY2lpKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIE1PVVNFX0VWRU5UOgogICAgICBET1NWTV9JbnQzM0NvbnNvbGUoJm1zZy5FdmVudC5Nb3VzZUV2ZW50KTsKICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkRPV19CVUZGRVJfU0laRV9FVkVOVDoKICAgICAgRklYTUUoInVuaGFuZGxlZCBXSU5ET1dfQlVGRkVSX1NJWkVfRVZFTlQuXG4iKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIE1FTlVfRVZFTlQ6CiAgICAgIEZJWE1FKCJ1bmhhbmRsZWQgTUVOVV9FVkVOVC5cbiIpOwogICAgICBicmVhazsKICAgIGNhc2UgRk9DVVNfRVZFTlQ6CiAgICAgIEZJWE1FKCJ1bmhhbmRsZWQgRk9DVVNfRVZFTlQuXG4iKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBGSVhNRSgidW5rbm93biBjb25zb2xlIGV2ZW50OiAlZFxuIiwgbXNnLkV2ZW50VHlwZSk7CiAgICB9CiAgfQp9CgpzdGF0aWMgdm9pZCBET1NWTV9Qcm9jZXNzTWVzc2FnZShNU0cgKm1zZykKewogIEJZVEUgc2NhbiA9IDA7CgogIFRSQUNFKCJnb3QgbWVzc2FnZSAlMDR4LCB3cGFyYW09JTA4bHgsIGxwYXJhbT0lMDhseFxuIixtc2ctPm1lc3NhZ2UsbXNnLT53UGFyYW0sbXNnLT5sUGFyYW0pOwogIGlmICgobXNnLT5tZXNzYWdlPj1XTV9NT1VTRUZJUlNUKSYmCiAgICAgIChtc2ctPm1lc3NhZ2U8PVdNX01PVVNFTEFTVCkpIHsKICAgIERPU1ZNX0ludDMzTWVzc2FnZShtc2ctPm1lc3NhZ2UsbXNnLT53UGFyYW0sbXNnLT5sUGFyYW0pOwogIH0gZWxzZSB7CiAgICBzd2l0Y2ggKG1zZy0+bWVzc2FnZSkgewogICAgY2FzZSBXTV9LRVlVUDoKICAgICAgc2NhbiA9IDB4ODA7CiAgICBjYXNlIFdNX0tFWURPV046CiAgICAgIHNjYW4gfD0gKG1zZy0+bFBhcmFtID4+IDE2KSAmIDB4N2Y7CgogICAgICAvKiBjaGVjayB3aGV0aGVyIGV4dGVuZGVkIGJpdCBpcyBzZXQsCiAgICAgICAqIGFuZCBpZiBzbywgcXVldWUgdGhlIGV4dGVuc2lvbiBwcmVmaXggKi8KICAgICAgaWYgKG1zZy0+bFBhcmFtICYgMHgxMDAwMDAwKSB7CgkvKiBGSVhNRTogc29tZSBrZXlzIChmdW5jdGlvbiBrZXlzKSBoYXZlCgkgKiBleHRlbmRlZCBiaXQgc2V0IGV2ZW4gd2hlbiB0aGV5IHNob3VsZG4ndCwKCSAqIHNob3VsZCBjaGVjayBmb3IgdGhlbSAqLwoJRE9TVk1fSW50MDlTZW5kU2NhbigweEUwLDApOwogICAgICB9CiAgICAgIERPU1ZNX0ludDA5U2VuZFNjYW4oc2NhbiwwKTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlET1NWTV9XYWl0CiAqCiAqIFdhaXQgZm9yIGFzeW5jaHJvbm91cyBldmVudHMuIFRoaXMgcm91dGluZSB0ZW1wb3JhcmlseSBlbmFibGVzCiAqIGludGVycnVwdHMgYW5kIHdhaXRzIHVudGlsIHNvbWUgYXN5bmNocm9ub3VzIGV2ZW50IGhhcyBiZWVuIAogKiBwcm9jZXNzZWQuCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9XYWl0KCBDT05URVhUODYgKndhaXRjdHggKQp7CiAgICBpZiAoRE9TVk1fSGFzUGVuZGluZ0V2ZW50cygpKQogICAgewogICAgICAgIENPTlRFWFQ4NiBjb250ZXh0ID0gKndhaXRjdHg7CiAgICAgICAgCiAgICAgICAgLyoKICAgICAgICAgKiBJZiBET1NWTV9XYWl0IGlzIGNhbGxlZCBmcm9tIHByb3RlY3RlZCBtb2RlIHdlIGVtdWxhdGUKICAgICAgICAgKiBpbnRlcnJ1cHQgcmVmbGVjdGlvbiBhbmQgY29udmVydCBjb250ZXh0IGludG8gcmVhbCBtb2RlIGNvbnRleHQuCiAgICAgICAgICogVGhpcyBpcyBhY3R1YWxseSB0aGUgY29ycmVjdCB0aGluZyB0byBkbyBhcyBsb25nIGFzIERPU1ZNX1dhaXQKICAgICAgICAgKiBpcyBvbmx5IGNhbGxlZCBmcm9tIHRob3NlIGludGVycnVwdCBmdW5jdGlvbnMgdGhhdCBEUE1JIHJlZmxlY3RzCiAgICAgICAgICogdG8gcmVhbCBtb2RlLgogICAgICAgICAqCiAgICAgICAgICogRklYTUU6IE5lZWQgdG8gdGhpbmsgYWJvdXQgd2hlcmUgdG8gcGxhY2UgcmVhbCBtb2RlIHN0YWNrLgogICAgICAgICAqIEZJWE1FOiBJZiBET1NWTV9XYWl0IGNhbGxzIGFyZSBuZXN0ZWQgc3RhY2sgZ2V0cyBjb3JydXB0ZWQuCiAgICAgICAgICogICAgICAgIENhbiB0aGlzIHJlYWxseSBoYXBwZW4/CiAgICAgICAgICovCiAgICAgICAgaWYgKCFJU1Y4NigmY29udGV4dCkpCiAgICAgICAgewogICAgICAgICAgICBjb250ZXh0LkVGbGFncyB8PSBWODZfRkxBRzsKICAgICAgICAgICAgY29udGV4dC5TZWdTcyA9IDB4ZmZmZjsKICAgICAgICAgICAgY29udGV4dC5Fc3AgPSAwOwogICAgICAgIH0KCiAgICAgICAgY29udGV4dC5FRmxhZ3MgfD0gVklGX01BU0s7CiAgICAgICAgY29udGV4dC5TZWdDcyA9IDA7CiAgICAgICAgY29udGV4dC5FaXAgPSAwOwoKICAgICAgICBET1NWTV9TZW5kUXVldWVkRXZlbnRzKCZjb250ZXh0KTsKCiAgICAgICAgaWYoY29udGV4dC5TZWdDcyB8fCBjb250ZXh0LkVpcCkKICAgICAgICAgICAgRFBNSV9DYWxsUk1Qcm9jKCAmY29udGV4dCwgTlVMTCwgMCwgVFJVRSApOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIEhBTkRMRSBvYmpzWzJdOwogICAgICAgIGludCAgICBvYmpjID0gRE9TVk1fSXNXaW4xNigpID8gMiA6IDE7CiAgICAgICAgRFdPUkQgIHdhaXRyZXQ7CgogICAgICAgIG9ianNbMF0gPSBldmVudF9ub3RpZmllcjsKICAgICAgICBvYmpzWzFdID0gR2V0U3RkSGFuZGxlKFNURF9JTlBVVF9IQU5ETEUpOwoKICAgICAgICB3YWl0cmV0ID0gTXNnV2FpdEZvck11bHRpcGxlT2JqZWN0cyggb2JqYywgb2JqcywgRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTkZJTklURSwgUVNfQUxMSU5QVVQgKTsKICAgICAgICAKICAgICAgICBpZiAod2FpdHJldCA9PSBXQUlUX09CSkVDVF8wKQogICAgICAgIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogTmV3IHBlbmRpbmcgZXZlbnQgaGFzIGJlZW4gcXVldWVkLCB3ZSBpZ25vcmUgaXQKICAgICAgICAgICAgICogaGVyZSBiZWNhdXNlIGl0IHdpbGwgYmUgcHJvY2Vzc2VkIG9uIG5leHQgY2FsbCB0bwogICAgICAgICAgICAgKiBET1NWTV9XYWl0LgogICAgICAgICAgICAgKi8KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAob2JqYyA9PSAyICYmIHdhaXRyZXQgPT0gV0FJVF9PQkpFQ1RfMCArIDEpCiAgICAgICAgewogICAgICAgICAgICBET1NWTV9Qcm9jZXNzQ29uc29sZSgpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICh3YWl0cmV0ID09IFdBSVRfT0JKRUNUXzAgKyBvYmpjKQogICAgICAgIHsKICAgICAgICAgICAgTVNHIG1zZzsKICAgICAgICAgICAgd2hpbGUgKFBlZWtNZXNzYWdlQSgmbXNnLDAsMCwwLFBNX1JFTU9WRXxQTV9OT1lJRUxEKSkgCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIGdvdCBhIG1lc3NhZ2UgKi8KICAgICAgICAgICAgICAgIERPU1ZNX1Byb2Nlc3NNZXNzYWdlKCZtc2cpOwogICAgICAgICAgICAgICAgLyogd2UgZG9uJ3QgbmVlZCBhIFRyYW5zbGF0ZU1lc3NhZ2UgaGVyZSAqLwogICAgICAgICAgICAgICAgRGlzcGF0Y2hNZXNzYWdlQSgmbXNnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBFUlJfKG1vZHVsZSkoICJkb3N2bSB3YWl0IGVycm9yPSVkXG4iLCBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIH0KICAgIH0KfQoKCkRXT1JEIFdJTkFQSSBET1NWTV9Mb29wKCBIQU5ETEUgaFRocmVhZCApCnsKICBIQU5ETEUgb2Jqc1syXTsKICBNU0cgbXNnOwogIERXT1JEIHdhaXRyZXQ7CgogIG9ianNbMF0gPSBHZXRTdGRIYW5kbGUoU1REX0lOUFVUX0hBTkRMRSk7CiAgb2Jqc1sxXSA9IGhUaHJlYWQ7CgogIGZvcig7OykgewogICAgICBUUkFDRV8oaW50KSgid2FpdGluZyBmb3IgYWN0aW9uXG4iKTsKICAgICAgd2FpdHJldCA9IE1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHMoMiwgb2JqcywgRkFMU0UsIElORklOSVRFLCBRU19BTExJTlBVVCk7CiAgICAgIGlmICh3YWl0cmV0ID09IFdBSVRfT0JKRUNUXzApIHsKICAgICAgICAgIERPU1ZNX1Byb2Nlc3NDb25zb2xlKCk7CiAgICAgIH0KICAgICAgZWxzZSBpZiAod2FpdHJldCA9PSBXQUlUX09CSkVDVF8wICsgMSkgewogICAgICAgICBEV09SRCBydjsKICAgICAgICAgaWYoIUdldEV4aXRDb2RlVGhyZWFkKGhUaHJlYWQsICZydikpIHsKICAgICAgICAgICAgIEVSUigiRmFpbGVkIHRvIGdldCB0aHJlYWQgZXhpdCBjb2RlIVxuIik7CiAgICAgICAgICAgICBydiA9IDA7CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIHJ2OwogICAgICB9CiAgICAgIGVsc2UgaWYgKHdhaXRyZXQgPT0gV0FJVF9PQkpFQ1RfMCArIDIpIHsKICAgICAgICAgIHdoaWxlIChQZWVrTWVzc2FnZUEoJm1zZywwLDAsMCxQTV9SRU1PVkUpKSB7CiAgICAgICAgICAgICAgaWYgKG1zZy5od25kKSB7CiAgICAgICAgICAgICAgICAgIC8qIGl0J3MgYSB3aW5kb3cgbWVzc2FnZSAqLwogICAgICAgICAgICAgICAgICBET1NWTV9Qcm9jZXNzTWVzc2FnZSgmbXNnKTsKICAgICAgICAgICAgICAgICAgRGlzcGF0Y2hNZXNzYWdlQSgmbXNnKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAvKiBpdCdzIGEgdGhyZWFkIG1lc3NhZ2UgKi8KICAgICAgICAgICAgICAgICAgc3dpdGNoIChtc2cubWVzc2FnZSkgewogICAgICAgICAgICAgICAgICBjYXNlIFdNX1FVSVQ6CiAgICAgICAgICAgICAgICAgICAgICAvKiBzdG9wIHRoaXMgbWFkbmVzcyEhICovCiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgY2FzZSBXTV9VU0VSOgogICAgICAgICAgICAgICAgICAgICAgLyogcnVuIHBhc3NlZCBwcm9jZWR1cmUgaW4gdGhpcyB0aHJlYWQgKi8KICAgICAgICAgICAgICAgICAgICAgIC8qIChzb3J0IG9mIGxpa2UgQVBDLCBidXQgd2Ugc2lnbmFsIHRoZSBjb21wbGV0aW9uKSAqLwogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgIERPU19TUEMgKnNwYyA9IChET1NfU1BDICopbXNnLmxQYXJhbTsKICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRV8oaW50KSgiY2FsbGluZyAlcCB3aXRoIGFyZyAlMDhseFxuIiwgc3BjLT5wcm9jLCBzcGMtPmFyZyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgKHNwYy0+cHJvYykoc3BjLT5hcmcpOwogICAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFXyhpbnQpKCJkb25lLCBzaWduYWxsaW5nIGV2ZW50ICVseFxuIiwgbXNnLndQYXJhbSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0RXZlbnQoIChIQU5ETEUpbXNnLndQYXJhbSApOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICBEaXNwYXRjaE1lc3NhZ2VBKCZtc2cpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgICAgRVJSXyhpbnQpKCJNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzIHJldHVybmVkIHVuZXhwZWN0ZWQgdmFsdWUuXG4iKTsKICAgICAgICAgIHJldHVybiAwOwogICAgICB9CiAgfQp9CgpzdGF0aWMgV0lORV9FWENFUFRJT05fRklMVEVSKGV4Y2VwdGlvbl9oYW5kbGVyKQp7CiAgRVhDRVBUSU9OX1JFQ09SRCAqcmVjID0gR2V0RXhjZXB0aW9uSW5mb3JtYXRpb24oKS0+RXhjZXB0aW9uUmVjb3JkOwogIENPTlRFWFQgKmNvbnRleHQgPSBHZXRFeGNlcHRpb25JbmZvcm1hdGlvbigpLT5Db250ZXh0UmVjb3JkOwogIGludCBhcmcgPSByZWMtPkV4Y2VwdGlvbkluZm9ybWF0aW9uWzBdOwogIEJPT0wgcmV0OwoKICBzd2l0Y2gocmVjLT5FeGNlcHRpb25Db2RlKSB7CiAgY2FzZSBFWENFUFRJT05fVk04Nl9JTlR4OgogICAgVFJBQ0VfKHJlbGF5KSgiQ2FsbCBET1MgaW50IDB4JTAyeCByZXQ9JTA0eDolMDR4XG4iCiAgICAgICAgICAgICAgICAgICIgZWF4PSUwOHggZWJ4PSUwOHggZWN4PSUwOHggZWR4PSUwOHggZXNpPSUwOHggZWRpPSUwOHhcbiIKICAgICAgICAgICAgICAgICAgIiBlYnA9JTA4eCBlc3A9JTA4eCBkcz0lMDR4IGVzPSUwNHggZnM9JTA0eCBncz0lMDR4IGZsYWdzPSUwOHhcbiIsCiAgICAgICAgICAgICAgICAgIGFyZywgY29udGV4dC0+U2VnQ3MsIGNvbnRleHQtPkVpcCwKICAgICAgICAgICAgICAgICAgY29udGV4dC0+RWF4LCBjb250ZXh0LT5FYngsIGNvbnRleHQtPkVjeCwgY29udGV4dC0+RWR4LCBjb250ZXh0LT5Fc2ksIGNvbnRleHQtPkVkaSwKICAgICAgICAgICAgICAgICAgY29udGV4dC0+RWJwLCBjb250ZXh0LT5Fc3AsIGNvbnRleHQtPlNlZ0RzLCBjb250ZXh0LT5TZWdFcywgY29udGV4dC0+U2VnRnMsIGNvbnRleHQtPlNlZ0dzLAogICAgICAgICAgICAgICAgICBjb250ZXh0LT5FRmxhZ3MgKTsKICAgIHJldCA9IERPU1ZNX0VtdWxhdGVJbnRlcnJ1cHRSTSggY29udGV4dCwgYXJnICk7CiAgICBUUkFDRV8ocmVsYXkpKCJSZXQgIERPUyBpbnQgMHglMDJ4IHJldD0lMDR4OiUwNHhcbiIKICAgICAgICAgICAgICAgICAgIiBlYXg9JTA4eCBlYng9JTA4eCBlY3g9JTA4eCBlZHg9JTA4eCBlc2k9JTA4eCBlZGk9JTA4eFxuIgogICAgICAgICAgICAgICAgICAiIGVicD0lMDh4IGVzcD0lMDh4IGRzPSUwNHggZXM9JTA0eCBmcz0lMDR4IGdzPSUwNHggZmxhZ3M9JTA4eFxuIiwKICAgICAgICAgICAgICAgICAgYXJnLCBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwLAogICAgICAgICAgICAgICAgICBjb250ZXh0LT5FYXgsIGNvbnRleHQtPkVieCwgY29udGV4dC0+RWN4LCBjb250ZXh0LT5FZHgsIGNvbnRleHQtPkVzaSwgY29udGV4dC0+RWRpLAogICAgICAgICAgICAgICAgICBjb250ZXh0LT5FYnAsIGNvbnRleHQtPkVzcCwgY29udGV4dC0+U2VnRHMsIGNvbnRleHQtPlNlZ0VzLAogICAgICAgICAgICAgICAgICBjb250ZXh0LT5TZWdGcywgY29udGV4dC0+U2VnR3MsIGNvbnRleHQtPkVGbGFncyApOwogICAgcmV0dXJuIHJldCA/IEVYQ0VQVElPTl9DT05USU5VRV9FWEVDVVRJT04gOiBFWENFUFRJT05fRVhFQ1VURV9IQU5ETEVSOwoKICBjYXNlIEVYQ0VQVElPTl9WTTg2X1NUSToKICAvKiBjYXNlIEVYQ0VQVElPTl9WTTg2X1BJQ1JFVFVSTjogKi8KICAgIGlmICghSVNWODYoY29udGV4dCkpCiAgICAgIEVSUiggIlByb3RlY3RlZCBtb2RlIFNUSSBjYXVnaHQgYnkgcmVhbCBtb2RlIGhhbmRsZXIhXG4iICk7CiAgICBET1NWTV9TZW5kUXVldWVkRXZlbnRzKGNvbnRleHQpOwogICAgcmV0dXJuIEVYQ0VQVElPTl9DT05USU5VRV9FWEVDVVRJT047CiAgCiAgY2FzZSBFWENFUFRJT05fU0lOR0xFX1NURVA6CiAgICByZXQgPSBET1NWTV9FbXVsYXRlSW50ZXJydXB0Uk0oIGNvbnRleHQsIDEgKTsKICAgIHJldHVybiByZXQgPyBFWENFUFRJT05fQ09OVElOVUVfRVhFQ1VUSU9OIDogRVhDRVBUSU9OX0VYRUNVVEVfSEFORExFUjsKICAKICBjYXNlIEVYQ0VQVElPTl9CUkVBS1BPSU5UOgogICAgcmV0ID0gRE9TVk1fRW11bGF0ZUludGVycnVwdFJNKCBjb250ZXh0LCAzICk7CiAgICByZXR1cm4gcmV0ID8gRVhDRVBUSU9OX0NPTlRJTlVFX0VYRUNVVElPTiA6IEVYQ0VQVElPTl9FWEVDVVRFX0hBTkRMRVI7CiAgCiAgfQogIHJldHVybiBFWENFUFRJT05fQ09OVElOVUVfU0VBUkNIOwp9CgppbnQgV0lOQVBJIERPU1ZNX0VudGVyKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgaWYgKCFJU1Y4Nihjb250ZXh0KSkKICAgICAgRVJSKCAiQ2FsbGVkIHdpdGggcHJvdGVjdGVkIG1vZGUgY29udGV4dCFcbiIgKTsKCiAgX19UUlkKICB7CiAgICAgIFdPV0NhbGxiYWNrMTZFeCggMCwgV0NCMTZfUkVHUywgMCwgTlVMTCwgKERXT1JEICopY29udGV4dCApOwogICAgICBUUkFDRV8obW9kdWxlKSggInZtODYgcmV0dXJuZWQ6ICVzXG4iLCBzdHJlcnJvcihlcnJubykgKTsKICB9CiAgX19FWENFUFQoZXhjZXB0aW9uX2hhbmRsZXIpCiAgewogICAgVFJBQ0VfKG1vZHVsZSkoICJsZWF2aW5nIHZtODYgbW9kZVxuIiApOwogIH0KICBfX0VORFRSWQoKICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlPdXRQSUMgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIERPU1ZNX1BJQ19pb3BvcnRfb3V0KCBXT1JEIHBvcnQsIEJZVEUgdmFsKQp7CiAgICBpZiAocG9ydCAhPSAweDIwKQogICAgewogICAgICAgIEZJWE1FKCAiVW5zdXBwb3J0ZWQgUElDIHBvcnQgJTA0eFxuIiwgcG9ydCApOwogICAgfQogICAgZWxzZSBpZiAodmFsID09IDB4MjAgfHwgKHZhbCA+PSAweDYwICYmIHZhbCA8PSAweDY3KSkgCiAgICB7CiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKCiAgICAgICAgaWYgKCFjdXJyZW50X2V2ZW50KQogICAgICAgIHsKICAgICAgICAgICAgV0FSTiggIiVzIHdpdGhvdXQgYWN0aXZlIElSUVxuIiwKICAgICAgICAgICAgICAgICAgdmFsID09IDB4MjAgPyAiRU9JIiA6ICJTcGVjaWZpYyBFT0kiICk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHZhbCAhPSAweDIwICYmIHZhbCAtIDB4NjAgIT0gY3VycmVudF9ldmVudC0+aXJxKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTiggIlNwZWNpZmljIEVPSSBidXQgY3VycmVudCBJUlEgJWQgaXMgbm90ICVkXG4iLCAKICAgICAgICAgICAgICAgICAgY3VycmVudF9ldmVudC0+aXJxLCB2YWwgLSAweDYwICk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIExQRE9TRVZFTlQgZXZlbnQgPSBjdXJyZW50X2V2ZW50OwoKICAgICAgICAgICAgVFJBQ0UoICJSZWNlaXZlZCAlcyBmb3IgY3VycmVudCBJUlEgJWQsIGNsZWFyaW5nIGV2ZW50XG4iLAogICAgICAgICAgICAgICAgICAgdmFsID09IDB4MjAgPyAiRU9JIiA6ICJTcGVjaWZpYyBFT0kiLCBldmVudC0+aXJxICk7CgogICAgICAgICAgICBjdXJyZW50X2V2ZW50ID0gZXZlbnQtPm5leHQ7CiAgICAgICAgICAgIGlmIChldmVudC0+cmVsYXkpCiAgICAgICAgICAgICAgICAoKmV2ZW50LT5yZWxheSkoTlVMTCxldmVudC0+ZGF0YSk7CiAgICAgICAgICAgIGZyZWUoZXZlbnQpOwoKICAgICAgICAgICAgaWYgKERPU1ZNX0hhc1BlbmRpbmdFdmVudHMoKSkgCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFRSQUNFKCAiQW5vdGhlciBldmVudCBwZW5kaW5nLCBzZXR0aW5nIHBlbmRpbmcgZmxhZ1xuIiApOwogICAgICAgICAgICAgICAgTnRDdXJyZW50VGViKCktPnZtODZfcGVuZGluZyB8PSBWSVBfTUFTSzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgIH0gCiAgICBlbHNlIAogICAgewogICAgICAgIEZJWE1FKCAiVW5yZWNvZ25pemVkIFBJQyBjb21tYW5kICUwMnhcbiIsIHZhbCApOwogICAgfQp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVudGVyIChXSU5FRE9TLkApCiAqLwpJTlQgV0lOQVBJIERPU1ZNX0VudGVyKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiBFUlJfKG1vZHVsZSkoIkRPUyByZWFsbW9kZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlIVxuIik7CiByZXR1cm4gLTE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV2FpdCAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fV2FpdCggQ09OVEVYVDg2ICp3YWl0Y3R4ICkgeyB9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU91dFBJQyAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUElDX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwpIHt9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVF1ZXVlRXZlbnQgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIERPU1ZNX1F1ZXVlRXZlbnQoIElOVCBpcnEsIElOVCBwcmlvcml0eSwgRE9TUkVMQVkgcmVsYXksIExQVk9JRCBkYXRhKQp7CiAgaWYgKGlycTwwKSB7CiAgICAvKiBjYWxsYmFjayBldmVudCwgcGVyZm9ybSBpdCB3aXRoIGR1bW15IGNvbnRleHQgKi8KICAgIENPTlRFWFQ4NiBjb250ZXh0OwogICAgbWVtc2V0KCZjb250ZXh0LDAsc2l6ZW9mKGNvbnRleHQpKTsKICAgICgqcmVsYXkpKCZjb250ZXh0LGRhdGEpOwogIH0gZWxzZSB7CiAgICBFUlIoIklSUSB3aXRob3V0IERPUyB0YXNrOiBzaG91bGQgbm90IGhhcHBlblxuIik7CiAgfQp9CgojZW5kaWYgLyogTVpfU1VQUE9SVEVEICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICBET1NWTV9BY2tub3dsZWRnZUlSUQogKgogKiBUaGlzIHJvdXRpbmUgc2hvdWxkIGJlIGNhbGxlZCBieSBhbGwgaW50ZXJuYWwgSVJRIGhhbmRsZXJzLgogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fQWNrbm93bGVkZ2VJUlEoIENPTlRFWFQ4NiAqY29udGV4dCApCnsKICAgIC8qCiAgICAgKiBTZW5kIEVPSSB0byBQSUMuCiAgICAgKi8KICAgIERPU1ZNX1BJQ19pb3BvcnRfb3V0KCAweDIwLCAweDIwICk7CgogICAgLyoKICAgICAqIFByb3RlY3RlZCBtb2RlIElSUSBoYW5kbGVycyBhcmUgc3VwcG9zZWQKICAgICAqIHRvIHR1cm4gVklGIGZsYWcgb24gYmVmb3JlIHRoZXkgcmV0dXJuLgogICAgICovCiAgICBpZiAoIUlTVjg2KGNvbnRleHQpKQogICAgICAgIE50Q3VycmVudFRlYigpLT5kcG1pX3ZpZiA9IDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkgICAgRGxsTWFpbiAgKERPU1ZNLjApCiAqLwpCT09MIFdJTkFQSSBEbGxNYWluKCBISU5TVEFOQ0UgaGluc3RETEwsIERXT1JEIGZkd1JlYXNvbiwgTFBWT0lEIGxwdlJlc2VydmVkICkKewogICAgVFJBQ0VfKG1vZHVsZSkoIiglcCwlZCwlcClcbiIsIGhpbnN0RExMLCBmZHdSZWFzb24sIGxwdlJlc2VydmVkKTsKCiAgICBpZiAoZmR3UmVhc29uID09IERMTF9QUk9DRVNTX0FUVEFDSCkKICAgIHsKICAgICAgICBEaXNhYmxlVGhyZWFkTGlicmFyeUNhbGxzKGhpbnN0RExMKTsKICAgICAgICBpZiAoIURPU01FTV9Jbml0RG9zTWVtb3J5KCkpIHJldHVybiBGQUxTRTsKICAgICAgICBET1NWTV9Jbml0U2VnbWVudHMoKTsKCiAgICAgICAgZXZlbnRfbm90aWZpZXIgPSBDcmVhdGVFdmVudFcoTlVMTCwgRkFMU0UsIEZBTFNFLCBOVUxMKTsKICAgICAgICBpZighZXZlbnRfbm90aWZpZXIpCiAgICAgICAgICBFUlIoIkZhaWxlZCB0byBjcmVhdGUgZXZlbnQgb2JqZWN0IVxuIik7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQo=