Ly8KLy8gqSBDb3B5cmlnaHQgSGVucmlrIFJhdm4gMjAwNAovLwovLyBVc2UsIG1vZGlmaWNhdGlvbiBhbmQgZGlzdHJpYnV0aW9uIGFyZSBzdWJqZWN0IHRvIHRoZSBCb29zdCBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMC4gCi8vIChTZWUgYWNjb21wYW55aW5nIGZpbGUgTElDRU5TRV8xXzAudHh0IG9yIGNvcHkgYXQgaHR0cDovL3d3dy5ib29zdC5vcmcvTElDRU5TRV8xXzAudHh0KQovLwoKdXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uRGlhZ25vc3RpY3M7CnVzaW5nIFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlczsKCm5hbWVzcGFjZSBEb3RaTGliCnsKCiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gSW1wbGVtZW50cyBhIGRhdGEgY29tcHJlc3NvciwgdXNpbmcgdGhlIGRlZmxhdGUgYWxnb3JpdGhtIGluIHRoZSBaTGliIGRsbAogICAgLy8vIDwvc3VtbWFyeT4KCXB1YmxpYyBzZWFsZWQgY2xhc3MgRGVmbGF0ZXIgOiBDb2RlY0Jhc2UKCXsKICAgICAgICAjcmVnaW9uIERsbCBpbXBvcnRzCiAgICAgICAgW0RsbEltcG9ydCgiWkxJQjEuZGxsIiwgQ2FsbGluZ0NvbnZlbnRpb249Q2FsbGluZ0NvbnZlbnRpb24uQ2RlY2wsIENoYXJTZXQ9Q2hhclNldC5BbnNpKV0KICAgICAgICBwcml2YXRlIHN0YXRpYyBleHRlcm4gaW50IGRlZmxhdGVJbml0XyhyZWYgWlN0cmVhbSBzeiwgaW50IGxldmVsLCBzdHJpbmcgdnMsIGludCBzaXplKTsKCiAgICAgICAgW0RsbEltcG9ydCgiWkxJQjEuZGxsIiwgQ2FsbGluZ0NvbnZlbnRpb249Q2FsbGluZ0NvbnZlbnRpb24uQ2RlY2wpXQogICAgICAgIHByaXZhdGUgc3RhdGljIGV4dGVybiBpbnQgZGVmbGF0ZShyZWYgWlN0cmVhbSBzeiwgaW50IGZsdXNoKTsKCiAgICAgICAgW0RsbEltcG9ydCgiWkxJQjEuZGxsIiwgQ2FsbGluZ0NvbnZlbnRpb249Q2FsbGluZ0NvbnZlbnRpb24uQ2RlY2wpXQogICAgICAgIHByaXZhdGUgc3RhdGljIGV4dGVybiBpbnQgZGVmbGF0ZVJlc2V0KHJlZiBaU3RyZWFtIHN6KTsKCiAgICAgICAgW0RsbEltcG9ydCgiWkxJQjEuZGxsIiwgQ2FsbGluZ0NvbnZlbnRpb249Q2FsbGluZ0NvbnZlbnRpb24uQ2RlY2wpXQogICAgICAgIHByaXZhdGUgc3RhdGljIGV4dGVybiBpbnQgZGVmbGF0ZUVuZChyZWYgWlN0cmVhbSBzeik7CiAgICAgICAgI2VuZHJlZ2lvbgoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIENvbnN0cnVjdHMgYW4gbmV3IGluc3RhbmNlIG9mIHRoZSA8Yz5EZWZsYXRlcjwvYz4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibGV2ZWwiPlRoZSBjb21wcmVzc2lvbiBsZXZlbCB0byB1c2UgZm9yIHRoaXMgPGM+RGVmbGF0ZXI8L2M+PC9wYXJhbT4KCQlwdWJsaWMgRGVmbGF0ZXIoQ29tcHJlc3NMZXZlbCBsZXZlbCkgOiBiYXNlKCkKCQl7CiAgICAgICAgICAgIGludCByZXR2YWwgPSBkZWZsYXRlSW5pdF8ocmVmIF96dHJlYW0sIChpbnQpbGV2ZWwsIEluZm8uVmVyc2lvbiwgTWFyc2hhbC5TaXplT2YoX3p0cmVhbSkpOwogICAgICAgICAgICBpZiAocmV0dmFsICE9IDApCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWkxpYkV4Y2VwdGlvbihyZXR2YWwsICJDb3VsZCBub3QgaW5pdGlhbGl6ZSBkZWZsYXRlciIpOwoKICAgICAgICAgICAgcmVzZXRPdXRwdXQoKTsKCQl9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQWRkcyBtb3JlIGRhdGEgdG8gdGhlIGNvZGVjIHRvIGJlIHByb2Nlc3NlZC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+Qnl0ZSBhcnJheSBjb250YWluaW5nIHRoZSBkYXRhIHRvIGJlIGFkZGVkIHRvIHRoZSBjb2RlYzwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvZmZzZXQiPlRoZSBpbmRleCBvZiB0aGUgZmlyc3QgYnl0ZSB0byBhZGQgZnJvbSA8Yz5kYXRhPC9jPjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb3VudCI+VGhlIG51bWJlciBvZiBieXRlcyB0byBhZGQ8L3BhcmFtPgogICAgICAgIC8vLyA8cmVtYXJrcz5BZGRpbmcgZGF0YSBtYXksIG9yIG1heSBub3QsIHJhaXNlIHRoZSA8Yz5EYXRhQXZhaWxhYmxlPC9jPiBldmVudDwvcmVtYXJrcz4KICAgICAgICBwdWJsaWMgb3ZlcnJpZGUgdm9pZCBBZGQoYnl0ZVtdIGRhdGEsIGludCBvZmZzZXQsIGludCBjb3VudCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChkYXRhID09IG51bGwpIHRocm93IG5ldyBBcmd1bWVudE51bGxFeGNlcHRpb24oKTsKICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgY291bnQgPCAwKSB0aHJvdyBuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIGlmICgob2Zmc2V0K2NvdW50KSA+IGRhdGEuTGVuZ3RoKSB0aHJvdyBuZXcgQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGludCB0b3RhbCA9IGNvdW50OwogICAgICAgICAgICBpbnQgaW5wdXRJbmRleCA9IG9mZnNldDsKICAgICAgICAgICAgaW50IGVyciA9IDA7CgogICAgICAgICAgICB3aGlsZSAoZXJyID49IDAgJiYgaW5wdXRJbmRleCA8IHRvdGFsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb3B5SW5wdXQoZGF0YSwgaW5wdXRJbmRleCwgTWF0aC5NaW4odG90YWwgLSBpbnB1dEluZGV4LCBrQnVmZmVyU2l6ZSkpOwogICAgICAgICAgICAgICAgd2hpbGUgKGVyciA+PSAwICYmIF96dHJlYW0uYXZhaWxfaW4gPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGVyciA9IGRlZmxhdGUocmVmIF96dHJlYW0sIChpbnQpRmx1c2hUeXBlcy5Ob25lKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZXJyID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChfenRyZWFtLmF2YWlsX291dCA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPbkRhdGFBdmFpbGFibGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyciA9IGRlZmxhdGUocmVmIF96dHJlYW0sIChpbnQpRmx1c2hUeXBlcy5Ob25lKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlucHV0SW5kZXggKz0gKGludClfenRyZWFtLnRvdGFsX2luOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldENoZWNrc3VtKCBfenRyZWFtLmFkbGVyICk7CiAgICAgICAgfQoKCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBGaW5pc2hlcyB1cCBhbnkgcGVuZGluZyBkYXRhIHRoYXQgbmVlZHMgdG8gYmUgcHJvY2Vzc2VkIGFuZCBoYW5kbGVkLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIG92ZXJyaWRlIHZvaWQgRmluaXNoKCkKICAgICAgICB7CiAgICAgICAgICAgIGludCBlcnI7CiAgICAgICAgICAgIGRvIAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlcnIgPSBkZWZsYXRlKHJlZiBfenRyZWFtLCAoaW50KUZsdXNoVHlwZXMuRmluaXNoKTsKICAgICAgICAgICAgICAgIE9uRGF0YUF2YWlsYWJsZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHdoaWxlIChlcnIgPT0gMCk7CiAgICAgICAgICAgIHNldENoZWNrc3VtKCBfenRyZWFtLmFkbGVyICk7CiAgICAgICAgICAgIGRlZmxhdGVSZXNldChyZWYgX3p0cmVhbSk7CiAgICAgICAgICAgIHJlc2V0T3V0cHV0KCk7CiAgICAgICAgfQoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIENsb3NlcyB0aGUgaW50ZXJuYWwgemxpYiBkZWZsYXRlIHN0cmVhbQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHJvdGVjdGVkIG92ZXJyaWRlIHZvaWQgQ2xlYW5VcCgpIHsgZGVmbGF0ZUVuZChyZWYgX3p0cmVhbSk7IH0KCiAgICB9Cn0K