LyoKICogTm90ZXBhZAogKgogKiBDb3B5cmlnaHQgMTk5NyBNYXJjZWwgQmF1ciA8bWJhdXJAZzI2LmV0aHouY2g+CiAqIENvcHlyaWdodCAxOTk4IEthcmwgQmFja3N0cvZtIDxrYXJsX2JAZ2VvY2l0aWVzLmNvbT4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIm1haW4uaCIKI2luY2x1ZGUgImxhbmd1YWdlLmgiCiNpZmRlZiBXSU5FTElCCiNpbmNsdWRlICJvcHRpb25zLmgiCiNlbmRpZgoKQ0hBUiBTVFJJTkdfTUVOVV9YeFtdICAgICAgPSAiTUVOVV9YeCI7CkNIQVIgU1RSSU5HX1BBR0VTRVRVUF9YeFtdID0gIkRJQUxPR19QQUdFU0VUVVBfWHgiOwoKdm9pZCBMQU5HVUFHRV9VcGRhdGVXaW5kb3dDYXB0aW9uKHZvaWQpIHsKICAvKiBTZXRzIHRoZSBjYXB0aW9uIG9mIHRoZSBtYWluIHdpbmRvdyBhY2NvcmRpbmcgdG8gR2xvYmFscy5zekZpbGVOYW1lOgogICAgICBOb3RlcGFkIC0gKHVudGl0bGVkKSAgICAgIGlmIG5vIGZpbGUgaXMgb3BlbgogICAgICBOb3RlcGFkIC0gW2ZpbGVuYW1lXSAgICAgIGlmIGEgZmlsZSBpcyBnaXZlbgogICovCiAgCiAgQ0hBUiBzekNhcHRpb25bTUFYX1NUUklOR19MRU5dOwogIENIQVIgc3pVbnRpdGxlZFtNQVhfU1RSSU5HX0xFTl07CgogIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19OT1RFUEFELCBzekNhcHRpb24sIHNpemVvZihzekNhcHRpb24pKTsKICAKICBpZiAoc3RybGVuKEdsb2JhbHMuc3pGaWxlTmFtZSk+MCkgewogICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgIiAtIFsiKTsKICAgICAgbHN0cmNhdChzekNhcHRpb24sIEdsb2JhbHMuc3pGaWxlTmFtZSk7CiAgICAgIGxzdHJjYXQoc3pDYXB0aW9uLCAiXSIpOwogIH0KICBlbHNlCiAgewogICAgICBMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBJRFNfVU5USVRMRUQsIHN6VW50aXRsZWQsIHNpemVvZihzelVudGl0bGVkKSk7CiAgICAgIGxzdHJjYXQoc3pDYXB0aW9uLCAiIC0gIik7CiAgICAgIGxzdHJjYXQoc3pDYXB0aW9uLCBzelVudGl0bGVkKTsKICB9CiAgICAKICBTZXRXaW5kb3dUZXh0KEdsb2JhbHMuaE1haW5XbmQsIHN6Q2FwdGlvbik7CiAgCn0KCgoKc3RhdGljIEJPT0wgTEFOR1VBR0VfTG9hZFN0cmluZ090aGVyKFVJTlQgbnVtLCBVSU5UIGlkcywgTFBTVFIgc3RyLCBVSU5UIGxlbikKewogIGlkcyAtPSBHbG9iYWxzLndTdHJpbmdUYWJsZU9mZnNldDsKICBpZHMgKz0gbnVtICogMHgxMDA7CiAgcmV0dXJuKExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIGlkcywgc3RyLCBsZW4pKTsKfTsKCgoKVk9JRCBMQU5HVUFHRV9TZWxlY3RCeU5hbWUoTFBDU1RSIGxhbmcpCnsKICBJTlQgaTsKICBDSEFSIG5ld2xhbmdbM107CgogIGZvciAoaSA9IDA7IGkgPD0gTUFYX0xBTkdVQUdFX05VTUJFUjsgaSsrKQogICAgaWYgKExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihpLCBJRFNfTEFOR1VBR0VfSUQsIG5ld2xhbmcsIHNpemVvZihuZXdsYW5nKSkgJiYKICAgICAgICAhbHN0cmNtcChsYW5nLCBuZXdsYW5nKSkKICAgICAgewogICAgICAgIExBTkdVQUdFX1NlbGVjdEJ5TnVtYmVyKGkpOwogICAgICAgIHJldHVybjsKICAgICAgfQoKICAvKiBGYWxsYmFjayAqLwogICAgZm9yIChpID0gMDsgaSA8PSBNQVhfTEFOR1VBR0VfTlVNQkVSOyBpKyspCiAgICBpZiAoTEFOR1VBR0VfTG9hZFN0cmluZ090aGVyKGksIElEU19MQU5HVUFHRV9JRCwgbmV3bGFuZywgc2l6ZW9mKG5ld2xhbmcpKSkKICAgICAgewogICAgICAgIExBTkdVQUdFX1NlbGVjdEJ5TnVtYmVyKGkpOwogICAgICAgIHJldHVybjsKICAgICAgfQoKICBNZXNzYWdlQm94KEdsb2JhbHMuaE1haW5XbmQsICJObyBsYW5ndWFnZSBmb3VuZCIsICJGQVRBTCBFUlJPUiIsIE1CX09LKTsKICBQb3N0UXVpdE1lc3NhZ2UoMSk7Cn0KClZPSUQgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIoVUlOVCBudW0pCnsKICBJTlQgICAgaTsKICBDSEFSICAgbGFuZ1szXTsKICBDSEFSICAgaXRlbVtNQVhfU1RSSU5HX0xFTl07CiAgSE1FTlUgIGhNYWluTWVudTsKCiAgLyogU2VsZWN0IHN0cmluZyB0YWJsZSAqLwogIEdsb2JhbHMud1N0cmluZ1RhYmxlT2Zmc2V0ID0gbnVtICogMHgxMDA7CgogIC8qIEdldCBMYW5ndWFnZSBpZCAqLwogIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19MQU5HVUFHRV9JRCwgbGFuZywgc2l6ZW9mKGxhbmcpKTsKICBHbG9iYWxzLmxwc3pMYW5ndWFnZSA9IGxhbmc7CgogIC8qIFNldCBmcmFtZSBjYXB0aW9uICovCiAgTEFOR1VBR0VfVXBkYXRlV2luZG93Q2FwdGlvbigpOwogIAogIC8qIENoYW5nZSBSZXNvdXJjZSBuYW1lcyAqLwogIGxzdHJjcHluKFNUUklOR19NRU5VX1h4ICAgICAgKyBzaXplb2YoU1RSSU5HX01FTlVfWHgpICAgICAgLSAzLCBsYW5nLCAzKTsKICBsc3RyY3B5bihTVFJJTkdfUEFHRVNFVFVQX1h4ICsgc2l6ZW9mKFNUUklOR19QQUdFU0VUVVBfWHgpIC0gMywgbGFuZywgMyk7CgogIC8qIENyZWF0ZSBtZW51ICovCiAgaE1haW5NZW51ID0gTG9hZE1lbnUoR2xvYmFscy5oSW5zdGFuY2UsIFNUUklOR19NRU5VX1h4KTsKICAgIEdsb2JhbHMuaEZpbGVNZW51ICAgICA9IEdldFN1Yk1lbnUoaE1haW5NZW51LCAwKTsKICAgIEdsb2JhbHMuaEVkaXRNZW51ICAgICA9IEdldFN1Yk1lbnUoaE1haW5NZW51LCAxKTsKICAgIEdsb2JhbHMuaFNlYXJjaE1lbnUgICA9IEdldFN1Yk1lbnUoaE1haW5NZW51LCAyKTsKICAgIEdsb2JhbHMuaExhbmd1YWdlTWVudSA9IEdldFN1Yk1lbnUoaE1haW5NZW51LCAzKTsKICAgIEdsb2JhbHMuaEhlbHBNZW51ICAgICA9IEdldFN1Yk1lbnUoaE1haW5NZW51LCA0KTsKCiAgLyogUmVtb3ZlIGR1bW15IGl0ZW0gKi8KICBSZW1vdmVNZW51KEdsb2JhbHMuaExhbmd1YWdlTWVudSwgMCwgTUZfQllQT1NJVElPTik7CiAgLyogQWRkIGxhbmd1YWdlIGl0ZW1zICovCiAgZm9yIChpID0gMDsgaSA8PSBNQVhfTEFOR1VBR0VfTlVNQkVSOyBpKyspCiAgICBpZiAoTEFOR1VBR0VfTG9hZFN0cmluZ090aGVyKGksIElEU19MQU5HVUFHRV9NRU5VX0lURU0sIGl0ZW0sIHNpemVvZihpdGVtKSkpCiAgICAgIEFwcGVuZE1lbnUoR2xvYmFscy5oTGFuZ3VhZ2VNZW51LCBNRl9TVFJJTkcgfCBNRl9CWUNPTU1BTkQsCiAgICAgICAgICAgICAgICAgTlBfRklSU1RfTEFOR1VBR0UgKyBpLCBpdGVtKTsKCiAgU2V0TWVudShHbG9iYWxzLmhNYWluV25kLCBoTWFpbk1lbnUpOwoKICAvKiBEZXN0cm95IG9sZCBtZW51ICovCiAgaWYgKEdsb2JhbHMuaE1haW5NZW51KSBEZXN0cm95TWVudShHbG9iYWxzLmhNYWluTWVudSk7CiAgR2xvYmFscy5oTWFpbk1lbnUgPSBoTWFpbk1lbnU7CgojaWZkZWYgV0lORUxJQgogIC8qIFVwZGF0ZSBzeXN0ZW0gbWVudXMgKi8KICBmb3IgKGkgPSAwOyBMYW5ndWFnZXNbaV0ubmFtZSAmJiBsc3RyY21wKGxhbmcsIExhbmd1YWdlc1tpXS5uYW1lKTspIGkrKzsKICBpZiAoTGFuZ3VhZ2VzW2ldLm5hbWUpIE9wdGlvbnMubGFuZ3VhZ2UgPSBpOwoKI2VuZGlmCn0KClZPSUQgTEFOR1VBR0VfRGVmYXVsdEhhbmRsZShXUEFSQU0gd1BhcmFtKQp7CiAgaWYgKCh3UGFyYW0gPj1OUF9GSVJTVF9MQU5HVUFHRSkgJiYgKHdQYXJhbTw9TlBfTEFTVF9MQU5HVUFHRSkpCiAgICAgICAgICBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcih3UGFyYW0gLSBOUF9GSVJTVF9MQU5HVUFHRSk7CiAgICAgZWxzZSBwcmludGYoIlVuaW1wbGVtZW50ZWQgbWVudSBjb21tYW5kICVpXG4iLCB3UGFyYW0pOwp9CgpWT0lEIExBTkdVQUdFX0luaXQoVk9JRCkKewogICNpZmRlZiBXSU5FTElCCiAgIEdsb2JhbHMubHBzekxhbmd1YWdlID0gTGFuZ3VhZ2VzW09wdGlvbnMubGFuZ3VhZ2VdLm5hbWU7CiAgI2Vsc2UKICBDSEFSIGJ1ZmZlcltNQVhfUEFUSE5BTUVfTEVOXSwgKnA7CgogICAgUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCJwcm9ncmFtcyIsICJsYW5ndWFnZSIsICJsYW5ndWFnZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpOwogIEdsb2JhbHMubHBzekxhbmd1YWdlID0gcCA9IExvY2FsTG9jayhMb2NhbEFsbG9jKExNRU1fRklYRUQsIGxzdHJsZW4oYnVmZmVyKSkpOwogIGhtZW1jcHkocCwgYnVmZmVyLCAxICsgbHN0cmxlbihidWZmZXIpKTsKICAjZW5kaWYKfQoKLyogTG9jYWwgVmFyaWFibGVzOiAgICAqLwovKiBjLWZpbGUtc3R5bGU6ICJHTlUiICovCi8qIEVuZDogICAgICAgICAgICAgICAgKi8KCg==