Ly8NCi8vIKkgQ29weXJpZ2h0IEhlbnJpayBSYXZuIDIwMDQNCi8vDQovLyBVc2UsIG1vZGlmaWNhdGlvbiBhbmQgZGlzdHJpYnV0aW9uIGFyZSBzdWJqZWN0IHRvIHRoZSBCb29zdCBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMC4NCi8vIChTZWUgYWNjb21wYW55aW5nIGZpbGUgTElDRU5TRV8xXzAudHh0IG9yIGNvcHkgYXQgaHR0cDovL3d3dy5ib29zdC5vcmcvTElDRU5TRV8xXzAudHh0KQ0KLy8NCg0KdXNpbmcgU3lzdGVtOw0KdXNpbmcgU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzOw0KdXNpbmcgU3lzdGVtLlRleHQ7DQoNCg0KbmFtZXNwYWNlIERvdFpMaWINCnsNCiAgICAjcmVnaW9uIENoZWNrc3VtR2VuZXJhdG9yQmFzZQ0KICAgIC8vLyA8c3VtbWFyeT4NCiAgICAvLy8gSW1wbGVtZW50cyB0aGUgY29tbW9uIGZ1bmN0aW9uYWxpdHkgbmVlZGVkIGZvciBhbGwgPHNlZSBjcmVmPSJDaGVja3N1bUdlbmVyYXRvciIvPnMNCiAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgIC8vLyA8ZXhhbXBsZT48L2V4YW1wbGU+DQogICAgcHVibGljIGFic3RyYWN0IGNsYXNzIENoZWNrc3VtR2VuZXJhdG9yQmFzZSA6IENoZWNrc3VtR2VuZXJhdG9yDQogICAgew0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBUaGUgdmFsdWUgb2YgdGhlIGN1cnJlbnQgY2hlY2tzdW0NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHJvdGVjdGVkIHVpbnQgX2N1cnJlbnQ7DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gSW5pdGlhbGl6ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGNoZWNrc3VtIGdlbmVyYXRvciBiYXNlIC0gdGhlIGN1cnJlbnQgY2hlY2tzdW0gaXMNCiAgICAgICAgLy8vIHNldCB0byB6ZXJvDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyBDaGVja3N1bUdlbmVyYXRvckJhc2UoKQ0KICAgICAgICB7DQogICAgICAgICAgICBfY3VycmVudCA9IDA7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgY2hlY2tzdW0gZ2VuZXJhdG9yIGJhc2Ugd2l0aCBhIHNwZWNpZmllZCB2YWx1ZQ0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImluaXRpYWxWYWx1ZSI+VGhlIHZhbHVlIHRvIHNldCB0aGUgY3VycmVudCBjaGVja3N1bSB0bzwvcGFyYW0+DQogICAgICAgIHB1YmxpYyBDaGVja3N1bUdlbmVyYXRvckJhc2UodWludCBpbml0aWFsVmFsdWUpDQogICAgICAgIHsNCiAgICAgICAgICAgIF9jdXJyZW50ID0gaW5pdGlhbFZhbHVlOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gUmVzZXRzIHRoZSBjdXJyZW50IGNoZWNrc3VtIHRvIHplcm8NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHVibGljIHZvaWQgUmVzZXQoKSB7IF9jdXJyZW50ID0gMDsgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEdldHMgdGhlIGN1cnJlbnQgY2hlY2tzdW0gdmFsdWUNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHVibGljIHVpbnQgVmFsdWUgeyBnZXQgeyByZXR1cm4gX2N1cnJlbnQ7IH0gfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFVwZGF0ZXMgdGhlIGN1cnJlbnQgY2hlY2tzdW0gd2l0aCBwYXJ0IG9mIGFuIGFycmF5IG9mIGJ5dGVzDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+VGhlIGRhdGEgdG8gdXBkYXRlIHRoZSBjaGVja3N1bSB3aXRoPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvZmZzZXQiPldoZXJlIGluIDxjPmRhdGE8L2M+IHRvIHN0YXJ0IHVwZGF0aW5nPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb3VudCI+VGhlIG51bWJlciBvZiBieXRlcyBmcm9tIDxjPmRhdGE8L2M+IHRvIHVzZTwvcGFyYW0+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9IkFyZ3VtZW50RXhjZXB0aW9uIj5UaGUgc3VtIG9mIG9mZnNldCBhbmQgY291bnQgaXMgbGFyZ2VyIHRoYW4gdGhlIGxlbmd0aCBvZiA8Yz5kYXRhPC9jPjwvZXhjZXB0aW9uPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJOdWxsUmVmZXJlbmNlRXhjZXB0aW9uIj48Yz5kYXRhPC9jPiBpcyBhIG51bGwgcmVmZXJlbmNlPC9leGNlcHRpb24+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9IkFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbiI+T2Zmc2V0IG9yIGNvdW50IGlzIG5lZ2F0aXZlLjwvZXhjZXB0aW9uPg0KICAgICAgICAvLy8gPHJlbWFya3M+QWxsIHRoZSBvdGhlciA8Yz5VcGRhdGU8L2M+IG1ldGhvZHMgYXJlIGltcGxlbWVudGVkIGluIHRlcm1zIG9mIHRoaXMgb25lLg0KICAgICAgICAvLy8gVGhpcyBpcyB0aGVyZWZvcmUgdGhlIG9ubHkgbWV0aG9kIGEgZGVyaXZlZCBjbGFzcyBoYXMgdG8gaW1wbGVtZW50PC9yZW1hcmtzPg0KICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBVcGRhdGUoYnl0ZVtdIGRhdGEsIGludCBvZmZzZXQsIGludCBjb3VudCk7DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gVXBkYXRlcyB0aGUgY3VycmVudCBjaGVja3N1bSB3aXRoIGFuIGFycmF5IG9mIGJ5dGVzLg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRhdGEiPlRoZSBkYXRhIHRvIHVwZGF0ZSB0aGUgY2hlY2tzdW0gd2l0aDwvcGFyYW0+DQogICAgICAgIHB1YmxpYyB2b2lkIFVwZGF0ZShieXRlW10gZGF0YSkNCiAgICAgICAgew0KICAgICAgICAgICAgVXBkYXRlKGRhdGEsIDAsIGRhdGEuTGVuZ3RoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFVwZGF0ZXMgdGhlIGN1cnJlbnQgY2hlY2tzdW0gd2l0aCB0aGUgZGF0YSBmcm9tIGEgc3RyaW5nDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+VGhlIHN0cmluZyB0byB1cGRhdGUgdGhlIGNoZWNrc3VtIHdpdGg8L3BhcmFtPg0KICAgICAgICAvLy8gPHJlbWFya3M+VGhlIGNoYXJhY3RlcnMgaW4gdGhlIHN0cmluZyBhcmUgY29udmVydGVkIGJ5IHRoZSBVVEYtOCBlbmNvZGluZzwvcmVtYXJrcz4NCiAgICAgICAgcHVibGljIHZvaWQgVXBkYXRlKHN0cmluZyBkYXRhKQ0KICAgICAgICB7DQoJCQlVcGRhdGUoRW5jb2RpbmcuVVRGOC5HZXRCeXRlcyhkYXRhKSk7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBVcGRhdGVzIHRoZSBjdXJyZW50IGNoZWNrc3VtIHdpdGggdGhlIGRhdGEgZnJvbSBhIHN0cmluZywgdXNpbmcgYSBzcGVjaWZpYyBlbmNvZGluZw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRhdGEiPlRoZSBzdHJpbmcgdG8gdXBkYXRlIHRoZSBjaGVja3N1bSB3aXRoPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJlbmNvZGluZyI+VGhlIGVuY29kaW5nIHRvIHVzZTwvcGFyYW0+DQogICAgICAgIHB1YmxpYyB2b2lkIFVwZGF0ZShzdHJpbmcgZGF0YSwgRW5jb2RpbmcgZW5jb2RpbmcpDQogICAgICAgIHsNCiAgICAgICAgICAgIFVwZGF0ZShlbmNvZGluZy5HZXRCeXRlcyhkYXRhKSk7DQogICAgICAgIH0NCg0KICAgIH0NCiAgICAjZW5kcmVnaW9uDQoNCiAgICAjcmVnaW9uIENSQzMyDQogICAgLy8vIDxzdW1tYXJ5Pg0KICAgIC8vLyBJbXBsZW1lbnRzIGEgQ1JDMzIgY2hlY2tzdW0gZ2VuZXJhdG9yDQogICAgLy8vIDwvc3VtbWFyeT4NCiAgICBwdWJsaWMgc2VhbGVkIGNsYXNzIENSQzMyQ2hlY2tzdW0gOiBDaGVja3N1bUdlbmVyYXRvckJhc2UNCiAgICB7DQogICAgICAgICNyZWdpb24gRExMIGltcG9ydHMNCg0KICAgICAgICBbRGxsSW1wb3J0KCJaTElCMS5kbGwiLCBDYWxsaW5nQ29udmVudGlvbj1DYWxsaW5nQ29udmVudGlvbi5DZGVjbCldDQogICAgICAgIHByaXZhdGUgc3RhdGljIGV4dGVybiB1aW50IGNyYzMyKHVpbnQgY3JjLCBpbnQgZGF0YSwgdWludCBsZW5ndGgpOw0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgQ1JDMzIgY2hlY2tzdW0gZ2VuZXJhdG9yDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyBDUkMzMkNoZWNrc3VtKCkgOiBiYXNlKCkge30NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgQ1JDMzIgY2hlY2tzdW0gZ2VuZXJhdG9yIHdpdGggYSBzcGVjaWZpZWQgdmFsdWUNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJpbml0aWFsVmFsdWUiPlRoZSB2YWx1ZSB0byBzZXQgdGhlIGN1cnJlbnQgY2hlY2tzdW0gdG88L3BhcmFtPg0KICAgICAgICBwdWJsaWMgQ1JDMzJDaGVja3N1bSh1aW50IGluaXRpYWxWYWx1ZSkgOiBiYXNlKGluaXRpYWxWYWx1ZSkge30NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBVcGRhdGVzIHRoZSBjdXJyZW50IGNoZWNrc3VtIHdpdGggcGFydCBvZiBhbiBhcnJheSBvZiBieXRlcw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRhdGEiPlRoZSBkYXRhIHRvIHVwZGF0ZSB0aGUgY2hlY2tzdW0gd2l0aDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib2Zmc2V0Ij5XaGVyZSBpbiA8Yz5kYXRhPC9jPiB0byBzdGFydCB1cGRhdGluZzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY291bnQiPlRoZSBudW1iZXIgb2YgYnl0ZXMgZnJvbSA8Yz5kYXRhPC9jPiB0byB1c2U8L3BhcmFtPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJBcmd1bWVudEV4Y2VwdGlvbiI+VGhlIHN1bSBvZiBvZmZzZXQgYW5kIGNvdW50IGlzIGxhcmdlciB0aGFuIHRoZSBsZW5ndGggb2YgPGM+ZGF0YTwvYz48L2V4Y2VwdGlvbj4NCiAgICAgICAgLy8vIDxleGNlcHRpb24gY3JlZj0iTnVsbFJlZmVyZW5jZUV4Y2VwdGlvbiI+PGM+ZGF0YTwvYz4gaXMgYSBudWxsIHJlZmVyZW5jZTwvZXhjZXB0aW9uPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24iPk9mZnNldCBvciBjb3VudCBpcyBuZWdhdGl2ZS48L2V4Y2VwdGlvbj4NCiAgICAgICAgcHVibGljIG92ZXJyaWRlIHZvaWQgVXBkYXRlKGJ5dGVbXSBkYXRhLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IGNvdW50IDwgMCkgdGhyb3cgbmV3IEFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbigpOw0KICAgICAgICAgICAgaWYgKChvZmZzZXQrY291bnQpID4gZGF0YS5MZW5ndGgpIHRocm93IG5ldyBBcmd1bWVudEV4Y2VwdGlvbigpOw0KICAgICAgICAgICAgR0NIYW5kbGUgaERhdGEgPSBHQ0hhbmRsZS5BbGxvYyhkYXRhLCBHQ0hhbmRsZVR5cGUuUGlubmVkKTsNCiAgICAgICAgICAgIHRyeQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIF9jdXJyZW50ID0gY3JjMzIoX2N1cnJlbnQsIGhEYXRhLkFkZHJPZlBpbm5lZE9iamVjdCgpLlRvSW50MzIoKStvZmZzZXQsICh1aW50KWNvdW50KTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGZpbmFsbHkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBoRGF0YS5GcmVlKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgIH0NCiAgICAjZW5kcmVnaW9uDQoNCiAgICAjcmVnaW9uIEFkbGVyDQogICAgLy8vIDxzdW1tYXJ5Pg0KICAgIC8vLyBJbXBsZW1lbnRzIGEgY2hlY2tzdW0gZ2VuZXJhdG9yIHRoYXQgY29tcHV0ZXMgdGhlIEFkbGVyIGNoZWNrc3VtIG9uIGRhdGENCiAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgIHB1YmxpYyBzZWFsZWQgY2xhc3MgQWRsZXJDaGVja3N1bSA6IENoZWNrc3VtR2VuZXJhdG9yQmFzZQ0KICAgIHsNCiAgICAgICAgI3JlZ2lvbiBETEwgaW1wb3J0cw0KDQogICAgICAgIFtEbGxJbXBvcnQoIlpMSUIxLmRsbCIsIENhbGxpbmdDb252ZW50aW9uPUNhbGxpbmdDb252ZW50aW9uLkNkZWNsKV0NCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZXh0ZXJuIHVpbnQgYWRsZXIzMih1aW50IGFkbGVyLCBpbnQgZGF0YSwgdWludCBsZW5ndGgpOw0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgQWRsZXIgY2hlY2tzdW0gZ2VuZXJhdG9yDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyBBZGxlckNoZWNrc3VtKCkgOiBiYXNlKCkge30NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgQWRsZXIgY2hlY2tzdW0gZ2VuZXJhdG9yIHdpdGggYSBzcGVjaWZpZWQgdmFsdWUNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJpbml0aWFsVmFsdWUiPlRoZSB2YWx1ZSB0byBzZXQgdGhlIGN1cnJlbnQgY2hlY2tzdW0gdG88L3BhcmFtPg0KICAgICAgICBwdWJsaWMgQWRsZXJDaGVja3N1bSh1aW50IGluaXRpYWxWYWx1ZSkgOiBiYXNlKGluaXRpYWxWYWx1ZSkge30NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBVcGRhdGVzIHRoZSBjdXJyZW50IGNoZWNrc3VtIHdpdGggcGFydCBvZiBhbiBhcnJheSBvZiBieXRlcw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRhdGEiPlRoZSBkYXRhIHRvIHVwZGF0ZSB0aGUgY2hlY2tzdW0gd2l0aDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib2Zmc2V0Ij5XaGVyZSBpbiA8Yz5kYXRhPC9jPiB0byBzdGFydCB1cGRhdGluZzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY291bnQiPlRoZSBudW1iZXIgb2YgYnl0ZXMgZnJvbSA8Yz5kYXRhPC9jPiB0byB1c2U8L3BhcmFtPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJBcmd1bWVudEV4Y2VwdGlvbiI+VGhlIHN1bSBvZiBvZmZzZXQgYW5kIGNvdW50IGlzIGxhcmdlciB0aGFuIHRoZSBsZW5ndGggb2YgPGM+ZGF0YTwvYz48L2V4Y2VwdGlvbj4NCiAgICAgICAgLy8vIDxleGNlcHRpb24gY3JlZj0iTnVsbFJlZmVyZW5jZUV4Y2VwdGlvbiI+PGM+ZGF0YTwvYz4gaXMgYSBudWxsIHJlZmVyZW5jZTwvZXhjZXB0aW9uPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24iPk9mZnNldCBvciBjb3VudCBpcyBuZWdhdGl2ZS48L2V4Y2VwdGlvbj4NCiAgICAgICAgcHVibGljIG92ZXJyaWRlIHZvaWQgVXBkYXRlKGJ5dGVbXSBkYXRhLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IGNvdW50IDwgMCkgdGhyb3cgbmV3IEFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbigpOw0KICAgICAgICAgICAgaWYgKChvZmZzZXQrY291bnQpID4gZGF0YS5MZW5ndGgpIHRocm93IG5ldyBBcmd1bWVudEV4Y2VwdGlvbigpOw0KICAgICAgICAgICAgR0NIYW5kbGUgaERhdGEgPSBHQ0hhbmRsZS5BbGxvYyhkYXRhLCBHQ0hhbmRsZVR5cGUuUGlubmVkKTsNCiAgICAgICAgICAgIHRyeQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIF9jdXJyZW50ID0gYWRsZXIzMihfY3VycmVudCwgaERhdGEuQWRkck9mUGlubmVkT2JqZWN0KCkuVG9JbnQzMigpK29mZnNldCwgKHVpbnQpY291bnQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZmluYWxseQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGhEYXRhLkZyZWUoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgfQ0KICAgICNlbmRyZWdpb24NCg0KfQ==