Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBCaXRtYXAgY29udmVyc2lvbiByb3V0aW5lcwovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gRmxvcmlzIHZhbiBkZW4gQmVyZyAoZmx2ZGJlcmdAd3hzLm5sKQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIC0gSmFuaSBLYWphbGEgKGphbmlrQHJlbWVkeS5maSkKLy8gLSBEZXRsZXYgVmVuZHQgKGRldGxldi52ZW5kdEBicmlsbGl0LmRlKQovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiBGcmVlSW1hZ2UgMwovLwovLyBDT1ZFUkVEIENPREUgSVMgUFJPVklERUQgVU5ERVIgVEhJUyBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVFkKLy8gT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFdBUlJBTlRJRVMKLy8gVEhBVCBUSEUgQ09WRVJFRCBDT0RFIElTIEZSRUUgT0YgREVGRUNUUywgTUVSQ0hBTlRBQkxFLCBGSVQgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi8vIE9SIE5PTi1JTkZSSU5HSU5HLiBUSEUgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBDT1ZFUkVECi8vIENPREUgSVMgV0lUSCBZT1UuIFNIT1VMRCBBTlkgQ09WRVJFRCBDT0RFIFBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgWU9VIChOT1QKLy8gVEhFIElOSVRJQUwgREVWRUxPUEVSIE9SIEFOWSBPVEhFUiBDT05UUklCVVRPUikgQVNTVU1FIFRIRSBDT1NUIE9GIEFOWSBORUNFU1NBUlkKLy8gU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOIEVTU0VOVElBTAovLyBQQVJUIE9GIFRISVMgTElDRU5TRS4gTk8gVVNFIE9GIEFOWSBDT1ZFUkVEIENPREUgSVMgQVVUSE9SSVpFRCBIRVJFVU5ERVIgRVhDRVBUIFVOREVSCi8vIFRISVMgRElTQ0xBSU1FUi4KLy8KLy8gVXNlIGF0IHlvdXIgb3duIHJpc2shCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpbmNsdWRlICJGcmVlSW1hZ2UuaCIKI2luY2x1ZGUgIlV0aWxpdGllcy5oIgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgaW50ZXJuYWwgY29udmVyc2lvbnMgWCB0byAzMiBiaXRzCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9Db252ZXJ0TGluZTFUbzMyKEJZVEUgKnRhcmdldCwgQllURSAqc291cmNlLCBpbnQgd2lkdGhfaW5fcGl4ZWxzLCBSR0JRVUFEICpwYWxldHRlKSB7Cglmb3IgKGludCBjb2xzID0gMDsgY29scyA8IHdpZHRoX2luX3BpeGVsczsgY29scysrKSB7CgkJaW50IGluZGV4ID0gKHNvdXJjZVtjb2xzPj4zXSAmICgweDgwID4+IChjb2xzICYgMHgwNykpKSAhPSAwID8gMSA6IDA7CgoJCXRhcmdldFtGSV9SR0JBX0JMVUVdCT0gcGFsZXR0ZVtpbmRleF0ucmdiQmx1ZTsKCQl0YXJnZXRbRklfUkdCQV9HUkVFTl0JPSBwYWxldHRlW2luZGV4XS5yZ2JHcmVlbjsKCQl0YXJnZXRbRklfUkdCQV9SRURdCQk9IHBhbGV0dGVbaW5kZXhdLnJnYlJlZDsKCQl0YXJnZXRbRklfUkdCQV9BTFBIQV0JPSAweEZGOwoJCXRhcmdldCArPSA0OwoJfQkKfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRMaW5lNFRvMzIoQllURSAqdGFyZ2V0LCBCWVRFICpzb3VyY2UsIGludCB3aWR0aF9pbl9waXhlbHMsIFJHQlFVQUQgKnBhbGV0dGUpIHsKCUJPT0wgbG93X25pYmJsZSA9IEZBTFNFOwoJaW50IHggPSAwOwoKCWZvciAoaW50IGNvbHMgPSAwIDsgY29scyA8IHdpZHRoX2luX3BpeGVscyA7ICsrY29scykgewoJCWlmIChsb3dfbmliYmxlKSB7CgkJCXRhcmdldFtGSV9SR0JBX0JMVUVdCT0gcGFsZXR0ZVtMT1dOSUJCTEUoc291cmNlW3hdKV0ucmdiQmx1ZTsKCQkJdGFyZ2V0W0ZJX1JHQkFfR1JFRU5dCT0gcGFsZXR0ZVtMT1dOSUJCTEUoc291cmNlW3hdKV0ucmdiR3JlZW47CgkJCXRhcmdldFtGSV9SR0JBX1JFRF0JCT0gcGFsZXR0ZVtMT1dOSUJCTEUoc291cmNlW3hdKV0ucmdiUmVkOwoKCQkJeCsrOwoJCX0gZWxzZSB7CgkJCXRhcmdldFtGSV9SR0JBX0JMVUVdCT0gcGFsZXR0ZVtISU5JQkJMRShzb3VyY2VbeF0pID4+IDRdLnJnYkJsdWU7CgkJCXRhcmdldFtGSV9SR0JBX0dSRUVOXQk9IHBhbGV0dGVbSElOSUJCTEUoc291cmNlW3hdKSA+PiA0XS5yZ2JHcmVlbjsKCQkJdGFyZ2V0W0ZJX1JHQkFfUkVEXQkJPSBwYWxldHRlW0hJTklCQkxFKHNvdXJjZVt4XSkgPj4gNF0ucmdiUmVkOwoJCX0KCgkJbG93X25pYmJsZSA9ICFsb3dfbmliYmxlOwoKCQl0YXJnZXRbRklfUkdCQV9BTFBIQV0gPSAweEZGOwoJCXRhcmdldCArPSA0OwoJfQp9Cgp2b2lkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfQ29udmVydExpbmU4VG8zMihCWVRFICp0YXJnZXQsIEJZVEUgKnNvdXJjZSwgaW50IHdpZHRoX2luX3BpeGVscywgUkdCUVVBRCAqcGFsZXR0ZSkgewoJZm9yIChpbnQgY29scyA9IDA7IGNvbHMgPCB3aWR0aF9pbl9waXhlbHM7IGNvbHMrKykgewoJCXRhcmdldFtGSV9SR0JBX0JMVUVdCT0gcGFsZXR0ZVtzb3VyY2VbY29sc11dLnJnYkJsdWU7CgkJdGFyZ2V0W0ZJX1JHQkFfR1JFRU5dCT0gcGFsZXR0ZVtzb3VyY2VbY29sc11dLnJnYkdyZWVuOwoJCXRhcmdldFtGSV9SR0JBX1JFRF0JCT0gcGFsZXR0ZVtzb3VyY2VbY29sc11dLnJnYlJlZDsKCQl0YXJnZXRbRklfUkdCQV9BTFBIQV0JPSAweEZGOwoJCXRhcmdldCArPSA0OwoJfQp9Cgp2b2lkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfQ29udmVydExpbmUxNlRvMzJfNTU1KEJZVEUgKnRhcmdldCwgQllURSAqc291cmNlLCBpbnQgd2lkdGhfaW5fcGl4ZWxzKSB7CglXT1JEICpiaXRzID0gKFdPUkQgKilzb3VyY2U7CgoJZm9yIChpbnQgY29scyA9IDA7IGNvbHMgPCB3aWR0aF9pbl9waXhlbHM7IGNvbHMrKykgewoJCXRhcmdldFtGSV9SR0JBX1JFRF0gICA9IChCWVRFKSgoKChiaXRzW2NvbHNdICYgRkkxNl81NTVfUkVEX01BU0spID4+IEZJMTZfNTU1X1JFRF9TSElGVCkgKiAweEZGKSAvIDB4MUYpOwoJCXRhcmdldFtGSV9SR0JBX0dSRUVOXSA9IChCWVRFKSgoKChiaXRzW2NvbHNdICYgRkkxNl81NTVfR1JFRU5fTUFTSykgPj4gRkkxNl81NTVfR1JFRU5fU0hJRlQpICogMHhGRikgLyAweDFGKTsKCQl0YXJnZXRbRklfUkdCQV9CTFVFXSAgPSAoQllURSkoKCgoYml0c1tjb2xzXSAmIEZJMTZfNTU1X0JMVUVfTUFTSykgPj4gRkkxNl81NTVfQkxVRV9TSElGVCkgKiAweEZGKSAvIDB4MUYpOwoJCXRhcmdldFtGSV9SR0JBX0FMUEhBXSA9IDB4RkY7CgkJdGFyZ2V0ICs9IDQ7Cgl9Cn0KCnZvaWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9Db252ZXJ0TGluZTE2VG8zMl81NjUoQllURSAqdGFyZ2V0LCBCWVRFICpzb3VyY2UsIGludCB3aWR0aF9pbl9waXhlbHMpIHsKCVdPUkQgKmJpdHMgPSAoV09SRCAqKXNvdXJjZTsKCglmb3IgKGludCBjb2xzID0gMDsgY29scyA8IHdpZHRoX2luX3BpeGVsczsgY29scysrKSB7CgkJdGFyZ2V0W0ZJX1JHQkFfUkVEXSAgID0gKEJZVEUpKCgoKGJpdHNbY29sc10gJiBGSTE2XzU2NV9SRURfTUFTSykgPj4gRkkxNl81NjVfUkVEX1NISUZUKSAqIDB4RkYpIC8gMHgxRik7CgkJdGFyZ2V0W0ZJX1JHQkFfR1JFRU5dID0gKEJZVEUpKCgoKGJpdHNbY29sc10gJiBGSTE2XzU2NV9HUkVFTl9NQVNLKSA+PiBGSTE2XzU2NV9HUkVFTl9TSElGVCkgKiAweEZGKSAvIDB4M0YpOwoJCXRhcmdldFtGSV9SR0JBX0JMVUVdICA9IChCWVRFKSgoKChiaXRzW2NvbHNdICYgRkkxNl81NjVfQkxVRV9NQVNLKSA+PiBGSTE2XzU2NV9CTFVFX1NISUZUKSAqIDB4RkYpIC8gMHgxRik7CgkJdGFyZ2V0W0ZJX1JHQkFfQUxQSEFdID0gMHhGRjsKCQl0YXJnZXQgKz0gNDsKCX0KfQovKgp2b2lkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfQ29udmVydExpbmUyNFRvMzIoQllURSAqdGFyZ2V0LCBCWVRFICpzb3VyY2UsIGludCB3aWR0aF9pbl9waXhlbHMpIHsKCWZvciAoaW50IGNvbHMgPSAwOyBjb2xzIDwgd2lkdGhfaW5fcGl4ZWxzOyBjb2xzKyspIHsKCQkqKERXT1JEICopdGFyZ2V0ID0gKCooRFdPUkQgKikgc291cmNlICYgRklfUkdCQV9SR0JfTUFTSykgfCBGSV9SR0JBX0FMUEhBX01BU0s7CgkJdGFyZ2V0ICs9IDQ7CgkJc291cmNlICs9IDM7Cgl9Cn0KKi8KLyoqClRoaXMgdW5vcHRpbWl6ZWQgdmVyc2lvbiBvZiB0aGUgY29udmVyc2lvbiBmdW5jdGlvbiBhdm9pZCBhbiB1bmRldGVybWluZWQgYnVnIHdpdGggVkMrKyBTUDYuIApUaGUgYnVnIG9jY3VycyBpbiByZWxlYXNlIG1vZGUgb25seSwgd2hlbiB0aGUgaW1hZ2UgaGVpZ2h0IGlzIGVxdWFsIHRvIDUzNyAKKHRyeSBlLmcuIGEgc2l6ZSBvZiA0MzJ4NTM3IHRvIHJlcHJvZHVjZSB0aGUgYnVnIHdpdGggdGhlIG9wdGltaXplZCBmdW5jdGlvbikuCiovCnZvaWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9Db252ZXJ0TGluZTI0VG8zMihCWVRFICp0YXJnZXQsIEJZVEUgKnNvdXJjZSwgaW50IHdpZHRoX2luX3BpeGVscykgewoJZm9yIChpbnQgY29scyA9IDA7IGNvbHMgPCB3aWR0aF9pbl9waXhlbHM7IGNvbHMrKykgewoJCXRhcmdldFtGSV9SR0JBX1JFRF0gICA9IHNvdXJjZVtGSV9SR0JBX1JFRF07CgkJdGFyZ2V0W0ZJX1JHQkFfR1JFRU5dID0gc291cmNlW0ZJX1JHQkFfR1JFRU5dOwoJCXRhcmdldFtGSV9SR0JBX0JMVUVdICA9IHNvdXJjZVtGSV9SR0JBX0JMVUVdOwoJCXRhcmdldFtGSV9SR0JBX0FMUEhBXSA9IDB4RkY7CgkJdGFyZ2V0ICs9IDQ7CgkJc291cmNlICs9IDM7Cgl9Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmlubGluZSB2b2lkIApGcmVlSW1hZ2VfQ29udmVydExpbmUxVG8zMk1hcFRyYW5zcGFyZW5jeShCWVRFICp0YXJnZXQsIEJZVEUgKnNvdXJjZSwgaW50IHdpZHRoX2luX3BpeGVscywgUkdCUVVBRCAqcGFsZXR0ZSwgQllURSAqdGFibGUsIGludCB0cmFuc3BhcmVudF9waXhlbHMpIHsKCWZvciAoaW50IGNvbHMgPSAwOyBjb2xzIDwgd2lkdGhfaW5fcGl4ZWxzOyBjb2xzKyspIHsKCQlpbnQgaW5kZXggPSAoc291cmNlW2NvbHM+PjNdICYgKDB4ODAgPj4gKGNvbHMgJiAweDA3KSkpICE9IDAgPyAxIDogMDsKCgkJdGFyZ2V0W0ZJX1JHQkFfQkxVRV0JPSBwYWxldHRlW2luZGV4XS5yZ2JCbHVlOwoJCXRhcmdldFtGSV9SR0JBX0dSRUVOXQk9IHBhbGV0dGVbaW5kZXhdLnJnYkdyZWVuOwoJCXRhcmdldFtGSV9SR0JBX1JFRF0JCT0gcGFsZXR0ZVtpbmRleF0ucmdiUmVkOwoJCXRhcmdldFtGSV9SR0JBX0FMUEhBXSA9IChpbmRleCA8IHRyYW5zcGFyZW50X3BpeGVscykgPyB0YWJsZVtpbmRleF0gOiAyNTU7CQkKCQl0YXJnZXQgKz0gNDsKCX0JCn0KCmlubGluZSB2b2lkIApGcmVlSW1hZ2VfQ29udmVydExpbmU0VG8zMk1hcFRyYW5zcGFyZW5jeShCWVRFICp0YXJnZXQsIEJZVEUgKnNvdXJjZSwgaW50IHdpZHRoX2luX3BpeGVscywgUkdCUVVBRCAqcGFsZXR0ZSwgQllURSAqdGFibGUsIGludCB0cmFuc3BhcmVudF9waXhlbHMpIHsKCUJPT0wgbG93X25pYmJsZSA9IEZBTFNFOwoJaW50IHggPSAwOwoKCWZvciAoaW50IGNvbHMgPSAwIDsgY29scyA8IHdpZHRoX2luX3BpeGVscyA7ICsrY29scykgewoJCWlmIChsb3dfbmliYmxlKSB7CgkJCXRhcmdldFtGSV9SR0JBX0JMVUVdCT0gcGFsZXR0ZVtMT1dOSUJCTEUoc291cmNlW3hdKV0ucmdiQmx1ZTsKCQkJdGFyZ2V0W0ZJX1JHQkFfR1JFRU5dCT0gcGFsZXR0ZVtMT1dOSUJCTEUoc291cmNlW3hdKV0ucmdiR3JlZW47CgkJCXRhcmdldFtGSV9SR0JBX1JFRF0JCT0gcGFsZXR0ZVtMT1dOSUJCTEUoc291cmNlW3hdKV0ucmdiUmVkOwoJCQl0YXJnZXRbRklfUkdCQV9BTFBIQV0JPSAoTE9XTklCQkxFKHNvdXJjZVt4XSkgPCB0cmFuc3BhcmVudF9waXhlbHMpID8gdGFibGVbTE9XTklCQkxFKHNvdXJjZVt4XSldIDogMjU1OwoKCQkJeCsrOwoJCX0gZWxzZSB7CgkJCXRhcmdldFtGSV9SR0JBX0JMVUVdCT0gcGFsZXR0ZVtISU5JQkJMRShzb3VyY2VbeF0pID4+IDRdLnJnYkJsdWU7CgkJCXRhcmdldFtGSV9SR0JBX0dSRUVOXQk9IHBhbGV0dGVbSElOSUJCTEUoc291cmNlW3hdKSA+PiA0XS5yZ2JHcmVlbjsKCQkJdGFyZ2V0W0ZJX1JHQkFfUkVEXQkJPSBwYWxldHRlW0hJTklCQkxFKHNvdXJjZVt4XSkgPj4gNF0ucmdiUmVkOwoJCQl0YXJnZXRbRklfUkdCQV9BTFBIQV0JPSAoSElOSUJCTEUoc291cmNlW3hdID4+IDQpIDwgdHJhbnNwYXJlbnRfcGl4ZWxzKSA/IHRhYmxlW0hJTklCQkxFKHNvdXJjZVt4XSkgPj4gNF0gOiAyNTU7CgkJfQoKCQlsb3dfbmliYmxlID0gIWxvd19uaWJibGU7CgkJCQkKCQl0YXJnZXQgKz0gNDsKCX0KfQoKaW5saW5lIHZvaWQgCkZyZWVJbWFnZV9Db252ZXJ0TGluZThUbzMyTWFwVHJhbnNwYXJlbmN5KEJZVEUgKnRhcmdldCwgQllURSAqc291cmNlLCBpbnQgd2lkdGhfaW5fcGl4ZWxzLCBSR0JRVUFEICpwYWxldHRlLCBCWVRFICp0YWJsZSwgaW50IHRyYW5zcGFyZW50X3BpeGVscykgewoJZm9yIChpbnQgY29scyA9IDA7IGNvbHMgPCB3aWR0aF9pbl9waXhlbHM7IGNvbHMrKykgewoJCXRhcmdldFtGSV9SR0JBX0JMVUVdCT0gcGFsZXR0ZVtzb3VyY2VbY29sc11dLnJnYkJsdWU7CgkJdGFyZ2V0W0ZJX1JHQkFfR1JFRU5dCT0gcGFsZXR0ZVtzb3VyY2VbY29sc11dLnJnYkdyZWVuOwoJCXRhcmdldFtGSV9SR0JBX1JFRF0JCT0gcGFsZXR0ZVtzb3VyY2VbY29sc11dLnJnYlJlZDsKCQl0YXJnZXRbRklfUkdCQV9BTFBIQV0gPSAoc291cmNlW2NvbHNdIDwgdHJhbnNwYXJlbnRfcGl4ZWxzKSA/IHRhYmxlW3NvdXJjZVtjb2xzXV0gOiAyNTU7CgkJdGFyZ2V0ICs9IDQ7CQkKCX0KfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKRklCSVRNQVAgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRUbzMyQml0cyhGSUJJVE1BUCAqZGliKSB7CglpZighRnJlZUltYWdlX0hhc1BpeGVscyhkaWIpKSByZXR1cm4gTlVMTDsKCgljb25zdCBpbnQgYnBwID0gRnJlZUltYWdlX0dldEJQUChkaWIpOwoJY29uc3QgRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRpYik7CgkKCWlmKChpbWFnZV90eXBlICE9IEZJVF9CSVRNQVApICYmIChpbWFnZV90eXBlICE9IEZJVF9SR0IxNikgJiYgKGltYWdlX3R5cGUgIT0gRklUX1JHQkExNikpIHsKCQlyZXR1cm4gTlVMTDsKCX0KCQoJY29uc3QgaW50IHdpZHRoID0gRnJlZUltYWdlX0dldFdpZHRoKGRpYik7Cgljb25zdCBpbnQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChkaWIpOwoKCWlmKGltYWdlX3R5cGUgPT0gRklUX0JJVE1BUCkgewoKCQlpZihicHAgPT0gMzIpIHsKCQkJcmV0dXJuIEZyZWVJbWFnZV9DbG9uZShkaWIpOwoJCX0KCgkJRklCSVRNQVAgKm5ld19kaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGUod2lkdGgsIGhlaWdodCwgMzIsIEZJX1JHQkFfUkVEX01BU0ssIEZJX1JHQkFfR1JFRU5fTUFTSywgRklfUkdCQV9CTFVFX01BU0spOwoJCWlmKG5ld19kaWIgPT0gTlVMTCkgewoJCQlyZXR1cm4gTlVMTDsKCQl9CgoJCS8vIGNvcHkgbWV0YWRhdGEgZnJvbSBzcmMgdG8gZHN0CgkJRnJlZUltYWdlX0Nsb25lTWV0YWRhdGEobmV3X2RpYiwgZGliKTsKCgkJQk9PTCBiSXNUcmFuc3BhcmVudCA9IEZyZWVJbWFnZV9Jc1RyYW5zcGFyZW50KGRpYik7CgoJCXN3aXRjaChicHApIHsKCQkJY2FzZSAxOgoJCQl7CgkJCQlpZihiSXNUcmFuc3BhcmVudCkgewoJCQkJCWZvciAoaW50IHJvd3MgPSAwOyByb3dzIDwgaGVpZ2h0OyByb3dzKyspIHsKCQkJCQkJRnJlZUltYWdlX0NvbnZlcnRMaW5lMVRvMzJNYXBUcmFuc3BhcmVuY3koRnJlZUltYWdlX0dldFNjYW5MaW5lKG5ld19kaWIsIHJvd3MpLCBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCByb3dzKSwgd2lkdGgsIEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYiksIEZyZWVJbWFnZV9HZXRUcmFuc3BhcmVuY3lUYWJsZShkaWIpLCBGcmVlSW1hZ2VfR2V0VHJhbnNwYXJlbmN5Q291bnQoZGliKSk7CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQlmb3IgKGludCByb3dzID0gMDsgcm93cyA8IGhlaWdodDsgcm93cysrKSB7CgkJCQkJCUZyZWVJbWFnZV9Db252ZXJ0TGluZTFUbzMyKEZyZWVJbWFnZV9HZXRTY2FuTGluZShuZXdfZGliLCByb3dzKSwgRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgcm93cyksIHdpZHRoLCBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkaWIpKTsKCQkJCQl9CQkJCQkKCQkJCX0KCgkJCQlyZXR1cm4gbmV3X2RpYjsKCQkJfQoKCQkJY2FzZSA0OgoJCQl7CgkJCQlpZihiSXNUcmFuc3BhcmVudCkgewoJCQkJCWZvciAoaW50IHJvd3MgPSAwOyByb3dzIDwgaGVpZ2h0OyByb3dzKyspIHsKCQkJCQkJRnJlZUltYWdlX0NvbnZlcnRMaW5lNFRvMzJNYXBUcmFuc3BhcmVuY3koRnJlZUltYWdlX0dldFNjYW5MaW5lKG5ld19kaWIsIHJvd3MpLCBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCByb3dzKSwgd2lkdGgsIEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYiksIEZyZWVJbWFnZV9HZXRUcmFuc3BhcmVuY3lUYWJsZShkaWIpLCBGcmVlSW1hZ2VfR2V0VHJhbnNwYXJlbmN5Q291bnQoZGliKSk7CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQlmb3IgKGludCByb3dzID0gMDsgcm93cyA8IGhlaWdodDsgcm93cysrKSB7CgkJCQkJCUZyZWVJbWFnZV9Db252ZXJ0TGluZTRUbzMyKEZyZWVJbWFnZV9HZXRTY2FuTGluZShuZXdfZGliLCByb3dzKSwgRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgcm93cyksIHdpZHRoLCBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkaWIpKTsKCQkJCQl9CQkJCQkKCQkJCX0KCgkJCQlyZXR1cm4gbmV3X2RpYjsKCQkJfQoJCQkJCgkJCWNhc2UgODoKCQkJewoJCQkJaWYoYklzVHJhbnNwYXJlbnQpIHsKCQkJCQlmb3IgKGludCByb3dzID0gMDsgcm93cyA8IGhlaWdodDsgcm93cysrKSB7CgkJCQkJCUZyZWVJbWFnZV9Db252ZXJ0TGluZThUbzMyTWFwVHJhbnNwYXJlbmN5KEZyZWVJbWFnZV9HZXRTY2FuTGluZShuZXdfZGliLCByb3dzKSwgRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgcm93cyksIHdpZHRoLCBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkaWIpLCBGcmVlSW1hZ2VfR2V0VHJhbnNwYXJlbmN5VGFibGUoZGliKSwgRnJlZUltYWdlX0dldFRyYW5zcGFyZW5jeUNvdW50KGRpYikpOwoJCQkJCX0KCQkJCX0gZWxzZSB7CgkJCQkJZm9yIChpbnQgcm93cyA9IDA7IHJvd3MgPCBoZWlnaHQ7IHJvd3MrKykgewoJCQkJCQlGcmVlSW1hZ2VfQ29udmVydExpbmU4VG8zMihGcmVlSW1hZ2VfR2V0U2NhbkxpbmUobmV3X2RpYiwgcm93cyksIEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHJvd3MpLCB3aWR0aCwgRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKSk7CgkJCQkJfQkJCQkJCgkJCQl9CgoJCQkJcmV0dXJuIG5ld19kaWI7CgkJCX0KCgkJCWNhc2UgMTY6CgkJCXsKCQkJCWZvciAoaW50IHJvd3MgPSAwOyByb3dzIDwgaGVpZ2h0OyByb3dzKyspIHsKCQkJCQlpZiAoKEZyZWVJbWFnZV9HZXRSZWRNYXNrKGRpYikgPT0gRkkxNl81NjVfUkVEX01BU0spICYmIChGcmVlSW1hZ2VfR2V0R3JlZW5NYXNrKGRpYikgPT0gRkkxNl81NjVfR1JFRU5fTUFTSykgJiYgKEZyZWVJbWFnZV9HZXRCbHVlTWFzayhkaWIpID09IEZJMTZfNTY1X0JMVUVfTUFTSykpIHsKCQkJCQkJRnJlZUltYWdlX0NvbnZlcnRMaW5lMTZUbzMyXzU2NShGcmVlSW1hZ2VfR2V0U2NhbkxpbmUobmV3X2RpYiwgcm93cyksIEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHJvd3MpLCB3aWR0aCk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJLy8gaW5jbHVkZXMgY2FzZSB3aGVyZSBhbGwgdGhlIG1hc2tzIGFyZSAwCgkJCQkJCUZyZWVJbWFnZV9Db252ZXJ0TGluZTE2VG8zMl81NTUoRnJlZUltYWdlX0dldFNjYW5MaW5lKG5ld19kaWIsIHJvd3MpLCBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCByb3dzKSwgd2lkdGgpOwoJCQkJCX0KCQkJCX0KCgkJCQlyZXR1cm4gbmV3X2RpYjsKCQkJfQoKCQkJY2FzZSAyNDoKCQkJewoJCQkJZm9yIChpbnQgcm93cyA9IDA7IHJvd3MgPCBoZWlnaHQ7IHJvd3MrKykgewoJCQkJCUZyZWVJbWFnZV9Db252ZXJ0TGluZTI0VG8zMihGcmVlSW1hZ2VfR2V0U2NhbkxpbmUobmV3X2RpYiwgcm93cyksIEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHJvd3MpLCB3aWR0aCk7CgkJCQl9CgoJCQkJcmV0dXJuIG5ld19kaWI7CgkJCX0KCQl9CgoJfSBlbHNlIGlmKGltYWdlX3R5cGUgPT0gRklUX1JHQjE2KSB7CgkJRklCSVRNQVAgKm5ld19kaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGUod2lkdGgsIGhlaWdodCwgMzIsIEZJX1JHQkFfUkVEX01BU0ssIEZJX1JHQkFfR1JFRU5fTUFTSywgRklfUkdCQV9CTFVFX01BU0spOwoJCWlmKG5ld19kaWIgPT0gTlVMTCkgewoJCQlyZXR1cm4gTlVMTDsKCQl9CgoJCS8vIGNvcHkgbWV0YWRhdGEgZnJvbSBzcmMgdG8gZHN0CgkJRnJlZUltYWdlX0Nsb25lTWV0YWRhdGEobmV3X2RpYiwgZGliKTsKCgkJY29uc3QgdW5zaWduZWQgc3JjX3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKGRpYik7CgkJY29uc3QgdW5zaWduZWQgZHN0X3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKG5ld19kaWIpOwoJCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gRnJlZUltYWdlX0dldEJpdHMoZGliKTsKCQlCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRCaXRzKG5ld19kaWIpOwoJCWZvciAoaW50IHJvd3MgPSAwOyByb3dzIDwgaGVpZ2h0OyByb3dzKyspIHsKCQkJY29uc3QgRklSR0IxNiAqc3JjX3BpeGVsID0gKEZJUkdCMTYqKXNyY19iaXRzOwoJCQlSR0JRVUFEICpkc3RfcGl4ZWwgPSAoUkdCUVVBRCopZHN0X2JpdHM7CgkJCWZvcihpbnQgY29scyA9IDA7IGNvbHMgPCB3aWR0aDsgY29scysrKSB7CgkJCQlkc3RfcGl4ZWxbY29sc10ucmdiUmVkCQk9IChCWVRFKShzcmNfcGl4ZWxbY29sc10ucmVkICAgPj4gOCk7CgkJCQlkc3RfcGl4ZWxbY29sc10ucmdiR3JlZW4JPSAoQllURSkoc3JjX3BpeGVsW2NvbHNdLmdyZWVuID4+IDgpOwoJCQkJZHN0X3BpeGVsW2NvbHNdLnJnYkJsdWUJCT0gKEJZVEUpKHNyY19waXhlbFtjb2xzXS5ibHVlICA+PiA4KTsKCQkJCWRzdF9waXhlbFtjb2xzXS5yZ2JSZXNlcnZlZCA9IChCWVRFKTB4RkY7CgkJCX0KCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJfQoKCQlyZXR1cm4gbmV3X2RpYjsKCgl9IGVsc2UgaWYoaW1hZ2VfdHlwZSA9PSBGSVRfUkdCQTE2KSB7CgkJRklCSVRNQVAgKm5ld19kaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGUod2lkdGgsIGhlaWdodCwgMzIsIEZJX1JHQkFfUkVEX01BU0ssIEZJX1JHQkFfR1JFRU5fTUFTSywgRklfUkdCQV9CTFVFX01BU0spOwoJCWlmKG5ld19kaWIgPT0gTlVMTCkgewoJCQlyZXR1cm4gTlVMTDsKCQl9CgoJCS8vIGNvcHkgbWV0YWRhdGEgZnJvbSBzcmMgdG8gZHN0CgkJRnJlZUltYWdlX0Nsb25lTWV0YWRhdGEobmV3X2RpYiwgZGliKTsKCgkJY29uc3QgdW5zaWduZWQgc3JjX3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKGRpYik7CgkJY29uc3QgdW5zaWduZWQgZHN0X3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKG5ld19kaWIpOwoJCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gRnJlZUltYWdlX0dldEJpdHMoZGliKTsKCQlCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRCaXRzKG5ld19kaWIpOwoJCWZvciAoaW50IHJvd3MgPSAwOyByb3dzIDwgaGVpZ2h0OyByb3dzKyspIHsKCQkJY29uc3QgRklSR0JBMTYgKnNyY19waXhlbCA9IChGSVJHQkExNiopc3JjX2JpdHM7CgkJCVJHQlFVQUQgKmRzdF9waXhlbCA9IChSR0JRVUFEKilkc3RfYml0czsKCQkJZm9yKGludCBjb2xzID0gMDsgY29scyA8IHdpZHRoOyBjb2xzKyspIHsKCQkJCWRzdF9waXhlbFtjb2xzXS5yZ2JSZWQJCT0gKEJZVEUpKHNyY19waXhlbFtjb2xzXS5yZWQgICA+PiA4KTsKCQkJCWRzdF9waXhlbFtjb2xzXS5yZ2JHcmVlbgk9IChCWVRFKShzcmNfcGl4ZWxbY29sc10uZ3JlZW4gPj4gOCk7CgkJCQlkc3RfcGl4ZWxbY29sc10ucmdiQmx1ZQkJPSAoQllURSkoc3JjX3BpeGVsW2NvbHNdLmJsdWUgID4+IDgpOwoJCQkJZHN0X3BpeGVsW2NvbHNdLnJnYlJlc2VydmVkID0gKEJZVEUpKHNyY19waXhlbFtjb2xzXS5hbHBoYSA+PiA4KTsKCQkJfQoJCQlzcmNfYml0cyArPSBzcmNfcGl0Y2g7CgkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQl9CQkKCgkJcmV0dXJuIG5ld19kaWI7Cgl9CgkKCXJldHVybiBOVUxMOwp9Cg==