Ly8NCi8vIENvcHlyaWdodCAoYykgMjAxOS0yMDIyIEFkdmFuY2VkIE1pY3JvIERldmljZXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi8vDQovLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5DQovLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbA0KLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cw0KLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbA0KLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzDQovLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOg0KLy8NCi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluDQovLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4NCi8vDQovLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUg0KLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksDQovLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFDQovLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSDQovLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLA0KLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTg0KLy8gVEhFIFNPRlRXQVJFLg0KLy8NCg0KI2luY2x1ZGUgIkNvbW1vbi5oIg0KI2luY2x1ZGUgIlRlc3RzLmgiDQojaW5jbHVkZSA8dGhyZWFkPg0KDQovLyBEZWZpbmUgdG8gdGhlIHNhbWUgdmFsdWUgYXMgeW91IGRpZCBmb3IgRDNEMTJNZW1BbGxvYy5jcHAuDQojaWZuZGVmIEQzRDEyTUFfREVCVUdfTUFSR0lODQogICAgI2RlZmluZSBEM0QxMk1BX0RFQlVHX01BUkdJTiAwDQojZW5kaWYNCg0KZXh0ZXJuIElEM0QxMkdyYXBoaWNzQ29tbWFuZExpc3QqIEJlZ2luQ29tbWFuZExpc3QoKTsNCmV4dGVybiBEWEdJX0FEQVBURVJfREVTQzEgZ19BZGFwdGVyRGVzYzsNCmV4dGVybiB2b2lkIEVuZENvbW1hbmRMaXN0KElEM0QxMkdyYXBoaWNzQ29tbWFuZExpc3QqIGNtZExpc3QpOw0KDQplbnVtIENPTkZJR19UWVBFDQp7DQogICAgQ09ORklHX1RZUEVfTUlOSU1VTSwNCiAgICBDT05GSUdfVFlQRV9TTUFMTCwNCiAgICBDT05GSUdfVFlQRV9BVkVSQUdFLA0KICAgIENPTkZJR19UWVBFX0xBUkdFLA0KICAgIENPTkZJR19UWVBFX01BWElNVU0sDQogICAgQ09ORklHX1RZUEVfQ09VTlQNCn07DQoNCmVudW0gY2xhc3MgRlJFRV9PUkRFUiB7IEZPUldBUkQsIEJBQ0tXQVJELCBSQU5ET00sIENPVU5UIH07DQoNCnN0YXRpYyBjb25zdCBjaGFyKiBDT0RFX0RFU0NSSVBUSU9OID0gIkQzRDEyTUEgVGVzdHMiOw0Kc3RhdGljIGNvbnN0ZXhwciBVSU5UNjQgS0lMT0JZVEUgPSAxMDI0Ow0Kc3RhdGljIGNvbnN0ZXhwciBVSU5UNjQgTUVHQUJZVEUgPSAxMDI0ICogS0lMT0JZVEU7DQpzdGF0aWMgY29uc3RleHByIENPTkZJR19UWVBFIENvbmZpZ1R5cGUgPSBDT05GSUdfVFlQRV9TTUFMTDsNCnN0YXRpYyBjb25zdCBjaGFyKiBGUkVFX09SREVSX05BTUVTW10gPSB7ICJGT1JXQVJEIiwgIkJBQ0tXQVJEIiwgIlJBTkRPTSIsIH07DQoNCnN0YXRpYyB2b2lkIEN1cnJlbnRUaW1lVG9TdHIoc3RkOjpzdHJpbmcmIG91dCkNCnsNCiAgICB0aW1lX3QgcmF3VGltZTsgdGltZSgmcmF3VGltZSk7DQogICAgc3RydWN0IHRtIHRpbWVJbmZvOyBsb2NhbHRpbWVfcygmdGltZUluZm8sICZyYXdUaW1lKTsNCiAgICBjaGFyIHRpbWVTdHJbMTI4XTsNCiAgICBzdHJmdGltZSh0aW1lU3RyLCBfY291bnRvZih0aW1lU3RyKSwgIiVjIiwgJnRpbWVJbmZvKTsNCiAgICBvdXQgPSB0aW1lU3RyOw0KfQ0KDQpzdGF0aWMgZmxvYXQgVG9GbG9hdFNlY29uZHMoZHVyYXRpb24gZCkNCnsNCiAgICByZXR1cm4gc3RkOjpjaHJvbm86OmR1cmF0aW9uX2Nhc3Q8c3RkOjpjaHJvbm86OmR1cmF0aW9uPGZsb2F0Pj4oZCkuY291bnQoKTsNCn0NCg0Kc3RhdGljIGNvbnN0IGNoYXIqIEFsZ29yaXRobVRvU3RyKEQzRDEyTUE6OlBPT0xfRkxBR1MgYWxnb3JpdGhtKQ0Kew0KICAgIHN3aXRjaCAoYWxnb3JpdGhtKQ0KICAgIHsNCiAgICBjYXNlIEQzRDEyTUE6OlBPT0xfRkxBR19BTEdPUklUSE1fTElORUFSOg0KICAgICAgICByZXR1cm4gIkxpbmVhciI7DQogICAgY2FzZSAwOg0KICAgICAgICByZXR1cm4gIlRMU0YiOw0KICAgIGRlZmF1bHQ6DQogICAgICAgIGFzc2VydCgwKTsNCiAgICAgICAgcmV0dXJuICIiOw0KICAgIH0NCn0NCg0Kc3RhdGljIGNvbnN0IGNoYXIqIFZpcnR1YWxBbGdvcml0aG1Ub1N0cihEM0QxMk1BOjpWSVJUVUFMX0JMT0NLX0ZMQUdTIGFsZ29yaXRobSkNCnsNCiAgICBzd2l0Y2ggKGFsZ29yaXRobSkNCiAgICB7DQogICAgY2FzZSBEM0QxMk1BOjpWSVJUVUFMX0JMT0NLX0ZMQUdfQUxHT1JJVEhNX0xJTkVBUjoNCiAgICAgICAgcmV0dXJuICJMaW5lYXIiOw0KICAgIGNhc2UgMDoNCiAgICAgICAgcmV0dXJuICJUTFNGIjsNCiAgICBkZWZhdWx0Og0KICAgICAgICBhc3NlcnQoMCk7DQogICAgICAgIHJldHVybiAiIjsNCiAgICB9DQp9DQoNCg0Kc3RydWN0IFJlc291cmNlV2l0aEFsbG9jYXRpb24NCnsNCiAgICBDb21QdHI8SUQzRDEyUmVzb3VyY2U+IHJlc291cmNlOw0KICAgIENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiBhbGxvY2F0aW9uOw0KICAgIFVJTlQ2NCBzaXplID0gVUlOVDY0X01BWDsNCiAgICBVSU5UIGRhdGFTZWVkID0gMDsNCg0KICAgIHZvaWQgUmVzZXQoKQ0KICAgIHsNCiAgICAgICAgcmVzb3VyY2UuUmVzZXQoKTsNCiAgICAgICAgYWxsb2NhdGlvbi5SZXNldCgpOw0KICAgICAgICBzaXplID0gVUlOVDY0X01BWDsNCiAgICAgICAgZGF0YVNlZWQgPSAwOw0KICAgIH0NCn07DQoNCnRlbXBsYXRlPHR5cGVuYW1lIEQzRDEyX1JFU09VUkNFX0RFU0NfVD4NCnN0YXRpYyB2b2lkIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIoRDNEMTJfUkVTT1VSQ0VfREVTQ19UJiBvdXRSZXNvdXJjZURlc2MsIFVJTlQ2NCBzaXplKQ0Kew0KICAgIG91dFJlc291cmNlRGVzYyA9IHt9Ow0KICAgIG91dFJlc291cmNlRGVzYy5EaW1lbnNpb24gPSBEM0QxMl9SRVNPVVJDRV9ESU1FTlNJT05fQlVGRkVSOw0KICAgIG91dFJlc291cmNlRGVzYy5BbGlnbm1lbnQgPSAwOw0KICAgIG91dFJlc291cmNlRGVzYy5XaWR0aCA9IHNpemU7DQogICAgb3V0UmVzb3VyY2VEZXNjLkhlaWdodCA9IDE7DQogICAgb3V0UmVzb3VyY2VEZXNjLkRlcHRoT3JBcnJheVNpemUgPSAxOw0KICAgIG91dFJlc291cmNlRGVzYy5NaXBMZXZlbHMgPSAxOw0KICAgIG91dFJlc291cmNlRGVzYy5Gb3JtYXQgPSBEWEdJX0ZPUk1BVF9VTktOT1dOOw0KICAgIG91dFJlc291cmNlRGVzYy5TYW1wbGVEZXNjLkNvdW50ID0gMTsNCiAgICBvdXRSZXNvdXJjZURlc2MuU2FtcGxlRGVzYy5RdWFsaXR5ID0gMDsNCiAgICBvdXRSZXNvdXJjZURlc2MuTGF5b3V0ID0gRDNEMTJfVEVYVFVSRV9MQVlPVVRfUk9XX01BSk9SOw0KICAgIG91dFJlc291cmNlRGVzYy5GbGFncyA9IEQzRDEyX1JFU09VUkNFX0ZMQUdfTk9ORTsNCn0NCg0Kc3RhdGljIHZvaWQgRmlsbERhdGEodm9pZCogb3V0UHRyLCBjb25zdCBVSU5UNjQgc2l6ZUluQnl0ZXMsIFVJTlQgc2VlZCkNCnsNCiAgICBVSU5UKiBvdXRWYWx1ZXMgPSAoVUlOVCopb3V0UHRyOw0KICAgIGNvbnN0IFVJTlQ2NCBzaXplSW5WYWx1ZXMgPSBzaXplSW5CeXRlcyAvIHNpemVvZihVSU5UKTsNCiAgICBVSU5UIHZhbHVlID0gc2VlZDsNCiAgICBmb3IoVUlOVCBpID0gMDsgaSA8IHNpemVJblZhbHVlczsgKytpKQ0KICAgIHsNCiAgICAgICAgb3V0VmFsdWVzW2ldID0gdmFsdWUrKzsNCiAgICB9DQp9DQoNCnN0YXRpYyBib29sIFZhbGlkYXRlRGF0YShjb25zdCB2b2lkKiBwdHIsIGNvbnN0IFVJTlQ2NCBzaXplSW5CeXRlcywgVUlOVCBzZWVkKQ0Kew0KICAgIGNvbnN0IFVJTlQqIHZhbHVlcyA9IChjb25zdCBVSU5UKilwdHI7DQogICAgY29uc3QgVUlOVDY0IHNpemVJblZhbHVlcyA9IHNpemVJbkJ5dGVzIC8gc2l6ZW9mKFVJTlQpOw0KICAgIFVJTlQgdmFsdWUgPSBzZWVkOw0KICAgIGZvcihVSU5UIGkgPSAwOyBpIDwgc2l6ZUluVmFsdWVzOyArK2kpDQogICAgew0KICAgICAgICBpZih2YWx1ZXNbaV0gIT0gdmFsdWUrKykNCiAgICAgICAgew0KICAgICAgICAgICAgLy9DSEVDS19CT09MKDAgJiYgIlZhbGlkYXRlRGF0YSBmYWlsZWQuIik7DQogICAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgIH0NCiAgICB9DQogICAgcmV0dXJuIHRydWU7DQp9DQoNCnN0YXRpYyBib29sIFZhbGlkYXRlRGF0YVplcm8oY29uc3Qgdm9pZCogcHRyLCBjb25zdCBVSU5UNjQgc2l6ZUluQnl0ZXMpDQp7DQogICAgY29uc3QgVUlOVCogdmFsdWVzID0gKGNvbnN0IFVJTlQqKXB0cjsNCiAgICBjb25zdCBVSU5UNjQgc2l6ZUluVmFsdWVzID0gc2l6ZUluQnl0ZXMgLyBzaXplb2YoVUlOVCk7DQogICAgZm9yKFVJTlQgaSA9IDA7IGkgPCBzaXplSW5WYWx1ZXM7ICsraSkNCiAgICB7DQogICAgICAgIGlmKHZhbHVlc1tpXSAhPSAwKQ0KICAgICAgICB7DQogICAgICAgICAgICAvL0NIRUNLX0JPT0woMCAmJiAiVmFsaWRhdGVEYXRhIGZhaWxlZC4iKTsNCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gdHJ1ZTsNCn0NCg0Kc3RhdGljIHZvaWQgU2F2ZVN0YXRzU3RyaW5nVG9GaWxlKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgsIGNvbnN0IHdjaGFyX3QqIGRzdEZpbGVQYXRoKQ0Kew0KICAgIFdDSEFSKiBzID0gbnVsbHB0cjsNCiAgICBjdHguYWxsb2NhdG9yLT5CdWlsZFN0YXRzU3RyaW5nKCZzLCBUUlVFKTsNCiAgICBTYXZlRmlsZShkc3RGaWxlUGF0aCwgcywgd2NzbGVuKHMpICogc2l6ZW9mKFdDSEFSKSk7DQogICAgY3R4LmFsbG9jYXRvci0+RnJlZVN0YXRzU3RyaW5nKHMpOw0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0RGVidWdNYXJnaW4oY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICB1c2luZyBuYW1lc3BhY2UgRDNEMTJNQTsNCg0KICAgIGlmKEQzRDEyTUFfREVCVUdfTUFSR0lOID09IDApDQogICAgew0KICAgICAgICByZXR1cm47DQogICAgfQ0KDQogICAgd3ByaW50ZihMIlRlc3QgRDNEMTJNQV9ERUJVR19NQVJHSU4gPSAldVxuIiwgKHVpbnQzMl90KUQzRDEyTUFfREVCVUdfTUFSR0lOKTsNCg0KICAgIEFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzRGVzYyA9IHt9Ow0KDQogICAgUE9PTF9ERVNDIHBvb2xEZXNjID0ge307DQogICAgcG9vbERlc2MuSGVhcFByb3BlcnRpZXMuVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9VUExPQUQ7DQoNCiAgICBmb3Ioc2l6ZV90IGFsZ29yaXRobUluZGV4ID0gMDsgYWxnb3JpdGhtSW5kZXggPCAyOyArK2FsZ29yaXRobUluZGV4KQ0KICAgIHsNCiAgICAgICAgc3dpdGNoKGFsZ29yaXRobUluZGV4KQ0KICAgICAgICB7DQogICAgICAgIGNhc2UgMDogcG9vbERlc2MuRmxhZ3MgPSBQT09MX0ZMQUdfTk9ORTsgYnJlYWs7DQogICAgICAgIGNhc2UgMTogcG9vbERlc2MuRmxhZ3MgPSBQT09MX0ZMQUdfQUxHT1JJVEhNX0xJTkVBUjsgYnJlYWs7DQogICAgICAgIGRlZmF1bHQ6IGFzc2VydCgwKTsNCiAgICAgICAgfQ0KICAgICAgICBDb21QdHI8UG9vbD4gcG9vbDsNCiAgICAgICAgQ0hFQ0tfSFIoY3R4LmFsbG9jYXRvci0+Q3JlYXRlUG9vbCgmcG9vbERlc2MsICZwb29sKSk7DQoNCiAgICAgICAgYWxsb2NEZXNjLkN1c3RvbVBvb2wgPSBwb29sLkdldCgpOw0KDQogICAgICAgIC8vIENyZWF0ZSBmZXcgYnVmZmVycyBvZiBkaWZmZXJlbnQgc2l6ZS4NCiAgICAgICAgY29uc3Qgc2l6ZV90IEJVRl9DT1VOVCA9IDEwOw0KICAgICAgICBDb21QdHI8QWxsb2NhdGlvbj4gYnVmZmVyc1tCVUZfQ09VTlRdOw0KICAgICAgICBmb3Ioc2l6ZV90IGFsbG9jSW5kZXggPSAwOyBhbGxvY0luZGV4IDwgMTA7ICsrYWxsb2NJbmRleCkNCiAgICAgICAgew0KICAgICAgICAgICAgY29uc3QgYm9vbCBpc0xhc3QgPSBhbGxvY0luZGV4ID09IEJVRl9DT1VOVCAtIDE7DQogICAgICAgICAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc0Rlc2MsIChVSU5UNjQpKGFsbG9jSW5kZXggKyAxKSAqIDB4MTAwMDApOw0KDQogICAgICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgNCiAgICAgICAgICAgICAgICAmYWxsb2NEZXNjLA0KICAgICAgICAgICAgICAgICZyZXNEZXNjLA0KICAgICAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0dFTkVSSUNfUkVBRCwNCiAgICAgICAgICAgICAgICBudWxscHRyLA0KICAgICAgICAgICAgICAgICZidWZmZXJzW2FsbG9jSW5kZXhdLA0KICAgICAgICAgICAgICAgIElJRF9OVUxMLCBudWxscHRyKSk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBKU09OIGR1bXANCiAgICAgICAgd2NoYXJfdCoganNvbiA9IG51bGxwdHI7DQogICAgICAgIGN0eC5hbGxvY2F0b3ItPkJ1aWxkU3RhdHNTdHJpbmcoJmpzb24sIFRSVUUpOw0KICAgICAgICBpbnQgSSA9IDE7IC8vIFB1dCBicmVha3BvaW50IGhlcmUgdG8gbWFudWFsbHkgaW5zcGVjdCBqc29uIGluIGEgZGVidWdnZXIuDQoNCiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlaXIgb2Zmc2V0cyBwcmVzZXJ2ZSBtYXJnaW4gYmV0d2VlbiB0aGVtLg0KICAgICAgICBzdGQ6OnNvcnQoYnVmZmVycywgYnVmZmVycyArIEJVRl9DT1VOVCwgW10oY29uc3QgQ29tUHRyPEFsbG9jYXRpb24+JiBsaHMsIGNvbnN0IENvbVB0cjxBbGxvY2F0aW9uPiYgcmhzKSAtPiBib29sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaWYobGhzLT5HZXRIZWFwKCkgIT0gcmhzLT5HZXRIZWFwKCkpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGhzLT5HZXRIZWFwKCkgPCByaHMtPkdldEhlYXAoKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgcmV0dXJuIGxocy0+R2V0T2Zmc2V0KCkgPCByaHMtPkdldE9mZnNldCgpOw0KICAgICAgICAgICAgfSk7DQogICAgICAgIGZvcihzaXplX3QgaSA9IDE7IGkgPCBCVUZfQ09VTlQ7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgaWYoYnVmZmVyc1tpXS0+R2V0SGVhcCgpID09IGJ1ZmZlcnNbaSAtIDFdLT5HZXRIZWFwKCkpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgY29uc3QgVUlOVDY0IGFsbG9jU3RhcnQgPSBidWZmZXJzW2ldLT5HZXRPZmZzZXQoKTsNCiAgICAgICAgICAgICAgICBjb25zdCBVSU5UNjQgcHJldkFsbG9jRW5kID0gYnVmZmVyc1tpIC0gMV0tPkdldE9mZnNldCgpICsgYnVmZmVyc1tpIC0gMV0tPkdldFNpemUoKTsNCiAgICAgICAgICAgICAgICBDSEVDS19CT09MKGFsbG9jU3RhcnQgPj0gcHJldkFsbG9jRW5kICsgRDNEMTJNQV9ERUJVR19NQVJHSU4pOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgY3R4LmFsbG9jYXRvci0+RnJlZVN0YXRzU3RyaW5nKGpzb24pOw0KICAgIH0NCn0NCg0Kc3RhdGljIHZvaWQgVGVzdERlYnVnTWFyZ2luTm90SW5WaXJ0dWFsQWxsb2NhdG9yKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgRDNEMTJNQV9ERUJVR19NQVJHSU4gbm90IGFwcGxpZWQgdG8gdmlydHVhbCBhbGxvY2F0b3JcbiIpOw0KICAgIHVzaW5nIG5hbWVzcGFjZSBEM0QxMk1BOw0KICAgIGNvbnN0ZXhwciBzaXplX3QgQUxMT0NBVElPTl9DT1VOVCA9IDEwOw0KICAgIGZvcihzaXplX3QgYWxnb3JpdGhtSW5kZXggPSAwOyBhbGdvcml0aG1JbmRleCA8IDI7ICsrYWxnb3JpdGhtSW5kZXgpDQogICAgew0KICAgICAgICBWSVJUVUFMX0JMT0NLX0RFU0MgYmxvY2tEZXNjID0ge307DQogICAgICAgIGJsb2NrRGVzYy5TaXplID0gQUxMT0NBVElPTl9DT1VOVCAqIE1FR0FCWVRFOw0KICAgICAgICBzd2l0Y2goYWxnb3JpdGhtSW5kZXgpDQogICAgICAgIHsNCiAgICAgICAgY2FzZSAwOiBibG9ja0Rlc2MuRmxhZ3MgPSBWSVJUVUFMX0JMT0NLX0ZMQUdfTk9ORTsgYnJlYWs7DQogICAgICAgIGNhc2UgMTogYmxvY2tEZXNjLkZsYWdzID0gVklSVFVBTF9CTE9DS19GTEFHX0FMR09SSVRITV9MSU5FQVI7IGJyZWFrOw0KICAgICAgICBkZWZhdWx0OiBhc3NlcnQoMCk7DQogICAgICAgIH0NCg0KICAgICAgICBDb21QdHI8VmlydHVhbEJsb2NrPiBibG9jazsNCiAgICAgICAgQ0hFQ0tfSFIoQ3JlYXRlVmlydHVhbEJsb2NrKCZibG9ja0Rlc2MsICZibG9jaykpOw0KDQogICAgICAgIC8vIEZpbGwgdGhlIGVudGlyZSBibG9jaw0KICAgICAgICBWaXJ0dWFsQWxsb2NhdGlvbiBhbGxvY3NbQUxMT0NBVElPTl9DT1VOVF07DQogICAgICAgIGZvcihzaXplX3QgaSA9IDA7IGkgPCBBTExPQ0FUSU9OX0NPVU5UOyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIFZJUlRVQUxfQUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgICAgICAgICAgYWxsb2NEZXNjLlNpemUgPSAxICogTUVHQUJZVEU7DQogICAgICAgICAgICBDSEVDS19IUihibG9jay0+QWxsb2NhdGUoJmFsbG9jRGVzYywgJmFsbG9jc1tpXSwgbnVsbHB0cikpOw0KICAgICAgICB9DQoNCiAgICAgICAgYmxvY2stPkNsZWFyKCk7DQogICAgfQ0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0RnJhbWVJbmRleEFuZEpzb24oY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICBjb25zdCBVSU5UNjQgYnVmU2l6ZSA9IDMydWxsICogMTAyNDsNCg0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfVVBMT0FEOw0KICAgIGFsbG9jRGVzYy5GbGFncyA9IEQzRDEyTUE6OkFMTE9DQVRJT05fRkxBR19DT01NSVRURUQ7DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc291cmNlRGVzYzsNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc291cmNlRGVzYywgYnVmU2l6ZSk7DQoNCiAgICBjb25zdCBVSU5UIEJFR0lOX0lOREVYID0gMTA7DQogICAgY29uc3QgVUlOVCBFTkRfSU5ERVggPSAyMDsNCiAgICBmb3IgKFVJTlQgZnJhbWVJbmRleCA9IEJFR0lOX0lOREVYOyBmcmFtZUluZGV4IDwgRU5EX0lOREVYOyArK2ZyYW1lSW5kZXgpDQogICAgew0KICAgICAgICBjdHguYWxsb2NhdG9yLT5TZXRDdXJyZW50RnJhbWVJbmRleChmcmFtZUluZGV4KTsNCiAgICAgICAgRDNEMTJNQTo6QWxsb2NhdGlvbiogYWxsb2MgPSBudWxscHRyOw0KICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgNCiAgICAgICAgICAgICZhbGxvY0Rlc2MsDQogICAgICAgICAgICAmcmVzb3VyY2VEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfR0VORVJJQ19SRUFELA0KICAgICAgICAgICAgTlVMTCwNCiAgICAgICAgICAgICZhbGxvYywNCiAgICAgICAgICAgIElJRF9OVUxMLA0KICAgICAgICAgICAgTlVMTCkpOw0KDQogICAgICAgIFdDSEFSKiBzdGF0c1N0cmluZzsNCiAgICAgICAgY3R4LmFsbG9jYXRvci0+QnVpbGRTdGF0c1N0cmluZygmc3RhdHNTdHJpbmcsIFRSVUUpOw0KICAgICAgICBjb25zdCBVSU5UIEJVRkZFUl9TSVpFID0gMTAyNDsNCiAgICAgICAgV0NIQVIgYnVmZmVyW0JVRkZFUl9TSVpFXTsNCiAgICAgICAgZm9yIChVSU5UIHRlc3RJbmRleCA9IEJFR0lOX0lOREVYOyB0ZXN0SW5kZXggPCBFTkRfSU5ERVg7ICsrdGVzdEluZGV4KQ0KICAgICAgICB7DQogICAgICAgICAgICBzd3ByaW50ZihidWZmZXIsIEJVRkZFUl9TSVpFLCBMIlwiQ3JlYXRpb25GcmFtZUluZGV4XCI6ICV1IiwgdGVzdEluZGV4KTsNCiAgICAgICAgICAgIGlmICh0ZXN0SW5kZXggPT0gZnJhbWVJbmRleCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBDSEVDS19CT09MKHdjc3N0cihzdGF0c1N0cmluZywgYnVmZmVyKSAhPSBOVUxMKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBDSEVDS19CT09MKHdjc3N0cihzdGF0c1N0cmluZywgYnVmZmVyKSA9PSBOVUxMKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBjdHguYWxsb2NhdG9yLT5GcmVlU3RhdHNTdHJpbmcoc3RhdHNTdHJpbmcpOw0KICAgICAgICBhbGxvYy0+UmVsZWFzZSgpOw0KICAgIH0NCn0NCg0Kc3RhdGljIHZvaWQgVGVzdENvbW1pdHRlZFJlc291cmNlc0FuZEpzb24oY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICB3cHJpbnRmKEwiVGVzdCBjb21taXR0ZWQgcmVzb3VyY2VzIGFuZCBKU09OXG4iKTsNCiAgICANCiAgICBjb25zdCBVSU5UIGNvdW50ID0gNDsNCiAgICBjb25zdCBVSU5UNjQgYnVmU2l6ZSA9IDMydWxsICogMTAyNDsNCiAgICBjb25zdCB3Y2hhcl90KiBuYW1lc1tjb3VudF0gPSB7DQogICAgICAgIEwiUmVzb3VyY2VcbkZvb1xyXG5CYXIiLA0KICAgICAgICBMIlJlc291cmNlIFwiJyY8Pj8jQCEmLT1fK1tde307OiwuL1xcIiwNCiAgICAgICAgbnVsbHB0ciwNCiAgICAgICAgTCIiLA0KICAgIH07DQoNCiAgICBSZXNvdXJjZVdpdGhBbGxvY2F0aW9uIHJlc291cmNlc1tjb3VudF07DQoNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgYWxsb2NEZXNjLkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQogICAgYWxsb2NEZXNjLkZsYWdzID0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX0NPTU1JVFRFRDsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzb3VyY2VEZXNjOw0KICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzb3VyY2VEZXNjLCBidWZTaXplKTsNCg0KICAgIGZvcihVSU5UIGkgPSAwOyBpIDwgY291bnQ7ICsraSkNCiAgICB7DQogICAgICAgIGNvbnN0IGJvb2wgcmVjZWl2ZUV4cGxpY2l0UmVzb3VyY2UgPSBpIDwgMjsNCg0KICAgICAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoDQogICAgICAgICAgICAmYWxsb2NEZXNjLA0KICAgICAgICAgICAgJnJlc291cmNlRGVzYywNCiAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPUFlfREVTVCwNCiAgICAgICAgICAgIE5VTEwsDQogICAgICAgICAgICAmcmVzb3VyY2VzW2ldLmFsbG9jYXRpb24sDQogICAgICAgICAgICBfX3V1aWRvZihJRDNEMTJSZXNvdXJjZSksDQogICAgICAgICAgICByZWNlaXZlRXhwbGljaXRSZXNvdXJjZSA/ICh2b2lkKiopJnJlc291cmNlc1tpXS5yZXNvdXJjZSA6IE5VTEwpKTsNCg0KICAgICAgICBpZihyZWNlaXZlRXhwbGljaXRSZXNvdXJjZSkNCiAgICAgICAgew0KICAgICAgICAgICAgSUQzRDEyUmVzb3VyY2UqIHJlcyA9IHJlc291cmNlc1tpXS5yZXNvdXJjZS5HZXQoKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0wocmVzICYmIHJlcyA9PSByZXNvdXJjZXNbaV0uYWxsb2NhdGlvbi0+R2V0UmVzb3VyY2UoKSk7DQogICAgICAgICAgICBjb25zdCBVTE9ORyByZWZDb3VudEFmdGVyQWRkID0gcmVzLT5BZGRSZWYoKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0wocmVmQ291bnRBZnRlckFkZCA9PSAzKTsNCiAgICAgICAgICAgIHJlcy0+UmVsZWFzZSgpOw0KICAgICAgICB9DQogICAgICAgIA0KICAgICAgICAvLyBNYWtlIHN1cmUgaXQgaGFzIGltcGxpY2l0IGhlYXAuDQogICAgICAgIENIRUNLX0JPT0woIHJlc291cmNlc1tpXS5hbGxvY2F0aW9uLT5HZXRIZWFwKCkgPT0gTlVMTCAmJiByZXNvdXJjZXNbaV0uYWxsb2NhdGlvbi0+R2V0T2Zmc2V0KCkgPT0gMCApOw0KDQogICAgICAgIHJlc291cmNlc1tpXS5hbGxvY2F0aW9uLT5TZXROYW1lKG5hbWVzW2ldKTsNCiAgICB9DQoNCiAgICAvLyBDaGVjayBuYW1lcy4NCiAgICBmb3IoVUlOVCBpID0gMDsgaSA8IGNvdW50OyArK2kpDQogICAgew0KICAgICAgICBjb25zdCB3Y2hhcl90KiBjb25zdCBhbGxvY05hbWUgPSByZXNvdXJjZXNbaV0uYWxsb2NhdGlvbi0+R2V0TmFtZSgpOw0KICAgICAgICBpZihhbGxvY05hbWUpDQogICAgICAgIHsNCiAgICAgICAgICAgIENIRUNLX0JPT0woIHdjc2NtcChhbGxvY05hbWUsIG5hbWVzW2ldKSA9PSAwICk7DQogICAgICAgIH0NCiAgICAgICAgZWxzZQ0KICAgICAgICB7DQogICAgICAgICAgICBDSEVDS19CT09MKG5hbWVzW2ldID09IE5VTEwpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgV0NIQVIqIGpzb25TdHJpbmc7DQogICAgY3R4LmFsbG9jYXRvci0+QnVpbGRTdGF0c1N0cmluZygmanNvblN0cmluZywgVFJVRSk7DQogICAgQ0hFQ0tfQk9PTCh3Y3NzdHIoanNvblN0cmluZywgTCJcIlJlc291cmNlXFxuRm9vXFxyXFxuQmFyXCIiKSAhPSBOVUxMKTsNCiAgICBDSEVDS19CT09MKHdjc3N0cihqc29uU3RyaW5nLCBMIlwiUmVzb3VyY2UgXFxcIicmPD4/I0AhJi09XytbXXt9OzosLlxcL1xcXFxcIiIpICE9IE5VTEwpOw0KICAgIENIRUNLX0JPT0wod2Nzc3RyKGpzb25TdHJpbmcsIEwiXCJcIiIpICE9IE5VTEwpOw0KICAgIGN0eC5hbGxvY2F0b3ItPkZyZWVTdGF0c1N0cmluZyhqc29uU3RyaW5nKTsNCn0NCg0Kc3RhdGljIHZvaWQgVGVzdEN1c3RvbUhlYXBGbGFncyhjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IGN1c3RvbSBoZWFwIGZsYWdzXG4iKTsNCg0KICAgIC8vIDEuIEp1c3QgbWVtb3J5IGhlYXAgd2l0aCBjdXN0b20gZmxhZ3MNCiAgICB7DQogICAgICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICAgICAgYWxsb2NEZXNjLkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQogICAgICAgIGFsbG9jRGVzYy5FeHRyYUhlYXBGbGFncyA9IEQzRDEyX0hFQVBfRkxBR19BTExPV19PTkxZX05PTl9SVF9EU19URVhUVVJFUyB8DQogICAgICAgICAgICBEM0QxMl9IRUFQX0ZMQUdfU0hBUkVEOyAvLyBFeHRyYSBmbGFnLg0KDQogICAgICAgIEQzRDEyX1JFU09VUkNFX0FMTE9DQVRJT05fSU5GTyByZXNBbGxvY0luZm8gPSB7fTsNCiAgICAgICAgcmVzQWxsb2NJbmZvLlNpemVJbkJ5dGVzID0gRDNEMTJfREVGQVVMVF9SRVNPVVJDRV9QTEFDRU1FTlRfQUxJR05NRU5UOw0KICAgICAgICByZXNBbGxvY0luZm8uQWxpZ25tZW50ID0gRDNEMTJfREVGQVVMVF9SRVNPVVJDRV9QTEFDRU1FTlRfQUxJR05NRU5UOw0KDQogICAgICAgIFJlc291cmNlV2l0aEFsbG9jYXRpb24gcmVzOw0KICAgICAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+QWxsb2NhdGVNZW1vcnkoJmFsbG9jRGVzYywgJnJlc0FsbG9jSW5mbywgJnJlcy5hbGxvY2F0aW9uKSApOw0KDQogICAgICAgIC8vIE11c3QgYmUgY3JlYXRlZCBhcyBzZXBhcmF0ZSBhbGxvY2F0aW9uLg0KICAgICAgICBDSEVDS19CT09MKCByZXMuYWxsb2NhdGlvbi0+R2V0T2Zmc2V0KCkgPT0gMCApOw0KICAgIH0NCg0KICAgIC8vIDIuIENvbW1pdHRlZCByZXNvdXJjZSB3aXRoIGN1c3RvbSBmbGFncw0KICAgIHsNCiAgICAgICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNvdXJjZURlc2MgPSB7fTsNCiAgICAgICAgcmVzb3VyY2VEZXNjLkRpbWVuc2lvbiA9IEQzRDEyX1JFU09VUkNFX0RJTUVOU0lPTl9URVhUVVJFMkQ7DQogICAgICAgIHJlc291cmNlRGVzYy5BbGlnbm1lbnQgPSAwOw0KICAgICAgICByZXNvdXJjZURlc2MuV2lkdGggPSAxOTIwOw0KICAgICAgICByZXNvdXJjZURlc2MuSGVpZ2h0ID0gMTA4MDsNCiAgICAgICAgcmVzb3VyY2VEZXNjLkRlcHRoT3JBcnJheVNpemUgPSAxOw0KICAgICAgICByZXNvdXJjZURlc2MuTWlwTGV2ZWxzID0gMTsNCiAgICAgICAgcmVzb3VyY2VEZXNjLkZvcm1hdCA9IERYR0lfRk9STUFUX1I4RzhCOEE4X1VOT1JNOw0KICAgICAgICByZXNvdXJjZURlc2MuU2FtcGxlRGVzYy5Db3VudCA9IDE7DQogICAgICAgIHJlc291cmNlRGVzYy5TYW1wbGVEZXNjLlF1YWxpdHkgPSAwOw0KICAgICAgICByZXNvdXJjZURlc2MuTGF5b3V0ID0gRDNEMTJfVEVYVFVSRV9MQVlPVVRfUk9XX01BSk9SOw0KICAgICAgICByZXNvdXJjZURlc2MuRmxhZ3MgPSBEM0QxMl9SRVNPVVJDRV9GTEFHX0FMTE9XX0NST1NTX0FEQVBURVI7DQoNCiAgICAgICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgICAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICAgICAgYWxsb2NEZXNjLkV4dHJhSGVhcEZsYWdzID0gRDNEMTJfSEVBUF9GTEFHX1NIQVJFRCB8IEQzRDEyX0hFQVBfRkxBR19TSEFSRURfQ1JPU1NfQURBUFRFUjsgLy8gRXh0cmEgZmxhZ3MuDQoNCiAgICAgICAgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiByZXM7DQogICAgICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgNCiAgICAgICAgICAgICZhbGxvY0Rlc2MsDQogICAgICAgICAgICAmcmVzb3VyY2VEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09NTU9OLA0KICAgICAgICAgICAgTlVMTCwNCiAgICAgICAgICAgICZyZXMuYWxsb2NhdGlvbiwNCiAgICAgICAgICAgIElJRF9QUFZfQVJHUygmcmVzLnJlc291cmNlKSkgKTsNCg0KICAgICAgICAvLyBNdXN0IGJlIGNyZWF0ZWQgYXMgY29tbWl0dGVkLg0KICAgICAgICBDSEVDS19CT09MKCByZXMuYWxsb2NhdGlvbi0+R2V0SGVhcCgpID09IE5VTEwgKTsNCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RQbGFjZWRSZXNvdXJjZXMoY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICB3cHJpbnRmKEwiVGVzdCBwbGFjZWQgcmVzb3VyY2VzXG4iKTsNCg0KICAgIGNvbnN0IGJvb2wgYWx3YXlzQ29tbWl0dGVkID0gKGN0eC5hbGxvY2F0b3JGbGFncyAmIEQzRDEyTUE6OkFMTE9DQVRPUl9GTEFHX0FMV0FZU19DT01NSVRURUQpICE9IDA7DQoNCiAgICBjb25zdCBVSU5UIGNvdW50ID0gNDsNCiAgICBjb25zdCBVSU5UNjQgYnVmU2l6ZSA9IDMydWxsICogMTAyNDsNCiAgICBSZXNvdXJjZVdpdGhBbGxvY2F0aW9uIHJlc291cmNlc1tjb3VudF07DQoNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgYWxsb2NEZXNjLkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc291cmNlRGVzYzsNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc291cmNlRGVzYywgYnVmU2l6ZSk7DQoNCiAgICBmb3IoVUlOVCBpID0gMDsgaSA8IGNvdW50OyArK2kpDQogICAgew0KICAgICAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoDQogICAgICAgICAgICAmYWxsb2NEZXNjLA0KICAgICAgICAgICAgJnJlc291cmNlRGVzYywNCiAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0dFTkVSSUNfUkVBRCwNCiAgICAgICAgICAgIE5VTEwsDQogICAgICAgICAgICAmcmVzb3VyY2VzW2ldLmFsbG9jYXRpb24sDQogICAgICAgICAgICBJSURfUFBWX0FSR1MoJnJlc291cmNlc1tpXS5yZXNvdXJjZSkpICk7DQoNCiAgICAgICAgLy8gTWFrZSBzdXJlIGl0IGRvZXNuJ3QgaGF2ZSBpbXBsaWNpdCBoZWFwLg0KICAgICAgICBpZighYWx3YXlzQ29tbWl0dGVkKQ0KICAgICAgICB7DQogICAgICAgICAgICBDSEVDS19CT09MKCByZXNvdXJjZXNbaV0uYWxsb2NhdGlvbi0+R2V0SGVhcCgpICE9IE5VTEwgKTsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIC8vIE1ha2Ugc3VyZSBhdCBsZWFzdCBzb21lIG9mIHRoZSByZXNvdXJjZXMgYmVsb25nIHRvIHRoZSBzYW1lIGhlYXAsIGJ1dCB0aGVpciBtZW1vcnkgcmFuZ2VzIGRvbid0IG92ZXJsYXAuDQogICAgYm9vbCBzYW1lSGVhcEZvdW5kID0gZmFsc2U7DQogICAgZm9yKHNpemVfdCBpID0gMDsgaSA8IGNvdW50OyArK2kpDQogICAgew0KICAgICAgICBmb3Ioc2l6ZV90IGogPSBpICsgMTsgaiA8IGNvdW50OyArK2opDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbnN0IFJlc291cmNlV2l0aEFsbG9jYXRpb24mIHJlc0kgPSByZXNvdXJjZXNbaV07DQogICAgICAgICAgICBjb25zdCBSZXNvdXJjZVdpdGhBbGxvY2F0aW9uJiByZXNKID0gcmVzb3VyY2VzW2pdOw0KICAgICAgICAgICAgaWYocmVzSS5hbGxvY2F0aW9uLT5HZXRIZWFwKCkgIT0gTlVMTCAmJg0KICAgICAgICAgICAgICAgIHJlc0kuYWxsb2NhdGlvbi0+R2V0SGVhcCgpID09IHJlc0ouYWxsb2NhdGlvbi0+R2V0SGVhcCgpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHNhbWVIZWFwRm91bmQgPSB0cnVlOw0KICAgICAgICAgICAgICAgIENIRUNLX0JPT0wocmVzSS5hbGxvY2F0aW9uLT5HZXRPZmZzZXQoKSArIHJlc0kuYWxsb2NhdGlvbi0+R2V0U2l6ZSgpIDw9IHJlc0ouYWxsb2NhdGlvbi0+R2V0T2Zmc2V0KCkgfHwNCiAgICAgICAgICAgICAgICAgICAgcmVzSi5hbGxvY2F0aW9uLT5HZXRPZmZzZXQoKSArIHJlc0ouYWxsb2NhdGlvbi0+R2V0U2l6ZSgpIDw9IHJlc0kuYWxsb2NhdGlvbi0+R2V0T2Zmc2V0KCkpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfQ0KICAgIGlmKCFhbHdheXNDb21taXR0ZWQpDQogICAgew0KICAgICAgICBDSEVDS19CT09MKHNhbWVIZWFwRm91bmQpOw0KICAgIH0NCg0KICAgIC8vIEFkZGl0aW9uYWxseSBjcmVhdGUgYSB0ZXh0dXJlIHRvIHNlZSBpZiBubyBlcnJvciBvY2N1cnMgZHVlIHRvIGJhZCBoYW5kbGluZyBvZiBSZXNvdXJjZSBUaWVyLg0KICAgIHJlc291cmNlRGVzYyA9IHt9Ow0KICAgIHJlc291cmNlRGVzYy5EaW1lbnNpb24gPSBEM0QxMl9SRVNPVVJDRV9ESU1FTlNJT05fVEVYVFVSRTJEOw0KICAgIHJlc291cmNlRGVzYy5BbGlnbm1lbnQgPSAwOw0KICAgIHJlc291cmNlRGVzYy5XaWR0aCA9IDEwMjQ7DQogICAgcmVzb3VyY2VEZXNjLkhlaWdodCA9IDEwMjQ7DQogICAgcmVzb3VyY2VEZXNjLkRlcHRoT3JBcnJheVNpemUgPSAxOw0KICAgIHJlc291cmNlRGVzYy5NaXBMZXZlbHMgPSAxOw0KICAgIHJlc291cmNlRGVzYy5Gb3JtYXQgPSBEWEdJX0ZPUk1BVF9SOEc4QjhBOF9VTk9STTsNCiAgICByZXNvdXJjZURlc2MuU2FtcGxlRGVzYy5Db3VudCA9IDE7DQogICAgcmVzb3VyY2VEZXNjLlNhbXBsZURlc2MuUXVhbGl0eSA9IDA7DQogICAgcmVzb3VyY2VEZXNjLkxheW91dCA9IEQzRDEyX1RFWFRVUkVfTEFZT1VUX1VOS05PV047DQogICAgcmVzb3VyY2VEZXNjLkZsYWdzID0gRDNEMTJfUkVTT1VSQ0VfRkxBR19OT05FOw0KICAgIFJlc291cmNlV2l0aEFsbG9jYXRpb24gdGV4dHVyZVJlczsNCiAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoDQogICAgICAgICZhbGxvY0Rlc2MsDQogICAgICAgICZyZXNvdXJjZURlc2MsDQogICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPUFlfREVTVCwNCiAgICAgICAgTlVMTCwNCiAgICAgICAgJnRleHR1cmVSZXMuYWxsb2NhdGlvbiwNCiAgICAgICAgSUlEX1BQVl9BUkdTKCZ0ZXh0dXJlUmVzLnJlc291cmNlKSkgKTsNCiAgICANCiAgICAvLyBBZGRpdGlvbmFsbHkgY3JlYXRlIGFuIE1TQUEgcmVuZGVyIHRhcmdldCB0byBzZWUgaWYgbm8gZXJyb3Igb2NjdXJzIGR1ZSB0byBiYWQgaGFuZGxpbmcgb2YgUmVzb3VyY2UgVGllci4NCiAgICByZXNvdXJjZURlc2MgPSB7fTsNCiAgICByZXNvdXJjZURlc2MuRGltZW5zaW9uID0gRDNEMTJfUkVTT1VSQ0VfRElNRU5TSU9OX1RFWFRVUkUyRDsNCiAgICByZXNvdXJjZURlc2MuQWxpZ25tZW50ID0gMDsNCiAgICByZXNvdXJjZURlc2MuV2lkdGggPSAxOTIwOw0KICAgIHJlc291cmNlRGVzYy5IZWlnaHQgPSAxMDgwOw0KICAgIHJlc291cmNlRGVzYy5EZXB0aE9yQXJyYXlTaXplID0gMTsNCiAgICByZXNvdXJjZURlc2MuTWlwTGV2ZWxzID0gMTsNCiAgICByZXNvdXJjZURlc2MuRm9ybWF0ID0gRFhHSV9GT1JNQVRfUjhHOEI4QThfVU5PUk07DQogICAgcmVzb3VyY2VEZXNjLlNhbXBsZURlc2MuQ291bnQgPSAyOw0KICAgIHJlc291cmNlRGVzYy5TYW1wbGVEZXNjLlF1YWxpdHkgPSAwOw0KICAgIHJlc291cmNlRGVzYy5MYXlvdXQgPSBEM0QxMl9URVhUVVJFX0xBWU9VVF9VTktOT1dOOw0KICAgIHJlc291cmNlRGVzYy5GbGFncyA9IEQzRDEyX1JFU09VUkNFX0ZMQUdfQUxMT1dfUkVOREVSX1RBUkdFVDsNCiAgICBSZXNvdXJjZVdpdGhBbGxvY2F0aW9uIHJlbmRlclRhcmdldFJlczsNCiAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoDQogICAgICAgICZhbGxvY0Rlc2MsDQogICAgICAgICZyZXNvdXJjZURlc2MsDQogICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX1JFTkRFUl9UQVJHRVQsDQogICAgICAgIE5VTEwsDQogICAgICAgICZyZW5kZXJUYXJnZXRSZXMuYWxsb2NhdGlvbiwNCiAgICAgICAgSUlEX1BQVl9BUkdTKCZyZW5kZXJUYXJnZXRSZXMucmVzb3VyY2UpKSApOw0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0T3RoZXJDb21JbnRlcmZhY2UoY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICB3cHJpbnRmKEwiVGVzdCBvdGhlciBDT00gaW50ZXJmYWNlXG4iKTsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzRGVzYzsNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc0Rlc2MsIDB4MTAwMDApOw0KDQogICAgZm9yKHVpbnQzMl90IGkgPSAwOyBpIDwgMjsgKytpKQ0KICAgIHsNCiAgICAgICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgICAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICAgICAgaWYoaSA9PSAxKQ0KICAgICAgICB7DQogICAgICAgICAgICBhbGxvY0Rlc2MuRmxhZ3MgPSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfQ09NTUlUVEVEOw0KICAgICAgICB9DQoNCiAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jOw0KICAgICAgICBDb21QdHI8SUQzRDEyUGFnZWFibGU+IHBhZ2VhYmxlOw0KICAgICAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgNCiAgICAgICAgICAgICZhbGxvY0Rlc2MsDQogICAgICAgICAgICAmcmVzRGVzYywNCiAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPTU1PTiwNCiAgICAgICAgICAgIG51bGxwdHIsIC8vIHBPcHRpbWl6ZWRDbGVhclZhbHVlDQogICAgICAgICAgICAmYWxsb2MsDQogICAgICAgICAgICBJSURfUFBWX0FSR1MoJnBhZ2VhYmxlKSkpOw0KDQogICAgICAgIC8vIERvIHNvbWV0aGluZyB3aXRoIHRoZSBpbnRlcmZhY2UgdG8gbWFrZSBzdXJlIGl0J3MgdmFsaWQuDQogICAgICAgIENvbVB0cjxJRDNEMTJEZXZpY2U+IGRldmljZTsNCiAgICAgICAgQ0hFQ0tfSFIocGFnZWFibGUtPkdldERldmljZShJSURfUFBWX0FSR1MoJmRldmljZSkpKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChkZXZpY2UuR2V0KCkgPT0gY3R4LmRldmljZSk7DQogICAgfQ0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0Q3VzdG9tUG9vbHMoY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICB3cHJpbnRmKEwiVGVzdCBjdXN0b20gcG9vbHNcbiIpOw0KDQogICAgLy8gIyBGZXRjaCBnbG9iYWwgc3RhdHMgMQ0KDQogICAgRDNEMTJNQTo6VG90YWxTdGF0aXN0aWNzIGdsb2JhbFN0YXRzQmVnID0ge307DQogICAgY3R4LmFsbG9jYXRvci0+Q2FsY3VsYXRlU3RhdGlzdGljcygmZ2xvYmFsU3RhdHNCZWcpOw0KDQogICAgLy8gIyBDcmVhdGUgcG9vbCwgMS4uMiBibG9ja3Mgb2YgMTEgTUINCiAgICANCiAgICBEM0QxMk1BOjpQT09MX0RFU0MgcG9vbERlc2MgPSB7fTsNCiAgICBwb29sRGVzYy5IZWFwUHJvcGVydGllcy5UeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQogICAgcG9vbERlc2MuSGVhcEZsYWdzID0gRDNEMTJfSEVBUF9GTEFHX0FMTE9XX09OTFlfQlVGRkVSUzsNCiAgICBwb29sRGVzYy5CbG9ja1NpemUgPSAxMSAqIE1FR0FCWVRFOw0KICAgIHBvb2xEZXNjLk1pbkJsb2NrQ291bnQgPSAxOw0KICAgIHBvb2xEZXNjLk1heEJsb2NrQ291bnQgPSAyOw0KDQogICAgQ29tUHRyPEQzRDEyTUE6OlBvb2w+IHBvb2w7DQogICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVBvb2woJnBvb2xEZXNjLCAmcG9vbCkgKTsNCg0KICAgIC8vICMgVmFsaWRhdGUgc3RhdHMgZm9yIGVtcHR5IHBvb2wNCg0KICAgIEQzRDEyTUE6OkRldGFpbGVkU3RhdGlzdGljcyBwb29sU3RhdHMgPSB7fTsNCiAgICBwb29sLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZwb29sU3RhdHMpOw0KICAgIENIRUNLX0JPT0woIHBvb2xTdGF0cy5TdGF0cy5CbG9ja0NvdW50ID09IDEgKTsNCiAgICBDSEVDS19CT09MKCBwb29sU3RhdHMuU3RhdHMuQWxsb2NhdGlvbkNvdW50ID09IDAgKTsNCiAgICBDSEVDS19CT09MKCBwb29sU3RhdHMuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzID09IDAgKTsNCiAgICBDSEVDS19CT09MKCBwb29sU3RhdHMuU3RhdHMuQmxvY2tCeXRlcyAtIHBvb2xTdGF0cy5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPT0NCiAgICAgICAgcG9vbFN0YXRzLlN0YXRzLkJsb2NrQ291bnQgKiBwb29sRGVzYy5CbG9ja1NpemUgKTsNCg0KICAgIC8vICMgU2V0TmFtZSBhbmQgR2V0TmFtZQ0KDQogICAgc3RhdGljIGNvbnN0IHdjaGFyX3QqIE5BTUUgPSBMIkN1c3RvbSBwb29sIG5hbWUgMSI7DQogICAgcG9vbC0+U2V0TmFtZShOQU1FKTsNCiAgICBDSEVDS19CT09MKCB3Y3NjbXAocG9vbC0+R2V0TmFtZSgpLCBOQU1FKSA9PSAwICk7DQoNCiAgICAvLyAjIENyZWF0ZSBidWZmZXJzIDJ4IDUgTUINCg0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuQ3VzdG9tUG9vbCA9IHBvb2wuR2V0KCk7DQogICAgYWxsb2NEZXNjLkV4dHJhSGVhcEZsYWdzID0gKEQzRDEyX0hFQVBfRkxBR1MpMHhDRENEQ0RDRDsgLy8gU2hvdWxkIGJlIGlnbm9yZWQuDQogICAgYWxsb2NEZXNjLkhlYXBUeXBlID0gKEQzRDEyX0hFQVBfVFlQRSkweENEQ0RDRENEOyAvLyBTaG91bGQgYmUgaWdub3JlZC4NCg0KICAgIGNvbnN0IFVJTlQ2NCBCVUZGRVJfU0laRSA9IDUgKiBNRUdBQllURTsNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc0Rlc2M7DQogICAgRmlsbFJlc291cmNlRGVzY0ZvckJ1ZmZlcihyZXNEZXNjLCBCVUZGRVJfU0laRSk7DQoNCiAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYWxsb2NzWzRdOw0KICAgIGZvcih1aW50MzJfdCBpID0gMDsgaSA8IDI7ICsraSkNCiAgICB7DQogICAgICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywNCiAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0dFTkVSSUNfUkVBRCwNCiAgICAgICAgICAgIE5VTEwsIC8vIHBPcHRpbWl6ZWRDbGVhclZhbHVlDQogICAgICAgICAgICAmYWxsb2NzW2ldLA0KICAgICAgICAgICAgX191dWlkb2YoSUQzRDEyUmVzb3VyY2UpLCBOVUxMKSApOyAvLyByaWlkUmVzb3VyY2UsIHBwdlJlc291cmNlDQogICAgfQ0KDQogICAgLy8gIyBWYWxpZGF0ZSBwb29sIHN0YXRzIG5vdw0KDQogICAgcG9vbC0+Q2FsY3VsYXRlU3RhdGlzdGljcygmcG9vbFN0YXRzKTsNCiAgICBDSEVDS19CT09MKCBwb29sU3RhdHMuU3RhdHMuQmxvY2tDb3VudCA9PSAxICk7DQogICAgQ0hFQ0tfQk9PTCggcG9vbFN0YXRzLlN0YXRzLkFsbG9jYXRpb25Db3VudCA9PSAyICk7DQogICAgQ0hFQ0tfQk9PTCggcG9vbFN0YXRzLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PSAyICogQlVGRkVSX1NJWkUgKTsNCiAgICBDSEVDS19CT09MKCBwb29sU3RhdHMuU3RhdHMuQmxvY2tCeXRlcyAtIHBvb2xTdGF0cy5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPT0NCiAgICAgICAgcG9vbERlc2MuQmxvY2tTaXplIC0gcG9vbFN0YXRzLlN0YXRzLkFsbG9jYXRpb25CeXRlcyApOw0KDQogICAgLy8gIyBDaGVjayB0aGF0IGdsb2JhbCBzdGF0cyBhcmUgdXBkYXRlZCBhcyB3ZWxsDQoNCiAgICBEM0QxMk1BOjpUb3RhbFN0YXRpc3RpY3MgZ2xvYmFsU3RhdHNDdXJyID0ge307DQogICAgY3R4LmFsbG9jYXRvci0+Q2FsY3VsYXRlU3RhdGlzdGljcygmZ2xvYmFsU3RhdHNDdXJyKTsNCg0KICAgIENIRUNLX0JPT0woIGdsb2JhbFN0YXRzQ3Vyci5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQ291bnQgPT0NCiAgICAgICAgZ2xvYmFsU3RhdHNCZWcuVG90YWwuU3RhdHMuQWxsb2NhdGlvbkNvdW50ICsgcG9vbFN0YXRzLlN0YXRzLkFsbG9jYXRpb25Db3VudCApOw0KICAgIENIRUNLX0JPT0woIGdsb2JhbFN0YXRzQ3Vyci5Ub3RhbC5TdGF0cy5CbG9ja0NvdW50ID09DQogICAgICAgIGdsb2JhbFN0YXRzQmVnLlRvdGFsLlN0YXRzLkJsb2NrQ291bnQgKyBwb29sU3RhdHMuU3RhdHMuQmxvY2tDb3VudCApOw0KICAgIENIRUNLX0JPT0woIGdsb2JhbFN0YXRzQ3Vyci5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPT0NCiAgICAgICAgZ2xvYmFsU3RhdHNCZWcuVG90YWwuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzICsgcG9vbFN0YXRzLlN0YXRzLkFsbG9jYXRpb25CeXRlcyApOw0KDQogICAgLy8gIyBORVZFUl9BTExPQ0FURSBhbmQgQ09NTUlUVEVEIHNob3VsZCBmYWlsDQogICAgLy8gKENvbW1pdHRlZCBhbGxvY2F0aW9ucyBub3QgYWxsb3dlZCBpbiB0aGlzIHBvb2wgYmVjYXVzZSBCbG9ja1NpemUgIT0gMC4pDQoNCiAgICBmb3IodWludDMyX3QgaSA9IDA7IGkgPCAyOyArK2kpDQogICAgew0KICAgICAgICBhbGxvY0Rlc2MuRmxhZ3MgPSBpID09IDAgPw0KICAgICAgICAgICAgRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX05FVkVSX0FMTE9DQVRFOg0KICAgICAgICAgICAgRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX0NPTU1JVFRFRDsNCiAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jOw0KICAgICAgICBjb25zdCBIUkVTVUxUIGhyID0gY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJnJlc0Rlc2MsDQogICAgICAgICAgICBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsDQogICAgICAgICAgICBOVUxMLCAvLyBwT3B0aW1pemVkQ2xlYXJWYWx1ZQ0KICAgICAgICAgICAgJmFsbG9jLA0KICAgICAgICAgICAgX191dWlkb2YoSUQzRDEyUmVzb3VyY2UpLCBOVUxMKTsgLy8gcmlpZFJlc291cmNlLCBwcHZSZXNvdXJjZQ0KICAgICAgICBDSEVDS19CT09MKCBGQUlMRUQoaHIpICk7DQogICAgfQ0KDQogICAgLy8gIyAzIG1vcmUgYnVmZmVycy4gM3JkIHNob3VsZCBmYWlsLg0KDQogICAgYWxsb2NEZXNjLkZsYWdzID0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX05PTkU7DQogICAgZm9yKHVpbnQzMl90IGkgPSAyOyBpIDwgNTsgKytpKQ0KICAgIHsNCiAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jOw0KICAgICAgICBIUkVTVUxUIGhyID0gY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJnJlc0Rlc2MsDQogICAgICAgICAgICBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsDQogICAgICAgICAgICBOVUxMLCAvLyBwT3B0aW1pemVkQ2xlYXJWYWx1ZQ0KICAgICAgICAgICAgJmFsbG9jLA0KICAgICAgICAgICAgX191dWlkb2YoSUQzRDEyUmVzb3VyY2UpLCBOVUxMKTsgLy8gcmlpZFJlc291cmNlLCBwcHZSZXNvdXJjZQ0KICAgICAgICBpZihpIDwgNCkNCiAgICAgICAgew0KICAgICAgICAgICAgQ0hFQ0tfSFIoIGhyICk7DQogICAgICAgICAgICBhbGxvY3NbaV0gPSBzdGQ6Om1vdmUoYWxsb2MpOw0KICAgICAgICB9DQogICAgICAgIGVsc2UNCiAgICAgICAgew0KICAgICAgICAgICAgQ0hFQ0tfQk9PTCggRkFJTEVEKGhyKSApOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgcG9vbC0+Q2FsY3VsYXRlU3RhdGlzdGljcygmcG9vbFN0YXRzKTsNCiAgICBDSEVDS19CT09MKCBwb29sU3RhdHMuU3RhdHMuQmxvY2tDb3VudCA9PSAyICk7DQogICAgQ0hFQ0tfQk9PTCggcG9vbFN0YXRzLlN0YXRzLkFsbG9jYXRpb25Db3VudCA9PSA0ICk7DQogICAgQ0hFQ0tfQk9PTCggcG9vbFN0YXRzLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PSA0ICogQlVGRkVSX1NJWkUgKTsNCiAgICBDSEVDS19CT09MKCBwb29sU3RhdHMuU3RhdHMuQmxvY2tCeXRlcyAtIHBvb2xTdGF0cy5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPT0NCiAgICAgICAgcG9vbFN0YXRzLlN0YXRzLkJsb2NrQ291bnQgKiBwb29sRGVzYy5CbG9ja1NpemUgLSBwb29sU3RhdHMuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzICk7DQoNCiAgICAvLyAjIE1ha2Ugcm9vbSwgQWxsb2NhdGVNZW1vcnksIENyZWF0ZUFsaWFzaW5nUmVzb3VyY2UNCg0KICAgIGFsbG9jc1szXS5SZXNldCgpOw0KICAgIGFsbG9jc1swXS5SZXNldCgpOw0KDQogICAgRDNEMTJfUkVTT1VSQ0VfQUxMT0NBVElPTl9JTkZPIHJlc0FsbG9jSW5mbyA9IHt9Ow0KICAgIHJlc0FsbG9jSW5mby5TaXplSW5CeXRlcyA9IDUgKiBNRUdBQllURTsNCiAgICByZXNBbGxvY0luZm8uQWxpZ25tZW50ID0gRDNEMTJfREVGQVVMVF9SRVNPVVJDRV9QTEFDRU1FTlRfQUxJR05NRU5UOw0KDQogICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkFsbG9jYXRlTWVtb3J5KCZhbGxvY0Rlc2MsICZyZXNBbGxvY0luZm8sICZhbGxvY3NbMF0pICk7DQoNCiAgICByZXNEZXNjLldpZHRoID0gMSAqIE1FR0FCWVRFOw0KICAgIENvbVB0cjxJRDNEMTJSZXNvdXJjZT4gcmVzOw0KICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVBbGlhc2luZ1Jlc291cmNlKGFsbG9jc1swXS5HZXQoKSwNCiAgICAgICAgMCwgLy8gQWxsb2NhdGlvbkxvY2FsT2Zmc2V0DQogICAgICAgICZyZXNEZXNjLA0KICAgICAgICBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsDQogICAgICAgIE5VTEwsIC8vIHBPcHRpbWl6ZWRDbGVhclZhbHVlDQogICAgICAgIElJRF9QUFZfQVJHUygmcmVzKSkgKTsNCn0NCg0Kc3RhdGljIHZvaWQgVGVzdFBvb2xzQW5kQWxsb2NhdGlvblBhcmFtZXRlcnMoY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICB3cHJpbnRmKEwiVGVzdCBwb29scyBhbmQgYWxsb2NhdGlvbiBwYXJhbWV0ZXJzXG4iKTsNCg0KICAgIENvbVB0cjxEM0QxMk1BOjpQb29sPiBwb29sMSwgcG9vbDI7DQogICAgc3RkOjp2ZWN0b3I8Q29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+PiBidWZzOw0KDQogICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KDQogICAgdWludDMyX3QgdG90YWxOZXdBbGxvY0NvdW50ID0gMCwgdG90YWxOZXdCbG9ja0NvdW50ID0gMDsNCiAgICBEM0QxMk1BOjpUb3RhbFN0YXRpc3RpY3Mgc3RhdHNCZWcsIHN0YXRzRW5kOw0KICAgIGN0eC5hbGxvY2F0b3ItPkNhbGN1bGF0ZVN0YXRpc3RpY3MoJnN0YXRzQmVnKTsNCg0KICAgIEhSRVNVTFQgaHI7DQogICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jOw0KDQogICAgLy8gcG9vbFR5cGVJOg0KICAgIC8vIDAgPSBkZWZhdWx0IHBvb2wNCiAgICAvLyAxID0gY3VzdG9tIHBvb2wsIGRlZmF1bHQgKGZsZXhpYmxlKSBibG9jayBzaXplIGFuZCBibG9jayBjb3VudA0KICAgIC8vIDIgPSBjdXN0b20gcG9vbCwgZml4ZWQgYmxvY2sgc2l6ZSBhbmQgbGltaXRlZCBibG9jayBjb3VudA0KICAgIGZvcihzaXplX3QgcG9vbFR5cGVJID0gMDsgcG9vbFR5cGVJIDwgMzsgKytwb29sVHlwZUkpDQogICAgew0KICAgICAgICBpZihwb29sVHlwZUkgPT0gMCkNCiAgICAgICAgew0KICAgICAgICAgICAgYWxsb2NEZXNjLkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQogICAgICAgICAgICBhbGxvY0Rlc2MuQ3VzdG9tUG9vbCA9IG51bGxwdHI7DQogICAgICAgIH0NCiAgICAgICAgZWxzZSBpZihwb29sVHlwZUkgPT0gMSkNCiAgICAgICAgew0KICAgICAgICAgICAgRDNEMTJNQTo6UE9PTF9ERVNDIHBvb2xEZXNjID0ge307DQogICAgICAgICAgICBwb29sRGVzYy5IZWFwUHJvcGVydGllcy5UeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQogICAgICAgICAgICBwb29sRGVzYy5IZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9CVUZGRVJTOw0KICAgICAgICAgICAgaHIgPSBjdHguYWxsb2NhdG9yLT5DcmVhdGVQb29sKCZwb29sRGVzYywgJnBvb2wxKTsNCiAgICAgICAgICAgIENIRUNLX0hSKGhyKTsNCiAgICAgICAgICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gcG9vbDEuR2V0KCk7DQogICAgICAgIH0NCiAgICAgICAgZWxzZSBpZihwb29sVHlwZUkgPT0gMikNCiAgICAgICAgew0KICAgICAgICAgICAgRDNEMTJNQTo6UE9PTF9ERVNDIHBvb2xEZXNjID0ge307DQogICAgICAgICAgICBwb29sRGVzYy5IZWFwUHJvcGVydGllcy5UeXBlID0gRDNEMTJfSEVBUF9UWVBFX0RFRkFVTFQ7DQogICAgICAgICAgICBwb29sRGVzYy5IZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9CVUZGRVJTOw0KICAgICAgICAgICAgcG9vbERlc2MuTWF4QmxvY2tDb3VudCA9IDE7DQogICAgICAgICAgICBwb29sRGVzYy5CbG9ja1NpemUgPSAyICogTUVHQUJZVEUgKyBNRUdBQllURSAvIDI7IC8vIDIuNSBNQg0KICAgICAgICAgICAgaHIgPSBjdHguYWxsb2NhdG9yLT5DcmVhdGVQb29sKCZwb29sRGVzYywgJnBvb2wyKTsNCiAgICAgICAgICAgIENIRUNLX0hSKGhyKTsNCiAgICAgICAgICAgIGFsbG9jRGVzYy5DdXN0b21Qb29sID0gcG9vbDIuR2V0KCk7DQogICAgICAgIH0NCg0KICAgICAgICB1aW50MzJfdCBwb29sQWxsb2NDb3VudCA9IDAsIHBvb2xCbG9ja0NvdW50ID0gMDsNCiAgICAgICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNEZXNjOw0KICAgICAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc0Rlc2MsIE1FR0FCWVRFKTsNCg0KICAgICAgICAvLyBEZWZhdWx0IHBhcmFtZXRlcnMNCiAgICAgICAgYWxsb2NEZXNjLkZsYWdzID0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX05PTkU7DQogICAgICAgIGhyID0gY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJnJlc0Rlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPUFlfREVTVCwgbnVsbHB0ciwgJmFsbG9jLCBJSURfTlVMTCwgbnVsbHB0cik7DQogICAgICAgIENIRUNLX0JPT0woU1VDQ0VFREVEKGhyKSAmJiBhbGxvYyAmJiBhbGxvYy0+R2V0UmVzb3VyY2UoKSk7DQogICAgICAgIElEM0QxMkhlYXAqIGNvbnN0IGRlZmF1bHRBbGxvY0hlYXAgPSBhbGxvYy0+R2V0SGVhcCgpOw0KICAgICAgICBjb25zdCBVSU5UNjQgZGVmYXVsdEFsbG9jT2Zmc2V0ID0gYWxsb2MtPkdldE9mZnNldCgpOw0KICAgICAgICBidWZzLnB1c2hfYmFjayhzdGQ6Om1vdmUoYWxsb2MpKTsNCiAgICAgICAgKytwb29sQWxsb2NDb3VudDsNCg0KICAgICAgICAvLyBDT01NSVRURUQuIFNob3VsZCBub3QgdHJ5IHBvb2wyIGFzIGl0IG1heSBhc3NlcnQgb24gaW52YWxpZCBjYWxsLg0KICAgICAgICBpZihwb29sVHlwZUkgIT0gMikNCiAgICAgICAgew0KICAgICAgICAgICAgYWxsb2NEZXNjLkZsYWdzID0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX0NPTU1JVFRFRDsNCiAgICAgICAgICAgIGhyID0gY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJnJlc0Rlc2MsIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPUFlfREVTVCwgbnVsbHB0ciwgJmFsbG9jLCBJSURfTlVMTCwgbnVsbHB0cik7DQogICAgICAgICAgICBDSEVDS19CT09MKFNVQ0NFRURFRChocikgJiYgYWxsb2MgJiYgYWxsb2MtPkdldFJlc291cmNlKCkpOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChhbGxvYy0+R2V0T2Zmc2V0KCkgPT0gMCk7IC8vIENvbW1pdHRlZA0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChhbGxvYy0+R2V0SGVhcCgpID09IG51bGxwdHIpOyAvLyBDb21taXR0ZWQNCiAgICAgICAgICAgIGJ1ZnMucHVzaF9iYWNrKHN0ZDo6bW92ZShhbGxvYykpOw0KICAgICAgICAgICAgKytwb29sQWxsb2NDb3VudDsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIE5FVkVSX0FMTE9DQVRFICMxDQogICAgICAgIGFsbG9jRGVzYy5GbGFncyA9IEQzRDEyTUE6OkFMTE9DQVRJT05fRkxBR19ORVZFUl9BTExPQ0FURTsNCiAgICAgICAgaHIgPSBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09QWV9ERVNULCBudWxscHRyLCAmYWxsb2MsIElJRF9OVUxMLCBudWxscHRyKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChTVUNDRUVERUQoaHIpICYmIGFsbG9jICYmIGFsbG9jLT5HZXRSZXNvdXJjZSgpKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChhbGxvYy0+R2V0SGVhcCgpID09IGRlZmF1bHRBbGxvY0hlYXApOyAvLyBTYW1lIG1lbW9yeSBibG9jayBhcyBkZWZhdWx0IG9uZS4NCiAgICAgICAgQ0hFQ0tfQk9PTChhbGxvYy0+R2V0T2Zmc2V0KCkgIT0gZGVmYXVsdEFsbG9jT2Zmc2V0KTsNCiAgICAgICAgYnVmcy5wdXNoX2JhY2soc3RkOjptb3ZlKGFsbG9jKSk7DQogICAgICAgICsrcG9vbEFsbG9jQ291bnQ7DQoNCiAgICAgICAgLy8gTkVWRVJfQUxMT0NBVEUgIzIuIFNob3VsZCBmYWlsIGluIHBvb2wyIGFzIGl0IGhhcyBubyBzcGFjZS4NCiAgICAgICAgYWxsb2NEZXNjLkZsYWdzID0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX05FVkVSX0FMTE9DQVRFOw0KICAgICAgICBociA9IGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKCZhbGxvY0Rlc2MsICZyZXNEZXNjLCBEM0QxMl9SRVNPVVJDRV9TVEFURV9DT1BZX0RFU1QsIG51bGxwdHIsICZhbGxvYywgSUlEX05VTEwsIG51bGxwdHIpOw0KICAgICAgICBpZihwb29sVHlwZUkgPT0gMikNCiAgICAgICAgICAgIENIRUNLX0JPT0woRkFJTEVEKGhyKSk7DQogICAgICAgIGVsc2UNCiAgICAgICAgew0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChTVUNDRUVERUQoaHIpICYmIGFsbG9jICYmIGFsbG9jLT5HZXRSZXNvdXJjZSgpKTsNCiAgICAgICAgICAgIGJ1ZnMucHVzaF9iYWNrKHN0ZDo6bW92ZShhbGxvYykpOw0KICAgICAgICAgICAgKytwb29sQWxsb2NDb3VudDsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIFBvb2wgc3RhdHMNCiAgICAgICAgc3dpdGNoKHBvb2xUeXBlSSkNCiAgICAgICAgew0KICAgICAgICBjYXNlIDA6IHBvb2xCbG9ja0NvdW50ID0gMTsgYnJlYWs7IC8vIEF0IGxlYXN0IDEgYWRkZWQgZm9yIGRlZGljYXRlZCBhbGxvY2F0aW9uLg0KICAgICAgICBjYXNlIDE6IHBvb2xCbG9ja0NvdW50ID0gMjsgYnJlYWs7IC8vIDEgZm9yIGN1c3RvbSBwb29sIGJsb2NrIGFuZCAxIGZvciBkZWRpY2F0ZWQgYWxsb2NhdGlvbi4NCiAgICAgICAgY2FzZSAyOiBwb29sQmxvY2tDb3VudCA9IDE7IGJyZWFrOyAvLyBPbmx5IGN1c3RvbSBwb29sLCBubyBkZWRpY2F0ZWQgYWxsb2NhdGlvbi4NCiAgICAgICAgfQ0KDQogICAgICAgIGlmKHBvb2xUeXBlSSA+IDApDQogICAgICAgIHsNCiAgICAgICAgICAgIEQzRDEyTUE6OkRldGFpbGVkU3RhdGlzdGljcyBwb29sU3RhdHMgPSB7fTsNCiAgICAgICAgICAgIChwb29sVHlwZUkgPT0gMiA/IHBvb2wyIDogcG9vbDEpLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZwb29sU3RhdHMpOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChwb29sU3RhdHMuU3RhdHMuQWxsb2NhdGlvbkNvdW50ID09IHBvb2xBbGxvY0NvdW50KTsNCiAgICAgICAgICAgIENIRUNLX0JPT0wocG9vbFN0YXRzLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PSBwb29sQWxsb2NDb3VudCAqIE1FR0FCWVRFKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0wocG9vbFN0YXRzLlN0YXRzLkJsb2NrQ291bnQgPT0gcG9vbEJsb2NrQ291bnQpOw0KICAgICAgICB9DQoNCiAgICAgICAgdG90YWxOZXdBbGxvY0NvdW50ICs9IHBvb2xBbGxvY0NvdW50Ow0KICAgICAgICB0b3RhbE5ld0Jsb2NrQ291bnQgKz0gcG9vbEJsb2NrQ291bnQ7DQogICAgfQ0KDQogICAgY3R4LmFsbG9jYXRvci0+Q2FsY3VsYXRlU3RhdGlzdGljcygmc3RhdHNFbmQpOw0KDQogICAgQ0hFQ0tfQk9PTChzdGF0c0VuZC5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQ291bnQgPT0NCiAgICAgICAgc3RhdHNCZWcuVG90YWwuU3RhdHMuQWxsb2NhdGlvbkNvdW50ICsgdG90YWxOZXdBbGxvY0NvdW50KTsNCiAgICBDSEVDS19CT09MKHN0YXRzRW5kLlRvdGFsLlN0YXRzLkJsb2NrQ291bnQgPj0NCiAgICAgICAgc3RhdHNCZWcuVG90YWwuU3RhdHMuQmxvY2tDb3VudCArIHRvdGFsTmV3QmxvY2tDb3VudCk7DQogICAgQ0hFQ0tfQk9PTChzdGF0c0VuZC5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPT0NCiAgICAgICAgc3RhdHNCZWcuVG90YWwuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzICsgdG90YWxOZXdBbGxvY0NvdW50ICogTUVHQUJZVEUpOw0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0Q3VzdG9tUG9vbF9NaW5BbGxvY2F0aW9uQWxpZ25tZW50KGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgY3VzdG9tIHBvb2wgTWluQWxsb2NhdGlvbkFsaWdubWVudFxuIik7DQoNCiAgICBjb25zdCBVSU5UNjQgQlVGRkVSX1NJWkUgPSAzMjsNCiAgICBjb25zdGV4cHIgc2l6ZV90IEJVRkZFUl9DT1VOVCA9IDQ7DQogICAgY29uc3QgVUlOVDY0IE1JTl9BTElHTk1FTlQgPSAxMjggKiAxMDI0Ow0KDQogICAgRDNEMTJNQTo6UE9PTF9ERVNDIHBvb2xEZXNjID0ge307DQogICAgcG9vbERlc2MuSGVhcFByb3BlcnRpZXMuVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9VUExPQUQ7DQogICAgcG9vbERlc2MuSGVhcEZsYWdzID0gRDNEMTJfSEVBUF9GTEFHX0FMTE9XX09OTFlfQlVGRkVSUzsNCiAgICBwb29sRGVzYy5NaW5BbGxvY2F0aW9uQWxpZ25tZW50ID0gTUlOX0FMSUdOTUVOVDsNCg0KICAgIENvbVB0cjxEM0QxMk1BOjpQb29sPiBwb29sOw0KICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVQb29sKCZwb29sRGVzYywgJnBvb2wpICk7DQoNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgYWxsb2NEZXNjLkN1c3RvbVBvb2wgPSBwb29sLkdldCgpOw0KDQogICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNEZXNjOw0KICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzRGVzYywgQlVGRkVSX1NJWkUpOw0KDQogICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jc1tCVUZGRVJfQ09VTlRdOw0KICAgIGZvcihzaXplX3QgaSA9IDA7IGkgPCBCVUZGRVJfQ09VTlQ7ICsraSkNCiAgICB7DQogICAgICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywNCiAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0dFTkVSSUNfUkVBRCwNCiAgICAgICAgICAgIE5VTEwsIC8vIHBPcHRpbWl6ZWRDbGVhclZhbHVlDQogICAgICAgICAgICAmYWxsb2NzW2ldLA0KICAgICAgICAgICAgSUlEX05VTEwsIE5VTEwpICk7IC8vIHJpaWRSZXNvdXJjZSwgcHB2UmVzb3VyY2UNCiAgICAgICAgQ0hFQ0tfQk9PTChhbGxvY3NbaV0tPkdldE9mZnNldCgpICUgTUlOX0FMSUdOTUVOVCA9PSAwKTsNCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RDdXN0b21Qb29sX0NvbW1pdHRlZChjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IGN1c3RvbSBwb29sIGNvbW1pdHRlZFxuIik7DQoNCiAgICBjb25zdCBVSU5UNjQgQlVGRkVSX1NJWkUgPSAzMjsNCg0KICAgIEQzRDEyTUE6OlBPT0xfREVTQyBwb29sRGVzYyA9IHt9Ow0KICAgIHBvb2xEZXNjLkhlYXBQcm9wZXJ0aWVzLlR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICBwb29sRGVzYy5IZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9CVUZGRVJTOw0KDQogICAgQ29tUHRyPEQzRDEyTUE6OlBvb2w+IHBvb2w7DQogICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVBvb2woJnBvb2xEZXNjLCAmcG9vbCkgKTsNCg0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuQ3VzdG9tUG9vbCA9IHBvb2wuR2V0KCk7DQogICAgYWxsb2NEZXNjLkZsYWdzID0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX0NPTU1JVFRFRDsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzRGVzYzsNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc0Rlc2MsIEJVRkZFUl9TSVpFKTsNCg0KICAgIENvbVB0cjxEM0QxMk1BOjpBbGxvY2F0aW9uPiBhbGxvYzsNCiAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoJmFsbG9jRGVzYywgJnJlc0Rlc2MsDQogICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPTU1PTiwNCiAgICAgICAgTlVMTCwgLy8gcE9wdGltaXplZENsZWFyVmFsdWUNCiAgICAgICAgJmFsbG9jLA0KICAgICAgICBJSURfTlVMTCwgTlVMTCkgKTsgLy8gcmlpZFJlc291cmNlLCBwcHZSZXNvdXJjZQ0KICAgIENIRUNLX0JPT0woYWxsb2MtPkdldEhlYXAoKSA9PSBOVUxMKTsNCiAgICBDSEVDS19CT09MKGFsbG9jLT5HZXRSZXNvdXJjZSgpICE9IE5VTEwpOw0KICAgIENIRUNLX0JPT0woYWxsb2MtPkdldE9mZnNldCgpID09IDApOw0KfQ0KDQpzdGF0aWMgSFJFU1VMVCBUZXN0Q3VzdG9tSGVhcChjb25zdCBUZXN0Q29udGV4dCYgY3R4LCBjb25zdCBEM0QxMl9IRUFQX1BST1BFUlRJRVMmIGhlYXBQcm9wcykNCnsNCiAgICBEM0QxMk1BOjpUb3RhbFN0YXRpc3RpY3MgZ2xvYmFsU3RhdHNCZWcgPSB7fTsNCiAgICBjdHguYWxsb2NhdG9yLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZnbG9iYWxTdGF0c0JlZyk7DQoNCiAgICBEM0QxMk1BOjpQT09MX0RFU0MgcG9vbERlc2MgPSB7fTsNCiAgICBwb29sRGVzYy5IZWFwUHJvcGVydGllcyA9IGhlYXBQcm9wczsNCiAgICBwb29sRGVzYy5IZWFwRmxhZ3MgPSBEM0QxMl9IRUFQX0ZMQUdfQUxMT1dfT05MWV9CVUZGRVJTOw0KICAgIHBvb2xEZXNjLkJsb2NrU2l6ZSA9IDEwICogTUVHQUJZVEU7DQogICAgcG9vbERlc2MuTWluQmxvY2tDb3VudCA9IDE7DQogICAgcG9vbERlc2MuTWF4QmxvY2tDb3VudCA9IDE7DQoNCiAgICBjb25zdCBVSU5UNjQgQlVGRkVSX1NJWkUgPSAxICogTUVHQUJZVEU7DQoNCiAgICBDb21QdHI8RDNEMTJNQTo6UG9vbD4gcG9vbDsNCiAgICBIUkVTVUxUIGhyID0gY3R4LmFsbG9jYXRvci0+Q3JlYXRlUG9vbCgmcG9vbERlc2MsICZwb29sKTsNCiAgICBpZihTVUNDRUVERUQoaHIpKQ0KICAgIHsNCiAgICAgICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgICAgICBhbGxvY0Rlc2MuQ3VzdG9tUG9vbCA9IHBvb2wuR2V0KCk7DQoNCiAgICAgICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNEZXNjOw0KICAgICAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc0Rlc2MsIEJVRkZFUl9TSVpFKTsNCg0KICAgICAgICAvLyBQb29sIGFscmVhZHkgYWxsb2NhdGVkIGEgYmxvY2suIFdlIGRvbid0IGV4cGVjdCBDcmVhdGVQbGFjZWRSZXNvdXJjZSB0byBmYWlsLg0KICAgICAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYWxsb2M7DQogICAgICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywNCiAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPUFlfREVTVCwNCiAgICAgICAgICAgIE5VTEwsIC8vIHBPcHRpbWl6ZWRDbGVhclZhbHVlDQogICAgICAgICAgICAmYWxsb2MsDQogICAgICAgICAgICBfX3V1aWRvZihJRDNEMTJSZXNvdXJjZSksIE5VTEwpICk7IC8vIHJpaWRSZXNvdXJjZSwgcHB2UmVzb3VyY2UNCg0KICAgICAgICBEM0QxMk1BOjpUb3RhbFN0YXRpc3RpY3MgZ2xvYmFsU3RhdHNDdXJyID0ge307DQogICAgICAgIGN0eC5hbGxvY2F0b3ItPkNhbGN1bGF0ZVN0YXRpc3RpY3MoJmdsb2JhbFN0YXRzQ3Vycik7DQoNCiAgICAgICAgLy8gTWFrZSBzdXJlIGl0IGlzIGFjY291bnRlZCBvbmx5IGluIENVU1RPTSBoZWFwIG5vdCBhbnkgb2YgdGhlIHN0YW5kYXJkIGhlYXBzLg0KICAgICAgICBDSEVDS19CT09MKG1lbWNtcCgmZ2xvYmFsU3RhdHNDdXJyLkhlYXBUeXBlWzBdLCAmZ2xvYmFsU3RhdHNCZWcuSGVhcFR5cGVbMF0sIHNpemVvZihEM0QxMk1BOjpEZXRhaWxlZFN0YXRpc3RpY3MpKSA9PSAwKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChtZW1jbXAoJmdsb2JhbFN0YXRzQ3Vyci5IZWFwVHlwZVsxXSwgJmdsb2JhbFN0YXRzQmVnLkhlYXBUeXBlWzFdLCBzaXplb2YoRDNEMTJNQTo6RGV0YWlsZWRTdGF0aXN0aWNzKSkgPT0gMCk7DQogICAgICAgIENIRUNLX0JPT0wobWVtY21wKCZnbG9iYWxTdGF0c0N1cnIuSGVhcFR5cGVbMl0sICZnbG9iYWxTdGF0c0JlZy5IZWFwVHlwZVsyXSwgc2l6ZW9mKEQzRDEyTUE6OkRldGFpbGVkU3RhdGlzdGljcykpID09IDApOw0KICAgICAgICBDSEVDS19CT09MKCBnbG9iYWxTdGF0c0N1cnIuSGVhcFR5cGVbM10uU3RhdHMuQWxsb2NhdGlvbkNvdW50ID09IGdsb2JhbFN0YXRzQmVnLkhlYXBUeXBlWzNdLlN0YXRzLkFsbG9jYXRpb25Db3VudCArIDEgKTsNCiAgICAgICAgQ0hFQ0tfQk9PTCggZ2xvYmFsU3RhdHNDdXJyLkhlYXBUeXBlWzNdLlN0YXRzLkJsb2NrQ291bnQgPT0gZ2xvYmFsU3RhdHNCZWcuSGVhcFR5cGVbM10uU3RhdHMuQmxvY2tDb3VudCArIDEgKTsNCiAgICAgICAgQ0hFQ0tfQk9PTCggZ2xvYmFsU3RhdHNDdXJyLkhlYXBUeXBlWzNdLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PSBnbG9iYWxTdGF0c0JlZy5IZWFwVHlwZVszXS5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgKyBCVUZGRVJfU0laRSApOw0KICAgICAgICBDSEVDS19CT09MKCBnbG9iYWxTdGF0c0N1cnIuVG90YWwuU3RhdHMuQWxsb2NhdGlvbkNvdW50ID09IGdsb2JhbFN0YXRzQmVnLlRvdGFsLlN0YXRzLkFsbG9jYXRpb25Db3VudCArIDEgKTsNCiAgICAgICAgQ0hFQ0tfQk9PTCggZ2xvYmFsU3RhdHNDdXJyLlRvdGFsLlN0YXRzLkJsb2NrQ291bnQgPT0gZ2xvYmFsU3RhdHNCZWcuVG90YWwuU3RhdHMuQmxvY2tDb3VudCArIDEgKTsNCiAgICAgICAgQ0hFQ0tfQk9PTCggZ2xvYmFsU3RhdHNDdXJyLlRvdGFsLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PSBnbG9iYWxTdGF0c0JlZy5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgKyBCVUZGRVJfU0laRSApOw0KDQogICAgICAgIC8vIE1hcCBhbmQgd3JpdGUgc29tZSBkYXRhLg0KICAgICAgICBpZihoZWFwUHJvcHMuQ1BVUGFnZVByb3BlcnR5ID09IEQzRDEyX0NQVV9QQUdFX1BST1BFUlRZX1dSSVRFX0NPTUJJTkUgfHwNCiAgICAgICAgICAgIGhlYXBQcm9wcy5DUFVQYWdlUHJvcGVydHkgPT0gRDNEMTJfQ1BVX1BBR0VfUFJPUEVSVFlfV1JJVEVfQkFDSykNCiAgICAgICAgew0KICAgICAgICAgICAgSUQzRDEyUmVzb3VyY2UqIGNvbnN0IHJlcyA9IGFsbG9jLT5HZXRSZXNvdXJjZSgpOw0KDQogICAgICAgICAgICBVSU5UKiBtYXBwZWRQdHIgPSBudWxscHRyOw0KICAgICAgICAgICAgY29uc3QgRDNEMTJfUkFOR0UgcmVhZFJhbmdlID0gezAsIDB9Ow0KICAgICAgICAgICAgQ0hFQ0tfSFIocmVzLT5NYXAoMCwgJnJlYWRSYW5nZSwgKHZvaWQqKikmbWFwcGVkUHRyKSk7DQogICAgICAgICAgICANCiAgICAgICAgICAgICptYXBwZWRQdHIgPSAweERFQURDMERFOw0KICAgICAgICAgICAgDQogICAgICAgICAgICByZXMtPlVubWFwKDAsIG51bGxwdHIpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgcmV0dXJuIGhyOw0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0Q3VzdG9tSGVhcHMoY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICB3cHJpbnRmKEwiVGVzdCBjdXN0b20gaGVhcFxuIik7DQoNCiAgICBEM0QxMl9IRUFQX1BST1BFUlRJRVMgaGVhcFByb3BzID0ge307DQoNCiAgICAvLyBVc2UgY3VzdG9tIHBvb2wgYnV0IHRoZSBzYW1lIGFzIFJFQURCQUNLLCB3aGljaCBzaG91bGQgYmUgYWx3YXlzIGF2YWlsYWJsZS4NCiAgICBoZWFwUHJvcHMuVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9DVVNUT007DQogICAgaGVhcFByb3BzLkNQVVBhZ2VQcm9wZXJ0eSA9IEQzRDEyX0NQVV9QQUdFX1BST1BFUlRZX1dSSVRFX0JBQ0s7DQogICAgaGVhcFByb3BzLk1lbW9yeVBvb2xQcmVmZXJlbmNlID0gRDNEMTJfTUVNT1JZX1BPT0xfTDA7IC8vIFN5c3RlbSBtZW1vcnkNCiAgICBIUkVTVUxUIGhyID0gVGVzdEN1c3RvbUhlYXAoY3R4LCBoZWFwUHJvcHMpOw0KICAgIENIRUNLX0hSKGhyKTsNCn0NCg0Kc3RhdGljIHZvaWQgVGVzdFN0YW5kYXJkQ3VzdG9tQ29tbWl0dGVkUGxhY2VkKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3Qgc3RhbmRhcmQsIGN1c3RvbSwgY29tbWl0dGVkLCBwbGFjZWRcbiIpOw0KDQogICAgc3RhdGljIGNvbnN0IEQzRDEyX0hFQVBfVFlQRSBoZWFwVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9ERUZBVUxUOw0KICAgIHN0YXRpYyBjb25zdCBVSU5UNjQgYnVmZmVyU2l6ZSA9IDEwMjQ7DQoNCiAgICBEM0QxMk1BOjpQT09MX0RFU0MgcG9vbERlc2MgPSB7fTsNCiAgICBwb29sRGVzYy5IZWFwUHJvcGVydGllcy5UeXBlID0gaGVhcFR5cGU7DQogICAgcG9vbERlc2MuSGVhcEZsYWdzID0gRDNEMTJfSEVBUF9GTEFHX0FMTE9XX09OTFlfQlVGRkVSUzsNCg0KICAgIENvbVB0cjxEM0QxMk1BOjpQb29sPiBwb29sOw0KICAgIENIRUNLX0hSKGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVBvb2woJnBvb2xEZXNjLCAmcG9vbCkpOw0KDQogICAgc3RkOjp2ZWN0b3I8Q29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+PiBhbGxvY2F0aW9uczsNCiAgICANCiAgICBEM0QxMk1BOjpUb3RhbFN0YXRpc3RpY3Mgc3RhdHNCZWcgPSB7fTsNCiAgICBEM0QxMk1BOjpEZXRhaWxlZFN0YXRpc3RpY3MgcG9vbFN0YXRJbmZvQmVnID0ge307DQogICAgY3R4LmFsbG9jYXRvci0+Q2FsY3VsYXRlU3RhdGlzdGljcygmc3RhdHNCZWcpOw0KICAgIHBvb2wtPkNhbGN1bGF0ZVN0YXRpc3RpY3MoJnBvb2xTdGF0SW5mb0JlZyk7DQoNCiAgICBzaXplX3QgcG9vbEFsbG9jQ291bnQgPSAwOw0KDQogICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNEZXNjID0ge307DQogICAgRmlsbFJlc291cmNlRGVzY0ZvckJ1ZmZlcihyZXNEZXNjLCBidWZmZXJTaXplKTsNCg0KICAgIGZvcih1aW50MzJfdCBzdGFuZGFyZEN1c3RvbUkgPSAwOyBzdGFuZGFyZEN1c3RvbUkgPCAyOyArK3N0YW5kYXJkQ3VzdG9tSSkNCiAgICB7DQogICAgICAgIGNvbnN0IGJvb2wgdXNlQ3VzdG9tUG9vbCA9IHN0YW5kYXJkQ3VzdG9tSSA+IDA7DQogICAgICAgIGZvcih1aW50MzJfdCBmbGFnc0kgPSAwOyBmbGFnc0kgPCAzOyArK2ZsYWdzSSkNCiAgICAgICAgew0KICAgICAgICAgICAgY29uc3QgYm9vbCB1c2VDb21taXR0ZWQgPSBmbGFnc0kgPiAwOw0KICAgICAgICAgICAgY29uc3QgYm9vbCBuZXZlckFsbG9jYXRlID0gZmxhZ3NJID4gMTsNCg0KICAgICAgICAgICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgICAgICAgICAgaWYodXNlQ3VzdG9tUG9vbCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBhbGxvY0Rlc2MuQ3VzdG9tUG9vbCA9IHBvb2wuR2V0KCk7DQogICAgICAgICAgICAgICAgYWxsb2NEZXNjLkhlYXBUeXBlID0gKEQzRDEyX0hFQVBfVFlQRSkweENEQ0RDRENEOyAvLyBTaG91bGQgYmUgaWdub3JlZC4NCiAgICAgICAgICAgICAgICBhbGxvY0Rlc2MuRXh0cmFIZWFwRmxhZ3MgPSAoRDNEMTJfSEVBUF9GTEFHUykweENEQ0RDRENEOyAvLyBTaG91bGQgYmUgaWdub3JlZC4NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBoZWFwVHlwZTsNCiAgICAgICAgICAgIGlmKHVzZUNvbW1pdHRlZCkNCiAgICAgICAgICAgICAgICBhbGxvY0Rlc2MuRmxhZ3MgfD0gRDNEMTJNQTo6QUxMT0NBVElPTl9GTEFHX0NPTU1JVFRFRDsNCiAgICAgICAgICAgIGlmKG5ldmVyQWxsb2NhdGUpDQogICAgICAgICAgICAgICAgYWxsb2NEZXNjLkZsYWdzIHw9IEQzRDEyTUE6OkFMTE9DQVRJT05fRkxBR19ORVZFUl9BTExPQ0FURTsNCg0KICAgICAgICAgICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jUHRyID0gTlVMTDsNCiAgICAgICAgICAgIEhSRVNVTFQgaHIgPSBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgmYWxsb2NEZXNjLCAmcmVzRGVzYywNCiAgICAgICAgICAgICAgICBEM0QxMl9SRVNPVVJDRV9TVEFURV9DT01NT04sDQogICAgICAgICAgICAgICAgTlVMTCwgLy8gcE9wdGltaXplZENsZWFyVmFsdWUNCiAgICAgICAgICAgICAgICAmYWxsb2NQdHIsIElJRF9OVUxMLCBOVUxMKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woU1VDQ0VFREVEKGhyKSA9PSAoYWxsb2NQdHIgIT0gTlVMTCkpOw0KICAgICAgICAgICAgaWYoYWxsb2NQdHIpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgYWxsb2NhdGlvbnMucHVzaF9iYWNrKGFsbG9jUHRyKTsNCiAgICAgICAgICAgICAgICBpZih1c2VDdXN0b21Qb29sKQ0KICAgICAgICAgICAgICAgICAgICArK3Bvb2xBbGxvY0NvdW50Ow0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBib29sIGV4cGVjdFN1Y2Nlc3MgPSAhbmV2ZXJBbGxvY2F0ZTsgLy8gTkVWRVJfQUxMT0NBVEUgc2hvdWxkIGFsd2F5cyBmYWlsIHdpdGggQ09NTUlUVEVELg0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChleHBlY3RTdWNjZXNzID09IFNVQ0NFRURFRChocikpOw0KICAgICAgICAgICAgaWYoU1VDQ0VFREVEKGhyKSAmJiB1c2VDb21taXR0ZWQpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgQ0hFQ0tfQk9PTChhbGxvY1B0ci0+R2V0SGVhcCgpID09IE5VTEwpOyAvLyBDb21taXR0ZWQgYWxsb2NhdGlvbiBoYXMgaW1wbGljaXQgaGVhcC4NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIEQzRDEyTUE6OlRvdGFsU3RhdGlzdGljcyBzdGF0c0VuZCA9IHt9Ow0KICAgIEQzRDEyTUE6OkRldGFpbGVkU3RhdGlzdGljcyBwb29sU3RhdEluZm9FbmQgPSB7fTsNCiAgICBjdHguYWxsb2NhdG9yLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZzdGF0c0VuZCk7DQogICAgcG9vbC0+Q2FsY3VsYXRlU3RhdGlzdGljcygmcG9vbFN0YXRJbmZvRW5kKTsNCg0KICAgIENIRUNLX0JPT0woc3RhdHNFbmQuVG90YWwuU3RhdHMuQWxsb2NhdGlvbkNvdW50ID09IHN0YXRzQmVnLlRvdGFsLlN0YXRzLkFsbG9jYXRpb25Db3VudCArIGFsbG9jYXRpb25zLnNpemUoKSk7DQogICAgQ0hFQ0tfQk9PTChzdGF0c0VuZC5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPj0gc3RhdHNCZWcuVG90YWwuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzICsgYWxsb2NhdGlvbnMuc2l6ZSgpICogYnVmZmVyU2l6ZSk7DQogICAgQ0hFQ0tfQk9PTChzdGF0c0VuZC5IZWFwVHlwZVswXS5TdGF0cy5BbGxvY2F0aW9uQ291bnQgPT0gc3RhdHNCZWcuSGVhcFR5cGVbMF0uU3RhdHMuQWxsb2NhdGlvbkNvdW50ICsgYWxsb2NhdGlvbnMuc2l6ZSgpKTsNCiAgICBDSEVDS19CT09MKHN0YXRzRW5kLkhlYXBUeXBlWzBdLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA+PSBzdGF0c0JlZy5IZWFwVHlwZVswXS5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgKyBhbGxvY2F0aW9ucy5zaXplKCkgKiBidWZmZXJTaXplKTsNCiAgICBDSEVDS19CT09MKHBvb2xTdGF0SW5mb0VuZC5TdGF0cy5BbGxvY2F0aW9uQ291bnQgPT0gcG9vbFN0YXRJbmZvQmVnLlN0YXRzLkFsbG9jYXRpb25Db3VudCArIHBvb2xBbGxvY0NvdW50KTsNCiAgICBDSEVDS19CT09MKHBvb2xTdGF0SW5mb0VuZC5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPj0gcG9vbFN0YXRJbmZvQmVnLlN0YXRzLkFsbG9jYXRpb25CeXRlcyArIHBvb2xBbGxvY0NvdW50ICogYnVmZmVyU2l6ZSk7DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RBbGlhc2luZ01lbW9yeShjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IGFsaWFzaW5nIG1lbW9yeVxuIik7DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc0Rlc2MxID0ge307DQogICAgcmVzRGVzYzEuRGltZW5zaW9uID0gRDNEMTJfUkVTT1VSQ0VfRElNRU5TSU9OX1RFWFRVUkUyRDsNCiAgICByZXNEZXNjMS5BbGlnbm1lbnQgPSAwOw0KICAgIHJlc0Rlc2MxLldpZHRoID0gMTkyMDsNCiAgICByZXNEZXNjMS5IZWlnaHQgPSAxMDgwOw0KICAgIHJlc0Rlc2MxLkRlcHRoT3JBcnJheVNpemUgPSAxOw0KICAgIHJlc0Rlc2MxLk1pcExldmVscyA9IDE7DQogICAgcmVzRGVzYzEuRm9ybWF0ID0gRFhHSV9GT1JNQVRfUjhHOEI4QThfVU5PUk07DQogICAgcmVzRGVzYzEuU2FtcGxlRGVzYy5Db3VudCA9IDE7DQogICAgcmVzRGVzYzEuU2FtcGxlRGVzYy5RdWFsaXR5ID0gMDsNCiAgICByZXNEZXNjMS5MYXlvdXQgPSBEM0QxMl9URVhUVVJFX0xBWU9VVF9VTktOT1dOOw0KICAgIHJlc0Rlc2MxLkZsYWdzID0gRDNEMTJfUkVTT1VSQ0VfRkxBR19BTExPV19SRU5ERVJfVEFSR0VUIHwgRDNEMTJfUkVTT1VSQ0VfRkxBR19BTExPV19VTk9SREVSRURfQUNDRVNTOw0KDQogICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNEZXNjMiA9IHt9Ow0KICAgIHJlc0Rlc2MyLkRpbWVuc2lvbiA9IEQzRDEyX1JFU09VUkNFX0RJTUVOU0lPTl9URVhUVVJFMkQ7DQogICAgcmVzRGVzYzIuQWxpZ25tZW50ID0gMDsNCiAgICByZXNEZXNjMi5XaWR0aCA9IDEwMjQ7DQogICAgcmVzRGVzYzIuSGVpZ2h0ID0gMTAyNDsNCiAgICByZXNEZXNjMi5EZXB0aE9yQXJyYXlTaXplID0gMTsNCiAgICByZXNEZXNjMi5NaXBMZXZlbHMgPSAwOw0KICAgIHJlc0Rlc2MyLkZvcm1hdCA9IERYR0lfRk9STUFUX1I4RzhCOEE4X1VOT1JNOw0KICAgIHJlc0Rlc2MyLlNhbXBsZURlc2MuQ291bnQgPSAxOw0KICAgIHJlc0Rlc2MyLlNhbXBsZURlc2MuUXVhbGl0eSA9IDA7DQogICAgcmVzRGVzYzIuTGF5b3V0ID0gRDNEMTJfVEVYVFVSRV9MQVlPVVRfVU5LTk9XTjsNCiAgICByZXNEZXNjMi5GbGFncyA9IEQzRDEyX1JFU09VUkNFX0ZMQUdfQUxMT1dfUkVOREVSX1RBUkdFVDsNCg0KICAgIGNvbnN0IEQzRDEyX1JFU09VUkNFX0FMTE9DQVRJT05fSU5GTyBhbGxvY0luZm8xID0NCiAgICAgICAgY3R4LmRldmljZS0+R2V0UmVzb3VyY2VBbGxvY2F0aW9uSW5mbygwLCAxLCAmcmVzRGVzYzEpOw0KICAgIGNvbnN0IEQzRDEyX1JFU09VUkNFX0FMTE9DQVRJT05fSU5GTyBhbGxvY0luZm8yID0NCiAgICAgICAgY3R4LmRldmljZS0+R2V0UmVzb3VyY2VBbGxvY2F0aW9uSW5mbygwLCAxLCAmcmVzRGVzYzIpOw0KDQogICAgRDNEMTJfUkVTT1VSQ0VfQUxMT0NBVElPTl9JTkZPIGZpbmFsQWxsb2NJbmZvID0ge307DQogICAgZmluYWxBbGxvY0luZm8uQWxpZ25tZW50ID0gc3RkOjptYXgoYWxsb2NJbmZvMS5BbGlnbm1lbnQsIGFsbG9jSW5mbzIuQWxpZ25tZW50KTsNCiAgICBmaW5hbEFsbG9jSW5mby5TaXplSW5CeXRlcyA9IHN0ZDo6bWF4KGFsbG9jSW5mbzEuU2l6ZUluQnl0ZXMsIGFsbG9jSW5mbzIuU2l6ZUluQnl0ZXMpOw0KDQogICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgIGFsbG9jRGVzYy5IZWFwVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9ERUZBVUxUOw0KICAgIGFsbG9jRGVzYy5FeHRyYUhlYXBGbGFncyA9IEQzRDEyX0hFQVBfRkxBR19BTExPV19PTkxZX1JUX0RTX1RFWFRVUkVTOw0KDQogICAgQ29tUHRyPEQzRDEyTUE6OkFsbG9jYXRpb24+IGFsbG9jOw0KICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5BbGxvY2F0ZU1lbW9yeSgmYWxsb2NEZXNjLCAmZmluYWxBbGxvY0luZm8sICZhbGxvYykgKTsNCiAgICBDSEVDS19CT09MKGFsbG9jICE9IE5VTEwgJiYgYWxsb2MtPkdldEhlYXAoKSAhPSBOVUxMKTsNCg0KICAgIENvbVB0cjxJRDNEMTJSZXNvdXJjZT4gcmVzMTsNCiAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+Q3JlYXRlQWxpYXNpbmdSZXNvdXJjZSgNCiAgICAgICAgYWxsb2MuR2V0KCksDQogICAgICAgIDAsIC8vIEFsbG9jYXRpb25Mb2NhbE9mZnNldA0KICAgICAgICAmcmVzRGVzYzEsDQogICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPTU1PTiwNCiAgICAgICAgTlVMTCwgLy8gcE9wdGltaXplZENsZWFyVmFsdWUNCiAgICAgICAgSUlEX1BQVl9BUkdTKCZyZXMxKSkgKTsNCiAgICBDSEVDS19CT09MKHJlczEgIT0gTlVMTCk7DQoNCiAgICBDb21QdHI8SUQzRDEyUmVzb3VyY2U+IHJlczI7DQogICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZUFsaWFzaW5nUmVzb3VyY2UoDQogICAgICAgIGFsbG9jLkdldCgpLA0KICAgICAgICAwLCAvLyBBbGxvY2F0aW9uTG9jYWxPZmZzZXQNCiAgICAgICAgJnJlc0Rlc2MyLA0KICAgICAgICBEM0QxMl9SRVNPVVJDRV9TVEFURV9DT01NT04sDQogICAgICAgIE5VTEwsIC8vIHBPcHRpbWl6ZWRDbGVhclZhbHVlDQogICAgICAgIElJRF9QUFZfQVJHUygmcmVzMikpICk7DQogICAgQ0hFQ0tfQk9PTChyZXMyICE9IE5VTEwpOw0KDQogICAgLy8gWW91IGNhbiB1c2UgcmVzMSBhbmQgcmVzMiwgYnV0IG5vdCBhdCB0aGUgc2FtZSB0aW1lIQ0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0TWFwcGluZyhjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IG1hcHBpbmdcbiIpOw0KDQogICAgY29uc3QgVUlOVCBjb3VudCA9IDEwOw0KICAgIGNvbnN0IFVJTlQ2NCBidWZTaXplID0gMzJ1bGwgKiAxMDI0Ow0KICAgIFJlc291cmNlV2l0aEFsbG9jYXRpb24gcmVzb3VyY2VzW2NvdW50XTsNCg0KICAgIEQzRDEyTUE6OkFMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfVVBMT0FEOw0KDQogICAgRDNEMTJfUkVTT1VSQ0VfREVTQyByZXNvdXJjZURlc2M7DQogICAgRmlsbFJlc291cmNlRGVzY0ZvckJ1ZmZlcihyZXNvdXJjZURlc2MsIGJ1ZlNpemUpOw0KDQogICAgZm9yKFVJTlQgaSA9IDA7IGkgPCBjb3VudDsgKytpKQ0KICAgIHsNCiAgICAgICAgQ0hFQ0tfSFIoIGN0eC5hbGxvY2F0b3ItPkNyZWF0ZVJlc291cmNlKA0KICAgICAgICAgICAgJmFsbG9jRGVzYywNCiAgICAgICAgICAgICZyZXNvdXJjZURlc2MsDQogICAgICAgICAgICBEM0QxMl9SRVNPVVJDRV9TVEFURV9HRU5FUklDX1JFQUQsDQogICAgICAgICAgICBOVUxMLA0KICAgICAgICAgICAgJnJlc291cmNlc1tpXS5hbGxvY2F0aW9uLA0KICAgICAgICAgICAgSUlEX1BQVl9BUkdTKCZyZXNvdXJjZXNbaV0ucmVzb3VyY2UpKSApOw0KDQogICAgICAgIHZvaWQqIG1hcHBlZFB0ciA9IE5VTEw7DQogICAgICAgIENIRUNLX0hSKCByZXNvdXJjZXNbaV0ucmVzb3VyY2UtPk1hcCgwLCAmRU1QVFlfUkFOR0UsICZtYXBwZWRQdHIpICk7DQoNCiAgICAgICAgRmlsbERhdGEobWFwcGVkUHRyLCBidWZTaXplLCBpKTsNCg0KICAgICAgICAvLyBVbm1hcCBldmVyeSBvdGhlciBidWZmZXIuIExlYXZlIG90aGVycyBtYXBwZWQuDQogICAgICAgIGlmKChpICUgMikgIT0gMCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmVzb3VyY2VzW2ldLnJlc291cmNlLT5Vbm1hcCgwLCBOVUxMKTsNCiAgICAgICAgfQ0KICAgIH0NCn0NCg0Kc3RhdGljIGlubGluZSBib29sIFN0YXRpc3RpY3NFcXVhbChjb25zdCBEM0QxMk1BOjpEZXRhaWxlZFN0YXRpc3RpY3MmIGxocywgY29uc3QgRDNEMTJNQTo6RGV0YWlsZWRTdGF0aXN0aWNzJiByaHMpDQp7DQogICAgcmV0dXJuIG1lbWNtcCgmbGhzLCAmcmhzLCBzaXplb2YobGhzKSkgPT0gMDsNCn0NCg0Kc3RhdGljIHZvaWQgQ2hlY2tTdGF0aXN0aWNzKGNvbnN0IEQzRDEyTUE6OkRldGFpbGVkU3RhdGlzdGljcyYgc3RhdHMpDQp7DQogICAgQ0hFQ0tfQk9PTChzdGF0cy5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPD0gc3RhdHMuU3RhdHMuQmxvY2tCeXRlcyk7DQogICAgaWYoc3RhdHMuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzID4gMCkNCiAgICB7DQogICAgICAgIENIRUNLX0JPT0woc3RhdHMuU3RhdHMuQWxsb2NhdGlvbkNvdW50ID4gMCk7DQogICAgICAgIENIRUNLX0JPT0woc3RhdHMuQWxsb2NhdGlvblNpemVNaW4gPD0gc3RhdHMuQWxsb2NhdGlvblNpemVNYXgpOw0KICAgIH0NCiAgICBpZihzdGF0cy5VbnVzZWRSYW5nZUNvdW50ID4gMCkNCiAgICB7DQogICAgICAgIENIRUNLX0JPT0woc3RhdHMuVW51c2VkUmFuZ2VTaXplTWF4ID4gMCk7DQogICAgICAgIENIRUNLX0JPT0woc3RhdHMuVW51c2VkUmFuZ2VTaXplTWluIDw9IHN0YXRzLlVudXNlZFJhbmdlU2l6ZU1heCk7DQogICAgfQ0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0U3RhdHMoY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICB3cHJpbnRmKEwiVGVzdCBzdGF0c1xuIik7DQoNCiAgICBEM0QxMk1BOjpUb3RhbFN0YXRpc3RpY3MgYmVnU3RhdHMgPSB7fTsNCiAgICBjdHguYWxsb2NhdG9yLT5DYWxjdWxhdGVTdGF0aXN0aWNzKCZiZWdTdGF0cyk7DQoNCiAgICBjb25zdCBVSU5UIGNvdW50ID0gMTA7DQogICAgY29uc3QgVUlOVDY0IGJ1ZlNpemUgPSA2NHVsbCAqIDEwMjQ7DQogICAgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiByZXNvdXJjZXNbY291bnRdOw0KDQogICAgRDNEMTJNQTo6QUxMT0NBVElPTl9ERVNDIGFsbG9jRGVzYyA9IHt9Ow0KICAgIGFsbG9jRGVzYy5IZWFwVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9VUExPQUQ7DQoNCiAgICBEM0QxMl9SRVNPVVJDRV9ERVNDIHJlc291cmNlRGVzYzsNCiAgICBGaWxsUmVzb3VyY2VEZXNjRm9yQnVmZmVyKHJlc291cmNlRGVzYywgYnVmU2l6ZSk7DQoNCiAgICBmb3IoVUlOVCBpID0gMDsgaSA8IGNvdW50OyArK2kpDQogICAgew0KICAgICAgICBpZihpID09IGNvdW50IC8gMikNCiAgICAgICAgICAgIGFsbG9jRGVzYy5GbGFncyB8PSBEM0QxMk1BOjpBTExPQ0FUSU9OX0ZMQUdfQ09NTUlUVEVEOw0KICAgICAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+Q3JlYXRlUmVzb3VyY2UoDQogICAgICAgICAgICAmYWxsb2NEZXNjLA0KICAgICAgICAgICAgJnJlc291cmNlRGVzYywNCiAgICAgICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0dFTkVSSUNfUkVBRCwNCiAgICAgICAgICAgIE5VTEwsDQogICAgICAgICAgICAmcmVzb3VyY2VzW2ldLmFsbG9jYXRpb24sDQogICAgICAgICAgICBJSURfUFBWX0FSR1MoJnJlc291cmNlc1tpXS5yZXNvdXJjZSkpICk7DQogICAgfQ0KDQogICAgRDNEMTJNQTo6VG90YWxTdGF0aXN0aWNzIGVuZFN0YXRzID0ge307DQogICAgY3R4LmFsbG9jYXRvci0+Q2FsY3VsYXRlU3RhdGlzdGljcygmZW5kU3RhdHMpOw0KDQogICAgQ0hFQ0tfQk9PTChlbmRTdGF0cy5Ub3RhbC5TdGF0cy5CbG9ja0NvdW50ID49IGJlZ1N0YXRzLlRvdGFsLlN0YXRzLkJsb2NrQ291bnQpOw0KICAgIENIRUNLX0JPT0woZW5kU3RhdHMuVG90YWwuU3RhdHMuQWxsb2NhdGlvbkNvdW50ID09IGJlZ1N0YXRzLlRvdGFsLlN0YXRzLkFsbG9jYXRpb25Db3VudCArIGNvdW50KTsNCiAgICBDSEVDS19CT09MKGVuZFN0YXRzLlRvdGFsLlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PSBiZWdTdGF0cy5Ub3RhbC5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgKyBjb3VudCAqIGJ1ZlNpemUpOw0KICAgIENIRUNLX0JPT0woZW5kU3RhdHMuVG90YWwuQWxsb2NhdGlvblNpemVNaW4gPD0gYnVmU2l6ZSk7DQogICAgQ0hFQ0tfQk9PTChlbmRTdGF0cy5Ub3RhbC5BbGxvY2F0aW9uU2l6ZU1heCA+PSBidWZTaXplKTsNCg0KICAgIENIRUNLX0JPT0woZW5kU3RhdHMuSGVhcFR5cGVbMV0uU3RhdHMuQmxvY2tDb3VudCA+PSBiZWdTdGF0cy5IZWFwVHlwZVsxXS5TdGF0cy5CbG9ja0NvdW50KTsNCiAgICBDSEVDS19CT09MKGVuZFN0YXRzLkhlYXBUeXBlWzFdLlN0YXRzLkFsbG9jYXRpb25Db3VudCA+PSBiZWdTdGF0cy5IZWFwVHlwZVsxXS5TdGF0cy5BbGxvY2F0aW9uQ291bnQgKyBjb3VudCk7DQogICAgQ0hFQ0tfQk9PTChlbmRTdGF0cy5IZWFwVHlwZVsxXS5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPj0gYmVnU3RhdHMuSGVhcFR5cGVbMV0uU3RhdHMuQWxsb2NhdGlvbkJ5dGVzICsgY291bnQgKiBidWZTaXplKTsNCiAgICBDSEVDS19CT09MKGVuZFN0YXRzLkhlYXBUeXBlWzFdLkFsbG9jYXRpb25TaXplTWluIDw9IGJ1ZlNpemUpOw0KICAgIENIRUNLX0JPT0woZW5kU3RhdHMuSGVhcFR5cGVbMV0uQWxsb2NhdGlvblNpemVNYXggPj0gYnVmU2l6ZSk7DQoNCiAgICBDSEVDS19CT09MKFN0YXRpc3RpY3NFcXVhbChiZWdTdGF0cy5IZWFwVHlwZVswXSwgZW5kU3RhdHMuSGVhcFR5cGVbMF0pKTsNCiAgICBDSEVDS19CT09MKFN0YXRpc3RpY3NFcXVhbChiZWdTdGF0cy5IZWFwVHlwZVsyXSwgZW5kU3RhdHMuSGVhcFR5cGVbMl0pKTsNCg0KICAgIENoZWNrU3RhdGlzdGljcyhlbmRTdGF0cy5Ub3RhbCk7DQogICAgQ2hlY2tTdGF0aXN0aWNzKGVuZFN0YXRzLkhlYXBUeXBlWzBdKTsNCiAgICBDaGVja1N0YXRpc3RpY3MoZW5kU3RhdHMuSGVhcFR5cGVbMV0pOw0KICAgIENoZWNrU3RhdGlzdGljcyhlbmRTdGF0cy5IZWFwVHlwZVsyXSk7DQoNCiAgICBEM0QxMk1BOjpCdWRnZXQgZ3B1QnVkZ2V0ID0ge30sIGNwdUJ1ZGdldCA9IHt9Ow0KICAgIGN0eC5hbGxvY2F0b3ItPkdldEJ1ZGdldCgmZ3B1QnVkZ2V0LCAmY3B1QnVkZ2V0KTsNCiAgICANCiAgICBDSEVDS19CT09MKGdwdUJ1ZGdldC5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPD0gZ3B1QnVkZ2V0LlN0YXRzLkJsb2NrQnl0ZXMpOw0KICAgIENIRUNLX0JPT0woZ3B1QnVkZ2V0LlN0YXRzLkFsbG9jYXRpb25CeXRlcyA9PSBlbmRTdGF0cy5IZWFwVHlwZVswXS5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMpOw0KICAgIENIRUNLX0JPT0woZ3B1QnVkZ2V0LlN0YXRzLkJsb2NrQnl0ZXMgPT0gZW5kU3RhdHMuSGVhcFR5cGVbMF0uU3RhdHMuQmxvY2tCeXRlcyk7DQogICAgDQogICAgQ0hFQ0tfQk9PTChjcHVCdWRnZXQuU3RhdHMuQWxsb2NhdGlvbkJ5dGVzIDw9IGNwdUJ1ZGdldC5TdGF0cy5CbG9ja0J5dGVzKTsNCiAgICBDSEVDS19CT09MKGNwdUJ1ZGdldC5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPT0gZW5kU3RhdHMuSGVhcFR5cGVbMV0uU3RhdHMuQWxsb2NhdGlvbkJ5dGVzICsgZW5kU3RhdHMuSGVhcFR5cGVbMl0uU3RhdHMuQWxsb2NhdGlvbkJ5dGVzKTsNCiAgICBDSEVDS19CT09MKGNwdUJ1ZGdldC5TdGF0cy5CbG9ja0J5dGVzID09DQogICAgICAgIGVuZFN0YXRzLkhlYXBUeXBlWzFdLlN0YXRzLkJsb2NrQnl0ZXMgKyBlbmRTdGF0cy5IZWFwVHlwZVsyXS5TdGF0cy5CbG9ja0J5dGVzKTsNCn0NCg0Kc3RhdGljIHZvaWQgVGVzdFRyYW5zZmVyKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgbWFwcGluZ1xuIik7DQoNCiAgICBjb25zdCBVSU5UIGNvdW50ID0gMTA7DQogICAgY29uc3QgVUlOVDY0IGJ1ZlNpemUgPSAzMnVsbCAqIDEwMjQ7DQogICAgDQogICAgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiByZXNvdXJjZXNVcGxvYWRbY291bnRdOw0KICAgIFJlc291cmNlV2l0aEFsbG9jYXRpb24gcmVzb3VyY2VzRGVmYXVsdFtjb3VudF07DQogICAgUmVzb3VyY2VXaXRoQWxsb2NhdGlvbiByZXNvdXJjZXNSZWFkYmFja1tjb3VudF07DQoNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjVXBsb2FkID0ge307DQogICAgYWxsb2NEZXNjVXBsb2FkLkhlYXBUeXBlID0gRDNEMTJfSEVBUF9UWVBFX1VQTE9BRDsNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjRGVmYXVsdCA9IHt9Ow0KICAgIGFsbG9jRGVzY0RlZmF1bHQuSGVhcFR5cGUgPSBEM0QxMl9IRUFQX1RZUEVfREVGQVVMVDsNCiAgICBEM0QxMk1BOjpBTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjUmVhZGJhY2sgPSB7fTsNCiAgICBhbGxvY0Rlc2NSZWFkYmFjay5IZWFwVHlwZSA9IEQzRDEyX0hFQVBfVFlQRV9SRUFEQkFDSzsNCg0KICAgIEQzRDEyX1JFU09VUkNFX0RFU0MgcmVzb3VyY2VEZXNjOw0KICAgIEZpbGxSZXNvdXJjZURlc2NGb3JCdWZmZXIocmVzb3VyY2VEZXNjLCBidWZTaXplKTsNCg0KICAgIC8vIENyZWF0ZSAzIHNldHMgb2YgcmVzb3VyY2VzLg0KICAgIGZvcihVSU5UIGkgPSAwOyBpIDwgY291bnQ7ICsraSkNCiAgICB7DQogICAgICAgIENIRUNLX0hSKCBjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZSgNCiAgICAgICAgICAgICZhbGxvY0Rlc2NVcGxvYWQsDQogICAgICAgICAgICAmcmVzb3VyY2VEZXNjLA0KICAgICAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfR0VORVJJQ19SRUFELA0KICAgICAgICAgICAgTlVMTCwNCiAgICAgICAgICAgICZyZXNvdXJjZXNVcGxvYWRbaV0uYWxsb2NhdGlvbiwNCiAgICAgICAgICAgIElJRF9QUFZfQVJHUygmcmVzb3VyY2VzVXBsb2FkW2ldLnJlc291cmNlKSkgKTsNCg0KICAgICAgICBDSEVDS19IUiggY3R4LmFsbG9jYXRvci0+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+Q3JlYXRlUmVzb3VyY2UyKCZhbGxvY0Rlc2MsICZyZXNvdXJjZURlc2MsDQogICAgICAgIEQzRDEyX1JFU09VUkNFX1NUQVRFX0NPTU1PTiwgTlVMTCwNCiAgICAgICAgJmFsbG9jUHRyMCwgSUlEX1BQVl9BUkdTKCZyZXMwKSkpOw0KICAgIENIRUNLX0JPT0woYWxsb2NQdHIwLT5HZXRIZWFwKCkgPT0gTlVMTCk7DQoNCiAgICAvLyBDcmVhdGUgYSBwbGFjZWQgYnVmZmVyDQoNCiAgICBhbGxvY0Rlc2MuRmxhZ3MgJj0gfkQzRDEyTUE6OkFMTE9DQVRJT05fRkxBR19DT01NSVRURUQ7DQoNCiAgICBDb21QdHI8RDNEMTJNQTo6QWxsb2NhdGlvbj4gYWxsb2NQdHIxOw0KICAgIENvbVB0cjxJRDNEMTJSZXNvdXJjZT4gcmVzMTsNCiAgICBDSEVDS19IUihjdHguYWxsb2NhdG9yLT5DcmVhdGVSZXNvdXJjZTIoJmFsbG9jRGVzYywgJnJlc291cmNlRGVzYywNCiAgICAgICAgRDNEMTJfUkVTT1VSQ0VfU1RBVEVfQ09NTU9OLCBOVUxMLA0KICAgICAgICAmYWxsb2NQdHIxLCBJSURfUFBWX0FSR1MoJnJlczEpKSk7DQogICAgQ0hFQ0tfQk9PTChhbGxvY1B0cjEtPkdldEhlYXAoKSE9IE5VTEwpOw0KfQ0KI2VuZGlmIC8vICNpZmRlZiBfX0lEM0QxMkRldmljZThfSU5URVJGQUNFX0RFRklORURfXw0KDQpzdGF0aWMgdm9pZCBUZXN0VmlydHVhbEJsb2Nrcyhjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJUZXN0IHZpcnR1YWwgYmxvY2tzXG4iKTsNCg0KICAgIHVzaW5nIG5hbWVzcGFjZSBEM0QxMk1BOw0KDQogICAgY29uc3QgVUlOVDY0IGJsb2NrU2l6ZSA9IDE2ICogTUVHQUJZVEU7DQogICAgY29uc3QgVUlOVDY0IGFsaWdubWVudCA9IDI1NjsNCg0KICAgIC8vICMgQ3JlYXRlIGJsb2NrIDE2IE1CDQoNCiAgICBDb21QdHI8RDNEMTJNQTo6VmlydHVhbEJsb2NrPiBibG9jazsNCiAgICBWSVJUVUFMX0JMT0NLX0RFU0MgYmxvY2tEZXNjID0ge307DQogICAgYmxvY2tEZXNjLnBBbGxvY2F0aW9uQ2FsbGJhY2tzID0gY3R4LmFsbG9jYXRpb25DYWxsYmFja3M7DQogICAgYmxvY2tEZXNjLlNpemUgPSBibG9ja1NpemU7DQogICAgQ0hFQ0tfSFIoQ3JlYXRlVmlydHVhbEJsb2NrKCZibG9ja0Rlc2MsICZibG9jaykpOw0KICAgIENIRUNLX0JPT0woYmxvY2spOw0KDQogICAgLy8gIyBBbGxvY2F0ZSA4IE1CDQoNCiAgICBWSVJUVUFMX0FMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICBhbGxvY0Rlc2MuQWxpZ25tZW50ID0gYWxpZ25tZW50Ow0KICAgIGFsbG9jRGVzYy5wVXNlckRhdGEgPSAodm9pZCopKHVpbnRwdHJfdCkxOw0KICAgIGFsbG9jRGVzYy5TaXplID0gOCAqIE1FR0FCWVRFOw0KICAgIFZpcnR1YWxBbGxvY2F0aW9uIGFsbG9jMDsNCiAgICBDSEVDS19IUihibG9jay0+QWxsb2NhdGUoJmFsbG9jRGVzYywgJmFsbG9jMCwgbnVsbHB0cikpOw0KDQogICAgLy8gIyBWYWxpZGF0ZSB0aGUgYWxsb2NhdGlvbg0KDQogICAgVklSVFVBTF9BTExPQ0FUSU9OX0lORk8gYWxsb2MwSW5mbyA9IHt9Ow0KICAgIGJsb2NrLT5HZXRBbGxvY2F0aW9uSW5mbyhhbGxvYzAsICZhbGxvYzBJbmZvKTsNCiAgICBDSEVDS19CT09MKGFsbG9jMEluZm8uT2Zmc2V0IDwgYmxvY2tTaXplKTsNCiAgICBDSEVDS19CT09MKGFsbG9jMEluZm8uU2l6ZSA9PSBhbGxvY0Rlc2MuU2l6ZSk7DQogICAgQ0hFQ0tfQk9PTChhbGxvYzBJbmZvLnBVc2VyRGF0YSA9PSBhbGxvY0Rlc2MucFVzZXJEYXRhKTsNCg0KICAgIC8vICMgQ2hlY2sgU2V0VXNlckRhdGENCg0KICAgIGJsb2NrLT5TZXRBbGxvY2F0aW9uVXNlckRhdGEoYWxsb2MwLCAodm9pZCopKHVpbnRwdHJfdCkyKTsNCiAgICBibG9jay0+R2V0QWxsb2NhdGlvbkluZm8oYWxsb2MwLCAmYWxsb2MwSW5mbyk7DQogICAgQ0hFQ0tfQk9PTChhbGxvYzBJbmZvLnBVc2VyRGF0YSA9PSAodm9pZCopKHVpbnRwdHJfdCkyKTsNCg0KICAgIC8vICMgQWxsb2NhdGUgNCBNQg0KDQogICAgYWxsb2NEZXNjLlNpemUgPSA0ICogTUVHQUJZVEU7DQogICAgYWxsb2NEZXNjLkFsaWdubWVudCA9IGFsaWdubWVudDsNCiAgICBWaXJ0dWFsQWxsb2NhdGlvbiBhbGxvYzE7DQogICAgQ0hFQ0tfSFIoYmxvY2stPkFsbG9jYXRlKCZhbGxvY0Rlc2MsICZhbGxvYzEsIG51bGxwdHIpKTsNCg0KICAgIFZJUlRVQUxfQUxMT0NBVElPTl9JTkZPIGFsbG9jMUluZm8gPSB7fTsNCiAgICBibG9jay0+R2V0QWxsb2NhdGlvbkluZm8oYWxsb2MxLCAmYWxsb2MxSW5mbyk7DQogICAgQ0hFQ0tfQk9PTChhbGxvYzFJbmZvLk9mZnNldCA8IGJsb2NrU2l6ZSk7DQogICAgQ0hFQ0tfQk9PTChhbGxvYzFJbmZvLk9mZnNldCArIDQgKiBNRUdBQllURSA8PSBhbGxvYzBJbmZvLk9mZnNldCB8fCBhbGxvYzBJbmZvLk9mZnNldCArIDggKiBNRUdBQllURSA8PSBhbGxvYzFJbmZvLk9mZnNldCk7IC8vIENoZWNrIGlmIHRoZXkgZG9uJ3Qgb3ZlcmxhcC4NCg0KICAgIC8vICMgQWxsb2NhdGUgYW5vdGhlciA4IE1CIC0gaXQgc2hvdWxkIGZhaWwNCg0KICAgIGFsbG9jRGVzYy5TaXplID0gOCAqIE1FR0FCWVRFOw0KICAgIGFsbG9jRGVzYy5BbGlnbm1lbnQgPSBhbGlnbm1lbnQ7DQogICAgVmlydHVhbEFsbG9jYXRpb24gYWxsb2MyOw0KICAgIENIRUNLX0JPT0woRkFJTEVEKGJsb2NrLT5BbGxvY2F0ZSgmYWxsb2NEZXNjLCAmYWxsb2MyLCBudWxscHRyKSkpOw0KICAgIENIRUNLX0JPT0woYWxsb2MyLkFsbG9jSGFuZGxlID09IChBbGxvY0hhbmRsZSkwKTsNCg0KICAgIC8vICMgRnJlZSB0aGUgNCBNQiBibG9jay4gTm93IGFsbG9jYXRpb24gb2YgOCBNQiBzaG91bGQgc3VjY2VlZC4NCg0KICAgIGJsb2NrLT5GcmVlQWxsb2NhdGlvbihhbGxvYzEpOw0KICAgIFVJTlQ2NCBhbGxvYzJPZmZzZXQ7DQogICAgQ0hFQ0tfSFIoYmxvY2stPkFsbG9jYXRlKCZhbGxvY0Rlc2MsICZhbGxvYzIsICZhbGxvYzJPZmZzZXQpKTsNCiAgICBDSEVDS19CT09MKGFsbG9jMk9mZnNldCA8IGJsb2NrU2l6ZSk7DQogICAgQ0hFQ0tfQk9PTChhbGxvYzJPZmZzZXQgKyA0ICogTUVHQUJZVEUgPD0gYWxsb2MwSW5mby5PZmZzZXQgfHwgYWxsb2MwSW5mby5PZmZzZXQgKyA4ICogTUVHQUJZVEUgPD0gYWxsb2MyT2Zmc2V0KTsgLy8gQ2hlY2sgaWYgdGhleSBkb24ndCBvdmVybGFwLg0KDQogICAgLy8gIyBDYWxjdWxhdGUgc3RhdGlzdGljcw0KDQogICAgRGV0YWlsZWRTdGF0aXN0aWNzIHN0YXRJbmZvID0ge307DQogICAgYmxvY2stPkNhbGN1bGF0ZVN0YXRpc3RpY3MoJnN0YXRJbmZvKTsNCiAgICBDSEVDS19CT09MKHN0YXRJbmZvLlN0YXRzLkFsbG9jYXRpb25Db3VudCA9PSAyKTsNCiAgICBDSEVDS19CT09MKHN0YXRJbmZvLlN0YXRzLkJsb2NrQ291bnQgPT0gMSk7DQogICAgQ0hFQ0tfQk9PTChzdGF0SW5mby5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPT0gYmxvY2tTaXplKTsNCiAgICBDSEVDS19CT09MKHN0YXRJbmZvLlN0YXRzLkJsb2NrQnl0ZXMgPT0gYmxvY2tTaXplKTsNCg0KICAgIC8vICMgR2VuZXJhdGUgSlNPTiBkdW1wDQoNCiAgICBXQ0hBUioganNvbiA9IG51bGxwdHI7DQogICAgYmxvY2stPkJ1aWxkU3RhdHNTdHJpbmcoJmpzb24pOw0KICAgIHsNCiAgICAgICAgc3RkOjp3c3RyaW5nIHN0cihqc29uKTsNCiAgICAgICAgQ0hFQ0tfQk9PTChzdHIuZmluZChMIlwiVXNlckRhdGFcIjogMSIpICE9IHN0ZDo6d3N0cmluZzo6bnBvcyk7DQogICAgICAgIENIRUNLX0JPT0woc3RyLmZpbmQoTCJcIlVzZXJEYXRhXCI6IDIiKSAhPSBzdGQ6OndzdHJpbmc6Om5wb3MpOw0KICAgIH0NCiAgICBibG9jay0+RnJlZVN0YXRzU3RyaW5nKGpzb24pOw0KDQogICAgLy8gIyBGcmVlIGFsbG9jMCwgbGVhdmUgYWxsb2MyIHVuZnJlZWQuDQoNCiAgICBibG9jay0+RnJlZUFsbG9jYXRpb24oYWxsb2MwKTsNCg0KICAgIC8vICMgVGVzdCBhbGlnbm1lbnQNCg0KICAgIHsNCiAgICAgICAgY29uc3RleHByIHNpemVfdCBhbGxvY0NvdW50ID0gMTA7DQogICAgICAgIFZpcnR1YWxBbGxvY2F0aW9uIGFsbG9jc1thbGxvY0NvdW50XSA9IHt9Ow0KICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGFsbG9jQ291bnQ7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgY29uc3QgYm9vbCBhbGlnbm1lbnQwID0gaSA9PSBhbGxvY0NvdW50IC0gMTsNCiAgICAgICAgICAgIGFsbG9jRGVzYy5TaXplID0gaSAqIDMgKyAxNTsNCiAgICAgICAgICAgIGFsbG9jRGVzYy5BbGlnbm1lbnQgPSBhbGlnbm1lbnQwID8gMCA6IDg7DQogICAgICAgICAgICBVSU5UNjQgb2Zmc2V0Ow0KICAgICAgICAgICAgQ0hFQ0tfSFIoYmxvY2stPkFsbG9jYXRlKCZhbGxvY0Rlc2MsICZhbGxvY3NbaV0sICZvZmZzZXQpKTsNCiAgICAgICAgICAgIGlmICghYWxpZ25tZW50MCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBDSEVDS19CT09MKG9mZnNldCAlIGFsbG9jRGVzYy5BbGlnbm1lbnQgPT0gMCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmb3IgKHNpemVfdCBpID0gYWxsb2NDb3VudDsgaS0tOyApDQogICAgICAgIHsNCiAgICAgICAgICAgIGJsb2NrLT5GcmVlQWxsb2NhdGlvbihhbGxvY3NbaV0pOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8gIyBGaW5hbCBjbGVhbnVwDQoNCiAgICBibG9jay0+RnJlZUFsbG9jYXRpb24oYWxsb2MyKTsNCn0NCg0Kc3RhdGljIHZvaWQgVGVzdFZpcnR1YWxCbG9ja3NBbGdvcml0aG1zKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIlRlc3QgdmlydHVhbCBibG9ja3MgYWxnb3JpdGhtc1xuIik7DQoNCiAgICBSYW5kb21OdW1iZXJHZW5lcmF0b3IgcmFuZHsgMzQ1NDMzNSB9Ow0KICAgIGF1dG8gY2FsY1JhbmRvbUFsbG9jU2l6ZSA9IFsmcmFuZF0oKSAtPiBVSU5UNjQgeyByZXR1cm4gcmFuZC5HZW5lcmF0ZSgpICUgMjAgKyA1OyB9Ow0KDQogICAgZm9yIChzaXplX3QgYWxnb3JpdGhtSW5kZXggPSAwOyBhbGdvcml0aG1JbmRleCA8IDI7ICsrYWxnb3JpdGhtSW5kZXgpDQogICAgew0KICAgICAgICAvLyBDcmVhdGUgdGhlIGJsb2NrDQogICAgICAgIEQzRDEyTUE6OlZJUlRVQUxfQkxPQ0tfREVTQyBibG9ja0Rlc2MgPSB7fTsNCiAgICAgICAgYmxvY2tEZXNjLnBBbGxvY2F0aW9uQ2FsbGJhY2tzID0gY3R4LmFsbG9jYXRpb25DYWxsYmFja3M7DQogICAgICAgIGJsb2NrRGVzYy5TaXplID0gMTAnMDAwOw0KICAgICAgICBzd2l0Y2ggKGFsZ29yaXRobUluZGV4KQ0KICAgICAgICB7DQogICAgICAgIGNhc2UgMDogYmxvY2tEZXNjLkZsYWdzID0gRDNEMTJNQTo6VklSVFVBTF9CTE9DS19GTEFHX05PTkU7IGJyZWFrOw0KICAgICAgICBjYXNlIDE6IGJsb2NrRGVzYy5GbGFncyA9IEQzRDEyTUE6OlZJUlRVQUxfQkxPQ0tfRkxBR19BTEdPUklUSE1fTElORUFSOyBicmVhazsNCiAgICAgICAgfQ0KICAgICAgICBDb21QdHI8RDNEMTJNQTo6VmlydHVhbEJsb2NrPiBibG9jazsNCiAgICAgICAgQ0hFQ0tfSFIoRDNEMTJNQTo6Q3JlYXRlVmlydHVhbEJsb2NrKCZibG9ja0Rlc2MsICZibG9jaykpOw0KDQogICAgICAgIHN0cnVjdCBBbGxvY0RhdGENCiAgICAgICAgew0KICAgICAgICAgICAgRDNEMTJNQTo6VmlydHVhbEFsbG9jYXRpb24gYWxsb2NhdGlvbjsNCiAgICAgICAgICAgIFVJTlQ2NCBhbGxvY09mZnNldCwgcmVxdWVzdGVkU2l6ZSwgYWxsb2NhdGlvblNpemU7DQogICAgICAgIH07DQogICAgICAgIHN0ZDo6dmVjdG9yPEFsbG9jRGF0YT4gYWxsb2NhdGlvbnM7DQoNCiAgICAgICAgLy8gTWFrZSBzb21lIGFsbG9jYXRpb25zDQogICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgMjA7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgRDNEMTJNQTo6VklSVFVBTF9BTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgICAgICAgICBhbGxvY0Rlc2MuU2l6ZSA9IGNhbGNSYW5kb21BbGxvY1NpemUoKTsNCiAgICAgICAgICAgIGFsbG9jRGVzYy5wVXNlckRhdGEgPSAodm9pZCopKHVpbnRwdHJfdCkoYWxsb2NEZXNjLlNpemUgKiAxMCk7DQogICAgICAgICAgICBpZiAoaSA8IDEwKSB7fQ0KICAgICAgICAgICAgZWxzZSBpZiAoaSA8IDIwICYmIGFsZ29yaXRobUluZGV4ID09IDEpIGFsbG9jRGVzYy5GbGFncyA9IEQzRDEyTUE6OlZJUlRVQUxfQUxMT0NBVElPTl9GTEFHX1VQUEVSX0FERFJFU1M7DQoNCiAgICAgICAgICAgIEFsbG9jRGF0YSBhbGxvYyA9IHt9Ow0KICAgICAgICAgICAgYWxsb2MucmVxdWVzdGVkU2l6ZSA9IGFsbG9jRGVzYy5TaXplOw0KICAgICAgICAgICAgQ0hFQ0tfSFIoYmxvY2stPkFsbG9jYXRlKCZhbGxvY0Rlc2MsICZhbGxvYy5hbGxvY2F0aW9uLCBudWxscHRyKSk7DQoNCiAgICAgICAgICAgIEQzRDEyTUE6OlZJUlRVQUxfQUxMT0NBVElPTl9JTkZPIGFsbG9jSW5mbzsNCiAgICAgICAgICAgIGJsb2NrLT5HZXRBbGxvY2F0aW9uSW5mbyhhbGxvYy5hbGxvY2F0aW9uLCAmYWxsb2NJbmZvKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woYWxsb2NJbmZvLlNpemUgPj0gYWxsb2NEZXNjLlNpemUpOw0KICAgICAgICAgICAgYWxsb2MuYWxsb2NPZmZzZXQgPSBhbGxvY0luZm8uT2Zmc2V0Ow0KICAgICAgICAgICAgYWxsb2MuYWxsb2NhdGlvblNpemUgPSBhbGxvY0luZm8uU2l6ZTsNCg0KICAgICAgICAgICAgYWxsb2NhdGlvbnMucHVzaF9iYWNrKGFsbG9jKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIEZyZWUgc29tZSBvZiB0aGUgYWxsb2NhdGlvbnMNCiAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCA1OyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbnN0IHNpemVfdCBpbmRleCA9IHJhbmQuR2VuZXJhdGUoKSAlIGFsbG9jYXRpb25zLnNpemUoKTsNCiAgICAgICAgICAgIGJsb2NrLT5GcmVlQWxsb2NhdGlvbihhbGxvY2F0aW9uc1tpbmRleF0uYWxsb2NhdGlvbik7DQogICAgICAgICAgICBhbGxvY2F0aW9ucy5lcmFzZShhbGxvY2F0aW9ucy5iZWdpbigpICsgaW5kZXgpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQWxsb2NhdGUgc29tZSBtb3JlDQogICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgNjsgKytpKQ0KICAgICAgICB7DQogICAgICAgICAgICBEM0QxMk1BOjpWSVJUVUFMX0FMTE9DQVRJT05fREVTQyBhbGxvY0Rlc2MgPSB7fTsNCiAgICAgICAgICAgIGFsbG9jRGVzYy5TaXplID0gY2FsY1JhbmRvbUFsbG9jU2l6ZSgpOw0KICAgICAgICAgICAgYWxsb2NEZXNjLnBVc2VyRGF0YSA9ICh2b2lkKikodWludHB0cl90KShhbGxvY0Rlc2MuU2l6ZSAqIDEwKTsNCg0KICAgICAgICAgICAgQWxsb2NEYXRhIGFsbG9jID0ge307DQogICAgICAgICAgICBhbGxvYy5yZXF1ZXN0ZWRTaXplID0gYWxsb2NEZXNjLlNpemU7DQogICAgICAgICAgICBDSEVDS19IUihibG9jay0+QWxsb2NhdGUoJmFsbG9jRGVzYywgJmFsbG9jLmFsbG9jYXRpb24sIG51bGxwdHIpKTsNCg0KICAgICAgICAgICAgRDNEMTJNQTo6VklSVFVBTF9BTExPQ0FUSU9OX0lORk8gYWxsb2NJbmZvOw0KICAgICAgICAgICAgYmxvY2stPkdldEFsbG9jYXRpb25JbmZvKGFsbG9jLmFsbG9jYXRpb24sICZhbGxvY0luZm8pOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChhbGxvY0luZm8uU2l6ZSA+PSBhbGxvY0Rlc2MuU2l6ZSk7DQogICAgICAgICAgICBhbGxvYy5hbGxvY09mZnNldCA9IGFsbG9jSW5mby5PZmZzZXQ7DQogICAgICAgICAgICBhbGxvYy5hbGxvY2F0aW9uU2l6ZSA9IGFsbG9jSW5mby5TaXplOw0KDQogICAgICAgICAgICBhbGxvY2F0aW9ucy5wdXNoX2JhY2soYWxsb2MpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQWxsb2NhdGUgc29tZSB3aXRoIGV4dHJhIGFsaWdubWVudA0KICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IDM7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgRDNEMTJNQTo6VklSVFVBTF9BTExPQ0FUSU9OX0RFU0MgYWxsb2NEZXNjID0ge307DQogICAgICAgICAgICBhbGxvY0Rlc2MuU2l6ZSA9IGNhbGNSYW5kb21BbGxvY1NpemUoKTsNCiAgICAgICAgICAgIGFsbG9jRGVzYy5BbGlnbm1lbnQgPSAxNjsNCiAgICAgICAgICAgIGFsbG9jRGVzYy5wVXNlckRhdGEgPSAodm9pZCopKHVpbnRwdHJfdCkoYWxsb2NEZXNjLlNpemUgKiAxMCk7DQoNCiAgICAgICAgICAgIEFsbG9jRGF0YSBhbGxvYyA9IHt9Ow0KICAgICAgICAgICAgYWxsb2MucmVxdWVzdGVkU2l6ZSA9IGFsbG9jRGVzYy5TaXplOw0KICAgICAgICAgICAgQ0hFQ0tfSFIoYmxvY2stPkFsbG9jYXRlKCZhbGxvY0Rlc2MsICZhbGxvYy5hbGxvY2F0aW9uLCBudWxscHRyKSk7DQoNCiAgICAgICAgICAgIEQzRDEyTUE6OlZJUlRVQUxfQUxMT0NBVElPTl9JTkZPIGFsbG9jSW5mbzsNCiAgICAgICAgICAgIGJsb2NrLT5HZXRBbGxvY2F0aW9uSW5mbyhhbGxvYy5hbGxvY2F0aW9uLCAmYWxsb2NJbmZvKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woYWxsb2NJbmZvLk9mZnNldCAlIDE2ID09IDApOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChhbGxvY0luZm8uU2l6ZSA+PSBhbGxvY0Rlc2MuU2l6ZSk7DQogICAgICAgICAgICBhbGxvYy5hbGxvY09mZnNldCA9IGFsbG9jSW5mby5PZmZzZXQ7DQogICAgICAgICAgICBhbGxvYy5hbGxvY2F0aW9uU2l6ZSA9IGFsbG9jSW5mby5TaXplOw0KDQogICAgICAgICAgICBhbGxvY2F0aW9ucy5wdXNoX2JhY2soYWxsb2MpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGFsbG9jYXRpb25zIGRvbid0IG92ZXJsYXANCiAgICAgICAgc3RkOjpzb3J0KGFsbG9jYXRpb25zLmJlZ2luKCksIGFsbG9jYXRpb25zLmVuZCgpLCBbXShjb25zdCBBbGxvY0RhdGEmIGxocywgY29uc3QgQWxsb2NEYXRhJiByaHMpIHsNCiAgICAgICAgICAgIHJldHVybiBsaHMuYWxsb2NPZmZzZXQgPCByaHMuYWxsb2NPZmZzZXQ7IH0pOw0KICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGFsbG9jYXRpb25zLnNpemUoKSAtIDE7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChhbGxvY2F0aW9uc1tpICsgMV0uYWxsb2NPZmZzZXQgPj0gYWxsb2NhdGlvbnNbaV0uYWxsb2NPZmZzZXQgKyBhbGxvY2F0aW9uc1tpXS5hbGxvY2F0aW9uU2l6ZSk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDaGVjayBwVXNlckRhdGENCiAgICAgICAgew0KICAgICAgICAgICAgY29uc3QgQWxsb2NEYXRhJiBhbGxvYyA9IGFsbG9jYXRpb25zLmJhY2soKTsNCiAgICAgICAgICAgIEQzRDEyTUE6OlZJUlRVQUxfQUxMT0NBVElPTl9JTkZPIGFsbG9jSW5mbzsNCiAgICAgICAgICAgIGJsb2NrLT5HZXRBbGxvY2F0aW9uSW5mbyhhbGxvYy5hbGxvY2F0aW9uLCAmYWxsb2NJbmZvKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woKHVpbnRwdHJfdClhbGxvY0luZm8ucFVzZXJEYXRhID09IGFsbG9jLnJlcXVlc3RlZFNpemUgKiAxMCk7DQoNCiAgICAgICAgICAgIGJsb2NrLT5TZXRBbGxvY2F0aW9uVXNlckRhdGEoYWxsb2MuYWxsb2NhdGlvbiwgKHZvaWQqKSh1aW50cHRyX3QpNjY2KTsNCiAgICAgICAgICAgIGJsb2NrLT5HZXRBbGxvY2F0aW9uSW5mbyhhbGxvYy5hbGxvY2F0aW9uLCAmYWxsb2NJbmZvKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woKHVpbnRwdHJfdClhbGxvY0luZm8ucFVzZXJEYXRhID09IDY2Nik7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxjdWxhdGUgc3RhdGlzdGljcw0KICAgICAgICB7DQogICAgICAgICAgICBVSU5UNjQgYWN0dWFsQWxsb2NTaXplTWluID0gVUlOVDY0X01BWCwgYWN0dWFsQWxsb2NTaXplTWF4ID0gMCwgYWN0dWFsQWxsb2NTaXplU3VtID0gMDsNCiAgICAgICAgICAgIHN0ZDo6Zm9yX2VhY2goYWxsb2NhdGlvbnMuYmVnaW4oKSwgYWxsb2NhdGlvbnMuZW5kKCksIFsmXShjb25zdCBBbGxvY0RhdGEmIGEpIHsNCiAgICAgICAgICAgICAgICBhY3R1YWxBbGxvY1NpemVNaW4gPSBzdGQ6Om1pbihhY3R1YWxBbGxvY1NpemVNaW4sIGEuYWxsb2NhdGlvblNpemUpOw0KICAgICAgICAgICAgICAgIGFjdHVhbEFsbG9jU2l6ZU1heCA9IHN0ZDo6bWF4KGFjdHVhbEFsbG9jU2l6ZU1heCwgYS5hbGxvY2F0aW9uU2l6ZSk7DQogICAgICAgICAgICAgICAgYWN0dWFsQWxsb2NTaXplU3VtICs9IGEuYWxsb2NhdGlvblNpemU7DQogICAgICAgICAgICAgICAgfSk7DQoNCiAgICAgICAgICAgIEQzRDEyTUE6OkRldGFpbGVkU3RhdGlzdGljcyBzdGF0SW5mbyA9IHt9Ow0KICAgICAgICAgICAgYmxvY2stPkNhbGN1bGF0ZVN0YXRpc3RpY3MoJnN0YXRJbmZvKTsNCiAgICAgICAgICAgIENIRUNLX0JPT0woc3RhdEluZm8uU3RhdHMuQWxsb2NhdGlvbkNvdW50ID09IGFsbG9jYXRpb25zLnNpemUoKSk7DQogICAgICAgICAgICBDSEVDS19CT09MKHN0YXRJbmZvLlN0YXRzLkJsb2NrQ291bnQgPT0gMSk7DQogICAgICAgICAgICBDSEVDS19CT09MKHN0YXRJbmZvLlN0YXRzLkJsb2NrQnl0ZXMgPT0gYmxvY2tEZXNjLlNpemUpOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChzdGF0SW5mby5BbGxvY2F0aW9uU2l6ZU1heCA9PSBhY3R1YWxBbGxvY1NpemVNYXgpOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChzdGF0SW5mby5BbGxvY2F0aW9uU2l6ZU1pbiA9PSBhY3R1YWxBbGxvY1NpemVNaW4pOw0KICAgICAgICAgICAgQ0hFQ0tfQk9PTChzdGF0SW5mby5TdGF0cy5BbGxvY2F0aW9uQnl0ZXMgPj0gYWN0dWFsQWxsb2NTaXplU3VtKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIEJ1aWxkIEpTT04gZHVtcCBzdHJpbmcNCiAgICAgICAgew0KICAgICAgICAgICAgV0NIQVIqIGpzb24gPSBudWxscHRyOw0KICAgICAgICAgICAgYmxvY2stPkJ1aWxkU3RhdHNTdHJpbmcoJmpzb24pOw0KICAgICAgICAgICAgaW50IEkgPSAwOyAvLyBwdXQgYSBicmVha3BvaW50IGhlcmUgdG8gZGVidWcNCiAgICAgICAgICAgIGJsb2NrLT5GcmVlU3RhdHNTdHJpbmcoanNvbik7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBGaW5hbCBjbGVhbnVwDQogICAgICAgIGJsb2NrLT5DbGVhcigpOw0KICAgIH0NCn0NCg0Kc3RhdGljIHZvaWQgVGVzdFZpcnR1YWxCbG9ja3NBbGdvcml0aG1zQmVuY2htYXJrKGNvbnN0IFRlc3RDb250ZXh0JiBjdHgpDQp7DQogICAgd3ByaW50ZihMIkJlbmNobWFyayB2aXJ0dWFsIGJsb2NrcyBhbGdvcml0aG1zXG4iKTsNCg0KICAgIGNvbnN0IHNpemVfdCBBTExPQ0FUSU9OX0NPVU5UID0gNzIwMDsNCiAgICBjb25zdCBVSU5UMzIgTUFYX0FMTE9DX1NJWkUgPSAyMDU2Ow0KDQogICAgRDNEMTJNQTo6VklSVFVBTF9CTE9DS19ERVNDIGJsb2NrRGVzYyA9IHt9Ow0KICAgIGJsb2NrRGVzYy5wQWxsb2NhdGlvbkNhbGxiYWNrcyA9IGN0eC5hbGxvY2F0aW9uQ2FsbGJhY2tzOw0KICAgIGJsb2NrRGVzYy5TaXplID0gMDsNCg0KICAgIFJhbmRvbU51bWJlckdlbmVyYXRvciByYW5keyAyMDA5MjAxMCB9Ow0KDQogICAgVUlOVDMyIGFsbG9jU2l6ZXNbQUxMT0NBVElPTl9DT1VOVF07DQogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBBTExPQ0FUSU9OX0NPVU5UOyArK2kpDQogICAgew0KICAgICAgICBhbGxvY1NpemVzW2ldID0gcmFuZC5HZW5lcmF0ZSgpICUgTUFYX0FMTE9DX1NJWkUgKyAxOw0KICAgICAgICBibG9ja0Rlc2MuU2l6ZSArPSBhbGxvY1NpemVzW2ldOw0KICAgIH0NCiAgICBibG9ja0Rlc2MuU2l6ZSA9IHN0YXRpY19jYXN0PFVJTlQ2ND4oYmxvY2tEZXNjLlNpemUgKiAxLjUpOyAvLyA1MCUgc2l6ZSBtYXJnaW4gaW4gY2FzZSBvZiBhbGlnbm1lbnQNCg0KICAgIGZvciAoVUlOVDggYWxpZ25tZW50SW5kZXggPSAwOyBhbGlnbm1lbnRJbmRleCA8IDQ7ICsrYWxpZ25tZW50SW5kZXgpDQogICAgew0KICAgICAgICBVSU5UNjQgYWxpZ25tZW50Ow0KICAgICAgICBzd2l0Y2ggKGFsaWdubWVudEluZGV4KQ0KICAgICAgICB7DQogICAgICAgIGNhc2UgMDogYWxpZ25tZW50ID0gMTsgYnJlYWs7DQogICAgICAgIGNhc2UgMTogYWxpZ25tZW50ID0gMTY7IGJyZWFrOw0KICAgICAgICBjYXNlIDI6IGFsaWdubWVudCA9IDY0OyBicmVhazsNCiAgICAgICAgY2FzZSAzOiBhbGlnbm1lbnQgPSAyNTY7IGJyZWFrOw0KICAgICAgICBkZWZhdWx0OiBhc3NlcnQoMCk7IGJyZWFrOw0KICAgICAgICB9DQogICAgICAgIHByaW50ZigiICAgIEFsaWdubWVudD0lbGx1XG4iLCBhbGlnbm1lbnQpOw0KDQogICAgICAgIGZvciAoVUlOVDggYWxnb3JpdGhtSW5kZXggPSAwOyBhbGdvcml0aG1JbmRleCA8IDI7ICsrYWxnb3JpdGhtSW5kZXgpDQogICAgICAgIHsNCiAgICAgICAgICAgIHN3aXRjaCAoYWxnb3JpdGhtSW5kZXgpDQogICAgICAgICAgICB7DQogICAgICAgICAgICBjYXNlIDA6DQogICAgICAgICAgICAgICAgYmxvY2tEZXNjLkZsYWdzID0gRDNEMTJNQTo6VklSVFVBTF9CTE9DS19GTEFHX05PTkU7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBjYXNlIDE6DQogICAgICAgICAgICAgICAgYmxvY2tEZXNjLkZsYWdzID0gRDNEMTJNQTo6VklSVFVBTF9CTE9DS19GTEFHX0FMR09SSVRITV9MSU5FQVI7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBkZWZhdWx0Og0KICAgICAgICAgICAgICAgIGFzc2VydCgwKTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgRDNEMTJNQTo6VmlydHVhbEFsbG9jYXRpb24gYWxsb2NzW0FMTE9DQVRJT05fQ09VTlRdOw0KICAgICAgICAgICAgQ29tUHRyPEQzRDEyTUE6OlZpcnR1YWxCbG9jaz4gYmxvY2s7DQogICAgICAgICAgICBDSEVDS19IUihEM0QxMk1BOjpDcmVhdGVWaXJ0dWFsQmxvY2soJmJsb2NrRGVzYywgJmJsb2NrKSk7DQogICAgICAgICAgICBkdXJhdGlvbiBhbGxvY0R1cmF0aW9uID0gZHVyYXRpb246Onplcm8oKTsNCiAgICAgICAgICAgIGR1cmF0aW9uIGZyZWVEdXJhdGlvbiA9IGR1cmF0aW9uOjp6ZXJvKCk7DQoNCiAgICAgICAgICAgIC8vIEFsbG9jDQogICAgICAgICAgICB0aW1lX3BvaW50IHRpbWVCZWdpbiA9IHN0ZDo6Y2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpOw0KICAgICAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBBTExPQ0FUSU9OX0NPVU5UOyArK2kpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgRDNEMTJNQTo6VklSVFVBTF9BTExPQ0FUSU9OX0RFU0MgYWxsb2NDcmVhdGVJbmZvID0ge307DQogICAgICAgICAgICAgICAgYWxsb2NDcmVhdGVJbmZvLlNpemUgPSBhbGxvY1NpemVzW2ldOw0KICAgICAgICAgICAgICAgIGFsbG9jQ3JlYXRlSW5mby5BbGlnbm1lbnQgPSBhbGlnbm1lbnQ7DQoNCiAgICAgICAgICAgICAgICBDSEVDS19IUihibG9jay0+QWxsb2NhdGUoJmFsbG9jQ3JlYXRlSW5mbywgYWxsb2NzICsgaSwgbnVsbHB0cikpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgYWxsb2NEdXJhdGlvbiArPSBzdGQ6OmNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKSAtIHRpbWVCZWdpbjsNCg0KICAgICAgICAgICAgLy8gRnJlZQ0KICAgICAgICAgICAgdGltZUJlZ2luID0gc3RkOjpjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCk7DQogICAgICAgICAgICBmb3IgKHNpemVfdCBpID0gQUxMT0NBVElPTl9DT1VOVDsgaTspDQogICAgICAgICAgICAgICAgYmxvY2stPkZyZWVBbGxvY2F0aW9uKGFsbG9jc1stLWldKTsNCiAgICAgICAgICAgIGZyZWVEdXJhdGlvbiArPSBzdGQ6OmNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKSAtIHRpbWVCZWdpbjsNCg0KICAgICAgICAgICAgcHJpbnRmKCIgICAgICAgIEFsZ29yaXRobT0lcyAgXHRhbGxvY2F0aW9ucyAlZyBzLCAgIFx0ZnJlZSAlZyBzXG4iLA0KICAgICAgICAgICAgICAgIFZpcnR1YWxBbGdvcml0aG1Ub1N0cihibG9ja0Rlc2MuRmxhZ3MpLA0KICAgICAgICAgICAgICAgIFRvRmxvYXRTZWNvbmRzKGFsbG9jRHVyYXRpb24pLA0KICAgICAgICAgICAgICAgIFRvRmxvYXRTZWNvbmRzKGZyZWVEdXJhdGlvbikpOw0KICAgICAgICB9DQogICAgICAgIHByaW50ZigiXG4iKTsNCiAgICB9DQp9DQoNCnN0YXRpYyB2b2lkIFRlc3RHcm91cFZpcnR1YWwoY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiAgICBUZXN0VmlydHVhbEJsb2NrcyhjdHgpOw0KICAgIFRlc3RWaXJ0dWFsQmxvY2tzQWxnb3JpdGhtcyhjdHgpOw0KICAgIFRlc3RWaXJ0dWFsQmxvY2tzQWxnb3JpdGhtc0JlbmNobWFyayhjdHgpOw0KfQ0KDQpzdGF0aWMgdm9pZCBUZXN0R3JvdXBCYXNpY3MoY29uc3QgVGVzdENvbnRleHQmIGN0eCkNCnsNCiNpZiBEM0QxMk1BX0RFQlVHX01BUkdJTg0KICAgIFRlc3REZWJ1Z01hcmdpbihjdHgpOw0KICAgIFRlc3REZWJ1Z01hcmdpbk5vdEluVmlydHVhbEFsbG9jYXRvcihjdHgpOw0KI2Vsc2UNCiAgICBUZXN0RnJhbWVJbmRleEFuZEpzb24oY3R4KTsNCiAgICBUZXN0Q29tbWl0dGVkUmVzb3VyY2VzQW5kSnNvbihjdHgpOw0KICAgIFRlc3RDdXN0b21IZWFwRmxhZ3MoY3R4KTsNCiAgICBUZXN0UGxhY2VkUmVzb3VyY2VzKGN0eCk7DQogICAgVGVzdE90aGVyQ29tSW50ZXJmYWNlKGN0eCk7DQogICAgVGVzdEN1c3RvbVBvb2xzKGN0eCk7DQogICAgVGVzdEN1c3RvbVBvb2xfTWluQWxsb2NhdGlvbkFsaWdubWVudChjdHgpOw0KICAgIFRlc3RDdXN0b21Qb29sX0NvbW1pdHRlZChjdHgpOw0KICAgIFRlc3RQb29sc0FuZEFsbG9jYXRpb25QYXJhbWV0ZXJzKGN0eCk7DQogICAgVGVzdEN1c3RvbUhlYXBzKGN0eCk7DQogICAgVGVzdFN0YW5kYXJkQ3VzdG9tQ29tbWl0dGVkUGxhY2VkKGN0eCk7DQogICAgVGVzdEFsaWFzaW5nTWVtb3J5KGN0eCk7DQogICAgVGVzdE1hcHBpbmcoY3R4KTsNCiAgICBUZXN0U3RhdHMoY3R4KTsNCiAgICBUZXN0VHJhbnNmZXIoY3R4KTsNCiAgICBUZXN0WmVyb0luaXRpYWxpemVkKGN0eCk7DQogICAgVGVzdE11bHRpdGhyZWFkaW5nKGN0eCk7DQogICAgVGVzdExpbmVhckFsbG9jYXRvcihjdHgpOw0KICAgIFRlc3RMaW5lYXJBbGxvY2F0b3JNdWx0aUJsb2NrKGN0eCk7DQogICAgTWFudWFsbHlUZXN0TGluZWFyQWxsb2NhdG9yKGN0eCk7DQojaWZkZWYgX19JRDNEMTJEZXZpY2U0X0lOVEVSRkFDRV9ERUZJTkVEX18NCiAgICBUZXN0RGV2aWNlNChjdHgpOw0KI2VuZGlmDQojaWZkZWYgX19JRDNEMTJEZXZpY2U4X0lOVEVSRkFDRV9ERUZJTkVEX18NCiAgICBUZXN0RGV2aWNlOChjdHgpOw0KI2VuZGlmDQoNCiAgICBGSUxFKiBmaWxlOw0KICAgIGZvcGVuX3MoJmZpbGUsICJSZXN1bHRzLmNzdiIsICJ3Iik7DQogICAgYXNzZXJ0KGZpbGUgIT0gTlVMTCk7DQogICAgQmVuY2htYXJrQWxnb3JpdGhtcyhjdHgsIGZpbGUpOw0KICAgIGZjbG9zZShmaWxlKTsNCiNlbmRpZiAvLyAjaWYgRDNEMTJfREVCVUdfTUFSR0lODQp9DQoNCnZvaWQgVGVzdChjb25zdCBUZXN0Q29udGV4dCYgY3R4KQ0Kew0KICAgIHdwcmludGYoTCJURVNUUyBCRUdJTlxuIik7DQoNCiAgICBpZihmYWxzZSkNCiAgICB7DQogICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQogICAgICAgIC8vIFRlbXBvcmFyaWx5IGluc2VydCBjdXN0b20gdGVzdHMgaGVyZToNCiAgICAgICAgcmV0dXJuOw0KICAgIH0NCg0KICAgIFRlc3RHcm91cFZpcnR1YWwoY3R4KTsNCiAgICBUZXN0R3JvdXBCYXNpY3MoY3R4KTsNCg0KICAgIHdwcmludGYoTCJURVNUUyBFTkRcbiIpOw0KfQ0K