Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KIA0KLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCg0KI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIg0KI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCINCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQnV0dG9uLmgiDQojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXRDdHJsLmgiDQojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXQuaCINCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGlzdEN0cmwuaCINCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmgiDQojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX05vdGUuaCINCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGFiZWwuaCINCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdC5oIg0KI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9TY3JvbGxCYXIuaCINCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCINCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQ2FyZXQuaCINCg0KI2RlZmluZSBQT1BVUF9JVEVNX0hFQURfQk9UVE9NCQkJCQkzLjBmDQojZGVmaW5lIFBPUFVQX0lURU1fQk9UVE9NV0lEVEgJCQkJCTEuMGYNCiNkZWZpbmUgUE9QVVBfSVRFTV9TSURFTUFSR0lOCQkJCQkzLjBmDQojZGVmaW5lIFBPUFVQX0lURU1fU1BBQ0UJCQkJCQk0LjBmDQojZGVmaW5lIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQJCQkJCTIuMGYNCiNkZWZpbmUgUE9QVVBfSVRFTV9CT1JERVJDT0xPUgkJCQkJQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLCA4MC8yNTUuMGYsIDgwLzI1NS4wZiwgODAvMjU1LjBmKQ0KDQojZGVmaW5lIElzRmxvYXRaZXJvKGYpCQkJCQkJKChmKSA8IDAuMDAwMSAmJiAoZikgPiAtMC4wMDAxKQ0KI2RlZmluZSBJc0Zsb2F0QmlnZ2VyKGZhLGZiKQkJCQkoKGZhKSA+IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkNCiNkZWZpbmUgSXNGbG9hdFNtYWxsZXIoZmEsZmIpCQkJCSgoZmEpIDwgKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQ0KI2RlZmluZSBJc0Zsb2F0RXF1YWwoZmEsZmIpCQkJCQlJc0Zsb2F0WmVybygoZmEpLShmYikpDQoNCg0KLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfT3B0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQoNCkNQV0xfTm90ZV9PcHRpb25zOjpDUFdMX05vdGVfT3B0aW9ucygpIDogbV9wVGV4dChOVUxMKQ0Kew0KfQ0KDQpDUFdMX05vdGVfT3B0aW9uczo6fkNQV0xfTm90ZV9PcHRpb25zKCkNCnsNCn0NCg0Kdm9pZCBDUFdMX05vdGVfT3B0aW9uczo6U2V0VGV4dENvbG9yKGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcikNCnsNCglDUFdMX1duZDo6U2V0VGV4dENvbG9yKGNvbG9yKTsNCg0KCWlmIChtX3BUZXh0KQ0KCQltX3BUZXh0LT5TZXRUZXh0Q29sb3IoY29sb3IpOw0KfQ0KDQp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpSZVBvc0NoaWxkV25kKCkNCnsNCglpZiAodGhpcy0+SXNWYWxpZCgpKQ0KCXsNCgkJQVNTRVJUKG1fcFRleHQgIT0gTlVMTCk7DQoNCgkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOw0KDQoJCWlmIChyY0NsaWVudC5XaWR0aCgpID4gMTUuMGYpDQoJCXsNCgkJCXJjQ2xpZW50LnJpZ2h0IC09IDE1LjBmOw0KCQkJbV9wVGV4dC0+TW92ZShyY0NsaWVudCwgVFJVRSwgRkFMU0UpOw0KCQkJbV9wVGV4dC0+U2V0VmlzaWJsZShUUlVFKTsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCW1fcFRleHQtPk1vdmUoQ1BERl9SZWN0KDAsMCwwLDApLCBUUlVFLCBGQUxTRSk7DQoJCQltX3BUZXh0LT5TZXRWaXNpYmxlKEZBTFNFKTsNCgkJfQ0KCX0NCn0NCg0Kdm9pZCBDUFdMX05vdGVfT3B0aW9uczo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApDQp7DQoJbV9wVGV4dCA9IG5ldyBDUFdMX0xhYmVsOw0KCVBXTF9DUkVBVEVQQVJBTSB0Y3AgPSBjcDsNCgl0Y3AucFBhcmVudFduZCA9IHRoaXM7DQoJdGNwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRTsNCgltX3BUZXh0LT5DcmVhdGUodGNwKTsNCn0NCg0Kdm9pZCBDUFdMX05vdGVfT3B0aW9uczo6U2V0VGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RleHQpDQp7DQoJbV9wVGV4dC0+U2V0VGV4dChzVGV4dCk7DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlX09wdGlvbnM6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQ0Kew0KCUNQV0xfV25kOjpEcmF3VGhpc0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlKTsNCg0KCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsNCglyY0NsaWVudC5sZWZ0ID0gcmNDbGllbnQucmlnaHQgLSAxNS4wZjsNCg0KCUNQREZfUG9pbnQgcHRDZW50ZXIgPSBDUERGX1BvaW50KChyY0NsaWVudC5sZWZ0ICsgcmNDbGllbnQucmlnaHQpICogMC41ZiwgKHJjQ2xpZW50LnRvcCArIHJjQ2xpZW50LmJvdHRvbSkgKiAwLjVmKTsNCg0KCUNQREZfUG9pbnQgcHQxKHB0Q2VudGVyLnggLSAyLjBmLCBwdENlbnRlci55ICsgMi4wZiAqIDAuNWYpOw0KCUNQREZfUG9pbnQgcHQyKHB0Q2VudGVyLnggKyAyLjBmLCBwdENlbnRlci55ICsgMi4wZiAqIDAuNWYpOw0KCUNQREZfUG9pbnQgcHQzKHB0Q2VudGVyLngsIHB0Q2VudGVyLnkgLSAzLjBmICogMC41Zik7DQoNCglDRlhfUGF0aERhdGEgcGF0aDsNCg0KCXBhdGguU2V0UG9pbnRDb3VudCg0KTsNCglwYXRoLlNldFBvaW50KDAsIHB0MS54LCBwdDEueSwgRlhQVF9NT1ZFVE8pOw0KCXBhdGguU2V0UG9pbnQoMSwgcHQyLngsIHB0Mi55LCBGWFBUX0xJTkVUTyk7DQoJcGF0aC5TZXRQb2ludCgyLCBwdDMueCwgcHQzLnksIEZYUFRfTElORVRPKTsNCglwYXRoLlNldFBvaW50KDMsIHB0MS54LCBwdDEueSwgRlhQVF9MSU5FVE8pOw0KDQoJcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgTlVMTCwgDQoJCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpLEdldFRyYW5zcGFyZW5jeSgpKSwgDQoJCTAsIEZYRklMTF9BTFRFUk5BVEUpOw0KfQ0KDQpDUERGX1JlY3QgQ1BXTF9Ob3RlX09wdGlvbnM6OkdldENvbnRlbnRSZWN0KCkgY29uc3QNCnsNCglBU1NFUlQobV9wVGV4dCAhPSBOVUxMKTsNCg0KCUNQREZfUmVjdCByY1RleHQgPSBtX3BUZXh0LT5HZXRDb250ZW50UmVjdCgpOw0KCXJjVGV4dC5yaWdodCArPSAxNS4wZjsNCglyZXR1cm4gcmNUZXh0Ow0KfQ0KDQovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9FZGl0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KDQpDUFdMX05vdGVfRWRpdDo6Q1BXTF9Ob3RlX0VkaXQoKSA6IG1fYkVuYWJsZU5vdGlmeShUUlVFKSwNCgltX2ZPbGRJdGVtSGVpZ2h0KDAuMGYpLA0KCW1fYlNpemVDaGFuZ2VkKEZBTFNFKSwNCgltX2ZPbGRNaW4oMC4wZiksDQoJbV9mT2xkTWF4KDAuMGYpDQp7DQp9DQoNCkNQV0xfTm90ZV9FZGl0Ojp+Q1BXTF9Ob3RlX0VkaXQoKQ0Kew0KfQ0KDQp2b2lkIENQV0xfTm90ZV9FZGl0OjpSZVBvc0NoaWxkV25kKCkNCnsNCgltX2JFbmFibGVOb3RpZnkgPSBGQUxTRTsJDQoJQ1BXTF9FZGl0OjpSZVBvc0NoaWxkV25kKCk7DQoJbV9iRW5hYmxlTm90aWZ5ID0gVFJVRTsNCg0KCW1fZk9sZEl0ZW1IZWlnaHQgPSB0aGlzLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOw0KfQ0KDQp2b2lkIENQV0xfTm90ZV9FZGl0OjpTZXRUZXh0KEZYX0xQQ1dTVFIgY3NUZXh0KQ0Kew0KCW1fYkVuYWJsZU5vdGlmeSA9IEZBTFNFOw0KCUNQV0xfRWRpdDo6U2V0VGV4dChjc1RleHQpOw0KCW1fYkVuYWJsZU5vdGlmeSA9IFRSVUU7CQ0KCW1fZk9sZEl0ZW1IZWlnaHQgPSB0aGlzLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOw0KfQ0KDQp2b2lkIENQV0xfTm90ZV9FZGl0OjpPblNldEZvY3VzKCkNCnsNCgltX2JFbmFibGVOb3RpZnkgPSBGQUxTRTsJDQoJQ1BXTF9FZGl0OjpPblNldEZvY3VzKCk7DQoJbV9iRW5hYmxlTm90aWZ5ID0gVFJVRTsJDQoNCgl0aGlzLT5FbmFibGVTcGVsbENoZWNrKFRSVUUpOw0KfQ0KDQp2b2lkIENQV0xfTm90ZV9FZGl0OjpPbktpbGxGb2N1cygpDQp7DQoJdGhpcy0+RW5hYmxlU3BlbGxDaGVjayhGQUxTRSk7DQoNCglpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSB0aGlzLT5HZXRQYXJlbnRXaW5kb3coKSkNCgl7DQoJCWlmIChDUFdMX1duZCogcEdyYW5kID0gcFBhcmVudC0+R2V0UGFyZW50V2luZG93KCkpDQoJCXsNCgkJCUFTU0VSVChwR3JhbmQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7DQoNCgkJCUNQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwR3JhbmQ7DQoNCgkJCXBOb3RlSXRlbS0+T25Db250ZW50c1ZhbGlkYXRlKCk7DQoJCX0NCgl9DQoNCglDUFdMX0VkaXQ6Ok9uS2lsbEZvY3VzKCk7DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlX0VkaXQ6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0sIEZYX0lOVFBUUiBsUGFyYW0pDQp7DQoJaWYgKG1fYkVuYWJsZU5vdGlmeSkNCgl7DQoJCWlmICh3UGFyYW0gPT0gU0JUX1ZTQ1JPTEwpDQoJCXsNCgkJCXN3aXRjaCAobXNnKQ0KCQkJew0KCQkJY2FzZSBQTk1fU0VUU0NST0xMSU5GTzoJDQoJCQkJaWYgKFBXTF9TQ1JPTExfSU5GTyogcEluZm8gPSAoUFdMX1NDUk9MTF9JTkZPKilsUGFyYW0pDQoJCQkJewkNCgkJCQkJaWYgKCFJc0Zsb2F0RXF1YWwocEluZm8tPmZDb250ZW50TWF4LCBtX2ZPbGRNYXgpIHx8IA0KCQkJCQkJIUlzRmxvYXRFcXVhbChwSW5mby0+ZkNvbnRlbnRNaW4sIG1fZk9sZE1pbikpDQoJCQkJCXsNCgkJCQkJCW1fYlNpemVDaGFuZ2VkID0gVFJVRTsJCQkJDQoJCQkJCQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpDQoJCQkJCQl7DQoJCQkJCQkJcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7DQoJCQkJCQl9DQoNCgkJCQkJCW1fZk9sZE1heCA9IHBJbmZvLT5mQ29udGVudE1heDsNCgkJCQkJCW1fZk9sZE1pbiA9IHBJbmZvLT5mQ29udGVudE1pbjsNCgkJCQkJCXJldHVybjsNCgkJCQkJfQ0KCQkJCX0NCgkJCX0NCgkJfQkJDQoJfQ0KDQoJQ1BXTF9FZGl0OjpPbk5vdGlmeShwV25kLCBtc2csIHdQYXJhbSwgbFBhcmFtKTsNCg0KCWlmIChtX2JFbmFibGVOb3RpZnkpDQoJew0KCQlzd2l0Y2ggKG1zZykNCgkJew0KCQljYXNlIFBOTV9TRVRDQVJFVElORk86DQoJCQlpZiAoUFdMX0NBUkVUX0lORk8gKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKQ0KCQkJew0KCQkJCVBXTF9DQVJFVF9JTkZPIG5ld0luZm8gPSAqcEluZm87DQoJCQkJbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7DQoJCQkJbmV3SW5mby5wdEhlYWQgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEhlYWQpOw0KCQkJCW5ld0luZm8ucHRGb290ID0gdGhpcy0+Q2hpbGRUb1BhcmVudChwSW5mby0+cHRGb290KTsNCg0KCQkJCWlmIChDUFdMX1duZCAqIHBQYXJlbnQgPSB0aGlzLT5HZXRQYXJlbnRXaW5kb3coKSkNCgkJCQl7DQoJCQkJCXBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRDQVJFVElORk8sIChGWF9JTlRQVFIpJm5ld0luZm8sIDApOw0KCQkJCX0NCgkJCX0NCgkJCWJyZWFrOw0KCQl9DQoJfQ0KfQ0KDQpGWF9GTE9BVCBDUFdMX05vdGVfRWRpdDo6R2V0SXRlbUhlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCkNCnsNCglpZiAoZkxpbWl0V2lkdGggPiAwKQ0KCXsNCgkJaWYgKCFtX2JTaXplQ2hhbmdlZCkNCgkJCXJldHVybiBtX2ZPbGRJdGVtSGVpZ2h0Ow0KDQoJCW1fYlNpemVDaGFuZ2VkID0gRkFMU0U7CQ0KDQoJCXRoaXMtPkVuYWJsZU5vdGlmeShGQUxTRSk7DQoJCXRoaXMtPkVuYWJsZVJlZnJlc2goRkFMU0UpOw0KCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOw0KDQoJCS8vQ1BERl9SZWN0IHJjT2xkID0gdGhpcy0+R2V0V2luZG93UmVjdCgpOw0KDQoJCXRoaXMtPk1vdmUoQ1BERl9SZWN0KDAsMCxmTGltaXRXaWR0aCwwKSwgVFJVRSwgRkFMU0UpOw0KCQlGWF9GTE9BVCBmUmV0ID0gdGhpcy0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsNCg0KCQkvL3RoaXMtPk1vdmUocmNPbGQsIFRSVUUsIEZBTFNFKTsNCg0KCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7DQoJCXRoaXMtPkVuYWJsZU5vdGlmeShUUlVFKTsNCgkJdGhpcy0+RW5hYmxlUmVmcmVzaChUUlVFKTsNCg0KCQlyZXR1cm4gZlJldDsNCgl9DQoNCglyZXR1cm4gMDsNCn0NCg0KRlhfRkxPQVQgQ1BXTF9Ob3RlX0VkaXQ6OkdldEl0ZW1MZWZ0TWFyZ2luKCkNCnsNCglyZXR1cm4gUE9QVVBfSVRFTV9URVhUX0lOREVOVDsNCn0NCg0KRlhfRkxPQVQgQ1BXTF9Ob3RlX0VkaXQ6OkdldEl0ZW1SaWdodE1hcmdpbigpDQp7DQoJcmV0dXJuIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7DQp9DQoNCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9MQkJveCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCkNQV0xfTm90ZV9MQkJveDo6Q1BXTF9Ob3RlX0xCQm94KCkNCnsNCn0NCg0KQ1BXTF9Ob3RlX0xCQm94Ojp+Q1BXTF9Ob3RlX0xCQm94KCkNCnsNCn0NCg0Kdm9pZCBDUFdMX05vdGVfTEJCb3g6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQ0Kew0KCUNQREZfUmVjdCByY0NsaWVudCA9IHRoaXMtPkdldENsaWVudFJlY3QoKTsNCg0KCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7DQoJZ3NkLm1fTGluZVdpZHRoID0gMS4wZjsNCg0KCUNGWF9QYXRoRGF0YSBwYXRoQ3Jvc3M7DQoNCglwYXRoQ3Jvc3MuU2V0UG9pbnRDb3VudCg0KTsNCglwYXRoQ3Jvc3MuU2V0UG9pbnQoMCwgcmNDbGllbnQubGVmdCwgcmNDbGllbnQudG9wLCBGWFBUX01PVkVUTyk7DQoJcGF0aENyb3NzLlNldFBvaW50KDEsIHJjQ2xpZW50LnJpZ2h0LCByY0NsaWVudC5ib3R0b20sIEZYUFRfTElORVRPKTsNCglwYXRoQ3Jvc3MuU2V0UG9pbnQoMiwgcmNDbGllbnQubGVmdCwgcmNDbGllbnQuYm90dG9tICsgcmNDbGllbnQuSGVpZ2h0KCkgKiAwLjVmLCBGWFBUX01PVkVUTyk7DQoJcGF0aENyb3NzLlNldFBvaW50KDMsIHJjQ2xpZW50LmxlZnQgKyByY0NsaWVudC5XaWR0aCgpICogMC41ZiwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7DQoJDQoJcERldmljZS0+RHJhd1BhdGgoJnBhdGhDcm9zcywgcFVzZXIyRGV2aWNlLCAmZ3NkLCANCgkJMCwgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpLCBGWEZJTExfQUxURVJOQVRFKTsNCn0NCg0KLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX1JCQm94IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KQ1BXTF9Ob3RlX1JCQm94OjpDUFdMX05vdGVfUkJCb3goKQ0Kew0KfQ0KDQpDUFdMX05vdGVfUkJCb3g6On5DUFdMX05vdGVfUkJCb3goKQ0Kew0KfQ0KDQp2b2lkIENQV0xfTm90ZV9SQkJveDo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpDQp7DQoJQ1BERl9SZWN0IHJjQ2xpZW50ID0gdGhpcy0+R2V0Q2xpZW50UmVjdCgpOw0KDQoJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsNCglnc2QubV9MaW5lV2lkdGggPSAxLjBmOw0KDQoJQ0ZYX1BhdGhEYXRhIHBhdGhDcm9zczsNCg0KCXBhdGhDcm9zcy5TZXRQb2ludENvdW50KDQpOw0KCXBhdGhDcm9zcy5TZXRQb2ludCgwLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQudG9wLCBGWFBUX01PVkVUTyk7DQoJcGF0aENyb3NzLlNldFBvaW50KDEsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOw0KCXBhdGhDcm9zcy5TZXRQb2ludCgyLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQuYm90dG9tICsgcmNDbGllbnQuSGVpZ2h0KCkgKiAwLjVmLCBGWFBUX01PVkVUTyk7DQoJcGF0aENyb3NzLlNldFBvaW50KDMsIHJjQ2xpZW50LmxlZnQgKyByY0NsaWVudC5XaWR0aCgpICogMC41ZiwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7DQoJDQoJcERldmljZS0+RHJhd1BhdGgoJnBhdGhDcm9zcywgcFVzZXIyRGV2aWNlLCAmZ3NkLCANCgkJMCwgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpLCBGWEZJTExfQUxURVJOQVRFKTsNCn0NCg0KLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9JY29uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCg0KQ1BXTF9Ob3RlX0ljb246OkNQV0xfTm90ZV9JY29uKCkgOiBtX25UeXBlKDApDQp7DQp9DQoNCkNQV0xfTm90ZV9JY29uOjp+Q1BXTF9Ob3RlX0ljb24oKQ0Kew0KfQ0KDQp2b2lkIENQV0xfTm90ZV9JY29uOjpTZXRJY29uVHlwZShGWF9JTlQzMiBuVHlwZSkNCnsNCgltX25UeXBlID0gblR5cGU7DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlX0ljb246OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQ0Kew0KCUNQV0xfVXRpbHM6OkRyYXdJY29uQXBwU3RyZWFtKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgbV9uVHlwZSwgR2V0Q2xpZW50UmVjdCgpLCANCgkJdGhpcy0+R2V0QmFja2dyb3VuZENvbG9yKCksIFBXTF9ERUZBVUxUX0JMQUNLQ09MT1IsIHRoaXMtPkdldFRyYW5zcGFyZW5jeSgpKTsNCn0NCg0KLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9DbG9zZUJveCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQoNCkNQV0xfTm90ZV9DbG9zZUJveDo6Q1BXTF9Ob3RlX0Nsb3NlQm94KCkgOiBtX2JNb3VzZURvd24oRkFMU0UpDQp7DQp9DQoNCkNQV0xfTm90ZV9DbG9zZUJveDo6fkNQV0xfTm90ZV9DbG9zZUJveCgpDQp7DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlX0Nsb3NlQm94OjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkNCnsNCglDUFdMX0J1dHRvbjo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSk7DQoNCglDUERGX1JlY3QgcmNDbGllbnQgPSB0aGlzLT5HZXRDbGllbnRSZWN0KCk7DQoJcmNDbGllbnQgPSBDUFdMX1V0aWxzOjpEZWZsYXRlUmVjdChyY0NsaWVudCwgMi4wZik7DQoNCglDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOw0KCWdzZC5tX0xpbmVXaWR0aCA9IDEuMGY7DQoNCglDRlhfUGF0aERhdGEgcGF0aENyb3NzOw0KDQoJaWYgKG1fYk1vdXNlRG93bikNCgl7DQoJCXJjQ2xpZW50LmxlZnQgKz0gMC41ZjsNCgkJcmNDbGllbnQucmlnaHQgKz0gMC41ZjsNCgkJcmNDbGllbnQudG9wIC09IDAuNWY7DQoJCXJjQ2xpZW50LmJvdHRvbSAtPSAwLjVmOw0KCX0NCg0KCXBhdGhDcm9zcy5TZXRQb2ludENvdW50KDQpOw0KCXBhdGhDcm9zcy5TZXRQb2ludCgwLCByY0NsaWVudC5sZWZ0LCByY0NsaWVudC5ib3R0b20sIEZYUFRfTU9WRVRPKTsNCglwYXRoQ3Jvc3MuU2V0UG9pbnQoMSwgcmNDbGllbnQucmlnaHQsIHJjQ2xpZW50LnRvcCwgRlhQVF9MSU5FVE8pOw0KCXBhdGhDcm9zcy5TZXRQb2ludCgyLCByY0NsaWVudC5sZWZ0LCByY0NsaWVudC50b3AsIEZYUFRfTU9WRVRPKTsNCglwYXRoQ3Jvc3MuU2V0UG9pbnQoMywgcmNDbGllbnQucmlnaHQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOw0KCQ0KCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoQ3Jvc3MsIHBVc2VyMkRldmljZSwgJmdzZCwgDQoJCTAsIENQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpLHRoaXMtPkdldFRyYW5zcGFyZW5jeSgpKSwgRlhGSUxMX0FMVEVSTkFURSk7DQp9DQoNCkZYX0JPT0wgQ1BXTF9Ob3RlX0Nsb3NlQm94OjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpDQp7DQoJU2V0Qm9yZGVyU3R5bGUoUEJTX0lOU0VUKTsNCglJbnZhbGlkYXRlUmVjdChOVUxMKTsNCg0KCW1fYk1vdXNlRG93biA9IFRSVUU7DQoNCglyZXR1cm4gQ1BXTF9CdXR0b246Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOw0KfQ0KDQpGWF9CT09MCUNQV0xfTm90ZV9DbG9zZUJveDo6T25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCnsNCgltX2JNb3VzZURvd24gPSBGQUxTRTsNCg0KCVNldEJvcmRlclN0eWxlKFBCU19CRVZFTEVEKTsNCglJbnZhbGlkYXRlUmVjdChOVUxMKTsNCg0KCXJldHVybiBDUFdMX0J1dHRvbjo6T25MQnV0dG9uVXAocG9pbnQsbkZsYWcpOw0KfQ0KDQovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX0NvbnRlbnRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCg0KQ1BXTF9Ob3RlX0NvbnRlbnRzOjpDUFdMX05vdGVfQ29udGVudHMoKSA6IG1fcEVkaXQoTlVMTCkNCnsNCn0NCg0KQ1BXTF9Ob3RlX0NvbnRlbnRzOjp+Q1BXTF9Ob3RlX0NvbnRlbnRzKCkNCnsNCn0NCg0KQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRDbGFzc05hbWUoKSBjb25zdA0Kew0KCXJldHVybiAiQ1BXTF9Ob3RlX0NvbnRlbnRzIjsNCn0NCg0Kdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQ0Kew0KCW1fcEVkaXQgPSBuZXcgQ1BXTF9Ob3RlX0VkaXQ7DQoJUFdMX0NSRUFURVBBUkFNIGVjcCA9IGNwOw0KCWVjcC5wUGFyZW50V25kID0gdGhpczsNCgllY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUEVTX01VTFRJTElORSB8IFBFU19BVVRPUkVUVVJOIHwgUEVTX1RFWFRPVkVSRkxPVyB8IFBFU19VTkRPIHwgUEVTX1NQRUxMQ0hFQ0s7DQoNCgltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOw0KCW1fcEVkaXQtPkNyZWF0ZShlY3ApOw0KCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsNCn0NCg0Kdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OlNldFRleHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUZXh0KQ0Kew0KCWlmIChtX3BFZGl0KQ0KCXsNCgkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsNCgkJbV9wRWRpdC0+U2V0VGV4dChzVGV4dCk7DQoJCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsNCgkJT25Ob3RpZnkobV9wRWRpdCwgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7CQkNCgl9DQp9DQoNCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZV9Db250ZW50czo6R2V0VGV4dCgpIGNvbnN0DQp7DQoJaWYgKG1fcEVkaXQpDQoJCXJldHVybiBtX3BFZGl0LT5HZXRUZXh0KCk7DQoNCglyZXR1cm4gTCIiOw0KfQ0KDQpDUFdMX05vdGVJdGVtKiBDUFdMX05vdGVfQ29udGVudHM6OkNyZWF0ZVN1Ykl0ZW0oKQ0Kew0KCUNQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IG5ldyBDUFdMX05vdGVJdGVtOw0KCVBXTF9DUkVBVEVQQVJBTSBpY3AgPSB0aGlzLT5HZXRDcmVhdGlvblBhcmFtKCk7DQoJaWNwLnBQYXJlbnRXbmQgPSB0aGlzOw0KCWljcC5kd0ZsYWdzID0gIFBXU19DSElMRCB8IFBXU19WSVNJQkxFIHwgUFdTX0JBQ0tHUk9VTkQ7DQoJcE5vdGVJdGVtLT5DcmVhdGUoaWNwKTsNCg0KCXBOb3RlSXRlbS0+T25DcmVhdGVOb3RlSXRlbSgpOw0KCQ0KCXBOb3RlSXRlbS0+UmVzZXRTdWJqZWN0TmFtZShtX2FDaGlsZHJlbi5HZXRTaXplKCkgLSAxKTsNCg0KCUZYX1NZU1RFTVRJTUUgc3Q7DQoJaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU0ggPSB0aGlzLT5HZXRTeXN0ZW1IYW5kbGVyKCkpDQoJCXN0ID0gcFNILT5HZXRMb2NhbFRpbWUoKTsNCglwTm90ZUl0ZW0tPlNldERhdGVUaW1lKHN0KTsNCg0KCXBOb3RlSXRlbS0+U2V0Q29udGVudHMoTCIiKTsNCg0KCXRoaXMtPk9uTm90aWZ5KHBOb3RlSXRlbSwgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7CQ0KDQoJcmV0dXJuIHBOb3RlSXRlbTsNCn0NCg0KRlhfSU5UMzIgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpDb3VudFN1Ykl0ZW1zKCkgY29uc3QNCnsNCglyZXR1cm4gbV9hQ2hpbGRyZW4uR2V0U2l6ZSgpIC0gMTsNCn0NCg0KSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRTdWJJdGVtcyhGWF9JTlQzMiBpbmRleCkgY29uc3QNCnsNCglGWF9JTlQzMiBuSW5kZXggPSBpbmRleCArIDE7DQoNCglpZiAobkluZGV4ID4gMCAmJiBuSW5kZXggPCBtX2FDaGlsZHJlbi5HZXRTaXplKCkpDQoJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQobkluZGV4KSkNCgkJew0KCQkJQVNTRVJUKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsNCgkJCUNQV0xfTm90ZUl0ZW0qIHBJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsNCgkJCXJldHVybiBwSXRlbTsNCgkJfQ0KCXJldHVybiBOVUxMOw0KfQ0KDQp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6RGVsZXRlU3ViSXRlbShJUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0pDQp7DQoJRlhfSU5UMzIgbkluZGV4ID0gdGhpcy0+R2V0SXRlbUluZGV4KChDUFdMX05vdGVJdGVtKilwTm90ZUl0ZW0pOw0KDQoJaWYgKG5JbmRleCA+IDApDQoJew0KCQlpZiAoQ1BXTF9Ob3RlSXRlbSogcFBXTE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBOb3RlSXRlbSkNCgkJew0KCQkJcFBXTE5vdGVJdGVtLT5LaWxsRm9jdXMoKTsNCgkJCXBQV0xOb3RlSXRlbS0+RGVzdHJveSgpOw0KCQkJZGVsZXRlIHBQV0xOb3RlSXRlbTsNCgkJfQ0KDQoJCWZvciAoRlhfSU5UMzIgaT1uSW5kZXgsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQoJCXsNCgkJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpDQoJCQl7DQoJCQkJQVNTRVJUKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsNCgkJCQlDUFdMX05vdGVJdGVtKiBwSXRlbSA9IChDUFdMX05vdGVJdGVtKilwQ2hpbGQ7DQoJCQkJcEl0ZW0tPlJlc2V0U3ViamVjdE5hbWUoaSk7DQoJCQl9DQoJCX0NCg0KCQl0aGlzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsNCgl9DQp9DQoNCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZV9Db250ZW50czo6R2V0SGl0Tm90ZUl0ZW0oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQp7DQoJQ1BERl9Qb2ludCBwdCA9IHRoaXMtPlBhcmVudFRvQ2hpbGQocG9pbnQpOw0KDQoJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQoJew0KCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQ0KCQl7DQoJCQlpZiAocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpDQoJCQl7DQoJCQkJQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsNCgkJCQlpZiAoSVBXTF9Ob3RlSXRlbSogcFJldCA9IHBOb3RlSXRlbS0+R2V0SGl0Tm90ZUl0ZW0ocHQpKQ0KCQkJCQlyZXR1cm4gcFJldDsNCgkJCX0NCgkJfQ0KCX0NCglyZXR1cm4gTlVMTDsNCn0NCg0Kdm9pZCBDUFdMX05vdGVfQ29udGVudHM6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0sIEZYX0lOVFBUUiBsUGFyYW0pDQp7DQoJc3dpdGNoIChtc2cpDQoJew0KCWNhc2UgUE5NX05PVEVFRElUQ0hBTkdFRDoNCgkJew0KCQkJRlhfSU5UMzIgbkluZGV4ID0gdGhpcy0+R2V0SXRlbUluZGV4KHBXbmQpOw0KCQkJaWYgKG5JbmRleCA8IDApIG5JbmRleCA9IDA7DQoNCgkJCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShGQUxTRSk7CQ0KCQkJdGhpcy0+UmVzZXRDb250ZW50KG5JbmRleCk7DQoJCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7DQoNCgkJCWZvciAoRlhfSU5UMzIgaT1uSW5kZXgrMSwgc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQoJCQl7DQoJCQkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkNCgkJCQkJcENoaWxkLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsNCgkJCX0NCg0KCQkJaWYgKENQV0xfV25kICogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQ0KCQkJew0KCQkJCXBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOw0KCQkJfQ0KCQl9DQoJCXJldHVybjsNCgljYXNlIFBOTV9TQ1JPTExXSU5ET1c6DQoJCXRoaXMtPlNldFNjcm9sbFBvcyhDUERGX1BvaW50KDAuMGYsICooRlhfRkxPQVQqKWxQYXJhbSkpOw0KCQl0aGlzLT5SZXNldEZhY2UoKTsNCgkJSW52YWxpZGF0ZVJlY3QoTlVMTCk7DQoJCXJldHVybjsJCQ0KCWNhc2UgUE5NX1NFVENBUkVUSU5GTzoNCgkJaWYgKFBXTF9DQVJFVF9JTkZPICogcEluZm8gPSAoUFdMX0NBUkVUX0lORk8qKXdQYXJhbSkNCgkJew0KCQkJUFdMX0NBUkVUX0lORk8gbmV3SW5mbyA9ICpwSW5mbzsNCgkJCW5ld0luZm8uYlZpc2libGUgPSBUUlVFOw0KCQkJbmV3SW5mby5wdEhlYWQgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEhlYWQpOw0KCQkJbmV3SW5mby5wdEZvb3QgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEZvb3QpOw0KDQoJCQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpDQoJCQl7DQoJCQkJcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX1NFVENBUkVUSU5GTywgKEZYX0lOVFBUUikmbmV3SW5mbywgMCk7DQoJCQl9DQoJCX0NCgkJcmV0dXJuOw0KCWNhc2UgUE5NX05PVEVSRVNFVDoNCgkJew0KCQkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsJDQoJCQl0aGlzLT5SZXNldENvbnRlbnQoMCk7DQoJCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7DQoNCgkJCWZvciAoRlhfSU5UMzIgaT0xLCBzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykNCgkJCXsNCgkJCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQ0KCQkJCQlwQ2hpbGQtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOw0KCQkJfQkNCg0KCQkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsJDQoJCQl0aGlzLT5SZXNldENvbnRlbnQoMCk7DQoJCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7DQoJCX0NCgkJcmV0dXJuOw0KCX0NCg0KCUNQV0xfV25kOjpPbk5vdGlmeShwV25kLCBtc2csIHdQYXJhbSwgbFBhcmFtKTsNCn0NCg0KRlhfQk9PTAlDUFdMX05vdGVfQ29udGVudHM6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCnsNCglpZiAoQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpKSByZXR1cm4gVFJVRTsNCg0KCWlmICghbV9wRWRpdC0+SXNGb2N1c2VkKCkpDQoJew0KCQltX3BFZGl0LT5TZXRGb2N1cygpOw0KCX0NCg0KCXJldHVybiBUUlVFOw0KfQ0KDQp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6U2V0RWRpdEZvY3VzKEZYX0JPT0wgYkxhc3QpDQp7DQoJaWYgKCFtX3BFZGl0LT5Jc0ZvY3VzZWQoKSkNCgl7DQoJCW1fcEVkaXQtPlNldEZvY3VzKCk7DQoJCW1fcEVkaXQtPlNldENhcmV0KGJMYXN0ID8gbV9wRWRpdC0+R2V0VG90YWxXb3JkcygpIDogMCk7DQoJfQ0KfQ0KDQpDUFdMX0VkaXQqIENQV0xfTm90ZV9Db250ZW50czo6R2V0RWRpdCgpIGNvbnN0DQp7DQoJcmV0dXJuIG1fcEVkaXQ7DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpFbmFibGVNb2RpZnkoRlhfQk9PTCBiRW5hYmxlZCkNCnsNCglpZiAoIWJFbmFibGVkKQ0KCQltX3BFZGl0LT5BZGRGbGFnKFBXU19SRUFET05MWSk7DQoJZWxzZQ0KCQltX3BFZGl0LT5SZW1vdmVGbGFnKFBXU19SRUFET05MWSk7DQoNCglmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykNCgl7DQoJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpDQoJCXsNCgkJCWlmIChwQ2hpbGQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIikNCgkJCXsNCgkJCQlDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcENoaWxkOw0KCQkJCXBOb3RlSXRlbS0+RW5hYmxlTW9kaWZ5KGJFbmFibGVkKTsNCgkJCX0NCgkJfQ0KCX0NCn0NCg0Kdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OkVuYWJsZVJlYWQoRlhfQk9PTCBiRW5hYmxlZCkNCnsNCglpZiAoIWJFbmFibGVkKQ0KCQltX3BFZGl0LT5BZGRGbGFnKFBFU19OT1JFQUQpOw0KCWVsc2UNCgkJbV9wRWRpdC0+UmVtb3ZlRmxhZyhQRVNfTk9SRUFEKTsNCg0KCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KCXsNCgkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkNCgkJew0KCQkJaWYgKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKQ0KCQkJew0KCQkJCUNQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwQ2hpbGQ7DQoJCQkJcE5vdGVJdGVtLT5FbmFibGVSZWFkKGJFbmFibGVkKTsNCgkJCX0NCgkJfQ0KCX0NCn0NCg0KLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVJdGVtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCg0KQ1BXTF9Ob3RlSXRlbTo6Q1BXTF9Ob3RlSXRlbSgpIDoNCgltX3BQcml2YXRlRGF0YShOVUxMKSwNCgltX3BTdWJqZWN0KE5VTEwpLA0KCW1fcERhdGVUaW1lKE5VTEwpLA0KCW1fcENvbnRlbnRzKE5VTEwpLA0KCW1fc0F1dGhvcihMIiIpLA0KCW1fZk9sZEl0ZW1IZWlnaHQoMC4wZiksDQoJbV9iU2l6ZUNoYW5nZWQoRkFMU0UpLA0KCW1fYkFsbG93TW9kaWZ5KFRSVUUpDQp7DQp9DQoNCkNQV0xfTm90ZUl0ZW06On5DUFdMX05vdGVJdGVtKCkNCnsNCn0NCg0KQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9Ob3RlSXRlbTo6R2V0Q2xhc3NOYW1lKCkgY29uc3QNCnsNCglyZXR1cm4gIkNQV0xfTm90ZUl0ZW0iOw0KfQ0KDQp2b2lkIENQV0xfTm90ZUl0ZW06OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQ0Kew0KCUNQV0xfQ29sb3Igc1RleHRDb2xvcjsNCg0KCWlmIChDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZSh0aGlzLT5HZXRCYWNrZ3JvdW5kQ29sb3IoKSkpDQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9XSElURUNPTE9SOw0KCWVsc2UNCgkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7DQoNCgltX3BTdWJqZWN0ID0gbmV3IENQV0xfTGFiZWw7DQoJUFdMX0NSRUFURVBBUkFNIHNjcCA9IGNwOw0KCXNjcC5wUGFyZW50V25kID0gdGhpczsNCglzY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUEVTX0xFRlQgfCBQRVNfVE9QOw0KCXNjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsNCgltX3BTdWJqZWN0LT5DcmVhdGUoc2NwKTsNCg0KCW1fcERhdGVUaW1lID0gbmV3IENQV0xfTGFiZWw7DQoJUFdMX0NSRUFURVBBUkFNIGRjcCA9IGNwOw0KCWRjcC5wUGFyZW50V25kID0gdGhpczsNCglkY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUEVTX1JJR0hUIHwgUEVTX1RPUDsNCglkY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7DQoJbV9wRGF0ZVRpbWUtPkNyZWF0ZShkY3ApOw0KDQoJbV9wQ29udGVudHMgPSBuZXcgQ1BXTF9Ob3RlX0NvbnRlbnRzOw0KCVBXTF9DUkVBVEVQQVJBTSBjY3AgPSBjcDsNCgljY3AucFBhcmVudFduZCA9IHRoaXM7DQoJLy9jY3Auc0JhY2tncm91bmRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7DQoJY2NwLnNCYWNrZ3JvdW5kQ29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIDI0MC8yNTUuMGYsIDI0MC8yNTUuMGYsIDI0MC8yNTUuMGYpOw0KCWNjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQV1NfQkFDS0dST1VORDsNCgltX3BDb250ZW50cy0+Q3JlYXRlKGNjcCk7DQoJbV9wQ29udGVudHMtPlNldEl0ZW1TcGFjZShQT1BVUF9JVEVNX1NQQUNFKTsNCgltX3BDb250ZW50cy0+U2V0VG9wU3BhY2UoUE9QVVBfSVRFTV9TUEFDRSk7DQoJbV9wQ29udGVudHMtPlNldEJvdHRvbVNwYWNlKFBPUFVQX0lURU1fU1BBQ0UpOw0KfQ0KDQp2b2lkIENQV0xfTm90ZUl0ZW06OlJlUG9zQ2hpbGRXbmQoKQ0Kew0KCWlmICh0aGlzLT5Jc1ZhbGlkKCkpDQoJew0KCQlBU1NFUlQobV9wU3ViamVjdCAhPSBOVUxMKTsNCgkJQVNTRVJUKG1fcERhdGVUaW1lICE9IE5VTEwpOw0KCQlBU1NFUlQobV9wQ29udGVudHMgIT0gTlVMTCk7DQoNCgkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOw0KDQoJCUNQREZfUmVjdCByY1N1YmplY3QgPSByY0NsaWVudDsNCgkJcmNTdWJqZWN0LmxlZnQgKz0gUE9QVVBfSVRFTV9URVhUX0lOREVOVDsNCgkJcmNTdWJqZWN0LnRvcCA9IHJjQ2xpZW50LnRvcDsNCgkJcmNTdWJqZWN0LnJpZ2h0ID0gUFdMX01JTihyY1N1YmplY3QubGVmdCArIG1fcFN1YmplY3QtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSArIDEuMGYsIHJjQ2xpZW50LnJpZ2h0KTsNCgkJcmNTdWJqZWN0LmJvdHRvbSA9IHJjU3ViamVjdC50b3AgLSBtX3BTdWJqZWN0LT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOw0KCQlyY1N1YmplY3QuTm9ybWFsaXplKCk7DQoJCW1fcFN1YmplY3QtPk1vdmUocmNTdWJqZWN0LCBUUlVFLCBGQUxTRSk7DQoJCW1fcFN1YmplY3QtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY1N1YmplY3QpKTsNCg0KCQlDUERGX1JlY3QgcmNEYXRlID0gcmNDbGllbnQ7DQoJCXJjRGF0ZS5yaWdodCAtPSBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOw0KCQlyY0RhdGUubGVmdCA9IFBXTF9NQVgocmNEYXRlLnJpZ2h0IC0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSAtIDEuMGYsIHJjU3ViamVjdC5yaWdodCk7DQoJCXJjRGF0ZS5ib3R0b20gPSByY0RhdGUudG9wIC0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7DQoJCXJjRGF0ZS5Ob3JtYWxpemUoKTsNCgkJbV9wRGF0ZVRpbWUtPk1vdmUocmNEYXRlLCBUUlVFLCBGQUxTRSk7DQoJCW1fcERhdGVUaW1lLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNEYXRlKSk7DQoNCgkJQ1BERl9SZWN0IHJjQ29udGVudHMgPSByY0NsaWVudDsNCgkJcmNDb250ZW50cy5sZWZ0ICs9IDEuMGY7DQoJCXJjQ29udGVudHMucmlnaHQgLT0gMS4wZjsNCgkJcmNDb250ZW50cy50b3AgPSByY0RhdGUuYm90dG9tIC0gUE9QVVBfSVRFTV9IRUFEX0JPVFRPTTsNCgkJcmNDb250ZW50cy5ib3R0b20gKz0gUE9QVVBfSVRFTV9CT1RUT01XSURUSDsNCgkJcmNDb250ZW50cy5Ob3JtYWxpemUoKTsNCgkJbV9wQ29udGVudHMtPk1vdmUocmNDb250ZW50cywgVFJVRSwgRkFMU0UpOw0KCQltX3BDb250ZW50cy0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjQ29udGVudHMpKTsNCgl9DQoNCglTZXRDbGlwUmVjdChDUFdMX1V0aWxzOjpJbmZsYXRlUmVjdChHZXRXaW5kb3dSZWN0KCksMS4wZikpOw0KfQ0KDQp2b2lkIENQV0xfTm90ZUl0ZW06OlNldFByaXZhdGVEYXRhKHZvaWQqIHBEYXRhKQ0Kew0KCW1fcFByaXZhdGVEYXRhID0gcERhdGE7DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0QmtDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcikNCnsNCglDUFdMX0NvbG9yIHNCSyA9IGNvbG9yOw0KCXRoaXMtPlNldEJhY2tncm91bmRDb2xvcihzQkspOw0KDQoJQ1BXTF9Db2xvciBzVGV4dENvbG9yOw0KDQoJaWYgKENQV0xfVXRpbHM6OklzQmxhY2tPcldoaXRlKHNCSykpDQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9XSElURUNPTE9SOw0KCWVsc2UNCgkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7DQoNCgl0aGlzLT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7DQoJaWYgKG1fcFN1YmplY3QpDQoJCW1fcFN1YmplY3QtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsNCglpZiAobV9wRGF0ZVRpbWUpDQoJCW1fcERhdGVUaW1lLT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7DQoNCgl0aGlzLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsNCg0KCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpDQoJew0KCQlwTm90aWZ5LT5PblNldEJrQ29sb3IodGhpcyk7DQoJfQ0KfQ0KDQp2b2lkIENQV0xfTm90ZUl0ZW06OlNldFN1YmplY3ROYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkNCnsNCglpZiAobV9wU3ViamVjdCkNCgl7DQoJCW1fcFN1YmplY3QtPlNldFRleHQoc05hbWUpOwkNCgl9DQoNCglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQ0KCXsNCgkJcE5vdGlmeS0+T25TZXRTdWJqZWN0TmFtZSh0aGlzKTsNCgl9DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0QXV0aG9yTmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpDQp7DQoJbV9zQXV0aG9yID0gc05hbWU7DQoJUmVzZXRTdWJqZWN0TmFtZSgtMSk7CQ0KDQoJaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkNCgl7DQoJCXBOb3RpZnktPk9uU2V0QXV0aG9yTmFtZSh0aGlzKTsNCgl9DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6UmVzZXRTdWJqZWN0TmFtZShGWF9JTlQzMiBuSXRlbUluZGV4KQ0Kew0KCWlmIChuSXRlbUluZGV4IDwgMCkNCgl7DQoJCWlmIChDUFdMX1duZCogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQ0KCQl7DQoJCQlBU1NFUlQocFBhcmVudC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZV9Db250ZW50cyIpOw0KDQoJCQlDUFdMX05vdGVfQ29udGVudHMqIHBDb250ZW50cyA9IChDUFdMX05vdGVfQ29udGVudHMqKXBQYXJlbnQ7DQoJCQluSXRlbUluZGV4ID0gcENvbnRlbnRzLT5HZXRJdGVtSW5kZXgodGhpcyk7DQoJCX0NCgl9DQoNCgljb25zdCBDUFdMX05vdGUqIHBOb3RlID0gR2V0Tm90ZSgpOw0KCUFTU0VSVChwTm90ZSAhPSBOVUxMKTsNCg0KCUNGWF9XaWRlU3RyaW5nIHNTdWJqZWN0Ow0KCXNTdWJqZWN0LkZvcm1hdChwTm90ZS0+R2V0UmVwbHlTdHJpbmcoKSwgbkl0ZW1JbmRleCk7DQoNCglpZiAoIW1fc0F1dGhvci5Jc0VtcHR5KCkpDQoJew0KCQkNCgkJc1N1YmplY3QgKz0gTCIgLSAiOw0KCQlzU3ViamVjdCArPSBtX3NBdXRob3I7DQoJfQ0KCXRoaXMtPlNldFN1YmplY3ROYW1lKHNTdWJqZWN0KTsNCgl0aGlzLT5SZVBvc0NoaWxkV25kKCk7DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0RGF0ZVRpbWUoRlhfU1lTVEVNVElNRSB0aW1lKQ0Kew0KCW1fZHROb3RlID0gdGltZTsNCgkNCglDRlhfV2lkZVN0cmluZyBzd1RpbWU7DQoJc3dUaW1lLkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwNGQtJTAyZC0lMDJkICUwMmQ6JTAyZDolMDJkIiwgdGltZS53WWVhciwgdGltZS53TW9udGgsIHRpbWUud0RheSwgdGltZS53SG91ciwgdGltZS53TWludXRlLCB0aW1lLndTZWNvbmQpOw0KCWlmIChtX3BEYXRlVGltZSkNCgl7DQoJCW1fcERhdGVUaW1lLT5TZXRUZXh0KHN3VGltZSk7DQoJfQ0KDQoJdGhpcy0+UmVQb3NDaGlsZFduZCgpOw0KDQoJaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkNCgl7DQoJCXBOb3RpZnktPk9uU2V0RGF0ZVRpbWUodGhpcyk7DQoJfQ0KfQ0KDQp2b2lkIENQV0xfTm90ZUl0ZW06OlNldENvbnRlbnRzKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzQ29udGVudHMpDQp7DQoJaWYgKG1fcENvbnRlbnRzKQ0KCXsNCgkJbV9wQ29udGVudHMtPlNldFRleHQoc0NvbnRlbnRzKTsNCgl9DQoNCglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQ0KCXsNCgkJcE5vdGlmeS0+T25TZXRDb250ZW50cyh0aGlzKTsNCgl9DQp9DQoNCkNQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldFBhcmVudE5vdGVJdGVtKCkgY29uc3QNCnsNCglpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSB0aGlzLT5HZXRQYXJlbnRXaW5kb3coKSkNCgl7DQoJCWlmIChDUFdMX1duZCogcEdyYW5kID0gcFBhcmVudC0+R2V0UGFyZW50V2luZG93KCkpDQoJCXsNCgkJCUFTU0VSVChwR3JhbmQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7DQoJCQlyZXR1cm4gKENQV0xfTm90ZUl0ZW0qKXBHcmFuZDsNCgkJfQ0KCX0NCg0KCXJldHVybiBOVUxMOw0KfQ0KDQpJUFdMX05vdGVJdGVtKiBDUFdMX05vdGVJdGVtOjpHZXRQYXJlbnRJdGVtKCkgY29uc3QNCnsNCglyZXR1cm4gR2V0UGFyZW50Tm90ZUl0ZW0oKTsNCn0NCg0KQ1BXTF9FZGl0KiBDUFdMX05vdGVJdGVtOjpHZXRFZGl0KCkgY29uc3QNCnsNCglpZiAobV9wQ29udGVudHMpDQoJCXJldHVybiBtX3BDb250ZW50cy0+R2V0RWRpdCgpOw0KCXJldHVybiBOVUxMOw0KfQ0KDQp2b2lkKiBDUFdMX05vdGVJdGVtOjpHZXRQcml2YXRlRGF0YSgpIGNvbnN0DQp7DQoJcmV0dXJuIG1fcFByaXZhdGVEYXRhOw0KfQ0KDQpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRBdXRob3JOYW1lKCkgY29uc3QNCnsNCglyZXR1cm4gbV9zQXV0aG9yOyANCn0NCg0KQ1BXTF9Db2xvciBDUFdMX05vdGVJdGVtOjpHZXRCa0NvbG9yKCkgY29uc3QNCnsNCglyZXR1cm4gdGhpcy0+R2V0QmFja2dyb3VuZENvbG9yKCk7DQp9DQoNCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldENvbnRlbnRzKCkgY29uc3QNCnsNCglpZiAobV9wQ29udGVudHMpDQoJCXJldHVybiBtX3BDb250ZW50cy0+R2V0VGV4dCgpOw0KDQoJcmV0dXJuIEwiIjsNCn0NCg0KRlhfU1lTVEVNVElNRSBDUFdMX05vdGVJdGVtOjpHZXREYXRlVGltZSgpIGNvbnN0DQp7DQoJcmV0dXJuIG1fZHROb3RlOw0KfQ0KDQpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRTdWJqZWN0TmFtZSgpIGNvbnN0DQp7DQoJaWYgKG1fcFN1YmplY3QpDQoJCXJldHVybiBtX3BTdWJqZWN0LT5HZXRUZXh0KCk7DQoNCglyZXR1cm4gTCIiOw0KfQ0KDQpDUFdMX05vdGVJdGVtKiBDUFdMX05vdGVJdGVtOjpDcmVhdGVOb3RlSXRlbSgpDQp7DQoJaWYgKG1fcENvbnRlbnRzKQ0KCQlyZXR1cm4gbV9wQ29udGVudHMtPkNyZWF0ZVN1Ykl0ZW0oKTsNCg0KCXJldHVybiBOVUxMOw0KfQ0KDQpJUFdMX05vdGVJdGVtKiBDUFdMX05vdGVJdGVtOjpDcmVhdGVTdWJJdGVtKCkNCnsNCglyZXR1cm4gQ3JlYXRlTm90ZUl0ZW0oKTsNCn0NCg0KRlhfSU5UMzIgQ1BXTF9Ob3RlSXRlbTo6Q291bnRTdWJJdGVtcygpIGNvbnN0DQp7DQoJaWYgKG1fcENvbnRlbnRzKQ0KCQlyZXR1cm4gbV9wQ29udGVudHMtPkNvdW50U3ViSXRlbXMoKTsNCg0KCXJldHVybiAwOw0KfQ0KDQpJUFdMX05vdGVJdGVtKiBDUFdMX05vdGVJdGVtOjpHZXRTdWJJdGVtcyhGWF9JTlQzMiBpbmRleCkgY29uc3QNCnsNCglpZiAobV9wQ29udGVudHMpDQoJCXJldHVybiBtX3BDb250ZW50cy0+R2V0U3ViSXRlbXMoaW5kZXgpOw0KDQoJcmV0dXJuIE5VTEw7DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6RGVsZXRlU3ViSXRlbShJUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0pDQp7DQoJdGhpcy0+S2lsbEZvY3VzKCk7DQoNCglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQ0KCXsNCgkJcE5vdGlmeS0+T25JdGVtRGVsZXRlKHBOb3RlSXRlbSk7DQoJfQ0KDQoJaWYgKG1fcENvbnRlbnRzKQ0KCQltX3BDb250ZW50cy0+RGVsZXRlU3ViSXRlbShwTm90ZUl0ZW0pOw0KfQ0KDQpJUFdMX05vdGVJdGVtKiBDUFdMX05vdGVJdGVtOjpHZXRIaXROb3RlSXRlbShjb25zdCBDUERGX1BvaW50JiBwb2ludCkNCnsNCglDUERGX1BvaW50IHB0ID0gdGhpcy0+UGFyZW50VG9DaGlsZChwb2ludCk7DQoNCglpZiAodGhpcy0+V25kSGl0VGVzdChwdCkpDQoJew0KCQlpZiAobV9wQ29udGVudHMpDQoJCXsNCgkJCWlmIChJUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSBtX3BDb250ZW50cy0+R2V0SGl0Tm90ZUl0ZW0ocHQpKQ0KCQkJCXJldHVybiBwTm90ZUl0ZW07DQoJCX0NCg0KCQlyZXR1cm4gdGhpczsNCgl9DQoNCglyZXR1cm4gTlVMTDsNCn0NCg0KSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0Rm9jdXNlZE5vdGVJdGVtKCkgY29uc3QNCnsNCglpZiAoY29uc3QgQ1BXTF9XbmQqIHBXbmQgPSB0aGlzLT5HZXRGb2N1c2VkKCkpDQoJew0KCQlpZiAocFduZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfRWRpdCIpDQoJCXsNCgkJCWlmIChDUFdMX1duZCogcFBhcmVudCA9IHBXbmQtPkdldFBhcmVudFdpbmRvdygpKQ0KCQkJew0KCQkJCUFTU0VSVChwUGFyZW50LT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlX0NvbnRlbnRzIik7DQoJCQkJDQoJCQkJaWYgKENQV0xfV25kKiBwR3JhbmQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKSkNCgkJCQl7DQoJCQkJCUFTU0VSVChwR3JhbmQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7CQkJCQkNCgkJCQkJcmV0dXJuIChDUFdMX05vdGVJdGVtKilwR3JhbmQ7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJfQ0KDQoJcmV0dXJuIE5VTEw7DQp9DQoNCkZYX0ZMT0FUIENQV0xfTm90ZUl0ZW06OkdldEl0ZW1IZWlnaHQoRlhfRkxPQVQgZkxpbWl0V2lkdGgpDQp7DQoJaWYgKGZMaW1pdFdpZHRoID4gMCkNCgl7DQoJCWlmICghbV9iU2l6ZUNoYW5nZWQpDQoJCQlyZXR1cm4gbV9mT2xkSXRlbUhlaWdodDsNCg0KCQltX2JTaXplQ2hhbmdlZCA9IEZBTFNFOw0KDQoJCUFTU0VSVChtX3BTdWJqZWN0ICE9IE5VTEwpOw0KCQlBU1NFUlQobV9wRGF0ZVRpbWUgIT0gTlVMTCk7DQoJCUFTU0VSVChtX3BDb250ZW50cyAhPSBOVUxMKTsNCg0KCQlGWF9GTE9BVCBmUmV0ID0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7DQoJCUZYX0ZMT0FUIGZCb3JkZXJXaWR0aCA9IChGWF9GTE9BVCl0aGlzLT5HZXRCb3JkZXJXaWR0aCgpOw0KCQlpZiAoZkxpbWl0V2lkdGggPiBmQm9yZGVyV2lkdGggKiAyKQ0KCQkJZlJldCArPSBtX3BDb250ZW50cy0+R2V0Q29udGVudHNIZWlnaHQoZkxpbWl0V2lkdGggLSBmQm9yZGVyV2lkdGggKiAyKTsNCgkJZlJldCArPSBQT1BVUF9JVEVNX0hFQURfQk9UVE9NICsgUE9QVVBfSVRFTV9CT1RUT01XSURUSCArIGZCb3JkZXJXaWR0aCAqIDI7DQoNCgkJcmV0dXJuIG1fZk9sZEl0ZW1IZWlnaHQgPSBmUmV0Ow0KCX0NCg0KCXJldHVybiAwOw0KfQ0KDQpGWF9GTE9BVCBDUFdMX05vdGVJdGVtOjpHZXRJdGVtTGVmdE1hcmdpbigpDQp7DQoJcmV0dXJuIFBPUFVQX0lURU1fU0lERU1BUkdJTjsNCn0NCg0KRlhfRkxPQVQgQ1BXTF9Ob3RlSXRlbTo6R2V0SXRlbVJpZ2h0TWFyZ2luKCkNCnsNCglyZXR1cm4gUE9QVVBfSVRFTV9TSURFTUFSR0lOOw0KfQ0KDQpGWF9CT09MCUNQV0xfTm90ZUl0ZW06Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQ0Kew0KCWlmICghbV9wQ29udGVudHMtPlduZEhpdFRlc3QobV9wQ29udGVudHMtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkNCgl7DQoJCVNldE5vdGVGb2N1cyhGQUxTRSk7DQoJfQ0KDQoJQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOw0KDQoJcmV0dXJuIFRSVUU7DQp9DQoNCkZYX0JPT0wJQ1BXTF9Ob3RlSXRlbTo6T25SQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCnsNCglpZiAoIW1fcENvbnRlbnRzLT5XbmRIaXRUZXN0KG1fcENvbnRlbnRzLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpDQoJew0KCQlTZXROb3RlRm9jdXMoRkFMU0UpOw0KCQlQb3B1cE5vdGVJdGVtTWVudShwb2ludCk7DQoNCgkJcmV0dXJuIFRSVUU7DQoJfQ0KDQoJcmV0dXJuIENQV0xfV25kOjpPblJCdXR0b25VcChwb2ludCxuRmxhZyk7DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSwgRlhfSU5UUFRSIGxQYXJhbSkNCnsNCglzd2l0Y2ggKG1zZykNCgl7DQoJY2FzZSBQTk1fTk9URUVESVRDSEFOR0VEOgkNCgkJbV9iU2l6ZUNoYW5nZWQgPSBUUlVFOw0KDQoJCWlmIChDUFdMX1duZCogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQ0KCQl7DQoJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsNCgkJfQ0KCQlyZXR1cm47CQ0KCWNhc2UgUE5NX1NFVENBUkVUSU5GTzoNCgkJaWYgKFBXTF9DQVJFVF9JTkZPICogcEluZm8gPSAoUFdMX0NBUkVUX0lORk8qKXdQYXJhbSkNCgkJew0KCQkJUFdMX0NBUkVUX0lORk8gbmV3SW5mbyA9ICpwSW5mbzsNCgkJCW5ld0luZm8uYlZpc2libGUgPSBUUlVFOw0KCQkJbmV3SW5mby5wdEhlYWQgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEhlYWQpOw0KCQkJbmV3SW5mby5wdEZvb3QgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEZvb3QpOw0KDQoJCQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpDQoJCQl7DQoJCQkJcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX1NFVENBUkVUSU5GTywgKEZYX0lOVFBUUikmbmV3SW5mbywgMCk7DQoJCQl9DQoJCX0NCgkJcmV0dXJuOw0KCWNhc2UgUE5NX05PVEVSRVNFVDoNCgkJbV9iU2l6ZUNoYW5nZWQgPSBUUlVFOw0KCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7DQoJCQ0KCQlyZXR1cm47DQoJfQ0KDQoJQ1BXTF9XbmQ6Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOw0KfQ0KDQp2b2lkIENQV0xfTm90ZUl0ZW06OlBvcHVwTm90ZUl0ZW1NZW51KGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0Kew0KCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpDQoJew0KCQlGWF9JTlQzMiB4LHk7DQoJCVBXTHRvV25kKHBvaW50LCB4LCB5KTsNCgkJaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU0ggPSBHZXRTeXN0ZW1IYW5kbGVyKCkpDQoJCQlwU0gtPkNsaWVudFRvU2NyZWVuKEdldEF0dGFjaGVkSFduZCgpLCB4LCB5KTsNCgkJcE5vdGlmeS0+T25Qb3B1cE1lbnUodGhpcywgeCwgeSk7DQoJfQ0KfQ0KDQpjb25zdCBDUFdMX05vdGUqIENQV0xfTm90ZUl0ZW06OkdldE5vdGUoKSBjb25zdA0Kew0KCWlmIChjb25zdCBDUFdMX1duZCogcFJvb3QgPSB0aGlzLT5HZXRSb290V25kKCkpDQoJew0KCQlBU1NFUlQocFJvb3QtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7DQoJCUNQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwUm9vdDsNCgkJaWYgKHBOb3RlSXRlbS0+SXNUb3BJdGVtKCkpDQoJCXsNCgkJCXJldHVybiAoQ1BXTF9Ob3RlKilwTm90ZUl0ZW07DQoJCX0NCgl9DQoNCglyZXR1cm4gTlVMTDsNCn0NCg0KSVBXTF9Ob3RlTm90aWZ5KiBDUFdMX05vdGVJdGVtOjpHZXROb3RlTm90aWZ5KCkgY29uc3QNCnsNCglpZiAoY29uc3QgQ1BXTF9Ob3RlKiBwTm90ZSA9IEdldE5vdGUoKSkNCgkJcmV0dXJuIHBOb3RlLT5HZXROb3RlTm90aWZ5KCk7DQoNCglyZXR1cm4gTlVMTDsNCn0NCg0Kdm9pZCBDUFdMX05vdGVJdGVtOjpPbkNyZWF0ZU5vdGVJdGVtKCkNCnsNCglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQ0KCXsNCgkJcE5vdGlmeS0+T25JdGVtQ3JlYXRlKHRoaXMpOw0KCX0NCn0NCg0Kdm9pZCBDUFdMX05vdGVJdGVtOjpPbkNvbnRlbnRzVmFsaWRhdGUoKQ0Kew0KCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpDQoJew0KCQlwTm90aWZ5LT5PblNldENvbnRlbnRzKHRoaXMpOw0KCX0NCn0NCg0Kdm9pZCBDUFdMX05vdGVJdGVtOjpTZXROb3RlRm9jdXMoRlhfQk9PTCBiTGFzdCkNCnsNCgltX3BDb250ZW50cy0+U2V0RWRpdEZvY3VzKGJMYXN0KTsNCn0NCg0Kdm9pZCBDUFdMX05vdGVJdGVtOjpFbmFibGVNb2RpZnkoRlhfQk9PTCBiRW5hYmxlZCkNCnsNCgltX3BDb250ZW50cy0+RW5hYmxlTW9kaWZ5KGJFbmFibGVkKTsNCgltX2JBbGxvd01vZGlmeSA9IGJFbmFibGVkOw0KfQ0KDQp2b2lkIENQV0xfTm90ZUl0ZW06OkVuYWJsZVJlYWQoRlhfQk9PTCBiRW5hYmxlZCkNCnsNCgltX3BDb250ZW50cy0+RW5hYmxlUmVhZChiRW5hYmxlZCk7DQp9DQoNCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCg0KQ1BXTF9Ob3RlOjpDUFdMX05vdGUoSVBvcHVwX05vdGUqIHBQb3B1cE5vdGUsIElQV0xfTm90ZU5vdGlmeSogcE5vdGVOb3RpZnksIElQV0xfTm90ZUhhbmRsZXIqIHBOb3RlSGFuZGxlcikgOiANCgltX3BBdXRob3IoTlVMTCksDQoJbV9wSWNvbihOVUxMKSwNCgltX3BDbG9zZUJveChOVUxMKSwNCgltX3BDb250ZW50c0JhcihOVUxMKSwNCgltX3BMQkJveChOVUxMKSwNCgltX3BSQkJveChOVUxMKSwNCgltX3BPcHRpb25zKE5VTEwpLA0KCW1fYlJlc2l6aW5nKEZBTFNFKSwNCgltX3JjQ2FwdGlvbigwLDAsMCwwKSwNCgltX3BOb3RlTm90aWZ5KHBOb3RlTm90aWZ5KSwNCgltX2JFbmFsYmxlTm90aWZ5KFRSVUUpLA0KCW1fcFBvcHVwTm90ZShwUG9wdXBOb3RlKSwNCgltX3BOb3RlSGFuZGxlcihwTm90ZUhhbmRsZXIpDQp7DQp9DQoNCkNQV0xfTm90ZTo6fkNQV0xfTm90ZSgpDQp7DQp9DQoNCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZTo6UmVwbHkoKQ0Kew0KCXJldHVybiBDcmVhdGVOb3RlSXRlbSgpOw0KfQ0KDQp2b2lkIENQV0xfTm90ZTo6RW5hYmxlTm90aWZ5KEZYX0JPT0wgYkVuYWJsZWQpDQp7DQoJbV9iRW5hbGJsZU5vdGlmeSA9IGJFbmFibGVkOw0KfQ0KDQp2b2lkIENQV0xfTm90ZTo6UmVQb3NDaGlsZFduZCgpDQp7DQoJUmVQb3NOb3RlQ2hpbGRyZW4oKTsNCgltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7DQoJUmVzZXRTY3JvbGxCYXIoKTsNCgltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7DQoJdGhpcy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7DQoJLy/NrLK9DQoJaWYgKGNvbnN0IENQV0xfV25kKiBwV25kID0gdGhpcy0+R2V0Rm9jdXNlZCgpKQ0KCXsNCgkJaWYgKHBXbmQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX0VkaXQiKQ0KCQl7DQoJCQlDUFdMX0VkaXQqIHBFZGl0ID0gKENQV0xfRWRpdCopcFduZDsNCgkJCXBFZGl0LT5TZXRDYXJldChwRWRpdC0+R2V0Q2FyZXQoKSk7DQoJCX0NCgl9DQoJLy9DUERGX1BvaW50IHB0TmV3ID0gbV9wQ29udGVudHMtPkdldFNjcm9sbFBvcygpOw0KCS8vbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdE5ldy55KTsNCn0NCg0KRlhfQk9PTCBDUFdMX05vdGU6OlJlc2V0U2Nyb2xsQmFyKCkNCnsNCglGWF9CT09MIGJTY3JvbGxDaGFuZ2VkID0gRkFMU0U7DQoNCglpZiAoU2Nyb2xsQmFyU2hvdWxkVmlzaWJsZSgpKQ0KCXsNCgkJaWYgKCFtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpDQoJCXsNCgkJCW1fcENvbnRlbnRzQmFyLT5TZXRWaXNpYmxlKFRSVUUpOw0KCQkJaWYgKG1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkNCgkJCXsNCgkJCQltX3BDb250ZW50c0Jhci0+SW52YWxpZGF0ZVJlY3QoTlVMTCk7DQoJCQkJYlNjcm9sbENoYW5nZWQgPSBUUlVFOw0KCQkJfQ0KCQl9CQ0KCX0NCgllbHNlDQoJew0KCQlpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQ0KCQl7DQoJCQltX3BDb250ZW50c0Jhci0+U2V0VmlzaWJsZShGQUxTRSk7DQoJCQltX3BDb250ZW50c0Jhci0+SW52YWxpZGF0ZVJlY3QoTlVMTCk7DQoNCgkJCWJTY3JvbGxDaGFuZ2VkID0gVFJVRTsNCgkJfQ0KCX0NCg0KCWlmIChiU2Nyb2xsQ2hhbmdlZCkNCgl7DQoJCUNQREZfUmVjdCByY05vdGUgPSB0aGlzLT5HZXRDbGllbnRSZWN0KCk7DQoJCUNQREZfUmVjdCByY0NvbnRlbnRzID0gbV9wQ29udGVudHMtPkdldFdpbmRvd1JlY3QoKTsNCgkJcmNDb250ZW50cy5yaWdodCA9IHJjTm90ZS5yaWdodCAtIDMuMGY7DQoJCWlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpDQoJCQlyY0NvbnRlbnRzLnJpZ2h0IC09IFBXTF9TQ1JPTExCQVJfV0lEVEg7DQoJCW1fcENvbnRlbnRzLT5Nb3ZlKHJjQ29udGVudHMsIFRSVUUsIFRSVUUpOw0KCQltX3BDb250ZW50cy0+U2V0U2Nyb2xsUG9zKENQREZfUG9pbnQoMC4wZiwwLjBmKSk7DQoJCW1fcENvbnRlbnRzLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsNCgl9DQoNCglyZXR1cm4gYlNjcm9sbENoYW5nZWQ7DQp9DQoNCkZYX0JPT0wgQ1BXTF9Ob3RlOjpTY3JvbGxCYXJTaG91bGRWaXNpYmxlKCkNCnsNCglDUERGX1JlY3QgcmNDb250ZW50c0ZhY3QgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsQXJlYSgpOw0KCUNQREZfUmVjdCByY0NvbnRlbnRzQ2xpZW50ID0gbV9wQ29udGVudHMtPkdldENsaWVudFJlY3QoKTsNCg0KCXJldHVybiByY0NvbnRlbnRzRmFjdC5IZWlnaHQoKSA+IHJjQ29udGVudHNDbGllbnQuSGVpZ2h0KCk7CQ0KfQ0KDQp2b2lkIENQV0xfTm90ZTo6U2V0T3B0aW9uc1RleHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUZXh0KQ0Kew0KCWlmIChtX3BPcHRpb25zKQ0KCQltX3BPcHRpb25zLT5TZXRUZXh0KHNUZXh0KTsNCg0KCVJlUG9zTm90ZUNoaWxkcmVuKCk7DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlOjpSZVBvc05vdGVDaGlsZHJlbigpDQp7DQoJaWYgKG1fYlJlc2l6aW5nKSByZXR1cm47DQoNCgltX2JSZXNpemluZyA9IFRSVUU7DQoNCglpZiAodGhpcy0+SXNWYWxpZCgpKQ0KCXsNCgkJQVNTRVJUKG1fcFN1YmplY3QgIT0gTlVMTCk7DQoJCUFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsNCgkJQVNTRVJUKG1fcENvbnRlbnRzICE9IE5VTEwpOw0KCQlBU1NFUlQobV9wQXV0aG9yICE9IE5VTEwpOw0KCQlBU1NFUlQobV9wQ2xvc2VCb3ggIT0gTlVMTCk7DQoJCUFTU0VSVChtX3BJY29uICE9IE5VTEwpOw0KCQlBU1NFUlQobV9wTEJCb3ggIT0gTlVMTCk7DQoJCUFTU0VSVChtX3BSQkJveCAhPSBOVUxMKTsNCgkJQVNTRVJUKG1fcENvbnRlbnRzQmFyICE9IE5VTEwpOw0KCQlBU1NFUlQobV9wT3B0aW9ucyAhPSBOVUxMKTsNCg0KCQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7DQoNCgkJQ1BERl9SZWN0IHJjSWNvbiA9IHJjQ2xpZW50Ow0KCQlyY0ljb24udG9wIC09IDIuMGY7DQoJCXJjSWNvbi5yaWdodCA9IHJjSWNvbi5sZWZ0ICsgMTQuMGY7DQoJCXJjSWNvbi5ib3R0b20gPSByY0ljb24udG9wIC0gMTQuMGY7DQoJCXJjSWNvbi5Ob3JtYWxpemUoKTsNCgkJbV9wSWNvbi0+TW92ZShyY0ljb24sIFRSVUUsIEZBTFNFKTsNCgkJbV9wSWNvbi0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjSWNvbikpOw0KDQoJCUNQREZfUmVjdCByY0Nsb3NlQm94ID0gcmNDbGllbnQ7DQoJCXJjQ2xvc2VCb3gucmlnaHQgLT0gMS4wZjsNCgkJcmNDbG9zZUJveC50b3AgLT0gMS4wZjsNCgkJcmNDbG9zZUJveC5sZWZ0ID0gcmNDbG9zZUJveC5yaWdodCAtIDE0LjBmOw0KCQlyY0Nsb3NlQm94LmJvdHRvbSA9IHJjQ2xvc2VCb3gudG9wIC0gMTQuMGY7DQoJCXJjQ2xvc2VCb3guTm9ybWFsaXplKCk7DQoJCW1fcENsb3NlQm94LT5Nb3ZlKHJjQ2xvc2VCb3gsIFRSVUUsIEZBTFNFKTsNCgkJbV9wQ2xvc2VCb3gtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0Nsb3NlQm94KSk7DQoNCgkJQ1BERl9SZWN0IHJjRGF0ZSA9IHJjQ2xpZW50Ow0KCQlyY0RhdGUucmlnaHQgPSByY0Nsb3NlQm94LmxlZnQgLSBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOw0KCQlyY0RhdGUubGVmdCA9IFBXTF9NQVgocmNEYXRlLnJpZ2h0IC0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSAtIDEuMGYsIHJjSWNvbi5yaWdodCArIDEuMGYpOw0KCQlyY0RhdGUudG9wID0gcmNDbGllbnQudG9wIC0gMi4wZjsNCgkJcmNEYXRlLmJvdHRvbSA9IHJjRGF0ZS50b3AgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsNCgkJcmNEYXRlLk5vcm1hbGl6ZSgpOw0KCQltX3BEYXRlVGltZS0+TW92ZShyY0RhdGUsIFRSVUUsIEZBTFNFKTsNCgkJbV9wRGF0ZVRpbWUtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0RhdGUpKTsNCg0KCQlDUERGX1JlY3QgcmNTdWJqZWN0ID0gcmNDbGllbnQ7DQoJCXJjU3ViamVjdC50b3AgPSByY0NsaWVudC50b3AgLSAyLjBmOw0KCQlyY1N1YmplY3QubGVmdCA9IHJjSWNvbi5yaWdodCArIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7DQoJCXJjU3ViamVjdC5yaWdodCA9IFBXTF9NSU4ocmNTdWJqZWN0LmxlZnQgKyBtX3BTdWJqZWN0LT5HZXRDb250ZW50UmVjdCgpLldpZHRoKCkgKyAxLjBmLCByY0RhdGUubGVmdCAtIDEuMGYpOw0KCQlyY1N1YmplY3QuYm90dG9tID0gcmNTdWJqZWN0LnRvcCAtIG1fcFN1YmplY3QtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7DQoJCXJjU3ViamVjdC5Ob3JtYWxpemUoKTsNCgkJbV9wU3ViamVjdC0+TW92ZShyY1N1YmplY3QsIFRSVUUsIEZBTFNFKTsJDQoJCW1fcFN1YmplY3QtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY1N1YmplY3QpKTsNCg0KCQlDUERGX1JlY3QgcmNPcHRpb25zID0gcmNDbGllbnQ7DQoJCXJjT3B0aW9ucy5sZWZ0ID0gUFdMX01BWChyY09wdGlvbnMucmlnaHQgLSBtX3BPcHRpb25zLT5HZXRDb250ZW50UmVjdCgpLldpZHRoKCksIHJjSWNvbi5yaWdodCArIDEuMGYpOw0KCQlyY09wdGlvbnMudG9wID0gcmNTdWJqZWN0LmJvdHRvbSAtIDQuMGY7DQoJCXJjT3B0aW9ucy5ib3R0b20gPSByY09wdGlvbnMudG9wIC0gbV9wT3B0aW9ucy0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsNCgkJcmNPcHRpb25zLk5vcm1hbGl6ZSgpOw0KCQltX3BPcHRpb25zLT5Nb3ZlKHJjT3B0aW9ucywgVFJVRSwgRkFMU0UpOw0KCQltX3BPcHRpb25zLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNPcHRpb25zKSk7DQoNCgkJQ1BERl9SZWN0IHJjQXV0aG9yID0gcmNDbGllbnQ7DQoJCXJjQXV0aG9yLnRvcCA9IHJjU3ViamVjdC5ib3R0b20gLSA0LjBmOw0KCQlyY0F1dGhvci5sZWZ0ID0gcmNTdWJqZWN0LmxlZnQ7DQoJCXJjQXV0aG9yLnJpZ2h0ID0gUFdMX01JTihyY1N1YmplY3QubGVmdCArIG1fcEF1dGhvci0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpICsgMS4wZiwgcmNPcHRpb25zLmxlZnQgLSAxLjBmKTsNCgkJcmNBdXRob3IuYm90dG9tID0gcmNBdXRob3IudG9wIC0gbV9wQXV0aG9yLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOw0KCQlyY0F1dGhvci5Ob3JtYWxpemUoKTsNCgkJbV9wQXV0aG9yLT5Nb3ZlKHJjQXV0aG9yLCBUUlVFLCBGQUxTRSk7DQoJCW1fcEF1dGhvci0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjQXV0aG9yKSk7DQoNCgkJQ1BERl9SZWN0IHJjTEJCb3ggPSByY0NsaWVudDsNCgkJcmNMQkJveC50b3AgPSByY0xCQm94LmJvdHRvbSArIDcuMGY7DQoJCXJjTEJCb3gucmlnaHQgPSByY0xCQm94LmxlZnQgKyA3LjBmOw0KCQlyY0xCQm94Lk5vcm1hbGl6ZSgpOw0KCQltX3BMQkJveC0+TW92ZShyY0xCQm94LCBUUlVFLCBGQUxTRSk7DQoJCW1fcExCQm94LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNMQkJveCkpOw0KDQoJCUNQREZfUmVjdCByY1JCQm94ID0gcmNDbGllbnQ7DQoJCXJjUkJCb3gudG9wID0gcmNSQkJveC5ib3R0b20gKyA3LjBmOw0KCQlyY1JCQm94LmxlZnQgPSByY1JCQm94LnJpZ2h0IC0gNy4wZjsNCgkJcmNSQkJveC5Ob3JtYWxpemUoKTsNCgkJbV9wUkJCb3gtPk1vdmUocmNSQkJveCwgVFJVRSwgRkFMU0UpOw0KCQltX3BSQkJveC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjUkJCb3gpKTsNCg0KCQlDUERGX1JlY3QgcmNDb250ZW50cyA9IHJjQ2xpZW50Ow0KCQlyY0NvbnRlbnRzLnRvcCA9IHJjQXV0aG9yLmJvdHRvbSAtIFBPUFVQX0lURU1fSEVBRF9CT1RUT007DQoJCXJjQ29udGVudHMubGVmdCArPSAzLjBmOw0KCQlyY0NvbnRlbnRzLnJpZ2h0IC09IDMuMGY7DQoJCWlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpDQoJCQlyY0NvbnRlbnRzLnJpZ2h0IC09IFBXTF9TQ1JPTExCQVJfV0lEVEg7DQoJCXJjQ29udGVudHMuYm90dG9tICs9IDE0LjBmOw0KCQlyY0NvbnRlbnRzLk5vcm1hbGl6ZSgpOw0KCQltX3BDb250ZW50cy0+TW92ZShyY0NvbnRlbnRzLCBGQUxTRSwgRkFMU0UpOw0KCQltX3BDb250ZW50cy0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjQ29udGVudHMpKTsNCg0KCQlDUERGX1JlY3QgcmNDb250ZW50c0JhciA9IHJjQ29udGVudHM7DQoJCXJjQ29udGVudHNCYXIucmlnaHQgPSByY0NsaWVudC5yaWdodCAtIDMuMGY7DQoJCXJjQ29udGVudHNCYXIubGVmdCA9IHJjQ29udGVudHNCYXIucmlnaHQgLSBQV0xfU0NST0xMQkFSX1dJRFRIOw0KCQlyY0NvbnRlbnRzQmFyLk5vcm1hbGl6ZSgpOw0KCQltX3BDb250ZW50c0Jhci0+TW92ZShyY0NvbnRlbnRzQmFyLCBUUlVFLCBGQUxTRSk7DQoJCQ0KCQltX3JjQ2FwdGlvbiA9IHJjQ2xpZW50Ow0KCQltX3JjQ2FwdGlvbi5ib3R0b20gPSByY0NvbnRlbnRzLnRvcDsNCgl9DQoNCgltX2JSZXNpemluZyA9IEZBTFNFOw0KfQ0KDQovLzAtbm9ybWFsIC8gMS1jYXB0aW9uIC8gMi1sZWZ0Ym90dG9tIGNvcm5lciAvIDMtcmlnaHRib3R0b20gY29ybmVyIC8gNC1jbG9zZSAvIDUtb3B0aW9ucyANCkZYX0lOVDMyIENQV0xfTm90ZTo6Tm90ZUhpdFRlc3QoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIGNvbnN0DQp7DQoJQVNTRVJUKG1fcFN1YmplY3QgIT0gTlVMTCk7DQoJQVNTRVJUKG1fcERhdGVUaW1lICE9IE5VTEwpOw0KCUFTU0VSVChtX3BDb250ZW50cyAhPSBOVUxMKTsNCglBU1NFUlQobV9wQXV0aG9yICE9IE5VTEwpOw0KCUFTU0VSVChtX3BJY29uICE9IE5VTEwpOw0KCUFTU0VSVChtX3BDb250ZW50c0JhciAhPSBOVUxMKTsNCg0KCUFTU0VSVChtX3BDbG9zZUJveCAhPSBOVUxMKTsNCglBU1NFUlQobV9wTEJCb3ggIT0gTlVMTCk7DQoJQVNTRVJUKG1fcFJCQm94ICE9IE5VTEwpOw0KCUFTU0VSVChtX3BPcHRpb25zICE9IE5VTEwpOw0KDQoJR2V0Q2xpZW50UmVjdCgpOw0KDQoJaWYgKG1fcFN1YmplY3QtPlduZEhpdFRlc3QobV9wU3ViamVjdC0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMTsNCglpZiAobV9wRGF0ZVRpbWUtPlduZEhpdFRlc3QobV9wRGF0ZVRpbWUtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDE7DQoJaWYgKG1fcEF1dGhvci0+V25kSGl0VGVzdChtX3BBdXRob3ItPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDE7DQoJaWYgKG1fcEljb24tPlduZEhpdFRlc3QobV9wSWNvbi0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMTsNCg0KCWlmIChtX3BDb250ZW50cy0+V25kSGl0VGVzdChtX3BDb250ZW50cy0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMDsNCglpZiAobV9wQ29udGVudHNCYXItPlduZEhpdFRlc3QobV9wQ29udGVudHNCYXItPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDA7DQoNCglpZiAobV9wQ2xvc2VCb3gtPlduZEhpdFRlc3QobV9wQ2xvc2VCb3gtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDQ7DQoJaWYgKG1fcExCQm94LT5XbmRIaXRUZXN0KG1fcExCQm94LT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAyOw0KCWlmIChtX3BSQkJveC0+V25kSGl0VGVzdChtX3BSQkJveC0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMzsNCglpZiAobV9wT3B0aW9ucy0+V25kSGl0VGVzdChtX3BPcHRpb25zLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiA1Ow0KDQoJcmV0dXJuIDE7DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkNCnsNCglDUFdMX05vdGVJdGVtOjpDcmVhdGVDaGlsZFduZChjcCk7DQoNCglDUFdMX0NvbG9yIHNUZXh0Q29sb3I7DQoNCglpZiAoQ1BXTF9VdGlsczo6SXNCbGFja09yV2hpdGUodGhpcy0+R2V0QmFja2dyb3VuZENvbG9yKCkpKQ0KCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsNCgllbHNlDQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9CTEFDS0NPTE9SOw0KDQoJbV9wQXV0aG9yID0gbmV3IENQV0xfTGFiZWw7DQoJUFdMX0NSRUFURVBBUkFNIGFjcCA9IGNwOw0KCWFjcC5wUGFyZW50V25kID0gdGhpczsNCglhY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUEVTX0xFRlQgfCBQRVNfVE9QOw0KCWFjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsNCgltX3BBdXRob3ItPkNyZWF0ZShhY3ApOwkgDQoNCgltX3BDbG9zZUJveCA9IG5ldyBDUFdMX05vdGVfQ2xvc2VCb3g7DQoJUFdMX0NSRUFURVBBUkFNIGNjcCA9IGNwOw0KCWNjcC5wUGFyZW50V25kID0gdGhpczsNCgljY3AuZHdCb3JkZXJXaWR0aCA9IDI7DQoJY2NwLm5Cb3JkZXJTdHlsZSA9IFBCU19CRVZFTEVEOw0KCWNjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQV1NfQk9SREVSOw0KCWNjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsNCgltX3BDbG9zZUJveC0+Q3JlYXRlKGNjcCk7DQoNCgltX3BJY29uID0gbmV3IENQV0xfTm90ZV9JY29uOw0KCVBXTF9DUkVBVEVQQVJBTSBpY3AgPSBjcDsNCglpY3AucFBhcmVudFduZCA9IHRoaXM7DQoJaWNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRDsNCgltX3BJY29uLT5DcmVhdGUoaWNwKTsNCg0KCW1fcE9wdGlvbnMgPSBuZXcgQ1BXTF9Ob3RlX09wdGlvbnM7DQoJUFdMX0NSRUFURVBBUkFNIG9jcCA9IGNwOw0KCW9jcC5wUGFyZW50V25kID0gdGhpczsNCglvY3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFOw0KCW9jcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsNCgltX3BPcHRpb25zLT5DcmVhdGUob2NwKTsNCg0KCW1fcExCQm94ID0gbmV3IENQV0xfTm90ZV9MQkJveDsNCglQV0xfQ1JFQVRFUEFSQU0gbGNwID0gY3A7DQoJbGNwLnBQYXJlbnRXbmQgPSB0aGlzOw0KCWxjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQ7DQoJbGNwLmVDdXJzb3JUeXBlID0gRlhDVF9ORVNXOw0KCWxjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsNCgltX3BMQkJveC0+Q3JlYXRlKGxjcCk7DQoNCgltX3BSQkJveCA9IG5ldyBDUFdMX05vdGVfUkJCb3g7DQoJUFdMX0NSRUFURVBBUkFNIHJjcCA9IGNwOw0KCXJjcC5wUGFyZW50V25kID0gdGhpczsNCglyY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEOw0KCXJjcC5lQ3Vyc29yVHlwZSA9IEZYQ1RfTldTRTsNCglyY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7DQoJbV9wUkJCb3gtPkNyZWF0ZShyY3ApOw0KDQoJbV9wQ29udGVudHNCYXIgPSBuZXcgQ1BXTF9TY3JvbGxCYXIoU0JUX1ZTQ1JPTEwpOw0KCVBXTF9DUkVBVEVQQVJBTSBzY3AgPSBjcDsNCglzY3AucFBhcmVudFduZCA9IHRoaXM7DQoJc2NwLnNCYWNrZ3JvdW5kQ29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIDI0MC8yNTUuMGYsIDI0MC8yNTUuMGYsIDI0MC8yNTUuMGYpOw0KCXNjcC5kd0ZsYWdzID0gUFdTX0NISUxEIHwgUFdTX1ZJU0lCTEUgfCBQV1NfQkFDS0dST1VORDsNCgltX3BDb250ZW50c0Jhci0+Q3JlYXRlKHNjcCk7DQoJbV9wQ29udGVudHNCYXItPlNldE5vdGlmeUZvcmV2ZXIoVFJVRSk7DQp9DQoNCnZvaWQgQ1BXTF9Ob3RlOjpTZXRTdWJqZWN0TmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpDQp7DQoJQ1BXTF9Ob3RlSXRlbTo6U2V0U3ViamVjdE5hbWUoc05hbWUpOw0KCVJlUG9zQ2hpbGRXbmQoKTsNCn0NCg0Kdm9pZCBDUFdMX05vdGU6OlNldEF1dGhvck5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNOYW1lKQ0Kew0KCWlmIChtX3BBdXRob3IpDQoJew0KCQltX3BBdXRob3ItPlNldFRleHQoc05hbWUpOw0KCQlSZVBvc0NoaWxkV25kKCk7DQoJfQ0KDQoJaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkNCgl7DQoJCXBOb3RpZnktPk9uU2V0QXV0aG9yTmFtZSh0aGlzKTsNCgl9CQ0KfQ0KDQpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGU6OkdldEF1dGhvck5hbWUoKSBjb25zdA0Kew0KCWlmIChtX3BBdXRob3IpDQoJCXJldHVybiBtX3BBdXRob3ItPkdldFRleHQoKTsNCg0KCXJldHVybiBMIiI7DQp9DQoNCkZYX0JPT0wgQ1BXTF9Ob3RlOjpPbk1vdXNlV2hlZWwoc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQ0Kew0KCUNQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7DQoJQ1BERl9SZWN0IHJjU2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbEFyZWEoKTsNCglDUERGX1JlY3QgcmNDb250ZW50cyA9IG1fcENvbnRlbnRzLT5HZXRDbGllbnRSZWN0KCk7DQoNCglpZiAocmNTY3JvbGwudG9wIC0gcmNTY3JvbGwuYm90dG9tID4gcmNDb250ZW50cy5IZWlnaHQoKSkNCgl7DQoJCUNQREZfUG9pbnQgcHROZXcgPSBwdFNjcm9sbDsNCg0KCQlpZiAoekRlbHRhID4gMCkNCgkJCXB0TmV3LnkgKz0gMzA7DQoJCWVsc2UNCgkJCXB0TmV3LnkgLT0gMzA7DQoNCgkJaWYgKHB0TmV3LnkgPiByY1Njcm9sbC50b3ApDQoJCQlwdE5ldy55ID0gcmNTY3JvbGwudG9wOw0KCQlpZiAocHROZXcueSA8IHJjU2Nyb2xsLmJvdHRvbSArIHJjQ29udGVudHMuSGVpZ2h0KCkpDQoJCQlwdE5ldy55ID0gcmNTY3JvbGwuYm90dG9tICsgcmNDb250ZW50cy5IZWlnaHQoKTsNCgkJaWYgKHB0TmV3LnkgPCByY1Njcm9sbC5ib3R0b20pDQoJCQlwdE5ldy55ID0gcmNTY3JvbGwuYm90dG9tOw0KDQoJCWlmIChwdE5ldy55ICE9IHB0U2Nyb2xsLnkpDQoJCXsNCgkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsNCgkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHROZXcueSk7CQkJDQoJCQltX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0TmV3LnkpOw0KDQoJCQlyZXR1cm4gVFJVRTsNCgkJfQ0KCX0NCg0KCXJldHVybiBGQUxTRTsNCn0NCg0Kdm9pZCBDUFdMX05vdGU6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0sIEZYX0lOVFBUUiBsUGFyYW0pDQp7DQoJc3dpdGNoIChtc2cpDQoJew0KCWNhc2UgUE5NX05PVEVFRElUQ0hBTkdFRDoNCgkJew0KCQkJQ1BERl9SZWN0IHJjU2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbEFyZWEoKTsNCgkJCQ0KDQoJCQlQV0xfU0NST0xMX0lORk8gc0luZm87DQoJCQlzSW5mby5mQ29udGVudE1pbiA9IHJjU2Nyb2xsLmJvdHRvbTsNCgkJCXNJbmZvLmZDb250ZW50TWF4ID0gcmNTY3JvbGwudG9wOw0KCQkJc0luZm8uZlBsYXRlV2lkdGggPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpLkhlaWdodCgpOw0KCQkJc0luZm8uZlNtYWxsU3RlcCA9IDEzLjBmOw0KCQkJc0luZm8uZkJpZ1N0ZXAgPSBzSW5mby5mUGxhdGVXaWR0aDsNCg0KCQkJaWYgKEZYU1lTX21lbWNtcCgmbV9PbGRTY3JvbGxJbmZvLCAmc0luZm8sIHNpemVvZihQV0xfU0NST0xMX0lORk8pKSAhPSAwKQ0KCQkJew0KCQkJCUZYX0JPT0wgYlNjcm9sbENoYW5nZWQgPSBGQUxTRTsNCg0KCQkJCWlmIChsUGFyYW0gPCAzKSAvL7fA1rnLwNGtu7cgbWFudGlzOjE1NzU5DQoJCQkJew0KCQkJCQliU2Nyb2xsQ2hhbmdlZCA9IFJlc2V0U2Nyb2xsQmFyKCk7DQoJCQkJCWlmIChiU2Nyb2xsQ2hhbmdlZCkNCgkJCQkJew0KCQkJCQkJbFBhcmFtKys7DQoJCQkJCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7DQoJCQkJCQl0aGlzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCBsUGFyYW0pOw0KCQkJCQl9DQoJCQkJfQ0KCQkJCQ0KCQkJCWlmICghYlNjcm9sbENoYW5nZWQpDQoJCQkJew0KCQkJCQlpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQ0KCQkJCQl7DQoJCQkJCQltX3BDb250ZW50c0Jhci0+T25Ob3RpZnkocFduZCwgUE5NX1NFVFNDUk9MTElORk8sIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZzSW5mbyk7DQoJCQkJCQltX09sZFNjcm9sbEluZm8gPSBzSW5mbzsNCg0KCQkJCQkJQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsNCgkJCQkJCUNQREZfUG9pbnQgcHRPbGQgPSBwdFNjcm9sbDsNCg0KCQkJCQkJaWYgKHB0U2Nyb2xsLnkgPiBzSW5mby5mQ29udGVudE1heCkNCgkJCQkJCQlwdFNjcm9sbC55ID0gc0luZm8uZkNvbnRlbnRNYXg7DQoJCQkJCQlpZiAocHRTY3JvbGwueSA8IHNJbmZvLmZDb250ZW50TWluICsgc0luZm8uZlBsYXRlV2lkdGgpDQoJCQkJCQkJcHRTY3JvbGwueSA9IHNJbmZvLmZDb250ZW50TWluICsgc0luZm8uZlBsYXRlV2lkdGg7DQoJCQkJCQlpZiAocHRTY3JvbGwueSA8IHNJbmZvLmZDb250ZW50TWluKQ0KCQkJCQkJCXB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1pbjsNCg0KCQkJCQkJaWYgKHB0T2xkLnkgIT0gcHRTY3JvbGwueSkNCgkJCQkJCXsNCgkJCQkJCQltX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0U2Nyb2xsLnkpOw0KCQkJCQkJCW1fcENvbnRlbnRzQmFyLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsNCgkJCQkJCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0U2Nyb2xsLnkpOw0KCQkJCQkJfQ0KCQkJCQl9DQoJCQkJfQ0KCQkJfQ0KCQl9DQoNCgkJbV9wQ29udGVudHMtPkludmFsaWRhdGVSZWN0KE5VTEwpOw0KDQoJCXJldHVybjsNCgljYXNlIFBOTV9TQ1JPTExXSU5ET1c6DQoJCWlmIChtX3BDb250ZW50cykNCgkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeShwV25kLCBtc2csIHdQYXJhbSwgbFBhcmFtKTsNCgkJcmV0dXJuOw0KCWNhc2UgUE5NX1NFVFNDUk9MTFBPUzoNCgkJaWYgKG1fcENvbnRlbnRzQmFyKQ0KCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHBXbmQsUE5NX1NFVFNDUk9MTFBPUyx3UGFyYW0sbFBhcmFtKTsNCgkJcmV0dXJuOw0KCX0NCg0KCWlmIChtc2cgPT0gUE5NX1NFVENBUkVUSU5GTyAmJiBJc1ZhbGlkKCkpDQoJew0KCQlpZiAoUFdMX0NBUkVUX0lORk8gKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKQ0KCQl7DQoJCQlpZiAobV9wQ29udGVudHMpDQoJCQl7DQoJCQkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gbV9wQ29udGVudHMtPkdldENsaWVudFJlY3QoKTsNCgkJCQlpZiAocEluZm8tPnB0SGVhZC55ID4gcmNDbGllbnQudG9wKQ0KCQkJCXsNCgkJCQkJQ1BERl9Qb2ludCBwdCA9IG1fcENvbnRlbnRzLT5PdXRUb0luKHBJbmZvLT5wdEhlYWQpOw0KCQkJCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0LnkpOw0KDQoJCQkJCUNQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7DQoJCQkJCW1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUU0NST0xMUE9TLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHRTY3JvbGwueSk7DQoNCgkJCQkJcmV0dXJuOw0KCQkJCX0NCgkJCQkNCgkJCQlpZiAocEluZm8tPnB0Rm9vdC55IDwgcmNDbGllbnQuYm90dG9tKQ0KCQkJCXsNCgkJCQkJQ1BERl9Qb2ludCBwdCA9IG1fcENvbnRlbnRzLT5PdXRUb0luKHBJbmZvLT5wdEZvb3QpOw0KCQkJCQlwdC55ICs9IHJjQ2xpZW50LkhlaWdodCgpOw0KCQkJCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0LnkpOw0KDQoJCQkJCUNQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7DQoJCQkJCW1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUU0NST0xMUE9TLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHRTY3JvbGwueSk7DQoNCgkJCQkJcmV0dXJuOw0KCQkJCX0NCgkJCX0NCgkJfQ0KCX0NCg0KCUNQV0xfTm90ZUl0ZW06Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOw0KfQ0KDQp2b2lkIENQV0xfTm90ZTo6U2V0QmtDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcikNCnsNCglDUFdMX05vdGVJdGVtOjpTZXRCa0NvbG9yKGNvbG9yKTsNCg0KCUNQV0xfQ29sb3Igc0JLID0gY29sb3I7DQoJQ1BXTF9Db2xvciBzVGV4dENvbG9yOw0KCWlmIChDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZShzQkspKQ0KCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsNCgllbHNlDQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9CTEFDS0NPTE9SOw0KDQoJaWYgKG1fcENsb3NlQm94KQ0KCQltX3BDbG9zZUJveC0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOw0KCWlmIChtX3BBdXRob3IpDQoJCW1fcEF1dGhvci0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOw0KCWlmIChtX3BPcHRpb25zKQ0KCQltX3BPcHRpb25zLT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7DQoJaWYgKG1fcExCQm94KQ0KCQltX3BMQkJveC0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOw0KCWlmIChtX3BSQkJveCkNCgkJbV9wUkJCb3gtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsNCn0NCg0KRlhfQk9PTAlDUFdMX05vdGU6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQ0Kew0KCWlmIChtX3BPcHRpb25zLT5XbmRIaXRUZXN0KG1fcE9wdGlvbnMtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkNCgl7DQoJCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSB0aGlzLT5HZXROb3RlTm90aWZ5KCkpDQoJCXsNCgkJCUZYX0lOVDMyIHgsIHk7DQoJCQlQV0x0b1duZChwb2ludCwgeCwgeSk7DQoJCQlpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkNCgkJCQlwU0gtPkNsaWVudFRvU2NyZWVuKEdldEF0dGFjaGVkSFduZCgpLCB4LCB5KTsNCgkJCXRoaXMtPktpbGxGb2N1cygpOw0KCQkJcE5vdGlmeS0+T25Qb3B1cE1lbnUoeCwgeSk7DQoNCgkJCXJldHVybiBUUlVFOw0KCQl9DQoJfQ0KDQoJcmV0dXJuIENQV0xfV25kOjpPbkxCdXR0b25Eb3duKHBvaW50LG5GbGFnKTsNCn0NCg0KRlhfQk9PTAlDUFdMX05vdGU6Ok9uUkJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpDQp7DQoJcmV0dXJuIENQV0xfV25kOjpPblJCdXR0b25VcChwb2ludCxuRmxhZyk7DQp9DQoNCmNvbnN0IENQV0xfTm90ZSogQ1BXTF9Ob3RlOjpHZXROb3RlKCkgY29uc3QNCnsNCglyZXR1cm4gdGhpczsNCn0NCg0KSVBXTF9Ob3RlTm90aWZ5KiBDUFdMX05vdGU6OkdldE5vdGVOb3RpZnkoKSBjb25zdA0Kew0KCWlmIChtX2JFbmFsYmxlTm90aWZ5KQ0KCQlyZXR1cm4gbV9wTm90ZU5vdGlmeTsNCg0KCXJldHVybiBOVUxMOw0KfQ0KDQp2b2lkIENQV0xfTm90ZTo6U2V0SWNvblR5cGUoRlhfSU5UMzIgblR5cGUpDQp7DQoJaWYgKG1fcEljb24pDQoJCW1fcEljb24tPlNldEljb25UeXBlKG5UeXBlKTsNCn0NCg0Kdm9pZCBDUFdMX05vdGU6OkVuYWJsZU1vZGlmeShGWF9CT09MIGJFbmFibGVkKQ0Kew0KCW1fcENvbnRlbnRzLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOw0KfQ0KDQp2b2lkIENQV0xfTm90ZTo6RW5hYmxlUmVhZChGWF9CT09MIGJFbmFibGVkKQ0Kew0KCW1fcENvbnRlbnRzLT5FbmFibGVSZWFkKGJFbmFibGVkKTsNCn0NCg0KQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9Ob3RlOjpHZXRSZXBseVN0cmluZygpIGNvbnN0DQp7DQoJcmV0dXJuIG1fc1JlcGx5U3RyaW5nOw0KfQ0KDQp2b2lkIENQV0xfTm90ZTo6U2V0UmVwbHlTdHJpbmcoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cmluZykNCnsNCgltX3NSZXBseVN0cmluZyA9IHN0cmluZzsNCn0NCg0K