Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBCaXRtYXAgY29udmVyc2lvbiByb3V0aW5lcwovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gSGVydukgRHJvbG9uIChkcm9sb25AaW5mb25pZS5mcikKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCiNpbmNsdWRlICJVdGlsaXRpZXMuaCIKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBzbWFydCBjb252ZXJ0IFggdG8gUkdCRgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpGSUJJVE1BUCAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfQ29udmVydFRvUkdCRihGSUJJVE1BUCAqZGliKSB7CglGSUJJVE1BUCAqc3JjID0gTlVMTDsKCUZJQklUTUFQICpkc3QgPSBOVUxMOwoKCWlmKCFGcmVlSW1hZ2VfSGFzUGl4ZWxzKGRpYikpIHJldHVybiBOVUxMOwoKCWNvbnN0IEZSRUVfSU1BR0VfVFlQRSBzcmNfdHlwZSA9IEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoZGliKTsKCgkvLyBjaGVjayBmb3IgYWxsb3dlZCBjb252ZXJzaW9ucyAKCXN3aXRjaChzcmNfdHlwZSkgewoJCWNhc2UgRklUX0JJVE1BUDoKCQl7CgkJCS8vIGFsbG93IGNvbnZlcnNpb24gZnJvbSAyNC0gYW5kIDMyLWJpdAoJCQljb25zdCBGUkVFX0lNQUdFX0NPTE9SX1RZUEUgY29sb3JfdHlwZSA9IEZyZWVJbWFnZV9HZXRDb2xvclR5cGUoZGliKTsKCQkJaWYoKGNvbG9yX3R5cGUgIT0gRklDX1JHQikgJiYgKGNvbG9yX3R5cGUgIT0gRklDX1JHQkFMUEhBKSkgewoJCQkJc3JjID0gRnJlZUltYWdlX0NvbnZlcnRUbzI0Qml0cyhkaWIpOwoJCQkJaWYoIXNyYykgcmV0dXJuIE5VTEw7CgkJCX0gZWxzZSB7CgkJCQlzcmMgPSBkaWI7CgkJCX0KCQkJYnJlYWs7CgkJfQoJCWNhc2UgRklUX1VJTlQxNjoKCQkJLy8gYWxsb3cgY29udmVyc2lvbiBmcm9tIDE2LWJpdAoJCQlzcmMgPSBkaWI7CgkJCWJyZWFrOwoJCWNhc2UgRklUX1JHQjE2OgoJCQkvLyBhbGxvdyBjb252ZXJzaW9uIGZyb20gNDgtYml0IFJHQgoJCQlzcmMgPSBkaWI7CgkJCWJyZWFrOwoJCWNhc2UgRklUX1JHQkExNjoKCQkJLy8gYWxsb3cgY29udmVyc2lvbiBmcm9tIDY0LWJpdCBSR0JBIChpZ25vcmUgdGhlIGFscGhhIGNoYW5uZWwpCgkJCXNyYyA9IGRpYjsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfRkxPQVQ6CgkJCS8vIGFsbG93IGNvbnZlcnNpb24gZnJvbSAzMi1iaXQgZmxvYXQKCQkJc3JjID0gZGliOwoJCQlicmVhazsKCQljYXNlIEZJVF9SR0JBRjoKCQkJLy8gYWxsb3cgY29udmVyc2lvbiBmcm9tIDEyOC1iaXQgUkdCQUYKCQkJc3JjID0gZGliOwoJCQlicmVhazsKCQljYXNlIEZJVF9SR0JGOgoJCQkvLyBSR0JGIHR5cGUgOiBjbG9uZSB0aGUgc3JjCgkJCXJldHVybiBGcmVlSW1hZ2VfQ2xvbmUoZGliKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcmV0dXJuIE5VTEw7Cgl9CgoJLy8gYWxsb2NhdGUgZHN0IGltYWdlCgoJY29uc3QgdW5zaWduZWQgd2lkdGggPSBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsKCWNvbnN0IHVuc2lnbmVkIGhlaWdodCA9IEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjKTsKCglkc3QgPSBGcmVlSW1hZ2VfQWxsb2NhdGVUKEZJVF9SR0JGLCB3aWR0aCwgaGVpZ2h0KTsKCWlmKCFkc3QpIHsKCQlpZihzcmMgIT0gZGliKSB7CgkJCUZyZWVJbWFnZV9VbmxvYWQoc3JjKTsKCQl9CgkJcmV0dXJuIE5VTEw7Cgl9CgoJLy8gY29weSBtZXRhZGF0YSBmcm9tIHNyYyB0byBkc3QKCUZyZWVJbWFnZV9DbG9uZU1ldGFkYXRhKGRzdCwgc3JjKTsKCgkvLyBjb252ZXJ0IGZyb20gc3JjIHR5cGUgdG8gUkdCRgoKCWNvbnN0IHVuc2lnbmVkIHNyY19waXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChzcmMpOwoJY29uc3QgdW5zaWduZWQgZHN0X3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKGRzdCk7CgoJc3dpdGNoKHNyY190eXBlKSB7CgkJY2FzZSBGSVRfQklUTUFQOgoJCXsKCQkJLy8gY2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgcGVyIHBpeGVsICgzIGZvciAyNC1iaXQgb3IgNCBmb3IgMzItYml0KQoJCQljb25zdCB1bnNpZ25lZCBieXRlc3BwID0gRnJlZUltYWdlX0dldExpbmUoc3JjKSAvIEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoKCQkJY29uc3QgQllURSAqc3JjX2JpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoc3JjKTsKCQkJQllURSAqZHN0X2JpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoZHN0KTsKCgkJCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQljb25zdCBCWVRFICAgKnNyY19waXhlbCA9IChCWVRFKilzcmNfYml0czsKCQkJCUZJUkdCRiAqZHN0X3BpeGVsID0gKEZJUkdCRiopZHN0X2JpdHM7CgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJLy8gY29udmVydCBhbmQgc2NhbGUgdG8gdGhlIHJhbmdlIFswLi4xXQoJCQkJCWRzdF9waXhlbC0+cmVkICAgPSAoZmxvYXQpKHNyY19waXhlbFtGSV9SR0JBX1JFRF0pICAgLyAyNTUuMEY7CgkJCQkJZHN0X3BpeGVsLT5ncmVlbiA9IChmbG9hdCkoc3JjX3BpeGVsW0ZJX1JHQkFfR1JFRU5dKSAvIDI1NS4wRjsKCQkJCQlkc3RfcGl4ZWwtPmJsdWUgID0gKGZsb2F0KShzcmNfcGl4ZWxbRklfUkdCQV9CTFVFXSkgIC8gMjU1LjBGOwoKCQkJCQlzcmNfcGl4ZWwgKz0gYnl0ZXNwcDsKCQkJCQlkc3RfcGl4ZWwgKys7CgkJCQl9CgkJCQlzcmNfYml0cyArPSBzcmNfcGl0Y2g7CgkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCX0KCQl9CgkJYnJlYWs7CgoJCWNhc2UgRklUX1VJTlQxNjoKCQl7CgkJCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKHNyYyk7CgkJCUJZVEUgKmRzdF9iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKGRzdCk7CgoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJY29uc3QgV09SRCAqc3JjX3BpeGVsID0gKFdPUkQqKXNyY19iaXRzOwoJCQkJRklSR0JGICpkc3RfcGl4ZWwgPSAoRklSR0JGKilkc3RfYml0czsKCgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJLy8gY29udmVydCBhbmQgc2NhbGUgdG8gdGhlIHJhbmdlIFswLi4xXQoJCQkJCWNvbnN0IGZsb2F0IGRzdF92YWx1ZSA9IChmbG9hdClzcmNfcGl4ZWxbeF0gLyA2NTUzNS4wRjsKCQkJCQlkc3RfcGl4ZWxbeF0ucmVkICAgPSBkc3RfdmFsdWU7CgkJCQkJZHN0X3BpeGVsW3hdLmdyZWVuID0gZHN0X3ZhbHVlOwoJCQkJCWRzdF9waXhlbFt4XS5ibHVlICA9IGRzdF92YWx1ZTsKCQkJCX0KCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJfQoJCX0KCQlicmVhazsKCgkJY2FzZSBGSVRfUkdCMTY6CgkJewoJCQljb25zdCBCWVRFICpzcmNfYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhzcmMpOwoJCQlCWVRFICpkc3RfYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhkc3QpOwoKCQkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCWNvbnN0IEZJUkdCMTYgKnNyY19waXhlbCA9IChGSVJHQjE2Kikgc3JjX2JpdHM7CgkJCQlGSVJHQkYgICpkc3RfcGl4ZWwgPSAoRklSR0JGKikgIGRzdF9iaXRzOwoKCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkvLyBjb252ZXJ0IGFuZCBzY2FsZSB0byB0aGUgcmFuZ2UgWzAuLjFdCgkJCQkJZHN0X3BpeGVsW3hdLnJlZCAgID0gKGZsb2F0KShzcmNfcGl4ZWxbeF0ucmVkKSAgIC8gNjU1MzUuMEY7CgkJCQkJZHN0X3BpeGVsW3hdLmdyZWVuID0gKGZsb2F0KShzcmNfcGl4ZWxbeF0uZ3JlZW4pIC8gNjU1MzUuMEY7CgkJCQkJZHN0X3BpeGVsW3hdLmJsdWUgID0gKGZsb2F0KShzcmNfcGl4ZWxbeF0uYmx1ZSkgIC8gNjU1MzUuMEY7CgkJCQl9CgkJCQlzcmNfYml0cyArPSBzcmNfcGl0Y2g7CgkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCX0KCQl9CgkJYnJlYWs7CgoJCWNhc2UgRklUX1JHQkExNjoKCQl7CgkJCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKHNyYyk7CgkJCUJZVEUgKmRzdF9iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKGRzdCk7CgoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJY29uc3QgRklSR0JBMTYgKnNyY19waXhlbCA9IChGSVJHQkExNiopIHNyY19iaXRzOwoJCQkJRklSR0JGICAqZHN0X3BpeGVsID0gKEZJUkdCRiopICBkc3RfYml0czsKCgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJLy8gY29udmVydCBhbmQgc2NhbGUgdG8gdGhlIHJhbmdlIFswLi4xXQoJCQkJCWRzdF9waXhlbFt4XS5yZWQgICA9IChmbG9hdCkoc3JjX3BpeGVsW3hdLnJlZCkgICAvIDY1NTM1LjBGOwoJCQkJCWRzdF9waXhlbFt4XS5ncmVlbiA9IChmbG9hdCkoc3JjX3BpeGVsW3hdLmdyZWVuKSAvIDY1NTM1LjBGOwoJCQkJCWRzdF9waXhlbFt4XS5ibHVlICA9IChmbG9hdCkoc3JjX3BpeGVsW3hdLmJsdWUpICAvIDY1NTM1LjBGOwoJCQkJfQoJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJZHN0X2JpdHMgKz0gZHN0X3BpdGNoOwoJCQl9CgkJfQoJCWJyZWFrOwoKCQljYXNlIEZJVF9GTE9BVDoKCQl7CgkJCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKHNyYyk7CgkJCUJZVEUgKmRzdF9iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKGRzdCk7CgoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJY29uc3QgZmxvYXQgKnNyY19waXhlbCA9IChmbG9hdCopIHNyY19iaXRzOwoJCQkJRklSR0JGICAqZHN0X3BpeGVsID0gKEZJUkdCRiopICBkc3RfYml0czsKCgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJLy8gY29udmVydCBieSBjb3B5aW5nIGdyZXlzY2FsZSBjaGFubmVsIHRvIGVhY2ggUiwgRywgQiBjaGFubmVscwoJCQkJCS8vIGFzc3VtZSBmbG9hdCB2YWx1ZXMgYXJlIGluIFswLi4xXQoJCQkJCWNvbnN0IGZsb2F0IHZhbHVlID0gQ0xBTVAoc3JjX3BpeGVsW3hdLCAwLjBGLCAxLjBGKTsKCQkJCQlkc3RfcGl4ZWxbeF0ucmVkICAgPSB2YWx1ZTsKCQkJCQlkc3RfcGl4ZWxbeF0uZ3JlZW4gPSB2YWx1ZTsKCQkJCQlkc3RfcGl4ZWxbeF0uYmx1ZSAgPSB2YWx1ZTsKCQkJCX0KCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJfQoJCX0KCQlicmVhazsKCgkJY2FzZSBGSVRfUkdCQUY6CgkJewoJCQljb25zdCBCWVRFICpzcmNfYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhzcmMpOwoJCQlCWVRFICpkc3RfYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhkc3QpOwoKCQkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCWNvbnN0IEZJUkdCQUYgKnNyY19waXhlbCA9IChGSVJHQkFGKikgc3JjX2JpdHM7CgkJCQlGSVJHQkYgICpkc3RfcGl4ZWwgPSAoRklSR0JGKikgIGRzdF9iaXRzOwoKCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkvLyBjb252ZXJ0IGFuZCBza2lwIGFscGhhIGNoYW5uZWwKCQkJCQlkc3RfcGl4ZWxbeF0ucmVkICAgPSBDTEFNUChzcmNfcGl4ZWxbeF0ucmVkLCAwLjBGLCAxLjBGKTsKCQkJCQlkc3RfcGl4ZWxbeF0uZ3JlZW4gPSBDTEFNUChzcmNfcGl4ZWxbeF0uZ3JlZW4sIDAuMEYsIDEuMEYpOwoJCQkJCWRzdF9waXhlbFt4XS5ibHVlICA9IENMQU1QKHNyY19waXhlbFt4XS5ibHVlLCAwLjBGLCAxLjBGKTsKCQkJCX0KCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJfQoJCX0KCQlicmVhazsKCX0KCglpZihzcmMgIT0gZGliKSB7CgkJRnJlZUltYWdlX1VubG9hZChzcmMpOwoJfQoKCXJldHVybiBkc3Q7Cn0KCg==