LyoKICogIE5vdGVwYWQKICoKICogIENvcHlyaWdodCAxOTk3LDk4IE1hcmNlbCBCYXVyIDxtYmF1ckBnMjYuZXRoei5jaD4KICogIENvcHlyaWdodCAxOTk4IEthcmwgQmFja3N0cpRtIDxrYXJsX2JAZ2VvY2l0aWVzLmNvbT4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIm1haW4uaCIKI2luY2x1ZGUgImxhbmd1YWdlLmgiCgojaWZkZWYgV0lORUxJQgojaW5jbHVkZSAib3B0aW9ucy5oIgojZW5kaWYKCkNIQVIgU1RSSU5HX01FTlVfWHhbXSAgICAgID0gIk1FTlVfWHgiOwpDSEFSIFNUUklOR19QQUdFU0VUVVBfWHhbXSA9ICJESUFMT0dfUEFHRVNFVFVQX1h4IjsKCnZvaWQgTEFOR1VBR0VfVXBkYXRlV2luZG93Q2FwdGlvbih2b2lkKSB7CiAgLyogU2V0cyB0aGUgY2FwdGlvbiBvZiB0aGUgbWFpbiB3aW5kb3cgYWNjb3JkaW5nIHRvIEdsb2JhbHMuc3pGaWxlTmFtZToKICAgICAgTm90ZXBhZCAtICh1bnRpdGxlZCkgICAgICBpZiBubyBmaWxlIGlzIG9wZW4KICAgICAgTm90ZXBhZCAtIFtmaWxlbmFtZV0gICAgICBpZiBhIGZpbGUgaXMgZ2l2ZW4KICAqLwogIAogIENIQVIgc3pDYXB0aW9uW01BWF9TVFJJTkdfTEVOXTsKICBDSEFSIHN6VW50aXRsZWRbTUFYX1NUUklOR19MRU5dOwoKICBMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBJRFNfTk9URVBBRCwgc3pDYXB0aW9uLCBzaXplb2Yoc3pDYXB0aW9uKSk7CiAgCiAgaWYgKHN0cmxlbihHbG9iYWxzLnN6RmlsZU5hbWUpPjApIHsKICAgICAgbHN0cmNhdChzekNhcHRpb24sICIgLSBbIik7CiAgICAgIGxzdHJjYXQoc3pDYXB0aW9uLCBHbG9iYWxzLnN6RmlsZU5hbWUpOwogICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgIl0iKTsKICB9CiAgZWxzZQogIHsKICAgICAgTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX1VOVElUTEVELCBzelVudGl0bGVkLCBzaXplb2Yoc3pVbnRpdGxlZCkpOwogICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgIiAtICIpOwogICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgc3pVbnRpdGxlZCk7CiAgfQogICAgCiAgU2V0V2luZG93VGV4dChHbG9iYWxzLmhNYWluV25kLCBzekNhcHRpb24pOwogIAp9CgoKCnN0YXRpYyBCT09MIExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihVSU5UIG51bSwgVUlOVCBpZHMsIExQU1RSIHN0ciwgVUlOVCBsZW4pCnsKICBCT09MIGJPazsKCiAgaWRzIC09IEdsb2JhbHMud1N0cmluZ1RhYmxlT2Zmc2V0OwogIGlkcyArPSBudW0gKiAweDEwMDsKCiAgYk9rID0gTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgaWRzLCBzdHIsIGxlbik7CgogIHJldHVybihiT2spOwp9CgoKClZPSUQgTEFOR1VBR0VfU2VsZWN0QnlOYW1lKExQQ1NUUiBsYW5nKQp7CiAgSU5UIGk7CiAgQ0hBUiBuZXdsYW5nWzNdOwoKICBmb3IgKGkgPSAwOyBpIDw9IE1BWF9MQU5HVUFHRV9OVU1CRVI7IGkrKykKICAgIGlmIChMQU5HVUFHRV9Mb2FkU3RyaW5nT3RoZXIoaSwgSURTX0xBTkdVQUdFX0lELCBuZXdsYW5nLCBzaXplb2YobmV3bGFuZykpICYmCiAgICAgICAgIWxzdHJjbXAobGFuZywgbmV3bGFuZykpCiAgICAgIHsKICAgICAgICBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcihpKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgLyogRmFsbGJhY2sgKi8KICAgIGZvciAoaSA9IDA7IGkgPD0gTUFYX0xBTkdVQUdFX05VTUJFUjsgaSsrKQogICAgaWYgKExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihpLCBJRFNfTEFOR1VBR0VfSUQsIG5ld2xhbmcsIHNpemVvZihuZXdsYW5nKSkpCiAgICAgIHsKICAgICAgICBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcihpKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgTWVzc2FnZUJveChHbG9iYWxzLmhNYWluV25kLCAiTm8gbGFuZ3VhZ2UgZm91bmQiLCAiRkFUQUwgRVJST1IiLCBNQl9PSyk7CiAgUG9zdFF1aXRNZXNzYWdlKDEpOwp9CgpWT0lEIExBTkdVQUdFX1NlbGVjdEJ5TnVtYmVyKFVJTlQgbnVtKQp7CiAgSU5UICAgIGk7CiAgQ0hBUiAgIGxhbmdbM107CiAgQ0hBUiAgIGl0ZW1bTUFYX1NUUklOR19MRU5dOwogIEhNRU5VICBoTWFpbk1lbnU7CgogIC8qIFNlbGVjdCBzdHJpbmcgdGFibGUgKi8KICBHbG9iYWxzLndTdHJpbmdUYWJsZU9mZnNldCA9IG51bSAqIDB4MTAwOwoKICAvKiBHZXQgTGFuZ3VhZ2UgaWQgKi8KICBMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBJRFNfTEFOR1VBR0VfSUQsIGxhbmcsIHNpemVvZihsYW5nKSk7CiAgR2xvYmFscy5scHN6TGFuZ3VhZ2UgPSBsYW5nOwoKICAvKiBTZXQgZnJhbWUgY2FwdGlvbiAqLwogIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oKTsKICAKICAvKiBDaGFuZ2UgUmVzb3VyY2UgbmFtZXMgKi8KICBsc3RyY3B5bihTVFJJTkdfTUVOVV9YeCAgICAgICsgc2l6ZW9mKFNUUklOR19NRU5VX1h4KSAgICAgIC0gMywgbGFuZywgMyk7CiAgbHN0cmNweW4oU1RSSU5HX1BBR0VTRVRVUF9YeCArIHNpemVvZihTVFJJTkdfUEFHRVNFVFVQX1h4KSAtIDMsIGxhbmcsIDMpOwoKICAvKiBDcmVhdGUgbWVudSAqLwogIGhNYWluTWVudSA9IExvYWRNZW51KEdsb2JhbHMuaEluc3RhbmNlLCBTVFJJTkdfTUVOVV9YeCk7CiAgICBHbG9iYWxzLmhGaWxlTWVudSAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMCk7CiAgICBHbG9iYWxzLmhFZGl0TWVudSAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMSk7CiAgICBHbG9iYWxzLmhTZWFyY2hNZW51ICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMik7CiAgICBHbG9iYWxzLmhMYW5ndWFnZU1lbnUgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMyk7CiAgICBHbG9iYWxzLmhIZWxwTWVudSAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgNCk7CgogIC8qIFJlbW92ZSBkdW1teSBpdGVtICovCiAgUmVtb3ZlTWVudShHbG9iYWxzLmhMYW5ndWFnZU1lbnUsIDAsIE1GX0JZUE9TSVRJT04pOwogIC8qIEFkZCBsYW5ndWFnZSBpdGVtcyAqLwogIGZvciAoaSA9IDA7IGkgPD0gTUFYX0xBTkdVQUdFX05VTUJFUjsgaSsrKQogICAgaWYgKExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihpLCBJRFNfTEFOR1VBR0VfTUVOVV9JVEVNLCBpdGVtLCBzaXplb2YoaXRlbSkpKQogICAgICBBcHBlbmRNZW51KEdsb2JhbHMuaExhbmd1YWdlTWVudSwgTUZfU1RSSU5HIHwgTUZfQllDT01NQU5ELAogICAgICAgICAgICAgICAgIE5QX0ZJUlNUX0xBTkdVQUdFICsgaSwgaXRlbSk7CgogIFNldE1lbnUoR2xvYmFscy5oTWFpblduZCwgaE1haW5NZW51KTsKCiAgLyogRGVzdHJveSBvbGQgbWVudSAqLwogIGlmIChHbG9iYWxzLmhNYWluTWVudSkgRGVzdHJveU1lbnUoR2xvYmFscy5oTWFpbk1lbnUpOwogIEdsb2JhbHMuaE1haW5NZW51ID0gaE1haW5NZW51Owp9CgpWT0lEIExBTkdVQUdFX0RlZmF1bHRIYW5kbGUoV1BBUkFNIHdQYXJhbSkKewogIGlmICgod1BhcmFtID49TlBfRklSU1RfTEFOR1VBR0UpICYmICh3UGFyYW08PU5QX0xBU1RfTEFOR1VBR0UpKQogICAgICAgICAgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIod1BhcmFtIC0gTlBfRklSU1RfTEFOR1VBR0UpOwogICAgIGVsc2UgcHJpbnRmKCJVbmltcGxlbWVudGVkIG1lbnUgY29tbWFuZCAlaVxuIiwgd1BhcmFtKTsKfQoKVk9JRCBMQU5HVUFHRV9Jbml0KFZPSUQpCnsKICBDSEFSIGJ1ZmZlcltNQVhfUEFUSE5BTUVfTEVOXSwgKnA7CgojaWZuZGVmIExDQwogICAgUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCJwcm9ncmFtcyIsICJsYW5ndWFnZSIsICJsYW5ndWFnZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpOwojZW5kaWYKICBHbG9iYWxzLmxwc3pMYW5ndWFnZSA9IHAgPSBMb2NhbExvY2soTG9jYWxBbGxvYyhMTUVNX0ZJWEVELCBsc3RybGVuKGJ1ZmZlcikrMSkpOwogIHN0cmNweShwLCBidWZmZXIpOwogIC8qIGhtZW1jcHkocCwgYnVmZmVyLCAxICsgbHN0cmxlbihidWZmZXIpKTsgKi8KfQoK