ZGlmZiAtLWdpdCBhL3N0ZC9yb29tL2NvbW1hbmRzLmMgYi9zdGQvcm9vbS9jb21tYW5kcy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVhYTc1YzMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcm9vbS9jb21tYW5kcy5jCkBAIC0wLDAgKzEsMzcgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyByb29tL2NvbW1hbmRzLmMgLS0gcm9vbSBjb21tYW5kcyBoYW5kbGluZworLy8KKy8vICRJZDogY29tbWFuZHMuYyA4MjAxIDIwMTItMTEtMDcgMTc6NTU6MTJaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisKK2luaGVyaXQgIi9zdGQvdGhpbmcvY29tbWFuZHMiOworCisvLyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8Y29uZmlnLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorCit2b2lkIGluaXQoKSAKK3sKKyAgOjppbml0KCk7CisKKyAgYWRkX2FjdGlvbigiaW1wb3NzIiwgInN1Y2giKTsKKyAgYWRkX2FjdGlvbigiaW1wb3NzIiwgInN1Y2hlIik7Cit9CisKKy8qIEZ1ZXIgZXR3YXMgYmVzc2VyZSBGZWhsZXJtZWxkdW5nZW4gYWxzICdXaWUgYml0dGU/JyBiZWkgZWluaWdlbiAqLworLyogYWxsZ2VtZWluZW4gS29tbWFuZG9zLgkJCQkJICAgKi8KK2ludCBpbXBvc3MoKQoreworICBfbm90aWZ5X2ZhaWwoIkR1IHN1Y2hzdCwgZmluZGVzdCBhYmVyIG5pY2h0cy5cbiIpOworICByZXR1cm4gMDsKK30KZGlmZiAtLWdpdCBhL3N0ZC9yb29tL2Rlc2NyaXB0aW9uLmMgYi9zdGQvcm9vbS9kZXNjcmlwdGlvbi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwZDNiMjgKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcm9vbS9kZXNjcmlwdGlvbi5jCkBAIC0wLDAgKzEsMjIyIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcm9vbS9kZXNjcmlwdGlvbi5jIC0tIHJvb20gZGVzY3JpcHRpb24gaGFuZGxpbmcKKy8vCisvLyAkSWQ6IGRlc2NyaXB0aW9uLmMgOTQ2OCAyMDE2LTAyLTE5IDIxOjA3OjA0WiBHbG9pbnNvbiAkCisKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKworaW5oZXJpdCAiL3N0ZC9jb250YWluZXIvZGVzY3JpcHRpb24iOworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxsYW5ndWFnZS5oPgorI2luY2x1ZGUgPGRvb3Jyb29tLmg+CisKK3ZvaWQgY3JlYXRlKCkKK3sKKyAgOjpjcmVhdGUoKTsKKyAgU2V0UHJvcChQX05BTUUsICJSYXVtIik7CisgIFNldFByb3AoUF9JTlRfU0hPUlQsIjxuYW1lbmxvc2VyIFJhdW0+Iik7CisgIFNldFByb3AoUF9JTlRfTE9ORywwKTsKKyAgU2V0UHJvcChQX1JPT01fTVNHLCAoe30pICk7CisgIFNldFByb3AoUF9GVU5DX01TRywgMCk7CisgIFNldFByb3AoUF9NU0dfUFJPQiwgMzApOworICBBZGRJZCgoeyJyYXVtIiwgImhpZXIifSkpOworfQorCit2b2lkIGluaXQoKQoreworICAvLyBXZW5uIFBfUk9PTV9NU0cgZ2VzZXR6dCBvZGVyIFBfRlVOQ19NU0cgdW5kIGtlaW4gQ2FsbG91dCBsYWV1ZnQsCisgIC8vIENhbGxvdXQgc3RhcnRlbi4KKyAgbWl4ZWQgcm9vbW1zZyA9IFF1ZXJ5UHJvcChQX1JPT01fTVNHKTsKKyAgaWYoICggKHJvb21tc2cgJiYgc2l6ZW9mKHJvb21tc2cpKSB8fAorICAgICAgICBRdWVyeVByb3AoUF9GVU5DX01TRykgKSAmJgorICAgICAgKGZpbmRfY2FsbF9vdXQoIldyaXRlUm9vbU1lc3NhZ2UiKT09LTEpKQorICAgIGNhbGxfb3V0KCJXcml0ZVJvb21NZXNzYWdlIiwgcmFuZG9tKFF1ZXJ5UHJvcChQX01TR19QUk9CKSkpOworfQorCit2YXJhcmdzIHZvaWQgQWRkUm9vbU1lc3NhZ2Uoc3RyaW5nICptZXNnLCBpbnQgcHJvYiwgbWl4ZWQgZnVuYykKK3sKKyAgaWYgKG1lc2cgJiYgIXBvaW50ZXJwKG1lc2cpKQorICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAiQWRkUm9vbU1lc3NhZ2UoKTogd3JvbmcgYXJndW1lbnQgdHlwZSwgZXhwZWN0ZWQgQXJyYXkgb3IgMCwgIgorICAgICAgImdvdCAlLjIwTyIsbWVzZykpOworCisgICBTZXRQcm9wKFBfUk9PTV9NU0csIG1lc2cpOworCisgIGlmIChwcm9iPjApCisgICAgU2V0UHJvcChQX01TR19QUk9CLCBwcm9iKTsKKworICBpZiAoZnVuYykKKyAgICBTZXRQcm9wKFBfRlVOQ19NU0csIGZ1bmMpOworfQorCitzdGF0aWMgdm9pZCBXcml0ZVJvb21NZXNzYWdlKCkKK3sKKyAgaW50IHRpbSwgbXNnaWQ7CisgIHN0cmluZyAqcm9vbV9tc2csZnVuYzsKKyAgbWl4ZWQgKmZ1bmNfbXNnOworCisgIHJvb21fbXNnID0gKHN0cmluZyAqKVF1ZXJ5UHJvcChQX1JPT01fTVNHKTsKKyAgZnVuY19tc2cgPSBRdWVyeVByb3AoUF9GVU5DX01TRyk7CisgIGlmICgoIXJvb21fbXNnIHx8ICFzaXplb2Yocm9vbV9tc2cpKSAmJiAhZnVuY19tc2cpCisgICAgcmV0dXJuOworCisgIGlmIChyb29tX21zZyYmc2l6ZW9mKHJvb21fbXNnKSkKKyAgeworICAgIG1zZ2lkID0gcmFuZG9tKHNpemVvZihyb29tX21zZykpOworICAgIC8vIERlZmF1bHR3ZXJ0ZSBzaW5kIGZ1ZXIgQWx0Y29kZSBzY2h3aWVyaWcKKyAgICBzZW5kX3Jvb20odGhpc19vYmplY3QoKSwgcm9vbV9tc2dbbXNnaWRdLAorICAgICAgICAgICAgICBNVF9MT09LfE1UX0xJU1RFTnxNVF9GRUVMfE1UX1NNRUxMfAorICAgICAgICAgICAgICBNU0dfRE9OVF9TVE9SRXxNU0dfRE9OVF9CVUZGRVJ8TVNHX0RPTlRfV1JBUCk7CisgIH0KKworICBpZiAoZnVuY19tc2cpCisgIHsKKyAgICBpZiAoc3RyaW5ncChmdW5jX21zZykpCisgICAgICBmdW5jPShzdHJpbmcpZnVuY19tc2c7CisgICAgZWxzZQorICAgICAgZnVuYz1mdW5jX21zZ1tyYW5kb20oc2l6ZW9mKGZ1bmNfbXNnKSldOworICAgIGlmIChmdW5jICYmIGZ1bmN0aW9uX2V4aXN0cyhmdW5jKSkKKyAgICAgIGNhbGxfb3RoZXIgKHRoaXNfb2JqZWN0KCksIGZ1bmMsIG1zZ2lkKTsKKyAgfQorCisgIHdoaWxlIChyZW1vdmVfY2FsbF9vdXQoIldyaXRlUm9vbU1lc3NhZ2UiKSE9LTEpOworICB0aW09UXVlcnlQcm9wKFBfTVNHX1BST0IpOworICBpZih0aGlzX29iamVjdCgpICYmIHNpemVvZihmaWx0ZXIoCisgICAgICAgZGVlcF9pbnZlbnRvcnkodGhpc19vYmplY3QoKSksICMnaW50ZXJhY3RpdmUpKSkgLy8nKSkpCisgICAgY2FsbF9vdXQoIldyaXRlUm9vbU1lc3NhZ2UiLCAodGltPDE1ID8gMTUgOiB0aW0pKTsKK30KKwordmFyYXJncyBzdHJpbmcgaW50X2xvbmcobWl4ZWQgdmlld2VyLG1peGVkIHZpZXdwb2ludCxpbnQgZmxhZ3MpCit7CisgIHN0cmluZyBkZXNjciwgaW52X2Rlc2NyOworCisgIGZsYWdzICY9IDM7CisgIGlmKCBJU19MRUFSTkVSKHZpZXdlcikgJiYgdmlld2VyLT5RdWVyeVByb3AoIFBfV0FOVFNfVE9fTEVBUk4gKSApCisgICAgZGVzY3IgPSAiWyIgKyBvYmplY3RfbmFtZShNRSkgKyAiXVxuIjsKKyAgZWxzZQorICAgIGRlc2NyID0gIiI7CisKKyAgZGVzY3IgKz0gcHJvY2Vzc19zdHJpbmcoUXVlcnlQcm9wKFBfSU5UX0xPTkcpfHwiIik7CisgIAorICAvLyBnZ2YuIFR1ZXJlbiBoaW56dWZ1ZWdlbi4KKyAgaWYgKFF1ZXJ5UHJvcChQX0RPT1JfSU5GT1MpKSB7CisgICAgc3RyaW5nIHRtcD0oKHN0cmluZyljYWxsX290aGVyKERPT1JfTUFTVEVSLCJsb29rX2Rvb3JzIikpOworICAgIGlmIChzdHJpbmdwKHRtcCkgJiYgc2l6ZW9mKHRtcCkpCisgICAgICAgIGRlc2NyICs9IHRtcDsKKyAgfQorICAKKyAgLy8gZ2dmLiBBdXNnYWVuZ2UgaGluenVmdWVnZW4uCisgIGlmICggdmlld2VyLT5RdWVyeVByb3AoUF9TSE9XX0VYSVRTKSAmJiAoIVF1ZXJ5UHJvcChQX0hJREVfRVhJVFMpIAorCXx8IHBvaW50ZXJwKFF1ZXJ5UHJvcChQX0hJREVfRVhJVFMpKSkgKQorICAgIGRlc2NyICs9IEdldEV4aXRzKHZpZXdlcikgfHwgIiI7CisKKyAgLy8gVmlld3BvaW50IChPYmpla3Qgb2RlciBPYmpla3RhcnJheSkgc2luZCBuaWNodCBzaWNodGJhcgorICBpbnZfZGVzY3IgPSAoc3RyaW5nKSBtYWtlX2ludmxpc3Qodmlld2VyLCBhbGxfaW52ZW50b3J5KE1FKSAKKwkJICAtIChwb2ludGVycCh2aWV3cG9pbnQpP3ZpZXdwb2ludDooe3ZpZXdwb2ludH0pKSAsZmxhZ3MpOworCisgIGlmICggaW52X2Rlc2NyICE9ICIiICkKKyAgICBkZXNjciArPSBpbnZfZGVzY3I7CisKKyAgaWYoZW52aXJvbm1lbnQoKSAmJiAoaW52X2Rlc2NyPVF1ZXJ5UHJvcChQX1RSQU5TUEFSRU5UKSkpCisgIHsKKyAgICBpZihzdHJpbmdwKGludl9kZXNjcikpIGRlc2NyICs9IGludl9kZXNjcjsKKyAgICBlbHNlICAgICAgICAgICAgICAgICAgIGRlc2NyICs9ICJBdXNzZXJoYWxiIHNpZWhzdCBEdTpcbiI7CisgICAgICAgICAgICAKKyAgICBkZXNjciArPSBlbnZpcm9ubWVudCgpLT5pbnRfc2hvcnQodmlld2VyLE1FKTsKKyAgfQorICAgICAgICAgICAgICAgICAgCisgIHJldHVybiBkZXNjcjsKK30KKworc3RyaW5nIGludF9zaG9ydChtaXhlZCB2aWV3ZXIsbWl4ZWQgdmlld3BvaW50KQoreworICBzdHJpbmcgZGVzY3IsIGludl9kZXNjcjsKKworICBkZXNjciA9IHByb2Nlc3Nfc3RyaW5nKCBRdWVyeVByb3AoUF9JTlRfU0hPUlQpfHwiIik7CisgIGlmKCBJU19MRUFSTkVSKHZpZXdlcikgJiYgdmlld2VyLT5RdWVyeVByb3AoIFBfV0FOVFNfVE9fTEVBUk4gKSApCisgICAgZGVzY3IgKz0gIiBbIiArIG9iamVjdF9uYW1lKE1FKSArICJdLlxuIjsKKyAgZWxzZQorICAgIGRlc2NyICs9ICIuXG4iOworCisgIGlmICggKCB2aWV3ZXItPlF1ZXJ5UHJvcChQX1NIT1dfRVhJVFMpCisgICAgICAgICB8fCAoIGVudmlyb25tZW50KHZpZXdlcikgPT0gTUUgJiYgIXZpZXdlci0+UXVlcnlQcm9wKFBfQlJJRUYpICkgKQorICAgICAgICYmICghUXVlcnlQcm9wKFBfSElERV9FWElUUykgfHwgcG9pbnRlcnAoUXVlcnlQcm9wKFBfSElERV9FWElUUykpKSApCisgICAgZGVzY3IgKz0gR2V0RXhpdHModmlld2VyKSB8fCAiIjsKKyAgCisgIC8vIFZpZXdwb2ludCAoT2JqZWt0IG9kZXIgT2JqZWt0YXJyYXkpIHNpbmQgbmljaHQgc2ljaHRiYXIKKyAgaW52X2Rlc2NyID0gKHN0cmluZykgbWFrZV9pbnZsaXN0KCB2aWV3ZXIsIGFsbF9pbnZlbnRvcnkoTUUpIAorCQkgIC0gKHBvaW50ZXJwKHZpZXdwb2ludCk/dmlld3BvaW50Oih7dmlld3BvaW50fSkpICk7CisKKyAgaWYgKCBpbnZfZGVzY3IgIT0gIiIgKQorICAgIGRlc2NyICs9IGludl9kZXNjcjsKKworICByZXR1cm4gZGVzY3I7Cit9CisKKy8qKiBSb29tbWVzc2FnZXMgYWJzY2hhbHRlbiwgd2VubiBrZWluZSBJbnRlcmFjdGl2ZXMgbWVociBkYSBzaW5kLgorICAqLworLy8gVE9ETzogSXJnZW5kd2FubiBkYXMgdmFyYXJncyBsb3N3ZXJkZW4sIHdlbm4gaW4gZGVyIHJlc3RsaWNoZW4gTXVkbGliCisvLyBUT0RPOjpleGl0KCkgJ3JpY2h0aWcnIHVlYmVyc2NocmllYmVuIHdpcmQuCit2YXJhcmdzIHZvaWQgZXhpdChvYmplY3QgbGl2LCBvYmplY3QgZGVzdCkgeworICAvLyBmYWxsIGVyYmVuZGUgT2JqZWt0ZSBkYXMgbGl2IG5pY2h0IHVlYmVyZ2ViZW4uIFBydWVmdW5nIG51ciBhdWYKKyAgLy8gcHJldmlvdXNfb2JqZWN0KCkuIFdlbm4gTWFnaWVyIGRhIG5vY2ggaXJnZW5kd2VsY2hlIFNwaWVsY2hlbiBtaXQKKyAgLy8gY2FsbF9vdGhlcigpICYgQ28gdHJlaWJlbiwgaGFiZW4gd2lyIFBlY2ggZ2VoYWJ0LCBtYWNodCBhYmVyIG5pY2h0IHZpZWwsCisgIC8vIHdlaWwgZGllIFJhdW1tZWxkdW5nZW4gZGFubiBpbSBuYWVjaHN0ZW4gY2FsbG91dCBhYmdlc2NoYWx0ZXQgd2VyZGVuLgorICBpZiAoIWxpdmluZyhsaXY9cHJldmlvdXNfb2JqZWN0KCkpKSByZXR1cm47CisKKyAgb2JqZWN0ICppbnRlcmFjdGl2ZXMgPSBmaWx0ZXIoYWxsX2ludmVudG9yeSgpLCAjJ2ludGVyYWN0aXZlKTsKKyAgLy8gbGl2IHd1cmRlIG5vY2ggbmljaHQgYmV3ZWd0LCBnZ2YuIGJlcnVlY2tzaWNodGlnZW4uCisgIGlmICggIXNpemVvZihpbnRlcmFjdGl2ZXMpIHx8CisgICAgICAoaW50ZXJhY3RpdmUobGl2KSAmJiBzaXplb2YoaW50ZXJhY3RpdmVzKSA8IDIpICkKKyAgICB3aGlsZSAocmVtb3ZlX2NhbGxfb3V0KCJXcml0ZVJvb21NZXNzYWdlIikhPS0xKTsKK30KKworc3RhdGljIHN0cmluZyBfcXVlcnlfaW50X2xvbmcoKSB7cmV0dXJuIFF1ZXJ5KFBfSU5UX0xPTkcsIEZfVkFMVUUpO30KKworCisvLyBRdWVyeW1ldGhvZGUgZnVlciBQX0RPTUFJTiAtIGdpYnQgZGllIFJlZ2lvbiBhbiwgaW4gZGVyIFJhdW0gbGllZ3QsIHNvZmVybgorLy8gZXIgdW50ZXIgL2QvIGxpZWd0Li4uCitzdGF0aWMgc3RyaW5nIF9xdWVyeV9saWJfcF9kb21haW4oKQoreworICBzdHJpbmcgZm4gPSBvYmplY3RfbmFtZSgpOworICBpZiAoc3Ryc3RyKGZuLCAiL2QvIikgPT0gMCkKKyAgeworICAgIHJldHVybiBjYXBpdGFsaXplKGV4cGxvZGUoZm4sICIvIilbMl0pOworICB9CisKKyAgcmV0dXJuICJ1bmJla2FubnQiOworfQorCis8c3RyaW5nfHN0cmluZyo+KiBfc2V0X2hhcmJvdXJfbmFtZSggPHN0cmluZ3xzdHJpbmcqPiogZGVzYykgCit7CisgIGlmICggc2l6ZW9mKGRlc2MpIT0yICkKKyAgeworICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIlVuYWNjZXB0YWJsZSBkYXRhIGluIFBfSEFSQk9VUiwgc2l6ZW9mKCkgd2FzICVkLCAiCisgICAgICAiZXhwZWN0ZWQgMi4iLCBzaXplb2YoZGVzYykpKTsKKyAgfQorICBlbHNlIGlmICggIXN0cmluZ3AoZGVzY1swXSkgKQorICB7CisgICAgcmFpc2VfZXJyb3IoIldyb25nIGRhdGEgdHlwZSBpbiBQX0hBUkJPVVJbMF06IGV4cGVjdGVkICdzdHJpbmcnLiIpOworICB9CisgIGVsc2UgaWYgKCBwb2ludGVycChkZXNjWzFdKSAmJiBzaXplb2YoZGVzY1sxXSk8MSApCisgIHsKKyAgICByYWlzZV9lcnJvcigiSW5zdWZmaWNpZW50IGRhdGEgaW4gUF9IQVJCT1VSWzFdOiBleHBlY3RlZCAnc3RyaW5nKicsICIKKyAgICAgICJnb3QgJyh7fSknLiIpOworICB9CisgIGVsc2UgaWYgKCBzdHJpbmdwKGRlc2NbMV0pICkKKyAgeworICAgIGRlc2NbMV0gPSAoe2Rlc2NbMV19KTsKKyAgfQorICByZXR1cm4gU2V0KFBfSEFSQk9VUiwgZGVzYywgRl9WQUxVRSk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9yb29tL2Rvb3JzLmMgYi9zdGQvcm9vbS9kb29ycy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwNWYwMDkKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcm9vbS9kb29ycy5jCkBAIC0wLDAgKzEsMTYyIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcm9vbS9kb29ycy5jIC0tIG5ldyBkb29ycywgbWFuYWdlZCBieSBkb29ybWFzdGVyCisvLworLy8gJElkOiBkb29ycy5jIDkxMzQgMjAxNS0wMi0wMiAxOToyNjowM1ogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKworI2luY2x1ZGUgPGNvbmZpZy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxkb29ycm9vbS5oPgorI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8cm9vbS9leGl0cy5oPgorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICBpZiAob2JqZWN0X25hbWUodGhpc19vYmplY3QoKSkgPT0gX19GSUxFX19bMC4uPDNdKQorICB7CisgICAgc2V0X25leHRfcmVzZXQoLTEpOworICAgIHJldHVybjsKKyAgfQorICBTZXRQcm9wKFBfRE9PUl9JTkZPUywwKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKK3ZhcmFyZ3MgaW50IE5ld0Rvb3Ioc3RyaW5nfHN0cmluZyogY21kcywgc3RyaW5nIGRlc3QsIHN0cmluZ3xzdHJpbmcqIGlkcywKKyAgICAgICAgICAgICAgICAgICAgbWFwcGluZ3w8aW50fHN0cmluZ3xzdHJpbmcqPiogcHJvcHMpCit7CisvKgorICBjbWRzOiBCZWZlaGwoZSksIHVtIGR1cmNoIGRpZSBUdWVyIHp1IGdlaGVuIChTdHJpbmcgb2RlciBBcnJheSB2b24gU3RyaW5ncykKKyAgZGVzdDogWmllbHJhdW0KKyAgaWRzOiAgSWQocykgZGVyIFR1ZXIsIGRlZmF1bHQgInR1ZXIiIChTdHJpbmcsIEFycmF5IHZvbiBTdHJpbmdzIG9kZXIgMCkKKyAgcHJvcHM6IGJlc29uZGVyZSBFaWdlbnNjaGFmdGVuIGRlciBUdWVyIChvcHRpb25hbCkKKyAgQXJyYXkgbWl0IFBhYXJlbiBOdW1tZXIgZGVyIEVpZ2Vuc2NoYWZ0LCBJbmhhbHQKKyAgZGVmaW5pZXJ0ZSBQcm9wZXJ0aWVzIHNpbmQ6CisgIERfRkxBR1M6ICBGbGFncyB3aWUgYmVpIFNpcidzIFR1ZXJlbgorICBkZWZhdWx0OiBET09SX0NMT1NFRCB8IERPT1JfUkVTRVRfQ0wKKyAgQmVpIFNjaGx1ZXNzZWxuIHdpcmQgZ2V0ZXN0ZXQsIG9iIGRlciBTdHJpbmcsIGRlbgorICBRdWVyeURvb3JLZXkgenVydWVja2xpZWZlcnQsIGdsZWljaAorICAicmF1bW5hbWUxOnJhdW1uYW1lMiIgaXN0LCB3b2JlaSByYXVtbmFtZTEsMiBkaWUKKyAga29tcGxldHRlbiBGaWxlbmFtZW4gZGVyIGJlaWRlbiBSYWV1bWUgaW4gc29ydGllcnRlcgorICBSZWloZW5mb2xnZSBzaW5kLgorICBEX0xPTkc6ICAgbGFuZ2UgQmVzY2hyZWlidW5nIGRlciBUdWVyCisgIGRlZmF1bHQ6ICJFaW5lIFR1ZXIuXG4iCisgIERfU0hPUlQ6ICBrdXJ6ZSBCZXNjaHJlaWJ1bmcgZGVyIFR1ZXIsIHdpcmQgYW4gZGllIFJhdW1iZXNjaHJlaWJ1bmcKKyAgYW5nZWZ1ZWd0LCB3b2JlaSAlcyBkdXJjaCBnZW9lZmZuZXQgYnp3LiBnZXNjaGxvc3NlbgorICBlcnNldHp0IHdpcmQuCisgIGRlZmF1bHQ6ICJFaW5lICVzZSBUdWVyLiAiCisgIERfTkFNRTogICBOYW1lLCBkZXIgYmVpbSBPZWZmbmVuL1NjaGxpZXNzZW4gdW5kIGJlaSBGZWhsZXJtZWxkdW5nZW4KKyAgYW5nZXplaWd0IHdpcmQuCisgIGRlZmF1bHQ6ICJUdWVyIgorICBEX0dFTkRFUjogZGVmYXVsdDogRkVNQUxFCisgIERfRlVOQzogICBGdW5rdGlvbiwgZGllIGltIFJhdW0gYXVmZ2VydWZlbiB3ZXJkZW4gc29sbCwgd2VubiBkaWUKKyAgVHVlciBlcmZvbGdyZWljaCBkdXJjaHNjaHJpdHRlbiB3aXJkLgorICBkZWZhdWx0OiAwCisgIERfTVNHUzogICBGYWxscyBTdHJpbmc6IGF1c2dlZ2ViZW5lIFJpY2h0dW5nIGZ1ZXIgbW92ZQorICBGYWxscyBBcnJheTogKHtkaXJlY3Rpb24sIHRleHRvdXQsIHRleHRpbn0pIGZ1ZXIgbW92ZQorICBkZWZhdWx0OiAwCisKKyAgQmVpc3BpZWw6CisgIE5ld0Rvb3IoIm5vcmRlbiIsIi9wbGF5ZXJzL3JvY2h1cy9yb29tL3Rlc3QyIiwicG9ydGFsIiwKKyAgKHtEX05BTUUsIlBvcnRhbCIsCisgIERfR0VOREVSLE5FVVRFUiwKKyAgRF9TSE9SVCwiSW0gTm9yZGVuIHNpZWhzdCBEdSBlaW4gJXNlcyBQb3J0YWwuICIsCisgIERfTE9ORywiRGFzIFBvcnRhbCBpc3QgZWluZmFjaCBudXIgZ2lnYW50aXNjaC5cbiIKKyAgfSkpOworCisqLworCisgIGlmICghY21kcyB8fCAhZGVzdCkgcmV0dXJuIDA7CisgIHJldHVybiBjYWxsX290aGVyKERPT1JfTUFTVEVSLCJOZXdEb29yIixjbWRzLGRlc3QsaWRzLHByb3BzKTsKK30KKwordm9pZCBpbml0KCkKK3sKKyAgbWl4ZWQgKmluZm87CisgIHN0cmluZyAqY21kczsKKyAgaW50IGksajsKKworICBpZiAoIXBvaW50ZXJwKGluZm89KG1peGVkICopUXVlcnlQcm9wKFBfRE9PUl9JTkZPUykpKSByZXR1cm47CisgIGFkZF9hY3Rpb24oIm9lZmZuZW4iLCJvZWZmbmUiKTsKKyAgYWRkX2FjdGlvbigic2NobGllc3NlbiIsInNjaGxpZXNzZSIpOworICBhZGRfYWN0aW9uKCJzY2hsaWVzc2VuIiwic2NobGllc3MiKTsKKyAgZm9yIChpPXNpemVvZihpbmZvKS0xO2k+PTA7aS0tKSB7CisgICAgY21kcz0oc3RyaW5nICopKGluZm9baV1bRF9DTURTXSk7CisgICAgZm9yIChqPXNpemVvZihjbWRzKS0xO2o+PTA7ai0tKQorICAgICAgYWRkX2FjdGlvbigiZ29fZG9vciIsY21kc1tqXSk7CisgICAgLy8gQmVmZWhsZSBJTU1FUiBhbmZ1ZWdlbiwgZ2VjaGVja2VkIHdpcmQgc293aWVzbyBlcnN0IGJlaW0gRHVyY2hnZWhlbi4KKyAgfQorfQorCit2b2lkIHJlc2V0KCkKK3sKKyAgaWYgKFF1ZXJ5UHJvcChQX0RPT1JfSU5GT1MpKQorICAgIGNhbGxfb3RoZXIoRE9PUl9NQVNURVIsInJlc2V0X2Rvb3JzIik7Cit9CisKK2ludCBvZWZmbmVuIChzdHJpbmcgc3RyKQoreworICBpZiAoIXN0ciB8fCAhUXVlcnlQcm9wKFBfRE9PUl9JTkZPUykpCisgICAgcmV0dXJuIDA7CisgIHJldHVybiAoaW50KSBjYWxsX290aGVyKERPT1JfTUFTVEVSLCJvZWZmbmVuIixzdHIpOworfQorCitpbnQgc2NobGllc3NlbiAoc3RyaW5nIHN0cikKK3sKKyAgaWYgKCFzdHIgfHwgIVF1ZXJ5UHJvcChQX0RPT1JfSU5GT1MpKQorICAgIHJldHVybiAwOworICByZXR1cm4gKGludCkgY2FsbF9vdGhlcihET09SX01BU1RFUiwic2NobGllc3NlbiIsc3RyKTsKK30KKwordmFyYXJncyBpbnQKK2dvX2Rvb3IgKHN0cmluZyBzdHIpCit7CisgIGlmICghUXVlcnlQcm9wKFBfRE9PUl9JTkZPUykpCisgICAgcmV0dXJuIDA7CisgIGlmIChjYWxsX290aGVyKERPT1JfTUFTVEVSLCJnb19kb29yIixxdWVyeV92ZXJiKCkpKQorICAgIHJldHVybiAxOworICByZXR1cm4gMDsKK30KKworaW50IHNldF9kb29ycyhzdHJpbmcgKmNtZHMsaW50IG9wZW4pCit7CisgIGludCBqOworICAKKyAgaWYgKCFwcmV2aW91c19vYmplY3QoKSkKKyAgICByZXR1cm4gMDsKKyAgaWYgKG9iamVjdF9uYW1lKHByZXZpb3VzX29iamVjdCgpKSE9RE9PUl9NQVNURVIpCisgICAgcmV0dXJuIDA7CisgIC8vIEFuZGVyZSBzb2xsZW4gbmljaHQgcnVtcGZ1c2NoZW4uCisgIGlmICghdGhpc19wbGF5ZXIoKSkgcmV0dXJuIDA7CisgIGlmIChlbnZpcm9ubWVudCh0aGlzX3BsYXllcigpKSE9dGhpc19vYmplY3QoKSkKKyAgICByZXR1cm4gMDsKKyAgLy8gSXN0IHNvd2llc28ga2VpbmVyIGRhLi4uCisgIGlmICghcG9pbnRlcnAoY21kcykpCisgICAgcmV0dXJuIDA7CisgIGlmIChvcGVuKQorICAgIEFkZFNwZWNpYWxFeGl0KGNtZHMsImdvX2Rvb3IiKTsKKyAgZWxzZQorICAgIFJlbW92ZVNwZWNpYWxFeGl0KGNtZHMpOworICBmb3IgKGo9c2l6ZW9mKGNtZHMpLTE7aj49MDtqLS0pCisgICAgYWRkX2FjdGlvbigiZ29fZG9vciIsY21kc1tqXSk7CisgIHJldHVybiAxOworfQorCisvKiBGdWVyIFR1ZXJlbiwgZGllIGZsZXhpYmxlIExhbmdiZXNjaHJlaWJ1bmdlbiBoYWJlbiwgd2lyZCBlaW4gCisgKiBTcGVjaWFsRGV0YWlsIGVpbmdlZnVlaHJ0LgorICovCisKK3N0cmluZyBzcGVjaWFsX2RldGFpbF9kb29ycyhzdHJpbmcga2V5KXsKKyAgcmV0dXJuIERPT1JfTUFTVEVSLT5zcGVjaWFsX2RldGFpbF9kb29ycyhrZXkpOworfQpkaWZmIC0tZ2l0IGEvc3RkL3Jvb20vZXhpdHMuYyBiL3N0ZC9yb29tL2V4aXRzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGM3MjRiOAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9yb29tL2V4aXRzLmMKQEAgLTAsMCArMSwzMzQgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyByb29tL2V4aXRzLmMgLS0gcm9vbSBleGl0cyBoYW5kbGluZyAKKy8vCisvLyAkSWQ6IGV4aXRzLmMgOTQ5NyAyMDE2LTAyLTIxIDE0OjIwOjAzWiBaZXNzdHJhICQKKworLyoKKyAqIEV4aXRzIG9mIHRoZSByb29tIChvYnZpb3VzIG9uZXMsIGRvb3JzLCBhbmQgc3BlY2lhbCBvbmVzKQorICogd2UgZGVmaW5lIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb24gZm9yIGVhc3kgcmVmZXJlbmNlOgorICogR2V0RXhpdHMoKSAtIHJldHVybiBhIHN0cmluZyBjb250YWluaW5nIGFuICJPYnZpb3VzIEV4aXRzIiBTdGF0ZW1lbnQKKyAqCisgKiBUaGUgZXhpdHMgYXJlIGltcGxlbWVudGVkIGFzIHByb3BlcnRpZXMgUF9FWElUUworICogVGhleSBhcmUgc3RvcmVkIGxvY2FsbHkgKF9zZXRfeHgsIF9xdWVyeV94eCkKKyAqIGFzIG1hcHBpbmcgdG8gc3BlZWQgdXAgdGhlIHJvdXRpbmVzIGluIHRoaXMgbW9kdWxlLgorICoKKyAqLworCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPHJvb20vZXhpdHMuaD4KKyNpbmNsdWRlIDxob29rLmg+CisjaW5jbHVkZSA8ZXhwbG9yYXRpb24uaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPHN5c19kZWJ1Zy5oPgorI2luY2x1ZGUgPGNvbmZpZy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8ZGFlbW9uLmg+CisjaW5jbHVkZSA8ZG9vcnJvb20uaD4KKyNpbmNsdWRlIDxyb3V0aW5nZC5oPgorCisjZGVmaW5lIE5VTUJFUlMgKHsgInp3ZWkiLCAiZHJlaSIsICJ2aWVyIiwgImZ1ZW5mIiwgInNlY2hzIiwgInNpZWJlbiIsICJhY2h0IiB9KQorCisKKy8vIEhpbGZzZnVua3Rpb24sIGRpZSBiZWkga2FwdXR0ZW4gRXhpdHMgZWluZSBOb3RyZXR0dW5nIGJldHJlaWJ0LCBhYmVyCisvLyB0cm90emRlbSBhdWYgRGVidWcgZWluZSBNZWxkdW5nIG1hY2h0Lgorc3RhdGljIG1hcHBpbmcgcmVzY3VlRXhpdCgpCit7CisgIGNhdGNoKHJhaXNlX2Vycm9yKHNwcmludGYoCisJICAicm9vbS9leGl0cy5jOiBGb3Jnb3R0ZW4gOjpjcmVhdGUoKT8gIgorCSAgIlBfRVhJVFMgaW4gJU8gaXMgMCFcbiIsIHRoaXNfb2JqZWN0KCkpKTtwdWJsaXNoKTsgCisKKyAgcmV0dXJuIChbOjJdKTsKK30KKworCitzdGF0aWMgbWFwcGluZyBfc2V0X2V4aXRzKCBtYXBwaW5nIG1hcF9sZGZpZWQgKSAKK3sKKyAgICBpZiggbWFwcGluZ3AobWFwX2xkZmllZCkgKQorICAgICAgICByZXR1cm4gU2V0KCBQX0VYSVRTLCBtYXBfbGRmaWVkICk7CisgICAgcmV0dXJuIDA7Cit9CisKKworc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X2V4aXRzKCkgCit7CisgICAgaWYoICghcHJldmlvdXNfb2JqZWN0KCkgfHwgb2JqZWN0X25hbWUocHJldmlvdXNfb2JqZWN0KCkpICE9IERPT1JfTUFTVEVSKQorICAgICAgICAmJiBRdWVyeVByb3AoUF9ET09SX0lORk9TKSApCisgICAgICAgIGNhbGxfb3RoZXIoIERPT1JfTUFTVEVSLCAiaW5pdF9kb29ycyIgKTsKKworICAgIG1hcHBpbmcgZXhpdHMgPSBRdWVyeShQX0VYSVRTKSB8fCByZXNjdWVFeGl0KCk7CisKKyAgICByZXR1cm4gZmlsdGVyKGV4aXRzLCBmdW5jdGlvbiBpbnQgKHN0cmluZyBrZXksIG1peGVkIHZhbCkKKyAgICAgICAge3JldHVybiBzdHJpbmdwKHZhbFswXSk7fSApOworfQorCisKK3N0YXRpYyBpbnQgX3NldF9zcGVjaWFsX2V4aXRzKCBtYXBwaW5nIG1hcF9sZGZpZWQgKQoreworICAgIHJldHVybiAtMTsKK30KKworCitzdGF0aWMgbWFwcGluZyBfcXVlcnlfc3BlY2lhbF9leGl0cygpIAoreworICAgIG1hcHBpbmcgZXhpdHMgPSBRdWVyeShQX0VYSVRTKSB8fCByZXNjdWVFeGl0KCk7CisKKyAgICByZXR1cm4gZmlsdGVyKGV4aXRzLCBmdW5jdGlvbiBpbnQgKHN0cmluZyBrZXksIG1peGVkIHZhbCkKKyAgICAgICAge3JldHVybiBjbG9zdXJlcCh2YWxbMF0pO30gKTsKK30KKworCit2b2lkIHJlc2V0KCkKK3t9CisKKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgb2ZmZXJIb29rKEhfSE9PS19FWElUX1VTRSwgMSk7CisgIFNldFByb3AoIFBfRVhJVFMsIChbOjJdKSApOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKworcHJvdGVjdGVkIHZvaWQgX0FkZEV4aXQoc3RyaW5nfHN0cmluZyogY21kLCBzdHJpbmd8Y2xvc3VyZSByb29tLAorICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIG1lc3NhZ2UpCit7CisgIG1hcHBpbmcgZXhpdGE7CisKKyAgZXhpdGEgPSBRdWVyeShQX0VYSVRTKSB8fCByZXNjdWVFeGl0KCk7CisKKyAgaWYgKCAhY2xvc3VyZXAocm9vbSkgKQorICB7CisgICAgb2JqZWN0IHJvdXRlcjsKKworICAgIHJvb20gPSBfTWFrZVBhdGgocm9vbSk7CisKKyAgICBpZiAoICFjbG9uZXAodGhpc19vYmplY3QoKSkgJiYgb2JqZWN0cChyb3V0ZXIgPSBmaW5kX29iamVjdChST1VURVIpKSApCisgICAgeworICAgICAgcm91dGVyLT5SZWdpc3RlckV4aXQoIG9iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpLCBjbWQsIHJvb20gKTsKKyAgICB9CisgIH0KKworICBpZiggc3RyaW5ncChjbWQpICkKKyAgeworICAgIGV4aXRhICs9IChbIGNtZCA6IHJvb207IG1lc3NhZ2UgXSk7CisgIH0KKyAgZWxzZQorICB7CisgICAgZm9yZWFjaChzdHJpbmcgYyA6IGNtZCkKKyAgICB7CisgICAgICBpZiAoc3RyaW5ncChjKSkKKyAgICAgICAgZXhpdGEgKz0gKFsgYyA6IHJvb207IG1lc3NhZ2UgXSk7CisgICAgfQorICB9CisKKyAgU2V0KCBQX0VYSVRTLCBleGl0YSApOworfQorCit2b2lkIEFkZEV4aXQoc3RyaW5nfHN0cmluZyogY21kLCBjbG9zdXJlfHN0cmluZyBkZXN0KQoreworICBzdHJpbmcgbXNnOworICBpZiAoIHN0cmluZ3AoZGVzdCkgKQorICB7CisgICAgaW50IHM7CisgICAgaWYoIChzID0gbWVtYmVyKGRlc3QsICcjJykpICE9IC0xICkKKyAgICB7CisgICAgICBtc2cgID0gZGVzdFswLi5zLTFdOworICAgICAgZGVzdCA9IGRlc3RbcysxLi5dOworICAgIH0KKyAgfQorICBfQWRkRXhpdChjbWQsIGRlc3QsIG1zZyk7Cit9CisKK3ZvaWQgUmVtb3ZlRXhpdChzdHJpbmd8c3RyaW5nKiBjbWQgKQoreworICAgIG1hcHBpbmcgZXhpdGE7CisKKyAgICBpZiAoICFjbWQgKSB7CisgICAgICAgIFNldFByb3AoUF9FWElUUywgKFs6Ml0pICk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoIHN0cmluZ3AoY21kKSApCisgICAgICAgIGNtZCA9ICh7IGNtZCB9KTsKKworICAgIGV4aXRhID0gUXVlcnkoUF9FWElUUywgRl9WQUxVRSkgfHwgcmVzY3VlRXhpdCgpOworICAgIGZvcmVhY2goc3RyaW5nIGMgOiBjbWQpCisgICAgICBtX2RlbGV0ZSggZXhpdGEsIGMgKTsKKworICAgIFNldCggUF9FWElUUywgZXhpdGEsIEZfVkFMVUUgKTsKK30KKworCit2b2lkIEFkZFNwZWNpYWxFeGl0KHN0cmluZ3xzdHJpbmcqIGNtZCwgc3RyaW5nfGNsb3N1cmUgZnVuY3Rpb25uYW1lICkKK3sKKworICAgIGlmICggc3RyaW5ncChmdW5jdGlvbm5hbWUpICkKKyAgICAgICAgZnVuY3Rpb25uYW1lID0gc3ltYm9sX2Z1bmN0aW9uKCBmdW5jdGlvbm5hbWUsIHRoaXNfb2JqZWN0KCkgKTsKKworICAgIGlmICggIWNsb3N1cmVwKGZ1bmN0aW9ubmFtZSkgKQorICAgIHsKKyAgICAgICAgY2F0Y2gocmFpc2VfZXJyb3Ioc3ByaW50ZiggIm1ldGhvZCAlTyBkb2Vzbid0IGV4aXN0XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbm5hbWUpKTsgcHVibGlzaCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBBZGRFeGl0KCBjbWQsIGZ1bmN0aW9ubmFtZSApOworfQorCisKK3ZvaWQgUmVtb3ZlU3BlY2lhbEV4aXQoc3RyaW5nfHN0cmluZyogY21kKQoreworICAgIFJlbW92ZUV4aXQoIGNtZCApOworfQorCisKK3ZhcmFyZ3Mgc3RyaW5nIEdldEV4aXRzKCBvYmplY3Qgdmlld2VyICkgCit7CisgICAgc3RyaW5nICppbmRpY2VzLCAqaGlkZGVuOworICAgIHN0cmluZyBleGl0czsKKworICAgIGlmICggUXVlcnlQcm9wKFBfRE9PUl9JTkZPUykgKQorICAgICAgICBjYWxsX290aGVyKCBET09SX01BU1RFUiwgImluaXRfZG9vcnMiICk7CisKKyAgICBpbmRpY2VzID0gbV9pbmRpY2VzKCBRdWVyeShQX0VYSVRTKSB8fCByZXNjdWVFeGl0KCkgKTsKKyAgICAKKyAgICBpZiAoIHBvaW50ZXJwKGhpZGRlbiA9IFF1ZXJ5UHJvcChQX0hJREVfRVhJVFMpKSApCisgICAgICAgIGluZGljZXMgLT0gaGlkZGVuOworCisgICAgaW50IG49c2l6ZW9mKGluZGljZXMpOworICAgIHN3aXRjaCAobikgeworICAgIGNhc2UgMDoKKyAgICAgICAgcmV0dXJuICJFcyBnaWJ0IGtlaW5lIHNpY2h0YmFyZW4gQXVzZ2FlbmdlLlxuIjsKKyAgICAgICAgCisgICAgY2FzZSAxOgorICAgICAgICByZXR1cm4gIkVzIGdpYnQgZWluZW4gc2ljaHRiYXJlbiBBdXNnYW5nOiAiICsgaW5kaWNlc1swXSArICIuXG4iOworICAgICAgICAKKyAgICBjYXNlIDI6IGNhc2UgMzogY2FzZSA0OiBjYXNlIDU6IGNhc2UgNjogY2FzZSA3OiBjYXNlIDg6CisgICAgICAgIGV4aXRzID0gIkVzIGdpYnQgIiArIE5VTUJFUlNbbi0yXSArICIgc2ljaHRiYXJlIEF1c2dhZW5nZTogIjsKKyAgICAgICAgYnJlYWs7CisgICAgICAgIAorICAgIGRlZmF1bHQ6CisgICAgICAgIGV4aXRzID0gIkVzIGdpYnQgdmllbGUgc2ljaHRiYXJlIEF1c2dhZW5nZTogIjsKKyAgICB9CisgICAgZXhpdHMgKz0gQ291bnRVcChpbmRpY2VzKTsKKyAgICByZXR1cm4gYnJlYWtfc3RyaW5nKCBleGl0cysiLiIsIDc4ICk7Cit9CisKKworLy8gUmljaHR1bmdzYmVmZWhsZSBudXIgaW50ZXJwcmV0aWVyZW4sIHdlbm4gZGVyIFNwaWVsZXIgKmltKiBSYXVtIHN0ZWh0IHVuZAorLy8gbmljaHQgZGF2b3IgKFRyYW5zcG9ydGVyIGV0Yy4pL28KK3ZvaWQgaW5pdCgpCit7CisgICAgaWYgKCBlbnZpcm9ubWVudCh0aGlzX3BsYXllcigpKSA9PSB0aGlzX29iamVjdCgpICkKKyAgICAgICAgYWRkX2FjdGlvbiggIl9ub3JtYWxmdW5jdGlvbiIsICIiLCAxICk7Cit9CisKKworLyogbm90IG9ubHkgbm9ybWFsIGV4aXRzIGFyZSBoYW5kbGVkIGhlcmUgKi8KKworaW50IF9ub3JtYWxmdW5jdGlvbigpCit7CisgIGludCByZXQ7CisgIG1hcHBpbmcgZXhpdHMgPSBRdWVyeShQX0VYSVRTLCBGX1ZBTFVFKSB8fCAoWzozXSk7CisgIGlmICghbWVtYmVyKGV4aXRzLHF1ZXJ5X3ZlcmIoKSkpCisgICAgcmV0dXJuIDA7CisKKyAgc3RyaW5nIHZlcmIgPSBxdWVyeV92ZXJiKCk7CisgIHN0cmluZyBkZXN0cm9vbSA9IGV4aXRzW3F1ZXJ5X3ZlcmIoKSwwXTsKKyAgc3RyaW5nIG1lc3NhZ2UgPSBleGl0c1txdWVyeV92ZXJiKCksMV07CisKKyAgbWl4ZWQgaHJlcyA9IEhvb2tGbG93KEhfSE9PS19FWElUX1VTRSwgKHt2ZXJiLCBkZXN0cm9vbSwgbWVzc2FnZX0pKTsKKyAgaWYoaHJlcyAmJiBwb2ludGVycChocmVzKSAmJiBzaXplb2YoaHJlcyk+SF9SRVREQVRBKQorICB7CisgICAgaWYoaHJlc1tIX1JFVENPREVdPT1IX0NBTkNFTExFRCkKKyAgICB7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgZWxzZSBpZihocmVzW0hfUkVUQ09ERV09PUhfQUxURVJFRAorICAgICAgICAgICAgJiYgcG9pbnRlcnAoaHJlc1tIX1JFVERBVEFdKQorICAgICAgICAgICAgJiYgc2l6ZW9mKGhyZXNbSF9SRVREQVRBXSkgPj0gMykKKyAgICB7CisgICAgICA8c3RyaW5nfGNsb3N1cmU+KiBoZGF0YSA9IGhyZXNbSF9SRVREQVRBXTsKKyAgICAgIGlmICghc3RyaW5ncChoZGF0YVswXSkKKyAgICAgICAgICB8fCAoIXN0cmluZ3AoaGRhdGFbMV0pICYmICFjbG9zdXJlcChoZGF0YVsxXSkpCisgICAgICAgICAgfHwgKGhkYXRhWzJdICYmICFzdHJpbmdwKGhkYXRhWzJdKSkgKQorICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJJbnZhbGlkZSBEYXRlbiBhdXMgSF9IT09LX0VYSVRfVVNFOiAlLjE1ME9cbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGRhdGEpKTsKKyAgICAgIHZlcmIgPSBoZGF0YVswXTsKKyAgICAgIGRlc3Ryb29tID0gaGRhdGFbMV07CisgICAgICBtZXNzYWdlID0gaGRhdGFbMl07CisgICAgfQorICB9CisKKyAgaWYoIGNsb3N1cmVwKGRlc3Ryb29tKSApCisgIHsKKyAgICByZXQgPSBmdW5jYWxsKCBkZXN0cm9vbSwgdmVyYiApOworCisgICAgaWYocmV0PT1NT1ZFX09LKQorICAgIHsKKyAgICAgIEdpdmVFUCggRVBfRVhJVCwgdmVyYiApOworICAgIH0KKworICAgIHJldHVybiByZXQ7CisgIH0KKworICBpZiAoIXN0cmluZ3AobWVzc2FnZSkpCisgIHsKKyAgICBpZiggbWVtYmVyKCAoeyAic3VlZGVuIiwgInN1ZWR3ZXN0ZW4iLCAid2VzdGVuIiwibm9yZHdlc3RlbiIsICJub3JkZW4iLAorICAgICAgICAibm9yZG9zdGVuIiwgIm9zdGVuIiwic3VlZG9zdGVuIiB9KSwgdmVyYiApICE9IC0xICkKKyAgICB7CisgICAgICBtZXNzYWdlID0gIm5hY2ggIiArIGNhcGl0YWxpemUodmVyYik7CisgICAgfQorICAgIGVsc2UgaWYgKCBtZW1iZXIoICh7ICJvYmVuIiwgInVudGVuIiB9KSwgdmVyYiApICE9IC0xICkKKyAgICB7CisgICAgICBtZXNzYWdlID0gIm5hY2ggIiArIHZlcmI7CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICBtZXNzYWdlID0gdmVyYjsKKyAgICB9CisgIH0KKworICByZXQgPSB0aGlzX3BsYXllcigpLT5tb3ZlKCBkZXN0cm9vbSwgTV9HTywgbWVzc2FnZSApOworCisgIGlmIChyZXQ9PU1PVkVfT0spCisgIHsKKyAgICBHaXZlRVAoIEVQX0VYSVQsIHZlcmIgKTsKKyAgfQorCisgIHJldHVybiByZXQ7Cit9CisKK3N0YXRpYyBzdHJpbmcgX01ha2VQYXRoKCBzdHJpbmcgc3RyICkKK3sKKyAgc3RyaW5nICpjb21wOworCisgIGNvbXAgPSBleHBsb2RlKCBvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSwgIi8iICkgLSAoeyIifSk7CisgIAorICAgc3dpdGNoKCBzdHJbMF0gKXsKKyAgIGNhc2UgJy4nOgorICAgICAgIHN0ciA9ICIvIiArIGltcGxvZGUoIGNvbXBbMC4uPDJdLCAiLyIgKSArICIvIiArIHN0cjsKKyAgICAgICBicmVhazsKKyAgICAgICAKKyAgIGNhc2UgJ34nOgorICAgICAgIHN0ciA9ICIvIiArIGNvbXBbMF0gKyAiLyIgKyAoY29tcFswXSA9PSAiZCIgPyBjb21wWzFdICsgIi8iIDogIiIpCisgICAgICAgICAgICtSRUFMX1VJRCh0aGlzX29iamVjdCgpKSArIHN0clsxLi5dOworICAgICAgIGJyZWFrOworICAgfQorICAgCisgICByZXR1cm4gTUFTVEVSLT5fZ2V0X3BhdGgoIHN0ciwgZ2V0dWlkKHRoaXNfb2JqZWN0KCkpICk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9yb29tL2l0ZW1zLmMgYi9zdGQvcm9vbS9pdGVtcy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFkNDAwNWEKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcm9vbS9pdGVtcy5jCkBAIC0wLDAgKzEsNDIgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyByb29tL2l0ZW1zLmMgLS0gY3JlYXRpbmcgZXh0cmEgaXRlbXMgaW4gcm9vbQorLy8KKy8vICRJZDogaXRlbXMuYyA5NTM4IDIwMTYtMDMtMjAgMjM6NDY6NDFaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisKK2luaGVyaXQgInN0ZC9jb250YWluZXIvaXRlbXMiOworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKwordm9pZCByZXNldCgpIAoreworICA6OnJlc2V0KCk7CisKKyAgb2JqZWN0ICppbmggPSBhbGxfaW52ZW50b3J5KHRoaXNfb2JqZWN0KCkpOworICBpZiAoICFwb2ludGVycChpbmgpIHx8IHNpemVvZihpbmgpIDwgMTAgKQorICAgIHJldHVybjsKKyAgLy8gbnVyIHdlbm4ga2VpbmUgU3BpZWxlciBhbndlc2VuZCBzaW5kLgorICBpZiAoICFzaXplb2YoaW5oICYgdXNlcnMoKSkgKQorICAgIHJlbW92ZV9tdWx0aXBsZSgzKTsKK30KKworLy8gUGVyIERlZmF1bHQgbnVyIGFuIGFsbGUgSXRlbXMgaW0gSW52ZW50YXIgd2VpdGVybGVpdGVuLgorcHVibGljIHZhcmFyZ3MgaW50IFJlY2VpdmVNc2coc3RyaW5nIG1zZywgaW50IG1zZ190eXBlLCBzdHJpbmcgbXNnX2FjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBtc2dfcHJlZml4LCBvYmplY3Qgb3JpZ2luKQoreworICBpbnQgKnJlcyA9IGFsbF9pbnZlbnRvcnkoKS0+UmVjZWl2ZU1zZyhtc2csIG1zZ190eXBlLCBtc2dfYWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2dfcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW4gfHwgcHJldmlvdXNfb2JqZWN0KCkpOworICBpZiAoc2l6ZW9mKHJlcykpCisgICAgcmV0dXJuIG1pbihyZXMpOworICByZXR1cm4gMDsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3Jvb20va3JhZXV0ZXIuYyBiL3N0ZC9yb29tL2tyYWV1dGVyLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjRmNTE5MwotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9yb29tL2tyYWV1dGVyLmMKQEAgLTAsMCArMSwyNDAgQEAKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHRoaW5nL2xhbmd1YWdlLmg+CisjaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KKyNpbmNsdWRlIDx0aGluZy9jb21tYW5kcy5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPGl0ZW1zL2tyYWV1dGVyL2tyYWV1dGVyLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPGxpdmluZy9jb21iYXQuaD4gLy8gRnVlciBQX0ZSRUVfSEFORFMKKworLy8gU3RhbmRhcmR3ZXJ0IHZvbiAyIGggZnVlciB2b2xsc3RhZW5kaWdlIFJlZ2VuZXJhdGlvbiBkZXMgS3JhdXRlcy4gCisvLyBFaW5mYWNoZXMgTmFjaHdhY2hzZW4gaXN0IHR5cGlzY2hlcndlaXNlIGRpZSBIYWVsZnRlIGRhdm9uLgorI2RlZmluZSBTVERfV0FDSFNUVU0gIDcyMDAKKyNkZWZpbmUgQlMoeCkgICAgICAgICBicmVha19zdHJpbmcoeCwgNzgpCisKKy8vIFN0cnVrdHVyICg2IEVpbnRyYWVnZSBwcm8gS3JhdXQpOgorLy8gKFsgZmlsZW5hbWUgOiAoeyBaZWl0X2Jpc19uYWNoZ2V3YWNoc2VuLCBaZWl0X2Jpc19rb21wbGV0dF9yZWdlbmVyaWVydCwKKy8vICAgICAgICAgICAgICAgICAgS3JhdXQtSURzLCBLcmF1dC1BZGpla3RpdmUsIEtyYXV0LT5OYW1lKFdFUiwxKSwKKy8vICAgICAgICAgICAgICAgICAgSURfZGVzX0Jld2FjaGVyLU5QQ3MgfSkgXSkKK21hcHBpbmcgcGxhbnRNYXAgPSAoW10pOworCisvLyBrYW5uIGJlbnV0enQgd2VyZGVuIHVtIHNjaG5lbGwgdW5kIGVpbmZhY2ggZWluZSBQZmxhbnplIGluIGVpbmVtIFJhdW0KKy8vIGhpbnp1enVmdWVnZW4uIEJlaXNwaWVsOiBBZGRQbGFudChCQUVSRU5LTEFVKTsKKy8vIERpZXNlIEZ1bmt0aW9uIGVyemV1Z3QgYXV0b21hdGlzY2ggZWluIEFkZENtZCgpIGZ1ZXIgZGFzIFBmbHVlY2tlbiB1bmQKKy8vIChmYWxscyBub2NoIG5pY2h0IHZvcmhhbmRlbikgRGV0YWlscyBmdWVyIGRpZSBQZmxhbnplLgorLy8gUnVlY2tnYWJld2VydGU6CisvLyAxIC0+IEVyZm9sZzsgLTEgLT4gZmlsZW5hbWUgdW5ndWVsdGlnCit2YXJhcmdzIGludCBBZGRQbGFudChzdHJpbmcgZmlsZW5hbWUsIHN0cmluZ3xzdHJpbmcqIG5wY0lkKQoreworICBtaXhlZCBhcnI7CisKKyAgLy8gRGF0ZWluYW1lIG5pY2h0IHVlYmVyZ2ViZW4/IERhbm4gdHVuIHdpciBlcnN0bWFsIGdhciBuaXguCisgIGlmICghc3RyaW5ncChmaWxlbmFtZSkpIAorICAgIHJldHVybiAtMTsKKyAgb2JqZWN0IG9iPWxvYWRfb2JqZWN0KGZpbGVuYW1lKTsKKyAgIAorICAvLyBXZW5uIHdpciB6dSBkZW0gS3JhdXQgc2Nob24gRGF0ZW4gaGFiZW4gKGVya2VubmJhciBhbiA+MiBFaW50cmFlZ2VuKSwKKyAgLy8gd2VyZmVuIHdpciBlaW5lbiBGZWhsZXIsIGRhbWl0IGRhcyBiZWltIExhZGVuIGRlcyBSYXVtZXMgc2Nob24KKyAgLy8gZXJrYW5udCB3aXJkLgorICBpZiAocG9pbnRlcnAoYXJyPXBsYW50TWFwW2ZpbGVuYW1lXSkgJiYgc2l6ZW9mKGFycik+MikKKyAgICByYWlzZV9lcnJvcigiQWRkUGxhbnQoKTogIitmaWxlbmFtZSsiIGFscmVhZHkgZXhpc3RzLlxuIik7CisKKyAgLy8gSURzIHVuZCBBZGpla3RpdmUgcGFyc2VuIHVuZCBkZW4gRGF0ZW5zYXR6IHp1c2FtbWVuc3RlbGxlbgorICBzdHJpbmcgKmlkcyA9IG9iLT5RdWVyeShQX0lEUywgRl9WQUxVRSktKHsgIkRpbmciIH0pOworICBzdHJpbmcgKmFkaiA9IG9iLT5RdWVyeShQX0FESkVDVElWRVMsIEZfVkFMVUUpOworICAKKyAgaWYgKCFwb2ludGVycChhcnIpIHx8IHNpemVvZihhcnIpPDIpIAorICAgIGFyciA9ICh7MCwwfSk7CisgIGlmICggIW5wY0lkICkKKyAgICBucGNJZCA9ICh7fSk7CisgIGVsc2UgaWYgKHN0cmluZ3AobnBjSWQpKQorICAgIG5wY0lkID0gKHtucGNJZH0pOworICBwbGFudE1hcFtmaWxlbmFtZV09KHthcnJbMF0sIGFyclsxXSwgaWRzLCBhZGosIG9iLT5OYW1lKFdFUiwgMSksIG5wY0lkIH0pOworICAgCisgIC8vIERldGFpbHMgZXJ6ZXVnZW4gYXVzIEFkamVrdGl2ZW4gdW5kIElEcworICBhZGogPSBvYi0+UXVlcnlQcm9wKFBfTkFNRV9BREopOworICAKKyAgLy8gYWt0dWVsbGVzIEdlc2NobGVjaHQgendpc2NoZW5zcGVpY2hlcm4sIHdpcmQgc3BhZXRlciB3aWVkZXJoZXJnZXN0ZWxsdAorICBpbnQgZ2VuZGVyID0gUXVlcnkoUF9HRU5ERVIsIEZfVkFMVUUpOworICBTZXQoUF9HRU5ERVIsIG9iLT5RdWVyeShQX0dFTkRFUiwgRl9WQUxVRSksIEZfVkFMVUUpOworICAKKyAgLy8gZXJ6ZXVndCBmdWVyIGplZGUgbW9lZ2xpY2hlIEtvbWJpbmF0aW9uIGF1cyBBZGpla3RpdiBpbSBBa2t1c2F0aXYKKyAgLy8gdW5kIElEIGRlcyBLcmF1dGVzIGVpbiBEZXRhaWwuCisgIGFkaiA9IG1hcChhZGosICMnRGVjbEFkaiwgV0VOLCAwKTsKKworICBzdHJpbmcgKmRldD0oe30pOworICBmb3JlYWNoKHN0cmluZyBfaWQgOiBpZHMpIHsKKyAgICBmb3JlYWNoKHN0cmluZyBfYWRqIDogYWRqKSB7CisgICAgICBkZXQgKz0gKHsgX2FkaiArIF9pZCB9KTsKKyAgICB9CisgIH0KKworICBkZXQgKz0gaWRzOworICAvLyBrZWluZSBleGlzdGllcmVuZGVuIERldGFpbHMgdWViZXJzY2hyZWliZW4KKyAgZGV0IC09IG1faW5kaWNlcyhRdWVyeShQX0RFVEFJTFMsIEZfVkFMVUUpIHx8IChbXSkpOworICBpZiAoc2l6ZW9mKGRldCkpIAorICAgIEFkZERldGFpbChkZXQsIG9iLT5RdWVyeShQTEFOVF9ST09NREVUQUlMLCBGX1ZBTFVFKSk7CisgIAorICAvLyBFaW5lIEJlZmVobHNmdW5rdGlvbiBicmF1Y2hlbiB3aXIgbmF0dWVybGljaCBhdWNoLgorICBBZGRDbWQoKHsicGZsdWVjayIsICJwZmx1ZWNrZSIsICJlcm50ZSJ9KSwgIl9wZmx1ZWNrZW4iKTsKKyAgCisgIHJldHVybiAxOworfQorCisvLyBXZW5uIGplbWFuZCBwZXIgSGFuZCBkYXMgUGxhbnRkZXRhaWwgaGluenVmdWVnZW4gbW9lY2h0ZS4uLgorLy8gei5CLiBiZWkgVmVyd2VuZHVuZyB2b24gR2V0UGxhbnQoKSBhbnN0ZWxsZSB2b24gQWRkUGxhbnQoKQordm9pZCBBZGRQbGFudERldGFpbChzdHJpbmcgZmlsZW5hbWUpCit7CisgIC8vIFBmYWQgaW4gT2JqZWt0cG9pbnRlciB3YW5kZWxuCisgIG9iamVjdCBvYj1sb2FkX29iamVjdChmaWxlbmFtZSk7CisgICAKKyAgLy8gRGV0YWlscyBlcnpldWdlbgorICBzdHJpbmcgKmRldCA9ICh7fSk7CisgIHN0cmluZyAqaWRzID0gb2ItPlF1ZXJ5KFBfSURTLCBGX1ZBTFVFKS0oeyAiRGluZyIgfSk7CisgIHN0cmluZyAqYWRqID0gb2ItPlF1ZXJ5UHJvcChQX05BTUVfQURKKTsKKyAgLy8gYWt0dWVsbGVzIEdlc2NobGVjaHQgendpc2NoZW5zcGVpY2hlcm4sIHdpcmQgc3BhZXRlciB3aWVkZXJoZXJnZXN0ZWxsdAorICBpbnQgZ2VuZGVyPVF1ZXJ5KFBfR0VOREVSLCBGX1ZBTFVFKTsKKyAgU2V0KFBfR0VOREVSLCBvYi0+UXVlcnkoUF9HRU5ERVIsIEZfVkFMVUUpKTsKKyAgLy8gZXJ6ZXVndCBmdWVyIGplZGUgbW9lZ2xpY2hlIEtvbWJpbmF0aW9uIGF1cyBBZGpla3RpdiBpbSBBa2t1c2F0aXYKKyAgLy8gdW5kIElEIGRlcyBLcmF1dGVzIGVpbiBEZXRhaWwuCisgIGFkaiA9IG1hcChhZGosICMnRGVjbEFkaiwgV0VOLCAwKTsKKyAgZm9yZWFjaChzdHJpbmcgX2lkIDogaWRzKSB7CisgICAgZm9yZWFjaChzdHJpbmcgX2FkaiA6IGFkaikgeworICAgICAgZGV0ICs9ICh7IF9hZGogKyBfaWQgfSk7CisgICAgfQorICB9CisgIEFkZERldGFpbChkZXQraWRzLCBvYi0+UXVlcnkoUExBTlRfUk9PTURFVEFJTCwgRl9WQUxVRSkpOworICAvLyBHZXNjaGxlY2h0IHp1cnVlY2tzZXR6ZW4KKyAgU2V0KFBfR0VOREVSLCBnZW5kZXIsIEZfVkFMVUUpOworfQorCisvLyBQcnVlZnQsIG9iIGRpZSBQZmxhbnplIHp1ICJmaWxlbmFtZSIgaW4gZGllc2VtIFJhdW0gc2Nob24gbmFjaGdld2FjaHNlbgorLy8gaXN0LgorcHJvdGVjdGVkIGludCBDaGVja1BsYW50KHN0cmluZyBmaWxlbmFtZSkKK3sKKyAgbWl4ZWQgYXJyPXBsYW50TWFwW2ZpbGVuYW1lXTsKKyAgaWYgKCFwb2ludGVycChhcnIpIHx8IHNpemVvZihhcnIpPDIpIHsKKyAgICBhcnI9cGxhbnRNYXBbZmlsZW5hbWVdPSh7IDAsIDAgfSk7CisgIH0KKyAgLy8gU29sYW5nZSBkaWUgWmVpdCBhcnJbMF0gbm9jaCBuaWNodCBlcnJlaWNodCBpc3QsIGlzdCBkYXMgS3JhdXQgbmljaHQgCisgIC8vIG5hY2hnZXdhY2hzZW4sIGRhbm4gZ2lidCBlcyBnYXIgbml4LgorICByZXR1cm4gKHRpbWUoKT5hcnJbMF0pOworfQorCisvLyBNb2VjaHRlIG1hbiBBZGRQbGFudCgpIG5pY2h0IGJlbnV0emVuLCB3ZWlsIG1hbiBkaWUgUGZsYW56ZSBuaWNodCBlaW5mYWNoCisvLyBwZmx1ZWNrZW4sIHNvbmRlcm4gdmllbGxlaWNodCBhYnNjaG5laWRlbiwgb2RlciBhdXNncmFiZW4gc29sbCwgc28ga2FubgorLy8gbWFuIHNpY2ggbWl0dGVscyBHZXRQbGFudChmaWxlbmFtZSkgZGFzIE9iamVrdCBlcnpldWdlbiBsYXNzZW4uIEdpYnQKKy8vIEdldFBsYW50KCkgMCB6dXJ1ZWNrLCBpc3QgZGllIFBmbGFuemUgbm9jaCBuaWNodCB3aWVkZXIgd2VpdCBnZW51ZworLy8gbmFjaGdld2FjaHNlbi4KK29iamVjdCBHZXRQbGFudChzdHJpbmcgZmlsZW5hbWUpCit7CisgIGludCAqYXJyPXBsYW50TWFwW2ZpbGVuYW1lXTsKKyAgaWYgKCFwb2ludGVycChhcnIpIHx8IHNpemVvZihhcnIpPDIpCisgIHsKKyAgICAgYXJyPXBsYW50TWFwW2ZpbGVuYW1lXT0oeyAwLCAwIH0pOworICB9CisgIC8vIGFyclswXSBlbnRoYWVsdCBkZW4gWmVpdHB1bmt0LCB3YW5uIGRhcyBLcmF1dCBuYWNoZ2V3YWNoc2VuIGlzdCwKKyAgaW50IG5hY2hnZXdhY2hzZW4gPSBhcnJbMF07CisgIC8vIGFyclsxXSBkZW5qZW5pZ2VuLCB3YW5uIGVzIHZvbGxzdGFlbmRpZyByZWdlbmVyaWVydCBpc3QuCisgIGludCByZWdlbmVyaWVydCA9IGFyclsxXTsKKworICAvLyBWb3IgZGVtIE5hY2hnZXdhY2hzZW4tWmVpdHB1bmt0IGthbm4gbWFuIGdhciBuaXggZXJudGVuLgorICBpZiAodGltZSgpPG5hY2hnZXdhY2hzZW4pIHJldHVybiAwOyAvLyBub2NoIG5pY2h0IG5hY2hnZXdhY2hzZW4KKworICAvLyBSZXN0emVpdCBiaXMgenVyIHZvbGxzdGFlbmRpZ2VuIFJlZ2VuZXJhdGlvbi4KKyAgcmVnZW5lcmllcnQtPXRpbWUoKTsKKyAgCisgIC8vIFdlbm4gdm9sbHN0YWVuZGlnIHJlZ2VuZXJpZXJ0LCBpc3QgU1REX1dBQ0hTVFVNIGRpZSBuZXVlIFplaXQgYmlzIHp1cgorICAvLyBSZWdlbmVyYXRpb24uIFdlbm4gbm9jaCBuaWNodCB2b2xsc3RhZW5kaWcgcmVnZW5yaWVydCwgUmVzdHplaXQKKyAgLy8gdmVyZG9wcGVsbiB1bmQgU1REX1dBQ0hTVFVNIG5vY2htYWwgZHJhdWYgYWRkaWVyZW4uCisgIHJlZ2VuZXJpZXJ0ID0gKHJlZ2VuZXJpZXJ0PD0wID8gU1REX1dBQ0hTVFVNIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IChyZWdlbmVyaWVydCoyKStTVERfV0FDSFNUVU0pOworICAvLyBuYWNoZ2V3YWNoc2VuIGlzdCBkaWUgaGFsYmUgUmVnZW5lcmF0aW9uc3plaXQKKyAgYXJyWzBdPW5hY2hnZXdhY2hzZW49dGltZSgpKyhyZWdlbmVyaWVydC8yKTsKKyAgLy8gWmVpdCB2b2VsbGlnZXIgUmVnZW5lcmF0aW9uCisgIGFyclsxXT1yZWdlbmVyaWVydCs9dGltZSgpOworICAKKyAgcmV0dXJuIGNsb25lX29iamVjdChmaWxlbmFtZSk7Cit9CisKK3N0YXRpYyBpbnQgX3BmbHVlY2tlbihzdHJpbmcgc3RyKQoreworICBpbnQgcmVzOworCisgIGlmICghbWFwcGluZ3AocGxhbnRNYXApKSByZXR1cm4gMDsKKyAgX25vdGlmeV9mYWlsKCJXQVMgbW9lY2h0ZXN0IER1IHBmbHVlY2tlbj9cbiIpOworCisgIC8vIElEcyB1bmQgQWRqZWt0aXZlIHp3aXNjaGVuc3BlaWNoZXJuCisgIG1peGVkIGlkcyA9IFF1ZXJ5KFBfSURTLCBGX1ZBTFVFKTsKKyAgbWl4ZWQgYWRqID0gUXVlcnkoUF9BREpFQ1RJVkVTLCBGX1ZBTFVFKTsKKworICBmb3JlYWNoKHN0cmluZyBrZXksIG1peGVkIGtyYXV0aW5mbyA6IHBsYW50TWFwKSAKKyAgeworICAgIGlmICggc2l6ZW9mKGtyYXV0aW5mbykgIT0gNiApCisgICAgICBjb250aW51ZTsKKyAKKyAgICAvLyBJRHMgdW5kIEFkamVrdGl2ZSBkZXMgS3JhdXRlcyBrb3BpZXJlbiAKKyAgICBTZXQoUF9JRFMsIGtyYXV0aW5mb1syXSwgRl9WQUxVRSk7CisgICAgU2V0KFBfQURKRUNUSVZFUywga3JhdXRpbmZvWzNdLCBGX1ZBTFVFKTsKKworICAgIC8vIFN5bnRheHBydWVmdW5nIHdpcmQgZGFubiBtaXQgaWQoKSBnZW1hY2h0LgorICAgIGlmIChpZChzdHIpKSAKKyAgICB7CisgICAgICBvYmplY3Qgb2I7CisgICAgICBvYmplY3QgYmV3YWNoZXI7CisgICAgICByZXM9MTsKKworICAgICAgLy8gTGlzdGUgZGVyIGVpbmdldHJhZ2VuZW4gQmV3YWNoZXItSURzIGR1cmNobGF1ZmVuIHVuZCBwcnVlZmVuLCBvYgorICAgICAgLy8gbWluZGVzdGVucyBlaW5lciBkYXZvbiBhbndlc2VuZCBpc3QuCisgICAgICBmb3JlYWNoKCBzdHJpbmcgbnBjSWQgOiBrcmF1dGluZm9bNV0gKQorICAgICAgeworICAgICAgICBiZXdhY2hlciA9IHByZXNlbnQobnBjSWQsIE1FKTsKKyAgICAgICAgaWYgKG9iamVjdHAoYmV3YWNoZXIpKQorICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgCisgICAgICBpZiAoICFQTC0+UXVlcnlQcm9wKFBfRlJFRV9IQU5EUykgKSAKKyAgICAgIHsKKyAgICAgICAgdGVsbF9vYmplY3QoUEwsIEJTKCJEdSBoYXN0IGtlaW5lIEhhbmQgZnJlaSwgdW0gZXR3YXMgcGZsdWVja2VuICIKKyAgICAgICAgICAienUga29lbm5lbi4iKSk7CisgICAgICB9CisgICAgICAvLyBJc3QgZGVyIEJld2FjaGVyIGFud2VzZW5kPyBEYW5uIGthbm4gbWFuIGRhcyBLcmF1dCBuaWNodCBwZmx1ZWNrZW4uCisgICAgICBlbHNlIGlmICggb2JqZWN0cChiZXdhY2hlcikgKQorICAgICAgeworICAgICAgICB0ZWxsX29iamVjdChQTCwgQlMoYmV3YWNoZXItPk5hbWUoV0VSLCAyKSsiIGxhZXNzdCBEaWNoICIKKyAgICAgICAgICAibGVpZGVyIG5pY2h0IG5haCBnZW51ZyBoZXJhbi4gSXJnZW5kd2llIG11c3N0IER1IERpY2ggd29obCAiCisgICAgICAgICAgInp1bmFlY2hzdCB1bSAiK2Jld2FjaGVyLT5RdWVyeVByb25vdW4oV0VOKSsiIGt1ZW1tZXJuLiIpKTsKKyAgICAgIH0KKyAgICAgIC8vIFdlbm4gR2V0UGxhbnQoKSBlaW4gT2JqZWt0IGxpZWZlcnQsIGthbm4gd2FzIGdlcGZsdWVja3Qgd2VyZGVuLgorICAgICAgZWxzZSBpZiAoIG9iamVjdHAob2I9R2V0UGxhbnQoa2V5KSkgKSAKKyAgICAgIHsKKyAgICAgICAgaWYgKCBvYi0+bW92ZShQTCwgTV9HRVQpID09IE1PVkVfT0sgKQorICAgICAgICB7CisgICAgICAgICAgd3JpdGUoQlMoIlZvcnNpY2h0aWcgcGZsdWVja3N0IER1ICIrb2ItPm5hbWUoV0VOLCAxKSsKKyAgICAgICAgICAgICIgdW5kIG5pbW1zdCAiK29iLT5RdWVyeVByb25vdW4oV0VOKSsiIGFuIERpY2guIikpOworICAgICAgICB9CisgICAgICAgIGVsc2UgCisgICAgICAgIHsKKyAgICAgICAgICB3cml0ZShCUygiVm9yc2ljaHRpZyBwZmx1ZWNrc3QgRHUgIitvYi0+bmFtZShXRU4sIDEpKyIsIGthbm5zdCAiKworICAgICAgICAgICAgb2ItPlF1ZXJ5UHJvbm91bihXRU4pKyIgYWJlciBuaWNodCBuZWhtZW4uIikpOworICAgICAgICAgIG9iLT5tb3ZlKGVudmlyb25tZW50KFBMKSwgTV9HRVQpOworICAgICAgICB9CisgICAgICB9CisgICAgICAvLyBXZW5uIGFsbGVzIG5pY2h0LCBkYW5uIGlzdCBkYXMgS3JhdXQgbm9jaCBuaWNodCB3aWVkZXIgZGEuCisgICAgICBlbHNlIAorICAgICAgeworICAgICAgICB3cml0ZShCUyhrcmF1dGluZm9bNF0rIiBpc3Qgbm9jaCBuaWNodCByZWlmIGdlbnVnICIKKyAgICAgICAgICArInVuZCBtdXNzIGVyc3Qgbm9jaCBldHdhcyB3YWNoc2VuLiIpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CisgICAvLyBJRHMgdW5kIEFkamVrdGl2ZSB6dXJ1ZWNrc2V0emVuLgorICBTZXQoUF9JRFMsIGlkcywgRl9WQUxVRSk7CisgIFNldChQX0FESkVDVElWRVMsIGFkaiwgRl9WQUxVRSk7CisKKyAgcmV0dXJuIHJlczsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3Jvb20va3JhZXV0ZXJsYWRlbi5jIGIvc3RkL3Jvb20va3JhZXV0ZXJsYWRlbi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmOTk3OTMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcm9vbS9rcmFldXRlcmxhZGVuLmMKQEAgLTAsMCArMSwxNjcgQEAKKy8vIChjKSAyMDAzIGJ5IFBhZHJlaWMgKHBhZHJlaWNAbWcubXVkLmRlKQorLy8gCisvLyBFcyBrYW5uIGJlc3RpbW10ZSBMYWVkZW4genVtIEhhbmRlbG4gdm9uIEtyYWV1dGVybiBnZWJlbi4KKy8vIFp1bmFlY2hzdCBlaW5tYWwgZ2lidCBlcyBlaW5lbiBpbiBkZXIgRHVua2VsZWxmZW5naWxkZS4KKy8vIEhpZXIga29lbm5lbiBLcmFldXRlciBnZS0gdW5kIHZlcmthdWZ0IHdlcmRlbi4KKy8vIEdydW5kc2FldHpsaWNoIGthbm4gZXMgYmVsaWViaWcgdmllbGUga3JhZXV0ZXJrdW5kaWdlCisvLyBIYWVuZGxlciBnZWJlbiwgZWluZSBrdXJ6ZSBBYnNwcmFjaGUgd2FlcmUgamVkb2NoIHZvbiBWb3J0ZWlsLgorCisvLyBEZXIgTGFkZW4gZXJ3ZWl0ZXJ0IGRpZSByb29tL3Nob3AgRnVua3Rpb25lbi4KKy8vIFp1ciBWZXJ3ZW5kdW5nIG11c3MgZGllc2VyIG5vY2ggbWl0IGVpbmVtIHN0ZC9yb29tIGtvbWJpbmllcnQKKy8vIHdlcmRlbi4gRGllcyBlcmxhdWJ0IGRpZSBWZXJ3ZW5kdW5nIHZvbiBlaWdlbmVuIFN0YW5kYXJkcmFldW1lbiBvZGVyCisvLyBLb21iaW5hdGlvbiBtaXQgS25laXBlbi4KKworaW5oZXJpdCAiL3N0ZC9yb29tL3Nob3AiOworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8aXRlbXMva3JhZXV0ZXIva3JhZXV0ZXIuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisKKy8vIEZsYWcsIGRhcyBpbSByZXNldCgpIGRhcyBTcGVpY2hlcm4gYXVzbG9lc3QsIHdlbm4gZXMgZ2VzZXR6dCBpc3QuCitzdGF0aWMgIGludCBuZWVkX3NhdmU7ICAKK3N0YXRpYyAgaW50IGJhc2lzdmFsdWU9NDAwOyAvLyBnaWJ0IGRlbiBfRHVyY2hzY2huaXR0c3dlcnRfIGVpbmVzIEtyYXV0cyBhbgorc3RhdGljICBpbnQgbWF4dmFsdWU9MTAwMDA7IC8vIGJlc3RpbW10IGRlbiBtYXguIFdlcnQgYWxsZXIgS3JhZXV0ZXIKKworLy8gRW50aGFlbHQgZnVlciBqZWRlIFBsYW50SUQgZWluZW4gWmFlaGxlciwgZGVyIGFuZ2lidCwgd2lldmllbCB2b24gZGVtCisvLyBqZXdlaWxpZ2VuIEtyYXV0IHZlcmthdWZ0IHd1cmRlLgorLy8gcHJpdmF0ZSBpbnQgKmNvdW50PSh7fSk7CisKKy8vIFN1bW1lIHVlYmVyIGFsbGUgRWludHJhZWdlIGluIGNvdW50CisvLyBwcml2YXRlIGludCBzdW07CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIGlmIChvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSA9PSBfX0ZJTEVfX1swLi48M10pCisgIHsKKyAgICBzZXRfbmV4dF9yZXNldCgtMSk7CisgICAgcmV0dXJuOworICB9CisgIDo6Y3JlYXRlKCk7CisKKyAgU2V0UHJvcChQX0JVWV9PTkxZX1BMQU5UUywxKTsKKyAgLyoKKyAgc2V0ZXVpZChnZXR1aWQoKSk7IC8vIHdpcmQgenVtIHNwZWljaGVybiBiZW72dGlndAorICBpbnQgc2k9c2l6ZW9mKGNvdW50KTsKKyAgLy8gZnVlciBqZWRlIFBsYW50SUQgZWluZW4gRWludHJhZyBhbmxlZ2VuLCBkLmguIHdlbm4gaW4gY291bnQgbm9jaAorICAvLyBuaWNodCBnZW51ZyB2b3JoYW5kZW4gc2luZCwgd2VyZGVuIGZlaGxlbmRlIEVpbnRyYWVnZSBlcmdhZW56dC4KKyAgaWYgKHNpPFBMQU5UQ09VTlQpIAorICAgIGNvdW50PWNvdW50K2FsbG9jYXRlKFBMQU5UQ09VTlQtc2kpOworICAqLworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKQoreworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKK3N0YXRpYyBzdHJpbmcgc2VsbF9vYmpfb25seV9wbGFudHMob2JqZWN0IG9iLCBpbnQgc2hvcnQpCit7CisgICBpZiAoIUlTX1BMQU5UKG9iKSkKKyAgICAgIHJldHVybiAiVHV0IG1pciBsZWlkLCBkYW1pdCBrYW5uIGljaCBuaWNodHMgYW5mYW5nZW4uIjsKKyAgIC8vIGVzIHdlcmRlbiBudXIgS3JhZXV0ZXIgYW5nZWthdWZ0LCBkaWUgbGVnYWwgZ2VjbG9udCB3dXJkZW4sCisgICAvLyBkLmguIGltIGVudHNwcmVjaGVuZGVuIE1hc3RlciBvcmRlbnRsaWNoIGVpbmdldHJhZ2VuIHd1cmRlbiEKKyAgIGlmIChvYi0+UXVlcnlQbGFudElkKCk8PTApCisgICAgICByZXR1cm4gb2ItPk5hbWUoV0VSLCAyKSsiIGlzdCBpbGxlZ2FsIGF1ZiBkaWUgV2VsdCBnZWtvbW1lbi4gSWNoIGRhcmYgIgorICAgICAgICAgICAgK29iLT5RdWVyeVByb25vdW4oV0VOKSsiIGxlaWRlciBuaWNodCBhbm5laG1lbi4iOworICAgcmV0dXJuIDo6c2VsbF9vYmoob2IsIHNob3J0KTsKK30KKworc3RhdGljIHN0cmluZyBzZWxsX29iaihvYmplY3Qgb2IsIGludCBzaG9ydCkKK3sKKyAgIC8vIGVzIHdlcmRlbiBudXIgS3JhZXV0ZXIgYW5nZWthdWZ0LCBkaWUgbGVnYWwgZ2VjbG9udCB3dXJkZW4sCisgICAvLyBkLmguIGltIGVudHNwcmVjaGVuZGVuIE1hc3RlciBvcmRlbnRsaWNoIGVpbmdldHJhZ2VuIHd1cmRlbiEKKyAgaWYgKElTX1BMQU5UKG9iKSAmJiBvYi0+UXVlcnlQbGFudElkKCk8PTApCisgICAgcmV0dXJuICJIbSwgIitvYi0+TmFtZShXRVIsIDIpKyIgc3RhbW10IGFiZXIgYXVzIGVpbmVyIHNlaHIgZHViaW9zZW4gIgorICAgICAgIlF1ZWxsZS4gSWNoIGthbm4gIitvYi0+UXVlcnlQcm9ub3VuKFdFTikrIiBsZWlkZXIgbmljaHQgYW5uZWhtZW4uIjsKKyAgaWYgKFF1ZXJ5UHJvcChQX0JVWV9PTkxZX1BMQU5UUykpCisgICAgcmV0dXJuIHNlbGxfb2JqX29ubHlfcGxhbnRzKG9iLCBzaG9ydCk7CisgIHJldHVybiA6OnNlbGxfb2JqKG9iLHNob3J0KTsKK30KKworLyoKK3ZvaWQgcmVzZXQoKQoreworICA6OnJlc2V0KCk7CisgIC8vIERhdGVuIHNpbmQgbmljaHQgc29vbyB3aWNodGlnLCBhbHMgZGFzIGJlaSBqZWRlciBBZW5kZXJ1bmcKKyAgLy8gZ2VzYXZldCB3ZXJkZW4gbXVlc3N0ZS4gRGFoZXIgbnVuIGltIHJlc2V0IHNwZWljaGVybi4KKyAgaWYgKG5lZWRfc2F2ZSkgeworICAgIC8vIGJhc2lzdmFsdWUvUExBTlRDT1VOVDogRHVyY2hzY2huaXR0c3dlcnQgZWluZXMgZWluemVsbmVuIEtyYXV0cworICAgIC8vIHN1bSArIFBMQU5UQ09VTlQ6IEdlc2FtdHphaGwgdmVya2F1ZnRlciBwbHVzIFphaGwgZXhpc3RpZXJlbmRlcgorICAgIC8vICAgICAgICAgICAgICAgICAgIEtyYWV1dGVyCisgICAgLy8gV2VubiBhbHNvIGRlciBXZXJ0IGFsbCBkaWVzZXIgS3JhZXV0ZXIgPiAxMGsgaXN0LCB3aXJkIGplZGVyCisgICAgLy8gRWluemVsemFlaGxlciBhdWYgOTAlIGdlc3R1dHp0LCBkYW1pdCBkaWUgV2VydGUgbmljaHQgaW5zIFVmZXJsb3NlCisgICAgLy8gc3RlaWdlbi4KKyAgICBpZiAoKChzdW0rUExBTlRDT1VOVCkqYmFzaXN2YWx1ZS9QTEFOVENPVU5UKT5tYXh2YWx1ZSkgeworICAgICAgaW50IGksIG5ld3N1bTsKKyAgICAgIGZvciAoaT1zaXplb2YoY291bnQpLTE7IGk+PTA7IGktLSkgeworICAgICAgICBjb3VudFtpXSA9IGNvdW50W2ldKjkvMTA7CisgICAgICAgIG5ld3N1bSs9Y291bnRbaV07CisgICAgICB9CisgICAgICBzdW09bmV3c3VtOworICAgIH0KKyAgICBuZWVkX3NhdmU9MDsKKyAgfQorfQorCisvLyBBa3R1YWxpc2llcnQgZGVuIERhdGVuYmVzdGFuZCBiZWltIEthdWZlbiBvZGVyIFZlcmthdWZlbiBlaW5lcyBPYmpla3RzCit2b2lkIFVwZGF0ZUNvdW50ZXIob2JqZWN0IG9iLCBpbnQgbnVtKQoreworICAgaW50IGlkPW9iLT5RdWVyeVBsYW50SWQoKTsKKyAgIGlmIChpZD4wICYmIGlzX3BsYW50KG9iKSkgeworICAgICAgLy8gS2F1ZiBvZGVyIFZlcmthdWYgdm9uIEtyYWV1dGVybiwgdmVyYWVuZGVydCBkZW4gV2VydCBkZXIKKyAgICAgIC8vIEtyYWV1dGVyCisgICAgICAvLyBaYWVobGVyIGluIGRlciBMaXN0ZSBob2NoemFlaGxlbgorICAgICAgY291bnRbaWRdKz1udW07CisgICAgICBpZiAoY291bnRbaWRdPDApIGNvdW50W2lkXT0wOyAvLyBkYXJmIGFiZXIgYW5zaWNoIG5pY2ggcGFzc2llcmVuCisgICAgICAvLyBHZXNhbXRzdW1tZSBha3R1YWxpc2llcmVuCisgICAgICBzdW0rPW51bTsKKyAgICAgIG5lZWRfc2F2ZT0xOworICAgfQorICAgOjpVcGRhdGVDb3VudGVyKG9iLCBudW0pOworfQorCisvLyBEaWUgUHJlaXNlIGRpZSBoaWVyIGltIExhYm9yIGZ1ZXIgS3JhZXV0ZXIgZ2V6YWhsdCB1bmQgdmVybGFuZ3QKKy8vIHdlcmRlbiwgc2luZCBuaWNodCBmaXggc29uZGVybiBoYWVuZ2VuIHZvbiBBbmdlYm90IHVuZCBOYWNoZnJhZ2UgYWIuCisvLyBIaWVyIHdlaXNzIG1hbiB1ZWJlciBkZW4gd2FocmVuIFdlcnQgZGVyIGVpbnplbG5lbiBLcmFldXRlciBiZXNjaGVpZC4KK3N0YXRpYyBpbnQgcmVhbFZhbHVlKG9iamVjdCBvYiwgb2JqZWN0IHBsYXllcikKK3sKKyAgIC8vIFByZWlzZSBmdWVyIG5vcm1hbGUgR3VldGVyIGdhbnogbm9ybWFsLi4uCisgICBpZiAoIWlzX3BsYW50KG9iKSkKKyAgICAgICByZXR1cm4gb2ItPlF1ZXJ5UHJvcChQX1ZBTFVFKTsKKworICAgLy8gamVkZSBLcmFldXRlcmthdGVnb3JpZSBiZWtvbW10IGRlbiBnbGVpY2hlbiBXZXJ0IHp1Z2V3aWVzZW4uICAgCisgICAvLyB2YWwgZW50c3ByaWNodCBkZW0gYWt0dWVsbGVuICJEdXJjaHNjaG5pdHRzd2VydCIgZWluZXMgS3JhdXRlcworICAgaW50IHZhbD0oc3VtK1BMQU5UQ09VTlQpKmJhc2lzdmFsdWUvUExBTlRDT1VOVDsKKworICAgLy8gYWJlciBkaWVzZXIgV2VydCB2ZXJ0ZWlsdCBzaWNoIGF1ZiB1bnRlcnNjaGllZGxpY2ggdmllbGUgS3JhZXV0ZXIKKyAgIC8vIChBTjogRGllc2VyIEtvbW1lbnRhciBlcnNjaGxpZXNzdCBzaWNoIG1pciBuaWNodC4pCisgICBpbnQgaWQ9b2ItPlF1ZXJ5UGxhbnRJZCgpOworICAgaWYgKGlkPD0wKSByZXR1cm4gMDsgLy8gaWxsZWdhbCBnZWNsb250IC0+IHdlcnRsb3MKKyAgIC8vIGdnZi4gZGllIFphZWhsZXJsaXN0ZSB1bSBkaWUgZmVobGVuZGVuIEVpbnRyYWVnZSBlcndlaXRlcm4uCisgICBpZiAoKGlkLTEpPnNpemVvZihjb3VudCkpIAorICAgICBjb3VudD1jb3VudCthbGxvY2F0ZShpZC0xLXNpemVvZihjb3VudCkpOworICAgCisgICAvLyAibWl0dGxlcmVuIFdlcnQiIGRlcyBhYmdlZnJhZ3RlbiBLcmF1dGVzIGVycmVjaG5lbiAoRGl2aXNpb24gZHVyY2gKKyAgIC8vIGRlc3NlbiB1bWdlc2V0enRlIEFuemFobCkKKyAgIHZhbD12YWwvKGNvdW50W2lkXSsxKTsKKyAgIAorICAgLy8gV2VydCBydW5kZW4gYXVmIG5hZWNoc3RuaWVkcmlnZXJlbiBnbGF0dCBkdXJjaCAxMCB0ZWlsYmFyZW4gV2VydC4KKyAgIHJldHVybiB2YWwtdmFsJTEwOyAKK30KKworLy8gZ2lidCBkZW4gUHJlaXMgenVy/GNrLCBkZXIgenVtIEFua2F1ZiBkZXMgT2JqZWt0ZXMgdmVyd2VuZGV0IHdlcmRlbiBzb2xsCitzdGF0aWMgdmFyYXJncyBpbnQgUXVlcnlWYWx1ZShvYmplY3Qgb2IsIGludCB2YWx1ZSwgb2JqZWN0IHBsYXllcikKK3sKKyAgIHJldHVybiA6OlF1ZXJ5VmFsdWUob2IsIHJlYWxWYWx1ZShvYiwgcGxheWVyKSwgcGxheWVyKTsKK30KKworLy8gZ2lidCBkZW4gUHJlaXMgYW4sIHp1IGRlbSBkYXMgT2JqZWt0IHZlcmthdWZ0IHdlcmRlbiBzb2xsLgorc3RhdGljIHZhcmFyZ3MgaW50IFF1ZXJ5QnV5VmFsdWUobWl4ZWQgb2IsIG9iamVjdCBwbGF5ZXIpCit7CisgICBpZiAob2JqZWN0cChvYikpCisgICAgICByZXR1cm4gKHJlYWxWYWx1ZShvYiwgcGxheWVyKSpRdWVyeUJ1eUZhY3QocGxheWVyKSArIDUwKS8xMDA7CisgICAvLyBmaXhlZCBPYmpla3RlLi4uCisgICByZXR1cm4gOjpRdWVyeUJ1eVZhbHVlKG9iLCBwbGF5ZXIpOworfQorKi8KZGlmZiAtLWdpdCBhL3N0ZC9yb29tL2xpZ2h0LmMgYi9zdGQvcm9vbS9saWdodC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEzNzIwNDcKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcm9vbS9saWdodC5jCkBAIC0wLDAgKzEsNjEgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBjb250YWluZXIvbGlnaHQuYyAtLSBMaWNodHN5c3RlbWtvbXBvbmVudGVuIGZ1ZXIgUmFldW1lCisvLworLy8gJElkOiBkZXNjcmlwdGlvbi5jIDY5ODYgMjAwOC0wOC0yMiAyMTozMjoxNVogWmVzc3RyYSAkCisKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL2xpZ2h0IjsKKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcyxydHRfY2hlY2tzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KKyNpbmNsdWRlIDxyb29tL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8Y29udGFpbmVyLmg+CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIDo6Y3JlYXRlKCk7CisgIFNldFByb3AoUF9MSUdIVF9BQlNPUlBUSU9OLCAxKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkge3NldF9uZXh0X3Jlc2V0KC0xKTt9CisKKy8qCisgICAvLyBkYXMgd2lyZCBzZWx0ZW4gYmVudXR6dCB1bmQgaXN0IHp1ciB6ZWl0IGZ1bmt0aW9uc3VuZmFlaGlnLCBkYSBkaWUKKyAgIC8vIGludGVybmUgU3BlaWNoZXJ1bmcgZGVyIFByb3Agc2ljaCBnZWFlbmRlcnQgaGF0Lgorc3RhdGljIGludCBfc2V0X2ludF9saWdodChpbnQgKmxpZ2h0KQoreworICAgaW50IHRtcDsKKworICAgLy8genVyIFNpY2hlcmhlaXQKKyAgIGlmICghcG9pbnRlcnAobGlnaHQpKSByZXR1cm4gLTE7CisgICBpZiAobGlnaHRbMF0+UXVlcnlQcm9wKFBfTElHSFQpKSB7CisgICAgICAvLyBMaWNodCB2ZXJsYWV1ZnQgc2ljaCBpbiBlaW5lbSBncm9zc2VuIFJhdW0sIGRhaGVyIE1vZGlmaWVyIGFiZnJhZ2VuLi4uCisgICAgICB0bXA9bGlnaHRbMF0tUXVlcnlQcm9wKFBfTElHSFRfQUJTT1JQVElPTik7CisgICAgICAvLyB3ZW5uIHNpY2ggZGFzIFZvcnplaWNoZW4gZ2VhZW5kZXJ0IGhhdCwgYXVmIDAgc2V0emVuLgorICAgICAgbGlnaHRbMF09KCh0bXBebGlnaHRbMF0pICYgMHg4MDAwMDAwMCA/IDAgOiB0bXApOworICAgfQorICAgaWYgKGxpZ2h0WzFdPFF1ZXJ5UHJvcChQX0xJR0hUKSAmJiBsaWdodFsxXTwwKSB7CisgICAgICAvLyBMaWNodCB2ZXJsYWV1ZnQgc2ljaCBpbiBlaW5lbSBncm9zc2VuIFJhdW0sIGRhaGVyIE1vZGlmaWVyIGFiZnJhZ2VuLi4uCisgICAgICB0bXA9bGlnaHRbMV0rUXVlcnlQcm9wKFBfTElHSFRfQUJTT1JQVElPTik7CisgICAgICAvLyB3ZW5uIHNpY2ggZGFzIFZvcnplaWNoZW4gZ2VhZW5kZXJ0IGhhdCwgYXVmIDAgc2V0emVuLgorICAgICAgbGlnaHRbMV09KCh0bXBebGlnaHRbMV0pICYgMHg4MDAwMDAwMCA/IDAgOiB0bXApOworICAgfQorICAgbGlnaHRbMl09bGlnaHRbMF0rbGlnaHRbMV07CisgICBTZXQoUF9JTlRfTElHSFQsIGxpZ2h0LCBGX1ZBTFVFKTsKKyAgIC8vIGRpZXNlIFByb3Agc2V0emVuIGthdW0gTGV1dGUgKG9mZml6aWVsbCBnZWh0cyBqYSBhdWNoIGdhciBuaWNodC4gS2VpbmVyCisgICAvLyBkYXZvbiBlcndhcnRldCBuZW4gUnVlY2tnYWJld2VydC4gRGFoZXIgd2lyZCBoaWVyIDAgenVydWVja2dlYmVuLCBzdGF0dAorICAgLy8gZGVzIGF1ZndhZW5kaWcgYmVyZWNobmV0ZW4gUXVlcnlQcm9wKFBfSU5UX0xJR0hUKS4KKyAgIC8vIEFjaGphLiBEZXIgUnVlY2tnYWJld2VydCB2b20gU2V0KCkgd2FlcmUgZWluIGludCosIHdhcyBuaWNodCBnZWh0LCB3ZWlsCisgICAvLyBkaWVzZSBGdW5rdGlvbiBudXIgaW50IHp1cnVlY2tnZWJlbiBkYXJmLgorICAgcmV0dXJuIDA7Cit9CisqLwpkaWZmIC0tZ2l0IGEvc3RkL3Jvb20vbW92aW5nLmMgYi9zdGQvcm9vbS9tb3ZpbmcuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZjdjMmIxCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3Jvb20vbW92aW5nLmMKQEAgLTAsMCArMSwxNyBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHJvb20vbW92aW5nLmMgLS0gRW50ZmVybmVuIHZvbiBSYWV1bWVuCisvLworLy8gJElkOiBtb3ZpbmcuYyA4MDQxIDIwMTItMDMtMTkgMTg6Mzg6MjFaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisKK3B1YmxpYyB2YXJhcmdzIGludCByZW1vdmUoaW50IHNpbGVudCkKK3sKKyAgZGVzdHJ1Y3QoIHRoaXNfb2JqZWN0KCkgKTsKKyAgcmV0dXJuIDE7Cit9CmRpZmYgLS1naXQgYS9zdGQvcm9vbS9wYXJhLmMgYi9zdGQvcm9vbS9wYXJhLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDY2Njc4MgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9yb29tL3BhcmEuYwpAQCAtMCwwICsxLDE4IEBACisvLyBUaGlzIG1heSBsb29rIGxpa2UgQyBjb2RlLCBidXQgaXQgaXMgcmVhbGx5IC0qLSBDKysgLSotCisKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyByb29tL3BhcmEuYyAtLSBCZXRyZXRlbiBlaW5lciBQYXJhbGxlbHdlbHQKKy8vCisvLyAkSWQ6IHBhcmEuYyA3NTEwIDIwMTAtMDMtMjUgMjM6Mzc6MTlaIFplc3N0cmEgJAorCisvLyBWZXJhbHRldCAtIHdpcmQgbmljaHQgbWVociBiZW5vZXRpZ3QuCisvLyBEaWUgWnVvcmRudW5nIGRlciAncmljaHRpZ2VuJyBXZWx0IHdpcmQgamV0enQgZGlyZWt0IHZvbiBtb3ZlKCkgdWViZXJub21tZW4uCisKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKworZGVwcmVjYXRlZCBpbnQgcGFyYW1vdmUoKSB7IHJldHVybiAwOyB9CmRpZmYgLS1naXQgYS9zdGQvcm9vbS9wdWIuYyBiL3N0ZC9yb29tL3B1Yi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxNWUzM2UKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcm9vbS9wdWIuYwpAQCAtMCwwICsxLDk4OSBAQAorLy8KKy8vIHB1Yi5jIC0tIEFsbGVzLCB3YXMgZWluZSBLbmVpcGUgYnJhdWNodC4KKy8vCisvLyAkSWQ6IHB1Yi5jIDg3NzggMjAxNC0wNC0zMCAyMzowNDowNlogWmVzc3RyYSAkCisvLyBzcGVuZGllcmUgdWViZXJhcmJlaXRldCwgMjIuMDUuMjAwNyAtIE1pcmlsCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvY29tbWFuZHMuaD4KKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisKKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8cm9vbXMuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8cm91dGluZ2QuaD4KKyNpbmNsdWRlIDxiYW5rLmg+CisjaW5jbHVkZSA8ZXhwbG9yYXRpb24uaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxwdWIuaD4KKworLy8gQWxsZSBuaWNodC1wcml2YXRlbiB3ZXJkZW4gaW4gZXJiZW5lbiBPYmpla3RlbiB2ZXJ3ZW5kZXQuCitwcml2YXRlIG5vc2F2ZSBpbnQgICAgIG1heF9saXN0OworcHJpdmF0ZSBub3NhdmUgaW50ICAgICByZWZyZXNoX2NvdW50OworcHJpdmF0ZSBub3NhdmUgaW50ICAgICBzdW07Citwcml2YXRlIG5vc2F2ZSBtYXBwaW5nIHJlZnJlc2hfbGlzdDsKK25vc2F2ZSBtYXBwaW5nIGlkX2xpc3Q7Citub3NhdmUgbWFwcGluZyBtZW51X2xpc3Q7Citub3NhdmUgb2JqZWN0ICAqd2FpdGluZzsKKworI2RlZmluZSBQTV9SQVRFX1BVQk1BU1RFUiAgInJhdGUiCisjZGVmaW5lIFBNX0RFTEFZX1BVQk1BU1RFUiAiZGVsYXkiCisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7IG9iamVjdCByb3V0ZXI7CisKKyAgU2V0UHJvcCggUF9ST09NX1RZUEUsIFF1ZXJ5UHJvcChQX1JPT01fVFlQRSkgfCBSVF9QVUIgKTsKKworICBTZXRQcm9wKCBQX1BVQl9OT1RfT05fTUVOVSwKKyAgICAiVHV0IG1pciBsZWlkLCBkYXMgZnVlaHJlbiB3aXIgbmljaHQhIFdpciBzaW5kIGVpbiBhbnN0YWVuZGlnZXMgIisKKyAgICAiTG9rYWwhXG4iICk7CisgIFNldFByb3AoIFBfUFVCX1VOQVZBSUxBQkxFLAorICAgICJEYXZvbiBpc3QgbGVpZGVyIG5pY2h0cyBtZWhyIGRhLlxuIiApOworICBTZXRQcm9wKFBfUFVCX05PX01PTkVZLAorICAgICJEYXMga29zdGV0ICVkIEdvbGRzdHVlY2tlLCB1bmQgRHUgaGFzdCBuaWNodCBzbyB2aWVsIVxuIiApOworICBTZXRQcm9wKFBfUFVCX05PX0tFRVBFUiwKKyAgICAiRXMgaXN0IG5pZW1hbmQgYW53ZXNlbmQsIGRlciBEaWNoIGJlZGllbmVuIGtvZW5udGUuXG4iKTsKKworICBBZGRDbWQoICJtZW51ZSIsIm1lbnVlIiApOworICBBZGRDbWQoICh7ImthdWYiLCJrYXVmZSIsImJlc3RlbGwiLCJiZXN0ZWxsZSJ9KSwiYmVzdGVsbGUiICk7CisgIEFkZENtZCggKHsic3BlbmRpZXIiLCJzcGVuZGllcmUifSksInNwZW5kaWVyZSIgKTsKKyAgQWRkQ21kKCAicHViaW5pdCIsInB1YmluaXQiICk7CisKKyAgbWF4X2xpc3Q9MDsKKyAgcmVmcmVzaF9jb3VudD0wOworICB3YWl0aW5nID0gKHsgfSk7CisgIGlkX2xpc3Q9KFtdKTsKKyAgbWVudV9saXN0PShbXSk7CisgIHJlZnJlc2hfbGlzdD0oW10pOworCisgIGlmICggIWNsb25lcChNRSkgJiYgb2JqZWN0cChyb3V0ZXI9ZmluZF9vYmplY3QoUk9VVEVSKSkgKQorICAgIHJvdXRlci0+UmVnaXN0ZXJUYXJnZXQoVEFSR0VUX1BVQixvYmplY3RfbmFtZShNRSkpOworCisgIGNhbGxfb3V0KCJhZGRfc3RkX2RyaW5rcyIsMSk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfQorCisvKiBadXIgU3ludGF4OgorICoKKyAqIG1lbnVldGV4dCAtIERlciBUZXh0IHN0ZWh0IGltIE1lbnVlCisgKgorICogaWRzICAgICAgIC0gQXJyYXkgZGVyIE5hbWVuLCBtaXQgZGVuZW4gYmVzdGVsbHQgd2VyZGVuIGthbm4KKyAqCisgKiBtaW5mbyAgICAgLSBNYXBwaW5nIG1pdCBFaW50cmFlZ2VuIGZ1ZXI6CisgKiAgICAgICAgICAgICAgICAgUF9IUCAoSFAtSGVpbHVuZyksCisgKiAgICAgICAgICAgICAgICAgUF9TUCAoU1AtSGVpbHVuZyksCisgKiAgICAgICAgICAgICAgICAgUF9GT09EIChTYWV0dGlndW5nKSwKKyAqICAgICAgICAgICAgICAgICBQX0RSSU5LIChGbHVlc3NpZ2tlaXQpCisgKiAgICAgICAgICAgICAgICAgUF9BTENPSE9MIChBbGtvaG9saXNpZXJ1bmcpCisgKiAgICAgICAgICAgICAgICAgUF9WQUxVRSAoUHJlaXMpCisgKiAgICAgICAgICAgICBEaWUgRWludHJhZWdlIHdlcmRlbiB1ZWJlciBldmFsX2FueXRoaW5nIGF1c2dld2VydGV0CisgKiAgICAgICAgICAgICAoc2llaGUgZGEpCisgKgorICogcmF0ZSAgICAgIC0gSGVpbHJhdGUgKGF1Y2ggdWViZXIgZWF2bF9hbnl0aGluZykgaW4gUHVua3RlIC8gaGVhcnRfYmVhdCgpCisgKgorICogbXNnICAgICAgIC0gTWVsZHVuZyBiZWltIEVzc2VuLgorICogICAgICAgICAgICAgYSkgY2xvc3VyZSAod2lyZCBtaXQgZnVuY2FsbChtc2csemFobGVyLGVtcGZhZW5nZXIpCisgKiAgICAgICAgICAgICAgICBhdXNnZXdlcnRldCkKKyAqICAgICAgICAgICAgIGIpIHN0cmluZyAod2llIGNsb3N1cmU6IGNhbGxfb3RoZXIodGhpc19vYmplY3QuLi4pKQorICogICAgICAgICAgICAgYykgYXJyYXkgbWl0IDIgc3RyaW5nczogMSkgZnVlciBFc3NlbmRlbiwgMikgZnVlciBhbmRlcmUKKyAqICAgICAgICAgICAgICAgIHNpZWhlIGF1Y2ggbWVzcygpCisgKgorICogcmVmcmVzaCAgIC0gTWFwcGluZyBtaXQgZGVuIG1vZWdsaWNoZW4gRWludHJhZWdlbjoKKyAqICAgICAgICAgICAgICAgICBQUl9VU0VSIDogPEtvbnRpbmdlbnQ+IDsgPFVwZGF0ZT4gKHBybyBTcGllbGVyKQorICogICAgICAgICAgICAgICAgIFBSX0FMTCAgOiA8S29udGluZ2VudD4gOyA8VXBkYXRlPiAoZnVlciBhbGxlKQorICogICAgICAgICAgICAgRXMgd2lyZCB6dW5hZWNoc3QgZ2VwcnVlZnQsIG9iIG5vY2ggZXR3YXMgZnVlciBkZW4KKyAqICAgICAgICAgICAgICh6YWhsZW5kZW4hKSBTcGllbGVyIHNlbGJzdCB2b3JoYW5kZW4gaXN0IHdlbm4gbmVpbiB3aXJkCisgKiAgICAgICAgICAgICBnZXNjaGF1dCwgb2IgZGFzIEtvbnRpbmdlbnQgZnVlciBhbGxlIHNjaG9uIGVyc2Nob2VwZnQgaXN0LgorICogICAgICAgICAgICAgU2luZCBiZWlkZSBLb250aW5nZW50ZSBlcnNjaG9lcGZ0LCBrYW5uIGRlciBTcGllbGVyIGRhcworICogICAgICAgICAgICAgQmVzdGVsbHRlIG5pY2h0IGJla29tbWVuLgorICogICAgICAgICAgICAgRGllIEtvbnRpbmdlbnRlIHdpcmQgYWxsZSA8VXBkYXRlPiByZXNldCgpcyAiYXVmZ2VmcmlzY2h0Ii4KKyAqICAgICAgICAgICAgIDxLb250aW5nZW50PiB3aXJkIHVlYmVyIGV2YWxfYW55dGhpbmcoKSBhdXNnZXdlcnRldC4KKyAqICAgICAgICAgICAgIEFsdGVybmF0aXYga2FubiBtYW4gZWluZW4gSW50LVdlcnQgYW5nZWJlbi4gRGllc2VyIHdpcmQgd2llCisgKiAgICAgICAgICAgICAoWyBQUl9BTEwgOiA8d2VydD4gOyAxIF0pIGJlaGFuZGVsdC4KKyAqCisgKiBkZWxheSAgICAgLSBaYWhsIGRlciBTZWt1bmRlbiwgdW0gZGllIHZlcnpvZWdlcnQgZGllIEhlaWx1bmcgZWludHJpdHQKKyAqICAgICAgICAgICAgIHouQi4gd2VpbCBkYXMgRXNzZW4gZXJzdCB6dWJlcmVpdGV0IHdlcmRlbiBtdXNzLgorICogICAgICAgICAgICAgRWJlbmZhbGxzIHVlYmVyIGV2YWxfYW55dGhpbmcoKQorICoKKyAqIGRfbXNnICAgICAtIE1lbGR1bmcgYmVpbSBiZXN0ZWxsZW4sIGZhbGxzIERlbGF5LiBXaWUgbXNnLgorICovCit2YXJhcmdzIHN0cmluZyBBZGRUb01lbnUoc3RyaW5nIG1lbnVldGV4dCwgbWl4ZWQgaWRzLCBtYXBwaW5nIG1pbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgIG1peGVkIHJhdGUsIG1peGVkIG1zZywgbWl4ZWQgcmVmcmVzaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBtaXhlZCBkZWxheSwgbWl4ZWQgZF9tc2cpCit7IHN0cmluZyBpZGVudDsKKyAgaW50IGk7CisKKyAgaWYgKCAhc3RyaW5ncChtZW51ZXRleHQpIHx8ICFpZHMgfHwgIW1hcHBpbmdwKG1pbmZvKSApCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKCBzdHJpbmdwKGlkcykgKQorICAgIGlkcyA9ICh7IGlkcyB9KTsKKyAgZWxzZSBpZiAoICFwb2ludGVycChpZHMpICkKKyAgICByZXR1cm4gMDsKKworICBpZGVudCA9IHNwcmludGYoIm1lbnVlbnRyeSVkIixtYXhfbGlzdCk7CisgIG1heF9saXN0Kys7CisKKyAgLyogRnVlciBzY2huZWxsZXMgTmFjaHNjaGxhZ2VuIGVpbiBlaWdlbmVzIE1hcHBpbmcgZnVlciBJZHMgKi8KKyAgZm9yKCBpPXNpemVvZihpZHMpLTE7aT49MDtpLS0gKQorICAgIGlkX2xpc3QgKz0gKFsgaWRzW2ldIDogaWRlbnQgXSk7CisKKyAgaWYgKCBpbnRwKHJlZnJlc2gpICYmIChyZWZyZXNoPjApICkKKyAgICByZWZyZXNoID0gKFsgUFJfQUxMIDogcmVmcmVzaDsgMSBdKTsKKyAgZWxzZSBpZiAoICFtYXBwaW5ncChyZWZyZXNoKSApCisgICAgcmVmcmVzaCA9IDA7CisKKyAgbWVudV9saXN0ICs9IChbIGlkZW50IDogbWVudWV0ZXh0OyBtaW5mbzsgcmF0ZTsgbXNnOyByZWZyZXNoOworICAgICAgICAgICAgICAgICAgIGRlbGF5OyBkX21zZzsgaWRzIF0pOworICByZXR1cm4gaWRlbnQ7Cit9CisKKy8vIERpZXNlIE1ldGhvZGUgaXN0IG51ciBub2NoIGF1cyBLb21wYXRpYmlsaXRhZXRzZ3J1ZW5kZW4gdm9yaGFuZGVuIHVuZCBkYXJmCisvLyBuaWNodCBtZWhyIHZlcndlbmRldCB3ZXJkZW4hISEKK3ZvaWQgQWRkRm9vZChzdHJpbmcgbmFtZU9mRm9vZCwgbWl4ZWQgaWRzLCBpbnQgcHJpY2UsIGludCBoZWFsLAorICAgICAgICAgICAgIG1peGVkIG15RnVuY3Rpb24pCit7CisgIGlmICggIW5hbWVPZkZvb2QgfHwgIWlkcyB8fCAhcHJpY2UpCisgICAgcmV0dXJuOyAvKiBGb29kIG5vdCBoZWFsaW5nIGlzIG9rICEgKi8KKworICBBZGRUb01lbnUoIG5hbWVPZkZvb2QsaWRzLAorICAgICAgICAgICAgIChbIFBfVkFMVUUgOiBwcmljZSwgUF9GT09EIDogaGVhbCwgUF9IUCA6IGhlYWwsIFBfU1AgOiBoZWFsIF0pLAorICAgICAgICAgICAgICgoaGVhbD41KT81OmhlYWwpLCBteUZ1bmN0aW9uLCAwLDAsMCk7Cit9CisKKy8vIERpZXNlIE1ldGhvZGUgaXN0IG51ciBub2NoIGF1cyBLb21wYXRpYmlsaXRhZXRzZ3J1ZW5kZW4gdm9yaGFuZGVuIHVuZCBkYXJmCisvLyBuaWNodCBtZWhyIHZlcndlbmRldCB3ZXJkZW4hISEKK3ZvaWQgQWRkRHJpbmsoc3RyaW5nIG5hbWVPZkRyaW5rLCBtaXhlZCBpZHMsIGludCBwcmljZSwgaW50IGhlYWwsCisgICAgICAgICAgICAgIGludCBzdHJlbmd0aCwgaW50IHNvYWssIG1peGVkIG15RnVuY3Rpb24pCit7CisgIGlmICggIW5hbWVPZkRyaW5rIHx8ICFpZHMgfHwgIXByaWNlICkKKyAgICByZXR1cm47CisKKyAgaGVhbD1oZWFsLzI7CisgIC8qIEtsZWluZSBLb3JyZWt0dXIsIGRhbWl0IG1hbiBpbiBhbHRlbiBQdWJzIHVlYmVyaGF1cHQgdHJpbmtlbiBrYW5uICovCisgIEFkZFRvTWVudShuYW1lT2ZEcmluayxpZHMsCisgICAgICAgICAgICAgKFsgUF9WQUxVRSA6IHByaWNlLCBQX0RSSU5LIDogc29haywgUF9BTENPSE9MIDogc3RyZW5ndGgsCisgICAgICAgICAgICAgICAgUF9IUCA6IGhlYWwsIFBfU1AgOiBoZWFsIF0pLAorICAgICAgICAgICAgICgoaGVhbD41KT81OmhlYWwpLCBteUZ1bmN0aW9uLDAsMCwwKTsKK30KKworaW50IFJlbW92ZUZyb21NZW51KG1peGVkIGlkcykgeworICBpbnQgcmV0OworCisgIGlmIChzdHJpbmdwKGlkcykpCisgICAgaWRzID0gKHtpZHN9KTsKKworICBpZiAocG9pbnRlcnAoaWRzKSkgeworICAgIGZvcmVhY2ggKHN0cmluZyBpZDogaWRzKSB7CisgICAgICAvLyBsb29rIGlmIHRoZSBpZCBoYXMgYSBtYXRjaGluZyBpZGVudAorICAgICAgc3RyaW5nIGlkZW50ID0gaWRfbGlzdFtpZF07CisgICAgICBpZiAoc3RyaW5ncChpZGVudCkpIHsKKyAgICAgICAgLy8gcmVtb3ZlIHRoaXMgaWRlbnQtZW50cnkgZnJvbSB0aGUgaWQtbGlzdCAuLi4KKyAgICAgICAgbV9kZWxldGUoaWRfbGlzdCwgaWQpOworICAgICAgICAvLyAuLi4gYW5kIHJlbW92ZSBhbGwgb3RoZXJzIG5vdyB0b28gKHNvIGl0IHdvbid0IGJ1ZyBsYXRlciwgaWYKKyAgICAgICAgLy8gICAgIHRoZSB3aXphcmQgY2FsbGluZyB0aGlzIG1ldGhvZCBmb3Jnb3QgYW4gaWQpCisgICAgICAgIGZvcmVhY2ggKHN0cmluZyBsaXN0aWQ6IG1faW5kaWNlcyhpZF9saXN0KSkKKyAgICAgICAgICBpZiAoaWRfbGlzdFtsaXN0aWRdID09IGlkZW50KQorICAgICAgICAgICAgbV9kZWxldGUoaWRfbGlzdCwgbGlzdGlkKTsKKworICAgICAgICAvLyBub3cgcmVtb3ZlIHRoZSBpZGVudCBmcm9tIHRoZSBtZW51X2xpc3QKKyAgICAgICAgaWYgKG1lbWJlcihtZW51X2xpc3QsIGlkZW50KSkgeworICAgICAgICAgIHJldCsrOworICAgICAgICAgIG1fZGVsZXRlKG1lbnVfbGlzdCwgaWRlbnQpOworCisgICAgICAgICAgLy8gZGVjcmVhc2UgdGhlIGlkZW50LWNvdW50ZXIsIGlmIHRoaXMgZW50cnkgd2FzIHRoZSBsYXN0IG9uZQorICAgICAgICAgIGludCBvbGRudW07CisgICAgICAgICAgaWYgKHNzY2FuZihpZGVudCwgIm1lbnVlbnRyeSVkIiwgb2xkbnVtKSA9PSAxICYmCisgICAgICAgICAgICAgIG9sZG51bSA9PSAobWF4X2xpc3QtMSkpCisgICAgICAgICAgICBtYXhfbGlzdC0tOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9CisgIC8vIHJldHVybiByZW1vdmVkIGVudHJpZXMKKyAgcmV0dXJuIHJldDsKK30KKworLyogWnVtIEF1c3dlcnRlbiBkZXIgRWludHJhZWdlIGZ1ZXIgUHJlaXMsIFJhdGUsIEhQLi4uCisgKiBhKSBpbnRlZ2VyLVdlcnQgICAgLT4gd2lyZCBkaXJla3QgdWViZXJub21tZW4KKyAqIGIpIG1hcHBpbmcgICAgICAgICAtPiBXaXJkIGFscyBSYWNlTW9kaWZpZXJlIHZlcnN0YW5kZW4uIEVzIHdpcmQgZGVyCisgKiAgICAgICAgICAgICAgICAgICAgICAgRWludHJhZyBnZXdhZWhsdCwgZGVyIGRlciBSYXNzZSBkZXMgU3BpZWxlcnMKKyAqICAgICAgICAgICAgICAgICAgICAgICBlbnRzcHJpY2h0LCBmYWxscyB2b3JoYW5kZW4sIGFuc29uc3RlbiBkZXIgRWludHJhZworICogICAgICAgICAgICAgICAgICAgICAgIGZ1ZXIgMC4KKyAqIGMpIEFycmF5ICAgICAgICAgICAtPiBJbiBlcnN0ZW0gRWxlbWVudCAobXVzcyBPYmpla3Qgb2RlciBkZXNzZW4gRmlsZW5hbWUKKyAqICAgICAgICAgICAgICAgICAgICAgICBzZWluKSB3aXJkIGRpZSBGdW5rdGlvbiBtaXQgZGVtIE5hbWVuIGltIDIuRWxlbWVudAorICogICAgICAgICAgICAgICAgICAgICAgIGF1ZmdlcnVmZW4uCisgKiBkKSBTdHJpbmcgICAgICAgICAgLT4gRGllIGdlbmFubnRlIEZ1bmt0aW9uIHdpcmQgaW4gZGVyIEtuZWlwZSBzZWxic3QKKyAqICAgICAgICAgICAgICAgICAgICAgICBhdWZnZXJ1ZmVuLgorICogZSkgQ2xvc3VyZSAgICAgICAgIC0+IERpZSBDbG9zdXJlIHdpcmQgYXVzZ2V3ZXJ0ZXQuCisgKiBBbGxlIEZ1bmt0aW9uc2F1ZnJ1ZmUgYmVrb21tZW4gZGVuIGVzc2VuZGVuIFNwaWVsZXIgKGJlaSBQcmljZSB1bmQgRGVsYXkKKyAqIGRlbiBiZXN0ZWxsZW5kZW4gU3BpZWxlcikgYWxzIEFyZ3VtZW50IHVlYmVyZ2ViZW4uIERpZSBBdXN3ZXJ0dW5nIGVyZm9sZ3QKKyAqIGluIGRlciBhbmdlZ2ViZW5lbiBSZWloZW5mb2xnZS4gQW0gRW5kZSBtdXNzIGVpbiBJbnRlcmdlcndlcnQgaGVyYXVza29tbWVuCisgKi8KK2ludCBldmFsX2FueXRoaW5nKG1peGVkIHdoYXQsIG9iamVjdCBwbCkKK3sgbWl4ZWQgcmU7CisKKyAgaWYgKGludHAod2hhdCkpCisgICAgcmV0dXJuIHdoYXQ7CisKKyAgaWYgKG1hcHBpbmdwKHdoYXQpICYmIHBsKQorICB7CisgICAgcmUgPSB3aGF0W3BsLT5RdWVyeVByb3AoUF9SQUNFKV18fHdoYXRbMF07CisgIH0KKworICBpZiAocmUpCisgICAgd2hhdD1yZTsKKworICBpZiAoIHBvaW50ZXJwKHdoYXQpICYmIChzaXplb2Yod2hhdCk+PTIpCisgICAgICAmJiAoIG9iamVjdHAod2hhdFswXSkgfHwgc3RyaW5ncCh3aGF0WzBdKSApCisgICAgICAmJiBzdHJpbmdwKHdoYXRbMV0pICkKKyAgICB3aGF0ID0gY2FsbF9vdGhlcih3aGF0WzBdLHdoYXRbMV0scGwpOworCisgIGlmICggc3RyaW5ncCh3aGF0KSAmJiBmdW5jdGlvbl9leGlzdHMod2hhdCxNRSkgKQorICAgIHdoYXQgPSBjYWxsX290aGVyKE1FLHdoYXQscGwpOworCisgIGlmICggY2xvc3VyZXAod2hhdCkgKQorICAgIHdoYXQgPSBmdW5jYWxsKHdoYXQscGwpOworCisgIGlmICggaW50cCh3aGF0KSApCisgICAgcmV0dXJuIHdoYXQ7CisKKyAgcmV0dXJuIDA7Cit9CisKKy8qIERpZXNlIEZ1bmt0aW9uIHVlYmVycHJ1ZWZ0LCBvYiBkYXMgS29udGluZ2VudCBlaW5lcyBNZW51ZWVpbnRyYWdzCisgKiBmdWVyIGVpbmVuIFNwaWVsZXIgZXJzY2hvZXBmdCBpc3QuCisgKi8KK3N0cmluZyBDaGVja0F2YWlsYWJpbGl0eShzdHJpbmcgaWRlbnQsIG9iamVjdCB6YWhsZXIpCit7IHN0cmluZyB1aWQ7CisKKyAgaWYgKCAhc3RyaW5ncChpZGVudCkgfHwgIW1lbWJlcihtZW51X2xpc3QsaWRlbnQpIHx8ICFvYmplY3RwKHphaGxlcikgKQorICAgIHJldHVybiAwOworICBpZiAoICFtYXBwaW5ncChtZW51X2xpc3RbaWRlbnQsUE1fUkVGUkVTSF0pICkKKyAgICByZXR1cm4gUFJfTk9ORTsKKworICBpZiAoICFtZW1iZXIocmVmcmVzaF9saXN0LGlkZW50KSApCisgICAgcmVmcmVzaF9saXN0ICs9IChbIGlkZW50IDogKFsgXSkgXSk7CisKKyAgaWYgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHphaGxlcikgKQorICAgIHVpZD1nZXR1aWQoemFobGVyKTsKKyAgZWxzZQorICAgIHVpZD1vYmplY3RfbmFtZSh6YWhsZXIpOworCisgIGlmICggbWVtYmVyKG1lbnVfbGlzdFtpZGVudCxQTV9SRUZSRVNIXSxQUl9VU0VSKSApCisgIHsKKyAgICBpZiAoICFtZW1iZXIocmVmcmVzaF9saXN0W2lkZW50XSx1aWQpICkKKyAgICB7CisgICAgICByZWZyZXNoX2xpc3RbaWRlbnRdICs9IChbIHVpZCA6IDAgOyByZWZyZXNoX2NvdW50IF0pOworICAgIH0KKworICAgIC8qIEtvbnRpbmdlbnQgZGVzIFphaGxlbmRlbiBwcnVlZmVuICovCisgICAgaWYgKCByZWZyZXNoX2xpc3RbaWRlbnRdW3VpZCxQUlZfQU1PVU5UXSA8CisgICAgICAgICAgZXZhbF9hbnl0aGluZyhtZW51X2xpc3RbaWRlbnQsUE1fUkVGUkVTSF1bUFJfVVNFUixQUlZfQU1PVU5UXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHphaGxlcikgKQorICAgICAgcmV0dXJuIHVpZDsKKyAgfQorCisgIGlmICggbWVtYmVyKG1lbnVfbGlzdFtpZGVudCxQTV9SRUZSRVNIXSxQUl9BTEwpICkKKyAgeworICAgIGlmICggIW1lbWJlcihyZWZyZXNoX2xpc3RbaWRlbnRdLFBSX0RFRkFVTFQpICkKKyAgICB7CisgICAgICByZWZyZXNoX2xpc3RbaWRlbnRdICs9IChbIFBSX0RFRkFVTFQgOiAwIDsgcmVmcmVzaF9jb3VudCBdKTsKKyAgICB9CisKKyAgICAvKiBLb250aW5nZW50IGRlciBBbGxnZW1laW5oZWl0IHBydWVmZW4gKi8KKyAgICBpZiAoIHJlZnJlc2hfbGlzdFtpZGVudF1bUFJfREVGQVVMVCxQUlZfQU1PVU5UXSA8CisgICAgICAgICAgZXZhbF9hbnl0aGluZyhtZW51X2xpc3RbaWRlbnQsUE1fUkVGUkVTSF1bUFJfQUxMLFBSVl9BTU9VTlRdLAorICAgICAgICAgICAgICAgICAgICAgICAgemFobGVyKSApCisgICAgICByZXR1cm4gUFJfREVGQVVMVDsKKyAgfQorCisgIHJldHVybiAwOworfQorCisvKiBEaWVzZSBGdW5rdGlvbiByZWR1emllcnQgZGFzIEtvbnRpbmdlbnQgZGVzIExlYmV3ZXNlbnMgdWlkIGJlaW0KKyAqIE1lbnVlZWludHJhZyBpZGVudCB1bSAxCisgKi8KK3ZvaWQgRGVjcmVhc2VBdmFpbGFiaWxpdHkoc3RyaW5nIGlkZW50LCBzdHJpbmcgdWlkKQoreworICBpZiAoICFzdHJpbmdwKGlkZW50KSB8fCAhc3RyaW5ncCh1aWQpICkKKyAgICByZXR1cm47CisgIHJlZnJlc2hfbGlzdFtpZGVudF1bdWlkLFBSVl9BTU9VTlRdKys7Cit9CisKKy8qIERpZXNlIEZ1bmt0aW9uIHNvcmd0IGRhZnVlciwgZGFzcyBkaWUgS29udGluZ2VudGUgYW4gbGltaXRpZXJ0ZW4KKyAqIFNhY2hlbiBpbiByZWdlbG1hZXNzaWdlbiBBYnN0YWVuZGVuIHdpZWRlcmhlcmdlc3RlbGx0IHdlcmRlbi4KKyAqLworc3RhdGljIHZvaWQgVXBkYXRlQXZhaWxhYmlsaXR5KCkKK3sgaW50ICAgIGkxLGkyOworICBzdHJpbmcgKmluZDEsKmluZDIsY2hrOworCisgIC8qIEtlaW5lIFJlZnJlc2gtRWludHJhZWdlLCBrZWluIFVwZGF0ZSAqLworICBpZiAoICFtYXBwaW5ncChyZWZyZXNoX2xpc3QpCisgICAgICB8fCAoaTE9c2l6ZW9mKGluZDE9bV9pbmRpY2VzKHJlZnJlc2hfbGlzdCkpKTwxICkKKyAgICByZXR1cm47CisKKyAgLyogRXMgbXVzcyBqZWRlciBNZW51ZWVpbnRyYWcsIGRlciBpbiBkZXIgcmVmcmVzaF9saXN0IHN0ZWh0LAorICAgKiBkdXJjaGdlZ2FuZ2VuIHdlcmRlbi4KKyAgICovCisgIGZvciAoIC0taTEgOyBpMT49MCA7IGkxLS0gKQorICB7CisgICAgaWYgKCAhbWFwcGluZ3AocmVmcmVzaF9saXN0W2luZDFbaTFdXSkKKyAgICAgICAgfHwgKGkyPXNpemVvZihpbmQyPW1faW5kaWNlcyhyZWZyZXNoX2xpc3RbaW5kMVtpMV1dKSkpPDEgKQorICAgICAgY29udGludWU7CisKKyAgICAvKiBGdWVyIGplZGVuIE1lbnVlZWludHJhZyBtdXNzIGplZGVyIFNwaWVsZXJlaW50cmFnIGR1cmNoZ2VnYW5nZW4KKyAgICAgKiB3ZXJkZW4sIGRlciBpbiBkZW0gZW50c3ByLiBtYXBwaW5nIHN0ZWh0LgorICAgICAqLworICAgIGZvciAoIC0taTIgOyBpMj49MCA7IGkyLS0gKSAvLyBBbGxlIFNwaWVsZXIKKyAgICB7CisgICAgICBpZiAoIGluZDJbaTJdPT1QUl9ERUZBVUxUICkKKyAgICAgICAgY2hrID0gUFJfQUxMOworICAgICAgZWxzZQorICAgICAgICBjaGsgPSBQUl9VU0VSOworCisgICAgICBpZiAoICggcmVmcmVzaF9saXN0W2luZDFbaTFdXVtpbmQyW2kyXSxQUlZfUkVGUkVTSF0KKyAgICAgICAgICAgICsgbWVudV9saXN0W2luZDFbaTFdLFBNX1JFRlJFU0hdW2NoayxQUlZfUkVGUkVTSF0gKQorICAgICAgICAgIDw9IHJlZnJlc2hfY291bnQgKQorICAgICAgeworICAgICAgICByZWZyZXNoX2xpc3RbaW5kMVtpMV1dW2luZDJbaTJdLFBSVl9BTU9VTlRdPTA7CisgICAgICAgIHJlZnJlc2hfbGlzdFtpbmQxW2kxXV1baW5kMltpMl0sUFJWX1JFRlJFU0hdPXJlZnJlc2hfY291bnQ7CisgICAgICB9CisgICAgfQorICB9Cit9CisKK21peGVkIERCRyhtaXhlZCBvKSB7CisgIGlmKGZpbmRfcGxheWVyKCJydW1hdGEiKSkKKyAgICB0ZWxsX29iamVjdCgKKyAgICAgICAgZmluZF9wbGF5ZXIoInJ1bWF0YSIpLAorICAgICAgICBzcHJpbnRmKCJEQkc6ICVPXG4iLCBvKQorICAgICk7CisgIHJldHVybiAwOworfQorCisvKiBFcndlaXRlcnQgdW0gZGllIE1vZWdsaWNoa2VpdCwgU3BlaXNlLSBvZGVyIEdldHJhZW5rZS1LYXJ0ZSB6dSBzZWhlbi4gKi8KK3N0cmluZyBtZW51ZV90ZXh0KHN0cmluZyBzdHIpCit7IGludCBpLHNkcixzZm87CisgIHN0cmluZyBpZGVudCxyZXM7CisgIHN0cmluZyAqZm89KHt9KSwqZHI9KHt9KTsKKworICBpZiAoICFtYXhfbGlzdCApCisgICAgcmV0dXJuICJIaWVyIHNjaGVpbnQgZXMgZGVyemVpdCBuaWNodHMgenUgZ2ViZW4uXG4iOworCisgIGlmICggIXN0cmluZ3Aoc3RyKSB8fCBzdHI9PSIiICkKKyAgICBzdHI9ImFsbGVzIjsKKworICAvKiBGdWVycyBNZW51ZSBlbnRzY2hlaWRlbiBvYiBEcmluayBvZGVyIEZvb2QgKi8KKyAgZm9yZWFjaChzdHJpbmcgaWQsIHN0cmluZyBtZW51ZXRleHQsIG1hcHBpbmcgbWluZm86IG1lbnVfbGlzdCkKKyAgeworICAgIGlmIChldmFsX2FueXRoaW5nKG1pbmZvW1BfRk9PRF0sdGhpc19wbGF5ZXIoKSkpCisgICAgICBmbys9KHsgaWQgfSk7CisgICAgZWxzZQorICAgICAgZHIrPSh7IGlkIH0pOworICB9CisKKyAgc2RyID0gc2l6ZW9mKGRyKTsKKyAgc2ZvID0gc2l6ZW9mKGZvKTsKKworICBpZiAoIG1lbWJlcigoeyJhbGxlIiwiYWxsZXMifSksc3RyKSE9LTEpCisgIHsKKyAgICBpZiAoICFzZm8gKQorICAgICAgc3RyPSJkcmlua3MiOworICAgIGVsc2UgaWYgKCAhc2RyICkKKyAgICAgIHN0cj0ic3BlaXNlIjsKKyAgICBlbHNlCisgICAgeworICAgICAgLyogR2VtaXNjaHRlIEthcnRlICovCisgICAgICByZXMgPSAiR2V0cmFlbmtlICAgICAgICAgICAgICAgICAgICBQcmVpcyBhbGMgfCAiKworICAgICAgICAgICAgIlNwZWlzZW4gICAgICAgICAgICAgICAgICAgICAgICAgIFByZWlzXG4iKworICAgICAgICAgICAgIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstIisKKyAgICAgICAgICAgICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIjsKKworICAgICAgZm9yICggaT0wIDsgKCBpPHNkciB8fCBpPHNmbyApIDsgaSsrICkKKyAgICAgIHsKKyAgICAgICAgaWYgKCBpPHNkciApCisgICAgICAgICAgcmVzICs9IHNwcmludGYoIiUtMjkuMjlzJTUuNWQgICVjICB8ICIsCisgICAgICAgICAgICAgICAgICAgbWVudV9saXN0W2RyW2ldLFBNX1RFWFRdLAorICAgICAgICAgICAgICAgICAgIGV2YWxfYW55dGhpbmcobWVudV9saXN0W2RyW2ldLFBNX0lORk9dW1BfVkFMVUVdLFBMKSwKKyAgICAgICAgICAgICAgICAgICAoZXZhbF9hbnl0aGluZyhtZW51X2xpc3RbZHJbaV0sUE1fSU5GT11bUF9BTENPSE9MXSxQTCk+MCkgPyAnSicgOiAnTicpOworICAgICAgICBlbHNlCisgICAgICAgICAgcmVzICs9ICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICI7CisKKyAgICAgICAgaWYgKCBpPHNmbyApCisgICAgICAgICAgcmVzICs9IHNwcmludGYoIiUtMzMuMzNzJTUuNWQiLAorICAgICAgICAgICAgICAgICAgIG1lbnVfbGlzdFtmb1tpXSxQTV9URVhUXSwKKyAgICAgICAgICAgICAgICAgICBldmFsX2FueXRoaW5nKG1lbnVfbGlzdFtmb1tpXSxQTV9JTkZPXVtQX1ZBTFVFXSxQTCkpOworCisgICAgICAgIHJlcyArPSAiXG4iOworICAgICAgfQorCisgICAgICByZXR1cm4gcmVzOworICAgIH0KKyAgfQorCisgIC8qIFJlaW5lIEdldHJhZW5rZWthcnRlICovCisgIGlmICggbWVtYmVyKCh7ImdldHJhZW5rZSIsImRyaW5rcyIsImdldHJhZW5rIiwidHJpbmtlbiJ9KSxzdHIpIT0tMSApCisgIHsKKyAgICBpZiAoICFzZHIgKQorICAgICAgcmV0dXJuICJIaWVyIGdpYnQgZXMgbGVpZGVyIG5pY2h0cyB6dSB0cmlua2VuLlxuIjsKKworICAgIHJlcyA9ICJHZXRyYWVua2UgICAgICAgICAgICAgICAgICAgIFByZWlzIGFsYyB8ICIrCisgICAgICAgICAgIkdldHJhZW5rZSAgICAgICAgICAgICAgICAgICAgUHJlaXMgYWxjXG4iKworICAgICAgICAgICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLSIrCisgICAgICAgICAgIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iOworCisgICAgZm9yICggaT0wIDsgaTxzZHIgOyBpKysgKQorICAgIHsKKyAgICAgIGlkZW50ID0gZHJbaV07CisKKyAgICAgIGlmICggIWV2YWxfYW55dGhpbmcobWVudV9saXN0W2lkZW50LFBNX0lORk9dW1BfRk9PRF0sIFBMKSApCisgICAgICAgIHJlcyArPSBzcHJpbnRmKCIlLTI5LjI5cyU1LjVkICAlYyVzIiwKKyAgICAgICAgICAgICAgICAgbWVudV9saXN0W2lkZW50LFBNX1RFWFRdLAorICAgICAgICAgICAgICAgICBldmFsX2FueXRoaW5nKG1lbnVfbGlzdFtpZGVudCxQTV9JTkZPXVtQX1ZBTFVFXSxQTCksCisgICAgICAgICAgICAgICAgIChldmFsX2FueXRoaW5nKG1lbnVfbGlzdFtpZGVudCxQTV9JTkZPXVtQX0FMQ09IT0xdLFBMKT4wKSA/ICdKJyA6ICdOJywKKyAgICAgICAgICAgICAgICAgKChpJTIpPyJcbiI6IiAgfCAiKSk7CisgICAgfQorCisgICAgaWYgKCByZXNbPDEuLjwxXSE9IlxuIiApCisgICAgICByZXMgKz0gIlxuIjsKKworICAgIHJldHVybiByZXM7CisgIH0KKworICAvKiBSZWluZSBTcGVpc2VrYXJ0ZSAqLworICBpZiAoIG1lbWJlcigoeyJzcGVpc2UiLCJzcGVpc2VuIiwiZXNzZW4ifSksc3RyKSE9LTEgKQorICB7CisgICAgaWYgKCAhc2ZvICkKKyAgICAgIHJldHVybiAiSGllciBnaWJ0IGVzIGxlaWRlciBuaWNodHMgenUgZXNzZW4uXG4iOworCisgICAgcmVzID0gIlNwZWlzZW4gICAgICAgICAgICAgICAgICAgICAgICAgIFByZWlzIHwgIisKKyAgICAgICAgICAiU3BlaXNlbiAgICAgICAgICAgICAgICAgICAgICAgICAgUHJlaXNcbiIrCisgICAgICAgICAgIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstIisKKyAgICAgICAgICAiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiI7CisKKyAgICBmb3IgKCBpPTAgOyBpPHNmbyA7IGkrKyApCisgICAgeworICAgICAgaWRlbnQgPSBmb1tpXTsKKyAgICAgIGlmIChldmFsX2FueXRoaW5nKG1lbnVfbGlzdFtpZGVudCxQTV9JTkZPXVtQX0ZPT0RdLFBMKSApCisgICAgICAgIHJlcyArPSBzcHJpbnRmKCIlLTMzLjMzcyU1LjVkJXMiLAorICAgICAgICAgICAgICAgICBtZW51X2xpc3RbaWRlbnQsUE1fVEVYVF0sCisgICAgICAgICAgICAgICAgIGV2YWxfYW55dGhpbmcobWVudV9saXN0W2lkZW50LFBNX0lORk9dW1BfVkFMVUVdLFBMKSwKKyAgICAgICAgICAgICAgICAgKChpJTIpPyJcbiI6IiB8ICIpKTsKKyAgICB9CisKKyAgICBpZiAoIHJlc1s8MS4uPDFdIT0iXG4iICkKKyAgICAgIHJlcyArPSAiXG4iOworCisgICAgcmV0dXJuIHJlczsKKyAgfQorCisgIHJldHVybiAwOworfQorCitpbnQgbWVudWUoc3RyaW5nIHN0cikKK3sgc3RyaW5nIHR4dDsKKworICBfbm90aWZ5X2ZhaWwoIldlbGNoZW4gVGVpbCBkZXMgTWVudWVzIG1vZWNodGVzdCBEdSBzZWhlbj9cbiIpOworICBpZiAoICFzdHJpbmdwKHR4dD1tZW51ZV90ZXh0KHN0cikpIHx8IHNpemVvZih0eHQpPDEgKQorICAgIHJldHVybiAwOworICB3cml0ZSh0eHQpOworICByZXR1cm4gMTsKK30KKworLyogRGllc2UgRnVua3Rpb24ga2Fubi9zb2xsIGJlaSBCZWRhcmYgdWViZXJsYWRlbiB3ZXJkZW4sIHVtIHNpbXVsdGFuZQorICogQWVuZGVydW5nZW4gZGVzIE1hcHBpbmdzIHp1IGVybW9lZ2xpY2hlbiAoenUgQmVpc3BpZWwgd2llIGVzIGluIGd1dGVuCisgKiBUYWdlbiBncm9lc3NlciBQb3J0aW9uZW4gZ2liLCBIb2JiaXRzIHBlciBzZSBtZWhyIGtyaWVnZW4sIC4uLgorICovCittYXBwaW5nIGFkanVzdF9pbmZvKHN0cmluZyBpZGVudCwgbWFwcGluZyBtaW5mbywgb2JqZWN0IHphaGxlciwKKyAgICAgICAgICAgICAgICAgICAgb2JqZWN0IGVtcGZhZW5nZXIpCit7CisgIHJldHVybiAwOworfQorCisvKiBIaWVyIGhhdHMgamVkZSBNZW5nZSBuZXVlIFBsYXR6aGFsdGVyICovCitzdHJpbmcgbWVzcyhzdHJpbmcgc3RyLG9iamVjdCBwbCkKK3sKKyAgc3RyaW5nIGR1bW15MSwgZHVtbXkyOworCisgIGlmICggIXBsICkKKyAgICBwbD1QTDsKKworICBpZiAoICFzdHJpbmdwKHN0cikgfHwgc3RyPT0iIiApCisgICAgcmV0dXJuIHN0cjsKKworICBzdHI9aW1wbG9kZShleHBsb2RlKHN0ciwiJiYiKSxwbC0+bmFtZShXRVIsMikpOworICBzdHI9aW1wbG9kZShleHBsb2RlKHN0ciwiJjEmIikscGwtPm5hbWUoV0VSLDIpKTsKKyAgc3RyPWltcGxvZGUoZXhwbG9kZShzdHIsIiYyJiIpLHBsLT5uYW1lKFdFU1NFTiwyKSk7CisgIHN0cj1pbXBsb2RlKGV4cGxvZGUoc3RyLCImMyYiKSxwbC0+bmFtZShXRU0sMikpOworICBzdHI9aW1wbG9kZShleHBsb2RlKHN0ciwiJjQmIikscGwtPm5hbWUoV0VOLDIpKTsKKyAgc3RyPWltcGxvZGUoZXhwbG9kZShzdHIsIiYxIyIpLGNhcGl0YWxpemUocGwtPm5hbWUoV0VSLDIpKSk7CisgIHN0cj1pbXBsb2RlKGV4cGxvZGUoc3RyLCImMiMiKSxjYXBpdGFsaXplKHBsLT5uYW1lKFdFU1NFTiwyKSkpOworICBzdHI9aW1wbG9kZShleHBsb2RlKHN0ciwiJjMjIiksY2FwaXRhbGl6ZShwbC0+bmFtZShXRU0sMikpKTsKKyAgc3RyPWltcGxvZGUoZXhwbG9kZShzdHIsIiY0IyIpLGNhcGl0YWxpemUocGwtPm5hbWUoV0VOLDIpKSk7CisgIHN0cj1pbXBsb2RlKGV4cGxvZGUoc3RyLCImISIpLHBsLT5RdWVyeVByb25vdW4oV0VSKSk7CisgIHN0cj1pbXBsb2RlKGV4cGxvZGUoc3RyLCImNSYiKSxwbC0+UXVlcnlQcm9ub3VuKFdFUikpOworICBzdHI9aW1wbG9kZShleHBsb2RlKHN0ciwiJjYmIikscGwtPlF1ZXJ5UHJvbm91bihXRVNTRU4pKTsKKyAgc3RyPWltcGxvZGUoZXhwbG9kZShzdHIsIiY3JiIpLHBsLT5RdWVyeVByb25vdW4oV0VNKSk7CisgIHN0cj1pbXBsb2RlKGV4cGxvZGUoc3RyLCImOCYiKSxwbC0+UXVlcnlQcm9ub3VuKFdFTikpOworICBzdHI9aW1wbG9kZShleHBsb2RlKHN0ciwiJjUjIiksY2FwaXRhbGl6ZShwbC0+UXVlcnlQcm9ub3VuKFdFUikpKTsKKyAgc3RyPWltcGxvZGUoZXhwbG9kZShzdHIsIiY2IyIpLGNhcGl0YWxpemUocGwtPlF1ZXJ5UHJvbm91bihXRVNTRU4pKSk7CisgIHN0cj1pbXBsb2RlKGV4cGxvZGUoc3RyLCImNyMiKSxjYXBpdGFsaXplKHBsLT5RdWVyeVByb25vdW4oV0VNKSkpOworICBzdHI9aW1wbG9kZShleHBsb2RlKHN0ciwiJjgjIiksY2FwaXRhbGl6ZShwbC0+UXVlcnlQcm9ub3VuKFdFTikpKTsKKworICByZXR1cm4gYnJlYWtfc3RyaW5nKGNhcGl0YWxpemUoc3RyKSw3OCwiIiwgQlNfTEVBVkVfTVlfTEZTKTsKK30KKworcHJvdGVjdGVkIHZvaWQgX2NvcHlfbWVudWxpc3RfdmFsdWVzKG1hcHBpbmcgZW50cnlpbmZvLCBzdHJpbmcgaWRlbnQpIHsKKyAgLyogS29waWVyZW4gYWxsZXIgV2VydGUgaW5zIG1pbmZvLU1hcHBpbmcsIHVtIFByb2JsZW1lbiBiZWkgTG9lc2NodW5nCisgICAgIGF1cyBkZW0gV2VnIHp1IGdlaGVuLiBTbG93IGFuZCBkaXJ0eSAqLworICBlbnRyeWluZm9bUE1fVEVYVF0gICAgICA9IGRlZXBfY29weShtZW51X2xpc3RbaWRlbnQsIFBNX1RFWFRdKTsKKyAgLy8gUE1fSU5GTyBpcyBhbHJlYWR5IGZsYXQgaW4gZW50cnlpbmZvCisgIGVudHJ5aW5mb1tQTV9SQVRFX1BVQk1BU1RFUl0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgPSBkZWVwX2NvcHkobWVudV9saXN0W2lkZW50LCBQTV9SQVRFXSk7CisgIGVudHJ5aW5mb1tQTV9TRVJWRV9NU0ddID0gZGVlcF9jb3B5KG1lbnVfbGlzdFtpZGVudCwgUE1fU0VSVkVfTVNHXSk7CisgIGVudHJ5aW5mb1tQTV9SRUZSRVNIXSAgID0gZGVlcF9jb3B5KG1lbnVfbGlzdFtpZGVudCwgUE1fUkVGUkVTSF0pOworICAvLyBQTV9ERUxBWSBpcyBhbHJlYWR5IGV2YWx1YXRlZCBpbiBlbnRyeWluZm8KKyAgZW50cnlpbmZvW1BNX0RFTEFZX01TR10gPSBkZWVwX2NvcHkobWVudV9saXN0W2lkZW50LCBQTV9ERUxBWV9NU0ddKTsKKyAgZW50cnlpbmZvW1BNX0lEU10gICAgICAgPSBkZWVwX2NvcHkobWVudV9saXN0W2lkZW50LCBQTV9JRFNdKTsKK30KKworaW50IGRvX2RlbGl2ZXIoc3RyaW5nIGlkZW50LCBvYmplY3QgemFobGVyLCBvYmplY3QgZW1wZmFlbmdlciwKKyAgICAgICAgICAgICAgIG1hcHBpbmcgZW50cnlpbmZvKSB7CisgIHdhaXRpbmcgLT0gKHsgZW1wZmFlbmdlciwwIH0pOworCisgIC8qIEVtcGZhZW5nZXIgbXVzcyBuYXR1ZXJsaWNoIG5vY2ggZGEgc2VpbiAqLworICBpZiAoICFvYmplY3RwKGVtcGZhZW5nZXIpIHx8ICFwcmVzZW50KGVtcGZhZW5nZXIpICkKKyAgICByZXR1cm4gMDsKKworICAvKiBaYWhsZXIgd2lyZCBudXIgd2VnZW4gZGVyIEFid2FlcnRza29tcGF0aWJpbGl0YWV0IGdlYnJhdWNodCAqLworICBpZiAoICFvYmplY3RwKHphaGxlcikgKQorICAgIHphaGxlciA9IGVtcGZhZW5nZXI7CisKKyAgLy8gYWx0ZSBQdWJzLCBkaWUgZG9fZGVsaXZlciBpcmdlbmR3aWUgc2VsYnN0IGF1ZnJ1ZmVuLCBzb2xsdGVuCisgIC8vIG1pdCBkZXIgWmVpdCBrb3JyaWdpZXJ0IHdlcmRlbgorICBpZighbWFwcGluZ3AoZW50cnlpbmZvKSkKKyAgICByYWlzZV9lcnJvcigiUHViIHJ1ZnQgZG9fZGVsaXZlcigpIG9obmUgc2lubnZvbGxlIEFyZ3VtZW50ZSBhdWYuXG4iKTsKKyAgaWYoIW1lbWJlcihlbnRyeWluZm8sIFBNX1JBVEVfUFVCTUFTVEVSKSkgeworICAgIGlmKCFtZW1iZXIobWVudV9saXN0LCBpZGVudCkpCisgICAgICByYWlzZV9lcnJvcigiUHViIHJ1ZnQgZG9fZGVsaXZlcigpIG1pdCBnZWxvZXNjaHRlbSBHZXRyYWVuayB1bmQgIgorICAgICAgICAgICAgICAgICAgInRlaWx3ZWlzZW4gQXJndW1lbnRlbiBhdWYhXG4iKTsKKworICAgIF9jb3B5X21lbnVsaXN0X3ZhbHVlcyhlbnRyeWluZm8sIGlkZW50KTsKKyAgICBjYWxsX291dCgjJ3JhaXNlX2Vycm9yLCAxLAorICAgICAgICAgICAgICJQdWIgcnVmdCBkb19kZWxpdmVyKCkgbnVyIG1pdCB0ZWlsd2Vpc2VuIEFyZ3VtZW50ZW4gYXVmLlxuIik7CisgIH0KKworICBlbnRyeWluZm9bUE1fUkFURV9QVUJNQVNURVJdID0gZXZhbF9hbnl0aGluZyhlbnRyeWluZm9bUE1fUkFURV9QVUJNQVNURVJdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXBmYWVuZ2VyKTsKKyAgZW50cnlpbmZvW1BfSFBdICAgICAgICAgICAgICA9IGV2YWxfYW55dGhpbmcoZW50cnlpbmZvW1BfSFBdLCBlbXBmYWVuZ2VyKTsKKyAgZW50cnlpbmZvW1BfU1BdICAgICAgICAgICAgICA9IGV2YWxfYW55dGhpbmcoZW50cnlpbmZvW1BfU1BdLCBlbXBmYWVuZ2VyKTsKKworICAvKiBVZWJlcnBydWVmZW4sIG9iIEhlaWxtb2VnbGljaGtlaXQgbGVnYWwgKi8KKyAgaWYgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGVtcGZhZW5nZXIpCisgICAgICAmJiAoKFBVQk1BU1RFUi0+UmVnaXN0ZXJJdGVtKGVudHJ5aW5mb1tQTV9URVhUXSwgZW50cnlpbmZvKSk8MSkgKSB7CisgICAgIHRlbGxfb2JqZWN0KGVtcGZhZW5nZXIsCisgICAgICAgIk1pdCBkaWVzZW0gR2V0cmFlbmsvR2VyaWNodCBzY2hlaW50IGV0d2FzIG5pY2h0IGluIE9yZG51bmcgIisKKyAgICAgICAienUgc2Vpbi5cblZlcnN0YWVuZGlnZSBiaXR0ZSBkZW4gTWFnaWVyLCBkZXIgZnVlciBkaWVzZW4gIisKKyAgICAgICAiUmF1bSB2ZXJhbnR3b3J0bGljaCBpc3QuXG4iKTsKKyAgICAgcmV0dXJuIC00OworICB9CisKKyAgaWYgKCBRdWVyeVByb3AoUF9OUENfRkFTVEhFQUwpICYmICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGVtcGZhZW5nZXIpICkgeworICAgIGVudHJ5aW5mb1tIX0RJU1RSSUJVVElPTl0gPSBIRF9JTlNUQU5UOworICB9CisgIGVsc2UgeworICAgIGVudHJ5aW5mb1tIX0RJU1RSSUJVVElPTl0gPSBlbnRyeWluZm9bUE1fUkFURV9QVUJNQVNURVJdOworICB9CisgIGVtcGZhZW5nZXItPmNvbnN1bWUoZW50cnlpbmZvKTsKKworICAvKiBNZWxkdW5nIGF1c2dlYmVuICovCisgIC8qIEhpbndlaXM6IERhIGRpZSBhdXNmdWVocmVuZGVuIEZ1bmt0aW9uZW4gYXVjaCBpZGVudCB1bmQgbWluZm8KKyAgICogdWViZXJnZWJlbiBiZWtvbW1lbiwga2FubiBtYW4gaGllciBhdWNoIHVlYmVyIGFkanVzdF9pbmZvIG9kZXIKKyAgICogYW4gYW5kZXJlciBTdGVsbGUgenVzYWV0emxpY2hlIEluZm9ybWF0aW9uZW4gdWViZXJnZWJlbi4uLgorICAgKi8KKyAgaWYgKGNsb3N1cmVwKGVudHJ5aW5mb1tQTV9TRVJWRV9NU0ddKSApCisgICAgZnVuY2FsbChlbnRyeWluZm9bUE1fU0VSVkVfTVNHXSwgemFobGVyLCBlbXBmYWVuZ2VyLCBpZGVudCwgZW50cnlpbmZvKTsKKyAgZWxzZSBpZiAoc3RyaW5ncChlbnRyeWluZm9bUE1fU0VSVkVfTVNHXSkgJiYKKyAgICAgICAgICAgZnVuY3Rpb25fZXhpc3RzKGVudHJ5aW5mb1tQTV9TRVJWRV9NU0ddLE1FKSkKKyAgICBjYWxsX290aGVyKE1FLCBlbnRyeWluZm9bUE1fU0VSVkVfTVNHXSwgemFobGVyLCBlbXBmYWVuZ2VyLCBpZGVudCwKKyAgICAgICAgICAgICAgICAgICBlbnRyeWluZm8pOworICBlbHNlIGlmIChwb2ludGVycChlbnRyeWluZm9bUE1fU0VSVkVfTVNHXSkgJiYKKyAgICAgICAgICAgc2l6ZW9mKGVudHJ5aW5mb1tQTV9TRVJWRV9NU0ddKT49MikgIHsKKyAgICBpZiAoc3RyaW5ncChlbnRyeWluZm9bUE1fU0VSVkVfTVNHXVswXSkgJiYKKyAgICAgICAgc2l6ZW9mKGVudHJ5aW5mb1tQTV9TRVJWRV9NU0ddWzBdKSkKKyAgICAgIHRlbGxfb2JqZWN0KGVtcGZhZW5nZXIsCisgICAgICAgIG1lc3MoZW50cnlpbmZvW1BNX1NFUlZFX01TR11bMF0rIlxuIiwgZW1wZmFlbmdlcikpOworICAgIGlmIChzdHJpbmdwKGVudHJ5aW5mb1tQTV9TRVJWRV9NU0ddWzFdKSAmJgorICAgICAgICBzaXplb2YoZW50cnlpbmZvW1BNX1NFUlZFX01TR11bMV0pKQorICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVtcGZhZW5nZXIpfHxNRSwKKyAgICAgICAgbWVzcyhlbnRyeWluZm9bUE1fU0VSVkVfTVNHXVsxXSsiXG4iLGVtcGZhZW5nZXIpLAorICAgICAgICAoe2VtcGZhZW5nZXJ9KSApOworICB9CisKKyAgcmV0dXJuIDE7Cit9CisKKy8qIFRlc3RldCwgb2IgZ2VudWcgR2VsZCB6dXIgVmVyZnVlZ3VuZyBzdGVodC4KKyAqIEZhbGxzIGRpZSBCb25pdGFldCBhbmRlcmVuIEJlc2NocmFlbmt1bmdlbiB1bnRlcmxpZWd0LCBhbHMKKyAqIGRhc3MgZGVyIFphaGxlciBnZW51ZyBHZWxkIGRhYmVpIGhhdCwgbXVzcyBkaWVzZSBNZXRob2RlCisgKiB1ZWJlcnNjaHJpZWJlbiB3ZXJkZW4uCisgKiBSdWVja2dhYmV3ZXJ0ZToKKyAqIC0yIDogT3V0IG9mIE1vbmV5CisgKiAgMCA6IEFsbGVzIE9LLgorICogUnVlY2tnYWJld2VydGUgIT0gMCBmdWVocmVuIHp1IGVpbmVtIEFiYnJ1Y2ggZGVyIEJlc3RlbGx1bmcKKyAqLworaW50IENoZWNrU29sdmVuY3koc3RyaW5nIGlkZW50LCBvYmplY3QgemFobGVyLCBvYmplY3QgZW1wZmFlbmdlciwKKyAgICAgICAgICAgICAgICAgICBtYXBwaW5nIGVudHJ5aW5mbykKK3sKKyAgaWYgKCAoemFobGVyLT5RdWVyeU1vbmV5KCkpPGVudHJ5aW5mb1tQX1ZBTFVFXSApCisgIHsKKyAgICBzdHJpbmcgcmVzOworICAgIGlmICggIXN0cmluZ3AocmVzPVF1ZXJ5UHJvcChQX1BVQl9OT19NT05FWSkpICkKKyAgICAgIHJlcyA9ICJEYXMga29zdGV0ICVkIEdvbGRzdHVlY2tlLCB1bmQgRHUgaGFzdCBuaWNodCBzbyB2aWVsIVxuIjsKKyAgICB0ZWxsX29iamVjdCh6YWhsZXIsc3ByaW50ZihyZXMsIGVudHJ5aW5mb1tQX1ZBTFVFXSkpOworICAgIHJldHVybiAtMjsKKyAgfQorICByZXR1cm4gMDsKK30KKworLyogRnVlaHJ0IGRpZSBCZXphaGx1bmcgZHVyY2guCisgKiBGYWxscyBkaWUgQmV6YWhsdW5nIGFuZGVycyBlcmZvbGd0LCBhbHMgZHVyY2ggQWJ6dWcgZGVzIEdlbGRlcyB2b20gWmFobGVyLAorICogbXVzcyBkaWVzZSBNZXRob2RlIHVlYmVyc2NocmllYmVuIHdlcmRlbgorICogUnVlY2tnYWJld2VydGU6CisgKiBBbnphaGwgZGVyIE11ZW56ZW4sIGRpZSBpbSBQdWIgbGFuZGVuIHVuZCBiZWkgUmVzZXQgaW4gZGllIFplbnRyYWxiYW5rCisgKiBlaW5nZXphaGx0IHdlcmRlbgorICovCitpbnQgRG9QYXkoc3RyaW5nIGlkZW50LCBvYmplY3QgemFobGVyLCBvYmplY3QgZW1wZmFlbmdlciwgbWFwcGluZyBlbnRyeWluZm8pCit7CisgIHphaGxlci0+QWRkTW9uZXkoLWVudHJ5aW5mb1tQX1ZBTFVFXSk7CisgIHJldHVybiBlbnRyeWluZm9bUF9WQUxVRV07Cit9CisKKy8qIFJ1ZWNrZ2FiZXdlcnRlOgorICogLTYgOiBOaWNodCB2b3JyYWV0aWcKKyAqIC01IDogV2lydCBuaWNodCBhbndlc2VuZAorICogLTQgOiBJbGxlZ2FsZXMgR2V0cmFlbmsvR2VyaWNodC4gQXVzZ2FiZSB2ZXJ3ZWlnZXJ0LgorICogICAgICBOdXIgYmVpIHNvZm9ydGlnZXIgTGllZmVydW5nLi4uCisgKiAtMyA6IEVtcGZhZW5nZXIgYmVyZWl0cyB2b2xsCisgKiAtMiA6IE91dCBvZiBNb25leQorICogLTEgOiBzcGVuZGllcmVuIGlnbm9yaWVydAorICogIDAgOiBFbXBmYWVuZ2VyIGF1c2dlZmxvZ2VuIChzb2xsdGUgZWlnZW50bGljaCBuaWNodCBwYXNzaWVyZW4pCisgKiAgMSA6IEFsbGVzIE9LLgorICovCitpbnQgY29uc3VtZV9zb21ldGhpbmcoc3RyaW5nIGlkZW50LCBvYmplY3QgemFobGVyLCBvYmplY3QgZW1wZmFlbmdlcikgeworICBpZiAoICFvYmplY3RwKHphaGxlcikgKQorICAgIHphaGxlcj1QTDsKKworICBpZiAoICFvYmplY3RwKGVtcGZhZW5nZXIpICkKKyAgICBlbXBmYWVuZ2VyPVBMOworCisgIC8qIERpZSBBYmZyYWdlIGF1ZiBhbndlc2VuZGVuIFdpcnQgZXJmb2xndCBOVVIgYW4gZGllc2VyIFN0ZWxsZSwgZGFtaXQgKi8KKyAgLyoga2VpbiBTcGllbGVyIGRhcnVudGVyIGxlaWRlbiBtdXNzLCB3ZW5uIGplbWFuZCBhbmRlcmVzIHp3aXNjaGVuICAgICAqLworICAvKiBCZXN0ZWxsdW5nIHVuZCBMaWVmZXJ1bmcgZGVuIFdpcnQgbWV1Y2hlbHQuICAgICAgICAgICAgICAgICAgICAgICAgICovCisgIGlmICggc3RyaW5ncChRdWVyeVByb3AoUF9LRUVQRVIpKSAmJiAhcHJlc2VudChRdWVyeVByb3AoUF9LRUVQRVIpLCBNRSkpCisgIHsKKyAgICBzdHJpbmcgcmVzID0gUXVlcnlQcm9wKFBfUFVCX05PX0tFRVBFUik7CisgICAgaWYgKCAhc3RyaW5ncChyZXMpICkgeworICAgICAgcmVzID0gIkVzIGlzdCBuaWVtYW5kIGFud2VzZW5kLCBkZXIgRGljaCBiZWRpZW5lbiBrb2VubnRlLlxuIjsKKyAgICB9CisgICAgdGVsbF9vYmplY3QoemFobGVyLHJlcyk7CisgICAgcmV0dXJuIC01OworICB9CisKKyAgLyogU3BlbmRpZXJ0IHVuZCBpZ25vcmllcnQ/ICovCisgIGlmICggemFobGVyIT1lbXBmYWVuZ2VyICkKKyAgeworICAgIG1peGVkIHJlcyA9ICh7InNwZW5kaWVyZSJ9KTsKKyAgICBpZiAoIGV2YWxfYW55dGhpbmcobWVudV9saXN0W2lkZW50LFBNX0lORk9dW1BfRFJJTktdLGVtcGZhZW5nZXIpICkKKyAgICAgIHJlcyArPSAoeyJzcGVuZGllcmUuZ2V0cmFlbmtlIn0pOworICAgIGlmICggZXZhbF9hbnl0aGluZyhtZW51X2xpc3RbaWRlbnQsUE1fSU5GT11bUF9GT09EXSxlbXBmYWVuZ2VyKSApCisgICAgICByZXMgKz0gKHsic3BlbmRpZXJlLmVzc2VuIn0pOworICAgIGlmICggZXZhbF9hbnl0aGluZyhtZW51X2xpc3RbaWRlbnQsUE1fSU5GT11bUF9BTENPSE9MXSxlbXBmYWVuZ2VyKSApCisgICAgICByZXMgKz0gKHsic3BlbmRpZXJlLmFsa29ob2wifSk7CisgICAgaWYgKCBlbXBmYWVuZ2VyLT5UZXN0SWdub3JlU2ltcGxlKHJlcykgKQorICAgIHsKKyAgICAgIHRlbGxfb2JqZWN0KHphaGxlciwKKyAgICAgICAgZW1wZmFlbmdlci0+TmFtZShXRVIpKyIgd2lsbCBkYXMgbmljaHQuXG4iKTsKKyAgICAgIHJldHVybiAtMTsKKyAgICB9CisgIH0KKworICAvKiBIaWVyIGthbm4gZGFzIEluZm8tTWFwcGluZyBlcnN0IG1hbCBhbHMgZ2FuemVzIGFuZ2VwYXNzdCB3ZXJkZW4uICovCisgIG1hcHBpbmcgeGluZm87CisgIG1hcHBpbmcgZW50cnlpbmZvID0gZGVlcF9jb3B5KG1lbnVfbGlzdFtpZGVudCwgUE1fSU5GT10pOworICBpZiAoICh4aW5mbz1hZGp1c3RfaW5mbyhpZGVudCxlbnRyeWluZm8semFobGVyLGVtcGZhZW5nZXIpKSAmJgorICAgICAgIG1hcHBpbmdwKHhpbmZvKSApCisgICAgZW50cnlpbmZvICs9IHhpbmZvOworCisgIC8qIEdlbnVnIEdlbGQgdm9yaGFuZGVuPyAqLworICBlbnRyeWluZm9bUF9WQUxVRV0gPSBldmFsX2FueXRoaW5nKGVudHJ5aW5mb1tQX1ZBTFVFXSwgemFobGVyKTsKKyAgeworICAgIGludCByZXMgPSBDaGVja1NvbHZlbmN5KGlkZW50LCB6YWhsZXIsIGVtcGZhZW5nZXIsIGVudHJ5aW5mbyk7CisgICAgaWYgKHJlcyAhPSAwKSByZXR1cm4gcmVzOworICB9CisKKyAgc3RyaW5nIGF2YjsKKyAgaWYgKCAhc3RyaW5ncChhdmI9Q2hlY2tBdmFpbGFiaWxpdHkoaWRlbnQsIHphaGxlcikpICkKKyAgeworICAgIHN0cmluZyByZXMgPSBRdWVyeVByb3AoUF9QVUJfVU5BVkFJTEFCTEUpOworICAgIGlmICggIXN0cmluZ3AocmVzKSApCisgICAgICByZXMgPSAiRGF2b24gaXN0IGxlaWRlciBuaWNodHMgbWVociBkYS5cbiI7CisgICAgdGVsbF9vYmplY3QoemFobGVyLHJlcyk7CisgICAgcmV0dXJuIC02OworICB9CisKKyAgLyogVGV4dGF1c2dhYmUgYmVpbSBzcGVuZGllcmVuICovCisgIGlmICggZW1wZmFlbmdlciE9emFobGVyKQorICB7CisgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVtcGZhZW5nZXIpfHxNRSwKKyAgICAgIHphaGxlci0+TmFtZShXRVIpKyIgc3BlbmRpZXJ0ICIrZW1wZmFlbmdlci0+bmFtZShXRU0pKyIgZXR3YXMuXG4iLAorICAgICAgKHt6YWhsZXIsIGVtcGZhZW5nZXJ9KSApOworICAgIHRlbGxfb2JqZWN0KGVtcGZhZW5nZXIsCisgICAgICB6YWhsZXItPk5hbWUoV0VSKSsiIHNwZW5kaWVydCBEaXIgZXR3YXMuXG4iKTsKKyAgICB0ZWxsX29iamVjdCh6YWhsZXIsCisgICAgICAiRHUgc3BlbmRpZXJzdCAiK2VtcGZhZW5nZXItPm5hbWUoV0VNKSsiIGV0d2FzLlxuIik7CisgIH0KKworICAvKiBUZXN0ZW4sIG9iIG1hbnMgbm9jaCBlc3NlbiAvIHRyaW5rZW4ga2FubiAqLworICAvKiBEaWUgaW50LVdlcnRlIHdlcmRlbiBpbiBtaW5mbyB1ZWJlcm5vbW1lbiBmdWVyIGRpZSBBdXN3ZXJ0dW5nICovCisgIC8qIGltIFB1Ym1hc3Rlci4gKi8KKyAgZW50cnlpbmZvW1BfRk9PRF0gICAgPSBldmFsX2FueXRoaW5nKGVudHJ5aW5mb1tQX0ZPT0RdLCAgIGVtcGZhZW5nZXIpOworICBlbnRyeWluZm9bUF9BTENPSE9MXSA9IGV2YWxfYW55dGhpbmcoZW50cnlpbmZvW1BfQUxDT0hPTF0sZW1wZmFlbmdlcik7CisgIGVudHJ5aW5mb1tQX0RSSU5LXSAgID0gZXZhbF9hbnl0aGluZyhlbnRyeWluZm9bUF9EUklOS10sICBlbXBmYWVuZ2VyKTsKKworICBpbnQgcmVzdWx0ID0gZW1wZmFlbmdlci0+Y29uc3VtZShlbnRyeWluZm8sIDEpOworICBpZiAocmVzdWx0IDwgMCkgeworICAgIGlmIChyZXN1bHQgJiBIQ19NQVhfRk9PRF9SRUFDSEVEKQorICAgICAgdGVsbF9vYmplY3QoZW1wZmFlbmdlciwKKyAgICAgICAgICAgICAgICAgICJEdSBiaXN0IHp1IHNhdHQsIGRhcyBzY2hhZmZzdCBEdSBuaWNodCBtZWhyLlxuIik7CisgICAgZWxzZSBpZiAocmVzdWx0ICYgSENfTUFYX0RSSU5LX1JFQUNIRUQpCisgICAgICB0ZWxsX29iamVjdChlbXBmYWVuZ2VyLAorICAgICAgICAgICAgICAgICAgIlNvIHZpZWwga2FubnN0IER1IGltIE1vbWVudCBuaWNodCB0cmlua2VuLlxuIik7CisgICAgZWxzZSBpZiAocmVzdWx0ICYgSENfTUFYX0FMQ09IT0xfUkVBQ0hFRCkKKyAgICAgIHRlbGxfb2JqZWN0KGVtcGZhZW5nZXIsCisgICAgICAgICAgICAgICAgICAiU292aWVsIEFsa29ob2wgdmVydHJhZWdzdCBEdSBuaWNodCBtZWhyLlxuIik7CisgICAgcmV0dXJuIC0zOworICB9CisKKyAgLyogR2V6YWhsdCB3aXJkIGF1Y2ggc29mb3J0ICovCisgIHN1bSArPSBEb1BheShpZGVudCwgemFobGVyLCBlbXBmYWVuZ2VyLCBlbnRyeWluZm8pOworCisgIC8qIEZQcyBnaWJ0cyBhdWNoIHNvZm9ydCAqLworICBpZiAoemFobGVyID09IGVtcGZhZW5nZXIpCisgICAgR2l2ZUVQKEVQX1BVQixtZW51X2xpc3RbaWRlbnQsUE1fSURTXVswXSk7CisKKyAgLyogRmFsbHMgZGllIEFuemFobCBkZXMgQmVzdGVsbHRlbiBiZXNjaHJhZW5rdCBpc3QsIG11c3MgZGllc2UgbmF0dWVybGljaAorICAgKiBhbmdlcGFzc3Qgd2VyZGVuLgorICAgKi8KKyAgaWYgKCBhdmIhPVBSX05PTkUgKQorICAgIERlY3JlYXNlQXZhaWxhYmlsaXR5KGlkZW50LGF2Yik7CisKKyAgLyogR2lidCBlcyBlaW5lIFplaXR2ZXJ6b2VnZXJ1bmcgendpc2NoZW4gQmVzdGVsbGVuIHVuZCBTZXJ2aWVyZW4/ICovCisgIGVudHJ5aW5mb1tQTV9ERUxBWV9QVUJNQVNURVJdID0gZXZhbF9hbnl0aGluZyhtZW51X2xpc3RbaWRlbnQsIFBNX0RFTEFZXSwgemFobGVyKTsKKworICAvLyBhbGxlIGZ1ZXIgZWluZW4gRHJpbmsgbm90d2VuZGlnZW4gV2VydGUga29waWVyZW4KKyAgX2NvcHlfbWVudWxpc3RfdmFsdWVzKGVudHJ5aW5mbywgaWRlbnQpOworCisgIGlmIChlbnRyeWluZm9bUE1fREVMQVlfUFVCTUFTVEVSXTw9MCkKKyAgICByZXR1cm4gZG9fZGVsaXZlcihpZGVudCx6YWhsZXIsZW1wZmFlbmdlcixlbnRyeWluZm8pOworCisgIC8qIEJlc3RlbGwtTWVsZHVuZyBhdXNnZWJlbiAqLworICBpZiAoY2xvc3VyZXAoZW50cnlpbmZvW1BNX0RFTEFZX01TR10pKQorICAgIGZ1bmNhbGwoZW50cnlpbmZvW1BNX0RFTEFZX01TR10sIHphaGxlciwgZW1wZmFlbmdlcixpZGVudCwgZW50cnlpbmZvKTsKKyAgZWxzZSBpZiAoc3RyaW5ncChlbnRyeWluZm9bUE1fREVMQVlfTVNHXSkgJiYKKyAgICAgICAgICAgZnVuY3Rpb25fZXhpc3RzKGVudHJ5aW5mb1tQTV9ERUxBWV9NU0ddLE1FKSkKKyAgICBjYWxsX290aGVyKE1FLCBlbnRyeWluZm9bUE1fREVMQVlfTVNHXSwgemFobGVyLCBlbXBmYWVuZ2VyLCBpZGVudCwKKyAgICAgICAgICAgICAgIGVudHJ5aW5mbyk7CisgIGVsc2UgaWYgKHBvaW50ZXJwKGVudHJ5aW5mb1tQTV9ERUxBWV9NU0ddKSAmJgorICAgICAgICAgICBzaXplb2YoZW50cnlpbmZvW1BNX0RFTEFZX01TR10pPj0yKSB7CisgICAgaWYgKHN0cmluZ3AoZW50cnlpbmZvW1BNX0RFTEFZX01TR11bMF0pICYmCisgICAgICAgc2l6ZW9mKGVudHJ5aW5mb1tQTV9ERUxBWV9NU0ddWzBdKSkKKyAgICAgIHRlbGxfb2JqZWN0KGVtcGZhZW5nZXIsCisgICAgICAgIG1lc3MoZW50cnlpbmZvW1BNX0RFTEFZX01TR11bMF0rIlxuIixlbXBmYWVuZ2VyKSk7CisgICAgaWYgKHN0cmluZ3AoZW50cnlpbmZvW1BNX0RFTEFZX01TR11bMV0pICYmCisgICAgICAgIHNpemVvZihlbnRyeWluZm9bUE1fREVMQVlfTVNHXVsxXSkpCisgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW1wZmFlbmdlcil8fE1FLAorICAgICAgICBtZXNzKGVudHJ5aW5mb1tQTV9ERUxBWV9NU0ddWzFdKyJcbiIsZW1wZmFlbmdlciksCisgICAgICAgICh7ZW1wZmFlbmdlcn0pICk7CisgIH0KKworICB3YWl0aW5nICs9ICh7IGVtcGZhZW5nZXIgfSk7CisgIGNhbGxfb3V0KCJkb19kZWxpdmVyIiwgZW50cnlpbmZvW1BNX0RFTEFZX1BVQk1BU1RFUl0sCisgICAgICAgICAgIGlkZW50LCB6YWhsZXIsIGVtcGZhZW5nZXIsIGVudHJ5aW5mbyk7CisKKyAgcmV0dXJuIDE7Cit9CisKKy8qIFJ1ZWNrZ2FiZXdlcmU6IDA6IE5pY2h0IGltIE1lbnVlIGdlZnVuZGUsIDEgc29uc3QgKi8KK2ludCBzZWFyY2hfd2hhdChzdHJpbmcgc3RyLG9iamVjdCB6YWhsZXIsb2JqZWN0IGVtcGZhZW5nZXIpCit7IHN0cmluZyBpZGVudDsKKworICBpZiAoIG1lbWJlcih3YWl0aW5nLGVtcGZhZW5nZXIpIT0tMSApCisgIHsKKyAgICBpZiAoIFBMPT1lbXBmYWVuZ2VyICkKKyAgICAgIHdyaXRlKCJEdSB3YXJ0ZXN0IGRvY2ggbm9jaCBhdWYgZXR3YXMhXG4iKTsKKyAgICBlbHNlCisgICAgICB3cml0ZShlbXBmYWVuZ2VyLT5OYW1lKFdFUiwyKSsiIHdhcnRldCBub2NoIGF1ZiBldHdhcy5cbiIpOworICAgIHJldHVybiAxOworICB9CisKKyAgc3RyID0gbG93ZXJfY2FzZShzdHIpOworICBpZiAoIGlkZW50PWlkX2xpc3Rbc3RyXSApCisgIHsKKyAgICBjb25zdW1lX3NvbWV0aGluZyhpZGVudCx6YWhsZXIsZW1wZmFlbmdlcik7CisgICAgcmV0dXJuIDE7CisgIH0KKworICByZXR1cm4gMDsKK30KKworLy8gTmV1ZSBWZXJzaW9uIHZvbiBNZXNpOgoraW50IHNwZW5kaWVyZShzdHJpbmcgc3RyKQoreworICAgX25vdGlmeV9mYWlsKCJzcGVuZGllcmUgPHNwaWVsZXI+IDxkcmluaz5cbiIpOworCisgICBpZiAoICFzdHJpbmdwKHN0cikgfHwgc3RyPT0iIiApCisgICAgIHJldHVybiAwOworCisgICBzdHJpbmcgd2hvLHdoYXQ7CisgICBpbnQgd2hvaWR4OworCisgICBpZiAoc3NjYW5mKHN0ciwiJXMgJWQgJXMiLHdobyx3aG9pZHgsd2hhdCkhPTMKKyAgICAmJiBzc2NhbmYoc3RyLCIlcyAlcyIsd2hvLHdoYXQpIT0yKQorICAgICAgcmV0dXJuIDA7CisgIG9iamVjdCB0YXJnZXQ9cHJlc2VudCh3aG8sIHdob2lkeCk7CisgIGlmKCF0YXJnZXQgJiYgdGhpc19wbGF5ZXIoKSkgdGFyZ2V0PXByZXNlbnQod2hvLCB3aG9pZHgsIHRoaXNfcGxheWVyKCkpOworICAgaWYgKCAhdGFyZ2V0IHx8ICFsaXZpbmcodGFyZ2V0KSApCisgICB7CisgICAgIHdyaXRlKCJEYXMgTGViZXdlc2VuIGlzdCBuaWNodCBoaWVyLi4uXG4iKTsKKyAgICAgcmV0dXJuIDE7CisgICB9CisKKyAgIG5vdGlmeV9mYWlsKChzdHJpbmcpUXVlcnlQcm9wKFBfUFVCX05PVF9PTl9NRU5VKXx8IlNvIGV0d2FzIGdpYnQgZXMgaGllciBuaWNodCFcbiIpOworCisgICByZXR1cm4gc2VhcmNoX3doYXQod2hhdCxQTCx0YXJnZXQpOworfQorCitpbnQgYmVzdGVsbGUoc3RyaW5nIHN0cikKK3sKKyAgbm90aWZ5X2ZhaWwoKHN0cmluZylRdWVyeVByb3AoUF9QVUJfTk9UX09OX01FTlUpKTsKKworICBpZiAoICFzdHJpbmdwKHN0cikgKQorICAgIHJldHVybiAwOworCisgIHJldHVybiBzZWFyY2hfd2hhdChzdHIsUEwsUEwpOworfQorCitpbnQgcHViaW5pdCgpCit7IHN0cmluZyAgKmxpc3RlLGlkZW50LGZuOworICBpbnQgICAgIHNpLGVyZyxtYXg7CisgIG1hcHBpbmcgbWluZm8seGluZm87CisKKyAgaWYgKCAhUEwgfHwgIUlTX1dJWkFSRChQTCkgKQorICAgIHJldHVybiAwOworCisgIHNpPXNpemVvZihsaXN0ZT1zb3J0X2FycmF5KG1faW5kaWNlcyhtZW51X2xpc3QpLCMnPCkpOworICBpZiAoIHNpPDEgKQorICAgIHJldHVybiBub3RpZnlfZmFpbCgiS2VpbmUgR2VyaWNodGUvR2V0cmFlbmtlIHZvcmhhbmRlbi5cbiIpLDA7CisKKyAgZm49b2xkX2V4cGxvZGUob2JqZWN0X25hbWUoTUUpLCIjIilbMF07CisgIHByaW50ZigiXG4lJ18nfDMwcyAlM3MgJTNzICUzcyAlNXMgJTJzICUycyAlM3MgJTNzICU0cyAlM3NcbiIsCisgICAgIklURU0iLCJBTEMiLCJEUkkiLCJGT08iLCJWQUxVRSIsIlJUIiwiREwiLCJfSFAiLCJfU1AiLCJURVNUIiwiTUFYIik7CisgIGZvciAoIC0tc2kgOyBzaT49MCA7IHNpLS0gKQorICB7CisgICAgaWRlbnQ9bGlzdGVbc2ldOworICAgIG1pbmZvPWRlZXBfY29weShtZW51X2xpc3RbaWRlbnQsUE1fSU5GT10pOworCisgICAgaWYgKCAoeGluZm89YWRqdXN0X2luZm8oaWRlbnQsbWluZm8sUEwsUEwpKSAmJiBtYXBwaW5ncCh4aW5mbykgKQorICAgICAgbWluZm8rPXhpbmZvOworCisgICAgbWluZm9bUF9WQUxVRV0gICA9IGV2YWxfYW55dGhpbmcobWluZm9bUF9WQUxVRV0sICAgICAgICAgICAgUEwpOworICAgIG1pbmZvW1BfRk9PRF0gICAgPSBldmFsX2FueXRoaW5nKG1pbmZvW1BfRk9PRF0sICAgICAgICAgICAgIFBMKTsKKyAgICBtaW5mb1tQX0FMQ09IT0xdID0gZXZhbF9hbnl0aGluZyhtaW5mb1tQX0FMQ09IT0xdLCAgICAgICAgICBQTCk7CisgICAgbWluZm9bUF9EUklOS10gICA9IGV2YWxfYW55dGhpbmcobWluZm9bUF9EUklOS10sICAgICAgICAgICAgUEwpOworICAgIG1pbmZvW1BNX0RFTEFZX1BVQk1BU1RFUl0KKyAgICAgICAgICAgICAgICAgICAgID0gZXZhbF9hbnl0aGluZyhtZW51X2xpc3RbaWRlbnQsUE1fREVMQVldLCBQTCk7CisgICAgbWluZm9bUE1fUkFURV9QVUJNQVNURVJdCisgICAgICAgICAgICAgICAgICAgICA9IGV2YWxfYW55dGhpbmcobWVudV9saXN0W2lkZW50LFBNX1JBVEVdLCAgUEwpOworICAgIG1pbmZvW1BfSFBdICAgICAgPSBldmFsX2FueXRoaW5nKG1pbmZvW1BfSFBdLCAgICAgICAgICAgICAgIFBMKTsKKyAgICBtaW5mb1tQX1NQXSAgICAgID0gZXZhbF9hbnl0aGluZyhtaW5mb1tQX1NQXSwgICAgICAgICAgICAgICBQTCk7CisgICAgZXJnPVBVQk1BU1RFUi0+UmVnaXN0ZXJJdGVtKG1lbnVfbGlzdFtpZGVudCwwXSxtaW5mbyk7CisgICAgbWF4PVBVQk1BU1RFUi0+Q2FsY01heChtaW5mbyxmbik7CisKKyAgICBwcmludGYoIiUtJy4uJzMwLjMwcyAlM2QgJTNkICUzZCAlNWQgJTJkICUyZCAlM2QgJTNkICV8NHMgJTNkXG4iLAorICAgICAgbWVudV9saXN0W2lkZW50LFBNX1RFWFRdLAorICAgICAgbWluZm9bUF9BTENPSE9MXSwgbWluZm9bUF9EUklOS10sIG1pbmZvW1BfRk9PRF0sCisgICAgICBtaW5mb1tQX1ZBTFVFXSwKKyAgICAgIG1pbmZvW1BNX1JBVEVfUFVCTUFTVEVSXSwKKyAgICAgIG1pbmZvW1BNX0RFTEFZX1BVQk1BU1RFUl0sCisgICAgICBtaW5mb1tQX0hQXSwgbWluZm9bUF9TUF0sCisgICAgICAoIGVyZyA/ICJPSyIgOiAiRkFJTCIgKSxtYXgpOworICB9CisgIHdyaXRlKCJEb25lLlxuIik7CisgIHJldHVybiAxOworfQorCit2b2lkIHJlc2V0KCkKK3sKKyAgaWYgKCBzdW0+MCApCisgICAgWkVOVFJBTEJBTkstPlBheUluKHN1bSk7CisgIHN1bT0wOworICByZWZyZXNoX2NvdW50Kys7CisgIFVwZGF0ZUF2YWlsYWJpbGl0eSgpOworfQorCit2b2lkIGFkZF9nbHVlaHdlaW4oKQoreworICBpZiAoIGN0aW1lKHRpbWUoKSlbNC4uNl09PSJEZWMiICkKKyAgICBBZGRUb01lbnUoICJHbHVlaHdlaW4iLCh7ImdsdWVod2VpbiJ9KSwoWworICAgICAgUF9WQUxVRSAgIDogODAsCisgICAgICBQX0RSSU5LICAgOiAgNSwKKyAgICAgIFBfQUxDT0hPTCA6IDIwLAorICAgICAgUF9IUCAgICAgIDogMTUsCisgICAgICBQX1NQICAgICAgOiAxNSBdKSwyLCh7CisgICAgICAoIkR1IHRyaW5rc3QgZWluIEdsYXMgR2x1ZWh3ZWluLCBhbiBkZW0gRHUgRGlyIGJlaW5haGUgZGllIFp1bmdlICIrCisgICAgICAgInZlcmJyZW5uc3QuXG4iKSwKKyAgICAgICgiJiYgYmVzdGVsbHQgZWluIEdsYXMgR2x1ZWh3ZWluIHVuZCB2ZXJicmVubnQgc2ljaCBiZWltXG4iKworICAgICAgICJUcmlua2VuIGJlaW5haGUgZGllIFp1bmdlLlxuIikgfSksIDAsIDAsIDApOworfQorCit2b2lkIGFkZF9zdGRfZHJpbmtzKCkKK3sKKyAgaWYgKCBRdWVyeVByb3AoUF9OT19TVERfRFJJTkspICkKKyAgICByZXR1cm4gOworICBhZGRfZ2x1ZWh3ZWluKCk7Cit9CisKK21hcHBpbmcgcXVlcnlfbWVudWxpc3QoKQoreworICByZXR1cm4gZGVlcF9jb3B5KG1lbnVfbGlzdCk7Cit9CisKK3N0cmluZyAqcXVlcnlfZHJpbmtzKCkKK3sKKyAgc3RyaW5nICpkcj0oe30pOworICBmb3JlYWNoKCBzdHJpbmcgaWRlbnQsIHN0cmluZyBtZW51ZXRleHQsIG1hcHBpbmcgbWluZm86IG1lbnVfbGlzdCkgeworICAgIGlmIChldmFsX2FueXRoaW5nKG1pbmZvW1BfRFJJTktdLCAwKSkKKyAgICAgIGRyICs9ICh7IGlkZW50IH0pOworICB9CisgIHJldHVybiBkcjsKK30KKworc3RyaW5nICpxdWVyeV9mb29kKCkKK3sKKyAgc3RyaW5nICpmbz0oe30pOworICBmb3JlYWNoKCBzdHJpbmcgaWRlbnQsIHN0cmluZyBtZW51ZXRleHQsIG1hcHBpbmcgbWluZm86IG1lbnVfbGlzdCkgeworICAgIGlmIChldmFsX2FueXRoaW5nKG1pbmZvW1BfRk9PRF0sIDApKQorICAgICAgZm8gKz0gKHsgaWRlbnQgfSk7CisgIH0KKyAgcmV0dXJuIGZvOworfQpkaWZmIC0tZ2l0IGEvc3RkL3Jvb20vcmVzdHJpY3Rpb25zLmMgYi9zdGQvcm9vbS9yZXN0cmljdGlvbnMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYTUwYzllCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3Jvb20vcmVzdHJpY3Rpb25zLmMKQEAgLTAsMCArMSw2MSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHJvb20vcmVzdHJpY3Rpb25zLmMgLS0gd2VpZ2h0IHByb3BlcnR5IGhhbmRsaW5nIGZvciByb29tcworLy8KKy8vICRJZDogcmVzdHJpY3Rpb25zLmMgOTAyMCAyMDE1LTAxLTEwIDIxOjQ5OjQxWiBaZXNzdHJhICQKKworaW5oZXJpdCAic3RkL2NvbnRhaW5lci9yZXN0cmljdGlvbnMiOworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorCisvLyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorCitzdGF0aWMgaW50IF9zZXRfd2VpZ2h0KGludCB3KTsKK3N0YXRpYyBpbnQgX3F1ZXJ5X3dlaWdodCgpOworc3RhdGljIGludCBfc2V0X3RvdGFsX3dlaWdodChpbnQgdyk7CitzdGF0aWMgaW50IF9xdWVyeV90b3RhbF93ZWlnaHQoKTsKKwordm9pZCBjcmVhdGUoKQoreworICBTZXQoUF9XRUlHSFQsUFJPVEVDVEVELEZfTU9ERSk7CisgIFNldChQX1RPVEFMX1dFSUdIVCxQUk9URUNURUQsRl9NT0RFKTsKK30KKworaW50IE1heUFkZFdlaWdodChpbnQgdykKK3sKKyAgcmV0dXJuIDA7Cit9CisKK2ludCBNYXlBZGRPYmplY3Qob2JqZWN0IG9iKQoreyAgcmV0dXJuIDE7ICB9CisKK2ludCBQcmV2ZW50SW5zZXJ0KG9iamVjdCBvYikKK3sKKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgX3NldF93ZWlnaHQoaW50IHcpCit7CisgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50IF9xdWVyeV93ZWlnaHQoKQoreworICByZXR1cm4gMDsKK30KKworc3RhdGljIGludCBfc2V0X3RvdGFsX3dlaWdodChpbnQgdykKK3sKKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgX3F1ZXJ5X3RvdGFsX3dlaWdodCgpCit7CisgIHJldHVybiAwOworfQpkaWZmIC0tZ2l0IGEvc3RkL3Jvb20vc2hvcC5jIGIvc3RkL3Jvb20vc2hvcC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM0MjkxMjcKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcm9vbS9zaG9wLmMKQEAgLTAsMCArMSwxMTEwIEBACisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisKK2luaGVyaXQgIi9zdGQvdHJhZGluZ19wcmljZSI7CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvY29tbWFuZHMuaD4KKyNpbmNsdWRlIDx0aGluZy9kZXNjcmlwdGlvbi5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxyb29tcy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8bW92aW5nLmg+CisjaW5jbHVkZSA8cm91dGluZ2QuaD4KKyNpbmNsdWRlIDxiYW5rLmg+CisjaW5jbHVkZSA8Y29tYmF0Lmg+CisjaW5jbHVkZSA8aW5wdXRfdG8uaD4KKyNpbmNsdWRlIDx1bml0Lmg+CisjaW5jbHVkZSA8bW9uZXkuaD4KKworLy8gVE9ETzogcHJ1ZWZlbiwgdW0gZGllIFZhcmlhYmxlbiBwcml2YXRlIHNlaW4ga29lbm5lbi4KKworLy8gYWxsZ2VtZWluIGJlbm9ldGlnZSBWYXJpYWJsZW4KK25vc2F2ZSBzdHJpbmcgc3RvcmFnZTsgLy8gRmlsZW5hbWUgZGVzIFN0b3JlcyBpbiBkZW0gZGllIE9iamVrdGUgbGFnZXJuLi4uCitub3NhdmUgbWFwcGluZyBvYl9hbno7IC8vIHdpZSBvZnQgaXN0IGVpbiBPYmpla3QgaW0gTGFkZW4gdm9yaGFuZGVuPworCisvLyBKZXR6dCBWYXJpYWJsZW4gZnVlciBzdGFlbmRpZyB2ZXJmdWVnYmFyZSBPYmpla3RlOgorbm9zYXZlIHN0cmluZyAqZml4ZWRfb2JqOyAvLyBMaXN0ZSBkZXIgc3RhZW5kaWcgdmVyZnVlZ2JhcmVuIE9iamVrdGUKK25vc2F2ZSBtYXBwaW5nIGZpeGVkX3ZhbHVlOyAvLyBQcmVpc2UgYmVpIFNvbmRlcmFuZ2Vib3Rlbgorbm9zYXZlIG1hcHBpbmcgZml4ZWRfaWRzOyAgIC8vIElkcworCit2YXJhcmdzIHZvaWQgQWRkRml4ZWRPYmplY3Qoc3RyaW5nIHN0ciwgaW50IHZhbCwgc3RyaW5nfHN0cmluZyogaWRzKQoreworICBpbnQgaTsKKworICAvLyBBY2h0dW5nLCBiZWkgc29sY2hlbiBPYmpla3RlbiBtdXNzIGRpZSBCbHVlcHJpbnQgaW5pdGlhbGlzaWVydCB3ZXJkZW4hCisgIGlmICghc3RyKSByZXR1cm47CisgIGlmICghdmFsKSB2YWw9c3RyLT5RdWVyeVByb3AoUF9WQUxVRSk7CisgIGlmICghaWRzKQorICB7CisgICAgaWYgKHN0ci0+UXVlcnlQcm9wKCJ1X2lkcyIpKSAvLyB1bml0cyBoYWJlbiBrZWluZSBQX0lEUworICAgICAgaWRzPXN0ci0+UXVlcnlQcm9wKCJ1X2lkcyIpWzBdOworICAgIGVsc2UKKyAgICAgIGlkcz1zdHItPlF1ZXJ5UHJvcChQX0lEUyk7CisgIH0KKyAgaWYgKCFwb2ludGVycChpZHMpKQorICB7CisgICAgaWYgKHN0cmluZ3AoaWRzKSkKKyAgICAgIGlkcz0oe2lkc30pOworICAgIGVsc2UKKyAgICAgIGlkcz0oe30pOworICB9CisKKyAgZml4ZWRfb2JqICs9ICh7c3RyfSk7CisgIGZpeGVkX3ZhbHVlW3N0cl0gPSB2YWw7CisgIC8vIEFsbGUgSURzIGVudGZlcm5lbiwgZGllIFNvbmRlcnplaWNoZW4gZW50aGFsdGVuLiBEaWUga29lbm50ZSBlaW4gU3BpZWxlcgorICAvLyBiZWkgImthdWZlIiBvaG5laGluIG5pY2h0IGVpbmdlYmVuLgorICBpZHMgLT0gcmVnZXhwKGlkcywgIltcYlxuXHJcdF0iKTsKKyAgZm9yZWFjaChzdHJpbmcgaWQgOiBpZHMpCisgIHsKKyAgICAvLyBOdXIgSURzIGF1Zm5laG1lbiwgZGllIGtlaW5lIEdyb3NzYnVjaHN0YWJlbiBlbnRoYWx0ZW4sIGRhIFNwaWVsZXIKKyAgICAvLyBkaWVzZSBlYmVuZmFsbHMgbmljaHQgZWluZ2ViZW4ga29lbm50ZS4KKyAgICBpZiAoIGxvd2Vyc3RyaW5nKGlkKSA9PSBpZCApCisgICAgICBmaXhlZF9pZHNbaWRdPXN0cjsKKyAgfQorfQorCit2b2lkIFJlbW92ZUZpeGVkT2JqZWN0KHN0cmluZyBmaWxlbmFtZSkKK3sKKyAgaWYoICFzdHJpbmdwKGZpbGVuYW1lKSB8fCAhc2l6ZW9mKGZpeGVkX29iaikpCisgICAgcmV0dXJuOworICBpZiggbWVtYmVyKGZpeGVkX29iaiwgZmlsZW5hbWUpPT0tMSApCisgICAgcmV0dXJuOworCisgIGZpeGVkX29iaiAtPSAoeyBmaWxlbmFtZSB9KTsKKyAgbV9kZWxldGUoZml4ZWRfdmFsdWUsIGZpbGVuYW1lKTsKKworICBmb3JlYWNoKHN0cmluZyBpZCwgc3RyaW5nIGZpbGUgOiBmaXhlZF9pZHMpCisgIHsKKyAgICBpZiAoIGZpbGUgPT0gZmlsZW5hbWUgKQorICAgICAgbV9kZWxldGUoZml4ZWRfaWRzLCBpZCk7CisgIH0KK30KKworc3RhdGljIHN0cmluZyBTZXRTdG9yYWdlUm9vbShzdHJpbmcgc3RyKQoreworICBpZiAoc3RyICYmIHN0cmluZ3Aoc3RyKSkgcmV0dXJuIHN0b3JhZ2U9c3RyOworICByZXR1cm4gMDsKK30KKworc3RyaW5nIFF1ZXJ5U3RvcmFnZVJvb20oKQoreyAgIHJldHVybiBzdG9yYWdlOyAgIH0KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgb2JqZWN0IHJvdXRlcjsKKyAgCisgIGlmIChvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSA9PSBfX0ZJTEVfX1swLi48M10pCisgIHsKKyAgICBzZXRfbmV4dF9yZXNldCgtMSk7CisgICAgcmV0dXJuOworICB9CisKKyAgdHJhZGluZ19wcmljZTo6Y3JlYXRlKCk7CisKKyAgU2V0UHJvcCggUF9OQU1FLCAiSGFlbmRsZXIiICk7CisgIFNldFByb3AoIFBfR0VOREVSLCBNQUxFICk7CisgIFNldFByb3AoIFBfUk9PTV9UWVBFLCBRdWVyeVByb3AoUF9ST09NX1RZUEUpIHwgUlRfU0hPUCApOworCisgIEFkZENtZCgiemVpZ2UiLCJsaXN0Iik7CisgIEFkZENtZCgoeyJrYXVmIiwia2F1ZmUiLCJiZXN0ZWxsIiwiYmVzdGVsbGUifSksImJ1eSIpOworICBBZGRDbWQoKHsidmVya2F1ZiIsInZlcmthdWZlIiwidmVyayJ9KSwic2VsbCIpOworICBBZGRDbWQoKHsidmVyc2V0eiIsInZlcnNldHplIn0pLCJmb3JjZV9zZWxsIik7CisgIEFkZENtZCgoeyJzY2hhZXR6Iiwic2NoYWV0emUifSksImV2YWx1YXRlIik7CisgIEFkZENtZCgoeyJ1bnRlcnN1Y2hlIiwidW50In0pLCAic2hvd19vYmoiKTsKKworICBTZXRUcmFkaW5nRGF0YSg1MDAwMCwzMDAsMyk7CisKKyAgb2JfYW56PShbXSk7CisgIGZpeGVkX29iaj0oe30pO2ZpeGVkX3ZhbHVlPShbXSk7Zml4ZWRfaWRzPShbXSk7CisKKyAgQWRkRml4ZWRPYmplY3QoQk9FUlNFLCA4MCwoeyAiYm9lcnNlIiwiZ2VsZGJvZXJzZSJ9KSk7CisKKyAgaWYgKCFjbG9uZXAoTUUpICYmIG9iamVjdHAocm91dGVyPWZpbmRfb2JqZWN0KFJPVVRFUikpKQorICAgIHJvdXRlci0+UmVnaXN0ZXJUYXJnZXQoVEFSR0VUX1NIT1Asb2JqZWN0X25hbWUoTUUpKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKKy8vIExlZ2FjeS1WZXJzaW9uIHZvbiBHZXRTaG9wSXRlbXMoKSBmdWVyIGRpZSBlcmJlbmRlbiBMYWVkZW4sIGRpZSBhdWYKKy8vIGRpZSBGdW5rdGlvbiBpbiBkaWVzZXIgRm9ybSBhbmdld2llc2VuIHNpbmQuCitzdGF0aWMgbWl4ZWQgKkdldExpc3QoKQoreworICBvYmplY3Qgc3RvcmUgPSBsb2FkX29iamVjdChzdG9yYWdlKTsKKyAgc3RvcmUtPl9yZWdpc3Rlcl9zaG9wKE1FKTsKKworICBtaXhlZCAqb3V0cHV0PSh7fSk7CisgIGlmICghb2JqZWN0cChzdG9yZSkpCisgICAgcmV0dXJuIG91dHB1dDsKKworICBtaXhlZCB0bXAgPSBtYXAoZml4ZWRfb2JqLCAjJ2xvYWRfb2JqZWN0KSthbGxfaW52ZW50b3J5KHN0b3JlKTsKKyAgbWFwcGluZyB0bXAyID0gKFtdKTsKKyAgbWl4ZWQgc3RyOworICBzdHJpbmcgY29tcDsKKyAgaW50IGk7CisgIGludCBzPTE7CisKKyAgZm9yIChpPXNpemVvZih0bXApLTEgOyBpPj0wIDsgaS0tKQorICB7CisgICAgc3RyID0gKHsgKHsgc3ByaW50ZigiJS0yNS4yNXMlNy43ZCIsCisgICAgICAgICAgICAgICAgICAgICAgICAodG1wW2ldLT5zaG9ydCgpfHwiPz8/IilbMC4uPDNdLAorICAgICAgICAgICAgICAgICAgICAgICAgUXVlcnlCdXlWYWx1ZSh0bXBbaV0sIFBMKSksCisgICAgICAgICAgICAgICAgdG1wW2ldIH0pIH0pOworICAgIGNvbXA9c3RyWzBdWzBdWzAuLjI1XTsKKyAgICBpZiAoIXRtcDJbY29tcF0pCisgICAgeworICAgICAgdG1wMltjb21wXSA9IHMrKzsKKyAgICAgIG91dHB1dCArPSBzdHI7CisgICAgfQorICAgIGVsc2Ugb3V0cHV0W3RtcDJbY29tcF0tMV1bMF0gPSBzdHJbMF1bMF07CisgIH0KKyAgcmV0dXJuIG91dHB1dDsKK30KKworLy8gTGVnYWN5LVZlcnNpb24gdm9uIFByaW50TGlzdCgpIGZ1ZXIgZGllIGVyYmVuZGVuIExhZWRlbiwgZGllIGF1ZgorLy8gZGllIEZ1bmt0aW9uIGluIGRpZXNlciBGb3JtIGFuZ2V3aWVzZW4gc2luZC4KK3N0YXRpYyBpbnQgRG9MaXN0KHN0cmluZyBxdWVyeV9mdW4pCit7CisgIG1peGVkKiBvdXRwdXQ9R2V0TGlzdCgpOworICBpbnQgc2kgPSBzaXplb2Yob3V0cHV0KTsKKyAgaWYgKCFzaSkKKyAgeworICAgIHdyaXRlKCJJbSBNb21lbnQgc2luZCB3aXIgbGVpZGVyIFZPRUxMSUcgYXVzdmVya2F1ZnQhXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBzdHJpbmcgb3V0PSIiOworICBpbnQgaTsKKyAgaW50IGluZGVudDsKKyAgZm9yIChpPTA7IGk8c2k7IGkrKykKKyAgeworICAgIGlmIChjYWxsX290aGVyKE1FLCBxdWVyeV9mdW4sIG91dHB1dFtpXVsxXSkpCisgICAgeworICAgICAgaW5kZW50ID0gIWluZGVudDsKKyAgICAgIG91dCArPSBzcHJpbnRmKCIlM2QuICVzIiwgaSsxLCBvdXRwdXRbaV1bMF0pOworICAgICAgaWYgKCFpbmRlbnQpCisgICAgICAgIG91dCArPSAiXG4iOworICAgICAgZWxzZSBvdXQgKz0gIiB8ICI7CisgICAgfQorICB9CisgIGlmIChpbmRlbnQpCisgICAgb3V0Kz0iXG4iOworICBQTC0+TW9yZShvdXQpOworICByZXR1cm4gMTsKK30KKworLy8gTGllZmVydCBlaW5lIExpc3RlIGRlciBPYmpla3RlIHp1cnVlY2ssIGRpZSBnZXJhZGUgaW0gU3RvcmFnZSBsaWVnZW4sCisvLyBwcm8gQmx1ZXByaW50IGpld2VpbHMgZWlucy4KK3Byb3RlY3RlZCBvYmplY3QqIEdldFNob3BJdGVtcygpCit7CisgIG9iamVjdCBzdG9yZSA9IGxvYWRfb2JqZWN0KHN0b3JhZ2UpOworICBzdG9yZS0+X3JlZ2lzdGVyX3Nob3AoTUUpOworICBvYmplY3QqIG91dHB1dCA9ICh7fSk7CisgIG9iamVjdCogYWxsX2l0ZW1zID0gYWxsX2ludmVudG9yeShzdG9yZSk7CisKKyAgLy8gV2lyIGJyYXVjaGVuIGVpbmUgTGlzdGUsIGRpZSB2b24gamVkZXIgQmx1ZXByaW50IG51ciBlaW5lbiBDbG9uZQorICAvLyBlbnRoYWVsdC4gRGFoZXIgd2VyZGVuIGRpZSBMYWRlbmFtZW4gZGVyIE9iamVrdGUgYWxzIEtleXMgaW0gTWFwcGluZworICAvLyA8aXRlbXM+IHZlcndlbmRldCB1bmQgamV3ZWlscyBkZXIgYWt0dWVsbGUgQ2xvbmUgYWxzIFZhbHVlIHp1Z2VvcmRuZXQuCisgIG1hcHBpbmcgaXRlbXMgPSBtX2FsbG9jYXRlKHNpemVvZihhbGxfaXRlbXMpKTsKKyAgZm9yZWFjaChvYmplY3Qgb2I6IGFsbF9pdGVtcykKKyAgeworICAgIGl0ZW1zW2xvYWRfbmFtZShvYildID0gb2I7CisgIH0KKyAgLy8gRGllIEZpeGVkIE9iamVjdHMgd2VyZGVuIGFucyBFbmRlIGFuZ2VoYWVuZ3QsIGRhbWl0IGluIGRlbSBGYWxsLCBkYXNzCisgIC8vIGVpbiBDbG9uZSBlaW5lcyBzb2xjaGVuIE9iamVrdGVzIGltIExhZ2VyIGxpZWd0LCBkaWVzZXIgenVlcnN0IHZlcmthdWZ0CisgIC8vIHdpcmQgdW5kIG5pY2h0IGltbWVyIHdpZWRlciBlaW4gbmV1ZXIgZXJzdGVsbHQgd2lyZC4KKyAgcmV0dXJuIG1fdmFsdWVzKGl0ZW1zKSArIG1hcChmaXhlZF9vYmosICMnbG9hZF9vYmplY3QpOworfQorCisjZGVmaW5lIExJU1RfTE9ORyAgMQorI2RlZmluZSBMSVNUX1NIT1JUIDAKKworLy8gS3VlbW1lcnQgc2ljaCB1bSBkaWUgTGlzdGVuYXVzZ2FiZSBmdWVyIGRlbiBCZWZlaGwgInplaWdlIgordmFyYXJncyBwcm90ZWN0ZWQgaW50IFByaW50TGlzdChzdHJpbmcgZmlsdGVyX2Z1biwgaW50IGxpc3RzdHlsZSkKK3sKKyAgLy8gQWxsZSBJdGVtcyBpbSBMYWdlciBob2xlbi4gV2VubiBrZWluZSB2b3JoYW5kZW4sIHR1dCB1bnMgZGFzIGxlaWQuCisgIG9iamVjdCAqaXRlbXNfaW5fc3RvcmUgPSBHZXRTaG9wSXRlbXMoKTsKKyAgaWYgKCAhc2l6ZW9mKGl0ZW1zX2luX3N0b3JlKSApIHsKKyAgICB3cml0ZSgiSW0gTW9tZW50IHNpbmQgd2lyIGxlaWRlciBWT0VMTElHIGF1c3ZlcmthdWZ0IVxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKworICAvLyBEYXMgTGlzdGVuZm9ybWF0IGlzdCB2b24gZGVyIFNwaWVsZXJlaW5nYWJlIGFiaGFlbmdpZy4gV3VyZGUgImxhbmciCisgIC8vIGFuZ2Vmb3JkZXJ0LCBnZWJlbiB3aXIgZWluc3BhbHRpZyBhdXMgbWl0IGdyb2Vzc2VyZXIgU3BhbHRlbmJyZWl0ZS4KKyAgLy8gRGllIFNwYWx0ZW5icmVpdGUgd2lyZCBkYWJlaSB2b24gZGVtIEl0ZW0gbWl0IGRlbSBsYWVuZ3N0ZW4gTmFtZW4gaW0KKyAgLy8gZ2VzYW10ZW4gU2hvcC1JbnZlbnRhciBiZXN0aW1tdCwgZGFtaXQgbmljaHQgYmVpIGplZGVyIFRlaWxsaXN0ZQorICAvLyAoV2FmZmVuLCBSdWVzdHVuZ2VuLCBWZXJzY2hpZWRlbmVzKSB1bnRlcnNjaGllZGxpY2hlIEJyZWl0ZW4gcmF1c2tvbW1lbi4KKyAgLy8KKyAgLy8gRGVyIGVyc3RlIFBhcmFtZXRlciBlbnRoYWVsdCBkaWUgS2F0YWxvZ251bW1lciBkZXMgSXRlbXMsIGRlciB6d2VpdGUKKyAgLy8gZGllIEt1cnpiZXNjaHJlaWJ1bmcsIGRlciBkcml0dGUgZGVuIFByZWlzLgorICBzdHJpbmcgbGlzdGZvcm1hdCA9ICIlM2QuICUtMjUuMjVzICU2LjZkIjsKKyAgaWYgKCBsaXN0c3R5bGUgPT0gTElTVF9MT05HICkKKyAgeworICAgIHN0cmluZyogbmFtZXMgPSBzb3J0X2FycmF5KAorICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zX2luX3N0b3JlLT5zaG9ydCgpLAorICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGludCAoc3RyaW5nIHMxLCBzdHJpbmcgczIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoc2l6ZW9mKHMxKSA8IHNpemVvZihzMikpOworICAgICAgICAgICAgICAgICAgICAgIH0pOworICAgIC8vIFdlbm4gZWluc3BhbHRpZyBhdXNnZWdlYmVuIHdpcmQsIHNvbGwgZGllIExpc3RlIG5pY2h0IGJlbGllYmlnIGJyZWl0CisgICAgLy8gd2VyZGVuLiBEYWhlciB3aXJkIGRpZSBTaG9ydCBhdWYgNjUgWmVpY2hlbiBsaW1pdGllcnQuCisgICAgaW50IGxlbiA9IDY1OworICAgIGlmICggc2l6ZW9mKG5hbWVzKSApCisgICAgICBsZW4gPSBtaW4obGVuLCBzaXplb2YobmFtZXNbMF0pKTsKKyAgICBsaXN0Zm9ybWF0ID0gIiUzZC4gJS0iK2xlbisiLiIrbGVuKyJzICU2LjZkIjsKKyAgfQorCisgIHN0cmluZyBvdXQ9IiI7CisgIC8vIFZhcmlhYmxlbiwgZGllIGlubmVyaGFsYiBkZXIgU2NobGVpZmUgYmVub2V0aWd0IHdlcmRlbi4KKyAgc3RyaW5nIGt1cno7CisgIGludCBpbmRlbnQsIHByZWlzOworICBvYmplY3QgaXRlbTsKKyAgLy8gVWViZXIgZGllIExpc3RlIGxhdWZlbi4gPGk+IHdpcmQgYmVub2V0aWd0LCB1bSBkaWUgYXVzZ2VnZWJlbmUgTGlzdGUKKyAgLy8ga29uc2lzdGVudCBudW1lcmllcmVuIHp1IGtvZW5uZW4sIGRhbWl0IGthdWZlIDxucj4gZnVua3Rpb25pZXJ0LgorICBmb3JlYWNoKGludCBpIDogc2l6ZW9mKGl0ZW1zX2luX3N0b3JlKSkKKyAgeworICAgIGl0ZW0gPSBpdGVtc19pbl9zdG9yZVtpXTsKKyAgICBpZiAoIGNhbGxfb3RoZXIoTUUsIGZpbHRlcl9mdW4sIGl0ZW0pICkKKyAgICB7CisgICAgICAvLyBLdXJ6YmVzY2hyZWlidW5nIHVuZCBQcmVpcyBlcm1pdHRlbG4uIEl0ZW1zIG9obmUgU2hvcnQgd2VyZGVuCisgICAgICAvLyBhbHMgIj8iIGFuZ2V6ZWlndC4KKyAgICAgIGt1cnogPSAoaXRlbS0+c2hvcnQoKSB8fCAiPz8/IilbMC4uPDNdOworICAgICAgcHJlaXMgPSBRdWVyeUJ1eVZhbHVlKGl0ZW0sIFBMKTsKKyAgICAgIC8vIEJlc2NocmVpYnVuZyBkZXMgSXRlbXMgYW5mdWVnZW4uCisgICAgICBvdXQgKz0gc3ByaW50ZihsaXN0Zm9ybWF0LCBpKzEsIGt1cnosIHByZWlzKTsKKyAgICAgIGluZGVudCA9ICFpbmRlbnQ7CisgICAgICAvLyBXZW5uIGluZGVudCBnZXNldHp0IGlzdCwgaGFuZGVsdCBlcyBzaWNoIHVtIGRhcyBsaW5rZSBJdGVtIGluIGRlcgorICAgICAgLy8gendlaXNwYWx0aWdlbiBMaXN0ZSwgZGFubiBmdWVnZW4gd2lyIGVpbmVuIFNwYWx0ZW50cmVubmVyIGFuLAorICAgICAgLy8gYW5zb25zdGVuIGlzdCBlcyBkYXMgcmVjaHRlLCBkYW5uIGJyZWNoZW4gd2lyIHVtLgorICAgICAgLy8gR2lsdCBuYXR1ZXJsaWNoIG51ciBmdWVyIGt1cnplIExpc3Rlbi4KKyAgICAgIG91dCArPSAoKGluZGVudCAmJiBsaXN0c3R5bGU9PUxJU1RfU0hPUlQpPyAiIHwgIiA6ICJcbiIpOworICAgIH0KKyAgfQorICAvLyBXZW5uIGRpZSBMaXN0ZSBlaW5lIHVuZ2VyYWRlIFphaGwgSXRlbXMgZW50aGFlbHQsIGlzdCBpbiBkZXIgbGV0enRlbgorICAvLyBaZWlsZSBsaW5rcyBlaW4gSXRlbSBhdWZnZWZ1ZWhydCwgZGFoZXIgbXVzcyBkYW5hY2ggdW1icm9jaGVuIHdlcmRlbi4KKyAgLy8gR2lsdCBuYXR1ZXJsaWNoIG51ciBmdWVyIGt1cnplIExpc3RlbgorICBpZiAoaW5kZW50ICYmIGxpc3RzdHlsZT09TElTVF9TSE9SVCkKKyAgICBvdXQrPSJcbiI7CisKKyAgLy8gVm9yIGRlbiBMaXN0ZW4gd2lyZCBlaW5lIEluZm8tWmVpbGUgYXVzZ2VnZWJlbiwgdW0gZ2VmaWx0ZXJ0ZSBMaXN0ZW4KKyAgLy8ga2VubnRsaWNoIHp1IG1hY2hlbi4gV2lyZCBuYWNoIGRlciBGaWx0ZXJ1bmcgZGVzIEludmVudGFycyBlcnpldWd0LAorICAvLyB1bSBlaW5lIGxlZXJlIE1lbGR1bmcgYXVzZ2ViZW4genUga29lbm5lbiwgd2VubiBuYWNoIEZpbHRlcnVuZyBuaWNodHMKKyAgLy8gbWVociB1ZWJyaWdibGVpYnQuCisgIHN0cmluZyB3YXM7CisgIHN3aXRjaChmaWx0ZXJfZnVuKQorICB7CisgICAgY2FzZSAiSXNBcm1vdXIiOiB3YXMgPSAiUnVlc3R1bmdlbiI7IGJyZWFrOworICAgIGNhc2UgIklzV2VhcG9uIjogd2FzID0gIldhZmZlbiI7IGJyZWFrOworICAgIGNhc2UgIk5vV2VhcG9uTm9Bcm1vdXIiOgorICAgICAgICAgd2FzID0gKG91dD09IiI/InNvbnN0aWdlbiBXYXJlbiI6InNvbnN0aWdlIFdhcmVuIik7IGJyZWFrOworICAgIGRlZmF1bHQ6IHdhcyA9ICJXYXJlbiI7IGJyZWFrOworICB9CisgIC8vIDxvdXQ+IGlzdCBlaW4gTGVlcnN0cmluZywgd2VubiBrZWluZSBXYXJlbiBkYSBzaW5kLCBkaWUgZGVtIEZpbHRlcmtyaS0KKyAgLy8gdGVyaXVtIGVudHNwcmVjaGVuLiBEYW5uIGdpYnQncyBlaW5lIGVudHNwcmVjaGVuZGUgTWVsZHVuZy4KKyAgaWYgKCBvdXQgPT0gIiIgKQorICAgIG91dCA9IHNwcmludGYoIkxlaWRlciBzaW5kIG1vbWVudGFuIGtlaW5lICVzIGltIEFuZ2Vib3QuXG4iLCB3YXMpOworICBlbHNlCisgICAgb3V0ID0gc3ByaW50ZigiRm9sZ2VuZGUgJXMga2FubnN0IER1IGhpZXIga2F1ZmVuOlxuIix3YXMpICsgb3V0OworCisgIFBMLT5Nb3JlKG91dCk7CisgIHJldHVybiAxOworfQorCisvLyBIaWxmc2Z1bmt0aW9uZW4genVtIEZpbHRlcm4gZGVzIExhZGVuaW52ZW50YXJzIGZ1ZXIgZGVuICJ6ZWlnZSItQmVmZWhsCitzdGF0aWMgaW50IEFsd2F5c1RydWUob2JqZWN0IG9iKQoreyAgIHJldHVybiAxOyAgIH0KKworc3RhdGljIHN0cmluZyBJc1dlYXBvbihvYmplY3Qgb2IpCit7ICByZXR1cm4gb2ItPlF1ZXJ5UHJvcChQX1dFQVBPTl9UWVBFKTsgIH0KKworc3RhdGljIHN0cmluZyBJc0FybW91cihvYmplY3Qgb2IpCit7ICByZXR1cm4gb2ItPlF1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKTsgIH0KKworc3RhdGljIGludCBOb1dlYXBvbk5vQXJtb3VyKG9iamVjdCBvYikKK3sgcmV0dXJuICghb2ItPlF1ZXJ5UHJvcChQX1dFQVBPTl9UWVBFKSAmJiAhb2ItPlF1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKSk7IH0KKworCisvLyBEaWVzZSBGdW5rdGlvbiBpc3Qgb2VmZmVudGxpY2gsIGZhbGxzIE1hZ2llciBhYmZyYWdlbiB3b2xsZW4sIG9iIGVpbiBsYWRlbgorLy8gZWluIE9iamVrdCB6ZXJzdG9lcmVuIHd1ZXJkZS4gQWJlcjogQmVudXR6dW5nIGF1ZiBlaWdlbmVzIFJpc2lrbyEgRXMgd2lyZAorLy8gbmljaHQgZ2FyYW50aWVydCwgZGFzcyBkaWVzZSBGdW5rdGlvbiBiencuIGlociBJbnRlcmZhY2Ugc2ljaCBuaWNodAorLy8gYWVuZGVydC4KK3B1YmxpYyBpbnQgQ2hlY2tGb3JEZXN0cnVjdChvYmplY3Qgb2IpIC8vIFBydWVmZW4sIG9iIHplcnN0b2VydCB3ZXJkZW4gc29sbAoreworICBzdHJpbmcgc3RyOworICAvKgorICAgKiBQX05PQlVZIC0gT2JqZWt0ZSBhdWYgamVkZW4gRmFsbCB6ZXJzdG9lcmVuCisgICAqLworICBpZihvYi0+UXVlcnlQcm9wKFBfTk9CVVkpKSByZXR1cm4gMTsKKyAgLyoKKyAgICogQmVzY2hhZWRpZ3RlIE9iamVrdGUgd2VyZGVuIGViZW5mYWxscyB6ZXJzdG9lcnQKKyAgICovCisgIGlmKG9iLT5RdWVyeVByb3AoUF9EQU1BR0VEKSkgcmV0dXJuIDE7CisgIC8qCisgICAqIFJ1ZXN0dW5nZW4gd2VubiBzaWUgYSkgZWluZSBEZWZlbmRGdW5jIGRlZmluaWVydCBoYWJlbiBvZGVyCisgICAqICAgICAgICAgICAgICAgICAgICAgYikgdWViZXIgZGVyIGluIEtFRVBfQVJNT1VSX0NMQVNTIGRlZmluaWVydGVuIEFDCisgICAqICAgICAgICAgICAgICAgICAgICAgICAgbGllZ2VuIChzaWVoZSAvc3lzL2NvbWJhdC5oKQorICAgKi8KKyAgaWYoc3RyID0gSXNBcm1vdXIob2IpKQorICB7CisgICAgaWYob2JqZWN0cChvYi0+UXVlcnlQcm9wKFBfREVGRU5EX0ZVTkMpKSkgcmV0dXJuIDE7CisgICAgaWYob2ItPlF1ZXJ5UHJvcChQX0FDKSA+PSBLRUVQX0FSTU9VUl9DTEFTU1tzdHJdKSByZXR1cm4gMTsKKyAgICByZXR1cm4gMDsKKyAgfQorICAvKgorICAgKiBXYWZmZW4gd2VubiBzaWUgYSkgMS1oYWVuZGlnIHNpbmQgdW5kIGVpbmUgV0MgPiAxMjAgYmVzaXR6ZW4gb2RlcgorICAgKiAgICAgICAgICAgICAgICAgYikgMi1oYWVuZGlnIHNpbmQgdW5kIGVpbmUgV0MgPiAxNTAgYmVzaXR6ZW4gb2RlciBhYmVyCisgICAqICAgICAgICAgICAgICAgICBjKSBlaW5lIEhpdEZ1bmMgZGVmaW5pZXJ0IGhhYmVuCisgICAqLworICBpZihzdHIgPSBJc1dlYXBvbihvYikpCisgIHsKKyAgICBpZihvYi0+UXVlcnlQcm9wKFBfTlJfSEFORFMpID4gMSAmJiBvYi0+UXVlcnlQcm9wKFBfV0MpID4gMTUwKSByZXR1cm4gMTsKKyAgICBpZihvYi0+UXVlcnlQcm9wKFBfTlJfSEFORFMpIDwgMiAmJiBvYi0+UXVlcnlQcm9wKFBfV0MpID4gMTIwKSByZXR1cm4gMTsKKyAgICBpZihvYmplY3RwKG9iLT5RdWVyeVByb3AoUF9ISVRfRlVOQykpKSByZXR1cm4gMTsKKyAgICByZXR1cm4gMDsKKyAgfQorICByZXR1cm4gMDsKK30KKworc3RhdGljIGludCBsaXN0KHN0cmluZyBzdHIpCit7CisgIF9ub3RpZnlfZmFpbCgKKyAgICAiQml0dGUgJ3plaWdlJywgJ3plaWdlIHdhZmZlbicsICd6ZWlnZSBydWVzdHVuZ2VuJyBvZGVyXG4iCisgICAgIid6ZWlnZSB2ZXJzY2hpZWRlbmVzJyBlaW5nZWJlbi4gV2VubiBEdSBkYXMgU2NobHVlc3NlbHdvcnQgJ2xhbmcnXG4iCisgICAgIm9kZXIgJy0xJyBhbmhhZW5nc3QsIHdpcmQgZGllIExpc3RlIGVpbnNwYWx0aWcgYXVzZ2VnZWJlbi5cbiIpOworCisgIGlmICghc3RyaW5ncChzdHIpIHx8ICFzaXplb2Yoc3RyKSApCisgICAgcmV0dXJuIFByaW50TGlzdCgiQWx3YXlzVHJ1ZSIpOworICBpZiAoIHN0ciA9PSAibGFuZyIgfHwgc3RyID09ICItMSIgKQorICAgIHJldHVybiBQcmludExpc3QoIkFsd2F5c1RydWUiLCBMSVNUX0xPTkcpOworCisgIHN0cmluZyAqcGFyYW1zID0gZXhwbG9kZShzdHIsIiAiKTsKKyAgaWYgKHNpemVvZihwYXJhbXNbMF0pPDMpCisgICAgcmV0dXJuIDA7CisKKyAgaW50IGxpc3RzdHlsZSA9IExJU1RfU0hPUlQ7CisgIGlmICggc2l6ZW9mKHBhcmFtcyk+MSAmJiBwYXJhbXNbMV0gPT0gImxhbmciICkKKyAgICBsaXN0c3R5bGUgPSBMSVNUX0xPTkc7CisKKyAgc3RyPXBhcmFtc1swXVswLi4yXTsKKyAgaWYgKHN0cj09IndhZiIpCisgICAgcmV0dXJuIFByaW50TGlzdCgiSXNXZWFwb24iLCBsaXN0c3R5bGUpOworICBpZiAoc3RyPT0idmVyIikKKyAgICByZXR1cm4gUHJpbnRMaXN0KCJOb1dlYXBvbk5vQXJtb3VyIiwgbGlzdHN0eWxlKTsKKyAgaWYgKHN0cj09InJ1ZSIpCisgICAgcmV0dXJuIFByaW50TGlzdCgiSXNBcm1vdXIiLCBsaXN0c3R5bGUpOworICByZXR1cm4gMDsKK30KKy8qCitzdGF0aWMgdmFyYXJncyBpbnQgUXVlcnlCdXlWYWx1ZShtaXhlZCBvYiwgb2JqZWN0IGNsaWVudCkKK3sKKyAgaWYgKG9iamVjdHAob2IpKQorICAgIHJldHVybiB0cmFkaW5nX3ByaWNlOjpRdWVyeUJ1eVZhbHVlKG9iLCBjbGllbnQpOworICByZXR1cm4gKGZpeGVkX3ZhbHVlW29iXSpRdWVyeUJ1eUZhY3QoY2xpZW50KSkvMTAwOworfQorKi8KKworc3RhdGljIHZhcmFyZ3MgaW50IFF1ZXJ5QnV5VmFsdWUob2JqZWN0IG9iLCBvYmplY3QgY2xpZW50KQoreworICBpbnQgZnByaWNlID0gZml4ZWRfdmFsdWVbbG9hZF9uYW1lKG9iKV07CisKKyAgcmV0dXJuIChmcHJpY2U+MCkgPyAKKyAgICAgICAgIGZwcmljZSpRdWVyeUJ1eUZhY3QoY2xpZW50KS8xMDAgOiAKKyAgICAgICAgIHRyYWRpbmdfcHJpY2U6OlF1ZXJ5QnV5VmFsdWUob2IsIGNsaWVudCk7Cit9CisKK3N0YXRpYyB2b2lkIFVwZGF0ZUNvdW50ZXIob2JqZWN0IG9iLCBpbnQgbnVtKQoreworICBzdHJpbmcgdG1wOworCisgIGlmICghbnVtIHx8ICFvYmplY3RwKG9iKSkgcmV0dXJuOworICB0bXA9QkxVRV9OQU1FKG9iKTsKKyAgaWYgKHRtcFswLi4yXSE9Ii9kLyIgJiYgdG1wWzAuLjhdIT0iL3BsYXllcnMvIikKKyAgICB0bXA9b2ItPnNob3J0KCkrdG1wOworICBvYl9hbnpbdG1wXSArPSBudW07CisgIGlmIChvYl9hbnpbdG1wXSA8PSAwKQorICAgIG1fZGVsZXRlKG9iX2Fueix0bXApOworfQorCitwcm90ZWN0ZWQgb2JqZWN0IEZpbmRJblN0b3JlKHN0cmluZ3xpbnQgeCkKK3sKKyAgb2JqZWN0KiBsaXN0ID0gR2V0U2hvcEl0ZW1zKCk7CisgIGlmICggaW50cCh4KSAmJiB4PjAgJiYgeDw9c2l6ZW9mKGxpc3QpICkgeworICAgIHJldHVybiBsaXN0W3gtMV07CisgIH0KKyAgaWYgKHN0cmluZ3AoeCkpCisgIHsKKyAgICBpZiAoIGZpeGVkX2lkc1t4XSApCisgICAgICByZXR1cm4gbG9hZF9vYmplY3QoZml4ZWRfaWRzW3hdKTsKKyAgICBsaXN0ID0gZmlsdGVyX29iamVjdHMobGlzdCwgImlkIiwgeCk7CisgICAgaWYgKCBzaXplb2YobGlzdCkgKQorICAgICAgcmV0dXJuIGxpc3RbMF07CisgICAgLy8gV2VubiBuaXggaW0gU3RvcmUgZ2VmdW5kZW4gKGRhcyBzY2hsaWVzc3QgZWlnZW50bGljaHQgc2Nob24gZGllIEJQcyBkZXIKKyAgICAvLyBmaXhlbiBPYmpla3RlIGVpbiwgYWJlciBuaWNodCwgd2VubiBkaWVzZSBuaWNodCBrb25maWd1cmllcnQgc2luZC4gRC5oLgorICAgIC8vIGRpZXNlIFBydWVmdW5nIGlzdCBmdWVyIG5pY2h0LWtvbmZpZ3VyaWVydGUgQlBzKSwgTGlzdGUgZGVyCisgICAgLy8gRml4ZWRPYmplY3RzIHBydWVmZW4gdW5kZSBzbyBkaWUgZXZlbnR1ZWxsIG1hbnVlbGwgaW4KKyAgICAvLyBBZGRGaXhlZE9iamVjdCgpIGFuZ2VnZWJlbmUgTGlzdGUgdm9uIElEcyBiZXJ1ZWNrc2ljaHRpZ2VuLgorICAgIGVsc2UgaWYgKCBmaXhlZF9pZHNbeF0gKQorICAgICAgcmV0dXJuIGxvYWRfb2JqZWN0KGZpeGVkX2lkc1t4XSk7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBzdHJpbmcgYnV5X29iaihtaXhlZCBvYiwgaW50IHNob3J0KQoreyByZXR1cm4gMDsgfQorCitwcml2YXRlIHZvaWQgcmVhbGx5X2J1eShpbnQgdmFsLCBvYmplY3QgcGwsIG9iamVjdCBvYiwgaW50IHVfcmVxKQoreworICAvLyBTdGFlbmRpZyB2ZXJmdWVnYmFyZSBPYmpla3RlIChmaXhlZF9vYmopIHNpbmQgZGFyYW4gZXJrZW5uYmFyLCBkYXNzIHNpZQorICAvLyBuaWNodCBpbSBMYWdlciBsaWVnZW4uIERhaGVyIGhpZXIgZWluZW4gQ2xvbmUgZXJzdGVsbGVuLCBkZXIgZGFubiAKKyAgLy8gc3RhdHRkZXNzZW4gcmF1c2dlZ2ViZW4gd2lyZC4KKyAgaWYgKCAhcHJlc2VudChvYiwgZmluZF9vYmplY3Qoc3RvcmFnZSkpICkKKyAgICBvYiA9IGNsb25lX29iamVjdChvYik7CisKKyAgLy8gSW4gVW5pdG9iamVrdGVuIFVfUkVRICh3aWVkZXIpIHNldHplbiAod2VnZW4gaW5wdXRfdG8gKGJlaSBkZW0gc2ljaCBkYXMKKyAgLy8gS29tbWFuZG92ZXJiIGFlbmRlcnQgdW5kIGRlc3dlZ2VuIFVfUkVRIGdlbG9lc2NodCB3aXJkKSwgdW5kIHdlZ2VuCisgIC8vIEthdWZlbnMgdm9uIEZpeGVkLU9iamVrdC1Vbml0b2JqZWt0ZW4gKGJlaSBkaWVzZW4gbXVzcyBVX1JFUSBfbmFjaF8gZGVtCisgIC8vIENsb25lbiBpbSBDbG9uZSBnZXNldHp0IHdlcmRlbiwgbmljaHQgYXV0b21hZ2lzY2ggaW4gZGVyIEJQIGR1cmNoIGRlbgorICAvLyBBdWZydWYgdm9uIGlkKCkgd2VpdGVyIHZvcmhlcikuCisgIGlmICh1X3JlcT4wKQorICB7CisgICAgLy8gRGFzIFF1ZXJ5UHJvcCgpIGlzdCBuaWNodCB1bm5vZXRpZy4gQmVpIGRlciBBYmZyYWdlIHZvbiBVX1JFUSB3aXJkCisgICAgLy8gVV9SRVEgZ2VudWxsdCwgd2VubiBkYXMgYWt0dWVsbGUgcXVlcnlfdmVyYigpICE9IGRlbSBsZXR6dGVuIGlzdC4KKyAgICAvLyBCZWkgZGVyIGVyc3RlbiBBYmZyYWdlIHd1ZXJkZSBhbHMgZGFzIGhpZXIgZ2VzZXR6dCBVX1JFUSB3aWVkZXIKKyAgICAvLyBnZWxvZXNjaHQuIERhaGVyIG11c3MgZGFzIGpldHp0IGhpZXIgYWxzIGVyc3RlcyBlaW5tYWwgYWJnZWZyYWd0CisgICAgLy8gd2VyZGVuLi4uCisgICAgICBvYi0+UXVlcnlQcm9wKFVfUkVRKTsKKyAgICAgIG9iLT5TZXRQcm9wKFVfUkVRLCB1X3JlcSk7CisgIH0KKworICBwbC0+QWRkTW9uZXkoLXZhbCk7CisgIF9hZGRfbW9uZXkodmFsKTsKKworICBpZiAob2ItPm1vdmUocGwsTV9HRVQpICE9IE1PVkVfT0spIC8vIEthbm4gZGVyIFNwaWVsZXIgZGFzIE9iamVrdCB0cmFnZW4/CisgIHsKKyAgICB3cml0ZShicmVha19zdHJpbmcoIkR1IGthbm5zdCAiK29iLT5uYW1lKFdFTiwxKSsiIG5pY2h0IG1laHIgdHJhZ2VuLiAiCisgICAgICJJY2ggbGVnZSAiK29iLT5RdWVyeVByb25vdW4oV0VOKSsiIGhpZXIgYXVmIGRlbiBCb2Rlbi4iLDc4LAorICAgICBOYW1lKFdFUikrIiBzYWd0OiAiKSk7CisgICAgb2ItPm1vdmUoTUUsTV9OT0NIRUNLKTsgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTmVpbiA6LSkKKyAgfQorICBlbHNlCisgIHsKKyAgICAvLyBGYWxscyBkYXMgT2JqZWt0IHNpY2ggdmVyZWluaWd0IGhhdCwgbXVzcyBqZXR6dCB3aWVkZXIgVV9SRVEKKyAgICAvLyByZXN0YXVyaWVydCB3ZXJkZW4uCisgICAgb2ItPlNldFByb3AoVV9SRVEsIHVfcmVxKTsKKyAgICB3cml0ZShicmVha19zdHJpbmcoIkR1IGthdWZzdCAiK29iLT5uYW1lKFdFTiwxKSsiLiIsIDc4KSk7CisgIH0KKworICBzYXkoYnJlYWtfc3RyaW5nKFBMLT5OYW1lKFdFUikrIiBrYXVmdCAiK29iLT5uYW1lKFdFTikrIi4iLDc4KSwgKHtQTH0pKTsKKyAgVXBkYXRlQ291bnRlcihvYiwtMSk7Cit9CisKK3N0YXRpYyB2b2lkIGFza19idXkoc3RyaW5nIHN0ciwgaW50IHZhbCwgb2JqZWN0IHBsLCBvYmplY3Qgb2IsIGludCB1X3JlcSkKK3sKKyAgX25vdGlmeV9mYWlsKGJyZWFrX3N0cmluZygiR3V0LCBEdSBrYW5uc3QgZXMgRGlyIGphIGplZGVyemVpdCAiCisgICAibm9jaCBhbmRlcnMgdWViZXJsZWdlbi4iLDc4LE5hbWUoV0VSKSsiIHNhZ3Q6ICIpKTsKKworICBpZighc3RyIHx8ICFzdHJpbmdwKHN0cikgfHwgc3RyID09ICJuZWluIiB8fCBzdHIgPT0gIm4iKQorICB7CisgICAgcmV0dXJuOworICB9CisgIGlmKHN0ciAhPSAiamEiICYmIHN0ciAhPSAiaiIpCisgIHsKKyAgICByZXR1cm47CisgIH0KKyAgcmVhbGx5X2J1eSh2YWwsIHBsLCBvYiwgdV9yZXEpOworfQorCitzdGF0aWMgaW50IGJ1eShzdHJpbmcgc3RyKQoreworICBpbnQgaSwgdmFsLCBwYXIsIGRleDsKKyAgbWl4ZWQgb2IsIHJlczsKKyAgc3RyaW5nIGR1bW15OworCisgIGlmICghc3RyKSB7CisgICAgd3JpdGUoIldhcyB3aWxsc3QgRHUga2F1ZmVuP1xuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBpZiAoc3RyaW5ncChRdWVyeVByb3AoUF9LRUVQRVIpKSAmJiAhcHJlc2VudChRdWVyeVByb3AoUF9LRUVQRVIpLCBNRSkpIHsKKyAgICB3cml0ZSgiRXMgaXN0IG5pZW1hbmQgZGEsIGRlciBEaWNoIGJlZGllbmVuIGtvZW5udGUuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIF9ub3RpZnlfZmFpbChicmVha19zdHJpbmcoIkRhcyBrYW5uIGljaCBpbiBtZWluZW0gTGFnZXIgbmljaHQgZmluZGVuLiIsNzgsCisgICBOYW1lKFdFUikrIiBzYWd0OiAiKSk7CisKKyAgLy8gVW0gYXVjaCBUZWlsZSB2b24gVW5pdC1TdGFja3Mga2F1ZmVuIHp1IGtvZW5uZW4sIHouQi4gImthdWZlIDUgcGhpb2xlbiIsCisgIC8vIGRhcmYgaGllciB6dXNhZXR6bGljaCA8ZHVtbXk+IG51ciBlaW4gTGVlcnN0cmluZyBzZWluLCBzb25zdCB2ZXJ6d2VpZ3QKKyAgLy8gZGllIFN5bnRheHBydWVmdW5nIGhpZXJoaW4gdW5kIGVzIHdpcmQgZGFzIDUuIEl0ZW0gZGVyIExpc3RlIGdla2F1ZnQuCisgIGlmIChzc2NhbmYoc3RyLCIlZCVzIixpLGR1bW15KT4wICYmIGk+MCAmJiAhc2l6ZW9mKGR1bW15KSkgeworICAgIG9iPUZpbmRJblN0b3JlKGkpOworICB9CisgIGVsc2Ugb2I9RmluZEluU3RvcmUoc3RyKTsKKworICBpZiAoIW9iKSByZXR1cm4gMDsKKworICBpZiAoc3RyID0gYnV5X29iaihvYiwwKSkgCisgIHsKKyAgICB3cml0ZShicmVha19zdHJpbmcoc3RyLDc4LE5hbWUoV0VSKSsiIHNhZ3Q6ICIpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIHZhbCA9IFF1ZXJ5QnV5VmFsdWUob2IsUEwpOworCisgIGlmIChQTC0+UXVlcnlNb25leSgpIDwgdmFsKQorICB7CisgICAgd3JpdGUoYnJlYWtfc3RyaW5nKGNhcGl0YWxpemUob2ItPlF1ZXJ5UHJvbm91bihXRVIpKSsiIHd1ZXJkZSAiK3ZhbCsKKyAgICAgIiBNdWVuemVuIGtvc3RlbiwgdW5kIER1IGhhc3QgbnVyICIrUEwtPlF1ZXJ5TW9uZXkoKSsiLiIsNzgsCisgICAgIE5hbWUoV0VSKSsiIGJlZGF1ZXJ0OiAiKSk7CisgICAgcmV0dXJuIDE7CisgIH0KKworICAvLyBBbnphaGwgZGVyIGFuZ2Vmb3JkZXJ0ZW4gRWluaGVpdGVuIHZvciBkZW0gQmV3ZWdlbiB6d2lzY2hlbnNwZWljaGVybi4KKyAgLy8gV2VpbCBkYWJlaSBpbSBGYWxsIHZvbiBVbml0cyBlaW5lIFZlcmVpbmlndW5nIG1pdCBiZXJlaXRzIGltIEludmVudGFyCisgIC8vIGJlZmluZGxpY2hlbiBFaW5oZWl0ZW4gc3RhdHRmaW5kZXQsIG11c3MgZGFzIGdnZi4gbmFjaCBCZXdlZ2VuCisgIC8vIHp1cnVlY2tnZXNldHp0IHdlcmRlbi4KKyAgaW50IHVfcmVxID0gb2ItPlF1ZXJ5UHJvcChVX1JFUSk7CisKKyAgaWYgKChyZXMgPSBvYi0+UXVlcnlQcm9wKFBfUkVTVFJJQ1RJT05TKSkgJiYgbWFwcGluZ3AocmVzKSAmJgorICAgICAgKHJlcyA9IGNhbGxfb3RoZXIoIi9zdGQvcmVzdHJpY3Rpb25fY2hlY2tlciIsCisgICAgICAgICAgICAgICAgICAgICAgICAiY2hlY2tfcmVzdHJpY3Rpb25zIixQTCxyZXMpKSAmJgorICAgICAgc3RyaW5ncChyZXMpKQorICB7CisgICAgX25vdGlmeV9mYWlsKGJyZWFrX3N0cmluZygiRHUga29lbm50ZXN0ICIrb2ItPm5hbWUoV0VOLDIpKyIgbmljaHQgIgorICAgICAidmVyd2VuZGVuLiBHcnVuZDogIityZXMrIk1vZWNodGVzdCBEdSAiK29iLT5RdWVyeVByb25vdW4oV0VOKSsKKyAgICAgIiBkZW5ub2NoIGthdWZlbj8iLDc4LE5hbWUoV0VSKSsiIHNhZ3Q6ICIpKTsKKworICAgIGlucHV0X3RvKCJhc2tfYnV5IixJTlBVVF9QUk9NUFQsICIoamEvbmVpbikgIiwgdmFsLFBMLG9iLHVfcmVxKTsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIHBhciA9IChpbnQpb2ItPlF1ZXJ5UHJvcChQX1BBUlJZKTsKKyAgZGV4ID0gKGludClQTC0+UXVlcnlBdHRyaWJ1dGUoQV9ERVgpOworCisgIGlmICgoKChwYXIgPCBQQVJSWV9PTkxZKSAmJiAoKGRleCArIDgpICogMTApIDwgb2ItPlF1ZXJ5UHJvcChQX1dDKSkgfHwKKyAgICAgICAoKHBhciA+IFBBUlJZX05PVCkgICYmICgoZGV4ICsgNSkgKiAgMikgPCBvYi0+UXVlcnlQcm9wKFBfQUMpKSkgJiYKKyAgICAgIFZBTElEX1dFQVBPTl9UWVBFKG9iKSkKKyAgeworICAgIF9ub3RpZnlfZmFpbChicmVha19zdHJpbmcoIkR1IGtvZW5udGVzdCAiK29iLT5uYW1lKFdFTiwyKSsiIG5pY2h0ICIKKyAgICAgInp1ZWNrZW4sIGRhIERlaW5lIEdlc2NoaWNrbGljaGtlaXQgZGFmdWVyIG5pY2h0IGF1c3JlaWNodC4gTW9lY2h0ZXN0ICIKKyAgICAgIkR1ICIrb2ItPlF1ZXJ5UHJvbm91bihXRU4pKyIgZGVubm9jaCBrYXVmZW4/Iiw3OCwKKyAgICAgTmFtZShXRVIpKyIgc2FndDogIikpOworCisgICAgaW5wdXRfdG8oImFza19idXkiLElOUFVUX1BST01QVCwgIihqYS9uZWluKSAiLCB2YWwsUEwsb2IsdV9yZXEpOworICAgIHJldHVybiAwOworICB9CisKKyAgcmVhbGx5X2J1eSh2YWwsIFBMLCBvYiwgdV9yZXEpOworCisgIHJldHVybiAxOworfQorCitwcml2YXRlIHZvaWQgZ2l2ZV9tb25leShpbnQgdmFsdWUpCisvLyBHZWxkIGd1dHNjaHJlaWJlbi4uLgoreworICBpZiAoIXZhbHVlKSByZXR1cm47CisgIHdyaXRlKGJyZWFrX3N0cmluZyhOYW1lKFdFUiwgMSkrIiB6YWhsdCBEaXIgIit2YWx1ZSsiIEdvbGRzdHVlY2siCisgICAgICAgICAgICAgICAgICAgICsodmFsdWU9PTE/Ii4iOiJlLiIpLCA3OCkpOworICBpZiAoKFBMLT5BZGRNb25leSh2YWx1ZSkpPD0wKSB7CisgICAgIG9iamVjdCBtb247CisKKyAgICAgd3JpdGUoIkR1IGthbm5zdCBkYXMgR2VsZCBuaWNodCBtZWhyIHRyYWdlbiFcbiIpOworICAgICBtb249Y2xvbmVfb2JqZWN0KEdFTEQpOworICAgICBtb24tPlNldFByb3AoUF9BTU9VTlQsdmFsdWUpOworICAgICBtb24tPm1vdmUoTUUsTV9NT1ZFX0FMTHxNX05PQ0hFQ0spOworICB9Cit9CisKK3N0YXRpYyBpbnQgbWFrZV90b19tb25leShvYmplY3Qgb2IsIGludCB2YWx1ZSkKKy8vIEludGVybmUgRnVua3Rpb24sIGRpZSBvYiB2ZXJzdWNodCBpbiBkYXMgTGFnZXIgenUgdWViZXJmdWVocmVuIHVuZCBkYXMKKy8vIEdlbGQgZGFzIGRhYmVpIGZ1ZXIgZGVuIFNwaWVsZXIgYWJmYWVsbHQgenVydWVja2xpZWZlcnQuCit7CisgIHN0cmluZyBzdHI7CisgIGludCByZXQ7CisKKyAgaWYgKCFvYmplY3RwKG9iKSB8fCBlbnZpcm9ubWVudChvYik9PWZpbmRfb2JqZWN0KHN0b3JhZ2UpKSB7CisgICAgd3JpdGUoYnJlYWtfc3RyaW5nKE5hbWUoV0VSLCAxKSsiIHd1bmRlcnQgc2ljaCB1ZWJlciBEaWNoLiIsIDc4KSk7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYgKHZhbHVlPlF1ZXJ5UHJvcChQX0NVUlJFTlRfTU9ORVkpKSB7CisgICAgd3JpdGUoYnJlYWtfc3RyaW5nKCJJY2ggaGFiIGRhcyBHZWxkIGxlaWRlciBuaWNodCBtZWhyLiIsIDc4LAorICAgICAgICAgICAgICAgICAgICAgICBOYW1lKFdFUiwgMSkrIiBzYWd0OiAiKSk7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgLy8gVV9SRVEgbWVya2VuLCBmYWxscyBzaWNoIE9iamVrdGUgdmVyZWluaWdlbi4gU29uc3Qgc3RpbW10IG5pY2h0IG51ciBkZXIKKyAgLy8gTmFtZSwgc29uZGVybiBlcyB3ZXJkZW4gZ2dmLiBhdWNoIGRpZSBmYWxzY2hlIEFuemFobCB6ZXJzdG9lcnQuCisgIC8vVE9PTzogT2RlciBVbml0cyBlbnRzb3JnZW4gdW5kIGFscyBGZWF0dXJlIGRla2xhcmllcmVuPworICBpbnQgcmVxID0gb2ItPlF1ZXJ5UHJvcChVX1JFUSk7CisgIGlmIChDaGVja0ZvckRlc3RydWN0KG9iKSA+IDApICAvLyBzb2xsIG9iIHplcnN0b2VydCB3ZXJkZW4/CisgIHsKKyAgICByZXQgPSBvYi0+bW92ZShzdG9yYWdlLE1fUFVUfE1fR0VUKTsKKyAgICAvLyBGYWxscyBkYXMgT2JqZWt0IHNpY2ggdmVyZWluaWd0IGhhdCAoVW5pdHMpLCBtdWVzc2VuIGRpZSBnZXd1ZW5zY2h0ZW4KKyAgICAvLyBFaW5oZWl0ZW4gcmVzdGF1cmllcnQgd2VyZGVuLgorICAgIC8vIFByb2JsZW06IGZhbGxzIGRhcyB2ZXJrYXVmdGUgT2JqZWt0IFVuaXRzIGhhdCwgYmVzY2hhZWRpZ3QgaXN0IHVuZCBzaWNoCisgICAgLy8gdmVyZWluaWd0IGhhdCwgc2luZCBqZXR6dCBsZWlkZXIgYWxsZSBFaW5oZWl0ZW4gaW0gTGFnZXIgYmVzY2hhZWRpZ3QuCisgICAgLy8gRGFzIGlzdCB1bnNjaG9lbiAtIGFiZXIgbWlyIGpldHp0IHp1dmllbCBBVWZ3YW5kLCBkYXMga29ycmVrdCB6dSBiYXVlbiwKKyAgICAvLyB3ZWlsIGVzIG51ciBzZWhyIHNlbHRlbiB2b3Jrb21tdC4gKEhpbnQ6IHNlcGFyYXRlciBNdWVsbHJhdW0pCisgICAgb2ItPlNldFByb3AoVV9SRVEsIHJlcSk7CisgICAgaWYgKHJldCA+IDApIC8vIFNvbnN0IHdlcmRlbiBhdWNoIFNhY2hlbiB6ZXJzdG9lcnQsIGRpZSBtYW4gbmljaHQKKyAgICB7ICAgICAgICAgICAgICAgICAvLyB3ZWdsZWdlbiBrYW5uCisgICAgICBzYXkoYnJlYWtfc3RyaW5nKFBMLT5OYW1lKCkrIiB2ZXJrYXVmdCAiK29iLT5uYW1lKFdFTikrIi4iLCA3OCkpOworICAgICAgaWYob2ItPlF1ZXJ5UHJvcChQX0RBTUFHRUQpKSAgLy8gQW5kZXJlIE1lbGR1bmcgYmVpIGJlc2NoYWVkaWd0ZW4KKyAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9iamVrdGVuIC4uLgorICAgICAgICB3cml0ZShicmVha19zdHJpbmcoTmFtZShXRVIsMSkrIiBmaW5kZXQgendhciBrZWluZW4gR2VmYWxsZW4gYW4gIgorICAgICAgICAgK29iLT5uYW1lKFdFTSwxKSsiLCBuaW1tdCAiK29iLT5RdWVyeVByb25vdW4oV0VOKSsiIERpciB6dWxpZWJlICIKKyAgICAgICAgICJhYmVyIHRyb3R6ZGVtLiIsNzgpKTsKKyAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgIHsKKyAgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKE5hbWUoV0VSLCAxKSsiIGZpbmRldCBHZWZhbGxlbiBhbiAiCisgICAgICAgICAgICtvYi0+bmFtZShXRU0sIDEpICsgIiB1bmQgbGVndCAiK29iLT5RdWVyeVByb25vdW4oV0VOKQorICAgICAgICAgICArIiB6dSAiKyhRdWVyeVByb3AoUF9HRU5ERVIpPT1GRU1BTEU/ImlocmVuIjoic2VpbmVuIikKKyAgICAgICAgICAgKyIgUHJpdmF0c2FjaGVuLiIsIDc4KSk7CisgICAgICB9CisgICAgICAvKiBFciB6YWhsdCBEaXIgIit2YWx1ZSsiIE11ZW56ZSIrKHZhbHVlPT0xPyIiOiJuIikrIiBkYWZ1ZXIuIiwgNzgpKTsgKi8KKyAgICAgIF9hZGRfbW9uZXkoLXZhbHVlKTsKKyAgICAgIF9hZGRfbW9uZXkodmFsdWUqUXVlcnlQcm9wKFBfU0hPUF9QRVJDRU5UX0xFRlQpLzEwMCk7IC8vIFdlZ2VuIFplcnN0b2VydW5nIGRlcyBPYmpla3RlcworICAgICAgVXBkYXRlQ291bnRlcihvYiwxKTsKKyAgICAgIG9iLT5yZW1vdmUoMSk7CisgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorICAgIGVsc2UgaWYgKHJldCA9PSBNRV9DQU5UX0JFX0RST1BQRUQpIHsKKyAgICAgIGlmICgoc3RyPW9iLT5RdWVyeVByb3AoUF9OT0RST1ApKSAmJiBzdHJpbmdwKHN0cikpIHsKKyAgICAgICAgd3JpdGUoc3RyKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgICB9CisgICAgICB3cml0ZShicmVha19zdHJpbmcoIkR1IGthbm5zdCAiK29iLT5uYW1lKFdFTiwxKSsiIG5pY2h0IHZlcmthdWZlbiEiLCA3OCkpOworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGVsc2UKKyAgICAgIHdyaXRlKGJyZWFrX3N0cmluZyhvYi0+TmFtZShXRVIpKyIgaW50ZXJlc3NpZXJ0IG1pY2ggbmljaHQuIiwgNzgsCisgICAgICAgICAgICAgICBOYW1lKFdFUiwgMSkrIiBzYWd0OiAiKSk7CisgIH0KKyAgZWxzZSBpZiAoKHJldD0ob2ItPm1vdmUoc3RvcmFnZSxNX1BVVHxNX0dFVCkpKT4wKQorICB7CisgICAgLy8gRmFsbHMgZGFzIE9iamVrdCBzaWNoIHZlcmVpbmlndCBoYXQgKFVuaXRzKSwgbXVlc3NlbiBkaWUgZ2V3dWVuc2NodGVuCisgICAgLy8gRWluaGVpdGVuIHJlc3RhdXJpZXJ0IHdlcmRlbi4KKyAgICBvYi0+U2V0UHJvcChVX1JFUSwgcmVxKTsKKyAgICBzYXkoYnJlYWtfc3RyaW5nKFBMLT5OYW1lKFdFUikrIiB2ZXJrYXVmdCAiK29iLT5uYW1lKFdFTikrIi4iLCA3OCkpOworICAgIF9hZGRfbW9uZXkoLXZhbHVlKTsKKyAgICBVcGRhdGVDb3VudGVyKG9iLDEpOworICAgIHJldHVybiB2YWx1ZTsKKyAgfQorICBlbHNlIGlmIChyZXQgPT0gTUVfQ0FOVF9CRV9EUk9QUEVEKSB7CisgICAgaWYgKChzdHI9b2ItPlF1ZXJ5UHJvcChQX05PRFJPUCkpICYmIHN0cmluZ3Aoc3RyKSkKKyAgICAgICB3cml0ZShzdHIpOworICAgIGVsc2Ugd3JpdGUoYnJlYWtfc3RyaW5nKCJEdSBrYW5uc3QgIitvYi0+bmFtZShXRU4sMSkrIiBuaWNodCB2ZXJrYXVmZW4hIiwgNzgpKTsKKyAgfQorICBlbHNlIHdyaXRlKGJyZWFrX3N0cmluZygiRHUga2FubnN0ICIrb2ItPm5hbWUoV0VOLDEpKyIgbmljaHQgdmVya2F1ZmVuISIsIDc4KSk7CisgIHJldHVybiAwOworfQorCitzdGF0aWMgdm9pZCBhc2tfc2VsbChzdHJpbmcgc3RyLCBvYmplY3Qgb2IsIGludCB2YWwsIGludCB1X3JlcSkKKy8vIFdlbm4gZWluIGVpbnplbG5lbiBTdHVlY2sgdW50ZXIgV2VydCB2ZXJrYXVmdCB3ZXJkZW4gc29sbCwgd2lyZCBuYWNoZ2VmcmFndAorLy8gdV9yZXEgaXN0IGJlaSBVbml0b2JqZWt0ZW4gZGllIEFuemFobCBhbiB6dSB2ZXJrYXVmZW5kZW4gRWluaGVpdGVuLiBCZWkKKy8vIG5vcm1hbGVuIE9iamVrdGVuIGlzdCB1X3JlcSAwLgoreworICBzdHI9bG93ZXJfY2FzZShzdHJ8fCIiKTsKKyAgaWYgKHN0cj09ImphInx8c3RyPT0iaiIpCisgIHsKKyAgICAgLy8gSW4gVW5pdG9iamVrdGVuIFVfUkVRICh3aWVkZXIpIHNldHplbi4KKyAgICAgaWYgKHVfcmVxPjApCisgICAgIHsKKyAgICAgICAvLyBEYXMgUXVlcnlQcm9wKCkgaXN0IG5pY2h0IHVubm9ldGlnLiBCZWkgZGVyIEFiZnJhZ2Ugdm9uIFVfUkVRIHdpcmQKKyAgICAgICAvLyBVX1JFUSBnZW51bGx0LCB3ZW5uIGRhcyBha3R1ZWxsZSBxdWVyeV92ZXJiKCkgIT0gZGVtIGxldHp0ZW4gaXN0LgorICAgICAgIC8vIEJlaSBkZXIgZXJzdGVuIEFiZnJhZ2Ugd3VlcmRlIGFscyBkYXMgaGllciBnZXNldHp0IFVfUkVRIHdpZWRlcgorICAgICAgIC8vIGdlbG9lc2NodC4gRGFoZXIgbXVzcyBkYXMgamV0enQgaGllciBhbHMgZXJzdGVzIGVpbm1hbCBhYmdlZnJhZ3QKKyAgICAgICAvLyB3ZXJkZW4uLi4KKyAgICAgICAgIG9iLT5RdWVyeVByb3AoVV9SRVEpOworICAgICAgICAgb2ItPlNldFByb3AoVV9SRVEsIHVfcmVxKTsKKyAgICAgfQorICAgICBnaXZlX21vbmV5KG1ha2VfdG9fbW9uZXkob2IsdmFsKSk7CisgIH0KKyAgZWxzZQorICAgICB3cml0ZShicmVha19zdHJpbmcoIk9rLCBkYW5uIGJlaGFsdHMhIiwgNzgsCisgICAgICAgICAgICAgTmFtZShXRVIsIDEpKyIgc2FndDogIikpOworfQorCitzdGF0aWMgc3RyaW5nIHNlbGxfb2JqKG9iamVjdCBvYiwgaW50IHNob3J0KQorLy8gSXN0IGRlciBIYWVuZGxlciBiZXJlaXQgb2IgenUga2F1ZmVuPyB3ZW5uIG5laW4sIFJ1ZWNrZ2FiZSBlaW5lciBNZWxkdW5nLAorLy8gZGllIGRlciBIYWVuZGxlciBzYWdlbiBzb2xsLgoreyAgbWl4ZWQgbm9zZWxsOworCisgICBpZiAoQkxVRV9OQU1FKG9iKT09R0VMRCkKKyAgICAgIHJldHVybiAiRGFzIHdhZXJlIGphIHdvaGwgVW5zaW5uLCBvZGVyIC4uLj8iOworICAgaWYgKG5vc2VsbD1vYi0+UXVlcnlQcm9wKFBfTk9TRUxMKSkKKyAgIHsKKyAgICAgaWYgKHN0cmluZ3Aobm9zZWxsKSkKKyAgICAgICByZXR1cm4gbm9zZWxsOworICAgICByZXR1cm4gKCJEdSBrYW5uc3QgIitvYi0+bmFtZShXRU4sMSkrIiBuaWNodCB2ZXJrYXVmZW4hIik7CisgICB9CisgICBpZiAob2ItPlF1ZXJ5UHJvcChQX0NVUlNFRCkpCisgICAgIHJldHVybiBvYi0+TmFtZShXRVIsMSkKKyAgICAgICAgICsiIGlzdCBtaXIgaXJnZW5kd2llIHVuZ2VoZXVlciEgRGFzIGthbm5zdCBEdSBuaWNodCB2ZXJrYXVmZW4hIjsKKyAgIC8vIG1hbiBzb2xsdGUga2VpbmUgQ09udGFpbmVyIG1pdCBJbmhhbHQgdmVya2F1ZmVuIGtvZW5uZW4sIGdnZi4ga2F1ZnQgc2llCisgICAvLyBkYW5uIGVpbiBhbmRlcmVyIFNwaWVsZXIuCisgICBpZiAoZmlyc3RfaW52ZW50b3J5KG9iKSkKKyAgIHsKKyAgICAgcmV0dXJuIG9iLT5OYW1lKFdFUiwgMSkgKyAiIGlzdCBuaWNodCBsZWVyISI7CisgICB9CisgICByZXR1cm4gMDsKK30KKworc3RhdGljIHZhcmFyZ3MgaW50IHNlbGwoc3RyaW5nIHN0ciwgaW50IGYpCit7CisgIGludCBpLCB2YWwsIG92YWwsIHRtcDsKKyAgb2JqZWN0ICpvYnM7CisKKyAgaWYgKHN0cmluZ3AoUXVlcnlQcm9wKFBfS0VFUEVSKSkgJiYgIXByZXNlbnQoUXVlcnlQcm9wKFBfS0VFUEVSKSxNRSkpIHsKKyAgICAgd3JpdGUoIkVzIGlzdCBuaWVtYW5kIGRhLCBkZXIgRGljaCBiZWRpZW5lbiBrb2VubnRlLlxuIik7CisgICAgIHJldHVybiAxOworICB9CisgIAorICBpZiAoIXN0cikgeworICAgICBub3RpZnlfZmFpbCgiV2FzIG1vZWNodGVzdCBEdSBkZW5uIHZlcmthdWZlbj9cbiIpOworICAgICByZXR1cm4gMDsKKyAgfQorICAKKyAgLyogRXJnZWJuaXMgdm9uIGZpbmRfb2JzKCkgc29sbHRlIHVuaWZpemllcnQgd2VyZGVuLCBkYW1pdCBlaW4gbWVocmZhY2gKKyAgICAgZ2VmdW5kZW5lcyBPYmpla3QgbmljaHQgbWVocmZhY2ggdmVyc3VjaHQgd2lyZCB6dSB2ZXJrYXVmZW4uCisgICAgIEJlaXNwaWVsOiBPYmpla3QgaGF0IFBfTk9CVVkgZ2VzZXR6dCB1bmQgbWVocmVyZSBJRHMgZ2VzZXR6dC4gV2VubgorICAgICBlaW4gU3BpZWxlciBlcyBtaXQgInZlcmthdWZlIElEMSB1bmQgSUQyIiB2ZXJzdWNodCB6dSB2ZXJrYXVmZW4sCisgICAgIHd1ZXJkZSBkYXMgZWluZW4gQnVnIGF1c2xvZXNlbi4gRGVyc2VsYmUgQnVnIGVudHN0ZWh0LCB3ZW5uIG1hbiBtaXQKKyAgICAgInZlcmthdWZlIElEMSB1bmQgSUQxIiB2ZXJrYXVmdC4gKi8KKyAgb2JzID0gUEwtPmZpbmRfb2JzKHN0ciwgUFVUX0dFVF9EUk9QKTsKKyAgLyogRXJzdCBpbSBJbnZlbnRhciBzY2hhdWVuLCBkYW5uIGltIEVudmlyb25tZW50LiBmaW5kX29icygpIG9obmUgMi4KKyAgICAgUGFyYW1ldGVyIG1hY2h0IGRhcyBzdGFuZGFyZG1hZXNzaWcgYW5kZXJzaGVydW0uCisgICAgIFRPRE86IEFlbmRlcnVuZyB1ZWJlcnBydWVmZW4sIHNvYmFsZCBkYXMgbmV1ZSBwdXRfYW5kX2dldC5jIAorICAgICBlaW5nZWJhdXQgd3VyZGUuICovCisgIGlmICggIXNpemVvZihvYnMpICkKKyAgICBvYnMgPSBQTC0+ZmluZF9vYnMoc3RyLCBQVVRfR0VUX1RBS0UpIHx8ICh7fSk7CisgIG9icyA9IG1faW5kaWNlcyhta21hcHBpbmcob2JzKSk7CisgIGlmICghaT1zaXplb2Yob2JzKSkgeworICAgICBub3RpZnlfZmFpbCgiV2FzIG1vZWNodGVzdCBEdSBkZW5uIHZlcmthdWZlbj9cbiIpOworICAgICByZXR1cm4gMDsKKyAgfQorICBjYWxsX290aGVyKHN0b3JhZ2UsICJfcmVnaXN0ZXJfc2hvcCIsIE1FKTsKKyAgaWYgKGk9PTEpIHsKKyAgICAgaWYgKHN0cj1zZWxsX29iaihvYnNbMF0sIDApKSB7CisgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZyhzdHIsIDc4LCBOYW1lKFdFUiwgMSkrIiBzYWd0OiAiKSk7CisgICAgICAgIHJldHVybiAxOworICAgICB9CisgICAgIGlmICgob3ZhbD1vYnNbMF0tPlF1ZXJ5UHJvcChQX1ZBTFVFKSk8PTApIHsKKyAgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKG9ic1swXS0+TmFtZShXRVIpCisgICAgICAgICAgICAgICsob2JzWzBdLT5RdWVyeVByb3AoUF9QTFVSQUwpID8gIiBoYWJlbiIgOiAiIGhhdCIpCisgICAgICAgICAgICAgICsiIGtlaW5lbiBtYXRlcmllbGxlbiBXZXJ0LCB0dXQgbWlyIGxlaWQuIiwgNzgsCisgICAgICAgICAgICAgIE5hbWUoV0VSLCAxKSsiIHNhZ3Q6ICIpKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgIH0KKyAgICAgdmFsPVF1ZXJ5U2VsbFZhbHVlKG9ic1swXSwgUEwpOworICAgICBpZiAoIXZhbCkgeworICAgICAgICB3cml0ZShicmVha19zdHJpbmcoIkljaCBiaW4gYWJzb2x1dCBwbGVpdGUuIFR1dCBtaXIgYXVmcmljaHRpZyBsZWlkLiIsCisgICAgICAgICAgICAgIDc4LCBOYW1lKFdFUiwgMSkrIiBzYWd0OiAiKSk7CisgICAgICAgIHJldHVybiAxOworICAgICB9CisgICAgIGlmICh2YWw9PW92YWwgfHwgZikgeworICAgICAgICBnaXZlX21vbmV5KG1ha2VfdG9fbW9uZXkob2JzWzBdLCB2YWwpKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgIH0KKyAgICAgaWYgKHN0cj1vYnNbMF0tPlF1ZXJ5UHJvcChQX05PRFJPUCkpIHsKKyAgICAgICAgaWYgKHN0cmluZ3Aoc3RyKSkKKyAgICAgICAgICAgd3JpdGUoc3RyKTsKKyAgICAgICAgZWxzZSB3cml0ZShicmVha19zdHJpbmcoIkR1IGthbm5zdCAiK29ic1swXS0+bmFtZShXRU4sMSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIiBuaWNodCB2ZXJrYXVmZW4hIiwgNzgpKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgIH0KKworICAgICBpZiAob2JzWzBdLT5RdWVyeVByb3AoUF9EQU1BR0VEKSkgIC8vIEJlaSBiZXNjaGFlZGlndGVuIE9iamVrdGVuIGdpYnQKKyAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlcyBhdWNoIGhpZXIgZWluZSBhbmRlcmUgTWVsZHVuZworICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygiRGEgIitvYnNbMF0tPm5hbWUoV0VSKSsiIGJlc2NoYWVkaWd0ICIKKyAgICAgICAgKyhvYnNbMF0tPlF1ZXJ5UHJvcChQX1BMVVJBTCk/InNpbmQiOiJpc3QiKSsiLCBrYW5uIGljaCBEaXIgIgorICAgICAgICAibnVyICIrdmFsKyIgTXVlbnplIisodmFsID09IDE/IiI6Im4iKSsiIGRhZnVlciBiaWV0ZW4uIFVuZCAiCisgICAgICAgICJkYW1pdCBtYWNoZSBpY2ggbm9jaCBWZXJsdXN0ISBOaW1tc3QgRHUgbWVpbiBBbmdlYm90IGFuPyAiCisgICAgICAgICIoamEvbmVpbikiLDc4LE5hbWUoV0VSLDEpKyIgc2FndDogIikpOworICAgICB9CisgICAgIGVsc2UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0CisgICAgIHsKKyAgICAgICB3cml0ZShicmVha19zdHJpbmcoTmFtZShXRVIsIDEpKyIgc2FndDogIgorICAgICAgICAgICsiTmFjaCBkZXIgYWt0dWVsbGVuIE1hcmt0bGFnZSBrYW5uIGljaCBEaXIgZGFmdWVyIG51ciAiCisgICAgICAgICAgK3ZhbCsiIE11ZW56ZSIrKHZhbD09MT8iIjoibiIpKyIgYmlldGVuLCBvYndvaGwgIgorICAgICAgICAgICtvYnNbMF0tPm5hbWUoV0VSKSsiIGVpZ2VudGxpY2ggIitvdmFsKyIgTXVlbnplIgorICAgICAgICAgICsob3ZhbD09MT8iIjoibiIpKyIgd2VydCB3YWVyZS4gV2lsbHN0IER1ICIKKyAgICAgICAgICArKFF1ZXJ5UHJvcChQX1BMVVJBTCkgPyAic2llIiA6ICJlcyIpCisgICAgICAgICAgKyIgbWlyIGRhZnVlciB1ZWJlcmxhc3Nlbj8iLCA3OCkpOworICAgICB9CisgICAgIC8vIGluIGFza19zZWxsKCkgZ2lidCBlcyBkYXMgcXVlcnlfdmVyYigpIG5pY2h0IG1laHIsIHdlc3dlZ2VuIFVfUkVRIGluCisgICAgIC8vIFVuaXRvYmpla3RlbiB6dXJ1ZWNrZ2VzZXR6dCB3aXJkLiBEYW1pdCBnZWh0IGRpZSBpbmZvIHZlcmxvcmVuLAorICAgICAvLyB3aWV2aWVsZSBPYmpla3RlIGRlciBTcGllbGVyIGFuZ2VnZWJlbiBoYXQuIERpZXNlIG11c3MgZ2VyZXR0ZXQgdW5kCisgICAgIC8vIHZpYSBhc2tfc2VsbCgpIGluIG1ha2VfdG9fbW9uZXkoKSBhbmtvbW1lbi4gSW4gbm9ybWFsZW4gT2JqZWt0ZW4gaXN0CisgICAgIC8vIFVfUkVRIDAuCisgICAgIGlucHV0X3RvKCJhc2tfc2VsbCIsSU5QVVRfUFJPTVBULCAiKGphL25laW4pICIsb2JzWzBdLCB2YWwsCisgICAgICAgICAgICAgIChvYnNbMF0pLT5RdWVyeVByb3AoVV9SRVEpICk7CisgICAgIHJldHVybiAxOworICB9CisgIGZvciAoLS1pOyBpPj0wICYmIGdldF9ldmFsX2Nvc3QoKT41MDAwMDsgaS0tKSB7CisgICAgIGlmIChvdmFsPW9ic1tpXS0+UXVlcnlQcm9wKFBfVkFMVUUpKSB7CisgICAgICAgIGlmIChvYnNbaV0tPlF1ZXJ5UHJvcChQX0tFRVBfT05fU0VMTCk9PWdldHVpZChQTCkKKyAgICAgICAgICAgIHx8IG9ic1tpXS0+UXVlcnlQcm9wKFBfV09STikgfHwgb2JzW2ldLT5RdWVyeVByb3AoUF9XSUVMREVEKSkKKyAgICAgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKG9ic1tpXS0+TmFtZShXRVIpKyI6IER1IGJlaGFlbHRzdCAiCisgICAgICAgICAgICAgICAgK29ic1tpXS0+bmFtZShXRU4pKyIuIiwgNzgpKTsKKyAgICAgICAgZWxzZSBpZiAoc3RyPXNlbGxfb2JqKG9ic1tpXSwgMSkpCisgICAgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZyhvYnNbaV0tPk5hbWUoV0VSKSsiOiAiK3N0ciwgNzgpKTsKKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgIHRtcD1RdWVyeVNlbGxWYWx1ZShvYnNbaV0sIFBMKTsKKyAgICAgICAgICAgaWYgKCF0bXApIHsKKyAgICAgICAgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKAorICAgICAgICAgICAgICAgICAgICAiSWNoIGJpbiBhYnNvbHV0IHBsZWl0ZS4gVHV0IG1pciBhdWZyaWNodGlnIGxlaWQuIiwgNzgsCisgICAgICAgICAgICAgICAgICAgIE5hbWUoV0VSLCAxKSsiIHNhZ3Q6ICIpKTsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgIH0KKyAgICAgICAgICAgZWxzZSBpZiAoIWYgJiYgdG1wKjEwPG92YWwpCisgICAgICAgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZyhvYnNbaV0tPk5hbWUoV0VSKSsiOiAiK05hbWUoV0VSLCAxKQorICAgICAgICAgICAgICAgICAgICArIiBiaWV0ZXQgRGlyIGFiZXIgbnVyICIrdG1wKyIgR29sZHN0dWVjayIKKyAgICAgICAgICAgICAgICAgICAgKyh0bXA+MSA/ICJlIiA6ICIiKSsiIGRhZnVlci4iLCA3OCkpOworICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgc3RyPShvYnNbaV0tPk5hbWUoV0VSKSk7CisgICAgICAgICAgICAgIGlmICh0bXA9bWFrZV90b19tb25leShvYnNbaV0sIHRtcCkpIHsKKyAgICAgICAgICAgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKHN0cisiOiAiK05hbWUoV0VSLCAxKQorICAgICAgICAgICAgICAgICAgICAgICsiIGdpYnQgRGlyIGRhZnVlciAiK3RtcCsiIEdvbGRzdHVlY2siCisgICAgICAgICAgICAgICAgICAgICAgKyh0bXA9PTE/Ii4iOiJlLiIpLCA3OCkpOworICAgICAgICAgICAgICAgICB2YWwrPXRtcDsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgfQorICB9CisgIGlmICghdmFsKQorICAgICB3cml0ZShicmVha19zdHJpbmcoIkhtbW0sIER1IGhhc3QgYWJlciBuaWNodCBiZXNvbmRlcnMgdmllbCB6dSBiaWV0ZW4uLi4iLAorICAgICAgICAgICAgICAgICAgICAgICAgNzgsIE5hbWUoV0VSKSsiIHNhZ3Q6ICIpKTsKKyAgZWxzZSBnaXZlX21vbmV5KHZhbCk7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IGZvcmNlX3NlbGwoc3RyaW5nIHN0cikKK3sgIHJldHVybiBzZWxsKHN0ciwgMSk7ICB9CisKK3N0YXRpYyBpbnQgZXZhbHVhdGUoc3RyaW5nIHN0cikKK3sKKyAgb2JqZWN0IG9iOworICBpbnQgdmFsLHJ2YWw7CisKKyAgaWYgKCFzdHIpIHJldHVybiAwOworICBpZihzdHJpbmdwKFF1ZXJ5UHJvcChQX0tFRVBFUikpICYmICFwcmVzZW50KFF1ZXJ5UHJvcChQX0tFRVBFUiksIE1FKSkgeworICAgIHdyaXRlKCJFcyBpc3QgbmllbWFuZCBkYSwgZGVyIERpY2ggYmVkaWVuZW4ga29lbm50ZS5cbiIpOworICAgIHJldHVybiAxOworICB9CisKKyAgb2I9cHJlc2VudChzdHIsIE1FKTsKKyAgaWYgKCFvYikgb2I9ZGVlcF9wcmVzZW50KHN0cixQTCk7CisgIGlmICghb2IpIHsKKyAgICB3cml0ZSgiSG0/ICIrY2FwaXRhbGl6ZShzdHIpKyI/IFdvdm9uIHJlZGVzdCBEdT9cbiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmIChsaXZpbmcob2IpKSB7CisgICAgX25vdGlmeV9mYWlsKCJOYW51LCBzZWl0IHdhbm4gd2VyZGVuIGhpZXIgTGViZXdlc2VuIHZlcmthdWZ0P1xuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYgKHN0cj1zZWxsX29iaihvYiwgMCkpIHsKKyAgICB3cml0ZShicmVha19zdHJpbmcoc3RyLCA3OCwgTmFtZShXRVIpKyIgc2FndDogIikpOworICAgIHJldHVybiAxOworICB9CisgIHJ2YWw9b2ItPlF1ZXJ5UHJvcChQX1ZBTFVFKTsKKyAgaWYgKHJ2YWwpIHsKKyAgICB2YWw9UXVlcnlTZWxsVmFsdWUob2IsIFBMKTsKKyAgICBpZiAocnZhbD09dmFsKSB7CisgICAgICB0ZWxsX29iamVjdCh0aGlzX3BsYXllcigpLGJyZWFrX3N0cmluZygKKyAgICAgICAgICJOYWphLCBpY2ggZGVua2UsICIgK3ZhbCsgIiBNdWVuemUiCisgICAgICAgICArICh2YWw9PTEgPyAiIiA6ICJuIikKKyAgICAgICAgICsgIiB3YWVyZSIrKG9iLT5RdWVyeVByb3AoUF9BTU9VTlQpPjE/Im4gIjoiICIpCisgICAgICAgICArIChvYi0+UXVlcnlQcm9ub3VuKFdFUikpKyIgc2Nob24gd2VydC5cbiIsNzgpKTsKKyAgICB9CisgICAgZWxzZSBpZiAodmFsKSB7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfcGxheWVyKCksYnJlYWtfc3RyaW5nKAorICAgICAgICAgICJPaCwgbmFjaCBkZXIgYWt0dWVsbGVuIE1hcmt0bGFnZSBrYW5uIGljaCBudXIgIit2YWwrIiBNdWVuemUiKworICAgICAgICAgICh2YWw9PTE/IiI6Im4iKSsiIGJlemFobGVuLCBvYndvaGwgIgorICAgICAgICAgICsgKFF1ZXJ5UHJvcChQX1BMVVJBTCkgPyAic2llIiA6ICJlcyIpCisgICAgICAgICAgKyAiIGVpZ2VudGxpY2ggIitydmFsCisgICAgICAgICAgKyAiIE11ZW56ZSIrKHJ2YWw9PTE/IiI6Im4iKSsiIHdlcnQgaXN0LlxuIiw3OCkpOworICAgIH0KKyAgICBlbHNlIHdyaXRlKCJJY2ggYmluIHZvbGxrb21tZW4gcGxlaXRlLiBUdXQgbWlyIGxlaWQuXG4iKTsKKyAgfQorICBlbHNlIHdyaXRlKCJEYXMgaXN0IHZvZWxsaWcgd2VydGxvcy5cbiIpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBzaG93X29iaihzdHJpbmcgc3RyKQoreworICBpbnQgaTsKKyAgc3RyaW5nIHdhczsKKyAgbWl4ZWQgb2I7CisKKyAgaWYgKCFzdHIpIHJldHVybiAwOworICBpZiAoc3NjYW5mKHN0ciwiJXMgaW0gbGFkZW4iLHdhcyk+MCB8fCBzc2NhbmYoc3RyLCIlcyBpbiBsYWRlbiIsd2FzKT4wKSB7CisgICAgX25vdGlmeV9mYWlsKCJEYXMga2FubiBpY2ggaW0gTGFnZXIgbmljaHQgZmluZGVuLlxuIik7CisgICAgb2I9RmluZEluU3RvcmUod2FzKTsKKyAgfSBlbHNlIGlmIChzc2NhbmYoc3RyLCIlZCIsaSk+MCAmJiBpPjApIHsKKyAgICBfbm90aWZ5X2ZhaWwoIkRhcyBrYW5uIGljaCBpbSBMYWdlciBuaWNodCBmaW5kZW4uXG4iKTsKKyAgICBvYj1GaW5kSW5TdG9yZShpKTsKKyAgfQorICBpZiAoIW9iKSByZXR1cm4gMDsKKyAgd3JpdGUob2ItPk5hbWUoV0VSKSsiOlxuIitvYi0+bG9uZygpK2NhcGl0YWxpemUob2ItPlF1ZXJ5UHJvbm91bigpKQorICAgICAgICsiIGtvc3RldCAiK1F1ZXJ5QnV5VmFsdWUob2IsUEwpKyIgTXVlbnplbi5cbiIpOworICByZXR1cm4gMTsKK30KKworLy8gYmVudXR6dCB2b24gdHJhZGluZ19wcmljZTo6UXVlcnlWYWx1ZShvYmplY3QsIGludCwgb2JqZWN0KQorc3RhdGljIGludCBPYmplY3RDb3VudChvYmplY3Qgb2IpCit7CisgIHN0cmluZyB0bXA7CisKKyAgaWYgKCFvYmplY3RwKG9iKSkgcmV0dXJuIDA7CisgIHRtcCA9IEJMVUVfTkFNRShvYik7CisgIGlmICh0bXBbMC4uMl0hPSIvZC8iICYmIHRtcFswLi44XSE9Ii9wbGF5ZXJzLyIpIHRtcD1vYi0+c2hvcnQoKSt0bXA7CisgIHJldHVybiBvYl9hbnpbdG1wXTsKK30KKworLy8gYmVudXR6dCB2b24gdHJhZGluZ19wcmljZTo6UXVlcnlTZWxsVmFsdWUob2JqZWN0LCBvYmplY3QpCitzdGF0aWMgdmFyYXJncyBpbnQgUXVlcnlWYWx1ZShvYmplY3Qgb2IsIGludCB2YWx1ZSwgb2JqZWN0IGNsaWVudCkKK3sKKyAgaW50IG5ld192YWx1ZSwgbXltb25leTsKKworICBpZiAoIW9iamVjdHAob2IpKSByZXR1cm4gMDsKKyAgaWYgKFF1ZXJ5KCJsYWRlbjo6Y29tcGF0IikpIHsKKyAgICBuZXdfdmFsdWU9KHZhbHVlPjEwMDA/MTAwMDp2YWx1ZSk7CisgICAgbXltb25leSA9IFF1ZXJ5UHJvcChQX0NVUlJFTlRfTU9ORVkpOworICAgIGlmIChuZXdfdmFsdWU+bXltb25leSkKKyAgICAgIHJldHVybiAobXltb25leT4wP215bW9uZXk6MCk7CisgICAgZWxzZSByZXR1cm4gbmV3X3ZhbHVlOworICB9CisgIHJldHVybiA6OlF1ZXJ5VmFsdWUob2IsIHZhbHVlLCBjbGllbnQpOworfQorCit2b2lkIHJlc2V0KCkKK3sKKyAgbWl4ZWQgKmtleXM7CisgIGludCBpOworCisgIHRyYWRpbmdfcHJpY2U6OnJlc2V0KCk7CisKKyAgaWYgKCFtYXBwaW5ncChvYl9hbnopKQorICAgIHJldHVybjsKKyAga2V5cz1tX2luZGljZXMob2JfYW56KTsKKyAgZm9yIChpPXNpemVvZihrZXlzKS0xO2k+PTA7aS0tKSB7CisgICAgb2JfYW56W2tleXNbaV1dPW9iX2FueltrZXlzW2ldXSo3Lzg7CisgICAgaWYgKCFvYl9hbnpba2V5c1tpXV0pCisgICAgICAgbV9kZWxldGUob2JfYW56LGtleXNbaV0pOworICB9Cit9CisKK3ZhcmFyZ3MgaW50IENoZWNrRmluZFJlc3RyaWN0aW9ucyhvYmplY3Qgb2IsIG1peGVkIHJlc3RyLCBjbG9zdXJlIHFwKSB7CisgIHJldHVybiAwOworfQorCitpbnQgRXZhbFdlYXBvbihvYmplY3Qgb2IsIGNsb3N1cmUgcXApIHsKKyAgaW50IHdjLHZhbDsKKworICB3Yz1mdW5jYWxsKHFwLFBfV0MpOworICB2YWw9ZnVuY2FsbChxcCxQX0VGRkVDVElWRV9XQyk7CisgIGlmICh2YWw+d2MpIHdjPXZhbDsKKyAgcmV0dXJuIHdjOworfQorCit2YXJhcmdzIG9iamVjdCBGaW5kQmVzdFdlYXBvbihtaXhlZCB0eXBlLCBpbnQgbWF4bW9uLCBpbnQgbWF4dywgaW50IGhhbmRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJlc3R3YywgbWl4ZWQgcmVzdHIpIHsKKyAgb2JqZWN0IGJlc3RvYixvYjsKKyAgc3RyaW5nIG90eXBlOworICBpbnQgd2MsYmVzdHZhbCx2YWwsdyxiZXN0dzsKKyAgY2xvc3VyZSBxcDsKKworICBpZiAoIXN0cmluZ3Aoc3RvcmFnZSkgfHwgIW9iamVjdHAob2I9ZmluZF9vYmplY3Qoc3RvcmFnZSkpKSByZXR1cm4gMDsKKyAgaWYgKCFtYXhtb24pIG1heG1vbj0xMDAwMDA7CisgIGlmICghbWF4dykgbWF4dz03NTAwMDsKKyAgaWYgKCFoYW5kcykgaGFuZHM9MjsKKyAgaWYgKHZhbD1RdWVyeUJ1eUZhY3QoKSkgbWF4bW9uPShtYXhtb24qMTAwKS92YWw7CisgIGlmICh0eXBlICYmICFwb2ludGVycCh0eXBlKSAmJiAhbWFwcGluZ3AodHlwZSkpIHR5cGU9KHt0eXBlfSk7CisKKyAgZm9yIChvYj1maXJzdF9pbnZlbnRvcnkob2IpO29iO29iPW5leHRfaW52ZW50b3J5KG9iKSkgeworICAgIHFwPXN5bWJvbF9mdW5jdGlvbigiUXVlcnlQcm9wIixvYik7CisgICAgaWYgKCFvdHlwZT1mdW5jYWxsKHFwLFBfV0VBUE9OX1RZUEUpKSBjb250aW51ZTsKKyAgICBpZiAodHlwZSAmJiBtZW1iZXIodHlwZSxvdHlwZSk8MCkgY29udGludWU7CisgICAgd2M9RXZhbFdlYXBvbihvYixxcCk7CisgICAgaWYgKHdjPGJlc3R3YykgY29udGludWU7CisgICAgaWYgKGZ1bmNhbGwocXAsUF9OUl9IQU5EUyk+aGFuZHMpIGNvbnRpbnVlOworICAgIHc9ZnVuY2FsbChxcCxQX1dFSUdIVCk7CisgICAgaWYgKHc+bWF4dykgY29udGludWU7CisgICAgdmFsPWZ1bmNhbGwocXAsUF9WQUxVRSk7CisgICAgaWYgKHZhbD5tYXhtb24pIGNvbnRpbnVlOworICAgIGlmIChiZXN0b2IgJiYgd2M8PWJlc3R3YykgeworICAgICAgaWYgKHZhbD5iZXN0dmFsKSBjb250aW51ZTsKKyAgICAgIGVsc2UgaWYgKHZhbD09YmVzdHZhbCAmJiB3PmJlc3R3KSBjb250aW51ZTsKKyAgICB9CisgICAgaWYgKHZhbD5iZXN0dmFsICYmIGJlc3RvYiAmJiB3Yzw9YmVzdHdjKSBjb250aW51ZTsKKyAgICBpZiAoQ2hlY2tGaW5kUmVzdHJpY3Rpb25zKG9iLHJlc3RyLHFwKSkgY29udGludWU7CisgICAgYmVzdG9iPW9iOworICAgIGJlc3R3Yz13YzsKKyAgICBiZXN0dmFsPXZhbDsKKyAgICBiZXN0dz13OworICB9CisgIHJldHVybiBiZXN0b2I7Cit9CisKK2ludCBFdmFsQXJtb3VyKG9iamVjdCBvYixjbG9zdXJlIHFwKSB7CisgIGludCBhYyx2YWw7CisKKyAgYWM9ZnVuY2FsbChxcCxQX0FDKTsKKyAgdmFsPWZ1bmNhbGwocXAsUF9FRkZFQ1RJVkVfQUMpOworICBpZiAodmFsPmFjKSBhYz12YWw7CisgIHJldHVybiBhYzsKK30KKwordmFyYXJncyBtYXBwaW5nIEZpbmRCZXN0QXJtb3Vyc1QobWl4ZWQgdHlwZSwgaW50IG1heG1vbiwgaW50IG1heHcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXBwaW5nIGJlc3RhYywgbWl4ZWQgcmVzdHIpIHsKKyAgb2JqZWN0IG9iOworICBzdHJpbmcgb3R5cGU7CisgIGludCBhYyx2YWwsc3VtLHcsd3N1bTsKKyAgbWFwcGluZyBiZXN0b2IsYmVzdHZhbCxiZXN0dzsKKyAgY2xvc3VyZSBxcDsKKworICBpZiAoIXN0cmluZ3Aoc3RvcmFnZSkgfHwgIW9iamVjdHAob2I9ZmluZF9vYmplY3Qoc3RvcmFnZSkpKSByZXR1cm4gKFtdKTsKKyAgaWYgKCFtYXhtb24pIG1heG1vbj0xMDAwMDA7CisgIGlmICghbWF4dykgbWF4dz03NTAwMDsKKyAgaWYgKHZhbD1RdWVyeUJ1eUZhY3QoKSkgbWF4bW9uPShtYXhtb24qMTAwKS92YWw7CisgIGlmICh0eXBlICYmICFwb2ludGVycCh0eXBlKSAmJiAhbWFwcGluZ3AodHlwZSkpIHR5cGU9KHt0eXBlfSk7CisgIGlmICghbWFwcGluZ3AoYmVzdGFjKSkgYmVzdGFjPShbXSk7CisgIGJlc3RvYj0oW10pO2Jlc3R2YWw9KFtdKTtiZXN0dz0oW10pOworCisgIGZvciAob2I9Zmlyc3RfaW52ZW50b3J5KG9iKTtvYjtvYj1uZXh0X2ludmVudG9yeShvYikpIHsKKyAgICBxcD1zeW1ib2xfZnVuY3Rpb24oIlF1ZXJ5UHJvcCIsb2IpOworICAgIGlmICghb3R5cGU9ZnVuY2FsbChxcCxQX0FSTU9VUl9UWVBFKSkgY29udGludWU7CisgICAgaWYgKHR5cGUgJiYgbWVtYmVyKHR5cGUsb3R5cGUpPDApIGNvbnRpbnVlOworICAgIGFjPUV2YWxBcm1vdXIob2IscXApOworICAgIGlmIChhYzxiZXN0YWNbb3R5cGVdKSBjb250aW51ZTsKKyAgICB3PWZ1bmNhbGwocXAsUF9XRUlHSFQpOworICAgIGlmICh3c3VtLWJlc3R3W290eXBlXSt3Pm1heHcpIGNvbnRpbnVlOworICAgIHZhbD1mdW5jYWxsKHFwLFBfVkFMVUUpOworICAgIGlmIChzdW0tYmVzdHZhbFtvdHlwZV0rdmFsPm1heG1vbikgY29udGludWU7CisgICAgaWYgKGJlc3RvYltvdHlwZV0gJiYgYWM8PWJlc3RhY1tvdHlwZV0pIHsKKyAgICAgIGlmICh2YWw+YmVzdHZhbFtvdHlwZV0pIGNvbnRpbnVlOworICAgICAgZWxzZSBpZiAodmFsPT1iZXN0dmFsW290eXBlXSAmJiB3PmJlc3R3W290eXBlXSkgY29udGludWU7CisgICAgfQorICAgIGlmIChDaGVja0ZpbmRSZXN0cmljdGlvbnMob2IscmVzdHIscXApKSBjb250aW51ZTsKKyAgICBzdW09c3VtLWJlc3R2YWxbb3R5cGVdK3ZhbDsKKyAgICB3c3VtPXdzdW0tYmVzdHdbb3R5cGVdK3c7CisgICAgYmVzdG9iW290eXBlXT1vYjsKKyAgICBiZXN0YWNbb3R5cGVdPWFjOworICAgIGJlc3R2YWxbb3R5cGVdPXZhbDsKKyAgICBiZXN0d1tvdHlwZV09dzsKKyAgfQorICByZXR1cm4gYmVzdG9iOworfQorCit2YXJhcmdzIG9iamVjdCAqRmluZEJlc3RBcm1vdXJzKG1peGVkIHR5cGUsIGludCBtYXhtb24sIGludCBtYXh3LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwcGluZyBiZXN0YWMsIG1peGVkIHJlc3RyKSB7CisgIHJldHVybiBtX3ZhbHVlcyhGaW5kQmVzdEFybW91cnNUKHR5cGUsbWF4bW9uLG1heHcsYmVzdGFjLHJlc3RyKSk7Cit9Cg==