Ly8gLSotIEMrKyAtKi0KLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGNvbmRpdGlvbl92YXJpYWJsZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KLy8KLy8gysrKysrKysrKysrKysrKysrKyspUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQovLwovLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgovLwovLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLwoKI2lmbmRlZiBfTElCQ1BQX0NPTkRJVElPTl9WQVJJQUJMRQojZGVmaW5lIF9MSUJDUFBfQ09ORElUSU9OX1ZBUklBQkxFCgovKgogICAgY29uZGl0aW9uX3ZhcmlhYmxlIHN5bm9wc2lzCgpuYW1lc3BhY2Ugc3RkCnsKCmVudW0gY2xhc3MgY3Zfc3RhdHVzIHsgbm9fdGltZW91dCwgdGltZW91dCB9OwoKY2xhc3MgY29uZGl0aW9uX3ZhcmlhYmxlCnsKcHVibGljOgogICAgY29uZGl0aW9uX3ZhcmlhYmxlKCk7CiAgICB+Y29uZGl0aW9uX3ZhcmlhYmxlKCk7CgogICAgY29uZGl0aW9uX3ZhcmlhYmxlKGNvbnN0IGNvbmRpdGlvbl92YXJpYWJsZSYpID0gZGVsZXRlOwogICAgY29uZGl0aW9uX3ZhcmlhYmxlJiBvcGVyYXRvcj0oY29uc3QgY29uZGl0aW9uX3ZhcmlhYmxlJikgPSBkZWxldGU7CgogICAgdm9pZCBub3RpZnlfb25lKCk7CiAgICB2b2lkIG5vdGlmeV9hbGwoKTsKCiAgICB2b2lkIHdhaXQodW5pcXVlX2xvY2s8bXV0ZXg+JiBsb2NrKTsKICAgIHRlbXBsYXRlIDxjbGFzcyBQcmVkaWNhdGU+CiAgICAgICAgdm9pZCB3YWl0KHVuaXF1ZV9sb2NrPG11dGV4PiYgbG9jaywgUHJlZGljYXRlIHByZWQpOwoKICAgIHRlbXBsYXRlIDxjbGFzcyBDbG9jaywgY2xhc3MgRHVyYXRpb24+CiAgICAgICAgY3Zfc3RhdHVzCiAgICAgICAgd2FpdF91bnRpbCh1bmlxdWVfbG9jazxtdXRleD4mIGxvY2ssCiAgICAgICAgICAgICAgICAgICBjb25zdCBjaHJvbm86OnRpbWVfcG9pbnQ8Q2xvY2ssIER1cmF0aW9uPiYgYWJzX3RpbWUpOwoKICAgIHRlbXBsYXRlIDxjbGFzcyBDbG9jaywgY2xhc3MgRHVyYXRpb24sIGNsYXNzIFByZWRpY2F0ZT4KICAgICAgICBib29sCiAgICAgICAgd2FpdF91bnRpbCh1bmlxdWVfbG9jazxtdXRleD4mIGxvY2ssCiAgICAgICAgICAgICAgICAgICBjb25zdCBjaHJvbm86OnRpbWVfcG9pbnQ8Q2xvY2ssIER1cmF0aW9uPiYgYWJzX3RpbWUsCiAgICAgICAgICAgICAgICAgICBQcmVkaWNhdGUgcHJlZCk7CgogICAgdGVtcGxhdGUgPGNsYXNzIFJlcCwgY2xhc3MgUGVyaW9kPgogICAgICAgIGN2X3N0YXR1cwogICAgICAgIHdhaXRfZm9yKHVuaXF1ZV9sb2NrPG11dGV4PiYgbG9jaywKICAgICAgICAgICAgICAgICBjb25zdCBjaHJvbm86OmR1cmF0aW9uPFJlcCwgUGVyaW9kPiYgcmVsX3RpbWUpOwoKICAgIHRlbXBsYXRlIDxjbGFzcyBSZXAsIGNsYXNzIFBlcmlvZCwgY2xhc3MgUHJlZGljYXRlPgogICAgICAgIGJvb2wKICAgICAgICB3YWl0X2Zvcih1bmlxdWVfbG9jazxtdXRleD4mIGxvY2ssCiAgICAgICAgICAgICAgICAgY29uc3QgY2hyb25vOjpkdXJhdGlvbjxSZXAsIFBlcmlvZD4mIHJlbF90aW1lLAogICAgICAgICAgICAgICAgIFByZWRpY2F0ZSBwcmVkKTsKCiAgICB0eXBlZGVmIHB0aHJlYWRfY29uZF90KiBuYXRpdmVfaGFuZGxlX3R5cGU7CiAgICBuYXRpdmVfaGFuZGxlX3R5cGUgbmF0aXZlX2hhbmRsZSgpOwp9OwoKY2xhc3MgY29uZGl0aW9uX3ZhcmlhYmxlX2FueQp7CnB1YmxpYzoKICAgIGNvbmRpdGlvbl92YXJpYWJsZV9hbnkoKTsKICAgIH5jb25kaXRpb25fdmFyaWFibGVfYW55KCk7CgogICAgY29uZGl0aW9uX3ZhcmlhYmxlX2FueShjb25zdCBjb25kaXRpb25fdmFyaWFibGVfYW55JikgPSBkZWxldGU7CiAgICBjb25kaXRpb25fdmFyaWFibGVfYW55JiBvcGVyYXRvcj0oY29uc3QgY29uZGl0aW9uX3ZhcmlhYmxlX2FueSYpID0gZGVsZXRlOwoKICAgIHZvaWQgbm90aWZ5X29uZSgpOwogICAgdm9pZCBub3RpZnlfYWxsKCk7CgogICAgdGVtcGxhdGUgPGNsYXNzIExvY2s+CiAgICAgICAgdm9pZCB3YWl0KExvY2smIGxvY2spOwogICAgdGVtcGxhdGUgPGNsYXNzIExvY2ssIGNsYXNzIFByZWRpY2F0ZT4KICAgICAgICB2b2lkIHdhaXQoTG9jayYgbG9jaywgUHJlZGljYXRlIHByZWQpOwoKICAgIHRlbXBsYXRlIDxjbGFzcyBMb2NrLCBjbGFzcyBDbG9jaywgY2xhc3MgRHVyYXRpb24+CiAgICAgICAgY3Zfc3RhdHVzCiAgICAgICAgd2FpdF91bnRpbChMb2NrJiBsb2NrLAogICAgICAgICAgICAgICAgICAgY29uc3QgY2hyb25vOjp0aW1lX3BvaW50PENsb2NrLCBEdXJhdGlvbj4mIGFic190aW1lKTsKCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgTG9jaywgY2xhc3MgQ2xvY2ssIGNsYXNzIER1cmF0aW9uLCBjbGFzcyBQcmVkaWNhdGU+CiAgICAgICAgYm9vbAogICAgICAgIHdhaXRfdW50aWwoTG9jayYgbG9jaywKICAgICAgICAgICAgICAgICAgIGNvbnN0IGNocm9ubzo6dGltZV9wb2ludDxDbG9jaywgRHVyYXRpb24+JiBhYnNfdGltZSwKICAgICAgICAgICAgICAgICAgIFByZWRpY2F0ZSBwcmVkKTsKCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgTG9jaywgY2xhc3MgUmVwLCBjbGFzcyBQZXJpb2Q+CiAgICAgICAgY3Zfc3RhdHVzCiAgICAgICAgd2FpdF9mb3IoTG9jayYgbG9jaywKICAgICAgICAgICAgICAgICBjb25zdCBjaHJvbm86OmR1cmF0aW9uPFJlcCwgUGVyaW9kPiYgcmVsX3RpbWUpOwoKICAgIHRlbXBsYXRlIDxjbGFzcyBMb2NrLCBjbGFzcyBSZXAsIGNsYXNzIFBlcmlvZCwgY2xhc3MgUHJlZGljYXRlPgogICAgICAgIGJvb2wKICAgICAgICB3YWl0X2ZvcihMb2NrJiBsb2NrLAogICAgICAgICAgICAgICAgIGNvbnN0IGNocm9ubzo6ZHVyYXRpb248UmVwLCBQZXJpb2Q+JiByZWxfdGltZSwKICAgICAgICAgICAgICAgICBQcmVkaWNhdGUgcHJlZCk7Cn07Cgp9ICAvLyBzdGQKCiovCgojaW5jbHVkZSA8X19jb25maWc+CiNpbmNsdWRlIDxfX211dGV4X2Jhc2U+CiNpbmNsdWRlIDxtZW1vcnk+CgojcHJhZ21hIEdDQyBzeXN0ZW1faGVhZGVyCgpfTElCQ1BQX0JFR0lOX05BTUVTUEFDRV9TVEQKCmNsYXNzIGNvbmRpdGlvbl92YXJpYWJsZV9hbnkKewogICAgY29uZGl0aW9uX3ZhcmlhYmxlIF9fY3ZfOwogICAgc2hhcmVkX3B0cjxtdXRleD4gIF9fbXV0XzsKcHVibGljOgogICAgY29uZGl0aW9uX3ZhcmlhYmxlX2FueSgpOwoKICAgIHZvaWQgbm90aWZ5X29uZSgpOwogICAgdm9pZCBub3RpZnlfYWxsKCk7CgogICAgdGVtcGxhdGUgPGNsYXNzIF9Mb2NrPgogICAgICAgIHZvaWQgd2FpdChfTG9jayYgX19sb2NrKTsKICAgIHRlbXBsYXRlIDxjbGFzcyBfTG9jaywgY2xhc3MgX1ByZWRpY2F0ZT4KICAgICAgICB2b2lkIHdhaXQoX0xvY2smIF9fbG9jaywgX1ByZWRpY2F0ZSBfX3ByZWQpOwoKICAgIHRlbXBsYXRlIDxjbGFzcyBfTG9jaywgY2xhc3MgX0Nsb2NrLCBjbGFzcyBfRHVyYXRpb24+CiAgICAgICAgY3Zfc3RhdHVzCiAgICAgICAgd2FpdF91bnRpbChfTG9jayYgX19sb2NrLAogICAgICAgICAgICAgICAgICAgY29uc3QgY2hyb25vOjp0aW1lX3BvaW50PF9DbG9jaywgX0R1cmF0aW9uPiYgX190KTsKCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgX0xvY2ssIGNsYXNzIF9DbG9jaywgY2xhc3MgX0R1cmF0aW9uLCBjbGFzcyBfUHJlZGljYXRlPgogICAgICAgIGJvb2wKICAgICAgICB3YWl0X3VudGlsKF9Mb2NrJiBfX2xvY2ssCiAgICAgICAgICAgICAgICAgICBjb25zdCBjaHJvbm86OnRpbWVfcG9pbnQ8X0Nsb2NrLCBfRHVyYXRpb24+JiBfX3QsCiAgICAgICAgICAgICAgICAgICBfUHJlZGljYXRlIF9fcHJlZCk7CgogICAgdGVtcGxhdGUgPGNsYXNzIF9Mb2NrLCBjbGFzcyBfUmVwLCBjbGFzcyBfUGVyaW9kPgogICAgICAgIGN2X3N0YXR1cwogICAgICAgIHdhaXRfZm9yKF9Mb2NrJiBfX2xvY2ssCiAgICAgICAgICAgICAgICAgY29uc3QgY2hyb25vOjpkdXJhdGlvbjxfUmVwLCBfUGVyaW9kPiYgX19kKTsKCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgX0xvY2ssIGNsYXNzIF9SZXAsIGNsYXNzIF9QZXJpb2QsIGNsYXNzIF9QcmVkaWNhdGU+CiAgICAgICAgYm9vbAogICAgICAgIHdhaXRfZm9yKF9Mb2NrJiBfX2xvY2ssCiAgICAgICAgICAgICAgICAgY29uc3QgY2hyb25vOjpkdXJhdGlvbjxfUmVwLCBfUGVyaW9kPiYgX19kLAogICAgICAgICAgICAgICAgIF9QcmVkaWNhdGUgX19wcmVkKTsKfTsKCmlubGluZQpjb25kaXRpb25fdmFyaWFibGVfYW55Ojpjb25kaXRpb25fdmFyaWFibGVfYW55KCkKICAgIDogX19tdXRfKG1ha2Vfc2hhcmVkPG11dGV4PigpKSB7fQoKaW5saW5lCnZvaWQKY29uZGl0aW9uX3ZhcmlhYmxlX2FueTo6bm90aWZ5X29uZSgpCnsKICAgIHtsb2NrX2d1YXJkPG11dGV4PiBfKCpfX211dF8pO30KICAgIF9fY3ZfLm5vdGlmeV9vbmUoKTsKfQoKaW5saW5lCnZvaWQKY29uZGl0aW9uX3ZhcmlhYmxlX2FueTo6bm90aWZ5X2FsbCgpCnsKICAgIHtsb2NrX2d1YXJkPG11dGV4PiBfKCpfX211dF8pO30KICAgIF9fY3ZfLm5vdGlmeV9hbGwoKTsKfQoKc3RydWN0IF9fbG9ja19leHRlcm5hbAp7CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgX0xvY2s+CiAgICB2b2lkIG9wZXJhdG9yKCkoX0xvY2sqIF9fbSkge19fbS0+bG9jaygpO30KfTsKCnRlbXBsYXRlIDxjbGFzcyBfTG9jaz4Kdm9pZApjb25kaXRpb25fdmFyaWFibGVfYW55Ojp3YWl0KF9Mb2NrJiBfX2xvY2spCnsKICAgIHNoYXJlZF9wdHI8bXV0ZXg+IF9fbXV0ID0gX19tdXRfOwogICAgdW5pcXVlX2xvY2s8bXV0ZXg+IF9fbGsoKl9fbXV0KTsKICAgIF9fbG9jay51bmxvY2soKTsKICAgIHVuaXF1ZV9wdHI8X0xvY2ssIF9fbG9ja19leHRlcm5hbD4gX18oJl9fbG9jayk7CiAgICBsb2NrX2d1YXJkPHVuaXF1ZV9sb2NrPG11dGV4PiA+IF8oX19saywgYWRvcHRfbG9jayk7CiAgICBfX2N2Xy53YWl0KF9fbGspOwp9ICAvLyBfX211dF8udW5sb2NrKCksIF9fbG9jay5sb2NrKCkKCnRlbXBsYXRlIDxjbGFzcyBfTG9jaywgY2xhc3MgX1ByZWRpY2F0ZT4KaW5saW5lCnZvaWQKY29uZGl0aW9uX3ZhcmlhYmxlX2FueTo6d2FpdChfTG9jayYgX19sb2NrLCBfUHJlZGljYXRlIF9fcHJlZCkKewogICAgd2hpbGUgKCFfX3ByZWQoKSkKICAgICAgICB3YWl0KF9fbG9jayk7Cn0KCnRlbXBsYXRlIDxjbGFzcyBfTG9jaywgY2xhc3MgX0Nsb2NrLCBjbGFzcyBfRHVyYXRpb24+CmN2X3N0YXR1cwpjb25kaXRpb25fdmFyaWFibGVfYW55Ojp3YWl0X3VudGlsKF9Mb2NrJiBfX2xvY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hyb25vOjp0aW1lX3BvaW50PF9DbG9jaywgX0R1cmF0aW9uPiYgX190KQp7CiAgICBzaGFyZWRfcHRyPG11dGV4PiBfX211dCA9IF9fbXV0XzsKICAgIHVuaXF1ZV9sb2NrPG11dGV4PiBfX2xrKCpfX211dCk7CiAgICBfX2xvY2sudW5sb2NrKCk7CiAgICB1bmlxdWVfcHRyPF9Mb2NrLCBfX2xvY2tfZXh0ZXJuYWw+IF9fKCZfX2xvY2spOwogICAgbG9ja19ndWFyZDx1bmlxdWVfbG9jazxtdXRleD4gPiBfKF9fbGssIGFkb3B0X2xvY2spOwogICAgcmV0dXJuIF9fY3ZfLndhaXRfdW50aWwoX19saywgX190KTsKfSAgLy8gX19tdXRfLnVubG9jaygpLCBfX2xvY2subG9jaygpCgp0ZW1wbGF0ZSA8Y2xhc3MgX0xvY2ssIGNsYXNzIF9DbG9jaywgY2xhc3MgX0R1cmF0aW9uLCBjbGFzcyBfUHJlZGljYXRlPgppbmxpbmUKYm9vbApjb25kaXRpb25fdmFyaWFibGVfYW55Ojp3YWl0X3VudGlsKF9Mb2NrJiBfX2xvY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hyb25vOjp0aW1lX3BvaW50PF9DbG9jaywgX0R1cmF0aW9uPiYgX190LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9QcmVkaWNhdGUgX19wcmVkKQp7CiAgICB3aGlsZSAoIV9fcHJlZCgpKQogICAgICAgIGlmICh3YWl0X3VudGlsKF9fbG9jaywgX190KSA9PSBjdl9zdGF0dXM6OnRpbWVvdXQpCiAgICAgICAgICAgIHJldHVybiBfX3ByZWQoKTsKICAgIHJldHVybiB0cnVlOwp9Cgp0ZW1wbGF0ZSA8Y2xhc3MgX0xvY2ssIGNsYXNzIF9SZXAsIGNsYXNzIF9QZXJpb2Q+CmlubGluZQpjdl9zdGF0dXMKY29uZGl0aW9uX3ZhcmlhYmxlX2FueTo6d2FpdF9mb3IoX0xvY2smIF9fbG9jaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hyb25vOjpkdXJhdGlvbjxfUmVwLCBfUGVyaW9kPiYgX19kKQp7CiAgICByZXR1cm4gd2FpdF91bnRpbChfX2xvY2ssIGNocm9ubzo6bW9ub3RvbmljX2Nsb2NrOjpub3coKSArIF9fZCk7Cn0KCnRlbXBsYXRlIDxjbGFzcyBfTG9jaywgY2xhc3MgX1JlcCwgY2xhc3MgX1BlcmlvZCwgY2xhc3MgX1ByZWRpY2F0ZT4KaW5saW5lCmJvb2wKY29uZGl0aW9uX3ZhcmlhYmxlX2FueTo6d2FpdF9mb3IoX0xvY2smIF9fbG9jaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hyb25vOjpkdXJhdGlvbjxfUmVwLCBfUGVyaW9kPiYgX19kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfUHJlZGljYXRlIF9fcHJlZCkKewogICAgcmV0dXJuIHdhaXRfdW50aWwoX19sb2NrLCBjaHJvbm86Om1vbm90b25pY19jbG9jazo6bm93KCkgKyBfX2QsCiAgICAgICAgICAgICAgICAgICAgICBfU1REOjptb3ZlKF9fcHJlZCkpOwp9CgpfTElCQ1BQX0VORF9OQU1FU1BBQ0VfU1RECgojZW5kaWYgIC8vIF9MSUJDUFBfQ09ORElUSU9OX1ZBUklBQkxFCg==