LyoKICogQ2xvY2sKICoKICogQ29weXJpZ2h0IDE5OTggTWFyY2VsIEJhdXIgPG1iYXVyQGcyNi5ldGh6LmNoPgogKiBDb3B5cmlnaHQgMTk5OCBLYXJsIEJhY2tzdHL2bSA8a2FybF9iQGdlb2NpdGllcy5jb20+CiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAibWFpbi5oIgojaW5jbHVkZSAibGFuZ3VhZ2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgoKQ0hBUiBTVFJJTkdfTUVOVV9YeFtdICAgICAgPSAiTUVOVV9YeCI7CgpWT0lEIExBTkdVQUdFX1VwZGF0ZU1lbnVDaGVja21hcmtzKFZPSUQpIHsKCiAgICBpZihHbG9iYWxzLmJBbmFsb2cgPT0gVFJVRSkgewoKICAgICAgICAvKiBhbmFsb2cgY2xvY2sgKi8KCiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgMHgxMDAsIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9DSEVDS0VEKTsKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwMSwgXAogICAgICAgICAgICAgICAgICAgICAgIE1GX0JZQ09NTUFORCB8IE1GX1VOQ0hFQ0tFRCk7CiAgICAgICAgRW5hYmxlTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIDB4MTAzLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfR1JBWUVEKTsKICAgIH0KICAgICAgICBlbHNlCiAgICB7CgogICAgICAgIC8qIGRpZ2l0YWwgY2xvY2sgKi8KCiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgMHgxMDAsIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9VTkNIRUNLRUQpOwogICAgICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIDB4MTAxLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfQ0hFQ0tFRCk7CiAgICAgICAgRW5hYmxlTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIDB4MTAzLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EKTsKCiAgICB9CgogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgMHgxMDUsIE1GX0JZQ09NTUFORCB8IFwKICAgICAgICAgICAgICAgICAoR2xvYmFscy5iV2l0aG91dFRpdGxlID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhTeXN0ZW1NZW51LCAweDEwRCwgTUZfQllDT01NQU5EIHwgXAogICAgICAgICAgICAgICAgIChHbG9iYWxzLmJBbHdheXNPblRvcCA/IE1GX0NIRUNLRUQgOiBNRl9VTkNIRUNLRUQpKTsKICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIDB4MTA3LCBNRl9CWUNPTU1BTkQgfCBcCiAgICAgICAgICAgICAgICAgKEdsb2JhbHMuYlNlY29uZHMgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEKSk7CiAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwOCwgTUZfQllDT01NQU5EIHwgXAogICAgICAgICAgICAgICAgIChHbG9iYWxzLmJEYXRlID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwp9CgpWT0lEIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oVk9JRCkgewoKICBDSEFSIHN6Q2FwdGlvbltNQVhfU1RSSU5HX0xFTl07CiAgQ0hBUiBzekRhdGVbTUFYX1NUUklOR19MRU5dOwoKICBMUFNUUiBkYXRlID0gc3pEYXRlOwoKICBTWVNURU1USU1FIHN0OwogIExQU1lTVEVNVElNRSBscHN0ID0gJnN0OwoKICBHZXRMb2NhbFRpbWUoJnN0KTsKICBHZXREYXRlRm9ybWF0KExPQ0FMRV9VU0VSX0RFRkFVTFQsIExPQ0FMRV9TTE9OR0RBVEUsIGxwc3QsIE5VTEwsIGRhdGUsCiAgICAgICAgICAgICAgICBNQVhfU1RSSU5HX0xFTik7CgogIC8qIFNldCBmcmFtZSBjYXB0aW9uICovCiAgTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgMHgxMEMsIHN6Q2FwdGlvbiwgc2l6ZW9mKHN6Q2FwdGlvbikpOwogIGlmIChHbG9iYWxzLmJEYXRlKSB7CiAgICAgbHN0cmNhdChzekNhcHRpb24sICIgLSAiKTsKICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgc3pEYXRlKTsKICB9CiAgU2V0V2luZG93VGV4dChHbG9iYWxzLmhNYWluV25kLCBzekNhcHRpb24pOwoKfQoKVk9JRCBMQU5HVUFHRV9Mb2FkTWVudXMoVk9JRCkKewoKICBDSEFSICAgc3pJdGVtW01BWF9TVFJJTkdfTEVOXTsKICBITUVOVSAgaE1haW5NZW51OwoKCiAgLyogQ3JlYXRlIG1lbnUgKi8KICBoTWFpbk1lbnUgPSBMb2FkTWVudShHbG9iYWxzLmhJbnN0YW5jZSwgTUFJTl9NRU5VKTsKICAgIEdsb2JhbHMuaFByb3BlcnRpZXNNZW51ICAgICA9IEdldFN1Yk1lbnUoaE1haW5NZW51LCAwKTsKICAgIEdsb2JhbHMuaExhbmd1YWdlTWVudSAgICAgICA9IEdldFN1Yk1lbnUoaE1haW5NZW51LCAxKTsKICAgIEdsb2JhbHMuaEluZm9NZW51ICAgICAgICAgICA9IEdldFN1Yk1lbnUoaE1haW5NZW51LCAyKTsKCiAgU2V0TWVudShHbG9iYWxzLmhNYWluV25kLCBoTWFpbk1lbnUpOwoKICAvKiBEZXN0cm95IG9sZCBtZW51ICovCiAgaWYgKEdsb2JhbHMuaE1haW5NZW51KSBEZXN0cm95TWVudShHbG9iYWxzLmhNYWluTWVudSk7CiAgR2xvYmFscy5oTWFpbk1lbnUgPSBoTWFpbk1lbnU7CgogIC8qIHNwZWNpZmljIGZvciBDbG9jazogKi8KCiAgTEFOR1VBR0VfVXBkYXRlTWVudUNoZWNrbWFya3MoKTsKICBMQU5HVUFHRV9VcGRhdGVXaW5kb3dDYXB0aW9uKCk7CgogIEdsb2JhbHMuaFN5c3RlbU1lbnUgPSBHZXRTeXN0ZW1NZW51KEdsb2JhbHMuaE1haW5XbmQsIFRSVUUpOwoKICAvKiBGSVhNRTogQXBwZW5kIGEgU0VQQVJBVE9SIHRvIEdsb2JhbHMuaFN5c3RlbU1lbnUgaGVyZSAqLwoKICBMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCAweDEwRCwgc3pJdGVtLCBzaXplb2Yoc3pJdGVtKSk7CiAgQXBwZW5kTWVudShHbG9iYWxzLmhTeXN0ZW1NZW51LCBNRl9TVFJJTkcgfCBNRl9CWUNPTU1BTkQsIDEwMDAsIHN6SXRlbSk7Cn0KCi8qClZPSUQgTEFOR1VBR0VfRGVmYXVsdEhhbmRsZShXUEFSQU0gd1BhcmFtKQp7CiAgaWYgKCh3UGFyYW0gPj1DTF9GSVJTVF9MQU5HVUFHRSkgJiYgKHdQYXJhbTw9Q0xfTEFTVF9MQU5HVUFHRSkpCiAgICAgICAgICBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcih3UGFyYW0gLSBDTF9GSVJTVF9MQU5HVUFHRSk7CiAgICAgZWxzZSBwcmludGYoIlVuaW1wbGVtZW50ZWQgbWVudSBjb21tYW5kICVpXG4iLCB3UGFyYW0pOwp9CiovCgovKiBMb2NhbCBWYXJpYWJsZXM6ICAgICovCi8qIGMtZmlsZS1zdHlsZTogIkdOVSIgKi8KLyogRW5kOiAgICAgICAgICAgICAgICAqLwo=