Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBCaXRtYXAgY29udmVyc2lvbiByb3V0aW5lcwovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gSGVydukgRHJvbG9uIChkcm9sb25AaW5mb25pZS5mcikKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCiNpbmNsdWRlICJVdGlsaXRpZXMuaCIKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBzbWFydCBjb252ZXJ0IFggdG8gUkdCQTE2Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkZJQklUTUFQICogRExMX0NBTExDT05WCkZyZWVJbWFnZV9Db252ZXJ0VG9SR0JBMTYoRklCSVRNQVAgKmRpYikgewoJRklCSVRNQVAgKnNyYyA9IE5VTEw7CglGSUJJVE1BUCAqZHN0ID0gTlVMTDsKCglpZighRnJlZUltYWdlX0hhc1BpeGVscyhkaWIpKSByZXR1cm4gTlVMTDsKCgljb25zdCBGUkVFX0lNQUdFX1RZUEUgc3JjX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRpYik7CgoJLy8gY2hlY2sgZm9yIGFsbG93ZWQgY29udmVyc2lvbnMgCglzd2l0Y2goc3JjX3R5cGUpIHsKCQljYXNlIEZJVF9CSVRNQVA6CgkJewoJCQkvLyBjb252ZXJ0IHRvIDMyLWJpdCBpZiBuZWVkZWQKCQkJaWYoRnJlZUltYWdlX0dldEJQUChkaWIpID09IDMyKSB7CgkJCQlzcmMgPSBkaWI7CgkJCX0gZWxzZSB7CgkJCQlzcmMgPSBGcmVlSW1hZ2VfQ29udmVydFRvMzJCaXRzKGRpYik7CgkJCQlpZighc3JjKSByZXR1cm4gTlVMTDsKCQkJfQoJCQlicmVhazsKCQl9CgkJY2FzZSBGSVRfVUlOVDE2OgoJCQkvLyBhbGxvdyBjb252ZXJzaW9uIGZyb20gdW5zaWduZWQgMTYtYml0CgkJCXNyYyA9IGRpYjsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfUkdCMTY6CgkJCS8vIGFsbG93IGNvbnZlcnNpb24gZnJvbSA0OC1iaXQgUkdCCgkJCXNyYyA9IGRpYjsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfUkdCQTE2OgoJCQkvLyBSR0JBMTYgdHlwZSA6IGNsb25lIHRoZSBzcmMKCQkJcmV0dXJuIEZyZWVJbWFnZV9DbG9uZShkaWIpOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlyZXR1cm4gTlVMTDsKCX0KCgkvLyBhbGxvY2F0ZSBkc3QgaW1hZ2UKCgljb25zdCB1bnNpZ25lZCB3aWR0aCA9IEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoJY29uc3QgdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChzcmMpOwoKCWRzdCA9IEZyZWVJbWFnZV9BbGxvY2F0ZVQoRklUX1JHQkExNiwgd2lkdGgsIGhlaWdodCk7CglpZighZHN0KSB7CgkJaWYoc3JjICE9IGRpYikgewoJCQlGcmVlSW1hZ2VfVW5sb2FkKHNyYyk7CgkJfQoJCXJldHVybiBOVUxMOwoJfQoKCS8vIGNvcHkgbWV0YWRhdGEgZnJvbSBzcmMgdG8gZHN0CglGcmVlSW1hZ2VfQ2xvbmVNZXRhZGF0YShkc3QsIHNyYyk7CgoJLy8gY29udmVydCBmcm9tIHNyYyB0eXBlIHRvIFJHQkExNgoKCXN3aXRjaChzcmNfdHlwZSkgewoJCWNhc2UgRklUX0JJVE1BUDoKCQl7CgkJCS8vIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHBlciBwaXhlbCAoNCBmb3IgMzItYml0KQoJCQljb25zdCB1bnNpZ25lZCBieXRlc3BwID0gRnJlZUltYWdlX0dldExpbmUoc3JjKSAvIEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoKCQkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCQkJRklSR0JBMTYgKmRzdF9iaXRzID0gKEZJUkdCQTE2KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZHN0LCB5KTsKCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQlkc3RfYml0c1t4XS5yZWQJCT0gc3JjX2JpdHNbRklfUkdCQV9SRURdIDw8IDg7CgkJCQkJZHN0X2JpdHNbeF0uZ3JlZW4JPSBzcmNfYml0c1tGSV9SR0JBX0dSRUVOXSA8PCA4OwoJCQkJCWRzdF9iaXRzW3hdLmJsdWUJPSBzcmNfYml0c1tGSV9SR0JBX0JMVUVdIDw8IDg7CgkJCQkJZHN0X2JpdHNbeF0uYWxwaGEJPSBzcmNfYml0c1tGSV9SR0JBX0FMUEhBXSA8PCA4OwoJCQkJCXNyY19iaXRzICs9IGJ5dGVzcHA7CgkJCQl9CgkJCX0KCQl9CgkJYnJlYWs7CgoJCWNhc2UgRklUX1VJTlQxNjoKCQl7CgkJCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQljb25zdCBXT1JEICpzcmNfYml0cyA9IChXT1JEKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5KTsKCQkJCUZJUkdCQTE2ICpkc3RfYml0cyA9IChGSVJHQkExNiopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRzdCwgeSk7CgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJLy8gY29udmVydCBieSBjb3B5aW5nIGdyZXlzY2FsZSBjaGFubmVsIHRvIGVhY2ggUiwgRywgQiBjaGFubmVscwoJCQkJCWRzdF9iaXRzW3hdLnJlZCAgID0gc3JjX2JpdHNbeF07CgkJCQkJZHN0X2JpdHNbeF0uZ3JlZW4gPSBzcmNfYml0c1t4XTsKCQkJCQlkc3RfYml0c1t4XS5ibHVlICA9IHNyY19iaXRzW3hdOwoJCQkJCWRzdF9iaXRzW3hdLmFscGhhID0gMHhGRkZGOwoJCQkJfQoJCQl9CgkJfQoJCWJyZWFrOwoKCQljYXNlIEZJVF9SR0IxNjoKCQl7CgkJCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQljb25zdCBGSVJHQjE2ICpzcmNfYml0cyA9IChGSVJHQjE2KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5KTsKCQkJCUZJUkdCQTE2ICpkc3RfYml0cyA9IChGSVJHQkExNiopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRzdCwgeSk7CgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJLy8gY29udmVydCBwaXhlbHMgZGlyZWN0bHksIHdoaWxlIGFkZGluZyBhICJkdW1teSIgYWxwaGEgb2YgMS4wCgkJCQkJZHN0X2JpdHNbeF0ucmVkICAgPSBzcmNfYml0c1t4XS5yZWQ7CgkJCQkJZHN0X2JpdHNbeF0uZ3JlZW4gPSBzcmNfYml0c1t4XS5ncmVlbjsKCQkJCQlkc3RfYml0c1t4XS5ibHVlICA9IHNyY19iaXRzW3hdLmJsdWU7CgkJCQkJZHN0X2JpdHNbeF0uYWxwaGEgPSAweEZGRkY7CgkJCQl9CgkJCX0KCQl9CgkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCWJyZWFrOwoJfQoKCWlmKHNyYyAhPSBkaWIpIHsKCQlGcmVlSW1hZ2VfVW5sb2FkKHNyYyk7Cgl9CgoJcmV0dXJuIGRzdDsKfQoK