Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBCaXRtYXAgY29udmVyc2lvbiByb3V0aW5lcwovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gSGVydukgRHJvbG9uIChkcm9sb25AaW5mb25pZS5mcikKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCiNpbmNsdWRlICJVdGlsaXRpZXMuaCIKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBzbWFydCBjb252ZXJ0IFggdG8gVUlOVDE2Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkZJQklUTUFQICogRExMX0NBTExDT05WCkZyZWVJbWFnZV9Db252ZXJ0VG9VSU5UMTYoRklCSVRNQVAgKmRpYikgewoJRklCSVRNQVAgKnNyYyA9IE5VTEw7CglGSUJJVE1BUCAqZHN0ID0gTlVMTDsKCglpZighRnJlZUltYWdlX0hhc1BpeGVscyhkaWIpKSByZXR1cm4gTlVMTDsKCgljb25zdCBGUkVFX0lNQUdFX1RZUEUgc3JjX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRpYik7CgoJLy8gY2hlY2sgZm9yIGFsbG93ZWQgY29udmVyc2lvbnMgCglzd2l0Y2goc3JjX3R5cGUpIHsKCQljYXNlIEZJVF9CSVRNQVA6CgkJewoJCQkvLyBjb252ZXJ0IHRvIGdyZXlzY2FsZSBpZiBuZWVkZWQKCQkJaWYoKEZyZWVJbWFnZV9HZXRCUFAoZGliKSA9PSA4KSAmJiAoRnJlZUltYWdlX0dldENvbG9yVHlwZShkaWIpID09IEZJQ19NSU5JU0JMQUNLKSkgewoJCQkJc3JjID0gZGliOwoJCQl9IGVsc2UgewoJCQkJc3JjID0gRnJlZUltYWdlX0NvbnZlcnRUb0dyZXlzY2FsZShkaWIpOwoJCQkJaWYoIXNyYykgcmV0dXJuIE5VTEw7CgkJCX0KCQkJYnJlYWs7CgkJfQoJCWNhc2UgRklUX1VJTlQxNjoKCQkJLy8gVUlOVDE2IHR5cGUgOiBjbG9uZSB0aGUgc3JjCgkJCXJldHVybiBGcmVlSW1hZ2VfQ2xvbmUoZGliKTsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfUkdCMTY6CgkJCS8vIGFsbG93IGNvbnZlcnNpb24gZnJvbSA0OC1iaXQgUkdCCgkJCXNyYyA9IGRpYjsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfUkdCQTE2OgoJCQkvLyBhbGxvdyBjb252ZXJzaW9uIGZyb20gNjQtYml0IFJHQkEgKGlnbm9yZSB0aGUgYWxwaGEgY2hhbm5lbCkKCQkJc3JjID0gZGliOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlyZXR1cm4gTlVMTDsKCX0KCgkvLyBhbGxvY2F0ZSBkc3QgaW1hZ2UKCgljb25zdCB1bnNpZ25lZCB3aWR0aCA9IEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoJY29uc3QgdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChzcmMpOwoKCWRzdCA9IEZyZWVJbWFnZV9BbGxvY2F0ZVQoRklUX1VJTlQxNiwgd2lkdGgsIGhlaWdodCk7CglpZighZHN0KSB7CgkJaWYoc3JjICE9IGRpYikgewoJCQlGcmVlSW1hZ2VfVW5sb2FkKHNyYyk7CgkJfQoJCXJldHVybiBOVUxMOwoJfQoKCS8vIGNvcHkgbWV0YWRhdGEgZnJvbSBzcmMgdG8gZHN0CglGcmVlSW1hZ2VfQ2xvbmVNZXRhZGF0YShkc3QsIHNyYyk7CgoJLy8gY29udmVydCBmcm9tIHNyYyB0eXBlIHRvIFVJTlQxNgoKCXN3aXRjaChzcmNfdHlwZSkgewoJCWNhc2UgRklUX0JJVE1BUDoKCQl7CgkJCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQljb25zdCBCWVRFICpzcmNfYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5KTsKCQkJCVdPUkQgKmRzdF9iaXRzID0gKFdPUkQqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoJCQkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCWRzdF9iaXRzW3hdID0gc3JjX2JpdHNbeF0gPDwgODsKCQkJCX0KCQkJfQoJCX0KCQlicmVhazsKCgkJY2FzZSBGSVRfUkdCMTY6CgkJewoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJY29uc3QgRklSR0IxNiAqc3JjX2JpdHMgPSAoRklSR0IxNiopRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSk7CgkJCQlXT1JEICpkc3RfYml0cyA9IChXT1JEKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZHN0LCB5KTsKCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkvLyBjb252ZXJ0IHRvIGdyZXkKCQkJCQlkc3RfYml0c1t4XSA9IChXT1JEKUxVTUFfUkVDNzA5KHNyY19iaXRzW3hdLnJlZCwgc3JjX2JpdHNbeF0uZ3JlZW4sIHNyY19iaXRzW3hdLmJsdWUpOwoJCQkJfQoJCQl9CgkJfQoJCWJyZWFrOwoKCQljYXNlIEZJVF9SR0JBMTY6CgkJewoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJY29uc3QgRklSR0JBMTYgKnNyY19iaXRzID0gKEZJUkdCQTE2KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5KTsKCQkJCVdPUkQgKmRzdF9iaXRzID0gKFdPUkQqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoJCQkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCS8vIGNvbnZlcnQgdG8gZ3JleQoJCQkJCWRzdF9iaXRzW3hdID0gKFdPUkQpTFVNQV9SRUM3MDkoc3JjX2JpdHNbeF0ucmVkLCBzcmNfYml0c1t4XS5ncmVlbiwgc3JjX2JpdHNbeF0uYmx1ZSk7CgkJCQl9CgkJCX0KCQl9CgkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCWJyZWFrOwoJfQoKCWlmKHNyYyAhPSBkaWIpIHsKCQlGcmVlSW1hZ2VfVW5sb2FkKHNyYyk7Cgl9CgoJcmV0dXJuIGRzdDsKfQoK