Lyogdmk6c2V0IHRzPTggc3RzPTQgc3c9NDoKICoKICogVklNIC0gVmkgSU1wcm92ZWQJCWJ5IEJyYW0gTW9vbGVuYWFyCiAqCQkJCUdVSS9Nb3RpZiBzdXBwb3J0IGJ5IFJvYmVydCBXZWJiCiAqCiAqIERvICI6aGVscCB1Z2FuZGEiICBpbiBWaW0gdG8gcmVhZCBjb3B5aW5nIGFuZCB1c2FnZSBjb25kaXRpb25zLgogKiBEbyAiOmhlbHAgY3JlZGl0cyIgaW4gVmltIHRvIHNlZSBhIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZC4KICogU2VlIFJFQURNRS50eHQgZm9yIGFuIG92ZXJ2aWV3IG9mIHRoZSBWaW0gc291cmNlIGNvZGUuCiAqLwoKI2luY2x1ZGUgPFhtL0Zvcm0uaD4KI2luY2x1ZGUgPFhtL1Jvd0NvbHVtbi5oPgojaW5jbHVkZSA8WG0vUHVzaEIuaD4KI2luY2x1ZGUgPFhtL1RleHQuaD4KI2luY2x1ZGUgPFhtL1RleHRGLmg+CiNpbmNsdWRlIDxYbS9TZXBhcmF0b3IuaD4KI2luY2x1ZGUgPFhtL0xhYmVsLmg+CiNpbmNsdWRlIDxYbS9DYXNjYWRlQi5oPgojaW5jbHVkZSA8WG0vU2Nyb2xsQmFyLmg+CiNpbmNsdWRlIDxYbS9NZW51U2hlbGwuaD4KI2luY2x1ZGUgPFhtL0RyYXdpbmdBLmg+CiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCiMgaW5jbHVkZSA8WG0vUmVwVHlwZS5oPgojZW5kaWYKI2luY2x1ZGUgPFhtL0ZyYW1lLmg+CiNpbmNsdWRlIDxYbS9MYWJlbEcuaD4KI2luY2x1ZGUgPFhtL1RvZ2dsZUJHLmg+CiNpbmNsdWRlIDxYbS9TZXBhcmF0b0cuaD4KI2luY2x1ZGUgPFhtL1htUC5oPgoKI2luY2x1ZGUgPFgxMS9rZXlzeW0uaD4KI2luY2x1ZGUgPFgxMS9YYXRvbS5oPgojaW5jbHVkZSA8WDExL1N0cmluZ0RlZnMuaD4KI2luY2x1ZGUgPFgxMS9JbnRyaW5zaWMuaD4KCiNpbmNsdWRlICJ2aW0uaCIKCiNpZmRlZiBIQVZFX1gxMV9YUE1fSAojIGluY2x1ZGUgPFgxMS94cG0uaD4KI2Vsc2UKIyBpZmRlZiBIQVZFX1hNX1hQTVBfSAojICBpbmNsdWRlIDxYbS9YcG1QLmg+CiMgZW5kaWYKI2VuZGlmCiNpZmRlZiBIQVZFX1hNX05PVEVCT09LX0gKIyBpbmNsdWRlIDxYbS9Ob3RlYm9vay5oPgojZW5kaWYKCiNpbmNsdWRlICJndWlfeG1lYncuaCIJLyogZm9yIG91ciBFbmhhbmNlZCBCdXR0b24gV2lkZ2V0ICovCgojaWYgZGVmaW5lZChGRUFUX0dVSV9ESUFMT0cpICYmIGRlZmluZWQoSEFWRV9YUE0pCiMgaW5jbHVkZSAiLi4vcGl4bWFwcy9hbGVydC54cG0iCiMgaW5jbHVkZSAiLi4vcGl4bWFwcy9lcnJvci54cG0iCiMgaW5jbHVkZSAiLi4vcGl4bWFwcy9nZW5lcmljLnhwbSIKIyBpbmNsdWRlICIuLi9waXhtYXBzL2luZm8ueHBtIgojIGluY2x1ZGUgIi4uL3BpeG1hcHMvcXVlc3QueHBtIgojZW5kaWYKCiNkZWZpbmUgTU9USUZfUE9QVVAKCmV4dGVybiBXaWRnZXQgdmltU2hlbGw7CgpzdGF0aWMgV2lkZ2V0IHZpbUZvcm07CnN0YXRpYyBXaWRnZXQgdGV4dEFyZWFGb3JtOwpXaWRnZXQgdGV4dEFyZWE7CiNpZmRlZiBGRUFUX1RPT0xCQVIKc3RhdGljIFdpZGdldCB0b29sQmFyRnJhbWU7CnN0YXRpYyBXaWRnZXQgdG9vbEJhcjsKI2VuZGlmCiNpZmRlZiBGRUFUX0dVSV9UQUJMSU5FCnN0YXRpYyBXaWRnZXQJdGFiTGluZTsKc3RhdGljIFdpZGdldAl0YWJMaW5lX21lbnUgPSAwOwpzdGF0aWMgaW50CXNob3dpbmdfdGFibGluZSA9IDA7CiNlbmRpZgojaWZkZWYgRkVBVF9GT09URVIKc3RhdGljIFdpZGdldCBmb290ZXI7CiNlbmRpZgojaWZkZWYgRkVBVF9NRU5VCiMgaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQovKiByZW1lbWJlciB0aGUgbGFzdCBzZXQgdmFsdWUgZm9yIHRoZSB0ZWFyb2ZmIGl0ZW0gKi8Kc3RhdGljIGludCB0ZWFyb2ZmX3ZhbCA9IChpbnQpWG1URUFSX09GRl9FTkFCTEVEOwojIGVuZGlmCnN0YXRpYyBXaWRnZXQgbWVudUJhcjsKI2VuZGlmCgpzdGF0aWMgdm9pZCBzY3JvbGxfY2IgX19BUkdTKChXaWRnZXQgdywgWHRQb2ludGVyIGNsaWVudF9kYXRhLCBYdFBvaW50ZXIgY2FsbF9kYXRhKSk7CiNpZmRlZiBGRUFUX0dVSV9UQUJMSU5FCnN0YXRpYyB2b2lkIHRhYmxpbmVfY2IgX19BUkdTKChXaWRnZXQgdywgWHRQb2ludGVyIGNsaWVudF9kYXRhLCBYdFBvaW50ZXIgY2FsbF9kYXRhKSk7CnN0YXRpYyB2b2lkIHRhYmxpbmVfYnV0dG9uX2NiIF9fQVJHUygoV2lkZ2V0IHcsIFh0UG9pbnRlciBjbGllbnRfZGF0YSwgWHRQb2ludGVyIGNhbGxfZGF0YSkpOwpzdGF0aWMgdm9pZCB0YWJsaW5lX21lbnVfY2IgX19BUkdTKChXaWRnZXQgdywgWHRQb2ludGVyCWNsb3N1cmUsIFhFdmVudAkqZSwgQm9vbGVhbiAqY29udGludWVfZGlzcGF0Y2gpKTsKc3RhdGljIHZvaWQgdGFibGluZV9iYWxsb29uX2NiIF9fQVJHUygoQmFsbG9vbkV2YWwgKmJldmFsLCBpbnQgc3RhdGUpKTsKI2VuZGlmCiNpZmRlZiBGRUFUX1RPT0xCQVIKIyBpZmRlZiBGRUFUX0ZPT1RFUgpzdGF0aWMgdm9pZCB0b29sYmFyYnV0dG9uX2VudGVyX2NiIF9fQVJHUygoV2lkZ2V0LCBYdFBvaW50ZXIsIFhFdmVudCAqLCBCb29sZWFuICopKTsKc3RhdGljIHZvaWQgdG9vbGJhcmJ1dHRvbl9sZWF2ZV9jYiBfX0FSR1MoKFdpZGdldCwgWHRQb2ludGVyLCBYRXZlbnQgKiwgQm9vbGVhbiAqKSk7CiMgZW5kaWYKc3RhdGljIHZvaWQgcmVzZXRfZm9jdXMgX19BUkdTKCh2b2lkKSk7CiNlbmRpZgojaWZkZWYgRkVBVF9GT09URVIKc3RhdGljIGludCBndWlfbWNoX2NvbXB1dGVfZm9vdGVyX2hlaWdodCBfX0FSR1MoKHZvaWQpKTsKI2VuZGlmCiNpZmRlZiBXU0RFQlVHCnN0YXRpYyB2b2lkIGF0dGFjaER1bXAoV2lkZ2V0LCBjaGFyICopOwojZW5kaWYKCnN0YXRpYyB2b2lkIGd1aV9tb3RpZl9tZW51X2NvbG9ycyBfX0FSR1MoKFdpZGdldCBpZCkpOwpzdGF0aWMgdm9pZCBndWlfbW90aWZfc2Nyb2xsX2NvbG9ycyBfX0FSR1MoKFdpZGdldCBpZCkpOwoKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKIyBkZWZpbmUgU1RSSU5HX1RBRyAgWG1GT05UTElTVF9ERUZBVUxUX1RBRwojZWxzZQojIGRlZmluZSBTVFJJTkdfVEFHICBYbVNUUklOR19ERUZBVUxUX0NIQVJTRVQKI2VuZGlmCgovKgogKiBDYWxsLWJhY2sgcm91dGluZXMuCiAqLwoKLyogQVJHU1VTRUQgKi8KICAgIHN0YXRpYyB2b2lkCnNjcm9sbF9jYih3LCBjbGllbnRfZGF0YSwgY2FsbF9kYXRhKQogICAgV2lkZ2V0CXc7CiAgICBYdFBvaW50ZXIJY2xpZW50X2RhdGEsIGNhbGxfZGF0YTsKewogICAgc2Nyb2xsYmFyX1QgKnNiOwogICAgbG9uZwl2YWx1ZTsKICAgIGludAkJZHJhZ2dpbmc7CgogICAgc2IgPSBndWlfZmluZF9zY3JvbGxiYXIoKGxvbmcpY2xpZW50X2RhdGEpOwoKICAgIHZhbHVlID0gKChYbVNjcm9sbEJhckNhbGxiYWNrU3RydWN0ICopY2FsbF9kYXRhKS0+dmFsdWU7CiAgICBkcmFnZ2luZyA9ICgoKFhtU2Nyb2xsQmFyQ2FsbGJhY2tTdHJ1Y3QgKiljYWxsX2RhdGEpLT5yZWFzb24gPT0KCQkJCQkJCSAgICAgIChpbnQpWG1DUl9EUkFHKTsKICAgIGd1aV9kcmFnX3Njcm9sbGJhcihzYiwgdmFsdWUsIGRyYWdnaW5nKTsKfQoKI2lmZGVmIEZFQVRfR1VJX1RBQkxJTkUKLypBUkdTVVNFRCovCiAgICBzdGF0aWMgdm9pZAp0YWJsaW5lX2NiKHcsIGNsaWVudF9kYXRhLCBjYWxsX2RhdGEpCiAgICBXaWRnZXQJdzsKICAgIFh0UG9pbnRlcgljbGllbnRfZGF0YSwgY2FsbF9kYXRhOwp7CiAgICBYbU5vdGVib29rQ2FsbGJhY2tTdHJ1Y3QgKm5wdHI7CgogICAgbnB0ciA9IChYbU5vdGVib29rQ2FsbGJhY2tTdHJ1Y3QgKiljYWxsX2RhdGE7CiAgICBpZiAobnB0ci0+cmVhc29uICE9IChpbnQpWG1DUl9OT05FKQoJc2VuZF90YWJsaW5lX2V2ZW50KG5wdHItPnBhZ2VfbnVtYmVyKTsKfQoKLypBUkdTVVNFRCovCiAgICBzdGF0aWMgdm9pZAp0YWJsaW5lX2J1dHRvbl9jYih3LCBjbGllbnRfZGF0YSwgY2FsbF9kYXRhKQogICAgV2lkZ2V0CXc7CiAgICBYdFBvaW50ZXIJY2xpZW50X2RhdGEsIGNhbGxfZGF0YTsKewogICAgaW50CQljbWQsIHRhYl9pZHg7CgogICAgWHRWYUdldFZhbHVlcyh3LCBYbU51c2VyRGF0YSwgJmNtZCwgTlVMTCk7CiAgICBYdFZhR2V0VmFsdWVzKHRhYkxpbmVfbWVudSwgWG1OdXNlckRhdGEsICZ0YWJfaWR4LCBOVUxMKTsKCiAgICBzZW5kX3RhYmxpbmVfbWVudV9ldmVudCh0YWJfaWR4LCBjbWQpOwp9CgovKgogKiBUYWJsaW5lIHNpbmdsZSBtb3VzZSBjbGljayB0aW1lb3V0IGhhbmRsZXIKICovCi8qQVJHU1VTRUQqLwogICAgc3RhdGljIHZvaWQKbW90aWZfdGFibGluZV90aW1lcl9jYiAodGltZWRfb3V0LCBpbnRlcnZhbF9pZCkKICAgIFh0UG9pbnRlcgkJdGltZWRfb3V0OwogICAgWHRJbnRlcnZhbElkCSppbnRlcnZhbF9pZDsKewogICAgKigoaW50ICopdGltZWRfb3V0KSA9IFRSVUU7Cn0KCi8qCiAqIGNoZWNrIGlmIHRoZSB0YWJsaW5lIHRhYiBzY3JvbGxlciBpcyBjbGlja2VkCiAqLwogICAgc3RhdGljIGludAp0YWJsaW5lX3Njcm9sbGVyX2NsaWNrZWQoc2Nyb2xsZXJfbmFtZSwgZXZlbnQpCiAgICBjaGFyCQkqc2Nyb2xsZXJfbmFtZTsKICAgIFhCdXR0b25QcmVzc2VkRXZlbnQgKmV2ZW50Owp7CiAgICBXaWRnZXQJdGFiX3Njcm9sbF93OwogICAgUG9zaXRpb24JcG9zX3gsIHBvc195OwogICAgRGltZW5zaW9uCXdpZHRoLCBoZWlnaHQ7CgogICAgdGFiX3Njcm9sbF93ID0gWHROYW1lVG9XaWRnZXQodGFiTGluZSwgc2Nyb2xsZXJfbmFtZSk7CiAgICBpZiAodGFiX3Njcm9sbF93ICE9IChXaWRnZXQpMCkgewoJWHRWYUdldFZhbHVlcyh0YWJfc2Nyb2xsX3csIFhtTngsICZwb3NfeCwgWG1OeSwgJnBvc195LCBYbU53aWR0aCwKCQkgICAgICAmd2lkdGgsIFhtTmhlaWdodCwgJmhlaWdodCwgTlVMTCk7CglpZiAocG9zX3ggPj0gMCkgewoJICAgIC8qIFRhYiBzY3JvbGxlciAobmV4dCkgaXMgdmlzaWJsZSAqLwoJICAgIGlmICgoZXZlbnQtPnggPj0gcG9zX3gpICYmIChldmVudC0+eCA8PSBwb3NfeCArIHdpZHRoKSAmJgoJCShldmVudC0+eSA+PSBwb3NfeSkgJiYgKGV2ZW50LT55IDw9IHBvc195ICsgaGVpZ2h0KSkgewoJCS8qIENsaWNrZWQgb24gdGhlIHNjcm9sbGVyICovCgkJcmV0dXJuIFRSVUU7CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuIEZBTFNFOwp9CgovKkFSR1NVU0VEKi8KICAgIHN0YXRpYyB2b2lkCnRhYmxpbmVfbWVudV9jYih3LCBjbG9zdXJlLCBlLCBjb250aW51ZV9kaXNwYXRjaCkKICAgIFdpZGdldAl3OwogICAgWHRQb2ludGVyCWNsb3N1cmU7CiAgICBYRXZlbnQJKmU7CiAgICBCb29sZWFuCSpjb250aW51ZV9kaXNwYXRjaDsKewogICAgV2lkZ2V0CQkJdGFiX3c7CiAgICBYQnV0dG9uUHJlc3NlZEV2ZW50CQkqZXZlbnQ7CiAgICBpbnQJCQkJdGFiX2lkeCA9IDA7CiAgICBXaWRnZXRMaXN0CQkJY2hpbGRyZW47CiAgICBDYXJkaW5hbAkJCW51bUNoaWxkcmVuOwogICAgc3RhdGljIFh0SW50ZXJ2YWxJZAkJdGltZXIgPSAoWHRJbnRlcnZhbElkKTA7CiAgICBzdGF0aWMgaW50CQkJdGltZWRfb3V0ID0gVFJVRTsKCiAgICBldmVudCA9IChYQnV0dG9uUHJlc3NlZEV2ZW50ICopZTsKCiAgICBpZiAoZXZlbnQtPmJ1dHRvbiA9PSBCdXR0b24xKQogICAgewoJaWYgKHRhYmxpbmVfc2Nyb2xsZXJfY2xpY2tlZCgiTWFqb3JUYWJTY3JvbGxlck5leHQiLCBldmVudCkKCSAgICB8fCB0YWJsaW5lX3Njcm9sbGVyX2NsaWNrZWQoIk1ham9yVGFiU2Nyb2xsZXJQcmV2aW91cyIsIGV2ZW50KSkKCSAgICByZXR1cm47CgoJaWYgKCF0aW1lZF9vdXQpCgl7CgkgICAgWHRSZW1vdmVUaW1lT3V0KHRpbWVyKTsKCSAgICB0aW1lZF9vdXQgPSBUUlVFOwoKCSAgICAvKgoJICAgICAqIERvdWJsZSBjbGljayBvbiB0aGUgdGFibGluZSBndXR0ZXIsIGFkZCBhIG5ldyB0YWIKCSAgICAgKi8KCSAgICBzZW5kX3RhYmxpbmVfbWVudV9ldmVudCgwLCBUQUJMSU5FX01FTlVfTkVXKTsKCX0KCWVsc2UKCXsKCSAgICAvKgoJICAgICAqIFNpbmdsZSBjbGljayBvbiB0aGUgdGFibGluZSBndXR0ZXIsIHN0YXJ0IGEgdGltZXIgdG8gY2hlY2sKCSAgICAgKiBmb3IgZG91YmxlIGNsaWNrcwoJICAgICAqLwoJICAgIHRpbWVyID0gWHRBcHBBZGRUaW1lT3V0KGFwcF9jb250ZXh0LCAobG9uZ191KXBfbW91c2V0LAoJCQkJICAgIG1vdGlmX3RhYmxpbmVfdGltZXJfY2IsICZ0aW1lZF9vdXQpOwoJICAgIHRpbWVkX291dCA9IEZBTFNFOwoJfQoJcmV0dXJuOwogICAgfQoKICAgIGlmIChldmVudC0+YnV0dG9uICE9IEJ1dHRvbjMpCglyZXR1cm47CgogICAgLyogV2hlbiBpZ25vcmluZyBldmVudHMgZG9uJ3Qgc2hvdyB0aGUgbWVudS4gKi8KICAgIGlmIChob2xkX2d1aV9ldmVudHMKIyBpZmRlZiBGRUFUX0NNRFdJTgoJICAgIHx8IGNtZHdpbl90eXBlICE9IDAKIyBlbmRpZgogICAgICAgKQoJcmV0dXJuOwoKICAgIGlmIChldmVudC0+c3Vid2luZG93ICE9IE5vbmUpCiAgICB7Cgl0YWJfdyA9IFh0V2luZG93VG9XaWRnZXQoWHREaXNwbGF5KHcpLCBldmVudC0+c3Vid2luZG93KTsKCS8qIExJTlRFRDogYXZvaWQgd2FybmluZzogZHViaW91cyBvcGVyYXRpb24gb24gZW51bSAqLwoJaWYgKHRhYl93ICE9IChXaWRnZXQpMCAmJiBYbUlzUHVzaEJ1dHRvbih0YWJfdykpCgkgICAgWHRWYUdldFZhbHVlcyh0YWJfdywgWG1OcGFnZU51bWJlciwgJnRhYl9pZHgsIE5VTEwpOwogICAgfQoKICAgIFh0VmFTZXRWYWx1ZXModGFiTGluZV9tZW51LCBYbU51c2VyRGF0YSwgdGFiX2lkeCwgTlVMTCk7CiAgICBYdFZhR2V0VmFsdWVzKHRhYkxpbmVfbWVudSwgWG1OY2hpbGRyZW4sICZjaGlsZHJlbiwgWG1ObnVtQ2hpbGRyZW4sCgkJICAmbnVtQ2hpbGRyZW4sIE5VTEwpOwogICAgWHRNYW5hZ2VDaGlsZHJlbihjaGlsZHJlbiwgbnVtQ2hpbGRyZW4pOwogICAgWG1NZW51UG9zaXRpb24odGFiTGluZV9tZW51LCAoWEJ1dHRvblByZXNzZWRFdmVudCAqKWUpIDsKICAgIFh0TWFuYWdlQ2hpbGQodGFiTGluZV9tZW51KTsKfQoKLypBUkdTVVNFRCovCiAgICBzdGF0aWMgdm9pZAp0YWJsaW5lX2JhbGxvb25fY2IoYmV2YWwsIHN0YXRlKQogICAgQmFsbG9vbkV2YWwJKmJldmFsOwogICAgaW50CQlzdGF0ZTsKewogICAgaW50CQlucjsKICAgIHRhYnBhZ2VfVAkqdHA7CgogICAgaWYgKGJldmFsLT50YXJnZXQgPT0gKFdpZGdldCkwKQoJcmV0dXJuOwoKICAgIFh0VmFHZXRWYWx1ZXMoYmV2YWwtPnRhcmdldCwgWG1OcGFnZU51bWJlciwgJm5yLCBOVUxMKTsKICAgIHRwID0gZmluZF90YWJwYWdlKG5yKTsKICAgIGlmICh0cCA9PSBOVUxMKQoJcmV0dXJuOwoKICAgIGdldF90YWJsaW5lX2xhYmVsKHRwLCBUUlVFKTsKICAgIGd1aV9tY2hfcG9zdF9iYWxsb29uKGJldmFsLCBOYW1lQnVmZik7Cn0KCiNlbmRpZgoKLyoKICogRW5kIG9mIGNhbGwtYmFjayByb3V0aW5lcwogKi8KCi8qCiAqIEltcGxlbWVudCB0aHJlZSBkaW1lbnNpb25hbCBzaGFkaW5nIG9mIGluc2Vuc2l0aXZlIGxhYmVscy4KICogQnkgTWFyY2luIERhbGVja2kuCiAqLwoKI2luY2x1ZGUgPFhtL1htUC5oPgojaW5jbHVkZSA8WG0vTGFiZWxQLmg+CgpzdGF0aWMgWHRFeHBvc2VQcm9jIG9sZF9sYWJlbF9leHBvc2UgPSBOVUxMOwoKc3RhdGljIHZvaWQgbGFiZWxfZXhwb3NlIF9fQVJHUygoV2lkZ2V0IF93LCBYRXZlbnQgKl9ldmVudCwgUmVnaW9uIF9yZWdpb24pKTsKCiAgICBzdGF0aWMgdm9pZApsYWJlbF9leHBvc2UoX3csIF9ldmVudCwgX3JlZ2lvbikKICAgIFdpZGdldAlfdzsKICAgIFhFdmVudAkqX2V2ZW50OwogICAgUmVnaW9uCV9yZWdpb247CnsKICAgIEdDCQkgICAgaW5zZW5zaXRpdmVHQzsKICAgIFhtTGFiZWxXaWRnZXQgICBsdyA9IChYbUxhYmVsV2lkZ2V0KV93OwogICAgdW5zaWduZWQgY2hhciAgIGxhYmVsX3R5cGUgPSAoaW50KVhtU1RSSU5HOwoKICAgIFh0VmFHZXRWYWx1ZXMoX3csIFhtTmxhYmVsVHlwZSwgJmxhYmVsX3R5cGUsIChYdFBvaW50ZXIpMCk7CgogICAgaWYgKFh0SXNTZW5zaXRpdmUoX3cpIHx8IGxhYmVsX3R5cGUgIT0gKGludClYbVNUUklORykKCSgqb2xkX2xhYmVsX2V4cG9zZSkoX3csIF9ldmVudCwgX3JlZ2lvbik7CiAgICBlbHNlCiAgICB7CglYR0NWYWx1ZXMgICB2YWx1ZXM7CglYdEdDTWFzayAgICBtYXNrOwoJWHRHQ01hc2sgICAgZHluYW1pYzsKCVhGb250U3RydWN0ICpmczsKCglfWG1Gb250TGlzdEdldERlZmF1bHRGb250KGx3LT5sYWJlbC5mb250LCAmZnMpOwoKCS8qIEZJWE1FOiB3ZSBzaG91bGQgYmUgZG9pbmcgdGhlIHdob2xlIGRyYXdpbmcgb3Vyc2VsZiBoZXJlLiAqLwoJaW5zZW5zaXRpdmVHQyA9IGx3LT5sYWJlbC5pbnNlbnNpdGl2ZV9HQzsKCgltYXNrID0gR0NGb3JlZ3JvdW5kIHwgR0NCYWNrZ3JvdW5kIHwgR0NHcmFwaGljc0V4cG9zdXJlczsKCWR5bmFtaWMgPSBHQ0NsaXBNYXNrIHwgR0NDbGlwWE9yaWdpbiB8IEdDQ2xpcFlPcmlnaW47Cgl2YWx1ZXMuZ3JhcGhpY3NfZXhwb3N1cmVzID0gRmFsc2U7CgoJaWYgKGZzICE9IDApCgl7CgkgICAgbWFzayB8PSBHQ0ZvbnQ7CgkgICAgdmFsdWVzLmZvbnQgPSBmcy0+ZmlkOwoJfQoKCWlmIChsdy0+cHJpbWl0aXZlLnRvcF9zaGFkb3dfcGl4bWFwICE9IE5vbmUKCQkmJiBsdy0+cHJpbWl0aXZlLnRvcF9zaGFkb3dfcGl4bWFwICE9IFhtVU5TUEVDSUZJRURfUElYTUFQKQoJewoJICAgIG1hc2sgfD0gR0NGaWxsU3R5bGUgfCBHQ1RpbGU7CgkgICAgdmFsdWVzLmZpbGxfc3R5bGUgPSBGaWxsVGlsZWQ7CgkgICAgdmFsdWVzLnRpbGUgPSBsdy0+cHJpbWl0aXZlLnRvcF9zaGFkb3dfcGl4bWFwOwoJfQoKCWx3LT5sYWJlbC5UZXh0UmVjdC54ICs9IDE7Cglsdy0+bGFiZWwuVGV4dFJlY3QueSArPSAxOwoJaWYgKGx3LT5sYWJlbC5fYWNjX3RleHQgIT0gMCkKCXsKCSAgICBsdy0+bGFiZWwuYWNjX1RleHRSZWN0LnggKz0gMTsKCSAgICBsdy0+bGFiZWwuYWNjX1RleHRSZWN0LnkgKz0gMTsKCX0KCgl2YWx1ZXMuZm9yZWdyb3VuZCA9IGx3LT5wcmltaXRpdmUudG9wX3NoYWRvd19jb2xvcjsKCXZhbHVlcy5iYWNrZ3JvdW5kID0gbHctPmNvcmUuYmFja2dyb3VuZF9waXhlbDsKCglsdy0+bGFiZWwuaW5zZW5zaXRpdmVfR0MgPSBYdEFsbG9jYXRlR0MoKFdpZGdldClsdywgMCwgbWFzaywKCQkJCQkgICAgICAgJnZhbHVlcywgZHluYW1pYywgKFh0R0NNYXNrKTApOwoJKCpvbGRfbGFiZWxfZXhwb3NlKShfdywgX2V2ZW50LCBfcmVnaW9uKTsKCVh0UmVsZWFzZUdDKF93LCBsdy0+bGFiZWwuaW5zZW5zaXRpdmVfR0MpOwoKCWx3LT5sYWJlbC5UZXh0UmVjdC54IC09IDE7Cglsdy0+bGFiZWwuVGV4dFJlY3QueSAtPSAxOwoJaWYgKGx3LT5sYWJlbC5fYWNjX3RleHQgIT0gMCkKCXsKCSAgICBsdy0+bGFiZWwuYWNjX1RleHRSZWN0LnggLT0gMTsKCSAgICBsdy0+bGFiZWwuYWNjX1RleHRSZWN0LnkgLT0gMTsKCX0KCgl2YWx1ZXMuZm9yZWdyb3VuZCA9IGx3LT5wcmltaXRpdmUuYm90dG9tX3NoYWRvd19jb2xvcjsKCXZhbHVlcy5iYWNrZ3JvdW5kID0gbHctPmNvcmUuYmFja2dyb3VuZF9waXhlbDsKCglsdy0+bGFiZWwuaW5zZW5zaXRpdmVfR0MgPSBYdEFsbG9jYXRlR0MoKFdpZGdldCkgbHcsIDAsIG1hc2ssCgkJCQkJICAgICAgICZ2YWx1ZXMsIGR5bmFtaWMsIChYdEdDTWFzaykwKTsKCSgqb2xkX2xhYmVsX2V4cG9zZSkoX3csIF9ldmVudCwgX3JlZ2lvbik7CglYdFJlbGVhc2VHQyhfdywgbHctPmxhYmVsLmluc2Vuc2l0aXZlX0dDKTsKCglsdy0+bGFiZWwuaW5zZW5zaXRpdmVfR0MgPSBpbnNlbnNpdGl2ZUdDOwogICAgfQp9CgovKgogKiBDcmVhdGUgYWxsIHRoZSBtb3RpZiB3aWRnZXRzIG5lY2Vzc2FyeS4KICovCiAgICB2b2lkCmd1aV94MTFfY3JlYXRlX3dpZGdldHMoKQp7CiNpZmRlZiBGRUFUX0dVSV9UQUJMSU5FCiAgICBXaWRnZXQJYnV0dG9uLCBzY3JvbGxlcjsKICAgIEFyZwkJYXJnc1sxMF07CiAgICBpbnQJCW47CiAgICBYbVN0cmluZwl4bXM7CiNlbmRpZgoKICAgIC8qCiAgICAgKiBJbnN0YWxsIHRoZSAzRCBzaGFkZSBlZmZlY3QgZHJhd2luZyByb3V0aW5lcy4KICAgICAqLwogICAgaWYgKG9sZF9sYWJlbF9leHBvc2UgPT0gTlVMTCkKICAgIHsKCW9sZF9sYWJlbF9leHBvc2UgPSB4bUxhYmVsV2lkZ2V0Q2xhc3MtPmNvcmVfY2xhc3MuZXhwb3NlOwoJeG1MYWJlbFdpZGdldENsYXNzLT5jb3JlX2NsYXNzLmV4cG9zZSA9IGxhYmVsX2V4cG9zZTsKICAgIH0KCiAgICAvKgogICAgICogU3RhcnQgb3V0IGJ5IGFkZGluZyB0aGUgY29uZmlndXJlZCBib3JkZXIgd2lkdGggaW50byB0aGUgYm9yZGVyIG9mZnNldAogICAgICovCiAgICBndWkuYm9yZGVyX29mZnNldCA9IGd1aS5ib3JkZXJfd2lkdGg7CgogICAgLyoKICAgICAqIEluc3RhbGwgdGhlIHRlYXJPZmZNb2RlbCByZXNvdXJjZSBjb252ZXJ0ZXIuCiAgICAgKi8KI2lmIChYbVZlcnNpb24gPj0gMTAwMikKICAgIFhtUmVwVHlwZUluc3RhbGxUZWFyT2ZmTW9kZWxDb252ZXJ0ZXIoKTsKI2VuZGlmCgogICAgLyogTWFrZSBzdXJlIHRoZSAiUXVpdCIgbWVudSBlbnRyeSBvZiB0aGUgd2luZG93IG1hbmFnZXIgaXMgaWdub3JlZCAqLwogICAgWHRWYVNldFZhbHVlcyh2aW1TaGVsbCwgWG1OZGVsZXRlUmVzcG9uc2UsIFhtRE9fTk9USElORywgTlVMTCk7CgogICAgdmltRm9ybSA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJ2aW1Gb3JtIiwKCXhtRm9ybVdpZGdldENsYXNzLCB2aW1TaGVsbCwKCVhtTmJvcmRlcldpZHRoLCAwLAoJWG1OaGlnaGxpZ2h0VGhpY2tuZXNzLCAwLAoJWG1Oc2hhZG93VGhpY2tuZXNzLCAwLAoJWG1ObWFyZ2luV2lkdGgsIDAsCglYbU5tYXJnaW5IZWlnaHQsIDAsCglYbU5yZXNpemVQb2xpY3ksIFhtUkVTSVpFX0FOWSwKCU5VTEwpOwogICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKHZpbUZvcm0pOwoKI2lmZGVmIEZFQVRfTUVOVQogICAgewoJQXJnIGFsWzddOyAvKiBNYWtlIHN1cmUgdGhlcmUgaXMgZW5vdWdoIHJvb20gZm9yIGFyZ3VtZW50cyEgKi8KCWludCBhYyA9IDA7CgojIGlmIChYbVZlcnNpb24gPj0gMTAwMikKCVh0U2V0QXJnKGFsW2FjXSwgWG1OdGVhck9mZk1vZGVsLCB0ZWFyb2ZmX3ZhbCk7IGFjKys7CiMgZW5kaWYKCVh0U2V0QXJnKGFsW2FjXSwgWG1ObGVmdEF0dGFjaG1lbnQsICBYbUFUVEFDSF9GT1JNKTsgYWMrKzsKCVh0U2V0QXJnKGFsW2FjXSwgWG1OdG9wQXR0YWNobWVudCwgICBYbUFUVEFDSF9GT1JNKTsgYWMrKzsKCVh0U2V0QXJnKGFsW2FjXSwgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgYWMrKzsKIyBpZm5kZWYgRkVBVF9UT09MQkFSCgkvKiBBbHdheXMgc3RpY2sgdG8gcmlnaHQgaGFuZCBzaWRlLiAqLwoJWHRTZXRBcmcoYWxbYWNdLCBYbU5yaWdodE9mZnNldCwgMCk7IGFjKys7CiMgZW5kaWYKCVh0U2V0QXJnKGFsW2FjXSwgWG1ObWFyZ2luSGVpZ2h0LCAwKTsgYWMrKzsKCW1lbnVCYXIgPSBYbUNyZWF0ZU1lbnVCYXIodmltRm9ybSwgIm1lbnVCYXIiLCBhbCwgYWMpOwoJWHRNYW5hZ2VDaGlsZChtZW51QmFyKTsKCgkvKiBSZW1lbWJlciB0aGUgZGVmYXVsdCBjb2xvcnMsIG5lZWRlZCBmb3IgIjpoaSBjbGVhciIuICovCglYdFZhR2V0VmFsdWVzKG1lbnVCYXIsCgkgICAgWG1OYmFja2dyb3VuZCwgJmd1aS5tZW51X2RlZl9iZ19waXhlbCwKCSAgICBYbU5mb3JlZ3JvdW5kLCAmZ3VpLm1lbnVfZGVmX2ZnX3BpeGVsLAoJICAgIE5VTEwpOwoJZ3VpX21vdGlmX21lbnVfY29sb3JzKG1lbnVCYXIpOwogICAgfQojZW5kaWYKCiNpZmRlZiBGRUFUX1RPT0xCQVIKICAgIC8qCiAgICAgKiBDcmVhdGUgYW4gZW1wdHkgVG9vbEJhci4gV2Ugc2hvdWxkIGdldCBidXR0b25zIGRlZmluZWQgZnJvbSBtZW51LnZpbS4KICAgICAqLwogICAgdG9vbEJhckZyYW1lID0gWHRWYUNyZWF0ZVdpZGdldCgidG9vbEJhckZyYW1lIiwKCXhtRnJhbWVXaWRnZXRDbGFzcywgdmltRm9ybSwKCVhtTnNoYWRvd1RoaWNrbmVzcywgMCwKCVhtTm1hcmdpbkhlaWdodCwgMCwKCVhtTm1hcmdpbldpZHRoLCAwLAoJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCglYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCglOVUxMKTsKICAgIGd1aV9tb3RpZl9tZW51X2NvbG9ycyh0b29sQmFyRnJhbWUpOwoKICAgIHRvb2xCYXIgPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgidG9vbEJhciIsCgl4bVJvd0NvbHVtbldpZGdldENsYXNzLCB0b29sQmFyRnJhbWUsCglYbU5jaGlsZFR5cGUsIFhtRlJBTUVfV09SS0FSRUFfQ0hJTEQsCglYbU5yb3dDb2x1bW5UeXBlLCBYbVdPUktfQVJFQSwKCVhtTm9yaWVudGF0aW9uLCBYbUhPUklaT05UQUwsCglYbU50cmF2ZXJzYWxPbiwgRmFsc2UsCglYbU5pc0hvbW9nZW5lb3VzLCBGYWxzZSwKCVhtTnBhY2tpbmcsIFhtUEFDS19USUdIVCwKCVhtTnNwYWNpbmcsIDAsCglYbU5zaGFkb3dUaGlja25lc3MsIDAsCglYbU5oaWdobGlnaHRUaGlja25lc3MsIDAsCglYbU5tYXJnaW5IZWlnaHQsIDAsCglYbU5tYXJnaW5XaWR0aCwgMCwKCVhtTmFkanVzdExhc3QsIFRydWUsCglOVUxMKTsKICAgIGd1aV9tb3RpZl9tZW51X2NvbG9ycyh0b29sQmFyKTsKCiNlbmRpZgoKI2lmZGVmIEZFQVRfR1VJX1RBQkxJTkUKICAgIC8qIENyZWF0ZSB0aGUgVmltIEdVSSB0YWJsaW5lICovCiAgICBuID0gMDsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmJpbmRpbmdUeXBlLCBYbU5PTkUpOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5vcmllbnRhdGlvbiwgWG1WRVJUSUNBTCk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmJhY2tQYWdlU2l6ZSwgWG1OT05FKTsgbisrOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OYmFja1BhZ2VOdW1iZXIsIDApOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5iYWNrUGFnZVBsYWNlbWVudCwgWG1UT1BfUklHSFQpOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5tYWpvclRhYlNwYWNpbmcsIDApOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5zaGFkb3dUaGlja25lc3MsIDApOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKICAgIHRhYkxpbmUgPSBYbUNyZWF0ZU5vdGVib29rKHZpbUZvcm0sICJWaW0gdGFibGluZSIsIGFyZ3MsIG4pOwoKICAgIFh0QWRkQ2FsbGJhY2sodGFiTGluZSwgWG1OcGFnZUNoYW5nZWRDYWxsYmFjaywgKFh0Q2FsbGJhY2tQcm9jKXRhYmxpbmVfY2IsCgkJCU5VTEwpOwogICAgWHRBZGRFdmVudEhhbmRsZXIodGFiTGluZSwgQnV0dG9uUHJlc3NNYXNrLCBGYWxzZSwKCQkJKFh0RXZlbnRIYW5kbGVyKXRhYmxpbmVfbWVudV9jYiwgTlVMTCk7CgogICAgZ3VpLnRhYmxpbmVfaGVpZ2h0ID0gVEFCTElORV9IRUlHSFQ7CgogICAgLyoKICAgICAqIFNldCB0aGUgc2l6ZSBvZiB0aGUgbWlub3IgbmV4dC9wcmV2IHNjcm9sbGVycyB0byB6ZXJvLCBzbwogICAgICogdGhhdCB0aGV5IGFyZSBub3QgZGlzcGxheWVkLiBEdWUgdG8gYSBidWcgaW4gT3Blbk1vdGlmIDIuMywKICAgICAqIGV2ZW4gaWYgdGhlc2UgY2hpbGRyZW4gd2lkZ2V0IGFyZSB1bm1hbmFnZWQsIHRoZXkgYXJlIGFnYWluCiAgICAgKiBtYW5hZ2VkIGJ5IHRoZSBOb3RlYm9vayB3aWRnZXQgYW5kIHRoZSBub3RlYm9vayB3aWRnZXQgZ2VvbWV0cnkKICAgICAqIGlzIGFkanVzdGVkIHRvIGFjY291bnQgZm9yIHRoZSBtaW5vciBzY3JvbGxlciB3aWRnZXRzLgogICAgICovCiAgICBzY3JvbGxlciA9IFh0TmFtZVRvV2lkZ2V0KHRhYkxpbmUsICJNaW5vclRhYlNjcm9sbGVyTmV4dCIpOwogICAgWHRWYVNldFZhbHVlcyhzY3JvbGxlciwgWG1Od2lkdGgsIDAsIFhtTnJlc2l6YWJsZSwgRmFsc2UsCgkJICBYbU50cmF2ZXJzYWxPbiwgRmFsc2UsIE5VTEwpOwogICAgc2Nyb2xsZXIgPSBYdE5hbWVUb1dpZGdldCh0YWJMaW5lLCAiTWlub3JUYWJTY3JvbGxlclByZXZpb3VzIik7CiAgICBYdFZhU2V0VmFsdWVzKHNjcm9sbGVyLCBYbU53aWR0aCwgMCwgWG1OcmVzaXphYmxlLCBGYWxzZSwKCQkgIFhtTnRyYXZlcnNhbE9uLCBGYWxzZSwgTlVMTCk7CgogICAgLyogQ3JlYXRlIHRoZSB0YWJsaW5lIHBvcHVwIG1lbnUgKi8KICAgIHRhYkxpbmVfbWVudSA9IFhtQ3JlYXRlUG9wdXBNZW51KHRhYkxpbmUsICJ0YWJsaW5lIHBvcHVwIiwgTlVMTCwgMCk7CgogICAgLyogQWRkIHRoZSBidXR0b25zIHRvIHRoZSBtZW51ICovCiAgICBuID0gMDsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnVzZXJEYXRhLCBUQUJMSU5FX01FTlVfQ0xPU0UpOyBuKys7CiAgICB4bXMgPSBYbVN0cmluZ0NyZWF0ZSgoY2hhciAqKSJDbG9zZSB0YWIiLCBTVFJJTkdfVEFHKTsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxhYmVsU3RyaW5nLCB4bXMpOyBuKys7CiAgICBidXR0b24gPSBYbUNyZWF0ZVB1c2hCdXR0b24odGFiTGluZV9tZW51LCAiQ2xvc2UiLCBhcmdzLCBuKTsKICAgIFh0QWRkQ2FsbGJhY2soYnV0dG9uLCBYbU5hY3RpdmF0ZUNhbGxiYWNrLAoJCSAgKFh0Q2FsbGJhY2tQcm9jKXRhYmxpbmVfYnV0dG9uX2NiLCBOVUxMKTsKICAgIFhtU3RyaW5nRnJlZSh4bXMpOwoKICAgIG4gPSAwOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OdXNlckRhdGEsIFRBQkxJTkVfTUVOVV9ORVcpOyBuKys7CiAgICB4bXMgPSBYbVN0cmluZ0NyZWF0ZSgoY2hhciAqKSJOZXcgVGFiIiwgU1RSSU5HX1RBRyk7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5sYWJlbFN0cmluZywgeG1zKTsgbisrOwogICAgYnV0dG9uID0gWG1DcmVhdGVQdXNoQnV0dG9uKHRhYkxpbmVfbWVudSwgIk5ldyBUYWIiLCBhcmdzLCBuKTsKICAgIFh0QWRkQ2FsbGJhY2soYnV0dG9uLCBYbU5hY3RpdmF0ZUNhbGxiYWNrLAoJCSAgKFh0Q2FsbGJhY2tQcm9jKXRhYmxpbmVfYnV0dG9uX2NiLCBOVUxMKTsKICAgIFhtU3RyaW5nRnJlZSh4bXMpOwoKICAgIG4gPSAwOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OdXNlckRhdGEsIFRBQkxJTkVfTUVOVV9PUEVOKTsgbisrOwogICAgeG1zID0gWG1TdHJpbmdDcmVhdGUoKGNoYXIgKikiT3BlbiB0YWIuLi4iLCBTVFJJTkdfVEFHKTsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxhYmVsU3RyaW5nLCB4bXMpOyBuKys7CiAgICBidXR0b24gPSBYbUNyZWF0ZVB1c2hCdXR0b24odGFiTGluZV9tZW51LCAiT3BlbiB0YWIuLi4iLCBhcmdzLCBuKTsKICAgIFh0QWRkQ2FsbGJhY2soYnV0dG9uLCBYbU5hY3RpdmF0ZUNhbGxiYWNrLAoJCSAgKFh0Q2FsbGJhY2tQcm9jKXRhYmxpbmVfYnV0dG9uX2NiLCBOVUxMKTsKICAgIFhtU3RyaW5nRnJlZSh4bXMpOwojZW5kaWYKCiAgICB0ZXh0QXJlYUZvcm0gPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgidGV4dEFyZWFGb3JtIiwKCXhtRm9ybVdpZGdldENsYXNzLCB2aW1Gb3JtLAoJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCglYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCglYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCVhtTm1hcmdpbldpZHRoLCAwLAoJWG1ObWFyZ2luSGVpZ2h0LCAwLAoJWG1OcmVzaXplUG9saWN5LCBYbVJFU0laRV9BTlksCglOVUxMKTsKICAgIGd1aV9tb3RpZl9zY3JvbGxfY29sb3JzKHRleHRBcmVhRm9ybSk7CgogICAgdGV4dEFyZWEgPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgidGV4dEFyZWEiLAoJeG1EcmF3aW5nQXJlYVdpZGdldENsYXNzLCB0ZXh0QXJlYUZvcm0sCglYbU5mb3JlZ3JvdW5kLCBndWkubm9ybV9waXhlbCwKCVhtTmJhY2tncm91bmQsIGd1aS5iYWNrX3BpeGVsLAoJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCglYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCgkvKgoJICogVGhlc2UgdGFrZSBzb21lIGNvbnRyb2wgYXdheSBmcm9tIHRoZSB1c2VyLCBidXQgYXZvaWRzIG1ha2luZyB0aGVtCgkgKiBhZGQgcmVzb3VyY2VzIHRvIGdldCBhIGRlY2VudCBsb29raW5nIHNldHVwLgoJICovCglYbU5ib3JkZXJXaWR0aCwgMCwKCVhtTmhpZ2hsaWdodFRoaWNrbmVzcywgMCwKCVhtTnNoYWRvd1RoaWNrbmVzcywgMCwKCU5VTEwpOwoKI2lmZGVmIEZFQVRfRk9PVEVSCiAgICAvKgogICAgICogQ3JlYXRlIHRoZSBGb290ZXIuCiAgICAgKi8KICAgIGZvb3RlciA9IFh0VmFDcmVhdGVXaWRnZXQoImZvb3RlciIsCgl4bUxhYmVsR2FkZ2V0Q2xhc3MsIHZpbUZvcm0sCglYbU5hbGlnbm1lbnQsIFhtQUxJR05NRU5UX0JFR0lOTklORywKCVhtTm1hcmdpbkhlaWdodCwgMCwKCVhtTm1hcmdpbldpZHRoLCAwLAoJWG1OdHJhdmVyc2FsT24sIEZhbHNlLAoJWG1OcmVjb21wdXRlU2l6ZSwgRmFsc2UsCglYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCVhtTmxlZnRPZmZzZXQsIDUsCglYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCglYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJTlVMTCk7CiAgICBndWlfbWNoX3NldF9mb290ZXIoKGNoYXJfdSAqKSAiIik7CiNlbmRpZgoKICAgIC8qCiAgICAgKiBJbnN0YWxsIHRoZSBjYWxsYmFja3MuCiAgICAgKi8KICAgIGd1aV94MTFfY2FsbGJhY2tzKHRleHRBcmVhLCB2aW1Gb3JtKTsKCiAgICAvKiBQcmV0ZW5kIHdlIGRvbid0IGhhdmUgaW5wdXQgZm9jdXMsIHdlIHdpbGwgZ2V0IGFuIGV2ZW50IGlmIHdlIGRvLiAqLwogICAgZ3VpLmluX2ZvY3VzID0gRkFMU0U7Cn0KCi8qCiAqIENhbGxlZCB3aGVuIHRoZSBHVUkgaXMgbm90IGdvaW5nIHRvIHN0YXJ0IGFmdGVyIGFsbC4KICovCiAgICB2b2lkCmd1aV94MTFfZGVzdHJveV93aWRnZXRzKCkKewogICAgdGV4dEFyZWEgPSBOVUxMOwojaWZkZWYgRkVBVF9NRU5VCiAgICBtZW51QmFyID0gTlVMTDsKI2VuZGlmCn0KCi8qQVJHU1VTRUQqLwogICAgdm9pZApndWlfbWNoX3NldF90ZXh0X2FyZWFfcG9zKHgsIHksIHcsIGgpCiAgICBpbnQJICAgIHg7CiAgICBpbnQJICAgIHk7CiAgICBpbnQJICAgIHc7CiAgICBpbnQJICAgIGg7CnsKI2lmZGVmIEZFQVRfVE9PTEJBUgogICAgLyogR2l2ZSBrZXlib2FyZCBmb2N1cyB0byB0aGUgdGV4dEFyZWEgaW5zdGVhZCBvZiB0aGUgdG9vbGJhci4gKi8KICAgIHJlc2V0X2ZvY3VzKCk7CiNlbmRpZgp9CgogICAgdm9pZApndWlfeDExX3NldF9iYWNrX2NvbG9yKCkKewogICAgaWYgKHRleHRBcmVhICE9IE5VTEwpCiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCglYbUNoYW5nZUNvbG9yKHRleHRBcmVhLCBndWkuYmFja19waXhlbCk7CiNlbHNlCglYdFZhU2V0VmFsdWVzKHRleHRBcmVhLAoJCSAgWG1OYmFja2dyb3VuZCwgZ3VpLmJhY2tfcGl4ZWwsCgkJICBOVUxMKTsKI2VuZGlmCn0KCi8qCiAqIE1hbmFnZSBkaWFsb2cgY2VudGVyZWQgb24gcG9pbnRlci4gVGhpcyBjb3VsZCBiZSB1c2VkIGJ5IHRoZSBBdGhlbmEgY29kZSBhcwogKiB3ZWxsLgogKi8KICAgIHZvaWQKbWFuYWdlX2NlbnRlcmVkKGRpYWxvZ19jaGlsZCkKICAgIFdpZGdldCBkaWFsb2dfY2hpbGQ7CnsKICAgIFdpZGdldCBzaGVsbCA9IFh0UGFyZW50KGRpYWxvZ19jaGlsZCk7CiAgICBXaW5kb3cgcm9vdCwgY2hpbGQ7CiAgICB1bnNpZ25lZCBpbnQgbWFzazsKICAgIHVuc2lnbmVkIGludCB3aWR0aCwgaGVpZ2h0LCBib3JkZXJfd2lkdGgsIGRlcHRoOwogICAgaW50IHgsIHksIHdpbl94LCB3aW5feSwgbWF4WCwgbWF4WTsKICAgIEJvb2xlYW4gbWFwcGVkV2hlbk1hbmFnZWQ7CgogICAgLyogVGVtcG9yYXJpbHkgc2V0IHZhbHVlIG9mIFhtTm1hcHBlZFdoZW5NYW5hZ2VkCiAgICAgICB0byBzdG9wIHRoZSBkaWFsb2cgZnJvbSBwb3BwaW5nIHVwIHJpZ2h0IGF3YXkgKi8KICAgIFh0VmFHZXRWYWx1ZXMoc2hlbGwsIFhtTm1hcHBlZFdoZW5NYW5hZ2VkLCAmbWFwcGVkV2hlbk1hbmFnZWQsIDApOwogICAgWHRWYVNldFZhbHVlcyhzaGVsbCwgWG1ObWFwcGVkV2hlbk1hbmFnZWQsIEZhbHNlLCAwKTsKCiAgICBYdE1hbmFnZUNoaWxkKGRpYWxvZ19jaGlsZCk7CgogICAgLyogR2V0IHRoZSBwb2ludGVyIHBvc2l0aW9uICh4LCB5KSAqLwogICAgWFF1ZXJ5UG9pbnRlcihYdERpc3BsYXkoc2hlbGwpLCBYdFdpbmRvdyhzaGVsbCksICZyb290LCAmY2hpbGQsCgkJICAmeCwgJnksICZ3aW5feCwgJndpbl95LCAmbWFzayk7CgogICAgLyogVHJhbnNsYXRlIHRoZSBwb2ludGVyIHBvc2l0aW9uICh4LCB5KSBpbnRvIGEgcG9zaXRpb24gZm9yIHRoZSBuZXcKICAgICAgIHdpbmRvdyB0aGF0IHdpbGwgcGxhY2UgdGhlIHBvaW50ZXIgYXQgaXRzIGNlbnRlciAqLwogICAgWEdldEdlb21ldHJ5KFh0RGlzcGxheShzaGVsbCksIFh0V2luZG93KHNoZWxsKSwgJnJvb3QsICZ3aW5feCwgJndpbl95LAoJCSAmd2lkdGgsICZoZWlnaHQsICZib3JkZXJfd2lkdGgsICZkZXB0aCk7CiAgICB3aWR0aCArPSAyICogYm9yZGVyX3dpZHRoOwogICAgaGVpZ2h0ICs9IDIgKiBib3JkZXJfd2lkdGg7CiAgICB4IC09IHdpZHRoIC8gMjsKICAgIHkgLT0gaGVpZ2h0IC8gMjsKCiAgICAvKiBFbnN1cmUgdGhhdCB0aGUgZGlhbG9nIHJlbWFpbnMgb24gc2NyZWVuICovCiAgICBtYXhYID0gWHRTY3JlZW4oc2hlbGwpLT53aWR0aCAtIHdpZHRoOwogICAgbWF4WSA9IFh0U2NyZWVuKHNoZWxsKS0+aGVpZ2h0IC0gaGVpZ2h0OwogICAgaWYgKHggPCAwKQoJeCA9IDA7CiAgICBpZiAoeCA+IG1heFgpCgl4ID0gbWF4WDsKICAgIGlmICh5IDwgMCkKCXkgPSAwOwogICAgaWYgKHkgPiBtYXhZKQoJeSA9IG1heFk7CgogICAgLyogU2V0IGRlc2lyZWQgd2luZG93IHBvc2l0aW9uIGluIHRoZSBEaWFsb2dTaGVsbCAqLwogICAgWHRWYVNldFZhbHVlcyhzaGVsbCwgWG1OeCwgeCwgWG1OeSwgeSwgTlVMTCk7CgogICAgLyogTWFwIHRoZSB3aWRnZXQgKi8KICAgIFh0TWFwV2lkZ2V0KHNoZWxsKTsKCiAgICAvKiBSZXN0b3JlIHRoZSB2YWx1ZSBvZiBYbU5tYXBwZWRXaGVuTWFuYWdlZCAqLwogICAgWHRWYVNldFZhbHVlcyhzaGVsbCwgWG1ObWFwcGVkV2hlbk1hbmFnZWQsIG1hcHBlZFdoZW5NYW5hZ2VkLCAwKTsKfQoKI2lmIGRlZmluZWQoRkVBVF9NRU5VKSB8fCBkZWZpbmVkKEZFQVRfU1VOX1dPUktTSE9QKSBcCgl8fCBkZWZpbmVkKEZFQVRfR1VJX0RJQUxPRykgfHwgZGVmaW5lZChQUk9UTykKCi8qCiAqIEVuY2Fwc3VsYXRlIHRoZSB3YXkgYW4gWG1Gb250TGlzdCBpcyBjcmVhdGVkLgogKi8KICAgIFhtRm9udExpc3QKZ3VpX21vdGlmX2NyZWF0ZV9mb250bGlzdChmb250KQogICAgWEZvbnRTdHJ1Y3QgICAgKmZvbnQ7CnsKICAgIFhtRm9udExpc3QgZm9udF9saXN0OwoKIyBpZiAoWG1WZXJzaW9uIDw9IDEwMDEpCiAgICAvKiBNb3RpZiAxLjEgbWV0aG9kICovCiAgICBmb250X2xpc3QgPSBYbUZvbnRMaXN0Q3JlYXRlKGZvbnQsIFNUUklOR19UQUcpOwojIGVsc2UKICAgIC8qIE1vdGlmIDEuMiBtZXRob2QgKi8KICAgIFhtRm9udExpc3RFbnRyeSBmb250X2xpc3RfZW50cnk7CgogICAgZm9udF9saXN0X2VudHJ5ID0gWG1Gb250TGlzdEVudHJ5Q3JlYXRlKFNUUklOR19UQUcsIFhtRk9OVF9JU19GT05ULAoJCQkJCSAgICAoWHRQb2ludGVyKWZvbnQpOwogICAgZm9udF9saXN0ID0gWG1Gb250TGlzdEFwcGVuZEVudHJ5KE5VTEwsIGZvbnRfbGlzdF9lbnRyeSk7CiAgICBYbUZvbnRMaXN0RW50cnlGcmVlKCZmb250X2xpc3RfZW50cnkpOwojIGVuZGlmCiAgICByZXR1cm4gZm9udF9saXN0Owp9CgojIGlmICgoWG1WZXJzaW9uID4gMTAwMSkgJiYgZGVmaW5lZChGRUFUX1hGT05UU0VUKSkgfHwgZGVmaW5lZChQUk9UTykKICAgIFhtRm9udExpc3QKZ3VpX21vdGlmX2ZvbnRzZXQyZm9udGxpc3QoZm9udHNldCkKICAgIFhGb250U2V0CSpmb250c2V0Owp7CiAgICBYbUZvbnRMaXN0IGZvbnRfbGlzdDsKCiAgICAvKiBNb3RpZiAxLjIgbWV0aG9kICovCiAgICBYbUZvbnRMaXN0RW50cnkgZm9udF9saXN0X2VudHJ5OwoKICAgIGZvbnRfbGlzdF9lbnRyeSA9IFhtRm9udExpc3RFbnRyeUNyZWF0ZShTVFJJTkdfVEFHLAoJCQkJCSAgICBYbUZPTlRfSVNfRk9OVFNFVCwKCQkJCQkgICAgKFh0UG9pbnRlcikqZm9udHNldCk7CiAgICBmb250X2xpc3QgPSBYbUZvbnRMaXN0QXBwZW5kRW50cnkoTlVMTCwgZm9udF9saXN0X2VudHJ5KTsKICAgIFhtRm9udExpc3RFbnRyeUZyZWUoJmZvbnRfbGlzdF9lbnRyeSk7CiAgICByZXR1cm4gZm9udF9saXN0Owp9CiMgZW5kaWYKCiNlbmRpZgoKI2lmIGRlZmluZWQoRkVBVF9NRU5VKSB8fCBkZWZpbmVkKFBST1RPKQovKgogKiBNZW51IHN0dWZmLgogKi8KCnN0YXRpYyB2b2lkIGd1aV9tb3RpZl9hZGRfYWN0ZXh0IF9fQVJHUygodmltbWVudV9UICptZW51KSk7CiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCnN0YXRpYyB2b2lkIHRvZ2dsZV90ZWFyb2ZmIF9fQVJHUygoV2lkZ2V0IHdpZCkpOwpzdGF0aWMgdm9pZCBndWlfbWNoX3JlY3Vyc2VfdGVhcm9mZnMgX19BUkdTKCh2aW1tZW51X1QgKm1lbnUpKTsKI2VuZGlmCnN0YXRpYyB2b2lkIHN1Ym1lbnVfY2hhbmdlIF9fQVJHUygodmltbWVudV9UICptcCwgaW50IGNvbG9ycykpOwoKc3RhdGljIHZvaWQgZG9fc2V0X21uZW1vbmljcyBfX0FSR1MoKGludCBlbmFibGUpKTsKc3RhdGljIGludCBtZW51X2VuYWJsZWQgPSBUUlVFOwoKICAgIHZvaWQKZ3VpX21jaF9lbmFibGVfbWVudShmbGFnKQogICAgaW50CSAgICBmbGFnOwp7CiAgICBpZiAoZmxhZykKICAgIHsKCVh0TWFuYWdlQ2hpbGQobWVudUJhcik7CiNpZmRlZiBGRUFUX1RPT0xCQVIKCWlmIChYdElzTWFuYWdlZChYdFBhcmVudCh0b29sQmFyKSkpCgl7CgkgICAgLyogdG9vbEJhciBpcyBhdHRhY2hlZCB0byB0b3AgZm9ybSAqLwoJICAgIFh0VmFTZXRWYWx1ZXMoWHRQYXJlbnQodG9vbEJhciksCgkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCVhtTnRvcFdpZGdldCwgbWVudUJhciwKCQlOVUxMKTsKI2lmZGVmIEZFQVRfR1VJX1RBQkxJTkUKCSAgICBpZiAoc2hvd2luZ190YWJsaW5lKQoJICAgIHsKCQlYdFZhU2V0VmFsdWVzKHRhYkxpbmUsCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCBYdFBhcmVudCh0b29sQmFyKSwKCQkJICAgICAgTlVMTCk7CgkJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCB0YWJMaW5lLAoJCQkgICAgICBOVUxMKTsKCSAgICB9CgkgICAgZWxzZQojZW5kaWYKCQlYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQkgICAgICBYbU50b3BXaWRnZXQsIFh0UGFyZW50KHRvb2xCYXIpLAoJCQkgICAgICBOVUxMKTsKCX0KCWVsc2UKI2VuZGlmCgl7CiNpZmRlZiBGRUFUX0dVSV9UQUJMSU5FCgkgICAgaWYgKHNob3dpbmdfdGFibGluZSkKCSAgICB7CgkJWHRWYVNldFZhbHVlcyh0YWJMaW5lLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICAgIFhtTnRvcFdpZGdldCwgbWVudUJhciwKCQkJICAgICAgTlVMTCk7CgkJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCB0YWJMaW5lLAoJCQkgICAgICBOVUxMKTsKCSAgICB9CgkgICAgZWxzZQojZW5kaWYKCQlYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQkgICAgICBYbU50b3BXaWRnZXQsIG1lbnVCYXIsCgkJCSAgICAgIE5VTEwpOwoJfQogICAgfQogICAgZWxzZQogICAgewoJWHRVbm1hbmFnZUNoaWxkKG1lbnVCYXIpOwojaWZkZWYgRkVBVF9UT09MQkFSCglpZiAoWHRJc01hbmFnZWQoWHRQYXJlbnQodG9vbEJhcikpKQoJewoJICAgIFh0VmFTZXRWYWx1ZXMoWHRQYXJlbnQodG9vbEJhciksCgkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlOVUxMKTsKI2lmZGVmIEZFQVRfR1VJX1RBQkxJTkUKCSAgICBpZiAoc2hvd2luZ190YWJsaW5lKQoJICAgIHsKCQlYdFZhU2V0VmFsdWVzKHRhYkxpbmUsCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCBYdFBhcmVudCh0b29sQmFyKSwKCQkJICAgICAgTlVMTCk7CgkJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCB0YWJMaW5lLAoJCQkgICAgICBOVUxMKTsKCSAgICB9CgkgICAgZWxzZQojZW5kaWYKCQlYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQkgICAgICBYbU50b3BXaWRnZXQsIFh0UGFyZW50KHRvb2xCYXIpLAoJCQkgICAgICBOVUxMKTsKCX0KCWVsc2UKI2VuZGlmCgl7CiNpZmRlZiBGRUFUX0dVSV9UQUJMSU5FCgkgICAgaWYgKHNob3dpbmdfdGFibGluZSkKCSAgICB7CgkJWHRWYVNldFZhbHVlcyh0YWJMaW5lLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCQkgICAgICBOVUxMKTsKCQlYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQkgICAgICBYbU50b3BXaWRnZXQsIHRhYkxpbmUsCgkJCSAgICAgIE5VTEwpOwoJICAgIH0KCSAgICBlbHNlCiNlbmRpZgoJCVh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCQkgICAgICBOVUxMKTsKCX0KICAgIH0KCn0KCi8qCiAqIEVuYWJsZSBvciBkaXNhYmxlIG1uZW1vbmljcyBmb3IgdGhlIHRvcGxldmVsIG1lbnVzLgogKi8KICAgIHZvaWQKZ3VpX21vdGlmX3NldF9tbmVtb25pY3MoZW5hYmxlKQogICAgaW50CQllbmFibGU7CnsKICAgIC8qCiAgICAgKiBEb24ndCBlbmFibGUgbWVudSBtbmVtb25pY3Mgd2hlbiB0aGUgbWVudSBiYXIgaXMgZGlzYWJsZWQsIExlc3NUaWYKICAgICAqIGNyYXNoZXMgd2hlbiB1c2luZyBhIG1uZW1vbmljIHRoZW4uCiAgICAgKi8KICAgIGlmICghbWVudV9lbmFibGVkKQoJZW5hYmxlID0gRkFMU0U7CiAgICBkb19zZXRfbW5lbW9uaWNzKGVuYWJsZSk7Cn0KCiAgICBzdGF0aWMgdm9pZApkb19zZXRfbW5lbW9uaWNzKGVuYWJsZSkKICAgIGludAkJZW5hYmxlOwp7CiAgICB2aW1tZW51X1QJKm1lbnU7CgogICAgZm9yIChtZW51ID0gcm9vdF9tZW51OyBtZW51ICE9IE5VTEw7IG1lbnUgPSBtZW51LT5uZXh0KQoJaWYgKG1lbnUtPmlkICE9IChXaWRnZXQpMCkKCSAgICBYdFZhU2V0VmFsdWVzKG1lbnUtPmlkLAoJCSAgICBYbU5tbmVtb25pYywgZW5hYmxlID8gbWVudS0+bW5lbW9uaWMgOiBOVUwsCgkJICAgIE5VTEwpOwp9CgogICAgdm9pZApndWlfbWNoX2FkZF9tZW51KG1lbnUsIGlkeCkKICAgIHZpbW1lbnVfVAkqbWVudTsKICAgIGludAkJaWR4Owp7CiAgICBYbVN0cmluZwlsYWJlbDsKICAgIFdpZGdldAlzaGVsbDsKICAgIHZpbW1lbnVfVAkqcGFyZW50ID0gbWVudS0+cGFyZW50OwoKI2lmZGVmIE1PVElGX1BPUFVQCiAgICBpZiAobWVudV9pc19wb3B1cChtZW51LT5uYW1lKSkKICAgIHsKCUFyZyBhcmdbMl07CglpbnQgbiA9IDA7CgoJLyogT25seSBjcmVhdGUgdGhlIHBvcHVwIG1lbnUgd2hlbiBpdCdzIGFjdHVhbGx5IHVzZWQsIG90aGVyd2lzZSB0aGVyZQoJICogaXMgYSBkZWxheSB3aGVuIHVzaW5nIHRoZSByaWdodCBtb3VzZSBidXR0b24uICovCiMgaWYgKFhtVmVyc2lvbiA8PSAxMDAyKQoJaWYgKG1vdXNlX21vZGVsX3BvcHVwKCkpCiMgZW5kaWYKCXsKCSAgICBpZiAoZ3VpLm1lbnVfYmdfcGl4ZWwgIT0gSU5WQUxDT0xPUikKCSAgICB7CgkJWHRTZXRBcmcoYXJnWzBdLCBYbU5iYWNrZ3JvdW5kLCBndWkubWVudV9iZ19waXhlbCk7IG4rKzsKCSAgICB9CgkgICAgaWYgKGd1aS5tZW51X2ZnX3BpeGVsICE9IElOVkFMQ09MT1IpCgkgICAgewoJCVh0U2V0QXJnKGFyZ1sxXSwgWG1OZm9yZWdyb3VuZCwgZ3VpLm1lbnVfZmdfcGl4ZWwpOyBuKys7CgkgICAgfQoJICAgIG1lbnUtPnN1Ym1lbnVfaWQgPSBYbUNyZWF0ZVBvcHVwTWVudSh0ZXh0QXJlYSwgImNvbnRleHRNZW51IiwKCQkJCQkJCQkgICAgICBhcmcsIG4pOwoJICAgIG1lbnUtPmlkID0gKFdpZGdldCkwOwoJfQoJcmV0dXJuOwogICAgfQojZW5kaWYKCiAgICBpZiAoIW1lbnVfaXNfbWVudWJhcihtZW51LT5uYW1lKQoJICAgIHx8IChwYXJlbnQgIT0gTlVMTCAmJiBwYXJlbnQtPnN1Ym1lbnVfaWQgPT0gKFdpZGdldCkwKSkKCXJldHVybjsKCiAgICBsYWJlbCA9IFhtU3RyaW5nQ3JlYXRlKChjaGFyICopbWVudS0+ZG5hbWUsIFNUUklOR19UQUcpOwogICAgaWYgKGxhYmVsID09IE5VTEwpCglyZXR1cm47CiAgICBtZW51LT5pZCA9IFh0VmFDcmVhdGVXaWRnZXQoInN1Yk1lbnUiLAoJICAgIHhtQ2FzY2FkZUJ1dHRvbldpZGdldENsYXNzLAoJICAgIChwYXJlbnQgPT0gTlVMTCkgPyBtZW51QmFyIDogcGFyZW50LT5zdWJtZW51X2lkLAoJICAgIFhtTmxhYmVsU3RyaW5nLCBsYWJlbCwKCSAgICBYbU5tbmVtb25pYywgcF93YWtbMF0gPT0gJ24nID8gTlVMIDogbWVudS0+bW5lbW9uaWMsCiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCgkgICAgLyogc3VibWVudTogY291bnQgdGhlIHRlYXJvZmYgaXRlbSAobmVlZGVkIGZvciBMZXNzVGlmKSAqLwoJICAgIFhtTnBvc2l0aW9uSW5kZXgsIGlkeCArIChwYXJlbnQgIT0gTlVMTAoJCQkgICAmJiB0ZWFyb2ZmX3ZhbCA9PSAoaW50KVhtVEVBUl9PRkZfRU5BQkxFRCA/IDEgOiAwKSwKI2VuZGlmCgkgICAgTlVMTCk7CiAgICBndWlfbW90aWZfbWVudV9jb2xvcnMobWVudS0+aWQpOwogICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3QobWVudS0+aWQpOwogICAgWG1TdHJpbmdGcmVlKGxhYmVsKTsKCiAgICBpZiAobWVudS0+aWQgPT0gKFdpZGdldCkwKQkJLyogZmFpbGVkICovCglyZXR1cm47CgogICAgLyogYWRkIGFjY2VsZXJhdG9yIHRleHQgKi8KICAgIGd1aV9tb3RpZl9hZGRfYWN0ZXh0KG1lbnUpOwoKICAgIHNoZWxsID0gWHRWYUNyZWF0ZVdpZGdldCgic3ViTWVudVNoZWxsIiwKCXhtTWVudVNoZWxsV2lkZ2V0Q2xhc3MsIG1lbnUtPmlkLAoJWG1Od2lkdGgsIDEsCglYbU5oZWlnaHQsIDEsCglOVUxMKTsKICAgIGd1aV9tb3RpZl9tZW51X2NvbG9ycyhzaGVsbCk7CiAgICBtZW51LT5zdWJtZW51X2lkID0gWHRWYUNyZWF0ZVdpZGdldCgicm93Q29sdW1uTWVudSIsCgl4bVJvd0NvbHVtbldpZGdldENsYXNzLCBzaGVsbCwKCVhtTnJvd0NvbHVtblR5cGUsIFhtTUVOVV9QVUxMRE9XTiwKCU5VTEwpOwogICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKG1lbnUtPnN1Ym1lbnVfaWQpOwoKICAgIGlmIChtZW51LT5zdWJtZW51X2lkID09IChXaWRnZXQpMCkJCS8qIGZhaWxlZCAqLwoJcmV0dXJuOwoKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKICAgIC8qIFNldCB0aGUgY29sb3JzIGZvciB0aGUgdGVhciBvZmYgd2lkZ2V0ICovCiAgICB0b2dnbGVfdGVhcm9mZihtZW51LT5zdWJtZW51X2lkKTsKI2VuZGlmCgogICAgWHRWYVNldFZhbHVlcyhtZW51LT5pZCwKCVhtTnN1Yk1lbnVJZCwgbWVudS0+c3VibWVudV9pZCwKCU5VTEwpOwoKICAgIC8qCiAgICAgKiBUaGUgIkhlbHAiIG1lbnUgaXMgYSBzcGVjaWFsIGNhc2UsIGFuZCBzaG91bGQgYmUgcGxhY2VkIGF0IHRoZSBmYXIKICAgICAqIHJpZ2h0IGhhbmQgc2lkZSBvZiB0aGUgbWVudS1iYXIuICBJdCdzIHJlY29nbml6ZWQgYnkgaXRzIGhpZ2ggcHJpb3JpdHkuCiAgICAgKi8KICAgIGlmIChwYXJlbnQgPT0gTlVMTCAmJiBtZW51LT5wcmlvcml0eSA+PSA5OTk5KQoJWHRWYVNldFZhbHVlcyhtZW51QmFyLAoJCVhtTm1lbnVIZWxwV2lkZ2V0LCBtZW51LT5pZCwKCQlOVUxMKTsKCiAgICAvKgogICAgICogV2hlbiB3ZSBhZGQgYSB0b3AtbGV2ZWwgaXRlbSB0byB0aGUgbWVudSBiYXIsIHdlIGNhbiBmaWd1cmUgb3V0IGhvdwogICAgICogaGlnaCB0aGUgbWVudSBiYXIgc2hvdWxkIGJlLgogICAgICovCiAgICBpZiAocGFyZW50ID09IE5VTEwpCglndWlfbWNoX2NvbXB1dGVfbWVudV9oZWlnaHQobWVudS0+aWQpOwp9CgoKLyoKICogQWRkIG1uZW1vbmljIGFuZCBhY2NlbGVyYXRvciB0ZXh0IHRvIGEgbWVudSBidXR0b24uCiAqLwogICAgc3RhdGljIHZvaWQKZ3VpX21vdGlmX2FkZF9hY3RleHQobWVudSkKICAgIHZpbW1lbnVfVAkqbWVudTsKewogICAgWG1TdHJpbmcJbGFiZWw7CgogICAgLyogQWRkIGFjY2VsZXJhdG9yIHRleHQsIGlmIHRoZXJlIGlzIG9uZSAqLwogICAgaWYgKG1lbnUtPmFjdGV4dCAhPSBOVUxMICYmIG1lbnUtPmlkICE9IChXaWRnZXQpMCkKICAgIHsKCWxhYmVsID0gWG1TdHJpbmdDcmVhdGUoKGNoYXIgKiltZW51LT5hY3RleHQsIFNUUklOR19UQUcpOwoJaWYgKGxhYmVsID09IE5VTEwpCgkgICAgcmV0dXJuOwoJWHRWYVNldFZhbHVlcyhtZW51LT5pZCwgWG1OYWNjZWxlcmF0b3JUZXh0LCBsYWJlbCwgTlVMTCk7CglYbVN0cmluZ0ZyZWUobGFiZWwpOwogICAgfQp9CgogICAgdm9pZApndWlfbWNoX3RvZ2dsZV90ZWFyb2ZmcyhlbmFibGUpCiAgICBpbnQJCWVuYWJsZTsKewojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQogICAgaWYgKGVuYWJsZSkKCXRlYXJvZmZfdmFsID0gKGludClYbVRFQVJfT0ZGX0VOQUJMRUQ7CiAgICBlbHNlCgl0ZWFyb2ZmX3ZhbCA9IChpbnQpWG1URUFSX09GRl9ESVNBQkxFRDsKICAgIHRvZ2dsZV90ZWFyb2ZmKG1lbnVCYXIpOwogICAgZ3VpX21jaF9yZWN1cnNlX3RlYXJvZmZzKHJvb3RfbWVudSk7CiNlbmRpZgp9CgojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQovKgogKiBTZXQgdGhlIHRlYXJvZmYgZm9yIG9uZSBtZW51IHdpZGdldCBvbiBvciBvZmYsIGFuZCBzZXQgdGhlIGNvbG9yIG9mIHRoZQogKiB0ZWFyb2ZmIHdpZGdldC4KICovCiAgICBzdGF0aWMgdm9pZAp0b2dnbGVfdGVhcm9mZih3aWQpCiAgICBXaWRnZXQJd2lkOwp7CiAgICBXaWRnZXQJdzsKCiAgICBYdFZhU2V0VmFsdWVzKHdpZCwgWG1OdGVhck9mZk1vZGVsLCB0ZWFyb2ZmX3ZhbCwgTlVMTCk7CiAgICBpZiAodGVhcm9mZl92YWwgPT0gKGludClYbVRFQVJfT0ZGX0VOQUJMRUQKCSAgICAmJiAodyA9IFhtR2V0VGVhck9mZkNvbnRyb2wod2lkKSkgIT0gKFdpZGdldCkwKQoJZ3VpX21vdGlmX21lbnVfY29sb3JzKHcpOwp9CgogICAgc3RhdGljIHZvaWQKZ3VpX21jaF9yZWN1cnNlX3RlYXJvZmZzKG1lbnUpCiAgICB2aW1tZW51X1QJKm1lbnU7CnsKICAgIHdoaWxlIChtZW51ICE9IE5VTEwpCiAgICB7CglpZiAoIW1lbnVfaXNfcG9wdXAobWVudS0+bmFtZSkpCgl7CgkgICAgaWYgKG1lbnUtPnN1Ym1lbnVfaWQgIT0gKFdpZGdldCkwKQoJCXRvZ2dsZV90ZWFyb2ZmKG1lbnUtPnN1Ym1lbnVfaWQpOwoJICAgIGd1aV9tY2hfcmVjdXJzZV90ZWFyb2ZmcyhtZW51LT5jaGlsZHJlbik7Cgl9CgltZW51ID0gbWVudS0+bmV4dDsKICAgIH0KfQojZW5kaWYKCiAgICBpbnQKZ3VpX21jaF90ZXh0X2FyZWFfZXh0cmFfaGVpZ2h0KCkKewogICAgRGltZW5zaW9uCXNoYWRvd0hlaWdodDsKCiAgICBYdFZhR2V0VmFsdWVzKHRleHRBcmVhRm9ybSwgWG1Oc2hhZG93VGhpY2tuZXNzLCAmc2hhZG93SGVpZ2h0LCBOVUxMKTsKICAgIHJldHVybiBzaGFkb3dIZWlnaHQ7Cn0KCi8qCiAqIENvbXB1dGUgdGhlIGhlaWdodCBvZiB0aGUgbWVudSBiYXIuCiAqIFdlIG5lZWQgdG8gY2hlY2sgYWxsIHRoZSBpdGVtcyBmb3IgdGhlaXIgcG9zaXRpb24gYW5kIGhlaWdodCwgZm9yIHRoZSBjYXNlCiAqIHRoZXJlIGFyZSBzZXZlcmFsIHJvd3MsIGFuZC9vciBzb21lIGNoYXJhY3RlcnMgZXh0ZW5kIGhpZ2hlciBvciBsb3dlci4KICovCiAgICB2b2lkCmd1aV9tY2hfY29tcHV0ZV9tZW51X2hlaWdodChpZCkKICAgIFdpZGdldAlpZDsJCSAgICAvKiBjYW4gYmUgTlVMTCB3aGVuIGRlbGV0aW5nIG1lbnUgKi8KewogICAgRGltZW5zaW9uCXksIG1heHk7CiAgICBEaW1lbnNpb24JbWFyZ2luLCBzaGFkb3c7CiAgICB2aW1tZW51X1QJKm1wOwogICAgc3RhdGljIERpbWVuc2lvbgloZWlnaHQgPSAyMTsJLyogbm9ybWFsIGhlaWdodCBvZiBhIG1lbnUgaXRlbSAqLwoKICAgIC8qCiAgICAgKiBHZXQgdGhlIGhlaWdodCBvZiB0aGUgbmV3IGl0ZW0sIGJlZm9yZSBtYW5hZ2luZyBpdCwgYmVjYXVzZSBpdCB3aWxsCiAgICAgKiBzdGlsbCByZWZsZWN0IHRoZSBmb250IHNpemUuICBBZnRlciBtYW5hZ2luZyBpdCBkZXBlbmRzIG9uIHRoZSBtZW51CiAgICAgKiBoZWlnaHQsIHdoaWNoIGlzIHdoYXQgd2UganVzdCB3YW50ZWQgdG8gZ2V0IS4KICAgICAqLwogICAgaWYgKGlkICE9IChXaWRnZXQpMCkKCVh0VmFHZXRWYWx1ZXMoaWQsIFhtTmhlaWdodCwgJmhlaWdodCwgTlVMTCk7CgogICAgLyogRmluZCBhbnkgbWVudSBXaWRnZXQsIHRvIGJlIGFibGUgdG8gY2FsbCBYdE1hbmFnZUNoaWxkKCkgKi8KICAgIGVsc2UKCWZvciAobXAgPSByb290X21lbnU7IG1wICE9IE5VTEw7IG1wID0gbXAtPm5leHQpCgkgICAgaWYgKG1wLT5pZCAhPSAoV2lkZ2V0KTAgJiYgbWVudV9pc19tZW51YmFyKG1wLT5uYW1lKSkKCSAgICB7CgkJaWQgPSBtcC0+aWQ7CgkJYnJlYWs7CgkgICAgfQoKICAgIC8qCiAgICAgKiBOb3cgbWFuYWdlIHRoZSBtZW51IGl0ZW0sIHRvIG1ha2UgdGhlbSBhbGwgYmUgcG9zaXRpb25lZCAobWFrZXMgYW4KICAgICAqIGV4dHJhIHJvdyB3aGVuIG5lZWRlZCwgcmVtb3ZlcyBpdCB3aGVuIG5vdCBuZWVkZWQpLgogICAgICovCiAgICBpZiAoaWQgIT0gKFdpZGdldCkwKQoJWHRNYW5hZ2VDaGlsZChpZCk7CgogICAgLyoKICAgICAqIE5vdyBmaW5kIHRoZSBtZW51IGl0ZW0gdGhhdCBpcyB0aGUgZnVydGhlc3QgZG93biwgYW5kIGdldCBpdCdzIHBvc2l0aW9uLgogICAgICovCiAgICBtYXh5ID0gMDsKICAgIGZvciAobXAgPSByb290X21lbnU7IG1wICE9IE5VTEw7IG1wID0gbXAtPm5leHQpCiAgICB7CglpZiAobXAtPmlkICE9IChXaWRnZXQpMCAmJiBtZW51X2lzX21lbnViYXIobXAtPm5hbWUpKQoJewoJICAgIFh0VmFHZXRWYWx1ZXMobXAtPmlkLCBYbU55LCAmeSwgTlVMTCk7CgkgICAgaWYgKHkgPiBtYXh5KQoJCW1heHkgPSB5OwoJfQogICAgfQoKICAgIFh0VmFHZXRWYWx1ZXMobWVudUJhciwKCVhtTm1hcmdpbkhlaWdodCwgJm1hcmdpbiwKCVhtTnNoYWRvd1RoaWNrbmVzcywgJnNoYWRvdywKCU5VTEwpOwoKICAgIC8qCiAgICAgKiBUaGlzIGNvbXB1dGF0aW9uIGlzIHRoZSByZXN1bHQgb2YgdHJpYWwtYW5kLWVycm9yOgogICAgICogbWF4eSA9CVRoZSBtYXhpbXVtIHBvc2l0aW9uIG9mIGFuIGl0ZW07IHJlcXVpcmVkIGZvciB3aGVuIHRoZXJlIGFyZQogICAgICoJCXR3byBvciBtb3JlIHJvd3MKICAgICAqIGhlaWdodCA9IGhlaWdodCBvZiBhbiBpdGVtLCBiZWZvcmUgbWFuYWdpbmcgaXQ7CUhvcGVmdWxseSB0aGlzIHdpbGwKICAgICAqCQljaGFuZ2Ugd2l0aCB0aGUgZm9udCBoZWlnaHQuICBJbmNsdWRlcyBzaGFkb3ctYm9yZGVyLgogICAgICogc2hhZG93ID0Jc2hhZG93LWJvcmRlcjsgbXVzdCBiZSBzdWJ0cmFjdGVkIGZyb20gdGhlIGhlaWdodC4KICAgICAqIG1hcmdpbiA9IG1hcmdpbiBhcm91bmQgdGhlIG1lbnUgYnV0dG9uczsgIE11c3QgYmUgYWRkZWQuCiAgICAgKiBBZGQgNCBmb3IgdGhlIHVuZGVybGluaW5nIG9mIHNob3J0Y3V0IGtleXMuCiAgICAgKi8KICAgIGd1aS5tZW51X2hlaWdodCA9IG1heHkgKyBoZWlnaHQgLSAyICogc2hhZG93ICsgMiAqIG1hcmdpbiArIDQ7CgogICAgLyogU29tZWhvdyB0aGUgbWVudSBiYXIgZG9lc24ndCByZXNpemUgYXV0b21hdGljYWxseS4gIFNldCBpdCBoZXJlLAogICAgICogZXZlbiB0aG91Z2ggdGhpcyBpcyBhIGNhdGNoIDIyLiAgRG9uJ3QgZG8gdGhpcyB3aGVuIHN0YXJ0aW5nIHVwLAogICAgICogc29tZWhvdyB0aGUgbWVudSBnZXRzIHZlcnkgaGlnaCB0aGVuLiAqLwogICAgaWYgKGd1aS5zaGVsbF9jcmVhdGVkKQoJWHRWYVNldFZhbHVlcyhtZW51QmFyLCBYbU5oZWlnaHQsIGd1aS5tZW51X2hlaWdodCwgTlVMTCk7Cn0KCiNpZmRlZiBGRUFUX1RPT0xCQVIKCi8qCiAqIEljb25zIHVzZWQgYnkgdGhlIHRvb2xiYXIgY29kZS4KICovCiNpbmNsdWRlICJndWlfeDExX3BtLmgiCgpzdGF0aWMgaW50IGNoZWNrX3hwbSBfX0FSR1MoKGNoYXJfdSAqcGF0aCkpOwpzdGF0aWMgY2hhciAqKmdldF90b29sYmFyX3BpeG1hcCBfX0FSR1MoKHZpbW1lbnVfVCAqbWVudSwgY2hhciAqKmZuYW1lKSk7CnN0YXRpYyBpbnQgYWRkX3BpeG1hcF9hcmdzIF9fQVJHUygodmltbWVudV9UICptZW51LCBBcmcgKmFyZ3MsIGludCBuKSk7CgovKgogKiBSZWFkIGFuIFhwbSBmaWxlLiAgUmV0dXJuIE9LIG9yIEZBSUwuCiAqLwogICAgc3RhdGljIGludApjaGVja194cG0ocGF0aCkKICAgIGNoYXJfdQkqcGF0aDsKewogICAgWHBtQXR0cmlidXRlcyBhdHRyczsKICAgIGludAkJc3RhdHVzOwogICAgUGl4bWFwCW1hc2s7CiAgICBQaXhtYXAJbWFwOwoKICAgIGF0dHJzLnZhbHVlbWFzayA9IDA7CgogICAgLyogQ3JlYXRlIHRoZSAic2Vuc2l0aXZlIiBwaXhtYXAgKi8KICAgIHN0YXR1cyA9IFhwbVJlYWRGaWxlVG9QaXhtYXAoZ3VpLmRweSwKCSAgICBSb290V2luZG93KGd1aS5kcHksIERlZmF1bHRTY3JlZW4oZ3VpLmRweSkpLAoJICAgIChjaGFyICopcGF0aCwgJm1hcCwgJm1hc2ssICZhdHRycyk7CiAgICBYcG1GcmVlQXR0cmlidXRlcygmYXR0cnMpOwoKICAgIGlmIChzdGF0dXMgPT0gWHBtU3VjY2VzcykKCXJldHVybiBPSzsKICAgIHJldHVybiBGQUlMOwp9CgoKLyoKICogQWxsb2NhdGVkIGEgcGl4bWFwIGZvciB0b29sYmFyIG1lbnUgIm1lbnUiLgogKiBXaGVuIGl0J3MgdG8gYmUgcmVhZCBmcm9tIGEgZmlsZSwgImZuYW1lIiBpcyBzZXQgdG8gdGhlIGZpbGUgbmFtZQogKiAoaW4gYWxsb2NhdGVkIG1lbW9yeSkuCiAqIFJldHVybiBhIGJsYW5rIHBpeG1hcCBpZiBpdCBmYWlscy4KICovCiAgICBzdGF0aWMgY2hhciAqKgpnZXRfdG9vbGJhcl9waXhtYXAobWVudSwgZm5hbWUpCiAgICB2aW1tZW51X1QJKm1lbnU7CiAgICBjaGFyCSoqZm5hbWU7CnsKICAgIGNoYXJfdQlidWZbTUFYUEFUSExdOwkJLyogYnVmZmVyIHN0b3JpbmcgZXhwYW5kZWQgcGF0aG5hbWUgKi8KICAgIGNoYXIJKip4cG0gPSBOVUxMOwkJLyogeHBtIGFycmF5ICovCiAgICBpbnQJCXJlczsKCiAgICAqZm5hbWUgPSBOVUxMOwogICAgYnVmWzBdID0gTlVMOwkJCS8qIHN0YXJ0IHdpdGggTlVMTCBwYXRoICovCgogICAgaWYgKG1lbnUtPmljb25maWxlICE9IE5VTEwpCiAgICB7CgkvKiBVc2UgdGhlICJpY29uPSIgIGFyZ3VtZW50LiAqLwoJZ3VpX2ZpbmRfaWNvbmZpbGUobWVudS0+aWNvbmZpbGUsIGJ1ZiwgInhwbSIpOwoJcmVzID0gY2hlY2tfeHBtKGJ1Zik7CgoJLyogSWYgaXQgZmFpbGVkLCB0cnkgdXNpbmcgdGhlIG1lbnUgbmFtZS4gKi8KCWlmIChyZXMgPT0gRkFJTCAmJiBndWlfZmluZF9iaXRtYXAobWVudS0+bmFtZSwgYnVmLCAieHBtIikgPT0gT0spCgkgICAgcmVzID0gY2hlY2tfeHBtKGJ1Zik7CglpZiAocmVzID09IE9LKQoJewoJICAgICpmbmFtZSA9IChjaGFyICopdmltX3N0cnNhdmUoYnVmKTsKCSAgICByZXR1cm4gdGJfYmxhbmtfeHBtOwoJfQogICAgfQoKICAgIGlmIChtZW51LT5pY29uX2J1aWx0aW4gfHwgZ3VpX2ZpbmRfYml0bWFwKG1lbnUtPm5hbWUsIGJ1ZiwgInhwbSIpID09IEZBSUwpCiAgICB7CglpZiAobWVudS0+aWNvbmlkeCA+PSAwICYmIG1lbnUtPmljb25pZHgKCQkgICA8IChzaXplb2YoYnVpbHRfaW5fcGl4bWFwcykgLyBzaXplb2YoYnVpbHRfaW5fcGl4bWFwc1swXSkpKQoJICAgIHhwbSA9IGJ1aWx0X2luX3BpeG1hcHNbbWVudS0+aWNvbmlkeF07CgllbHNlCgkgICAgeHBtID0gdGJfYmxhbmtfeHBtOwogICAgfQoKICAgIHJldHVybiB4cG07Cn0KCi8qCiAqIEFkZCBhcmd1bWVudHMgZm9yIHRoZSB0b29sYmFyIHBpeG1hcCB0byBhIG1lbnUgaXRlbS4KICovCiAgICBzdGF0aWMgaW50CmFkZF9waXhtYXBfYXJncyhtZW51LCBhcmdzLCBuKQogICAgdmltbWVudV9UCSptZW51OwogICAgQXJnCQkqYXJnczsKICAgIGludAkJbjsKewogICAgdmltX2ZyZWUobWVudS0+eHBtX2ZuYW1lKTsKICAgIG1lbnUtPnhwbSA9IGdldF90b29sYmFyX3BpeG1hcChtZW51LCAmbWVudS0+eHBtX2ZuYW1lKTsKICAgIGlmIChtZW51LT54cG0gPT0gTlVMTCkKICAgIHsKCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxhYmVsVHlwZSwgWG1TVFJJTkcpOyBuKys7CiAgICB9CiAgICBlbHNlCiAgICB7CglpZiAobWVudS0+eHBtX2ZuYW1lICE9IE5VTEwpCgl7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OcGl4bWFwRmlsZSwgbWVudS0+eHBtX2ZuYW1lKTsgbisrOwoJfQoJWHRTZXRBcmcoYXJnc1tuXSwgWG1OcGl4bWFwRGF0YSwgbWVudS0+eHBtKTsgbisrOwoJWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGFiZWxMb2NhdGlvbiwgWG1CT1RUT00pOyBuKys7CiAgICB9CiAgICByZXR1cm4gbjsKfQojZW5kaWYgLyogRkVBVF9UT09MQkFSICovCgogICAgdm9pZApndWlfbWNoX2FkZF9tZW51X2l0ZW0obWVudSwgaWR4KQogICAgdmltbWVudV9UCSptZW51OwogICAgaW50CQlpZHg7CnsKICAgIFhtU3RyaW5nCWxhYmVsOwogICAgdmltbWVudV9UCSpwYXJlbnQgPSBtZW51LT5wYXJlbnQ7CgojIGlmZGVmIEVCQ0RJQwogICAgbWVudS0+bW5lbW9uaWMgPSAwOwojIGVuZGlmCgojIGlmIChYbVZlcnNpb24gPD0gMTAwMikKICAgIC8qIERvbid0IGFkZCBQb3B1cCBtZW51IGl0ZW1zIHdoZW4gdGhlIHBvcHVwIG1lbnUgaXNuJ3QgdXNlZC4gKi8KICAgIGlmIChtZW51X2lzX2NoaWxkX29mX3BvcHVwKG1lbnUpICYmICFtb3VzZV9tb2RlbF9wb3B1cCgpKQoJcmV0dXJuOwojIGVuZGlmCgojIGlmZGVmIEZFQVRfVE9PTEJBUgogICAgaWYgKG1lbnVfaXNfdG9vbGJhcihwYXJlbnQtPm5hbWUpKQogICAgewoJV2lkZ2V0Q2xhc3MJdHlwZTsKCVhtU3RyaW5nCXhtcyA9IE5VTEw7ICAgIC8qIGZhbGxiYWNrIGxhYmVsIGlmIHBpeG1hcCBub3QgZm91bmQgKi8KCWludAkJbjsKCUFyZwkJYXJnc1sxOF07CgoJbiA9IDA7CglpZiAobWVudV9pc19zZXBhcmF0b3IobWVudS0+bmFtZSkpCgl7CgkgICAgY2hhcgkqY3A7CgkgICAgRGltZW5zaW9uCXdpZDsKCgkgICAgLyoKCSAgICAgKiBBIHNlcGFyYXRvciBoYXMgdGhlIGZvcm1hdCAiLXNlcCVkWzolZF0tIi4gVGhlIG9wdGlvbmFsIDolZCBpcwoJICAgICAqIGEgd2lkdGggc3BlY2lmaWVyLiBJZiBubyB3aWR0aCBpcyBzcGVjaWZpZWQgdGhlbiB3ZSBjaG9vc2Ugb25lLgoJICAgICAqLwoJICAgIGNwID0gKGNoYXIgKil2aW1fc3RyY2hyKG1lbnUtPm5hbWUsICc6Jyk7CgkgICAgaWYgKGNwICE9IE5VTEwpCgkJd2lkID0gKERpbWVuc2lvbilhdG9pKCsrY3ApOwoJICAgIGVsc2UKCQl3aWQgPSA0OwoKI2lmIDAKCSAgICAvKiBXZSBiZXR0ZXIgdXNlIGEgRm9ybVdpZGdldCBoZXJlLCBzaW5jZSBpdCdzIGZhciBtb3JlCgkgICAgICogZmxleGlibGUgaW4gdGVybXMgb2Ygc2l6ZS4gICovCgkgICAgdHlwZSA9IHhtRm9ybVdpZGdldENsYXNzOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTndpZHRoLCB3aWQpOyBuKys7CiNlbHNlCgkgICAgdHlwZSA9IHhtU2VwYXJhdG9yV2lkZ2V0Q2xhc3M7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1Od2lkdGgsIHdpZCk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5taW5XaWR0aCwgd2lkKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm9yaWVudGF0aW9uLCBYbVZFUlRJQ0FMKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnNlcGFyYXRvclR5cGUsIFhtU0hBRE9XX0VUQ0hFRF9JTik7IG4rKzsKI2VuZGlmCgl9CgllbHNlCgl7CgkgICAgLyogV2l0aG91dCBzaGFkb3dzIG9uZSBjYW4ndCBzZW5zZSB3aGF0ZXZlciB0aGUgYnV0dG9uIGhhcyBiZWVuCgkgICAgICogcHJlc3NlZCBvciBub3QhIEhvd2V2ZXIgd2Ugd2FuJ3QgdG8gc2F2ZSBhIGJpdCBvZiBzcGFjZS4uLgoJICAgICAqIE5lZWQgdGhlIGhpZ2hsaWdodFRoaWNrbmVzcyB0byBzZWUgdGhlIGZvY3VzLgoJICAgICAqLwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmhpZ2hsaWdodFRoaWNrbmVzcywgMSk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5oaWdobGlnaHRPbkVudGVyLCBUcnVlKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm1hcmdpbldpZHRoLCAwKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm1hcmdpbkhlaWdodCwgMCk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU50cmF2ZXJzYWxPbiwgRmFsc2UpOyBuKys7CgkgICAgLyogU2V0IHRoZSBsYWJlbCBoZXJlLCBzbyB0aGF0IHdlIGNhbiBzd2l0Y2ggYmV0d2VlbiBpY29ucy90ZXh0CgkgICAgICogYnkgY2hhbmdpbmcgdGhlIFhtTmxhYmVsVHlwZSByZXNvdXJjZS4gKi8KCSAgICB4bXMgPSBYbVN0cmluZ0NyZWF0ZSgoY2hhciAqKW1lbnUtPmRuYW1lLCBTVFJJTkdfVEFHKTsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5sYWJlbFN0cmluZywgeG1zKTsgbisrOwoKCSAgICBuID0gYWRkX3BpeG1hcF9hcmdzKG1lbnUsIGFyZ3MsIG4pOwoKCSAgICB0eXBlID0geG1FbmhhbmNlZEJ1dHRvbldpZGdldENsYXNzOwoJfQoKCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnBvc2l0aW9uSW5kZXgsIGlkeCk7IG4rKzsKCWlmIChtZW51LT5pZCA9PSBOVUxMKQoJewoJICAgIG1lbnUtPmlkID0gWHRDcmVhdGVNYW5hZ2VkV2lkZ2V0KChjaGFyICopbWVudS0+ZG5hbWUsCgkJCXR5cGUsIHRvb2xCYXIsIGFyZ3MsIG4pOwoJICAgIGlmIChtZW51LT5pZCAhPSBOVUxMICYmIHR5cGUgPT0geG1FbmhhbmNlZEJ1dHRvbldpZGdldENsYXNzKQoJICAgIHsKCQlYdEFkZENhbGxiYWNrKG1lbnUtPmlkLAoJCQlYbU5hY3RpdmF0ZUNhbGxiYWNrLCBndWlfeDExX21lbnVfY2IsIG1lbnUpOwojIGlmZGVmIEZFQVRfRk9PVEVSCgkJWHRBZGRFdmVudEhhbmRsZXIobWVudS0+aWQsIEVudGVyV2luZG93TWFzaywgRmFsc2UsCgkJCXRvb2xiYXJidXR0b25fZW50ZXJfY2IsIG1lbnUpOwoJCVh0QWRkRXZlbnRIYW5kbGVyKG1lbnUtPmlkLCBMZWF2ZVdpbmRvd01hc2ssIEZhbHNlLAoJCQl0b29sYmFyYnV0dG9uX2xlYXZlX2NiLCBtZW51KTsKIyBlbmRpZgoJICAgIH0KCX0KCWVsc2UKCSAgICBYdFNldFZhbHVlcyhtZW51LT5pZCwgYXJncywgbik7CglpZiAoeG1zICE9IE5VTEwpCgkgICAgWG1TdHJpbmdGcmVlKHhtcyk7CgojIGlmZGVmIEZFQVRfQkVWQUwKCWd1aV9tY2hfbWVudV9zZXRfdGlwKG1lbnUpOwojIGVuZGlmCgoJbWVudS0+cGFyZW50ID0gcGFyZW50OwoJbWVudS0+c3VibWVudV9pZCA9IE5VTEw7CgkvKiBXaGVuIGFkZGluZyBmaXJzdCBpdGVtIHRvIHRvb2xiYXIgaXQgbWlnaHQgaGF2ZSB0byBiZSBlbmFibGVkIC4qLwoJaWYgKCFYdElzTWFuYWdlZChYdFBhcmVudCh0b29sQmFyKSkKCQkgICAgJiYgdmltX3N0cmNocihwX2dvLCBHT19UT09MQkFSKSAhPSBOVUxMKQoJICAgIGd1aV9tY2hfc2hvd190b29sYmFyKFRSVUUpOwoJZ3VpLnRvb2xiYXJfaGVpZ2h0ID0gZ3VpX21jaF9jb21wdXRlX3Rvb2xiYXJfaGVpZ2h0KCk7CglyZXR1cm47CiAgICB9IC8qIHRvb2xiYXIgbWVudSBpdGVtICovCiMgZW5kaWYKCiAgICAvKiBObyBwYXJlbnQsIG11c3QgYmUgYSBub24tbWVudWJhciBtZW51ICovCiAgICBpZiAocGFyZW50LT5zdWJtZW51X2lkID09IChXaWRnZXQpMCkKCXJldHVybjsKCiAgICBtZW51LT5zdWJtZW51X2lkID0gKFdpZGdldCkwOwoKICAgIC8qIEFkZCBtZW51IHNlcGFyYXRvciAqLwogICAgaWYgKG1lbnVfaXNfc2VwYXJhdG9yKG1lbnUtPm5hbWUpKQogICAgewoJbWVudS0+aWQgPSBYdFZhQ3JlYXRlV2lkZ2V0KCJzdWJNZW51IiwKCQl4bVNlcGFyYXRvckdhZGdldENsYXNzLCBwYXJlbnQtPnN1Ym1lbnVfaWQsCiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCgkJLyogY291bnQgdGhlIHRlYXJvZmYgaXRlbSAobmVlZGVkIGZvciBMZXNzVGlmKSAqLwoJCVhtTnBvc2l0aW9uSW5kZXgsIGlkeCArICh0ZWFyb2ZmX3ZhbCA9PSAoaW50KVhtVEVBUl9PRkZfRU5BQkxFRAoJCQkJCQkJCSAgICAgPyAxIDogMCksCiNlbmRpZgoJCU5VTEwpOwoJZ3VpX21vdGlmX21lbnVfY29sb3JzKG1lbnUtPmlkKTsKCXJldHVybjsKICAgIH0KCiAgICBsYWJlbCA9IFhtU3RyaW5nQ3JlYXRlKChjaGFyICopbWVudS0+ZG5hbWUsIFNUUklOR19UQUcpOwogICAgaWYgKGxhYmVsID09IE5VTEwpCglyZXR1cm47CiAgICBtZW51LT5pZCA9IFh0VmFDcmVhdGVXaWRnZXQoInN1Yk1lbnUiLAoJeG1QdXNoQnV0dG9uV2lkZ2V0Q2xhc3MsIHBhcmVudC0+c3VibWVudV9pZCwKCVhtTmxhYmVsU3RyaW5nLCBsYWJlbCwKCVhtTm1uZW1vbmljLCBtZW51LT5tbmVtb25pYywKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKCS8qIGNvdW50IHRoZSB0ZWFyb2ZmIGl0ZW0gKG5lZWRlZCBmb3IgTGVzc1RpZikgKi8KCVhtTnBvc2l0aW9uSW5kZXgsIGlkeCArICh0ZWFyb2ZmX3ZhbCA9PSAoaW50KVhtVEVBUl9PRkZfRU5BQkxFRAoJCQkJCQkJCSAgICAgPyAxIDogMCksCiNlbmRpZgoJTlVMTCk7CiAgICBndWlfbW90aWZfbWVudV9jb2xvcnMobWVudS0+aWQpOwogICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3QobWVudS0+aWQpOwogICAgWG1TdHJpbmdGcmVlKGxhYmVsKTsKCiAgICBpZiAobWVudS0+aWQgIT0gKFdpZGdldCkwKQogICAgewoJWHRBZGRDYWxsYmFjayhtZW51LT5pZCwgWG1OYWN0aXZhdGVDYWxsYmFjaywgZ3VpX3gxMV9tZW51X2NiLAoJCShYdFBvaW50ZXIpbWVudSk7CgkvKiBhZGQgYWNjZWxlcmF0b3IgdGV4dCAqLwoJZ3VpX21vdGlmX2FkZF9hY3RleHQobWVudSk7CiAgICB9Cn0KCiNpZiAoWG1WZXJzaW9uIDw9IDEwMDIpIHx8IGRlZmluZWQoUFJPVE8pCi8qCiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBkZXN0cm95L2NyZWF0ZSB0aGUgcG9wdXAgbWVudXMgZHluYW1pY2FsbHksCiAqIGFjY29yZGluZyB0byB0aGUgdmFsdWUgb2YgJ21vdXNlbW9kZWwnLgogKiBUaGlzIHdpbGwgZml4IHRoZSAicmlnaHQgbW91c2UgYnV0dG9uIGZyZWV6ZSIgdGhhdCBvY2N1cnMgd2hlbgogKiB0aGVyZSBleGlzdHMgYSBwb3B1cCBtZW51IGJ1dCBpdCBpc24ndCBtYW5hZ2VkLgogKi8KICAgIHZvaWQKZ3VpX21vdGlmX3VwZGF0ZV9tb3VzZW1vZGVsKG1lbnUpCiAgICB2aW1tZW51X1QJKm1lbnU7CnsKICAgIGludAkJaWR4ID0gMDsKCiAgICAvKiBXaGVuIEdVSSBoYXNuJ3Qgc3RhcnRlZCB0aGUgbWVudXMgaGF2ZSBub3QgYmVlbiBjcmVhdGVkLiAqLwogICAgaWYgKCFndWkuaW5fdXNlKQogICAgICByZXR1cm47CgogICAgd2hpbGUgKG1lbnUpCiAgICB7CiAgICAgIGlmIChtZW51LT5jaGlsZHJlbiAhPSBOVUxMKQogICAgICB7CgkgIGlmIChtZW51X2lzX3BvcHVwKG1lbnUtPm5hbWUpKQoJICB7CgkgICAgICBpZiAobW91c2VfbW9kZWxfcG9wdXAoKSkKCSAgICAgIHsKCQkgIC8qIFBvcHVwIG1lbnUgd2lsbCBiZSB1c2VkLiAgQ3JlYXRlIHRoZSBwb3B1cCBtZW51cy4gKi8KCQkgIGd1aV9tY2hfYWRkX21lbnUobWVudSwgaWR4KTsKCQkgIGd1aV9tb3RpZl91cGRhdGVfbW91c2Vtb2RlbChtZW51LT5jaGlsZHJlbik7CgkgICAgICB9CgkgICAgICBlbHNlCgkgICAgICB7CgkJICAvKiBQb3B1cCBtZW51IHdpbGwgbm90IGJlIHVzZWQuICBEZXN0cm95IHRoZSBwb3B1cCBtZW51cy4gKi8KCQkgIGd1aV9tb3RpZl91cGRhdGVfbW91c2Vtb2RlbChtZW51LT5jaGlsZHJlbik7CgkJICBndWlfbWNoX2Rlc3Ryb3lfbWVudShtZW51KTsKCSAgICAgIH0KCSAgfQogICAgICB9CiAgICAgIGVsc2UgaWYgKG1lbnVfaXNfY2hpbGRfb2ZfcG9wdXAobWVudSkpCiAgICAgIHsKCSAgaWYgKG1vdXNlX21vZGVsX3BvcHVwKCkpCgkgICAgICBndWlfbWNoX2FkZF9tZW51X2l0ZW0obWVudSwgaWR4KTsKCSAgZWxzZQoJICAgICAgZ3VpX21jaF9kZXN0cm95X21lbnUobWVudSk7CiAgICAgIH0KICAgICAgbWVudSA9IG1lbnUtPm5leHQ7CiAgICAgICsraWR4OwogICAgfQp9CiNlbmRpZgoKICAgIHZvaWQKZ3VpX21jaF9uZXdfbWVudV9jb2xvcnMoKQp7CiAgICBpZiAobWVudUJhciA9PSAoV2lkZ2V0KTApCglyZXR1cm47CiAgICBndWlfbW90aWZfbWVudV9jb2xvcnMobWVudUJhcik7CiNpZmRlZiBGRUFUX1RPT0xCQVIKICAgIGd1aV9tb3RpZl9tZW51X2NvbG9ycyh0b29sQmFyRnJhbWUpOwogICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKHRvb2xCYXIpOwojZW5kaWYKCiAgICBzdWJtZW51X2NoYW5nZShyb290X21lbnUsIFRSVUUpOwp9CgogICAgdm9pZApndWlfbWNoX25ld19tZW51X2ZvbnQoKQp7CiAgICBpZiAobWVudUJhciA9PSAoV2lkZ2V0KTApCglyZXR1cm47CiAgICBzdWJtZW51X2NoYW5nZShyb290X21lbnUsIEZBTFNFKTsKICAgIHsKCURpbWVuc2lvbiAgIGhlaWdodDsKCVBvc2l0aW9uIHcsIGg7CgoJWHRWYUdldFZhbHVlcyhtZW51QmFyLCBYbU5oZWlnaHQsICZoZWlnaHQsIE5VTEwpOwoJZ3VpLm1lbnVfaGVpZ2h0ID0gaGVpZ2h0OwoKCVh0VmFHZXRWYWx1ZXModmltU2hlbGwsIFh0TndpZHRoLCAmdywgWHROaGVpZ2h0LCAmaCwgTlVMTCk7CglndWlfcmVzaXplX3NoZWxsKHcsIGgKI2lmZGVmIEZFQVRfWElNCgkJLSB4aW1fZ2V0X3N0YXR1c19hcmVhX2hlaWdodCgpCiNlbmRpZgoJCSAgICAgKTsKICAgIH0KICAgIGd1aV9zZXRfc2hlbGxzaXplKEZBTFNFLCBUUlVFLCBSRVNJWkVfVkVSVCk7CiAgICB1aV9uZXdfc2hlbGxzaXplKCk7Cn0KCiNpZiBkZWZpbmVkKEZFQVRfQkVWQUwpIHx8IGRlZmluZWQoUFJPVE8pCiAgICB2b2lkCmd1aV9tY2hfbmV3X3Rvb2x0aXBfZm9udCgpCnsKIyBpZmRlZiBGRUFUX1RPT0xCQVIKICAgIHZpbW1lbnVfVCAgICptZW51OwoKICAgIGlmICh0b29sQmFyID09IChXaWRnZXQpMCkKCXJldHVybjsKCiAgICBtZW51ID0gZ3VpX2ZpbmRfbWVudSgoY2hhcl91ICopIlRvb2xCYXIiKTsKICAgIGlmIChtZW51ICE9IE5VTEwpCglzdWJtZW51X2NoYW5nZShtZW51LCBGQUxTRSk7CiMgZW5kaWYKfQoKICAgIHZvaWQKZ3VpX21jaF9uZXdfdG9vbHRpcF9jb2xvcnMoKQp7CiMgaWZkZWYgRkVBVF9UT09MQkFSCiAgICB2aW1tZW51X1QgICAqdG9vbGJhcjsKCiAgICBpZiAodG9vbEJhciA9PSAoV2lkZ2V0KTApCglyZXR1cm47CgogICAgdG9vbGJhciA9IGd1aV9maW5kX21lbnUoKGNoYXJfdSAqKSJUb29sQmFyIik7CiAgICBpZiAodG9vbGJhciAhPSBOVUxMKQoJc3VibWVudV9jaGFuZ2UodG9vbGJhciwgVFJVRSk7CiMgZW5kaWYKfQojZW5kaWYKCiAgICBzdGF0aWMgdm9pZApzdWJtZW51X2NoYW5nZShtZW51LCBjb2xvcnMpCiAgICB2aW1tZW51X1QJKm1lbnU7CiAgICBpbnQJCWNvbG9yczsJCS8qIFRSVUUgZm9yIGNvbG9ycywgRkFMU0UgZm9yIGZvbnQgKi8KewogICAgdmltbWVudV9UCSptcDsKCiAgICBmb3IgKG1wID0gbWVudTsgbXAgIT0gTlVMTDsgbXAgPSBtcC0+bmV4dCkKICAgIHsKCWlmIChtcC0+aWQgIT0gKFdpZGdldCkwKQoJewoJICAgIGlmIChjb2xvcnMpCgkgICAgewoJCWd1aV9tb3RpZl9tZW51X2NvbG9ycyhtcC0+aWQpOwojaWZkZWYgRkVBVF9UT09MQkFSCgkJLyogRm9yIGEgdG9vbGJhciBpdGVtOiBGcmVlIHRoZSBwaXhtYXAgYW5kIGFsbG9jYXRlIGEgbmV3IG9uZSwKCQkgKiBzbyB0aGF0IHRoZSBiYWNrZ3JvdW5kIGNvbG9yIGlzIHJpZ2h0LiAqLwoJCWlmIChtcC0+eHBtICE9IE5VTEwpCgkJewoJCSAgICBpbnQJCW4gPSAwOwoJCSAgICBBcmcJCWFyZ3NbMThdOwoKCQkgICAgbiA9IGFkZF9waXhtYXBfYXJncyhtcCwgYXJncywgbik7CgkJICAgIFh0U2V0VmFsdWVzKG1wLT5pZCwgYXJncywgbik7CgkJfQojIGlmZGVmIEZFQVRfQkVWQUwKCQkvKiBJZiB3ZSBoYXZlIGEgdG9vbHRpcCwgdGhlbiB3ZSBuZWVkIHRvIGNoYW5nZSBpdCdzIGZvbnQgKi8KCQlpZiAobXAtPnRpcCAhPSBOVUxMKQoJCXsKCQkgICAgQXJnIGFyZ3NbMl07CgoJCSAgICBhcmdzWzBdLm5hbWUgPSBYbU5iYWNrZ3JvdW5kOwoJCSAgICBhcmdzWzBdLnZhbHVlID0gZ3VpLnRvb2x0aXBfYmdfcGl4ZWw7CgkJICAgIGFyZ3NbMV0ubmFtZSA9IFhtTmZvcmVncm91bmQ7CgkJICAgIGFyZ3NbMV0udmFsdWUgPSBndWkudG9vbHRpcF9mZ19waXhlbDsKCQkgICAgWHRTZXRWYWx1ZXMobXAtPnRpcC0+YmFsbG9vbkxhYmVsLCAmYXJnc1swXSwgWHROdW1iZXIoYXJncykpOwoJCX0KIyBlbmRpZgojZW5kaWYKCSAgICB9CgkgICAgZWxzZQoJICAgIHsKCQlndWlfbW90aWZfbWVudV9mb250bGlzdChtcC0+aWQpOwojaWZkZWYgRkVBVF9CRVZBTAoJCS8qIElmIHdlIGhhdmUgYSB0b29sdGlwLCB0aGVuIHdlIG5lZWQgdG8gY2hhbmdlIGl0J3MgZm9udCAqLwoJCWlmIChtcC0+dGlwICE9IE5VTEwpCgkJewoJCSAgICBBcmcgYXJnc1sxXTsKCgkJICAgIGFyZ3NbMF0ubmFtZSA9IFhtTmZvbnRMaXN0OwoJCSAgICBhcmdzWzBdLnZhbHVlID0gKFh0QXJnVmFsKWd1aV9tb3RpZl9mb250c2V0MmZvbnRsaXN0KAoJCQkJCQkgICAgJmd1aS50b29sdGlwX2ZvbnRzZXQpOwoJCSAgICBYdFNldFZhbHVlcyhtcC0+dGlwLT5iYWxsb29uTGFiZWwsICZhcmdzWzBdLCBYdE51bWJlcihhcmdzKSk7CgkJfQojZW5kaWYKCSAgICB9Cgl9CgoJaWYgKG1wLT5jaGlsZHJlbiAhPSBOVUxMKQoJewojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQoJICAgIC8qIFNldCB0aGUgY29sb3JzL2ZvbnQgZm9yIHRoZSB0ZWFyIG9mZiB3aWRnZXQgKi8KCSAgICBpZiAobXAtPnN1Ym1lbnVfaWQgIT0gKFdpZGdldCkwKQoJICAgIHsKCQlpZiAoY29sb3JzKQoJCSAgICBndWlfbW90aWZfbWVudV9jb2xvcnMobXAtPnN1Ym1lbnVfaWQpOwoJCWVsc2UKCQkgICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3QobXAtPnN1Ym1lbnVfaWQpOwoJCXRvZ2dsZV90ZWFyb2ZmKG1wLT5zdWJtZW51X2lkKTsKCSAgICB9CiNlbmRpZgoJICAgIC8qIFNldCB0aGUgY29sb3JzIGZvciB0aGUgY2hpbGRyZW4gKi8KCSAgICBzdWJtZW51X2NoYW5nZShtcC0+Y2hpbGRyZW4sIGNvbG9ycyk7Cgl9CiAgICB9Cn0KCi8qCiAqIERlc3Ryb3kgdGhlIG1hY2hpbmUgc3BlY2lmaWMgbWVudSB3aWRnZXQuCiAqLwogICAgdm9pZApndWlfbWNoX2Rlc3Ryb3lfbWVudShtZW51KQogICAgdmltbWVudV9UCSptZW51Owp7CiAgICAvKiBQbGVhc2UgYmUgc3VyZSB0byBkZXN0cm95IHRoZSBwYXJlbnQgd2lkZ2V0IGZpcnN0IChpLmUuIG1lbnUtPmlkKS4KICAgICAqIE9uIHRoZSBvdGhlciBoYW5kLCBwcm9ibGVtcyBoYXZlIGJlZW4gcmVwb3J0ZWQgdGhhdCB0aGUgc3VibWVudSBtdXN0IGJlCiAgICAgKiBkZWxldGVkIGZpcnN0Li4uCiAgICAgKgogICAgICogVGhpcyBjb2RlIHNob3VsZCBiZSBiYXNpY2FsbHkgaWRlbnRpY2FsIHRvIHRoYXQgaW4gdGhlIGZpbGUgZ3VpX2F0aGVuYS5jCiAgICAgKiBiZWNhdXNlIHRoZXkgYXJlIGJvdGggWHQgYmFzZWQuCiAgICAgKi8KICAgIGlmIChtZW51LT5zdWJtZW51X2lkICE9IChXaWRnZXQpMCkKICAgIHsKCVh0RGVzdHJveVdpZGdldChtZW51LT5zdWJtZW51X2lkKTsKCW1lbnUtPnN1Ym1lbnVfaWQgPSAoV2lkZ2V0KTA7CiAgICB9CgogICAgaWYgKG1lbnUtPmlkICE9IChXaWRnZXQpMCkKICAgIHsKCVdpZGdldAkgICAgcGFyZW50OwoKCXBhcmVudCA9IFh0UGFyZW50KG1lbnUtPmlkKTsKI2lmIGRlZmluZWQoRkVBVF9UT09MQkFSKSAmJiBkZWZpbmVkKEZFQVRfQkVWQUwpCglpZiAocGFyZW50ID09IHRvb2xCYXIgJiYgbWVudS0+dGlwICE9IE5VTEwpCgl7CgkgICAgLyogV2UgdHJ5IHRvIGRlc3Ryb3kgdGhpcyBiZWZvcmUgdGhlIGFjdHVhbCBtZW51LCBiZWNhdXNlIHRoZXJlIGFyZQoJICAgICAqIGNhbGxiYWNrcywgZXRjLiB0aGF0IHdpbGwgYmUgdW5yZWdpc3RlcmVkIGR1cmluZyB0aGUgdG9vbHRpcAoJICAgICAqIGRlc3RydWN0aW9uLgoJICAgICAqCgkgICAgICogSWYgeW91IGNhbGwgImd1aV9tY2hfZGVzdHJveV9iZXZhbF9hcmVhKCkiIGFmdGVyIGRlc3Ryb3lpbmcKCSAgICAgKiBtZW51LT5pZCwgdGhlbiB0aGUgdG9vbHRpcCdzIHdpbmRvdyB3aWxsIGhhdmUgYWxyZWFkeSBiZWVuCgkgICAgICogZGVhbGxvY2F0ZWQgYnkgWHQsIGFuZCB1bmtub3duIGJlaGF2aW91ciB3aWxsIGVuc3VlIChwcm9iYWJseQoJICAgICAqIGEgY29yZSBkdW1wKS4KCSAgICAgKi8KCSAgICBndWlfbWNoX2Rlc3Ryb3lfYmV2YWxfYXJlYShtZW51LT50aXApOwoJICAgIG1lbnUtPnRpcCA9IE5VTEw7Cgl9CiNlbmRpZgoJWHREZXN0cm95V2lkZ2V0KG1lbnUtPmlkKTsKCW1lbnUtPmlkID0gKFdpZGdldCkwOwoJaWYgKHBhcmVudCA9PSBtZW51QmFyKQoJICAgIGd1aV9tY2hfY29tcHV0ZV9tZW51X2hlaWdodCgoV2lkZ2V0KTApOwojaWZkZWYgRkVBVF9UT09MQkFSCgllbHNlIGlmIChwYXJlbnQgPT0gdG9vbEJhcikKCXsKCSAgICBDYXJkaW5hbCAgICBudW1fY2hpbGRyZW47CgoJICAgIC8qIFdoZW4gcmVtb3ZpbmcgbGFzdCB0b29sYmFyIGl0ZW0sIGRvbid0IGRpc3BsYXkgdGhlIHRvb2xiYXIuICovCgkgICAgWHRWYUdldFZhbHVlcyh0b29sQmFyLCBYbU5udW1DaGlsZHJlbiwgJm51bV9jaGlsZHJlbiwgTlVMTCk7CgkgICAgaWYgKG51bV9jaGlsZHJlbiA9PSAwKQoJCWd1aV9tY2hfc2hvd190b29sYmFyKEZBTFNFKTsKCSAgICBlbHNlCgkJZ3VpLnRvb2xiYXJfaGVpZ2h0ID0gZ3VpX21jaF9jb21wdXRlX3Rvb2xiYXJfaGVpZ2h0KCk7Cgl9CiNlbmRpZgogICAgfQp9CgovKiBBUkdTVVNFRCAqLwogICAgdm9pZApndWlfbWNoX3Nob3dfcG9wdXBtZW51KG1lbnUpCiAgICB2aW1tZW51X1QgKm1lbnU7CnsKI2lmZGVmIE1PVElGX1BPUFVQCiAgICBYbU1lbnVQb3NpdGlvbihtZW51LT5zdWJtZW51X2lkLCBndWlfeDExX2dldF9sYXN0X21vdXNlX2V2ZW50KCkpOwogICAgWHRNYW5hZ2VDaGlsZChtZW51LT5zdWJtZW51X2lkKTsKI2VuZGlmCn0KCiNlbmRpZiAvKiBGRUFUX01FTlUgKi8KCi8qCiAqIFNldCB0aGUgbWVudSBhbmQgc2Nyb2xsYmFyIGNvbG9ycyB0byB0aGVpciBkZWZhdWx0IHZhbHVlcy4KICovCiAgICB2b2lkCmd1aV9tY2hfZGVmX2NvbG9ycygpCnsKICAgIGlmIChndWkuaW5fdXNlKQogICAgewoJLyogVXNlIHRoZSB2YWx1ZXMgc2F2ZWQgd2hlbiBzdGFydGluZyB1cC4gIFRoZXNlIHNob3VsZCBjb21lIGZyb20gdGhlCgkgKiB3aW5kb3cgbWFuYWdlciBvciBhIHJlc291cmNlcyBmaWxlLiAqLwoJZ3VpLm1lbnVfZmdfcGl4ZWwgPSBndWkubWVudV9kZWZfZmdfcGl4ZWw7CglndWkubWVudV9iZ19waXhlbCA9IGd1aS5tZW51X2RlZl9iZ19waXhlbDsKCWd1aS5zY3JvbGxfZmdfcGl4ZWwgPSBndWkuc2Nyb2xsX2RlZl9mZ19waXhlbDsKCWd1aS5zY3JvbGxfYmdfcGl4ZWwgPSBndWkuc2Nyb2xsX2RlZl9iZ19waXhlbDsKI2lmZGVmIEZFQVRfQkVWQUwKCWd1aS50b29sdGlwX2ZnX3BpeGVsID0KCQkJZ3VpX2dldF9jb2xvcigoY2hhcl91ICopZ3VpLnJzcmNfdG9vbHRpcF9mZ19uYW1lKTsKCWd1aS50b29sdGlwX2JnX3BpeGVsID0KCQkJZ3VpX2dldF9jb2xvcigoY2hhcl91ICopZ3VpLnJzcmNfdG9vbHRpcF9iZ19uYW1lKTsKI2VuZGlmCiAgICB9Cn0KCgovKgogKiBTY3JvbGxiYXIgc3R1ZmYuCiAqLwoKICAgIHZvaWQKZ3VpX21jaF9zZXRfc2Nyb2xsYmFyX3RodW1iKHNiLCB2YWwsIHNpemUsIG1heCkKICAgIHNjcm9sbGJhcl9UICpzYjsKICAgIGxvbmcJdmFsOwogICAgbG9uZwlzaXplOwogICAgbG9uZwltYXg7CnsKICAgIGlmIChzYi0+aWQgIT0gKFdpZGdldCkwKQoJWHRWYVNldFZhbHVlcyhzYi0+aWQsCgkJICBYbU52YWx1ZSwgdmFsLAoJCSAgWG1Oc2xpZGVyU2l6ZSwgc2l6ZSwKCQkgIFhtTnBhZ2VJbmNyZW1lbnQsIChzaXplID4gMiA/IHNpemUgLSAyIDogMSksCgkJICBYbU5tYXhpbXVtLCBtYXggKyAxLAkgICAgLyogTW90aWYgaGFzIG1heCBvbmUgcGFzdCB0aGUgZW5kICovCgkJICBOVUxMKTsKfQoKICAgIHZvaWQKZ3VpX21jaF9zZXRfc2Nyb2xsYmFyX3BvcyhzYiwgeCwgeSwgdywgaCkKICAgIHNjcm9sbGJhcl9UICpzYjsKICAgIGludAkJeDsKICAgIGludAkJeTsKICAgIGludAkJdzsKICAgIGludAkJaDsKewogICAgaWYgKHNiLT5pZCAhPSAoV2lkZ2V0KTApCiAgICB7CglpZiAoc2ItPnR5cGUgPT0gU0JBUl9MRUZUIHx8IHNiLT50eXBlID09IFNCQVJfUklHSFQpCgl7CgkgICAgaWYgKHkgPT0gMCkKCQloIC09IGd1aS5ib3JkZXJfb2Zmc2V0OwoJICAgIGVsc2UKCQl5IC09IGd1aS5ib3JkZXJfb2Zmc2V0OwoJICAgIFh0VmFTZXRWYWx1ZXMoc2ItPmlkLAoJCQkgIFhtTnRvcE9mZnNldCwgeSwKCQkJICBYbU5ib3R0b21PZmZzZXQsIC15IC0gaCwKCQkJICBYbU53aWR0aCwgdywKCQkJICBOVUxMKTsKCX0KCWVsc2UKCSAgICBYdFZhU2V0VmFsdWVzKHNiLT5pZCwKCQkJICBYbU50b3BPZmZzZXQsIHksCgkJCSAgWG1ObGVmdE9mZnNldCwgeCwKCQkJICBYbU5yaWdodE9mZnNldCwgZ3VpLndoaWNoX3Njcm9sbGJhcnNbU0JBUl9SSUdIVF0KCQkJCQkJICAgID8gZ3VpLnNjcm9sbGJhcl93aWR0aCA6IDAsCgkJCSAgWG1OaGVpZ2h0LCBoLAoJCQkgIE5VTEwpOwoJWHRNYW5hZ2VDaGlsZChzYi0+aWQpOwogICAgfQp9CgogICAgdm9pZApndWlfbWNoX2VuYWJsZV9zY3JvbGxiYXIoc2IsIGZsYWcpCiAgICBzY3JvbGxiYXJfVCAqc2I7CiAgICBpbnQJCWZsYWc7CnsKICAgIEFyZwkJYXJnc1sxNl07CiAgICBpbnQJCW47CgogICAgaWYgKHNiLT5pZCAhPSAoV2lkZ2V0KTApCiAgICB7CgluID0gMDsKCWlmIChmbGFnKQoJewoJICAgIHN3aXRjaCAoc2ItPnR5cGUpCgkgICAgewoJCWNhc2UgU0JBUl9MRUZUOgoJCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5sZWZ0T2Zmc2V0LCBndWkuc2Nyb2xsYmFyX3dpZHRoKTsgbisrOwoJCSAgICBicmVhazsKCgkJY2FzZSBTQkFSX1JJR0hUOgoJCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5yaWdodE9mZnNldCwgZ3VpLnNjcm9sbGJhcl93aWR0aCk7IG4rKzsKCQkgICAgYnJlYWs7CgoJCWNhc2UgU0JBUl9CT1RUT006CgkJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmJvdHRvbU9mZnNldCwgZ3VpLnNjcm9sbGJhcl9oZWlnaHQpO24rKzsKCQkgICAgYnJlYWs7CgkgICAgfQoJICAgIFh0U2V0VmFsdWVzKHRleHRBcmVhLCBhcmdzLCBuKTsKCSAgICBYdE1hbmFnZUNoaWxkKHNiLT5pZCk7Cgl9CgllbHNlCgl7CgkgICAgaWYgKCFndWkud2hpY2hfc2Nyb2xsYmFyc1tzYi0+dHlwZV0pCgkgICAgewoJCS8qIFRoZSBzY3JvbGxiYXJzIG9mIHRoaXMgdHlwZSBhcmUgYWxsIGRpc2FibGVkLCBhZGp1c3QgdGhlCgkJICogdGV4dEFyZWEgYXR0YWNobWVudCBvZmZzZXQuICovCgkJc3dpdGNoIChzYi0+dHlwZSkKCQl7CgkJICAgIGNhc2UgU0JBUl9MRUZUOgoJCQlYdFNldEFyZyhhcmdzW25dLCBYbU5sZWZ0T2Zmc2V0LCAwKTsgbisrOwoJCQlicmVhazsKCgkJICAgIGNhc2UgU0JBUl9SSUdIVDoKCQkJWHRTZXRBcmcoYXJnc1tuXSwgWG1OcmlnaHRPZmZzZXQsIDApOyBuKys7CgkJCWJyZWFrOwoKCQkgICAgY2FzZSBTQkFSX0JPVFRPTToKCQkJWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tT2Zmc2V0LCAwKTtuKys7CgkJCWJyZWFrOwoJCX0KCQlYdFNldFZhbHVlcyh0ZXh0QXJlYSwgYXJncywgbik7CgkgICAgfQoJICAgIFh0VW5tYW5hZ2VDaGlsZChzYi0+aWQpOwoJfQogICAgfQp9CgogICAgdm9pZApndWlfbWNoX2NyZWF0ZV9zY3JvbGxiYXIoc2IsIG9yaWVudCkKICAgIHNjcm9sbGJhcl9UICpzYjsKICAgIGludAkJb3JpZW50OwkvKiBTQkFSX1ZFUlQgb3IgU0JBUl9IT1JJWiAqLwp7CiAgICBBcmcJCWFyZ3NbMTZdOwogICAgaW50CQluOwoKICAgIG4gPSAwOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1ObWluaW11bSwgMCk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm9yaWVudGF0aW9uLAoJICAgIChvcmllbnQgPT0gU0JBUl9WRVJUKSA/IFhtVkVSVElDQUwgOiBYbUhPUklaT05UQUwpOyBuKys7CgogICAgc3dpdGNoIChzYi0+dHlwZSkKICAgIHsKCWNhc2UgU0JBUl9MRUZUOgoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfT1BQT1NJVEVfRk9STSk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKCSAgICBicmVhazsKCgljYXNlIFNCQVJfUklHSFQ6CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9PUFBPU0lURV9GT1JNKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKCSAgICBicmVhazsKCgljYXNlIFNCQVJfQk9UVE9NOgoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgbisrOwoJICAgIGJyZWFrOwogICAgfQoKICAgIHNiLT5pZCA9IFh0Q3JlYXRlV2lkZ2V0KCJzY3JvbGxCYXIiLAoJICAgIHhtU2Nyb2xsQmFyV2lkZ2V0Q2xhc3MsIHRleHRBcmVhRm9ybSwgYXJncywgbik7CgogICAgLyogUmVtZW1iZXIgdGhlIGRlZmF1bHQgY29sb3JzLCBuZWVkZWQgZm9yICI6aGkgY2xlYXIiLiAqLwogICAgaWYgKGd1aS5zY3JvbGxfZGVmX2JnX3BpeGVsID09IChndWljb2xvcl9UKTAKCSAgICAmJiBndWkuc2Nyb2xsX2RlZl9mZ19waXhlbCA9PSAoZ3VpY29sb3JfVCkwKQoJWHRWYUdldFZhbHVlcyhzYi0+aWQsCgkJWG1OYmFja2dyb3VuZCwgJmd1aS5zY3JvbGxfZGVmX2JnX3BpeGVsLAoJCVhtTmZvcmVncm91bmQsICZndWkuc2Nyb2xsX2RlZl9mZ19waXhlbCwKCQlOVUxMKTsKCiAgICBpZiAoc2ItPmlkICE9IChXaWRnZXQpMCkKICAgIHsKCWd1aV9tY2hfc2V0X3Njcm9sbGJhcl9jb2xvcnMoc2IpOwoJWHRBZGRDYWxsYmFjayhzYi0+aWQsIFhtTnZhbHVlQ2hhbmdlZENhbGxiYWNrLAoJCSAgICAgIHNjcm9sbF9jYiwgKFh0UG9pbnRlcilzYi0+aWRlbnQpOwoJWHRBZGRDYWxsYmFjayhzYi0+aWQsIFhtTmRyYWdDYWxsYmFjaywKCQkgICAgICBzY3JvbGxfY2IsIChYdFBvaW50ZXIpc2ItPmlkZW50KTsKCVh0QWRkRXZlbnRIYW5kbGVyKHNiLT5pZCwgS2V5UHJlc3NNYXNrLCBGQUxTRSwgZ3VpX3gxMV9rZXlfaGl0X2NiLAoJICAgIChYdFBvaW50ZXIpMCk7CiAgICB9Cn0KCiNpZiBkZWZpbmVkKEZFQVRfV0lORE9XUykgfHwgZGVmaW5lZChQUk9UTykKICAgIHZvaWQKZ3VpX21jaF9kZXN0cm95X3Njcm9sbGJhcihzYikKICAgIHNjcm9sbGJhcl9UICpzYjsKewogICAgaWYgKHNiLT5pZCAhPSAoV2lkZ2V0KTApCglYdERlc3Ryb3lXaWRnZXQoc2ItPmlkKTsKfQojZW5kaWYKCiAgICB2b2lkCmd1aV9tY2hfc2V0X3Njcm9sbGJhcl9jb2xvcnMoc2IpCiAgICBzY3JvbGxiYXJfVCAqc2I7CnsKICAgIGlmIChzYi0+aWQgIT0gKFdpZGdldCkwKQogICAgewoJaWYgKGd1aS5zY3JvbGxfYmdfcGl4ZWwgIT0gSU5WQUxDT0xPUikKCXsKI2lmIChYbVZlcnNpb24+PTEwMDIpCgkgICAgWG1DaGFuZ2VDb2xvcihzYi0+aWQsIGd1aS5zY3JvbGxfYmdfcGl4ZWwpOwojZWxzZQoJICAgIFh0VmFTZXRWYWx1ZXMoc2ItPmlkLAoJCSAgICBYbU50cm91Z2hDb2xvciwgZ3VpLnNjcm9sbF9iZ19waXhlbCwKCQkgICAgTlVMTCk7CiNlbmRpZgoJfQoKCWlmIChndWkuc2Nyb2xsX2ZnX3BpeGVsICE9IElOVkFMQ09MT1IpCgkgICAgWHRWYVNldFZhbHVlcyhzYi0+aWQsCgkJICAgIFhtTmZvcmVncm91bmQsIGd1aS5zY3JvbGxfZmdfcGl4ZWwsCiNpZiAoWG1WZXJzaW9uPDEwMDIpCgkJICAgIFhtTmJhY2tncm91bmQsIGd1aS5zY3JvbGxfZmdfcGl4ZWwsCiNlbmRpZgoJCSAgICBOVUxMKTsKICAgIH0KCiAgICAvKiBUaGlzIGlzIG5lZWRlZCBmb3IgdGhlIHJlY3RhbmdsZSBiZWxvdyB0aGUgdmVydGljYWwgc2Nyb2xsYmFycy4gKi8KICAgIGlmIChzYiA9PSAmZ3VpLmJvdHRvbV9zYmFyICYmIHRleHRBcmVhRm9ybSAhPSAoV2lkZ2V0KTApCglndWlfbW90aWZfc2Nyb2xsX2NvbG9ycyh0ZXh0QXJlYUZvcm0pOwp9CgovKgogKiBNaXNjZWxsYW5lb3VzIHN0dWZmOgogKi8KCiAgICBXaW5kb3cKZ3VpX3gxMV9nZXRfd2lkKCkKewogICAgcmV0dXJuKFh0V2luZG93KHRleHRBcmVhKSk7Cn0KCi8qCiAqIExvb2sgZm9yIGEgd2lkZ2V0IGluIHRoZSB3aWRnZXQgdHJlZSB3LCB3aXRoIGEgbW5lbW9uaWMgbWF0Y2hpbmcga2V5Y29kZS4KICogV2hlbiBvbmUgaXMgZm91bmQsIHNpbXVsYXRlIGEgYnV0dG9uIHByZXNzIG9uIHRoYXQgd2lkZ2V0IGFuZCBnaXZlIGl0IHRoZQogKiBrZXlib2FyZCBmb2N1cy4gIElmIHRoZSBtbmVtb25pYyBpcyBvbiBhIGxhYmVsLCBsb29rIGluIHRoZSB1c2VyRGF0YSBmaWVsZAogKiBvZiB0aGUgbGFiZWwgdG8gc2VlIGlmIGl0IHBvaW50cyB0byBhbm90aGVyIHdpZGdldCwgYW5kIGdpdmUgdGhhdCB0aGUgZm9jdXMuCiAqLwogICAgc3RhdGljIHZvaWQKZG9fbW5lbW9uaWMoV2lkZ2V0IHcsIHVuc2lnbmVkIGludCBrZXljb2RlKQp7CiAgICBXaWRnZXRMaXN0CSAgICBjaGlsZHJlbjsKICAgIGludAkJICAgIG51bUNoaWxkcmVuLCBpOwogICAgQm9vbGVhbgkgICAgaXNNZW51OwogICAgS2V5U3ltCSAgICBtbmVtb25pYyA9ICdcMCc7CiAgICBjaGFyCSAgICBtbmVTdHJpbmdbMl07CiAgICBXaWRnZXQJICAgIHVzZXJEYXRhOwogICAgdW5zaWduZWQgY2hhciAgIHJvd0NvbFR5cGU7CgogICAgaWYgKFh0SXNDb21wb3NpdGUodykpCiAgICB7CglpZiAoWHRDbGFzcyh3KSA9PSB4bVJvd0NvbHVtbldpZGdldENsYXNzKQoJewoJICAgIFh0VmFHZXRWYWx1ZXModywgWG1Ocm93Q29sdW1uVHlwZSwgJnJvd0NvbFR5cGUsIDApOwoJICAgIGlzTWVudSA9IChyb3dDb2xUeXBlICE9ICh1bnNpZ25lZCBjaGFyKVhtV09SS19BUkVBKTsKCX0KCWVsc2UKCSAgICBpc01lbnUgPSBGYWxzZTsKCWlmICghaXNNZW51KQoJewoJICAgIFh0VmFHZXRWYWx1ZXModywgWG1OY2hpbGRyZW4sICZjaGlsZHJlbiwgWG1ObnVtQ2hpbGRyZW4sCgkJCSAgJm51bUNoaWxkcmVuLCAwKTsKCSAgICBmb3IgKGkgPSAwOyBpIDwgbnVtQ2hpbGRyZW47IGkrKykKCQlkb19tbmVtb25pYyhjaGlsZHJlbltpXSwga2V5Y29kZSk7Cgl9CiAgICB9CiAgICBlbHNlCiAgICB7CglYdFZhR2V0VmFsdWVzKHcsIFhtTm1uZW1vbmljLCAmbW5lbW9uaWMsIDApOwoJaWYgKG1uZW1vbmljICE9ICdcMCcpCgl7CgkgICAgbW5lU3RyaW5nWzBdID0gbW5lbW9uaWM7CgkgICAgbW5lU3RyaW5nWzFdID0gJ1wwJzsKCSAgICBpZiAoWEtleXN5bVRvS2V5Y29kZShYdERpc3BsYXkoWHRQYXJlbnQodykpLAoJCQkJICAgICAgIFhTdHJpbmdUb0tleXN5bShtbmVTdHJpbmcpKSA9PSBrZXljb2RlKQoJICAgIHsKCQlpZiAoWHRDbGFzcyh3KSA9PSB4bUxhYmVsV2lkZ2V0Q2xhc3MKCQkJfHwgWHRDbGFzcyh3KSA9PSB4bUxhYmVsR2FkZ2V0Q2xhc3MpCgkJewoJCSAgICBYdFZhR2V0VmFsdWVzKHcsIFhtTnVzZXJEYXRhLCAmdXNlckRhdGEsIDApOwoJCSAgICBpZiAodXNlckRhdGEgIT0gTlVMTCAmJiBYdElzV2lkZ2V0KHVzZXJEYXRhKSkKCQkJWG1Qcm9jZXNzVHJhdmVyc2FsKHVzZXJEYXRhLCBYbVRSQVZFUlNFX0NVUlJFTlQpOwoJCX0KCQllbHNlCgkJewoJCSAgICBYS2V5UHJlc3NlZEV2ZW50IGtleUV2ZW50OwoKCQkgICAgWG1Qcm9jZXNzVHJhdmVyc2FsKHcsIFhtVFJBVkVSU0VfQ1VSUkVOVCk7CgoJCSAgICBtZW1zZXQoKGNoYXIgKikgJmtleUV2ZW50LCAwLCBzaXplb2YoWEtleVByZXNzZWRFdmVudCkpOwoJCSAgICBrZXlFdmVudC50eXBlID0gS2V5UHJlc3M7CgkJICAgIGtleUV2ZW50LnNlcmlhbCA9IDE7CgkJICAgIGtleUV2ZW50LnNlbmRfZXZlbnQgPSBUcnVlOwoJCSAgICBrZXlFdmVudC5kaXNwbGF5ID0gWHREaXNwbGF5KHcpOwoJCSAgICBrZXlFdmVudC53aW5kb3cgPSBYdFdpbmRvdyh3KTsKCQkgICAgWHRDYWxsQWN0aW9uUHJvYyh3LCAiQWN0aXZhdGUiLCAoWEV2ZW50ICopICYga2V5RXZlbnQsCgkJCQkJCQkJICAgICBOVUxMLCAwKTsKCQl9CgkgICAgfQoJfQogICAgfQp9CgovKgogKiBDYWxsYmFjayByb3V0aW5lIGZvciBkaWFsb2cgbW5lbW9uaWMgcHJvY2Vzc2luZy4KICovCi8qQVJHU1VTRUQqLwogICAgc3RhdGljIHZvaWQKbW5lbW9uaWNfZXZlbnQoV2lkZ2V0IHcsIFh0UG9pbnRlciBjYWxsX2RhdGEsIFhLZXlFdmVudCAqZXZlbnQpCnsKICAgIGRvX21uZW1vbmljKHcsIGV2ZW50LT5rZXljb2RlKTsKfQoKCi8qCiAqIFNlYXJjaCB0aGUgd2lkZ2V0IHRyZWUgdW5kZXIgdyBmb3Igd2lkZ2V0cyB3aXRoIG1uZW1vbmljcy4gIFdoZW4gZm91bmQsIGFkZAogKiBhIHBhc3NpdmUgZ3JhYiB0byB0aGUgZGlhbG9nIHdpZGdldCBmb3IgdGhlIG1uZW1vbmljIGNoYXJhY3RlciwgdGh1cwogKiBkaXJlY3RpbmcgbW5lbW9uaWMgZXZlbnRzIHRvIHRoZSBkaWFsb2cgd2lkZ2V0LgogKi8KICAgIHN0YXRpYyB2b2lkCmFkZF9tbmVtb25pY19ncmFicyhXaWRnZXQgZGlhbG9nLCBXaWRnZXQgdykKewogICAgY2hhcgkgICAgbW5lU3RyaW5nWzJdOwogICAgV2lkZ2V0TGlzdAkgICAgY2hpbGRyZW47CiAgICBpbnQJCSAgICBudW1DaGlsZHJlbiwgaTsKICAgIEJvb2xlYW4JICAgIGlzTWVudTsKICAgIEtleVN5bQkgICAgbW5lbW9uaWMgPSAnXDAnOwogICAgdW5zaWduZWQgY2hhciAgIHJvd0NvbFR5cGU7CgogICAgaWYgKFh0SXNDb21wb3NpdGUodykpCiAgICB7CglpZiAoWHRDbGFzcyh3KSA9PSB4bVJvd0NvbHVtbldpZGdldENsYXNzKQoJewoJICAgIFh0VmFHZXRWYWx1ZXModywgWG1Ocm93Q29sdW1uVHlwZSwgJnJvd0NvbFR5cGUsIDApOwoJICAgIGlzTWVudSA9IChyb3dDb2xUeXBlICE9ICh1bnNpZ25lZCBjaGFyKVhtV09SS19BUkVBKTsKCX0KCWVsc2UKCSAgICBpc01lbnUgPSBGYWxzZTsKCWlmICghaXNNZW51KQoJewoJICAgIFh0VmFHZXRWYWx1ZXModywgWG1OY2hpbGRyZW4sICZjaGlsZHJlbiwgWG1ObnVtQ2hpbGRyZW4sCgkJCQkJCQkgICAgICZudW1DaGlsZHJlbiwgMCk7CgkgICAgZm9yIChpID0gMDsgaSA8IG51bUNoaWxkcmVuOyBpKyspCgkJYWRkX21uZW1vbmljX2dyYWJzKGRpYWxvZywgY2hpbGRyZW5baV0pOwoJfQogICAgfQogICAgZWxzZQogICAgewoJWHRWYUdldFZhbHVlcyh3LCBYbU5tbmVtb25pYywgJm1uZW1vbmljLCAwKTsKCWlmIChtbmVtb25pYyAhPSAnXDAnKQoJewoJICAgIG1uZVN0cmluZ1swXSA9IG1uZW1vbmljOwoJICAgIG1uZVN0cmluZ1sxXSA9ICdcMCc7CgkgICAgWHRHcmFiS2V5KGRpYWxvZywgWEtleXN5bVRvS2V5Y29kZShYdERpc3BsYXkoZGlhbG9nKSwKCQkJCQkJICBYU3RyaW5nVG9LZXlzeW0obW5lU3RyaW5nKSksCgkJICAgIE1vZDFNYXNrLCBUcnVlLCBHcmFiTW9kZUFzeW5jLCBHcmFiTW9kZUFzeW5jKTsKCX0KICAgIH0KfQoKLyoKICogQWRkIGEgaGFuZGxlciBmb3IgbW5lbW9uaWNzIGluIGEgZGlhbG9nLiAgTW90aWYgaXRzZWxmIG9ubHkgaGFuZGxlcwogKiBtbmVtb25pY3MgaW4gbWVudXMuIE1uZW1vbmljcyBhZGRlZCBvciBjaGFuZ2VkIGFmdGVyIHRoaXMgY2FsbCB3aWxsIGJlCiAqIGlnbm9yZWQuCiAqCiAqIFRvIGFkZCBhIG1uZW1vbmljIHRvIGEgdGV4dCBmaWVsZCBvciBsaXN0LCBzZXQgdGhlIFhtTm1uZW1vbmljIHJlc291cmNlIG9uCiAqIHRoZSBhcHByb3ByaWF0ZSBsYWJlbCBhbmQgc2V0IHRoZSBYbU51c2VyRGF0YSByZXNvdXJjZSBvZiB0aGUgbGFiZWwgdG8gdGhlCiAqIHdpZGdldCB0byBnZXQgdGhlIGZvY3VzIHdoZW4gdGhlIG1uZW1vbmljIGlzIHR5cGVkLgogKi8KICAgIHN0YXRpYyB2b2lkCmFjdGl2YXRlX2RpYWxvZ19tbmVtb25pY3MoV2lkZ2V0IGRpYWxvZykKewogICAgaWYgKCFkaWFsb2cpCglyZXR1cm47CgogICAgWHRBZGRFdmVudEhhbmRsZXIoZGlhbG9nLCBLZXlQcmVzc01hc2ssIEZhbHNlLAoJCQkgICAoWHRFdmVudEhhbmRsZXIpIG1uZW1vbmljX2V2ZW50LCAoWHRQb2ludGVyKSBOVUxMKTsKICAgIGFkZF9tbmVtb25pY19ncmFicyhkaWFsb2csIGRpYWxvZyk7Cn0KCi8qCiAqIFJlbW92ZXMgdGhlIGV2ZW50IGhhbmRsZXIgYW5kIGtleS1ncmFicyBmb3IgZGlhbG9nIG1uZW1vbmljIGhhbmRsaW5nLgogKi8KICAgIHN0YXRpYyB2b2lkCnN1cHByZXNzX2RpYWxvZ19tbmVtb25pY3MoV2lkZ2V0IGRpYWxvZykKewogICAgaWYgKCFkaWFsb2cpCglyZXR1cm47CgogICAgWHRVbmdyYWJLZXkoZGlhbG9nLCBBbnlLZXksIE1vZDFNYXNrKTsKICAgIFh0UmVtb3ZlRXZlbnRIYW5kbGVyKGRpYWxvZywgS2V5UHJlc3NNYXNrLCBGYWxzZSwKCQkJICAgKFh0RXZlbnRIYW5kbGVyKSBtbmVtb25pY19ldmVudCwgKFh0UG9pbnRlcikgTlVMTCk7Cn0KCiNpZiBkZWZpbmVkKEZFQVRfQlJPV1NFKSB8fCBkZWZpbmVkKEZFQVRfR1VJX0RJQUxPRykKc3RhdGljIHZvaWQgc2V0X2ZvbnRsaXN0IF9fQVJHUygoV2lkZ2V0IHdnKSk7CgovKgogKiBVc2UgdGhlICdndWlmb250JyBvciAnZ3VpZm9udHNldCcgYXMgYSBmb250bGlzdCBmb3IgYSBkaWFsb2cgd2lkZ2V0LgogKi8KICAgIHN0YXRpYyB2b2lkCnNldF9mb250bGlzdChpZCkKICAgIFdpZGdldCBpZDsKewogICAgWG1Gb250TGlzdCBmbDsKCiNpZmRlZiBGT05UU0VUX0FMV0FZUwogICAgaWYgKGd1aS5mb250c2V0ICE9IE5PRk9OVFNFVCkKICAgIHsKCWZsID0gZ3VpX21vdGlmX2ZvbnRzZXQyZm9udGxpc3QoKFhGb250U2V0ICopJmd1aS5mb250c2V0KTsKCWlmIChmbCAhPSBOVUxMKQoJewoJICAgIGlmIChYdElzTWFuYWdlZChpZCkpCgkgICAgewoJCVh0VW5tYW5hZ2VDaGlsZChpZCk7CgkJWHRWYVNldFZhbHVlcyhpZCwgWG1OZm9udExpc3QsIGZsLCBOVUxMKTsKCQkvKiBXZSBzaG91bGQgZm9yY2UgdGhlIHdpZGdldCB0byByZWNhbGN1bGF0ZSBpdCdzCgkJICogZ2VvbWV0cnkgbm93LiAqLwoJCVh0TWFuYWdlQ2hpbGQoaWQpOwoJICAgIH0KCSAgICBlbHNlCgkJWHRWYVNldFZhbHVlcyhpZCwgWG1OZm9udExpc3QsIGZsLCBOVUxMKTsKCSAgICBYbUZvbnRMaXN0RnJlZShmbCk7Cgl9CiAgICB9CiNlbHNlCiAgICBpZiAoZ3VpLm5vcm1fZm9udCAhPSBOT0ZPTlQpCiAgICB7CglmbCA9IGd1aV9tb3RpZl9jcmVhdGVfZm9udGxpc3QoKFhGb250U3RydWN0ICopZ3VpLm5vcm1fZm9udCk7CglpZiAoZmwgIT0gTlVMTCkKCXsKCSAgICBpZiAoWHRJc01hbmFnZWQoaWQpKQoJICAgIHsKCQlYdFVubWFuYWdlQ2hpbGQoaWQpOwoJCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmZvbnRMaXN0LCBmbCwgTlVMTCk7CgkJLyogV2Ugc2hvdWxkIGZvcmNlIHRoZSB3aWRnZXQgdG8gcmVjYWxjdWxhdGUgaXQncwoJCSAqIGdlb21ldHJ5IG5vdy4gKi8KCQlYdE1hbmFnZUNoaWxkKGlkKTsKCSAgICB9CgkgICAgZWxzZQoJCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmZvbnRMaXN0LCBmbCwgTlVMTCk7CgkgICAgWG1Gb250TGlzdEZyZWUoZmwpOwoJfQogICAgfQojZW5kaWYKfQojZW5kaWYKCiNpZiBkZWZpbmVkKEZFQVRfQlJPV1NFKSB8fCBkZWZpbmVkKFBST1RPKQoKLyoKICogZmlsZSBzZWxlY3RvciByZWxhdGVkIHN0dWZmCiAqLwoKI2luY2x1ZGUgPFhtL0ZpbGVTQi5oPgojaW5jbHVkZSA8WG0vWG1TdHJEZWZzLmg+Cgp0eXBlZGVmIHN0cnVjdCBkaWFsb2dfY2FsbGJhY2tfYXJnCnsKICAgIGNoYXIgKiAgYXJnczsgICAvKiBub3QgdXNlZCByaWdodCBub3cgKi8KICAgIGludAkgICAgaWQ7Cn0gZGNiYXJnX1Q7CgpzdGF0aWMgV2lkZ2V0IGRpYWxvZ193Z3Q7CnN0YXRpYyBjaGFyICpicm93c2VfZm5hbWUgPSBOVUxMOwpzdGF0aWMgWG1TdHJpbmdDaGFyU2V0IGNoYXJzZXQgPSAoWG1TdHJpbmdDaGFyU2V0KSBYbVNUUklOR19ERUZBVUxUX0NIQVJTRVQ7CgkJCQkvKiB1c2VkIHRvIHNldCB1cCBYbVN0cmluZ3MgKi8KCnN0YXRpYyB2b2lkIERpYWxvZ0NhbmNlbENCIF9fQVJHUygoV2lkZ2V0LCBYdFBvaW50ZXIsIFh0UG9pbnRlcikpOwpzdGF0aWMgdm9pZCBEaWFsb2dBY2NlcHRDQiBfX0FSR1MoKFdpZGdldCwgWHRQb2ludGVyLCBYdFBvaW50ZXIpKTsKCi8qCiAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byB0cmFuc2xhdGUgdGhlIHByZWRlZmluZWQgbGFiZWwgdGV4dCBvZiB0aGUKICogcHJlY29tcG9zZWQgZGlhbG9ncy4gV2UgZG8gdGhpcyBleHBsaWNpdGx5IHRvIGFsbG93OgogKgogKiAtIHVzYWdlIG9mIGdldHRleHQgZm9yIHRyYW5zbGF0aW9uLCBhcyBpbiBhbGwgdGhlIG90aGVyIHBsYWNlcy4KICoKICogLSBlcXVhbGl6ZSB0aGUgbWVzc2FnZXMgYmV0d2VlbiBkaWZmZXJlbnQgR1VJIGltcGxlbWVudGF0aW9ucyBhcyBmYXIgYXMKICogcG9zc2libGUuCiAqLwpzdGF0aWMgdm9pZCBzZXRfcHJlZGVmaW5lZF9sYWJlbCBfX0FSR1MoKFdpZGdldCBwYXJlbnQsIFN0cmluZyBuYW1lLCBjaGFyICpuZXdfbGFiZWwpKTsKCnN0YXRpYyB2b2lkCnNldF9wcmVkZWZpbmVkX2xhYmVsKHBhcmVudCwgbmFtZSwgbmV3X2xhYmVsKQogICAgV2lkZ2V0ICBwYXJlbnQ7CiAgICBTdHJpbmcgIG5hbWU7CiAgICBjaGFyICAgICpuZXdfbGFiZWw7CnsKICAgIFhtU3RyaW5nCXN0cjsKICAgIFdpZGdldAl3OwogICAgY2hhcl91CSpwLCAqbmV4dDsKICAgIEtleVN5bQltbmVtb25pYyA9IE5VTDsKCiAgICB3ID0gWHROYW1lVG9XaWRnZXQocGFyZW50LCBuYW1lKTsKCiAgICBpZiAoIXcpCglyZXR1cm47CgogICAgcCA9IHZpbV9zdHJzYXZlKChjaGFyX3UgKiluZXdfbGFiZWwpOwogICAgaWYgKHAgPT0gTlVMTCkKCXJldHVybjsKICAgIGZvciAobmV4dCA9IHA7ICpuZXh0OyArK25leHQpCiAgICB7CglpZiAoKm5leHQgPT0gRExHX0hPVEtFWV9DSEFSKQoJewoJICAgIGludCBsZW4gPSBTVFJMRU4obmV4dCk7CgoJICAgIGlmIChsZW4gPiAwKQoJICAgIHsKCQltY2hfbWVtbW92ZShuZXh0LCBuZXh0ICsgMSwgbGVuKTsKCQltbmVtb25pYyA9IG5leHRbMF07CgkgICAgfQoJfQogICAgfQoKICAgIHN0ciA9IFhtU3RyaW5nQ3JlYXRlKChjaGFyICopcCwgU1RSSU5HX1RBRyk7CiAgICB2aW1fZnJlZShwKTsKCiAgICBpZiAoc3RyICE9IE5VTEwpCiAgICB7CglYdFZhU2V0VmFsdWVzKHcsCgkJWG1ObGFiZWxTdHJpbmcsIHN0ciwKCQlYbU5tbmVtb25pYywgbW5lbW9uaWMsCgkJTlVMTCk7CglYbVN0cmluZ0ZyZWUoc3RyKTsKICAgIH0KICAgIGd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KHcpOwp9CgpzdGF0aWMgdm9pZApzZXRfcHJlZGVmaW5lZF9mb250bGlzdChwYXJlbnQsIG5hbWUpCiAgICBXaWRnZXQgcGFyZW50OwogICAgU3RyaW5nIG5hbWU7CnsKICAgIFdpZGdldCB3OwogICAgdyA9IFh0TmFtZVRvV2lkZ2V0KHBhcmVudCwgbmFtZSk7CgogICAgaWYgKCF3KQoJcmV0dXJuOwoKICAgIHNldF9mb250bGlzdCh3KTsKfQoKLyoKICogUHV0IHVwIGEgZmlsZSByZXF1ZXN0ZXIuCiAqIFJldHVybnMgdGhlIHNlbGVjdGVkIG5hbWUgaW4gYWxsb2NhdGVkIG1lbW9yeSwgb3IgTlVMTCBmb3IgQ2FuY2VsLgogKi8KLyogQVJHU1VTRUQgKi8KICAgIGNoYXJfdSAqCmd1aV9tY2hfYnJvd3NlKHNhdmluZywgdGl0bGUsIGRmbHQsIGV4dCwgaW5pdGRpciwgZmlsdGVyKQogICAgaW50CQlzYXZpbmc7CQkvKiBzZWxlY3QgZmlsZSB0byB3cml0ZSAqLwogICAgY2hhcl91CSp0aXRsZTsJCS8qIHRpdGxlIGZvciB0aGUgd2luZG93ICovCiAgICBjaGFyX3UJKmRmbHQ7CQkvKiBkZWZhdWx0IG5hbWUgKi8KICAgIGNoYXJfdQkqZXh0OwkJLyogbm90IHVzZWQgKGV4dGVuc2lvbiBhZGRlZCkgKi8KICAgIGNoYXJfdQkqaW5pdGRpcjsJLyogaW5pdGlhbCBkaXJlY3RvcnksIE5VTEwgZm9yIGN1cnJlbnQgZGlyICovCiAgICBjaGFyX3UJKmZpbHRlcjsJLyogZmlsZSBuYW1lIGZpbHRlciAqLwp7CiAgICBjaGFyX3UJZGlyYnVmW01BWFBBVEhMXTsKICAgIGNoYXJfdQlkZmx0YnVmW01BWFBBVEhMXTsKICAgIGNoYXJfdQkqcGF0dGVybjsKICAgIGNoYXJfdQkqdG9mcmVlID0gTlVMTDsKCiAgICAvKiBUaGVyZSBhIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgcmVzb3VyY2UgbmFtZSBhbmQgdmFsdWUsIFRoZXJlZm9yZSwgd2UKICAgICAqIGF2b2lkIHRvIChhYi0pdXNlIHRoZSAobWF5YmUgaW50ZXJuYXRpb25hbGl6ZWQhKSBkaWFsb2cgdGl0bGUgYXMgYQogICAgICogZGlhbG9nIG5hbWUuCiAgICAgKi8KCiAgICBkaWFsb2dfd2d0ID0gWG1DcmVhdGVGaWxlU2VsZWN0aW9uRGlhbG9nKHZpbVNoZWxsLCAiYnJvd3NlRGlhbG9nIiwgTlVMTCwgMCk7CgogICAgaWYgKGluaXRkaXIgPT0gTlVMTCB8fCAqaW5pdGRpciA9PSBOVUwpCiAgICB7CgltY2hfZGlybmFtZShkaXJidWYsIE1BWFBBVEhMKTsKCWluaXRkaXIgPSBkaXJidWY7CiAgICB9CgogICAgaWYgKGRmbHQgPT0gTlVMTCkKCWRmbHQgPSAoY2hhcl91ICopIiI7CiAgICBlbHNlIGlmIChTVFJMRU4oaW5pdGRpcikgKyBTVFJMRU4oZGZsdCkgKyAyIDwgTUFYUEFUSEwpCiAgICB7CgkvKiBUaGUgZGVmYXVsdCBzZWxlY3Rpb24gc2hvdWxkIGJlIHRoZSBmdWxsIHBhdGgsICJkZmx0IiBpcyBvbmx5IHRoZQoJICogZmlsZSBuYW1lLiAqLwoJU1RSQ1BZKGRmbHRidWYsIGluaXRkaXIpOwoJYWRkX3BhdGhzZXAoZGZsdGJ1Zik7CglTVFJDQVQoZGZsdGJ1ZiwgZGZsdCk7CglkZmx0ID0gZGZsdGJ1ZjsKICAgIH0KCiAgICAvKiBDYW4gb25seSB1c2Ugb25lIHBhdHRlcm4gZm9yIGEgZmlsZSBuYW1lLiAgR2V0IHRoZSBmaXJzdCBwYXR0ZXJuIG91dCBvZgogICAgICogdGhlIGZpbHRlci4gIEFuIGVtcHR5IHBhdHRlcm4gbWVhbnMgZXZlcnl0aGluZyBtYXRjaGVzLiAqLwogICAgaWYgKGZpbHRlciA9PSBOVUxMKQoJcGF0dGVybiA9IChjaGFyX3UgKikiIjsKICAgIGVsc2UKICAgIHsKCWNoYXJfdQkqcywgKnA7CgoJcyA9IGZpbHRlcjsKCWZvciAocCA9IGZpbHRlcjsgKnAgIT0gTlVMOyArK3ApCgl7CgkgICAgaWYgKCpwID09ICdcdCcpCS8qIGVuZCBvZiBkZXNjcmlwdGlvbiwgc3RhcnQgb2YgcGF0dGVybiAqLwoJCXMgPSBwICsgMTsKCSAgICBpZiAoKnAgPT0gJzsnIHx8ICpwID09ICdcbicpCS8qIGVuZCBvZiAoZmlyc3QpIHBhdHRlcm4gKi8KCQlicmVhazsKCX0KCXBhdHRlcm4gPSB2aW1fc3RybnNhdmUocywgcCAtIHMpOwoJdG9mcmVlID0gcGF0dGVybjsKCWlmIChwYXR0ZXJuID09IE5VTEwpCgkgICAgcGF0dGVybiA9IChjaGFyX3UgKikiIjsKICAgIH0KCiAgICBYdFZhU2V0VmFsdWVzKGRpYWxvZ193Z3QsCglYdFZhVHlwZWRBcmcsCgkgICAgWG1OZGlyZWN0b3J5LCBYbVJTdHJpbmcsIChjaGFyICopaW5pdGRpciwgU1RSTEVOKGluaXRkaXIpICsgMSwKCVh0VmFUeXBlZEFyZywKCSAgICBYbU5kaXJTcGVjLAlYbVJTdHJpbmcsIChjaGFyICopZGZsdCwgU1RSTEVOKGRmbHQpICsgMSwKCVh0VmFUeXBlZEFyZywKCSAgICBYbU5wYXR0ZXJuLAlYbVJTdHJpbmcsIChjaGFyICopcGF0dGVybiwgU1RSTEVOKHBhdHRlcm4pICsgMSwKCVh0VmFUeXBlZEFyZywKCSAgICBYbU5kaWFsb2dUaXRsZSwgWG1SU3RyaW5nLCAoY2hhciAqKXRpdGxlLCBTVFJMRU4odGl0bGUpICsgMSwKCU5VTEwpOwoKICAgIHNldF9wcmVkZWZpbmVkX2xhYmVsKGRpYWxvZ193Z3QsICJBcHBseSIsIF8oIiZGaWx0ZXIiKSk7CiAgICBzZXRfcHJlZGVmaW5lZF9sYWJlbChkaWFsb2dfd2d0LCAiQ2FuY2VsIiwgXygiJkNhbmNlbCIpKTsKICAgIHNldF9wcmVkZWZpbmVkX2xhYmVsKGRpYWxvZ193Z3QsICJEaXIiLCBfKCJEaXJlY3RvcmllcyIpKTsKICAgIHNldF9wcmVkZWZpbmVkX2xhYmVsKGRpYWxvZ193Z3QsICJGaWx0ZXJMYWJlbCIsIF8oIkZpbHRlciIpKTsKICAgIHNldF9wcmVkZWZpbmVkX2xhYmVsKGRpYWxvZ193Z3QsICJIZWxwIiwgXygiJkhlbHAiKSk7CiAgICBzZXRfcHJlZGVmaW5lZF9sYWJlbChkaWFsb2dfd2d0LCAiSXRlbXMiLCBfKCJGaWxlcyIpKTsKICAgIHNldF9wcmVkZWZpbmVkX2xhYmVsKGRpYWxvZ193Z3QsICJPSyIsIF8oIiZPSyIpKTsKICAgIHNldF9wcmVkZWZpbmVkX2xhYmVsKGRpYWxvZ193Z3QsICJTZWxlY3Rpb24iLCBfKCJTZWxlY3Rpb24iKSk7CgogICAgLyogVGhpcyBpcyB0byBzYXZlIHVzIGZyb20gc2lsbHkgZXh0ZXJuYWwgc2V0dGluZ3MgdXNpbmcgbm90IGZpeGVkIHdpdGgKICAgICAqIGZvbnRzIGZvciBmaWxlIHNlbGVjdGlvbi4KICAgICAqLwogICAgc2V0X3ByZWRlZmluZWRfZm9udGxpc3QoZGlhbG9nX3dndCwgIkRpckxpc3RTVy5EaXJMaXN0Iik7CiAgICBzZXRfcHJlZGVmaW5lZF9mb250bGlzdChkaWFsb2dfd2d0LCAiSXRlbXNMaXN0U1cuSXRlbXNMaXN0Iik7CgogICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKGRpYWxvZ193Z3QpOwogICAgaWYgKGd1aS5zY3JvbGxfYmdfcGl4ZWwgIT0gSU5WQUxDT0xPUikKCVh0VmFTZXRWYWx1ZXMoZGlhbG9nX3dndCwgWG1OdHJvdWdoQ29sb3IsIGd1aS5zY3JvbGxfYmdfcGl4ZWwsIE5VTEwpOwoKICAgIFh0QWRkQ2FsbGJhY2soZGlhbG9nX3dndCwgWG1Ob2tDYWxsYmFjaywgRGlhbG9nQWNjZXB0Q0IsIChYdFBvaW50ZXIpMCk7CiAgICBYdEFkZENhbGxiYWNrKGRpYWxvZ193Z3QsIFhtTmNhbmNlbENhbGxiYWNrLCBEaWFsb2dDYW5jZWxDQiwgKFh0UG9pbnRlcikwKTsKICAgIC8qIFdlIGhhdmUgbm8gaGVscCBpbiB0aGlzIHdpbmRvdywgc28gaGlkZSBoZWxwIGJ1dHRvbiAqLwogICAgWHRVbm1hbmFnZUNoaWxkKFhtRmlsZVNlbGVjdGlvbkJveEdldENoaWxkKGRpYWxvZ193Z3QsCgkJCQkJKHVuc2lnbmVkIGNoYXIpWG1ESUFMT0dfSEVMUF9CVVRUT04pKTsKCiAgICBtYW5hZ2VfY2VudGVyZWQoZGlhbG9nX3dndCk7CiAgICBhY3RpdmF0ZV9kaWFsb2dfbW5lbW9uaWNzKGRpYWxvZ193Z3QpOwoKICAgIC8qIHNpdCBpbiBhIGxvb3AgdW50aWwgdGhlIGRpYWxvZyBib3ggaGFzIGdvbmUgYXdheSAqLwogICAgZG8KICAgIHsKCVh0QXBwUHJvY2Vzc0V2ZW50KFh0V2lkZ2V0VG9BcHBsaWNhdGlvbkNvbnRleHQoZGlhbG9nX3dndCksCgkgICAgKFh0SW5wdXRNYXNrKVh0SU1BbGwpOwogICAgfSB3aGlsZSAoWHRJc01hbmFnZWQoZGlhbG9nX3dndCkpOwoKICAgIHN1cHByZXNzX2RpYWxvZ19tbmVtb25pY3MoZGlhbG9nX3dndCk7CiAgICBYdERlc3Ryb3lXaWRnZXQoZGlhbG9nX3dndCk7CiAgICB2aW1fZnJlZSh0b2ZyZWUpOwoKICAgIGlmIChicm93c2VfZm5hbWUgPT0gTlVMTCkKCXJldHVybiBOVUxMOwogICAgcmV0dXJuIHZpbV9zdHJzYXZlKChjaGFyX3UgKilicm93c2VfZm5hbWUpOwp9CgovKgogKiBUaGUgY29kZSBiZWxvdyB3YXMgb3JpZ2luYWxseSB0YWtlbiBmcm9tCiAqCS91c3IvZXhhbXBsZXMvbW90aWYveG1zYW1wbGVycy94bWVkaXRvci5jCiAqIG9uIERpZ2l0YWwgVW5peCA0LjBkLCBidXQgaGVhdmlseSBtb2RpZmllZC4KICovCgovKgogKiBQcm9jZXNzIGNhbGxiYWNrIGZyb20gRGlhbG9nIGNhbmNlbCBhY3Rpb25zLgogKi8KLyogQVJHU1VTRUQgKi8KICAgIHN0YXRpYyB2b2lkCkRpYWxvZ0NhbmNlbENCKHcsIGNsaWVudF9kYXRhLCBjYWxsX2RhdGEpCiAgICBXaWRnZXQJdzsJCS8qICB3aWRnZXQgaWQJCSovCiAgICBYdFBvaW50ZXIJY2xpZW50X2RhdGE7CS8qICBkYXRhIGZyb20gYXBwbGljYXRpb24gICAqLwogICAgWHRQb2ludGVyCWNhbGxfZGF0YTsJLyogIGRhdGEgZnJvbSB3aWRnZXQgY2xhc3MgICovCnsKICAgIGlmIChicm93c2VfZm5hbWUgIT0gTlVMTCkKICAgIHsKCVh0RnJlZShicm93c2VfZm5hbWUpOwoJYnJvd3NlX2ZuYW1lID0gTlVMTDsKICAgIH0KICAgIFh0VW5tYW5hZ2VDaGlsZChkaWFsb2dfd2d0KTsKfQoKLyoKICogUHJvY2VzcyBjYWxsYmFjayBmcm9tIERpYWxvZyBhY3Rpb25zLgogKi8KLyogQVJHU1VTRUQgKi8KICAgIHN0YXRpYyB2b2lkCkRpYWxvZ0FjY2VwdENCKHcsIGNsaWVudF9kYXRhLCBjYWxsX2RhdGEpCiAgICBXaWRnZXQJdzsJCS8qICB3aWRnZXQgaWQJCSovCiAgICBYdFBvaW50ZXIJY2xpZW50X2RhdGE7CS8qICBkYXRhIGZyb20gYXBwbGljYXRpb24gICAqLwogICAgWHRQb2ludGVyCWNhbGxfZGF0YTsJLyogIGRhdGEgZnJvbSB3aWRnZXQgY2xhc3MgICovCnsKICAgIFhtRmlsZVNlbGVjdGlvbkJveENhbGxiYWNrU3RydWN0ICpmY2I7CgogICAgaWYgKGJyb3dzZV9mbmFtZSAhPSBOVUxMKQogICAgewoJWHRGcmVlKGJyb3dzZV9mbmFtZSk7Cglicm93c2VfZm5hbWUgPSBOVUxMOwogICAgfQogICAgZmNiID0gKFhtRmlsZVNlbGVjdGlvbkJveENhbGxiYWNrU3RydWN0ICopY2FsbF9kYXRhOwoKICAgIC8qIGdldCB0aGUgZmlsZW5hbWUgZnJvbSB0aGUgZmlsZSBzZWxlY3Rpb24gYm94ICovCiAgICBYbVN0cmluZ0dldEx0b1IoZmNiLT52YWx1ZSwgY2hhcnNldCwgJmJyb3dzZV9mbmFtZSk7CgogICAgLyogcG9wZG93biB0aGUgZmlsZSBzZWxlY3Rpb24gYm94ICovCiAgICBYdFVubWFuYWdlQ2hpbGQoZGlhbG9nX3dndCk7Cn0KCiNlbmRpZiAvKiBGRUFUX0JST1dTRSAqLwoKI2lmIGRlZmluZWQoRkVBVF9HVUlfRElBTE9HKSB8fCBkZWZpbmVkKFBST1RPKQoKc3RhdGljIGludAlkaWFsb2dTdGF0dXM7CgpzdGF0aWMgdm9pZCBrZXloaXRfY2FsbGJhY2sgX19BUkdTKChXaWRnZXQgdywgWHRQb2ludGVyIGNsaWVudF9kYXRhLCBYRXZlbnQgKmV2ZW50LCBCb29sZWFuICpjb250KSk7CnN0YXRpYyB2b2lkIGJ1dHByb2MgX19BUkdTKChXaWRnZXQgdywgWHRQb2ludGVyIGNsaWVudF9kYXRhLCBYdFBvaW50ZXIgY2FsbF9kYXRhKSk7CgovKgogKiBDYWxsYmFjayBmdW5jdGlvbiBmb3IgdGhlIHRleHRmaWVsZC4gIFdoZW4gQ1IgaXMgaGl0IHRoaXMgd29ya3MgbGlrZQogKiBoaXR0aW5nIHRoZSAiT0siIGJ1dHRvbiwgRVNDIGxpa2UgIkNhbmNlbCIuCiAqLwovKiBBUkdTVVNFRCAqLwogICAgc3RhdGljIHZvaWQKa2V5aGl0X2NhbGxiYWNrKHcsIGNsaWVudF9kYXRhLCBldmVudCwgY29udCkKICAgIFdpZGdldAkJdzsKICAgIFh0UG9pbnRlcgkJY2xpZW50X2RhdGE7CiAgICBYRXZlbnQJCSpldmVudDsKICAgIEJvb2xlYW4JCSpjb250Owp7CiAgICBjaGFyCWJ1ZlsyXTsKICAgIEtleVN5bQlrZXlfc3ltOwoKICAgIGlmIChYTG9va3VwU3RyaW5nKCYoZXZlbnQtPnhrZXkpLCBidWYsIDIsICZrZXlfc3ltLCBOVUxMKSA9PSAxKQogICAgewoJaWYgKCpidWYgPT0gQ0FSKQoJICAgIGRpYWxvZ1N0YXR1cyA9IDE7CgllbHNlIGlmICgqYnVmID09IEVTQykKCSAgICBkaWFsb2dTdGF0dXMgPSAyOwogICAgfQogICAgaWYgKChrZXlfc3ltID09IFhLX0xlZnQgfHwga2V5X3N5bSA9PSBYS19SaWdodCkKCSAgICAmJiAhKGV2ZW50LT54a2V5LnN0YXRlICYgU2hpZnRNYXNrKSkKCVhtVGV4dEZpZWxkQ2xlYXJTZWxlY3Rpb24odywgWHRMYXN0VGltZXN0YW1wUHJvY2Vzc2VkKGd1aS5kcHkpKTsKfQoKLyogQVJHU1VTRUQgKi8KICAgIHN0YXRpYyB2b2lkCmJ1dHByb2ModywgY2xpZW50X2RhdGEsIGNhbGxfZGF0YSkKICAgIFdpZGdldAl3OwogICAgWHRQb2ludGVyCWNsaWVudF9kYXRhOwogICAgWHRQb2ludGVyCWNhbGxfZGF0YTsKewogICAgZGlhbG9nU3RhdHVzID0gKGludCkobG9uZyljbGllbnRfZGF0YSArIDE7Cn0KCiNpZmRlZiBIQVZFX1hQTQoKc3RhdGljIFdpZGdldCBjcmVhdGVfcGl4bWFwX2xhYmVsKFdpZGdldCBwYXJlbnQsIFN0cmluZyBuYW1lLCBjaGFyICoqZGF0YSwgQXJnTGlzdCBhcmdzLCBDYXJkaW5hbCBhcmcpOwoKICAgIHN0YXRpYyBXaWRnZXQKY3JlYXRlX3BpeG1hcF9sYWJlbChwYXJlbnQsIG5hbWUsIGRhdGEsIGFyZ3MsIGFyZykKICAgIFdpZGdldAlwYXJlbnQ7CiAgICBTdHJpbmcJbmFtZTsKICAgIGNoYXIJKipkYXRhOwogICAgQXJnTGlzdAlhcmdzOwogICAgQ2FyZGluYWwJYXJnOwp7CiAgICBXaWRnZXQJCWxhYmVsOwogICAgRGlzcGxheQkJKmRzcDsKICAgIFNjcmVlbgkJKnNjcjsKICAgIGludAkJCWRlcHRoOwogICAgUGl4bWFwCQlwaXhtYXAgPSAwOwogICAgWHBtQXR0cmlidXRlcwlhdHRyOwogICAgQm9vbGVhbgkJcnM7CiAgICBYcG1Db2xvclN5bWJvbAljb2xvcls1XSA9CiAgICB7Cgl7Im5vbmUiLCBOVUxMLCAwfSwKCXsiaWNvbkNvbG9yMSIsIE5VTEwsIDB9LAoJeyJib3R0b21TaGFkb3dDb2xvciIsIE5VTEwsIDB9LAoJeyJ0b3BTaGFkb3dDb2xvciIsIE5VTEwsIDB9LAoJeyJzZWxlY3RDb2xvciIsIE5VTEwsIDB9CiAgICB9OwoKICAgIGxhYmVsID0gWG1DcmVhdGVMYWJlbEdhZGdldChwYXJlbnQsIG5hbWUsIGFyZ3MsIGFyZyk7CgogICAgLyoKICAgICAqIFdlIG5lZWQgdG8gYmUgY2FyZWZ1bCBoZXJlLCBzaW5jZSBpbiBjYXNlIG9mIGdhZGdldHMsIHRoZXJlIGlzCiAgICAgKiBubyB3YXkgdG8gZ2V0IHRoZSBiYWNrZ3JvdW5kIGNvbG9yIGRpcmVjdGx5IGZyb20gdGhlIHdpZGdldCBpdHNlbGYuCiAgICAgKiBJbiBzdWNoIGNhc2VzIHdlIGdldCBpdCBmcm9tIFRoZSBDb3JlIHBhcnQgb2YgaGlzIHBhcmVudCBpbnN0ZWFkLgogICAgICovCiAgICBkc3AgPSBYdERpc3BsYXlPZk9iamVjdChsYWJlbCk7CiAgICBzY3IgPSBYdFNjcmVlbk9mT2JqZWN0KGxhYmVsKTsKICAgIFh0VmFHZXRWYWx1ZXMoWHRJc1N1YmNsYXNzKGxhYmVsLCBjb3JlV2lkZ2V0Q2xhc3MpCgkgICAgPyAgbGFiZWwgOiBYdFBhcmVudChsYWJlbCksCgkJICBYbU5kZXB0aCwgJmRlcHRoLAoJCSAgWG1OYmFja2dyb3VuZCwgJmNvbG9yWzBdLnBpeGVsLAoJCSAgWG1OZm9yZWdyb3VuZCwgJmNvbG9yWzFdLnBpeGVsLAoJCSAgWG1OYm90dG9tU2hhZG93Q29sb3IsICZjb2xvclsyXS5waXhlbCwKCQkgIFhtTnRvcFNoYWRvd0NvbG9yLCAmY29sb3JbM10ucGl4ZWwsCgkJICBYbU5oaWdobGlnaHQsICZjb2xvcls0XS5waXhlbCwKCQkgIE5VTEwpOwoKICAgIGF0dHIudmFsdWVtYXNrID0gWHBtQ29sb3JTeW1ib2xzIHwgWHBtQ2xvc2VuZXNzIHwgWHBtRGVwdGg7CiAgICBhdHRyLmNvbG9yc3ltYm9scyA9IGNvbG9yOwogICAgYXR0ci5udW1zeW1ib2xzID0gNTsKICAgIGF0dHIuY2xvc2VuZXNzID0gNjU1MzU7CiAgICBhdHRyLmRlcHRoID0gZGVwdGg7CiAgICBYcG1DcmVhdGVQaXhtYXBGcm9tRGF0YShkc3AsIFJvb3RXaW5kb3dPZlNjcmVlbihzY3IpLAoJCSAgICBkYXRhLCAmcGl4bWFwLCBOVUxMLCAmYXR0cik7CgogICAgWHRWYUdldFZhbHVlcyhsYWJlbCwgWG1OcmVjb21wdXRlU2l6ZSwgJnJzLCBOVUxMKTsKICAgIFh0VmFTZXRWYWx1ZXMobGFiZWwsIFhtTnJlY29tcHV0ZVNpemUsIFRydWUsIE5VTEwpOwogICAgWHRWYVNldFZhbHVlcyhsYWJlbCwKCSAgICBYbU5sYWJlbFR5cGUsIFhtUElYTUFQLAoJICAgIFhtTmxhYmVsUGl4bWFwLCBwaXhtYXAsCgkgICAgTlVMTCk7CiAgICBYdFZhU2V0VmFsdWVzKGxhYmVsLCBYbU5yZWNvbXB1dGVTaXplLCBycywgTlVMTCk7CgogICAgcmV0dXJuIGxhYmVsOwp9CiNlbmRpZgoKLyogQVJHU1VTRUQgKi8KICAgIGludApndWlfbWNoX2RpYWxvZyh0eXBlLCB0aXRsZSwgbWVzc2FnZSwgYnV0dG9uX25hbWVzLCBkZmx0YnV0dG9uLCB0ZXh0ZmllbGQpCiAgICBpbnQJCXR5cGU7CiAgICBjaGFyX3UJKnRpdGxlOwogICAgY2hhcl91CSptZXNzYWdlOwogICAgY2hhcl91CSpidXR0b25fbmFtZXM7CiAgICBpbnQJCWRmbHRidXR0b247CiAgICBjaGFyX3UJKnRleHRmaWVsZDsJCS8qIGJ1ZmZlciBvZiBzaXplIElPU0laRSAqLwp7CiAgICBjaGFyX3UJCSpidXRzOwogICAgY2hhcl91CQkqcCwgKm5leHQ7CiAgICBYdEFwcENvbnRleHQJYXBwOwogICAgWG1TdHJpbmcJCWxhYmVsOwogICAgaW50CQkJYnV0Y291bnQ7CiAgICBXaWRnZXQJCXc7CiAgICBXaWRnZXQJCWRpYWxvZ2Zvcm0gPSBOVUxMOwogICAgV2lkZ2V0CQlmb3JtID0gTlVMTDsKICAgIFdpZGdldAkJZGlhbG9ndGV4dGZpZWxkID0gTlVMTDsKICAgIFdpZGdldAkJKmJ1dHRvbnM7CiAgICBXaWRnZXQJCXNlcF9mb3JtID0gTlVMTDsKICAgIEJvb2xlYW4JCXZlcnRpY2FsOwogICAgV2lkZ2V0CQlzZXBhcmF0b3IgPSBOVUxMOwogICAgaW50CQkJbjsKICAgIEFyZwkJCWFyZ3NbNl07CiNpZmRlZiBIQVZFX1hQTQogICAgY2hhcgkJKippY29uX2RhdGEgPSBOVUxMOwogICAgV2lkZ2V0CQlkaWFsb2dwaXhtYXAgPSBOVUxMOwojZW5kaWYKCiAgICBpZiAodGl0bGUgPT0gTlVMTCkKCXRpdGxlID0gKGNoYXJfdSAqKV8oIlZpbSBkaWFsb2ciKTsKCiAgICAvKiBpZiBvdXIgcG9pbnRlciBpcyBjdXJyZW50bHkgaGlkZGVuLCB0aGVuIHdlIHNob3VsZCBzaG93IGl0LiAqLwogICAgZ3VpX21jaF9tb3VzZWhpZGUoRkFMU0UpOwoKICAgIGRpYWxvZ2Zvcm0gPSBYbUNyZWF0ZUZvcm1EaWFsb2codmltU2hlbGwsIChjaGFyICopImRpYWxvZyIsIE5VTEwsIDApOwoKICAgIC8qIENoZWNrICd2JyBmbGFnIGluICdndWlvcHRpb25zJzogdmVydGljYWwgYnV0dG9uIHBsYWNlbWVudC4gKi8KICAgIHZlcnRpY2FsID0gKHZpbV9zdHJjaHIocF9nbywgR09fVkVSVElDQUwpICE9IE5VTEwpOwoKICAgIC8qIFNldCB0aGUgdGl0bGUgb2YgdGhlIERpYWxvZyB3aW5kb3cgKi8KICAgIGxhYmVsID0gWG1TdHJpbmdDcmVhdGVTaW1wbGUoKGNoYXIgKil0aXRsZSk7CiAgICBpZiAobGFiZWwgPT0gTlVMTCkKCXJldHVybiAtMTsKICAgIFh0VmFTZXRWYWx1ZXMoZGlhbG9nZm9ybSwKCSAgICBYbU5kaWFsb2dUaXRsZSwgbGFiZWwsCgkgICAgWG1OaG9yaXpvbnRhbFNwYWNpbmcsIDQsCgkgICAgWG1OdmVydGljYWxTcGFjaW5nLCB2ZXJ0aWNhbCA/IDAgOiA0LAoJICAgIE5VTEwpOwogICAgWG1TdHJpbmdGcmVlKGxhYmVsKTsKCiAgICAvKiBtYWtlIGEgY29weSwgc28gdGhhdCB3ZSBjYW4gaW5zZXJ0IE5VTHMgKi8KICAgIGJ1dHMgPSB2aW1fc3Ryc2F2ZShidXR0b25fbmFtZXMpOwogICAgaWYgKGJ1dHMgPT0gTlVMTCkKCXJldHVybiAtMTsKCiAgICAvKiBDb3VudCB0aGUgbnVtYmVyIG9mIGJ1dHRvbnMgYW5kIGFsbG9jYXRlIGJ1dHRvbnNbXS4gKi8KICAgIGJ1dGNvdW50ID0gMTsKICAgIGZvciAocCA9IGJ1dHM7ICpwOyArK3ApCglpZiAoKnAgPT0gRExHX0JVVFRPTl9TRVApCgkgICAgKytidXRjb3VudDsKICAgIGJ1dHRvbnMgPSAoV2lkZ2V0ICopYWxsb2MoKHVuc2lnbmVkKShidXRjb3VudCAqIHNpemVvZihXaWRnZXQpKSk7CiAgICBpZiAoYnV0dG9ucyA9PSBOVUxMKQogICAgewoJdmltX2ZyZWUoYnV0cyk7CglyZXR1cm4gLTE7CiAgICB9CgogICAgLyoKICAgICAqIENyZWF0ZSB0aGUgYnV0dG9ucy4KICAgICAqLwogICAgc2VwX2Zvcm0gPSAoV2lkZ2V0KSAwOwogICAgcCA9IGJ1dHM7CiAgICBmb3IgKGJ1dGNvdW50ID0gMDsgKnA7ICsrYnV0Y291bnQpCiAgICB7CglLZXlTeW0gbW5lbW9uaWMgPSBOVUw7CgoJZm9yIChuZXh0ID0gcDsgKm5leHQ7ICsrbmV4dCkKCXsKCSAgICBpZiAoKm5leHQgPT0gRExHX0hPVEtFWV9DSEFSKQoJICAgIHsKCQlpbnQgbGVuID0gU1RSTEVOKG5leHQpOwoKCQlpZiAobGVuID4gMCkKCQl7CgkJICAgIG1jaF9tZW1tb3ZlKG5leHQsIG5leHQgKyAxLCBsZW4pOwoJCSAgICBtbmVtb25pYyA9IG5leHRbMF07CgkJfQoJICAgIH0KCSAgICBpZiAoKm5leHQgPT0gRExHX0JVVFRPTl9TRVApCgkgICAgewoJCSpuZXh0KysgPSBOVUw7CgkJYnJlYWs7CgkgICAgfQoJfQoJbGFiZWwgPSBYbVN0cmluZ0NyZWF0ZShfKChjaGFyICopcCksIFNUUklOR19UQUcpOwoJaWYgKGxhYmVsID09IE5VTEwpCgkgICAgYnJlYWs7CgoJYnV0dG9uc1tidXRjb3VudF0gPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgiYnV0dG9uIiwKCQl4bVB1c2hCdXR0b25XaWRnZXRDbGFzcywgZGlhbG9nZm9ybSwKCQlYbU5sYWJlbFN0cmluZywgbGFiZWwsCgkJWG1ObW5lbW9uaWMsIG1uZW1vbmljLAoJCVhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJWG1OYm90dG9tT2Zmc2V0LCA0LAoJCVhtTnNob3dBc0RlZmF1bHQsIGJ1dGNvdW50ID09IGRmbHRidXR0b24gLSAxLAoJCVhtTmRlZmF1bHRCdXR0b25TaGFkb3dUaGlja25lc3MsIDEsCgkJTlVMTCk7CglYbVN0cmluZ0ZyZWUobGFiZWwpOwoJZ3VpX21vdGlmX21lbnVfZm9udGxpc3QoYnV0dG9uc1tidXRjb3VudF0pOwoKCS8qIExheW91dCBwcm9wZXJseS4gKi8KCglpZiAoYnV0Y291bnQgPiAwKQoJewoJICAgIGlmICh2ZXJ0aWNhbCkKCQlYdFZhU2V0VmFsdWVzKGJ1dHRvbnNbYnV0Y291bnRdLAoJCQlYbU50b3BXaWRnZXQsIGJ1dHRvbnNbYnV0Y291bnQgLSAxXSwKCQkJTlVMTCk7CgkgICAgZWxzZQoJICAgIHsKCQlpZiAoKm5leHQgPT0gTlVMKQoJCXsKCQkgICAgWHRWYVNldFZhbHVlcyhidXR0b25zW2J1dGNvdW50XSwKCQkJICAgIFhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkJICAgIFhtTnJpZ2h0T2Zmc2V0LCA0LAoJCQkgICAgTlVMTCk7CgoJCSAgICAvKiBmaWxsIGluIGEgZm9ybSBhcyBpbnZpc2libGUgc2VwYXJhdG9yICovCgkJICAgIHNlcF9mb3JtID0gWHRWYUNyZWF0ZVdpZGdldCgic2VwYXJhdG9yRm9ybSIsCgkJCSAgICB4bUZvcm1XaWRnZXRDbGFzcywJZGlhbG9nZm9ybSwKCQkJICAgIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICBYbU5sZWZ0V2lkZ2V0LCBidXR0b25zW2J1dGNvdW50IC0gMV0sCgkJCSAgICBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgIFhtTnJpZ2h0V2lkZ2V0LCBidXR0b25zW2J1dGNvdW50XSwKCQkJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCSAgICBYbU5ib3R0b21PZmZzZXQsIDQsCgkJCSAgICBOVUxMKTsKCQkgICAgWHRNYW5hZ2VDaGlsZChzZXBfZm9ybSk7CgkJfQoJCWVsc2UKCQl7CgkJICAgIFh0VmFTZXRWYWx1ZXMoYnV0dG9uc1tidXRjb3VudF0sCgkJCSAgICBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQkgICAgWG1ObGVmdFdpZGdldCwgYnV0dG9uc1tidXRjb3VudCAtIDFdLAoJCQkgICAgTlVMTCk7CgkJfQoJICAgIH0KCX0KCWVsc2UgaWYgKCF2ZXJ0aWNhbCkKCXsKCSAgICBpZiAoKm5leHQgPT0gTlVMKQoJICAgIHsKCQlYdFZhU2V0VmFsdWVzKGJ1dHRvbnNbMF0sCgkJCVhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkJWG1OcmlnaHRPZmZzZXQsIDQsCgkJCU5VTEwpOwoKCQkvKiBmaWxsIGluIGEgZm9ybSBhcyBpbnZpc2libGUgc2VwYXJhdG9yICovCgkJc2VwX2Zvcm0gPSBYdFZhQ3JlYXRlV2lkZ2V0KCJzZXBhcmF0b3JGb3JtIiwKCQkJeG1Gb3JtV2lkZ2V0Q2xhc3MsIGRpYWxvZ2Zvcm0sCgkJCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCQlYbU5sZWZ0T2Zmc2V0LCA0LAoJCQlYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJWG1OcmlnaHRXaWRnZXQsIGJ1dHRvbnNbMF0sCgkJCVhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCVhtTmJvdHRvbU9mZnNldCwgNCwKCQkJTlVMTCk7CgkJWHRNYW5hZ2VDaGlsZChzZXBfZm9ybSk7CgkgICAgfQoJICAgIGVsc2UKCQlYdFZhU2V0VmFsdWVzKGJ1dHRvbnNbMF0sCgkJCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCQlYbU5sZWZ0T2Zmc2V0LCA0LAoJCQlOVUxMKTsKCX0KCglYdEFkZENhbGxiYWNrKGJ1dHRvbnNbYnV0Y291bnRdLCBYbU5hY3RpdmF0ZUNhbGxiYWNrLAoJCQkgIChYdENhbGxiYWNrUHJvYylidXRwcm9jLCAoWHRQb2ludGVyKShsb25nKWJ1dGNvdW50KTsKCXAgPSBuZXh0OwogICAgfQogICAgdmltX2ZyZWUoYnV0cyk7CgogICAgc2VwYXJhdG9yID0gKFdpZGdldCkgMDsKICAgIGlmIChidXRjb3VudCA+IDApCiAgICB7CgkvKiBDcmVhdGUgdGhlIHNlcGFyYXRvciBmb3IgYmVhdXR5LiAqLwoJbiA9IDA7CglYdFNldEFyZyhhcmdzW25dLCBYbU5vcmllbnRhdGlvbiwgWG1IT1JJWk9OVEFMKTsgbisrOwoJWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VUKTsgbisrOwoJWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tV2lkZ2V0LCBidXR0b25zWzBdKTsgbisrOwoJWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tT2Zmc2V0LCA0KTsgbisrOwoJWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CglYdFNldEFyZyhhcmdzW25dLCBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CglzZXBhcmF0b3IgPSBYbUNyZWF0ZVNlcGFyYXRvckdhZGdldChkaWFsb2dmb3JtLCAic2VwYXJhdG9yIiwgYXJncywgbik7CglYdE1hbmFnZUNoaWxkKHNlcGFyYXRvcik7CiAgICB9CgogICAgaWYgKHRleHRmaWVsZCAhPSBOVUxMKQogICAgewoJZGlhbG9ndGV4dGZpZWxkID0gWHRWYUNyZWF0ZVdpZGdldCgidGV4dEZpZWxkIiwKCQl4bVRleHRGaWVsZFdpZGdldENsYXNzLCBkaWFsb2dmb3JtLAoJCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCVhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlOVUxMKTsKCWlmIChidXRjb3VudCA+IDApCgkgICAgWHRWYVNldFZhbHVlcyhkaWFsb2d0ZXh0ZmllbGQsCgkJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkgICAgWG1OYm90dG9tV2lkZ2V0LCBzZXBhcmF0b3IsCgkJICAgIE5VTEwpOwoJZWxzZQoJICAgIFh0VmFTZXRWYWx1ZXMoZGlhbG9ndGV4dGZpZWxkLAoJCSAgICBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCSAgICBOVUxMKTsKCglzZXRfZm9udGxpc3QoZGlhbG9ndGV4dGZpZWxkKTsKCVhtVGV4dEZpZWxkU2V0U3RyaW5nKGRpYWxvZ3RleHRmaWVsZCwgKGNoYXIgKil0ZXh0ZmllbGQpOwoJWHRNYW5hZ2VDaGlsZChkaWFsb2d0ZXh0ZmllbGQpOwoJWHRBZGRFdmVudEhhbmRsZXIoZGlhbG9ndGV4dGZpZWxkLCBLZXlQcmVzc01hc2ssIEZhbHNlLAoJCQkgICAgKFh0RXZlbnRIYW5kbGVyKWtleWhpdF9jYWxsYmFjaywgKFh0UG9pbnRlcilOVUxMKTsKICAgIH0KCiAgICAvKiBGb3JtIGhvbGRpbmcgYm90aCBtZXNzYWdlIGFuZCBwaXhtYXAgbGFiZWxzICovCiAgICBmb3JtID0gWHRWYUNyZWF0ZVdpZGdldCgic2VwYXJhdG9yRm9ybSIsCgkgICAgeG1Gb3JtV2lkZ2V0Q2xhc3MsIGRpYWxvZ2Zvcm0sCgkgICAgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgTlVMTCk7CiAgICBYdE1hbmFnZUNoaWxkKGZvcm0pOwoKI2lmZGVmIEhBVkVfWFBNCiAgICAvKiBBZGQgYSBwaXhtYXAsIGxlZnQgb2YgdGhlIG1lc3NhZ2UuICovCiAgICBzd2l0Y2ggKHR5cGUpCiAgICB7CgljYXNlIFZJTV9HRU5FUklDOgoJICAgIGljb25fZGF0YSA9IGdlbmVyaWNfeHBtOwoJICAgIGJyZWFrOwoJY2FzZSBWSU1fRVJST1I6CgkgICAgaWNvbl9kYXRhID0gZXJyb3JfeHBtOwoJICAgIGJyZWFrOwoJY2FzZSBWSU1fV0FSTklORzoKCSAgICBpY29uX2RhdGEgPSBhbGVydF94cG07CgkgICAgYnJlYWs7CgljYXNlIFZJTV9JTkZPOgoJICAgIGljb25fZGF0YSA9IGluZm9feHBtOwoJICAgIGJyZWFrOwoJY2FzZSBWSU1fUVVFU1RJT046CgkgICAgaWNvbl9kYXRhID0gcXVlc3RfeHBtOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBpY29uX2RhdGEgPSBnZW5lcmljX3hwbTsKICAgIH0KCiAgICBuID0gMDsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU50b3BPZmZzZXQsIDgpOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgbisrOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tT2Zmc2V0LCA4KTsgbisrOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5sZWZ0T2Zmc2V0LCA4KTsgbisrOwoKICAgIGRpYWxvZ3BpeG1hcCA9IGNyZWF0ZV9waXhtYXBfbGFiZWwoZm9ybSwgImRpYWxvZ1BpeG1hcCIsCgkgICAgaWNvbl9kYXRhLCBhcmdzLCBuKTsKICAgIFh0TWFuYWdlQ2hpbGQoZGlhbG9ncGl4bWFwKTsKI2VuZGlmCgogICAgLyogQ3JlYXRlIHRoZSBkaWFsb2cgbWVzc2FnZS4KICAgICAqIFNpbmNlIExlc3NUaWYgaXMgYXBwYXJlbnRseSBoYXZpbmcgcHJvYmxlbXMgd2l0aCB0aGUgY3JlYXRpb24gb2YKICAgICAqIHByb3Blcmx5IGxvY2FsaXplZCBzdHJpbmcsIHdlIHVzZSBMdG9SIGhlcmUuIFRoZSBzeW1wdG9tIGlzIHRoYXQgdGhlCiAgICAgKiBzdHJpbmcgc2lsbCBub3Qgc2hvdyBwcm9wZXJseSBpbiBtdWx0aXBsZSBsaW5lcyBhcyBpdCBkb2VzIGluIG5hdGl2ZQogICAgICogTW90aWYuCiAgICAgKi8KICAgIGxhYmVsID0gWG1TdHJpbmdDcmVhdGVMdG9SKChjaGFyICopbWVzc2FnZSwgU1RSSU5HX1RBRyk7CiAgICBpZiAobGFiZWwgPT0gTlVMTCkKCXJldHVybiAtMTsKICAgIHcgPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgiZGlhbG9nTWVzc2FnZSIsCgkJCQl4bUxhYmVsR2FkZ2V0Q2xhc3MsIGZvcm0sCgkJCQlYbU5sYWJlbFN0cmluZywgbGFiZWwsCgkJCQlYbU5hbGlnbm1lbnQsIFhtQUxJR05NRU5UX0JFR0lOTklORywKCQkJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCQlYbU50b3BPZmZzZXQsIDgsCiNpZmRlZiBIQVZFX1hQTQoJCQkJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJCVhtTmxlZnRXaWRnZXQsIGRpYWxvZ3BpeG1hcCwKI2Vsc2UKCQkJCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAojZW5kaWYKCQkJCVhtTmxlZnRPZmZzZXQsIDgsCgkJCQlYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCQlYbU5yaWdodE9mZnNldCwgOCwKCQkJCVhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCQlYbU5ib3R0b21PZmZzZXQsIDgsCgkJCQlOVUxMKTsKICAgIFhtU3RyaW5nRnJlZShsYWJlbCk7CiAgICBzZXRfZm9udGxpc3Qodyk7CgogICAgaWYgKHRleHRmaWVsZCAhPSBOVUxMKQogICAgewoJWHRWYVNldFZhbHVlcyhmb3JtLAoJCVhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQlYbU5ib3R0b21XaWRnZXQsIGRpYWxvZ3RleHRmaWVsZCwKCQlOVUxMKTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWlmIChidXRjb3VudCA+IDApCgkgICAgWHRWYVNldFZhbHVlcyhmb3JtLAoJCSAgICBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJICAgIFhtTmJvdHRvbVdpZGdldCwgc2VwYXJhdG9yLAoJCSAgICBOVUxMKTsKCWVsc2UKCSAgICBYdFZhU2V0VmFsdWVzKGZvcm0sCgkJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJICAgIE5VTEwpOwogICAgfQoKICAgIGlmIChkZmx0YnV0dG9uIDwgMSkKCWRmbHRidXR0b24gPSAxOwogICAgaWYgKGRmbHRidXR0b24gPiBidXRjb3VudCkKCWRmbHRidXR0b24gPSBidXRjb3VudDsKICAgIFh0VmFTZXRWYWx1ZXMoZGlhbG9nZm9ybSwKCSAgICBYbU5kZWZhdWx0QnV0dG9uLCBidXR0b25zW2RmbHRidXR0b24gLSAxXSwgTlVMTCk7CiAgICBpZiAodGV4dGZpZWxkICE9IE5VTEwpCglYdFZhU2V0VmFsdWVzKGRpYWxvZ2Zvcm0sIFhtTmluaXRpYWxGb2N1cywgZGlhbG9ndGV4dGZpZWxkLCBOVUxMKTsKICAgIGVsc2UKCVh0VmFTZXRWYWx1ZXMoZGlhbG9nZm9ybSwgWG1OaW5pdGlhbEZvY3VzLCBidXR0b25zW2RmbHRidXR0b24gLSAxXSwKCQkJCQkJCQkJTlVMTCk7CgogICAgbWFuYWdlX2NlbnRlcmVkKGRpYWxvZ2Zvcm0pOwogICAgYWN0aXZhdGVfZGlhbG9nX21uZW1vbmljcyhkaWFsb2dmb3JtKTsKCiAgICBpZiAodGV4dGZpZWxkICE9IE5VTEwgJiYgKnRleHRmaWVsZCAhPSBOVUwpCiAgICB7CgkvKiBUaGlzIG9ubHkgd29ya3MgYWZ0ZXIgdGhlIHRleHRmaWVsZCBoYXMgYmVlbiByZWFsaXNlZC4gKi8KCVhtVGV4dEZpZWxkU2V0U2VsZWN0aW9uKGRpYWxvZ3RleHRmaWVsZCwKCQkJIChYbVRleHRQb3NpdGlvbikwLCAoWG1UZXh0UG9zaXRpb24pU1RSTEVOKHRleHRmaWVsZCksCgkJCQkJICAgWHRMYXN0VGltZXN0YW1wUHJvY2Vzc2VkKGd1aS5kcHkpKTsKCVhtVGV4dEZpZWxkU2V0Q3Vyc29yUG9zaXRpb24oZGlhbG9ndGV4dGZpZWxkLAoJCQkJCSAgIChYbVRleHRQb3NpdGlvbilTVFJMRU4odGV4dGZpZWxkKSk7CiAgICB9CgogICAgYXBwID0gWHRXaWRnZXRUb0FwcGxpY2F0aW9uQ29udGV4dChkaWFsb2dmb3JtKTsKCiAgICAvKiBMb29wIHVudGlsIGEgYnV0dG9uIGlzIHByZXNzZWQgb3IgdGhlIGRpYWxvZyBpcyBraWxsZWQgc29tZWhvdy4gKi8KICAgIGRpYWxvZ1N0YXR1cyA9IC0xOwogICAgZm9yICg7OykKICAgIHsKCVh0QXBwUHJvY2Vzc0V2ZW50KGFwcCwgKFh0SW5wdXRNYXNrKVh0SU1BbGwpOwoJaWYgKGRpYWxvZ1N0YXR1cyA+PSAwIHx8ICFYdElzTWFuYWdlZChkaWFsb2dmb3JtKSkKCSAgICBicmVhazsKICAgIH0KCiAgICB2aW1fZnJlZShidXR0b25zKTsKCiAgICBpZiAodGV4dGZpZWxkICE9IE5VTEwpCiAgICB7CglwID0gKGNoYXJfdSAqKVhtVGV4dEdldFN0cmluZyhkaWFsb2d0ZXh0ZmllbGQpOwoJaWYgKHAgPT0gTlVMTCB8fCBkaWFsb2dTdGF0dXMgPCAwKQoJICAgICp0ZXh0ZmllbGQgPSBOVUw7CgllbHNlCgkgICAgdmltX3N0cm5jcHkodGV4dGZpZWxkLCBwLCBJT1NJWkUgLSAxKTsKICAgIH0KCiAgICBzdXBwcmVzc19kaWFsb2dfbW5lbW9uaWNzKGRpYWxvZ2Zvcm0pOwogICAgWHREZXN0cm95V2lkZ2V0KGRpYWxvZ2Zvcm0pOwoKICAgIHJldHVybiBkaWFsb2dTdGF0dXM7Cn0KI2VuZGlmIC8qIEZFQVRfR1VJX0RJQUxPRyAqLwoKI2lmIGRlZmluZWQoRkVBVF9GT09URVIpIHx8IGRlZmluZWQoUFJPVE8pCgogICAgc3RhdGljIGludApndWlfbWNoX2NvbXB1dGVfZm9vdGVyX2hlaWdodCgpCnsKICAgIERpbWVuc2lvbgloZWlnaHQ7CQkgICAgLyogdG90YWwgVG9vbGJhciBoZWlnaHQgKi8KICAgIERpbWVuc2lvbgl0b3A7CQkgICAgLyogWG1ObWFyZ2luVG9wICovCiAgICBEaW1lbnNpb24JYm90dG9tOwkJICAgIC8qIFhtTm1hcmdpbkJvdHRvbSAqLwogICAgRGltZW5zaW9uCXNoYWRvdzsJCSAgICAvKiBYbU5zaGFkb3dUaGlja25lc3MgKi8KCiAgICBYdFZhR2V0VmFsdWVzKGZvb3RlciwKCSAgICBYbU5oZWlnaHQsICZoZWlnaHQsCgkgICAgWG1ObWFyZ2luVG9wLCAmdG9wLAoJICAgIFhtTm1hcmdpbkJvdHRvbSwgJmJvdHRvbSwKCSAgICBYbU5zaGFkb3dUaGlja25lc3MsICZzaGFkb3csCgkgICAgTlVMTCk7CgogICAgcmV0dXJuIChpbnQpIGhlaWdodCArIHRvcCArIGJvdHRvbSArIChzaGFkb3cgPDwgMSk7Cn0KCiNpZiAwCSAgICAvKiBub3QgdXNlZCAqLwogICAgdm9pZApndWlfbWNoX3NldF9mb290ZXJfcG9zKGgpCiAgICBpbnQJICAgIGg7CQkJICAgIC8qIHRleHRBcmVhIGhlaWdodCAqLwp7CiAgICBYdFZhU2V0VmFsdWVzKGZvb3RlciwKCQkgIFhtTnRvcE9mZnNldCwgaCArIDcsCgkJICBOVUxMKTsKfQojZW5kaWYKCiAgICB2b2lkCmd1aV9tY2hfZW5hYmxlX2Zvb3RlcihzaG93aXQpCiAgICBpbnQJCXNob3dpdDsKewogICAgaWYgKHNob3dpdCkKICAgIHsKCWd1aS5mb290ZXJfaGVpZ2h0ID0gZ3VpX21jaF9jb21wdXRlX2Zvb3Rlcl9oZWlnaHQoKTsKCVh0TWFuYWdlQ2hpbGQoZm9vdGVyKTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWd1aS5mb290ZXJfaGVpZ2h0ID0gMDsKCVh0VW5tYW5hZ2VDaGlsZChmb290ZXIpOwogICAgfQogICAgWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sIFhtTmJvdHRvbU9mZnNldCwgZ3VpLmZvb3Rlcl9oZWlnaHQsIE5VTEwpOwp9CgogICAgdm9pZApndWlfbWNoX3NldF9mb290ZXIocykKICAgIGNoYXJfdQkqczsKewogICAgWG1TdHJpbmcJeG1zOwoKICAgIHhtcyA9IFhtU3RyaW5nQ3JlYXRlKChjaGFyICopcywgU1RSSU5HX1RBRyk7CiAgICBpZiAoeG1zICE9IE5VTEwpCiAgICB7CglYdFZhU2V0VmFsdWVzKGZvb3RlciwgWG1ObGFiZWxTdHJpbmcsIHhtcywgTlVMTCk7CglYbVN0cmluZ0ZyZWUoeG1zKTsKICAgIH0KfQoKI2VuZGlmCgoKI2lmIGRlZmluZWQoRkVBVF9UT09MQkFSKSB8fCBkZWZpbmVkKFBST1RPKQogICAgdm9pZApndWlfbWNoX3Nob3dfdG9vbGJhcihpbnQgc2hvd2l0KQp7CiAgICBDYXJkaW5hbAludW1DaGlsZHJlbjsJICAgIC8qIGhvdyBtYW55IGNoaWxkcmVuIHRvb2xCYXIgaGFzICovCgogICAgaWYgKHRvb2xCYXIgPT0gKFdpZGdldCkwKQoJcmV0dXJuOwogICAgWHRWYUdldFZhbHVlcyh0b29sQmFyLCBYbU5udW1DaGlsZHJlbiwgJm51bUNoaWxkcmVuLCBOVUxMKTsKICAgIGlmIChzaG93aXQgJiYgbnVtQ2hpbGRyZW4gPiAwKQogICAgewoJLyogQXNzdW1lIHRoYXQgd2Ugd2FudCB0byBzaG93IHRoZSB0b29sYmFyIGlmIHBfdG9vbGJhciBjb250YWlucwoJICogdmFsaWQgb3B0aW9uIHNldHRpbmdzLCB0aGVyZWZvcmUgcF90b29sYmFyIG11c3Qgbm90IGJlIE5VTEwuCgkgKi8KCVdpZGdldExpc3QgIGNoaWxkcmVuOwoKCVh0VmFHZXRWYWx1ZXModG9vbEJhciwgWG1OY2hpbGRyZW4sICZjaGlsZHJlbiwgTlVMTCk7Cgl7CgkgICAgdm9pZCAgICAoKmFjdGlvbikoQmFsbG9vbkV2YWwgKik7CgkgICAgaW50CSAgICB0ZXh0ID0gMDsKCgkgICAgaWYgKHN0cnN0cigoY29uc3QgY2hhciAqKXBfdG9vbGJhciwgInRvb2x0aXBzIikpCgkJYWN0aW9uID0gJmd1aV9tY2hfZW5hYmxlX2JldmFsX2FyZWE7CgkgICAgZWxzZQoJCWFjdGlvbiA9ICZndWlfbWNoX2Rpc2FibGVfYmV2YWxfYXJlYTsKCSAgICBpZiAoc3Ryc3RyKChjb25zdCBjaGFyICopcF90b29sYmFyLCAidGV4dCIpKQoJCXRleHQgPSAxOwoJICAgIGVsc2UgaWYgKHN0cnN0cigoY29uc3QgY2hhciAqKXBfdG9vbGJhciwgImljb25zIikpCgkJdGV4dCA9IC0xOwoJICAgIGlmICh0ZXh0ICE9IDApCgkgICAgewoJCXZpbW1lbnVfVCAgICp0b29sYmFyOwoJCXZpbW1lbnVfVCAgICpjdXI7CgoJCWZvciAodG9vbGJhciA9IHJvb3RfbWVudTsgdG9vbGJhcjsgdG9vbGJhciA9IHRvb2xiYXItPm5leHQpCgkJICAgIGlmIChtZW51X2lzX3Rvb2xiYXIodG9vbGJhci0+ZG5hbWUpKQoJCQlicmVhazsKCQkvKiBBc3N1bXB0aW9uOiB0b29sYmFyIGlzIE5VTEwgaWYgdGhlcmUgaXMgbm8gdG9vbGJhciwKCQkgKgkgICAgICAgb3RoZXJ3aXNlIGl0IGNvbnRhaW5zIHRoZSB0b29sYmFyIG1lbnUgc3RydWN0dXJlLgoJCSAqCgkJICogQXNzdW1wdGlvbjogIm51bUNoaWxkcmVuIiA9PSB0aGUgbnVtYmVyIG9mIGl0ZW1zIGluIHRoZSBsaXN0CgkJICoJICAgICAgIG9mIGl0ZW1zIGJlZ2lubmluZyB3aXRoIHRvb2xiYXItPmNoaWxkcmVuLgoJCSAqLwoJCWlmICh0b29sYmFyKQoJCXsKCQkgICAgZm9yIChjdXIgPSB0b29sYmFyLT5jaGlsZHJlbjsgY3VyOyBjdXIgPSBjdXItPm5leHQpCgkJICAgIHsKCQkJQXJnCSAgICBhcmdzWzFdOwoJCQlpbnQJICAgIG4gPSAwOwoKCQkJLyogRW5hYmxlL0Rpc2FibGUgdG9vbHRpcCAoT0sgdG8gZW5hYmxlIHdoaWxlCgkJCSAqIGN1cnJlbnRseSBlbmFibGVkKS4gKi8KCQkJaWYgKGN1ci0+dGlwICE9IE5VTEwpCgkJCSAgICAoKmFjdGlvbikoY3VyLT50aXApOwoJCQlpZiAoIW1lbnVfaXNfc2VwYXJhdG9yKGN1ci0+bmFtZSkpCgkJCXsKCQkJICAgIGlmICh0ZXh0ID09IDEgfHwgY3VyLT54cG0gPT0gTlVMTCkKCQkJICAgIHsKCQkJCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxhYmVsVHlwZSwgWG1TVFJJTkcpOwoJCQkJKytuOwoJCQkgICAgfQoJCQkgICAgaWYgKGN1ci0+aWQgIT0gTlVMTCkKCQkJICAgIHsKCQkJCVh0VW5tYW5hZ2VDaGlsZChjdXItPmlkKTsKCQkJCVh0U2V0VmFsdWVzKGN1ci0+aWQsIGFyZ3MsIG4pOwoJCQkJWHRNYW5hZ2VDaGlsZChjdXItPmlkKTsKCQkJICAgIH0KCQkJfQoJCSAgICB9CgkJfQoJICAgIH0KCX0KCWd1aS50b29sYmFyX2hlaWdodCA9IGd1aV9tY2hfY29tcHV0ZV90b29sYmFyX2hlaWdodCgpOwoJWHRNYW5hZ2VDaGlsZChYdFBhcmVudCh0b29sQmFyKSk7CiNpZmRlZiBGRUFUX0dVSV9UQUJMSU5FCglpZiAoc2hvd2luZ190YWJsaW5lKQoJewoJICAgIFh0VmFTZXRWYWx1ZXModGFiTGluZSwKCQkJICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgWG1OdG9wV2lkZ2V0LCBYdFBhcmVudCh0b29sQmFyKSwKCQkJICBOVUxMKTsKCSAgICBYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQkJICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgWG1OdG9wV2lkZ2V0LCB0YWJMaW5lLAoJCQkgIE5VTEwpOwoJfQoJZWxzZQojZW5kaWYKCSAgICBYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQkJICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgWG1OdG9wV2lkZ2V0LCBYdFBhcmVudCh0b29sQmFyKSwKCQkJICBOVUxMKTsKCWlmIChYdElzTWFuYWdlZChtZW51QmFyKSkKCSAgICBYdFZhU2V0VmFsdWVzKFh0UGFyZW50KHRvb2xCYXIpLAoJCSAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJICAgIFhtTnRvcFdpZGdldCwgbWVudUJhciwKCQkgICAgTlVMTCk7CgllbHNlCgkgICAgWHRWYVNldFZhbHVlcyhYdFBhcmVudCh0b29sQmFyKSwKCQkgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkgICAgTlVMTCk7CiAgICB9CiAgICBlbHNlCiAgICB7CglndWkudG9vbGJhcl9oZWlnaHQgPSAwOwoJaWYgKFh0SXNNYW5hZ2VkKG1lbnVCYXIpKQoJewojaWZkZWYgRkVBVF9HVUlfVEFCTElORQoJICAgIGlmIChzaG93aW5nX3RhYmxpbmUpCgkgICAgewoJCVh0VmFTZXRWYWx1ZXModGFiTGluZSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQkgICAgICBYbU50b3BXaWRnZXQsIG1lbnVCYXIsCgkJCSAgICAgIE5VTEwpOwoJCVh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICAgIFhtTnRvcFdpZGdldCwgdGFiTGluZSwKCQkJICAgICAgTlVMTCk7CgkgICAgfQoJICAgIGVsc2UKI2VuZGlmCgkJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCBtZW51QmFyLAoJCQkgICAgICBOVUxMKTsKCX0KCWVsc2UKCXsKI2lmZGVmIEZFQVRfR1VJX1RBQkxJTkUKCSAgICBpZiAoc2hvd2luZ190YWJsaW5lKQoJICAgIHsKCQlYdFZhU2V0VmFsdWVzKHRhYkxpbmUsCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCSAgICAgIE5VTEwpOwoJCVh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICAgIFhtTnRvcFdpZGdldCwgdGFiTGluZSwKCQkJICAgICAgTlVMTCk7CgkgICAgfQoJICAgIGVsc2UKI2VuZGlmCgkJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCSAgICAgIE5VTEwpOwoJfQoKCVh0VW5tYW5hZ2VDaGlsZChYdFBhcmVudCh0b29sQmFyKSk7CiAgICB9CiAgICBndWlfc2V0X3NoZWxsc2l6ZShGQUxTRSwgRkFMU0UsIFJFU0laRV9WRVJUKTsKfQoKLyoKICogQSB0b29sYmFyIGJ1dHRvbiBoYXMgYmVlbiBwdXNoZWQ7IG5vdyByZXNldCB0aGUgaW5wdXQgZm9jdXMKICogc3VjaCB0aGF0IHRoZSB1c2VyIGNhbiB0eXBlIHBhZ2UgdXAvZG93biBldGMuIGFuZCBoYXZlIHRoZQogKiBpbnB1dCBnbyB0byB0aGUgZWRpdG9yIHdpbmRvdywgbm90IHRoZSBidXR0b24KICovCiAgICBzdGF0aWMgdm9pZApyZXNldF9mb2N1cygpCnsKICAgIGlmICh0ZXh0QXJlYSAhPSBOVUxMKQoJWG1Qcm9jZXNzVHJhdmVyc2FsKHRleHRBcmVhLCBYbVRSQVZFUlNFX0NVUlJFTlQpOwp9CgogICAgaW50Cmd1aV9tY2hfY29tcHV0ZV90b29sYmFyX2hlaWdodCgpCnsKICAgIERpbWVuc2lvbglib3JkZXJzOwogICAgRGltZW5zaW9uCWhlaWdodDsJCSAgICAvKiB0b3RhbCBUb29sYmFyIGhlaWdodCAqLwogICAgRGltZW5zaW9uCXdoZ3Q7CQkgICAgLyogaGVpZ2h0IG9mIGVhY2ggd2lkZ2V0ICovCiAgICBXaWRnZXRMaXN0CWNoaWxkcmVuOwkgICAgLyogbGlzdCBvZiB0b29sQmFyJ3MgY2hpbGRyZW4gKi8KICAgIENhcmRpbmFsCW51bUNoaWxkcmVuOwkgICAgLyogaG93IG1hbnkgY2hpbGRyZW4gdG9vbEJhciBoYXMgKi8KICAgIGludAkJaTsKCiAgICBib3JkZXJzID0gMDsKICAgIGhlaWdodCA9IDA7CiAgICBpZiAodG9vbEJhciAhPSAoV2lkZ2V0KTAgJiYgdG9vbEJhckZyYW1lICE9IChXaWRnZXQpMCkKICAgIHsJCQkJICAgIC8qIGdldCBoZWlnaHQgb2YgWG1GcmFtZSBwYXJlbnQgKi8KCURpbWVuc2lvbglmc3Q7CglEaW1lbnNpb24JZm1oOwoJRGltZW5zaW9uCXRzdDsKCURpbWVuc2lvbgl0bWg7CgoJWHRWYUdldFZhbHVlcyh0b29sQmFyRnJhbWUsCgkJWG1Oc2hhZG93VGhpY2tuZXNzLCAmZnN0LAoJCVhtTm1hcmdpbkhlaWdodCwgJmZtaCwKCQlOVUxMKTsKCWJvcmRlcnMgKz0gZnN0ICsgZm1oOwoJWHRWYUdldFZhbHVlcyh0b29sQmFyLAoJCVhtTnNoYWRvd1RoaWNrbmVzcywgJnRzdCwKCQlYbU5tYXJnaW5IZWlnaHQsICZ0bWgsCgkJWG1OY2hpbGRyZW4sICZjaGlsZHJlbiwKCQlYbU5udW1DaGlsZHJlbiwgJm51bUNoaWxkcmVuLCBOVUxMKTsKCWJvcmRlcnMgKz0gdHN0ICsgdG1oOwoJZm9yIChpID0gMDsgaSA8IG51bUNoaWxkcmVuOyBpKyspCgl7CgkgICAgd2hndCA9IDA7CgkgICAgWHRWYUdldFZhbHVlcyhjaGlsZHJlbltpXSwgWG1OaGVpZ2h0LCAmd2hndCwgTlVMTCk7CgkgICAgaWYgKGhlaWdodCA8IHdoZ3QpCgkJaGVpZ2h0ID0gd2hndDsKCX0KICAgIH0KI2lmZGVmIExFU1NUSUZfVkVSU0lPTgogICAgLyogSGFjazogV2hlbiBzdGFydGluZyB1cCB3ZSBnZXQgd3JvbmcgZGltZW5zaW9ucy4gKi8KICAgIGlmIChoZWlnaHQgPCAxMCkKCWhlaWdodCA9IDI0OwojZW5kaWYKCiAgICByZXR1cm4gKGludCkoaGVpZ2h0ICsgKGJvcmRlcnMgPDwgMSkpOwp9CgogICAgdm9pZAptb3RpZl9nZXRfdG9vbGJhcl9jb2xvcnMoYmdwLCBmZ3AsIGJzcCwgdHNwLCBoc3ApCiAgICBQaXhlbCAgICAgICAqYmdwOwogICAgUGl4ZWwgICAgICAgKmZncDsKICAgIFBpeGVsICAgICAgICpic3A7CiAgICBQaXhlbCAgICAgICAqdHNwOwogICAgUGl4ZWwgICAgICAgKmhzcDsKewogICAgWHRWYUdldFZhbHVlcyh0b29sQmFyLAoJICAgIFhtTmJhY2tncm91bmQsIGJncCwKCSAgICBYbU5mb3JlZ3JvdW5kLCBmZ3AsCgkgICAgWG1OYm90dG9tU2hhZG93Q29sb3IsIGJzcCwKCSAgICBYbU50b3BTaGFkb3dDb2xvciwgdHNwLAoJICAgIFhtTmhpZ2hsaWdodENvbG9yLCBoc3AsCgkgICAgTlVMTCk7Cn0KCiMgaWZkZWYgRkVBVF9GT09URVIKLyoKICogVGhlIG5leHQgdG9vbGJhciBlbnRlci9sZWF2ZSBjYWxsYmFja3Mgc2hvdWxkIHJlYWxseSBkbyBiYWxsb29uIGhlbHAuICBCdXQKICogSSBoYXZlIHRvIHVzZSBmb290ZXIgaGVscCBmb3IgYmFja3dhcmRzIGNvbXBhdGFiaWxpdHkuICBIb3BlZnVsbHkgYm90aCB3aWxsCiAqIGdldCBpbXBsZW1lbnRlZCBhbmQgdGhlIHVzZXIgd2lsbCBoYXZlIGEgY2hvaWNlLgogKi8KLypBUkdTVVNFRCovCiAgICBzdGF0aWMgdm9pZAp0b29sYmFyYnV0dG9uX2VudGVyX2NiKHcsIGNsaWVudF9kYXRhLCBldmVudCwgY29udCkKICAgIFdpZGdldAl3OwogICAgWHRQb2ludGVyCWNsaWVudF9kYXRhOwogICAgWEV2ZW50CSpldmVudDsKICAgIEJvb2xlYW4JKmNvbnQ7CnsKICAgIHZpbW1lbnVfVAkqbWVudSA9ICh2aW1tZW51X1QgKikgY2xpZW50X2RhdGE7CgogICAgaWYgKG1lbnUtPnN0cmluZ3NbTUVOVV9JTkRFWF9USVBdICE9IE5VTEwpCiAgICB7CglpZiAodmltX3N0cmNocihwX2dvLCBHT19GT09URVIpICE9IE5VTEwpCgkgICAgZ3VpX21jaF9zZXRfZm9vdGVyKG1lbnUtPnN0cmluZ3NbTUVOVV9JTkRFWF9USVBdKTsKICAgIH0KfQoKLypBUkdTVVNFRCovCiAgICBzdGF0aWMgdm9pZAp0b29sYmFyYnV0dG9uX2xlYXZlX2NiKHcsIGNsaWVudF9kYXRhLCBldmVudCwgY29udCkKICAgIFdpZGdldAl3OwogICAgWHRQb2ludGVyCWNsaWVudF9kYXRhOwogICAgWEV2ZW50CSpldmVudDsKICAgIEJvb2xlYW4JKmNvbnQ7CnsKICAgIGd1aV9tY2hfc2V0X2Zvb3RlcigoY2hhcl91ICopICIiKTsKfQojIGVuZGlmCiNlbmRpZgoKI2lmIGRlZmluZWQoRkVBVF9HVUlfVEFCTElORSkgfHwgZGVmaW5lZChQUk9UTykKLyoKICogU2hvdyBvciBoaWRlIHRoZSB0YWJsaW5lLgogKi8KICAgIHZvaWQKZ3VpX21jaF9zaG93X3RhYmxpbmUoaW50IHNob3dpdCkKewogICAgaWYgKHRhYkxpbmUgPT0gKFdpZGdldCkwKQoJcmV0dXJuOwoKICAgIGlmICghc2hvd2l0ICE9ICFzaG93aW5nX3RhYmxpbmUpCiAgICB7CglpZiAoc2hvd2l0KQoJewoJICAgIFh0TWFuYWdlQ2hpbGQodGFiTGluZSk7CgkgICAgWHRVbm1hbmFnZUNoaWxkKFh0TmFtZVRvV2lkZ2V0KHRhYkxpbmUsICJQYWdlU2Nyb2xsZXIiKSk7CgkgICAgWHRVbm1hbmFnZUNoaWxkKFh0TmFtZVRvV2lkZ2V0KHRhYkxpbmUsICJNaW5vclRhYlNjcm9sbGVyTmV4dCIpKTsKCSAgICBYdFVubWFuYWdlQ2hpbGQoWHROYW1lVG9XaWRnZXQodGFiTGluZSwKCQkJCQkgICAiTWlub3JUYWJTY3JvbGxlclByZXZpb3VzIikpOwojaWZkZWYgRkVBVF9NRU5VCiMgaWZkZWYgRkVBVF9UT09MQkFSCgkgICAgaWYgKFh0SXNNYW5hZ2VkKFh0UGFyZW50KHRvb2xCYXIpKSkKCQlYdFZhU2V0VmFsdWVzKHRhYkxpbmUsCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCBYdFBhcmVudCh0b29sQmFyKSwgTlVMTCk7CgkgICAgZWxzZQojIGVuZGlmCgkJaWYgKFh0SXNNYW5hZ2VkKG1lbnVCYXIpKQoJCVh0VmFTZXRWYWx1ZXModGFiTGluZSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQkgICAgICBYbU50b3BXaWRnZXQsIG1lbnVCYXIsIE5VTEwpOwoJICAgIGVsc2UKI2VuZGlmCgkJWHRWYVNldFZhbHVlcyh0YWJMaW5lLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLCBOVUxMKTsKCSAgICBYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQkJICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgWG1OdG9wV2lkZ2V0LCB0YWJMaW5lLAoJCQkgIE5VTEwpOwoJfQoJZWxzZQoJewoJICAgIFh0VW5tYW5hZ2VDaGlsZCh0YWJMaW5lKTsKI2lmZGVmIEZFQVRfTUVOVQojIGlmZGVmIEZFQVRfVE9PTEJBUgoJICAgIGlmIChYdElzTWFuYWdlZChYdFBhcmVudCh0b29sQmFyKSkpCgkJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCBYdFBhcmVudCh0b29sQmFyKSwgTlVMTCk7CgkgICAgZWxzZQojIGVuZGlmCgkJaWYgKFh0SXNNYW5hZ2VkKG1lbnVCYXIpKQoJCVh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICAgIFhtTnRvcFdpZGdldCwgbWVudUJhciwgTlVMTCk7CgkgICAgZWxzZQojZW5kaWYKCQlYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwgTlVMTCk7Cgl9CglzaG93aW5nX3RhYmxpbmUgPSBzaG93aXQ7CiAgICB9Cn0KCi8qCiAqIFJldHVybiBUUlVFIHdoZW4gdGFibGluZSBpcyBkaXNwbGF5ZWQuCiAqLwogICAgaW50Cmd1aV9tY2hfc2hvd2luZ190YWJsaW5lKHZvaWQpCnsKICAgIHJldHVybiB0YWJMaW5lICE9IChXaWRnZXQpMCAmJiBzaG93aW5nX3RhYmxpbmU7Cn0KCi8qCiAqIFVwZGF0ZSB0aGUgbGFiZWxzIG9mIHRoZSB0YWJsaW5lLgogKi8KICAgIHZvaWQKZ3VpX21jaF91cGRhdGVfdGFibGluZSh2b2lkKQp7CiAgICB0YWJwYWdlX1QJCSp0cDsKICAgIGludAkJCW5yID0gMSwgbjsKICAgIEFyZwkJCWFyZ3NbMTBdOwogICAgaW50CQkJY3VydGFiaWR4ID0gMCwgY3VycmVudHBhZ2U7CiAgICBXaWRnZXQJCXRhYjsKICAgIFhtTm90ZWJvb2tQYWdlSW5mbwlwYWdlX2luZm87CiAgICBYbU5vdGVib29rUGFnZVN0YXR1cyBwYWdlX3N0YXR1czsKICAgIGludAkJCWxhc3RfcGFnZSwgdGFiX2NvdW50OwogICAgWG1TdHJpbmcJCWxhYmVsX3N0cjsKICAgIGNoYXIJCSpsYWJlbF9jc3RyOwogICAgQmFsbG9vbkV2YWwJCSpiZXZhbDsKCiAgICBpZiAodGFiTGluZSA9PSAoV2lkZ2V0KTApCglyZXR1cm47CgogICAgLyogQWRkIGEgbGFiZWwgZm9yIGVhY2ggdGFiIHBhZ2UuICBUaGV5IGFsbCBjb250YWluIHRoZSBzYW1lIHRleHQgYXJlYS4gKi8KICAgIGZvciAodHAgPSBmaXJzdF90YWJwYWdlOyB0cCAhPSBOVUxMOyB0cCA9IHRwLT50cF9uZXh0LCArK25yKQogICAgewoJaWYgKHRwID09IGN1cnRhYikKCSAgICBjdXJ0YWJpZHggPSBucjsKCglwYWdlX3N0YXR1cyA9IFhtTm90ZWJvb2tHZXRQYWdlSW5mbyh0YWJMaW5lLCBuciwgJnBhZ2VfaW5mbyk7CglpZiAocGFnZV9zdGF0dXMgPT0gWG1QQUdFX0lOVkFMSUQKCQl8fCBwYWdlX2luZm8ubWFqb3JfdGFiX3dpZGdldCA9PSAoV2lkZ2V0KTApCgl7CgkgICAgLyogQWRkIHRoZSB0YWIgKi8KCSAgICBuID0gMDsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5ub3RlYm9va0NoaWxkVHlwZSwgWG1NQUpPUl9UQUIpOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OdHJhdmVyc2FsT24sIEZhbHNlKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmFsaWdubWVudCwgWG1BTElHTk1FTlRfQkVHSU5OSU5HKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmhpZ2hsaWdodFRoaWNrbmVzcywgMSk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5zaGFkb3dUaGlja25lc3MgLCAxKTsgbisrOwoJICAgIHRhYiA9IFhtQ3JlYXRlUHVzaEJ1dHRvbih0YWJMaW5lLCAiLUVtcHR5LSIsIGFyZ3MsIG4pOwoJICAgIFh0TWFuYWdlQ2hpbGQodGFiKTsKCSAgICBiZXZhbCA9IGd1aV9tY2hfY3JlYXRlX2JldmFsX2FyZWEodGFiLCBOVUxMLCB0YWJsaW5lX2JhbGxvb25fY2IsCgkJCQkJCQkJCU5VTEwpOwoJICAgIFh0VmFTZXRWYWx1ZXModGFiLCBYbU51c2VyRGF0YSwgYmV2YWwsIE5VTEwpOwoJfQoJZWxzZQoJICAgIHRhYiA9IHBhZ2VfaW5mby5tYWpvcl90YWJfd2lkZ2V0OwoKCVh0VmFTZXRWYWx1ZXModGFiLCBYbU5wYWdlTnVtYmVyLCBuciwgTlVMTCk7CgoJLyoKCSAqIENoYW5nZSB0aGUgbGFiZWwgdGV4dCBvbmx5IGlmIGl0IGlzIGRpZmZlcmVudAoJICovCglYdFZhR2V0VmFsdWVzKHRhYiwgWG1ObGFiZWxTdHJpbmcsICZsYWJlbF9zdHIsIE5VTEwpOwoJaWYgKFhtU3RyaW5nR2V0THRvUihsYWJlbF9zdHIsIFhtU1RSSU5HX0RFRkFVTFRfQ0hBUlNFVCwgJmxhYmVsX2NzdHIpKQoJewoJICAgIGdldF90YWJsaW5lX2xhYmVsKHRwLCBGQUxTRSk7CgkgICAgaWYgKFNUUkNNUChsYWJlbF9jc3RyLCBOYW1lQnVmZikgIT0gMCkKCSAgICB7CgkJWHRWYVNldFZhbHVlcyh0YWIsIFh0VmFUeXBlZEFyZywgWG1ObGFiZWxTdHJpbmcsIFhtUlN0cmluZywKCQkJICAgICAgTmFtZUJ1ZmYsIFNUUkxFTihOYW1lQnVmZikgKyAxLCBOVUxMKTsKCQkvKgoJCSAqIEZvcmNlIGEgcmVzaXplIG9mIHRoZSB0YWIgbGFiZWwgYnV0dG9uCgkJICovCgkJWHRVbm1hbmFnZUNoaWxkKHRhYik7CgkJWHRNYW5hZ2VDaGlsZCh0YWIpOwoJICAgIH0KCSAgICBYdEZyZWUobGFiZWxfY3N0cik7Cgl9CiAgICB9CgogICAgdGFiX2NvdW50ID0gbnIgLSAxOwoKICAgIFh0VmFHZXRWYWx1ZXModGFiTGluZSwgWG1ObGFzdFBhZ2VOdW1iZXIsICZsYXN0X3BhZ2UsIE5VTEwpOwoKICAgIC8qIFJlbW92ZSBhbnkgb2xkIGxhYmVscy4gKi8KICAgIHdoaWxlIChuciA8PSBsYXN0X3BhZ2UpCiAgICB7CglpZiAoWG1Ob3RlYm9va0dldFBhZ2VJbmZvKHRhYkxpbmUsIG5yLCAmcGFnZV9pbmZvKSAhPSBYbVBBR0VfSU5WQUxJRAoJICAgICYmIHBhZ2VfaW5mby5wYWdlX251bWJlciA9PSBucgoJICAgICYmIHBhZ2VfaW5mby5tYWpvcl90YWJfd2lkZ2V0ICE9IChXaWRnZXQpMCkKCXsKCSAgICBYdFZhR2V0VmFsdWVzKHBhZ2VfaW5mby5tYWpvcl90YWJfd2lkZ2V0LCBYbU51c2VyRGF0YSwgJmJldmFsLCBOVUxMKTsKCSAgICBpZiAoYmV2YWwgIT0gTlVMTCkKCQlndWlfbWNoX2Rlc3Ryb3lfYmV2YWxfYXJlYShiZXZhbCk7CgkgICAgWHRVbm1hbmFnZUNoaWxkKHBhZ2VfaW5mby5tYWpvcl90YWJfd2lkZ2V0KTsKCSAgICBYdERlc3Ryb3lXaWRnZXQocGFnZV9pbmZvLm1ham9yX3RhYl93aWRnZXQpOwoJfQoJbnIrKzsKICAgIH0KCiAgICBYdFZhU2V0VmFsdWVzKHRhYkxpbmUsIFhtTmxhc3RQYWdlTnVtYmVyLCB0YWJfY291bnQsIE5VTEwpOwoKICAgIFh0VmFHZXRWYWx1ZXModGFiTGluZSwgWG1OY3VycmVudFBhZ2VOdW1iZXIsICZjdXJyZW50cGFnZSwgTlVMTCk7CiAgICBpZiAoY3VycmVudHBhZ2UgIT0gY3VydGFiaWR4KQoJWHRWYVNldFZhbHVlcyh0YWJMaW5lLCBYbU5jdXJyZW50UGFnZU51bWJlciwgY3VydGFiaWR4LCBOVUxMKTsKfQoKLyoKICogU2V0IHRoZSBjdXJyZW50IHRhYiB0byAibnIiLiAgRmlyc3QgdGFiIGlzIDEuCiAqLwogICAgdm9pZApndWlfbWNoX3NldF9jdXJ0YWIobnIpCiAgICBpbnQJCW5yOwp7CiAgICBpbnQJCWN1cnJlbnRwYWdlOwoKICAgIGlmICh0YWJMaW5lID09IChXaWRnZXQpMCkKCXJldHVybjsKCiAgICBYdFZhR2V0VmFsdWVzKHRhYkxpbmUsIFhtTmN1cnJlbnRQYWdlTnVtYmVyLCAmY3VycmVudHBhZ2UsIE5VTEwpOwogICAgaWYgKGN1cnJlbnRwYWdlICE9IG5yKQoJWHRWYVNldFZhbHVlcyh0YWJMaW5lLCBYbU5jdXJyZW50UGFnZU51bWJlciwgbnIsIE5VTEwpOwp9CiNlbmRpZgoKLyoKICogU2V0IHRoZSBjb2xvcnMgb2YgV2lkZ2V0ICJpZCIgdG8gdGhlIG1lbnUgY29sb3JzLgogKi8KICAgIHN0YXRpYyB2b2lkCmd1aV9tb3RpZl9tZW51X2NvbG9ycyhpZCkKICAgIFdpZGdldCAgaWQ7CnsKICAgIGlmIChndWkubWVudV9iZ19waXhlbCAhPSBJTlZBTENPTE9SKQojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQoJWG1DaGFuZ2VDb2xvcihpZCwgZ3VpLm1lbnVfYmdfcGl4ZWwpOwojZWxzZQoJWHRWYVNldFZhbHVlcyhpZCwgWG1OYmFja2dyb3VuZCwgZ3VpLm1lbnVfYmdfcGl4ZWwsIE5VTEwpOwojZW5kaWYKICAgIGlmIChndWkubWVudV9mZ19waXhlbCAhPSBJTlZBTENPTE9SKQoJWHRWYVNldFZhbHVlcyhpZCwgWG1OZm9yZWdyb3VuZCwgZ3VpLm1lbnVfZmdfcGl4ZWwsIE5VTEwpOwp9CgovKgogKiBTZXQgdGhlIGNvbG9ycyBvZiBXaWRnZXQgImlkIiB0byB0aGUgc2Nyb2xsYmFyIGNvbG9ycy4KICovCiAgICBzdGF0aWMgdm9pZApndWlfbW90aWZfc2Nyb2xsX2NvbG9ycyhpZCkKICAgIFdpZGdldCAgaWQ7CnsKICAgIGlmIChndWkuc2Nyb2xsX2JnX3BpeGVsICE9IElOVkFMQ09MT1IpCiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCglYbUNoYW5nZUNvbG9yKGlkLCBndWkuc2Nyb2xsX2JnX3BpeGVsKTsKI2Vsc2UKCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmJhY2tncm91bmQsIGd1aS5zY3JvbGxfYmdfcGl4ZWwsIE5VTEwpOwojZW5kaWYKICAgIGlmIChndWkuc2Nyb2xsX2ZnX3BpeGVsICE9IElOVkFMQ09MT1IpCglYdFZhU2V0VmFsdWVzKGlkLCBYbU5mb3JlZ3JvdW5kLCBndWkuc2Nyb2xsX2ZnX3BpeGVsLCBOVUxMKTsKfQoKLyoKICogU2V0IHRoZSBmb250bGlzdCBmb3IgV2lkZ2V0ICJpZCIgdG8gdXNlIGd1aS5tZW51X2ZvbnRzZXQgb3IgZ3VpLm1lbnVfZm9udC4KICovCi8qQVJHU1VTRUQqLwogICAgdm9pZApndWlfbW90aWZfbWVudV9mb250bGlzdChpZCkKICAgIFdpZGdldCAgaWQ7CnsKI2lmZGVmIEZFQVRfTUVOVQojaWZkZWYgRk9OVFNFVF9BTFdBWVMKICAgIGlmIChndWkubWVudV9mb250c2V0ICE9IE5PRk9OVFNFVCkKICAgIHsKCVhtRm9udExpc3QgZmw7CgoJZmwgPSBndWlfbW90aWZfZm9udHNldDJmb250bGlzdCgoWEZvbnRTZXQgKikmZ3VpLm1lbnVfZm9udHNldCk7CglpZiAoZmwgIT0gTlVMTCkKCXsKCSAgICBpZiAoWHRJc01hbmFnZWQoaWQpKQoJICAgIHsKCQlYdFVubWFuYWdlQ2hpbGQoaWQpOwoJCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmZvbnRMaXN0LCBmbCwgTlVMTCk7CgkJLyogV2Ugc2hvdWxkIGZvcmNlIHRoZSB3aWRnZXQgdG8gcmVjYWxjdWxhdGUgaXQncwoJCSAqIGdlb21ldHJ5IG5vdy4gKi8KCQlYdE1hbmFnZUNoaWxkKGlkKTsKCSAgICB9CgkgICAgZWxzZQoJCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmZvbnRMaXN0LCBmbCwgTlVMTCk7CgkgICAgWG1Gb250TGlzdEZyZWUoZmwpOwoJfQogICAgfQojZWxzZQogICAgaWYgKGd1aS5tZW51X2ZvbnQgIT0gTk9GT05UKQogICAgewoJWG1Gb250TGlzdCBmbDsKCglmbCA9IGd1aV9tb3RpZl9jcmVhdGVfZm9udGxpc3QoKFhGb250U3RydWN0ICopZ3VpLm1lbnVfZm9udCk7CglpZiAoZmwgIT0gTlVMTCkKCXsKCSAgICBpZiAoWHRJc01hbmFnZWQoaWQpKQoJICAgIHsKCQlYdFVubWFuYWdlQ2hpbGQoaWQpOwoJCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmZvbnRMaXN0LCBmbCwgTlVMTCk7CgkJLyogV2Ugc2hvdWxkIGZvcmNlIHRoZSB3aWRnZXQgdG8gcmVjYWxjdWxhdGUgaXQncwoJCSAqIGdlb21ldHJ5IG5vdy4gKi8KCQlYdE1hbmFnZUNoaWxkKGlkKTsKCSAgICB9CgkgICAgZWxzZQoJCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmZvbnRMaXN0LCBmbCwgTlVMTCk7CgkgICAgWG1Gb250TGlzdEZyZWUoZmwpOwoJfQogICAgfQojZW5kaWYKI2VuZGlmCn0KCgovKgogKiBXZSBkb24ndCBjcmVhdGUgaXQgdHdpY2UgZm9yIHRoZSBzYWtlIG9mIHNwZWVkLgogKi8KCnR5cGVkZWYgc3RydWN0IF9TaGFyZWRGaW5kUmVwbGFjZQp7CiAgICBXaWRnZXQgZGlhbG9nOwkvKiB0aGUgbWFpbiBkaWFsb2cgd2lkZ2V0ICovCiAgICBXaWRnZXQgd3dvcmQ7CS8qICdFeGFjdCBtYXRjaCcgY2hlY2sgYnV0dG9uICovCiAgICBXaWRnZXQgbWNhc2U7CS8qICdtYXRjaCBjYXNlJyBjaGVjayBidXR0b24gKi8KICAgIFdpZGdldCB1cDsJCS8qIHNlYXJjaCBkaXJlY3Rpb24gJ1VwJyByYWRpbyBidXR0b24gKi8KICAgIFdpZGdldCBkb3duOwkvKiBzZWFyY2ggZGlyZWN0aW9uICdEb3duJyByYWRpbyBidXR0b24gKi8KICAgIFdpZGdldCB3aGF0OwkvKiAnRmluZCB3aGF0JyBlbnRyeSB0ZXh0IHdpZGdldCAqLwogICAgV2lkZ2V0IHdpdGg7CS8qICdSZXBsYWNlIHdpdGgnIGVudHJ5IHRleHQgd2lkZ2V0ICovCiAgICBXaWRnZXQgZmluZDsJLyogJ0ZpbmQgTmV4dCcgYWN0aW9uIGJ1dHRvbiAqLwogICAgV2lkZ2V0IHJlcGxhY2U7CS8qICdSZXBsYWNlIFdpdGgnIGFjdGlvbiBidXR0b24gKi8KICAgIFdpZGdldCBhbGw7CQkvKiAnUmVwbGFjZSBBbGwnIGFjdGlvbiBidXR0b24gKi8KICAgIFdpZGdldCB1bmRvOwkvKiAnVW5kbycgYWN0aW9uIGJ1dHRvbiAqLwoKICAgIFdpZGdldCBjYW5jZWw7Cn0gU2hhcmVkRmluZFJlcGxhY2U7CgpzdGF0aWMgU2hhcmVkRmluZFJlcGxhY2UgZmluZF93aWRnZXRzID0geyBOVUxMIH07CnN0YXRpYyBTaGFyZWRGaW5kUmVwbGFjZSByZXBsX3dpZGdldHMgPSB7IE5VTEwgfTsKCnN0YXRpYyB2b2lkIGZpbmRfcmVwbGFjZV9kZXN0cm95X2NhbGxiYWNrIF9fQVJHUygoV2lkZ2V0IHcsIFh0UG9pbnRlciBjbGllbnRfZGF0YSwgWHRQb2ludGVyIGNhbGxfZGF0YSkpOwpzdGF0aWMgdm9pZCBmaW5kX3JlcGxhY2VfZGlzbWlzc19jYWxsYmFjayBfX0FSR1MoKFdpZGdldCB3LCBYdFBvaW50ZXIgY2xpZW50X2RhdGEsIFh0UG9pbnRlciBjYWxsX2RhdGEpKTsKc3RhdGljIHZvaWQgZW50cnlfYWN0aXZhdGVfY2FsbGJhY2sgX19BUkdTKChXaWRnZXQgdywgWHRQb2ludGVyIGNsaWVudF9kYXRhLCBYdFBvaW50ZXIgY2FsbF9kYXRhKSk7CnN0YXRpYyB2b2lkIGZpbmRfcmVwbGFjZV9jYWxsYmFjayBfX0FSR1MoKFdpZGdldCB3LCBYdFBvaW50ZXIgY2xpZW50X2RhdGEsIFh0UG9pbnRlciBjYWxsX2RhdGEpKTsKc3RhdGljIHZvaWQgZmluZF9yZXBsYWNlX2tleXByZXNzIF9fQVJHUygoV2lkZ2V0IHcsIFNoYXJlZEZpbmRSZXBsYWNlICogZnJkcCwgWEtleUV2ZW50ICogZXZlbnQpKTsKc3RhdGljIHZvaWQgZmluZF9yZXBsYWNlX2RpYWxvZ19jcmVhdGUgX19BUkdTKChjaGFyX3UgKmVudHJ5X3RleHQsIGludCBkb19yZXBsYWNlKSk7CgovKkFSR1NVU0VEKi8KICAgIHN0YXRpYyB2b2lkCmZpbmRfcmVwbGFjZV9kZXN0cm95X2NhbGxiYWNrKHcsIGNsaWVudF9kYXRhLCBjYWxsX2RhdGEpCiAgICBXaWRnZXQJdzsKICAgIFh0UG9pbnRlcgljbGllbnRfZGF0YTsKICAgIFh0UG9pbnRlcgljYWxsX2RhdGE7CnsKICAgIFNoYXJlZEZpbmRSZXBsYWNlICpjZCA9IChTaGFyZWRGaW5kUmVwbGFjZSAqKWNsaWVudF9kYXRhOwoKICAgIGlmIChjZCAhPSBOVUxMKQogICAgICAgLyogc3VwcHJlc3NfZGlhbG9nX21uZW1vbmljcyhjZC0+ZGlhbG9nKTsgKi8KCWNkLT5kaWFsb2cgPSAoV2lkZ2V0KTA7Cn0KCi8qQVJHU1VTRUQqLwogICAgc3RhdGljIHZvaWQKZmluZF9yZXBsYWNlX2Rpc21pc3NfY2FsbGJhY2sodywgY2xpZW50X2RhdGEsIGNhbGxfZGF0YSkKICAgIFdpZGdldAl3OwogICAgWHRQb2ludGVyCWNsaWVudF9kYXRhOwogICAgWHRQb2ludGVyCWNhbGxfZGF0YTsKewogICAgU2hhcmVkRmluZFJlcGxhY2UgKmNkID0gKFNoYXJlZEZpbmRSZXBsYWNlICopY2xpZW50X2RhdGE7CgogICAgaWYgKGNkICE9IE5VTEwpCglYdFVubWFuYWdlQ2hpbGQoY2QtPmRpYWxvZyk7Cn0KCi8qQVJHU1VTRUQqLwogICAgc3RhdGljIHZvaWQKZW50cnlfYWN0aXZhdGVfY2FsbGJhY2sodywgY2xpZW50X2RhdGEsIGNhbGxfZGF0YSkKICAgIFdpZGdldAl3OwogICAgWHRQb2ludGVyCWNsaWVudF9kYXRhOwogICAgWHRQb2ludGVyCWNhbGxfZGF0YTsKewogICAgWG1Qcm9jZXNzVHJhdmVyc2FsKChXaWRnZXQpY2xpZW50X2RhdGEsIFhtVFJBVkVSU0VfQ1VSUkVOVCk7Cn0KCi8qQVJHU1VTRUQqLwogICAgc3RhdGljIHZvaWQKZmluZF9yZXBsYWNlX2NhbGxiYWNrKHcsIGNsaWVudF9kYXRhLCBjYWxsX2RhdGEpCiAgICBXaWRnZXQJdzsKICAgIFh0UG9pbnRlcgljbGllbnRfZGF0YTsKICAgIFh0UG9pbnRlcgljYWxsX2RhdGE7CnsKICAgIGxvbmdfdQlmbGFncyA9IChsb25nX3UpY2xpZW50X2RhdGE7CiAgICBjaGFyCSpmaW5kX3RleHQsICpyZXBsX3RleHQ7CiAgICBCb29sZWFuCWRpcmVjdGlvbl9kb3duID0gVFJVRTsKICAgIEJvb2xlYW4Jd3dvcmQ7CiAgICBCb29sZWFuCW1jYXNlOwogICAgU2hhcmVkRmluZFJlcGxhY2UgKnNmcjsKCiAgICBpZiAoZmxhZ3MgPT0gRlJEX1VORE8pCiAgICB7CgljaGFyX3UJKnNhdmVfY3BvID0gcF9jcG87CgoJLyogTm8gbmVlZCB0byBiZSBWaSBjb21wYXRpYmxlIGhlcmUuICovCglwX2NwbyA9IChjaGFyX3UgKikiIjsKCXVfdW5kbygxKTsKCXBfY3BvID0gc2F2ZV9jcG87CglndWlfdXBkYXRlX3NjcmVlbigpOwoJcmV0dXJuOwogICAgfQoKICAgIC8qIEdldCB0aGUgc2VhcmNoL3JlcGxhY2Ugc3RyaW5ncyBmcm9tIHRoZSBkaWFsb2cgKi8KICAgIGlmIChmbGFncyA9PSBGUkRfRklORE5FWFQpCiAgICB7CglyZXBsX3RleHQgPSBOVUxMOwoJc2ZyID0gJmZpbmRfd2lkZ2V0czsKICAgIH0KICAgIGVsc2UKICAgIHsKCXJlcGxfdGV4dCA9IFhtVGV4dEZpZWxkR2V0U3RyaW5nKHJlcGxfd2lkZ2V0cy53aXRoKTsKCXNmciA9ICZyZXBsX3dpZGdldHM7CiAgICB9CiAgICBmaW5kX3RleHQgPSBYbVRleHRGaWVsZEdldFN0cmluZyhzZnItPndoYXQpOwogICAgWHRWYUdldFZhbHVlcyhzZnItPmRvd24sIFhtTnNldCwgJmRpcmVjdGlvbl9kb3duLCBOVUxMKTsKICAgIFh0VmFHZXRWYWx1ZXMoc2ZyLT53d29yZCwgWG1Oc2V0LCAmd3dvcmQsIE5VTEwpOwogICAgWHRWYUdldFZhbHVlcyhzZnItPm1jYXNlLCBYbU5zZXQsICZtY2FzZSwgTlVMTCk7CiAgICBpZiAod3dvcmQpCglmbGFncyB8PSBGUkRfV0hPTEVfV09SRDsKICAgIGlmIChtY2FzZSkKCWZsYWdzIHw9IEZSRF9NQVRDSF9DQVNFOwoKICAgICh2b2lkKWd1aV9kb19maW5kcmVwbCgoaW50KWZsYWdzLCAoY2hhcl91ICopZmluZF90ZXh0LCAoY2hhcl91ICopcmVwbF90ZXh0LAoJCQkJCQkJICAgICAgZGlyZWN0aW9uX2Rvd24pOwoKICAgIGlmIChmaW5kX3RleHQgIT0gTlVMTCkKCVh0RnJlZShmaW5kX3RleHQpOwogICAgaWYgKHJlcGxfdGV4dCAhPSBOVUxMKQoJWHRGcmVlKHJlcGxfdGV4dCk7Cn0KCi8qQVJHU1VTRUQqLwogICAgc3RhdGljIHZvaWQKZmluZF9yZXBsYWNlX2tleXByZXNzKHcsIGZyZHAsIGV2ZW50KQogICAgV2lkZ2V0CQl3OwogICAgU2hhcmVkRmluZFJlcGxhY2UJKmZyZHA7CiAgICBYS2V5RXZlbnQJCSpldmVudDsKewogICAgS2V5U3ltIGtleXN5bTsKCiAgICBpZiAoZnJkcCA9PSBOVUxMKQoJcmV0dXJuOwoKICAgIGtleXN5bSA9IFhMb29rdXBLZXlzeW0oZXZlbnQsIDApOwoKICAgIC8qIHRoZSBzY2FwZSBrZXkgcG9wcyB0aGUgd2hvbGUgZGlhbG9nIGRvd24gKi8KICAgIGlmIChrZXlzeW0gPT0gWEtfRXNjYXBlKQoJWHRVbm1hbmFnZUNoaWxkKGZyZHAtPmRpYWxvZyk7Cn0KCiAgICBzdGF0aWMgdm9pZApzZXRfbGFiZWwodywgbGFiZWwpCiAgICBXaWRnZXQgdzsKICAgIGNoYXJfdSAqbGFiZWw7CnsKICAgIFhtU3RyaW5nCXN0cjsKICAgIGNoYXJfdQkqcCwgKm5leHQ7CiAgICBLZXlTeW0JbW5lbW9uaWMgPSBOVUw7CgogICAgaWYgKCF3KQoJcmV0dXJuOwoKICAgIHAgPSB2aW1fc3Ryc2F2ZShsYWJlbCk7CiAgICBpZiAocCA9PSBOVUxMKQoJcmV0dXJuOwogICAgZm9yIChuZXh0ID0gcDsgKm5leHQ7ICsrbmV4dCkKICAgIHsKCWlmICgqbmV4dCA9PSBETEdfSE9US0VZX0NIQVIpCgl7CgkgICAgaW50IGxlbiA9IFNUUkxFTihuZXh0KTsKCgkgICAgaWYgKGxlbiA+IDApCgkgICAgewoJCW1jaF9tZW1tb3ZlKG5leHQsIG5leHQgKyAxLCBsZW4pOwoJCW1uZW1vbmljID0gbmV4dFswXTsKCSAgICB9Cgl9CiAgICB9CgogICAgc3RyID0gWG1TdHJpbmdDcmVhdGVTaW1wbGUoKGNoYXIgKilwKTsKICAgIHZpbV9mcmVlKHApOwogICAgaWYgKHN0cikKICAgIHsKCVh0VmFTZXRWYWx1ZXModywKCQlYbU5sYWJlbFN0cmluZywgc3RyLAoJCVhtTm1uZW1vbmljLCBtbmVtb25pYywKCQlOVUxMKTsKCVhtU3RyaW5nRnJlZShzdHIpOwogICAgfQogICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3Qodyk7Cn0KCiAgICBzdGF0aWMgdm9pZApmaW5kX3JlcGxhY2VfZGlhbG9nX2NyZWF0ZShhcmcsIGRvX3JlcGxhY2UpCiAgICBjaGFyX3UJKmFyZzsKICAgIGludAkJZG9fcmVwbGFjZTsKewogICAgU2hhcmVkRmluZFJlcGxhY2UJKmZyZHA7CiAgICBXaWRnZXQJCXNlcGFyYXRvcjsKICAgIFdpZGdldAkJaW5wdXRfZm9ybTsKICAgIFdpZGdldAkJYnV0dG9uX2Zvcm07CiAgICBXaWRnZXQJCXRvZ2dsZV9mb3JtOwogICAgV2lkZ2V0CQlmcmFtZTsKICAgIFhtU3RyaW5nCQlzdHI7CiAgICBpbnQJCQluOwogICAgQXJnCQkJYXJnc1s2XTsKICAgIGludAkJCXd3b3JkID0gRkFMU0U7CiAgICBpbnQJCQltY2FzZSA9ICFwX2ljOwogICAgRGltZW5zaW9uCQl3aWR0aDsKICAgIERpbWVuc2lvbgkJd2lkZXN0OwogICAgY2hhcl91CQkqZW50cnlfdGV4dDsKCiAgICBmcmRwID0gZG9fcmVwbGFjZSA/ICZyZXBsX3dpZGdldHMgOiAmZmluZF93aWRnZXRzOwoKICAgIC8qIEdldCB0aGUgc2VhcmNoIHN0cmluZyB0byB1c2UuICovCiAgICBlbnRyeV90ZXh0ID0gZ2V0X2ZpbmRfZGlhbG9nX3RleHQoYXJnLCAmd3dvcmQsICZtY2FzZSk7CgogICAgLyogSWYgdGhlIGRpYWxvZyBhbHJlYWR5IGV4aXN0cywganVzdCByYWlzZSBpdC4gKi8KICAgIGlmIChmcmRwLT5kaWFsb2cpCiAgICB7CglndWlfbW90aWZfc3luY2hfZm9udHMoKTsKCgkvKiBJZiB0aGUgd2luZG93IGlzIGFscmVhZHkgdXAsIGp1c3QgcG9wIGl0IHRvIHRoZSB0b3AgKi8KCWlmIChYdElzTWFuYWdlZChmcmRwLT5kaWFsb2cpKQoJICAgIFhNYXBSYWlzZWQoWHREaXNwbGF5KGZyZHAtPmRpYWxvZyksCgkJCQkJICAgIFh0V2luZG93KFh0UGFyZW50KGZyZHAtPmRpYWxvZykpKTsKCWVsc2UKCSAgICBYdE1hbmFnZUNoaWxkKGZyZHAtPmRpYWxvZyk7CglYdFBvcHVwKFh0UGFyZW50KGZyZHAtPmRpYWxvZyksIFh0R3JhYk5vbmUpOwoJWG1Qcm9jZXNzVHJhdmVyc2FsKGZyZHAtPndoYXQsIFhtVFJBVkVSU0VfQ1VSUkVOVCk7CgoJaWYgKGVudHJ5X3RleHQgIT0gTlVMTCkKCSAgICBYbVRleHRGaWVsZFNldFN0cmluZyhmcmRwLT53aGF0LCAoY2hhciAqKWVudHJ5X3RleHQpOwoJdmltX2ZyZWUoZW50cnlfdGV4dCk7CgoJWHRWYVNldFZhbHVlcyhmcmRwLT53d29yZCwgWG1Oc2V0LCB3d29yZCwgTlVMTCk7CglyZXR1cm47CiAgICB9CgogICAgLyogQ3JlYXRlIGEgZnJlc2ggbmV3IGRpYWxvZyB3aW5kb3cgKi8KICAgIGlmIChkb19yZXBsYWNlKQoJIHN0ciA9IFhtU3RyaW5nQ3JlYXRlU2ltcGxlKF8oIlZJTSAtIFNlYXJjaCBhbmQgUmVwbGFjZS4uLiIpKTsKICAgIGVsc2UKCSBzdHIgPSBYbVN0cmluZ0NyZWF0ZVNpbXBsZShfKCJWSU0gLSBTZWFyY2guLi4iKSk7CgogICAgbiA9IDA7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5hdXRvVW5tYW5hZ2UsIEZhbHNlKTsgbisrOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1Obm9SZXNpemUsIFRydWUpOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5kaWFsb2dUaXRsZSwgc3RyKTsgbisrOwoKICAgIGZyZHAtPmRpYWxvZyA9IFhtQ3JlYXRlRm9ybURpYWxvZyh2aW1TaGVsbCwgImZpbmRSZXBsYWNlRGlhbG9nIiwgYXJncywgbik7CiAgICBYbVN0cmluZ0ZyZWUoc3RyKTsKICAgIFh0QWRkQ2FsbGJhY2soZnJkcC0+ZGlhbG9nLCBYbU5kZXN0cm95Q2FsbGJhY2ssCgkgICAgZmluZF9yZXBsYWNlX2Rlc3Ryb3lfY2FsbGJhY2ssIGZyZHApOwoKICAgIGJ1dHRvbl9mb3JtID0gWHRWYUNyZWF0ZVdpZGdldCgiYnV0dG9uRm9ybSIsCgkgICAgeG1Gb3JtV2lkZ2V0Q2xhc3MsCWZyZHAtPmRpYWxvZywKCSAgICBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1OcmlnaHRPZmZzZXQsIDQsCgkgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBYbU50b3BPZmZzZXQsIDQsCgkgICAgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBYbU5ib3R0b21PZmZzZXQsIDQsCgkgICAgTlVMTCk7CgogICAgZnJkcC0+ZmluZCA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJmaW5kQnV0dG9uIiwKCSAgICB4bVB1c2hCdXR0b25XaWRnZXRDbGFzcywgYnV0dG9uX2Zvcm0sCgkgICAgWG1Oc2Vuc2l0aXZlLCBUcnVlLAoJICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIE5VTEwpOwogICAgc2V0X2xhYmVsKGZyZHAtPmZpbmQsIF8oIkZpbmQgJk5leHQiKSk7CgogICAgWHRBZGRDYWxsYmFjayhmcmRwLT5maW5kLCBYbU5hY3RpdmF0ZUNhbGxiYWNrLAoJICAgIGZpbmRfcmVwbGFjZV9jYWxsYmFjaywKCSAgICAoWHRQb2ludGVyKSAoZG9fcmVwbGFjZSA/IEZSRF9SX0ZJTkRORVhUIDogRlJEX0ZJTkRORVhUKSk7CgogICAgaWYgKGRvX3JlcGxhY2UpCiAgICB7CglmcmRwLT5yZXBsYWNlID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoInJlcGxhY2VCdXR0b24iLAoJCXhtUHVzaEJ1dHRvbldpZGdldENsYXNzLCBidXR0b25fZm9ybSwKCQlYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJWG1OdG9wV2lkZ2V0LCBmcmRwLT5maW5kLAoJCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCVhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlOVUxMKTsKCXNldF9sYWJlbChmcmRwLT5yZXBsYWNlLCBfKCImUmVwbGFjZSIpKTsKCVh0QWRkQ2FsbGJhY2soZnJkcC0+cmVwbGFjZSwgWG1OYWN0aXZhdGVDYWxsYmFjaywKCQlmaW5kX3JlcGxhY2VfY2FsbGJhY2ssIChYdFBvaW50ZXIpRlJEX1JFUExBQ0UpOwoKCWZyZHAtPmFsbCA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJyZXBsYWNlQWxsQnV0dG9uIiwKCQl4bVB1c2hCdXR0b25XaWRnZXRDbGFzcywgYnV0dG9uX2Zvcm0sCgkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCVhtTnRvcFdpZGdldCwgZnJkcC0+cmVwbGFjZSwKCQlYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJTlVMTCk7CglzZXRfbGFiZWwoZnJkcC0+YWxsLCBfKCJSZXBsYWNlICZBbGwiKSk7CglYdEFkZENhbGxiYWNrKGZyZHAtPmFsbCwgWG1OYWN0aXZhdGVDYWxsYmFjaywKCQlmaW5kX3JlcGxhY2VfY2FsbGJhY2ssIChYdFBvaW50ZXIpRlJEX1JFUExBQ0VBTEwpOwoKCWZyZHAtPnVuZG8gPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgidW5kb0J1dHRvbiIsCgkJeG1QdXNoQnV0dG9uV2lkZ2V0Q2xhc3MsIGJ1dHRvbl9mb3JtLAoJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQlYbU50b3BXaWRnZXQsIGZyZHAtPmFsbCwKCQlYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJTlVMTCk7CglzZXRfbGFiZWwoZnJkcC0+dW5kbywgXygiJlVuZG8iKSk7CglYdEFkZENhbGxiYWNrKGZyZHAtPnVuZG8sIFhtTmFjdGl2YXRlQ2FsbGJhY2ssCgkJZmluZF9yZXBsYWNlX2NhbGxiYWNrLCAoWHRQb2ludGVyKUZSRF9VTkRPKTsKICAgIH0KCiAgICBmcmRwLT5jYW5jZWwgPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgiY2xvc2VCdXR0b24iLAoJICAgIHhtUHVzaEJ1dHRvbldpZGdldENsYXNzLCBidXR0b25fZm9ybSwKCSAgICBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBOVUxMKTsKICAgIHNldF9sYWJlbChmcmRwLT5jYW5jZWwsIF8oIiZDYW5jZWwiKSk7CiAgICBYdEFkZENhbGxiYWNrKGZyZHAtPmNhbmNlbCwgWG1OYWN0aXZhdGVDYWxsYmFjaywKCSAgICBmaW5kX3JlcGxhY2VfZGlzbWlzc19jYWxsYmFjaywgZnJkcCk7CiAgICBndWlfbW90aWZfbWVudV9mb250bGlzdChmcmRwLT5jYW5jZWwpOwoKICAgIFh0TWFuYWdlQ2hpbGQoYnV0dG9uX2Zvcm0pOwoKICAgIG4gPSAwOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1Ob3JpZW50YXRpb24sIFhtVkVSVElDQUwpOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnJpZ2h0V2lkZ2V0LCBidXR0b25fZm9ybSk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnJpZ2h0T2Zmc2V0LCA0KTsgbisrOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CiAgICBzZXBhcmF0b3IgPSBYbUNyZWF0ZVNlcGFyYXRvckdhZGdldChmcmRwLT5kaWFsb2csICJzZXBhcmF0b3IiLCBhcmdzLCBuKTsKICAgIFh0TWFuYWdlQ2hpbGQoc2VwYXJhdG9yKTsKCiAgICBpbnB1dF9mb3JtID0gWHRWYUNyZWF0ZVdpZGdldCgiaW5wdXRGb3JtIiwKCSAgICB4bUZvcm1XaWRnZXRDbGFzcywJZnJkcC0+ZGlhbG9nLAoJICAgIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTmxlZnRPZmZzZXQsIDQsCgkgICAgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkgICAgWG1OcmlnaHRXaWRnZXQsIHNlcGFyYXRvciwKCSAgICBYbU5yaWdodE9mZnNldCwgNCwKCSAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTnRvcE9mZnNldCwgNCwKCSAgICBOVUxMKTsKCiAgICB7CglXaWRnZXQgbGFiZWxfd2hhdDsKCVdpZGdldCBsYWJlbF93aXRoID0gKFdpZGdldCkwOwoKCXN0ciA9IFhtU3RyaW5nQ3JlYXRlU2ltcGxlKF8oIkZpbmQgd2hhdDoiKSk7CglsYWJlbF93aGF0ID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoIndoYXRMYWJlbCIsCgkJeG1MYWJlbEdhZGdldENsYXNzLCBpbnB1dF9mb3JtLAoJCVhtTmxhYmVsU3RyaW5nLCBzdHIsCgkJWG1ObGVmdEF0dGFjaG1lbnQsCVhtQVRUQUNIX0ZPUk0sCgkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlYbU50b3BPZmZzZXQsIDQsCgkJTlVMTCk7CglYbVN0cmluZ0ZyZWUoc3RyKTsKCWd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KGxhYmVsX3doYXQpOwoKCWZyZHAtPndoYXQgPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgid2hhdFRleHQiLAoJCXhtVGV4dEZpZWxkV2lkZ2V0Q2xhc3MsIGlucHV0X2Zvcm0sCgkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJTlVMTCk7CgoJaWYgKGRvX3JlcGxhY2UpCgl7CgkgICAgZnJkcC0+d2l0aCA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJ3aXRoVGV4dCIsCgkJICAgIHhtVGV4dEZpZWxkV2lkZ2V0Q2xhc3MsCWlucHV0X2Zvcm0sCgkJICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkgICAgWG1OdG9wV2lkZ2V0LCBmcmRwLT53aGF0LAoJCSAgICBYbU50b3BPZmZzZXQsIDQsCgkJICAgIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCSAgICBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJICAgIE5VTEwpOwoKCSAgICBYdEFkZENhbGxiYWNrKGZyZHAtPndpdGgsIFhtTmFjdGl2YXRlQ2FsbGJhY2ssCgkJICAgIGZpbmRfcmVwbGFjZV9jYWxsYmFjaywgKFh0UG9pbnRlcikgRlJEX1JfRklORE5FWFQpOwoKCSAgICBzdHIgPSBYbVN0cmluZ0NyZWF0ZVNpbXBsZShfKCJSZXBsYWNlIHdpdGg6IikpOwoJICAgIGxhYmVsX3dpdGggPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgid2l0aExhYmVsIiwKCQkgICAgeG1MYWJlbEdhZGdldENsYXNzLCBpbnB1dF9mb3JtLAoJCSAgICBYbU5sYWJlbFN0cmluZywgc3RyLAoJCSAgICBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCSAgICBYbU50b3BXaWRnZXQsIGZyZHAtPndoYXQsCgkJICAgIFhtTnRvcE9mZnNldCwgNCwKCQkgICAgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkgICAgTlVMTCk7CgkgICAgWG1TdHJpbmdGcmVlKHN0cik7CgkgICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3QobGFiZWxfd2l0aCk7CgoJICAgIC8qCgkgICAgICogTWFrZSB0aGUgZW50cnkgYWN0aXZhdGlvbiBvbmx5IGNoYW5nZSB0aGUgaW5wdXQgZm9jdXMgb250byB0aGUKCSAgICAgKiB3aXRoIGl0ZW0uCgkgICAgICovCgkgICAgWHRBZGRDYWxsYmFjayhmcmRwLT53aGF0LCBYbU5hY3RpdmF0ZUNhbGxiYWNrLAoJCSAgICBlbnRyeV9hY3RpdmF0ZV9jYWxsYmFjaywgZnJkcC0+d2l0aCk7CgkgICAgWHRBZGRFdmVudEhhbmRsZXIoZnJkcC0+d2l0aCwgS2V5UHJlc3NNYXNrLCBGYWxzZSwKCQkJICAgIChYdEV2ZW50SGFuZGxlcilmaW5kX3JlcGxhY2Vfa2V5cHJlc3MsCgkJCSAgICAoWHRQb2ludGVyKSBmcmRwKTsKCgl9CgllbHNlCgl7CgkgICAgLyoKCSAgICAgKiBNYWtlIHRoZSBlbnRyeSBhY3RpdmF0aW9uIGRvIHRoZSBzZWFyY2guCgkgICAgICovCgkgICAgWHRBZGRDYWxsYmFjayhmcmRwLT53aGF0LCBYbU5hY3RpdmF0ZUNhbGxiYWNrLAoJCSAgICBmaW5kX3JlcGxhY2VfY2FsbGJhY2ssIChYdFBvaW50ZXIpRlJEX0ZJTkRORVhUKTsKCX0KCVh0QWRkRXZlbnRIYW5kbGVyKGZyZHAtPndoYXQsIEtleVByZXNzTWFzaywgRmFsc2UsCgkJCSAgICAoWHRFdmVudEhhbmRsZXIpZmluZF9yZXBsYWNlX2tleXByZXNzLAoJCQkgICAgKFh0UG9pbnRlcilmcmRwKTsKCgkvKiBHZXQgdGhlIG1heGltdW0gd2lkdGggYmV0d2VlbiB0aGUgbGFiZWwgd2lkZ2V0cyBhbmQgbGluZSB0aGVtIHVwLgoJICovCgluID0gMDsKCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTndpZHRoLCAmd2lkdGgpOyBuKys7CglYdEdldFZhbHVlcyhsYWJlbF93aGF0LCBhcmdzLCBuKTsKCXdpZGVzdCA9IHdpZHRoOwoJaWYgKGRvX3JlcGxhY2UpCgl7CgkgICAgWHRHZXRWYWx1ZXMobGFiZWxfd2l0aCwgYXJncywgbik7CgkgICAgaWYgKHdpZHRoID4gd2lkZXN0KQoJCXdpZGVzdCA9IHdpZHRoOwoJfQoKCVh0VmFTZXRWYWx1ZXMoZnJkcC0+d2hhdCwgWG1ObGVmdE9mZnNldCwgd2lkZXN0LCBOVUxMKTsKCWlmIChkb19yZXBsYWNlKQoJICAgIFh0VmFTZXRWYWx1ZXMoZnJkcC0+d2l0aCwgWG1ObGVmdE9mZnNldCwgd2lkZXN0LCBOVUxMKTsKCiAgICB9CgogICAgWHRNYW5hZ2VDaGlsZChpbnB1dF9mb3JtKTsKCiAgICB7CglXaWRnZXQgcmFkaW9fYm94OwoJV2lkZ2V0IHc7CgoJZnJhbWUgPSBYdFZhQ3JlYXRlV2lkZ2V0KCJkaXJlY3Rpb25GcmFtZSIsCgkJeG1GcmFtZVdpZGdldENsYXNzLCBmcmRwLT5kaWFsb2csCgkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCVhtTnRvcFdpZGdldCwgaW5wdXRfZm9ybSwKCQlYbU50b3BPZmZzZXQsIDQsCgkJWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlYbU5ib3R0b21PZmZzZXQsIDQsCgkJWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9PUFBPU0lURV9XSURHRVQsCgkJWG1OcmlnaHRXaWRnZXQsIGlucHV0X2Zvcm0sCgkJTlVMTCk7CgoJc3RyID0gWG1TdHJpbmdDcmVhdGVTaW1wbGUoXygiRGlyZWN0aW9uIikpOwoJdyA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJkaXJlY3Rpb25GcmFtZUxhYmVsIiwKCQl4bUxhYmVsR2FkZ2V0Q2xhc3MsIGZyYW1lLAoJCVhtTmxhYmVsU3RyaW5nLCBzdHIsCgkJWG1OY2hpbGRIb3Jpem9udGFsQWxpZ25tZW50LCBYbUFMSUdOTUVOVF9CRUdJTk5JTkcsCgkJWG1OY2hpbGRUeXBlLCBYbUZSQU1FX1RJVExFX0NISUxELAoJCU5VTEwpOwoJWG1TdHJpbmdGcmVlKHN0cik7CglndWlfbW90aWZfbWVudV9mb250bGlzdCh3KTsKCglyYWRpb19ib3ggPSBYbUNyZWF0ZVJhZGlvQm94KGZyYW1lLCAicmFkaW9Cb3giLAoJCShBcmdMaXN0KU5VTEwsIDApOwoKCXN0ciA9IFhtU3RyaW5nQ3JlYXRlU2ltcGxlKCBfKCJVcCIpKTsKCWZyZHAtPnVwID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoInVwUmFkaW9CdXR0b24iLAoJCXhtVG9nZ2xlQnV0dG9uR2FkZ2V0Q2xhc3MsIHJhZGlvX2JveCwKCQlYbU5sYWJlbFN0cmluZywgc3RyLAoJCVhtTnNldCwgRmFsc2UsCgkJTlVMTCk7CglYbVN0cmluZ0ZyZWUoc3RyKTsKCWd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KGZyZHAtPnVwKTsKCglzdHIgPSBYbVN0cmluZ0NyZWF0ZVNpbXBsZShfKCJEb3duIikpOwoJZnJkcC0+ZG93biA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJkb3duUmFkaW9CdXR0b24iLAoJCXhtVG9nZ2xlQnV0dG9uR2FkZ2V0Q2xhc3MsIHJhZGlvX2JveCwKCQlYbU5sYWJlbFN0cmluZywgc3RyLAoJCVhtTnNldCwgVHJ1ZSwKCQlOVUxMKTsKCVhtU3RyaW5nRnJlZShzdHIpOwoJZ3VpX21vdGlmX21lbnVfZm9udGxpc3QoZnJkcC0+ZG93bik7CgoJWHRNYW5hZ2VDaGlsZChyYWRpb19ib3gpOwoJWHRNYW5hZ2VDaGlsZChmcmFtZSk7CiAgICB9CgogICAgdG9nZ2xlX2Zvcm0gPSBYdFZhQ3JlYXRlV2lkZ2V0KCJ0b2dnbGVGb3JtIiwKCSAgICB4bUZvcm1XaWRnZXRDbGFzcywJZnJkcC0+ZGlhbG9nLAoJICAgIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTmxlZnRPZmZzZXQsIDQsCgkgICAgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkgICAgWG1OcmlnaHRXaWRnZXQsIGZyYW1lLAoJICAgIFhtTnJpZ2h0T2Zmc2V0LCA0LAoJICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCSAgICBYbU50b3BXaWRnZXQsIGlucHV0X2Zvcm0sCgkgICAgWG1OdG9wT2Zmc2V0LCA0LAoJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1OYm90dG9tT2Zmc2V0LCA0LAoJICAgIE5VTEwpOwoKICAgIHN0ciA9IFhtU3RyaW5nQ3JlYXRlU2ltcGxlKF8oIk1hdGNoIHdob2xlIHdvcmQgb25seSIpKTsKICAgIGZyZHAtPnd3b3JkID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoIndvcmRUb2dnbGUiLAoJICAgIHhtVG9nZ2xlQnV0dG9uR2FkZ2V0Q2xhc3MsIHRvZ2dsZV9mb3JtLAoJICAgIFhtTmxhYmVsU3RyaW5nLCBzdHIsCgkgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBYbU50b3BPZmZzZXQsIDQsCgkgICAgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1ObGVmdE9mZnNldCwgNCwKCSAgICBYbU5zZXQsIHd3b3JkLAoJICAgIE5VTEwpOwogICAgWG1TdHJpbmdGcmVlKHN0cik7CgogICAgc3RyID0gWG1TdHJpbmdDcmVhdGVTaW1wbGUoXygiTWF0Y2ggY2FzZSIpKTsKICAgIGZyZHAtPm1jYXNlID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoImNhc2VUb2dnbGUiLAoJICAgIHhtVG9nZ2xlQnV0dG9uR2FkZ2V0Q2xhc3MsIHRvZ2dsZV9mb3JtLAoJICAgIFhtTmxhYmVsU3RyaW5nLCBzdHIsCgkgICAgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1ObGVmdE9mZnNldCwgNCwKCSAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkgICAgWG1OdG9wV2lkZ2V0LCBmcmRwLT53d29yZCwKCSAgICBYbU50b3BPZmZzZXQsIDQsCgkgICAgWG1Oc2V0LCBtY2FzZSwKCSAgICBOVUxMKTsKICAgIFhtU3RyaW5nRnJlZShzdHIpOwogICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3QoZnJkcC0+d3dvcmQpOwogICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3QoZnJkcC0+bWNhc2UpOwoKICAgIFh0TWFuYWdlQ2hpbGQodG9nZ2xlX2Zvcm0pOwoKICAgIGlmIChlbnRyeV90ZXh0ICE9IE5VTEwpCglYbVRleHRGaWVsZFNldFN0cmluZyhmcmRwLT53aGF0LCAoY2hhciAqKWVudHJ5X3RleHQpOwogICAgdmltX2ZyZWUoZW50cnlfdGV4dCk7CgogICAgZ3VpX21vdGlmX3N5bmNoX2ZvbnRzKCk7CgogICAgbWFuYWdlX2NlbnRlcmVkKGZyZHAtPmRpYWxvZyk7CiAgICBhY3RpdmF0ZV9kaWFsb2dfbW5lbW9uaWNzKGZyZHAtPmRpYWxvZyk7CiAgICBYbVByb2Nlc3NUcmF2ZXJzYWwoZnJkcC0+d2hhdCwgWG1UUkFWRVJTRV9DVVJSRU5UKTsKfQoKICAgdm9pZApndWlfbWNoX2ZpbmRfZGlhbG9nKGVhcCkKICAgIGV4YXJnX1QJKmVhcDsKewogICAgaWYgKCFndWkuaW5fdXNlKQoJcmV0dXJuOwoKICAgIGZpbmRfcmVwbGFjZV9kaWFsb2dfY3JlYXRlKGVhcC0+YXJnLCBGQUxTRSk7Cn0KCgogICAgdm9pZApndWlfbWNoX3JlcGxhY2VfZGlhbG9nKGVhcCkKICAgIGV4YXJnX1QJKmVhcDsKewogICAgaWYgKCFndWkuaW5fdXNlKQoJcmV0dXJuOwoKICAgIGZpbmRfcmVwbGFjZV9kaWFsb2dfY3JlYXRlKGVhcC0+YXJnLCBUUlVFKTsKfQoKLyoKICogU3luY2hyb25pemUgYWxsIGd1aSBlbGVtZW50cywgd2hpY2ggYXJlIGRlcGVuZGFudCB1cG9uIHRoZQogKiBtYWluIHRleHQgZm9udCB1c2VkLiBUaG9zZSBhcmUgaW4gZXNwLiB0aGUgZmluZC9yZXBsYWNlIGRpYWxvZ3MuCiAqIElmIHlvdSBkb24ndCB1bmRlcnN0YW5kIHdoeSB0aGlzIHNob3VsZCBiZSBuZWVkZWQsIHBsZWFzZSB0cnkgdG8KICogc2VhcmNoIGZvciAicGnqtuYiIGluIGlzbzg4NTktMi4KICovCiAgICB2b2lkCmd1aV9tb3RpZl9zeW5jaF9mb250cyh2b2lkKQp7CiAgICBTaGFyZWRGaW5kUmVwbGFjZSAqZnJkcDsKICAgIGludAkJICAgIGRvX3JlcGxhY2U7CiAgICBYRm9udFN0cnVjdAkgICAgKmZvbnQ7CiAgICBYbUZvbnRMaXN0CSAgICBmb250X2xpc3Q7CgogICAgLyogRklYTUU6IFVubGVzcyB3ZSBmaW5kIG91dCBob3cgdG8gY3JlYXRlIGEgWG1Gb250TGlzdCBmcm9tIGEgWEZvbnRTZXQsCiAgICAgKiB3ZSBqdXN0IGdpdmUgdXAgaGVyZSBvbiBmb250IHN5bmNocm9uaXphdGlvbi4gKi8KICAgIGZvbnQgPSAoWEZvbnRTdHJ1Y3QgKilndWkubm9ybV9mb250OwogICAgaWYgKGZvbnQgPT0gTlVMTCkKCXJldHVybjsKCiAgICBmb250X2xpc3QgPSBndWlfbW90aWZfY3JlYXRlX2ZvbnRsaXN0KGZvbnQpOwoKICAgIC8qIE9LIHRoaXMgbG9vcCBpcyBhIGJpdCB0cmlja3kuLi4gKi8KICAgIGZvciAoZG9fcmVwbGFjZSA9IDA7IGRvX3JlcGxhY2UgPD0gMTsgKytkb19yZXBsYWNlKQogICAgewoJZnJkcCA9IChkb19yZXBsYWNlKSA/ICgmcmVwbF93aWRnZXRzKSA6ICgmZmluZF93aWRnZXRzKTsKCWlmIChmcmRwLT5kaWFsb2cpCgl7CgkgICAgWHRWYVNldFZhbHVlcyhmcmRwLT53aGF0LCBYbU5mb250TGlzdCwgZm9udF9saXN0LCBOVUxMKTsKCSAgICBpZiAoZG9fcmVwbGFjZSkKCQlYdFZhU2V0VmFsdWVzKGZyZHAtPndpdGgsIFhtTmZvbnRMaXN0LCBmb250X2xpc3QsIE5VTEwpOwoJfQogICAgfQoKICAgIFhtRm9udExpc3RGcmVlKGZvbnRfbGlzdCk7Cn0K