Ly8NCi8vIKkgQ29weXJpZ2h0IEhlbnJpayBSYXZuIDIwMDQNCi8vDQovLyBVc2UsIG1vZGlmaWNhdGlvbiBhbmQgZGlzdHJpYnV0aW9uIGFyZSBzdWJqZWN0IHRvIHRoZSBCb29zdCBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMC4NCi8vIChTZWUgYWNjb21wYW55aW5nIGZpbGUgTElDRU5TRV8xXzAudHh0IG9yIGNvcHkgYXQgaHR0cDovL3d3dy5ib29zdC5vcmcvTElDRU5TRV8xXzAudHh0KQ0KLy8NCg0KdXNpbmcgU3lzdGVtOw0KdXNpbmcgU3lzdGVtLklPOw0KdXNpbmcgU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzOw0KDQpuYW1lc3BhY2UgRG90WkxpYg0Kew0KCS8vLyA8c3VtbWFyeT4NCgkvLy8gSW1wbGVtZW50cyBhIGNvbXByZXNzZWQgPHNlZSBjcmVmPSJTdHJlYW0iLz4sIGluIEdaaXAgKC5neikgZm9ybWF0Lg0KCS8vLyA8L3N1bW1hcnk+DQoJcHVibGljIGNsYXNzIEdaaXBTdHJlYW0gOiBTdHJlYW0sIElEaXNwb3NhYmxlDQoJew0KICAgICAgICAjcmVnaW9uIERsbCBJbXBvcnRzDQogICAgICAgIFtEbGxJbXBvcnQoIlpMSUIxLmRsbCIsIENhbGxpbmdDb252ZW50aW9uPUNhbGxpbmdDb252ZW50aW9uLkNkZWNsLCBDaGFyU2V0PUNoYXJTZXQuQW5zaSldDQogICAgICAgIHByaXZhdGUgc3RhdGljIGV4dGVybiBJbnRQdHIgZ3pvcGVuKHN0cmluZyBuYW1lLCBzdHJpbmcgbW9kZSk7DQoNCiAgICAgICAgW0RsbEltcG9ydCgiWkxJQjEuZGxsIiwgQ2FsbGluZ0NvbnZlbnRpb249Q2FsbGluZ0NvbnZlbnRpb24uQ2RlY2wpXQ0KICAgICAgICBwcml2YXRlIHN0YXRpYyBleHRlcm4gaW50IGd6Y2xvc2UoSW50UHRyIGd6RmlsZSk7DQoNCiAgICAgICAgW0RsbEltcG9ydCgiWkxJQjEuZGxsIiwgQ2FsbGluZ0NvbnZlbnRpb249Q2FsbGluZ0NvbnZlbnRpb24uQ2RlY2wpXQ0KICAgICAgICBwcml2YXRlIHN0YXRpYyBleHRlcm4gaW50IGd6d3JpdGUoSW50UHRyIGd6RmlsZSwgaW50IGRhdGEsIGludCBsZW5ndGgpOw0KDQogICAgICAgIFtEbGxJbXBvcnQoIlpMSUIxLmRsbCIsIENhbGxpbmdDb252ZW50aW9uPUNhbGxpbmdDb252ZW50aW9uLkNkZWNsKV0NCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZXh0ZXJuIGludCBnenJlYWQoSW50UHRyIGd6RmlsZSwgaW50IGRhdGEsIGludCBsZW5ndGgpOw0KDQogICAgICAgIFtEbGxJbXBvcnQoIlpMSUIxLmRsbCIsIENhbGxpbmdDb252ZW50aW9uPUNhbGxpbmdDb252ZW50aW9uLkNkZWNsKV0NCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZXh0ZXJuIGludCBnemdldGMoSW50UHRyIGd6RmlsZSk7DQoNCiAgICAgICAgW0RsbEltcG9ydCgiWkxJQjEuZGxsIiwgQ2FsbGluZ0NvbnZlbnRpb249Q2FsbGluZ0NvbnZlbnRpb24uQ2RlY2wpXQ0KICAgICAgICBwcml2YXRlIHN0YXRpYyBleHRlcm4gaW50IGd6cHV0YyhJbnRQdHIgZ3pGaWxlLCBpbnQgYyk7DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgICNyZWdpb24gUHJpdmF0ZSBkYXRhDQogICAgICAgIHByaXZhdGUgSW50UHRyIF9nekZpbGU7DQogICAgICAgIHByaXZhdGUgYm9vbCBfaXNEaXNwb3NlZCA9IGZhbHNlOw0KICAgICAgICBwcml2YXRlIGJvb2wgX2lzV3JpdGluZzsNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgICNyZWdpb24gQ29uc3RydWN0b3JzDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIENyZWF0ZXMgYSBuZXcgZmlsZSBhcyBhIHdyaXRlYWJsZSBHWmlwU3RyZWFtDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZmlsZU5hbWUiPlRoZSBuYW1lIG9mIHRoZSBjb21wcmVzc2VkIGZpbGUgdG8gY3JlYXRlPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJsZXZlbCI+VGhlIGNvbXByZXNzaW9uIGxldmVsIHRvIHVzZSB3aGVuIGFkZGluZyBkYXRhPC9wYXJhbT4NCiAgICAgICAgLy8vIDxleGNlcHRpb24gY3JlZj0iWkxpYkV4Y2VwdGlvbiI+SWYgYW4gZXJyb3Igb2NjdXJyZWQgaW4gdGhlIGludGVybmFsIHpsaWIgZnVuY3Rpb248L2V4Y2VwdGlvbj4NCgkJcHVibGljIEdaaXBTdHJlYW0oc3RyaW5nIGZpbGVOYW1lLCBDb21wcmVzc0xldmVsIGxldmVsKQ0KCQl7DQogICAgICAgICAgICBfaXNXcml0aW5nID0gdHJ1ZTsNCiAgICAgICAgICAgIF9nekZpbGUgPSBnem9wZW4oZmlsZU5hbWUsIFN0cmluZy5Gb3JtYXQoIndiezB9IiwgKGludClsZXZlbCkpOw0KICAgICAgICAgICAgaWYgKF9nekZpbGUgPT0gSW50UHRyLlplcm8pDQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFpMaWJFeGNlcHRpb24oLTEsICJDb3VsZCBub3Qgb3BlbiAiICsgZmlsZU5hbWUpOw0KCQl9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gT3BlbnMgYW4gZXhpc3RpbmcgZmlsZSBhcyBhIHJlYWRhYmxlIEdaaXBTdHJlYW0NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJmaWxlTmFtZSI+VGhlIG5hbWUgb2YgdGhlIGZpbGUgdG8gb3BlbjwvcGFyYW0+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9IlpMaWJFeGNlcHRpb24iPklmIGFuIGVycm9yIG9jY3VycmVkIGluIHRoZSBpbnRlcm5hbCB6bGliIGZ1bmN0aW9uPC9leGNlcHRpb24+DQogICAgICAgIHB1YmxpYyBHWmlwU3RyZWFtKHN0cmluZyBmaWxlTmFtZSkNCiAgICAgICAgew0KICAgICAgICAgICAgX2lzV3JpdGluZyA9IGZhbHNlOw0KICAgICAgICAgICAgX2d6RmlsZSA9IGd6b3BlbihmaWxlTmFtZSwgInJiIik7DQogICAgICAgICAgICBpZiAoX2d6RmlsZSA9PSBJbnRQdHIuWmVybykNCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWkxpYkV4Y2VwdGlvbigtMSwgIkNvdWxkIG5vdCBvcGVuICIgKyBmaWxlTmFtZSk7DQoNCiAgICAgICAgfQ0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgI3JlZ2lvbiBBY2Nlc3MgcHJvcGVydGllcw0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBSZXR1cm5zIHRydWUgb2YgdGhpcyBzdHJlYW0gY2FuIGJlIHJlYWQgZnJvbSwgZmFsc2Ugb3RoZXJ3aXNlDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyBvdmVycmlkZSBib29sIENhblJlYWQNCiAgICAgICAgew0KICAgICAgICAgICAgZ2V0DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgcmV0dXJuICFfaXNXcml0aW5nOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBSZXR1cm5zIGZhbHNlLg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwdWJsaWMgb3ZlcnJpZGUgYm9vbCBDYW5TZWVrDQogICAgICAgIHsNCiAgICAgICAgICAgIGdldA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHRzcmVhbSBpcyB3cml0ZWFibGUsIGZhbHNlIG90aGVyd2lzZQ0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwdWJsaWMgb3ZlcnJpZGUgYm9vbCBDYW5Xcml0ZQ0KICAgICAgICB7DQogICAgICAgICAgICBnZXQNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICByZXR1cm4gX2lzV3JpdGluZzsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgI3JlZ2lvbiBEZXN0cnVjdG9yICYgSURpc3Bvc2Ugc3R1ZmYNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBEZXN0cm95cyB0aGlzIGluc3RhbmNlDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIH5HWmlwU3RyZWFtKCkNCiAgICAgICAgew0KICAgICAgICAgICAgY2xlYW5VcChmYWxzZSk7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBDbG9zZXMgdGhlIGV4dGVybmFsIGZpbGUgaGFuZGxlDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyB2b2lkIERpc3Bvc2UoKQ0KICAgICAgICB7DQogICAgICAgICAgICBjbGVhblVwKHRydWUpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gRG9lcyB0aGUgYWN0dWFsIGNsb3Npbmcgb2YgdGhlIGZpbGUgaGFuZGxlLg0KICAgICAgICBwcml2YXRlIHZvaWQgY2xlYW5VcChib29sIGlzRGlzcG9zaW5nKQ0KICAgICAgICB7DQogICAgICAgICAgICBpZiAoIV9pc0Rpc3Bvc2VkKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGd6Y2xvc2UoX2d6RmlsZSk7DQogICAgICAgICAgICAgICAgX2lzRGlzcG9zZWQgPSB0cnVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIEJhc2ljIHJlYWRpbmcgYW5kIHdyaXRpbmcNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gQXR0ZW1wdHMgdG8gcmVhZCBhIG51bWJlciBvZiBieXRlcyBmcm9tIHRoZSBzdHJlYW0uDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iYnVmZmVyIj5UaGUgZGVzdGluYXRpb24gZGF0YSBidWZmZXI8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9mZnNldCI+VGhlIGluZGV4IG9mIHRoZSBmaXJzdCBkZXN0aW5hdGlvbiBieXRlIGluIDxjPmJ1ZmZlcjwvYz48L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvdW50Ij5UaGUgbnVtYmVyIG9mIGJ5dGVzIHJlcXVlc3RlZDwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQ8L3JldHVybnM+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9IkFyZ3VtZW50TnVsbEV4Y2VwdGlvbiI+SWYgPGM+YnVmZmVyPC9jPiBpcyBudWxsPC9leGNlcHRpb24+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9IkFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbiI+SWYgPGM+Y291bnQ8L2M+IG9yIDxjPm9mZnNldDwvYz4gYXJlIG5lZ2F0aXZlPC9leGNlcHRpb24+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9IkFyZ3VtZW50RXhjZXB0aW9uIj5JZiA8Yz5vZmZzZXQ8L2M+ICArIDxjPmNvdW50PC9jPiBpcyAmZ3Q7IGJ1ZmZlci5MZW5ndGg8L2V4Y2VwdGlvbj4NCiAgICAgICAgLy8vIDxleGNlcHRpb24gY3JlZj0iTm90U3VwcG9ydGVkRXhjZXB0aW9uIj5JZiB0aGlzIHN0cmVhbSBpcyBub3QgcmVhZGFibGUuPC9leGNlcHRpb24+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9Ik9iamVjdERpc3Bvc2VkRXhjZXB0aW9uIj5JZiB0aGlzIHN0cmVhbSBoYXMgYmVlbiBkaXNwb3NlZC48L2V4Y2VwdGlvbj4NCiAgICAgICAgcHVibGljIG92ZXJyaWRlIGludCBSZWFkKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCkNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKCFDYW5SZWFkKSB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCk7DQogICAgICAgICAgICBpZiAoYnVmZmVyID09IG51bGwpIHRocm93IG5ldyBBcmd1bWVudE51bGxFeGNlcHRpb24oKTsNCiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IGNvdW50IDwgMCkgdGhyb3cgbmV3IEFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbigpOw0KICAgICAgICAgICAgaWYgKChvZmZzZXQrY291bnQpID4gYnVmZmVyLkxlbmd0aCkgdGhyb3cgbmV3IEFyZ3VtZW50RXhjZXB0aW9uKCk7DQogICAgICAgICAgICBpZiAoX2lzRGlzcG9zZWQpIHRocm93IG5ldyBPYmplY3REaXNwb3NlZEV4Y2VwdGlvbigiR1ppcFN0cmVhbSIpOw0KDQogICAgICAgICAgICBHQ0hhbmRsZSBoID0gR0NIYW5kbGUuQWxsb2MoYnVmZmVyLCBHQ0hhbmRsZVR5cGUuUGlubmVkKTsNCiAgICAgICAgICAgIGludCByZXN1bHQ7DQogICAgICAgICAgICB0cnkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICByZXN1bHQgPSBnenJlYWQoX2d6RmlsZSwgaC5BZGRyT2ZQaW5uZWRPYmplY3QoKS5Ub0ludDMyKCkgKyBvZmZzZXQsIGNvdW50KTsNCiAgICAgICAgICAgICAgICBpZiAocmVzdWx0IDwgMCkNCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBmaW5hbGx5DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaC5GcmVlKCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gcmVzdWx0Ow0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gQXR0ZW1wdHMgdG8gcmVhZCBhIHNpbmdsZSBieXRlIGZyb20gdGhlIHN0cmVhbS4NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxyZXR1cm5zPlRoZSBieXRlIHRoYXQgd2FzIHJlYWQsIG9yIC0xIGluIGNhc2Ugb2YgZXJyb3Igb3IgRW5kLU9mLUZpbGU8L3JldHVybnM+DQogICAgICAgIHB1YmxpYyBvdmVycmlkZSBpbnQgUmVhZEJ5dGUoKQ0KICAgICAgICB7DQogICAgICAgICAgICBpZiAoIUNhblJlYWQpIHRocm93IG5ldyBOb3RTdXBwb3J0ZWRFeGNlcHRpb24oKTsNCiAgICAgICAgICAgIGlmIChfaXNEaXNwb3NlZCkgdGhyb3cgbmV3IE9iamVjdERpc3Bvc2VkRXhjZXB0aW9uKCJHWmlwU3RyZWFtIik7DQogICAgICAgICAgICByZXR1cm4gZ3pnZXRjKF9nekZpbGUpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gV3JpdGVzIGEgbnVtYmVyIG9mIGJ5dGVzIHRvIHRoZSBzdHJlYW0NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJidWZmZXIiPjwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib2Zmc2V0Ij48L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvdW50Ij48L3BhcmFtPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJBcmd1bWVudE51bGxFeGNlcHRpb24iPklmIDxjPmJ1ZmZlcjwvYz4gaXMgbnVsbDwvZXhjZXB0aW9uPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24iPklmIDxjPmNvdW50PC9jPiBvciA8Yz5vZmZzZXQ8L2M+IGFyZSBuZWdhdGl2ZTwvZXhjZXB0aW9uPg0KICAgICAgICAvLy8gPGV4Y2VwdGlvbiBjcmVmPSJBcmd1bWVudEV4Y2VwdGlvbiI+SWYgPGM+b2Zmc2V0PC9jPiAgKyA8Yz5jb3VudDwvYz4gaXMgJmd0OyBidWZmZXIuTGVuZ3RoPC9leGNlcHRpb24+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9Ik5vdFN1cHBvcnRlZEV4Y2VwdGlvbiI+SWYgdGhpcyBzdHJlYW0gaXMgbm90IHdyaXRlYWJsZS48L2V4Y2VwdGlvbj4NCiAgICAgICAgLy8vIDxleGNlcHRpb24gY3JlZj0iT2JqZWN0RGlzcG9zZWRFeGNlcHRpb24iPklmIHRoaXMgc3RyZWFtIGhhcyBiZWVuIGRpc3Bvc2VkLjwvZXhjZXB0aW9uPg0KICAgICAgICBwdWJsaWMgb3ZlcnJpZGUgdm9pZCBXcml0ZShieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmICghQ2FuV3JpdGUpIHRocm93IG5ldyBOb3RTdXBwb3J0ZWRFeGNlcHRpb24oKTsNCiAgICAgICAgICAgIGlmIChidWZmZXIgPT0gbnVsbCkgdGhyb3cgbmV3IEFyZ3VtZW50TnVsbEV4Y2VwdGlvbigpOw0KICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgY291bnQgPCAwKSB0aHJvdyBuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCk7DQogICAgICAgICAgICBpZiAoKG9mZnNldCtjb3VudCkgPiBidWZmZXIuTGVuZ3RoKSB0aHJvdyBuZXcgQXJndW1lbnRFeGNlcHRpb24oKTsNCiAgICAgICAgICAgIGlmIChfaXNEaXNwb3NlZCkgdGhyb3cgbmV3IE9iamVjdERpc3Bvc2VkRXhjZXB0aW9uKCJHWmlwU3RyZWFtIik7DQoNCiAgICAgICAgICAgIEdDSGFuZGxlIGggPSBHQ0hhbmRsZS5BbGxvYyhidWZmZXIsIEdDSGFuZGxlVHlwZS5QaW5uZWQpOw0KICAgICAgICAgICAgdHJ5DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaW50IHJlc3VsdCA9IGd6d3JpdGUoX2d6RmlsZSwgaC5BZGRyT2ZQaW5uZWRPYmplY3QoKS5Ub0ludDMyKCkgKyBvZmZzZXQsIGNvdW50KTsNCiAgICAgICAgICAgICAgICBpZiAocmVzdWx0IDwgMCkNCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBmaW5hbGx5DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaC5GcmVlKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBXcml0ZXMgYSBzaW5nbGUgYnl0ZSB0byB0aGUgc3RyZWFtDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idmFsdWUiPlRoZSBieXRlIHRvIGFkZCB0byB0aGUgc3RyZWFtLjwvcGFyYW0+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9Ik5vdFN1cHBvcnRlZEV4Y2VwdGlvbiI+SWYgdGhpcyBzdHJlYW0gaXMgbm90IHdyaXRlYWJsZS48L2V4Y2VwdGlvbj4NCiAgICAgICAgLy8vIDxleGNlcHRpb24gY3JlZj0iT2JqZWN0RGlzcG9zZWRFeGNlcHRpb24iPklmIHRoaXMgc3RyZWFtIGhhcyBiZWVuIGRpc3Bvc2VkLjwvZXhjZXB0aW9uPg0KICAgICAgICBwdWJsaWMgb3ZlcnJpZGUgdm9pZCBXcml0ZUJ5dGUoYnl0ZSB2YWx1ZSkNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKCFDYW5Xcml0ZSkgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigpOw0KICAgICAgICAgICAgaWYgKF9pc0Rpc3Bvc2VkKSB0aHJvdyBuZXcgT2JqZWN0RGlzcG9zZWRFeGNlcHRpb24oIkdaaXBTdHJlYW0iKTsNCg0KICAgICAgICAgICAgaW50IHJlc3VsdCA9IGd6cHV0YyhfZ3pGaWxlLCAoaW50KXZhbHVlKTsNCiAgICAgICAgICAgIGlmIChyZXN1bHQgPCAwKQ0KICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigpOw0KICAgICAgICB9DQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIFBvc2l0aW9uICYgbGVuZ3RoIHN0dWZmDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIE5vdCBzdXBwb3J0ZWQuDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idmFsdWUiPjwvcGFyYW0+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9Ik5vdFN1cHBvcnRlZEV4Y2VwdGlvbiI+QWx3YXlzIHRocm93bjwvZXhjZXB0aW9uPg0KICAgICAgICBwdWJsaWMgb3ZlcnJpZGUgdm9pZCBTZXRMZW5ndGgobG9uZyB2YWx1ZSkNCiAgICAgICAgew0KICAgICAgICAgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gIE5vdCBzdXBwcG9ydGVkLg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9mZnNldCI+PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcmlnaW4iPjwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9Ik5vdFN1cHBvcnRlZEV4Y2VwdGlvbiI+QWx3YXlzIHRocm93bjwvZXhjZXB0aW9uPg0KICAgICAgICBwdWJsaWMgb3ZlcnJpZGUgbG9uZyBTZWVrKGxvbmcgb2Zmc2V0LCBTZWVrT3JpZ2luIG9yaWdpbikNCiAgICAgICAgew0KICAgICAgICAgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gRmx1c2hlcyB0aGUgPGM+R1ppcFN0cmVhbTwvYz4uDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cmVtYXJrcz5JbiB0aGlzIGltcGxlbWVudGF0aW9uLCB0aGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcuIFRoaXMgaXMgYmVjYXVzZSBleGNlc3NpdmUNCiAgICAgICAgLy8vIGZsdXNoaW5nIG1heSBkZWdyYWRlIHRoZSBhY2hpZXZhYmxlIGNvbXByZXNzaW9uIHJhdGVzLjwvcmVtYXJrcz4NCiAgICAgICAgcHVibGljIG92ZXJyaWRlIHZvaWQgRmx1c2goKQ0KICAgICAgICB7DQogICAgICAgICAgICAvLyBsZWZ0IGVtcHR5IG9uIHB1cnBvc2UNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEdldHMvc2V0cyB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgPGM+R1ppcFN0cmVhbTwvYz4uIE5vdCBzdXBwcG9ydGVkLg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHJlbWFya3M+SW4gdGhpcyBpbXBsZW1lbnRhdGlvbiB0aGlzIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQ8L3JlbWFya3M+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9Ik5vdFN1cHBvcnRlZEV4Y2VwdGlvbiI+QWx3YXlzIHRocm93bjwvZXhjZXB0aW9uPg0KICAgICAgICBwdWJsaWMgb3ZlcnJpZGUgbG9uZyBQb3NpdGlvbg0KICAgICAgICB7DQogICAgICAgICAgICBnZXQNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBzZXQNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBHZXRzIHRoZSBzaXplIG9mIHRoZSBzdHJlYW0uIE5vdCBzdXBwcG9ydGVkLg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHJlbWFya3M+SW4gdGhpcyBpbXBsZW1lbnRhdGlvbiB0aGlzIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQ8L3JlbWFya3M+DQogICAgICAgIC8vLyA8ZXhjZXB0aW9uIGNyZWY9Ik5vdFN1cHBvcnRlZEV4Y2VwdGlvbiI+QWx3YXlzIHRocm93bjwvZXhjZXB0aW9uPg0KICAgICAgICBwdWJsaWMgb3ZlcnJpZGUgbG9uZyBMZW5ndGgNCiAgICAgICAgew0KICAgICAgICAgICAgZ2V0DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgICNlbmRyZWdpb24NCiAgICB9DQp9DQo=