LyogQm9vc3QgaW50ZXJ2YWwvYXJpdGgyLmhwcCB0ZW1wbGF0ZSBpbXBsZW1lbnRhdGlvbiBmaWxlCiAqCiAqIFRoaXMgaGVhZGVyIHByb3ZpZGVzIHNvbWUgYXV4aWxpYXJ5IGFyaXRobWV0aWMKICogZnVuY3Rpb25zOiBmbW9kLCBzcXJ0LCBzcXVhcmUsIHBvdiwgaW52ZXJzZSBhbmQKICogYSBtdWx0aS1pbnRlcnZhbCBkaXZpc2lvbi4KICoKICogQ29weXJpZ2h0IDIwMDItMjAwMyBIZXJ26SBCcvZubmltYW5uLCBHdWlsbGF1bWUgTWVscXVpb25kLCBTeWx2YWluIFBpb24KICoKICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJvb3N0IFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4wLgogKiAoU2VlIGFjY29tcGFueWluZyBmaWxlIExJQ0VOU0VfMV8wLnR4dCBvcgogKiBjb3B5IGF0IGh0dHA6Ly93d3cuYm9vc3Qub3JnL0xJQ0VOU0VfMV8wLnR4dCkKICovCgojaWZuZGVmIEJPT1NUX05VTUVSSUNfSU5URVJWQUxfQVJJVEgyX0hQUAojZGVmaW5lIEJPT1NUX05VTUVSSUNfSU5URVJWQUxfQVJJVEgyX0hQUAoKI2luY2x1ZGUgPGJvb3N0L2NvbmZpZy5ocHA+CiNpbmNsdWRlIDxib29zdC9udW1lcmljL2ludGVydmFsL2RldGFpbC9pbnRlcnZhbF9wcm90b3R5cGUuaHBwPgojaW5jbHVkZSA8Ym9vc3QvbnVtZXJpYy9pbnRlcnZhbC9kZXRhaWwvdGVzdF9pbnB1dC5ocHA+CiNpbmNsdWRlIDxib29zdC9udW1lcmljL2ludGVydmFsL2RldGFpbC9idWdzLmhwcD4KI2luY2x1ZGUgPGJvb3N0L251bWVyaWMvaW50ZXJ2YWwvZGV0YWlsL2RpdmlzaW9uLmhwcD4KI2luY2x1ZGUgPGJvb3N0L251bWVyaWMvaW50ZXJ2YWwvYXJpdGguaHBwPgojaW5jbHVkZSA8Ym9vc3QvbnVtZXJpYy9pbnRlcnZhbC9wb2xpY2llcy5ocHA+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxjYXNzZXJ0PgojaW5jbHVkZSA8Ym9vc3QvY29uZmlnL25vX3RyMS9jbWF0aC5ocHA+CgpuYW1lc3BhY2UgYm9vc3QgewpuYW1lc3BhY2UgbnVtZXJpYyB7Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBmbW9kKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB5KQp7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgsIHkpKQogICAgcmV0dXJuIGludGVydmFsPFQsIFBvbGljaWVzPjo6ZW1wdHkoKTsKICB0eXBlbmFtZSBQb2xpY2llczo6cm91bmRpbmcgcm5kOwogIHR5cGVkZWYgdHlwZW5hbWUgaW50ZXJ2YWxfbGliOjp1bnByb3RlY3Q8aW50ZXJ2YWw8VCwgUG9saWNpZXM+ID46OnR5cGUgSTsKICBUIGNvbnN0ICZ5YiA9IGludGVydmFsX2xpYjo6dXNlcjo6aXNfbmVnKHgubG93ZXIoKSkgPyB5Lmxvd2VyKCkgOiB5LnVwcGVyKCk7CiAgVCBuID0gcm5kLmludF9kb3duKHJuZC5kaXZfZG93bih4Lmxvd2VyKCksIHliKSk7CiAgcmV0dXJuIChjb25zdCBJJil4IC0gbiAqIChjb25zdCBJJil5Owp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBmbW9kKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCwgY29uc3QgVCYgeSkKewogIGlmIChpbnRlcnZhbF9saWI6OmRldGFpbDo6dGVzdF9pbnB1dCh4LCB5KSkKICAgIHJldHVybiBpbnRlcnZhbDxULCBQb2xpY2llcz46OmVtcHR5KCk7CiAgdHlwZW5hbWUgUG9saWNpZXM6OnJvdW5kaW5nIHJuZDsKICB0eXBlZGVmIHR5cGVuYW1lIGludGVydmFsX2xpYjo6dW5wcm90ZWN0PGludGVydmFsPFQsIFBvbGljaWVzPiA+Ojp0eXBlIEk7CiAgVCBuID0gcm5kLmludF9kb3duKHJuZC5kaXZfZG93bih4Lmxvd2VyKCksIHkpKTsKICByZXR1cm4gKGNvbnN0IEkmKXggLSBuICogSSh5KTsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4gZm1vZChjb25zdCBUJiB4LCBjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHkpCnsKICBpZiAoaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoeCwgeSkpCiAgICByZXR1cm4gaW50ZXJ2YWw8VCwgUG9saWNpZXM+OjplbXB0eSgpOwogIHR5cGVuYW1lIFBvbGljaWVzOjpyb3VuZGluZyBybmQ7CiAgdHlwZWRlZiB0eXBlbmFtZSBpbnRlcnZhbF9saWI6OnVucHJvdGVjdDxpbnRlcnZhbDxULCBQb2xpY2llcz4gPjo6dHlwZSBJOwogIFQgY29uc3QgJnliID0gaW50ZXJ2YWxfbGliOjp1c2VyOjppc19uZWcoeCkgPyB5Lmxvd2VyKCkgOiB5LnVwcGVyKCk7CiAgVCBuID0gcm5kLmludF9kb3duKHJuZC5kaXZfZG93bih4LCB5YikpOwogIHJldHVybiB4IC0gbiAqIChjb25zdCBJJil5Owp9CgpuYW1lc3BhY2UgaW50ZXJ2YWxfbGliIHsKCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFBvbGljaWVzPiBpbmxpbmUKaW50ZXJ2YWw8VCwgUG9saWNpZXM+IGRpdmlzaW9uX3BhcnQxKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeSwgYm9vbCYgYikKewogIHR5cGVkZWYgaW50ZXJ2YWw8VCwgUG9saWNpZXM+IEk7CiAgYiA9IGZhbHNlOwogIGlmIChkZXRhaWw6OnRlc3RfaW5wdXQoeCwgeSkpCiAgICByZXR1cm4gSTo6ZW1wdHkoKTsKICBpZiAoemVyb19pbih5KSkKICAgIGlmICghdXNlcjo6aXNfemVybyh5Lmxvd2VyKCkpKQogICAgICBpZiAoIXVzZXI6OmlzX3plcm8oeS51cHBlcigpKSkKICAgICAgICByZXR1cm4gZGV0YWlsOjpkaXZfemVyb19wYXJ0MSh4LCB5LCBiKTsKICAgICAgZWxzZQogICAgICAgIHJldHVybiBkZXRhaWw6OmRpdl9uZWdhdGl2ZSh4LCB5Lmxvd2VyKCkpOwogICAgZWxzZQogICAgICBpZiAoIXVzZXI6OmlzX3plcm8oeS51cHBlcigpKSkKICAgICAgICByZXR1cm4gZGV0YWlsOjpkaXZfcG9zaXRpdmUoeCwgeS51cHBlcigpKTsKICAgICAgZWxzZQogICAgICAgIHJldHVybiBJOjplbXB0eSgpOwogIGVsc2UKICAgIHJldHVybiBkZXRhaWw6OmRpdl9ub25femVybyh4LCB5KTsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4gZGl2aXNpb25fcGFydDIoY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB5LCBib29sIGIgPSB0cnVlKQp7CiAgaWYgKCFiKSByZXR1cm4gaW50ZXJ2YWw8VCwgUG9saWNpZXM+OjplbXB0eSgpOwogIHJldHVybiBkZXRhaWw6OmRpdl96ZXJvX3BhcnQyKHgsIHkpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBtdWx0aXBsaWNhdGl2ZV9pbnZlcnNlKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCkKewogIHR5cGVkZWYgaW50ZXJ2YWw8VCwgUG9saWNpZXM+IEk7CiAgaWYgKGRldGFpbDo6dGVzdF9pbnB1dCh4KSkKICAgIHJldHVybiBJOjplbXB0eSgpOwogIFQgb25lID0gc3RhdGljX2Nhc3Q8VD4oMSk7CiAgdHlwZW5hbWUgUG9saWNpZXM6OnJvdW5kaW5nIHJuZDsKICBpZiAoemVyb19pbih4KSkgewogICAgdHlwZWRlZiB0eXBlbmFtZSBQb2xpY2llczo6Y2hlY2tpbmcgY2hlY2tpbmc7CiAgICBpZiAoIXVzZXI6OmlzX3plcm8oeC5sb3dlcigpKSkKICAgICAgaWYgKCF1c2VyOjppc196ZXJvKHgudXBwZXIoKSkpCiAgICAgICAgcmV0dXJuIEk6Ondob2xlKCk7CiAgICAgIGVsc2UKICAgICAgICByZXR1cm4gSShjaGVja2luZzo6bmVnX2luZigpLCBybmQuZGl2X3VwKG9uZSwgeC5sb3dlcigpKSwgdHJ1ZSk7CiAgICBlbHNlCiAgICAgIGlmICghdXNlcjo6aXNfemVybyh4LnVwcGVyKCkpKQogICAgICAgIHJldHVybiBJKHJuZC5kaXZfZG93bihvbmUsIHgudXBwZXIoKSksIGNoZWNraW5nOjpwb3NfaW5mKCksIHRydWUpOwogICAgICBlbHNlCiAgICAgICAgcmV0dXJuIEk6OmVtcHR5KCk7CiAgfSBlbHNlIAogICAgcmV0dXJuIEkocm5kLmRpdl9kb3duKG9uZSwgeC51cHBlcigpKSwgcm5kLmRpdl91cChvbmUsIHgubG93ZXIoKSksIHRydWUpOwp9CgpuYW1lc3BhY2UgZGV0YWlsIHsKCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFJvdW5kaW5nPiBpbmxpbmUKVCBwb3dfZG4oY29uc3QgVCYgeF8sIGludCBwd3IsIFJvdW5kaW5nJiBybmQpIC8vIHggYW5kIHB3ciBhcmUgcG9zaXRpdmUKewogIFQgeCA9IHhfOwogIFQgeSA9IChwd3IgJiAxKSA/IHhfIDogc3RhdGljX2Nhc3Q8VD4oMSk7CiAgcHdyID4+PSAxOwogIHdoaWxlIChwd3IgPiAwKSB7CiAgICB4ID0gcm5kLm11bF9kb3duKHgsIHgpOwogICAgaWYgKHB3ciAmIDEpIHkgPSBybmQubXVsX2Rvd24oeCwgeSk7CiAgICBwd3IgPj49IDE7CiAgfQogIHJldHVybiB5Owp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBSb3VuZGluZz4gaW5saW5lClQgcG93X3VwKGNvbnN0IFQmIHhfLCBpbnQgcHdyLCBSb3VuZGluZyYgcm5kKSAvLyB4IGFuZCBwd3IgYXJlIHBvc2l0aXZlCnsKICBUIHggPSB4XzsKICBUIHkgPSAocHdyICYgMSkgPyB4XyA6IHN0YXRpY19jYXN0PFQ+KDEpOwogIHB3ciA+Pj0gMTsKICB3aGlsZSAocHdyID4gMCkgewogICAgeCA9IHJuZC5tdWxfdXAoeCwgeCk7CiAgICBpZiAocHdyICYgMSkgeSA9IHJuZC5tdWxfdXAoeCwgeSk7CiAgICBwd3IgPj49IDE7CiAgfQogIHJldHVybiB5Owp9Cgp9IC8vIG5hbWVzcGFjZSBkZXRhaWwKfSAvLyBuYW1lc3BhY2UgaW50ZXJ2YWxfbGliCgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBwb3coY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4LCBpbnQgcHdyKQp7CiAgQk9PU1RfVVNJTkdfU1REX01BWCgpOwogIHVzaW5nIGludGVydmFsX2xpYjo6ZGV0YWlsOjpwb3dfZG47CiAgdXNpbmcgaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnBvd191cDsKICB0eXBlZGVmIGludGVydmFsPFQsIFBvbGljaWVzPiBJOwoKICBpZiAoaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoeCkpCiAgICByZXR1cm4gSTo6ZW1wdHkoKTsKCiAgaWYgKHB3ciA9PSAwKQogICAgaWYgKGludGVydmFsX2xpYjo6dXNlcjo6aXNfemVybyh4Lmxvd2VyKCkpCiAgICAgICAgJiYgaW50ZXJ2YWxfbGliOjp1c2VyOjppc196ZXJvKHgudXBwZXIoKSkpCiAgICAgIHJldHVybiBJOjplbXB0eSgpOwogICAgZWxzZQogICAgICByZXR1cm4gSShzdGF0aWNfY2FzdDxUPigxKSk7CiAgZWxzZSBpZiAocHdyIDwgMCkKICAgIHJldHVybiBpbnRlcnZhbF9saWI6Om11bHRpcGxpY2F0aXZlX2ludmVyc2UocG93KHgsIC1wd3IpKTsKCiAgdHlwZW5hbWUgUG9saWNpZXM6OnJvdW5kaW5nIHJuZDsKICAKICBpZiAoaW50ZXJ2YWxfbGliOjp1c2VyOjppc19uZWcoeC51cHBlcigpKSkgeyAgICAgICAgLy8gWy0yLC0xXQogICAgVCB5bCA9IHBvd19kbihzdGF0aWNfY2FzdDxUPigteC51cHBlcigpKSwgcHdyLCBybmQpOwogICAgVCB5dSA9IHBvd191cChzdGF0aWNfY2FzdDxUPigteC5sb3dlcigpKSwgcHdyLCBybmQpOwogICAgaWYgKHB3ciAmIDEpICAgICAvLyBbLTIsLTFdXjEKICAgICAgcmV0dXJuIEkoLXl1LCAteWwsIHRydWUpOwogICAgZWxzZSAgICAgICAgICAgICAvLyBbLTIsLTFdXjIKICAgICAgcmV0dXJuIEkoeWwsIHl1LCB0cnVlKTsKICB9IGVsc2UgaWYgKGludGVydmFsX2xpYjo6dXNlcjo6aXNfbmVnKHgubG93ZXIoKSkpIHsgLy8gWy0xLDFdCiAgICBpZiAocHdyICYgMSkgeyAgIC8vIFstMSwxXV4xCiAgICAgIHJldHVybiBJKC1wb3dfdXAoLXgubG93ZXIoKSwgcHdyLCBybmQpLCBwb3dfdXAoeC51cHBlcigpLCBwd3IsIHJuZCksIHRydWUpOwogICAgfSBlbHNlIHsgICAgICAgICAvLyBbLTEsMV1eMgogICAgICByZXR1cm4gSShzdGF0aWNfY2FzdDxUPigwKSwgcG93X3VwKG1heCBCT09TVF9QUkVWRU5UX01BQ1JPX1NVQlNUSVRVVElPTihzdGF0aWNfY2FzdDxUPigteC5sb3dlcigpKSwgeC51cHBlcigpKSwgcHdyLCBybmQpLCB0cnVlKTsKICAgIH0KICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gWzEsMl0KICAgIHJldHVybiBJKHBvd19kbih4Lmxvd2VyKCksIHB3ciwgcm5kKSwgcG93X3VwKHgudXBwZXIoKSwgcHdyLCBybmQpLCB0cnVlKTsKICB9Cn0KCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFBvbGljaWVzPiBpbmxpbmUKaW50ZXJ2YWw8VCwgUG9saWNpZXM+IHNxcnQoY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4KQp7CiAgdHlwZWRlZiBpbnRlcnZhbDxULCBQb2xpY2llcz4gSTsKICBpZiAoaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoeCkgfHwgaW50ZXJ2YWxfbGliOjp1c2VyOjppc19uZWcoeC51cHBlcigpKSkKICAgIHJldHVybiBJOjplbXB0eSgpOwogIHR5cGVuYW1lIFBvbGljaWVzOjpyb3VuZGluZyBybmQ7CiAgVCBsID0gIWludGVydmFsX2xpYjo6dXNlcjo6aXNfcG9zKHgubG93ZXIoKSkgPyBzdGF0aWNfY2FzdDxUPigwKSA6IHJuZC5zcXJ0X2Rvd24oeC5sb3dlcigpKTsKICByZXR1cm4gSShsLCBybmQuc3FydF91cCh4LnVwcGVyKCkpLCB0cnVlKTsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4gc3F1YXJlKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCkKewogIHR5cGVkZWYgaW50ZXJ2YWw8VCwgUG9saWNpZXM+IEk7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgpKQogICAgcmV0dXJuIEk6OmVtcHR5KCk7CiAgdHlwZW5hbWUgUG9saWNpZXM6OnJvdW5kaW5nIHJuZDsKICBjb25zdCBUJiB4bCA9IHgubG93ZXIoKTsKICBjb25zdCBUJiB4dSA9IHgudXBwZXIoKTsKICBpZiAoaW50ZXJ2YWxfbGliOjp1c2VyOjppc19uZWcoeHUpKQogICAgcmV0dXJuIEkocm5kLm11bF9kb3duKHh1LCB4dSksIHJuZC5tdWxfdXAoeGwsIHhsKSwgdHJ1ZSk7CiAgZWxzZSBpZiAoaW50ZXJ2YWxfbGliOjp1c2VyOjppc19wb3MoeC5sb3dlcigpKSkKICAgIHJldHVybiBJKHJuZC5tdWxfZG93bih4bCwgeGwpLCBybmQubXVsX3VwKHh1LCB4dSksIHRydWUpOwogIGVsc2UKICAgIHJldHVybiBJKHN0YXRpY19jYXN0PFQ+KDApLCAoLXhsID4geHUgPyBybmQubXVsX3VwKHhsLCB4bCkgOiBybmQubXVsX3VwKHh1LCB4dSkpLCB0cnVlKTsKfQoKbmFtZXNwYWNlIGludGVydmFsX2xpYiB7Cm5hbWVzcGFjZSBkZXRhaWwgewoKdGVtcGxhdGU8IGNsYXNzIEkgPiBpbmxpbmUKSSByb290X2F1eCh0eXBlbmFtZSBJOjpiYXNlX3R5cGUgY29uc3QgJngsIGludCBrKSAvLyB4IGFuZCBrIGFyZSBiaWdnZXIgdGhhbiBvbmUKewogIHR5cGVkZWYgdHlwZW5hbWUgSTo6YmFzZV90eXBlIFQ7CiAgVCB0ayhrKTsKICBJIHkoc3RhdGljX2Nhc3Q8VD4oMSksIHgsIHRydWUpOwogIGZvcig7OykgewogICAgVCB5MCA9IG1lZGlhbih5KTsKICAgIEkgeXkgPSBpbnRlcnNlY3QoeSwgeTAgLSAocG93KEkoeTAsIHkwLCB0cnVlKSwgaykgLSB4KSAvICh0ayAqIHBvdyh5LCBrIC0gMSkpKTsKICAgIGlmIChlcXVhbCh5LCB5eSkpIHJldHVybiB5OwogICAgeSA9IHl5OwogIH0KfQoKdGVtcGxhdGU8IGNsYXNzIEkgPiBpbmxpbmUgLy8geCBpcyBwb3NpdGl2ZSBhbmQgayBiaWdnZXIgdGhhbiBvbmUKdHlwZW5hbWUgSTo6YmFzZV90eXBlIHJvb3RfYXV4X2RuKHR5cGVuYW1lIEk6OmJhc2VfdHlwZSBjb25zdCAmeCwgaW50IGspCnsKICB0eXBlZGVmIHR5cGVuYW1lIEk6OmJhc2VfdHlwZSBUOwogIHR5cGVkZWYgdHlwZW5hbWUgSTo6dHJhaXRzX3R5cGUgUG9saWNpZXM7CiAgdHlwZW5hbWUgUG9saWNpZXM6OnJvdW5kaW5nIHJuZDsKICBUIG9uZSgxKTsKICBpZiAoeCA+IG9uZSkgcmV0dXJuIHJvb3RfYXV4PEk+KHgsIGspLmxvd2VyKCk7CiAgaWYgKHggPT0gb25lKSByZXR1cm4gb25lOwogIHJldHVybiBybmQuZGl2X2Rvd24ob25lLCByb290X2F1eDxJPihybmQuZGl2X3VwKG9uZSwgeCksIGspLnVwcGVyKCkpOwp9Cgp0ZW1wbGF0ZTwgY2xhc3MgSSA+IGlubGluZSAvLyB4IGlzIHBvc2l0aXZlIGFuZCBrIGJpZ2dlciB0aGFuIG9uZQp0eXBlbmFtZSBJOjpiYXNlX3R5cGUgcm9vdF9hdXhfdXAodHlwZW5hbWUgSTo6YmFzZV90eXBlIGNvbnN0ICZ4LCBpbnQgaykKewogIHR5cGVkZWYgdHlwZW5hbWUgSTo6YmFzZV90eXBlIFQ7CiAgdHlwZWRlZiB0eXBlbmFtZSBJOjp0cmFpdHNfdHlwZSBQb2xpY2llczsKICB0eXBlbmFtZSBQb2xpY2llczo6cm91bmRpbmcgcm5kOwogIFQgb25lKDEpOwogIGlmICh4ID4gb25lKSByZXR1cm4gcm9vdF9hdXg8ST4oeCwgaykudXBwZXIoKTsKICBpZiAoeCA9PSBvbmUpIHJldHVybiBvbmU7CiAgcmV0dXJuIHJuZC5kaXZfdXAob25lLCByb290X2F1eDxJPihybmQuZGl2X2Rvd24ob25lLCB4KSwgaykubG93ZXIoKSk7Cn0KCn0gLy8gbmFtZXNwYWNlIGRldGFpbAp9IC8vIG5hbWVzcGFjZSBpbnRlcnZhbF9saWIKCnRlbXBsYXRlPCBjbGFzcyBULCBjbGFzcyBQb2xpY2llcyA+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4gbnRoX3Jvb3QoaW50ZXJ2YWw8VCwgUG9saWNpZXM+IGNvbnN0ICZ4LCBpbnQgaykKewogIHR5cGVkZWYgaW50ZXJ2YWw8VCwgUG9saWNpZXM+IEk7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgpKSByZXR1cm4gSTo6ZW1wdHkoKTsKICBhc3NlcnQoayA+IDApOwogIGlmIChrID09IDEpIHJldHVybiB4OwogIHR5cGVuYW1lIFBvbGljaWVzOjpyb3VuZGluZyBybmQ7CiAgdHlwZWRlZiB0eXBlbmFtZSBpbnRlcnZhbF9saWI6OnVucHJvdGVjdDxJPjo6dHlwZSBSOwogIGlmICghaW50ZXJ2YWxfbGliOjp1c2VyOjppc19wb3MoeC51cHBlcigpKSkgewogICAgaWYgKGludGVydmFsX2xpYjo6dXNlcjo6aXNfemVybyh4LnVwcGVyKCkpKSB7CiAgICAgIFQgemVybygwKTsKICAgICAgaWYgKCEoayAmIDEpIHx8IGludGVydmFsX2xpYjo6dXNlcjo6aXNfemVybyh4Lmxvd2VyKCkpKSAvLyBbLTEsMF1eLzIgb3IgWzAsMF0KICAgICAgICByZXR1cm4gSSh6ZXJvLCB6ZXJvLCB0cnVlKTsKICAgICAgZWxzZSAgICAgICAgICAgICAgIC8vIFstMSwwXV4vMwogICAgICAgIHJldHVybiBJKC1pbnRlcnZhbF9saWI6OmRldGFpbDo6cm9vdF9hdXhfdXA8Uj4oLXgubG93ZXIoKSwgayksIHplcm8sIHRydWUpOwogICAgfSBlbHNlIGlmICghKGsgJiAxKSkgLy8gWy0yLC0xXV4vMgogICAgICByZXR1cm4gSTo6ZW1wdHkoKTsKICAgIGVsc2UgeyAgICAgICAgICAgICAgIC8vIFstMiwtMV1eLzMKICAgICAgcmV0dXJuIEkoLWludGVydmFsX2xpYjo6ZGV0YWlsOjpyb290X2F1eF91cDxSPigteC5sb3dlcigpLCBrKSwKICAgICAgICAgICAgICAgLWludGVydmFsX2xpYjo6ZGV0YWlsOjpyb290X2F1eF9kbjxSPigteC51cHBlcigpLCBrKSwgdHJ1ZSk7CiAgICB9CiAgfQogIFQgdSA9IGludGVydmFsX2xpYjo6ZGV0YWlsOjpyb290X2F1eF91cDxSPih4LnVwcGVyKCksIGspOwogIGlmICghaW50ZXJ2YWxfbGliOjp1c2VyOjppc19wb3MoeC5sb3dlcigpKSkKICAgIGlmICghKGsgJiAxKSB8fCBpbnRlcnZhbF9saWI6OnVzZXI6OmlzX3plcm8oeC5sb3dlcigpKSkgLy8gWy0xLDFdXi8yIG9yIFswLDFdCiAgICAgIHJldHVybiBJKHN0YXRpY19jYXN0PFQ+KDApLCB1LCB0cnVlKTsKICAgIGVsc2UgICAgICAgICAgICAgICAgIC8vIFstMSwxXV4vMwogICAgICByZXR1cm4gSSgtaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnJvb3RfYXV4X3VwPFI+KC14Lmxvd2VyKCksIGspLCB1LCB0cnVlKTsKICBlbHNlICAgICAgICAgICAgICAgICAgIC8vIFsxLDJdCiAgICByZXR1cm4gSShpbnRlcnZhbF9saWI6OmRldGFpbDo6cm9vdF9hdXhfZG48Uj4oeC5sb3dlcigpLCBrKSwgdSwgdHJ1ZSk7Cn0KCn0gLy8gbmFtZXNwYWNlIG51bWVyaWMKfSAvLyBuYW1lc3BhY2UgYm9vc3QKCiNlbmRpZiAvLyBCT09TVF9OVU1FUklDX0lOVEVSVkFMX0FSSVRIMl9IUFAK