LyoKICogQ2xvY2sKICoKICogQ29weXJpZ2h0IDE5OTggTWFyY2VsIEJhdXIgPG1iYXVyQGcyNi5ldGh6LmNoPgogKiBDb3B5cmlnaHQgMTk5OCBLYXJsIEJhY2tzdHL2bSA8a2FybF9iQGdlb2NpdGllcy5jb20+CiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAibWFpbi5oIgojaW5jbHVkZSAibGFuZ3VhZ2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgoKQ0hBUiBTVFJJTkdfTUVOVV9YeFtdICAgICAgPSAiTUVOVV9YeCI7CgpWT0lEIExBTkdVQUdFX1VwZGF0ZU1lbnVDaGVja21hcmtzKFZPSUQpCnsKICAgIGlmKEdsb2JhbHMuYkFuYWxvZyA9PSBUUlVFKSB7CgogICAgICAgIC8qIGFuYWxvZyBjbG9jayAqLwoKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwMCwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9DSEVDS0VEKTsKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwMSwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9VTkNIRUNLRUQpOwogICAgICAgIEVuYWJsZU1lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwMywKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9HUkFZRUQpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8qIGRpZ2l0YWwgY2xvY2sgKi8KCiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgMHgxMDAsCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfVU5DSEVDS0VEKTsKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwMSwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9DSEVDS0VEKTsKICAgICAgICBFbmFibGVNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgMHgxMDMsCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EKTsKICAgIH0KCiAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwNSwgTUZfQllDT01NQU5EIHwKICAgICAgICAgICAgICAgICAoR2xvYmFscy5iV2l0aG91dFRpdGxlID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhTeXN0ZW1NZW51LCAweDEwRCwgTUZfQllDT01NQU5EIHwKICAgICAgICAgICAgICAgICAoR2xvYmFscy5iQWx3YXlzT25Ub3AgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEKSk7CiAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwNywgTUZfQllDT01NQU5EIHwKICAgICAgICAgICAgICAgICAoR2xvYmFscy5iU2Vjb25kcyA/IE1GX0NIRUNLRUQgOiBNRl9VTkNIRUNLRUQpKTsKICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIDB4MTA4LCBNRl9CWUNPTU1BTkQgfAogICAgICAgICAgICAgICAgIChHbG9iYWxzLmJEYXRlID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwp9CgpWT0lEIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oVk9JRCkKewogICAgQ0hBUiBzekNhcHRpb25bTUFYX1NUUklOR19MRU5dOwogICAgQ0hBUiBzekRhdGVbTUFYX1NUUklOR19MRU5dOwoKICAgIExQU1RSIGRhdGUgPSBzekRhdGU7CgogICAgU1lTVEVNVElNRSBzdDsKICAgIExQU1lTVEVNVElNRSBscHN0ID0gJnN0OwoKICAgIEdldExvY2FsVGltZSgmc3QpOwogICAgR2V0RGF0ZUZvcm1hdChMT0NBTEVfVVNFUl9ERUZBVUxULCBMT0NBTEVfU0xPTkdEQVRFLCBscHN0LCBOVUxMLCBkYXRlLAogICAgICAgICAgICAgICAgICBNQVhfU1RSSU5HX0xFTik7CgogICAgLyogU2V0IGZyYW1lIGNhcHRpb24gKi8KICAgIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIDB4MTBDLCBzekNhcHRpb24sIHNpemVvZihzekNhcHRpb24pKTsKICAgIGlmIChHbG9iYWxzLmJEYXRlKSB7CiAgICAgICAgbHN0cmNhdChzekNhcHRpb24sICIgLSAiKTsKICAgICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgc3pEYXRlKTsKICAgIH0KICAgIFNldFdpbmRvd1RleHQoR2xvYmFscy5oTWFpblduZCwgc3pDYXB0aW9uKTsKfQoKVk9JRCBMQU5HVUFHRV9Mb2FkTWVudXMoVk9JRCkKewogICAgQ0hBUiAgIHN6SXRlbVtNQVhfU1RSSU5HX0xFTl07CiAgICBITUVOVSAgaE1haW5NZW51OwoKICAgIC8qIENyZWF0ZSBtZW51ICovCiAgICBoTWFpbk1lbnUgPSBMb2FkTWVudShHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKE1BSU5fTUVOVSkpOwogICAgR2xvYmFscy5oUHJvcGVydGllc01lbnUgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDApOwogICAgR2xvYmFscy5oTGFuZ3VhZ2VNZW51ICAgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDEpOwogICAgR2xvYmFscy5oSW5mb01lbnUgICAgICAgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDIpOwogICAgCiAgICBTZXRNZW51KEdsb2JhbHMuaE1haW5XbmQsIGhNYWluTWVudSk7CgogICAgLyogRGVzdHJveSBvbGQgbWVudSAqLwogICAgaWYgKEdsb2JhbHMuaE1haW5NZW51KSBEZXN0cm95TWVudShHbG9iYWxzLmhNYWluTWVudSk7CiAgICBHbG9iYWxzLmhNYWluTWVudSA9IGhNYWluTWVudTsKCiAgICAvKiBzcGVjaWZpYyBmb3IgQ2xvY2s6ICovCgogICAgTEFOR1VBR0VfVXBkYXRlTWVudUNoZWNrbWFya3MoKTsKICAgIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oKTsKCiAgICBHbG9iYWxzLmhTeXN0ZW1NZW51ID0gR2V0U3lzdGVtTWVudShHbG9iYWxzLmhNYWluV25kLCBUUlVFKTsKICAgIAogICAgLyogRklYTUU6IEFwcGVuZCBhIFNFUEFSQVRPUiB0byBHbG9iYWxzLmhTeXN0ZW1NZW51IGhlcmUgKi8KCiAgICBMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCAweDEwRCwgc3pJdGVtLCBzaXplb2Yoc3pJdGVtKSk7CiAgICBBcHBlbmRNZW51KEdsb2JhbHMuaFN5c3RlbU1lbnUsIE1GX1NUUklORyB8IE1GX0JZQ09NTUFORCwgMTAwMCwgc3pJdGVtKTsKfQoKLyoKVk9JRCBMQU5HVUFHRV9EZWZhdWx0SGFuZGxlKFdQQVJBTSB3UGFyYW0pCnsKICAgIGlmICgod1BhcmFtID49Q0xfRklSU1RfTEFOR1VBR0UpICYmICh3UGFyYW08PUNMX0xBU1RfTEFOR1VBR0UpKQogICAgICAgIExBTkdVQUdFX1NlbGVjdEJ5TnVtYmVyKHdQYXJhbSAtIENMX0ZJUlNUX0xBTkdVQUdFKTsKICAgIGVsc2UgCiAgICAgICAgcHJpbnRmKCJVbmltcGxlbWVudGVkIG1lbnUgY29tbWFuZCAlaVxuIiwgd1BhcmFtKTsKfQoqLwoKLyogTG9jYWwgVmFyaWFibGVzOiAgICAqLwovKiBjLWZpbGUtc3R5bGU6ICJHTlUiICovCi8qIEVuZDogICAgICAgICAgICAgICAgKi8K