LyoKICogQ2xvY2sKICoKICogQ29weXJpZ2h0IDE5OTggTWFyY2VsIEJhdXIgPG1iYXVyQGcyNi5ldGh6LmNoPgogKiBDb3B5cmlnaHQgMTk5OCBLYXJsIEJhY2tzdHL2bSA8a2FybF9iQGdlb2NpdGllcy5jb20+CiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJtYWluLmgiCiNpbmNsdWRlICJsYW5ndWFnZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCgpDSEFSIFNUUklOR19NRU5VX1h4W10gICAgICA9ICJNRU5VX1h4IjsKClZPSUQgTEFOR1VBR0VfVXBkYXRlTWVudUNoZWNrbWFya3MoVk9JRCkgewoKICAgIGlmKEdsb2JhbHMuYkFuYWxvZyA9PSBUUlVFKSB7CiAgICAKICAgICAgICAvKiBhbmFsb2cgY2xvY2sgKi8KICAgICAgICAKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCBDTF9BTkFMT0csIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9DSEVDS0VEKTsKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCBDTF9ESUdJVEFMLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfVU5DSEVDS0VEKTsKICAgICAgICBFbmFibGVNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfRk9OVCwgXAogICAgICAgICAgICAgICAgICAgICAgIE1GX0JZQ09NTUFORCB8IE1GX0dSQVlFRCk7CiAgICB9CiAgICAgICAgZWxzZSAKICAgIHsKICAgIAogICAgICAgIC8qIGRpZ2l0YWwgY2xvY2sgKi8KICAgICAgICAKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCBDTF9BTkFMT0csIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9VTkNIRUNLRUQpOwogICAgICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIENMX0RJR0lUQUwsIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9DSEVDS0VEKTsKICAgICAgICBFbmFibGVNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfRk9OVCwgXAogICAgICAgICAgICAgICAgICAgICAgIE1GX0JZQ09NTUFORCk7CiAgICAgICAgICAgICAgICAgICAgICAgCiAgICB9CiAgICAKICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIENMX1dJVEhPVVRfVElUTEUsIE1GX0JZQ09NTUFORCB8IFwKICAgICAgICAgICAgICAgICAoR2xvYmFscy5iV2l0aG91dFRpdGxlID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhTeXN0ZW1NZW51LCBDTF9PTl9UT1AsIE1GX0JZQ09NTUFORCB8IFwKICAgICAgICAgICAgICAgICAoR2xvYmFscy5iQWx3YXlzT25Ub3AgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEKSk7CiAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCBDTF9TRUNPTkRTLCBNRl9CWUNPTU1BTkQgfCBcCiAgICAgICAgICAgICAgICAgKEdsb2JhbHMuYlNlY29uZHMgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEKSk7CiAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCBDTF9EQVRFLCBNRl9CWUNPTU1BTkQgfCBcCiAgICAgICAgICAgICAgICAgKEdsb2JhbHMuYkRhdGUgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEKSk7Cn0KClZPSUQgTEFOR1VBR0VfVXBkYXRlV2luZG93Q2FwdGlvbihWT0lEKSB7CgogIENIQVIgc3pDYXB0aW9uW01BWF9TVFJJTkdfTEVOXTsKICBDSEFSIHN6RGF0ZVtNQVhfU1RSSU5HX0xFTl07CiAgCiAgTFBTVFIgZGF0ZSA9IHN6RGF0ZTsKICAKICBTWVNURU1USU1FIHN0OwogIExQU1lTVEVNVElNRSBscHN0ID0gJnN0OwoKICBHZXRMb2NhbFRpbWUoJnN0KTsKICBHZXREYXRlRm9ybWF0KExPQ0FMRV9VU0VSX0RFRkFVTFQsIExPQ0FMRV9TTE9OR0RBVEUsIGxwc3QsIE5VTEwsIGRhdGUsCiAgICAgICAgICAgICAgICBNQVhfU1RSSU5HX0xFTik7CgogIC8qIFNldCBmcmFtZSBjYXB0aW9uICovCiAgTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX0NMT0NLLCBzekNhcHRpb24sIHNpemVvZihzekNhcHRpb24pKTsKICBpZiAoR2xvYmFscy5iRGF0ZSkgewogICAgIGxzdHJjYXQoc3pDYXB0aW9uLCAiIC0gIik7CiAgICAgbHN0cmNhdChzekNhcHRpb24sIHN6RGF0ZSk7CiAgfQogIFNldFdpbmRvd1RleHQoR2xvYmFscy5oTWFpblduZCwgc3pDYXB0aW9uKTsKCn0KCgoKc3RhdGljIEJPT0wgTEFOR1VBR0VfTG9hZFN0cmluZ090aGVyKFVJTlQgbnVtLCBVSU5UIGlkcywgTFBTVFIgc3RyLCBVSU5UIGxlbikKewogIGlkcyAtPSBHbG9iYWxzLndTdHJpbmdUYWJsZU9mZnNldDsKICBpZHMgKz0gbnVtICogMHgxMDA7CiAgcmV0dXJuKExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIGlkcywgc3RyLCBsZW4pKTsKfTsKClZPSUQgTEFOR1VBR0VfU2VsZWN0QnlOYW1lKExQQ1NUUiBsYW5nKQp7CiAgSU5UIGk7CiAgQ0hBUiBzek5ld0xhbmdbM107CgogIGZvciAoaSA9IDA7IGkgPD0gTUFYX0xBTkdVQUdFX05VTUJFUjsgaSsrKQogICAgaWYgKExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihpLCBJRFNfTEFOR1VBR0VfSUQsIHN6TmV3TGFuZywgCiAgICAgICAgICAgICAgICBzaXplb2Yoc3pOZXdMYW5nKSkgJiYgIWxzdHJjbXAobGFuZywgc3pOZXdMYW5nKSkKICAgICAgewogICAgICAgIExBTkdVQUdFX1NlbGVjdEJ5TnVtYmVyKGkpOwogICAgICAgIHJldHVybjsKICAgICAgfQoKICAvKiBGYWxsYmFjayAqLwogICAgZm9yIChpID0gMDsgaSA8PSBNQVhfTEFOR1VBR0VfTlVNQkVSOyBpKyspCiAgICBpZiAoTEFOR1VBR0VfTG9hZFN0cmluZ090aGVyKGksIElEU19MQU5HVUFHRV9JRCwgc3pOZXdMYW5nLCBzaXplb2Yoc3pOZXdMYW5nKSkpCiAgICAgIHsKICAgICAgICBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcihpKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICBNZXNzYWdlQm94KEdsb2JhbHMuaE1haW5XbmQsICJObyBsYW5ndWFnZSBmb3VuZCIsICJGQVRBTCBFUlJPUiIsIE1CX09LKTsKICAgIFBvc3RRdWl0TWVzc2FnZSgxKTsKfQoKVk9JRCBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcihVSU5UIG51bSkKewogIElOVCAgICBpOwogIENIQVIgICBzekxhbmd1YWdlWzNdOwoKICBDSEFSICAgc3pJdGVtW01BWF9TVFJJTkdfTEVOXTsKICBITUVOVSAgaE1haW5NZW51OwoKICAvKiBTZWxlY3Qgc3RyaW5nIHRhYmxlICovCiAgR2xvYmFscy53U3RyaW5nVGFibGVPZmZzZXQgPSBudW0gKiAweDEwMDsKCiAgLyogR2V0IExhbmd1YWdlIGlkICovCiAgTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX0xBTkdVQUdFX0lELCBzekxhbmd1YWdlLCBzaXplb2Yoc3pMYW5ndWFnZSkpOwoKICAvKiBDaGFuZ2UgUmVzb3VyY2UgbmFtZXMgKi8KICBsc3RyY3B5bihTVFJJTkdfTUVOVV9YeCArIHNpemVvZihTVFJJTkdfTUVOVV9YeCkgLSAzLCBzekxhbmd1YWdlLCAzKTsKCiAgLyogQ3JlYXRlIG1lbnUgKi8KICBoTWFpbk1lbnUgPSBMb2FkTWVudShHbG9iYWxzLmhJbnN0YW5jZSwgU1RSSU5HX01FTlVfWHgpOwogICAgR2xvYmFscy5oUHJvcGVydGllc01lbnUgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDApOwogICAgR2xvYmFscy5oTGFuZ3VhZ2VNZW51ICAgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDEpOwogICAgR2xvYmFscy5oSW5mb01lbnUgICAgICAgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDIpOwoKICAvKiBSZW1vdmUgZHVtbXkgaXRlbSAqLwogIFJlbW92ZU1lbnUoR2xvYmFscy5oTGFuZ3VhZ2VNZW51LCAwLCBNRl9CWVBPU0lUSU9OKTsKICAvKiBBZGQgbGFuZ3VhZ2UgaXRlbXMgKi8KICBmb3IgKGkgPSAwOyBpIDw9IE1BWF9MQU5HVUFHRV9OVU1CRVI7IGkrKykKICAgIGlmIChMQU5HVUFHRV9Mb2FkU3RyaW5nT3RoZXIoaSwgSURTX0xBTkdVQUdFX01FTlVfSVRFTSwgc3pJdGVtLCBzaXplb2Yoc3pJdGVtKSkpCiAgICAgICAgICAgICBBcHBlbmRNZW51KEdsb2JhbHMuaExhbmd1YWdlTWVudSwgTUZfU1RSSU5HIHwgTUZfQllDT01NQU5ELAogICAgICAgICAgICAgICAgICAgICAgICBDTF9GSVJTVF9MQU5HVUFHRSArIGksIHN6SXRlbSk7CiAgRW5hYmxlTWVudUl0ZW0oR2xvYmFscy5oTGFuZ3VhZ2VNZW51LCBDTF9GSVJTVF9MQU5HVUFHRSArIG51bSwgTUZfQllDT01NQU5EIHwgTUZfQ0hFQ0tFRCk7CgogIFNldE1lbnUoR2xvYmFscy5oTWFpblduZCwgaE1haW5NZW51KTsKCiAgLyogRGVzdHJveSBvbGQgbWVudSAqLwogIGlmIChHbG9iYWxzLmhNYWluTWVudSkgRGVzdHJveU1lbnUoR2xvYmFscy5oTWFpbk1lbnUpOwogIEdsb2JhbHMuaE1haW5NZW51ID0gaE1haW5NZW51OwoKICAvKiBzcGVjaWZpYyBmb3IgQ2xvY2s6ICovCgogIExBTkdVQUdFX1VwZGF0ZU1lbnVDaGVja21hcmtzKCk7CiAgTEFOR1VBR0VfVXBkYXRlV2luZG93Q2FwdGlvbigpOyAgIAoKICBHbG9iYWxzLmhTeXN0ZW1NZW51ID0gR2V0U3lzdGVtTWVudShHbG9iYWxzLmhNYWluV25kLCBUUlVFKTsKCiAgLyogRklYTUU6IEFwcGVuZCBhIFNFUEFSQVRPUiB0byBHbG9iYWxzLmhTeXN0ZW1NZW51IGhlcmUgKi8KCiAgTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX01FTlVfT05fVE9QLCBzekl0ZW0sIHNpemVvZihzekl0ZW0pKTsKICBBcHBlbmRNZW51KEdsb2JhbHMuaFN5c3RlbU1lbnUsIE1GX1NUUklORyB8IE1GX0JZQ09NTUFORCwgMTAwMCwgc3pJdGVtKTsKfQoKVk9JRCBMQU5HVUFHRV9EZWZhdWx0SGFuZGxlKFdQQVJBTSB3UGFyYW0pCnsKICBpZiAoKHdQYXJhbSA+PUNMX0ZJUlNUX0xBTkdVQUdFKSAmJiAod1BhcmFtPD1DTF9MQVNUX0xBTkdVQUdFKSkKICAgICAgICAgIExBTkdVQUdFX1NlbGVjdEJ5TnVtYmVyKHdQYXJhbSAtIENMX0ZJUlNUX0xBTkdVQUdFKTsKICAgICBlbHNlIHByaW50ZigiVW5pbXBsZW1lbnRlZCBtZW51IGNvbW1hbmQgJWlcbiIsIHdQYXJhbSk7Cn0KCi8qIExvY2FsIFZhcmlhYmxlczogICAgKi8KLyogYy1maWxlLXN0eWxlOiAiR05VIiAqLwovKiBFbmQ6ICAgICAgICAgICAgICAgICovCg==