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+aWQpOwp9CgoKLyoKICogQWRkIG1uZW1vbmljIGFuZCBhY2NlbGVyYXRvciB0ZXh0IHRvIGEgbWVudSBidXR0b24uCiAqLwogICAgc3RhdGljIHZvaWQKZ3VpX21vdGlmX2FkZF9hY3RleHQobWVudSkKICAgIHZpbW1lbnVfVAkqbWVudTsKewogICAgWG1TdHJpbmcJbGFiZWw7CgogICAgLyogQWRkIGFjY2VscmF0b3IgdGV4dCwgaWYgdGhlcmUgaXMgb25lICovCiAgICBpZiAobWVudS0+YWN0ZXh0ICE9IE5VTEwgJiYgbWVudS0+aWQgIT0gKFdpZGdldCkwKQogICAgewoJbGFiZWwgPSBYbVN0cmluZ0NyZWF0ZSgoY2hhciAqKW1lbnUtPmFjdGV4dCwgU1RSSU5HX1RBRyk7CglpZiAobGFiZWwgPT0gTlVMTCkKCSAgICByZXR1cm47CglYdFZhU2V0VmFsdWVzKG1lbnUtPmlkLCBYbU5hY2NlbGVyYXRvclRleHQsIGxhYmVsLCBOVUxMKTsKCVhtU3RyaW5nRnJlZShsYWJlbCk7CiAgICB9Cn0KCiAgICB2b2lkCmd1aV9tY2hfdG9nZ2xlX3RlYXJvZmZzKGVuYWJsZSkKICAgIGludAkJZW5hYmxlOwp7CiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCiAgICBpZiAoZW5hYmxlKQoJdGVhcm9mZl92YWwgPSAoaW50KVhtVEVBUl9PRkZfRU5BQkxFRDsKICAgIGVsc2UKCXRlYXJvZmZfdmFsID0gKGludClYbVRFQVJfT0ZGX0RJU0FCTEVEOwogICAgdG9nZ2xlX3RlYXJvZmYobWVudUJhcik7CiAgICBndWlfbWNoX3JlY3Vyc2VfdGVhcm9mZnMocm9vdF9tZW51KTsKI2VuZGlmCn0KCiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCi8qCiAqIFNldCB0aGUgdGVhcm9mZiBmb3Igb25lIG1lbnUgd2lkZ2V0IG9uIG9yIG9mZiwgYW5kIHNldCB0aGUgY29sb3Igb2YgdGhlCiAqIHRlYXJvZmYgd2lkZ2V0LgogKi8KICAgIHN0YXRpYyB2b2lkCnRvZ2dsZV90ZWFyb2ZmKHdpZCkKICAgIFdpZGdldAl3aWQ7CnsKICAgIFdpZGdldAl3OwoKICAgIFh0VmFTZXRWYWx1ZXMod2lkLCBYbU50ZWFyT2ZmTW9kZWwsIHRlYXJvZmZfdmFsLCBOVUxMKTsKICAgIGlmICh0ZWFyb2ZmX3ZhbCA9PSAoaW50KVhtVEVBUl9PRkZfRU5BQkxFRAoJICAgICYmICh3ID0gWG1HZXRUZWFyT2ZmQ29udHJvbCh3aWQpKSAhPSAoV2lkZ2V0KTApCglndWlfbW90aWZfbWVudV9jb2xvcnModyk7Cn0KCiAgICBzdGF0aWMgdm9pZApndWlfbWNoX3JlY3Vyc2VfdGVhcm9mZnMobWVudSkKICAgIHZpbW1lbnVfVAkqbWVudTsKewogICAgd2hpbGUgKG1lbnUgIT0gTlVMTCkKICAgIHsKCWlmICghbWVudV9pc19wb3B1cChtZW51LT5uYW1lKSkKCXsKCSAgICBpZiAobWVudS0+c3VibWVudV9pZCAhPSAoV2lkZ2V0KTApCgkJdG9nZ2xlX3RlYXJvZmYobWVudS0+c3VibWVudV9pZCk7CgkgICAgZ3VpX21jaF9yZWN1cnNlX3RlYXJvZmZzKG1lbnUtPmNoaWxkcmVuKTsKCX0KCW1lbnUgPSBtZW51LT5uZXh0OwogICAgfQp9CiNlbmRpZgoKICAgIGludApndWlfbWNoX3RleHRfYXJlYV9leHRyYV9oZWlnaHQoKQp7CiAgICBEaW1lbnNpb24Jc2hhZG93SGVpZ2h0OwoKICAgIFh0VmFHZXRWYWx1ZXModGV4dEFyZWFGb3JtLCBYbU5zaGFkb3dUaGlja25lc3MsICZzaGFkb3dIZWlnaHQsIE5VTEwpOwogICAgcmV0dXJuIHNoYWRvd0hlaWdodDsKfQoKLyoKICogQ29tcHV0ZSB0aGUgaGVpZ2h0IG9mIHRoZSBtZW51IGJhci4KICogV2UgbmVlZCB0byBjaGVjayBhbGwgdGhlIGl0ZW1zIGZvciB0aGVpciBwb3NpdGlvbiBhbmQgaGVpZ2h0LCBmb3IgdGhlIGNhc2UKICogdGhlcmUgYXJlIHNldmVyYWwgcm93cywgYW5kL29yIHNvbWUgY2hhcmFjdGVycyBleHRlbmQgaGlnaGVyIG9yIGxvd2VyLgogKi8KICAgIHZvaWQKZ3VpX21jaF9jb21wdXRlX21lbnVfaGVpZ2h0KGlkKQogICAgV2lkZ2V0CWlkOwkJICAgIC8qIGNhbiBiZSBOVUxMIHdoZW4gZGVsZXRpbmcgbWVudSAqLwp7CiAgICBEaW1lbnNpb24JeSwgbWF4eTsKICAgIERpbWVuc2lvbgltYXJnaW4sIHNoYWRvdzsKICAgIHZpbW1lbnVfVAkqbXA7CiAgICBzdGF0aWMgRGltZW5zaW9uCWhlaWdodCA9IDIxOwkvKiBub3JtYWwgaGVpZ2h0IG9mIGEgbWVudSBpdGVtICovCgogICAgLyoKICAgICAqIEdldCB0aGUgaGVpZ2h0IG9mIHRoZSBuZXcgaXRlbSwgYmVmb3JlIG1hbmFnaW5nIGl0LCBiZWNhdXNlIGl0IHdpbGwKICAgICAqIHN0aWxsIHJlZmxlY3QgdGhlIGZvbnQgc2l6ZS4gIEFmdGVyIG1hbmFnaW5nIGl0IGRlcGVuZHMgb24gdGhlIG1lbnUKICAgICAqIGhlaWdodCwgd2hpY2ggaXMgd2hhdCB3ZSBqdXN0IHdhbnRlZCB0byBnZXQhLgogICAgICovCiAgICBpZiAoaWQgIT0gKFdpZGdldCkwKQoJWHRWYUdldFZhbHVlcyhpZCwgWG1OaGVpZ2h0LCAmaGVpZ2h0LCBOVUxMKTsKCiAgICAvKiBGaW5kIGFueSBtZW51IFdpZGdldCwgdG8gYmUgYWJsZSB0byBjYWxsIFh0TWFuYWdlQ2hpbGQoKSAqLwogICAgZWxzZQoJZm9yIChtcCA9IHJvb3RfbWVudTsgbXAgIT0gTlVMTDsgbXAgPSBtcC0+bmV4dCkKCSAgICBpZiAobXAtPmlkICE9IChXaWRnZXQpMCAmJiBtZW51X2lzX21lbnViYXIobXAtPm5hbWUpKQoJICAgIHsKCQlpZCA9IG1wLT5pZDsKCQlicmVhazsKCSAgICB9CgogICAgLyoKICAgICAqIE5vdyBtYW5hZ2UgdGhlIG1lbnUgaXRlbSwgdG8gbWFrZSB0aGVtIGFsbCBiZSBwb3NpdGlvbmVkIChtYWtlcyBhbgogICAgICogZXh0cmEgcm93IHdoZW4gbmVlZGVkLCByZW1vdmVzIGl0IHdoZW4gbm90IG5lZWRlZCkuCiAgICAgKi8KICAgIGlmIChpZCAhPSAoV2lkZ2V0KTApCglYdE1hbmFnZUNoaWxkKGlkKTsKCiAgICAvKgogICAgICogTm93IGZpbmQgdGhlIG1lbnUgaXRlbSB0aGF0IGlzIHRoZSBmdXJ0aGVzdCBkb3duLCBhbmQgZ2V0IGl0J3MgcG9zaXRpb24uCiAgICAgKi8KICAgIG1heHkgPSAwOwogICAgZm9yIChtcCA9IHJvb3RfbWVudTsgbXAgIT0gTlVMTDsgbXAgPSBtcC0+bmV4dCkKICAgIHsKCWlmIChtcC0+aWQgIT0gKFdpZGdldCkwICYmIG1lbnVfaXNfbWVudWJhcihtcC0+bmFtZSkpCgl7CgkgICAgWHRWYUdldFZhbHVlcyhtcC0+aWQsIFhtTnksICZ5LCBOVUxMKTsKCSAgICBpZiAoeSA+IG1heHkpCgkJbWF4eSA9IHk7Cgl9CiAgICB9CgogICAgWHRWYUdldFZhbHVlcyhtZW51QmFyLAoJWG1ObWFyZ2luSGVpZ2h0LCAmbWFyZ2luLAoJWG1Oc2hhZG93VGhpY2tuZXNzLCAmc2hhZG93LAoJTlVMTCk7CgogICAgLyoKICAgICAqIFRoaXMgY29tcHV0YXRpb24gaXMgdGhlIHJlc3VsdCBvZiB0cmlhbC1hbmQtZXJyb3I6CiAgICAgKiBtYXh5ID0JVGhlIG1heGltdW0gcG9zaXRpb24gb2YgYW4gaXRlbTsgcmVxdWlyZWQgZm9yIHdoZW4gdGhlcmUgYXJlCiAgICAgKgkJdHdvIG9yIG1vcmUgcm93cwogICAgICogaGVpZ2h0ID0gaGVpZ2h0IG9mIGFuIGl0ZW0sIGJlZm9yZSBtYW5hZ2luZyBpdDsJSG9wZWZ1bGx5IHRoaXMgd2lsbAogICAgICoJCWNoYW5nZSB3aXRoIHRoZSBmb250IGhlaWdodC4gIEluY2x1ZGVzIHNoYWRvdy1ib3JkZXIuCiAgICAgKiBzaGFkb3cgPQlzaGFkb3ctYm9yZGVyOyBtdXN0IGJlIHN1YnRyYWN0ZWQgZnJvbSB0aGUgaGVpZ2h0LgogICAgICogbWFyZ2luID0gbWFyZ2luIGFyb3VuZCB0aGUgbWVudSBidXR0b25zOyAgTXVzdCBiZSBhZGRlZC4KICAgICAqIEFkZCA0IGZvciB0aGUgdW5kZXJsaW5pbmcgb2Ygc2hvcnRjdXQga2V5cy4KICAgICAqLwogICAgZ3VpLm1lbnVfaGVpZ2h0ID0gbWF4eSArIGhlaWdodCAtIDIgKiBzaGFkb3cgKyAyICogbWFyZ2luICsgNDsKCiAgICAvKiBTb21laG93IHRoZSBtZW51IGJhciBkb2Vzbid0IHJlc2l6ZSBhdXRvbWF0aWNhbGx5LiAgU2V0IGl0IGhlcmUsCiAgICAgKiBldmVuIHRob3VnaCB0aGlzIGlzIGEgY2F0Y2ggMjIuICBEb24ndCBkbyB0aGlzIHdoZW4gc3RhcnRpbmcgdXAsCiAgICAgKiBzb21laG93IHRoZSBtZW51IGdldHMgdmVyeSBoaWdoIHRoZW4uICovCiAgICBpZiAoZ3VpLnNoZWxsX2NyZWF0ZWQpCglYdFZhU2V0VmFsdWVzKG1lbnVCYXIsIFhtTmhlaWdodCwgZ3VpLm1lbnVfaGVpZ2h0LCBOVUxMKTsKfQoKI2lmZGVmIEZFQVRfVE9PTEJBUgoKLyoKICogSWNvbnMgdXNlZCBieSB0aGUgdG9vbGJhciBjb2RlLgogKi8KI2luY2x1ZGUgImd1aV94MTFfcG0uaCIKCnN0YXRpYyBpbnQgY2hlY2tfeHBtIF9fQVJHUygoY2hhcl91ICpwYXRoKSk7CnN0YXRpYyBjaGFyICoqZ2V0X3Rvb2xiYXJfcGl4bWFwIF9fQVJHUygodmltbWVudV9UICptZW51LCBjaGFyICoqZm5hbWUpKTsKc3RhdGljIGludCBhZGRfcGl4bWFwX2FyZ3MgX19BUkdTKCh2aW1tZW51X1QgKm1lbnUsIEFyZyAqYXJncywgaW50IG4pKTsKCi8qCiAqIFJlYWQgYW4gWHBtIGZpbGUuICBSZXR1cm4gT0sgb3IgRkFJTC4KICovCiAgICBzdGF0aWMgaW50CmNoZWNrX3hwbShwYXRoKQogICAgY2hhcl91CSpwYXRoOwp7CiAgICBYcG1BdHRyaWJ1dGVzIGF0dHJzOwogICAgaW50CQlzdGF0dXM7CiAgICBQaXhtYXAJbWFzazsKICAgIFBpeG1hcAltYXA7CgogICAgYXR0cnMudmFsdWVtYXNrID0gMDsKCiAgICAvKiBDcmVhdGUgdGhlICJzZW5zaXRpdmUiIHBpeG1hcCAqLwogICAgc3RhdHVzID0gWHBtUmVhZEZpbGVUb1BpeG1hcChndWkuZHB5LAoJICAgIFJvb3RXaW5kb3coZ3VpLmRweSwgRGVmYXVsdFNjcmVlbihndWkuZHB5KSksCgkgICAgKGNoYXIgKilwYXRoLCAmbWFwLCAmbWFzaywgJmF0dHJzKTsKICAgIFhwbUZyZWVBdHRyaWJ1dGVzKCZhdHRycyk7CgogICAgaWYgKHN0YXR1cyA9PSBYcG1TdWNjZXNzKQoJcmV0dXJuIE9LOwogICAgcmV0dXJuIEZBSUw7Cn0KCgovKgogKiBBbGxvY2F0ZWQgYSBwaXhtYXAgZm9yIHRvb2xiYXIgbWVudSAibWVudSIuCiAqIFdoZW4gaXQncyB0byBiZSByZWFkIGZyb20gYSBmaWxlLCAiZm5hbWUiIGlzIHNldCB0byB0aGUgZmlsZSBuYW1lCiAqIChpbiBhbGxvY2F0ZWQgbWVtb3J5KS4KICogUmV0dXJuIGEgYmxhbmsgcGl4bWFwIGlmIGl0IGZhaWxzLgogKi8KICAgIHN0YXRpYyBjaGFyICoqCmdldF90b29sYmFyX3BpeG1hcChtZW51LCBmbmFtZSkKICAgIHZpbW1lbnVfVAkqbWVudTsKICAgIGNoYXIJKipmbmFtZTsKewogICAgY2hhcl91CWJ1ZltNQVhQQVRITF07CQkvKiBidWZmZXIgc3RvcmluZyBleHBhbmRlZCBwYXRobmFtZSAqLwogICAgY2hhcgkqKnhwbSA9IE5VTEw7CQkvKiB4cG0gYXJyYXkgKi8KICAgIGludAkJcmVzOwoKICAgICpmbmFtZSA9IE5VTEw7CiAgICBidWZbMF0gPSBOVUw7CQkJLyogc3RhcnQgd2l0aCBOVUxMIHBhdGggKi8KCiAgICBpZiAobWVudS0+aWNvbmZpbGUgIT0gTlVMTCkKICAgIHsKCS8qIFVzZSB0aGUgImljb249IiAgYXJndW1lbnQuICovCglndWlfZmluZF9pY29uZmlsZShtZW51LT5pY29uZmlsZSwgYnVmLCAieHBtIik7CglyZXMgPSBjaGVja194cG0oYnVmKTsKCgkvKiBJZiBpdCBmYWlsZWQsIHRyeSB1c2luZyB0aGUgbWVudSBuYW1lLiAqLwoJaWYgKHJlcyA9PSBGQUlMICYmIGd1aV9maW5kX2JpdG1hcChtZW51LT5uYW1lLCBidWYsICJ4cG0iKSA9PSBPSykKCSAgICByZXMgPSBjaGVja194cG0oYnVmKTsKCWlmIChyZXMgPT0gT0spCgl7CgkgICAgKmZuYW1lID0gKGNoYXIgKil2aW1fc3Ryc2F2ZShidWYpOwoJICAgIHJldHVybiB0Yl9ibGFua194cG07Cgl9CiAgICB9CgogICAgaWYgKG1lbnUtPmljb25fYnVpbHRpbiB8fCBndWlfZmluZF9iaXRtYXAobWVudS0+bmFtZSwgYnVmLCAieHBtIikgPT0gRkFJTCkKICAgIHsKCWlmIChtZW51LT5pY29uaWR4ID49IDAgJiYgbWVudS0+aWNvbmlkeAoJCSAgIDwgKHNpemVvZihidWlsdF9pbl9waXhtYXBzKSAvIHNpemVvZihidWlsdF9pbl9waXhtYXBzWzBdKSkpCgkgICAgeHBtID0gYnVpbHRfaW5fcGl4bWFwc1ttZW51LT5pY29uaWR4XTsKCWVsc2UKCSAgICB4cG0gPSB0Yl9ibGFua194cG07CiAgICB9CgogICAgcmV0dXJuIHhwbTsKfQoKLyoKICogQWRkIGFyZ3VtZW50cyBmb3IgdGhlIHRvb2xiYXIgcGl4bWFwIHRvIGEgbWVudSBpdGVtLgogKi8KICAgIHN0YXRpYyBpbnQKYWRkX3BpeG1hcF9hcmdzKG1lbnUsIGFyZ3MsIG4pCiAgICB2aW1tZW51X1QJKm1lbnU7CiAgICBBcmcJCSphcmdzOwogICAgaW50CQluOwp7CiAgICB2aW1fZnJlZShtZW51LT54cG1fZm5hbWUpOwogICAgbWVudS0+eHBtID0gZ2V0X3Rvb2xiYXJfcGl4bWFwKG1lbnUsICZtZW51LT54cG1fZm5hbWUpOwogICAgaWYgKG1lbnUtPnhwbSA9PSBOVUxMKQogICAgewoJWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGFiZWxUeXBlLCBYbVNUUklORyk7IG4rKzsKICAgIH0KICAgIGVsc2UKICAgIHsKCWlmIChtZW51LT54cG1fZm5hbWUgIT0gTlVMTCkKCXsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5waXhtYXBGaWxlLCBtZW51LT54cG1fZm5hbWUpOyBuKys7Cgl9CglYdFNldEFyZyhhcmdzW25dLCBYbU5waXhtYXBEYXRhLCBtZW51LT54cG0pOyBuKys7CglYdFNldEFyZyhhcmdzW25dLCBYbU5sYWJlbExvY2F0aW9uLCBYbUJPVFRPTSk7IG4rKzsKICAgIH0KICAgIHJldHVybiBuOwp9CiNlbmRpZiAvKiBGRUFUX1RPT0xCQVIgKi8KCiAgICB2b2lkCmd1aV9tY2hfYWRkX21lbnVfaXRlbShtZW51LCBpZHgpCiAgICB2aW1tZW51X1QJKm1lbnU7CiAgICBpbnQJCWlkeDsKewogICAgWG1TdHJpbmcJbGFiZWw7CiAgICB2aW1tZW51X1QJKnBhcmVudCA9IG1lbnUtPnBhcmVudDsKCiMgaWZkZWYgRUJDRElDCiAgICBtZW51LT5tbmVtb25pYyA9IDA7CiMgZW5kaWYKCiMgaWYgKFhtVmVyc2lvbiA8PSAxMDAyKQogICAgLyogRG9uJ3QgYWRkIFBvcHVwIG1lbnUgaXRlbXMgd2hlbiB0aGUgcG9wdXAgbWVudSBpc24ndCB1c2VkLiAqLwogICAgaWYgKG1lbnVfaXNfY2hpbGRfb2ZfcG9wdXAobWVudSkgJiYgIW1vdXNlX21vZGVsX3BvcHVwKCkpCglyZXR1cm47CiMgZW5kaWYKCiMgaWZkZWYgRkVBVF9UT09MQkFSCiAgICBpZiAobWVudV9pc190b29sYmFyKHBhcmVudC0+bmFtZSkpCiAgICB7CglXaWRnZXRDbGFzcwl0eXBlOwoJWG1TdHJpbmcJeG1zID0gTlVMTDsgICAgLyogZmFsbGJhY2sgbGFiZWwgaWYgcGl4bWFwIG5vdCBmb3VuZCAqLwoJaW50CQluOwoJQXJnCQlhcmdzWzE4XTsKCgluID0gMDsKCWlmIChtZW51X2lzX3NlcGFyYXRvcihtZW51LT5uYW1lKSkKCXsKCSAgICBjaGFyCSpjcDsKCSAgICBEaW1lbnNpb24Jd2lkOwoKCSAgICAvKgoJICAgICAqIEEgc2VwYXJhdG9yIGhhcyB0aGUgZm9ybWF0ICItc2VwJWRbOiVkXS0iLiBUaGUgb3B0aW9uYWwgOiVkIGlzCgkgICAgICogYSB3aWR0aCBzcGVjaWZpZXIuIElmIG5vIHdpZHRoIGlzIHNwZWNpZmllZCB0aGVuIHdlIGNob29zZSBvbmUuCgkgICAgICovCgkgICAgY3AgPSAoY2hhciAqKXZpbV9zdHJjaHIobWVudS0+bmFtZSwgJzonKTsKCSAgICBpZiAoY3AgIT0gTlVMTCkKCQl3aWQgPSAoRGltZW5zaW9uKWF0b2koKytjcCk7CgkgICAgZWxzZQoJCXdpZCA9IDQ7CgojaWYgMAoJICAgIC8qIFdlIGJldHRlciB1c2UgYSBGb3JtV2lkZ2V0IGhlcmUsIHNpbmNlIGl0J3MgZmFyIG1vcmUKCSAgICAgKiBmbGV4aWJsZSBpbiB0ZXJtcyBvZiBzaXplLiAgKi8KCSAgICB0eXBlID0geG1Gb3JtV2lkZ2V0Q2xhc3M7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1Od2lkdGgsIHdpZCk7IG4rKzsKI2Vsc2UKCSAgICB0eXBlID0geG1TZXBhcmF0b3JXaWRnZXRDbGFzczsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU53aWR0aCwgd2lkKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm1pbldpZHRoLCB3aWQpOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1Ob3JpZW50YXRpb24sIFhtVkVSVElDQUwpOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1Oc2VwYXJhdG9yVHlwZSwgWG1TSEFET1dfRVRDSEVEX0lOKTsgbisrOwojZW5kaWYKCX0KCWVsc2UKCXsKCSAgICAvKiBXaXRob3V0IHNoYWRvd3Mgb25lIGNhbid0IHNlbnNlIHdoYXRldmVyIHRoZSBidXR0b24gaGFzIGJlZW4KCSAgICAgKiBwcmVzc2VkIG9yIG5vdCEgSG93ZXZlciB3ZSB3YW4ndCB0byBzYXZlIGEgYml0IG9mIHNwYWNlLi4uCgkgICAgICogTmVlZCB0aGUgaGlnaGxpZ2h0VGhpY2tuZXNzIHRvIHNlZSB0aGUgZm9jdXMuCgkgICAgICovCgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OaGlnaGxpZ2h0VGhpY2tuZXNzLCAxKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmhpZ2hsaWdodE9uRW50ZXIsIFRydWUpOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1ObWFyZ2luV2lkdGgsIDApOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1ObWFyZ2luSGVpZ2h0LCAwKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnRyYXZlcnNhbE9uLCBGYWxzZSk7IG4rKzsKCSAgICAvKiBTZXQgdGhlIGxhYmVsIGhlcmUsIHNvIHRoYXQgd2UgY2FuIHN3aXRjaCBiZXR3ZWVuIGljb25zL3RleHQKCSAgICAgKiBieSBjaGFuZ2luZyB0aGUgWG1ObGFiZWxUeXBlIHJlc291cmNlLiAqLwoJICAgIHhtcyA9IFhtU3RyaW5nQ3JlYXRlKChjaGFyICopbWVudS0+ZG5hbWUsIFNUUklOR19UQUcpOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxhYmVsU3RyaW5nLCB4bXMpOyBuKys7CgoJICAgIG4gPSBhZGRfcGl4bWFwX2FyZ3MobWVudSwgYXJncywgbik7CgoJICAgIHR5cGUgPSB4bUVuaGFuY2VkQnV0dG9uV2lkZ2V0Q2xhc3M7Cgl9CgoJWHRTZXRBcmcoYXJnc1tuXSwgWG1OcG9zaXRpb25JbmRleCwgaWR4KTsgbisrOwoJaWYgKG1lbnUtPmlkID09IE5VTEwpCgl7CgkgICAgbWVudS0+aWQgPSBYdENyZWF0ZU1hbmFnZWRXaWRnZXQoKGNoYXIgKiltZW51LT5kbmFtZSwKCQkJdHlwZSwgdG9vbEJhciwgYXJncywgbik7CgkgICAgaWYgKG1lbnUtPmlkICE9IE5VTEwgJiYgdHlwZSA9PSB4bUVuaGFuY2VkQnV0dG9uV2lkZ2V0Q2xhc3MpCgkgICAgewoJCVh0QWRkQ2FsbGJhY2sobWVudS0+aWQsCgkJCVhtTmFjdGl2YXRlQ2FsbGJhY2ssIGd1aV94MTFfbWVudV9jYiwgbWVudSk7CiMgaWZkZWYgRkVBVF9GT09URVIKCQlYdEFkZEV2ZW50SGFuZGxlcihtZW51LT5pZCwgRW50ZXJXaW5kb3dNYXNrLCBGYWxzZSwKCQkJdG9vbGJhcmJ1dHRvbl9lbnRlcl9jYiwgbWVudSk7CgkJWHRBZGRFdmVudEhhbmRsZXIobWVudS0+aWQsIExlYXZlV2luZG93TWFzaywgRmFsc2UsCgkJCXRvb2xiYXJidXR0b25fbGVhdmVfY2IsIG1lbnUpOwojIGVuZGlmCgkgICAgfQoJfQoJZWxzZQoJICAgIFh0U2V0VmFsdWVzKG1lbnUtPmlkLCBhcmdzLCBuKTsKCWlmICh4bXMgIT0gTlVMTCkKCSAgICBYbVN0cmluZ0ZyZWUoeG1zKTsKCiMgaWZkZWYgRkVBVF9CRVZBTAoJZ3VpX21jaF9tZW51X3NldF90aXAobWVudSk7CiMgZW5kaWYKCgltZW51LT5wYXJlbnQgPSBwYXJlbnQ7CgltZW51LT5zdWJtZW51X2lkID0gTlVMTDsKCS8qIFdoZW4gYWRkaW5nIGZpcnN0IGl0ZW0gdG8gdG9vbGJhciBpdCBtaWdodCBoYXZlIHRvIGJlIGVuYWJsZWQgLiovCglpZiAoIVh0SXNNYW5hZ2VkKFh0UGFyZW50KHRvb2xCYXIpKQoJCSAgICAmJiB2aW1fc3RyY2hyKHBfZ28sIEdPX1RPT0xCQVIpICE9IE5VTEwpCgkgICAgZ3VpX21jaF9zaG93X3Rvb2xiYXIoVFJVRSk7CglndWkudG9vbGJhcl9oZWlnaHQgPSBndWlfbWNoX2NvbXB1dGVfdG9vbGJhcl9oZWlnaHQoKTsKCXJldHVybjsKICAgIH0gLyogdG9vbGJhciBtZW51IGl0ZW0gKi8KIyBlbmRpZgoKICAgIC8qIE5vIHBhcmVudCwgbXVzdCBiZSBhIG5vbi1tZW51YmFyIG1lbnUgKi8KICAgIGlmIChwYXJlbnQtPnN1Ym1lbnVfaWQgPT0gKFdpZGdldCkwKQoJcmV0dXJuOwoKICAgIG1lbnUtPnN1Ym1lbnVfaWQgPSAoV2lkZ2V0KTA7CgogICAgLyogQWRkIG1lbnUgc2VwYXJhdG9yICovCiAgICBpZiAobWVudV9pc19zZXBhcmF0b3IobWVudS0+bmFtZSkpCiAgICB7CgltZW51LT5pZCA9IFh0VmFDcmVhdGVXaWRnZXQoInN1Yk1lbnUiLAoJCXhtU2VwYXJhdG9yR2FkZ2V0Q2xhc3MsIHBhcmVudC0+c3VibWVudV9pZCwKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKCQkvKiBjb3VudCB0aGUgdGVhcm9mZiBpdGVtIChuZWVkZWQgZm9yIExlc3NUaWYpICovCgkJWG1OcG9zaXRpb25JbmRleCwgaWR4ICsgKHRlYXJvZmZfdmFsID09IChpbnQpWG1URUFSX09GRl9FTkFCTEVECgkJCQkJCQkJICAgICA/IDEgOiAwKSwKI2VuZGlmCgkJTlVMTCk7CglndWlfbW90aWZfbWVudV9jb2xvcnMobWVudS0+aWQpOwoJcmV0dXJuOwogICAgfQoKICAgIGxhYmVsID0gWG1TdHJpbmdDcmVhdGUoKGNoYXIgKiltZW51LT5kbmFtZSwgU1RSSU5HX1RBRyk7CiAgICBpZiAobGFiZWwgPT0gTlVMTCkKCXJldHVybjsKICAgIG1lbnUtPmlkID0gWHRWYUNyZWF0ZVdpZGdldCgic3ViTWVudSIsCgl4bVB1c2hCdXR0b25XaWRnZXRDbGFzcywgcGFyZW50LT5zdWJtZW51X2lkLAoJWG1ObGFiZWxTdHJpbmcsIGxhYmVsLAoJWG1ObW5lbW9uaWMsIG1lbnUtPm1uZW1vbmljLAojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQoJLyogY291bnQgdGhlIHRlYXJvZmYgaXRlbSAobmVlZGVkIGZvciBMZXNzVGlmKSAqLwoJWG1OcG9zaXRpb25JbmRleCwgaWR4ICsgKHRlYXJvZmZfdmFsID09IChpbnQpWG1URUFSX09GRl9FTkFCTEVECgkJCQkJCQkJICAgICA/IDEgOiAwKSwKI2VuZGlmCglOVUxMKTsKICAgIGd1aV9tb3RpZl9tZW51X2NvbG9ycyhtZW51LT5pZCk7CiAgICBndWlfbW90aWZfbWVudV9mb250bGlzdChtZW51LT5pZCk7CiAgICBYbVN0cmluZ0ZyZWUobGFiZWwpOwoKICAgIGlmIChtZW51LT5pZCAhPSAoV2lkZ2V0KTApCiAgICB7CglYdEFkZENhbGxiYWNrKG1lbnUtPmlkLCBYbU5hY3RpdmF0ZUNhbGxiYWNrLCBndWlfeDExX21lbnVfY2IsCgkJKFh0UG9pbnRlciltZW51KTsKCS8qIGFkZCBhY2NlbGVyYXRvciB0ZXh0ICovCglndWlfbW90aWZfYWRkX2FjdGV4dChtZW51KTsKICAgIH0KfQoKI2lmIChYbVZlcnNpb24gPD0gMTAwMikgfHwgZGVmaW5lZChQUk9UTykKLyoKICogVGhpcyBmdW5jdGlvbiB3aWxsIGRlc3Ryb3kvY3JlYXRlIHRoZSBwb3B1cCBtZW51cyBkeW5hbWljYWxseSwKICogYWNjb3JkaW5nIHRvIHRoZSB2YWx1ZSBvZiAnbW91c2Vtb2RlbCcuCiAqIFRoaXMgd2lsbCBmaXggdGhlICJyaWdodCBtb3VzZSBidXR0b24gZnJlZXplIiB0aGF0IG9jY3VycyB3aGVuCiAqIHRoZXJlIGV4aXN0cyBhIHBvcHVwIG1lbnUgYnV0IGl0IGlzbid0IG1hbmFnZWQuCiAqLwogICAgdm9pZApndWlfbW90aWZfdXBkYXRlX21vdXNlbW9kZWwobWVudSkKICAgIHZpbW1lbnVfVAkqbWVudTsKewogICAgaW50CQlpZHggPSAwOwoKICAgIC8qIFdoZW4gR1VJIGhhc24ndCBzdGFydGVkIHRoZSBtZW51cyBoYXZlIG5vdCBiZWVuIGNyZWF0ZWQuICovCiAgICBpZiAoIWd1aS5pbl91c2UpCiAgICAgIHJldHVybjsKCiAgICB3aGlsZSAobWVudSkKICAgIHsKICAgICAgaWYgKG1lbnUtPmNoaWxkcmVuICE9IE5VTEwpCiAgICAgIHsKCSAgaWYgKG1lbnVfaXNfcG9wdXAobWVudS0+bmFtZSkpCgkgIHsKCSAgICAgIGlmIChtb3VzZV9tb2RlbF9wb3B1cCgpKQoJICAgICAgewoJCSAgLyogUG9wdXAgbWVudSB3aWxsIGJlIHVzZWQuICBDcmVhdGUgdGhlIHBvcHVwIG1lbnVzLiAqLwoJCSAgZ3VpX21jaF9hZGRfbWVudShtZW51LCBpZHgpOwoJCSAgZ3VpX21vdGlmX3VwZGF0ZV9tb3VzZW1vZGVsKG1lbnUtPmNoaWxkcmVuKTsKCSAgICAgIH0KCSAgICAgIGVsc2UKCSAgICAgIHsKCQkgIC8qIFBvcHVwIG1lbnUgd2lsbCBub3QgYmUgdXNlZC4gIERlc3Ryb3kgdGhlIHBvcHVwIG1lbnVzLiAqLwoJCSAgZ3VpX21vdGlmX3VwZGF0ZV9tb3VzZW1vZGVsKG1lbnUtPmNoaWxkcmVuKTsKCQkgIGd1aV9tY2hfZGVzdHJveV9tZW51KG1lbnUpOwoJICAgICAgfQoJICB9CiAgICAgIH0KICAgICAgZWxzZSBpZiAobWVudV9pc19jaGlsZF9vZl9wb3B1cChtZW51KSkKICAgICAgewoJICBpZiAobW91c2VfbW9kZWxfcG9wdXAoKSkKCSAgICAgIGd1aV9tY2hfYWRkX21lbnVfaXRlbShtZW51LCBpZHgpOwoJICBlbHNlCgkgICAgICBndWlfbWNoX2Rlc3Ryb3lfbWVudShtZW51KTsKICAgICAgfQogICAgICBtZW51ID0gbWVudS0+bmV4dDsKICAgICAgKytpZHg7CiAgICB9Cn0KI2VuZGlmCgogICAgdm9pZApndWlfbWNoX25ld19tZW51X2NvbG9ycygpCnsKICAgIGlmIChtZW51QmFyID09IChXaWRnZXQpMCkKCXJldHVybjsKICAgIGd1aV9tb3RpZl9tZW51X2NvbG9ycyhtZW51QmFyKTsKI2lmZGVmIEZFQVRfVE9PTEJBUgogICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKHRvb2xCYXJGcmFtZSk7CiAgICBndWlfbW90aWZfbWVudV9jb2xvcnModG9vbEJhcik7CiNlbmRpZgoKICAgIHN1Ym1lbnVfY2hhbmdlKHJvb3RfbWVudSwgVFJVRSk7Cn0KCiAgICB2b2lkCmd1aV9tY2hfbmV3X21lbnVfZm9udCgpCnsKICAgIGlmIChtZW51QmFyID09IChXaWRnZXQpMCkKCXJldHVybjsKICAgIHN1Ym1lbnVfY2hhbmdlKHJvb3RfbWVudSwgRkFMU0UpOwogICAgewoJRGltZW5zaW9uICAgaGVpZ2h0OwoJUG9zaXRpb24gdywgaDsKCglYdFZhR2V0VmFsdWVzKG1lbnVCYXIsIFhtTmhlaWdodCwgJmhlaWdodCwgTlVMTCk7CglndWkubWVudV9oZWlnaHQgPSBoZWlnaHQ7CgoJWHRWYUdldFZhbHVlcyh2aW1TaGVsbCwgWHROd2lkdGgsICZ3LCBYdE5oZWlnaHQsICZoLCBOVUxMKTsKCWd1aV9yZXNpemVfc2hlbGwodywgaAojaWZkZWYgRkVBVF9YSU0KCQktIHhpbV9nZXRfc3RhdHVzX2FyZWFfaGVpZ2h0KCkKI2VuZGlmCgkJICAgICApOwogICAgfQogICAgZ3VpX3NldF9zaGVsbHNpemUoRkFMU0UsIFRSVUUsIFJFU0laRV9WRVJUKTsKICAgIHVpX25ld19zaGVsbHNpemUoKTsKfQoKI2lmIGRlZmluZWQoRkVBVF9CRVZBTCkgfHwgZGVmaW5lZChQUk9UTykKICAgIHZvaWQKZ3VpX21jaF9uZXdfdG9vbHRpcF9mb250KCkKewojIGlmZGVmIEZFQVRfVE9PTEJBUgogICAgdmltbWVudV9UICAgKm1lbnU7CgogICAgaWYgKHRvb2xCYXIgPT0gKFdpZGdldCkwKQoJcmV0dXJuOwoKICAgIG1lbnUgPSBndWlfZmluZF9tZW51KChjaGFyX3UgKikiVG9vbEJhciIpOwogICAgaWYgKG1lbnUgIT0gTlVMTCkKCXN1Ym1lbnVfY2hhbmdlKG1lbnUsIEZBTFNFKTsKIyBlbmRpZgp9CgogICAgdm9pZApndWlfbWNoX25ld190b29sdGlwX2NvbG9ycygpCnsKIyBpZmRlZiBGRUFUX1RPT0xCQVIKICAgIHZpbW1lbnVfVCAgICp0b29sYmFyOwoKICAgIGlmICh0b29sQmFyID09IChXaWRnZXQpMCkKCXJldHVybjsKCiAgICB0b29sYmFyID0gZ3VpX2ZpbmRfbWVudSgoY2hhcl91ICopIlRvb2xCYXIiKTsKICAgIGlmICh0b29sYmFyICE9IE5VTEwpCglzdWJtZW51X2NoYW5nZSh0b29sYmFyLCBUUlVFKTsKIyBlbmRpZgp9CiNlbmRpZgoKICAgIHN0YXRpYyB2b2lkCnN1Ym1lbnVfY2hhbmdlKG1lbnUsIGNvbG9ycykKICAgIHZpbW1lbnVfVAkqbWVudTsKICAgIGludAkJY29sb3JzOwkJLyogVFJVRSBmb3IgY29sb3JzLCBGQUxTRSBmb3IgZm9udCAqLwp7CiAgICB2aW1tZW51X1QJKm1wOwoKICAgIGZvciAobXAgPSBtZW51OyBtcCAhPSBOVUxMOyBtcCA9IG1wLT5uZXh0KQogICAgewoJaWYgKG1wLT5pZCAhPSAoV2lkZ2V0KTApCgl7CgkgICAgaWYgKGNvbG9ycykKCSAgICB7CgkJZ3VpX21vdGlmX21lbnVfY29sb3JzKG1wLT5pZCk7CiNpZmRlZiBGRUFUX1RPT0xCQVIKCQkvKiBGb3IgYSB0b29sYmFyIGl0ZW06IEZyZWUgdGhlIHBpeG1hcCBhbmQgYWxsb2NhdGUgYSBuZXcgb25lLAoJCSAqIHNvIHRoYXQgdGhlIGJhY2tncm91bmQgY29sb3IgaXMgcmlnaHQuICovCgkJaWYgKG1wLT54cG0gIT0gTlVMTCkKCQl7CgkJICAgIGludAkJbiA9IDA7CgkJICAgIEFyZwkJYXJnc1sxOF07CgoJCSAgICBuID0gYWRkX3BpeG1hcF9hcmdzKG1wLCBhcmdzLCBuKTsKCQkgICAgWHRTZXRWYWx1ZXMobXAtPmlkLCBhcmdzLCBuKTsKCQl9CiMgaWZkZWYgRkVBVF9CRVZBTAoJCS8qIElmIHdlIGhhdmUgYSB0b29sdGlwLCB0aGVuIHdlIG5lZWQgdG8gY2hhbmdlIGl0J3MgZm9udCAqLwoJCWlmIChtcC0+dGlwICE9IE5VTEwpCgkJewoJCSAgICBBcmcgYXJnc1syXTsKCgkJICAgIGFyZ3NbMF0ubmFtZSA9IFhtTmJhY2tncm91bmQ7CgkJICAgIGFyZ3NbMF0udmFsdWUgPSBndWkudG9vbHRpcF9iZ19waXhlbDsKCQkgICAgYXJnc1sxXS5uYW1lID0gWG1OZm9yZWdyb3VuZDsKCQkgICAgYXJnc1sxXS52YWx1ZSA9IGd1aS50b29sdGlwX2ZnX3BpeGVsOwoJCSAgICBYdFNldFZhbHVlcyhtcC0+dGlwLT5iYWxsb29uTGFiZWwsICZhcmdzWzBdLCBYdE51bWJlcihhcmdzKSk7CgkJfQojIGVuZGlmCiNlbmRpZgoJICAgIH0KCSAgICBlbHNlCgkgICAgewoJCWd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KG1wLT5pZCk7CiNpZmRlZiBGRUFUX0JFVkFMCgkJLyogSWYgd2UgaGF2ZSBhIHRvb2x0aXAsIHRoZW4gd2UgbmVlZCB0byBjaGFuZ2UgaXQncyBmb250ICovCgkJaWYgKG1wLT50aXAgIT0gTlVMTCkKCQl7CgkJICAgIEFyZyBhcmdzWzFdOwoKCQkgICAgYXJnc1swXS5uYW1lID0gWG1OZm9udExpc3Q7CgkJICAgIGFyZ3NbMF0udmFsdWUgPSAoWHRBcmdWYWwpZ3VpX21vdGlmX2ZvbnRzZXQyZm9udGxpc3QoCgkJCQkJCSAgICAmZ3VpLnRvb2x0aXBfZm9udHNldCk7CgkJICAgIFh0U2V0VmFsdWVzKG1wLT50aXAtPmJhbGxvb25MYWJlbCwgJmFyZ3NbMF0sIFh0TnVtYmVyKGFyZ3MpKTsKCQl9CiNlbmRpZgoJICAgIH0KCX0KCglpZiAobXAtPmNoaWxkcmVuICE9IE5VTEwpCgl7CiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCgkgICAgLyogU2V0IHRoZSBjb2xvcnMvZm9udCBmb3IgdGhlIHRlYXIgb2ZmIHdpZGdldCAqLwoJICAgIGlmIChtcC0+c3VibWVudV9pZCAhPSAoV2lkZ2V0KTApCgkgICAgewoJCWlmIChjb2xvcnMpCgkJICAgIGd1aV9tb3RpZl9tZW51X2NvbG9ycyhtcC0+c3VibWVudV9pZCk7CgkJZWxzZQoJCSAgICBndWlfbW90aWZfbWVudV9mb250bGlzdChtcC0+c3VibWVudV9pZCk7CgkJdG9nZ2xlX3RlYXJvZmYobXAtPnN1Ym1lbnVfaWQpOwoJICAgIH0KI2VuZGlmCgkgICAgLyogU2V0IHRoZSBjb2xvcnMgZm9yIHRoZSBjaGlsZHJlbiAqLwoJICAgIHN1Ym1lbnVfY2hhbmdlKG1wLT5jaGlsZHJlbiwgY29sb3JzKTsKCX0KICAgIH0KfQoKLyoKICogRGVzdHJveSB0aGUgbWFjaGluZSBzcGVjaWZpYyBtZW51IHdpZGdldC4KICovCiAgICB2b2lkCmd1aV9tY2hfZGVzdHJveV9tZW51KG1lbnUpCiAgICB2aW1tZW51X1QJKm1lbnU7CnsKICAgIC8qIFBsZWFzZSBiZSBzdXJlIHRvIGRlc3Ryb3kgdGhlIHBhcmVudCB3aWRnZXQgZmlyc3QgKGkuZS4gbWVudS0+aWQpLgogICAgICogT24gdGhlIG90aGVyIGhhbmQsIHByb2JsZW1zIGhhdmUgYmVlbiByZXBvcnRlZCB0aGF0IHRoZSBzdWJtZW51IG11c3QgYmUKICAgICAqIGRlbGV0ZWQgZmlyc3QuLi4KICAgICAqCiAgICAgKiBUaGlzIGNvZGUgc2hvdWxkIGJlIGJhc2ljYWxseSBpZGVudGljYWwgdG8gdGhhdCBpbiB0aGUgZmlsZSBndWlfYXRoZW5hLmMKICAgICAqIGJlY2F1c2UgdGhleSBhcmUgYm90aCBYdCBiYXNlZC4KICAgICAqLwogICAgaWYgKG1lbnUtPnN1Ym1lbnVfaWQgIT0gKFdpZGdldCkwKQogICAgewoJWHREZXN0cm95V2lkZ2V0KG1lbnUtPnN1Ym1lbnVfaWQpOwoJbWVudS0+c3VibWVudV9pZCA9IChXaWRnZXQpMDsKICAgIH0KCiAgICBpZiAobWVudS0+aWQgIT0gKFdpZGdldCkwKQogICAgewoJV2lkZ2V0CSAgICBwYXJlbnQ7CgoJcGFyZW50ID0gWHRQYXJlbnQobWVudS0+aWQpOwojaWYgZGVmaW5lZChGRUFUX1RPT0xCQVIpICYmIGRlZmluZWQoRkVBVF9CRVZBTCkKCWlmIChwYXJlbnQgPT0gdG9vbEJhciAmJiBtZW51LT50aXAgIT0gTlVMTCkKCXsKCSAgICAvKiBXZSB0cnkgdG8gZGVzdHJveSB0aGlzIGJlZm9yZSB0aGUgYWN0dWFsIG1lbnUsIGJlY2F1c2UgdGhlcmUgYXJlCgkgICAgICogY2FsbGJhY2tzLCBldGMuIHRoYXQgd2lsbCBiZSB1bnJlZ2lzdGVyZWQgZHVyaW5nIHRoZSB0b29sdGlwCgkgICAgICogZGVzdHJ1Y3Rpb24uCgkgICAgICoKCSAgICAgKiBJZiB5b3UgY2FsbCAiZ3VpX21jaF9kZXN0cm95X2JldmFsX2FyZWEoKSIgYWZ0ZXIgZGVzdHJveWluZwoJICAgICAqIG1lbnUtPmlkLCB0aGVuIHRoZSB0b29sdGlwJ3Mgd2luZG93IHdpbGwgaGF2ZSBhbHJlYWR5IGJlZW4KCSAgICAgKiBkZWFsbG9jYXRlZCBieSBYdCwgYW5kIHVua25vd24gYmVoYXZpb3VyIHdpbGwgZW5zdWUgKHByb2JhYmx5CgkgICAgICogYSBjb3JlIGR1bXApLgoJICAgICAqLwoJICAgIGd1aV9tY2hfZGVzdHJveV9iZXZhbF9hcmVhKG1lbnUtPnRpcCk7CgkgICAgbWVudS0+dGlwID0gTlVMTDsKCX0KI2VuZGlmCglYdERlc3Ryb3lXaWRnZXQobWVudS0+aWQpOwoJbWVudS0+aWQgPSAoV2lkZ2V0KTA7CglpZiAocGFyZW50ID09IG1lbnVCYXIpCgkgICAgZ3VpX21jaF9jb21wdXRlX21lbnVfaGVpZ2h0KChXaWRnZXQpMCk7CiNpZmRlZiBGRUFUX1RPT0xCQVIKCWVsc2UgaWYgKHBhcmVudCA9PSB0b29sQmFyKQoJewoJICAgIENhcmRpbmFsICAgIG51bV9jaGlsZHJlbjsKCgkgICAgLyogV2hlbiByZW1vdmluZyBsYXN0IHRvb2xiYXIgaXRlbSwgZG9uJ3QgZGlzcGxheSB0aGUgdG9vbGJhci4gKi8KCSAgICBYdFZhR2V0VmFsdWVzKHRvb2xCYXIsIFhtTm51bUNoaWxkcmVuLCAmbnVtX2NoaWxkcmVuLCBOVUxMKTsKCSAgICBpZiAobnVtX2NoaWxkcmVuID09IDApCgkJZ3VpX21jaF9zaG93X3Rvb2xiYXIoRkFMU0UpOwoJICAgIGVsc2UKCQlndWkudG9vbGJhcl9oZWlnaHQgPSBndWlfbWNoX2NvbXB1dGVfdG9vbGJhcl9oZWlnaHQoKTsKCX0KI2VuZGlmCiAgICB9Cn0KCi8qIEFSR1NVU0VEICovCiAgICB2b2lkCmd1aV9tY2hfc2hvd19wb3B1cG1lbnUobWVudSkKICAgIHZpbW1lbnVfVCAqbWVudTsKewojaWZkZWYgTU9USUZfUE9QVVAKICAgIFhtTWVudVBvc2l0aW9uKG1lbnUtPnN1Ym1lbnVfaWQsIGd1aV94MTFfZ2V0X2xhc3RfbW91c2VfZXZlbnQoKSk7CiAgICBYdE1hbmFnZUNoaWxkKG1lbnUtPnN1Ym1lbnVfaWQpOwojZW5kaWYKfQoKI2VuZGlmIC8qIEZFQVRfTUVOVSAqLwoKLyoKICogU2V0IHRoZSBtZW51IGFuZCBzY3JvbGxiYXIgY29sb3JzIHRvIHRoZWlyIGRlZmF1bHQgdmFsdWVzLgogKi8KICAgIHZvaWQKZ3VpX21jaF9kZWZfY29sb3JzKCkKewogICAgaWYgKGd1aS5pbl91c2UpCiAgICB7CgkvKiBVc2UgdGhlIHZhbHVlcyBzYXZlZCB3aGVuIHN0YXJ0aW5nIHVwLiAgVGhlc2Ugc2hvdWxkIGNvbWUgZnJvbSB0aGUKCSAqIHdpbmRvdyBtYW5hZ2VyIG9yIGEgcmVzb3VyY2VzIGZpbGUuICovCglndWkubWVudV9mZ19waXhlbCA9IGd1aS5tZW51X2RlZl9mZ19waXhlbDsKCWd1aS5tZW51X2JnX3BpeGVsID0gZ3VpLm1lbnVfZGVmX2JnX3BpeGVsOwoJZ3VpLnNjcm9sbF9mZ19waXhlbCA9IGd1aS5zY3JvbGxfZGVmX2ZnX3BpeGVsOwoJZ3VpLnNjcm9sbF9iZ19waXhlbCA9IGd1aS5zY3JvbGxfZGVmX2JnX3BpeGVsOwojaWZkZWYgRkVBVF9CRVZBTAoJZ3VpLnRvb2x0aXBfZmdfcGl4ZWwgPQoJCQlndWlfZ2V0X2NvbG9yKChjaGFyX3UgKilndWkucnNyY190b29sdGlwX2ZnX25hbWUpOwoJZ3VpLnRvb2x0aXBfYmdfcGl4ZWwgPQoJCQlndWlfZ2V0X2NvbG9yKChjaGFyX3UgKilndWkucnNyY190b29sdGlwX2JnX25hbWUpOwojZW5kaWYKICAgIH0KfQoKCi8qCiAqIFNjcm9sbGJhciBzdHVmZi4KICovCgogICAgdm9pZApndWlfbWNoX3NldF9zY3JvbGxiYXJfdGh1bWIoc2IsIHZhbCwgc2l6ZSwgbWF4KQogICAgc2Nyb2xsYmFyX1QgKnNiOwogICAgbG9uZwl2YWw7CiAgICBsb25nCXNpemU7CiAgICBsb25nCW1heDsKewogICAgaWYgKHNiLT5pZCAhPSAoV2lkZ2V0KTApCglYdFZhU2V0VmFsdWVzKHNiLT5pZCwKCQkgIFhtTnZhbHVlLCB2YWwsCgkJICBYbU5zbGlkZXJTaXplLCBzaXplLAoJCSAgWG1OcGFnZUluY3JlbWVudCwgKHNpemUgPiAyID8gc2l6ZSAtIDIgOiAxKSwKCQkgIFhtTm1heGltdW0sIG1heCArIDEsCSAgICAvKiBNb3RpZiBoYXMgbWF4IG9uZSBwYXN0IHRoZSBlbmQgKi8KCQkgIE5VTEwpOwp9CgogICAgdm9pZApndWlfbWNoX3NldF9zY3JvbGxiYXJfcG9zKHNiLCB4LCB5LCB3LCBoKQogICAgc2Nyb2xsYmFyX1QgKnNiOwogICAgaW50CQl4OwogICAgaW50CQl5OwogICAgaW50CQl3OwogICAgaW50CQloOwp7CiAgICBpZiAoc2ItPmlkICE9IChXaWRnZXQpMCkKICAgIHsKCWlmIChzYi0+dHlwZSA9PSBTQkFSX0xFRlQgfHwgc2ItPnR5cGUgPT0gU0JBUl9SSUdIVCkKCXsKCSAgICBpZiAoeSA9PSAwKQoJCWggLT0gZ3VpLmJvcmRlcl9vZmZzZXQ7CgkgICAgZWxzZQoJCXkgLT0gZ3VpLmJvcmRlcl9vZmZzZXQ7CgkgICAgWHRWYVNldFZhbHVlcyhzYi0+aWQsCgkJCSAgWG1OdG9wT2Zmc2V0LCB5LAoJCQkgIFhtTmJvdHRvbU9mZnNldCwgLXkgLSBoLAoJCQkgIFhtTndpZHRoLCB3LAoJCQkgIE5VTEwpOwoJfQoJZWxzZQoJICAgIFh0VmFTZXRWYWx1ZXMoc2ItPmlkLAoJCQkgIFhtTnRvcE9mZnNldCwgeSwKCQkJICBYbU5sZWZ0T2Zmc2V0LCB4LAoJCQkgIFhtTnJpZ2h0T2Zmc2V0LCBndWkud2hpY2hfc2Nyb2xsYmFyc1tTQkFSX1JJR0hUXQoJCQkJCQkgICAgPyBndWkuc2Nyb2xsYmFyX3dpZHRoIDogMCwKCQkJICBYbU5oZWlnaHQsIGgsCgkJCSAgTlVMTCk7CglYdE1hbmFnZUNoaWxkKHNiLT5pZCk7CiAgICB9Cn0KCiAgICB2b2lkCmd1aV9tY2hfZW5hYmxlX3Njcm9sbGJhcihzYiwgZmxhZykKICAgIHNjcm9sbGJhcl9UICpzYjsKICAgIGludAkJZmxhZzsKewogICAgQXJnCQlhcmdzWzE2XTsKICAgIGludAkJbjsKCiAgICBpZiAoc2ItPmlkICE9IChXaWRnZXQpMCkKICAgIHsKCW4gPSAwOwoJaWYgKGZsYWcpCgl7CgkgICAgc3dpdGNoIChzYi0+dHlwZSkKCSAgICB7CgkJY2FzZSBTQkFSX0xFRlQ6CgkJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxlZnRPZmZzZXQsIGd1aS5zY3JvbGxiYXJfd2lkdGgpOyBuKys7CgkJICAgIGJyZWFrOwoKCQljYXNlIFNCQVJfUklHSFQ6CgkJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnJpZ2h0T2Zmc2V0LCBndWkuc2Nyb2xsYmFyX3dpZHRoKTsgbisrOwoJCSAgICBicmVhazsKCgkJY2FzZSBTQkFSX0JPVFRPTToKCQkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tT2Zmc2V0LCBndWkuc2Nyb2xsYmFyX2hlaWdodCk7bisrOwoJCSAgICBicmVhazsKCSAgICB9CgkgICAgWHRTZXRWYWx1ZXModGV4dEFyZWEsIGFyZ3MsIG4pOwoJICAgIFh0TWFuYWdlQ2hpbGQoc2ItPmlkKTsKCX0KCWVsc2UKCXsKCSAgICBpZiAoIWd1aS53aGljaF9zY3JvbGxiYXJzW3NiLT50eXBlXSkKCSAgICB7CgkJLyogVGhlIHNjcm9sbGJhcnMgb2YgdGhpcyB0eXBlIGFyZSBhbGwgZGlzYWJsZWQsIGFkanVzdCB0aGUKCQkgKiB0ZXh0QXJlYSBhdHRhY2htZW50IG9mZnNldC4gKi8KCQlzd2l0Y2ggKHNiLT50eXBlKQoJCXsKCQkgICAgY2FzZSBTQkFSX0xFRlQ6CgkJCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxlZnRPZmZzZXQsIDApOyBuKys7CgkJCWJyZWFrOwoKCQkgICAgY2FzZSBTQkFSX1JJR0hUOgoJCQlYdFNldEFyZyhhcmdzW25dLCBYbU5yaWdodE9mZnNldCwgMCk7IG4rKzsKCQkJYnJlYWs7CgoJCSAgICBjYXNlIFNCQVJfQk9UVE9NOgoJCQlYdFNldEFyZyhhcmdzW25dLCBYbU5ib3R0b21PZmZzZXQsIDApO24rKzsKCQkJYnJlYWs7CgkJfQoJCVh0U2V0VmFsdWVzKHRleHRBcmVhLCBhcmdzLCBuKTsKCSAgICB9CgkgICAgWHRVbm1hbmFnZUNoaWxkKHNiLT5pZCk7Cgl9CiAgICB9Cn0KCiAgICB2b2lkCmd1aV9tY2hfY3JlYXRlX3Njcm9sbGJhcihzYiwgb3JpZW50KQogICAgc2Nyb2xsYmFyX1QgKnNiOwogICAgaW50CQlvcmllbnQ7CS8qIFNCQVJfVkVSVCBvciBTQkFSX0hPUklaICovCnsKICAgIEFyZwkJYXJnc1sxNl07CiAgICBpbnQJCW47CgogICAgbiA9IDA7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5taW5pbXVtLCAwKTsgbisrOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1Ob3JpZW50YXRpb24sCgkgICAgKG9yaWVudCA9PSBTQkFSX1ZFUlQpID8gWG1WRVJUSUNBTCA6IFhtSE9SSVpPTlRBTCk7IG4rKzsKCiAgICBzd2l0Y2ggKHNiLT50eXBlKQogICAgewoJY2FzZSBTQkFSX0xFRlQ6CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9PUFBPU0lURV9GT1JNKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgbisrOwoJICAgIGJyZWFrOwoKCWNhc2UgU0JBUl9SSUdIVDoKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX09QUE9TSVRFX0ZPUk0pOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgbisrOwoJICAgIGJyZWFrOwoKCWNhc2UgU0JBUl9CT1RUT006CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CgkgICAgYnJlYWs7CiAgICB9CgogICAgc2ItPmlkID0gWHRDcmVhdGVXaWRnZXQoInNjcm9sbEJhciIsCgkgICAgeG1TY3JvbGxCYXJXaWRnZXRDbGFzcywgdGV4dEFyZWFGb3JtLCBhcmdzLCBuKTsKCiAgICAvKiBSZW1lbWJlciB0aGUgZGVmYXVsdCBjb2xvcnMsIG5lZWRlZCBmb3IgIjpoaSBjbGVhciIuICovCiAgICBpZiAoZ3VpLnNjcm9sbF9kZWZfYmdfcGl4ZWwgPT0gKGd1aWNvbG9yX1QpMAoJICAgICYmIGd1aS5zY3JvbGxfZGVmX2ZnX3BpeGVsID09IChndWljb2xvcl9UKTApCglYdFZhR2V0VmFsdWVzKHNiLT5pZCwKCQlYbU5iYWNrZ3JvdW5kLCAmZ3VpLnNjcm9sbF9kZWZfYmdfcGl4ZWwsCgkJWG1OZm9yZWdyb3VuZCwgJmd1aS5zY3JvbGxfZGVmX2ZnX3BpeGVsLAoJCU5VTEwpOwoKICAgIGlmIChzYi0+aWQgIT0gKFdpZGdldCkwKQogICAgewoJZ3VpX21jaF9zZXRfc2Nyb2xsYmFyX2NvbG9ycyhzYik7CglYdEFkZENhbGxiYWNrKHNiLT5pZCwgWG1OdmFsdWVDaGFuZ2VkQ2FsbGJhY2ssCgkJICAgICAgc2Nyb2xsX2NiLCAoWHRQb2ludGVyKXNiLT5pZGVudCk7CglYdEFkZENhbGxiYWNrKHNiLT5pZCwgWG1OZHJhZ0NhbGxiYWNrLAoJCSAgICAgIHNjcm9sbF9jYiwgKFh0UG9pbnRlcilzYi0+aWRlbnQpOwoJWHRBZGRFdmVudEhhbmRsZXIoc2ItPmlkLCBLZXlQcmVzc01hc2ssIEZBTFNFLCBndWlfeDExX2tleV9oaXRfY2IsCgkgICAgKFh0UG9pbnRlcikwKTsKICAgIH0KfQoKI2lmIGRlZmluZWQoRkVBVF9XSU5ET1dTKSB8fCBkZWZpbmVkKFBST1RPKQogICAgdm9pZApndWlfbWNoX2Rlc3Ryb3lfc2Nyb2xsYmFyKHNiKQogICAgc2Nyb2xsYmFyX1QgKnNiOwp7CiAgICBpZiAoc2ItPmlkICE9IChXaWRnZXQpMCkKCVh0RGVzdHJveVdpZGdldChzYi0+aWQpOwp9CiNlbmRpZgoKICAgIHZvaWQKZ3VpX21jaF9zZXRfc2Nyb2xsYmFyX2NvbG9ycyhzYikKICAgIHNjcm9sbGJhcl9UICpzYjsKewogICAgaWYgKHNiLT5pZCAhPSAoV2lkZ2V0KTApCiAgICB7CglpZiAoZ3VpLnNjcm9sbF9iZ19waXhlbCAhPSBJTlZBTENPTE9SKQoJewojaWYgKFhtVmVyc2lvbj49MTAwMikKCSAgICBYbUNoYW5nZUNvbG9yKHNiLT5pZCwgZ3VpLnNjcm9sbF9iZ19waXhlbCk7CiNlbHNlCgkgICAgWHRWYVNldFZhbHVlcyhzYi0+aWQsCgkJICAgIFhtTnRyb3VnaENvbG9yLCBndWkuc2Nyb2xsX2JnX3BpeGVsLAoJCSAgICBOVUxMKTsKI2VuZGlmCgl9CgoJaWYgKGd1aS5zY3JvbGxfZmdfcGl4ZWwgIT0gSU5WQUxDT0xPUikKCSAgICBYdFZhU2V0VmFsdWVzKHNiLT5pZCwKCQkgICAgWG1OZm9yZWdyb3VuZCwgZ3VpLnNjcm9sbF9mZ19waXhlbCwKI2lmIChYbVZlcnNpb248MTAwMikKCQkgICAgWG1OYmFja2dyb3VuZCwgZ3VpLnNjcm9sbF9mZ19waXhlbCwKI2VuZGlmCgkJICAgIE5VTEwpOwogICAgfQoKICAgIC8qIFRoaXMgaXMgbmVlZGVkIGZvciB0aGUgcmVjdGFuZ2xlIGJlbG93IHRoZSB2ZXJ0aWNhbCBzY3JvbGxiYXJzLiAqLwogICAgaWYgKHNiID09ICZndWkuYm90dG9tX3NiYXIgJiYgdGV4dEFyZWFGb3JtICE9IChXaWRnZXQpMCkKCWd1aV9tb3RpZl9zY3JvbGxfY29sb3JzKHRleHRBcmVhRm9ybSk7Cn0KCi8qCiAqIE1pc2NlbGxhbmVvdXMgc3R1ZmY6CiAqLwoKICAgIFdpbmRvdwpndWlfeDExX2dldF93aWQoKQp7CiAgICByZXR1cm4oWHRXaW5kb3codGV4dEFyZWEpKTsKfQoKLyoKICogTG9vayBmb3IgYSB3aWRnZXQgaW4gdGhlIHdpZGdldCB0cmVlIHcsIHdpdGggYSBtbmVtb25pYyBtYXRjaGluZyBrZXljb2RlLgogKiBXaGVuIG9uZSBpcyBmb3VuZCwgc2ltdWxhdGUgYSBidXR0b24gcHJlc3Mgb24gdGhhdCB3aWRnZXQgYW5kIGdpdmUgaXQgdGhlCiAqIGtleWJvYXJkIGZvY3VzLiAgSWYgdGhlIG1uZW1vbmljIGlzIG9uIGEgbGFiZWwsIGxvb2sgaW4gdGhlIHVzZXJEYXRhIGZpZWxkCiAqIG9mIHRoZSBsYWJlbCB0byBzZWUgaWYgaXQgcG9pbnRzIHRvIGFub3RoZXIgd2lkZ2V0LCBhbmQgZ2l2ZSB0aGF0IHRoZSBmb2N1cy4KICovCiAgICBzdGF0aWMgdm9pZApkb19tbmVtb25pYyhXaWRnZXQgdywgdW5zaWduZWQgaW50IGtleWNvZGUpCnsKICAgIFdpZGdldExpc3QJICAgIGNoaWxkcmVuOwogICAgaW50CQkgICAgbnVtQ2hpbGRyZW4sIGk7CiAgICBCb29sZWFuCSAgICBpc01lbnU7CiAgICBLZXlTeW0JICAgIG1uZW1vbmljID0gJ1wwJzsKICAgIGNoYXIJICAgIG1uZVN0cmluZ1syXTsKICAgIFdpZGdldAkgICAgdXNlckRhdGE7CiAgICB1bnNpZ25lZCBjaGFyICAgcm93Q29sVHlwZTsKCiAgICBpZiAoWHRJc0NvbXBvc2l0ZSh3KSkKICAgIHsKCWlmIChYdENsYXNzKHcpID09IHhtUm93Q29sdW1uV2lkZ2V0Q2xhc3MpCgl7CgkgICAgWHRWYUdldFZhbHVlcyh3LCBYbU5yb3dDb2x1bW5UeXBlLCAmcm93Q29sVHlwZSwgMCk7CgkgICAgaXNNZW51ID0gKHJvd0NvbFR5cGUgIT0gKHVuc2lnbmVkIGNoYXIpWG1XT1JLX0FSRUEpOwoJfQoJZWxzZQoJICAgIGlzTWVudSA9IEZhbHNlOwoJaWYgKCFpc01lbnUpCgl7CgkgICAgWHRWYUdldFZhbHVlcyh3LCBYbU5jaGlsZHJlbiwgJmNoaWxkcmVuLCBYbU5udW1DaGlsZHJlbiwKCQkJICAmbnVtQ2hpbGRyZW4sIDApOwoJICAgIGZvciAoaSA9IDA7IGkgPCBudW1DaGlsZHJlbjsgaSsrKQoJCWRvX21uZW1vbmljKGNoaWxkcmVuW2ldLCBrZXljb2RlKTsKCX0KICAgIH0KICAgIGVsc2UKICAgIHsKCVh0VmFHZXRWYWx1ZXModywgWG1ObW5lbW9uaWMsICZtbmVtb25pYywgMCk7CglpZiAobW5lbW9uaWMgIT0gJ1wwJykKCXsKCSAgICBtbmVTdHJpbmdbMF0gPSBtbmVtb25pYzsKCSAgICBtbmVTdHJpbmdbMV0gPSAnXDAnOwoJICAgIGlmIChYS2V5c3ltVG9LZXljb2RlKFh0RGlzcGxheShYdFBhcmVudCh3KSksCgkJCQkgICAgICAgWFN0cmluZ1RvS2V5c3ltKG1uZVN0cmluZykpID09IGtleWNvZGUpCgkgICAgewoJCWlmIChYdENsYXNzKHcpID09IHhtTGFiZWxXaWRnZXRDbGFzcwoJCQl8fCBYdENsYXNzKHcpID09IHhtTGFiZWxHYWRnZXRDbGFzcykKCQl7CgkJICAgIFh0VmFHZXRWYWx1ZXModywgWG1OdXNlckRhdGEsICZ1c2VyRGF0YSwgMCk7CgkJICAgIGlmICh1c2VyRGF0YSAhPSBOVUxMICYmIFh0SXNXaWRnZXQodXNlckRhdGEpKQoJCQlYbVByb2Nlc3NUcmF2ZXJzYWwodXNlckRhdGEsIFhtVFJBVkVSU0VfQ1VSUkVOVCk7CgkJfQoJCWVsc2UKCQl7CgkJICAgIFhLZXlQcmVzc2VkRXZlbnQga2V5RXZlbnQ7CgoJCSAgICBYbVByb2Nlc3NUcmF2ZXJzYWwodywgWG1UUkFWRVJTRV9DVVJSRU5UKTsKCgkJICAgIG1lbXNldCgoY2hhciAqKSAma2V5RXZlbnQsIDAsIHNpemVvZihYS2V5UHJlc3NlZEV2ZW50KSk7CgkJICAgIGtleUV2ZW50LnR5cGUgPSBLZXlQcmVzczsKCQkgICAga2V5RXZlbnQuc2VyaWFsID0gMTsKCQkgICAga2V5RXZlbnQuc2VuZF9ldmVudCA9IFRydWU7CgkJICAgIGtleUV2ZW50LmRpc3BsYXkgPSBYdERpc3BsYXkodyk7CgkJICAgIGtleUV2ZW50LndpbmRvdyA9IFh0V2luZG93KHcpOwoJCSAgICBYdENhbGxBY3Rpb25Qcm9jKHcsICJBY3RpdmF0ZSIsIChYRXZlbnQgKikgJiBrZXlFdmVudCwKCQkJCQkJCQkgICAgIE5VTEwsIDApOwoJCX0KCSAgICB9Cgl9CiAgICB9Cn0KCi8qCiAqIENhbGxiYWNrIHJvdXRpbmUgZm9yIGRpYWxvZyBtbmVtb25pYyBwcm9jZXNzaW5nLgogKi8KLypBUkdTVVNFRCovCiAgICBzdGF0aWMgdm9pZAptbmVtb25pY19ldmVudChXaWRnZXQgdywgWHRQb2ludGVyIGNhbGxfZGF0YSwgWEtleUV2ZW50ICpldmVudCkKewogICAgZG9fbW5lbW9uaWModywgZXZlbnQtPmtleWNvZGUpOwp9CgoKLyoKICogU2VhcmNoIHRoZSB3aWRnZXQgdHJlZSB1bmRlciB3IGZvciB3aWRnZXRzIHdpdGggbW5lbW9uaWNzLiAgV2hlbiBmb3VuZCwgYWRkCiAqIGEgcGFzc2l2ZSBncmFiIHRvIHRoZSBkaWFsb2cgd2lkZ2V0IGZvciB0aGUgbW5lbW9uaWMgY2hhcmFjdGVyLCB0aHVzCiAqIGRpcmVjdGluZyBtbmVtb25pYyBldmVudHMgdG8gdGhlIGRpYWxvZyB3aWRnZXQuCiAqLwogICAgc3RhdGljIHZvaWQKYWRkX21uZW1vbmljX2dyYWJzKFdpZGdldCBkaWFsb2csIFdpZGdldCB3KQp7CiAgICBjaGFyCSAgICBtbmVTdHJpbmdbMl07CiAgICBXaWRnZXRMaXN0CSAgICBjaGlsZHJlbjsKICAgIGludAkJICAgIG51bUNoaWxkcmVuLCBpOwogICAgQm9vbGVhbgkgICAgaXNNZW51OwogICAgS2V5U3ltCSAgICBtbmVtb25pYyA9ICdcMCc7CiAgICB1bnNpZ25lZCBjaGFyICAgcm93Q29sVHlwZTsKCiAgICBpZiAoWHRJc0NvbXBvc2l0ZSh3KSkKICAgIHsKCWlmIChYdENsYXNzKHcpID09IHhtUm93Q29sdW1uV2lkZ2V0Q2xhc3MpCgl7CgkgICAgWHRWYUdldFZhbHVlcyh3LCBYbU5yb3dDb2x1bW5UeXBlLCAmcm93Q29sVHlwZSwgMCk7CgkgICAgaXNNZW51ID0gKHJvd0NvbFR5cGUgIT0gKHVuc2lnbmVkIGNoYXIpWG1XT1JLX0FSRUEpOwoJfQoJZWxzZQoJICAgIGlzTWVudSA9IEZhbHNlOwoJaWYgKCFpc01lbnUpCgl7CgkgICAgWHRWYUdldFZhbHVlcyh3LCBYbU5jaGlsZHJlbiwgJmNoaWxkcmVuLCBYbU5udW1DaGlsZHJlbiwKCQkJCQkJCSAgICAgJm51bUNoaWxkcmVuLCAwKTsKCSAgICBmb3IgKGkgPSAwOyBpIDwgbnVtQ2hpbGRyZW47IGkrKykKCQlhZGRfbW5lbW9uaWNfZ3JhYnMoZGlhbG9nLCBjaGlsZHJlbltpXSk7Cgl9CiAgICB9CiAgICBlbHNlCiAgICB7CglYdFZhR2V0VmFsdWVzKHcsIFhtTm1uZW1vbmljLCAmbW5lbW9uaWMsIDApOwoJaWYgKG1uZW1vbmljICE9ICdcMCcpCgl7CgkgICAgbW5lU3RyaW5nWzBdID0gbW5lbW9uaWM7CgkgICAgbW5lU3RyaW5nWzFdID0gJ1wwJzsKCSAgICBYdEdyYWJLZXkoZGlhbG9nLCBYS2V5c3ltVG9LZXljb2RlKFh0RGlzcGxheShkaWFsb2cpLAoJCQkJCQkgIFhTdHJpbmdUb0tleXN5bShtbmVTdHJpbmcpKSwKCQkgICAgTW9kMU1hc2ssIFRydWUsIEdyYWJNb2RlQXN5bmMsIEdyYWJNb2RlQXN5bmMpOwoJfQogICAgfQp9CgovKgogKiBBZGQgYSBoYW5kbGVyIGZvciBtbmVtb25pY3MgaW4gYSBkaWFsb2cuICBNb3RpZiBpdHNlbGYgb25seSBoYW5kbGVzCiAqIG1uZW1vbmljcyBpbiBtZW51cy4gTW5lbW9uaWNzIGFkZGVkIG9yIGNoYW5nZWQgYWZ0ZXIgdGhpcyBjYWxsIHdpbGwgYmUKICogaWdub3JlZC4KICoKICogVG8gYWRkIGEgbW5lbW9uaWMgdG8gYSB0ZXh0IGZpZWxkIG9yIGxpc3QsIHNldCB0aGUgWG1ObW5lbW9uaWMgcmVzb3VyY2Ugb24KICogdGhlIGFwcHJvcHJpYXRlIGxhYmVsIGFuZCBzZXQgdGhlIFhtTnVzZXJEYXRhIHJlc291cmNlIG9mIHRoZSBsYWJlbCB0byB0aGUKICogd2lkZ2V0IHRvIGdldCB0aGUgZm9jdXMgd2hlbiB0aGUgbW5lbW9uaWMgaXMgdHlwZWQuCiAqLwogICAgc3RhdGljIHZvaWQKYWN0aXZhdGVfZGlhbG9nX21uZW1vbmljcyhXaWRnZXQgZGlhbG9nKQp7CiAgICBpZiAoIWRpYWxvZykKCXJldHVybjsKCiAgICBYdEFkZEV2ZW50SGFuZGxlcihkaWFsb2csIEtleVByZXNzTWFzaywgRmFsc2UsCgkJCSAgIChYdEV2ZW50SGFuZGxlcikgbW5lbW9uaWNfZXZlbnQsIChYdFBvaW50ZXIpIE5VTEwpOwogICAgYWRkX21uZW1vbmljX2dyYWJzKGRpYWxvZywgZGlhbG9nKTsKfQoKLyoKICogUmVtb3ZlcyB0aGUgZXZlbnQgaGFuZGxlciBhbmQga2V5LWdyYWJzIGZvciBkaWFsb2cgbW5lbW9uaWMgaGFuZGxpbmcuCiAqLwogICAgc3RhdGljIHZvaWQKc3VwcHJlc3NfZGlhbG9nX21uZW1vbmljcyhXaWRnZXQgZGlhbG9nKQp7CiAgICBpZiAoIWRpYWxvZykKCXJldHVybjsKCiAgICBYdFVuZ3JhYktleShkaWFsb2csIEFueUtleSwgTW9kMU1hc2spOwogICAgWHRSZW1vdmVFdmVudEhhbmRsZXIoZGlhbG9nLCBLZXlQcmVzc01hc2ssIEZhbHNlLAoJCQkgICAoWHRFdmVudEhhbmRsZXIpIG1uZW1vbmljX2V2ZW50LCAoWHRQb2ludGVyKSBOVUxMKTsKfQoKI2lmIGRlZmluZWQoRkVBVF9CUk9XU0UpIHx8IGRlZmluZWQoRkVBVF9HVUlfRElBTE9HKQpzdGF0aWMgdm9pZCBzZXRfZm9udGxpc3QgX19BUkdTKChXaWRnZXQgd2cpKTsKCi8qCiAqIFVzZSB0aGUgJ2d1aWZvbnQnIG9yICdndWlmb250c2V0JyBhcyBhIGZvbnRsaXN0IGZvciBhIGRpYWxvZyB3aWRnZXQuCiAqLwogICAgc3RhdGljIHZvaWQKc2V0X2ZvbnRsaXN0KGlkKQogICAgV2lkZ2V0IGlkOwp7CiAgICBYbUZvbnRMaXN0IGZsOwoKI2lmZGVmIEZPTlRTRVRfQUxXQVlTCiAgICBpZiAoZ3VpLmZvbnRzZXQgIT0gTk9GT05UU0VUKQogICAgewoJZmwgPSBndWlfbW90aWZfZm9udHNldDJmb250bGlzdCgoWEZvbnRTZXQgKikmZ3VpLmZvbnRzZXQpOwoJaWYgKGZsICE9IE5VTEwpCgl7CgkgICAgaWYgKFh0SXNNYW5hZ2VkKGlkKSkKCSAgICB7CgkJWHRVbm1hbmFnZUNoaWxkKGlkKTsKCQlYdFZhU2V0VmFsdWVzKGlkLCBYbU5mb250TGlzdCwgZmwsIE5VTEwpOwoJCS8qIFdlIHNob3VsZCBmb3JjZSB0aGUgd2lkZ2V0IHRvIHJlY2FsY3VsYXRlIGl0J3MKCQkgKiBnZW9tZXRyeSBub3cuICovCgkJWHRNYW5hZ2VDaGlsZChpZCk7CgkgICAgfQoJICAgIGVsc2UKCQlYdFZhU2V0VmFsdWVzKGlkLCBYbU5mb250TGlzdCwgZmwsIE5VTEwpOwoJICAgIFhtRm9udExpc3RGcmVlKGZsKTsKCX0KICAgIH0KI2Vsc2UKICAgIGlmIChndWkubm9ybV9mb250ICE9IE5PRk9OVCkKICAgIHsKCWZsID0gZ3VpX21vdGlmX2NyZWF0ZV9mb250bGlzdCgoWEZvbnRTdHJ1Y3QgKilndWkubm9ybV9mb250KTsKCWlmIChmbCAhPSBOVUxMKQoJewoJICAgIGlmIChYdElzTWFuYWdlZChpZCkpCgkgICAgewoJCVh0VW5tYW5hZ2VDaGlsZChpZCk7CgkJWHRWYVNldFZhbHVlcyhpZCwgWG1OZm9udExpc3QsIGZsLCBOVUxMKTsKCQkvKiBXZSBzaG91bGQgZm9yY2UgdGhlIHdpZGdldCB0byByZWNhbGN1bGF0ZSBpdCdzCgkJICogZ2VvbWV0cnkgbm93LiAqLwoJCVh0TWFuYWdlQ2hpbGQoaWQpOwoJICAgIH0KCSAgICBlbHNlCgkJWHRWYVNldFZhbHVlcyhpZCwgWG1OZm9udExpc3QsIGZsLCBOVUxMKTsKCSAgICBYbUZvbnRMaXN0RnJlZShmbCk7Cgl9CiAgICB9CiNlbmRpZgp9CiNlbmRpZgoKI2lmIGRlZmluZWQoRkVBVF9CUk9XU0UpIHx8IGRlZmluZWQoUFJPVE8pCgovKgogKiBmaWxlIHNlbGVjdG9yIHJlbGF0ZWQgc3R1ZmYKICovCgojaW5jbHVkZSA8WG0vRmlsZVNCLmg+CiNpbmNsdWRlIDxYbS9YbVN0ckRlZnMuaD4KCnR5cGVkZWYgc3RydWN0IGRpYWxvZ19jYWxsYmFja19hcmcKewogICAgY2hhciAqICBhcmdzOyAgIC8qIG5vdCB1c2VkIHJpZ2h0IG5vdyAqLwogICAgaW50CSAgICBpZDsKfSBkY2JhcmdfVDsKCnN0YXRpYyBXaWRnZXQgZGlhbG9nX3dndDsKc3RhdGljIGNoYXIgKmJyb3dzZV9mbmFtZSA9IE5VTEw7CnN0YXRpYyBYbVN0cmluZ0NoYXJTZXQgY2hhcnNldCA9IChYbVN0cmluZ0NoYXJTZXQpIFhtU1RSSU5HX0RFRkFVTFRfQ0hBUlNFVDsKCQkJCS8qIHVzZWQgdG8gc2V0IHVwIFhtU3RyaW5ncyAqLwoKc3RhdGljIHZvaWQgRGlhbG9nQ2FuY2VsQ0IgX19BUkdTKChXaWRnZXQsIFh0UG9pbnRlciwgWHRQb2ludGVyKSk7CnN0YXRpYyB2b2lkIERpYWxvZ0FjY2VwdENCIF9fQVJHUygoV2lkZ2V0LCBYdFBvaW50ZXIsIFh0UG9pbnRlcikpOwoKLyoKICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIHRyYW5zbGF0ZSB0aGUgcHJlZGVmaW5lZCBsYWJlbCB0ZXh0IG9mIHRoZQogKiBwcmVjb21wb3NlZCBkaWFsb2dzLiBXZSBkbyB0aGlzIGV4cGxpY2l0bHkgdG8gYWxsb3c6CiAqCiAqIC0gdXNhZ2Ugb2YgZ2V0dGV4dCBmb3IgdHJhbnNsYXRpb24sIGFzIGluIGFsbCB0aGUgb3RoZXIgcGxhY2VzLgogKgogKiAtIGVxdWFsaXplIHRoZSBtZXNzYWdlcyBiZXR3ZWVuIGRpZmZlcmVudCBHVUkgaW1wbGVtZW50YXRpb25zIGFzIGZhciBhcwogKiBwb3NzaWJsZS4KICovCnN0YXRpYyB2b2lkIHNldF9wcmVkZWZpbmVkX2xhYmVsIF9fQVJHUygoV2lkZ2V0IHBhcmVudCwgU3RyaW5nIG5hbWUsIGNoYXIgKm5ld19sYWJlbCkpOwoKc3RhdGljIHZvaWQKc2V0X3ByZWRlZmluZWRfbGFiZWwocGFyZW50LCBuYW1lLCBuZXdfbGFiZWwpCiAgICBXaWRnZXQgIHBhcmVudDsKICAgIFN0cmluZyAgbmFtZTsKICAgIGNoYXIgICAgKm5ld19sYWJlbDsKewogICAgWG1TdHJpbmcJc3RyOwogICAgV2lkZ2V0CXc7CiAgICBjaGFyX3UJKnAsICpuZXh0OwogICAgS2V5U3ltCW1uZW1vbmljID0gTlVMOwoKICAgIHcgPSBYdE5hbWVUb1dpZGdldChwYXJlbnQsIG5hbWUpOwoKICAgIGlmICghdykKCXJldHVybjsKCiAgICBwID0gdmltX3N0cnNhdmUoKGNoYXJfdSAqKW5ld19sYWJlbCk7CiAgICBpZiAocCA9PSBOVUxMKQoJcmV0dXJuOwogICAgZm9yIChuZXh0ID0gcDsgKm5leHQ7ICsrbmV4dCkKICAgIHsKCWlmICgqbmV4dCA9PSBETEdfSE9US0VZX0NIQVIpCgl7CgkgICAgaW50IGxlbiA9IFNUUkxFTihuZXh0KTsKCgkgICAgaWYgKGxlbiA+IDApCgkgICAgewoJCW1jaF9tZW1tb3ZlKG5leHQsIG5leHQgKyAxLCBsZW4pOwoJCW1uZW1vbmljID0gbmV4dFswXTsKCSAgICB9Cgl9CiAgICB9CgogICAgc3RyID0gWG1TdHJpbmdDcmVhdGUoKGNoYXIgKilwLCBTVFJJTkdfVEFHKTsKICAgIHZpbV9mcmVlKHApOwoKICAgIGlmIChzdHIgIT0gTlVMTCkKICAgIHsKCVh0VmFTZXRWYWx1ZXModywKCQlYbU5sYWJlbFN0cmluZywgc3RyLAoJCVhtTm1uZW1vbmljLCBtbmVtb25pYywKCQlOVUxMKTsKCVhtU3RyaW5nRnJlZShzdHIpOwogICAgfQogICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3Qodyk7Cn0KCnN0YXRpYyB2b2lkCnNldF9wcmVkZWZpbmVkX2ZvbnRsaXN0KHBhcmVudCwgbmFtZSkKICAgIFdpZGdldCBwYXJlbnQ7CiAgICBTdHJpbmcgbmFtZTsKewogICAgV2lkZ2V0IHc7CiAgICB3ID0gWHROYW1lVG9XaWRnZXQocGFyZW50LCBuYW1lKTsKCiAgICBpZiAoIXcpCglyZXR1cm47CgogICAgc2V0X2ZvbnRsaXN0KHcpOwp9CgovKgogKiBQdXQgdXAgYSBmaWxlIHJlcXVlc3Rlci4KICogUmV0dXJucyB0aGUgc2VsZWN0ZWQgbmFtZSBpbiBhbGxvY2F0ZWQgbWVtb3J5LCBvciBOVUxMIGZvciBDYW5jZWwuCiAqLwovKiBBUkdTVVNFRCAqLwogICAgY2hhcl91ICoKZ3VpX21jaF9icm93c2Uoc2F2aW5nLCB0aXRsZSwgZGZsdCwgZXh0LCBpbml0ZGlyLCBmaWx0ZXIpCiAgICBpbnQJCXNhdmluZzsJCS8qIHNlbGVjdCBmaWxlIHRvIHdyaXRlICovCiAgICBjaGFyX3UJKnRpdGxlOwkJLyogdGl0bGUgZm9yIHRoZSB3aW5kb3cgKi8KICAgIGNoYXJfdQkqZGZsdDsJCS8qIGRlZmF1bHQgbmFtZSAqLwogICAgY2hhcl91CSpleHQ7CQkvKiBub3QgdXNlZCAoZXh0ZW5zaW9uIGFkZGVkKSAqLwogICAgY2hhcl91CSppbml0ZGlyOwkvKiBpbml0aWFsIGRpcmVjdG9yeSwgTlVMTCBmb3IgY3VycmVudCBkaXIgKi8KICAgIGNoYXJfdQkqZmlsdGVyOwkvKiBmaWxlIG5hbWUgZmlsdGVyICovCnsKICAgIGNoYXJfdQlkaXJidWZbTUFYUEFUSExdOwogICAgY2hhcl91CWRmbHRidWZbTUFYUEFUSExdOwogICAgY2hhcl91CSpwYXR0ZXJuOwogICAgY2hhcl91CSp0b2ZyZWUgPSBOVUxMOwoKICAgIC8qIFRoZXJlIGEgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSByZXNvdXJjZSBuYW1lIGFuZCB2YWx1ZSwgVGhlcmVmb3JlLCB3ZQogICAgICogYXZvaWQgdG8gKGFiLSl1c2UgdGhlIChtYXliZSBpbnRlcm5hdGlvbmFsaXplZCEpIGRpYWxvZyB0aXRsZSBhcyBhCiAgICAgKiBkaWFsb2cgbmFtZS4KICAgICAqLwoKICAgIGRpYWxvZ193Z3QgPSBYbUNyZWF0ZUZpbGVTZWxlY3Rpb25EaWFsb2codmltU2hlbGwsICJicm93c2VEaWFsb2ciLCBOVUxMLCAwKTsKCiAgICBpZiAoaW5pdGRpciA9PSBOVUxMIHx8ICppbml0ZGlyID09IE5VTCkKICAgIHsKCW1jaF9kaXJuYW1lKGRpcmJ1ZiwgTUFYUEFUSEwpOwoJaW5pdGRpciA9IGRpcmJ1ZjsKICAgIH0KCiAgICBpZiAoZGZsdCA9PSBOVUxMKQoJZGZsdCA9IChjaGFyX3UgKikiIjsKICAgIGVsc2UgaWYgKFNUUkxFTihpbml0ZGlyKSArIFNUUkxFTihkZmx0KSArIDIgPCBNQVhQQVRITCkKICAgIHsKCS8qIFRoZSBkZWZhdWx0IHNlbGVjdGlvbiBzaG91bGQgYmUgdGhlIGZ1bGwgcGF0aCwgImRmbHQiIGlzIG9ubHkgdGhlCgkgKiBmaWxlIG5hbWUuICovCglTVFJDUFkoZGZsdGJ1ZiwgaW5pdGRpcik7CglhZGRfcGF0aHNlcChkZmx0YnVmKTsKCVNUUkNBVChkZmx0YnVmLCBkZmx0KTsKCWRmbHQgPSBkZmx0YnVmOwogICAgfQoKICAgIC8qIENhbiBvbmx5IHVzZSBvbmUgcGF0dGVybiBmb3IgYSBmaWxlIG5hbWUuICBHZXQgdGhlIGZpcnN0IHBhdHRlcm4gb3V0IG9mCiAgICAgKiB0aGUgZmlsdGVyLiAgQW4gZW1wdHkgcGF0dGVybiBtZWFucyBldmVyeXRoaW5nIG1hdGNoZXMuICovCiAgICBpZiAoZmlsdGVyID09IE5VTEwpCglwYXR0ZXJuID0gKGNoYXJfdSAqKSIiOwogICAgZWxzZQogICAgewoJY2hhcl91CSpzLCAqcDsKCglzID0gZmlsdGVyOwoJZm9yIChwID0gZmlsdGVyOyAqcCAhPSBOVUw7ICsrcCkKCXsKCSAgICBpZiAoKnAgPT0gJ1x0JykJLyogZW5kIG9mIGRlc2NyaXB0aW9uLCBzdGFydCBvZiBwYXR0ZXJuICovCgkJcyA9IHAgKyAxOwoJICAgIGlmICgqcCA9PSAnOycgfHwgKnAgPT0gJ1xuJykJLyogZW5kIG9mIChmaXJzdCkgcGF0dGVybiAqLwoJCWJyZWFrOwoJfQoJcGF0dGVybiA9IHZpbV9zdHJuc2F2ZShzLCBwIC0gcyk7Cgl0b2ZyZWUgPSBwYXR0ZXJuOwoJaWYgKHBhdHRlcm4gPT0gTlVMTCkKCSAgICBwYXR0ZXJuID0gKGNoYXJfdSAqKSIiOwogICAgfQoKICAgIFh0VmFTZXRWYWx1ZXMoZGlhbG9nX3dndCwKCVh0VmFUeXBlZEFyZywKCSAgICBYbU5kaXJlY3RvcnksIFhtUlN0cmluZywgKGNoYXIgKilpbml0ZGlyLCBTVFJMRU4oaW5pdGRpcikgKyAxLAoJWHRWYVR5cGVkQXJnLAoJICAgIFhtTmRpclNwZWMsCVhtUlN0cmluZywgKGNoYXIgKilkZmx0LCBTVFJMRU4oZGZsdCkgKyAxLAoJWHRWYVR5cGVkQXJnLAoJICAgIFhtTnBhdHRlcm4sCVhtUlN0cmluZywgKGNoYXIgKilwYXR0ZXJuLCBTVFJMRU4ocGF0dGVybikgKyAxLAoJWHRWYVR5cGVkQXJnLAoJICAgIFhtTmRpYWxvZ1RpdGxlLCBYbVJTdHJpbmcsIChjaGFyICopdGl0bGUsIFNUUkxFTih0aXRsZSkgKyAxLAoJTlVMTCk7CgogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIkFwcGx5IiwgXygiJkZpbHRlciIpKTsKICAgIHNldF9wcmVkZWZpbmVkX2xhYmVsKGRpYWxvZ193Z3QsICJDYW5jZWwiLCBfKCImQ2FuY2VsIikpOwogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIkRpciIsIF8oIkRpcmVjdG9yaWVzIikpOwogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIkZpbHRlckxhYmVsIiwgXygiRmlsdGVyIikpOwogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIkhlbHAiLCBfKCImSGVscCIpKTsKICAgIHNldF9wcmVkZWZpbmVkX2xhYmVsKGRpYWxvZ193Z3QsICJJdGVtcyIsIF8oIkZpbGVzIikpOwogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIk9LIiwgXygiJk9LIikpOwogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIlNlbGVjdGlvbiIsIF8oIlNlbGVjdGlvbiIpKTsKCiAgICAvKiBUaGlzIGlzIHRvIHNhdmUgdXMgZnJvbSBzaWxseSBleHRlcm5hbCBzZXR0aW5ncyB1c2luZyBub3QgZml4ZWQgd2l0aAogICAgICogZm9udHMgZm9yIGZpbGUgc2VsZWN0aW9uLgogICAgICovCiAgICBzZXRfcHJlZGVmaW5lZF9mb250bGlzdChkaWFsb2dfd2d0LCAiRGlyTGlzdFNXLkRpckxpc3QiKTsKICAgIHNldF9wcmVkZWZpbmVkX2ZvbnRsaXN0KGRpYWxvZ193Z3QsICJJdGVtc0xpc3RTVy5JdGVtc0xpc3QiKTsKCiAgICBndWlfbW90aWZfbWVudV9jb2xvcnMoZGlhbG9nX3dndCk7CiAgICBpZiAoZ3VpLnNjcm9sbF9iZ19waXhlbCAhPSBJTlZBTENPTE9SKQoJWHRWYVNldFZhbHVlcyhkaWFsb2dfd2d0LCBYbU50cm91Z2hDb2xvciwgZ3VpLnNjcm9sbF9iZ19waXhlbCwgTlVMTCk7CgogICAgWHRBZGRDYWxsYmFjayhkaWFsb2dfd2d0LCBYbU5va0NhbGxiYWNrLCBEaWFsb2dBY2NlcHRDQiwgKFh0UG9pbnRlcikwKTsKICAgIFh0QWRkQ2FsbGJhY2soZGlhbG9nX3dndCwgWG1OY2FuY2VsQ2FsbGJhY2ssIERpYWxvZ0NhbmNlbENCLCAoWHRQb2ludGVyKTApOwogICAgLyogV2UgaGF2ZSBubyBoZWxwIGluIHRoaXMgd2luZG93LCBzbyBoaWRlIGhlbHAgYnV0dG9uICovCiAgICBYdFVubWFuYWdlQ2hpbGQoWG1GaWxlU2VsZWN0aW9uQm94R2V0Q2hpbGQoZGlhbG9nX3dndCwKCQkJCQkodW5zaWduZWQgY2hhcilYbURJQUxPR19IRUxQX0JVVFRPTikpOwoKICAgIG1hbmFnZV9jZW50ZXJlZChkaWFsb2dfd2d0KTsKICAgIGFjdGl2YXRlX2RpYWxvZ19tbmVtb25pY3MoZGlhbG9nX3dndCk7CgogICAgLyogc2l0IGluIGEgbG9vcCB1bnRpbCB0aGUgZGlhbG9nIGJveCBoYXMgZ29uZSBhd2F5ICovCiAgICBkbwogICAgewoJWHRBcHBQcm9jZXNzRXZlbnQoWHRXaWRnZXRUb0FwcGxpY2F0aW9uQ29udGV4dChkaWFsb2dfd2d0KSwKCSAgICAoWHRJbnB1dE1hc2spWHRJTUFsbCk7CiAgICB9IHdoaWxlIChYdElzTWFuYWdlZChkaWFsb2dfd2d0KSk7CgogICAgc3VwcHJlc3NfZGlhbG9nX21uZW1vbmljcyhkaWFsb2dfd2d0KTsKICAgIFh0RGVzdHJveVdpZGdldChkaWFsb2dfd2d0KTsKICAgIHZpbV9mcmVlKHRvZnJlZSk7CgogICAgaWYgKGJyb3dzZV9mbmFtZSA9PSBOVUxMKQoJcmV0dXJuIE5VTEw7CiAgICByZXR1cm4gdmltX3N0cnNhdmUoKGNoYXJfdSAqKWJyb3dzZV9mbmFtZSk7Cn0KCi8qCiAqIFRoZSBjb2RlIGJlbG93IHdhcyBvcmlnaW5hbGx5IHRha2VuIGZyb20KICoJL3Vzci9leGFtcGxlcy9tb3RpZi94bXNhbXBsZXJzL3htZWRpdG9yLmMKICogb24gRGlnaXRhbCBVbml4IDQuMGQsIGJ1dCBoZWF2aWx5IG1vZGlmaWVkLgogKi8KCi8qCiAqIFByb2Nlc3MgY2FsbGJhY2sgZnJvbSBEaWFsb2cgY2FuY2VsIGFjdGlvbnMuCiAqLwovKiBBUkdTVVNFRCAqLwogICAgc3RhdGljIHZvaWQKRGlhbG9nQ2FuY2VsQ0IodywgY2xpZW50X2RhdGEsIGNhbGxfZGF0YSkKICAgIFdpZGdldAl3OwkJLyogIHdpZGdldCBpZAkJKi8KICAgIFh0UG9pbnRlcgljbGllbnRfZGF0YTsJLyogIGRhdGEgZnJvbSBhcHBsaWNhdGlvbiAgICovCiAgICBYdFBvaW50ZXIJY2FsbF9kYXRhOwkvKiAgZGF0YSBmcm9tIHdpZGdldCBjbGFzcyAgKi8KewogICAgaWYgKGJyb3dzZV9mbmFtZSAhPSBOVUxMKQogICAgewoJWHRGcmVlKGJyb3dzZV9mbmFtZSk7Cglicm93c2VfZm5hbWUgPSBOVUxMOwogICAgfQogICAgWHRVbm1hbmFnZUNoaWxkKGRpYWxvZ193Z3QpOwp9CgovKgogKiBQcm9jZXNzIGNhbGxiYWNrIGZyb20gRGlhbG9nIGFjdGlvbnMuCiAqLwovKiBBUkdTVVNFRCAqLwogICAgc3RhdGljIHZvaWQKRGlhbG9nQWNjZXB0Q0IodywgY2xpZW50X2RhdGEsIGNhbGxfZGF0YSkKICAgIFdpZGdldAl3OwkJLyogIHdpZGdldCBpZAkJKi8KICAgIFh0UG9pbnRlcgljbGllbnRfZGF0YTsJLyogIGRhdGEgZnJvbSBhcHBsaWNhdGlvbiAgICovCiAgICBYdFBvaW50ZXIJY2FsbF9kYXRhOwkvKiAgZGF0YSBmcm9tIHdpZGdldCBjbGFzcyAgKi8KewogICAgWG1GaWxlU2VsZWN0aW9uQm94Q2FsbGJhY2tTdHJ1Y3QgKmZjYjsKCiAgICBpZiAoYnJvd3NlX2ZuYW1lICE9IE5VTEwpCiAgICB7CglYdEZyZWUoYnJvd3NlX2ZuYW1lKTsKCWJyb3dzZV9mbmFtZSA9IE5VTEw7CiAgICB9CiAgICBmY2IgPSAoWG1GaWxlU2VsZWN0aW9uQm94Q2FsbGJhY2tTdHJ1Y3QgKiljYWxsX2RhdGE7CgogICAgLyogZ2V0IHRoZSBmaWxlbmFtZSBmcm9tIHRoZSBmaWxlIHNlbGVjdGlvbiBib3ggKi8KICAgIFhtU3RyaW5nR2V0THRvUihmY2ItPnZhbHVlLCBjaGFyc2V0LCAmYnJvd3NlX2ZuYW1lKTsKCiAgICAvKiBwb3Bkb3duIHRoZSBmaWxlIHNlbGVjdGlvbiBib3ggKi8KICAgIFh0VW5tYW5hZ2VDaGlsZChkaWFsb2dfd2d0KTsKfQoKI2VuZGlmIC8qIEZFQVRfQlJPV1NFICovCgojaWYgZGVmaW5lZChGRUFUX0dVSV9ESUFMT0cpIHx8IGRlZmluZWQoUFJPVE8pCgpzdGF0aWMgaW50CWRpYWxvZ1N0YXR1czsKCnN0YXRpYyB2b2lkIGtleWhpdF9jYWxsYmFjayBfX0FSR1MoKFdpZGdldCB3LCBYdFBvaW50ZXIgY2xpZW50X2RhdGEsIFhFdmVudCAqZXZlbnQsIEJvb2xlYW4gKmNvbnQpKTsKc3RhdGljIHZvaWQgYnV0cHJvYyBfX0FSR1MoKFdpZGdldCB3LCBYdFBvaW50ZXIgY2xpZW50X2RhdGEsIFh0UG9pbnRlciBjYWxsX2RhdGEpKTsKCi8qCiAqIENhbGxiYWNrIGZ1bmN0aW9uIGZvciB0aGUgdGV4dGZpZWxkLiAgV2hlbiBDUiBpcyBoaXQgdGhpcyB3b3JrcyBsaWtlCiAqIGhpdHRpbmcgdGhlICJPSyIgYnV0dG9uLCBFU0MgbGlrZSAiQ2FuY2VsIi4KICovCi8qIEFSR1NVU0VEICovCiAgICBzdGF0aWMgdm9pZAprZXloaXRfY2FsbGJhY2sodywgY2xpZW50X2RhdGEsIGV2ZW50LCBjb250KQogICAgV2lkZ2V0CQl3OwogICAgWHRQb2ludGVyCQljbGllbnRfZGF0YTsKICAgIFhFdmVudAkJKmV2ZW50OwogICAgQm9vbGVhbgkJKmNvbnQ7CnsKICAgIGNoYXIJYnVmWzJdOwogICAgS2V5U3ltCWtleV9zeW07CgogICAgaWYgKFhMb29rdXBTdHJpbmcoJihldmVudC0+eGtleSksIGJ1ZiwgMiwgJmtleV9zeW0sIE5VTEwpID09IDEpCiAgICB7CglpZiAoKmJ1ZiA9PSBDQVIpCgkgICAgZGlhbG9nU3RhdHVzID0gMTsKCWVsc2UgaWYgKCpidWYgPT0gRVNDKQoJICAgIGRpYWxvZ1N0YXR1cyA9IDI7CiAgICB9CiAgICBpZiAoKGtleV9zeW0gPT0gWEtfTGVmdCB8fCBrZXlfc3ltID09IFhLX1JpZ2h0KQoJICAgICYmICEoZXZlbnQtPnhrZXkuc3RhdGUgJiBTaGlmdE1hc2spKQoJWG1UZXh0RmllbGRDbGVhclNlbGVjdGlvbih3LCBYdExhc3RUaW1lc3RhbXBQcm9jZXNzZWQoZ3VpLmRweSkpOwp9CgovKiBBUkdTVVNFRCAqLwogICAgc3RhdGljIHZvaWQKYnV0cHJvYyh3LCBjbGllbnRfZGF0YSwgY2FsbF9kYXRhKQogICAgV2lkZ2V0CXc7CiAgICBYdFBvaW50ZXIJY2xpZW50X2RhdGE7CiAgICBYdFBvaW50ZXIJY2FsbF9kYXRhOwp7CiAgICBkaWFsb2dTdGF0dXMgPSAoaW50KShsb25nKWNsaWVudF9kYXRhICsgMTsKfQoKI2lmZGVmIEhBVkVfWFBNCgpzdGF0aWMgV2lkZ2V0IGNyZWF0ZV9waXhtYXBfbGFiZWwoV2lkZ2V0IHBhcmVudCwgU3RyaW5nIG5hbWUsIGNoYXIgKipkYXRhLCBBcmdMaXN0IGFyZ3MsIENhcmRpbmFsIGFyZyk7CgogICAgc3RhdGljIFdpZGdldApjcmVhdGVfcGl4bWFwX2xhYmVsKHBhcmVudCwgbmFtZSwgZGF0YSwgYXJncywgYXJnKQogICAgV2lkZ2V0CXBhcmVudDsKICAgIFN0cmluZwluYW1lOwogICAgY2hhcgkqKmRhdGE7CiAgICBBcmdMaXN0CWFyZ3M7CiAgICBDYXJkaW5hbAlhcmc7CnsKICAgIFdpZGdldAkJbGFiZWw7CiAgICBEaXNwbGF5CQkqZHNwOwogICAgU2NyZWVuCQkqc2NyOwogICAgaW50CQkJZGVwdGg7CiAgICBQaXhtYXAJCXBpeG1hcCA9IDA7CiAgICBYcG1BdHRyaWJ1dGVzCWF0dHI7CiAgICBCb29sZWFuCQlyczsKICAgIFhwbUNvbG9yU3ltYm9sCWNvbG9yWzVdID0KICAgIHsKCXsibm9uZSIsIE5VTEwsIDB9LAoJeyJpY29uQ29sb3IxIiwgTlVMTCwgMH0sCgl7ImJvdHRvbVNoYWRvd0NvbG9yIiwgTlVMTCwgMH0sCgl7InRvcFNoYWRvd0NvbG9yIiwgTlVMTCwgMH0sCgl7InNlbGVjdENvbG9yIiwgTlVMTCwgMH0KICAgIH07CgogICAgbGFiZWwgPSBYbUNyZWF0ZUxhYmVsR2FkZ2V0KHBhcmVudCwgbmFtZSwgYXJncywgYXJnKTsKCiAgICAvKgogICAgICogV2UgbmVlZCB0byBiZSBjYXJlZnVsbCBoZXJlLCBzaW5jZSBpbiBjYXNlIG9mIGdhZGdldHMsIHRoZXJlIGlzCiAgICAgKiBubyB3YXkgdG8gZ2V0IHRoZSBiYWNrZ3JvdW5kIGNvbG9yIGRpcmVjdGx5IGZyb20gdGhlIHdpZGdldCBpdHNlbGYuCiAgICAgKiBJbiBzdWNoIGNhc2VzIHdlIGdldCBpdCBmcm9tIFRoZSBDb3JlIHBhcnQgb2YgaGlzIHBhcmVudCBpbnN0ZWFkLgogICAgICovCiAgICBkc3AgPSBYdERpc3BsYXlPZk9iamVjdChsYWJlbCk7CiAgICBzY3IgPSBYdFNjcmVlbk9mT2JqZWN0KGxhYmVsKTsKICAgIFh0VmFHZXRWYWx1ZXMoWHRJc1N1YmNsYXNzKGxhYmVsLCBjb3JlV2lkZ2V0Q2xhc3MpCgkgICAgPyAgbGFiZWwgOiBYdFBhcmVudChsYWJlbCksCgkJICBYbU5kZXB0aCwgJmRlcHRoLAoJCSAgWG1OYmFja2dyb3VuZCwgJmNvbG9yWzBdLnBpeGVsLAoJCSAgWG1OZm9yZWdyb3VuZCwgJmNvbG9yWzFdLnBpeGVsLAoJCSAgWG1OYm90dG9tU2hhZG93Q29sb3IsICZjb2xvclsyXS5waXhlbCwKCQkgIFhtTnRvcFNoYWRvd0NvbG9yLCAmY29sb3JbM10ucGl4ZWwsCgkJICBYbU5oaWdobGlnaHQsICZjb2xvcls0XS5waXhlbCwKCQkgIE5VTEwpOwoKICAgIGF0dHIudmFsdWVtYXNrID0gWHBtQ29sb3JTeW1ib2xzIHwgWHBtQ2xvc2VuZXNzIHwgWHBtRGVwdGg7CiAgICBhdHRyLmNvbG9yc3ltYm9scyA9IGNvbG9yOwogICAgYXR0ci5udW1zeW1ib2xzID0gNTsKICAgIGF0dHIuY2xvc2VuZXNzID0gNjU1MzU7CiAgICBhdHRyLmRlcHRoID0gZGVwdGg7CiAgICBYcG1DcmVhdGVQaXhtYXBGcm9tRGF0YShkc3AsIFJvb3RXaW5kb3dPZlNjcmVlbihzY3IpLAoJCSAgICBkYXRhLCAmcGl4bWFwLCBOVUxMLCAmYXR0cik7CgogICAgWHRWYUdldFZhbHVlcyhsYWJlbCwgWG1OcmVjb21wdXRlU2l6ZSwgJnJzLCBOVUxMKTsKICAgIFh0VmFTZXRWYWx1ZXMobGFiZWwsIFhtTnJlY29tcHV0ZVNpemUsIFRydWUsIE5VTEwpOwogICAgWHRWYVNldFZhbHVlcyhsYWJlbCwKCSAgICBYbU5sYWJlbFR5cGUsIFhtUElYTUFQLAoJICAgIFhtTmxhYmVsUGl4bWFwLCBwaXhtYXAsCgkgICAgTlVMTCk7CiAgICBYdFZhU2V0VmFsdWVzKGxhYmVsLCBYbU5yZWNvbXB1dGVTaXplLCBycywgTlVMTCk7CgogICAgcmV0dXJuIGxhYmVsOwp9CiNlbmRpZgoKLyogQVJHU1VTRUQgKi8KICAgIGludApndWlfbWNoX2RpYWxvZyh0eXBlLCB0aXRsZSwgbWVzc2FnZSwgYnV0dG9uX25hbWVzLCBkZmx0YnV0dG9uLCB0ZXh0ZmllbGQpCiAgICBpbnQJCXR5cGU7CiAgICBjaGFyX3UJKnRpdGxlOwogICAgY2hhcl91CSptZXNzYWdlOwogICAgY2hhcl91CSpidXR0b25fbmFtZXM7CiAgICBpbnQJCWRmbHRidXR0b247CiAgICBjaGFyX3UJKnRleHRmaWVsZDsJCS8qIGJ1ZmZlciBvZiBzaXplIElPU0laRSAqLwp7CiAgICBjaGFyX3UJCSpidXRzOwogICAgY2hhcl91CQkqcCwgKm5leHQ7CiAgICBYdEFwcENvbnRleHQJYXBwOwogICAgWG1TdHJpbmcJCWxhYmVsOwogICAgaW50CQkJYnV0Y291bnQ7CiAgICBXaWRnZXQJCXc7CiAgICBXaWRnZXQJCWRpYWxvZ2Zvcm0gPSBOVUxMOwogICAgV2lkZ2V0CQlmb3JtID0gTlVMTDsKICAgIFdpZGdldAkJZGlhbG9ndGV4dGZpZWxkID0gTlVMTDsKICAgIFdpZGdldAkJKmJ1dHRvbnM7CiAgICBXaWRnZXQJCXNlcF9mb3JtID0gTlVMTDsKICAgIEJvb2xlYW4JCXZlcnRpY2FsOwogICAgV2lkZ2V0CQlzZXBhcmF0b3IgPSBOVUxMOwogICAgaW50CQkJbjsKICAgIEFyZwkJCWFyZ3NbNl07CiNpZmRlZiBIQVZFX1hQTQogICAgY2hhcgkJKippY29uX2RhdGEgPSBOVUxMOwogICAgV2lkZ2V0CQlkaWFsb2dwaXhtYXAgPSBOVUxMOwojZW5kaWYKCiAgICBpZiAodGl0bGUgPT0gTlVMTCkKCXRpdGxlID0gKGNoYXJfdSAqKV8oIlZpbSBkaWFsb2ciKTsKCiAgICAvKiBpZiBvdXIgcG9pbnRlciBpcyBjdXJyZW50bHkgaGlkZGVuLCB0aGVuIHdlIHNob3VsZCBzaG93IGl0LiAqLwogICAgZ3VpX21jaF9tb3VzZWhpZGUoRkFMU0UpOwoKICAgIGRpYWxvZ2Zvcm0gPSBYbUNyZWF0ZUZvcm1EaWFsb2codmltU2hlbGwsIChjaGFyICopImRpYWxvZyIsIE5VTEwsIDApOwoKICAgIC8qIENoZWNrICd2JyBmbGFnIGluICdndWlvcHRpb25zJzogdmVydGljYWwgYnV0dG9uIHBsYWNlbWVudC4gKi8KICAgIHZlcnRpY2FsID0gKHZpbV9zdHJjaHIocF9nbywgR09fVkVSVElDQUwpICE9IE5VTEwpOwoKICAgIC8qIFNldCB0aGUgdGl0bGUgb2YgdGhlIERpYWxvZyB3aW5kb3cgKi8KICAgIGxhYmVsID0gWG1TdHJpbmdDcmVhdGVTaW1wbGUoKGNoYXIgKil0aXRsZSk7CiAgICBpZiAobGFiZWwgPT0gTlVMTCkKCXJldHVybiAtMTsKICAgIFh0VmFTZXRWYWx1ZXMoZGlhbG9nZm9ybSwKCSAgICBYbU5kaWFsb2dUaXRsZSwgbGFiZWwsCgkgICAgWG1OaG9yaXpvbnRhbFNwYWNpbmcsIDQsCgkgICAgWG1OdmVydGljYWxTcGFjaW5nLCB2ZXJ0aWNhbCA/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