Ly8NCi8vIKkgQ29weXJpZ2h0IEhlbnJpayBSYXZuIDIwMDQNCi8vDQovLyBVc2UsIG1vZGlmaWNhdGlvbiBhbmQgZGlzdHJpYnV0aW9uIGFyZSBzdWJqZWN0IHRvIHRoZSBCb29zdCBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMC4NCi8vIChTZWUgYWNjb21wYW55aW5nIGZpbGUgTElDRU5TRV8xXzAudHh0IG9yIGNvcHkgYXQgaHR0cDovL3d3dy5ib29zdC5vcmcvTElDRU5TRV8xXzAudHh0KQ0KLy8NCg0KdXNpbmcgU3lzdGVtOw0KdXNpbmcgU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzOw0KdXNpbmcgU3lzdGVtLlRleHQ7DQoNCg0KbmFtZXNwYWNlIERvdFpMaWINCnsNCiAgICAjcmVnaW9uIENoZWNrc3VtR2VuZXJhdG9yQmFzZQ0KICAgIC8vLyA8c3VtbWFyeT4NCiAgICAvLy8gSW1wbGVtZW50cyB0aGUgY29tbW9uIGZ1bmN0aW9uYWxpdHkgbmVlZGVkIGZvciBhbGwgPHNlZSBjcmVmPSJDaGVja3N1bUdlbmVyYXRvciIvPnMNCiAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgIC8vLyA8ZXhhbXBsZT48L2V4YW1wbGU+DQogICAgcHVibGljIGFic3RyYWN0IGNsYXNzIENoZWNrc3VtR2VuZXJhdG9yQmFzZSA6IENoZWNrc3VtR2VuZXJhdG9yDQogICAgew0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBUaGUgdmFsdWUgb2YgdGhlIGN1cnJlbnQgY2hlY2tzdW0NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHJvdGVjdGVkIHVpbnQgX2N1cnJlbnQ7DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gSW5pdGlhbGl6ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGNoZWNrc3VtIGdlbmVyYXRvciBiYXNlIC0gdGhlIGN1cnJlbnQgY2hlY2tzdW0gaXMNCiAgICAgICAgLy8vIHNldCB0byB6ZXJvDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyBDaGVja3N1bUdlbmVyYXRvckJhc2UoKQ0KICAgICAgICB7DQogICAgICAgICAgICBfY3VycmVudCA9IDA7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgY2hlY2tzdW0gZ2VuZXJhdG9yIGJhc2V3aXRoIGEgc3BlY2lmaWVkIHZhbHVlDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iaW5pdGlhbFZhbHVlIj5UaGUgdmFsdWUgdG8gc2V0IHRoZSBjdXJyZW50IGNoZWNrc3VtIHRvPC9wYXJhbT4NCiAgICAgICAgcHVibGljIENoZWNrc3VtR2VuZXJhdG9yQmFzZSh1aW50IGluaXRpYWxWYWx1ZSkNCiAgICAgICAgew0KICAgICAgICAgICAgX2N1cnJlbnQgPSBpbml0aWFsVmFsdWU7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBSZXNldHMgdGhlIGN1cnJlbnQgY2hlY2tzdW0gdG8gemVybw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwdWJsaWMgdm9pZCBSZXNldCgpIHsgX2N1cnJlbnQgPSAwOyB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gR2V0cyB0aGUgY3VycmVudCBjaGVja3N1bSB2YWx1ZQ0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwdWJsaWMgdWludCBWYWx1ZSB7IGdldCB7IHJldHVybiBfY3VycmVudDsgfSB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gVXBkYXRlcyB0aGUgY3VycmVudCBjaGVja3N1bSB3aXRoIHBhcnQgb2YgYW4gYXJyYXkgb2YgYnl0ZXMNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkYXRhIj5UaGUgZGF0YSB0byB1cGRhdGUgdGhlIGNoZWNrc3VtIHdpdGg8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9mZnNldCI+V2hlcmUgaW4gPGM+ZGF0YTwvYz4gdG8gc3RhcnQgdXBkYXRpbmc8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvdW50Ij5UaGUgbnVtYmVyIG9mIGJ5dGVzIGZyb20gPGM+ZGF0YTwvYz4gdG8gdXNlPC9wYXJhbT4NCiAgICAgICAgLy8vIDxleGNlcHRpb24gY3JlZj0iQXJndW1lbnRFeGNlcHRpb24iPlRoZSBzdW0gb2Ygb2Zmc2V0IGFuZCBjb3VudCBpcyBsYXJnZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIDxjPmRhdGE8L2M+PC9leGNlcHRpb24+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9Ik51bGxSZWZlcmVuY2VFeGNlcHRpb24iPjxjPmRhdGE8L2M+IGlzIGEgbnVsbCByZWZlcmVuY2U8L2V4Y2VwdGlvbj4NCiAgICAgICAgLy8vIDxleGNlcHRpb24gY3JlZj0iQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uIj5PZmZzZXQgb3IgY291bnQgaXMgbmVnYXRpdmUuPC9leGNlcHRpb24+DQogICAgICAgIC8vLyA8cmVtYXJrcz5BbGwgdGhlIG90aGVyIDxjPlVwZGF0ZTwvYz4gbWV0aG9kcyBhcmUgaW1wbG1lbmV0ZWQgaW4gdGVybXMgb2YgdGhpcyBvbmUuDQogICAgICAgIC8vLyBUaGlzIGlzIHRoZXJlZm9yZSB0aGUgb25seSBtZXRob2QgYSBkZXJpdmVkIGNsYXNzIGhhcyB0byBpbXBsZW1lbnQ8L3JlbWFya3M+DQogICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIFVwZGF0ZShieXRlW10gZGF0YSwgaW50IG9mZnNldCwgaW50IGNvdW50KTsNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBVcGRhdGVzIHRoZSBjdXJyZW50IGNoZWNrc3VtIHdpdGggYW4gYXJyYXkgb2YgYnl0ZXMuDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+VGhlIGRhdGEgdG8gdXBkYXRlIHRoZSBjaGVja3N1bSB3aXRoPC9wYXJhbT4NCiAgICAgICAgcHVibGljIHZvaWQgVXBkYXRlKGJ5dGVbXSBkYXRhKQ0KICAgICAgICB7DQogICAgICAgICAgICBVcGRhdGUoZGF0YSwgMCwgZGF0YS5MZW5ndGgpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gVXBkYXRlcyB0aGUgY3VycmVudCBjaGVja3N1bSB3aXRoIHRoZSBkYXRhIGZyb20gYSBzdHJpbmcNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkYXRhIj5UaGUgc3RyaW5nIHRvIHVwZGF0ZSB0aGUgY2hlY2tzdW0gd2l0aDwvcGFyYW0+DQogICAgICAgIC8vLyA8cmVtYXJrcz5UaGUgY2hhcmFjdGVycyBpbiB0aGUgc3RyaW5nIGFyZSBjb252ZXJ0ZWQgYnkgdGhlIFVURi04IGVuY29kaW5nPC9yZW1hcmtzPg0KICAgICAgICBwdWJsaWMgdm9pZCBVcGRhdGUoc3RyaW5nIGRhdGEpDQogICAgICAgIHsNCgkJCVVwZGF0ZShFbmNvZGluZy5VVEY4LkdldEJ5dGVzKGRhdGEpKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFVwZGF0ZXMgdGhlIGN1cnJlbnQgY2hlY2tzdW0gd2l0aCB0aGUgZGF0YSBmcm9tIGEgc3RyaW5nLCB1c2luZyBhIHNwZWNpZmljIGVuY29kaW5nDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+VGhlIHN0cmluZyB0byB1cGRhdGUgdGhlIGNoZWNrc3VtIHdpdGg8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImVuY29kaW5nIj5UaGUgZW5jb2RpbmcgdG8gdXNlPC9wYXJhbT4NCiAgICAgICAgcHVibGljIHZvaWQgVXBkYXRlKHN0cmluZyBkYXRhLCBFbmNvZGluZyBlbmNvZGluZykNCiAgICAgICAgew0KICAgICAgICAgICAgVXBkYXRlKGVuY29kaW5nLkdldEJ5dGVzKGRhdGEpKTsNCiAgICAgICAgfQ0KDQogICAgfQ0KICAgICNlbmRyZWdpb24NCg0KICAgICNyZWdpb24gQ1JDMzINCiAgICAvLy8gPHN1bW1hcnk+DQogICAgLy8vIEltcGxlbWVudHMgYSBDUkMzMiBjaGVja3N1bSBnZW5lcmF0b3INCiAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgIHB1YmxpYyBzZWFsZWQgY2xhc3MgQ1JDMzJDaGVja3N1bSA6IENoZWNrc3VtR2VuZXJhdG9yQmFzZQ0KICAgIHsNCiAgICAgICAgI3JlZ2lvbiBETEwgaW1wb3J0cw0KDQogICAgICAgIFtEbGxJbXBvcnQoIlpMSUIxLmRsbCIsIENhbGxpbmdDb252ZW50aW9uPUNhbGxpbmdDb252ZW50aW9uLkNkZWNsKV0NCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZXh0ZXJuIHVpbnQgY3JjMzIodWludCBjcmMsIGludCBkYXRhLCB1aW50IGxlbmd0aCk7DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEluaXRpYWxpemVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBDUkMzMiBjaGVja3N1bSBnZW5lcmF0b3INCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHVibGljIENSQzMyQ2hlY2tzdW0oKSA6IGJhc2UoKSB7fQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEluaXRpYWxpemVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBDUkMzMiBjaGVja3N1bSBnZW5lcmF0b3Igd2l0aCBhIHNwZWNpZmllZCB2YWx1ZQ0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImluaXRpYWxWYWx1ZSI+VGhlIHZhbHVlIHRvIHNldCB0aGUgY3VycmVudCBjaGVja3N1bSB0bzwvcGFyYW0+DQogICAgICAgIHB1YmxpYyBDUkMzMkNoZWNrc3VtKHVpbnQgaW5pdGlhbFZhbHVlKSA6IGJhc2UoaW5pdGlhbFZhbHVlKSB7fQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFVwZGF0ZXMgdGhlIGN1cnJlbnQgY2hlY2tzdW0gd2l0aCBwYXJ0IG9mIGFuIGFycmF5IG9mIGJ5dGVzDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+VGhlIGRhdGEgdG8gdXBkYXRlIHRoZSBjaGVja3N1bSB3aXRoPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvZmZzZXQiPldoZXJlIGluIDxjPmRhdGE8L2M+IHRvIHN0YXJ0IHVwZGF0aW5nPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb3VudCI+VGhlIG51bWJlciBvZiBieXRlcyBmcm9tIDxjPmRhdGE8L2M+IHRvIHVzZTwvcGFyYW0+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9IkFyZ3VtZW50RXhjZXB0aW9uIj5UaGUgc3VtIG9mIG9mZnNldCBhbmQgY291bnQgaXMgbGFyZ2VyIHRoYW4gdGhlIGxlbmd0aCBvZiA8Yz5kYXRhPC9jPjwvZXhjZXB0aW9uPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJOdWxsUmVmZXJlbmNlRXhjZXB0aW9uIj48Yz5kYXRhPC9jPiBpcyBhIG51bGwgcmVmZXJlbmNlPC9leGNlcHRpb24+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9IkFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbiI+T2Zmc2V0IG9yIGNvdW50IGlzIG5lZ2F0aXZlLjwvZXhjZXB0aW9uPg0KICAgICAgICBwdWJsaWMgb3ZlcnJpZGUgdm9pZCBVcGRhdGUoYnl0ZVtdIGRhdGEsIGludCBvZmZzZXQsIGludCBjb3VudCkNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgY291bnQgPCAwKSB0aHJvdyBuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCk7DQogICAgICAgICAgICBpZiAoKG9mZnNldCtjb3VudCkgPiBkYXRhLkxlbmd0aCkgdGhyb3cgbmV3IEFyZ3VtZW50RXhjZXB0aW9uKCk7DQogICAgICAgICAgICBHQ0hhbmRsZSBoRGF0YSA9IEdDSGFuZGxlLkFsbG9jKGRhdGEsIEdDSGFuZGxlVHlwZS5QaW5uZWQpOw0KICAgICAgICAgICAgdHJ5DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgX2N1cnJlbnQgPSBjcmMzMihfY3VycmVudCwgaERhdGEuQWRkck9mUGlubmVkT2JqZWN0KCkuVG9JbnQzMigpK29mZnNldCwgKHVpbnQpY291bnQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZmluYWxseQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGhEYXRhLkZyZWUoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgfQ0KICAgICNlbmRyZWdpb24NCg0KICAgICNyZWdpb24gQWRsZXINCiAgICAvLy8gPHN1bW1hcnk+DQogICAgLy8vIEltcGxlbWVudHMgYSBjaGVja3N1bSBnZW5lcmF0b3IgdGhhdCBjb21wdXRlcyB0aGUgQWRsZXIgY2hlY2tzdW0gb24gZGF0YQ0KICAgIC8vLyA8L3N1bW1hcnk+DQogICAgcHVibGljIHNlYWxlZCBjbGFzcyBBZGxlckNoZWNrc3VtIDogQ2hlY2tzdW1HZW5lcmF0b3JCYXNlDQogICAgew0KICAgICAgICAjcmVnaW9uIERMTCBpbXBvcnRzDQoNCiAgICAgICAgW0RsbEltcG9ydCgiWkxJQjEuZGxsIiwgQ2FsbGluZ0NvbnZlbnRpb249Q2FsbGluZ0NvbnZlbnRpb24uQ2RlY2wpXQ0KICAgICAgICBwcml2YXRlIHN0YXRpYyBleHRlcm4gdWludCBhZGxlcjMyKHVpbnQgYWRsZXIsIGludCBkYXRhLCB1aW50IGxlbmd0aCk7DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEluaXRpYWxpemVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBBZGxlciBjaGVja3N1bSBnZW5lcmF0b3INCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHVibGljIEFkbGVyQ2hlY2tzdW0oKSA6IGJhc2UoKSB7fQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEluaXRpYWxpemVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBBZGxlciBjaGVja3N1bSBnZW5lcmF0b3Igd2l0aCBhIHNwZWNpZmllZCB2YWx1ZQ0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImluaXRpYWxWYWx1ZSI+VGhlIHZhbHVlIHRvIHNldCB0aGUgY3VycmVudCBjaGVja3N1bSB0bzwvcGFyYW0+DQogICAgICAgIHB1YmxpYyBBZGxlckNoZWNrc3VtKHVpbnQgaW5pdGlhbFZhbHVlKSA6IGJhc2UoaW5pdGlhbFZhbHVlKSB7fQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFVwZGF0ZXMgdGhlIGN1cnJlbnQgY2hlY2tzdW0gd2l0aCBwYXJ0IG9mIGFuIGFycmF5IG9mIGJ5dGVzDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+VGhlIGRhdGEgdG8gdXBkYXRlIHRoZSBjaGVja3N1bSB3aXRoPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvZmZzZXQiPldoZXJlIGluIDxjPmRhdGE8L2M+IHRvIHN0YXJ0IHVwZGF0aW5nPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb3VudCI+VGhlIG51bWJlciBvZiBieXRlcyBmcm9tIDxjPmRhdGE8L2M+IHRvIHVzZTwvcGFyYW0+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9IkFyZ3VtZW50RXhjZXB0aW9uIj5UaGUgc3VtIG9mIG9mZnNldCBhbmQgY291bnQgaXMgbGFyZ2VyIHRoYW4gdGhlIGxlbmd0aCBvZiA8Yz5kYXRhPC9jPjwvZXhjZXB0aW9uPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJOdWxsUmVmZXJlbmNlRXhjZXB0aW9uIj48Yz5kYXRhPC9jPiBpcyBhIG51bGwgcmVmZXJlbmNlPC9leGNlcHRpb24+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9IkFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbiI+T2Zmc2V0IG9yIGNvdW50IGlzIG5lZ2F0aXZlLjwvZXhjZXB0aW9uPg0KICAgICAgICBwdWJsaWMgb3ZlcnJpZGUgdm9pZCBVcGRhdGUoYnl0ZVtdIGRhdGEsIGludCBvZmZzZXQsIGludCBjb3VudCkNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgY291bnQgPCAwKSB0aHJvdyBuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCk7DQogICAgICAgICAgICBpZiAoKG9mZnNldCtjb3VudCkgPiBkYXRhLkxlbmd0aCkgdGhyb3cgbmV3IEFyZ3VtZW50RXhjZXB0aW9uKCk7DQogICAgICAgICAgICBHQ0hhbmRsZSBoRGF0YSA9IEdDSGFuZGxlLkFsbG9jKGRhdGEsIEdDSGFuZGxlVHlwZS5QaW5uZWQpOw0KICAgICAgICAgICAgdHJ5DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgX2N1cnJlbnQgPSBhZGxlcjMyKF9jdXJyZW50LCBoRGF0YS5BZGRyT2ZQaW5uZWRPYmplY3QoKS5Ub0ludDMyKCkrb2Zmc2V0LCAodWludCljb3VudCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBmaW5hbGx5DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaERhdGEuRnJlZSgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICB9DQogICAgI2VuZHJlZ2lvbg0KDQp9