Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBCaXRtYXAgY29udmVyc2lvbiByb3V0aW5lcwovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gRmxvcmlzIHZhbiBkZW4gQmVyZyAoZmx2ZGJlcmdAd3hzLm5sKQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIC0gSmFuaSBLYWphbGEgKGphbmlrQHJlbWVkeS5maSkKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCiNpbmNsdWRlICJVdGlsaXRpZXMuaCIKI2luY2x1ZGUgIlF1YW50aXplcnMuaCIKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiNkZWZpbmUgQ09OVkVSVChmcm9tLCB0bykgY2FzZSB0byA6IEZyZWVJbWFnZV9Db252ZXJ0TGluZSMjZnJvbSMjVG8jI3RvKGJpdHMsIHNjYW5saW5lLCBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKSk7IGJyZWFrOwojZGVmaW5lIENPTlZFUlRXSVRIUEFMRVRURShmcm9tLCB0bykgY2FzZSB0byA6IEZyZWVJbWFnZV9Db252ZXJ0TGluZSMjZnJvbSMjVG8jI3RvKGJpdHMsIHNjYW5saW5lLCBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKSwgRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKSk7IGJyZWFrOwoKI2RlZmluZSBDT05WRVJUVE8xNihmcm9tKSBcCgljYXNlIDE2IDogXAoJCWlmICgocmVkX21hc2sgPT0gRkkxNl81NTVfUkVEX01BU0spICYmIChncmVlbl9tYXNrID09IEZJMTZfNTU1X0dSRUVOX01BU0spICYmIChibHVlX21hc2sgPT0gRkkxNl81NTVfQkxVRV9NQVNLKSkgeyBcCgkJCUZyZWVJbWFnZV9Db252ZXJ0TGluZSMjZnJvbSMjVG8xNl81NTUoYml0cywgc2NhbmxpbmUsIEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpKTsgXAoJCX0gZWxzZSB7IFwKCQkJRnJlZUltYWdlX0NvbnZlcnRMaW5lIyNmcm9tIyNUbzE2XzU2NShiaXRzLCBzY2FubGluZSwgRnJlZUltYWdlX0dldFdpZHRoKGRpYikpOyBcCgkJfSBcCgkJYnJlYWs7CgojZGVmaW5lIENPTlZFUlRUTzE2V0lUSFBBTEVUVEUoZnJvbSkgXAoJY2FzZSAxNiA6IFwKCQlpZiAoKHJlZF9tYXNrID09IEZJMTZfNTU1X1JFRF9NQVNLKSAmJiAoZ3JlZW5fbWFzayA9PSBGSTE2XzU1NV9HUkVFTl9NQVNLKSAmJiAoYmx1ZV9tYXNrID09IEZJMTZfNTU1X0JMVUVfTUFTSykpIHsgXAoJCQlGcmVlSW1hZ2VfQ29udmVydExpbmUjI2Zyb20jI1RvMTZfNTU1KGJpdHMsIHNjYW5saW5lLCBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKSwgRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKSk7IFwKCQl9IGVsc2UgeyBcCgkJCUZyZWVJbWFnZV9Db252ZXJ0TGluZSMjZnJvbSMjVG8xNl81NjUoYml0cywgc2NhbmxpbmUsIEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpLCBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkaWIpKTsgXAoJCX0gXAoJCWJyZWFrOwoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKRklCSVRNQVAgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbG9yUXVhbnRpemUoRklCSVRNQVAgKmRpYiwgRlJFRV9JTUFHRV9RVUFOVElaRSBxdWFudGl6ZSkgewoJcmV0dXJuIEZyZWVJbWFnZV9Db2xvclF1YW50aXplRXgoZGliLCBxdWFudGl6ZSk7Cn0KCkZJQklUTUFQICogRExMX0NBTExDT05WCkZyZWVJbWFnZV9Db2xvclF1YW50aXplRXgoRklCSVRNQVAgKmRpYiwgRlJFRV9JTUFHRV9RVUFOVElaRSBxdWFudGl6ZSwgaW50IFBhbGV0dGVTaXplLCBpbnQgUmVzZXJ2ZVNpemUsIFJHQlFVQUQgKlJlc2VydmVQYWxldHRlKSB7CglpZiggUGFsZXR0ZVNpemUgPCAyICkgUGFsZXR0ZVNpemUgPSAyOwoJaWYoIFBhbGV0dGVTaXplID4gMjU2ICkgUGFsZXR0ZVNpemUgPSAyNTY7CglpZiggUmVzZXJ2ZVNpemUgPCAwICkgUmVzZXJ2ZVNpemUgPSAwOwoJaWYoIFJlc2VydmVTaXplID4gUGFsZXR0ZVNpemUgKSBSZXNlcnZlU2l6ZSA9IFBhbGV0dGVTaXplOwoJaWYgKGRpYikgewoJCWlmIChGcmVlSW1hZ2VfR2V0QlBQKGRpYikgPT0gMjQpIHsKCQkJc3dpdGNoKHF1YW50aXplKSB7CgkJCQljYXNlIEZJUV9XVVFVQU5UIDoKCQkJCXsKCQkJCQl0cnkgewoJCQkJCQlXdVF1YW50aXplciBRIChkaWIpOwoJCQkJCQlGSUJJVE1BUCAqZHN0ID0gUS5RdWFudGl6ZShQYWxldHRlU2l6ZSwgUmVzZXJ2ZVNpemUsIFJlc2VydmVQYWxldHRlKTsKCQkJCQkJaWYoZHN0KSB7CgkJCQkJCQkvLyBjb3B5IG1ldGFkYXRhIGZyb20gc3JjIHRvIGRzdAoJCQkJCQkJRnJlZUltYWdlX0Nsb25lTWV0YWRhdGEoZHN0LCBkaWIpOwoJCQkJCQl9CgkJCQkJCXJldHVybiBkc3Q7CgkJCQkJfSBjYXRjaCAoY29uc3QgY2hhciAqKSB7CgkJCQkJCXJldHVybiBOVUxMOwoJCQkJCX0KCQkJCX0KCQkJCWNhc2UgRklRX05OUVVBTlQgOgoJCQkJewoJCQkJCS8vIHNhbXBsaW5nIGZhY3RvciBpbiByYW5nZSAxLi4zMC4gCgkJCQkJLy8gMSA9PiBzbG93ZXIgKGJ1dCBiZXR0ZXIpLCAzMCA9PiBmYXN0ZXIuIERlZmF1bHQgdmFsdWUgaXMgMQoJCQkJCWNvbnN0IGludCBzYW1wbGluZyA9IDE7CgoJCQkJCU5OUXVhbnRpemVyIFEoUGFsZXR0ZVNpemUpOwoJCQkJCUZJQklUTUFQICpkc3QgPSBRLlF1YW50aXplKGRpYiwgUmVzZXJ2ZVNpemUsIFJlc2VydmVQYWxldHRlLCBzYW1wbGluZyk7CgkJCQkJaWYoZHN0KSB7CgkJCQkJCS8vIGNvcHkgbWV0YWRhdGEgZnJvbSBzcmMgdG8gZHN0CgkJCQkJCUZyZWVJbWFnZV9DbG9uZU1ldGFkYXRhKGRzdCwgZGliKTsKCQkJCQl9CgkJCQkJcmV0dXJuIGRzdDsKCQkJCX0KCQkJfQoJCX0KCX0KCglyZXR1cm4gTlVMTDsKfQoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKRklCSVRNQVAgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRGcm9tUmF3Qml0cyhCWVRFICpiaXRzLCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBwaXRjaCwgdW5zaWduZWQgYnBwLCB1bnNpZ25lZCByZWRfbWFzaywgdW5zaWduZWQgZ3JlZW5fbWFzaywgdW5zaWduZWQgYmx1ZV9tYXNrLCBCT09MIHRvcGRvd24pIHsKCUZJQklUTUFQICpkaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGUod2lkdGgsIGhlaWdodCwgYnBwLCByZWRfbWFzaywgZ3JlZW5fbWFzaywgYmx1ZV9tYXNrKTsKCglpZiAoZGliICE9IE5VTEwpIHsKCQlpZiAodG9wZG93bikgewoJCQlmb3IgKGludCBpID0gaGVpZ2h0IC0gMTsgaSA+PSAwOyAtLWkpIHsKCQkJCW1lbWNweShGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBpKSwgYml0cywgRnJlZUltYWdlX0dldExpbmUoZGliKSk7CgkJCQliaXRzICs9IHBpdGNoOwoJCQl9CgkJfSBlbHNlIHsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBoZWlnaHQ7ICsraSkgewkJCQoJCQkJbWVtY3B5KEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGkpLCBiaXRzLCBGcmVlSW1hZ2VfR2V0TGluZShkaWIpKTsKCQkJCWJpdHMgKz0gcGl0Y2g7CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIGRpYjsKfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRUb1Jhd0JpdHMoQllURSAqYml0cywgRklCSVRNQVAgKmRpYiwgaW50IHBpdGNoLCB1bnNpZ25lZCBicHAsIHVuc2lnbmVkIHJlZF9tYXNrLCB1bnNpZ25lZCBncmVlbl9tYXNrLCB1bnNpZ25lZCBibHVlX21hc2ssIEJPT0wgdG9wZG93bikgewoJaWYgKChkaWIgIT0gTlVMTCkgJiYgKGJpdHMgIT0gTlVMTCkpIHsKCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgRnJlZUltYWdlX0dldEhlaWdodChkaWIpOyArK2kpIHsKCQkJQllURSAqc2NhbmxpbmUgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCB0b3Bkb3duID8gKEZyZWVJbWFnZV9HZXRIZWlnaHQoZGliKSAtIGkgLSAxKSA6IGkpOwoKCQkJaWYgKChicHAgPT0gMTYpICYmIChGcmVlSW1hZ2VfR2V0QlBQKGRpYikgPT0gMTYpKSB7CgkJCQkvLyBjb252ZXJ0IDU1NSB0byA1NjUgb3IgdmljZSB2ZXJzYQoKCQkJCWlmICgocmVkX21hc2sgPT0gRkkxNl81NTVfUkVEX01BU0spICYmIChncmVlbl9tYXNrID09IEZJMTZfNTU1X0dSRUVOX01BU0spICYmIChibHVlX21hc2sgPT0gRkkxNl81NTVfQkxVRV9NQVNLKSkgewoJCQkJCWlmICgoRnJlZUltYWdlX0dldFJlZE1hc2soZGliKSA9PSBGSTE2XzU2NV9SRURfTUFTSykgJiYgKEZyZWVJbWFnZV9HZXRHcmVlbk1hc2soZGliKSA9PSBGSTE2XzU2NV9HUkVFTl9NQVNLKSAmJiAoRnJlZUltYWdlX0dldEJsdWVNYXNrKGRpYikgPT0gRkkxNl81NjVfQkxVRV9NQVNLKSkgewoJCQkJCQlGcmVlSW1hZ2VfQ29udmVydExpbmUxNl81NjVfVG8xNl81NTUoYml0cywgc2NhbmxpbmUsIEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpKTsKCQkJCQl9IGVsc2UgewoJCQkJCQltZW1jcHkoYml0cywgc2NhbmxpbmUsIEZyZWVJbWFnZV9HZXRMaW5lKGRpYikpOwoJCQkJCX0KCQkJCX0gZWxzZSB7CgkJCQkJaWYgKChGcmVlSW1hZ2VfR2V0UmVkTWFzayhkaWIpID09IEZJMTZfNTU1X1JFRF9NQVNLKSAmJiAoRnJlZUltYWdlX0dldEdyZWVuTWFzayhkaWIpID09IEZJMTZfNTU1X0dSRUVOX01BU0spICYmIChGcmVlSW1hZ2VfR2V0Qmx1ZU1hc2soZGliKSA9PSBGSTE2XzU1NV9CTFVFX01BU0spKSB7CgkJCQkJCUZyZWVJbWFnZV9Db252ZXJ0TGluZTE2XzU1NV9UbzE2XzU2NShiaXRzLCBzY2FubGluZSwgRnJlZUltYWdlX0dldFdpZHRoKGRpYikpOwoJCQkJCX0gZWxzZSB7CgkJCQkJCW1lbWNweShiaXRzLCBzY2FubGluZSwgRnJlZUltYWdlX0dldExpbmUoZGliKSk7CgkJCQkJfQoJCQkJfQoJCQl9IGVsc2UgaWYgKEZyZWVJbWFnZV9HZXRCUFAoZGliKSAhPSBicHApIHsKCQkJCXN3aXRjaChGcmVlSW1hZ2VfR2V0QlBQKGRpYikpIHsKCQkJCQljYXNlIDEgOgoJCQkJCQlzd2l0Y2goYnBwKSB7CgkJCQkJCQlDT05WRVJUKDEsIDgpCgkJCQkJCQlDT05WRVJUVE8xNldJVEhQQUxFVFRFKDEpCgkJCQkJCQlDT05WRVJUV0lUSFBBTEVUVEUoMSwgMjQpCgkJCQkJCQlDT05WRVJUV0lUSFBBTEVUVEUoMSwgMzIpCgkJCQkJCX07CgoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSA0IDoKCQkJCQkJc3dpdGNoKGJwcCkgewoJCQkJCQkJQ09OVkVSVCg0LCA4KQoJCQkJCQkJQ09OVkVSVFRPMTZXSVRIUEFMRVRURSg0KQoJCQkJCQkJQ09OVkVSVFdJVEhQQUxFVFRFKDQsIDI0KQoJCQkJCQkJQ09OVkVSVFdJVEhQQUxFVFRFKDQsIDMyKQoJCQkJCQl9OwoKCQkJCQkJYnJlYWs7CgoJCQkJCWNhc2UgOCA6CgkJCQkJCXN3aXRjaChicHApIHsKCQkJCQkJCUNPTlZFUlRUTzE2V0lUSFBBTEVUVEUoOCkKCQkJCQkJCUNPTlZFUlRXSVRIUEFMRVRURSg4LCAyNCkKCQkJCQkJCUNPTlZFUlRXSVRIUEFMRVRURSg4LCAzMikKCQkJCQkJfTsKCgkJCQkJCWJyZWFrOwoKCQkJCQljYXNlIDI0IDoKCQkJCQkJc3dpdGNoKGJwcCkgewoJCQkJCQkJQ09OVkVSVCgyNCwgOCkKCQkJCQkJCUNPTlZFUlRUTzE2KDI0KQoJCQkJCQkJQ09OVkVSVCgyNCwgMzIpCgkJCQkJCX07CgoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAzMiA6CgkJCQkJCXN3aXRjaChicHApIHsKCQkJCQkJCUNPTlZFUlQoMzIsIDgpCgkJCQkJCQlDT05WRVJUVE8xNigzMikKCQkJCQkJCUNPTlZFUlQoMzIsIDI0KQoJCQkJCQl9OwoKCQkJCQkJYnJlYWs7CgkJCQl9OwoJCQl9IGVsc2UgewoJCQkJbWVtY3B5KGJpdHMsIHNjYW5saW5lLCBGcmVlSW1hZ2VfR2V0TGluZShkaWIpKTsKCQkJfQoKCQkJYml0cyArPSBwaXRjaDsKCQl9Cgl9Cn0K