Lyogc3RhdGVtZW50LmMgLSB0aGUgc3RhdGVtZW50IHR5cGUKICoKICogQ29weXJpZ2h0IChDKSAyMDA1LTIwMDYgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgogKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBweXNxbGl0ZS4KICoKICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICogd2FycmFudHkuICBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlcwogKiBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgogKgogKiBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSwKICogaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogKiBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6CiAqCiAqIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiAqICAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlCiAqICAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQogKiAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgogKiAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZQogKiAgICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAqIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCiAqLwoKI2luY2x1ZGUgInN0YXRlbWVudC5oIgojaW5jbHVkZSAiY3Vyc29yLmgiCiNpbmNsdWRlICJjb25uZWN0aW9uLmgiCiNpbmNsdWRlICJtaWNyb3Byb3RvY29scy5oIgojaW5jbHVkZSAicHJlcGFyZV9wcm90b2NvbC5oIgojaW5jbHVkZSAic3FsaXRlY29tcGF0LmgiCgovKiBwcm90b3R5cGVzICovCnN0YXRpYyBpbnQgcHlzcWxpdGVfY2hlY2tfcmVtYWluaW5nX3NxbChjb25zdCBjaGFyKiB0YWlsKTsKCnR5cGVkZWYgZW51bSB7CiAgICBMSU5FQ09NTUVOVF8xLAogICAgSU5fTElORUNPTU1FTlQsCiAgICBDT01NRU5UU1RBUlRfMSwKICAgIElOX0NPTU1FTlQsCiAgICBDT01NRU5URU5EXzEsCiAgICBOT1JNQUwKfSBwYXJzZV9yZW1haW5pbmdfc3FsX3N0YXRlOwoKaW50IHB5c3FsaXRlX3N0YXRlbWVudF9jcmVhdGUocHlzcWxpdGVfU3RhdGVtZW50KiBzZWxmLCBweXNxbGl0ZV9Db25uZWN0aW9uKiBjb25uZWN0aW9uLCBQeU9iamVjdCogc3FsKQp7CiAgICBjb25zdCBjaGFyKiB0YWlsOwogICAgaW50IHJjOwogICAgY29uc3QgY2hhciogc3FsX2NzdHI7CiAgICBQeV9zc2l6ZV90IHNxbF9jc3RyX2xlbjsKCiAgICBzZWxmLT5zdCA9IE5VTEw7CiAgICBzZWxmLT5pbl91c2UgPSAwOwoKICAgIHNxbF9jc3RyID0gUHlVbmljb2RlX0FzU3RyaW5nQW5kU2l6ZShzcWwsICZzcWxfY3N0cl9sZW4pOwogICAgaWYgKHNxbF9jc3RyID09IE5VTEwpIHsKICAgICAgICByYyA9IFBZU1FMSVRFX1NRTF9XUk9OR19UWVBFOwogICAgICAgIHJldHVybiByYzsKICAgIH0KCiAgICBzZWxmLT5pbl93ZWFrcmVmbGlzdCA9IE5VTEw7CiAgICBQeV9JTkNSRUYoc3FsKTsKICAgIHNlbGYtPnNxbCA9IHNxbDsKCiAgICByYyA9IHNxbGl0ZTNfcHJlcGFyZShjb25uZWN0aW9uLT5kYiwKICAgICAgICAgICAgICAgICAgICAgICAgIHNxbF9jc3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgLTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+c3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAmdGFpbCk7CgogICAgc2VsZi0+ZGIgPSBjb25uZWN0aW9uLT5kYjsKCiAgICBpZiAocmMgPT0gU1FMSVRFX09LICYmIHB5c3FsaXRlX2NoZWNrX3JlbWFpbmluZ19zcWwodGFpbCkpIHsKICAgICAgICAodm9pZClzcWxpdGUzX2ZpbmFsaXplKHNlbGYtPnN0KTsKICAgICAgICBzZWxmLT5zdCA9IE5VTEw7CiAgICAgICAgcmMgPSBQWVNRTElURV9UT09fTVVDSF9TUUw7CiAgICB9CgogICAgcmV0dXJuIHJjOwp9CgppbnQgcHlzcWxpdGVfc3RhdGVtZW50X2JpbmRfcGFyYW1ldGVyKHB5c3FsaXRlX1N0YXRlbWVudCogc2VsZiwgaW50IHBvcywgUHlPYmplY3QqIHBhcmFtZXRlcikKewogICAgaW50IHJjID0gU1FMSVRFX09LOwojaWZkZWYgSEFWRV9MT05HX0xPTkcKICAgIFBZX0xPTkdfTE9ORyBsb25nbG9uZ3ZhbDsKI2Vsc2UKICAgIGxvbmcgbG9uZ3ZhbDsKI2VuZGlmCiAgICBjb25zdCBjaGFyKiBidWZmZXI7CiAgICBjaGFyKiBzdHJpbmc7CiAgICBQeV9zc2l6ZV90IGJ1ZmxlbjsKCiAgICBpZiAocGFyYW1ldGVyID09IFB5X05vbmUpIHsKICAgICAgICByYyA9IHNxbGl0ZTNfYmluZF9udWxsKHNlbGYtPnN0LCBwb3MpOwojaWZkZWYgSEFWRV9MT05HX0xPTkcKICAgIH0gZWxzZSBpZiAoUHlMb25nX0NoZWNrKHBhcmFtZXRlcikpIHsKICAgICAgICBsb25nbG9uZ3ZhbCA9IFB5TG9uZ19Bc0xvbmdMb25nKHBhcmFtZXRlcik7CiAgICAgICAgLyogaW4gdGhlIG92ZXJmbG93IGVycm9yIGNhc2UsIGxvbmdsb25ndmFsIGlzIC0xLCBhbmQgYW4gZXhjZXB0aW9uIGlzIHNldCAqLwogICAgICAgIHJjID0gc3FsaXRlM19iaW5kX2ludDY0KHNlbGYtPnN0LCBwb3MsIChzcWxpdGVfaW50NjQpbG9uZ2xvbmd2YWwpOwojZWxzZQogICAgfSBlbHNlIGlmIChQeUxvbmdfQ2hlY2socGFyYW1ldGVyKSkgewogICAgICAgIGxvbmd2YWwgPSBQeUxvbmdfQXNMb25nKHBhcmFtZXRlcik7CiAgICAgICAgLyogaW4gdGhlIG92ZXJmbG93IGVycm9yIGNhc2UsIGxvbmd2YWwgaXMgLTEsIGFuZCBhbiBleGNlcHRpb24gaXMgc2V0ICovCiAgICAgICAgcmMgPSBzcWxpdGUzX2JpbmRfaW50NjQoc2VsZi0+c3QsIHBvcywgKHNxbGl0ZV9pbnQ2NClsb25ndmFsKTsKI2VuZGlmCiAgICB9IGVsc2UgaWYgKFB5RmxvYXRfQ2hlY2socGFyYW1ldGVyKSkgewogICAgICAgIHJjID0gc3FsaXRlM19iaW5kX2RvdWJsZShzZWxmLT5zdCwgcG9zLCBQeUZsb2F0X0FzRG91YmxlKHBhcmFtZXRlcikpOwogICAgfSBlbHNlIGlmIFB5VW5pY29kZV9DaGVjayhwYXJhbWV0ZXIpIHsKICAgICAgICBzdHJpbmcgPSBQeVVuaWNvZGVfQXNTdHJpbmcocGFyYW1ldGVyKTsKCiAgICAgICAgcmMgPSBzcWxpdGUzX2JpbmRfdGV4dChzZWxmLT5zdCwgcG9zLCBzdHJpbmcsIC0xLCBTUUxJVEVfVFJBTlNJRU5UKTsKICAgIH0gZWxzZSBpZiAoUHlPYmplY3RfQ2hlY2tCdWZmZXIocGFyYW1ldGVyKSkgewogICAgICAgIGlmIChQeU9iamVjdF9Bc0NoYXJCdWZmZXIocGFyYW1ldGVyLCAmYnVmZmVyLCAmYnVmbGVuKSA9PSAwKSB7CiAgICAgICAgICAgIHJjID0gc3FsaXRlM19iaW5kX2Jsb2Ioc2VsZi0+c3QsIHBvcywgYnVmZmVyLCBidWZsZW4sIFNRTElURV9UUkFOU0lFTlQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAiY291bGQgbm90IGNvbnZlcnQgQkxPQiB0byBidWZmZXIiKTsKICAgICAgICAgICAgcmMgPSAtMTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIHJjID0gLTE7CiAgICB9CgogICAgcmV0dXJuIHJjOwp9Cgp2b2lkIHB5c3FsaXRlX3N0YXRlbWVudF9iaW5kX3BhcmFtZXRlcnMocHlzcWxpdGVfU3RhdGVtZW50KiBzZWxmLCBQeU9iamVjdCogcGFyYW1ldGVycykKewogICAgUHlPYmplY3QqIGN1cnJlbnRfcGFyYW07CiAgICBQeU9iamVjdCogYWRhcHRlZDsKICAgIGNvbnN0IGNoYXIqIGJpbmRpbmdfbmFtZTsKICAgIGludCBpOwogICAgaW50IHJjOwogICAgaW50IG51bV9wYXJhbXNfbmVlZGVkOwogICAgaW50IG51bV9wYXJhbXM7CgogICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgbnVtX3BhcmFtc19uZWVkZWQgPSBzcWxpdGUzX2JpbmRfcGFyYW1ldGVyX2NvdW50KHNlbGYtPnN0KTsKICAgIFB5X0VORF9BTExPV19USFJFQURTCgogICAgaWYgKFB5RGljdF9DaGVjayhwYXJhbWV0ZXJzKSkgewogICAgICAgIC8qIHBhcmFtZXRlcnMgcGFzc2VkIGFzIGRpY3Rpb25hcnkgKi8KICAgICAgICBmb3IgKGkgPSAxOyBpIDw9IG51bV9wYXJhbXNfbmVlZGVkOyBpKyspIHsKICAgICAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgICAgICAgICBiaW5kaW5nX25hbWUgPSBzcWxpdGUzX2JpbmRfcGFyYW1ldGVyX25hbWUoc2VsZi0+c3QsIGkpOwogICAgICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwogICAgICAgICAgICBpZiAoIWJpbmRpbmdfbmFtZSkgewogICAgICAgICAgICAgICAgUHlFcnJfRm9ybWF0KHB5c3FsaXRlX1Byb2dyYW1taW5nRXJyb3IsICJCaW5kaW5nICVkIGhhcyBubyBuYW1lLCBidXQgeW91IHN1cHBsaWVkIGEgZGljdGlvbmFyeSAod2hpY2ggaGFzIG9ubHkgbmFtZXMpLiIsIGkpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBiaW5kaW5nX25hbWUrKzsgLyogc2tpcCBmaXJzdCBjaGFyICh0aGUgY29sb24pICovCiAgICAgICAgICAgIGN1cnJlbnRfcGFyYW0gPSBQeURpY3RfR2V0SXRlbVN0cmluZyhwYXJhbWV0ZXJzLCBiaW5kaW5nX25hbWUpOwogICAgICAgICAgICBpZiAoIWN1cnJlbnRfcGFyYW0pIHsKICAgICAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChweXNxbGl0ZV9Qcm9ncmFtbWluZ0Vycm9yLCAiWW91IGRpZCBub3Qgc3VwcGx5IGEgdmFsdWUgZm9yIGJpbmRpbmcgJWQuIiwgaSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFB5X0lOQ1JFRihjdXJyZW50X3BhcmFtKTsKICAgICAgICAgICAgYWRhcHRlZCA9IG1pY3JvcHJvdG9jb2xzX2FkYXB0KGN1cnJlbnRfcGFyYW0sIChQeU9iamVjdCopJnB5c3FsaXRlX1ByZXBhcmVQcm90b2NvbFR5cGUsIE5VTEwpOwogICAgICAgICAgICBpZiAoYWRhcHRlZCkgewogICAgICAgICAgICAgICAgUHlfREVDUkVGKGN1cnJlbnRfcGFyYW0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKICAgICAgICAgICAgICAgIGFkYXB0ZWQgPSBjdXJyZW50X3BhcmFtOwogICAgICAgICAgICB9CgogICAgICAgICAgICByYyA9IHB5c3FsaXRlX3N0YXRlbWVudF9iaW5kX3BhcmFtZXRlcihzZWxmLCBpLCBhZGFwdGVkKTsKICAgICAgICAgICAgUHlfREVDUkVGKGFkYXB0ZWQpOwoKICAgICAgICAgICAgaWYgKHJjICE9IFNRTElURV9PSykgewogICAgICAgICAgICAgICAgUHlFcnJfRm9ybWF0KHB5c3FsaXRlX0ludGVyZmFjZUVycm9yLCAiRXJyb3IgYmluZGluZyBwYXJhbWV0ZXIgOiVzIC0gcHJvYmFibHkgdW5zdXBwb3J0ZWQgdHlwZS4iLCBiaW5kaW5nX25hbWUpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qIHBhcmFtZXRlcnMgcGFzc2VkIGFzIHNlcXVlbmNlICovCiAgICAgICAgbnVtX3BhcmFtcyA9IFB5U2VxdWVuY2VfTGVuZ3RoKHBhcmFtZXRlcnMpOwogICAgICAgIGlmIChudW1fcGFyYW1zICE9IG51bV9wYXJhbXNfbmVlZGVkKSB7CiAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChweXNxbGl0ZV9Qcm9ncmFtbWluZ0Vycm9yLCAiSW5jb3JyZWN0IG51bWJlciBvZiBiaW5kaW5ncyBzdXBwbGllZC4gVGhlIGN1cnJlbnQgc3RhdGVtZW50IHVzZXMgJWQsIGFuZCB0aGVyZSBhcmUgJWQgc3VwcGxpZWQuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIG51bV9wYXJhbXNfbmVlZGVkLCBudW1fcGFyYW1zKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbnVtX3BhcmFtczsgaSsrKSB7CiAgICAgICAgICAgIGN1cnJlbnRfcGFyYW0gPSBQeVNlcXVlbmNlX0dldEl0ZW0ocGFyYW1ldGVycywgaSk7CiAgICAgICAgICAgIGlmICghY3VycmVudF9wYXJhbSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGFkYXB0ZWQgPSBtaWNyb3Byb3RvY29sc19hZGFwdChjdXJyZW50X3BhcmFtLCAoUHlPYmplY3QqKSZweXNxbGl0ZV9QcmVwYXJlUHJvdG9jb2xUeXBlLCBOVUxMKTsKCiAgICAgICAgICAgIGlmIChhZGFwdGVkKSB7CiAgICAgICAgICAgICAgICBQeV9ERUNSRUYoY3VycmVudF9wYXJhbSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBQeUVycl9DbGVhcigpOwogICAgICAgICAgICAgICAgYWRhcHRlZCA9IGN1cnJlbnRfcGFyYW07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJjID0gcHlzcWxpdGVfc3RhdGVtZW50X2JpbmRfcGFyYW1ldGVyKHNlbGYsIGkgKyAxLCBhZGFwdGVkKTsKICAgICAgICAgICAgUHlfREVDUkVGKGFkYXB0ZWQpOwoKICAgICAgICAgICAgaWYgKHJjICE9IFNRTElURV9PSykgewogICAgICAgICAgICAgICAgUHlFcnJfRm9ybWF0KHB5c3FsaXRlX0ludGVyZmFjZUVycm9yLCAiRXJyb3IgYmluZGluZyBwYXJhbWV0ZXIgJWQgLSBwcm9iYWJseSB1bnN1cHBvcnRlZCB0eXBlLiIsIGkpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgppbnQgcHlzcWxpdGVfc3RhdGVtZW50X3JlY29tcGlsZShweXNxbGl0ZV9TdGF0ZW1lbnQqIHNlbGYsIFB5T2JqZWN0KiBwYXJhbXMpCnsKICAgIGNvbnN0IGNoYXIqIHRhaWw7CiAgICBpbnQgcmM7CiAgICBjb25zdCBjaGFyKiBzcWxfY3N0cjsKICAgIFB5X3NzaXplX3Qgc3FsX2xlbjsKICAgIHNxbGl0ZTNfc3RtdCogbmV3X3N0OwoKICAgIHNxbF9jc3RyID0gUHlVbmljb2RlX0FzU3RyaW5nQW5kU2l6ZShzZWxmLT5zcWwsICZzcWxfbGVuKTsKICAgIGlmIChzcWxfY3N0ciA9PSBOVUxMKSB7CiAgICAgICAgcmMgPSBQWVNRTElURV9TUUxfV1JPTkdfVFlQRTsKICAgICAgICByZXR1cm4gcmM7CiAgICB9CgogICAgcmMgPSBzcWxpdGUzX3ByZXBhcmUoc2VsZi0+ZGIsCiAgICAgICAgICAgICAgICAgICAgICAgICBzcWxfY3N0ciwKICAgICAgICAgICAgICAgICAgICAgICAgIC0xLAogICAgICAgICAgICAgICAgICAgICAgICAgJm5ld19zdCwKICAgICAgICAgICAgICAgICAgICAgICAgICZ0YWlsKTsKCiAgICBpZiAocmMgPT0gU1FMSVRFX09LKSB7CiAgICAgICAgLyogVGhlIGVmZmljaWVudCBzcWxpdGUzX3RyYW5zZmVyX2JpbmRpbmdzIGlzIG9ubHkgYXZhaWxhYmxlIGluIFNRTGl0ZQogICAgICAgICAqIHZlcnNpb24gMy4yLjIgb3IgbGF0ZXIuIEZvciBvbGRlciBTUUxpdGUgcmVsZWFzZXMsIHRoYXQgbWlnaHQgbm90CiAgICAgICAgICogZXZlbiBkZWZpbmUgU1FMSVRFX1ZFUlNJT05fTlVNQkVSLCB3ZSBkbyBpdCB0aGUgbWFudWFsIHdheS4KICAgICAgICAgKi8KICAgICAgICAjaWZkZWYgU1FMSVRFX1ZFUlNJT05fTlVNQkVSCiAgICAgICAgI2lmIFNRTElURV9WRVJTSU9OX05VTUJFUiA+PSAzMDAyMDAyCiAgICAgICAgLyogVGhlIGNoZWNrIGZvciB0aGUgbnVtYmVyIG9mIHBhcmFtZXRlcnMgaXMgbmVjZXNzYXJ5IHRvIG5vdCB0cmlnZ2VyIGEKICAgICAgICAgKiBidWcgaW4gY2VydGFpbiBTUUxpdGUgdmVyc2lvbnMgKGV4cGVyaWVuY2VkIGluIDMuMi44IGFuZCAzLjMuNCkuICovCiAgICAgICAgaWYgKHNxbGl0ZTNfYmluZF9wYXJhbWV0ZXJfY291bnQoc2VsZi0+c3QpID4gMCkgewogICAgICAgICAgICAodm9pZClzcWxpdGUzX3RyYW5zZmVyX2JpbmRpbmdzKHNlbGYtPnN0LCBuZXdfc3QpOwogICAgICAgIH0KICAgICAgICAjZW5kaWYKICAgICAgICAjZWxzZQogICAgICAgIHN0YXRlbWVudF9iaW5kX3BhcmFtZXRlcnMoc2VsZiwgcGFyYW1zKTsKICAgICAgICAjZW5kaWYKCiAgICAgICAgKHZvaWQpc3FsaXRlM19maW5hbGl6ZShzZWxmLT5zdCk7CiAgICAgICAgc2VsZi0+c3QgPSBuZXdfc3Q7CiAgICB9CgogICAgcmV0dXJuIHJjOwp9CgppbnQgcHlzcWxpdGVfc3RhdGVtZW50X2ZpbmFsaXplKHB5c3FsaXRlX1N0YXRlbWVudCogc2VsZikKewogICAgaW50IHJjOwoKICAgIHJjID0gU1FMSVRFX09LOwogICAgaWYgKHNlbGYtPnN0KSB7CiAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgICAgIHJjID0gc3FsaXRlM19maW5hbGl6ZShzZWxmLT5zdCk7CiAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKICAgICAgICBzZWxmLT5zdCA9IE5VTEw7CiAgICB9CgogICAgc2VsZi0+aW5fdXNlID0gMDsKCiAgICByZXR1cm4gcmM7Cn0KCmludCBweXNxbGl0ZV9zdGF0ZW1lbnRfcmVzZXQocHlzcWxpdGVfU3RhdGVtZW50KiBzZWxmKQp7CiAgICBpbnQgcmM7CgogICAgcmMgPSBTUUxJVEVfT0s7CgogICAgaWYgKHNlbGYtPmluX3VzZSAmJiBzZWxmLT5zdCkgewogICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgICAgICByYyA9IHNxbGl0ZTNfcmVzZXQoc2VsZi0+c3QpOwogICAgICAgIFB5X0VORF9BTExPV19USFJFQURTCgogICAgICAgIGlmIChyYyA9PSBTUUxJVEVfT0spIHsKICAgICAgICAgICAgc2VsZi0+aW5fdXNlID0gMDsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJjOwp9Cgp2b2lkIHB5c3FsaXRlX3N0YXRlbWVudF9tYXJrX2RpcnR5KHB5c3FsaXRlX1N0YXRlbWVudCogc2VsZikKewogICAgc2VsZi0+aW5fdXNlID0gMTsKfQoKdm9pZCBweXNxbGl0ZV9zdGF0ZW1lbnRfZGVhbGxvYyhweXNxbGl0ZV9TdGF0ZW1lbnQqIHNlbGYpCnsKICAgIGludCByYzsKCiAgICBpZiAoc2VsZi0+c3QpIHsKICAgICAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCiAgICAgICAgcmMgPSBzcWxpdGUzX2ZpbmFsaXplKHNlbGYtPnN0KTsKICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwogICAgfQoKICAgIHNlbGYtPnN0ID0gTlVMTDsKCiAgICBQeV9YREVDUkVGKHNlbGYtPnNxbCk7CgogICAgaWYgKHNlbGYtPmluX3dlYWtyZWZsaXN0ICE9IE5VTEwpIHsKICAgICAgICBQeU9iamVjdF9DbGVhcldlYWtSZWZzKChQeU9iamVjdCopc2VsZik7CiAgICB9CgogICAgUHlfVFlQRShzZWxmKS0+dHBfZnJlZSgoUHlPYmplY3QqKXNlbGYpOwp9CgovKgogKiBDaGVja3MgaWYgdGhlcmUgaXMgYW55dGhpbmcgbGVmdCBpbiBhbiBTUUwgc3RyaW5nIGFmdGVyIFNRTGl0ZSBjb21waWxlZCBpdC4KICogVGhpcyBpcyB1c2VkIHRvIGNoZWNrIGlmIHNvbWVib2R5IHRyaWVkIHRvIGV4ZWN1dGUgbW9yZSB0aGFuIG9uZSBTUUwgY29tbWFuZAogKiB3aXRoIG9uZSBleGVjdXRlKCkvZXhlY3V0ZW1hbnkoKSBjb21tYW5kLCB3aGljaCB0aGUgREItQVBJIGFuZCB3ZSBkb24ndAogKiBhbGxvdy4KICoKICogUmV0dXJucyAxIGlmIHRoZXJlIGlzIG1vcmUgbGVmdCB0aGFuIHNob3VsZCBiZS4gMCBpZiBvay4KICovCnN0YXRpYyBpbnQgcHlzcWxpdGVfY2hlY2tfcmVtYWluaW5nX3NxbChjb25zdCBjaGFyKiB0YWlsKQp7CiAgICBjb25zdCBjaGFyKiBwb3MgPSB0YWlsOwoKICAgIHBhcnNlX3JlbWFpbmluZ19zcWxfc3RhdGUgc3RhdGUgPSBOT1JNQUw7CgogICAgZm9yICg7OykgewogICAgICAgIHN3aXRjaCAoKnBvcykgewogICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgY2FzZSAnLSc6CiAgICAgICAgICAgICAgICBpZiAoc3RhdGUgPT0gTk9STUFMKSB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGUgID0gTElORUNPTU1FTlRfMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT0gTElORUNPTU1FTlRfMSkgewogICAgICAgICAgICAgICAgICAgIHN0YXRlID0gSU5fTElORUNPTU1FTlQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnICc6CiAgICAgICAgICAgIGNhc2UgJ1x0JzoKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdcbic6CiAgICAgICAgICAgIGNhc2UgMTM6CiAgICAgICAgICAgICAgICBpZiAoc3RhdGUgPT0gSU5fTElORUNPTU1FTlQpIHsKICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IE5PUk1BTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICcvJzoKICAgICAgICAgICAgICAgIGlmIChzdGF0ZSA9PSBOT1JNQUwpIHsKICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IENPTU1FTlRTVEFSVF8xOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PSBDT01NRU5URU5EXzEpIHsKICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IE5PUk1BTDsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT0gQ09NTUVOVFNUQVJUXzEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICcqJzoKICAgICAgICAgICAgICAgIGlmIChzdGF0ZSA9PSBOT1JNQUwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT0gTElORUNPTU1FTlRfMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PSBDT01NRU5UU1RBUlRfMSkgewogICAgICAgICAgICAgICAgICAgIHN0YXRlID0gSU5fQ09NTUVOVDsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT0gSU5fQ09NTUVOVCkgewogICAgICAgICAgICAgICAgICAgIHN0YXRlID0gQ09NTUVOVEVORF8xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBpZiAoc3RhdGUgPT0gQ09NTUVOVEVORF8xKSB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSBJTl9DT01NRU5UOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PSBJTl9MSU5FQ09NTUVOVCkgewogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PSBJTl9DT01NRU5UKSB7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcG9zKys7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KClB5VHlwZU9iamVjdCBweXNxbGl0ZV9TdGF0ZW1lbnRUeXBlID0gewogICAgICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVChOVUxMLCAwKQogICAgICAgIE1PRFVMRV9OQU1FICIuU3RhdGVtZW50IiwgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25hbWUgKi8KICAgICAgICBzaXplb2YocHlzcWxpdGVfU3RhdGVtZW50KSwgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVtc2l6ZSAqLwogICAgICAgIChkZXN0cnVjdG9yKXB5c3FsaXRlX3N0YXRlbWVudF9kZWFsbG9jLCAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KICAgICAgICBQeV9UUEZMQUdTX0RFRkFVTFQsCQkJCS8qIHRwX2ZsYWdzICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCiAgICAgICAgb2Zmc2V0b2YocHlzcWxpdGVfU3RhdGVtZW50LCBpbl93ZWFrcmVmbGlzdCksICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3JfZ2V0ICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdG9mZnNldCAqLwogICAgICAgIChpbml0cHJvYykwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2luaXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25ldyAqLwogICAgICAgIDAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2ZyZWUgKi8KfTsKCmV4dGVybiBpbnQgcHlzcWxpdGVfc3RhdGVtZW50X3NldHVwX3R5cGVzKHZvaWQpCnsKICAgIHB5c3FsaXRlX1N0YXRlbWVudFR5cGUudHBfbmV3ID0gUHlUeXBlX0dlbmVyaWNOZXc7CiAgICByZXR1cm4gUHlUeXBlX1JlYWR5KCZweXNxbGl0ZV9TdGF0ZW1lbnRUeXBlKTsKfQo=