LyogSGFuZGxlIHR5cGVzIGZvciB0aGUgR05VIGNvbXBpbGVyIGZvciB0aGUgSmF2YShUTSkgbGFuZ3VhZ2UuCiAgIENvcHlyaWdodCAoQykgMTk5NiwgMTk5NywgMTk5OCwgMTk5OSwgMjAwMCwgMjAwMSwgMjAwMywgMjAwNCwgMjAwNQogICBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4KClRoaXMgZmlsZSBpcyBwYXJ0IG9mIEdDQy4KCkdDQyBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5Cml0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CnRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIsIG9yIChhdCB5b3VyIG9wdGlvbikKYW55IGxhdGVyIHZlcnNpb24uCgpHQ0MgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQpHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgoKWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKYWxvbmcgd2l0aCBHQ0M7IHNlZSB0aGUgZmlsZSBDT1BZSU5HLiAgSWYgbm90LCB3cml0ZSB0bwp0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLApCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQS4gIAoKSmF2YSBhbmQgYWxsIEphdmEtYmFzZWQgbWFya3MgYXJlIHRyYWRlbWFya3Mgb3IgcmVnaXN0ZXJlZCB0cmFkZW1hcmtzCm9mIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gaW4gdGhlIFVuaXRlZCBTdGF0ZXMgYW5kIG90aGVyIGNvdW50cmllcy4KVGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiBpcyBpbmRlcGVuZGVudCBvZiBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuICAqLwoKLyogV3JpdHRlbiBieSBQZXIgQm90aG5lciA8Ym90aG5lckBjeWdudXMuY29tPiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAic3lzdGVtLmgiCiNpbmNsdWRlICJjb3JldHlwZXMuaCIKI2luY2x1ZGUgInRtLmgiCiNpbmNsdWRlICJ0cmVlLmgiCiNpbmNsdWRlICJyZWFsLmgiCiNpbmNsdWRlICJvYnN0YWNrLmgiCiNpbmNsdWRlICJmbGFncy5oIgojaW5jbHVkZSAiamF2YS10cmVlLmgiCiNpbmNsdWRlICJqY2YuaCIKI2luY2x1ZGUgImNvbnZlcnQuaCIKI2luY2x1ZGUgInRvcGxldi5oIgojaW5jbHVkZSAiZ2djLmgiCgpzdGF0aWMgdHJlZSBjb252ZXJ0X2llZWVfcmVhbF90b19pbnRlZ2VyICh0cmVlLCB0cmVlKTsKc3RhdGljIHRyZWUgcGFyc2Vfc2lnbmF0dXJlX3R5cGUgKGNvbnN0IHVuc2lnbmVkIGNoYXIgKiosCgkJCQkgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKik7CnN0YXRpYyB0cmVlIGxvb2t1cF9kbyAodHJlZSwgaW50LCB0cmVlLCB0cmVlLCB0cmVlICgqKSh0cmVlKSk7CnN0YXRpYyB0cmVlIGJ1aWxkX251bGxfc2lnbmF0dXJlICh0cmVlKTsKCnRyZWUgKiB0eXBlX21hcDsKCi8qIFNldCB0aGUgdHlwZSBvZiB0aGUgbG9jYWwgdmFyaWFibGUgd2l0aCBpbmRleCBTTE9UIHRvIFRZUEUuICovCgp2b2lkCnNldF9sb2NhbF90eXBlIChpbnQgc2xvdCwgdHJlZSB0eXBlKQp7CiAgaW50IG1heF9sb2NhbHMgPSBERUNMX01BWF9MT0NBTFMoY3VycmVudF9mdW5jdGlvbl9kZWNsKTsKICBpbnQgbnNsb3RzID0gVFlQRV9JU19XSURFICh0eXBlKSA/IDIgOiAxOwoKICBnY2NfYXNzZXJ0IChzbG90ID49IDAgJiYgKHNsb3QgKyBuc2xvdHMgLSAxIDwgbWF4X2xvY2FscykpOwoKICB0eXBlX21hcFtzbG90XSA9IHR5cGU7CiAgd2hpbGUgKC0tbnNsb3RzID4gMCkKICAgIHR5cGVfbWFwWysrc2xvdF0gPSB2b2lkX3R5cGVfbm9kZTsKfQoKLyogQ29udmVydCBhbiBJRUVFIHJlYWwgdG8gYW4gaW50ZWdlciB0eXBlLiAgVGhlIHJlc3VsdCBvZiBzdWNoIGEKICAgY29udmVyc2lvbiB3aGVuIHRoZSBzb3VyY2Ugb3BlcmFuZCBpcyBhIE5hTiBpc24ndCBkZWZpbmVkIGJ5CiAgIElFRUU3NTQsIGJ1dCBieSB0aGUgSmF2YSBsYW5ndWFnZSBzdGFuZGFyZDogaXQgbXVzdCBiZSB6ZXJvLiAgQWxzbywKICAgb3ZlcmZsb3dzIG11c3QgYmUgY2xpcHBlZCB0byB3aXRoaW4gcmFuZ2UuICBUaGlzIGNvbnZlcnNpb24KICAgcHJvZHVjZXMgc29tZXRoaW5nIGxpa2U6CgogICAgICAoKGV4cHIgPj0gKGZsb2F0KU1BWF9JTlQpCiAgICAgICA/IE1BWF9JTlQgCiAgICAgICA6ICgoZXhwciA8PSAoZmxvYXQpTUlOX0lOVCkKCSAgPyBNSU5fSU5UCgkgIDogKChleHByICE9IGV4cHIpCgkgICAgID8gMCAKCSAgICAgOiAoaW50KWV4cHIpKSkgKi8KCnN0YXRpYyB0cmVlCmNvbnZlcnRfaWVlZV9yZWFsX3RvX2ludGVnZXIgKHRyZWUgdHlwZSwgdHJlZSBleHByKQp7CiAgdHJlZSByZXN1bHQ7CiAgZXhwciA9IHNhdmVfZXhwciAoZXhwcik7CgogIHJlc3VsdCA9IGZvbGRfYnVpbGQzIChDT05EX0VYUFIsIHR5cGUsCgkJCWZvbGRfYnVpbGQyIChORV9FWFBSLCBib29sZWFuX3R5cGVfbm9kZSwgZXhwciwgZXhwciksCgkJCSBjb252ZXJ0ICh0eXBlLCBpbnRlZ2VyX3plcm9fbm9kZSksCgkJCSBjb252ZXJ0X3RvX2ludGVnZXIgKHR5cGUsIGV4cHIpKTsKICAKICByZXN1bHQgPSBmb2xkX2J1aWxkMyAoQ09ORF9FWFBSLCB0eXBlLCAKCQkJZm9sZF9idWlsZDIgKExFX0VYUFIsIGJvb2xlYW5fdHlwZV9ub2RlLCBleHByLCAKCQkJCSAgICAgY29udmVydCAoVFJFRV9UWVBFIChleHByKSwgCgkJCQkJICAgICAgVFlQRV9NSU5fVkFMVUUgKHR5cGUpKSksCgkJCVRZUEVfTUlOX1ZBTFVFICh0eXBlKSwKCQkJcmVzdWx0KTsKICAKICByZXN1bHQgPSBmb2xkX2J1aWxkMyAoQ09ORF9FWFBSLCB0eXBlLAoJCQlmb2xkX2J1aWxkMiAoR0VfRVhQUiwgYm9vbGVhbl90eXBlX25vZGUsIGV4cHIsIAoJCQkJICAgICBjb252ZXJ0IChUUkVFX1RZUEUgKGV4cHIpLCAKCQkJCQkgICAgICBUWVBFX01BWF9WQUxVRSAodHlwZSkpKSwKCQkJVFlQRV9NQVhfVkFMVUUgKHR5cGUpLAoJCQlyZXN1bHQpOwoKICByZXR1cm4gcmVzdWx0Owp9ICAKCi8qIENyZWF0ZSBhbiBleHByZXNzaW9uIHdob3NlIHZhbHVlIGlzIHRoYXQgb2YgRVhQUiwKICAgY29udmVydGVkIHRvIHR5cGUgVFlQRS4gIFRoZSBUUkVFX1RZUEUgb2YgdGhlIHZhbHVlCiAgIGlzIGFsd2F5cyBUWVBFLiAgVGhpcyBmdW5jdGlvbiBpbXBsZW1lbnRzIGFsbCByZWFzb25hYmxlCiAgIGNvbnZlcnNpb25zOyBjYWxsZXJzIHNob3VsZCBmaWx0ZXIgb3V0IHRob3NlIHRoYXQgYXJlCiAgIG5vdCBwZXJtaXR0ZWQgYnkgdGhlIGxhbmd1YWdlIGJlaW5nIGNvbXBpbGVkLiAgKi8KCnRyZWUKY29udmVydCAodHJlZSB0eXBlLCB0cmVlIGV4cHIpCnsKICBlbnVtIHRyZWVfY29kZSBjb2RlID0gVFJFRV9DT0RFICh0eXBlKTsKCiAgaWYgKCFleHByKQogICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoKICBpZiAodHlwZSA9PSBUUkVFX1RZUEUgKGV4cHIpCiAgICAgIHx8IFRSRUVfQ09ERSAoZXhwcikgPT0gRVJST1JfTUFSSykKICAgIHJldHVybiBleHByOwogIGlmIChUUkVFX0NPREUgKFRSRUVfVFlQRSAoZXhwcikpID09IEVSUk9SX01BUkspCiAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwogIGlmIChjb2RlID09IFZPSURfVFlQRSkKICAgIHJldHVybiBidWlsZDEgKENPTlZFUlRfRVhQUiwgdHlwZSwgZXhwcik7CiAgaWYgKGNvZGUgPT0gQk9PTEVBTl9UWVBFKQogICAgcmV0dXJuIGZvbGRfY29udmVydCAodHlwZSwgZXhwcik7CiAgaWYgKGNvZGUgPT0gSU5URUdFUl9UWVBFKQogICAgewogICAgICBpZiAodHlwZSA9PSBjaGFyX3R5cGVfbm9kZSB8fCB0eXBlID09IHByb21vdGVkX2NoYXJfdHlwZV9ub2RlKQoJcmV0dXJuIGZvbGRfY29udmVydCAodHlwZSwgZXhwcik7CiAgICAgIGlmICgocmVhbGx5X2NvbnN0YW50X3AgKGV4cHIpCgkgICB8fCAoISBmbGFnX3Vuc2FmZV9tYXRoX29wdGltaXphdGlvbnMKCSAgICAgICAmJiAhIGZsYWdfZW1pdF9jbGFzc19maWxlcykpCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9UWVBFIChleHByKSkgPT0gUkVBTF9UWVBFCgkgICYmIFRBUkdFVF9GTE9BVF9GT1JNQVQgPT0gSUVFRV9GTE9BVF9GT1JNQVQpCglyZXR1cm4gY29udmVydF9pZWVlX3JlYWxfdG9faW50ZWdlciAodHlwZSwgZXhwcik7CiAgICAgIGVsc2UKCXsKCSAgLyogZm9sZCB2ZXJ5IGhlbHBmdWxseSBzZXRzIHRoZSBvdmVyZmxvdyBzdGF0dXMgaWYgYSB0eXBlCgkgICAgIG92ZXJmbG93cyBpbiBhIG5hcnJvd2luZyBpbnRlZ2VyIGNvbnZlcnNpb24sIGJ1dCBKYXZhCgkgICAgIGRvZXNuJ3QgY2FyZS4gICovCgkgIHRyZWUgdG1wID0gZm9sZCAoY29udmVydF90b19pbnRlZ2VyICh0eXBlLCBleHByKSk7CgkgIGlmIChUUkVFX0NPREUgKHRtcCkgPT0gSU5URUdFUl9DU1QpCgkgICAgVFJFRV9PVkVSRkxPVyAodG1wKSA9IDA7CgkgIHJldHVybiB0bXA7Cgl9CiAgICB9CSAgCiAgaWYgKGNvZGUgPT0gUkVBTF9UWVBFKQogICAgcmV0dXJuIGZvbGQgKGNvbnZlcnRfdG9fcmVhbCAodHlwZSwgZXhwcikpOwogIGlmIChjb2RlID09IFBPSU5URVJfVFlQRSkKICAgIHJldHVybiBmb2xkIChjb252ZXJ0X3RvX3BvaW50ZXIgKHR5cGUsIGV4cHIpKTsKICBlcnJvciAoImNvbnZlcnNpb24gdG8gbm9uLXNjYWxhciB0eXBlIHJlcXVlc3RlZCIpOwogIHJldHVybiBlcnJvcl9tYXJrX25vZGU7Cn0KCgovKiBSZXR1cm4gYSBkYXRhIHR5cGUgdGhhdCBoYXMgbWFjaGluZSBtb2RlIE1PREUuCiAgIElmIHRoZSBtb2RlIGlzIGFuIGludGVnZXIsCiAgIHRoZW4gVU5TSUdORURQIHNlbGVjdHMgYmV0d2VlbiBzaWduZWQgYW5kIHVuc2lnbmVkIHR5cGVzLiAgKi8KCnRyZWUKamF2YV90eXBlX2Zvcl9tb2RlIChlbnVtIG1hY2hpbmVfbW9kZSBtb2RlLCBpbnQgdW5zaWduZWRwKQp7CiAgaWYgKG1vZGUgPT0gVFlQRV9NT0RFIChpbnRfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9pbnRfdHlwZV9ub2RlIDogaW50X3R5cGVfbm9kZTsKICBpZiAobW9kZSA9PSBUWVBFX01PREUgKGxvbmdfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9sb25nX3R5cGVfbm9kZSA6IGxvbmdfdHlwZV9ub2RlOwogIGlmIChtb2RlID09IFRZUEVfTU9ERSAoc2hvcnRfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9zaG9ydF90eXBlX25vZGUgOiBzaG9ydF90eXBlX25vZGU7CiAgaWYgKG1vZGUgPT0gVFlQRV9NT0RFIChieXRlX3R5cGVfbm9kZSkpCiAgICByZXR1cm4gdW5zaWduZWRwID8gdW5zaWduZWRfYnl0ZV90eXBlX25vZGUgOiBieXRlX3R5cGVfbm9kZTsKICBpZiAobW9kZSA9PSBUWVBFX01PREUgKGZsb2F0X3R5cGVfbm9kZSkpCiAgICByZXR1cm4gZmxvYXRfdHlwZV9ub2RlOwogIGlmIChtb2RlID09IFRZUEVfTU9ERSAoZG91YmxlX3R5cGVfbm9kZSkpCiAgICByZXR1cm4gZG91YmxlX3R5cGVfbm9kZTsKCiAgcmV0dXJuIDA7Cn0KCi8qIFJldHVybiBhbiBpbnRlZ2VyIHR5cGUgd2l0aCBCSVRTIGJpdHMgb2YgcHJlY2lzaW9uLAogICB0aGF0IGlzIHVuc2lnbmVkIGlmIFVOU0lHTkVEUCBpcyBub256ZXJvLCBvdGhlcndpc2Ugc2lnbmVkLiAgKi8KCnRyZWUKamF2YV90eXBlX2Zvcl9zaXplICh1bnNpZ25lZCBiaXRzLCBpbnQgdW5zaWduZWRwKQp7CiAgaWYgKGJpdHMgPD0gVFlQRV9QUkVDSVNJT04gKGJ5dGVfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9ieXRlX3R5cGVfbm9kZSA6IGJ5dGVfdHlwZV9ub2RlOwogIGlmIChiaXRzIDw9IFRZUEVfUFJFQ0lTSU9OIChzaG9ydF90eXBlX25vZGUpKQogICAgcmV0dXJuIHVuc2lnbmVkcCA/IHVuc2lnbmVkX3Nob3J0X3R5cGVfbm9kZSA6IHNob3J0X3R5cGVfbm9kZTsKICBpZiAoYml0cyA8PSBUWVBFX1BSRUNJU0lPTiAoaW50X3R5cGVfbm9kZSkpCiAgICByZXR1cm4gdW5zaWduZWRwID8gdW5zaWduZWRfaW50X3R5cGVfbm9kZSA6IGludF90eXBlX25vZGU7CiAgaWYgKGJpdHMgPD0gVFlQRV9QUkVDSVNJT04gKGxvbmdfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9sb25nX3R5cGVfbm9kZSA6IGxvbmdfdHlwZV9ub2RlOwogIHJldHVybiAwOwp9CgovKiBSZXR1cm4gYSB0eXBlIHRoZSBzYW1lIGFzIFRZUEUgZXhjZXB0IHVuc2lnbmVkIG9yCiAgIHNpZ25lZCBhY2NvcmRpbmcgdG8gVU5TSUdORURQLiAgKi8KCnRyZWUKamF2YV9zaWduZWRfb3JfdW5zaWduZWRfdHlwZSAoaW50IHVuc2lnbmVkcCwgdHJlZSB0eXBlKQp7CiAgaWYgKCEgSU5URUdSQUxfVFlQRV9QICh0eXBlKSkKICAgIHJldHVybiB0eXBlOwogIGlmIChUWVBFX1BSRUNJU0lPTiAodHlwZSkgPT0gVFlQRV9QUkVDSVNJT04gKGludF90eXBlX25vZGUpKQogICAgcmV0dXJuIHVuc2lnbmVkcCA/IHVuc2lnbmVkX2ludF90eXBlX25vZGUgOiBpbnRfdHlwZV9ub2RlOwogIGlmIChUWVBFX1BSRUNJU0lPTiAodHlwZSkgPT0gVFlQRV9QUkVDSVNJT04gKGJ5dGVfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9ieXRlX3R5cGVfbm9kZSA6IGJ5dGVfdHlwZV9ub2RlOwogIGlmIChUWVBFX1BSRUNJU0lPTiAodHlwZSkgPT0gVFlQRV9QUkVDSVNJT04gKHNob3J0X3R5cGVfbm9kZSkpCiAgICByZXR1cm4gdW5zaWduZWRwID8gdW5zaWduZWRfc2hvcnRfdHlwZV9ub2RlIDogc2hvcnRfdHlwZV9ub2RlOwogIGlmIChUWVBFX1BSRUNJU0lPTiAodHlwZSkgPT0gVFlQRV9QUkVDSVNJT04gKGxvbmdfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9sb25nX3R5cGVfbm9kZSA6IGxvbmdfdHlwZV9ub2RlOwogIHJldHVybiB0eXBlOwp9CgovKiBSZXR1cm4gYSBzaWduZWQgdHlwZSB0aGUgc2FtZSBhcyBUWVBFIGluIG90aGVyIHJlc3BlY3RzLiAgKi8KCnRyZWUKamF2YV9zaWduZWRfdHlwZSAodHJlZSB0eXBlKQp7CiAgcmV0dXJuIGphdmFfc2lnbmVkX29yX3Vuc2lnbmVkX3R5cGUgKDAsIHR5cGUpOwp9CgovKiBSZXR1cm4gYW4gdW5zaWduZWQgdHlwZSB0aGUgc2FtZSBhcyBUWVBFIGluIG90aGVyIHJlc3BlY3RzLiAgKi8KCnRyZWUKamF2YV91bnNpZ25lZF90eXBlICh0cmVlIHR5cGUpCnsKICByZXR1cm4gamF2YV9zaWduZWRfb3JfdW5zaWduZWRfdHlwZSAoMSwgdHlwZSk7Cn0KCi8qIE1hcmsgRVhQIHNheWluZyB0aGF0IHdlIG5lZWQgdG8gYmUgYWJsZSB0byB0YWtlIHRoZQogICBhZGRyZXNzIG9mIGl0OyBpdCBzaG91bGQgbm90IGJlIGFsbG9jYXRlZCBpbiBhIHJlZ2lzdGVyLgogICBWYWx1ZSBpcyB0cnVlIGlmIHN1Y2Nlc3NmdWwuICAqLwoKYm9vbApqYXZhX21hcmtfYWRkcmVzc2FibGUgKHRyZWUgZXhwKQp7CiAgdHJlZSB4ID0gZXhwOwogIHdoaWxlICgxKQogICAgc3dpdGNoIChUUkVFX0NPREUgKHgpKQogICAgICB7CiAgICAgIGNhc2UgQUREUl9FWFBSOgogICAgICBjYXNlIENPTVBPTkVOVF9SRUY6CiAgICAgIGNhc2UgQVJSQVlfUkVGOgogICAgICBjYXNlIFJFQUxQQVJUX0VYUFI6CiAgICAgIGNhc2UgSU1BR1BBUlRfRVhQUjoKCXggPSBUUkVFX09QRVJBTkQgKHgsIDApOwoJYnJlYWs7CgogICAgICBjYXNlIFRSVVRIX0FORElGX0VYUFI6CiAgICAgIGNhc2UgVFJVVEhfT1JJRl9FWFBSOgogICAgICBjYXNlIENPTVBPVU5EX0VYUFI6Cgl4ID0gVFJFRV9PUEVSQU5EICh4LCAxKTsKCWJyZWFrOwoKICAgICAgY2FzZSBDT05EX0VYUFI6CglyZXR1cm4gamF2YV9tYXJrX2FkZHJlc3NhYmxlIChUUkVFX09QRVJBTkQgKHgsIDEpKQoJICAmJiBqYXZhX21hcmtfYWRkcmVzc2FibGUgKFRSRUVfT1BFUkFORCAoeCwgMikpOwoKICAgICAgY2FzZSBDT05TVFJVQ1RPUjoKCVRSRUVfQUREUkVTU0FCTEUgKHgpID0gMTsKCXJldHVybiB0cnVlOwoKICAgICAgY2FzZSBJTkRJUkVDVF9SRUY6CgkvKiBXZSBzb21ldGltZXMgYWRkIGEgY2FzdCAqKFRZUEUqKSZGT08gdG8gaGFuZGxlIHR5cGUgYW5kIG1vZGUKCSAgIGluY29tcGF0aWJpbGl0eSBwcm9ibGVtcy4gIEhhbmRsZSB0aGlzIGNhc2UgYnkgbWFya2luZyBGT08uICAqLwoJaWYgKFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EICh4LCAwKSkgPT0gTk9QX0VYUFIKCSAgICAmJiBUUkVFX0NPREUgKFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EICh4LCAwKSwgMCkpID09IEFERFJfRVhQUikKCSAgewoJICAgIHggPSBUUkVFX09QRVJBTkQgKFRSRUVfT1BFUkFORCAoeCwgMCksIDApOwoJICAgIGJyZWFrOwoJICB9CglpZiAoVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKHgsIDApKSA9PSBBRERSX0VYUFIpCgkgIHsKCSAgICB4ID0gVFJFRV9PUEVSQU5EICh4LCAwKTsKCSAgICBicmVhazsKCSAgfQoJcmV0dXJuIHRydWU7CgogICAgICBjYXNlIFZBUl9ERUNMOgogICAgICBjYXNlIENPTlNUX0RFQ0w6CiAgICAgIGNhc2UgUEFSTV9ERUNMOgogICAgICBjYXNlIFJFU1VMVF9ERUNMOgogICAgICBjYXNlIEZVTkNUSU9OX0RFQ0w6CglUUkVFX0FERFJFU1NBQkxFICh4KSA9IDE7CiNpZiAwICAvKiBwb3BsZXZlbCBkZWFscyB3aXRoIHRoaXMgbm93LiAgKi8KCWlmIChERUNMX0NPTlRFWFQgKHgpID09IDApCgkgIFRSRUVfQUREUkVTU0FCTEUgKERFQ0xfQVNTRU1CTEVSX05BTUUgKHgpKSA9IDE7CiNlbmRpZgoJLyogZHJvcHMgdGhyb3VnaCAqLwogICAgICBkZWZhdWx0OgoJcmV0dXJuIHRydWU7CiAgICB9Cn0KCi8qIFRob3JvdWdoIGNoZWNraW5nIG9mIHRoZSBhcnJheW5lc3Mgb2YgVFlQRS4gICovCgppbnQKaXNfYXJyYXlfdHlwZV9wICh0cmVlIHR5cGUpCnsKICByZXR1cm4gVFJFRV9DT0RFICh0eXBlKSA9PSBQT0lOVEVSX1RZUEUKICAgICYmIFRSRUVfQ09ERSAoVFJFRV9UWVBFICh0eXBlKSkgPT0gUkVDT1JEX1RZUEUKICAgICYmIFRZUEVfQVJSQVlfUCAoVFJFRV9UWVBFICh0eXBlKSk7Cn0KCi8qIFJldHVybiB0aGUgbGVuZ3RoIG9mIGEgSmF2YSBhcnJheSB0eXBlLgogICBSZXR1cm4gLTEgaWYgdGhlIGxlbmd0aCBpcyB1bmtub3duIG9yIG5vbi1jb25zdGFudC4gKi8KCkhPU1RfV0lERV9JTlQKamF2YV9hcnJheV90eXBlX2xlbmd0aCAodHJlZSBhcnJheV90eXBlKQp7CiAgdHJlZSBhcmZsZDsKICBpZiAoVFJFRV9DT0RFIChhcnJheV90eXBlKSA9PSBQT0lOVEVSX1RZUEUpCiAgICBhcnJheV90eXBlID0gVFJFRV9UWVBFIChhcnJheV90eXBlKTsKICBhcmZsZCA9IFRSRUVfQ0hBSU4gKFRSRUVfQ0hBSU4gKFRZUEVfRklFTERTIChhcnJheV90eXBlKSkpOwogIGlmIChhcmZsZCAhPSBOVUxMX1RSRUUpCiAgICB7CiAgICAgIHRyZWUgaW5kZXhfdHlwZSA9IFRZUEVfRE9NQUlOIChUUkVFX1RZUEUgKGFyZmxkKSk7CiAgICAgIGlmIChpbmRleF90eXBlICE9IE5VTExfVFJFRSkKCXsKCSAgdHJlZSBoaWdoID0gVFlQRV9NQVhfVkFMVUUgKGluZGV4X3R5cGUpOwoJICBpZiAoVFJFRV9DT0RFIChoaWdoKSA9PSBJTlRFR0VSX0NTVCkKCSAgICByZXR1cm4gVFJFRV9JTlRfQ1NUX0xPVyAoaGlnaCkgKyAxOwoJfQogICAgfQogIHJldHVybiAtMTsKfQoKLyogQW4gYXJyYXkgb2YgdW5rbm93biBsZW5ndGggd2lsbCBiZSB1bHRpbWF0ZWx5IGdpdmVuIGEgbGVuZ3RoIG9mCiAgIC0yLCBzbyB0aGF0IHdlIGNhbiBzdGlsbCBoYXZlIGBsZW5ndGgnIHByb2R1Y2luZyBhIG5lZ2F0aXZlIHZhbHVlCiAgIGV2ZW4gaWYgZm91bmQuIFRoaXMgd2FzIHBhcnQgb2YgYW4gb3B0aW1pemF0aW9uIGFpbWluZyBhdCByZW1vdmluZwogICBgbGVuZ3RoJyBmcm9tIHN0YXRpYyBhcnJheXMuIFdlIGNvdWxkIHJlc3RvcmUgaXQsIEZJWE1FLiAgKi8KCnRyZWUKYnVpbGRfcHJpbV9hcnJheV90eXBlICh0cmVlIGVsZW1lbnRfdHlwZSwgSE9TVF9XSURFX0lOVCBsZW5ndGgpCnsKICB0cmVlIGluZGV4ID0gTlVMTDsKCiAgaWYgKGxlbmd0aCAhPSAtMSkKICAgIHsKICAgICAgdHJlZSBtYXhfaW5kZXggPSBidWlsZF9pbnRfY3N0IChzaXpldHlwZSwgbGVuZ3RoIC0gMSk7CiAgICAgIGluZGV4ID0gYnVpbGRfaW5kZXhfdHlwZSAobWF4X2luZGV4KTsKICAgIH0KICByZXR1cm4gYnVpbGRfYXJyYXlfdHlwZSAoZWxlbWVudF90eXBlLCBpbmRleCk7Cn0KCi8qIFJldHVybiBhIEphdmEgYXJyYXkgdHlwZSB3aXRoIGEgZ2l2ZW4gRUxFTUVOVF9UWVBFIGFuZCBMRU5HVEguCiAgIFRoZXNlIGFyZSBoYXNoZWQgKHNoYXJlZCkgdXNpbmcgSURFTlRJRklFUl9TSUdOQVRVUkVfVFlQRS4KICAgVGhlIExFTkdUSCBpcyAtMSBpZiB0aGUgbGVuZ3RoIGlzIHVua25vd24uICovCgp0cmVlCmJ1aWxkX2phdmFfYXJyYXlfdHlwZSAodHJlZSBlbGVtZW50X3R5cGUsIEhPU1RfV0lERV9JTlQgbGVuZ3RoKQp7CiAgdHJlZSBzaWcsIHQsIGZsZCwgYXR5cGUsIGFyZmxkOwogIGNoYXIgYnVmWzIzXTsgLyogMjAgZm9yIHRoZSBkaWdpdHMgb2YgYSA2NCBiaXQgbnVtYmVyICsgIltdIiArIFwwICovCiAgdHJlZSBlbHNpZyA9IGJ1aWxkX2phdmFfc2lnbmF0dXJlIChlbGVtZW50X3R5cGUpOwogIHRyZWUgZWxfbmFtZSA9IGVsZW1lbnRfdHlwZTsKICBidWZbMF0gPSAnWyc7CiAgaWYgKGxlbmd0aCA+PSAwKQogICAgc3ByaW50ZiAoYnVmKzEsIEhPU1RfV0lERV9JTlRfUFJJTlRfREVDLCBsZW5ndGgpOwogIGVsc2UKICAgIGJ1ZlsxXSA9ICdcMCc7CiAgc2lnID0gaWRlbnRfc3Vic3QgKElERU5USUZJRVJfUE9JTlRFUiAoZWxzaWcpLCBJREVOVElGSUVSX0xFTkdUSCAoZWxzaWcpLAoJCSAgICAgYnVmLCAwLCAwLCAiIik7CiAgdCA9IElERU5USUZJRVJfU0lHTkFUVVJFX1RZUEUgKHNpZyk7CiAgaWYgKHQgIT0gTlVMTF9UUkVFKQogICAgcmV0dXJuIFRSRUVfVFlQRSAodCk7CiAgdCA9IG1ha2VfY2xhc3MgKCk7CiAgSURFTlRJRklFUl9TSUdOQVRVUkVfVFlQRSAoc2lnKSA9IGJ1aWxkX3BvaW50ZXJfdHlwZSAodCk7CiAgVFlQRV9BUlJBWV9QICh0KSA9IDE7CgogIGlmIChUUkVFX0NPREUgKGVsX25hbWUpID09IFBPSU5URVJfVFlQRSkKICAgIGVsX25hbWUgPSBUUkVFX1RZUEUgKGVsX25hbWUpOwogIGVsX25hbWUgPSBUWVBFX05BTUUgKGVsX25hbWUpOwogIGlmIChUUkVFX0NPREUgKGVsX25hbWUpID09IFRZUEVfREVDTCkKICAgIGVsX25hbWUgPSBERUNMX05BTUUgKGVsX25hbWUpOwogIHsKICAgIGNoYXIgc3VmZml4WzIzXTsKICAgIGlmIChsZW5ndGggPj0gMCkKICAgICAgc3ByaW50ZiAoc3VmZml4LCAiWyVkXSIsIChpbnQpbGVuZ3RoKTsgCiAgICBlbHNlCiAgICAgIHN0cmNweSAoc3VmZml4LCAiW10iKTsKICAgIFRZUEVfTkFNRSAodCkgCiAgICAgID0gVFlQRV9TVFVCX0RFQ0wgKHQpCiAgICAgID0gYnVpbGRfZGVjbCAoVFlQRV9ERUNMLAoJCSAgICBpZGVudGlmaWVyX3N1YnN0IChlbF9uYW1lLCAiIiwgJy4nLCAnLicsIHN1ZmZpeCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdCk7CiAgICBUWVBFX0RFQ0xfU1VQUFJFU1NfREVCVUcgKFRZUEVfU1RVQl9ERUNMICh0KSkgPSB0cnVlOwogIH0KCiAgc2V0X2phdmFfc2lnbmF0dXJlICh0LCBzaWcpOwogIHNldF9zdXBlcl9pbmZvICgwLCB0LCBvYmplY3RfdHlwZV9ub2RlLCAwKTsKICBpZiAoVFJFRV9DT0RFIChlbGVtZW50X3R5cGUpID09IFJFQ09SRF9UWVBFKQogICAgZWxlbWVudF90eXBlID0gcHJvbW90ZV90eXBlIChlbGVtZW50X3R5cGUpOwogIFRZUEVfQVJSQVlfRUxFTUVOVCAodCkgPSBlbGVtZW50X3R5cGU7CgogIC8qIEFkZCBsZW5ndGggcHNldWRvLWZpZWxkLiAqLwogIGZsZCA9IGJ1aWxkX2RlY2wgKEZJRUxEX0RFQ0wsIGdldF9pZGVudGlmaWVyICgibGVuZ3RoIiksIGludF90eXBlX25vZGUpOwogIFRZUEVfRklFTERTICh0KSA9IGZsZDsKICBERUNMX0NPTlRFWFQgKGZsZCkgPSB0OwogIEZJRUxEX1BVQkxJQyAoZmxkKSA9IDE7CiAgRklFTERfRklOQUwgKGZsZCkgPSAxOwogIFRSRUVfUkVBRE9OTFkgKGZsZCkgPSAxOwoKICBhdHlwZSA9IGJ1aWxkX3ByaW1fYXJyYXlfdHlwZSAoZWxlbWVudF90eXBlLCBsZW5ndGgpOwogIGFyZmxkID0gYnVpbGRfZGVjbCAoRklFTERfREVDTCwgZ2V0X2lkZW50aWZpZXIgKCJkYXRhIiksIGF0eXBlKTsKICBERUNMX0NPTlRFWFQgKGFyZmxkKSA9IHQ7CiAgVFJFRV9DSEFJTiAoZmxkKSA9IGFyZmxkOwogIERFQ0xfQUxJR04gKGFyZmxkKSA9IFRZUEVfQUxJR04gKGVsZW1lbnRfdHlwZSk7CgogIC8qIFdlIGNvdWxkIGxheW91dF9jbGFzcywgYnV0IHRoYXQgbG9hZHMgamF2YS5sYW5nLk9iamVjdCBwcmVtYXR1cmVseS4KICAgKiBUaGlzIGlzIGNhbGxlZCBieSB0aGUgcGFyc2VyLCBhbmQgaXQgaXMgYSBiYWQgaWRlYSB0byBkbyBsb2FkX2NsYXNzCiAgICogaW4gdGhlIG1pZGRsZSBvZiBwYXJzaW5nLCBiZWNhdXNlIG9mIHBvc3NpYmxlIGNpcmN1bGFyaXR5IHByb2JsZW1zLiAqLwogIHB1c2hfc3VwZXJfZmllbGQgKHQsIG9iamVjdF90eXBlX25vZGUpOwogIGxheW91dF90eXBlICh0KTsKCiAgcmV0dXJuIHQ7Cn0KCi8qIFByb21vdGUgVFlQRSB0byB0aGUgdHlwZSBhY3R1YWxseSB1c2VkIGZvciBmaWVsZHMgYW5kIHBhcmFtZXRlcnMuICovCgp0cmVlCnByb21vdGVfdHlwZSAodHJlZSB0eXBlKQp7CiAgc3dpdGNoIChUUkVFX0NPREUgKHR5cGUpKQogICAgewogICAgY2FzZSBSRUNPUkRfVFlQRToKICAgICAgcmV0dXJuIGJ1aWxkX3BvaW50ZXJfdHlwZSAodHlwZSk7CiAgICBjYXNlIEJPT0xFQU5fVFlQRToKICAgICAgaWYgKHR5cGUgPT0gYm9vbGVhbl90eXBlX25vZGUpCglyZXR1cm4gcHJvbW90ZWRfYm9vbGVhbl90eXBlX25vZGU7CiAgICAgIGdvdG8gaGFuZGxlX2ludDsKICAgIGNhc2UgSU5URUdFUl9UWVBFOgogICAgICBpZiAodHlwZSA9PSBjaGFyX3R5cGVfbm9kZSkKCXJldHVybiBwcm9tb3RlZF9jaGFyX3R5cGVfbm9kZTsKICAgIGhhbmRsZV9pbnQ6CiAgICAgIGlmIChUWVBFX1BSRUNJU0lPTiAodHlwZSkgPCBUWVBFX1BSRUNJU0lPTiAoaW50X3R5cGVfbm9kZSkpCgl7CgkgIGlmICh0eXBlID09IHNob3J0X3R5cGVfbm9kZSkKCSAgICByZXR1cm4gcHJvbW90ZWRfc2hvcnRfdHlwZV9ub2RlOwoJICBpZiAodHlwZSA9PSBieXRlX3R5cGVfbm9kZSkKCSAgICByZXR1cm4gcHJvbW90ZWRfYnl0ZV90eXBlX25vZGU7CgkgIHJldHVybiBpbnRfdHlwZV9ub2RlOwoJfQogICAgICAvKiAuLi4gZWxzZSBmYWxsIHRocm91Z2ggLi4uICovCiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gdHlwZTsKICAgIH0KfQoKLyogUGFyc2UgYSBzaWduYXR1cmUgc3RyaW5nLCBzdGFydGluZyBhdCAqUFRSIGFuZCBlbmRpbmcgYXQgTElNSVQuCiAgIFJldHVybiB0aGUgc2VlbiBUUkVFX1RZUEUsIHVwZGF0aW5nICpQVFIuICovCgpzdGF0aWMgdHJlZQpwYXJzZV9zaWduYXR1cmVfdHlwZSAoY29uc3QgdW5zaWduZWQgY2hhciAqKnB0ciwgY29uc3QgdW5zaWduZWQgY2hhciAqbGltaXQpCnsKICB0cmVlIHR5cGU7CiAgZ2NjX2Fzc2VydCAoKnB0ciA8IGxpbWl0KTsKCiAgc3dpdGNoICgqKnB0cikKICAgIHsKICAgIGNhc2UgJ0InOiAgKCpwdHIpKys7ICByZXR1cm4gYnl0ZV90eXBlX25vZGU7CiAgICBjYXNlICdDJzogICgqcHRyKSsrOyAgcmV0dXJuIGNoYXJfdHlwZV9ub2RlOwogICAgY2FzZSAnRCc6ICAoKnB0cikrKzsgIHJldHVybiBkb3VibGVfdHlwZV9ub2RlOwogICAgY2FzZSAnRic6ICAoKnB0cikrKzsgIHJldHVybiBmbG9hdF90eXBlX25vZGU7CiAgICBjYXNlICdTJzogICgqcHRyKSsrOyAgcmV0dXJuIHNob3J0X3R5cGVfbm9kZTsKICAgIGNhc2UgJ0knOiAgKCpwdHIpKys7ICByZXR1cm4gaW50X3R5cGVfbm9kZTsKICAgIGNhc2UgJ0onOiAgKCpwdHIpKys7ICByZXR1cm4gbG9uZ190eXBlX25vZGU7CiAgICBjYXNlICdaJzogICgqcHRyKSsrOyAgcmV0dXJuIGJvb2xlYW5fdHlwZV9ub2RlOwogICAgY2FzZSAnVic6ICAoKnB0cikrKzsgIHJldHVybiB2b2lkX3R5cGVfbm9kZTsKICAgIGNhc2UgJ1snOgogICAgICBmb3IgKCgqcHRyKSsrOyAoKnB0cikgPCBsaW1pdCAmJiBJU0RJR0lUICgqKnB0cik7ICkgKCpwdHIpKys7CiAgICAgIHR5cGUgPSBwYXJzZV9zaWduYXR1cmVfdHlwZSAocHRyLCBsaW1pdCk7CiAgICAgIHR5cGUgPSBidWlsZF9qYXZhX2FycmF5X3R5cGUgKHR5cGUsIC0xKTsgCiAgICAgIGJyZWFrOwogICAgY2FzZSAnTCc6CiAgICAgIHsKCWNvbnN0IHVuc2lnbmVkIGNoYXIgKnN0YXJ0ID0gKysoKnB0cik7Cgljb25zdCB1bnNpZ25lZCBjaGFyICpzdHIgPSBzdGFydDsKCWZvciAoIDsgOyBzdHIrKykKCSAgewoJICAgIGdjY19hc3NlcnQgKHN0ciA8IGxpbWl0KTsKCSAgICBpZiAoKnN0ciA9PSAnOycpCgkgICAgICBicmVhazsKCSAgfQoJKnB0ciA9IHN0cisxOwoJdHlwZSA9IGxvb2t1cF9jbGFzcyAodW5tYW5nbGVfY2xhc3NuYW1lICgoY29uc3QgY2hhciAqKSBzdGFydCwgc3RyIC0gc3RhcnQpKTsKCWJyZWFrOwogICAgICB9CiAgICBkZWZhdWx0OgogICAgICBnY2NfdW5yZWFjaGFibGUgKCk7CiAgICB9CiAgcmV0dXJuIHByb21vdGVfdHlwZSAodHlwZSk7Cn0KCi8qIFBhcnNlIGEgSmF2YSAibWFuZ2xlZCIgc2lnbmF0dXJlIHN0cmluZywgc3RhcnRpbmcgYXQgU0lHX1NUUklORywKICAgYW5kIFNJR19MRU5HVEggYnl0ZXMgbG9uZy4KICAgUmV0dXJuIGEgZ2NjIHR5cGUgbm9kZS4gKi8KCnRyZWUKcGFyc2Vfc2lnbmF0dXJlX3N0cmluZyAoY29uc3QgdW5zaWduZWQgY2hhciAqc2lnX3N0cmluZywgaW50IHNpZ19sZW5ndGgpCnsKICB0cmVlIHJlc3VsdF90eXBlOwogIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnN0ciA9IHNpZ19zdHJpbmc7CiAgY29uc3QgdW5zaWduZWQgY2hhciAqbGltaXQgPSBzdHIgKyBzaWdfbGVuZ3RoOwoKICBpZiAoc3RyIDwgbGltaXQgJiYgc3RyWzBdID09ICcoJykKICAgIHsKICAgICAgdHJlZSBhcmd0eXBlX2xpc3QgPSBOVUxMX1RSRUU7CiAgICAgIHN0cisrOwogICAgICB3aGlsZSAoc3RyIDwgbGltaXQgJiYgc3RyWzBdICE9ICcpJykKCXsKCSAgdHJlZSBhcmd0eXBlID0gcGFyc2Vfc2lnbmF0dXJlX3R5cGUgKCZzdHIsIGxpbWl0KTsKCSAgYXJndHlwZV9saXN0ID0gdHJlZV9jb25zIChOVUxMX1RSRUUsIGFyZ3R5cGUsIGFyZ3R5cGVfbGlzdCk7Cgl9CiAgICAgIGlmIChzdHIrKywgc3RyID49IGxpbWl0KQoJYWJvcnQgKCk7CiAgICAgIHJlc3VsdF90eXBlID0gcGFyc2Vfc2lnbmF0dXJlX3R5cGUgKCZzdHIsIGxpbWl0KTsKICAgICAgYXJndHlwZV9saXN0ID0gY2hhaW5vbiAobnJldmVyc2UgKGFyZ3R5cGVfbGlzdCksIGVuZF9wYXJhbXNfbm9kZSk7CiAgICAgIHJlc3VsdF90eXBlID0gYnVpbGRfZnVuY3Rpb25fdHlwZSAocmVzdWx0X3R5cGUsIGFyZ3R5cGVfbGlzdCk7CiAgICB9CiAgZWxzZQogICAgcmVzdWx0X3R5cGUgPSBwYXJzZV9zaWduYXR1cmVfdHlwZSAoJnN0ciwgbGltaXQpOwogIGlmIChzdHIgIT0gbGltaXQpCiAgICBlcnJvciAoImp1bmsgYXQgZW5kIG9mIHNpZ25hdHVyZSBzdHJpbmciKTsKICByZXR1cm4gcmVzdWx0X3R5cGU7Cn0KCi8qIENvbnZlcnQgYSBzaWduYXR1cmUgdG8gaXRzIHR5cGUuCiAqIFVzZXMgSURFTlRJRklFUl9TSUdOQVRVUkVfVFlQRSBhcyBhIGNhY2hlIChleGNlcHQgZm9yIHByaW1pdGl2ZSB0eXBlcykuCiAqLwoKdHJlZQpnZXRfdHlwZV9mcm9tX3NpZ25hdHVyZSAodHJlZSBzaWduYXR1cmUpCnsKICBjb25zdCB1bnNpZ25lZCBjaGFyICpzaWcgPSAoY29uc3QgdW5zaWduZWQgY2hhciAqKSBJREVOVElGSUVSX1BPSU5URVIgKHNpZ25hdHVyZSk7CiAgaW50IGxlbiA9IElERU5USUZJRVJfTEVOR1RIIChzaWduYXR1cmUpOwogIHRyZWUgdHlwZTsKICAvKiBQcmltaXRpdmUgdHlwZXMgYXJlbid0IGNhY2hlZC4gKi8KICBpZiAobGVuIDw9IDEpCiAgICByZXR1cm4gcGFyc2Vfc2lnbmF0dXJlX3N0cmluZyAoc2lnLCBsZW4pOwogIHR5cGUgPSBJREVOVElGSUVSX1NJR05BVFVSRV9UWVBFIChzaWduYXR1cmUpOwogIGlmICh0eXBlID09IE5VTExfVFJFRSkKICAgIHsKICAgICAgdHlwZSA9IHBhcnNlX3NpZ25hdHVyZV9zdHJpbmcgKHNpZywgbGVuKTsKICAgICAgSURFTlRJRklFUl9TSUdOQVRVUkVfVFlQRSAoc2lnbmF0dXJlKSA9IHR5cGU7CiAgICB9CiAgcmV0dXJuIHR5cGU7Cn0KCi8qIElnbm9yZSBzaWduYXR1cmUgYW5kIGFsd2F5cyByZXR1cm4gbnVsbC4gIFVzZWQgYnkgaGFzX21ldGhvZC4gKi8KCnN0YXRpYyB0cmVlCmJ1aWxkX251bGxfc2lnbmF0dXJlICh0cmVlIHR5cGUgQVRUUklCVVRFX1VOVVNFRCkKewogIHJldHVybiBOVUxMX1RSRUU7Cn0KCi8qIFJldHVybiB0aGUgc2lnbmF0dXJlIHN0cmluZyBmb3IgdGhlIGFyZ3VtZW50cyBvZiBtZXRob2QgdHlwZSBUWVBFLiAqLwoKdHJlZQpidWlsZF9qYXZhX2FyZ3VtZW50X3NpZ25hdHVyZSAodHJlZSB0eXBlKQp7CiAgZXh0ZXJuIHN0cnVjdCBvYnN0YWNrIHRlbXBvcmFyeV9vYnN0YWNrOwogIHRyZWUgc2lnID0gVFlQRV9BUkdVTUVOVF9TSUdOQVRVUkUgKHR5cGUpOwogIGlmIChzaWcgPT0gTlVMTF9UUkVFKQogICAgewogICAgICB0cmVlIGFyZ3MgPSBUWVBFX0FSR19UWVBFUyAodHlwZSk7CiAgICAgIGlmIChUUkVFX0NPREUgKHR5cGUpID09IE1FVEhPRF9UWVBFKQoJYXJncyA9IFRSRUVfQ0hBSU4gKGFyZ3MpOyAgLyogU2tpcCAidGhpcyIgYXJndW1lbnQuICovCiAgICAgIGZvciAoOyBhcmdzICE9IGVuZF9wYXJhbXNfbm9kZTsgYXJncyA9IFRSRUVfQ0hBSU4gKGFyZ3MpKQoJewoJICB0cmVlIHQgPSBidWlsZF9qYXZhX3NpZ25hdHVyZSAoVFJFRV9WQUxVRSAoYXJncykpOwoJICBvYnN0YWNrX2dyb3cgKCZ0ZW1wb3Jhcnlfb2JzdGFjaywKCQkJSURFTlRJRklFUl9QT0lOVEVSICh0KSwgSURFTlRJRklFUl9MRU5HVEggKHQpKTsKCX0KICAgICAgb2JzdGFja18xZ3JvdyAoJnRlbXBvcmFyeV9vYnN0YWNrLCAnXDAnKTsKCiAgICAgIHNpZyA9IGdldF9pZGVudGlmaWVyIChvYnN0YWNrX2Jhc2UgKCZ0ZW1wb3Jhcnlfb2JzdGFjaykpOwogICAgICBUWVBFX0FSR1VNRU5UX1NJR05BVFVSRSAodHlwZSkgPSBzaWc7CiAgICAgIG9ic3RhY2tfZnJlZSAoJnRlbXBvcmFyeV9vYnN0YWNrLCBvYnN0YWNrX2Jhc2UgKCZ0ZW1wb3Jhcnlfb2JzdGFjaykpOwogICAgfQogIHJldHVybiBzaWc7Cn0KCi8qIFJldHVybiB0aGUgc2lnbmF0dXJlIG9mIHRoZSBnaXZlbiBUWVBFLiAqLwoKdHJlZQpidWlsZF9qYXZhX3NpZ25hdHVyZSAodHJlZSB0eXBlKQp7CiAgdHJlZSBzaWcsIHQ7CiAgd2hpbGUgKFRSRUVfQ09ERSAodHlwZSkgPT0gUE9JTlRFUl9UWVBFKQogICAgdHlwZSA9IFRSRUVfVFlQRSAodHlwZSk7CiAgTUFZQkVfQ1JFQVRFX1RZUEVfVFlQRV9MQU5HX1NQRUNJRklDICh0eXBlKTsKICBzaWcgPSBUWVBFX1NJR05BVFVSRSAodHlwZSk7CiAgaWYgKHNpZyA9PSBOVUxMX1RSRUUpCiAgICB7CiAgICAgIGNoYXIgc2dbMl07CiAgICAgIHN3aXRjaCAoVFJFRV9DT0RFICh0eXBlKSkKCXsKCWNhc2UgQk9PTEVBTl9UWVBFOiBzZ1swXSA9ICdaJzsgIGdvdG8gbmF0aXZlOwoJY2FzZSBWT0lEX1RZUEU6ICAgIHNnWzBdID0gJ1YnOyAgZ290byBuYXRpdmU7CgljYXNlIElOVEVHRVJfVFlQRToKICAgICAgICAgIGlmICh0eXBlID09IGNoYXJfdHlwZV9ub2RlIHx8IHR5cGUgPT0gcHJvbW90ZWRfY2hhcl90eXBlX25vZGUpCgkgICAgewoJICAgICAgc2dbMF0gPSAnQyc7CgkgICAgICBnb3RvIG5hdGl2ZTsKCSAgICB9CgkgIHN3aXRjaCAoVFlQRV9QUkVDSVNJT04gKHR5cGUpKQoJICAgIHsKCSAgICBjYXNlICA4OiAgICAgICBzZ1swXSA9ICdCJzsgIGdvdG8gbmF0aXZlOwoJICAgIGNhc2UgMTY6ICAgICAgIHNnWzBdID0gJ1MnOyAgZ290byBuYXRpdmU7CgkgICAgY2FzZSAzMjogICAgICAgc2dbMF0gPSAnSSc7ICBnb3RvIG5hdGl2ZTsKCSAgICBjYXNlIDY0OiAgICAgICBzZ1swXSA9ICdKJzsgIGdvdG8gbmF0aXZlOwoJICAgIGRlZmF1bHQ6ICBnb3RvIGJhZF90eXBlOwoJICAgIH0KCWNhc2UgUkVBTF9UWVBFOgoJICBzd2l0Y2ggKFRZUEVfUFJFQ0lTSU9OICh0eXBlKSkKCSAgICB7CgkgICAgY2FzZSAzMjogICAgICAgc2dbMF0gPSAnRic7ICBnb3RvIG5hdGl2ZTsKCSAgICBjYXNlIDY0OiAgICAgICBzZ1swXSA9ICdEJzsgIGdvdG8gbmF0aXZlOwoJICAgIGRlZmF1bHQ6ICBnb3RvIGJhZF90eXBlOwoJICAgIH0KCW5hdGl2ZToKCSAgc2dbMV0gPSAwOwoJICBzaWcgPSBnZXRfaWRlbnRpZmllciAoc2cpOwoJICBicmVhazsKCWNhc2UgUkVDT1JEX1RZUEU6CgkgIGlmIChUWVBFX0FSUkFZX1AgKHR5cGUpKQoJICAgIHsKCSAgICAgIHQgPSBidWlsZF9qYXZhX3NpZ25hdHVyZSAoVFlQRV9BUlJBWV9FTEVNRU5UICh0eXBlKSk7CgkgICAgICBzaWcgPSBpZGVudF9zdWJzdCAoSURFTlRJRklFUl9QT0lOVEVSICh0KSwgSURFTlRJRklFUl9MRU5HVEggKHQpLAoJCQkJICJbIiwgMCwgMCwgIiIpOwoJICAgIH0KCSAgZWxzZQoJICAgIHsKCSAgICAgIHQgPSBERUNMX05BTUUgKFRZUEVfTkFNRSAodHlwZSkpOwoJICAgICAgc2lnID0gaWRlbnRfc3Vic3QgKElERU5USUZJRVJfUE9JTlRFUiAodCksIElERU5USUZJRVJfTEVOR1RIICh0KSwKCQkJCSAiTCIsICcuJywgJy8nLCAiOyIpOwoJICAgIH0KCSAgYnJlYWs7CgljYXNlIE1FVEhPRF9UWVBFOgoJY2FzZSBGVU5DVElPTl9UWVBFOgoJICB7CgkgICAgZXh0ZXJuIHN0cnVjdCBvYnN0YWNrIHRlbXBvcmFyeV9vYnN0YWNrOwoJICAgIHNpZyA9IGJ1aWxkX2phdmFfYXJndW1lbnRfc2lnbmF0dXJlICh0eXBlKTsKCSAgICBvYnN0YWNrXzFncm93ICgmdGVtcG9yYXJ5X29ic3RhY2ssICcoJyk7CgkgICAgb2JzdGFja19ncm93ICgmdGVtcG9yYXJ5X29ic3RhY2ssCgkJCSAgSURFTlRJRklFUl9QT0lOVEVSIChzaWcpLCBJREVOVElGSUVSX0xFTkdUSCAoc2lnKSk7CgkgICAgb2JzdGFja18xZ3JvdyAoJnRlbXBvcmFyeV9vYnN0YWNrLCAnKScpOwoKCSAgICB0ID0gYnVpbGRfamF2YV9zaWduYXR1cmUgKFRSRUVfVFlQRSAodHlwZSkpOwoJICAgIG9ic3RhY2tfZ3JvdzAgKCZ0ZW1wb3Jhcnlfb2JzdGFjaywKCQkJICAgSURFTlRJRklFUl9QT0lOVEVSICh0KSwgSURFTlRJRklFUl9MRU5HVEggKHQpKTsKCgkgICAgc2lnID0gZ2V0X2lkZW50aWZpZXIgKG9ic3RhY2tfYmFzZSAoJnRlbXBvcmFyeV9vYnN0YWNrKSk7CgkgICAgb2JzdGFja19mcmVlICgmdGVtcG9yYXJ5X29ic3RhY2ssCgkJCSAgb2JzdGFja19iYXNlICgmdGVtcG9yYXJ5X29ic3RhY2spKTsKCSAgfQoJICBicmVhazsKCWJhZF90eXBlOgoJZGVmYXVsdDoKCSAgZ2NjX3VucmVhY2hhYmxlICgpOwoJfQogICAgICBUWVBFX1NJR05BVFVSRSAodHlwZSkgPSBzaWc7CiAgICB9CiAgcmV0dXJuIHNpZzsKfQoKLyogU2F2ZSBzaWduYXR1cmUgc3RyaW5nIFNJRyAoYW4gSURFTlRJRklFUl9OT0RFKSBpbiBUWVBFIGZvciBmdXR1cmUgdXNlLiAqLwoKdm9pZApzZXRfamF2YV9zaWduYXR1cmUgKHRyZWUgdHlwZSwgdHJlZSBzaWcpCnsKICB0cmVlIG9sZF9zaWc7CiAgd2hpbGUgKFRSRUVfQ09ERSAodHlwZSkgPT0gUE9JTlRFUl9UWVBFKQogICAgdHlwZSA9IFRSRUVfVFlQRSAodHlwZSk7CiAgTUFZQkVfQ1JFQVRFX1RZUEVfVFlQRV9MQU5HX1NQRUNJRklDICh0eXBlKTsKICBvbGRfc2lnID0gVFlQRV9TSUdOQVRVUkUgKHR5cGUpOwogIGlmIChvbGRfc2lnICE9IE5VTExfVFJFRSAmJiBvbGRfc2lnICE9IHNpZykKICAgIGFib3J0ICgpOwogIFRZUEVfU0lHTkFUVVJFICh0eXBlKSA9IHNpZzsKI2lmIDAgLyogY2FyZWZ1bCBhYm91dCBNRVRIT0RfVFlQRSAqLwogIGlmIChJREVOVElGSUVSX1NJR05BVFVSRV9UWVBFIChzaWcpID09IE5VTExfVFJFRSAmJiBUUkVFX1BFUk1BTkVOVCAodHlwZSkpCiAgICBJREVOVElGSUVSX1NJR05BVFVSRV9UWVBFIChzaWcpID0gdHlwZTsKI2VuZGlmCn0KCi8qIFNlYXJjaCBpbiBTRUFSQ0hFRF9DTEFTUyBhbmQgaXRzIHN1cGVyY2xhc3NlcyBmb3IgYSBtZXRob2QgbWF0Y2hpbmcKICAgTUVUSE9EX05BTUUgYW5kIHNpZ25hdHVyZSBNRVRIT0RfU0lHTkFUVVJFLiAgVGhpcyBmdW5jdGlvbiB3aWxsCiAgIG9ubHkgc2VhcmNoIGZvciBtZXRob2RzIGRlY2xhcmVkIGluIHRoZSBjbGFzcyBoaWVyYXJjaHk7IGludGVyZmFjZXMKICAgd2lsbCBub3QgYmUgY29uc2lkZXJlZC4gIFJldHVybnMgTlVMTF9UUkVFIGlmIHRoZSBtZXRob2QgaXMgbm90CiAgIGZvdW5kLiAgKi8KdHJlZQpsb29rdXBfYXJndW1lbnRfbWV0aG9kICh0cmVlIHNlYXJjaGVkX2NsYXNzLCB0cmVlIG1ldGhvZF9uYW1lLAoJCQl0cmVlIG1ldGhvZF9zaWduYXR1cmUpCnsKICByZXR1cm4gbG9va3VwX2RvIChzZWFyY2hlZF9jbGFzcywgMCwKCQkgICAgbWV0aG9kX25hbWUsIG1ldGhvZF9zaWduYXR1cmUsIAoJCSAgICBidWlsZF9qYXZhX2FyZ3VtZW50X3NpZ25hdHVyZSk7Cn0KCi8qIExpa2UgbG9va3VwX2FyZ3VtZW50X21ldGhvZCwgYnV0IGxldHMgdGhlIGNhbGxlciBzZXQgYW55IGZsYWdzCiAgIGRlc2lyZWQuICAqLwp0cmVlCmxvb2t1cF9hcmd1bWVudF9tZXRob2RfZ2VuZXJpYyAodHJlZSBzZWFyY2hlZF9jbGFzcywgdHJlZSBtZXRob2RfbmFtZSwKCQkJCXRyZWUgbWV0aG9kX3NpZ25hdHVyZSwgaW50IGZsYWdzKQp7CiAgcmV0dXJuIGxvb2t1cF9kbyAoc2VhcmNoZWRfY2xhc3MsIGZsYWdzLAoJCSAgICBtZXRob2RfbmFtZSwgbWV0aG9kX3NpZ25hdHVyZSwgCgkJICAgIGJ1aWxkX2phdmFfYXJndW1lbnRfc2lnbmF0dXJlKTsKfQoKCi8qIFNlYXJjaCBpbiBjbGFzcyBTRUFSQ0hFRF9DTEFTUyAoYW5kIGl0cyBzdXBlcmNsYXNzZXMpIGZvciBhIG1ldGhvZAogICBtYXRjaGluZyBNRVRIT0RfTkFNRSBhbmQgc2lnbmF0dXJlIE1FVEhPRF9TSUdOQVRVUkUuICBSZXR1cm4gYQogICBGVU5DVElPTl9ERUNMIG9uIHN1Y2Nlc3MsIG9yIE5VTExfVFJFRSBpZiBub25lIGZvdW5kLiAgKENvbnRyYXN0CiAgIGxvb2t1cF9hcmd1bWVudF9tZXRob2QsIHdoaWNoIGlnbm9yZXMgcmV0dXJuIHR5cGUuKSAgSWYKICAgU0VBUkNIRURfQ0xBU1MgaXMgYW4gaW50ZXJmYWNlLCBzZWFyY2ggaXQgdG9vLiAqLwp0cmVlCmxvb2t1cF9qYXZhX21ldGhvZCAodHJlZSBzZWFyY2hlZF9jbGFzcywgdHJlZSBtZXRob2RfbmFtZSwKCQkgICAgdHJlZSBtZXRob2Rfc2lnbmF0dXJlKQp7CiAgcmV0dXJuIGxvb2t1cF9kbyAoc2VhcmNoZWRfY2xhc3MsIFNFQVJDSF9JTlRFUkZBQ0UsIG1ldGhvZF9uYW1lLCAKCQkgICAgbWV0aG9kX3NpZ25hdHVyZSwgYnVpbGRfamF2YV9zaWduYXR1cmUpOwp9CgovKiBSZXR1cm4gdHJ1ZSBpZmYgQ0xBU1MgKG9yIGl0cyBhbmNlc3RvcnMpIGhhcyBhIG1ldGhvZCBNRVRIT0RfTkFNRS4goCovCmludApoYXNfbWV0aG9kICh0cmVlIGNsYXNzLCB0cmVlIG1ldGhvZF9uYW1lKQp7CiAgcmV0dXJuIGxvb2t1cF9kbyAoY2xhc3MsIFNFQVJDSF9JTlRFUkZBQ0UsCgkJICAgIG1ldGhvZF9uYW1lLCBOVUxMX1RSRUUsCgkJICAgIGJ1aWxkX251bGxfc2lnbmF0dXJlKSAhPSBOVUxMX1RSRUU7Cn0KCi8qIFNlYXJjaCBpbiBjbGFzcyBTRUFSQ0hFRF9DTEFTUywgYnV0IG5vdCBpdHMgc3VwZXJjbGFzc2VzLCBmb3IgYQogICBtZXRob2QgbWF0Y2hpbmcgTUVUSE9EX05BTUUgYW5kIHNpZ25hdHVyZSBTSUdOQVRVUkUuICBBIHByaXZhdGUKICAgaGVscGVyIGZvciBsb29rdXBfZG8uICAqLwpzdGF0aWMgdHJlZQpzaGFsbG93X2ZpbmRfbWV0aG9kICh0cmVlIHNlYXJjaGVkX2NsYXNzLCBpbnQgZmxhZ3MsIHRyZWUgbWV0aG9kX25hbWUsIAoJICAgICB0cmVlIHNpZ25hdHVyZSwgdHJlZSAoKnNpZ25hdHVyZV9idWlsZGVyKSAodHJlZSkpCnsKICB0cmVlIG1ldGhvZDsKICBmb3IgKG1ldGhvZCA9IFRZUEVfTUVUSE9EUyAoc2VhcmNoZWRfY2xhc3MpOwogICAgICAgbWV0aG9kICE9IE5VTExfVFJFRTsgIG1ldGhvZCA9IFRSRUVfQ0hBSU4gKG1ldGhvZCkpCiAgICB7CiAgICAgIHRyZWUgbWV0aG9kX3NpZyA9ICgqc2lnbmF0dXJlX2J1aWxkZXIpIChUUkVFX1RZUEUgKG1ldGhvZCkpOwogICAgICBpZiAoREVDTF9OQU1FIChtZXRob2QpID09IG1ldGhvZF9uYW1lICYmIG1ldGhvZF9zaWcgPT0gc2lnbmF0dXJlKQoJewoJICAvKiBJZiB0aGUgY2FsbGVyIHJlcXVpcmVzIGEgdmlzaWJsZSBtZXRob2QsIHRoZW4gd2UKCSAgICAgc2tpcCBpbnZpc2libGUgbWV0aG9kcyBoZXJlLiAgKi8KCSAgaWYgKCEgKGZsYWdzICYgU0VBUkNIX1ZJU0lCTEUpCgkgICAgICB8fCAhIE1FVEhPRF9JTlZJU0lCTEUgKG1ldGhvZCkpCgkgICAgcmV0dXJuIG1ldGhvZDsKCX0KICAgIH0KICByZXR1cm4gTlVMTF9UUkVFOwp9CgovKiBTZWFyY2ggaW4gdGhlIHN1cGVyY2xhc3NlcyBvZiBTRUFSQ0hFRF9DTEFTUyBmb3IgYSBtZXRob2QgbWF0Y2hpbmcKICAgTUVUSE9EX05BTUUgYW5kIHNpZ25hdHVyZSBTSUdOQVRVUkUuICBBIHByaXZhdGUgaGVscGVyIGZvcgogICBsb29rdXBfZG8uICAqLwpzdGF0aWMgdHJlZQpmaW5kX21ldGhvZF9pbl9zdXBlcmNsYXNzZXMgKHRyZWUgc2VhcmNoZWRfY2xhc3MsIGludCBmbGFncywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZSBtZXRob2RfbmFtZSwgdHJlZSBzaWduYXR1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZSAoKnNpZ25hdHVyZV9idWlsZGVyKSAodHJlZSkpCnsKICB0cmVlIGtsYXNzOwogIGZvciAoa2xhc3MgPSBDTEFTU1RZUEVfU1VQRVIgKHNlYXJjaGVkX2NsYXNzKTsga2xhc3MgIT0gTlVMTF9UUkVFOwogICAgICAga2xhc3MgPSBDTEFTU1RZUEVfU1VQRVIgKGtsYXNzKSkKICAgIHsKICAgICAgdHJlZSBtZXRob2Q7CiAgICAgIG1ldGhvZCA9IHNoYWxsb3dfZmluZF9tZXRob2QgKGtsYXNzLCBmbGFncywgbWV0aG9kX25hbWUsIAoJCQkJICAgIHNpZ25hdHVyZSwgc2lnbmF0dXJlX2J1aWxkZXIpOwogICAgICBpZiAobWV0aG9kICE9IE5VTExfVFJFRSkKCXJldHVybiBtZXRob2Q7CiAgICB9CgogIHJldHVybiBOVUxMX1RSRUU7Cn0KCi8qIFNlYXJjaCBpbiB0aGUgaW50ZXJmYWNlcyBvZiBTRUFSQ0hFRF9DTEFTUyBhbmQgaXRzIHN1cGVyaW50ZXJmYWNlcwogICBmb3IgYSBtZXRob2QgbWF0Y2hpbmcgTUVUSE9EX05BTUUgYW5kIHNpZ25hdHVyZSBTSUdOQVRVUkUuICBBCiAgIHByaXZhdGUgaGVscGVyIGZvciBsb29rdXBfZG8uICAqLwpzdGF0aWMgdHJlZQpmaW5kX21ldGhvZF9pbl9pbnRlcmZhY2VzICh0cmVlIHNlYXJjaGVkX2NsYXNzLCBpbnQgZmxhZ3MsIHRyZWUgbWV0aG9kX25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUgc2lnbmF0dXJlLCB0cmVlICgqc2lnbmF0dXJlX2J1aWxkZXIpICh0cmVlKSkKewogIGludCBpOwogIHRyZWUgYmluZm8sIGJhc2VfYmluZm87CgogIGZvciAoYmluZm8gPSBUWVBFX0JJTkZPIChzZWFyY2hlZF9jbGFzcyksIGkgPSAxOwogICAgICAgQklORk9fQkFTRV9JVEVSQVRFIChiaW5mbywgaSwgYmFzZV9iaW5mbyk7IGkrKykKICAgIHsKICAgICAgdHJlZSBpY2xhc3MgPSBCSU5GT19UWVBFIChiYXNlX2JpbmZvKTsKICAgICAgdHJlZSBtZXRob2Q7CgkgIAogICAgICAvKiBJZiB0aGUgc3VwZXJpbnRlcmZhY2UgaGFzbid0IGJlZW4gbG9hZGVkIHlldCwgZG8gc28gbm93LiAgKi8KICAgICAgaWYgKENMQVNTX0ZST01fU09VUkNFX1AgKGljbGFzcykpCglzYWZlX2xheW91dF9jbGFzcyAoaWNsYXNzKTsKICAgICAgZWxzZSBpZiAoIUNMQVNTX0xPQURFRF9QIChpY2xhc3MpKQoJbG9hZF9jbGFzcyAoaWNsYXNzLCAxKTsKCSAgCiAgICAgIC8qIEZpcnN0LCB3ZSBsb29rIGluIElDTEFTUy4gIElmIHRoYXQgZG9lc24ndCB3b3JrIHdlJ2xsCgkgcmVjdXJzaXZlbHkgbG9vayB0aHJvdWdoIGFsbCBpdHMgc3VwZXJpbnRlcmZhY2VzLiAgKi8KICAgICAgbWV0aG9kID0gc2hhbGxvd19maW5kX21ldGhvZCAoaWNsYXNzLCBmbGFncywgbWV0aG9kX25hbWUsIAoJCQkJICAgIHNpZ25hdHVyZSwgc2lnbmF0dXJlX2J1aWxkZXIpOyAgICAgIAogICAgICBpZiAobWV0aG9kICE9IE5VTExfVFJFRSkKCXJldHVybiBtZXRob2Q7CiAgCiAgICAgIG1ldGhvZCA9IGZpbmRfbWV0aG9kX2luX2ludGVyZmFjZXMgCgkoaWNsYXNzLCBmbGFncywgbWV0aG9kX25hbWUsIHNpZ25hdHVyZSwgc2lnbmF0dXJlX2J1aWxkZXIpOwogICAgICBpZiAobWV0aG9kICE9IE5VTExfVFJFRSkKCXJldHVybiBtZXRob2Q7CiAgICB9CiAgCiAgcmV0dXJuIE5VTExfVFJFRTsKfQoKCi8qIFNlYXJjaCBpbiBjbGFzcyBTRUFSQ0hFRF9DTEFTUyAoYW5kIGl0cyBzdXBlcmNsYXNzZXMpIGZvciBhIG1ldGhvZAogICBtYXRjaGluZyBNRVRIT0RfTkFNRSBhbmQgc2lnbmF0dXJlIFNJR05BVFVSRS4gIEZMQUdTIGNvbnRyb2wgc29tZQogICBwYXJhbWV0ZXJzIG9mIHRoZSBzZWFyY2guCiAgIAogICBTRUFSQ0hfSU5URVJGQUNFIG1lYW5zIGFsc28gc2VhcmNoIGludGVyZmFjZXMgYW5kIHN1cGVyaW50ZXJmYWNlcwogICBvZiBTRUFSQ0hFRF9DTEFTUy4KICAgCiAgIFNFQVJDSF9TVVBFUiBtZWFucyBza2lwIFNFQVJDSEVEX0NMQVNTIGFuZCBzdGFydCB3aXRoIGl0cwogICBzdXBlcmNsYXNzLgogICAKICAgU0VBUkNIX1ZJU0lCTEUgbWVhbnMgc2tpcCBtZXRob2RzIGZvciB3aGljaCBNRVRIT0RfSU5WSVNJQkxFIGlzCiAgIHNldC4KCiAgIFJldHVybiB0aGUgbWF0Y2hlZCBtZXRob2QgREVDTCBvciBOVUxMX1RSRUUuICBTSUdOQVRVUkVfQlVJTERFUiBpcwogICB1c2VkIG9uIG1ldGhvZCBjYW5kaWRhdGVzIHRvIGJ1aWxkIHRoZWlyIChzb21ldGltZXMgcGFydGlhbCkKICAgc2lnbmF0dXJlLiAgKi8Kc3RhdGljIHRyZWUKbG9va3VwX2RvICh0cmVlIHNlYXJjaGVkX2NsYXNzLCBpbnQgZmxhZ3MsIHRyZWUgbWV0aG9kX25hbWUsCgkgICB0cmVlIHNpZ25hdHVyZSwgdHJlZSAoKnNpZ25hdHVyZV9idWlsZGVyKSAodHJlZSkpCnsKICB0cmVlIG1ldGhvZDsKICB0cmVlIG9yaWdfY2xhc3MgPSBzZWFyY2hlZF9jbGFzczsKICAgIAogIGlmIChzZWFyY2hlZF9jbGFzcyA9PSBOVUxMX1RSRUUpCiAgICByZXR1cm4gTlVMTF9UUkVFOwoKICBpZiAoZmxhZ3MgJiBTRUFSQ0hfU1VQRVIpCiAgICB7CiAgICAgIHNlYXJjaGVkX2NsYXNzID0gQ0xBU1NUWVBFX1NVUEVSIChzZWFyY2hlZF9jbGFzcyk7CiAgICAgIGlmIChzZWFyY2hlZF9jbGFzcyA9PSBOVUxMX1RSRUUpCglyZXR1cm4gTlVMTF9UUkVFOwogICAgfQoKICAvKiBGaXJzdCBsb29rIGluIG91ciBvd24gbWV0aG9kcy4gICovCiAgbWV0aG9kID0gc2hhbGxvd19maW5kX21ldGhvZCAoc2VhcmNoZWRfY2xhc3MsIGZsYWdzLCBtZXRob2RfbmFtZSwKCQkJCXNpZ25hdHVyZSwgc2lnbmF0dXJlX2J1aWxkZXIpOyAgCiAgaWYgKG1ldGhvZCkKICAgIHJldHVybiBtZXRob2Q7CgogIC8qIFRoZW4gbG9vayBpbiBvdXIgc3VwZXJjbGFzc2VzLiAgKi8KICBpZiAoISBDTEFTU19JTlRFUkZBQ0UgKFRZUEVfTkFNRSAoc2VhcmNoZWRfY2xhc3MpKSkKICAgIG1ldGhvZCA9IGZpbmRfbWV0aG9kX2luX3N1cGVyY2xhc3NlcyAoc2VhcmNoZWRfY2xhc3MsIGZsYWdzLCBtZXRob2RfbmFtZSwKCQkJCQkgIHNpZ25hdHVyZSwgc2lnbmF0dXJlX2J1aWxkZXIpOyAgCiAgaWYgKG1ldGhvZCkKICAgIHJldHVybiBtZXRob2Q7CiAgCiAgLyogSWYgdGhhdCBkb2Vzbid0IHdvcmssIGxvb2sgaW4gb3VyIGludGVyZmFjZXMuICAqLwogIGlmIChmbGFncyAmIFNFQVJDSF9JTlRFUkZBQ0UpCiAgICBtZXRob2QgPSBmaW5kX21ldGhvZF9pbl9pbnRlcmZhY2VzIChvcmlnX2NsYXNzLCBmbGFncywgbWV0aG9kX25hbWUsIAoJCQkJCXNpZ25hdHVyZSwgc2lnbmF0dXJlX2J1aWxkZXIpOwogIAogIHJldHVybiBtZXRob2Q7Cn0KCi8qIFNlYXJjaCBpbiBjbGFzcyBDTEFTIGZvciBhIGNvbnN0cnVjdG9yIG1hdGNoaW5nIE1FVEhPRF9TSUdOQVRVUkUuCiAgIFJldHVybiBhIEZVTkNUSU9OX0RFQ0wgb24gc3VjY2Vzcywgb3IgTlVMTF9UUkVFIGlmIG5vbmUgZm91bmQuICovCgp0cmVlCmxvb2t1cF9qYXZhX2NvbnN0cnVjdG9yICh0cmVlIGNsYXMsIHRyZWUgbWV0aG9kX3NpZ25hdHVyZSkKewogIHRyZWUgbWV0aG9kID0gVFlQRV9NRVRIT0RTIChjbGFzKTsKICBmb3IgKCA7IG1ldGhvZCAhPSBOVUxMX1RSRUU7ICBtZXRob2QgPSBUUkVFX0NIQUlOIChtZXRob2QpKQogICAgewogICAgICB0cmVlIG1ldGhvZF9zaWcgPSBidWlsZF9qYXZhX3NpZ25hdHVyZSAoVFJFRV9UWVBFIChtZXRob2QpKTsKICAgICAgaWYgKERFQ0xfQ09OU1RSVUNUT1JfUCAobWV0aG9kKSAmJiBtZXRob2Rfc2lnID09IG1ldGhvZF9zaWduYXR1cmUpCglyZXR1cm4gbWV0aG9kOwogICAgfQogIHJldHVybiBOVUxMX1RSRUU7Cn0KCi8qIFJldHVybiBhIHR5cGUgd2hpY2ggaXMgdGhlIEJpbmFyeSBOdW1lcmljIFByb21vdGlvbiBvZiB0aGUgcGFpciBUMSwKICAgVDIgYW5kIGNvbnZlcnQgRVhQMSBhbmQvb3IgRVhQMi4gU2VlIDUuNi4yIEJpbmFyeSBOdW1lcmljCiAgIFByb21vdGlvbi4gSXQgYXNzdW1lcyB0aGF0IGJvdGggVDEgYW5kIFQyIGFyZSBlbGlnaWJsZSB0byBCTlAuICovCgp0cmVlCmJpbmFyeV9udW1lcmljX3Byb21vdGlvbiAodHJlZSB0MSwgdHJlZSB0MiwgdHJlZSAqZXhwMSwgdHJlZSAqZXhwMikKewogIGlmICh0MSA9PSBkb3VibGVfdHlwZV9ub2RlIHx8IHQyID09IGRvdWJsZV90eXBlX25vZGUpCiAgICB7CiAgICAgIGlmICh0MSAhPSBkb3VibGVfdHlwZV9ub2RlKQoJKmV4cDEgPSBjb252ZXJ0IChkb3VibGVfdHlwZV9ub2RlLCAqZXhwMSk7CiAgICAgIGlmICh0MiAhPSBkb3VibGVfdHlwZV9ub2RlKQoJKmV4cDIgPSBjb252ZXJ0IChkb3VibGVfdHlwZV9ub2RlLCAqZXhwMik7CiAgICAgIHJldHVybiBkb3VibGVfdHlwZV9ub2RlOwogICAgfQogIGlmICh0MSA9PSBmbG9hdF90eXBlX25vZGUgfHwgdDIgPT0gZmxvYXRfdHlwZV9ub2RlKQogICAgewogICAgICBpZiAodDEgIT0gZmxvYXRfdHlwZV9ub2RlKQoJKmV4cDEgPSBjb252ZXJ0IChmbG9hdF90eXBlX25vZGUsICpleHAxKTsKICAgICAgaWYgKHQyICE9IGZsb2F0X3R5cGVfbm9kZSkKCSpleHAyID0gY29udmVydCAoZmxvYXRfdHlwZV9ub2RlLCAqZXhwMik7CiAgICAgIHJldHVybiBmbG9hdF90eXBlX25vZGU7CiAgICB9CiAgaWYgKHQxID09IGxvbmdfdHlwZV9ub2RlIHx8IHQyID09IGxvbmdfdHlwZV9ub2RlKQogICAgewogICAgICBpZiAodDEgIT0gbG9uZ190eXBlX25vZGUpCgkqZXhwMSA9IGNvbnZlcnQgKGxvbmdfdHlwZV9ub2RlLCAqZXhwMSk7CiAgICAgIGlmICh0MiAhPSBsb25nX3R5cGVfbm9kZSkKCSpleHAyID0gY29udmVydCAobG9uZ190eXBlX25vZGUsICpleHAyKTsKICAgICAgcmV0dXJuIGxvbmdfdHlwZV9ub2RlOwogICAgfQoKICBpZiAodDEgIT0gaW50X3R5cGVfbm9kZSkKICAgICpleHAxID0gY29udmVydCAoaW50X3R5cGVfbm9kZSwgKmV4cDEpOwogIGlmICh0MiAhPSBpbnRfdHlwZV9ub2RlKQogICAgKmV4cDIgPSBjb252ZXJ0IChpbnRfdHlwZV9ub2RlLCAqZXhwMik7CiAgcmV0dXJuIGludF90eXBlX25vZGU7Cn0K