Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8KLy8gIExpdHRsZSBDb2xvciBNYW5hZ2VtZW50IFN5c3RlbQovLyAgQ29weXJpZ2h0IChjKSAxOTk4LTIwMTIgTWFydGkgTWFyaWEgU2FndWVyCi8vCi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZwovLyBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksCi8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24KLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsCi8vIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZQovLyBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgovLwovLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgovLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KLy8KLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCi8vIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTwovLyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORAovLyBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFCi8vIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04KLy8gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OCi8vIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgovLwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLwoKI2luY2x1ZGUgImxjbXMyX2ludGVybmFsLmgiCgoKLy8gSVQ4LjcgLyBDR0FUUy4xNy0yMDB4IGhhbmRsaW5nIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoKI2RlZmluZSBNQVhJRCAgICAgICAgMTI4ICAgICAvLyBNYXggbGVuZ3RoIG9mIGlkZW50aWZpZXIKI2RlZmluZSBNQVhTVFIgICAgICAxMDI0ICAgICAvLyBNYXggbGVuZ3RoIG9mIHN0cmluZwojZGVmaW5lIE1BWFRBQkxFUyAgICAyNTUgICAgIC8vIE1heCBOdW1iZXIgb2YgdGFibGVzIGluIGEgc2luZ2xlIHN0cmVhbQojZGVmaW5lIE1BWElOQ0xVREUgICAgMjAgICAgIC8vIE1heCBudW1iZXIgb2YgbmVzdGVkIGluY2x1ZGVzCgojZGVmaW5lIERFRkFVTFRfREJMX0ZPUk1BVCAgIiUuMTBnIiAvLyBEb3VibGUgZm9ybWF0dGluZwoKI2lmZGVmIENNU19JU19XSU5ET1dTXwovL3N1bmxpYW5nLmxpdSBtb2RpZmllZCAyMDEwNDI2IGZvciB3aW5jZSBlcnJvcgojCWlmbmRlZiBfV0lOMzJfV0NFCiMJCWluY2x1ZGUgPGlvLmg+CiMJZW5kaWYKIyAgICBkZWZpbmUgRElSX0NIQVIgICAgJ1xcJwojZWxzZQojICAgIGRlZmluZSBESVJfQ0hBUiAgICAnLycKI2VuZGlmCgoKLy8gU3ltYm9scwp0eXBlZGVmIGVudW0gewoKICAgICAgICBTTk9ORSwKICAgICAgICBTSU5VTSwgICAgICAvLyBJbnRlZ2VyCiAgICAgICAgU0ROVU0sICAgICAgLy8gUmVhbAogICAgICAgIFNJREVOVCwgICAgIC8vIElkZW50aWZpZXIKICAgICAgICBTU1RSSU5HLCAgICAvLyBzdHJpbmcKICAgICAgICBTQ09NTUVOVCwgICAvLyBjb21tZW50CiAgICAgICAgU0VPTE4sICAgICAgLy8gRW5kIG9mIGxpbmUKICAgICAgICBTRU9GLCAgICAgICAvLyBFbmQgb2Ygc3RyZWFtCiAgICAgICAgU1NZTkVSUk9SLCAgLy8gU3ludGF4IGVycm9yIGZvdW5kIG9uIHN0cmVhbQoKICAgICAgICAvLyBLZXl3b3JkcwoKICAgICAgICBTQkVHSU5fREFUQSwKICAgICAgICBTQkVHSU5fREFUQV9GT1JNQVQsCiAgICAgICAgU0VORF9EQVRBLAogICAgICAgIFNFTkRfREFUQV9GT1JNQVQsCiAgICAgICAgU0tFWVdPUkQsCiAgICAgICAgU0RBVEFfRk9STUFUX0lELAogICAgICAgIFNJTkNMVURFCgogICAgfSBTWU1CT0w7CgoKLy8gSG93IHRvIHdyaXRlIHRoZSB2YWx1ZQp0eXBlZGVmIGVudW0gewoKICAgICAgICBXUklURV9VTkNPT0tFRCwKICAgICAgICBXUklURV9TVFJJTkdJRlksCiAgICAgICAgV1JJVEVfSEVYQURFQ0lNQUwsCiAgICAgICAgV1JJVEVfQklOQVJZLAogICAgICAgIFdSSVRFX1BBSVIKCiAgICB9IFdSSVRFTU9ERTsKCi8vIExpbmtlZCBsaXN0IG9mIHZhcmlhYmxlIG5hbWVzCnR5cGVkZWYgc3RydWN0IF9LZXlWYWwgewoKICAgICAgICBzdHJ1Y3QgX0tleVZhbCogIE5leHQ7CiAgICAgICAgY2hhciogICAgICAgICAgICBLZXl3b3JkOyAgICAgICAvLyBOYW1lIG9mIHZhcmlhYmxlCiAgICAgICAgc3RydWN0IF9LZXlWYWwqICBOZXh0U3Via2V5OyAgICAvLyBJZiBrZXkgaXMgYSBkaWN0aW9uYXJ5LCBwb2ludHMgdG8gdGhlIG5leHQgaXRlbQogICAgICAgIGNoYXIqICAgICAgICAgICAgU3Via2V5OyAgICAgICAgLy8gSWYga2V5IGlzIGEgZGljdGlvbmFyeSwgcG9pbnRzIHRvIHRoZSBzdWJrZXkgbmFtZQogICAgICAgIGNoYXIqICAgICAgICAgICAgVmFsdWU7ICAgICAgICAgLy8gUG9pbnRzIHRvIHZhbHVlCiAgICAgICAgV1JJVEVNT0RFICAgICAgICBXcml0ZUFzOyAgICAgICAvLyBIb3cgdG8gd3JpdGUgdGhlIHZhbHVlCgogICB9IEtFWVZBTFVFOwoKCi8vIExpbmtlZCBsaXN0IG9mIG1lbW9yeSBjaHVua3MgKE1lbW9yeSBzaW5rKQp0eXBlZGVmIHN0cnVjdCBfT3duZWRNZW0gewoKICAgICAgICBzdHJ1Y3QgX093bmVkTWVtKiBOZXh0OwogICAgICAgIHZvaWQgKiAgICAgICAgICAgIFB0cjsgICAgICAgICAgLy8gUG9pbnQgdG8gdmFsdWUKCiAgIH0gT1dORURNRU07CgovLyBTdWJhbGxvY2F0b3IKdHlwZWRlZiBzdHJ1Y3QgX1N1YkFsbG9jYXRvciB7CgogICAgICAgICBjbXNVSW50OE51bWJlciogQmxvY2s7CiAgICAgICAgIGNtc1VJbnQzMk51bWJlciBCbG9ja1NpemU7CiAgICAgICAgIGNtc1VJbnQzMk51bWJlciBVc2VkOwoKICAgIH0gU1VCQUxMT0NBVE9SOwoKLy8gVGFibGUuIEVhY2ggaW5kaXZpZHVhbCB0YWJsZSBjYW4gaG9sZCBwcm9wZXJ0aWVzIGFuZCByb3dzICYgY29scwp0eXBlZGVmIHN0cnVjdCBfVGFibGUgewoKICAgICAgICBjaGFyIFNoZWV0VHlwZVtNQVhTVFJdOyAgICAgICAgICAgICAgIC8vIFRoZSBmaXJzdCByb3cgb2YgdGhlIElUOCAodGhlIHR5cGUpCgogICAgICAgIGludCAgICAgICAgICAgIG5TYW1wbGVzLCBuUGF0Y2hlczsgICAgLy8gQ29scywgUm93cwogICAgICAgIGludCAgICAgICAgICAgIFNhbXBsZUlEOyAgICAgICAgICAgICAgLy8gUG9zIG9mIElECgogICAgICAgIEtFWVZBTFVFKiAgICAgIEhlYWRlckxpc3Q7ICAgICAgICAgICAgLy8gVGhlIHByb3BlcnRpZXMKCiAgICAgICAgY2hhcioqICAgICAgICAgRGF0YUZvcm1hdDsgICAgICAgICAgICAvLyBUaGUgYmluYXJ5IHN0cmVhbSBkZXNjcmlwdG9yCiAgICAgICAgY2hhcioqICAgICAgICAgRGF0YTsgICAgICAgICAgICAgICAgICAvLyBUaGUgYmluYXJ5IHN0cmVhbQoKICAgIH0gVEFCTEU7CgovLyBGaWxlIHN0cmVhbSBiZWluZyBwYXJzZWQKdHlwZWRlZiBzdHJ1Y3QgX0ZpbGVDb250ZXh0IHsKICAgICAgICBjaGFyICAgICAgICAgICBGaWxlTmFtZVtjbXNNQVhfUEFUSF07ICAgIC8vIEZpbGUgbmFtZSBpZiBiZWluZyByZWFkZWQgZnJvbSBmaWxlCiAgICAgICAgRklMRSogICAgICAgICAgU3RyZWFtOyAgICAgICAgICAgICAgICAgICAvLyBGaWxlIHN0cmVhbSBvciBOVUxMIGlmIGhvbGRlZCBpbiBtZW1vcnkKICAgIH0gRklMRUNUWDsKCi8vIFRoaXMgc3RydWN0IGhvbGQgYWxsIGluZm9ybWF0aW9uIGFib3V0IGFuIG9wZW4gSVQ4IGhhbmRsZXIuCnR5cGVkZWYgc3RydWN0IHsKCgogICAgICAgIGNtc1VJbnQzMk51bWJlciAgVGFibGVzQ291bnQ7ICAgICAgICAgICAgICAgICAgICAgLy8gSG93IG1hbnkgdGFibGVzIGluIHRoaXMgc3RyZWFtCiAgICAgICAgY21zVUludDMyTnVtYmVyICBuVGFibGU7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgYWN0dWFsIHRhYmxlCgogICAgICAgIFRBQkxFIFRhYltNQVhUQUJMRVNdOwoKICAgICAgICAvLyBNZW1vcnkgbWFuYWdlbWVudAogICAgICAgIE9XTkVETUVNKiAgICAgIE1lbW9yeVNpbms7ICAgICAgICAgICAgLy8gVGhlIHN0b3JhZ2UgYmFja2VuZAogICAgICAgIFNVQkFMTE9DQVRPUiAgIEFsbG9jYXRvcjsgICAgICAgICAgICAgLy8gU3RyaW5nIHN1YmFsbG9jYXRvciAtLSBqdXN0IHRvIGtlZXAgaXQgZmFzdAoKICAgICAgICAvLyBQYXJzZXIgc3RhdGUgbWFjaGluZQogICAgICAgIFNZTUJPTCAgICAgICAgIHN5OyAgICAgICAgICAgICAgICAgICAgLy8gQ3VycmVudCBzeW1ib2wKICAgICAgICBpbnQgICAgICAgICAgICBjaDsgICAgICAgICAgICAgICAgICAgIC8vIEN1cnJlbnQgY2hhcmFjdGVyCgogICAgICAgIGludCAgICAgICAgICAgIGludW07ICAgICAgICAgICAgICAgICAgLy8gaW50ZWdlciB2YWx1ZQogICAgICAgIGNtc0Zsb2F0NjROdW1iZXIgICAgICAgICBkbnVtOyAgICAgICAgICAgICAgICAgIC8vIHJlYWwgdmFsdWUKICAgICAgICBjaGFyICAgICAgICAgICBpZFtNQVhJRF07ICAgICAgICAgICAgIC8vIGlkZW50aWZpZXIKICAgICAgICBjaGFyICAgICAgICAgICBzdHJbTUFYU1RSXTsgICAgICAgICAgIC8vIHN0cmluZwoKICAgICAgICAvLyBBbGxvd2VkIGtleXdvcmRzICYgZGF0YXNldHMuIFRoZXkgaGF2ZSB2aXNpYmlsaXR5IG9uIHdob2xlIHN0cmVhbQogICAgICAgIEtFWVZBTFVFKiAgICAgVmFsaWRLZXl3b3JkczsKICAgICAgICBLRVlWQUxVRSogICAgIFZhbGlkU2FtcGxlSUQ7CgogICAgICAgIGNoYXIqICAgICAgICAgIFNvdXJjZTsgICAgICAgICAgICAgICAgLy8gUG9pbnRzIHRvIGxvYy4gYmVpbmcgcGFyc2VkCiAgICAgICAgaW50ICAgICAgICAgICAgbGluZW5vOyAgICAgICAgICAgICAgICAvLyBsaW5lIGNvdW50ZXIgZm9yIGVycm9yIHJlcG9ydGluZwoKICAgICAgICBGSUxFQ1RYKiAgICAgICBGaWxlU3RhY2tbTUFYSU5DTFVERV07IC8vIFN0YWNrIG9mIGZpbGVzIGJlaW5nIHBhcnNlZAogICAgICAgIGludCAgICAgICAgICAgIEluY2x1ZGVTUDsgICAgICAgICAgICAgLy8gSW5jbHVkZSBTdGFjayBQb2ludGVyCgogICAgICAgIGNoYXIqICAgICAgICAgIE1lbW9yeUJsb2NrOyAgICAgICAgICAgLy8gVGhlIHN0cmVhbSBpZiBob2xkZWQgaW4gbWVtb3J5CgogICAgICAgIGNoYXIgICAgICAgICAgIERvdWJsZUZvcm1hdHRlcltNQVhJRF07Ly8gUHJpbnRmLWxpa2UgJ2Ntc0Zsb2F0NjROdW1iZXInIGZvcm1hdHRlcgoKICAgICAgICBjbXNDb250ZXh0ICAgIENvbnRleHRJRDsgICAgICAgICAgICAgIC8vIFRoZSB0aHJlYWRpbmcgY29udGV4dAoKICAgfSBjbXNJVDg7CgoKLy8gVGhlIHN0cmVhbSBmb3Igc2F2ZSBvcGVyYXRpb25zCnR5cGVkZWYgc3RydWN0IHsKCiAgICAgICAgRklMRSogc3RyZWFtOyAgIC8vIEZvciBzYXZlLXRvLWZpbGUgYmVoYXZpb3VyCgogICAgICAgIGNtc1VJbnQ4TnVtYmVyKiBCYXNlOwogICAgICAgIGNtc1VJbnQ4TnVtYmVyKiBQdHI7ICAgICAgICAvLyBGb3Igc2F2ZS10by1tZW0gYmVoYXZpb3VyCiAgICAgICAgY21zVUludDMyTnVtYmVyIFVzZWQ7CiAgICAgICAgY21zVUludDMyTnVtYmVyIE1heDsKCiAgICB9IFNBVkVTVFJFQU07CgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGNtc0lUOCBwYXJzaW5nIHJvdXRpbmVzCgoKLy8gQSBrZXl3b3JkCnR5cGVkZWYgc3RydWN0IHsKCiAgICAgICAgY29uc3QgY2hhciAqaWQ7CiAgICAgICAgU1lNQk9MIHN5OwoKICAgfSBLRVlXT1JEOwoKLy8gVGhlIGtleXdvcmQtPnN5bWJvbCB0cmFuc2xhdGlvbiB0YWJsZS4gU29ydGluZyBpcyByZXF1aXJlZC4Kc3RhdGljIGNvbnN0IEtFWVdPUkQgVGFiS2V5c1tdID0gewoKICAgICAgICB7IiRJTkNMVURFIiwgICAgICAgICAgICAgICBTSU5DTFVERX0sICAgLy8gVGhpcyBpcyBhbiBleHRlbnNpb24hCiAgICAgICAgeyIuSU5DTFVERSIsICAgICAgICAgICAgICAgU0lOQ0xVREV9LCAgIC8vIFRoaXMgaXMgYW4gZXh0ZW5zaW9uIQoKICAgICAgICB7IkJFR0lOX0RBVEEiLCAgICAgICAgICAgICBTQkVHSU5fREFUQSB9LAogICAgICAgIHsiQkVHSU5fREFUQV9GT1JNQVQiLCAgICAgIFNCRUdJTl9EQVRBX0ZPUk1BVCB9LAogICAgICAgIHsiREFUQV9GT1JNQVRfSURFTlRJRklFUiIsIFNEQVRBX0ZPUk1BVF9JRH0sCiAgICAgICAgeyJFTkRfREFUQSIsICAgICAgICAgICAgICAgU0VORF9EQVRBfSwKICAgICAgICB7IkVORF9EQVRBX0ZPUk1BVCIsICAgICAgICBTRU5EX0RBVEFfRk9STUFUfSwKICAgICAgICB7IktFWVdPUkQiLCAgICAgICAgICAgICAgICBTS0VZV09SRH0KICAgICAgICB9OwoKI2RlZmluZSBOVU1LRVlTIChzaXplb2YoVGFiS2V5cykvc2l6ZW9mKEtFWVdPUkQpKQoKLy8gUHJlZGVmaW5lZCBwcm9wZXJ0aWVzCgovLyBBIHByb3BlcnR5CnR5cGVkZWYgc3RydWN0IHsKICAgICAgICBjb25zdCBjaGFyICppZDsgICAgLy8gVGhlIGlkZW50aWZpZXIKICAgICAgICBXUklURU1PREUgYXM7ICAgICAgLy8gSG93IGlzIHN1cHBvc2VkIHRvIGJlIHdyaXR0ZW4KICAgIH0gUFJPUEVSVFk7CgpzdGF0aWMgUFJPUEVSVFkgUHJlZGVmaW5lZFByb3BlcnRpZXNbXSA9IHsKCiAgICAgICAgeyJOVU1CRVJfT0ZfRklFTERTIiwgV1JJVEVfVU5DT09LRUR9LCAgICAvLyBSZXF1aXJlZCAtIE5VTUJFUiBPRiBGSUVMRFMKICAgICAgICB7Ik5VTUJFUl9PRl9TRVRTIiwgICBXUklURV9VTkNPT0tFRH0sICAgIC8vIFJlcXVpcmVkIC0gTlVNQkVSIE9GIFNFVFMKICAgICAgICB7Ik9SSUdJTkFUT1IiLCAgICAgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIFJlcXVpcmVkIC0gSWRlbnRpZmllcyB0aGUgc3BlY2lmaWMgc3lzdGVtLCBvcmdhbml6YXRpb24gb3IgaW5kaXZpZHVhbCB0aGF0IGNyZWF0ZWQgdGhlIGRhdGEgZmlsZS4KICAgICAgICB7IkZJTEVfREVTQ1JJUFRPUiIsICBXUklURV9TVFJJTkdJRll9LCAgIC8vIFJlcXVpcmVkIC0gRGVzY3JpYmVzIHRoZSBwdXJwb3NlIG9yIGNvbnRlbnRzIG9mIHRoZSBkYXRhIGZpbGUuCiAgICAgICAgeyJDUkVBVEVEIiwgICAgICAgICAgV1JJVEVfU1RSSU5HSUZZfSwgICAvLyBSZXF1aXJlZCAtIEluZGljYXRlcyBkYXRlIG9mIGNyZWF0aW9uIG9mIHRoZSBkYXRhIGZpbGUuCiAgICAgICAgeyJERVNDUklQVE9SIiwgICAgICAgV1JJVEVfU1RSSU5HSUZZfSwgICAvLyBSZXF1aXJlZCAgLSBEZXNjcmliZXMgdGhlIHB1cnBvc2Ugb3IgY29udGVudHMgb2YgdGhlIGRhdGEgZmlsZS4KICAgICAgICB7IkRJRkZVU0VfR0VPTUVUUlkiLCBXUklURV9TVFJJTkdJRll9LCAgIC8vIFRoZSBkaWZmdXNlIGdlb21ldHJ5IHVzZWQuIEFsbG93ZWQgdmFsdWVzIGFyZSAic3BoZXJlIiBvciAib3BhbCIuCiAgICAgICAgeyJNQU5VRkFDVFVSRVIiLCAgICAgV1JJVEVfU1RSSU5HSUZZfSwKICAgICAgICB7Ik1BTlVGQUNUVVJFIiwgICAgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIFNvbWUgYnJva2VuIEZ1amkgdGFyZ2V0cyBkb2VzIHN0b3JlIHRoaXMgdmFsdWUKICAgICAgICB7IlBST0RfREFURSIsICAgICAgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIElkZW50aWZpZXMgeWVhciBhbmQgbW9udGggb2YgcHJvZHVjdGlvbiBvZiB0aGUgdGFyZ2V0IGluIHRoZSBmb3JtIHl5eXk6bW0uCiAgICAgICAgeyJTRVJJQUwiLCAgICAgICAgICAgV1JJVEVfU1RSSU5HSUZZfSwgICAvLyBVbmlxdWVseSBpZGVudGlmaWVzIGluZGl2aWR1YWwgcGh5c2ljYWwgdGFyZ2V0LgoKICAgICAgICB7Ik1BVEVSSUFMIiwgICAgICAgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIElkZW50aWZpZXMgdGhlIG1hdGVyaWFsIG9uIHdoaWNoIHRoZSB0YXJnZXQgd2FzIHByb2R1Y2VkIHVzaW5nIGEgY29kZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdW5pcXVlbHkgaWRlbnRpZnlpbmcgdGggZSBtYXRlcmlhbC4gVGhpcyBpcyBpbnRlbmQgZWQgdG8gYmUgdXNlZCBmb3IgSVQ4LjcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHBoeXNpY2FsIHRhcmdldHMgb25seSAoaS5lIC4gSVQ4LjcvMSBhIG5kIElUOC43LzIpLgoKICAgICAgICB7IklOU1RSVU1FTlRBVElPTiIsICBXUklURV9TVFJJTkdJRll9LCAgIC8vIFVzZWQgdG8gcmVwb3J0IHRoZSBzcGVjaWZpYyBpbnN0cnVtZW50YXRpb24gdXNlZCAobWFudWZhY3R1cmVyIGFuZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbW9kZWwgbnVtYmVyKSB0byBnZW5lcmF0ZSB0aGUgZGF0YSByZXBvcnRlZC4gVGhpcyBkYXRhIHdpbGwgb2Z0ZW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByb3ZpZGUgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGFydGljdWxhciBkYXRhIGNvbGxlY3RlZCB0aGFuIGFuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBleHRlbnNpdmUgbGlzdCBvZiBzcGVjaWZpYyBkZXRhaWxzLiBUaGlzIGlzIHBhcnRpY3VsYXJseSBpbXBvcnRhbnQgZm9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzcGVjdHJhbCBkYXRhIG9yIGRhdGEgZGVyaXZlZCBmcm9tIHNwZWN0cm9waG90b21ldHJ5LgoKICAgICAgICB7Ik1FQVNVUkVNRU5UX1NPVVJDRSIsIFdSSVRFX1NUUklOR0lGWX0sIC8vIElsbHVtaW5hdGlvbiB1c2VkIGZvciBzcGVjdHJhbCBtZWFzdXJlbWVudHMuIFRoaXMgZGF0YSBoZWxwcyBwcm92aWRlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhIGd1aWRlIHRvIHRoZSBwb3RlbnRpYWwgZm9yIGlzc3VlcyBvZiBwYXBlciBmbHVvcmVzY2VuY2UsIGV0Yy4KCiAgICAgICAgeyJQUklOVF9DT05ESVRJT05TIiwgV1JJVEVfU1RSSU5HSUZZfSwgICAvLyBVc2VkIHRvIGRlZmluZSB0aGUgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBwcmludGVkIHNoZWV0IGJlaW5nIHJlcG9ydGVkLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2hlcmUgc3RhbmRhcmQgY29uZGl0aW9ucyBoYXZlIGJlZW4gZGVmaW5lZCAoZS5nLiwgU1dPUCBhdCBub21pbmFsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmFtZWQgY29uZGl0aW9ucyBtYXkgc3VmZmljZS4gT3RoZXJ3aXNlLCBkZXRhaWxlZCBpbmZvcm1hdGlvbiBpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmVlZGVkLgoKICAgICAgICB7IlNBTVBMRV9CQUNLSU5HIiwgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIElkZW50aWZpZXMgdGhlIGJhY2tpbmcgbWF0ZXJpYWwgdXNlZCBiZWhpbmQgdGhlIHNhbXBsZSBkdXJpbmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1lYXN1cmVtZW50LiBBbGxvd2VkIHZhbHVlcyBhcmUgk2JsYWNrPyCTd2hpdGU/IG9yIHsibmEiLgoKICAgICAgICB7IkNISVNRX0RPRiIsICAgICAgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIERlZ3JlZXMgb2YgZnJlZWRvbSBhc3NvY2lhdGVkIHdpdGggdGhlIENoaSBzcXVhcmVkIHN0YXRpc3RpYwoKICAgICAgIC8vIGJlbG93IHByb3BlcnRpZXMgYXJlIG5ldyBpbiByZWNlbnQgc3BlY3M6CgogICAgICAgIHsiTUVBU1VSRU1FTlRfR0VPTUVUUlkiLCBXUklURV9TVFJJTkdJRll9LCAvLyBUaGUgdHlwZSBvZiBtZWFzdXJlbWVudCwgZWl0aGVyIHJlZmxlY3Rpb24gb3IgdHJhbnNtaXNzaW9uLCBzaG91bGQgYmUgaW5kaWNhdGVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbG9uZyB3aXRoIGRldGFpbHMgb2YgdGhlIGdlb21ldHJ5IGFuZCB0aGUgYXBlcnR1cmUgc2l6ZSBhbmQgc2hhcGUuIEZvciBleGFtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIHRyYW5zbWlzc2lvbiBtZWFzdXJlbWVudHMgaXQgaXMgaW1wb3J0YW50IHRvIGlkZW50aWZ5IDAvZGlmZnVzZSwgZGlmZnVzZS8wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3BhbCBvciBpbnRlZ3JhdGluZyBzcGhlcmUsIGV0Yy4gRm9yIHJlZmxlY3Rpb24gaXQgaXMgaW1wb3J0YW50IHRvIGlkZW50aWZ5IDAvNDUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA0NS8wLCBzcGhlcmUgKHNwZWN1bGFyIGluY2x1ZGVkIG9yIGV4Y2x1ZGVkKSwgZXRjLgoKICAgICAgIHsiRklMVEVSIiwgICAgICAgICAgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIElkZW50aWZpZXMgdGhlIHVzZSBvZiBwaHlzaWNhbCBmaWx0ZXIocykgZHVyaW5nIG1lYXN1cmVtZW50LiBUeXBpY2FsbHkgdXNlZCB0bwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVub3RlIHRoZSB1c2Ugb2YgZmlsdGVycyBzdWNoIGFzIG5vbmUsIEQ2NSwgUmVkLCBHcmVlbiBvciBCbHVlLgoKICAgICAgIHsiUE9MQVJJWkFUSU9OIiwgICAgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIElkZW50aWZpZXMgdGhlIHVzZSBvZiBhIHBoeXNpY2FsIHBvbGFyaXphdGlvbiBmaWx0ZXIgZHVyaW5nIG1lYXN1cmVtZW50LiBBbGxvd2VkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2YWx1ZXMgYXJlIHsieWVzPyCTd2hpdGU/IJNub25lP29yIJNuYT8KCiAgICAgICB7IldFSUdIVElOR19GVU5DVElPTiIsIFdSSVRFX1BBSVJ9LCAgIC8vIEluZGljYXRlcyBzdWNoIGZ1bmN0aW9ucyBhczogdGhlIENJRSBzdGFuZGFyZCBvYnNlcnZlciBmdW5jdGlvbnMgdXNlZCBpbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbGN1bGF0aW9uIG9mIHZhcmlvdXMgZGF0YSBwYXJhbWV0ZXJzICgyIGRlZ3JlZSBhbmQgMTAgZGVncmVlKSwgQ0lFIHN0YW5kYXJkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbGx1bWluYW50IGZ1bmN0aW9ucyB1c2VkIGluIHRoZSBjYWxjdWxhdGlvbiBvZiB2YXJpb3VzIGRhdGEgcGFyYW1ldGVycyAoZS5nLiwgRDUwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRDY1LCBldGMuKSwgZGVuc2l0eSBzdGF0dXMgcmVzcG9uc2UsIGV0Yy4gSWYgdXNlZCB0aGVyZSBzaGFsbCBiZSBhdCBsZWFzdCBvbmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5hbWUtdmFsdWUgcGFpciBmb2xsb3dpbmcgdGhlIFdFSUdIVElOR19GVU5DVElPTiB0YWcva2V5d29yZC4gVGhlIGZpcnN0IGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW4gdGhlIHNldCBzaGFsbCBiZSB7Im5hbWUiIGFuZCBzaGFsbCBpZGVudGlmeSB0aGUgcGFydGljdWxhciBwYXJhbWV0ZXIgdXNlZC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBzZWNvbmQgc2hhbGwgYmUgeyJ2YWx1ZSIgYW5kIHNoYWxsIHByb3ZpZGUgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGF0IG5hbWUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3IgQVNDSUkgZGF0YSwgYSBzdHJpbmcgY29udGFpbmluZyB0aGUgTmFtZSBhbmQgVmFsdWUgYXR0cmlidXRlIHBhaXJzIHNoYWxsIGZvbGxvdwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHdlaWdodGluZyBmdW5jdGlvbiBrZXl3b3JkLiBBIHNlbWktY29sb24gc2VwYXJhdGVzIGF0dHJpYnV0ZSBwYWlycyBmcm9tIGVhY2gKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG90aGVyIGFuZCB3aXRoaW4gdGhlIGF0dHJpYnV0ZSB0aGUgbmFtZSBhbmQgdmFsdWUgYXJlIHNlcGFyYXRlZCBieSBhIGNvbW1hLgoKICAgICAgIHsiQ09NUFVUQVRJT05BTF9QQVJBTUVURVIiLCBXUklURV9QQUlSfSwgLy8gUGFyYW1ldGVyIHRoYXQgaXMgdXNlZCBpbiBjb21wdXRpbmcgYSB2YWx1ZSBmcm9tIG1lYXN1cmVkIGRhdGEuIE5hbWUgaXMgdGhlIG5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9mIHRoZSBjYWxjdWxhdGlvbiwgcGFyYW1ldGVyIGlzIHRoZSBuYW1lIG9mIHRoZSBwYXJhbWV0ZXIgdXNlZCBpbiB0aGUgY2FsY3VsYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCB2YWx1ZSBpcyB0aGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlci4KCiAgICAgICB7IlRBUkdFVF9UWVBFIiwgICAgICAgIFdSSVRFX1NUUklOR0lGWX0sICAvLyBUaGUgdHlwZSBvZiB0YXJnZXQgYmVpbmcgbWVhc3VyZWQsIGUuZy4gSVQ4LjcvMSwgSVQ4LjcvMywgdXNlciBkZWZpbmVkLCBldGMuCgogICAgICAgeyJDT0xPUkFOVCIsICAgICAgICAgICBXUklURV9TVFJJTkdJRll9LCAgLy8gSWRlbnRpZmllcyB0aGUgY29sb3JhbnQocykgdXNlZCBpbiBjcmVhdGluZyB0aGUgdGFyZ2V0LgoKICAgICAgIHsiVEFCTEVfREVTQ1JJUFRPUiIsICAgV1JJVEVfU1RSSU5HSUZZfSwgIC8vIERlc2NyaWJlcyB0aGUgcHVycG9zZSBvciBjb250ZW50cyBvZiBhIGRhdGEgdGFibGUuCgogICAgICAgeyJUQUJMRV9OQU1FIiwgICAgICAgICBXUklURV9TVFJJTkdJRll9ICAgLy8gUHJvdmlkZXMgYSBzaG9ydCBuYW1lIGZvciBhIGRhdGEgdGFibGUuCn07CgojZGVmaW5lIE5VTVBSRURFRklORURQUk9QUyAoc2l6ZW9mKFByZWRlZmluZWRQcm9wZXJ0aWVzKS9zaXplb2YoUFJPUEVSVFkpKQoKCi8vIFByZWRlZmluZWQgc2FtcGxlIHR5cGVzIG9uIGRhdGFzZXQKc3RhdGljIGNvbnN0IGNoYXIqIFByZWRlZmluZWRTYW1wbGVJRFtdID0gewogICAgICAgICJTQU1QTEVfSUQiLCAgICAgIC8vIElkZW50aWZpZXMgc2FtcGxlIHRoYXQgZGF0YSByZXByZXNlbnRzCiAgICAgICAgIlNUUklORyIsICAgICAgICAgLy8gSWRlbnRpZmllcyBsYWJlbCwgb3Igb3RoZXIgbm9uLW1hY2hpbmUgcmVhZGFibGUgdmFsdWUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmFsdWUgbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggYSAiIHN5bWJvbAoKICAgICAgICAiQ01ZS19DIiwgICAgICAgICAvLyBDeWFuIGNvbXBvbmVudCBvZiBDTVlLIGRhdGEgZXhwcmVzc2VkIGFzIGEgcGVyY2VudGFnZQogICAgICAgICJDTVlLX00iLCAgICAgICAgIC8vIE1hZ2VudGEgY29tcG9uZW50IG9mIENNWUsgZGF0YSBleHByZXNzZWQgYXMgYSBwZXJjZW50YWdlCiAgICAgICAgIkNNWUtfWSIsICAgICAgICAgLy8gWWVsbG93IGNvbXBvbmVudCBvZiBDTVlLIGRhdGEgZXhwcmVzc2VkIGFzIGEgcGVyY2VudGFnZQogICAgICAgICJDTVlLX0siLCAgICAgICAgIC8vIEJsYWNrIGNvbXBvbmVudCBvZiBDTVlLIGRhdGEgZXhwcmVzc2VkIGFzIGEgcGVyY2VudGFnZQogICAgICAgICJEX1JFRCIsICAgICAgICAgIC8vIFJlZCBmaWx0ZXIgZGVuc2l0eQogICAgICAgICJEX0dSRUVOIiwgICAgICAgIC8vIEdyZWVuIGZpbHRlciBkZW5zaXR5CiAgICAgICAgIkRfQkxVRSIsICAgICAgICAgLy8gQmx1ZSBmaWx0ZXIgZGVuc2l0eQogICAgICAgICJEX1ZJUyIsICAgICAgICAgIC8vIFZpc3VhbCBmaWx0ZXIgZGVuc2l0eQogICAgICAgICJEX01BSk9SX0ZJTFRFUiIsIC8vIE1ham9yIGZpbHRlciBkIGVuc2l0eQogICAgICAgICJSR0JfUiIsICAgICAgICAgIC8vIFJlZCBjb21wb25lbnQgb2YgUkdCIGRhdGEKICAgICAgICAiUkdCX0ciLCAgICAgICAgICAvLyBHcmVlbiBjb21wb25lbnQgb2YgUkdCIGRhdGEKICAgICAgICAiUkdCX0IiLCAgICAgICAgICAvLyBCbHVlIGNvbSBwb25lbnQgb2YgUkdCIGRhdGEKICAgICAgICAiU1BFQ1RSQUxfTk0iLCAgICAvLyBXYXZlbGVuZ3RoIG9mIG1lYXN1cmVtZW50IGV4cHJlc3NlZCBpbiBuYW5vbWV0ZXJzCiAgICAgICAgIlNQRUNUUkFMX1BDVCIsICAgLy8gUGVyY2VudGFnZSByZWZsZWN0YW5jZS90cmFuc21pdHRhbmNlCiAgICAgICAgIlNQRUNUUkFMX0RFQyIsICAgLy8gUmVmbGVjdGFuY2UvdHJhbnNtaXR0YW5jZQogICAgICAgICJYWVpfWCIsICAgICAgICAgIC8vIFggY29tcG9uZW50IG9mIHRyaXN0aW11bHVzIGRhdGEKICAgICAgICAiWFlaX1kiLCAgICAgICAgICAvLyBZIGNvbXBvbmVudCBvZiB0cmlzdGltdWx1cyBkYXRhCiAgICAgICAgIlhZWl9aIiwgICAgICAgICAgLy8gWiBjb21wb25lbnQgb2YgdHJpc3RpbXVsdXMgZGF0YQogICAgICAgICJYWVlfWCIgICAgICAgICAgIC8vIHggY29tcG9uZW50IG9mIGNocm9tYXRpY2l0eSBkYXRhCiAgICAgICAgIlhZWV9ZIiwgICAgICAgICAgLy8geSBjb21wb25lbnQgb2YgY2hyb21hdGljaXR5IGRhdGEKICAgICAgICAiWFlZX0NBUFkiLCAgICAgICAvLyBZIGNvbXBvbmVudCBvZiB0cmlzdGltdWx1cyBkYXRhCiAgICAgICAgIkxBQl9MIiwgICAgICAgICAgLy8gTCogY29tcG9uZW50IG9mIExhYiBkYXRhCiAgICAgICAgIkxBQl9BIiwgICAgICAgICAgLy8gYSogY29tcG9uZW50IG9mIExhYiBkYXRhCiAgICAgICAgIkxBQl9CIiwgICAgICAgICAgLy8gYiogY29tcG9uZW50IG9mIExhYiBkYXRhCiAgICAgICAgIkxBQl9DIiwgICAgICAgICAgLy8gQyphYiBjb21wb25lbnQgb2YgTGFiIGRhdGEKICAgICAgICAiTEFCX0giLCAgICAgICAgICAvLyBoYWIgY29tcG9uZW50IG9mIExhYiBkYXRhCiAgICAgICAgIkxBQl9ERSIsICAgICAgICAgLy8gQ0lFIGRFCiAgICAgICAgIkxBQl9ERV85NCIsICAgICAgLy8gQ0lFIGRFIHVzaW5nIENJRSA5NAogICAgICAgICJMQUJfREVfQ01DIiwgICAgIC8vIGRFIHVzaW5nIENNQwogICAgICAgICJMQUJfREVfMjAwMCIsICAgIC8vIENJRSBkRSB1c2luZyBDSUUgREUgMjAwMAogICAgICAgICJNRUFOX0RFIiwgICAgICAgIC8vIE1lYW4gRGVsdGEgRSAoTEFCX0RFKSBvZiBzYW1wbGVzIGNvbXBhcmVkIHRvIGJhdGNoIGF2ZXJhZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAoVXNlZCBmb3IgZGF0YSBmaWxlcyBmb3IgQU5TSSBJVDguNy8xIGFuZCBJVDguNy8yIHRhcmdldHMpCiAgICAgICAgIlNUREVWX1giLCAgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIFggKHRyaXN0aW11bHVzIGRhdGEpCiAgICAgICAgIlNUREVWX1kiLCAgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIFkgKHRyaXN0aW11bHVzIGRhdGEpCiAgICAgICAgIlNUREVWX1oiLCAgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIFogKHRyaXN0aW11bHVzIGRhdGEpCiAgICAgICAgIlNUREVWX0wiLCAgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIEwqCiAgICAgICAgIlNUREVWX0EiLCAgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIGEqCiAgICAgICAgIlNUREVWX0IiLCAgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIGIqCiAgICAgICAgIlNUREVWX0RFIiwgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIENJRSBkRQogICAgICAgICJDSElfU1FEX1BBUiJ9OyAgIC8vIFRoZSBhdmVyYWdlIG9mIHRoZSBzdGFuZGFyZCBkZXZpYXRpb25zIG9mIEwqLCBhKiBhbmQgYiouIEl0IGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXNlZCB0byBkZXJpdmUgYW4gZXN0aW1hdGUgb2YgdGhlIGNoaS1zcXVhcmVkIHBhcmFtZXRlciB3aGljaCBpcwogICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlY29tbWVuZGVkIGFzIHRoZSBwcmVkaWN0b3Igb2YgdGhlIHZhcmlhYmlsaXR5IG9mIGRFCgojZGVmaW5lIE5VTVBSRURFRklORURTQU1QTEVJRCAoc2l6ZW9mKFByZWRlZmluZWRTYW1wbGVJRCkvc2l6ZW9mKGNoYXIgKikpCgovL0ZvcndhcmQgZGVjbGFyYXRpb24gb2Ygc29tZSBpbnRlcm5hbCBmdW5jdGlvbnMKc3RhdGljIHZvaWQqIEFsbG9jQ2h1bmsoY21zSVQ4KiBpdDgsIGNtc1VJbnQzMk51bWJlciBzaXplKTsKCi8vIENoZWNrcyB3aGF0ZXZlciBjIGlzIGEgc2VwYXJhdG9yCnN0YXRpYwpjbXNCb29sIGlzc2VwYXJhdG9yKGludCBjKQp7CiAgICByZXR1cm4gKGMgPT0gJyAnKSB8fCAoYyA9PSAnXHQnKSA7IAp9CgovLyBDaGVja3Mgd2hhdGV2ZXIgYyBpcyBhIHZhbGlkIGlkZW50aWZpZXIgY2hhcgpzdGF0aWMKY21zQm9vbCBpc21pZGRsZShpbnQgYykKewogICByZXR1cm4gKCFpc3NlcGFyYXRvcihjKSAmJiAoYyAhPSAnIycpICYmIChjICE9J1wiJykgJiYgKGMgIT0gJ1wnJykgJiYgKGMgPiAzMikgJiYgKGMgPCAxMjcpKTsKfQoKLy8gQ2hlY2tzIHdoYXRzZXZlciBjIGlzIGEgdmFsaWQgaWRlbnRpZmllciBtaWRkbGUgY2hhci4Kc3RhdGljCmNtc0Jvb2wgaXNpZGNoYXIoaW50IGMpCnsKICAgcmV0dXJuIGlzYWxudW0oYykgfHwgaXNtaWRkbGUoYyk7Cn0KCi8vIENoZWNrcyB3aGF0c2V2ZXIgYyBpcyBhIHZhbGlkIGlkZW50aWZpZXIgZmlyc3QgY2hhci4Kc3RhdGljCmNtc0Jvb2wgaXNmaXJzdGlkY2hhcihpbnQgYykKewogICAgIHJldHVybiAhaXNkaWdpdChjKSAmJiBpc21pZGRsZShjKTsKfQoKLy8gR3Vlc3Mgd2hldGhlciB0aGUgc3VwcGxpZWQgcGF0aCBsb29rcyBsaWtlIGFuIGFic29sdXRlIHBhdGgKc3RhdGljCmNtc0Jvb2wgaXNhYnNvbHV0ZXBhdGgoY29uc3QgY2hhciAqcGF0aCkKewogICAgY2hhciBUaHJlZUNoYXJzWzRdOwoKICAgIGlmKHBhdGggPT0gTlVMTCkKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBpZiAocGF0aFswXSA9PSAwKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBzdHJuY3B5KFRocmVlQ2hhcnMsIHBhdGgsIDMpOwogICAgVGhyZWVDaGFyc1szXSA9IDA7CgogICAgaWYoVGhyZWVDaGFyc1swXSA9PSBESVJfQ0hBUikKICAgICAgICByZXR1cm4gVFJVRTsKCiNpZmRlZiAgQ01TX0lTX1dJTkRPV1NfCiAgICBpZiAoaXNhbHBoYSgoaW50KSBUaHJlZUNoYXJzWzBdKSAmJiBUaHJlZUNoYXJzWzFdID09ICc6JykKICAgICAgICByZXR1cm4gVFJVRTsKI2VuZGlmCiAgICByZXR1cm4gRkFMU0U7Cn0KCgovLyBNYWtlcyBhIGZpbGUgcGF0aCBiYXNlZCBvbiBhIGdpdmVuIHJlZmVyZW5jZSBwYXRoCi8vIE5PVEU6IHRoaXMgZnVuY3Rpb24gZG9lc24ndCBjaGVjayBpZiB0aGUgcGF0aCBleGlzdHMgb3IgZXZlbiBpZiBpdCdzIGxlZ2FsCnN0YXRpYwpjbXNCb29sIEJ1aWxkQWJzb2x1dGVQYXRoKGNvbnN0IGNoYXIgKnJlbFBhdGgsIGNvbnN0IGNoYXIgKmJhc2VQYXRoLCBjaGFyICpidWZmZXIsIGNtc1VJbnQzMk51bWJlciBNYXhMZW4pCnsKICAgIGNoYXIgKnRhaWw7CiAgICBjbXNVSW50MzJOdW1iZXIgbGVuOwoKICAgIC8vIEFscmVhZHkgYWJzb2x1dGU/CiAgICBpZiAoaXNhYnNvbHV0ZXBhdGgocmVsUGF0aCkpIHsKCiAgICAgICAgc3RybmNweShidWZmZXIsIHJlbFBhdGgsIE1heExlbik7CiAgICAgICAgYnVmZmVyW01heExlbi0xXSA9IDA7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgLy8gTm8sIHNlYXJjaCBmb3IgbGFzdAogICAgc3RybmNweShidWZmZXIsIGJhc2VQYXRoLCBNYXhMZW4pOwogICAgYnVmZmVyW01heExlbi0xXSA9IDA7CgogICAgdGFpbCA9IHN0cnJjaHIoYnVmZmVyLCBESVJfQ0hBUik7CiAgICBpZiAodGFpbCA9PSBOVUxMKSByZXR1cm4gRkFMU0U7ICAgIC8vIElzIG5vdCBhYnNvbHV0ZSBhbmQgaGFzIG5vIHNlcGFyYXRvcnM/PwoKICAgIGxlbiA9IChjbXNVSW50MzJOdW1iZXIpICh0YWlsIC0gYnVmZmVyKTsKICAgIGlmIChsZW4gPj0gTWF4TGVuKSByZXR1cm4gRkFMU0U7CgogICAgLy8gTm8gbmVlZCB0byBhc3N1cmUgemVybyB0ZXJtaW5hdG9yIG92ZXIgaGVyZQogICAgc3RybmNweSh0YWlsICsgMSwgcmVsUGF0aCwgTWF4TGVuIC0gbGVuKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKCi8vIE1ha2Ugc3VyZSBubyBleHBsb2l0IGlzIGJlaW5nIGV2ZW4gdHJpZWQKc3RhdGljCmNvbnN0IGNoYXIqIE5vTWV0YShjb25zdCBjaGFyKiBzdHIpCnsKICAgIGlmIChzdHJjaHIoc3RyLCAnJScpICE9IE5VTEwpCiAgICAgICAgcmV0dXJuICIqKioqIENPUlJVUFRFRCBGT1JNQVQgU1RSSU5HICoqKiI7CgogICAgcmV0dXJuIHN0cjsKfQoKLy8gU3ludGF4IGVycm9yCnN0YXRpYwpjbXNCb29sIFN5bkVycm9yKGNtc0lUOCogaXQ4LCBjb25zdCBjaGFyICpUeHQsIC4uLikKewogICAgY2hhciBCdWZmZXJbMjU2XSwgRXJyTXNnWzEwMjRdOwogICAgdmFfbGlzdCBhcmdzOwoKICAgIHZhX3N0YXJ0KGFyZ3MsIFR4dCk7CiAgICB2c25wcmludGYoQnVmZmVyLCAyNTUsIFR4dCwgYXJncyk7CiAgICBCdWZmZXJbMjU1XSA9IDA7CiAgICB2YV9lbmQoYXJncyk7CgogICAgc25wcmludGYoRXJyTXNnLCAxMDIzLCAiJXM6IExpbmUgJWQsICVzIiwgaXQ4LT5GaWxlU3RhY2tbaXQ4IC0+SW5jbHVkZVNQXS0+RmlsZU5hbWUsIGl0OC0+bGluZW5vLCBCdWZmZXIpOwogICAgRXJyTXNnWzEwMjNdID0gMDsKICAgIGl0OC0+c3kgPSBTU1lORVJST1I7CiAgICBjbXNTaWduYWxFcnJvcihpdDggLT5Db250ZXh0SUQsIGNtc0VSUk9SX0NPUlJVUFRJT05fREVURUNURUQsICIlcyIsIEVyck1zZyk7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8vIENoZWNrIGlmIGN1cnJlbnQgc3ltYm9sIGlzIHNhbWUgYXMgc3BlY2lmaWVkLiBpc3N1ZSBhbiBlcnJvciBlbHNlLgpzdGF0aWMKY21zQm9vbCBDaGVjayhjbXNJVDgqIGl0OCwgU1lNQk9MIHN5LCBjb25zdCBjaGFyKiBFcnIpCnsKICAgICAgICBpZiAoaXQ4IC0+IHN5ICE9IHN5KQogICAgICAgICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgTm9NZXRhKEVycikpOwogICAgICAgIHJldHVybiBUUlVFOwp9CgovLyBSZWFkIE5leHQgY2hhcmFjdGVyIGZyb20gc3RyZWFtCnN0YXRpYwp2b2lkIE5leHRDaChjbXNJVDgqIGl0OCkKewogICAgaWYgKGl0OCAtPiBGaWxlU3RhY2tbaXQ4IC0+SW5jbHVkZVNQXS0+U3RyZWFtKSB7CgogICAgICAgIGl0OCAtPmNoID0gZmdldGMoaXQ4IC0+RmlsZVN0YWNrW2l0OCAtPkluY2x1ZGVTUF0tPlN0cmVhbSk7CgogICAgICAgIGlmIChmZW9mKGl0OCAtPiBGaWxlU3RhY2tbaXQ4IC0+SW5jbHVkZVNQXS0+U3RyZWFtKSkgIHsKCiAgICAgICAgICAgIGlmIChpdDggLT5JbmNsdWRlU1AgPiAwKSB7CgogICAgICAgICAgICAgICAgZmNsb3NlKGl0OCAtPkZpbGVTdGFja1tpdDgtPkluY2x1ZGVTUC0tXS0+U3RyZWFtKTsKICAgICAgICAgICAgICAgIGl0OCAtPiBjaCA9ICcgJzsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2hpdGVzcGFjZSB0byBiZSBpZ25vcmVkCgogICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgIGl0OCAtPmNoID0gMDsgICAvLyBFT0YKICAgICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBpdDgtPmNoID0gKml0OC0+U291cmNlOwogICAgICAgIGlmIChpdDgtPmNoKSBpdDgtPlNvdXJjZSsrOwogICAgfQp9CgoKLy8gVHJ5IHRvIHNlZSBpZiBjdXJyZW50IGlkZW50aWZpZXIgaXMgYSBrZXl3b3JkLCBpZiBzbyByZXR1cm4gdGhlIHJlZmVycmVkIHN5bWJvbApzdGF0aWMKU1lNQk9MIEJpblNyY2hLZXkoY29uc3QgY2hhciAqaWQpCnsKICAgIGludCBsID0gMTsKICAgIGludCByID0gTlVNS0VZUzsKICAgIGludCB4LCByZXM7CgogICAgd2hpbGUgKHIgPj0gbCkKICAgIHsKICAgICAgICB4ID0gKGwrcikvMjsKICAgICAgICByZXMgPSBjbXNzdHJjYXNlY21wKGlkLCBUYWJLZXlzW3gtMV0uaWQpOwogICAgICAgIGlmIChyZXMgPT0gMCkgcmV0dXJuIFRhYktleXNbeC0xXS5zeTsKICAgICAgICBpZiAocmVzIDwgMCkgciA9IHggLSAxOwogICAgICAgIGVsc2UgbCA9IHggKyAxOwogICAgfQoKICAgIHJldHVybiBTTk9ORTsKfQoKCi8vIDEwIF5uCnN0YXRpYwpjbXNGbG9hdDY0TnVtYmVyIHhwb3cxMChpbnQgbikKewogICAgcmV0dXJuIHBvdygxMCwgKGNtc0Zsb2F0NjROdW1iZXIpIG4pOwp9CgoKLy8gIFJlYWRzIGEgUmVhbCBudW1iZXIsIHRyaWVzIHRvIGZvbGxvdyBmcm9tIGludGVnZXIgbnVtYmVyCnN0YXRpYwp2b2lkIFJlYWRSZWFsKGNtc0lUOCogaXQ4LCBpbnQgaW51bSkKewogICAgaXQ4LT5kbnVtID0gKGNtc0Zsb2F0NjROdW1iZXIpIGludW07CgogICAgd2hpbGUgKGlzZGlnaXQoaXQ4LT5jaCkpIHsKCiAgICAgICAgaXQ4LT5kbnVtID0gaXQ4LT5kbnVtICogMTAuMCArIChpdDgtPmNoIC0gJzAnKTsKICAgICAgICBOZXh0Q2goaXQ4KTsKICAgIH0KCiAgICBpZiAoaXQ4LT5jaCA9PSAnLicpIHsgICAgICAgIC8vIERlY2ltYWwgcG9pbnQKCiAgICAgICAgY21zRmxvYXQ2NE51bWJlciBmcmFjID0gMC4wOyAgICAgIC8vIGZyYWN0aW9uCiAgICAgICAgaW50IHByZWMgPSAwOyAgICAgICAgICAgICAgICAgICAgIC8vIHByZWNpc2lvbgoKICAgICAgICBOZXh0Q2goaXQ4KTsgICAgICAgICAgICAgICAvLyBFYXRzIGRlYy4gcG9pbnQKCiAgICAgICAgd2hpbGUgKGlzZGlnaXQoaXQ4LT5jaCkpIHsKCiAgICAgICAgICAgIGZyYWMgPSBmcmFjICogMTAuMCArIChpdDgtPmNoIC0gJzAnKTsKICAgICAgICAgICAgcHJlYysrOwogICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICB9CgogICAgICAgIGl0OC0+ZG51bSA9IGl0OC0+ZG51bSArIChmcmFjIC8geHBvdzEwKHByZWMpKTsKICAgIH0KCiAgICAvLyBFeHBvbmVudCwgZXhhbXBsZSAzNC4wMEUrMjAKICAgIGlmICh0b3VwcGVyKGl0OC0+Y2gpID09ICdFJykgewoKICAgICAgICBpbnQgZTsKICAgICAgICBpbnQgc2duOwoKICAgICAgICBOZXh0Q2goaXQ4KTsgc2duID0gMTsKCiAgICAgICAgaWYgKGl0OC0+Y2ggPT0gJy0nKSB7CgogICAgICAgICAgICBzZ24gPSAtMTsgTmV4dENoKGl0OCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgICAgaWYgKGl0OC0+Y2ggPT0gJysnKSB7CgogICAgICAgICAgICAgICAgc2duID0gKzE7CiAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZSA9IDA7CiAgICAgICAgICAgIHdoaWxlIChpc2RpZ2l0KGl0OC0+Y2gpKSB7CgogICAgICAgICAgICAgICAgaWYgKChjbXNGbG9hdDY0TnVtYmVyKSBlICogMTBMIDwgSU5UX01BWCkKICAgICAgICAgICAgICAgICAgICBlID0gZSAqIDEwICsgKGl0OC0+Y2ggLSAnMCcpOwoKICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBlID0gc2duKmU7CiAgICAgICAgICAgIGl0OCAtPiBkbnVtID0gaXQ4IC0+IGRudW0gKiB4cG93MTAoZSk7CiAgICB9Cn0KCi8vIFBhcnNlcyBhIGZsb2F0IG51bWJlcgovLyBUaGlzIGNhbiBub3QgY2FsbCBkaXJlY3RseSBhdG9mIGJlY2F1c2UgaXQgdXNlcyBsb2NhbGUgZGVwZW5kYW50Ci8vIHBhcnNpbmcsIHdoaWxlIENDTVggZmlsZXMgYWx3YXlzIHVzZSAuIGFzIGRlY2ltYWwgc2VwYXJhdG9yCnN0YXRpYwpjbXNGbG9hdDY0TnVtYmVyIFBhcnNlRmxvYXROdW1iZXIoY29uc3QgY2hhciAqQnVmZmVyKQp7CiAgICBjbXNGbG9hdDY0TnVtYmVyIGRudW0gPSAwLjA7CiAgICBpbnQgc2lnbiA9IDE7CgogICAgLy8ga2VlcCBzYWZlCiAgICBpZiAoQnVmZmVyID09IE5VTEwpIHJldHVybiAwLjA7CgogICAgaWYgKCpCdWZmZXIgPT0gJy0nIHx8ICpCdWZmZXIgPT0gJysnKSB7CgogICAgICAgICBzaWduID0gKCpCdWZmZXIgPT0gJy0nKSA/IC0xIDogMTsKICAgICAgICAgQnVmZmVyKys7CiAgICB9CgoKICAgIHdoaWxlICgqQnVmZmVyICYmIGlzZGlnaXQoKGludCkgKkJ1ZmZlcikpIHsKCiAgICAgICAgZG51bSA9IGRudW0gKiAxMC4wICsgKCpCdWZmZXIgLSAnMCcpOwogICAgICAgIGlmICgqQnVmZmVyKSBCdWZmZXIrKzsKICAgIH0KCiAgICBpZiAoKkJ1ZmZlciA9PSAnLicpIHsKCiAgICAgICAgY21zRmxvYXQ2NE51bWJlciBmcmFjID0gMC4wOyAgICAgIC8vIGZyYWN0aW9uCiAgICAgICAgaW50IHByZWMgPSAwOyAgICAgICAgICAgICAgICAgICAgIC8vIHByZWNpc3Npb24KCiAgICAgICAgaWYgKCpCdWZmZXIpIEJ1ZmZlcisrOwoKICAgICAgICB3aGlsZSAoKkJ1ZmZlciAmJiBpc2RpZ2l0KChpbnQpICpCdWZmZXIpKSB7CgogICAgICAgICAgICBmcmFjID0gZnJhYyAqIDEwLjAgKyAoKkJ1ZmZlciAtICcwJyk7CiAgICAgICAgICAgIHByZWMrKzsKICAgICAgICAgICAgaWYgKCpCdWZmZXIpIEJ1ZmZlcisrOwogICAgICAgIH0KCiAgICAgICAgZG51bSA9IGRudW0gKyAoZnJhYyAvIHhwb3cxMChwcmVjKSk7CiAgICB9CgogICAgLy8gRXhwb25lbnQsIGV4YW1wbGUgMzQuMDBFKzIwCiAgICBpZiAoKkJ1ZmZlciAmJiB0b3VwcGVyKCpCdWZmZXIpID09ICdFJykgewoKICAgICAgICBpbnQgZTsKICAgICAgICBpbnQgc2duOwoKICAgICAgICBpZiAoKkJ1ZmZlcikgQnVmZmVyKys7CiAgICAgICAgc2duID0gMTsKCiAgICAgICAgaWYgKCpCdWZmZXIgPT0gJy0nKSB7CgogICAgICAgICAgICBzZ24gPSAtMTsKICAgICAgICAgICAgaWYgKCpCdWZmZXIpIEJ1ZmZlcisrOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIGlmICgqQnVmZmVyID09ICcrJykgewoKICAgICAgICAgICAgICAgIHNnbiA9ICsxOwogICAgICAgICAgICAgICAgaWYgKCpCdWZmZXIpIEJ1ZmZlcisrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBlID0gMDsKICAgICAgICAgICAgd2hpbGUgKCpCdWZmZXIgJiYgaXNkaWdpdCgoaW50KSAqQnVmZmVyKSkgewoKICAgICAgICAgICAgICAgIGlmICgoY21zRmxvYXQ2NE51bWJlcikgZSAqIDEwTCA8IElOVF9NQVgpCiAgICAgICAgICAgICAgICAgICAgZSA9IGUgKiAxMCArICgqQnVmZmVyIC0gJzAnKTsKCiAgICAgICAgICAgICAgICBpZiAoKkJ1ZmZlcikgQnVmZmVyKys7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGUgPSBzZ24qZTsKICAgICAgICAgICAgZG51bSA9IGRudW0gKiB4cG93MTAoZSk7CiAgICB9CgogICAgcmV0dXJuIHNpZ24gKiBkbnVtOwp9CgoKLy8gUmVhZHMgbmV4dCBzeW1ib2wKc3RhdGljCnZvaWQgSW5TeW1ib2woY21zSVQ4KiBpdDgpCnsKICAgIHJlZ2lzdGVyIGNoYXIgKmlkcHRyOwogICAgcmVnaXN0ZXIgaW50IGs7CiAgICBTWU1CT0wga2V5OwogICAgaW50IHNuZzsKICAgIAogICAgZG8gewoKICAgICAgICB3aGlsZSAoaXNzZXBhcmF0b3IoaXQ4LT5jaCkpCiAgICAgICAgICAgIE5leHRDaChpdDgpOwoKICAgICAgICBpZiAoaXNmaXJzdGlkY2hhcihpdDgtPmNoKSkgeyAgICAgICAgICAvLyBJZGVudGlmaWVyCgogICAgICAgICAgICBrID0gMDsKICAgICAgICAgICAgaWRwdHIgPSBpdDgtPmlkOwoKICAgICAgICAgICAgZG8gewoKICAgICAgICAgICAgICAgIGlmICgrK2sgPCBNQVhJRCkgKmlkcHRyKysgPSAoY2hhcikgaXQ4LT5jaDsKCiAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsKCiAgICAgICAgICAgIH0gd2hpbGUgKGlzaWRjaGFyKGl0OC0+Y2gpKTsKCiAgICAgICAgICAgICppZHB0ciA9ICdcMCc7CgoKICAgICAgICAgICAga2V5ID0gQmluU3JjaEtleShpdDgtPmlkKTsKICAgICAgICAgICAgaWYgKGtleSA9PSBTTk9ORSkgaXQ4LT5zeSA9IFNJREVOVDsKICAgICAgICAgICAgZWxzZSBpdDgtPnN5ID0ga2V5OwoKICAgICAgICB9CiAgICAgICAgZWxzZSAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJcyBhIG51bWJlcj8KICAgICAgICAgICAgaWYgKGlzZGlnaXQoaXQ4LT5jaCkgfHwgaXQ4LT5jaCA9PSAnLicgfHwgaXQ4LT5jaCA9PSAnLScgfHwgaXQ4LT5jaCA9PSAnKycpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCBzaWduID0gMTsKCiAgICAgICAgICAgICAgICBpZiAoaXQ4LT5jaCA9PSAnLScpIHsKICAgICAgICAgICAgICAgICAgICBzaWduID0gLTE7CiAgICAgICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaXQ4LT5pbnVtID0gMDsKICAgICAgICAgICAgICAgIGl0OC0+c3kgICA9IFNJTlVNOwoKICAgICAgICAgICAgICAgIGlmIChpdDgtPmNoID09ICcwJykgeyAgICAgICAgICAvLyAweG5ubm4gKEhleGEpIG9yIDBibm5ubiAoQmluYXJ5KQoKICAgICAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgICAgICAgICBpZiAodG91cHBlcihpdDgtPmNoKSA9PSAnWCcpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgIGludCBqOwoKICAgICAgICAgICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChpc3hkaWdpdChpdDgtPmNoKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQ4LT5jaCA9IHRvdXBwZXIoaXQ4LT5jaCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXQ4LT5jaCA+PSAnQScgJiYgaXQ4LT5jaCA8PSAnRicpICBqID0gaXQ4LT5jaCAtJ0EnKzEwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBqID0gaXQ4LT5jaCAtICcwJzsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGxvbmcpIGl0OC0+aW51bSAqIDE2TCA+IChsb25nKSBJTlRfTUFYKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIkludmFsaWQgaGV4YWRlY2ltYWwgbnVtYmVyIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0OC0+aW51bSA9IGl0OC0+aW51bSAqIDE2ICsgajsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh0b3VwcGVyKGl0OC0+Y2gpID09ICdCJykgeyAgLy8gQmluYXJ5CgogICAgICAgICAgICAgICAgICAgICAgICBpbnQgajsKCiAgICAgICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaXQ4LT5jaCA9PSAnMCcgfHwgaXQ4LT5jaCA9PSAnMScpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGogPSBpdDgtPmNoIC0gJzAnOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobG9uZykgaXQ4LT5pbnVtICogMkwgPiAobG9uZykgSU5UX01BWCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeW5FcnJvcihpdDgsICJJbnZhbGlkIGJpbmFyeSBudW1iZXIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQ4LT5pbnVtID0gaXQ4LT5pbnVtICogMiArIGo7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICB3aGlsZSAoaXNkaWdpdChpdDgtPmNoKSkgewoKICAgICAgICAgICAgICAgICAgICBpZiAoKGxvbmcpIGl0OC0+aW51bSAqIDEwTCA+IChsb25nKSBJTlRfTUFYKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRSZWFsKGl0OCwgaXQ4LT5pbnVtKTsKICAgICAgICAgICAgICAgICAgICAgICAgaXQ4LT5zeSA9IFNETlVNOwogICAgICAgICAgICAgICAgICAgICAgICBpdDgtPmRudW0gKj0gc2lnbjsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaXQ4LT5pbnVtID0gaXQ4LT5pbnVtICogMTAgKyAoaXQ4LT5jaCAtICcwJyk7CiAgICAgICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGl0OC0+Y2ggPT0gJy4nKSB7CgogICAgICAgICAgICAgICAgICAgIFJlYWRSZWFsKGl0OCwgaXQ4LT5pbnVtKTsKICAgICAgICAgICAgICAgICAgICBpdDgtPnN5ID0gU0ROVU07CiAgICAgICAgICAgICAgICAgICAgaXQ4LT5kbnVtICo9IHNpZ247CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGl0OCAtPiBpbnVtICo9IHNpZ247CgogICAgICAgICAgICAgICAgLy8gU3BlY2lhbCBjYXNlLiBOdW1iZXJzIGZvbGxvd2VkIGJ5IGxldHRlcnMgYXJlIHRha2VuIGFzIGlkZW50aWZpZXJzCgogICAgICAgICAgICAgICAgaWYgKGlzaWRjaGFyKGl0OCAtPmNoKSkgewoKICAgICAgICAgICAgICAgICAgICBpZiAoaXQ4IC0+c3kgPT0gU0lOVU0pIHsKCiAgICAgICAgICAgICAgICAgICAgICAgIHNwcmludGYoaXQ4LT5pZCwgIiVkIiwgaXQ4LT5pbnVtKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CgogICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKGl0OC0+aWQsIGl0OCAtPkRvdWJsZUZvcm1hdHRlciwgaXQ4LT5kbnVtKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGsgPSAoaW50KSBzdHJsZW4oaXQ4IC0+aWQpOwogICAgICAgICAgICAgICAgICAgIGlkcHRyID0gaXQ4IC0+aWQgKyBrOwogICAgICAgICAgICAgICAgICAgIGRvIHsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgrK2sgPCBNQVhJRCkgKmlkcHRyKysgPSAoY2hhcikgaXQ4LT5jaDsKCiAgICAgICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwoKICAgICAgICAgICAgICAgICAgICB9IHdoaWxlIChpc2lkY2hhcihpdDgtPmNoKSk7CgogICAgICAgICAgICAgICAgICAgICppZHB0ciA9ICdcMCc7CiAgICAgICAgICAgICAgICAgICAgaXQ4LT5zeSA9IFNJREVOVDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgc3dpdGNoICgoaW50KSBpdDgtPmNoKSB7CgogICAgICAgIC8vIEVPRiBtYXJrZXIgLS0gaWdub3JlIGl0CiAgICAgICAgY2FzZSAnXHgxYSc6CiAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgLy8gRW9mIHN0cmVhbSBtYXJrZXJzCiAgICAgICAgY2FzZSAwOgogICAgICAgIGNhc2UgLTE6CiAgICAgICAgICAgIGl0OC0+c3kgPSBTRU9GOwogICAgICAgICAgICBicmVhazsKCgogICAgICAgIC8vIE5leHQgbGluZQogICAgICAgIGNhc2UgJ1xyJzoKICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgIGlmIChpdDggLT5jaCA9PSAnXG4nKSAKICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICBpdDgtPnN5ID0gU0VPTE47CiAgICAgICAgICAgIGl0OC0+bGluZW5vKys7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlICdcbic6CiAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICBpdDgtPnN5ID0gU0VPTE47CiAgICAgICAgICAgIGl0OC0+bGluZW5vKys7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAvLyBDb21tZW50CiAgICAgICAgY2FzZSAnIyc6CiAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICB3aGlsZSAoaXQ4LT5jaCAmJiBpdDgtPmNoICE9ICdcbicgJiYgaXQ4LT5jaCAhPSAnXHInKQogICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CgogICAgICAgICAgICBpdDgtPnN5ID0gU0NPTU1FTlQ7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAvLyBTdHJpbmcuCiAgICAgICAgY2FzZSAnXCcnOgogICAgICAgIGNhc2UgJ1wiJzoKICAgICAgICAgICAgaWRwdHIgPSBpdDgtPnN0cjsKICAgICAgICAgICAgc25nID0gaXQ4LT5jaDsKICAgICAgICAgICAgayA9IDA7CiAgICAgICAgICAgIE5leHRDaChpdDgpOwoKICAgICAgICAgICAgd2hpbGUgKGsgPCBNQVhTVFIgJiYgaXQ4LT5jaCAhPSBzbmcpIHsKCiAgICAgICAgICAgICAgICBpZiAoaXQ4LT5jaCA9PSAnXG4nfHwgaXQ4LT5jaCA9PSAnXHInKSBrID0gTUFYU1RSKzE7CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAqaWRwdHIrKyA9IChjaGFyKSBpdDgtPmNoOwogICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICAgICAgICAgIGsrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaXQ4LT5zeSA9IFNTVFJJTkc7CiAgICAgICAgICAgICppZHB0ciA9ICdcMCc7CiAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICBicmVhazsKCgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIlVucmVjb2duaXplZCBjaGFyYWN0ZXI6IDB4JXgiLCBpdDggLT5jaCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgIH0gd2hpbGUgKGl0OC0+c3kgPT0gU0NPTU1FTlQpOwoKICAgIC8vIEhhbmRsZSB0aGUgaW5jbHVkZSBzcGVjaWFsIHRva2VuCgogICAgaWYgKGl0OCAtPiBzeSA9PSBTSU5DTFVERSkgewoKICAgICAgICAgICAgICAgIEZJTEVDVFgqIEZpbGVOZXN0OwoKICAgICAgICAgICAgICAgIGlmKGl0OCAtPiBJbmNsdWRlU1AgPj0gKE1BWElOQ0xVREUtMSkpIHsKCiAgICAgICAgICAgICAgICAgICAgU3luRXJyb3IoaXQ4LCAiVG9vIG1hbnkgcmVjdXJzaW9uIGxldmVscyIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICAgICAgaWYgKCFDaGVjayhpdDgsIFNTVFJJTkcsICJGaWxlbmFtZSBleHBlY3RlZCIpKSByZXR1cm47CgogICAgICAgICAgICAgICAgRmlsZU5lc3QgPSBpdDggLT4gRmlsZVN0YWNrW2l0OCAtPiBJbmNsdWRlU1AgKyAxXTsKICAgICAgICAgICAgICAgIGlmKEZpbGVOZXN0ID09IE5VTEwpIHsKCiAgICAgICAgICAgICAgICAgICAgRmlsZU5lc3QgPSBpdDggLT5GaWxlU3RhY2tbaXQ4IC0+IEluY2x1ZGVTUCArIDFdID0gKEZJTEVDVFgqKUFsbG9jQ2h1bmsoaXQ4LCBzaXplb2YoRklMRUNUWCkpOwogICAgICAgICAgICAgICAgICAgIC8vaWYoRmlsZU5lc3QgPT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICAvLyAgVE9ETzogaG93IHRvIG1hbmFnZSBvdXQtb2YtbWVtb3J5IGNvbmRpdGlvbnM/CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKEJ1aWxkQWJzb2x1dGVQYXRoKGl0OC0+c3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0OC0+RmlsZVN0YWNrW2l0OC0+SW5jbHVkZVNQXS0+RmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZU5lc3QtPkZpbGVOYW1lLCBjbXNNQVhfUEFUSC0xKSA9PSBGQUxTRSkgewogICAgICAgICAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIkZpbGUgcGF0aCB0b28gbG9uZyIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBGaWxlTmVzdC0+U3RyZWFtID0gZm9wZW4oRmlsZU5lc3QtPkZpbGVOYW1lLCAicnQiKTsKICAgICAgICAgICAgICAgIGlmIChGaWxlTmVzdC0+U3RyZWFtID09IE5VTEwpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIkZpbGUgJXMgbm90IGZvdW5kIiwgRmlsZU5lc3QtPkZpbGVOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaXQ4LT5JbmNsdWRlU1ArKzsKCiAgICAgICAgICAgICAgICBpdDggLT5jaCA9ICcgJzsKICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICB9Cgp9CgovLyBDaGVja3MgZW5kIG9mIGxpbmUgc2VwYXJhdG9yCnN0YXRpYwpjbXNCb29sIENoZWNrRU9MTihjbXNJVDgqIGl0OCkKewogICAgICAgIGlmICghQ2hlY2soaXQ4LCBTRU9MTiwgIkV4cGVjdGVkIHNlcGFyYXRvciIpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgd2hpbGUgKGl0OCAtPiBzeSA9PSBTRU9MTikKICAgICAgICAgICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgICAgICByZXR1cm4gVFJVRTsKCn0KCi8vIFNraXAgYSBzeW1ib2wKCnN0YXRpYwp2b2lkIFNraXAoY21zSVQ4KiBpdDgsIFNZTUJPTCBzeSkKewogICAgICAgIGlmIChpdDgtPnN5ID09IHN5ICYmIGl0OC0+c3kgIT0gU0VPRikKICAgICAgICAgICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKfQoKCi8vIFNraXAgbXVsdGlwbGUgRU9MTgpzdGF0aWMKdm9pZCBTa2lwRU9MTihjbXNJVDgqIGl0OCkKewogICAgd2hpbGUgKGl0OC0+c3kgPT0gU0VPTE4pIHsKICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICB9Cn0KCgovLyBSZXR1cm5zIGEgc3RyaW5nIGhvbGRpbmcgY3VycmVudCB2YWx1ZQpzdGF0aWMKY21zQm9vbCBHZXRWYWwoY21zSVQ4KiBpdDgsIGNoYXIqIEJ1ZmZlciwgY21zVUludDMyTnVtYmVyIG1heCwgY29uc3QgY2hhciogRXJyb3JUaXRsZSkKewogICAgc3dpdGNoIChpdDgtPnN5KSB7CgogICAgY2FzZSBTRU9MTjogICAvLyBFbXB0eSB2YWx1ZQogICAgICAgICAgICAgICAgICBCdWZmZXJbMF09MDsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICBjYXNlIFNJREVOVDogIHN0cm5jcHkoQnVmZmVyLCBpdDgtPmlkLCBtYXgpOwogICAgICAgICAgICAgICAgICBCdWZmZXJbbWF4LTFdPTA7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgY2FzZSBTSU5VTTogICBzbnByaW50ZihCdWZmZXIsIG1heCwgIiVkIiwgaXQ4IC0+IGludW0pOyBicmVhazsKICAgIGNhc2UgU0ROVU06ICAgc25wcmludGYoQnVmZmVyLCBtYXgsIGl0OC0+RG91YmxlRm9ybWF0dGVyLCBpdDggLT4gZG51bSk7IGJyZWFrOwogICAgY2FzZSBTU1RSSU5HOiBzdHJuY3B5KEJ1ZmZlciwgaXQ4LT5zdHIsIG1heCk7CiAgICAgICAgICAgICAgICAgIEJ1ZmZlclttYXgtMV0gPSAwOwogICAgICAgICAgICAgICAgICBicmVhazsKCgogICAgZGVmYXVsdDoKICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIiVzIiwgRXJyb3JUaXRsZSk7CiAgICB9CgogICAgQnVmZmVyW21heF0gPSAwOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gVGFibGUKCnN0YXRpYwpUQUJMRSogR2V0VGFibGUoY21zSVQ4KiBpdDgpCnsKICAgaWYgKChpdDggLT4gblRhYmxlID49IGl0OCAtPlRhYmxlc0NvdW50KSkgewoKICAgICAgICAgICBTeW5FcnJvcihpdDgsICJUYWJsZSAlZCBvdXQgb2Ygc2VxdWVuY2UiLCBpdDggLT4gblRhYmxlKTsKICAgICAgICAgICByZXR1cm4gaXQ4IC0+IFRhYjsKICAgfQoKICAgcmV0dXJuIGl0OCAtPlRhYiArIGl0OCAtPm5UYWJsZTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNZW1vcnkgbWFuYWdlbWVudAoKCi8vIEZyZWVzIGFuIGFsbG9jYXRvciBhbmQgb3duZWQgbWVtb3J5CnZvaWQgQ01TRVhQT1JUIGNtc0lUOEZyZWUoY21zSEFORExFIGhJVDgpCnsKICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKCiAgICBpZiAoaXQ4ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChpdDgtPk1lbW9yeVNpbmspIHsKCiAgICAgICAgT1dORURNRU0qIHA7CiAgICAgICAgT1dORURNRU0qIG47CgogICAgICAgIGZvciAocCA9IGl0OC0+TWVtb3J5U2luazsgcCAhPSBOVUxMOyBwID0gbikgewoKICAgICAgICAgICAgbiA9IHAtPk5leHQ7CiAgICAgICAgICAgIGlmIChwLT5QdHIpIF9jbXNGcmVlKGl0OCAtPkNvbnRleHRJRCwgcC0+UHRyKTsKICAgICAgICAgICAgX2Ntc0ZyZWUoaXQ4IC0+Q29udGV4dElELCBwKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGl0OC0+TWVtb3J5QmxvY2spCiAgICAgICAgX2Ntc0ZyZWUoaXQ4IC0+Q29udGV4dElELCBpdDgtPk1lbW9yeUJsb2NrKTsKCiAgICBfY21zRnJlZShpdDggLT5Db250ZXh0SUQsIGl0OCk7Cn0KCgovLyBBbGxvY2F0ZXMgYSBjaHVuayBvZiBkYXRhLCBrZWVwIGxpbmtlZCBsaXN0CnN0YXRpYwp2b2lkKiBBbGxvY0JpZ0Jsb2NrKGNtc0lUOCogaXQ4LCBjbXNVSW50MzJOdW1iZXIgc2l6ZSkKewogICAgT1dORURNRU0qIHB0cjE7CiAgICB2b2lkKiBwdHIgPSBfY21zTWFsbG9jWmVybyhpdDgtPkNvbnRleHRJRCwgc2l6ZSk7CgogICAgaWYgKHB0ciAhPSBOVUxMKSB7CgogICAgICAgIHB0cjEgPSAoT1dORURNRU0qKSBfY21zTWFsbG9jWmVybyhpdDggLT5Db250ZXh0SUQsIHNpemVvZihPV05FRE1FTSkpOwoKICAgICAgICBpZiAocHRyMSA9PSBOVUxMKSB7CgogICAgICAgICAgICBfY21zRnJlZShpdDggLT5Db250ZXh0SUQsIHB0cik7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KCiAgICAgICAgcHRyMS0+IFB0ciAgICAgICAgPSBwdHI7CiAgICAgICAgcHRyMS0+IE5leHQgICAgICAgPSBpdDggLT4gTWVtb3J5U2luazsKICAgICAgICBpdDggLT4gTWVtb3J5U2luayA9IHB0cjE7CiAgICB9CgogICAgcmV0dXJuIHB0cjsKfQoKCi8vIFN1YmFsbG9jYXRvci4Kc3RhdGljCnZvaWQqIEFsbG9jQ2h1bmsoY21zSVQ4KiBpdDgsIGNtc1VJbnQzMk51bWJlciBzaXplKQp7CiAgICBjbXNVSW50MzJOdW1iZXIgRnJlZSA9IGl0OCAtPkFsbG9jYXRvci5CbG9ja1NpemUgLSBpdDggLT5BbGxvY2F0b3IuVXNlZDsKICAgIGNtc1VJbnQ4TnVtYmVyKiBwdHI7CgogICAgc2l6ZSA9IF9jbXNBTElHTk1FTShzaXplKTsKCiAgICBpZiAoc2l6ZSA+IEZyZWUpIHsKCiAgICAgICAgaWYgKGl0OCAtPiBBbGxvY2F0b3IuQmxvY2tTaXplID09IDApCgogICAgICAgICAgICAgICAgaXQ4IC0+IEFsbG9jYXRvci5CbG9ja1NpemUgPSAyMCoxMDI0OwogICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGl0OCAtPkFsbG9jYXRvci5CbG9ja1NpemUgKj0gMjsKCiAgICAgICAgaWYgKGl0OCAtPkFsbG9jYXRvci5CbG9ja1NpemUgPCBzaXplKQogICAgICAgICAgICAgICAgaXQ4IC0+QWxsb2NhdG9yLkJsb2NrU2l6ZSA9IHNpemU7CgogICAgICAgIGl0OCAtPkFsbG9jYXRvci5Vc2VkID0gMDsKICAgICAgICBpdDggLT5BbGxvY2F0b3IuQmxvY2sgPSAoY21zVUludDhOdW1iZXIqKSAgQWxsb2NCaWdCbG9jayhpdDgsIGl0OCAtPkFsbG9jYXRvci5CbG9ja1NpemUpOwogICAgfQoKICAgIHB0ciA9IGl0OCAtPkFsbG9jYXRvci5CbG9jayArIGl0OCAtPkFsbG9jYXRvci5Vc2VkOwogICAgaXQ4IC0+QWxsb2NhdG9yLlVzZWQgKz0gc2l6ZTsKCiAgICByZXR1cm4gKHZvaWQqKSBwdHI7Cgp9CgoKLy8gQWxsb2NhdGVzIGEgc3RyaW5nCnN0YXRpYwpjaGFyICpBbGxvY1N0cmluZyhjbXNJVDgqIGl0OCwgY29uc3QgY2hhciogc3RyKQp7CiAgICBjbXNVSW50MzJOdW1iZXIgU2l6ZSA9IChjbXNVSW50MzJOdW1iZXIpIHN0cmxlbihzdHIpKzE7CiAgICBjaGFyICpwdHI7CgoKICAgIHB0ciA9IChjaGFyICopIEFsbG9jQ2h1bmsoaXQ4LCBTaXplKTsKICAgIGlmIChwdHIpIHN0cm5jcHkgKHB0ciwgc3RyLCBTaXplLTEpOwoKICAgIHJldHVybiBwdHI7Cn0KCi8vIFNlYXJjaGVzIHRocm91Z2ggbGlua2VkIGxpc3QKCnN0YXRpYwpjbXNCb29sIElzQXZhaWxhYmxlT25MaXN0KEtFWVZBTFVFKiBwLCBjb25zdCBjaGFyKiBLZXksIGNvbnN0IGNoYXIqIFN1YmtleSwgS0VZVkFMVUUqKiBMYXN0UHRyKQp7CiAgICBpZiAoTGFzdFB0cikgKkxhc3RQdHIgPSBwOwoKICAgIGZvciAoOyAgcCAhPSBOVUxMOyBwID0gcC0+TmV4dCkgewoKICAgICAgICBpZiAoTGFzdFB0cikgKkxhc3RQdHIgPSBwOwoKICAgICAgICBpZiAoKktleSAhPSAnIycpIHsgLy8gQ29tbWVudHMgYXJlIGlnbm9yZWQKCiAgICAgICAgICAgIGlmIChjbXNzdHJjYXNlY21wKEtleSwgcC0+S2V5d29yZCkgPT0gMCkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAocCA9PSBOVUxMKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAoU3Via2V5ID09IDApCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgZm9yICg7IHAgIT0gTlVMTDsgcCA9IHAtPk5leHRTdWJrZXkpIHsKCiAgICAgICAgaWYgKHAgLT5TdWJrZXkgPT0gTlVMTCkgY29udGludWU7CgogICAgICAgIGlmIChMYXN0UHRyKSAqTGFzdFB0ciA9IHA7CgogICAgICAgIGlmIChjbXNzdHJjYXNlY21wKFN1YmtleSwgcC0+U3Via2V5KSA9PSAwKQogICAgICAgICAgICByZXR1cm4gVFJVRTsKICAgIH0KCiAgICByZXR1cm4gRkFMU0U7Cn0KCgoKLy8gQWRkIGEgcHJvcGVydHkgaW50byBhIGxpbmtlZCBsaXN0CnN0YXRpYwpLRVlWQUxVRSogQWRkVG9MaXN0KGNtc0lUOCogaXQ4LCBLRVlWQUxVRSoqIEhlYWQsIGNvbnN0IGNoYXIgKktleSwgY29uc3QgY2hhciAqU3Via2V5LCBjb25zdCBjaGFyKiB4VmFsdWUsIFdSSVRFTU9ERSBXcml0ZUFzKQp7CiAgICBLRVlWQUxVRSogcDsKICAgIEtFWVZBTFVFKiBsYXN0OwoKCiAgICAvLyBDaGVjayBpZiBwcm9wZXJ0eSBpcyBhbHJlYWR5IGluIGxpc3QKCiAgICBpZiAoSXNBdmFpbGFibGVPbkxpc3QoKkhlYWQsIEtleSwgU3Via2V5LCAmcCkpIHsKCiAgICAgICAgLy8gVGhpcyBtYXkgd29yayBmb3IgZWRpdGluZyBwcm9wZXJ0aWVzCgogICAgICAgIC8vICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiZHVwbGljYXRlIGtleSA8JXM+IiwgS2V5KTsKICAgIH0KICAgIGVsc2UgewoKICAgICAgICBsYXN0ID0gcDsKCiAgICAgICAgLy8gQWxsb2NhdGUgdGhlIGNvbnRhaW5lcgogICAgICAgIHAgPSAoS0VZVkFMVUUqKSBBbGxvY0NodW5rKGl0OCwgc2l6ZW9mKEtFWVZBTFVFKSk7CiAgICAgICAgaWYgKHAgPT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIkFkZFRvTGlzdDogb3V0IG9mIG1lbW9yeSIpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CgogICAgICAgIC8vIFN0b3JlIG5hbWUgYW5kIHZhbHVlCiAgICAgICAgcC0+S2V5d29yZCA9IEFsbG9jU3RyaW5nKGl0OCwgS2V5KTsKICAgICAgICBwLT5TdWJrZXkgPSAoU3Via2V5ID09IE5VTEwpID8gTlVMTCA6IEFsbG9jU3RyaW5nKGl0OCwgU3Via2V5KTsKCiAgICAgICAgLy8gS2VlcCB0aGUgY29udGFpbmVyIGluIG91ciBsaXN0CiAgICAgICAgaWYgKCpIZWFkID09IE5VTEwpIHsKICAgICAgICAgICAgKkhlYWQgPSBwOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBpZiAoU3Via2V5ICE9IE5VTEwgJiYgbGFzdCAhPSBOVUxMKSB7CgogICAgICAgICAgICAgICAgbGFzdC0+TmV4dFN1YmtleSA9IHA7CgogICAgICAgICAgICAgICAgLy8gSWYgU3Via2V5IGlzIG5vdCBudWxsLCB0aGVuIGxhc3QgaXMgdGhlIGxhc3QgcHJvcGVydHkgd2l0aCB0aGUgc2FtZSBrZXksCiAgICAgICAgICAgICAgICAvLyBidXQgbm90IG5lY2Vzc2FyaWx5IGlzIHRoZSBsYXN0IHByb3BlcnR5IGluIHRoZSBsaXN0LCBzbyB3ZSBuZWVkIHRvIG1vdmUKICAgICAgICAgICAgICAgIC8vIHRvIHRoZSBhY3R1YWwgbGlzdCBlbmQKICAgICAgICAgICAgICAgIHdoaWxlIChsYXN0LT5OZXh0ICE9IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0ID0gbGFzdC0+TmV4dDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGxhc3QgIT0gTlVMTCkgbGFzdC0+TmV4dCA9IHA7CiAgICAgICAgfQoKICAgICAgICBwLT5OZXh0ICAgID0gTlVMTDsKICAgICAgICBwLT5OZXh0U3Via2V5ID0gTlVMTDsKICAgIH0KCiAgICBwLT5Xcml0ZUFzID0gV3JpdGVBczsKCiAgICBpZiAoeFZhbHVlICE9IE5VTEwpIHsKCiAgICAgICAgcC0+VmFsdWUgICA9IEFsbG9jU3RyaW5nKGl0OCwgeFZhbHVlKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHAtPlZhbHVlICAgPSBOVUxMOwogICAgfQoKICAgIHJldHVybiBwOwp9CgpzdGF0aWMKS0VZVkFMVUUqIEFkZEF2YWlsYWJsZVByb3BlcnR5KGNtc0lUOCogaXQ4LCBjb25zdCBjaGFyKiBLZXksIFdSSVRFTU9ERSBhcykKewogICAgcmV0dXJuIEFkZFRvTGlzdChpdDgsICZpdDgtPlZhbGlkS2V5d29yZHMsIEtleSwgTlVMTCwgTlVMTCwgYXMpOwp9CgoKc3RhdGljCktFWVZBTFVFKiBBZGRBdmFpbGFibGVTYW1wbGVJRChjbXNJVDgqIGl0OCwgY29uc3QgY2hhciogS2V5KQp7CiAgICByZXR1cm4gQWRkVG9MaXN0KGl0OCwgJml0OC0+VmFsaWRTYW1wbGVJRCwgS2V5LCBOVUxMLCBOVUxMLCBXUklURV9VTkNPT0tFRCk7Cn0KCgpzdGF0aWMKdm9pZCBBbGxvY1RhYmxlKGNtc0lUOCogaXQ4KQp7CiAgICBUQUJMRSogdDsKCiAgICB0ID0gaXQ4IC0+VGFiICsgaXQ4IC0+VGFibGVzQ291bnQ7CgogICAgdC0+SGVhZGVyTGlzdCA9IE5VTEw7CiAgICB0LT5EYXRhRm9ybWF0ID0gTlVMTDsKICAgIHQtPkRhdGEgICAgICAgPSBOVUxMOwoKICAgIGl0OCAtPlRhYmxlc0NvdW50Kys7Cn0KCgpjbXNJbnQzMk51bWJlciBDTVNFWFBPUlQgY21zSVQ4U2V0VGFibGUoY21zSEFORExFICBJVDgsIGNtc1VJbnQzMk51bWJlciBuVGFibGUpCnsKICAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBJVDg7CgogICAgIGlmIChuVGFibGUgPj0gaXQ4IC0+VGFibGVzQ291bnQpIHsKCiAgICAgICAgIGlmIChuVGFibGUgPT0gaXQ4IC0+VGFibGVzQ291bnQpIHsKCiAgICAgICAgICAgICBBbGxvY1RhYmxlKGl0OCk7CiAgICAgICAgIH0KICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICBTeW5FcnJvcihpdDgsICJUYWJsZSAlZCBpcyBvdXQgb2Ygc2VxdWVuY2UiLCBuVGFibGUpOwogICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICB9CiAgICAgfQoKICAgICBpdDggLT5uVGFibGUgPSBuVGFibGU7CgogICAgIHJldHVybiAoY21zSW50MzJOdW1iZXIpIG5UYWJsZTsKfQoKCgovLyBJbml0IGFuIGVtcHR5IGNvbnRhaW5lcgpjbXNIQU5ETEUgIENNU0VYUE9SVCBjbXNJVDhBbGxvYyhjbXNDb250ZXh0IENvbnRleHRJRCkKewogICAgY21zSVQ4KiBpdDg7CiAgICBjbXNVSW50MzJOdW1iZXIgaTsKCiAgICBpdDggPSAoY21zSVQ4KikgX2Ntc01hbGxvY1plcm8oQ29udGV4dElELCBzaXplb2YoY21zSVQ4KSk7CiAgICBpZiAoaXQ4ID09IE5VTEwpIHJldHVybiBOVUxMOwoKICAgIEFsbG9jVGFibGUoaXQ4KTsKCiAgICBpdDgtPk1lbW9yeUJsb2NrID0gTlVMTDsKICAgIGl0OC0+TWVtb3J5U2luayAgPSBOVUxMOwoKICAgIGl0OCAtPm5UYWJsZSA9IDA7CgogICAgaXQ4LT5Db250ZXh0SUQgPSBDb250ZXh0SUQ7CiAgICBpdDgtPkFsbG9jYXRvci5Vc2VkID0gMDsKICAgIGl0OC0+QWxsb2NhdG9yLkJsb2NrID0gTlVMTDsKICAgIGl0OC0+QWxsb2NhdG9yLkJsb2NrU2l6ZSA9IDA7CgogICAgaXQ4LT5WYWxpZEtleXdvcmRzID0gTlVMTDsKICAgIGl0OC0+VmFsaWRTYW1wbGVJRCA9IE5VTEw7CgogICAgaXQ4IC0+IHN5ID0gU05PTkU7CiAgICBpdDggLT4gY2ggPSAnICc7CiAgICBpdDggLT4gU291cmNlID0gTlVMTDsKICAgIGl0OCAtPiBpbnVtID0gMDsKICAgIGl0OCAtPiBkbnVtID0gMC4wOwoKICAgIGl0OC0+RmlsZVN0YWNrWzBdID0gKEZJTEVDVFgqKUFsbG9jQ2h1bmsoaXQ4LCBzaXplb2YoRklMRUNUWCkpOwogICAgaXQ4LT5JbmNsdWRlU1AgICA9IDA7CiAgICBpdDggLT4gbGluZW5vID0gMTsKCiAgICBzdHJjcHkoaXQ4LT5Eb3VibGVGb3JtYXR0ZXIsIERFRkFVTFRfREJMX0ZPUk1BVCk7CiAgICBjbXNJVDhTZXRTaGVldFR5cGUoKGNtc0hBTkRMRSkgaXQ4LCAiQ0dBVFMuMTciKTsKCiAgICAvLyBJbml0aWFsaXplIHByZWRlZmluZWQgcHJvcGVydGllcyAmIGRhdGEKCiAgICBmb3IgKGk9MDsgaSA8IE5VTVBSRURFRklORURQUk9QUzsgaSsrKQogICAgICAgICAgICBBZGRBdmFpbGFibGVQcm9wZXJ0eShpdDgsIFByZWRlZmluZWRQcm9wZXJ0aWVzW2ldLmlkLCBQcmVkZWZpbmVkUHJvcGVydGllc1tpXS5hcyk7CgogICAgZm9yIChpPTA7IGkgPCBOVU1QUkVERUZJTkVEU0FNUExFSUQ7IGkrKykKICAgICAgICAgICAgQWRkQXZhaWxhYmxlU2FtcGxlSUQoaXQ4LCBQcmVkZWZpbmVkU2FtcGxlSURbaV0pOwoKCiAgIHJldHVybiAoY21zSEFORExFKSBpdDg7Cn0KCgpjb25zdCBjaGFyKiBDTVNFWFBPUlQgY21zSVQ4R2V0U2hlZXRUeXBlKGNtc0hBTkRMRSBoSVQ4KQp7CiAgICAgICAgcmV0dXJuIEdldFRhYmxlKChjbXNJVDgqKSBoSVQ4KS0+U2hlZXRUeXBlOwp9CgpjbXNCb29sIENNU0VYUE9SVCBjbXNJVDhTZXRTaGVldFR5cGUoY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIFR5cGUpCnsKICAgICAgICBUQUJMRSogdCA9IEdldFRhYmxlKChjbXNJVDgqKSBoSVQ4KTsKCiAgICAgICAgc3RybmNweSh0IC0+U2hlZXRUeXBlLCBUeXBlLCBNQVhTVFItMSk7CiAgICAgICAgdCAtPlNoZWV0VHlwZVtNQVhTVFItMV0gPSAwOwogICAgICAgIHJldHVybiBUUlVFOwp9CgpjbXNCb29sIENNU0VYUE9SVCBjbXNJVDhTZXRDb21tZW50KGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBWYWwpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CgogICAgaWYgKCFWYWwpIHJldHVybiBGQUxTRTsKICAgIGlmICghKlZhbCkgcmV0dXJuIEZBTFNFOwoKICAgIHJldHVybiBBZGRUb0xpc3QoaXQ4LCAmR2V0VGFibGUoaXQ4KS0+SGVhZGVyTGlzdCwgIiMgIiwgTlVMTCwgVmFsLCBXUklURV9VTkNPT0tFRCkgIT0gTlVMTDsKfQoKLy8gU2V0cyBhIHByb3BlcnR5CmNtc0Jvb2wgQ01TRVhQT1JUIGNtc0lUOFNldFByb3BlcnR5U3RyKGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBLZXksIGNvbnN0IGNoYXIgKlZhbCkKewogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKCiAgICBpZiAoIVZhbCkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCEqVmFsKSByZXR1cm4gRkFMU0U7CgogICAgcmV0dXJuIEFkZFRvTGlzdChpdDgsICZHZXRUYWJsZShpdDgpLT5IZWFkZXJMaXN0LCBLZXksIE5VTEwsIFZhbCwgV1JJVEVfU1RSSU5HSUZZKSAhPSBOVUxMOwp9CgpjbXNCb29sIENNU0VYUE9SVCBjbXNJVDhTZXRQcm9wZXJ0eURibChjbXNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1Byb3AsIGNtc0Zsb2F0NjROdW1iZXIgVmFsKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwogICAgY2hhciBCdWZmZXJbMTAyNF07CgogICAgc3ByaW50ZihCdWZmZXIsIGl0OC0+RG91YmxlRm9ybWF0dGVyLCBWYWwpOwoKICAgIHJldHVybiBBZGRUb0xpc3QoaXQ4LCAmR2V0VGFibGUoaXQ4KS0+SGVhZGVyTGlzdCwgY1Byb3AsIE5VTEwsIEJ1ZmZlciwgV1JJVEVfVU5DT09LRUQpICE9IE5VTEw7Cn0KCmNtc0Jvb2wgQ01TRVhQT1JUIGNtc0lUOFNldFByb3BlcnR5SGV4KGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCwgY21zVUludDMyTnVtYmVyIFZhbCkKewogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKICAgIGNoYXIgQnVmZmVyWzEwMjRdOwoKICAgIHNwcmludGYoQnVmZmVyLCAiJXUiLCBWYWwpOwoKICAgIHJldHVybiBBZGRUb0xpc3QoaXQ4LCAmR2V0VGFibGUoaXQ4KS0+SGVhZGVyTGlzdCwgY1Byb3AsIE5VTEwsIEJ1ZmZlciwgV1JJVEVfSEVYQURFQ0lNQUwpICE9IE5VTEw7Cn0KCmNtc0Jvb2wgQ01TRVhQT1JUIGNtc0lUOFNldFByb3BlcnR5VW5jb29rZWQoY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIEtleSwgY29uc3QgY2hhciogQnVmZmVyKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwoKICAgIHJldHVybiBBZGRUb0xpc3QoaXQ4LCAmR2V0VGFibGUoaXQ4KS0+SGVhZGVyTGlzdCwgS2V5LCBOVUxMLCBCdWZmZXIsIFdSSVRFX1VOQ09PS0VEKSAhPSBOVUxMOwp9CgpjbXNCb29sIENNU0VYUE9SVCBjbXNJVDhTZXRQcm9wZXJ0eU11bHRpKGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBLZXksIGNvbnN0IGNoYXIqIFN1YktleSwgY29uc3QgY2hhciAqQnVmZmVyKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwoKICAgIHJldHVybiBBZGRUb0xpc3QoaXQ4LCAmR2V0VGFibGUoaXQ4KS0+SGVhZGVyTGlzdCwgS2V5LCBTdWJLZXksIEJ1ZmZlciwgV1JJVEVfUEFJUikgIT0gTlVMTDsKfQoKLy8gR2V0cyBhIHByb3BlcnR5CmNvbnN0IGNoYXIqIENNU0VYUE9SVCBjbXNJVDhHZXRQcm9wZXJ0eShjbXNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogS2V5KQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwogICAgS0VZVkFMVUUqIHA7CgogICAgaWYgKElzQXZhaWxhYmxlT25MaXN0KEdldFRhYmxlKGl0OCkgLT4gSGVhZGVyTGlzdCwgS2V5LCBOVUxMLCAmcCkpCiAgICB7CiAgICAgICAgcmV0dXJuIHAgLT4gVmFsdWU7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKCmNtc0Zsb2F0NjROdW1iZXIgQ01TRVhQT1JUIGNtc0lUOEdldFByb3BlcnR5RGJsKGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCkKewogICAgY29uc3QgY2hhciAqdiA9IGNtc0lUOEdldFByb3BlcnR5KGhJVDgsIGNQcm9wKTsKCiAgICBpZiAodiA9PSBOVUxMKSByZXR1cm4gMC4wOwoKICAgIHJldHVybiBQYXJzZUZsb2F0TnVtYmVyKHYpOwp9Cgpjb25zdCBjaGFyKiBDTVNFWFBPUlQgY21zSVQ4R2V0UHJvcGVydHlNdWx0aShjbXNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogS2V5LCBjb25zdCBjaGFyICpTdWJLZXkpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CiAgICBLRVlWQUxVRSogcDsKCiAgICBpZiAoSXNBdmFpbGFibGVPbkxpc3QoR2V0VGFibGUoaXQ4KSAtPiBIZWFkZXJMaXN0LCBLZXksIFN1YktleSwgJnApKSB7CiAgICAgICAgcmV0dXJuIHAgLT4gVmFsdWU7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRGF0YXNldHMKCgpzdGF0aWMKdm9pZCBBbGxvY2F0ZURhdGFGb3JtYXQoY21zSVQ4KiBpdDgpCnsKICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBpZiAodCAtPiBEYXRhRm9ybWF0KSByZXR1cm47ICAgIC8vIEFscmVhZHkgYWxsb2NhdGVkCgogICAgdCAtPiBuU2FtcGxlcyAgPSAoaW50KSBjbXNJVDhHZXRQcm9wZXJ0eURibChpdDgsICJOVU1CRVJfT0ZfRklFTERTIik7CgogICAgaWYgKHQgLT4gblNhbXBsZXMgPD0gMCkgewoKICAgICAgICBTeW5FcnJvcihpdDgsICJBbGxvY2F0ZURhdGFGb3JtYXQ6IFVua25vd24gTlVNQkVSX09GX0ZJRUxEUyIpOwogICAgICAgIHQgLT4gblNhbXBsZXMgPSAxMDsKICAgICAgICB9CgogICAgdCAtPiBEYXRhRm9ybWF0ID0gKGNoYXIqKikgQWxsb2NDaHVuayAoaXQ4LCAoKGNtc1VJbnQzMk51bWJlcikgdC0+blNhbXBsZXMgKyAxKSAqIHNpemVvZihjaGFyICopKTsKICAgIGlmICh0LT5EYXRhRm9ybWF0ID09IE5VTEwpIHsKCiAgICAgICAgU3luRXJyb3IoaXQ4LCAiQWxsb2NhdGVEYXRhRm9ybWF0OiBVbmFibGUgdG8gYWxsb2NhdGUgZGF0YUZvcm1hdCBhcnJheSIpOwogICAgfQoKfQoKc3RhdGljCmNvbnN0IGNoYXIgKkdldERhdGFGb3JtYXQoY21zSVQ4KiBpdDgsIGludCBuKQp7CiAgICBUQUJMRSogdCA9IEdldFRhYmxlKGl0OCk7CgogICAgaWYgKHQtPkRhdGFGb3JtYXQpCiAgICAgICAgcmV0dXJuIHQtPkRhdGFGb3JtYXRbbl07CgogICAgcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYwpjbXNCb29sIFNldERhdGFGb3JtYXQoY21zSVQ4KiBpdDgsIGludCBuLCBjb25zdCBjaGFyICpsYWJlbCkKewogICAgVEFCTEUqIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGlmICghdC0+RGF0YUZvcm1hdCkKICAgICAgICBBbGxvY2F0ZURhdGFGb3JtYXQoaXQ4KTsKCiAgICBpZiAobiA+IHQgLT4gblNhbXBsZXMpIHsKICAgICAgICBTeW5FcnJvcihpdDgsICJNb3JlIHRoYW4gTlVNQkVSX09GX0ZJRUxEUyBmaWVsZHMuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICh0LT5EYXRhRm9ybWF0KSB7CiAgICAgICAgdC0+RGF0YUZvcm1hdFtuXSA9IEFsbG9jU3RyaW5nKGl0OCwgbGFiZWwpOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgoKY21zQm9vbCBDTVNFWFBPUlQgY21zSVQ4U2V0RGF0YUZvcm1hdChjbXNIQU5ETEUgIGgsIGludCBuLCBjb25zdCBjaGFyICpTYW1wbGUpCnsKICAgICAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoOwogICAgICAgIHJldHVybiBTZXREYXRhRm9ybWF0KGl0OCwgbiwgU2FtcGxlKTsKfQoKc3RhdGljCnZvaWQgQWxsb2NhdGVEYXRhU2V0KGNtc0lUOCogaXQ4KQp7CiAgICBUQUJMRSogdCA9IEdldFRhYmxlKGl0OCk7CgogICAgaWYgKHQgLT4gRGF0YSkgcmV0dXJuOyAgICAvLyBBbHJlYWR5IGFsbG9jYXRlZAoKICAgIHQtPiBuU2FtcGxlcyAgID0gYXRvaShjbXNJVDhHZXRQcm9wZXJ0eShpdDgsICJOVU1CRVJfT0ZfRklFTERTIikpOwogICAgdC0+IG5QYXRjaGVzICAgPSBhdG9pKGNtc0lUOEdldFByb3BlcnR5KGl0OCwgIk5VTUJFUl9PRl9TRVRTIikpOwoKICAgIHQtPiBEYXRhID0gKGNoYXIqKilBbGxvY0NodW5rIChpdDgsICgoY21zVUludDMyTnVtYmVyKSB0LT5uU2FtcGxlcyArIDEpICogKChjbXNVSW50MzJOdW1iZXIpIHQtPm5QYXRjaGVzICsgMSkgKnNpemVvZiAoY2hhciopKTsKICAgIGlmICh0LT5EYXRhID09IE5VTEwpIHsKCiAgICAgICAgU3luRXJyb3IoaXQ4LCAiQWxsb2NhdGVEYXRhU2V0OiBVbmFibGUgdG8gYWxsb2NhdGUgZGF0YSBhcnJheSIpOwogICAgfQoKfQoKc3RhdGljCmNoYXIqIEdldERhdGEoY21zSVQ4KiBpdDgsIGludCBuU2V0LCBpbnQgbkZpZWxkKQp7CiAgICBUQUJMRSogdCA9IEdldFRhYmxlKGl0OCk7CiAgICBpbnQgIG5TYW1wbGVzICAgPSB0IC0+IG5TYW1wbGVzOwogICAgaW50ICBuUGF0Y2hlcyAgID0gdCAtPiBuUGF0Y2hlczsKCiAgICBpZiAoblNldCA+PSBuUGF0Y2hlcyB8fCBuRmllbGQgPj0gblNhbXBsZXMpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgaWYgKCF0LT5EYXRhKSByZXR1cm4gTlVMTDsKICAgIHJldHVybiB0LT5EYXRhIFtuU2V0ICogblNhbXBsZXMgKyBuRmllbGRdOwp9CgpzdGF0aWMKY21zQm9vbCBTZXREYXRhKGNtc0lUOCogaXQ4LCBpbnQgblNldCwgaW50IG5GaWVsZCwgY29uc3QgY2hhciAqVmFsKQp7CiAgICBUQUJMRSogdCA9IEdldFRhYmxlKGl0OCk7CgogICAgaWYgKCF0LT5EYXRhKQogICAgICAgIEFsbG9jYXRlRGF0YVNldChpdDgpOwoKICAgIGlmICghdC0+RGF0YSkgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChuU2V0ID4gdCAtPiBuUGF0Y2hlcyB8fCBuU2V0IDwgMCkgewoKICAgICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIlBhdGNoICVkIG91dCBvZiByYW5nZSwgdGhlcmUgYXJlICVkIHBhdGNoZXMiLCBuU2V0LCB0IC0+IG5QYXRjaGVzKTsKICAgIH0KCiAgICBpZiAobkZpZWxkID4gdCAtPm5TYW1wbGVzIHx8IG5GaWVsZCA8IDApIHsKICAgICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIlNhbXBsZSAlZCBvdXQgb2YgcmFuZ2UsIHRoZXJlIGFyZSAlZCBzYW1wbGVzIiwgbkZpZWxkLCB0IC0+blNhbXBsZXMpOwoKICAgIH0KCiAgICB0LT5EYXRhIFtuU2V0ICogdCAtPiBuU2FtcGxlcyArIG5GaWVsZF0gPSBBbGxvY1N0cmluZyhpdDgsIFZhbCk7CiAgICByZXR1cm4gVFJVRTsKfQoKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaWxlIEkvTwoKCi8vIFdyaXRlcyBhIHN0cmluZyB0byBmaWxlCnN0YXRpYwp2b2lkIFdyaXRlU3RyKFNBVkVTVFJFQU0qIGYsIGNvbnN0IGNoYXIgKnN0cikKewogICAgY21zVUludDMyTnVtYmVyIGxlbjsKCiAgICBpZiAoc3RyID09IE5VTEwpCiAgICAgICAgc3RyID0gIiAiOwoKICAgIC8vIExlbmd0aCB0byB3cml0ZQogICAgbGVuID0gKGNtc1VJbnQzMk51bWJlcikgc3RybGVuKHN0cik7CiAgICBmIC0+VXNlZCArPSBsZW47CgoKICAgIGlmIChmIC0+c3RyZWFtKSB7ICAgLy8gU2hvdWxkIEkgd3JpdGUgaXQgdG8gYSBmaWxlPwoKICAgICAgICBpZiAoZndyaXRlKHN0ciwgMSwgbGVuLCBmLT5zdHJlYW0pICE9IGxlbikgewogICAgICAgICAgICBjbXNTaWduYWxFcnJvcigwLCBjbXNFUlJPUl9XUklURSwgIldyaXRlIHRvIGZpbGUgZXJyb3IgaW4gQ0dBVFMgcGFyc2VyIik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgfQogICAgZWxzZSB7ICAvLyBPciB0byBhIG1lbW9yeSBibG9jaz8KCiAgICAgICAgaWYgKGYgLT5CYXNlKSB7ICAgLy8gQW0gSSBqdXN0IGNvdW50aW5nIHRoZSBieXRlcz8KCiAgICAgICAgICAgIGlmIChmIC0+VXNlZCA+IGYgLT5NYXgpIHsKCiAgICAgICAgICAgICAgICAgY21zU2lnbmFsRXJyb3IoMCwgY21zRVJST1JfV1JJVEUsICJXcml0ZSB0byBtZW1vcnkgb3ZlcmZsb3dzIGluIENHQVRTIHBhcnNlciIpOwogICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbWVtbW92ZShmIC0+UHRyLCBzdHIsIGxlbik7CiAgICAgICAgICAgIGYtPlB0ciArPSBsZW47CiAgICAgICAgfQoKICAgIH0KfQoKCi8vIFdyaXRlIGZvcm1hdHRlZAoKc3RhdGljCnZvaWQgV3JpdGVmKFNBVkVTVFJFQU0qIGYsIGNvbnN0IGNoYXIqIGZybSwgLi4uKQp7CiAgICBjaGFyIEJ1ZmZlcls0MDk2XTsKICAgIHZhX2xpc3QgYXJnczsKCiAgICB2YV9zdGFydChhcmdzLCBmcm0pOwogICAgdnNucHJpbnRmKEJ1ZmZlciwgNDA5NSwgZnJtLCBhcmdzKTsKICAgIEJ1ZmZlcls0MDk1XSA9IDA7CiAgICBXcml0ZVN0cihmLCBCdWZmZXIpOwogICAgdmFfZW5kKGFyZ3MpOwoKfQoKLy8gV3JpdGVzIGZ1bGwgaGVhZGVyCnN0YXRpYwp2b2lkIFdyaXRlSGVhZGVyKGNtc0lUOCogaXQ4LCBTQVZFU1RSRUFNKiBmcCkKewogICAgS0VZVkFMVUUqIHA7CiAgICBUQUJMRSogdCA9IEdldFRhYmxlKGl0OCk7CgogICAgLy8gV3JpdGVzIHRoZSB0eXBlCiAgICBXcml0ZVN0cihmcCwgdC0+U2hlZXRUeXBlKTsKICAgIFdyaXRlU3RyKGZwLCAiXG4iKTsKCiAgICBmb3IgKHAgPSB0LT5IZWFkZXJMaXN0OyAocCAhPSBOVUxMKTsgcCA9IHAtPk5leHQpCiAgICB7CiAgICAgICAgaWYgKCpwIC0+S2V5d29yZCA9PSAnIycpIHsKCiAgICAgICAgICAgIGNoYXIqIFB0OwoKICAgICAgICAgICAgV3JpdGVTdHIoZnAsICIjXG4jICIpOwogICAgICAgICAgICBmb3IgKFB0ID0gcCAtPlZhbHVlOyAqUHQ7IFB0KyspIHsKCgogICAgICAgICAgICAgICAgV3JpdGVmKGZwLCAiJWMiLCAqUHQpOwoKICAgICAgICAgICAgICAgIGlmICgqUHQgPT0gJ1xuJykgewogICAgICAgICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCAiIyAiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgV3JpdGVTdHIoZnAsICJcbiNcbiIpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgoKICAgICAgICBpZiAoIUlzQXZhaWxhYmxlT25MaXN0KGl0OC0+IFZhbGlkS2V5d29yZHMsIHAtPktleXdvcmQsIE5VTEwsIE5VTEwpKSB7CgojaWZkZWYgQ01TX1NUUklDVF9DR0FUUwogICAgICAgICAgICBXcml0ZVN0cihmcCwgIktFWVdPUkRcdFwiIik7CiAgICAgICAgICAgIFdyaXRlU3RyKGZwLCBwLT5LZXl3b3JkKTsKICAgICAgICAgICAgV3JpdGVTdHIoZnAsICJcIlxuIik7CiNlbmRpZgoKICAgICAgICAgICAgQWRkQXZhaWxhYmxlUHJvcGVydHkoaXQ4LCBwLT5LZXl3b3JkLCBXUklURV9VTkNPT0tFRCk7CiAgICAgICAgfQoKICAgICAgICBXcml0ZVN0cihmcCwgcC0+S2V5d29yZCk7CiAgICAgICAgaWYgKHAtPlZhbHVlKSB7CgogICAgICAgICAgICBzd2l0Y2ggKHAgLT5Xcml0ZUFzKSB7CgogICAgICAgICAgICBjYXNlIFdSSVRFX1VOQ09PS0VEOgogICAgICAgICAgICAgICAgICAgIFdyaXRlZihmcCwgIlx0JXMiLCBwIC0+VmFsdWUpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXUklURV9TVFJJTkdJRlk6CiAgICAgICAgICAgICAgICAgICAgV3JpdGVmKGZwLCAiXHRcIiVzXCIiLCBwLT5WYWx1ZSApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXUklURV9IRVhBREVDSU1BTDoKICAgICAgICAgICAgICAgICAgICBXcml0ZWYoZnAsICJcdDB4JVgiLCBhdG9pKHAgLT5WYWx1ZSkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXUklURV9CSU5BUlk6CiAgICAgICAgICAgICAgICAgICAgV3JpdGVmKGZwLCAiXHQweCVCIiwgYXRvaShwIC0+VmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgV1JJVEVfUEFJUjoKICAgICAgICAgICAgICAgICAgICBXcml0ZWYoZnAsICJcdFwiJXMsJXNcIiIsIHAtPlN1YmtleSwgcC0+VmFsdWUpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgZGVmYXVsdDogU3luRXJyb3IoaXQ4LCAiVW5rbm93biB3cml0ZSBtb2RlICVkIiwgcCAtPldyaXRlQXMpOwogICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIFdyaXRlU3RyIChmcCwgIlxuIik7CiAgICB9Cgp9CgoKLy8gV3JpdGVzIHRoZSBkYXRhIGZvcm1hdApzdGF0aWMKdm9pZCBXcml0ZURhdGFGb3JtYXQoU0FWRVNUUkVBTSogZnAsIGNtc0lUOCogaXQ4KQp7CiAgICBpbnQgaSwgblNhbXBsZXM7CiAgICBUQUJMRSogdCA9IEdldFRhYmxlKGl0OCk7CgogICAgaWYgKCF0IC0+IERhdGFGb3JtYXQpIHJldHVybjsKCiAgICAgICBXcml0ZVN0cihmcCwgIkJFR0lOX0RBVEFfRk9STUFUXG4iKTsKICAgICAgIFdyaXRlU3RyKGZwLCAiICIpOwogICAgICAgblNhbXBsZXMgPSBhdG9pKGNtc0lUOEdldFByb3BlcnR5KGl0OCwgIk5VTUJFUl9PRl9GSUVMRFMiKSk7CgogICAgICAgZm9yIChpID0gMDsgaSA8IG5TYW1wbGVzOyBpKyspIHsKCiAgICAgICAgICAgICAgV3JpdGVTdHIoZnAsIHQtPkRhdGFGb3JtYXRbaV0pOwogICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCAoKGkgPT0gKG5TYW1wbGVzLTEpKSA/ICJcbiIgOiAiXHQiKSk7CiAgICAgICAgICB9CgogICAgICAgV3JpdGVTdHIgKGZwLCAiRU5EX0RBVEFfRk9STUFUXG4iKTsKfQoKCi8vIFdyaXRlcyBkYXRhIGFycmF5CnN0YXRpYwp2b2lkIFdyaXRlRGF0YShTQVZFU1RSRUFNKiBmcCwgY21zSVQ4KiBpdDgpCnsKICAgICAgIGludCAgaSwgajsKICAgICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICAgICBpZiAoIXQtPkRhdGEpIHJldHVybjsKCiAgICAgICBXcml0ZVN0ciAoZnAsICJCRUdJTl9EQVRBXG4iKTsKCiAgICAgICB0LT5uUGF0Y2hlcyA9IGF0b2koY21zSVQ4R2V0UHJvcGVydHkoaXQ4LCAiTlVNQkVSX09GX1NFVFMiKSk7CgogICAgICAgZm9yIChpID0gMDsgaSA8IHQtPiBuUGF0Y2hlczsgaSsrKSB7CgogICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCAiICIpOwoKICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgdC0+blNhbXBsZXM7IGorKykgewoKICAgICAgICAgICAgICAgICAgICAgY2hhciAqcHRyID0gdC0+RGF0YVtpKnQtPm5TYW1wbGVzK2pdOwoKICAgICAgICAgICAgICAgICAgICAgaWYgKHB0ciA9PSBOVUxMKSBXcml0ZVN0cihmcCwgIlwiXCIiKTsKICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB2YWx1ZSBjb250YWlucyB3aGl0ZXNwYWNlLCBlbmNsb3NlIHdpdGhpbiBxdW90ZQoKICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJjaHIocHRyLCAnICcpICE9IE5VTEwpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV3JpdGVTdHIoZnAsICJcIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCBwdHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCAiXCIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCBwdHIpOwogICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICBXcml0ZVN0cihmcCwgKChqID09ICh0LT5uU2FtcGxlcy0xKSkgPyAiXG4iIDogIlx0IikpOwogICAgICAgICAgICAgIH0KICAgICAgIH0KICAgICAgIFdyaXRlU3RyIChmcCwgIkVORF9EQVRBXG4iKTsKfQoKCgovLyBTYXZlcyB3aG9sZSBmaWxlCmNtc0Jvb2wgQ01TRVhQT1JUIGNtc0lUOFNhdmVUb0ZpbGUoY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNGaWxlTmFtZSkKewogICAgU0FWRVNUUkVBTSBzZDsKICAgIGNtc1VJbnQzMk51bWJlciBpOwogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKCiAgICBtZW1zZXQoJnNkLCAwLCBzaXplb2Yoc2QpKTsKCiAgICBzZC5zdHJlYW0gPSBmb3BlbihjRmlsZU5hbWUsICJ3dCIpOwogICAgaWYgKCFzZC5zdHJlYW0pIHJldHVybiBGQUxTRTsKCiAgICBmb3IgKGk9MDsgaSA8IGl0OCAtPlRhYmxlc0NvdW50OyBpKyspIHsKCiAgICAgICAgICAgIGNtc0lUOFNldFRhYmxlKGhJVDgsIGkpOwogICAgICAgICAgICBXcml0ZUhlYWRlcihpdDgsICZzZCk7CiAgICAgICAgICAgIFdyaXRlRGF0YUZvcm1hdCgmc2QsIGl0OCk7CiAgICAgICAgICAgIFdyaXRlRGF0YSgmc2QsIGl0OCk7CiAgICB9CgogICAgaWYgKGZjbG9zZShzZC5zdHJlYW0pICE9IDApIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gVFJVRTsKfQoKCi8vIFNhdmVzIHRvIG1lbW9yeQpjbXNCb29sIENNU0VYUE9SVCBjbXNJVDhTYXZlVG9NZW0oY21zSEFORExFIGhJVDgsIHZvaWQgKk1lbVB0ciwgY21zVUludDMyTnVtYmVyKiBCeXRlc05lZWRlZCkKewogICAgU0FWRVNUUkVBTSBzZDsKICAgIGNtc1VJbnQzMk51bWJlciBpOwogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKCiAgICBtZW1zZXQoJnNkLCAwLCBzaXplb2Yoc2QpKTsKCiAgICBzZC5zdHJlYW0gPSBOVUxMOwogICAgc2QuQmFzZSAgID0gKGNtc1VJbnQ4TnVtYmVyKikgIE1lbVB0cjsKICAgIHNkLlB0ciAgICA9IHNkLkJhc2U7CgogICAgc2QuVXNlZCA9IDA7CgogICAgaWYgKHNkLkJhc2UpCiAgICAgICAgc2QuTWF4ICA9ICpCeXRlc05lZWRlZDsgICAgIC8vIFdyaXRlIHRvIG1lbW9yeT8KICAgIGVsc2UKICAgICAgICBzZC5NYXggID0gMDsgICAgICAgICAgICAgICAgLy8gSnVzdCBjb3VudGluZyB0aGUgbmVlZGVkIGJ5dGVzCgogICAgZm9yIChpPTA7IGkgPCBpdDggLT5UYWJsZXNDb3VudDsgaSsrKSB7CgogICAgICAgIGNtc0lUOFNldFRhYmxlKGhJVDgsIGkpOwogICAgICAgIFdyaXRlSGVhZGVyKGl0OCwgJnNkKTsKICAgICAgICBXcml0ZURhdGFGb3JtYXQoJnNkLCBpdDgpOwogICAgICAgIFdyaXRlRGF0YSgmc2QsIGl0OCk7CiAgICB9CgogICAgc2QuVXNlZCsrOyAgLy8gVGhlIFwwIGF0IHRoZSB2ZXJ5IGVuZAoKICAgIGlmIChzZC5CYXNlKQogICAgICAgICpzZC5QdHIgPSAwOwoKICAgICpCeXRlc05lZWRlZCA9IHNkLlVzZWQ7CgogICAgcmV0dXJuIFRSVUU7Cn0KCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBIaWdlciBsZXZlbCBwYXJzaW5nCgpzdGF0aWMKY21zQm9vbCBEYXRhRm9ybWF0U2VjdGlvbihjbXNJVDgqIGl0OCkKewogICAgaW50IGlGaWVsZCA9IDA7CiAgICBUQUJMRSogdCA9IEdldFRhYmxlKGl0OCk7CgogICAgSW5TeW1ib2woaXQ4KTsgICAvLyBFYXRzICJCRUdJTl9EQVRBX0ZPUk1BVCIKICAgIENoZWNrRU9MTihpdDgpOwoKICAgIHdoaWxlIChpdDgtPnN5ICE9IFNFTkRfREFUQV9GT1JNQVQgJiYKICAgICAgICBpdDgtPnN5ICE9IFNFT0xOICYmCiAgICAgICAgaXQ4LT5zeSAhPSBTRU9GICYmCiAgICAgICAgaXQ4LT5zeSAhPSBTU1lORVJST1IpICB7CgogICAgICAgICAgICBpZiAoaXQ4LT5zeSAhPSBTSURFTlQpIHsKCiAgICAgICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiU2FtcGxlIHR5cGUgZXhwZWN0ZWQiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFTZXREYXRhRm9ybWF0KGl0OCwgaUZpZWxkLCBpdDgtPmlkKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICBpRmllbGQrKzsKCiAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgICAgIFNraXBFT0xOKGl0OCk7CiAgICAgICB9CgogICAgICAgU2tpcEVPTE4oaXQ4KTsKICAgICAgIFNraXAoaXQ4LCBTRU5EX0RBVEFfRk9STUFUKTsKICAgICAgIFNraXBFT0xOKGl0OCk7CgogICAgICAgaWYgKGlGaWVsZCAhPSB0IC0+blNhbXBsZXMpIHsKICAgICAgICAgICBTeW5FcnJvcihpdDgsICJDb3VudCBtaXNtYXRjaC4gTlVNQkVSX09GX0ZJRUxEUyB3YXMgJWQsIGZvdW5kICVkXG4iLCB0IC0+blNhbXBsZXMsIGlGaWVsZCk7CgoKICAgICAgIH0KCiAgICAgICByZXR1cm4gVFJVRTsKfQoKCgpzdGF0aWMKY21zQm9vbCBEYXRhU2VjdGlvbiAoY21zSVQ4KiBpdDgpCnsKICAgIGludCAgaUZpZWxkID0gMDsKICAgIGludCAgaVNldCAgID0gMDsKICAgIGNoYXIgQnVmZmVyWzI1Nl07CiAgICBUQUJMRSogdCA9IEdldFRhYmxlKGl0OCk7CgogICAgSW5TeW1ib2woaXQ4KTsgICAvLyBFYXRzICJCRUdJTl9EQVRBIgogICAgQ2hlY2tFT0xOKGl0OCk7CgogICAgaWYgKCF0LT5EYXRhKQogICAgICAgIEFsbG9jYXRlRGF0YVNldChpdDgpOwoKICAgIHdoaWxlIChpdDgtPnN5ICE9IFNFTkRfREFUQSAmJiBpdDgtPnN5ICE9IFNFT0YpCiAgICB7CiAgICAgICAgaWYgKGlGaWVsZCA+PSB0IC0+IG5TYW1wbGVzKSB7CiAgICAgICAgICAgIGlGaWVsZCA9IDA7CiAgICAgICAgICAgIGlTZXQrKzsKCiAgICAgICAgfQoKICAgICAgICBpZiAoaXQ4LT5zeSAhPSBTRU5EX0RBVEEgJiYgaXQ4LT5zeSAhPSBTRU9GKSB7CgogICAgICAgICAgICBpZiAoIUdldFZhbChpdDgsIEJ1ZmZlciwgMjU1LCAiU2FtcGxlIGRhdGEgZXhwZWN0ZWQiKSkKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICAgICAgICAgIGlmICghU2V0RGF0YShpdDgsIGlTZXQsIGlGaWVsZCwgQnVmZmVyKSkKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICAgICAgICAgIGlGaWVsZCsrOwoKICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgICAgICAgICAgU2tpcEVPTE4oaXQ4KTsKICAgICAgICB9CiAgICB9CgogICAgU2tpcEVPTE4oaXQ4KTsKICAgIFNraXAoaXQ4LCBTRU5EX0RBVEEpOwogICAgU2tpcEVPTE4oaXQ4KTsKCiAgICAvLyBDaGVjayBmb3IgZGF0YSBjb21wbGV0aW9uLgoKICAgIGlmICgoaVNldCsxKSAhPSB0IC0+IG5QYXRjaGVzKQogICAgICAgIHJldHVybiBTeW5FcnJvcihpdDgsICJDb3VudCBtaXNtYXRjaC4gTlVNQkVSX09GX1NFVFMgd2FzICVkLCBmb3VuZCAlZFxuIiwgdCAtPm5QYXRjaGVzLCBpU2V0KzEpOwoKICAgIHJldHVybiBUUlVFOwp9CgoKCgpzdGF0aWMKY21zQm9vbCBIZWFkZXJTZWN0aW9uKGNtc0lUOCogaXQ4KQp7CiAgICBjaGFyIFZhck5hbWVbTUFYSURdOwogICAgY2hhciBCdWZmZXJbTUFYU1RSXTsKICAgIEtFWVZBTFVFKiBLZXk7CgogICAgICAgIHdoaWxlIChpdDgtPnN5ICE9IFNFT0YgJiYKICAgICAgICAgICAgICAgaXQ4LT5zeSAhPSBTU1lORVJST1IgJiYKICAgICAgICAgICAgICAgaXQ4LT5zeSAhPSBTQkVHSU5fREFUQV9GT1JNQVQgJiYKICAgICAgICAgICAgICAgaXQ4LT5zeSAhPSBTQkVHSU5fREFUQSkgewoKCiAgICAgICAgc3dpdGNoIChpdDggLT4gc3kpIHsKCiAgICAgICAgY2FzZSBTS0VZV09SRDoKICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgICAgICAgICBpZiAoIUdldFZhbChpdDgsIEJ1ZmZlciwgTUFYU1RSLTEsICJLZXl3b3JkIGV4cGVjdGVkIikpIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgICAgIGlmICghQWRkQXZhaWxhYmxlUHJvcGVydHkoaXQ4LCBCdWZmZXIsIFdSSVRFX1VOQ09PS0VEKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKCiAgICAgICAgY2FzZSBTREFUQV9GT1JNQVRfSUQ6CiAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICAgICAgaWYgKCFHZXRWYWwoaXQ4LCBCdWZmZXIsIE1BWFNUUi0xLCAiS2V5d29yZCBleHBlY3RlZCIpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgICAgICBpZiAoIUFkZEF2YWlsYWJsZVNhbXBsZUlEKGl0OCwgQnVmZmVyKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKCiAgICAgICAgY2FzZSBTSURFTlQ6CiAgICAgICAgICAgICAgICBzdHJuY3B5KFZhck5hbWUsIGl0OC0+aWQsIE1BWElELTEpOwogICAgICAgICAgICAgICAgVmFyTmFtZVtNQVhJRC0xXSA9IDA7CgogICAgICAgICAgICAgICAgaWYgKCFJc0F2YWlsYWJsZU9uTGlzdChpdDgtPiBWYWxpZEtleXdvcmRzLCBWYXJOYW1lLCBOVUxMLCAmS2V5KSkgewoKI2lmZGVmIENNU19TVFJJQ1RfQ0dBVFMKICAgICAgICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiVW5kZWZpbmVkIGtleXdvcmQgJyVzJyIsIFZhck5hbWUpOwojZWxzZQogICAgICAgICAgICAgICAgICAgIEtleSA9IEFkZEF2YWlsYWJsZVByb3BlcnR5KGl0OCwgVmFyTmFtZSwgV1JJVEVfVU5DT09LRUQpOwogICAgICAgICAgICAgICAgICAgIGlmIChLZXkgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwojZW5kaWYKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICAgICAgaWYgKCFHZXRWYWwoaXQ4LCBCdWZmZXIsIE1BWFNUUi0xLCAiUHJvcGVydHkgZGF0YSBleHBlY3RlZCIpKSByZXR1cm4gRkFMU0U7CgogICAgICAgICAgICAgICAgaWYoS2V5LT5Xcml0ZUFzICE9IFdSSVRFX1BBSVIpIHsKICAgICAgICAgICAgICAgICAgICBBZGRUb0xpc3QoaXQ4LCAmR2V0VGFibGUoaXQ4KS0+SGVhZGVyTGlzdCwgVmFyTmFtZSwgTlVMTCwgQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpdDgtPnN5ID09IFNTVFJJTkcpID8gV1JJVEVfU1RSSU5HSUZZIDogV1JJVEVfVU5DT09LRUQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqU3Via2V5OwogICAgICAgICAgICAgICAgICAgIGNoYXIgKk5leHRrZXk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGl0OC0+c3kgIT0gU1NUUklORykKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIkludmFsaWQgdmFsdWUgJyVzJyBmb3IgcHJvcGVydHkgJyVzJy4iLCBCdWZmZXIsIFZhck5hbWUpOwoKICAgICAgICAgICAgICAgICAgICAvLyBjaG9wIHRoZSBzdHJpbmcgYXMgYSBsaXN0IG9mICJzdWJrZXksIHZhbHVlIiBwYWlycywgdXNpbmcgJzsnIGFzIGEgc2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgZm9yIChTdWJrZXkgPSBCdWZmZXI7IFN1YmtleSAhPSBOVUxMOyBTdWJrZXkgPSBOZXh0a2V5KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2hhciAqVmFsdWUsICp0ZW1wOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gIGlkZW50aWZ5IHRva2VuIHBhaXIgYm91bmRhcnkKICAgICAgICAgICAgICAgICAgICAgICAgTmV4dGtleSA9IChjaGFyKikgc3RyY2hyKFN1YmtleSwgJzsnKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoTmV4dGtleSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICpOZXh0a2V5KysgPSAnXDAnOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIGVhY2ggcGFpciwgc3BsaXQgdGhlIHN1YmtleSBhbmQgdGhlIHZhbHVlCiAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlID0gKGNoYXIqKSBzdHJyY2hyKFN1YmtleSwgJywnKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoVmFsdWUgPT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBTeW5FcnJvcihpdDgsICJJbnZhbGlkIHZhbHVlIGZvciBwcm9wZXJ0eSAnJXMnLiIsIFZhck5hbWUpOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ29iYmxlIHRoZSBzcGFjZXMgYmVmb3JlIHRoZSBjb21hLCBhbmQgdGhlIGNvbWEgaXRzZWxmCiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAgPSBWYWx1ZSsrOwogICAgICAgICAgICAgICAgICAgICAgICBkbyAqdGVtcC0tID0gJ1wwJzsgd2hpbGUodGVtcCA+PSBTdWJrZXkgJiYgKnRlbXAgPT0gJyAnKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdvYmJsZSBhbnkgc3BhY2UgYXQgdGhlIHJpZ2h0CiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAgPSBWYWx1ZSArIHN0cmxlbihWYWx1ZSkgLSAxOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSgqdGVtcCA9PSAnICcpICp0ZW1wLS0gPSAnXDAnOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHJpbSB0aGUgc3RyaW5ncyBmcm9tIHRoZSBsZWZ0CiAgICAgICAgICAgICAgICAgICAgICAgIFN1YmtleSArPSBzdHJzcG4oU3Via2V5LCAiICIpOwogICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSArPSBzdHJzcG4oVmFsdWUsICIgIik7CgogICAgICAgICAgICAgICAgICAgICAgICBpZihTdWJrZXlbMF0gPT0gMCB8fCBWYWx1ZVswXSA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIkludmFsaWQgdmFsdWUgZm9yIHByb3BlcnR5ICclcycuIiwgVmFyTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFkZFRvTGlzdChpdDgsICZHZXRUYWJsZShpdDgpLT5IZWFkZXJMaXN0LCBWYXJOYW1lLCBTdWJrZXksIFZhbHVlLCBXUklURV9QQUlSKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKCiAgICAgICAgY2FzZSBTRU9MTjogYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiZXhwZWN0ZWQga2V5d29yZCBvciBpZGVudGlmaWVyIik7CiAgICAgICAgfQoKICAgIFNraXBFT0xOKGl0OCk7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cgp9CgoKc3RhdGljCnZvaWQgUmVhZFR5cGUoY21zSVQ4KiBpdDgsIGNoYXIqIFNoZWV0VHlwZVB0cikKewogICAgLy8gRmlyc3QgbGluZSBpcyBhIHZlcnkgc3BlY2lhbCBjYXNlLgoKICAgIHdoaWxlIChpc3NlcGFyYXRvcihpdDgtPmNoKSkKICAgICAgICAgICAgTmV4dENoKGl0OCk7CgogICAgd2hpbGUgKGl0OC0+Y2ggIT0gJ1xyJyAmJiBpdDggLT5jaCAhPSAnXG4nICYmIGl0OC0+Y2ggIT0gJ1x0JyAmJiBpdDggLT4gY2ggIT0gLTEpIHsKCiAgICAgICAgKlNoZWV0VHlwZVB0cisrPSAoY2hhcikgaXQ4IC0+Y2g7CiAgICAgICAgTmV4dENoKGl0OCk7CiAgICB9CgogICAgKlNoZWV0VHlwZVB0ciA9IDA7Cn0KCgpzdGF0aWMKY21zQm9vbCBQYXJzZUlUOChjbXNJVDgqIGl0OCwgY21zQm9vbCBub3NoZWV0KQp7CiAgICBjaGFyKiBTaGVldFR5cGVQdHIgPSBpdDggLT5UYWJbMF0uU2hlZXRUeXBlOwoKICAgIGlmIChub3NoZWV0ID09IDApIHsKICAgICAgICBSZWFkVHlwZShpdDgsIFNoZWV0VHlwZVB0cik7CiAgICB9CgogICAgSW5TeW1ib2woaXQ4KTsKCiAgICBTa2lwRU9MTihpdDgpOwoKICAgIHdoaWxlIChpdDgtPiBzeSAhPSBTRU9GICYmCiAgICAgICAgICAgaXQ4LT4gc3kgIT0gU1NZTkVSUk9SKSB7CgogICAgICAgICAgICBzd2l0Y2ggKGl0OCAtPiBzeSkgewoKICAgICAgICAgICAgY2FzZSBTQkVHSU5fREFUQV9GT1JNQVQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKCFEYXRhRm9ybWF0U2VjdGlvbihpdDgpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFNCRUdJTl9EQVRBOgoKICAgICAgICAgICAgICAgICAgICBpZiAoIURhdGFTZWN0aW9uKGl0OCkpIHJldHVybiBGQUxTRTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGl0OCAtPiBzeSAhPSBTRU9GKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgQWxsb2NUYWJsZShpdDgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQ4IC0+blRhYmxlID0gaXQ4IC0+VGFibGVzQ291bnQgLSAxOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlYWQgc2hlZXQgdHlwZSBpZiBwcmVzZW50LiBXZSBvbmx5IHN1cHBvcnQgaWRlbnRpZmllciBhbmQgc3RyaW5nLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gPGlkZW50PiA8ZW9sbj4gaXMgYSB0eXBlIHN0cmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW55dGhpbmcgZWxzZSwgaXMgbm90IGEgdHlwZSBzdHJpbmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub3NoZWV0ID09IDApIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0OCAtPnN5ID09IFNJREVOVCkgewoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWF5IGJlIGEgdHlwZSBzaGVldCBvciBtYXkgYmUgYSBwcm9wIHZhbHVlIHN0YXRlbWVudC4gV2UgY2Fubm90IHVzZSBpbnN5bWJvbCBpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHNwZWNpYWwgY2FzZS4uLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGlzc2VwYXJhdG9yKGl0OC0+Y2gpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIGEgbmV3bGluZSBpcyBmb3VuZCwgdGhlbiB0aGlzIGlzIGEgdHlwZSBzdHJpbmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0OCAtPmNoID09ICdcbicgfHwgaXQ4LT5jaCA9PSAnXHInKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc0lUOFNldFNoZWV0VHlwZShpdDgsIGl0OCAtPmlkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXQgaXMgbm90LiBKdXN0IGNvbnRpbnVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNJVDhTZXRTaGVldFR5cGUoaXQ4LCAiIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWYWxpZGF0ZSBxdW90ZWQgc3RyaW5ncwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXQ4IC0+c3kgPT0gU1NUUklORykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zSVQ4U2V0U2hlZXRUeXBlKGl0OCwgaXQ4IC0+c3RyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFNFT0xOOgogICAgICAgICAgICAgICAgICAgIFNraXBFT0xOKGl0OCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIGlmICghSGVhZGVyU2VjdGlvbihpdDgpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgfQoKICAgIH0KCiAgICByZXR1cm4gKGl0OCAtPiBzeSAhPSBTU1lORVJST1IpOwp9CgoKCi8vIEluaXQgdXNlZnVsbCBwb2ludGVycwoKc3RhdGljCnZvaWQgQ29va1BvaW50ZXJzKGNtc0lUOCogaXQ4KQp7CiAgICBpbnQgaWRGaWVsZCwgaTsKICAgIGNoYXIqIEZsZDsKICAgIGNtc1VJbnQzMk51bWJlciBqOwogICAgY21zVUludDMyTnVtYmVyIG5PbGRUYWJsZSA9IGl0OCAtPm5UYWJsZTsKCiAgICBmb3IgKGo9MDsgaiA8IGl0OCAtPlRhYmxlc0NvdW50OyBqKyspIHsKCiAgICBUQUJMRSogdCA9IGl0OCAtPlRhYiArIGo7CgogICAgdCAtPiBTYW1wbGVJRCA9IDA7CiAgICBpdDggLT5uVGFibGUgPSBqOwoKICAgIGZvciAoaWRGaWVsZCA9IDA7IGlkRmllbGQgPCB0IC0+IG5TYW1wbGVzOyBpZEZpZWxkKyspCiAgICB7CiAgICAgICAgaWYgKHQgLT5EYXRhRm9ybWF0ID09IE5VTEwpewogICAgICAgICAgICBTeW5FcnJvcihpdDgsICJVbmRlZmluZWQgREFUQV9GT1JNQVQiKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgRmxkID0gdC0+RGF0YUZvcm1hdFtpZEZpZWxkXTsKICAgICAgICBpZiAoIUZsZCkgY29udGludWU7CgoKICAgICAgICBpZiAoY21zc3RyY2FzZWNtcChGbGQsICJTQU1QTEVfSUQiKSA9PSAwKSB7CgogICAgICAgICAgICB0IC0+IFNhbXBsZUlEID0gaWRGaWVsZDsKCiAgICAgICAgICAgIGZvciAoaT0wOyBpIDwgdCAtPiBuUGF0Y2hlczsgaSsrKSB7CgogICAgICAgICAgICAgICAgY2hhciAqRGF0YSA9IEdldERhdGEoaXQ4LCBpLCBpZEZpZWxkKTsKICAgICAgICAgICAgICAgIGlmIChEYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgY2hhciBCdWZmZXJbMjU2XTsKCiAgICAgICAgICAgICAgICAgICAgc3RybmNweShCdWZmZXIsIERhdGEsIDI1NSk7CiAgICAgICAgICAgICAgICAgICAgQnVmZmVyWzI1NV0gPSAwOwoKICAgICAgICAgICAgICAgICAgICBpZiAoc3RybGVuKEJ1ZmZlcikgPD0gc3RybGVuKERhdGEpKQogICAgICAgICAgICAgICAgICAgICAgICBzdHJjcHkoRGF0YSwgQnVmZmVyKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIFNldERhdGEoaXQ4LCBpLCBpZEZpZWxkLCBCdWZmZXIpOwoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICB9CgogICAgICAgIC8vICJMQUJFTCIgaXMgYW4gZXh0ZW5zaW9uLiBJdCBrZWVwcyByZWZlcmVuY2VzIHRvIGZvcndhcmQgdGFibGVzCgogICAgICAgIGlmICgoY21zc3RyY2FzZWNtcChGbGQsICJMQUJFTCIpID09IDApIHx8IEZsZFswXSA9PSAnJCcgKSB7CgogICAgICAgICAgICAgICAgICAgIC8vIFNlYXJjaCBmb3IgdGFibGUgcmVmZXJlbmNlcy4uLgogICAgICAgICAgICAgICAgICAgIGZvciAoaT0wOyBpIDwgdCAtPiBuUGF0Y2hlczsgaSsrKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciAqTGFiZWwgPSBHZXREYXRhKGl0OCwgaSwgaWRGaWVsZCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKExhYmVsKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBrOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBsYWJlbCwgc2VhcmNoIGZvciBhIHRhYmxlIGNvbnRhaW5pbmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHByb3BlcnR5CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaz0wOyBrIDwgaXQ4IC0+VGFibGVzQ291bnQ7IGsrKykgewoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVEFCTEUqIFRhYmxlID0gaXQ4IC0+VGFiICsgazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZVkFMVUUqIHA7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoSXNBdmFpbGFibGVPbkxpc3QoVGFibGUtPkhlYWRlckxpc3QsIExhYmVsLCBOVUxMLCAmcCkpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdmFpbGFibGUsIGtlZXAgdHlwZSBhbmQgdGFibGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgQnVmZmVyWzI1Nl07CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciAqVHlwZSAgPSBwIC0+VmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgIG5UYWJsZSA9IChpbnQpIGs7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25wcmludGYoQnVmZmVyLCAyNTUsICIlcyAlZCAlcyIsIExhYmVsLCBuVGFibGUsIFR5cGUgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXREYXRhKGl0OCwgaSwgaWRGaWVsZCwgQnVmZmVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCgogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB9CgoKICAgICAgICB9CgogICAgfQogICAgfQoKICAgIGl0OCAtPm5UYWJsZSA9IG5PbGRUYWJsZTsKfQoKLy8gVHJ5IHRvIGluZmVyZSBpZiB0aGUgZmlsZSBpcyBhIENHQVRTL0lUOCBmaWxlIGF0IGFsbC4gUmVhZCBmaXJzdCBsaW5lCi8vIHRoYXQgc2hvdWxkIGJlIHNvbWV0aGluZyBsaWtlIHNvbWUgcHJpbnRhYmxlIGNoYXJhY3RlcnMgcGx1cyBhIFxuCi8vIHJldHVybnMgMCBpZiB0aGlzIGlzIG5vdCBsaWtlIGEgQ0dBVFMsIG9yIGFuIGludGVnZXIgb3RoZXJ3aXNlLiBUaGlzIGludGVnZXIgaXMgdGhlIG51bWJlciBvZiB3b3JkcyBpbiBmaXJzdCBsaW5lPwpzdGF0aWMKaW50IElzTXlCbG9jayhjbXNVSW50OE51bWJlciogQnVmZmVyLCBpbnQgbikKewogICAgaW50IHdvcmRzID0gMSwgc3BhY2UgPSAwLCBxdW90ID0gMDsKICAgIGludCBpOwoKICAgIGlmIChuIDwgMTApIHJldHVybiAwOyAgIC8vIFRvbyBzbWFsbAoKICAgIGlmIChuID4gMTMyKQogICAgICAgIG4gPSAxMzI7CgogICAgZm9yIChpID0gMTsgaSA8IG47IGkrKykgewoKICAgICAgICBzd2l0Y2goQnVmZmVyW2ldKQogICAgICAgIHsKICAgICAgICBjYXNlICdcbic6CiAgICAgICAgY2FzZSAnXHInOgogICAgICAgICAgICByZXR1cm4gKChxdW90ID09IDEpIHx8ICh3b3JkcyA+IDIpKSA/IDAgOiB3b3JkczsKICAgICAgICBjYXNlICdcdCc6CiAgICAgICAgY2FzZSAnICc6CiAgICAgICAgICAgIGlmKCFxdW90ICYmICFzcGFjZSkKICAgICAgICAgICAgICAgIHNwYWNlID0gMTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnXCInOgogICAgICAgICAgICBxdW90ID0gIXF1b3Q7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGlmIChCdWZmZXJbaV0gPCAzMikgcmV0dXJuIDA7CiAgICAgICAgICAgIGlmIChCdWZmZXJbaV0gPiAxMjcpIHJldHVybiAwOwogICAgICAgICAgICB3b3JkcyArPSBzcGFjZTsKICAgICAgICAgICAgc3BhY2UgPSAwOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCgpzdGF0aWMKY21zQm9vbCBJc015RmlsZShjb25zdCBjaGFyKiBGaWxlTmFtZSkKewogICBGSUxFICpmcDsKICAgY21zVUludDMyTnVtYmVyIFNpemU7CiAgIGNtc1VJbnQ4TnVtYmVyIFB0clsxMzNdOwoKICAgZnAgPSBmb3BlbihGaWxlTmFtZSwgInJ0Iik7CiAgIGlmICghZnApIHsKICAgICAgIGNtc1NpZ25hbEVycm9yKDAsIGNtc0VSUk9SX0ZJTEUsICJGaWxlICclcycgbm90IGZvdW5kIiwgRmlsZU5hbWUpOwogICAgICAgcmV0dXJuIEZBTFNFOwogICB9CgogICBTaXplID0gKGNtc1VJbnQzMk51bWJlcikgZnJlYWQoUHRyLCAxLCAxMzIsIGZwKTsKCiAgIGlmIChmY2xvc2UoZnApICE9IDApCiAgICAgICByZXR1cm4gRkFMU0U7CgogICBQdHJbU2l6ZV0gPSAnXDAnOwoKICAgcmV0dXJuIElzTXlCbG9jayhQdHIsIFNpemUpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV4cG9ydGVkIHJvdXRpbmVzCgoKY21zSEFORExFICBDTVNFWFBPUlQgY21zSVQ4TG9hZEZyb21NZW0oY21zQ29udGV4dCBDb250ZXh0SUQsIHZvaWQgKlB0ciwgY21zVUludDMyTnVtYmVyIGxlbikKewogICAgY21zSEFORExFIGhJVDg7CiAgICBjbXNJVDgqICBpdDg7CiAgICBpbnQgdHlwZTsKCiAgICBfY21zQXNzZXJ0KFB0ciAhPSBOVUxMKTsKICAgIF9jbXNBc3NlcnQobGVuICE9IDApOwoKICAgIHR5cGUgPSBJc015QmxvY2soKGNtc1VJbnQ4TnVtYmVyKilQdHIsIGxlbik7CiAgICBpZiAodHlwZSA9PSAwKSByZXR1cm4gTlVMTDsKCiAgICBoSVQ4ID0gY21zSVQ4QWxsb2MoQ29udGV4dElEKTsKICAgIGlmICghaElUOCkgcmV0dXJuIE5VTEw7CgogICAgaXQ4ID0gKGNtc0lUOCopIGhJVDg7CiAgICBpdDggLT5NZW1vcnlCbG9jayA9IChjaGFyKikgX2Ntc01hbGxvYyhDb250ZXh0SUQsIGxlbiArIDEpOwoKICAgIHN0cm5jcHkoaXQ4IC0+TWVtb3J5QmxvY2ssIChjb25zdCBjaGFyKikgUHRyLCBsZW4pOwogICAgaXQ4IC0+TWVtb3J5QmxvY2tbbGVuXSA9IDA7CgogICAgc3RybmNweShpdDgtPkZpbGVTdGFja1swXS0+RmlsZU5hbWUsICIiLCBjbXNNQVhfUEFUSC0xKTsKICAgIGl0OC0+IFNvdXJjZSA9IGl0OCAtPiBNZW1vcnlCbG9jazsKCiAgICBpZiAoIVBhcnNlSVQ4KGl0OCwgdHlwZS0xKSkgewoKICAgICAgICBjbXNJVDhGcmVlKGhJVDgpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBDb29rUG9pbnRlcnMoaXQ4KTsKICAgIGl0OCAtPm5UYWJsZSA9IDA7CgogICAgX2Ntc0ZyZWUoQ29udGV4dElELCBpdDgtPk1lbW9yeUJsb2NrKTsKICAgIGl0OCAtPiBNZW1vcnlCbG9jayA9IE5VTEw7CgogICAgcmV0dXJuIGhJVDg7CgoKfQoKCmNtc0hBTkRMRSAgQ01TRVhQT1JUIGNtc0lUOExvYWRGcm9tRmlsZShjbXNDb250ZXh0IENvbnRleHRJRCwgY29uc3QgY2hhciogY0ZpbGVOYW1lKQp7CgogICAgIGNtc0hBTkRMRSBoSVQ4OwogICAgIGNtc0lUOCogIGl0ODsKICAgICBpbnQgdHlwZTsKCiAgICAgX2Ntc0Fzc2VydChjRmlsZU5hbWUgIT0gTlVMTCk7CgogICAgIHR5cGUgPSBJc015RmlsZShjRmlsZU5hbWUpOwogICAgIGlmICh0eXBlID09IDApIHJldHVybiBOVUxMOwoKICAgICBoSVQ4ID0gY21zSVQ4QWxsb2MoQ29udGV4dElEKTsKICAgICBpdDggPSAoY21zSVQ4KikgaElUODsKICAgICBpZiAoIWhJVDgpIHJldHVybiBOVUxMOwoKCiAgICAgaXQ4IC0+RmlsZVN0YWNrWzBdLT5TdHJlYW0gPSBmb3BlbihjRmlsZU5hbWUsICJydCIpOwoKICAgICBpZiAoIWl0OCAtPkZpbGVTdGFja1swXS0+U3RyZWFtKSB7CiAgICAgICAgIGNtc0lUOEZyZWUoaElUOCk7CiAgICAgICAgIHJldHVybiBOVUxMOwogICAgIH0KCgogICAgc3RybmNweShpdDgtPkZpbGVTdGFja1swXS0+RmlsZU5hbWUsIGNGaWxlTmFtZSwgY21zTUFYX1BBVEgtMSk7CiAgICBpdDgtPkZpbGVTdGFja1swXS0+RmlsZU5hbWVbY21zTUFYX1BBVEgtMV0gPSAwOwoKICAgIGlmICghUGFyc2VJVDgoaXQ4LCB0eXBlLTEpKSB7CgogICAgICAgICAgICBmY2xvc2UoaXQ4IC0+RmlsZVN0YWNrWzBdLT5TdHJlYW0pOwogICAgICAgICAgICBjbXNJVDhGcmVlKGhJVDgpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBDb29rUG9pbnRlcnMoaXQ4KTsKICAgIGl0OCAtPm5UYWJsZSA9IDA7CgogICAgaWYgKGZjbG9zZShpdDggLT5GaWxlU3RhY2tbMF0tPlN0cmVhbSkhPSAwKSB7CiAgICAgICAgICAgIGNtc0lUOEZyZWUoaElUOCk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJldHVybiBoSVQ4OwoKfQoKaW50IENNU0VYUE9SVCBjbXNJVDhFbnVtRGF0YUZvcm1hdChjbXNIQU5ETEUgaElUOCwgY2hhciAqKipTYW1wbGVOYW1lcykKewogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKICAgIFRBQkxFKiB0OwoKICAgIF9jbXNBc3NlcnQoaElUOCAhPSBOVUxMKTsKCiAgICB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBpZiAoU2FtcGxlTmFtZXMpCiAgICAgICAgKlNhbXBsZU5hbWVzID0gdCAtPiBEYXRhRm9ybWF0OwogICAgcmV0dXJuIHQgLT4gblNhbXBsZXM7Cn0KCgpjbXNVSW50MzJOdW1iZXIgQ01TRVhQT1JUIGNtc0lUOEVudW1Qcm9wZXJ0aWVzKGNtc0hBTkRMRSBoSVQ4LCBjaGFyICoqKlByb3BlcnR5TmFtZXMpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CiAgICBLRVlWQUxVRSogcDsKICAgIGNtc1VJbnQzMk51bWJlciBuOwogICAgY2hhciAqKlByb3BzOwogICAgVEFCTEUqIHQ7CgogICAgX2Ntc0Fzc2VydChoSVQ4ICE9IE5VTEwpOwoKICAgIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIC8vIFBhc3MjMSAtIGNvdW50IHByb3BlcnRpZXMKCiAgICBuID0gMDsKICAgIGZvciAocCA9IHQgLT4gSGVhZGVyTGlzdDsgIHAgIT0gTlVMTDsgcCA9IHAtPk5leHQpIHsKICAgICAgICBuKys7CiAgICB9CgoKICAgIFByb3BzID0gKGNoYXIgKiopIEFsbG9jQ2h1bmsoaXQ4LCBzaXplb2YoY2hhciAqKSAqIG4pOwoKICAgIC8vIFBhc3MjMiAtIEZpbGwgcG9pbnRlcnMKICAgIG4gPSAwOwogICAgZm9yIChwID0gdCAtPiBIZWFkZXJMaXN0OyAgcCAhPSBOVUxMOyBwID0gcC0+TmV4dCkgewogICAgICAgIFByb3BzW24rK10gPSBwIC0+IEtleXdvcmQ7CiAgICB9CgogICAgKlByb3BlcnR5TmFtZXMgPSBQcm9wczsKICAgIHJldHVybiBuOwp9CgpjbXNVSW50MzJOdW1iZXIgQ01TRVhQT1JUIGNtc0lUOEVudW1Qcm9wZXJ0eU11bHRpKGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCwgY29uc3QgY2hhciAqKipTdWJwcm9wZXJ0eU5hbWVzKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwogICAgS0VZVkFMVUUgKnAsICp0bXA7CiAgICBjbXNVSW50MzJOdW1iZXIgbjsKICAgIGNvbnN0IGNoYXIgKipQcm9wczsKICAgIFRBQkxFKiB0OwoKICAgIF9jbXNBc3NlcnQoaElUOCAhPSBOVUxMKTsKCgogICAgdCA9IEdldFRhYmxlKGl0OCk7CgogICAgaWYoIUlzQXZhaWxhYmxlT25MaXN0KHQtPkhlYWRlckxpc3QsIGNQcm9wLCBOVUxMLCAmcCkpIHsKICAgICAgICAqU3VicHJvcGVydHlOYW1lcyA9IDA7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLy8gUGFzcyMxIC0gY291bnQgcHJvcGVydGllcwoKICAgIG4gPSAwOwogICAgZm9yICh0bXAgPSBwOyAgdG1wICE9IE5VTEw7IHRtcCA9IHRtcC0+TmV4dFN1YmtleSkgewogICAgICAgIGlmKHRtcC0+U3Via2V5ICE9IE5VTEwpCiAgICAgICAgICAgIG4rKzsKICAgIH0KCgogICAgUHJvcHMgPSAoY29uc3QgY2hhciAqKikgQWxsb2NDaHVuayhpdDgsIHNpemVvZihjaGFyICopICogbik7CgogICAgLy8gUGFzcyMyIC0gRmlsbCBwb2ludGVycwogICAgbiA9IDA7CiAgICBmb3IgKHRtcCA9IHA7ICB0bXAgIT0gTlVMTDsgdG1wID0gdG1wLT5OZXh0U3Via2V5KSB7CiAgICAgICAgaWYodG1wLT5TdWJrZXkgIT0gTlVMTCkKICAgICAgICAgICAgUHJvcHNbbisrXSA9IHAgLT5TdWJrZXk7CiAgICB9CgogICAgKlN1YnByb3BlcnR5TmFtZXMgPSBQcm9wczsKICAgIHJldHVybiBuOwp9CgpzdGF0aWMKaW50IExvY2F0ZVBhdGNoKGNtc0lUOCogaXQ4LCBjb25zdCBjaGFyKiBjUGF0Y2gpCnsKICAgIGludCBpOwogICAgY29uc3QgY2hhciAqZGF0YTsKICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBmb3IgKGk9MDsgaSA8IHQtPiBuUGF0Y2hlczsgaSsrKSB7CgogICAgICAgIGRhdGEgPSBHZXREYXRhKGl0OCwgaSwgdC0+U2FtcGxlSUQpOwoKICAgICAgICBpZiAoZGF0YSAhPSBOVUxMKSB7CgogICAgICAgICAgICAgICAgaWYgKGNtc3N0cmNhc2VjbXAoZGF0YSwgY1BhdGNoKSA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFN5bkVycm9yKGl0OCwgIkNvdWxkbid0IGZpbmQgcGF0Y2ggJyVzJ1xuIiwgY1BhdGNoKTsKICAgICAgICByZXR1cm4gLTE7Cn0KCgpzdGF0aWMKaW50IExvY2F0ZUVtcHR5UGF0Y2goY21zSVQ4KiBpdDgpCnsKICAgIGludCBpOwogICAgY29uc3QgY2hhciAqZGF0YTsKICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBmb3IgKGk9MDsgaSA8IHQtPiBuUGF0Y2hlczsgaSsrKSB7CgogICAgICAgIGRhdGEgPSBHZXREYXRhKGl0OCwgaSwgdC0+U2FtcGxlSUQpOwoKICAgICAgICBpZiAoZGF0YSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gaTsKCiAgICB9CgogICAgcmV0dXJuIC0xOwp9CgpzdGF0aWMKaW50IExvY2F0ZVNhbXBsZShjbXNJVDgqIGl0OCwgY29uc3QgY2hhciogY1NhbXBsZSkKewogICAgaW50IGk7CiAgICBjb25zdCBjaGFyICpmbGQ7CiAgICBUQUJMRSogdCA9IEdldFRhYmxlKGl0OCk7CgogICAgZm9yIChpPTA7IGkgPCB0LT5uU2FtcGxlczsgaSsrKSB7CgogICAgICAgIGZsZCA9IEdldERhdGFGb3JtYXQoaXQ4LCBpKTsKICAgICAgICBpZiAoY21zc3RyY2FzZWNtcChmbGQsIGNTYW1wbGUpID09IDApCiAgICAgICAgICAgIHJldHVybiBpOwogICAgfQoKICAgIHJldHVybiAtMTsKCn0KCgppbnQgQ01TRVhQT1JUIGNtc0lUOEZpbmREYXRhRm9ybWF0KGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjU2FtcGxlKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwoKICAgIF9jbXNBc3NlcnQoaElUOCAhPSBOVUxMKTsKCiAgICByZXR1cm4gTG9jYXRlU2FtcGxlKGl0OCwgY1NhbXBsZSk7Cn0KCgoKY29uc3QgY2hhciogQ01TRVhQT1JUIGNtc0lUOEdldERhdGFSb3dDb2woY21zSEFORExFIGhJVDgsIGludCByb3csIGludCBjb2wpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CgogICAgX2Ntc0Fzc2VydChoSVQ4ICE9IE5VTEwpOwoKICAgIHJldHVybiBHZXREYXRhKGl0OCwgcm93LCBjb2wpOwp9CgoKY21zRmxvYXQ2NE51bWJlciBDTVNFWFBPUlQgY21zSVQ4R2V0RGF0YVJvd0NvbERibChjbXNIQU5ETEUgaElUOCwgaW50IHJvdywgaW50IGNvbCkKewogICAgY29uc3QgY2hhciogQnVmZmVyOwoKICAgIEJ1ZmZlciA9IGNtc0lUOEdldERhdGFSb3dDb2woaElUOCwgcm93LCBjb2wpOwoKICAgIGlmIChCdWZmZXIgPT0gTlVMTCkgcmV0dXJuIDAuMDsKCiAgICByZXR1cm4gUGFyc2VGbG9hdE51bWJlcihCdWZmZXIpOwp9CgoKY21zQm9vbCBDTVNFWFBPUlQgY21zSVQ4U2V0RGF0YVJvd0NvbChjbXNIQU5ETEUgaElUOCwgaW50IHJvdywgaW50IGNvbCwgY29uc3QgY2hhciogVmFsKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwoKICAgIF9jbXNBc3NlcnQoaElUOCAhPSBOVUxMKTsKCiAgICByZXR1cm4gU2V0RGF0YShpdDgsIHJvdywgY29sLCBWYWwpOwp9CgoKY21zQm9vbCBDTVNFWFBPUlQgY21zSVQ4U2V0RGF0YVJvd0NvbERibChjbXNIQU5ETEUgaElUOCwgaW50IHJvdywgaW50IGNvbCwgY21zRmxvYXQ2NE51bWJlciBWYWwpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CiAgICBjaGFyIEJ1ZmZbMjU2XTsKCiAgICBfY21zQXNzZXJ0KGhJVDggIT0gTlVMTCk7CgogICAgc3ByaW50ZihCdWZmLCBpdDgtPkRvdWJsZUZvcm1hdHRlciwgVmFsKTsKCiAgICByZXR1cm4gU2V0RGF0YShpdDgsIHJvdywgY29sLCBCdWZmKTsKfQoKCgpjb25zdCBjaGFyKiBDTVNFWFBPUlQgY21zSVQ4R2V0RGF0YShjbXNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1BhdGNoLCBjb25zdCBjaGFyKiBjU2FtcGxlKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwogICAgaW50IGlGaWVsZCwgaVNldDsKCiAgICBfY21zQXNzZXJ0KGhJVDggIT0gTlVMTCk7CgogICAgaUZpZWxkID0gTG9jYXRlU2FtcGxlKGl0OCwgY1NhbXBsZSk7CiAgICBpZiAoaUZpZWxkIDwgMCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlTZXQgPSBMb2NhdGVQYXRjaChpdDgsIGNQYXRjaCk7CiAgICBpZiAoaVNldCA8IDApIHsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIEdldERhdGEoaXQ4LCBpU2V0LCBpRmllbGQpOwp9CgoKY21zRmxvYXQ2NE51bWJlciBDTVNFWFBPUlQgY21zSVQ4R2V0RGF0YURibChjbXNIQU5ETEUgIGl0OCwgY29uc3QgY2hhciogY1BhdGNoLCBjb25zdCBjaGFyKiBjU2FtcGxlKQp7CiAgICBjb25zdCBjaGFyKiBCdWZmZXI7CgogICAgQnVmZmVyID0gY21zSVQ4R2V0RGF0YShpdDgsIGNQYXRjaCwgY1NhbXBsZSk7CgogICAgcmV0dXJuIFBhcnNlRmxvYXROdW1iZXIoQnVmZmVyKTsKfQoKCgpjbXNCb29sIENNU0VYUE9SVCBjbXNJVDhTZXREYXRhKGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUGF0Y2gsIGNvbnN0IGNoYXIqIGNTYW1wbGUsIGNvbnN0IGNoYXIgKlZhbCkKewogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKICAgIGludCBpRmllbGQsIGlTZXQ7CiAgICBUQUJMRSogdDsKCiAgICBfY21zQXNzZXJ0KGhJVDggIT0gTlVMTCk7CgogICAgdCA9IEdldFRhYmxlKGl0OCk7CgogICAgaUZpZWxkID0gTG9jYXRlU2FtcGxlKGl0OCwgY1NhbXBsZSk7CgogICAgaWYgKGlGaWVsZCA8IDApCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmICh0LT4gblBhdGNoZXMgPT0gMCkgewoKICAgICAgICBBbGxvY2F0ZURhdGFGb3JtYXQoaXQ4KTsKICAgICAgICBBbGxvY2F0ZURhdGFTZXQoaXQ4KTsKICAgICAgICBDb29rUG9pbnRlcnMoaXQ4KTsKICAgIH0KCiAgICBpZiAoY21zc3RyY2FzZWNtcChjU2FtcGxlLCAiU0FNUExFX0lEIikgPT0gMCkgewoKICAgICAgICBpU2V0ICAgPSBMb2NhdGVFbXB0eVBhdGNoKGl0OCk7CiAgICAgICAgaWYgKGlTZXQgPCAwKSB7CiAgICAgICAgICAgIHJldHVybiBTeW5FcnJvcihpdDgsICJDb3VsZG4ndCBhZGQgbW9yZSBwYXRjaGVzICclcydcbiIsIGNQYXRjaCk7CiAgICAgICAgfQoKICAgICAgICBpRmllbGQgPSB0IC0+IFNhbXBsZUlEOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgaVNldCA9IExvY2F0ZVBhdGNoKGl0OCwgY1BhdGNoKTsKICAgICAgICBpZiAoaVNldCA8IDApIHsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gU2V0RGF0YShpdDgsIGlTZXQsIGlGaWVsZCwgVmFsKTsKfQoKCmNtc0Jvb2wgQ01TRVhQT1JUIGNtc0lUOFNldERhdGFEYmwoY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNQYXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBjU2FtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc0Zsb2F0NjROdW1iZXIgVmFsKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwogICAgY2hhciBCdWZmWzI1Nl07CgogICAgX2Ntc0Fzc2VydChoSVQ4ICE9IE5VTEwpOwoKICAgIHNucHJpbnRmKEJ1ZmYsIDI1NSwgaXQ4LT5Eb3VibGVGb3JtYXR0ZXIsIFZhbCk7CiAgICByZXR1cm4gY21zSVQ4U2V0RGF0YShoSVQ4LCBjUGF0Y2gsIGNTYW1wbGUsIEJ1ZmYpOwp9CgovLyBCdWZmZXIgc2hvdWxkIGdldCBNQVhTVFIgYXQgbGVhc3QKCmNvbnN0IGNoYXIqIENNU0VYUE9SVCBjbXNJVDhHZXRQYXRjaE5hbWUoY21zSEFORExFIGhJVDgsIGludCBuUGF0Y2gsIGNoYXIqIGJ1ZmZlcikKewogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKICAgIFRBQkxFKiB0OwogICAgY2hhciogRGF0YTsKCiAgICBfY21zQXNzZXJ0KGhJVDggIT0gTlVMTCk7CgogICAgdCA9IEdldFRhYmxlKGl0OCk7CiAgICBEYXRhID0gR2V0RGF0YShpdDgsIG5QYXRjaCwgdC0+U2FtcGxlSUQpOwoKICAgIGlmICghRGF0YSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIWJ1ZmZlcikgcmV0dXJuIERhdGE7CgogICAgc3RybmNweShidWZmZXIsIERhdGEsIE1BWFNUUi0xKTsKICAgIGJ1ZmZlcltNQVhTVFItMV0gPSAwOwogICAgcmV0dXJuIGJ1ZmZlcjsKfQoKaW50IENNU0VYUE9SVCBjbXNJVDhHZXRQYXRjaEJ5TmFtZShjbXNIQU5ETEUgaElUOCwgY29uc3QgY2hhciAqY1BhdGNoKQp7CiAgICBfY21zQXNzZXJ0KGhJVDggIT0gTlVMTCk7CgogICAgcmV0dXJuIExvY2F0ZVBhdGNoKChjbXNJVDgqKWhJVDgsIGNQYXRjaCk7Cn0KCmNtc1VJbnQzMk51bWJlciBDTVNFWFBPUlQgY21zSVQ4VGFibGVDb3VudChjbXNIQU5ETEUgaElUOCkKewogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKCiAgICBfY21zQXNzZXJ0KGhJVDggIT0gTlVMTCk7CgogICAgcmV0dXJuIGl0OCAtPlRhYmxlc0NvdW50Owp9CgovLyBUaGlzIGhhbmRsZXMgdGhlICJMQUJFTCIgZXh0ZW5zaW9uLgovLyBMYWJlbCwgblRhYmxlLCBUeXBlCgppbnQgQ01TRVhQT1JUIGNtc0lUOFNldFRhYmxlQnlMYWJlbChjbXNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1NldCwgY29uc3QgY2hhciogY0ZpZWxkLCBjb25zdCBjaGFyKiBFeHBlY3RlZFR5cGUpCnsKICAgIGNvbnN0IGNoYXIqIGNMYWJlbEZsZDsKICAgIGNoYXIgVHlwZVsyNTZdLCBMYWJlbFsyNTZdOwogICAgaW50IG5UYWJsZTsKCiAgICBfY21zQXNzZXJ0KGhJVDggIT0gTlVMTCk7CgogICAgaWYgKGNGaWVsZCAhPSBOVUxMICYmICpjRmllbGQgPT0gMCkKICAgICAgICAgICAgY0ZpZWxkID0gIkxBQkVMIjsKCiAgICBpZiAoY0ZpZWxkID09IE5VTEwpCiAgICAgICAgICAgIGNGaWVsZCA9ICJMQUJFTCI7CgogICAgY0xhYmVsRmxkID0gY21zSVQ4R2V0RGF0YShoSVQ4LCBjU2V0LCBjRmllbGQpOwogICAgaWYgKCFjTGFiZWxGbGQpIHJldHVybiAtMTsKCiAgICBpZiAoc3NjYW5mKGNMYWJlbEZsZCwgIiUyNTVzICVkICUyNTVzIiwgTGFiZWwsICZuVGFibGUsIFR5cGUpICE9IDMpCiAgICAgICAgICAgIHJldHVybiAtMTsKCiAgICBpZiAoRXhwZWN0ZWRUeXBlICE9IE5VTEwgJiYgKkV4cGVjdGVkVHlwZSA9PSAwKQogICAgICAgIEV4cGVjdGVkVHlwZSA9IE5VTEw7CgogICAgaWYgKEV4cGVjdGVkVHlwZSkgewoKICAgICAgICBpZiAoY21zc3RyY2FzZWNtcChUeXBlLCBFeHBlY3RlZFR5cGUpICE9IDApIHJldHVybiAtMTsKICAgIH0KCiAgICByZXR1cm4gY21zSVQ4U2V0VGFibGUoaElUOCwgblRhYmxlKTsKfQoKCmNtc0Jvb2wgQ01TRVhQT1JUIGNtc0lUOFNldEluZGV4Q29sdW1uKGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjU2FtcGxlKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwogICAgaW50IHBvczsKCiAgICBfY21zQXNzZXJ0KGhJVDggIT0gTlVMTCk7CgogICAgcG9zID0gTG9jYXRlU2FtcGxlKGl0OCwgY1NhbXBsZSk7CiAgICBpZihwb3MgPT0gLTEpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGl0OC0+VGFiW2l0OC0+blRhYmxlXS5TYW1wbGVJRCA9IHBvczsKICAgIHJldHVybiBUUlVFOwp9CgoKdm9pZCBDTVNFWFBPUlQgY21zSVQ4RGVmaW5lRGJsRm9ybWF0KGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBGb3JtYXR0ZXIpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CgogICAgX2Ntc0Fzc2VydChoSVQ4ICE9IE5VTEwpOwoKICAgIGlmIChGb3JtYXR0ZXIgPT0gTlVMTCkKICAgICAgICBzdHJjcHkoaXQ4LT5Eb3VibGVGb3JtYXR0ZXIsIERFRkFVTFRfREJMX0ZPUk1BVCk7CiAgICBlbHNlCiAgICAgICAgc3RybmNweShpdDgtPkRvdWJsZUZvcm1hdHRlciwgRm9ybWF0dGVyLCBzaXplb2YoaXQ4LT5Eb3VibGVGb3JtYXR0ZXIpKTsKCiAgICBpdDggLT5Eb3VibGVGb3JtYXR0ZXJbc2l6ZW9mKGl0OCAtPkRvdWJsZUZvcm1hdHRlciktMV0gPSAwOwp9Cg==