Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBDaGFubmVsIHByb2Nlc3Npbmcgc3VwcG9ydAovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gSGVydukgRHJvbG9uIChkcm9sb25AaW5mb25pZS5mcikKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCiNpbmNsdWRlICJVdGlsaXRpZXMuaCIKCgovKiogQGJyaWVmIFJldHJpZXZlcyB0aGUgcmVkLCBncmVlbiwgYmx1ZSBvciBhbHBoYSBjaGFubmVsIG9mIGEgQkdSW0FdIGltYWdlLiAKQHBhcmFtIHNyYyBJbnB1dCBpbWFnZSB0byBiZSBwcm9jZXNzZWQuCkBwYXJhbSBjaGFubmVsIENvbG9yIGNoYW5uZWwgdG8gZXh0cmFjdApAcmV0dXJuIFJldHVybnMgdGhlIGV4dHJhY3RlZCBjaGFubmVsIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgTlVMTCBvdGhlcndpc2UuCiovCkZJQklUTUFQICogRExMX0NBTExDT05WIApGcmVlSW1hZ2VfR2V0Q2hhbm5lbChGSUJJVE1BUCAqc3JjLCBGUkVFX0lNQUdFX0NPTE9SX0NIQU5ORUwgY2hhbm5lbCkgewoKCWlmKCFGcmVlSW1hZ2VfSGFzUGl4ZWxzKHNyYykpIHJldHVybiBOVUxMOwoKCUZSRUVfSU1BR0VfVFlQRSBpbWFnZV90eXBlID0gRnJlZUltYWdlX0dldEltYWdlVHlwZShzcmMpOwoJdW5zaWduZWQgYnBwID0gRnJlZUltYWdlX0dldEJQUChzcmMpOwoKCS8vIDI0LSBvciAzMi1iaXQgCglpZihpbWFnZV90eXBlID09IEZJVF9CSVRNQVAgJiYgKChicHAgPT0gMjQpIHx8IChicHAgPT0gMzIpKSkgewoJCWludCBjOwoKCQkvLyBzZWxlY3QgdGhlIGNoYW5uZWwgdG8gZXh0cmFjdAoJCXN3aXRjaChjaGFubmVsKSB7CgkJCWNhc2UgRklDQ19CTFVFOgoJCQkJYyA9IEZJX1JHQkFfQkxVRTsKCQkJCWJyZWFrOwoJCQljYXNlIEZJQ0NfR1JFRU46CgkJCQljID0gRklfUkdCQV9HUkVFTjsKCQkJCWJyZWFrOwoJCQljYXNlIEZJQ0NfUkVEOiAKCQkJCWMgPSBGSV9SR0JBX1JFRDsKCQkJCWJyZWFrOwoJCQljYXNlIEZJQ0NfQUxQSEE6CgkJCQlpZihicHAgIT0gMzIpIHJldHVybiBOVUxMOwoJCQkJYyA9IEZJX1JHQkFfQUxQSEE7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCXJldHVybiBOVUxMOwoJCX0KCgkJLy8gYWxsb2NhdGUgYSA4LWJpdCBkaWIKCQl1bnNpZ25lZCB3aWR0aCAgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsKCQl1bnNpZ25lZCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyYyk7CgkJRklCSVRNQVAgKmRzdCA9IEZyZWVJbWFnZV9BbGxvY2F0ZSh3aWR0aCwgaGVpZ2h0LCA4KSA7CgkJaWYoIWRzdCkgcmV0dXJuIE5VTEw7CgkJLy8gYnVpbGQgYSBncmV5c2NhbGUgcGFsZXR0ZQoJCVJHQlFVQUQgKnBhbCA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGRzdCk7CgkJZm9yKGludCBpID0gMDsgaSA8IDI1NjsgaSsrKSB7CgkJCXBhbFtpXS5yZ2JCbHVlID0gcGFsW2ldLnJnYkdyZWVuID0gcGFsW2ldLnJnYlJlZCA9IChCWVRFKWk7CgkJfQoKCQkvLyBwZXJmb3JtIGV4dHJhY3Rpb24KCgkJaW50IGJ5dGVzcHAgPSBicHAgLyA4OwkvLyBieXRlcyAvIHBpeGVsCgoJCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCUJZVEUgKnNyY19iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSk7CgkJCUJZVEUgKmRzdF9iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRzdCwgeSk7CgkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCWRzdF9iaXRzW3hdID0gc3JjX2JpdHNbY107CgkJCQlzcmNfYml0cyArPSBieXRlc3BwOwoJCQl9CgkJfQoKCQkvLyBjb3B5IG1ldGFkYXRhIGZyb20gc3JjIHRvIGRzdAoJCUZyZWVJbWFnZV9DbG9uZU1ldGFkYXRhKGRzdCwgc3JjKTsKCQkKCQlyZXR1cm4gZHN0OwoJfQoKCS8vIDQ4LWJpdCBSR0Igb3IgNjQtYml0IFJHQkEgaW1hZ2VzCglpZigoaW1hZ2VfdHlwZSA9PSBGSVRfUkdCMTYpIHx8ICAoaW1hZ2VfdHlwZSA9PSBGSVRfUkdCQTE2KSkgewoJCWludCBjOwoKCQkvLyBzZWxlY3QgdGhlIGNoYW5uZWwgdG8gZXh0cmFjdCAoYWx3YXlzIFJHQltBXSkKCQlzd2l0Y2goY2hhbm5lbCkgewoJCQljYXNlIEZJQ0NfQkxVRToKCQkJCWMgPSAyOwoJCQkJYnJlYWs7CgkJCWNhc2UgRklDQ19HUkVFTjoKCQkJCWMgPSAxOwoJCQkJYnJlYWs7CgkJCWNhc2UgRklDQ19SRUQ6IAoJCQkJYyA9IDA7CgkJCQlicmVhazsKCQkJY2FzZSBGSUNDX0FMUEhBOgoJCQkJaWYoYnBwICE9IDY0KSByZXR1cm4gTlVMTDsKCQkJCWMgPSAzOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlyZXR1cm4gTlVMTDsKCQl9CgoJCS8vIGFsbG9jYXRlIGEgZ3JleXNjYWxlIGRpYgoJCXVuc2lnbmVkIHdpZHRoICA9IEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoJCXVuc2lnbmVkIGhlaWdodCA9IEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjKTsKCQlGSUJJVE1BUCAqZHN0ID0gRnJlZUltYWdlX0FsbG9jYXRlVChGSVRfVUlOVDE2LCB3aWR0aCwgaGVpZ2h0KSA7CgkJaWYoIWRzdCkgcmV0dXJuIE5VTEw7CgoJCS8vIHBlcmZvcm0gZXh0cmFjdGlvbgoKCQlpbnQgYnl0ZXNwcCA9IGJwcCAvIDE2OwkvLyB3b3JkcyAvIHBpeGVsCgoJCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCXVuc2lnbmVkIHNob3J0ICpzcmNfYml0cyA9ICh1bnNpZ25lZCBzaG9ydCopRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSk7CgkJCXVuc2lnbmVkIHNob3J0ICpkc3RfYml0cyA9ICh1bnNpZ25lZCBzaG9ydCopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRzdCwgeSk7CgkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCWRzdF9iaXRzW3hdID0gc3JjX2JpdHNbY107CgkJCQlzcmNfYml0cyArPSBieXRlc3BwOwoJCQl9CgkJfQoKCQkvLyBjb3B5IG1ldGFkYXRhIGZyb20gc3JjIHRvIGRzdAoJCUZyZWVJbWFnZV9DbG9uZU1ldGFkYXRhKGRzdCwgc3JjKTsKCQkKCQlyZXR1cm4gZHN0OwoJfQoKCS8vIDk2LWJpdCBSR0JGIG9yIDEyOC1iaXQgUkdCQUYgaW1hZ2VzCglpZigoaW1hZ2VfdHlwZSA9PSBGSVRfUkdCRikgfHwgIChpbWFnZV90eXBlID09IEZJVF9SR0JBRikpIHsKCQlpbnQgYzsKCgkJLy8gc2VsZWN0IHRoZSBjaGFubmVsIHRvIGV4dHJhY3QgKGFsd2F5cyBSR0JbQV0pCgkJc3dpdGNoKGNoYW5uZWwpIHsKCQkJY2FzZSBGSUNDX0JMVUU6CgkJCQljID0gMjsKCQkJCWJyZWFrOwoJCQljYXNlIEZJQ0NfR1JFRU46CgkJCQljID0gMTsKCQkJCWJyZWFrOwoJCQljYXNlIEZJQ0NfUkVEOiAKCQkJCWMgPSAwOwoJCQkJYnJlYWs7CgkJCWNhc2UgRklDQ19BTFBIQToKCQkJCWlmKGJwcCAhPSAxMjgpIHJldHVybiBOVUxMOwoJCQkJYyA9IDM7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCXJldHVybiBOVUxMOwoJCX0KCgkJLy8gYWxsb2NhdGUgYSBncmV5c2NhbGUgZGliCgkJdW5zaWduZWQgd2lkdGggID0gRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7CgkJdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChzcmMpOwoJCUZJQklUTUFQICpkc3QgPSBGcmVlSW1hZ2VfQWxsb2NhdGVUKEZJVF9GTE9BVCwgd2lkdGgsIGhlaWdodCkgOwoJCWlmKCFkc3QpIHJldHVybiBOVUxMOwoKCQkvLyBwZXJmb3JtIGV4dHJhY3Rpb24KCgkJaW50IGJ5dGVzcHAgPSBicHAgLyAzMjsJLy8gZmxvYXRzIC8gcGl4ZWwKCgkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJZmxvYXQgKnNyY19iaXRzID0gKGZsb2F0KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5KTsKCQkJZmxvYXQgKmRzdF9iaXRzID0gKGZsb2F0KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZHN0LCB5KTsKCQkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJZHN0X2JpdHNbeF0gPSBzcmNfYml0c1tjXTsKCQkJCXNyY19iaXRzICs9IGJ5dGVzcHA7CgkJCX0KCQl9CgoJCS8vIGNvcHkgbWV0YWRhdGEgZnJvbSBzcmMgdG8gZHN0CgkJRnJlZUltYWdlX0Nsb25lTWV0YWRhdGEoZHN0LCBzcmMpOwoJCQoJCXJldHVybiBkc3Q7Cgl9CgoJcmV0dXJuIE5VTEw7Cn0KCi8qKiBAYnJpZWYgSW5zZXJ0IGEgZ3JleXNjYWxlIGRpYiBpbnRvIGEgUkdCW0FdIGltYWdlLiAKQm90aCBzcmMgYW5kIGRzdCBtdXN0IGhhdmUgdGhlIHNhbWUgd2lkdGggYW5kIGhlaWdodC4KQHBhcmFtIGRzdCBJbWFnZSB0byBtb2RpZnkgKFJHQiBvciBSR0JBKQpAcGFyYW0gc3JjIElucHV0IGdyZXlzY2FsZSBpbWFnZSB0byBpbnNlcnQKQHBhcmFtIGNoYW5uZWwgQ29sb3IgY2hhbm5lbCB0byBtb2RpZnkKQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLgoqLwpCT09MIERMTF9DQUxMQ09OViAKRnJlZUltYWdlX1NldENoYW5uZWwoRklCSVRNQVAgKmRzdCwgRklCSVRNQVAgKnNyYywgRlJFRV9JTUFHRV9DT0xPUl9DSEFOTkVMIGNoYW5uZWwpIHsKCWludCBjOwoKCWlmKCFGcmVlSW1hZ2VfSGFzUGl4ZWxzKHNyYykgfHwgIUZyZWVJbWFnZV9IYXNQaXhlbHMoZHN0KSkgcmV0dXJuIEZBTFNFOwoJCgkvLyBzcmMgYW5kIGRzdCBpbWFnZXMgc2hvdWxkIGhhdmUgdGhlIHNhbWUgd2lkdGggYW5kIGhlaWdodAoJdW5zaWduZWQgc3JjX3dpZHRoICA9IEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoJdW5zaWduZWQgc3JjX2hlaWdodCA9IEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjKTsKCXVuc2lnbmVkIGRzdF93aWR0aCAgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoZHN0KTsKCXVuc2lnbmVkIGRzdF9oZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRzdCk7CglpZigoc3JjX3dpZHRoICE9IGRzdF93aWR0aCkgfHwgKHNyY19oZWlnaHQgIT0gZHN0X2hlaWdodCkpCgkJcmV0dXJuIEZBTFNFOwoKCS8vIHNyYyBpbWFnZSBzaG91bGQgYmUgZ3JheXNjYWxlLCBkc3QgaW1hZ2Ugc2hvdWxkIGJlIFJHQiBvciBSR0JBCglGUkVFX0lNQUdFX0NPTE9SX1RZUEUgc3JjX3R5cGUgPSBGcmVlSW1hZ2VfR2V0Q29sb3JUeXBlKHNyYyk7CglGUkVFX0lNQUdFX0NPTE9SX1RZUEUgZHN0X3R5cGUgPSBGcmVlSW1hZ2VfR2V0Q29sb3JUeXBlKGRzdCk7CglpZigoZHN0X3R5cGUgIT0gRklDX1JHQikgJiYgKGRzdF90eXBlICE9IEZJQ19SR0JBTFBIQSkgfHwgKHNyY190eXBlICE9IEZJQ19NSU5JU0JMQUNLKSkgewoJCXJldHVybiBGQUxTRTsKCX0KCglGUkVFX0lNQUdFX1RZUEUgc3JjX2ltYWdlX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKHNyYyk7CglGUkVFX0lNQUdFX1RZUEUgZHN0X2ltYWdlX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRzdCk7CgoJaWYoKGRzdF9pbWFnZV90eXBlID09IEZJVF9CSVRNQVApICYmIChzcmNfaW1hZ2VfdHlwZSA9PSBGSVRfQklUTUFQKSkgewoKCQkvLyBzcmMgaW1hZ2Ugc2hvdWxkIGJlIGdyYXlzY2FsZSwgZHN0IGltYWdlIHNob3VsZCBiZSAyNC0gb3IgMzItYml0CgkJdW5zaWduZWQgc3JjX2JwcCA9IEZyZWVJbWFnZV9HZXRCUFAoc3JjKTsKCQl1bnNpZ25lZCBkc3RfYnBwID0gRnJlZUltYWdlX0dldEJQUChkc3QpOwoJCWlmKChzcmNfYnBwICE9IDgpIHx8IChkc3RfYnBwICE9IDI0KSAmJiAoZHN0X2JwcCAhPSAzMikpCgkJCXJldHVybiBGQUxTRTsKCgoJCS8vIHNlbGVjdCB0aGUgY2hhbm5lbCB0byBtb2RpZnkKCQlzd2l0Y2goY2hhbm5lbCkgewoJCQljYXNlIEZJQ0NfQkxVRToKCQkJCWMgPSBGSV9SR0JBX0JMVUU7CgkJCQlicmVhazsKCQkJY2FzZSBGSUNDX0dSRUVOOgoJCQkJYyA9IEZJX1JHQkFfR1JFRU47CgkJCQlicmVhazsKCQkJY2FzZSBGSUNDX1JFRDogCgkJCQljID0gRklfUkdCQV9SRUQ7CgkJCQlicmVhazsKCQkJY2FzZSBGSUNDX0FMUEhBOgoJCQkJaWYoZHN0X2JwcCAhPSAzMikgcmV0dXJuIEZBTFNFOwoJCQkJYyA9IEZJX1JHQkFfQUxQSEE7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCXJldHVybiBGQUxTRTsKCQl9CgoJCS8vIHBlcmZvcm0gaW5zZXJ0aW9uCgoJCWludCBieXRlc3BwID0gZHN0X2JwcCAvIDg7CS8vIGJ5dGVzIC8gcGl4ZWwKCgkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgZHN0X2hlaWdodDsgeSsrKSB7CgkJCUJZVEUgKnNyY19iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSk7CgkJCUJZVEUgKmRzdF9iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRzdCwgeSk7CgkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IGRzdF93aWR0aDsgeCsrKSB7CgkJCQlkc3RfYml0c1tjXSA9IHNyY19iaXRzW3hdOwoJCQkJZHN0X2JpdHMgKz0gYnl0ZXNwcDsKCQkJfQoJCX0KCgkJcmV0dXJuIFRSVUU7Cgl9CgoJaWYoKChkc3RfaW1hZ2VfdHlwZSA9PSBGSVRfUkdCMTYpIHx8IChkc3RfaW1hZ2VfdHlwZSA9PSBGSVRfUkdCQTE2KSkgJiYgKHNyY19pbWFnZV90eXBlID09IEZJVF9VSU5UMTYpKSB7CgoJCS8vIHNyYyBpbWFnZSBzaG91bGQgYmUgZ3JheXNjYWxlLCBkc3QgaW1hZ2Ugc2hvdWxkIGJlIDQ4LSBvciA2NC1iaXQKCQl1bnNpZ25lZCBzcmNfYnBwID0gRnJlZUltYWdlX0dldEJQUChzcmMpOwoJCXVuc2lnbmVkIGRzdF9icHAgPSBGcmVlSW1hZ2VfR2V0QlBQKGRzdCk7CgkJaWYoKHNyY19icHAgIT0gMTYpIHx8IChkc3RfYnBwICE9IDQ4KSAmJiAoZHN0X2JwcCAhPSA2NCkpCgkJCXJldHVybiBGQUxTRTsKCgoJCS8vIHNlbGVjdCB0aGUgY2hhbm5lbCB0byBtb2RpZnkgKGFsd2F5cyBSR0JbQV0pCgkJc3dpdGNoKGNoYW5uZWwpIHsKCQkJY2FzZSBGSUNDX0JMVUU6CgkJCQljID0gMjsKCQkJCWJyZWFrOwoJCQljYXNlIEZJQ0NfR1JFRU46CgkJCQljID0gMTsKCQkJCWJyZWFrOwoJCQljYXNlIEZJQ0NfUkVEOiAKCQkJCWMgPSAwOwoJCQkJYnJlYWs7CgkJCWNhc2UgRklDQ19BTFBIQToKCQkJCWlmKGRzdF9icHAgIT0gNjQpIHJldHVybiBGQUxTRTsKCQkJCWMgPSAzOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlyZXR1cm4gRkFMU0U7CgkJfQoKCQkvLyBwZXJmb3JtIGluc2VydGlvbgoKCQlpbnQgYnl0ZXNwcCA9IGRzdF9icHAgLyAxNjsJLy8gd29yZHMgLyBwaXhlbAoKCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBkc3RfaGVpZ2h0OyB5KyspIHsKCQkJdW5zaWduZWQgc2hvcnQgKnNyY19iaXRzID0gKHVuc2lnbmVkIHNob3J0KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5KTsKCQkJdW5zaWduZWQgc2hvcnQgKmRzdF9iaXRzID0gKHVuc2lnbmVkIHNob3J0KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZHN0LCB5KTsKCQkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgZHN0X3dpZHRoOyB4KyspIHsKCQkJCWRzdF9iaXRzW2NdID0gc3JjX2JpdHNbeF07CgkJCQlkc3RfYml0cyArPSBieXRlc3BwOwoJCQl9CgkJfQoKCQlyZXR1cm4gVFJVRTsKCX0KCQoJaWYoKChkc3RfaW1hZ2VfdHlwZSA9PSBGSVRfUkdCRikgfHwgKGRzdF9pbWFnZV90eXBlID09IEZJVF9SR0JBRikpICYmIChzcmNfaW1hZ2VfdHlwZSA9PSBGSVRfRkxPQVQpKSB7CgoJCS8vIHNyYyBpbWFnZSBzaG91bGQgYmUgZ3JheXNjYWxlLCBkc3QgaW1hZ2Ugc2hvdWxkIGJlIDk2LSBvciAxMjgtYml0CgkJdW5zaWduZWQgc3JjX2JwcCA9IEZyZWVJbWFnZV9HZXRCUFAoc3JjKTsKCQl1bnNpZ25lZCBkc3RfYnBwID0gRnJlZUltYWdlX0dldEJQUChkc3QpOwoJCWlmKChzcmNfYnBwICE9IDMyKSB8fCAoZHN0X2JwcCAhPSA5NikgJiYgKGRzdF9icHAgIT0gMTI4KSkKCQkJcmV0dXJuIEZBTFNFOwoKCgkJLy8gc2VsZWN0IHRoZSBjaGFubmVsIHRvIG1vZGlmeSAoYWx3YXlzIFJHQltBXSkKCQlzd2l0Y2goY2hhbm5lbCkgewoJCQljYXNlIEZJQ0NfQkxVRToKCQkJCWMgPSAyOwoJCQkJYnJlYWs7CgkJCWNhc2UgRklDQ19HUkVFTjoKCQkJCWMgPSAxOwoJCQkJYnJlYWs7CgkJCWNhc2UgRklDQ19SRUQ6IAoJCQkJYyA9IDA7CgkJCQlicmVhazsKCQkJY2FzZSBGSUNDX0FMUEhBOgoJCQkJaWYoZHN0X2JwcCAhPSAxMjgpIHJldHVybiBGQUxTRTsKCQkJCWMgPSAzOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlyZXR1cm4gRkFMU0U7CgkJfQoKCQkvLyBwZXJmb3JtIGluc2VydGlvbgoKCQlpbnQgYnl0ZXNwcCA9IGRzdF9icHAgLyAzMjsJLy8gZmxvYXRzIC8gcGl4ZWwKCgkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgZHN0X2hlaWdodDsgeSsrKSB7CgkJCWZsb2F0ICpzcmNfYml0cyA9IChmbG9hdCopRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSk7CgkJCWZsb2F0ICpkc3RfYml0cyA9IChmbG9hdCopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRzdCwgeSk7CgkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IGRzdF93aWR0aDsgeCsrKSB7CgkJCQlkc3RfYml0c1tjXSA9IHNyY19iaXRzW3hdOwoJCQkJZHN0X2JpdHMgKz0gYnl0ZXNwcDsKCQkJfQoJCX0KCgkJcmV0dXJuIFRSVUU7Cgl9CgoJcmV0dXJuIEZBTFNFOwp9CgovKiogQGJyaWVmIFJldHJpZXZlcyB0aGUgcmVhbCBwYXJ0LCBpbWFnaW5hcnkgcGFydCwgbWFnbml0dWRlIG9yIHBoYXNlIG9mIGEgY29tcGxleCBpbWFnZS4KQHBhcmFtIHNyYyBJbnB1dCBpbWFnZSB0byBiZSBwcm9jZXNzZWQuCkBwYXJhbSBjaGFubmVsIENoYW5uZWwgdG8gZXh0cmFjdApAcmV0dXJuIFJldHVybnMgdGhlIGV4dHJhY3RlZCBjaGFubmVsIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgTlVMTCBvdGhlcndpc2UuCiovCkZJQklUTUFQICogRExMX0NBTExDT05WIApGcmVlSW1hZ2VfR2V0Q29tcGxleENoYW5uZWwoRklCSVRNQVAgKnNyYywgRlJFRV9JTUFHRV9DT0xPUl9DSEFOTkVMIGNoYW5uZWwpIHsKCXVuc2lnbmVkIHgsIHk7Cglkb3VibGUgbWFnLCBwaGFzZTsKCUZJQ09NUExFWCAqc3JjX2JpdHMgPSBOVUxMOwoJZG91YmxlICpkc3RfYml0cyA9IE5VTEw7CglGSUJJVE1BUCAqZHN0ID0gTlVMTDsKCglpZighRnJlZUltYWdlX0hhc1BpeGVscyhzcmMpKSByZXR1cm4gTlVMTDsKCglpZihGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKHNyYykgPT0gRklUX0NPTVBMRVgpIHsKCQkvLyBhbGxvY2F0ZSBhIGRpYiBvZiB0eXBlIEZJVF9ET1VCTEUKCQl1bnNpZ25lZCB3aWR0aCAgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsKCQl1bnNpZ25lZCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyYyk7CgkJZHN0ID0gRnJlZUltYWdlX0FsbG9jYXRlVChGSVRfRE9VQkxFLCB3aWR0aCwgaGVpZ2h0KSA7CgkJaWYoIWRzdCkgcmV0dXJuIE5VTEw7CgoJCS8vIHBlcmZvcm0gZXh0cmFjdGlvbgoKCQlzd2l0Y2goY2hhbm5lbCkgewoJCQljYXNlIEZJQ0NfUkVBTDogLy8gcmVhbCBwYXJ0CgkJCQlmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCXNyY19iaXRzID0gKEZJQ09NUExFWCAqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCQkJCWRzdF9iaXRzID0gKGRvdWJsZSAqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoJCQkJCWZvcih4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJZHN0X2JpdHNbeF0gPSBzcmNfYml0c1t4XS5yOwoJCQkJCX0KCQkJCX0KCQkJCWJyZWFrOwoKCQkJY2FzZSBGSUNDX0lNQUc6IC8vIGltYWdpbmFyeSBwYXJ0CgkJCQlmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCXNyY19iaXRzID0gKEZJQ09NUExFWCAqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCQkJCWRzdF9iaXRzID0gKGRvdWJsZSAqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoJCQkJCWZvcih4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJZHN0X2JpdHNbeF0gPSBzcmNfYml0c1t4XS5pOwoJCQkJCX0KCQkJCX0KCQkJCWJyZWFrOwoKCQkJY2FzZSBGSUNDX01BRzogLy8gbWFnbml0dWRlCgkJCQlmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCXNyY19iaXRzID0gKEZJQ09NUExFWCAqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCQkJCWRzdF9iaXRzID0gKGRvdWJsZSAqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoJCQkJCWZvcih4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJbWFnID0gc3JjX2JpdHNbeF0uciAqIHNyY19iaXRzW3hdLnIgKyBzcmNfYml0c1t4XS5pICogc3JjX2JpdHNbeF0uaTsKCQkJCQkJZHN0X2JpdHNbeF0gPSBzcXJ0KG1hZyk7CgkJCQkJfQoJCQkJfQoJCQkJYnJlYWs7CgoJCQljYXNlIEZJQ0NfUEhBU0U6IC8vIHBoYXNlCgkJCQlmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCXNyY19iaXRzID0gKEZJQ09NUExFWCAqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCQkJCWRzdF9iaXRzID0gKGRvdWJsZSAqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoJCQkJCWZvcih4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJaWYoKHNyY19iaXRzW3hdLnIgPT0gMCkgJiYgKHNyY19iaXRzW3hdLmkgPT0gMCkpIHsKCQkJCQkJCXBoYXNlID0gMDsKCQkJCQkJfSBlbHNlIHsKCQkJCQkJCXBoYXNlID0gYXRhbjIoc3JjX2JpdHNbeF0uaSwgc3JjX2JpdHNbeF0ucik7CgkJCQkJCX0KCQkJCQkJZHN0X2JpdHNbeF0gPSBwaGFzZTsKCQkJCQl9CgkJCQl9CgkJCQlicmVhazsKCQl9Cgl9CgoJLy8gY29weSBtZXRhZGF0YSBmcm9tIHNyYyB0byBkc3QKCUZyZWVJbWFnZV9DbG9uZU1ldGFkYXRhKGRzdCwgc3JjKTsKCQoJcmV0dXJuIGRzdDsKfQoKLyoqIEBicmllZiBTZXQgdGhlIHJlYWwgb3IgaW1hZ2luYXJ5IHBhcnQgb2YgYSBjb21wbGV4IGltYWdlLgpCb3RoIHNyYyBhbmQgZHN0IG11c3QgaGF2ZSB0aGUgc2FtZSB3aWR0aCBhbmQgaGVpZ2h0LgpAcGFyYW0gZHN0IEltYWdlIHRvIG1vZGlmeSAoaW1hZ2Ugb2YgdHlwZSBGSVRfQ09NUExFWCkKQHBhcmFtIHNyYyBJbnB1dCBpbWFnZSBvZiB0eXBlIEZJVF9ET1VCTEUKQHBhcmFtIGNoYW5uZWwgQ2hhbm5lbCB0byBtb2RpZnkKQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLgoqLwpCT09MIERMTF9DQUxMQ09OViAKRnJlZUltYWdlX1NldENvbXBsZXhDaGFubmVsKEZJQklUTUFQICpkc3QsIEZJQklUTUFQICpzcmMsIEZSRUVfSU1BR0VfQ09MT1JfQ0hBTk5FTCBjaGFubmVsKSB7Cgl1bnNpZ25lZCB4LCB5OwoJZG91YmxlICpzcmNfYml0cyA9IE5VTEw7CglGSUNPTVBMRVggKmRzdF9iaXRzID0gTlVMTDsKCglpZighRnJlZUltYWdlX0hhc1BpeGVscyhzcmMpIHx8ICFGcmVlSW1hZ2VfSGFzUGl4ZWxzKGRzdCkpIHJldHVybiBGQUxTRTsKCgkvLyBzcmMgaW1hZ2Ugc2hvdWxkIGJlIG9mIHR5cGUgRklUX0RPVUJMRSwgZHN0IGltYWdlIHNob3VsZCBiZSBvZiB0eXBlIEZJVF9DT01QTEVYCgljb25zdCBGUkVFX0lNQUdFX1RZUEUgc3JjX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKHNyYyk7Cgljb25zdCBGUkVFX0lNQUdFX1RZUEUgZHN0X3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRzdCk7CglpZigoc3JjX3R5cGUgIT0gRklUX0RPVUJMRSkgfHwgKGRzdF90eXBlICE9IEZJVF9DT01QTEVYKSkKCQlyZXR1cm4gRkFMU0U7CgoJLy8gc3JjIGFuZCBkc3QgaW1hZ2VzIHNob3VsZCBoYXZlIHRoZSBzYW1lIHdpZHRoIGFuZCBoZWlnaHQKCXVuc2lnbmVkIHNyY193aWR0aCAgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsKCXVuc2lnbmVkIHNyY19oZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyYyk7Cgl1bnNpZ25lZCBkc3Rfd2lkdGggID0gRnJlZUltYWdlX0dldFdpZHRoKGRzdCk7Cgl1bnNpZ25lZCBkc3RfaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChkc3QpOwoJaWYoKHNyY193aWR0aCAhPSBkc3Rfd2lkdGgpIHx8IChzcmNfaGVpZ2h0ICE9IGRzdF9oZWlnaHQpKQoJCXJldHVybiBGQUxTRTsKCgkvLyBzZWxlY3QgdGhlIGNoYW5uZWwgdG8gbW9kaWZ5Cglzd2l0Y2goY2hhbm5lbCkgewoJCWNhc2UgRklDQ19SRUFMOiAvLyByZWFsIHBhcnQKCQkJZm9yKHkgPSAwOyB5IDwgZHN0X2hlaWdodDsgeSsrKSB7CgkJCQlzcmNfYml0cyA9IChkb3VibGUgKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5KTsKCQkJCWRzdF9iaXRzID0gKEZJQ09NUExFWCAqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoJCQkJZm9yKHggPSAwOyB4IDwgZHN0X3dpZHRoOyB4KyspIHsKCQkJCQlkc3RfYml0c1t4XS5yID0gc3JjX2JpdHNbeF07CgkJCQl9CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBGSUNDX0lNQUc6IC8vIGltYWdpbmFyeSBwYXJ0CgkJCWZvcih5ID0gMDsgeSA8IGRzdF9oZWlnaHQ7IHkrKykgewoJCQkJc3JjX2JpdHMgPSAoZG91YmxlICopRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSk7CgkJCQlkc3RfYml0cyA9IChGSUNPTVBMRVggKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZHN0LCB5KTsKCQkJCWZvcih4ID0gMDsgeCA8IGRzdF93aWR0aDsgeCsrKSB7CgkJCQkJZHN0X2JpdHNbeF0uaSA9IHNyY19iaXRzW3hdOwoJCQkJfQoJCQl9CgkJCWJyZWFrOwoJfQoKCXJldHVybiBUUlVFOwp9Cg==