Ly8NCi8vIKkgQ29weXJpZ2h0IEhlbnJpayBSYXZuIDIwMDQNCi8vDQovLyBVc2UsIG1vZGlmaWNhdGlvbiBhbmQgZGlzdHJpYnV0aW9uIGFyZSBzdWJqZWN0IHRvIHRoZSBCb29zdCBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMC4gDQovLyAoU2VlIGFjY29tcGFueWluZyBmaWxlIExJQ0VOU0VfMV8wLnR4dCBvciBjb3B5IGF0IGh0dHA6Ly93d3cuYm9vc3Qub3JnL0xJQ0VOU0VfMV8wLnR4dCkNCi8vDQoNCnVzaW5nIFN5c3RlbTsNCnVzaW5nIFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlczsNCnVzaW5nIFN5c3RlbS5UZXh0Ow0KDQoNCm5hbWVzcGFjZSBEb3RaTGliDQp7DQogICAgI3JlZ2lvbiBDaGVja3N1bUdlbmVyYXRvckJhc2UNCiAgICAvLy8gPHN1bW1hcnk+DQogICAgLy8vIEltcGxlbWVudHMgdGhlIGNvbW1vbiBmdW5jdGlvbmFsaXR5IG5lZWRlZCBmb3IgYWxsIDxzZWUgY3JlZj0iQ2hlY2tzdW1HZW5lcmF0b3IiLz5zDQogICAgLy8vIDwvc3VtbWFyeT4NCiAgICAvLy8gPGV4YW1wbGU+PC9leGFtcGxlPg0KICAgIHB1YmxpYyBhYnN0cmFjdCBjbGFzcyBDaGVja3N1bUdlbmVyYXRvckJhc2UgOiBDaGVja3N1bUdlbmVyYXRvcg0KICAgIHsNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gVGhlIHZhbHVlIG9mIHRoZSBjdXJyZW50IGNoZWNrc3VtDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByb3RlY3RlZCB1aW50IF9jdXJyZW50Ow0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEluaXRpYWxpemVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBjaGVja3N1bSBnZW5lcmF0b3IgYmFzZSAtIHRoZSBjdXJyZW50IGNoZWNrc3VtIGlzIA0KICAgICAgICAvLy8gc2V0IHRvIHplcm8NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHVibGljIENoZWNrc3VtR2VuZXJhdG9yQmFzZSgpDQogICAgICAgIHsNCiAgICAgICAgICAgIF9jdXJyZW50ID0gMDsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEluaXRpYWxpemVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBjaGVja3N1bSBnZW5lcmF0b3IgYmFzZXdpdGggYSBzcGVjaWZpZWQgdmFsdWUNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJpbml0aWFsVmFsdWUiPlRoZSB2YWx1ZSB0byBzZXQgdGhlIGN1cnJlbnQgY2hlY2tzdW0gdG88L3BhcmFtPg0KICAgICAgICBwdWJsaWMgQ2hlY2tzdW1HZW5lcmF0b3JCYXNlKHVpbnQgaW5pdGlhbFZhbHVlKQ0KICAgICAgICB7DQogICAgICAgICAgICBfY3VycmVudCA9IGluaXRpYWxWYWx1ZTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFJlc2V0cyB0aGUgY3VycmVudCBjaGVja3N1bSB0byB6ZXJvDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyB2b2lkIFJlc2V0KCkgeyBfY3VycmVudCA9IDA7IH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBHZXRzIHRoZSBjdXJyZW50IGNoZWNrc3VtIHZhbHVlDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyB1aW50IFZhbHVlIHsgZ2V0IHsgcmV0dXJuIF9jdXJyZW50OyB9IH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBVcGRhdGVzIHRoZSBjdXJyZW50IGNoZWNrc3VtIHdpdGggcGFydCBvZiBhbiBhcnJheSBvZiBieXRlcw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRhdGEiPlRoZSBkYXRhIHRvIHVwZGF0ZSB0aGUgY2hlY2tzdW0gd2l0aDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib2Zmc2V0Ij5XaGVyZSBpbiA8Yz5kYXRhPC9jPiB0byBzdGFydCB1cGRhdGluZzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY291bnQiPlRoZSBudW1iZXIgb2YgYnl0ZXMgZnJvbSA8Yz5kYXRhPC9jPiB0byB1c2U8L3BhcmFtPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJBcmd1bWVudEV4Y2VwdGlvbiI+VGhlIHN1bSBvZiBvZmZzZXQgYW5kIGNvdW50IGlzIGxhcmdlciB0aGFuIHRoZSBsZW5ndGggb2YgPGM+ZGF0YTwvYz48L2V4Y2VwdGlvbj4NCiAgICAgICAgLy8vIDxleGNlcHRpb24gY3JlZj0iTnVsbFJlZmVyZW5jZUV4Y2VwdGlvbiI+PGM+ZGF0YTwvYz4gaXMgYSBudWxsIHJlZmVyZW5jZTwvZXhjZXB0aW9uPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24iPk9mZnNldCBvciBjb3VudCBpcyBuZWdhdGl2ZS48L2V4Y2VwdGlvbj4NCiAgICAgICAgLy8vIDxyZW1hcmtzPkFsbCB0aGUgb3RoZXIgPGM+VXBkYXRlPC9jPiBtZXRob2RzIGFyZSBpbXBsbWVuZXRlZCBpbiB0ZXJtcyBvZiB0aGlzIG9uZS4gDQogICAgICAgIC8vLyBUaGlzIGlzIHRoZXJlZm9yZSB0aGUgb25seSBtZXRob2QgYSBkZXJpdmVkIGNsYXNzIGhhcyB0byBpbXBsZW1lbnQ8L3JlbWFya3M+DQogICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIFVwZGF0ZShieXRlW10gZGF0YSwgaW50IG9mZnNldCwgaW50IGNvdW50KTsNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBVcGRhdGVzIHRoZSBjdXJyZW50IGNoZWNrc3VtIHdpdGggYW4gYXJyYXkgb2YgYnl0ZXMuDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+VGhlIGRhdGEgdG8gdXBkYXRlIHRoZSBjaGVja3N1bSB3aXRoPC9wYXJhbT4NCiAgICAgICAgcHVibGljIHZvaWQgVXBkYXRlKGJ5dGVbXSBkYXRhKQ0KICAgICAgICB7DQogICAgICAgICAgICBVcGRhdGUoZGF0YSwgMCwgZGF0YS5MZW5ndGgpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gVXBkYXRlcyB0aGUgY3VycmVudCBjaGVja3N1bSB3aXRoIHRoZSBkYXRhIGZyb20gYSBzdHJpbmcNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkYXRhIj5UaGUgc3RyaW5nIHRvIHVwZGF0ZSB0aGUgY2hlY2tzdW0gd2l0aDwvcGFyYW0+DQogICAgICAgIC8vLyA8cmVtYXJrcz5UaGUgY2hhcmFjdGVycyBpbiB0aGUgc3RyaW5nIGFyZSBjb252ZXJ0ZWQgYnkgdGhlIFVURi04IGVuY29kaW5nPC9yZW1hcmtzPg0KICAgICAgICBwdWJsaWMgdm9pZCBVcGRhdGUoc3RyaW5nIGRhdGEpDQogICAgICAgIHsNCgkJCVVwZGF0ZShFbmNvZGluZy5VVEY4LkdldEJ5dGVzKGRhdGEpKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFVwZGF0ZXMgdGhlIGN1cnJlbnQgY2hlY2tzdW0gd2l0aCB0aGUgZGF0YSBmcm9tIGEgc3RyaW5nLCB1c2luZyBhIHNwZWNpZmljIGVuY29kaW5nDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+VGhlIHN0cmluZyB0byB1cGRhdGUgdGhlIGNoZWNrc3VtIHdpdGg8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImVuY29kaW5nIj5UaGUgZW5jb2RpbmcgdG8gdXNlPC9wYXJhbT4NCiAgICAgICAgcHVibGljIHZvaWQgVXBkYXRlKHN0cmluZyBkYXRhLCBFbmNvZGluZyBlbmNvZGluZykNCiAgICAgICAgew0KICAgICAgICAgICAgVXBkYXRlKGVuY29kaW5nLkdldEJ5dGVzKGRhdGEpKTsNCiAgICAgICAgfQ0KDQogICAgfQ0KICAgICNlbmRyZWdpb24NCg0KICAgICNyZWdpb24gQ1JDMzINCiAgICAvLy8gPHN1bW1hcnk+DQogICAgLy8vIEltcGxlbWVudHMgYSBDUkMzMiBjaGVja3N1bSBnZW5lcmF0b3INCiAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgIHB1YmxpYyBzZWFsZWQgY2xhc3MgQ1JDMzJDaGVja3N1bSA6IENoZWNrc3VtR2VuZXJhdG9yQmFzZSAgICANCiAgICB7DQogICAgICAgICNyZWdpb24gRExMIGltcG9ydHMNCg0KICAgICAgICBbRGxsSW1wb3J0KCJaTElCMS5kbGwiLCBDYWxsaW5nQ29udmVudGlvbj1DYWxsaW5nQ29udmVudGlvbi5DZGVjbCldDQogICAgICAgIHByaXZhdGUgc3RhdGljIGV4dGVybiB1aW50IGNyYzMyKHVpbnQgY3JjLCBpbnQgZGF0YSwgdWludCBsZW5ndGgpOw0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgQ1JDMzIgY2hlY2tzdW0gZ2VuZXJhdG9yDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyBDUkMzMkNoZWNrc3VtKCkgOiBiYXNlKCkge30NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgQ1JDMzIgY2hlY2tzdW0gZ2VuZXJhdG9yIHdpdGggYSBzcGVjaWZpZWQgdmFsdWUNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJpbml0aWFsVmFsdWUiPlRoZSB2YWx1ZSB0byBzZXQgdGhlIGN1cnJlbnQgY2hlY2tzdW0gdG88L3BhcmFtPg0KICAgICAgICBwdWJsaWMgQ1JDMzJDaGVja3N1bSh1aW50IGluaXRpYWxWYWx1ZSkgOiBiYXNlKGluaXRpYWxWYWx1ZSkge30NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBVcGRhdGVzIHRoZSBjdXJyZW50IGNoZWNrc3VtIHdpdGggcGFydCBvZiBhbiBhcnJheSBvZiBieXRlcw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRhdGEiPlRoZSBkYXRhIHRvIHVwZGF0ZSB0aGUgY2hlY2tzdW0gd2l0aDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib2Zmc2V0Ij5XaGVyZSBpbiA8Yz5kYXRhPC9jPiB0byBzdGFydCB1cGRhdGluZzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY291bnQiPlRoZSBudW1iZXIgb2YgYnl0ZXMgZnJvbSA8Yz5kYXRhPC9jPiB0byB1c2U8L3BhcmFtPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJBcmd1bWVudEV4Y2VwdGlvbiI+VGhlIHN1bSBvZiBvZmZzZXQgYW5kIGNvdW50IGlzIGxhcmdlciB0aGFuIHRoZSBsZW5ndGggb2YgPGM+ZGF0YTwvYz48L2V4Y2VwdGlvbj4NCiAgICAgICAgLy8vIDxleGNlcHRpb24gY3JlZj0iTnVsbFJlZmVyZW5jZUV4Y2VwdGlvbiI+PGM+ZGF0YTwvYz4gaXMgYSBudWxsIHJlZmVyZW5jZTwvZXhjZXB0aW9uPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24iPk9mZnNldCBvciBjb3VudCBpcyBuZWdhdGl2ZS48L2V4Y2VwdGlvbj4NCiAgICAgICAgcHVibGljIG92ZXJyaWRlIHZvaWQgVXBkYXRlKGJ5dGVbXSBkYXRhLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IGNvdW50IDwgMCkgdGhyb3cgbmV3IEFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbigpOw0KICAgICAgICAgICAgaWYgKChvZmZzZXQrY291bnQpID4gZGF0YS5MZW5ndGgpIHRocm93IG5ldyBBcmd1bWVudEV4Y2VwdGlvbigpOw0KICAgICAgICAgICAgR0NIYW5kbGUgaERhdGEgPSBHQ0hhbmRsZS5BbGxvYyhkYXRhLCBHQ0hhbmRsZVR5cGUuUGlubmVkKTsNCiAgICAgICAgICAgIHRyeQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIF9jdXJyZW50ID0gY3JjMzIoX2N1cnJlbnQsIGhEYXRhLkFkZHJPZlBpbm5lZE9iamVjdCgpLlRvSW50MzIoKStvZmZzZXQsICh1aW50KWNvdW50KTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGZpbmFsbHkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBoRGF0YS5GcmVlKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgIH0NCiAgICAjZW5kcmVnaW9uDQoNCiAgICAjcmVnaW9uIEFkbGVyDQogICAgLy8vIDxzdW1tYXJ5Pg0KICAgIC8vLyBJbXBsZW1lbnRzIGEgY2hlY2tzdW0gZ2VuZXJhdG9yIHRoYXQgY29tcHV0ZXMgdGhlIEFkbGVyIGNoZWNrc3VtIG9uIGRhdGENCiAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgIHB1YmxpYyBzZWFsZWQgY2xhc3MgQWRsZXJDaGVja3N1bSA6IENoZWNrc3VtR2VuZXJhdG9yQmFzZSAgICANCiAgICB7DQogICAgICAgICNyZWdpb24gRExMIGltcG9ydHMNCg0KICAgICAgICBbRGxsSW1wb3J0KCJaTElCMS5kbGwiLCBDYWxsaW5nQ29udmVudGlvbj1DYWxsaW5nQ29udmVudGlvbi5DZGVjbCldDQogICAgICAgIHByaXZhdGUgc3RhdGljIGV4dGVybiB1aW50IGFkbGVyMzIodWludCBhZGxlciwgaW50IGRhdGEsIHVpbnQgbGVuZ3RoKTsNCg0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gSW5pdGlhbGl6ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEFkbGVyIGNoZWNrc3VtIGdlbmVyYXRvcg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwdWJsaWMgQWRsZXJDaGVja3N1bSgpIDogYmFzZSgpIHt9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gSW5pdGlhbGl6ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEFkbGVyIGNoZWNrc3VtIGdlbmVyYXRvciB3aXRoIGEgc3BlY2lmaWVkIHZhbHVlDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iaW5pdGlhbFZhbHVlIj5UaGUgdmFsdWUgdG8gc2V0IHRoZSBjdXJyZW50IGNoZWNrc3VtIHRvPC9wYXJhbT4NCiAgICAgICAgcHVibGljIEFkbGVyQ2hlY2tzdW0odWludCBpbml0aWFsVmFsdWUpIDogYmFzZShpbml0aWFsVmFsdWUpIHt9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gVXBkYXRlcyB0aGUgY3VycmVudCBjaGVja3N1bSB3aXRoIHBhcnQgb2YgYW4gYXJyYXkgb2YgYnl0ZXMNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkYXRhIj5UaGUgZGF0YSB0byB1cGRhdGUgdGhlIGNoZWNrc3VtIHdpdGg8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9mZnNldCI+V2hlcmUgaW4gPGM+ZGF0YTwvYz4gdG8gc3RhcnQgdXBkYXRpbmc8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvdW50Ij5UaGUgbnVtYmVyIG9mIGJ5dGVzIGZyb20gPGM+ZGF0YTwvYz4gdG8gdXNlPC9wYXJhbT4NCiAgICAgICAgLy8vIDxleGNlcHRpb24gY3JlZj0iQXJndW1lbnRFeGNlcHRpb24iPlRoZSBzdW0gb2Ygb2Zmc2V0IGFuZCBjb3VudCBpcyBsYXJnZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIDxjPmRhdGE8L2M+PC9leGNlcHRpb24+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9Ik51bGxSZWZlcmVuY2VFeGNlcHRpb24iPjxjPmRhdGE8L2M+IGlzIGEgbnVsbCByZWZlcmVuY2U8L2V4Y2VwdGlvbj4NCiAgICAgICAgLy8vIDxleGNlcHRpb24gY3JlZj0iQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uIj5PZmZzZXQgb3IgY291bnQgaXMgbmVnYXRpdmUuPC9leGNlcHRpb24+DQogICAgICAgIHB1YmxpYyBvdmVycmlkZSB2b2lkIFVwZGF0ZShieXRlW10gZGF0YSwgaW50IG9mZnNldCwgaW50IGNvdW50KQ0KICAgICAgICB7DQogICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBjb3VudCA8IDApIHRocm93IG5ldyBBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24oKTsNCiAgICAgICAgICAgIGlmICgob2Zmc2V0K2NvdW50KSA+IGRhdGEuTGVuZ3RoKSB0aHJvdyBuZXcgQXJndW1lbnRFeGNlcHRpb24oKTsNCiAgICAgICAgICAgIEdDSGFuZGxlIGhEYXRhID0gR0NIYW5kbGUuQWxsb2MoZGF0YSwgR0NIYW5kbGVUeXBlLlBpbm5lZCk7DQogICAgICAgICAgICB0cnkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBfY3VycmVudCA9IGFkbGVyMzIoX2N1cnJlbnQsIGhEYXRhLkFkZHJPZlBpbm5lZE9iamVjdCgpLlRvSW50MzIoKStvZmZzZXQsICh1aW50KWNvdW50KTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGZpbmFsbHkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBoRGF0YS5GcmVlKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgIH0NCiAgICAjZW5kcmVnaW9uDQoNCn0=