Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBJQ08gTG9hZGVyIGFuZCBXcml0ZXIKLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIEZsb3JpcyB2YW4gZGVuIEJlcmcgKGZsdmRiZXJnQHd4cy5ubCkKLy8gLSBIZXJ26SBEcm9sb24gKGRyb2xvbkBpbmZvbmllLmZyKQovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiBGcmVlSW1hZ2UgMwovLwovLyBDT1ZFUkVEIENPREUgSVMgUFJPVklERUQgVU5ERVIgVEhJUyBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVFkKLy8gT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFdBUlJBTlRJRVMKLy8gVEhBVCBUSEUgQ09WRVJFRCBDT0RFIElTIEZSRUUgT0YgREVGRUNUUywgTUVSQ0hBTlRBQkxFLCBGSVQgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi8vIE9SIE5PTi1JTkZSSU5HSU5HLiBUSEUgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBDT1ZFUkVECi8vIENPREUgSVMgV0lUSCBZT1UuIFNIT1VMRCBBTlkgQ09WRVJFRCBDT0RFIFBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgWU9VIChOT1QKLy8gVEhFIElOSVRJQUwgREVWRUxPUEVSIE9SIEFOWSBPVEhFUiBDT05UUklCVVRPUikgQVNTVU1FIFRIRSBDT1NUIE9GIEFOWSBORUNFU1NBUlkKLy8gU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOIEVTU0VOVElBTAovLyBQQVJUIE9GIFRISVMgTElDRU5TRS4gTk8gVVNFIE9GIEFOWSBDT1ZFUkVEIENPREUgSVMgQVVUSE9SSVpFRCBIRVJFVU5ERVIgRVhDRVBUIFVOREVSCi8vIFRISVMgRElTQ0xBSU1FUi4KLy8KLy8gVXNlIGF0IHlvdXIgb3duIHJpc2shCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpbmNsdWRlICJGcmVlSW1hZ2UuaCIKI2luY2x1ZGUgIlV0aWxpdGllcy5oIgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIENvbnN0YW50cyArIGhlYWRlcnMKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKI2lmZGVmIF9XSU4zMgojcHJhZ21hIHBhY2socHVzaCwgMSkKI2Vsc2UKI3ByYWdtYSBwYWNrKDEpCiNlbmRpZgoKLy8gVGhlc2UgbmV4dCB0d28gc3RydWN0cyByZXByZXNlbnQgaG93IHRoZSBpY29uIGluZm9ybWF0aW9uIGlzIHN0b3JlZAovLyBpbiBhbiBJQ08gZmlsZS4KCnR5cGVkZWYgc3RydWN0IHRhZ0lDT05IRUFERVIgewoJV09SRAkJCWlkUmVzZXJ2ZWQ7ICAgLy8gcmVzZXJ2ZWQKCVdPUkQJCQlpZFR5cGU7ICAgICAgIC8vIHJlc291cmNlIHR5cGUgKDEgZm9yIGljb25zKQoJV09SRAkJCWlkQ291bnQ7ICAgICAgLy8gaG93IG1hbnkgaW1hZ2VzPwp9IElDT05IRUFERVI7Cgp0eXBlZGVmIHN0cnVjdCB0YWdJQ09ORElSRUNUT1JZRU5UUlkgewoJQllURQliV2lkdGg7ICAgICAgICAgICAgICAgLy8gd2lkdGggb2YgdGhlIGltYWdlCglCWVRFCWJIZWlnaHQ7ICAgICAgICAgICAgICAvLyBoZWlnaHQgb2YgdGhlIGltYWdlICh0aW1lcyAyKQoJQllURQliQ29sb3JDb3VudDsgICAgICAgICAgLy8gbnVtYmVyIG9mIGNvbG9ycyBpbiBpbWFnZSAoMCBpZiA+PThicHApCglCWVRFCWJSZXNlcnZlZDsgICAgICAgICAgICAvLyByZXNlcnZlZAoJV09SRAl3UGxhbmVzOyAgICAgICAgICAgICAgLy8gY29sb3IgUGxhbmVzCglXT1JECXdCaXRDb3VudDsgICAgICAgICAgICAvLyBiaXRzIHBlciBwaXhlbAoJRFdPUkQJZHdCeXRlc0luUmVzOyAgICAgICAgIC8vIGhvdyBtYW55IGJ5dGVzIGluIHRoaXMgcmVzb3VyY2U/CglEV09SRAlkd0ltYWdlT2Zmc2V0OyAgICAgICAgLy8gd2hlcmUgaW4gdGhlIGZpbGUgaXMgdGhpcyBpbWFnZQp9IElDT05ESVJFTlRSWTsKCiNpZmRlZiBfV0lOMzIKI3ByYWdtYSBwYWNrKHBvcCkKI2Vsc2UKI3ByYWdtYSBwYWNrKCkKI2VuZGlmCgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIFN0YXRpYyBoZWxwZXJzCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKiAgSG93IHdpZGUsIGluIGJ5dGVzLCB3b3VsZCB0aGlzIG1hbnkgYml0cyBiZSwgRFdPUkQgYWxpZ25lZCA/CiovCnN0YXRpYyBpbnQgCldpZHRoQnl0ZXMoaW50IGJpdHMpIHsKCXJldHVybiAoKCgoYml0cykgKyAzMSk+PjUpPDwyKTsKfQoKLyoqIENhbGN1bGF0ZXMgdGhlIHNpemUgb2YgYSBzaW5nbGUgaWNvbiBpbWFnZQpAcmV0dXJuIFJldHVybnMgdGhlIHNpemUgZm9yIHRoYXQgaW1hZ2UKKi8Kc3RhdGljIERXT1JEIApDYWxjdWxhdGVJbWFnZVNpemUoRklCSVRNQVAqIGljb25fZGliKSB7CglEV09SRCBkd051bUJ5dGVzID0gMDsKCgl1bnNpZ25lZCBjb2xvcnMJCT0gRnJlZUltYWdlX0dldENvbG9yc1VzZWQoaWNvbl9kaWIpOwoJdW5zaWduZWQgd2lkdGgJCT0gRnJlZUltYWdlX0dldFdpZHRoKGljb25fZGliKTsKCXVuc2lnbmVkIGhlaWdodAkJPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGljb25fZGliKTsKCXVuc2lnbmVkIHBpdGNoCQk9IEZyZWVJbWFnZV9HZXRQaXRjaChpY29uX2RpYik7CgoJZHdOdW1CeXRlcyA9IHNpemVvZiggQklUTUFQSU5GT0hFQURFUiApOwkvLyBoZWFkZXIKCWR3TnVtQnl0ZXMgKz0gY29sb3JzICogc2l6ZW9mKFJHQlFVQUQpOwkJLy8gcGFsZXR0ZQoJZHdOdW1CeXRlcyArPSBoZWlnaHQgKiBwaXRjaDsJCQkJLy8gWE9SIG1hc2sKCWR3TnVtQnl0ZXMgKz0gaGVpZ2h0ICogV2lkdGhCeXRlcyh3aWR0aCk7CS8vIEFORCBtYXNrCgoJcmV0dXJuIGR3TnVtQnl0ZXM7Cn0KCi8qKiBDYWxjdWxhdGVzIHRoZSBmaWxlIG9mZnNldCBmb3IgYW4gaWNvbiBpbWFnZQpAcmV0dXJuIFJldHVybnMgdGhlIGZpbGUgb2Zmc2V0IGZvciB0aGF0IGltYWdlCiovCnN0YXRpYyBEV09SRCAKQ2FsY3VsYXRlSW1hZ2VPZmZzZXQoc3RkOjp2ZWN0b3I8RklCSVRNQVAqPiYgdlBhZ2VzLCBpbnQgbkluZGV4ICkgewoJRFdPUkQJZHdTaXplOwoKICAgIC8vIGNhbGN1bGF0ZSB0aGUgSUNPIGhlYWRlciBzaXplCiAgICBkd1NpemUgPSBzaXplb2YoSUNPTkhFQURFUik7IAogICAgLy8gYWRkIHRoZSBJQ09ORElSRU5UUlkncwogICAgZHdTaXplICs9IChEV09SRCkoIHZQYWdlcy5zaXplKCkgKiBzaXplb2YoSUNPTkRJUkVOVFJZKSApOwogICAgLy8gYWRkIHRoZSBzaXplcyBvZiB0aGUgcHJldmlvdXMgaW1hZ2VzCiAgICBmb3IoaW50IGsgPSAwOyBrIDwgbkluZGV4OyBrKyspIHsKCQlGSUJJVE1BUCAqaWNvbl9kaWIgPSAoRklCSVRNQVAqKXZQYWdlc1trXTsKCQlkd1NpemUgKz0gQ2FsY3VsYXRlSW1hZ2VTaXplKGljb25fZGliKTsKCX0KCiAgICByZXR1cm4gZHdTaXplOwp9CgovKioKVmlzdGEgaWNvbiBzdXBwb3J0CkByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHRoZSBiaXRtYXAgZGF0YSBpcyBzdG9yZWQgaW4gUE5HIGZvcm1hdAoqLwpzdGF0aWMgQk9PTApJc1BORyhGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUpIHsKCUJZVEUgcG5nX3NpZ25hdHVyZVs4XSA9IHsgMTM3LCA4MCwgNzgsIDcxLCAxMywgMTAsIDI2LCAxMCB9OwoJQllURSBzaWduYXR1cmVbOF0gPSB7IDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAgfTsKCglsb25nIHRlbGwgPSBpby0+dGVsbF9wcm9jKGhhbmRsZSk7Cglpby0+cmVhZF9wcm9jKCZzaWduYXR1cmUsIDEsIDgsIGhhbmRsZSk7CglCT09MIGJJc1BORyA9IChtZW1jbXAocG5nX3NpZ25hdHVyZSwgc2lnbmF0dXJlLCA4KSA9PSAwKTsKCWlvLT5zZWVrX3Byb2MoaGFuZGxlLCB0ZWxsLCBTRUVLX1NFVCk7CgoJcmV0dXJuIGJJc1BORzsKfQoKI2lmZGVmIEZSRUVJTUFHRV9CSUdFTkRJQU4Kc3RhdGljIHZvaWQKU3dhcEluZm9IZWFkZXIoQklUTUFQSU5GT0hFQURFUiAqaGVhZGVyKSB7CglTd2FwTG9uZygmaGVhZGVyLT5iaVNpemUpOwoJU3dhcExvbmcoKERXT1JEICopJmhlYWRlci0+YmlXaWR0aCk7CglTd2FwTG9uZygoRFdPUkQgKikmaGVhZGVyLT5iaUhlaWdodCk7CglTd2FwU2hvcnQoJmhlYWRlci0+YmlQbGFuZXMpOwoJU3dhcFNob3J0KCZoZWFkZXItPmJpQml0Q291bnQpOwoJU3dhcExvbmcoJmhlYWRlci0+YmlDb21wcmVzc2lvbik7CglTd2FwTG9uZygmaGVhZGVyLT5iaVNpemVJbWFnZSk7CglTd2FwTG9uZygoRFdPUkQgKikmaGVhZGVyLT5iaVhQZWxzUGVyTWV0ZXIpOwoJU3dhcExvbmcoKERXT1JEICopJmhlYWRlci0+YmlZUGVsc1Blck1ldGVyKTsKCVN3YXBMb25nKCZoZWFkZXItPmJpQ2xyVXNlZCk7CglTd2FwTG9uZygmaGVhZGVyLT5iaUNsckltcG9ydGFudCk7Cn0KCnN0YXRpYyB2b2lkClN3YXBJY29uSGVhZGVyKElDT05IRUFERVIgKmhlYWRlcikgewoJU3dhcFNob3J0KCZoZWFkZXItPmlkUmVzZXJ2ZWQpOwoJU3dhcFNob3J0KCZoZWFkZXItPmlkVHlwZSk7CglTd2FwU2hvcnQoJmhlYWRlci0+aWRDb3VudCk7Cn0KCnN0YXRpYyB2b2lkClN3YXBJY29uRGlyRW50cmllcyhJQ09ORElSRU5UUlkgKmVudCwgaW50IG51bSkgewoJd2hpbGUobnVtKSB7CgkJU3dhcFNob3J0KCZlbnQtPndQbGFuZXMpOwoJCVN3YXBTaG9ydCgmZW50LT53Qml0Q291bnQpOwoJCVN3YXBMb25nKCZlbnQtPmR3Qnl0ZXNJblJlcyk7CgkJU3dhcExvbmcoJmVudC0+ZHdJbWFnZU9mZnNldCk7CgkJbnVtLS07CgkJZW50Kys7Cgl9Cn0KI2VuZGlmCgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIFBsdWdpbiBJbnRlcmZhY2UKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKc3RhdGljIGludCBzX2Zvcm1hdF9pZDsKCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gUGx1Z2luIEltcGxlbWVudGF0aW9uCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCnN0YXRpYyBjb25zdCBjaGFyICogRExMX0NBTExDT05WCkZvcm1hdCgpIHsKCXJldHVybiAiSUNPIjsKfQoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKRGVzY3JpcHRpb24oKSB7CglyZXR1cm4gIldpbmRvd3MgSWNvbiI7Cn0KCnN0YXRpYyBjb25zdCBjaGFyICogRExMX0NBTExDT05WCkV4dGVuc2lvbigpIHsKCXJldHVybiAiaWNvIjsKfQoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKUmVnRXhwcigpIHsKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpNaW1lVHlwZSgpIHsKCXJldHVybiAiaW1hZ2Uvdm5kLm1pY3Jvc29mdC5pY29uIjsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WClZhbGlkYXRlKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSkgewoJSUNPTkhFQURFUiBpY29uX2hlYWRlcjsKCglpby0+cmVhZF9wcm9jKCZpY29uX2hlYWRlciwgc2l6ZW9mKElDT05IRUFERVIpLCAxLCBoYW5kbGUpOwojaWZkZWYgRlJFRUlNQUdFX0JJR0VORElBTgoJU3dhcEljb25IZWFkZXIoJmljb25faGVhZGVyKTsKI2VuZGlmCgoJcmV0dXJuICgoaWNvbl9oZWFkZXIuaWRSZXNlcnZlZCA9PSAwKSAmJiAoaWNvbl9oZWFkZXIuaWRUeXBlID09IDEpICYmIChpY29uX2hlYWRlci5pZENvdW50ID4gMCkpOwp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYKU3VwcG9ydHNFeHBvcnREZXB0aChpbnQgZGVwdGgpIHsKCXJldHVybiAoCgkJCShkZXB0aCA9PSAxKSB8fAoJCQkoZGVwdGggPT0gNCkgfHwKCQkJKGRlcHRoID09IDgpIHx8CgkJCShkZXB0aCA9PSAxNikgfHwKCQkJKGRlcHRoID09IDI0KSB8fAoJCQkoZGVwdGggPT0gMzIpCgkJKTsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WIApTdXBwb3J0c0V4cG9ydFR5cGUoRlJFRV9JTUFHRV9UWVBFIHR5cGUpIHsKCXJldHVybiAodHlwZSA9PSBGSVRfQklUTUFQKSA/IFRSVUUgOiBGQUxTRTsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WClN1cHBvcnRzTm9QaXhlbHMoKSB7CglyZXR1cm4gVFJVRTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc3RhdGljIHZvaWQgKiBETExfQ0FMTENPTlYKT3BlbihGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIEJPT0wgcmVhZCkgewoJLy8gQWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgaGVhZGVyIHN0cnVjdHVyZQoJSUNPTkhFQURFUiAqbHBJSCA9IChJQ09OSEVBREVSKiltYWxsb2Moc2l6ZW9mKElDT05IRUFERVIpKTsKCWlmKGxwSUggPT0gTlVMTCkgewoJCXJldHVybiBOVUxMOwoJfQoKCWlmIChyZWFkKSB7CgkJLy8gUmVhZCBpbiB0aGUgaGVhZGVyCgkJaW8tPnJlYWRfcHJvYyhscElILCAxLCBzaXplb2YoSUNPTkhFQURFUiksIGhhbmRsZSk7CiNpZmRlZiBGUkVFSU1BR0VfQklHRU5ESUFOCgkJU3dhcEljb25IZWFkZXIobHBJSCk7CiNlbmRpZgoKCQlpZighKGxwSUgtPmlkUmVzZXJ2ZWQgPT0gMCkgfHwgIShscElILT5pZFR5cGUgPT0gMSkpIHsKCQkJLy8gTm90IGFuIElDTyBmaWxlCgkJCWZyZWUobHBJSCk7CgkJCXJldHVybiBOVUxMOwoJCX0KCX0KCWVsc2UgewoJCS8vIEZpbGwgdGhlIGhlYWRlcgoJCWxwSUgtPmlkUmVzZXJ2ZWQgPSAwOwoJCWxwSUgtPmlkVHlwZSA9IDE7CgkJbHBJSC0+aWRDb3VudCA9IDA7Cgl9CgoJcmV0dXJuIGxwSUg7Cn0KCnN0YXRpYyB2b2lkIERMTF9DQUxMQ09OVgpDbG9zZShGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIHZvaWQgKmRhdGEpIHsKCS8vIGZyZWUgdGhlIGhlYWRlciBzdHJ1Y3R1cmUKCUlDT05IRUFERVIgKmxwSUggPSAoSUNPTkhFQURFUiopZGF0YTsKCWZyZWUobHBJSCk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnN0YXRpYyBpbnQgRExMX0NBTExDT05WClBhZ2VDb3VudChGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIHZvaWQgKmRhdGEpIHsKCUlDT05IRUFERVIgKmxwSUggPSAoSUNPTkhFQURFUiopZGF0YTsKCglpZihscElIKSB7CgkJcmV0dXJuIGxwSUgtPmlkQ291bnQ7Cgl9CglyZXR1cm4gMTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc3RhdGljIEZJQklUTUFQKgpMb2FkU3RhbmRhcmRJY29uKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgaW50IGZsYWdzLCBCT09MIGhlYWRlcl9vbmx5KSB7CglGSUJJVE1BUCAqZGliID0gTlVMTDsKCgkvLyBsb2FkIHRoZSBCSVRNQVBJTkZPSEVBREVSCglCSVRNQVBJTkZPSEVBREVSIGJtaWg7Cglpby0+cmVhZF9wcm9jKCZibWloLCBzaXplb2YoQklUTUFQSU5GT0hFQURFUiksIDEsIGhhbmRsZSk7CiNpZmRlZiBGUkVFSU1BR0VfQklHRU5ESUFOCglTd2FwSW5mb0hlYWRlcigmYm1paCk7CiNlbmRpZgoKCS8vIGFsbG9jYXRlIHRoZSBiaXRtYXAKCWludCB3aWR0aCAgPSBibWloLmJpV2lkdGg7CglpbnQgaGVpZ2h0ID0gYm1paC5iaUhlaWdodCAvIDI7IC8vIGhlaWdodCA9PSB4b3IgKyBhbmQgbWFzawoJdW5zaWduZWQgYml0X2NvdW50ID0gYm1paC5iaUJpdENvdW50OwoJdW5zaWduZWQgbGluZSAgID0gQ2FsY3VsYXRlTGluZSh3aWR0aCwgYml0X2NvdW50KTsKCXVuc2lnbmVkIHBpdGNoICA9IENhbGN1bGF0ZVBpdGNoKGxpbmUpOwoKCS8vIGFsbG9jYXRlIG1lbW9yeSBmb3Igb25lIGljb24KCglkaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGVIZWFkZXIoaGVhZGVyX29ubHksIHdpZHRoLCBoZWlnaHQsIGJpdF9jb3VudCk7CgoJaWYgKGRpYiA9PSBOVUxMKSB7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJaWYoIGJtaWguYmlCaXRDb3VudCA8PSA4ICkgewoJCS8vIHJlYWQgdGhlIHBhbGV0dGUgZGF0YQoJCWlvLT5yZWFkX3Byb2MoRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKSwgQ2FsY3VsYXRlVXNlZFBhbGV0dGVFbnRyaWVzKGJpdF9jb3VudCkgKiBzaXplb2YoUkdCUVVBRCksIDEsIGhhbmRsZSk7CiNpZiBGUkVFSU1BR0VfQ09MT1JPUkRFUiA9PSBGUkVFSU1BR0VfQ09MT1JPUkRFUl9SR0IKCQlSR0JRVUFEICpwYWwgPSBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkaWIpOwoJCWZvcih1bnNpZ25lZCBpID0gMDsgaSA8IENhbGN1bGF0ZVVzZWRQYWxldHRlRW50cmllcyhiaXRfY291bnQpOyBpKyspIHsKCQkJSU5QTEFDRVNXQVAocGFsW2ldLnJnYlJlZCwgcGFsW2ldLnJnYkJsdWUpOwoJCX0KI2VuZGlmCgl9CgkKCWlmKGhlYWRlcl9vbmx5KSB7CgkJLy8gaGVhZGVyIG9ubHkgbW9kZQoJCXJldHVybiBkaWI7Cgl9CgoJLy8gcmVhZCB0aGUgaWNvbgoJaW8tPnJlYWRfcHJvYyhGcmVlSW1hZ2VfR2V0Qml0cyhkaWIpLCBoZWlnaHQgKiBwaXRjaCwgMSwgaGFuZGxlKTsKCiNpZmRlZiBGUkVFSU1BR0VfQklHRU5ESUFOCglpZiAoYml0X2NvdW50ID09IDE2KSB7CgkJZm9yKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCVdPUkQgKnBpeGVsID0gKFdPUkQgKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCB5KTsKCQkJZm9yKGludCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCVN3YXBTaG9ydChwaXhlbCk7CgkJCQlwaXhlbCsrOwoJCQl9CgkJfQoJfQojZW5kaWYKI2lmIEZSRUVJTUFHRV9DT0xPUk9SREVSID09IEZSRUVJTUFHRV9DT0xPUk9SREVSX1JHQgoJaWYgKGJpdF9jb3VudCA9PSAyNCB8fCBiaXRfY291bnQgPT0gMzIpIHsKCQlmb3IoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJQllURSAqcGl4ZWwgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCB5KTsKCQkJZm9yKGludCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCUlOUExBQ0VTV0FQKHBpeGVsWzBdLCBwaXhlbFsyXSk7CgkJCQlwaXhlbCArPSAoYml0X2NvdW50Pj4zKTsKCQkJfQoJCX0KCX0KI2VuZGlmCgkvLyBiaXRtYXAgaGFzIGJlZW4gbG9hZGVkIHN1Y2Nlc3NmdWxseSEKCgkvLyBjb252ZXJ0IHRvIDMyYnBwIGFuZCBnZW5lcmF0ZSBhbiBhbHBoYSBjaGFubmVsCgkvLyBhcHBseSB0aGUgQU5EIG1hc2sgb25seSBpZiB0aGUgaW1hZ2UgaXMgbm90IDMyIGJwcAoJaWYoKChmbGFncyAmIElDT19NQUtFQUxQSEEpID09IElDT19NQUtFQUxQSEEpICYmIChiaXRfY291bnQgPCAzMikpIHsKCQlGSUJJVE1BUCAqZGliMzIgPSBGcmVlSW1hZ2VfQ29udmVydFRvMzJCaXRzKGRpYik7CgkJRnJlZUltYWdlX1VubG9hZChkaWIpOwoKCQlpZiAoZGliMzIgPT0gTlVMTCkgewoJCQlyZXR1cm4gTlVMTDsKCQl9CgoJCWludCB3aWR0aF9hbmQJPSBXaWR0aEJ5dGVzKHdpZHRoKTsKCQlCWVRFICpsaW5lX2FuZAk9IChCWVRFICopbWFsbG9jKHdpZHRoX2FuZCk7CgoJCWlmKCBsaW5lX2FuZCA9PSBOVUxMICkgewoJCQlGcmVlSW1hZ2VfVW5sb2FkKGRpYjMyKTsKCQkJcmV0dXJuIE5VTEw7CgkJfQoKCQkvL2xvb3AgdGhyb3VnaCBlYWNoIGxpbmUgb2YgdGhlIEFORC1tYXNrIGdlbmVyYXRpbmcgdGhlIGFscGhhIGNoYW5uZWwsIGludmVydCBYT1ItbWFzawoJCWZvcihpbnQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQlSR0JRVUFEICpxdWFkID0gKFJHQlFVQUQgKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliMzIsIHkpOwoJCQlpby0+cmVhZF9wcm9jKGxpbmVfYW5kLCB3aWR0aF9hbmQsIDEsIGhhbmRsZSk7CgkJCWZvcihpbnQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQlxdWFkLT5yZ2JSZXNlcnZlZCA9IChsaW5lX2FuZFt4Pj4zXSAmICgweDgwID4+ICh4ICYgMHgwNykpKSAhPSAwID8gMCA6IDB4RkY7CgkJCQlpZiggcXVhZC0+cmdiUmVzZXJ2ZWQgPT0gMCApIHsKCQkJCQlxdWFkLT5yZ2JCbHVlIF49IDB4RkY7CgkJCQkJcXVhZC0+cmdiR3JlZW4gXj0gMHhGRjsKCQkJCQlxdWFkLT5yZ2JSZWQgXj0gMHhGRjsKCQkJCX0KCQkJCXF1YWQrKzsKCQkJfQoJCX0KCQlmcmVlKGxpbmVfYW5kKTsKCgkJcmV0dXJuIGRpYjMyOwoJfQoKCXJldHVybiBkaWI7Cn0KCnN0YXRpYyBGSUJJVE1BUCAqIERMTF9DQUxMQ09OVgpMb2FkKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgaW50IHBhZ2UsIGludCBmbGFncywgdm9pZCAqZGF0YSkgewoJaWYgKHBhZ2UgPT0gLTEpIHsKCQlwYWdlID0gMDsKCX0KCglCT09MIGhlYWRlcl9vbmx5ID0gKGZsYWdzICYgRklGX0xPQURfTk9QSVhFTFMpID09IEZJRl9MT0FEX05PUElYRUxTOwoKCWlmIChoYW5kbGUgIT0gTlVMTCkgewoJCUZJQklUTUFQICpkaWIgPSBOVUxMOwoKCQkvLyBnZXQgdGhlIGljb24gaGVhZGVyCgkJSUNPTkhFQURFUiAqaWNvbl9oZWFkZXIgPSAoSUNPTkhFQURFUiopZGF0YTsKCgkJaWYgKGljb25faGVhZGVyKSB7CgkJCS8vIGxvYWQgdGhlIGljb24gZGVzY3JpcHRpb25zCgkJCUlDT05ESVJFTlRSWSAqaWNvbl9saXN0ID0gKElDT05ESVJFTlRSWSopbWFsbG9jKGljb25faGVhZGVyLT5pZENvdW50ICogc2l6ZW9mKElDT05ESVJFTlRSWSkpOwoJCQlpZihpY29uX2xpc3QgPT0gTlVMTCkgewoJCQkJcmV0dXJuIE5VTEw7CgkJCX0KCQkJaW8tPnNlZWtfcHJvYyhoYW5kbGUsIHNpemVvZihJQ09OSEVBREVSKSwgU0VFS19TRVQpOwoJCQlpby0+cmVhZF9wcm9jKGljb25fbGlzdCwgaWNvbl9oZWFkZXItPmlkQ291bnQgKiBzaXplb2YoSUNPTkRJUkVOVFJZKSwgMSwgaGFuZGxlKTsKI2lmZGVmIEZSRUVJTUFHRV9CSUdFTkRJQU4KCQkJU3dhcEljb25EaXJFbnRyaWVzKGljb25fbGlzdCwgaWNvbl9oZWFkZXItPmlkQ291bnQpOwojZW5kaWYKCgkJCS8vIGxvYWQgdGhlIHJlcXVlc3RlZCBpY29uCgkJCWlmIChwYWdlIDwgaWNvbl9oZWFkZXItPmlkQ291bnQpIHsKCQkJCS8vIHNlZWsgdG8gdGhlIHN0YXJ0IG9mIHRoZSBiaXRtYXAgZGF0YSBmb3IgdGhlIGljb24KCQkJCWlvLT5zZWVrX3Byb2MoaGFuZGxlLCBpY29uX2xpc3RbcGFnZV0uZHdJbWFnZU9mZnNldCwgU0VFS19TRVQpOwoKCQkJCWlmKCBJc1BORyhpbywgaGFuZGxlKSApIHsKCQkJCQkvLyBWaXN0YSBpY29uIHN1cHBvcnQKCQkJCQkvLyBzZWUgaHR0cDovL2Jsb2dzLm1zZG4uY29tL2Ivb2xkbmV3dGhpbmcvYXJjaGl2ZS8yMDEwLzEwLzIyLzEwMDc5MTkyLmFzcHgKCQkJCQlkaWIgPSBGcmVlSW1hZ2VfTG9hZEZyb21IYW5kbGUoRklGX1BORywgaW8sIGhhbmRsZSwgaGVhZGVyX29ubHkgPyBGSUZfTE9BRF9OT1BJWEVMUyA6IFBOR19ERUZBVUxUKTsKCQkJCX0KCQkJCWVsc2UgewoJCQkJCS8vIHN0YW5kYXJkIGljb24gc3VwcG9ydAoJCQkJCS8vIHNlZSBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM5OTc1MzguYXNweAoJCQkJCS8vIHNlZSBodHRwOi8vYmxvZ3MubXNkbi5jb20vYi9vbGRuZXd0aGluZy9hcmNoaXZlLzIwMTAvMTAvMTgvMTAwNzcxMzMuYXNweAoJCQkJCWRpYiA9IExvYWRTdGFuZGFyZEljb24oaW8sIGhhbmRsZSwgZmxhZ3MsIGhlYWRlcl9vbmx5KTsKCQkJCX0KCgkJCQlmcmVlKGljb25fbGlzdCk7CgoJCQkJcmV0dXJuIGRpYjsKCgkJCX0gZWxzZSB7CgkJCQlmcmVlKGljb25fbGlzdCk7CgkJCQlGcmVlSW1hZ2VfT3V0cHV0TWVzc2FnZVByb2Moc19mb3JtYXRfaWQsICJQYWdlIGRvZXNuJ3QgZXhpc3QiKTsKCQkJfQoJCX0gZWxzZSB7CgkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhzX2Zvcm1hdF9pZCwgIkZpbGUgaXMgbm90IGFuIElDTyBmaWxlIik7CgkJfQoJfQoKCXJldHVybiBOVUxMOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgQk9PTCAKU2F2ZVN0YW5kYXJkSWNvbihGcmVlSW1hZ2VJTyAqaW8sIEZJQklUTUFQICpkaWIsIGZpX2hhbmRsZSBoYW5kbGUpIHsKCUJJVE1BUElORk9IRUFERVIgKmJtaWggPSBOVUxMOwoKCS8vIHdyaXRlIHRoZSBCSVRNQVBJTkZPSEVBREVSCglibWloID0gRnJlZUltYWdlX0dldEluZm9IZWFkZXIoZGliKTsKCWJtaWgtPmJpSGVpZ2h0ICo9IDI7CS8vIGhlaWdodCA9PSB4b3IgKyBhbmQgbWFzawojaWZkZWYgRlJFRUlNQUdFX0JJR0VORElBTgoJU3dhcEluZm9IZWFkZXIoYm1paCk7CiNlbmRpZgoJaW8tPndyaXRlX3Byb2MoYm1paCwgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpLCAxLCBoYW5kbGUpOwojaWZkZWYgRlJFRUlNQUdFX0JJR0VORElBTgoJU3dhcEluZm9IZWFkZXIoYm1paCk7CiNlbmRpZgoJYm1paC0+YmlIZWlnaHQgLz0gMjsKCgkvLyB3cml0ZSB0aGUgcGFsZXR0ZSBkYXRhCglpZiAoRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKSAhPSBOVUxMKSB7CgkJUkdCUVVBRCAqcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKTsKCQlGSUxFX0JHUkEgYmdyYTsKCQlmb3IodW5zaWduZWQgaSA9IDA7IGkgPCBGcmVlSW1hZ2VfR2V0Q29sb3JzVXNlZChkaWIpOyBpKyspIHsKCQkJYmdyYS5iID0gcGFsW2ldLnJnYkJsdWU7CgkJCWJncmEuZyA9IHBhbFtpXS5yZ2JHcmVlbjsKCQkJYmdyYS5yID0gcGFsW2ldLnJnYlJlZDsKCQkJYmdyYS5hID0gcGFsW2ldLnJnYlJlc2VydmVkOwoJCQlpby0+d3JpdGVfcHJvYygmYmdyYSwgc2l6ZW9mKEZJTEVfQkdSQSksIDEsIGhhbmRsZSk7CgkJfQoJfQoKCS8vIHdyaXRlIHRoZSBiaXRzCglpbnQgd2lkdGgJCQk9IGJtaWgtPmJpV2lkdGg7CglpbnQgaGVpZ2h0CQkJPSBibWloLT5iaUhlaWdodDsKCXVuc2lnbmVkIGJpdF9jb3VudAk9IGJtaWgtPmJpQml0Q291bnQ7Cgl1bnNpZ25lZCBsaW5lCQk9IENhbGN1bGF0ZUxpbmUod2lkdGgsIGJpdF9jb3VudCk7Cgl1bnNpZ25lZCBwaXRjaAkJPSBDYWxjdWxhdGVQaXRjaChsaW5lKTsKCWludCBzaXplX3hvcgkJPSBoZWlnaHQgKiBwaXRjaDsKCWludCBzaXplX2FuZAkJPSBoZWlnaHQgKiBXaWR0aEJ5dGVzKHdpZHRoKTsKCgkvLyBYT1IgbWFzawojaWZkZWYgRlJFRUlNQUdFX0JJR0VORElBTgoJaWYgKGJpdF9jb3VudCA9PSAxNikgewoJCVdPUkQgcGl4ZWw7CgkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgRnJlZUltYWdlX0dldEhlaWdodChkaWIpOyB5KyspIHsKCQkJQllURSAqbGluZSA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHkpOwoJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKTsgeCsrKSB7CgkJCQlwaXhlbCA9ICgoV09SRCAqKWxpbmUpW3hdOwoJCQkJU3dhcFNob3J0KCZwaXhlbCk7CgkJCQlpZiAoaW8tPndyaXRlX3Byb2MoJnBpeGVsLCBzaXplb2YoV09SRCksIDEsIGhhbmRsZSkgIT0gMSkKCQkJCQlyZXR1cm4gRkFMU0U7CgkJCX0KCQl9Cgl9IGVsc2UKI2VuZGlmCiNpZiBGUkVFSU1BR0VfQ09MT1JPUkRFUiA9PSBGUkVFSU1BR0VfQ09MT1JPUkRFUl9SR0IKCWlmIChiaXRfY291bnQgPT0gMjQpIHsKCQlGSUxFX0JHUiBiZ3I7CgkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgRnJlZUltYWdlX0dldEhlaWdodChkaWIpOyB5KyspIHsKCQkJQllURSAqbGluZSA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHkpOwoJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKTsgeCsrKSB7CgkJCQlSR0JUUklQTEUgKnRyaXBsZSA9ICgoUkdCVFJJUExFICopbGluZSkreDsKCQkJCWJnci5iID0gdHJpcGxlLT5yZ2J0Qmx1ZTsKCQkJCWJnci5nID0gdHJpcGxlLT5yZ2J0R3JlZW47CgkJCQliZ3IuciA9IHRyaXBsZS0+cmdidFJlZDsKCQkJCWlmIChpby0+d3JpdGVfcHJvYygmYmdyLCBzaXplb2YoRklMRV9CR1IpLCAxLCBoYW5kbGUpICE9IDEpCgkJCQkJcmV0dXJuIEZBTFNFOwoJCQl9CgkJfQoJfSBlbHNlIGlmIChiaXRfY291bnQgPT0gMzIpIHsKCQlGSUxFX0JHUkEgYmdyYTsKCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7IHkrKykgewoJCQlCWVRFICpsaW5lID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgeSk7CgkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpOyB4KyspIHsKCQkJCVJHQlFVQUQgKnF1YWQgPSAoKFJHQlFVQUQgKilsaW5lKSt4OwoJCQkJYmdyYS5iID0gcXVhZC0+cmdiQmx1ZTsKCQkJCWJncmEuZyA9IHF1YWQtPnJnYkdyZWVuOwoJCQkJYmdyYS5yID0gcXVhZC0+cmdiUmVkOwoJCQkJYmdyYS5hID0gcXVhZC0+cmdiUmVzZXJ2ZWQ7CgkJCQlpZiAoaW8tPndyaXRlX3Byb2MoJmJncmEsIHNpemVvZihGSUxFX0JHUkEpLCAxLCBoYW5kbGUpICE9IDEpCgkJCQkJcmV0dXJuIEZBTFNFOwoJCQl9CgkJfQoJfSBlbHNlCiNlbmRpZgojaWYgZGVmaW5lZChGUkVFSU1BR0VfQklHRU5ESUFOKSB8fCBGUkVFSU1BR0VfQ09MT1JPUkRFUiA9PSBGUkVFSU1BR0VfQ09MT1JPUkRFUl9SR0IKCXsKI2VuZGlmCgkJQllURSAqeG9yX21hc2sgPSBGcmVlSW1hZ2VfR2V0Qml0cyhkaWIpOwoJCWlvLT53cml0ZV9wcm9jKHhvcl9tYXNrLCBzaXplX3hvciwgMSwgaGFuZGxlKTsKI2lmIGRlZmluZWQoRlJFRUlNQUdFX0JJR0VORElBTikgfHwgRlJFRUlNQUdFX0NPTE9ST1JERVIgPT0gRlJFRUlNQUdFX0NPTE9ST1JERVJfUkdCCgl9CiNlbmRpZgoJLy8gQU5EIG1hc2sKCUJZVEUgKmFuZF9tYXNrID0gKEJZVEUqKW1hbGxvYyhzaXplX2FuZCk7CglpZighYW5kX21hc2spIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJaWYoRnJlZUltYWdlX0lzVHJhbnNwYXJlbnQoZGliKSkgewoKCQlpZihiaXRfY291bnQgPT0gMzIpIHsKCQkJLy8gY3JlYXRlIHRoZSBBTkQgbWFzayBmcm9tIHRoZSBhbHBoYSBjaGFubmVsCgoJCQlpbnQgd2lkdGhfYW5kICA9IFdpZHRoQnl0ZXMod2lkdGgpOwoJCQlCWVRFICphbmRfYml0cyA9IGFuZF9tYXNrOwoKCQkJLy8gY2xlYXIgdGhlIG1hc2sKCQkJbWVtc2V0KGFuZF9tYXNrLCAwLCBzaXplX2FuZCk7CgoJCQlmb3IoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCVJHQlFVQUQgKmJpdHMgPSAoUkdCUVVBRCopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgeSk7CgoJCQkJZm9yKGludCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQlpZihiaXRzW3hdLnJnYlJlc2VydmVkICE9IDB4RkYpIHsKCQkJCQkJLy8gc2V0IGFueSB0cmFuc3BhcmVudCBjb2xvciB0byBmdWxsIHRyYW5zcGFyZW5jeQoJCQkJCQlhbmRfYml0c1t4ID4+IDNdIHw9ICgweDgwID4+ICh4ICYgMHg3KSk7IAoJCQkJCX0KCQkJCX0KCgkJCQlhbmRfYml0cyArPSB3aWR0aF9hbmQ7CgkJCX0KCQl9IAoJCWVsc2UgaWYoYml0X2NvdW50IDw9IDgpIHsKCQkJLy8gY3JlYXRlIHRoZSBBTkQgbWFzayBmcm9tIHRoZSB0cmFuc3BhcmVuY3kgdGFibGUKCgkJCUJZVEUgKnRybnMgPSBGcmVlSW1hZ2VfR2V0VHJhbnNwYXJlbmN5VGFibGUoZGliKTsKCgkJCWludCB3aWR0aF9hbmQgID0gV2lkdGhCeXRlcyh3aWR0aCk7CgkJCUJZVEUgKmFuZF9iaXRzID0gYW5kX21hc2s7CgoJCQkvLyBjbGVhciB0aGUgbWFzawoJCQltZW1zZXQoYW5kX21hc2ssIDAsIHNpemVfYW5kKTsKCgkJCXN3aXRjaChGcmVlSW1hZ2VfR2V0QlBQKGRpYikpIHsKCQkJCWNhc2UgMToKCQkJCXsKCQkJCQlmb3IoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJQllURSAqYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCB5KTsKCQkJCQkJZm9yKGludCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCS8vIGdldCBwaXhlbCBhdCAoeCwgeSkKCQkJCQkJCUJZVEUgaW5kZXggPSAoYml0c1t4ID4+IDNdICYgKDB4ODAgPj4gKHggJiAweDA3KSkpICE9IDA7CgkJCQkJCQlpZih0cm5zW2luZGV4XSAhPSAweEZGKSB7CgkJCQkJCQkJLy8gc2V0IGFueSB0cmFuc3BhcmVudCBjb2xvciB0byBmdWxsIHRyYW5zcGFyZW5jeQoJCQkJCQkJCWFuZF9iaXRzW3ggPj4gM10gfD0gKDB4ODAgPj4gKHggJiAweDcpKTsgCgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJYW5kX2JpdHMgKz0gd2lkdGhfYW5kOwoJCQkJCX0KCQkJCX0KCQkJCWJyZWFrOwoKCQkJCWNhc2UgNDoKCQkJCXsKCQkJCQlmb3IoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJQllURSAqYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCB5KTsKCQkJCQkJZm9yKGludCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCS8vIGdldCBwaXhlbCBhdCAoeCwgeSkKCQkJCQkJCUJZVEUgc2hpZnQgPSAoQllURSkoKDEgLSB4ICUgMikgPDwgMik7CgkJCQkJCQlCWVRFIGluZGV4ID0gKGJpdHNbeCA+PiAxXSAmICgweDBGIDw8IHNoaWZ0KSkgPj4gc2hpZnQ7CgkJCQkJCQlpZih0cm5zW2luZGV4XSAhPSAweEZGKSB7CgkJCQkJCQkJLy8gc2V0IGFueSB0cmFuc3BhcmVudCBjb2xvciB0byBmdWxsIHRyYW5zcGFyZW5jeQoJCQkJCQkJCWFuZF9iaXRzW3ggPj4gM10gfD0gKDB4ODAgPj4gKHggJiAweDcpKTsgCgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJYW5kX2JpdHMgKz0gd2lkdGhfYW5kOwoJCQkJCX0KCQkJCX0KCQkJCWJyZWFrOwoKCQkJCWNhc2UgODoKCQkJCXsKCQkJCQlmb3IoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJQllURSAqYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCB5KTsKCQkJCQkJZm9yKGludCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCS8vIGdldCBwaXhlbCBhdCAoeCwgeSkKCQkJCQkJCUJZVEUgaW5kZXggPSBiaXRzW3hdOwoJCQkJCQkJaWYodHJuc1tpbmRleF0gIT0gMHhGRikgewoJCQkJCQkJCS8vIHNldCBhbnkgdHJhbnNwYXJlbnQgY29sb3IgdG8gZnVsbCB0cmFuc3BhcmVuY3kKCQkJCQkJCQlhbmRfYml0c1t4ID4+IDNdIHw9ICgweDgwID4+ICh4ICYgMHg3KSk7IAoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWFuZF9iaXRzICs9IHdpZHRoX2FuZDsKCQkJCQl9CgkJCQl9CgkJCQlicmVhazsKCgkJCX0KCQl9Cgl9CgllbHNlIHsKCQkvLyBlbXB0eSBBTkQgbWFzawoJCW1lbXNldChhbmRfbWFzaywgMCwgc2l6ZV9hbmQpOwoJfQoKCWlvLT53cml0ZV9wcm9jKGFuZF9tYXNrLCBzaXplX2FuZCwgMSwgaGFuZGxlKTsKCWZyZWUoYW5kX21hc2spOwoKCXJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYKU2F2ZShGcmVlSW1hZ2VJTyAqaW8sIEZJQklUTUFQICpkaWIsIGZpX2hhbmRsZSBoYW5kbGUsIGludCBwYWdlLCBpbnQgZmxhZ3MsIHZvaWQgKmRhdGEpIHsKCUlDT05IRUFERVIgKmljb25faGVhZGVyID0gTlVMTDsKCXN0ZDo6dmVjdG9yPEZJQklUTUFQKj4gdlBhZ2VzOwoJaW50IGs7CgoJaWYoIWRpYiB8fCAhaGFuZGxlIHx8ICFkYXRhKSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCS8vIGNoZWNrIGZvcm1hdCBsaW1pdHMKCXVuc2lnbmVkIHcgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKTsKCXVuc2lnbmVkIGggPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7CglpZigodyA8IDE2KSB8fCAodyA+IDI1NikgfHwgKGggPCAxNikgfHwgKGggPiAyNTYpIHx8ICh3ICE9IGgpKSB7CgkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKHNfZm9ybWF0X2lkLCAiVW5zdXBwb3J0ZWQgaWNvbiBzaXplOiB3aWR0aCB4IGhlaWdodCA9ICVkIHggJWQiLCB3LCBoKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJaWYgKHBhZ2UgPT0gLTEpIHsKCQlwYWdlID0gMDsKCX0KCQoJLy8gZ2V0IHRoZSBpY29uIGhlYWRlcgoJaWNvbl9oZWFkZXIgPSAoSUNPTkhFQURFUiopZGF0YTsKCgl0cnkgewoJCUZJQklUTUFQICppY29uX2RpYiA9IE5VTEw7CgoJCS8vIGxvYWQgYWxsIGljb25zCgkJZm9yKGsgPSAwOyBrIDwgaWNvbl9oZWFkZXItPmlkQ291bnQ7IGsrKykgewoJCQlpY29uX2RpYiA9IExvYWQoaW8sIGhhbmRsZSwgaywgZmxhZ3MsIGRhdGEpOwoJCQlpZighaWNvbl9kaWIpIHsKCQkJCXRocm93IEZJX01TR19FUlJPUl9ESUJfTUVNT1JZOwoJCQl9CgkJCXZQYWdlcy5wdXNoX2JhY2soaWNvbl9kaWIpOwoJCX0KCgkJLy8gYWRkIHRoZSBwYWdlCgkJaWNvbl9kaWIgPSBGcmVlSW1hZ2VfQ2xvbmUoZGliKTsKCQl2UGFnZXMucHVzaF9iYWNrKGljb25fZGliKTsKCQlpY29uX2hlYWRlci0+aWRDb3VudCsrOwoKCQkvLyB3cml0ZSB0aGUgaGVhZGVyCgkJaW8tPnNlZWtfcHJvYyhoYW5kbGUsIDAsIFNFRUtfU0VUKTsKI2lmZGVmIEZSRUVJTUFHRV9CSUdFTkRJQU4KCQlTd2FwSWNvbkhlYWRlcihpY29uX2hlYWRlcik7CiNlbmRpZgoJCWlvLT53cml0ZV9wcm9jKGljb25faGVhZGVyLCBzaXplb2YoSUNPTkhFQURFUiksIDEsIGhhbmRsZSk7CiNpZmRlZiBGUkVFSU1BR0VfQklHRU5ESUFOCgkJU3dhcEljb25IZWFkZXIoaWNvbl9oZWFkZXIpOwojZW5kaWYKCgkJLy8gd3JpdGUgYWxsIGljb25zCgkJLy8gLi4uCgkJCgkJLy8gc2F2ZSB0aGUgaWNvbiBkZXNjcmlwdGlvbnMKCgkJSUNPTkRJUkVOVFJZICppY29uX2xpc3QgPSAoSUNPTkRJUkVOVFJZICopbWFsbG9jKGljb25faGVhZGVyLT5pZENvdW50ICogc2l6ZW9mKElDT05ESVJFTlRSWSkpOwoJCWlmKCFpY29uX2xpc3QpIHsKCQkJdGhyb3cgRklfTVNHX0VSUk9SX01FTU9SWTsKCQl9CgkJbWVtc2V0KGljb25fbGlzdCwgMCwgaWNvbl9oZWFkZXItPmlkQ291bnQgKiBzaXplb2YoSUNPTkRJUkVOVFJZKSk7CgoJCWZvcihrID0gMDsgayA8IGljb25faGVhZGVyLT5pZENvdW50OyBrKyspIHsKCQkJaWNvbl9kaWIgPSAoRklCSVRNQVAqKXZQYWdlc1trXTsKCgkJCS8vIGNvbnZlcnQgaW50ZXJuYWwgZm9ybWF0IHRvIElDT05ESVJFTlRSWQoJCQkvLyB0YWtlIGludG8gYWNjb3VudCBWaXN0YSBpY29ucyB3aG9zZSBzaXplIGlzIDI1NngyNTYKCQkJY29uc3QgQklUTUFQSU5GT0hFQURFUiAqYm1paCA9IEZyZWVJbWFnZV9HZXRJbmZvSGVhZGVyKGljb25fZGliKTsKCQkJaWNvbl9saXN0W2tdLmJXaWR0aAkJCT0gKGJtaWgtPmJpV2lkdGggPiAyNTUpICA/IDAgOiAoQllURSlibWloLT5iaVdpZHRoOwoJCQlpY29uX2xpc3Rba10uYkhlaWdodAkJPSAoYm1paC0+YmlIZWlnaHQgPiAyNTUpID8gMCA6IChCWVRFKWJtaWgtPmJpSGVpZ2h0OwoJCQlpY29uX2xpc3Rba10uYlJlc2VydmVkCQk9IDA7CgkJCWljb25fbGlzdFtrXS53UGxhbmVzCQk9IGJtaWgtPmJpUGxhbmVzOwoJCQlpY29uX2xpc3Rba10ud0JpdENvdW50CQk9IGJtaWgtPmJpQml0Q291bnQ7CgkJCWlmKCAoaWNvbl9saXN0W2tdLndQbGFuZXMgKiBpY29uX2xpc3Rba10ud0JpdENvdW50KSA+PSA4ICkgewoJCQkJaWNvbl9saXN0W2tdLmJDb2xvckNvdW50ID0gMDsKCQkJfSBlbHNlIHsKCQkJCWljb25fbGlzdFtrXS5iQ29sb3JDb3VudCA9IChCWVRFKSgxIDw8IChpY29uX2xpc3Rba10ud1BsYW5lcyAqIGljb25fbGlzdFtrXS53Qml0Q291bnQpKTsKCQkJfQoJCQkvLyBpbml0aWFsIGd1ZXNzIChjb3JyZWN0IG9ubHkgZm9yIHN0YW5kYXJkIGljb25zKQoJCQlpY29uX2xpc3Rba10uZHdCeXRlc0luUmVzCT0gQ2FsY3VsYXRlSW1hZ2VTaXplKGljb25fZGliKTsKCQkJaWNvbl9saXN0W2tdLmR3SW1hZ2VPZmZzZXQgPSBDYWxjdWxhdGVJbWFnZU9mZnNldCh2UGFnZXMsIGspOwoJCX0KCgkJLy8gbWFrZSBhIHJvb20gZm9yIGljb24gZGlyIGVudHJpZXMsIHVudGlsIGxhdGVyIHVwZGF0ZQoJCWNvbnN0IGxvbmcgZGlyZWN0b3J5X3N0YXJ0ID0gaW8tPnRlbGxfcHJvYyhoYW5kbGUpOwoJCWlvLT53cml0ZV9wcm9jKGljb25fbGlzdCwgc2l6ZW9mKElDT05ESVJFTlRSWSkgKiBpY29uX2hlYWRlci0+aWRDb3VudCwgMSwgaGFuZGxlKTsKCgkJLy8gd3JpdGUgdGhlIGltYWdlIGJpdHMgZm9yIGVhY2ggaW1hZ2UKCQkKCQlEV09SRCBkd0ltYWdlT2Zmc2V0ID0gKERXT1JEKWlvLT50ZWxsX3Byb2MoaGFuZGxlKTsKCgkJZm9yKGsgPSAwOyBrIDwgaWNvbl9oZWFkZXItPmlkQ291bnQ7IGsrKykgewoJCQlpY29uX2RpYiA9IChGSUJJVE1BUCopdlBhZ2VzW2tdOwoJCQkKCQkJaWYoKGljb25fbGlzdFtrXS5iV2lkdGggPT0gMCkgJiYgKGljb25fbGlzdFtrXS5iSGVpZ2h0ID09IDApKSB7CgkJCQkvLyBWaXN0YSBpY29uIHN1cHBvcnQKCQkJCUZyZWVJbWFnZV9TYXZlVG9IYW5kbGUoRklGX1BORywgaWNvbl9kaWIsIGlvLCBoYW5kbGUsIFBOR19ERUZBVUxUKTsKCQkJfQoJCQllbHNlIHsKCQkJCS8vIHN0YW5kYXJkIGljb24gc3VwcG9ydAoJCQkJLy8gc2VlIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczk5NzUzOC5hc3B4CgkJCQlTYXZlU3RhbmRhcmRJY29uKGlvLCBpY29uX2RpYiwgaGFuZGxlKTsKCQkJfQoKCQkJLy8gdXBkYXRlIElDT05ESVJFTlRSWSBtZW1iZXJzCQkJCgkJCURXT1JEIGR3Qnl0ZXNJblJlcyA9IChEV09SRClpby0+dGVsbF9wcm9jKGhhbmRsZSkgLSBkd0ltYWdlT2Zmc2V0OwoJCQlpY29uX2xpc3Rba10uZHdJbWFnZU9mZnNldCA9IGR3SW1hZ2VPZmZzZXQ7CgkJCWljb25fbGlzdFtrXS5kd0J5dGVzSW5SZXMgID0gZHdCeXRlc0luUmVzOwoJCQlkd0ltYWdlT2Zmc2V0ICs9IGR3Qnl0ZXNJblJlczsKCQl9CgoJCS8vIHVwZGF0ZSB0aGUgaWNvbiBkZXNjcmlwdGlvbnMKCQljb25zdCBsb25nIGN1cnJlbnRfcG9zID0gaW8tPnRlbGxfcHJvYyhoYW5kbGUpOwoJCWlvLT5zZWVrX3Byb2MoaGFuZGxlLCBkaXJlY3Rvcnlfc3RhcnQsIFNFRUtfU0VUKTsKI2lmZGVmIEZSRUVJTUFHRV9CSUdFTkRJQU4KCQlTd2FwSWNvbkRpckVudHJpZXMoaWNvbl9saXN0LCBpY29uX2hlYWRlci0+aWRDb3VudCk7CiNlbmRpZgoJCWlvLT53cml0ZV9wcm9jKGljb25fbGlzdCwgc2l6ZW9mKElDT05ESVJFTlRSWSkgKiBpY29uX2hlYWRlci0+aWRDb3VudCwgMSwgaGFuZGxlKTsKCQlpby0+c2Vla19wcm9jKGhhbmRsZSwgY3VycmVudF9wb3MsIFNFRUtfU0VUKTsKCgkJZnJlZShpY29uX2xpc3QpOwoKCQkvLyBmcmVlIHRoZSB2ZWN0b3IgY2xhc3MKCQlmb3IoayA9IDA7IGsgPCBpY29uX2hlYWRlci0+aWRDb3VudDsgaysrKSB7CgkJCWljb25fZGliID0gKEZJQklUTUFQKil2UGFnZXNba107CgkJCUZyZWVJbWFnZV9VbmxvYWQoaWNvbl9kaWIpOwoJCX0KCgkJcmV0dXJuIFRSVUU7CgoJfSBjYXRjaChjb25zdCBjaGFyICp0ZXh0KSB7CgkJLy8gZnJlZSB0aGUgdmVjdG9yIGNsYXNzCgkJZm9yKHNpemVfdCBrID0gMDsgayA8IHZQYWdlcy5zaXplKCk7IGsrKykgewoJCQlGSUJJVE1BUCAqaWNvbl9kaWIgPSAoRklCSVRNQVAqKXZQYWdlc1trXTsKCQkJRnJlZUltYWdlX1VubG9hZChpY29uX2RpYik7CgkJfQoJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhzX2Zvcm1hdF9pZCwgdGV4dCk7CgkJcmV0dXJuIEZBTFNFOwoJfQp9CgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vICAgSW5pdAovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Cgp2b2lkIERMTF9DQUxMQ09OVgpJbml0SUNPKFBsdWdpbiAqcGx1Z2luLCBpbnQgZm9ybWF0X2lkKSB7CglzX2Zvcm1hdF9pZCA9IGZvcm1hdF9pZDsKCglwbHVnaW4tPmZvcm1hdF9wcm9jID0gRm9ybWF0OwoJcGx1Z2luLT5kZXNjcmlwdGlvbl9wcm9jID0gRGVzY3JpcHRpb247CglwbHVnaW4tPmV4dGVuc2lvbl9wcm9jID0gRXh0ZW5zaW9uOwoJcGx1Z2luLT5yZWdleHByX3Byb2MgPSBSZWdFeHByOwoJcGx1Z2luLT5vcGVuX3Byb2MgPSBPcGVuOwoJcGx1Z2luLT5jbG9zZV9wcm9jID0gQ2xvc2U7CglwbHVnaW4tPnBhZ2Vjb3VudF9wcm9jID0gUGFnZUNvdW50OwoJcGx1Z2luLT5wYWdlY2FwYWJpbGl0eV9wcm9jID0gTlVMTDsKCXBsdWdpbi0+bG9hZF9wcm9jID0gTG9hZDsKCXBsdWdpbi0+c2F2ZV9wcm9jID0gU2F2ZTsKCXBsdWdpbi0+dmFsaWRhdGVfcHJvYyA9IFZhbGlkYXRlOwoJcGx1Z2luLT5taW1lX3Byb2MgPSBNaW1lVHlwZTsKCXBsdWdpbi0+c3VwcG9ydHNfZXhwb3J0X2JwcF9wcm9jID0gU3VwcG9ydHNFeHBvcnREZXB0aDsKCXBsdWdpbi0+c3VwcG9ydHNfZXhwb3J0X3R5cGVfcHJvYyA9IFN1cHBvcnRzRXhwb3J0VHlwZTsKCXBsdWdpbi0+c3VwcG9ydHNfaWNjX3Byb2ZpbGVzX3Byb2MgPSBOVUxMOwoJcGx1Z2luLT5zdXBwb3J0c19ub19waXhlbHNfcHJvYyA9IFN1cHBvcnRzTm9QaXhlbHM7Cn0K