LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAZmlsZSAgICAgYXBwX2luZm8uYwogKgogKiBAYnJpZWYgICAgZm9yIFRMU1IgY2hpcHMKICoKICogQGF1dGhvciAgIHB1YmxpY0B0ZWxpbmstc2VtaS5jb207CiAqIEBkYXRlICAgICBTZXAuIDMwLCAyMDEwCiAqCiAqIEBhdHRlbnRpb24KICoKICogIENvcHlyaWdodCAoQykgMjAxOS0yMDIwIFRlbGluayBTZW1pY29uZHVjdG9yIChTaGFuZ2hhaSkgQ28uLCBMdGQuCiAqCiAqICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJ0bF9jb21tb24uaCIKI2luY2x1ZGUgImRyaXZlcnMuaCIKI2luY2x1ZGUgImFwcF9mbGFzaF93cml0ZS5oIgoKCl9hdHRyaWJ1dGVfZGF0YV9yZXRlbnRpb25fIHU4IGZsYWdfY2NjX2RhdGEgPSAwOwpfYXR0cmlidXRlX2RhdGFfcmV0ZW50aW9uXyB1OCBwZWVyX21hY1s2XSA9IHswfTsKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoqKiogb3BlcmF0ZSAgZmxhc2ggZnVuY3Rpb24KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogQGJyaWVmIFRoaXMgZnVuY3Rpb24gY2FuIG1ha2UgbW9yZSBlZmZlY3RpdmUgdXNlIG9mIGZsYXNoLgogKiBAcGFyYW1baW5dICAgYWRkciB0aGUgc3RhcnQgYWRkcmVzcyBvZiB0aGUgcGFnZQogKiBAcGFyYW1baW5dICAgTnVtYmVyIG9mIHNlY3RvcnMgdXNlZCB0byBzYXZlIHRoaXMgZGF0YSB0eXBlCiAqIEBwYXJhbVtpbl0gICBTcGFjZSBvY2N1cGllZCBieSBhIHBpZWNlIG9mIGRhdGEuTGVzcyB0aGFuIDI1NqOsCiAqIEByZXR1cm4gLTE6Tm8gZGF0YSBmb3VuZCxvdGhlcnM6YWRkcmVzcyBvZmZzZXQKICovCnMxNiBic2VhcmNoX3dpdGhvdXRfcmVjdXJzaW9uKHVuc2lnbmVkIGxvbmcgYWRkciwgdTggdXNlZF9zZWN0b3IsIHU4IHVzZWRfYmxvY2spCnsKICAgIHMxNiBsb3c9MCwgaGlnaD0oNCoxMDI0L3VzZWRfYmxvY2spKnVzZWRfc2VjdG9yIC0xOwogICAgdTggcmJ1ZlsyXTsKICAgIHU4IGNtcDFbXSA9IHtVMTZfTE8oRkxBU0hfRkxBRyksVTE2X0hJKEZMQVNIX0ZMQUcpfTsvL3sweGE1LDB4ZmZ9OwogICAgdTggY21wMltdID0gezB4MDAsMHgwMH07CiAgICB1OCBjbXAzW10gPSB7MHhmZiwweGZmfTsKICAgIHdoaWxlKGxvdzw9aGlnaCkKICAgIHsKICAgICAgICAvL0RFQlVHKCJsb3c6ICVkICBoaWdoOiAlZFxuIixsb3csaGlnaCk7CiAgICAgICAgczE2IG1pZD0obG93K2hpZ2gpLzI7CgogICAgICAgIGZsYXNoX3JlYWRfcGFnZShhZGRyICsgbWlkKnVzZWRfYmxvY2ssMixyYnVmKTsKICAgICAgICAvL3ByaW50ZigiYnNlYXJjaFdpdGhvdXRSZWN1cnNpb24gdG1wOiIpOwogICAgICAgIC8vYXJyYXlQcmludCh0bXAsMik7CiAgICAgICAgLy9wcmludGYoIlxuOiIpOwogICAgICAgIGlmKCFtZW1jbXAocmJ1ZiwgY21wMywgMikpICAgIGhpZ2ggPSBtaWQgLSAxOwogICAgICAgIGVsc2UgaWYoIW1lbWNtcChyYnVmLCBjbXAyLCAyKSkgICAgbG93ID0gbWlkICsgMTsKICAgICAgICBlbHNlIGlmKCFtZW1jbXAocmJ1ZiwgY21wMSwgMikpICAgICByZXR1cm4gbWlkOy8vcmV0dXJuIG1pZCp1c2VkX2Jsb2NrOwogICAgICAgIGVsc2UgcmV0dXJuIC0xOwogICAgfQogICAgcmV0dXJuIC0xOwp9CgovKioKICogQGJyaWVmIFRoaXMgZnVuY3Rpb24gY2FuIG1ha2UgbW9yZSBlZmZlY3RpdmUgdXNlIG9mIGZsYXNoLgogKiBAcGFyYW1baW5dICAgYWRkciB0aGUgc3RhcnQgYWRkcmVzcyBvZiB0aGUgcGFnZQogKiBAcGFyYW1baW5dICAgTnVtYmVyIG9mIHNlY3RvcnMgdXNlZCB0byBzYXZlIHRoaXMgZGF0YSB0eXBlCiAqIEBwYXJhbVtpbl0gICBTcGFjZSBvY2N1cGllZCBieSBhIHBpZWNlIG9mIGRhdGEuTGVzcyB0aGFuIDI1NqOsCiAqIEBwYXJhbVtpbl0gICBsZW4gdGhlIGxlbmd0aChpbiBieXRlKSBvZiBjb250ZW50IG5lZWRzIHRvIHJlYWQgb3V0IGZyb20gdGhlIHBhZ2UKICogQHBhcmFtW291dF0gIGJ1ZiB0aGUgc3RhcnQgYWRkcmVzcyBvZiB0aGUgYnVmZmVyCiAqIEByZXR1cm4gMDpTdWNjZXNzLDE6Zmxhc2ggaXMgZW1wdHksMjpzZWN0b3IgZGF0YSBlcnJvcgogKi8KdTggZmxhc2hfcG9zX2luZm8odW5zaWduZWQgbG9uZyBhZGRyLCB1OCB1c2VkX3NlY3RvciwgdTggdXNlZF9ibG9jayl7CiAgICB1OCByZXQgPSAwOwogICAgdTggYmVnaW5fZGF0YVsyXTsgICAgLy9iZWdpbm5pbmcgb2Ygc2VjdG9yIGRhdGEuYnl0ZSAwLDEgaXMgMXN0IHNlY3RvciBkYXRhLGJ5dGUgMiwzIGlzIDJuZCBzZWN0b3IgZGF0YS4KCiAgICBzMTYgaGlnaD0oNCoxMDI0L3VzZWRfYmxvY2spKnVzZWRfc2VjdG9yIC0xOwoKICAgIC8vUmVhZCB0aGUgYmVnaW5uaW5nIGFuZCBlbmQgZGF0YSBvZiB0aGUgMXN0IHNlY3RvcgogICAgZmxhc2hfcmVhZF9wYWdlKGFkZHIsIDIsIGJlZ2luX2RhdGEpOwogICAgLy9mbGFzaF9yZWFkX3BhZ2UoYWRkciwgMiwgZW5kX2RhdGEpOwoKICAgIHU4IGFsbGZmWzJdID0gezB4ZmYsMHhmZn07CgogICAgLyoqKiogIHN0YXJ0IGNoZWNrIGZsYXNoICAqKioqLwoKICAgIGlmKCFtZW1jbXAoYmVnaW5fZGF0YSwgYWxsZmYsIDIpKXsKICAgICAgICAvL2JlZ2lubmluZyBvZiAxc3Qgc2VjdG9yIGRhdGEoMmJ5dGUpIGlzIGFsbCAweGZmLgogICAgICAgIC8vSW5kaWNhdGVzIHdoZXRoZXIgdGhlIFJDVSBpcyBicmFuZCBuZXcgb3IgZmFjdG9yeSBzZXQKICAgICAgICByZXQgPSAxOyAgICAvL3JldHVybiAxOyAgICAvL05vIGRhdGEgaW4gZmxhc2gKICAgIH1lbHNlewoKICAgICAgICAvL3NlYXJjaCBkYXRhIGluIGZsYXNoCiAgICAgICAgczE2IG9mZnNldCA9IGJzZWFyY2hfd2l0aG91dF9yZWN1cnNpb24oYWRkcix1c2VkX3NlY3Rvcix1c2VkX2Jsb2NrKTsKICAgICAgICAvL3ByaW50Zigib2Zmc2V0PSV4IFxyXG4iLCAodTE2KW9mZnNldCk7CiAgICAgICAgaWYob2Zmc2V0ID09IC0xKXsKCiAgICAgICAgICAgIHJldCA9IDI7ICAgIC8vcmV0dXJuIDI7ICAgIC8vc2VjdG9yIGRhdGEgZXJyb3IKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgIGlmKG9mZnNldD4oaGlnaC8xMCo5KSkKICAgICAgICAgICAgICAgICByZXR1cm4gMzsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKCi8qKgogKiBAYnJpZWYgVGhpcyBmdW5jdGlvbiBjYW4gbWFrZSBtb3JlIGVmZmVjdGl2ZSB1c2Ugb2YgZmxhc2guCiAqIEBwYXJhbVtpbl0gICBhZGRyIHRoZSBzdGFydCBhZGRyZXNzIG9mIHRoZSBwYWdlCiAqIEBwYXJhbVtpbl0gICBOdW1iZXIgb2Ygc2VjdG9ycyB1c2VkIHRvIHNhdmUgdGhpcyBkYXRhIHR5cGUKICogQHBhcmFtW2luXSAgIFNwYWNlIG9jY3VwaWVkIGJ5IGEgcGllY2Ugb2YgZGF0YS5MZXNzIHRoYW4gMjU2o6wKICogQHBhcmFtW2luXSAgIGxlbiB0aGUgbGVuZ3RoKGluIGJ5dGUpIG9mIGNvbnRlbnQgbmVlZHMgdG8gcmVhZCBvdXQgZnJvbSB0aGUgcGFnZQogKiBAcGFyYW1bb3V0XSAgYnVmIHRoZSBzdGFydCBhZGRyZXNzIG9mIHRoZSBidWZmZXIKICogQHJldHVybiAwOlN1Y2Nlc3MsMTpmbGFzaCBpcyBlbXB0eSwyOnNlY3RvciBkYXRhIGVycm9yCiAqLwp1OCBmbGFzaF9yZWFkX2luZm8odW5zaWduZWQgbG9uZyBhZGRyLCB1OCB1c2VkX3NlY3RvciwgdTggdXNlZF9ibG9jaywgdW5zaWduZWQgbG9uZyBsZW4sIHU4ICpyYnVmKXsKICAgIHU4IHJldCA9IDA7CiAgICB1OCBiZWdpbl9kYXRhWzJdOyAgICAvL2JlZ2lubmluZyBvZiBzZWN0b3IgZGF0YS5ieXRlIDAsMSBpcyAxc3Qgc2VjdG9yIGRhdGEsYnl0ZSAyLDMgaXMgMm5kIHNlY3RvciBkYXRhLgogICAgLy9SZWFkIHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBkYXRhIG9mIHRoZSAxc3Qgc2VjdG9yCiAgICBmbGFzaF9yZWFkX3BhZ2UoYWRkciwgMiwgYmVnaW5fZGF0YSk7CiAgICAvL2ZsYXNoX3JlYWRfcGFnZShhZGRyLCAyLCBlbmRfZGF0YSk7CgogICAgdTggYWxsZmZbMl0gPSB7MHhmZiwweGZmfTsKCiAgICAvKioqKiAgc3RhcnQgY2hlY2sgZmxhc2ggICoqKiovCgogICAgaWYoIW1lbWNtcChiZWdpbl9kYXRhLCBhbGxmZiwgMikpewogICAgICAgIC8vYmVnaW5uaW5nIG9mIDFzdCBzZWN0b3IgZGF0YSgyYnl0ZSkgaXMgYWxsIDB4ZmYuCiAgICAgICAgLy9JbmRpY2F0ZXMgd2hldGhlciB0aGUgUkNVIGlzIGJyYW5kIG5ldyBvciBmYWN0b3J5IHNldAogICAgICAgIHJldCA9IDE7ICAgIC8vcmV0dXJuIDE7ICAgIC8vTm8gZGF0YSBpbiBmbGFzaAogICAgfWVsc2V7CgogICAgICAgIC8vc2VhcmNoIGRhdGEgaW4gZmxhc2gKICAgICAgICBzMTYgb2Zmc2V0ID0gYnNlYXJjaF93aXRob3V0X3JlY3Vyc2lvbihhZGRyLHVzZWRfc2VjdG9yLHVzZWRfYmxvY2spOwoKICAgICAgICBpZihvZmZzZXQgPT0gLTEpewoKICAgICAgICAgICAgcmV0ID0gMjsgICAgLy9yZXR1cm4gMjsgICAgLy9zZWN0b3IgZGF0YSBlcnJvcgogICAgICAgIH1lbHNlewoKICAgICAgICAgICAgZmxhc2hfcmVhZF9wYWdlKGFkZHIgKyBvZmZzZXQqdXNlZF9ibG9jaywgbGVuLCByYnVmKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKLyoqCiAqIEBicmllZiBUaGlzIGZ1bmN0aW9uIGNhbiBtYWtlIG1vcmUgZWZmZWN0aXZlIHVzZSBvZiBmbGFzaC4KICogQHBhcmFtW2luXSAgIGFkZHIgdGhlIHN0YXJ0IGFkZHJlc3Mgb2YgdGhlIHBhZ2UKICogQHBhcmFtW2luXSAgIE51bWJlciBvZiBzZWN0b3JzIHVzZWQgdG8gc2F2ZSB0aGlzIGRhdGEgdHlwZQogKiBAcGFyYW1baW5dICAgU3BhY2Ugb2NjdXBpZWQgYnkgYSBwaWVjZSBvZiBkYXRhLkxlc3MgdGhhbiAyNTajrAogKiBAcGFyYW1baW5dICAgbGVuIHRoZSBsZW5ndGgoaW4gYnl0ZSkgb2YgY29udGVudCBuZWVkcyB0byByZWFkIG91dCBmcm9tIHRoZSBwYWdlCiAqIEBwYXJhbVtvdXRdICBidWYgdGhlIHN0YXJ0IGFkZHJlc3Mgb2YgdGhlIGJ1ZmZlcgogKiBAcmV0dXJuIDA6U3VjY2VzcywxOmZsYXNoIGlzIGVtcHR5LDI6c2VjdG9yIGRhdGEgZXJyb3IsMzpyZWFkIGRhdGEgZXJyb3IKICovCnU4IGZsYXNoX3dyaXRlX2luZm8odW5zaWduZWQgbG9uZyBhZGRyLCB1OCB1c2VkX3NlY3RvciwgdTggdXNlZF9ibG9jaywgdW5zaWduZWQgbG9uZyBsZW4sIHU4ICp3YnVmICl7CgogICAgdTggcmV0ID0gMDsKICAgIHU4IGJlZ2luX2RhdGFbMl07ICAgIC8vYmVnaW5uaW5nIG9mIHNlY3RvciBkYXRhLmJ5dGUgMCwxIGlzIDFzdCBzZWN0b3IgZGF0YSxieXRlIDIsMyBpcyAybmQgc2VjdG9yIGRhdGEuCiAgICAvL3U4IGVuZF9kYXRhWzRdOyAgICAgICAgLy9lbmQgb2Ygc2VjdG9yIGRhdGEuYnl0ZSAwLDEgaXMgMXN0IHNlY3RvciBkYXRhLGJ5dGUgMiwzIGlzIDJuZCBzZWN0b3IgZGF0YS4KCiAgICAvL1JlYWQgdGhlIGJlZ2lubmluZyBhbmQgZW5kIGRhdGEgb2YgdGhlIDFzdCBzZWN0b3IKICAgIGZsYXNoX3JlYWRfcGFnZShhZGRyLCAyLCBiZWdpbl9kYXRhKTsKICAgIC8vZmxhc2hfcmVhZF9wYWdlKGFkZHIsIDIsIGVuZF9kYXRhKTsKCiAgICB1OCBhbGxmZlsyXSA9IHsweGZmLDB4ZmZ9OwoKICAgIC8qKioqICBzdGFydCBjaGVjayBmbGFzaCAgKioqKi8KCiAgICBpZighbWVtY21wKGJlZ2luX2RhdGEsIGFsbGZmLCAyKSl7CiAgICAgICAgLy9iZWdpbm5pbmcgb2YgMXN0IHNlY3RvciBkYXRhKDJieXRlKSBpcyBhbGwgMHhmZi4KICAgICAgICAvL0luZGljYXRlcyB3aGV0aGVyIHRoZSBSQ1UgaXMgYnJhbmQgbmV3IG9yIGZhY3Rvcnkgc2V0CiAgICAgICAgcmV0ID0gMTsgICAgLy9ObyBkYXRhIGluIGZsYXNoCiAgICB9ZWxzZXsKCiAgICAgICAgLy9zZWFyY2ggZGF0YSBpbiBmbGFzaAogICAgICAgIHMxNiBvZmZzZXQgPSBic2VhcmNoX3dpdGhvdXRfcmVjdXJzaW9uKGFkZHIsdXNlZF9zZWN0b3IsdXNlZF9ibG9jayk7CgogICAgICAgIGlmKG9mZnNldCA9PSAtMSl7CgogICAgICAgICAgICByZXQgPSAyOyAgICAvL3NlY3RvciBkYXRhIGVycm9yCiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIHU4IGNsclsyXSA9IHswfTsKICAgICAgICAgICAgZmxhc2hfd3JpdGVfcGFnZShhZGRyICsgb2Zmc2V0KnVzZWRfYmxvY2ssIDIsIGNscik7CgogICAgICAgICAgICAvL2lmKG9mZnNldCArIDEgPj0gNCoxMDI0KnVzZWRfc2VjdG9yL3VzZWRfYmxvY2spIG9mZnRzZXQgPSAtMTsgICAgLy8ybmQgc2VjdG9yIGlzIGZ1bGwuc28gc2V0IG9mZnNldCB0byBiZWdpbm5pbmcgb2YgMXN0IHNlY3RvcgogICAgICAgICAgICAvL3dyaXRlIGRhdGEgdG8gZmxhc2gKICAgICAgICAgICAgZmxhc2hfd3JpdGVfcGFnZShhZGRyICsgKG9mZnNldCArIDEpKnVzZWRfYmxvY2ssIGxlbiwgd2J1Zik7CiAgICAgICAgICAgIC8vQ29uZmlybSB0aGF0IHdyaXRpbmcgZGF0YSBpcyBjb3JyZWN0CiAgICAgICAgICAgIC8vdTggdGVtcFsyNTZdID0gezB9OwogICAgICAgICAgICB1OCB0ZW1wWzE2XSA9IHswfTsKICAgICAgICAgICAgZmxhc2hfcmVhZF9wYWdlKGFkZHIgKyAob2Zmc2V0ICsgMSkqdXNlZF9ibG9jaywgbGVuLCB0ZW1wKTsKICAgICAgICAgICAgaWYobWVtY21wKHdidWYsIHRlbXAsIGxlbikpICAgICByZXQgPSAzOyAgICAvL1RoZSBkYXRhIHdyaXR0ZW4gYW5kIHJlYWQgZG9lcyBub3QgbWF0Y2gKICAgICAgICB9CiAgICB9CgogICAgc3dpdGNoKHJldCl7CiAgICAgICAgY2FzZSAzOgogICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxOgogICAgICAgIHsKICAgICAgICAgICAgZmxhc2hfd3JpdGVfcGFnZShhZGRyLCBsZW4sIHdidWYpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCnZvaWQgZmxhc2hfY2hlY2tfYXJlYSh1bnNpZ25lZCBsb25nIGFkZHIsIHU4IHVzZWRfc2VjdG9yLCB1OCB1c2VkX2Jsb2NrLCB1bnNpZ25lZCBsb25nIGxlbil7CgoKICAgIHU4IGJlZ2luX2RhdGFbMl07ICAgIC8vYmVnaW5uaW5nIG9mIHNlY3RvciBkYXRhLmJ5dGUgMCwxIGlzIDFzdCBzZWN0b3IgZGF0YSxieXRlIDIsMyBpcyAybmQgc2VjdG9yIGRhdGEuCiAgICB1OCBhbGxmZlsyXSA9IHsweGZmLDB4ZmZ9OwogICAgLy9SZWFkIHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBkYXRhIG9mIHRoZSAxc3Qgc2VjdG9yCiAgICBmbGFzaF9yZWFkX3BhZ2UoYWRkciwgMiwgYmVnaW5fZGF0YSk7CgogICAgaWYoIW1lbWNtcChiZWdpbl9kYXRhLCBhbGxmZiwgMikpewogICAgICAgIC8vYmVnaW5uaW5nIG9mIDFzdCBzZWN0b3IgZGF0YSgyYnl0ZSkgaXMgYWxsIDB4ZmYuCiAgICAgICAgLy9JbmRpY2F0ZXMgd2hldGhlciB0aGUgUkNVIGlzIGJyYW5kIG5ldyBvciBmYWN0b3J5IHNldAogICAgICAgIHJldHVybjsKICAgIH0KCgogICAgczE2IG9mZnNldCA9IGJzZWFyY2hfd2l0aG91dF9yZWN1cnNpb24oYWRkcix1c2VkX3NlY3Rvcix1c2VkX2Jsb2NrKTsKICAgIGlmKG9mZnNldCA9PSAtMSl7CiAgICAgICAgLy9zZWN0b3IgZGF0YSBlcnJvcgogICAgICAgIGZvcih1OCBpPTA7aTx1c2VkX3NlY3RvcjtpKyspewogICAgICAgICAgICBmbGFzaF9lcmFzZV9zZWN0b3IoYWRkcitpKjB4MTAwMCk7CiAgICAgICAgfQogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvL0lmIHRoZSBhcmVhIHVzYWdlIGV4Y2VlZHMgNzAlLCBlcmFzZSB0aGUgYXJlYQovLyAgICBpZihvZmZzZXQgPiAoNCoxMDI0L3VzZWRfYmxvY2spKnVzZWRfc2VjdG9yLzEwKjgpewovLyAgICAgICAgdTggcmJ1ZlsyNTZdID0gezB9OwovLyAgICAgICAgZmxhc2hfcmVhZF9wYWdlKGFkZHIgKyBvZmZzZXQqdXNlZF9ibG9jayxsZW4scmJ1Zik7Ci8vICAgICAgICAvL2ZsYXNoX3JlYWRfcGFnZShhZGRyICsgb2Zmc2V0KnVzZWRfYmxvY2ssdXNlZF9ibG9jayxyYnVmKTsKLy8gICAgICAgIGZvcih1OCBpPTA7aTx1c2VkX3NlY3RvcjtpKyspewovLyAgICAgICAgICAgIGZsYXNoX2VyYXNlX3NlY3RvcihhZGRyK2kqMHgxMDAwKTsKLy8gICAgICAgIH0KLy8gICAgICAgIC8vTW92ZSB0aGUgZGF0YSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSAyc3Qgc2VjdG9yCi8vICAgICAgICBmbGFzaF93cml0ZV9wYWdlKGFkZHIsbGVuLHJidWYpOwovLyAgICAgICAgLy9mbGFzaF93cml0ZV9wYWdlKGFkZHIsdXNlZF9ibG9jayxyYnVmKTsKLy8gICAgfQp9CgoKdm9pZCB3cml0ZV9jY2NfaW5mbyh1OCAqY2NjKXsKCiAgICB1OCBkYXRbNF0gPXsweEE1LDB4RkYsMHhGRiwweEZGfTsKICAgIG1lbWNweShkYXQrMixjY2MsMSk7CiAgICB1OCByZXQgPSBmbGFzaF93cml0ZV9pbmZvKENDQ19EQVRBX0FSRUEsMSw0LDMsZGF0KTsKICAgIHByaW50Zigid3JpdGVfY2NjX2luZm86MHgleCIscmV0KTsKfQoKdTggcmVhZF9jY2NfaW5mbyh1OCAqY2NjKXsKCiAgICB1OCBkYXRbNF0gPXswfTsKICAgIHU4IHJldCA9IGZsYXNoX3JlYWRfaW5mbyhDQ0NfREFUQV9BUkVBLDEsNCwzLGRhdCk7CiAgICBpZighcmV0KXsKICAgICAgICBjY2NbMF0gPSBkYXRbMl07CiAgICB9CiAgICAvL3JldHVybiAwOlN1Y2Nlc3MsMTpmbGFzaCBpcyBlbXB0eSwyOnNlY3RvciBkYXRhIGVycm9yCiAgICByZXR1cm4gcmV0Owp9CgpleHRlcm4gdTE2IGF0dl9jaGFyX2N0bF9jY2M7CmV4dGVybiB1MTYgYXR2X2NoYXJfcnhfY2NjOwoKdm9pZCBpbml0X2NjY192YWx1ZSgpewoKICAgIHJlYWRfY2NjX2luZm8oJmZsYWdfY2NjX2RhdGEpOwoKICAgIGF0dl9jaGFyX2N0bF9jY2MgPSAoZmxhZ19jY2NfZGF0YSAmIEZMQUdfR09PR0xFX0NUTF9DQ0MpPzE6MDsKICAgIGF0dl9jaGFyX3J4X2NjYyA9IChmbGFnX2NjY19kYXRhICYgRkxBR19HT09HTEVfUlhfQ0NDKT8xOjA7CgogICAgcHJpbnRmKCJhdHZfY2hhcl9jdGxfY2NjOiVkXG4iLGF0dl9jaGFyX2N0bF9jY2MpOwogICAgcHJpbnRmKCJhdHZfY2hhcl9yeF9jY2M6JWRcbiIsYXR2X2NoYXJfcnhfY2NjKTsKfQoKCnZvaWQgaXNfZmxhc2hfaW5mb19mdWxsKHZvaWQpCnsKICAgIGlmKGZsYXNoX3Bvc19pbmZvKENDQ19EQVRBX0FSRUEsMSw0KSA9PSAweDAzKQogICAgewogICAgICAgIGZsYXNoX2VyYXNlX3NlY3RvcihDQ0NfREFUQV9BUkVBKTsKICAgICAgICB3cml0ZV9jY2NfaW5mbygmZmxhZ19jY2NfZGF0YSk7CiAgICB9Cn0KCnZvaWQgd3JpdGVfcGVlcl9tYWNfaW5mbyh1OCAqbWFjKXsKCiAgICB1OCBkYXRbOF0gPXsweEE1LDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkZ9OwogICAgbWVtY3B5KGRhdCsyLG1hYyw2KTsKICAgIHU4IHJldCA9IGZsYXNoX3dyaXRlX2luZm8oTUFDX0RBVEFfU0VDVF9BRERSLDEsOCw4LGRhdCk7CiAgICBwcmludGYoIndyaXRlX21hY19pbmZvOjB4JXhcclxuIixyZXQpOwp9Cgp1OCByZWFkX3BlZXJfbWFjX2luZm8odTggKm1hYyl7CgogICAgdTggZGF0WzhdID17MH07CiAgICB1OCByZXQgPSBmbGFzaF9yZWFkX2luZm8oTUFDX0RBVEFfU0VDVF9BRERSLDEsOCw4LGRhdCk7CiAgICBpZighcmV0KXsKICAgICAgICBmb3IodTggaT0wO2k8NjtpKyspCiAgICAgICAgICAgIG1hY1tpXSA9IGRhdFsyK2ldOwogICAgfQogICAgLy9yZXR1cm4gMDpTdWNjZXNzLDE6Zmxhc2ggaXMgZW1wdHksMjpzZWN0b3IgZGF0YSBlcnJvcgogICAgcmV0dXJuIHJldDsKfQoKdTggaXNfcGVlcl9tYWNfZmxhc2hfaW5mb19mdWxsKHZvaWQpCnsKICAgIGlmKGZsYXNoX3Bvc19pbmZvKE1BQ19EQVRBX1NFQ1RfQUREUiwxLDgpID09IDB4MDMpCiAgICB7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKdm9pZCBpbml0X3BlZXJfbWFjKHZvaWQpCnsKICAgIHU4IGk7CiAgICB1OCBkYXQ7CiAgICBmb3IoaT0wO2k8NTtpKyspCiAgICB7CiAgICAgICAgZGF0ID0gcmVhZF9wZWVyX21hY19pbmZvKHBlZXJfbWFjKTsKICAgICAgICBpZihkYXQgPT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHByaW50ZigicGVlcl9tYWMgPVxyXG4iKTsKICAgICAgICAgICAgZm9yKHU4IGk9MDtpPDY7aSsrKQogICAgICAgICAgICAgICAgcHJpbnRmKCIgJXgiLHBlZXJfbWFjW2ldKTsKICAgICAgICAgICAgIHByaW50ZigiXHJcbiIpOwogICAgICAgICAgICBpZihpc19wZWVyX21hY19mbGFzaF9pbmZvX2Z1bGwoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZmxhc2hfZXJhc2Vfc2VjdG9yKE1BQ19EQVRBX1NFQ1RfQUREUik7CiAgICAgICAgICAgICAgICB3cml0ZV9wZWVyX21hY19pbmZvKHBlZXJfbWFjKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZihkYXQgPT0gMSkKICAgICAgICB7CiAgICAgICAgICAgIHByaW50Zigibm9fcGVlcl9tYWNcclxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KfQoKdm9pZCB3cml0ZV93YWtldXBfa2V5aW5kZXhfaW5mbyh1OCBpbmRleCl7CgogICAgdTggZGF0WzRdID17MHhBNSwweGZmLDB4ZmYsMHhmZn07CgogICAgZGF0WzJdID0gaW5kZXg7CiAgICB1OCByZXQgPSBmbGFzaF93cml0ZV9pbmZvKFdBS0VVUF9LRVlJTkRFWF9EQVRBX1NFQ1RfQUREUiwyLDQsMyxkYXQpOwogICAgcHJpbnRmKCJ3cml0ZV93YWtldXBfa2V5aW5kZXhfaW5mbzoweCV4XHJcbiIscmV0KTsKfQoKdTggcmVhZF93YWtldXBfa2V5aW5kZXhfaW5mbyh1OCAqaW5kZXgpewoKICAgIHU4IGRhdFs0XSA9ezB9OwogICAgdTggcmV0ID0gZmxhc2hfcmVhZF9pbmZvKFdBS0VVUF9LRVlJTkRFWF9EQVRBX1NFQ1RfQUREUiwyLDQsMyxkYXQpOwogICAgaWYoIXJldCl7CiAgICAgICAgKmluZGV4ID0gZGF0WzJdOwogICAgfQogICAgLy9yZXR1cm4gMDpTdWNjZXNzLDE6Zmxhc2ggaXMgZW1wdHksMjpzZWN0b3IgZGF0YSBlcnJvcgogICAgcmV0dXJuIHJldDsKfQoKdTggaXNfd2FrZXVwX2tleWluZGV4X2ZsYXNoX2luZm9fZnVsbCh2b2lkKQp7CiAgICBpZihmbGFzaF9wb3NfaW5mbyhXQUtFVVBfS0VZSU5ERVhfREFUQV9TRUNUX0FERFIsMiw0KSA9PSAweDAzKQogICAgewogICAgICAgIHJldHVybiAxOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCnZvaWQgaW5pdF93YWtldXBfa2V5aW5kZXgodm9pZCkKewogICAgdTggaW5kZXg9MDsKICAgIGlmKHJlYWRfd2FrZXVwX2tleWluZGV4X2luZm8oJmluZGV4KSA9PSAwKQogICAgewogICAgICAgIGlmKGlzX3dha2V1cF9rZXlpbmRleF9mbGFzaF9pbmZvX2Z1bGwoKSkKICAgICAgICB7CiAgICAgICAgICAgIGZsYXNoX2VyYXNlX3NlY3RvcihXQUtFVVBfS0VZSU5ERVhfREFUQV9TRUNUX0FERFIpOwogICAgICAgICAgICBmbGFzaF9lcmFzZV9zZWN0b3IoV0FLRVVQX0tFWUlOREVYX0RBVEFfU0VDVF9BRERSKzB4MTAwMCk7CiAgICAgICAgICAgIHdyaXRlX3dha2V1cF9rZXlpbmRleF9pbmZvKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcHJpbnRmKCJ3YWtldXBfa2V5aW5kZXg9JXhcclxuIixpbmRleCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgcHJpbnRmKCJub193YWtldXBfa2V5aW5kZXhcclxuIik7CiAgICB9ICAgIAp9Cgp2b2lkIHdyaXRlX2lyX2tleV9ldmVudF9ub3RpZnkodTggaW5kZXgpewoKICAgIHU4IGRhdFs0XSA9ezB4QTUsMHhmZiwweGZmLDB4ZmZ9OwoKICAgIGRhdFsyXSA9IGluZGV4OwogICAgdTggcmV0ID0gZmxhc2hfd3JpdGVfaW5mbyhJUl9LRVlfRVZFTlRfTk9USUZZX1NFQ1RfQUREUiwxLDQsMyxkYXQpOwogICAgcHJpbnRmKCJ3cml0ZV9pcl9rZXlfZXZlbnRfbm90aWZ5IGluZGV4ID0leCxyZXQ9MHgleFxyXG4iLGluZGV4LHJldCk7Cn0KCnU4IHJlYWRfaXJfa2V5X2V2ZW50X25vdGlmeSh1OCAqaW5kZXgpewoKICAgIHU4IGRhdFs0XSA9ezB9OwogICAgdTggcmV0ID0gZmxhc2hfcmVhZF9pbmZvKElSX0tFWV9FVkVOVF9OT1RJRllfU0VDVF9BRERSLDEsNCwzLGRhdCk7CiAgICBpZighcmV0KXsKICAgICAgICAqaW5kZXggPSBkYXRbMl07CiAgICB9CiAgICAvL3JldHVybiAwOlN1Y2Nlc3MsMTpmbGFzaCBpcyBlbXB0eSwyOnNlY3RvciBkYXRhIGVycm9yCiAgICByZXR1cm4gcmV0Owp9Cgp1OCBpc19pcl9rZXlfZXZlbnRfbm90aWZ5X2ZsYXNoX2luZm9fZnVsbCh2b2lkKQp7CiAgICBpZihmbGFzaF9wb3NfaW5mbyhJUl9LRVlfRVZFTlRfTk9USUZZX1NFQ1RfQUREUiwxLDQpID09IDB4MDMpCiAgICB7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKdTggaW5pdF9pcl9rZXlfZXZlbnRfbm90aWZ5KHZvaWQpCnsKICAgIHU4IGluZGV4PTB4ZmY7CiAgICBpZihyZWFkX2lyX2tleV9ldmVudF9ub3RpZnkoJmluZGV4KSA9PSAwKQogICAgewogICAgICAgIGlmKGlzX2lyX2tleV9ldmVudF9ub3RpZnlfZmxhc2hfaW5mb19mdWxsKCkpCiAgICAgICAgewogICAgICAgICAgICBmbGFzaF9lcmFzZV9zZWN0b3IoSVJfS0VZX0VWRU5UX05PVElGWV9TRUNUX0FERFIpOwogICAgICAgICAgICB3cml0ZV9pcl9rZXlfZXZlbnRfbm90aWZ5KGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcHJpbnRmKCJpcl9rZXlfZXZlbnRfbm90aWZ5IGNjYz0leFxyXG4iLGluZGV4KTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBwcmludGYoIm5vIGlyX2tleV9ldmVudF9ub3RpZnlcclxuIik7CiAgICB9CiAgICByZXR1cm4gaW5kZXg7Cn0KCgoK