LyoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmFsaW5rIFRlY2ggSW5jLgogKiA1Ri4sIE5vLjM2LCBUYWl5dWFuIFN0LiwgSmh1YmVpIENpdHksCiAqIEhzaW5jaHUgQ291bnR5IDMwMiwKICogVGFpd2FuLCBSLk8uQy4KICoKICogKGMpIENvcHlyaWdodCAyMDAyLTIwMDcsIFJhbGluayBUZWNobm9sb2d5LCBJbmMuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5ICAqCiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5ICAqCiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yICAgICAqCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCAgICAgICAqCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mICAgICAgICAqCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgICAgICAgICAqCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlICAgICAqCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNywgVVNBLiAgICAgICAgICAgICAqCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgoJTW9kdWxlIE5hbWU6CgllZXByb20uYwoKCUFic3RyYWN0OgoKCVJldmlzaW9uIEhpc3Rvcnk6CglXaG8JCQlXaGVuCQkJV2hhdAoJLS0tLS0tLS0JLS0tLS0tLS0tLQkJLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJTmFtZQkJRGF0ZQkJCU1vZGlmaWNhdGlvbiBsb2dzCiovCiNpbmNsdWRlCSIuLi9ydF9jb25maWcuaCIKCi8vIElSUUwgPSBQQVNTSVZFX0xFVkVMClZPSUQgUmFpc2VDbG9jaygKICAgIElOCVBSVE1QX0FEQVBURVIJcEFkLAogICAgSU4gIFVJTlQzMiAqeCkKewogICAgKnggPSAqeCB8IEVFU0s7CiAgICBSVE1QX0lPX1dSSVRFMzIocEFkLCBFMlBST01fQ1NSLCAqeCk7CiAgICBSVE1QdXNlY0RlbGF5KDEpOwkJCQkvLyBNYXggZnJlcXVlbmN5ID0gMU1IeiBpbiBTcGVjLiBkZWZpbml0aW9uCn0KCi8vIElSUUwgPSBQQVNTSVZFX0xFVkVMClZPSUQgTG93ZXJDbG9jaygKICAgIElOCVBSVE1QX0FEQVBURVIJcEFkLAogICAgSU4gIFVJTlQzMiAqeCkKewogICAgKnggPSAqeCAmIH5FRVNLOwogICAgUlRNUF9JT19XUklURTMyKHBBZCwgRTJQUk9NX0NTUiwgKngpOwogICAgUlRNUHVzZWNEZWxheSgxKTsKfQoKLy8gSVJRTCA9IFBBU1NJVkVfTEVWRUwKVVNIT1JUIFNoaWZ0SW5CaXRzKAogICAgSU4JUFJUTVBfQURBUFRFUglwQWQpCnsKICAgIFVJTlQzMgkJeCxpOwoJVVNIT1JUICAgICAgZGF0YT0wOwoKICAgIFJUTVBfSU9fUkVBRDMyKHBBZCwgRTJQUk9NX0NTUiwgJngpOwoKICAgIHggJj0gfiggRUVETyB8IEVFREkpOwoKICAgIGZvcihpPTA7IGk8MTY7IGkrKykKICAgIHsKICAgICAgICBkYXRhID0gZGF0YSA8PCAxOwogICAgICAgIFJhaXNlQ2xvY2socEFkLCAmeCk7CgogICAgICAgIFJUTVBfSU9fUkVBRDMyKHBBZCwgRTJQUk9NX0NTUiwgJngpOwoJCUxvd2VyQ2xvY2socEFkLCAmeCk7IC8vcHJldmVudCByZWFkIGZhaWxlZAoKICAgICAgICB4ICY9IH4oRUVESSk7CiAgICAgICAgaWYoeCAmIEVFRE8pCiAgICAgICAgICAgIGRhdGEgfD0gMTsKICAgIH0KCiAgICByZXR1cm4gZGF0YTsKfQoKLy8gSVJRTCA9IFBBU1NJVkVfTEVWRUwKVk9JRCBTaGlmdE91dEJpdHMoCiAgICBJTglQUlRNUF9BREFQVEVSCXBBZCwKICAgIElOICBVU0hPUlQgZGF0YSwKICAgIElOICBVU0hPUlQgY291bnQpCnsKICAgIFVJTlQzMiAgICAgICB4LG1hc2s7CgogICAgbWFzayA9IDB4MDEgPDwgKGNvdW50IC0gMSk7CiAgICBSVE1QX0lPX1JFQUQzMihwQWQsIEUyUFJPTV9DU1IsICZ4KTsKCiAgICB4ICY9IH4oRUVETyB8IEVFREkpOwoKICAgIGRvCiAgICB7CiAgICAgICAgeCAmPSB+RUVESTsKICAgICAgICBpZihkYXRhICYgbWFzaykJCXggfD0gRUVESTsKCiAgICAgICAgUlRNUF9JT19XUklURTMyKHBBZCwgRTJQUk9NX0NTUiwgeCk7CgogICAgICAgIFJhaXNlQ2xvY2socEFkLCAmeCk7CiAgICAgICAgTG93ZXJDbG9jayhwQWQsICZ4KTsKCiAgICAgICAgbWFzayA9IG1hc2sgPj4gMTsKICAgIH0gd2hpbGUobWFzayk7CgogICAgeCAmPSB+RUVESTsKICAgIFJUTVBfSU9fV1JJVEUzMihwQWQsIEUyUFJPTV9DU1IsIHgpOwp9CgovLyBJUlFMID0gUEFTU0lWRV9MRVZFTApWT0lEIEVFcHJvbUNsZWFudXAoCiAgICBJTglQUlRNUF9BREFQVEVSCXBBZCkKewogICAgVUlOVDMyIHg7CgogICAgUlRNUF9JT19SRUFEMzIocEFkLCBFMlBST01fQ1NSLCAmeCk7CgogICAgeCAmPSB+KEVFQ1MgfCBFRURJKTsKICAgIFJUTVBfSU9fV1JJVEUzMihwQWQsIEUyUFJPTV9DU1IsIHgpOwoKICAgIFJhaXNlQ2xvY2socEFkLCAmeCk7CiAgICBMb3dlckNsb2NrKHBBZCwgJngpOwp9CgpWT0lEIEVXRU4oCglJTglQUlRNUF9BREFQVEVSCXBBZCkKewogICAgVUlOVDMyCXg7CgogICAgLy8gcmVzZXQgYml0cyBhbmQgc2V0IEVFQ1MKICAgIFJUTVBfSU9fUkVBRDMyKHBBZCwgRTJQUk9NX0NTUiwgJngpOwogICAgeCAmPSB+KEVFREkgfCBFRURPIHwgRUVTSyk7CiAgICB4IHw9IEVFQ1M7CiAgICBSVE1QX0lPX1dSSVRFMzIocEFkLCBFMlBST01fQ1NSLCB4KTsKCgkvLyBraWNrIGEgcHVsc2UKCVJhaXNlQ2xvY2socEFkLCAmeCk7CglMb3dlckNsb2NrKHBBZCwgJngpOwoKICAgIC8vIG91dHB1dCB0aGUgcmVhZF9vcGNvZGUgYW5kIHNpeCBwdWxzZSBpbiB0aGF0IG9yZGVyCiAgICBTaGlmdE91dEJpdHMocEFkLCBFRVBST01fRVdFTl9PUENPREUsIDUpOwogICAgU2hpZnRPdXRCaXRzKHBBZCwgMCwgNik7CgogICAgRUVwcm9tQ2xlYW51cChwQWQpOwp9CgpWT0lEIEVXRFMoCglJTglQUlRNUF9BREFQVEVSCXBBZCkKewogICAgVUlOVDMyCXg7CgogICAgLy8gcmVzZXQgYml0cyBhbmQgc2V0IEVFQ1MKICAgIFJUTVBfSU9fUkVBRDMyKHBBZCwgRTJQUk9NX0NTUiwgJngpOwogICAgeCAmPSB+KEVFREkgfCBFRURPIHwgRUVTSyk7CiAgICB4IHw9IEVFQ1M7CiAgICBSVE1QX0lPX1dSSVRFMzIocEFkLCBFMlBST01fQ1NSLCB4KTsKCgkvLyBraWNrIGEgcHVsc2UKCVJhaXNlQ2xvY2socEFkLCAmeCk7CglMb3dlckNsb2NrKHBBZCwgJngpOwoKICAgIC8vIG91dHB1dCB0aGUgcmVhZF9vcGNvZGUgYW5kIHNpeCBwdWxzZSBpbiB0aGF0IG9yZGVyCiAgICBTaGlmdE91dEJpdHMocEFkLCBFRVBST01fRVdEU19PUENPREUsIDUpOwogICAgU2hpZnRPdXRCaXRzKHBBZCwgMCwgNik7CgogICAgRUVwcm9tQ2xlYW51cChwQWQpOwp9CgovLyBJUlFMID0gUEFTU0lWRV9MRVZFTApVU0hPUlQgUlRNUF9FRVBST01fUkVBRDE2KAogICAgSU4JUFJUTVBfQURBUFRFUglwQWQsCiAgICBJTiAgVVNIT1JUIE9mZnNldCkKewogICAgVUlOVDMyCQl4OwogICAgVVNIT1JUCQlkYXRhOwoKCWlmIChwQWQtPk5pY0NvbmZpZzIuZmllbGQuQW50RGl2ZXJzaXR5KQogICAgewogICAgCXBBZC0+RWVwcm9tQWNjZXNzID0gVFJVRTsKICAgIH0KLy8yMDA4LzA5LzExOktIIGFkZCB0byBzdXBwb3J0IGVmdXNlPC0tCi8vMjAwOC8wOS8xMTpLSCBhZGQgdG8gc3VwcG9ydCBlZnVzZS0tPgp7CiAgICBPZmZzZXQgLz0gMjsKICAgIC8vIHJlc2V0IGJpdHMgYW5kIHNldCBFRUNTCiAgICBSVE1QX0lPX1JFQUQzMihwQWQsIEUyUFJPTV9DU1IsICZ4KTsKICAgIHggJj0gfihFRURJIHwgRUVETyB8IEVFU0spOwogICAgeCB8PSBFRUNTOwogICAgUlRNUF9JT19XUklURTMyKHBBZCwgRTJQUk9NX0NTUiwgeCk7CgoJLy8gcGF0Y2ggY2FuIG5vdCBhY2Nlc3MgZS1GdXNlIGlzc3VlCiAgICBpZiAoIUlTX1JUMzA5MChwQWQpKQogICAgewoJLy8ga2ljayBhIHB1bHNlCglSYWlzZUNsb2NrKHBBZCwgJngpOwoJTG93ZXJDbG9jayhwQWQsICZ4KTsKICAgIH0KCiAgICAvLyBvdXRwdXQgdGhlIHJlYWRfb3Bjb2RlIGFuZCByZWdpc3RlciBudW1iZXIgaW4gdGhhdCBvcmRlcgogICAgU2hpZnRPdXRCaXRzKHBBZCwgRUVQUk9NX1JFQURfT1BDT0RFLCAzKTsKICAgIFNoaWZ0T3V0Qml0cyhwQWQsIE9mZnNldCwgcEFkLT5FRVBST01BZGRyZXNzTnVtKTsKCiAgICAvLyBOb3cgcmVhZCB0aGUgZGF0YSAoMTYgYml0cykgaW4gZnJvbSB0aGUgc2VsZWN0ZWQgRUVQUk9NIHdvcmQKICAgIGRhdGEgPSBTaGlmdEluQml0cyhwQWQpOwoKICAgIEVFcHJvbUNsZWFudXAocEFkKTsKCgkvLyBBbnRlbm5hIGFuZCBFRVBST00gYWNjZXNzIGFyZSBib3RoIHVzaW5nIEVFU0sgcGluLAogICAgLy8gVGhlcmVmb3Igd2Ugc2hvdWxkIGF2b2lkIGFjY2Vzc2luZyBFRVNLIGF0IHRoZSBzYW1lIHRpbWUKICAgIC8vIFRoZW4gcmVzdG9yZSBhbnRlbm5hIGFmdGVyIEVFUFJPTSBhY2Nlc3MKCWlmICgocEFkLT5OaWNDb25maWcyLmZpZWxkLkFudERpdmVyc2l0eSkgfHwgKHBBZC0+UmZJY1R5cGUgPT0gUkZJQ18zMDIwKSkKICAgIHsKCSAgICBwQWQtPkVlcHJvbUFjY2VzcyA9IEZBTFNFOwoJICAgIEFzaWNTZXRSeEFudChwQWQsIHBBZC0+UnhBbnQuUGFpcjFQcmltYXJ5UnhBbnQpOwogICAgfQp9CiAgICByZXR1cm4gZGF0YTsKfQkvL1JlYWRFRXByb20KClZPSUQgUlRNUF9FRVBST01fV1JJVEUxNigKICAgIElOCVBSVE1QX0FEQVBURVIJcEFkLAogICAgSU4gIFVTSE9SVCBPZmZzZXQsCiAgICBJTiAgVVNIT1JUIERhdGEpCnsKICAgIFVJTlQzMiB4OwoKCWlmIChwQWQtPk5pY0NvbmZpZzIuZmllbGQuQW50RGl2ZXJzaXR5KQogICAgewogICAgCXBBZC0+RWVwcm9tQWNjZXNzID0gVFJVRTsKICAgIH0KCS8vMjAwOC8wOS8xMTpLSCBhZGQgdG8gc3VwcG9ydCBlZnVzZTwtLQovLzIwMDgvMDkvMTE6S0ggYWRkIHRvIHN1cHBvcnQgZWZ1c2UtLT4KCXsKCU9mZnNldCAvPSAyOwoKCUVXRU4ocEFkKTsKCiAgICAvLyByZXNldCBiaXRzIGFuZCBzZXQgRUVDUwogICAgUlRNUF9JT19SRUFEMzIocEFkLCBFMlBST01fQ1NSLCAmeCk7CiAgICB4ICY9IH4oRUVESSB8IEVFRE8gfCBFRVNLKTsKICAgIHggfD0gRUVDUzsKICAgIFJUTVBfSU9fV1JJVEUzMihwQWQsIEUyUFJPTV9DU1IsIHgpOwoKCS8vIHBhdGNoIGNhbiBub3QgYWNjZXNzIGUtRnVzZSBpc3N1ZQogICAgaWYgKCFJU19SVDMwOTAocEFkKSkKICAgIHsKCS8vIGtpY2sgYSBwdWxzZQoJUmFpc2VDbG9jayhwQWQsICZ4KTsKCUxvd2VyQ2xvY2socEFkLCAmeCk7CiAgICB9CgogICAgLy8gb3V0cHV0IHRoZSByZWFkX29wY29kZSAscmVnaXN0ZXIgbnVtYmVyIGFuZCBkYXRhIGluIHRoYXQgb3JkZXIKICAgIFNoaWZ0T3V0Qml0cyhwQWQsIEVFUFJPTV9XUklURV9PUENPREUsIDMpOwogICAgU2hpZnRPdXRCaXRzKHBBZCwgT2Zmc2V0LCBwQWQtPkVFUFJPTUFkZHJlc3NOdW0pOwoJU2hpZnRPdXRCaXRzKHBBZCwgRGF0YSwgMTYpOwkJLy8gMTYtYml0IGFjY2VzcwoKICAgIC8vIHJlYWQgRE8gc3RhdHVzCiAgICBSVE1QX0lPX1JFQUQzMihwQWQsIEUyUFJPTV9DU1IsICZ4KTsKCglFRXByb21DbGVhbnVwKHBBZCk7CgoJUlRNUHVzZWNEZWxheSgxMDAwMCk7CS8vZGVsYXkgZm9yIHR3cChNQVgpPTEwbXMKCglFV0RTKHBBZCk7CgogICAgRUVwcm9tQ2xlYW51cChwQWQpOwoKCS8vIEFudGVubmEgYW5kIEVFUFJPTSBhY2Nlc3MgYXJlIGJvdGggdXNpbmcgRUVTSyBwaW4sCiAgICAvLyBUaGVyZWZvciB3ZSBzaG91bGQgYXZvaWQgYWNjZXNzaW5nIEVFU0sgYXQgdGhlIHNhbWUgdGltZQogICAgLy8gVGhlbiByZXN0b3JlIGFudGVubmEgYWZ0ZXIgRUVQUk9NIGFjY2VzcwoJaWYgKChwQWQtPk5pY0NvbmZpZzIuZmllbGQuQW50RGl2ZXJzaXR5KSB8fCAocEFkLT5SZkljVHlwZSA9PSBSRklDXzMwMjApKQogICAgewoJICAgIHBBZC0+RWVwcm9tQWNjZXNzID0gRkFMU0U7CgkgICAgQXNpY1NldFJ4QW50KHBBZCwgcEFkLT5SeEFudC5QYWlyMVByaW1hcnlSeEFudCk7CiAgICB9Cn0KfQoKLy8yMDA4LzA5LzExOktIIGFkZCB0byBzdXBwb3J0IGVmdXNlPC0tCiNpZmRlZiBSVDMweHgKLyoKCT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKCVJvdXRpbmUgRGVzY3JpcHRpb246CgoJQXJndW1lbnRzOgoKCVJldHVybiBWYWx1ZToKCglJUlFMID0KCglOb3RlOgoKCT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoqLwpVQ0hBUiBlRnVzZVJlYWRSZWdpc3RlcnMoCglJTglQUlRNUF9BREFQVEVSCXBBZCwKCUlOCVVTSE9SVCBPZmZzZXQsCglJTglVU0hPUlQgTGVuZ3RoLAoJT1VUCVVTSE9SVCogcERhdGEpCnsKCUVGVVNFX0NUUkxfU1RSVUMJCWVGdXNlQ3RybFN0cnVjOwoJaW50CWk7CglVU0hPUlQJZWZ1c2VEYXRhT2Zmc2V0OwoJVUlOVDMyCWRhdGE7CgoJUlRNUF9JT19SRUFEMzIocEFkLCBFRlVTRV9DVFJMLCAoUFVJTlQzMikgJmVGdXNlQ3RybFN0cnVjKTsKCgkvL1N0ZXAwLiBXcml0ZSAxMC1iaXQgb2YgYWRkcmVzcyB0byBFRlNST01fQUlOICgweDU4MCwgYml0MjU6Yml0MTYpLiBUaGUgYWRkcmVzcyBtdXN0IGJlIDE2LWJ5dGUgYWxpZ25tZW50LgoJLy9Vc2UgdGhlIGVlcHJvbSBsb2dpY2FsIGFkZHJlc3MgYW5kIGNvdmVydCB0byBhZGRyZXNzIHRvIGJsb2NrIG51bWJlcgoJZUZ1c2VDdHJsU3RydWMuZmllbGQuRUZTUk9NX0FJTiA9IE9mZnNldCAmIDB4ZmZmMDsKCgkvL1N0ZXAxLiBXcml0ZSBFRlNST01fTU9ERSAoMHg1ODAsIGJpdDc6Yml0NikgdG8gMC4KCWVGdXNlQ3RybFN0cnVjLmZpZWxkLkVGU1JPTV9NT0RFID0gMDsKCgkvL1N0ZXAyLiBXcml0ZSBFRlNST01fS0lDSyAoMHg1ODAsIGJpdDMwKSB0byAxIHRvIGtpY2stb2ZmIHBoeXNpY2FsIHJlYWQgcHJvY2VkdXJlLgoJZUZ1c2VDdHJsU3RydWMuZmllbGQuRUZTUk9NX0tJQ0sgPSAxOwoKCU5kaXNNb3ZlTWVtb3J5KCZkYXRhLCAmZUZ1c2VDdHJsU3RydWMsIDQpOwoJUlRNUF9JT19XUklURTMyKHBBZCwgRUZVU0VfQ1RSTCwgZGF0YSk7CgoJLy9TdGVwMy4gUG9sbGluZyBFRlNST01fS0lDSygweDU4MCwgYml0MzApIHVudGlsIGl0IGJlY29tZSAwIGFnYWluLgoJaSA9IDA7Cgl3aGlsZShpIDwgMTAwKQoJewoJCS8vcnRtcC5Id01lbW9yeVJlYWREd29yZChFRlVTRV9DVFJMLCAoRFdPUkQgKikgJmVGdXNlQ3RybFN0cnVjLCA0KTsKCQlSVE1QX0lPX1JFQUQzMihwQWQsIEVGVVNFX0NUUkwsIChQVUlOVDMyKSAmZUZ1c2VDdHJsU3RydWMpOwoJCWlmKGVGdXNlQ3RybFN0cnVjLmZpZWxkLkVGU1JPTV9LSUNLID09IDApCgkJewoJCQlicmVhazsKCQl9CgkJUlRNUHVzZWNEZWxheSgyKTsKCQlpKys7Cgl9CgoJLy9pZiBFRlNST01fQU9VVCBpcyBub3QgZm91bmQgaW4gcGh5c2ljYWwgYWRkcmVzcywgd3JpdGUgMHhmZmZmCglpZiAoZUZ1c2VDdHJsU3RydWMuZmllbGQuRUZTUk9NX0FPVVQgPT0gMHgzZikKCXsKCQlmb3IoaT0wOyBpPExlbmd0aC8yOyBpKyspCgkJCSoocERhdGErMippKSA9IDB4ZmZmZjsKCX0KCWVsc2UKCXsKCQkvL1N0ZXA0LiBSZWFkIDE2LWJ5dGUgb2YgZGF0YSBmcm9tIEVGVVNFX0RBVEEwLTMgKDB4NTkwLTB4NTlDKQoJCWVmdXNlRGF0YU9mZnNldCA9ICBFRlVTRV9EQVRBMyAtIChPZmZzZXQgJiAweEMpICA7CgkJLy9kYXRhIGhvbGQgNCBieXRlcyBkYXRhLgoJCS8vSW4gUlRNUF9JT19SRUFEMzIgd2lsbCBhdXRvbWF0aWNhbGx5IGV4ZWN1dGUgMzItYnl0ZXMgc3dhcHBpbmcKCQlSVE1QX0lPX1JFQUQzMihwQWQsIGVmdXNlRGF0YU9mZnNldCwgJmRhdGEpOwoJCS8vRGVjaWRlIHRoZSB1cHBlciAyIGJ5dGVzIG9yIHRoZSBib3R0b20gMiBieXRlcy4KCQkvLyBMaXR0bGUtZW5kaWFuCQlTCXwJUwlCaWctZW5kaWFuCgkJLy8gYWRkcgkzCTIJMQkwCXwJMAkxCTIJMwoJCS8vIE9yaS1WCUQJQwlCCUEJfAlBCUIJQwlECgkJLy9BZnRlciBzd2FwcGluZwoJCS8vCQlECUMJQglBCXwJRAlDCUIJQQoJCS8vUmV0dXJuIDItYnl0ZXMKCQkvL1RoZSByZXR1cm4gYnl0ZSBzdGF0cnMgZnJvbSBTLiBUaGVyZWZvcmUsIHRoZSBsaXR0bGUtZW5kaWFuIHdpbGwgcmV0dXJuIEJBLCB0aGUgQmlnLWVuZGlhbiB3aWxsIHJldHVybiBEQy4KCQkvL0ZvciByZXR1cm5pbmcgdGhlIGJvdHRvbSAyIGJ5dGVzLCB0aGUgQmlnLWVuZGlhbiBzaG91bGQgc2hpZnQgcmlnaHQgMi1ieXRlcy4KI2lmZGVmIFJUX0JJR19FTkRJQU4KCQlkYXRhID0gZGF0YSA8PCAoOCooKE9mZnNldCAmIDB4MyleMHgyKSk7CiNlbHNlCgkJZGF0YSA9IGRhdGEgPj4gKDgqKE9mZnNldCAmIDB4MykpOwojZW5kaWYKCgkJTmRpc01vdmVNZW1vcnkocERhdGEsICZkYXRhLCBMZW5ndGgpOwoJfQoKCXJldHVybiAoVUNIQVIpIGVGdXNlQ3RybFN0cnVjLmZpZWxkLkVGU1JPTV9BT1VUOwoKfQoKLyoKCT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKCVJvdXRpbmUgRGVzY3JpcHRpb246CgoJQXJndW1lbnRzOgoKCVJldHVybiBWYWx1ZToKCglJUlFMID0KCglOb3RlOgoKCT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoqLwpWT0lEIGVGdXNlUGh5c2ljYWxSZWFkUmVnaXN0ZXJzKAoJSU4JUFJUTVBfQURBUFRFUglwQWQsCglJTglVU0hPUlQgT2Zmc2V0LAoJSU4JVVNIT1JUIExlbmd0aCwKCU9VVAlVU0hPUlQqIHBEYXRhKQp7CglFRlVTRV9DVFJMX1NUUlVDCQllRnVzZUN0cmxTdHJ1YzsKCWludAlpOwoJVVNIT1JUCWVmdXNlRGF0YU9mZnNldDsKCVVJTlQzMglkYXRhOwoKCVJUTVBfSU9fUkVBRDMyKHBBZCwgRUZVU0VfQ1RSTCwgKFBVSU5UMzIpICZlRnVzZUN0cmxTdHJ1Yyk7CgoJLy9TdGVwMC4gV3JpdGUgMTAtYml0IG9mIGFkZHJlc3MgdG8gRUZTUk9NX0FJTiAoMHg1ODAsIGJpdDI1OmJpdDE2KS4gVGhlIGFkZHJlc3MgbXVzdCBiZSAxNi1ieXRlIGFsaWdubWVudC4KCWVGdXNlQ3RybFN0cnVjLmZpZWxkLkVGU1JPTV9BSU4gPSBPZmZzZXQgJiAweGZmZjA7CgoJLy9TdGVwMS4gV3JpdGUgRUZTUk9NX01PREUgKDB4NTgwLCBiaXQ3OmJpdDYpIHRvIDEuCgkvL1JlYWQgaW4gcGh5c2ljYWwgdmlldwoJZUZ1c2VDdHJsU3RydWMuZmllbGQuRUZTUk9NX01PREUgPSAxOwoKCS8vU3RlcDIuIFdyaXRlIEVGU1JPTV9LSUNLICgweDU4MCwgYml0MzApIHRvIDEgdG8ga2ljay1vZmYgcGh5c2ljYWwgcmVhZCBwcm9jZWR1cmUuCgllRnVzZUN0cmxTdHJ1Yy5maWVsZC5FRlNST01fS0lDSyA9IDE7CgoJTmRpc01vdmVNZW1vcnkoJmRhdGEsICZlRnVzZUN0cmxTdHJ1YywgNCk7CglSVE1QX0lPX1dSSVRFMzIocEFkLCBFRlVTRV9DVFJMLCBkYXRhKTsKCgkvL1N0ZXAzLiBQb2xsaW5nIEVGU1JPTV9LSUNLKDB4NTgwLCBiaXQzMCkgdW50aWwgaXQgYmVjb21lIDAgYWdhaW4uCglpID0gMDsKCXdoaWxlKGkgPCAxMDApCgl7CgkJUlRNUF9JT19SRUFEMzIocEFkLCBFRlVTRV9DVFJMLCAoUFVJTlQzMikgJmVGdXNlQ3RybFN0cnVjKTsKCQlpZihlRnVzZUN0cmxTdHJ1Yy5maWVsZC5FRlNST01fS0lDSyA9PSAwKQoJCQlicmVhazsKCQlSVE1QdXNlY0RlbGF5KDIpOwoJCWkrKzsKCX0KCgkvL1N0ZXA0LiBSZWFkIDE2LWJ5dGUgb2YgZGF0YSBmcm9tIEVGVVNFX0RBVEEwLTMgKDB4NTlDLTB4NTkwKQoJLy9CZWNhdXNlIHRoZSBzaXplIG9mIGVhY2ggRUZVU0VfREFUQSBpcyA0IEJ5dGVzLCB0aGUgc2l6ZSBvZiBhZGRyZXNzIG9mIGVhY2ggaXMgMiBiaXRzLgoJLy9UaGUgcHJldmlvdXMgMiBiaXRzIGlzIHRoZSBFRlVTRV9EQVRBIG51bWJlciwgdGhlIGxhc3QgMiBiaXRzIGlzIHVzZWQgdG8gZGVjaWRlIHdoaWNoIGJ5dGVzCgkvL0RlY2lkZSB3aGljaCBFRlVTRV9EQVRBIHRvIHJlYWQKCS8vNTkwOkYgRSBEIEMKCS8vNTk0OkIgQSA5IDgKCS8vNTk4OjcgNiA1IDQKCS8vNTlDOjMgMiAxIDAKCWVmdXNlRGF0YU9mZnNldCA9ICBFRlVTRV9EQVRBMyAtIChPZmZzZXQgJiAweEMpICA7CgoJUlRNUF9JT19SRUFEMzIocEFkLCBlZnVzZURhdGFPZmZzZXQsICZkYXRhKTsKCiNpZmRlZiBSVF9CSUdfRU5ESUFOCgkJZGF0YSA9IGRhdGEgPDwgKDgqKChPZmZzZXQgJiAweDMpXjB4MikpOwojZWxzZQoJZGF0YSA9IGRhdGEgPj4gKDgqKE9mZnNldCAmIDB4MykpOwojZW5kaWYKCglOZGlzTW92ZU1lbW9yeShwRGF0YSwgJmRhdGEsIExlbmd0aCk7Cgp9CgovKgoJPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgoJUm91dGluZSBEZXNjcmlwdGlvbjoKCglBcmd1bWVudHM6CgoJUmV0dXJuIFZhbHVlOgoKCUlSUUwgPQoKCU5vdGU6CgoJPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiovClZPSUQgZUZ1c2VSZWFkUGh5c2ljYWwoCglJTglQUlRNUF9BREFQVEVSCXBBZCwKICAJSU4JUFVTSE9SVCBscEluQnVmZmVyLAogIAlJTglVTE9ORyBuSW5CdWZmZXJTaXplLAogIAlPVVQJUFVTSE9SVCBscE91dEJ1ZmZlciwKICAJSU4JVUxPTkcgbk91dEJ1ZmZlclNpemUKKQp7CglVU0hPUlQqIHBJbkJ1ZiA9IChVU0hPUlQqKWxwSW5CdWZmZXI7CglVU0hPUlQqIHBPdXRCdWYgPSAoVVNIT1JUKilscE91dEJ1ZmZlcjsKCglVU0hPUlQgT2Zmc2V0ID0gcEluQnVmWzBdOwkJCQkJLy9hZGRyCglVU0hPUlQgTGVuZ3RoID0gcEluQnVmWzFdOwkJCQkJLy9sZW5ndGgKCWludCAJCWk7CgoJZm9yKGk9MDsgaTxMZW5ndGg7IGkrPTIpCgl7CgkJZUZ1c2VQaHlzaWNhbFJlYWRSZWdpc3RlcnMocEFkLE9mZnNldCtpLCAyLCAmcE91dEJ1ZltpLzJdKTsKCX0KfQoKLyoKCT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKCVJvdXRpbmUgRGVzY3JpcHRpb246CgoJQXJndW1lbnRzOgoKCVJldHVybiBWYWx1ZToKCglJUlFMID0KCglOb3RlOgoKCT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoqLwpOVFNUQVRVUyBlRnVzZVJlYWQoCglJTglQUlRNUF9BREFQVEVSCXBBZCwKCUlOCVVTSE9SVAkJCU9mZnNldCwKCU9VVAlQVUNIQVIJCQlwRGF0YSwKCUlOCVVTSE9SVAkJCUxlbmd0aCkKewoJVVNIT1JUKiBwT3V0QnVmID0gKFVTSE9SVCopcERhdGE7CglOVFNUQVRVUwlTdGF0dXMgPSBTVEFUVVNfU1VDQ0VTUzsKCVVDSEFSCUVGU1JPTV9BT1VUOwoJaW50CWk7CgoJZm9yKGk9MDsgaTxMZW5ndGg7IGkrPTIpCgl7CgkJRUZTUk9NX0FPVVQgPSBlRnVzZVJlYWRSZWdpc3RlcnMocEFkLCBPZmZzZXQraSwgMiwgJnBPdXRCdWZbaS8yXSk7Cgl9CglyZXR1cm4gU3RhdHVzOwp9CgovKgoJPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgoJUm91dGluZSBEZXNjcmlwdGlvbjoKCglBcmd1bWVudHM6CgoJUmV0dXJuIFZhbHVlOgoKCUlSUUwgPQoKCU5vdGU6CgoJPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiovClZPSUQgZUZ1c2VQaHlzaWNhbFdyaXRlUmVnaXN0ZXJzKAoJSU4JUFJUTVBfQURBUFRFUglwQWQsCglJTglVU0hPUlQgT2Zmc2V0LAoJSU4JVVNIT1JUIExlbmd0aCwKCU9VVAlVU0hPUlQqIHBEYXRhKQp7CglFRlVTRV9DVFJMX1NUUlVDCQllRnVzZUN0cmxTdHJ1YzsKCWludAlpOwoJVVNIT1JUCWVmdXNlRGF0YU9mZnNldDsKCVVJTlQzMglkYXRhLCBlRnVzZURhdGFCdWZmZXJbNF07CgoJLy9TdGVwMC4gV3JpdGUgMTYtYnl0ZSBvZiBkYXRhIHRvIEVGVVNFX0RBVEEwLTMgKDB4NTkwLTB4NTlDKSwgd2hlcmUgRUZVU0VfREFUQTAgaXMgdGhlIExTQiBEVywgRUZVU0VfREFUQTMgaXMgdGhlIE1TQiBEVy4KCgkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoJLy9yZWFkIGN1cnJlbnQgdmFsdWVzIG9mIDE2LWJ5dGUgYmxvY2sKCVJUTVBfSU9fUkVBRDMyKHBBZCwgRUZVU0VfQ1RSTCwgKFBVSU5UMzIpICZlRnVzZUN0cmxTdHJ1Yyk7CgoJLy9TdGVwMC4gV3JpdGUgMTAtYml0IG9mIGFkZHJlc3MgdG8gRUZTUk9NX0FJTiAoMHg1ODAsIGJpdDI1OmJpdDE2KS4gVGhlIGFkZHJlc3MgbXVzdCBiZSAxNi1ieXRlIGFsaWdubWVudC4KCWVGdXNlQ3RybFN0cnVjLmZpZWxkLkVGU1JPTV9BSU4gPSBPZmZzZXQgJiAweGZmZjA7CgoJLy9TdGVwMS4gV3JpdGUgRUZTUk9NX01PREUgKDB4NTgwLCBiaXQ3OmJpdDYpIHRvIDEuCgllRnVzZUN0cmxTdHJ1Yy5maWVsZC5FRlNST01fTU9ERSA9IDE7CgoJLy9TdGVwMi4gV3JpdGUgRUZTUk9NX0tJQ0sgKDB4NTgwLCBiaXQzMCkgdG8gMSB0byBraWNrLW9mZiBwaHlzaWNhbCByZWFkIHByb2NlZHVyZS4KCWVGdXNlQ3RybFN0cnVjLmZpZWxkLkVGU1JPTV9LSUNLID0gMTsKCglOZGlzTW92ZU1lbW9yeSgmZGF0YSwgJmVGdXNlQ3RybFN0cnVjLCA0KTsKCVJUTVBfSU9fV1JJVEUzMihwQWQsIEVGVVNFX0NUUkwsIGRhdGEpOwoKCS8vU3RlcDMuIFBvbGxpbmcgRUZTUk9NX0tJQ0soMHg1ODAsIGJpdDMwKSB1bnRpbCBpdCBiZWNvbWUgMCBhZ2Fpbi4KCWkgPSAwOwoJd2hpbGUoaSA8IDEwMCkKCXsKCQlSVE1QX0lPX1JFQUQzMihwQWQsIEVGVVNFX0NUUkwsIChQVUlOVDMyKSAmZUZ1c2VDdHJsU3RydWMpOwoKCQlpZihlRnVzZUN0cmxTdHJ1Yy5maWVsZC5FRlNST01fS0lDSyA9PSAwKQoJCQlicmVhazsKCQlSVE1QdXNlY0RlbGF5KDIpOwoJCWkrKzsKCX0KCgkvL1N0ZXA0LiBSZWFkIDE2LWJ5dGUgb2YgZGF0YSBmcm9tIEVGVVNFX0RBVEEwLTMgKDB4NTlDLTB4NTkwKQoJZWZ1c2VEYXRhT2Zmc2V0ID0gIEVGVVNFX0RBVEEzOwoJZm9yKGk9MDsgaTwgNDsgaSsrKQoJewoJCVJUTVBfSU9fUkVBRDMyKHBBZCwgZWZ1c2VEYXRhT2Zmc2V0LCAoUFVJTlQzMikgJmVGdXNlRGF0YUJ1ZmZlcltpXSk7CgkJZWZ1c2VEYXRhT2Zmc2V0IC09ICA0OwoJfQoKCS8vVXBkYXRlIHRoZSB2YWx1ZSwgdGhlIG9mZnNldCBpcyBtdWx0aXBsZSBvZiAyLCBsZW5ndGggaXMgMgoJZWZ1c2VEYXRhT2Zmc2V0ID0gKE9mZnNldCAmIDB4YykgPj4gMjsKCWRhdGEgPSBwRGF0YVswXSAmIDB4ZmZmZjsKCS8vVGhlIG9mZnNldCBzaG91bGQgYmUgMHgqKioxMCBvciAweCoqKjAwCglpZigoT2Zmc2V0ICUgNCkgIT0gMCkKCXsKCQllRnVzZURhdGFCdWZmZXJbZWZ1c2VEYXRhT2Zmc2V0XSA9IChlRnVzZURhdGFCdWZmZXJbZWZ1c2VEYXRhT2Zmc2V0XSAmIDB4ZmZmZikgfCAoZGF0YSA8PCAxNik7Cgl9CgllbHNlCgl7CgkJZUZ1c2VEYXRhQnVmZmVyW2VmdXNlRGF0YU9mZnNldF0gPSAoZUZ1c2VEYXRhQnVmZmVyW2VmdXNlRGF0YU9mZnNldF0gJiAweGZmZmYwMDAwKSB8IGRhdGE7Cgl9CgoJZWZ1c2VEYXRhT2Zmc2V0ID0gIEVGVVNFX0RBVEEzOwoJZm9yKGk9MDsgaTwgNDsgaSsrKQoJewoJCVJUTVBfSU9fV1JJVEUzMihwQWQsIGVmdXNlRGF0YU9mZnNldCwgZUZ1c2VEYXRhQnVmZmVyW2ldKTsKCQllZnVzZURhdGFPZmZzZXQgLT0gNDsKCX0KCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgoJLy9TdGVwMS4gV3JpdGUgMTAtYml0IG9mIGFkZHJlc3MgdG8gRUZTUk9NX0FJTiAoMHg1ODAsIGJpdDI1OmJpdDE2KS4gVGhlIGFkZHJlc3MgbXVzdCBiZSAxNi1ieXRlIGFsaWdubWVudC4KCWVGdXNlQ3RybFN0cnVjLmZpZWxkLkVGU1JPTV9BSU4gPSBPZmZzZXQgJiAweGZmZjA7CgoJLy9TdGVwMi4gV3JpdGUgRUZTUk9NX01PREUgKDB4NTgwLCBiaXQ3OmJpdDYpIHRvIDMuCgllRnVzZUN0cmxTdHJ1Yy5maWVsZC5FRlNST01fTU9ERSA9IDM7CgoJLy9TdGVwMy4gV3JpdGUgRUZTUk9NX0tJQ0sgKDB4NTgwLCBiaXQzMCkgdG8gMSB0byBraWNrLW9mZiBwaHlzaWNhbCB3cml0ZSBwcm9jZWR1cmUuCgllRnVzZUN0cmxTdHJ1Yy5maWVsZC5FRlNST01fS0lDSyA9IDE7CgoJTmRpc01vdmVNZW1vcnkoJmRhdGEsICZlRnVzZUN0cmxTdHJ1YywgNCk7CglSVE1QX0lPX1dSSVRFMzIocEFkLCBFRlVTRV9DVFJMLCBkYXRhKTsKCgkvL1N0ZXA0LiBQb2xsaW5nIEVGU1JPTV9LSUNLKDB4NTgwLCBiaXQzMCkgdW50aWwgaXQgYmVjb21lIDAgYWdhaW4uIEl0oaZzIGRvbmUuCglpID0gMDsKCXdoaWxlKGkgPCAxMDApCgl7CgkJUlRNUF9JT19SRUFEMzIocEFkLCBFRlVTRV9DVFJMLCAoUFVJTlQzMikgJmVGdXNlQ3RybFN0cnVjKTsKCgkJaWYoZUZ1c2VDdHJsU3RydWMuZmllbGQuRUZTUk9NX0tJQ0sgPT0gMCkKCQkJYnJlYWs7CgoJCVJUTVB1c2VjRGVsYXkoMik7CgkJaSsrOwoJfQp9CgovKgoJPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgoJUm91dGluZSBEZXNjcmlwdGlvbjoKCglBcmd1bWVudHM6CgoJUmV0dXJuIFZhbHVlOgoKCUlSUUwgPQoKCU5vdGU6CgoJPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiovCk5UU1RBVFVTIGVGdXNlV3JpdGVSZWdpc3RlcnMoCglJTglQUlRNUF9BREFQVEVSCXBBZCwKCUlOCVVTSE9SVCBPZmZzZXQsCglJTglVU0hPUlQgTGVuZ3RoLAoJSU4JVVNIT1JUKiBwRGF0YSkKewoJVVNIT1JUCWk7CglVU0hPUlQJZUZ1c2VEYXRhOwoJVVNIT1JUCUxvZ2ljYWxBZGRyZXNzLCBCbGtOdW0gPSAweGZmZmY7CglVQ0hBUglFRlNST01fQU9VVDsKCglVU0hPUlQgYWRkcix0bXBhZGRyLCBJbkJ1ZlszXSwgdG1wT2Zmc2V0OwoJVVNIT1JUIGJ1ZmZlcls4XTsKCUJPT0xFQU4JCWJXcml0ZVN1Y2Nlc3MgPSBUUlVFOwoKCURCR1BSSU5UKFJUX0RFQlVHX1RSQUNFLCAoImVGdXNlV3JpdGVSZWdpc3RlcnMgT2Zmc2V0PSV4LCBwRGF0YT0leFxuIiwgT2Zmc2V0LCAqcERhdGEpKTsKCgkvL1N0ZXAgMC4gZmluZCB0aGUgZW50cnkgaW4gdGhlIG1hcHBpbmcgdGFibGUKCS8vVGhlIGFkZHJlc3Mgb2YgRUVQUk9NIGlzIDItYnl0ZXMgYWxpZ25tZW50LgoJLy9UaGUgbGFzdCBiaXQgaXMgdXNlZCBmb3IgYWxpZ25tZW50LCBzbyBpdCBtdXN0IGJlIDAuCgl0bXBPZmZzZXQgPSBPZmZzZXQgJiAweGZmZmU7CglFRlNST01fQU9VVCA9IGVGdXNlUmVhZFJlZ2lzdGVycyhwQWQsIHRtcE9mZnNldCwgMiwgJmVGdXNlRGF0YSk7CgoJaWYoIEVGU1JPTV9BT1VUID09IDB4M2YpCgl7CS8vZmluZCBhdmFpbGFibGUgbG9naWNhbCBhZGRyZXNzIHBvaW50ZXIKCQkvL3RoZSBsb2dpY2FsIGFkZHJlc3MgZG9lcyBub3QgZXhpc3QsIGZpbmQgYW4gZW1wdHkgb25lCgkJLy9mcm9tIHRoZSBmaXJzdCBhZGRyZXNzIG9mIGJsb2NrIDQ1PTE2KjQ1PTB4MmQwIHRvIHRoZSBsYXN0IGFkZHJlc3Mgb2YgYmxvY2sgNDcKCQkvLz09PjQ4KjE2LTMocmVzZXJ2ZWQpPTJGQwoJCWZvciAoaT1FRlVTRV9VU0FHRV9NQVBfU1RBUlQ7IGk8PUVGVVNFX1VTQUdFX01BUF9FTkQ7IGkrPTIpCgkJewoJCQkvL1JldHJpdmUgdGhlIGxvZ2ljYWwgYmxvY2sgbnVibWVyIGZvcm0gZWFjaCBsb2dpY2FsIGFkZHJlc3MgcG9pbnRlcgoJCQkvL0l0IHdpbGwgYWNjZXNzIHR3byBsb2dpY2FsIGFkZHJlc3MgcG9pbnRlciBlYWNoIHRpbWUuCgkJCWVGdXNlUGh5c2ljYWxSZWFkUmVnaXN0ZXJzKHBBZCwgaSwgMiwgJkxvZ2ljYWxBZGRyZXNzKTsKCQkJaWYoIChMb2dpY2FsQWRkcmVzcyAmIDB4ZmYpID09IDApCgkJCXsvL05vdCB1c2VkIGxvZ2ljYWwgYWRkcmVzcyBwb2ludGVyCgkJCQlCbGtOdW0gPSBpLUVGVVNFX1VTQUdFX01BUF9TVEFSVDsKCQkJCWJyZWFrOwoJCQl9CgkJCWVsc2UgaWYoKCAoTG9naWNhbEFkZHJlc3MgPj4gOCkgJiAweGZmKSA9PSAwKQoJCQl7Ly9Ob3QgdXNlZCBsb2dpY2FsIGFkZHJlc3MgcG9pbnRlcgoJCQkJaWYgKGkgIT0gRUZVU0VfVVNBR0VfTUFQX0VORCkKCQkJCXsKCQkJCQlCbGtOdW0gPSBpLUVGVVNFX1VTQUdFX01BUF9TVEFSVCsxOwoJCQkJfQoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9CgllbHNlCgl7CgkJQmxrTnVtID0gRUZTUk9NX0FPVVQ7Cgl9CgoJREJHUFJJTlQoUlRfREVCVUdfVFJBQ0UsICgiZUZ1c2VXcml0ZVJlZ2lzdGVycyBCbGtOdW0gPSAlZCBcbiIsIEJsa051bSkpOwoKCWlmKEJsa051bSA9PSAweGZmZmYpCgl7CgkJREJHUFJJTlQoUlRfREVCVUdfVFJBQ0UsICgiZUZ1c2VXcml0ZVJlZ2lzdGVyczogb3V0IG9mIGZyZWUgRS1mdXNlIHNwYWNlISEhXG4iKSk7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCS8vU3RlcCAxLiBTYXZlIGRhdGEgb2YgdGhpcyBibG9jawl3aGljaCBpcyBwb2ludGVkIGJ5IHRoZSBhdmFpYmxlIGxvZ2ljYWwgYWRkcmVzcyBwb2ludGVyCgkvLyByZWFkIGFuZCBzYXZlIHRoZSBvcmlnaW5hbCBibG9jayBkYXRhCglmb3IoaSA9MDsgaTw4OyBpKyspCgl7CgkJYWRkciA9IEJsa051bSAqIDB4MTAgOwoKCQlJbkJ1ZlswXSA9IGFkZHIrMippOwoJCUluQnVmWzFdID0gMjsKCQlJbkJ1ZlsyXSA9IDB4MDsKCgkJZUZ1c2VSZWFkUGh5c2ljYWwocEFkLCAmSW5CdWZbMF0sIDQsICZJbkJ1ZlsyXSwgMik7CgoJCWJ1ZmZlcltpXSA9IEluQnVmWzJdOwoJfQoKCS8vU3RlcCAyLiBVcGRhdGUgdGhlIGRhdGEgaW4gYnVmZmVyLCBhbmQgd3JpdGUgdGhlIGRhdGEgdG8gRWZ1c2UKCWJ1ZmZlclsgKE9mZnNldCA+PiAxKSAlIDhdID0gcERhdGFbMF07CgoJZG8KCXsKCQkvL1N0ZXAgMy4gV3JpdGUgdGhlIGRhdGEgdG8gRWZ1c2UKCQlpZighYldyaXRlU3VjY2VzcykKCQl7CgkJCWZvcihpID0wOyBpPDg7IGkrKykKCQkJewoJCQkJYWRkciA9IEJsa051bSAqIDB4MTAgOwoKCQkJCUluQnVmWzBdID0gYWRkcisyKmk7CgkJCQlJbkJ1ZlsxXSA9IDI7CgkJCQlJbkJ1ZlsyXSA9IGJ1ZmZlcltpXTsKCgkJCQllRnVzZVdyaXRlUGh5c2ljYWwocEFkLCAmSW5CdWZbMF0sIDYsIE5VTEwsIDIpOwoJCQl9CgkJfQoJCWVsc2UKCQl7CgkJCQlhZGRyID0gQmxrTnVtICogMHgxMCA7CgoJCQkJSW5CdWZbMF0gPSBhZGRyKyhPZmZzZXQgJSAxNik7CgkJCQlJbkJ1ZlsxXSA9IDI7CgkJCQlJbkJ1ZlsyXSA9IHBEYXRhWzBdOwoKCQkJCWVGdXNlV3JpdGVQaHlzaWNhbChwQWQsICZJbkJ1ZlswXSwgNiwgTlVMTCwgMik7CgkJfQoKCQkvL1N0ZXAgNC4gV3JpdGUgbWFwcGluZyB0YWJsZQoJCWFkZHIgPSBFRlVTRV9VU0FHRV9NQVBfU1RBUlQrQmxrTnVtOwoKCQl0bXBhZGRyID0gYWRkcjsKCgkJaWYoYWRkciAlIDIgIT0gMCkKCQkJYWRkciA9IGFkZHIgLTE7CgkJSW5CdWZbMF0gPSBhZGRyOwoJCUluQnVmWzFdID0gMjsKCgkJLy9jb252ZXJ0IHRoZSBhZGRyZXNzIGZyb20gMTAgdG8gOCBiaXQgKCBiaXQ3LCA2ID0gcGFyaXR5IGFuZCBiaXQ1IH4gMCA9IGJpdDl+NCksIGFuZCB3cml0ZSB0byBsb2dpY2FsIG1hcCBlbnRyeQoJCXRtcE9mZnNldCA9IE9mZnNldDsKCQl0bXBPZmZzZXQgPj49IDQ7CgkJdG1wT2Zmc2V0IHw9ICgofigodG1wT2Zmc2V0ICYgMHgwMSkgXiAoIHRtcE9mZnNldCA+PiAxICYgMHgwMSkgXiAgKHRtcE9mZnNldCA+PiAyICYgMHgwMSkgXiAgKHRtcE9mZnNldCA+PiAzICYgMHgwMSkpKSA8PCA2KSAmIDB4NDA7CgkJdG1wT2Zmc2V0IHw9ICgofiggKHRtcE9mZnNldCA+PiAyICYgMHgwMSkgXiAodG1wT2Zmc2V0ID4+IDMgJiAweDAxKSBeICh0bXBPZmZzZXQgPj4gNCAmIDB4MDEpIF4gKCB0bXBPZmZzZXQgPj4gNSAmIDB4MDEpKSkgPDwgNykgJiAweDgwOwoKCQkvLyB3cml0ZSB0aGUgbG9naWNhbCBhZGRyZXNzCgkJaWYodG1wYWRkciUyICE9IDApCgkJCUluQnVmWzJdID0gdG1wT2Zmc2V0PDw4OwoJCWVsc2UKCQkJSW5CdWZbMl0gPSB0bXBPZmZzZXQ7CgoJCWVGdXNlV3JpdGVQaHlzaWNhbChwQWQsJkluQnVmWzBdLCA2LCBOVUxMLCAwKTsKCgkJLy9TdGVwIDUuIENvbXBhcmUgZGF0YSBpZiBub3QgdGhlIHNhbWUsIGludmFsaWRhdGUgdGhlIG1hcHBpbmcgZW50cnksIHRoZW4gcmUtd3JpdGUgdGhlIGRhdGEgdW50aWwgRS1mdXNlIGlzIGV4aGF1c3RlZAoJCWJXcml0ZVN1Y2Nlc3MgPSBUUlVFOwoJCWZvcihpID0wOyBpPDg7IGkrKykKCQl7CgkJCWFkZHIgPSBCbGtOdW0gKiAweDEwIDsKCgkJCUluQnVmWzBdID0gYWRkcisyKmk7CgkJCUluQnVmWzFdID0gMjsKCQkJSW5CdWZbMl0gPSAweDA7CgoJCQllRnVzZVJlYWRQaHlzaWNhbChwQWQsICZJbkJ1ZlswXSwgNCwgJkluQnVmWzJdLCAyKTsKCgkJCWlmKGJ1ZmZlcltpXSAhPSBJbkJ1ZlsyXSkKCQkJewoJCQkJYldyaXRlU3VjY2VzcyA9IEZBTFNFOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCS8vU3RlcCA2LiBpbnZsaWRhdGUgbWFwcGluZyBlbnRyeSBhbmQgZmluZCBhIGZyZWUgbWFwcGluZyBlbnRyeSBpZiBub3Qgc3VjY2VlZAoJCWlmICghYldyaXRlU3VjY2VzcykKCQl7CgkJCURCR1BSSU5UKFJUX0RFQlVHX1RSQUNFLCAoIk5vdCBiV3JpdGVTdWNjZXNzIEJsa051bSA9ICVkXG4iLCBCbGtOdW0pKTsKCgkJCS8vIHRoZSBvZmZzZXQgb2YgY3VycmVudCBtYXBwaW5nIGVudHJ5CgkJCWFkZHIgPSBFRlVTRV9VU0FHRV9NQVBfU1RBUlQrQmxrTnVtOwoKCQkJLy9maW5kIGEgbmV3IG1hcHBpbmcgZW50cnkKCQkJQmxrTnVtID0gMHhmZmZmOwoJCQlmb3IgKGk9RUZVU0VfVVNBR0VfTUFQX1NUQVJUOyBpPD1FRlVTRV9VU0FHRV9NQVBfRU5EOyBpKz0yKQoJCQl7CgkJCQllRnVzZVBoeXNpY2FsUmVhZFJlZ2lzdGVycyhwQWQsIGksIDIsICZMb2dpY2FsQWRkcmVzcyk7CgkJCQlpZiggKExvZ2ljYWxBZGRyZXNzICYgMHhmZikgPT0gMCkKCQkJCXsKCQkJCQlCbGtOdW0gPSBpLUVGVVNFX1VTQUdFX01BUF9TVEFSVDsKCQkJCQlicmVhazsKCQkJCX0KCQkJCWVsc2UgaWYoKCAoTG9naWNhbEFkZHJlc3MgPj4gOCkgJiAweGZmKSA9PSAwKQoJCQkJewoJCQkJCWlmIChpICE9IEVGVVNFX1VTQUdFX01BUF9FTkQpCgkJCQkJewoJCQkJCQlCbGtOdW0gPSBpKzEtRUZVU0VfVVNBR0VfTUFQX1NUQVJUOwoJCQkJCX0KCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCQlEQkdQUklOVChSVF9ERUJVR19UUkFDRSwgKCJOb3QgYldyaXRlU3VjY2VzcyBuZXcgQmxrTnVtID0gJWRcbiIsIEJsa051bSkpOwoJCQlpZihCbGtOdW0gPT0gMHhmZmZmKQoJCQl7CgkJCQlEQkdQUklOVChSVF9ERUJVR19UUkFDRSwgKCJlRnVzZVdyaXRlUmVnaXN0ZXJzOiBvdXQgb2YgZnJlZSBFLWZ1c2Ugc3BhY2UhISFcbiIpKTsKCQkJCXJldHVybiBGQUxTRTsKCQkJfQoKCQkJLy9pbnZhbGlkYXRlIHRoZSBvcmlnaW5hbCBtYXBwaW5nIGVudHJ5IGlmIG5ldyBlbnRyeSBpcyBub3QgZm91bmQKCQkJdG1wYWRkciA9IGFkZHI7CgoJCQlpZihhZGRyICUgMiAhPSAwKQoJCQkJYWRkciA9IGFkZHIgLTE7CgkJCUluQnVmWzBdID0gYWRkcjsKCQkJSW5CdWZbMV0gPSAyOwoKCQkJZUZ1c2VSZWFkUGh5c2ljYWwocEFkLCAmSW5CdWZbMF0sIDQsICZJbkJ1ZlsyXSwgMik7CgoJCQkvLyB3cml0ZSB0aGUgbG9naWNhbCBhZGRyZXNzCgkJCWlmKHRtcGFkZHIlMiAhPSAwKQoJCQl7CgkJCQkvLyBJbnZhbGlkYXRlIHRoZSBoaWdoIGJ5dGUKCQkJCWZvciAoaT04OyBpPDE1OyBpKyspCgkJCQl7CgkJCQkJaWYoICggKEluQnVmWzJdID4+IGkpICYgMHgwMSkgPT0gMCkKCQkJCQl7CgkJCQkJCUluQnVmWzJdIHw9ICgweDEgPDxpKTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWVsc2UKCQkJewoJCQkJLy8gaW52YWxpZGF0ZSB0aGUgbG93IGJ5dGUKCQkJCWZvciAoaT0wOyBpPDg7IGkrKykKCQkJCXsKCQkJCQlpZiggKCAoSW5CdWZbMl0gPj4gaSkgJiAweDAxKSA9PSAwKQoJCQkJCXsKCQkJCQkJSW5CdWZbMl0gfD0gKDB4MSA8PGkpOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCX0KCQkJZUZ1c2VXcml0ZVBoeXNpY2FsKHBBZCwgJkluQnVmWzBdLCA2LCBOVUxMLCAwKTsKCQl9Cgl9Cgl3aGlsZSghYldyaXRlU3VjY2Vzcyk7CgoJcmV0dXJuIFRSVUU7Cn0KCi8qCgk9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCglSb3V0aW5lIERlc2NyaXB0aW9uOgoKCUFyZ3VtZW50czoKCglSZXR1cm4gVmFsdWU6CgoJSVJRTCA9CgoJTm90ZToKCgk9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKi8KVk9JRCBlRnVzZVdyaXRlUGh5c2ljYWwoCglJTglQUlRNUF9BREFQVEVSCXBBZCwKICAJUFVTSE9SVCBscEluQnVmZmVyLAoJVUxPTkcgbkluQnVmZmVyU2l6ZSwKICAJUFVDSEFSIGxwT3V0QnVmZmVyLAogIAlVTE9ORyBuT3V0QnVmZmVyU2l6ZQopCnsKCVVTSE9SVCogcEluQnVmID0gKFVTSE9SVCopbHBJbkJ1ZmZlcjsKCWludCAJCWk7CgkvL1VTSE9SVCogcE91dEJ1ZiA9IChVU0hPUlQqKWlvQnVmZmVyOwoKCVVTSE9SVCBPZmZzZXQgPSBwSW5CdWZbMF07CQkJCQkvL2FkZHIKCVVTSE9SVCBMZW5ndGggPSBwSW5CdWZbMV07CQkJCQkvL2xlbmd0aAoJVVNIT1JUKiBwVmFsdWVYID0gJnBJbkJ1ZlsyXTsJCQkJLy92YWx1ZSAuLi4KCQkvLyBMaXR0bGUtZW5kaWFuCQlTCXwJUwlCaWctZW5kaWFuCgkJLy8gYWRkcgkzCTIJMQkwCXwJMAkxCTIJMwoJCS8vIE9yaS1WCUQJQwlCCUEJfAlBCUIJQwlECgkJLy9BZnRlciBzd2FwcGluZwoJCS8vCQlECUMJQglBCXwJRAlDCUIJQQoJCS8vQm90aCB0aGUgbGl0dGxlIGFuZCBiaWctZW5kaWFuIHVzZSB0aGUgc2FtZSBzZXF1ZW5jZSB0byB3cml0ZSAgZGF0YS4KCQkvL1RoZXJlZm9yZSwgd2Ugb25seSBuZWVkIHN3YXAgZGF0YSB3aGVuIHJlYWQgdGhlIGRhdGEuCglmb3IoaT0wOyBpPExlbmd0aDsgaSs9MikKCXsKCQllRnVzZVBoeXNpY2FsV3JpdGVSZWdpc3RlcnMocEFkLCBPZmZzZXQraSwgMiwgJnBWYWx1ZVhbaS8yXSk7Cgl9Cn0KCgovKgoJPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgoJUm91dGluZSBEZXNjcmlwdGlvbjoKCglBcmd1bWVudHM6CgoJUmV0dXJuIFZhbHVlOgoKCUlSUUwgPQoKCU5vdGU6CgoJPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiovCk5UU1RBVFVTIGVGdXNlV3JpdGUoCiAgIAlJTglQUlRNUF9BREFQVEVSCXBBZCwKCUlOCVVTSE9SVAkJCU9mZnNldCwKCUlOCVBVQ0hBUgkJCXBEYXRhLAoJSU4JVVNIT1JUCQkJbGVuZ3RoKQp7CglpbnQgaTsKCglVU0hPUlQqIHBWYWx1ZVggPSAoUFVTSE9SVCkgcERhdGE7CQkJCS8vdmFsdWUgLi4uCgkJLy9UaGUgaW5wdXQgdmFsdWU9MzA3MCB3aWxsIGJlIHN0b3JlZCBhcyBmb2xsb3dpbmcKIAkJLy8gTGl0dGxlLWVuZGlhbgkJUwl8CVMJQmlnLWVuZGlhbgoJCS8vIGFkZHIJCQkxCTAJfAkwCTEKCQkvLyBPcmktVgkJCTMwCTcwCXwJMzAJNzAKCQkvL0FmdGVyIHN3YXBwaW5nCgkJLy8JCQkJMzAJNzAJfAk3MAkzMAoJCS8vQ2FzdGluZwoJCS8vCQkJCTMwNzAJfAk3MDMwICh4KQoJCS8vVGhlIHN3YXBwaW5nIHNob3VsZCBiZSByZW1vdmVkIGZvciBiaWctZW5kaWFuCglmb3IoaT0wOyBpPGxlbmd0aDsgaSs9MikKCXsKCQllRnVzZVdyaXRlUmVnaXN0ZXJzKHBBZCwgT2Zmc2V0K2ksIDIsICZwVmFsdWVYW2kvMl0pOwoJfQoKCXJldHVybiBUUlVFOwp9CgovKgoJPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgoJUm91dGluZSBEZXNjcmlwdGlvbjoKCglBcmd1bWVudHM6CgoJUmV0dXJuIFZhbHVlOgoKCUlSUUwgPQoKCU5vdGU6CgoJPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiovCklOVCBzZXRfZUZ1c2VHZXRGcmVlQmxvY2tDb3VudF9Qcm9jKAogICAJSU4JUFJUTVBfQURBUFRFUglwQWQsCglJTglQVUNIQVIJCQlhcmcpCnsKCVVTSE9SVCBpOwoJVVNIT1JUCUxvZ2ljYWxBZGRyZXNzOwoJVVNIT1JUIGVmdXNlZnJlZW51bT0wOwoJaWYoIXBBZC0+YlVzZUVmdXNlKQoJCXJldHVybiBGQUxTRTsKCWZvciAoaSA9IEVGVVNFX1VTQUdFX01BUF9TVEFSVDsgaSA8PSBFRlVTRV9VU0FHRV9NQVBfRU5EOyBpKz0yKQoJewoJCWVGdXNlUGh5c2ljYWxSZWFkUmVnaXN0ZXJzKHBBZCwgaSwgMiwgJkxvZ2ljYWxBZGRyZXNzKTsKCQlpZiggKExvZ2ljYWxBZGRyZXNzICYgMHhmZikgPT0gMCkKCQl7CgkJCWVmdXNlZnJlZW51bT0gKFVDSEFSKSAoRUZVU0VfVVNBR0VfTUFQX0VORC1pKzEpOwoJCQlicmVhazsKCQl9CgkJZWxzZSBpZigoIChMb2dpY2FsQWRkcmVzcyA+PiA4KSAmIDB4ZmYpID09IDApCgkJewoJCQllZnVzZWZyZWVudW0gPSAoVUNIQVIpIChFRlVTRV9VU0FHRV9NQVBfRU5ELWkpOwoJCQlicmVhazsKCQl9CgoJCWlmKGkgPT0gRUZVU0VfVVNBR0VfTUFQX0VORCkKCQkJZWZ1c2VmcmVlbnVtID0gMDsKCX0KCXByaW50aygiZWZ1c2VGcmVlTnVtYmVyIGlzICVkXG4iLGVmdXNlZnJlZW51bSk7CglyZXR1cm4gVFJVRTsKfQpJTlQgc2V0X2VGdXNlZHVtcF9Qcm9jKAoJSU4JUFJUTVBfQURBUFRFUglwQWQsCglJTglQVUNIQVIJCQlhcmcpCnsKVVNIT1JUIEluQnVmWzNdOwoJSU5UIGk9MDsKCWlmKCFwQWQtPmJVc2VFZnVzZSkKCQlyZXR1cm4gRkFMU0U7Cglmb3IoaSA9MDsgaTxFRlVTRV9VU0FHRV9NQVBfRU5ELzI7IGkrKykKCXsKCQlJbkJ1ZlswXSA9IDIqaTsKCQlJbkJ1ZlsxXSA9IDI7CgkJSW5CdWZbMl0gPSAweDA7CgoJCWVGdXNlUmVhZFBoeXNpY2FsKHBBZCwgJkluQnVmWzBdLCA0LCAmSW5CdWZbMl0sIDIpOwoJCWlmKGklND09MCkKCQlwcmludGsoIlxuQmxvY2sgJXg6IixpLzgpOwoJCXByaW50aygiJTA0eCAiLEluQnVmWzJdKTsKCX0KCXJldHVybiBUUlVFOwp9CklOVAlzZXRfZUZ1c2VMb2FkRnJvbUJpbl9Qcm9jKAoJSU4JUFJUTVBfQURBUFRFUglwQWQsCglJTglQVUNIQVIJCQlhcmcpCnsKCUNIQVIJCQkJCSpzcmM7CglzdHJ1Y3QgZmlsZQkJCQkqc3JjZjsKCUlOVCAJCQkJCXJldHZhbCwgb3JnZnN1aWQsIG9yZ2ZzZ2lkOwogICAJbW1fc2VnbWVudF90CQkJb3JnZnM7CglVQ0hBUgkJCQkJKmJ1ZmZlcjsKCVVDSEFSCQkJCQlCaW5GaWxlU2l6ZT0wOwoJSU5UCQkJCQkJaSA9IDAsaj0wLGs9MTsKCVVTSE9SVAkJCQkJKlBEQVRBOwoJVVNIT1JUCQkJCQlEQVRBOwoJQmluRmlsZVNpemU9c3RybGVuKCJSVDMweHhFRVBST00uYmluIik7CglzcmMgPSBrbWFsbG9jKDEyOCwgTUVNX0FMTE9DX0ZMQUcpOwoJTmRpc1plcm9NZW1vcnkoc3JjLCAxMjgpOwoKIAlpZihzdHJsZW4oYXJnKT4wKQoJewoKCQlOZGlzTW92ZU1lbW9yeShzcmMsIGFyZywgc3RybGVuKGFyZykpOwogCX0KCgllbHNlCgl7CgoJCU5kaXNNb3ZlTWVtb3J5KHNyYywgIlJUMzB4eEVFUFJPTS5iaW4iLCBCaW5GaWxlU2l6ZSk7Cgl9CgoJREJHUFJJTlQoUlRfREVCVUdfVFJBQ0UsICgiRmlsZU5hbWU9JXNcbiIsc3JjKSk7CglidWZmZXIgPSBrbWFsbG9jKE1BWF9FRVBST01fQklOX0ZJTEVfU0laRSwgTUVNX0FMTE9DX0ZMQUcpOwoKCWlmKGJ1ZmZlciA9PSBOVUxMKQoJewoJCWtmcmVlKHNyYyk7CgkJIHJldHVybiBGQUxTRTsKfQoJUERBVEE9a21hbGxvYyhzaXplb2YoVVNIT1JUKSo4LE1FTV9BTExPQ19GTEFHKTsKCglpZihQREFUQT09TlVMTCkKCXsKCQlrZnJlZShzcmMpOwoKCQlrZnJlZShidWZmZXIpOwoJCXJldHVybiBGQUxTRTsKCX0KCS8qIERvbid0IGNoYW5nZSB0byB1aWQgMCwgbGV0IHRoZSBmaWxlIGJlIG9wZW5lZCBhcyB0aGUgIm5vcm1hbCIgdXNlciAqLwojaWYgMAoJb3JnZnN1aWQgPSBjdXJyZW50LT5mc3VpZDsKCW9yZ2ZzZ2lkID0gY3VycmVudC0+ZnNnaWQ7CgljdXJyZW50LT5mc3VpZD1jdXJyZW50LT5mc2dpZCA9IDA7CiNlbmRpZgogICAgCW9yZ2ZzID0gZ2V0X2ZzKCk7CiAgIAkgc2V0X2ZzKEtFUk5FTF9EUyk7CgoJaWYgKHNyYyAmJiAqc3JjKQoJewoJCXNyY2YgPSBmaWxwX29wZW4oc3JjLCBPX1JET05MWSwgMCk7CgkJaWYgKElTX0VSUihzcmNmKSkKCQl7CgkJCURCR1BSSU5UKFJUX0RFQlVHX0VSUk9SLCAoIi0tPiBFcnJvciAlbGQgb3BlbmluZyAlc1xuIiwgLVBUUl9FUlIoc3JjZiksc3JjKSk7CgkJCXJldHVybiBGQUxTRTsKCQl9CgkJZWxzZQoJCXsKCQkJLy8gVGhlIG9iamVjdCBtdXN0IGhhdmUgYSByZWFkIG1ldGhvZAoJCQlpZiAoc3JjZi0+Zl9vcCAmJiBzcmNmLT5mX29wLT5yZWFkKQoJCQl7CgkJCQltZW1zZXQoYnVmZmVyLCAweDAwLCBNQVhfRUVQUk9NX0JJTl9GSUxFX1NJWkUpOwoJCQkJd2hpbGUoc3JjZi0+Zl9vcC0+cmVhZChzcmNmLCAmYnVmZmVyW2ldLCAxLCAmc3JjZi0+Zl9wb3MpPT0xKQoJCQkJewoJCQkJCURCR1BSSU5UKFJUX0RFQlVHX1RSQUNFLCAoIiUwMlggIixidWZmZXJbaV0pKTsKCQkJCQlpZigoaSsxKSU4PT0wKQoJCQkJCQlEQkdQUklOVChSVF9ERUJVR19UUkFDRSwgKCJcbiIpKTsKICAgICAgICAgICAgICAJCQlpKys7CgkJCQkJCWlmKGk+PU1BWF9FRVBST01fQklOX0ZJTEVfU0laRSkKCQkJCQkJCXsKCQkJCQkJCQlEQkdQUklOVChSVF9ERUJVR19FUlJPUiwgKCItLT4gRXJyb3IgJWxkIHJlYWRpbmcgJXMsIFRoZSBmaWxlIGlzIHRvbyBsYXJnZVsxMDI0XVxuIiwgLVBUUl9FUlIoc3JjZiksc3JjKSk7CgkJCQkJCQkJa2ZyZWUoUERBVEEpOwoJCQkJCQkJCWtmcmVlKGJ1ZmZlcik7CgkJCQkJCQkJa2ZyZWUoc3JjKTsKCQkJCQkJCQlyZXR1cm4gRkFMU0U7CgkJCQkJCQl9CgkJCSAgICAgICB9CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQkJCURCR1BSSU5UKFJUX0RFQlVHX0VSUk9SLCAoIi0tPiBFcnJvciEhIFN5c3RlbSBkb2VzdCBub3Qgc3VwcG9ydCByZWFkIGZ1bmN0aW9uXG4iKSk7CgkJCQkJCWtmcmVlKFBEQVRBKTsKCQkJCQkJa2ZyZWUoYnVmZmVyKTsKCQkJCQkJa2ZyZWUoc3JjKTsKCQkJCQkJcmV0dXJuIEZBTFNFOwoJCQl9CiAgICAgIAkJfQoKCgl9CgllbHNlCgkJewoJCQkJCURCR1BSSU5UKFJUX0RFQlVHX0VSUk9SLCAoIi0tPiBFcnJvciBzcmMgIG9yIHNyY2YgaXMgbnVsbFxuIikpOwoJCQkJCWtmcmVlKFBEQVRBKTsKCQkJCQlrZnJlZShidWZmZXIpOwoJCQkJCXJldHVybiBGQUxTRTsKCgkJfQoKCglyZXR2YWw9ZmlscF9jbG9zZShzcmNmLE5VTEwpOwoKCWlmIChyZXR2YWwpCgl7CgkJREJHUFJJTlQoUlRfREVCVUdfVFJBQ0UsICgiLS0+IEVycm9yICVkIGNsb3NpbmcgJXNcbiIsIC1yZXR2YWwsIHNyYykpOwoJfQoJc2V0X2ZzKG9yZ2ZzKTsKI2lmIDAKCWN1cnJlbnQtPmZzdWlkID0gb3JnZnN1aWQ7CgljdXJyZW50LT5mc2dpZCA9IG9yZ2ZzZ2lkOwojZW5kaWYKCWZvcihqPTA7ajxpO2orKykKCXsKCQlEQkdQUklOVChSVF9ERUJVR19UUkFDRSwgKCIlMDJYICIsYnVmZmVyW2pdKSk7CgkJaWYoKGorMSklMj09MCkKCQkJUERBVEFbai8yJThdPSgoYnVmZmVyW2pdPDw4KSYweGZmMDApfChidWZmZXJbai0xXSYweGZmKTsKCQlpZihqJTE2PT0wKQoJCXsKCQkJaz1idWZmZXJbal07CgkJfQoJCWVsc2UKCQl7CgkJCWsmPWJ1ZmZlcltqXTsKCQkJaWYoKGorMSklMTY9PTApCgkJCXsKCgkJCQlEQkdQUklOVChSVF9ERUJVR19UUkFDRSwgKCIgcmVzdWx0PSUwMlgsYmxrPSUwMnhcbiIsayxqLzE2KSk7CgoJCQkJaWYoayE9MHhmZikKCQkJCQllRnVzZVdyaXRlUmVnaXN0ZXJzRnJvbUJpbihwQWQsKFVTSE9SVClqLTE1LCAxNiwgUERBVEEpOwoJCQkJZWxzZQoJCQkJCXsKCQkJCQkJaWYoZUZ1c2VSZWFkUmVnaXN0ZXJzKHBBZCxqLCAyLChQVVNIT1JUKSZEQVRBKSE9MHgzZikKCQkJCQkJCWVGdXNlV3JpdGVSZWdpc3RlcnNGcm9tQmluKHBBZCwoVVNIT1JUKWotMTUsIDE2LCBQREFUQSk7CgkJCQkJfQoJCQkJLyoKCQkJCWZvcihsPTA7bDw4O2wrKykKCQkJCQlwcmludGsoIiUwNHggIixQREFUQVtsXSk7CgkJCQlwcmludGsoIlxuIik7CgkJCQkqLwoJCQkJTmRpc1plcm9NZW1vcnkoUERBVEEsMTYpOwoKCgkJCX0KCQl9CgoKCX0KCgoJa2ZyZWUoUERBVEEpOwoJa2ZyZWUoYnVmZmVyKTsKCWtmcmVlKHNyYyk7CglyZXR1cm4gVFJVRTsKfQpOVFNUQVRVUyBlRnVzZVdyaXRlUmVnaXN0ZXJzRnJvbUJpbigKCUlOCVBSVE1QX0FEQVBURVIJcEFkLAoJSU4JVVNIT1JUIE9mZnNldCwKCUlOCVVTSE9SVCBMZW5ndGgsCglJTglVU0hPUlQqIHBEYXRhKQp7CglVU0hPUlQJaTsKCVVTSE9SVAllRnVzZURhdGE7CglVU0hPUlQJTG9naWNhbEFkZHJlc3MsIEJsa051bSA9IDB4ZmZmZjsKCVVDSEFSCUVGU1JPTV9BT1VULExvb3A9MDsKCUVGVVNFX0NUUkxfU1RSVUMJCWVGdXNlQ3RybFN0cnVjOwoJVVNIT1JUCWVmdXNlRGF0YU9mZnNldDsKCVVJTlQzMglkYXRhLHRlbXBidWZmZXI7CglVU0hPUlQgYWRkcix0bXBhZGRyLCBJbkJ1ZlszXSwgdG1wT2Zmc2V0OwoJVUlOVDMyIGJ1ZmZlcls0XTsKCUJPT0xFQU4JCWJXcml0ZVN1Y2Nlc3MgPSBUUlVFOwoJQk9PTEVBTgkJYk5vdFdyaXRlPVRSVUU7CglCT09MRUFOCQliQWxsb2NhdGVOZXdCbGs9VFJVRTsKCglEQkdQUklOVChSVF9ERUJVR19UUkFDRSwgKCJlRnVzZVdyaXRlUmVnaXN0ZXJzRnJvbUJpbiBPZmZzZXQ9JXgsIHBEYXRhPSUwNHg6JTA0eDolMDR4OiUwNHhcbiIsIE9mZnNldCwgKnBEYXRhLCoocERhdGErMSksKihwRGF0YSsyKSwqKHBEYXRhKzMpKSk7CgoJZG8KCXsKCS8vU3RlcCAwLiBmaW5kIHRoZSBlbnRyeSBpbiB0aGUgbWFwcGluZyB0YWJsZQoJLy9UaGUgYWRkcmVzcyBvZiBFRVBST00gaXMgMi1ieXRlcyBhbGlnbm1lbnQuCgkvL1RoZSBsYXN0IGJpdCBpcyB1c2VkIGZvciBhbGlnbm1lbnQsIHNvIGl0IG11c3QgYmUgMC4KCUxvb3ArKzsKCXRtcE9mZnNldCA9IE9mZnNldCAmIDB4ZmZmZTsKCUVGU1JPTV9BT1VUID0gZUZ1c2VSZWFkUmVnaXN0ZXJzKHBBZCwgdG1wT2Zmc2V0LCAyLCAmZUZ1c2VEYXRhKTsKCglpZiggRUZTUk9NX0FPVVQgPT0gMHgzZikKCXsJLy9maW5kIGF2YWlsYWJsZSBsb2dpY2FsIGFkZHJlc3MgcG9pbnRlcgoJCS8vdGhlIGxvZ2ljYWwgYWRkcmVzcyBkb2VzIG5vdCBleGlzdCwgZmluZCBhbiBlbXB0eSBvbmUKCQkvL2Zyb20gdGhlIGZpcnN0IGFkZHJlc3Mgb2YgYmxvY2sgNDU9MTYqNDU9MHgyZDAgdG8gdGhlIGxhc3QgYWRkcmVzcyBvZiBibG9jayA0NwoJCS8vPT0+NDgqMTYtMyhyZXNlcnZlZCk9MkZDCgkJYkFsbG9jYXRlTmV3QmxrPVRSVUU7CgkJZm9yIChpPUVGVVNFX1VTQUdFX01BUF9TVEFSVDsgaTw9RUZVU0VfVVNBR0VfTUFQX0VORDsgaSs9MikKCQl7CgkJCS8vUmV0cml2ZSB0aGUgbG9naWNhbCBibG9jayBudWJtZXIgZm9ybSBlYWNoIGxvZ2ljYWwgYWRkcmVzcyBwb2ludGVyCgkJCS8vSXQgd2lsbCBhY2Nlc3MgdHdvIGxvZ2ljYWwgYWRkcmVzcyBwb2ludGVyIGVhY2ggdGltZS4KCQkJZUZ1c2VQaHlzaWNhbFJlYWRSZWdpc3RlcnMocEFkLCBpLCAyLCAmTG9naWNhbEFkZHJlc3MpOwoJCQlpZiggKExvZ2ljYWxBZGRyZXNzICYgMHhmZikgPT0gMCkKCQkJey8vTm90IHVzZWQgbG9naWNhbCBhZGRyZXNzIHBvaW50ZXIKCQkJCUJsa051bSA9IGktRUZVU0VfVVNBR0VfTUFQX1NUQVJUOwoJCQkJYnJlYWs7CgkJCX0KCQkJZWxzZSBpZigoIChMb2dpY2FsQWRkcmVzcyA+PiA4KSAmIDB4ZmYpID09IDApCgkJCXsvL05vdCB1c2VkIGxvZ2ljYWwgYWRkcmVzcyBwb2ludGVyCgkJCQlpZiAoaSAhPSBFRlVTRV9VU0FHRV9NQVBfRU5EKQoJCQkJewoJCQkJCUJsa051bSA9IGktRUZVU0VfVVNBR0VfTUFQX1NUQVJUKzE7CgkJCQl9CgkJCQlicmVhazsKCQkJfQoJCX0KCX0KCWVsc2UKCXsKCQliQWxsb2NhdGVOZXdCbGs9RkFMU0U7CgkJQmxrTnVtID0gRUZTUk9NX0FPVVQ7Cgl9CgoJREJHUFJJTlQoUlRfREVCVUdfVFJBQ0UsICgiZUZ1c2VXcml0ZVJlZ2lzdGVycyBCbGtOdW0gPSAlZCBcbiIsIEJsa051bSkpOwoKCWlmKEJsa051bSA9PSAweGZmZmYpCgl7CgkJREJHUFJJTlQoUlRfREVCVUdfVFJBQ0UsICgiZUZ1c2VXcml0ZVJlZ2lzdGVyczogb3V0IG9mIGZyZWUgRS1mdXNlIHNwYWNlISEhXG4iKSk7CgkJcmV0dXJuIEZBTFNFOwoJfQoJLy9TdGVwIDEuMS4wCgkvL0lmIHRoZSBibG9jayBpcyBub3QgZXhpc3RpbmcgaW4gbWFwcGluZyB0YWJsZSwgY3JlYXRlIG9uZQoJLy9hbmQgd3JpdGUgZG93biB0aGUgMTYtYnl0ZXMgZGF0YSB0byB0aGUgbmV3IGJsb2NrCglpZihiQWxsb2NhdGVOZXdCbGspCgl7CgkJREJHUFJJTlQoUlRfREVCVUdfVFJBQ0UsICgiQWxsb2NhdGUgTmV3IEJsa1xuIikpOwoJCWVmdXNlRGF0YU9mZnNldCA9ICBFRlVTRV9EQVRBMzsKCQlmb3IoaT0wOyBpPCA0OyBpKyspCgkJewoJCQlEQkdQUklOVChSVF9ERUJVR19UUkFDRSwgKCJBbGxvY2F0ZSBOZXcgQmxrLCBEYXRhJWQ9JTA0eCUwNHhcbiIsMy1pLHBEYXRhWzIqaSsxXSxwRGF0YVsyKmldKSk7CgkJCXRlbXBidWZmZXI9KChwRGF0YVsyKmkrMV08PDE2KSYweGZmZmYwMDAwKXxwRGF0YVsyKmldOwoKCgkJCVJUTVBfSU9fV1JJVEUzMihwQWQsIGVmdXNlRGF0YU9mZnNldCx0ZW1wYnVmZmVyKTsKCQkJZWZ1c2VEYXRhT2Zmc2V0IC09IDQ7CgoJCX0KCQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKCQkvL1N0ZXAxLjEuMS4gV3JpdGUgMTAtYml0IG9mIGFkZHJlc3MgdG8gRUZTUk9NX0FJTiAoMHg1ODAsIGJpdDI1OmJpdDE2KS4gVGhlIGFkZHJlc3MgbXVzdCBiZSAxNi1ieXRlIGFsaWdubWVudC4KCQllRnVzZUN0cmxTdHJ1Yy5maWVsZC5FRlNST01fQUlOID0gQmxrTnVtKiAweDEwIDsKCgkJLy9TdGVwMS4xLjIuIFdyaXRlIEVGU1JPTV9NT0RFICgweDU4MCwgYml0NzpiaXQ2KSB0byAzLgoJCWVGdXNlQ3RybFN0cnVjLmZpZWxkLkVGU1JPTV9NT0RFID0gMzsKCgkJLy9TdGVwMS4xLjMuIFdyaXRlIEVGU1JPTV9LSUNLICgweDU4MCwgYml0MzApIHRvIDEgdG8ga2ljay1vZmYgcGh5c2ljYWwgd3JpdGUgcHJvY2VkdXJlLgoJCWVGdXNlQ3RybFN0cnVjLmZpZWxkLkVGU1JPTV9LSUNLID0gMTsKCgkJTmRpc01vdmVNZW1vcnkoJmRhdGEsICZlRnVzZUN0cmxTdHJ1YywgNCk7CgoJCVJUTVBfSU9fV1JJVEUzMihwQWQsIEVGVVNFX0NUUkwsIGRhdGEpOwoKCQkvL1N0ZXAxLjEuNC4gUG9sbGluZyBFRlNST01fS0lDSygweDU4MCwgYml0MzApIHVudGlsIGl0IGJlY29tZSAwIGFnYWluLiBJdKGmcyBkb25lLgoJCWkgPSAwOwoJCXdoaWxlKGkgPCAxMDApCgkJewoJCQlSVE1QX0lPX1JFQUQzMihwQWQsIEVGVVNFX0NUUkwsIChQVUlOVDMyKSAmZUZ1c2VDdHJsU3RydWMpOwoKCQkJaWYoZUZ1c2VDdHJsU3RydWMuZmllbGQuRUZTUk9NX0tJQ0sgPT0gMCkKCQkJCWJyZWFrOwoKCQkJUlRNUHVzZWNEZWxheSgyKTsKCQkJaSsrOwoJCX0KCgl9CgllbHNlCgl7CS8vU3RlcDEuMi4KCQkvL0lmIHRoZSBzYW1lIGxvZ2ljYWwgbnVtYmVyIGlzIGV4aXN0aW5nLCBjaGVjayBpZiB0aGUgd3JpdHRpbmcgZGF0YSBhbmQgdGhlIGRhdGEKCQkvL3NhdmluZyBpbiB0aGlzIGJsb2NrIGFyZSB0aGUgc2FtZS4KCQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoJCS8vcmVhZCBjdXJyZW50IHZhbHVlcyBvZiAxNi1ieXRlIGJsb2NrCgkJUlRNUF9JT19SRUFEMzIocEFkLCBFRlVTRV9DVFJMLCAoUFVJTlQzMikgJmVGdXNlQ3RybFN0cnVjKTsKCgkJLy9TdGVwMS4yLjAuIFdyaXRlIDEwLWJpdCBvZiBhZGRyZXNzIHRvIEVGU1JPTV9BSU4gKDB4NTgwLCBiaXQyNTpiaXQxNikuIFRoZSBhZGRyZXNzIG11c3QgYmUgMTYtYnl0ZSBhbGlnbm1lbnQuCgkJZUZ1c2VDdHJsU3RydWMuZmllbGQuRUZTUk9NX0FJTiA9IE9mZnNldCAmIDB4ZmZmMDsKCgkJLy9TdGVwMS4yLjEuIFdyaXRlIEVGU1JPTV9NT0RFICgweDU4MCwgYml0NzpiaXQ2KSB0byAxLgoJCWVGdXNlQ3RybFN0cnVjLmZpZWxkLkVGU1JPTV9NT0RFID0gMDsKCgkJLy9TdGVwMS4yLjIuIFdyaXRlIEVGU1JPTV9LSUNLICgweDU4MCwgYml0MzApIHRvIDEgdG8ga2ljay1vZmYgcGh5c2ljYWwgcmVhZCBwcm9jZWR1cmUuCgkJZUZ1c2VDdHJsU3RydWMuZmllbGQuRUZTUk9NX0tJQ0sgPSAxOwoKCQlOZGlzTW92ZU1lbW9yeSgmZGF0YSwgJmVGdXNlQ3RybFN0cnVjLCA0KTsKCQlSVE1QX0lPX1dSSVRFMzIocEFkLCBFRlVTRV9DVFJMLCBkYXRhKTsKCgkJLy9TdGVwMS4yLjMuIFBvbGxpbmcgRUZTUk9NX0tJQ0soMHg1ODAsIGJpdDMwKSB1bnRpbCBpdCBiZWNvbWUgMCBhZ2Fpbi4KCQlpID0gMDsKCQl3aGlsZShpIDwgMTAwKQoJCXsKCQkJUlRNUF9JT19SRUFEMzIocEFkLCBFRlVTRV9DVFJMLCAoUFVJTlQzMikgJmVGdXNlQ3RybFN0cnVjKTsKCgkJCWlmKGVGdXNlQ3RybFN0cnVjLmZpZWxkLkVGU1JPTV9LSUNLID09IDApCgkJCQlicmVhazsKCQkJUlRNUHVzZWNEZWxheSgyKTsKCQkJaSsrOwoJCX0KCgkJLy9TdGVwMS4yLjQuIFJlYWQgMTYtYnl0ZSBvZiBkYXRhIGZyb20gRUZVU0VfREFUQTAtMyAoMHg1OUMtMHg1OTApCgkJZWZ1c2VEYXRhT2Zmc2V0ID0gIEVGVVNFX0RBVEEzOwoJCWZvcihpPTA7IGk8IDQ7IGkrKykKCQl7CgkJCVJUTVBfSU9fUkVBRDMyKHBBZCwgZWZ1c2VEYXRhT2Zmc2V0LCAoUFVJTlQzMikgJmJ1ZmZlcltpXSk7CgkJCWVmdXNlRGF0YU9mZnNldCAtPSAgNDsKCQl9CgkJLy9TdGVwMS4yLjUuIENoZWNrIGlmIHRoZSBkYXRhIG9mIGVmdXNlIGFuZCB0aGUgd3JpdGluZyBkYXRhIGFyZSB0aGUgc2FtZS4KCQlmb3IoaSA9MDsgaTw0OyBpKyspCgkJewoJCQl0ZW1wYnVmZmVyPSgocERhdGFbMippKzFdPDwxNikmMHhmZmZmMDAwMCl8cERhdGFbMippXTsKCQkJREJHUFJJTlQoUlRfREVCVUdfVFJBQ0UsICgiYnVmZmVyWyVkXT0leCxwRGF0YVslZF09JXgscERhdGFbJWRdPSV4LHRlbXBidWZmZXI9JXhcbiIsaSxidWZmZXJbaV0sMippLHBEYXRhWzIqaV0sMippKzEscERhdGFbMippKzFdLHRlbXBidWZmZXIpKTsKCgkJCWlmKCgoYnVmZmVyW2ldJjB4ZmZmZjAwMDApPT0ocERhdGFbMippKzFdPDwxNikpJiYoKGJ1ZmZlcltpXSYweGZmZmYpPT1wRGF0YVsyKmldKSkKCQkJCWJOb3RXcml0ZSY9VFJVRTsKCQkJZWxzZQoJCQl7CgkJCQliTm90V3JpdGUmPUZBTFNFOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJaWYoIWJOb3RXcml0ZSkKCQl7CgkJcHJpbnRrKCJUaGUgZGF0YSBpcyBub3QgdGhlIHNhbWVcbiIpOwoKCQkJZm9yKGkgPTA7IGk8ODsgaSsrKQoJCQl7CgkJCQlhZGRyID0gQmxrTnVtICogMHgxMCA7CgoJCQkJSW5CdWZbMF0gPSBhZGRyKzIqaTsKCQkJCUluQnVmWzFdID0gMjsKCQkJCUluQnVmWzJdID0gcERhdGFbaV07CgoJCQkJZUZ1c2VXcml0ZVBoeXNpY2FsKHBBZCwgJkluQnVmWzBdLCA2LCBOVUxMLCAyKTsKCQkJfQoKCQl9CgkJZWxzZQoJCQlyZXR1cm4gVFJVRTsKCSAgICAgfQoKCgoJCS8vU3RlcCAyLiBXcml0ZSBtYXBwaW5nIHRhYmxlCgkJYWRkciA9IEVGVVNFX1VTQUdFX01BUF9TVEFSVCtCbGtOdW07CgoJCXRtcGFkZHIgPSBhZGRyOwoKCQlpZihhZGRyICUgMiAhPSAwKQoJCQlhZGRyID0gYWRkciAtMTsKCQlJbkJ1ZlswXSA9IGFkZHI7CgkJSW5CdWZbMV0gPSAyOwoKCQkvL2NvbnZlcnQgdGhlIGFkZHJlc3MgZnJvbSAxMCB0byA4IGJpdCAoIGJpdDcsIDYgPSBwYXJpdHkgYW5kIGJpdDUgfiAwID0gYml0OX40KSwgYW5kIHdyaXRlIHRvIGxvZ2ljYWwgbWFwIGVudHJ5CgkJdG1wT2Zmc2V0ID0gT2Zmc2V0OwoJCXRtcE9mZnNldCA+Pj0gNDsKCQl0bXBPZmZzZXQgfD0gKCh+KCh0bXBPZmZzZXQgJiAweDAxKSBeICggdG1wT2Zmc2V0ID4+IDEgJiAweDAxKSBeICAodG1wT2Zmc2V0ID4+IDIgJiAweDAxKSBeICAodG1wT2Zmc2V0ID4+IDMgJiAweDAxKSkpIDw8IDYpICYgMHg0MDsKCQl0bXBPZmZzZXQgfD0gKCh+KCAodG1wT2Zmc2V0ID4+IDIgJiAweDAxKSBeICh0bXBPZmZzZXQgPj4gMyAmIDB4MDEpIF4gKHRtcE9mZnNldCA+PiA0ICYgMHgwMSkgXiAoIHRtcE9mZnNldCA+PiA1ICYgMHgwMSkpKSA8PCA3KSAmIDB4ODA7CgoJCS8vIHdyaXRlIHRoZSBsb2dpY2FsIGFkZHJlc3MKCQlpZih0bXBhZGRyJTIgIT0gMCkKCQkJSW5CdWZbMl0gPSB0bXBPZmZzZXQ8PDg7CgkJZWxzZQoJCQlJbkJ1ZlsyXSA9IHRtcE9mZnNldDsKCgkJZUZ1c2VXcml0ZVBoeXNpY2FsKHBBZCwmSW5CdWZbMF0sIDYsIE5VTEwsIDApOwoKCQkvL1N0ZXAgMy4gQ29tcGFyZSBkYXRhIGlmIG5vdCB0aGUgc2FtZSwgaW52YWxpZGF0ZSB0aGUgbWFwcGluZyBlbnRyeSwgdGhlbiByZS13cml0ZSB0aGUgZGF0YSB1bnRpbCBFLWZ1c2UgaXMgZXhoYXVzdGVkCgkJYldyaXRlU3VjY2VzcyA9IFRSVUU7CgkJZm9yKGkgPTA7IGk8ODsgaSsrKQoJCXsKCQkJYWRkciA9IEJsa051bSAqIDB4MTAgOwoKCQkJSW5CdWZbMF0gPSBhZGRyKzIqaTsKCQkJSW5CdWZbMV0gPSAyOwoJCQlJbkJ1ZlsyXSA9IDB4MDsKCgkJCWVGdXNlUmVhZFBoeXNpY2FsKHBBZCwgJkluQnVmWzBdLCA0LCAmSW5CdWZbMl0sIDIpOwoJCQlEQkdQUklOVChSVF9ERUJVR19UUkFDRSwgKCJhZGRyPSV4LCBidWZmZXJbaV09JXgsSW5CdWZbMl09JXhcbiIsSW5CdWZbMF0scERhdGFbaV0sSW5CdWZbMl0pKTsKCQkJaWYocERhdGFbaV0gIT0gSW5CdWZbMl0pCgkJCXsKCQkJCWJXcml0ZVN1Y2Nlc3MgPSBGQUxTRTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoKCQkvL1N0ZXAgNC4gaW52bGlkYXRlIG1hcHBpbmcgZW50cnkgYW5kIGZpbmQgYSBmcmVlIG1hcHBpbmcgZW50cnkgaWYgbm90IHN1Y2NlZWQKCgkJaWYgKCFiV3JpdGVTdWNjZXNzJiZMb29wPDIpCgkJewoJCQlEQkdQUklOVChSVF9ERUJVR19UUkFDRSwgKCJlRnVzZVdyaXRlUmVnaXN0ZXJzRnJvbUJpbjo6Tm90IGJXcml0ZVN1Y2Nlc3MgQmxrTnVtID0gJWRcbiIsIEJsa051bSkpOwoKCQkJLy8gdGhlIG9mZnNldCBvZiBjdXJyZW50IG1hcHBpbmcgZW50cnkKCQkJYWRkciA9IEVGVVNFX1VTQUdFX01BUF9TVEFSVCtCbGtOdW07CgoJCQkvL2ZpbmQgYSBuZXcgbWFwcGluZyBlbnRyeQoJCQlCbGtOdW0gPSAweGZmZmY7CgkJCWZvciAoaT1FRlVTRV9VU0FHRV9NQVBfU1RBUlQ7IGk8PUVGVVNFX1VTQUdFX01BUF9FTkQ7IGkrPTIpCgkJCXsKCQkJCWVGdXNlUGh5c2ljYWxSZWFkUmVnaXN0ZXJzKHBBZCwgaSwgMiwgJkxvZ2ljYWxBZGRyZXNzKTsKCQkJCWlmKCAoTG9naWNhbEFkZHJlc3MgJiAweGZmKSA9PSAwKQoJCQkJewoJCQkJCUJsa051bSA9IGktRUZVU0VfVVNBR0VfTUFQX1NUQVJUOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJZWxzZSBpZigoIChMb2dpY2FsQWRkcmVzcyA+PiA4KSAmIDB4ZmYpID09IDApCgkJCQl7CgkJCQkJaWYgKGkgIT0gRUZVU0VfVVNBR0VfTUFQX0VORCkKCQkJCQl7CgkJCQkJCUJsa051bSA9IGkrMS1FRlVTRV9VU0FHRV9NQVBfU1RBUlQ7CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJCURCR1BSSU5UKFJUX0RFQlVHX1RSQUNFLCAoImVGdXNlV3JpdGVSZWdpc3RlcnNGcm9tQmluOjpOb3QgYldyaXRlU3VjY2VzcyBuZXcgQmxrTnVtID0gJWRcbiIsIEJsa051bSkpOwoJCQlpZihCbGtOdW0gPT0gMHhmZmZmKQoJCQl7CgkJCQlEQkdQUklOVChSVF9ERUJVR19UUkFDRSwgKCJlRnVzZVdyaXRlUmVnaXN0ZXJzRnJvbUJpbjogb3V0IG9mIGZyZWUgRS1mdXNlIHNwYWNlISEhXG4iKSk7CgkJCQlyZXR1cm4gRkFMU0U7CgkJCX0KCgkJCS8vaW52YWxpZGF0ZSB0aGUgb3JpZ2luYWwgbWFwcGluZyBlbnRyeSBpZiBuZXcgZW50cnkgaXMgbm90IGZvdW5kCgkJCXRtcGFkZHIgPSBhZGRyOwoKCQkJaWYoYWRkciAlIDIgIT0gMCkKCQkJCWFkZHIgPSBhZGRyIC0xOwoJCQlJbkJ1ZlswXSA9IGFkZHI7CgkJCUluQnVmWzFdID0gMjsKCgkJCWVGdXNlUmVhZFBoeXNpY2FsKHBBZCwgJkluQnVmWzBdLCA0LCAmSW5CdWZbMl0sIDIpOwoKCQkJLy8gd3JpdGUgdGhlIGxvZ2ljYWwgYWRkcmVzcwoJCQlpZih0bXBhZGRyJTIgIT0gMCkKCQkJewoJCQkJLy8gSW52YWxpZGF0ZSB0aGUgaGlnaCBieXRlCgkJCQlmb3IgKGk9ODsgaTwxNTsgaSsrKQoJCQkJewoJCQkJCWlmKCAoIChJbkJ1ZlsyXSA+PiBpKSAmIDB4MDEpID09IDApCgkJCQkJewoJCQkJCQlJbkJ1ZlsyXSB8PSAoMHgxIDw8aSk7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCX0KCQkJfQoJCQllbHNlCgkJCXsKCQkJCS8vIGludmFsaWRhdGUgdGhlIGxvdyBieXRlCgkJCQlmb3IgKGk9MDsgaTw4OyBpKyspCgkJCQl7CgkJCQkJaWYoICggKEluQnVmWzJdID4+IGkpICYgMHgwMSkgPT0gMCkKCQkJCQl7CgkJCQkJCUluQnVmWzJdIHw9ICgweDEgPDxpKTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWVGdXNlV3JpdGVQaHlzaWNhbChwQWQsICZJbkJ1ZlswXSwgNiwgTlVMTCwgMCk7CgkJfQoKCX0KCXdoaWxlKCFiV3JpdGVTdWNjZXNzJiZMb29wPDIpOwoKCXJldHVybiBUUlVFOwp9CgojZW5kaWYgLy8gUlQzMHh4IC8vCi8vMjAwOC8wOS8xMTpLSCBhZGQgdG8gc3VwcG9ydCBlZnVzZS0tPgoK