LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNuYW1lLmMsdiAxLjE1IDIwMDIvMDkvMjYgMDA6MTc6Mjgga2VpdGhwIEV4cCAkCiAqCiAqIENvcHlyaWdodCCpIDIwMDAgS2VpdGggUGFja2FyZAogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgImZjaW50LmgiCgpzdGF0aWMgY29uc3QgRmNPYmplY3RUeXBlIF9GY0Jhc2VPYmplY3RUeXBlc1tdID0gewogICAgeyBGQ19GQU1JTFksCUZjVHlwZVN0cmluZywgfSwKICAgIHsgRkNfU1RZTEUsCQlGY1R5cGVTdHJpbmcsIH0sCiAgICB7IEZDX1NMQU5ULAkJRmNUeXBlSW50ZWdlciwgfSwKICAgIHsgRkNfV0VJR0hULAlGY1R5cGVJbnRlZ2VyLCB9LAogICAgeyBGQ19XSURUSCwJCUZjVHlwZUludGVnZXIsIH0sCiAgICB7IEZDX1NJWkUsCQlGY1R5cGVEb3VibGUsIH0sCiAgICB7IEZDX0FTUEVDVCwJRmNUeXBlRG91YmxlLCB9LAogICAgeyBGQ19QSVhFTF9TSVpFLAlGY1R5cGVEb3VibGUsIH0sCiAgICB7IEZDX1NQQUNJTkcsCUZjVHlwZUludGVnZXIsIH0sCiAgICB7IEZDX0ZPVU5EUlksCUZjVHlwZVN0cmluZywgfSwKLyogICAgeyBGQ19DT1JFLAkJRmNUeXBlQm9vbCwgfSwgKi8KICAgIHsgRkNfQU5USUFMSUFTLAlGY1R5cGVCb29sLCB9LAogICAgeyBGQ19ISU5USU5HLAlGY1R5cGVCb29sLCB9LAogICAgeyBGQ19WRVJUSUNBTF9MQVlPVVQsICAgRmNUeXBlQm9vbCwgfSwKICAgIHsgRkNfQVVUT0hJTlQsCUZjVHlwZUJvb2wsIH0sCiAgICB7IEZDX0dMT0JBTF9BRFZBTkNFLCAgICBGY1R5cGVCb29sLCB9LAovKiAgICB7IEZDX1hMRkQsCQlGY1R5cGVTdHJpbmcsIH0sICovCiAgICB7IEZDX0ZJTEUsCQlGY1R5cGVTdHJpbmcsIH0sCiAgICB7IEZDX0lOREVYLAkJRmNUeXBlSW50ZWdlciwgfSwKICAgIHsgRkNfUkFTVEVSSVpFUiwJRmNUeXBlU3RyaW5nLCB9LAogICAgeyBGQ19PVVRMSU5FLAlGY1R5cGVCb29sLCB9LAogICAgeyBGQ19TQ0FMQUJMRSwJRmNUeXBlQm9vbCwgfSwKICAgIHsgRkNfRFBJLAkJRmNUeXBlRG91YmxlIH0sCiAgICB7IEZDX1JHQkEsCQlGY1R5cGVJbnRlZ2VyLCB9LAogICAgeyBGQ19TQ0FMRSwJCUZjVHlwZURvdWJsZSwgfSwKLyogICAgeyBGQ19SRU5ERVIsCUZjVHlwZUJvb2wsIH0sKi8KICAgIHsgRkNfTUlOU1BBQ0UsCUZjVHlwZUJvb2wsIH0sCiAgICB7IEZDX0NIQVJfV0lEVEgsCUZjVHlwZUludGVnZXIgfSwKICAgIHsgRkNfQ0hBUl9IRUlHSFQsCUZjVHlwZUludGVnZXIgfSwKICAgIHsgRkNfTUFUUklYLAlGY1R5cGVNYXRyaXggfSwKICAgIHsgRkNfQ0hBUlNFVCwJRmNUeXBlQ2hhclNldCB9LAogICAgeyBGQ19MQU5HLAkJRmNUeXBlTGFuZ1NldCB9LAogICAgeyBGQ19GT05UVkVSU0lPTiwJRmNUeXBlSW50ZWdlciB9LAp9OwoKI2RlZmluZSBOVU1fT0JKRUNUX1RZUEVTICAgIChzaXplb2YgX0ZjQmFzZU9iamVjdFR5cGVzIC8gc2l6ZW9mIF9GY0Jhc2VPYmplY3RUeXBlc1swXSkKCnR5cGVkZWYgc3RydWN0IF9GY09iamVjdFR5cGVMaXN0ICAgIEZjT2JqZWN0VHlwZUxpc3Q7CgpzdHJ1Y3QgX0ZjT2JqZWN0VHlwZUxpc3QgewogICAgY29uc3QgRmNPYmplY3RUeXBlTGlzdCAgKm5leHQ7CiAgICBjb25zdCBGY09iamVjdFR5cGUJICAgICp0eXBlczsKICAgIGludAkJCSAgICBudHlwZXM7Cn07CgpzdGF0aWMgY29uc3QgRmNPYmplY3RUeXBlTGlzdCBfRmNCYXNlT2JqZWN0VHlwZXNMaXN0ID0gewogICAgMCwKICAgIF9GY0Jhc2VPYmplY3RUeXBlcywKICAgIE5VTV9PQkpFQ1RfVFlQRVMKfTsKCnN0YXRpYyBjb25zdCBGY09iamVjdFR5cGVMaXN0CSpfRmNPYmplY3RUeXBlcyA9ICZfRmNCYXNlT2JqZWN0VHlwZXNMaXN0OwoKRmNCb29sCkZjTmFtZVJlZ2lzdGVyT2JqZWN0VHlwZXMgKGNvbnN0IEZjT2JqZWN0VHlwZSAqdHlwZXMsIGludCBudHlwZXMpCnsKICAgIEZjT2JqZWN0VHlwZUxpc3QJKmw7CgogICAgbCA9IChGY09iamVjdFR5cGVMaXN0ICopIG1hbGxvYyAoc2l6ZW9mIChGY09iamVjdFR5cGVMaXN0KSk7CiAgICBpZiAoIWwpCglyZXR1cm4gRmNGYWxzZTsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9PQkpFQ1RUWVBFLCBzaXplb2YgKEZjT2JqZWN0VHlwZUxpc3QpKTsKICAgIGwtPnR5cGVzID0gdHlwZXM7CiAgICBsLT5udHlwZXMgPSBudHlwZXM7CiAgICBsLT5uZXh0ID0gX0ZjT2JqZWN0VHlwZXM7CiAgICBfRmNPYmplY3RUeXBlcyA9IGw7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNOYW1lVW5yZWdpc3Rlck9iamVjdFR5cGVzIChjb25zdCBGY09iamVjdFR5cGUgKnR5cGVzLCBpbnQgbnR5cGVzKQp7CiAgICBjb25zdCBGY09iamVjdFR5cGVMaXN0CSpsLCAqKnByZXY7CgogICAgZm9yIChwcmV2ID0gJl9GY09iamVjdFR5cGVzOyAKCSAobCA9ICpwcmV2KTsgCgkgcHJldiA9IChjb25zdCBGY09iamVjdFR5cGVMaXN0ICoqKSAmKGwtPm5leHQpKQogICAgewoJaWYgKGwtPnR5cGVzID09IHR5cGVzICYmIGwtPm50eXBlcyA9PSBudHlwZXMpCgl7CgkgICAgKnByZXYgPSBsLT5uZXh0OwoJICAgIEZjTWVtRnJlZSAoRkNfTUVNX09CSkVDVFRZUEUsIHNpemVvZiAoRmNPYmplY3RUeXBlTGlzdCkpOwoJICAgIGZyZWUgKCh2b2lkICopIGwpOwoJICAgIHJldHVybiBGY1RydWU7Cgl9CiAgICB9CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKY29uc3QgRmNPYmplY3RUeXBlICoKRmNOYW1lR2V0T2JqZWN0VHlwZSAoY29uc3QgY2hhciAqb2JqZWN0KQp7CiAgICBpbnQJCQkgICAgaTsKICAgIGNvbnN0IEZjT2JqZWN0VHlwZUxpc3QgICpsOwogICAgY29uc3QgRmNPYmplY3RUeXBlCSAgICAqdDsKICAgIAogICAgZm9yIChsID0gX0ZjT2JqZWN0VHlwZXM7IGw7IGwgPSBsLT5uZXh0KQogICAgewoJZm9yIChpID0gMDsgaSA8IGwtPm50eXBlczsgaSsrKQoJewoJICAgIHQgPSAmbC0+dHlwZXNbaV07CgkgICAgaWYgKCFzdHJjbXAgKG9iamVjdCwgdC0+b2JqZWN0KSkKCQlyZXR1cm4gdDsKCX0KICAgIH0KICAgIHJldHVybiAwOwp9CgpzdGF0aWMgY29uc3QgRmNDb25zdGFudCBfRmNCYXNlQ29uc3RhbnRzW10gPSB7CiAgICB7IChGY0NoYXI4ICopICJ0aGluIiwJICAgICJ3ZWlnaHQiLCAgIEZDX1dFSUdIVF9USElOLCB9LAogICAgeyAoRmNDaGFyOCAqKSAiZXh0cmFsaWdodCIsCSAgICAid2VpZ2h0IiwgICBGQ19XRUlHSFRfRVhUUkFMSUdIVCwgfSwKICAgIHsgKEZjQ2hhcjggKikgInVsdHJhbGlnaHQiLAkgICAgIndlaWdodCIsICAgRkNfV0VJR0hUX0VYVFJBTElHSFQsIH0sCiAgICB7IChGY0NoYXI4ICopICJsaWdodCIsCSAgICAid2VpZ2h0IiwgICBGQ19XRUlHSFRfTElHSFQsIH0sCiAgICB7IChGY0NoYXI4ICopICJyZWd1bGFyIiwJICAgICJ3ZWlnaHQiLCAgIEZDX1dFSUdIVF9SRUdVTEFSLCB9LAogICAgeyAoRmNDaGFyOCAqKSAibWVkaXVtIiwJICAgICJ3ZWlnaHQiLCAgIEZDX1dFSUdIVF9NRURJVU0sIH0sCiAgICB7IChGY0NoYXI4ICopICJkZW1pYm9sZCIsCSAgICAid2VpZ2h0IiwgICBGQ19XRUlHSFRfREVNSUJPTEQsIH0sCiAgICB7IChGY0NoYXI4ICopICJzZW1pYm9sZCIsCSAgICAid2VpZ2h0IiwgICBGQ19XRUlHSFRfREVNSUJPTEQsIH0sCiAgICB7IChGY0NoYXI4ICopICJib2xkIiwJICAgICJ3ZWlnaHQiLCAgIEZDX1dFSUdIVF9CT0xELCB9LAogICAgeyAoRmNDaGFyOCAqKSAiZXh0cmFib2xkIiwJICAgICJ3ZWlnaHQiLCAgIEZDX1dFSUdIVF9FWFRSQUJPTEQsIH0sCiAgICB7IChGY0NoYXI4ICopICJ1bHRyYWJvbGQiLAkgICAgIndlaWdodCIsICAgRkNfV0VJR0hUX0VYVFJBQk9MRCwgfSwKICAgIHsgKEZjQ2hhcjggKikgImJsYWNrIiwJICAgICJ3ZWlnaHQiLCAgIEZDX1dFSUdIVF9CTEFDSywgfSwKCiAgICB7IChGY0NoYXI4ICopICJyb21hbiIsCSAgICAic2xhbnQiLCAgICBGQ19TTEFOVF9ST01BTiwgfSwKICAgIHsgKEZjQ2hhcjggKikgIml0YWxpYyIsCSAgICAic2xhbnQiLCAgICBGQ19TTEFOVF9JVEFMSUMsIH0sCiAgICB7IChGY0NoYXI4ICopICJvYmxpcXVlIiwJICAgICJzbGFudCIsICAgIEZDX1NMQU5UX09CTElRVUUsIH0sCgogICAgeyAoRmNDaGFyOCAqKSAidWx0cmFjb25kZW5zZWQiLCAid2lkdGgiLAlGQ19XSURUSF9VTFRSQUNPTkRFTlNFRCB9LAogICAgeyAoRmNDaGFyOCAqKSAiZXh0cmFjb25kZW5zZWQiLCAid2lkdGgiLAlGQ19XSURUSF9FWFRSQUNPTkRFTlNFRCB9LAogICAgeyAoRmNDaGFyOCAqKSAiY29uZGVuc2VkIiwJICAgICJ3aWR0aCIsCUZDX1dJRFRIX0NPTkRFTlNFRCB9LAogICAgeyAoRmNDaGFyOCAqKSAic2VtaWNvbmRlbnNlZCIsICJ3aWR0aCIsCUZDX1dJRFRIX1NFTUlDT05ERU5TRUQgfSwKICAgIHsgKEZjQ2hhcjggKikgIm5vcm1hbCIsCSAgICAid2lkdGgiLAlGQ19XSURUSF9OT1JNQUwgfSwKICAgIHsgKEZjQ2hhcjggKikgInNlbWlleHBhbmRlZCIsICAgIndpZHRoIiwJRkNfV0lEVEhfU0VNSUVYUEFOREVEIH0sCiAgICB7IChGY0NoYXI4ICopICJleHBhbmRlZCIsCSAgICAid2lkdGgiLAlGQ19XSURUSF9FWFBBTkRFRCB9LAogICAgeyAoRmNDaGFyOCAqKSAiZXh0cmFleHBhbmRlZCIsICAid2lkdGgiLAlGQ19XSURUSF9FWFRSQUVYUEFOREVEIH0sCiAgICB7IChGY0NoYXI4ICopICJ1bHRyYWV4cGFuZGVkIiwgICJ3aWR0aCIsCUZDX1dJRFRIX1VMVFJBRVhQQU5ERUQgfSwKICAgIAogICAgeyAoRmNDaGFyOCAqKSAicHJvcG9ydGlvbmFsIiwgICAic3BhY2luZyIsICBGQ19QUk9QT1JUSU9OQUwsIH0sCiAgICB7IChGY0NoYXI4ICopICJtb25vIiwJICAgICJzcGFjaW5nIiwgIEZDX01PTk8sIH0sCiAgICB7IChGY0NoYXI4ICopICJjaGFyY2VsbCIsCSAgICAic3BhY2luZyIsICBGQ19DSEFSQ0VMTCwgfSwKCiAgICB7IChGY0NoYXI4ICopICJ1bmtub3duIiwJICAgICJyZ2JhIiwJICAgIEZDX1JHQkFfVU5LTk9XTiB9LAogICAgeyAoRmNDaGFyOCAqKSAicmdiIiwJICAgICJyZ2JhIiwJICAgIEZDX1JHQkFfUkdCLCB9LAogICAgeyAoRmNDaGFyOCAqKSAiYmdyIiwJICAgICJyZ2JhIiwJICAgIEZDX1JHQkFfQkdSLCB9LAogICAgeyAoRmNDaGFyOCAqKSAidnJnYiIsCSAgICAicmdiYSIsCSAgICBGQ19SR0JBX1ZSR0IgfSwKICAgIHsgKEZjQ2hhcjggKikgInZiZ3IiLAkgICAgInJnYmEiLAkgICAgRkNfUkdCQV9WQkdSIH0sCiAgICB7IChGY0NoYXI4ICopICJub25lIiwJICAgICJyZ2JhIiwJICAgIEZDX1JHQkFfTk9ORSB9LAp9OwoKI2RlZmluZSBOVU1fRkNfQ09OU1RBTlRTICAgKHNpemVvZiBfRmNCYXNlQ29uc3RhbnRzL3NpemVvZiBfRmNCYXNlQ29uc3RhbnRzWzBdKQoKdHlwZWRlZiBzdHJ1Y3QgX0ZjQ29uc3RhbnRMaXN0IEZjQ29uc3RhbnRMaXN0OwoKc3RydWN0IF9GY0NvbnN0YW50TGlzdCB7CiAgICBjb25zdCBGY0NvbnN0YW50TGlzdCAgICAqbmV4dDsKICAgIGNvbnN0IEZjQ29uc3RhbnQJICAgICpjb25zdHM7CiAgICBpbnQJCQkgICAgbmNvbnN0czsKfTsKCnN0YXRpYyBjb25zdCBGY0NvbnN0YW50TGlzdCBfRmNCYXNlQ29uc3RhbnRMaXN0ID0gewogICAgMCwKICAgIF9GY0Jhc2VDb25zdGFudHMsCiAgICBOVU1fRkNfQ09OU1RBTlRTCn07CgpzdGF0aWMgY29uc3QgRmNDb25zdGFudExpc3QJKl9GY0NvbnN0YW50cyA9ICZfRmNCYXNlQ29uc3RhbnRMaXN0OwoKRmNCb29sCkZjTmFtZVJlZ2lzdGVyQ29uc3RhbnRzIChjb25zdCBGY0NvbnN0YW50ICpjb25zdHMsIGludCBuY29uc3RzKQp7CiAgICBGY0NvbnN0YW50TGlzdAkqbDsKCiAgICBsID0gKEZjQ29uc3RhbnRMaXN0ICopIG1hbGxvYyAoc2l6ZW9mIChGY0NvbnN0YW50TGlzdCkpOwogICAgaWYgKCFsKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fQ09OU1RBTlQsIHNpemVvZiAoRmNDb25zdGFudExpc3QpKTsKICAgIGwtPmNvbnN0cyA9IGNvbnN0czsKICAgIGwtPm5jb25zdHMgPSBuY29uc3RzOwogICAgbC0+bmV4dCA9IF9GY0NvbnN0YW50czsKICAgIF9GY0NvbnN0YW50cyA9IGw7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNOYW1lVW5yZWdpc3RlckNvbnN0YW50cyAoY29uc3QgRmNDb25zdGFudCAqY29uc3RzLCBpbnQgbmNvbnN0cykKewogICAgY29uc3QgRmNDb25zdGFudExpc3QJKmwsICoqcHJldjsKCiAgICBmb3IgKHByZXYgPSAmX0ZjQ29uc3RhbnRzOyAKCSAobCA9ICpwcmV2KTsgCgkgcHJldiA9IChjb25zdCBGY0NvbnN0YW50TGlzdCAqKikgJihsLT5uZXh0KSkKICAgIHsKCWlmIChsLT5jb25zdHMgPT0gY29uc3RzICYmIGwtPm5jb25zdHMgPT0gbmNvbnN0cykKCXsKCSAgICAqcHJldiA9IGwtPm5leHQ7CgkgICAgRmNNZW1GcmVlIChGQ19NRU1fQ09OU1RBTlQsIHNpemVvZiAoRmNDb25zdGFudExpc3QpKTsKCSAgICBmcmVlICgodm9pZCAqKSBsKTsKCSAgICByZXR1cm4gRmNUcnVlOwoJfQogICAgfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCmNvbnN0IEZjQ29uc3RhbnQgKgpGY05hbWVHZXRDb25zdGFudCAoRmNDaGFyOCAqc3RyaW5nKQp7CiAgICBjb25zdCBGY0NvbnN0YW50TGlzdCAgICAqbDsKICAgIGludAkJCSAgICBpOwoKICAgIGZvciAobCA9IF9GY0NvbnN0YW50czsgbDsgbCA9IGwtPm5leHQpCiAgICB7Cglmb3IgKGkgPSAwOyBpIDwgbC0+bmNvbnN0czsgaSsrKQoJICAgIGlmICghRmNTdHJDbXBJZ25vcmVDYXNlIChzdHJpbmcsIGwtPmNvbnN0c1tpXS5uYW1lKSkKCQlyZXR1cm4gJmwtPmNvbnN0c1tpXTsKICAgIH0KICAgIHJldHVybiAwOwp9CgpGY0Jvb2wKRmNOYW1lQ29uc3RhbnQgKEZjQ2hhcjggKnN0cmluZywgaW50ICpyZXN1bHQpCnsKICAgIGNvbnN0IEZjQ29uc3RhbnQJKmM7CgogICAgaWYgKChjID0gRmNOYW1lR2V0Q29uc3RhbnQoc3RyaW5nKSkpCiAgICB7CgkqcmVzdWx0ID0gYy0+dmFsdWU7CglyZXR1cm4gRmNUcnVlOwogICAgfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCkZjQm9vbApGY05hbWVCb29sIChGY0NoYXI4ICp2LCBGY0Jvb2wgKnJlc3VsdCkKewogICAgY2hhciAgICBjMCwgYzE7CgogICAgYzAgPSAqdjsKICAgIGMwID0gRmNUb0xvd2VyIChjMCk7CiAgICBpZiAoYzAgPT0gJ3QnIHx8IGMwID09ICd5JyB8fCBjMCA9PSAnMScpCiAgICB7CgkqcmVzdWx0ID0gRmNUcnVlOwoJcmV0dXJuIEZjVHJ1ZTsKICAgIH0KICAgIGlmIChjMCA9PSAnZicgfHwgYzAgPT0gJ24nIHx8IGMwID09ICcwJykKICAgIHsKCSpyZXN1bHQgPSBGY0ZhbHNlOwoJcmV0dXJuIEZjVHJ1ZTsKICAgIH0KICAgIGlmIChjMCA9PSAnbycpCiAgICB7CgljMSA9IHZbMV07CgljMSA9IEZjVG9Mb3dlciAoYzEpOwoJaWYgKGMxID09ICduJykKCXsKCSAgICAqcmVzdWx0ID0gRmNUcnVlOwoJICAgIHJldHVybiBGY1RydWU7Cgl9CglpZiAoYzEgPT0gJ2YnKQoJewoJICAgICpyZXN1bHQgPSBGY0ZhbHNlOwoJICAgIHJldHVybiBGY1RydWU7Cgl9CiAgICB9CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKc3RhdGljIEZjVmFsdWUKRmNOYW1lQ29udmVydCAoRmNUeXBlIHR5cGUsIEZjQ2hhcjggKnN0cmluZywgRmNNYXRyaXggKm0pCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSB0eXBlOwogICAgc3dpdGNoICh2LnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCWlmICghRmNOYW1lQ29uc3RhbnQgKHN0cmluZywgJnYudS5pKSkKCSAgICB2LnUuaSA9IGF0b2kgKChjaGFyICopIHN0cmluZyk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJdi51LnMgPSBzdHJpbmc7CglicmVhazsKICAgIGNhc2UgRmNUeXBlQm9vbDoKCWlmICghRmNOYW1lQm9vbCAoc3RyaW5nLCAmdi51LmIpKQoJICAgIHYudS5iID0gRmNGYWxzZTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVEb3VibGU6Cgl2LnUuZCA9IHN0cnRvZCAoKGNoYXIgKikgc3RyaW5nLCAwKTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVNYXRyaXg6Cgl2LnUubSA9IG07Cglzc2NhbmYgKChjaGFyICopIHN0cmluZywgIiVsZyAlbGcgJWxnICVsZyIsICZtLT54eCwgJm0tPnh5LCAmbS0+eXgsICZtLT55eSk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCXYudS5jID0gRmNOYW1lUGFyc2VDaGFyU2V0IChzdHJpbmcpOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZUxhbmdTZXQ6Cgl2LnUubCA9IEZjTmFtZVBhcnNlTGFuZ1NldCAoc3RyaW5nKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCWJyZWFrOwogICAgfQogICAgcmV0dXJuIHY7Cn0KCnN0YXRpYyBjb25zdCBGY0NoYXI4ICoKRmNOYW1lRmluZE5leHQgKGNvbnN0IEZjQ2hhcjggKmN1ciwgY29uc3QgY2hhciAqZGVsaW0sIEZjQ2hhcjggKnNhdmUsIEZjQ2hhcjggKmxhc3QpCnsKICAgIEZjQ2hhcjggICAgYzsKICAgIAogICAgd2hpbGUgKChjID0gKmN1cikpCiAgICB7CglpZiAoYyA9PSAnXFwnKQoJewoJICAgICsrY3VyOwoJICAgIGlmICghKGMgPSAqY3VyKSkKCQlicmVhazsKCX0KCWVsc2UgaWYgKHN0cmNociAoZGVsaW0sIGMpKQoJICAgIGJyZWFrOwoJKytjdXI7Cgkqc2F2ZSsrID0gYzsKICAgIH0KICAgICpzYXZlID0gMDsKICAgICpsYXN0ID0gKmN1cjsKICAgIGlmICgqY3VyKQoJY3VyKys7CiAgICByZXR1cm4gY3VyOwp9CgpGY1BhdHRlcm4gKgpGY05hbWVQYXJzZSAoY29uc3QgRmNDaGFyOCAqbmFtZSkKewogICAgRmNDaGFyOAkJKnNhdmU7CiAgICBGY1BhdHRlcm4JCSpwYXQ7CiAgICBkb3VibGUJCWQ7CiAgICBGY0NoYXI4CQkqZTsKICAgIEZjQ2hhcjgJCWRlbGltOwogICAgRmNWYWx1ZQkJdjsKICAgIEZjTWF0cml4CQltOwogICAgY29uc3QgRmNPYmplY3RUeXBlCSp0OwogICAgY29uc3QgRmNDb25zdGFudAkqYzsKCiAgICAvKiBmcmVlZCBiZWxvdyAqLwogICAgc2F2ZSA9IG1hbGxvYyAoc3RybGVuICgoY2hhciAqKSBuYW1lKSArIDEpOwogICAgaWYgKCFzYXZlKQoJZ290byBiYWlsMDsKICAgIHBhdCA9IEZjUGF0dGVybkNyZWF0ZSAoKTsKICAgIGlmICghcGF0KQoJZ290byBiYWlsMTsKCiAgICBmb3IgKDs7KQogICAgewoJbmFtZSA9IEZjTmFtZUZpbmROZXh0IChuYW1lLCAiLSw6Iiwgc2F2ZSwgJmRlbGltKTsKCWlmIChzYXZlWzBdKQoJewoJICAgIGlmICghRmNQYXR0ZXJuQWRkU3RyaW5nIChwYXQsIEZDX0ZBTUlMWSwgc2F2ZSkpCgkJZ290byBiYWlsMjsKCX0KCWlmIChkZWxpbSAhPSAnLCcpCgkgICAgYnJlYWs7CiAgICB9CiAgICBpZiAoZGVsaW0gPT0gJy0nKQogICAgewoJZm9yICg7OykKCXsKCSAgICBuYW1lID0gRmNOYW1lRmluZE5leHQgKG5hbWUsICItLDoiLCBzYXZlLCAmZGVsaW0pOwoJICAgIGQgPSBzdHJ0b2QgKChjaGFyICopIHNhdmUsIChjaGFyICoqKSAmZSk7CgkgICAgaWYgKGUgIT0gc2F2ZSkKCSAgICB7CgkJaWYgKCFGY1BhdHRlcm5BZGREb3VibGUgKHBhdCwgRkNfU0laRSwgZCkpCgkJICAgIGdvdG8gYmFpbDI7CgkgICAgfQoJICAgIGlmIChkZWxpbSAhPSAnLCcpCgkJYnJlYWs7Cgl9CiAgICB9CiAgICB3aGlsZSAoZGVsaW0gPT0gJzonKQogICAgewoJbmFtZSA9IEZjTmFtZUZpbmROZXh0IChuYW1lLCAiPV86Iiwgc2F2ZSwgJmRlbGltKTsKCWlmIChzYXZlWzBdKQoJewoJICAgIGlmIChkZWxpbSA9PSAnPScgfHwgZGVsaW0gPT0gJ18nKQoJICAgIHsKCQl0ID0gRmNOYW1lR2V0T2JqZWN0VHlwZSAoKGNoYXIgKikgc2F2ZSk7CgkJZm9yICg7OykKCQl7CgkJICAgIG5hbWUgPSBGY05hbWVGaW5kTmV4dCAobmFtZSwgIjosIiwgc2F2ZSwgJmRlbGltKTsKCQkgICAgaWYgKHQpCgkJICAgIHsKCQkJdiA9IEZjTmFtZUNvbnZlcnQgKHQtPnR5cGUsIHNhdmUsICZtKTsKCQkJaWYgKCFGY1BhdHRlcm5BZGQgKHBhdCwgdC0+b2JqZWN0LCB2LCBGY1RydWUpKQoJCQl7CgkJCSAgICBzd2l0Y2ggKHYudHlwZSkgewoJCQkgICAgY2FzZSBGY1R5cGVDaGFyU2V0OgoJCQkJRmNDaGFyU2V0RGVzdHJveSAoKEZjQ2hhclNldCAqKSB2LnUuYyk7CgkJCQlicmVhazsKCQkJICAgIGNhc2UgRmNUeXBlTGFuZ1NldDoKCQkJCUZjTGFuZ1NldERlc3Ryb3kgKChGY0xhbmdTZXQgKikgdi51LmwpOwoJCQkJYnJlYWs7CgkJCSAgICBkZWZhdWx0OgoJCQkJYnJlYWs7CgkJCSAgICB9CgkJCSAgICBnb3RvIGJhaWwyOwoJCQl9CgkJCXN3aXRjaCAodi50eXBlKSB7CgkJCWNhc2UgRmNUeXBlQ2hhclNldDoKCQkJICAgIEZjQ2hhclNldERlc3Ryb3kgKChGY0NoYXJTZXQgKikgdi51LmMpOwoJCQkgICAgYnJlYWs7CgkJCWNhc2UgRmNUeXBlTGFuZ1NldDoKCQkJICAgIEZjTGFuZ1NldERlc3Ryb3kgKChGY0xhbmdTZXQgKikgdi51LmwpOwoJCQkgICAgYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCSAgICBicmVhazsKCQkJfQoJCSAgICB9CgkJICAgIGlmIChkZWxpbSAhPSAnLCcpCgkJCWJyZWFrOwoJCX0KCSAgICB9CgkgICAgZWxzZQoJICAgIHsKCQlpZiAoKGMgPSBGY05hbWVHZXRDb25zdGFudCAoc2F2ZSkpKQoJCXsKCQkgICAgaWYgKCFGY1BhdHRlcm5BZGRJbnRlZ2VyIChwYXQsIGMtPm9iamVjdCwgYy0+dmFsdWUpKQoJCQlnb3RvIGJhaWwyOwoJCX0KCSAgICB9Cgl9CiAgICB9CgogICAgZnJlZSAoc2F2ZSk7CiAgICByZXR1cm4gcGF0OwoKYmFpbDI6CiAgICBGY1BhdHRlcm5EZXN0cm95IChwYXQpOwpiYWlsMToKICAgIGZyZWUgKHNhdmUpOwpiYWlsMDoKICAgIHJldHVybiAwOwp9CnN0YXRpYyBGY0Jvb2wKRmNOYW1lVW5wYXJzZVN0cmluZyAoRmNTdHJCdWYJICAgICpidWYsIAoJCSAgICAgY29uc3QgRmNDaGFyOCAgKnN0cmluZywKCQkgICAgIGNvbnN0IEZjQ2hhcjggICplc2NhcGUpCnsKICAgIEZjQ2hhcjggYzsKICAgIHdoaWxlICgoYyA9ICpzdHJpbmcrKykpCiAgICB7CglpZiAoZXNjYXBlICYmIHN0cmNociAoKGNoYXIgKikgZXNjYXBlLCAoY2hhcikgYykpCgl7CgkgICAgaWYgKCFGY1N0ckJ1ZkNoYXIgKGJ1ZiwgZXNjYXBlWzBdKSkKCQlyZXR1cm4gRmNGYWxzZTsKCX0KCWlmICghRmNTdHJCdWZDaGFyIChidWYsIGMpKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY05hbWVVbnBhcnNlVmFsdWUgKEZjU3RyQnVmCSpidWYsCgkJICAgIEZjVmFsdWUJdiwKCQkgICAgRmNDaGFyOAkqZXNjYXBlKQp7CiAgICBGY0NoYXI4CXRlbXBbMTAyNF07CiAgICAKICAgIHN3aXRjaCAodi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZVZvaWQ6CglyZXR1cm4gRmNUcnVlOwogICAgY2FzZSBGY1R5cGVJbnRlZ2VyOgoJc3ByaW50ZiAoKGNoYXIgKikgdGVtcCwgIiVkIiwgdi51LmkpOwoJcmV0dXJuIEZjTmFtZVVucGFyc2VTdHJpbmcgKGJ1ZiwgdGVtcCwgMCk7CiAgICBjYXNlIEZjVHlwZURvdWJsZToKCXNwcmludGYgKChjaGFyICopIHRlbXAsICIlZyIsIHYudS5kKTsKCXJldHVybiBGY05hbWVVbnBhcnNlU3RyaW5nIChidWYsIHRlbXAsIDApOwogICAgY2FzZSBGY1R5cGVTdHJpbmc6CglyZXR1cm4gRmNOYW1lVW5wYXJzZVN0cmluZyAoYnVmLCB2LnUucywgZXNjYXBlKTsKICAgIGNhc2UgRmNUeXBlQm9vbDoKCXJldHVybiBGY05hbWVVbnBhcnNlU3RyaW5nIChidWYsIHYudS5iID8gKEZjQ2hhcjggKikgIlRydWUiIDogKEZjQ2hhcjggKikgIkZhbHNlIiwgMCk7CiAgICBjYXNlIEZjVHlwZU1hdHJpeDoKCXNwcmludGYgKChjaGFyICopIHRlbXAsICIlZyAlZyAlZyAlZyIsIAoJCSB2LnUubS0+eHgsIHYudS5tLT54eSwgdi51Lm0tPnl4LCB2LnUubS0+eXkpOwoJcmV0dXJuIEZjTmFtZVVucGFyc2VTdHJpbmcgKGJ1ZiwgdGVtcCwgMCk7CiAgICBjYXNlIEZjVHlwZUNoYXJTZXQ6CglyZXR1cm4gRmNOYW1lVW5wYXJzZUNoYXJTZXQgKGJ1Ziwgdi51LmMpOwogICAgY2FzZSBGY1R5cGVMYW5nU2V0OgoJcmV0dXJuIEZjTmFtZVVucGFyc2VMYW5nU2V0IChidWYsIHYudS5sKTsKICAgIGNhc2UgRmNUeXBlRlRGYWNlOgoJcmV0dXJuIEZjVHJ1ZTsKICAgIH0KICAgIHJldHVybiBGY0ZhbHNlOwp9CgpzdGF0aWMgRmNCb29sCkZjTmFtZVVucGFyc2VWYWx1ZUxpc3QgKEZjU3RyQnVmCSpidWYsCgkJCUZjVmFsdWVMaXN0CSp2LAoJCQlGY0NoYXI4CQkqZXNjYXBlKQp7CiAgICB3aGlsZSAodikKICAgIHsKCWlmICghRmNOYW1lVW5wYXJzZVZhbHVlIChidWYsIHYtPnZhbHVlLCBlc2NhcGUpKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJaWYgKCh2ID0gdi0+bmV4dCkpCgkgICAgaWYgKCFGY05hbWVVbnBhcnNlU3RyaW5nIChidWYsIChGY0NoYXI4ICopICIsIiwgMCkpCgkJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgojZGVmaW5lIEZDX0VTQ0FQRV9GSVhFRCAgICAiXFwtOiwiCiNkZWZpbmUgRkNfRVNDQVBFX1ZBUklBQkxFICJcXD1fOiwiCgpGY0NoYXI4ICoKRmNOYW1lVW5wYXJzZSAoRmNQYXR0ZXJuICpwYXQpCnsKICAgIEZjU3RyQnVmCQkgICAgYnVmOwogICAgRmNDaGFyOAkJICAgIGJ1Zl9zdGF0aWNbODE5Ml07CiAgICBpbnQJCQkgICAgaTsKICAgIEZjUGF0dGVybkVsdAkgICAgKmU7CiAgICBjb25zdCBGY09iamVjdFR5cGVMaXN0ICAqbDsKICAgIGNvbnN0IEZjT2JqZWN0VHlwZQkgICAgKm87CgogICAgRmNTdHJCdWZJbml0ICgmYnVmLCBidWZfc3RhdGljLCBzaXplb2YgKGJ1Zl9zdGF0aWMpKTsKICAgIGUgPSBGY1BhdHRlcm5GaW5kRWx0IChwYXQsIEZDX0ZBTUlMWSk7CiAgICBpZiAoZSkKICAgIHsKCWlmICghRmNOYW1lVW5wYXJzZVZhbHVlTGlzdCAoJmJ1ZiwgZS0+dmFsdWVzLCAoRmNDaGFyOCAqKSBGQ19FU0NBUEVfRklYRUQpKQoJICAgIGdvdG8gYmFpbDA7CiAgICB9CiAgICBlID0gRmNQYXR0ZXJuRmluZEVsdCAocGF0LCBGQ19TSVpFKTsKICAgIGlmIChlKQogICAgewoJaWYgKCFGY05hbWVVbnBhcnNlU3RyaW5nICgmYnVmLCAoRmNDaGFyOCAqKSAiLSIsIDApKQoJICAgIGdvdG8gYmFpbDA7CglpZiAoIUZjTmFtZVVucGFyc2VWYWx1ZUxpc3QgKCZidWYsIGUtPnZhbHVlcywgKEZjQ2hhcjggKikgRkNfRVNDQVBFX0ZJWEVEKSkKCSAgICBnb3RvIGJhaWwwOwogICAgfQogICAgZm9yIChsID0gX0ZjT2JqZWN0VHlwZXM7IGw7IGwgPSBsLT5uZXh0KQogICAgewoJZm9yIChpID0gMDsgaSA8IGwtPm50eXBlczsgaSsrKQoJewoJICAgIG8gPSAmbC0+dHlwZXNbaV07CgkgICAgaWYgKCFzdHJjbXAgKG8tPm9iamVjdCwgRkNfRkFNSUxZKSB8fCAKCQkhc3RyY21wIChvLT5vYmplY3QsIEZDX1NJWkUpIHx8CgkJIXN0cmNtcCAoby0+b2JqZWN0LCBGQ19GSUxFKSkKCQljb250aW51ZTsKCSAgICAKCSAgICBlID0gRmNQYXR0ZXJuRmluZEVsdCAocGF0LCBvLT5vYmplY3QpOwoJICAgIGlmIChlKQoJICAgIHsKCQlpZiAoIUZjTmFtZVVucGFyc2VTdHJpbmcgKCZidWYsIChGY0NoYXI4ICopICI6IiwgMCkpCgkJICAgIGdvdG8gYmFpbDA7CgkJaWYgKCFGY05hbWVVbnBhcnNlU3RyaW5nICgmYnVmLCAoRmNDaGFyOCAqKSBvLT5vYmplY3QsIChGY0NoYXI4ICopIEZDX0VTQ0FQRV9WQVJJQUJMRSkpCgkJICAgIGdvdG8gYmFpbDA7CgkJaWYgKCFGY05hbWVVbnBhcnNlU3RyaW5nICgmYnVmLCAoRmNDaGFyOCAqKSAiPSIsIDApKQoJCSAgICBnb3RvIGJhaWwwOwoJCWlmICghRmNOYW1lVW5wYXJzZVZhbHVlTGlzdCAoJmJ1ZiwgZS0+dmFsdWVzLCAKCQkJCQkgICAgIChGY0NoYXI4ICopIEZDX0VTQ0FQRV9WQVJJQUJMRSkpCgkJICAgIGdvdG8gYmFpbDA7CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuIEZjU3RyQnVmRG9uZSAoJmJ1Zik7CmJhaWwwOgogICAgRmNTdHJCdWZEZXN0cm95ICgmYnVmKTsKICAgIHJldHVybiAwOwp9Cg==