LyoKICogJFhGcmVlODY6ICQKICoKICogQ29weXJpZ2h0IKkgMjAwMCBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJmY2ludC5oIgoKRmNQYXR0ZXJuICoKRmNQYXR0ZXJuQ3JlYXRlICh2b2lkKQp7CiAgICBGY1BhdHRlcm4JKnA7CgogICAgcCA9IChGY1BhdHRlcm4gKikgbWFsbG9jIChzaXplb2YgKEZjUGF0dGVybikpOwogICAgaWYgKCFwKQoJcmV0dXJuIDA7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fUEFUVEVSTiwgc2l6ZW9mIChGY1BhdHRlcm4pKTsKICAgIHAtPm51bSA9IDA7CiAgICBwLT5zaXplID0gMDsKICAgIHAtPmVsdHMgPSAwOwogICAgcmV0dXJuIHA7Cn0KCnZvaWQKRmNWYWx1ZURlc3Ryb3kgKEZjVmFsdWUgdikKewogICAgc3dpdGNoICh2LnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJRmNTdHJGcmVlICgoRmNDaGFyOCAqKSB2LnUucyk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJRmNNYXRyaXhGcmVlICgoRmNNYXRyaXggKikgdi51Lm0pOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZUNoYXJTZXQ6CglGY0NoYXJTZXREZXN0cm95ICgoRmNDaGFyU2V0ICopIHYudS5jKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCWJyZWFrOwogICAgfQp9CgpGY1ZhbHVlCkZjVmFsdWVTYXZlIChGY1ZhbHVlIHYpCnsKICAgIHN3aXRjaCAodi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZVN0cmluZzoKCXYudS5zID0gRmNTdHJDb3B5ICh2LnUucyk7CglpZiAoIXYudS5zKQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJdi51Lm0gPSBGY01hdHJpeENvcHkgKHYudS5tKTsKCWlmICghdi51Lm0pCgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVDaGFyU2V0OgoJdi51LmMgPSBGY0NoYXJTZXRDb3B5ICgoRmNDaGFyU2V0ICopIHYudS5jKTsKCWlmICghdi51LmMpCgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCWJyZWFrOwogICAgZGVmYXVsdDoKCWJyZWFrOwogICAgfQogICAgcmV0dXJuIHY7Cn0KCnZvaWQKRmNWYWx1ZUxpc3REZXN0cm95IChGY1ZhbHVlTGlzdCAqbCkKewogICAgRmNWYWx1ZUxpc3QgICAgKm5leHQ7CiAgICBmb3IgKDsgbDsgbCA9IG5leHQpCiAgICB7Cglzd2l0Y2ggKGwtPnZhbHVlLnR5cGUpIHsKCWNhc2UgRmNUeXBlU3RyaW5nOgoJICAgIEZjU3RyRnJlZSAoKEZjQ2hhcjggKikgbC0+dmFsdWUudS5zKTsKCSAgICBicmVhazsKCWNhc2UgRmNUeXBlTWF0cml4OgoJICAgIEZjTWF0cml4RnJlZSAoKEZjTWF0cml4ICopIGwtPnZhbHVlLnUubSk7CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZUNoYXJTZXQ6CgkgICAgRmNDaGFyU2V0RGVzdHJveSAoKEZjQ2hhclNldCAqKSBsLT52YWx1ZS51LmMpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBicmVhazsKCX0KCW5leHQgPSBsLT5uZXh0OwoJRmNNZW1GcmVlIChGQ19NRU1fVkFMTElTVCwgc2l6ZW9mIChGY1ZhbHVlTGlzdCkpOwoJZnJlZSAobCk7CiAgICB9Cn0KCnZvaWQKRmNQYXR0ZXJuRGVzdHJveSAoRmNQYXR0ZXJuICpwKQp7CiAgICBpbnQJCSAgICBpOwogICAgCiAgICBmb3IgKGkgPSAwOyBpIDwgcC0+bnVtOyBpKyspCglGY1ZhbHVlTGlzdERlc3Ryb3kgKHAtPmVsdHNbaV0udmFsdWVzKTsKCiAgICBwLT5udW0gPSAwOwogICAgaWYgKHAtPmVsdHMpCiAgICB7CglGY01lbUZyZWUgKEZDX01FTV9QQVRFTFQsIHAtPnNpemUgKiBzaXplb2YgKEZjUGF0dGVybkVsdCkpOwoJZnJlZSAocC0+ZWx0cyk7CglwLT5lbHRzID0gMDsKICAgIH0KICAgIHAtPnNpemUgPSAwOwogICAgRmNNZW1GcmVlIChGQ19NRU1fUEFUVEVSTiwgc2l6ZW9mIChGY1BhdHRlcm4pKTsKICAgIGZyZWUgKHApOwp9CgpGY1BhdHRlcm5FbHQgKgpGY1BhdHRlcm5GaW5kIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgRmNCb29sIGluc2VydCkKewogICAgaW50CQkgICAgaTsKICAgIGludAkJICAgIHM7CiAgICBGY1BhdHRlcm5FbHQgICAqZTsKICAgIAogICAgLyogbWF0Y2ggZXhpc3RpbmcgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBwLT5udW07IGkrKykKICAgIHsKCWlmICghRmNTdHJDbXBJZ25vcmVDYXNlIChvYmplY3QsIHAtPmVsdHNbaV0ub2JqZWN0KSkKCSAgICByZXR1cm4gJnAtPmVsdHNbaV07CiAgICB9CgogICAgaWYgKCFpbnNlcnQpCglyZXR1cm4gRmNGYWxzZTsKCiAgICAvKiBncm93IGFycmF5ICovCiAgICBpZiAoaSA9PSBwLT5zaXplKQogICAgewoJcyA9IHAtPnNpemUgKyAxNjsKCWlmIChwLT5lbHRzKQoJICAgIGUgPSAoRmNQYXR0ZXJuRWx0ICopIHJlYWxsb2MgKHAtPmVsdHMsIHMgKiBzaXplb2YgKEZjUGF0dGVybkVsdCkpOwoJZWxzZQoJICAgIGUgPSAoRmNQYXR0ZXJuRWx0ICopIG1hbGxvYyAocyAqIHNpemVvZiAoRmNQYXR0ZXJuRWx0KSk7CglpZiAoIWUpCgkgICAgcmV0dXJuIEZjRmFsc2U7CglwLT5lbHRzID0gZTsKCWlmIChwLT5zaXplKQoJICAgIEZjTWVtRnJlZSAoRkNfTUVNX1BBVEVMVCwgcC0+c2l6ZSAqIHNpemVvZiAoRmNQYXR0ZXJuRWx0KSk7CglGY01lbUFsbG9jIChGQ19NRU1fUEFURUxULCBzICogc2l6ZW9mIChGY1BhdHRlcm5FbHQpKTsKCXdoaWxlIChwLT5zaXplIDwgcykKCXsKCSAgICBwLT5lbHRzW3AtPnNpemVdLm9iamVjdCA9IDA7CgkgICAgcC0+ZWx0c1twLT5zaXplXS52YWx1ZXMgPSAwOwoJICAgIHAtPnNpemUrKzsKCX0KICAgIH0KICAgIAogICAgLyogYnVtcCBjb3VudCAqLwogICAgcC0+bnVtKys7CiAgICAKICAgIHAtPmVsdHNbaV0ub2JqZWN0ID0gb2JqZWN0OwogICAgCiAgICByZXR1cm4gJnAtPmVsdHNbaV07Cn0KCkZjQm9vbApGY1BhdHRlcm5BZGQgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBGY1ZhbHVlIHZhbHVlLCBGY0Jvb2wgYXBwZW5kKQp7CiAgICBGY1BhdHRlcm5FbHQgICAqZTsKICAgIEZjVmFsdWVMaXN0ICAgICpuZXcsICoqcHJldjsKCiAgICBuZXcgPSAoRmNWYWx1ZUxpc3QgKikgbWFsbG9jIChzaXplb2YgKEZjVmFsdWVMaXN0KSk7CiAgICBpZiAoIW5ldykKCWdvdG8gYmFpbDA7CgogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1ZBTExJU1QsIHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKICAgIC8qIGR1cCBzdHJpbmcgKi8KICAgIHZhbHVlID0gRmNWYWx1ZVNhdmUgKHZhbHVlKTsKICAgIGlmICh2YWx1ZS50eXBlID09IEZjVHlwZVZvaWQpCglnb3RvIGJhaWwxOwoKICAgIG5ldy0+dmFsdWUgPSB2YWx1ZTsKICAgIG5ldy0+bmV4dCA9IDA7CiAgICAKICAgIGUgPSBGY1BhdHRlcm5GaW5kIChwLCBvYmplY3QsIEZjVHJ1ZSk7CiAgICBpZiAoIWUpCglnb3RvIGJhaWwyOwogICAgCiAgICBpZiAoYXBwZW5kKQogICAgewoJZm9yIChwcmV2ID0gJmUtPnZhbHVlczsgKnByZXY7IHByZXYgPSAmKCpwcmV2KS0+bmV4dCk7CgkqcHJldiA9IG5ldzsKICAgIH0KICAgIGVsc2UKICAgIHsKCW5ldy0+bmV4dCA9IGUtPnZhbHVlczsKCWUtPnZhbHVlcyA9IG5ldzsKICAgIH0KICAgIAogICAgcmV0dXJuIEZjVHJ1ZTsKCmJhaWwyOiAgICAKICAgIHN3aXRjaCAodmFsdWUudHlwZSkgewogICAgY2FzZSBGY1R5cGVTdHJpbmc6CglGY1N0ckZyZWUgKChGY0NoYXI4ICopIHZhbHVlLnUucyk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJRmNNYXRyaXhGcmVlICgoRmNNYXRyaXggKikgdmFsdWUudS5tKTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVDaGFyU2V0OgoJRmNDaGFyU2V0RGVzdHJveSAoKEZjQ2hhclNldCAqKSB2YWx1ZS51LmMpOwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJYnJlYWs7CiAgICB9CmJhaWwxOgogICAgRmNNZW1GcmVlIChGQ19NRU1fVkFMTElTVCwgc2l6ZW9mIChGY1ZhbHVlTGlzdCkpOwogICAgZnJlZSAobmV3KTsKYmFpbDA6CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKRmNCb29sCkZjUGF0dGVybkRlbCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QpCnsKICAgIEZjUGF0dGVybkVsdCAgICplOwogICAgaW50CQkgICAgaTsKCiAgICBlID0gRmNQYXR0ZXJuRmluZCAocCwgb2JqZWN0LCBGY0ZhbHNlKTsKICAgIGlmICghZSkKCXJldHVybiBGY0ZhbHNlOwoKICAgIGkgPSBlIC0gcC0+ZWx0czsKICAgIAogICAgLyogZGVzdHJveSB2YWx1ZSAqLwogICAgRmNWYWx1ZUxpc3REZXN0cm95IChlLT52YWx1ZXMpOwogICAgCiAgICAvKiBzaHVmZmxlIGV4aXN0aW5nIG9uZXMgZG93biAqLwogICAgbWVtbW92ZSAoZSwgZSsxLCAocC0+ZWx0cyArIHAtPm51bSAtIChlICsgMSkpICogc2l6ZW9mIChGY1BhdHRlcm5FbHQpKTsKICAgIHAtPm51bS0tOwogICAgcC0+ZWx0c1twLT5udW1dLm9iamVjdCA9IDA7CiAgICBwLT5lbHRzW3AtPm51bV0udmFsdWVzID0gMDsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY1BhdHRlcm5BZGRJbnRlZ2VyIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGkpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwogICAgdi51LmkgPSBpOwogICAgcmV0dXJuIEZjUGF0dGVybkFkZCAocCwgb2JqZWN0LCB2LCBGY1RydWUpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkRG91YmxlIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgZG91YmxlIGQpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVEb3VibGU7CiAgICB2LnUuZCA9IGQ7CiAgICByZXR1cm4gRmNQYXR0ZXJuQWRkIChwLCBvYmplY3QsIHYsIEZjVHJ1ZSk7Cn0KCgpGY0Jvb2wKRmNQYXR0ZXJuQWRkU3RyaW5nIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgY29uc3QgY2hhciAqcykKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZVN0cmluZzsKICAgIHYudS5zID0gKGNoYXIgKikgczsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKRmNCb29sCkZjUGF0dGVybkFkZE1hdHJpeCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGNvbnN0IEZjTWF0cml4ICpzKQp7CiAgICBGY1ZhbHVlCXY7CgogICAgdi50eXBlID0gRmNUeXBlTWF0cml4OwogICAgdi51Lm0gPSAoRmNNYXRyaXggKikgczsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKCkZjQm9vbApGY1BhdHRlcm5BZGRCb29sIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgRmNCb29sIGIpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVCb29sOwogICAgdi51LmIgPSBiOwogICAgcmV0dXJuIEZjUGF0dGVybkFkZCAocCwgb2JqZWN0LCB2LCBGY1RydWUpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkQ2hhclNldCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGNvbnN0IEZjQ2hhclNldCAqYykKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZUNoYXJTZXQ7CiAgICB2LnUuYyA9IChGY0NoYXJTZXQgKikgYzsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0IChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBGY1ZhbHVlICp2KQp7CiAgICBGY1BhdHRlcm5FbHQgICAqZTsKICAgIEZjVmFsdWVMaXN0ICAgICpsOwoKICAgIGUgPSBGY1BhdHRlcm5GaW5kIChwLCBvYmplY3QsIEZjRmFsc2UpOwogICAgaWYgKCFlKQoJcmV0dXJuIEZjUmVzdWx0Tm9NYXRjaDsKICAgIGZvciAobCA9IGUtPnZhbHVlczsgbDsgbCA9IGwtPm5leHQpCiAgICB7CglpZiAoIWlkKQoJewoJICAgICp2ID0gbC0+dmFsdWU7CgkgICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cgl9CglpZC0tOwogICAgfQogICAgcmV0dXJuIEZjUmVzdWx0Tm9JZDsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0SW50ZWdlciAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgaW50ICppKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIHN3aXRjaCAodi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZURvdWJsZToKCSppID0gKGludCkgdi51LmQ7CglicmVhazsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCSppID0gdi51Lmk7CglicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgfQogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCkZjUmVzdWx0CkZjUGF0dGVybkdldERvdWJsZSAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgZG91YmxlICpkKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIHN3aXRjaCAodi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZURvdWJsZToKCSpkID0gdi51LmQ7CglicmVhazsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCSpkID0gKGRvdWJsZSkgdi51Lmk7CglicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgfQogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCkZjUmVzdWx0CkZjUGF0dGVybkdldFN0cmluZyAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgY2hhciAqKiBzKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIGlmICh2LnR5cGUgIT0gRmNUeXBlU3RyaW5nKQogICAgICAgIHJldHVybiBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKICAgICpzID0gKGNoYXIgKikgdi51LnM7CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0TWF0cml4IChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBGY01hdHJpeCAqKm0pCnsKICAgIEZjVmFsdWUJdjsKICAgIEZjUmVzdWx0CXI7CgogICAgciA9IEZjUGF0dGVybkdldCAocCwgb2JqZWN0LCBpZCwgJnYpOwogICAgaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCXJldHVybiByOwogICAgaWYgKHYudHlwZSAhPSBGY1R5cGVNYXRyaXgpCiAgICAgICAgcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgKm0gPSAoRmNNYXRyaXggKikgdi51Lm07CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKCkZjUmVzdWx0CkZjUGF0dGVybkdldEJvb2wgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBpbnQgaWQsIEZjQm9vbCAqYikKewogICAgRmNWYWx1ZQl2OwogICAgRmNSZXN1bHQJcjsKCiAgICByID0gRmNQYXR0ZXJuR2V0IChwLCBvYmplY3QsIGlkLCAmdik7CiAgICBpZiAociAhPSBGY1Jlc3VsdE1hdGNoKQoJcmV0dXJuIHI7CiAgICBpZiAodi50eXBlICE9IEZjVHlwZUJvb2wpCiAgICAgICAgcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgKmIgPSB2LnUuYjsKICAgIHJldHVybiBGY1Jlc3VsdE1hdGNoOwp9CgpGY1Jlc3VsdApGY1BhdHRlcm5HZXRDaGFyU2V0IChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBGY0NoYXJTZXQgKipjKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIGlmICh2LnR5cGUgIT0gRmNUeXBlQ2hhclNldCkKICAgICAgICByZXR1cm4gRmNSZXN1bHRUeXBlTWlzbWF0Y2g7CiAgICAqYyA9IChGY0NoYXJTZXQgKikgdi51LmM7CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKRmNQYXR0ZXJuICoKRmNQYXR0ZXJuRHVwbGljYXRlIChGY1BhdHRlcm4gKm9yaWcpCnsKICAgIEZjUGF0dGVybgkgICAgKm5ldzsKICAgIGludAkJICAgIGk7CiAgICBGY1ZhbHVlTGlzdCAgICAqbDsKCiAgICBuZXcgPSBGY1BhdHRlcm5DcmVhdGUgKCk7CiAgICBpZiAoIW5ldykKCWdvdG8gYmFpbDA7CgogICAgZm9yIChpID0gMDsgaSA8IG9yaWctPm51bTsgaSsrKQogICAgewoJZm9yIChsID0gb3JpZy0+ZWx0c1tpXS52YWx1ZXM7IGw7IGwgPSBsLT5uZXh0KQoJICAgIGlmICghRmNQYXR0ZXJuQWRkIChuZXcsIG9yaWctPmVsdHNbaV0ub2JqZWN0LCBsLT52YWx1ZSwgRmNUcnVlKSkKCQlnb3RvIGJhaWwxOwogICAgfQoKICAgIHJldHVybiBuZXc7CgpiYWlsMToKICAgIEZjUGF0dGVybkRlc3Ryb3kgKG5ldyk7CmJhaWwwOgogICAgcmV0dXJuIDA7Cn0KCkZjUGF0dGVybiAqCkZjUGF0dGVyblZhQnVpbGQgKEZjUGF0dGVybiAqb3JpZywgdmFfbGlzdCB2YSkKewogICAgRmNQYXR0ZXJuCSpyZXQ7CiAgICAKICAgIEZjUGF0dGVyblZhcEJ1aWxkIChyZXQsIG9yaWcsIHZhKTsKICAgIHJldHVybiByZXQ7Cn0KCkZjUGF0dGVybiAqCkZjUGF0dGVybkJ1aWxkIChGY1BhdHRlcm4gKm9yaWcsIC4uLikKewogICAgdmFfbGlzdAl2YTsKICAgIAogICAgdmFfc3RhcnQgKHZhLCBvcmlnKTsKICAgIEZjUGF0dGVyblZhcEJ1aWxkIChvcmlnLCBvcmlnLCB2YSk7CiAgICB2YV9lbmQgKHZhKTsKICAgIHJldHVybiBvcmlnOwp9Cg==