LyoKICogTm90ZXBhZAogKgogKiBDb3B5cmlnaHQgMTk5NyBNYXJjZWwgQmF1ciA8bWJhdXJAZzI2LmV0aHouY2g+CiAqIENvcHlyaWdodCAxOTk4IEthcmwgQmFja3N0cvZtIDxrYXJsX2JAZ2VvY2l0aWVzLmNvbT4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIm1haW4uaCIKI2luY2x1ZGUgImxhbmd1YWdlLmgiCiNpZmRlZiBXSU5FTElCCiNpbmNsdWRlICJvcHRpb25zLmgiCiNlbmRpZgoKQ0hBUiBTVFJJTkdfTUVOVV9YeFtdICAgICAgPSAiTUVOVV9YeCI7CkNIQVIgU1RSSU5HX1BBR0VTRVRVUF9YeFtdID0gIkRJQUxPR19QQUdFU0VUVVBfWHgiOwoKc3RhdGljIEJPT0wgTEFOR1VBR0VfTG9hZFN0cmluZ090aGVyKFVJTlQgbnVtLCBVSU5UIGlkcywgTFBTVFIgc3RyLCBVSU5UIGxlbikKewogIGlkcyAtPSBHbG9iYWxzLndTdHJpbmdUYWJsZU9mZnNldDsKICBpZHMgKz0gbnVtICogMHgxMDA7CiAgcmV0dXJuKExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIGlkcywgc3RyLCBsZW4pKTsKfTsKClZPSUQgTEFOR1VBR0VfU2VsZWN0QnlOYW1lKExQQ1NUUiBsYW5nKQp7CiAgSU5UIGk7CiAgQ0hBUiBuZXdsYW5nWzNdOwoKICBmb3IgKGkgPSAwOyBpIDw9IE1BWF9MQU5HVUFHRV9OVU1CRVI7IGkrKykKICAgIGlmIChMQU5HVUFHRV9Mb2FkU3RyaW5nT3RoZXIoaSwgSURTX0xBTkdVQUdFX0lELCBuZXdsYW5nLCBzaXplb2YobmV3bGFuZykpICYmCgkhbHN0cmNtcChsYW5nLCBuZXdsYW5nKSkKICAgICAgewogICAgICAgIExBTkdVQUdFX1NlbGVjdEJ5TnVtYmVyKGkpOwoJcmV0dXJuOwogICAgICB9CgogIC8qIEZhbGxiYWNrICovCiAgICBmb3IgKGkgPSAwOyBpIDw9IE1BWF9MQU5HVUFHRV9OVU1CRVI7IGkrKykKICAgIGlmIChMQU5HVUFHRV9Mb2FkU3RyaW5nT3RoZXIoaSwgSURTX0xBTkdVQUdFX0lELCBuZXdsYW5nLCBzaXplb2YobmV3bGFuZykpKQogICAgICB7CglMQU5HVUFHRV9TZWxlY3RCeU51bWJlcihpKTsKCXJldHVybjsKICAgICAgfQoKICBNZXNzYWdlQm94KEdsb2JhbHMuaE1haW5XbmQsICJObyBsYW5ndWFnZSBmb3VuZCIsICJGQVRBTCBFUlJPUiIsIE1CX09LKTsKICBQb3N0UXVpdE1lc3NhZ2UoMSk7Cn0KClZPSUQgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIoVUlOVCBudW0pCnsKICBJTlQgICAgaTsKICBDSEFSICAgbGFuZ1szXTsKICBDSEFSICAgY2FwdGlvbltNQVhfU1RSSU5HX0xFTl07CiAgQ0hBUiAgIGl0ZW1bTUFYX1NUUklOR19MRU5dOwogIEhNRU5VICBoTWFpbk1lbnU7CgogIC8qIFNlbGVjdCBzdHJpbmcgdGFibGUgKi8KICBHbG9iYWxzLndTdHJpbmdUYWJsZU9mZnNldCA9IG51bSAqIDB4MTAwOwoKICAvKiBHZXQgTGFuZ3VhZ2UgaWQgKi8KICBMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBJRFNfTEFOR1VBR0VfSUQsIGxhbmcsIHNpemVvZihsYW5nKSk7CiAgR2xvYmFscy5scHN6TGFuZ3VhZ2UgPSBsYW5nOwoKICAvKiBTZXQgZnJhbWUgY2FwdGlvbiAqLwogIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19OT1RFUEFELCBjYXB0aW9uLCBzaXplb2YoY2FwdGlvbikpOwogIFNldFdpbmRvd1RleHQoR2xvYmFscy5oTWFpblduZCwgY2FwdGlvbik7CgogIC8qIENoYW5nZSBSZXNvdXJjZSBuYW1lcyAqLwogIGxzdHJjcHluKFNUUklOR19NRU5VX1h4ICAgICsgc2l6ZW9mKFNUUklOR19NRU5VX1h4KSAgICAtIDMsIGxhbmcsIDMpOwogIGxzdHJjcHluKFNUUklOR19QQUdFU0VUVVBfWHggICAgKyBzaXplb2YoU1RSSU5HX1BBR0VTRVRVUF9YeCkgICAgLSAzLCBsYW5nLCAzKTsKCiAgLyogQ3JlYXRlIG1lbnUgKi8KICBoTWFpbk1lbnUgPSBMb2FkTWVudShHbG9iYWxzLmhJbnN0YW5jZSwgU1RSSU5HX01FTlVfWHgpOwogICAgR2xvYmFscy5oRmlsZU1lbnUgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDApOwogICAgR2xvYmFscy5oRWRpdE1lbnUgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDEpOwogICAgR2xvYmFscy5oU2VhcmNoTWVudSAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDIpOwogICAgR2xvYmFscy5oTGFuZ3VhZ2VNZW51ID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDMpOwogICAgR2xvYmFscy5oSGVscE1lbnUgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDQpOwoKICAvKiBSZW1vdmUgZHVtbXkgaXRlbSAqLwogIFJlbW92ZU1lbnUoR2xvYmFscy5oTGFuZ3VhZ2VNZW51LCAwLCBNRl9CWVBPU0lUSU9OKTsKICAvKiBBZGQgbGFuZ3VhZ2UgaXRlbXMgKi8KICBmb3IgKGkgPSAwOyBpIDw9IE1BWF9MQU5HVUFHRV9OVU1CRVI7IGkrKykKICAgIGlmIChMQU5HVUFHRV9Mb2FkU3RyaW5nT3RoZXIoaSwgSURTX0xBTkdVQUdFX01FTlVfSVRFTSwgaXRlbSwgc2l6ZW9mKGl0ZW0pKSkKICAgICAgQXBwZW5kTWVudShHbG9iYWxzLmhMYW5ndWFnZU1lbnUsIE1GX1NUUklORyB8IE1GX0JZQ09NTUFORCwKCQkgTlBfRklSU1RfTEFOR1VBR0UgKyBpLCBpdGVtKTsKCiAgU2V0TWVudShHbG9iYWxzLmhNYWluV25kLCBoTWFpbk1lbnUpOwoKICAvKiBEZXN0cm95IG9sZCBtZW51ICovCiAgaWYgKEdsb2JhbHMuaE1haW5NZW51KSBEZXN0cm95TWVudShHbG9iYWxzLmhNYWluTWVudSk7CiAgR2xvYmFscy5oTWFpbk1lbnUgPSBoTWFpbk1lbnU7CgojaWZkZWYgV0lORUxJQgogIC8qIFVwZGF0ZSBzeXN0ZW0gbWVudXMgKi8KICBmb3IgKGkgPSAwOyBMYW5ndWFnZXNbaV0ubmFtZSAmJiBsc3RyY21wKGxhbmcsIExhbmd1YWdlc1tpXS5uYW1lKTspIGkrKzsKICBpZiAoTGFuZ3VhZ2VzW2ldLm5hbWUpIE9wdGlvbnMubGFuZ3VhZ2UgPSBpOwoKI2VuZGlmCn0KClZPSUQgTEFOR1VBR0VfRGVmYXVsdEhhbmRsZShXUEFSQU0gd1BhcmFtKQp7CiAgaWYgKCh3UGFyYW0gPj1OUF9GSVJTVF9MQU5HVUFHRSkgJiYgKHdQYXJhbTw9TlBfTEFTVF9MQU5HVUFHRSkpCiAgICAgICAgICBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcih3UGFyYW0gLSBOUF9GSVJTVF9MQU5HVUFHRSk7CiAgICAgZWxzZSBwcmludGYoIlVuaW1wbGVtZW50ZWQgbWVudSBjb21tYW5kICVpXG4iLCB3UGFyYW0pOwp9CgpWT0lEIExBTkdVQUdFX0luaXQoVk9JRCkKewogICNpZmRlZiBXSU5FTElCCiAgIEdsb2JhbHMubHBzekxhbmd1YWdlID0gTGFuZ3VhZ2VzW09wdGlvbnMubGFuZ3VhZ2VdLm5hbWU7CiAgI2Vsc2UKICBDSEFSIGJ1ZmZlcltNQVhfUEFUSE5BTUVfTEVOXSwgKnA7CgogICAgUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCJwcm9ncmFtcyIsICJsYW5ndWFnZSIsICJsYW5ndWFnZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpOwogIEdsb2JhbHMubHBzekxhbmd1YWdlID0gcCA9IExvY2FsTG9jayhMb2NhbEFsbG9jKExNRU1fRklYRUQsIGxzdHJsZW4oYnVmZmVyKSkpOwogIGhtZW1jcHkocCwgYnVmZmVyLCAxICsgbHN0cmxlbihidWZmZXIpKTsKICAjZW5kaWYKfQoKLyogTG9jYWwgVmFyaWFibGVzOiAgICAqLwovKiBjLWZpbGUtc3R5bGU6ICJHTlUiICovCi8qIEVuZDogICAgICAgICAgICAgICAgKi8K