LyoKICogIE5vdGVwYWQKICoKICogIENvcHlyaWdodCAxOTk3LDk4IE1hcmNlbCBCYXVyIDxtYmF1ckBnMjYuZXRoei5jaD4KICogIENvcHlyaWdodCAxOTk4IEthcmwgQmFja3N0cpRtIDxrYXJsX2JAZ2VvY2l0aWVzLmNvbT4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIm1haW4uaCIKI2luY2x1ZGUgImxhbmd1YWdlLmgiCgpDSEFSIFNUUklOR19NRU5VX1h4W10gICAgICA9ICJNRU5VX1h4IjsKQ0hBUiBTVFJJTkdfUEFHRVNFVFVQX1h4W10gPSAiRElBTE9HX1BBR0VTRVRVUF9YeCI7Cgp2b2lkIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24odm9pZCkgewogIC8qIFNldHMgdGhlIGNhcHRpb24gb2YgdGhlIG1haW4gd2luZG93IGFjY29yZGluZyB0byBHbG9iYWxzLnN6RmlsZU5hbWU6CiAgICAgIE5vdGVwYWQgLSAodW50aXRsZWQpICAgICAgaWYgbm8gZmlsZSBpcyBvcGVuCiAgICAgIE5vdGVwYWQgLSBbZmlsZW5hbWVdICAgICAgaWYgYSBmaWxlIGlzIGdpdmVuCiAgKi8KICAKICBDSEFSIHN6Q2FwdGlvbltNQVhfU1RSSU5HX0xFTl07CiAgQ0hBUiBzelVudGl0bGVkW01BWF9TVFJJTkdfTEVOXTsKCiAgTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX05PVEVQQUQsIHN6Q2FwdGlvbiwgc2l6ZW9mKHN6Q2FwdGlvbikpOwogIAogIGlmIChzdHJsZW4oR2xvYmFscy5zekZpbGVOYW1lKT4wKSB7CiAgICAgIGxzdHJjYXQoc3pDYXB0aW9uLCAiIC0gWyIpOwogICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgR2xvYmFscy5zekZpbGVOYW1lKTsKICAgICAgbHN0cmNhdChzekNhcHRpb24sICJdIik7CiAgfQogIGVsc2UKICB7CiAgICAgIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19VTlRJVExFRCwgc3pVbnRpdGxlZCwgc2l6ZW9mKHN6VW50aXRsZWQpKTsKICAgICAgbHN0cmNhdChzekNhcHRpb24sICIgLSAiKTsKICAgICAgbHN0cmNhdChzekNhcHRpb24sIHN6VW50aXRsZWQpOwogIH0KICAgIAogIFNldFdpbmRvd1RleHQoR2xvYmFscy5oTWFpblduZCwgc3pDYXB0aW9uKTsKICAKfQoKCgpzdGF0aWMgQk9PTCBMQU5HVUFHRV9Mb2FkU3RyaW5nT3RoZXIoVUlOVCBudW0sIFVJTlQgaWRzLCBMUFNUUiBzdHIsIFVJTlQgbGVuKQp7CiAgQk9PTCBiT2s7CgogIGlkcyAtPSBHbG9iYWxzLndTdHJpbmdUYWJsZU9mZnNldDsKICBpZHMgKz0gbnVtICogMHgxMDA7CgogIGJPayA9IExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIGlkcywgc3RyLCBsZW4pOwoKICByZXR1cm4oYk9rKTsKfQoKCgpWT0lEIExBTkdVQUdFX1NlbGVjdEJ5TmFtZShMUENTVFIgbGFuZykKewogIElOVCBpOwogIENIQVIgbmV3bGFuZ1szXTsKCiAgZm9yIChpID0gMDsgaSA8PSBNQVhfTEFOR1VBR0VfTlVNQkVSOyBpKyspCiAgICBpZiAoTEFOR1VBR0VfTG9hZFN0cmluZ090aGVyKGksIElEU19MQU5HVUFHRV9JRCwgbmV3bGFuZywgc2l6ZW9mKG5ld2xhbmcpKSAmJgogICAgICAgICFsc3RyY21wKGxhbmcsIG5ld2xhbmcpKQogICAgICB7CiAgICAgICAgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIoaSk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogIC8qIEZhbGxiYWNrICovCiAgICBmb3IgKGkgPSAwOyBpIDw9IE1BWF9MQU5HVUFHRV9OVU1CRVI7IGkrKykKICAgIGlmIChMQU5HVUFHRV9Mb2FkU3RyaW5nT3RoZXIoaSwgSURTX0xBTkdVQUdFX0lELCBuZXdsYW5nLCBzaXplb2YobmV3bGFuZykpKQogICAgICB7CiAgICAgICAgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIoaSk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogIE1lc3NhZ2VCb3goR2xvYmFscy5oTWFpblduZCwgIk5vIGxhbmd1YWdlIGZvdW5kIiwgIkZBVEFMIEVSUk9SIiwgTUJfT0spOwogIFBvc3RRdWl0TWVzc2FnZSgxKTsKfQoKVk9JRCBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcihVSU5UIG51bSkKewogIElOVCAgICBpOwogIENIQVIgICBsYW5nWzNdOwogIENIQVIgICBpdGVtW01BWF9TVFJJTkdfTEVOXTsKICBITUVOVSAgaE1haW5NZW51OwoKICAvKiBTZWxlY3Qgc3RyaW5nIHRhYmxlICovCiAgR2xvYmFscy53U3RyaW5nVGFibGVPZmZzZXQgPSBudW0gKiAweDEwMDsKCiAgLyogR2V0IExhbmd1YWdlIGlkICovCiAgTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX0xBTkdVQUdFX0lELCBsYW5nLCBzaXplb2YobGFuZykpOwoKICAvKiBTZXQgZnJhbWUgY2FwdGlvbiAqLwogIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oKTsKICAKICAvKiBDaGFuZ2UgUmVzb3VyY2UgbmFtZXMgKi8KICBsc3RyY3B5bihTVFJJTkdfTUVOVV9YeCAgICAgICsgc2l6ZW9mKFNUUklOR19NRU5VX1h4KSAgICAgIC0gMywgbGFuZywgMyk7CiAgbHN0cmNweW4oU1RSSU5HX1BBR0VTRVRVUF9YeCArIHNpemVvZihTVFJJTkdfUEFHRVNFVFVQX1h4KSAtIDMsIGxhbmcsIDMpOwoKICAvKiBDcmVhdGUgbWVudSAqLwogIGhNYWluTWVudSA9IExvYWRNZW51KEdsb2JhbHMuaEluc3RhbmNlLCBTVFJJTkdfTUVOVV9YeCk7CiAgICBHbG9iYWxzLmhGaWxlTWVudSAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMCk7CiAgICBHbG9iYWxzLmhFZGl0TWVudSAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMSk7CiAgICBHbG9iYWxzLmhTZWFyY2hNZW51ICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMik7CiAgICBHbG9iYWxzLmhMYW5ndWFnZU1lbnUgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMyk7CiAgICBHbG9iYWxzLmhIZWxwTWVudSAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgNCk7CgogIC8qIFJlbW92ZSBkdW1teSBpdGVtICovCiAgUmVtb3ZlTWVudShHbG9iYWxzLmhMYW5ndWFnZU1lbnUsIDAsIE1GX0JZUE9TSVRJT04pOwogIC8qIEFkZCBsYW5ndWFnZSBpdGVtcyAqLwogIGZvciAoaSA9IDA7IGkgPD0gTUFYX0xBTkdVQUdFX05VTUJFUjsgaSsrKQogICAgaWYgKExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihpLCBJRFNfTEFOR1VBR0VfTUVOVV9JVEVNLCBpdGVtLCBzaXplb2YoaXRlbSkpKQogICAgICBBcHBlbmRNZW51KEdsb2JhbHMuaExhbmd1YWdlTWVudSwgTUZfU1RSSU5HIHwgTUZfQllDT01NQU5ELAogICAgICAgICAgICAgICAgIE5QX0ZJUlNUX0xBTkdVQUdFICsgaSwgaXRlbSk7CgogIFNldE1lbnUoR2xvYmFscy5oTWFpblduZCwgaE1haW5NZW51KTsKCiAgLyogRGVzdHJveSBvbGQgbWVudSAqLwogIGlmIChHbG9iYWxzLmhNYWluTWVudSkgRGVzdHJveU1lbnUoR2xvYmFscy5oTWFpbk1lbnUpOwogIEdsb2JhbHMuaE1haW5NZW51ID0gaE1haW5NZW51Owp9CgpWT0lEIExBTkdVQUdFX0RlZmF1bHRIYW5kbGUoV1BBUkFNIHdQYXJhbSkKewogIGlmICgod1BhcmFtID49TlBfRklSU1RfTEFOR1VBR0UpICYmICh3UGFyYW08PU5QX0xBU1RfTEFOR1VBR0UpKQogICAgICAgICAgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIod1BhcmFtIC0gTlBfRklSU1RfTEFOR1VBR0UpOwogICAgIGVsc2UgcHJpbnRmKCJVbmltcGxlbWVudGVkIG1lbnUgY29tbWFuZCAlaVxuIiwgd1BhcmFtKTsKfQo=