LyoKICogIFN5c3RlbSBNSUIgZ3JvdXAgaW1wbGVtZW50YXRpb24gLSBzeXN0ZW0uYwogKgogKi8KLyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1mZWF0dXJlcy5oPgoKI2lmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKI2lmZGVmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZWxzZQojaW5jbHVkZSA8c3RyaW5ncy5oPgojZW5kaWYKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgoKI2lmIEhBVkVfVVRTTkFNRV9ICiNpbmNsdWRlIDx1dHNuYW1lLmg+CiNlbHNlCiNpZiBIQVZFX1NZU19VVFNOQU1FX0gKI2luY2x1ZGUgPHN5cy91dHNuYW1lLmg+CiNlbmRpZgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L3N5c09SVGFibGUuaD4KCiNpbmNsdWRlICJ1dGlsX2Z1bmNzLmgiCiNpbmNsdWRlICJzeXN0ZW1fbWliLmgiCiNpbmNsdWRlICJ1cGRhdGVzLmgiCgpuZXRzbm1wX2ZlYXR1cmVfcmVxdWlyZSh3YXRjaGVyX3JlYWRfb25seV9pbnRfc2NhbGFyKQoKICAgICAgICAvKioqKioqKioqKioqKioqKioqKioqCgkgKgoJICogIEtlcm5lbCAmIGludGVyZmFjZSBpbmZvcm1hdGlvbiwKCSAqICAgYW5kIGludGVybmFsIGZvcndhcmQgZGVjbGFyYXRpb25zCgkgKgoJICoqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgU1lTX1NUUklOR19MRU4JMjU2CnN0YXRpYyBjaGFyICAgICB2ZXJzaW9uX2Rlc2NyW1NZU19TVFJJTkdfTEVOXSA9IE5FVFNOTVBfVkVSU19ERVNDOwpzdGF0aWMgY2hhciAgICAgc3lzQ29udGFjdFtTWVNfU1RSSU5HX0xFTl0gPSBORVRTTk1QX1NZU19DT05UQUNUOwpzdGF0aWMgY2hhciAgICAgc3lzTmFtZVtTWVNfU1RSSU5HX0xFTl0gPSBORVRTTk1QX1NZU19OQU1FOwpzdGF0aWMgY2hhciAgICAgc3lzTG9jYXRpb25bU1lTX1NUUklOR19MRU5dID0gTkVUU05NUF9TWVNfTE9DOwpzdGF0aWMgb2lkICAgICAgc3lzT2JqZWN0SURbTUFYX09JRF9MRU5dOwpzdGF0aWMgc2l6ZV90IHN5c09iamVjdElEQnl0ZUxlbmd0aDsKCmV4dGVybiBvaWQgICAgICB2ZXJzaW9uX3N5c29pZFtdOwpleHRlcm4gaW50ICAgICAgdmVyc2lvbl9zeXNvaWRfbGVuOwoKc3RhdGljIGludCAgICAgIHN5c1NlcnZpY2VzID0gNzI7CnN0YXRpYyBpbnQgICAgICBzeXNTZXJ2aWNlc0NvbmZpZ2VkID0gMDsKCmV4dGVybiBvaWQgICAgICB2ZXJzaW9uX2lkW107CmV4dGVybiBpbnQgICAgICB2ZXJzaW9uX2lkX2xlbjsKCnN0YXRpYyBpbnQgICAgICBzeXNDb250YWN0U2V0ID0gMCwgc3lzTG9jYXRpb25TZXQgPSAwLCBzeXNOYW1lU2V0ID0gMDsKCiNpZiAoZGVmaW5lZCAoV0lOMzIpICYmIGRlZmluZWQgKEhBVkVfV0lOMzJfUExBVEZPUk1fU0RLKSkgfHwgZGVmaW5lZCAobWluZ3czMikKc3RhdGljIHZvaWQgICAgIHdpbmRvd3NPU1ZlcnNpb25TdHJpbmcoY2hhciBbXSwgc2l6ZV90KTsKI2VuZGlmCgogICAgICAgIC8qKioqKioqKioqKioqKioqKioqKioKCSAqCgkgKiAgc25tcGQuY29uZiBjb25maWcgcGFyc2luZwoJICoKCSAqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZApzeXN0ZW1fcGFyc2VfY29uZmlnX3N0cmluZzIoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpCnsKICAgIGlmIChzdHJsZW4oY3B0cikgPCBzaXplKSB7CiAgICAgICAgc3RyY3B5KHZhbHVlLCBjcHRyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgbmV0c25tcF9jb25maWdfZXJyb3IoIiVzIHRva2VuIHRvbyBsb25nIChtdXN0IGJlIDwgJWx1KTpcblx0JXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuLCAodW5zaWduZWQgbG9uZylzaXplLCBjcHRyKTsKICAgIH0KfQoKc3RhdGljIHZvaWQKc3lzdGVtX3BhcnNlX2NvbmZpZ19zdHJpbmcoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUsIGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50KiBndWFyZCkKewogICAgaWYgKCp0b2tlbiA9PSAncCcpIHsKICAgICAgICBpZiAoKmd1YXJkIDwgMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGlzIGlzIGJvZ3VzIChhbmQgc2hvdWxkbid0IGhhcHBlbiBhbnl3YXkpIC0tIHRoZSB2YWx1ZSBpcwogICAgICAgICAgICAgKiBhbHJlYWR5IGNvbmZpZ3VyZWQgcmVhZC1vbmx5LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJpZ25vcmluZyBhdHRlbXB0ZWQgb3ZlcnJpZGUgb2YgcmVhZC1vbmx5ICVzLjBcbiIsIG5hbWUpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgKmd1YXJkID0gMTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGlmICgqZ3VhcmQgPiAwKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRoaXMgaXMgYm9ndXMgKGFuZCBzaG91bGRuJ3QgaGFwcGVuIGFueXdheSkgLS0gd2UgYWxyZWFkeSByZWFkIGEKICAgICAgICAgICAgICogcGVyc2lzdGVudCB2YWx1ZSB3aGljaCB3ZSBzaG91bGQgaWdub3JlIGluIGZhdm91ciBvZiB0aGlzIG9uZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAiaWdub3JpbmcgYXR0ZW1wdGVkIG92ZXJyaWRlIG9mIHJlYWQtb25seSAlcy4wXG4iLCBuYW1lKTsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogRmFsbCB0aHJvdWdoIGFuZCBjb3B5IGluIHRoaXMgdmFsdWUuCiAgICAgICAgICAgICAqLwogICAgICAgIH0KICAgICAgICAqZ3VhcmQgPSAtMTsKICAgIH0KCiAgICBzeXN0ZW1fcGFyc2VfY29uZmlnX3N0cmluZzIodG9rZW4sIGNwdHIsIHZhbHVlLCBzaXplKTsKfQoKc3RhdGljIHZvaWQKc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNkZXNjcihjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0cikKewogICAgc3lzdGVtX3BhcnNlX2NvbmZpZ19zdHJpbmcyKHRva2VuLCBjcHRyLCB2ZXJzaW9uX2Rlc2NyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih2ZXJzaW9uX2Rlc2NyKSk7Cn0KCnN0YXRpYyB2b2lkCnN5c3RlbV9wYXJzZV9jb25maWdfc3lzbG9jKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpjcHRyKQp7CiAgICBzeXN0ZW1fcGFyc2VfY29uZmlnX3N0cmluZyh0b2tlbiwgY3B0ciwgInN5c0xvY2F0aW9uIiwgc3lzTG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3lzTG9jYXRpb24pLCAmc3lzTG9jYXRpb25TZXQpOwp9CgpzdGF0aWMgdm9pZApzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c2Nvbihjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0cikKewogICAgc3lzdGVtX3BhcnNlX2NvbmZpZ19zdHJpbmcodG9rZW4sIGNwdHIsICJzeXNDb250YWN0Iiwgc3lzQ29udGFjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzeXNDb250YWN0KSwgJnN5c0NvbnRhY3RTZXQpOwp9CgpzdGF0aWMgdm9pZApzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c25hbWUoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIpCnsKICAgIHN5c3RlbV9wYXJzZV9jb25maWdfc3RyaW5nKHRva2VuLCBjcHRyLCAic3lzTmFtZSIsIHN5c05hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3lzTmFtZSksICZzeXNOYW1lU2V0KTsKfQoKc3RhdGljIHZvaWQKc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNTZXJ2aWNlcyhjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0cikKewogICAgc3lzU2VydmljZXMgPSBhdG9pKGNwdHIpOwogICAgc3lzU2VydmljZXNDb25maWdlZCA9IDE7Cn0KCnN0YXRpYyB2b2lkCnN5c3RlbV9wYXJzZV9jb25maWdfc3lzT2JqZWN0SUQoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIpCnsKICAgIHNpemVfdCBzeXNPYmplY3RJRExlbmd0aCA9IE1BWF9PSURfTEVOOwogICAgaWYgKCFyZWFkX29iamlkKGNwdHIsIHN5c09iamVjdElELCAmc3lzT2JqZWN0SURMZW5ndGgpKSB7CgluZXRzbm1wX2NvbmZpZ19lcnJvcigic3lzb2JqZWN0aWQgdG9rZW4gbm90IGEgcGFyc2FibGUgT0lEOlxuXHQlcyIsCgkJCSAgICAgY3B0cik7CiAgICAgICAgc3lzT2JqZWN0SURCeXRlTGVuZ3RoID0gdmVyc2lvbl9zeXNvaWRfbGVuICAqIHNpemVvZihvaWQpOwogICAgICAgIG1lbWNweShzeXNPYmplY3RJRCwgdmVyc2lvbl9zeXNvaWQsIHN5c09iamVjdElEQnl0ZUxlbmd0aCk7CiAgICB9IGVsc2UKCgkJc3lzT2JqZWN0SURCeXRlTGVuZ3RoID0gc3lzT2JqZWN0SURMZW5ndGggKiBzaXplb2Yob2lkKTsKfQoKCiAgICAgICAgLyoqKioqKioqKioqKioqKioqKioqKgoJICoKCSAqICBJbml0aWFsaXNhdGlvbiAmIGNvbW1vbiBpbXBsZW1lbnRhdGlvbiBmdW5jdGlvbnMKCSAqCgkgKioqKioqKioqKioqKioqKioqKioqLwoKb2lkICAgICAgICAgICAgIHN5c3RlbV9tb2R1bGVfb2lkW10gPSB7IFNOTVBfT0lEX1NOTVBNT0RVTEVTLCAxIH07CmludCAgICAgICAgICAgICBzeXN0ZW1fbW9kdWxlX29pZF9sZW4gPSBPSURfTEVOR1RIKHN5c3RlbV9tb2R1bGVfb2lkKTsKaW50ICAgICAgICAgICAgIHN5c3RlbV9tb2R1bGVfY291bnQgPSAwOwoKc3RhdGljIGludApzeXN0ZW1fc3RvcmUoaW50IGEsIGludCBiLCB2b2lkICpjLCB2b2lkICpkKQp7CiAgICBjaGFyICAgICAgICAgICAgbGluZVtTTk1QX01BWEJVRl9TTUFMTF07CgogICAgaWYgKHN5c0xvY2F0aW9uU2V0ID4gMCkgewogICAgICAgIHNucHJpbnRmKGxpbmUsIFNOTVBfTUFYQlVGX1NNQUxMLCAicHN5c2xvY2F0aW9uICVzIiwgc3lzTG9jYXRpb24pOwogICAgICAgIHNubXBkX3N0b3JlX2NvbmZpZyhsaW5lKTsKICAgIH0KICAgIGlmIChzeXNDb250YWN0U2V0ID4gMCkgewogICAgICAgIHNucHJpbnRmKGxpbmUsIFNOTVBfTUFYQlVGX1NNQUxMLCAicHN5c2NvbnRhY3QgJXMiLCBzeXNDb250YWN0KTsKICAgICAgICBzbm1wZF9zdG9yZV9jb25maWcobGluZSk7CiAgICB9CiAgICBpZiAoc3lzTmFtZVNldCA+IDApIHsKICAgICAgICBzbnByaW50ZihsaW5lLCBTTk1QX01BWEJVRl9TTUFMTCwgInBzeXNuYW1lICVzIiwgc3lzTmFtZSk7CiAgICAgICAgc25tcGRfc3RvcmVfY29uZmlnKGxpbmUpOwogICAgfQoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgaW50CmhhbmRsZV9zeXNTZXJ2aWNlcyhuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CiNpZiBORVRTTk1QX05PX0RVTU1ZX1ZBTFVFUwogICAgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVQgJiYgIXN5c1NlcnZpY2VzQ29uZmlnZWQpCiAgICAgICAgbmV0c25tcF9yZXF1ZXN0X3NldF9lcnJvcihyZXF1ZXN0cywgU05NUF9OT1NVQ0hJTlNUQU5DRSk7CiNlbmRpZgogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCnN0YXRpYyBpbnQKaGFuZGxlX3N5c1VwVGltZShuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CiAgICBzbm1wX3NldF92YXJfdHlwZWRfaW50ZWdlcihyZXF1ZXN0cy0+cmVxdWVzdHZiLCBBU05fVElNRVRJQ0tTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9nZXRfYWdlbnRfdXB0aW1lKCkpOwogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCnZvaWQKaW5pdF9zeXN0ZW1fbWliKHZvaWQpCnsKCiNpZmRlZiBIQVZFX1VOQU1FCiAgICBzdHJ1Y3QgdXRzbmFtZSAgdXRzTmFtZTsKCiAgICB1bmFtZSgmdXRzTmFtZSk7CiAgICBzbnByaW50Zih2ZXJzaW9uX2Rlc2NyLCBzaXplb2YodmVyc2lvbl9kZXNjciksCiAgICAgICAgICAgICIlcyAlcyAlcyAlcyAlcyIsIHV0c05hbWUuc3lzbmFtZSwKICAgICAgICAgICAgdXRzTmFtZS5ub2RlbmFtZSwgdXRzTmFtZS5yZWxlYXNlLCB1dHNOYW1lLnZlcnNpb24sCiAgICAgICAgICAgIHV0c05hbWUubWFjaGluZSk7CiAgICB2ZXJzaW9uX2Rlc2NyWyBzaXplb2YodmVyc2lvbl9kZXNjciktMSBdID0gMDsKI2Vsc2UKI2lmIEhBVkVfRVhFQ1YKICAgIHN0cnVjdCBleHRlbnNpYmxlIGV4dG1wOwoKICAgIC8qCiAgICAgKiBzZXQgZGVmYXVsdCB2YWx1ZXMgb2Ygc3lzdGVtIHN0dWZmIAogICAgICovCiAgICBzcHJpbnRmKGV4dG1wLmNvbW1hbmQsICIlcyAtYSIsIFVOQU1FUFJPRyk7CiAgICAvKgogICAgICogc2V0dXAgZGVmYXVsdHMgCiAgICAgKi8KICAgIGV4dG1wLnR5cGUgPSBFWEVDUFJPQzsKICAgIGV4dG1wLm5leHQgPSBOVUxMOwogICAgZXhlY19jb21tYW5kKCZleHRtcCk7CiAgICBzdHJsY3B5KHZlcnNpb25fZGVzY3IsIGV4dG1wLm91dHB1dCwgc2l6ZW9mKHZlcnNpb25fZGVzY3IpKTsKICAgIGlmIChzdHJsZW4odmVyc2lvbl9kZXNjcikgPj0gMSkKICAgICAgICB2ZXJzaW9uX2Rlc2NyW3N0cmxlbih2ZXJzaW9uX2Rlc2NyKSAtIDFdID0gMDsgLyogY2hvbXAgbmV3IGxpbmUgKi8KI2Vsc2UKI2lmIChkZWZpbmVkIChXSU4zMikgJiYgZGVmaW5lZCAoSEFWRV9XSU4zMl9QTEFURk9STV9TREspKSB8fCBkZWZpbmVkIChtaW5ndzMyKQogICAgd2luZG93c09TVmVyc2lvblN0cmluZyh2ZXJzaW9uX2Rlc2NyLCBzaXplb2YodmVyc2lvbl9kZXNjcikpOwojZWxzZQogICAgc3RyY3B5KHZlcnNpb25fZGVzY3IsICJ1bmtub3duIik7CiNlbmRpZgojZW5kaWYKI2VuZGlmCgojaWZkZWYgSEFWRV9HRVRIT1NUTkFNRQogICAgZ2V0aG9zdG5hbWUoc3lzTmFtZSwgc2l6ZW9mKHN5c05hbWUpKTsKI2Vsc2UKI2lmZGVmIEhBVkVfVU5BTUUKICAgIHN0cmxjcHkoc3lzTmFtZSwgdXRzTmFtZS5ub2RlbmFtZSwgc2l6ZW9mKHN5c05hbWUpKTsKI2Vsc2UKI2lmIGRlZmluZWQgKEhBVkVfRVhFQ1YpICYmICFkZWZpbmVkIChtaW5ndzMyKQogICAgc3ByaW50ZihleHRtcC5jb21tYW5kLCAiJXMgLW4iLCBVTkFNRVBST0cpOwogICAgLyoKICAgICAqIHNldHVwIGRlZmF1bHRzIAogICAgICovCiAgICBleHRtcC50eXBlID0gRVhFQ1BST0M7CiAgICBleHRtcC5uZXh0ID0gTlVMTDsKICAgIGV4ZWNfY29tbWFuZCgmZXh0bXApOwogICAgc3RybGNweShzeXNOYW1lLCBleHRtcC5vdXRwdXQsIHNpemVvZihzeXNOYW1lKSk7CiAgICBpZiAoc3RybGVuKHN5c05hbWUpID49IDEpCiAgICAgICAgc3lzTmFtZVtzdHJsZW4oc3lzTmFtZSkgLSAxXSA9IDA7IC8qIGNob21wIG5ldyBsaW5lICovCiNlbHNlCiAgICBzdHJjcHkoc3lzTmFtZSwgInVua25vd24iKTsKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBIQVZFX0VYRUNWICovCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogSEFWRV9VTkFNRSAqLwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEhBVkVfR0VUSE9TVE5BTUUgKi8KCiNpZiAoZGVmaW5lZCAoV0lOMzIpICYmIGRlZmluZWQgKEhBVkVfV0lOMzJfUExBVEZPUk1fU0RLKSkgfHwgZGVmaW5lZCAobWluZ3czMikKICAgIHsKICAgICAgSEtFWSBoS2V5OwogICAgICAvKiBEZWZhdWx0IHN5c0NvbnRhY3QgaXMgdGhlIHJlZ2lzdGVyZWQgd2luZG93cyB1c2VyICovCiAgICAgIGlmIChSZWdPcGVuS2V5RXgoSEtFWV9MT0NBTF9NQUNISU5FLAogICAgICAgICAgICAgICAgICAgICAgICJTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3dzIE5UXFxDdXJyZW50VmVyc2lvbiIsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgS0VZX1FVRVJZX1ZBTFVFLCAmaEtleSkgPT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgICAgY2hhciByZWdpc3RlcmVkT3duZXJbMjU2XSA9ICIiOwogICAgICAgICAgRFdPUkQgcmVnaXN0ZXJlZE93bmVyU3ogPSAyNTY7CiAgICAgICAgICBpZiAoUmVnUXVlcnlWYWx1ZUV4KGhLZXksICJSZWdpc3RlcmVkT3duZXIiLCBOVUxMLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKXJlZ2lzdGVyZWRPd25lciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnJlZ2lzdGVyZWRPd25lclN6KSA9PSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgICAgICAgc3RyY3B5KHN5c0NvbnRhY3QsIHJlZ2lzdGVyZWRPd25lcik7CiAgICAgICAgICB9CiAgICAgICAgICBSZWdDbG9zZUtleShoS2V5KTsKICAgICAgfQogICAgfQojZW5kaWYKCiAgICAvKiBkZWZhdWx0IHN5c09iamVjdElEICovCiAgICBtZW1jcHkoc3lzT2JqZWN0SUQsIHZlcnNpb25fc3lzb2lkLCB2ZXJzaW9uX3N5c29pZF9sZW4gKiBzaXplb2Yob2lkKSk7CiAgICBzeXNPYmplY3RJREJ5dGVMZW5ndGggPSB2ZXJzaW9uX3N5c29pZF9sZW4gKiBzaXplb2Yob2lkKTsKCiAgICB7CiAgICAgICAgY29uc3Qgb2lkIHN5c0Rlc2NyX29pZFtdID0geyAxLCAzLCA2LCAxLCAyLCAxLCAxLCAxIH07CiAgICAgICAgc3RhdGljIG5ldHNubXBfd2F0Y2hlcl9pbmZvIHN5c0Rlc2NyX3dpbmZvOwogICAgICAgIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9zY2FsYXIoCiAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKAogICAgICAgICAgICAgICAgIm1pYklJL3N5c0Rlc2NyIiwgTlVMTCwgc3lzRGVzY3Jfb2lkLCBPSURfTEVOR1RIKHN5c0Rlc2NyX29pZCksCiAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9ST05MWSksCiAgICAgICAgICAgIG5ldHNubXBfaW5pdF93YXRjaGVyX2luZm8oJnN5c0Rlc2NyX3dpbmZvLCB2ZXJzaW9uX2Rlc2NyLCAwLAoJCQkJICAgICAgQVNOX09DVEVUX1NUUiwgV0FUQ0hFUl9TSVpFX1NUUkxFTikpOwogICAgfQogICAgewogICAgICAgIGNvbnN0IG9pZCBzeXNPYmplY3RJRF9vaWRbXSA9IHsgMSwgMywgNiwgMSwgMiwgMSwgMSwgMiB9OwogICAgICAgIHN0YXRpYyBuZXRzbm1wX3dhdGNoZXJfaW5mbyBzeXNPYmplY3RJRF93aW5mbzsKICAgICAgICBuZXRzbm1wX3JlZ2lzdGVyX3dhdGNoZWRfc2NhbGFyKAogICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbigKICAgICAgICAgICAgICAgICJtaWJJSS9zeXNPYmplY3RJRCIsIE5VTEwsCiAgICAgICAgICAgICAgICBzeXNPYmplY3RJRF9vaWQsIE9JRF9MRU5HVEgoc3lzT2JqZWN0SURfb2lkKSwKICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX1JPTkxZKSwKICAgICAgICAgICAgbmV0c25tcF9pbml0X3dhdGNoZXJfaW5mbzYoCgkJJnN5c09iamVjdElEX3dpbmZvLCBzeXNPYmplY3RJRCwgMCwgQVNOX09CSkVDVF9JRCwKICAgICAgICAgICAgICAgIFdBVENIRVJfTUFYX1NJWkUgfCBXQVRDSEVSX1NJWkVfSVNfUFRSLAogICAgICAgICAgICAgICAgTUFYX09JRF9MRU4sICZzeXNPYmplY3RJREJ5dGVMZW5ndGgpKTsKICAgIH0KICAgIHsKICAgICAgICBjb25zdCBvaWQgc3lzVXBUaW1lX29pZFtdID0geyAxLCAzLCA2LCAxLCAyLCAxLCAxLCAzIH07CiAgICAgICAgbmV0c25tcF9yZWdpc3Rlcl9zY2FsYXIoCiAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKAogICAgICAgICAgICAgICAgIm1pYklJL3N5c1VwVGltZSIsIGhhbmRsZV9zeXNVcFRpbWUsCiAgICAgICAgICAgICAgICBzeXNVcFRpbWVfb2lkLCBPSURfTEVOR1RIKHN5c1VwVGltZV9vaWQpLAogICAgICAgICAgICAgICAgSEFORExFUl9DQU5fUk9OTFkpKTsKICAgIH0KICAgIHsKICAgICAgICBjb25zdCBvaWQgc3lzQ29udGFjdF9vaWRbXSA9IHsgMSwgMywgNiwgMSwgMiwgMSwgMSwgNCB9OwogICAgICAgIHN0YXRpYyBuZXRzbm1wX3dhdGNoZXJfaW5mbyBzeXNDb250YWN0X3dpbmZvOwojaWZuZGVmIE5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVAogICAgICAgIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9zY2FsYXIoCiAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX3VwZGF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbigKICAgICAgICAgICAgICAgICJtaWJJSS9zeXNDb250YWN0Iiwgc3lzQ29udGFjdF9vaWQsIE9JRF9MRU5HVEgoc3lzQ29udGFjdF9vaWQpLCAKICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX1JXUklURSwgJnN5c0NvbnRhY3RTZXQpLAogICAgICAgICAgICBuZXRzbm1wX2luaXRfd2F0Y2hlcl9pbmZvKAogICAgICAgICAgICAgICAgJnN5c0NvbnRhY3Rfd2luZm8sIHN5c0NvbnRhY3QsIFNZU19TVFJJTkdfTEVOIC0gMSwKICAgICAgICAgICAgICAgIEFTTl9PQ1RFVF9TVFIsIFdBVENIRVJfTUFYX1NJWkUgfCBXQVRDSEVSX1NJWkVfU1RSTEVOKSk7CiNlbHNlICAvKiAhTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCiAgICAgICAgbmV0c25tcF9yZWdpc3Rlcl93YXRjaGVkX3NjYWxhcigKICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfdXBkYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKAogICAgICAgICAgICAgICAgIm1pYklJL3N5c0NvbnRhY3QiLCBzeXNDb250YWN0X29pZCwgT0lEX0xFTkdUSChzeXNDb250YWN0X29pZCksCiAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9ST05MWSwgJnN5c0NvbnRhY3RTZXQpLAogICAgICAgICAgICBuZXRzbm1wX2luaXRfd2F0Y2hlcl9pbmZvKAogICAgICAgICAgICAgICAgJnN5c0NvbnRhY3Rfd2luZm8sIHN5c0NvbnRhY3QsIFNZU19TVFJJTkdfTEVOIC0gMSwKICAgICAgICAgICAgICAgIEFTTl9PQ1RFVF9TVFIsIFdBVENIRVJfTUFYX1NJWkUgfCBXQVRDSEVSX1NJWkVfU1RSTEVOKSk7CiNlbmRpZiAvKiAhTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCiAgICB9CiAgICB7CiAgICAgICAgY29uc3Qgb2lkIHN5c05hbWVfb2lkW10gPSB7IDEsIDMsIDYsIDEsIDIsIDEsIDEsIDUgfTsKICAgICAgICBzdGF0aWMgbmV0c25tcF93YXRjaGVyX2luZm8gc3lzTmFtZV93aW5mbzsKI2lmbmRlZiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQKICAgICAgICBuZXRzbm1wX3JlZ2lzdGVyX3dhdGNoZWRfc2NhbGFyKAogICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV91cGRhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24oCiAgICAgICAgICAgICAgICAibWliSUkvc3lzTmFtZSIsIHN5c05hbWVfb2lkLCBPSURfTEVOR1RIKHN5c05hbWVfb2lkKSwKICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX1JXUklURSwgJnN5c05hbWVTZXQpLAogICAgICAgICAgICBuZXRzbm1wX2luaXRfd2F0Y2hlcl9pbmZvKAogICAgICAgICAgICAgICAgJnN5c05hbWVfd2luZm8sIHN5c05hbWUsIFNZU19TVFJJTkdfTEVOIC0gMSwgQVNOX09DVEVUX1NUUiwKICAgICAgICAgICAgICAgIFdBVENIRVJfTUFYX1NJWkUgfCBXQVRDSEVSX1NJWkVfU1RSTEVOKSk7CiNlbHNlICAvKiAhTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCiAgICAgICAgbmV0c25tcF9yZWdpc3Rlcl93YXRjaGVkX3NjYWxhcigKICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfdXBkYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKAogICAgICAgICAgICAgICAgIm1pYklJL3N5c05hbWUiLCBzeXNOYW1lX29pZCwgT0lEX0xFTkdUSChzeXNOYW1lX29pZCksCiAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9ST05MWSwgJnN5c05hbWVTZXQpLAogICAgICAgICAgICBuZXRzbm1wX2luaXRfd2F0Y2hlcl9pbmZvKAogICAgICAgICAgICAgICAgJnN5c05hbWVfd2luZm8sIHN5c05hbWUsIFNZU19TVFJJTkdfTEVOIC0gMSwgQVNOX09DVEVUX1NUUiwKICAgICAgICAgICAgICAgIFdBVENIRVJfTUFYX1NJWkUgfCBXQVRDSEVSX1NJWkVfU1RSTEVOKSk7CiNlbmRpZiAvKiAhTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCiAgICB9CiAgICB7CiAgICAgICAgY29uc3Qgb2lkIHN5c0xvY2F0aW9uX29pZFtdID0geyAxLCAzLCA2LCAxLCAyLCAxLCAxLCA2IH07CiAgICAgICAgc3RhdGljIG5ldHNubXBfd2F0Y2hlcl9pbmZvIHN5c0xvY2F0aW9uX3dpbmZvOwojaWZuZGVmIE5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVAogICAgICAgIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9zY2FsYXIoCiAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX3VwZGF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbigKICAgICAgICAgICAgICAgICJtaWJJSS9zeXNMb2NhdGlvbiIsIHN5c0xvY2F0aW9uX29pZCwKICAgICAgICAgICAgICAgIE9JRF9MRU5HVEgoc3lzTG9jYXRpb25fb2lkKSwKICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX1JXUklURSwgJnN5c0xvY2F0aW9uU2V0KSwKICAgICAgICAgICAgbmV0c25tcF9pbml0X3dhdGNoZXJfaW5mbygKCQkmc3lzTG9jYXRpb25fd2luZm8sIHN5c0xvY2F0aW9uLCBTWVNfU1RSSU5HX0xFTiAtIDEsCgkJQVNOX09DVEVUX1NUUiwgV0FUQ0hFUl9NQVhfU0laRSB8IFdBVENIRVJfU0laRV9TVFJMRU4pKTsKI2Vsc2UgIC8qICFORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQgKi8KICAgICAgICBuZXRzbm1wX3JlZ2lzdGVyX3dhdGNoZWRfc2NhbGFyKAogICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV91cGRhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24oCiAgICAgICAgICAgICAgICAibWliSUkvc3lzTG9jYXRpb24iLCBzeXNMb2NhdGlvbl9vaWQsCiAgICAgICAgICAgICAgICBPSURfTEVOR1RIKHN5c0xvY2F0aW9uX29pZCksCiAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9ST05MWSwgJnN5c0xvY2F0aW9uU2V0KSwKICAgICAgICAgICAgbmV0c25tcF9pbml0X3dhdGNoZXJfaW5mbygKCQkmc3lzTG9jYXRpb25fd2luZm8sIHN5c0xvY2F0aW9uLCBTWVNfU1RSSU5HX0xFTiAtIDEsCgkJQVNOX09DVEVUX1NUUiwgV0FUQ0hFUl9NQVhfU0laRSB8IFdBVENIRVJfU0laRV9TVFJMRU4pKTsKI2VuZGlmIC8qICFORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQgKi8KICAgIH0KICAgIHsKICAgICAgICBjb25zdCBvaWQgc3lzU2VydmljZXNfb2lkW10gPSB7IDEsIDMsIDYsIDEsIDIsIDEsIDEsIDcgfTsKICAgICAgICBuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV9pbnRfc2NhbGFyKAogICAgICAgICAgICAibWliSUkvc3lzU2VydmljZXMiLCBzeXNTZXJ2aWNlc19vaWQsIE9JRF9MRU5HVEgoc3lzU2VydmljZXNfb2lkKSwKICAgICAgICAgICAgJnN5c1NlcnZpY2VzLCBoYW5kbGVfc3lzU2VydmljZXMpOwogICAgfQogICAgaWYgKCsrc3lzdGVtX21vZHVsZV9jb3VudCA9PSAzKQogICAgICAgIFJFR0lTVEVSX1NZU09SX0VOVFJZKHN5c3RlbV9tb2R1bGVfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUaGUgTUlCIG1vZHVsZSBmb3IgU05NUHYyIGVudGl0aWVzIik7CgogICAgc3lzQ29udGFjdFNldCA9IHN5c0xvY2F0aW9uU2V0ID0gc3lzTmFtZVNldCA9IDA7CgogICAgLyoKICAgICAqIHJlZ2lzdGVyIG91ciBjb25maWcgaGFuZGxlcnMgCiAgICAgKi8KICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJzeXNkZXNjciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c2Rlc2NyLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIik7CiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigic3lzbG9jYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNsb2MsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibG9jYXRpb24iKTsKICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJzeXNjb250YWN0Iiwgc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNjb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAiY29udGFjdC1uYW1lIik7CiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigic3lzbmFtZSIsIHN5c3RlbV9wYXJzZV9jb25maWdfc3lzbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsICJub2RlLW5hbWUiKTsKICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJwc3lzbG9jYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNsb2MsIE5VTEwsIE5VTEwpOwogICAgc25tcGRfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoInBzeXNjb250YWN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbV9wYXJzZV9jb25maWdfc3lzY29uLCBOVUxMLCBOVUxMKTsKICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJwc3lzbmFtZSIsIHN5c3RlbV9wYXJzZV9jb25maWdfc3lzbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwpOwogICAgc25tcGRfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoInN5c3NlcnZpY2VzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbV9wYXJzZV9jb25maWdfc3lzU2VydmljZXMsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTlVNQkVSIik7CiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigic3lzb2JqZWN0aWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNPYmplY3RJRCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPSUQiKTsKICAgIHNubXBfcmVnaXN0ZXJfY2FsbGJhY2soU05NUF9DQUxMQkFDS19MSUJSQVJZLCBTTk1QX0NBTExCQUNLX1NUT1JFX0RBVEEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbV9zdG9yZSwgTlVMTCk7Cn0KCiAgICAgICAgLyoqKioqKioqKioqKioqKioqKioqKgoJICoKCSAqICBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBmdW5jdGlvbnMgLSBOb25lCgkgKgoJICoqKioqKioqKioqKioqKioqKioqKi8KCiNpZiAoZGVmaW5lZCAoV0lOMzIpICYmIGRlZmluZWQgKEhBVkVfV0lOMzJfUExBVEZPUk1fU0RLKSkgfHwgZGVmaW5lZCAobWluZ3czMikKc3RhdGljIHZvaWQKd2luZG93c09TVmVyc2lvblN0cmluZyhjaGFyIHN0cmluZ2J1ZltdLCBzaXplX3Qgc3RyaW5nYnVmbGVuKQp7CiAgICAvKiBjb3B5IE9TIHZlcnNpb24gdG8gc3RyaW5nIGJ1ZmZlciBpbiAndW5hbWUgLWEnIGZvcm1hdCAqLwogICAgT1NWRVJTSU9OSU5GT0VYIG9zVmVyc2lvbkluZm87CiAgICBCT09MIGdvdE9zVmVyc2lvbkluZm9FeDsKICAgIGNoYXIgd2luZG93c1ZlcnNpb25bMjU2XSA9ICIiOwogICAgY2hhciBob3N0bmFtZVsyNTZdID0gIiI7CiAgICBjaGFyIGlkZW50aWZpZXJbMjU2XSA9ICIiOwogICAgRFdPUkQgaWRlbnRpZmllclN6ID0gMjU2OwogICAgSEtFWSBoS2V5OwoKICAgIFplcm9NZW1vcnkoJm9zVmVyc2lvbkluZm8sIHNpemVvZihPU1ZFUlNJT05JTkZPRVgpKTsKICAgIG9zVmVyc2lvbkluZm8uZHdPU1ZlcnNpb25JbmZvU2l6ZSA9IHNpemVvZihPU1ZFUlNJT05JTkZPRVgpOwogICAgZ290T3NWZXJzaW9uSW5mb0V4ID0gR2V0VmVyc2lvbkV4KChPU1ZFUlNJT05JTkZPICopJm9zVmVyc2lvbkluZm8pOwogICAgaWYgKGdvdE9zVmVyc2lvbkluZm9FeCA9PSBGQUxTRSkgewogICAgICAgR2V0VmVyc2lvbkV4KChPU1ZFUlNJT05JTkZPICopJm9zVmVyc2lvbkluZm8pOwogICAgfQoKICAgIHN3aXRjaCAob3NWZXJzaW9uSW5mby5kd1BsYXRmb3JtSWQpIHsKICAgICAgIGNhc2UgVkVSX1BMQVRGT1JNX1dJTjMyX05UOgogICAgICAgICAgaWYgKChvc1ZlcnNpb25JbmZvLmR3TWFqb3JWZXJzaW9uID09IDUpICYmIChvc1ZlcnNpb25JbmZvLmR3TWlub3JWZXJzaW9uID09IDIpKSB7CiAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICJTZXJ2ZXIgMjAwMyIpOwogICAgICAgICAgfSBlbHNlIGlmICgob3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiA9PSA1KSAmJiAob3NWZXJzaW9uSW5mby5kd01pbm9yVmVyc2lvbiA9PSAxKSkgewogICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiWFAiKTsKICAgICAgICAgIH0gZWxzZSBpZiAoKG9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24gPT0gNSkgJiYgKG9zVmVyc2lvbkluZm8uZHdNaW5vclZlcnNpb24gPT0gMCkpIHsKICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIjIwMDAiKTsKICAgICAgICAgIH0gZWxzZSBpZiAob3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiA8PSA0KSB7CiAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICJOVCIpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGdvdE9zVmVyc2lvbkluZm9FeCA9PSBUUlVFKSB7CiAgICAgICAgICAgICBpZiAob3NWZXJzaW9uSW5mby53UHJvZHVjdFR5cGUgPT0gVkVSX05UX1dPUktTVEFUSU9OKSB7CiAgICAgICAgICAgICAgICBpZiAob3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiA9PSA0KSB7CiAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgV29ya3N0YXRpb24gNC4wIik7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG9zVmVyc2lvbkluZm8ud1N1aXRlTWFzayAmIFZFUl9TVUlURV9QRVJTT05BTCkgewogICAgICAgICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiIEhvbWUgRWRpdGlvbiIpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBQcm9mZXNzaW9uYWwiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgIH0gZWxzZSBpZiAob3NWZXJzaW9uSW5mby53UHJvZHVjdFR5cGUgPT0gVkVSX05UX1NFUlZFUikgewogICAgICAgICAgICAgICAgaWYgKChvc1ZlcnNpb25JbmZvLmR3TWFqb3JWZXJzaW9uID09IDUpICYmIChvc1ZlcnNpb25JbmZvLmR3TWlub3JWZXJzaW9uID09IDIpKSB7CiAgICAgICAgICAgICAgICAgICBpZiAob3NWZXJzaW9uSW5mby53U3VpdGVNYXNrICYgVkVSX1NVSVRFX0RBVEFDRU5URVIpIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBEYXRhY2VudGVyIEVkaXRpb24iKTsKICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAob3NWZXJzaW9uSW5mby53U3VpdGVNYXNrICYgVkVSX1NVSVRFX0VOVEVSUFJJU0UpIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBFbnRlcnByaXNlIEVkaXRpb24iKTsKICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAob3NWZXJzaW9uSW5mby53U3VpdGVNYXNrID09IFZFUl9TVUlURV9CTEFERSkgewogICAgICAgICAgICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiIFdlYiBFZGl0aW9uIik7CiAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiIFN0YW5kYXJkIEVkaXRpb24iKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKG9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24gPT0gNSkgJiYgKG9zVmVyc2lvbkluZm8uZHdNaW5vclZlcnNpb24gPT0gMCkpIHsKICAgICAgICAgICAgICAgICAgIGlmIChvc1ZlcnNpb25JbmZvLndTdWl0ZU1hc2sgJiBWRVJfU1VJVEVfREFUQUNFTlRFUikgewogICAgICAgICAgICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiIERhdGFjZW50ZXIgU2VydmVyIik7CiAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG9zVmVyc2lvbkluZm8ud1N1aXRlTWFzayAmIFZFUl9TVUlURV9FTlRFUlBSSVNFKSB7CiAgICAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgQWR2YW5jZWQgU2VydmVyIik7CiAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiIFNlcnZlciIpOwogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgIGlmIChvc1ZlcnNpb25JbmZvLndTdWl0ZU1hc2sgJiBWRVJfU1VJVEVfRU5URVJQUklTRSkgewogICAgICAgICAgICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiIFNlcnZlciA0LjAsIEVudGVycHJpc2UgRWRpdGlvbiIpOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBTZXJ2ZXIgNC4wIik7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgY2hhciBwcm9kdWN0VHlwZVs4MF07CiAgICAgICAgICAgICBEV09SRCBwcm9kdWN0VHlwZVN6ID0gODA7CgogICAgICAgICAgICAgaWYgKFJlZ09wZW5LZXlFeChIS0VZX0xPQ0FMX01BQ0hJTkUsICJTWVNURU1cXEN1cnJlbnRDb250cm9sU2V0XFxDb250cm9sXFxQcm9kdWN0T3B0aW9ucyIsIDAsIEtFWV9RVUVSWV9WQUxVRSwgJmhLZXkpID09IEVSUk9SX1NVQ0NFU1MpIHsKICAgICAgICAgICAgICAgIGlmIChSZWdRdWVyeVZhbHVlRXgoaEtleSwgIlByb2R1Y3RUeXBlIiwgTlVMTCwgTlVMTCwgKExQQllURSkgcHJvZHVjdFR5cGUsICZwcm9kdWN0VHlwZVN6KSA9PSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgICAgICAgICAgICBjaGFyIHZlcnNpb25TdHJbMTBdOwogICAgICAgICAgICAgICAgICAgaWYgKHN0cmNtcGkoIldJTk5UIiwgcHJvZHVjdFR5cGUpID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBXb3Jrc3RhdGlvbiIpOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJjbXBpKCJMQU5NQU5OVCIsIHByb2R1Y3RUeXBlKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgU2VydmVyIik7CiAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0cmNtcGkoIlNFUlZFUk5UIiwgcHJvZHVjdFR5cGUpID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBBZHZhbmNlZCBTZXJ2ZXIiKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIHNwcmludGYodmVyc2lvblN0ciwgIiAlZC4lZCIsIChpbnQpb3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiwgKGludClvc1ZlcnNpb25JbmZvLmR3TWlub3JWZXJzaW9uKTsKICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgdmVyc2lvblN0cik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleShoS2V5KTsKICAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGJyZWFrOwogICAgICAgY2FzZSBWRVJfUExBVEZPUk1fV0lOMzJfV0lORE9XUzoKICAgICAgICAgIGlmICgob3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiA9PSA0KSAmJiAob3NWZXJzaW9uSW5mby5kd01pbm9yVmVyc2lvbiA9PSA5MCkpIHsKICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIk1FIik7CiAgICAgICAgICB9IGVsc2UgaWYgKChvc1ZlcnNpb25JbmZvLmR3TWFqb3JWZXJzaW9uID09IDQpICYmIChvc1ZlcnNpb25JbmZvLmR3TWlub3JWZXJzaW9uID09IDEwKSkgewogICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiOTgiKTsKICAgICAgICAgICAgIGlmIChvc1ZlcnNpb25JbmZvLnN6Q1NEVmVyc2lvblsxXSA9PSAnQScpIHsKICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBTRSIpOwogICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIGlmICgob3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiA9PSA0KSAmJiAob3NWZXJzaW9uSW5mby5kd01pbm9yVmVyc2lvbiA9PSAwKSkgewogICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiOTUiKTsKICAgICAgICAgICAgIGlmICgob3NWZXJzaW9uSW5mby5zekNTRFZlcnNpb25bMV0gPT0gJ0MnKSB8fCAob3NWZXJzaW9uSW5mby5zekNTRFZlcnNpb25bMV0gPT0gJ0InKSkgewogICAgICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiIE9TUjIiKTsKICAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIGdldGhvc3RuYW1lKGhvc3RuYW1lLCBzaXplb2YoaG9zdG5hbWUpKTsKCiAgICBpZiAoUmVnT3BlbktleUV4KEhLRVlfTE9DQUxfTUFDSElORSwgIkhBUkRXQVJFXFxERVNDUklQVElPTlxcU3lzdGVtXFxDZW50cmFsUHJvY2Vzc29yXFwwIiwgMCwgS0VZX0FMTF9BQ0NFU1MsICZoS2V5KSA9PSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICBSZWdRdWVyeVZhbHVlRXgoaEtleSwgIklkZW50aWZpZXIiLCBOVUxMLCBOVUxMLCAoTFBCWVRFKSZpZGVudGlmaWVyLCAmaWRlbnRpZmllclN6KTsKICAgICAgIFJlZ0Nsb3NlS2V5KGhLZXkpOwogICAgfQoKICAgIC8qIE91dHB1dCBpcyBtYWRlIHRvIGxvb2sgbGlrZSByZXN1bHRzIGZyb20gdW5hbWUgLWEgKi8KICAgIHNucHJpbnRmKHN0cmluZ2J1Ziwgc3RyaW5nYnVmbGVuLAogICAgICAgICAgICAiV2luZG93cyAlcyAlZC4lZC4lZCAlcyAlcyAlcyIsIGhvc3RuYW1lLAogICAgICAgICAgICAgKGludClvc1ZlcnNpb25JbmZvLmR3TWFqb3JWZXJzaW9uLCAoaW50KW9zVmVyc2lvbkluZm8uZHdNaW5vclZlcnNpb24sCiAgICAgICAgICAgICAoaW50KW9zVmVyc2lvbkluZm8uZHdCdWlsZE51bWJlciwgb3NWZXJzaW9uSW5mby5zekNTRFZlcnNpb24sCiAgICAgICAgICAgICB3aW5kb3dzVmVyc2lvbiwgaWRlbnRpZmllcik7Cn0KI2VuZGlmIC8qIFdJTjMyIGFuZCBIQVZFX1dJTjMyX1BMQVRGT1JNX1NESyBvciBtaW5ndzMyICovCgo=