Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBQaXhlbCBhY2Nlc3MgZnVuY3Rpb25zCi8vCi8vIERlc2lnbiBhbmQgaW1wbGVtZW50YXRpb24gYnkKLy8gLSBGbG9yaXMgdmFuIGRlbiBCZXJnIChmbHZkYmVyZ0B3eHMubmwpCi8vIC0gSGVydukgRHJvbG9uIChkcm9sb25AaW5mb25pZS5mcikKLy8gLSBSeWFuIFJ1YmxleSAocnlhbkBsb3N0cmVhbGl0eS5vcmcpCi8vIC0gUmlsZXkgTWNOaWZmIChybWNuaWZmQG1hcmV4Z3JvdXAuY29tKQovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiBGcmVlSW1hZ2UgMwovLwovLyBDT1ZFUkVEIENPREUgSVMgUFJPVklERUQgVU5ERVIgVEhJUyBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVFkKLy8gT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFdBUlJBTlRJRVMKLy8gVEhBVCBUSEUgQ09WRVJFRCBDT0RFIElTIEZSRUUgT0YgREVGRUNUUywgTUVSQ0hBTlRBQkxFLCBGSVQgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi8vIE9SIE5PTi1JTkZSSU5HSU5HLiBUSEUgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBDT1ZFUkVECi8vIENPREUgSVMgV0lUSCBZT1UuIFNIT1VMRCBBTlkgQ09WRVJFRCBDT0RFIFBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgWU9VIChOT1QKLy8gVEhFIElOSVRJQUwgREVWRUxPUEVSIE9SIEFOWSBPVEhFUiBDT05UUklCVVRPUikgQVNTVU1FIFRIRSBDT1NUIE9GIEFOWSBORUNFU1NBUlkKLy8gU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOIEVTU0VOVElBTAovLyBQQVJUIE9GIFRISVMgTElDRU5TRS4gTk8gVVNFIE9GIEFOWSBDT1ZFUkVEIENPREUgSVMgQVVUSE9SSVpFRCBIRVJFVU5ERVIgRVhDRVBUIFVOREVSCi8vIFRISVMgRElTQ0xBSU1FUi4KLy8KLy8gVXNlIGF0IHlvdXIgb3duIHJpc2shCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpbmNsdWRlICJGcmVlSW1hZ2UuaCIKI2luY2x1ZGUgIlV0aWxpdGllcy5oIgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKQllURSAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoRklCSVRNQVAgKmRpYiwgaW50IHNjYW5saW5lKSB7CglpZighRnJlZUltYWdlX0hhc1BpeGVscyhkaWIpKSB7CgkJcmV0dXJuIE5VTEw7Cgl9CglyZXR1cm4gQ2FsY3VsYXRlU2NhbkxpbmUoRnJlZUltYWdlX0dldEJpdHMoZGliKSwgRnJlZUltYWdlX0dldFBpdGNoKGRpYiksIHNjYW5saW5lKTsKfQoKQk9PTCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldFBpeGVsSW5kZXgoRklCSVRNQVAgKmRpYiwgdW5zaWduZWQgeCwgdW5zaWduZWQgeSwgQllURSAqdmFsdWUpIHsKCUJZVEUgc2hpZnQ7CgoJaWYoIUZyZWVJbWFnZV9IYXNQaXhlbHMoZGliKSB8fCAoRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpICE9IEZJVF9CSVRNQVApKQoJCXJldHVybiBGQUxTRTsKCglpZigoeCA8IEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpKSAmJiAoeSA8IEZyZWVJbWFnZV9HZXRIZWlnaHQoZGliKSkpIHsKCQlCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgeSk7CgoJCXN3aXRjaChGcmVlSW1hZ2VfR2V0QlBQKGRpYikpIHsKCQkJY2FzZSAxOgoJCQkJKnZhbHVlID0gKGJpdHNbeCA+PiAzXSAmICgweDgwID4+ICh4ICYgMHgwNykpKSAhPSAwOwoJCQkJYnJlYWs7CgkJCWNhc2UgNDoKCQkJCXNoaWZ0ID0gKEJZVEUpKCgxIC0geCAlIDIpIDw8IDIpOwoJCQkJKnZhbHVlID0gKGJpdHNbeCA+PiAxXSAmICgweDBGIDw8IHNoaWZ0KSkgPj4gc2hpZnQ7CgkJCQlicmVhazsKCQkJY2FzZSA4OgoJCQkJKnZhbHVlID0gYml0c1t4XTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJcmV0dXJuIEZBTFNFOwoJCX0KCgkJcmV0dXJuIFRSVUU7Cgl9CgoJcmV0dXJuIEZBTFNFOwp9CgpCT09MIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0UGl4ZWxDb2xvcihGSUJJVE1BUCAqZGliLCB1bnNpZ25lZCB4LCB1bnNpZ25lZCB5LCBSR0JRVUFEICp2YWx1ZSkgewoJaWYoIUZyZWVJbWFnZV9IYXNQaXhlbHMoZGliKSB8fCAoRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpICE9IEZJVF9CSVRNQVApKQoJCXJldHVybiBGQUxTRTsKCglpZigoeCA8IEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpKSAmJiAoeSA8IEZyZWVJbWFnZV9HZXRIZWlnaHQoZGliKSkpIHsKCQlCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgeSk7CgoJCXN3aXRjaChGcmVlSW1hZ2VfR2V0QlBQKGRpYikpIHsKCQkJY2FzZSAxNjoKCQkJewoJCQkJYml0cyArPSAyKng7CgkJCQlXT1JEICpwaXhlbCA9IChXT1JEICopYml0czsKCQkJCWlmKChGcmVlSW1hZ2VfR2V0UmVkTWFzayhkaWIpID09IEZJMTZfNTY1X1JFRF9NQVNLKSAmJiAoRnJlZUltYWdlX0dldEdyZWVuTWFzayhkaWIpID09IEZJMTZfNTY1X0dSRUVOX01BU0spICYmIChGcmVlSW1hZ2VfR2V0Qmx1ZU1hc2soZGliKSA9PSBGSTE2XzU2NV9CTFVFX01BU0spKSB7CgkJCQkJdmFsdWUtPnJnYkJsdWUJCT0gKEJZVEUpKCgoKCpwaXhlbCAmIEZJMTZfNTY1X0JMVUVfTUFTSykgPj4gRkkxNl81NjVfQkxVRV9TSElGVCkgKiAweEZGKSAvIDB4MUYpOwoJCQkJCXZhbHVlLT5yZ2JHcmVlbgkJPSAoQllURSkoKCgoKnBpeGVsICYgRkkxNl81NjVfR1JFRU5fTUFTSykgPj4gRkkxNl81NjVfR1JFRU5fU0hJRlQpICogMHhGRikgLyAweDNGKTsKCQkJCQl2YWx1ZS0+cmdiUmVkCQk9IChCWVRFKSgoKCgqcGl4ZWwgJiBGSTE2XzU2NV9SRURfTUFTSykgPj4gRkkxNl81NjVfUkVEX1NISUZUKSAqIDB4RkYpIC8gMHgxRik7CgkJCQkJdmFsdWUtPnJnYlJlc2VydmVkCT0gMDsKCQkJCX0gZWxzZSB7CgkJCQkJdmFsdWUtPnJnYkJsdWUJCT0gKEJZVEUpKCgoKCpwaXhlbCAmIEZJMTZfNTU1X0JMVUVfTUFTSykgPj4gRkkxNl81NTVfQkxVRV9TSElGVCkgKiAweEZGKSAvIDB4MUYpOwoJCQkJCXZhbHVlLT5yZ2JHcmVlbgkJPSAoQllURSkoKCgoKnBpeGVsICYgRkkxNl81NTVfR1JFRU5fTUFTSykgPj4gRkkxNl81NTVfR1JFRU5fU0hJRlQpICogMHhGRikgLyAweDFGKTsKCQkJCQl2YWx1ZS0+cmdiUmVkCQk9IChCWVRFKSgoKCgqcGl4ZWwgJiBGSTE2XzU1NV9SRURfTUFTSykgPj4gRkkxNl81NTVfUkVEX1NISUZUKSAqIDB4RkYpIC8gMHgxRik7CgkJCQkJdmFsdWUtPnJnYlJlc2VydmVkCT0gMDsKCQkJCX0KCQkJCWJyZWFrOwoJCQl9CgkJCWNhc2UgMjQ6CgkJCQliaXRzICs9IDMqeDsKCQkJCXZhbHVlLT5yZ2JCbHVlCQk9IGJpdHNbRklfUkdCQV9CTFVFXTsJLy8gQgoJCQkJdmFsdWUtPnJnYkdyZWVuCQk9IGJpdHNbRklfUkdCQV9HUkVFTl07CS8vIEcKCQkJCXZhbHVlLT5yZ2JSZWQJCT0gYml0c1tGSV9SR0JBX1JFRF07CS8vIFIKCQkJCXZhbHVlLT5yZ2JSZXNlcnZlZAk9IDA7CgkJCQlicmVhazsKCQkJY2FzZSAzMjoKCQkJCWJpdHMgKz0gNCp4OwoJCQkJdmFsdWUtPnJnYkJsdWUJCT0gYml0c1tGSV9SR0JBX0JMVUVdOwkvLyBCCgkJCQl2YWx1ZS0+cmdiR3JlZW4JCT0gYml0c1tGSV9SR0JBX0dSRUVOXTsJLy8gRwoJCQkJdmFsdWUtPnJnYlJlZAkJPSBiaXRzW0ZJX1JHQkFfUkVEXTsJLy8gUgoJCQkJdmFsdWUtPnJnYlJlc2VydmVkCT0gYml0c1tGSV9SR0JBX0FMUEhBXTsJLy8gQQoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlyZXR1cm4gRkFMU0U7CgkJfQoKCQlyZXR1cm4gVFJVRTsKCX0KCglyZXR1cm4gRkFMU0U7Cn0KCkJPT0wgRExMX0NBTExDT05WCkZyZWVJbWFnZV9TZXRQaXhlbEluZGV4KEZJQklUTUFQICpkaWIsIHVuc2lnbmVkIHgsIHVuc2lnbmVkIHksIEJZVEUgKnZhbHVlKSB7CglCWVRFIHNoaWZ0OwoKCWlmKCFGcmVlSW1hZ2VfSGFzUGl4ZWxzKGRpYikgfHwgKEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoZGliKSAhPSBGSVRfQklUTUFQKSkKCQlyZXR1cm4gRkFMU0U7CgoJaWYoKHggPCBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKSkgJiYgKHkgPCBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYikpKSB7CgkJQllURSAqYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHkpOwoKCQlzd2l0Y2goRnJlZUltYWdlX0dldEJQUChkaWIpKSB7CgkJCWNhc2UgMToKCQkJCSp2YWx1ZSA/IGJpdHNbeCA+PiAzXSB8PSAoMHg4MCA+PiAoeCAmIDB4NykpIDogYml0c1t4ID4+IDNdICY9ICgweEZGN0YgPj4gKHggJiAweDcpKTsKCQkJCWJyZWFrOwoJCQljYXNlIDQ6CgkJCQlzaGlmdCA9IChCWVRFKSgoMSAtIHggJSAyKSA8PCAyKTsKCQkJCWJpdHNbeCA+PiAxXSAmPSB+KDB4MEYgPDwgc2hpZnQpOwoJCQkJYml0c1t4ID4+IDFdIHw9ICgoKnZhbHVlICYgMHgwRikgPDwgc2hpZnQpOwoJCQkJYnJlYWs7CgkJCWNhc2UgODoKCQkJCWJpdHNbeF0gPSAqdmFsdWU7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCXJldHVybiBGQUxTRTsKCQl9CgoJCXJldHVybiBUUlVFOwoJfQoKCXJldHVybiBGQUxTRTsKfQoKQk9PTCBETExfQ0FMTENPTlYKRnJlZUltYWdlX1NldFBpeGVsQ29sb3IoRklCSVRNQVAgKmRpYiwgdW5zaWduZWQgeCwgdW5zaWduZWQgeSwgUkdCUVVBRCAqdmFsdWUpIHsKCWlmKCFGcmVlSW1hZ2VfSGFzUGl4ZWxzKGRpYikgfHwgKEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoZGliKSAhPSBGSVRfQklUTUFQKSkKCQlyZXR1cm4gRkFMU0U7CgoJaWYoKHggPCBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKSkgJiYgKHkgPCBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYikpKSB7CgkJQllURSAqYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHkpOwoKCQlzd2l0Y2goRnJlZUltYWdlX0dldEJQUChkaWIpKSB7CgkJCWNhc2UgMTY6CgkJCXsKCQkJCWJpdHMgKz0gMip4OwoJCQkJV09SRCAqcGl4ZWwgPSAoV09SRCAqKWJpdHM7CgkJCQlpZigoRnJlZUltYWdlX0dldFJlZE1hc2soZGliKSA9PSBGSTE2XzU2NV9SRURfTUFTSykgJiYgKEZyZWVJbWFnZV9HZXRHcmVlbk1hc2soZGliKSA9PSBGSTE2XzU2NV9HUkVFTl9NQVNLKSAmJiAoRnJlZUltYWdlX0dldEJsdWVNYXNrKGRpYikgPT0gRkkxNl81NjVfQkxVRV9NQVNLKSkgewoJCQkJCSpwaXhlbCA9ICgodmFsdWUtPnJnYkJsdWUgPj4gMykgPDwgRkkxNl81NjVfQkxVRV9TSElGVCkgfAoJCQkJCQkoKHZhbHVlLT5yZ2JHcmVlbiA+PiAyKSA8PCBGSTE2XzU2NV9HUkVFTl9TSElGVCkgfAoJCQkJCQkoKHZhbHVlLT5yZ2JSZWQgPj4gMykgPDwgRkkxNl81NjVfUkVEX1NISUZUKTsKCQkJCX0gZWxzZSB7CgkJCQkJKnBpeGVsID0gKCh2YWx1ZS0+cmdiQmx1ZSA+PiAzKSA8PCBGSTE2XzU1NV9CTFVFX1NISUZUKSB8CgkJCQkJCSgodmFsdWUtPnJnYkdyZWVuID4+IDMpIDw8IEZJMTZfNTU1X0dSRUVOX1NISUZUKSB8CgkJCQkJCSgodmFsdWUtPnJnYlJlZCA+PiAzKSA8PCBGSTE2XzU1NV9SRURfU0hJRlQpOwoJCQkJfQoJCQkJYnJlYWs7CgkJCX0KCQkJY2FzZSAyNDoKCQkJCWJpdHMgKz0gMyp4OwoJCQkJYml0c1tGSV9SR0JBX0JMVUVdCT0gdmFsdWUtPnJnYkJsdWU7CS8vIEIKCQkJCWJpdHNbRklfUkdCQV9HUkVFTl0gPSB2YWx1ZS0+cmdiR3JlZW47CS8vIEcKCQkJCWJpdHNbRklfUkdCQV9SRURdCT0gdmFsdWUtPnJnYlJlZDsJLy8gUgoJCQkJYnJlYWs7CgkJCWNhc2UgMzI6CgkJCQliaXRzICs9IDQqeDsKCQkJCWJpdHNbRklfUkdCQV9CTFVFXQk9IHZhbHVlLT5yZ2JCbHVlOwkJLy8gQgoJCQkJYml0c1tGSV9SR0JBX0dSRUVOXSA9IHZhbHVlLT5yZ2JHcmVlbjsJCS8vIEcKCQkJCWJpdHNbRklfUkdCQV9SRURdCT0gdmFsdWUtPnJnYlJlZDsJCS8vIFIKCQkJCWJpdHNbRklfUkdCQV9BTFBIQV0gPSB2YWx1ZS0+cmdiUmVzZXJ2ZWQ7CS8vIEEKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJcmV0dXJuIEZBTFNFOwoJCX0KCgkJcmV0dXJuIFRSVUU7Cgl9CgoJcmV0dXJuIEZBTFNFOwp9Cgo=