LyogQm9vc3QgaW50ZXJ2YWwvY2hlY2tpbmcuaHBwIHRlbXBsYXRlIGltcGxlbWVudGF0aW9uIGZpbGUKICoKICogQ29weXJpZ2h0IDIwMDIgSGVydukgQnL2bm5pbWFubiwgR3VpbGxhdW1lIE1lbHF1aW9uZCwgU3lsdmFpbiBQaW9uCiAqCiAqIERpc3RyaWJ1dGVkIHVuZGVyIHRoZSBCb29zdCBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMC4KICogKFNlZSBhY2NvbXBhbnlpbmcgZmlsZSBMSUNFTlNFXzFfMC50eHQgb3IKICogY29weSBhdCBodHRwOi8vd3d3LmJvb3N0Lm9yZy9MSUNFTlNFXzFfMC50eHQpCiAqLwoKI2lmbmRlZiBCT09TVF9OVU1FUklDX0lOVEVSVkFMX0NIRUNLSU5HX0hQUAojZGVmaW5lIEJPT1NUX05VTUVSSUNfSU5URVJWQUxfQ0hFQ0tJTkdfSFBQCgojaW5jbHVkZSA8c3RkZXhjZXB0PgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8Y2Fzc2VydD4KI2luY2x1ZGUgPGJvb3N0L2xpbWl0cy5ocHA+CgpuYW1lc3BhY2UgYm9vc3QgewpuYW1lc3BhY2UgbnVtZXJpYyB7Cm5hbWVzcGFjZSBpbnRlcnZhbF9saWIgewoKc3RydWN0IGV4Y2VwdGlvbl9jcmVhdGVfZW1wdHkKewogIHZvaWQgb3BlcmF0b3IoKSgpCiAgewogICAgdGhyb3cgc3RkOjpydW50aW1lX2Vycm9yKCJib29zdDo6aW50ZXJ2YWw6IGVtcHR5IGludGVydmFsIGNyZWF0ZWQiKTsKICB9Cn07CgpzdHJ1Y3QgZXhjZXB0aW9uX2ludmFsaWRfbnVtYmVyCnsKICB2b2lkIG9wZXJhdG9yKCkoKQogIHsKICAgIHRocm93IHN0ZDo6aW52YWxpZF9hcmd1bWVudCgiYm9vc3Q6OmludGVydmFsOiBpbnZhbGlkIG51bWJlciIpOwogIH0KfTsKCnRlbXBsYXRlPGNsYXNzIFQ+CnN0cnVjdCBjaGVja2luZ19iYXNlCnsKICBzdGF0aWMgVCBwb3NfaW5mKCkKICB7CiAgICBhc3NlcnQoc3RkOjpudW1lcmljX2xpbWl0czxUPjo6aGFzX2luZmluaXR5KTsKICAgIHJldHVybiBzdGQ6Om51bWVyaWNfbGltaXRzPFQ+OjppbmZpbml0eSgpOwogIH0KICBzdGF0aWMgVCBuZWdfaW5mKCkKICB7CiAgICBhc3NlcnQoc3RkOjpudW1lcmljX2xpbWl0czxUPjo6aGFzX2luZmluaXR5KTsKICAgIHJldHVybiAtc3RkOjpudW1lcmljX2xpbWl0czxUPjo6aW5maW5pdHkoKTsKICB9CiAgc3RhdGljIFQgbmFuKCkKICB7CiAgICBhc3NlcnQoc3RkOjpudW1lcmljX2xpbWl0czxUPjo6aGFzX3F1aWV0X05hTik7CiAgICByZXR1cm4gc3RkOjpudW1lcmljX2xpbWl0czxUPjo6cXVpZXRfTmFOKCk7CiAgfQogIHN0YXRpYyBib29sIGlzX25hbihjb25zdCBUJiB4KQogIHsKICAgIHJldHVybiBzdGQ6Om51bWVyaWNfbGltaXRzPFQ+OjpoYXNfcXVpZXRfTmFOICYmICh4ICE9IHgpOwogIH0KICBzdGF0aWMgVCBlbXB0eV9sb3dlcigpCiAgewogICAgcmV0dXJuIChzdGQ6Om51bWVyaWNfbGltaXRzPFQ+OjpoYXNfcXVpZXRfTmFOID8KICAgICAgICAgICAgc3RkOjpudW1lcmljX2xpbWl0czxUPjo6cXVpZXRfTmFOKCkgOiBzdGF0aWNfY2FzdDxUPigxKSk7CiAgfQogIHN0YXRpYyBUIGVtcHR5X3VwcGVyKCkKICB7CiAgICByZXR1cm4gKHN0ZDo6bnVtZXJpY19saW1pdHM8VD46Omhhc19xdWlldF9OYU4gPwogICAgICAgICAgICBzdGQ6Om51bWVyaWNfbGltaXRzPFQ+OjpxdWlldF9OYU4oKSA6IHN0YXRpY19jYXN0PFQ+KDApKTsKICB9CiAgc3RhdGljIGJvb2wgaXNfZW1wdHkoY29uc3QgVCYgbCwgY29uc3QgVCYgdSkKICB7CiAgICByZXR1cm4gIShsIDw9IHUpOyAvLyBzYWZldHkgZm9yIHBhcnRpYWwgb3JkZXJzCiAgfQp9OwoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgQ2hlY2tpbmcgPSBjaGVja2luZ19iYXNlPFQ+LAogICAgICAgICBjbGFzcyBFeGNlcHRpb24gPSBleGNlcHRpb25fY3JlYXRlX2VtcHR5PgpzdHJ1Y3QgY2hlY2tpbmdfbm9fZW1wdHk6IENoZWNraW5nCnsKICBzdGF0aWMgVCBuYW4oKQogIHsKICAgIGFzc2VydChmYWxzZSk7CiAgICByZXR1cm4gQ2hlY2tpbmc6Om5hbigpOwogIH0KICBzdGF0aWMgVCBlbXB0eV9sb3dlcigpCiAgewogICAgRXhjZXB0aW9uKCkoKTsKICAgIHJldHVybiBDaGVja2luZzo6ZW1wdHlfbG93ZXIoKTsKICB9CiAgc3RhdGljIFQgZW1wdHlfdXBwZXIoKQogIHsKICAgIEV4Y2VwdGlvbigpKCk7CiAgICByZXR1cm4gQ2hlY2tpbmc6OmVtcHR5X3VwcGVyKCk7CiAgfQogIHN0YXRpYyBib29sIGlzX2VtcHR5KGNvbnN0IFQmLCBjb25zdCBUJikKICB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQp9OwoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgQ2hlY2tpbmcgPSBjaGVja2luZ19iYXNlPFQ+ID4Kc3RydWN0IGNoZWNraW5nX25vX25hbjogQ2hlY2tpbmcKewogIHN0YXRpYyBib29sIGlzX25hbihjb25zdCBUJikKICB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQp9OwoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgQ2hlY2tpbmcgPSBjaGVja2luZ19iYXNlPFQ+LAogICAgICAgICBjbGFzcyBFeGNlcHRpb24gPSBleGNlcHRpb25faW52YWxpZF9udW1iZXI+CnN0cnVjdCBjaGVja2luZ19jYXRjaF9uYW46IENoZWNraW5nCnsKICBzdGF0aWMgYm9vbCBpc19uYW4oY29uc3QgVCYgeCkKICB7CiAgICBpZiAoQ2hlY2tpbmc6OmlzX25hbih4KSkgRXhjZXB0aW9uKCkoKTsKICAgIHJldHVybiBmYWxzZTsKICB9Cn07Cgp0ZW1wbGF0ZTxjbGFzcyBUPgpzdHJ1Y3QgY2hlY2tpbmdfc3RyaWN0OgogIGNoZWNraW5nX25vX25hbjxULCBjaGVja2luZ19ub19lbXB0eTxUPiA+Cnt9OwoKfSAvLyBuYW1lc3BhY2UgaW50ZXJ2YWxfbGliCn0gLy8gbmFtZXNwYWNlIG51bWVyaWMKfSAvLyBuYW1lc3BhY2UgYm9vc3QKCiNlbmRpZiAvLyBCT09TVF9OVU1FUklDX0lOVEVSVkFMX0NIRUNLSU5HX0hQUAo=