Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBVcHNhbXBsaW5nIC8gZG93bnNhbXBsaW5nIHJvdXRpbmUKLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIC0gQ2Fyc3RlbiBLbGVpbiAoY2tsZWluMDVAdXNlcnMuc291cmNlZm9yZ2UubmV0KQovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiBGcmVlSW1hZ2UgMwovLwovLyBDT1ZFUkVEIENPREUgSVMgUFJPVklERUQgVU5ERVIgVEhJUyBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVFkKLy8gT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFdBUlJBTlRJRVMKLy8gVEhBVCBUSEUgQ09WRVJFRCBDT0RFIElTIEZSRUUgT0YgREVGRUNUUywgTUVSQ0hBTlRBQkxFLCBGSVQgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi8vIE9SIE5PTi1JTkZSSU5HSU5HLiBUSEUgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBDT1ZFUkVECi8vIENPREUgSVMgV0lUSCBZT1UuIFNIT1VMRCBBTlkgQ09WRVJFRCBDT0RFIFBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgWU9VIChOT1QKLy8gVEhFIElOSVRJQUwgREVWRUxPUEVSIE9SIEFOWSBPVEhFUiBDT05UUklCVVRPUikgQVNTVU1FIFRIRSBDT1NUIE9GIEFOWSBORUNFU1NBUlkKLy8gU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOIEVTU0VOVElBTAovLyBQQVJUIE9GIFRISVMgTElDRU5TRS4gTk8gVVNFIE9GIEFOWSBDT1ZFUkVEIENPREUgSVMgQVVUSE9SSVpFRCBIRVJFVU5ERVIgRVhDRVBUIFVOREVSCi8vIFRISVMgRElTQ0xBSU1FUi4KLy8KLy8gVXNlIGF0IHlvdXIgb3duIHJpc2shCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpbmNsdWRlICJSZXNpemUuaCIKCkZJQklUTUFQICogRExMX0NBTExDT05WCkZyZWVJbWFnZV9SZXNjYWxlUmVjdChGSUJJVE1BUCAqc3JjLCBpbnQgZHN0X3dpZHRoLCBpbnQgZHN0X2hlaWdodCwgaW50IHNyY19sZWZ0LCBpbnQgc3JjX3RvcCwgaW50IHNyY19yaWdodCwgaW50IHNyY19ib3R0b20sIEZSRUVfSU1BR0VfRklMVEVSIGZpbHRlciwgdW5zaWduZWQgZmxhZ3MpIHsKCUZJQklUTUFQICpkc3QgPSBOVUxMOwoKCWNvbnN0IGludCBzcmNfd2lkdGggPSBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsKCWNvbnN0IGludCBzcmNfaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChzcmMpOwoKCWlmICghRnJlZUltYWdlX0hhc1BpeGVscyhzcmMpIHx8IChkc3Rfd2lkdGggPD0gMCkgfHwgKGRzdF9oZWlnaHQgPD0gMCkgfHwgKHNyY193aWR0aCA8PSAwKSB8fCAoc3JjX2hlaWdodCA8PSAwKSkgewoJCXJldHVybiBOVUxMOwoJfQoKCS8vIG5vcm1hbGl6ZSB0aGUgcmVjdGFuZ2xlCglpZiAoc3JjX3JpZ2h0IDwgc3JjX2xlZnQpIHsKCQlJTlBMQUNFU1dBUChzcmNfbGVmdCwgc3JjX3JpZ2h0KTsKCX0KCWlmIChzcmNfYm90dG9tIDwgc3JjX3RvcCkgewoJCUlOUExBQ0VTV0FQKHNyY190b3AsIHNyY19ib3R0b20pOwoJfQoKCS8vIGNoZWNrIHRoZSBzaXplIG9mIHRoZSBzdWIgaW1hZ2UKCWlmKChzcmNfbGVmdCA8IDApIHx8IChzcmNfcmlnaHQgPiBzcmNfd2lkdGgpIHx8IChzcmNfdG9wIDwgMCkgfHwgKHNyY19ib3R0b20gPiBzcmNfaGVpZ2h0KSkgewoJCXJldHVybiBOVUxMOwoJfQoKCS8vIHNlbGVjdCB0aGUgZmlsdGVyCglDR2VuZXJpY0ZpbHRlciAqcEZpbHRlciA9IE5VTEw7Cglzd2l0Y2ggKGZpbHRlcikgewoJCWNhc2UgRklMVEVSX0JPWDoKCQkJcEZpbHRlciA9IG5ldyhzdGQ6Om5vdGhyb3cpIENCb3hGaWx0ZXIoKTsKCQkJYnJlYWs7CgkJY2FzZSBGSUxURVJfQklDVUJJQzoKCQkJcEZpbHRlciA9IG5ldyhzdGQ6Om5vdGhyb3cpIENCaWN1YmljRmlsdGVyKCk7CgkJCWJyZWFrOwoJCWNhc2UgRklMVEVSX0JJTElORUFSOgoJCQlwRmlsdGVyID0gbmV3KHN0ZDo6bm90aHJvdykgQ0JpbGluZWFyRmlsdGVyKCk7CgkJCWJyZWFrOwoJCWNhc2UgRklMVEVSX0JTUExJTkU6CgkJCXBGaWx0ZXIgPSBuZXcoc3RkOjpub3Rocm93KSBDQlNwbGluZUZpbHRlcigpOwoJCQlicmVhazsKCQljYXNlIEZJTFRFUl9DQVRNVUxMUk9NOgoJCQlwRmlsdGVyID0gbmV3KHN0ZDo6bm90aHJvdykgQ0NhdG11bGxSb21GaWx0ZXIoKTsKCQkJYnJlYWs7CgkJY2FzZSBGSUxURVJfTEFOQ1pPUzM6CgkJCXBGaWx0ZXIgPSBuZXcoc3RkOjpub3Rocm93KSBDTGFuY3pvczNGaWx0ZXIoKTsKCQkJYnJlYWs7Cgl9CgoJaWYgKCFwRmlsdGVyKSB7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJQ1Jlc2l6ZUVuZ2luZSBFbmdpbmUocEZpbHRlcik7CgoJZHN0ID0gRW5naW5lLnNjYWxlKHNyYywgZHN0X3dpZHRoLCBkc3RfaGVpZ2h0LCBzcmNfbGVmdCwgc3JjX3RvcCwKCQkJc3JjX3JpZ2h0IC0gc3JjX2xlZnQsIHNyY19ib3R0b20gLSBzcmNfdG9wLCBmbGFncyk7CgoJZGVsZXRlIHBGaWx0ZXI7CgoJaWYgKChmbGFncyAmIEZJX1JFU0NBTEVfT01JVF9NRVRBREFUQSkgIT0gRklfUkVTQ0FMRV9PTUlUX01FVEFEQVRBKSB7CgkJLy8gY29weSBtZXRhZGF0YSBmcm9tIHNyYyB0byBkc3QKCQlGcmVlSW1hZ2VfQ2xvbmVNZXRhZGF0YShkc3QsIHNyYyk7Cgl9CgoJcmV0dXJuIGRzdDsKfQoKRklCSVRNQVAgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX1Jlc2NhbGUoRklCSVRNQVAgKnNyYywgaW50IGRzdF93aWR0aCwgaW50IGRzdF9oZWlnaHQsIEZSRUVfSU1BR0VfRklMVEVSIGZpbHRlcikgewoJcmV0dXJuIEZyZWVJbWFnZV9SZXNjYWxlUmVjdChzcmMsIGRzdF93aWR0aCwgZHN0X2hlaWdodCwgMCwgMCwgRnJlZUltYWdlX0dldFdpZHRoKHNyYyksIEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjKSwgZmlsdGVyLCBGSV9SRVNDQUxFX0RFRkFVTFQpOwp9CgpGSUJJVE1BUCAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfTWFrZVRodW1ibmFpbChGSUJJVE1BUCAqZGliLCBpbnQgbWF4X3BpeGVsX3NpemUsIEJPT0wgY29udmVydCkgewoJRklCSVRNQVAgKnRodW1ibmFpbCA9IE5VTEw7CglpbnQgbmV3X3dpZHRoLCBuZXdfaGVpZ2h0OwoKCWlmKCFGcmVlSW1hZ2VfSGFzUGl4ZWxzKGRpYikgfHwgKG1heF9waXhlbF9zaXplIDw9IDApKSByZXR1cm4gTlVMTDsKCglpbnQgd2lkdGgJPSBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKTsKCWludCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7CgoJaWYobWF4X3BpeGVsX3NpemUgPT0gMCkgbWF4X3BpeGVsX3NpemUgPSAxOwoKCWlmKCh3aWR0aCA8IG1heF9waXhlbF9zaXplKSAmJiAoaGVpZ2h0IDwgbWF4X3BpeGVsX3NpemUpKSB7CgkJLy8gaW1hZ2UgaXMgc21hbGxlciB0aGFuIHRoZSByZXF1ZXN0ZWQgdGh1bWJuYWlsCgkJcmV0dXJuIEZyZWVJbWFnZV9DbG9uZShkaWIpOwoJfQoKCWlmKHdpZHRoID4gaGVpZ2h0KSB7CgkJbmV3X3dpZHRoID0gbWF4X3BpeGVsX3NpemU7CgkJLy8gY2hhbmdlIGltYWdlIGhlaWdodCB3aXRoIHRoZSBzYW1lIHJhdGlvCgkJZG91YmxlIHJhdGlvID0gKChkb3VibGUpbmV3X3dpZHRoIC8gKGRvdWJsZSl3aWR0aCk7CgkJbmV3X2hlaWdodCA9IChpbnQpKGhlaWdodCAqIHJhdGlvICsgMC41KTsKCQlpZihuZXdfaGVpZ2h0ID09IDApIG5ld19oZWlnaHQgPSAxOwoJfSBlbHNlIHsKCQluZXdfaGVpZ2h0ID0gbWF4X3BpeGVsX3NpemU7CgkJLy8gY2hhbmdlIGltYWdlIHdpZHRoIHdpdGggdGhlIHNhbWUgcmF0aW8KCQlkb3VibGUgcmF0aW8gPSAoKGRvdWJsZSluZXdfaGVpZ2h0IC8gKGRvdWJsZSloZWlnaHQpOwoJCW5ld193aWR0aCA9IChpbnQpKHdpZHRoICogcmF0aW8gKyAwLjUpOwoJCWlmKG5ld193aWR0aCA9PSAwKSBuZXdfd2lkdGggPSAxOwoJfQoKCWNvbnN0IEZSRUVfSU1BR0VfVFlQRSBpbWFnZV90eXBlID0gRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpOwoKCS8vIHBlcmZvcm0gZG93bnNhbXBsaW5nIHVzaW5nIGEgYmlsaW5lYXIgaW50ZXJwb2xhdGlvbgoKCXN3aXRjaChpbWFnZV90eXBlKSB7CgkJY2FzZSBGSVRfQklUTUFQOgoJCWNhc2UgRklUX1VJTlQxNjoKCQljYXNlIEZJVF9SR0IxNjoKCQljYXNlIEZJVF9SR0JBMTY6CgkJY2FzZSBGSVRfRkxPQVQ6CgkJY2FzZSBGSVRfUkdCRjoKCQljYXNlIEZJVF9SR0JBRjoKCQl7CgkJCUZSRUVfSU1BR0VfRklMVEVSIGZpbHRlciA9IEZJTFRFUl9CSUxJTkVBUjsKCQkJdGh1bWJuYWlsID0gRnJlZUltYWdlX1Jlc2NhbGUoZGliLCBuZXdfd2lkdGgsIG5ld19oZWlnaHQsIGZpbHRlcik7CgkJfQoJCWJyZWFrOwoKCQljYXNlIEZJVF9JTlQxNjoKCQljYXNlIEZJVF9VSU5UMzI6CgkJY2FzZSBGSVRfSU5UMzI6CgkJY2FzZSBGSVRfRE9VQkxFOgoJCWNhc2UgRklUX0NPTVBMRVg6CgkJZGVmYXVsdDoKCQkJLy8gY2Fubm90IHJlc2NhbGUgdGhpcyBraW5kIG9mIGltYWdlCgkJCXRodW1ibmFpbCA9IE5VTEw7CgkJCWJyZWFrOwoJfQoKCWlmKCh0aHVtYm5haWwgIT0gTlVMTCkgJiYgKGltYWdlX3R5cGUgIT0gRklUX0JJVE1BUCkgJiYgY29udmVydCkgewoJCS8vIGNvbnZlcnQgdG8gYSBzdGFuZGFyZCBiaXRtYXAKCQlGSUJJVE1BUCAqYml0bWFwID0gTlVMTDsKCQlzd2l0Y2goaW1hZ2VfdHlwZSkgewoJCQljYXNlIEZJVF9VSU5UMTY6CgkJCQliaXRtYXAgPSBGcmVlSW1hZ2VfQ29udmVydFRvOEJpdHModGh1bWJuYWlsKTsKCQkJCWJyZWFrOwoJCQljYXNlIEZJVF9SR0IxNjoKCQkJCWJpdG1hcCA9IEZyZWVJbWFnZV9Db252ZXJ0VG8yNEJpdHModGh1bWJuYWlsKTsKCQkJCWJyZWFrOwoJCQljYXNlIEZJVF9SR0JBMTY6CgkJCQliaXRtYXAgPSBGcmVlSW1hZ2VfQ29udmVydFRvMzJCaXRzKHRodW1ibmFpbCk7CgkJCQlicmVhazsKCQkJY2FzZSBGSVRfRkxPQVQ6CgkJCQliaXRtYXAgPSBGcmVlSW1hZ2VfQ29udmVydFRvU3RhbmRhcmRUeXBlKHRodW1ibmFpbCwgVFJVRSk7CgkJCQlicmVhazsKCQkJY2FzZSBGSVRfUkdCRjoKCQkJCWJpdG1hcCA9IEZyZWVJbWFnZV9Ub25lTWFwcGluZyh0aHVtYm5haWwsIEZJVE1PX0RSQUdPMDMpOwoJCQkJYnJlYWs7CgkJCWNhc2UgRklUX1JHQkFGOgoJCQkJLy8gbm8gd2F5IHRvIGtlZXAgdGhlIHRyYW5zcGFyZW5jeSB5ZXQgLi4uCgkJCQlGSUJJVE1BUCAqcmdiZiA9IEZyZWVJbWFnZV9Db252ZXJ0VG9SR0JGKHRodW1ibmFpbCk7CgkJCQliaXRtYXAgPSBGcmVlSW1hZ2VfVG9uZU1hcHBpbmcocmdiZiwgRklUTU9fRFJBR08wMyk7CgkJCQlGcmVlSW1hZ2VfVW5sb2FkKHJnYmYpOwoJCQkJYnJlYWs7CgkJfQoJCWlmKGJpdG1hcCAhPSBOVUxMKSB7CgkJCUZyZWVJbWFnZV9VbmxvYWQodGh1bWJuYWlsKTsKCQkJdGh1bWJuYWlsID0gYml0bWFwOwoJCX0KCX0KCgkvLyBjb3B5IG1ldGFkYXRhIGZyb20gc3JjIHRvIGRzdAoJRnJlZUltYWdlX0Nsb25lTWV0YWRhdGEodGh1bWJuYWlsLCBkaWIpOwoKCXJldHVybiB0aHVtYm5haWw7Cn0K