Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgYWx0X3NzdHJlYW1faW1wbC5ocHAgOiBhbHRlcm5hdGl2ZSBzdHJpbmdzdHJlYW0sIHRlbXBsYXRlcyBpbXBsZW1lbnRhdGlvbiAKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLy8gIENvcHlyaWdodCBTYW11ZWwgS3JlbXBwIDIwMDMuIFVzZSwgbW9kaWZpY2F0aW9uLCBhbmQgZGlzdHJpYnV0aW9uIGFyZQovLyAgc3ViamVjdCB0byB0aGUgQm9vc3QgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjAuIChTZWUgYWNjb21wYW55aW5nCi8vICBmaWxlIExJQ0VOU0VfMV8wLnR4dCBvciBjb3B5IGF0IGh0dHA6Ly93d3cuYm9vc3Qub3JnL0xJQ0VOU0VfMV8wLnR4dCkKCi8vICBTZWUgaHR0cDovL3d3dy5ib29zdC5vcmcvbGlicy9mb3JtYXQgZm9yIGxpYnJhcnkgaG9tZSBwYWdlCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojaWZuZGVmIEJPT1NUX1NLX0FMVF9TU1RSRUFNX0lNUExfSFBQCiNkZWZpbmUgQk9PU1RfU0tfQUxUX1NTVFJFQU1fSU1QTF9IUFAKCm5hbWVzcGFjZSBib29zdCB7CiAgICBuYW1lc3BhY2UgaW8gewovLyAtLS0gSW1wbGVtZW50YXRpb24gIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8vCgogICAgICAgIHRlbXBsYXRlPGNsYXNzIENoLCBjbGFzcyBUciwgY2xhc3MgQWxsb2M+CiAgICAgICAgdm9pZCBiYXNpY19hbHRzdHJpbmdidWY8Q2gsIFRyLCBBbGxvYz46OiAKICAgICAgICBjbGVhcl9idWZmZXIgKCkgewogICAgICAgICAgICBjb25zdCBDaCAqIHAgPSBwcHRyKCk7CiAgICAgICAgICAgIGNvbnN0IENoICogYiA9IHBiYXNlKCk7CiAgICAgICAgICAgIGlmKHAgIT0gTlVMTCAmJiBwICE9IGIpIHsKICAgICAgICAgICAgICAgIHNlZWtwb3MoMCwgOjpzdGQ6Omlvc19iYXNlOjpvdXQpOyAKICAgICAgICAgICAgfQogICAgICAgICAgICBwID0gZ3B0cigpOwogICAgICAgICAgICBiID0gZWJhY2soKTsKICAgICAgICAgICAgaWYocCAhPSBOVUxMICYmIHAgIT0gYikgewogICAgICAgICAgICAgICAgc2Vla3BvcygwLCA6OnN0ZDo6aW9zX2Jhc2U6OmluKTsgCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHRlbXBsYXRlPGNsYXNzIENoLCBjbGFzcyBUciwgY2xhc3MgQWxsb2M+CiAgICAgICAgdm9pZCBiYXNpY19hbHRzdHJpbmdidWY8Q2gsIFRyLCBBbGxvYz46OiAKICAgICAgICBzdHIgKGNvbnN0IHN0cmluZ190eXBlJiBzKSB7CiAgICAgICAgICAgIHNpemVfdHlwZSBzej1zLnNpemUoKTsKICAgICAgICAgICAgaWYoc3ogIT0gMCAmJiBtb2RlXyAmICg6OnN0ZDo6aW9zX2Jhc2U6OmluIHwgOjpzdGQ6Omlvc19iYXNlOjpvdXQpICkgewojaWZkZWYgX1JXU1REX05PX0NMQVNTX1BBUlRJQUxfU1BFQwogICAgICAgICAgICAgICAgdm9pZCAqdmRfcHRyID0gYWxsb2NfLmFsbG9jYXRlKHN6LCBpc19hbGxvY2F0ZWRfPyBlYmFjaygpIDogMCk7CiAgICAgICAgICAgICAgICBDaCAqbmV3X3B0ciA9IHN0YXRpY19jYXN0PENoICo+KHZkX3B0cik7CiNlbHNlCiAgICAgICAgICAgICAgICBDaCAqbmV3X3B0ciA9IGFsbG9jXy5hbGxvY2F0ZShzeiwgaXNfYWxsb2NhdGVkXz8gZWJhY2soKSA6IDApOwojZW5kaWYKICAgICAgICAgICAgICAgIC8vIGlmIHRoaXMgZGlkbnQgdGhyb3csIHdlJ3JlIHNhZmUsIHVwZGF0ZSB0aGUgYnVmZmVyCiAgICAgICAgICAgICAgICBkZWFsbG9jKCk7CiAgICAgICAgICAgICAgICBzeiA9IHMuY29weShuZXdfcHRyLCBzeik7CiAgICAgICAgICAgICAgICBwdXRlbmRfID0gbmV3X3B0ciArIHN6OwogICAgICAgICAgICAgICAgaWYobW9kZV8gJiA6OnN0ZDo6aW9zX2Jhc2U6OmluKQogICAgICAgICAgICAgICAgICAgIHN0cmVhbWJ1Zl90OjpzZXRnKG5ld19wdHIsIG5ld19wdHIsIG5ld19wdHIgKyBzeik7CiAgICAgICAgICAgICAgICBpZihtb2RlXyAmIDo6c3RkOjppb3NfYmFzZTo6b3V0KSB7CiAgICAgICAgICAgICAgICAgICAgc3RyZWFtYnVmX3Q6OnNldHAobmV3X3B0ciwgbmV3X3B0ciArIHN6KTsKICAgICAgICAgICAgICAgICAgICBpZihtb2RlXyAmICg6OnN0ZDo6aW9zX2Jhc2U6OmFwcCB8IDo6c3RkOjppb3NfYmFzZTo6YXRlKSkKICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtYnVmX3Q6OnBidW1wKHN0YXRpY19jYXN0PGludD4oc3opKTsKICAgICAgICAgICAgICAgICAgICBpZihncHRyKCkgPT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtYnVmX3Q6OnNldGcobmV3X3B0ciwgTlVMTCwgbmV3X3B0cik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpc19hbGxvY2F0ZWRfID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIAogICAgICAgICAgICAgICAgZGVhbGxvYygpOwogICAgICAgIH0KICAgICAgICB0ZW1wbGF0ZTxjbGFzcyBDaCwgY2xhc3MgVHIsIGNsYXNzIEFsbG9jPgogICAgICAgIENoKiAgIGJhc2ljX2FsdHN0cmluZ2J1ZjxDaCwgVHIsIEFsbG9jPjo6IAogICAgICAgIGJlZ2luICgpIGNvbnN0IHsKICAgICAgICAgICAgaWYobW9kZV8gJiA6OnN0ZDo6aW9zX2Jhc2U6Om91dCAmJiBwcHRyKCkgIT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldHVybiBwYmFzZSgpOwogICAgICAgICAgICBlbHNlIGlmKG1vZGVfICYgOjpzdGQ6Omlvc19iYXNlOjppbiAmJiBncHRyKCkgIT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldHVybiBlYmFjaygpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CgogICAgICAgIHRlbXBsYXRlPGNsYXNzIENoLCBjbGFzcyBUciwgY2xhc3MgQWxsb2M+CiAgICAgICAgdHlwZW5hbWUgc3RkOjpiYXNpY19zdHJpbmc8Q2gsVHIsQWxsb2M+OjpzaXplX3R5cGUKICAgICAgICBiYXNpY19hbHRzdHJpbmdidWY8Q2gsIFRyLCBBbGxvYz46OiAKICAgICAgICBzaXplICgpIGNvbnN0IHsgCiAgICAgICAgICAgIGlmKG1vZGVfICYgOjpzdGQ6Omlvc19iYXNlOjpvdXQgJiYgcHB0cigpKQogICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PHNpemVfdHlwZT4ocGVuZCgpIC0gcGJhc2UoKSk7CiAgICAgICAgICAgIGVsc2UgaWYobW9kZV8gJiA6OnN0ZDo6aW9zX2Jhc2U6OmluICYmIGdwdHIoKSkKICAgICAgICAgICAgICAgIHJldHVybiBzdGF0aWNfY2FzdDxzaXplX3R5cGU+KGVncHRyKCkgLSBlYmFjaygpKTsKICAgICAgICAgICAgZWxzZSAKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdGVtcGxhdGU8Y2xhc3MgQ2gsIGNsYXNzIFRyLCBjbGFzcyBBbGxvYz4KICAgICAgICB0eXBlbmFtZSBzdGQ6OmJhc2ljX3N0cmluZzxDaCxUcixBbGxvYz46OnNpemVfdHlwZQogICAgICAgIGJhc2ljX2FsdHN0cmluZ2J1ZjxDaCwgVHIsIEFsbG9jPjo6IAogICAgICAgIGN1cl9zaXplICgpIGNvbnN0IHsgCiAgICAgICAgICAgIGlmKG1vZGVfICYgOjpzdGQ6Omlvc19iYXNlOjpvdXQgJiYgcHB0cigpKQogICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PHN0cmVhbXNpemU+KCBwcHRyKCkgLSBwYmFzZSgpKTsKICAgICAgICAgICAgZWxzZSBpZihtb2RlXyAmIDo6c3RkOjppb3NfYmFzZTo6aW4gJiYgZ3B0cigpKQogICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PHN0cmVhbXNpemU+KCBncHRyKCkgLSBlYmFjaygpKTsKICAgICAgICAgICAgZWxzZSAKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdGVtcGxhdGU8Y2xhc3MgQ2gsIGNsYXNzIFRyLCBjbGFzcyBBbGxvYz4KICAgICAgICB0eXBlbmFtZSBiYXNpY19hbHRzdHJpbmdidWY8Q2gsIFRyLCBBbGxvYz46OnBvc190eXBlICAKICAgICAgICBiYXNpY19hbHRzdHJpbmdidWY8Q2gsIFRyLCBBbGxvYz46OiAKICAgICAgICBzZWVrb2ZmIChvZmZfdHlwZSBvZmYsIDo6c3RkOjppb3NfYmFzZTo6c2Vla2RpciB3YXksIDo6c3RkOjppb3NfYmFzZTo6b3Blbm1vZGUgd2hpY2gpIHsKICAgICAgICAgICAgaWYocHB0cigpICE9IE5VTEwgJiYgcHV0ZW5kXyA8IHBwdHIoKSkKICAgICAgICAgICAgICAgIHB1dGVuZF8gPSBwcHRyKCk7CiAgICAgICAgICAgIGlmKHdoaWNoICYgOjpzdGQ6Omlvc19iYXNlOjppbiAmJiBncHRyKCkgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgLy8gZ2V0IGFyZWEKICAgICAgICAgICAgICAgIGlmKHdheSA9PSA6OnN0ZDo6aW9zX2Jhc2U6OmVuZCkKICAgICAgICAgICAgICAgICAgICBvZmYgKz0gc3RhdGljX2Nhc3Q8b2ZmX3R5cGU+KHB1dGVuZF8gLSBncHRyKCkpOwogICAgICAgICAgICAgICAgZWxzZSBpZih3YXkgPT0gOjpzdGQ6Omlvc19iYXNlOjpiZWcpCiAgICAgICAgICAgICAgICAgICAgb2ZmICs9IHN0YXRpY19jYXN0PG9mZl90eXBlPihlYmFjaygpIC0gZ3B0cigpKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYod2F5ICE9IDo6c3RkOjppb3NfYmFzZTo6Y3VyIHx8ICh3aGljaCAmIDo6c3RkOjppb3NfYmFzZTo6b3V0KSApCiAgICAgICAgICAgICAgICAgICAgLy8gKGFsdGVyaW5nIGluJm91dCBpcyBvbmx5IHN1cHBvcnRlZCBpZiB3YXkgaXMgYmVnIG9yIGVuZCwgbm90IGN1cikKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcG9zX3R5cGUob2ZmX3R5cGUoLTEpKTsKICAgICAgICAgICAgICAgIGlmKGViYWNrKCkgPD0gb2ZmK2dwdHIoKSAmJiBvZmYrZ3B0cigpIDw9IHB1dGVuZF8gKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gc2V0IGdwdHIKICAgICAgICAgICAgICAgICAgICBzdHJlYW1idWZfdDo6Z2J1bXAoc3RhdGljX2Nhc3Q8aW50PihvZmYpKTsKICAgICAgICAgICAgICAgICAgICBpZih3aGljaCAmIDo6c3RkOjppb3NfYmFzZTo6b3V0ICYmIHBwdHIoKSAhPSBOVUxMKQogICAgICAgICAgICAgICAgICAgICAgICAvLyB1cGRhdGUgcHB0ciB0byBtYXRjaCBncHRyCiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbWJ1Zl90OjpwYnVtcChzdGF0aWNfY2FzdDxpbnQ+KGdwdHIoKS1wcHRyKCkpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBvZmYgPSBvZmZfdHlwZSgtMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZih3aGljaCAmIDo6c3RkOjppb3NfYmFzZTo6b3V0ICYmIHBwdHIoKSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAvLyBwdXQgYXJlYQogICAgICAgICAgICAgICAgaWYod2F5ID09IDo6c3RkOjppb3NfYmFzZTo6ZW5kKQogICAgICAgICAgICAgICAgICAgIG9mZiArPSBzdGF0aWNfY2FzdDxvZmZfdHlwZT4ocHV0ZW5kXyAtIHBwdHIoKSk7CiAgICAgICAgICAgICAgICBlbHNlIGlmKHdheSA9PSA6OnN0ZDo6aW9zX2Jhc2U6OmJlZykKICAgICAgICAgICAgICAgICAgICBvZmYgKz0gc3RhdGljX2Nhc3Q8b2ZmX3R5cGU+KHBiYXNlKCkgLSBwcHRyKCkpOwogICAgICAgICAgICAgICAgZWxzZSBpZih3YXkgIT0gOjpzdGQ6Omlvc19iYXNlOjpiZWcpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBvc190eXBlKG9mZl90eXBlKC0xKSk7ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmKHBiYXNlKCkgPD0gb2ZmK3BwdHIoKSAmJiBvZmYrcHB0cigpIDw9IHB1dGVuZF8pCiAgICAgICAgICAgICAgICAgICAgLy8gc2V0IHBwdHIKICAgICAgICAgICAgICAgICAgICBzdHJlYW1idWZfdDo6cGJ1bXAoc3RhdGljX2Nhc3Q8aW50PihvZmYpKTsgCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgb2ZmID0gb2ZmX3R5cGUoLTEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgLy8gbmVpdGhlciBpbiBub3Igb3V0CiAgICAgICAgICAgICAgICBvZmYgPSBvZmZfdHlwZSgtMSk7CiAgICAgICAgICAgIHJldHVybiAocG9zX3R5cGUob2ZmKSk7CiAgICAgICAgfQogICAgICAgIC8vLSBlbmQgc2Vla29mZiguLikKCiAgICAgICAgCiAgICAgICAgdGVtcGxhdGU8Y2xhc3MgQ2gsIGNsYXNzIFRyLCBjbGFzcyBBbGxvYz4KICAgICAgICB0eXBlbmFtZSBiYXNpY19hbHRzdHJpbmdidWY8Q2gsIFRyLCBBbGxvYz46OnBvc190eXBlIAogICAgICAgIGJhc2ljX2FsdHN0cmluZ2J1ZjxDaCwgVHIsIEFsbG9jPjo6IAogICAgICAgIHNlZWtwb3MgKHBvc190eXBlIHBvcywgOjpzdGQ6Omlvc19iYXNlOjpvcGVubW9kZSB3aGljaCkgewogICAgICAgICAgICBvZmZfdHlwZSBvZmYgPSBvZmZfdHlwZShwb3MpOyAvLyBvcGVyYXRpb24gZ3VhcmFudGVlZCBieSAyNy40LjMuMiB0YWJsZSA4OAogICAgICAgICAgICBpZihwcHRyKCkgIT0gTlVMTCAmJiBwdXRlbmRfIDwgcHB0cigpKQogICAgICAgICAgICAgICAgcHV0ZW5kXyA9IHBwdHIoKTsKICAgICAgICAgICAgaWYob2ZmICE9IG9mZl90eXBlKC0xKSkgewogICAgICAgICAgICAgICAgaWYod2hpY2ggJiA6OnN0ZDo6aW9zX2Jhc2U6OmluICYmIGdwdHIoKSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IGFyZWEKICAgICAgICAgICAgICAgICAgICBpZigwIDw9IG9mZiAmJiBvZmYgPD0gcHV0ZW5kXyAtIGViYWNrKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtYnVmX3Q6OmdidW1wKHN0YXRpY19jYXN0PGludD4oZWJhY2soKSAtIGdwdHIoKSArIG9mZikpOwogICAgICAgICAgICAgICAgICAgICAgICBpZih3aGljaCAmIDo6c3RkOjppb3NfYmFzZTo6b3V0ICYmIHBwdHIoKSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1cGRhdGUgcHB0ciB0byBtYXRjaCBncHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1idWZfdDo6cGJ1bXAoc3RhdGljX2Nhc3Q8aW50PihncHRyKCktcHB0cigpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBvZmYgPSBvZmZfdHlwZSgtMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKHdoaWNoICYgOjpzdGQ6Omlvc19iYXNlOjpvdXQgJiYgcHB0cigpICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAvLyBwdXQgYXJlYQogICAgICAgICAgICAgICAgICAgIGlmKDAgPD0gb2ZmICYmIG9mZiA8PSBwdXRlbmRfIC0gZWJhY2soKSkKICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtYnVmX3Q6OnBidW1wKHN0YXRpY19jYXN0PGludD4oZWJhY2soKSAtIHBwdHIoKSArIG9mZikpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgb2ZmID0gb2ZmX3R5cGUoLTEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSAvLyBuZWl0aGVyIGluIG5vciBvdXQKICAgICAgICAgICAgICAgICAgICBvZmYgPSBvZmZfdHlwZSgtMSk7CiAgICAgICAgICAgICAgICByZXR1cm4gKHBvc190eXBlKG9mZikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgQk9PU1RfQVNTRVJUKDApOyAvLyCnMjcuNC4zLjIgYWxsb3dzIHVuZGVmaW5lZC1iZWhhdmlvdXIgaGVyZQogICAgICAgICAgICAgICAgcmV0dXJuIHBvc190eXBlKG9mZl90eXBlKC0xKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8gLWVuZCBzZWVrcG9zKC4uKQoKCiAgICAgICAgdGVtcGxhdGU8Y2xhc3MgQ2gsIGNsYXNzIFRyLCBjbGFzcyBBbGxvYz4KICAgICAgICB0eXBlbmFtZSBiYXNpY19hbHRzdHJpbmdidWY8Q2gsIFRyLCBBbGxvYz46OmludF90eXBlCiAgICAgICAgYmFzaWNfYWx0c3RyaW5nYnVmPENoLCBUciwgQWxsb2M+OjogCiAgICAgICAgdW5kZXJmbG93ICgpIHsKICAgICAgICAgICAgaWYoZ3B0cigpID09IE5VTEwpIC8vIG5vIGdldCBhcmVhIC0+IG5vdGhpbmcgdG8gZ2V0LgogICAgICAgICAgICAgICAgcmV0dXJuIChjb21wYXRfdHJhaXRzX3R5cGU6OmVvZigpKTsgCiAgICAgICAgICAgIGVsc2UgaWYoZ3B0cigpIDwgZWdwdHIoKSkgIC8vIG9rLCBpbiBidWZmZXIKICAgICAgICAgICAgICAgIHJldHVybiAoY29tcGF0X3RyYWl0c190eXBlOjp0b19pbnRfdHlwZSgqZ3B0cigpKSk7IAogICAgICAgICAgICBlbHNlIGlmKG1vZGVfICYgOjpzdGQ6Omlvc19iYXNlOjppbiAmJiBwcHRyKCkgIT0gTlVMTAogICAgICAgICAgICAgICAgICAgICYmIChncHRyKCkgPCBwcHRyKCkgfHwgZ3B0cigpIDwgcHV0ZW5kXykgKQogICAgICAgICAgICAgICAgeyAgLy8gZXhwYW5kIGdldCBhcmVhIAogICAgICAgICAgICAgICAgICAgIGlmKHB1dGVuZF8gPCBwcHRyKCkpIAogICAgICAgICAgICAgICAgICAgICAgICBwdXRlbmRfID0gcHB0cigpOyAvLyByZW1lbWJlciBwcHRyIHJlYWNoZWQgdGhpcyBmYXIKICAgICAgICAgICAgICAgICAgICBzdHJlYW1idWZfdDo6c2V0ZyhlYmFjaygpLCBncHRyKCksIHB1dGVuZF8pOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAoY29tcGF0X3RyYWl0c190eXBlOjp0b19pbnRfdHlwZSgqZ3B0cigpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgLy8gY291bGRudCBnZXQgYW55dGhpbmcuIEVPRi4KICAgICAgICAgICAgICAgIHJldHVybiAoY29tcGF0X3RyYWl0c190eXBlOjplb2YoKSk7CiAgICAgICAgfQogICAgICAgIC8vIC1lbmQgdW5kZXJmbG93KC4uKQoKCiAgICAgICAgdGVtcGxhdGU8Y2xhc3MgQ2gsIGNsYXNzIFRyLCBjbGFzcyBBbGxvYz4KICAgICAgICB0eXBlbmFtZSBiYXNpY19hbHRzdHJpbmdidWY8Q2gsIFRyLCBBbGxvYz46OmludF90eXBlIAogICAgICAgIGJhc2ljX2FsdHN0cmluZ2J1ZjxDaCwgVHIsIEFsbG9jPjo6IAogICAgICAgIHBiYWNrZmFpbCAoaW50X3R5cGUgbWV0YSkgewogICAgICAgICAgICBpZihncHRyKCkgIT0gTlVMTCAgJiYgIChlYmFjaygpIDwgZ3B0cigpKSAKICAgICAgICAgICAgICAgJiYgKG1vZGVfICYgKDo6c3RkOjppb3NfYmFzZTo6b3V0KQogICAgICAgICAgICAgICAgICAgfHwgY29tcGF0X3RyYWl0c190eXBlOjplcV9pbnRfdHlwZShjb21wYXRfdHJhaXRzX3R5cGU6OmVvZigpLCBtZXRhKQogICAgICAgICAgICAgICAgICAgfHwgY29tcGF0X3RyYWl0c190eXBlOjplcShjb21wYXRfdHJhaXRzX3R5cGU6OnRvX2NoYXJfdHlwZShtZXRhKSwgZ3B0cigpWy0xXSkgKSApIHsgCiAgICAgICAgICAgICAgICBzdHJlYW1idWZfdDo6Z2J1bXAoLTEpOyAvLyBiYWNrIG9uZSBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgIGlmKCFjb21wYXRfdHJhaXRzX3R5cGU6OmVxX2ludF90eXBlKGNvbXBhdF90cmFpdHNfdHlwZTo6ZW9mKCksIG1ldGEpKQogICAgICAgICAgICAgICAgICAgIC8vICBwdXQtYmFjayBtZXRhIGludG8gZ2V0IGFyZWEKICAgICAgICAgICAgICAgICAgICAqZ3B0cigpID0gY29tcGF0X3RyYWl0c190eXBlOjp0b19jaGFyX3R5cGUobWV0YSk7CiAgICAgICAgICAgICAgICByZXR1cm4gKGNvbXBhdF90cmFpdHNfdHlwZTo6bm90X2VvZihtZXRhKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIChjb21wYXRfdHJhaXRzX3R5cGU6OmVvZigpKTsgIC8vIGZhaWxlZCBwdXRiYWNrCiAgICAgICAgfQogICAgICAgIC8vIC1lbmQgcGJhY2tmYWlsKC4uKQoKCiAgICAgICAgdGVtcGxhdGU8Y2xhc3MgQ2gsIGNsYXNzIFRyLCBjbGFzcyBBbGxvYz4KICAgICAgICB0eXBlbmFtZSBiYXNpY19hbHRzdHJpbmdidWY8Q2gsIFRyLCBBbGxvYz46OmludF90eXBlIAogICAgICAgIGJhc2ljX2FsdHN0cmluZ2J1ZjxDaCwgVHIsIEFsbG9jPjo6IAogICAgICAgIG92ZXJmbG93IChpbnRfdHlwZSBtZXRhKSB7CiNpZmRlZiBCT09TVF9NU1ZDCiNwcmFnbWEgd2FybmluZyhwdXNoKQojcHJhZ21hIHdhcm5pbmcoZGlzYWJsZTo0OTk2KQojZW5kaWYKICAgICAgICAgICAgaWYoY29tcGF0X3RyYWl0c190eXBlOjplcV9pbnRfdHlwZShjb21wYXRfdHJhaXRzX3R5cGU6OmVvZigpLCBtZXRhKSkKICAgICAgICAgICAgICAgIHJldHVybiBjb21wYXRfdHJhaXRzX3R5cGU6Om5vdF9lb2YobWV0YSk7IC8vIG5vdGhpbmcgdG8gZG8KICAgICAgICAgICAgZWxzZSBpZihwcHRyKCkgIT0gTlVMTCAmJiBwcHRyKCkgPCBlcHB0cigpKSB7CiAgICAgICAgICAgICAgICBzdHJlYW1idWZfdDo6c3B1dGMoY29tcGF0X3RyYWl0c190eXBlOjp0b19jaGFyX3R5cGUobWV0YSkpOwogICAgICAgICAgICAgICAgcmV0dXJuIG1ldGE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZighIChtb2RlXyAmIDo6c3RkOjppb3NfYmFzZTo6b3V0KSkgCiAgICAgICAgICAgICAgICAvLyBubyB3cml0ZSBwb3NpdGlvbiwgYW5kIGNhbnQgbWFrZSBvbmUKICAgICAgICAgICAgICAgIHJldHVybiBjb21wYXRfdHJhaXRzX3R5cGU6OmVvZigpOyAKICAgICAgICAgICAgZWxzZSB7IC8vIG1ha2UgYSB3cml0ZSBwb3NpdGlvbiBhdmFpbGFibGUKICAgICAgICAgICAgICAgIHN0ZDo6c2l6ZV90IHByZXZfc2l6ZSA9IHBwdHIoKSA9PSBOVUxMID8gMCA6IGVwcHRyKCkgLSBlYmFjaygpOwogICAgICAgICAgICAgICAgc3RkOjpzaXplX3QgbmV3X3NpemUgPSBwcmV2X3NpemU7CiAgICAgICAgICAgICAgICAvLyBleHBvbmVudGlhbCBncm93dGggOiBzaXplICo9IDEuNQogICAgICAgICAgICAgICAgc3RkOjpzaXplX3QgYWRkX3NpemUgPSBuZXdfc2l6ZSAvIDI7CiAgICAgICAgICAgICAgICBpZihhZGRfc2l6ZSA8IGFsbG9jX21pbikKICAgICAgICAgICAgICAgICAgICBhZGRfc2l6ZSA9IGFsbG9jX21pbjsKICAgICAgICAgICAgICAgIENoICogbmV3cHRyID0gTlVMTCwgICpvbGRwdHIgPSBlYmFjaygpOwoKICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSBhZGRpbmcgYWRkX3NpemUgd29udCBvdmVyZmxvdyBzaXplX3QKICAgICAgICAgICAgICAgIHdoaWxlICgwIDwgYWRkX3NpemUgJiYgKChzdGQ6Om51bWVyaWNfbGltaXRzPHN0ZDo6c2l6ZV90Pjo6bWF4KSgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIGFkZF9zaXplIDwgbmV3X3NpemUpICkKICAgICAgICAgICAgICAgICAgICBhZGRfc2l6ZSAvPSAyOwogICAgICAgICAgICAgICAgaWYoMCA8IGFkZF9zaXplKSB7CiAgICAgICAgICAgICAgICAgICAgbmV3X3NpemUgKz0gYWRkX3NpemU7CiNpZmRlZiBfUldTVERfTk9fQ0xBU1NfUEFSVElBTF9TUEVDCiAgICAgICAgICAgICAgICAgICAgdm9pZCAqdmRwdHIgPSBhbGxvY18uYWxsb2NhdGUobmV3X3NpemUsIGlzX2FsbG9jYXRlZF8/IG9sZHB0ciA6IDApOwogICAgICAgICAgICAgICAgICAgIG5ld3B0ciA9IHN0YXRpY19jYXN0PENoICo+KHZkcHRyKTsKI2Vsc2UKICAgICAgICAgICAgICAgICAgICBuZXdwdHIgPSBhbGxvY18uYWxsb2NhdGUobmV3X3NpemUsIGlzX2FsbG9jYXRlZF8/IG9sZHB0ciA6IDApOwojZW5kaWYKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZigwIDwgcHJldl9zaXplKQogICAgICAgICAgICAgICAgICAgIGNvbXBhdF90cmFpdHNfdHlwZTo6Y29weShuZXdwdHIsIG9sZHB0ciwgcHJldl9zaXplKTsKICAgICAgICAgICAgICAgIGlmKGlzX2FsbG9jYXRlZF8pCiAgICAgICAgICAgICAgICAgICAgYWxsb2NfLmRlYWxsb2NhdGUob2xkcHRyLCBwcmV2X3NpemUpOwogICAgICAgICAgICAgICAgaXNfYWxsb2NhdGVkXz10cnVlOwoKICAgICAgICAgICAgICAgIGlmKHByZXZfc2l6ZSA9PSAwKSB7IC8vIGZpcnN0IGFsbG9jYXRpb24KICAgICAgICAgICAgICAgICAgICBwdXRlbmRfID0gbmV3cHRyOwogICAgICAgICAgICAgICAgICAgIHN0cmVhbWJ1Zl90OjpzZXRwKG5ld3B0ciwgbmV3cHRyICsgbmV3X3NpemUpOwogICAgICAgICAgICAgICAgICAgIGlmKG1vZGVfICYgOjpzdGQ6Omlvc19iYXNlOjppbikKICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtYnVmX3Q6OnNldGcobmV3cHRyLCBuZXdwdHIsIG5ld3B0ciArIDEpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtYnVmX3Q6OnNldGcobmV3cHRyLCAwLCBuZXdwdHIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7IC8vIHVwZGF0ZSBwb2ludGVycwogICAgICAgICAgICAgICAgICAgIHB1dGVuZF8gPSBwdXRlbmRfIC0gb2xkcHRyICsgbmV3cHRyOwogICAgICAgICAgICAgICAgICAgIGludCBwcHRyX2NvdW50ID0gc3RhdGljX2Nhc3Q8aW50PihwcHRyKCktcGJhc2UoKSk7CiAgICAgICAgICAgICAgICAgICAgaW50IGdwdHJfY291bnQgPSBzdGF0aWNfY2FzdDxpbnQ+KGdwdHIoKS1lYmFjaygpKTsKICAgICAgICAgICAgICAgICAgICBzdHJlYW1idWZfdDo6c2V0cChwYmFzZSgpIC0gb2xkcHRyICsgbmV3cHRyLCBuZXdwdHIgKyBuZXdfc2l6ZSk7CiAgICAgICAgICAgICAgICAgICAgc3RyZWFtYnVmX3Q6OnBidW1wKHBwdHJfY291bnQpOwogICAgICAgICAgICAgICAgICAgIGlmKG1vZGVfICYgOjpzdGQ6Omlvc19iYXNlOjppbikKICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtYnVmX3Q6OnNldGcobmV3cHRyLCBuZXdwdHIgKyBncHRyX2NvdW50LCBwcHRyKCkgKyAxKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbWJ1Zl90OjpzZXRnKG5ld3B0ciwgMCwgbmV3cHRyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHN0cmVhbWJ1Zl90OjpzcHV0Yyhjb21wYXRfdHJhaXRzX3R5cGU6OnRvX2NoYXJfdHlwZShtZXRhKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbWV0YTsKICAgICAgICAgICAgfQojaWZkZWYgQk9PU1RfTVNWQwojcHJhZ21hIHdhcm5pbmcocG9wKQojZW5kaWYKICAgICAgICB9CiAgICAgICAgLy8gLWVuZCBvdmVyZmxvdyguLikKCiAgICAgICAgdGVtcGxhdGU8Y2xhc3MgQ2gsIGNsYXNzIFRyLCBjbGFzcyBBbGxvYz4KICAgICAgICB2b2lkIGJhc2ljX2FsdHN0cmluZ2J1ZjxDaCwgVHIsIEFsbG9jPjo6IGRlYWxsb2MoKSB7CiAgICAgICAgICAgIGlmKGlzX2FsbG9jYXRlZF8pCiAgICAgICAgICAgICAgICBhbGxvY18uZGVhbGxvY2F0ZShlYmFjaygpLCAocHB0cigpICE9IE5VTEwgPyBlcHB0cigpIDogZWdwdHIoKSkgLSBlYmFjaygpKTsKICAgICAgICAgICAgaXNfYWxsb2NhdGVkXyA9IGZhbHNlOwogICAgICAgICAgICBzdHJlYW1idWZfdDo6c2V0ZygwLCAwLCAwKTsKICAgICAgICAgICAgc3RyZWFtYnVmX3Q6OnNldHAoMCwgMCk7CiAgICAgICAgICAgIHB1dGVuZF8gPSBOVUxMOwogICAgICAgIH0KCiAgICB9Ly8gTi5TLiBpbwp9IC8vIE4uUy4gYm9vc3QKCiNlbmRpZiAvLyBpbmNsdWRlIGd1YXJkCgo=