LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY25hbWUuYyx2IDEuMTIgMjAwMi8wOC8xOSAxOTozMjowNSBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMCBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgImZjaW50LmgiCgpzdGF0aWMgY29uc3QgRmNPYmplY3RUeXBlIF9GY0Jhc2VPYmplY3RUeXBlc1tdID0gewogICAgeyBGQ19GQU1JTFksCUZjVHlwZVN0cmluZywgfSwKICAgIHsgRkNfU1RZTEUsCQlGY1R5cGVTdHJpbmcsIH0sCiAgICB7IEZDX1NMQU5ULAkJRmNUeXBlSW50ZWdlciwgfSwKICAgIHsgRkNfV0VJR0hULAlGY1R5cGVJbnRlZ2VyLCB9LAogICAgeyBGQ19TSVpFLAkJRmNUeXBlRG91YmxlLCB9LAogICAgeyBGQ19BU1BFQ1QsCUZjVHlwZURvdWJsZSwgfSwKICAgIHsgRkNfUElYRUxfU0laRSwJRmNUeXBlRG91YmxlLCB9LAogICAgeyBGQ19TUEFDSU5HLAlGY1R5cGVJbnRlZ2VyLCB9LAogICAgeyBGQ19GT1VORFJZLAlGY1R5cGVTdHJpbmcsIH0sCi8qICAgIHsgRkNfQ09SRSwJCUZjVHlwZUJvb2wsIH0sICovCiAgICB7IEZDX0FOVElBTElBUywJRmNUeXBlQm9vbCwgfSwKICAgIHsgRkNfSElOVElORywJRmNUeXBlQm9vbCwgfSwKICAgIHsgRkNfVkVSVElDQUxfTEFZT1VULCAgIEZjVHlwZUJvb2wsIH0sCiAgICB7IEZDX0FVVE9ISU5ULAlGY1R5cGVCb29sLCB9LAogICAgeyBGQ19HTE9CQUxfQURWQU5DRSwgICAgRmNUeXBlQm9vbCwgfSwKLyogICAgeyBGQ19YTEZELAkJRmNUeXBlU3RyaW5nLCB9LCAqLwogICAgeyBGQ19GSUxFLAkJRmNUeXBlU3RyaW5nLCB9LAogICAgeyBGQ19JTkRFWCwJCUZjVHlwZUludGVnZXIsIH0sCiAgICB7IEZDX1JBU1RFUklaRVIsCUZjVHlwZVN0cmluZywgfSwKICAgIHsgRkNfT1VUTElORSwJRmNUeXBlQm9vbCwgfSwKICAgIHsgRkNfU0NBTEFCTEUsCUZjVHlwZUJvb2wsIH0sCiAgICB7IEZDX0RQSSwJCUZjVHlwZURvdWJsZSB9LAogICAgeyBGQ19SR0JBLAkJRmNUeXBlSW50ZWdlciwgfSwKICAgIHsgRkNfU0NBTEUsCQlGY1R5cGVEb3VibGUsIH0sCi8qICAgIHsgRkNfUkVOREVSLAlGY1R5cGVCb29sLCB9LCovCiAgICB7IEZDX01JTlNQQUNFLAlGY1R5cGVCb29sLCB9LAogICAgeyBGQ19DSEFSX1dJRFRILAlGY1R5cGVJbnRlZ2VyIH0sCiAgICB7IEZDX0NIQVJfSEVJR0hULAlGY1R5cGVJbnRlZ2VyIH0sCiAgICB7IEZDX01BVFJJWCwJRmNUeXBlTWF0cml4IH0sCiAgICB7IEZDX0NIQVJTRVQsCUZjVHlwZUNoYXJTZXQgfSwKICAgIHsgRkNfTEFORywJCUZjVHlwZUxhbmdTZXQgfSwKfTsKCiNkZWZpbmUgTlVNX09CSkVDVF9UWVBFUyAgICAoc2l6ZW9mIF9GY0Jhc2VPYmplY3RUeXBlcyAvIHNpemVvZiBfRmNCYXNlT2JqZWN0VHlwZXNbMF0pCgp0eXBlZGVmIHN0cnVjdCBfRmNPYmplY3RUeXBlTGlzdCAgICBGY09iamVjdFR5cGVMaXN0OwoKc3RydWN0IF9GY09iamVjdFR5cGVMaXN0IHsKICAgIGNvbnN0IEZjT2JqZWN0VHlwZUxpc3QgICpuZXh0OwogICAgY29uc3QgRmNPYmplY3RUeXBlCSAgICAqdHlwZXM7CiAgICBpbnQJCQkgICAgbnR5cGVzOwp9OwoKc3RhdGljIGNvbnN0IEZjT2JqZWN0VHlwZUxpc3QgX0ZjQmFzZU9iamVjdFR5cGVzTGlzdCA9IHsKICAgIDAsCiAgICBfRmNCYXNlT2JqZWN0VHlwZXMsCiAgICBOVU1fT0JKRUNUX1RZUEVTCn07CgpzdGF0aWMgY29uc3QgRmNPYmplY3RUeXBlTGlzdAkqX0ZjT2JqZWN0VHlwZXMgPSAmX0ZjQmFzZU9iamVjdFR5cGVzTGlzdDsKCkZjQm9vbApGY05hbWVSZWdpc3Rlck9iamVjdFR5cGVzIChjb25zdCBGY09iamVjdFR5cGUgKnR5cGVzLCBpbnQgbnR5cGVzKQp7CiAgICBGY09iamVjdFR5cGVMaXN0CSpsOwoKICAgIGwgPSAoRmNPYmplY3RUeXBlTGlzdCAqKSBtYWxsb2MgKHNpemVvZiAoRmNPYmplY3RUeXBlTGlzdCkpOwogICAgaWYgKCFsKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBsLT50eXBlcyA9IHR5cGVzOwogICAgbC0+bnR5cGVzID0gbnR5cGVzOwogICAgbC0+bmV4dCA9IF9GY09iamVjdFR5cGVzOwogICAgX0ZjT2JqZWN0VHlwZXMgPSBsOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjTmFtZVVucmVnaXN0ZXJPYmplY3RUeXBlcyAoY29uc3QgRmNPYmplY3RUeXBlICp0eXBlcywgaW50IG50eXBlcykKewogICAgY29uc3QgRmNPYmplY3RUeXBlTGlzdAkqbCwgKipwcmV2OwoKICAgIGZvciAocHJldiA9ICZfRmNPYmplY3RUeXBlczsgCgkgKGwgPSAqcHJldik7IAoJIHByZXYgPSAoY29uc3QgRmNPYmplY3RUeXBlTGlzdCAqKikgJihsLT5uZXh0KSkKICAgIHsKCWlmIChsLT50eXBlcyA9PSB0eXBlcyAmJiBsLT5udHlwZXMgPT0gbnR5cGVzKQoJewoJICAgICpwcmV2ID0gbC0+bmV4dDsKCSAgICBmcmVlICgodm9pZCAqKSBsKTsKCSAgICByZXR1cm4gRmNUcnVlOwoJfQogICAgfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCmNvbnN0IEZjT2JqZWN0VHlwZSAqCkZjTmFtZUdldE9iamVjdFR5cGUgKGNvbnN0IGNoYXIgKm9iamVjdCkKewogICAgaW50CQkJICAgIGk7CiAgICBjb25zdCBGY09iamVjdFR5cGVMaXN0ICAqbDsKICAgIGNvbnN0IEZjT2JqZWN0VHlwZQkgICAgKnQ7CiAgICAKICAgIGZvciAobCA9IF9GY09iamVjdFR5cGVzOyBsOyBsID0gbC0+bmV4dCkKICAgIHsKCWZvciAoaSA9IDA7IGkgPCBsLT5udHlwZXM7IGkrKykKCXsKCSAgICB0ID0gJmwtPnR5cGVzW2ldOwoJICAgIGlmICghc3RyY21wIChvYmplY3QsIHQtPm9iamVjdCkpCgkJcmV0dXJuIHQ7Cgl9CiAgICB9CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGNvbnN0IEZjQ29uc3RhbnQgX0ZjQmFzZUNvbnN0YW50c1tdID0gewogICAgeyAoRmNDaGFyOCAqKSAibGlnaHQiLAkgICAgIndlaWdodCIsICAgRkNfV0VJR0hUX0xJR0hULCB9LAogICAgeyAoRmNDaGFyOCAqKSAibWVkaXVtIiwJICAgICJ3ZWlnaHQiLCAgIEZDX1dFSUdIVF9NRURJVU0sIH0sCiAgICB7IChGY0NoYXI4ICopICJkZW1pYm9sZCIsCSAgICAid2VpZ2h0IiwgICBGQ19XRUlHSFRfREVNSUJPTEQsIH0sCiAgICB7IChGY0NoYXI4ICopICJib2xkIiwJICAgICJ3ZWlnaHQiLCAgIEZDX1dFSUdIVF9CT0xELCB9LAogICAgeyAoRmNDaGFyOCAqKSAiYmxhY2siLAkgICAgIndlaWdodCIsICAgRkNfV0VJR0hUX0JMQUNLLCB9LAoKICAgIHsgKEZjQ2hhcjggKikgInJvbWFuIiwJICAgICJzbGFudCIsICAgIEZDX1NMQU5UX1JPTUFOLCB9LAogICAgeyAoRmNDaGFyOCAqKSAiaXRhbGljIiwJICAgICJzbGFudCIsICAgIEZDX1NMQU5UX0lUQUxJQywgfSwKICAgIHsgKEZjQ2hhcjggKikgIm9ibGlxdWUiLAkgICAgInNsYW50IiwgICAgRkNfU0xBTlRfT0JMSVFVRSwgfSwKCiAgICB7IChGY0NoYXI4ICopICJwcm9wb3J0aW9uYWwiLCAgICJzcGFjaW5nIiwgIEZDX1BST1BPUlRJT05BTCwgfSwKICAgIHsgKEZjQ2hhcjggKikgIm1vbm8iLAkgICAgInNwYWNpbmciLCAgRkNfTU9OTywgfSwKICAgIHsgKEZjQ2hhcjggKikgImNoYXJjZWxsIiwJICAgICJzcGFjaW5nIiwgIEZDX0NIQVJDRUxMLCB9LAoKICAgIHsgKEZjQ2hhcjggKikgIm5vbmUiLAkgICAgInJnYmEiLAkgICAgRkNfUkdCQV9OT05FIH0sCiAgICB7IChGY0NoYXI4ICopICJyZ2IiLAkgICAgInJnYmEiLAkgICAgRkNfUkdCQV9SR0IsIH0sCiAgICB7IChGY0NoYXI4ICopICJiZ3IiLAkgICAgInJnYmEiLAkgICAgRkNfUkdCQV9CR1IsIH0sCiAgICB7IChGY0NoYXI4ICopICJ2cmdiIiwJICAgICJyZ2JhIiwJICAgIEZDX1JHQkFfVlJHQiB9LAogICAgeyAoRmNDaGFyOCAqKSAidmJnciIsCSAgICAicmdiYSIsCSAgICBGQ19SR0JBX1ZCR1IgfSwKfTsKCiNkZWZpbmUgTlVNX0ZDX0NPTlNUQU5UUyAgIChzaXplb2YgX0ZjQmFzZUNvbnN0YW50cy9zaXplb2YgX0ZjQmFzZUNvbnN0YW50c1swXSkKCnR5cGVkZWYgc3RydWN0IF9GY0NvbnN0YW50TGlzdCBGY0NvbnN0YW50TGlzdDsKCnN0cnVjdCBfRmNDb25zdGFudExpc3QgewogICAgY29uc3QgRmNDb25zdGFudExpc3QgICAgKm5leHQ7CiAgICBjb25zdCBGY0NvbnN0YW50CSAgICAqY29uc3RzOwogICAgaW50CQkJICAgIG5jb25zdHM7Cn07CgpzdGF0aWMgY29uc3QgRmNDb25zdGFudExpc3QgX0ZjQmFzZUNvbnN0YW50TGlzdCA9IHsKICAgIDAsCiAgICBfRmNCYXNlQ29uc3RhbnRzLAogICAgTlVNX0ZDX0NPTlNUQU5UUwp9OwoKc3RhdGljIGNvbnN0IEZjQ29uc3RhbnRMaXN0CSpfRmNDb25zdGFudHMgPSAmX0ZjQmFzZUNvbnN0YW50TGlzdDsKCkZjQm9vbApGY05hbWVSZWdpc3RlckNvbnN0YW50cyAoY29uc3QgRmNDb25zdGFudCAqY29uc3RzLCBpbnQgbmNvbnN0cykKewogICAgRmNDb25zdGFudExpc3QJKmw7CgogICAgbCA9IChGY0NvbnN0YW50TGlzdCAqKSBtYWxsb2MgKHNpemVvZiAoRmNDb25zdGFudExpc3QpKTsKICAgIGlmICghbCkKCXJldHVybiBGY0ZhbHNlOwogICAgbC0+Y29uc3RzID0gY29uc3RzOwogICAgbC0+bmNvbnN0cyA9IG5jb25zdHM7CiAgICBsLT5uZXh0ID0gX0ZjQ29uc3RhbnRzOwogICAgX0ZjQ29uc3RhbnRzID0gbDsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY05hbWVVbnJlZ2lzdGVyQ29uc3RhbnRzIChjb25zdCBGY0NvbnN0YW50ICpjb25zdHMsIGludCBuY29uc3RzKQp7CiAgICBjb25zdCBGY0NvbnN0YW50TGlzdAkqbCwgKipwcmV2OwoKICAgIGZvciAocHJldiA9ICZfRmNDb25zdGFudHM7IAoJIChsID0gKnByZXYpOyAKCSBwcmV2ID0gKGNvbnN0IEZjQ29uc3RhbnRMaXN0ICoqKSAmKGwtPm5leHQpKQogICAgewoJaWYgKGwtPmNvbnN0cyA9PSBjb25zdHMgJiYgbC0+bmNvbnN0cyA9PSBuY29uc3RzKQoJewoJICAgICpwcmV2ID0gbC0+bmV4dDsKCSAgICBmcmVlICgodm9pZCAqKSBsKTsKCSAgICByZXR1cm4gRmNUcnVlOwoJfQogICAgfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCmNvbnN0IEZjQ29uc3RhbnQgKgpGY05hbWVHZXRDb25zdGFudCAoRmNDaGFyOCAqc3RyaW5nKQp7CiAgICBjb25zdCBGY0NvbnN0YW50TGlzdCAgICAqbDsKICAgIGludAkJCSAgICBpOwogICAgCiAgICBmb3IgKGwgPSBfRmNDb25zdGFudHM7IGw7IGwgPSBsLT5uZXh0KQogICAgewoJZm9yIChpID0gMDsgaSA8IGwtPm5jb25zdHM7IGkrKykKCSAgICBpZiAoIUZjU3RyQ21wSWdub3JlQ2FzZSAoc3RyaW5nLCBsLT5jb25zdHNbaV0ubmFtZSkpCgkJcmV0dXJuICZsLT5jb25zdHNbaV07CiAgICB9CiAgICByZXR1cm4gMDsKfQoKRmNCb29sCkZjTmFtZUNvbnN0YW50IChGY0NoYXI4ICpzdHJpbmcsIGludCAqcmVzdWx0KQp7CiAgICBjb25zdCBGY0NvbnN0YW50CSpjOwoKICAgIGlmICgoYyA9IEZjTmFtZUdldENvbnN0YW50KHN0cmluZykpKQogICAgewoJKnJlc3VsdCA9IGMtPnZhbHVlOwoJcmV0dXJuIEZjVHJ1ZTsKICAgIH0KICAgIHJldHVybiBGY0ZhbHNlOwp9CgpGY0Jvb2wKRmNOYW1lQm9vbCAoRmNDaGFyOCAqdiwgRmNCb29sICpyZXN1bHQpCnsKICAgIGNoYXIgICAgYzAsIGMxOwoKICAgIGMwID0gKnY7CiAgICBpZiAoaXN1cHBlciAoYzApKQoJYzAgPSB0b2xvd2VyIChjMCk7CiAgICBpZiAoYzAgPT0gJ3QnIHx8IGMwID09ICd5JyB8fCBjMCA9PSAnMScpCiAgICB7CgkqcmVzdWx0ID0gRmNUcnVlOwoJcmV0dXJuIEZjVHJ1ZTsKICAgIH0KICAgIGlmIChjMCA9PSAnZicgfHwgYzAgPT0gJ24nIHx8IGMwID09ICcwJykKICAgIHsKCSpyZXN1bHQgPSBGY0ZhbHNlOwoJcmV0dXJuIEZjVHJ1ZTsKICAgIH0KICAgIGlmIChjMCA9PSAnbycpCiAgICB7CgljMSA9IHZbMV07CglpZiAoaXN1cHBlciAoYzEpKQoJICAgIGMxID0gdG9sb3dlciAoYzEpOwoJaWYgKGMxID09ICduJykKCXsKCSAgICAqcmVzdWx0ID0gRmNUcnVlOwoJICAgIHJldHVybiBGY1RydWU7Cgl9CglpZiAoYzEgPT0gJ2YnKQoJewoJICAgICpyZXN1bHQgPSBGY0ZhbHNlOwoJICAgIHJldHVybiBGY1RydWU7Cgl9CiAgICB9CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKc3RhdGljIEZjVmFsdWUKRmNOYW1lQ29udmVydCAoRmNUeXBlIHR5cGUsIEZjQ2hhcjggKnN0cmluZywgRmNNYXRyaXggKm0pCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSB0eXBlOwogICAgc3dpdGNoICh2LnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCWlmICghRmNOYW1lQ29uc3RhbnQgKHN0cmluZywgJnYudS5pKSkKCSAgICB2LnUuaSA9IGF0b2kgKChjaGFyICopIHN0cmluZyk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJdi51LnMgPSBzdHJpbmc7CglicmVhazsKICAgIGNhc2UgRmNUeXBlQm9vbDoKCWlmICghRmNOYW1lQm9vbCAoc3RyaW5nLCAmdi51LmIpKQoJICAgIHYudS5iID0gRmNGYWxzZTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVEb3VibGU6Cgl2LnUuZCA9IHN0cnRvZCAoKGNoYXIgKikgc3RyaW5nLCAwKTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVNYXRyaXg6Cgl2LnUubSA9IG07Cglzc2NhbmYgKChjaGFyICopIHN0cmluZywgIiVsZyAlbGcgJWxnICVsZyIsICZtLT54eCwgJm0tPnh5LCAmbS0+eXgsICZtLT55eSk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCXYudS5jID0gRmNOYW1lUGFyc2VDaGFyU2V0IChzdHJpbmcpOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZUxhbmdTZXQ6Cgl2LnUubCA9IEZjTmFtZVBhcnNlTGFuZ1NldCAoc3RyaW5nKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCWJyZWFrOwogICAgfQogICAgcmV0dXJuIHY7Cn0KCnN0YXRpYyBjb25zdCBGY0NoYXI4ICoKRmNOYW1lRmluZE5leHQgKGNvbnN0IEZjQ2hhcjggKmN1ciwgY29uc3QgY2hhciAqZGVsaW0sIEZjQ2hhcjggKnNhdmUsIEZjQ2hhcjggKmxhc3QpCnsKICAgIEZjQ2hhcjggICAgYzsKICAgIAogICAgd2hpbGUgKChjID0gKmN1cikpCiAgICB7CglpZiAoYyA9PSAnXFwnKQoJewoJICAgICsrY3VyOwoJICAgIGlmICghKGMgPSAqY3VyKSkKCQlicmVhazsKCX0KCWVsc2UgaWYgKHN0cmNociAoZGVsaW0sIGMpKQoJICAgIGJyZWFrOwoJKytjdXI7Cgkqc2F2ZSsrID0gYzsKICAgIH0KICAgICpzYXZlID0gMDsKICAgICpsYXN0ID0gKmN1cjsKICAgIGlmICgqY3VyKQoJY3VyKys7CiAgICByZXR1cm4gY3VyOwp9CgpGY1BhdHRlcm4gKgpGY05hbWVQYXJzZSAoY29uc3QgRmNDaGFyOCAqbmFtZSkKewogICAgRmNDaGFyOAkJKnNhdmU7CiAgICBGY1BhdHRlcm4JCSpwYXQ7CiAgICBkb3VibGUJCWQ7CiAgICBGY0NoYXI4CQkqZTsKICAgIEZjQ2hhcjgJCWRlbGltOwogICAgRmNWYWx1ZQkJdjsKICAgIEZjTWF0cml4CQltOwogICAgY29uc3QgRmNPYmplY3RUeXBlCSp0OwogICAgY29uc3QgRmNDb25zdGFudAkqYzsKCiAgICBzYXZlID0gbWFsbG9jIChzdHJsZW4gKChjaGFyICopIG5hbWUpICsgMSk7CiAgICBpZiAoIXNhdmUpCglnb3RvIGJhaWwwOwogICAgcGF0ID0gRmNQYXR0ZXJuQ3JlYXRlICgpOwogICAgaWYgKCFwYXQpCglnb3RvIGJhaWwxOwoKICAgIGZvciAoOzspCiAgICB7CgluYW1lID0gRmNOYW1lRmluZE5leHQgKG5hbWUsICItLDoiLCBzYXZlLCAmZGVsaW0pOwoJaWYgKHNhdmVbMF0pCgl7CgkgICAgaWYgKCFGY1BhdHRlcm5BZGRTdHJpbmcgKHBhdCwgRkNfRkFNSUxZLCBzYXZlKSkKCQlnb3RvIGJhaWwyOwoJfQoJaWYgKGRlbGltICE9ICcsJykKCSAgICBicmVhazsKICAgIH0KICAgIGlmIChkZWxpbSA9PSAnLScpCiAgICB7Cglmb3IgKDs7KQoJewoJICAgIG5hbWUgPSBGY05hbWVGaW5kTmV4dCAobmFtZSwgIi0sOiIsIHNhdmUsICZkZWxpbSk7CgkgICAgZCA9IHN0cnRvZCAoKGNoYXIgKikgc2F2ZSwgKGNoYXIgKiopICZlKTsKCSAgICBpZiAoZSAhPSBzYXZlKQoJICAgIHsKCQlpZiAoIUZjUGF0dGVybkFkZERvdWJsZSAocGF0LCBGQ19TSVpFLCBkKSkKCQkgICAgZ290byBiYWlsMjsKCSAgICB9CgkgICAgaWYgKGRlbGltICE9ICcsJykKCQlicmVhazsKCX0KICAgIH0KICAgIHdoaWxlIChkZWxpbSA9PSAnOicpCiAgICB7CgluYW1lID0gRmNOYW1lRmluZE5leHQgKG5hbWUsICI9XzoiLCBzYXZlLCAmZGVsaW0pOwoJaWYgKHNhdmVbMF0pCgl7CgkgICAgaWYgKGRlbGltID09ICc9JyB8fCBkZWxpbSA9PSAnXycpCgkgICAgewoJCXQgPSBGY05hbWVHZXRPYmplY3RUeXBlICgoY2hhciAqKSBzYXZlKTsKCQlmb3IgKDs7KQoJCXsKCQkgICAgbmFtZSA9IEZjTmFtZUZpbmROZXh0IChuYW1lLCAiOiwiLCBzYXZlLCAmZGVsaW0pOwoJCSAgICBpZiAodCkKCQkgICAgewoJCQl2ID0gRmNOYW1lQ29udmVydCAodC0+dHlwZSwgc2F2ZSwgJm0pOwoJCQlpZiAoIUZjUGF0dGVybkFkZCAocGF0LCB0LT5vYmplY3QsIHYsIEZjVHJ1ZSkpCgkJCXsKCQkJICAgIHN3aXRjaCAodi50eXBlKSB7CgkJCSAgICBjYXNlIEZjVHlwZUNoYXJTZXQ6CgkJCQlGY0NoYXJTZXREZXN0cm95ICgoRmNDaGFyU2V0ICopIHYudS5jKTsKCQkJCWJyZWFrOwoJCQkgICAgY2FzZSBGY1R5cGVMYW5nU2V0OgoJCQkJRmNMYW5nU2V0RGVzdHJveSAoKEZjTGFuZ1NldCAqKSB2LnUubCk7CgkJCQlicmVhazsKCQkJICAgIGRlZmF1bHQ6CgkJCQlicmVhazsKCQkJICAgIH0KCQkJICAgIGdvdG8gYmFpbDI7CgkJCX0KCQkJc3dpdGNoICh2LnR5cGUpIHsKCQkJY2FzZSBGY1R5cGVDaGFyU2V0OgoJCQkgICAgRmNDaGFyU2V0RGVzdHJveSAoKEZjQ2hhclNldCAqKSB2LnUuYyk7CgkJCSAgICBicmVhazsKCQkJY2FzZSBGY1R5cGVMYW5nU2V0OgoJCQkgICAgRmNMYW5nU2V0RGVzdHJveSAoKEZjTGFuZ1NldCAqKSB2LnUubCk7CgkJCSAgICBicmVhazsKCQkJZGVmYXVsdDoKCQkJICAgIGJyZWFrOwoJCQl9CgkJICAgIH0KCQkgICAgaWYgKGRlbGltICE9ICcsJykKCQkJYnJlYWs7CgkJfQoJICAgIH0KCSAgICBlbHNlCgkgICAgewoJCWlmICgoYyA9IEZjTmFtZUdldENvbnN0YW50IChzYXZlKSkpCgkJewoJCSAgICBpZiAoIUZjUGF0dGVybkFkZEludGVnZXIgKHBhdCwgYy0+b2JqZWN0LCBjLT52YWx1ZSkpCgkJCWdvdG8gYmFpbDI7CgkJfQoJICAgIH0KCX0KICAgIH0KCiAgICBmcmVlIChzYXZlKTsKICAgIHJldHVybiBwYXQ7CgpiYWlsMjoKICAgIEZjUGF0dGVybkRlc3Ryb3kgKHBhdCk7CmJhaWwxOgogICAgZnJlZSAoc2F2ZSk7CmJhaWwwOgogICAgcmV0dXJuIDA7Cn0Kc3RhdGljIEZjQm9vbApGY05hbWVVbnBhcnNlU3RyaW5nIChGY1N0ckJ1ZgkgICAgKmJ1ZiwgCgkJICAgICBjb25zdCBGY0NoYXI4ICAqc3RyaW5nLAoJCSAgICAgY29uc3QgRmNDaGFyOCAgKmVzY2FwZSkKewogICAgRmNDaGFyOCBjOwogICAgd2hpbGUgKChjID0gKnN0cmluZysrKSkKICAgIHsKCWlmIChlc2NhcGUgJiYgc3RyY2hyICgoY2hhciAqKSBlc2NhcGUsIChjaGFyKSBjKSkKCXsKCSAgICBpZiAoIUZjU3RyQnVmQ2hhciAoYnVmLCBlc2NhcGVbMF0pKQoJCXJldHVybiBGY0ZhbHNlOwoJfQoJaWYgKCFGY1N0ckJ1ZkNoYXIgKGJ1ZiwgYykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjTmFtZVVucGFyc2VWYWx1ZSAoRmNTdHJCdWYJKmJ1ZiwKCQkgICAgRmNWYWx1ZQl2LAoJCSAgICBGY0NoYXI4CSplc2NhcGUpCnsKICAgIEZjQ2hhcjgJdGVtcFsxMDI0XTsKICAgIAogICAgc3dpdGNoICh2LnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlVm9pZDoKCXJldHVybiBGY1RydWU7CiAgICBjYXNlIEZjVHlwZUludGVnZXI6CglzcHJpbnRmICgoY2hhciAqKSB0ZW1wLCAiJWQiLCB2LnUuaSk7CglyZXR1cm4gRmNOYW1lVW5wYXJzZVN0cmluZyAoYnVmLCB0ZW1wLCAwKTsKICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJc3ByaW50ZiAoKGNoYXIgKikgdGVtcCwgIiVnIiwgdi51LmQpOwoJcmV0dXJuIEZjTmFtZVVucGFyc2VTdHJpbmcgKGJ1ZiwgdGVtcCwgMCk7CiAgICBjYXNlIEZjVHlwZVN0cmluZzoKCXJldHVybiBGY05hbWVVbnBhcnNlU3RyaW5nIChidWYsIHYudS5zLCBlc2NhcGUpOwogICAgY2FzZSBGY1R5cGVCb29sOgoJcmV0dXJuIEZjTmFtZVVucGFyc2VTdHJpbmcgKGJ1Ziwgdi51LmIgPyAoRmNDaGFyOCAqKSAiVHJ1ZSIgOiAoRmNDaGFyOCAqKSAiRmFsc2UiLCAwKTsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJc3ByaW50ZiAoKGNoYXIgKikgdGVtcCwgIiVnICVnICVnICVnIiwgCgkJIHYudS5tLT54eCwgdi51Lm0tPnh5LCB2LnUubS0+eXgsIHYudS5tLT55eSk7CglyZXR1cm4gRmNOYW1lVW5wYXJzZVN0cmluZyAoYnVmLCB0ZW1wLCAwKTsKICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCXJldHVybiBGY05hbWVVbnBhcnNlQ2hhclNldCAoYnVmLCB2LnUuYyk7CiAgICBjYXNlIEZjVHlwZUxhbmdTZXQ6CglyZXR1cm4gRmNOYW1lVW5wYXJzZUxhbmdTZXQgKGJ1Ziwgdi51LmwpOwogICAgY2FzZSBGY1R5cGVGVEZhY2U6CglyZXR1cm4gRmNUcnVlOwogICAgfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNOYW1lVW5wYXJzZVZhbHVlTGlzdCAoRmNTdHJCdWYJKmJ1ZiwKCQkJRmNWYWx1ZUxpc3QJKnYsCgkJCUZjQ2hhcjgJCSplc2NhcGUpCnsKICAgIHdoaWxlICh2KQogICAgewoJaWYgKCFGY05hbWVVbnBhcnNlVmFsdWUgKGJ1Ziwgdi0+dmFsdWUsIGVzY2FwZSkpCgkgICAgcmV0dXJuIEZjRmFsc2U7CglpZiAoKHYgPSB2LT5uZXh0KSkKCSAgICBpZiAoIUZjTmFtZVVucGFyc2VTdHJpbmcgKGJ1ZiwgKEZjQ2hhcjggKikgIiwiLCAwKSkKCQlyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCiNkZWZpbmUgRkNfRVNDQVBFX0ZJWEVEICAgICJcXC06LCIKI2RlZmluZSBGQ19FU0NBUEVfVkFSSUFCTEUgIlxcPV86LCIKCkZjQ2hhcjggKgpGY05hbWVVbnBhcnNlIChGY1BhdHRlcm4gKnBhdCkKewogICAgRmNTdHJCdWYJCSAgICBidWY7CiAgICBGY0NoYXI4CQkgICAgYnVmX3N0YXRpY1s4MTkyXTsKICAgIGludAkJCSAgICBpOwogICAgRmNQYXR0ZXJuRWx0CSAgICAqZTsKICAgIGNvbnN0IEZjT2JqZWN0VHlwZUxpc3QgICpsOwogICAgY29uc3QgRmNPYmplY3RUeXBlCSAgICAqbzsKCiAgICBGY1N0ckJ1ZkluaXQgKCZidWYsIGJ1Zl9zdGF0aWMsIHNpemVvZiAoYnVmX3N0YXRpYykpOwogICAgZSA9IEZjUGF0dGVybkZpbmRFbHQgKHBhdCwgRkNfRkFNSUxZKTsKICAgIGlmIChlKQogICAgewoJaWYgKCFGY05hbWVVbnBhcnNlVmFsdWVMaXN0ICgmYnVmLCBlLT52YWx1ZXMsIChGY0NoYXI4ICopIEZDX0VTQ0FQRV9GSVhFRCkpCgkgICAgZ290byBiYWlsMDsKICAgIH0KICAgIGUgPSBGY1BhdHRlcm5GaW5kRWx0IChwYXQsIEZDX1NJWkUpOwogICAgaWYgKGUpCiAgICB7CglpZiAoIUZjTmFtZVVucGFyc2VTdHJpbmcgKCZidWYsIChGY0NoYXI4ICopICItIiwgMCkpCgkgICAgZ290byBiYWlsMDsKCWlmICghRmNOYW1lVW5wYXJzZVZhbHVlTGlzdCAoJmJ1ZiwgZS0+dmFsdWVzLCAoRmNDaGFyOCAqKSBGQ19FU0NBUEVfRklYRUQpKQoJICAgIGdvdG8gYmFpbDA7CiAgICB9CiAgICBmb3IgKGwgPSBfRmNPYmplY3RUeXBlczsgbDsgbCA9IGwtPm5leHQpCiAgICB7Cglmb3IgKGkgPSAwOyBpIDwgbC0+bnR5cGVzOyBpKyspCgl7CgkgICAgbyA9ICZsLT50eXBlc1tpXTsKCSAgICBpZiAoIXN0cmNtcCAoby0+b2JqZWN0LCBGQ19GQU1JTFkpIHx8IAoJCSFzdHJjbXAgKG8tPm9iamVjdCwgRkNfU0laRSkgfHwKCQkhc3RyY21wIChvLT5vYmplY3QsIEZDX0ZJTEUpKQoJCWNvbnRpbnVlOwoJICAgIAoJICAgIGUgPSBGY1BhdHRlcm5GaW5kRWx0IChwYXQsIG8tPm9iamVjdCk7CgkgICAgaWYgKGUpCgkgICAgewoJCWlmICghRmNOYW1lVW5wYXJzZVN0cmluZyAoJmJ1ZiwgKEZjQ2hhcjggKikgIjoiLCAwKSkKCQkgICAgZ290byBiYWlsMDsKCQlpZiAoIUZjTmFtZVVucGFyc2VTdHJpbmcgKCZidWYsIChGY0NoYXI4ICopIG8tPm9iamVjdCwgKEZjQ2hhcjggKikgRkNfRVNDQVBFX1ZBUklBQkxFKSkKCQkgICAgZ290byBiYWlsMDsKCQlpZiAoIUZjTmFtZVVucGFyc2VTdHJpbmcgKCZidWYsIChGY0NoYXI4ICopICI9IiwgMCkpCgkJICAgIGdvdG8gYmFpbDA7CgkJaWYgKCFGY05hbWVVbnBhcnNlVmFsdWVMaXN0ICgmYnVmLCBlLT52YWx1ZXMsIAoJCQkJCSAgICAgKEZjQ2hhcjggKikgRkNfRVNDQVBFX1ZBUklBQkxFKSkKCQkgICAgZ290byBiYWlsMDsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gRmNTdHJCdWZEb25lICgmYnVmKTsKYmFpbDA6CiAgICBGY1N0ckJ1ZkRlc3Ryb3kgKCZidWYpOwogICAgcmV0dXJuIDA7Cn0K