LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2lmIEhBVkVfU1lTX1BBUkFNX0gKI2luY2x1ZGUgPHN5cy9wYXJhbS5oPgojZW5kaWYKI2lmIEhBVkVfU1lTX0ZJTEVfSAojaW5jbHVkZSA8c3lzL2ZpbGUuaD4KI2VuZGlmCiNpZiBIQVZFX1NZU19TT0NLRVRfSAojaW5jbHVkZSA8c3lzL3NvY2tldC5oPgojZW5kaWYKI2lmIEhBVkVfU1lTX1NPQ0tJT19ICiNpbmNsdWRlIDxzeXMvc29ja2lvLmg+CiNlbmRpZgojaWYgSEFWRV9TWVNfSU9DVExfSAojaW5jbHVkZSA8c3lzL2lvY3RsLmg+CiNlbmRpZgojaWYgSEFWRV9TWVNfTUJVRl9ICiNpbmNsdWRlIDxzeXMvbWJ1Zi5oPgojZW5kaWYKCgojaWYgSEFWRV9TWVNfU1RSRUFNX0gKI2luY2x1ZGUgPHN5cy9zdHJlYW0uaD4KI2VuZGlmCiNpZiBIQVZFX05FVF9ST1VURV9ICiNpbmNsdWRlIDxuZXQvcm91dGUuaD4KI2VuZGlmCiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2lmIEhBVkVfQVJQQV9JTkVUX0gKI2luY2x1ZGUgPGFycGEvaW5ldC5oPgojZW5kaWYKI2lmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCgojaW5jbHVkZSA8ZXJybm8uaD4KI2lmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbmRpZgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgoKI2lmIEhBVkVfV0lOU09DS19ICiNpbmNsdWRlIDx3aW5zb2NrLmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgoKI2luY2x1ZGUgImlwLmgiCiNpbmNsdWRlICJyb3V0ZV93cml0ZS5oIgoKI2lmZGVmIGN5Z3dpbgojaW5jbHVkZSA8d2luZG93cy5oPgojZW5kaWYKCiNpZiAhZGVmaW5lZCAoV0lOMzIpICYmICFkZWZpbmVkIChjeWd3aW4pCgojaWZuZGVmIEhBVkVfU1RSVUNUX1JURU5UUllfUlRfRFNUCiNkZWZpbmUgcnRfZHN0IHJ0X25vZGVzLT5ybl9rZXkKI2VuZGlmCiNpZm5kZWYgSEFWRV9TVFJVQ1RfUlRFTlRSWV9SVF9IQVNICiNkZWZpbmUgcnRfaGFzaCBydF9wYWQxCiNlbmRpZgoKI2lmZGVmIGlyaXg2CiNkZWZpbmUgU0lPQ0FERFJUIFNJT0NBRERNVUxUSQojZGVmaW5lIFNJT0NERUxSVCBTSU9DREVMTVVMVEkKI2VuZGlmCgojaWZkZWYgbGludXgKI2RlZmluZSBORVRTTk1QX1JPVVRFX1dSSVRFX1BST1RPQ09MIFBGX1JPVVRFCiNlbHNlCiNkZWZpbmUgTkVUU05NUF9ST1VURV9XUklURV9QUk9UT0NPTCAwCiNlbmRpZgoKaW50CmFkZFJvdXRlKHVfbG9uZyBkc3RpcCwgdV9sb25nIGd3aXAsIHVfbG9uZyBpZmYsIHVfc2hvcnQgZmxhZ3MpCnsKI2lmIGRlZmluZWQgU0lPQ0FERFJUICYmICEoZGVmaW5lZChpcml4NikgfHwgZGVmaW5lZChfX09wZW5CU0RfXykgfHwgZGVmaW5lZChkYXJ3aW4pKQogICAgc3RydWN0IHNvY2thZGRyX2luIGRzdDsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBnYXRld2F5OwogICAgaW50ICAgICAgICAgICAgIHMsIHJjOwogICAgUlRFTlRSWSAgICAgICAgIHJvdXRlOwoKICAgIHMgPSBzb2NrZXQoQUZfSU5FVCwgU09DS19SQVcsIE5FVFNOTVBfUk9VVEVfV1JJVEVfUFJPVE9DT0wpOwogICAgaWYgKHMgPCAwKSB7CiAgICAgICAgc25tcF9sb2dfcGVycm9yKCJzb2NrZXQiKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgoKICAgIGZsYWdzIHw9IFJURl9VUDsKCiAgICBkc3Quc2luX2ZhbWlseSA9IEFGX0lORVQ7CiAgICBkc3Quc2luX2FkZHIuc19hZGRyID0gaHRvbmwoZHN0aXApOwoKCiAgICBnYXRld2F5LnNpbl9mYW1pbHkgPSBBRl9JTkVUOwogICAgZ2F0ZXdheS5zaW5fYWRkci5zX2FkZHIgPSBodG9ubChnd2lwKTsKCiAgICBtZW1jcHkoJnJvdXRlLnJ0X2RzdCwgJmRzdCwgc2l6ZW9mKHN0cnVjdCBzb2NrYWRkcl9pbikpOwogICAgbWVtY3B5KCZyb3V0ZS5ydF9nYXRld2F5LCAmZ2F0ZXdheSwgc2l6ZW9mKHN0cnVjdCBzb2NrYWRkcl9pbikpOwoKICAgIHJvdXRlLnJ0X2ZsYWdzID0gZmxhZ3M7CiNpZm5kZWYgUlRFTlRSWV80XzQKICAgIHJvdXRlLnJ0X2hhc2ggPSBpZmY7CiNlbmRpZgoKICAgIHJjID0gaW9jdGwocywgU0lPQ0FERFJULCAoY2FkZHJfdCkgJiByb3V0ZSk7CiAgICBjbG9zZShzKTsKICAgIGlmIChyYyA8IDApCiAgICAgICAgc25tcF9sb2dfcGVycm9yKCJpb2N0bCIpOwogICAgcmV0dXJuIHJjOwoKI2VsaWYgKGRlZmluZWQgX19PcGVuQlNEX18gfHwgZGVmaW5lZChkYXJ3aW4pKQoKICAgICAgIGludCAgICAgcywgcmM7CiAgICAgICBzdHJ1Y3QgewogICAgICAgICAgICAgICBzdHJ1Y3QgIHJ0X21zZ2hkciBoZHI7CiAgICAgICAgICAgICAgIHN0cnVjdCAgc29ja2FkZHJfaW4gZHN0OwogICAgICAgICAgICAgICBzdHJ1Y3QgIHNvY2thZGRyX2luIGdhdGV3YXk7CiAgICAgICB9IHJ0bXNnOwoKICAgICAgIHMgPSBzb2NrZXQoUEZfUk9VVEUsIFNPQ0tfUkFXLCAwKTsKICAgICAgIGlmIChzIDwgMCkgewogICAgICAgICAgICBzbm1wX2xvZ19wZXJyb3IoInNvY2tldCIpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICB9CgogICAgICAgc2h1dGRvd24ocywgU0hVVF9SRCk7CgogICAgICAgLyogcG9zc2libGUgcGFuaWMgb3RoZXJ3aXNlICovCiAgICAgICBmbGFncyB8PSAoUlRGX1VQIHwgUlRGX0dBVEVXQVkpOwoKICAgICAgIGJ6ZXJvKCZydG1zZywgc2l6ZW9mKHJ0bXNnKSk7CgogICAgICAgcnRtc2cuaGRyLnJ0bV90eXBlID0gUlRNX0FERDsKICAgICAgIHJ0bXNnLmhkci5ydG1fdmVyc2lvbiA9IFJUTV9WRVJTSU9OOwogICAgICAgcnRtc2cuaGRyLnJ0bV9hZGRycyA9IFJUQV9EU1QgfCBSVEFfR0FURVdBWTsKICAgICAgIHJ0bXNnLmhkci5ydG1fZmxhZ3MgPSBSVEZfR0FURVdBWTsKCiAgICAgICBydG1zZy5kc3Quc2luX2xlbiA9IHNpemVvZihydG1zZy5kc3QpOwogICAgICAgcnRtc2cuZHN0LnNpbl9mYW1pbHkgPSBBRl9JTkVUOwogICAgICAgcnRtc2cuZHN0LnNpbl9hZGRyLnNfYWRkciA9IGh0b25sKGRzdGlwKTsKCiAgICAgICBydG1zZy5nYXRld2F5LnNpbl9sZW4gPSBzaXplb2YocnRtc2cuZ2F0ZXdheSk7CiAgICAgICBydG1zZy5nYXRld2F5LnNpbl9mYW1pbHkgPSBBRl9JTkVUOwogICAgICAgcnRtc2cuZ2F0ZXdheS5zaW5fYWRkci5zX2FkZHIgPSBodG9ubChnd2lwKTsKCiAgICAgICByYyA9IHNpemVvZihydG1zZyk7CiAgICAgICBydG1zZy5oZHIucnRtX21zZ2xlbiA9IHJjOwoKICAgICAgIGlmICgocmMgPSB3cml0ZShzLCAmcnRtc2csIHJjKSkgPCAwKSB7CiAgICAgICAgICAgICAgIHNubXBfbG9nX3BlcnJvcigid3JpdGluZyB0byByb3V0aW5nIHNvY2tldCIpOwogICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICB9CiAgICAgICByZXR1cm4gKHJjKTsKI2Vsc2UgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBTSU9DQUREUlQgKi8KICAgIHJldHVybiAtMTsKI2VuZGlmCn0KCgoKaW50CmRlbFJvdXRlKHVfbG9uZyBkc3RpcCwgdV9sb25nIGd3aXAsIHVfbG9uZyBpZmYsIHVfc2hvcnQgZmxhZ3MpCnsKI2lmIGRlZmluZWQgU0lPQ0FERFJUICYmICEoZGVmaW5lZChpcml4NikgfHwgZGVmaW5lZChfX09wZW5CU0RfXykgfHwgZGVmaW5lZChkYXJ3aW4pKQoKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBkc3Q7CiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gZ2F0ZXdheTsKICAgIGludCAgICAgICAgICAgICBzLCByYzsKICAgIFJURU5UUlkgICAgICAgICByb3V0ZTsKCiAgICBzID0gc29ja2V0KEFGX0lORVQsIFNPQ0tfUkFXLCBORVRTTk1QX1JPVVRFX1dSSVRFX1BST1RPQ09MKTsKICAgIGlmIChzIDwgMCkgewogICAgICAgIHNubXBfbG9nX3BlcnJvcigic29ja2V0Iik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgoKICAgIGZsYWdzIHw9IFJURl9VUDsKCiAgICBkc3Quc2luX2ZhbWlseSA9IEFGX0lORVQ7CiAgICBkc3Quc2luX2FkZHIuc19hZGRyID0gaHRvbmwoZHN0aXApOwoKCiAgICBnYXRld2F5LnNpbl9mYW1pbHkgPSBBRl9JTkVUOwogICAgZ2F0ZXdheS5zaW5fYWRkci5zX2FkZHIgPSBodG9ubChnd2lwKTsKCiAgICBtZW1jcHkoJnJvdXRlLnJ0X2RzdCwgJmRzdCwgc2l6ZW9mKHN0cnVjdCBzb2NrYWRkcl9pbikpOwogICAgbWVtY3B5KCZyb3V0ZS5ydF9nYXRld2F5LCAmZ2F0ZXdheSwgc2l6ZW9mKHN0cnVjdCBzb2NrYWRkcl9pbikpOwoKICAgIHJvdXRlLnJ0X2ZsYWdzID0gZmxhZ3M7CiNpZm5kZWYgUlRFTlRSWV80XzQKICAgIHJvdXRlLnJ0X2hhc2ggPSBpZmY7CiNlbmRpZgoKICAgIHJjID0gaW9jdGwocywgU0lPQ0RFTFJULCAoY2FkZHJfdCkgJiByb3V0ZSk7CiAgICBjbG9zZShzKTsKICAgIHJldHVybiByYzsKI2VsaWYgKGRlZmluZWQgX19PcGVuQlNEX18gfHwgZGVmaW5lZChkYXJ3aW4pKQogCiAgICAgICBpbnQgICAgIHMsIHJjOwogICAgICAgc3RydWN0IHsKICAgICAgICAgICAgICAgc3RydWN0ICBydF9tc2doZHIgaGRyOwogICAgICAgICAgICAgICBzdHJ1Y3QgIHNvY2thZGRyX2luIGRzdDsKICAgICAgICAgICAgICAgc3RydWN0ICBzb2NrYWRkcl9pbiBnYXRld2F5OwogICAgICAgfSBydG1zZzsKCiAgICAgICBzID0gc29ja2V0KFBGX1JPVVRFLCBTT0NLX1JBVywgMCk7CiAgICAgICBpZiAocyA8IDApIHsKICAgICAgICAgICAgc25tcF9sb2dfcGVycm9yKCJzb2NrZXQiKTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgfQoKICAgICAgIHNodXRkb3duKHMsIFNIVVRfUkQpOwoKICAgICAgIC8qIHBvc3NpYmxlIHBhbmljIG90aGVyd2lzZSAqLwogICAgICAgZmxhZ3MgfD0gKFJURl9VUCB8IFJURl9HQVRFV0FZKTsKCiAgICAgICBiemVybygmcnRtc2csIHNpemVvZihydG1zZykpOwoKICAgICAgIHJ0bXNnLmhkci5ydG1fdHlwZSA9IFJUTV9ERUxFVEU7CiAgICAgICBydG1zZy5oZHIucnRtX3ZlcnNpb24gPSBSVE1fVkVSU0lPTjsKICAgICAgIHJ0bXNnLmhkci5ydG1fYWRkcnMgPSBSVEFfRFNUIHwgUlRBX0dBVEVXQVk7CiAgICAgICBydG1zZy5oZHIucnRtX2ZsYWdzID0gUlRGX0dBVEVXQVk7CgogICAgICAgcnRtc2cuZHN0LnNpbl9sZW4gPSBzaXplb2YocnRtc2cuZHN0KTsKICAgICAgIHJ0bXNnLmRzdC5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKICAgICAgIHJ0bXNnLmRzdC5zaW5fYWRkci5zX2FkZHIgPSBodG9ubChkc3RpcCk7CgogICAgICAgcnRtc2cuZ2F0ZXdheS5zaW5fbGVuID0gc2l6ZW9mKHJ0bXNnLmdhdGV3YXkpOwogICAgICAgcnRtc2cuZ2F0ZXdheS5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKICAgICAgIHJ0bXNnLmdhdGV3YXkuc2luX2FkZHIuc19hZGRyID0gaHRvbmwoZ3dpcCk7CgogICAgICAgcmMgPSBzaXplb2YocnRtc2cpOwogICAgICAgcnRtc2cuaGRyLnJ0bV9tc2dsZW4gPSByYzsKCiAgICAgICBpZiAoKHJjID0gd3JpdGUocywgJnJ0bXNnLCByYykpIDwgMCkgewogICAgICAgICAgICAgICBzbm1wX2xvZ19wZXJyb3IoIndyaXRpbmcgdG8gcm91dGluZyBzb2NrZXQiKTsKICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgfQogICAgICAgcmV0dXJuIChyYyk7CiNlbHNlICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogU0lPQ0RFTFJUICovCiAgICByZXR1cm4gMDsKI2VuZGlmCn0KCgojaWZuZGVmIEhBVkVfU1RSVUNUX1JURU5UUllfUlRfRFNUCiN1bmRlZiBydF9kc3QKI2VuZGlmCgoKI2RlZmluZSAgTUFYX0NBQ0hFICAgOAoKc3RydWN0IHJ0ZW50IHsKCiAgICB1X2xvbmcgICAgICAgICAgaW5fdXNlOwogICAgdV9sb25nICAgICAgICAgIG9sZF9kc3Q7CiAgICB1X2xvbmcgICAgICAgICAgb2xkX25leHRJUjsKICAgIHVfbG9uZyAgICAgICAgICBvbGRfaWZpeDsKICAgIHVfbG9uZyAgICAgICAgICBvbGRfZmxhZ3M7CgogICAgdV9sb25nICAgICAgICAgIHJ0X2RzdDsgICAgIC8qICBtYWluIGVudHJpZXMgICAgKi8KICAgIHVfbG9uZyAgICAgICAgICBydF9pZml4OwogICAgdV9sb25nICAgICAgICAgIHJ0X21ldHJpYzE7CiAgICB1X2xvbmcgICAgICAgICAgcnRfbmV4dElSOwogICAgdV9sb25nICAgICAgICAgIHJ0X3R5cGU7CiAgICB1X2xvbmcgICAgICAgICAgcnRfcHJvdG87CgoKICAgIHVfbG9uZyAgICAgICAgICB4eF9kc3Q7ICAgICAvKiAgc2hhZG93IGVudHJpZXMgICovCiAgICB1X2xvbmcgICAgICAgICAgeHhfaWZpeDsKICAgIHVfbG9uZyAgICAgICAgICB4eF9tZXRyaWMxOwogICAgdV9sb25nICAgICAgICAgIHh4X25leHRJUjsKICAgIHVfbG9uZyAgICAgICAgICB4eF90eXBlOwogICAgdV9sb25nICAgICAgICAgIHh4X3Byb3RvOwp9OwoKc3RydWN0IHJ0ZW50ICAgIHJ0Y2FjaGVbTUFYX0NBQ0hFXTsKCnN0cnVjdCBydGVudCAgICoKZmluZENhY2hlUlRFKHVfbG9uZyBkc3QpCnsKICAgIGludCAgICAgICAgICAgICBpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfQ0FDSEU7IGkrKykgewoKICAgICAgICBpZiAocnRjYWNoZVtpXS5pbl91c2UgJiYgKHJ0Y2FjaGVbaV0ucnRfZHN0ID09IGRzdCkpIHsgIC8qIHZhbGlkICYgbWF0Y2g/ICovCiAgICAgICAgICAgIHJldHVybiAoJnJ0Y2FjaGVbaV0pOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgpzdHJ1Y3QgcnRlbnQgICAqCm5ld0NhY2hlUlRFKHZvaWQpCnsKCiAgICBpbnQgICAgICAgICAgICAgaTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX0NBQ0hFOyBpKyspIHsKCiAgICAgICAgaWYgKCFydGNhY2hlW2ldLmluX3VzZSkgewogICAgICAgICAgICBydGNhY2hlW2ldLmluX3VzZSA9IDE7CiAgICAgICAgICAgIHJldHVybiAoJnJ0Y2FjaGVbaV0pOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBOVUxMOwoKfQoKaW50CmRlbENhY2hlUlRFKHVfbG9uZyBkc3QpCnsKICAgIHN0cnVjdCBydGVudCAgICpydDsKCiAgICBydCA9IGZpbmRDYWNoZVJURShkc3QpOwogICAgaWYgKCFydCkgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHJ0LT5pbl91c2UgPSAwOwogICAgcmV0dXJuIDE7Cn0KCgpzdHJ1Y3QgcnRlbnQgICAqCmNhY2hlS2VybmVsUlRFKHVfbG9uZyBkc3QpCnsKICAgIHJldHVybiBOVUxMOyAgICAgICAgICAgICAgICAvKiBmb3Igbm93ICovCiAgICAvKgogICAgICogLi4uLi4uIAogICAgICovCn0KCi8qCiAqIElmIHN0YXRQIGlzIG5vbi1OVUxMLCB0aGUgcmVmZXJlbmNlZCBvYmplY3QgaXMgYXQgdGhhdCBsb2NhdGlvbi4KICogSWYgc3RhdFAgaXMgTlVMTCBhbmQgYXAgaXMgbm9uLU5VTEwsIHRoZSBpbnN0YW5jZSBleGlzdHMsIGJ1dCBub3QgdGhpcyB2YXJpYWJsZS4KICogSWYgc3RhdFAgaXMgTlVMTCBhbmQgYXAgaXMgTlVMTCwgdGhlbiBuZWl0aGVyIHRoaXMgaW5zdGFuY2Ugbm9yIHRoZSB2YXJpYWJsZSBleGlzdHMuCiAqLwoKaW50CndyaXRlX3J0ZShpbnQgYWN0aW9uLAogICAgICAgICAgdV9jaGFyICogdmFyX3ZhbCwKICAgICAgICAgIHVfY2hhciB2YXJfdmFsX3R5cGUsCiAgICAgICAgICBzaXplX3QgdmFyX3ZhbF9sZW4sIHVfY2hhciAqIHN0YXRQLCBvaWQgKiBuYW1lLCBzaXplX3QgbGVuZ3RoKQp7CiAgICBzdHJ1Y3QgcnRlbnQgICAqcnA7CiAgICBpbnQgICAgICAgICAgICAgdmFyOwogICAgbG9uZyAgICAgICAgICAgIHZhbDsKICAgIHVfbG9uZyAgICAgICAgICBkc3Q7CiAgICBjaGFyICAgICAgICAgICAgYnVmWzhdOwogICAgdV9zaG9ydCAgICAgICAgIGZsYWdzOwogICAgaW50ICAgICAgICAgICAgIG9sZHR5OwoKICAgIC8qCiAgICAgKiBvYmplY3QgaWRlbnRpZmllciBpcyBvZiBmb3JtOgogICAgICogMS4zLjYuMS4yLjEuNC4yMS4xLlguQS5CLkMuRCAsICB3aGVyZSBBLkIuQy5EIGlzIElQIGFkZHJlc3MuCiAgICAgKiBJUEFERFIgc3RhcnRzIGF0IG9mZnNldCAxMC4KICAgICAqLwoKICAgIGlmIChsZW5ndGggIT0gMTQpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibGVuZ3RoIGVycm9yXG4iKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9DUkVBVElPTjsKICAgIH0KCiNpZmRlZiBzb2xhcmlzMgkJLyogbm90IGltcGxlbWVudGVkICovCiAgICByZXR1cm4gU05NUF9FUlJfTk9UV1JJVEFCTEU7CiNlbmRpZgoKICAgIHZhciA9IG5hbWVbOV07CgogICAgZHN0ID0gKigodV9sb25nICopICYgbmFtZVsxMF0pOwoKICAgIHJwID0gZmluZENhY2hlUlRFKGRzdCk7CgogICAgaWYgKCFycCkgewogICAgICAgIHJwID0gY2FjaGVLZXJuZWxSVEUoZHN0KTsKICAgIH0KCgogICAgaWYgKGFjdGlvbiA9PSBSRVNFUlZFMSAmJiAhcnApIHsKCiAgICAgICAgcnAgPSBuZXdDYWNoZVJURSgpOwogICAgICAgIGlmICghcnApIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5ld0NhY2hlUlRFIik7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9SRVNPVVJDRVVOQVZBSUxBQkxFOwogICAgICAgIH0KICAgICAgICBycC0+cnRfZHN0ID0gZHN0OwogICAgICAgIHJwLT5ydF90eXBlID0gcnAtPnh4X3R5cGUgPSAyOwoKICAgIH0gZWxzZSBpZiAoYWN0aW9uID09IENPTU1JVCkgewoKCiAgICB9IGVsc2UgaWYgKGFjdGlvbiA9PSBGUkVFKSB7CiAgICAgICAgaWYgKHJwICYmIHJwLT5ydF90eXBlID09IDIpIHsgLyogd2FzIGludmFsaWQgYmVmb3JlICovCiAgICAgICAgICAgIGRlbENhY2hlUlRFKGRzdCk7CiAgICAgICAgfQogICAgfQoKICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgIT0gcnApOyAvKiBzaG91bGQgaGF2ZSBmb3VuZCBvciBjcmVhdGVkIHJwICovCgoKICAgIHN3aXRjaCAodmFyKSB7CgogICAgY2FzZSBJUFJPVVRFREVTVDoKCiAgICAgICAgaWYgKGFjdGlvbiA9PSBSRVNFUlZFMSkgewoKICAgICAgICAgICAgaWYgKHZhcl92YWxfdHlwZSAhPSBBU05fSVBBRERSRVNTKSB7CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibm90IElQIGFkZHJlc3MiKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9XUk9OR1RZUEU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG1lbWNweShidWYsIHZhcl92YWwsICh2YXJfdmFsX2xlbiA+IDgpID8gOCA6IHZhcl92YWxfbGVuKTsKCiAgICAgICAgICAgIHJwLT54eF9kc3QgPSAqKCh1X2xvbmcgKikgYnVmKTsKCgogICAgICAgIH0gZWxzZSBpZiAoYWN0aW9uID09IENPTU1JVCkgewogICAgICAgICAgICBycC0+cnRfZHN0ID0gcnAtPnh4X2RzdDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBJUFJPVVRFTUVUUklDMToKCiAgICAgICAgaWYgKGFjdGlvbiA9PSBSRVNFUlZFMSkgewogICAgICAgICAgICBpZiAodmFyX3ZhbF90eXBlICE9IEFTTl9JTlRFR0VSKSB7CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibm90IGludDEiKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9XUk9OR1RZUEU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhbCA9ICooKGxvbmcgKikgdmFyX3ZhbCk7CgogICAgICAgICAgICBpZiAodmFsIDwgLTEpIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJub3QgcmlnaHQxIik7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfV1JPTkdWQUxVRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcnAtPnh4X21ldHJpYzEgPSB2YWw7CgogICAgICAgIH0gZWxzZSBpZiAoYWN0aW9uID09IFJFU0VSVkUyKSB7CgogICAgICAgICAgICBpZiAoKHJwLT54eF9tZXRyaWMxID09IDEpICYmIChycC0+eHhfdHlwZSAhPSA0KSkgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgInJlc2VydmUyIGZhaWxlZFxuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfV1JPTkdWQUxVRTsKICAgICAgICAgICAgfQoKICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbiA9PSBDT01NSVQpIHsKICAgICAgICAgICAgcnAtPnJ0X21ldHJpYzEgPSBycC0+eHhfbWV0cmljMTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBJUFJPVVRFSUZJTkRFWDoKCiAgICAgICAgaWYgKGFjdGlvbiA9PSBSRVNFUlZFMSkgewogICAgICAgICAgICBpZiAodmFyX3ZhbF90eXBlICE9IEFTTl9JTlRFR0VSKSB7CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibm90IHJpZ2h0MiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX1dST05HVFlQRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFsID0gKigobG9uZyAqKSB2YXJfdmFsKTsKCiAgICAgICAgICAgIGlmICh2YWwgPD0gMCkgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5vdCByaWdodDMiKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9XUk9OR1ZBTFVFOwogICAgICAgICAgICB9CgogICAgICAgICAgICBycC0+eHhfaWZpeCA9IHZhbDsKCiAgICAgICAgfSBlbHNlIGlmIChhY3Rpb24gPT0gQ09NTUlUKSB7CiAgICAgICAgICAgIHJwLT5ydF9pZml4ID0gcnAtPnh4X2lmaXg7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgSVBST1VURU5FWFRIT1A6CgogICAgICAgIGlmIChhY3Rpb24gPT0gUkVTRVJWRTEpIHsKCiAgICAgICAgICAgIGlmICh2YXJfdmFsX3R5cGUgIT0gQVNOX0lQQUREUkVTUykgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5vdCByaWdodDQiKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9XUk9OR1RZUEU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG1lbWNweShidWYsIHZhcl92YWwsICh2YXJfdmFsX2xlbiA+IDgpID8gOCA6IHZhcl92YWxfbGVuKTsKCiAgICAgICAgICAgIHJwLT54eF9uZXh0SVIgPSAqKCh1X2xvbmcgKikgYnVmKTsKCiAgICAgICAgfSBlbHNlIGlmIChhY3Rpb24gPT0gQ09NTUlUKSB7CiAgICAgICAgICAgIHJwLT5ydF9uZXh0SVIgPSBycC0+eHhfbmV4dElSOwogICAgICAgIH0KCWJyZWFrOwoKCiAgICBjYXNlIElQUk9VVEVUWVBFOgoKICAgICAgICAvKgogICAgICAgICAqICBmbGFnIG1lYW5pbmc6CiAgICAgICAgICoKICAgICAgICAgKiAgSVBST1VURVBST1RPIChydF9wcm90byk6IG5vbmU6IChjYW50IHNldCA9PSAzIChuZXRtZ210KSkgCiAgICAgICAgICoKICAgICAgICAgKiAgSVBST1VURU1FVFJJQzE6ICAxIGlmZiBnYXRld2F5LCAwIG90aGVyd2lzZQogICAgICAgICAqICBJUFJPVVRFVFlQRTogICAgIDQgaWZmIGdhdGV3YXksIDMgb3RoZXJ3aXNlCiAgICAgICAgICovCgogICAgICAgIGlmIChhY3Rpb24gPT0gUkVTRVJWRTEpIHsKICAgICAgICAgICAgaWYgKHZhcl92YWxfdHlwZSAhPSBBU05fSU5URUdFUikgewogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX1dST05HVFlQRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFsID0gKigobG9uZyAqKSB2YXJfdmFsKTsKCiAgICAgICAgICAgIGlmICgodmFsIDwgMikgfHwgKHZhbCA+IDQpKSB7ICAgICAgIC8qIG9ubHkgYWNjZXB0IGludmFsaWQsIGRpcmVjdCwgaW5kaXJlY3QgKi8KICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJub3QgcmlnaHQ2Iik7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfV1JPTkdWQUxVRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcnAtPnh4X3R5cGUgPSB2YWw7CgogICAgICAgIH0gZWxzZSBpZiAoYWN0aW9uID09IENPTU1JVCkgewoKICAgICAgICAgICAgb2xkdHkgPSBycC0+cnRfdHlwZTsKICAgICAgICAgICAgcnAtPnJ0X3R5cGUgPSBycC0+eHhfdHlwZTsKCiAgICAgICAgICAgIGlmIChycC0+cnRfdHlwZSA9PSAyKSB7ICAgICAvKiBpbnZhbGlkLCBzbyBkZWxldGUgZnJvbSBrZXJuZWwgKi8KCiAgICAgICAgICAgICAgICBpZiAoZGVsUm91dGUKICAgICAgICAgICAgICAgICAgICAocnAtPnJ0X2RzdCwgcnAtPnJ0X25leHRJUiwgcnAtPnJ0X2lmaXgsCiAgICAgICAgICAgICAgICAgICAgIHJwLT5vbGRfZmxhZ3MpIDwgMCkgewogICAgICAgICAgICAgICAgICAgIHNubXBfbG9nX3BlcnJvcigiZGVsUm91dGUiKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgIH0gZWxzZSB7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGl0IG11c3QgYmUgdmFsaWQgbm93LCBzbyBmbHVzaCB0byBrZXJuZWwgCiAgICAgICAgICAgICAgICAgKi8KCiAgICAgICAgICAgICAgICBpZiAob2xkdHkgIT0gMikgeyAgICAgICAvKiB3YXMgdGhlIG9sZCBlbnRyeSB2YWxpZCA/ICAqLwogICAgICAgICAgICAgICAgICAgIGlmIChkZWxSb3V0ZQogICAgICAgICAgICAgICAgICAgICAgICAocnAtPm9sZF9kc3QsIHJwLT5vbGRfbmV4dElSLCBycC0+b2xkX2lmaXgsCiAgICAgICAgICAgICAgICAgICAgICAgICBycC0+b2xkX2ZsYWdzKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2dfcGVycm9yKCJkZWxSb3V0ZSIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogbm90IGludmFsaWQsIHNvIHJlbW92ZSBmcm9tIGNhY2hlIAogICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgZmxhZ3MgPSAocnAtPnJ0X3R5cGUgPT0gNCA/IFJURl9HQVRFV0FZIDogMCk7CgogICAgICAgICAgICAgICAgaWYgKGFkZFJvdXRlKHJwLT5ydF9kc3QsIHJwLT5ydF9uZXh0SVIsIHJwLT5ydF9pZml4LCBmbGFncykKICAgICAgICAgICAgICAgICAgICA8IDApIHsKICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZ19wZXJyb3IoImFkZFJvdXRlIik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZGVsQ2FjaGVSVEUocnAtPnJ0X3R5cGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKCiAgICBjYXNlIElQUk9VVEVQUk9UTzoKCiAgICBkZWZhdWx0OgogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wZCIsICJ1bmtub3duIHN1Yi1pZCAlZCBpbiB3cml0ZV9ydGVcbiIsIHZhcikpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0NSRUFUSU9OOwoKCiAgICB9CgogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCiNlbHNlICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogV0lOMzIgY3lnd2luICovCiNpbmNsdWRlIDxpcGhscGFwaS5oPgoKZXh0ZXJuIFBNSUJfSVBGT1JXQVJEUk9XIHJvdXRlX3JvdzsKZXh0ZXJuIGludCAgICAgIGNyZWF0ZV9mbGFnOwoKaW50CndyaXRlX3J0ZShpbnQgYWN0aW9uLAogICAgICAgICAgdV9jaGFyICogdmFyX3ZhbCwKICAgICAgICAgIHVfY2hhciB2YXJfdmFsX3R5cGUsCiAgICAgICAgICBzaXplX3QgdmFyX3ZhbF9sZW4sIHVfY2hhciAqIHN0YXRQLCBvaWQgKiBuYW1lLCBzaXplX3QgbGVuZ3RoKQp7CiAgICBpbnQgICAgICAgICAgICAgdmFyLCByZXR2YWwgPSBOT19FUlJPUjsKICAgIHN0YXRpYyBQTUlCX0lQRk9SV0FSRFJPVyBvbGRyb3V0ZV9yb3cgPSBOVUxMOwogICAgc3RhdGljIGludCAgICAgIG1hc2tfZmxhZyA9IDAsIG5leHRob3BfZmxhZyA9IDA7CiAgICBzdGF0aWMgaW50ICAgICAgaW5kZXhfZmxhZyA9IDAsIG1ldHJpY19mbGFnID0gMDsKICAgIHN0YXRpYyBpbnQgICAgICBkZXN0X2ZsYWcgPSAwOwogICAgRFdPUkQgICAgICAgICAgIHN0YXR1cyA9IE5PX0VSUk9SOwogICAgLyoKICAgICAqIG9iamVjdCBpZGVudGlmaWVyIGlzIG9mIGZvcm06CiAgICAgKiAxLjMuNi4xLjIuMS40LjIxLjEuWC5BLkIuQy5EICwgIHdoZXJlIEEuQi5DLkQgaXMgSVAgYWRkcmVzcy4KICAgICAqIElQQUREUiBzdGFydHMgYXQgb2Zmc2V0IDEwLgogICAgICovCgogICAgaWYgKGxlbmd0aCAhPSAxNCkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJsZW5ndGggZXJyb3JcbiIpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0NSRUFUSU9OOwogICAgfQogICAgLyoKICAgICAqICNkZWZpbmUgZm9yIGlwUm91dGVUYWJsZSBlbnRyaWVzIGFyZSAxIGxlc3MgdGhhbiBjb3JyZXNwb25kaW5nIHN1Yi1pZCBpbiBNSUIKICAgICAqICogaS5lLiBJUFJPVVRFREVTVCBkZWZpbmVkIGFzIDAsIGJ1dCBpcFJvdXRlRGVzdCByZWdpc3RlcmVkIGFzIDEKICAgICAqLwogICAgdmFyID0gbmFtZVs5XSAtIDE7CgogICAgc3dpdGNoIChhY3Rpb24pIHsKICAgIGNhc2UgUkVTRVJWRTE6CiAgICAgICAgc3dpdGNoICh2YXIpIHsKICAgICAgICBjYXNlIElQUk9VVEVNRVRSSUMxOgogICAgICAgIGNhc2UgSVBST1VURU1FVFJJQzI6CiAgICAgICAgY2FzZSBJUFJPVVRFTUVUUklDMzoKICAgICAgICBjYXNlIElQUk9VVEVNRVRSSUM0OgogICAgICAgIGNhc2UgSVBST1VURU1FVFJJQzU6CiAgICAgICAgY2FzZSBJUFJPVVRFVFlQRToKICAgICAgICBjYXNlIElQUk9VVEVBR0U6CiAgICAgICAgY2FzZSBJUFJPVVRFSUZJTkRFWDoKICAgICAgICAgICAgaWYgKHZhcl92YWxfdHlwZSAhPSBBU05fSU5URUdFUikgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5vdCBpbnRlZ2VyXG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9XUk9OR1RZUEU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHZhcl92YWxfbGVuID4gc2l6ZW9mKGludCkpIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJiYWQgbGVuZ3RoXG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9XUk9OR0xFTkdUSDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodmFyID09IElQUk9VVEVUWVBFKSB7CiAgICAgICAgICAgICAgICBpZiAoKCooKGludCAqKSB2YXJfdmFsKSkgPCAyIHx8ICgqKChpbnQgKikgdmFyX3ZhbCkpID4gNCkgewogICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJpbnZhbGlkIGlwUm91dGVUeXBlXG4iKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfV1JPTkdWQUxVRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmICgodmFyID09IElQUk9VVEVJRklOREVYKSB8fCAodmFyID09IElQUk9VVEVBR0UpKSB7CiAgICAgICAgICAgICAgICBpZiAoKCooKGludCAqKSB2YXJfdmFsKSkgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgImludmFsaWQgaXBSb3V0ZUlmSW5kZXhcbiIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9XUk9OR1ZBTFVFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCgqKChpbnQgKikgdmFyX3ZhbCkpIDwgLTEpIHsKICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibm90IHJpZ2h0MSIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9XUk9OR1ZBTFVFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgSVBST1VURU5FWFRIT1A6CiAgICAgICAgY2FzZSBJUFJPVVRFTUFTSzoKICAgICAgICBjYXNlIElQUk9VVEVERVNUOgogICAgICAgICAgICBpZiAodmFyX3ZhbF90eXBlICE9IEFTTl9JUEFERFJFU1MpIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJub3QgcmlnaHQ0Iik7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfV1JPTkdUWVBFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh2YXJfdmFsX2xlbiAhPSA0KSB7CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiaW5jb3JyZWN0IGlwQWRkcmVzcyBsZW5ndGgiKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9XUk9OR0xFTkdUSDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcGQiLCAidW5rbm93biBzdWItaWQgJWQgaW4gd3JpdGVfcnRlXG4iLAogICAgICAgICAgICAgICAgICAgICAgICB2YXIgKyAxKSk7CiAgICAgICAgICAgIHJldHZhbCA9IFNOTVBfRVJSX05PVFdSSVRBQkxFOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFJFU0VSVkUyOgogICAgICAgIC8qCiAgICAgICAgICogU2F2ZSB0aGUgb2xkIHZhbHVlLCBpbiBjYXNlIG9mIFVORE8gCiAgICAgICAgICovCiAgICAgICAgaWYgKG9sZHJvdXRlX3JvdyA9PSBOVUxMKSB7CiAgICAgICAgICAgIG9sZHJvdXRlX3JvdyA9CiAgICAgICAgICAgICAgICAoUE1JQl9JUEZPUldBUkRST1cpIG1hbGxvYyhzaXplb2YoTUlCX0lQRk9SV0FSRFJPVykpOwogICAgICAgICAgICAqb2xkcm91dGVfcm93ID0gKnJvdXRlX3JvdzsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBBQ1RJT046ICAgICAgICAgICAgICAgLyogUGVyZm9ybSB0aGUgU0VUIGFjdGlvbiAoaWYgcmV2ZXJzaWJsZSkgKi8KICAgICAgICBzd2l0Y2ggKHZhcikgewogICAgICAgIGNhc2UgSVBST1VURU1FVFJJQzE6CiAgICAgICAgICAgIG1ldHJpY19mbGFnID0gMTsKICAgICAgICAgICAgcm91dGVfcm93LT5kd0ZvcndhcmRNZXRyaWMxID0gKigoaW50ICopIHZhcl92YWwpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIElQUk9VVEVNRVRSSUMyOgogICAgICAgICAgICByb3V0ZV9yb3ctPmR3Rm9yd2FyZE1ldHJpYzIgPSAqKChpbnQgKikgdmFyX3ZhbCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgSVBST1VURU1FVFJJQzM6CiAgICAgICAgICAgIHJvdXRlX3Jvdy0+ZHdGb3J3YXJkTWV0cmljMyA9ICooKGludCAqKSB2YXJfdmFsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBJUFJPVVRFTUVUUklDNDoKICAgICAgICAgICAgcm91dGVfcm93LT5kd0ZvcndhcmRNZXRyaWM0ID0gKigoaW50ICopIHZhcl92YWwpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIElQUk9VVEVNRVRSSUM1OgogICAgICAgICAgICByb3V0ZV9yb3ctPmR3Rm9yd2FyZE1ldHJpYzUgPSAqKChpbnQgKikgdmFyX3ZhbCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgSVBST1VURVRZUEU6CiAgICAgICAgICAgIHJvdXRlX3Jvdy0+ZHdGb3J3YXJkVHlwZSA9ICooKGludCAqKSB2YXJfdmFsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBJUFJPVVRFQUdFOgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBJcnJlc3BlY3RpdmUgb2Ygc3VwcGllZCB2YWx1ZSwgdGhpcyB3aWxsIGJlIHNldCB3aXRoIDAuCiAgICAgICAgICAgICAqICogQXMgcm93IHdpbGwgYmUgdXBkYXRlZCBhbmQgdGhpcyBmaWVsZCBnaXZlcyB0aGUgbnVtYmVyIG9mIAogICAgICAgICAgICAgKiAqIHNlY29uZHMgc2luY2UgdGhpcyByb3V0ZSB3YXMgbGFzdCB1cGRhdGVkCiAgICAgICAgICAgICAqLwogICAgICAgICAgICByb3V0ZV9yb3ctPmR3Rm9yd2FyZEFnZSA9ICooKGludCAqKSB2YXJfdmFsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBJUFJPVVRFSUZJTkRFWDoKICAgICAgICAgICAgaW5kZXhfZmxhZyA9IDE7CiAgICAgICAgICAgIHJvdXRlX3Jvdy0+ZHdGb3J3YXJkSWZJbmRleCA9ICooKGludCAqKSB2YXJfdmFsKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgSVBST1VURU5FWFRIT1A6CiAgICAgICAgICAgIG5leHRob3BfZmxhZyA9IDE7CiAgICAgICAgICAgIHJvdXRlX3Jvdy0+ZHdGb3J3YXJkTmV4dEhvcCA9ICooKERXT1JEICopIHZhcl92YWwpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIElQUk9VVEVNQVNLOgogICAgICAgICAgICBtYXNrX2ZsYWcgPSAxOwogICAgICAgICAgICByb3V0ZV9yb3ctPmR3Rm9yd2FyZE1hc2sgPSAqKChEV09SRCAqKSB2YXJfdmFsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBJUFJPVVRFREVTVDoKICAgICAgICAgICAgZGVzdF9mbGFnID0gMTsKICAgICAgICAgICAgcm91dGVfcm93LT5kd0ZvcndhcmREZXN0ID0gKigoRFdPUkQgKikgdmFyX3ZhbCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wZCIsICJ1bmtub3duIHN1Yi1pZCAlZCBpbiB3cml0ZV9ydGVcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciArIDEpKTsKICAgICAgICAgICAgcmV0dmFsID0gU05NUF9FUlJfTk9UV1JJVEFCTEU7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXR2YWw7CiAgICBjYXNlIFVORE86CiAgICAgICAgLyoKICAgICAgICAgKiBSZXZlcnNlIHRoZSBTRVQgYWN0aW9uIGFuZCBmcmVlIHJlc291cmNlcyAKICAgICAgICAgKi8KICAgICAgICBpZiAob2xkcm91dGVfcm93KSB7CiAgICAgICAgICAgICpyb3V0ZV9yb3cgPSAqb2xkcm91dGVfcm93OwogICAgICAgICAgICBmcmVlKG9sZHJvdXRlX3Jvdyk7CiAgICAgICAgICAgIG9sZHJvdXRlX3JvdyA9IE5VTEw7CiAgICAgICAgICAgIGZyZWUocm91dGVfcm93KTsKICAgICAgICAgICAgcm91dGVfcm93ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBDT01NSVQ6CiAgICAgICAgLyoKICAgICAgICAgKiBXaGVuIHRoaXMgY2FzZSBlbnRlcmVkICdyb3V0ZV9yb3cnIHdpbGwgaGF2ZSB1c2VyIHN1cHBsaWVkIHZhbHVlcyBmb3IgYXNrZWQgZW50cmllcy4gCiAgICAgICAgICogKiBUaGF0cyB3aHkgaXQgaXMgZW5vdWdoIGlmIHdlIGNhbGwgU2V0SXBGb3J3YXJkRW50cnkvQ3JlYXRlSXBGb3J3YXJkRW50cnkgb25seSBvbmNlIAogICAgICAgICAqICogU2V0SXBGb3J3YXJkRU50cnkgaXMgbm90IGRvbmUgaW4gQUNUSU9OIHBoYXNlLCBhcyB0aGF0IHdpbGwgcmVzZXQgaXBSb3V0ZUFnZSBvbiBzdWNjZXNzCiAgICAgICAgICogKiBhbmQgaWYgYW55IHZhcmJpbmQgZmFpbHMsIHRoZW4gd2UgY2FuJ3QgVU5ETyB0aGUgY2hhbmdlIGZvciBpcFJPdXRlQWdlLiAKICAgICAgICAgKi8KICAgICAgICBpZiAocm91dGVfcm93KSB7CiAgICAgICAgICAgIGlmICghY3JlYXRlX2ZsYWcpIHsKCiAgICAgICAgICAgICAgICBpZiAoU2V0SXBGb3J3YXJkRW50cnkocm91dGVfcm93KSAhPSBOT19FUlJPUikgewogICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbid0IHNldCByb3V0ZSB0YWJsZSdzIHJvdyB3aXRoIHNwZWNpZmllZCB2YWx1ZVxuIik7CiAgICAgICAgICAgICAgICAgICAgcmV0dmFsID0gU05NUF9FUlJfQ09NTUlURkFJTEVEOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIFNFVCBvbiBJcFJvdXRlTmV4dEhvcCwgSXBSb3V0ZU1hc2sgJiBpcFJvdXRlRGVzdCBjcmVhdGVzIG5ldyByb3cuIAogICAgICAgICAgICAgICAgICAgICAqICpJZiBTZXQgc3VjY2VlZHMsIHRoZW4gZGVsZXRlIHRoZSBvbGQgcm93LgogICAgICAgICAgICAgICAgICAgICAqICogRG9uJ3Qga25vdyB5ZXQgd2hldGhlciBTRVQgb24gaXBSb3V0ZUlmSW5kZXggY3JlYXRlcyBuZXcgcm93LgogICAgICAgICAgICAgICAgICAgICAqICogSWYgaXQgY3JlYXRlcyB0aGVuIGluZGV4X2ZsYWcgc2hvdWxkIGJlIGFkZGVkIHRvIGZvbGxvd2luZyBpZiBzdGF0ZW1lbnQKICAgICAgICAgICAgICAgICAgICAgKi8KCiAgICAgICAgICAgICAgICAgICAgaWYgKGRlc3RfZmxhZyB8fCBuZXh0aG9wX2ZsYWcgfHwgbWFza19mbGFnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9sZHJvdXRlX3Jvdy0+ZHdGb3J3YXJkVHlwZSA9IDI7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChTZXRJcEZvcndhcmRFbnRyeShvbGRyb3V0ZV9yb3cpICE9IE5PX0VSUk9SKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNldCBvbiBpcFJvdXRlVGFibGUgY3JlYXRlZCBuZXcgcm93LCBidXQgZmFpbGVkIHRvIGRlbGV0ZSB0aGUgb2xkIHJvd1xuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR2YWwgPSBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogT25seSBpZiBjcmVhdGVfZmxhZywgbWFzaywgbmV4dGhvcCwgaWZJbmRleCBhbmQgbWV0cmljIGFyZSBzcGVjaWZpZWQsIGNyZWF0ZSBuZXcgZW50cnkgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoY3JlYXRlX2ZsYWcpIHsKICAgICAgICAgICAgICAgIGlmIChtYXNrX2ZsYWcgJiYgbmV4dGhvcF9mbGFnICYmIG1ldHJpY19mbGFnICYmIGluZGV4X2ZsYWcpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKHN0YXR1cyA9CiAgICAgICAgICAgICAgICAgICAgICAgICBDcmVhdGVJcEZvcndhcmRFbnRyeShyb3V0ZV9yb3cpKSAhPSBOT19FUlJPUikgewogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSW5zaWRlIENPTU1JVDogQ3JlYXRlSXBOZXRFbnRyeSBmYWlsZWQsIHN0YXR1cyAlbHVcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHZhbCA9IFNOTVBfRVJSX0NPTU1JVEZBSUxFRDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogRm9yIG5ldyBlbnRyeSwgbWFzaywgbmV4dGhvcCwgaWZJbmRleCBhbmQgbWV0cmljIG11c3QgYmUgc3VwcGxpZWQgCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2FzZSBDT01NSVQsIGNhbid0IGNyZWF0ZSB3aXRob3V0IGluZGV4LCBtYXNrLCBuZXh0SG9wIGFuZCBtZXRyaWNcbiIpOwogICAgICAgICAgICAgICAgICAgIHJldHZhbCA9IFNOTVBfRVJSX1dST05HVkFMVUU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgY2FzZSBGUkVFOgogICAgICAgIC8qCiAgICAgICAgICogRnJlZSBhbnkgcmVzb3VyY2VzIGFsbG9jYXRlZCAKICAgICAgICAgKi8KICAgICAgICBmcmVlKG9sZHJvdXRlX3Jvdyk7CiAgICAgICAgb2xkcm91dGVfcm93ID0gTlVMTDsKICAgICAgICBmcmVlKHJvdXRlX3Jvdyk7CiAgICAgICAgcm91dGVfcm93ID0gTlVMTDsKICAgICAgICBtYXNrX2ZsYWcgPSBuZXh0aG9wX2ZsYWcgPSBtZXRyaWNfZmxhZyA9IGluZGV4X2ZsYWcgPSBkZXN0X2ZsYWcgPQogICAgICAgICAgICAwOwogICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIHJldHZhbDsKfQoKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBXSU4zMiBjeWd3aW4gKi8K