Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBCaXRtYXAgY29udmVyc2lvbiByb3V0aW5lcwovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gSGVydukgRHJvbG9uIChkcm9sb25AaW5mb25pZS5mcikKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCiNpbmNsdWRlICJVdGlsaXRpZXMuaCIKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBzbWFydCBjb252ZXJ0IFggdG8gRmxvYXQKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKRklCSVRNQVAgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRUb0Zsb2F0KEZJQklUTUFQICpkaWIpIHsKCUZJQklUTUFQICpzcmMgPSBOVUxMOwoJRklCSVRNQVAgKmRzdCA9IE5VTEw7CgoJaWYoIUZyZWVJbWFnZV9IYXNQaXhlbHMoZGliKSkgcmV0dXJuIE5VTEw7CgoJRlJFRV9JTUFHRV9UWVBFIHNyY190eXBlID0gRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpOwoKCS8vIGNoZWNrIGZvciBhbGxvd2VkIGNvbnZlcnNpb25zIAoJc3dpdGNoKHNyY190eXBlKSB7CgkJY2FzZSBGSVRfQklUTUFQOgoJCXsKCQkJLy8gYWxsb3cgY29udmVyc2lvbiBmcm9tIDgtYml0CgkJCWlmKChGcmVlSW1hZ2VfR2V0QlBQKGRpYikgPT0gOCkgJiYgKEZyZWVJbWFnZV9HZXRDb2xvclR5cGUoZGliKSA9PSBGSUNfTUlOSVNCTEFDSykpIHsKCQkJCXNyYyA9IGRpYjsKCQkJfSBlbHNlIHsKCQkJCXNyYyA9IEZyZWVJbWFnZV9Db252ZXJ0VG9HcmV5c2NhbGUoZGliKTsKCQkJCWlmKCFzcmMpIHJldHVybiBOVUxMOwoJCQl9CgkJCWJyZWFrOwoJCX0KCQljYXNlIEZJVF9VSU5UMTY6CgkJY2FzZSBGSVRfUkdCMTY6CgkJY2FzZSBGSVRfUkdCQTE2OgoJCWNhc2UgRklUX1JHQkY6CgkJY2FzZSBGSVRfUkdCQUY6CgkJCXNyYyA9IGRpYjsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfRkxPQVQ6CgkJCS8vIGZsb2F0IHR5cGUgOiBjbG9uZSB0aGUgc3JjCgkJCXJldHVybiBGcmVlSW1hZ2VfQ2xvbmUoZGliKTsKCQlkZWZhdWx0OgoJCQlyZXR1cm4gTlVMTDsKCX0KCgkvLyBhbGxvY2F0ZSBkc3QgaW1hZ2UKCgljb25zdCB1bnNpZ25lZCB3aWR0aCA9IEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoJY29uc3QgdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChzcmMpOwoKCWRzdCA9IEZyZWVJbWFnZV9BbGxvY2F0ZVQoRklUX0ZMT0FULCB3aWR0aCwgaGVpZ2h0KTsKCWlmKCFkc3QpIHsKCQlpZihzcmMgIT0gZGliKSB7CgkJCUZyZWVJbWFnZV9VbmxvYWQoc3JjKTsKCQl9CgkJcmV0dXJuIE5VTEw7Cgl9CgoJLy8gY29weSBtZXRhZGF0YSBmcm9tIHNyYyB0byBkc3QKCUZyZWVJbWFnZV9DbG9uZU1ldGFkYXRhKGRzdCwgc3JjKTsKCgkvLyBjb252ZXJ0IGZyb20gc3JjIHR5cGUgdG8gZmxvYXQKCgljb25zdCB1bnNpZ25lZCBzcmNfcGl0Y2ggPSBGcmVlSW1hZ2VfR2V0UGl0Y2goc3JjKTsKCWNvbnN0IHVuc2lnbmVkIGRzdF9waXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChkc3QpOwoKCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKHNyYyk7CglCWVRFICpkc3RfYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhkc3QpOwoKCXN3aXRjaChzcmNfdHlwZSkgewoJCWNhc2UgRklUX0JJVE1BUDoKCQl7CgkJCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQljb25zdCBCWVRFICpzcmNfcGl4ZWwgPSAoQllURSopc3JjX2JpdHM7CgkJCQlmbG9hdCAqZHN0X3BpeGVsID0gKGZsb2F0Kilkc3RfYml0czsKCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkvLyBjb252ZXJ0IGFuZCBzY2FsZSB0byB0aGUgcmFuZ2UgWzAuLjFdCgkJCQkJZHN0X3BpeGVsW3hdID0gKGZsb2F0KShzcmNfcGl4ZWxbeF0pIC8gMjU1OwoJCQkJfQoJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJZHN0X2JpdHMgKz0gZHN0X3BpdGNoOwoJCQl9CgkJfQoJCWJyZWFrOwoKCQljYXNlIEZJVF9VSU5UMTY6CgkJewoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJY29uc3QgV09SRCAqc3JjX3BpeGVsID0gKFdPUkQqKXNyY19iaXRzOwoJCQkJZmxvYXQgKmRzdF9waXhlbCA9IChmbG9hdCopZHN0X2JpdHM7CgoJCQkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCS8vIGNvbnZlcnQgYW5kIHNjYWxlIHRvIHRoZSByYW5nZSBbMC4uMV0KCQkJCQlkc3RfcGl4ZWxbeF0gPSAoZmxvYXQpKHNyY19waXhlbFt4XSkgLyA2NTUzNTsKCQkJCX0KCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJfQoJCX0KCQlicmVhazsKCgkJY2FzZSBGSVRfUkdCMTY6CgkJewoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJY29uc3QgRklSR0IxNiAqc3JjX3BpeGVsID0gKEZJUkdCMTYqKXNyY19iaXRzOwoJCQkJZmxvYXQgKmRzdF9waXhlbCA9IChmbG9hdCopZHN0X2JpdHM7CgoJCQkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCS8vIGNvbnZlcnQgYW5kIHNjYWxlIHRvIHRoZSByYW5nZSBbMC4uMV0KCQkJCQlkc3RfcGl4ZWxbeF0gPSBMVU1BX1JFQzcwOShzcmNfcGl4ZWxbeF0ucmVkLCBzcmNfcGl4ZWxbeF0uZ3JlZW4sIHNyY19waXhlbFt4XS5ibHVlKSAvIDY1NTM1LjBGOwoJCQkJfQoJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJZHN0X2JpdHMgKz0gZHN0X3BpdGNoOwoJCQl9CgkJfQoJCWJyZWFrOwoKCQljYXNlIEZJVF9SR0JBMTY6CgkJewoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJY29uc3QgRklSR0JBMTYgKnNyY19waXhlbCA9IChGSVJHQkExNiopc3JjX2JpdHM7CgkJCQlmbG9hdCAqZHN0X3BpeGVsID0gKGZsb2F0Kilkc3RfYml0czsKCgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJLy8gY29udmVydCBhbmQgc2NhbGUgdG8gdGhlIHJhbmdlIFswLi4xXQoJCQkJCWRzdF9waXhlbFt4XSA9IExVTUFfUkVDNzA5KHNyY19waXhlbFt4XS5yZWQsIHNyY19waXhlbFt4XS5ncmVlbiwgc3JjX3BpeGVsW3hdLmJsdWUpIC8gNjU1MzUuMEY7CgkJCQl9CgkJCQlzcmNfYml0cyArPSBzcmNfcGl0Y2g7CgkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCX0KCQl9CgkJYnJlYWs7CgoJCWNhc2UgRklUX1JHQkY6CgkJewoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJY29uc3QgRklSR0JGICpzcmNfcGl4ZWwgPSAoRklSR0JGKilzcmNfYml0czsKCQkJCWZsb2F0ICpkc3RfcGl4ZWwgPSAoZmxvYXQqKWRzdF9iaXRzOwoKCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkvLyBjb252ZXJ0IChhc3N1bWUgcGl4ZWwgdmFsdWVzIGFyZSBpbiB0aGUgcmFuZ2UgWzAuLjFdKQoJCQkJCWRzdF9waXhlbFt4XSA9IExVTUFfUkVDNzA5KHNyY19waXhlbFt4XS5yZWQsIHNyY19waXhlbFt4XS5ncmVlbiwgc3JjX3BpeGVsW3hdLmJsdWUpOwoJCQkJCWRzdF9waXhlbFt4XSA9IENMQU1QKGRzdF9waXhlbFt4XSwgMC4wRiwgMS4wRik7CgkJCQl9CgkJCQlzcmNfYml0cyArPSBzcmNfcGl0Y2g7CgkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCX0KCQl9CgkJYnJlYWs7CgoJCWNhc2UgRklUX1JHQkFGOgoJCXsKCQkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCWNvbnN0IEZJUkdCQUYgKnNyY19waXhlbCA9IChGSVJHQkFGKilzcmNfYml0czsKCQkJCWZsb2F0ICpkc3RfcGl4ZWwgPSAoZmxvYXQqKWRzdF9iaXRzOwoKCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkvLyBjb252ZXJ0IChhc3N1bWUgcGl4ZWwgdmFsdWVzIGFyZSBpbiB0aGUgcmFuZ2UgWzAuLjFdKQoJCQkJCWRzdF9waXhlbFt4XSA9IExVTUFfUkVDNzA5KHNyY19waXhlbFt4XS5yZWQsIHNyY19waXhlbFt4XS5ncmVlbiwgc3JjX3BpeGVsW3hdLmJsdWUpOwoJCQkJCWRzdF9waXhlbFt4XSA9IENMQU1QKGRzdF9waXhlbFt4XSwgMC4wRiwgMS4wRik7CgkJCQl9CgkJCQlzcmNfYml0cyArPSBzcmNfcGl0Y2g7CgkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCX0KCQl9CgkJYnJlYWs7Cgl9CgoJaWYoc3JjICE9IGRpYikgewoJCUZyZWVJbWFnZV9VbmxvYWQoc3JjKTsKCX0KCglyZXR1cm4gZHN0Owp9Cgo=