Ly8gYmFzaXN1X3RyYW5zY29kZXJfaW50ZXJuYWwuaCAtIFVuaXZlcnNhbCB0ZXh0dXJlIGZvcm1hdCB0cmFuc2NvZGVyIGxpYnJhcnkuCi8vIENvcHlyaWdodCAoQykgMjAxOS0yMDI2IEJpbm9taWFsIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLy8KLy8gSW1wb3J0YW50OiBJZiBjb21waWxpbmcgd2l0aCBnY2MsIGJlIHN1cmUgc3RyaWN0IGFsaWFzaW5nIGlzIGRpc2FibGVkOiAtZm5vLXN0cmljdC1hbGlhc2luZwovLwovLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgovLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLy8KLy8gICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi8vCi8vIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLy8gZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLy8gV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi8vIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLy8gbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiNwcmFnbWEgb25jZQoKI2lmZGVmIF9NU0NfVkVSCiNwcmFnbWEgd2FybmluZyAoZGlzYWJsZTogNDEyNykgLy8gIGNvbmRpdGlvbmFsIGV4cHJlc3Npb24gaXMgY29uc3RhbnQKI2VuZGlmCgovLyB2MS41MDogQWRkZWQgVUFTVEMgSERSIDR4NCBzdXBwb3J0Ci8vIHYxLjYwOiBBZGRlZCBSRE8gQVNUQyBIRFIgNng2IGFuZCBpbnRlcm1lZGlhdGUgc3VwcG9ydAovLyB2MS42NTogQWRkZWQgQVNUQyBMRFIgNHg0LTEyeDEyIGFuZCBYVUFTVEMgTERSIDR4NC0xMngxMiAobm90IHB1YmxpY2FsbHkgcmVsZWFzZWQpCi8vIHYyLjAwOiBBZGRlZCB1bmlmaWVkIGVmZm9ydC9xdWFsaXR5IG9wdGlvbnMgYWNyb3NzIGFsbCBmb3JtYXRzLCBmYXN0IGRpcmVjdCB0cmFuc2NvZGluZyBvZiBYVUFTVEMgNHg0LzZ4Ni84eDYgdG8gQkM3LCBhZGFwdGl2ZSBkZWJsb2NraW5nLCBaU3RkIG9yIGFyaXRobWV0aWMgcHJvZmlsZXMsIHdlaWdodCBncmlkIERDVAovLyB2Mi4xMDogS2hyb25vcyBtb2RpZmljYXRpb25zIHRvIEtUWDIgZmlsZSBmb3JtYXQgZm9yIFVBU1RDIEhEUiA2eDZpIHN1cHBvcnQgZm9yIEtUWC1Tb2Z0d2FyZSBjb21wYXRpYmxpdHkgKHdlJ3JlIGFsc28gbW9kaWZ5aW5nIGhvdyBYVUFTVEMgTERSIGZpbGVzIHVzZSBLVFgyIHRvIGJlIGNvbXBhdGlibGUpCiNkZWZpbmUgQkFTSVNEX0xJQl9WRVJTSU9OIDIxMAojZGVmaW5lIEJBU0lTRF9WRVJTSU9OX1NUUklORyAiMDIuMTAiCgojaWZkZWYgX0RFQlVHCiNkZWZpbmUgQkFTSVNEX0JVSUxEX0RFQlVHCiNlbHNlCiNkZWZpbmUgQkFTSVNEX0JVSUxEX1JFTEVBU0UKI2VuZGlmCgojaW5jbHVkZSAiYmFzaXN1LmgiCiNpbmNsdWRlICJiYXNpc3VfYXN0Y19oZWxwZXJzLmgiCgojZGVmaW5lIEJBU0lTRF96bmV3ICh6ID0gMzY5NjkgKiAoeiAmIDY1NTM1KSArICh6ID4+IDE2KSkKCm5hbWVzcGFjZSBiYXNpc3UKewoJZXh0ZXJuIGJvb2wgZ19kZWJ1Z19wcmludGY7Cn0KCm5hbWVzcGFjZSBiYXNpc3QKewoJLy8gTG93LWxldmVsIGZvcm1hdHMgZGlyZWN0bHkgc3VwcG9ydGVkIGJ5IHRoZSB0cmFuc2NvZGVyIChvdGhlciBzdXBwb3J0ZWQgdGV4dHVyZSBmb3JtYXRzIGFyZSBjb21iaW5hdGlvbnMgb2YgdGhlc2UgbG93LWxldmVsIGJsb2NrIGZvcm1hdHMpLgoJLy8gWW91IHByb2JhYmx5IGRvbid0IGNhcmUgYWJvdXQgdGhlc2UgZW51bSdzIHVubGVzcyB5b3UgYXJlIGdvaW5nIHByZXR0eSBsb3ctbGV2ZWwgYW5kIGNhbGxpbmcgdGhlIHRyYW5zY29kZXIgdG8gZGVjb2RlIGluZGl2aWR1YWwgc2xpY2VzLgoJZW51bSBjbGFzcyBibG9ja19mb3JtYXQKCXsKCQljRVRDMSwJCQkJCQkJCS8vIEVUQzFTIFJHQiAKCQljRVRDMl9SR0JBLAkJCQkJCQkvLyBmdWxsIEVUQzIgRUFDIFJHQkE4IGJsb2NrCgkJY0JDMSwJCQkJCQkJCS8vIERYVDEgUkdCIAoJCWNCQzMsCQkJCQkJCQkvLyBCQzQgYmxvY2sgZm9sbG93ZWQgYnkgYSBmb3VyIGNvbG9yIEJDMSBibG9jawoJCWNCQzQsCQkJCQkJCQkvLyBEWFQ1QSAoYWxwaGEgYmxvY2sgb25seSkKCQljQkM1LAkJCQkJCQkJLy8gdHdvIEJDNCBibG9ja3MKCQljUFZSVEMxXzRfUkdCLAkJCQkJCS8vIG9wYXF1ZS1vbmx5IFBWUlRDMSA0YnBwCgkJY1BWUlRDMV80X1JHQkEsCQkJCQkJLy8gUFZSVEMxIDRicHAgUkdCQQoJCWNCQzcsCQkJCQkJCQkvLyBGdWxsIEJDNyBibG9jaywgYW55IG1vZGUKCQljQkM3X001X0NPTE9SLAkJCQkJCS8vIFJHQiBCQzcgbW9kZSA1IGNvbG9yICh3cml0ZXMgYW4gb3BhcXVlIG1vZGUgNSBibG9jaykKCQljQkM3X001X0FMUEhBLAkJCQkJCS8vIGFscGhhIHBvcnRpb24gb2YgQkM3IG1vZGUgNSAoY0JDN19NNV9DT0xPUiBvdXRwdXQgZGF0YSBtdXN0IGhhdmUgYmVlbiB3cml0dGVuIHRvIHRoZSBvdXRwdXQgYnVmZmVyIGZpcnN0IHRvIHNldCB0aGUgbW9kZS9yb3QgZmllbGRzIGV0Yy4pCgkJY0VUQzJfRUFDX0E4LAkJCQkJCS8vIGFscGhhIGJsb2NrIG9mIEVUQzIgRUFDIChmaXJzdCA4IGJ5dGVzIG9mIHRoZSAxNi1iaXQgRVRDMiBFQUMgUkdCQSBmb3JtYXQpCgkJY0FTVENfTERSXzR4NCwJCQkJCQkvLyBBU1RDIExEUiA0eDQgKGVpdGhlciBjb2xvci1vbmx5IG9yIGNvbG9yK2FscGhhKS4gTm90ZSB0aGF0IHRoZSB0cmFuc2NvZGVyIGFsd2F5cyBjdXJyZW50bHkgYXNzdW1lcyBzUkdCIGRlY29kZSBtb2RlIGlzIG5vdCBlbmFibGVkIHdoZW4gb3V0cHV0dGluZyBBU1RDIExEUiBmb3IgRVRDMVMvVUFTVEMgTERSIDR4NC4KCQkJCQkJCQkJCQkvLyBkYXRhLiBJZiB5b3UgdXNlIGEgc1JHQiBBU1RDIGZvcm1hdCB5b3UnbGwgZ2V0IH4xIExTQiBvZiBhZGRpdGlvbmFsIGVycm9yLCBiZWNhdXNlIG9mIHRoZSBkaWZmZXJlbnQgd2F5IEFTVEMgZGVjb2RlcnMgc2NhbGUgOC1iaXQgZW5kcG9pbnRzIHRvIDE2LWJpdHMgZHVyaW5nIHVucGFja2luZy4KCQkKCQljQVRDX1JHQiwKCQljQVRDX1JHQkFfSU5URVJQT0xBVEVEX0FMUEhBLAoJCWNGWFQxX1JHQiwJCQkJCQkJLy8gT3BhcXVlLW9ubHksIGhhcyBvZGRiYWxsIDh4NCBwaXhlbCBibG9jayBzaXplCgoJCWNQVlJUQzJfNF9SR0IsCgkJY1BWUlRDMl80X1JHQkEsCgoJCWNFVEMyX0VBQ19SMTEsCgkJY0VUQzJfRUFDX1JHMTEsCgkJCQkJCQkJCQkJCQoJCWNJbmRpY2VzLAkJCQkJCQkvLyBVc2VkIGludGVybmFsbHk6IFdyaXRlIDE2LWJpdCBlbmRwb2ludCBhbmQgc2VsZWN0b3IgaW5kaWNlcyBkaXJlY3RseSB0byBvdXRwdXQgKG91dHB1dCBibG9jayBtdXN0IGJlIGF0IGxlYXN0IDMyLWJpdHMpCgoJCWNSR0IzMiwJCQkJCQkJCS8vIFdyaXRlcyBSR0IgY29tcG9uZW50cyB0byAzMmJwcCBvdXRwdXQgcGl4ZWxzCgkJY1JHQkEzMiwJCQkJCQkJLy8gV3JpdGVzIFJHQjI1NSBjb21wb25lbnRzIHRvIDMyYnBwIG91dHB1dCBwaXhlbHMKCQljQTMyLAkJCQkJCQkJLy8gV3JpdGVzIGFscGhhIGNvbXBvbmVudCB0byAzMmJwcCBvdXRwdXQgcGl4ZWxzCgkJCQkKCQljUkdCNTY1LAoJCWNCR1I1NjUsCgkJCgkJY1JHQkE0NDQ0X0NPTE9SLAoJCWNSR0JBNDQ0NF9BTFBIQSwKCQljUkdCQTQ0NDRfQ09MT1JfT1BBUVVFLAoJCWNSR0JBNDQ0NCwKCQljUkdCQV9IQUxGLAoJCWNSR0JfSEFMRiwKCQljUkdCXzlFNSwKCgkJY1VBU1RDXzR4NCwJCQkJCQkJLy8gTERSLCB1bml2ZXJzYWwKCQljVUFTVENfSERSXzR4NCwJCQkJCQkvLyBIRFIsIHRyYW5zY29kZXMgb25seSB0byA0eDQgSERSIEFTVEMsIEJDNkgsIG9yIHVuY29tcHJlc3NlZAoJCWNCQzZILAoJCQoJCWNBU1RDX0hEUl80eDQsCgkJY0FTVENfSERSXzZ4NiwKCgkJLy8gVGhlIHJlbWFpbmluZyBBU1RDIExEUiBibG9jayBzaXplcy4KCQljQVNUQ19MRFJfNXg0LAoJCWNBU1RDX0xEUl81eDUsCgkJY0FTVENfTERSXzZ4NSwKCQljQVNUQ19MRFJfNng2LAoJCWNBU1RDX0xEUl84eDUsCgkJY0FTVENfTERSXzh4NiwKCQljQVNUQ19MRFJfMTB4NSwKCQljQVNUQ19MRFJfMTB4NiwKCQljQVNUQ19MRFJfOHg4LAoJCWNBU1RDX0xEUl8xMHg4LAoJCWNBU1RDX0xEUl8xMHgxMCwKCQljQVNUQ19MRFJfMTJ4MTAsCgkJY0FTVENfTERSXzEyeDEyLAoJCQkJCQkJCQkJCgkJY1RvdGFsQmxvY2tGb3JtYXRzCgl9OwoKCWlubGluZSBib29sIGJsb2NrX2Zvcm1hdF9pc19oZHIoYmxvY2tfZm9ybWF0IGZtdCkKCXsKCQlzd2l0Y2ggKGZtdCkKCQl7CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNVQVNUQ19IRFJfNHg0OgoJCWNhc2UgYmxvY2tfZm9ybWF0OjpjQkM2SDoKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfSERSXzR4NDoKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfSERSXzZ4NjoKCQkJcmV0dXJuIHRydWU7CgkJZGVmYXVsdDoKCQkJYnJlYWs7CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLy8gTERSIG9yIEhEUiBBU1RDPwoJaW5saW5lIGJvb2wgYmxvY2tfZm9ybWF0X2lzX2FzdGMoYmxvY2tfZm9ybWF0IGZtdCkKCXsKCQlzd2l0Y2ggKGZtdCkKCQl7CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl80eDQ6CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl81eDQ6CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl81eDU6CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl82eDU6CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl82eDY6CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl84eDU6CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl84eDY6CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl8xMHg1OgoJCWNhc2UgYmxvY2tfZm9ybWF0OjpjQVNUQ19MRFJfMTB4NjoKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfTERSXzh4ODoKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfTERSXzEweDg6CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl8xMHgxMDoKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfTERSXzEyeDEwOgoJCWNhc2UgYmxvY2tfZm9ybWF0OjpjQVNUQ19MRFJfMTJ4MTI6CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0hEUl80eDQ6CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0hEUl82eDY6CgkJCXJldHVybiB0cnVlOwoJCWRlZmF1bHQ6CgkJCWJyZWFrOwoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQoKCWlubGluZSB1aW50MzJfdCBnZXRfYmxvY2tfd2lkdGgoYmxvY2tfZm9ybWF0IGZtdCkKCXsKCQlzd2l0Y2ggKGZtdCkKCQl7CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNGWFQxX1JHQjoKCQkJcmV0dXJuIDg7CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0hEUl82eDY6CgkJCXJldHVybiA2OwoKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfTERSXzV4NDogcmV0dXJuIDU7CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl81eDU6IHJldHVybiA1OwoJCWNhc2UgYmxvY2tfZm9ybWF0OjpjQVNUQ19MRFJfNng1OiByZXR1cm4gNjsKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfTERSXzZ4NjogcmV0dXJuIDY7CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl84eDU6IHJldHVybiA4OwoJCWNhc2UgYmxvY2tfZm9ybWF0OjpjQVNUQ19MRFJfOHg2OiByZXR1cm4gODsKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfTERSXzEweDU6IHJldHVybiAxMDsKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfTERSXzEweDY6IHJldHVybiAxMDsKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfTERSXzh4ODogcmV0dXJuIDg7CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl8xMHg4OiByZXR1cm4gMTA7CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl8xMHgxMDogcmV0dXJuIDEwOwoJCWNhc2UgYmxvY2tfZm9ybWF0OjpjQVNUQ19MRFJfMTJ4MTA6IHJldHVybiAxMjsKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfTERSXzEyeDEyOiByZXR1cm4gMTI7CgoJCWRlZmF1bHQ6CgkJCWJyZWFrOwoJCX0KCQlyZXR1cm4gNDsKCX0KCglpbmxpbmUgdWludDMyX3QgZ2V0X2Jsb2NrX2hlaWdodChibG9ja19mb3JtYXQgZm10KQoJewoJCXN3aXRjaCAoZm10KQoJCXsKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfSERSXzZ4NjoKCQkJcmV0dXJuIDY7CgkJCQkJCgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl81eDU6IHJldHVybiA1OwoJCWNhc2UgYmxvY2tfZm9ybWF0OjpjQVNUQ19MRFJfNng1OiByZXR1cm4gNTsKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfTERSXzZ4NjogcmV0dXJuIDY7CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl84eDU6IHJldHVybiA1OwoJCWNhc2UgYmxvY2tfZm9ybWF0OjpjQVNUQ19MRFJfOHg2OiByZXR1cm4gNjsKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfTERSXzEweDU6IHJldHVybiA1OwoJCWNhc2UgYmxvY2tfZm9ybWF0OjpjQVNUQ19MRFJfMTB4NjogcmV0dXJuIDY7CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl84eDg6IHJldHVybiA4OwoJCWNhc2UgYmxvY2tfZm9ybWF0OjpjQVNUQ19MRFJfMTB4ODogcmV0dXJuIDg7CgkJY2FzZSBibG9ja19mb3JtYXQ6OmNBU1RDX0xEUl8xMHgxMDogcmV0dXJuIDEwOwoJCWNhc2UgYmxvY2tfZm9ybWF0OjpjQVNUQ19MRFJfMTJ4MTA6IHJldHVybiAxMDsKCQljYXNlIGJsb2NrX2Zvcm1hdDo6Y0FTVENfTERSXzEyeDEyOiByZXR1cm4gMTI7CgoJCWRlZmF1bHQ6CgkJCWJyZWFrOwoJCX0KCQlyZXR1cm4gNDsKCX0KCgljb25zdCBpbnQgQ09MT1I1X1BBTDBfUFJFVl9ISSA9IDksIENPTE9SNV9QQUwwX0RFTFRBX0xPID0gLTksIENPTE9SNV9QQUwwX0RFTFRBX0hJID0gMzE7Cgljb25zdCBpbnQgQ09MT1I1X1BBTDFfUFJFVl9ISSA9IDIxLCBDT0xPUjVfUEFMMV9ERUxUQV9MTyA9IC0yMSwgQ09MT1I1X1BBTDFfREVMVEFfSEkgPSAyMTsKCWNvbnN0IGludCBDT0xPUjVfUEFMMl9QUkVWX0hJID0gMzEsIENPTE9SNV9QQUwyX0RFTFRBX0xPID0gLTMxLCBDT0xPUjVfUEFMMl9ERUxUQV9ISSA9IDk7Cgljb25zdCBpbnQgQ09MT1I1X1BBTF9NSU5fREVMVEFfQl9SVU5MRU4gPSAzLCBDT0xPUjVfUEFMX0RFTFRBXzVfUlVOTEVOX1ZMQ19CSVRTID0gMzsKCgljb25zdCB1aW50MzJfdCBFTkRQT0lOVF9QUkVEX1RPVEFMX1NZTUJPTFMgPSAoNCAqIDQgKiA0ICogNCkgKyAxOwoJY29uc3QgdWludDMyX3QgRU5EUE9JTlRfUFJFRF9SRVBFQVRfTEFTVF9TWU1CT0wgPSBFTkRQT0lOVF9QUkVEX1RPVEFMX1NZTUJPTFMgLSAxOwoJY29uc3QgdWludDMyX3QgRU5EUE9JTlRfUFJFRF9NSU5fUkVQRUFUX0NPVU5UID0gMzsKCWNvbnN0IHVpbnQzMl90IEVORFBPSU5UX1BSRURfQ09VTlRfVkxDX0JJVFMgPSA0OwoKCWNvbnN0IHVpbnQzMl90IE5VTV9FTkRQT0lOVF9QUkVEUyA9IDM7Ly8gQkFTSVNVX0FSUkFZX1NJWkUoZ19lbmRwb2ludF9wcmVkcyk7Cgljb25zdCB1aW50MzJfdCBDUl9FTkRQT0lOVF9QUkVEX0lOREVYID0gTlVNX0VORFBPSU5UX1BSRURTIC0gMTsKCWNvbnN0IHVpbnQzMl90IE5PX0VORFBPSU5UX1BSRURfSU5ERVggPSAzOy8vTlVNX0VORFBPSU5UX1BSRURTOwoJY29uc3QgdWludDMyX3QgTUFYX1NFTEVDVE9SX0hJU1RPUllfQlVGX1NJWkUgPSA2NDsKCWNvbnN0IHVpbnQzMl90IFNFTEVDVE9SX0hJU1RPUllfQlVGX1JMRV9DT1VOVF9USFJFU0ggPSAzOwoJY29uc3QgdWludDMyX3QgU0VMRUNUT1JfSElTVE9SWV9CVUZfUkxFX0NPVU5UX0JJVFMgPSA2OwoJY29uc3QgdWludDMyX3QgU0VMRUNUT1JfSElTVE9SWV9CVUZfUkxFX0NPVU5UX1RPVEFMID0gKDEgPDwgU0VMRUNUT1JfSElTVE9SWV9CVUZfUkxFX0NPVU5UX0JJVFMpOwoJCQoJdWludDE2X3QgY3JjMTYoY29uc3Qgdm9pZCAqciwgc2l6ZV90IHNpemUsIHVpbnQxNl90IGNyYyk7CgoJdWludDMyX3QgaGFzaF9oc2llaChjb25zdCB1aW50OF90KiBwQnVmLCBzaXplX3QgbGVuKTsKCgl0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5PgoJc3RydWN0IGJpdF9oYXNoZXIKCXsKCQlpbmxpbmUgc3RkOjpzaXplX3Qgb3BlcmF0b3IoKShjb25zdCBLZXkmIGspIGNvbnN0CgkJewoJCQlyZXR1cm4gaGFzaF9oc2llaChyZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4X3QqPigmayksIHNpemVvZihrKSk7CgkJfQoJfTsKCglzdHJ1Y3Qgc3RyaW5nX2hhc2hlcgoJewoJCWlubGluZSBzdGQ6OnNpemVfdCBvcGVyYXRvcigpKGNvbnN0IHN0ZDo6c3RyaW5nJiBrKSBjb25zdAoJCXsKCQkJc2l6ZV90IGwgPSBrLnNpemUoKTsKCQkJaWYgKCFsKQoJCQkJcmV0dXJuIDA7CgkJCXJldHVybiBoYXNoX2hzaWVoKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDhfdCo+KGsuY19zdHIoKSksIGwpOwoJCX0KCX07CgoJY2xhc3MgaHVmZm1hbl9kZWNvZGluZ190YWJsZQoJewoJCWZyaWVuZCBjbGFzcyBiaXR3aXNlX2RlY29kZXI7CgoJcHVibGljOgoJCWh1ZmZtYW5fZGVjb2RpbmdfdGFibGUoKQoJCXsKCQl9CgoJCXZvaWQgY2xlYXIoKQoJCXsKCQkJYmFzaXN1OjpjbGVhcl92ZWN0b3IobV9jb2RlX3NpemVzKTsKCQkJYmFzaXN1OjpjbGVhcl92ZWN0b3IobV9sb29rdXApOwoJCQliYXNpc3U6OmNsZWFyX3ZlY3RvcihtX3RyZWUpOwoJCX0KCgkJYm9vbCBpbml0KHVpbnQzMl90IHRvdGFsX3N5bXMsIGNvbnN0IHVpbnQ4X3QgKnBDb2RlX3NpemVzLCB1aW50MzJfdCBmYXN0X2xvb2t1cF9iaXRzID0gYmFzaXN1OjpjSHVmZm1hbkZhc3RMb29rdXBCaXRzKQoJCXsKCQkJaWYgKCF0b3RhbF9zeW1zKQoJCQl7CgkJCQljbGVhcigpOwoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCgkJCW1fY29kZV9zaXplcy5yZXNpemUodG90YWxfc3ltcyk7CgkJCW1lbWNweSgmbV9jb2RlX3NpemVzWzBdLCBwQ29kZV9zaXplcywgdG90YWxfc3ltcyk7CgoJCQljb25zdCB1aW50MzJfdCBodWZmbWFuX2Zhc3RfbG9va3VwX3NpemUgPSAxIDw8IGZhc3RfbG9va3VwX2JpdHM7CgoJCQltX2xvb2t1cC5yZXNpemUoMCk7CgkJCW1fbG9va3VwLnJlc2l6ZShodWZmbWFuX2Zhc3RfbG9va3VwX3NpemUpOwoKCQkJbV90cmVlLnJlc2l6ZSgwKTsKCQkJbV90cmVlLnJlc2l6ZSh0b3RhbF9zeW1zICogMik7CgoJCQl1aW50MzJfdCBzeW1zX3VzaW5nX2NvZGVzaXplW2Jhc2lzdTo6Y0h1ZmZtYW5NYXhTdXBwb3J0ZWRJbnRlcm5hbENvZGVTaXplICsgMV07CgkJCWJhc2lzdTo6Y2xlYXJfb2JqKHN5bXNfdXNpbmdfY29kZXNpemUpOwoJCQlmb3IgKHVpbnQzMl90IGkgPSAwOyBpIDwgdG90YWxfc3ltczsgaSsrKQoJCQl7CgkJCQlpZiAocENvZGVfc2l6ZXNbaV0gPiBiYXNpc3U6OmNIdWZmbWFuTWF4U3VwcG9ydGVkSW50ZXJuYWxDb2RlU2l6ZSkKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQlzeW1zX3VzaW5nX2NvZGVzaXplW3BDb2RlX3NpemVzW2ldXSsrOwoJCQl9CgoJCQl1aW50MzJfdCBuZXh0X2NvZGVbYmFzaXN1OjpjSHVmZm1hbk1heFN1cHBvcnRlZEludGVybmFsQ29kZVNpemUgKyAxXTsKCQkJbmV4dF9jb2RlWzBdID0gbmV4dF9jb2RlWzFdID0gMDsKCgkJCXVpbnQzMl90IHVzZWRfc3ltcyA9IDAsIHRvdGFsID0gMDsKCQkJZm9yICh1aW50MzJfdCBpID0gMTsgaSA8IGJhc2lzdTo6Y0h1ZmZtYW5NYXhTdXBwb3J0ZWRJbnRlcm5hbENvZGVTaXplOyBpKyspCgkJCXsKCQkJCXVzZWRfc3ltcyArPSBzeW1zX3VzaW5nX2NvZGVzaXplW2ldOwoJCQkJbmV4dF9jb2RlW2kgKyAxXSA9ICh0b3RhbCA9ICgodG90YWwgKyBzeW1zX3VzaW5nX2NvZGVzaXplW2ldKSA8PCAxKSk7CgkJCX0KCgkJCWlmICgoKDFVIDw8IGJhc2lzdTo6Y0h1ZmZtYW5NYXhTdXBwb3J0ZWRJbnRlcm5hbENvZGVTaXplKSAhPSB0b3RhbCkgJiYgKHVzZWRfc3ltcyAhPSAxVSkpCgkJCQlyZXR1cm4gZmFsc2U7CgoJCQlmb3IgKGludCB0cmVlX25leHQgPSAtMSwgc3ltX2luZGV4ID0gMDsgc3ltX2luZGV4IDwgKGludCl0b3RhbF9zeW1zOyArK3N5bV9pbmRleCkKCQkJewoJCQkJdWludDMyX3QgcmV2X2NvZGUgPSAwLCBsLCBjdXJfY29kZSwgY29kZV9zaXplID0gcENvZGVfc2l6ZXNbc3ltX2luZGV4XTsKCQkJCWlmICghY29kZV9zaXplKQoJCQkJCWNvbnRpbnVlOwoKCQkJCWN1cl9jb2RlID0gbmV4dF9jb2RlW2NvZGVfc2l6ZV0rKzsKCgkJCQlmb3IgKGwgPSBjb2RlX3NpemU7IGwgPiAwOyBsLS0sIGN1cl9jb2RlID4+PSAxKQoJCQkJCXJldl9jb2RlID0gKHJldl9jb2RlIDw8IDEpIHwgKGN1cl9jb2RlICYgMSk7CgoJCQkJaWYgKGNvZGVfc2l6ZSA8PSBmYXN0X2xvb2t1cF9iaXRzKQoJCQkJewoJCQkJCXVpbnQzMl90IGsgPSAoY29kZV9zaXplIDw8IDE2KSB8IHN5bV9pbmRleDsKCQkJCQl3aGlsZSAocmV2X2NvZGUgPCBodWZmbWFuX2Zhc3RfbG9va3VwX3NpemUpCgkJCQkJewoJCQkJCQlpZiAobV9sb29rdXBbcmV2X2NvZGVdICE9IDApCgkJCQkJCXsKCQkJCQkJCS8vIFN1cHBsaWVkIGNvZGVzaXplcyBjYW4ndCBjcmVhdGUgYSB2YWxpZCBwcmVmaXggY29kZS4KCQkJCQkJCXJldHVybiBmYWxzZTsKCQkJCQkJfQoKCQkJCQkJbV9sb29rdXBbcmV2X2NvZGVdID0gazsKCQkJCQkJcmV2X2NvZGUgKz0gKDEgPDwgY29kZV9zaXplKTsKCQkJCQl9CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJaW50IHRyZWVfY3VyOwoJCQkJaWYgKDAgPT0gKHRyZWVfY3VyID0gbV9sb29rdXBbcmV2X2NvZGUgJiAoaHVmZm1hbl9mYXN0X2xvb2t1cF9zaXplIC0gMSldKSkKCQkJCXsKCQkJCQljb25zdCB1aW50MzJfdCBpZHggPSByZXZfY29kZSAmIChodWZmbWFuX2Zhc3RfbG9va3VwX3NpemUgLSAxKTsKCQkJCQlpZiAobV9sb29rdXBbaWR4XSAhPSAwKQoJCQkJCXsKCQkJCQkJLy8gU3VwcGxpZWQgY29kZXNpemVzIGNhbid0IGNyZWF0ZSBhIHZhbGlkIHByZWZpeCBjb2RlLgoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJfQoKCQkJCQltX2xvb2t1cFtpZHhdID0gdHJlZV9uZXh0OwoJCQkJCXRyZWVfY3VyID0gdHJlZV9uZXh0OwoJCQkJCXRyZWVfbmV4dCAtPSAyOwoJCQkJfQoKCQkJCWlmICh0cmVlX2N1ciA+PSAwKQoJCQkJewoJCQkJCS8vIFN1cHBsaWVkIGNvZGVzaXplcyBjYW4ndCBjcmVhdGUgYSB2YWxpZCBwcmVmaXggY29kZS4KCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgoJCQkJcmV2X2NvZGUgPj49IChmYXN0X2xvb2t1cF9iaXRzIC0gMSk7CgoJCQkJZm9yIChpbnQgaiA9IGNvZGVfc2l6ZTsgaiA+ICgoaW50KWZhc3RfbG9va3VwX2JpdHMgKyAxKTsgai0tKQoJCQkJewoJCQkJCXRyZWVfY3VyIC09ICgocmV2X2NvZGUgPj49IDEpICYgMSk7CgoJCQkJCWNvbnN0IGludCBpZHggPSAtdHJlZV9jdXIgLSAxOwoJCQkJCWlmIChpZHggPCAwKQoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJZWxzZSBpZiAoaWR4ID49IChpbnQpbV90cmVlLnNpemUoKSkKCQkJCQkJbV90cmVlLnJlc2l6ZShpZHggKyAxKTsKCQkJCQkJCQkJCQoJCQkJCWlmICghbV90cmVlW2lkeF0pCgkJCQkJewoJCQkJCQltX3RyZWVbaWR4XSA9IChpbnQxNl90KXRyZWVfbmV4dDsKCQkJCQkJdHJlZV9jdXIgPSB0cmVlX25leHQ7CgkJCQkJCXRyZWVfbmV4dCAtPSAyOwoJCQkJCX0KCQkJCQllbHNlCgkJCQkJewoJCQkJCQl0cmVlX2N1ciA9IG1fdHJlZVtpZHhdOwoJCQkJCQlpZiAodHJlZV9jdXIgPj0gMCkKCQkJCQkJewoJCQkJCQkJLy8gU3VwcGxpZWQgY29kZXNpemVzIGNhbid0IGNyZWF0ZSBhIHZhbGlkIHByZWZpeCBjb2RlLgoJCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoKCQkJCXRyZWVfY3VyIC09ICgocmV2X2NvZGUgPj49IDEpICYgMSk7CgoJCQkJY29uc3QgaW50IGlkeCA9IC10cmVlX2N1ciAtIDE7CgkJCQlpZiAoaWR4IDwgMCkKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQllbHNlIGlmIChpZHggPj0gKGludCltX3RyZWUuc2l6ZSgpKQoJCQkJCW1fdHJlZS5yZXNpemUoaWR4ICsgMSk7CgoJCQkJaWYgKG1fdHJlZVtpZHhdICE9IDApCgkJCQl7CgkJCQkJLy8gU3VwcGxpZWQgY29kZXNpemVzIGNhbid0IGNyZWF0ZSBhIHZhbGlkIHByZWZpeCBjb2RlLgoJCQkJCXJldHVybiBmYWxzZTsKCQkJCX0KCgkJCQltX3RyZWVbaWR4XSA9IChpbnQxNl90KXN5bV9pbmRleDsKCQkJfQoKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQljb25zdCBiYXNpc3U6OnVpbnQ4X3ZlYyAmZ2V0X2NvZGVfc2l6ZXMoKSBjb25zdCB7IHJldHVybiBtX2NvZGVfc2l6ZXM7IH0KCQljb25zdCBiYXNpc3U6OmludF92ZWMgJmdldF9sb29rdXAoKSBjb25zdCB7IHJldHVybiBtX2xvb2t1cDsgfQoJCWNvbnN0IGJhc2lzdTo6aW50MTZfdmVjICZnZXRfdHJlZSgpIGNvbnN0IHsgcmV0dXJuIG1fdHJlZTsgfQoKCQlib29sIGlzX3ZhbGlkKCkgY29uc3QgeyByZXR1cm4gbV9jb2RlX3NpemVzLnNpemUoKSA+IDA7IH0KCglwcml2YXRlOgoJCWJhc2lzdTo6dWludDhfdmVjIG1fY29kZV9zaXplczsKCQliYXNpc3U6OmludF92ZWMgbV9sb29rdXA7CgkJYmFzaXN1OjppbnQxNl92ZWMgbV90cmVlOwoJfTsKCgljbGFzcyBiaXR3aXNlX2RlY29kZXIKCXsKCXB1YmxpYzoKCQliaXR3aXNlX2RlY29kZXIoKSA6CgkJCW1fYnVmX3NpemUoMCksCgkJCW1fcEJ1ZihudWxscHRyKSwKCQkJbV9wQnVmX3N0YXJ0KG51bGxwdHIpLAoJCQltX3BCdWZfZW5kKG51bGxwdHIpLAoJCQltX2JpdF9idWYoMCksCgkJCW1fYml0X2J1Zl9zaXplKDApCgkJewoJCX0KCgkJdm9pZCBjbGVhcigpCgkJewoJCQltX2J1Zl9zaXplID0gMDsKCQkJbV9wQnVmID0gbnVsbHB0cjsKCQkJbV9wQnVmX3N0YXJ0ID0gbnVsbHB0cjsKCQkJbV9wQnVmX2VuZCA9IG51bGxwdHI7CgkJCW1fYml0X2J1ZiA9IDA7CgkJCW1fYml0X2J1Zl9zaXplID0gMDsKCQl9CgoJCWJvb2wgaW5pdChjb25zdCB1aW50OF90ICpwQnVmLCB1aW50MzJfdCBidWZfc2l6ZSkKCQl7CgkJCWlmICgoIXBCdWYpICYmIChidWZfc2l6ZSkpCgkJCQlyZXR1cm4gZmFsc2U7CgoJCQltX2J1Zl9zaXplID0gYnVmX3NpemU7CgkJCW1fcEJ1ZiA9IHBCdWY7CgkJCW1fcEJ1Zl9zdGFydCA9IHBCdWY7CgkJCW1fcEJ1Zl9lbmQgPSBwQnVmICsgYnVmX3NpemU7CgkJCW1fYml0X2J1ZiA9IDA7CgkJCW1fYml0X2J1Zl9zaXplID0gMDsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQl2b2lkIHN0b3AoKQoJCXsKCQl9CgkJCQkKCQlpbmxpbmUgdWludDMyX3QgcGVla19iaXRzKHVpbnQzMl90IG51bV9iaXRzKQoJCXsKCQkJaWYgKCFudW1fYml0cykKCQkJCXJldHVybiAwOwoKCQkJYXNzZXJ0KG51bV9iaXRzIDw9IDI1KTsKCgkJCXdoaWxlIChtX2JpdF9idWZfc2l6ZSA8IG51bV9iaXRzKQoJCQl7CgkJCQl1aW50MzJfdCBjID0gMDsKCQkJCWlmIChtX3BCdWYgPCBtX3BCdWZfZW5kKQoJCQkJCWMgPSAqbV9wQnVmKys7CgoJCQkJbV9iaXRfYnVmIHw9IChjIDw8IG1fYml0X2J1Zl9zaXplKTsKCQkJCW1fYml0X2J1Zl9zaXplICs9IDg7CgkJCQlhc3NlcnQobV9iaXRfYnVmX3NpemUgPD0gMzIpOwoJCQl9CgoJCQlyZXR1cm4gbV9iaXRfYnVmICYgKCgxIDw8IG51bV9iaXRzKSAtIDEpOwoJCX0KCgkJdm9pZCByZW1vdmVfYml0cyh1aW50MzJfdCBudW1fYml0cykKCQl7CgkJCWFzc2VydChtX2JpdF9idWZfc2l6ZSA+PSBudW1fYml0cyk7CgoJCQltX2JpdF9idWYgPj49IG51bV9iaXRzOwoJCQltX2JpdF9idWZfc2l6ZSAtPSBudW1fYml0czsKCQl9CgoJCXVpbnQzMl90IGdldF9iaXRzKHVpbnQzMl90IG51bV9iaXRzKQoJCXsKCQkJaWYgKG51bV9iaXRzID4gMjUpCgkJCXsKCQkJCWFzc2VydChudW1fYml0cyA8PSAzMik7CgoJCQkJY29uc3QgdWludDMyX3QgYml0czAgPSBwZWVrX2JpdHMoMjUpOwoJCQkJbV9iaXRfYnVmID4+PSAyNTsKCQkJCW1fYml0X2J1Zl9zaXplIC09IDI1OwoJCQkJbnVtX2JpdHMgLT0gMjU7CgoJCQkJY29uc3QgdWludDMyX3QgYml0cyA9IHBlZWtfYml0cyhudW1fYml0cyk7CgkJCQltX2JpdF9idWYgPj49IG51bV9iaXRzOwoJCQkJbV9iaXRfYnVmX3NpemUgLT0gbnVtX2JpdHM7CgoJCQkJcmV0dXJuIGJpdHMwIHwgKGJpdHMgPDwgMjUpOwoJCQl9CgoJCQljb25zdCB1aW50MzJfdCBiaXRzID0gcGVla19iaXRzKG51bV9iaXRzKTsKCgkJCW1fYml0X2J1ZiA+Pj0gbnVtX2JpdHM7CgkJCW1fYml0X2J1Zl9zaXplIC09IG51bV9iaXRzOwoKCQkJcmV0dXJuIGJpdHM7CgkJfQoKCQl1aW50MzJfdCBkZWNvZGVfdHJ1bmNhdGVkX2JpbmFyeSh1aW50MzJfdCBuKQoJCXsKCQkJYXNzZXJ0KG4gPj0gMik7CgoJCQljb25zdCB1aW50MzJfdCBrID0gYmFzaXN1OjpmbG9vcl9sb2cyaShuKTsKCQkJY29uc3QgdWludDMyX3QgdSA9ICgxIDw8IChrICsgMSkpIC0gbjsKCgkJCXVpbnQzMl90IHJlc3VsdCA9IGdldF9iaXRzKGspOwoKCQkJaWYgKHJlc3VsdCA+PSB1KQoJCQkJcmVzdWx0ID0gKChyZXN1bHQgPDwgMSkgfCBnZXRfYml0cygxKSkgLSB1OwoKCQkJcmV0dXJuIHJlc3VsdDsKCQl9CgoJCXVpbnQzMl90IGRlY29kZV9yaWNlKHVpbnQzMl90IG0pCgkJewoJCQlhc3NlcnQobSk7CgoJCQl1aW50MzJfdCBxID0gMDsKCQkJZm9yICg7OykKCQkJewoJCQkJdWludDMyX3QgayA9IHBlZWtfYml0cygxNik7CgkJCQkKCQkJCXVpbnQzMl90IGwgPSAwOwoJCQkJd2hpbGUgKGsgJiAxKQoJCQkJewoJCQkJCWwrKzsKCQkJCQlrID4+PSAxOwoJCQkJfQoJCQkJCgkJCQlxICs9IGw7CgoJCQkJcmVtb3ZlX2JpdHMobCk7CgoJCQkJaWYgKGwgPCAxNikKCQkJCQlicmVhazsKCQkJfQoKCQkJcmV0dXJuIChxIDw8IG0pICsgKGdldF9iaXRzKG0gKyAxKSA+PiAxKTsKCQl9CgoJCWlubGluZSB1aW50MzJfdCBkZWNvZGVfdmxjKHVpbnQzMl90IGNodW5rX2JpdHMpCgkJewoJCQlhc3NlcnQoY2h1bmtfYml0cyk7CgoJCQljb25zdCB1aW50MzJfdCBjaHVua19zaXplID0gMSA8PCBjaHVua19iaXRzOwoJCQljb25zdCB1aW50MzJfdCBjaHVua19tYXNrID0gY2h1bmtfc2l6ZSAtIDE7CgkJCQkJCgkJCXVpbnQzMl90IHYgPSAwOwoJCQl1aW50MzJfdCBvZnMgPSAwOwoKCQkJZm9yICggOyA7ICkKCQkJewoJCQkJdWludDMyX3QgcyA9IGdldF9iaXRzKGNodW5rX2JpdHMgKyAxKTsKCQkJCXYgfD0gKChzICYgY2h1bmtfbWFzaykgPDwgb2ZzKTsKCQkJCW9mcyArPSBjaHVua19iaXRzOwoKCQkJCWlmICgocyAmIGNodW5rX3NpemUpID09IDApCgkJCQkJYnJlYWs7CgkJCQkKCQkJCWlmIChvZnMgPj0gMzIpCgkJCQl7CgkJCQkJYXNzZXJ0KDApOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgoJCQlyZXR1cm4gdjsKCQl9CgoJCWlubGluZSB1aW50MzJfdCBkZWNvZGVfaHVmZm1hbihjb25zdCBodWZmbWFuX2RlY29kaW5nX3RhYmxlICZjdCwgaW50IGZhc3RfbG9va3VwX2JpdHMgPSBiYXNpc3U6OmNIdWZmbWFuRmFzdExvb2t1cEJpdHMpCgkJewoJCQlhc3NlcnQoY3QubV9jb2RlX3NpemVzLnNpemUoKSk7CgoJCQljb25zdCB1aW50MzJfdCBodWZmbWFuX2Zhc3RfbG9va3VwX3NpemUgPSAxIDw8IGZhc3RfbG9va3VwX2JpdHM7CgkJCQkJCQoJCQl3aGlsZSAobV9iaXRfYnVmX3NpemUgPCAxNikKCQkJewoJCQkJdWludDMyX3QgYyA9IDA7CgkJCQlpZiAobV9wQnVmIDwgbV9wQnVmX2VuZCkKCQkJCQljID0gKm1fcEJ1ZisrOwoKCQkJCW1fYml0X2J1ZiB8PSAoYyA8PCBtX2JpdF9idWZfc2l6ZSk7CgkJCQltX2JpdF9idWZfc2l6ZSArPSA4OwoJCQkJYXNzZXJ0KG1fYml0X2J1Zl9zaXplIDw9IDMyKTsKCQkJfQoJCQkJCQkKCQkJaW50IGNvZGVfbGVuOwoKCQkJaW50IHN5bTsKCQkJaWYgKChzeW0gPSBjdC5tX2xvb2t1cFttX2JpdF9idWYgJiAoaHVmZm1hbl9mYXN0X2xvb2t1cF9zaXplIC0gMSldKSA+PSAwKQoJCQl7CgkJCQljb2RlX2xlbiA9IHN5bSA+PiAxNjsKCQkJCXN5bSAmPSAweEZGRkY7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQljb2RlX2xlbiA9IGZhc3RfbG9va3VwX2JpdHM7CgkJCQlkbwoJCQkJewoJCQkJCXN5bSA9IGN0Lm1fdHJlZVt+c3ltICsgKChtX2JpdF9idWYgPj4gY29kZV9sZW4rKykgJiAxKV07IC8vIH5zeW0gPSAtc3ltIC0gMQoJCQkJfSB3aGlsZSAoc3ltIDwgMCk7CgkJCX0KCgkJCW1fYml0X2J1ZiA+Pj0gY29kZV9sZW47CgkJCW1fYml0X2J1Zl9zaXplIC09IGNvZGVfbGVuOwoKCQkJcmV0dXJuIHN5bTsKCQl9CgoJCWJvb2wgcmVhZF9odWZmbWFuX3RhYmxlKGh1ZmZtYW5fZGVjb2RpbmdfdGFibGUgJmN0KQoJCXsKCQkJY3QuY2xlYXIoKTsKCgkJCWNvbnN0IHVpbnQzMl90IHRvdGFsX3VzZWRfc3ltcyA9IGdldF9iaXRzKGJhc2lzdTo6Y0h1ZmZtYW5NYXhTeW1zTG9nMik7CgoJCQlpZiAoIXRvdGFsX3VzZWRfc3ltcykKCQkJCXJldHVybiB0cnVlOwoJCQlpZiAodG90YWxfdXNlZF9zeW1zID4gYmFzaXN1OjpjSHVmZm1hbk1heFN5bXMpCgkJCQlyZXR1cm4gZmFsc2U7CgoJCQl1aW50OF90IGNvZGVfbGVuZ3RoX2NvZGVfc2l6ZXNbYmFzaXN1OjpjSHVmZm1hblRvdGFsQ29kZWxlbmd0aENvZGVzXTsKCQkJYmFzaXN1OjpjbGVhcl9vYmooY29kZV9sZW5ndGhfY29kZV9zaXplcyk7CgoJCQljb25zdCB1aW50MzJfdCBudW1fY29kZWxlbmd0aF9jb2RlcyA9IGdldF9iaXRzKDUpOwoJCQlpZiAoKG51bV9jb2RlbGVuZ3RoX2NvZGVzIDwgMSkgfHwgKG51bV9jb2RlbGVuZ3RoX2NvZGVzID4gYmFzaXN1OjpjSHVmZm1hblRvdGFsQ29kZWxlbmd0aENvZGVzKSkKCQkJCXJldHVybiBmYWxzZTsKCgkJCWZvciAodWludDMyX3QgaSA9IDA7IGkgPCBudW1fY29kZWxlbmd0aF9jb2RlczsgaSsrKQoJCQkJY29kZV9sZW5ndGhfY29kZV9zaXplc1tiYXNpc3U6OmdfaHVmZm1hbl9zb3J0ZWRfY29kZWxlbmd0aF9jb2Rlc1tpXV0gPSBzdGF0aWNfY2FzdDx1aW50OF90PihnZXRfYml0cygzKSk7CgoJCQlodWZmbWFuX2RlY29kaW5nX3RhYmxlIGNvZGVfbGVuZ3RoX3RhYmxlOwoJCQlpZiAoIWNvZGVfbGVuZ3RoX3RhYmxlLmluaXQoYmFzaXN1OjpjSHVmZm1hblRvdGFsQ29kZWxlbmd0aENvZGVzLCBjb2RlX2xlbmd0aF9jb2RlX3NpemVzKSkKCQkJCXJldHVybiBmYWxzZTsKCgkJCWlmICghY29kZV9sZW5ndGhfdGFibGUuaXNfdmFsaWQoKSkKCQkJCXJldHVybiBmYWxzZTsKCgkJCWJhc2lzdTo6dWludDhfdmVjIGNvZGVfc2l6ZXModG90YWxfdXNlZF9zeW1zKTsKCgkJCXVpbnQzMl90IGN1ciA9IDA7CgkJCXdoaWxlIChjdXIgPCB0b3RhbF91c2VkX3N5bXMpCgkJCXsKCQkJCWludCBjID0gZGVjb2RlX2h1ZmZtYW4oY29kZV9sZW5ndGhfdGFibGUpOwoKCQkJCWlmIChjIDw9IDE2KQoJCQkJCWNvZGVfc2l6ZXNbY3VyKytdID0gc3RhdGljX2Nhc3Q8dWludDhfdD4oYyk7CgkJCQllbHNlIGlmIChjID09IGJhc2lzdTo6Y0h1ZmZtYW5TbWFsbFplcm9SdW5Db2RlKQoJCQkJCWN1ciArPSBnZXRfYml0cyhiYXNpc3U6OmNIdWZmbWFuU21hbGxaZXJvUnVuRXh0cmFCaXRzKSArIGJhc2lzdTo6Y0h1ZmZtYW5TbWFsbFplcm9SdW5TaXplTWluOwoJCQkJZWxzZSBpZiAoYyA9PSBiYXNpc3U6OmNIdWZmbWFuQmlnWmVyb1J1bkNvZGUpCgkJCQkJY3VyICs9IGdldF9iaXRzKGJhc2lzdTo6Y0h1ZmZtYW5CaWdaZXJvUnVuRXh0cmFCaXRzKSArIGJhc2lzdTo6Y0h1ZmZtYW5CaWdaZXJvUnVuU2l6ZU1pbjsKCQkJCWVsc2UKCQkJCXsKCQkJCQlpZiAoIWN1cikKCQkJCQkJcmV0dXJuIGZhbHNlOwoKCQkJCQl1aW50MzJfdCBsOwoJCQkJCWlmIChjID09IGJhc2lzdTo6Y0h1ZmZtYW5TbWFsbFJlcGVhdENvZGUpCgkJCQkJCWwgPSBnZXRfYml0cyhiYXNpc3U6OmNIdWZmbWFuU21hbGxSZXBlYXRFeHRyYUJpdHMpICsgYmFzaXN1OjpjSHVmZm1hblNtYWxsUmVwZWF0U2l6ZU1pbjsKCQkJCQllbHNlCgkJCQkJCWwgPSBnZXRfYml0cyhiYXNpc3U6OmNIdWZmbWFuQmlnUmVwZWF0RXh0cmFCaXRzKSArIGJhc2lzdTo6Y0h1ZmZtYW5CaWdSZXBlYXRTaXplTWluOwoKCQkJCQljb25zdCB1aW50OF90IHByZXYgPSBjb2RlX3NpemVzW2N1ciAtIDFdOwoJCQkJCWlmIChwcmV2ID09IDApCgkJCQkJCXJldHVybiBmYWxzZTsKCQkJCQlkbwoJCQkJCXsKCQkJCQkJaWYgKGN1ciA+PSB0b3RhbF91c2VkX3N5bXMpCgkJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJCWNvZGVfc2l6ZXNbY3VyKytdID0gcHJldjsKCQkJCQl9IHdoaWxlICgtLWwgPiAwKTsKCQkJCX0KCQkJfQoKCQkJaWYgKGN1ciAhPSB0b3RhbF91c2VkX3N5bXMpCgkJCQlyZXR1cm4gZmFsc2U7CgoJCQlyZXR1cm4gY3QuaW5pdCh0b3RhbF91c2VkX3N5bXMsICZjb2RlX3NpemVzWzBdKTsKCQl9CgoJCXNpemVfdCBnZXRfYml0c19yZW1haW5pbmcoKSBjb25zdAoJCXsKCQkJc2l6ZV90IHRvdGFsX2J5dGVzX3JlbWFpbmluZyA9IG1fcEJ1Zl9lbmQgLSBtX3BCdWY7CgkJCXJldHVybiB0b3RhbF9ieXRlc19yZW1haW5pbmcgKiA4ICsgbV9iaXRfYnVmX3NpemU7CgkJfQoKCXByaXZhdGU6CgkJdWludDMyX3QgbV9idWZfc2l6ZTsKCQljb25zdCB1aW50OF90ICptX3BCdWY7CgkJY29uc3QgdWludDhfdCAqbV9wQnVmX3N0YXJ0OwoJCWNvbnN0IHVpbnQ4X3QgKm1fcEJ1Zl9lbmQ7CgoJCXVpbnQzMl90IG1fYml0X2J1ZjsKCQl1aW50MzJfdCBtX2JpdF9idWZfc2l6ZTsKCX07CgoJY2xhc3Mgc2ltcGxpZmllZF9iaXR3aXNlX2RlY29kZXIKCXsKCXB1YmxpYzoKCQlzaW1wbGlmaWVkX2JpdHdpc2VfZGVjb2RlcigpIDoKCQkJbV9wQnVmKG51bGxwdHIpLAoJCQltX3BCdWZfZW5kKG51bGxwdHIpLAoJCQltX2JpdF9idWYoMCkKCQl7CgkJfQoKCQl2b2lkIGNsZWFyKCkKCQl7CgkJCW1fcEJ1ZiA9IG51bGxwdHI7CgkJCW1fcEJ1Zl9lbmQgPSBudWxscHRyOwoJCQltX2JpdF9idWYgPSAwOwoJCX0KCgkJYm9vbCBpbml0KGNvbnN0IHVpbnQ4X3QqIHBCdWYsIHNpemVfdCBidWZfc2l6ZSkKCQl7CgkJCWlmICgoIXBCdWYpICYmIChidWZfc2l6ZSkpCgkJCQlyZXR1cm4gZmFsc2U7CgoJCQltX3BCdWYgPSBwQnVmOwoJCQltX3BCdWZfZW5kID0gcEJ1ZiArIGJ1Zl9zaXplOwoJCQltX2JpdF9idWYgPSAxOwoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCWJvb2wgaW5pdChjb25zdCBiYXNpc3U6OnVpbnQ4X3ZlYyYgYnVmKQoJCXsKCQkJcmV0dXJuIGluaXQoYnVmLmRhdGEoKSwgYnVmLnNpemUoKSk7CgkJfQoKCQkvLyBudW1fYml0cyBtdXN0IGJlIDEsIDIsIDQgb3IgOCBhbmQgY29kZXMgY2Fubm90IGNyb3NzIGJ5dGVzCgkJaW5saW5lIHVpbnQzMl90IGdldF9iaXRzKHVpbnQzMl90IG51bV9iaXRzKQoJCXsKCQkJYXNzZXJ0KG1fcEJ1Zik7CgoJCQlpZiAobV9iaXRfYnVmIDw9IDEpCgkJCQltX2JpdF9idWYgPSAyNTYgfCAoKG1fcEJ1ZiA8IG1fcEJ1Zl9lbmQpID8gKm1fcEJ1ZisrIDogMCk7CgoJCQljb25zdCB1aW50MzJfdCBtYXNrID0gKDEgPDwgbnVtX2JpdHMpIC0gMTsKCQkJY29uc3QgdWludDMyX3QgcmVzID0gbV9iaXRfYnVmICYgbWFzazsKCQkJbV9iaXRfYnVmID4+PSBudW1fYml0czsKCQkJYXNzZXJ0KG1fYml0X2J1ZiA+PSAxKTsKCgkJCXJldHVybiByZXM7CgkJfQoKCQlpbmxpbmUgdWludDMyX3QgZ2V0X2JpdHMxKCkKCQl7CgkJCWFzc2VydChtX3BCdWYpOwoJCQlpZiAobV9iaXRfYnVmIDw9IDEpCgkJCQltX2JpdF9idWYgPSAyNTYgfCAoKG1fcEJ1ZiA8IG1fcEJ1Zl9lbmQpID8gKm1fcEJ1ZisrIDogMCk7CgkJCWNvbnN0IHVpbnQzMl90IHJlcyA9IG1fYml0X2J1ZiAmIDE7CgkJCW1fYml0X2J1ZiA+Pj0gMTsKCQkJYXNzZXJ0KG1fYml0X2J1ZiA+PSAxKTsKCQkJcmV0dXJuIHJlczsKCQl9CgoJCWlubGluZSB1aW50MzJfdCBnZXRfYml0czIoKQoJCXsKCQkJYXNzZXJ0KG1fcEJ1Zik7CgkJCWlmIChtX2JpdF9idWYgPD0gMSkKCQkJCW1fYml0X2J1ZiA9IDI1NiB8ICgobV9wQnVmIDwgbV9wQnVmX2VuZCkgPyAqbV9wQnVmKysgOiAwKTsKCQkJY29uc3QgdWludDMyX3QgcmVzID0gbV9iaXRfYnVmICYgMzsKCQkJbV9iaXRfYnVmID4+PSAyOwoJCQlhc3NlcnQobV9iaXRfYnVmID49IDEpOwoJCQlyZXR1cm4gcmVzOwoJCX0KCgkJaW5saW5lIHVpbnQzMl90IGdldF9iaXRzNCgpCgkJewoJCQlhc3NlcnQobV9wQnVmKTsKCQkJaWYgKG1fYml0X2J1ZiA8PSAxKQoJCQkJbV9iaXRfYnVmID0gMjU2IHwgKChtX3BCdWYgPCBtX3BCdWZfZW5kKSA/ICptX3BCdWYrKyA6IDApOwoJCQljb25zdCB1aW50MzJfdCByZXMgPSBtX2JpdF9idWYgJiAxNTsKCQkJbV9iaXRfYnVmID4+PSA0OwoJCQlhc3NlcnQobV9iaXRfYnVmID49IDEpOwoJCQlyZXR1cm4gcmVzOwoJCX0KCgkJLy8gTm8gYml0YnVmZmVyLCBjYW4gb25seSBldmVyIHJldHJpZXZlIGJ5dGVzIGNvcnJlY3RseS4KCQlpbmxpbmUgdWludDMyX3QgZ2V0X2JpdHM4KCkKCQl7CgkJCWFzc2VydChtX3BCdWYpOwoJCQlyZXR1cm4gKG1fcEJ1ZiA8IG1fcEJ1Zl9lbmQpID8gKm1fcEJ1ZisrIDogMDsKCQl9CgoJCWNvbnN0IHVpbnQ4X3QqIG1fcEJ1ZjsKCQljb25zdCB1aW50OF90KiBtX3BCdWZfZW5kOwoJCXVpbnQzMl90IG1fYml0X2J1ZjsKCX07CgoJaW5saW5lIHVpbnQzMl90IGJhc2lzZF9yYW5kKHVpbnQzMl90IHNlZWQpCgl7CgkJaWYgKCFzZWVkKQoJCQlzZWVkKys7CgkJdWludDMyX3QgeiA9IHNlZWQ7CgkJQkFTSVNEX3puZXc7CgkJcmV0dXJuIHo7Cgl9CgoJLy8gUmV0dXJucyByYW5kb20gbnVtYmVyIGluIFswLGxpbWl0KS4gTWF4IGxpbWl0IGlzIDB4RkZGRi4KCWlubGluZSB1aW50MzJfdCBiYXNpc2RfdXJhbmQodWludDMyX3QmIHNlZWQsIHVpbnQzMl90IGxpbWl0KQoJewoJCXNlZWQgPSBiYXNpc2RfcmFuZChzZWVkKTsKCQlyZXR1cm4gKCgoc2VlZCBeIChzZWVkID4+IDE2KSkgJiAweEZGRkYpICogbGltaXQpID4+IDE2OwoJfQoKCWNsYXNzIGFwcHJveF9tb3ZlX3RvX2Zyb250Cgl7CglwdWJsaWM6CgkJYXBwcm94X21vdmVfdG9fZnJvbnQodWludDMyX3QgbikKCQl7CgkJCWluaXQobik7CgkJfQoKCQl2b2lkIGluaXQodWludDMyX3QgbikKCQl7CgkJCW1fdmFsdWVzLnJlc2l6ZShuKTsKCQkJbV9yb3ZlciA9IG4gLyAyOwoJCX0KCgkJY29uc3QgYmFzaXN1OjppbnRfdmVjJiBnZXRfdmFsdWVzKCkgY29uc3QgeyByZXR1cm4gbV92YWx1ZXM7IH0KCQliYXNpc3U6OmludF92ZWMmIGdldF92YWx1ZXMoKSB7IHJldHVybiBtX3ZhbHVlczsgfQoKCQl1aW50MzJfdCBzaXplKCkgY29uc3QgeyByZXR1cm4gKHVpbnQzMl90KW1fdmFsdWVzLnNpemUoKTsgfQoKCQljb25zdCBpbnQmIG9wZXJhdG9yW10gKHVpbnQzMl90IGluZGV4KSBjb25zdCB7IHJldHVybiBtX3ZhbHVlc1tpbmRleF07IH0KCQlpbnQgb3BlcmF0b3JbXSAodWludDMyX3QgaW5kZXgpIHsgcmV0dXJuIG1fdmFsdWVzW2luZGV4XTsgfQoKCQl2b2lkIGFkZChpbnQgbmV3X3ZhbHVlKQoJCXsKCQkJbV92YWx1ZXNbbV9yb3ZlcisrXSA9IG5ld192YWx1ZTsKCQkJaWYgKG1fcm92ZXIgPT0gbV92YWx1ZXMuc2l6ZSgpKQoJCQkJbV9yb3ZlciA9ICh1aW50MzJfdCltX3ZhbHVlcy5zaXplKCkgLyAyOwoJCX0KCgkJdm9pZCB1c2UodWludDMyX3QgaW5kZXgpCgkJewoJCQlpZiAoaW5kZXgpCgkJCXsKCQkJCS8vc3RkOjpzd2FwKG1fdmFsdWVzW2luZGV4IC8gMl0sIG1fdmFsdWVzW2luZGV4XSk7CgkJCQlpbnQgeCA9IG1fdmFsdWVzW2luZGV4IC8gMl07CgkJCQlpbnQgeSA9IG1fdmFsdWVzW2luZGV4XTsKCQkJCW1fdmFsdWVzW2luZGV4IC8gMl0gPSB5OwoJCQkJbV92YWx1ZXNbaW5kZXhdID0geDsKCQkJfQoJCX0KCgkJLy8gcmV0dXJucyAtMSBpZiBub3QgZm91bmQKCQlpbnQgZmluZChpbnQgdmFsdWUpIGNvbnN0CgkJewoJCQlmb3IgKHVpbnQzMl90IGkgPSAwOyBpIDwgbV92YWx1ZXMuc2l6ZSgpOyBpKyspCgkJCQlpZiAobV92YWx1ZXNbaV0gPT0gdmFsdWUpCgkJCQkJcmV0dXJuIGk7CgkJCXJldHVybiAtMTsKCQl9CgoJCXZvaWQgcmVzZXQoKQoJCXsKCQkJY29uc3QgdWludDMyX3QgbiA9ICh1aW50MzJfdCltX3ZhbHVlcy5zaXplKCk7CgoJCQltX3ZhbHVlcy5jbGVhcigpOwoKCQkJaW5pdChuKTsKCQl9CgoJcHJpdmF0ZToKCQliYXNpc3U6OmludF92ZWMgbV92YWx1ZXM7CgkJdWludDMyX3QgbV9yb3ZlcjsKCX07CgoJc3RydWN0IGRlY29kZXJfZXRjX2Jsb2NrOwoJCglpbmxpbmUgdWludDhfdCBjbGFtcDI1NShpbnQzMl90IGkpCgl7CgkJcmV0dXJuICh1aW50OF90KSgoaSAmIDB4RkZGRkZGMDBVKSA/ICh+KGkgPj4gMzEpKSA6IGkpOwoJfQoKCWVudW0gZU5vQ2xhbXAKCXsKCQljTm9DbGFtcCA9IDAKCX07CgoJc3RydWN0IGNvbG9yMzIKCXsKCQl1bmlvbgoJCXsKCQkJc3RydWN0CgkJCXsKCQkJCXVpbnQ4X3QgcjsKCQkJCXVpbnQ4X3QgZzsKCQkJCXVpbnQ4X3QgYjsKCQkJCXVpbnQ4X3QgYTsKCQkJfTsKCgkJCXVpbnQ4X3QgY1s0XTsKCQkJCgkJCXVpbnQzMl90IG07CgkJfTsKCgkJLy9jb2xvcjMyKCkgeyB9CgkJY29sb3IzMigpID0gZGVmYXVsdDsKCgkJY29sb3IzMih1aW50MzJfdCB2ciwgdWludDMyX3QgdmcsIHVpbnQzMl90IHZiLCB1aW50MzJfdCB2YSkgeyBzZXQodnIsIHZnLCB2YiwgdmEpOyB9CgkJY29sb3IzMihlTm9DbGFtcCB1bnVzZWQsIHVpbnQzMl90IHZyLCB1aW50MzJfdCB2ZywgdWludDMyX3QgdmIsIHVpbnQzMl90IHZhKSB7ICh2b2lkKXVudXNlZDsgc2V0X25vY2xhbXBfcmdiYSh2ciwgdmcsIHZiLCB2YSk7IH0KCgkJdm9pZCBzZXQodWludDMyX3QgdnIsIHVpbnQzMl90IHZnLCB1aW50MzJfdCB2YiwgdWludDMyX3QgdmEpIHsgY1swXSA9IHN0YXRpY19jYXN0PHVpbnQ4X3Q+KHZyKTsgY1sxXSA9IHN0YXRpY19jYXN0PHVpbnQ4X3Q+KHZnKTsgY1syXSA9IHN0YXRpY19jYXN0PHVpbnQ4X3Q+KHZiKTsgY1szXSA9IHN0YXRpY19jYXN0PHVpbnQ4X3Q+KHZhKTsgfQoKCQl2b2lkIHNldF9ub2NsYW1wX3JnYih1aW50MzJfdCB2ciwgdWludDMyX3QgdmcsIHVpbnQzMl90IHZiKSB7IGNbMF0gPSBzdGF0aWNfY2FzdDx1aW50OF90Pih2cik7IGNbMV0gPSBzdGF0aWNfY2FzdDx1aW50OF90Pih2Zyk7IGNbMl0gPSBzdGF0aWNfY2FzdDx1aW50OF90Pih2Yik7IH0KCQl2b2lkIHNldF9ub2NsYW1wX3JnYmEodWludDMyX3QgdnIsIHVpbnQzMl90IHZnLCB1aW50MzJfdCB2YiwgdWludDMyX3QgdmEpIHsgc2V0KHZyLCB2ZywgdmIsIHZhKTsgfQoKCQl2b2lkIHNldF9jbGFtcGVkKGludCB2ciwgaW50IHZnLCBpbnQgdmIsIGludCB2YSkgeyBjWzBdID0gY2xhbXAyNTUodnIpOyBjWzFdID0gY2xhbXAyNTUodmcpOwljWzJdID0gY2xhbXAyNTUodmIpOyBjWzNdID0gY2xhbXAyNTUodmEpOyB9CgoJCXVpbnQ4X3Qgb3BlcmF0b3JbXSAodWludDMyX3QgaWR4KSBjb25zdCB7IGFzc2VydChpZHggPCA0KTsgcmV0dXJuIGNbaWR4XTsgfQoJCXVpbnQ4X3QgJm9wZXJhdG9yW10gKHVpbnQzMl90IGlkeCkgeyBhc3NlcnQoaWR4IDwgNCk7IHJldHVybiBjW2lkeF07IH0KCgkJYm9vbCBvcGVyYXRvcj09IChjb25zdCBjb2xvcjMyJnJocykgY29uc3QgeyByZXR1cm4gbSA9PSByaHMubTsgfQoKCQlzdGF0aWMgY29sb3IzMiBjb21wX21pbihjb25zdCBjb2xvcjMyJiBhLCBjb25zdCBjb2xvcjMyJiBiKSB7IHJldHVybiBjb2xvcjMyKGNOb0NsYW1wLCBiYXNpc3U6Om1pbmltdW0oYVswXSwgYlswXSksIGJhc2lzdTo6bWluaW11bShhWzFdLCBiWzFdKSwgYmFzaXN1OjptaW5pbXVtKGFbMl0sIGJbMl0pLCBiYXNpc3U6Om1pbmltdW0oYVszXSwgYlszXSkpOyB9CgkJc3RhdGljIGNvbG9yMzIgY29tcF9tYXgoY29uc3QgY29sb3IzMiYgYSwgY29uc3QgY29sb3IzMiYgYikgeyByZXR1cm4gY29sb3IzMihjTm9DbGFtcCwgYmFzaXN1OjptYXhpbXVtKGFbMF0sIGJbMF0pLCBiYXNpc3U6Om1heGltdW0oYVsxXSwgYlsxXSksIGJhc2lzdTo6bWF4aW11bShhWzJdLCBiWzJdKSwgYmFzaXN1OjptYXhpbXVtKGFbM10sIGJbM10pKTsgfQoJfTsKCglzdHJ1Y3QgZW5kcG9pbnQKCXsKCQljb2xvcjMyIG1fY29sb3I1OwoJCXVpbnQ4X3QgbV9pbnRlbjU7CgkJYm9vbCBvcGVyYXRvcj09IChjb25zdCBlbmRwb2ludCYgcmhzKSBjb25zdAoJCXsKCQkJcmV0dXJuIChtX2NvbG9yNS5yID09IHJocy5tX2NvbG9yNS5yKSAmJiAobV9jb2xvcjUuZyA9PSByaHMubV9jb2xvcjUuZykgJiYgKG1fY29sb3I1LmIgPT0gcmhzLm1fY29sb3I1LmIpICYmIChtX2ludGVuNSA9PSByaHMubV9pbnRlbjUpOwoJCX0KCQlib29sIG9wZXJhdG9yIT0gKGNvbnN0IGVuZHBvaW50JiByaHMpIGNvbnN0IHsgcmV0dXJuICEoKnRoaXMgPT0gcmhzKTsgfQoJfTsKCgkvLyBUaGlzIGR1cGxpY2F0ZXMga2V5IGZ1bmN0aW9uYWxpdHkgaW4gdGhlIGVuY29kZXIgbGlicmFyeSdzIGNvbG9yX3JnYmEgY2xhc3MuIFBvcnRpbmcgYW5kIHJldGVzdGluZyBjb2RlIHRoYXQgdXNlcyBpdCB0byBjb2xvcjMyIGlzIGltcHJhY3RpY2FsLgoJY2xhc3MgY29sb3JfcmdiYQoJewoJcHVibGljOgoJCXVuaW9uCgkJewoJCQl1aW50OF90IG1fY29tcHNbNF07CgoJCQlzdHJ1Y3QKCQkJewoJCQkJdWludDhfdCByOwoJCQkJdWludDhfdCBnOwoJCQkJdWludDhfdCBiOwoJCQkJdWludDhfdCBhOwoJCQl9OwoJCX07CgoJCWlubGluZSBjb2xvcl9yZ2JhKCkKCQl7CgkJCXN0YXRpY19hc3NlcnQoc2l6ZW9mKCp0aGlzKSA9PSA0LCAic2l6ZW9mKCp0aGlzKSAhPSA0Iik7CgkJCXN0YXRpY19hc3NlcnQoc2l6ZW9mKCp0aGlzKSA9PSBzaXplb2YoY29sb3IzMiksICJzaXplb2YoKnRoaXMpICE9IHNpemVvZihiYXNpc3Q6OmNvbG9yMzIpIik7CgkJfQoKCQlpbmxpbmUgY29sb3JfcmdiYShjb25zdCBjb2xvcjMyJiBvdGhlcikgOgoJCQlyKG90aGVyLnIpLAoJCQlnKG90aGVyLmcpLAoJCQliKG90aGVyLmIpLAoJCQlhKG90aGVyLmEpCgkJewoJCX0KCgkJY29sb3JfcmdiYSYgb3BlcmF0b3I9IChjb25zdCBiYXNpc3Q6OmNvbG9yMzImIHJocykKCQl7CgkJCXIgPSByaHMucjsKCQkJZyA9IHJocy5nOwoJCQliID0gcmhzLmI7CgkJCWEgPSByaHMuYTsKCQkJcmV0dXJuICp0aGlzOwoJCX0KCgkJaW5saW5lIGNvbG9yX3JnYmEoaW50IHkpCgkJewoJCQlzZXQoeSk7CgkJfQoKCQlpbmxpbmUgY29sb3JfcmdiYShpbnQgeSwgaW50IG5hKQoJCXsKCQkJc2V0KHksIG5hKTsKCQl9CgoJCWlubGluZSBjb2xvcl9yZ2JhKGludCBzciwgaW50IHNnLCBpbnQgc2IsIGludCBzYSkKCQl7CgkJCXNldChzciwgc2csIHNiLCBzYSk7CgkJfQoKCQlpbmxpbmUgY29sb3JfcmdiYShlTm9DbGFtcCwgaW50IHNyLCBpbnQgc2csIGludCBzYiwgaW50IHNhKQoJCXsKCQkJc2V0X25vY2xhbXBfcmdiYSgodWludDhfdClzciwgKHVpbnQ4X3Qpc2csICh1aW50OF90KXNiLCAodWludDhfdClzYSk7CgkJfQoKCQlpbmxpbmUgY29sb3JfcmdiYSYgc2V0X25vY2xhbXBfeShpbnQgeSkKCQl7CgkJCW1fY29tcHNbMF0gPSAodWludDhfdCl5OwoJCQltX2NvbXBzWzFdID0gKHVpbnQ4X3QpeTsKCQkJbV9jb21wc1syXSA9ICh1aW50OF90KXk7CgkJCW1fY29tcHNbM10gPSAodWludDhfdCkyNTU7CgkJCXJldHVybiAqdGhpczsKCQl9CgoJCWlubGluZSBjb2xvcl9yZ2JhJiBzZXRfbm9jbGFtcF9yZ2JhKGludCBzciwgaW50IHNnLCBpbnQgc2IsIGludCBzYSkKCQl7CgkJCW1fY29tcHNbMF0gPSAodWludDhfdClzcjsKCQkJbV9jb21wc1sxXSA9ICh1aW50OF90KXNnOwoJCQltX2NvbXBzWzJdID0gKHVpbnQ4X3Qpc2I7CgkJCW1fY29tcHNbM10gPSAodWludDhfdClzYTsKCQkJcmV0dXJuICp0aGlzOwoJCX0KCgkJaW5saW5lIGNvbG9yX3JnYmEmIHNldChpbnQgeSkKCQl7CgkJCW1fY29tcHNbMF0gPSBzdGF0aWNfY2FzdDx1aW50OF90PihiYXNpc3U6OmNsYW1wPGludD4oeSwgMCwgMjU1KSk7CgkJCW1fY29tcHNbMV0gPSBtX2NvbXBzWzBdOwoJCQltX2NvbXBzWzJdID0gbV9jb21wc1swXTsKCQkJbV9jb21wc1szXSA9IDI1NTsKCQkJcmV0dXJuICp0aGlzOwoJCX0KCgkJaW5saW5lIGNvbG9yX3JnYmEmIHNldChpbnQgeSwgaW50IG5hKQoJCXsKCQkJbV9jb21wc1swXSA9IHN0YXRpY19jYXN0PHVpbnQ4X3Q+KGJhc2lzdTo6Y2xhbXA8aW50Pih5LCAwLCAyNTUpKTsKCQkJbV9jb21wc1sxXSA9IG1fY29tcHNbMF07CgkJCW1fY29tcHNbMl0gPSBtX2NvbXBzWzBdOwoJCQltX2NvbXBzWzNdID0gc3RhdGljX2Nhc3Q8dWludDhfdD4oYmFzaXN1OjpjbGFtcDxpbnQ+KG5hLCAwLCAyNTUpKTsKCQkJcmV0dXJuICp0aGlzOwoJCX0KCgkJaW5saW5lIGNvbG9yX3JnYmEmIHNldChpbnQgc3IsIGludCBzZywgaW50IHNiLCBpbnQgc2EpCgkJewoJCQltX2NvbXBzWzBdID0gc3RhdGljX2Nhc3Q8dWludDhfdD4oYmFzaXN1OjpjbGFtcDxpbnQ+KHNyLCAwLCAyNTUpKTsKCQkJbV9jb21wc1sxXSA9IHN0YXRpY19jYXN0PHVpbnQ4X3Q+KGJhc2lzdTo6Y2xhbXA8aW50PihzZywgMCwgMjU1KSk7CgkJCW1fY29tcHNbMl0gPSBzdGF0aWNfY2FzdDx1aW50OF90PihiYXNpc3U6OmNsYW1wPGludD4oc2IsIDAsIDI1NSkpOwoJCQltX2NvbXBzWzNdID0gc3RhdGljX2Nhc3Q8dWludDhfdD4oYmFzaXN1OjpjbGFtcDxpbnQ+KHNhLCAwLCAyNTUpKTsKCQkJcmV0dXJuICp0aGlzOwoJCX0KCgkJaW5saW5lIGNvbG9yX3JnYmEmIHNldF9yZ2IoaW50IHNyLCBpbnQgc2csIGludCBzYikKCQl7CgkJCW1fY29tcHNbMF0gPSBzdGF0aWNfY2FzdDx1aW50OF90PihiYXNpc3U6OmNsYW1wPGludD4oc3IsIDAsIDI1NSkpOwoJCQltX2NvbXBzWzFdID0gc3RhdGljX2Nhc3Q8dWludDhfdD4oYmFzaXN1OjpjbGFtcDxpbnQ+KHNnLCAwLCAyNTUpKTsKCQkJbV9jb21wc1syXSA9IHN0YXRpY19jYXN0PHVpbnQ4X3Q+KGJhc2lzdTo6Y2xhbXA8aW50PihzYiwgMCwgMjU1KSk7CgkJCXJldHVybiAqdGhpczsKCQl9CgoJCWlubGluZSBjb2xvcl9yZ2JhJiBzZXRfcmdiKGNvbnN0IGNvbG9yX3JnYmEmIG90aGVyKQoJCXsKCQkJciA9IG90aGVyLnI7CgkJCWcgPSBvdGhlci5nOwoJCQliID0gb3RoZXIuYjsKCQkJcmV0dXJuICp0aGlzOwoJCX0KCgkJaW5saW5lIGNvbnN0IHVpbnQ4X3QmIG9wZXJhdG9yW10gKHVpbnQzMl90IGluZGV4KSBjb25zdCB7IGFzc2VydChpbmRleCA8IDQpOyByZXR1cm4gbV9jb21wc1tpbmRleF07IH0KCQlpbmxpbmUgdWludDhfdCYgb3BlcmF0b3JbXSAodWludDMyX3QgaW5kZXgpIHsgYXNzZXJ0KGluZGV4IDwgNCk7IHJldHVybiBtX2NvbXBzW2luZGV4XTsgfQoKCQlpbmxpbmUgdm9pZCBjbGVhcigpCgkJewoJCQltX2NvbXBzWzBdID0gMDsKCQkJbV9jb21wc1sxXSA9IDA7CgkJCW1fY29tcHNbMl0gPSAwOwoJCQltX2NvbXBzWzNdID0gMDsKCQl9CgoJCWlubGluZSBib29sIG9wZXJhdG9yPT0gKGNvbnN0IGNvbG9yX3JnYmEmIHJocykgY29uc3QKCQl7CgkJCWlmIChtX2NvbXBzWzBdICE9IHJocy5tX2NvbXBzWzBdKSByZXR1cm4gZmFsc2U7CgkJCWlmIChtX2NvbXBzWzFdICE9IHJocy5tX2NvbXBzWzFdKSByZXR1cm4gZmFsc2U7CgkJCWlmIChtX2NvbXBzWzJdICE9IHJocy5tX2NvbXBzWzJdKSByZXR1cm4gZmFsc2U7CgkJCWlmIChtX2NvbXBzWzNdICE9IHJocy5tX2NvbXBzWzNdKSByZXR1cm4gZmFsc2U7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJaW5saW5lIGJvb2wgb3BlcmF0b3IhPSAoY29uc3QgY29sb3JfcmdiYSYgcmhzKSBjb25zdAoJCXsKCQkJcmV0dXJuICEoKnRoaXMgPT0gcmhzKTsKCQl9CgoJCWlubGluZSBib29sIG9wZXJhdG9yPChjb25zdCBjb2xvcl9yZ2JhJiByaHMpIGNvbnN0CgkJewoJCQlmb3IgKGludCBpID0gMDsgaSA8IDQ7IGkrKykKCQkJewoJCQkJaWYgKG1fY29tcHNbaV0gPCByaHMubV9jb21wc1tpXSkKCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCWVsc2UgaWYgKG1fY29tcHNbaV0gIT0gcmhzLm1fY29tcHNbaV0pCgkJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCWlubGluZSBjb2xvcjMyIGdldF9jb2xvcjMyKCkgY29uc3QKCQl7CgkJCXJldHVybiBjb2xvcjMyKHIsIGcsIGIsIGEpOwoJCX0KCgkJaW5saW5lIGludCBnZXRfNzA5X2x1bWEoKSBjb25zdCB7IHJldHVybiAoMTM5MzhVICogbV9jb21wc1swXSArIDQ2ODY5VSAqIG1fY29tcHNbMV0gKyA0NzI5VSAqIG1fY29tcHNbMl0gKyAzMjc2OFUpID4+IDE2VTsgfQoJfTsKCglzdHJ1Y3Qgc2VsZWN0b3IKCXsKCQkvLyBQbGFpbiBzZWxlY3RvcnMgKDItYml0cyBwZXIgdmFsdWUpCgkJdWludDhfdCBtX3NlbGVjdG9yc1s0XTsKCgkJLy8gRVRDMSBzZWxlY3RvcnMKCQl1aW50OF90IG1fYnl0ZXNbNF07CgoJCXVpbnQ4X3QgbV9sb19zZWxlY3RvciwgbV9oaV9zZWxlY3RvcjsKCQl1aW50OF90IG1fbnVtX3VuaXF1ZV9zZWxlY3RvcnM7CgkJYm9vbCBvcGVyYXRvcj09IChjb25zdCBzZWxlY3RvciYgcmhzKSBjb25zdAoJCXsKCQkJcmV0dXJuIChtX3NlbGVjdG9yc1swXSA9PSByaHMubV9zZWxlY3RvcnNbMF0pICYmCgkJCQkobV9zZWxlY3RvcnNbMV0gPT0gcmhzLm1fc2VsZWN0b3JzWzFdKSAmJgoJCQkJKG1fc2VsZWN0b3JzWzJdID09IHJocy5tX3NlbGVjdG9yc1syXSkgJiYKCQkJCShtX3NlbGVjdG9yc1szXSA9PSByaHMubV9zZWxlY3RvcnNbM10pOwoJCX0KCQlib29sIG9wZXJhdG9yIT0gKGNvbnN0IHNlbGVjdG9yJiByaHMpIGNvbnN0CgkJewoJCQlyZXR1cm4gISgqdGhpcyA9PSByaHMpOwoJCX0KCgkJdm9pZCBpbml0X2ZsYWdzKCkKCQl7CgkJCXVpbnQzMl90IGhpc3RbNF0gPSB7IDAsIDAsIDAsIDAgfTsKCQkJZm9yICh1aW50MzJfdCB5ID0gMDsgeSA8IDQ7IHkrKykKCQkJewoJCQkJZm9yICh1aW50MzJfdCB4ID0gMDsgeCA8IDQ7IHgrKykKCQkJCXsKCQkJCQl1aW50MzJfdCBzID0gZ2V0X3NlbGVjdG9yKHgsIHkpOwoJCQkJCWhpc3Rbc10rKzsKCQkJCX0KCQkJfQoKCQkJbV9sb19zZWxlY3RvciA9IDM7CgkJCW1faGlfc2VsZWN0b3IgPSAwOwoJCQltX251bV91bmlxdWVfc2VsZWN0b3JzID0gMDsKCgkJCWZvciAodWludDMyX3QgaSA9IDA7IGkgPCA0OyBpKyspCgkJCXsKCQkJCWlmIChoaXN0W2ldKQoJCQkJewoJCQkJCW1fbnVtX3VuaXF1ZV9zZWxlY3RvcnMrKzsKCQkJCQlpZiAoaSA8IG1fbG9fc2VsZWN0b3IpIG1fbG9fc2VsZWN0b3IgPSBzdGF0aWNfY2FzdDx1aW50OF90PihpKTsKCQkJCQlpZiAoaSA+IG1faGlfc2VsZWN0b3IpIG1faGlfc2VsZWN0b3IgPSBzdGF0aWNfY2FzdDx1aW50OF90PihpKTsKCQkJCX0KCQkJfQoJCX0KCgkJLy8gUmV0dXJuZWQgc2VsZWN0b3IgdmFsdWUgcmFuZ2VzIGZyb20gMC0zIGFuZCBpcyBhIGRpcmVjdCBpbmRleCBpbnRvIGdfZXRjMV9pbnRlbl90YWJsZXMuCgkJaW5saW5lIHVpbnQzMl90IGdldF9zZWxlY3Rvcih1aW50MzJfdCB4LCB1aW50MzJfdCB5KSBjb25zdAoJCXsKCQkJYXNzZXJ0KCh4IDwgNCkgJiYgKHkgPCA0KSk7CgkJCXJldHVybiAobV9zZWxlY3RvcnNbeV0gPj4gKHggKiAyKSkgJiAzOwoJCX0KCgkJdm9pZCBzZXRfc2VsZWN0b3IodWludDMyX3QgeCwgdWludDMyX3QgeSwgdWludDMyX3QgdmFsKQoJCXsKCQkJc3RhdGljIGNvbnN0IHVpbnQ4X3Qgc19zZWxlY3Rvcl9pbmRleF90b19ldGMxWzRdID0geyAzLCAyLCAwLCAxIH07CgoJCQlhc3NlcnQoKHggfCB5IHwgdmFsKSA8IDQpOwoKCQkJbV9zZWxlY3RvcnNbeV0gJj0gfigzIDw8ICh4ICogMikpOwoJCQltX3NlbGVjdG9yc1t5XSB8PSAodmFsIDw8ICh4ICogMikpOwoKCQkJY29uc3QgdWludDMyX3QgZXRjMV9iaXRfaW5kZXggPSB4ICogNCArIHk7CgoJCQl1aW50OF90ICpwID0gJm1fYnl0ZXNbMyAtIChldGMxX2JpdF9pbmRleCA+PiAzKV07CgoJCQljb25zdCB1aW50MzJfdCBieXRlX2JpdF9vZnMgPSBldGMxX2JpdF9pbmRleCAmIDc7CgkJCWNvbnN0IHVpbnQzMl90IG1hc2sgPSAxIDw8IGJ5dGVfYml0X29mczsKCgkJCWNvbnN0IHVpbnQzMl90IGV0YzFfdmFsID0gc19zZWxlY3Rvcl9pbmRleF90b19ldGMxW3ZhbF07CgoJCQljb25zdCB1aW50MzJfdCBsc2IgPSBldGMxX3ZhbCAmIDE7CgkJCWNvbnN0IHVpbnQzMl90IG1zYiA9IGV0YzFfdmFsID4+IDE7CgoJCQlwWzBdICY9IH5tYXNrOwoJCQlwWzBdIHw9IChsc2IgPDwgYnl0ZV9iaXRfb2ZzKTsKCgkJCXBbLTJdICY9IH5tYXNrOwoJCQlwWy0yXSB8PSAobXNiIDw8IGJ5dGVfYml0X29mcyk7CgkJfQoJfTsKCglib29sIGJhc2lzX2Jsb2NrX2Zvcm1hdF9pc191bmNvbXByZXNzZWQoYmxvY2tfZm9ybWF0IHRleF90eXBlKTsKCgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCXR5cGVkZWYgdWludDE2X3QgaGFsZl9mbG9hdDsKCgljb25zdCBkb3VibGUgTUlOX0RFTk9STV9IQUxGX0ZMT0FUID0gMC4wMDAwMDAwNTk2MDQ2NDU7IC8vIHNtYWxsZXN0IHBvc2l0aXZlIHN1Ym5vcm1hbCBudW1iZXIKCWNvbnN0IGRvdWJsZSBNSU5fSEFMRl9GTE9BVCA9IDAuMDAwMDYxMDM1MTU2MjU7IC8vIHNtYWxsZXN0IHBvc2l0aXZlIG5vcm1hbCBudW1iZXIKCWNvbnN0IGRvdWJsZSBNQVhfSEFMRl9GTE9BVCA9IDY1NTA0LjA7IC8vIGxhcmdlc3Qgbm9ybWFsIG51bWJlcgoJY29uc3QgdWludDMyX3QgTUFYX0hBTEZfRkxPQVRfQVNfSU5UX0JJVFMgPSAweDdCRkY7IC8vIHRoZSBoYWxmIGZsb2F0IHJlcCBmb3IgNjU1MDQuMAoKCWlubGluZSB1aW50MzJfdCBnZXRfYml0cyh1aW50MzJfdCB2YWwsIGludCBsb3csIGludCBoaWdoKQoJewoJCWNvbnN0IGludCBudW1fYml0cyA9IChoaWdoIC0gbG93KSArIDE7CgkJYXNzZXJ0KChudW1fYml0cyA+PSAxKSAmJiAobnVtX2JpdHMgPD0gMzIpKTsKCgkJdmFsID4+PSBsb3c7CgkJaWYgKG51bV9iaXRzICE9IDMyKQoJCQl2YWwgJj0gKCgxdSA8PCBudW1fYml0cykgLSAxKTsKCgkJcmV0dXJuIHZhbDsKCX0KCglpbmxpbmUgYm9vbCBpc19oYWxmX2luZl9vcl9uYW4oaGFsZl9mbG9hdCB2KQoJewoJCXJldHVybiBnZXRfYml0cyh2LCAxMCwgMTQpID09IDMxOwoJfQoKCWlubGluZSBib29sIGlzX2hhbGZfZGVub3JtKGhhbGZfZmxvYXQgdikKCXsKCQlpbnQgZSA9ICh2ID4+IDEwKSAmIDMxOwoJCXJldHVybiAhZTsKCX0KCglpbmxpbmUgaW50IGdldF9oYWxmX2V4cChoYWxmX2Zsb2F0IHYpCgl7CgkJaW50IGUgPSAoKHYgPj4gMTApICYgMzEpOwoJCXJldHVybiBlID8gKGUgLSAxNSkgOiAtMTQ7Cgl9CgoJaW5saW5lIGludCBnZXRfaGFsZl9tYW50aXNzYShoYWxmX2Zsb2F0IHYpCgl7CgkJaWYgKGlzX2hhbGZfZGVub3JtKHYpKQoJCQlyZXR1cm4gdiAmIDB4M0ZGOwoJCXJldHVybiAodiAmIDB4M0ZGKSB8IDB4NDAwOwoJfQoKCWlubGluZSBmbG9hdCBnZXRfaGFsZl9tYW50aXNzYWYoaGFsZl9mbG9hdCB2KQoJewoJCXJldHVybiAoKGZsb2F0KWdldF9oYWxmX21hbnRpc3NhKHYpKSAvIDEwMjQuMGY7Cgl9CgoJaW5saW5lIGludCBnZXRfaGFsZl9zaWduKGhhbGZfZmxvYXQgdikKCXsKCQlyZXR1cm4gdiA/ICgodiAmIDB4ODAwMCkgPyAtMSA6IDEpIDogMDsKCX0KCglpbmxpbmUgYm9vbCBoYWxmX2lzX3NpZ25lZChoYWxmX2Zsb2F0IHYpCgl7CgkJcmV0dXJuICh2ICYgMHg4MDAwKSAhPSAwOwoJfQoKI2lmIDAKCWludCBoZXhwID0gZ2V0X2hhbGZfZXhwKENmKTsKCWZsb2F0IGhtYW4gPSBnZXRfaGFsZl9tYW50aXNzYWYoQ2YpOwoJaW50IGhzaWduID0gZ2V0X2hhbGZfc2lnbihDZik7CglmbG9hdCBrID0gcG93ZigyLjBmLCBoZXhwKSAqIGhtYW4gKiBoc2lnbjsKCWlmIChpc19oYWxmX2luZl9vcl9uYW4oQ2YpKQoJCWsgPSBzdGQ6Om51bWVyaWNfbGltaXRzPGZsb2F0Pjo6cXVpZXRfTmFOKCk7CiNlbmRpZgoKCWhhbGZfZmxvYXQgZmxvYXRfdG9faGFsZihmbG9hdCB2YWwpOwoKCWlubGluZSBmbG9hdCBoYWxmX3RvX2Zsb2F0KGhhbGZfZmxvYXQgaHZhbCkKCXsKCQl1bmlvbiB7IGZsb2F0IGY7IHVpbnQzMl90IHU7IH0geCA9IHsgMCB9OwoKCQl1aW50MzJfdCBzID0gKCh1aW50MzJfdClodmFsID4+IDE1KSAmIDE7CgkJdWludDMyX3QgZSA9ICgodWludDMyX3QpaHZhbCA+PiAxMCkgJiAweDFGOwoJCXVpbnQzMl90IG0gPSAodWludDMyX3QpaHZhbCAmIDB4M0ZGOwoKCQlpZiAoIWUpCgkJewoJCQlpZiAoIW0pCgkJCXsKCQkJCS8vICstIDAKCQkJCXgudSA9IHMgPDwgMzE7CgkJCQlyZXR1cm4geC5mOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJLy8gZGVub3JtYWxpemVkCgkJCQl3aGlsZSAoIShtICYgMHgwMDAwMDQwMCkpCgkJCQl7CgkJCQkJbSA8PD0gMTsKCQkJCQktLWU7CgkJCQl9CgoJCQkJKytlOwoJCQkJbSAmPSB+MHgwMDAwMDQwMDsKCQkJfQoJCX0KCQllbHNlIGlmIChlID09IDMxKQoJCXsKCQkJaWYgKG0gPT0gMCkKCQkJewoJCQkJLy8gKy8tIElORgoJCQkJeC51ID0gKHMgPDwgMzEpIHwgMHg3ZjgwMDAwMDsKCQkJCXJldHVybiB4LmY7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQkvLyArLy0gTmFOCgkJCQl4LnUgPSAocyA8PCAzMSkgfCAweDdmODAwMDAwIHwgKG0gPDwgMTMpOwoJCQkJcmV0dXJuIHguZjsKCQkJfQoJCX0KCgkJZSA9IGUgKyAoMTI3IC0gMTUpOwoJCW0gPSBtIDw8IDEzOwoKCQlhc3NlcnQocyA8PSAxKTsKCQlhc3NlcnQobSA8PSAweDdGRkZGRik7CgkJYXNzZXJ0KGUgPD0gMjU1KTsKCgkJeC51ID0gbSB8IChlIDw8IDIzKSB8IChzIDw8IDMxKTsKCQlyZXR1cm4geC5mOwoJfQoKCS8vIE9yaWdpbmFsbHkgZnJvbSBiYzZoX2VuYy5oCgoJdm9pZCBiYzZoX2VuY19pbml0KCk7CgoJY29uc3QgdWludDMyX3QgTUFYX0JMT0cxNl9WQUwgPSAweEZGRkY7CgoJLy8gQkM2SCBpbnRlcm5hbHMKCWNvbnN0IHVpbnQzMl90IE5VTV9CQzZIX01PREVTID0gMTQ7Cgljb25zdCB1aW50MzJfdCBCQzZIX0xBU1RfTU9ERV9JTkRFWCA9IDEzOwoJY29uc3QgdWludDMyX3QgQkM2SF9GSVJTVF8xU1VCU0VUX01PREVfSU5ERVggPSAxMDsgLy8gaW4gdGhlIE1TIGRvY3MsIHRoaXMgaXMgIm1vZGUgMTEiICh3aGVyZSB0aGUgZmlyc3QgbW9kZSBpcyAxKSwgNjAgYml0cyBmb3IgZW5kcG9pbnRzICgxMC4xMCwgMTAuMTAsIDEwLjEwKSwgNjMgYml0cyBmb3Igd2VpZ2h0cwoJY29uc3QgdWludDMyX3QgVE9UQUxfQkM2SF9QQVJUSVRJT05fUEFUVEVSTlMgPSAzMjsKCglleHRlcm4gY29uc3QgdWludDhfdCBnX2JjNmhfbW9kZV9zaWdfYml0c1tOVU1fQkM2SF9NT0RFU11bNF07IC8vIGJhc2UsIHIsIGcsIGIKCglzdHJ1Y3QgYmM2aF9iaXRfbGF5b3V0Cgl7CgkJaW50OF90IG1fY29tcDsgLy8gUj0wLEc9MSxCPTIsRD0zIChEPXBhcnRpdGlvbiBpbmRleCkKCQlpbnQ4X3QgbV9pbmRleDsgLy8gMC0zLCAwLTEgTG93L0hpZ2ggc3Vic2V0IDEsIDItMyBMb3cvSGlnaCBzdWJzZXQgMiwgLTE9cGFydGl0aW9uIGluZGV4IChkKQoJCWludDhfdCBtX2xhc3RfYml0OwoJCWludDhfdCBtX2ZpcnN0X2JpdDsgLy8gbWF5IGJlIC0xIGlmIGEgc2luZ2xlIGJpdCwgbWF5IGJlID5tX2xhc3RfYml0IGlmIHJldmVyc2VkCgl9OwoKCWNvbnN0IHVpbnQzMl90IE1BWF9CQzZIX0xBWU9VVF9JTkRFWCA9IDI1OwoJZXh0ZXJuIGNvbnN0IGJjNmhfYml0X2xheW91dCBnX2JjNmhfYml0X2xheW91dHNbTlVNX0JDNkhfTU9ERVNdW01BWF9CQzZIX0xBWU9VVF9JTkRFWF07CgoJZXh0ZXJuIGNvbnN0IHVpbnQ4X3QgZ19iYzZoXzJzdWJzZXRfcGF0dGVybnNbVE9UQUxfQkM2SF9QQVJUSVRJT05fUEFUVEVSTlNdWzRdWzRdOyAvLyBbeV1beF0KCglleHRlcm4gY29uc3QgdWludDhfdCBnX2JjNmhfd2VpZ2h0M1s4XTsKCWV4dGVybiBjb25zdCB1aW50OF90IGdfYmM2aF93ZWlnaHQ0WzE2XTsKCglleHRlcm4gY29uc3QgaW50OF90IGdfYmM2aF9tb2RlX2xvb2t1cFszMl07CgkJCgkvLyBDb252ZXJ0cyBiMTYgdG8gaGFsZiBmbG9hdAoJaW5saW5lIGhhbGZfZmxvYXQgYmM2aF9ibG9nMTZfdG9faGFsZih1aW50MzJfdCBjb21wKQoJewoJCWFzc2VydChjb21wIDw9IDB4RkZGRik7CgoJCS8vIHNjYWxlIHRoZSBtYWduaXR1ZGUgYnkgMzEvNjQKCQljb21wID0gKGNvbXAgKiAzMXUpID4+IDZ1OwoJCXJldHVybiAoaGFsZl9mbG9hdCljb21wOwoJfQoKCWNvbnN0IHVpbnQzMl90IE1BWF9CQzZIX0hBTEZfRkxPQVRfQVNfVUlOVCA9IDB4N0JGRjsKCgkvLyBJbnZlcnRzIGJjNmhfYmxvZzE2X3RvX2hhbGYoKS4KCS8vIFJldHVybnMgdGhlIG5lYXJlc3QgYmxvZzE2IGdpdmVuIGEgaGFsZiB2YWx1ZS4gCglpbmxpbmUgdWludDMyX3QgYmM2aF9oYWxmX3RvX2Jsb2cxNihoYWxmX2Zsb2F0IGgpCgl7CgkJYXNzZXJ0KGggPD0gTUFYX0JDNkhfSEFMRl9GTE9BVF9BU19VSU5UKTsKCQlyZXR1cm4gKGggKiA2NCArIDMwKSAvIDMxOwoJfQoKCS8vIFN1Ym9wdGltYWwsIGJ1dCB2ZXJ5IGNsb3NlLgoJaW5saW5lIHVpbnQzMl90IGJjNmhfaGFsZl90b19ibG9nKGhhbGZfZmxvYXQgaCwgdWludDMyX3QgbnVtX2JpdHMpCgl7CgkJYXNzZXJ0KGggPD0gTUFYX0JDNkhfSEFMRl9GTE9BVF9BU19VSU5UKTsKCQlyZXR1cm4gKGggKiA2NCArIDMwKSAvICgzMSAqICgxIDw8ICgxNiAtIG51bV9iaXRzKSkpOwoJfQoKCXN0cnVjdCBiYzZoX2Jsb2NrCgl7CgkJdWludDhfdCBtX2J5dGVzWzE2XTsKCX07CgoJdm9pZCBiYzZoX2VuY19ibG9ja19tb2RlMTAoYmM2aF9ibG9jayogcFBhY2tlZF9ibG9jaywgY29uc3QgaGFsZl9mbG9hdCBwRW5kcG9pbnRzWzNdWzJdLCBjb25zdCB1aW50OF90KiBwV2VpZ2h0cyk7Cgl2b2lkIGJjNmhfZW5jX2Jsb2NrXzFzdWJzZXRfNGJpdF93ZWlnaHRzKGJjNmhfYmxvY2sqIHBQYWNrZWRfYmxvY2ssIGNvbnN0IGhhbGZfZmxvYXQgcEVuZHBvaW50c1szXVsyXSwgY29uc3QgdWludDhfdCogcFdlaWdodHMpOwoJdm9pZCBiYzZoX2VuY19ibG9ja18xc3Vic2V0X21vZGU5XzNiaXRfd2VpZ2h0cyhiYzZoX2Jsb2NrKiBwUGFja2VkX2Jsb2NrLCBjb25zdCBoYWxmX2Zsb2F0IHBFbmRwb2ludHNbM11bMl0sIGNvbnN0IHVpbnQ4X3QqIHBXZWlnaHRzKTsKCXZvaWQgYmM2aF9lbmNfYmxvY2tfMXN1YnNldF8zYml0X3dlaWdodHMoYmM2aF9ibG9jayogcFBhY2tlZF9ibG9jaywgY29uc3QgaGFsZl9mbG9hdCBwRW5kcG9pbnRzWzNdWzJdLCBjb25zdCB1aW50OF90KiBwV2VpZ2h0cyk7Cgl2b2lkIGJjNmhfZW5jX2Jsb2NrXzJzdWJzZXRfbW9kZTlfM2JpdF93ZWlnaHRzKGJjNmhfYmxvY2sqIHBQYWNrZWRfYmxvY2ssIHVpbnQzMl90IGNvbW1vbl9wYXJ0X2luZGV4LCBjb25zdCBoYWxmX2Zsb2F0IHBFbmRwb2ludHNbMl1bM11bMl0sIGNvbnN0IHVpbnQ4X3QqIHBXZWlnaHRzKTsgLy8gcEVuZHBvaW50c1tzdWJzZXRdW2NvbXBdW2xoX2luZGV4XQoJdm9pZCBiYzZoX2VuY19ibG9ja18yc3Vic2V0XzNiaXRfd2VpZ2h0cyhiYzZoX2Jsb2NrKiBwUGFja2VkX2Jsb2NrLCB1aW50MzJfdCBjb21tb25fcGFydF9pbmRleCwgY29uc3QgaGFsZl9mbG9hdCBwRW5kcG9pbnRzWzJdWzNdWzJdLCBjb25zdCB1aW50OF90KiBwV2VpZ2h0cyk7IC8vIHBFbmRwb2ludHNbc3Vic2V0XVtjb21wXVtsaF9pbmRleF0KCWJvb2wgYmM2aF9lbmNfYmxvY2tfc29saWRfY29sb3IoYmM2aF9ibG9jayogcFBhY2tlZF9ibG9jaywgY29uc3QgaGFsZl9mbG9hdCBwQ29sb3JbM10pOwoKCXN0cnVjdCBiYzZoX2xvZ2ljYWxfYmxvY2sKCXsKCQl1aW50MzJfdCBtX21vZGU7CgkJdWludDMyX3QgbV9wYXJ0aXRpb25fcGF0dGVybjsJLy8gbXVzdCBiZSAwIGlmIDEgc3Vic2V0CgkJdWludDMyX3QgbV9lbmRwb2ludHNbM11bNF07CQkvLyBbY29tcF1bc3Vic2V0KjIrbGhfaW5kZXhdIC0gbXVzdCBiZSBhbHJlYWR5IHByb3Blcmx5IHBhY2tlZAoJCXVpbnQ4X3QgbV93ZWlnaHRzWzE2XTsJCQkvLyB3ZWlnaHRzIG11c3QgYmUgb2YgdGhlIHByb3BlciBzaXplLCB0YWtpbmcgaW50byBhY2NvdW50IHNraXBwZWQgTVNCJ3Mgd2hpY2ggbXVzdCBiZSAwCgoJCXZvaWQgY2xlYXIoKQoJCXsKCQkJYmFzaXN1OjpjbGVhcl9vYmooKnRoaXMpOwoJCX0KCX07CgoJdm9pZCBwYWNrX2JjNmhfYmxvY2soYmM2aF9ibG9jayYgZHN0X2JsaywgYmM2aF9sb2dpY2FsX2Jsb2NrJiBsb2dfYmxrKTsKCQkKCW5hbWVzcGFjZSBiYzdfbW9kZV81X2VuY29kZXIKCXsKCQl2b2lkIGVuY29kZV9iYzdfbW9kZV81X2Jsb2NrKHZvaWQqIHBEc3RfYmxvY2ssIGNvbG9yMzIqIHBQaXhlbHMsIGJvb2wgaHFfbW9kZSk7Cgl9CgoJbmFtZXNwYWNlIGFzdGNfNng2X2hkcgoJewoJCWV4dGVybiB1aW50OF90IGdfcXVhbnRpemVfdGFibGVzX3ByZXNlcnZlMlsyMSAtIDFdWzI1Nl07IC8vIGFzdGNfaGVscGVyczo6VE9UQUxfSVNFX1JBTkdFUz0yMQoJCWV4dGVybiB1aW50OF90IGdfcXVhbnRpemVfdGFibGVzX3ByZXNlcnZlM1syMSAtIDFdWzI1Nl07Cgl9IC8vIG5hbWVzcGFjZSBhc3RjXzZ4Nl9oZHIKCiNpZiBCQVNJU0RfU1VQUE9SVF9YVUFTVEMKCW5hbWVzcGFjZSBhc3RjX2xkcl90Cgl7CgkJY29uc3QgdWludDMyX3QgQVJJVEhfSEVBREVSX01BUktFUiA9IDB4MDE7CgkJY29uc3QgdWludDMyX3QgQVJJVEhfSEVBREVSX01BUktFUl9CSVRTID0gNTsKCgkJY29uc3QgdWludDMyX3QgRlVMTF9aU1REX0hFQURFUl9NQVJLRVIgPSAweDAxOwoJCWNvbnN0IHVpbnQzMl90IEZVTExfWlNURF9IRUFERVJfTUFSS0VSX0JJVFMgPSA1OwoKCQljb25zdCB1aW50MzJfdCBGSU5BTF9TWU5DX01BUktFUiA9IDB4QUY7CgkJY29uc3QgdWludDMyX3QgRklOQUxfU1lOQ19NQVJLRVJfQklUUyA9IDg7CgoJCWNvbnN0IHVpbnQzMl90IGNNYXhDb25maWdSZXVzZU5laWdoYm9ycyA9IDM7CgojcHJhZ21hIHBhY2socHVzaCwgMSkKCQlzdHJ1Y3QgeHVhc3RjX2xkcl9hcml0aF9oZWFkZXIKCQl7CgkJCXVpbnQ4X3QgbV9mbGFnczsKCQkJYmFzaXN1OjpwYWNrZWRfdWludDw0PiBtX2FyaXRoX2J5dGVzX2xlbjsKCQkJYmFzaXN1OjpwYWNrZWRfdWludDw0PiBtX21lYW4wX2JpdHNfbGVuOwoJCQliYXNpc3U6OnBhY2tlZF91aW50PDQ+IG1fbWVhbjFfYnl0ZXNfbGVuOwoJCQliYXNpc3U6OnBhY2tlZF91aW50PDQ+IG1fcnVuX2J5dGVzX2xlbjsKCQkJYmFzaXN1OjpwYWNrZWRfdWludDw0PiBtX2NvZWZmX2J5dGVzX2xlbjsKCQkJYmFzaXN1OjpwYWNrZWRfdWludDw0PiBtX3NpZ25fYml0c19sZW47CgkJCWJhc2lzdTo6cGFja2VkX3VpbnQ8ND4gbV93ZWlnaHQyX2JpdHNfbGVuOyAvLyAyLWJpdCB3ZWlnaHRzICg0IHBlciBieXRlKSwgdXAgdG8gQklTRV80X0xFVkVMUwoJCQliYXNpc3U6OnBhY2tlZF91aW50PDQ+IG1fd2VpZ2h0M19iaXRzX2xlbjsgLy8gMy1iaXQgd2VpZ2h0cyAoMiBwZXIgYnl0ZSksIHVwIHRvIEJJU0VfOF9MRVZFTFMKCQkJYmFzaXN1OjpwYWNrZWRfdWludDw0PiBtX3dlaWdodDRfYml0c19sZW47IC8vIDQtYml0IHdlaWdodHMgKDIgcGVyIGJ5dGUpLCB1cCB0byBCSVNFXzE2X0xFVkVMUwoJCQliYXNpc3U6OnBhY2tlZF91aW50PDQ+IG1fd2VpZ2h0OF9ieXRlc19sZW47IC8vIDgtYml0IHdlaWdodHMgKDEgcGVyIGJ5dGUpLCB1cCB0byBCSVNFXzMyX0xFVkVMUwoJCQliYXNpc3U6OnBhY2tlZF91aW50PDQ+IG1fdW51c2VkOwkJCS8vIEZ1dHVyZSBleHBhbnNpb24KCQl9OwoKCQlzdHJ1Y3QgeHVhc3RjX2xkcl9mdWxsX3pzdGRfaGVhZGVyCgkJewoJCQl1aW50OF90IG1fZmxhZ3M7CgoJCQkvLyBDb250cm9sCgkJCWJhc2lzdTo6cGFja2VkX3VpbnQ8ND4gbV9yYXdfYml0c19sZW47IC8vIHVuY29tcHJlc3NlZAoJCQliYXNpc3U6OnBhY2tlZF91aW50PDQ+IG1fbW9kZV9ieXRlc19sZW47CgkJCWJhc2lzdTo6cGFja2VkX3VpbnQ8ND4gbV9zb2xpZF9kcGNtX2J5dGVzX2xlbjsKCQkJCgkJCS8vIEVuZHBvaW50IERQQ00KCQkJYmFzaXN1OjpwYWNrZWRfdWludDw0PiBtX2VuZHBvaW50X2RwY21fcmV1c2VfaW5kaWNlc19sZW47CgkJCWJhc2lzdTo6cGFja2VkX3VpbnQ8ND4gbV91c2VfYmNfYml0c19sZW47CgkJCWJhc2lzdTo6cGFja2VkX3VpbnQ8ND4gbV9lbmRwb2ludF9kcGNtXzNiaXRfbGVuOwoJCQliYXNpc3U6OnBhY2tlZF91aW50PDQ+IG1fZW5kcG9pbnRfZHBjbV80Yml0X2xlbjsKCQkJYmFzaXN1OjpwYWNrZWRfdWludDw0PiBtX2VuZHBvaW50X2RwY21fNWJpdF9sZW47CgkJCWJhc2lzdTo6cGFja2VkX3VpbnQ8ND4gbV9lbmRwb2ludF9kcGNtXzZiaXRfbGVuOwoJCQliYXNpc3U6OnBhY2tlZF91aW50PDQ+IG1fZW5kcG9pbnRfZHBjbV83Yml0X2xlbjsKCQkJYmFzaXN1OjpwYWNrZWRfdWludDw0PiBtX2VuZHBvaW50X2RwY21fOGJpdF9sZW47CgoJCQkvLyBXZWlnaHQgZ3JpZCBEQ1QKCQkJYmFzaXN1OjpwYWNrZWRfdWludDw0PiBtX21lYW4wX2JpdHNfbGVuOwoJCQliYXNpc3U6OnBhY2tlZF91aW50PDQ+IG1fbWVhbjFfYnl0ZXNfbGVuOwoJCQliYXNpc3U6OnBhY2tlZF91aW50PDQ+IG1fcnVuX2J5dGVzX2xlbjsKCQkJYmFzaXN1OjpwYWNrZWRfdWludDw0PiBtX2NvZWZmX2J5dGVzX2xlbjsKCQkJYmFzaXN1OjpwYWNrZWRfdWludDw0PiBtX3NpZ25fYml0c19sZW47CgkJCQoJCQkvLyBXZWlnaHQgRFBDTQoJCQliYXNpc3U6OnBhY2tlZF91aW50PDQ+IG1fd2VpZ2h0Ml9iaXRzX2xlbjsgLy8gMi1iaXQgd2VpZ2h0cyAoNCBwZXIgYnl0ZSksIHVwIHRvIEJJU0VfNF9MRVZFTFMKCQkJYmFzaXN1OjpwYWNrZWRfdWludDw0PiBtX3dlaWdodDNfYml0c19sZW47IC8vIDMtYml0IHdlaWdodHMgKDQgcGVyIGJ5dGUpLCB1cCB0byBCSVNFXzhfTEVWRUxTCgkJCWJhc2lzdTo6cGFja2VkX3VpbnQ8ND4gbV93ZWlnaHQ0X2JpdHNfbGVuOyAvLyA0LWJpdCB3ZWlnaHRzICgyIHBlciBieXRlKSwgdXAgdG8gQklTRV8xNl9MRVZFTFMKCQkJYmFzaXN1OjpwYWNrZWRfdWludDw0PiBtX3dlaWdodDhfYnl0ZXNfbGVuOyAvLyA4LWJpdCB3ZWlnaHRzICgxIHBlciBieXRlKSwgdXAgdG8gQklTRV8zMl9MRVZFTFMKCgkJCWJhc2lzdTo6cGFja2VkX3VpbnQ8ND4gbV91bnVzZWQ7CQkJLy8gRnV0dXJlIGV4cGFuc2lvbgoJCX07CiNwcmFnbWEgcGFjayhwb3ApCgoJCWNvbnN0IHVpbnQzMl90IERDVF9SVU5fTEVOX0VPQl9TWU1fSU5ERVggPSA2NDsKCQljb25zdCB1aW50MzJfdCBEQ1RfTUFYX0FSSVRIX0NPRUZGX01BRyA9IDI1NTsKCQkKCQljb25zdCB1aW50MzJfdCBEQ1RfTUVBTl9MRVZFTFMwID0gOSwgRENUX01FQU5fTEVWRUxTMSA9IDMzOwoJCQoJCWNvbnN0IHVpbnQzMl90IFBBUlRfSEFTSF9CSVRTID0gNnU7CgkJY29uc3QgdWludDMyX3QgUEFSVF9IQVNIX1NJWkUgPSAxdSA8PCBQQVJUX0hBU0hfQklUUzsKCgkJY29uc3QgdWludDMyX3QgVE1fSEFTSF9CSVRTID0gN3U7CgkJY29uc3QgdWludDMyX3QgVE1fSEFTSF9TSVpFID0gMXUgPDwgVE1fSEFTSF9CSVRTOwoJCQkJCgkJdHlwZWRlZiBiYXNpc3U6OnZlY3RvcjxmbG9hdD4gZnZlYzsKCgkJdm9pZCBpbml0KCk7CgoJCWNvbG9yX3JnYmEgYmx1ZV9jb250cmFjdF9lbmMoY29sb3JfcmdiYSBvcmlnLCBib29sJiBkaWRfY2xhbXAsIGludCBlbmNvZGVkX2IpOwoJCWNvbG9yX3JnYmEgYmx1ZV9jb250cmFjdF9kZWMoaW50IGVuY19yLCBpbnQgZW5jX2csIGludCBlbmNfYiwgaW50IGVuY19hKTsKCQkJCQkJCQkKCQlzdHJ1Y3QgYXN0Y19ibG9ja19ncmlkX2NvbmZpZwoJCXsKCQkJdWludDE2X3QgbV9ibG9ja193aWR0aCwgbV9ibG9ja19oZWlnaHQ7CgkJCXVpbnQxNl90IG1fZ3JpZF93aWR0aCwgbV9ncmlkX2hlaWdodDsKCgkJCWFzdGNfYmxvY2tfZ3JpZF9jb25maWcoKSB7fQoKCQkJYXN0Y19ibG9ja19ncmlkX2NvbmZpZyh1aW50MzJfdCBibG9ja193aWR0aCwgdWludDMyX3QgYmxvY2tfaGVpZ2h0LCB1aW50MzJfdCBncmlkX3dpZHRoLCB1aW50MzJfdCBncmlkX2hlaWdodCkKCQkJewoJCQkJYXNzZXJ0KChibG9ja193aWR0aCA+PSA0KSAmJiAoYmxvY2tfd2lkdGggPD0gMTIpKTsKCQkJCWFzc2VydCgoYmxvY2tfaGVpZ2h0ID49IDQpICYmIChibG9ja19oZWlnaHQgPD0gMTIpKTsKCQkJCW1fYmxvY2tfd2lkdGggPSAodWludDE2X3QpYmxvY2tfd2lkdGg7CgkJCQltX2Jsb2NrX2hlaWdodCA9ICh1aW50MTZfdClibG9ja19oZWlnaHQ7CgoJCQkJYXNzZXJ0KChncmlkX3dpZHRoID49IDIpICYmIChncmlkX3dpZHRoIDw9IGJsb2NrX3dpZHRoKSk7CgkJCQlhc3NlcnQoKGdyaWRfaGVpZ2h0ID49IDIpICYmIChncmlkX2hlaWdodCA8PSBibG9ja19oZWlnaHQpKTsKCQkJCW1fZ3JpZF93aWR0aCA9ICh1aW50MTZfdClncmlkX3dpZHRoOwoJCQkJbV9ncmlkX2hlaWdodCA9ICh1aW50MTZfdClncmlkX2hlaWdodDsKCQkJfQoKCQkJYm9vbCBvcGVyYXRvcj09KGNvbnN0IGFzdGNfYmxvY2tfZ3JpZF9jb25maWcmIG90aGVyKSBjb25zdAoJCQl7CgkJCQlyZXR1cm4gKG1fYmxvY2tfd2lkdGggPT0gb3RoZXIubV9ibG9ja193aWR0aCkgJiYgKG1fYmxvY2tfaGVpZ2h0ID09IG90aGVyLm1fYmxvY2tfaGVpZ2h0KSAmJgoJCQkJCShtX2dyaWRfd2lkdGggPT0gb3RoZXIubV9ncmlkX3dpZHRoKSAmJiAobV9ncmlkX2hlaWdodCA9PSBvdGhlci5tX2dyaWRfaGVpZ2h0KTsKCQkJfQoJCX07CgoJCXN0cnVjdCBhc3RjX2Jsb2NrX2dyaWRfZGF0YQoJCXsKCQkJZmxvYXQgbV93ZWlnaHRfZ2FtbWE7CgoJCQkvLyBBbiB1bmZvcnR1bmF0ZSBkaWZmZXJlbmNlIG9mIGNvbnRhaW5lcnMsIGJ1dCBpbiBtZW1vcnkgdGhlc2UgbWF0cmljZXMgYXJlIGJvdGggYWRkcmVzc2VkIGFzIFtyXVtjXS4KCQkJYmFzaXN1Ojp2ZWN0b3IyRDxmbG9hdD4gbV91cHNhbXBsZV9tYXRyaXg7CgoJCQliYXNpc3U6OnZlY3RvcjxmbG9hdD4gbV9kb3duc2FtcGxlX21hdHJpeDsKCgkJCWFzdGNfYmxvY2tfZ3JpZF9kYXRhKCkge30KCQkJYXN0Y19ibG9ja19ncmlkX2RhdGEoZmxvYXQgd2VpZ2h0X2dhbW1hKSA6IG1fd2VpZ2h0X2dhbW1hKHdlaWdodF9nYW1tYSkge30KCQl9OwoKCQl0eXBlZGVmIGJhc2lzdTo6aGFzaF9tYXA8YXN0Y19ibG9ja19ncmlkX2NvbmZpZywgYXN0Y19ibG9ja19ncmlkX2RhdGEsIGJpdF9oYXNoZXI8YXN0Y19ibG9ja19ncmlkX2NvbmZpZz4gPiBhc3RjX2Jsb2NrX2dyaWRfZGF0YV9oYXNoX3Q7CgkJCQkJCQoJCXZvaWQgZGVjb2RlX2VuZHBvaW50c19pc2UyMCh1aW50MzJfdCBjZW1faW5kZXgsIGNvbnN0IHVpbnQ4X3QqIHBFbmRwb2ludF92YWxzLCBjb2xvcjMyJiBsLCBjb2xvcjMyJiBoKTsKCQl2b2lkIGRlY29kZV9lbmRwb2ludHModWludDMyX3QgY2VtX2luZGV4LCBjb25zdCB1aW50OF90KiBwRW5kcG9pbnRfdmFscywgdWludDMyX3QgZW5kcG9pbnRfaXNlX2luZGV4LCBjb2xvcjMyJiBsLCBjb2xvcjMyJiBoLCBmbG9hdCogcFNjYWxlID0gbnVsbHB0cik7CgoJCXZvaWQgZGVjb2RlX2VuZHBvaW50c19pc2UyMCh1aW50MzJfdCBjZW1faW5kZXgsIGNvbnN0IHVpbnQ4X3QqIHBFbmRwb2ludF92YWxzLCBjb2xvcl9yZ2JhJiBsLCBjb2xvcl9yZ2JhJiBoKTsKCQl2b2lkIGRlY29kZV9lbmRwb2ludHModWludDMyX3QgY2VtX2luZGV4LCBjb25zdCB1aW50OF90KiBwRW5kcG9pbnRfdmFscywgdWludDMyX3QgZW5kcG9pbnRfaXNlX2luZGV4LCBjb2xvcl9yZ2JhJiBsLCBjb2xvcl9yZ2JhJiBoLCBmbG9hdCogcFNjYWxlID0gbnVsbHB0cik7CgoJCXZvaWQgY29tcHV0ZV9hZGpvaW50X2Rvd25zYW1wbGVfbWF0cml4KGJhc2lzdTo6dmVjdG9yPGZsb2F0PiYgZG93bnNhbXBsZV9tYXRyaXgsIHVpbnQzMl90IGJsb2NrX3dpZHRoLCB1aW50MzJfdCBibG9ja19oZWlnaHQsIHVpbnQzMl90IGdyaWRfd2lkdGgsIHVpbnQzMl90IGdyaWRfaGVpZ2h0KTsKCQl2b2lkIGNvbXB1dGVfdXBzYW1wbGVfbWF0cml4KGJhc2lzdTo6dmVjdG9yMkQ8ZmxvYXQ+JiB1cHNhbXBsZV9tYXRyaXgsIHVpbnQzMl90IGJsb2NrX3dpZHRoLCB1aW50MzJfdCBibG9ja19oZWlnaHQsIHVpbnQzMl90IGdyaWRfd2lkdGgsIHVpbnQzMl90IGdyaWRfaGVpZ2h0KTsKCgkJY2xhc3MgZGN0MmYKCQl7CgkJCWVudW0geyBjTWF4U2l6ZSA9IDEyIH07CgoJCXB1YmxpYzoKCQkJZGN0MmYoKSA6IG1fcm93cygwdSksIG1fY29scygwdSkge30KCgkJCS8vIGNhbGwgd2l0aCBncmlkX2hlaWdodC9ncmlkX3dpZHRoIChJTlZFUlRFRCkKCQkJYm9vbCBpbml0KHVpbnQzMl90IHJvd3MsIHVpbnQzMl90IGNvbHMpOwoJCQkKCQkJdWludDMyX3Qgcm93cygpIGNvbnN0IHsgcmV0dXJuIG1fcm93czsgfQoJCQl1aW50MzJfdCBjb2xzKCkgY29uc3QgeyByZXR1cm4gbV9jb2xzOyB9CgoJCQl2b2lkIGZvcndhcmQoY29uc3QgZmxvYXQqIHBTcmMsIGZsb2F0KiBwRHN0LCBmdmVjJiB3b3JrKSBjb25zdDsKCQkJCgkJCXZvaWQgaW52ZXJzZShjb25zdCBmbG9hdCogcFNyYywgZmxvYXQqIHBEc3QsIGZ2ZWMmIHdvcmspIGNvbnN0OwoJCQkKCQkJLy8gY2hlY2sgdmFyaWFudHMgdXNlIGEgbGVzcyBvcHRpbWl6ZWQgaW1wbGVtZW50YXRpb24sIHVzZWQgZm9yIHNhbml0eSBjaGVja2luZwoJCQl2b2lkIGludmVyc2VfY2hlY2soY29uc3QgZmxvYXQqIHBTcmMsIGZsb2F0KiBwRHN0LCBmdmVjJiB3b3JrKSBjb25zdDsKCQkJCgkJCXZvaWQgZm9yd2FyZChjb25zdCBmbG9hdCogcFNyYywgdWludDMyX3Qgc3JjX3N0cmlkZSwKCQkJCWZsb2F0KiBwRHN0LCB1aW50MzJfdCBkc3Rfc3RyaWRlLCBmdmVjJiB3b3JrKSBjb25zdDsKCQkJCgkJCXZvaWQgaW52ZXJzZShjb25zdCBmbG9hdCogcFNyYywgdWludDMyX3Qgc3JjX3N0cmlkZSwKCQkJCWZsb2F0KiBwRHN0LCB1aW50MzJfdCBkc3Rfc3RyaWRlLCBmdmVjJiB3b3JrKSBjb25zdDsKCQkJCgkJCXZvaWQgaW52ZXJzZV9jaGVjayhjb25zdCBmbG9hdCogcFNyYywgdWludDMyX3Qgc3JjX3N0cmlkZSwKCQkJCWZsb2F0KiBwRHN0LCB1aW50MzJfdCBkc3Rfc3RyaWRlLCBmdmVjJiB3b3JrKSBjb25zdDsKCgkJcHJpdmF0ZToKCQkJdWludDMyX3QgbV9yb3dzLCBtX2NvbHM7CgkJCWZ2ZWMgbV9jX2NvbDsgICAvLyBbdSptX3Jvd3MgKyB4XQoJCQlmdmVjIG1fY19yb3c7ICAgLy8gW3YqbV9jb2xzICsgeV0KCQkJZnZlYyBtX2FfY29sOyAgIC8vIGFscGhhKHUpCgkJCWZ2ZWMgbV9hX3JvdzsgICAvLyBhbHBoYSh2KQoJCX07CgoJCXN0cnVjdCBkY3Rfc3ltcwoJCXsKCQkJZGN0X3N5bXMoKQoJCQl7CgkJCQljbGVhcigpOwoJCQl9CgoJCQl2b2lkIGNsZWFyKCkKCQkJewoJCQkJbV9kY19zeW0gPSAwOwoJCQkJbV9udW1fZGNfbGV2ZWxzID0gMDsKCQkJCW1fY29lZmZzLnJlc2l6ZSgwKTsKCQkJCW1fbWF4X2NvZWZmX21hZyA9IDA7CgkJCQltX21heF96aWd6YWdfaW5kZXggPSAwOwoJCQl9CgoJCQl1aW50MzJfdCBtX2RjX3N5bTsKCQkJdWludDMyX3QgbV9udW1fZGNfbGV2ZWxzOwoKCQkJc3RydWN0IGNvZWZmCgkJCXsKCQkJCXVpbnQxNl90IG1fbnVtX3plcm9zOwoJCQkJaW50MTZfdCBtX2NvZWZmOyAvLyBvciBJTlQxNl9NQVggaWYgaW52YWxpZAoKCQkJCWNvZWZmKCkge30KCQkJCWNvZWZmKHVpbnQxNl90IG51bV96ZXJvcywgaW50MTZfdCBjb2VmZikgOiBtX251bV96ZXJvcyhudW1femVyb3MpLCBtX2NvZWZmKGNvZWZmKSB7fQoJCQl9OwoKCQkJYmFzaXN1OjpzdGF0aWNfdmVjdG9yPGNvZWZmLCA2NT4gbV9jb2VmZnM7CgoJCQl1aW50MzJfdCBtX21heF9jb2VmZl9tYWc7CgkJCXVpbnQzMl90IG1fbWF4X3ppZ3phZ19pbmRleDsKCQl9OwoJCQkJCgkJc3RydWN0IGdyaWRfZGltX2tleQoJCXsKCQkJaW50IG1fZ3JpZF93aWR0aDsKCQkJaW50IG1fZ3JpZF9oZWlnaHQ7CgoJCQlncmlkX2RpbV9rZXkoKSB7fQoKCQkJZ3JpZF9kaW1fa2V5KGludCB3LCBpbnQgaCkgOiBtX2dyaWRfd2lkdGgodyksIG1fZ3JpZF9oZWlnaHQoaCkge30KCgkJCWJvb2wgb3BlcmF0b3I9PSAoY29uc3QgZ3JpZF9kaW1fa2V5JiByaHMpIGNvbnN0CgkJCXsKCQkJCXJldHVybiAobV9ncmlkX3dpZHRoID09IHJocy5tX2dyaWRfd2lkdGgpICYmIChtX2dyaWRfaGVpZ2h0ID09IHJocy5tX2dyaWRfaGVpZ2h0KTsKCQkJfQoJCX07CgoJCXN0cnVjdCBncmlkX2RpbV92YWx1ZQoJCXsKCQkJYmFzaXN1OjppbnRfdmVjIG1femlnemFnOwoJCQlkY3QyZiBtX2RjdDsKCQl9OwoKCQl0eXBlZGVmIGJhc2lzdTo6aGFzaF9tYXA8Z3JpZF9kaW1fa2V5LCBncmlkX2RpbV92YWx1ZSwgYml0X2hhc2hlcjxncmlkX2RpbV9rZXk+ID4gZ3JpZF9kaW1faGFzaF9tYXA7CgoJCXZvaWQgaW5pdF9hc3RjX2Jsb2NrX2dyaWRfZGF0YV9oYXNoKCk7CgoJCWNvbnN0IGFzdGNfYmxvY2tfZ3JpZF9kYXRhKiBmaW5kX2FzdGNfYmxvY2tfZ3JpZF9kYXRhKHVpbnQzMl90IGJsb2NrX3dpZHRoLCB1aW50MzJfdCBibG9ja19oZWlnaHQsIHVpbnQzMl90IGdyaWRfd2lkdGgsIHVpbnQzMl90IGdyaWRfaGVpZ2h0KTsKCgkJY29uc3QgZmxvYXQgREVBRFpPTkVfQUxQSEEgPSAuNWY7CgkJY29uc3QgZmxvYXQgU0NBTEVEX1dFSUdIVF9CQVNFX0NPRElOR19TQ0FMRSA9IC41ZjsgLy8gdHlwaWNhbGx5IH41IGJpdHMgWzAsMzJdLCBvciAzIFswLDhdCgoJCXN0cnVjdCBzYW1wbGVfcXVhbnRfdGFibGVfc3RhdGUKCQl7CgkJCWZsb2F0IG1fcSwgbV9zeCwgbV9zeSwgbV9sZXZlbF9zY2FsZTsKCgkJCXZvaWQgaW5pdChmbG9hdCBxLAoJCQkJdWludDMyX3QgYmxvY2tfd2lkdGgsIHVpbnQzMl90IGJsb2NrX2hlaWdodCwKCQkJCWZsb2F0IGxldmVsX3NjYWxlKQoJCQl7CgkJCQltX3EgPSBxOwoJCQkJbV9sZXZlbF9zY2FsZSA9IGxldmVsX3NjYWxlOwoKCQkJCWNvbnN0IGludCBCeCA9IGJsb2NrX3dpZHRoLCBCeSA9IGJsb2NrX2hlaWdodDsKCgkJCQltX3N4ID0gKGZsb2F0KTguMGYgLyAoZmxvYXQpQng7CgkJCQltX3N5ID0gKGZsb2F0KTguMGYgLyAoZmxvYXQpQnk7CgkJCX0KCQl9OwoKCQljbGFzcyBncmlkX3dlaWdodF9kY3QKCQl7CgkJcHVibGljOgoJCQlncmlkX3dlaWdodF9kY3QoKSB7IH0KCgkJCXZvaWQgaW5pdCh1aW50MzJfdCBibG9ja193aWR0aCwgdWludDMyX3QgYmxvY2tfaGVpZ2h0KTsKCQkJCgkJCXN0YXRpYyB1aW50MzJfdCBnZXRfbnVtX3dlaWdodF9kY19sZXZlbHModWludDMyX3Qgd2VpZ2h0X2lzZV9yYW5nZSkKCQkJewoJCQkJZmxvYXQgc2NhbGVkX3dlaWdodF9jb2Rpbmdfc2NhbGUgPSBTQ0FMRURfV0VJR0hUX0JBU0VfQ09ESU5HX1NDQUxFOwoJCQkJaWYgKHdlaWdodF9pc2VfcmFuZ2UgPD0gYXN0Y19oZWxwZXJzOjpCSVNFXzhfTEVWRUxTKQoJCQkJCXNjYWxlZF93ZWlnaHRfY29kaW5nX3NjYWxlID0gMS4wZiAvIDguMGY7CgoJCQkJcmV0dXJuICh1aW50MzJfdCkoNjQuMGYgKiBzY2FsZWRfd2VpZ2h0X2NvZGluZ19zY2FsZSkgKyAxOwoJCQl9CgoJCQlzdHJ1Y3QgYmxvY2tfc3RhdHMKCQkJewoJCQkJZmxvYXQgbV9tZWFuX3dlaWdodDsKCQkJCXVpbnQzMl90IG1fdG90YWxfY29kZWRfYWNzOwoJCQkJdWludDMyX3QgbV9tYXhfYWNfY29lZmY7CgkJCX07CgoJCQlib29sIGRlY29kZV9ibG9ja193ZWlnaHRzKAoJCQkJZmxvYXQgcSwgdWludDMyX3QgcGxhbmVfaW5kZXgsIC8vIHBsYW5lIG9mIHdlaWdodHMgdG8gZGVjb2RlIGFuZCBJRENUIGZyb20gc3RyZWFtCgkJCQlhc3RjX2hlbHBlcnM6OmxvZ19hc3RjX2Jsb2NrJiBsb2dfYmxrLCAvLyBtdXN0IGJlIGluaXRpYWxpemVkIGV4Y2VwdCBmb3IgdGhlIHBsYW5lIHdlaWdodHMgd2hpY2ggYXJlIGRlY29kZWQKCQkJCWJhc2lzdDo6Yml0d2lzZV9kZWNvZGVyKiBwRGVjLAoJCQkJY29uc3QgYXN0Y19ibG9ja19ncmlkX2RhdGEqIHBHcmlkX2RhdGEsIC8vIGdyaWQgZGF0YSBmb3IgdGhpcyBncmlkIHNpemUKCQkJCWJsb2NrX3N0YXRzKiBwUywKCQkJCWZ2ZWMmIGRjdF93b3JrLCAvLyB0aHJlYWQgbG9jYWwKCQkJCWNvbnN0IGRjdF9zeW1zKiBwU3ltcyA9IG51bGxwdHIpIGNvbnN0OwoJCQkJCQkKCQkJZW51bSB7IG1femVyb19ydW4gPSAzLCBtX2NvZWZmID0gMiB9OwoKCQkJdWludDMyX3QgbV9ibG9ja193aWR0aCwgbV9ibG9ja19oZWlnaHQ7CgoJCQlncmlkX2RpbV9oYXNoX21hcCBtX2dyaWRfZGltX2tleV92YWxzOwoJCQkJCQkKCQkJLy8gQWRhcHRpdmVseSBjb21wZW5zYXRlIGZvciB3ZWlnaHQgbGV2ZWwgcXVhbnRpemF0aW9uIG5vaXNlIGJlaW5nIGZlZCBpbnRvIHRoZSBEQ1QuIAoJCQkvLyBUaGUgbW9yZSBjb3Vyc2VseSB0aGUgd2VpZ2h0IGxldmVscyBhcmUgcXVhbnRpemVkLCB0aGUgbW9yZSBub2lzZSBpbmplY3RlZCwgYW5kIHRoZSBtb3JlIG5vaXNlIHdpbGwgYmUgc3ByZWFkIGJldHdlZW4gbXVsdGlwbGUgQUMgY29lZmZpY2llbnRzLgoJCQkvLyBUaGlzIHdpbGwgY2F1c2Ugc29tZSBwcmV2aW91c2x5IDAgY29lZmZpY2llbnRzIHRvIGluY3JlYXNlIGluIG1hZywgYnV0IHRoZXkncmUgbGlrZWx5IG5vaXNlLiBTbyBjYXJlZnVsbHkgbnVkZ2UgdGhlIHF1YW50IHN0ZXAgc2l6ZSB0byBjb21wZW5zYXRlLgoJCQlzdGF0aWMgZmxvYXQgc2NhbGVfcXVhbnRfc3RlcHMoaW50IFFfYXN0YywgZmxvYXQgZ2FtbWEgPSAwLjFmIC8qLjEzZiovLCBmbG9hdCBjbGFtcF9tYXggPSAyLjBmKQoJCQl7CgkJCQlhc3NlcnQoUV9hc3RjID49IDIpOwoJCQkJZmxvYXQgZmFjdG9yID0gNjMuMGYgLyAoUV9hc3RjIC0gMSk7CgkJCQkvLyBUT0RPOiBBcHByb3hpbWF0ZSBwb3dmKCkKCQkJCWZsb2F0IHNjYWxlZCA9IHBvd2YoZmFjdG9yLCBnYW1tYSk7CgkJCQlzY2FsZWQgPSBiYXNpc3U6OmNsYW1wPGZsb2F0PihzY2FsZWQsIDEuMGYsIGNsYW1wX21heCk7CgkJCQlyZXR1cm4gc2NhbGVkOwoJCQl9CgoJCQlmbG9hdCBjb21wdXRlX2xldmVsX3NjYWxlKGZsb2F0IHEsIGZsb2F0IHNwYW5fbGVuLCBmbG9hdCB3ZWlnaHRfZ2FtbWEsIHVpbnQzMl90IGdyaWRfd2lkdGgsIHVpbnQzMl90IGdyaWRfaGVpZ2h0LCB1aW50MzJfdCB3ZWlnaHRfaXNlX3JhbmdlKSBjb25zdDsKCgkJCWludCBzYW1wbGVfcXVhbnRfdGFibGUoc2FtcGxlX3F1YW50X3RhYmxlX3N0YXRlJiBzdGF0ZSwgdWludDMyX3QgeCwgdWludDMyX3QgeSkgY29uc3Q7CgoJCQl2b2lkIGNvbXB1dGVfcXVhbnRfdGFibGUoZmxvYXQgcSwKCQkJCXVpbnQzMl90IGdyaWRfd2lkdGgsIHVpbnQzMl90IGdyaWRfaGVpZ2h0LAoJCQkJZmxvYXQgbGV2ZWxfc2NhbGUsIGludCogZGN0X3F1YW50X3RhYikgY29uc3Q7CgkJCQoJCQlmbG9hdCBnZXRfbWF4X3NwYW5fbGVuKGNvbnN0IGFzdGNfaGVscGVyczo6bG9nX2FzdGNfYmxvY2smIGxvZ19ibGssIHVpbnQzMl90IHBsYW5lX2luZGV4KSBjb25zdDsKCQkJCgkJCWlubGluZSBpbnQgcXVhbnRpemVfZGVhZHpvbmUoZmxvYXQgZCwgaW50IEwsIGZsb2F0IGFscGhhLCB1aW50MzJfdCB4LCB1aW50MzJfdCB5KSBjb25zdAoJCQl7CgkJCQlhc3NlcnQoKHggPCBtX2Jsb2NrX3dpZHRoKSAmJiAoeSA8IG1fYmxvY2tfaGVpZ2h0KSk7CgoJCQkJaWYgKCgoeCA9PSAxKSAmJiAoeSA9PSAwKSkgfHwKCQkJCQkoKHggPT0gMCkgJiYgKHkgPT0gMSkpKQoJCQkJewoJCQkJCXJldHVybiAoaW50KXN0ZDo6cm91bmQoZCAvIChmbG9hdClMKTsKCQkJCX0KCgkJCQkvLyBMID0gcXVhbnQgc3RlcCwgYWxwaGEgaW4gWzAsMS4yXSAodHlwaWNhbCAwLjeWMC44NSkKCQkJCWlmIChMIDw9IDApIAoJCQkJCXJldHVybiAwOwoKCQkJCWZsb2F0IHMgPSBmYWJzZihkKTsKCQkJCWZsb2F0IHRhdSA9IGFscGhhICogZmxvYXQoTCk7ICAgICAgICAgICAgICAgICAvLyBoYWxmLXdpZHRoIG9mIHRoZSB6ZXJvIGJhbmQKCgkJCQlpZiAocyA8PSB0YXUpIAoJCQkJCXJldHVybiAwOyAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5zaWRlIGRlYWQtem9uZSB0b3dhcmRzIHplcm8KCgkJCQkvLyBRdWFudGl6ZSB0aGUgcmVzaWR1YWwgb3V0c2lkZSB0aGUgZGVhZC16b25lIHdpdGggbWlkLXRyZWFkIHJvdW5kaW5nCgkJCQlmbG9hdCBxZiA9IChzIC0gdGF1KSAvIGZsb2F0KEwpOwoJCQkJaW50ICAgcSA9IChpbnQpZmxvb3JmKHFmICsgMC41Zik7ICAgICAgICAgICAgLy8gdGllcy1uZWFyZXN0CgkJCQlyZXR1cm4gKGQgPCAwLjBmKSA/IC1xIDogcTsKCQkJfQoKCQkJaW5saW5lIGZsb2F0IGRlcXVhbnRfZGVhZHpvbmUoaW50IHEsIGludCBMLCBmbG9hdCBhbHBoYSwgdWludDMyX3QgeCwgdWludDMyX3QgeSkgY29uc3QKCQkJewoJCQkJYXNzZXJ0KCh4IDwgbV9ibG9ja193aWR0aCkgJiYgKHkgPCBtX2Jsb2NrX2hlaWdodCkpOwoKCQkJCWlmICgoKHggPT0gMSkgJiYgKHkgPT0gMCkpIHx8CgkJCQkJKCh4ID09IDApICYmICh5ID09IDEpKSkKCQkJCXsKCQkJCQlyZXR1cm4gKGZsb2F0KXEgKiAoZmxvYXQpTDsKCQkJCX0KCgkJCQlpZiAocSA9PSAwIHx8IEwgPD0gMCkgCgkJCQkJcmV0dXJuIDAuMGY7CgoJCQkJZmxvYXQgdGF1ID0gYWxwaGEgKiBmbG9hdChMKTsKCQkJCWZsb2F0IG1hZyA9IHRhdSArIGZsb2F0KGFicyhxKSkgKiBmbG9hdChMKTsgICAvLyBjZW50ZXIgb2YgdGhlIChub256ZXJvKSBiaW4KCQkJCXJldHVybiAocSA8IDApID8gLW1hZyA6IG1hZzsKCQkJfQoJCX07CgoJCXN0cnVjdCB0cmlhbF9tb2RlCgkJewoJCQl1aW50MzJfdCBtX2dyaWRfd2lkdGg7CgkJCXVpbnQzMl90IG1fZ3JpZF9oZWlnaHQ7CgkJCXVpbnQzMl90IG1fY2VtOwoJCQlpbnQgbV9jY3NfaW5kZXg7CgkJCXVpbnQzMl90IG1fZW5kcG9pbnRfaXNlX3JhbmdlOwoJCQl1aW50MzJfdCBtX3dlaWdodF9pc2VfcmFuZ2U7CgkJCXVpbnQzMl90IG1fbnVtX3BhcnRzOwoKCQkJYm9vbCBvcGVyYXRvcj09KGNvbnN0IHRyaWFsX21vZGUmIG90aGVyKSBjb25zdAoJCQl7CiNkZWZpbmUgQlVfQ09NUChhKSBpZiAoYSAhPSBvdGhlci5hKSByZXR1cm4gZmFsc2U7CgkJCQlCVV9DT01QKG1fZ3JpZF93aWR0aCk7CgkJCQlCVV9DT01QKG1fZ3JpZF9oZWlnaHQpOwoJCQkJQlVfQ09NUChtX2NlbSk7CgkJCQlCVV9DT01QKG1fY2NzX2luZGV4KTsKCQkJCUJVX0NPTVAobV9lbmRwb2ludF9pc2VfcmFuZ2UpOwoJCQkJQlVfQ09NUChtX3dlaWdodF9pc2VfcmFuZ2UpOwoJCQkJQlVfQ09NUChtX251bV9wYXJ0cyk7CiN1bmRlZiBCVV9DT01QCgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoKCQkJYm9vbCBvcGVyYXRvcjwoY29uc3QgdHJpYWxfbW9kZSYgcmhzKSBjb25zdAoJCQl7CiNkZWZpbmUgQlVfQ09NUChhKSBpZiAoYSA8IHJocy5hKSByZXR1cm4gdHJ1ZTsgZWxzZSBpZiAoYSA+IHJocy5hKSByZXR1cm4gZmFsc2U7CgkJCQlCVV9DT01QKG1fZ3JpZF93aWR0aCk7CgkJCQlCVV9DT01QKG1fZ3JpZF9oZWlnaHQpOwoJCQkJQlVfQ09NUChtX2NlbSk7CgkJCQlCVV9DT01QKG1fY2NzX2luZGV4KTsKCQkJCUJVX0NPTVAobV9lbmRwb2ludF9pc2VfcmFuZ2UpOwoJCQkJQlVfQ09NUChtX3dlaWdodF9pc2VfcmFuZ2UpOwoJCQkJQlVfQ09NUChtX251bV9wYXJ0cyk7CiN1bmRlZiBCVV9DT01QCgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCgkJCW9wZXJhdG9yIHNpemVfdCgpIGNvbnN0CgkJCXsKCQkJCXNpemVfdCBoID0gMHhBQkMxRjQxOTsKI2RlZmluZSBCVV9GSUVMRChhKSBkbyB7IGggXj0gaGFzaF9oc2llaChyZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4X3QgKj4oJmEpLCBzaXplb2YoYSkpOyB9IHdoaWxlKDApCgkJCQlCVV9GSUVMRChtX2dyaWRfd2lkdGgpOwoJCQkJQlVfRklFTEQobV9ncmlkX2hlaWdodCk7CgkJCQlCVV9GSUVMRChtX2NlbSk7CgkJCQlCVV9GSUVMRChtX2Njc19pbmRleCk7CgkJCQlCVV9GSUVMRChtX2VuZHBvaW50X2lzZV9yYW5nZSk7CgkJCQlCVV9GSUVMRChtX3dlaWdodF9pc2VfcmFuZ2UpOwoJCQkJQlVfRklFTEQobV9udW1fcGFydHMpOwojdW5kZWYgQlVfRklFTEQKCQkJCXJldHVybiBoOwoJCQl9CgkJfTsKCgkJLy8gT3JnYW5pemUgdHJpYWwgbW9kZXMgZm9yIGZhc3RlciBpbml0aWFsIG1vZGUgdHJpYWdpbmcuCgkJY29uc3QgdWludDMyX3QgT1RNX05VTV9DRU1TID0gMTQ7IC8vIDAtMTMgKDEzPWhpZ2hlc3QgdmFsaWQgTERSIENFTSkKCQljb25zdCB1aW50MzJfdCBPVE1fTlVNX1NVQlNFVFMgPSAzOyAvLyAxLTMKCQljb25zdCB1aW50MzJfdCBPVE1fTlVNX0NDUyA9IDU7IC8vIC0xIHRvIDMKCQljb25zdCB1aW50MzJfdCBPVE1fTlVNX0dSSURfU0laRVMgPSAyOyAvLyAwPXNtYWxsIG9yIDE9bGFyZ2UgKGdyaWRfdz49YmxvY2tfdy0xIGFuZCBncmlkX2g+PWJsb2NrX2gtMSkKCQljb25zdCB1aW50MzJfdCBPVE1fTlVNX0dSSURfQU5JU09TID0gMzsgLy8gMD1XPUgsIDE9Vz5ILCAyPVc8SAoKCQlpbmxpbmUgdWludDMyX3QgY2FsY19ncmlkX2FuaXNvX3ZhbCh1aW50MzJfdCBndywgdWludDMyX3QgZ2gsIHVpbnQzMl90IGJ3LCB1aW50MzJfdCBiaCkKCQl7CgkJCWFzc2VydCgoZ3cgPiAwKSAmJiAoZ2ggPiAwKSk7CgkJCWFzc2VydCgoYncgPiAwKSAmJiAoYmggPiAwKSk7CgkJCWFzc2VydCgoZ3cgPD0gMTIpICYmIChnaCA8PSAxMikgJiYgKGJ3IDw9IDEyKSAmJiAoYmggPD0gMTIpKTsKCQkJYXNzZXJ0KChndyA8PSBidykgJiYgKGdoIDw9IGJoKSk7CgkJCQkJCQojaWYgMAoJCQkvLyBQcmV2LiBjb2RlOgoJCQl1aW50MzJfdCBncmlkX2FuaXNvID0gMDsKCQkJaWYgKHRtLm1fZ3JpZF93aWR0aCAhPSB0bS5tX2dyaWRfaGVpZ2h0KSAvLyBub3Qgb3B0aW1hbCBmb3Igbm9uLXNxdWFyZSBibG9jayBzaXplcwoJCQl7CgkJCQljb25zdCBmbG9hdCBncmlkX3hfZnJhY3QgPSAoZmxvYXQpdG0ubV9ncmlkX3dpZHRoIC8gKGZsb2F0KWJsb2NrX3dpZHRoOwoJCQkJY29uc3QgZmxvYXQgZ3JpZF95X2ZyYWN0ID0gKGZsb2F0KXRtLm1fZ3JpZF9oZWlnaHQgLyAoZmxvYXQpYmxvY2tfaGVpZ2h0OwoJCQkJaWYgKGdyaWRfeF9mcmFjdCA+PSBncmlkX3lfZnJhY3QpCgkJCQkJZ3JpZF9hbmlzbyA9IDE7CgkJCQllbHNlIGlmIChncmlkX3hfZnJhY3QgPCBncmlkX3lfZnJhY3QpCgkJCQkJZ3JpZF9hbmlzbyA9IDI7CgkJCX0KI2VuZGlmCgkJCS8vIENvbXBhcmUgZ3cvYncgdnMuIGdoL2JoIHVzaW5nIGludGVnZXIgbWF0aDoKCQkJLy8gZ3cqYmggPj0gZ2gqYncgIC0+IFgtZG9taW5hbnQgKDEpLCBlbHNlIFktZG9taW5hbnQgKDIpCgkJCWNvbnN0IHVpbnQzMl90IGxocyA9IGd3ICogYmg7CgkJCWNvbnN0IHVpbnQzMl90IHJocyA9IGdoICogYnc7CgoJCQkvLyBFcXVhbCAoaXNvdHJvcGljKSwgWD1ZCgkJCWlmIChsaHMgPT0gcmhzKQoJCQkJcmV0dXJuIDA7CgoJCQkvLyBBbmlzb3Ryb3BpYyAtIDE9WCwgMj1ZCgkJCXJldHVybiAobGhzID49IHJocykgPyAxIDogMjsKCQl9CgoJCXN0cnVjdCBncm91cGVkX3RyaWFsX21vZGVzCgkJewoJCQliYXNpc3U6OnVpbnRfdmVjIG1fdG1fZ3JvdXBzW09UTV9OVU1fQ0VNU11bT1RNX05VTV9TVUJTRVRTXVtPVE1fTlVNX0NDU11bT1RNX05VTV9HUklEX1NJWkVTXVtPVE1fTlVNX0dSSURfQU5JU09TXTsgLy8gaW5kaWNlcyBvZiBlbmNvZGVyIHRyaWFsIG1vZGVzIGluIGVhY2ggYnVja2V0CgoJCQl2b2lkIGNsZWFyKCkKCQkJewoJCQkJZm9yICh1aW50MzJfdCBjZW1faXRlciA9IDA7IGNlbV9pdGVyIDwgT1RNX05VTV9DRU1TOyBjZW1faXRlcisrKQoJCQkJCWZvciAodWludDMyX3Qgc3Vic2V0c19pdGVyID0gMDsgc3Vic2V0c19pdGVyIDwgT1RNX05VTV9TVUJTRVRTOyBzdWJzZXRzX2l0ZXIrKykKCQkJCQkJZm9yICh1aW50MzJfdCBjY3NfaXRlciA9IDA7IGNjc19pdGVyIDwgT1RNX05VTV9DQ1M7IGNjc19pdGVyKyspCgkJCQkJCQlmb3IgKHVpbnQzMl90IGdyaWRfc2l6ZXNfaXRlciA9IDA7IGdyaWRfc2l6ZXNfaXRlciA8IE9UTV9OVU1fR1JJRF9TSVpFUzsgZ3JpZF9zaXplc19pdGVyKyspCgkJCQkJCQkJZm9yICh1aW50MzJfdCBncmlkX2FuaXNvc19pdGVyID0gMDsgZ3JpZF9hbmlzb3NfaXRlciA8IE9UTV9OVU1fR1JJRF9BTklTT1M7IGdyaWRfYW5pc29zX2l0ZXIrKykKCQkJCQkJCQkJbV90bV9ncm91cHNbY2VtX2l0ZXJdW3N1YnNldHNfaXRlcl1bY2NzX2l0ZXJdW2dyaWRfc2l6ZXNfaXRlcl1bZ3JpZF9hbmlzb3NfaXRlcl0uY2xlYXIoKTsKCQkJfQoKCQkJdm9pZCBhZGQodWludDMyX3QgYmxvY2tfd2lkdGgsIHVpbnQzMl90IGJsb2NrX2hlaWdodCwKCQkJCWNvbnN0IHRyaWFsX21vZGUmIHRtLCB1aW50MzJfdCB0bV9pbmRleCkKCQkJewoJCQkJY29uc3QgdWludDMyX3QgY2VtX2luZGV4ID0gdG0ubV9jZW07CgkJCQlhc3NlcnQoY2VtX2luZGV4IDwgT1RNX05VTV9DRU1TKTsKCgkJCQljb25zdCB1aW50MzJfdCBzdWJzZXRfaW5kZXggPSB0bS5tX251bV9wYXJ0cyAtIDE7CgkJCQlhc3NlcnQoc3Vic2V0X2luZGV4IDwgT1RNX05VTV9TVUJTRVRTKTsKCgkJCQljb25zdCB1aW50MzJfdCBjY3NfaW5kZXggPSB0bS5tX2Njc19pbmRleCArIDE7CgkJCQlhc3NlcnQoY2NzX2luZGV4IDwgT1RNX05VTV9DQ1MpOwoKCQkJCWNvbnN0IHVpbnQzMl90IGdyaWRfc2l6ZSA9ICh0bS5tX2dyaWRfd2lkdGggPj0gKGJsb2NrX3dpZHRoIC0gMSkpICYmICh0bS5tX2dyaWRfaGVpZ2h0ID49IChibG9ja19oZWlnaHQgLSAxKSk7CgkJCQljb25zdCB1aW50MzJfdCBncmlkX2FuaXNvID0gY2FsY19ncmlkX2FuaXNvX3ZhbCh0bS5tX2dyaWRfd2lkdGgsIHRtLm1fZ3JpZF9oZWlnaHQsIGJsb2NrX3dpZHRoLCBibG9ja19oZWlnaHQpOwoKCQkJCWJhc2lzdTo6dWludF92ZWMmIHYgPSBtX3RtX2dyb3Vwc1tjZW1faW5kZXhdW3N1YnNldF9pbmRleF1bY2NzX2luZGV4XVtncmlkX3NpemVdW2dyaWRfYW5pc29dOwoJCQkJaWYgKCF2LmNhcGFjaXR5KCkpCgkJCQkJdi5yZXNlcnZlKDY0KTsKCgkJCQl2LnB1c2hfYmFjayh0bV9pbmRleCk7CgkJCX0KCgkJCXVpbnQzMl90IGNvdW50X3VzZWRfZ3JvdXBzKCkgY29uc3QKCQkJewoJCQkJdWludDMyX3QgbiA9IDA7CgoJCQkJZm9yICh1aW50MzJfdCBjZW1faXRlciA9IDA7IGNlbV9pdGVyIDwgT1RNX05VTV9DRU1TOyBjZW1faXRlcisrKQoJCQkJCWZvciAodWludDMyX3Qgc3Vic2V0c19pdGVyID0gMDsgc3Vic2V0c19pdGVyIDwgT1RNX05VTV9TVUJTRVRTOyBzdWJzZXRzX2l0ZXIrKykKCQkJCQkJZm9yICh1aW50MzJfdCBjY3NfaXRlciA9IDA7IGNjc19pdGVyIDwgT1RNX05VTV9DQ1M7IGNjc19pdGVyKyspCgkJCQkJCQlmb3IgKHVpbnQzMl90IGdyaWRfc2l6ZXNfaXRlciA9IDA7IGdyaWRfc2l6ZXNfaXRlciA8IE9UTV9OVU1fR1JJRF9TSVpFUzsgZ3JpZF9zaXplc19pdGVyKyspCgkJCQkJCQkJZm9yICh1aW50MzJfdCBncmlkX2FuaXNvc19pdGVyID0gMDsgZ3JpZF9hbmlzb3NfaXRlciA8IE9UTV9OVU1fR1JJRF9BTklTT1M7IGdyaWRfYW5pc29zX2l0ZXIrKykKCQkJCQkJCQl7CgkJCQkJCQkJCWlmIChtX3RtX2dyb3Vwc1tjZW1faXRlcl1bc3Vic2V0c19pdGVyXVtjY3NfaXRlcl1bZ3JpZF9zaXplc19pdGVyXVtncmlkX2FuaXNvc19pdGVyXS5zaXplKCkpCgkJCQkJCQkJCQluKys7CgkJCQkJCQkJfQoJCQkJcmV0dXJuIG47CgkJCX0KCQl9OwoKCQlleHRlcm4gZ3JvdXBlZF90cmlhbF9tb2RlcyBnX2dyb3VwZWRfZW5jb2Rlcl90cmlhbF9tb2Rlc1thc3RjX2hlbHBlcnM6OmNUT1RBTF9CTE9DS19TSVpFU107CgoJCWlubGluZSBjb25zdCBiYXNpc3U6OnVpbnRfdmVjJiBnZXRfdG1fY2FuZGlkYXRlcyhjb25zdCBncm91cGVkX3RyaWFsX21vZGVzJiBncm91cGVkX2VuY190cmlhbF9tb2RlcywKCQkJdWludDMyX3QgY2VtX2luZGV4LCB1aW50MzJfdCBzdWJzZXRfaW5kZXgsIHVpbnQzMl90IGNjc19pbmRleCwgdWludDMyX3QgZ3JpZF9zaXplLCB1aW50MzJfdCBncmlkX2FuaXNvKQoJCXsKCQkJYXNzZXJ0KGNlbV9pbmRleCA8IE9UTV9OVU1fQ0VNUyk7CgkJCWFzc2VydChzdWJzZXRfaW5kZXggPCBPVE1fTlVNX1NVQlNFVFMpOwoJCQlhc3NlcnQoY2NzX2luZGV4IDwgT1RNX05VTV9DQ1MpOwoJCQlhc3NlcnQoZ3JpZF9zaXplIDwgT1RNX05VTV9HUklEX1NJWkVTKTsKCQkJYXNzZXJ0KGdyaWRfYW5pc28gPCBPVE1fTlVNX0dSSURfQU5JU09TKTsKCgkJCWNvbnN0IGJhc2lzdTo6dWludF92ZWMmIG1vZGVzID0gZ3JvdXBlZF9lbmNfdHJpYWxfbW9kZXMubV90bV9ncm91cHNbY2VtX2luZGV4XVtzdWJzZXRfaW5kZXhdW2Njc19pbmRleF1bZ3JpZF9zaXplXVtncmlkX2FuaXNvXTsKCQkJcmV0dXJuIG1vZGVzOwoJCX0KCgkJY29uc3QgdWludDMyX3QgQ0ZHX1BBQ0tfR1JJRF9CSVRTID0gNzsKCQljb25zdCB1aW50MzJfdCBDRkdfUEFDS19DRU1fQklUUyA9IDM7CgkJY29uc3QgdWludDMyX3QgQ0ZHX1BBQ0tfQ0NTX0JJVFMgPSAzOwoJCWNvbnN0IHVpbnQzMl90IENGR19QQUNLX1NVQlNFVFNfQklUUyA9IDI7CgkJY29uc3QgdWludDMyX3QgQ0ZHX1BBQ0tfV0lTRV9CSVRTID0gNDsKCQljb25zdCB1aW50MzJfdCBDRkdfUEFDS19FSVNFX0JJVFMgPSA1OwoKCQlleHRlcm4gY29uc3QgaW50IHNfdW5pcXVlX2xkcl9pbmRleF90b19hc3RjX2NlbVs2XTsKCgkJZW51bSBjbGFzcyB4dWFzdGNfbW9kZQoJCXsKCQkJY01PREVfU09MSUQgPSAwLAoJCQljTU9ERV9SQVcgPSAxLAoKCQkJLy8gRnVsbCBjZmcsIHBhcnRpdGlvbiBJRCwgYW5kIGFsbCBlbmRwb2ludCB2YWx1ZSByZXVzZS4KCQkJY01PREVfUkVVU0VfQ0ZHX0VORFBPSU5UU19MRUZUID0gMiwKCQkJY01PREVfUkVVU0VfQ0ZHX0VORFBPSU5UU19VUCA9IDMsCgkJCWNNT0RFX1JFVVNFX0NGR19FTkRQT0lOVFNfRElBRyA9IDQsCgoJCQljTU9ERV9SVU4gPSA1LAoKCQkJY01PREVfVE9UQUwsCgkJfTsKCgkJZW51bSBjbGFzcyB4dWFzdGNfenN0ZF9tb2RlCgkJewoJCQkvLyBsZW49MSBiaXRzCgkJCWNNT0RFX1JBVyA9IDBiMCwKCgkJCS8vIGxlbj0yIGJpdHMKCQkJY01PREVfUlVOID0gMGIwMSwKCgkJCS8vIGxlbj00IGJpdHMKCQkJY01PREVfU09MSUQgPSAwYjAwMTEsCgkJCWNNT0RFX1JFVVNFX0NGR19FTkRQT0lOVFNfTEVGVCA9IDBiMDExMSwgCgkJCWNNT0RFX1JFVVNFX0NGR19FTkRQT0lOVFNfVVAgPSAwYjEwMTEsICAgCgkJCWNNT0RFX1JFVVNFX0NGR19FTkRQT0lOVFNfRElBRyA9IDBiMTExMSAgCgkJfTsKCgkJY29uc3QgdWludDMyX3QgWFVBU1RDX0xEUl9NT0RFX0JZVEVfSVNfQkFTRV9PRlNfRkxBRyA9IDEgPDwgMzsKCQljb25zdCB1aW50MzJfdCBYVUFTVENfTERSX01PREVfQllURV9QQVJUX0hBU0hfSElUID0gMSA8PCA0OwoJCWNvbnN0IHVpbnQzMl90IFhVQVNUQ19MRFJfTU9ERV9CWVRFX0RQQ01fRU5EUE9JTlRTX0ZMQUcgPSAxIDw8IDU7CgkJY29uc3QgdWludDMyX3QgWFVBU1RDX0xEUl9NT0RFX0JZVEVfVE1fSEFTSF9ISVRfRkxBRyA9IDEgPDwgNjsKCQljb25zdCB1aW50MzJfdCBYVUFTVENfTERSX01PREVfQllURV9VU0VfRENUID0gMSA8PCA3OwoKCQllbnVtIGNsYXNzIHh1YXN0Y19sZHJfc3ludGF4CgkJewoJCQljRnVsbEFyaXRoID0gMCwKCQkJY0h5YnJpZEFyaXRoWlN0ZCA9IDEsCgkJCWNGdWxsWlN0ZCA9IDIsCgoJCQljVG90YWwKCQl9OwoKCQl2b2lkIGNyZWF0ZV9lbmNvZGVyX3RyaWFsX21vZGVzX3RhYmxlKHVpbnQzMl90IGJsb2NrX3dpZHRoLCB1aW50MzJfdCBibG9ja19oZWlnaHQsCgkJCWJhc2lzdTo6dmVjdG9yPHRyaWFsX21vZGU+JiBlbmNvZGVyX3RyaWFsX21vZGVzLCBncm91cGVkX3RyaWFsX21vZGVzJiBncm91cGVkX2VuY29kZXJfdHJpYWxfbW9kZXMsCgkJCWJvb2wgcHJpbnRfZGVidWdfaW5mbywgYm9vbCBwcmludF9tb2Rlcyk7CgoJCWV4dGVybiBiYXNpc3U6OnZlY3Rvcjx0cmlhbF9tb2RlPiBnX2VuY29kZXJfdHJpYWxfbW9kZXNbYXN0Y19oZWxwZXJzOjpjVE9UQUxfQkxPQ0tfU0laRVNdOwoJCQkJCgkJaW5saW5lIHVpbnQzMl90IHBhcnRfaGFzaF9pbmRleCh1aW50MzJfdCB4KQoJCXsKCQkJLy8gZmliIGhhc2gKCQkJcmV0dXJuICh4ICogMjY1NDQzNTc2OXUpICYgKFBBUlRfSEFTSF9TSVpFIC0gMSk7CgkJfQoKCQkvLyBGdWxsIFpTdGQgc3ludGF4IG9ubHkKCQlpbmxpbmUgdWludDMyX3QgdG1faGFzaF9pbmRleCh1aW50MzJfdCB4KQoJCXsKCQkJLy8gZmliIGhhc2gKCQkJcmV0dXJuICh4ICogMjY1NDQzNTc2OXUpICYgKFRNX0hBU0hfU0laRSAtIDEpOwoJCX0KCgkJLy8gVE9ETzogU29tZSBmaWVsZHMgYXJlIHVudXNlZCBkdXJpbmcgdHJhbnNjb2RpbmcuCgkJc3RydWN0IHByZXZfYmxvY2tfc3RhdGUKCQl7CgkJCWJvb2wgbV93YXNfc29saWRfY29sb3I7CgkJCWJvb2wgbV91c2VkX3dlaWdodF9kY3Q7CgkJCWJvb2wgbV9maXJzdF9lbmRwb2ludF91c2VzX2JjOwoJCQlib29sIG1fcmV1c2VkX2Z1bGxfY2ZnOwoJCQlib29sIG1fdXNlZF9wYXJ0X2hhc2g7CgoJCQlpbnQgbV90bV9pbmRleDsgLy8gLTEgaWYgaW52YWxpZCAoc29saWQgY29sb3IgYmxvY2spCgkJCXVpbnQzMl90IG1fYmFzZV9jZW1faW5kZXg7IC8vIGRvZXNuJ3QgaW5jbHVkZSBiYXNlK29mcwoJCQl1aW50MzJfdCBtX3N1YnNldF9pbmRleCwgbV9jY3NfaW5kZXgsIG1fZ3JpZF9zaXplLCBtX2dyaWRfYW5pc287CgoJCQlwcmV2X2Jsb2NrX3N0YXRlKCkKCQkJewoJCQkJY2xlYXIoKTsKCQkJfQoKCQkJdm9pZCBjbGVhcigpCgkJCXsKCQkJCWJhc2lzdTo6Y2xlYXJfb2JqKCp0aGlzKTsKCQkJfQoJCX07CgoJCXN0cnVjdCBwcmV2X2Jsb2NrX3N0YXRlX2Z1bGxfenN0ZAoJCXsKCQkJaW50IG1fdG1faW5kZXg7IC8vIC0xIGlmIGludmFsaWQgKHNvbGlkIGNvbG9yIGJsb2NrKQoJCQkKCQkJYm9vbCB3YXNfc29saWRfY29sb3IoKSBjb25zdCB7IHJldHVybiBtX3RtX2luZGV4IDwgMDsgfQoKCQkJcHJldl9ibG9ja19zdGF0ZV9mdWxsX3pzdGQoKQoJCQl7CgkJCQljbGVhcigpOwoJCQl9CgoJCQl2b2lkIGNsZWFyKCkKCQkJewoJCQkJYmFzaXN1OjpjbGVhcl9vYmooKnRoaXMpOwoJCQl9CgkJfTsKCgkJaW5saW5lIHVpbnQzMl90IGNlbV90b19sZHJjZW1faW5kZXgodWludDMyX3QgY2VtKQoJCXsKCQkJc3dpdGNoIChjZW0pCgkJCXsKCQkJY2FzZSBhc3RjX2hlbHBlcnM6OkNFTV9MRFJfTFVNX0RJUkVDVDogcmV0dXJuIDA7CgkJCWNhc2UgYXN0Y19oZWxwZXJzOjpDRU1fTERSX0xVTV9BTFBIQV9ESVJFQ1Q6IHJldHVybiAxOwoJCQljYXNlIGFzdGNfaGVscGVyczo6Q0VNX0xEUl9SR0JfQkFTRV9TQ0FMRTogcmV0dXJuIDI7CgkJCWNhc2UgYXN0Y19oZWxwZXJzOjpDRU1fTERSX1JHQl9ESVJFQ1Q6IHJldHVybiAzOwoJCQljYXNlIGFzdGNfaGVscGVyczo6Q0VNX0xEUl9SR0JfQkFTRV9QTFVTX09GRlNFVDogcmV0dXJuIDQ7CgkJCWNhc2UgYXN0Y19oZWxwZXJzOjpDRU1fTERSX1JHQl9CQVNFX1NDQUxFX1BMVVNfVFdPX0E6IHJldHVybiA1OwoJCQljYXNlIGFzdGNfaGVscGVyczo6Q0VNX0xEUl9SR0JBX0RJUkVDVDogcmV0dXJuIDY7CgkJCWNhc2UgYXN0Y19oZWxwZXJzOjpDRU1fTERSX1JHQkFfQkFTRV9QTFVTX09GRlNFVDogcmV0dXJuIDc7CgkJCWRlZmF1bHQ6CgkJCQlhc3NlcnQoMCk7CgkJCQlicmVhazsKCQkJfQoKCQkJcmV0dXJuIDA7CgkJfQoJCQkJCgkJYm9vbCBwYWNrX2Jhc2Vfb2Zmc2V0KAoJCQl1aW50MzJfdCBjZW1faW5kZXgsIHVpbnQzMl90IGRzdF9pc2VfZW5kcG9pbnRfcmFuZ2UsIHVpbnQ4X3QqIHBQYWNrZWRfZW5kcG9pbnRzLAoJCQljb25zdCBjb2xvcl9yZ2JhJiBsLCBjb25zdCBjb2xvcl9yZ2JhJiBoLAoJCQlib29sIHVzZV9ibHVlX2NvbnRyYWN0aW9uLCBib29sIGF1dG9fZGlzYWJsZV9ibHVlX2NvbnRyYWN0aW9uX2lmX2NsYW1wZWQsCgkJCWJvb2wmIGJsdWVfY29udHJhY3Rpb25fY2xhbXBlZF9mbGFnLCBib29sJiBiYXNlX29mc19jbGFtcGVkX2ZsYWcsIGJvb2wmIGVuZHBvaW50c19zd2FwcGVkKTsKCgkJYm9vbCBjb252ZXJ0X2VuZHBvaW50c19hY3Jvc3NfY2VtcygKCQkJdWludDMyX3QgcHJldl9jZW0sIHVpbnQzMl90IHByZXZfZW5kcG9pbnRfaXNlX3JhbmdlLCBjb25zdCB1aW50OF90KiBwUHJldl9lbmRwb2ludHMsCgkJCXVpbnQzMl90IGRzdF9jZW0sIHVpbnQzMl90IGRzdF9lbmRwb2ludF9pc2VfcmFuZ2UsIHVpbnQ4X3QqIHBEc3RfZW5kcG9pbnRzLAoJCQlib29sIGFsd2F5c19yZXBhY2ssCgkJCWJvb2wgdXNlX2JsdWVfY29udHJhY3Rpb24sIGJvb2wgYXV0b19kaXNhYmxlX2JsdWVfY29udHJhY3Rpb25faWZfY2xhbXBlZCwKCQkJYm9vbCYgYmx1ZV9jb250cmFjdGlvbl9jbGFtcGVkX2ZsYWcsIGJvb2wmIGJhc2Vfb2ZzX2NsYW1wZWRfZmxhZyk7CgoJCXVpbnQzMl90IGdldF90b3RhbF91bmlxdWVfcGF0dGVybnModWludDMyX3QgYXN0Y19ibG9ja19zaXplX2luZGV4LCB1aW50MzJfdCBudW1fcGFydHMpOwoJCS8vdWludDE2X3QgdW5pcXVlX3BhdF9pbmRleF90b19wYXJ0X3NlZWQodWludDMyX3QgYXN0Y19ibG9ja19zaXplX2luZGV4LCB1aW50MzJfdCBudW1fcGFydHMsIHVpbnQzMl90IHVuaXF1ZV9wYXRfaW5kZXgpOwoKCQl0eXBlZGVmIGJvb2wgKCp4dWFzdGNfZGVjb21wX2ltYWdlX2luaXRfY2FsbGJhY2tfcHRyKSh1aW50MzJfdCBudW1fYmxvY2tzX3gsIHVpbnQzMl90IG51bV9ibG9ja3NfeSwgdWludDMyX3QgYmxvY2tfd2lkdGgsIHVpbnQzMl90IGJsb2NrX2hlaWdodCwgYm9vbCBzcmdiX2RlY29kZV9wcm9maWxlLCBmbG9hdCBkY3RfcSwgYm9vbCBoYXNfYWxwaGEsIHZvaWQqIHBEYXRhKTsKCQl0eXBlZGVmIGJvb2wgKCp4dWFzdGNfZGVjb21wX2ltYWdlX2Jsb2NrX2NhbGxiYWNrX3B0cikodWludDMyX3QgYngsIHVpbnQzMl90IGJ5LCBjb25zdCBhc3RjX2hlbHBlcnM6OmxvZ19hc3RjX2Jsb2NrJiBsb2dfYmxrLCB2b2lkKiBwRGF0YSk7CgkJCQkKCQlib29sIHh1YXN0Y19sZHJfZGVjb21wcmVzc19pbWFnZSgKCQkJY29uc3QgdWludDhfdCogcENvbXBfZGF0YSwgc2l6ZV90IGNvbXBfZGF0YV9zaXplLAoJCQl1aW50MzJfdCYgYXN0Y19ibG9ja193aWR0aCwgdWludDMyX3QmIGFzdGNfYmxvY2tfaGVpZ2h0LAoJCQl1aW50MzJfdCYgYWN0dWFsX3dpZHRoLCB1aW50MzJfdCYgYWN0dWFsX2hlaWdodCwgYm9vbCYgaGFzX2FscGhhLCBib29sJiB1c2VzX3NyZ2JfYXN0Y19kZWNvZGVfbW9kZSwKCQkJYm9vbCBkZWJ1Z19vdXRwdXQsCgkJCXh1YXN0Y19kZWNvbXBfaW1hZ2VfaW5pdF9jYWxsYmFja19wdHIgcEluaXRfY2FsbGJhY2ssIHZvaWQgKnBJbml0X2NhbGxiYWNrX2RhdGEsCgkJCXh1YXN0Y19kZWNvbXBfaW1hZ2VfYmxvY2tfY2FsbGJhY2tfcHRyIHBCbG9ja19jYWxsYmFjaywgdm9pZCAqcEJsb2NrX2NhbGxiYWNrX2RhdGEpOwoJCQoJfSAvLyBuYW1lc3BhY2UgYXN0Y19sZHJfdAoKCW5hbWVzcGFjZSBhcml0aF9mYXN0Yml0c19mMzIKCXsKCQllbnVtIHsgVEFCTEVfQklUUyA9IDggfTsgICAgICAgICAgICAgICAvLyAyNTYuLjEwMjQgZW50cmllcyB0eXBpY2FsICg4Li4xMCkKCQllbnVtIHsgVEFCTEVfU0laRSA9IDEgPDwgVEFCTEVfQklUUyB9OwoJCWVudW0geyBNQU5UX0JJVFMgPSAyMyB9OwoJCWVudW0geyBGUkFDX0JJVFMgPSBNQU5UX0JJVFMgLSBUQUJMRV9CSVRTIH07CgkJZW51bSB7IEZSQUNfTUFTSyA9ICgxdSA8PCBGUkFDX0JJVFMpIC0gMXUgfTsKCgkJZXh0ZXJuIGJvb2wgZ19pbml0aWFsaXplZDsKCQlleHRlcm4gZmxvYXQgZ19sdXRfZWRnZVtUQUJMRV9TSVpFICsgMV07IC8vIHNhbXBsZXMgYXQgbSA9IDEgKyBpL1RBQkxFX1NJWkUgKGZvciBsaW5lYXIpCgoJCWlubGluZSB2b2lkIGluaXQoKQoJCXsKCQkJaWYgKGdfaW5pdGlhbGl6ZWQpCgkJCQlyZXR1cm47CgoJCQljb25zdCBmbG9hdCBpbnZfbG4yID0gMS40NDI2OTUwNDA4ODg5NjM0ZjsgLy8gMS9sbigyKQoKCQkJZm9yIChpbnQgaSA9IDA7IGkgPD0gVEFCTEVfU0laRTsgKytpKQoJCQl7CgkJCQlmbG9hdCBtID0gMS4wZiArIGZsb2F0KGkpIC8gZmxvYXQoVEFCTEVfU0laRSk7ICAgICAgLy8gbSBpbiBbMSwyXQoJCQkJZ19sdXRfZWRnZVtpXSA9IGxvZ2YobSkgKiBpbnZfbG4yOyAgICAgICAgICAgICAvLyBsb2cyKG0pCgkJCX0KCgkJCWdfaW5pdGlhbGl6ZWQgPSB0cnVlOwoJCX0KCgkJaW5saW5lIHZvaWQgdW5wYWNrKGZsb2F0IHAsIGludCYgZV91bmJpYXNlZCwgdWludDMyX3QmIG1hbnQpCgkJewoJCQkvLyBraWxsIGFueSBkZW5vcm1zCgkJCWlmIChwIDwgRkxUX01JTikKCQkJCXAgPSAwOwoKCQkJdW5pb24geyBmbG9hdCBmOyB1aW50MzJfdCB1OyB9IHg7CgkJCXguZiA9IHA7CgkJCWVfdW5iaWFzZWQgPSBpbnQoKHgudSA+PiAyMykgJiAweEZGKSAtIDEyNzsKCQkJbWFudCA9ICh4LnUgJiAweDdGRkZGRnUpOyAvLyAyMy1iaXQgbWFudGlzc2EKCQl9CgoJCS8vIFJldHVybnMgZXN0aW1hdGVkIGJpdHMgZ2l2ZW4gcHJvYmFiaWxpdHkgcCwgYXBwcm94aW1hdGVzIC1sb2cyZihwKS4KCQlpbmxpbmUgZmxvYXQgYml0c19mcm9tX3Byb2JfbGluZWFyKGZsb2F0IHApCgkJewoJCQlhc3NlcnQoKHAgPiAwLjBmKSAmJiAocCA8PSAxLjBmKSk7CgkJCWlmICghZ19pbml0aWFsaXplZCkKCQkJCWluaXQoKTsKCgkJCWludCBlOyB1aW50MzJfdCBtYW50OwoJCQl1bnBhY2socCwgZSwgbWFudCk7CgoJCQl1aW50MzJfdCBpZHggPSBtYW50ID4+IEZSQUNfQklUUzsgICAgICAgICAgICAvLyAwLi5UQUJMRV9TSVpFLTEKCQkJdWludDMyX3QgZnJhYyA9IG1hbnQgJiBGUkFDX01BU0s7ICAgICAgICAgICAgIC8vIGxvdyBGUkFDX0JJVFMKCQkJY29uc3QgZmxvYXQgaW52X3NjYWxlID0gMS4wZiAvIGZsb2F0KDF1IDw8IEZSQUNfQklUUyk7CgkJCWZsb2F0IHQgPSBmbG9hdChmcmFjKSAqIGludl9zY2FsZTsgICAgICAgICAgICAgICAgIC8vIFswLDEpCgoJCQlmbG9hdCB5MCA9IGdfbHV0X2VkZ2VbaWR4XTsKCQkJZmxvYXQgeTEgPSBnX2x1dF9lZGdlW2lkeCArIDFdOwoJCQlmbG9hdCBsb2cybSA9IHkwICsgdCAqICh5MSAtIHkwKTsKCgkJCXJldHVybiAtKGZsb2F0KGUpICsgbG9nMm0pOwoJCX0KCgl9IC8vIG5hbWVzcGFjZSBhcml0aF9mYXN0Yml0c19mMzIKCgluYW1lc3BhY2UgYXJpdGgKCXsKCQkvLyBBIHNpbXBsZSByYW5nZSBjb2RlcgoJCWNvbnN0IHVpbnQzMl90IEFyaXRoTWF4U3ltcyA9IDIwNDg7CgkJY29uc3QgdWludDMyX3QgRE1MZW5TaGlmdCA9IDE1dTsKCQljb25zdCB1aW50MzJfdCBETU1heENvdW50ID0gMXUgPDwgRE1MZW5TaGlmdDsKCQljb25zdCB1aW50MzJfdCBCTUxlblNoaWZ0ID0gMTN1OwoJCWNvbnN0IHVpbnQzMl90IEJNTWF4Q291bnQgPSAxdSA8PCBCTUxlblNoaWZ0OwoJCWNvbnN0IHVpbnQzMl90IEFyaXRoTWluTGVuID0gMXUgPDwgMjR1OwoJCWNvbnN0IHVpbnQzMl90IEFyaXRoTWF4TGVuID0gVUlOVDMyX01BWDsKCQljb25zdCB1aW50MzJfdCBBcml0aE1pbkV4cGVjdGVkRGF0YUJ1ZlNpemUgPSA1OwoKCQljbGFzcyBhcml0aF9iaXRfbW9kZWwKCQl7CgkJcHVibGljOgoJCQlhcml0aF9iaXRfbW9kZWwoKQoJCQl7CgkJCQlyZXNldCgpOwoJCQl9CgoJCQl2b2lkIGluaXQoKQoJCQl7CgkJCQlyZXNldCgpOwoJCQl9CgoJCQl2b2lkIHJlc2V0KCkKCQkJewoJCQkJbV9iaXQwX2NvdW50ID0gMTsKCQkJCW1fYml0X2NvdW50ID0gMjsKCQkJCW1fYml0MF9wcm9iID0gMVUgPDwgKEJNTGVuU2hpZnQgLSAxKTsKCQkJCW1fdXBkYXRlX2ludGVydmFsID0gNDsKCQkJCW1fYml0c191bnRpbF91cGRhdGUgPSA0OwoJCQl9CgoJCQlmbG9hdCBnZXRfcHJpY2UoYm9vbCBiaXQpIGNvbnN0CgkJCXsKCQkJCWNvbnN0IGZsb2F0IHByb2JfMCA9IChmbG9hdCltX2JpdDBfcHJvYiAvIChmbG9hdClCTU1heENvdW50OwoJCQkJY29uc3QgZmxvYXQgcHJvYiA9IGJpdCA/ICgxLjBmIC0gcHJvYl8wKSA6IHByb2JfMDsKCQkJCWNvbnN0IGZsb2F0IGJpdHMgPSBhcml0aF9mYXN0Yml0c19mMzI6OmJpdHNfZnJvbV9wcm9iX2xpbmVhcihwcm9iKTsKCQkJCWFzc2VydChmYWJzKGJpdHMgLSAoLWxvZzJmKHByb2IpKSkgPCAuMDAxMjVmKTsgLy8gYmFzaWMgc2FuaXR5IGNoZWNrCgkJCQlyZXR1cm4gYml0czsKCQkJfQoKCQkJdm9pZCB1cGRhdGUoKQoJCQl7CgkJCQlhc3NlcnQobV9iaXRfY291bnQgPj0gMik7CgkJCQlhc3NlcnQobV9iaXQwX2NvdW50IDwgbV9iaXRfY291bnQpOwoKCQkJCWlmIChtX2JpdF9jb3VudCA+PSBCTU1heENvdW50KQoJCQkJewoJCQkJCWFzc2VydChtX2JpdF9jb3VudCAmJiBtX2JpdDBfY291bnQpOwoKCQkJCQltX2JpdF9jb3VudCA9IChtX2JpdF9jb3VudCArIDEpID4+IDE7CgkJCQkJbV9iaXQwX2NvdW50ID0gKG1fYml0MF9jb3VudCArIDEpID4+IDE7CgoJCQkJCWlmIChtX2JpdDBfY291bnQgPT0gbV9iaXRfY291bnQpCgkJCQkJCSsrbV9iaXRfY291bnQ7CgoJCQkJCWFzc2VydChtX2JpdDBfY291bnQgPCBtX2JpdF9jb3VudCk7CgkJCQl9CgoJCQkJY29uc3QgdWludDMyX3Qgc2NhbGUgPSAweDgwMDAwMDAwVSAvIG1fYml0X2NvdW50OwoJCQkJbV9iaXQwX3Byb2IgPSAobV9iaXQwX2NvdW50ICogc2NhbGUpID4+ICgzMSAtIEJNTGVuU2hpZnQpOwoKCQkJCW1fdXBkYXRlX2ludGVydmFsID0gYmFzaXN1OjpjbGFtcDx1aW50MzJfdD4oKDUgKiBtX3VwZGF0ZV9pbnRlcnZhbCkgPj4gMiwgNHUsIDEyOCk7CgoJCQkJbV9iaXRzX3VudGlsX3VwZGF0ZSA9IG1fdXBkYXRlX2ludGVydmFsOwoJCQl9CgoJCQl2b2lkIHByaW50X3ByaWNlcyhjb25zdCBjaGFyKiBwRGVzYykKCQkJewoJCQkJaWYgKHBEZXNjKQoJCQkJCXByaW50ZigiYXJpdGhfZGF0YV9tb2RlbCBiaXQgcHJpY2VzIGZvciBtb2RlbCAlczpcbiIsIHBEZXNjKTsKCQkJCWZvciAodWludDMyX3QgaSA9IDA7IGkgPCAyOyBpKyspCgkJCQkJcHJpbnRmKCIldTogJTMuM2YgYml0c1xuIiwgaSwgZ2V0X3ByaWNlKGkpKTsKCQkJCXByaW50ZigiXG4iKTsKCQkJfQoKCQlwcml2YXRlOgoJCQlmcmllbmQgY2xhc3MgYXJpdGhfZW5jOwoJCQlmcmllbmQgY2xhc3MgYXJpdGhfZGVjOwoKCQkJdWludDMyX3QgbV9iaXQwX3Byb2I7CS8vIHNuYXBzaG90IG1hZGUgYXQgbGFzdCB1cGRhdGUKCgkJCXVpbnQzMl90IG1fYml0MF9jb3VudDsJLy8gbGl2ZQoJCQl1aW50MzJfdCBtX2JpdF9jb3VudDsJLy8gbGl2ZQoKCQkJaW50IG1fYml0c191bnRpbF91cGRhdGU7CgkJCXVpbnQzMl90IG1fdXBkYXRlX2ludGVydmFsOwoJCX07CgoJCWVudW0geyBjQVJJVEhfR0FNTUFfTUFYX1RBSUxfQ1RYID0gNCwgY0FSSVRIX0dBTU1BX01BWF9QUkVGSVhfQ1RYID0gMyB9OwoJCXN0cnVjdCBhcml0aF9nYW1tYV9jb250ZXh0cwoJCXsKCQkJYXJpdGhfYml0X21vZGVsIG1fY3R4X3ByZWZpeFtjQVJJVEhfR0FNTUFfTUFYX1BSRUZJWF9DVFhdOyAvLyBmb3IgdW5hcnkgY29udGludWUgcHJlZml4CgkJCWFyaXRoX2JpdF9tb2RlbCBtX2N0eF90YWlsW2NBUklUSF9HQU1NQV9NQVhfVEFJTF9DVFhdOyAgICAgLy8gZm9yIGJpbmFyeSBzdWZmaXggYml0cwoJCX07CgoJCWNsYXNzIGFyaXRoX2RhdGFfbW9kZWwKCQl7CgkJcHVibGljOgoJCQlhcml0aF9kYXRhX21vZGVsKCkgOgoJCQkJbV9udW1fZGF0YV9zeW1zKDApLAoJCQkJbV90b3RhbF9zeW1fZnJlcSgwKSwKCQkJCW1fdXBkYXRlX2ludGVydmFsKDApLAoJCQkJbV9udW1fc3ltc191bnRpbF9uZXh0X3VwZGF0ZSgwKQoJCQl7CgkJCX0KCgkJCWFyaXRoX2RhdGFfbW9kZWwodWludDMyX3QgbnVtX3N5bXMsIGJvb2wgZmFzdGVyX3VwZGF0ZSA9IGZhbHNlKSA6CgkJCQltX251bV9kYXRhX3N5bXMoMCksCgkJCQltX3RvdGFsX3N5bV9mcmVxKDApLAoJCQkJbV91cGRhdGVfaW50ZXJ2YWwoMCksCgkJCQltX251bV9zeW1zX3VudGlsX25leHRfdXBkYXRlKDApCgkJCXsKCQkJCWluaXQobnVtX3N5bXMsIGZhc3Rlcl91cGRhdGUpOwoJCQl9CgoJCQl2b2lkIGNsZWFyKCkKCQkJewoJCQkJbV9jdW1fc3ltX2ZyZXFzLmNsZWFyKCk7CgkJCQltX3N5bV9mcmVxcy5jbGVhcigpOwoKCQkJCW1fbnVtX2RhdGFfc3ltcyA9IDA7CgkJCQltX3RvdGFsX3N5bV9mcmVxID0gMDsKCQkJCW1fdXBkYXRlX2ludGVydmFsID0gMDsKCQkJCW1fbnVtX3N5bXNfdW50aWxfbmV4dF91cGRhdGUgPSAwOwoJCQl9CgoJCQl2b2lkIGluaXQodWludDMyX3QgbnVtX3N5bXMsIGJvb2wgZmFzdGVyX3VwZGF0ZSA9IGZhbHNlKQoJCQl7CgkJCQlhc3NlcnQoKG51bV9zeW1zID49IDIpICYmIChudW1fc3ltcyA8PSBBcml0aE1heFN5bXMpKTsKCgkJCQltX251bV9kYXRhX3N5bXMgPSBudW1fc3ltczsKCgkJCQltX3N5bV9mcmVxcy5yZXNpemUobnVtX3N5bXMpOwoJCQkJbV9jdW1fc3ltX2ZyZXFzLnJlc2l6ZShudW1fc3ltcyArIDEpOwoKCQkJCXJlc2V0KGZhc3Rlcl91cGRhdGUpOwoJCQl9CgoJCQl2b2lkIHJlc2V0KGJvb2wgZmFzdGVyX3VwZGF0ZSA9IGZhbHNlKQoJCQl7CgkJCQlpZiAoIW1fbnVtX2RhdGFfc3ltcykKCQkJCQlyZXR1cm47CgoJCQkJbV9zeW1fZnJlcXMuc2V0X2FsbCgxKTsKCQkJCW1fdG90YWxfc3ltX2ZyZXEgPSBtX251bV9kYXRhX3N5bXM7CgoJCQkJbV91cGRhdGVfaW50ZXJ2YWwgPSBtX251bV9kYXRhX3N5bXM7CgkJCQltX251bV9zeW1zX3VudGlsX25leHRfdXBkYXRlID0gMDsKCgkJCQl1cGRhdGUoZmFsc2UpOwoKCQkJCWlmIChmYXN0ZXJfdXBkYXRlKQoJCQkJewoJCQkJCW1fdXBkYXRlX2ludGVydmFsID0gYmFzaXN1OjpjbGFtcDx1aW50MzJfdD4oKG1fbnVtX2RhdGFfc3ltcyArIDcpIC8gOCwgNHUsIChtX251bV9kYXRhX3N5bXMgKyA2KSA8PCAzKTsKCQkJCQltX251bV9zeW1zX3VudGlsX25leHRfdXBkYXRlID0gbV91cGRhdGVfaW50ZXJ2YWw7CgkJCQl9CgkJCX0KCgkJCXZvaWQgdXBkYXRlKGJvb2wgZW5jX2ZsYWcpCgkJCXsKCQkJCWFzc2VydChtX251bV9kYXRhX3N5bXMpOwoJCQkJQkFTSVNVX05PVEVfVU5VU0VEKGVuY19mbGFnKTsKCgkJCQlpZiAoIW1fbnVtX2RhdGFfc3ltcykKCQkJCQlyZXR1cm47CgoJCQkJd2hpbGUgKG1fdG90YWxfc3ltX2ZyZXEgPj0gRE1NYXhDb3VudCkKCQkJCXsKCQkJCQltX3RvdGFsX3N5bV9mcmVxID0gMDsKCgkJCQkJZm9yICh1aW50MzJfdCBuID0gMDsgbiA8IG1fbnVtX2RhdGFfc3ltczsgbisrKQoJCQkJCXsKCQkJCQkJbV9zeW1fZnJlcXNbbl0gPSAobV9zeW1fZnJlcXNbbl0gKyAxdSkgPj4gMXU7CgkJCQkJCW1fdG90YWxfc3ltX2ZyZXEgKz0gbV9zeW1fZnJlcXNbbl07CgkJCQkJfQoJCQkJfQoKCQkJCWNvbnN0IHVpbnQzMl90IHNjYWxlID0gMHg4MDAwMDAwMFUgLyBtX3RvdGFsX3N5bV9mcmVxOwoKCQkJCXVpbnQzMl90IHN1bSA9IDA7CgkJCQlmb3IgKHVpbnQzMl90IGkgPSAwOyBpIDwgbV9udW1fZGF0YV9zeW1zOyArK2kpCgkJCQl7CgkJCQkJYXNzZXJ0KCgodWludDY0X3Qpc2NhbGUgKiBzdW0pIDw9IFVJTlQzMl9NQVgpOwoJCQkJCW1fY3VtX3N5bV9mcmVxc1tpXSA9IChzY2FsZSAqIHN1bSkgPj4gKDMxIC0gRE1MZW5TaGlmdCk7CgkJCQkJc3VtICs9IG1fc3ltX2ZyZXFzW2ldOwoJCQkJfQoJCQkJYXNzZXJ0KHN1bSA9PSBtX3RvdGFsX3N5bV9mcmVxKTsKCgkJCQltX2N1bV9zeW1fZnJlcXNbbV9udW1fZGF0YV9zeW1zXSA9IERNTWF4Q291bnQ7CgoJCQkJbV91cGRhdGVfaW50ZXJ2YWwgPSBiYXNpc3U6OmNsYW1wPHVpbnQzMl90PigoNSAqIG1fdXBkYXRlX2ludGVydmFsKSA+PiAyLCA0dSwgKG1fbnVtX2RhdGFfc3ltcyArIDYpIDw8IDMpOwoKCQkJCW1fbnVtX3N5bXNfdW50aWxfbmV4dF91cGRhdGUgPSBtX3VwZGF0ZV9pbnRlcnZhbDsKCQkJfQoKCQkJZmxvYXQgZ2V0X3ByaWNlKHVpbnQzMl90IHN5bV9pbmRleCkgY29uc3QKCQkJewoJCQkJYXNzZXJ0KHN5bV9pbmRleCA8IG1fbnVtX2RhdGFfc3ltcyk7CgoJCQkJaWYgKHN5bV9pbmRleCA+PSBtX251bV9kYXRhX3N5bXMpCgkJCQkJcmV0dXJuIDAuMGY7CgoJCQkJY29uc3QgZmxvYXQgcHJvYiA9IChmbG9hdCkobV9jdW1fc3ltX2ZyZXFzW3N5bV9pbmRleCArIDFdIC0gbV9jdW1fc3ltX2ZyZXFzW3N5bV9pbmRleF0pIC8gKGZsb2F0KURNTWF4Q291bnQ7CgoJCQkJY29uc3QgZmxvYXQgYml0cyA9IGFyaXRoX2Zhc3RiaXRzX2YzMjo6Yml0c19mcm9tX3Byb2JfbGluZWFyKHByb2IpOwoJCQkJYXNzZXJ0KGZhYnMoYml0cyAtICgtbG9nMmYocHJvYikpKSA8IC4wMDEyNWYpOyAvLyBiYXNpYyBzYW5pdHkgY2hlY2sKCQkJCXJldHVybiBiaXRzOwoJCQl9CgoJCQl2b2lkIHByaW50X3ByaWNlcyhjb25zdCBjaGFyKiBwRGVzYykKCQkJewoJCQkJaWYgKHBEZXNjKQoJCQkJCXByaW50ZigiYXJpdGhfZGF0YV9tb2RlbCBiaXQgcHJpY2VzIGZvciBtb2RlbCAlczpcbiIsIHBEZXNjKTsKCQkJCWZvciAodWludDMyX3QgaSA9IDA7IGkgPCBtX251bV9kYXRhX3N5bXM7IGkrKykKCQkJCQlwcmludGYoIiV1OiAlMy4zZiBiaXRzXG4iLCBpLCBnZXRfcHJpY2UoaSkpOwoJCQkJcHJpbnRmKCJcbiIpOwoJCQl9CgoJCQl1aW50MzJfdCBnZXRfbnVtX2RhdGFfc3ltcygpIGNvbnN0IHsgcmV0dXJuIG1fbnVtX2RhdGFfc3ltczsgfQoKCQlwcml2YXRlOgoJCQlmcmllbmQgY2xhc3MgYXJpdGhfZW5jOwoJCQlmcmllbmQgY2xhc3MgYXJpdGhfZGVjOwoKCQkJdWludDMyX3QgbV9udW1fZGF0YV9zeW1zOwoKCQkJYmFzaXN1Ojp1aW50X3ZlYyBtX3N5bV9mcmVxczsJCS8vIGxpdmUgaGlzdG9ncmFtCgkJCXVpbnQzMl90IG1fdG90YWxfc3ltX2ZyZXE7IC8vIGFsd2F5cyBsaXZlIHZzLiBtX3N5bV9mcmVxcwoKCQkJYmFzaXN1Ojp1aW50X3ZlYyBtX2N1bV9zeW1fZnJlcXM7IC8vIGhhcyAxIGV4dHJhIGVudHJ5LCBzbmFwc2hvdCBmcm9tIGxhc3QgdXBkYXRlCgoJCQl1aW50MzJfdCBtX3VwZGF0ZV9pbnRlcnZhbDsKCQkJaW50IG1fbnVtX3N5bXNfdW50aWxfbmV4dF91cGRhdGU7CgoJCQl1aW50MzJfdCBnZXRfbGFzdF9zeW1faW5kZXgoKSBjb25zdCB7IHJldHVybiBtX251bV9kYXRhX3N5bXMgLSAxOyB9CgkJfTsKCgkJY2xhc3MgYXJpdGhfZW5jCgkJewoJCXB1YmxpYzoKCQkJYXJpdGhfZW5jKCkKCQkJewoJCQkJY2xlYXIoKTsKCQkJfQoKCQkJdm9pZCBjbGVhcigpCgkJCXsKCQkJCW1fZGF0YV9idWYuY2xlYXIoKTsKCgkJCQltX2Jhc2UgPSAwOwoJCQkJbV9sZW5ndGggPSBBcml0aE1heExlbjsKCQkJfQoKCQkJdm9pZCBpbml0KHNpemVfdCByZXNlcnZlX3NpemUpCgkJCXsKCQkJCW1fZGF0YV9idWYucmVzZXJ2ZShyZXNlcnZlX3NpemUpOwoJCQkJbV9kYXRhX2J1Zi5yZXNpemUoMCk7CgoJCQkJbV9iYXNlID0gMDsKCQkJCW1fbGVuZ3RoID0gQXJpdGhNYXhMZW47CgoJCQkJLy8gUGxhY2UgOC1iaXQgbWFya2VyIGF0IGJlZ2lubmluZy4gCgkJCQkvLyBUaGlzIHZpcnR1YWxseSBhbHdheXMgZ3VhcmFudGVlcyBubyBiYWNrd2FyZHMgY2FycmllcyBjYW4gYmUgbG9zdCBhdCB0aGUgdmVyeSBiZWdpbm5pbmcgb2YgdGhlIHN0cmVhbS4gKFNob3VsZCBiZSBpbXBvc3NpYmxlIHdpdGggdGhpcyBkZXNpZ24uKQoJCQkJLy8gSXQgYWx3YXlzIHB1c2hlcyBvdXQgMSAwIGJ5dGUgYXQgdGhlIHZlcnkgYmVnaW5uaW5nIHRvIGFic29yYiBmdXR1cmUgY2Fycmllcy4KCQkJCS8vIENhbGxlciBkb2VzIHRoaXMgbm93LCB3ZSBzZW5kIGEgdGlueSBoZWFkZXIgYW55d2F5CgkJCQkvL3B1dF9iaXRzKDB4MSwgOCk7CgkJCQkvL2Fzc2VydChtX2RhdGFfYnVmWzBdICE9IDB4RkYpOwoJCQl9CgoJCQl2b2lkIHB1dF9iaXQodWludDMyX3QgYml0KQoJCQl7CgkJCQltX2xlbmd0aCA+Pj0gMTsKCgkJCQlpZiAoYml0KQoJCQkJewoJCQkJCWNvbnN0IHVpbnQzMl90IG9yaWdfYmFzZSA9IG1fYmFzZTsKCgkJCQkJbV9iYXNlICs9IG1fbGVuZ3RoOwoKCQkJCQlpZiAob3JpZ19iYXNlID4gbV9iYXNlKQoJCQkJCQlwcm9wX2NhcnJ5KCk7CgkJCQl9CgoJCQkJaWYgKG1fbGVuZ3RoIDwgQXJpdGhNaW5MZW4pCgkJCQkJcmVub3JtKCk7CgkJCX0KCgkJCWVudW0geyBjTWF4UHV0Qml0c0xlbiA9IDIwIH07CgkJCXZvaWQgcHV0X2JpdHModWludDMyX3QgdmFsLCB1aW50MzJfdCBudW1fYml0cykKCQkJewoJCQkJYXNzZXJ0KG51bV9iaXRzICYmIChudW1fYml0cyA8PSBjTWF4UHV0Qml0c0xlbikpOwoJCQkJYXNzZXJ0KHZhbCA8ICgxdSA8PCBudW1fYml0cykpOwoKCQkJCW1fbGVuZ3RoID4+PSBudW1fYml0czsKCgkJCQljb25zdCB1aW50MzJfdCBvcmlnX2Jhc2UgPSBtX2Jhc2U7CgoJCQkJbV9iYXNlICs9IHZhbCAqIG1fbGVuZ3RoOwoKCQkJCWlmIChvcmlnX2Jhc2UgPiBtX2Jhc2UpCgkJCQkJcHJvcF9jYXJyeSgpOwoKCQkJCWlmIChtX2xlbmd0aCA8IEFyaXRoTWluTGVuKQoJCQkJCXJlbm9ybSgpOwoJCQl9CgoJCQkvLyByZXR1cm5zICMgb2YgYml0cyBhY3R1YWxseSB3cml0dGVuCgkJCWlubGluZSB1aW50MzJfdCBwdXRfdHJ1bmNhdGVkX2JpbmFyeSh1aW50MzJfdCB2LCB1aW50MzJfdCBuKQoJCQl7CgkJCQlhc3NlcnQoKG4gPj0gMikgJiYgKHYgPCBuKSk7CgoJCQkJdWludDMyX3QgayA9IGJhc2lzdTo6Zmxvb3JfbG9nMmkobik7CgkJCQl1aW50MzJfdCB1ID0gKDEgPDwgKGsgKyAxKSkgLSBuOwoKCQkJCWlmICh2IDwgdSkKCQkJCXsKCQkJCQlwdXRfYml0cyh2LCBrKTsKCQkJCQlyZXR1cm4gazsKCQkJCX0KCgkJCQl1aW50MzJfdCB4ID0gdiArIHU7CgkJCQlhc3NlcnQoKHggPj4gMSkgPj0gdSk7CgoJCQkJcHV0X2JpdHMoeCA+PiAxLCBrKTsKCQkJCXB1dF9iaXRzKHggJiAxLCAxKTsKCQkJCXJldHVybiBrICsgMTsKCQkJfQoKCQkJc3RhdGljIGlubGluZSB1aW50MzJfdCBnZXRfdHJ1bmNhdGVkX2JpbmFyeV9iaXRzKHVpbnQzMl90IHYsIHVpbnQzMl90IG4pCgkJCXsKCQkJCWFzc2VydCgobiA+PSAyKSAmJiAodiA8IG4pKTsKCgkJCQl1aW50MzJfdCBrID0gYmFzaXN1OjpmbG9vcl9sb2cyaShuKTsKCQkJCXVpbnQzMl90IHUgPSAoMSA8PCAoayArIDEpKSAtIG47CgoJCQkJaWYgKHYgPCB1KQoJCQkJCXJldHVybiBrOwoKI2lmZGVmIF9ERUJVRwoJCQkJdWludDMyX3QgeCA9IHYgKyB1OwoJCQkJYXNzZXJ0KCh4ID4+IDEpID49IHUpOwojZW5kaWYKCgkJCQlyZXR1cm4gayArIDE7CgkJCX0KCgkJCWlubGluZSB1aW50MzJfdCBwdXRfcmljZSh1aW50MzJfdCB2LCB1aW50MzJfdCBtKQoJCQl7CgkJCQlhc3NlcnQobSk7CgoJCQkJdWludDMyX3QgcSA9IHYgPj4gbSwgciA9IHYgJiAoKDEgPDwgbSkgLSAxKTsKCgkJCQkvLyByaWNlIGNvZGluZyBzYW5pdHkgY2hlY2sKCQkJCWFzc2VydChxIDw9IDY0KTsKCgkJCQl1aW50MzJfdCB0b3RhbF9iaXRzID0gcTsKCgkJCQkvLyBUT0RPOiBwdXRfYml0cyB0aGUgcGF0dGVybiBpbnZlcnRlZCBpbiBiaXQgb3JkZXIKCQkJCXdoaWxlIChxKQoJCQkJewoJCQkJCXB1dF9iaXQoMSk7CgkJCQkJcS0tOwoJCQkJfQoKCQkJCXB1dF9iaXQoMCk7CgoJCQkJcHV0X2JpdHMociwgbSk7CgoJCQkJdG90YWxfYml0cyArPSAobSArIDEpOwoKCQkJCXJldHVybiB0b3RhbF9iaXRzOwoJCQl9CgoJCQlzdGF0aWMgaW5saW5lIHVpbnQzMl90IGdldF9yaWNlX3ByaWNlKHVpbnQzMl90IHYsIHVpbnQzMl90IG0pCgkJCXsKCQkJCWFzc2VydChtKTsKCgkJCQl1aW50MzJfdCBxID0gdiA+PiBtOwoKCQkJCS8vIHJpY2UgY29kaW5nIHNhbml0eSBjaGVjawoJCQkJYXNzZXJ0KHEgPD0gNjQpOwoKCQkJCXVpbnQzMl90IHRvdGFsX2JpdHMgPSBxICsgMSArIG07CgoJCQkJcmV0dXJuIHRvdGFsX2JpdHM7CgkJCX0KCgkJCWlubGluZSB2b2lkIHB1dF9nYW1tYSh1aW50MzJfdCBuLCBhcml0aF9nYW1tYV9jb250ZXh0cyYgY3R4cykKCQkJewoJCQkJYXNzZXJ0KG4pOwoJCQkJaWYgKCFuKQoJCQkJCXJldHVybjsKCgkJCQljb25zdCBpbnQgayA9IGJhc2lzdTo6Zmxvb3JfbG9nMmkobik7CgkJCQlpZiAoayA+IDE2KQoJCQkJewoJCQkJCWFzc2VydCgwKTsKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJLy8gcHJlZml4OiBrIHRpbWVzICcxJyB0aGVuIGEgJzAnCgkJCQlmb3IgKGludCBpID0gMDsgaSA8IGs7ICsraSkKCQkJCQllbmNvZGUoMSwgY3R4cy5tX2N0eF9wcmVmaXhbYmFzaXN1OjptaW5pbXVtPGludD4oaSwgY0FSSVRIX0dBTU1BX01BWF9QUkVGSVhfQ1RYIC0gMSldKTsKCgkJCQllbmNvZGUoMCwgY3R4cy5tX2N0eF9wcmVmaXhbYmFzaXN1OjptaW5pbXVtKGssIGNBUklUSF9HQU1NQV9NQVhfUFJFRklYX0NUWCAtIDEpXSk7CgoJCQkJLy8gc3VmZml4OiB0aGUgayBsb3cgYml0cyBvZiBuCgkJCQlmb3IgKGludCBpID0gayAtIDE7IGkgPj0gMDsgLS1pKQoJCQkJewoJCQkJCXVpbnQzMl90IGJpdCA9IChuID4+IGkpICYgMXU7CgkJCQkJZW5jb2RlKGJpdCwgY3R4cy5tX2N0eF90YWlsW2Jhc2lzdTo6bWluaW11bTxpbnQ+KGksIGNBUklUSF9HQU1NQV9NQVhfVEFJTF9DVFggLSAxKV0pOwoJCQkJfQoJCQl9CgoJCQlpbmxpbmUgZmxvYXQgcHV0X2dhbW1hX2FuZF9yZXR1cm5fcHJpY2UodWludDMyX3QgbiwgYXJpdGhfZ2FtbWFfY29udGV4dHMmIGN0eHMpCgkJCXsKCQkJCWFzc2VydChuKTsKCQkJCWlmICghbikKCQkJCQlyZXR1cm4gMC4wZjsKCgkJCQljb25zdCBpbnQgayA9IGJhc2lzdTo6Zmxvb3JfbG9nMmkobik7CgkJCQlpZiAoayA+IDE2KQoJCQkJewoJCQkJCWFzc2VydCgwKTsKCQkJCQlyZXR1cm4gMC4wZjsKCQkJCX0KCgkJCQlmbG9hdCB0b3RhbF9wcmljZSA9IDAuMGY7CgoJCQkJLy8gcHJlZml4OiBrIHRpbWVzICcxJyB0aGVuIGEgJzAnCgkJCQlmb3IgKGludCBpID0gMDsgaSA8IGs7ICsraSkKCQkJCXsKCQkJCQl0b3RhbF9wcmljZSArPSBjdHhzLm1fY3R4X3ByZWZpeFtiYXNpc3U6Om1pbmltdW08aW50PihpLCBjQVJJVEhfR0FNTUFfTUFYX1BSRUZJWF9DVFggLSAxKV0uZ2V0X3ByaWNlKDEpOwoJCQkJCWVuY29kZSgxLCBjdHhzLm1fY3R4X3ByZWZpeFtiYXNpc3U6Om1pbmltdW08aW50PihpLCBjQVJJVEhfR0FNTUFfTUFYX1BSRUZJWF9DVFggLSAxKV0pOwoJCQkJfQoKCQkJCXRvdGFsX3ByaWNlICs9IGN0eHMubV9jdHhfcHJlZml4W2Jhc2lzdTo6bWluaW11bShrLCBjQVJJVEhfR0FNTUFfTUFYX1BSRUZJWF9DVFggLSAxKV0uZ2V0X3ByaWNlKDApOwoJCQkJZW5jb2RlKDAsIGN0eHMubV9jdHhfcHJlZml4W2Jhc2lzdTo6bWluaW11bShrLCBjQVJJVEhfR0FNTUFfTUFYX1BSRUZJWF9DVFggLSAxKV0pOwoKCQkJCS8vIHN1ZmZpeDogdGhlIGsgbG93IGJpdHMgb2YgbgoJCQkJZm9yIChpbnQgaSA9IGsgLSAxOyBpID49IDA7IC0taSkKCQkJCXsKCQkJCQl1aW50MzJfdCBiaXQgPSAobiA+PiBpKSAmIDF1OwoJCQkJCXRvdGFsX3ByaWNlICs9IGN0eHMubV9jdHhfdGFpbFtiYXNpc3U6Om1pbmltdW08aW50PihpLCBjQVJJVEhfR0FNTUFfTUFYX1RBSUxfQ1RYIC0gMSldLmdldF9wcmljZShiaXQpOwoJCQkJCWVuY29kZShiaXQsIGN0eHMubV9jdHhfdGFpbFtiYXNpc3U6Om1pbmltdW08aW50PihpLCBjQVJJVEhfR0FNTUFfTUFYX1RBSUxfQ1RYIC0gMSldKTsKCQkJCX0KCgkJCQlyZXR1cm4gdG90YWxfcHJpY2U7CgkJCX0KCgkJCS8vIHByZWRpY2VkIHByaWNlLCB3b24ndCBiZSBhY2N1cmF0ZSBpZiBhIGJpbmFyeSBhcml0aCBtb2RlbCBkZWNpZGVzIHRvIHVwZGF0ZSBpbiBiZXR3ZWVuCgkJCWlubGluZSBmbG9hdCBnZXRfZ2FtbWFfcHJpY2UodWludDMyX3QgbiwgY29uc3QgYXJpdGhfZ2FtbWFfY29udGV4dHMmIGN0eHMpCgkJCXsKCQkJCWFzc2VydChuKTsKCQkJCWlmICghbikKCQkJCQlyZXR1cm4gMC4wZjsKCgkJCQljb25zdCBpbnQgayA9IGJhc2lzdTo6Zmxvb3JfbG9nMmkobik7CgkJCQlpZiAoayA+IDE2KQoJCQkJewoJCQkJCWFzc2VydCgwKTsKCQkJCQlyZXR1cm4gMC4wZjsKCQkJCX0KCgkJCQlmbG9hdCB0b3RhbF9wcmljZSA9IDAuMGY7CgoJCQkJLy8gcHJlZml4OiBrIHRpbWVzICcxJyB0aGVuIGEgJzAnCgkJCQlmb3IgKGludCBpID0gMDsgaSA8IGs7ICsraSkKCQkJCQl0b3RhbF9wcmljZSArPSBjdHhzLm1fY3R4X3ByZWZpeFtiYXNpc3U6Om1pbmltdW08aW50PihpLCBjQVJJVEhfR0FNTUFfTUFYX1BSRUZJWF9DVFggLSAxKV0uZ2V0X3ByaWNlKDEpOwoKCQkJCXRvdGFsX3ByaWNlICs9IGN0eHMubV9jdHhfcHJlZml4W2Jhc2lzdTo6bWluaW11bShrLCBjQVJJVEhfR0FNTUFfTUFYX1BSRUZJWF9DVFggLSAxKV0uZ2V0X3ByaWNlKDApOwoKCQkJCS8vIHN1ZmZpeDogdGhlIGsgbG93IGJpdHMgb2YgbgoJCQkJZm9yIChpbnQgaSA9IGsgLSAxOyBpID49IDA7IC0taSkKCQkJCXsKCQkJCQl1aW50MzJfdCBiaXQgPSAobiA+PiBpKSAmIDF1OwoJCQkJCXRvdGFsX3ByaWNlICs9IGN0eHMubV9jdHhfdGFpbFtiYXNpc3U6Om1pbmltdW08aW50PihpLCBjQVJJVEhfR0FNTUFfTUFYX1RBSUxfQ1RYIC0gMSldLmdldF9wcmljZShiaXQpOwoJCQkJfQoKCQkJCXJldHVybiB0b3RhbF9wcmljZTsKCQkJfQoKCQkJdm9pZCBlbmNvZGUodWludDMyX3QgYml0LCBhcml0aF9iaXRfbW9kZWwmIGRtKQoJCQl7CgkJCQl1aW50MzJfdCB4ID0gZG0ubV9iaXQwX3Byb2IgKiAobV9sZW5ndGggPj4gQk1MZW5TaGlmdCk7CgoJCQkJaWYgKCFiaXQpCgkJCQl7CgkJCQkJbV9sZW5ndGggPSB4OwoJCQkJCSsrZG0ubV9iaXQwX2NvdW50OwoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCWNvbnN0IHVpbnQzMl90IG9yaWdfYmFzZSA9IG1fYmFzZTsKCQkJCQltX2Jhc2UgKz0geDsKCQkJCQltX2xlbmd0aCAtPSB4OwoKCQkJCQlpZiAob3JpZ19iYXNlID4gbV9iYXNlKQoJCQkJCQlwcm9wX2NhcnJ5KCk7CgkJCQl9CgkJCQkrK2RtLm1fYml0X2NvdW50OwoKCQkJCWlmIChtX2xlbmd0aCA8IEFyaXRoTWluTGVuKQoJCQkJCXJlbm9ybSgpOwoKCQkJCWlmICgtLWRtLm1fYml0c191bnRpbF91cGRhdGUgPD0gMCkKCQkJCQlkbS51cGRhdGUoKTsKCQkJfQoKCQkJZmxvYXQgZW5jb2RlX2FuZF9yZXR1cm5fcHJpY2UodWludDMyX3QgYml0LCBhcml0aF9iaXRfbW9kZWwmIGRtKQoJCQl7CgkJCQljb25zdCBmbG9hdCBwcmljZSA9IGRtLmdldF9wcmljZShiaXQpOwoJCQkJZW5jb2RlKGJpdCwgZG0pOwoJCQkJcmV0dXJuIHByaWNlOwoJCQl9CgoJCQl2b2lkIGVuY29kZSh1aW50MzJfdCBzeW0sIGFyaXRoX2RhdGFfbW9kZWwmIGRtKQoJCQl7CgkJCQlhc3NlcnQoc3ltIDwgZG0ubV9udW1fZGF0YV9zeW1zKTsKCgkJCQljb25zdCB1aW50MzJfdCBvcmlnX2Jhc2UgPSBtX2Jhc2U7CgoJCQkJaWYgKHN5bSA9PSBkbS5nZXRfbGFzdF9zeW1faW5kZXgoKSkKCQkJCXsKCQkJCQl1aW50MzJfdCB4ID0gZG0ubV9jdW1fc3ltX2ZyZXFzW3N5bV0gKiAobV9sZW5ndGggPj4gRE1MZW5TaGlmdCk7CgkJCQkJbV9iYXNlICs9IHg7CgkJCQkJbV9sZW5ndGggLT0geDsKCQkJCX0KCQkJCWVsc2UKCQkJCXsKCQkJCQltX2xlbmd0aCA+Pj0gRE1MZW5TaGlmdDsKCQkJCQl1aW50MzJfdCB4ID0gZG0ubV9jdW1fc3ltX2ZyZXFzW3N5bV0gKiBtX2xlbmd0aDsKCQkJCQltX2Jhc2UgKz0geDsKCQkJCQltX2xlbmd0aCA9IGRtLm1fY3VtX3N5bV9mcmVxc1tzeW0gKyAxXSAqIG1fbGVuZ3RoIC0geDsKCQkJCX0KCgkJCQlpZiAob3JpZ19iYXNlID4gbV9iYXNlKQoJCQkJCXByb3BfY2FycnkoKTsKCgkJCQlpZiAobV9sZW5ndGggPCBBcml0aE1pbkxlbikKCQkJCQlyZW5vcm0oKTsKCgkJCQkrK2RtLm1fc3ltX2ZyZXFzW3N5bV07CgkJCQkrK2RtLm1fdG90YWxfc3ltX2ZyZXE7CgoJCQkJaWYgKC0tZG0ubV9udW1fc3ltc191bnRpbF9uZXh0X3VwZGF0ZSA8PSAwKQoJCQkJCWRtLnVwZGF0ZSh0cnVlKTsKCQkJfQoKCQkJZmxvYXQgZW5jb2RlX2FuZF9yZXR1cm5fcHJpY2UodWludDMyX3Qgc3ltLCBhcml0aF9kYXRhX21vZGVsJiBkbSkKCQkJewoJCQkJY29uc3QgZmxvYXQgcHJpY2UgPSBkbS5nZXRfcHJpY2Uoc3ltKTsKCQkJCWVuY29kZShzeW0sIGRtKTsKCQkJCXJldHVybiBwcmljZTsKCQkJfQoKCQkJdm9pZCBmbHVzaCgpCgkJCXsKCQkJCWNvbnN0IHVpbnQzMl90IG9yaWdfYmFzZSA9IG1fYmFzZTsKCgkJCQlpZiAobV9sZW5ndGggPD0gKDIgKiBBcml0aE1pbkxlbikpCgkJCQl7CgkJCQkJbV9iYXNlICs9IEFyaXRoTWluTGVuID4+IDE7CgkJCQkJbV9sZW5ndGggPSBBcml0aE1pbkxlbiA+PiA5OwoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCW1fYmFzZSArPSBBcml0aE1pbkxlbjsKCQkJCQltX2xlbmd0aCA9IEFyaXRoTWluTGVuID4+IDE7CgkJCQl9CgoJCQkJaWYgKG9yaWdfYmFzZSA+IG1fYmFzZSkKCQkJCQlwcm9wX2NhcnJ5KCk7CgoJCQkJcmVub3JtKCk7CgoJCQkJLy8gUGFkIG91dHB1dCB0byBtaW4gNSBieXRlcyAtIHF1aXRlIGNvbnNlcnZhdGl2ZTsgd2UncmUgdHlwaWNhbGx5IGNvbXByZXNzaW5nIGxhcmdlIHN0cmVhbXMgc28gdGhlIG92ZXJoZWFkIHNob3VsZG4ndCBtYXR0ZXIuCgkJCQlpZiAobV9kYXRhX2J1Zi5zaXplKCkgPCBBcml0aE1pbkV4cGVjdGVkRGF0YUJ1ZlNpemUpCgkJCQkJbV9kYXRhX2J1Zi5yZXNpemUoQXJpdGhNaW5FeHBlY3RlZERhdGFCdWZTaXplKTsKCQkJfQoKCQkJYmFzaXN1Ojp1aW50OF92ZWMmIGdldF9kYXRhX2J1ZigpIHsgcmV0dXJuIG1fZGF0YV9idWY7IH0KCQkJY29uc3QgYmFzaXN1Ojp1aW50OF92ZWMmIGdldF9kYXRhX2J1ZigpIGNvbnN0IHsgcmV0dXJuIG1fZGF0YV9idWY7IH0KCgkJcHJpdmF0ZToKCQkJYmFzaXN1Ojp1aW50OF92ZWMgbV9kYXRhX2J1ZjsKCQkJdWludDMyX3QgbV9iYXNlLCBtX2xlbmd0aDsKCgkJCWlubGluZSB2b2lkIHByb3BfY2FycnkoKQoJCQl7CgkJCQlpbnQ2NF90IG9mcyA9IG1fZGF0YV9idWYuc2l6ZSgpIC0gMTsKCgkJCQlmb3IgKDsgKG9mcyA+PSAwKSAmJiAobV9kYXRhX2J1Zlsoc2l6ZV90KW9mc10gPT0gMHhGRik7IC0tb2ZzKQoJCQkJCW1fZGF0YV9idWZbKHNpemVfdClvZnNdID0gMDsKCgkJCQlpZiAob2ZzID49IDApCgkJCQkJKyttX2RhdGFfYnVmWyhzaXplX3Qpb2ZzXTsKCQkJfQoKCQkJaW5saW5lIHZvaWQgcmVub3JtKCkKCQkJewoJCQkJYXNzZXJ0KG1fbGVuZ3RoIDwgQXJpdGhNaW5MZW4pOwoJCQkJZG8KCQkJCXsKCQkJCQltX2RhdGFfYnVmLnB1c2hfYmFjaygodWludDhfdCkobV9iYXNlID4+IDI0dSkpOwoJCQkJCW1fYmFzZSA8PD0gOHU7CgkJCQkJbV9sZW5ndGggPDw9IDh1OwoJCQkJfSB3aGlsZSAobV9sZW5ndGggPCBBcml0aE1pbkxlbik7CgkJCX0KCQl9OwoKCQljbGFzcyBhcml0aF9kZWMKCQl7CgkJcHVibGljOgoJCQlhcml0aF9kZWMoKQoJCQl7CgkJCQljbGVhcigpOwoJCQl9CgoJCQl2b2lkIGNsZWFyKCkKCQkJewoJCQkJbV9wRGF0YV9idWYgPSBudWxscHRyOwoJCQkJbV9wRGF0YV9idWZfbGFzdF9ieXRlID0gbnVsbHB0cjsKCQkJCW1fcERhdGFfYnVmX2N1ciA9IG51bGxwdHI7CgkJCQltX2RhdGFfYnVmX3NpemUgPSAwOwoKCQkJCW1fdmFsdWUgPSAwOwoJCQkJbV9sZW5ndGggPSAwOwoJCQl9CgoJCQlib29sIGluaXQoY29uc3QgdWludDhfdCogcEJ1Ziwgc2l6ZV90IGJ1Zl9zaXplKQoJCQl7CgkJCQlpZiAoYnVmX3NpemUgPCBBcml0aE1pbkV4cGVjdGVkRGF0YUJ1ZlNpemUpCgkJCQl7CgkJCQkJYXNzZXJ0KDApOwoJCQkJCXJldHVybiBmYWxzZTsKCQkJCX0KCgkJCQltX3BEYXRhX2J1ZiA9IHBCdWY7CgkJCQltX3BEYXRhX2J1Zl9sYXN0X2J5dGUgPSBwQnVmICsgYnVmX3NpemUgLSAxOwoJCQkJbV9wRGF0YV9idWZfY3VyID0gbV9wRGF0YV9idWYgKyA0OwoJCQkJbV9kYXRhX2J1Zl9zaXplID0gYnVmX3NpemU7CgoJCQkJbV92YWx1ZSA9ICgodWludDMyX3QpKHBCdWZbMF0pIDw8IDI0dSkgfCAoKHVpbnQzMl90KShwQnVmWzFdKSA8PCAxNnUpIHwgKCh1aW50MzJfdCkocEJ1ZlsyXSkgPDwgOHUpIHwgKHVpbnQzMl90KShwQnVmWzNdKTsKCQkJCW1fbGVuZ3RoID0gQXJpdGhNYXhMZW47CgoJCQkJLy8gQ2hlY2sgZm9yIHRoZSA4LWJpdCBtYXJrZXIgd2UgYWx3YXlzIHBsYWNlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmVhbS4KCQkJCS8vdWludDMyX3QgbWFya2VyID0gZ2V0X2JpdHMoOCk7CgkJCQkvL2lmIChtYXJrZXIgIT0gMHgxKQoJCQkJLy8JcmV0dXJuIGZhbHNlOwoKCQkJCXJldHVybiB0cnVlOwoJCQl9CgoJCQl1aW50MzJfdCBnZXRfYml0KCkKCQkJewoJCQkJYXNzZXJ0KG1fZGF0YV9idWZfc2l6ZSk7CgoJCQkJbV9sZW5ndGggPj49IDE7CgoJCQkJdWludDMyX3QgYml0ID0gKG1fdmFsdWUgPj0gbV9sZW5ndGgpOwoKCQkJCWlmIChiaXQpCgkJCQkJbV92YWx1ZSAtPSBtX2xlbmd0aDsKCgkJCQlpZiAobV9sZW5ndGggPCBBcml0aE1pbkxlbikKCQkJCQlyZW5vcm0oKTsKCgkJCQlyZXR1cm4gYml0OwoJCQl9CgoJCQllbnVtIHsgY01heEdldEJpdHNMZW4gPSAyMCB9OwoKCQkJdWludDMyX3QgZ2V0X2JpdHModWludDMyX3QgbnVtX2JpdHMpCgkJCXsKCQkJCWFzc2VydChtX2RhdGFfYnVmX3NpemUpOwoKCQkJCWlmICgobnVtX2JpdHMgPCAxKSB8fCAobnVtX2JpdHMgPiBjTWF4R2V0Qml0c0xlbikpCgkJCQl7CgkJCQkJYXNzZXJ0KDApOwoJCQkJCXJldHVybiAwOwoJCQkJfQoKCQkJCW1fbGVuZ3RoID4+PSBudW1fYml0czsKCQkJCWFzc2VydChtX2xlbmd0aCk7CgoJCQkJY29uc3QgdWludDMyX3QgdiA9IG1fdmFsdWUgLyBtX2xlbmd0aDsKCgkJCQltX3ZhbHVlIC09IG1fbGVuZ3RoICogdjsKCgkJCQlpZiAobV9sZW5ndGggPCBBcml0aE1pbkxlbikKCQkJCQlyZW5vcm0oKTsKCgkJCQlyZXR1cm4gdjsKCQkJfQoKCQkJdWludDMyX3QgZGVjb2RlX3RydW5jYXRlZF9iaW5hcnkodWludDMyX3QgbikKCQkJewoJCQkJYXNzZXJ0KG4gPj0gMik7CgoJCQkJY29uc3QgdWludDMyX3QgayA9IGJhc2lzdTo6Zmxvb3JfbG9nMmkobik7CgkJCQljb25zdCB1aW50MzJfdCB1ID0gKDEgPDwgKGsgKyAxKSkgLSBuOwoKCQkJCXVpbnQzMl90IHJlc3VsdCA9IGdldF9iaXRzKGspOwoKCQkJCWlmIChyZXN1bHQgPj0gdSkKCQkJCQlyZXN1bHQgPSAoKHJlc3VsdCA8PCAxKSB8IGdldF9iaXRzKDEpKSAtIHU7CgoJCQkJcmV0dXJuIHJlc3VsdDsKCQkJfQoKCQkJdWludDMyX3QgZGVjb2RlX3JpY2UodWludDMyX3QgbSkKCQkJewoJCQkJYXNzZXJ0KG0pOwoKCQkJCXVpbnQzMl90IHEgPSAwOwoJCQkJZm9yICg7OykKCQkJCXsKCQkJCQl1aW50MzJfdCBrID0gZ2V0X2JpdCgpOwoJCQkJCWlmICghaykKCQkJCQkJYnJlYWs7CgoJCQkJCXErKzsKCQkJCQlpZiAocSA+IDY0KQoJCQkJCXsKCQkJCQkJYXNzZXJ0KDApOwoJCQkJCQlyZXR1cm4gMDsKCQkJCQl9CgkJCQl9CgoJCQkJcmV0dXJuIChxIDw8IG0pICsgZ2V0X2JpdHMobSk7CgkJCX0KCgkJCXVpbnQzMl90IGRlY29kZV9iaXQoYXJpdGhfYml0X21vZGVsJiBkbSkKCQkJewoJCQkJYXNzZXJ0KG1fZGF0YV9idWZfc2l6ZSk7CgoJCQkJdWludDMyX3QgeCA9IGRtLm1fYml0MF9wcm9iICogKG1fbGVuZ3RoID4+IEJNTGVuU2hpZnQpOwoJCQkJdWludDMyX3QgYml0ID0gKG1fdmFsdWUgPj0geCk7CgoJCQkJaWYgKGJpdCA9PSAwKQoJCQkJewoJCQkJCW1fbGVuZ3RoID0geDsKCQkJCQkrK2RtLm1fYml0MF9jb3VudDsKCQkJCX0KCQkJCWVsc2UKCQkJCXsKCQkJCQltX3ZhbHVlIC09IHg7CgkJCQkJbV9sZW5ndGggLT0geDsKCQkJCX0KCQkJCSsrZG0ubV9iaXRfY291bnQ7CgoJCQkJaWYgKG1fbGVuZ3RoIDwgQXJpdGhNaW5MZW4pCgkJCQkJcmVub3JtKCk7CgoJCQkJaWYgKC0tZG0ubV9iaXRzX3VudGlsX3VwZGF0ZSA8PSAwKQoJCQkJCWRtLnVwZGF0ZSgpOwoKCQkJCXJldHVybiBiaXQ7CgkJCX0KCgkJCWlubGluZSB1aW50MzJfdCBkZWNvZGVfZ2FtbWEoYXJpdGhfZ2FtbWFfY29udGV4dHMmIGN0eHMpCgkJCXsKCQkJCWludCBrID0gMDsKCQkJCXdoaWxlIChkZWNvZGVfYml0KGN0eHMubV9jdHhfcHJlZml4W2Jhc2lzdTo6bWluaW11bTxpbnQ+KGssIGNBUklUSF9HQU1NQV9NQVhfUFJFRklYX0NUWCAtIDEpXSkpCgkJCQl7CgkJCQkJKytrOwoKCQkJCQlpZiAoayA+IDE2KQoJCQkJCXsKCQkJCQkJLy8gc29tZXRoaW5nIGlzIHZlcnkgd3JvbmcKCQkJCQkJYXNzZXJ0KDApOwoJCQkJCQlyZXR1cm4gMDsKCQkJCQl9CgkJCQl9CgoJCQkJaW50IG4gPSAxIDw8IGs7CgkJCQlmb3IgKGludCBpID0gayAtIDE7IGkgPj0gMDsgLS1pKQoJCQkJewoJCQkJCXVpbnQzMl90IGJpdCA9IGRlY29kZV9iaXQoY3R4cy5tX2N0eF90YWlsW2Jhc2lzdTo6bWluaW11bTxpbnQ+KGksIGNBUklUSF9HQU1NQV9NQVhfVEFJTF9DVFggLSAxKV0pOwoJCQkJCW4gfD0gKGJpdCA8PCBpKTsKCQkJCX0KCgkJCQlyZXR1cm4gbjsKCQkJfQoKCQkJdWludDMyX3QgZGVjb2RlX3N5bShhcml0aF9kYXRhX21vZGVsJiBkbSkKCQkJewoJCQkJYXNzZXJ0KG1fZGF0YV9idWZfc2l6ZSk7CgkJCQlhc3NlcnQoZG0ubV9udW1fZGF0YV9zeW1zKTsKCgkJCQl1aW50MzJfdCB4ID0gMCwgeSA9IG1fbGVuZ3RoOwoKCQkJCW1fbGVuZ3RoID4+PSBETUxlblNoaWZ0OwoKCQkJCXVpbnQzMl90IGxvd19pZHggPSAwLCBoaV9pZHggPSBkbS5tX251bV9kYXRhX3N5bXM7CgkJCQl1aW50MzJfdCBtaWRfaWR4ID0gaGlfaWR4ID4+IDE7CgoJCQkJZG8KCQkJCXsKCQkJCQl1aW50MzJfdCB6ID0gbV9sZW5ndGggKiBkbS5tX2N1bV9zeW1fZnJlcXNbbWlkX2lkeF07CgoJCQkJCWlmICh6ID4gbV92YWx1ZSkKCQkJCQl7CgkJCQkJCWhpX2lkeCA9IG1pZF9pZHg7CgkJCQkJCXkgPSB6OwoJCQkJCX0KCQkJCQllbHNlCgkJCQkJewoJCQkJCQlsb3dfaWR4ID0gbWlkX2lkeDsKCQkJCQkJeCA9IHo7CgkJCQkJfQoJCQkJCW1pZF9pZHggPSAobG93X2lkeCArIGhpX2lkeCkgPj4gMTsKCgkJCQl9IHdoaWxlIChtaWRfaWR4ICE9IGxvd19pZHgpOwoKCQkJCW1fdmFsdWUgLT0geDsKCQkJCW1fbGVuZ3RoID0geSAtIHg7CgoJCQkJaWYgKG1fbGVuZ3RoIDwgQXJpdGhNaW5MZW4pCgkJCQkJcmVub3JtKCk7CgoJCQkJKytkbS5tX3N5bV9mcmVxc1tsb3dfaWR4XTsKCQkJCSsrZG0ubV90b3RhbF9zeW1fZnJlcTsKCgkJCQlpZiAoLS1kbS5tX251bV9zeW1zX3VudGlsX25leHRfdXBkYXRlIDw9IDApCgkJCQkJZG0udXBkYXRlKGZhbHNlKTsKCgkJCQlyZXR1cm4gbG93X2lkeDsKCQkJfQoKCQlwcml2YXRlOgoJCQljb25zdCB1aW50OF90KiBtX3BEYXRhX2J1ZjsKCQkJY29uc3QgdWludDhfdCogbV9wRGF0YV9idWZfbGFzdF9ieXRlOwoJCQljb25zdCB1aW50OF90KiBtX3BEYXRhX2J1Zl9jdXI7CgkJCXNpemVfdCBtX2RhdGFfYnVmX3NpemU7CgoJCQl1aW50MzJfdCBtX3ZhbHVlLCBtX2xlbmd0aDsKCgkJCWlubGluZSB2b2lkIHJlbm9ybSgpCgkJCXsKCQkJCWRvCgkJCQl7CgkJCQkJY29uc3QgdWludDMyX3QgbmV4dF9ieXRlID0gKG1fcERhdGFfYnVmX2N1ciA+IG1fcERhdGFfYnVmX2xhc3RfYnl0ZSkgPyAwIDogKm1fcERhdGFfYnVmX2N1cisrOwoKCQkJCQltX3ZhbHVlID0gKG1fdmFsdWUgPDwgOHUpIHwgbmV4dF9ieXRlOwoKCQkJCX0gd2hpbGUgKChtX2xlbmd0aCA8PD0gOHUpIDwgQXJpdGhNaW5MZW4pOwoJCQl9CgkJfTsKCgl9IC8vIG5hbWVzcGFjZSBhcml0aAojZW5kaWYgLy8gQkFTSVNEX1NVUFBPUlRfWFVBU1RDCgojaWYgQkFTSVNEX1NVUFBPUlRfWFVBU1RDCgluYW1lc3BhY2UgYmM3dQoJewoJCWludCBkZXRlcm1pbmVfYmM3X21vZGUoY29uc3Qgdm9pZCogcEJsb2NrKTsKCQlpbnQgZGV0ZXJtaW5lX2JjN19tb2RlXzRfaW5kZXhfbW9kZShjb25zdCB2b2lkKiBwQmxvY2spOwoJCWludCBkZXRlcm1pbmVfYmM3X21vZGVfNF9vcl81X3JvdGF0aW9uKGNvbnN0IHZvaWQqIHBCbG9jayk7CgkJYm9vbCB1bnBhY2tfYmM3X21vZGU2KGNvbnN0IHZvaWQqIHBCbG9ja19iaXRzLCBjb2xvcl9yZ2JhKiBwUGl4ZWxzKTsKCQlib29sIHVucGFja19iYzcoY29uc3Qgdm9pZCogcEJsb2NrLCBjb2xvcl9yZ2JhKiBwUGl4ZWxzKTsKCX0gLy8gbmFtZXNwYWNlIGJjN3UKCgluYW1lc3BhY2UgYmM3ZiAKCXsKCQllbnVtCgkJewoJCQkvLyBMb3ctbGV2ZWwgQkM3IGVuY29kZXIgY29uZmlndXJhdGlvbiBmbGFncy4KCQkJY1BhY2tCQzdGbGFnVXNlMlN1YnNldHNSR0IgPSAxLCAvLyB1c2UgbW9kZSAxLzMgZm9yIFJHQiBibG9ja3MKCQkJY1BhY2tCQzdGbGFnVXNlMlN1YnNldHNSR0JBID0gMiwgLy8gdXNlIG1vZGUgNyBmb3IgUkdCQSBibG9ja3MKCgkJCWNQYWNrQkM3RmxhZ1VzZTNTdWJzZXRzUkdCID0gNCwgLy8gYWxzbyB1c2UgbW9kZSAwLzIsIGNQYWNrQkM3RmxhZ1VzZTJTdWJzZXRzUkdCIE1VU1QgYmUgZW5hYmxlZCB0b28KCgkJCWNQYWNrQkM3RmxhZ1VzZUR1YWxQbGFuZVJHQiA9IDgsIC8vIGVuYWJsZSBtb2RlIDQvNSB1c2FnZSBmb3IgUkdCIGJsb2NrcwoJCQljUGFja0JDN0ZsYWdVc2VEdWFsUGxhbmVSR0JBID0gMTYsIC8vIGVuYWJsZSBtb2RlIDQvNSB1c2FnZSBmb3IgUkdCQSBibG9ja3MKCgkJCWNQYWNrQkM3RmxhZ1BCaXRPcHQgPSAzMiwgLy8gZW5hYmxlIHRvIGRpc2FibGUgdXNhZ2Ugb2YgZml4ZWQgcC1iaXRzIG9uIHNvbWUgbW9kZXM7IHNsb3dlcgoJCQljUGFja0JDN0ZsYWdQQml0T3B0TW9kZTYgPSA2NCwgLy8gZW5hYmxlIHRvIGRpc2FibGUgdXNhZ2Ugb2YgZml4ZWQgcC1iaXRzIG9uIG1vZGUgNiwgYWxwaGEgb24gZnVsbHkgb3BhcXVlIGJsb2NrcyBtYXkgYmUgMjU0IGhvd2V2ZXI7IHNsb3dlcgoKCQkJY1BhY2tCQzdGbGFnVXNlVHJpdmlhbE1vZGU2ID0gMTI4LCAvLyBlbmFibGUgdHJpdmlhbCBmYXN0IG1vZGUgNiBlbmNvZGVyIG9uIGJsb2NrcyB3aXRoIHZlcnkgbG93IHZhcmlhbmNlcyAoaGlnaGx5IHJlY29tbWVuZGVkKQoKCQkJY1BhY2tCQzdGbGFnUGFydGlhbGx5QW5hbHl0aWNhbFJHQiA9IDI1NiwgLy8gcGFydGlhbGx5IGFuYWx5dGljYWwgbW9kZSBmb3IgUkdCIGJsb2Nrcywgc2xvd2VyIGJ1dCBoaWdoZXIgcXVhbGl0eSwgY29tcHV0ZXMgYWN0dWFsIFNTRSdzIG9uIGNvbXBsZXggYmxvY2tzIHRvIHJlc29sdmUgd2hpY2ggbW9kZSB0byB1c2UgdnMuIHByZWRpY3Rpb25zCgkJCWNQYWNrQkM3RmxhZ1BhcnRpYWxseUFuYWx5dGljYWxSR0JBID0gNTEyLCAvLyBwYXJ0aWFsbHkgYW5hbHl0aWNhbCBtb2RlIGZvciBSR0JBIGJsb2Nrcywgc2xvd2VyIGJ1dCBoaWdoZXIgcXVhbGl0eSwgY29tcHV0ZXMgYWN0dWFsIFNTRSdzIG9uIGNvbXBsZXggYmxvY2tzIHRvIHJlc29sdmUgd2hpY2ggbW9kZSB0byB1c2UgdnMuIHByZWRpY3Rpb25zCgoJCQkvLyBOb24tYW5hbHl0aWNhbCBpcyByZWFsbHkgc3RpbGwgcGFydGlhbGx5IGFuYWx5dGljYWwgb24gdGhlIG1vZGUgcGFpcnMgKDAgdnMuIDIsIDEgdnMgMywgNCB2cy4gNSkuCgkJCWNQYWNrQkM3RmxhZ05vbkFuYWx5dGljYWxSR0IgPSAxMDI0LCAvLyB2ZXJ5IHNsb3cvYnJ1dGUgZm9yY2UsIHRvdGFsbHkgYWJ1c2VzIHRoZSBlbmNvZGVyLCBNVVNUIHVzZSB3aXRoIGNQYWNrQkM3RmxhZ1BhcnRpYWxseUFuYWx5dGljYWxSR0IgZmxhZwoJCQljUGFja0JDN0ZsYWdOb25BbmFseXRpY2FsUkdCQSA9IDIwNDgsIC8vIHZlcnkgc2xvdy9icnV0ZSBmb3JjZSwgdG90YWxseSBhYnVzZXMgdGhlIGVuY29kZXIsIE1VU1QgdXNlIHdpdGggY1BhY2tCQzdGbGFnUGFydGlhbGx5QW5hbHl0aWNhbFJHQkEgZmxhZwoKCQkJLy8gRGVmYXVsdCB0byB1c2UgZmlyc3Q6CgoJCQkvLyBEZWNlbnQgYW5hbHl0aWNhbCBCQzcgZGVmYXVsdHMKCQkJY1BhY2tCQzdGbGFnRGVmYXVsdEZhc3Rlc3QgPSBjUGFja0JDN0ZsYWdVc2VUcml2aWFsTW9kZTYsIC8vIHZlcnkgd2VhayBwYXJ0aWN1bGFybHkgb24gYWxwaGEsIG1vZGUgNiBvbmx5IGZvciBSR0IvUkdCQSwgCgoJCQkvLyBNb2RlIDYgd2l0aCBwYml0cyBmb3IgUkdCLCBNb2RlcyA0LDUsNiBmb3IgYWxwaGEuCgkJCWNQYWNrQkM3RmxhZ0RlZmF1bHRGYXN0ZXIgPSBjUGFja0JDN0ZsYWdQQml0T3B0IHwgY1BhY2tCQzdGbGFnVXNlRHVhbFBsYW5lUkdCQSB8IGNQYWNrQkM3RmxhZ1VzZVRyaXZpYWxNb2RlNiwKCgkJCWNQYWNrQkM3RmxhZ0RlZmF1bHRGYXN0ID0gY1BhY2tCQzdGbGFnVXNlMlN1YnNldHNSR0IgfCBjUGFja0JDN0ZsYWdVc2UyU3Vic2V0c1JHQkEgfCBjUGFja0JDN0ZsYWdVc2VEdWFsUGxhbmVSR0JBIHwKCQkJCWNQYWNrQkM3RmxhZ1BCaXRPcHQgfCBjUGFja0JDN0ZsYWdVc2VUcml2aWFsTW9kZTYsCgoJCQljUGFja0JDN0ZsYWdEZWZhdWx0ID0gKGNQYWNrQkM3RmxhZ1VzZTJTdWJzZXRzUkdCIHwgY1BhY2tCQzdGbGFnVXNlMlN1YnNldHNSR0JBIHwgY1BhY2tCQzdGbGFnVXNlM1N1YnNldHNSR0IpIHwKCQkJCShjUGFja0JDN0ZsYWdVc2VEdWFsUGxhbmVSR0IgfCBjUGFja0JDN0ZsYWdVc2VEdWFsUGxhbmVSR0JBKSB8CgkJCQkoY1BhY2tCQzdGbGFnUEJpdE9wdCB8IGNQYWNrQkM3RmxhZ1BCaXRPcHRNb2RlNikgfAoJCQkJY1BhY2tCQzdGbGFnVXNlVHJpdmlhbE1vZGU2LAoKCQkJLy8gRGVmYXVsdCBwYXJ0aWFsbHkgYW5hbHl0aWNhbCBCQzcgZGVmYXVsdHMgKHNsb3dlcikKCQkJY1BhY2tCQzdGbGFnRGVmYXVsdFBhcnRpYWxseUFuYWx5dGljYWwgPSBjUGFja0JDN0ZsYWdEZWZhdWx0IHwgKGNQYWNrQkM3RmxhZ1BhcnRpYWxseUFuYWx5dGljYWxSR0IgfCBjUGFja0JDN0ZsYWdQYXJ0aWFsbHlBbmFseXRpY2FsUkdCQSksCgoJCQkvLyBEZWZhdWx0IG5vbi1hbmFseXRpY2FsIEJDNyBkZWZhdWx0cyAodmVyeSBzbG93KS4gSW4gcmVhbGl0eSB0aGUgZW5jb2RlciBpcyBzdGlsbCBhbmFseXRpY2FsIG9uIHRoZSBtb2RlIHBhaXJzLCBidXQgYXQgdGhlIGhpZ2hlc3QgbGV2ZWwgaXMgbm9uLWFuYWx5dGljYWwuCgkJCWNQYWNrQkM3RmxhZ0RlZmF1bHROb25BbmFseXRpY2FsID0gKGNQYWNrQkM3RmxhZ0RlZmF1bHRQYXJ0aWFsbHlBbmFseXRpY2FsIHwgKGNQYWNrQkM3RmxhZ05vbkFuYWx5dGljYWxSR0IgfCBjUGFja0JDN0ZsYWdOb25BbmFseXRpY2FsUkdCQSkpICYgfmNQYWNrQkM3RmxhZ1VzZVRyaXZpYWxNb2RlNgoJCX07CgoJCXZvaWQgaW5pdCgpOwoJCQoJCXZvaWQgZmFzdF9wYWNrX2JjN19yZ2JfYW5hbHl0aWNhbCh1aW50OF90KiBwQmxvY2ssIGNvbnN0IGNvbG9yX3JnYmEqIHBQaXhlbHMsIHVpbnQzMl90IGZsYWdzKTsKCQl1aW50MzJfdCBmYXN0X3BhY2tfYmM3X3JnYl9wYXJ0aWFsX2FuYWx5dGljYWwodWludDhfdCogcEJsb2NrLCBjb25zdCBjb2xvcl9yZ2JhKiBwUGl4ZWxzLCB1aW50MzJfdCBmbGFncyk7CgoJCXZvaWQgZmFzdF9wYWNrX2JjN19yZ2JhX2FuYWx5dGljYWwodWludDhfdCogcEJsb2NrLCBjb25zdCBjb2xvcl9yZ2JhKiBwUGl4ZWxzLCB1aW50MzJfdCBmbGFncyk7CgkJdWludDMyX3QgZmFzdF9wYWNrX2JjN19yZ2JhX3BhcnRpYWxfYW5hbHl0aWNhbCh1aW50OF90KiBwQmxvY2ssIGNvbnN0IGNvbG9yX3JnYmEqIHBQaXhlbHMsIHVpbnQzMl90IGZsYWdzKTsKCQkKCQl1aW50MzJfdCBmYXN0X3BhY2tfYmM3X2F1dG9fcmdiYSh1aW50OF90KiBwQmxvY2ssIGNvbnN0IGNvbG9yX3JnYmEqIHBQaXhlbHMsIHVpbnQzMl90IGZsYWdzKTsKCgkJdm9pZCBwcmludF9wZXJmX3N0YXRzKCk7CgojaWYgMAoJCS8vIFZlcnkgYmFzaWMgQkM3IG1vZGUgNiBvbmx5IHRvIEFTVEMuCgkJdm9pZCBmYXN0X3BhY2tfYXN0Yyh2b2lkKiBwQmxvY2ssIGNvbnN0IGNvbG9yX3JnYmEqIHBQaXhlbHMpOwojZW5kaWYKCQkKCQl1aW50MzJfdCBjYWxjX3NzZShjb25zdCB1aW50OF90KiBwQmxvY2ssIGNvbnN0IGNvbG9yX3JnYmEqIHBQaXhlbHMpOwoKCX0gLy8gbmFtZXNwYWNlIGJjN2YKCgluYW1lc3BhY2UgZXRjMWYKCXsKCQlzdHJ1Y3QgcGFja19ldGMxX3N0YXRlCgkJewoJCQl1aW50NjRfdCBtX3ByZXZfc29saWRfYmxvY2s7CgkJCS8vZGVjb2Rlcl9ldGNfYmxvY2sgbV9wcmV2X3NvbGlkX2Jsb2NrOwoKCQkJaW50IG1fcHJldl9zb2xpZF9yODsKCQkJaW50IG1fcHJldl9zb2xpZF9nODsKCQkJaW50IG1fcHJldl9zb2xpZF9iODsKCgkJCXBhY2tfZXRjMV9zdGF0ZSgpCgkJCXsKCQkJCWNsZWFyKCk7CgkJCX0KCgkJCXZvaWQgY2xlYXIoKQoJCQl7CgkJCQltX3ByZXZfc29saWRfcjggPSAtMTsKCQkJCW1fcHJldl9zb2xpZF9nOCA9IC0xOwoJCQkJbV9wcmV2X3NvbGlkX2I4ID0gLTE7CgkJCX0KCQl9OwoKCQl2b2lkIGluaXQoKTsKCgkJdm9pZCBwYWNrX2V0YzFfc29saWQodWludDhfdCogcEJsb2NrLCBjb25zdCBjb2xvcl9yZ2JhJiBjb2xvciwgcGFja19ldGMxX3N0YXRlJiBzdGF0ZSwgYm9vbCBpbml0X2ZsYWcgPSBmYWxzZSk7CgoJCXZvaWQgcGFja19ldGMxKHVpbnQ4X3QqIHBCbG9jaywgY29uc3QgY29sb3JfcmdiYSogcFBpeGVscywgcGFja19ldGMxX3N0YXRlJiBzdGF0ZSk7CgkJCgkJdm9pZCBwYWNrX2V0YzFfZ3JheXNjYWxlKHVpbnQ4X3QqIHBCbG9jaywgY29uc3QgdWludDhfdCogcFBpeGVscywgcGFja19ldGMxX3N0YXRlJiBzdGF0ZSk7CgoJfSAvLyBuYW1lc3BhY2UgZXRjMWYKI2VuZGlmIC8vIEJBU0lTRF9TVVBQT1JUX1hVQVNUQwoKCS8vIFByaXZhdGUvaW50ZXJuYWwgWFVBU1RDIExEUiB0cmFuc2NvZGluZyBoZWxwZXJzCgoJLy8gWFVBU1RDIExEUiBmb3JtYXRzIG9ubHkKCWVudW0gY2xhc3MgdHJhbnNjb2Rlcl90ZXh0dXJlX2Zvcm1hdDsKCWJsb2NrX2Zvcm1hdCB4dWFzdGNfZ2V0X2Jsb2NrX2Zvcm1hdCh0cmFuc2NvZGVyX3RleHR1cmVfZm9ybWF0IHRleF9mbXQpOwoKI2lmIEJBU0lTRF9TVVBQT1JUX1hVQVNUQwoJLy8gTG93LXF1YWxpdHksIGJ1dCBmYXN0LCBQVlJUQzEgUkdCL1JHQkEgZW5jb2Rlci4gUG93ZXIgb2YgMiB0ZXh0dXJlIGRpbWVuc2lvbnMgcmVxdWlyZWQuCgkvLyBOb3RlOiBOb3QgeWV0IHBhcnQgb2Ygb3VyIHB1YmxpYyBBUEk6IHRoaXMgQVBJIG1heSBjaGFuZ2UhIAoJdm9pZCBlbmNvZGVfcHZydGMxKAoJCWJsb2NrX2Zvcm1hdCBmbXQsIHZvaWQqIHBEc3RfYmxvY2tzLAoJCWNvbnN0IGJhc2lzdTo6dmVjdG9yMkQ8Y29sb3IzMj4mIHRlbXBfaW1hZ2UsCgkJdWludDMyX3QgZHN0X251bV9ibG9ja3NfeCwgdWludDMyX3QgZHN0X251bV9ibG9ja3NfeSwgYm9vbCBmcm9tX2FscGhhKTsKCQkKCXZvaWQgdHJhbnNjb2RlXzR4NF9ibG9jaygKCQlibG9ja19mb3JtYXQgZm10LCAvLyBkZXNpcmVkIG91dHB1dCBibG9jayBmb3JtYXQKCQl1aW50MzJfdCBibG9ja194LCB1aW50MzJfdCBibG9ja195LCAvLyA0eDQgYmxvY2sgYmVpbmcgcHJvY2Vzc2VkCgkJdm9pZCogcERzdF9ibG9ja3MsIC8vIGJhc2UgcG9pbnRlciB0byBvdXRwdXQgYnVmZmVyL2JpdG1hcAoJCXVpbnQ4X3QqIHBEc3RfYmxvY2tfdTgsIC8vIHBvaW50ZXIgdG8gb3V0cHV0IGJsb2NrL29yIGZpcnN0IHBpeGVsIHRvIHdyaXRlCgkJY29uc3QgY29sb3IzMiogYmxvY2tfcGl4ZWxzLCAvLyBwb2ludGVyIHRvIDR4NCAoMTYpIDMyYnBwIFJHQkEgcGl4ZWxzCgkJdWludDMyX3Qgb3V0cHV0X2Jsb2NrX29yX3BpeGVsX3N0cmlkZV9pbl9ieXRlcywgdWludDMyX3Qgb3V0cHV0X3Jvd19waXRjaF9pbl9ibG9ja3Nfb3JfcGl4ZWxzLCB1aW50MzJfdCBvdXRwdXRfcm93c19pbl9waXhlbHMsIC8vIG91dHB1dCBidWZmZXIgZGltZW5zaW9ucwoJCWludCBjaGFubmVsMCwgaW50IGNoYW5uZWwxLCAvLyBjaGFubmVscyB0byBwcm9jZXNzLCB1c2VkIGJ5IHNvbWUgYmxvY2sgZm9ybWF0cwoJCWJvb2wgaGlnaF9xdWFsaXR5LCBib29sIGZyb21fYWxwaGEsCS8vIEZsYWdzIHNwZWNpZmljIHRvIGNlcnRhaW4gYmxvY2sgZm9ybWF0cwoJCXVpbnQzMl90IGJjN2ZfZmxhZ3MsIC8vIFJlYWwtdGltZSBiYzdmIEJDNyBlbmNvZGVyIGZsYWdzLCBzZWUgYmM3Zjo6Y1BhY2tCQzdGbGFnRGVmYXVsdCBldGMuCgkJZXRjMWY6OnBhY2tfZXRjMV9zdGF0ZSYgZXRjMV9wYWNrX3N0YXRlLCAgLy8gZXRjMWYgdGhyZWFkIGxvY2FsIHN0YXRlCgkJaW50IGhhc19hbHBoYSA9IC0xKTsgLy8gaGFzX2FscGhhID0gLTEgdW5rbm93biwgMD1kZWZpbml0ZWx5IG5vIChhIGFsbCAyNTUncyksIDE9cG90ZW50aWFsbHkgeWVzCiNlbmRpZiAvLyBCQVNJU0RfU1VQUE9SVF9YVUFTVEMKCglzdHJ1Y3QgYmM3X21vZGVfNQoJewoJCXVuaW9uCgkJewoJCQlzdHJ1Y3QKCQkJewoJCQkJdWludDY0X3QgbV9tb2RlIDogNjsKCQkJCXVpbnQ2NF90IG1fcm90IDogMjsKCgkJCQl1aW50NjRfdCBtX3IwIDogNzsKCQkJCXVpbnQ2NF90IG1fcjEgOiA3OwoJCQkJdWludDY0X3QgbV9nMCA6IDc7CgkJCQl1aW50NjRfdCBtX2cxIDogNzsKCQkJCXVpbnQ2NF90IG1fYjAgOiA3OwoJCQkJdWludDY0X3QgbV9iMSA6IDc7CgkJCQl1aW50NjRfdCBtX2EwIDogODsKCQkJCXVpbnQ2NF90IG1fYTFfMCA6IDY7CgoJCQl9IG1fbG87CgoJCQl1aW50NjRfdCBtX2xvX2JpdHM7CgkJfTsKCgkJdW5pb24KCQl7CgkJCXN0cnVjdAoJCQl7CgkJCQl1aW50NjRfdCBtX2ExXzEgOiAyOwoKCQkJCS8vIGJpdCAyCgkJCQl1aW50NjRfdCBtX2MwMCA6IDE7CgkJCQl1aW50NjRfdCBtX2MxMCA6IDI7CgkJCQl1aW50NjRfdCBtX2MyMCA6IDI7CgkJCQl1aW50NjRfdCBtX2MzMCA6IDI7CgoJCQkJdWludDY0X3QgbV9jMDEgOiAyOwoJCQkJdWludDY0X3QgbV9jMTEgOiAyOwoJCQkJdWludDY0X3QgbV9jMjEgOiAyOwoJCQkJdWludDY0X3QgbV9jMzEgOiAyOwoKCQkJCXVpbnQ2NF90IG1fYzAyIDogMjsKCQkJCXVpbnQ2NF90IG1fYzEyIDogMjsKCQkJCXVpbnQ2NF90IG1fYzIyIDogMjsKCQkJCXVpbnQ2NF90IG1fYzMyIDogMjsKCgkJCQl1aW50NjRfdCBtX2MwMyA6IDI7CgkJCQl1aW50NjRfdCBtX2MxMyA6IDI7CgkJCQl1aW50NjRfdCBtX2MyMyA6IDI7CgkJCQl1aW50NjRfdCBtX2MzMyA6IDI7CgoJCQkJLy8gYml0IDMzCgkJCQl1aW50NjRfdCBtX2EwMCA6IDE7CgkJCQl1aW50NjRfdCBtX2ExMCA6IDI7CgkJCQl1aW50NjRfdCBtX2EyMCA6IDI7CgkJCQl1aW50NjRfdCBtX2EzMCA6IDI7CgoJCQkJdWludDY0X3QgbV9hMDEgOiAyOwoJCQkJdWludDY0X3QgbV9hMTEgOiAyOwoJCQkJdWludDY0X3QgbV9hMjEgOiAyOwoJCQkJdWludDY0X3QgbV9hMzEgOiAyOwoKCQkJCXVpbnQ2NF90IG1fYTAyIDogMjsKCQkJCXVpbnQ2NF90IG1fYTEyIDogMjsKCQkJCXVpbnQ2NF90IG1fYTIyIDogMjsKCQkJCXVpbnQ2NF90IG1fYTMyIDogMjsKCgkJCQl1aW50NjRfdCBtX2EwMyA6IDI7CgkJCQl1aW50NjRfdCBtX2ExMyA6IDI7CgkJCQl1aW50NjRfdCBtX2EyMyA6IDI7CgkJCQl1aW50NjRfdCBtX2EzMyA6IDI7CgoJCQl9IG1faGk7CgoJCQl1aW50NjRfdCBtX2hpX2JpdHM7CgkJfTsKCX07Cgp9IC8vIG5hbWVzcGFjZSBiYXNpc3QKCgoK