Ly8gTW9yZ2VuR3JhdWVuIE1VRGxpYgovLwovLyB0aGluZy9jb21tYW5kcy5jIC0tIHRoaW5nIGRlc2NyaXB0aW9uCi8vCi8vICRJZDogY29tbWFuZHMuYyA5NTE0IDIwMTYtMDItMjMgMjA6MzM6MDlaIEdsb2luc29uICQKLy8KLy8gQXVzIFJlZ2VuYm9nZW4gTVVETGliCi8vIGF1cyBHdWVsZGVubGFuZC9XdW5kZXJsYW5kIE1VRGxpYiAoTW9yZ2VuZ3JhdWVuIE1VRGxpYikKLy8KLy8gUF9DT01NQU5EUyBkYXRhLXN0cnVjdHVyZToKLy8KLy8gQWRkQ21kKHZlcmIsZnVuMSwxKTsKLy8gQWRkQ21kKHZlcmIrc3luMWF8c3luMWImc3luMmF8c3luMmJ8c3luMmMsZnVuMiwKLy8gICAgICAgIGVycm9yMV9ub3RpZnl8ZXJyb3IyX25vdGlmeV5lcnJvcjJfd3JpdGUpOwovLyAtLT4KLy8gKFt2ZXJiOgovLyAgICAoe2Z1bjEsZnVuMn0pOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmdW5zCi8vICAgICh7MSwoe2Vycm9yMV9ub3RpZnksIGVycm9yMl93cml0ZV5lcnJvcjJfc2F5LCAxfSl9KTsgIC8vIGZsYWdzCi8vICAgICh7MCwoeyh7c3luMWEsc3luMWJ9KSwoe3N5bjJhLHN5bjJiLHN5bjJjfSl9KX0pOyAgICAgIC8vIHJ1bGVzCi8vICAgIDA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElEcwovLyAgICAoe2Nsb3N1cmUgYXVmIGZ1bjEsIGNsb3N1cmUgYXVmIGZ1bjJ9KSBdKSAgICAgICAgICAgICAvLyBDYWNoZQovLwovLyBGdW5zOiAgKHs8ZnVuMT4gLC4uLgovLyAgICAgICAgICAnZnVuJyBrYW5uIHNlaW46IENsb3N1cmUKLy8gICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc6IE1ldGhvZGVubmFtZSAtIHdpcmQgZXR3YXMgZ2VwcnVlZnQKLy8gICAgICAgICAgICAgICAgICAgICAgICAgICBPYmpla3Q6IHdlbm4ga2VpbmUgTWV0aG9kZSwgdGhpc19vYmplY3QoKSBmdWVyCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcm4sIHByZXZpb3VzX29iamVjdCgpIGZ1ZXIgZXh0ZXJuCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAoZXJsb3NjaGVuZXMgZXh0ZXJuZXMgT2JqZWt0KQovLyBSdWxlczogKHs8UmVnZWxzYXR6IGZ1ZXIgZnVuMT4sICh7PDEuIFN5bm9ueW1ncnVwcGU+LAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDIuIFN5bm9ueW1ncnVwcGUsIC4uLn0pLCAuLi59KQovLyBGbGFnczogKHs8RmxhZyBmdWVyIGZ1bjE+LCAoezxGZWhsZXJtZWxkdW5nIDEuIFN5bm9ueW1ncnVwcGU+LCAuLi4gLAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFssIEluZGV4IGZ1ZXIgd3JpdGUgYW5zdGF0dCBub3RpZnlfZmFpbF19KSwKLy8gICAgICAgICAgICAuLi4gfSkKLy8gSURzOiAgIDAgb2RlciAoezxJRCBmdWVyIGZ1bjE+fSkgb2RlciAoezAsIDxJRCBmdWVyIGZ1bjI+fSkgLi4uCi8vIENhY2hlOiAoezxjbG9zdXJlIGZ1ZXIgZnVuMT4sIC4uLgovLyAgICAgICAgQ2FjaGUtQ2xvc3VyZXMgc2luZCBiZWkgRXhwb3J0IChRdWVyeVByb3ApIGltbWVyIGdlbnVsbHQKI3ByYWdtYSBzdHJpY3RfdHlwZXMKI3ByYWdtYSBzYXZlX3R5cGVzCiNwcmFnbWEgcmFuZ2VfY2hlY2sKI3ByYWdtYSBub19jbG9uZQojcHJhZ21hIHBlZGFudGljCgojaW5jbHVkZSA8bW92aW5nLmg+CiNpbmNsdWRlIDx0aGluZy9sYW5ndWFnZS5oPgojaW5jbHVkZSA8ZXhwbG9yYXRpb24uaD4KI2luY2x1ZGUgPGRlZmluZXMuaD4KI2luY2x1ZGUgPGxpdmluZy9jb21tLmg+CiNpbmNsdWRlIDxmdW5jdGlvbmxpc3QuaD4KCiNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCiNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CiNpbmNsdWRlIDx0aGluZy9kZXNjcmlwdGlvbi5oPgojaW5jbHVkZSA8dGhpbmcvY29tbWFuZHMuaD4KI3VuZGVmIE5FRURfUFJPVE9UWVBFUwoKI2RlZmluZSBDTURTX1dJRFRIIDUKLy8gTWFwcGluZy1JbmRpemVzCiNkZWZpbmUgQ01ESURYX0ZVTiAgIDAKI2RlZmluZSBDTURJRFhfRkxBRyAgMQojZGVmaW5lIENNRElEWF9SVUxFICAyCiNkZWZpbmUgQ01ESURYX0lEICAgIDMKI2RlZmluZSBDTURJRFhfQ0FDSEUgNAoKI2lmZGVmIERCRwojdW5kZWYgREJHCiNlbmRpZgojZGVmaW5lIERCRyh4KSBwcmludGYoIk9iamVjdCAlTyB0bXBzdHI9JXNcbiIsIGV4cGxvZGUob2JqZWN0X25hbWUodGhpc19vYmplY3QoKSksIiMiKVsxXSwgeCk7Cgpwcml2YXRlIG5vc2F2ZSBtYXBwaW5nIGFkZGVkX2NtZHM7Cgpwcm90ZWN0ZWQgaW50IF9jbWRfc3ludGF4aGVscChzdHJpbmcgc3RyLCBtaXhlZCAqYXJncykKewogIG1hcHBpbmd8Y2xvc3VyZSByZXN0cjsKICBtaXhlZCBoZWxwID0gUXVlcnlQcm9wKFBfU1lOVEFYX0hFTFApOwogIGlmIChwb2ludGVycChoZWxwKSkKICB7CiAgICByZXN0ciA9IGhlbHBbMV07CiAgICBoZWxwID0gaGVscFswXTsKICB9CiAgLy8gUmVzdHJpa3Rpb25lbiB2b3IgZGVtIEFuemVpZ2VuIHBydWVmZW4uCiAgaWYgKG1hcHBpbmdwKHJlc3RyKSkKICB7CiAgICBzdHJpbmcgcmVzID0gIi9zdGQvcmVzdHJpY3Rpb25fY2hlY2tlciItPmNoZWNrX3Jlc3RyaWN0aW9ucyhQTCxyZXN0cik7CiAgICBpZiAocmVzKQogICAgewogICAgICBQTC0+UmVjZWl2ZU1zZygiRnVlciAiICsgbmFtZShXRU4sMSkgKyAiIGRhcmZzdCBEdSAiCiAgICAgICAgICAgICAgICAgICAgICJkaWUgU3ludGF4aGlsZmUgKG5vY2gpIG5pY2h0IGxlc2VuOlxuIgogICAgICAgICAgICAgICAgICAgICArIHJlcywKICAgICAgICAgICAgICAgICAgICAgTVRfTk9USUZJQ0FUSU9OfE1TR19CU19MRUFWRV9MRlMsCiAgICAgICAgICAgICAgICAgICAgICJzeW50YXhoaWxmZSIsMCx0aGlzX29iamVjdCgpKTsKICAgICAgcmV0dXJuIDE7CiAgICB9CiAgfQogIGVsc2UgaWYgKGNsb3N1cmVwKHJlc3RyKSkKICB7CiAgICBzdHJpbmcgcmVzID0gZnVuY2FsbChyZXN0ciwgTUUpOwogICAgaWYgKHJlcykKICAgIHsKICAgICAgaWYgKGludHAocmVzKSkKICAgICAgICBQTC0+UmVjZWl2ZU1zZygiRnVlciAiICsgbmFtZShXRU4sMSkgKyAiIGRhcmZzdCBEdSAiCiAgICAgICAgICAgICAgICAgICAgICAgImRpZSBTeW50YXhoaWxmZSAobm9jaCkgbmljaHQgbGVzZW4uIiwKICAgICAgICAgICAgICAgICAgICAgICBNVF9OT1RJRklDQVRJT058TVNHX0JTX0xFQVZFX0xGUywKICAgICAgICAgICAgICAgICAgICAgICAic3ludGF4aGlsZmUiLDAsdGhpc19vYmplY3QoKSk7CiAgICAgIGVsc2UgaWYgKHN0cmluZ3AocmVzKSkKICAgICAgICBQTC0+UmVjZWl2ZU1zZyhyZXMsCiAgICAgICAgICAgICAgICAgICAgICAgTVRfTk9USUZJQ0FUSU9OfE1TR19CU19MRUFWRV9MRlMsCiAgICAgICAgICAgICAgICAgICAgICAgInN5bnRheGhpbGZlIiwwLHRoaXNfb2JqZWN0KCkpOwogICAgICByZXR1cm4gMTsKICAgIH0KICB9CgogIGlmIChzdHJpbmdwKGhlbHApKQogIHsKICAgIGhlbHAgPSAiRnVlciAiICsgbmFtZShXRU4sMSkgKyAiIGdpYnQgZXMgZm9sZ2VuZGUgU3ludGF4aGlsZmU6XG4iCiAgICAgICAgICAgKyBoZWxwOwogIH0KICBlbHNlIGlmIChjbG9zdXJlcChoZWxwKSkKICB7CiAgICBoZWxwID0gZnVuY2FsbChoZWxwLCB0aGlzX29iamVjdCgpKTsKICB9CiAgZWxzZQogIHsKICAgIC8vIHdlbm4gZGFzIE9iamVrdCBrZWluZSBTeW50YXhoaWxmZSBoYXQsIGJyYXVjaHQgZXMgZGFzIEtvbW1hbmRvIGF1Y2gKICAgIC8vIG5pY2h0LgogICAgbm90aWZ5X2ZhaWwoIkZ1ZXIgIiArIG5hbWUoV0VOLDEpCiAgICAgICAgICAgICAgICArICIgZ2lidCBlcyBrZWluZSBTeW50YXhoaWxmZS5cbiIpOwogICAgUmVtb3ZlQ21kKDAsMCwgIl9jbWRfc3ludGF4aGVscCIpOwogICAgcmV0dXJuIDA7CiAgfQogIGlmIChzdHJpbmdwKGhlbHApICYmIHNpemVvZihoZWxwKSkKICAgIFBMLT5SZWNlaXZlTXNnKGhlbHAsIE1UX05PVElGSUNBVElPTnxNU0dfQlNfTEVBVkVfTEZTLAogICAgICAgICAgICAgICAgICAgInN5bnRheGhpbGZlIiwwLHRoaXNfb2JqZWN0KCkpOwoKICByZXR1cm4gMTsKfQoKcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKewogIEFkZENtZCgic3ludGF4aGlsZmUmQElEIiwgIydfY21kX3N5bnRheGhlbHAsCiAgICAgICAgICJGdWVyIFdBUyBtb2VjaHRlc3QgRHUgZWluZSBTeW50YXhoaWxmZT9cbiIsCiAgICAgICAgICJfY21kX3N5bnRheGhlbHAiKTsKfQoKcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgewogIHNldF9uZXh0X3Jlc2V0KC0xKTsKfQoKcHJpdmF0ZSBjbG9zdXJlIF9jaGVja19zdHJpbmdtZXRob2QobWl4ZWQgZnVuYywgaW50IGV4LCBzdHJpbmcgcmVzcCkgewogIGNsb3N1cmUgY2w7CiAgaWYoIWZ1bmN0aW9uX2V4aXN0cyhmdW5jKSkKICAgIGNhdGNoKHJhaXNlX2Vycm9yKHNwcmludGYoCiAgICAgIHJlc3ArInN0cmluZy1NZXRob2RlICclcycgZmVobHQgb2RlciBpc3QgcHJpdmF0ZS5cbiIsIGZ1bmMpKTsKICAgICAgcHVibGlzaCk7CgogIC8vIGV4dGVybiBlcnN0ZWxsdGUgYXVmIFNpY2h0YmFya2VpdCBwcnVlZmVuIHVuZCBhYmJyZWNoZW4vZGF2b3Igd2FybmVuCiAgaWYoZXgpIHsKICAgIG1peGVkICpmbCA9IGZ1bmN0aW9ubGlzdCh0aGlzX29iamVjdCgpLCBSRVRVUk5fRlVOQ1RJT05fTkFNRXwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRVRVUk5fRlVOQ1RJT05fRkxBR1MpOwogICAgaW50IGluZGV4ID0gbWVtYmVyKGZsLCBmdW5jKSsxOwogICAgaWYoaW5kZXg8PTAgfHwgc2l6ZW9mKGZsKTw9aW5kZXgpCiAgICAgIGNhdGNoKHJhaXNlX2Vycm9yKHNwcmludGYoCiAgICAgICAgcmVzcCsic3RyaW5nLU1ldGhvZGUgJyVzJyBuaWNodCBpbiBmdW5jdGlvbmxpc3QuXG4iLCBmdW5jKSk7CiAgICAgICAgcHVibGlzaCk7CiAgICBlbHNlIGlmKGZsW2luZGV4XSZUWVBFX01PRF9QUk9URUNURUQgfHwgZmxbaW5kZXhdJlRZUEVfTU9EX1NUQVRJQykKICAgICAgY2F0Y2gocmFpc2VfZXJyb3Ioc3ByaW50ZigKICAgICAgICByZXNwKyJzdHJpbmctTWV0aG9kZSAnJXMnIGlzdCBwcm90ZWN0ZWQvc3RhdGljLiBFeHRlcm4gIgogICAgICAgICJkZWZpbmllcnRlcyBLb21tYW5kbyBkYXJmIHNvIGVpbmUgTWV0aG9kZSBuaWNodCBhdWZydWZlbiFcbiIsCiAgICAgICAgZnVuYykpOwogICAgICAgIHB1Ymxpc2gpOwogIH0KCiAgLy8gYW5zb25zdGVuIE1ldGhvZGUgZXJzdG1hbCBjYWNoZW4KICBjbCA9IHN5bWJvbF9mdW5jdGlvbihmdW5jLCB0aGlzX29iamVjdCgpKTsKICBpZighY2wpCiAgICBjYXRjaChyYWlzZV9lcnJvcihzcHJpbnRmKAogICAgICByZXNwKyJzdHJpbmctTWV0aG9kZSAnJXMnIG5pY2h0IGluIENsb3N1cmUgd2FuZGVsYmFyP1xuIiwgZnVuYykpOwogICAgICBwdWJsaXNoKTsKCiAgcmV0dXJuIGNsOwp9Cgp2YXJhcmdzIHZvaWQgQWRkQ21kKG1peGVkIGNtZCwgbWl4ZWQgZnVuYywgbWl4ZWQgZmxhZywgbWl4ZWQgY21kaWQpIHsKIGludCBpLGo7CiBjbG9zdXJlIGNhY2hlZGNsOwogbWl4ZWQgKnJ1bGU7CgogLy8gcG90ZW50aWVsbGUgQWRkQ21kIG1pdCBSZWdlbD8KIGlmKHN0cmluZ3AoY21kKSkgewogIC8vIGVpbmUgUmVnZWw/IC0gYXVmc3BsaXR0ZW4KICBpZigoaT1tZW1iZXIoY21kLCcmJykpPjApIHsKICAgLy8gLi4uIGluIEFycmF5IG1pdCBWZXJrbnVlcGZ1bmdzZWxlbWVudGVuCiAgIHJ1bGU9ZXhwbG9kZShjbWRbKGkrMSkuLl0sIiYiKTsKICAgaj1zaXplb2YocnVsZSk7CiAgIC8vIC4uLiBpbiBBcnJheSBtaXQgQXJyYXlzIG1pdCBBbHRlcm5hdGl2ZWxlbWVudGVuOgogICAvLyAicHxxJnJ8cyIgLT4gKHsgKHsicCIsInEifSksICh7InIiLCJzIn19IH0pCiAgIHdoaWxlKGotLSkKICAgIHJ1bGVbal09ZXhwbG9kZShydWxlW2pdLCJ8Iik7CgogICAvLyBSZWdlbG4gdm9uIEtvbW1hbmRvdmVyYmVuIGFic2NobmVpZGVuCiAgIGNtZD1jbWRbMC4uKGktMSldOwogIH0KICAvLyBLb21tYW5kb3ZlcmJlbiBleHRyYWhpZXJlbgogIGNtZD1leHBsb2RlKGNtZCwifCIpOwoKICAvLyBTYXR6IHZvbiBSZWdlbG4gZXhpc3RpZXJ0OiBBdWZzcGxpdHRlbiB2b24gRmVobGVybWVsZHVuZ2VuCiAgaWYocnVsZSkKICAgaWYoc3RyaW5ncChmbGFnKSkgewogICAgbWl4ZWQgKmZhaWw7CiAgICAvLyBpbiBlaW5mYWNoZXMgQXJyYXkgbWl0IGpld2VpbGlnZW4gRmVobGVybWVsZHVuZ2VuCiAgICBmYWlsPWV4cGxvZGUoZmxhZywifCIpOwogICAgaj0wOwogICAgaT1zaXplb2YoZmFpbCk7CiAgICB3aGlsZShqPGkpIHsKICAgICAvLyB3cml0ZSAtIEZlaGxlcm1lbGR1bmcgZW50ZGVja3QgLSBQb3NpdGlvbiBnZ2YuIGVpbnRyYWdlbgogICAgIGlmKG1lbWJlcihmYWlsW2pdLCdeJyk+PTAgJiYgIWludHAoZmFpbFs8MV0pKQogICAgICBmYWlsKz0oe2p9KTsKICAgICBpZihtZW1iZXIoZmFpbFtqXSwnQCcpPj0wKSB7CiAgICAgIGludCBzOwogICAgICBmbGFnPXJlZ2V4cGxvZGUoZmFpbFtqXSwgIkBXRVtBLVNVXSpbMC05XSIpOwogICAgICBzPXNpemVvZihmbGFnKTsKICAgICAgd2hpbGUoKHMtPTIpPjApIHsKICAgICAgIGludCB0bXBpbnQ7CiAgICAgICB0bXBpbnQ9ZmxhZ1tzXVs8MV0tJzEnOwogICAgICAgaWYodG1waW50PDAgfHwgdG1waW50PmopCiAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKICAgICAgICAgIkFkZENtZDogZXJyb3ItbWVzc2FnZSAlZCBjb250YWlucyBvdXQtb2YtYm91bmRzIEBXRXh4LXJ1bGUuXG4iLGorMSkpOwogICAgICB9CiAgICAgfQogICAgIGorKzsKICAgIH0KICAgIC8vICJXYXM/fFdpZSBkYXM/IiAtPiAoeyJXYXM/IiwiV2llIGRhcz8ifSkKICAgIC8vICJXYXM/fFdpZSBkYXM/XnxXb21pdCBkYXM/fFdvcmF1ZiBkYXM/XkBXRVIxIG1hY2h0IHdhcy4iIC0+CiAgICAvLyAgKHsiV2FzPyIsCiAgICAvLyAgICAiV2llIGRhcz9eV29taXQgZGFzPyIsCiAgICAvLwkgICJXb3JhdWYgZGFzP15AV0VSMSBtYWNodCB3YXMuIiwxfSkKICAgIGZsYWc9c2l6ZW9mKGZhaWwpOwogICAgaWYoZmxhZyAmJiBmbGFnPHNpemVvZihydWxlKSkKICAgICByYWlzZV9lcnJvcigKICAgICAgIkFkZENtZDogbnVtYmVyIG9mIGVycm9yLW1lc3NhZ2VzIGRvZXMgbm90IG1hdGNoIG51bWJlciBvZiBydWxlcy5cbiIpOwogICAgZmxhZz1mYWlsOyAvLyB1ZWJlcnNjaHJlaWJlbiBtaXQgZGVuIHBhcnNlZnJldW5kbGljaGVuIEZvcm1hdAogIH0gZWxzZSBpZihmbGFnKQogICByYWlzZV9lcnJvcigiQWRkQ21kOiBydWxlcyBleGlzdCBidXQgZmxhZ3MgYXJlIG5vdCBhbiBlcnJvci1zdHJpbmcuXG4iKTsKIH0gLy8gZW5kIGlmKHN0cmluZ3AoY21kKSkgLi4uIGtlaW4gUmVnZWxzdHJpbmcgdm9yaGFuZGVuCgogLy8ga2VpbiBLb21tYW5kb2FycmF5IGdld2VzZW4gbm9jaCBlcnpldWd0PwogaWYoIXBvaW50ZXJwKGNtZCkpCiAgIHJhaXNlX2Vycm9yKCJBZGRDbWQ6IG1pc3Npbmcgc3RyaW5nL3BvaW50ZXItcGFyYW1ldGVyIGZvciBjb21tYW5kLlxuIik7CgogIC8vIFN0cmluZy1NZXRob2RlIGF1ZiBTaWNodGJhcmtlaXQgcHJ1ZWZlbiwgQ2FjaGUgZ2xlaWNoIGFucGFzc2VuCiAgc3dpdGNoKHR5cGVvZihmdW5jKSkgewogICAgY2FzZSBUX1NUUklORzoKICAgICAgY2FjaGVkY2w9X2NoZWNrX3N0cmluZ21ldGhvZChmdW5jLCBleHRlcm5fY2FsbCgpLCAiQWRkQ21kOiAiKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIFRfQ0xPU1VSRToKICAgICAgY2FjaGVkY2w9ZnVuYzsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBpZihleHRlcm5fY2FsbCgpKSBmdW5jPXByZXZpb3VzX29iamVjdCgpOwogICAgICBlbHNlIGZ1bmM9dGhpc19vYmplY3QoKTsKICAgICAgYnJlYWs7CiAgfQoKICAvLyBqZWRlcyBlaW56ZWxuZSBWZXJiIG1pdCBzZWluZW4gUmVnZWxuIHVuZCBGdW5rdGlvbmVuIGVpbnRyYWdlbgogaT1zaXplb2YoY21kKTsKIGlmKCFhZGRlZF9jbWRzKSBhZGRlZF9jbWRzPW1fYWxsb2NhdGUoaSwgQ01EU19XSURUSCk7CiB3aGlsZShpLS0pIHsKICBzdHJpbmcgc3RyOwogIHN0cj1jbWRbaV07CiAgaWYoIW1lbWJlcihhZGRlZF9jbWRzLHN0cikpCiAgIGFkZGVkX2NtZHMrPShbc3RyOmFsbG9jYXRlKDApO2FsbG9jYXRlKDApO2FsbG9jYXRlKDApOzA7YWxsb2NhdGUoMCldKTsKICAvLyBleGlzdGllcmVuZGVzIFZlcmIgZXJnYWVuemVuCiAgYWRkZWRfY21kc1tzdHIsIENNRElEWF9GVU5dKz0oe2Z1bmN9KTsKICBhZGRlZF9jbWRzW3N0ciwgQ01ESURYX0ZMQUddKz0oe2ZsYWd9KTsKICBhZGRlZF9jbWRzW3N0ciwgQ01ESURYX1JVTEVdKz0oe3J1bGV9KTsKICBhZGRlZF9jbWRzW3N0ciwgQ01ESURYX0NBQ0hFXSs9KHtjYWNoZWRjbH0pOwogIC8vIGdnZi4gaWQgaW4gZGFzIElELU1hcHBpbmcgZWludHJhZ2VuCiAgaWYoY21kaWQpIHsKICAgbWl4ZWQgKnRtcDsKICAgaj1zaXplb2YoKHN0cmluZyopYWRkZWRfY21kc1tzdHIsIENNRElEWF9GVU5dKTsKICAgdG1wPWFkZGVkX2NtZHNbc3RyLCBDTURJRFhfSURdfHxhbGxvY2F0ZShqKTsKICAgaWYoc2l6ZW9mKHRtcCk8aikgdG1wKz1hbGxvY2F0ZShqLXNpemVvZih0bXApKTsKICAgdG1wWzwxXT1jbWRpZDsKICAgYWRkZWRfY21kc1tzdHIsIENNRElEWF9JRF09dG1wOwogIH0KIH0KfQoKLy8gQXVzd2VydHVuZyBmdWVyIGVpbiBWZXJiIGxvZXNjaGVuCnZhcmFyZ3MgaW50IFJlbW92ZUNtZChtaXhlZCBjbWQsIGludCBkZWxfbm9ydWxlLCBtaXhlZCBvbmx5aWQpIHsKIGludCByZXQ7CgogLy8gRmFsbHMgTWFnaWVyIGRhcyBSZW1vdmVDbWQgZmFsc2NoIG51dHplbiAoei5CLiBhbmFsb2cgenUgQWRkQ21kKQogLy8gd2lyZCBkYXMgUmVnZWxzeXN0ZW0gdmVyd2lycnQuIERhIGRhcyBkZWxfbm9ydWxlIG51ciBpbnQgc2VpbiBkYXJmLAogLy8gZ2lidCBlcyBoaWVyIGVpbmUgZ3V0ZSBDaGFuY2UgZGVuIEZlaGxlciBhYndhZXJ0c2tvbXBhdGliZWwgenUgZW50LQogLy8gZGVja2VuLiBEYW1pdCBTcGllbGVyIGRlbiBGZWhsZXIgbmljaHQgbWl0YmVrb21tZW4sIHdpcmQgaGllciBhdWYKIC8vIGVpbiByYWlzZV9lcnJvciB2ZXJ6aWNodGV0LCB1bmQgc3RhdHQgZGVzc2VuIGluIGVpbiBMb2dmaWxlIGdlLQogLy8gc2NocmllYmVuLgogaWYgKCFpbnRwKGRlbF9ub3J1bGUpKQogewogICBsb2dfZmlsZSgiUkVNT1ZFX0NNRCIsCiAgICAgc3ByaW50ZigiXG4tLSAlcyAtLVxuSWxsZWdhbCBSZW1vdmVDb21tYW5kKCkgaW4gT2JqZWN0IFslT106XG4gJU9cbiIsCiAgICAgICBkdGltZSh0aW1lKCkpLCB0aGlzX29iamVjdCgpLCBjbWQpKTsKICAgZGVsX25vcnVsZT0wOwogICBvbmx5aWQ9MDsKIH0KIAogaWYoIWFkZGVkX2NtZHMgfHwgKCFjbWQgJiYgIWRlbF9ub3J1bGUgJiYgIW9ubHlpZCkpCiAgYWRkZWRfY21kcz0obWFwcGluZykwOyAKIGVsc2UgewogIGludCBpLCBqOwogIG1peGVkICpydWxlLCAqZmxhZywgKmZ1biwgKmRlbHJ1bGUsICppZHMsICpjYWNoZWNsOwoKICBpZihzdHJpbmdwKGNtZCkpIHsKICAgLy8gUmVnZWxuIGVudGRlY2t0IC0gWmVybGVnZW4gKHdpZSBBZGRDbWQpCiAgIGlmKChpPW1lbWJlcihjbWQsJyYnKSk+MCkgewogICAgZGVscnVsZT1leHBsb2RlKGNtZFsoaSsxKS4uXSwiJiIpOwogICAgaj1zaXplb2YoZGVscnVsZSk7CiAgICB3aGlsZShqLS0pCiAgICAgZGVscnVsZVtqXT1leHBsb2RlKGRlbHJ1bGVbal0sInwiKTsKICAgIGNtZD1jbWRbMC4uKGktMSldOwogICB9CiAgIGNtZD1leHBsb2RlKGNtZCwifCIpOwogIH0gZWxzZSBpZihkZWxfbm9ydWxlIHx8IG9ubHlpZCkgY21kPW1faW5kaWNlcyhhZGRlZF9jbWRzKTsKCiAgaWYoIXBvaW50ZXJwKGNtZCkpCiAgIHJhaXNlX2Vycm9yKCJSZW1vdmVDbWQ6IG1pc3Npbmcgc3RyaW5nL3BvaW50ZXItcGFyYW1ldGVyLlxuIik7CiAgaT1zaXplb2YoY21kKTsKCiAgd2hpbGUoaS0tKSB7CiAgIC8vIGtlaW5lIFJlZ2VsbiBkYSB1bmQgUmVnZWxuIGxvZXNjaGVuIGVybGF1YnQ6IGFsbGVzIGxvZXNjaGVuCiAgIGlmKCFkZWxydWxlICYmICFkZWxfbm9ydWxlICYmICFvbmx5aWQpIG1fZGVsZXRlKGFkZGVkX2NtZHMsY21kW2ldKTsKICAgZWxzZSBpZihtX2NvbnRhaW5zKCZmdW4sICZmbGFnLCAmcnVsZSwgJmlkcywgJmNhY2hlY2wsIGFkZGVkX2NtZHMsIGNtZFtpXSkpIHsKICAgIGo9c2l6ZW9mKGZ1bik7CiAgICB3aGlsZShqLS0pIHsKICAgICBpbnQgazsKICAgICAvLyBEQkcocnVsZVtqXSk7CiAgICAJLy8gUmVnZWxuIG5pY2h0IGz2c2NoZW4gdW5kIFJlZ2VsPwogICAgIGlmKCEoZGVsX25vcnVsZSAmJiBwb2ludGVycChydWxlW2pdKSkgJiYKICAgICAgICAvLyBudXIgYmVzdGltbXRlIElEIGz2c2NoZW4gdW5kIElEIHBhc3N0IG5pY2h0PwogICAgICAgICEob25seWlkICYmICghcG9pbnRlcnAoaWRzKSB8fCBzaXplb2YoaWRzKTw9aiB8fCBpZHNbal0hPW9ubHlpZCkpICYmCiAgICAgICAgLy8gTPZzY2hyZWdlbCBleGlzdGllcnQgdW5kIHBhc3N0IG5pY2h0IGF1ZiBSZWdlbD8KICAgICAgICAhKGRlbHJ1bGUgJiYgKGs9c2l6ZW9mKHJ1bGVbal0pKSE9c2l6ZW9mKGRlbHJ1bGUpKSkgewogICAgICAvLyBwYXJ0aWVsbGVzIFRlc3RlbiBlaW5lciBM9nNjaHJlZ2VsIC4uLgogICAgICBpZihkZWxydWxlKSB7CiAgICAgICB3aGlsZShrLS0pCiAgICAgICAgaWYoIXNpemVvZihydWxlW2pdW2tdJmRlbHJ1bGVba10pKSBicmVhazsKICAgICAgIGlmKGs+PTApIGNvbnRpbnVlOwogICAgICB9CiAgICAgIC8vIGFsbGVzIGtvcnJla3Q6IEz2c2NoZW4hCiAgICAgIC8vIChBcnJheWJlcmVpY2ggZHVyY2ggbGVlcmVzIEFycmF5IGxvZXNjaGVuKQogICAgICBmbGFnW2ouLmpdICAgID0gYWxsb2NhdGUoMCk7CiAgICAgIGZ1bltqLi5qXSAgICAgPSBhbGxvY2F0ZSgwKTsKICAgICAgcnVsZVtqLi5qXSAgICA9IGFsbG9jYXRlKDApOwogICAgICBjYWNoZWNsW2ouLmpdID0gYWxsb2NhdGUoMCk7CiAgICAgIGlmKGlkcykgewogICAgICAgaWRzW2ouLmpdID0gYWxsb2NhdGUoMCk7CiAgICAgICBpZighc2l6ZW9mKGlkcy1hbGxvY2F0ZSgxKSkpIGlkcz0obWl4ZWQqKTA7CiAgICAgIH0KICAgICAgcmV0Kys7CiAgICAgfQogICAgfSAvLyBlbmQgd2hpbGUoai0tKSB7CiAgIH0KICAgLy8gRnVua3Rpb25zL1JlZ2VsbGlzdGUgdXBkYXRlIG9kZXIgZ2dmLiBLb21tYW5kbyB2b2VsbGlnIGxvZXNjaGVuCiAgIGlmKHNpemVvZihydWxlKSkgewogICAgYWRkZWRfY21kc1tjbWRbaV0sIENNRElEWF9GVU5dPWZ1bjsKICAgIGFkZGVkX2NtZHNbY21kW2ldLCBDTURJRFhfRkxBR109ZmxhZzsKICAgIGFkZGVkX2NtZHNbY21kW2ldLCBDTURJRFhfUlVMRV09cnVsZTsKICAgIGFkZGVkX2NtZHNbY21kW2ldLCBDTURJRFhfSURdPWlkczsKICAgIGFkZGVkX2NtZHNbY21kW2ldLCBDTURJRFhfQ0FDSEVdPWNhY2hlY2w7CiAgIH0gZWxzZSBtX2RlbGV0ZShhZGRlZF9jbWRzLGNtZFtpXSk7CiAgfQogIGlmKCFzaXplb2YoYWRkZWRfY21kcykpIGFkZGVkX2NtZHM9KG1hcHBpbmcpMDsKIH0KIHJldHVybiByZXQ7Cn0KCi8vIEF1c2Z1ZWhyZW4gc2FtdCBnZXBhcnN0ZW0gSW5wdXRzdHJpbmcgdW5kIGdldHJpZ2dlcnRlbiBQYXJzZXJlcmdlYm5pc3NlbgpzdGF0aWMgaW50IF9leGVjdXRlKG1peGVkIGZ1biwgc3RyaW5nIHN0ciwgbWl4ZWQgKnBhcnNlZCkgewogIHN3aXRjaCh0eXBlb2YoZnVuKSkgewogICAgY2FzZSBUX0NMT1NVUkU6CiAgICAgIHJldHVybiAoKGludClmdW5jYWxsKGZ1bixzdHIsJnBhcnNlZCkpOwogICAgY2FzZSBUX1NUUklORzoKICAgICAgaW50IHJldDsKICAgICAgaWYoIWNhbGxfcmVzb2x2ZWQoJnJldCwgdGhpc19vYmplY3QoKSwgZnVuLCBzdHIsICZwYXJzZWQpKQogICAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCiAgICAgICAgICAiQWRkQ21kOiBTdHJpbmctTWV0aG9kZSAnJXMnIGluIEtvbW1hbmRvICUjTyBzY2hlaW50IHp1IGZlaGxlbiAiCiAgICAgICAgICAib2RlciBuaWNodCB6dWdyZWlmYmFyIHp1IHNlaW4uXG4iLCBmdW4sIHBhcnNlZCkpOwogICAgICByZXR1cm4gcmV0OwogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgfQogIHJldHVybiAwOwp9CgojZGVmaW5lIENIRUNLX1BSRVNFTlQgICAgIDEKI2RlZmluZSBDSEVDS19JRCAgICAgICAgICAyCiNkZWZpbmUgQ0hFQ0tfUFVUR0VUTk9ORSAgNAojZGVmaW5lIENIRUNLX1BVVEdFVERST1AgIDgKI2RlZmluZSBDSEVDS19QVVRHRVRUQUtFICAxNgojZGVmaW5lIENIRUNLX1BVVEdFVCAgICAgIChDSEVDS19QVVRHRVROT05FfENIRUNLX1BVVEdFVERST1B8Q0hFQ0tfUFVUR0VUVEFLRSkKCi8vIFdlcnQgZnVlciBGZWhsc2NobGFnLCBGYWxsYmFjay1XZXJ0IGRlciBiZW51dHp0ZW4gd2hpbGUtLSAtIFNjaGxlaWZlbgojZGVmaW5lIE5PTUFUQ0hGT1VORCAgICAgIC0xCgovLyBSZWdlbG4gZnVlciBlaW4gKG51biB1bndpY2h0aWdlcykgVmVyYiB0cmlnZ2VybgpzdGF0aWMgaW50IF9wcm9jZXNzX2NvbW1hbmQoc3RyaW5nIHN0ciwgc3RyaW5nICpub3BhcnNlc3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWl4ZWQgZnVuLCBtaXhlZCBmbGFnLCBtaXhlZCBydWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWl4ZWQgaWQsIG1peGVkIGNhY2hlZGNsKSB7CiBtaXhlZCAqcGFyc2VkLCAqb2JqbWF0Y2hlczsKCiAvLyBlaW5lIFJlZ2VsIC4uLiBhdXN3ZXJ0ZW4gLi4uCiBpZihwb2ludGVycChydWxlKSkgewogIGludCBucnVsOwogIHBhcnNlZD1vYmptYXRjaGVzPWFsbG9jYXRlKDApOwogIGludCBsYXN0bWF0Y2hwb3M9Tk9NQVRDSEZPVU5EOwoKICAvLyBBYmdsZWljaGVuIGRlciBnZXNwbGl0dGV0ZW4gRWluZ2FiZSBtaXQgUmVnZWxuOgogIC8vIHZvcndhZXJ0cyBkdXJjaCBkaWUgU3lub255bWdydXBwZW4KICBpbnQgcnM9c2l6ZW9mKHJ1bGUpOwogIHdoaWxlKG5ydWw8cnMpIHsKICAgaW50IG1hdGNocG9zOwogICBzdHJpbmcgKnN5bm9ueW07CiAgIG1peGVkIG1hdGNoc3RyOwoKICAgbWF0Y2hwb3M9Tk9NQVRDSEZPVU5EOwogICBtYXRjaHN0cj0wOwoKICAgLy8gU3lub255bWUgZXh0cmFoaWVyZW4KICAgaW50IG5yc3lub255bXM9c2l6ZW9mKHN5bm9ueW09cnVsZVtucnVsXSk7CgogICAvLyBlZ2FsIHdpZSBkdXJjaCBTeW5vbnltZSBiaXMgTWF0Y2ggLSBBYmdsZWljaCBtaXQgRWluZ2FiZQogICB3aGlsZShucnN5bm9ueW1zLS0pIHsKICAgIGludCB0bXBwb3MgPSBtZW1iZXIobm9wYXJzZXN0cixzeW5vbnltW25yc3lub255bXNdKTsKICAgIC8vIGlzdCBTeW5vbnltIGltIEVpbmdhYmVzdHJpbmcgdW5kIGtvbW10IHNwYWV0ZXIgYWxzIHZvcmhlcmlnZXMgU3lub255bT8KICAgIGlmKHRtcHBvcz49MCAmJiB0bXBwb3M+bGFzdG1hdGNocG9zKSB7CiAgICAgLy8gRXJmb2xnOiBtZXJrZW4gZGVyIFBvc2l0aW9uIGltIEVpbmdhYmVzdHJpbmcgdW5kIGRlbiBtYXRjaGVuZGVuIFN0cmluZwogICAgIG1hdGNocG9zPXRtcHBvczsKICAgICBtYXRjaHN0cj1ub3BhcnNlc3RyW3RtcHBvc107CiAgICAgYnJlYWs7CiAgICB9CiAgIH0KCiAgIC8vIGtlaW4gTWF0Y2ggZHVyY2ggU3lub255bWU/IFBydWVmZSBkaWUgQC1TcGV6aWFsdmFyaWFibGVuLgogICBpZihtYXRjaHBvcyA9PSBOT01BVENIRk9VTkQpIHsKICAgIGludCBjaGVja19wcmVzZW50OwogICAgLy8gaXN0IEFicHJ1ZWZlbiB2b24gSUQvUFJFU0VOVCBpbiBkZXIgU3lub255bWdydXBwZSB2ZXJsYW5ndAogICAgLy8gYmVpIHByZXNlbnQoKS9maW5kX29icyBnbGVpY2ggVm9yYXVzc2V0enVuZyBndWVsdGlnZXIgVFAgbWl0cHJ1ZmVuCiAgICBpZihtZW1iZXIoc3lub255bSwiQElEIik+PTApIGNoZWNrX3ByZXNlbnQ9Q0hFQ0tfSUQ7CiAgICBpZih0aGlzX3BsYXllcigpKSB7CiAgICAgaWYobWVtYmVyKHN5bm9ueW0sIkBQUkVTRU5UIik+PTApIGNoZWNrX3ByZXNlbnR8PUNIRUNLX1BSRVNFTlQ7CiAgICAgZWxzZSBpZihtZW1iZXIoc3lub255bSwiQFBVVF9HRVRfTk9ORSIpPj0wKQoJCWNoZWNrX3ByZXNlbnR8PUNIRUNLX1BVVEdFVE5PTkU7CiAgICAgZWxzZSBpZihtZW1iZXIoc3lub255bSwiQFBVVF9HRVRfVEFLRSIpPj0wKQoJCWNoZWNrX3ByZXNlbnR8PUNIRUNLX1BVVEdFVERST1A7CiAgICAgZWxzZSBpZihtZW1iZXIoc3lub255bSwiQFBVVF9HRVRfRFJPUCIpPj0wKQoJCWNoZWNrX3ByZXNlbnR8PUNIRUNLX1BVVEdFVFRBS0U7CiAgICB9CgogICAgaWYoY2hlY2tfcHJlc2VudCkgewogICAgIC8vIHdpciBmYW5nZW4gaGludGVyIGRlbSBsZXR6dGVuIE1hdGNoIGFuCiAgICAgaW50IHFfc3RhcnQ9bGFzdG1hdGNocG9zKzE7CiAgICAgaW50IHJfZW5kPXNpemVvZihub3BhcnNlc3RyKS0xOwoKICAgICBpbnQgcmFuZ2U7CiAgICAgd2hpbGUoKHJhbmdlPXJfZW5kLXFfc3RhcnQpPj0wKSB7CiAgICAgIG1peGVkIHRtcG9iajsKCiAgICAgIC8vIHdpZSB3ZWl0IHdvbGxlbiB3aXIgenVy/GNrZ2VoZW4/CiAgICAgIGlmKHJhbmdlKQogICAgICAgIGlmKCEoY2hlY2tfcHJlc2VudCZDSEVDS19QVVRHRVQpKQogICAgICAgICAgcmFuZ2U9cmFuZ2U+Mj8yOnJhbmdlOyAvLyAzIEZyYWdtZW50ZSBmdWVyIEBJRC9AUFJFU0VOVCAoQWR2ZXJiL05yKQogICAgICAgIGVsc2UgaWYocmFuZ2U+NCkKICAgICAgICAgIHJhbmdlPTQ7ICAgICAgICAgICAgICAgLy8gNSBGcmFnbWVudGUgZnVlciBAUFVUX1hYWCAKCiAgICAgIC8vIHVuZCBqZXR6dCBkaWUgU3Vic3RyaW5ncyBwcnVlZmVuCiAgICAgIHdoaWxlKHJhbmdlPj0wICYmICFtYXRjaHN0cikgewogICAgICAgc3RyaW5nIHRtcHN0cjsKCiAgICAgICAvLyB6dSBwcnVlZmVuZGVuIFN0cmluZyBhdXMgZGVuIFRlaWxlbiB6dXNhbW1lbnNldHplbgogICAgICAgaWYocmFuZ2UpIHRtcHN0cj1pbXBsb2RlKG5vcGFyc2VzdHJbcV9zdGFydC4uKHFfc3RhcnQrcmFuZ2UpXSwiICIpOwogICAgICAgZWxzZSB0bXBzdHI9bm9wYXJzZXN0cltxX3N0YXJ0XTsKCiAgICAgICAvL0RCRyh0bXBzdHIpOwogICAgICAgaWYoY2hlY2tfcHJlc2VudCZDSEVDS19QUkVTRU5UICYmCQkJLy8gUFJFU0VOVCA/CiAgICAgICAgICAoKHRtcG9iaj1wcmVzZW50KHRtcHN0cix0aGlzX3BsYXllcigpKSkgfHwKICAgICAgICAgICAodG1wb2JqPXByZXNlbnQodG1wc3RyLGVudmlyb25tZW50KHRoaXNfcGxheWVyKCkpKSkpKQogICAgICAgIG1hdGNoc3RyPXRtcG9iajsKICAgICAgIGVsc2UgaWYoY2hlY2tfcHJlc2VudCZDSEVDS19JRCAmJiBpZCh0bXBzdHIpKQkvLyBJRCA/CiAgICAgICAgbWF0Y2hzdHI9dGhpc19vYmplY3QoKTsKICAgICAgIGVsc2UgaWYoKGNoZWNrX3ByZXNlbnQmQ0hFQ0tfUFVUR0VUKSAmJgkvLyBQVVRfR0VUXz8/PyA/CiAgICAgICAgICAgICAgICh0bXBvYmo9KG9iamVjdCopCiAgICAgICAgICAgICAgICAgIHRoaXNfcGxheWVyKCktPmZpbmRfb2JzKHRtcHN0ciwKICAgICAgICAgICAgICAgICAgICAgIChbQ0hFQ0tfUFVUR0VUTk9ORTpQVVRfR0VUX05PTkUsCiAgICAgICAgICAgICAgICAgICAgICAgIENIRUNLX1BVVEdFVERST1A6UFVUX0dFVF9UQUtFLAogICAgICAgICAgICAgICAgICAgICAgICBDSEVDS19QVVRHRVRUQUtFOlBVVF9HRVRfRFJPUF0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbQ0hFQ0tfUFVUR0VUJmNoZWNrX3ByZXNlbnRdKSkgJiYKICAgICAgICAgICAgICAgc2l6ZW9mKHRtcG9iaikpIHsKICAgICAgICBpZihzaXplb2YodG1wb2JqKT09MSkgbWF0Y2hzdHI9dG1wb2JqWzBdOwogICAgICAgIGVsc2UgewkvLyBBcnJheXMgd2VyZGVuIHp3aXNjaGVuZ2VzcGVpY2hlcnQgLi4uCiAgICAgICAgIG9iam1hdGNoZXMrPSh7c2l6ZW9mKHBhcnNlZCksdG1wb2JqfSk7CiAgICAgICAgIG1hdGNoc3RyPXRtcHN0cjsKICAgICAgICB9CiAgICAgICB9IGVsc2UgeyAvLyBkaWVzZXIgU3Vic3RyaW5nIGhhdCBuaWNodCBnZW1hdGNodAogICAgICAgIC8vIGFiIHdlbmlnZXIgYWxzIDMgVGVpbGVuIGlzdCBkYXMgTmljaHRtYXRjaGluZyBlaW5lcyBTdWJzdHJpbmdzIG1pdAogICAgICAgIC8vIGJlZW5kZW5kZW0gTnVtZXJhbCBLcml0ZXJpdW0gZnVlciBBYmJydWNoICgib2JqZWt0IDIiIHNvbGwgbWF0Y2hlbikKICAgICAgICBzdHJpbmcgbnVtZXJhbGNoZWNrOwogICAgICAgIGlmKHJhbmdlICYmIHJhbmdlPD0yICYmCiAgICAgICAgICAgc2l6ZW9mKG51bWVyYWxjaGVjaz1ub3BhcnNlc3RyW3Ffc3RhcnQrcmFuZ2VdKSAmJgogICAgICAgICAgIHRvX3N0cmluZyh0b19pbnQobnVtZXJhbGNoZWNrKSk9PW51bWVyYWxjaGVjaykKICAgICAgICAgIGJyZWFrOwoKICAgICAgICAvLyBTdWJzdHJpbmdsYWVuZ2UgdmVya3VlcnplbiB1bmQgd2VpdGVyCiAgICAgICAgcmFuZ2UtLTsKICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gTWF0Y2ggZ2VmdW5kZW4hCiAgICAgIGlmKG1hdGNoc3RyKSB7CiAgICAgICBtYXRjaHBvcz1yYW5nZStxX3N0YXJ0OwogICAgICAgLy8gREJHKG1hdGNocG9zKTsKICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIHFfc3RhcnQrKzsKICAgICB9IC8vIGVuZCB3aGlsZQogICAgfQogICB9CgogICAvLyBGZWhsZXJtZWxkdW5nIGZ1ZXIgZGllc2UgZmVobGdlc2NobGFnZW5lIFN5bm9ueW1ncnVwcGUgc2V0emVuCiAgIGlmKG1hdGNocG9zID09IE5PTUFUQ0hGT1VORCkgewogICAgLy8gRmVobGVybWVsZHVuZ2VuIHVuZCBlaW4gRWludHJhZyBhbiBkZXIgRmVobGVyc3RlbGxlPwogICAgaWYocG9pbnRlcnAoZmxhZykgJiYgc2l6ZW9mKGZsYWcpPm5ydWwpIHsKCiAgICAgbWF0Y2hzdHI9ZmxhZ1tucnVsXTsKCiAgICAgaWYoc3RyaW5ncChtYXRjaHN0cikgJiYgc2l6ZW9mKG1hdGNoc3RyKSkgewogICAgICBpZihtZW1iZXIobWF0Y2hzdHIsJ0AnKT49MCkgewogICAgICAgbWF0Y2hzdHI9cmVwbGFjZV9wZXJzb25hbCgmbWF0Y2hzdHIsKHt0aGlzX3BsYXllcigpfSkrcGFyc2VkLDEpOwogICAgICAgc3RyaW5nIHN0YW1tPSgocXVlcnlfdmVyYigpWzwxXV4nZScpP3F1ZXJ5X3ZlcmIoKTpxdWVyeV92ZXJiKClbMC4uPDJdKTsKICAgICAgIG1hdGNoc3RyPXJlZ3JlcGxhY2UobWF0Y2hzdHIsIkBWRVJCIixjYXBpdGFsaXplKHN0YW1tKSwxKTsKICAgICAgIG1hdGNoc3RyPXJlZ3JlcGxhY2UobWF0Y2hzdHIsIkB2ZXJiIixzdGFtbSwxKTsKICAgICAgfQoKICAgICAgLy8gaXN0IEZlaGxlcm1lbGR1bmcgZWluIFdSSVRFPwogICAgICAvLyBkYW5uIHJldHVybiAxICEKICAgICAgaWYoaW50cChmbGFnWzwxXSkgJiYgZmxhZ1s8MV08PW5ydWwpIHsKICAgICAgIGlmKG1lbWJlcihtYXRjaHN0ciwnXicpPj0wKSB7CiAgICAgICAgbWF0Y2hzdHI9ZXhwbG9kZShtYXRjaHN0ciwiXiIpOwogICAgICAgIHdyaXRlKGNhcGl0YWxpemUoYnJlYWtfc3RyaW5nKG1hdGNoc3RyWzBdLDc4LDAsMSkpKTsKICAgICAgICBpZihzaXplb2YobWF0Y2hzdHJbMV0pKQogICAgICAgICBzYXkoY2FwaXRhbGl6ZShicmVha19zdHJpbmcobWF0Y2hzdHJbMV0sNzgsMCwxKSksKHt0aGlzX3BsYXllcigpfSkgKTsKICAgICAgIH0gZWxzZSB3cml0ZShjYXBpdGFsaXplKGJyZWFrX3N0cmluZyhtYXRjaHN0ciw3OCwwLDEpKSk7CiAgICAgICByZXR1cm4gMTsKICAgICAgfSBlbHNlIG5vdGlmeV9mYWlsKGNhcGl0YWxpemUoYnJlYWtfc3RyaW5nKG1hdGNoc3RyLDc4LDAsMSkpKTsKICAgICB9CiAgICB9CiAgICByZXR1cm4gMDsKICAgfQoKICAgLy8gVXBkYXRlbiBkZXIgSGlsZnN2YXJpYWJsZW4KICAgcGFyc2VkKz0oe21hdGNoc3RyfSk7CiAgIGxhc3RtYXRjaHBvcz1tYXRjaHBvczsKICAgbnJ1bCsrOwogIH0gLy8gZW5kIHdoaWxlKG5ydWw8cnMpIC4uLiBFcmZvbGcgLi4uIGFiIHp1bSBuYWVjaHN0ZW4gUmVnZWx0ZWlsCiB9CgogLy8gQXJyYXlzIGRlciBALU9iamVjdG1hdGNoZXMgaW4gUGFyYW1ldGVyIGZ1ZXIgTWV0aG9kZSByZXN1YnN0aXR1aWVyZW4KIGludCBvYmpzaXplOwogaWYoKG9ianNpemU9c2l6ZW9mKG9iam1hdGNoZXMpKSkKICB3aGlsZSgob2Jqc2l6ZS09Mik+PTApCiAgIHBhcnNlZFtvYmptYXRjaGVzW29ianNpemVdXT1vYmptYXRjaGVzW29ianNpemUrMV07CgogLy8gZXJmb2xncmVpY2ggTWV0aG9kZSBnZWZ1bmRlbi9laW5lIFJlZ2VsIGJpcyB6dW0gRW5kZSBkdXJjaGdlcGFyc3Q6CiByZXR1cm4oX2V4ZWN1dGUoY2FjaGVkY2x8fGZ1biwgc3RyLCAmcGFyc2VkKSk7Cn0KCi8vIEF1c3dlcnR1bmcgLSBhZGRfYWN0aW9uLUZ1biAKcHVibGljIGludCBfY2woc3RyaW5nIHN0cikgewogaW50IG5pbmRleDsKIHN0cmluZyAqa2V5czsKIG1peGVkICpmbGFnOwogLy8gVmVyYiBleGlzdGllcnQsIEtvbW1hbmRvcyBhdWNoLCBFaW50cmFnIGZ1ZXIgVmVyYiBnZWZ1bmRlbgogaWYobWFwcGluZ3AoYWRkZWRfY21kcykgJiYgcXVlcnlfdmVyYigpKSB7CiAgbWl4ZWQgKmZ1biwgKnJ1bGUsICppZHMsICpjYWNoZWNsOwoKICAvLyBpc3QgZGFzIFZlcmIgZWluIEtleSBpbSBLb21tYW5kb21hcHBpbmc/CiAgaWYobV9jb250YWlucygmZnVuLCAmZmxhZywgJnJ1bGUsICZpZHMsICZjYWNoZWNsLCBhZGRlZF9jbWRzLCBxdWVyeV92ZXJiKCkpKSB7CiAgIHN0cmluZyAqbm9wYXJzZXN0cjsKICAgbmluZGV4PXNpemVvZihmdW4pOwogICBub3BhcnNlc3RyPWV4cGxvZGUoKHN0cnx8IiIpLCIgIiktKHsiIn0pOwogICAvLyBkYW5uIG1hdGNoZSB1bmdlcGFyc3RlbiBJbnB1dCBnZWdlbiBldHdhaWdlIFJlZ2VsbgogICAvLyAtLSBuaWNodCBhZW5kZXJuOiBuZXVlIEtvbW1hbmRvcyBzb2xsZW4gYWx0ZSAidWViZXJzY2hyZWliZW4iIGtvZW5uZW4KICAgd2hpbGUobmluZGV4LS0pCiAgIHsKICAgIG1peGVkIGNtZF9pZCA9IChwb2ludGVycChpZHMpICYmIHNpemVvZihpZHMpPm5pbmRleCkgPyBpZHNbbmluZGV4XSA6IDA7CiAgICBpZihfcHJvY2Vzc19jb21tYW5kKCZzdHIsIG5vcGFyc2VzdHIsIGZ1bltuaW5kZXhdLCBmbGFnW25pbmRleF0sCiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVbbmluZGV4XSwgY21kX2lkLCBjYWNoZWNsW25pbmRleF0pKSB7CiAgICAgIEdpdmVFUChFUF9DTUQsIHF1ZXJ5X3ZlcmIoKSk7CiAgICAgIHJldHVybiAxOwogICAgfQogICB9CiAgfQoKICAvLyBrZWluZSBSZWdlbCBwYXNzdGUsIHVuc2NoYXJmZSBBdXN3ZXJ0dW5nIGF1ZiBhbGxlCiAgLy8gQWRkQ21kdmVyYmVuIGF1c2RlaG5lbgogIGtleXM9bV9pbmRpY2VzKGFkZGVkX2NtZHMpOwogIG5pbmRleD1zaXplb2Yoa2V5cyk7CiAgd2hpbGUobmluZGV4LS0pCiAgIGlmKCFzdHJzdHIocXVlcnlfdmVyYigpLGtleXNbbmluZGV4XSkgJiYKICAgICAgbWVtYmVyKChmbGFnPWFkZGVkX2NtZHNba2V5c1tuaW5kZXhdLCBDTURJRFhfRkxBR10pLDEpPj0wKSB7CiAgICBpbnQgaSxyZXQ7CiAgICBpPXNpemVvZihmbGFnKTsKICAgIC8vIFJlaWhlbmZvbGdlIG5pY2h0IGFlbmRlcm4gIQogICAgd2hpbGUoaS0tKQogICAgICBpZihmbGFnW2ldPT0xKSB7CiAgICAgICAgbWl4ZWQgKmZ1enp5ZnVucyAgID0gYWRkZWRfY21kc1trZXlzW25pbmRleF0sIENNRElEWF9GVU5dOwogICAgICAgIG1peGVkICpmdXp6eWNhY2hlICA9IGFkZGVkX2NtZHNba2V5c1tuaW5kZXhdLCBDTURJRFhfQ0FDSEVdOwogICAgICAgIGlmKCFwb2ludGVycChmdXp6eWZ1bnMpIHx8IHNpemVvZihmdXp6eWZ1bnMpPD1pKQogICAgICAgICAgY2F0Y2gocmFpc2VfZXJyb3IoCiAgICAgICAgICAgICJBZGRDbWQtQXVzd2VydHVuZzogQ2F0Y2hBbGwtS29tbWFuZG8gXCIiK2tleXNbbmluZGV4XSsiXCIiCiAgICAgICAgICAgICIgd3VyZGUgd2FlaHJlbmQgZGVyIEF1c2Z1ZWhydW5nIHZlcmFlbmRlcnQgb2RlciBnZWxvZXNjaHQuICIKICAgICAgICAgICAgIktsYXJ0ZXh0OiBEYXMgaXN0IHNjaGxlY2h0LiBTdWNodCBlaW4gUmVtb3ZlQ21kPyAiKTsKICAgICAgICAgICAgcHVibGlzaCk7CiAgICAgICAgZWxzZSBpZihfZXhlY3V0ZShmdXp6eWNhY2hlW2ldfHxmdXp6eWZ1bnNbaV0sIHN0ciwgMCkpIHsKICAgICAgICAgIEdpdmVFUChFUF9DTUQsIHF1ZXJ5X3ZlcmIoKSk7CiAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgIH0KICAgfQogfQogcmV0dXJuIDA7Cn0KCnZvaWQgaW5pdCgpIHsKIGFkZF9hY3Rpb24oIl9jbCIsIiIsMSk7Cn0KCgpwcml2YXRlIHZvaWQgX2NoZWNrX2ltcG9ydGVudHJ5KHN0cmluZyBpbmQsIG1peGVkICpmdW4sIG1peGVkICpmbGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1peGVkICpydWxlLCBpbnR8bWl4ZWQgaWQsIG1peGVkICpjYWNoZWRjbCkgewogIC8vIENoZWNrIGRlciBTdHJpbmdtZXRob2RlbjogRmVobGVyIHdlcmRlbiBhYmdlZmFuZ2VuLCB1bSBnZW5lcmVsbGVzCiAgLy8gS29waWVyZW4genUgZXJtb2VnbGljaGVuLiBFcyBrb2VubmVuIGFiZXIgS29tbWFuZG9tZXRob2RlbiB2ZXJsb3JlbiBnZWhlbi4KICBjYWNoZWRjbCA9IG1hcChmdW4sIGZ1bmN0aW9uIGludHxjbG9zdXJlKHN0cmluZyBjbGZ1bikgewogICAgICAgICAgICAgICAgICAgICAgICBjbG9zdXJlIHJldDsKICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2gocmV0PV9jaGVja19zdHJpbmdtZXRob2QoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZnVuLCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiV2FybnVuZyBTZXRQcm9wKFBfQ09NTUFORFMpOiAiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICAgICAgICAgICAgICB9KTsKICBpZihzaXplb2YoZnVuKSE9c2l6ZW9mKGZsYWcpIHx8IHNpemVvZihmdW4pIT1zaXplb2YocnVsZSkpCiAgICByYWlzZV9lcnJvcigiU2V0UHJvcChQX0NPTU1BTkRTKTogY29ycnVwdCBjb21tYW5kcy1tYXBwaW5nLlxuIik7Cn0KCnByaXZhdGUgdm9pZCBfY2xlYW51cF9leHBvcnRjbChzdHJpbmcgaW5kLCBtaXhlZCAqZnVuLCBtaXhlZCAqZmxhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1peGVkICpydWxlLCBpbnR8bWl4ZWQgaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaXhlZCAqY2FjaGVkY2wpIHsKICBjYWNoZWRjbCA9IGFsbG9jYXRlKHNpemVvZihmdW4pKTsKfQoKc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X2NvbW1hbmRzKCkgewogIG1hcHBpbmcgcmV0OwogIGlmKG1hcHBpbmdwKGFkZGVkX2NtZHMpKSB7CiAgICByZXQgPSBkZWVwX2NvcHkoYWRkZWRfY21kcyk7CiAgICAvLyBDbG9zdXJlcyBpbSBDYWNoZSB3ZXJkZW4gaW1tZXIgZ2Vsb2VzY2h0LCBkYSBzb25zdCB2ZXJzZWhlbnRsaWNoCiAgICAvLyBkb2NoIGV4cG9ydGllcnQgd2VyZGVuIGtvZW5udGUKICAgIHdhbGtfbWFwcGluZyhyZXQsICMnX2NsZWFudXBfZXhwb3J0Y2wpOwogIH0KICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgbWFwcGluZyBfc2V0X2NvbW1hbmRzKG1hcHBpbmcgY29tbWFuZHMpIHsKICBpZighY29tbWFuZHMpIGFkZGVkX2NtZHM9KG1hcHBpbmcpMDsKICBlbHNlIGlmKG1hcHBpbmdwKGNvbW1hbmRzKSkgewogICAgaWYod2lkdGhvZihjb21tYW5kcykgIT0gQ01EU19XSURUSCkKICAgICAgcmFpc2VfZXJyb3IoIlNldFByb3AoUF9DT01NQU5EUyk6IGNvcnJ1cHQgY29tbWFuZHMtbWFwcGluZy5cbiIpOwogICAgbWFwcGluZyB0bXAgPSBkZWVwX2NvcHkoY29tbWFuZHMpOwogICAgd2Fsa19tYXBwaW5nKHRtcCwgIydfY2hlY2tfaW1wb3J0ZW50cnkpOwogICAgYWRkZWRfY21kcyA9IHRtcDsKICB9CiAgcmV0dXJuIF9xdWVyeV9jb21tYW5kcygpOwp9Cg==