LyogQm9vc3QgaW50ZXJ2YWwvdXRpbGl0eS5ocHAgdGVtcGxhdGUgaW1wbGVtZW50YXRpb24gZmlsZQogKgogKiBDb3B5cmlnaHQgMjAwMCBKZW5zIE1hdXJlcgogKiBDb3B5cmlnaHQgMjAwMi0yMDAzIEhlcnbpIEJy9m5uaW1hbm4sIEd1aWxsYXVtZSBNZWxxdWlvbmQsIFN5bHZhaW4gUGlvbgogKgogKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQm9vc3QgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjAuCiAqIChTZWUgYWNjb21wYW55aW5nIGZpbGUgTElDRU5TRV8xXzAudHh0IG9yCiAqIGNvcHkgYXQgaHR0cDovL3d3dy5ib29zdC5vcmcvTElDRU5TRV8xXzAudHh0KQogKi8KCiNpZm5kZWYgQk9PU1RfTlVNRVJJQ19JTlRFUlZBTF9VVElMSVRZX0hQUAojZGVmaW5lIEJPT1NUX05VTUVSSUNfSU5URVJWQUxfVVRJTElUWV9IUFAKCiNpbmNsdWRlIDxib29zdC9jb25maWcuaHBwPgojaW5jbHVkZSA8Ym9vc3QvbnVtZXJpYy9pbnRlcnZhbC9kZXRhaWwvaW50ZXJ2YWxfcHJvdG90eXBlLmhwcD4KI2luY2x1ZGUgPGJvb3N0L251bWVyaWMvaW50ZXJ2YWwvZGV0YWlsL3Rlc3RfaW5wdXQuaHBwPgojaW5jbHVkZSA8Ym9vc3QvbnVtZXJpYy9pbnRlcnZhbC9kZXRhaWwvYnVncy5ocHA+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDx1dGlsaXR5PgoKLyoKICogSW1wbGVtZW50YXRpb24gb2Ygc2ltcGxlIGZ1bmN0aW9ucwogKi8KCm5hbWVzcGFjZSBib29zdCB7Cm5hbWVzcGFjZSBudW1lcmljIHsKCi8qCiAqIFV0aWxpdHkgRnVuY3Rpb25zCiAqLwoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQpjb25zdCBUJiBsb3dlcihjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHgpCnsKICByZXR1cm4geC5sb3dlcigpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmNvbnN0IFQmIHVwcGVyKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCkKewogIHJldHVybiB4LnVwcGVyKCk7Cn0KCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFBvbGljaWVzPiBpbmxpbmUKVCBjaGVja2VkX2xvd2VyKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCkKewogIGlmIChlbXB0eSh4KSkgewogICAgdHlwZWRlZiB0eXBlbmFtZSBQb2xpY2llczo6Y2hlY2tpbmcgY2hlY2tpbmc7CiAgICByZXR1cm4gY2hlY2tpbmc6Om5hbigpOwogIH0KICByZXR1cm4geC5sb3dlcigpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lClQgY2hlY2tlZF91cHBlcihjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHgpCnsKICBpZiAoZW1wdHkoeCkpIHsKICAgIHR5cGVkZWYgdHlwZW5hbWUgUG9saWNpZXM6OmNoZWNraW5nIGNoZWNraW5nOwogICAgcmV0dXJuIGNoZWNraW5nOjpuYW4oKTsKICB9CiAgcmV0dXJuIHgudXBwZXIoKTsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQpUIHdpZHRoKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCkKewogIGlmIChpbnRlcnZhbF9saWI6OmRldGFpbDo6dGVzdF9pbnB1dCh4KSkgcmV0dXJuIHN0YXRpY19jYXN0PFQ+KDApOwogIHR5cGVuYW1lIFBvbGljaWVzOjpyb3VuZGluZyBybmQ7CiAgcmV0dXJuIHJuZC5zdWJfdXAoeC51cHBlcigpLCB4Lmxvd2VyKCkpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lClQgbWVkaWFuKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCkKewogIGlmIChpbnRlcnZhbF9saWI6OmRldGFpbDo6dGVzdF9pbnB1dCh4KSkgewogICAgdHlwZWRlZiB0eXBlbmFtZSBQb2xpY2llczo6Y2hlY2tpbmcgY2hlY2tpbmc7CiAgICByZXR1cm4gY2hlY2tpbmc6Om5hbigpOwogIH0KICB0eXBlbmFtZSBQb2xpY2llczo6cm91bmRpbmcgcm5kOwogIHJldHVybiBybmQubWVkaWFuKHgubG93ZXIoKSwgeC51cHBlcigpKTsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4gd2lkZW4oY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4LCBjb25zdCBUJiB2KQp7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgpKQogICAgcmV0dXJuIGludGVydmFsPFQsIFBvbGljaWVzPjo6ZW1wdHkoKTsKICB0eXBlbmFtZSBQb2xpY2llczo6cm91bmRpbmcgcm5kOwogIHJldHVybiBpbnRlcnZhbDxULCBQb2xpY2llcz4ocm5kLnN1Yl9kb3duKHgubG93ZXIoKSwgdiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBybmQuYWRkX3VwICAoeC51cHBlcigpLCB2KSwgdHJ1ZSk7Cn0KCi8qCiAqIFNldC1saWtlIG9wZXJhdGlvbnMKICovCgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmJvb2wgZW1wdHkoY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4KQp7CiAgcmV0dXJuIGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmJvb2wgemVyb19pbihjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHgpCnsKICBpZiAoaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoeCkpIHJldHVybiBmYWxzZTsKICByZXR1cm4gKCFpbnRlcnZhbF9saWI6OnVzZXI6OmlzX3Bvcyh4Lmxvd2VyKCkpKSAmJgogICAgICAgICAoIWludGVydmFsX2xpYjo6dXNlcjo6aXNfbmVnKHgudXBwZXIoKSkpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmJvb2wgaW5femVybyhjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHgpIC8vIERFUFJFQ0FURUQKewogIHJldHVybiB6ZXJvX2luPFQsIFBvbGljaWVzPih4KTsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQpib29sIGluKGNvbnN0IFQmIHgsIGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeSkKewogIGlmIChpbnRlcnZhbF9saWI6OmRldGFpbDo6dGVzdF9pbnB1dCh4LCB5KSkgcmV0dXJuIGZhbHNlOwogIHJldHVybiB5Lmxvd2VyKCkgPD0geCAmJiB4IDw9IHkudXBwZXIoKTsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQpib29sIHN1YnNldChjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHgsCiAgICAgICAgICAgIGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeSkKewogIGlmIChlbXB0eSh4KSkgcmV0dXJuIHRydWU7CiAgcmV0dXJuICFlbXB0eSh5KSAmJiB5Lmxvd2VyKCkgPD0geC5sb3dlcigpICYmIHgudXBwZXIoKSA8PSB5LnVwcGVyKCk7Cn0KCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFBvbGljaWVzMSwgY2xhc3MgUG9saWNpZXMyPiBpbmxpbmUKYm9vbCBwcm9wZXJfc3Vic2V0KGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzMT4mIHgsCiAgICAgICAgICAgICAgICAgICBjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llczI+JiB5KQp7CiAgaWYgKGVtcHR5KHkpKSByZXR1cm4gZmFsc2U7CiAgaWYgKGVtcHR5KHgpKSByZXR1cm4gdHJ1ZTsKICByZXR1cm4geS5sb3dlcigpIDw9IHgubG93ZXIoKSAmJiB4LnVwcGVyKCkgPD0geS51cHBlcigpICYmCiAgICAgICAgICh5Lmxvd2VyKCkgIT0geC5sb3dlcigpIHx8IHgudXBwZXIoKSAhPSB5LnVwcGVyKCkpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llczEsIGNsYXNzIFBvbGljaWVzMj4gaW5saW5lCmJvb2wgb3ZlcmxhcChjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llczE+JiB4LAogICAgICAgICAgICAgY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXMyPiYgeSkKewogIGlmIChpbnRlcnZhbF9saWI6OmRldGFpbDo6dGVzdF9pbnB1dCh4LCB5KSkgcmV0dXJuIGZhbHNlOwogIHJldHVybiB4Lmxvd2VyKCkgPD0geS5sb3dlcigpICYmIHkubG93ZXIoKSA8PSB4LnVwcGVyKCkgfHwKICAgICAgICAgeS5sb3dlcigpIDw9IHgubG93ZXIoKSAmJiB4Lmxvd2VyKCkgPD0geS51cHBlcigpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmJvb2wgc2luZ2xldG9uKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCkKewogcmV0dXJuICFlbXB0eSh4KSAmJiB4Lmxvd2VyKCkgPT0geC51cHBlcigpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llczEsIGNsYXNzIFBvbGljaWVzMj4gaW5saW5lCmJvb2wgZXF1YWwoY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXMxPiYgeCwgY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXMyPiYgeSkKewogIGlmIChlbXB0eSh4KSkgcmV0dXJuIGVtcHR5KHkpOwogIHJldHVybiAhZW1wdHkoeSkgJiYgeC5sb3dlcigpID09IHkubG93ZXIoKSAmJiB4LnVwcGVyKCkgPT0geS51cHBlcigpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBpbnRlcnNlY3QoY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeSkKewogIEJPT1NUX1VTSU5HX1NURF9NSU4oKTsKICBCT09TVF9VU0lOR19TVERfTUFYKCk7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgsIHkpKQogICAgcmV0dXJuIGludGVydmFsPFQsIFBvbGljaWVzPjo6ZW1wdHkoKTsKICBjb25zdCBUJiBsID0gbWF4IEJPT1NUX1BSRVZFTlRfTUFDUk9fU1VCU1RJVFVUSU9OKHgubG93ZXIoKSwgeS5sb3dlcigpKTsKICBjb25zdCBUJiB1ID0gbWluIEJPT1NUX1BSRVZFTlRfTUFDUk9fU1VCU1RJVFVUSU9OKHgudXBwZXIoKSwgeS51cHBlcigpKTsKICBpZiAobCA8PSB1KSByZXR1cm4gaW50ZXJ2YWw8VCwgUG9saWNpZXM+KGwsIHUsIHRydWUpOwogIGVsc2UgICAgICAgIHJldHVybiBpbnRlcnZhbDxULCBQb2xpY2llcz46OmVtcHR5KCk7Cn0KCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFBvbGljaWVzPiBpbmxpbmUKaW50ZXJ2YWw8VCwgUG9saWNpZXM+IGh1bGwoY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHkpCnsKICBCT09TVF9VU0lOR19TVERfTUlOKCk7CiAgQk9PU1RfVVNJTkdfU1REX01BWCgpOwogIGJvb2wgYmFkX3ggPSBpbnRlcnZhbF9saWI6OmRldGFpbDo6dGVzdF9pbnB1dCh4KTsKICBib29sIGJhZF95ID0gaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoeSk7CiAgaWYgKGJhZF94KQogICAgaWYgKGJhZF95KSByZXR1cm4gaW50ZXJ2YWw8VCwgUG9saWNpZXM+OjplbXB0eSgpOwogICAgZWxzZSAgICAgICByZXR1cm4geTsKICBlbHNlCiAgICBpZiAoYmFkX3kpIHJldHVybiB4OwogIHJldHVybiBpbnRlcnZhbDxULCBQb2xpY2llcz4obWluIEJPT1NUX1BSRVZFTlRfTUFDUk9fU1VCU1RJVFVUSU9OKHgubG93ZXIoKSwgeS5sb3dlcigpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heCBCT09TVF9QUkVWRU5UX01BQ1JPX1NVQlNUSVRVVElPTih4LnVwcGVyKCksIHkudXBwZXIoKSksIHRydWUpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBodWxsKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCwgY29uc3QgVCYgeSkKewogIEJPT1NUX1VTSU5HX1NURF9NSU4oKTsKICBCT09TVF9VU0lOR19TVERfTUFYKCk7CiAgYm9vbCBiYWRfeCA9IGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgpOwogIGJvb2wgYmFkX3kgPSBpbnRlcnZhbF9saWI6OmRldGFpbDo6dGVzdF9pbnB1dDxULCBQb2xpY2llcz4oeSk7CiAgaWYgKGJhZF95KQogICAgaWYgKGJhZF94KSByZXR1cm4gaW50ZXJ2YWw8VCwgUG9saWNpZXM+OjplbXB0eSgpOwogICAgZWxzZSAgICAgICByZXR1cm4geDsKICBlbHNlCiAgICBpZiAoYmFkX3gpIHJldHVybiBpbnRlcnZhbDxULCBQb2xpY2llcz4oeSwgeSwgdHJ1ZSk7CiAgcmV0dXJuIGludGVydmFsPFQsIFBvbGljaWVzPihtaW4gQk9PU1RfUFJFVkVOVF9NQUNST19TVUJTVElUVVRJT04oeC5sb3dlcigpLCB5KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heCBCT09TVF9QUkVWRU5UX01BQ1JPX1NVQlNUSVRVVElPTih4LnVwcGVyKCksIHkpLCB0cnVlKTsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4gaHVsbChjb25zdCBUJiB4LCBjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHkpCnsKICBCT09TVF9VU0lOR19TVERfTUlOKCk7CiAgQk9PU1RfVVNJTkdfU1REX01BWCgpOwogIGJvb2wgYmFkX3ggPSBpbnRlcnZhbF9saWI6OmRldGFpbDo6dGVzdF9pbnB1dDxULCBQb2xpY2llcz4oeCk7CiAgYm9vbCBiYWRfeSA9IGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHkpOwogIGlmIChiYWRfeCkKICAgIGlmIChiYWRfeSkgcmV0dXJuIGludGVydmFsPFQsIFBvbGljaWVzPjo6ZW1wdHkoKTsKICAgIGVsc2UgICAgICAgcmV0dXJuIHk7CiAgZWxzZQogICAgaWYgKGJhZF95KSByZXR1cm4gaW50ZXJ2YWw8VCwgUG9saWNpZXM+KHgsIHgsIHRydWUpOwogIHJldHVybiBpbnRlcnZhbDxULCBQb2xpY2llcz4obWluIEJPT1NUX1BSRVZFTlRfTUFDUk9fU1VCU1RJVFVUSU9OKHgsIHkubG93ZXIoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXggQk9PU1RfUFJFVkVOVF9NQUNST19TVUJTVElUVVRJT04oeCwgeS51cHBlcigpKSwgdHJ1ZSk7Cn0KCnRlbXBsYXRlPGNsYXNzIFQ+IGlubGluZQppbnRlcnZhbDxUPiBodWxsKGNvbnN0IFQmIHgsIGNvbnN0IFQmIHkpCnsKICByZXR1cm4gaW50ZXJ2YWw8VD46Omh1bGwoeCwgeSk7Cn0KCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFBvbGljaWVzPiBpbmxpbmUKc3RkOjpwYWlyPGludGVydmFsPFQsIFBvbGljaWVzPiwgaW50ZXJ2YWw8VCwgUG9saWNpZXM+ID4KYmlzZWN0KGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCkKewogIHR5cGVkZWYgaW50ZXJ2YWw8VCwgUG9saWNpZXM+IEk7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgpKQogICAgcmV0dXJuIHN0ZDo6cGFpcjxJLEk+KEk6OmVtcHR5KCksIEk6OmVtcHR5KCkpOwogIGNvbnN0IFQgbSA9IG1lZGlhbih4KTsKICByZXR1cm4gc3RkOjpwYWlyPEksST4oSSh4Lmxvd2VyKCksIG0sIHRydWUpLCBJKG0sIHgudXBwZXIoKSwgdHJ1ZSkpOwp9CgovKgogKiBFbGVtZW50YXJ5IGZ1bmN0aW9ucwogKi8KCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFBvbGljaWVzPiBpbmxpbmUKVCBub3JtKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCkKewogIHR5cGVkZWYgaW50ZXJ2YWw8VCwgUG9saWNpZXM+IEk7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgpKSB7CiAgICB0eXBlZGVmIHR5cGVuYW1lIFBvbGljaWVzOjpjaGVja2luZyBjaGVja2luZzsKICAgIHJldHVybiBjaGVja2luZzo6bmFuKCk7CiAgfQogIEJPT1NUX1VTSU5HX1NURF9NQVgoKTsKICByZXR1cm4gbWF4IEJPT1NUX1BSRVZFTlRfTUFDUk9fU1VCU1RJVFVUSU9OKHN0YXRpY19jYXN0PFQ+KC14Lmxvd2VyKCkpLCB4LnVwcGVyKCkpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBhYnMoY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4KQp7CiAgdHlwZWRlZiBpbnRlcnZhbDxULCBQb2xpY2llcz4gSTsKICBpZiAoaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoeCkpCiAgICByZXR1cm4gSTo6ZW1wdHkoKTsKICBpZiAoIWludGVydmFsX2xpYjo6dXNlcjo6aXNfbmVnKHgubG93ZXIoKSkpIHJldHVybiB4OwogIGlmICghaW50ZXJ2YWxfbGliOjp1c2VyOjppc19wb3MoeC51cHBlcigpKSkgcmV0dXJuIC14OwogIEJPT1NUX1VTSU5HX1NURF9NQVgoKTsKICByZXR1cm4gSShzdGF0aWNfY2FzdDxUPigwKSwgbWF4IEJPT1NUX1BSRVZFTlRfTUFDUk9fU1VCU1RJVFVUSU9OKHN0YXRpY19jYXN0PFQ+KC14Lmxvd2VyKCkpLCB4LnVwcGVyKCkpLCB0cnVlKTsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4gbWF4IEJPT1NUX1BSRVZFTlRfTUFDUk9fU1VCU1RJVFVUSU9OIChjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeSkKewogIHR5cGVkZWYgaW50ZXJ2YWw8VCwgUG9saWNpZXM+IEk7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgsIHkpKQogICAgcmV0dXJuIEk6OmVtcHR5KCk7CiAgQk9PU1RfVVNJTkdfU1REX01BWCgpOwogIHJldHVybiBJKG1heCBCT09TVF9QUkVWRU5UX01BQ1JPX1NVQlNUSVRVVElPTih4Lmxvd2VyKCksIHkubG93ZXIoKSksIG1heCBCT09TVF9QUkVWRU5UX01BQ1JPX1NVQlNUSVRVVElPTih4LnVwcGVyKCksIHkudXBwZXIoKSksIHRydWUpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBtYXggQk9PU1RfUFJFVkVOVF9NQUNST19TVUJTVElUVVRJT04gKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCwgY29uc3QgVCYgeSkKewogIHR5cGVkZWYgaW50ZXJ2YWw8VCwgUG9saWNpZXM+IEk7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgsIHkpKQogICAgcmV0dXJuIEk6OmVtcHR5KCk7CiAgQk9PU1RfVVNJTkdfU1REX01BWCgpOwogIHJldHVybiBJKG1heCBCT09TVF9QUkVWRU5UX01BQ1JPX1NVQlNUSVRVVElPTih4Lmxvd2VyKCksIHkpLCBtYXggQk9PU1RfUFJFVkVOVF9NQUNST19TVUJTVElUVVRJT04oeC51cHBlcigpLCB5KSwgdHJ1ZSk7Cn0KCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFBvbGljaWVzPiBpbmxpbmUKaW50ZXJ2YWw8VCwgUG9saWNpZXM+IG1heCBCT09TVF9QUkVWRU5UX01BQ1JPX1NVQlNUSVRVVElPTiAoY29uc3QgVCYgeCwgY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB5KQp7CiAgdHlwZWRlZiBpbnRlcnZhbDxULCBQb2xpY2llcz4gSTsKICBpZiAoaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoeCwgeSkpCiAgICByZXR1cm4gSTo6ZW1wdHkoKTsKICBCT09TVF9VU0lOR19TVERfTUFYKCk7CiAgcmV0dXJuIEkobWF4IEJPT1NUX1BSRVZFTlRfTUFDUk9fU1VCU1RJVFVUSU9OKHgsIHkubG93ZXIoKSksIG1heCBCT09TVF9QUkVWRU5UX01BQ1JPX1NVQlNUSVRVVElPTih4LCB5LnVwcGVyKCkpLCB0cnVlKTsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4gbWluIEJPT1NUX1BSRVZFTlRfTUFDUk9fU1VCU1RJVFVUSU9OIChjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeSkKewogIHR5cGVkZWYgaW50ZXJ2YWw8VCwgUG9saWNpZXM+IEk7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgsIHkpKQogICAgcmV0dXJuIEk6OmVtcHR5KCk7CiAgQk9PU1RfVVNJTkdfU1REX01JTigpOwogIHJldHVybiBJKG1pbiBCT09TVF9QUkVWRU5UX01BQ1JPX1NVQlNUSVRVVElPTih4Lmxvd2VyKCksIHkubG93ZXIoKSksIG1pbiBCT09TVF9QUkVWRU5UX01BQ1JPX1NVQlNUSVRVVElPTih4LnVwcGVyKCksIHkudXBwZXIoKSksIHRydWUpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBtaW4gQk9PU1RfUFJFVkVOVF9NQUNST19TVUJTVElUVVRJT04gKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCwgY29uc3QgVCYgeSkKewogIHR5cGVkZWYgaW50ZXJ2YWw8VCwgUG9saWNpZXM+IEk7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgsIHkpKQogICAgcmV0dXJuIEk6OmVtcHR5KCk7CiAgQk9PU1RfVVNJTkdfU1REX01JTigpOwogIHJldHVybiBJKG1pbiBCT09TVF9QUkVWRU5UX01BQ1JPX1NVQlNUSVRVVElPTih4Lmxvd2VyKCksIHkpLCBtaW4gQk9PU1RfUFJFVkVOVF9NQUNST19TVUJTVElUVVRJT04oeC51cHBlcigpLCB5KSwgdHJ1ZSk7Cn0KCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFBvbGljaWVzPiBpbmxpbmUKaW50ZXJ2YWw8VCwgUG9saWNpZXM+IG1pbiBCT09TVF9QUkVWRU5UX01BQ1JPX1NVQlNUSVRVVElPTiAoY29uc3QgVCYgeCwgY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB5KQp7CiAgdHlwZWRlZiBpbnRlcnZhbDxULCBQb2xpY2llcz4gSTsKICBpZiAoaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoeCwgeSkpCiAgICByZXR1cm4gSTo6ZW1wdHkoKTsKICBCT09TVF9VU0lOR19TVERfTUlOKCk7CiAgcmV0dXJuIEkobWluIEJPT1NUX1BSRVZFTlRfTUFDUk9fU1VCU1RJVFVUSU9OKHgsIHkubG93ZXIoKSksIG1pbiBCT09TVF9QUkVWRU5UX01BQ1JPX1NVQlNUSVRVVElPTih4LCB5LnVwcGVyKCkpLCB0cnVlKTsKfQoKfSAvLyBuYW1lc3BhY2UgbnVtZXJpYwp9IC8vIG5hbWVzcGFjZSBib29zdAoKI2VuZGlmIC8vIEJPT1NUX05VTUVSSUNfSU5URVJWQUxfVVRJTElUWV9IUFAK