LyoKICogIFN5c3RlbSBNSUIgZ3JvdXAgaW1wbGVtZW50YXRpb24gLSBzeXN0ZW0uYwogKgogKi8KLyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZiBIQVZFX1dJTlNPQ0tfSAojaW5jbHVkZSA8d2luc29jay5oPgojZW5kaWYKCiNpZiAhZGVmaW5lZChtaW5ndzMyKSAmJiBkZWZpbmVkKEhBVkVfU1lTX1RJTUVfSCkKI2luY2x1ZGUgPHN5cy90aW1lLmg+CiNlbmRpZgoKI2luY2x1ZGUgPGN0eXBlLmg+CiNpZiBIQVZFX1VUU05BTUVfSAojaW5jbHVkZSA8dXRzbmFtZS5oPgojZWxzZQojaWYgSEFWRV9TWVNfVVRTTkFNRV9ICiNpbmNsdWRlIDxzeXMvdXRzbmFtZS5oPgojZW5kaWYKI2VuZGlmCiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KCiNpbmNsdWRlICJ1dGlsX2Z1bmNzLmgiCiNpbmNsdWRlICJzeXN0ZW1fbWliLmgiCiNpbmNsdWRlICJzdHJ1Y3QuaCIKI2luY2x1ZGUgInN5c09SVGFibGUuaCIKCgogICAgICAgIC8qKioqKioqKioqKioqKioqKioqKioKCSAqCgkgKiAgS2VybmVsICYgaW50ZXJmYWNlIGluZm9ybWF0aW9uLAoJICogICBhbmQgaW50ZXJuYWwgZm9yd2FyZCBkZWNsYXJhdGlvbnMKCSAqCgkgKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBTWVNfU1RSSU5HX0xFTgkyNTYKY2hhciAgICAgICAgICAgIHZlcnNpb25fZGVzY3JbU1lTX1NUUklOR19MRU5dID0gTkVUU05NUF9WRVJTX0RFU0M7CmNoYXIgICAgICAgICAgICBzeXNDb250YWN0W1NZU19TVFJJTkdfTEVOXSA9IE5FVFNOTVBfU1lTX0NPTlRBQ1Q7CmNoYXIgICAgICAgICAgICBzeXNOYW1lW1NZU19TVFJJTkdfTEVOXSA9IE5FVFNOTVBfU1lTX05BTUU7CmNoYXIgICAgICAgICAgICBzeXNMb2NhdGlvbltTWVNfU1RSSU5HX0xFTl0gPSBORVRTTk1QX1NZU19MT0M7Cm9pZCAgICAgICAgICAgICBzeXNPYmplY3RJRFtNQVhfT0lEX0xFTl07CnNpemVfdCAgICAgICAgICBzeXNPYmplY3RJRExlbmd0aDsKCmV4dGVybiBvaWQgICAgICB2ZXJzaW9uX3N5c29pZFtdOwpleHRlcm4gaW50ICAgICAgdmVyc2lvbl9zeXNvaWRfbGVuOwoKY2hhciAgICAgICAgICAgIG9sZHZlcnNpb25fZGVzY3JbU1lTX1NUUklOR19MRU5dOwpjaGFyICAgICAgICAgICAgb2xkc3lzQ29udGFjdFtTWVNfU1RSSU5HX0xFTl07CmNoYXIgICAgICAgICAgICBvbGRzeXNOYW1lW1NZU19TVFJJTkdfTEVOXTsKY2hhciAgICAgICAgICAgIG9sZHN5c0xvY2F0aW9uW1NZU19TVFJJTkdfTEVOXTsKCmludCAgICAgICAgICAgICBzeXNTZXJ2aWNlcyA9IDcyOwppbnQgICAgICAgICAgICAgc3lzU2VydmljZXNDb25maWdlZCA9IDA7CgpleHRlcm4gb2lkICAgICAgdmVyc2lvbl9pZFtdOwpleHRlcm4gaW50ICAgICAgdmVyc2lvbl9pZF9sZW47CgpzdGF0aWMgaW50ICAgICAgc3lzQ29udGFjdFNldCA9IDAsIHN5c0xvY2F0aW9uU2V0ID0gMCwgc3lzTmFtZVNldCA9IDA7CgpXcml0ZU1ldGhvZCAgICAgd3JpdGVTeXN0ZW07CmludCAgICAgICAgICAgICBoZWFkZXJfc3lzdGVtKHN0cnVjdCB2YXJpYWJsZSAqLCBvaWQgKiwgc2l6ZV90ICosIGludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90ICosIFdyaXRlTWV0aG9kICoqKTsKCiNpZiAoZGVmaW5lZCAoV0lOMzIpICYmIGRlZmluZWQgKEhBVkVfV0lOMzJfUExBVEZPUk1fU0RLKSkgfHwgZGVmaW5lZCAobWluZ3czMikKc3RhdGljIHZvaWQgICAgIHdpbmRvd3NPU1ZlcnNpb25TdHJpbmcoY2hhciBbXSwgc2l6ZV90KTsKI2VuZGlmCgogICAgICAgIC8qKioqKioqKioqKioqKioqKioqKioKCSAqCgkgKiAgc25tcGQuY29uZiBjb25maWcgcGFyc2luZwoJICoKCSAqKioqKioqKioqKioqKioqKioqKiovCgp2b2lkCnN5c3RlbV9wYXJzZV9jb25maWdfc3lzZGVzY3IoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIpCnsKICAgIGNoYXIgICAgICAgICAgICB0bXBidWZbMTAyNF07CgogICAgaWYgKHN0cmxlbihjcHRyKSA+PSBzaXplb2YodmVyc2lvbl9kZXNjcikpIHsKICAgICAgICBzbnByaW50Zih0bXBidWYsCiAgICAgICAgICAgICAgICAgc2l6ZW9mKHRtcGJ1ZiksCiAgICAgICAgICAgICAgICAgInN5c2Rlc2NyIHRva2VuIHRvbyBsb25nIChtdXN0IGJlIDwgJWx1KTpcblx0JXMiLAogICAgICAgICAgICAgICAgICh1bnNpZ25lZCBsb25nKXNpemVvZih2ZXJzaW9uX2Rlc2NyKSwKICAgICAgICAgICAgICAgICBjcHRyKTsKICAgICAgICBjb25maWdfcGVycm9yKHRtcGJ1Zik7CiAgICB9IGVsc2UgaWYgKHN0cmNtcChjcHRyLCAiXCJcIiIpID09IDApIHsKICAgICAgICB2ZXJzaW9uX2Rlc2NyWzBdID0gJ1wwJzsKICAgIH0gZWxzZSB7CiAgICAgICAgc3RyY3B5KHZlcnNpb25fZGVzY3IsIGNwdHIpOwogICAgfQp9Cgp2b2lkCnN5c3RlbV9wYXJzZV9jb25maWdfc3lzbG9jKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpjcHRyKQp7CiAgICBjaGFyICAgICAgICAgICAgdG1wYnVmWzEwMjRdOwoKICAgIGlmIChzdHJsZW4oY3B0cikgPj0gc2l6ZW9mKHN5c0xvY2F0aW9uKSkgewogICAgICAgIHNucHJpbnRmKHRtcGJ1ZiwgMTAyNCwKICAgICAgICAgICAgICAgICAic3lzbG9jYXRpb24gdG9rZW4gdG9vIGxvbmcgKG11c3QgYmUgPCAlbHUpOlxuXHQlcyIsCiAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGxvbmcpc2l6ZW9mKHN5c0xvY2F0aW9uKSwgY3B0cik7CiAgICAgICAgY29uZmlnX3BlcnJvcih0bXBidWYpOwogICAgfQoKICAgIGlmIChzdHJjbXAodG9rZW4sICJwc3lzbG9jYXRpb24iKSA9PSAwKSB7CiAgICAgICAgaWYgKHN5c0xvY2F0aW9uU2V0IDwgMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGlzIGlzIGJvZ3VzIChhbmQgc2hvdWxkbid0IGhhcHBlbiBhbnl3YXkpIC0tIHRoZSBzeXNMb2NhdGlvbgogICAgICAgICAgICAgKiBpcyBhbHJlYWR5IGNvbmZpZ3VyZWQgcmVhZC1vbmx5LiAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgImlnbm9yaW5nIGF0dGVtcHRlZCBvdmVycmlkZSBvZiByZWFkLW9ubHkgc3lzTG9jYXRpb24uMFxuIik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzeXNMb2NhdGlvblNldCsrOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKHN5c0xvY2F0aW9uU2V0ID4gMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGlzIGlzIGJvZ3VzIChhbmQgc2hvdWxkbid0IGhhcHBlbiBhbnl3YXkpIC0tIHdlIGFscmVhZHkgcmVhZCBhCiAgICAgICAgICAgICAqIHBlcnNpc3RlbnQgdmFsdWUgb2Ygc3lzTG9jYXRpb24sIHdoaWNoIHdlIHNob3VsZCBpZ25vcmUgaW4KICAgICAgICAgICAgICogZmF2b3VyIG9mIHRoaXMgb25lLiAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgImlnbm9yaW5nIGF0dGVtcHRlZCBvdmVycmlkZSBvZiByZWFkLW9ubHkgc3lzTG9jYXRpb24uMFxuIik7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEZhbGwgdGhyb3VnaCBhbmQgY29weSBpbiB0aGlzIHZhbHVlLiAgCiAgICAgICAgICAgICAqLwogICAgICAgIH0KICAgICAgICBzeXNMb2NhdGlvblNldCA9IC0xOwogICAgfQoKICAgIGlmIChzdHJjbXAoY3B0ciwgIlwiXCIiKSA9PSAwKSB7CiAgICAgICAgc3lzTG9jYXRpb25bMF0gPSAnXDAnOwogICAgfSBlbHNlIGlmIChzdHJsZW4oY3B0cikgPCBzaXplb2Yoc3lzTG9jYXRpb24pKSB7CiAgICAgICAgc3RyY3B5KHN5c0xvY2F0aW9uLCBjcHRyKTsKICAgIH0KfQoKdm9pZApzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c2Nvbihjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0cikKewogICAgY2hhciAgICAgICAgICAgIHRtcGJ1ZlsxMDI0XTsKCiAgICBpZiAoc3RybGVuKGNwdHIpID49IHNpemVvZihzeXNDb250YWN0KSkgewogICAgICAgIHNucHJpbnRmKHRtcGJ1ZiwgMTAyNCwKICAgICAgICAgICAgICAgICAic3lzY29udGFjdCB0b2tlbiB0b28gbG9uZyAobXVzdCBiZSA8ICVsdSk6XG5cdCVzIiwKICAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZylzaXplb2Yoc3lzQ29udGFjdCksIGNwdHIpOwogICAgICAgIGNvbmZpZ19wZXJyb3IodG1wYnVmKTsKICAgIH0KCiAgICBpZiAoc3RyY21wKHRva2VuLCAicHN5c2NvbnRhY3QiKSA9PSAwKSB7CiAgICAgICAgaWYgKHN5c0NvbnRhY3RTZXQgPCAwKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRoaXMgaXMgYm9ndXMgKGFuZCBzaG91bGRuJ3QgaGFwcGVuIGFueXdheSkgLS0gdGhlIHN5c0NvbnRhY3QKICAgICAgICAgICAgICogaXMgYWxyZWFkeSBjb25maWd1cmVkIHJlYWQtb25seS4gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJpZ25vcmluZyBhdHRlbXB0ZWQgb3ZlcnJpZGUgb2YgcmVhZC1vbmx5IHN5c0NvbnRhY3QuMFxuIik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzeXNDb250YWN0U2V0Kys7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBpZiAoc3lzQ29udGFjdFNldCA+IDApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGhpcyBpcyBib2d1cyAoYW5kIHNob3VsZG4ndCBoYXBwZW4gYW55d2F5KSAtLSB3ZSBhbHJlYWR5IHJlYWQgYQogICAgICAgICAgICAgKiBwZXJzaXN0ZW50IHZhbHVlIG9mIHN5c0NvbnRhY3QsIHdoaWNoIHdlIHNob3VsZCBpZ25vcmUgaW4gZmF2b3VyCiAgICAgICAgICAgICAqIG9mIHRoaXMgb25lLiAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgImlnbm9yaW5nIGF0dGVtcHRlZCBvdmVycmlkZSBvZiByZWFkLW9ubHkgc3lzQ29udGFjdC4wXG4iKTsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogRmFsbCB0aHJvdWdoIGFuZCBjb3B5IGluIHRoaXMgdmFsdWUuICAKICAgICAgICAgICAgICovCiAgICAgICAgfQogICAgICAgIHN5c0NvbnRhY3RTZXQgPSAtMTsKICAgIH0KCiAgICBpZiAoc3RyY21wKGNwdHIsICJcIlwiIikgPT0gMCkgewogICAgICAgIHN5c0NvbnRhY3RbMF0gPSAnXDAnOwogICAgfSBlbHNlIGlmIChzdHJsZW4oY3B0cikgPCBzaXplb2Yoc3lzQ29udGFjdCkpIHsKICAgICAgICBzdHJjcHkoc3lzQ29udGFjdCwgY3B0cik7CiAgICB9Cn0KCnZvaWQKc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNuYW1lKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpjcHRyKQp7CiAgICBjaGFyICAgICAgICAgICAgdG1wYnVmWzEwMjRdOwoKICAgIGlmIChzdHJsZW4oY3B0cikgPj0gc2l6ZW9mKHN5c05hbWUpKSB7CiAgICAgICAgc25wcmludGYodG1wYnVmLCAxMDI0LAogICAgICAgICAgICAgICAgICJzeXNuYW1lIHRva2VuIHRvbyBsb25nIChtdXN0IGJlIDwgJWx1KTpcblx0JXMiLAogICAgICAgICAgICAgICAgICh1bnNpZ25lZCBsb25nKXNpemVvZihzeXNOYW1lKSwgY3B0cik7CiAgICAgICAgY29uZmlnX3BlcnJvcih0bXBidWYpOwogICAgfQoKICAgIGlmIChzdHJjbXAodG9rZW4sICJwc3lzbmFtZSIpID09IDApIHsKICAgICAgICBpZiAoc3lzTmFtZVNldCA8IDApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGhpcyBpcyBib2d1cyAoYW5kIHNob3VsZG4ndCBoYXBwZW4gYW55d2F5KSAtLSB0aGUgc3lzTmFtZQogICAgICAgICAgICAgKiBpcyBhbHJlYWR5IGNvbmZpZ3VyZWQgcmVhZC1vbmx5LiAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgImlnbm9yaW5nIGF0dGVtcHRlZCBvdmVycmlkZSBvZiByZWFkLW9ubHkgc3lzTmFtZS4wXG4iKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN5c05hbWVTZXQrKzsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGlmIChzeXNOYW1lU2V0ID4gMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGlzIGlzIGJvZ3VzIChhbmQgc2hvdWxkbid0IGhhcHBlbiBhbnl3YXkpIC0tIHdlIGFscmVhZHkgcmVhZCBhCiAgICAgICAgICAgICAqIHBlcnNpc3RlbnQgdmFsdWUgb2Ygc3lzTmFtZSwgd2hpY2ggd2Ugc2hvdWxkIGlnbm9yZSBpbiBmYXZvdXIKICAgICAgICAgICAgICogb2YgdGhpcyBvbmUuICAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAiaWdub3JpbmcgYXR0ZW1wdGVkIG92ZXJyaWRlIG9mIHJlYWQtb25seSBzeXNOYW1lLjBcbiIpOwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBGYWxsIHRocm91Z2ggYW5kIGNvcHkgaW4gdGhpcyB2YWx1ZS4gIAogICAgICAgICAgICAgKi8KICAgICAgICB9CiAgICAgICAgc3lzTmFtZVNldCA9IC0xOwogICAgfQoKICAgIGlmIChzdHJjbXAoY3B0ciwgIlwiXCIiKSA9PSAwKSB7CiAgICAgICAgc3lzTmFtZVswXSA9ICdcMCc7CiAgICB9IGVsc2UgaWYgKHN0cmxlbihjcHRyKSA8IHNpemVvZihzeXNOYW1lKSkgewogICAgICAgIHN0cmNweShzeXNOYW1lLCBjcHRyKTsKICAgIH0KfQoKdm9pZApzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c1NlcnZpY2VzKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpjcHRyKQp7CiAgICBzeXNTZXJ2aWNlcyA9IGF0b2koY3B0cik7CiAgICBzeXNTZXJ2aWNlc0NvbmZpZ2VkID0gMTsKfQoKdm9pZCBzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c09iamVjdElEKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpjcHRyKQp7CiAgICBjaGFyIHRtcGJ1ZlsxMDI0XTsKCiAgICBzeXNPYmplY3RJRExlbmd0aCA9IE1BWF9PSURfTEVOOwogICAgaWYgKCFyZWFkX29iamlkKGNwdHIsIHN5c09iamVjdElELCAmc3lzT2JqZWN0SURMZW5ndGgpKSB7CiAgICAgICAgc25wcmludGYodG1wYnVmLAogICAgICAgICAgICAgICAgIHNpemVvZih0bXBidWYpLAogICAgICAgICAgICAgICAgICJzeXNvYmplY3RpZCB0b2tlbiBub3QgYSBwYXJzYWJsZSBPSUQ6XG5cdCVzIiwKICAgICAgICAgICAgICAgICBjcHRyKTsKICAgICAgICBjb25maWdfcGVycm9yKHRtcGJ1Zik7CiAgICAgICAgbWVtY3B5KHN5c09iamVjdElELCB2ZXJzaW9uX3N5c29pZCwgdmVyc2lvbl9zeXNvaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgICAgIHN5c09iamVjdElETGVuZ3RoID0gdmVyc2lvbl9zeXNvaWRfbGVuOwogICAgfQp9CgoKICAgICAgICAvKioqKioqKioqKioqKioqKioqKioqCgkgKgoJICogIEluaXRpYWxpc2F0aW9uICYgY29tbW9uIGltcGxlbWVudGF0aW9uIGZ1bmN0aW9ucwoJICoKCSAqKioqKioqKioqKioqKioqKioqKiovCgovKgogKiBkZWZpbmUgdGhlIHN0cnVjdHVyZSB3ZSdyZSBnb2luZyB0byBhc2sgdGhlIGFnZW50IHRvIHJlZ2lzdGVyIG91cgogKiBpbmZvcm1hdGlvbiBhdCAKICovCnN0cnVjdCB2YXJpYWJsZTEgc3lzdGVtX3ZhcmlhYmxlc1tdID0gewogICAge1ZFUlNJT05fREVTQ1IsIEFTTl9PQ1RFVF9TVFIsIFJPTkxZLCB2YXJfc3lzdGVtLCAxLCB7MX19LAogICAge1ZFUlNJT05JRCwgQVNOX09CSkVDVF9JRCwgUk9OTFksIHZhcl9zeXN0ZW0sIDEsIHsyfX0sCiAgICB7VVBUSU1FLCBBU05fVElNRVRJQ0tTLCBST05MWSwgdmFyX3N5c3RlbSwgMSwgezN9fSwKICAgIHtTWVNDT05UQUNULCBBU05fT0NURVRfU1RSLCBSV1JJVEUsIHZhcl9zeXN0ZW0sIDEsIHs0fX0sCiAgICB7U1lTVEVNTkFNRSwgQVNOX09DVEVUX1NUUiwgUldSSVRFLCB2YXJfc3lzdGVtLCAxLCB7NX19LAogICAge1NZU0xPQ0FUSU9OLCBBU05fT0NURVRfU1RSLCBSV1JJVEUsIHZhcl9zeXN0ZW0sIDEsIHs2fX0sCiAgICB7U1lTU0VSVklDRVMsIEFTTl9JTlRFR0VSLCBST05MWSwgdmFyX3N5c3RlbSwgMSwgezd9fSwKICAgIHtTWVNPUkxBU1RDSEFOR0UsIEFTTl9USU1FVElDS1MsIFJPTkxZLCB2YXJfc3lzdGVtLCAxLCB7OH19Cn07Ci8qCiAqIERlZmluZSB0aGUgT0lEIHBvaW50ZXIgdG8gdGhlIHRvcCBvZiB0aGUgbWliIHRyZWUgdGhhdCB3ZSdyZQogKiByZWdpc3RlcmluZyB1bmRlcm5lYXRoIAogKi8Kb2lkICAgICAgICAgICAgIHN5c3RlbV92YXJpYWJsZXNfb2lkW10gPSB7IFNOTVBfT0lEX01JQjIsIDEgfTsKb2lkICAgICAgICAgICAgIHN5c3RlbV9tb2R1bGVfb2lkW10gPSB7IFNOTVBfT0lEX1NOTVBNT0RVTEVTLCAxIH07CmludCAgICAgICAgICAgICBzeXN0ZW1fbW9kdWxlX29pZF9sZW4gPQogICAgc2l6ZW9mKHN5c3RlbV9tb2R1bGVfb2lkKSAvIHNpemVvZihvaWQpOwppbnQgICAgICAgICAgICAgc3lzdGVtX21vZHVsZV9jb3VudCA9IDA7CgpzdGF0aWMgaW50CnN5c3RlbV9zdG9yZShpbnQgYSwgaW50IGIsIHZvaWQgKmMsIHZvaWQgKmQpCnsKICAgIGNoYXIgICAgICAgICAgICBsaW5lW1NOTVBfTUFYQlVGX1NNQUxMXTsKCiAgICBpZiAoc3lzTG9jYXRpb25TZXQgPiAwKSB7CiAgICAgICAgc25wcmludGYobGluZSwgU05NUF9NQVhCVUZfU01BTEwsICJwc3lzbG9jYXRpb24gJXMiLCBzeXNMb2NhdGlvbik7CiAgICAgICAgc25tcGRfc3RvcmVfY29uZmlnKGxpbmUpOwogICAgfQogICAgaWYgKHN5c0NvbnRhY3RTZXQgPiAwKSB7CiAgICAgICAgc25wcmludGYobGluZSwgU05NUF9NQVhCVUZfU01BTEwsICJwc3lzY29udGFjdCAlcyIsIHN5c0NvbnRhY3QpOwogICAgICAgIHNubXBkX3N0b3JlX2NvbmZpZyhsaW5lKTsKICAgIH0KICAgIGlmIChzeXNOYW1lU2V0ID4gMCkgewogICAgICAgIHNucHJpbnRmKGxpbmUsIFNOTVBfTUFYQlVGX1NNQUxMLCAicHN5c25hbWUgJXMiLCBzeXNOYW1lKTsKICAgICAgICBzbm1wZF9zdG9yZV9jb25maWcobGluZSk7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCnZvaWQKaW5pdF9zeXN0ZW1fbWliKHZvaWQpCnsKCiNpZmRlZiBIQVZFX1VOQU1FCiAgICBzdHJ1Y3QgdXRzbmFtZSAgdXRzTmFtZTsKCiAgICB1bmFtZSgmdXRzTmFtZSk7CiAgICBzbnByaW50Zih2ZXJzaW9uX2Rlc2NyLCBzaXplb2YodmVyc2lvbl9kZXNjciksCiAgICAgICAgICAgICIlcyAlcyAlcyAlcyAlcyIsIHV0c05hbWUuc3lzbmFtZSwKICAgICAgICAgICAgdXRzTmFtZS5ub2RlbmFtZSwgdXRzTmFtZS5yZWxlYXNlLCB1dHNOYW1lLnZlcnNpb24sCiAgICAgICAgICAgIHV0c05hbWUubWFjaGluZSk7CiAgICB2ZXJzaW9uX2Rlc2NyWyBzaXplb2YodmVyc2lvbl9kZXNjciktMSBdID0gMDsKI2Vsc2UKI2lmIEhBVkVfRVhFQ1YKICAgIHN0cnVjdCBleHRlbnNpYmxlIGV4dG1wOwoKICAgIC8qCiAgICAgKiBzZXQgZGVmYXVsdCB2YWx1ZXMgb2Ygc3lzdGVtIHN0dWZmIAogICAgICovCiAgICBzcHJpbnRmKGV4dG1wLmNvbW1hbmQsICIlcyAtYSIsIFVOQU1FUFJPRyk7CiAgICAvKgogICAgICogc2V0dXAgZGVmYXVsdHMgCiAgICAgKi8KICAgIGV4dG1wLnR5cGUgPSBFWEVDUFJPQzsKICAgIGV4dG1wLm5leHQgPSBOVUxMOwogICAgZXhlY19jb21tYW5kKCZleHRtcCk7CiAgICBzdHJsY3B5KHZlcnNpb25fZGVzY3IsIGV4dG1wLm91dHB1dCwgc2l6ZW9mKHZlcnNpb25fZGVzY3IpKTsKICAgIGlmIChzdHJsZW4odmVyc2lvbl9kZXNjcikgPj0gMSkKICAgICAgICB2ZXJzaW9uX2Rlc2NyW3N0cmxlbih2ZXJzaW9uX2Rlc2NyKSAtIDFdID0gMDsgLyogY2hvbXAgbmV3IGxpbmUgKi8KI2Vsc2UKI2lmIChkZWZpbmVkIChXSU4zMikgJiYgZGVmaW5lZCAoSEFWRV9XSU4zMl9QTEFURk9STV9TREspKSB8fCBkZWZpbmVkIChtaW5ndzMyKQogICAgd2luZG93c09TVmVyc2lvblN0cmluZyh2ZXJzaW9uX2Rlc2NyLCBzaXplb2YodmVyc2lvbl9kZXNjcikpOwojZWxzZQogICAgc3RyY3B5KHZlcnNpb25fZGVzY3IsICJ1bmtub3duIik7CiNlbmRpZgojZW5kaWYKI2VuZGlmCgojaWZkZWYgSEFWRV9HRVRIT1NUTkFNRQogICAgZ2V0aG9zdG5hbWUoc3lzTmFtZSwgc2l6ZW9mKHN5c05hbWUpKTsKI2Vsc2UKI2lmZGVmIEhBVkVfVU5BTUUKICAgIHN0cmxjcHkoc3lzTmFtZSwgdXRzTmFtZS5ub2RlbmFtZSwgc2l6ZW9mKHN5c05hbWUpKTsKI2Vsc2UKI2lmIGRlZmluZWQgKEhBVkVfRVhFQ1YpICYmICFkZWZpbmVkIChtaW5ndzMyKQogICAgc3ByaW50ZihleHRtcC5jb21tYW5kLCAiJXMgLW4iLCBVTkFNRVBST0cpOwogICAgLyoKICAgICAqIHNldHVwIGRlZmF1bHRzIAogICAgICovCiAgICBleHRtcC50eXBlID0gRVhFQ1BST0M7CiAgICBleHRtcC5uZXh0ID0gTlVMTDsKICAgIGV4ZWNfY29tbWFuZCgmZXh0bXApOwogICAgc3RybGNweShzeXNOYW1lLCBleHRtcC5vdXRwdXQsIHNpemVvZihzeXNOYW1lKSk7CiAgICBpZiAoc3RybGVuKHN5c05hbWUpID49IDEpCiAgICAgICAgc3lzTmFtZVtzdHJsZW4oc3lzTmFtZSkgLSAxXSA9IDA7IC8qIGNob21wIG5ldyBsaW5lICovCiNlbHNlCiAgICBzdHJjcHkoc3lzTmFtZSwgInVua25vd24iKTsKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBIQVZFX0VYRUNWICovCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogSEFWRV9VTkFNRSAqLwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEhBVkVfR0VUSE9TVE5BTUUgKi8KCiNpZiAoZGVmaW5lZCAoV0lOMzIpICYmIGRlZmluZWQgKEhBVkVfV0lOMzJfUExBVEZPUk1fU0RLKSkgfHwgZGVmaW5lZCAobWluZ3czMikKICB7CiAgICBIS0VZIGhLZXk7CiAgICAvKiBEZWZhdWx0IHN5c0NvbnRhY3QgaXMgdGhlIHJlZ2lzdGVyZWQgd2luZG93cyB1c2VyICovCiAgICBpZiAoUmVnT3BlbktleUV4KEhLRVlfTE9DQUxfTUFDSElORSwgIlNPRlRXQVJFXFxNaWNyb3NvZnRcXFdpbmRvd3MgTlRcXEN1cnJlbnRWZXJzaW9uIiwgMCwgS0VZX1FVRVJZX1ZBTFVFLCAmaEtleSkgPT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgY2hhciByZWdpc3RlcmVkT3duZXJbMjU2XSA9ICIiOwogICAgICAgRFdPUkQgcmVnaXN0ZXJlZE93bmVyU3ogPSAyNTY7CiAgICAgICBpZiAoUmVnUXVlcnlWYWx1ZUV4KGhLZXksICJSZWdpc3RlcmVkT3duZXIiLCBOVUxMLCBOVUxMLCAoTFBCWVRFKXJlZ2lzdGVyZWRPd25lciwgJnJlZ2lzdGVyZWRPd25lclN6KSA9PSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgICBzdHJjcHkoc3lzQ29udGFjdCwgcmVnaXN0ZXJlZE93bmVyKTsKICAgICAgIH0KICAgICAgIFJlZ0Nsb3NlS2V5KGhLZXkpOwogICAgfQogIH0KI2VuZGlmCgogICAgLyogZGVmYXVsdCBzeXNPYmplY3RJRCAqLwogICAgbWVtY3B5KHN5c09iamVjdElELCB2ZXJzaW9uX3N5c29pZCwgdmVyc2lvbl9zeXNvaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgc3lzT2JqZWN0SURMZW5ndGggPSB2ZXJzaW9uX3N5c29pZF9sZW47CgogICAgLyoKICAgICAqIHJlZ2lzdGVyIG91cnNlbHZlcyB3aXRoIHRoZSBhZ2VudCB0byBoYW5kbGUgb3VyIG1pYiB0cmVlIAogICAgICovCiAgICBSRUdJU1RFUl9NSUIoIm1pYklJL3N5c3RlbSIsIHN5c3RlbV92YXJpYWJsZXMsIHZhcmlhYmxlMSwKICAgICAgICAgICAgICAgICBzeXN0ZW1fdmFyaWFibGVzX29pZCk7CgogICAgaWYgKCsrc3lzdGVtX21vZHVsZV9jb3VudCA9PSAzKQogICAgICAgIFJFR0lTVEVSX1NZU09SX0VOVFJZKHN5c3RlbV9tb2R1bGVfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUaGUgTUlCIG1vZHVsZSBmb3IgU05NUHYyIGVudGl0aWVzIik7CgogICAgc3lzQ29udGFjdFNldCA9IHN5c0xvY2F0aW9uU2V0ID0gc3lzTmFtZVNldCA9IDA7CgogICAgLyoKICAgICAqIHJlZ2lzdGVyIG91ciBjb25maWcgaGFuZGxlcnMgCiAgICAgKi8KICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJzeXNkZXNjciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c2Rlc2NyLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIik7CiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigic3lzbG9jYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNsb2MsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibG9jYXRpb24iKTsKICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJzeXNjb250YWN0Iiwgc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNjb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAiY29udGFjdC1uYW1lIik7CiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigic3lzbmFtZSIsIHN5c3RlbV9wYXJzZV9jb25maWdfc3lzbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsICJub2RlLW5hbWUiKTsKICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJwc3lzbG9jYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNsb2MsIE5VTEwsIE5VTEwpOwogICAgc25tcGRfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoInBzeXNjb250YWN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbV9wYXJzZV9jb25maWdfc3lzY29uLCBOVUxMLCBOVUxMKTsKICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJwc3lzbmFtZSIsIHN5c3RlbV9wYXJzZV9jb25maWdfc3lzbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwpOwogICAgc25tcGRfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoInN5c3NlcnZpY2VzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbV9wYXJzZV9jb25maWdfc3lzU2VydmljZXMsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTlVNQkVSIik7CiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigic3lzb2JqZWN0aWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNPYmplY3RJRCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPSUQiKTsKICAgIHNubXBfcmVnaXN0ZXJfY2FsbGJhY2soU05NUF9DQUxMQkFDS19MSUJSQVJZLCBTTk1QX0NBTExCQUNLX1NUT1JFX0RBVEEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbV9zdG9yZSwgTlVMTCk7Cgp9CgoKICAgICAgICAvKioqKioqKioqKioqKioqKioqKioqCgkgKgoJICogIFN5c3RlbSBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbiBmdW5jdGlvbnMKCSAqCgkgKioqKioqKioqKioqKioqKioqKioqLwoKI2lmZGVmIFVTSU5HX01JQklJX1NZU09SVEFCTEVfTU9EVUxFCmV4dGVybiBzdHJ1Y3QgdGltZXZhbCBzeXNPUl9sYXN0Y2hhbmdlOwojZW5kaWYKCnVfY2hhciAgICAgICAgICoKdmFyX3N5c3RlbShzdHJ1Y3QgdmFyaWFibGUgKnZwLAogICAgICAgICAgIG9pZCAqIG5hbWUsCiAgICAgICAgICAgc2l6ZV90ICogbGVuZ3RoLAogICAgICAgICAgIGludCBleGFjdCwgc2l6ZV90ICogdmFyX2xlbiwgV3JpdGVNZXRob2QgKiogd3JpdGVfbWV0aG9kKQp7CiAgICBzdGF0aWMgdV9sb25nICAgdWxyZXQ7CgogICAgaWYgKGhlYWRlcl9nZW5lcmljKHZwLCBuYW1lLCBsZW5ndGgsIGV4YWN0LCB2YXJfbGVuLCB3cml0ZV9tZXRob2QpID09CiAgICAgICAgTUFUQ0hfRkFJTEVEKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIHN3aXRjaCAodnAtPm1hZ2ljKSB7CiAgICBjYXNlIFZFUlNJT05fREVTQ1I6CiAgICAgICAgKnZhcl9sZW4gPSBzdHJsZW4odmVyc2lvbl9kZXNjcik7CiAgICAgICAgcmV0dXJuICh1X2NoYXIgKikgdmVyc2lvbl9kZXNjcjsKICAgIGNhc2UgVkVSU0lPTklEOgogICAgICAgICp2YXJfbGVuID0gc3lzT2JqZWN0SURMZW5ndGggKiBzaXplb2Yoc3lzT2JqZWN0SURbMF0pOwogICAgICAgIHJldHVybiAodV9jaGFyICopc3lzT2JqZWN0SUQ7CiAgICBjYXNlIFVQVElNRToKICAgICAgICB1bHJldCA9IG5ldHNubXBfZ2V0X2FnZW50X3VwdGltZSgpOwogICAgICAgIHJldHVybiAoKHVfY2hhciAqKSAmIHVscmV0KTsKICAgIGNhc2UgU1lTQ09OVEFDVDoKICAgICAgICAqdmFyX2xlbiA9IHN0cmxlbihzeXNDb250YWN0KTsKICAgICAgICAqd3JpdGVfbWV0aG9kID0gd3JpdGVTeXN0ZW07CiAgICAgICAgcmV0dXJuICh1X2NoYXIgKikgc3lzQ29udGFjdDsKICAgIGNhc2UgU1lTVEVNTkFNRToKICAgICAgICAqdmFyX2xlbiA9IHN0cmxlbihzeXNOYW1lKTsKICAgICAgICAqd3JpdGVfbWV0aG9kID0gd3JpdGVTeXN0ZW07CiAgICAgICAgcmV0dXJuICh1X2NoYXIgKikgc3lzTmFtZTsKICAgIGNhc2UgU1lTTE9DQVRJT046CiAgICAgICAgKnZhcl9sZW4gPSBzdHJsZW4oc3lzTG9jYXRpb24pOwogICAgICAgICp3cml0ZV9tZXRob2QgPSB3cml0ZVN5c3RlbTsKICAgICAgICByZXR1cm4gKHVfY2hhciAqKSBzeXNMb2NhdGlvbjsKICAgIGNhc2UgU1lTU0VSVklDRVM6CiNpZiBORVRTTk1QX05PX0RVTU1ZX1ZBTFVFUwogICAgICAgIGlmICghc3lzU2VydmljZXNDb25maWdlZCkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiNlbmRpZgogICAgICAgIGxvbmdfcmV0dXJuID0gc3lzU2VydmljZXM7CiAgICAgICAgcmV0dXJuICh1X2NoYXIgKikgJiBsb25nX3JldHVybjsKCiNpZmRlZiBVU0lOR19NSUJJSV9TWVNPUlRBQkxFX01PRFVMRQogICAgY2FzZSBTWVNPUkxBU1RDSEFOR0U6CiAgICAgICAgdWxyZXQgPSBuZXRzbm1wX3RpbWV2YWxfdXB0aW1lKCZzeXNPUl9sYXN0Y2hhbmdlKTsKICAgICAgICByZXR1cm4gKCh1X2NoYXIgKikgJiB1bHJldCk7CiNlbmRpZgoKICAgIGRlZmF1bHQ6CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBkIiwgInVua25vd24gc3ViLWlkICVkIGluIHZhcl9zeXN0ZW1cbiIsCiAgICAgICAgICAgICAgICAgICAgdnAtPm1hZ2ljKSk7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKCgppbnQKd3JpdGVTeXN0ZW0oaW50IGFjdGlvbiwKICAgICAgICAgICAgdV9jaGFyICogdmFyX3ZhbCwKICAgICAgICAgICAgdV9jaGFyIHZhcl92YWxfdHlwZSwKICAgICAgICAgICAgc2l6ZV90IHZhcl92YWxfbGVuLAogICAgICAgICAgICB1X2NoYXIgKiBzdGF0UCwgb2lkICogbmFtZSwgc2l6ZV90IG5hbWVfbGVuKQp7CiAgICB1X2NoYXIgICAgICAgICAqY3A7CiAgICBjaGFyICAgICAgICAgICAqYnVmID0gTlVMTCwgKm9sZGJ1ZiA9IE5VTEw7CiAgICBpbnQgICAgICAgICAgICAgY291bnQsICpzZXR2YXIgPSBOVUxMOwoKICAgIHN3aXRjaCAoKGNoYXIpIG5hbWVbN10pIHsKICAgIGNhc2UgVkVSU0lPTl9ERVNDUjoKICAgIGNhc2UgVkVSU0lPTklEOgogICAgY2FzZSBVUFRJTUU6CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIkF0dGVtcHQgdG8gd3JpdGUgdG8gUi9PIE9JRFxuIik7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PVFdSSVRBQkxFOwogICAgY2FzZSBTWVNDT05UQUNUOgogICAgICAgIGJ1ZiA9IHN5c0NvbnRhY3Q7CiAgICAgICAgb2xkYnVmID0gb2xkc3lzQ29udGFjdDsKICAgICAgICBzZXR2YXIgPSAmc3lzQ29udGFjdFNldDsKICAgICAgICBicmVhazsKICAgIGNhc2UgU1lTVEVNTkFNRToKICAgICAgICBidWYgPSBzeXNOYW1lOwogICAgICAgIG9sZGJ1ZiA9IG9sZHN5c05hbWU7CiAgICAgICAgc2V0dmFyID0gJnN5c05hbWVTZXQ7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFNZU0xPQ0FUSU9OOgogICAgICAgIGJ1ZiA9IHN5c0xvY2F0aW9uOwogICAgICAgIG9sZGJ1ZiA9IG9sZHN5c0xvY2F0aW9uOwogICAgICAgIHNldHZhciA9ICZzeXNMb2NhdGlvblNldDsKICAgICAgICBicmVhazsKICAgIGNhc2UgU1lTU0VSVklDRVM6CiAgICBjYXNlIFNZU09STEFTVENIQU5HRToKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiQXR0ZW1wdCB0byB3cml0ZSB0byBSL08gT0lEXG4iKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9UV1JJVEFCTEU7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7IC8qID8/PyAqLwogICAgfQoKICAgIHN3aXRjaCAoYWN0aW9uKSB7CiAgICBjYXNlIFJFU0VSVkUxOiAgICAgICAgICAgICAvKiBDaGVjayB2YWx1ZXMgZm9yIGFjY2VwdGFiaWxpdHkgKi8KICAgICAgICBpZiAodmFyX3ZhbF90eXBlICE9IEFTTl9PQ1RFVF9TVFIpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5vdCBzdHJpbmdcbiIpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfV1JPTkdUWVBFOwogICAgICAgIH0KICAgICAgICBpZiAodmFyX3ZhbF9sZW4gPiBzaXplb2Yoc3lzTG9jYXRpb24pIC0gMSkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiYmFkIGxlbmd0aFxuIik7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9XUk9OR0xFTkdUSDsKICAgICAgICB9CgogICAgICAgIGZvciAoY3AgPSB2YXJfdmFsLCBjb3VudCA9IDA7IGNvdW50IDwgKGludCkgdmFyX3ZhbF9sZW47CiAgICAgICAgICAgICBjb3VudCsrLCBjcCsrKSB7CiAgICAgICAgICAgIGlmICghaXNwcmludCgqY3ApKSB7CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibm90IHByaW50ICV4XG4iLCAqY3ApOwogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX1dST05HVkFMVUU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHNldHZhciAhPSBOVUxMICYmICpzZXR2YXIgPCAwKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRoZSBvYmplY3QgaXMgc2V0IGluIGEgcmVhZC1vbmx5IGNvbmZpZ3VyYXRpb24gZmlsZS4gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PVFdSSVRBQkxFOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFJFU0VSVkUyOiAgICAgICAgICAgICAvKiBBbGxvY2F0ZSBtZW1vcnkgYW5kIHNpbWlsYXIgcmVzb3VyY2VzICovCgogICAgICAgIC8qCiAgICAgICAgICogVXNpbmcgc3RhdGljIHN0cmluZ3MsIHNvIG5vdGhpbmcgbmVlZHMgdG8gYmUgZG9uZSAKICAgICAgICAgKi8KICAgICAgICBicmVhazsKCiAgICBjYXNlIEFDVElPTjogICAgICAgICAgICAgICAvKiBQZXJmb3JtIHRoZSBTRVQgYWN0aW9uIChpZiByZXZlcnNpYmxlKSAqLwoKICAgICAgICAvKgogICAgICAgICAqIFNhdmUgdGhlIG9sZCB2YWx1ZSwgaW4gY2FzZSBvZiBVTkRPIAogICAgICAgICAqLwogICAgICAgIHN0cmNweShvbGRidWYsIGJ1Zik7CiAgICAgICAgbWVtY3B5KGJ1ZiwgdmFyX3ZhbCwgdmFyX3ZhbF9sZW4pOwogICAgICAgIGJ1Zlt2YXJfdmFsX2xlbl0gPSAwOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgVU5ETzogICAgICAgICAgICAgICAgIC8qIFJldmVyc2UgdGhlIFNFVCBhY3Rpb24gYW5kIGZyZWUgcmVzb3VyY2VzICovCgogICAgICAgIHN0cmNweShidWYsIG9sZGJ1Zik7CiAgICAgICAgb2xkYnVmWzBdID0gMDsKICAgICAgICBicmVhazsKCiAgICBjYXNlIENPTU1JVDoKICAgICAgICBpZiAoc2V0dmFyICE9IE5VTEwpIHsKICAgICAgICAgICAgKnNldHZhciA9IDE7CiAgICAgICAgfQogICAgICAgIHNubXBfc2F2ZV9wZXJzaXN0ZW50KG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0FQUFRZUEUpKTsKICAgICAgICAodm9pZCkgc25tcF9jYWxsX2NhbGxiYWNrcyhTTk1QX0NBTExCQUNLX0xJQlJBUlksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9DQUxMQkFDS19TVE9SRV9EQVRBLCBOVUxMKTsKICAgICAgICBzbm1wX2NsZWFuX3BlcnNpc3RlbnQobmV0c25tcF9kc19nZXRfc3RyaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0FQUFRZUEUpKTsKCiAgICBjYXNlIEZSRUU6ICAgICAgICAgICAgICAgICAvKiBGcmVlIGFueSByZXNvdXJjZXMgYWxsb2NhdGVkICovCgogICAgICAgIC8qCiAgICAgICAgICogTm8gcmVzb3VyY2VzIGhhdmUgYmVlbiBhbGxvY2F0ZWQsIGJ1dCAiZW1wdHkiIHRoZSAnb2xkYnVmJyAKICAgICAgICAgKi8KICAgICAgICBvbGRidWZbMF0gPSAwOwogICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIG9mIHdyaXRlU3lzdGVtICovCgogICAgICAgIC8qKioqKioqKioqKioqKioqKioqKioKCSAqCgkgKiAgSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gZnVuY3Rpb25zIC0gTm9uZQoJICoKCSAqKioqKioqKioqKioqKioqKioqKiovCgojaWYgKGRlZmluZWQgKFdJTjMyKSAmJiBkZWZpbmVkIChIQVZFX1dJTjMyX1BMQVRGT1JNX1NESykpIHx8IGRlZmluZWQgKG1pbmd3MzIpCnN0YXRpYyB2b2lkCndpbmRvd3NPU1ZlcnNpb25TdHJpbmcoY2hhciBzdHJpbmdidWZbXSwgc2l6ZV90IHN0cmluZ2J1ZmxlbikKewogICAgLyogY29weSBPUyB2ZXJzaW9uIHRvIHN0cmluZyBidWZmZXIgaW4gJ3VuYW1lIC1hJyBmb3JtYXQgKi8KICAgIE9TVkVSU0lPTklORk9FWCBvc1ZlcnNpb25JbmZvOwogICAgQk9PTCBnb3RPc1ZlcnNpb25JbmZvRXg7CiAgICBjaGFyIHdpbmRvd3NWZXJzaW9uWzI1Nl0gPSAiIjsKICAgIGNoYXIgaG9zdG5hbWVbMjU2XSA9ICIiOwogICAgY2hhciBpZGVudGlmaWVyWzI1Nl0gPSAiIjsKICAgIERXT1JEIGlkZW50aWZpZXJTeiA9IDI1NjsKICAgIEhLRVkgaEtleTsKCiAgICBaZXJvTWVtb3J5KCZvc1ZlcnNpb25JbmZvLCBzaXplb2YoT1NWRVJTSU9OSU5GT0VYKSk7CiAgICBvc1ZlcnNpb25JbmZvLmR3T1NWZXJzaW9uSW5mb1NpemUgPSBzaXplb2YoT1NWRVJTSU9OSU5GT0VYKTsKICAgIGdvdE9zVmVyc2lvbkluZm9FeCA9IEdldFZlcnNpb25FeCgoT1NWRVJTSU9OSU5GTyAqKSZvc1ZlcnNpb25JbmZvKTsKICAgIGlmIChnb3RPc1ZlcnNpb25JbmZvRXggPT0gRkFMU0UpIHsKICAgICAgIEdldFZlcnNpb25FeCgoT1NWRVJTSU9OSU5GTyAqKSZvc1ZlcnNpb25JbmZvKTsKICAgIH0KCiAgICBzd2l0Y2ggKG9zVmVyc2lvbkluZm8uZHdQbGF0Zm9ybUlkKSB7CiAgICAgICBjYXNlIFZFUl9QTEFURk9STV9XSU4zMl9OVDoKICAgICAgICAgIGlmICgob3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiA9PSA1KSAmJiAob3NWZXJzaW9uSW5mby5kd01pbm9yVmVyc2lvbiA9PSAyKSkgewogICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiU2VydmVyIDIwMDMiKTsKICAgICAgICAgIH0gZWxzZSBpZiAoKG9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24gPT0gNSkgJiYgKG9zVmVyc2lvbkluZm8uZHdNaW5vclZlcnNpb24gPT0gMSkpIHsKICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIlhQIik7CiAgICAgICAgICB9IGVsc2UgaWYgKChvc1ZlcnNpb25JbmZvLmR3TWFqb3JWZXJzaW9uID09IDUpICYmIChvc1ZlcnNpb25JbmZvLmR3TWlub3JWZXJzaW9uID09IDApKSB7CiAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIyMDAwIik7CiAgICAgICAgICB9IGVsc2UgaWYgKG9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24gPD0gNCkgewogICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiTlQiKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChnb3RPc1ZlcnNpb25JbmZvRXggPT0gVFJVRSkgewogICAgICAgICAgICAgaWYgKG9zVmVyc2lvbkluZm8ud1Byb2R1Y3RUeXBlID09IFZFUl9OVF9XT1JLU1RBVElPTikgewogICAgICAgICAgICAgICAgaWYgKG9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24gPT0gNCkgewogICAgICAgICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiIFdvcmtzdGF0aW9uIDQuMCIpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvc1ZlcnNpb25JbmZvLndTdWl0ZU1hc2sgJiBWRVJfU1VJVEVfUEVSU09OQUwpIHsKICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBIb21lIEVkaXRpb24iKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgUHJvZmVzc2lvbmFsIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9IGVsc2UgaWYgKG9zVmVyc2lvbkluZm8ud1Byb2R1Y3RUeXBlID09IFZFUl9OVF9TRVJWRVIpIHsKICAgICAgICAgICAgICAgIGlmICgob3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiA9PSA1KSAmJiAob3NWZXJzaW9uSW5mby5kd01pbm9yVmVyc2lvbiA9PSAyKSkgewogICAgICAgICAgICAgICAgICAgaWYgKG9zVmVyc2lvbkluZm8ud1N1aXRlTWFzayAmIFZFUl9TVUlURV9EQVRBQ0VOVEVSKSB7CiAgICAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgRGF0YWNlbnRlciBFZGl0aW9uIik7CiAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG9zVmVyc2lvbkluZm8ud1N1aXRlTWFzayAmIFZFUl9TVUlURV9FTlRFUlBSSVNFKSB7CiAgICAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgRW50ZXJwcmlzZSBFZGl0aW9uIik7CiAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG9zVmVyc2lvbkluZm8ud1N1aXRlTWFzayA9PSBWRVJfU1VJVEVfQkxBREUpIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBXZWIgRWRpdGlvbiIpOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBTdGFuZGFyZCBFZGl0aW9uIik7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChvc1ZlcnNpb25JbmZvLmR3TWFqb3JWZXJzaW9uID09IDUpICYmIChvc1ZlcnNpb25JbmZvLmR3TWlub3JWZXJzaW9uID09IDApKSB7CiAgICAgICAgICAgICAgICAgICBpZiAob3NWZXJzaW9uSW5mby53U3VpdGVNYXNrICYgVkVSX1NVSVRFX0RBVEFDRU5URVIpIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBEYXRhY2VudGVyIFNlcnZlciIpOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvc1ZlcnNpb25JbmZvLndTdWl0ZU1hc2sgJiBWRVJfU1VJVEVfRU5URVJQUklTRSkgewogICAgICAgICAgICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiIEFkdmFuY2VkIFNlcnZlciIpOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBTZXJ2ZXIiKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICBpZiAob3NWZXJzaW9uSW5mby53U3VpdGVNYXNrICYgVkVSX1NVSVRFX0VOVEVSUFJJU0UpIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBTZXJ2ZXIgNC4wLCBFbnRlcnByaXNlIEVkaXRpb24iKTsKICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgU2VydmVyIDQuMCIpOwogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgIGNoYXIgcHJvZHVjdFR5cGVbODBdOwogICAgICAgICAgICAgRFdPUkQgcHJvZHVjdFR5cGVTeiA9IDgwOwoKICAgICAgICAgICAgIGlmIChSZWdPcGVuS2V5RXgoSEtFWV9MT0NBTF9NQUNISU5FLCAiU1lTVEVNXFxDdXJyZW50Q29udHJvbFNldFxcQ29udHJvbFxcUHJvZHVjdE9wdGlvbnMiLCAwLCBLRVlfUVVFUllfVkFMVUUsICZoS2V5KSA9PSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgICAgICAgICBpZiAoUmVnUXVlcnlWYWx1ZUV4KGhLZXksICJQcm9kdWN0VHlwZSIsIE5VTEwsIE5VTEwsIChMUEJZVEUpIHByb2R1Y3RUeXBlLCAmcHJvZHVjdFR5cGVTeikgPT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgICAgICAgICAgICAgY2hhciB2ZXJzaW9uU3RyWzEwXTsKICAgICAgICAgICAgICAgICAgIGlmIChzdHJjbXBpKCJXSU5OVCIsIHByb2R1Y3RUeXBlKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgV29ya3N0YXRpb24iKTsKICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RyY21waSgiTEFOTUFOTlQiLCBwcm9kdWN0VHlwZSkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiIFNlcnZlciIpOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJjbXBpKCJTRVJWRVJOVCIsIHByb2R1Y3RUeXBlKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgQWR2YW5jZWQgU2VydmVyIik7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHZlcnNpb25TdHIsICIgJWQuJWQiLCAoaW50KW9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24sIChpbnQpb3NWZXJzaW9uSW5mby5kd01pbm9yVmVyc2lvbik7CiAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sIHZlcnNpb25TdHIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoaEtleSk7CiAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBicmVhazsKICAgICAgIGNhc2UgVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1M6CiAgICAgICAgICBpZiAoKG9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24gPT0gNCkgJiYgKG9zVmVyc2lvbkluZm8uZHdNaW5vclZlcnNpb24gPT0gOTApKSB7CiAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICJNRSIpOwogICAgICAgICAgfSBlbHNlIGlmICgob3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiA9PSA0KSAmJiAob3NWZXJzaW9uSW5mby5kd01pbm9yVmVyc2lvbiA9PSAxMCkpIHsKICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIjk4Iik7CiAgICAgICAgICAgICBpZiAob3NWZXJzaW9uSW5mby5zekNTRFZlcnNpb25bMV0gPT0gJ0EnKSB7CiAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgU0UiKTsKICAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSBpZiAoKG9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24gPT0gNCkgJiYgKG9zVmVyc2lvbkluZm8uZHdNaW5vclZlcnNpb24gPT0gMCkpIHsKICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIjk1Iik7CiAgICAgICAgICAgICBpZiAoKG9zVmVyc2lvbkluZm8uc3pDU0RWZXJzaW9uWzFdID09ICdDJykgfHwgKG9zVmVyc2lvbkluZm8uc3pDU0RWZXJzaW9uWzFdID09ICdCJykpIHsKICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBPU1IyIik7CiAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBnZXRob3N0bmFtZShob3N0bmFtZSwgc2l6ZW9mKGhvc3RuYW1lKSk7CgogICAgaWYgKFJlZ09wZW5LZXlFeChIS0VZX0xPQ0FMX01BQ0hJTkUsICJIQVJEV0FSRVxcREVTQ1JJUFRJT05cXFN5c3RlbVxcQ2VudHJhbFByb2Nlc3NvclxcMCIsIDAsIEtFWV9BTExfQUNDRVNTLCAmaEtleSkgPT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgUmVnUXVlcnlWYWx1ZUV4KGhLZXksICJJZGVudGlmaWVyIiwgTlVMTCwgTlVMTCwgKExQQllURSkmaWRlbnRpZmllciwgJmlkZW50aWZpZXJTeik7CiAgICAgICBSZWdDbG9zZUtleShoS2V5KTsKICAgIH0KCiAgICAvKiBPdXRwdXQgaXMgbWFkZSB0byBsb29rIGxpa2UgcmVzdWx0cyBmcm9tIHVuYW1lIC1hICovCiAgICBzbnByaW50ZihzdHJpbmdidWYsIHN0cmluZ2J1ZmxlbiwKICAgICAgICAgICAgIldpbmRvd3MgJXMgJWQuJWQuJWQgJXMgJXMgJXMiLCBob3N0bmFtZSwKICAgICAgICAgICAgIChpbnQpb3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiwgKGludClvc1ZlcnNpb25JbmZvLmR3TWlub3JWZXJzaW9uLAogICAgICAgICAgICAgKGludClvc1ZlcnNpb25JbmZvLmR3QnVpbGROdW1iZXIsIG9zVmVyc2lvbkluZm8uc3pDU0RWZXJzaW9uLAogICAgICAgICAgICAgd2luZG93c1ZlcnNpb24sIGlkZW50aWZpZXIpOwp9CiNlbmRpZiAvKiBXSU4zMiBhbmQgSEFWRV9XSU4zMl9QTEFURk9STV9TREsgb3IgbWluZ3czMiAqLwoK