Ly8KLy8gqSBDb3B5cmlnaHQgSGVucmlrIFJhdm4gMjAwNAovLwovLyBVc2UsIG1vZGlmaWNhdGlvbiBhbmQgZGlzdHJpYnV0aW9uIGFyZSBzdWJqZWN0IHRvIHRoZSBCb29zdCBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMC4KLy8gKFNlZSBhY2NvbXBhbnlpbmcgZmlsZSBMSUNFTlNFXzFfMC50eHQgb3IgY29weSBhdCBodHRwOi8vd3d3LmJvb3N0Lm9yZy9MSUNFTlNFXzFfMC50eHQpCi8vCgp1c2luZyBTeXN0ZW07CnVzaW5nIFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlczsKCm5hbWVzcGFjZSBEb3RaTGliCnsKCS8vLyA8c3VtbWFyeT4KCS8vLyBJbXBsZW1lbnRzIHRoZSBjb21tb24gZnVuY3Rpb25hbGl0eSBuZWVkZWQgZm9yIGFsbCA8c2VlIGNyZWY9IkNvZGVjIi8+cwoJLy8vIDwvc3VtbWFyeT4KCXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBDb2RlY0Jhc2UgOiBDb2RlYywgSURpc3Bvc2FibGUKCXsKCiAgICAgICAgI3JlZ2lvbiBEYXRhIG1lbWJlcnMKCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBJbnN0YW5jZSBvZiB0aGUgaW50ZXJuYWwgemxpYiBidWZmZXIgc3RydWN0dXJlIHRoYXQgaXMKICAgICAgICAvLy8gcGFzc2VkIHRvIGFsbCBmdW5jdGlvbnMgaW4gdGhlIHpsaWIgZGxsCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBpbnRlcm5hbCBaU3RyZWFtIF96dHJlYW0gPSBuZXcgWlN0cmVhbSgpOwoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRydWUgaWYgdGhlIG9iamVjdCBpbnN0YW5jZSBoYXMgYmVlbiBkaXNwb3NlZCwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwcm90ZWN0ZWQgYm9vbCBfaXNEaXNwb3NlZCA9IGZhbHNlOwoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBzaXplIG9mIHRoZSBpbnRlcm5hbCBidWZmZXJzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwcm90ZWN0ZWQgY29uc3QgaW50IGtCdWZmZXJTaXplID0gMTYzODQ7CgogICAgICAgIHByaXZhdGUgYnl0ZVtdIF9vdXRCdWZmZXIgPSBuZXcgYnl0ZVtrQnVmZmVyU2l6ZV07CiAgICAgICAgcHJpdmF0ZSBieXRlW10gX2luQnVmZmVyID0gbmV3IGJ5dGVba0J1ZmZlclNpemVdOwoKICAgICAgICBwcml2YXRlIEdDSGFuZGxlIF9oSW5wdXQ7CiAgICAgICAgcHJpdmF0ZSBHQ0hhbmRsZSBfaE91dHB1dDsKCiAgICAgICAgcHJpdmF0ZSB1aW50IF9jaGVja3N1bSA9IDA7CgogICAgICAgICNlbmRyZWdpb24KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgPGM+Q29kZUJhc2U8L2M+IGNsYXNzLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CgkJcHVibGljIENvZGVjQmFzZSgpCgkJewogICAgICAgICAgICB0cnkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX2hJbnB1dCA9IEdDSGFuZGxlLkFsbG9jKF9pbkJ1ZmZlciwgR0NIYW5kbGVUeXBlLlBpbm5lZCk7CiAgICAgICAgICAgICAgICBfaE91dHB1dCA9IEdDSGFuZGxlLkFsbG9jKF9vdXRCdWZmZXIsIEdDSGFuZGxlVHlwZS5QaW5uZWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENsZWFuVXAoZmFsc2UpOwogICAgICAgICAgICAgICAgdGhyb3c7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoKICAgICAgICAjcmVnaW9uIENvZGVjIE1lbWJlcnMKCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBPY2N1cnMgd2hlbiBtb3JlIHByb2Nlc3NlZCBkYXRhIGFyZSBhdmFpbGFibGUuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgZXZlbnQgRGF0YUF2YWlsYWJsZUhhbmRsZXIgRGF0YUF2YWlsYWJsZTsKCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBGaXJlcyB0aGUgPHNlZSBjcmVmPSJEYXRhQXZhaWxhYmxlIi8+IGV2ZW50CiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwcm90ZWN0ZWQgdm9pZCBPbkRhdGFBdmFpbGFibGUoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKF96dHJlYW0udG90YWxfb3V0ID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKERhdGFBdmFpbGFibGUgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBEYXRhQXZhaWxhYmxlKCBfb3V0QnVmZmVyLCAwLCAoaW50KV96dHJlYW0udG90YWxfb3V0KTsKICAgICAgICAgICAgICAgIHJlc2V0T3V0cHV0KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQWRkcyBtb3JlIGRhdGEgdG8gdGhlIGNvZGVjIHRvIGJlIHByb2Nlc3NlZC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+Qnl0ZSBhcnJheSBjb250YWluaW5nIHRoZSBkYXRhIHRvIGJlIGFkZGVkIHRvIHRoZSBjb2RlYzwvcGFyYW0+CiAgICAgICAgLy8vIDxyZW1hcmtzPkFkZGluZyBkYXRhIG1heSwgb3IgbWF5IG5vdCwgcmFpc2UgdGhlIDxjPkRhdGFBdmFpbGFibGU8L2M+IGV2ZW50PC9yZW1hcmtzPgogICAgICAgIHB1YmxpYyB2b2lkIEFkZChieXRlW10gZGF0YSkKICAgICAgICB7CiAgICAgICAgICAgIEFkZChkYXRhLDAsZGF0YS5MZW5ndGgpOwogICAgICAgIH0KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBBZGRzIG1vcmUgZGF0YSB0byB0aGUgY29kZWMgdG8gYmUgcHJvY2Vzc2VkLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkYXRhIj5CeXRlIGFycmF5IGNvbnRhaW5pbmcgdGhlIGRhdGEgdG8gYmUgYWRkZWQgdG8gdGhlIGNvZGVjPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9mZnNldCI+VGhlIGluZGV4IG9mIHRoZSBmaXJzdCBieXRlIHRvIGFkZCBmcm9tIDxjPmRhdGE8L2M+PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvdW50Ij5UaGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGFkZDwvcGFyYW0+CiAgICAgICAgLy8vIDxyZW1hcmtzPkFkZGluZyBkYXRhIG1heSwgb3IgbWF5IG5vdCwgcmFpc2UgdGhlIDxjPkRhdGFBdmFpbGFibGU8L2M+IGV2ZW50PC9yZW1hcmtzPgogICAgICAgIC8vLyA8cmVtYXJrcz5UaGlzIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgYSBkZXJpdmVkIGNsYXNzPC9yZW1hcmtzPgogICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIEFkZChieXRlW10gZGF0YSwgaW50IG9mZnNldCwgaW50IGNvdW50KTsKCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBGaW5pc2hlcyB1cCBhbnkgcGVuZGluZyBkYXRhIHRoYXQgbmVlZHMgdG8gYmUgcHJvY2Vzc2VkIGFuZCBoYW5kbGVkLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxyZW1hcmtzPlRoaXMgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBhIGRlcml2ZWQgY2xhc3M8L3JlbWFya3M+CiAgICAgICAgcHVibGljIGFic3RyYWN0IHZvaWQgRmluaXNoKCk7CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0cyB0aGUgY2hlY2tzdW0gb2YgdGhlIGRhdGEgdGhhdCBoYXMgYmVlbiBhZGRlZCBzbyBmYXIKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyB1aW50IENoZWNrc3VtIHsgZ2V0IHsgcmV0dXJuIF9jaGVja3N1bTsgfSB9CgogICAgICAgICNlbmRyZWdpb24KCiAgICAgICAgI3JlZ2lvbiBEZXN0cnVjdG9yICYgSURpc3Bvc2FibGUgc3R1ZmYKCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBEZXN0cm95cyB0aGlzIGluc3RhbmNlCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICB+Q29kZWNCYXNlKCkKICAgICAgICB7CiAgICAgICAgICAgIENsZWFuVXAoZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBSZWxlYXNlcyBhbnkgdW5tYW5hZ2VkIHJlc291cmNlcyBhbmQgY2FsbHMgdGhlIDxzZWUgY3JlZj0iQ2xlYW5VcCgpIi8+IG1ldGhvZCBvZiB0aGUgZGVyaXZlZCBjbGFzcwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIHZvaWQgRGlzcG9zZSgpCiAgICAgICAgewogICAgICAgICAgICBDbGVhblVwKHRydWUpOwogICAgICAgIH0KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBQZXJmb3JtcyBhbnkgY29kZWMgc3BlY2lmaWMgY2xlYW51cAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxyZW1hcmtzPlRoaXMgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBhIGRlcml2ZWQgY2xhc3M8L3JlbWFya3M+CiAgICAgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgQ2xlYW5VcCgpOwoKICAgICAgICAvLyBwZXJmb3JtcyB0aGUgcmVsZWFzZSBvZiB0aGUgaGFuZGxlcyBhbmQgY2FsbHMgdGhlIGRlcml2ZWQgQ2xlYW5VcCgpCiAgICAgICAgcHJpdmF0ZSB2b2lkIENsZWFuVXAoYm9vbCBpc0Rpc3Bvc2luZykKICAgICAgICB7CiAgICAgICAgICAgIGlmICghX2lzRGlzcG9zZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENsZWFuVXAoKTsKICAgICAgICAgICAgICAgIGlmIChfaElucHV0LklzQWxsb2NhdGVkKQogICAgICAgICAgICAgICAgICAgIF9oSW5wdXQuRnJlZSgpOwogICAgICAgICAgICAgICAgaWYgKF9oT3V0cHV0LklzQWxsb2NhdGVkKQogICAgICAgICAgICAgICAgICAgIF9oT3V0cHV0LkZyZWUoKTsKCiAgICAgICAgICAgICAgICBfaXNEaXNwb3NlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoKICAgICAgICAjZW5kcmVnaW9uCgogICAgICAgICNyZWdpb24gSGVscGVyIG1ldGhvZHMKCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBDb3BpZXMgYSBudW1iZXIgb2YgYnl0ZXMgdG8gdGhlIGludGVybmFsIGNvZGVjIGJ1ZmZlciAtIHJlYWR5IGZvciBwcm9jZXNzaW5nCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRhdGEiPlRoZSBieXRlIGFycmF5IHRoYXQgY29udGFpbnMgdGhlIGRhdGEgdG8gY29weTwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzdGFydEluZGV4Ij5UaGUgaW5kZXggb2YgdGhlIGZpcnN0IGJ5dGUgdG8gY29weTwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb3VudCI+VGhlIG51bWJlciBvZiBieXRlcyB0byBjb3B5IGZyb20gPGM+ZGF0YTwvYz48L3BhcmFtPgogICAgICAgIHByb3RlY3RlZCB2b2lkIGNvcHlJbnB1dChieXRlW10gZGF0YSwgaW50IHN0YXJ0SW5kZXgsIGludCBjb3VudCkKICAgICAgICB7CiAgICAgICAgICAgIEFycmF5LkNvcHkoZGF0YSwgc3RhcnRJbmRleCwgX2luQnVmZmVyLDAsIGNvdW50KTsKICAgICAgICAgICAgX3p0cmVhbS5uZXh0X2luID0gX2hJbnB1dC5BZGRyT2ZQaW5uZWRPYmplY3QoKTsKICAgICAgICAgICAgX3p0cmVhbS50b3RhbF9pbiA9IDA7CiAgICAgICAgICAgIF96dHJlYW0uYXZhaWxfaW4gPSAodWludCljb3VudDsKCiAgICAgICAgfQoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFJlc2V0cyB0aGUgaW50ZXJuYWwgb3V0cHV0IGJ1ZmZlcnMgdG8gYSBrbm93biBzdGF0ZSAtIHJlYWR5IGZvciBwcm9jZXNzaW5nCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZXNldE91dHB1dCgpCiAgICAgICAgewogICAgICAgICAgICBfenRyZWFtLnRvdGFsX291dCA9IDA7CiAgICAgICAgICAgIF96dHJlYW0uYXZhaWxfb3V0ID0ga0J1ZmZlclNpemU7CiAgICAgICAgICAgIF96dHJlYW0ubmV4dF9vdXQgPSBfaE91dHB1dC5BZGRyT2ZQaW5uZWRPYmplY3QoKTsKICAgICAgICB9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVXBkYXRlcyB0aGUgcnVubmluZyBjaGVja3N1bSBwcm9wZXJ0eQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJuZXdTdW0iPlRoZSBuZXcgY2hlY2tzdW0gdmFsdWU8L3BhcmFtPgogICAgICAgIHByb3RlY3RlZCB2b2lkIHNldENoZWNrc3VtKHVpbnQgbmV3U3VtKQogICAgICAgIHsKICAgICAgICAgICAgX2NoZWNrc3VtID0gbmV3U3VtOwogICAgICAgIH0KICAgICAgICAjZW5kcmVnaW9uCgogICAgfQp9Cg==