Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBCaXRtYXAgY29udmVyc2lvbiByb3V0aW5lcwovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gRmxvcmlzIHZhbiBkZW4gQmVyZyAoZmx2ZGJlcmdAd3hzLm5sKQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIC0gSmFuaSBLYWphbGEgKGphbmlrQHJlbWVkeS5maSkKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCiNpbmNsdWRlICJVdGlsaXRpZXMuaCIKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiNkZWZpbmUgUkdCNTU1KGIsIGcsIHIpICgoKChiKSA+PiAzKSA8PCBGSTE2XzU1NV9CTFVFX1NISUZUKSB8ICgoKGcpID4+IDMpIDw8IEZJMTZfNTU1X0dSRUVOX1NISUZUKSB8ICgoKHIpID4+IDMpIDw8IEZJMTZfNTU1X1JFRF9TSElGVCkpCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICBpbnRlcm5hbCBjb252ZXJzaW9ucyBYIHRvIDE2IGJpdHMgKDU1NSkKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRMaW5lMVRvMTZfNTU1KEJZVEUgKnRhcmdldCwgQllURSAqc291cmNlLCBpbnQgd2lkdGhfaW5fcGl4ZWxzLCBSR0JRVUFEICpwYWxldHRlKSB7CglXT1JEICpuZXdfYml0cyA9IChXT1JEICopdGFyZ2V0OwoKCWZvciAoaW50IGNvbHMgPSAwOyBjb2xzIDwgd2lkdGhfaW5fcGl4ZWxzOyBjb2xzKyspIHsKCQlpbnQgaW5kZXggPSAoc291cmNlW2NvbHMgPj4gM10gJiAoMHg4MCA+PiAoY29scyAmIDB4MDcpKSkgIT0gMCA/IDEgOiAwOwoKCQluZXdfYml0c1tjb2xzXSA9IFJHQjU1NShwYWxldHRlW2luZGV4XS5yZ2JCbHVlLCBwYWxldHRlW2luZGV4XS5yZ2JHcmVlbiwgcGFsZXR0ZVtpbmRleF0ucmdiUmVkKTsKCX0KfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRMaW5lNFRvMTZfNTU1KEJZVEUgKnRhcmdldCwgQllURSAqc291cmNlLCBpbnQgd2lkdGhfaW5fcGl4ZWxzLCBSR0JRVUFEICpwYWxldHRlKSB7CglXT1JEICpuZXdfYml0cyA9IChXT1JEICopdGFyZ2V0OwoJQk9PTCBsb25pYmJsZSA9IEZBTFNFOwoJaW50IHggPSAwOwoKCWZvciAoaW50IGNvbHMgPSAwOyBjb2xzIDwgd2lkdGhfaW5fcGl4ZWxzOyBjb2xzKyspIHsKCQlSR0JRVUFEICpncmFiX3BhbGV0dGU7CgoJCWlmIChsb25pYmJsZSkgewoJCQlncmFiX3BhbGV0dGUgPSBwYWxldHRlICsgTE9XTklCQkxFKHNvdXJjZVt4KytdKTsKCQl9IGVsc2UgewoJCQlncmFiX3BhbGV0dGUgPSBwYWxldHRlICsgKEhJTklCQkxFKHNvdXJjZVt4XSkgPj4gNCk7CQkJCQkJCQkKCQl9CgoJCW5ld19iaXRzW2NvbHNdID0gUkdCNTU1KGdyYWJfcGFsZXR0ZS0+cmdiQmx1ZSwgZ3JhYl9wYWxldHRlLT5yZ2JHcmVlbiwgZ3JhYl9wYWxldHRlLT5yZ2JSZWQpOwoKCQlsb25pYmJsZSA9ICFsb25pYmJsZTsKCX0KfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRMaW5lOFRvMTZfNTU1KEJZVEUgKnRhcmdldCwgQllURSAqc291cmNlLCBpbnQgd2lkdGhfaW5fcGl4ZWxzLCBSR0JRVUFEICpwYWxldHRlKSB7CglXT1JEICpuZXdfYml0cyA9IChXT1JEICopdGFyZ2V0OwoKCWZvciAoaW50IGNvbHMgPSAwOyBjb2xzIDwgd2lkdGhfaW5fcGl4ZWxzOyBjb2xzKyspIHsKCQlSR0JRVUFEICpncmFiX3BhbGV0dGUgPSBwYWxldHRlICsgc291cmNlW2NvbHNdOwoKCQluZXdfYml0c1tjb2xzXSA9IFJHQjU1NShncmFiX3BhbGV0dGUtPnJnYkJsdWUsIGdyYWJfcGFsZXR0ZS0+cmdiR3JlZW4sIGdyYWJfcGFsZXR0ZS0+cmdiUmVkKTsKCX0KfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRMaW5lMTZfNTY1X1RvMTZfNTU1KEJZVEUgKnRhcmdldCwgQllURSAqc291cmNlLCBpbnQgd2lkdGhfaW5fcGl4ZWxzKSB7CglXT1JEICpzcmNfYml0cyA9IChXT1JEICopc291cmNlOwoJV09SRCAqbmV3X2JpdHMgPSAoV09SRCAqKXRhcmdldDsKCglmb3IgKGludCBjb2xzID0gMDsgY29scyA8IHdpZHRoX2luX3BpeGVsczsgY29scysrKSB7CgkJbmV3X2JpdHNbY29sc10gPSBSR0I1NTUoKCgoc3JjX2JpdHNbY29sc10gJiBGSTE2XzU2NV9CTFVFX01BU0spID4+IEZJMTZfNTY1X0JMVUVfU0hJRlQpICogMHhGRikgLyAweDFGLAoJCQkgICAgICAgICAgICAgICAgICAgICgoKHNyY19iaXRzW2NvbHNdICYgRkkxNl81NjVfR1JFRU5fTUFTSykgPj4gRkkxNl81NjVfR1JFRU5fU0hJRlQpICogMHhGRikgLyAweDNGLAoJCQkJCQkJCSgoKHNyY19iaXRzW2NvbHNdICYgRkkxNl81NjVfUkVEX01BU0spID4+IEZJMTZfNTY1X1JFRF9TSElGVCkgKiAweEZGKSAvIDB4MUYpOwoJfQp9Cgp2b2lkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfQ29udmVydExpbmUyNFRvMTZfNTU1KEJZVEUgKnRhcmdldCwgQllURSAqc291cmNlLCBpbnQgd2lkdGhfaW5fcGl4ZWxzKSB7CglXT1JEICpuZXdfYml0cyA9IChXT1JEICopdGFyZ2V0OwoKCWZvciAoaW50IGNvbHMgPSAwOyBjb2xzIDwgd2lkdGhfaW5fcGl4ZWxzOyBjb2xzKyspIHsKCQluZXdfYml0c1tjb2xzXSA9IFJHQjU1NShzb3VyY2VbRklfUkdCQV9CTFVFXSwgc291cmNlW0ZJX1JHQkFfR1JFRU5dLCBzb3VyY2VbRklfUkdCQV9SRURdKTsKCgkJc291cmNlICs9IDM7Cgl9Cn0KCnZvaWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9Db252ZXJ0TGluZTMyVG8xNl81NTUoQllURSAqdGFyZ2V0LCBCWVRFICpzb3VyY2UsIGludCB3aWR0aF9pbl9waXhlbHMpIHsKCVdPUkQgKm5ld19iaXRzID0gKFdPUkQgKil0YXJnZXQ7CgoJZm9yIChpbnQgY29scyA9IDA7IGNvbHMgPCB3aWR0aF9pbl9waXhlbHM7IGNvbHMrKykgewoJCW5ld19iaXRzW2NvbHNdID0gUkdCNTU1KHNvdXJjZVtGSV9SR0JBX0JMVUVdLCBzb3VyY2VbRklfUkdCQV9HUkVFTl0sIHNvdXJjZVtGSV9SR0JBX1JFRF0pOwoKCQlzb3VyY2UgKz0gNDsKCX0KfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIHNtYXJ0IGNvbnZlcnQgWCB0byAxNiBiaXRzCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkZJQklUTUFQICogRExMX0NBTExDT05WCkZyZWVJbWFnZV9Db252ZXJ0VG8xNkJpdHM1NTUoRklCSVRNQVAgKmRpYikgewoJaWYoIUZyZWVJbWFnZV9IYXNQaXhlbHMoZGliKSB8fCAoRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpICE9IEZJVF9CSVRNQVApKSByZXR1cm4gTlVMTDsKCgljb25zdCBpbnQgd2lkdGggPSBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKTsKCWNvbnN0IGludCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7Cgljb25zdCBpbnQgYnBwID0gRnJlZUltYWdlX0dldEJQUChkaWIpOwoKCWlmKGJwcCA9PSAxNikgewoJCWlmICgoRnJlZUltYWdlX0dldFJlZE1hc2soZGliKSA9PSBGSTE2XzU2NV9SRURfTUFTSykgJiYgKEZyZWVJbWFnZV9HZXRHcmVlbk1hc2soZGliKSA9PSBGSTE2XzU2NV9HUkVFTl9NQVNLKSAmJiAoRnJlZUltYWdlX0dldEJsdWVNYXNrKGRpYikgPT0gRkkxNl81NjVfQkxVRV9NQVNLKSkgewoJCQkvLyBSR0IgNTY1CgkJCUZJQklUTUFQICpuZXdfZGliID0gRnJlZUltYWdlX0FsbG9jYXRlKHdpZHRoLCBoZWlnaHQsIDE2LCBGSTE2XzU1NV9SRURfTUFTSywgRkkxNl81NTVfR1JFRU5fTUFTSywgRkkxNl81NTVfQkxVRV9NQVNLKTsKCQkJaWYobmV3X2RpYiA9PSBOVUxMKSB7CgkJCQlyZXR1cm4gTlVMTDsKCQkJfQoJCQlmb3IgKGludCByb3dzID0gMDsgcm93cyA8IGhlaWdodDsgcm93cysrKSB7CgkJCQlGcmVlSW1hZ2VfQ29udmVydExpbmUxNl81NjVfVG8xNl81NTUoRnJlZUltYWdlX0dldFNjYW5MaW5lKG5ld19kaWIsIHJvd3MpLCBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCByb3dzKSwgd2lkdGgpOwoJCQl9CgoJCQkvLyBjb3B5IG1ldGFkYXRhIGZyb20gc3JjIHRvIGRzdAoJCQlGcmVlSW1hZ2VfQ2xvbmVNZXRhZGF0YShuZXdfZGliLCBkaWIpOwoKCQkJcmV0dXJuIG5ld19kaWI7CgkJfSBlbHNlIHsKCQkJLy8gUkdCIDU1NQoJCQlyZXR1cm4gRnJlZUltYWdlX0Nsb25lKGRpYik7CgkJfQoJfQoJZWxzZSB7CgkJLy8gb3RoZXIgYnBwIGNhc2VzID0+IGNvbnZlcnQgdG8gUkdCIDU1NQoJCUZJQklUTUFQICpuZXdfZGliID0gRnJlZUltYWdlX0FsbG9jYXRlKHdpZHRoLCBoZWlnaHQsIDE2LCBGSTE2XzU1NV9SRURfTUFTSywgRkkxNl81NTVfR1JFRU5fTUFTSywgRkkxNl81NTVfQkxVRV9NQVNLKTsKCQlpZihuZXdfZGliID09IE5VTEwpIHsKCQkJcmV0dXJuIE5VTEw7CgkJfQoKCQkvLyBjb3B5IG1ldGFkYXRhIGZyb20gc3JjIHRvIGRzdAoJCUZyZWVJbWFnZV9DbG9uZU1ldGFkYXRhKG5ld19kaWIsIGRpYik7CgoJCXN3aXRjaCAoYnBwKSB7CgkJCWNhc2UgMSA6CgkJCXsKCQkJCWZvciAoaW50IHJvd3MgPSAwOyByb3dzIDwgaGVpZ2h0OyByb3dzKyspIHsKCQkJCQlGcmVlSW1hZ2VfQ29udmVydExpbmUxVG8xNl81NTUoRnJlZUltYWdlX0dldFNjYW5MaW5lKG5ld19kaWIsIHJvd3MpLCBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCByb3dzKSwgd2lkdGgsIEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYikpOwoJCQkJfQoKCQkJCXJldHVybiBuZXdfZGliOwoJCQl9CgoJCQljYXNlIDQgOgoJCQl7CgkJCQlmb3IgKGludCByb3dzID0gMDsgcm93cyA8IGhlaWdodDsgcm93cysrKSB7CgkJCQkJRnJlZUltYWdlX0NvbnZlcnRMaW5lNFRvMTZfNTU1KEZyZWVJbWFnZV9HZXRTY2FuTGluZShuZXdfZGliLCByb3dzKSwgRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgcm93cyksIHdpZHRoLCBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkaWIpKTsKCQkJCX0KCgkJCQlyZXR1cm4gbmV3X2RpYjsKCQkJfQoKCQkJY2FzZSA4IDoKCQkJewoJCQkJZm9yIChpbnQgcm93cyA9IDA7IHJvd3MgPCBoZWlnaHQ7IHJvd3MrKykgewoJCQkJCUZyZWVJbWFnZV9Db252ZXJ0TGluZThUbzE2XzU1NShGcmVlSW1hZ2VfR2V0U2NhbkxpbmUobmV3X2RpYiwgcm93cyksIEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHJvd3MpLCB3aWR0aCwgRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKSk7CgkJCQl9CgoJCQkJcmV0dXJuIG5ld19kaWI7CgkJCX0KCgkJCWNhc2UgMjQgOgoJCQl7CgkJCQlmb3IgKGludCByb3dzID0gMDsgcm93cyA8IGhlaWdodDsgcm93cysrKSB7CgkJCQkJRnJlZUltYWdlX0NvbnZlcnRMaW5lMjRUbzE2XzU1NShGcmVlSW1hZ2VfR2V0U2NhbkxpbmUobmV3X2RpYiwgcm93cyksIEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHJvd3MpLCB3aWR0aCk7CgkJCQl9CgoJCQkJcmV0dXJuIG5ld19kaWI7CgkJCX0KCgkJCWNhc2UgMzIgOgoJCQl7CgkJCQlmb3IgKGludCByb3dzID0gMDsgcm93cyA8IGhlaWdodDsgcm93cysrKSB7CgkJCQkJRnJlZUltYWdlX0NvbnZlcnRMaW5lMzJUbzE2XzU1NShGcmVlSW1hZ2VfR2V0U2NhbkxpbmUobmV3X2RpYiwgcm93cyksIEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHJvd3MpLCB3aWR0aCk7CgkJCQl9CgoJCQkJcmV0dXJuIG5ld19kaWI7CgkJCX0KCgkJCWRlZmF1bHQgOgoJCQkJLy8gdW5yZWFjaGFibGUgY29kZSAuLi4KCQkJCUZyZWVJbWFnZV9VbmxvYWQobmV3X2RpYik7CgkJCQlicmVhazsKCgkJfQoJfQoKCXJldHVybiBOVUxMOwp9Cg==