Ly8NCi8vIENvcHlyaWdodCAoYykgMjAxOS0yMDIyIEFkdmFuY2VkIE1pY3JvIERldmljZXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi8vDQovLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5DQovLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbA0KLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cw0KLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbA0KLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzDQovLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOg0KLy8NCi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluDQovLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4NCi8vDQovLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUg0KLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksDQovLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFDQovLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSDQovLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLA0KLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTg0KLy8gVEhFIFNPRlRXQVJFLg0KLy8NCg0KI2luY2x1ZGUgIkNvbW1vbi5oIg0KI2luY2x1ZGUgIlRlc3RzLmgiDQojaW5jbHVkZSA8dGhyZWFkPg0KDQovLyBEZWZpbmUgdG8gdGhlIHNhbWUgdmFsdWUgYXMgeW91IGRpZCBmb3IgRDNEMTJNZW1BbGxvYy5jcHAuDQojaWZuZGVmIEQzRDEyTUFfREVCVUdfTUFSR0lODQogICAgI2RlZmluZSBEM0QxMk1BX0RFQlVHX01BUkdJTiAwDQojZW5kaWYNCg0KZXh0ZXJuIElEM0QxMkdyYXBoaWNzQ29tbWFuZExpc3QqIEJlZ2luQ29tbWFuZExpc3QoKTsNCmV4dGVybiBEWEdJX0FEQVBURVJfREVTQzEgZ19BZGFwdGVyRGVzYzsNCmV4dGVybiB2b2lkIEVuZENvbW1hbmRMaXN0KElEM0QxMkdyYXBoaWNzQ29tbWFuZExpc3QqIGNtZExpc3QpOw0KDQplbnVtIENPTkZJR19UWVBFDQp7DQogICAgQ09ORklHX1RZUEVfTUlOSU1VTSwNCiAgICBDT05GSUdfVFlQRV9TTUFMTCwNCiAgICBDT05GSUdfVFlQRV9BVkVSQUdFLA0KICAgIENPTkZJR19UWVBFX0xBUkdFLA0KICAgIENPTkZJR19UWVBFX01BWElNVU0sDQogICAgQ09ORklHX1RZUEVfQ09VTlQNCn07DQoNCmVudW0gY2xhc3MgRlJFRV9PUkRFUiB7IEZPUldBUkQsIEJBQ0tXQVJELCBSQU5ET00sIENPVU5UIH07DQoNCnN0YXRpYyBjb25zdCBjaGFyKiBDT0RFX0RFU0NSSVBUSU9OID0gIkQzRDEyTUEgVGVzdHMiOw0Kc3RhdGljIGNvbnN0ZXhwciBVSU5UNjQgS0lMT0JZVEUgPSAxMDI0Ow0Kc3RhdGljIGNvbnN0ZXhwciBVSU5UNjQgTUVHQUJZVEUgPSAxMDI0ICogS0lMT0JZVEU7DQpzdGF0aWMgY29uc3RleHByIENPTkZJR19UWVBFIENvbmZpZ1R5cGUgPSBDT05GSUdfVFlQRV9BVkVSQUdFOw0Kc3RhdGljIGNvbnN0IGNoYXIqIEZSRUVfT1JERVJfTkFNRVNbXSA9IHsgIkZPUldBUkQiLCAiQkFDS1dBUkQiLCAiUkFORE9NIiwgfTsNCg0Kc3RhdGljIHZvaWQgQ3VycmVudFRpbWVUb1N0cihzdGQ6OnN0cmluZyYgb3V0KQ0Kew0KICAgIHRpbWVfdCByYXdUaW1lOyB0aW1lKCZyYXdUaW1lKTsNCiAgICBzdHJ1Y3QgdG0gdGltZUluZm87IGxvY2FsdGltZV9zKCZ0aW1lSW5mbywgJnJhd1RpbWUpOw0KICAgIGNoYXIgdGltZVN0clsxMjhdOw0KICAgIHN0cmZ0aW1lKHRpbWVTdHIsIF9jb3VudG9mKHRpbWVTdHIpLCAiJWMiLCAmdGltZUluZm8pOw0KICAgIG91dCA9IHRpbWVTdHI7DQp9DQoNCnN0YXRpYyBmbG9hdCBUb0Zsb2F0U2Vjb25kcyhkdXJhdGlvbiBkKQ0Kew0KICAgIHJldHVybiBzdGQ6OmNocm9ubzo6ZHVyYXRpb25fY2FzdDxzdGQ6OmNocm9ubzo6ZHVyYXRpb248ZmxvYXQ+PihkKS5jb3VudCgpOw0KfQ0KDQpzdGF0aWMgY29uc3QgY2hhciogQWxnb3JpdGhtVG9TdHIoRDNEMTJNQTo6UE9PTF9GTEFHUyBhbGdvcml0aG0pDQp7DQogICAgc3dpdGNoIChhbGdvcml0aG0pDQogICAgew0KICAgIGNhc2UgRDNEMTJNQTo6UE9PTF9GTEFHX0FMR09SSVRITV9MSU5FQVI6DQogICAgICAgIHJldHVybiAiTGluZWFyIjsNCiAgICBjYXNlIDA6DQogICAgICAgIHJldHVybiAiVExTRiI7DQogICAgZGVmYXVsdDoNCiAgICAgICAgYXNzZXJ0KDApOw0KICAgICAgICByZXR1cm4gIiI7DQogICAgfQ0KfQ0KDQpzdGF0aWMgY29uc3QgY2hhciogVmlydHVhbEFsZ29yaXRobVRvU3RyKEQzRDEyTUE6OlZJUlRVQUxfQkxPQ0tfRkxBR1MgYWxnb3JpdGhtKQ0Kew0KICAgIHN3aXRjaCAoYWxnb3JpdGhtKQ0KICAgIHsNCiAgICBjYXNlIEQzRDEyTUE6OlZJUlRVQUxfQkxPQ0tfRkxBR19BTEdPUklUSE1fTElORUFSOg0KICAgICAgICByZXR1cm4gIkxpbmVhciI7DQogICAgY2FzZSAwOg0KICAgICAgICByZXR1cm4gIlRMU0YiOw0KICAgIGRlZmF1bHQ6DQogICAgICAgIGFzc2VydCgwKTsNCiAgICAgICAgcmV0dXJuICIiOw0KICAgIH0NCn0NCg0Kc3RhdGljIGNvbnN0IHdjaGFyX3QqIERlZnJhZ21lbnRhdGlvbkFsZ29yaXRobVRvU3RyKFVJTlQzMiBhbGdvcml0aG0pDQp7DQogICAgc3dpdGNoIChhbGdvcml0aG0pDQogICAgew0KICAgIGNhc2UgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX0ZMQUdfQUxHT1JJVEhNX0JBTEFOQ0VEOg0KICAgICAgICByZXR1cm4gTCJCYWxhbmNlZCI7DQogICAgY2FzZSBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fRkxBR19BTEdPUklUSE1fRkFTVDoNCiAgICAgICAgcmV0dXJuIEwiRmFzdCI7DQogICAgY2FzZSBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fRkxBR19BTEdPUklUSE1fRlVMTDoNCiAgICAgICAgcmV0dXJuIEwiRnVsbCI7DQogICAgY2FzZSAwOg0KICAgICAgICByZXR1cm4gTCJEZWZhdWx0IjsNCiAgICBkZWZhdWx0Og0KICAgICAgICBhc3NlcnQoMCk7DQogICAgICAgIHJldHVybiBMIiI7DQogICAgfQ0KfQ0KDQpzdHJ1Y3QgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbg0Kew0KICAgIENvbVB0cjxJRDNEMTJSZXNvdXJjZT4gcmVzb3VyY2U7DQogICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jYXRpb247DQogICAgVUlOVDY0IHNpemUgPSBVSU5UNjRfTUFYOw0KICAgIFVJTlQgZGF0YVNlZWQgPSAwOw0KDQogICAgdm9pZCBSZXNldCgpDQogICAgew0KICAgICAgICByZXNvdXJjZS5SZXNldCgpOw0KICAgICAgICBhbGxvY2F0aW9uLlJlc2V0KCk7DQogICAgICAgIHNpemUgPSBVSU5UNjRfTUFYOw0KICAgICAgICBkYXRhU2VlZCA9IDA7DQogICAgfQ0KfTsNCg0KdGVtcGxhdGU8dHlwZW5hbWUgRDNEMTJfUkVTT1VSQ0VfREVTQ19UPg0Kc3RhdGljIHZvaWQgRmlsbFJlc291cmNlRGVzY0ZvckJ1ZmZlcihEM0QxMl9SRVNPVVJDRV9ERVNDX1QmIG91dFJlc291cmNlRGVzYywgVUlOVDY0IHNpemUpDQp7DQogICAgb3V0UmVzb3VyY2VEZXNjID0ge307DQogICAgb3V0UmVzb3VyY2VEZXNjLkRpbWVuc2lvbiA9IEQzRDEyX1JFU09VUkNFX0RJTUVOU0lPTl9CVUZGRVI7DQogICAgb3V0UmVzb3VyY2VEZXNjLkFsaWdubWVudCA9IDA7DQogICAgb3V0UmVzb3VyY2VEZXNjLldpZHRoID0gc2l6ZTsNCiAgICBvdXRSZXNvdXJjZURlc2MuSGVpZ2h0ID0gMTsNCiAgICBvdXRSZXNvdXJjZURlc2MuRGVwdGhPckFycmF5U2l6ZSA9IDE7DQogICAgb3V0UmVzb3VyY2VEZXNjLk1pcExldmVscyA9IDE7DQogICAgb3V0UmVzb3VyY2VEZXNjLkZvcm1hdCA9IERYR0lfRk9STUFUX1VOS05PV047DQogICAgb3V0UmVzb3VyY2VEZXNjLlNhbXBsZURlc2MuQ291bnQgPSAxOw0KICAgIG91dFJlc291cmNlRGVzYy5TYW1wbGVEZXNjLlF1YWxpdHkgPSAwOw0KICAgIG91dFJlc291cmNlRGVzYy5MYXlvdXQgPSBEM0QxMl9URVhUVVJFX0xBWU9VVF9ST1dfTUFKT1I7DQogICAgb3V0UmVzb3VyY2VEZXNjLkZsYWdzID0gRDNEMTJfUkVTT1VSQ0VfRkxBR19OT05FOw0KfQ0KDQpzdGF0aWMgdm9pZCBGaWxsRGF0YSh2b2lkKiBvdXRQdHIsIGNvbnN0IFVJTlQ2NCBzaXplSW5CeXRlcywgVUlOVCBzZWVkKQ0Kew0KICAgIFVJTlQqIG91dFZhbHVlcyA9IChVSU5UKilvdXRQdHI7DQogICAgY29uc3QgVUlOVDY0IHNpemVJblZhbHVlcyA9IHNpemVJbkJ5dGVzIC8gc2l6ZW9mKFVJTlQpOw0KICAgIFVJTlQgdmFsdWUgPSBzZWVkOw0KICAgIGZvcihVSU5UIGkgPSAwOyBpIDwgc2l6ZUluVmFsdWVzOyArK2kpDQogICAgew0KICAgICAgICBvdXRWYWx1ZXNbaV0gPSB2YWx1ZSsrOw0KICAgIH0NCn0NCg0Kc3RhdGljIHZvaWQgRmlsbEFsbG9jYXRpb25zRGF0YShjb25zdCBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4qIGFsbG9jcywgc2l6ZV90IGFsbG9jQ291bnQsIFVJTlQgc2VlZCkNCnsNCiAgICBzdGQ6OmZvcl9lYWNoKGFsbG9jcywgYWxsb2NzICsgYWxsb2NDb3VudCwgW3NlZWRdKGNvbnN0IENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiYgYWxsb2MpDQogICAgICAgIHsNCiAgICAgICAgICAgIEQzRDEyX1JBTkdFIHJhbmdlID0ge307DQogICAgICAgICAgICB2b2lkKiBwdHI7DQogICAgICAgICAgICBDSEVDS19IUihhbGxvYy0+R2V0UmVzb3VyY2UoKS0+TWFwKDAsICZyYW5nZSwgJnB0cikpOw0KICAgICAgICAgICAgRmlsbERhdGEocHRyLCBhbGxvYy0+R2V0U2l6ZSgpLCBzZWVkKTsNCiAgICAgICAgICAgIGFsbG9jLT5HZXRSZXNvdXJjZSgpLT5Vbm1hcCgwLCBudWxscHRyKTsNCiAgICAgICAgfSk7DQp9DQoNCnN0YXRpYyB2b2lkIEZpbGxBbGxvY2F0aW9uc0RhdGFHUFUoY29uc3QgVGVzdENvbnRleHQmIGN0eCwgY29uc3QgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+KiBhbGxvY3MsIHNpemVfdCBhbGxvY0NvdW50LCBVSU5UIHNlZWQpDQp7DQogICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgIGFsbG9jRGVzYy5IZWFwVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9VUExPQUQ7DQogICAgYWxsb2NEZXNjLkV4dHJhSGVhcEZsYWdzID0gRDNEMTJfSEVBUF9GTEFHX0FMTE9XX09OTFlfQlVGRkVSUzsNCiAgICBhbGxvY0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdTOjpBTExPQ0FUSU9OX0ZMQUdfQ09NTUlUVEVEOw0KDQogICAgc3RkOjp2ZWN0b3I8RDNEMTJfUkVTT1VSQ0VfQkFSUklFUj4gYmFycmllcnM7DQogICAgc3RkOjp2ZWN0b3I8Q29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+PiB1cGxvYWRBbGxvY3M7DQogICAgYmFycmllcnMucmVzZXJ2ZShhbGxvY0NvdW50KTsNCiAgICB1cGxvYWRBbGxvY3MucmVzZXJ2ZShhbGxvY0NvdW50KTsNCg0KICAgIC8vIE1vdmUgcmVzb3VyY2UgaW50byByaWdodCBzdGF0ZQ0KICAgIEQzRDEyX1JFU09VUkNFX0JBUlJJRVIgYmFycmllciA9IHt9Ow0KICAgIGJhcnJpZXIuVHlwZSA9IEQzRDEyX1JFU09VUkNFX0JBUlJJRVJfVFlQRV9UUkFOU0lUSU9OOw0KICAgIGJhcnJpZXIuRmxhZ3MgPSBEM0QxMl9SRVNPVVJDRV9CQVJSSUVSX0ZMQUdfTk9ORTsNCiAgICBiYXJyaWVyLlRyYW5zaXRpb24uU3VicmVzb3VyY2UgPSBEM0QxMl9SRVNPVVJDRV9CQVJSSUVSX0FMTF9TVUJSRVNPVVJDRVM7DQogICAgYmFycmllci5UcmFuc2l0aW9uLlN0YXRlQmVmb3JlID0gRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9ERVNUOw0KDQogICAgSUQzRDEyR3JhcGhpY3NDb21tYW5kTGlzdCogY2wgPSBCZWdpbkNvbW1hbmRMaXN0KCk7DQogICAgc3RkOjpmb3JfZWFjaChhbGxvY3MsIGFsbG9jcyArIGFsbG9jQ291bnQsIFsmXShjb25zdCBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4mIGFsbG9jKQ0KICAgICAgICB7DQogICAgICAgICAgICAvLyBDb3B5IG9ubHkgYnVmZmVycyBmb3Igbm93DQogICAgICAgICAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc0Rlc2MgPSBhbGxvYy0+R2V0UmVzb3VyY2UoKS0+R2V0RGVzYygpOw0KICAgICAgICAgICAgaWYgKHJlc0Rlc2MuRGltZW5zaW9uID09IEQzRDEyX1JFU09VUkNFX0RJTUVOU0lPTl9CVUZGRVIpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IHVwbG9hZEFsbG9jOw0KICAgICAgICAgICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsDQogICAgICAgICAgICAgICAgICAgIG51bGxwdHIsICZ1cGxvYWRBbGxvYywgSUlEX05VTEwsIG51bGxwdHIpKTsNCg0KICAgICAgICAgICAgICAgIEQzRDEyX1JBTkdFIHJhbmdlID0ge307DQogICAgICAgICAgICAgICAgdm9pZCogcHRyOw0KICAgICAgICAgICAgICAgIENIRUNLX0hSKHVwbG9hZEFsbG9jLT5HZXRSZXNvdXJjZSgpLT5NYXAoMCwgJnJhbmdlLCAmcHRyKSk7DQogICAgICAgICAgICAgICAgRmlsbERhdGEocHRyLCByZXNEZXNjLldpZHRoLCBzZWVkKTsNCiAgICAgICAgICAgICAgICB1cGxvYWRBbGxvYy0+R2V0UmVzb3VyY2UoKS0+VW5tYXAoMCwgbnVsbHB0cik7DQoNCiAgICAgICAgICAgICAgICBjbC0+Q29weVJlc291cmNlKGFsbG9jLT5HZXRSZXNvdXJjZSgpLCB1cGxvYWRBbGxvYy0+R2V0UmVzb3VyY2UoKSk7DQogICAgICAgICAgICAgICAgdXBsb2FkQWxsb2NzLmVtcGxhY2VfYmFjayhzdGQ6Om1vdmUodXBsb2FkQWxsb2MpKTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgYmFycmllci5UcmFuc2l0aW9uLnBSZXNvdXJjZSA9IGFsbG9jLT5HZXRSZXNvdXJjZSgpOw0KICAgICAgICAgICAgYmFycmllci5UcmFuc2l0aW9uLlN0YXRlQWZ0ZXIgPSAoRDNEMTJfUkVTT1VSQ0VfU1RBVEVTKSh1aW50cHRyX3QpYWxsb2MtPkdldFByaXZhdGVEYXRhKCk7DQogICAgICAgICAgICBiYXJyaWVycy5lbXBsYWNlX2JhY2soYmFycmllcik7DQogICAgICAgIH0pOw0KICAgIGNsLT5SZXNvdXJjZUJhcnJpZXIoc3RhdGljX2Nhc3Q8VUlOVD4oYWxsb2NDb3VudCksIGJhcnJpZXJzLmRhdGEoKSk7DQogICAgRW5kQ29tbWFuZExpc3QoY2wpOw0KfQ0KDQpzdGF0aWMgYm9vbCBWYWxpZGF0ZURhdGEoY29uc3Qgdm9pZCogcHRyLCBjb25zdCBVSU5UNjQgc2l6ZUluQnl0ZXMsIFVJTlQgc2VlZCkNCnsNCiAgICBjb25zdCBVSU5UKiB2YWx1ZXMgPSAoY29uc3QgVUlOVCopcHRyOw0KICAgIGNvbnN0IFVJTlQ2NCBzaXplSW5WYWx1ZXMgPSBzaXplSW5CeXRlcyAvIHNpemVvZihVSU5UKTsNCiAgICBVSU5UIHZhbHVlID0gc2VlZDsNCiAgICBmb3IoVUlOVCBpID0gMDsgaSA8IHNpemVJblZhbHVlczsgKytpKQ0KICAgIHsNCiAgICAgICAgaWYodmFsdWVzW2ldICE9IHZhbHVlKyspDQogICAgICAgIHsNCiAgICAgICAgICAgIC8vQ0hFQ0tfQk9PTCgwICYmICJWYWxpZGF0ZURhdGEgZmFpbGVkLiIpOw0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOw0KICAgICAgICB9DQogICAgfQ0KICAgIHJldHVybiB0cnVlOw0KfQ0KDQpzdGF0aWMgYm9vbCBWYWxpZGF0ZURhdGFaZXJvKGNvbnN0IHZvaWQqIHB0ciwgY29uc3QgVUlOVDY0IHNpemVJbkJ5dGVzKQ0Kew0KICAgIGNvbnN0IFVJTlQqIHZhbHVlcyA9IChjb25zdCBVSU5UKilwdHI7DQogICAgY29uc3QgVUlOVDY0IHNpemVJblZhbHVlcyA9IHNpemVJbkJ5dGVzIC8gc2l6ZW9mKFVJTlQpOw0KICAgIGZvcihVSU5UIGkgPSAwOyBpIDwgc2l6ZUluVmFsdWVzOyArK2kpDQogICAgew0KICAgICAgICBpZih2YWx1ZXNbaV0gIT0gMCkNCiAgICAgICAgew0KICAgICAgICAgICAgLy9DSEVDS19CT09MKDAgJiYgIlZhbGlkYXRlRGF0YSBmYWlsZWQuIik7DQogICAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgIH0NCiAgICB9DQogICAgcmV0dXJuIHRydWU7DQp9DQoNCnN0YXRpYyB2b2lkIFZhbGlkYXRlQWxsb2NhdGlvbnNEYXRhKGNvbnN0IENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiogYWxsb2NzLCBzaXplX3QgYWxsb2NDb3VudCwgVUlOVCBzZWVkKQ0Kew0KICAgIHN0ZDo6Zm9yX2VhY2goYWxsb2NzLCBhbGxvY3MgKyBhbGxvY0NvdW50LCBbc2VlZF0oY29uc3QgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+JiBhbGxvYykNCiAgICAgICAgew0KICAgICAgICAgICAgRDNEMTJfUkFOR0UgcmFuZ2UgPSB7fTsNCiAgICAgICAgICAgIHZvaWQqIHB0cjsNCiAgICAgICAgICAgIENIRUNLX0hSKGFsbG9jLT5HZXRSZXNvdXJjZSgpLT5NYXAoMCwgJnJhbmdlLCAmcHRyKSk7DQogICAgICAgICAgICBDSEVDS19CT09MKFZhbGlkYXRlRGF0YShwdHIsIGFsbG9jLT5HZXRTaXplKCksIHNlZWQpKTsNCiAgICAgICAgICAgIGFsbG9jLT5HZXRSZXNvdXJjZSgpLT5Vbm1hcCgwLCBudWxscHRyKTsNCiAgICAgICAgfSk7DQp9DQoNCnN0YXRpYyB2b2lkIFZhbGlkYXRlQWxsb2NhdGlvbnNEYXRhR1BVKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgsIGNvbnN0IENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiogYWxsb2NzLCBzaXplX3QgYWxsb2NDb3VudCwgVUlOVCBzZWVkKQ0Kew0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfUkVBREJBQ0s7DQogICAgYWxsb2NEZXNjLkV4dHJhSGVhcEZsYWdzID0gRDNEMTJfSEVBUF9GTEFHX0FMTE9XX09OTFlfQlVGRkVSUzsNCiAgICBhbGxvY0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdTOjpBTExPQ0FUSU9OX0ZMQUdfQ09NTUlUVEVEOw0KDQogICAgc3RkOjp2ZWN0b3I8RDNEMTJfUkVTT1VSQ0VfQkFSUklFUj4gYmFycmllcnM7DQogICAgc3RkOjp2ZWN0b3I8Q29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+PiBkb3dubG9hZEFsbG9jczsNCiAgICBiYXJyaWVycy5yZXNlcnZlKGFsbG9jQ291bnQpOw0KICAgIGRvd25sb2FkQWxsb2NzLnJlc2VydmUoYWxsb2NDb3VudCk7DQoNCiAgICAvLyBNb3ZlIHJlc291cmNlIGludG8gcmlnaHQgc3RhdGUNCiAgICBEM0QxMl9SRVNPVVJDRV9CQVJSSUVSIGJhcnJpZXIgPSB7fTsNCiAgICBiYXJyaWVyLlR5cGUgPSBEM0QxMl9SRVNPVVJDRV9CQVJSSUVSX1RZUEVfVFJBTlNJVElPTjsNCiAgICBiYXJyaWVyLkZsYWdzID0gRDNEMTJfUkVTT1VSQ0VfQkFSUklFUl9GTEFHX05PTkU7DQogICAgYmFycmllci5UcmFuc2l0aW9uLlN1YnJlc291cmNlID0gRDNEMTJfUkVTT1VSQ0VfQkFSUklFUl9BTExfU1VCUkVTT1VSQ0VTOw0KICAgIGJhcnJpZXIuVHJhbnNpdGlvbi5TdGF0ZUFmdGVyID0gRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9TT1VSQ0U7DQoNCiAgICBJRDNEMTJHcmFwaGljc0NvbW1hbmRMaXN0KiBjbCA9IEJlZ2luQ29tbWFuZExpc3QoKTsNCiAgICBzaXplX3QgcmVzQ291bnQgPSBhbGxvY0NvdW50Ow0KICAgIHN0ZDo6Zm9yX2VhY2goYWxsb2NzLCBhbGxvY3MgKyBhbGxvY0NvdW50LCBbJl0oY29uc3QgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+JiBhbGxvYykNCiAgICAgICAgew0KICAgICAgICAgICAgLy8gQ2hlY2sgb25seSBidWZmZXJzIGZvciBub3cNCiAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzRGVzYyA9IGFsbG9jLT5HZXRSZXNvdXJjZSgpLT5HZXREZXNjKCk7DQogICAgICAgICAgICBpZiAocmVzRGVzYy5EaW1lbnNpb24gPT0gRDNEMTJfUkVTT1VSQ0VfRElNRU5TSU9OX0JVRkZFUikNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gZG93bmxvYWRBbGxvYzsNCiAgICAgICAgICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9ERVNULA0KICAgICAgICAgICAgICAgICAgICBudWxscHRyLCAmZG93bmxvYWRBbGxvYywgSUlEX05VTEwsIG51bGxwdHIpKTsNCg0KICAgICAgICAgICAgICAgIGJhcnJpZXIuVHJhbnNpdGlvbi5wUmVzb3VyY2UgPSBhbGxvYy0+R2V0UmVzb3VyY2UoKTsNCiAgICAgICAgICAgICAgICBiYXJyaWVyLlRyYW5zaXRpb24uU3RhdGVCZWZvcmUgPSAoRDNEMTJfUkVTT1VSQ0VfU1RBVEVTKSh1aW50cHRyX3QpYWxsb2MtPkdldFByaXZhdGVEYXRhKCk7DQogICAgICAgICAgICAgICAgYmFycmllcnMuZW1wbGFjZV9iYWNrKGJhcnJpZXIpOw0KICAgICAgICAgICAgICAgIGRvd25sb2FkQWxsb2NzLmVtcGxhY2VfYmFjayhzdGQ6Om1vdmUoZG93bmxvYWRBbGxvYykpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgICAgIC0tcmVzQ291bnQ7DQogICAgICAgIH0pOw0KDQogICAgY2wtPlJlc291cmNlQmFycmllcihzdGF0aWNfY2FzdDxVSU5UPihyZXNDb3VudCksIGJhcnJpZXJzLmRhdGEoKSk7DQogICAgZm9yIChzaXplX3QgaSA9IDAsIGogPSAwOyBpIDwgcmVzQ291bnQ7ICsraikNCiAgICB7DQogICAgICAgIGlmIChhbGxvY3Nbal0tPkdldFJlc291cmNlKCktPkdldERlc2MoKS5EaW1lbnNpb24gPT0gRDNEMTJfUkVTT1VSQ0VfRElNRU5TSU9OX0JVRkZFUikNCiAgICAgICAgew0KICAgICAgICAgICAgY2wtPkNvcHlSZXNvdXJjZShkb3dubG9hZEFsbG9jcy5hdChpKS0+R2V0UmVzb3VyY2UoKSwgYWxsb2NzW2pdLT5HZXRSZXNvdXJjZSgpKTsNCiAgICAgICAgICAgIGJhcnJpZXJzLmF0KGkpLlRyYW5zaXRpb24uU3RhdGVBZnRlciA9IGJhcnJpZXJzLmF0KGkpLlRyYW5zaXRpb24uU3RhdGVCZWZvcmU7DQogICAgICAgICAgICBiYXJyaWVycy5hdChpKS5UcmFuc2l0aW9uLlN0YXRlQmVmb3JlID0gRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9TT1VSQ0U7DQogICAgICAgICAgICArK2k7DQogICAgICAgIH0NCiAgICB9DQogICAgY2wtPlJlc291cmNlQmFycmllcihzdGF0aWNfY2FzdDxVSU5UPihyZXNDb3VudCksIGJhcnJpZXJzLmRhdGEoKSk7DQogICAgRW5kQ29tbWFuZExpc3QoY2wpOw0KDQogICAgZm9yIChhdXRvJiBhbGxvYyA6IGRvd25sb2FkQWxsb2NzKQ0KICAgIHsNCiAgICAgICAgRDNEMTJfUkFOR0UgcmFuZ2UgPSB7fTsNCiAgICAgICAgdm9pZCogcHRyOw0KICAgICAgICBDSEVDS19IUihhbGxvYy0+R2V0UmVzb3VyY2UoKS0+TWFwKDAsICZyYW5nZSwgJnB0cikpOw0KICAgICAgICBDSEVDS19CT09MKFZhbGlkYXRlRGF0YShwdHIsIGFsbG9jLT5HZXRSZXNvdXJjZSgpLT5HZXREZXNjKCkuV2lkdGgsIHNlZWQpKTsNCiAgICAgICAgYWxsb2MtPkdldFJlc291cmNlKCktPlVubWFwKDAsIG51bGxwdHIpOw0KICAgIH0NCn0NCg0Kc3RhdGljIHZvaWQgU2F2ZVN0YXRzU3RyaW5nVG9GaWxlKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgsIGNvbnN0IHdjaGFyX3QqIGRzdEZpbGVQYXRoLCBCT09MIGRldGFpbGVkID0gVFJVRSkNCnsNCiAgICBXQ0hBUiogcyA9IG51bGxwdHI7DQogICAgY3R4LmFsbG9jYXRvci0+QnVpbGRTdGF0c1N0cmluZygmcywgZGV0YWlsZWQpOw0KICAgIFNhdmVGaWxlKGRzdEZpbGVQYXRoLCBzLCB3Y3NsZW4ocykgKiBzaXplb2YoV0NIQVIpKTsNCiAgICBjdHguYWxsb2NhdG9yLT5GcmVlU3RhdHNTdHJpbmcocyk7DQp9DQoNCg0Kc3RhdGljIHZvaWQgVGVzdERlYnVnTWFyZ2luKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgdXNpbmcgbmFtZXNwYWNlIEQzRDEyTUE7DQoNCiAgICBpZihEM0QxMk1BX0RFQlVHX01BUkdJTiA9PSAwKQ0KICAgIHsNCiAgICAgICAgcmV0dXJuOw0KICAgIH0NCg0KICAgIHdwcmludGYoTCJUZXN0IEQzRDEyTUFfREVCVUdfTUFSR0lOID0gJXVcbiIsICh1aW50MzJfdClEM0QxMk1BX0RFQlVHX01BUkdJTik7DQoNCiAgICBBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc0Rlc2MgPSB7fTsNCg0KICAgIFBPT0xfREVTQyBwb29sRGVzYyA9IHt9Ow0KICAgIHBvb2xEZXNjLkhlYXBQcm9wZXJ0aWVzLlR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfVVBMT0FEOw0KDQogICAgZm9yKHNpemVfdCBhbGdvcml0aG1JbmRleCA9IDA7IGFsZ29yaXRobUluZGV4IDwgMjsgKythbGdvcml0aG1JbmRleCkNCiAgICB7DQogICAgICAgIHN3aXRjaChhbGdvcml0aG1JbmRleCkNCiAgICAgICAgew0KICAgICAgICBjYXNlIDA6IHBvb2xEZXNjLkZsYWdzID0gUE9PTF9GTEFHX05PTkU7IGJyZWFrOw0KICAgICAgICBjYXNlIDE6IHBvb2xEZXNjLkZsYWdzID0gUE9PTF9GTEFHX0FMR09SSVRITV9MSU5FQVI7IGJyZWFrOw0KICAgICAgICBkZWZhdWx0OiBhc3NlcnQoMCk7DQogICAgICAgIH0NCiAgICAgICAgQ29tUHRyPFBvb2w+IHBvb2w7DQogICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVBvb2woJnBvb2xEZXNjLCAmcG9vbCkpOw0KDQogICAgICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gcG9vbC5HZXQoKTsNCg0KICAgICAgICAvLyBDcmVhdGUgZmV3IGJ1ZmZlcnMgb2YgZGlmZmVyZW50IHNpemUuDQogICAgICAgIGNvbnN0IHNpemVfdCBCVUZfQ09VTlQgPSAxMDsNCiAgICAgICAgQ29tUHRyPEFsbG9jYXRpb24+IGJ1ZmZlcnNbQlVGX0NPVU5UXTsNCiAgICAgICAgZm9yKHNpemVfdCBhbGxvY0luZGV4ID0gMDsgYWxsb2NJbmRleCA8IDEwOyArK2FsbG9jSW5kZXgpDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbnN0IGJvb2wgaXNMYXN0ID0gYWxsb2NJbmRleCA9PSBCVUZfQ09VTlQgLSAxOw0KICAgICAgICAgICAgRmlsbFJlc291cmNlRGVzY0ZvckJ1ZmZlcihyZXNEZXNjLCAoVUlOVDY0KShhbGxvY0luZGV4ICsgMSkgKiAweDEwMDAwKTsNCg0KICAgICAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoDQogICAgICAgICAgICAgICAgJmFsbG9jRGVzYywNCiAgICAgICAgICAgICAgICAmcmVzRGVzYywNCiAgICAgICAgICAgICAgICBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsDQogICAgICAgICAgICAgICAgbnVsbHB0ciwNCiAgICAgICAgICAgICAgICAmYnVmZmVyc1thbGxvY0luZGV4XSwNCiAgICAgICAgICAgICAgICBJSURfTlVMTCwgbnVsbHB0cikpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gSlNPTiBkdW1wDQogICAgICAgIHdjaGFyX3QqIGpzb24gPSBudWxscHRyOw0KICAgICAgICBjdHguYWxsb2NhdG9yLT5CdWlsZFN0YXRzU3RyaW5nKCZqc29uLCBUUlVFKTsNCiAgICAgICAgaW50IEkgPSAxOyAvLyBQdXQgYnJlYWtwb2ludCBoZXJlIHRvIG1hbnVhbGx5IGluc3BlY3QganNvbiBpbiBhIGRlYnVnZ2VyLg0KDQogICAgICAgIC8vIENoZWNrIGlmIHRoZWlyIG9mZnNldHMgcHJlc2VydmUgbWFyZ2luIGJldHdlZW4gdGhlbS4NCiAgICAgICAgc3RkOjpzb3J0KGJ1ZmZlcnMsIGJ1ZmZlcnMgKyBCVUZfQ09VTlQsIFtdKGNvbnN0IENvbVB0cjxBbGxvY2F0aW9uPiYgbGhzLCBjb25zdCBDb21QdHI8QWxsb2NhdGlvbj4mIHJocykgLT4gYm9vbA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGlmKGxocy0+R2V0SGVhcCgpICE9IHJocy0+R2V0SGVhcCgpKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxocy0+R2V0SGVhcCgpIDwgcmhzLT5HZXRIZWFwKCk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHJldHVybiBsaHMtPkdldE9mZnNldCgpIDwgcmhzLT5HZXRPZmZzZXQoKTsNCiAgICAgICAgICAgIH0pOw0KICAgICAgICBmb3Ioc2l6ZV90IGkgPSAxOyBpIDwgQlVGX0NPVU5UOyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmKGJ1ZmZlcnNbaV0tPkdldEhlYXAoKSA9PSBidWZmZXJzW2kgLSAxXS0+R2V0SGVhcCgpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGNvbnN0IFVJTlQ2NCBhbGxvY1N0YXJ0ID0gYnVmZmVyc1tpXS0+R2V0T2Zmc2V0KCk7DQogICAgICAgICAgICAgICAgY29uc3QgVUlOVDY0IHByZXZBbGxvY0VuZCA9IGJ1ZmZlcnNbaSAtIDFdLT5HZXRPZmZzZXQoKSArIGJ1ZmZlcnNbaSAtIDFdLT5HZXRTaXplKCk7DQogICAgICAgICAgICAgICAgQ0hFQ0tfQk9PTChhbGxvY1N0YXJ0ID49IHByZXZBbGxvY0VuZCArIEQzRDEyTUFfREVCVUdfTUFSR0lOKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGN0eC5hbGxvY2F0b3ItPkZyZWVTdGF0c1N0cmluZyhqc29uKTsNCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3REZWJ1Z01hcmdpbk5vdEluVmlydHVhbEFsbG9jYXRvcihjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IEQzRDEyTUFfREVCVUdfTUFSR0lOIG5vdCBhcHBsaWVkIHRvIHZpcnR1YWwgYWxsb2NhdG9yXG4iKTsNCiAgICB1c2luZyBuYW1lc3BhY2UgRDNEMTJNQTsNCiAgICBjb25zdGV4cHIgc2l6ZV90IEFMTE9DQVRJT05fQ09VTlQgPSAxMDsNCiAgICBmb3Ioc2l6ZV90IGFsZ29yaXRobUluZGV4ID0gMDsgYWxnb3JpdGhtSW5kZXggPCAyOyArK2FsZ29yaXRobUluZGV4KQ0KICAgIHsNCiAgICAgICAgVklSVFVBTF9CTE9DS19ERVNDIGJsb2NrRGVzYyA9IHt9Ow0KICAgICAgICBibG9ja0Rlc2MuU2l6ZSA9IEFMTE9DQVRJT05fQ09VTlQgKiBNRUdBQllURTsNCiAgICAgICAgc3dpdGNoKGFsZ29yaXRobUluZGV4KQ0KICAgICAgICB7DQogICAgICAgIGNhc2UgMDogYmxvY2tEZXNjLkZsYWdzID0gVklSVFVBTF9CTE9DS19GTEFHX05PTkU7IGJyZWFrOw0KICAgICAgICBjYXNlIDE6IGJsb2NrRGVzYy5GbGFncyA9IFZJUlRVQUxfQkxPQ0tfRkxBR19BTEdPUklUSE1fTElORUFSOyBicmVhazsNCiAgICAgICAgZGVmYXVsdDogYXNzZXJ0KDApOw0KICAgICAgICB9DQoNCiAgICAgICAgQ29tUHRyPFZpcnR1YWxCbG9jaz4gYmxvY2s7DQogICAgICAgIENIRUNLX0hSKENyZWF0ZVZpcnR1YWxCbG9jaygmYmxvY2tEZXNjLCAmYmxvY2spKTsNCg0KICAgICAgICAvLyBGaWxsIHRoZSBlbnRpcmUgYmxvY2sNCiAgICAgICAgVmlydHVhbEFsbG9jYXRpb24gYWxsb2NzW0FMTE9DQVRJT05fQ09VTlRdOw0KICAgICAgICBmb3Ioc2l6ZV90IGkgPSAwOyBpIDwgQUxMT0NBVElPTl9DT1VOVDsgKytpKQ0KICAgICAgICB7DQogICAgICAgICAgICBWSVJUVUFMX0FMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICAgICAgICAgIGFsbG9jRGVzYy5TaXplID0gMSAqIE1FR0FCWVRFOw0KICAgICAgICAgICAgQ0hFQ0tfSFIoYmxvY2stPkFsbG9jYXRlKCZhbGxvY0Rlc2MsICZhbGxvY3NbaV0sIG51bGxwdHIpKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGJsb2NrLT5DbGVhcigpOw0KICAgIH0NCn0NCg0Kc3RhdGljIHZvaWQgVGVzdEpzb24oY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICB3cHJpbnRmKEwiVGVzdCBKU09OXG4iKTsNCg0KICAgIHN0ZDo6dmVjdG9yPENvbVB0cjxEM0QxMk1BOjpQb29sPj4gcG9vbHM7DQogICAgc3RkOjp2ZWN0b3I8Q29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+PiBhbGxvY3M7DQoNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNEZXNjID0ge307DQogICAgcmVzRGVzYy5BbGlnbm1lbnQgPSAwOw0KICAgIHJlc0Rlc2MuTWlwTGV2ZWxzID0gMTsNCiAgICByZXNEZXNjLlNhbXBsZURlc2MuQ291bnQgPSAxOw0KICAgIHJlc0Rlc2MuU2FtcGxlRGVzYy5RdWFsaXR5ID0gMDsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0FMTE9DQVRJT05fSU5GTyBhbGxvY0luZm8gPSB7fTsNCiAgICBhbGxvY0luZm8uQWxpZ25tZW50ID0gRDNEMTJfREVGQVVMVF9SRVNPVVJDRV9QTEFDRU1FTlRfQUxJR05NRU5UOw0KICAgIGFsbG9jSW5mby5TaXplSW5CeXRlcyA9IEQzRDEyX0RFRkFVTFRfUkVTT1VSQ0VfUExBQ0VNRU5UX0FMSUdOTUVOVDsNCg0KICAgIC8vIFNlbGVjdCBpZiB1c2luZyBjdXN0b20gcG9vbCBvciBkZWZhdWx0DQogICAgZm9yIChVSU5UOCBwb29sVHlwZSA9IDA7IHBvb2xUeXBlIDwgMjsgKytwb29sVHlwZSkNCiAgICB7DQogICAgICAgIC8vIFNlbGVjdCBkaWZmZXJlbnQgaGVhcHMNCiAgICAgICAgZm9yIChVSU5UOCBoZWFwVHlwZSA9IDA7IGhlYXBUeXBlIDwgNTsgKytoZWFwVHlwZSkNCiAgICAgICAgew0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVTIHN0YXRlOw0KICAgICAgICAgICAgRDNEMTJfQ1BVX1BBR0VfUFJPUEVSVFkgY3B1UGFnZVR5cGUgPSBEM0QxMl9DUFVfUEFHRV9QUk9QRVJUWV9VTktOT1dOOw0KICAgICAgICAgICAgRDNEMTJfTUVNT1JZX1BPT0wgbWVtb3J5UG9vbCA9IEQzRDEyX01FTU9SWV9QT09MX1VOS05PV047DQogICAgICAgICAgICBzd2l0Y2ggKGhlYXBUeXBlKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgY2FzZSAwOg0KICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5IZWFwVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9ERUZBVUxUOw0KICAgICAgICAgICAgICAgIHN0YXRlID0gRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09NTU9OOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgY2FzZSAxOg0KICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5IZWFwVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9VUExPQUQ7DQogICAgICAgICAgICAgICAgc3RhdGUgPSBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQ7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBjYXNlIDI6DQogICAgICAgICAgICAgICAgYWxsb2NEZXNjLkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX1JFQURCQUNLOw0KICAgICAgICAgICAgICAgIHN0YXRlID0gRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9ERVNUOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgY2FzZSAzOg0KICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5IZWFwVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9DVVNUT007DQogICAgICAgICAgICAgICAgc3RhdGUgPSBEM0QxMl9SRVNPVVJDRV9TVEFURV9DT01NT047DQogICAgICAgICAgICAgICAgY3B1UGFnZVR5cGUgPSBEM0QxMl9DUFVfUEFHRV9QUk9QRVJUWV9OT1RfQVZBSUxBQkxFOw0KICAgICAgICAgICAgICAgIG1lbW9yeVBvb2wgPSBjdHguYWxsb2NhdG9yLT5Jc1VNQSgpID8gRDNEMTJfTUVNT1JZX1BPT0xfTDAgOiBEM0QxMl9NRU1PUllfUE9PTF9MMTsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIGNhc2UgNDoNCiAgICAgICAgICAgICAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfQ1VTVE9NOw0KICAgICAgICAgICAgICAgIHN0YXRlID0gRDNEMTJfUkVTT1VSQ0VfU1RBVEVfR0VORVJJQ19SRUFEOw0KICAgICAgICAgICAgICAgIGNwdVBhZ2VUeXBlID0gRDNEMTJfQ1BVX1BBR0VfUFJPUEVSVFlfV1JJVEVfQ09NQklORTsNCiAgICAgICAgICAgICAgICBtZW1vcnlQb29sID0gRDNEMTJfTUVNT1JZX1BPT0xfTDA7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICB9DQogICAgICAgICAgICAvLyBTa2lwIGN1c3RvbSBoZWFwcyBmb3IgZGVmYXVsdCBwb29scw0KICAgICAgICAgICAgaWYgKHBvb2xUeXBlID09IDAgJiYgaGVhcFR5cGUgPiAyKQ0KICAgICAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICAgICAgY29uc3QgYm9vbCB0ZXh0dXJlc1Bvc3NpYmxlID0gaGVhcFR5cGUgPT0gMCB8fCBoZWFwVHlwZSA9PSAzOw0KDQogICAgICAgICAgICAvLyBTZWxlY3QgZGlmZmVyZW50IHJlc291cmNlIHJlZ2lvbiB0eXBlcw0KICAgICAgICAgICAgZm9yIChVSU5UOCByZXNUeXBlID0gMDsgcmVzVHlwZSA8IDM7ICsrcmVzVHlwZSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBhbGxvY0Rlc2MuRXh0cmFIZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9CVUZGRVJTOw0KICAgICAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX0ZMQUdTIHJlc0ZsYWdzID0gRDNEMTJfUkVTT1VSQ0VfRkxBR19OT05FOw0KICAgICAgICAgICAgICAgIGlmICh0ZXh0dXJlc1Bvc3NpYmxlKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChyZXNUeXBlKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIGNhc2UgMToNCiAgICAgICAgICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5FeHRyYUhlYXBGbGFncyA9IEQzRDEyX0hFQVBfRkxBR19BTExPV19PTkxZX05PTl9SVF9EU19URVhUVVJFUzsNCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICBjYXNlIDI6DQogICAgICAgICAgICAgICAgICAgICAgICBhbGxvY0Rlc2MuRXh0cmFIZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9SVF9EU19URVhUVVJFUzsNCiAgICAgICAgICAgICAgICAgICAgICAgIHJlc0ZsYWdzID0gRDNEMTJfUkVTT1VSQ0VfRkxBR19BTExPV19SRU5ERVJfVEFSR0VUOw0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBzd2l0Y2ggKHBvb2xUeXBlKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBjYXNlIDA6DQogICAgICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gbnVsbHB0cjsNCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgY2FzZSAxOg0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgQ29tUHRyPEQzRDEyTUE6OlBvb2w+IHBvb2w7DQogICAgICAgICAgICAgICAgICAgIEQzRDEyTUE6OlBPT0xfREVTQyBwb29sRGVzYyA9IHt9Ow0KICAgICAgICAgICAgICAgICAgICBwb29sRGVzYy5IZWFwRmxhZ3MgPSBhbGxvY0Rlc2MuRXh0cmFIZWFwRmxhZ3M7DQogICAgICAgICAgICAgICAgICAgIHBvb2xEZXNjLkhlYXBQcm9wZXJ0aWVzLlR5cGUgPSBhbGxvY0Rlc2MuSGVhcFR5cGU7DQogICAgICAgICAgICAgICAgICAgIHBvb2xEZXNjLkhlYXBQcm9wZXJ0aWVzLkNQVVBhZ2VQcm9wZXJ0eSA9IGNwdVBhZ2VUeXBlOw0KICAgICAgICAgICAgICAgICAgICBwb29sRGVzYy5IZWFwUHJvcGVydGllcy5NZW1vcnlQb29sUHJlZmVyZW5jZSA9IG1lbW9yeVBvb2w7DQogICAgICAgICAgICAgICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVBvb2woJnBvb2xEZXNjLCAmcG9vbCkpOw0KDQogICAgICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gcG9vbC5HZXQoKTsNCiAgICAgICAgICAgICAgICAgICAgcG9vbHMuZW1wbGFjZV9iYWNrKHN0ZDo6bW92ZShwb29sKSk7DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAvLyBTZWxlY3QgZGlmZmVyZW50IGFsbG9jYXRpb24gZmxhZ3MNCiAgICAgICAgICAgICAgICBmb3IgKFVJTlQ4IGFsbG9jRmxhZyA9IDA7IGFsbG9jRmxhZyA8IDI7ICsrYWxsb2NGbGFnKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChhbGxvY0ZsYWcpDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgY2FzZSAwOg0KICAgICAgICAgICAgICAgICAgICAgICAgYWxsb2NEZXNjLkZsYWdzID0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX05PTkU7DQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgY2FzZSAxOg0KICAgICAgICAgICAgICAgICAgICAgICAgYWxsb2NEZXNjLkZsYWdzID0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX0NPTU1JVFRFRDsNCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAgICAgLy8gU2VsZWN0IGRpZmZlcmVudCBhbGxvYyB0eXBlcyAoYmxvY2ssIGJ1ZmZlciwgdGV4dHVyZSwgZXRjLikNCiAgICAgICAgICAgICAgICAgICAgZm9yIChVSU5UOCBhbGxvY1R5cGUgPSAwOyBhbGxvY1R5cGUgPCA1OyArK2FsbG9jVHlwZSkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2VsZWN0IGRpZmZlcmVudCBkYXRhIHN0b3JlZCBpbiB0aGUgYWxsb2NhdGlvbg0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChVSU5UOCBkYXRhID0gMDsgZGF0YSA8IDQ7ICsrZGF0YSkNCiAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYWxsb2M7DQoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGV4dHVyZXNQb3NzaWJsZSAmJiByZXNUeXBlICE9IDApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNEZXNjLkxheW91dCA9IEQzRDEyX1RFWFRVUkVfTEFZT1VUX1VOS05PV047DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc0Rlc2MuRm9ybWF0ID0gRFhHSV9GT1JNQVRfUjhHOEI4QThfVU5PUk07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoYWxsb2NUeXBlICUgMykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDA6DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNEZXNjLkRpbWVuc2lvbiA9IEQzRDEyX1JFU09VUkNFX0RJTUVOU0lPTl9URVhUVVJFMUQ7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNEZXNjLldpZHRoID0gNTEyOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzRGVzYy5IZWlnaHQgPSAxOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzRGVzYy5EZXB0aE9yQXJyYXlTaXplID0gMTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc0Rlc2MuRmxhZ3MgPSByZXNGbGFnczsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLCBzdGF0ZSwgbnVsbHB0ciwgJmFsbG9jLCBJSURfTlVMTCwgbnVsbHB0cikpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc0Rlc2MuRGltZW5zaW9uID0gRDNEMTJfUkVTT1VSQ0VfRElNRU5TSU9OX1RFWFRVUkUyRDsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc0Rlc2MuV2lkdGggPSAxMDI0Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzRGVzYy5IZWlnaHQgPSA1MTI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNEZXNjLkRlcHRoT3JBcnJheVNpemUgPSAxOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzRGVzYy5GbGFncyA9IHJlc0ZsYWdzOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJnJlc0Rlc2MsIHN0YXRlLCBudWxscHRyLCAmYWxsb2MsIElJRF9OVUxMLCBudWxscHRyKSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzRGVzYy5EaW1lbnNpb24gPSBEM0QxMl9SRVNPVVJDRV9ESU1FTlNJT05fVEVYVFVSRTNEOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzRGVzYy5XaWR0aCA9IDUxMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc0Rlc2MuSGVpZ2h0ID0gMjU2Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzRGVzYy5EZXB0aE9yQXJyYXlTaXplID0gMTI4Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzRGVzYy5GbGFncyA9IHJlc0ZsYWdzOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJnJlc0Rlc2MsIHN0YXRlLCBudWxscHRyLCAmYWxsb2MsIElJRF9OVUxMLCBudWxscHRyKSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGFsbG9jVHlwZSAlIDIpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+QWxsb2NhdGVNZW1vcnkoJmFsbG9jRGVzYywgJmFsbG9jSW5mbywgJmFsbG9jKSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsbFJlc291cmNlRGVzY0ZvckJ1ZmZlcihyZXNEZXNjLCAxMDI0KTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLCBzdGF0ZSwgbnVsbHB0ciwgJmFsbG9jLCBJSURfTlVMTCwgbnVsbHB0cikpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGRhdGEpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsb2MtPlNldFByaXZhdGVEYXRhKCh2b2lkKikxNjExMjAwNyk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsb2MtPlNldE5hbWUoTCJTSEVQVVJEIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMzoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsb2MtPlNldFByaXZhdGVEYXRhKCh2b2lkKikyNjAxMjAxMCk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbG9jLT5TZXROYW1lKEwiSk9LRVIiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbG9jcy5lbXBsYWNlX2JhY2soc3RkOjptb3ZlKGFsbG9jKSk7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCiAgICBTYXZlU3RhdHNTdHJpbmdUb0ZpbGUoY3R4LCBMIkpTT05fRDNEMTIuanNvbiIpOw0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0Q29tbWl0dGVkUmVzb3VyY2VzQW5kSnNvbihjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IGNvbW1pdHRlZCByZXNvdXJjZXMgYW5kIEpTT05cbiIpOw0KICAgIA0KICAgIGNvbnN0IFVJTlQgY291bnQgPSA0Ow0KICAgIGNvbnN0IFVJTlQ2NCBidWZTaXplID0gMzJ1bGwgKiAxMDI0Ow0KICAgIGNvbnN0IHdjaGFyX3QqIG5hbWVzW2NvdW50XSA9IHsNCiAgICAgICAgTCJSZXNvdXJjZVxuRm9vXHJcbkJhciIsDQogICAgICAgIEwiUmVzb3VyY2UgXCInJjw+PyNAISYtPV8rW117fTs6LC4vXFwiLA0KICAgICAgICBudWxscHRyLA0KICAgICAgICBMIiIsDQogICAgfTsNCg0KICAgIFJlc291cmNlV2l0aEFsbG9jYXRpb24gcmVzb3VyY2VzW2NvdW50XTsNCg0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICBhbGxvY0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfQ09NTUlUVEVEOw0KDQogICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNvdXJjZURlc2M7DQogICAgRmlsbFJlc291cmNlRGVzY0ZvckJ1ZmZlcihyZXNvdXJjZURlc2MsIGJ1ZlNpemUpOw0KDQogICAgZm9yKFVJTlQgaSA9IDA7IGkgPCBjb3VudDsgKytpKQ0KICAgIHsNCiAgICAgICAgY29uc3QgYm9vbCByZWNlaXZlRXhwbGljaXRSZXNvdXJjZSA9IGkgPCAyOw0KDQogICAgICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgNCiAgICAgICAgICAgICZhbGxvY0Rlc2MsDQogICAgICAgICAgICAmcmVzb3VyY2VEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9ERVNULA0KICAgICAgICAgICAgTlVMTCwNCiAgICAgICAgICAgICZyZXNvdXJjZXNbaV0uYWxsb2NhdGlvbiwNCiAgICAgICAgICAgIF9fdXVpZG9mKElEM0QxMlJlc291cmNlKSwNCiAgICAgICAgICAgIHJlY2VpdmVFeHBsaWNpdFJlc291cmNlID8gKHZvaWQqKikmcmVzb3VyY2VzW2ldLnJlc291cmNlIDogTlVMTCkpOw0KDQogICAgICAgIGlmKHJlY2VpdmVFeHBsaWNpdFJlc291cmNlKQ0KICAgICAgICB7DQogICAgICAgICAgICBJRDNEMTJSZXNvdXJjZSogcmVzID0gcmVzb3VyY2VzW2ldLnJlc291cmNlLkdldCgpOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChyZXMgJiYgcmVzID09IHJlc291cmNlc1tpXS5hbGxvY2F0aW9uLT5HZXRSZXNvdXJjZSgpKTsNCiAgICAgICAgICAgIGNvbnN0IFVMT05HIHJlZkNvdW50QWZ0ZXJBZGQgPSByZXMtPkFkZFJlZigpOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChyZWZDb3VudEFmdGVyQWRkID09IDMpOw0KICAgICAgICAgICAgcmVzLT5SZWxlYXNlKCk7DQogICAgICAgIH0NCiAgICAgICAgDQogICAgICAgIC8vIE1ha2Ugc3VyZSBpdCBoYXMgaW1wbGljaXQgaGVhcC4NCiAgICAgICAgQ0hFQ0tfQk9PTCggcmVzb3VyY2VzW2ldLmFsbG9jYXRpb24tPkdldEhlYXAoKSA9PSBOVUxMICYmIHJlc291cmNlc1tpXS5hbGxvY2F0aW9uLT5HZXRPZmZzZXQoKSA9PSAwICk7DQoNCiAgICAgICAgcmVzb3VyY2VzW2ldLmFsbG9jYXRpb24tPlNldE5hbWUobmFtZXNbaV0pOw0KICAgIH0NCg0KICAgIC8vIENoZWNrIG5hbWVzLg0KICAgIGZvcihVSU5UIGkgPSAwOyBpIDwgY291bnQ7ICsraSkNCiAgICB7DQogICAgICAgIGNvbnN0IHdjaGFyX3QqIGNvbnN0IGFsbG9jTmFtZSA9IHJlc291cmNlc1tpXS5hbGxvY2F0aW9uLT5HZXROYW1lKCk7DQogICAgICAgIGlmKGFsbG9jTmFtZSkNCiAgICAgICAgew0KICAgICAgICAgICAgQ0hFQ0tfQk9PTCggd2NzY21wKGFsbG9jTmFtZSwgbmFtZXNbaV0pID09IDAgKTsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlDQogICAgICAgIHsNCiAgICAgICAgICAgIENIRUNLX0JPT0wobmFtZXNbaV0gPT0gTlVMTCk7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICBXQ0hBUioganNvblN0cmluZzsNCiAgICBjdHguYWxsb2NhdG9yLT5CdWlsZFN0YXRzU3RyaW5nKCZqc29uU3RyaW5nLCBUUlVFKTsNCiAgICBDSEVDS19CT09MKHdjc3N0cihqc29uU3RyaW5nLCBMIlwiUmVzb3VyY2VcXG5Gb29cXHJcXG5CYXJcIiIpICE9IE5VTEwpOw0KICAgIENIRUNLX0JPT0wod2Nzc3RyKGpzb25TdHJpbmcsIEwiXCJSZXNvdXJjZSBcXFwiJyY8Pj8jQCEmLT1fK1tde307OiwuXFwvXFxcXFwiIikgIT0gTlVMTCk7DQogICAgQ0hFQ0tfQk9PTCh3Y3NzdHIoanNvblN0cmluZywgTCJcIlwiIikgIT0gTlVMTCk7DQogICAgY3R4LmFsbG9jYXRvci0+RnJlZVN0YXRzU3RyaW5nKGpzb25TdHJpbmcpOw0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0Q3VzdG9tSGVhcEZsYWdzKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgY3VzdG9tIGhlYXAgZmxhZ3NcbiIpOw0KDQogICAgLy8gMS4gSnVzdCBtZW1vcnkgaGVhcCB3aXRoIGN1c3RvbSBmbGFncw0KICAgIHsNCiAgICAgICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgICAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICAgICAgYWxsb2NEZXNjLkV4dHJhSGVhcEZsYWdzID0gRDNEMTJfSEVBUF9GTEFHX0FMTE9XX09OTFlfTk9OX1JUX0RTX1RFWFRVUkVTIHwNCiAgICAgICAgICAgIEQzRDEyX0hFQVBfRkxBR19TSEFSRUQ7IC8vIEV4dHJhIGZsYWcuDQoNCiAgICAgICAgRDNEMTJfUkVTT1VSQ0VfQUxMT0NBVElPTl9JTkZPIHJlc0FsbG9jSW5mbyA9IHt9Ow0KICAgICAgICByZXNBbGxvY0luZm8uU2l6ZUluQnl0ZXMgPSBEM0QxMl9ERUZBVUxUX1JFU09VUkNFX1BMQUNFTUVOVF9BTElHTk1FTlQ7DQogICAgICAgIHJlc0FsbG9jSW5mby5BbGlnbm1lbnQgPSBEM0QxMl9ERUZBVUxUX1JFU09VUkNFX1BMQUNFTUVOVF9BTElHTk1FTlQ7DQoNCiAgICAgICAgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiByZXM7DQogICAgICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5BbGxvY2F0ZU1lbW9yeSgmYWxsb2NEZXNjLCAmcmVzQWxsb2NJbmZvLCAmcmVzLmFsbG9jYXRpb24pICk7DQoNCiAgICAgICAgLy8gTXVzdCBiZSBjcmVhdGVkIGFzIHNlcGFyYXRlIGFsbG9jYXRpb24uDQogICAgICAgIENIRUNLX0JPT0woIHJlcy5hbGxvY2F0aW9uLT5HZXRPZmZzZXQoKSA9PSAwICk7DQogICAgfQ0KDQogICAgLy8gMi4gQ29tbWl0dGVkIHJlc291cmNlIHdpdGggY3VzdG9tIGZsYWdzDQogICAgew0KICAgICAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc291cmNlRGVzYyA9IHt9Ow0KICAgICAgICByZXNvdXJjZURlc2MuRGltZW5zaW9uID0gRDNEMTJfUkVTT1VSQ0VfRElNRU5TSU9OX1RFWFRVUkUyRDsNCiAgICAgICAgcmVzb3VyY2VEZXNjLkFsaWdubWVudCA9IDA7DQogICAgICAgIHJlc291cmNlRGVzYy5XaWR0aCA9IDE5MjA7DQogICAgICAgIHJlc291cmNlRGVzYy5IZWlnaHQgPSAxMDgwOw0KICAgICAgICByZXNvdXJjZURlc2MuRGVwdGhPckFycmF5U2l6ZSA9IDE7DQogICAgICAgIHJlc291cmNlRGVzYy5NaXBMZXZlbHMgPSAxOw0KICAgICAgICByZXNvdXJjZURlc2MuRm9ybWF0ID0gRFhHSV9GT1JNQVRfUjhHOEI4QThfVU5PUk07DQogICAgICAgIHJlc291cmNlRGVzYy5TYW1wbGVEZXNjLkNvdW50ID0gMTsNCiAgICAgICAgcmVzb3VyY2VEZXNjLlNhbXBsZURlc2MuUXVhbGl0eSA9IDA7DQogICAgICAgIHJlc291cmNlRGVzYy5MYXlvdXQgPSBEM0QxMl9URVhUVVJFX0xBWU9VVF9ST1dfTUFKT1I7DQogICAgICAgIHJlc291cmNlRGVzYy5GbGFncyA9IEQzRDEyX1JFU09VUkNFX0ZMQUdfQUxMT1dfQ1JPU1NfQURBUFRFUjsNCg0KICAgICAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgICAgIGFsbG9jRGVzYy5IZWFwVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9ERUZBVUxUOw0KICAgICAgICBhbGxvY0Rlc2MuRXh0cmFIZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfU0hBUkVEIHwgRDNEMTJfSEVBUF9GTEFHX1NIQVJFRF9DUk9TU19BREFQVEVSOyAvLyBFeHRyYSBmbGFncy4NCg0KICAgICAgICBSZXNvdXJjZVdpdGhBbGxvY2F0aW9uIHJlczsNCiAgICAgICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKA0KICAgICAgICAgICAgJmFsbG9jRGVzYywNCiAgICAgICAgICAgICZyZXNvdXJjZURlc2MsDQogICAgICAgICAgICBEM0QxMl9SRVNPVVJDRV9TVEFURV9DT01NT04sDQogICAgICAgICAgICBOVUxMLA0KICAgICAgICAgICAgJnJlcy5hbGxvY2F0aW9uLA0KICAgICAgICAgICAgSUlEX1BQVl9BUkdTKCZyZXMucmVzb3VyY2UpKSApOw0KDQogICAgICAgIC8vIE11c3QgYmUgY3JlYXRlZCBhcyBjb21taXR0ZWQuDQogICAgICAgIENIRUNLX0JPT0woIHJlcy5hbGxvY2F0aW9uLT5HZXRIZWFwKCkgPT0gTlVMTCApOw0KICAgIH0NCn0NCg0Kc3RhdGljIHZvaWQgVGVzdFBsYWNlZFJlc291cmNlcyhjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IHBsYWNlZCByZXNvdXJjZXNcbiIpOw0KDQogICAgY29uc3QgYm9vbCBhbHdheXNDb21taXR0ZWQgPSAoY3R4LmFsbG9jYXRvckZsYWdzICYgRDNEMTJNQTo6QUxMT0NBVE9SX0ZMQUdfQUxXQVlTX0NPTU1JVFRFRCkgIT0gMDsNCg0KICAgIGNvbnN0IFVJTlQgY291bnQgPSA0Ow0KICAgIGNvbnN0IFVJTlQ2NCBidWZTaXplID0gMzJ1bGwgKiAxMDI0Ow0KICAgIFJlc291cmNlV2l0aEFsbG9jYXRpb24gcmVzb3VyY2VzW2NvdW50XTsNCg0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzb3VyY2VEZXNjOw0KICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzb3VyY2VEZXNjLCBidWZTaXplKTsNCg0KICAgIGZvcihVSU5UIGkgPSAwOyBpIDwgY291bnQ7ICsraSkNCiAgICB7DQogICAgICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgNCiAgICAgICAgICAgICZhbGxvY0Rlc2MsDQogICAgICAgICAgICAmcmVzb3VyY2VEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfR0VORVJJQ19SRUFELA0KICAgICAgICAgICAgTlVMTCwNCiAgICAgICAgICAgICZyZXNvdXJjZXNbaV0uYWxsb2NhdGlvbiwNCiAgICAgICAgICAgIElJRF9QUFZfQVJHUygmcmVzb3VyY2VzW2ldLnJlc291cmNlKSkgKTsNCg0KICAgICAgICAvLyBNYWtlIHN1cmUgaXQgZG9lc24ndCBoYXZlIGltcGxpY2l0IGhlYXAuDQogICAgICAgIGlmKCFhbHdheXNDb21taXR0ZWQpDQogICAgICAgIHsNCiAgICAgICAgICAgIENIRUNLX0JPT0woIHJlc291cmNlc1tpXS5hbGxvY2F0aW9uLT5HZXRIZWFwKCkgIT0gTlVMTCApOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8gTWFrZSBzdXJlIGF0IGxlYXN0IHNvbWUgb2YgdGhlIHJlc291cmNlcyBiZWxvbmcgdG8gdGhlIHNhbWUgaGVhcCwgYnV0IHRoZWlyIG1lbW9yeSByYW5nZXMgZG9uJ3Qgb3ZlcmxhcC4NCiAgICBib29sIHNhbWVIZWFwRm91bmQgPSBmYWxzZTsNCiAgICBmb3Ioc2l6ZV90IGkgPSAwOyBpIDwgY291bnQ7ICsraSkNCiAgICB7DQogICAgICAgIGZvcihzaXplX3QgaiA9IGkgKyAxOyBqIDwgY291bnQ7ICsraikNCiAgICAgICAgew0KICAgICAgICAgICAgY29uc3QgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiYgcmVzSSA9IHJlc291cmNlc1tpXTsNCiAgICAgICAgICAgIGNvbnN0IFJlc291cmNlV2l0aEFsbG9jYXRpb24mIHJlc0ogPSByZXNvdXJjZXNbal07DQogICAgICAgICAgICBpZihyZXNJLmFsbG9jYXRpb24tPkdldEhlYXAoKSAhPSBOVUxMICYmDQogICAgICAgICAgICAgICAgcmVzSS5hbGxvY2F0aW9uLT5HZXRIZWFwKCkgPT0gcmVzSi5hbGxvY2F0aW9uLT5HZXRIZWFwKCkpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgc2FtZUhlYXBGb3VuZCA9IHRydWU7DQogICAgICAgICAgICAgICAgQ0hFQ0tfQk9PTChyZXNJLmFsbG9jYXRpb24tPkdldE9mZnNldCgpICsgcmVzSS5hbGxvY2F0aW9uLT5HZXRTaXplKCkgPD0gcmVzSi5hbGxvY2F0aW9uLT5HZXRPZmZzZXQoKSB8fA0KICAgICAgICAgICAgICAgICAgICByZXNKLmFsbG9jYXRpb24tPkdldE9mZnNldCgpICsgcmVzSi5hbGxvY2F0aW9uLT5HZXRTaXplKCkgPD0gcmVzSS5hbGxvY2F0aW9uLT5HZXRPZmZzZXQoKSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQogICAgaWYoIWFsd2F5c0NvbW1pdHRlZCkNCiAgICB7DQogICAgICAgIENIRUNLX0JPT0woc2FtZUhlYXBGb3VuZCk7DQogICAgfQ0KDQogICAgLy8gQWRkaXRpb25hbGx5IGNyZWF0ZSBhIHRleHR1cmUgdG8gc2VlIGlmIG5vIGVycm9yIG9jY3VycyBkdWUgdG8gYmFkIGhhbmRsaW5nIG9mIFJlc291cmNlIFRpZXIuDQogICAgcmVzb3VyY2VEZXNjID0ge307DQogICAgcmVzb3VyY2VEZXNjLkRpbWVuc2lvbiA9IEQzRDEyX1JFU09VUkNFX0RJTUVOU0lPTl9URVhUVVJFMkQ7DQogICAgcmVzb3VyY2VEZXNjLkFsaWdubWVudCA9IDA7DQogICAgcmVzb3VyY2VEZXNjLldpZHRoID0gMTAyNDsNCiAgICByZXNvdXJjZURlc2MuSGVpZ2h0ID0gMTAyNDsNCiAgICByZXNvdXJjZURlc2MuRGVwdGhPckFycmF5U2l6ZSA9IDE7DQogICAgcmVzb3VyY2VEZXNjLk1pcExldmVscyA9IDE7DQogICAgcmVzb3VyY2VEZXNjLkZvcm1hdCA9IERYR0lfRk9STUFUX1I4RzhCOEE4X1VOT1JNOw0KICAgIHJlc291cmNlRGVzYy5TYW1wbGVEZXNjLkNvdW50ID0gMTsNCiAgICByZXNvdXJjZURlc2MuU2FtcGxlRGVzYy5RdWFsaXR5ID0gMDsNCiAgICByZXNvdXJjZURlc2MuTGF5b3V0ID0gRDNEMTJfVEVYVFVSRV9MQVlPVVRfVU5LTk9XTjsNCiAgICByZXNvdXJjZURlc2MuRmxhZ3MgPSBEM0QxMl9SRVNPVVJDRV9GTEFHX05PTkU7DQogICAgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiB0ZXh0dXJlUmVzOw0KICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgNCiAgICAgICAgJmFsbG9jRGVzYywNCiAgICAgICAgJnJlc291cmNlRGVzYywNCiAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9ERVNULA0KICAgICAgICBOVUxMLA0KICAgICAgICAmdGV4dHVyZVJlcy5hbGxvY2F0aW9uLA0KICAgICAgICBJSURfUFBWX0FSR1MoJnRleHR1cmVSZXMucmVzb3VyY2UpKSApOw0KICAgIA0KICAgIC8vIEFkZGl0aW9uYWxseSBjcmVhdGUgYW4gTVNBQSByZW5kZXIgdGFyZ2V0IHRvIHNlZSBpZiBubyBlcnJvciBvY2N1cnMgZHVlIHRvIGJhZCBoYW5kbGluZyBvZiBSZXNvdXJjZSBUaWVyLg0KICAgIHJlc291cmNlRGVzYyA9IHt9Ow0KICAgIHJlc291cmNlRGVzYy5EaW1lbnNpb24gPSBEM0QxMl9SRVNPVVJDRV9ESU1FTlNJT05fVEVYVFVSRTJEOw0KICAgIHJlc291cmNlRGVzYy5BbGlnbm1lbnQgPSAwOw0KICAgIHJlc291cmNlRGVzYy5XaWR0aCA9IDE5MjA7DQogICAgcmVzb3VyY2VEZXNjLkhlaWdodCA9IDEwODA7DQogICAgcmVzb3VyY2VEZXNjLkRlcHRoT3JBcnJheVNpemUgPSAxOw0KICAgIHJlc291cmNlRGVzYy5NaXBMZXZlbHMgPSAxOw0KICAgIHJlc291cmNlRGVzYy5Gb3JtYXQgPSBEWEdJX0ZPUk1BVF9SOEc4QjhBOF9VTk9STTsNCiAgICByZXNvdXJjZURlc2MuU2FtcGxlRGVzYy5Db3VudCA9IDI7DQogICAgcmVzb3VyY2VEZXNjLlNhbXBsZURlc2MuUXVhbGl0eSA9IDA7DQogICAgcmVzb3VyY2VEZXNjLkxheW91dCA9IEQzRDEyX1RFWFRVUkVfTEFZT1VUX1VOS05PV047DQogICAgcmVzb3VyY2VEZXNjLkZsYWdzID0gRDNEMTJfUkVTT1VSQ0VfRkxBR19BTExPV19SRU5ERVJfVEFSR0VUOw0KICAgIFJlc291cmNlV2l0aEFsbG9jYXRpb24gcmVuZGVyVGFyZ2V0UmVzOw0KICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgNCiAgICAgICAgJmFsbG9jRGVzYywNCiAgICAgICAgJnJlc291cmNlRGVzYywNCiAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfUkVOREVSX1RBUkdFVCwNCiAgICAgICAgTlVMTCwNCiAgICAgICAgJnJlbmRlclRhcmdldFJlcy5hbGxvY2F0aW9uLA0KICAgICAgICBJSURfUFBWX0FSR1MoJnJlbmRlclRhcmdldFJlcy5yZXNvdXJjZSkpICk7DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RPdGhlckNvbUludGVyZmFjZShjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IG90aGVyIENPTSBpbnRlcmZhY2VcbiIpOw0KDQogICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNEZXNjOw0KICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzRGVzYywgMHgxMDAwMCk7DQoNCiAgICBmb3IodWludDMyX3QgaSA9IDA7IGkgPCAyOyArK2kpDQogICAgew0KICAgICAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgICAgIGFsbG9jRGVzYy5IZWFwVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9ERUZBVUxUOw0KICAgICAgICBpZihpID09IDEpDQogICAgICAgIHsNCiAgICAgICAgICAgIGFsbG9jRGVzYy5GbGFncyA9IEQzRDEyTUE6OkFMTE9DQVRJT05fRkxBR19DT01NSVRURUQ7DQogICAgICAgIH0NCg0KICAgICAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYWxsb2M7DQogICAgICAgIENvbVB0cjxJRDNEMTJQYWdlYWJsZT4gcGFnZWFibGU7DQogICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKA0KICAgICAgICAgICAgJmFsbG9jRGVzYywNCiAgICAgICAgICAgICZyZXNEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09NTU9OLA0KICAgICAgICAgICAgbnVsbHB0ciwgLy8gcE9wdGltaXplZENsZWFyVmFsdWUNCiAgICAgICAgICAgICZhbGxvYywNCiAgICAgICAgICAgIElJRF9QUFZfQVJHUygmcGFnZWFibGUpKSk7DQoNCiAgICAgICAgLy8gRG8gc29tZXRoaW5nIHdpdGggdGhlIGludGVyZmFjZSB0byBtYWtlIHN1cmUgaXQncyB2YWxpZC4NCiAgICAgICAgQ29tUHRyPElEM0QxMkRldmljZT4gZGV2aWNlOw0KICAgICAgICBDSEVDS19IUihwYWdlYWJsZS0+R2V0RGV2aWNlKElJRF9QUFZfQVJHUygmZGV2aWNlKSkpOw0KICAgICAgICBDSEVDS19CT09MKGRldmljZS5HZXQoKSA9PSBjdHguZGV2aWNlKTsNCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RDdXN0b21Qb29scyhjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IGN1c3RvbSBwb29sc1xuIik7DQoNCiAgICAvLyAjIEZldGNoIGdsb2JhbCBzdGF0cyAxDQoNCiAgICBEM0QxMk1BOjpUb3RhbFN0YXRpc3RpY3MgZ2xvYmFsU3RhdHNCZWcgPSB7fTsNCiAgICBjdHguYWxsb2NhdG9yLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZnbG9iYWxTdGF0c0JlZyk7DQoNCiAgICAvLyAjIENyZWF0ZSBwb29sLCAxLi4yIGJsb2NrcyBvZiAxMSBNQg0KICAgIA0KICAgIEQzRDEyTUE6OlBPT0xfREVTQyBwb29sRGVzYyA9IHt9Ow0KICAgIHBvb2xEZXNjLkhlYXBQcm9wZXJ0aWVzLlR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICBwb29sRGVzYy5IZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9CVUZGRVJTOw0KICAgIHBvb2xEZXNjLkJsb2NrU2l6ZSA9IDExICogTUVHQUJZVEU7DQogICAgcG9vbERlc2MuTWluQmxvY2tDb3VudCA9IDE7DQogICAgcG9vbERlc2MuTWF4QmxvY2tDb3VudCA9IDI7DQoNCiAgICBDb21QdHI8RDNEMTJNQTo6UG9vbD4gcG9vbDsNCiAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+Q3JlYXRlUG9vbCgmcG9vbERlc2MsICZwb29sKSApOw0KDQogICAgLy8gIyBWYWxpZGF0ZSBzdGF0cyBmb3IgZW1wdHkgcG9vbA0KDQogICAgRDNEMTJNQTo6RGV0YWlsZWRTdGF0aXN0aWNzIHBvb2xTdGF0cyA9IHt9Ow0KICAgIHBvb2wtPkNhbGN1bGF0ZVN0YXRpc3RpY3MoJnBvb2xTdGF0cyk7DQogICAgQ0hFQ0tfQk9PTCggcG9vbFN0YXRzLlN0YXRzLkJsb2NrQ291bnQgPT0gMSApOw0KICAgIENIRUNLX0JPT0woIHBvb2xTdGF0cy5TdGF0cy5BbGxvY2F0aW9uQ291bnQgPT0gMCApOw0KICAgIENIRUNLX0JPT0woIHBvb2xTdGF0cy5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPT0gMCApOw0KICAgIENIRUNLX0JPT0woIHBvb2xTdGF0cy5TdGF0cy5CbG9ja0J5dGVzIC0gcG9vbFN0YXRzLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PQ0KICAgICAgICBwb29sU3RhdHMuU3RhdHMuQmxvY2tDb3VudCAqIHBvb2xEZXNjLkJsb2NrU2l6ZSApOw0KDQogICAgLy8gIyBTZXROYW1lIGFuZCBHZXROYW1lDQoNCiAgICBzdGF0aWMgY29uc3Qgd2NoYXJfdCogTkFNRSA9IEwiQ3VzdG9tIHBvb2wgbmFtZSAxIjsNCiAgICBwb29sLT5TZXROYW1lKE5BTUUpOw0KICAgIENIRUNLX0JPT0woIHdjc2NtcChwb29sLT5HZXROYW1lKCksIE5BTUUpID09IDAgKTsNCg0KICAgIC8vICMgQ3JlYXRlIGJ1ZmZlcnMgMnggNSBNQg0KDQogICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gcG9vbC5HZXQoKTsNCiAgICBhbGxvY0Rlc2MuRXh0cmFIZWFwRmxhZ3MgPSAoRDNEMTJfSEVBUF9GTEFHUykweENEQ0RDRENEOyAvLyBTaG91bGQgYmUgaWdub3JlZC4NCiAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSAoRDNEMTJfSEVBUF9UWVBFKTB4Q0RDRENEQ0Q7IC8vIFNob3VsZCBiZSBpZ25vcmVkLg0KDQogICAgY29uc3QgVUlOVDY0IEJVRkZFUl9TSVpFID0gNSAqIE1FR0FCWVRFOw0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzRGVzYzsNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc0Rlc2MsIEJVRkZFUl9TSVpFKTsNCg0KICAgIENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiBhbGxvY3NbNF07DQogICAgZm9yKHVpbnQzMl90IGkgPSAwOyBpIDwgMjsgKytpKQ0KICAgIHsNCiAgICAgICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfR0VORVJJQ19SRUFELA0KICAgICAgICAgICAgTlVMTCwgLy8gcE9wdGltaXplZENsZWFyVmFsdWUNCiAgICAgICAgICAgICZhbGxvY3NbaV0sDQogICAgICAgICAgICBfX3V1aWRvZihJRDNEMTJSZXNvdXJjZSksIE5VTEwpICk7IC8vIHJpaWRSZXNvdXJjZSwgcHB2UmVzb3VyY2UNCiAgICB9DQoNCiAgICAvLyAjIFZhbGlkYXRlIHBvb2wgc3RhdHMgbm93DQoNCiAgICBwb29sLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZwb29sU3RhdHMpOw0KICAgIENIRUNLX0JPT0woIHBvb2xTdGF0cy5TdGF0cy5CbG9ja0NvdW50ID09IDEgKTsNCiAgICBDSEVDS19CT09MKCBwb29sU3RhdHMuU3RhdHMuQWxsb2NhdGlvbkNvdW50ID09IDIgKTsNCiAgICBDSEVDS19CT09MKCBwb29sU3RhdHMuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzID09IDIgKiBCVUZGRVJfU0laRSApOw0KICAgIENIRUNLX0JPT0woIHBvb2xTdGF0cy5TdGF0cy5CbG9ja0J5dGVzIC0gcG9vbFN0YXRzLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PQ0KICAgICAgICBwb29sRGVzYy5CbG9ja1NpemUgLSBwb29sU3RhdHMuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzICk7DQoNCiAgICAvLyAjIENoZWNrIHRoYXQgZ2xvYmFsIHN0YXRzIGFyZSB1cGRhdGVkIGFzIHdlbGwNCg0KICAgIEQzRDEyTUE6OlRvdGFsU3RhdGlzdGljcyBnbG9iYWxTdGF0c0N1cnIgPSB7fTsNCiAgICBjdHguYWxsb2NhdG9yLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZnbG9iYWxTdGF0c0N1cnIpOw0KDQogICAgQ0hFQ0tfQk9PTCggZ2xvYmFsU3RhdHNDdXJyLlRvdGFsLlN0YXRzLkFsbG9jYXRpb25Db3VudCA9PQ0KICAgICAgICBnbG9iYWxTdGF0c0JlZy5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQ291bnQgKyBwb29sU3RhdHMuU3RhdHMuQWxsb2NhdGlvbkNvdW50ICk7DQogICAgQ0hFQ0tfQk9PTCggZ2xvYmFsU3RhdHNDdXJyLlRvdGFsLlN0YXRzLkJsb2NrQ291bnQgPT0NCiAgICAgICAgZ2xvYmFsU3RhdHNCZWcuVG90YWwuU3RhdHMuQmxvY2tDb3VudCArIHBvb2xTdGF0cy5TdGF0cy5CbG9ja0NvdW50ICk7DQogICAgQ0hFQ0tfQk9PTCggZ2xvYmFsU3RhdHNDdXJyLlRvdGFsLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PQ0KICAgICAgICBnbG9iYWxTdGF0c0JlZy5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgKyBwb29sU3RhdHMuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzICk7DQoNCiAgICAvLyAjIE5FVkVSX0FMTE9DQVRFIGFuZCBDT01NSVRURUQgc2hvdWxkIGZhaWwNCiAgICAvLyAoQ29tbWl0dGVkIGFsbG9jYXRpb25zIG5vdCBhbGxvd2VkIGluIHRoaXMgcG9vbCBiZWNhdXNlIEJsb2NrU2l6ZSAhPSAwLikNCg0KICAgIGZvcih1aW50MzJfdCBpID0gMDsgaSA8IDI7ICsraSkNCiAgICB7DQogICAgICAgIGFsbG9jRGVzYy5GbGFncyA9IGkgPT0gMCA/DQogICAgICAgICAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfTkVWRVJfQUxMT0NBVEU6DQogICAgICAgICAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfQ09NTUlUVEVEOw0KICAgICAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYWxsb2M7DQogICAgICAgIGNvbnN0IEhSRVNVTFQgaHIgPSBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywNCiAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0dFTkVSSUNfUkVBRCwNCiAgICAgICAgICAgIE5VTEwsIC8vIHBPcHRpbWl6ZWRDbGVhclZhbHVlDQogICAgICAgICAgICAmYWxsb2MsDQogICAgICAgICAgICBfX3V1aWRvZihJRDNEMTJSZXNvdXJjZSksIE5VTEwpOyAvLyByaWlkUmVzb3VyY2UsIHBwdlJlc291cmNlDQogICAgICAgIENIRUNLX0JPT0woIEZBSUxFRChocikgKTsNCiAgICB9DQoNCiAgICAvLyAjIDMgbW9yZSBidWZmZXJzLiAzcmQgc2hvdWxkIGZhaWwuDQoNCiAgICBhbGxvY0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfTk9ORTsNCiAgICBmb3IodWludDMyX3QgaSA9IDI7IGkgPCA1OyArK2kpDQogICAgew0KICAgICAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYWxsb2M7DQogICAgICAgIEhSRVNVTFQgaHIgPSBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywNCiAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0dFTkVSSUNfUkVBRCwNCiAgICAgICAgICAgIE5VTEwsIC8vIHBPcHRpbWl6ZWRDbGVhclZhbHVlDQogICAgICAgICAgICAmYWxsb2MsDQogICAgICAgICAgICBfX3V1aWRvZihJRDNEMTJSZXNvdXJjZSksIE5VTEwpOyAvLyByaWlkUmVzb3VyY2UsIHBwdlJlc291cmNlDQogICAgICAgIGlmKGkgPCA0KQ0KICAgICAgICB7DQogICAgICAgICAgICBDSEVDS19IUiggaHIgKTsNCiAgICAgICAgICAgIGFsbG9jc1tpXSA9IHN0ZDo6bW92ZShhbGxvYyk7DQogICAgICAgIH0NCiAgICAgICAgZWxzZQ0KICAgICAgICB7DQogICAgICAgICAgICBDSEVDS19CT09MKCBGQUlMRUQoaHIpICk7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICBwb29sLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZwb29sU3RhdHMpOw0KICAgIENIRUNLX0JPT0woIHBvb2xTdGF0cy5TdGF0cy5CbG9ja0NvdW50ID09IDIgKTsNCiAgICBDSEVDS19CT09MKCBwb29sU3RhdHMuU3RhdHMuQWxsb2NhdGlvbkNvdW50ID09IDQgKTsNCiAgICBDSEVDS19CT09MKCBwb29sU3RhdHMuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzID09IDQgKiBCVUZGRVJfU0laRSApOw0KICAgIENIRUNLX0JPT0woIHBvb2xTdGF0cy5TdGF0cy5CbG9ja0J5dGVzIC0gcG9vbFN0YXRzLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PQ0KICAgICAgICBwb29sU3RhdHMuU3RhdHMuQmxvY2tDb3VudCAqIHBvb2xEZXNjLkJsb2NrU2l6ZSAtIHBvb2xTdGF0cy5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgKTsNCg0KICAgIC8vICMgTWFrZSByb29tLCBBbGxvY2F0ZU1lbW9yeSwgQ3JlYXRlQWxpYXNpbmdSZXNvdXJjZQ0KDQogICAgYWxsb2NzWzNdLlJlc2V0KCk7DQogICAgYWxsb2NzWzBdLlJlc2V0KCk7DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9BTExPQ0FUSU9OX0lORk8gcmVzQWxsb2NJbmZvID0ge307DQogICAgcmVzQWxsb2NJbmZvLlNpemVJbkJ5dGVzID0gNSAqIE1FR0FCWVRFOw0KICAgIHJlc0FsbG9jSW5mby5BbGlnbm1lbnQgPSBEM0QxMl9ERUZBVUxUX1JFU09VUkNFX1BMQUNFTUVOVF9BTElHTk1FTlQ7DQoNCiAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+QWxsb2NhdGVNZW1vcnkoJmFsbG9jRGVzYywgJnJlc0FsbG9jSW5mbywgJmFsbG9jc1swXSkgKTsNCg0KICAgIHJlc0Rlc2MuV2lkdGggPSAxICogTUVHQUJZVEU7DQogICAgQ29tUHRyPElEM0QxMlJlc291cmNlPiByZXM7DQogICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZUFsaWFzaW5nUmVzb3VyY2UoYWxsb2NzWzBdLkdldCgpLA0KICAgICAgICAwLCAvLyBBbGxvY2F0aW9uTG9jYWxPZmZzZXQNCiAgICAgICAgJnJlc0Rlc2MsDQogICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0dFTkVSSUNfUkVBRCwNCiAgICAgICAgTlVMTCwgLy8gcE9wdGltaXplZENsZWFyVmFsdWUNCiAgICAgICAgSUlEX1BQVl9BUkdTKCZyZXMpKSApOw0KDQogICAgLy8gSlNPTiBkdW1wDQogICAgd2NoYXJfdCoganNvbiA9IG51bGxwdHI7DQogICAgY3R4LmFsbG9jYXRvci0+QnVpbGRTdGF0c1N0cmluZygmanNvbiwgVFJVRSk7DQogICAgY3R4LmFsbG9jYXRvci0+RnJlZVN0YXRzU3RyaW5nKGpzb24pOw0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0UG9vbHNBbmRBbGxvY2F0aW9uUGFyYW1ldGVycyhjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IHBvb2xzIGFuZCBhbGxvY2F0aW9uIHBhcmFtZXRlcnNcbiIpOw0KDQogICAgQ29tUHRyPEQzRDEyTUE6OlBvb2w+IHBvb2wxLCBwb29sMjsNCiAgICBzdGQ6OnZlY3RvcjxDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4+IGJ1ZnM7DQoNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQoNCiAgICB1aW50MzJfdCB0b3RhbE5ld0FsbG9jQ291bnQgPSAwLCB0b3RhbE5ld0Jsb2NrQ291bnQgPSAwOw0KICAgIEQzRDEyTUE6OlRvdGFsU3RhdGlzdGljcyBzdGF0c0JlZywgc3RhdHNFbmQ7DQogICAgY3R4LmFsbG9jYXRvci0+Q2FsY3VsYXRlU3RhdGlzdGljcygmc3RhdHNCZWcpOw0KDQogICAgSFJFU1VMVCBocjsNCiAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYWxsb2M7DQoNCiAgICAvLyBwb29sVHlwZUk6DQogICAgLy8gMCA9IGRlZmF1bHQgcG9vbA0KICAgIC8vIDEgPSBjdXN0b20gcG9vbCwgZGVmYXVsdCAoZmxleGlibGUpIGJsb2NrIHNpemUgYW5kIGJsb2NrIGNvdW50DQogICAgLy8gMiA9IGN1c3RvbSBwb29sLCBmaXhlZCBibG9jayBzaXplIGFuZCBsaW1pdGVkIGJsb2NrIGNvdW50DQogICAgZm9yKHNpemVfdCBwb29sVHlwZUkgPSAwOyBwb29sVHlwZUkgPCAzOyArK3Bvb2xUeXBlSSkNCiAgICB7DQogICAgICAgIGlmKHBvb2xUeXBlSSA9PSAwKQ0KICAgICAgICB7DQogICAgICAgICAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICAgICAgICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gbnVsbHB0cjsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlIGlmKHBvb2xUeXBlSSA9PSAxKQ0KICAgICAgICB7DQogICAgICAgICAgICBEM0QxMk1BOjpQT09MX0RFU0MgcG9vbERlc2MgPSB7fTsNCiAgICAgICAgICAgIHBvb2xEZXNjLkhlYXBQcm9wZXJ0aWVzLlR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICAgICAgICAgIHBvb2xEZXNjLkhlYXBGbGFncyA9IEQzRDEyX0hFQVBfRkxBR19BTExPV19PTkxZX0JVRkZFUlM7DQogICAgICAgICAgICBociA9IGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVBvb2woJnBvb2xEZXNjLCAmcG9vbDEpOw0KICAgICAgICAgICAgQ0hFQ0tfSFIoaHIpOw0KICAgICAgICAgICAgYWxsb2NEZXNjLkN1c3RvbVBvb2wgPSBwb29sMS5HZXQoKTsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlIGlmKHBvb2xUeXBlSSA9PSAyKQ0KICAgICAgICB7DQogICAgICAgICAgICBEM0QxMk1BOjpQT09MX0RFU0MgcG9vbERlc2MgPSB7fTsNCiAgICAgICAgICAgIHBvb2xEZXNjLkhlYXBQcm9wZXJ0aWVzLlR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICAgICAgICAgIHBvb2xEZXNjLkhlYXBGbGFncyA9IEQzRDEyX0hFQVBfRkxBR19BTExPV19PTkxZX0JVRkZFUlM7DQogICAgICAgICAgICBwb29sRGVzYy5NYXhCbG9ja0NvdW50ID0gMTsNCiAgICAgICAgICAgIHBvb2xEZXNjLkJsb2NrU2l6ZSA9IDIgKiBNRUdBQllURSArIE1FR0FCWVRFIC8gMjsgLy8gMi41IE1CDQogICAgICAgICAgICBociA9IGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVBvb2woJnBvb2xEZXNjLCAmcG9vbDIpOw0KICAgICAgICAgICAgQ0hFQ0tfSFIoaHIpOw0KICAgICAgICAgICAgYWxsb2NEZXNjLkN1c3RvbVBvb2wgPSBwb29sMi5HZXQoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIHVpbnQzMl90IHBvb2xBbGxvY0NvdW50ID0gMCwgcG9vbEJsb2NrQ291bnQgPSAwOw0KICAgICAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc0Rlc2M7DQogICAgICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzRGVzYywgTUVHQUJZVEUpOw0KDQogICAgICAgIC8vIERlZmF1bHQgcGFyYW1ldGVycw0KICAgICAgICBhbGxvY0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfTk9ORTsNCiAgICAgICAgaHIgPSBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9ERVNULCBudWxscHRyLCAmYWxsb2MsIElJRF9OVUxMLCBudWxscHRyKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChTVUNDRUVERUQoaHIpICYmIGFsbG9jICYmIGFsbG9jLT5HZXRSZXNvdXJjZSgpKTsNCiAgICAgICAgSUQzRDEySGVhcCogY29uc3QgZGVmYXVsdEFsbG9jSGVhcCA9IGFsbG9jLT5HZXRIZWFwKCk7DQogICAgICAgIGNvbnN0IFVJTlQ2NCBkZWZhdWx0QWxsb2NPZmZzZXQgPSBhbGxvYy0+R2V0T2Zmc2V0KCk7DQogICAgICAgIGJ1ZnMucHVzaF9iYWNrKHN0ZDo6bW92ZShhbGxvYykpOw0KICAgICAgICArK3Bvb2xBbGxvY0NvdW50Ow0KDQogICAgICAgIC8vIENPTU1JVFRFRC4gU2hvdWxkIG5vdCB0cnkgcG9vbDIgYXMgaXQgbWF5IGFzc2VydCBvbiBpbnZhbGlkIGNhbGwuDQogICAgICAgIGlmKHBvb2xUeXBlSSAhPSAyKQ0KICAgICAgICB7DQogICAgICAgICAgICBhbGxvY0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfQ09NTUlUVEVEOw0KICAgICAgICAgICAgaHIgPSBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9ERVNULCBudWxscHRyLCAmYWxsb2MsIElJRF9OVUxMLCBudWxscHRyKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woU1VDQ0VFREVEKGhyKSAmJiBhbGxvYyAmJiBhbGxvYy0+R2V0UmVzb3VyY2UoKSk7DQogICAgICAgICAgICBDSEVDS19CT09MKGFsbG9jLT5HZXRPZmZzZXQoKSA9PSAwKTsgLy8gQ29tbWl0dGVkDQogICAgICAgICAgICBDSEVDS19CT09MKGFsbG9jLT5HZXRIZWFwKCkgPT0gbnVsbHB0cik7IC8vIENvbW1pdHRlZA0KICAgICAgICAgICAgYnVmcy5wdXNoX2JhY2soc3RkOjptb3ZlKGFsbG9jKSk7DQogICAgICAgICAgICArK3Bvb2xBbGxvY0NvdW50Ow0KICAgICAgICB9DQoNCiAgICAgICAgLy8gTkVWRVJfQUxMT0NBVEUgIzENCiAgICAgICAgYWxsb2NEZXNjLkZsYWdzID0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX05FVkVSX0FMTE9DQVRFOw0KICAgICAgICBociA9IGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9DT1BZX0RFU1QsIG51bGxwdHIsICZhbGxvYywgSUlEX05VTEwsIG51bGxwdHIpOw0KICAgICAgICBDSEVDS19CT09MKFNVQ0NFRURFRChocikgJiYgYWxsb2MgJiYgYWxsb2MtPkdldFJlc291cmNlKCkpOw0KICAgICAgICBDSEVDS19CT09MKGFsbG9jLT5HZXRIZWFwKCkgPT0gZGVmYXVsdEFsbG9jSGVhcCk7IC8vIFNhbWUgbWVtb3J5IGJsb2NrIGFzIGRlZmF1bHQgb25lLg0KICAgICAgICBDSEVDS19CT09MKGFsbG9jLT5HZXRPZmZzZXQoKSAhPSBkZWZhdWx0QWxsb2NPZmZzZXQpOw0KICAgICAgICBidWZzLnB1c2hfYmFjayhzdGQ6Om1vdmUoYWxsb2MpKTsNCiAgICAgICAgKytwb29sQWxsb2NDb3VudDsNCg0KICAgICAgICAvLyBORVZFUl9BTExPQ0FURSAjMi4gU2hvdWxkIGZhaWwgaW4gcG9vbDIgYXMgaXQgaGFzIG5vIHNwYWNlLg0KICAgICAgICBhbGxvY0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfTkVWRVJfQUxMT0NBVEU7DQogICAgICAgIGhyID0gY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJnJlc0Rlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPUFlfREVTVCwgbnVsbHB0ciwgJmFsbG9jLCBJSURfTlVMTCwgbnVsbHB0cik7DQogICAgICAgIGlmKHBvb2xUeXBlSSA9PSAyKQ0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChGQUlMRUQoaHIpKTsNCiAgICAgICAgZWxzZQ0KICAgICAgICB7DQogICAgICAgICAgICBDSEVDS19CT09MKFNVQ0NFRURFRChocikgJiYgYWxsb2MgJiYgYWxsb2MtPkdldFJlc291cmNlKCkpOw0KICAgICAgICAgICAgYnVmcy5wdXNoX2JhY2soc3RkOjptb3ZlKGFsbG9jKSk7DQogICAgICAgICAgICArK3Bvb2xBbGxvY0NvdW50Ow0KICAgICAgICB9DQoNCiAgICAgICAgLy8gUG9vbCBzdGF0cw0KICAgICAgICBzd2l0Y2gocG9vbFR5cGVJKQ0KICAgICAgICB7DQogICAgICAgIGNhc2UgMDogcG9vbEJsb2NrQ291bnQgPSAxOyBicmVhazsgLy8gQXQgbGVhc3QgMSBhZGRlZCBmb3IgZGVkaWNhdGVkIGFsbG9jYXRpb24uDQogICAgICAgIGNhc2UgMTogcG9vbEJsb2NrQ291bnQgPSAyOyBicmVhazsgLy8gMSBmb3IgY3VzdG9tIHBvb2wgYmxvY2sgYW5kIDEgZm9yIGRlZGljYXRlZCBhbGxvY2F0aW9uLg0KICAgICAgICBjYXNlIDI6IHBvb2xCbG9ja0NvdW50ID0gMTsgYnJlYWs7IC8vIE9ubHkgY3VzdG9tIHBvb2wsIG5vIGRlZGljYXRlZCBhbGxvY2F0aW9uLg0KICAgICAgICB9DQoNCiAgICAgICAgaWYocG9vbFR5cGVJID4gMCkNCiAgICAgICAgew0KICAgICAgICAgICAgRDNEMTJNQTo6RGV0YWlsZWRTdGF0aXN0aWNzIHBvb2xTdGF0cyA9IHt9Ow0KICAgICAgICAgICAgKHBvb2xUeXBlSSA9PSAyID8gcG9vbDIgOiBwb29sMSktPkNhbGN1bGF0ZVN0YXRpc3RpY3MoJnBvb2xTdGF0cyk7DQogICAgICAgICAgICBDSEVDS19CT09MKHBvb2xTdGF0cy5TdGF0cy5BbGxvY2F0aW9uQ291bnQgPT0gcG9vbEFsbG9jQ291bnQpOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChwb29sU3RhdHMuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzID09IHBvb2xBbGxvY0NvdW50ICogTUVHQUJZVEUpOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChwb29sU3RhdHMuU3RhdHMuQmxvY2tDb3VudCA9PSBwb29sQmxvY2tDb3VudCk7DQogICAgICAgIH0NCg0KICAgICAgICB0b3RhbE5ld0FsbG9jQ291bnQgKz0gcG9vbEFsbG9jQ291bnQ7DQogICAgICAgIHRvdGFsTmV3QmxvY2tDb3VudCArPSBwb29sQmxvY2tDb3VudDsNCiAgICB9DQoNCiAgICBjdHguYWxsb2NhdG9yLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZzdGF0c0VuZCk7DQoNCiAgICBDSEVDS19CT09MKHN0YXRzRW5kLlRvdGFsLlN0YXRzLkFsbG9jYXRpb25Db3VudCA9PQ0KICAgICAgICBzdGF0c0JlZy5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQ291bnQgKyB0b3RhbE5ld0FsbG9jQ291bnQpOw0KICAgIENIRUNLX0JPT0woc3RhdHNFbmQuVG90YWwuU3RhdHMuQmxvY2tDb3VudCA+PQ0KICAgICAgICBzdGF0c0JlZy5Ub3RhbC5TdGF0cy5CbG9ja0NvdW50ICsgdG90YWxOZXdCbG9ja0NvdW50KTsNCiAgICBDSEVDS19CT09MKHN0YXRzRW5kLlRvdGFsLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PQ0KICAgICAgICBzdGF0c0JlZy5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgKyB0b3RhbE5ld0FsbG9jQ291bnQgKiBNRUdBQllURSk7DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RDdXN0b21Qb29sX01pbkFsbG9jYXRpb25BbGlnbm1lbnQoY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICB3cHJpbnRmKEwiVGVzdCBjdXN0b20gcG9vbCBNaW5BbGxvY2F0aW9uQWxpZ25tZW50XG4iKTsNCg0KICAgIGNvbnN0IFVJTlQ2NCBCVUZGRVJfU0laRSA9IDMyOw0KICAgIGNvbnN0ZXhwciBzaXplX3QgQlVGRkVSX0NPVU5UID0gNDsNCiAgICBjb25zdCBVSU5UNjQgTUlOX0FMSUdOTUVOVCA9IDEyOCAqIDEwMjQ7DQoNCiAgICBEM0QxMk1BOjpQT09MX0RFU0MgcG9vbERlc2MgPSB7fTsNCiAgICBwb29sRGVzYy5IZWFwUHJvcGVydGllcy5UeXBlID0gRDNEMTJfSEVBUF9UWVBFX1VQTE9BRDsNCiAgICBwb29sRGVzYy5IZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9CVUZGRVJTOw0KICAgIHBvb2xEZXNjLk1pbkFsbG9jYXRpb25BbGlnbm1lbnQgPSBNSU5fQUxJR05NRU5UOw0KDQogICAgQ29tUHRyPEQzRDEyTUE6OlBvb2w+IHBvb2w7DQogICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVBvb2woJnBvb2xEZXNjLCAmcG9vbCkgKTsNCg0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuQ3VzdG9tUG9vbCA9IHBvb2wuR2V0KCk7DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc0Rlc2M7DQogICAgRmlsbFJlc291cmNlRGVzY0ZvckJ1ZmZlcihyZXNEZXNjLCBCVUZGRVJfU0laRSk7DQoNCiAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYWxsb2NzW0JVRkZFUl9DT1VOVF07DQogICAgZm9yKHNpemVfdCBpID0gMDsgaSA8IEJVRkZFUl9DT1VOVDsgKytpKQ0KICAgIHsNCiAgICAgICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfR0VORVJJQ19SRUFELA0KICAgICAgICAgICAgTlVMTCwgLy8gcE9wdGltaXplZENsZWFyVmFsdWUNCiAgICAgICAgICAgICZhbGxvY3NbaV0sDQogICAgICAgICAgICBJSURfTlVMTCwgTlVMTCkgKTsgLy8gcmlpZFJlc291cmNlLCBwcHZSZXNvdXJjZQ0KICAgICAgICBDSEVDS19CT09MKGFsbG9jc1tpXS0+R2V0T2Zmc2V0KCkgJSBNSU5fQUxJR05NRU5UID09IDApOw0KICAgIH0NCn0NCg0Kc3RhdGljIHZvaWQgVGVzdEN1c3RvbVBvb2xfQ29tbWl0dGVkKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgY3VzdG9tIHBvb2wgY29tbWl0dGVkXG4iKTsNCg0KICAgIGNvbnN0IFVJTlQ2NCBCVUZGRVJfU0laRSA9IDMyOw0KDQogICAgRDNEMTJNQTo6UE9PTF9ERVNDIHBvb2xEZXNjID0ge307DQogICAgcG9vbERlc2MuSGVhcFByb3BlcnRpZXMuVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9ERUZBVUxUOw0KICAgIHBvb2xEZXNjLkhlYXBGbGFncyA9IEQzRDEyX0hFQVBfRkxBR19BTExPV19PTkxZX0JVRkZFUlM7DQoNCiAgICBDb21QdHI8RDNEMTJNQTo6UG9vbD4gcG9vbDsNCiAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+Q3JlYXRlUG9vbCgmcG9vbERlc2MsICZwb29sKSApOw0KDQogICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gcG9vbC5HZXQoKTsNCiAgICBhbGxvY0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfQ09NTUlUVEVEOw0KDQogICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNEZXNjOw0KICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzRGVzYywgQlVGRkVSX1NJWkUpOw0KDQogICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jOw0KICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywNCiAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09NTU9OLA0KICAgICAgICBOVUxMLCAvLyBwT3B0aW1pemVkQ2xlYXJWYWx1ZQ0KICAgICAgICAmYWxsb2MsDQogICAgICAgIElJRF9OVUxMLCBOVUxMKSApOyAvLyByaWlkUmVzb3VyY2UsIHBwdlJlc291cmNlDQogICAgQ0hFQ0tfQk9PTChhbGxvYy0+R2V0SGVhcCgpID09IE5VTEwpOw0KICAgIENIRUNLX0JPT0woYWxsb2MtPkdldFJlc291cmNlKCkgIT0gTlVMTCk7DQogICAgQ0hFQ0tfQk9PTChhbGxvYy0+R2V0T2Zmc2V0KCkgPT0gMCk7DQp9DQoNCnN0YXRpYyBIUkVTVUxUIFRlc3RDdXN0b21IZWFwKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgsIGNvbnN0IEQzRDEyX0hFQVBfUFJPUEVSVElFUyYgaGVhcFByb3BzKQ0Kew0KICAgIEQzRDEyTUE6OlRvdGFsU3RhdGlzdGljcyBnbG9iYWxTdGF0c0JlZyA9IHt9Ow0KICAgIGN0eC5hbGxvY2F0b3ItPkNhbGN1bGF0ZVN0YXRpc3RpY3MoJmdsb2JhbFN0YXRzQmVnKTsNCg0KICAgIEQzRDEyTUE6OlBPT0xfREVTQyBwb29sRGVzYyA9IHt9Ow0KICAgIHBvb2xEZXNjLkhlYXBQcm9wZXJ0aWVzID0gaGVhcFByb3BzOw0KICAgIHBvb2xEZXNjLkhlYXBGbGFncyA9IEQzRDEyX0hFQVBfRkxBR19BTExPV19PTkxZX0JVRkZFUlM7DQogICAgcG9vbERlc2MuQmxvY2tTaXplID0gMTAgKiBNRUdBQllURTsNCiAgICBwb29sRGVzYy5NaW5CbG9ja0NvdW50ID0gMTsNCiAgICBwb29sRGVzYy5NYXhCbG9ja0NvdW50ID0gMTsNCg0KICAgIGNvbnN0IFVJTlQ2NCBCVUZGRVJfU0laRSA9IDEgKiBNRUdBQllURTsNCg0KICAgIENvbVB0cjxEM0QxMk1BOjpQb29sPiBwb29sOw0KICAgIEhSRVNVTFQgaHIgPSBjdHguYWxsb2NhdG9yLT5DcmVhdGVQb29sKCZwb29sRGVzYywgJnBvb2wpOw0KICAgIGlmKFNVQ0NFRURFRChocikpDQogICAgew0KICAgICAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gcG9vbC5HZXQoKTsNCg0KICAgICAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc0Rlc2M7DQogICAgICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzRGVzYywgQlVGRkVSX1NJWkUpOw0KDQogICAgICAgIC8vIFBvb2wgYWxyZWFkeSBhbGxvY2F0ZWQgYSBibG9jay4gV2UgZG9uJ3QgZXhwZWN0IENyZWF0ZVBsYWNlZFJlc291cmNlIHRvIGZhaWwuDQogICAgICAgIENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiBhbGxvYzsNCiAgICAgICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9ERVNULA0KICAgICAgICAgICAgTlVMTCwgLy8gcE9wdGltaXplZENsZWFyVmFsdWUNCiAgICAgICAgICAgICZhbGxvYywNCiAgICAgICAgICAgIF9fdXVpZG9mKElEM0QxMlJlc291cmNlKSwgTlVMTCkgKTsgLy8gcmlpZFJlc291cmNlLCBwcHZSZXNvdXJjZQ0KDQogICAgICAgIEQzRDEyTUE6OlRvdGFsU3RhdGlzdGljcyBnbG9iYWxTdGF0c0N1cnIgPSB7fTsNCiAgICAgICAgY3R4LmFsbG9jYXRvci0+Q2FsY3VsYXRlU3RhdGlzdGljcygmZ2xvYmFsU3RhdHNDdXJyKTsNCg0KICAgICAgICAvLyBNYWtlIHN1cmUgaXQgaXMgYWNjb3VudGVkIG9ubHkgaW4gQ1VTVE9NIGhlYXAgbm90IGFueSBvZiB0aGUgc3RhbmRhcmQgaGVhcHMuDQogICAgICAgIENIRUNLX0JPT0wobWVtY21wKCZnbG9iYWxTdGF0c0N1cnIuSGVhcFR5cGVbMF0sICZnbG9iYWxTdGF0c0JlZy5IZWFwVHlwZVswXSwgc2l6ZW9mKEQzRDEyTUE6OkRldGFpbGVkU3RhdGlzdGljcykpID09IDApOw0KICAgICAgICBDSEVDS19CT09MKG1lbWNtcCgmZ2xvYmFsU3RhdHNDdXJyLkhlYXBUeXBlWzFdLCAmZ2xvYmFsU3RhdHNCZWcuSGVhcFR5cGVbMV0sIHNpemVvZihEM0QxMk1BOjpEZXRhaWxlZFN0YXRpc3RpY3MpKSA9PSAwKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChtZW1jbXAoJmdsb2JhbFN0YXRzQ3Vyci5IZWFwVHlwZVsyXSwgJmdsb2JhbFN0YXRzQmVnLkhlYXBUeXBlWzJdLCBzaXplb2YoRDNEMTJNQTo6RGV0YWlsZWRTdGF0aXN0aWNzKSkgPT0gMCk7DQogICAgICAgIENIRUNLX0JPT0woIGdsb2JhbFN0YXRzQ3Vyci5IZWFwVHlwZVszXS5TdGF0cy5BbGxvY2F0aW9uQ291bnQgPT0gZ2xvYmFsU3RhdHNCZWcuSGVhcFR5cGVbM10uU3RhdHMuQWxsb2NhdGlvbkNvdW50ICsgMSApOw0KICAgICAgICBDSEVDS19CT09MKCBnbG9iYWxTdGF0c0N1cnIuSGVhcFR5cGVbM10uU3RhdHMuQmxvY2tDb3VudCA9PSBnbG9iYWxTdGF0c0JlZy5IZWFwVHlwZVszXS5TdGF0cy5CbG9ja0NvdW50ICsgMSApOw0KICAgICAgICBDSEVDS19CT09MKCBnbG9iYWxTdGF0c0N1cnIuSGVhcFR5cGVbM10uU3RhdHMuQWxsb2NhdGlvbkJ5dGVzID09IGdsb2JhbFN0YXRzQmVnLkhlYXBUeXBlWzNdLlN0YXRzLkFsbG9jYXRpb25CeXRlcyArIEJVRkZFUl9TSVpFICk7DQogICAgICAgIENIRUNLX0JPT0woIGdsb2JhbFN0YXRzQ3Vyci5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQ291bnQgPT0gZ2xvYmFsU3RhdHNCZWcuVG90YWwuU3RhdHMuQWxsb2NhdGlvbkNvdW50ICsgMSApOw0KICAgICAgICBDSEVDS19CT09MKCBnbG9iYWxTdGF0c0N1cnIuVG90YWwuU3RhdHMuQmxvY2tDb3VudCA9PSBnbG9iYWxTdGF0c0JlZy5Ub3RhbC5TdGF0cy5CbG9ja0NvdW50ICsgMSApOw0KICAgICAgICBDSEVDS19CT09MKCBnbG9iYWxTdGF0c0N1cnIuVG90YWwuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzID09IGdsb2JhbFN0YXRzQmVnLlRvdGFsLlN0YXRzLkFsbG9jYXRpb25CeXRlcyArIEJVRkZFUl9TSVpFICk7DQoNCiAgICAgICAgLy8gTWFwIGFuZCB3cml0ZSBzb21lIGRhdGEuDQogICAgICAgIGlmKGhlYXBQcm9wcy5DUFVQYWdlUHJvcGVydHkgPT0gRDNEMTJfQ1BVX1BBR0VfUFJPUEVSVFlfV1JJVEVfQ09NQklORSB8fA0KICAgICAgICAgICAgaGVhcFByb3BzLkNQVVBhZ2VQcm9wZXJ0eSA9PSBEM0QxMl9DUFVfUEFHRV9QUk9QRVJUWV9XUklURV9CQUNLKQ0KICAgICAgICB7DQogICAgICAgICAgICBJRDNEMTJSZXNvdXJjZSogY29uc3QgcmVzID0gYWxsb2MtPkdldFJlc291cmNlKCk7DQoNCiAgICAgICAgICAgIFVJTlQqIG1hcHBlZFB0ciA9IG51bGxwdHI7DQogICAgICAgICAgICBjb25zdCBEM0QxMl9SQU5HRSByZWFkUmFuZ2UgPSB7MCwgMH07DQogICAgICAgICAgICBDSEVDS19IUihyZXMtPk1hcCgwLCAmcmVhZFJhbmdlLCAodm9pZCoqKSZtYXBwZWRQdHIpKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgKm1hcHBlZFB0ciA9IDB4REVBREMwREU7DQogICAgICAgICAgICANCiAgICAgICAgICAgIHJlcy0+VW5tYXAoMCwgbnVsbHB0cik7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICByZXR1cm4gaHI7DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RDdXN0b21IZWFwcyhjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IGN1c3RvbSBoZWFwXG4iKTsNCg0KICAgIEQzRDEyX0hFQVBfUFJPUEVSVElFUyBoZWFwUHJvcHMgPSB7fTsNCg0KICAgIC8vIFVzZSBjdXN0b20gcG9vbCBidXQgdGhlIHNhbWUgYXMgUkVBREJBQ0ssIHdoaWNoIHNob3VsZCBiZSBhbHdheXMgYXZhaWxhYmxlLg0KICAgIGhlYXBQcm9wcy5UeXBlID0gRDNEMTJfSEVBUF9UWVBFX0NVU1RPTTsNCiAgICBoZWFwUHJvcHMuQ1BVUGFnZVByb3BlcnR5ID0gRDNEMTJfQ1BVX1BBR0VfUFJPUEVSVFlfV1JJVEVfQkFDSzsNCiAgICBoZWFwUHJvcHMuTWVtb3J5UG9vbFByZWZlcmVuY2UgPSBEM0QxMl9NRU1PUllfUE9PTF9MMDsgLy8gU3lzdGVtIG1lbW9yeQ0KICAgIEhSRVNVTFQgaHIgPSBUZXN0Q3VzdG9tSGVhcChjdHgsIGhlYXBQcm9wcyk7DQogICAgQ0hFQ0tfSFIoaHIpOw0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0U3RhbmRhcmRDdXN0b21Db21taXR0ZWRQbGFjZWQoY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICB3cHJpbnRmKEwiVGVzdCBzdGFuZGFyZCwgY3VzdG9tLCBjb21taXR0ZWQsIHBsYWNlZFxuIik7DQoNCiAgICBzdGF0aWMgY29uc3QgRDNEMTJfSEVBUF9UWVBFIGhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQogICAgc3RhdGljIGNvbnN0IFVJTlQ2NCBidWZmZXJTaXplID0gMTAyNDsNCg0KICAgIEQzRDEyTUE6OlBPT0xfREVTQyBwb29sRGVzYyA9IHt9Ow0KICAgIHBvb2xEZXNjLkhlYXBQcm9wZXJ0aWVzLlR5cGUgPSBoZWFwVHlwZTsNCiAgICBwb29sRGVzYy5IZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9CVUZGRVJTOw0KDQogICAgQ29tUHRyPEQzRDEyTUE6OlBvb2w+IHBvb2w7DQogICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUG9vbCgmcG9vbERlc2MsICZwb29sKSk7DQoNCiAgICBzdGQ6OnZlY3RvcjxDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4+IGFsbG9jYXRpb25zOw0KICAgIA0KICAgIEQzRDEyTUE6OlRvdGFsU3RhdGlzdGljcyBzdGF0c0JlZyA9IHt9Ow0KICAgIEQzRDEyTUE6OkRldGFpbGVkU3RhdGlzdGljcyBwb29sU3RhdEluZm9CZWcgPSB7fTsNCiAgICBjdHguYWxsb2NhdG9yLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZzdGF0c0JlZyk7DQogICAgcG9vbC0+Q2FsY3VsYXRlU3RhdGlzdGljcygmcG9vbFN0YXRJbmZvQmVnKTsNCg0KICAgIHNpemVfdCBwb29sQWxsb2NDb3VudCA9IDA7DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc0Rlc2MgPSB7fTsNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc0Rlc2MsIGJ1ZmZlclNpemUpOw0KDQogICAgZm9yKHVpbnQzMl90IHN0YW5kYXJkQ3VzdG9tSSA9IDA7IHN0YW5kYXJkQ3VzdG9tSSA8IDI7ICsrc3RhbmRhcmRDdXN0b21JKQ0KICAgIHsNCiAgICAgICAgY29uc3QgYm9vbCB1c2VDdXN0b21Qb29sID0gc3RhbmRhcmRDdXN0b21JID4gMDsNCiAgICAgICAgZm9yKHVpbnQzMl90IGZsYWdzSSA9IDA7IGZsYWdzSSA8IDM7ICsrZmxhZ3NJKQ0KICAgICAgICB7DQogICAgICAgICAgICBjb25zdCBib29sIHVzZUNvbW1pdHRlZCA9IGZsYWdzSSA+IDA7DQogICAgICAgICAgICBjb25zdCBib29sIG5ldmVyQWxsb2NhdGUgPSBmbGFnc0kgPiAxOw0KDQogICAgICAgICAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgICAgICAgICBpZih1c2VDdXN0b21Qb29sKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gcG9vbC5HZXQoKTsNCiAgICAgICAgICAgICAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSAoRDNEMTJfSEVBUF9UWVBFKTB4Q0RDRENEQ0Q7IC8vIFNob3VsZCBiZSBpZ25vcmVkLg0KICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5FeHRyYUhlYXBGbGFncyA9IChEM0QxMl9IRUFQX0ZMQUdTKTB4Q0RDRENEQ0Q7IC8vIFNob3VsZCBiZSBpZ25vcmVkLg0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5IZWFwVHlwZSA9IGhlYXBUeXBlOw0KICAgICAgICAgICAgaWYodXNlQ29tbWl0dGVkKQ0KICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5GbGFncyB8PSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfQ09NTUlUVEVEOw0KICAgICAgICAgICAgaWYobmV2ZXJBbGxvY2F0ZSkNCiAgICAgICAgICAgICAgICBhbGxvY0Rlc2MuRmxhZ3MgfD0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX05FVkVSX0FMTE9DQVRFOw0KDQogICAgICAgICAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYWxsb2NQdHIgPSBOVUxMOw0KICAgICAgICAgICAgSFJFU1VMVCBociA9IGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLA0KICAgICAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPTU1PTiwNCiAgICAgICAgICAgICAgICBOVUxMLCAvLyBwT3B0aW1pemVkQ2xlYXJWYWx1ZQ0KICAgICAgICAgICAgICAgICZhbGxvY1B0ciwgSUlEX05VTEwsIE5VTEwpOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChTVUNDRUVERUQoaHIpID09IChhbGxvY1B0ciAhPSBOVUxMKSk7DQogICAgICAgICAgICBpZihhbGxvY1B0cikNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBhbGxvY2F0aW9ucy5wdXNoX2JhY2soYWxsb2NQdHIpOw0KICAgICAgICAgICAgICAgIGlmKHVzZUN1c3RvbVBvb2wpDQogICAgICAgICAgICAgICAgICAgICsrcG9vbEFsbG9jQ291bnQ7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIGJvb2wgZXhwZWN0U3VjY2VzcyA9ICFuZXZlckFsbG9jYXRlOyAvLyBORVZFUl9BTExPQ0FURSBzaG91bGQgYWx3YXlzIGZhaWwgd2l0aCBDT01NSVRURUQuDQogICAgICAgICAgICBDSEVDS19CT09MKGV4cGVjdFN1Y2Nlc3MgPT0gU1VDQ0VFREVEKGhyKSk7DQogICAgICAgICAgICBpZihTVUNDRUVERUQoaHIpICYmIHVzZUNvbW1pdHRlZCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBDSEVDS19CT09MKGFsbG9jUHRyLT5HZXRIZWFwKCkgPT0gTlVMTCk7IC8vIENvbW1pdHRlZCBhbGxvY2F0aW9uIGhhcyBpbXBsaWNpdCBoZWFwLg0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfQ0KDQogICAgRDNEMTJNQTo6VG90YWxTdGF0aXN0aWNzIHN0YXRzRW5kID0ge307DQogICAgRDNEMTJNQTo6RGV0YWlsZWRTdGF0aXN0aWNzIHBvb2xTdGF0SW5mb0VuZCA9IHt9Ow0KICAgIGN0eC5hbGxvY2F0b3ItPkNhbGN1bGF0ZVN0YXRpc3RpY3MoJnN0YXRzRW5kKTsNCiAgICBwb29sLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZwb29sU3RhdEluZm9FbmQpOw0KDQogICAgQ0hFQ0tfQk9PTChzdGF0c0VuZC5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQ291bnQgPT0gc3RhdHNCZWcuVG90YWwuU3RhdHMuQWxsb2NhdGlvbkNvdW50ICsgYWxsb2NhdGlvbnMuc2l6ZSgpKTsNCiAgICBDSEVDS19CT09MKHN0YXRzRW5kLlRvdGFsLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA+PSBzdGF0c0JlZy5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgKyBhbGxvY2F0aW9ucy5zaXplKCkgKiBidWZmZXJTaXplKTsNCiAgICBDSEVDS19CT09MKHN0YXRzRW5kLkhlYXBUeXBlWzBdLlN0YXRzLkFsbG9jYXRpb25Db3VudCA9PSBzdGF0c0JlZy5IZWFwVHlwZVswXS5TdGF0cy5BbGxvY2F0aW9uQ291bnQgKyBhbGxvY2F0aW9ucy5zaXplKCkpOw0KICAgIENIRUNLX0JPT0woc3RhdHNFbmQuSGVhcFR5cGVbMF0uU3RhdHMuQWxsb2NhdGlvbkJ5dGVzID49IHN0YXRzQmVnLkhlYXBUeXBlWzBdLlN0YXRzLkFsbG9jYXRpb25CeXRlcyArIGFsbG9jYXRpb25zLnNpemUoKSAqIGJ1ZmZlclNpemUpOw0KICAgIENIRUNLX0JPT0wocG9vbFN0YXRJbmZvRW5kLlN0YXRzLkFsbG9jYXRpb25Db3VudCA9PSBwb29sU3RhdEluZm9CZWcuU3RhdHMuQWxsb2NhdGlvbkNvdW50ICsgcG9vbEFsbG9jQ291bnQpOw0KICAgIENIRUNLX0JPT0wocG9vbFN0YXRJbmZvRW5kLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA+PSBwb29sU3RhdEluZm9CZWcuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzICsgcG9vbEFsbG9jQ291bnQgKiBidWZmZXJTaXplKTsNCn0NCg0Kc3RhdGljIHZvaWQgVGVzdEFsaWFzaW5nTWVtb3J5KGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgYWxpYXNpbmcgbWVtb3J5XG4iKTsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzRGVzYzEgPSB7fTsNCiAgICByZXNEZXNjMS5EaW1lbnNpb24gPSBEM0QxMl9SRVNPVVJDRV9ESU1FTlNJT05fVEVYVFVSRTJEOw0KICAgIHJlc0Rlc2MxLkFsaWdubWVudCA9IDA7DQogICAgcmVzRGVzYzEuV2lkdGggPSAxOTIwOw0KICAgIHJlc0Rlc2MxLkhlaWdodCA9IDEwODA7DQogICAgcmVzRGVzYzEuRGVwdGhPckFycmF5U2l6ZSA9IDE7DQogICAgcmVzRGVzYzEuTWlwTGV2ZWxzID0gMTsNCiAgICByZXNEZXNjMS5Gb3JtYXQgPSBEWEdJX0ZPUk1BVF9SOEc4QjhBOF9VTk9STTsNCiAgICByZXNEZXNjMS5TYW1wbGVEZXNjLkNvdW50ID0gMTsNCiAgICByZXNEZXNjMS5TYW1wbGVEZXNjLlF1YWxpdHkgPSAwOw0KICAgIHJlc0Rlc2MxLkxheW91dCA9IEQzRDEyX1RFWFRVUkVfTEFZT1VUX1VOS05PV047DQogICAgcmVzRGVzYzEuRmxhZ3MgPSBEM0QxMl9SRVNPVVJDRV9GTEFHX0FMTE9XX1JFTkRFUl9UQVJHRVQgfCBEM0QxMl9SRVNPVVJDRV9GTEFHX0FMTE9XX1VOT1JERVJFRF9BQ0NFU1M7DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc0Rlc2MyID0ge307DQogICAgcmVzRGVzYzIuRGltZW5zaW9uID0gRDNEMTJfUkVTT1VSQ0VfRElNRU5TSU9OX1RFWFRVUkUyRDsNCiAgICByZXNEZXNjMi5BbGlnbm1lbnQgPSAwOw0KICAgIHJlc0Rlc2MyLldpZHRoID0gMTAyNDsNCiAgICByZXNEZXNjMi5IZWlnaHQgPSAxMDI0Ow0KICAgIHJlc0Rlc2MyLkRlcHRoT3JBcnJheVNpemUgPSAxOw0KICAgIHJlc0Rlc2MyLk1pcExldmVscyA9IDA7DQogICAgcmVzRGVzYzIuRm9ybWF0ID0gRFhHSV9GT1JNQVRfUjhHOEI4QThfVU5PUk07DQogICAgcmVzRGVzYzIuU2FtcGxlRGVzYy5Db3VudCA9IDE7DQogICAgcmVzRGVzYzIuU2FtcGxlRGVzYy5RdWFsaXR5ID0gMDsNCiAgICByZXNEZXNjMi5MYXlvdXQgPSBEM0QxMl9URVhUVVJFX0xBWU9VVF9VTktOT1dOOw0KICAgIHJlc0Rlc2MyLkZsYWdzID0gRDNEMTJfUkVTT1VSQ0VfRkxBR19BTExPV19SRU5ERVJfVEFSR0VUOw0KDQogICAgY29uc3QgRDNEMTJfUkVTT1VSQ0VfQUxMT0NBVElPTl9JTkZPIGFsbG9jSW5mbzEgPQ0KICAgICAgICBjdHguZGV2aWNlLT5HZXRSZXNvdXJjZUFsbG9jYXRpb25JbmZvKDAsIDEsICZyZXNEZXNjMSk7DQogICAgY29uc3QgRDNEMTJfUkVTT1VSQ0VfQUxMT0NBVElPTl9JTkZPIGFsbG9jSW5mbzIgPQ0KICAgICAgICBjdHguZGV2aWNlLT5HZXRSZXNvdXJjZUFsbG9jYXRpb25JbmZvKDAsIDEsICZyZXNEZXNjMik7DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9BTExPQ0FUSU9OX0lORk8gZmluYWxBbGxvY0luZm8gPSB7fTsNCiAgICBmaW5hbEFsbG9jSW5mby5BbGlnbm1lbnQgPSBzdGQ6Om1heChhbGxvY0luZm8xLkFsaWdubWVudCwgYWxsb2NJbmZvMi5BbGlnbm1lbnQpOw0KICAgIGZpbmFsQWxsb2NJbmZvLlNpemVJbkJ5dGVzID0gc3RkOjptYXgoYWxsb2NJbmZvMS5TaXplSW5CeXRlcywgYWxsb2NJbmZvMi5TaXplSW5CeXRlcyk7DQoNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgYWxsb2NEZXNjLkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQogICAgYWxsb2NEZXNjLkV4dHJhSGVhcEZsYWdzID0gRDNEMTJfSEVBUF9GTEFHX0FMTE9XX09OTFlfUlRfRFNfVEVYVFVSRVM7DQoNCiAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYWxsb2M7DQogICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkFsbG9jYXRlTWVtb3J5KCZhbGxvY0Rlc2MsICZmaW5hbEFsbG9jSW5mbywgJmFsbG9jKSApOw0KICAgIENIRUNLX0JPT0woYWxsb2MgIT0gTlVMTCAmJiBhbGxvYy0+R2V0SGVhcCgpICE9IE5VTEwpOw0KDQogICAgQ29tUHRyPElEM0QxMlJlc291cmNlPiByZXMxOw0KICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVBbGlhc2luZ1Jlc291cmNlKA0KICAgICAgICBhbGxvYy5HZXQoKSwNCiAgICAgICAgMCwgLy8gQWxsb2NhdGlvbkxvY2FsT2Zmc2V0DQogICAgICAgICZyZXNEZXNjMSwNCiAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09NTU9OLA0KICAgICAgICBOVUxMLCAvLyBwT3B0aW1pemVkQ2xlYXJWYWx1ZQ0KICAgICAgICBJSURfUFBWX0FSR1MoJnJlczEpKSApOw0KICAgIENIRUNLX0JPT0wocmVzMSAhPSBOVUxMKTsNCg0KICAgIENvbVB0cjxJRDNEMTJSZXNvdXJjZT4gcmVzMjsNCiAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+Q3JlYXRlQWxpYXNpbmdSZXNvdXJjZSgNCiAgICAgICAgYWxsb2MuR2V0KCksDQogICAgICAgIDAsIC8vIEFsbG9jYXRpb25Mb2NhbE9mZnNldA0KICAgICAgICAmcmVzRGVzYzIsDQogICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPTU1PTiwNCiAgICAgICAgTlVMTCwgLy8gcE9wdGltaXplZENsZWFyVmFsdWUNCiAgICAgICAgSUlEX1BQVl9BUkdTKCZyZXMyKSkgKTsNCiAgICBDSEVDS19CT09MKHJlczIgIT0gTlVMTCk7DQoNCiAgICAvLyBZb3UgY2FuIHVzZSByZXMxIGFuZCByZXMyLCBidXQgbm90IGF0IHRoZSBzYW1lIHRpbWUhDQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RBbGlhc2luZ0ltcGxpY2l0Q29tbWl0dGVkKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgYWxpYXNpbmcgaW1wbGljaXQgZGVkaWNhdGVkXG4iKTsNCg0KICAgIC8vIFRoZSBidWZmZXIgd2lsbCBiZSBsYXJnZSBlbm91Z2ggdG8gYmUgYWxsb2NhdGVkIGFzIGNvbW1pdHRlZC4NCiAgICAvLyBXZSBzdGlsbCBuZWVkIGl0IHRvIGhhdmUgYW4gZXhwbGljaXQgaGVhcCB0byBiZSBhYmxlIHRvIGFsaWFzLg0KDQogICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNEZXNjID0ge307DQogICAgRmlsbFJlc291cmNlRGVzY0ZvckJ1ZmZlcihyZXNEZXNjLCAzMDAgKiBNRUdBQllURSk7DQoNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgYWxsb2NEZXNjLkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX1VQTE9BRDsNCiAgICBhbGxvY0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfQ0FOX0FMSUFTOw0KDQogICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jOw0KICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLA0KICAgICAgICBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsIE5VTEwsDQogICAgICAgICZhbGxvYywgSUlEX05VTEwsIE5VTEwpKTsNCiAgICBDSEVDS19CT09MKGFsbG9jICE9IE5VTEwgJiYgYWxsb2MtPkdldEhlYXAoKSAhPSBOVUxMKTsNCg0KICAgIHJlc0Rlc2MuV2lkdGggPSAyMDAgKiBNRUdBQllURTsNCiAgICBDb21QdHI8SUQzRDEyUmVzb3VyY2U+IGFsaWFzaW5nUmVzOw0KICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZUFsaWFzaW5nUmVzb3VyY2UoYWxsb2MuR2V0KCksDQogICAgICAgIDAsIC8vIEFsbG9jYXRpb25Mb2NhbE9mZnNldA0KICAgICAgICAmcmVzRGVzYywNCiAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfR0VORVJJQ19SRUFELCBOVUxMLCBJSURfUFBWX0FSR1MoJmFsaWFzaW5nUmVzKSkpOw0KICAgIENIRUNLX0JPT0woYWxpYXNpbmdSZXMgIT0gTlVMTCk7DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RQb29sTXNhYVRleHR1cmVBc0NvbW1pdHRlZChjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IE1TQUEgdGV4dHVyZSBhbHdheXMgYXMgY29tbWl0dGVkIGluIHBvb2xcbiIpOw0KDQogICAgRDNEMTJNQTo6UE9PTF9ERVNDIHBvb2xEZXNjID0ge307DQogICAgcG9vbERlc2MuSGVhcEZsYWdzID0gRDNEMTJfSEVBUF9GTEFHX0FMTE9XX09OTFlfUlRfRFNfVEVYVFVSRVM7DQogICAgcG9vbERlc2MuSGVhcFByb3BlcnRpZXMuVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9ERUZBVUxUOw0KICAgIHBvb2xEZXNjLkZsYWdzID0gRDNEMTJNQTo6UE9PTF9GTEFHX01TQUFfVEVYVFVSRVNfQUxXQVlTX0NPTU1JVFRFRDsNCg0KICAgIENvbVB0cjxEM0QxMk1BOjpQb29sPiBwb29sOw0KICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVBvb2woJnBvb2xEZXNjLCAmcG9vbCkpOw0KDQogICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gcG9vbC5HZXQoKTsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzRGVzYyA9IHt9Ow0KICAgIHJlc0Rlc2MuRGltZW5zaW9uID0gRDNEMTJfUkVTT1VSQ0VfRElNRU5TSU9OX1RFWFRVUkUyRDsNCiAgICByZXNEZXNjLldpZHRoID0gMTAyNDsNCiAgICByZXNEZXNjLkhlaWdodCA9IDUxMjsNCiAgICByZXNEZXNjLkRlcHRoT3JBcnJheVNpemUgPSAxOw0KICAgIHJlc0Rlc2MuTWlwTGV2ZWxzID0gMTsNCiAgICByZXNEZXNjLkZvcm1hdCA9IERYR0lfRk9STUFUX1I4RzhCOEE4X1VOT1JNOw0KICAgIHJlc0Rlc2MuU2FtcGxlRGVzYy5Db3VudCA9IDI7DQogICAgcmVzRGVzYy5TYW1wbGVEZXNjLlF1YWxpdHkgPSAwOw0KICAgIHJlc0Rlc2MuTGF5b3V0ID0gRDNEMTJfVEVYVFVSRV9MQVlPVVRfVU5LTk9XTjsNCiAgICByZXNEZXNjLkZsYWdzID0gRDNEMTJfUkVTT1VSQ0VfRkxBR19BTExPV19SRU5ERVJfVEFSR0VUOw0KDQogICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jOw0KICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9SRU5ERVJfVEFSR0VULCBudWxscHRyLCAmYWxsb2MsIElJRF9OVUxMLCBudWxscHRyKSk7DQogICAgLy8gQ29tbWl0dGVkIGFsbG9jYXRpb24gc2hvdWxkIG5vdCBoYXZlIGV4cGxpY2l0IGhlYXANCiAgICBDSEVDS19CT09MKGFsbG9jLT5HZXRIZWFwKCkgPT0gbnVsbHB0cik7DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RNYXBwaW5nKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgbWFwcGluZ1xuIik7DQoNCiAgICBjb25zdCBVSU5UIGNvdW50ID0gMTA7DQogICAgY29uc3QgVUlOVDY0IGJ1ZlNpemUgPSAzMnVsbCAqIDEwMjQ7DQogICAgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiByZXNvdXJjZXNbY291bnRdOw0KDQogICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgIGFsbG9jRGVzYy5IZWFwVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9VUExPQUQ7DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc291cmNlRGVzYzsNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc291cmNlRGVzYywgYnVmU2l6ZSk7DQoNCiAgICBmb3IoVUlOVCBpID0gMDsgaSA8IGNvdW50OyArK2kpDQogICAgew0KICAgICAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoDQogICAgICAgICAgICAmYWxsb2NEZXNjLA0KICAgICAgICAgICAgJnJlc291cmNlRGVzYywNCiAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0dFTkVSSUNfUkVBRCwNCiAgICAgICAgICAgIE5VTEwsDQogICAgICAgICAgICAmcmVzb3VyY2VzW2ldLmFsbG9jYXRpb24sDQogICAgICAgICAgICBJSURfUFBWX0FSR1MoJnJlc291cmNlc1tpXS5yZXNvdXJjZSkpICk7DQoNCiAgICAgICAgdm9pZCogbWFwcGVkUHRyID0gTlVMTDsNCiAgICAgICAgQ0hFQ0tfSFIoIHJlc291cmNlc1tpXS5yZXNvdXJjZS0+TWFwKDAsICZFTVBUWV9SQU5HRSwgJm1hcHBlZFB0cikgKTsNCg0KICAgICAgICBGaWxsRGF0YShtYXBwZWRQdHIsIGJ1ZlNpemUsIGkpOw0KDQogICAgICAgIC8vIFVubWFwIGV2ZXJ5IG90aGVyIGJ1ZmZlci4gTGVhdmUgb3RoZXJzIG1hcHBlZC4NCiAgICAgICAgaWYoKGkgJSAyKSAhPSAwKQ0KICAgICAgICB7DQogICAgICAgICAgICByZXNvdXJjZXNbaV0ucmVzb3VyY2UtPlVubWFwKDAsIE5VTEwpOw0KICAgICAgICB9DQogICAgfQ0KfQ0KDQpzdGF0aWMgaW5saW5lIGJvb2wgU3RhdGlzdGljc0VxdWFsKGNvbnN0IEQzRDEyTUE6OkRldGFpbGVkU3RhdGlzdGljcyYgbGhzLCBjb25zdCBEM0QxMk1BOjpEZXRhaWxlZFN0YXRpc3RpY3MmIHJocykNCnsNCiAgICByZXR1cm4gbWVtY21wKCZsaHMsICZyaHMsIHNpemVvZihsaHMpKSA9PSAwOw0KfQ0KDQpzdGF0aWMgdm9pZCBDaGVja1N0YXRpc3RpY3MoY29uc3QgRDNEMTJNQTo6RGV0YWlsZWRTdGF0aXN0aWNzJiBzdGF0cykNCnsNCiAgICBDSEVDS19CT09MKHN0YXRzLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA8PSBzdGF0cy5TdGF0cy5CbG9ja0J5dGVzKTsNCiAgICBpZihzdGF0cy5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPiAwKQ0KICAgIHsNCiAgICAgICAgQ0hFQ0tfQk9PTChzdGF0cy5TdGF0cy5BbGxvY2F0aW9uQ291bnQgPiAwKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChzdGF0cy5BbGxvY2F0aW9uU2l6ZU1pbiA8PSBzdGF0cy5BbGxvY2F0aW9uU2l6ZU1heCk7DQogICAgfQ0KICAgIGlmKHN0YXRzLlVudXNlZFJhbmdlQ291bnQgPiAwKQ0KICAgIHsNCiAgICAgICAgQ0hFQ0tfQk9PTChzdGF0cy5VbnVzZWRSYW5nZVNpemVNYXggPiAwKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChzdGF0cy5VbnVzZWRSYW5nZVNpemVNaW4gPD0gc3RhdHMuVW51c2VkUmFuZ2VTaXplTWF4KTsNCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RTdGF0cyhjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IHN0YXRzXG4iKTsNCg0KICAgIEQzRDEyTUE6OlRvdGFsU3RhdGlzdGljcyBiZWdTdGF0cyA9IHt9Ow0KICAgIGN0eC5hbGxvY2F0b3ItPkNhbGN1bGF0ZVN0YXRpc3RpY3MoJmJlZ1N0YXRzKTsNCg0KICAgIGNvbnN0IFVJTlQgY291bnQgPSAxMDsNCiAgICBjb25zdCBVSU5UNjQgYnVmU2l6ZSA9IDY0dWxsICogMTAyNDsNCiAgICBSZXNvdXJjZVdpdGhBbGxvY2F0aW9uIHJlc291cmNlc1tjb3VudF07DQoNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgYWxsb2NEZXNjLkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX1VQTE9BRDsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzb3VyY2VEZXNjOw0KICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzb3VyY2VEZXNjLCBidWZTaXplKTsNCg0KICAgIGZvcihVSU5UIGkgPSAwOyBpIDwgY291bnQ7ICsraSkNCiAgICB7DQogICAgICAgIGlmKGkgPT0gY291bnQgLyAyKQ0KICAgICAgICAgICAgYWxsb2NEZXNjLkZsYWdzIHw9IEQzRDEyTUE6OkFMTE9DQVRJT05fRkxBR19DT01NSVRURUQ7DQogICAgICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgNCiAgICAgICAgICAgICZhbGxvY0Rlc2MsDQogICAgICAgICAgICAmcmVzb3VyY2VEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfR0VORVJJQ19SRUFELA0KICAgICAgICAgICAgTlVMTCwNCiAgICAgICAgICAgICZyZXNvdXJjZXNbaV0uYWxsb2NhdGlvbiwNCiAgICAgICAgICAgIElJRF9QUFZfQVJHUygmcmVzb3VyY2VzW2ldLnJlc291cmNlKSkgKTsNCiAgICB9DQoNCiAgICBEM0QxMk1BOjpUb3RhbFN0YXRpc3RpY3MgZW5kU3RhdHMgPSB7fTsNCiAgICBjdHguYWxsb2NhdG9yLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZlbmRTdGF0cyk7DQoNCiAgICBDSEVDS19CT09MKGVuZFN0YXRzLlRvdGFsLlN0YXRzLkJsb2NrQ291bnQgPj0gYmVnU3RhdHMuVG90YWwuU3RhdHMuQmxvY2tDb3VudCk7DQogICAgQ0hFQ0tfQk9PTChlbmRTdGF0cy5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQ291bnQgPT0gYmVnU3RhdHMuVG90YWwuU3RhdHMuQWxsb2NhdGlvbkNvdW50ICsgY291bnQpOw0KICAgIENIRUNLX0JPT0woZW5kU3RhdHMuVG90YWwuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzID09IGJlZ1N0YXRzLlRvdGFsLlN0YXRzLkFsbG9jYXRpb25CeXRlcyArIGNvdW50ICogYnVmU2l6ZSk7DQogICAgQ0hFQ0tfQk9PTChlbmRTdGF0cy5Ub3RhbC5BbGxvY2F0aW9uU2l6ZU1pbiA8PSBidWZTaXplKTsNCiAgICBDSEVDS19CT09MKGVuZFN0YXRzLlRvdGFsLkFsbG9jYXRpb25TaXplTWF4ID49IGJ1ZlNpemUpOw0KDQogICAgQ0hFQ0tfQk9PTChlbmRTdGF0cy5IZWFwVHlwZVsxXS5TdGF0cy5CbG9ja0NvdW50ID49IGJlZ1N0YXRzLkhlYXBUeXBlWzFdLlN0YXRzLkJsb2NrQ291bnQpOw0KICAgIENIRUNLX0JPT0woZW5kU3RhdHMuSGVhcFR5cGVbMV0uU3RhdHMuQWxsb2NhdGlvbkNvdW50ID49IGJlZ1N0YXRzLkhlYXBUeXBlWzFdLlN0YXRzLkFsbG9jYXRpb25Db3VudCArIGNvdW50KTsNCiAgICBDSEVDS19CT09MKGVuZFN0YXRzLkhlYXBUeXBlWzFdLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA+PSBiZWdTdGF0cy5IZWFwVHlwZVsxXS5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgKyBjb3VudCAqIGJ1ZlNpemUpOw0KICAgIENIRUNLX0JPT0woZW5kU3RhdHMuSGVhcFR5cGVbMV0uQWxsb2NhdGlvblNpemVNaW4gPD0gYnVmU2l6ZSk7DQogICAgQ0hFQ0tfQk9PTChlbmRTdGF0cy5IZWFwVHlwZVsxXS5BbGxvY2F0aW9uU2l6ZU1heCA+PSBidWZTaXplKTsNCg0KICAgIENIRUNLX0JPT0woU3RhdGlzdGljc0VxdWFsKGJlZ1N0YXRzLkhlYXBUeXBlWzBdLCBlbmRTdGF0cy5IZWFwVHlwZVswXSkpOw0KICAgIENIRUNLX0JPT0woU3RhdGlzdGljc0VxdWFsKGJlZ1N0YXRzLkhlYXBUeXBlWzJdLCBlbmRTdGF0cy5IZWFwVHlwZVsyXSkpOw0KDQogICAgQ2hlY2tTdGF0aXN0aWNzKGVuZFN0YXRzLlRvdGFsKTsNCiAgICBDaGVja1N0YXRpc3RpY3MoZW5kU3RhdHMuSGVhcFR5cGVbMF0pOw0KICAgIENoZWNrU3RhdGlzdGljcyhlbmRTdGF0cy5IZWFwVHlwZVsxXSk7DQogICAgQ2hlY2tTdGF0aXN0aWNzKGVuZFN0YXRzLkhlYXBUeXBlWzJdKTsNCg0KICAgIEQzRDEyTUE6OkJ1ZGdldCBsb2NhbEJ1ZGdldCA9IHt9LCBub25Mb2NhbEJ1ZGdldCA9IHt9Ow0KICAgIGN0eC5hbGxvY2F0b3ItPkdldEJ1ZGdldCgmbG9jYWxCdWRnZXQsICZub25Mb2NhbEJ1ZGdldCk7DQoNCiAgICBDSEVDS19CT09MKGxvY2FsQnVkZ2V0LlN0YXRzLkFsbG9jYXRpb25CeXRlcyA8PSBsb2NhbEJ1ZGdldC5TdGF0cy5CbG9ja0J5dGVzKTsNCiAgICBDSEVDS19CT09MKGVuZFN0YXRzLkhlYXBUeXBlWzNdLlN0YXRzLkJsb2NrQ291bnQgPT0gMCk7IC8vIE5vIGFsbG9jYXRpb24gZnJvbSBEM0QxMl9IRUFQX1RZUEVfQ1VTVE9NIGluIHRoaXMgdGVzdC4NCiAgICBpZighY3R4LmFsbG9jYXRvci0+SXNVTUEoKSkNCiAgICB7DQogICAgICAgIC8vIERpc2NyZXRlIEdQVQ0KICAgICAgICBDSEVDS19CT09MKGxvY2FsQnVkZ2V0LlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PSBlbmRTdGF0cy5IZWFwVHlwZVswXS5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMpOw0KICAgICAgICBDSEVDS19CT09MKGxvY2FsQnVkZ2V0LlN0YXRzLkJsb2NrQnl0ZXMgPT0gZW5kU3RhdHMuSGVhcFR5cGVbMF0uU3RhdHMuQmxvY2tCeXRlcyk7DQogICAgDQogICAgICAgIENIRUNLX0JPT0wobm9uTG9jYWxCdWRnZXQuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzIDw9IG5vbkxvY2FsQnVkZ2V0LlN0YXRzLkJsb2NrQnl0ZXMpOw0KICAgICAgICBDSEVDS19CT09MKG5vbkxvY2FsQnVkZ2V0LlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PSBlbmRTdGF0cy5IZWFwVHlwZVsxXS5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgKyBlbmRTdGF0cy5IZWFwVHlwZVsyXS5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMpOw0KICAgICAgICBDSEVDS19CT09MKG5vbkxvY2FsQnVkZ2V0LlN0YXRzLkJsb2NrQnl0ZXMgPT0NCiAgICAgICAgICAgIGVuZFN0YXRzLkhlYXBUeXBlWzFdLlN0YXRzLkJsb2NrQnl0ZXMgKyBlbmRTdGF0cy5IZWFwVHlwZVsyXS5TdGF0cy5CbG9ja0J5dGVzKTsNCiAgICB9DQogICAgZWxzZQ0KICAgIHsNCiAgICAgICAgLy8gSW50ZWdyYXRlZCBHUFUgLSBhbGwgbWVtb3J5IGlzIGxvY2FsDQogICAgICAgIENIRUNLX0JPT0wobG9jYWxCdWRnZXQuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzID09IGVuZFN0YXRzLkhlYXBUeXBlWzBdLlN0YXRzLkFsbG9jYXRpb25CeXRlcyArDQogICAgICAgICAgICBlbmRTdGF0cy5IZWFwVHlwZVsxXS5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgKw0KICAgICAgICAgICAgZW5kU3RhdHMuSGVhcFR5cGVbMl0uU3RhdHMuQWxsb2NhdGlvbkJ5dGVzKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChsb2NhbEJ1ZGdldC5TdGF0cy5CbG9ja0J5dGVzID09IGVuZFN0YXRzLkhlYXBUeXBlWzBdLlN0YXRzLkJsb2NrQnl0ZXMgKw0KICAgICAgICAgICAgZW5kU3RhdHMuSGVhcFR5cGVbMV0uU3RhdHMuQmxvY2tCeXRlcyArDQogICAgICAgICAgICBlbmRTdGF0cy5IZWFwVHlwZVsyXS5TdGF0cy5CbG9ja0J5dGVzKTsNCg0KICAgICAgICBDSEVDS19CT09MKG5vbkxvY2FsQnVkZ2V0LlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PSAwKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChub25Mb2NhbEJ1ZGdldC5TdGF0cy5CbG9ja0J5dGVzID09IDApOw0KICAgIH0NCn0NCg0Kc3RhdGljIHZvaWQgVGVzdFRyYW5zZmVyKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgbWFwcGluZ1xuIik7DQoNCiAgICBjb25zdCBVSU5UIGNvdW50ID0gMTA7DQogICAgY29uc3QgVUlOVDY0IGJ1ZlNpemUgPSAzMnVsbCAqIDEwMjQ7DQogICAgDQogICAgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiByZXNvdXJjZXNVcGxvYWRbY291bnRdOw0KICAgIFJlc291cmNlV2l0aEFsbG9jYXRpb24gcmVzb3VyY2VzRGVmYXVsdFtjb3VudF07DQogICAgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiByZXNvdXJjZXNSZWFkYmFja1tjb3VudF07DQoNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjVXBsb2FkID0ge307DQogICAgYWxsb2NEZXNjVXBsb2FkLkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX1VQTE9BRDsNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjRGVmYXVsdCA9IHt9Ow0KICAgIGFsbG9jRGVzY0RlZmF1bHQuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjUmVhZGJhY2sgPSB7fTsNCiAgICBhbGxvY0Rlc2NSZWFkYmFjay5IZWFwVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9SRUFEQkFDSzsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzb3VyY2VEZXNjOw0KICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzb3VyY2VEZXNjLCBidWZTaXplKTsNCg0KICAgIC8vIENyZWF0ZSAzIHNldHMgb2YgcmVzb3VyY2VzLg0KICAgIGZvcihVSU5UIGkgPSAwOyBpIDwgY291bnQ7ICsraSkNCiAgICB7DQogICAgICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgNCiAgICAgICAgICAgICZhbGxvY0Rlc2NVcGxvYWQsDQogICAgICAgICAgICAmcmVzb3VyY2VEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfR0VORVJJQ19SRUFELA0KICAgICAgICAgICAgTlVMTCwNCiAgICAgICAgICAgICZyZXNvdXJjZXNVcGxvYWRbaV0uYWxsb2NhdGlvbiwNCiAgICAgICAgICAgIElJRF9QUFZfQVJHUygmcmVzb3VyY2VzVXBsb2FkW2ldLnJlc291cmNlKSkgKTsNCg0KICAgICAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoDQogICAgICAgICAgICAmYWxsb2NEZXNjRGVmYXVsdCwNCiAgICAgICAgICAgICZyZXNvdXJjZURlc2MsDQogICAgICAgICAgICBEM0QxMl9SRVNPVVJDRV9TVEFURV9DT1BZX0RFU1QsDQogICAgICAgICAgICBOVUxMLA0KICAgICAgICAgICAgJnJlc291cmNlc0RlZmF1bHRbaV0uYWxsb2NhdGlvbiwNCiAgICAgICAgICAgIElJRF9QUFZfQVJHUygmcmVzb3VyY2VzRGVmYXVsdFtpXS5yZXNvdXJjZSkpICk7DQoNCiAgICAgICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKA0KICAgICAgICAgICAgJmFsbG9jRGVzY1JlYWRiYWNrLA0KICAgICAgICAgICAgJnJlc291cmNlRGVzYywNCiAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPUFlfREVTVCwNCiAgICAgICAgICAgIE5VTEwsDQogICAgICAgICAgICAmcmVzb3VyY2VzUmVhZGJhY2tbaV0uYWxsb2NhdGlvbiwNCiAgICAgICAgICAgIElJRF9QUFZfQVJHUygmcmVzb3VyY2VzUmVhZGJhY2tbaV0ucmVzb3VyY2UpKSApOw0KICAgIH0NCg0KICAgIC8vIE1hcCBhbmQgZmlsbCBkYXRhIGluIFVQTE9BRC4NCiAgICBmb3IoVUlOVCBpID0gMDsgaSA8IGNvdW50OyArK2kpDQogICAgew0KICAgICAgICB2b2lkKiBtYXBwZWRQdHIgPSBudWxscHRyOw0KICAgICAgICBDSEVDS19IUiggcmVzb3VyY2VzVXBsb2FkW2ldLnJlc291cmNlLT5NYXAoMCwgJkVNUFRZX1JBTkdFLCAmbWFwcGVkUHRyKSApOw0KDQogICAgICAgIEZpbGxEYXRhKG1hcHBlZFB0ciwgYnVmU2l6ZSwgaSk7DQoNCiAgICAgICAgLy8gVW5tYXAgZXZlcnkgb3RoZXIgcmVzb3VyY2UsIGxlYXZlIG90aGVycyBtYXBwZWQuDQogICAgICAgIGlmKChpICUgMikgIT0gMCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmVzb3VyY2VzVXBsb2FkW2ldLnJlc291cmNlLT5Vbm1hcCgwLCBOVUxMKTsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIC8vIFRyYW5zZmVyIGZyb20gVVBMT0FEIHRvIERFRkFVTFQsIGZyb20gdGhlcmUgdG8gUkVBREJBQ0suDQogICAgSUQzRDEyR3JhcGhpY3NDb21tYW5kTGlzdCogY21kTGlzdCA9IEJlZ2luQ29tbWFuZExpc3QoKTsNCiAgICBmb3IoVUlOVCBpID0gMDsgaSA8IGNvdW50OyArK2kpDQogICAgew0KICAgICAgICBjbWRMaXN0LT5Db3B5QnVmZmVyUmVnaW9uKHJlc291cmNlc0RlZmF1bHRbaV0ucmVzb3VyY2UuR2V0KCksIDAsIHJlc291cmNlc1VwbG9hZFtpXS5yZXNvdXJjZS5HZXQoKSwgMCwgYnVmU2l6ZSk7DQogICAgfQ0KICAgIEQzRDEyX1JFU09VUkNFX0JBUlJJRVIgYmFycmllcnNbY291bnRdID0ge307DQogICAgZm9yKFVJTlQgaSA9IDA7IGkgPCBjb3VudDsgKytpKQ0KICAgIHsNCiAgICAgICAgYmFycmllcnNbaV0uVHlwZSA9IEQzRDEyX1JFU09VUkNFX0JBUlJJRVJfVFlQRV9UUkFOU0lUSU9OOw0KICAgICAgICBiYXJyaWVyc1tpXS5UcmFuc2l0aW9uLnBSZXNvdXJjZSA9IHJlc291cmNlc0RlZmF1bHRbaV0ucmVzb3VyY2UuR2V0KCk7DQogICAgICAgIGJhcnJpZXJzW2ldLlRyYW5zaXRpb24uU3RhdGVCZWZvcmUgPSBEM0QxMl9SRVNPVVJDRV9TVEFURV9DT1BZX0RFU1Q7DQogICAgICAgIGJhcnJpZXJzW2ldLlRyYW5zaXRpb24uU3RhdGVBZnRlciA9IEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPUFlfU09VUkNFOw0KICAgICAgICBiYXJyaWVyc1tpXS5UcmFuc2l0aW9uLlN1YnJlc291cmNlID0gRDNEMTJfUkVTT1VSQ0VfQkFSUklFUl9BTExfU1VCUkVTT1VSQ0VTOw0KICAgIH0NCiAgICBjbWRMaXN0LT5SZXNvdXJjZUJhcnJpZXIoY291bnQsIGJhcnJpZXJzKTsNCiAgICBmb3IoVUlOVCBpID0gMDsgaSA8IGNvdW50OyArK2kpDQogICAgew0KICAgICAgICBjbWRMaXN0LT5Db3B5QnVmZmVyUmVnaW9uKHJlc291cmNlc1JlYWRiYWNrW2ldLnJlc291cmNlLkdldCgpLCAwLCByZXNvdXJjZXNEZWZhdWx0W2ldLnJlc291cmNlLkdldCgpLCAwLCBidWZTaXplKTsNCiAgICB9DQogICAgRW5kQ29tbWFuZExpc3QoY21kTGlzdCk7DQoNCiAgICAvLyBWYWxpZGF0ZSBSRUFEQkFDSyBidWZmZXJzLg0KICAgIGZvcihVSU5UIGkgPSBjb3VudDsgaS0tOyApDQogICAgew0KICAgICAgICBjb25zdCBEM0QxMl9SQU5HRSBtYXBSYW5nZSA9IHswLCBidWZTaXplfTsNCiAgICAgICAgdm9pZCogbWFwcGVkUHRyID0gbnVsbHB0cjsNCiAgICAgICAgQ0hFQ0tfSFIoIHJlc291cmNlc1JlYWRiYWNrW2ldLnJlc291cmNlLT5NYXAoMCwgJm1hcFJhbmdlLCAmbWFwcGVkUHRyKSApOw0KDQogICAgICAgIENIRUNLX0JPT0woIFZhbGlkYXRlRGF0YShtYXBwZWRQdHIsIGJ1ZlNpemUsIGkpICk7DQoNCiAgICAgICAgLy8gVW5tYXAgZXZlcnkgM3JkIHJlc291cmNlLCBsZWF2ZSBvdGhlcnMgbWFwcGVkLg0KICAgICAgICBpZigoaSAlIDMpICE9IDApDQogICAgICAgIHsNCiAgICAgICAgICAgIHJlc291cmNlc1JlYWRiYWNrW2ldLnJlc291cmNlLT5Vbm1hcCgwLCAmRU1QVFlfUkFOR0UpOw0KICAgICAgICB9DQogICAgfQ0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0WmVyb0luaXRpYWxpemVkKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgemVybyBpbml0aWFsaXplZFxuIik7DQoNCiAgICBjb25zdCBVSU5UNjQgYnVmU2l6ZSA9IDEyOHVsbCAqIDEwMjQ7DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc291cmNlRGVzYzsNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc291cmNlRGVzYywgYnVmU2l6ZSk7DQoNCiAgICAvLyAjIENyZWF0ZSB1cGxvYWQgYnVmZmVyIGFuZCBmaWxsIGl0IHdpdGggZGF0YS4NCg0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2NVcGxvYWQgPSB7fTsNCiAgICBhbGxvY0Rlc2NVcGxvYWQuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfVVBMT0FEOw0KDQogICAgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiBidWZVcGxvYWQ7DQogICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKA0KICAgICAgICAmYWxsb2NEZXNjVXBsb2FkLA0KICAgICAgICAmcmVzb3VyY2VEZXNjLA0KICAgICAgICBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsDQogICAgICAgIE5VTEwsDQogICAgICAgICZidWZVcGxvYWQuYWxsb2NhdGlvbiwNCiAgICAgICAgSUlEX1BQVl9BUkdTKCZidWZVcGxvYWQucmVzb3VyY2UpKSApOw0KDQogICAgew0KICAgICAgICB2b2lkKiBtYXBwZWRQdHIgPSBudWxscHRyOw0KICAgICAgICBDSEVDS19IUiggYnVmVXBsb2FkLnJlc291cmNlLT5NYXAoMCwgJkVNUFRZX1JBTkdFLCAmbWFwcGVkUHRyKSApOw0KICAgICAgICBGaWxsRGF0YShtYXBwZWRQdHIsIGJ1ZlNpemUsIDUyMzYyNDUpOw0KICAgICAgICBidWZVcGxvYWQucmVzb3VyY2UtPlVubWFwKDAsIE5VTEwpOw0KICAgIH0NCg0KICAgIC8vICMgQ3JlYXRlIHJlYWRiYWNrIGJ1ZmZlcg0KICAgIA0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2NSZWFkYmFjayA9IHt9Ow0KICAgIGFsbG9jRGVzY1JlYWRiYWNrLkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX1JFQURCQUNLOw0KDQogICAgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiBidWZSZWFkYmFjazsNCiAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoDQogICAgICAgICZhbGxvY0Rlc2NSZWFkYmFjaywNCiAgICAgICAgJnJlc291cmNlRGVzYywNCiAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9ERVNULA0KICAgICAgICBOVUxMLA0KICAgICAgICAmYnVmUmVhZGJhY2suYWxsb2NhdGlvbiwNCiAgICAgICAgSUlEX1BQVl9BUkdTKCZidWZSZWFkYmFjay5yZXNvdXJjZSkpICk7DQoNCiAgICBhdXRvIENoZWNrQnVmZmVyRGF0YSA9IFsmXShjb25zdCBSZXNvdXJjZVdpdGhBbGxvY2F0aW9uJiBidWYpDQogICAgew0KICAgICAgICBjb25zdCBib29sIHNob3VsZEJlWmVybyA9IGJ1Zi5hbGxvY2F0aW9uLT5XYXNaZXJvSW5pdGlhbGl6ZWQoKSAhPSBGQUxTRTsNCg0KICAgICAgICB7DQogICAgICAgICAgICBJRDNEMTJHcmFwaGljc0NvbW1hbmRMaXN0KiBjbWRMaXN0ID0gQmVnaW5Db21tYW5kTGlzdCgpOw0KICAgICAgICAgICAgY21kTGlzdC0+Q29weUJ1ZmZlclJlZ2lvbihidWZSZWFkYmFjay5yZXNvdXJjZS5HZXQoKSwgMCwgYnVmLnJlc291cmNlLkdldCgpLCAwLCBidWZTaXplKTsNCiAgICAgICAgICAgIEVuZENvbW1hbmRMaXN0KGNtZExpc3QpOw0KICAgICAgICB9DQoNCiAgICAgICAgYm9vbCBpc1plcm8gPSBmYWxzZTsNCiAgICAgICAgew0KICAgICAgICAgICAgY29uc3QgRDNEMTJfUkFOR0UgcmVhZFJhbmdlezAsIGJ1ZlNpemV9OyAvLyBJIGNvdWxkIHBhc3MgcFJlYWRSYW5nZSA9IE5VTEwgYnV0IGl0IGdlbmVyYXRlcyBEM0QgRGVidWcgbGF5ZXIgd2FybmluZzogRVhFQ1VUSU9OIFdBUk5JTkcgIzkzMDogTUFQX0lOVkFMSURfTlVMTFJBTkdFDQogICAgICAgICAgICB2b2lkKiBtYXBwZWRQdHIgPSBudWxscHRyOw0KICAgICAgICAgICAgQ0hFQ0tfSFIoIGJ1ZlJlYWRiYWNrLnJlc291cmNlLT5NYXAoMCwgJnJlYWRSYW5nZSwgJm1hcHBlZFB0cikgKTsNCiAgICAgICAgICAgIGlzWmVybyA9IFZhbGlkYXRlRGF0YVplcm8obWFwcGVkUHRyLCBidWZTaXplKTsNCiAgICAgICAgICAgIGJ1ZlJlYWRiYWNrLnJlc291cmNlLT5Vbm1hcCgwLCAmRU1QVFlfUkFOR0UpOw0KICAgICAgICB9DQoNCiAgICAgICAgd3ByaW50ZihMIlNob3VsZCBiZSB6ZXJvOiAldSwgaXMgemVybzogJXVcbiIsIHNob3VsZEJlWmVybyA/IDEgOiAwLCBpc1plcm8gPyAxIDogMCk7DQoNCiAgICAgICAgaWYoc2hvdWxkQmVaZXJvKQ0KICAgICAgICB7DQogICAgICAgICAgICBDSEVDS19CT09MKGlzWmVybyk7DQogICAgICAgIH0NCiAgICB9Ow0KDQogICAgLy8gIyBUZXN0IDE6IENvbW1pdHRlZCByZXNvdXJjZS4gU2hvdWxkIGFsd2F5cyBiZSB6ZXJvIGluaXRpYWxpemVkLg0KDQogICAgew0KICAgICAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjRGVmYXVsdCA9IHt9Ow0KICAgICAgICBhbGxvY0Rlc2NEZWZhdWx0LkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQogICAgICAgIGFsbG9jRGVzY0RlZmF1bHQuRmxhZ3MgPSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfQ09NTUlUVEVEOw0KDQogICAgICAgIFJlc291cmNlV2l0aEFsbG9jYXRpb24gYnVmRGVmYXVsdDsNCiAgICAgICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKA0KICAgICAgICAgICAgJmFsbG9jRGVzY0RlZmF1bHQsDQogICAgICAgICAgICAmcmVzb3VyY2VEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9TT1VSQ0UsDQogICAgICAgICAgICBOVUxMLA0KICAgICAgICAgICAgJmJ1ZkRlZmF1bHQuYWxsb2NhdGlvbiwNCiAgICAgICAgICAgIElJRF9QUFZfQVJHUygmYnVmRGVmYXVsdC5yZXNvdXJjZSkpICk7DQoNCiAgICAgICAgd3ByaW50ZihMIiAgQ29tbWl0dGVkOiAiKTsNCiAgICAgICAgQ2hlY2tCdWZmZXJEYXRhKGJ1ZkRlZmF1bHQpOw0KICAgICAgICBDSEVDS19CT09MKCBidWZEZWZhdWx0LmFsbG9jYXRpb24tPldhc1plcm9Jbml0aWFsaXplZCgpICk7DQogICAgfQ0KDQogICAgLy8gIyBUZXN0IDI6IChQcm9iYWJseSkgcGxhY2VkIHJlc291cmNlLg0KDQogICAgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiBidWZEZWZhdWx0Ow0KICAgIGZvcih1aW50MzJfdCBpID0gMDsgaSA8IDI7ICsraSkNCiAgICB7DQogICAgICAgIC8vIDEuIENyZWF0ZSBidWZmZXINCg0KICAgICAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjRGVmYXVsdCA9IHt9Ow0KICAgICAgICBhbGxvY0Rlc2NEZWZhdWx0LkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQoNCiAgICAgICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKA0KICAgICAgICAgICAgJmFsbG9jRGVzY0RlZmF1bHQsDQogICAgICAgICAgICAmcmVzb3VyY2VEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9TT1VSQ0UsDQogICAgICAgICAgICBOVUxMLA0KICAgICAgICAgICAgJmJ1ZkRlZmF1bHQuYWxsb2NhdGlvbiwNCiAgICAgICAgICAgIElJRF9QUFZfQVJHUygmYnVmRGVmYXVsdC5yZXNvdXJjZSkpICk7DQoNCiAgICAgICAgLy8gMi4gQ2hlY2sgaXQNCg0KICAgICAgICB3cHJpbnRmKEwiICBOb3JtYWwgIyV1OiAiLCBpKTsNCiAgICAgICAgQ2hlY2tCdWZmZXJEYXRhKGJ1ZkRlZmF1bHQpOw0KDQogICAgICAgIC8vIDMuIFVwbG9hZCBzb21lIGRhdGEgdG8gaXQNCg0KICAgICAgICB7DQogICAgICAgICAgICBJRDNEMTJHcmFwaGljc0NvbW1hbmRMaXN0KiBjbWRMaXN0ID0gQmVnaW5Db21tYW5kTGlzdCgpOw0KDQogICAgICAgICAgICBEM0QxMl9SRVNPVVJDRV9CQVJSSUVSIGJhcnJpZXIgPSB7fTsNCiAgICAgICAgICAgIGJhcnJpZXIuVHlwZSA9IEQzRDEyX1JFU09VUkNFX0JBUlJJRVJfVFlQRV9UUkFOU0lUSU9OOw0KICAgICAgICAgICAgYmFycmllci5UcmFuc2l0aW9uLnBSZXNvdXJjZSA9IGJ1ZkRlZmF1bHQucmVzb3VyY2UuR2V0KCk7DQogICAgICAgICAgICBiYXJyaWVyLlRyYW5zaXRpb24uU3RhdGVCZWZvcmUgPSBEM0QxMl9SRVNPVVJDRV9TVEFURV9DT1BZX1NPVVJDRTsNCiAgICAgICAgICAgIGJhcnJpZXIuVHJhbnNpdGlvbi5TdGF0ZUFmdGVyID0gRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9ERVNUOw0KICAgICAgICAgICAgYmFycmllci5UcmFuc2l0aW9uLlN1YnJlc291cmNlID0gRDNEMTJfUkVTT1VSQ0VfQkFSUklFUl9BTExfU1VCUkVTT1VSQ0VTOw0KICAgICAgICAgICAgY21kTGlzdC0+UmVzb3VyY2VCYXJyaWVyKDEsICZiYXJyaWVyKTsNCg0KICAgICAgICAgICAgY21kTGlzdC0+Q29weUJ1ZmZlclJlZ2lvbihidWZEZWZhdWx0LnJlc291cmNlLkdldCgpLCAwLCBidWZVcGxvYWQucmVzb3VyY2UuR2V0KCksIDAsIGJ1ZlNpemUpOw0KICAgICAgICAgICAgDQogICAgICAgICAgICBFbmRDb21tYW5kTGlzdChjbWRMaXN0KTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIDQuIERlbGV0ZSBpdA0KDQogICAgICAgIGJ1ZkRlZmF1bHQuUmVzZXQoKTsNCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RNdWx0aXRocmVhZGluZyhjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IG11bHRpdGhyZWFkaW5nXG4iKTsNCg0KICAgIGNvbnN0IFVJTlQgdGhyZWFkQ291bnQgPSAzMjsNCiAgICBjb25zdCBVSU5UIGJ1ZlNpemVNaW4gPSAxMDI0dWxsOw0KICAgIGNvbnN0IFVJTlQgYnVmU2l6ZU1heCA9IDEwMjR1bGwgKiAxMDI0Ow0KDQogICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgIGFsbG9jRGVzYy5IZWFwVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9VUExPQUQ7DQoNCiAgICAvLyBMYXVuY2ggdGhyZWFkcy4NCiAgICBzdGQ6OnRocmVhZCB0aHJlYWRzW3RocmVhZENvdW50XTsNCiAgICBmb3IoVUlOVCB0aHJlYWRJbmRleCA9IDA7IHRocmVhZEluZGV4IDwgdGhyZWFkQ291bnQ7ICsrdGhyZWFkSW5kZXgpDQogICAgew0KICAgICAgICBhdXRvIHRocmVhZEZ1bmMgPSBbJiwgdGhyZWFkSW5kZXhdKCkNCiAgICAgICAgew0KICAgICAgICAgICAgUmFuZG9tTnVtYmVyR2VuZXJhdG9yIHJhbmQodGhyZWFkSW5kZXgpOw0KDQogICAgICAgICAgICBzdGQ6OnZlY3RvcjxSZXNvdXJjZVdpdGhBbGxvY2F0aW9uPiByZXNvdXJjZXM7DQogICAgICAgICAgICByZXNvdXJjZXMucmVzZXJ2ZSgyNTYpOw0KDQogICAgICAgICAgICAvLyBDcmVhdGUgc3RhcnRpbmcgbnVtYmVyIG9mIGJ1ZmZlcnMuDQogICAgICAgICAgICBjb25zdCBVSU5UIGJ1ZlRvQ3JlYXRlQ291bnQgPSAzMjsNCiAgICAgICAgICAgIGZvcihVSU5UIGJ1ZkluZGV4ID0gMDsgYnVmSW5kZXggPCBidWZUb0NyZWF0ZUNvdW50OyArK2J1ZkluZGV4KQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIFJlc291cmNlV2l0aEFsbG9jYXRpb24gcmVzID0ge307DQogICAgICAgICAgICAgICAgcmVzLmRhdGFTZWVkID0gKHRocmVhZEluZGV4IDw8IDE2KSB8IGJ1ZkluZGV4Ow0KICAgICAgICAgICAgICAgIHJlcy5zaXplID0gQWxpZ25VcDxVSU5UPihyYW5kLkdlbmVyYXRlKCkgJSAoYnVmU2l6ZU1heCAtIGJ1ZlNpemVNaW4pICsgYnVmU2l6ZU1pbiwgMTYpOw0KDQogICAgICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNvdXJjZURlc2M7DQogICAgICAgICAgICAgICAgRmlsbFJlc291cmNlRGVzY0ZvckJ1ZmZlcihyZXNvdXJjZURlc2MsIHJlcy5zaXplKTsNCg0KICAgICAgICAgICAgICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgNCiAgICAgICAgICAgICAgICAgICAgJmFsbG9jRGVzYywNCiAgICAgICAgICAgICAgICAgICAgJnJlc291cmNlRGVzYywNCiAgICAgICAgICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfR0VORVJJQ19SRUFELA0KICAgICAgICAgICAgICAgICAgICBOVUxMLA0KICAgICAgICAgICAgICAgICAgICAmcmVzLmFsbG9jYXRpb24sDQogICAgICAgICAgICAgICAgICAgIElJRF9QUFZfQVJHUygmcmVzLnJlc291cmNlKSkgKTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICB2b2lkKiBtYXBwZWRQdHIgPSBudWxscHRyOw0KICAgICAgICAgICAgICAgIENIRUNLX0hSKCByZXMucmVzb3VyY2UtPk1hcCgwLCAmRU1QVFlfUkFOR0UsICZtYXBwZWRQdHIpICk7DQoNCiAgICAgICAgICAgICAgICBGaWxsRGF0YShtYXBwZWRQdHIsIHJlcy5zaXplLCByZXMuZGF0YVNlZWQpOw0KDQogICAgICAgICAgICAgICAgLy8gVW5tYXAgc29tZSBvZiB0aGVtLCBsZWF2ZSBvdGhlcnMgbWFwcGVkLg0KICAgICAgICAgICAgICAgIGlmKHJhbmQuR2VuZXJhdGVCb29sKCkpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICByZXMucmVzb3VyY2UtPlVubWFwKDAsIE5VTEwpOw0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIHJlc291cmNlcy5wdXNoX2JhY2soc3RkOjptb3ZlKHJlcykpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgDQogICAgICAgICAgICBTbGVlcCgyMCk7DQoNCiAgICAgICAgICAgIC8vIE1ha2UgYSBudW1iZXIgb2YgcmFuZG9tIGFsbG9jYXRlIGFuZCBmcmVlIG9wZXJhdGlvbnMuDQogICAgICAgICAgICBjb25zdCBVSU5UIG9wZXJhdGlvbkNvdW50ID0gMTI4Ow0KICAgICAgICAgICAgZm9yKFVJTlQgb3BlcmF0aW9uSW5kZXggPSAwOyBvcGVyYXRpb25JbmRleCA8IG9wZXJhdGlvbkNvdW50OyArK29wZXJhdGlvbkluZGV4KQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGNvbnN0IGJvb2wgcmVtb3ZlUG9zc2libGUgPSAhcmVzb3VyY2VzLmVtcHR5KCk7DQogICAgICAgICAgICAgICAgY29uc3QgYm9vbCByZW1vdmUgPSByZW1vdmVQb3NzaWJsZSAmJiByYW5kLkdlbmVyYXRlQm9vbCgpOw0KICAgICAgICAgICAgICAgIGlmKHJlbW92ZSkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIGNvbnN0IFVJTlQgaW5kZXhUb1JlbW92ZSA9IHJhbmQuR2VuZXJhdGUoKSAlIHJlc291cmNlcy5zaXplKCk7DQogICAgICAgICAgICAgICAgICAgIHJlc291cmNlcy5lcmFzZShyZXNvdXJjZXMuYmVnaW4oKSArIGluZGV4VG9SZW1vdmUpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBlbHNlIC8vIENyZWF0ZSBuZXcgYnVmZmVyLg0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiByZXMgPSB7fTsNCiAgICAgICAgICAgICAgICAgICAgcmVzLmRhdGFTZWVkID0gKHRocmVhZEluZGV4IDw8IDE2KSB8IG9wZXJhdGlvbkluZGV4Ow0KICAgICAgICAgICAgICAgICAgICByZXMuc2l6ZSA9IEFsaWduVXA8VUlOVD4ocmFuZC5HZW5lcmF0ZSgpICUgKGJ1ZlNpemVNYXggLSBidWZTaXplTWluKSArIGJ1ZlNpemVNaW4sIDE2KTsNCiAgICAgICAgICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNvdXJjZURlc2M7DQogICAgICAgICAgICAgICAgICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzb3VyY2VEZXNjLCByZXMuc2l6ZSk7DQoNCiAgICAgICAgICAgICAgICAgICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgJmFsbG9jRGVzYywNCiAgICAgICAgICAgICAgICAgICAgICAgICZyZXNvdXJjZURlc2MsDQogICAgICAgICAgICAgICAgICAgICAgICBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsDQogICAgICAgICAgICAgICAgICAgICAgICBOVUxMLA0KICAgICAgICAgICAgICAgICAgICAgICAgJnJlcy5hbGxvY2F0aW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgSUlEX1BQVl9BUkdTKCZyZXMucmVzb3VyY2UpKSApOw0KDQogICAgICAgICAgICAgICAgICAgIHZvaWQqIG1hcHBlZFB0ciA9IG51bGxwdHI7DQogICAgICAgICAgICAgICAgICAgIENIRUNLX0hSKCByZXMucmVzb3VyY2UtPk1hcCgwLCBOVUxMLCAmbWFwcGVkUHRyKSApOw0KDQogICAgICAgICAgICAgICAgICAgIEZpbGxEYXRhKG1hcHBlZFB0ciwgcmVzLnNpemUsIHJlcy5kYXRhU2VlZCk7DQoNCiAgICAgICAgICAgICAgICAgICAgLy8gVW5tYXAgc29tZSBvZiB0aGVtLCBsZWF2ZSBvdGhlcnMgbWFwcGVkLg0KICAgICAgICAgICAgICAgICAgICBpZihyYW5kLkdlbmVyYXRlQm9vbCgpKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICByZXMucmVzb3VyY2UtPlVubWFwKDAsIE5VTEwpOw0KICAgICAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAgICAgcmVzb3VyY2VzLnB1c2hfYmFjayhzdGQ6Om1vdmUocmVzKSk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBTbGVlcCgyMCk7DQoNCiAgICAgICAgICAgIC8vIFZhbGlkYXRlIGRhdGEgaW4gYWxsIHJlbWFpbmluZyBidWZmZXJzIHdoaWxlIGRlbGV0aW5nIHRoZW0uDQogICAgICAgICAgICBmb3Ioc2l6ZV90IHJlc0luZGV4ID0gcmVzb3VyY2VzLnNpemUoKTsgcmVzSW5kZXgtLTsgKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZvaWQqIG1hcHBlZFB0ciA9IG51bGxwdHI7DQogICAgICAgICAgICAgICAgQ0hFQ0tfSFIoIHJlc291cmNlc1tyZXNJbmRleF0ucmVzb3VyY2UtPk1hcCgwLCBOVUxMLCAmbWFwcGVkUHRyKSApOw0KDQogICAgICAgICAgICAgICAgVmFsaWRhdGVEYXRhKG1hcHBlZFB0ciwgcmVzb3VyY2VzW3Jlc0luZGV4XS5zaXplLCByZXNvdXJjZXNbcmVzSW5kZXhdLmRhdGFTZWVkKTsNCg0KICAgICAgICAgICAgICAgIC8vIFVubWFwIHNvbWUgb2YgdGhlbSwgbGVhdmUgb3RoZXJzIG1hcHBlZC4NCiAgICAgICAgICAgICAgICBpZigocmVzSW5kZXggJSAzKSA9PSAxKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgcmVzb3VyY2VzW3Jlc0luZGV4XS5yZXNvdXJjZS0+VW5tYXAoMCwgJkVNUFRZX1JBTkdFKTsNCiAgICAgICAgICAgICAgICB9IA0KDQogICAgICAgICAgICAgICAgcmVzb3VyY2VzLnBvcF9iYWNrKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH07DQogICAgICAgIHRocmVhZHNbdGhyZWFkSW5kZXhdID0gc3RkOjp0aHJlYWQodGhyZWFkRnVuYyk7DQogICAgfQ0KDQogICAgLy8gV2FpdCBmb3IgdGhyZWFkcyB0byBmaW5pc2guDQogICAgZm9yKFVJTlQgdGhyZWFkSW5kZXggPSB0aHJlYWRDb3VudDsgdGhyZWFkSW5kZXgtLTsgKQ0KICAgIHsNCiAgICAgICAgdGhyZWFkc1t0aHJlYWRJbmRleF0uam9pbigpOw0KICAgIH0NCn0NCg0Kc3RhdGljIGJvb2wgSXNQcm90ZWN0ZWRSZXNvdXJjZVNlc3Npb25TdXBwb3J0ZWQoY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICBEM0QxMl9GRUFUVVJFX0RBVEFfUFJPVEVDVEVEX1JFU09VUkNFX1NFU1NJT05fU1VQUE9SVCBzdXBwb3J0ID0ge307DQogICAgQ0hFQ0tfSFIoY3R4LmRldmljZS0+Q2hlY2tGZWF0dXJlU3VwcG9ydCgNCiAgICAgICAgRDNEMTJfRkVBVFVSRV9QUk9URUNURURfUkVTT1VSQ0VfU0VTU0lPTl9TVVBQT1JULCAmc3VwcG9ydCwgc2l6ZW9mIHN1cHBvcnQpKTsNCiAgICByZXR1cm4gc3VwcG9ydC5TdXBwb3J0ID4gRDNEMTJfUFJPVEVDVEVEX1JFU09VUkNFX1NFU1NJT05fU1VQUE9SVF9GTEFHX05PTkU7DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RMaW5lYXJBbGxvY2F0b3IoY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICB3cHJpbnRmKEwiVGVzdCBsaW5lYXIgYWxsb2NhdG9yXG4iKTsNCg0KICAgIFJhbmRvbU51bWJlckdlbmVyYXRvciByYW5keyA2NDUzMzIgfTsNCg0KICAgIEQzRDEyTUE6OlBPT0xfREVTQyBwb29sRGVzYyA9IHt9Ow0KICAgIHBvb2xEZXNjLkhlYXBGbGFncyA9IEQzRDEyX0hFQVBfRkxBR19BTExPV19PTkxZX0JVRkZFUlM7DQogICAgcG9vbERlc2MuSGVhcFByb3BlcnRpZXMuVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9ERUZBVUxUOw0KICAgIHBvb2xEZXNjLkZsYWdzID0gRDNEMTJNQTo6UE9PTF9GTEFHX0FMR09SSVRITV9MSU5FQVI7DQogICAgcG9vbERlc2MuQmxvY2tTaXplID0gNjQgKiBLSUxPQllURSAqIDMwMDsgLy8gQWxpZ25tZW50IG9mIGJ1ZmZlcnMgaXMgYWx3YXlzIDY0S0INCiAgICBwb29sRGVzYy5NaW5CbG9ja0NvdW50ID0gcG9vbERlc2MuTWF4QmxvY2tDb3VudCA9IDE7DQoNCiAgICBDb21QdHI8RDNEMTJNQTo6UG9vbD4gcG9vbDsNCiAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVQb29sKCZwb29sRGVzYywgJnBvb2wpKTsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgYnVmZkRlc2MgPSB7fTsNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKGJ1ZmZEZXNjLCAwKTsNCg0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuQ3VzdG9tUG9vbCA9IHBvb2wuR2V0KCk7DQoNCiAgICBjb25zdGV4cHIgc2l6ZV90IG1heEJ1ZkNvdW50ID0gMTAwOw0KICAgIHN0cnVjdCBCdWZmZXJJbmZvDQogICAgew0KICAgICAgICBDb21QdHI8SUQzRDEyUmVzb3VyY2U+IEJ1ZmZlcjsNCiAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IEFsbG9jYXRpb247DQogICAgfTsNCiAgICBzdGQ6OnZlY3RvcjxCdWZmZXJJbmZvPiBidWZmSW5mbzsNCg0KICAgIGNvbnN0ZXhwciBVSU5UNjQgYnVmU2l6ZU1pbiA9IDE2Ow0KICAgIGNvbnN0ZXhwciBVSU5UNjQgYnVmU2l6ZU1heCA9IDEwMjQ7DQogICAgVUlOVDY0IHByZXZPZmZzZXQgPSAwOw0KDQogICAgLy8gVGVzdCBvbmUtdGltZSBmcmVlLg0KICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgMjsgKytpKQ0KICAgIHsNCiAgICAgICAgLy8gQWxsb2NhdGUgbnVtYmVyIG9mIGJ1ZmZlcnMgb2YgdmFyeWluZyBzaXplIHRoYXQgc3VyZWx5IGZpdCBpbnRvIHRoaXMgYmxvY2suDQogICAgICAgIFVJTlQ2NCBidWZTdW1TaXplID0gMDsNCiAgICAgICAgVUlOVDY0IGFsbG9jU3VtU2l6ZSA9IDA7DQogICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbWF4QnVmQ291bnQ7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgYnVmZkRlc2MuV2lkdGggPSBBbGlnblVwPFVJTlQ2ND4oYnVmU2l6ZU1pbiArIHJhbmQuR2VuZXJhdGUoKSAlIChidWZTaXplTWF4IC0gYnVmU2l6ZU1pbiksIDE2KTsNCiAgICAgICAgICAgIEJ1ZmZlckluZm8gbmV3QnVmZkluZm87DQogICAgICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmYnVmZkRlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX1ZFUlRFWF9BTkRfQ09OU1RBTlRfQlVGRkVSLA0KICAgICAgICAgICAgICAgIG51bGxwdHIsICZuZXdCdWZmSW5mby5BbGxvY2F0aW9uLCBJSURfUFBWX0FSR1MoJm5ld0J1ZmZJbmZvLkJ1ZmZlcikpKTsNCiAgICAgICAgICAgIGNvbnN0IFVJTlQ2NCBvZmZzZXQgPSBuZXdCdWZmSW5mby5BbGxvY2F0aW9uLT5HZXRPZmZzZXQoKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woaSA9PSAwIHx8IG9mZnNldCA+IHByZXZPZmZzZXQpOw0KICAgICAgICAgICAgcHJldk9mZnNldCA9IG9mZnNldDsNCiAgICAgICAgICAgIGJ1ZlN1bVNpemUgKz0gYnVmZkRlc2MuV2lkdGg7DQogICAgICAgICAgICBhbGxvY1N1bVNpemUgKz0gbmV3QnVmZkluZm8uQWxsb2NhdGlvbi0+R2V0U2l6ZSgpOw0KICAgICAgICAgICAgYnVmZkluZm8ucHVzaF9iYWNrKHN0ZDo6bW92ZShuZXdCdWZmSW5mbykpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gVmFsaWRhdGUgcG9vbCBzdGF0cy4NCiAgICAgICAgRDNEMTJNQTo6RGV0YWlsZWRTdGF0aXN0aWNzIHN0YXRzOw0KICAgICAgICBwb29sLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZzdGF0cyk7DQogICAgICAgIENIRUNLX0JPT0woc3RhdHMuU3RhdHMuQmxvY2tCeXRlcyAtIHN0YXRzLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PSBwb29sRGVzYy5CbG9ja1NpemUgLSBhbGxvY1N1bVNpemUpOw0KICAgICAgICBDSEVDS19CT09MKGFsbG9jU3VtU2l6ZSA+PSBidWZTdW1TaXplKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChzdGF0cy5TdGF0cy5BbGxvY2F0aW9uQ291bnQgPT0gYnVmZkluZm8uc2l6ZSgpKTsNCg0KICAgICAgICAvLyBEZXN0cm95IHRoZSBidWZmZXJzIGluIHJhbmRvbSBvcmRlci4NCiAgICAgICAgd2hpbGUgKCFidWZmSW5mby5lbXB0eSgpKQ0KICAgICAgICB7DQogICAgICAgICAgICBjb25zdCBzaXplX3QgaW5kZXhUb0Rlc3Ryb3kgPSByYW5kLkdlbmVyYXRlKCkgJSBidWZmSW5mby5zaXplKCk7DQogICAgICAgICAgICBidWZmSW5mby5lcmFzZShidWZmSW5mby5iZWdpbigpICsgaW5kZXhUb0Rlc3Ryb3kpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8gVGVzdCBzdGFjay4NCiAgICB7DQogICAgICAgIC8vIEFsbG9jYXRlIG51bWJlciBvZiBidWZmZXJzIG9mIHZhcnlpbmcgc2l6ZSB0aGF0IHN1cmVseSBmaXQgaW50byB0aGlzIGJsb2NrLg0KICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IG1heEJ1ZkNvdW50OyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIGJ1ZmZEZXNjLldpZHRoID0gQWxpZ25VcDxVSU5UNjQ+KGJ1ZlNpemVNaW4gKyByYW5kLkdlbmVyYXRlKCkgJSAoYnVmU2l6ZU1heCAtIGJ1ZlNpemVNaW4pLCAxNik7DQogICAgICAgICAgICBCdWZmZXJJbmZvIG5ld0J1ZmZJbmZvOw0KICAgICAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJmJ1ZmZEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9WRVJURVhfQU5EX0NPTlNUQU5UX0JVRkZFUiwNCiAgICAgICAgICAgICAgICBudWxscHRyLCAmbmV3QnVmZkluZm8uQWxsb2NhdGlvbiwgSUlEX1BQVl9BUkdTKCZuZXdCdWZmSW5mby5CdWZmZXIpKSk7DQogICAgICAgICAgICBjb25zdCBVSU5UNjQgb2Zmc2V0ID0gbmV3QnVmZkluZm8uQWxsb2NhdGlvbi0+R2V0T2Zmc2V0KCk7DQogICAgICAgICAgICBDSEVDS19CT09MKGkgPT0gMCB8fCBvZmZzZXQgPiBwcmV2T2Zmc2V0KTsNCiAgICAgICAgICAgIGJ1ZmZJbmZvLnB1c2hfYmFjayhzdGQ6Om1vdmUobmV3QnVmZkluZm8pKTsNCiAgICAgICAgICAgIHByZXZPZmZzZXQgPSBvZmZzZXQ7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBEZXN0cm95IGZldyBidWZmZXJzIGZyb20gdG9wIG9mIHRoZSBzdGFjay4NCiAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBtYXhCdWZDb3VudCAvIDU7ICsraSkNCiAgICAgICAgICAgIGJ1ZmZJbmZvLnBvcF9iYWNrKCk7DQoNCiAgICAgICAgLy8gQ3JlYXRlIHNvbWUgbW9yZQ0KICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IG1heEJ1ZkNvdW50IC8gNTsgKytpKQ0KICAgICAgICB7DQogICAgICAgICAgICBidWZmRGVzYy5XaWR0aCA9IEFsaWduVXA8VUlOVDY0PihidWZTaXplTWluICsgcmFuZC5HZW5lcmF0ZSgpICUgKGJ1ZlNpemVNYXggLSBidWZTaXplTWluKSwgMTYpOw0KICAgICAgICAgICAgQnVmZmVySW5mbyBuZXdCdWZmSW5mbzsNCiAgICAgICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZidWZmRGVzYywgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfVkVSVEVYX0FORF9DT05TVEFOVF9CVUZGRVIsDQogICAgICAgICAgICAgICAgbnVsbHB0ciwgJm5ld0J1ZmZJbmZvLkFsbG9jYXRpb24sIElJRF9QUFZfQVJHUygmbmV3QnVmZkluZm8uQnVmZmVyKSkpOw0KICAgICAgICAgICAgY29uc3QgVUlOVDY0IG9mZnNldCA9IG5ld0J1ZmZJbmZvLkFsbG9jYXRpb24tPkdldE9mZnNldCgpOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChpID09IDAgfHwgb2Zmc2V0ID4gcHJldk9mZnNldCk7DQogICAgICAgICAgICBidWZmSW5mby5wdXNoX2JhY2soc3RkOjptb3ZlKG5ld0J1ZmZJbmZvKSk7DQogICAgICAgICAgICBwcmV2T2Zmc2V0ID0gb2Zmc2V0Ow0KICAgICAgICB9DQoNCiAgICAgICAgLy8gRGVzdHJveSB0aGUgYnVmZmVycyBpbiByZXZlcnNlIG9yZGVyLg0KICAgICAgICB3aGlsZSAoIWJ1ZmZJbmZvLmVtcHR5KCkpDQogICAgICAgICAgICBidWZmSW5mby5wb3BfYmFjaygpOw0KICAgIH0NCg0KICAgIC8vIFRlc3QgcmluZyBidWZmZXIuDQogICAgew0KICAgICAgICAvLyBBbGxvY2F0ZSBudW1iZXIgb2YgYnVmZmVycyB0aGF0IHN1cmVseSBmaXQgaW50byB0aGlzIGJsb2NrLg0KICAgICAgICBidWZmRGVzYy5XaWR0aCA9IGJ1ZlNpemVNYXg7DQogICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbWF4QnVmQ291bnQ7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgQnVmZmVySW5mbyBuZXdCdWZmSW5mbzsNCiAgICAgICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZidWZmRGVzYywgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfVkVSVEVYX0FORF9DT05TVEFOVF9CVUZGRVIsDQogICAgICAgICAgICAgICAgbnVsbHB0ciwgJm5ld0J1ZmZJbmZvLkFsbG9jYXRpb24sIElJRF9QUFZfQVJHUygmbmV3QnVmZkluZm8uQnVmZmVyKSkpOw0KICAgICAgICAgICAgY29uc3QgVUlOVDY0IG9mZnNldCA9IG5ld0J1ZmZJbmZvLkFsbG9jYXRpb24tPkdldE9mZnNldCgpOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChpID09IDAgfHwgb2Zmc2V0ID4gcHJldk9mZnNldCk7DQogICAgICAgICAgICBidWZmSW5mby5wdXNoX2JhY2soc3RkOjptb3ZlKG5ld0J1ZmZJbmZvKSk7DQogICAgICAgICAgICBwcmV2T2Zmc2V0ID0gb2Zmc2V0Ow0KICAgICAgICB9DQoNCiAgICAgICAgLy8gRnJlZSBhbmQgYWxsb2NhdGUgbmV3IGJ1ZmZlcnMgc28gbWFueSB0aW1lcyB0aGF0IHdlIG1ha2Ugc3VyZSB3ZSB3cmFwLWFyb3VuZCBhdCBsZWFzdCBvbmNlLg0KICAgICAgICBjb25zdCBzaXplX3QgYnVmZmVyc1Blckl0ZXIgPSBtYXhCdWZDb3VudCAvIDEwIC0gMTsNCiAgICAgICAgY29uc3Qgc2l6ZV90IGl0ZXJDb3VudCA9IHBvb2xEZXNjLkJsb2NrU2l6ZSAvIGJ1ZmZEZXNjLldpZHRoIC8gYnVmZmVyc1Blckl0ZXIgKiAyOw0KICAgICAgICBmb3IgKHNpemVfdCBpdGVyID0gMDsgaXRlciA8IGl0ZXJDb3VudDsgKytpdGVyKQ0KICAgICAgICB7DQogICAgICAgICAgICBidWZmSW5mby5lcmFzZShidWZmSW5mby5iZWdpbigpLCBidWZmSW5mby5iZWdpbigpICsgYnVmZmVyc1Blckl0ZXIpOw0KDQogICAgICAgICAgICBmb3IgKHNpemVfdCBidWZQZXJJdGVyID0gMDsgYnVmUGVySXRlciA8IGJ1ZmZlcnNQZXJJdGVyOyArK2J1ZlBlckl0ZXIpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgQnVmZmVySW5mbyBuZXdCdWZmSW5mbzsNCiAgICAgICAgICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmYnVmZkRlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX1ZFUlRFWF9BTkRfQ09OU1RBTlRfQlVGRkVSLA0KICAgICAgICAgICAgICAgICAgICBudWxscHRyLCAmbmV3QnVmZkluZm8uQWxsb2NhdGlvbiwgSUlEX1BQVl9BUkdTKCZuZXdCdWZmSW5mby5CdWZmZXIpKSk7DQogICAgICAgICAgICAgICAgYnVmZkluZm8ucHVzaF9iYWNrKHN0ZDo6bW92ZShuZXdCdWZmSW5mbykpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQWxsb2NhdGUgYnVmZmVycyB1bnRpbCB3ZSByZWFjaCBvdXQtb2YtbWVtb3J5Lg0KICAgICAgICBVSU5UMzIgZGVidWdJbmRleCA9IDA7DQogICAgICAgIHdoaWxlICh0cnVlKQ0KICAgICAgICB7DQogICAgICAgICAgICBCdWZmZXJJbmZvIG5ld0J1ZmZJbmZvOw0KICAgICAgICAgICAgSFJFU1VMVCBociA9IGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZidWZmRGVzYywgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfVkVSVEVYX0FORF9DT05TVEFOVF9CVUZGRVIsDQogICAgICAgICAgICAgICAgbnVsbHB0ciwgJm5ld0J1ZmZJbmZvLkFsbG9jYXRpb24sIElJRF9QUFZfQVJHUygmbmV3QnVmZkluZm8uQnVmZmVyKSk7DQogICAgICAgICAgICArK2RlYnVnSW5kZXg7DQogICAgICAgICAgICBpZiAoU1VDQ0VFREVEKGhyKSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBidWZmSW5mby5wdXNoX2JhY2soc3RkOjptb3ZlKG5ld0J1ZmZJbmZvKSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgQ0hFQ0tfQk9PTChociA9PSBFX09VVE9GTUVNT1JZKTsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIERlc3Ryb3kgdGhlIGJ1ZmZlcnMgaW4gcmFuZG9tIG9yZGVyLg0KICAgICAgICB3aGlsZSAoIWJ1ZmZJbmZvLmVtcHR5KCkpDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbnN0IHNpemVfdCBpbmRleFRvRGVzdHJveSA9IHJhbmQuR2VuZXJhdGUoKSAlIGJ1ZmZJbmZvLnNpemUoKTsNCiAgICAgICAgICAgIGJ1ZmZJbmZvLmVyYXNlKGJ1ZmZJbmZvLmJlZ2luKCkgKyBpbmRleFRvRGVzdHJveSk7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICAvLyBUZXN0IGRvdWJsZSBzdGFjay4NCiAgICB7DQogICAgICAgIC8vIEFsbG9jYXRlIG51bWJlciBvZiBidWZmZXJzIG9mIHZhcnlpbmcgc2l6ZSB0aGF0IHN1cmVseSBmaXQgaW50byB0aGlzIGJsb2NrLCBhbHRlcm5hdGUgZnJvbSBib3R0b20vdG9wLg0KICAgICAgICBVSU5UNjQgcHJldk9mZnNldExvd2VyID0gMDsNCiAgICAgICAgVUlOVDY0IHByZXZPZmZzZXRVcHBlciA9IHBvb2xEZXNjLkJsb2NrU2l6ZTsNCiAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBtYXhCdWZDb3VudDsgKytpKQ0KICAgICAgICB7DQogICAgICAgICAgICBjb25zdCBib29sIHVwcGVyQWRkcmVzcyA9IChpICUgMikgIT0gMDsNCiAgICAgICAgICAgIGlmICh1cHBlckFkZHJlc3MpDQogICAgICAgICAgICAgICAgYWxsb2NEZXNjLkZsYWdzID0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX1VQUEVSX0FERFJFU1M7DQogICAgICAgICAgICBlbHNlDQogICAgICAgICAgICAgICAgYWxsb2NEZXNjLkZsYWdzID0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX05PTkU7DQogICAgICAgICAgICBidWZmRGVzYy5XaWR0aCA9IEFsaWduVXA8VUlOVDY0PihidWZTaXplTWluICsgcmFuZC5HZW5lcmF0ZSgpICUgKGJ1ZlNpemVNYXggLSBidWZTaXplTWluKSwgMTYpOw0KICAgICAgICAgICAgQnVmZmVySW5mbyBuZXdCdWZmSW5mbzsNCiAgICAgICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZidWZmRGVzYywgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfVkVSVEVYX0FORF9DT05TVEFOVF9CVUZGRVIsDQogICAgICAgICAgICAgICAgbnVsbHB0ciwgJm5ld0J1ZmZJbmZvLkFsbG9jYXRpb24sIElJRF9QUFZfQVJHUygmbmV3QnVmZkluZm8uQnVmZmVyKSkpOw0KICAgICAgICAgICAgY29uc3QgVUlOVDY0IG9mZnNldCA9IG5ld0J1ZmZJbmZvLkFsbG9jYXRpb24tPkdldE9mZnNldCgpOw0KICAgICAgICAgICAgaWYgKHVwcGVyQWRkcmVzcykNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBDSEVDS19CT09MKG9mZnNldCA8IHByZXZPZmZzZXRVcHBlcik7DQogICAgICAgICAgICAgICAgcHJldk9mZnNldFVwcGVyID0gb2Zmc2V0Ow0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIENIRUNLX0JPT0wob2Zmc2V0ID49IHByZXZPZmZzZXRMb3dlcik7DQogICAgICAgICAgICAgICAgcHJldk9mZnNldExvd2VyID0gb2Zmc2V0Ow0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChwcmV2T2Zmc2V0TG93ZXIgPCBwcmV2T2Zmc2V0VXBwZXIpOw0KICAgICAgICAgICAgYnVmZkluZm8ucHVzaF9iYWNrKHN0ZDo6bW92ZShuZXdCdWZmSW5mbykpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gRGVzdHJveSBmZXcgYnVmZmVycyBmcm9tIHRvcCBvZiB0aGUgc3RhY2suDQogICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbWF4QnVmQ291bnQgLyA1OyArK2kpDQogICAgICAgICAgICBidWZmSW5mby5wb3BfYmFjaygpOw0KDQogICAgICAgIC8vIENyZWF0ZSBzb21lIG1vcmUNCiAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBtYXhCdWZDb3VudCAvIDU7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgY29uc3QgYm9vbCB1cHBlckFkZHJlc3MgPSAoaSAlIDIpICE9IDA7DQogICAgICAgICAgICBpZiAodXBwZXJBZGRyZXNzKQ0KICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5GbGFncyA9IEQzRDEyTUE6OkFMTE9DQVRJT05fRkxBR19VUFBFUl9BRERSRVNTOw0KICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5GbGFncyA9IEQzRDEyTUE6OkFMTE9DQVRJT05fRkxBR19OT05FOw0KICAgICAgICAgICAgYnVmZkRlc2MuV2lkdGggPSBBbGlnblVwPFVJTlQ2ND4oYnVmU2l6ZU1pbiArIHJhbmQuR2VuZXJhdGUoKSAlIChidWZTaXplTWF4IC0gYnVmU2l6ZU1pbiksIDE2KTsNCiAgICAgICAgICAgIEJ1ZmZlckluZm8gbmV3QnVmZkluZm87DQogICAgICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmYnVmZkRlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX1ZFUlRFWF9BTkRfQ09OU1RBTlRfQlVGRkVSLA0KICAgICAgICAgICAgICAgIG51bGxwdHIsICZuZXdCdWZmSW5mby5BbGxvY2F0aW9uLCBJSURfUFBWX0FSR1MoJm5ld0J1ZmZJbmZvLkJ1ZmZlcikpKTsNCiAgICAgICAgICAgIGJ1ZmZJbmZvLnB1c2hfYmFjayhzdGQ6Om1vdmUobmV3QnVmZkluZm8pKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIERlc3Ryb3kgdGhlIGJ1ZmZlcnMgaW4gcmV2ZXJzZSBvcmRlci4NCiAgICAgICAgd2hpbGUgKCFidWZmSW5mby5lbXB0eSgpKQ0KICAgICAgICAgICAgYnVmZkluZm8ucG9wX2JhY2soKTsNCg0KICAgICAgICAvLyBDcmVhdGUgYnVmZmVycyBvbiBib3RoIHNpZGVzIHVudGlsIHdlIHJlYWNoIG91dCBvZiBtZW1vcnkuDQogICAgICAgIHByZXZPZmZzZXRMb3dlciA9IDA7DQogICAgICAgIHByZXZPZmZzZXRVcHBlciA9IHBvb2xEZXNjLkJsb2NrU2l6ZTsNCiAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IHRydWU7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgY29uc3QgYm9vbCB1cHBlckFkZHJlc3MgPSAoaSAlIDIpICE9IDA7DQogICAgICAgICAgICBpZiAodXBwZXJBZGRyZXNzKQ0KICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5GbGFncyA9IEQzRDEyTUE6OkFMTE9DQVRJT05fRkxBR19VUFBFUl9BRERSRVNTOw0KICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgICAgIGFsbG9jRGVzYy5GbGFncyA9IEQzRDEyTUE6OkFMTE9DQVRJT05fRkxBR19OT05FOw0KICAgICAgICAgICAgYnVmZkRlc2MuV2lkdGggPSBBbGlnblVwPFVJTlQ2ND4oYnVmU2l6ZU1pbiArIHJhbmQuR2VuZXJhdGUoKSAlIChidWZTaXplTWF4IC0gYnVmU2l6ZU1pbiksIDE2KTsNCiAgICAgICAgICAgIEJ1ZmZlckluZm8gbmV3QnVmZkluZm87DQogICAgICAgICAgICBIUkVTVUxUIGhyID0gY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJmJ1ZmZEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9WRVJURVhfQU5EX0NPTlNUQU5UX0JVRkZFUiwNCiAgICAgICAgICAgICAgICBudWxscHRyLCAmbmV3QnVmZkluZm8uQWxsb2NhdGlvbiwgSUlEX1BQVl9BUkdTKCZuZXdCdWZmSW5mby5CdWZmZXIpKTsNCiAgICAgICAgICAgIGlmIChTVUNDRUVERUQoaHIpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGNvbnN0IFVJTlQ2NCBvZmZzZXQgPSBuZXdCdWZmSW5mby5BbGxvY2F0aW9uLT5HZXRPZmZzZXQoKTsNCiAgICAgICAgICAgICAgICBpZiAodXBwZXJBZGRyZXNzKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgQ0hFQ0tfQk9PTChvZmZzZXQgPCBwcmV2T2Zmc2V0VXBwZXIpOw0KICAgICAgICAgICAgICAgICAgICBwcmV2T2Zmc2V0VXBwZXIgPSBvZmZzZXQ7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIENIRUNLX0JPT0wob2Zmc2V0ID49IHByZXZPZmZzZXRMb3dlcik7DQogICAgICAgICAgICAgICAgICAgIHByZXZPZmZzZXRMb3dlciA9IG9mZnNldDsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgQ0hFQ0tfQk9PTChwcmV2T2Zmc2V0TG93ZXIgPCBwcmV2T2Zmc2V0VXBwZXIpOw0KICAgICAgICAgICAgICAgIGJ1ZmZJbmZvLnB1c2hfYmFjayhzdGQ6Om1vdmUobmV3QnVmZkluZm8pKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIERlc3Ryb3kgdGhlIGJ1ZmZlcnMgaW4gcmFuZG9tIG9yZGVyLg0KICAgICAgICB3aGlsZSAoIWJ1ZmZJbmZvLmVtcHR5KCkpDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbnN0IHNpemVfdCBpbmRleFRvRGVzdHJveSA9IHJhbmQuR2VuZXJhdGUoKSAlIGJ1ZmZJbmZvLnNpemUoKTsNCiAgICAgICAgICAgIGJ1ZmZJbmZvLmVyYXNlKGJ1ZmZJbmZvLmJlZ2luKCkgKyBpbmRleFRvRGVzdHJveSk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDcmVhdGUgYnVmZmVycyBvbiB1cHBlciBzaWRlIG9ubHksIGNvbnN0YW50IHNpemUsIHVudGlsIHdlIHJlYWNoIG91dCBvZiBtZW1vcnkuDQogICAgICAgIHByZXZPZmZzZXRVcHBlciA9IHBvb2xEZXNjLkJsb2NrU2l6ZTsNCiAgICAgICAgYWxsb2NEZXNjLkZsYWdzID0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX1VQUEVSX0FERFJFU1M7DQogICAgICAgIGJ1ZmZEZXNjLldpZHRoID0gYnVmU2l6ZU1heDsNCiAgICAgICAgd2hpbGUgKHRydWUpDQogICAgICAgIHsNCiAgICAgICAgICAgIEJ1ZmZlckluZm8gbmV3QnVmZkluZm87DQogICAgICAgICAgICBIUkVTVUxUIGhyID0gY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJmJ1ZmZEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9WRVJURVhfQU5EX0NPTlNUQU5UX0JVRkZFUiwNCiAgICAgICAgICAgICAgICBudWxscHRyLCAmbmV3QnVmZkluZm8uQWxsb2NhdGlvbiwgSUlEX1BQVl9BUkdTKCZuZXdCdWZmSW5mby5CdWZmZXIpKTsNCiAgICAgICAgICAgIGlmIChTVUNDRUVERUQoaHIpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGNvbnN0IFVJTlQ2NCBvZmZzZXQgPSBuZXdCdWZmSW5mby5BbGxvY2F0aW9uLT5HZXRPZmZzZXQoKTsNCiAgICAgICAgICAgICAgICBDSEVDS19CT09MKG9mZnNldCA8IHByZXZPZmZzZXRVcHBlcik7DQogICAgICAgICAgICAgICAgcHJldk9mZnNldFVwcGVyID0gb2Zmc2V0Ow0KICAgICAgICAgICAgICAgIGJ1ZmZJbmZvLnB1c2hfYmFjayhzdGQ6Om1vdmUobmV3QnVmZkluZm8pKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIERlc3Ryb3kgdGhlIGJ1ZmZlcnMgaW4gcmV2ZXJzZSBvcmRlci4NCiAgICAgICAgd2hpbGUgKCFidWZmSW5mby5lbXB0eSgpKQ0KICAgICAgICB7DQogICAgICAgICAgICBjb25zdCBCdWZmZXJJbmZvJiBjdXJyQnVmSW5mbyA9IGJ1ZmZJbmZvLmJhY2soKTsNCiAgICAgICAgICAgIGJ1ZmZJbmZvLnBvcF9iYWNrKCk7DQogICAgICAgIH0NCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RMaW5lYXJBbGxvY2F0b3JNdWx0aUJsb2NrKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgbGluZWFyIGFsbG9jYXRvciBtdWx0aSBibG9ja1xuIik7DQoNCiAgICBSYW5kb21OdW1iZXJHZW5lcmF0b3IgcmFuZHsgMzQ1NjczIH07DQoNCiAgICBEM0QxMk1BOjpQT09MX0RFU0MgcG9vbERlc2MgPSB7fTsNCiAgICBwb29sRGVzYy5IZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9CVUZGRVJTOw0KICAgIHBvb2xEZXNjLkhlYXBQcm9wZXJ0aWVzLlR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICBwb29sRGVzYy5GbGFncyA9IEQzRDEyTUE6OlBPT0xfRkxBR19BTEdPUklUSE1fTElORUFSOw0KDQogICAgQ29tUHRyPEQzRDEyTUE6OlBvb2w+IHBvb2w7DQogICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUG9vbCgmcG9vbERlc2MsICZwb29sKSk7DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIGJ1ZmZEZXNjID0ge307DQogICAgRmlsbFJlc291cmNlRGVzY0ZvckJ1ZmZlcihidWZmRGVzYywgMTAyNCAqIDEwMjQpOw0KDQogICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gcG9vbC5HZXQoKTsNCg0KICAgIHN0cnVjdCBCdWZmZXJJbmZvDQogICAgew0KICAgICAgICBDb21QdHI8SUQzRDEyUmVzb3VyY2U+IEJ1ZmZlcjsNCiAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IEFsbG9jYXRpb247DQogICAgfTsNCiAgICBzdGQ6OnZlY3RvcjxCdWZmZXJJbmZvPiBidWZmSW5mbzsNCg0KICAgIC8vIFRlc3Qgb25lLXRpbWUgZnJlZS4NCiAgICB7DQogICAgICAgIC8vIEFsbG9jYXRlIGJ1ZmZlcnMgdW50aWwgd2UgbW92ZSB0byBhIHNlY29uZCBibG9jay4NCiAgICAgICAgSUQzRDEySGVhcCogbGFzdEhlYXAgPSBudWxscHRyOw0KICAgICAgICB3aGlsZSAodHJ1ZSkNCiAgICAgICAgew0KICAgICAgICAgICAgQnVmZmVySW5mbyBuZXdCdWZmSW5mbzsNCiAgICAgICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZidWZmRGVzYywgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfVkVSVEVYX0FORF9DT05TVEFOVF9CVUZGRVIsDQogICAgICAgICAgICAgICAgbnVsbHB0ciwgJm5ld0J1ZmZJbmZvLkFsbG9jYXRpb24sIElJRF9QUFZfQVJHUygmbmV3QnVmZkluZm8uQnVmZmVyKSkpOw0KICAgICAgICAgICAgSUQzRDEySGVhcCogaGVhcCA9IG5ld0J1ZmZJbmZvLkFsbG9jYXRpb24tPkdldEhlYXAoKTsNCiAgICAgICAgICAgIGJ1ZmZJbmZvLnB1c2hfYmFjayhzdGQ6Om1vdmUobmV3QnVmZkluZm8pKTsNCiAgICAgICAgICAgIGlmIChsYXN0SGVhcCAmJiBoZWFwICE9IGxhc3RIZWFwKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgbGFzdEhlYXAgPSBoZWFwOw0KICAgICAgICB9DQogICAgICAgIENIRUNLX0JPT0woYnVmZkluZm8uc2l6ZSgpID4gMik7DQoNCiAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgcG9vbCBoYXMgbm93IHR3byBibG9ja3MuDQogICAgICAgIEQzRDEyTUE6OkRldGFpbGVkU3RhdGlzdGljcyBwb29sU3RhdHMgPSB7fTsNCiAgICAgICAgcG9vbC0+Q2FsY3VsYXRlU3RhdGlzdGljcygmcG9vbFN0YXRzKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChwb29sU3RhdHMuU3RhdHMuQmxvY2tDb3VudCA9PSAyKTsNCg0KICAgICAgICAvLyBEZXN0cm95IGFsbCB0aGUgYnVmZmVycyBpbiByYW5kb20gb3JkZXIuDQogICAgICAgIHdoaWxlICghYnVmZkluZm8uZW1wdHkoKSkNCiAgICAgICAgew0KICAgICAgICAgICAgY29uc3Qgc2l6ZV90IGluZGV4VG9EZXN0cm95ID0gcmFuZC5HZW5lcmF0ZSgpICUgYnVmZkluZm8uc2l6ZSgpOw0KICAgICAgICAgICAgYnVmZkluZm8uZXJhc2UoYnVmZkluZm8uYmVnaW4oKSArIGluZGV4VG9EZXN0cm95KTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHBvb2wgaGFzIG5vdyBhdCBtb3N0IG9uZSBibG9jay4NCiAgICAgICAgcG9vbC0+Q2FsY3VsYXRlU3RhdGlzdGljcygmcG9vbFN0YXRzKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChwb29sU3RhdHMuU3RhdHMuQmxvY2tDb3VudCA8PSAxKTsNCiAgICB9DQoNCiAgICAvLyBUZXN0IHN0YWNrLg0KICAgIHsNCiAgICAgICAgLy8gQWxsb2NhdGUgYnVmZmVycyB1bnRpbCB3ZSBtb3ZlIHRvIGEgc2Vjb25kIGJsb2NrLg0KICAgICAgICBJRDNEMTJIZWFwKiBsYXN0SGVhcCA9IG51bGxwdHI7DQogICAgICAgIHdoaWxlICh0cnVlKQ0KICAgICAgICB7DQogICAgICAgICAgICBCdWZmZXJJbmZvIG5ld0J1ZmZJbmZvOw0KICAgICAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJmJ1ZmZEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9WRVJURVhfQU5EX0NPTlNUQU5UX0JVRkZFUiwNCiAgICAgICAgICAgICAgICBudWxscHRyLCAmbmV3QnVmZkluZm8uQWxsb2NhdGlvbiwgSUlEX1BQVl9BUkdTKCZuZXdCdWZmSW5mby5CdWZmZXIpKSk7DQogICAgICAgICAgICBJRDNEMTJIZWFwKiBoZWFwID0gbmV3QnVmZkluZm8uQWxsb2NhdGlvbi0+R2V0SGVhcCgpOw0KICAgICAgICAgICAgYnVmZkluZm8ucHVzaF9iYWNrKHN0ZDo6bW92ZShuZXdCdWZmSW5mbykpOw0KICAgICAgICAgICAgaWYgKGxhc3RIZWFwICYmIGhlYXAgIT0gbGFzdEhlYXApDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBsYXN0SGVhcCA9IGhlYXA7DQogICAgICAgIH0NCiAgICAgICAgQ0hFQ0tfQk9PTChidWZmSW5mby5zaXplKCkgPiAyKTsNCg0KICAgICAgICAvLyBBZGQgZmV3IG1vcmUgYnVmZmVycy4NCiAgICAgICAgZm9yIChVSU5UMzIgaSA9IDA7IGkgPCA1OyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIEJ1ZmZlckluZm8gbmV3QnVmZkluZm87DQogICAgICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmYnVmZkRlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX1ZFUlRFWF9BTkRfQ09OU1RBTlRfQlVGRkVSLA0KICAgICAgICAgICAgICAgIG51bGxwdHIsICZuZXdCdWZmSW5mby5BbGxvY2F0aW9uLCBJSURfUFBWX0FSR1MoJm5ld0J1ZmZJbmZvLkJ1ZmZlcikpKTsNCiAgICAgICAgICAgIGJ1ZmZJbmZvLnB1c2hfYmFjayhzdGQ6Om1vdmUobmV3QnVmZkluZm8pKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHBvb2wgaGFzIG5vdyB0d28gYmxvY2tzLg0KICAgICAgICBEM0QxMk1BOjpEZXRhaWxlZFN0YXRpc3RpY3MgcG9vbFN0YXRzID0ge307DQogICAgICAgIHBvb2wtPkNhbGN1bGF0ZVN0YXRpc3RpY3MoJnBvb2xTdGF0cyk7DQogICAgICAgIENIRUNLX0JPT0wocG9vbFN0YXRzLlN0YXRzLkJsb2NrQ291bnQgPT0gMik7DQoNCiAgICAgICAgLy8gRGVsZXRlIGhhbGYgb2YgYnVmZmVycywgTElGTy4NCiAgICAgICAgZm9yIChzaXplX3QgaSA9IDAsIGNvdW50VG9EZWxldGUgPSBidWZmSW5mby5zaXplKCkgLyAyOyBpIDwgY291bnRUb0RlbGV0ZTsgKytpKQ0KICAgICAgICAgICAgYnVmZkluZm8ucG9wX2JhY2soKTsNCg0KICAgICAgICAvLyBBZGQgb25lIG1vcmUgYnVmZmVyLg0KICAgICAgICBCdWZmZXJJbmZvIG5ld0J1ZmZJbmZvOw0KICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmYnVmZkRlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX1ZFUlRFWF9BTkRfQ09OU1RBTlRfQlVGRkVSLA0KICAgICAgICAgICAgbnVsbHB0ciwgJm5ld0J1ZmZJbmZvLkFsbG9jYXRpb24sIElJRF9QUFZfQVJHUygmbmV3QnVmZkluZm8uQnVmZmVyKSkpOw0KICAgICAgICBidWZmSW5mby5wdXNoX2JhY2soc3RkOjptb3ZlKG5ld0J1ZmZJbmZvKSk7DQoNCiAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgcG9vbCBoYXMgbm93IG9uZSBibG9jay4NCiAgICAgICAgcG9vbC0+Q2FsY3VsYXRlU3RhdGlzdGljcygmcG9vbFN0YXRzKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChwb29sU3RhdHMuU3RhdHMuQmxvY2tDb3VudCA9PSAxKTsNCg0KICAgICAgICAvLyBEZWxldGUgYWxsIHRoZSByZW1haW5pbmcgYnVmZmVycywgTElGTy4NCiAgICAgICAgd2hpbGUgKCFidWZmSW5mby5lbXB0eSgpKQ0KICAgICAgICAgICAgYnVmZkluZm8ucG9wX2JhY2soKTsNCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIE1hbnVhbGx5VGVzdExpbmVhckFsbG9jYXRvcihjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJNYW51YWxseSB0ZXN0IGxpbmVhciBhbGxvY2F0b3JcbiIpOw0KDQogICAgUmFuZG9tTnVtYmVyR2VuZXJhdG9yIHJhbmR7IDY0NTMzMiB9Ow0KDQogICAgRDNEMTJNQTo6VG90YWxTdGF0aXN0aWNzIG9yaWdTdGF0czsNCiAgICBjdHguYWxsb2NhdG9yLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZvcmlnU3RhdHMpOw0KDQogICAgRDNEMTJNQTo6UE9PTF9ERVNDIHBvb2xEZXNjID0ge307DQogICAgcG9vbERlc2MuSGVhcEZsYWdzID0gRDNEMTJfSEVBUF9GTEFHX0FMTE9XX09OTFlfQlVGRkVSUzsNCiAgICBwb29sRGVzYy5IZWFwUHJvcGVydGllcy5UeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQogICAgcG9vbERlc2MuRmxhZ3MgPSBEM0QxMk1BOjpQT09MX0ZMQUdfQUxHT1JJVEhNX0xJTkVBUjsNCiAgICBwb29sRGVzYy5CbG9ja1NpemUgPSA2ICogNjQgKiBLSUxPQllURTsNCiAgICBwb29sRGVzYy5NaW5CbG9ja0NvdW50ID0gcG9vbERlc2MuTWF4QmxvY2tDb3VudCA9IDE7DQoNCiAgICBDb21QdHI8RDNEMTJNQTo6UG9vbD4gcG9vbDsNCiAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVQb29sKCZwb29sRGVzYywgJnBvb2wpKTsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgYnVmZkRlc2MgPSB7fTsNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKGJ1ZmZEZXNjLCAwKTsNCg0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuQ3VzdG9tUG9vbCA9IHBvb2wuR2V0KCk7DQoNCiAgICBzdHJ1Y3QgQnVmZmVySW5mbw0KICAgIHsNCiAgICAgICAgQ29tUHRyPElEM0QxMlJlc291cmNlPiBCdWZmZXI7DQogICAgICAgIENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiBBbGxvY2F0aW9uOw0KICAgIH07DQogICAgc3RkOjp2ZWN0b3I8QnVmZmVySW5mbz4gYnVmZkluZm87DQogICAgQnVmZmVySW5mbyBuZXdCdWZmSW5mbzsNCg0KICAgIC8vIFRlc3QgZG91YmxlIHN0YWNrLg0KICAgIHsNCiAgICAgICAgLyoNCiAgICAgICAgTG93ZXI6IEJ1ZmZlciAzMiBCLCBCdWZmZXIgMTAyNCBCLCBCdWZmZXIgMzIgQg0KICAgICAgICBVcHBlcjogQnVmZmVyIDE2IEIsIEJ1ZmZlciAxMDI0IEIsIEJ1ZmZlciAxMjggQg0KDQogICAgICAgIFRvdGFsbHk6DQogICAgICAgIDEgYmxvY2sgYWxsb2NhdGVkDQogICAgICAgIDM5M6AyMTYgRGlyZWN0WCAxMiBieXRlcw0KICAgICAgICA2IG5ldyBhbGxvY2F0aW9ucw0KICAgICAgICAyMjU2IGJ5dGVzIGluIGFsbG9jYXRpb25zICgzODQgS0IgYWNjb3JkaW5nIHRvIGFsaWdubWVudCkNCiAgICAgICAgKi8NCg0KICAgICAgICBidWZmRGVzYy5XaWR0aCA9IDMyOw0KICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmYnVmZkRlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX1ZFUlRFWF9BTkRfQ09OU1RBTlRfQlVGRkVSLA0KICAgICAgICAgICAgbnVsbHB0ciwgJm5ld0J1ZmZJbmZvLkFsbG9jYXRpb24sIElJRF9QUFZfQVJHUygmbmV3QnVmZkluZm8uQnVmZmVyKSkpOw0KICAgICAgICBidWZmSW5mby5wdXNoX2JhY2soc3RkOjptb3ZlKG5ld0J1ZmZJbmZvKSk7DQoNCiAgICAgICAgYnVmZkRlc2MuV2lkdGggPSAxMDI0Ow0KICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmYnVmZkRlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX1ZFUlRFWF9BTkRfQ09OU1RBTlRfQlVGRkVSLA0KICAgICAgICAgICAgbnVsbHB0ciwgJm5ld0J1ZmZJbmZvLkFsbG9jYXRpb24sIElJRF9QUFZfQVJHUygmbmV3QnVmZkluZm8uQnVmZmVyKSkpOw0KICAgICAgICBidWZmSW5mby5wdXNoX2JhY2soc3RkOjptb3ZlKG5ld0J1ZmZJbmZvKSk7DQoNCiAgICAgICAgYnVmZkRlc2MuV2lkdGggPSAzMjsNCiAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJmJ1ZmZEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9WRVJURVhfQU5EX0NPTlNUQU5UX0JVRkZFUiwNCiAgICAgICAgICAgIG51bGxwdHIsICZuZXdCdWZmSW5mby5BbGxvY2F0aW9uLCBJSURfUFBWX0FSR1MoJm5ld0J1ZmZJbmZvLkJ1ZmZlcikpKTsNCiAgICAgICAgYnVmZkluZm8ucHVzaF9iYWNrKHN0ZDo6bW92ZShuZXdCdWZmSW5mbykpOw0KDQogICAgICAgIGFsbG9jRGVzYy5GbGFncyB8PSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfVVBQRVJfQUREUkVTUzsNCg0KICAgICAgICBidWZmRGVzYy5XaWR0aCA9IDEyODsNCiAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJmJ1ZmZEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9WRVJURVhfQU5EX0NPTlNUQU5UX0JVRkZFUiwNCiAgICAgICAgICAgIG51bGxwdHIsICZuZXdCdWZmSW5mby5BbGxvY2F0aW9uLCBJSURfUFBWX0FSR1MoJm5ld0J1ZmZJbmZvLkJ1ZmZlcikpKTsNCiAgICAgICAgYnVmZkluZm8ucHVzaF9iYWNrKHN0ZDo6bW92ZShuZXdCdWZmSW5mbykpOw0KDQogICAgICAgIGJ1ZmZEZXNjLldpZHRoID0gMTAyNDsNCiAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJmJ1ZmZEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9WRVJURVhfQU5EX0NPTlNUQU5UX0JVRkZFUiwNCiAgICAgICAgICAgIG51bGxwdHIsICZuZXdCdWZmSW5mby5BbGxvY2F0aW9uLCBJSURfUFBWX0FSR1MoJm5ld0J1ZmZJbmZvLkJ1ZmZlcikpKTsNCiAgICAgICAgYnVmZkluZm8ucHVzaF9iYWNrKHN0ZDo6bW92ZShuZXdCdWZmSW5mbykpOw0KDQogICAgICAgIGJ1ZmZEZXNjLldpZHRoID0gMTY7DQogICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZidWZmRGVzYywgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfVkVSVEVYX0FORF9DT05TVEFOVF9CVUZGRVIsDQogICAgICAgICAgICBudWxscHRyLCAmbmV3QnVmZkluZm8uQWxsb2NhdGlvbiwgSUlEX1BQVl9BUkdTKCZuZXdCdWZmSW5mby5CdWZmZXIpKSk7DQogICAgICAgIGJ1ZmZJbmZvLnB1c2hfYmFjayhzdGQ6Om1vdmUobmV3QnVmZkluZm8pKTsNCg0KICAgICAgICBEM0QxMk1BOjpUb3RhbFN0YXRpc3RpY3MgY3VyclN0YXRzOw0KICAgICAgICBjdHguYWxsb2NhdG9yLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZjdXJyU3RhdHMpOw0KICAgICAgICBEM0QxMk1BOjpEZXRhaWxlZFN0YXRpc3RpY3MgcG9vbFN0YXRzOw0KICAgICAgICBwb29sLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZwb29sU3RhdHMpOw0KDQogICAgICAgIFdDSEFSKiBzdGF0c1N0ciA9IG51bGxwdHI7DQogICAgICAgIGN0eC5hbGxvY2F0b3ItPkJ1aWxkU3RhdHNTdHJpbmcoJnN0YXRzU3RyLCBGQUxTRSk7DQoNCiAgICAgICAgLy8gUFVUIEJSRUFLUE9JTlQgSEVSRSBUTyBDSEVDSy4NCiAgICAgICAgLy8gSW5zcGVjdDogY3VyclN0YXRzIHZlcnN1cyBvcmlnU3RhdHMsIHBvb2xTdGF0cywgc3RhdHNTdHIuDQogICAgICAgIGludCBJID0gMDsNCg0KICAgICAgICBjdHguYWxsb2NhdG9yLT5GcmVlU3RhdHNTdHJpbmcoc3RhdHNTdHIpOw0KDQogICAgICAgIC8vIERlc3Ryb3kgdGhlIGJ1ZmZlcnMgaW4gcmV2ZXJzZSBvcmRlci4NCiAgICAgICAgd2hpbGUgKCFidWZmSW5mby5lbXB0eSgpKQ0KICAgICAgICAgICAgYnVmZkluZm8ucG9wX2JhY2soKTsNCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIEJlbmNobWFya0FsZ29yaXRobXNDYXNlKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgsDQogICAgRklMRSogZmlsZSwNCiAgICBEM0QxMk1BOjpQT09MX0ZMQUdTIGFsZ29yaXRobSwNCiAgICBib29sIGVtcHR5LA0KICAgIEZSRUVfT1JERVIgZnJlZU9yZGVyKQ0Kew0KICAgIFJhbmRvbU51bWJlckdlbmVyYXRvciByYW5keyAxNjIyMyB9Ow0KDQogICAgY29uc3QgVUlOVDY0IGJ1ZlNpemUgPSBEM0QxMl9ERUZBVUxUX1JFU09VUkNFX1BMQUNFTUVOVF9BTElHTk1FTlQ7DQogICAgY29uc3Qgc2l6ZV90IG1heEJ1ZkNhcGFjaXR5ID0gMTAwMDA7DQogICAgY29uc3QgVUlOVDMyIGl0ZXJhdGlvbkNvdW50ID0gMTA7DQoNCiAgICBEM0QxMk1BOjpQT09MX0RFU0MgcG9vbERlc2MgPSB7fTsNCiAgICBwb29sRGVzYy5IZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9CVUZGRVJTOw0KICAgIHBvb2xEZXNjLkhlYXBQcm9wZXJ0aWVzLlR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICBwb29sRGVzYy5CbG9ja1NpemUgPSBidWZTaXplICogbWF4QnVmQ2FwYWNpdHk7DQogICAgcG9vbERlc2MuRmxhZ3MgfD0gYWxnb3JpdGhtOw0KICAgIHBvb2xEZXNjLk1pbkJsb2NrQ291bnQgPSBwb29sRGVzYy5NYXhCbG9ja0NvdW50ID0gMTsNCg0KICAgIENvbVB0cjxEM0QxMk1BOjpQb29sPiBwb29sOw0KICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVBvb2woJnBvb2xEZXNjLCAmcG9vbCkpOw0KDQogICAgRDNEMTJfUkVTT1VSQ0VfQUxMT0NBVElPTl9JTkZPIGFsbG9jSW5mbyA9IHt9Ow0KICAgIGFsbG9jSW5mby5TaXplSW5CeXRlcyA9IGJ1ZlNpemU7DQoNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgYWxsb2NEZXNjLkN1c3RvbVBvb2wgPSBwb29sLkdldCgpOw0KDQogICAgc3RkOjp2ZWN0b3I8Q29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+PiBiYXNlQWxsb2NhdGlvbnM7DQogICAgY29uc3Qgc2l6ZV90IGFsbG9jQ291bnQgPSBtYXhCdWZDYXBhY2l0eSAvIDM7DQogICAgaWYgKCFlbXB0eSkNCiAgICB7DQogICAgICAgIC8vIE1ha2UgYWxsb2NhdGlvbnMgdXAgdG8gMS8zIG9mIHBvb2wgc2l6ZS4NCiAgICAgICAgZm9yIChVSU5UNjQgaSA9IDA7IGkgPCBhbGxvY0NvdW50OyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiBhbGxvYzsNCiAgICAgICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkFsbG9jYXRlTWVtb3J5KCZhbGxvY0Rlc2MsICZhbGxvY0luZm8sICZhbGxvYykpOw0KICAgICAgICAgICAgYmFzZUFsbG9jYXRpb25zLnB1c2hfYmFjayhzdGQ6Om1vdmUoYWxsb2MpKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIERlbGV0ZSBoYWxmIG9mIHRoZW0sIGNob29zZSByYW5kb21seS4NCiAgICAgICAgc2l6ZV90IGFsbG9jc1RvRGVsZXRlID0gYmFzZUFsbG9jYXRpb25zLnNpemUoKSAvIDI7DQogICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgYWxsb2NzVG9EZWxldGU7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgY29uc3Qgc2l6ZV90IGluZGV4ID0gKHNpemVfdClyYW5kLkdlbmVyYXRlKCkgJSBiYXNlQWxsb2NhdGlvbnMuc2l6ZSgpOw0KICAgICAgICAgICAgYmFzZUFsbG9jYXRpb25zLmVyYXNlKGJhc2VBbGxvY2F0aW9ucy5iZWdpbigpICsgaW5kZXgpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8gQkVOQ0hNQVJLDQogICAgc3RkOjp2ZWN0b3I8Q29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+PiB0ZXN0QWxsb2NhdGlvbnM7DQogICAgZHVyYXRpb24gYWxsb2NUb3RhbER1cmF0aW9uID0gZHVyYXRpb246Onplcm8oKTsNCiAgICBkdXJhdGlvbiBmcmVlVG90YWxEdXJhdGlvbiA9IGR1cmF0aW9uOjp6ZXJvKCk7DQogICAgZm9yICh1aW50MzJfdCBpdGVyYXRpb25JbmRleCA9IDA7IGl0ZXJhdGlvbkluZGV4IDwgaXRlcmF0aW9uQ291bnQ7ICsraXRlcmF0aW9uSW5kZXgpDQogICAgew0KICAgICAgICB0ZXN0QWxsb2NhdGlvbnMucmVzZXJ2ZShhbGxvY0NvdW50KTsNCiAgICAgICAgLy8gQWxsb2NhdGlvbnMNCiAgICAgICAgdGltZV9wb2ludCBhbGxvY1RpbWVCZWcgPSBzdGQ6OmNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsNCiAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBhbGxvY0NvdW50OyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiBhbGxvYzsNCiAgICAgICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkFsbG9jYXRlTWVtb3J5KCZhbGxvY0Rlc2MsICZhbGxvY0luZm8sICZhbGxvYykpOw0KICAgICAgICAgICAgdGVzdEFsbG9jYXRpb25zLnB1c2hfYmFjayhzdGQ6Om1vdmUoYWxsb2MpKTsNCiAgICAgICAgfQ0KICAgICAgICBhbGxvY1RvdGFsRHVyYXRpb24gKz0gc3RkOjpjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCkgLSBhbGxvY1RpbWVCZWc7DQoNCiAgICAgICAgLy8gRGVhbGxvY2F0aW9ucw0KICAgICAgICBzd2l0Y2ggKGZyZWVPcmRlcikNCiAgICAgICAgew0KICAgICAgICBjYXNlIEZSRUVfT1JERVI6OkZPUldBUkQ6DQogICAgICAgICAgICAvLyBMZWF2ZSB0ZXN0QWxsb2NhdGlvbnMgdW5jaGFuZ2VkLg0KICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIGNhc2UgRlJFRV9PUkRFUjo6QkFDS1dBUkQ6DQogICAgICAgICAgICBzdGQ6OnJldmVyc2UodGVzdEFsbG9jYXRpb25zLmJlZ2luKCksIHRlc3RBbGxvY2F0aW9ucy5lbmQoKSk7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgY2FzZSBGUkVFX09SREVSOjpSQU5ET006DQogICAgICAgICAgICBzdGQ6OnNodWZmbGUodGVzdEFsbG9jYXRpb25zLmJlZ2luKCksIHRlc3RBbGxvY2F0aW9ucy5lbmQoKSwgTXlVbmlmb3JtUmFuZG9tTnVtYmVyR2VuZXJhdG9yKHJhbmQpKTsNCiAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICBkZWZhdWx0OiBhc3NlcnQoMCk7DQogICAgICAgIH0NCg0KICAgICAgICB0aW1lX3BvaW50IGZyZWVUaW1lQmVnID0gc3RkOjpjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCk7DQogICAgICAgIHRlc3RBbGxvY2F0aW9ucy5jbGVhcigpOw0KICAgICAgICBmcmVlVG90YWxEdXJhdGlvbiArPSBzdGQ6OmNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKSAtIGZyZWVUaW1lQmVnOw0KDQogICAgfQ0KDQogICAgLy8gRGVsZXRlIGJhc2VBbGxvY2F0aW9ucw0KICAgIGJhc2VBbGxvY2F0aW9ucy5jbGVhcigpOw0KDQogICAgY29uc3QgZmxvYXQgYWxsb2NUb3RhbFNlY29uZHMgPSBUb0Zsb2F0U2Vjb25kcyhhbGxvY1RvdGFsRHVyYXRpb24pOw0KICAgIGNvbnN0IGZsb2F0IGZyZWVUb3RhbFNlY29uZHMgPSBUb0Zsb2F0U2Vjb25kcyhmcmVlVG90YWxEdXJhdGlvbik7DQoNCiAgICBwcmludGYoIiAgICBBbGdvcml0aG09JXMgJXMgRnJlZU9yZGVyPSVzOiBhbGxvY2F0aW9ucyAlZyBzLCBmcmVlICVnIHNcbiIsDQogICAgICAgIEFsZ29yaXRobVRvU3RyKGFsZ29yaXRobSksDQogICAgICAgIGVtcHR5ID8gIkVtcHR5IiA6ICJOb3QgZW1wdHkiLA0KICAgICAgICBGUkVFX09SREVSX05BTUVTWyhzaXplX3QpZnJlZU9yZGVyXSwNCiAgICAgICAgYWxsb2NUb3RhbFNlY29uZHMsDQogICAgICAgIGZyZWVUb3RhbFNlY29uZHMpOw0KDQogICAgaWYgKGZpbGUpDQogICAgew0KICAgICAgICBzdGQ6OnN0cmluZyBjdXJyVGltZTsNCiAgICAgICAgQ3VycmVudFRpbWVUb1N0cihjdXJyVGltZSk7DQoNCiAgICAgICAgZnByaW50ZihmaWxlLCAiJXMsJXMsJXMsJXUsJXMsJWcsJWdcbiIsDQogICAgICAgICAgICBDT0RFX0RFU0NSSVBUSU9OLCBjdXJyVGltZS5jX3N0cigpLA0KICAgICAgICAgICAgQWxnb3JpdGhtVG9TdHIoYWxnb3JpdGhtKSwNCiAgICAgICAgICAgIGVtcHR5ID8gMSA6IDAsDQogICAgICAgICAgICBGUkVFX09SREVSX05BTUVTWyh1aW50MzJfdClmcmVlT3JkZXJdLA0KICAgICAgICAgICAgYWxsb2NUb3RhbFNlY29uZHMsDQogICAgICAgICAgICBmcmVlVG90YWxTZWNvbmRzKTsNCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIEJlbmNobWFya0FsZ29yaXRobXMoY29uc3QgVGVzdENvbnRleHQmIGN0eCwgRklMRSogZmlsZSkNCnsNCiAgICB3cHJpbnRmKEwiQmVuY2htYXJrIGFsZ29yaXRobXNcbiIpOw0KDQogICAgaWYgKGZpbGUpDQogICAgew0KICAgICAgICBmcHJpbnRmKGZpbGUsDQogICAgICAgICAgICAiQ29kZSxUaW1lLCINCiAgICAgICAgICAgICJBbGdvcml0aG0sRW1wdHksRnJlZSBvcmRlciwiDQogICAgICAgICAgICAiQWxsb2NhdGlvbiB0aW1lIChzKSxEZWFsbG9jYXRpb24gdGltZSAocylcbiIpOw0KICAgIH0NCg0KICAgIFVJTlQzMiBmcmVlT3JkZXJDb3VudCA9IDE7DQogICAgaWYgKENvbmZpZ1R5cGUgPj0gQ09ORklHX1RZUEU6OkNPTkZJR19UWVBFX0xBUkdFKQ0KICAgICAgICBmcmVlT3JkZXJDb3VudCA9IDM7DQogICAgZWxzZSBpZiAoQ29uZmlnVHlwZSA+PSBDT05GSUdfVFlQRTo6Q09ORklHX1RZUEVfU01BTEwpDQogICAgICAgIGZyZWVPcmRlckNvdW50ID0gMjsNCg0KICAgIGNvbnN0IFVJTlQzMiBlbXB0eUNvdW50ID0gQ29uZmlnVHlwZSA+PSBDT05GSUdfVFlQRTo6Q09ORklHX1RZUEVfU01BTEwgPyAyIDogMTsNCg0KICAgIGZvciAoVUlOVDMyIGZyZWVPcmRlckluZGV4ID0gMDsgZnJlZU9yZGVySW5kZXggPCBmcmVlT3JkZXJDb3VudDsgKytmcmVlT3JkZXJJbmRleCkNCiAgICB7DQogICAgICAgIEZSRUVfT1JERVIgZnJlZU9yZGVyID0gRlJFRV9PUkRFUjo6Q09VTlQ7DQogICAgICAgIHN3aXRjaCAoZnJlZU9yZGVySW5kZXgpDQogICAgICAgIHsNCiAgICAgICAgY2FzZSAwOiBmcmVlT3JkZXIgPSBGUkVFX09SREVSOjpCQUNLV0FSRDsgYnJlYWs7DQogICAgICAgIGNhc2UgMTogZnJlZU9yZGVyID0gRlJFRV9PUkRFUjo6Rk9SV0FSRDsgYnJlYWs7DQogICAgICAgIGNhc2UgMjogZnJlZU9yZGVyID0gRlJFRV9PUkRFUjo6UkFORE9NOyBicmVhazsNCiAgICAgICAgZGVmYXVsdDogYXNzZXJ0KDApOw0KICAgICAgICB9DQoNCiAgICAgICAgZm9yIChVSU5UMzIgZW1wdHlJbmRleCA9IDA7IGVtcHR5SW5kZXggPCBlbXB0eUNvdW50OyArK2VtcHR5SW5kZXgpDQogICAgICAgIHsNCiAgICAgICAgICAgIGZvciAoVUlOVDMyIGFsZ29yaXRobUluZGV4ID0gMDsgYWxnb3JpdGhtSW5kZXggPCAyOyArK2FsZ29yaXRobUluZGV4KQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIEQzRDEyTUE6OlBPT0xfRkxBR1MgYWxnb3JpdGhtOw0KICAgICAgICAgICAgICAgIHN3aXRjaCAoYWxnb3JpdGhtSW5kZXgpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGNhc2UgMDoNCiAgICAgICAgICAgICAgICAgICAgYWxnb3JpdGhtID0gRDNEMTJNQTo6UE9PTF9GTEFHX05PTkU7DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGNhc2UgMToNCiAgICAgICAgICAgICAgICAgICAgYWxnb3JpdGhtID0gRDNEMTJNQTo6UE9PTF9GTEFHX0FMR09SSVRITV9MSU5FQVI7DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGRlZmF1bHQ6DQogICAgICAgICAgICAgICAgICAgIGFzc2VydCgwKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBCZW5jaG1hcmtBbGdvcml0aG1zQ2FzZShjdHgsDQogICAgICAgICAgICAgICAgICAgIGZpbGUsDQogICAgICAgICAgICAgICAgICAgIGFsZ29yaXRobSwNCiAgICAgICAgICAgICAgICAgICAgKGVtcHR5SW5kZXggPT0gMCksIC8vIGVtcHR5DQogICAgICAgICAgICAgICAgICAgIGZyZWVPcmRlcik7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQp9DQoNCiNpZmRlZiBfX0lEM0QxMkRldmljZTRfSU5URVJGQUNFX0RFRklORURfXw0Kc3RhdGljIHZvaWQgVGVzdERldmljZTQoY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICB3cHJpbnRmKEwiVGVzdCBJRDNEMTJEZXZpY2U0XG4iKTsNCg0KICAgIGlmKCFJc1Byb3RlY3RlZFJlc291cmNlU2Vzc2lvblN1cHBvcnRlZChjdHgpKQ0KICAgIHsNCiAgICAgICAgd3ByaW50ZihMIkQzRDEyX0ZFQVRVUkVfUFJPVEVDVEVEX1JFU09VUkNFX1NFU1NJT05fU1VQUE9SVCByZXR1cm5lZCBubyBzdXBwb3J0IGZvciBwcm90ZWN0ZWQgcmVzb3VyY2Ugc2Vzc2lvbi5cbiIpOw0KICAgICAgICByZXR1cm47DQogICAgfQ0KDQogICAgQ29tUHRyPElEM0QxMkRldmljZTQ+IGRldjQ7DQogICAgSFJFU1VMVCBociA9IGN0eC5kZXZpY2UtPlF1ZXJ5SW50ZXJmYWNlKElJRF9QUFZfQVJHUygmZGV2NCkpOw0KICAgIGlmKEZBSUxFRChocikpDQogICAgew0KICAgICAgICB3cHJpbnRmKEwiUXVlcnlJbnRlcmZhY2UgZm9yIElEM0QxMkRldmljZTQgRkFJTEVELlxuIik7DQogICAgICAgIHJldHVybjsNCiAgICB9DQoNCiAgICBEM0QxMl9QUk9URUNURURfUkVTT1VSQ0VfU0VTU0lPTl9ERVNDIHNlc3Npb25EZXNjID0ge307DQogICAgQ29tUHRyPElEM0QxMlByb3RlY3RlZFJlc291cmNlU2Vzc2lvbj4gc2Vzc2lvbjsNCiAgICAvLyBUaGlzIGZhaWxzIG9uIHRoZSBTT0ZUV0FSRSBhZGFwdGVyLg0KICAgIGhyID0gZGV2NC0+Q3JlYXRlUHJvdGVjdGVkUmVzb3VyY2VTZXNzaW9uKCZzZXNzaW9uRGVzYywgSUlEX1BQVl9BUkdTKCZzZXNzaW9uKSk7DQogICAgaWYoRkFJTEVEKGhyKSkNCiAgICB7DQogICAgICAgIHdwcmludGYoTCJJRDNEMTJEZXZpY2U0OjpDcmVhdGVQcm90ZWN0ZWRSZXNvdXJjZVNlc3Npb24gRkFJTEVELlxuIik7DQogICAgICAgIHJldHVybjsNCiAgICB9DQoNCiAgICBEM0QxMk1BOjpQT09MX0RFU0MgcG9vbERlc2MgPSB7fTsNCiAgICBwb29sRGVzYy5IZWFwUHJvcGVydGllcy5UeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQogICAgcG9vbERlc2MucFByb3RlY3RlZFNlc3Npb24gPSBzZXNzaW9uLkdldCgpOw0KICAgIHBvb2xEZXNjLk1pbkFsbG9jYXRpb25BbGlnbm1lbnQgPSAwOw0KICAgIHBvb2xEZXNjLkhlYXBGbGFncyA9IEQzRDEyX0hFQVBfRkxBR19BTExPV19PTkxZX0JVRkZFUlM7DQoNCiAgICBDb21QdHI8RDNEMTJNQTo6UG9vbD4gcG9vbDsNCiAgICBociA9IGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVBvb2woJnBvb2xEZXNjLCAmcG9vbCk7DQogICAgaWYoRkFJTEVEKGhyKSkNCiAgICB7DQogICAgICAgIHdwcmludGYoTCJGYWlsZWQgdG8gY3JlYXRlIGN1c3RvbSBwb29sLlxuIik7DQogICAgICAgIHJldHVybjsNCiAgICB9DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc291cmNlRGVzYzsNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc291cmNlRGVzYywgMTAyNCk7DQoNCiAgICBmb3IoVUlOVCB0ZXN0SW5kZXggPSAwOyB0ZXN0SW5kZXggPCAyOyArK3Rlc3RJbmRleCkNCiAgICB7DQogICAgICAgIC8vIENyZWF0ZSBhIGJ1ZmZlcg0KICAgICAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gcG9vbC5HZXQoKTsNCiAgICAgICAgaWYodGVzdEluZGV4ID09IDApDQogICAgICAgICAgICBhbGxvY0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfQ09NTUlUVEVEOw0KICAgICAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYnVmQWxsb2M7DQogICAgICAgIENvbVB0cjxJRDNEMTJSZXNvdXJjZT4gYnVmUmVzOw0KICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzb3VyY2VEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09NTU9OLCBOVUxMLA0KICAgICAgICAgICAgJmJ1ZkFsbG9jLCBJSURfUFBWX0FSR1MoJmJ1ZlJlcykpKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChidWZBbGxvYyAmJiBidWZBbGxvYy0+R2V0UmVzb3VyY2UoKSA9PSBidWZSZXMuR2V0KCkpOw0KICAgICAgICAvLyBNYWtlIHN1cmUgaXQncyAobm90KSBjb21taXR0ZWQuDQogICAgICAgIENIRUNLX0JPT0woKGJ1ZkFsbG9jLT5HZXRIZWFwKCkgPT0gTlVMTCkgPT0gKHRlc3RJbmRleCA9PSAwKSk7DQoNCiAgICAgICAgLy8gQWxsb2NhdGUgbWVtb3J5L2hlYXANCiAgICAgICAgLy8gVGVtcG9yYXJpbHkgZGlzYWJsZWQgb24gTlZJRElBIGFzIGl0IGNhdXNlcyBCU09EIG9uIFJUWDIwODBUaSBkcml2ZXIgNDYxLjQwLg0KICAgICAgICBpZihnX0FkYXB0ZXJEZXNjLlZlbmRvcklkICE9IFZFTkRPUl9JRF9OVklESUEpDQogICAgICAgIHsNCiAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX0FMTE9DQVRJT05fSU5GTyBoZWFwQWxsb2NJbmZvID0gew0KICAgICAgICAgICAgICAgIEQzRDEyX0RFRkFVTFRfUkVTT1VSQ0VfUExBQ0VNRU5UX0FMSUdOTUVOVCAqIDIsIC8vIFNpemVJbkJ5dGVzDQogICAgICAgICAgICAgICAgRDNEMTJfREVGQVVMVF9SRVNPVVJDRV9QTEFDRU1FTlRfQUxJR05NRU5ULCAvLyBBbGlnbm1lbnQNCiAgICAgICAgICAgIH07DQogICAgICAgICAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gbWVtQWxsb2M7DQogICAgICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5BbGxvY2F0ZU1lbW9yeSgmYWxsb2NEZXNjLCAmaGVhcEFsbG9jSW5mbywgJm1lbUFsbG9jKSk7DQogICAgICAgICAgICBDSEVDS19CT09MKG1lbUFsbG9jLT5HZXRIZWFwKCkpOw0KICAgICAgICB9DQogICAgfQ0KfQ0KI2VuZGlmIC8vICNpZmRlZiBfX0lEM0QxMkRldmljZTRfSU5URVJGQUNFX0RFRklORURfXw0KDQojaWZkZWYgX19JRDNEMTJEZXZpY2U4X0lOVEVSRkFDRV9ERUZJTkVEX18NCnN0YXRpYyB2b2lkIFRlc3REZXZpY2U4KGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgSUQzRDEyRGV2aWNlOFxuIik7DQoNCiAgICBDb21QdHI8SUQzRDEyRGV2aWNlOD4gZGV2ODsNCiAgICBDSEVDS19IUihjdHguZGV2aWNlLT5RdWVyeUludGVyZmFjZShJSURfUFBWX0FSR1MoJmRldjgpKSk7DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDMSByZXNvdXJjZURlc2M7DQogICAgRmlsbFJlc291cmNlRGVzY0ZvckJ1ZmZlcihyZXNvdXJjZURlc2MsIDEwMjQgKiAxMDI0KTsNCg0KICAgIC8vIENyZWF0ZSBhIGNvbW1pdHRlZCBidWZmZXINCg0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICBhbGxvY0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfQ09NTUlUVEVEOw0KDQogICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jUHRyMDsNCiAgICBDb21QdHI8SUQzRDEyUmVzb3VyY2U+IHJlczA7DQogICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UyKCZhbGxvY0Rlc2MsICZyZXNvdXJjZURlc2MsDQogICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPTU1PTiwgTlVMTCwNCiAgICAgICAgJmFsbG9jUHRyMCwgSUlEX1BQVl9BUkdTKCZyZXMwKSkpOw0KICAgIENIRUNLX0JPT0woYWxsb2NQdHIwLT5HZXRIZWFwKCkgPT0gTlVMTCk7DQoNCiAgICAvLyBDcmVhdGUgYSBwbGFjZWQgYnVmZmVyDQoNCiAgICBhbGxvY0Rlc2MuRmxhZ3MgJj0gfkQzRDEyTUE6OkFMTE9DQVRJT05fRkxBR19DT01NSVRURUQ7DQoNCiAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYWxsb2NQdHIxOw0KICAgIENvbVB0cjxJRDNEMTJSZXNvdXJjZT4gcmVzMTsNCiAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZTIoJmFsbG9jRGVzYywgJnJlc291cmNlRGVzYywNCiAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09NTU9OLCBOVUxMLA0KICAgICAgICAmYWxsb2NQdHIxLCBJSURfUFBWX0FSR1MoJnJlczEpKSk7DQogICAgQ0hFQ0tfQk9PTChhbGxvY1B0cjEtPkdldEhlYXAoKSE9IE5VTEwpOw0KfQ0KI2VuZGlmIC8vICNpZmRlZiBfX0lEM0QxMkRldmljZThfSU5URVJGQUNFX0RFRklORURfXw0KDQpzdGF0aWMgdm9pZCBUZXN0VmlydHVhbEJsb2Nrcyhjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IHZpcnR1YWwgYmxvY2tzXG4iKTsNCg0KICAgIHVzaW5nIG5hbWVzcGFjZSBEM0QxMk1BOw0KDQogICAgY29uc3QgVUlOVDY0IGJsb2NrU2l6ZSA9IDE2ICogTUVHQUJZVEU7DQogICAgY29uc3QgVUlOVDY0IGFsaWdubWVudCA9IDI1NjsNCg0KICAgIC8vICMgQ3JlYXRlIGJsb2NrIDE2IE1CDQoNCiAgICBDb21QdHI8RDNEMTJNQTo6VmlydHVhbEJsb2NrPiBibG9jazsNCiAgICBWSVJUVUFMX0JMT0NLX0RFU0MgYmxvY2tEZXNjID0ge307DQogICAgYmxvY2tEZXNjLnBBbGxvY2F0aW9uQ2FsbGJhY2tzID0gY3R4LmFsbG9jYXRpb25DYWxsYmFja3M7DQogICAgYmxvY2tEZXNjLlNpemUgPSBibG9ja1NpemU7DQogICAgQ0hFQ0tfSFIoQ3JlYXRlVmlydHVhbEJsb2NrKCZibG9ja0Rlc2MsICZibG9jaykpOw0KICAgIENIRUNLX0JPT0woYmxvY2spOw0KDQogICAgLy8gIyBBbGxvY2F0ZSA4IE1CDQoNCiAgICBWSVJUVUFMX0FMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuQWxpZ25tZW50ID0gYWxpZ25tZW50Ow0KICAgIGFsbG9jRGVzYy5wUHJpdmF0ZURhdGEgPSAodm9pZCopKHVpbnRwdHJfdCkxOw0KICAgIGFsbG9jRGVzYy5TaXplID0gOCAqIE1FR0FCWVRFOw0KICAgIFZpcnR1YWxBbGxvY2F0aW9uIGFsbG9jMDsNCiAgICBDSEVDS19IUihibG9jay0+QWxsb2NhdGUoJmFsbG9jRGVzYywgJmFsbG9jMCwgbnVsbHB0cikpOw0KDQogICAgLy8gIyBWYWxpZGF0ZSB0aGUgYWxsb2NhdGlvbg0KDQogICAgVklSVFVBTF9BTExPQ0FUSU9OX0lORk8gYWxsb2MwSW5mbyA9IHt9Ow0KICAgIGJsb2NrLT5HZXRBbGxvY2F0aW9uSW5mbyhhbGxvYzAsICZhbGxvYzBJbmZvKTsNCiAgICBDSEVDS19CT09MKGFsbG9jMEluZm8uT2Zmc2V0IDwgYmxvY2tTaXplKTsNCiAgICBDSEVDS19CT09MKGFsbG9jMEluZm8uU2l6ZSA9PSBhbGxvY0Rlc2MuU2l6ZSk7DQogICAgQ0hFQ0tfQk9PTChhbGxvYzBJbmZvLnBQcml2YXRlRGF0YSA9PSBhbGxvY0Rlc2MucFByaXZhdGVEYXRhKTsNCg0KICAgIC8vICMgQ2hlY2sgU2V0VXNlckRhdGENCg0KICAgIGJsb2NrLT5TZXRBbGxvY2F0aW9uUHJpdmF0ZURhdGEoYWxsb2MwLCAodm9pZCopKHVpbnRwdHJfdCkyKTsNCiAgICBibG9jay0+R2V0QWxsb2NhdGlvbkluZm8oYWxsb2MwLCAmYWxsb2MwSW5mbyk7DQogICAgQ0hFQ0tfQk9PTChhbGxvYzBJbmZvLnBQcml2YXRlRGF0YSA9PSAodm9pZCopKHVpbnRwdHJfdCkyKTsNCg0KICAgIC8vICMgQWxsb2NhdGUgNCBNQg0KDQogICAgYWxsb2NEZXNjLlNpemUgPSA0ICogTUVHQUJZVEU7DQogICAgYWxsb2NEZXNjLkFsaWdubWVudCA9IGFsaWdubWVudDsNCiAgICBWaXJ0dWFsQWxsb2NhdGlvbiBhbGxvYzE7DQogICAgQ0hFQ0tfSFIoYmxvY2stPkFsbG9jYXRlKCZhbGxvY0Rlc2MsICZhbGxvYzEsIG51bGxwdHIpKTsNCg0KICAgIFZJUlRVQUxfQUxMT0NBVElPTl9JTkZPIGFsbG9jMUluZm8gPSB7fTsNCiAgICBibG9jay0+R2V0QWxsb2NhdGlvbkluZm8oYWxsb2MxLCAmYWxsb2MxSW5mbyk7DQogICAgQ0hFQ0tfQk9PTChhbGxvYzFJbmZvLk9mZnNldCA8IGJsb2NrU2l6ZSk7DQogICAgQ0hFQ0tfQk9PTChhbGxvYzFJbmZvLk9mZnNldCArIDQgKiBNRUdBQllURSA8PSBhbGxvYzBJbmZvLk9mZnNldCB8fCBhbGxvYzBJbmZvLk9mZnNldCArIDggKiBNRUdBQllURSA8PSBhbGxvYzFJbmZvLk9mZnNldCk7IC8vIENoZWNrIGlmIHRoZXkgZG9uJ3Qgb3ZlcmxhcC4NCg0KICAgIC8vICMgQWxsb2NhdGUgYW5vdGhlciA4IE1CIC0gaXQgc2hvdWxkIGZhaWwNCg0KICAgIGFsbG9jRGVzYy5TaXplID0gOCAqIE1FR0FCWVRFOw0KICAgIGFsbG9jRGVzYy5BbGlnbm1lbnQgPSBhbGlnbm1lbnQ7DQogICAgVmlydHVhbEFsbG9jYXRpb24gYWxsb2MyOw0KICAgIENIRUNLX0JPT0woRkFJTEVEKGJsb2NrLT5BbGxvY2F0ZSgmYWxsb2NEZXNjLCAmYWxsb2MyLCBudWxscHRyKSkpOw0KICAgIENIRUNLX0JPT0woYWxsb2MyLkFsbG9jSGFuZGxlID09IChBbGxvY0hhbmRsZSkwKTsNCg0KICAgIC8vICMgRnJlZSB0aGUgNCBNQiBibG9jay4gTm93IGFsbG9jYXRpb24gb2YgOCBNQiBzaG91bGQgc3VjY2VlZC4NCg0KICAgIGJsb2NrLT5GcmVlQWxsb2NhdGlvbihhbGxvYzEpOw0KICAgIFVJTlQ2NCBhbGxvYzJPZmZzZXQ7DQogICAgQ0hFQ0tfSFIoYmxvY2stPkFsbG9jYXRlKCZhbGxvY0Rlc2MsICZhbGxvYzIsICZhbGxvYzJPZmZzZXQpKTsNCiAgICBDSEVDS19CT09MKGFsbG9jMk9mZnNldCA8IGJsb2NrU2l6ZSk7DQogICAgQ0hFQ0tfQk9PTChhbGxvYzJPZmZzZXQgKyA0ICogTUVHQUJZVEUgPD0gYWxsb2MwSW5mby5PZmZzZXQgfHwgYWxsb2MwSW5mby5PZmZzZXQgKyA4ICogTUVHQUJZVEUgPD0gYWxsb2MyT2Zmc2V0KTsgLy8gQ2hlY2sgaWYgdGhleSBkb24ndCBvdmVybGFwLg0KDQogICAgLy8gIyBDYWxjdWxhdGUgc3RhdGlzdGljcw0KDQogICAgRGV0YWlsZWRTdGF0aXN0aWNzIHN0YXRJbmZvID0ge307DQogICAgYmxvY2stPkNhbGN1bGF0ZVN0YXRpc3RpY3MoJnN0YXRJbmZvKTsNCiAgICBDSEVDS19CT09MKHN0YXRJbmZvLlN0YXRzLkFsbG9jYXRpb25Db3VudCA9PSAyKTsNCiAgICBDSEVDS19CT09MKHN0YXRJbmZvLlN0YXRzLkJsb2NrQ291bnQgPT0gMSk7DQogICAgQ0hFQ0tfQk9PTChzdGF0SW5mby5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPT0gYmxvY2tTaXplKTsNCiAgICBDSEVDS19CT09MKHN0YXRJbmZvLlN0YXRzLkJsb2NrQnl0ZXMgPT0gYmxvY2tTaXplKTsNCg0KICAgIC8vICMgR2VuZXJhdGUgSlNPTiBkdW1wDQoNCiAgICBXQ0hBUioganNvbiA9IG51bGxwdHI7DQogICAgYmxvY2stPkJ1aWxkU3RhdHNTdHJpbmcoJmpzb24pOw0KICAgIHsNCiAgICAgICAgc3RkOjp3c3RyaW5nIHN0cihqc29uKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChzdHIuZmluZChMIlwiQ3VzdG9tRGF0YVwiOiAxIikgIT0gc3RkOjp3c3RyaW5nOjpucG9zKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChzdHIuZmluZChMIlwiQ3VzdG9tRGF0YVwiOiAyIikgIT0gc3RkOjp3c3RyaW5nOjpucG9zKTsNCiAgICB9DQogICAgYmxvY2stPkZyZWVTdGF0c1N0cmluZyhqc29uKTsNCg0KICAgIC8vICMgRnJlZSBhbGxvYzAsIGxlYXZlIGFsbG9jMiB1bmZyZWVkLg0KDQogICAgYmxvY2stPkZyZWVBbGxvY2F0aW9uKGFsbG9jMCk7DQoNCiAgICAvLyAjIFRlc3QgYWxpZ25tZW50DQoNCiAgICB7DQogICAgICAgIGNvbnN0ZXhwciBzaXplX3QgYWxsb2NDb3VudCA9IDEwOw0KICAgICAgICBWaXJ0dWFsQWxsb2NhdGlvbiBhbGxvY3NbYWxsb2NDb3VudF0gPSB7fTsNCiAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBhbGxvY0NvdW50OyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbnN0IGJvb2wgYWxpZ25tZW50MCA9IGkgPT0gYWxsb2NDb3VudCAtIDE7DQogICAgICAgICAgICBhbGxvY0Rlc2MuU2l6ZSA9IGkgKiAzICsgMTU7DQogICAgICAgICAgICBhbGxvY0Rlc2MuQWxpZ25tZW50ID0gYWxpZ25tZW50MCA/IDAgOiA4Ow0KICAgICAgICAgICAgVUlOVDY0IG9mZnNldDsNCiAgICAgICAgICAgIENIRUNLX0hSKGJsb2NrLT5BbGxvY2F0ZSgmYWxsb2NEZXNjLCAmYWxsb2NzW2ldLCAmb2Zmc2V0KSk7DQogICAgICAgICAgICBpZiAoIWFsaWdubWVudDApDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgQ0hFQ0tfQk9PTChvZmZzZXQgJSBhbGxvY0Rlc2MuQWxpZ25tZW50ID09IDApOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZm9yIChzaXplX3QgaSA9IGFsbG9jQ291bnQ7IGktLTsgKQ0KICAgICAgICB7DQogICAgICAgICAgICBibG9jay0+RnJlZUFsbG9jYXRpb24oYWxsb2NzW2ldKTsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIC8vICMgRmluYWwgY2xlYW51cA0KDQogICAgYmxvY2stPkZyZWVBbGxvY2F0aW9uKGFsbG9jMik7DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RWaXJ0dWFsQmxvY2tzQWxnb3JpdGhtcyhjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IHZpcnR1YWwgYmxvY2tzIGFsZ29yaXRobXNcbiIpOw0KDQogICAgUmFuZG9tTnVtYmVyR2VuZXJhdG9yIHJhbmR7IDM0NTQzMzUgfTsNCiAgICBhdXRvIGNhbGNSYW5kb21BbGxvY1NpemUgPSBbJnJhbmRdKCkgLT4gVUlOVDY0IHsgcmV0dXJuIHJhbmQuR2VuZXJhdGUoKSAlIDIwICsgNTsgfTsNCg0KICAgIGZvciAoc2l6ZV90IGFsZ29yaXRobUluZGV4ID0gMDsgYWxnb3JpdGhtSW5kZXggPCAyOyArK2FsZ29yaXRobUluZGV4KQ0KICAgIHsNCiAgICAgICAgLy8gQ3JlYXRlIHRoZSBibG9jaw0KICAgICAgICBEM0QxMk1BOjpWSVJUVUFMX0JMT0NLX0RFU0MgYmxvY2tEZXNjID0ge307DQogICAgICAgIGJsb2NrRGVzYy5wQWxsb2NhdGlvbkNhbGxiYWNrcyA9IGN0eC5hbGxvY2F0aW9uQ2FsbGJhY2tzOw0KICAgICAgICBibG9ja0Rlc2MuU2l6ZSA9IDEwJzAwMDsNCiAgICAgICAgc3dpdGNoIChhbGdvcml0aG1JbmRleCkNCiAgICAgICAgew0KICAgICAgICBjYXNlIDA6IGJsb2NrRGVzYy5GbGFncyA9IEQzRDEyTUE6OlZJUlRVQUxfQkxPQ0tfRkxBR19OT05FOyBicmVhazsNCiAgICAgICAgY2FzZSAxOiBibG9ja0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpWSVJUVUFMX0JMT0NLX0ZMQUdfQUxHT1JJVEhNX0xJTkVBUjsgYnJlYWs7DQogICAgICAgIH0NCiAgICAgICAgQ29tUHRyPEQzRDEyTUE6OlZpcnR1YWxCbG9jaz4gYmxvY2s7DQogICAgICAgIENIRUNLX0hSKEQzRDEyTUE6OkNyZWF0ZVZpcnR1YWxCbG9jaygmYmxvY2tEZXNjLCAmYmxvY2spKTsNCg0KICAgICAgICBzdHJ1Y3QgQWxsb2NEYXRhDQogICAgICAgIHsNCiAgICAgICAgICAgIEQzRDEyTUE6OlZpcnR1YWxBbGxvY2F0aW9uIGFsbG9jYXRpb247DQogICAgICAgICAgICBVSU5UNjQgYWxsb2NPZmZzZXQsIHJlcXVlc3RlZFNpemUsIGFsbG9jYXRpb25TaXplOw0KICAgICAgICB9Ow0KICAgICAgICBzdGQ6OnZlY3RvcjxBbGxvY0RhdGE+IGFsbG9jYXRpb25zOw0KDQogICAgICAgIC8vIE1ha2Ugc29tZSBhbGxvY2F0aW9ucw0KICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IDIwOyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIEQzRDEyTUE6OlZJUlRVQUxfQUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgICAgICAgICAgYWxsb2NEZXNjLlNpemUgPSBjYWxjUmFuZG9tQWxsb2NTaXplKCk7DQogICAgICAgICAgICBhbGxvY0Rlc2MucFByaXZhdGVEYXRhID0gKHZvaWQqKSh1aW50cHRyX3QpKGFsbG9jRGVzYy5TaXplICogMTApOw0KICAgICAgICAgICAgaWYgKGkgPCAxMCkge30NCiAgICAgICAgICAgIGVsc2UgaWYgKGkgPCAyMCAmJiBhbGdvcml0aG1JbmRleCA9PSAxKSBhbGxvY0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpWSVJUVUFMX0FMTE9DQVRJT05fRkxBR19VUFBFUl9BRERSRVNTOw0KDQogICAgICAgICAgICBBbGxvY0RhdGEgYWxsb2MgPSB7fTsNCiAgICAgICAgICAgIGFsbG9jLnJlcXVlc3RlZFNpemUgPSBhbGxvY0Rlc2MuU2l6ZTsNCiAgICAgICAgICAgIENIRUNLX0hSKGJsb2NrLT5BbGxvY2F0ZSgmYWxsb2NEZXNjLCAmYWxsb2MuYWxsb2NhdGlvbiwgbnVsbHB0cikpOw0KDQogICAgICAgICAgICBEM0QxMk1BOjpWSVJUVUFMX0FMTE9DQVRJT05fSU5GTyBhbGxvY0luZm87DQogICAgICAgICAgICBibG9jay0+R2V0QWxsb2NhdGlvbkluZm8oYWxsb2MuYWxsb2NhdGlvbiwgJmFsbG9jSW5mbyk7DQogICAgICAgICAgICBDSEVDS19CT09MKGFsbG9jSW5mby5TaXplID49IGFsbG9jRGVzYy5TaXplKTsNCiAgICAgICAgICAgIGFsbG9jLmFsbG9jT2Zmc2V0ID0gYWxsb2NJbmZvLk9mZnNldDsNCiAgICAgICAgICAgIGFsbG9jLmFsbG9jYXRpb25TaXplID0gYWxsb2NJbmZvLlNpemU7DQoNCiAgICAgICAgICAgIGFsbG9jYXRpb25zLnB1c2hfYmFjayhhbGxvYyk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBGcmVlIHNvbWUgb2YgdGhlIGFsbG9jYXRpb25zDQogICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgNTsgKytpKQ0KICAgICAgICB7DQogICAgICAgICAgICBjb25zdCBzaXplX3QgaW5kZXggPSByYW5kLkdlbmVyYXRlKCkgJSBhbGxvY2F0aW9ucy5zaXplKCk7DQogICAgICAgICAgICBibG9jay0+RnJlZUFsbG9jYXRpb24oYWxsb2NhdGlvbnNbaW5kZXhdLmFsbG9jYXRpb24pOw0KICAgICAgICAgICAgYWxsb2NhdGlvbnMuZXJhc2UoYWxsb2NhdGlvbnMuYmVnaW4oKSArIGluZGV4KTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIEFsbG9jYXRlIHNvbWUgbW9yZQ0KICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IDY7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgRDNEMTJNQTo6VklSVFVBTF9BTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgICAgICAgICBhbGxvY0Rlc2MuU2l6ZSA9IGNhbGNSYW5kb21BbGxvY1NpemUoKTsNCiAgICAgICAgICAgIGFsbG9jRGVzYy5wUHJpdmF0ZURhdGEgPSAodm9pZCopKHVpbnRwdHJfdCkoYWxsb2NEZXNjLlNpemUgKiAxMCk7DQoNCiAgICAgICAgICAgIEFsbG9jRGF0YSBhbGxvYyA9IHt9Ow0KICAgICAgICAgICAgYWxsb2MucmVxdWVzdGVkU2l6ZSA9IGFsbG9jRGVzYy5TaXplOw0KICAgICAgICAgICAgQ0hFQ0tfSFIoYmxvY2stPkFsbG9jYXRlKCZhbGxvY0Rlc2MsICZhbGxvYy5hbGxvY2F0aW9uLCBudWxscHRyKSk7DQoNCiAgICAgICAgICAgIEQzRDEyTUE6OlZJUlRVQUxfQUxMT0NBVElPTl9JTkZPIGFsbG9jSW5mbzsNCiAgICAgICAgICAgIGJsb2NrLT5HZXRBbGxvY2F0aW9uSW5mbyhhbGxvYy5hbGxvY2F0aW9uLCAmYWxsb2NJbmZvKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woYWxsb2NJbmZvLlNpemUgPj0gYWxsb2NEZXNjLlNpemUpOw0KICAgICAgICAgICAgYWxsb2MuYWxsb2NPZmZzZXQgPSBhbGxvY0luZm8uT2Zmc2V0Ow0KICAgICAgICAgICAgYWxsb2MuYWxsb2NhdGlvblNpemUgPSBhbGxvY0luZm8uU2l6ZTsNCg0KICAgICAgICAgICAgYWxsb2NhdGlvbnMucHVzaF9iYWNrKGFsbG9jKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIEFsbG9jYXRlIHNvbWUgd2l0aCBleHRyYSBhbGlnbm1lbnQNCiAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCAzOyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIEQzRDEyTUE6OlZJUlRVQUxfQUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgICAgICAgICAgYWxsb2NEZXNjLlNpemUgPSBjYWxjUmFuZG9tQWxsb2NTaXplKCk7DQogICAgICAgICAgICBhbGxvY0Rlc2MuQWxpZ25tZW50ID0gMTY7DQogICAgICAgICAgICBhbGxvY0Rlc2MucFByaXZhdGVEYXRhID0gKHZvaWQqKSh1aW50cHRyX3QpKGFsbG9jRGVzYy5TaXplICogMTApOw0KDQogICAgICAgICAgICBBbGxvY0RhdGEgYWxsb2MgPSB7fTsNCiAgICAgICAgICAgIGFsbG9jLnJlcXVlc3RlZFNpemUgPSBhbGxvY0Rlc2MuU2l6ZTsNCiAgICAgICAgICAgIENIRUNLX0hSKGJsb2NrLT5BbGxvY2F0ZSgmYWxsb2NEZXNjLCAmYWxsb2MuYWxsb2NhdGlvbiwgbnVsbHB0cikpOw0KDQogICAgICAgICAgICBEM0QxMk1BOjpWSVJUVUFMX0FMTE9DQVRJT05fSU5GTyBhbGxvY0luZm87DQogICAgICAgICAgICBibG9jay0+R2V0QWxsb2NhdGlvbkluZm8oYWxsb2MuYWxsb2NhdGlvbiwgJmFsbG9jSW5mbyk7DQogICAgICAgICAgICBDSEVDS19CT09MKGFsbG9jSW5mby5PZmZzZXQgJSAxNiA9PSAwKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woYWxsb2NJbmZvLlNpemUgPj0gYWxsb2NEZXNjLlNpemUpOw0KICAgICAgICAgICAgYWxsb2MuYWxsb2NPZmZzZXQgPSBhbGxvY0luZm8uT2Zmc2V0Ow0KICAgICAgICAgICAgYWxsb2MuYWxsb2NhdGlvblNpemUgPSBhbGxvY0luZm8uU2l6ZTsNCg0KICAgICAgICAgICAgYWxsb2NhdGlvbnMucHVzaF9iYWNrKGFsbG9jKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENoZWNrIGlmIHRoZSBhbGxvY2F0aW9ucyBkb24ndCBvdmVybGFwDQogICAgICAgIHN0ZDo6c29ydChhbGxvY2F0aW9ucy5iZWdpbigpLCBhbGxvY2F0aW9ucy5lbmQoKSwgW10oY29uc3QgQWxsb2NEYXRhJiBsaHMsIGNvbnN0IEFsbG9jRGF0YSYgcmhzKSB7DQogICAgICAgICAgICByZXR1cm4gbGhzLmFsbG9jT2Zmc2V0IDwgcmhzLmFsbG9jT2Zmc2V0OyB9KTsNCiAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBhbGxvY2F0aW9ucy5zaXplKCkgLSAxOyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIENIRUNLX0JPT0woYWxsb2NhdGlvbnNbaSArIDFdLmFsbG9jT2Zmc2V0ID49IGFsbG9jYXRpb25zW2ldLmFsbG9jT2Zmc2V0ICsgYWxsb2NhdGlvbnNbaV0uYWxsb2NhdGlvblNpemUpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ2hlY2sgcFByaXZhdGVEYXRhDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbnN0IEFsbG9jRGF0YSYgYWxsb2MgPSBhbGxvY2F0aW9ucy5iYWNrKCk7DQogICAgICAgICAgICBEM0QxMk1BOjpWSVJUVUFMX0FMTE9DQVRJT05fSU5GTyBhbGxvY0luZm87DQogICAgICAgICAgICBibG9jay0+R2V0QWxsb2NhdGlvbkluZm8oYWxsb2MuYWxsb2NhdGlvbiwgJmFsbG9jSW5mbyk7DQogICAgICAgICAgICBDSEVDS19CT09MKCh1aW50cHRyX3QpYWxsb2NJbmZvLnBQcml2YXRlRGF0YSA9PSBhbGxvYy5yZXF1ZXN0ZWRTaXplICogMTApOw0KDQogICAgICAgICAgICBibG9jay0+U2V0QWxsb2NhdGlvblByaXZhdGVEYXRhKGFsbG9jLmFsbG9jYXRpb24sICh2b2lkKikodWludHB0cl90KTY2Nik7DQogICAgICAgICAgICBibG9jay0+R2V0QWxsb2NhdGlvbkluZm8oYWxsb2MuYWxsb2NhdGlvbiwgJmFsbG9jSW5mbyk7DQogICAgICAgICAgICBDSEVDS19CT09MKCh1aW50cHRyX3QpYWxsb2NJbmZvLnBQcml2YXRlRGF0YSA9PSA2NjYpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ2FsY3VsYXRlIHN0YXRpc3RpY3MNCiAgICAgICAgew0KICAgICAgICAgICAgVUlOVDY0IGFjdHVhbEFsbG9jU2l6ZU1pbiA9IFVJTlQ2NF9NQVgsIGFjdHVhbEFsbG9jU2l6ZU1heCA9IDAsIGFjdHVhbEFsbG9jU2l6ZVN1bSA9IDA7DQogICAgICAgICAgICBzdGQ6OmZvcl9lYWNoKGFsbG9jYXRpb25zLmJlZ2luKCksIGFsbG9jYXRpb25zLmVuZCgpLCBbJl0oY29uc3QgQWxsb2NEYXRhJiBhKSB7DQogICAgICAgICAgICAgICAgYWN0dWFsQWxsb2NTaXplTWluID0gc3RkOjptaW4oYWN0dWFsQWxsb2NTaXplTWluLCBhLmFsbG9jYXRpb25TaXplKTsNCiAgICAgICAgICAgICAgICBhY3R1YWxBbGxvY1NpemVNYXggPSBzdGQ6Om1heChhY3R1YWxBbGxvY1NpemVNYXgsIGEuYWxsb2NhdGlvblNpemUpOw0KICAgICAgICAgICAgICAgIGFjdHVhbEFsbG9jU2l6ZVN1bSArPSBhLmFsbG9jYXRpb25TaXplOw0KICAgICAgICAgICAgICAgIH0pOw0KDQogICAgICAgICAgICBEM0QxMk1BOjpEZXRhaWxlZFN0YXRpc3RpY3Mgc3RhdEluZm8gPSB7fTsNCiAgICAgICAgICAgIGJsb2NrLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZzdGF0SW5mbyk7DQogICAgICAgICAgICBDSEVDS19CT09MKHN0YXRJbmZvLlN0YXRzLkFsbG9jYXRpb25Db3VudCA9PSBhbGxvY2F0aW9ucy5zaXplKCkpOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChzdGF0SW5mby5TdGF0cy5CbG9ja0NvdW50ID09IDEpOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChzdGF0SW5mby5TdGF0cy5CbG9ja0J5dGVzID09IGJsb2NrRGVzYy5TaXplKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woc3RhdEluZm8uQWxsb2NhdGlvblNpemVNYXggPT0gYWN0dWFsQWxsb2NTaXplTWF4KTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woc3RhdEluZm8uQWxsb2NhdGlvblNpemVNaW4gPT0gYWN0dWFsQWxsb2NTaXplTWluKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woc3RhdEluZm8uU3RhdHMuQWxsb2NhdGlvbkJ5dGVzID49IGFjdHVhbEFsbG9jU2l6ZVN1bSk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBCdWlsZCBKU09OIGR1bXAgc3RyaW5nDQogICAgICAgIHsNCiAgICAgICAgICAgIFdDSEFSKiBqc29uID0gbnVsbHB0cjsNCiAgICAgICAgICAgIGJsb2NrLT5CdWlsZFN0YXRzU3RyaW5nKCZqc29uKTsNCiAgICAgICAgICAgIGludCBJID0gMDsgLy8gcHV0IGEgYnJlYWtwb2ludCBoZXJlIHRvIGRlYnVnDQogICAgICAgICAgICBibG9jay0+RnJlZVN0YXRzU3RyaW5nKGpzb24pOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gRmluYWwgY2xlYW51cA0KICAgICAgICBibG9jay0+Q2xlYXIoKTsNCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RWaXJ0dWFsQmxvY2tzQWxnb3JpdGhtc0JlbmNobWFyayhjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJCZW5jaG1hcmsgdmlydHVhbCBibG9ja3MgYWxnb3JpdGhtc1xuIik7DQoNCiAgICBjb25zdCBzaXplX3QgQUxMT0NBVElPTl9DT1VOVCA9IDcyMDA7DQogICAgY29uc3QgVUlOVDMyIE1BWF9BTExPQ19TSVpFID0gMjA1NjsNCg0KICAgIEQzRDEyTUE6OlZJUlRVQUxfQkxPQ0tfREVTQyBibG9ja0Rlc2MgPSB7fTsNCiAgICBibG9ja0Rlc2MucEFsbG9jYXRpb25DYWxsYmFja3MgPSBjdHguYWxsb2NhdGlvbkNhbGxiYWNrczsNCiAgICBibG9ja0Rlc2MuU2l6ZSA9IDA7DQoNCiAgICBSYW5kb21OdW1iZXJHZW5lcmF0b3IgcmFuZHsgMjAwOTIwMTAgfTsNCg0KICAgIFVJTlQzMiBhbGxvY1NpemVzW0FMTE9DQVRJT05fQ09VTlRdOw0KICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgQUxMT0NBVElPTl9DT1VOVDsgKytpKQ0KICAgIHsNCiAgICAgICAgYWxsb2NTaXplc1tpXSA9IHJhbmQuR2VuZXJhdGUoKSAlIE1BWF9BTExPQ19TSVpFICsgMTsNCiAgICAgICAgYmxvY2tEZXNjLlNpemUgKz0gYWxsb2NTaXplc1tpXTsNCiAgICB9DQogICAgYmxvY2tEZXNjLlNpemUgPSBzdGF0aWNfY2FzdDxVSU5UNjQ+KGJsb2NrRGVzYy5TaXplICogMS41KTsgLy8gNTAlIHNpemUgbWFyZ2luIGluIGNhc2Ugb2YgYWxpZ25tZW50DQoNCiAgICBmb3IgKFVJTlQ4IGFsaWdubWVudEluZGV4ID0gMDsgYWxpZ25tZW50SW5kZXggPCA0OyArK2FsaWdubWVudEluZGV4KQ0KICAgIHsNCiAgICAgICAgVUlOVDY0IGFsaWdubWVudDsNCiAgICAgICAgc3dpdGNoIChhbGlnbm1lbnRJbmRleCkNCiAgICAgICAgew0KICAgICAgICBjYXNlIDA6IGFsaWdubWVudCA9IDE7IGJyZWFrOw0KICAgICAgICBjYXNlIDE6IGFsaWdubWVudCA9IDE2OyBicmVhazsNCiAgICAgICAgY2FzZSAyOiBhbGlnbm1lbnQgPSA2NDsgYnJlYWs7DQogICAgICAgIGNhc2UgMzogYWxpZ25tZW50ID0gMjU2OyBicmVhazsNCiAgICAgICAgZGVmYXVsdDogYXNzZXJ0KDApOyBicmVhazsNCiAgICAgICAgfQ0KICAgICAgICBwcmludGYoIiAgICBBbGlnbm1lbnQ9JWxsdVxuIiwgYWxpZ25tZW50KTsNCg0KICAgICAgICBmb3IgKFVJTlQ4IGFsZ29yaXRobUluZGV4ID0gMDsgYWxnb3JpdGhtSW5kZXggPCAyOyArK2FsZ29yaXRobUluZGV4KQ0KICAgICAgICB7DQogICAgICAgICAgICBzd2l0Y2ggKGFsZ29yaXRobUluZGV4KQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgY2FzZSAwOg0KICAgICAgICAgICAgICAgIGJsb2NrRGVzYy5GbGFncyA9IEQzRDEyTUE6OlZJUlRVQUxfQkxPQ0tfRkxBR19OT05FOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgY2FzZSAxOg0KICAgICAgICAgICAgICAgIGJsb2NrRGVzYy5GbGFncyA9IEQzRDEyTUE6OlZJUlRVQUxfQkxPQ0tfRkxBR19BTEdPUklUSE1fTElORUFSOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgZGVmYXVsdDoNCiAgICAgICAgICAgICAgICBhc3NlcnQoMCk7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIEQzRDEyTUE6OlZpcnR1YWxBbGxvY2F0aW9uIGFsbG9jc1tBTExPQ0FUSU9OX0NPVU5UXTsNCiAgICAgICAgICAgIENvbVB0cjxEM0QxMk1BOjpWaXJ0dWFsQmxvY2s+IGJsb2NrOw0KICAgICAgICAgICAgQ0hFQ0tfSFIoRDNEMTJNQTo6Q3JlYXRlVmlydHVhbEJsb2NrKCZibG9ja0Rlc2MsICZibG9jaykpOw0KICAgICAgICAgICAgZHVyYXRpb24gYWxsb2NEdXJhdGlvbiA9IGR1cmF0aW9uOjp6ZXJvKCk7DQogICAgICAgICAgICBkdXJhdGlvbiBmcmVlRHVyYXRpb24gPSBkdXJhdGlvbjo6emVybygpOw0KDQogICAgICAgICAgICAvLyBBbGxvYw0KICAgICAgICAgICAgdGltZV9wb2ludCB0aW1lQmVnaW4gPSBzdGQ6OmNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsNCiAgICAgICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgQUxMT0NBVElPTl9DT1VOVDsgKytpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIEQzRDEyTUE6OlZJUlRVQUxfQUxMT0NBVElPTl9ERVNDIGFsbG9jQ3JlYXRlSW5mbyA9IHt9Ow0KICAgICAgICAgICAgICAgIGFsbG9jQ3JlYXRlSW5mby5TaXplID0gYWxsb2NTaXplc1tpXTsNCiAgICAgICAgICAgICAgICBhbGxvY0NyZWF0ZUluZm8uQWxpZ25tZW50ID0gYWxpZ25tZW50Ow0KDQogICAgICAgICAgICAgICAgQ0hFQ0tfSFIoYmxvY2stPkFsbG9jYXRlKCZhbGxvY0NyZWF0ZUluZm8sIGFsbG9jcyArIGksIG51bGxwdHIpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGFsbG9jRHVyYXRpb24gKz0gc3RkOjpjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCkgLSB0aW1lQmVnaW47DQoNCiAgICAgICAgICAgIC8vIEZyZWUNCiAgICAgICAgICAgIHRpbWVCZWdpbiA9IHN0ZDo6Y2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpOw0KICAgICAgICAgICAgZm9yIChzaXplX3QgaSA9IEFMTE9DQVRJT05fQ09VTlQ7IGk7KQ0KICAgICAgICAgICAgICAgIGJsb2NrLT5GcmVlQWxsb2NhdGlvbihhbGxvY3NbLS1pXSk7DQogICAgICAgICAgICBmcmVlRHVyYXRpb24gKz0gc3RkOjpjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCkgLSB0aW1lQmVnaW47DQoNCiAgICAgICAgICAgIHByaW50ZigiICAgICAgICBBbGdvcml0aG09JXMgIFx0YWxsb2NhdGlvbnMgJWcgcywgICBcdGZyZWUgJWcgc1xuIiwNCiAgICAgICAgICAgICAgICBWaXJ0dWFsQWxnb3JpdGhtVG9TdHIoYmxvY2tEZXNjLkZsYWdzKSwNCiAgICAgICAgICAgICAgICBUb0Zsb2F0U2Vjb25kcyhhbGxvY0R1cmF0aW9uKSwNCiAgICAgICAgICAgICAgICBUb0Zsb2F0U2Vjb25kcyhmcmVlRHVyYXRpb24pKTsNCiAgICAgICAgfQ0KICAgICAgICBwcmludGYoIlxuIik7DQogICAgfQ0KfQ0KDQpzdGF0aWMgdm9pZCBQcm9jZXNzRGVmcmFnbWVudGF0aW9uUGFzcyhjb25zdCBUZXN0Q29udGV4dCYgY3R4LCBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fUEFTU19NT1ZFX0lORk8mIHN0ZXBJbmZvKQ0Kew0KICAgIHN0ZDo6dmVjdG9yPEQzRDEyX1JFU09VUkNFX0JBUlJJRVI+IHN0YXJ0QmFycmllcnM7DQogICAgc3RkOjp2ZWN0b3I8RDNEMTJfUkVTT1VSQ0VfQkFSUklFUj4gZmluYWxCYXJyaWVyczsNCg0KICAgIGJvb2wgZGVmYXVsdEhlYXAgPSBmYWxzZTsNCiAgICBmb3IgKFVJTlQzMiBpID0gMDsgaSA8IHN0ZXBJbmZvLk1vdmVDb3VudDsgKytpKQ0KICAgIHsNCiAgICAgICAgaWYgKHN0ZXBJbmZvLnBNb3Zlc1tpXS5PcGVyYXRpb24gPT0gRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX01PVkVfT1BFUkFUSU9OX0NPUFkpDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbnN0IGJvb2wgaXNEZWZhdWx0SGVhcCA9IHN0ZXBJbmZvLnBNb3Zlc1tpXS5wU3JjQWxsb2NhdGlvbi0+R2V0SGVhcCgpLT5HZXREZXNjKCkuUHJvcGVydGllcy5UeXBlID09IEQzRDEyX0hFQVBfVFlQRV9ERUZBVUxUOw0KICAgICAgICAgICAgLy8gQ3JlYXRlIG5ldyByZXNvdXJjZQ0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfREVTQyBkZXNjID0gc3RlcEluZm8ucE1vdmVzW2ldLnBTcmNBbGxvY2F0aW9uLT5HZXRSZXNvdXJjZSgpLT5HZXREZXNjKCk7DQogICAgICAgICAgICBDb21QdHI8SUQzRDEyUmVzb3VyY2U+IGRzdFJlczsNCiAgICAgICAgICAgIENIRUNLX0hSKGN0eC5kZXZpY2UtPkNyZWF0ZVBsYWNlZFJlc291cmNlKHN0ZXBJbmZvLnBNb3Zlc1tpXS5wRHN0VG1wQWxsb2NhdGlvbi0+R2V0SGVhcCgpLA0KICAgICAgICAgICAgICAgIHN0ZXBJbmZvLnBNb3Zlc1tpXS5wRHN0VG1wQWxsb2NhdGlvbi0+R2V0T2Zmc2V0KCksICZkZXNjLA0KICAgICAgICAgICAgICAgIGlzRGVmYXVsdEhlYXAgPyBEM0QxMl9SRVNPVVJDRV9TVEFURV9DT1BZX0RFU1QgOiBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsDQogICAgICAgICAgICAgICAgbnVsbHB0ciwgSUlEX1BQVl9BUkdTKCZkc3RSZXMpKSk7DQogICAgICAgICAgICBzdGVwSW5mby5wTW92ZXNbaV0ucERzdFRtcEFsbG9jYXRpb24tPlNldFJlc291cmNlKGRzdFJlcy5HZXQoKSk7DQoNCiAgICAgICAgICAgIC8vIFBlcmZvcm0gYmFycmllcnMgb25seSBpZiBub3QgaW4gcmlnaHQgc3RhdGUNCiAgICAgICAgICAgIGlmIChpc0RlZmF1bHRIZWFwKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGRlZmF1bHRIZWFwID0gdHJ1ZTsNCiAgICAgICAgICAgICAgICAvLyBNb3ZlIG5ldyByZXNvdXJjZSBpbnRvIHByZXZpb3VzIHN0YXRlDQogICAgICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfQkFSUklFUiBiYXJyaWVyID0ge307DQogICAgICAgICAgICAgICAgYmFycmllci5UeXBlID0gRDNEMTJfUkVTT1VSQ0VfQkFSUklFUl9UWVBFX1RSQU5TSVRJT047DQogICAgICAgICAgICAgICAgYmFycmllci5GbGFncyA9IEQzRDEyX1JFU09VUkNFX0JBUlJJRVJfRkxBR19OT05FOw0KICAgICAgICAgICAgICAgIGJhcnJpZXIuVHJhbnNpdGlvbi5TdWJyZXNvdXJjZSA9IEQzRDEyX1JFU09VUkNFX0JBUlJJRVJfQUxMX1NVQlJFU09VUkNFUzsNCiAgICAgICAgICAgICAgICBiYXJyaWVyLlRyYW5zaXRpb24ucFJlc291cmNlID0gZHN0UmVzLkdldCgpOw0KICAgICAgICAgICAgICAgIGJhcnJpZXIuVHJhbnNpdGlvbi5TdGF0ZUFmdGVyID0gKEQzRDEyX1JFU09VUkNFX1NUQVRFUykodWludHB0cl90KXN0ZXBJbmZvLnBNb3Zlc1tpXS5wU3JjQWxsb2NhdGlvbi0+R2V0UHJpdmF0ZURhdGEoKTsNCiAgICAgICAgICAgICAgICBiYXJyaWVyLlRyYW5zaXRpb24uU3RhdGVCZWZvcmUgPSBEM0QxMl9SRVNPVVJDRV9TVEFURV9DT1BZX0RFU1Q7DQogICAgICAgICAgICAgICAgZmluYWxCYXJyaWVycy5lbXBsYWNlX2JhY2soYmFycmllcik7DQoNCiAgICAgICAgICAgICAgICAvLyBNb3ZlIHJlc291cmNlIGludG8gcmlnaHQgc3RhdGUNCiAgICAgICAgICAgICAgICBiYXJyaWVyLlRyYW5zaXRpb24ucFJlc291cmNlID0gc3RlcEluZm8ucE1vdmVzW2ldLnBTcmNBbGxvY2F0aW9uLT5HZXRSZXNvdXJjZSgpOw0KICAgICAgICAgICAgICAgIGJhcnJpZXIuVHJhbnNpdGlvbi5TdGF0ZUJlZm9yZSA9IGJhcnJpZXIuVHJhbnNpdGlvbi5TdGF0ZUFmdGVyOw0KICAgICAgICAgICAgICAgIGJhcnJpZXIuVHJhbnNpdGlvbi5TdGF0ZUFmdGVyID0gRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9TT1VSQ0U7DQogICAgICAgICAgICAgICAgc3RhcnRCYXJyaWVycy5lbXBsYWNlX2JhY2soYmFycmllcik7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQoNCiAgICBpZiAoZGVmYXVsdEhlYXApDQogICAgew0KICAgICAgICBJRDNEMTJHcmFwaGljc0NvbW1hbmRMaXN0KiBjbCA9IEJlZ2luQ29tbWFuZExpc3QoKTsNCiAgICAgICAgY2wtPlJlc291cmNlQmFycmllcihzdGF0aWNfY2FzdDxVSU5UPihzdGFydEJhcnJpZXJzLnNpemUoKSksIHN0YXJ0QmFycmllcnMuZGF0YSgpKTsNCg0KICAgICAgICAvLyBDb3B5IHJlc291cmNlcw0KICAgICAgICBmb3IgKFVJTlQzMiBpID0gMDsgaSA8IHN0ZXBJbmZvLk1vdmVDb3VudDsgKytpKQ0KICAgICAgICB7DQogICAgICAgICAgICBpZiAoc3RlcEluZm8ucE1vdmVzW2ldLk9wZXJhdGlvbiA9PSBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fTU9WRV9PUEVSQVRJT05fQ09QWSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBJRDNEMTJSZXNvdXJjZSogZHN0UmVzID0gc3RlcEluZm8ucE1vdmVzW2ldLnBEc3RUbXBBbGxvY2F0aW9uLT5HZXRSZXNvdXJjZSgpOw0KICAgICAgICAgICAgICAgIElEM0QxMlJlc291cmNlKiBzcmNSZXMgPSBzdGVwSW5mby5wTW92ZXNbaV0ucFNyY0FsbG9jYXRpb24tPkdldFJlc291cmNlKCk7DQoNCiAgICAgICAgICAgICAgICBpZiAoc3RlcEluZm8ucE1vdmVzW2ldLnBEc3RUbXBBbGxvY2F0aW9uLT5HZXRIZWFwKCktPkdldERlc2MoKS5Qcm9wZXJ0aWVzLlR5cGUgPT0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBjbC0+Q29weVJlc291cmNlKGRzdFJlcywgc3JjUmVzKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgRDNEMTJfUkFOR0UgcmFuZ2UgPSB7fTsNCiAgICAgICAgICAgICAgICAgICAgdm9pZCogZHN0Ow0KICAgICAgICAgICAgICAgICAgICBDSEVDS19IUihkc3RSZXMtPk1hcCgwLCAmcmFuZ2UsICZkc3QpKTsNCiAgICAgICAgICAgICAgICAgICAgdm9pZCogc3JjOw0KICAgICAgICAgICAgICAgICAgICBDSEVDS19IUihzcmNSZXMtPk1hcCgwLCAmcmFuZ2UsICZzcmMpKTsNCiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRzdCwgc3JjLCBzdGVwSW5mby5wTW92ZXNbaV0ucFNyY0FsbG9jYXRpb24tPkdldFNpemUoKSk7DQogICAgICAgICAgICAgICAgICAgIGRzdFJlcy0+VW5tYXAoMCwgbnVsbHB0cik7DQogICAgICAgICAgICAgICAgICAgIHNyY1Jlcy0+VW5tYXAoMCwgbnVsbHB0cik7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgY2wtPlJlc291cmNlQmFycmllcihzdGF0aWNfY2FzdDxVSU5UPihmaW5hbEJhcnJpZXJzLnNpemUoKSksIGZpbmFsQmFycmllcnMuZGF0YSgpKTsNCiAgICAgICAgRW5kQ29tbWFuZExpc3QoY2wpOw0KICAgIH0NCiAgICBlbHNlDQogICAgew0KICAgICAgICAvLyBDb3B5IG9ubHkgQ1BVLXNpZGUNCiAgICAgICAgZm9yIChVSU5UMzIgaSA9IDA7IGkgPCBzdGVwSW5mby5Nb3ZlQ291bnQ7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKHN0ZXBJbmZvLnBNb3Zlc1tpXS5PcGVyYXRpb24gPT0gRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX01PVkVfT1BFUkFUSU9OX0NPUFkpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgRDNEMTJfUkFOR0UgcmFuZ2UgPSB7fTsNCg0KICAgICAgICAgICAgICAgIHZvaWQqIGRzdDsNCiAgICAgICAgICAgICAgICBJRDNEMTJSZXNvdXJjZSogZHN0UmVzID0gc3RlcEluZm8ucE1vdmVzW2ldLnBEc3RUbXBBbGxvY2F0aW9uLT5HZXRSZXNvdXJjZSgpOw0KICAgICAgICAgICAgICAgIENIRUNLX0hSKGRzdFJlcy0+TWFwKDAsICZyYW5nZSwgJmRzdCkpOw0KDQogICAgICAgICAgICAgICAgdm9pZCogc3JjOw0KICAgICAgICAgICAgICAgIElEM0QxMlJlc291cmNlKiBzcmNSZXMgPSBzdGVwSW5mby5wTW92ZXNbaV0ucFNyY0FsbG9jYXRpb24tPkdldFJlc291cmNlKCk7DQogICAgICAgICAgICAgICAgQ0hFQ0tfSFIoc3JjUmVzLT5NYXAoMCwgJnJhbmdlLCAmc3JjKSk7DQoNCiAgICAgICAgICAgICAgICBtZW1jcHkoZHN0LCBzcmMsIHN0ZXBJbmZvLnBNb3Zlc1tpXS5wU3JjQWxsb2NhdGlvbi0+R2V0U2l6ZSgpKTsNCiAgICAgICAgICAgICAgICBkc3RSZXMtPlVubWFwKDAsIG51bGxwdHIpOw0KICAgICAgICAgICAgICAgIHNyY1Jlcy0+VW5tYXAoMCwgbnVsbHB0cik7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIERlZnJhZ21lbnQoY29uc3QgVGVzdENvbnRleHQmIGN0eCwNCiAgICBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fREVTQyYgZGVmcmFnRGVzYywNCiAgICBEM0QxMk1BOjpQb29sKiBwb29sLA0KICAgIEQzRDEyTUE6OkRFRlJBR01FTlRBVElPTl9TVEFUUyogZGVmcmFnU3RhdHMgPSBudWxscHRyKQ0Kew0KICAgIENvbVB0cjxEM0QxMk1BOjpEZWZyYWdtZW50YXRpb25Db250ZXh0PiBkZWZyYWdDdHg7DQogICAgaWYgKHBvb2wgIT0gbnVsbHB0cikNCiAgICB7DQogICAgICAgIENIRUNLX0hSKHBvb2wtPkJlZ2luRGVmcmFnbWVudGF0aW9uKCZkZWZyYWdEZXNjLCAmZGVmcmFnQ3R4KSk7DQogICAgfQ0KICAgIGVsc2UNCiAgICAgICAgY3R4LmFsbG9jYXRvci0+QmVnaW5EZWZyYWdtZW50YXRpb24oJmRlZnJhZ0Rlc2MsICZkZWZyYWdDdHgpOw0KDQogICAgSFJFU1VMVCBociA9IFNfT0s7DQogICAgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX1BBU1NfTU9WRV9JTkZPIHBhc3MgPSB7fTsNCiAgICB3aGlsZSAoKGhyID0gZGVmcmFnQ3R4LT5CZWdpblBhc3MoJnBhc3MpKSA9PSBTX0ZBTFNFKQ0KICAgIHsNCiAgICAgICAgUHJvY2Vzc0RlZnJhZ21lbnRhdGlvblBhc3MoY3R4LCBwYXNzKTsNCg0KICAgICAgICBpZiAoKGhyID0gZGVmcmFnQ3R4LT5FbmRQYXNzKCZwYXNzKSkgPT0gU19PSykNCiAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICBDSEVDS19CT09MKGhyID09IFNfRkFMU0UpOw0KICAgIH0NCiAgICBDSEVDS19IUihocik7DQogICAgaWYgKGRlZnJhZ1N0YXRzICE9IG51bGxwdHIpDQogICAgICAgIGRlZnJhZ0N0eC0+R2V0U3RhdHMoZGVmcmFnU3RhdHMpOw0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0RGVmcmFnbWVudGF0aW9uU2ltcGxlKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgZGVmcmFnbWVudGF0aW9uIHNpbXBsZVxuIik7DQoNCiAgICBSYW5kb21OdW1iZXJHZW5lcmF0b3IgcmFuZCg2NjcpOw0KDQogICAgY29uc3QgVUlOVCBBTExPQ19TRUVEID0gMjAyMjAzMTA7DQogICAgY29uc3QgVUlOVDY0IEJVRl9TSVpFID0gMHgxMDAwMDsNCiAgICBjb25zdCBVSU5UNjQgQkxPQ0tfU0laRSA9IEJVRl9TSVpFICogODsNCg0KICAgIGNvbnN0IFVJTlQ2NCBNSU5fQlVGX1NJWkUgPSAzMjsNCiAgICBjb25zdCBVSU5UNjQgTUFYX0JVRl9TSVpFID0gQlVGX1NJWkUgKiA0Ow0KICAgIGF1dG8gUmFuZG9tQnVmU2l6ZSA9IFsmXSgpIC0+IFVJTlQ2NA0KICAgIHsNCiAgICAgICAgcmV0dXJuIEFsaWduVXA8VUlOVDY0PihyYW5kLkdlbmVyYXRlKCkgJSAoTUFYX0JVRl9TSVpFIC0gTUlOX0JVRl9TSVpFICsgMSkgKyBNSU5fQlVGX1NJWkUsIDY0KTsNCiAgICB9Ow0KDQogICAgRDNEMTJNQTo6UE9PTF9ERVNDIHBvb2xEZXNjID0ge307DQogICAgcG9vbERlc2MuQmxvY2tTaXplID0gQkxPQ0tfU0laRTsNCiAgICBwb29sRGVzYy5IZWFwUHJvcGVydGllcy5UeXBlID0gRDNEMTJfSEVBUF9UWVBFX1VQTE9BRDsNCiAgICBwb29sRGVzYy5IZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9CVUZGRVJTOw0KICAgIENvbVB0cjxEM0QxMk1BOjpQb29sPiBwb29sOw0KICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVBvb2woJnBvb2xEZXNjLCAmcG9vbCkpOw0KDQogICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gcG9vbC5HZXQoKTsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzRGVzYyA9IHt9Ow0KICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzRGVzYywgQlVGX1NJWkUpOw0KDQogICAgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX0RFU0MgZGVmcmFnRGVzYyA9IHt9Ow0KICAgIGRlZnJhZ0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fRkxBR19BTEdPUklUSE1fRkFTVDsNCg0KICAgIC8vIERlZnJhZ21lbnRhdGlvbiBvZiBlbXB0eSBwb29sLg0KICAgIHsNCiAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkRlZnJhZ21lbnRhdGlvbkNvbnRleHQ+IGRlZnJhZ0N0eCA9IG51bGxwdHI7DQogICAgICAgIENIRUNLX0hSKHBvb2wtPkJlZ2luRGVmcmFnbWVudGF0aW9uKCZkZWZyYWdEZXNjLCAmZGVmcmFnQ3R4KSk7DQoNCiAgICAgICAgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX1BBU1NfTU9WRV9JTkZPIHBhc3MgPSB7fTsNCiAgICAgICAgQ0hFQ0tfQk9PTChkZWZyYWdDdHgtPkJlZ2luUGFzcygmcGFzcykgPT0gU19PSyk7DQoNCiAgICAgICAgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX1NUQVRTIGRlZnJhZ1N0YXRzID0ge307DQogICAgICAgIGRlZnJhZ0N0eC0+R2V0U3RhdHMoJmRlZnJhZ1N0YXRzKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChkZWZyYWdTdGF0cy5BbGxvY2F0aW9uc01vdmVkID09IDAgJiYgZGVmcmFnU3RhdHMuQnl0ZXNGcmVlZCA9PSAwICYmDQogICAgICAgICAgICBkZWZyYWdTdGF0cy5CeXRlc01vdmVkID09IDAgJiYgZGVmcmFnU3RhdHMuSGVhcHNGcmVlZCA9PSAwKTsNCiAgICB9DQoNCiAgICBEM0QxMl9SQU5HRSBtYXBSYW5nZSA9IHt9Ow0KICAgIHZvaWQqIG1hcFB0cjsNCiAgICBzdGQ6OnZlY3RvcjxDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4+IGFsbG9jYXRpb25zOw0KDQogICAgLy8gcGVyc2lzdGVudGx5TWFwcGVkT3B0aW9uID0gMCAtIG5vdCBwZXJzaXN0ZW50bHkgbWFwcGVkLg0KICAgIC8vIHBlcnNpc3RlbnRseU1hcHBlZE9wdGlvbiA9IDEgLSBwZXJzaXN0ZW50bHkgbWFwcGVkLg0KICAgIGZvciAoVUlOVDggcGVyc2lzdGVudGx5TWFwcGVkT3B0aW9uID0gMDsgcGVyc2lzdGVudGx5TWFwcGVkT3B0aW9uIDwgMjsgKytwZXJzaXN0ZW50bHlNYXBwZWRPcHRpb24pDQogICAgew0KICAgICAgICB3cHJpbnRmKEwiICBQZXJzaXN0ZW50bHkgbWFwcGVkIG9wdGlvbiA9ICV1XG4iLCBwZXJzaXN0ZW50bHlNYXBwZWRPcHRpb24pOw0KICAgICAgICBjb25zdCBib29sIHBlcnNpc3RlbnRseU1hcHBlZCA9IHBlcnNpc3RlbnRseU1hcHBlZE9wdGlvbiAhPSAwOw0KDQogICAgICAgIC8vICMgVGVzdCAxDQogICAgICAgIC8vIEJ1ZmZlcnMgb2YgZml4ZWQgc2l6ZS4NCiAgICAgICAgLy8gRmlsbCAyIGJsb2Nrcy4gUmVtb3ZlIG9kZCBidWZmZXJzLiBEZWZyYWdtZW50IGV2ZXJ5dGhpbmcuDQogICAgICAgIC8vIEV4cGVjdGVkIHJlc3VsdDogYXQgbGVhc3QgMSBibG9jayBmcmVlZC4NCiAgICAgICAgew0KICAgICAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBCTE9DS19TSVpFIC8gQlVGX1NJWkUgKiAyOyArK2kpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jOw0KICAgICAgICAgICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsDQogICAgICAgICAgICAgICAgICAgIG51bGxwdHIsICZhbGxvYywgSUlEX05VTEwsIG51bGxwdHIpKTsNCiAgICAgICAgICAgICAgICBpZiAocGVyc2lzdGVudGx5TWFwcGVkKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgQ0hFQ0tfSFIoYWxsb2MtPkdldFJlc291cmNlKCktPk1hcCgwLCAmbWFwUmFuZ2UsICZtYXBQdHIpKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBhbGxvY2F0aW9ucy5lbXBsYWNlX2JhY2soc3RkOjptb3ZlKGFsbG9jKSk7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIGZvciAoc2l6ZV90IGkgPSAxOyBpIDwgYWxsb2NhdGlvbnMuc2l6ZSgpOyArK2kpDQogICAgICAgICAgICAgICAgYWxsb2NhdGlvbnMuZXJhc2UoYWxsb2NhdGlvbnMuYmVnaW4oKSArIGkpOw0KICAgICAgICAgICAgRmlsbEFsbG9jYXRpb25zRGF0YShhbGxvY2F0aW9ucy5kYXRhKCksIGFsbG9jYXRpb25zLnNpemUoKSwgQUxMT0NfU0VFRCk7DQoNCiAgICAgICAgICAgIC8vIFNldCBkYXRhIGZvciBkZWZyYWdtZW50YXRpb24gcmV0cmlldmFsDQogICAgICAgICAgICBmb3IgKGF1dG8mIGFsbG9jIDogYWxsb2NhdGlvbnMpDQogICAgICAgICAgICAgICAgYWxsb2MtPlNldFByaXZhdGVEYXRhKCh2b2lkKilEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQpOw0KDQogICAgICAgICAgICBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fU1RBVFMgZGVmcmFnU3RhdHM7DQogICAgICAgICAgICBEZWZyYWdtZW50KGN0eCwgZGVmcmFnRGVzYywgcG9vbC5HZXQoKSwgJiBkZWZyYWdTdGF0cyk7DQogICAgICAgICAgICBDSEVDS19CT09MKGRlZnJhZ1N0YXRzLkFsbG9jYXRpb25zTW92ZWQgPT0gNCAmJiBkZWZyYWdTdGF0cy5CeXRlc01vdmVkID09IDQgKiBCVUZfU0laRSk7DQoNCiAgICAgICAgICAgIFZhbGlkYXRlQWxsb2NhdGlvbnNEYXRhKGFsbG9jYXRpb25zLmRhdGEoKSwgYWxsb2NhdGlvbnMuc2l6ZSgpLCBBTExPQ19TRUVEKTsNCiAgICAgICAgICAgIGFsbG9jYXRpb25zLmNsZWFyKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyAjIFRlc3QgMg0KICAgICAgICAvLyBCdWZmZXJzIG9mIGZpeGVkIHNpemUuDQogICAgICAgIC8vIEZpbGwgMiBibG9ja3MuIFJlbW92ZSBvZGQgYnVmZmVycy4gRGVmcmFnbWVudCBvbmUgYnVmZmVyIGF0IHRpbWUuDQogICAgICAgIC8vIEV4cGVjdGVkIHJlc3VsdDogRWFjaCBvZiA0IGludGVyYXRpb25zIG1ha2VzIHNvbWUgcHJvZ3Jlc3MuDQogICAgICAgIHsNCiAgICAgICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgQkxPQ0tfU0laRSAvIEJVRl9TSVpFICogMjsgKytpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiBhbGxvYzsNCiAgICAgICAgICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfR0VORVJJQ19SRUFELA0KICAgICAgICAgICAgICAgICAgICBudWxscHRyLCAmYWxsb2MsIElJRF9OVUxMLCBudWxscHRyKSk7DQogICAgICAgICAgICAgICAgaWYgKHBlcnNpc3RlbnRseU1hcHBlZCkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIENIRUNLX0hSKGFsbG9jLT5HZXRSZXNvdXJjZSgpLT5NYXAoMCwgJm1hcFJhbmdlLCAmbWFwUHRyKSk7DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgYWxsb2NhdGlvbnMuZW1wbGFjZV9iYWNrKHN0ZDo6bW92ZShhbGxvYykpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBmb3IgKHNpemVfdCBpID0gMTsgaSA8IGFsbG9jYXRpb25zLnNpemUoKTsgKytpKQ0KICAgICAgICAgICAgICAgIGFsbG9jYXRpb25zLmVyYXNlKGFsbG9jYXRpb25zLmJlZ2luKCkgKyBpKTsNCiAgICAgICAgICAgIEZpbGxBbGxvY2F0aW9uc0RhdGEoYWxsb2NhdGlvbnMuZGF0YSgpLCBhbGxvY2F0aW9ucy5zaXplKCksIEFMTE9DX1NFRUQpOw0KDQogICAgICAgICAgICAvLyBTZXQgZGF0YSBmb3IgZGVmcmFnbWVudGF0aW9uIHJldHJpZXZhbA0KICAgICAgICAgICAgZm9yIChhdXRvJiBhbGxvYyA6IGFsbG9jYXRpb25zKQ0KICAgICAgICAgICAgICAgIGFsbG9jLT5TZXRQcml2YXRlRGF0YSgodm9pZCopRDNEMTJfUkVTT1VSQ0VfU1RBVEVfR0VORVJJQ19SRUFEKTsNCg0KICAgICAgICAgICAgZGVmcmFnRGVzYy5NYXhBbGxvY2F0aW9uc1BlclBhc3MgPSAxOw0KICAgICAgICAgICAgZGVmcmFnRGVzYy5NYXhCeXRlc1BlclBhc3MgPSBCVUZfU0laRTsNCg0KICAgICAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkRlZnJhZ21lbnRhdGlvbkNvbnRleHQ+IGRlZnJhZ0N0eDsNCiAgICAgICAgICAgIENIRUNLX0hSKHBvb2wtPkJlZ2luRGVmcmFnbWVudGF0aW9uKCZkZWZyYWdEZXNjLCAmZGVmcmFnQ3R4KSk7DQoNCiAgICAgICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgQkxPQ0tfU0laRSAvIEJVRl9TSVpFIC8gMjsgKytpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIEQzRDEyTUE6OkRFRlJBR01FTlRBVElPTl9QQVNTX01PVkVfSU5GTyBwYXNzID0ge307DQogICAgICAgICAgICAgICAgQ0hFQ0tfQk9PTChkZWZyYWdDdHgtPkJlZ2luUGFzcygmcGFzcykgPT0gU19GQUxTRSk7DQoNCiAgICAgICAgICAgICAgICBQcm9jZXNzRGVmcmFnbWVudGF0aW9uUGFzcyhjdHgsIHBhc3MpOw0KDQogICAgICAgICAgICAgICAgQ0hFQ0tfQk9PTChkZWZyYWdDdHgtPkVuZFBhc3MoJnBhc3MpID09IFNfRkFMU0UpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fU1RBVFMgZGVmcmFnU3RhdHMgPSB7fTsNCiAgICAgICAgICAgIGRlZnJhZ0N0eC0+R2V0U3RhdHMoJmRlZnJhZ1N0YXRzKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woZGVmcmFnU3RhdHMuQWxsb2NhdGlvbnNNb3ZlZCA9PSA0ICYmIGRlZnJhZ1N0YXRzLkJ5dGVzTW92ZWQgPT0gNCAqIEJVRl9TSVpFKTsNCg0KICAgICAgICAgICAgVmFsaWRhdGVBbGxvY2F0aW9uc0RhdGEoYWxsb2NhdGlvbnMuZGF0YSgpLCBhbGxvY2F0aW9ucy5zaXplKCksIEFMTE9DX1NFRUQpOw0KICAgICAgICAgICAgYWxsb2NhdGlvbnMuY2xlYXIoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vICMgVGVzdCAzDQogICAgICAgIC8vIEJ1ZmZlcnMgb2YgdmFyaWFibGUgc2l6ZS4NCiAgICAgICAgLy8gQ3JlYXRlIGEgbnVtYmVyIG9mIGJ1ZmZlcnMuIFJlbW92ZSBzb21lIHBlcmNlbnQgb2YgdGhlbS4NCiAgICAgICAgLy8gRGVmcmFnbWVudCB3aGlsZSBoYXZpbmcgc29tZSBwZXJjZW50IG9mIHRoZW0gdW5tb3ZhYmxlLg0KICAgICAgICAvLyBFeHBlY3RlZCByZXN1bHQ6IEp1c3Qgc2ltcGxlIHZhbGlkYXRpb24uDQogICAgICAgIHsNCiAgICAgICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgMTAwOyArK2kpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfREVTQyBsb2NhbFJlc0Rlc2MgPSByZXNEZXNjOw0KICAgICAgICAgICAgICAgIGxvY2FsUmVzRGVzYy5XaWR0aCA9IFJhbmRvbUJ1ZlNpemUoKTsNCg0KICAgICAgICAgICAgICAgIENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiBhbGxvYzsNCiAgICAgICAgICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmbG9jYWxSZXNEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsDQogICAgICAgICAgICAgICAgICAgIG51bGxwdHIsICZhbGxvYywgSUlEX05VTEwsIG51bGxwdHIpKTsNCiAgICAgICAgICAgICAgICBpZiAocGVyc2lzdGVudGx5TWFwcGVkKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgQ0hFQ0tfSFIoYWxsb2MtPkdldFJlc291cmNlKCktPk1hcCgwLCAmbWFwUmFuZ2UsICZtYXBQdHIpKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBhbGxvY2F0aW9ucy5lbXBsYWNlX2JhY2soc3RkOjptb3ZlKGFsbG9jKSk7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIGNvbnN0IFVJTlQzMiBwZXJjZW50VG9EZWxldGUgPSA2MDsNCiAgICAgICAgICAgIGNvbnN0IHNpemVfdCBudW1iZXJUb0RlbGV0ZSA9IGFsbG9jYXRpb25zLnNpemUoKSAqIHBlcmNlbnRUb0RlbGV0ZSAvIDEwMDsNCiAgICAgICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbnVtYmVyVG9EZWxldGU7ICsraSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBzaXplX3QgaW5kZXhUb0RlbGV0ZSA9IHJhbmQuR2VuZXJhdGUoKSAlIChVSU5UMzIpYWxsb2NhdGlvbnMuc2l6ZSgpOw0KICAgICAgICAgICAgICAgIGFsbG9jYXRpb25zLmVyYXNlKGFsbG9jYXRpb25zLmJlZ2luKCkgKyBpbmRleFRvRGVsZXRlKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIEZpbGxBbGxvY2F0aW9uc0RhdGEoYWxsb2NhdGlvbnMuZGF0YSgpLCBhbGxvY2F0aW9ucy5zaXplKCksIEFMTE9DX1NFRUQpOw0KDQogICAgICAgICAgICAvLyBOb24tbW92YWJsZSBhbGxvY2F0aW9ucyB3aWxsIGJlIGF0IHRoZSBiZWdpbm5pbmcgb2YgYWxsb2NhdGlvbnMgYXJyYXkuDQogICAgICAgICAgICBjb25zdCBVSU5UMzIgcGVyY2VudE5vbk1vdmFibGUgPSAyMDsNCiAgICAgICAgICAgIGNvbnN0IHNpemVfdCBudW1iZXJOb25Nb3ZhYmxlID0gYWxsb2NhdGlvbnMuc2l6ZSgpICogcGVyY2VudE5vbk1vdmFibGUgLyAxMDA7DQogICAgICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IG51bWJlck5vbk1vdmFibGU7ICsraSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBzaXplX3QgaW5kZXhOb25Nb3ZhYmxlID0gaSArIHJhbmQuR2VuZXJhdGUoKSAlIChVSU5UMzIpKGFsbG9jYXRpb25zLnNpemUoKSAtIGkpOw0KICAgICAgICAgICAgICAgIGlmIChpbmRleE5vbk1vdmFibGUgIT0gaSkNCiAgICAgICAgICAgICAgICAgICAgc3RkOjpzd2FwKGFsbG9jYXRpb25zW2ldLCBhbGxvY2F0aW9uc1tpbmRleE5vbk1vdmFibGVdKTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gU2V0IGRhdGEgZm9yIGRlZnJhZ21lbnRhdGlvbiByZXRyaWV2YWwNCiAgICAgICAgICAgIGZvciAoYXV0byYgYWxsb2MgOiBhbGxvY2F0aW9ucykNCiAgICAgICAgICAgICAgICBhbGxvYy0+U2V0UHJpdmF0ZURhdGEoKHZvaWQqKUQzRDEyX1JFU09VUkNFX1NUQVRFX0dFTkVSSUNfUkVBRCk7DQoNCiAgICAgICAgICAgIGRlZnJhZ0Rlc2MuTWF4QWxsb2NhdGlvbnNQZXJQYXNzID0gMDsNCiAgICAgICAgICAgIGRlZnJhZ0Rlc2MuTWF4Qnl0ZXNQZXJQYXNzID0gMDsNCg0KICAgICAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkRlZnJhZ21lbnRhdGlvbkNvbnRleHQ+IGRlZnJhZ0N0eDsNCiAgICAgICAgICAgIENIRUNLX0hSKHBvb2wtPkJlZ2luRGVmcmFnbWVudGF0aW9uKCZkZWZyYWdEZXNjLCAmZGVmcmFnQ3R4KSk7DQoNCiAgICAgICAgICAgIEhSRVNVTFQgaHIgPSBTX09LOw0KICAgICAgICAgICAgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX1BBU1NfTU9WRV9JTkZPIHBhc3MgPSB7fTsNCiAgICAgICAgICAgIHdoaWxlICgoaHIgPSBkZWZyYWdDdHgtPkJlZ2luUGFzcygmcGFzcykpID09IFNfRkFMU0UpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX01PVkUqIGVuZCA9IHBhc3MucE1vdmVzICsgcGFzcy5Nb3ZlQ291bnQ7DQogICAgICAgICAgICAgICAgZm9yIChVSU5UMzIgaSA9IDA7IGkgPCBudW1iZXJOb25Nb3ZhYmxlOyArK2kpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fTU9WRSogbW92ZSA9IHN0ZDo6ZmluZF9pZihwYXNzLnBNb3ZlcywgZW5kLCBbJl0oRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX01PVkUmIG1vdmUpIHsgcmV0dXJuIG1vdmUucFNyY0FsbG9jYXRpb24gPT0gYWxsb2NhdGlvbnNbaV0uR2V0KCk7IH0pOw0KICAgICAgICAgICAgICAgICAgICBpZiAobW92ZSAhPSBlbmQpDQogICAgICAgICAgICAgICAgICAgICAgICBtb3ZlLT5PcGVyYXRpb24gPSBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fTU9WRV9PUEVSQVRJT05fSUdOT1JFOw0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIFByb2Nlc3NEZWZyYWdtZW50YXRpb25QYXNzKGN0eCwgcGFzcyk7DQoNCiAgICAgICAgICAgICAgICBpZiAoKGhyID0gZGVmcmFnQ3R4LT5FbmRQYXNzKCZwYXNzKSkgPT0gU19PSykNCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgQ0hFQ0tfQk9PTChociA9PSBTX0ZBTFNFKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIENIRUNLX0JPT0woaHIgPT0gU19PSyk7DQoNCiAgICAgICAgICAgIFZhbGlkYXRlQWxsb2NhdGlvbnNEYXRhKGFsbG9jYXRpb25zLmRhdGEoKSwgYWxsb2NhdGlvbnMuc2l6ZSgpLCBBTExPQ19TRUVEKTsNCiAgICAgICAgICAgIGFsbG9jYXRpb25zLmNsZWFyKCk7DQogICAgICAgIH0NCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3REZWZyYWdtZW50YXRpb25BbGdvcml0aG1zKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgZGVmcmFnbWVudGF0aW9uIGFsZ29yaXRobXNcbiIpOw0KDQogICAgUmFuZG9tTnVtYmVyR2VuZXJhdG9yIHJhbmQoNjY5KTsNCg0KICAgIGNvbnN0IFVJTlQgQUxMT0NfU0VFRCA9IDIwMDkxMjI1Ow0KICAgIGNvbnN0IFVJTlQ2NCBCVUZfU0laRSA9IDB4MTAwMDA7DQogICAgY29uc3QgVUlOVDY0IEJMT0NLX1NJWkUgPSBCVUZfU0laRSAqIDQwMDsNCg0KICAgIGNvbnN0IFVJTlQ2NCBNSU5fQlVGX1NJWkUgPSAzMjsNCiAgICBjb25zdCBVSU5UNjQgTUFYX0JVRl9TSVpFID0gQlVGX1NJWkUgKiA0Ow0KICAgIGF1dG8gUmFuZG9tQnVmU2l6ZSA9IFsmXSgpIC0+IFVJTlQ2NA0KICAgIHsNCiAgICAgICAgcmV0dXJuIEFsaWduVXA8VUlOVDY0PihyYW5kLkdlbmVyYXRlKCkgJSAoTUFYX0JVRl9TSVpFIC0gTUlOX0JVRl9TSVpFICsgMSkgKyBNSU5fQlVGX1NJWkUsIDY0KTsNCiAgICB9Ow0KDQogICAgRDNEMTJNQTo6UE9PTF9ERVNDIHBvb2xEZXNjID0ge307DQogICAgcG9vbERlc2MuQmxvY2tTaXplID0gQkxPQ0tfU0laRTsNCiAgICBwb29sRGVzYy5IZWFwUHJvcGVydGllcy5UeXBlID0gRDNEMTJfSEVBUF9UWVBFX1VQTE9BRDsNCiAgICBwb29sRGVzYy5IZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9CVUZGRVJTOw0KICAgIENvbVB0cjxEM0QxMk1BOjpQb29sPiBwb29sOw0KICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVBvb2woJnBvb2xEZXNjLCAmcG9vbCkpOw0KDQogICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gcG9vbC5HZXQoKTsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzRGVzYyA9IHt9Ow0KICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzRGVzYywgQlVGX1NJWkUpOw0KDQogICAgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX0RFU0MgZGVmcmFnRGVzYyA9IHt9Ow0KDQogICAgc3RkOjp2ZWN0b3I8Q29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+PiBhbGxvY2F0aW9uczsNCg0KICAgIGZvciAoVUlOVDggaSA9IDA7IGkgPCAzOyArK2kpDQogICAgew0KICAgICAgICBzd2l0Y2ggKGkpDQogICAgICAgIHsNCiAgICAgICAgY2FzZSAwOg0KICAgICAgICAgICAgZGVmcmFnRGVzYy5GbGFncyA9IEQzRDEyTUE6OkRFRlJBR01FTlRBVElPTl9GTEFHX0FMR09SSVRITV9GQVNUOw0KICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIGNhc2UgMToNCiAgICAgICAgICAgIGRlZnJhZ0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fRkxBR19BTEdPUklUSE1fQkFMQU5DRUQ7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgY2FzZSAyOg0KICAgICAgICAgICAgZGVmcmFnRGVzYy5GbGFncyA9IEQzRDEyTUE6OkRFRlJBR01FTlRBVElPTl9GTEFHX0FMR09SSVRITV9GVUxMOw0KICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIH0NCiAgICAgICAgd3ByaW50ZihMIiAgQWxnb3JpdGhtID0gJXNcbiIsIERlZnJhZ21lbnRhdGlvbkFsZ29yaXRobVRvU3RyKGRlZnJhZ0Rlc2MuRmxhZ3MpKTsNCg0KICAgICAgICAvLyAwIC0gV2l0aG91dCBpbW1vdmFibGUgYWxsb2NhdGlvbnMNCiAgICAgICAgLy8gMSAtIFdpdGggaW1tb3ZhYmxlIGFsbG9jYXRpb25zDQogICAgICAgIGZvciAodWludDhfdCBqID0gMDsgaiA8IDI7ICsraikNCiAgICAgICAgew0KICAgICAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCA4MDA7ICsraSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICByZXNEZXNjLldpZHRoID0gUmFuZG9tQnVmU2l6ZSgpOw0KDQogICAgICAgICAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jOw0KICAgICAgICAgICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsDQogICAgICAgICAgICAgICAgICAgIG51bGxwdHIsICZhbGxvYywgSUlEX05VTEwsIG51bGxwdHIpKTsNCiAgICAgICAgICAgICAgICBhbGxvY2F0aW9ucy5lbXBsYWNlX2JhY2soc3RkOjptb3ZlKGFsbG9jKSk7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIGNvbnN0IFVJTlQzMiBwZXJjZW50VG9EZWxldGUgPSA1NTsNCiAgICAgICAgICAgIGNvbnN0IHNpemVfdCBudW1iZXJUb0RlbGV0ZSA9IGFsbG9jYXRpb25zLnNpemUoKSAqIHBlcmNlbnRUb0RlbGV0ZSAvIDEwMDsNCiAgICAgICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbnVtYmVyVG9EZWxldGU7ICsraSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBzaXplX3QgaW5kZXhUb0RlbGV0ZSA9IHJhbmQuR2VuZXJhdGUoKSAlICh1aW50MzJfdClhbGxvY2F0aW9ucy5zaXplKCk7DQogICAgICAgICAgICAgICAgYWxsb2NhdGlvbnMuZXJhc2UoYWxsb2NhdGlvbnMuYmVnaW4oKSArIGluZGV4VG9EZWxldGUpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgRmlsbEFsbG9jYXRpb25zRGF0YShhbGxvY2F0aW9ucy5kYXRhKCksIGFsbG9jYXRpb25zLnNpemUoKSwgQUxMT0NfU0VFRCk7DQoNCiAgICAgICAgICAgIC8vIE5vbi1tb3ZhYmxlIGFsbG9jYXRpb25zIHdpbGwgYmUgYXQgdGhlIGJlZ2lubmluZyBvZiBhbGxvY2F0aW9ucyBhcnJheS4NCiAgICAgICAgICAgIGNvbnN0IFVJTlQzMiBwZXJjZW50Tm9uTW92YWJsZSA9IDIwOw0KICAgICAgICAgICAgY29uc3Qgc2l6ZV90IG51bWJlck5vbk1vdmFibGUgPSBqID09IDAgPyAwIDogKGFsbG9jYXRpb25zLnNpemUoKSAqIHBlcmNlbnROb25Nb3ZhYmxlIC8gMTAwKTsNCiAgICAgICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbnVtYmVyTm9uTW92YWJsZTsgKytpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHNpemVfdCBpbmRleE5vbk1vdmFibGUgPSBpICsgcmFuZC5HZW5lcmF0ZSgpICUgKFVJTlQzMikoYWxsb2NhdGlvbnMuc2l6ZSgpIC0gaSk7DQogICAgICAgICAgICAgICAgaWYgKGluZGV4Tm9uTW92YWJsZSAhPSBpKQ0KICAgICAgICAgICAgICAgICAgICBzdGQ6OnN3YXAoYWxsb2NhdGlvbnNbaV0sIGFsbG9jYXRpb25zW2luZGV4Tm9uTW92YWJsZV0pOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBTZXQgZGF0YSBmb3IgZGVmcmFnbWVudGF0aW9uIHJldHJpZXZhbA0KICAgICAgICAgICAgZm9yIChhdXRvJiBhbGxvYyA6IGFsbG9jYXRpb25zKQ0KICAgICAgICAgICAgICAgIGFsbG9jLT5TZXRQcml2YXRlRGF0YSgodm9pZCopRDNEMTJfUkVTT1VSQ0VfU1RBVEVfR0VORVJJQ19SRUFEKTsNCg0KICAgICAgICAgICAgc3RkOjp3c3RyaW5nIG91dHB1dCA9IERlZnJhZ21lbnRhdGlvbkFsZ29yaXRobVRvU3RyKGRlZnJhZ0Rlc2MuRmxhZ3MpOw0KICAgICAgICAgICAgaWYgKGogPT0gMCkNCiAgICAgICAgICAgICAgICBvdXRwdXQgKz0gTCJfTm9Nb3ZlIjsNCiAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICAgICBvdXRwdXQgKz0gTCJfTW92ZSI7DQogICAgICAgICAgICBTYXZlU3RhdHNTdHJpbmdUb0ZpbGUoY3R4LCAob3V0cHV0ICsgTCJfQmVmb3JlLmpzb24iKS5jX3N0cigpKTsNCg0KICAgICAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkRlZnJhZ21lbnRhdGlvbkNvbnRleHQ+IGRlZnJhZ0N0eDsNCiAgICAgICAgICAgIENIRUNLX0hSKHBvb2wtPkJlZ2luRGVmcmFnbWVudGF0aW9uKCZkZWZyYWdEZXNjLCAmZGVmcmFnQ3R4KSk7DQoNCiAgICAgICAgICAgIEhSRVNVTFQgaHIgPSBTX09LOw0KICAgICAgICAgICAgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX1BBU1NfTU9WRV9JTkZPIHBhc3MgPSB7fTsNCiAgICAgICAgICAgIHdoaWxlICgoaHIgPSBkZWZyYWdDdHgtPkJlZ2luUGFzcygmcGFzcykpID09IFNfRkFMU0UpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX01PVkUqIGVuZCA9IHBhc3MucE1vdmVzICsgcGFzcy5Nb3ZlQ291bnQ7DQogICAgICAgICAgICAgICAgZm9yIChVSU5UMzIgaSA9IDA7IGkgPCBudW1iZXJOb25Nb3ZhYmxlOyArK2kpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fTU9WRSogbW92ZSA9IHN0ZDo6ZmluZF9pZihwYXNzLnBNb3ZlcywgZW5kLCBbJl0oRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX01PVkUmIG1vdmUpIHsgcmV0dXJuIG1vdmUucFNyY0FsbG9jYXRpb24gPT0gYWxsb2NhdGlvbnNbaV0uR2V0KCk7IH0pOw0KICAgICAgICAgICAgICAgICAgICBpZiAobW92ZSAhPSBlbmQpDQogICAgICAgICAgICAgICAgICAgICAgICBtb3ZlLT5PcGVyYXRpb24gPSBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fTU9WRV9PUEVSQVRJT05fSUdOT1JFOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBmb3IgKFVJTlQzMiBpID0gMDsgaSA8IHBhc3MuTW92ZUNvdW50OyArK2kpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBhdXRvIGl0ID0gc3RkOjpmaW5kX2lmKGFsbG9jYXRpb25zLmJlZ2luKCksIGFsbG9jYXRpb25zLmVuZCgpLCBbJl0oY29uc3QgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+JiBhbGxvYykgeyByZXR1cm4gcGFzcy5wTW92ZXNbaV0ucFNyY0FsbG9jYXRpb24gPT0gYWxsb2MuR2V0KCk7IH0pOw0KICAgICAgICAgICAgICAgICAgICBhc3NlcnQoaXQgIT0gYWxsb2NhdGlvbnMuZW5kKCkpOw0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIFByb2Nlc3NEZWZyYWdtZW50YXRpb25QYXNzKGN0eCwgcGFzcyk7DQoNCiAgICAgICAgICAgICAgICBpZiAoKGhyID0gZGVmcmFnQ3R4LT5FbmRQYXNzKCZwYXNzKSkgPT0gU19PSykNCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgQ0hFQ0tfQk9PTChociA9PSBTX0ZBTFNFKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIENIRUNLX0JPT0woaHIgPT0gU19PSyk7DQoNCiAgICAgICAgICAgIFNhdmVTdGF0c1N0cmluZ1RvRmlsZShjdHgsIChvdXRwdXQgKyBMIl9BZnRlci5qc29uIikuY19zdHIoKSk7DQogICAgICAgICAgICBWYWxpZGF0ZUFsbG9jYXRpb25zRGF0YShhbGxvY2F0aW9ucy5kYXRhKCksIGFsbG9jYXRpb25zLnNpemUoKSwgQUxMT0NfU0VFRCk7DQogICAgICAgICAgICBhbGxvY2F0aW9ucy5jbGVhcigpOw0KICAgICAgICB9DQogICAgfQ0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0RGVmcmFnbWVudGF0aW9uRnVsbChjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIGNvbnN0IFVJTlQgQUxMT0NfU0VFRCA9IDIwMTAxMjIwOw0KICAgIHN0ZDo6dmVjdG9yPENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPj4gYWxsb2NhdGlvbnM7DQoNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgYWxsb2NEZXNjLkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX1VQTE9BRDsNCiAgICBhbGxvY0Rlc2MuRXh0cmFIZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9CVUZGRVJTOw0KDQogICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNEZXNjID0ge307DQogICAgRmlsbFJlc291cmNlRGVzY0ZvckJ1ZmZlcihyZXNEZXNjLCAweDEwMDAwKTsNCg0KICAgIC8vIENyZWF0ZSBpbml0aWFsIGFsbG9jYXRpb25zLg0KICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgNDAwOyArK2kpDQogICAgew0KICAgICAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYWxsb2M7DQogICAgICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsDQogICAgICAgICAgICBudWxscHRyLCAmYWxsb2MsIElJRF9OVUxMLCBudWxscHRyKSk7DQogICAgICAgIGFsbG9jYXRpb25zLmVtcGxhY2VfYmFjayhzdGQ6Om1vdmUoYWxsb2MpKTsNCiAgICB9DQogICAgRmlsbEFsbG9jYXRpb25zRGF0YShhbGxvY2F0aW9ucy5kYXRhKCksIGFsbG9jYXRpb25zLnNpemUoKSwgQUxMT0NfU0VFRCk7DQoNCiAgICAvLyBEZWxldGUgcmFuZG9tIGFsbG9jYXRpb25zDQogICAgY29uc3Qgc2l6ZV90IGFsbG9jYXRpb25zVG9EZWxldGVQZXJjZW50ID0gODA7DQogICAgc2l6ZV90IGFsbG9jYXRpb25zVG9EZWxldGUgPSBhbGxvY2F0aW9ucy5zaXplKCkgKiBhbGxvY2F0aW9uc1RvRGVsZXRlUGVyY2VudCAvIDEwMDsNCiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGFsbG9jYXRpb25zVG9EZWxldGU7ICsraSkNCiAgICB7DQogICAgICAgIHNpemVfdCBpbmRleCA9IChzaXplX3QpcmFuZCgpICUgYWxsb2NhdGlvbnMuc2l6ZSgpOw0KICAgICAgICBhbGxvY2F0aW9ucy5lcmFzZShhbGxvY2F0aW9ucy5iZWdpbigpICsgaW5kZXgpOw0KICAgIH0NCiAgICBTYXZlU3RhdHNTdHJpbmdUb0ZpbGUoY3R4LCBMIkZ1bGxCZWZvcmUuanNvbiIpOw0KDQogICAgew0KICAgICAgICAvLyBTZXQgZGF0YSBmb3IgZGVmcmFnbWVudGF0aW9uIHJldHJpZXZhbA0KICAgICAgICBmb3IgKGF1dG8mIGFsbG9jIDogYWxsb2NhdGlvbnMpDQogICAgICAgICAgICBhbGxvYy0+U2V0UHJpdmF0ZURhdGEoKHZvaWQqKUQzRDEyX1JFU09VUkNFX1NUQVRFX0dFTkVSSUNfUkVBRCk7DQoNCiAgICAgICAgY29uc3QgVUlOVDMyIGRlZnJhZ0NvdW50ID0gMTsNCiAgICAgICAgZm9yIChVSU5UMzIgZGVmcmFnSW5kZXggPSAwOyBkZWZyYWdJbmRleCA8IGRlZnJhZ0NvdW50OyArK2RlZnJhZ0luZGV4KQ0KICAgICAgICB7DQogICAgICAgICAgICBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fREVTQyBkZWZyYWdEZXNjID0ge307DQogICAgICAgICAgICBkZWZyYWdEZXNjLkZsYWdzID0gRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX0ZMQUdfQUxHT1JJVEhNX0ZVTEw7DQoNCiAgICAgICAgICAgIHdwcmludGYoTCJUZXN0IGRlZnJhZ21lbnRhdGlvbiBmdWxsICMldVxuIiwgZGVmcmFnSW5kZXgpOw0KDQogICAgICAgICAgICB0aW1lX3BvaW50IGJlZ1RpbWUgPSBzdGQ6OmNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsNCg0KICAgICAgICAgICAgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX1NUQVRTIHN0YXRzOw0KICAgICAgICAgICAgRGVmcmFnbWVudChjdHgsIGRlZnJhZ0Rlc2MsIG51bGxwdHIsICZzdGF0cyk7DQoNCiAgICAgICAgICAgIGZsb2F0IGRlZnJhZ21lbnREdXJhdGlvbiA9IFRvRmxvYXRTZWNvbmRzKHN0ZDo6Y2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpIC0gYmVnVGltZSk7DQoNCiAgICAgICAgICAgIHdwcmludGYoTCJNb3ZlZCBhbGxvY2F0aW9ucyAldSwgYnl0ZXMgJWxsdVxuIiwgc3RhdHMuQWxsb2NhdGlvbnNNb3ZlZCwgc3RhdHMuQnl0ZXNNb3ZlZCk7DQogICAgICAgICAgICB3cHJpbnRmKEwiRnJlZWQgYmxvY2tzICV1LCBieXRlcyAlbGx1XG4iLCBzdGF0cy5IZWFwc0ZyZWVkLCBzdGF0cy5CeXRlc0ZyZWVkKTsNCiAgICAgICAgICAgIHdwcmludGYoTCJUaW1lOiAlLjJmIHNcbiIsIGRlZnJhZ21lbnREdXJhdGlvbik7DQoNCiAgICAgICAgICAgIFNhdmVTdGF0c1N0cmluZ1RvRmlsZShjdHgsIChMIkZ1bGxBZnRlcl8iICsgc3RkOjp0b193c3RyaW5nKGRlZnJhZ0luZGV4KSArIEwiLmpzb24iKS5jX3N0cigpKTsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIFZhbGlkYXRlQWxsb2NhdGlvbnNEYXRhKGFsbG9jYXRpb25zLmRhdGEoKSwgYWxsb2NhdGlvbnMuc2l6ZSgpLCBBTExPQ19TRUVEKTsNCn0NCg0Kc3RhdGljIHZvaWQgVGVzdERlZnJhZ21lbnRhdGlvbkdwdShjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IGRlZnJhZ21lbnRhdGlvbiBHUFVcbiIpOw0KDQogICAgY29uc3QgVUlOVCBBTExPQ19TRUVEID0gMjAxODAzMTQ7DQogICAgc3RkOjp2ZWN0b3I8Q29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+PiBhbGxvY2F0aW9uczsNCg0KICAgIC8vIENyZWF0ZSB0aGF0IG1hbnkgYWxsb2NhdGlvbnMgdG8gc3VyZWx5IGZpbGwgMyBuZXcgYmxvY2tzIG9mIDI1NiBNQi4NCiAgICBjb25zdCBVSU5UNjQgYnVmU2l6ZU1pbiA9IDV1bGwgKiAxMDI0ICogMTAyNDsNCiAgICBjb25zdCBVSU5UNjQgYnVmU2l6ZU1heCA9IDEwdWxsICogMTAyNCAqIDEwMjQ7DQogICAgY29uc3QgVUlOVDY0IHRvdGFsU2l6ZSA9IDN1bGwgKiAyNTYgKiAxMDI0ICogMTAyNDsNCiAgICBjb25zdCBzaXplX3QgYnVmQ291bnQgPSAoc2l6ZV90KSh0b3RhbFNpemUgLyBidWZTaXplTWluKTsNCiAgICBjb25zdCBzaXplX3QgcGVyY2VudFRvTGVhdmUgPSAzMDsNCiAgICBjb25zdCBzaXplX3QgcGVyY2VudE5vbk1vdmFibGUgPSAzOw0KICAgIFJhbmRvbU51bWJlckdlbmVyYXRvciByYW5kID0geyAyMzQ1MjIgfTsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzRGVzYyA9IHt9Ow0KICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzRGVzYywgMHgxMDAwMCk7DQoNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgYWxsb2NEZXNjLkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQogICAgYWxsb2NEZXNjLkV4dHJhSGVhcEZsYWdzID0gRDNEMTJfSEVBUF9GTEFHX0FMTE9XX09OTFlfQlVGRkVSUzsNCg0KICAgIC8vIENyZWF0ZSBhbGwgaW50ZW5kZWQgYnVmZmVycy4NCiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGJ1ZkNvdW50OyArK2kpDQogICAgew0KICAgICAgICByZXNEZXNjLldpZHRoID0gQWxpZ25VcChyYW5kLkdlbmVyYXRlKCkgJSAoYnVmU2l6ZU1heCAtIGJ1ZlNpemVNaW4pICsgYnVmU2l6ZU1pbiwgMzJ1bGwpOw0KDQogICAgICAgIENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiBhbGxvYzsNCiAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJnJlc0Rlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPUFlfREVTVCwNCiAgICAgICAgICAgIG51bGxwdHIsICZhbGxvYywgSUlEX05VTEwsIG51bGxwdHIpKTsNCiAgICAgICAgYWxsb2NhdGlvbnMuZW1wbGFjZV9iYWNrKHN0ZDo6bW92ZShhbGxvYykpOw0KICAgIH0NCg0KICAgIC8vIERlc3Ryb3kgc29tZSBwZXJjZW50YWdlIG9mIHRoZW0uDQogICAgew0KICAgICAgICBjb25zdCBzaXplX3QgYnVmZmVyc1RvRGVzdHJveSA9IFJvdW5kRGl2PHNpemVfdD4oYnVmQ291bnQgKiAoMTAwIC0gcGVyY2VudFRvTGVhdmUpLCAxMDApOw0KICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGJ1ZmZlcnNUb0Rlc3Ryb3k7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgY29uc3Qgc2l6ZV90IGluZGV4ID0gcmFuZC5HZW5lcmF0ZSgpICUgYWxsb2NhdGlvbnMuc2l6ZSgpOw0KICAgICAgICAgICAgYWxsb2NhdGlvbnMuZXJhc2UoYWxsb2NhdGlvbnMuYmVnaW4oKSArIGluZGV4KTsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIC8vIFNldCBkYXRhIGZvciBkZWZyYWdtZW50YXRpb24gcmV0cmlldmFsDQogICAgZm9yIChhdXRvJiBhbGxvYyA6IGFsbG9jYXRpb25zKQ0KICAgICAgICBhbGxvYy0+U2V0UHJpdmF0ZURhdGEoKHZvaWQqKUQzRDEyX1JFU09VUkNFX1NUQVRFX1ZFUlRFWF9BTkRfQ09OU1RBTlRfQlVGRkVSKTsNCg0KICAgIC8vIEZpbGwgdGhlbSB3aXRoIG1lYW5pbmdmdWwgZGF0YS4NCiAgICBGaWxsQWxsb2NhdGlvbnNEYXRhR1BVKGN0eCwgYWxsb2NhdGlvbnMuZGF0YSgpLCBhbGxvY2F0aW9ucy5zaXplKCksIEFMTE9DX1NFRUQpOw0KDQogICAgU2F2ZVN0YXRzU3RyaW5nVG9GaWxlKGN0eCwgTCJHUFVfZGVmcmFnbWVudGF0aW9uX0FfYmVmb3JlLmpzb24iKTsNCiAgICAvLyBEZWZyYWdtZW50IHVzaW5nIEdQVSBvbmx5Lg0KICAgIHsNCiAgICAgICAgY29uc3Qgc2l6ZV90IG51bWJlck5vbk1vdmFibGUgPSBhbGxvY2F0aW9ucy5zaXplKCkgKiBwZXJjZW50Tm9uTW92YWJsZSAvIDEwMDsNCiAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBudW1iZXJOb25Nb3ZhYmxlOyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIHNpemVfdCBpbmRleE5vbk1vdmFibGUgPSBpICsgcmFuZC5HZW5lcmF0ZSgpICUgKFVJTlQzMikoYWxsb2NhdGlvbnMuc2l6ZSgpIC0gaSk7DQogICAgICAgICAgICBpZiAoaW5kZXhOb25Nb3ZhYmxlICE9IGkpDQogICAgICAgICAgICAgICAgc3RkOjpzd2FwKGFsbG9jYXRpb25zW2ldLCBhbGxvY2F0aW9uc1tpbmRleE5vbk1vdmFibGVdKTsNCiAgICAgICAgfQ0KDQogICAgICAgIEQzRDEyTUE6OkRFRlJBR01FTlRBVElPTl9ERVNDIGRlZnJhZ0Rlc2MgPSB7fTsNCiAgICAgICAgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX1NUQVRTIHN0YXRzOw0KICAgICAgICBEZWZyYWdtZW50KGN0eCwgZGVmcmFnRGVzYywgbnVsbHB0ciwgJnN0YXRzKTsNCg0KICAgICAgICBDSEVDS19CT09MKHN0YXRzLkFsbG9jYXRpb25zTW92ZWQgPiAwICYmIHN0YXRzLkJ5dGVzTW92ZWQgPiAwKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChzdGF0cy5IZWFwc0ZyZWVkID4gMCAmJiBzdGF0cy5CeXRlc0ZyZWVkID4gMCk7DQogICAgfQ0KDQogICAgU2F2ZVN0YXRzU3RyaW5nVG9GaWxlKGN0eCwgTCJHUFVfZGVmcmFnbWVudGF0aW9uX0JfYWZ0ZXIuanNvbiIpOw0KICAgIFZhbGlkYXRlQWxsb2NhdGlvbnNEYXRhR1BVKGN0eCwgYWxsb2NhdGlvbnMuZGF0YSgpLCBhbGxvY2F0aW9ucy5zaXplKCksIEFMTE9DX1NFRUQpOw0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0RGVmcmFnbWVudGF0aW9uSW5jcmVtZW50YWxCYXNpYyhjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IGRlZnJhZ21lbnRhdGlvbiBpbmNyZW1lbnRhbCBiYXNpY1xuIik7DQoNCiAgICBjb25zdCBVSU5UIEFMTE9DX1NFRUQgPSAyMDIxMDkxODsNCiAgICBzdGQ6OnZlY3RvcjxDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4+IGFsbG9jYXRpb25zOw0KDQogICAgLy8gQ3JlYXRlIHRoYXQgbWFueSBhbGxvY2F0aW9ucyB0byBzdXJlbHkgZmlsbCAzIG5ldyBibG9ja3Mgb2YgMjU2IE1CLg0KICAgIGNvbnN0IHN0ZDo6YXJyYXk8VUlOVDMyLCAzPiBpbWFnZVNpemVzID0geyAyNTYsIDUxMiwgMTAyNCB9Ow0KICAgIGNvbnN0IFVJTlQ2NCBidWZTaXplTWluID0gNXVsbCAqIDEwMjQgKiAxMDI0Ow0KICAgIGNvbnN0IFVJTlQ2NCBidWZTaXplTWF4ID0gMTB1bGwgKiAxMDI0ICogMTAyNDsNCiAgICBjb25zdCBVSU5UNjQgdG90YWxTaXplID0gM3VsbCAqIDI1NiAqIDEwMjQgKiAxMDI0Ow0KICAgIGNvbnN0IHNpemVfdCBpbWFnZUNvdW50ID0gdG90YWxTaXplIC8gKChzaXplX3QpaW1hZ2VTaXplc1swXSAqIGltYWdlU2l6ZXNbMF0gKiA0KSAvIDI7DQogICAgY29uc3Qgc2l6ZV90IGJ1ZkNvdW50ID0gKHNpemVfdCkodG90YWxTaXplIC8gYnVmU2l6ZU1pbikgLyAyOw0KICAgIGNvbnN0IHNpemVfdCBwZXJjZW50VG9MZWF2ZSA9IDMwOw0KICAgIFJhbmRvbU51bWJlckdlbmVyYXRvciByYW5kID0geyAyMzQ1MjIgfTsNCg0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzRGVzYyA9IHt9Ow0KICAgIHJlc0Rlc2MuRGltZW5zaW9uID0gRDNEMTJfUkVTT1VSQ0VfRElNRU5TSU9OX1RFWFRVUkUyRDsNCiAgICByZXNEZXNjLkFsaWdubWVudCA9IDA7DQogICAgcmVzRGVzYy5EZXB0aE9yQXJyYXlTaXplID0gMTsNCiAgICByZXNEZXNjLk1pcExldmVscyA9IDE7DQogICAgcmVzRGVzYy5Gb3JtYXQgPSBEWEdJX0ZPUk1BVF9SOEc4QjhBOF9VTk9STTsNCiAgICByZXNEZXNjLlNhbXBsZURlc2MuQ291bnQgPSAxOw0KICAgIHJlc0Rlc2MuU2FtcGxlRGVzYy5RdWFsaXR5ID0gMDsNCiAgICByZXNEZXNjLkxheW91dCA9IEQzRDEyX1RFWFRVUkVfTEFZT1VUX1VOS05PV047DQogICAgcmVzRGVzYy5GbGFncyA9IEQzRDEyX1JFU09VUkNFX0ZMQUdfTk9ORTsNCg0KICAgIC8vIENyZWF0ZSBhbGwgaW50ZW5kZWQgaW1hZ2VzLg0KICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgaW1hZ2VDb3VudDsgKytpKQ0KICAgIHsNCiAgICAgICAgY29uc3QgVUlOVDMyIHNpemUgPSBpbWFnZVNpemVzW3JhbmQuR2VuZXJhdGUoKSAlIDNdOw0KICAgICAgICByZXNEZXNjLldpZHRoID0gc2l6ZTsNCiAgICAgICAgcmVzRGVzYy5IZWlnaHQgPSBzaXplOw0KDQogICAgICAgIENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiBhbGxvYzsNCiAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJnJlc0Rlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPUFlfREVTVCwNCiAgICAgICAgICAgIG51bGxwdHIsICZhbGxvYywgSUlEX05VTEwsIG51bGxwdHIpKTsNCg0KICAgICAgICBhbGxvYy0+U2V0UHJpdmF0ZURhdGEoKHZvaWQqKUQzRDEyX1JFU09VUkNFX1NUQVRFX1BJWEVMX1NIQURFUl9SRVNPVVJDRSk7DQogICAgICAgIGFsbG9jYXRpb25zLmVtcGxhY2VfYmFjayhzdGQ6Om1vdmUoYWxsb2MpKTsNCiAgICB9DQoNCiAgICAvLyBBbmQgYWxsIGJ1ZmZlcnMNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc0Rlc2MsIDB4MTAwMDApOw0KICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgYnVmQ291bnQ7ICsraSkNCiAgICB7DQogICAgICAgIHJlc0Rlc2MuV2lkdGggPSBBbGlnblVwKHJhbmQuR2VuZXJhdGUoKSAlIChidWZTaXplTWF4IC0gYnVmU2l6ZU1pbikgKyBidWZTaXplTWluLCAzMnVsbCk7DQoNCiAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jOw0KICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9ERVNULA0KICAgICAgICAgICAgbnVsbHB0ciwgJmFsbG9jLCBJSURfTlVMTCwgbnVsbHB0cikpOw0KDQogICAgICAgIGFsbG9jLT5TZXRQcml2YXRlRGF0YSgodm9pZCopRDNEMTJfUkVTT1VSQ0VfU1RBVEVfVkVSVEVYX0FORF9DT05TVEFOVF9CVUZGRVIpOw0KICAgICAgICBhbGxvY2F0aW9ucy5lbXBsYWNlX2JhY2soc3RkOjptb3ZlKGFsbG9jKSk7DQogICAgfQ0KDQogICAgLy8gRGVzdHJveSBzb21lIHBlcmNlbnRhZ2Ugb2YgdGhlbS4NCiAgICB7DQogICAgICAgIGNvbnN0IHNpemVfdCBhbGxvY2F0aW9uc1RvRGVzdHJveSA9IFJvdW5kRGl2PHNpemVfdD4oKGltYWdlQ291bnQgKyBidWZDb3VudCkgKiAoMTAwIC0gcGVyY2VudFRvTGVhdmUpLCAxMDApOw0KICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGFsbG9jYXRpb25zVG9EZXN0cm95OyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbnN0IHNpemVfdCBpbmRleCA9IHJhbmQuR2VuZXJhdGUoKSAlIGFsbG9jYXRpb25zLnNpemUoKTsNCiAgICAgICAgICAgIGFsbG9jYXRpb25zLmVyYXNlKGFsbG9jYXRpb25zLmJlZ2luKCkgKyBpbmRleCk7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICAvLyBGaWxsIHRoZW0gd2l0aCBtZWFuaW5nZnVsIGRhdGEuDQogICAgRmlsbEFsbG9jYXRpb25zRGF0YUdQVShjdHgsIGFsbG9jYXRpb25zLmRhdGEoKSwgYWxsb2NhdGlvbnMuc2l6ZSgpLCBBTExPQ19TRUVEKTsNCg0KICAgIFNhdmVTdGF0c1N0cmluZ1RvRmlsZShjdHgsIEwiR1BVX2RlZnJhZ21lbnRhdGlvbl9pbmNyZW1lbnRhbF9iYXNpY19BX2JlZm9yZS5qc29uIik7DQogICAgLy8gRGVmcmFnbWVudCB1c2luZyBHUFUgb25seS4NCiAgICB7DQogICAgICAgIEQzRDEyTUE6OkRFRlJBR01FTlRBVElPTl9ERVNDIGRlZnJhZ0Rlc2MgPSB7fTsNCiAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkRlZnJhZ21lbnRhdGlvbkNvbnRleHQ+IGRlZnJhZ0N0eDsNCiAgICAgICAgY3R4LmFsbG9jYXRvci0+QmVnaW5EZWZyYWdtZW50YXRpb24oJmRlZnJhZ0Rlc2MsICZkZWZyYWdDdHgpOw0KDQogICAgICAgIEhSRVNVTFQgaHIgPSBTX09LOw0KICAgICAgICBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fUEFTU19NT1ZFX0lORk8gcGFzcyA9IHt9Ow0KICAgICAgICB3aGlsZSAoKGhyID0gZGVmcmFnQ3R4LT5CZWdpblBhc3MoJnBhc3MpKSA9PSBTX0ZBTFNFKQ0KICAgICAgICB7DQogICAgICAgICAgICAvLyBJZ25vcmUgZGF0YSBvdXRzaWRlIG9mIHRlc3QNCiAgICAgICAgICAgIGZvciAoVUlOVDMyIGkgPSAwOyBpIDwgcGFzcy5Nb3ZlQ291bnQ7ICsraSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBhdXRvIGl0ID0gc3RkOjpmaW5kX2lmKGFsbG9jYXRpb25zLmJlZ2luKCksIGFsbG9jYXRpb25zLmVuZCgpLCBbJl0oY29uc3QgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+JiBhbGxvYykgeyByZXR1cm4gcGFzcy5wTW92ZXNbaV0ucFNyY0FsbG9jYXRpb24gPT0gYWxsb2MuR2V0KCk7IH0pOw0KICAgICAgICAgICAgICAgIGlmIChpdCA9PSBhbGxvY2F0aW9ucy5lbmQoKSkNCiAgICAgICAgICAgICAgICAgICAgcGFzcy5wTW92ZXNbaV0uT3BlcmF0aW9uID0gRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX01PVkVfT1BFUkFUSU9OX0lHTk9SRTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgUHJvY2Vzc0RlZnJhZ21lbnRhdGlvblBhc3MoY3R4LCBwYXNzKTsNCg0KICAgICAgICAgICAgaWYgKChociA9IGRlZnJhZ0N0eC0+RW5kUGFzcygmcGFzcykpID09IFNfT0spDQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBDSEVDS19CT09MKGhyID09IFNfRkFMU0UpOw0KICAgICAgICB9DQogICAgICAgIENIRUNLX0JPT0woaHIgPT0gU19PSyk7DQoNCiAgICAgICAgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX1NUQVRTIHN0YXRzID0ge307DQogICAgICAgIGRlZnJhZ0N0eC0+R2V0U3RhdHMoJnN0YXRzKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChzdGF0cy5BbGxvY2F0aW9uc01vdmVkID4gMCAmJiBzdGF0cy5CeXRlc01vdmVkID4gMCk7DQogICAgICAgIENIRUNLX0JPT0woc3RhdHMuSGVhcHNGcmVlZCA+IDAgJiYgc3RhdHMuQnl0ZXNGcmVlZCA+IDApOw0KICAgIH0NCg0KICAgIFNhdmVTdGF0c1N0cmluZ1RvRmlsZShjdHgsIEwiR1BVX2RlZnJhZ21lbnRhdGlvbl9pbmNyZW1lbnRhbF9iYXNpY19CX2FmdGVyLmpzb24iKTsNCiAgICBWYWxpZGF0ZUFsbG9jYXRpb25zRGF0YUdQVShjdHgsIGFsbG9jYXRpb25zLmRhdGEoKSwgYWxsb2NhdGlvbnMuc2l6ZSgpLCBBTExPQ19TRUVEKTsNCn0NCg0Kdm9pZCBUZXN0RGVmcmFnbWVudGF0aW9uSW5jcmVtZW50YWxDb21wbGV4KGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgZGVmcmFnbWVudGF0aW9uIGluY3JlbWVudGFsIGNvbXBsZXhcbiIpOw0KDQogICAgY29uc3QgVUlOVCBBTExPQ19TRUVEID0gMjAxODAxMTI7DQogICAgc3RkOjp2ZWN0b3I8Q29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+PiBhbGxvY2F0aW9uczsNCg0KICAgIC8vIENyZWF0ZSB0aGF0IG1hbnkgYWxsb2NhdGlvbnMgdG8gc3VyZWx5IGZpbGwgMyBuZXcgYmxvY2tzIG9mIDI1NiBNQi4NCiAgICBjb25zdCBzdGQ6OmFycmF5PFVJTlQzMiwgMz4gaW1hZ2VTaXplcyA9IHsgMjU2LCA1MTIsIDEwMjQgfTsNCiAgICBjb25zdCBVSU5UNjQgYnVmU2l6ZU1pbiA9IDV1bGwgKiAxMDI0ICogMTAyNDsNCiAgICBjb25zdCBVSU5UNjQgYnVmU2l6ZU1heCA9IDEwdWxsICogMTAyNCAqIDEwMjQ7DQogICAgY29uc3QgVUlOVDY0IHRvdGFsU2l6ZSA9IDN1bGwgKiAyNTYgKiAxMDI0ICogMTAyNDsNCiAgICBjb25zdCBzaXplX3QgaW1hZ2VDb3VudCA9IChzaXplX3QpKHRvdGFsU2l6ZSAvIChpbWFnZVNpemVzWzBdICogaW1hZ2VTaXplc1swXSAqIDQpKSAvIDI7DQogICAgY29uc3Qgc2l6ZV90IGJ1ZkNvdW50ID0gKHNpemVfdCkodG90YWxTaXplIC8gYnVmU2l6ZU1pbikgLyAyOw0KICAgIGNvbnN0IHNpemVfdCBwZXJjZW50VG9MZWF2ZSA9IDMwOw0KICAgIFJhbmRvbU51bWJlckdlbmVyYXRvciByYW5kID0geyAyMzQ1MjIgfTsNCg0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzRGVzYyA9IHt9Ow0KICAgIHJlc0Rlc2MuRGltZW5zaW9uID0gRDNEMTJfUkVTT1VSQ0VfRElNRU5TSU9OX1RFWFRVUkUyRDsNCiAgICByZXNEZXNjLkFsaWdubWVudCA9IDA7DQogICAgcmVzRGVzYy5EZXB0aE9yQXJyYXlTaXplID0gMTsNCiAgICByZXNEZXNjLk1pcExldmVscyA9IDE7DQogICAgcmVzRGVzYy5Gb3JtYXQgPSBEWEdJX0ZPUk1BVF9SOEc4QjhBOF9VTk9STTsNCiAgICByZXNEZXNjLlNhbXBsZURlc2MuQ291bnQgPSAxOw0KICAgIHJlc0Rlc2MuU2FtcGxlRGVzYy5RdWFsaXR5ID0gMDsNCiAgICByZXNEZXNjLkxheW91dCA9IEQzRDEyX1RFWFRVUkVfTEFZT1VUX1VOS05PV047DQogICAgcmVzRGVzYy5GbGFncyA9IEQzRDEyX1JFU09VUkNFX0ZMQUdfTk9ORTsNCg0KICAgIC8vIENyZWF0ZSBhbGwgaW50ZW5kZWQgaW1hZ2VzLg0KICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgaW1hZ2VDb3VudDsgKytpKQ0KICAgIHsNCiAgICAgICAgY29uc3QgVUlOVDMyIHNpemUgPSBpbWFnZVNpemVzW3JhbmQuR2VuZXJhdGUoKSAlIDNdOw0KICAgICAgICByZXNEZXNjLldpZHRoID0gc2l6ZTsNCiAgICAgICAgcmVzRGVzYy5IZWlnaHQgPSBzaXplOw0KDQogICAgICAgIENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiBhbGxvYzsNCiAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJnJlc0Rlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPUFlfREVTVCwNCiAgICAgICAgICAgIG51bGxwdHIsICZhbGxvYywgSUlEX05VTEwsIG51bGxwdHIpKTsNCg0KICAgICAgICBhbGxvYy0+U2V0UHJpdmF0ZURhdGEoKHZvaWQqKUQzRDEyX1JFU09VUkNFX1NUQVRFX1BJWEVMX1NIQURFUl9SRVNPVVJDRSk7DQogICAgICAgIGFsbG9jYXRpb25zLmVtcGxhY2VfYmFjayhzdGQ6Om1vdmUoYWxsb2MpKTsNCiAgICB9DQoNCiAgICAvLyBBbmQgYWxsIGJ1ZmZlcnMNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc0Rlc2MsIDB4MTAwMDApOw0KICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgYnVmQ291bnQ7ICsraSkNCiAgICB7DQogICAgICAgIHJlc0Rlc2MuV2lkdGggPSBBbGlnblVwKHJhbmQuR2VuZXJhdGUoKSAlIChidWZTaXplTWF4IC0gYnVmU2l6ZU1pbikgKyBidWZTaXplTWluLCAzMnVsbCk7DQoNCiAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jOw0KICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9ERVNULA0KICAgICAgICAgICAgbnVsbHB0ciwgJmFsbG9jLCBJSURfTlVMTCwgbnVsbHB0cikpOw0KDQogICAgICAgIGFsbG9jLT5TZXRQcml2YXRlRGF0YSgodm9pZCopRDNEMTJfUkVTT1VSQ0VfU1RBVEVfVkVSVEVYX0FORF9DT05TVEFOVF9CVUZGRVIpOw0KICAgICAgICBhbGxvY2F0aW9ucy5lbXBsYWNlX2JhY2soc3RkOjptb3ZlKGFsbG9jKSk7DQogICAgfQ0KDQogICAgLy8gRGVzdHJveSBzb21lIHBlcmNlbnRhZ2Ugb2YgdGhlbS4NCiAgICB7DQogICAgICAgIGNvbnN0IHNpemVfdCBhbGxvY2F0aW9uc1RvRGVzdHJveSA9IFJvdW5kRGl2PHNpemVfdD4oKGltYWdlQ291bnQgKyBidWZDb3VudCkgKiAoMTAwIC0gcGVyY2VudFRvTGVhdmUpLCAxMDApOw0KICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGFsbG9jYXRpb25zVG9EZXN0cm95OyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbnN0IHNpemVfdCBpbmRleCA9IHJhbmQuR2VuZXJhdGUoKSAlIGFsbG9jYXRpb25zLnNpemUoKTsNCiAgICAgICAgICAgIGFsbG9jYXRpb25zLmVyYXNlKGFsbG9jYXRpb25zLmJlZ2luKCkgKyBpbmRleCk7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICAvLyBGaWxsIHRoZW0gd2l0aCBtZWFuaW5nZnVsIGRhdGEuDQogICAgRmlsbEFsbG9jYXRpb25zRGF0YUdQVShjdHgsIGFsbG9jYXRpb25zLmRhdGEoKSwgYWxsb2NhdGlvbnMuc2l6ZSgpLCBBTExPQ19TRUVEKTsNCg0KICAgIFNhdmVTdGF0c1N0cmluZ1RvRmlsZShjdHgsIEwiR1BVX2RlZnJhZ21lbnRhdGlvbl9pbmNyZW1lbnRhbF9jb21wbGV4X0FfYmVmb3JlLmpzb24iKTsNCg0KICAgIGNvbnN0IHNpemVfdCBtYXhBZGRpdGlvbmFsQWxsb2NhdGlvbnMgPSAxMDA7DQogICAgc3RkOjp2ZWN0b3I8Q29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+PiBhZGRpdGlvbmFsQWxsb2NhdGlvbnM7DQogICAgYWRkaXRpb25hbEFsbG9jYXRpb25zLnJlc2VydmUobWF4QWRkaXRpb25hbEFsbG9jYXRpb25zKTsNCg0KICAgIGNvbnN0IGF1dG8gbWFrZUFkZGl0aW9uYWxBbGxvY2F0aW9uID0gWyZdKCkNCiAgICB7DQogICAgICAgIGlmIChhZGRpdGlvbmFsQWxsb2NhdGlvbnMuc2l6ZSgpIDwgbWF4QWRkaXRpb25hbEFsbG9jYXRpb25zKQ0KICAgICAgICB7DQogICAgICAgICAgICByZXNEZXNjLldpZHRoID0gQWxpZ25VcChidWZTaXplTWluICsgcmFuZC5HZW5lcmF0ZSgpICUgKGJ1ZlNpemVNYXggLSBidWZTaXplTWluKSwgMTZ1bGwpOw0KICAgICAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jOw0KICAgICAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJnJlc0Rlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX1ZFUlRFWF9BTkRfQ09OU1RBTlRfQlVGRkVSLA0KICAgICAgICAgICAgICAgIG51bGxwdHIsICZhbGxvYywgSUlEX05VTEwsIG51bGxwdHIpKTsNCiAgICAgICAgICAgIGFsbG9jLT5TZXRQcml2YXRlRGF0YSgodm9pZCopRDNEMTJfUkVTT1VSQ0VfU1RBVEVfVkVSVEVYX0FORF9DT05TVEFOVF9CVUZGRVIpOw0KICAgICAgICAgICAgYWRkaXRpb25hbEFsbG9jYXRpb25zLmVtcGxhY2VfYmFjayhzdGQ6Om1vdmUoYWxsb2MpKTsNCiAgICAgICAgfQ0KICAgIH07DQoNCiAgICAvLyBEZWZyYWdtZW50IHVzaW5nIEdQVSBvbmx5Lg0KICAgIHsNCiAgICAgICAgRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX0RFU0MgZGVmcmFnRGVzYyA9IHt9Ow0KICAgICAgICBkZWZyYWdEZXNjLkZsYWdzID0gRDNEMTJNQTo6REVGUkFHTUVOVEFUSU9OX0ZMQUdfQUxHT1JJVEhNX0ZVTEw7DQoNCiAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkRlZnJhZ21lbnRhdGlvbkNvbnRleHQ+IGRlZnJhZ0N0eDsNCiAgICAgICAgY3R4LmFsbG9jYXRvci0+QmVnaW5EZWZyYWdtZW50YXRpb24oJmRlZnJhZ0Rlc2MsICZkZWZyYWdDdHgpOw0KDQogICAgICAgIG1ha2VBZGRpdGlvbmFsQWxsb2NhdGlvbigpOw0KDQogICAgICAgIEhSRVNVTFQgaHIgPSBTX09LOw0KICAgICAgICBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fUEFTU19NT1ZFX0lORk8gcGFzcyA9IHt9Ow0KICAgICAgICB3aGlsZSAoKGhyID0gZGVmcmFnQ3R4LT5CZWdpblBhc3MoJnBhc3MpKSA9PSBTX0ZBTFNFKQ0KICAgICAgICB7DQogICAgICAgICAgICBtYWtlQWRkaXRpb25hbEFsbG9jYXRpb24oKTsNCg0KICAgICAgICAgICAgLy8gSWdub3JlIGRhdGEgb3V0c2lkZSBvZiB0ZXN0DQogICAgICAgICAgICBmb3IgKFVJTlQzMiBpID0gMDsgaSA8IHBhc3MuTW92ZUNvdW50OyArK2kpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgYXV0byBpdCA9IHN0ZDo6ZmluZF9pZihhbGxvY2F0aW9ucy5iZWdpbigpLCBhbGxvY2F0aW9ucy5lbmQoKSwgWyZdKGNvbnN0IENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiYgYWxsb2MpIHsgcmV0dXJuIHBhc3MucE1vdmVzW2ldLnBTcmNBbGxvY2F0aW9uID09IGFsbG9jLkdldCgpOyB9KTsNCiAgICAgICAgICAgICAgICBpZiAoaXQgPT0gYWxsb2NhdGlvbnMuZW5kKCkpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBhdXRvIGl0ID0gc3RkOjpmaW5kX2lmKGFkZGl0aW9uYWxBbGxvY2F0aW9ucy5iZWdpbigpLCBhZGRpdGlvbmFsQWxsb2NhdGlvbnMuZW5kKCksIFsmXShjb25zdCBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4mIGFsbG9jKSB7IHJldHVybiBwYXNzLnBNb3Zlc1tpXS5wU3JjQWxsb2NhdGlvbiA9PSBhbGxvYy5HZXQoKTsgfSk7DQogICAgICAgICAgICAgICAgICAgIGlmIChpdCA9PSBhZGRpdGlvbmFsQWxsb2NhdGlvbnMuZW5kKCkpDQogICAgICAgICAgICAgICAgICAgICAgICBwYXNzLnBNb3Zlc1tpXS5PcGVyYXRpb24gPSBEM0QxMk1BOjpERUZSQUdNRU5UQVRJT05fTU9WRV9PUEVSQVRJT05fSUdOT1JFOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgUHJvY2Vzc0RlZnJhZ21lbnRhdGlvblBhc3MoY3R4LCBwYXNzKTsNCg0KICAgICAgICAgICAgbWFrZUFkZGl0aW9uYWxBbGxvY2F0aW9uKCk7DQoNCiAgICAgICAgICAgIGlmICgoaHIgPSBkZWZyYWdDdHgtPkVuZFBhc3MoJnBhc3MpKSA9PSBTX09LKQ0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChociA9PSBTX0ZBTFNFKTsNCiAgICAgICAgfQ0KICAgICAgICBDSEVDS19CT09MKGhyID09IFNfT0spOw0KDQogICAgICAgIEQzRDEyTUE6OkRFRlJBR01FTlRBVElPTl9TVEFUUyBzdGF0cyA9IHt9Ow0KICAgICAgICBkZWZyYWdDdHgtPkdldFN0YXRzKCZzdGF0cyk7DQoNCiAgICAgICAgQ0hFQ0tfQk9PTChzdGF0cy5BbGxvY2F0aW9uc01vdmVkID4gMCAmJiBzdGF0cy5CeXRlc01vdmVkID4gMCk7DQogICAgICAgIENIRUNLX0JPT0woc3RhdHMuSGVhcHNGcmVlZCA+IDAgJiYgc3RhdHMuQnl0ZXNGcmVlZCA+IDApOw0KICAgIH0NCg0KICAgIFNhdmVTdGF0c1N0cmluZ1RvRmlsZShjdHgsIEwiR1BVX2RlZnJhZ21lbnRhdGlvbl9pbmNyZW1lbnRhbF9jb21wbGV4X0JfYWZ0ZXIuanNvbiIpOw0KICAgIFZhbGlkYXRlQWxsb2NhdGlvbnNEYXRhR1BVKGN0eCwgYWxsb2NhdGlvbnMuZGF0YSgpLCBhbGxvY2F0aW9ucy5zaXplKCksIEFMTE9DX1NFRUQpOw0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0R3JvdXBWaXJ0dWFsKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgVGVzdFZpcnR1YWxCbG9ja3MoY3R4KTsNCiAgICBUZXN0VmlydHVhbEJsb2Nrc0FsZ29yaXRobXMoY3R4KTsNCiAgICBUZXN0VmlydHVhbEJsb2Nrc0FsZ29yaXRobXNCZW5jaG1hcmsoY3R4KTsNCn0NCg0Kc3RhdGljIHZvaWQgVGVzdEdyb3VwQmFzaWNzKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQojaWYgRDNEMTJNQV9ERUJVR19NQVJHSU4NCiAgICBUZXN0RGVidWdNYXJnaW4oY3R4KTsNCiAgICBUZXN0RGVidWdNYXJnaW5Ob3RJblZpcnR1YWxBbGxvY2F0b3IoY3R4KTsNCiNlbHNlDQogICAgVGVzdEpzb24oY3R4KTsNCiAgICBUZXN0Q29tbWl0dGVkUmVzb3VyY2VzQW5kSnNvbihjdHgpOw0KICAgIFRlc3RDdXN0b21IZWFwRmxhZ3MoY3R4KTsNCiAgICBUZXN0UGxhY2VkUmVzb3VyY2VzKGN0eCk7DQogICAgVGVzdE90aGVyQ29tSW50ZXJmYWNlKGN0eCk7DQogICAgVGVzdEN1c3RvbVBvb2xzKGN0eCk7DQogICAgVGVzdEN1c3RvbVBvb2xfTWluQWxsb2NhdGlvbkFsaWdubWVudChjdHgpOw0KICAgIFRlc3RDdXN0b21Qb29sX0NvbW1pdHRlZChjdHgpOw0KICAgIFRlc3RQb29sc0FuZEFsbG9jYXRpb25QYXJhbWV0ZXJzKGN0eCk7DQogICAgVGVzdEN1c3RvbUhlYXBzKGN0eCk7DQogICAgVGVzdFN0YW5kYXJkQ3VzdG9tQ29tbWl0dGVkUGxhY2VkKGN0eCk7DQogICAgVGVzdEFsaWFzaW5nTWVtb3J5KGN0eCk7DQogICAgVGVzdEFsaWFzaW5nSW1wbGljaXRDb21taXR0ZWQoY3R4KTsNCiAgICBUZXN0UG9vbE1zYWFUZXh0dXJlQXNDb21taXR0ZWQoY3R4KTsNCiAgICBUZXN0TWFwcGluZyhjdHgpOw0KICAgIFRlc3RTdGF0cyhjdHgpOw0KICAgIFRlc3RUcmFuc2ZlcihjdHgpOw0KICAgIFRlc3RaZXJvSW5pdGlhbGl6ZWQoY3R4KTsNCiAgICBUZXN0TXVsdGl0aHJlYWRpbmcoY3R4KTsNCiAgICBUZXN0TGluZWFyQWxsb2NhdG9yKGN0eCk7DQogICAgVGVzdExpbmVhckFsbG9jYXRvck11bHRpQmxvY2soY3R4KTsNCiAgICBNYW51YWxseVRlc3RMaW5lYXJBbGxvY2F0b3IoY3R4KTsNCiNpZmRlZiBfX0lEM0QxMkRldmljZTRfSU5URVJGQUNFX0RFRklORURfXw0KICAgIFRlc3REZXZpY2U0KGN0eCk7DQojZW5kaWYNCiNpZmRlZiBfX0lEM0QxMkRldmljZThfSU5URVJGQUNFX0RFRklORURfXw0KICAgIFRlc3REZXZpY2U4KGN0eCk7DQojZW5kaWYNCg0KICAgIEZJTEUqIGZpbGU7DQogICAgZm9wZW5fcygmZmlsZSwgIlJlc3VsdHMuY3N2IiwgInciKTsNCiAgICBhc3NlcnQoZmlsZSAhPSBOVUxMKTsNCiAgICBCZW5jaG1hcmtBbGdvcml0aG1zKGN0eCwgZmlsZSk7DQogICAgZmNsb3NlKGZpbGUpOw0KI2VuZGlmIC8vICNpZiBEM0QxMl9ERUJVR19NQVJHSU4NCn0NCg0Kc3RhdGljIHZvaWQgVGVzdEdyb3VwRGVmcmFnbWVudGF0aW9uKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgVGVzdERlZnJhZ21lbnRhdGlvblNpbXBsZShjdHgpOw0KICAgIFRlc3REZWZyYWdtZW50YXRpb25BbGdvcml0aG1zKGN0eCk7DQogICAgVGVzdERlZnJhZ21lbnRhdGlvbkZ1bGwoY3R4KTsNCiAgICBUZXN0RGVmcmFnbWVudGF0aW9uR3B1KGN0eCk7DQogICAgVGVzdERlZnJhZ21lbnRhdGlvbkluY3JlbWVudGFsQmFzaWMoY3R4KTsNCiAgICBUZXN0RGVmcmFnbWVudGF0aW9uSW5jcmVtZW50YWxDb21wbGV4KGN0eCk7DQp9DQoNCnZvaWQgVGVzdChjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJURVNUUyBCRUdJTlxuIik7DQoNCiAgICBpZihmYWxzZSkNCiAgICB7DQogICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQogICAgICAgIC8vIFRlbXBvcmFyaWx5IGluc2VydCBjdXN0b20gdGVzdHMgaGVyZToNCiAgICAgICAgcmV0dXJuOw0KICAgIH0NCg0KICAgIFRlc3RHcm91cFZpcnR1YWwoY3R4KTsNCiAgICBUZXN0R3JvdXBCYXNpY3MoY3R4KTsNCiAgICBUZXN0R3JvdXBEZWZyYWdtZW50YXRpb24oY3R4KTsNCg0KICAgIHdwcmludGYoTCJURVNUUyBFTkRcbiIpOw0KfQ0K