LyogSGFuZGxlIHR5cGVzIGZvciB0aGUgR05VIGNvbXBpbGVyIGZvciB0aGUgSmF2YShUTSkgbGFuZ3VhZ2UuCiAgIENvcHlyaWdodCAoQykgMTk5NiwgMTk5NywgMTk5OCwgMTk5OSwgMjAwMCwgMjAwMSwgMjAwMywgMjAwNCwgMjAwNSwgMjAwNywgMjAwOAogICBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4KClRoaXMgZmlsZSBpcyBwYXJ0IG9mIEdDQy4KCkdDQyBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5Cml0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CnRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDMsIG9yIChhdCB5b3VyIG9wdGlvbikKYW55IGxhdGVyIHZlcnNpb24uCgpHQ0MgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQpHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgoKWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKYWxvbmcgd2l0aCBHQ0M7IHNlZSB0aGUgZmlsZSBDT1BZSU5HMy4gIElmIG5vdCBzZWUKPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LiAgCgpKYXZhIGFuZCBhbGwgSmF2YS1iYXNlZCBtYXJrcyBhcmUgdHJhZGVtYXJrcyBvciByZWdpc3RlcmVkIHRyYWRlbWFya3MKb2YgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBpbiB0aGUgVW5pdGVkIFN0YXRlcyBhbmQgb3RoZXIgY291bnRyaWVzLgpUaGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGlzIGluZGVwZW5kZW50IG9mIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gICovCgovKiBXcml0dGVuIGJ5IFBlciBCb3RobmVyIDxib3RobmVyQGN5Z251cy5jb20+ICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJzeXN0ZW0uaCIKI2luY2x1ZGUgImNvcmV0eXBlcy5oIgojaW5jbHVkZSAidG0uaCIKI2luY2x1ZGUgInRyZWUuaCIKI2luY2x1ZGUgInJlYWwuaCIKI2luY2x1ZGUgIm9ic3RhY2suaCIKI2luY2x1ZGUgImZsYWdzLmgiCiNpbmNsdWRlICJqYXZhLXRyZWUuaCIKI2luY2x1ZGUgImpjZi5oIgojaW5jbHVkZSAiY29udmVydC5oIgojaW5jbHVkZSAidG9wbGV2LmgiCiNpbmNsdWRlICJnZ2MuaCIKCnN0YXRpYyB0cmVlIGNvbnZlcnRfaWVlZV9yZWFsX3RvX2ludGVnZXIgKHRyZWUsIHRyZWUpOwpzdGF0aWMgdHJlZSBwYXJzZV9zaWduYXR1cmVfdHlwZSAoY29uc3QgdW5zaWduZWQgY2hhciAqKiwKCQkJCSAgY29uc3QgdW5zaWduZWQgY2hhciAqKTsKc3RhdGljIHRyZWUgbG9va3VwX2RvICh0cmVlLCBpbnQsIHRyZWUsIHRyZWUsIHRyZWUgKCopKHRyZWUpKTsKc3RhdGljIHRyZWUgYnVpbGRfbnVsbF9zaWduYXR1cmUgKHRyZWUpOwoKdHJlZSAqIHR5cGVfbWFwOwoKLyogU2V0IHRoZSB0eXBlIG9mIHRoZSBsb2NhbCB2YXJpYWJsZSB3aXRoIGluZGV4IFNMT1QgdG8gVFlQRS4gKi8KCnZvaWQKc2V0X2xvY2FsX3R5cGUgKGludCBzbG90LCB0cmVlIHR5cGUpCnsKICBpbnQgbWF4X2xvY2FscyA9IERFQ0xfTUFYX0xPQ0FMUyhjdXJyZW50X2Z1bmN0aW9uX2RlY2wpOwogIGludCBuc2xvdHMgPSBUWVBFX0lTX1dJREUgKHR5cGUpID8gMiA6IDE7CgogIGdjY19hc3NlcnQgKHNsb3QgPj0gMCAmJiAoc2xvdCArIG5zbG90cyAtIDEgPCBtYXhfbG9jYWxzKSk7CgogIHR5cGVfbWFwW3Nsb3RdID0gdHlwZTsKICB3aGlsZSAoLS1uc2xvdHMgPiAwKQogICAgdHlwZV9tYXBbKytzbG90XSA9IHZvaWRfdHlwZV9ub2RlOwp9CgovKiBDb252ZXJ0IGFuIElFRUUgcmVhbCB0byBhbiBpbnRlZ2VyIHR5cGUuICBUaGUgcmVzdWx0IG9mIHN1Y2ggYQogICBjb252ZXJzaW9uIHdoZW4gdGhlIHNvdXJjZSBvcGVyYW5kIGlzIGEgTmFOIGlzbid0IGRlZmluZWQgYnkKICAgSUVFRTc1NCwgYnV0IGJ5IHRoZSBKYXZhIGxhbmd1YWdlIHN0YW5kYXJkOiBpdCBtdXN0IGJlIHplcm8uICBBbHNvLAogICBvdmVyZmxvd3MgbXVzdCBiZSBjbGlwcGVkIHRvIHdpdGhpbiByYW5nZS4gIFRoaXMgY29udmVyc2lvbgogICBwcm9kdWNlcyBzb21ldGhpbmcgbGlrZToKCiAgICAgICgoZXhwciA+PSAoZmxvYXQpTUFYX0lOVCkKICAgICAgID8gTUFYX0lOVCAKICAgICAgIDogKChleHByIDw9IChmbG9hdClNSU5fSU5UKQoJICA/IE1JTl9JTlQKCSAgOiAoKGV4cHIgIT0gZXhwcikKCSAgICAgPyAwIAoJICAgICA6IChpbnQpZXhwcikpKSAqLwoKc3RhdGljIHRyZWUKY29udmVydF9pZWVlX3JlYWxfdG9faW50ZWdlciAodHJlZSB0eXBlLCB0cmVlIGV4cHIpCnsKICB0cmVlIHJlc3VsdDsKICBleHByID0gc2F2ZV9leHByIChleHByKTsKCiAgcmVzdWx0ID0gZm9sZF9idWlsZDMgKENPTkRfRVhQUiwgdHlwZSwKCQkJZm9sZF9idWlsZDIgKE5FX0VYUFIsIGJvb2xlYW5fdHlwZV9ub2RlLCBleHByLCBleHByKSwKCQkJIGNvbnZlcnQgKHR5cGUsIGludGVnZXJfemVyb19ub2RlKSwKCQkJIGNvbnZlcnRfdG9faW50ZWdlciAodHlwZSwgZXhwcikpOwogIAogIHJlc3VsdCA9IGZvbGRfYnVpbGQzIChDT05EX0VYUFIsIHR5cGUsIAoJCQlmb2xkX2J1aWxkMiAoTEVfRVhQUiwgYm9vbGVhbl90eXBlX25vZGUsIGV4cHIsIAoJCQkJICAgICBjb252ZXJ0IChUUkVFX1RZUEUgKGV4cHIpLCAKCQkJCQkgICAgICBUWVBFX01JTl9WQUxVRSAodHlwZSkpKSwKCQkJVFlQRV9NSU5fVkFMVUUgKHR5cGUpLAoJCQlyZXN1bHQpOwogIAogIHJlc3VsdCA9IGZvbGRfYnVpbGQzIChDT05EX0VYUFIsIHR5cGUsCgkJCWZvbGRfYnVpbGQyIChHRV9FWFBSLCBib29sZWFuX3R5cGVfbm9kZSwgZXhwciwgCgkJCQkgICAgIGNvbnZlcnQgKFRSRUVfVFlQRSAoZXhwciksIAoJCQkJCSAgICAgIFRZUEVfTUFYX1ZBTFVFICh0eXBlKSkpLAoJCQlUWVBFX01BWF9WQUxVRSAodHlwZSksCgkJCXJlc3VsdCk7CgogIHJldHVybiByZXN1bHQ7Cn0gIAoKLyogQ3JlYXRlIGFuIGV4cHJlc3Npb24gd2hvc2UgdmFsdWUgaXMgdGhhdCBvZiBFWFBSLAogICBjb252ZXJ0ZWQgdG8gdHlwZSBUWVBFLiAgVGhlIFRSRUVfVFlQRSBvZiB0aGUgdmFsdWUKICAgaXMgYWx3YXlzIFRZUEUuICBUaGlzIGZ1bmN0aW9uIGltcGxlbWVudHMgYWxsIHJlYXNvbmFibGUKICAgY29udmVyc2lvbnM7IGNhbGxlcnMgc2hvdWxkIGZpbHRlciBvdXQgdGhvc2UgdGhhdCBhcmUKICAgbm90IHBlcm1pdHRlZCBieSB0aGUgbGFuZ3VhZ2UgYmVpbmcgY29tcGlsZWQuICAqLwoKdHJlZQpjb252ZXJ0ICh0cmVlIHR5cGUsIHRyZWUgZXhwcikKewogIGVudW0gdHJlZV9jb2RlIGNvZGUgPSBUUkVFX0NPREUgKHR5cGUpOwoKICBpZiAoIWV4cHIpCiAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CgogIGlmICh0eXBlID09IFRSRUVfVFlQRSAoZXhwcikKICAgICAgfHwgVFJFRV9DT0RFIChleHByKSA9PSBFUlJPUl9NQVJLKQogICAgcmV0dXJuIGV4cHI7CiAgaWYgKFRSRUVfQ09ERSAoVFJFRV9UWVBFIChleHByKSkgPT0gRVJST1JfTUFSSykKICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CiAgaWYgKGNvZGUgPT0gVk9JRF9UWVBFKQogICAgcmV0dXJuIGJ1aWxkMSAoQ09OVkVSVF9FWFBSLCB0eXBlLCBleHByKTsKICBpZiAoY29kZSA9PSBCT09MRUFOX1RZUEUpCiAgICByZXR1cm4gZm9sZF9jb252ZXJ0ICh0eXBlLCBleHByKTsKICBpZiAoY29kZSA9PSBJTlRFR0VSX1RZUEUpCiAgICB7CiAgICAgIGlmICh0eXBlID09IGNoYXJfdHlwZV9ub2RlIHx8IHR5cGUgPT0gcHJvbW90ZWRfY2hhcl90eXBlX25vZGUpCglyZXR1cm4gZm9sZF9jb252ZXJ0ICh0eXBlLCBleHByKTsKICAgICAgaWYgKChyZWFsbHlfY29uc3RhbnRfcCAoZXhwcikgfHwgISBmbGFnX3Vuc2FmZV9tYXRoX29wdGltaXphdGlvbnMpCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9UWVBFIChleHByKSkgPT0gUkVBTF9UWVBFKQoJcmV0dXJuIGNvbnZlcnRfaWVlZV9yZWFsX3RvX2ludGVnZXIgKHR5cGUsIGV4cHIpOwogICAgICBlbHNlCgl7CgkgIC8qIGZvbGQgdmVyeSBoZWxwZnVsbHkgc2V0cyB0aGUgb3ZlcmZsb3cgc3RhdHVzIGlmIGEgdHlwZQoJICAgICBvdmVyZmxvd3MgaW4gYSBuYXJyb3dpbmcgaW50ZWdlciBjb252ZXJzaW9uLCBidXQgSmF2YQoJICAgICBkb2Vzbid0IGNhcmUuICAqLwoJICB0cmVlIHRtcCA9IGZvbGQgKGNvbnZlcnRfdG9faW50ZWdlciAodHlwZSwgZXhwcikpOwoJICBpZiAoVFJFRV9DT0RFICh0bXApID09IElOVEVHRVJfQ1NUKQoJICAgIFRSRUVfT1ZFUkZMT1cgKHRtcCkgPSAwOwoJICByZXR1cm4gdG1wOwoJfQogICAgfQkgIAogIGlmIChjb2RlID09IFJFQUxfVFlQRSkKICAgIHJldHVybiBmb2xkIChjb252ZXJ0X3RvX3JlYWwgKHR5cGUsIGV4cHIpKTsKICBpZiAoY29kZSA9PSBQT0lOVEVSX1RZUEUpCiAgICByZXR1cm4gZm9sZCAoY29udmVydF90b19wb2ludGVyICh0eXBlLCBleHByKSk7CiAgZXJyb3IgKCJjb252ZXJzaW9uIHRvIG5vbi1zY2FsYXIgdHlwZSByZXF1ZXN0ZWQiKTsKICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwp9CgoKLyogUmV0dXJuIGEgZGF0YSB0eXBlIHRoYXQgaGFzIG1hY2hpbmUgbW9kZSBNT0RFLgogICBJZiB0aGUgbW9kZSBpcyBhbiBpbnRlZ2VyLAogICB0aGVuIFVOU0lHTkVEUCBzZWxlY3RzIGJldHdlZW4gc2lnbmVkIGFuZCB1bnNpZ25lZCB0eXBlcy4gICovCgp0cmVlCmphdmFfdHlwZV9mb3JfbW9kZSAoZW51bSBtYWNoaW5lX21vZGUgbW9kZSwgaW50IHVuc2lnbmVkcCkKewogIGlmIChtb2RlID09IFRZUEVfTU9ERSAoaW50X3R5cGVfbm9kZSkpCiAgICByZXR1cm4gdW5zaWduZWRwID8gdW5zaWduZWRfaW50X3R5cGVfbm9kZSA6IGludF90eXBlX25vZGU7CiAgaWYgKG1vZGUgPT0gVFlQRV9NT0RFIChsb25nX3R5cGVfbm9kZSkpCiAgICByZXR1cm4gdW5zaWduZWRwID8gdW5zaWduZWRfbG9uZ190eXBlX25vZGUgOiBsb25nX3R5cGVfbm9kZTsKICBpZiAobW9kZSA9PSBUWVBFX01PREUgKHNob3J0X3R5cGVfbm9kZSkpCiAgICByZXR1cm4gdW5zaWduZWRwID8gdW5zaWduZWRfc2hvcnRfdHlwZV9ub2RlIDogc2hvcnRfdHlwZV9ub2RlOwogIGlmIChtb2RlID09IFRZUEVfTU9ERSAoYnl0ZV90eXBlX25vZGUpKQogICAgcmV0dXJuIHVuc2lnbmVkcCA/IHVuc2lnbmVkX2J5dGVfdHlwZV9ub2RlIDogYnl0ZV90eXBlX25vZGU7CiAgaWYgKG1vZGUgPT0gVFlQRV9NT0RFIChmbG9hdF90eXBlX25vZGUpKQogICAgcmV0dXJuIGZsb2F0X3R5cGVfbm9kZTsKICBpZiAobW9kZSA9PSBUWVBFX01PREUgKGRvdWJsZV90eXBlX25vZGUpKQogICAgcmV0dXJuIGRvdWJsZV90eXBlX25vZGU7CgogIHJldHVybiAwOwp9CgovKiBSZXR1cm4gYW4gaW50ZWdlciB0eXBlIHdpdGggQklUUyBiaXRzIG9mIHByZWNpc2lvbiwKICAgdGhhdCBpcyB1bnNpZ25lZCBpZiBVTlNJR05FRFAgaXMgbm9uemVybywgb3RoZXJ3aXNlIHNpZ25lZC4gICovCgp0cmVlCmphdmFfdHlwZV9mb3Jfc2l6ZSAodW5zaWduZWQgYml0cywgaW50IHVuc2lnbmVkcCkKewogIGlmIChiaXRzIDw9IFRZUEVfUFJFQ0lTSU9OIChieXRlX3R5cGVfbm9kZSkpCiAgICByZXR1cm4gdW5zaWduZWRwID8gdW5zaWduZWRfYnl0ZV90eXBlX25vZGUgOiBieXRlX3R5cGVfbm9kZTsKICBpZiAoYml0cyA8PSBUWVBFX1BSRUNJU0lPTiAoc2hvcnRfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9zaG9ydF90eXBlX25vZGUgOiBzaG9ydF90eXBlX25vZGU7CiAgaWYgKGJpdHMgPD0gVFlQRV9QUkVDSVNJT04gKGludF90eXBlX25vZGUpKQogICAgcmV0dXJuIHVuc2lnbmVkcCA/IHVuc2lnbmVkX2ludF90eXBlX25vZGUgOiBpbnRfdHlwZV9ub2RlOwogIGlmIChiaXRzIDw9IFRZUEVfUFJFQ0lTSU9OIChsb25nX3R5cGVfbm9kZSkpCiAgICByZXR1cm4gdW5zaWduZWRwID8gdW5zaWduZWRfbG9uZ190eXBlX25vZGUgOiBsb25nX3R5cGVfbm9kZTsKICByZXR1cm4gMDsKfQoKLyogTWFyayBFWFAgc2F5aW5nIHRoYXQgd2UgbmVlZCB0byBiZSBhYmxlIHRvIHRha2UgdGhlCiAgIGFkZHJlc3Mgb2YgaXQ7IGl0IHNob3VsZCBub3QgYmUgYWxsb2NhdGVkIGluIGEgcmVnaXN0ZXIuCiAgIFZhbHVlIGlzIHRydWUgaWYgc3VjY2Vzc2Z1bC4gICovCgpib29sCmphdmFfbWFya19hZGRyZXNzYWJsZSAodHJlZSBleHApCnsKICB0cmVlIHggPSBleHA7CiAgd2hpbGUgKDEpCiAgICBzd2l0Y2ggKFRSRUVfQ09ERSAoeCkpCiAgICAgIHsKICAgICAgY2FzZSBBRERSX0VYUFI6CiAgICAgIGNhc2UgQ09NUE9ORU5UX1JFRjoKICAgICAgY2FzZSBBUlJBWV9SRUY6CiAgICAgIGNhc2UgUkVBTFBBUlRfRVhQUjoKICAgICAgY2FzZSBJTUFHUEFSVF9FWFBSOgoJeCA9IFRSRUVfT1BFUkFORCAoeCwgMCk7CglicmVhazsKCiAgICAgIGNhc2UgVFJVVEhfQU5ESUZfRVhQUjoKICAgICAgY2FzZSBUUlVUSF9PUklGX0VYUFI6CiAgICAgIGNhc2UgQ09NUE9VTkRfRVhQUjoKCXggPSBUUkVFX09QRVJBTkQgKHgsIDEpOwoJYnJlYWs7CgogICAgICBjYXNlIENPTkRfRVhQUjoKCXJldHVybiBqYXZhX21hcmtfYWRkcmVzc2FibGUgKFRSRUVfT1BFUkFORCAoeCwgMSkpCgkgICYmIGphdmFfbWFya19hZGRyZXNzYWJsZSAoVFJFRV9PUEVSQU5EICh4LCAyKSk7CgogICAgICBjYXNlIENPTlNUUlVDVE9SOgoJVFJFRV9BRERSRVNTQUJMRSAoeCkgPSAxOwoJcmV0dXJuIHRydWU7CgogICAgICBjYXNlIElORElSRUNUX1JFRjoKCS8qIFdlIHNvbWV0aW1lcyBhZGQgYSBjYXN0ICooVFlQRSopJkZPTyB0byBoYW5kbGUgdHlwZSBhbmQgbW9kZQoJICAgaW5jb21wYXRpYmlsaXR5IHByb2JsZW1zLiAgSGFuZGxlIHRoaXMgY2FzZSBieSBtYXJraW5nIEZPTy4gICovCglpZiAoVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKHgsIDApKSA9PSBOT1BfRVhQUgoJICAgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKHgsIDApLCAwKSkgPT0gQUREUl9FWFBSKQoJICB7CgkgICAgeCA9IFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EICh4LCAwKSwgMCk7CgkgICAgYnJlYWs7CgkgIH0KCWlmIChUUkVFX0NPREUgKFRSRUVfT1BFUkFORCAoeCwgMCkpID09IEFERFJfRVhQUikKCSAgewoJICAgIHggPSBUUkVFX09QRVJBTkQgKHgsIDApOwoJICAgIGJyZWFrOwoJICB9CglyZXR1cm4gdHJ1ZTsKCiAgICAgIGNhc2UgVkFSX0RFQ0w6CiAgICAgIGNhc2UgQ09OU1RfREVDTDoKICAgICAgY2FzZSBQQVJNX0RFQ0w6CiAgICAgIGNhc2UgUkVTVUxUX0RFQ0w6CiAgICAgIGNhc2UgRlVOQ1RJT05fREVDTDoKCVRSRUVfQUREUkVTU0FCTEUgKHgpID0gMTsKI2lmIDAgIC8qIHBvcGxldmVsIGRlYWxzIHdpdGggdGhpcyBub3cuICAqLwoJaWYgKERFQ0xfQ09OVEVYVCAoeCkgPT0gMCkKCSAgVFJFRV9BRERSRVNTQUJMRSAoREVDTF9BU1NFTUJMRVJfTkFNRSAoeCkpID0gMTsKI2VuZGlmCgkvKiBkcm9wcyB0aHJvdWdoICovCiAgICAgIGRlZmF1bHQ6CglyZXR1cm4gdHJ1ZTsKICAgIH0KfQoKLyogVGhvcm91Z2ggY2hlY2tpbmcgb2YgdGhlIGFycmF5bmVzcyBvZiBUWVBFLiAgKi8KCmludAppc19hcnJheV90eXBlX3AgKHRyZWUgdHlwZSkKewogIHJldHVybiBUUkVFX0NPREUgKHR5cGUpID09IFBPSU5URVJfVFlQRQogICAgJiYgVFJFRV9DT0RFIChUUkVFX1RZUEUgKHR5cGUpKSA9PSBSRUNPUkRfVFlQRQogICAgJiYgVFlQRV9BUlJBWV9QIChUUkVFX1RZUEUgKHR5cGUpKTsKfQoKLyogUmV0dXJuIHRoZSBsZW5ndGggb2YgYSBKYXZhIGFycmF5IHR5cGUuCiAgIFJldHVybiAtMSBpZiB0aGUgbGVuZ3RoIGlzIHVua25vd24gb3Igbm9uLWNvbnN0YW50LiAqLwoKSE9TVF9XSURFX0lOVApqYXZhX2FycmF5X3R5cGVfbGVuZ3RoICh0cmVlIGFycmF5X3R5cGUpCnsKICB0cmVlIGFyZmxkOwogIGlmIChUUkVFX0NPREUgKGFycmF5X3R5cGUpID09IFBPSU5URVJfVFlQRSkKICAgIGFycmF5X3R5cGUgPSBUUkVFX1RZUEUgKGFycmF5X3R5cGUpOwogIGFyZmxkID0gVFJFRV9DSEFJTiAoVFJFRV9DSEFJTiAoVFlQRV9GSUVMRFMgKGFycmF5X3R5cGUpKSk7CiAgaWYgKGFyZmxkICE9IE5VTExfVFJFRSkKICAgIHsKICAgICAgdHJlZSBpbmRleF90eXBlID0gVFlQRV9ET01BSU4gKFRSRUVfVFlQRSAoYXJmbGQpKTsKICAgICAgaWYgKGluZGV4X3R5cGUgIT0gTlVMTF9UUkVFKQoJewoJICB0cmVlIGhpZ2ggPSBUWVBFX01BWF9WQUxVRSAoaW5kZXhfdHlwZSk7CgkgIGlmIChUUkVFX0NPREUgKGhpZ2gpID09IElOVEVHRVJfQ1NUKQoJICAgIHJldHVybiBUUkVFX0lOVF9DU1RfTE9XIChoaWdoKSArIDE7Cgl9CiAgICB9CiAgcmV0dXJuIC0xOwp9CgovKiBBbiBhcnJheSBvZiB1bmtub3duIGxlbmd0aCB3aWxsIGJlIHVsdGltYXRlbHkgZ2l2ZW4gYSBsZW5ndGggb2YKICAgLTIsIHNvIHRoYXQgd2UgY2FuIHN0aWxsIGhhdmUgYGxlbmd0aCcgcHJvZHVjaW5nIGEgbmVnYXRpdmUgdmFsdWUKICAgZXZlbiBpZiBmb3VuZC4gVGhpcyB3YXMgcGFydCBvZiBhbiBvcHRpbWl6YXRpb24gYWltaW5nIGF0IHJlbW92aW5nCiAgIGBsZW5ndGgnIGZyb20gc3RhdGljIGFycmF5cy4gV2UgY291bGQgcmVzdG9yZSBpdCwgRklYTUUuICAqLwoKdHJlZQpidWlsZF9wcmltX2FycmF5X3R5cGUgKHRyZWUgZWxlbWVudF90eXBlLCBIT1NUX1dJREVfSU5UIGxlbmd0aCkKewogIHRyZWUgaW5kZXggPSBOVUxMOwoKICBpZiAobGVuZ3RoICE9IC0xKQogICAgewogICAgICB0cmVlIG1heF9pbmRleCA9IGJ1aWxkX2ludF9jc3QgKHNpemV0eXBlLCBsZW5ndGggLSAxKTsKICAgICAgaW5kZXggPSBidWlsZF9pbmRleF90eXBlIChtYXhfaW5kZXgpOwogICAgfQogIHJldHVybiBidWlsZF9hcnJheV90eXBlIChlbGVtZW50X3R5cGUsIGluZGV4KTsKfQoKLyogUmV0dXJuIGEgSmF2YSBhcnJheSB0eXBlIHdpdGggYSBnaXZlbiBFTEVNRU5UX1RZUEUgYW5kIExFTkdUSC4KICAgVGhlc2UgYXJlIGhhc2hlZCAoc2hhcmVkKSB1c2luZyBJREVOVElGSUVSX1NJR05BVFVSRV9UWVBFLgogICBUaGUgTEVOR1RIIGlzIC0xIGlmIHRoZSBsZW5ndGggaXMgdW5rbm93bi4gKi8KCnRyZWUKYnVpbGRfamF2YV9hcnJheV90eXBlICh0cmVlIGVsZW1lbnRfdHlwZSwgSE9TVF9XSURFX0lOVCBsZW5ndGgpCnsKICB0cmVlIHNpZywgdCwgZmxkLCBhdHlwZSwgYXJmbGQ7CiAgY2hhciBidWZbMjNdOwogIHRyZWUgZWxzaWcgPSBidWlsZF9qYXZhX3NpZ25hdHVyZSAoZWxlbWVudF90eXBlKTsKICB0cmVlIGVsX25hbWUgPSBlbGVtZW50X3R5cGU7CiAgYnVmWzBdID0gJ1snOwogIGlmIChsZW5ndGggPj0gMCkKICAgIHNwcmludGYgKGJ1ZisxLCBIT1NUX1dJREVfSU5UX1BSSU5UX0RFQywgbGVuZ3RoKTsKICBlbHNlCiAgICBidWZbMV0gPSAnXDAnOwogIHNpZyA9IGlkZW50X3N1YnN0IChJREVOVElGSUVSX1BPSU5URVIgKGVsc2lnKSwgSURFTlRJRklFUl9MRU5HVEggKGVsc2lnKSwKCQkgICAgIGJ1ZiwgMCwgMCwgIiIpOwogIHQgPSBJREVOVElGSUVSX1NJR05BVFVSRV9UWVBFIChzaWcpOwogIGlmICh0ICE9IE5VTExfVFJFRSkKICAgIHJldHVybiBUUkVFX1RZUEUgKHQpOwogIHQgPSBtYWtlX2NsYXNzICgpOwogIElERU5USUZJRVJfU0lHTkFUVVJFX1RZUEUgKHNpZykgPSBidWlsZF9wb2ludGVyX3R5cGUgKHQpOwogIFRZUEVfQVJSQVlfUCAodCkgPSAxOwoKICBpZiAoVFJFRV9DT0RFIChlbF9uYW1lKSA9PSBQT0lOVEVSX1RZUEUpCiAgICBlbF9uYW1lID0gVFJFRV9UWVBFIChlbF9uYW1lKTsKICBlbF9uYW1lID0gVFlQRV9OQU1FIChlbF9uYW1lKTsKICBpZiAoVFJFRV9DT0RFIChlbF9uYW1lKSA9PSBUWVBFX0RFQ0wpCiAgICBlbF9uYW1lID0gREVDTF9OQU1FIChlbF9uYW1lKTsKICB7CiAgICBjaGFyIHN1ZmZpeFsyM107CiAgICBpZiAobGVuZ3RoID49IDApCiAgICAgIHNwcmludGYgKHN1ZmZpeCwgIlslZF0iLCAoaW50KWxlbmd0aCk7IAogICAgZWxzZQogICAgICBzdHJjcHkgKHN1ZmZpeCwgIltdIik7CiAgICBUWVBFX05BTUUgKHQpIAogICAgICA9IFRZUEVfU1RVQl9ERUNMICh0KQogICAgICA9IGJ1aWxkX2RlY2wgKFRZUEVfREVDTCwKCQkgICAgaWRlbnRpZmllcl9zdWJzdCAoZWxfbmFtZSwgIiIsICcuJywgJy4nLCBzdWZmaXgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQpOwogICAgVFlQRV9ERUNMX1NVUFBSRVNTX0RFQlVHIChUWVBFX1NUVUJfREVDTCAodCkpID0gdHJ1ZTsKICB9CgogIHNldF9qYXZhX3NpZ25hdHVyZSAodCwgc2lnKTsKICBzZXRfc3VwZXJfaW5mbyAoMCwgdCwgb2JqZWN0X3R5cGVfbm9kZSwgMCk7CiAgaWYgKFRSRUVfQ09ERSAoZWxlbWVudF90eXBlKSA9PSBSRUNPUkRfVFlQRSkKICAgIGVsZW1lbnRfdHlwZSA9IHByb21vdGVfdHlwZSAoZWxlbWVudF90eXBlKTsKICBUWVBFX0FSUkFZX0VMRU1FTlQgKHQpID0gZWxlbWVudF90eXBlOwoKICAvKiBBZGQgbGVuZ3RoIHBzZXVkby1maWVsZC4gKi8KICBmbGQgPSBidWlsZF9kZWNsIChGSUVMRF9ERUNMLCBnZXRfaWRlbnRpZmllciAoImxlbmd0aCIpLCBpbnRfdHlwZV9ub2RlKTsKICBUWVBFX0ZJRUxEUyAodCkgPSBmbGQ7CiAgREVDTF9DT05URVhUIChmbGQpID0gdDsKICBGSUVMRF9QVUJMSUMgKGZsZCkgPSAxOwogIEZJRUxEX0ZJTkFMIChmbGQpID0gMTsKICBUUkVFX1JFQURPTkxZIChmbGQpID0gMTsKCiAgYXR5cGUgPSBidWlsZF9wcmltX2FycmF5X3R5cGUgKGVsZW1lbnRfdHlwZSwgbGVuZ3RoKTsKICBhcmZsZCA9IGJ1aWxkX2RlY2wgKEZJRUxEX0RFQ0wsIGdldF9pZGVudGlmaWVyICgiZGF0YSIpLCBhdHlwZSk7CiAgREVDTF9DT05URVhUIChhcmZsZCkgPSB0OwogIFRSRUVfQ0hBSU4gKGZsZCkgPSBhcmZsZDsKICBERUNMX0FMSUdOIChhcmZsZCkgPSBUWVBFX0FMSUdOIChlbGVtZW50X3R5cGUpOwoKICAvKiBXZSBjb3VsZCBsYXlvdXRfY2xhc3MsIGJ1dCB0aGF0IGxvYWRzIGphdmEubGFuZy5PYmplY3QgcHJlbWF0dXJlbHkuCiAgICogVGhpcyBpcyBjYWxsZWQgYnkgdGhlIHBhcnNlciwgYW5kIGl0IGlzIGEgYmFkIGlkZWEgdG8gZG8gbG9hZF9jbGFzcwogICAqIGluIHRoZSBtaWRkbGUgb2YgcGFyc2luZywgYmVjYXVzZSBvZiBwb3NzaWJsZSBjaXJjdWxhcml0eSBwcm9ibGVtcy4gKi8KICBwdXNoX3N1cGVyX2ZpZWxkICh0LCBvYmplY3RfdHlwZV9ub2RlKTsKICBsYXlvdXRfdHlwZSAodCk7CgogIHJldHVybiB0Owp9CgovKiBQcm9tb3RlIFRZUEUgdG8gdGhlIHR5cGUgYWN0dWFsbHkgdXNlZCBmb3IgZmllbGRzIGFuZCBwYXJhbWV0ZXJzLiAqLwoKdHJlZQpwcm9tb3RlX3R5cGUgKHRyZWUgdHlwZSkKewogIHN3aXRjaCAoVFJFRV9DT0RFICh0eXBlKSkKICAgIHsKICAgIGNhc2UgUkVDT1JEX1RZUEU6CiAgICAgIHJldHVybiBidWlsZF9wb2ludGVyX3R5cGUgKHR5cGUpOwogICAgY2FzZSBCT09MRUFOX1RZUEU6CiAgICAgIGlmICh0eXBlID09IGJvb2xlYW5fdHlwZV9ub2RlKQoJcmV0dXJuIHByb21vdGVkX2Jvb2xlYW5fdHlwZV9ub2RlOwogICAgICBnb3RvIGhhbmRsZV9pbnQ7CiAgICBjYXNlIElOVEVHRVJfVFlQRToKICAgICAgaWYgKHR5cGUgPT0gY2hhcl90eXBlX25vZGUpCglyZXR1cm4gcHJvbW90ZWRfY2hhcl90eXBlX25vZGU7CiAgICBoYW5kbGVfaW50OgogICAgICBpZiAoVFlQRV9QUkVDSVNJT04gKHR5cGUpIDwgVFlQRV9QUkVDSVNJT04gKGludF90eXBlX25vZGUpKQoJewoJICBpZiAodHlwZSA9PSBzaG9ydF90eXBlX25vZGUpCgkgICAgcmV0dXJuIHByb21vdGVkX3Nob3J0X3R5cGVfbm9kZTsKCSAgaWYgKHR5cGUgPT0gYnl0ZV90eXBlX25vZGUpCgkgICAgcmV0dXJuIHByb21vdGVkX2J5dGVfdHlwZV9ub2RlOwoJICByZXR1cm4gaW50X3R5cGVfbm9kZTsKCX0KICAgICAgLyogLi4uIGVsc2UgZmFsbCB0aHJvdWdoIC4uLiAqLwogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIHR5cGU7CiAgICB9Cn0KCi8qIFBhcnNlIGEgc2lnbmF0dXJlIHN0cmluZywgc3RhcnRpbmcgYXQgKlBUUiBhbmQgZW5kaW5nIGF0IExJTUlULgogICBSZXR1cm4gdGhlIHNlZW4gVFJFRV9UWVBFLCB1cGRhdGluZyAqUFRSLiAqLwoKc3RhdGljIHRyZWUKcGFyc2Vfc2lnbmF0dXJlX3R5cGUgKGNvbnN0IHVuc2lnbmVkIGNoYXIgKipwdHIsIGNvbnN0IHVuc2lnbmVkIGNoYXIgKmxpbWl0KQp7CiAgdHJlZSB0eXBlOwogIGdjY19hc3NlcnQgKCpwdHIgPCBsaW1pdCk7CgogIHN3aXRjaCAoKipwdHIpCiAgICB7CiAgICBjYXNlICdCJzogICgqcHRyKSsrOyAgcmV0dXJuIGJ5dGVfdHlwZV9ub2RlOwogICAgY2FzZSAnQyc6ICAoKnB0cikrKzsgIHJldHVybiBjaGFyX3R5cGVfbm9kZTsKICAgIGNhc2UgJ0QnOiAgKCpwdHIpKys7ICByZXR1cm4gZG91YmxlX3R5cGVfbm9kZTsKICAgIGNhc2UgJ0YnOiAgKCpwdHIpKys7ICByZXR1cm4gZmxvYXRfdHlwZV9ub2RlOwogICAgY2FzZSAnUyc6ICAoKnB0cikrKzsgIHJldHVybiBzaG9ydF90eXBlX25vZGU7CiAgICBjYXNlICdJJzogICgqcHRyKSsrOyAgcmV0dXJuIGludF90eXBlX25vZGU7CiAgICBjYXNlICdKJzogICgqcHRyKSsrOyAgcmV0dXJuIGxvbmdfdHlwZV9ub2RlOwogICAgY2FzZSAnWic6ICAoKnB0cikrKzsgIHJldHVybiBib29sZWFuX3R5cGVfbm9kZTsKICAgIGNhc2UgJ1YnOiAgKCpwdHIpKys7ICByZXR1cm4gdm9pZF90eXBlX25vZGU7CiAgICBjYXNlICdbJzoKICAgICAgZm9yICgoKnB0cikrKzsgKCpwdHIpIDwgbGltaXQgJiYgSVNESUdJVCAoKipwdHIpOyApICgqcHRyKSsrOwogICAgICB0eXBlID0gcGFyc2Vfc2lnbmF0dXJlX3R5cGUgKHB0ciwgbGltaXQpOwogICAgICB0eXBlID0gYnVpbGRfamF2YV9hcnJheV90eXBlICh0eXBlLCAtMSk7IAogICAgICBicmVhazsKICAgIGNhc2UgJ0wnOgogICAgICB7Cgljb25zdCB1bnNpZ25lZCBjaGFyICpzdGFydCA9ICsrKCpwdHIpOwoJY29uc3QgdW5zaWduZWQgY2hhciAqc3RyID0gc3RhcnQ7Cglmb3IgKCA7IDsgc3RyKyspCgkgIHsKCSAgICBnY2NfYXNzZXJ0IChzdHIgPCBsaW1pdCk7CgkgICAgaWYgKCpzdHIgPT0gJzsnKQoJICAgICAgYnJlYWs7CgkgIH0KCSpwdHIgPSBzdHIrMTsKCXR5cGUgPSBsb29rdXBfY2xhc3MgKHVubWFuZ2xlX2NsYXNzbmFtZSAoKGNvbnN0IGNoYXIgKikgc3RhcnQsIHN0ciAtIHN0YXJ0KSk7CglicmVhazsKICAgICAgfQogICAgZGVmYXVsdDoKICAgICAgZ2NjX3VucmVhY2hhYmxlICgpOwogICAgfQogIHJldHVybiBwcm9tb3RlX3R5cGUgKHR5cGUpOwp9CgovKiBQYXJzZSBhIEphdmEgIm1hbmdsZWQiIHNpZ25hdHVyZSBzdHJpbmcsIHN0YXJ0aW5nIGF0IFNJR19TVFJJTkcsCiAgIGFuZCBTSUdfTEVOR1RIIGJ5dGVzIGxvbmcuCiAgIFJldHVybiBhIGdjYyB0eXBlIG5vZGUuICovCgp0cmVlCnBhcnNlX3NpZ25hdHVyZV9zdHJpbmcgKGNvbnN0IHVuc2lnbmVkIGNoYXIgKnNpZ19zdHJpbmcsIGludCBzaWdfbGVuZ3RoKQp7CiAgdHJlZSByZXN1bHRfdHlwZTsKICBjb25zdCB1bnNpZ25lZCBjaGFyICpzdHIgPSBzaWdfc3RyaW5nOwogIGNvbnN0IHVuc2lnbmVkIGNoYXIgKmxpbWl0ID0gc3RyICsgc2lnX2xlbmd0aDsKCiAgaWYgKHN0ciA8IGxpbWl0ICYmIHN0clswXSA9PSAnKCcpCiAgICB7CiAgICAgIHRyZWUgYXJndHlwZV9saXN0ID0gTlVMTF9UUkVFOwogICAgICBzdHIrKzsKICAgICAgd2hpbGUgKHN0ciA8IGxpbWl0ICYmIHN0clswXSAhPSAnKScpCgl7CgkgIHRyZWUgYXJndHlwZSA9IHBhcnNlX3NpZ25hdHVyZV90eXBlICgmc3RyLCBsaW1pdCk7CgkgIGFyZ3R5cGVfbGlzdCA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBhcmd0eXBlLCBhcmd0eXBlX2xpc3QpOwoJfQogICAgICBpZiAoc3RyKyssIHN0ciA+PSBsaW1pdCkKCWFib3J0ICgpOwogICAgICByZXN1bHRfdHlwZSA9IHBhcnNlX3NpZ25hdHVyZV90eXBlICgmc3RyLCBsaW1pdCk7CiAgICAgIGFyZ3R5cGVfbGlzdCA9IGNoYWlub24gKG5yZXZlcnNlIChhcmd0eXBlX2xpc3QpLCBlbmRfcGFyYW1zX25vZGUpOwogICAgICByZXN1bHRfdHlwZSA9IGJ1aWxkX2Z1bmN0aW9uX3R5cGUgKHJlc3VsdF90eXBlLCBhcmd0eXBlX2xpc3QpOwogICAgfQogIGVsc2UKICAgIHJlc3VsdF90eXBlID0gcGFyc2Vfc2lnbmF0dXJlX3R5cGUgKCZzdHIsIGxpbWl0KTsKICBpZiAoc3RyICE9IGxpbWl0KQogICAgZXJyb3IgKCJqdW5rIGF0IGVuZCBvZiBzaWduYXR1cmUgc3RyaW5nIik7CiAgcmV0dXJuIHJlc3VsdF90eXBlOwp9CgovKiBDb252ZXJ0IGEgc2lnbmF0dXJlIHRvIGl0cyB0eXBlLgogKiBVc2VzIElERU5USUZJRVJfU0lHTkFUVVJFX1RZUEUgYXMgYSBjYWNoZSAoZXhjZXB0IGZvciBwcmltaXRpdmUgdHlwZXMpLgogKi8KCnRyZWUKZ2V0X3R5cGVfZnJvbV9zaWduYXR1cmUgKHRyZWUgc2lnbmF0dXJlKQp7CiAgY29uc3QgdW5zaWduZWQgY2hhciAqc2lnID0gKGNvbnN0IHVuc2lnbmVkIGNoYXIgKikgSURFTlRJRklFUl9QT0lOVEVSIChzaWduYXR1cmUpOwogIGludCBsZW4gPSBJREVOVElGSUVSX0xFTkdUSCAoc2lnbmF0dXJlKTsKICB0cmVlIHR5cGU7CiAgLyogUHJpbWl0aXZlIHR5cGVzIGFyZW4ndCBjYWNoZWQuICovCiAgaWYgKGxlbiA8PSAxKQogICAgcmV0dXJuIHBhcnNlX3NpZ25hdHVyZV9zdHJpbmcgKHNpZywgbGVuKTsKICB0eXBlID0gSURFTlRJRklFUl9TSUdOQVRVUkVfVFlQRSAoc2lnbmF0dXJlKTsKICBpZiAodHlwZSA9PSBOVUxMX1RSRUUpCiAgICB7CiAgICAgIHR5cGUgPSBwYXJzZV9zaWduYXR1cmVfc3RyaW5nIChzaWcsIGxlbik7CiAgICAgIElERU5USUZJRVJfU0lHTkFUVVJFX1RZUEUgKHNpZ25hdHVyZSkgPSB0eXBlOwogICAgfQogIHJldHVybiB0eXBlOwp9CgovKiBJZ25vcmUgc2lnbmF0dXJlIGFuZCBhbHdheXMgcmV0dXJuIG51bGwuICBVc2VkIGJ5IGhhc19tZXRob2QuICovCgpzdGF0aWMgdHJlZQpidWlsZF9udWxsX3NpZ25hdHVyZSAodHJlZSB0eXBlIEFUVFJJQlVURV9VTlVTRUQpCnsKICByZXR1cm4gTlVMTF9UUkVFOwp9CgovKiBSZXR1cm4gdGhlIHNpZ25hdHVyZSBzdHJpbmcgZm9yIHRoZSBhcmd1bWVudHMgb2YgbWV0aG9kIHR5cGUgVFlQRS4gKi8KCnRyZWUKYnVpbGRfamF2YV9hcmd1bWVudF9zaWduYXR1cmUgKHRyZWUgdHlwZSkKewogIGV4dGVybiBzdHJ1Y3Qgb2JzdGFjayB0ZW1wb3Jhcnlfb2JzdGFjazsKICB0cmVlIHNpZyA9IFRZUEVfQVJHVU1FTlRfU0lHTkFUVVJFICh0eXBlKTsKICBpZiAoc2lnID09IE5VTExfVFJFRSkKICAgIHsKICAgICAgdHJlZSBhcmdzID0gVFlQRV9BUkdfVFlQRVMgKHR5cGUpOwogICAgICBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBNRVRIT0RfVFlQRSkKCWFyZ3MgPSBUUkVFX0NIQUlOIChhcmdzKTsgIC8qIFNraXAgInRoaXMiIGFyZ3VtZW50LiAqLwogICAgICBmb3IgKDsgYXJncyAhPSBlbmRfcGFyYW1zX25vZGU7IGFyZ3MgPSBUUkVFX0NIQUlOIChhcmdzKSkKCXsKCSAgdHJlZSB0ID0gYnVpbGRfamF2YV9zaWduYXR1cmUgKFRSRUVfVkFMVUUgKGFyZ3MpKTsKCSAgb2JzdGFja19ncm93ICgmdGVtcG9yYXJ5X29ic3RhY2ssCgkJCUlERU5USUZJRVJfUE9JTlRFUiAodCksIElERU5USUZJRVJfTEVOR1RIICh0KSk7Cgl9CiAgICAgIG9ic3RhY2tfMWdyb3cgKCZ0ZW1wb3Jhcnlfb2JzdGFjaywgJ1wwJyk7CgogICAgICBzaWcgPSBnZXRfaWRlbnRpZmllciAob2JzdGFja19iYXNlICgmdGVtcG9yYXJ5X29ic3RhY2spKTsKICAgICAgVFlQRV9BUkdVTUVOVF9TSUdOQVRVUkUgKHR5cGUpID0gc2lnOwogICAgICBvYnN0YWNrX2ZyZWUgKCZ0ZW1wb3Jhcnlfb2JzdGFjaywgb2JzdGFja19iYXNlICgmdGVtcG9yYXJ5X29ic3RhY2spKTsKICAgIH0KICByZXR1cm4gc2lnOwp9CgovKiBSZXR1cm4gdGhlIHNpZ25hdHVyZSBvZiB0aGUgZ2l2ZW4gVFlQRS4gKi8KCnRyZWUKYnVpbGRfamF2YV9zaWduYXR1cmUgKHRyZWUgdHlwZSkKewogIHRyZWUgc2lnLCB0OwogIHdoaWxlIChUUkVFX0NPREUgKHR5cGUpID09IFBPSU5URVJfVFlQRSkKICAgIHR5cGUgPSBUUkVFX1RZUEUgKHR5cGUpOwogIE1BWUJFX0NSRUFURV9UWVBFX1RZUEVfTEFOR19TUEVDSUZJQyAodHlwZSk7CiAgc2lnID0gVFlQRV9TSUdOQVRVUkUgKHR5cGUpOwogIGlmIChzaWcgPT0gTlVMTF9UUkVFKQogICAgewogICAgICBjaGFyIHNnWzJdOwogICAgICBzd2l0Y2ggKFRSRUVfQ09ERSAodHlwZSkpCgl7CgljYXNlIEJPT0xFQU5fVFlQRTogc2dbMF0gPSAnWic7ICBnb3RvIG5hdGl2ZTsKCWNhc2UgVk9JRF9UWVBFOiAgICBzZ1swXSA9ICdWJzsgIGdvdG8gbmF0aXZlOwoJY2FzZSBJTlRFR0VSX1RZUEU6CiAgICAgICAgICBpZiAodHlwZSA9PSBjaGFyX3R5cGVfbm9kZSB8fCB0eXBlID09IHByb21vdGVkX2NoYXJfdHlwZV9ub2RlKQoJICAgIHsKCSAgICAgIHNnWzBdID0gJ0MnOwoJICAgICAgZ290byBuYXRpdmU7CgkgICAgfQoJICBzd2l0Y2ggKFRZUEVfUFJFQ0lTSU9OICh0eXBlKSkKCSAgICB7CgkgICAgY2FzZSAgODogICAgICAgc2dbMF0gPSAnQic7ICBnb3RvIG5hdGl2ZTsKCSAgICBjYXNlIDE2OiAgICAgICBzZ1swXSA9ICdTJzsgIGdvdG8gbmF0aXZlOwoJICAgIGNhc2UgMzI6ICAgICAgIHNnWzBdID0gJ0knOyAgZ290byBuYXRpdmU7CgkgICAgY2FzZSA2NDogICAgICAgc2dbMF0gPSAnSic7ICBnb3RvIG5hdGl2ZTsKCSAgICBkZWZhdWx0OiAgZ290byBiYWRfdHlwZTsKCSAgICB9CgljYXNlIFJFQUxfVFlQRToKCSAgc3dpdGNoIChUWVBFX1BSRUNJU0lPTiAodHlwZSkpCgkgICAgewoJICAgIGNhc2UgMzI6ICAgICAgIHNnWzBdID0gJ0YnOyAgZ290byBuYXRpdmU7CgkgICAgY2FzZSA2NDogICAgICAgc2dbMF0gPSAnRCc7ICBnb3RvIG5hdGl2ZTsKCSAgICBkZWZhdWx0OiAgZ290byBiYWRfdHlwZTsKCSAgICB9CgluYXRpdmU6CgkgIHNnWzFdID0gMDsKCSAgc2lnID0gZ2V0X2lkZW50aWZpZXIgKHNnKTsKCSAgYnJlYWs7CgljYXNlIFJFQ09SRF9UWVBFOgoJICBpZiAoVFlQRV9BUlJBWV9QICh0eXBlKSkKCSAgICB7CgkgICAgICB0ID0gYnVpbGRfamF2YV9zaWduYXR1cmUgKFRZUEVfQVJSQVlfRUxFTUVOVCAodHlwZSkpOwoJICAgICAgc2lnID0gaWRlbnRfc3Vic3QgKElERU5USUZJRVJfUE9JTlRFUiAodCksIElERU5USUZJRVJfTEVOR1RIICh0KSwKCQkJCSAiWyIsIDAsIDAsICIiKTsKCSAgICB9CgkgIGVsc2UKCSAgICB7CgkgICAgICB0ID0gREVDTF9OQU1FIChUWVBFX05BTUUgKHR5cGUpKTsKCSAgICAgIHNpZyA9IGlkZW50X3N1YnN0IChJREVOVElGSUVSX1BPSU5URVIgKHQpLCBJREVOVElGSUVSX0xFTkdUSCAodCksCgkJCQkgIkwiLCAnLicsICcvJywgIjsiKTsKCSAgICB9CgkgIGJyZWFrOwoJY2FzZSBNRVRIT0RfVFlQRToKCWNhc2UgRlVOQ1RJT05fVFlQRToKCSAgewoJICAgIGV4dGVybiBzdHJ1Y3Qgb2JzdGFjayB0ZW1wb3Jhcnlfb2JzdGFjazsKCSAgICBzaWcgPSBidWlsZF9qYXZhX2FyZ3VtZW50X3NpZ25hdHVyZSAodHlwZSk7CgkgICAgb2JzdGFja18xZ3JvdyAoJnRlbXBvcmFyeV9vYnN0YWNrLCAnKCcpOwoJICAgIG9ic3RhY2tfZ3JvdyAoJnRlbXBvcmFyeV9vYnN0YWNrLAoJCQkgIElERU5USUZJRVJfUE9JTlRFUiAoc2lnKSwgSURFTlRJRklFUl9MRU5HVEggKHNpZykpOwoJICAgIG9ic3RhY2tfMWdyb3cgKCZ0ZW1wb3Jhcnlfb2JzdGFjaywgJyknKTsKCgkgICAgdCA9IGJ1aWxkX2phdmFfc2lnbmF0dXJlIChUUkVFX1RZUEUgKHR5cGUpKTsKCSAgICBvYnN0YWNrX2dyb3cwICgmdGVtcG9yYXJ5X29ic3RhY2ssCgkJCSAgIElERU5USUZJRVJfUE9JTlRFUiAodCksIElERU5USUZJRVJfTEVOR1RIICh0KSk7CgoJICAgIHNpZyA9IGdldF9pZGVudGlmaWVyIChvYnN0YWNrX2Jhc2UgKCZ0ZW1wb3Jhcnlfb2JzdGFjaykpOwoJICAgIG9ic3RhY2tfZnJlZSAoJnRlbXBvcmFyeV9vYnN0YWNrLAoJCQkgIG9ic3RhY2tfYmFzZSAoJnRlbXBvcmFyeV9vYnN0YWNrKSk7CgkgIH0KCSAgYnJlYWs7CgliYWRfdHlwZToKCWRlZmF1bHQ6CgkgIGdjY191bnJlYWNoYWJsZSAoKTsKCX0KICAgICAgVFlQRV9TSUdOQVRVUkUgKHR5cGUpID0gc2lnOwogICAgfQogIHJldHVybiBzaWc7Cn0KCi8qIFNhdmUgc2lnbmF0dXJlIHN0cmluZyBTSUcgKGFuIElERU5USUZJRVJfTk9ERSkgaW4gVFlQRSBmb3IgZnV0dXJlIHVzZS4gKi8KCnZvaWQKc2V0X2phdmFfc2lnbmF0dXJlICh0cmVlIHR5cGUsIHRyZWUgc2lnKQp7CiAgdHJlZSBvbGRfc2lnOwogIHdoaWxlIChUUkVFX0NPREUgKHR5cGUpID09IFBPSU5URVJfVFlQRSkKICAgIHR5cGUgPSBUUkVFX1RZUEUgKHR5cGUpOwogIE1BWUJFX0NSRUFURV9UWVBFX1RZUEVfTEFOR19TUEVDSUZJQyAodHlwZSk7CiAgb2xkX3NpZyA9IFRZUEVfU0lHTkFUVVJFICh0eXBlKTsKICBpZiAob2xkX3NpZyAhPSBOVUxMX1RSRUUgJiYgb2xkX3NpZyAhPSBzaWcpCiAgICBhYm9ydCAoKTsKICBUWVBFX1NJR05BVFVSRSAodHlwZSkgPSBzaWc7CiNpZiAwIC8qIGNhcmVmdWwgYWJvdXQgTUVUSE9EX1RZUEUgKi8KICBpZiAoSURFTlRJRklFUl9TSUdOQVRVUkVfVFlQRSAoc2lnKSA9PSBOVUxMX1RSRUUgJiYgVFJFRV9QRVJNQU5FTlQgKHR5cGUpKQogICAgSURFTlRJRklFUl9TSUdOQVRVUkVfVFlQRSAoc2lnKSA9IHR5cGU7CiNlbmRpZgp9CgovKiBTZWFyY2ggaW4gU0VBUkNIRURfQ0xBU1MgYW5kIGl0cyBzdXBlcmNsYXNzZXMgZm9yIGEgbWV0aG9kIG1hdGNoaW5nCiAgIE1FVEhPRF9OQU1FIGFuZCBzaWduYXR1cmUgTUVUSE9EX1NJR05BVFVSRS4gIFRoaXMgZnVuY3Rpb24gd2lsbAogICBvbmx5IHNlYXJjaCBmb3IgbWV0aG9kcyBkZWNsYXJlZCBpbiB0aGUgY2xhc3MgaGllcmFyY2h5OyBpbnRlcmZhY2VzCiAgIHdpbGwgbm90IGJlIGNvbnNpZGVyZWQuICBSZXR1cm5zIE5VTExfVFJFRSBpZiB0aGUgbWV0aG9kIGlzIG5vdAogICBmb3VuZC4gICovCnRyZWUKbG9va3VwX2FyZ3VtZW50X21ldGhvZCAodHJlZSBzZWFyY2hlZF9jbGFzcywgdHJlZSBtZXRob2RfbmFtZSwKCQkJdHJlZSBtZXRob2Rfc2lnbmF0dXJlKQp7CiAgcmV0dXJuIGxvb2t1cF9kbyAoc2VhcmNoZWRfY2xhc3MsIDAsCgkJICAgIG1ldGhvZF9uYW1lLCBtZXRob2Rfc2lnbmF0dXJlLCAKCQkgICAgYnVpbGRfamF2YV9hcmd1bWVudF9zaWduYXR1cmUpOwp9CgovKiBMaWtlIGxvb2t1cF9hcmd1bWVudF9tZXRob2QsIGJ1dCBsZXRzIHRoZSBjYWxsZXIgc2V0IGFueSBmbGFncwogICBkZXNpcmVkLiAgKi8KdHJlZQpsb29rdXBfYXJndW1lbnRfbWV0aG9kX2dlbmVyaWMgKHRyZWUgc2VhcmNoZWRfY2xhc3MsIHRyZWUgbWV0aG9kX25hbWUsCgkJCQl0cmVlIG1ldGhvZF9zaWduYXR1cmUsIGludCBmbGFncykKewogIHJldHVybiBsb29rdXBfZG8gKHNlYXJjaGVkX2NsYXNzLCBmbGFncywKCQkgICAgbWV0aG9kX25hbWUsIG1ldGhvZF9zaWduYXR1cmUsIAoJCSAgICBidWlsZF9qYXZhX2FyZ3VtZW50X3NpZ25hdHVyZSk7Cn0KCgovKiBTZWFyY2ggaW4gY2xhc3MgU0VBUkNIRURfQ0xBU1MgKGFuZCBpdHMgc3VwZXJjbGFzc2VzKSBmb3IgYSBtZXRob2QKICAgbWF0Y2hpbmcgTUVUSE9EX05BTUUgYW5kIHNpZ25hdHVyZSBNRVRIT0RfU0lHTkFUVVJFLiAgUmV0dXJuIGEKICAgRlVOQ1RJT05fREVDTCBvbiBzdWNjZXNzLCBvciBOVUxMX1RSRUUgaWYgbm9uZSBmb3VuZC4gIChDb250cmFzdAogICBsb29rdXBfYXJndW1lbnRfbWV0aG9kLCB3aGljaCBpZ25vcmVzIHJldHVybiB0eXBlLikgIElmCiAgIFNFQVJDSEVEX0NMQVNTIGlzIGFuIGludGVyZmFjZSwgc2VhcmNoIGl0IHRvby4gKi8KdHJlZQpsb29rdXBfamF2YV9tZXRob2QgKHRyZWUgc2VhcmNoZWRfY2xhc3MsIHRyZWUgbWV0aG9kX25hbWUsCgkJICAgIHRyZWUgbWV0aG9kX3NpZ25hdHVyZSkKewogIHJldHVybiBsb29rdXBfZG8gKHNlYXJjaGVkX2NsYXNzLCBTRUFSQ0hfSU5URVJGQUNFLCBtZXRob2RfbmFtZSwgCgkJICAgIG1ldGhvZF9zaWduYXR1cmUsIGJ1aWxkX2phdmFfc2lnbmF0dXJlKTsKfQoKLyogUmV0dXJuIHRydWUgaWZmIEtMQVNTIChvciBpdHMgYW5jZXN0b3JzKSBoYXMgYSBtZXRob2QgTUVUSE9EX05BTUUuIKAqLwppbnQKaGFzX21ldGhvZCAodHJlZSBrbGFzcywgdHJlZSBtZXRob2RfbmFtZSkKewogIHJldHVybiBsb29rdXBfZG8gKGtsYXNzLCBTRUFSQ0hfSU5URVJGQUNFLAoJCSAgICBtZXRob2RfbmFtZSwgTlVMTF9UUkVFLAoJCSAgICBidWlsZF9udWxsX3NpZ25hdHVyZSkgIT0gTlVMTF9UUkVFOwp9CgovKiBTZWFyY2ggaW4gY2xhc3MgU0VBUkNIRURfQ0xBU1MsIGJ1dCBub3QgaXRzIHN1cGVyY2xhc3NlcywgZm9yIGEKICAgbWV0aG9kIG1hdGNoaW5nIE1FVEhPRF9OQU1FIGFuZCBzaWduYXR1cmUgU0lHTkFUVVJFLiAgQSBwcml2YXRlCiAgIGhlbHBlciBmb3IgbG9va3VwX2RvLiAgKi8Kc3RhdGljIHRyZWUKc2hhbGxvd19maW5kX21ldGhvZCAodHJlZSBzZWFyY2hlZF9jbGFzcywgaW50IGZsYWdzLCB0cmVlIG1ldGhvZF9uYW1lLCAKCSAgICAgdHJlZSBzaWduYXR1cmUsIHRyZWUgKCpzaWduYXR1cmVfYnVpbGRlcikgKHRyZWUpKQp7CiAgdHJlZSBtZXRob2Q7CiAgZm9yIChtZXRob2QgPSBUWVBFX01FVEhPRFMgKHNlYXJjaGVkX2NsYXNzKTsKICAgICAgIG1ldGhvZCAhPSBOVUxMX1RSRUU7ICBtZXRob2QgPSBUUkVFX0NIQUlOIChtZXRob2QpKQogICAgewogICAgICB0cmVlIG1ldGhvZF9zaWcgPSAoKnNpZ25hdHVyZV9idWlsZGVyKSAoVFJFRV9UWVBFIChtZXRob2QpKTsKICAgICAgaWYgKERFQ0xfTkFNRSAobWV0aG9kKSA9PSBtZXRob2RfbmFtZSAmJiBtZXRob2Rfc2lnID09IHNpZ25hdHVyZSkKCXsKCSAgLyogSWYgdGhlIGNhbGxlciByZXF1aXJlcyBhIHZpc2libGUgbWV0aG9kLCB0aGVuIHdlCgkgICAgIHNraXAgaW52aXNpYmxlIG1ldGhvZHMgaGVyZS4gICovCgkgIGlmICghIChmbGFncyAmIFNFQVJDSF9WSVNJQkxFKQoJICAgICAgfHwgISBNRVRIT0RfSU5WSVNJQkxFIChtZXRob2QpKQoJICAgIHJldHVybiBtZXRob2Q7Cgl9CiAgICB9CiAgcmV0dXJuIE5VTExfVFJFRTsKfQoKLyogU2VhcmNoIGluIHRoZSBzdXBlcmNsYXNzZXMgb2YgU0VBUkNIRURfQ0xBU1MgZm9yIGEgbWV0aG9kIG1hdGNoaW5nCiAgIE1FVEhPRF9OQU1FIGFuZCBzaWduYXR1cmUgU0lHTkFUVVJFLiAgQSBwcml2YXRlIGhlbHBlciBmb3IKICAgbG9va3VwX2RvLiAgKi8Kc3RhdGljIHRyZWUKZmluZF9tZXRob2RfaW5fc3VwZXJjbGFzc2VzICh0cmVlIHNlYXJjaGVkX2NsYXNzLCBpbnQgZmxhZ3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUgbWV0aG9kX25hbWUsIHRyZWUgc2lnbmF0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUgKCpzaWduYXR1cmVfYnVpbGRlcikgKHRyZWUpKQp7CiAgdHJlZSBrbGFzczsKICBmb3IgKGtsYXNzID0gQ0xBU1NUWVBFX1NVUEVSIChzZWFyY2hlZF9jbGFzcyk7IGtsYXNzICE9IE5VTExfVFJFRTsKICAgICAgIGtsYXNzID0gQ0xBU1NUWVBFX1NVUEVSIChrbGFzcykpCiAgICB7CiAgICAgIHRyZWUgbWV0aG9kOwogICAgICBtZXRob2QgPSBzaGFsbG93X2ZpbmRfbWV0aG9kIChrbGFzcywgZmxhZ3MsIG1ldGhvZF9uYW1lLCAKCQkJCSAgICBzaWduYXR1cmUsIHNpZ25hdHVyZV9idWlsZGVyKTsKICAgICAgaWYgKG1ldGhvZCAhPSBOVUxMX1RSRUUpCglyZXR1cm4gbWV0aG9kOwogICAgfQoKICByZXR1cm4gTlVMTF9UUkVFOwp9CgovKiBTZWFyY2ggaW4gdGhlIGludGVyZmFjZXMgb2YgU0VBUkNIRURfQ0xBU1MgYW5kIGl0cyBzdXBlcmludGVyZmFjZXMKICAgZm9yIGEgbWV0aG9kIG1hdGNoaW5nIE1FVEhPRF9OQU1FIGFuZCBzaWduYXR1cmUgU0lHTkFUVVJFLiAgQQogICBwcml2YXRlIGhlbHBlciBmb3IgbG9va3VwX2RvLiAgKi8Kc3RhdGljIHRyZWUKZmluZF9tZXRob2RfaW5faW50ZXJmYWNlcyAodHJlZSBzZWFyY2hlZF9jbGFzcywgaW50IGZsYWdzLCB0cmVlIG1ldGhvZF9uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlIHNpZ25hdHVyZSwgdHJlZSAoKnNpZ25hdHVyZV9idWlsZGVyKSAodHJlZSkpCnsKICBpbnQgaTsKICB0cmVlIGJpbmZvLCBiYXNlX2JpbmZvOwoKICBmb3IgKGJpbmZvID0gVFlQRV9CSU5GTyAoc2VhcmNoZWRfY2xhc3MpLCBpID0gMTsKICAgICAgIEJJTkZPX0JBU0VfSVRFUkFURSAoYmluZm8sIGksIGJhc2VfYmluZm8pOyBpKyspCiAgICB7CiAgICAgIHRyZWUgaWNsYXNzID0gQklORk9fVFlQRSAoYmFzZV9iaW5mbyk7CiAgICAgIHRyZWUgbWV0aG9kOwoJICAKICAgICAgLyogSWYgdGhlIHN1cGVyaW50ZXJmYWNlIGhhc24ndCBiZWVuIGxvYWRlZCB5ZXQsIGRvIHNvIG5vdy4gICovCiAgICAgIGlmICghQ0xBU1NfTE9BREVEX1AgKGljbGFzcykpCglsb2FkX2NsYXNzIChpY2xhc3MsIDEpOwoJICAKICAgICAgLyogRmlyc3QsIHdlIGxvb2sgaW4gSUNMQVNTLiAgSWYgdGhhdCBkb2Vzbid0IHdvcmsgd2UnbGwKCSByZWN1cnNpdmVseSBsb29rIHRocm91Z2ggYWxsIGl0cyBzdXBlcmludGVyZmFjZXMuICAqLwogICAgICBtZXRob2QgPSBzaGFsbG93X2ZpbmRfbWV0aG9kIChpY2xhc3MsIGZsYWdzLCBtZXRob2RfbmFtZSwgCgkJCQkgICAgc2lnbmF0dXJlLCBzaWduYXR1cmVfYnVpbGRlcik7ICAgICAgCiAgICAgIGlmIChtZXRob2QgIT0gTlVMTF9UUkVFKQoJcmV0dXJuIG1ldGhvZDsKICAKICAgICAgbWV0aG9kID0gZmluZF9tZXRob2RfaW5faW50ZXJmYWNlcyAKCShpY2xhc3MsIGZsYWdzLCBtZXRob2RfbmFtZSwgc2lnbmF0dXJlLCBzaWduYXR1cmVfYnVpbGRlcik7CiAgICAgIGlmIChtZXRob2QgIT0gTlVMTF9UUkVFKQoJcmV0dXJuIG1ldGhvZDsKICAgIH0KICAKICByZXR1cm4gTlVMTF9UUkVFOwp9CgoKLyogU2VhcmNoIGluIGNsYXNzIFNFQVJDSEVEX0NMQVNTIChhbmQgaXRzIHN1cGVyY2xhc3NlcykgZm9yIGEgbWV0aG9kCiAgIG1hdGNoaW5nIE1FVEhPRF9OQU1FIGFuZCBzaWduYXR1cmUgU0lHTkFUVVJFLiAgRkxBR1MgY29udHJvbCBzb21lCiAgIHBhcmFtZXRlcnMgb2YgdGhlIHNlYXJjaC4KICAgCiAgIFNFQVJDSF9JTlRFUkZBQ0UgbWVhbnMgYWxzbyBzZWFyY2ggaW50ZXJmYWNlcyBhbmQgc3VwZXJpbnRlcmZhY2VzCiAgIG9mIFNFQVJDSEVEX0NMQVNTLgogICAKICAgU0VBUkNIX1NVUEVSIG1lYW5zIHNraXAgU0VBUkNIRURfQ0xBU1MgYW5kIHN0YXJ0IHdpdGggaXRzCiAgIHN1cGVyY2xhc3MuCiAgIAogICBTRUFSQ0hfVklTSUJMRSBtZWFucyBza2lwIG1ldGhvZHMgZm9yIHdoaWNoIE1FVEhPRF9JTlZJU0lCTEUgaXMKICAgc2V0LgoKICAgUmV0dXJuIHRoZSBtYXRjaGVkIG1ldGhvZCBERUNMIG9yIE5VTExfVFJFRS4gIFNJR05BVFVSRV9CVUlMREVSIGlzCiAgIHVzZWQgb24gbWV0aG9kIGNhbmRpZGF0ZXMgdG8gYnVpbGQgdGhlaXIgKHNvbWV0aW1lcyBwYXJ0aWFsKQogICBzaWduYXR1cmUuICAqLwpzdGF0aWMgdHJlZQpsb29rdXBfZG8gKHRyZWUgc2VhcmNoZWRfY2xhc3MsIGludCBmbGFncywgdHJlZSBtZXRob2RfbmFtZSwKCSAgIHRyZWUgc2lnbmF0dXJlLCB0cmVlICgqc2lnbmF0dXJlX2J1aWxkZXIpICh0cmVlKSkKewogIHRyZWUgbWV0aG9kOwogIHRyZWUgb3JpZ19jbGFzcyA9IHNlYXJjaGVkX2NsYXNzOwogICAgCiAgaWYgKHNlYXJjaGVkX2NsYXNzID09IE5VTExfVFJFRSkKICAgIHJldHVybiBOVUxMX1RSRUU7CgogIGlmIChmbGFncyAmIFNFQVJDSF9TVVBFUikKICAgIHsKICAgICAgc2VhcmNoZWRfY2xhc3MgPSBDTEFTU1RZUEVfU1VQRVIgKHNlYXJjaGVkX2NsYXNzKTsKICAgICAgaWYgKHNlYXJjaGVkX2NsYXNzID09IE5VTExfVFJFRSkKCXJldHVybiBOVUxMX1RSRUU7CiAgICB9CgogIC8qIEZpcnN0IGxvb2sgaW4gb3VyIG93biBtZXRob2RzLiAgKi8KICBtZXRob2QgPSBzaGFsbG93X2ZpbmRfbWV0aG9kIChzZWFyY2hlZF9jbGFzcywgZmxhZ3MsIG1ldGhvZF9uYW1lLAoJCQkJc2lnbmF0dXJlLCBzaWduYXR1cmVfYnVpbGRlcik7ICAKICBpZiAobWV0aG9kKQogICAgcmV0dXJuIG1ldGhvZDsKCiAgLyogVGhlbiBsb29rIGluIG91ciBzdXBlcmNsYXNzZXMuICAqLwogIGlmICghIENMQVNTX0lOVEVSRkFDRSAoVFlQRV9OQU1FIChzZWFyY2hlZF9jbGFzcykpKQogICAgbWV0aG9kID0gZmluZF9tZXRob2RfaW5fc3VwZXJjbGFzc2VzIChzZWFyY2hlZF9jbGFzcywgZmxhZ3MsIG1ldGhvZF9uYW1lLAoJCQkJCSAgc2lnbmF0dXJlLCBzaWduYXR1cmVfYnVpbGRlcik7ICAKICBpZiAobWV0aG9kKQogICAgcmV0dXJuIG1ldGhvZDsKICAKICAvKiBJZiB0aGF0IGRvZXNuJ3Qgd29yaywgbG9vayBpbiBvdXIgaW50ZXJmYWNlcy4gICovCiAgaWYgKGZsYWdzICYgU0VBUkNIX0lOVEVSRkFDRSkKICAgIG1ldGhvZCA9IGZpbmRfbWV0aG9kX2luX2ludGVyZmFjZXMgKG9yaWdfY2xhc3MsIGZsYWdzLCBtZXRob2RfbmFtZSwgCgkJCQkJc2lnbmF0dXJlLCBzaWduYXR1cmVfYnVpbGRlcik7CiAgCiAgcmV0dXJuIG1ldGhvZDsKfQoKLyogU2VhcmNoIGluIGNsYXNzIENMQVMgZm9yIGEgY29uc3RydWN0b3IgbWF0Y2hpbmcgTUVUSE9EX1NJR05BVFVSRS4KICAgUmV0dXJuIGEgRlVOQ1RJT05fREVDTCBvbiBzdWNjZXNzLCBvciBOVUxMX1RSRUUgaWYgbm9uZSBmb3VuZC4gKi8KCnRyZWUKbG9va3VwX2phdmFfY29uc3RydWN0b3IgKHRyZWUgY2xhcywgdHJlZSBtZXRob2Rfc2lnbmF0dXJlKQp7CiAgdHJlZSBtZXRob2QgPSBUWVBFX01FVEhPRFMgKGNsYXMpOwogIGZvciAoIDsgbWV0aG9kICE9IE5VTExfVFJFRTsgIG1ldGhvZCA9IFRSRUVfQ0hBSU4gKG1ldGhvZCkpCiAgICB7CiAgICAgIHRyZWUgbWV0aG9kX3NpZyA9IGJ1aWxkX2phdmFfc2lnbmF0dXJlIChUUkVFX1RZUEUgKG1ldGhvZCkpOwogICAgICBpZiAoREVDTF9DT05TVFJVQ1RPUl9QIChtZXRob2QpICYmIG1ldGhvZF9zaWcgPT0gbWV0aG9kX3NpZ25hdHVyZSkKCXJldHVybiBtZXRob2Q7CiAgICB9CiAgcmV0dXJuIE5VTExfVFJFRTsKfQoKLyogUmV0dXJuIGEgdHlwZSB3aGljaCBpcyB0aGUgQmluYXJ5IE51bWVyaWMgUHJvbW90aW9uIG9mIHRoZSBwYWlyIFQxLAogICBUMiBhbmQgY29udmVydCBFWFAxIGFuZC9vciBFWFAyLiBTZWUgNS42LjIgQmluYXJ5IE51bWVyaWMKICAgUHJvbW90aW9uLiBJdCBhc3N1bWVzIHRoYXQgYm90aCBUMSBhbmQgVDIgYXJlIGVsaWdpYmxlIHRvIEJOUC4gKi8KCnRyZWUKYmluYXJ5X251bWVyaWNfcHJvbW90aW9uICh0cmVlIHQxLCB0cmVlIHQyLCB0cmVlICpleHAxLCB0cmVlICpleHAyKQp7CiAgaWYgKHQxID09IGRvdWJsZV90eXBlX25vZGUgfHwgdDIgPT0gZG91YmxlX3R5cGVfbm9kZSkKICAgIHsKICAgICAgaWYgKHQxICE9IGRvdWJsZV90eXBlX25vZGUpCgkqZXhwMSA9IGNvbnZlcnQgKGRvdWJsZV90eXBlX25vZGUsICpleHAxKTsKICAgICAgaWYgKHQyICE9IGRvdWJsZV90eXBlX25vZGUpCgkqZXhwMiA9IGNvbnZlcnQgKGRvdWJsZV90eXBlX25vZGUsICpleHAyKTsKICAgICAgcmV0dXJuIGRvdWJsZV90eXBlX25vZGU7CiAgICB9CiAgaWYgKHQxID09IGZsb2F0X3R5cGVfbm9kZSB8fCB0MiA9PSBmbG9hdF90eXBlX25vZGUpCiAgICB7CiAgICAgIGlmICh0MSAhPSBmbG9hdF90eXBlX25vZGUpCgkqZXhwMSA9IGNvbnZlcnQgKGZsb2F0X3R5cGVfbm9kZSwgKmV4cDEpOwogICAgICBpZiAodDIgIT0gZmxvYXRfdHlwZV9ub2RlKQoJKmV4cDIgPSBjb252ZXJ0IChmbG9hdF90eXBlX25vZGUsICpleHAyKTsKICAgICAgcmV0dXJuIGZsb2F0X3R5cGVfbm9kZTsKICAgIH0KICBpZiAodDEgPT0gbG9uZ190eXBlX25vZGUgfHwgdDIgPT0gbG9uZ190eXBlX25vZGUpCiAgICB7CiAgICAgIGlmICh0MSAhPSBsb25nX3R5cGVfbm9kZSkKCSpleHAxID0gY29udmVydCAobG9uZ190eXBlX25vZGUsICpleHAxKTsKICAgICAgaWYgKHQyICE9IGxvbmdfdHlwZV9ub2RlKQoJKmV4cDIgPSBjb252ZXJ0IChsb25nX3R5cGVfbm9kZSwgKmV4cDIpOwogICAgICByZXR1cm4gbG9uZ190eXBlX25vZGU7CiAgICB9CgogIGlmICh0MSAhPSBpbnRfdHlwZV9ub2RlKQogICAgKmV4cDEgPSBjb252ZXJ0IChpbnRfdHlwZV9ub2RlLCAqZXhwMSk7CiAgaWYgKHQyICE9IGludF90eXBlX25vZGUpCiAgICAqZXhwMiA9IGNvbnZlcnQgKGludF90eXBlX25vZGUsICpleHAyKTsKICByZXR1cm4gaW50X3R5cGVfbm9kZTsKfQo=