Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KIAovLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQoKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0J1dHRvbi5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXRDdHJsLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdC5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0xpc3RDdHJsLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTm90ZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0xhYmVsLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdC5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1V0aWxzLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQ2FyZXQuaCIKCiNkZWZpbmUgUE9QVVBfSVRFTV9IRUFEX0JPVFRPTQkJCQkJMy4wZgojZGVmaW5lIFBPUFVQX0lURU1fQk9UVE9NV0lEVEgJCQkJCTEuMGYKI2RlZmluZSBQT1BVUF9JVEVNX1NJREVNQVJHSU4JCQkJCTMuMGYKI2RlZmluZSBQT1BVUF9JVEVNX1NQQUNFCQkJCQkJNC4wZgojZGVmaW5lIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQJCQkJCTIuMGYKI2RlZmluZSBQT1BVUF9JVEVNX0JPUkRFUkNPTE9SCQkJCQlDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIDgwLzI1NS4wZiwgODAvMjU1LjBmLCA4MC8yNTUuMGYpCgojZGVmaW5lIElzRmxvYXRaZXJvKGYpCQkJCQkJKChmKSA8IDAuMDAwMSAmJiAoZikgPiAtMC4wMDAxKQojZGVmaW5lIElzRmxvYXRCaWdnZXIoZmEsZmIpCQkJCSgoZmEpID4gKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQojZGVmaW5lIElzRmxvYXRTbWFsbGVyKGZhLGZiKQkJCQkoKGZhKSA8IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkKI2RlZmluZSBJc0Zsb2F0RXF1YWwoZmEsZmIpCQkJCQlJc0Zsb2F0WmVybygoZmEpLShmYikpCgoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfT3B0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpDUFdMX05vdGVfT3B0aW9uczo6Q1BXTF9Ob3RlX09wdGlvbnMoKSA6IG1fcFRleHQoTlVMTCkKewp9CgpDUFdMX05vdGVfT3B0aW9uczo6fkNQV0xfTm90ZV9PcHRpb25zKCkKewp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpTZXRUZXh0Q29sb3IoY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yKQp7CglDUFdMX1duZDo6U2V0VGV4dENvbG9yKGNvbG9yKTsKCglpZiAobV9wVGV4dCkKCQltX3BUZXh0LT5TZXRUZXh0Q29sb3IoY29sb3IpOwp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpSZVBvc0NoaWxkV25kKCkKewoJaWYgKHRoaXMtPklzVmFsaWQoKSkKCXsKCQlBU1NFUlQobV9wVGV4dCAhPSBOVUxMKTsKCgkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOwoKCQlpZiAocmNDbGllbnQuV2lkdGgoKSA+IDE1LjBmKQoJCXsKCQkJcmNDbGllbnQucmlnaHQgLT0gMTUuMGY7CgkJCW1fcFRleHQtPk1vdmUocmNDbGllbnQsIFRSVUUsIEZBTFNFKTsKCQkJbV9wVGV4dC0+U2V0VmlzaWJsZShUUlVFKTsKCQl9CgkJZWxzZQoJCXsKCQkJbV9wVGV4dC0+TW92ZShDUERGX1JlY3QoMCwwLDAsMCksIFRSVUUsIEZBTFNFKTsKCQkJbV9wVGV4dC0+U2V0VmlzaWJsZShGQUxTRSk7CgkJfQoJfQp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkKewoJbV9wVGV4dCA9IG5ldyBDUFdMX0xhYmVsOwoJUFdMX0NSRUFURVBBUkFNIHRjcCA9IGNwOwoJdGNwLnBQYXJlbnRXbmQgPSB0aGlzOwoJdGNwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRTsKCW1fcFRleHQtPkNyZWF0ZSh0Y3ApOwp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpTZXRUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGV4dCkKewoJbV9wVGV4dC0+U2V0VGV4dChzVGV4dCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlX09wdGlvbnM6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQp7CglDUFdMX1duZDo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSk7CgoJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOwoJcmNDbGllbnQubGVmdCA9IHJjQ2xpZW50LnJpZ2h0IC0gMTUuMGY7CgoJQ1BERl9Qb2ludCBwdENlbnRlciA9IENQREZfUG9pbnQoKHJjQ2xpZW50LmxlZnQgKyByY0NsaWVudC5yaWdodCkgKiAwLjVmLCAocmNDbGllbnQudG9wICsgcmNDbGllbnQuYm90dG9tKSAqIDAuNWYpOwoKCUNQREZfUG9pbnQgcHQxKHB0Q2VudGVyLnggLSAyLjBmLCBwdENlbnRlci55ICsgMi4wZiAqIDAuNWYpOwoJQ1BERl9Qb2ludCBwdDIocHRDZW50ZXIueCArIDIuMGYsIHB0Q2VudGVyLnkgKyAyLjBmICogMC41Zik7CglDUERGX1BvaW50IHB0MyhwdENlbnRlci54LCBwdENlbnRlci55IC0gMy4wZiAqIDAuNWYpOwoKCUNGWF9QYXRoRGF0YSBwYXRoOwoKCXBhdGguU2V0UG9pbnRDb3VudCg0KTsKCXBhdGguU2V0UG9pbnQoMCwgcHQxLngsIHB0MS55LCBGWFBUX01PVkVUTyk7CglwYXRoLlNldFBvaW50KDEsIHB0Mi54LCBwdDIueSwgRlhQVF9MSU5FVE8pOwoJcGF0aC5TZXRQb2ludCgyLCBwdDMueCwgcHQzLnksIEZYUFRfTElORVRPKTsKCXBhdGguU2V0UG9pbnQoMywgcHQxLngsIHB0MS55LCBGWFBUX0xJTkVUTyk7CgoJcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgTlVMTCwgCgkJQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksR2V0VHJhbnNwYXJlbmN5KCkpLCAKCQkwLCBGWEZJTExfQUxURVJOQVRFKTsKfQoKQ1BERl9SZWN0IENQV0xfTm90ZV9PcHRpb25zOjpHZXRDb250ZW50UmVjdCgpIGNvbnN0CnsKCUFTU0VSVChtX3BUZXh0ICE9IE5VTEwpOwoKCUNQREZfUmVjdCByY1RleHQgPSBtX3BUZXh0LT5HZXRDb250ZW50UmVjdCgpOwoJcmNUZXh0LnJpZ2h0ICs9IDE1LjBmOwoJcmV0dXJuIHJjVGV4dDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfRWRpdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCkNQV0xfTm90ZV9FZGl0OjpDUFdMX05vdGVfRWRpdCgpIDogbV9iRW5hYmxlTm90aWZ5KFRSVUUpLAoJbV9mT2xkSXRlbUhlaWdodCgwLjBmKSwKCW1fYlNpemVDaGFuZ2VkKEZBTFNFKSwKCW1fZk9sZE1pbigwLjBmKSwKCW1fZk9sZE1heCgwLjBmKQp7Cn0KCkNQV0xfTm90ZV9FZGl0Ojp+Q1BXTF9Ob3RlX0VkaXQoKQp7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0VkaXQ6OlJlUG9zQ2hpbGRXbmQoKQp7CgltX2JFbmFibGVOb3RpZnkgPSBGQUxTRTsJCglDUFdMX0VkaXQ6OlJlUG9zQ2hpbGRXbmQoKTsKCW1fYkVuYWJsZU5vdGlmeSA9IFRSVUU7CgoJbV9mT2xkSXRlbUhlaWdodCA9IHRoaXMtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0VkaXQ6OlNldFRleHQoRlhfTFBDV1NUUiBjc1RleHQpCnsKCW1fYkVuYWJsZU5vdGlmeSA9IEZBTFNFOwoJQ1BXTF9FZGl0OjpTZXRUZXh0KGNzVGV4dCk7CgltX2JFbmFibGVOb3RpZnkgPSBUUlVFOwkKCW1fZk9sZEl0ZW1IZWlnaHQgPSB0aGlzLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwp9Cgp2b2lkIENQV0xfTm90ZV9FZGl0OjpPblNldEZvY3VzKCkKewoJbV9iRW5hYmxlTm90aWZ5ID0gRkFMU0U7CQoJQ1BXTF9FZGl0OjpPblNldEZvY3VzKCk7CgltX2JFbmFibGVOb3RpZnkgPSBUUlVFOwkKCgl0aGlzLT5FbmFibGVTcGVsbENoZWNrKFRSVUUpOwp9Cgp2b2lkIENQV0xfTm90ZV9FZGl0OjpPbktpbGxGb2N1cygpCnsKCXRoaXMtPkVuYWJsZVNwZWxsQ2hlY2soRkFMU0UpOwoKCWlmIChDUFdMX1duZCogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQoJewoJCWlmIChDUFdMX1duZCogcEdyYW5kID0gcFBhcmVudC0+R2V0UGFyZW50V2luZG93KCkpCgkJewoJCQlBU1NFUlQocEdyYW5kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwoKCQkJQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBHcmFuZDsKCgkJCXBOb3RlSXRlbS0+T25Db250ZW50c1ZhbGlkYXRlKCk7CgkJfQoJfQoKCUNQV0xfRWRpdDo6T25LaWxsRm9jdXMoKTsKfQoKdm9pZCBDUFdMX05vdGVfRWRpdDo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSwgRlhfSU5UUFRSIGxQYXJhbSkKewoJaWYgKG1fYkVuYWJsZU5vdGlmeSkKCXsKCQlpZiAod1BhcmFtID09IFNCVF9WU0NST0xMKQoJCXsKCQkJc3dpdGNoIChtc2cpCgkJCXsKCQkJY2FzZSBQTk1fU0VUU0NST0xMSU5GTzoJCgkJCQlpZiAoUFdMX1NDUk9MTF9JTkZPKiBwSW5mbyA9IChQV0xfU0NST0xMX0lORk8qKWxQYXJhbSkKCQkJCXsJCgkJCQkJaWYgKCFJc0Zsb2F0RXF1YWwocEluZm8tPmZDb250ZW50TWF4LCBtX2ZPbGRNYXgpIHx8IAoJCQkJCQkhSXNGbG9hdEVxdWFsKHBJbmZvLT5mQ29udGVudE1pbiwgbV9mT2xkTWluKSkKCQkJCQl7CgkJCQkJCW1fYlNpemVDaGFuZ2VkID0gVFJVRTsJCQkJCgkJCQkJCWlmIChDUFdMX1duZCAqIHBQYXJlbnQgPSB0aGlzLT5HZXRQYXJlbnRXaW5kb3coKSkKCQkJCQkJewoJCQkJCQkJcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7CgkJCQkJCX0KCgkJCQkJCW1fZk9sZE1heCA9IHBJbmZvLT5mQ29udGVudE1heDsKCQkJCQkJbV9mT2xkTWluID0gcEluZm8tPmZDb250ZW50TWluOwoJCQkJCQlyZXR1cm47CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQkJCgl9CgoJQ1BXTF9FZGl0OjpPbk5vdGlmeShwV25kLCBtc2csIHdQYXJhbSwgbFBhcmFtKTsKCglpZiAobV9iRW5hYmxlTm90aWZ5KQoJewoJCXN3aXRjaCAobXNnKQoJCXsKCQljYXNlIFBOTV9TRVRDQVJFVElORk86CgkJCWlmIChQV0xfQ0FSRVRfSU5GTyAqIHBJbmZvID0gKFBXTF9DQVJFVF9JTkZPKil3UGFyYW0pCgkJCXsKCQkJCVBXTF9DQVJFVF9JTkZPIG5ld0luZm8gPSAqcEluZm87CgkJCQluZXdJbmZvLmJWaXNpYmxlID0gVFJVRTsKCQkJCW5ld0luZm8ucHRIZWFkID0gdGhpcy0+Q2hpbGRUb1BhcmVudChwSW5mby0+cHRIZWFkKTsKCQkJCW5ld0luZm8ucHRGb290ID0gdGhpcy0+Q2hpbGRUb1BhcmVudChwSW5mby0+cHRGb290KTsKCgkJCQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpCgkJCQl7CgkJCQkJcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX1NFVENBUkVUSU5GTywgKEZYX0lOVFBUUikmbmV3SW5mbywgMCk7CgkJCQl9CgkJCX0KCQkJYnJlYWs7CgkJfQoJfQp9CgpGWF9GTE9BVCBDUFdMX05vdGVfRWRpdDo6R2V0SXRlbUhlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCkKewoJaWYgKGZMaW1pdFdpZHRoID4gMCkKCXsKCQlpZiAoIW1fYlNpemVDaGFuZ2VkKQoJCQlyZXR1cm4gbV9mT2xkSXRlbUhlaWdodDsKCgkJbV9iU2l6ZUNoYW5nZWQgPSBGQUxTRTsJCgoJCXRoaXMtPkVuYWJsZU5vdGlmeShGQUxTRSk7CgkJdGhpcy0+RW5hYmxlUmVmcmVzaChGQUxTRSk7CgkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsKCgkJLy9DUERGX1JlY3QgcmNPbGQgPSB0aGlzLT5HZXRXaW5kb3dSZWN0KCk7CgoJCXRoaXMtPk1vdmUoQ1BERl9SZWN0KDAsMCxmTGltaXRXaWR0aCwwKSwgVFJVRSwgRkFMU0UpOwoJCUZYX0ZMT0FUIGZSZXQgPSB0aGlzLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwoKCQkvL3RoaXMtPk1vdmUocmNPbGQsIFRSVUUsIEZBTFNFKTsKCgkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOwoJCXRoaXMtPkVuYWJsZU5vdGlmeShUUlVFKTsKCQl0aGlzLT5FbmFibGVSZWZyZXNoKFRSVUUpOwoKCQlyZXR1cm4gZlJldDsKCX0KCglyZXR1cm4gMDsKfQoKRlhfRkxPQVQgQ1BXTF9Ob3RlX0VkaXQ6OkdldEl0ZW1MZWZ0TWFyZ2luKCkKewoJcmV0dXJuIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZV9FZGl0OjpHZXRJdGVtUmlnaHRNYXJnaW4oKQp7CglyZXR1cm4gUE9QVVBfSVRFTV9URVhUX0lOREVOVDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX0xCQm94IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCkNQV0xfTm90ZV9MQkJveDo6Q1BXTF9Ob3RlX0xCQm94KCkKewp9CgpDUFdMX05vdGVfTEJCb3g6On5DUFdMX05vdGVfTEJCb3goKQp7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0xCQm94OjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkKewoJQ1BERl9SZWN0IHJjQ2xpZW50ID0gdGhpcy0+R2V0Q2xpZW50UmVjdCgpOwoKCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7Cglnc2QubV9MaW5lV2lkdGggPSAxLjBmOwoKCUNGWF9QYXRoRGF0YSBwYXRoQ3Jvc3M7CgoJcGF0aENyb3NzLlNldFBvaW50Q291bnQoNCk7CglwYXRoQ3Jvc3MuU2V0UG9pbnQoMCwgcmNDbGllbnQubGVmdCwgcmNDbGllbnQudG9wLCBGWFBUX01PVkVUTyk7CglwYXRoQ3Jvc3MuU2V0UG9pbnQoMSwgcmNDbGllbnQucmlnaHQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOwoJcGF0aENyb3NzLlNldFBvaW50KDIsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LmJvdHRvbSArIHJjQ2xpZW50LkhlaWdodCgpICogMC41ZiwgRlhQVF9NT1ZFVE8pOwoJcGF0aENyb3NzLlNldFBvaW50KDMsIHJjQ2xpZW50LmxlZnQgKyByY0NsaWVudC5XaWR0aCgpICogMC41ZiwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7CgkKCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoQ3Jvc3MsIHBVc2VyMkRldmljZSwgJmdzZCwgCgkJMCwgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpLCBGWEZJTExfQUxURVJOQVRFKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX1JCQm94IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCkNQV0xfTm90ZV9SQkJveDo6Q1BXTF9Ob3RlX1JCQm94KCkKewp9CgpDUFdMX05vdGVfUkJCb3g6On5DUFdMX05vdGVfUkJCb3goKQp7Cn0KCnZvaWQgQ1BXTF9Ob3RlX1JCQm94OjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkKewoJQ1BERl9SZWN0IHJjQ2xpZW50ID0gdGhpcy0+R2V0Q2xpZW50UmVjdCgpOwoKCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7Cglnc2QubV9MaW5lV2lkdGggPSAxLjBmOwoKCUNGWF9QYXRoRGF0YSBwYXRoQ3Jvc3M7CgoJcGF0aENyb3NzLlNldFBvaW50Q291bnQoNCk7CglwYXRoQ3Jvc3MuU2V0UG9pbnQoMCwgcmNDbGllbnQucmlnaHQsIHJjQ2xpZW50LnRvcCwgRlhQVF9NT1ZFVE8pOwoJcGF0aENyb3NzLlNldFBvaW50KDEsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOwoJcGF0aENyb3NzLlNldFBvaW50KDIsIHJjQ2xpZW50LnJpZ2h0LCByY0NsaWVudC5ib3R0b20gKyByY0NsaWVudC5IZWlnaHQoKSAqIDAuNWYsIEZYUFRfTU9WRVRPKTsKCXBhdGhDcm9zcy5TZXRQb2ludCgzLCByY0NsaWVudC5sZWZ0ICsgcmNDbGllbnQuV2lkdGgoKSAqIDAuNWYsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOwoJCglwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aENyb3NzLCBwVXNlcjJEZXZpY2UsICZnc2QsIAoJCTAsIENQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpLHRoaXMtPkdldFRyYW5zcGFyZW5jeSgpKSwgRlhGSUxMX0FMVEVSTkFURSk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfSWNvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpDUFdMX05vdGVfSWNvbjo6Q1BXTF9Ob3RlX0ljb24oKSA6IG1fblR5cGUoMCkKewp9CgpDUFdMX05vdGVfSWNvbjo6fkNQV0xfTm90ZV9JY29uKCkKewp9Cgp2b2lkIENQV0xfTm90ZV9JY29uOjpTZXRJY29uVHlwZShGWF9JTlQzMiBuVHlwZSkKewoJbV9uVHlwZSA9IG5UeXBlOwp9Cgp2b2lkIENQV0xfTm90ZV9JY29uOjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkKewoJQ1BXTF9VdGlsczo6RHJhd0ljb25BcHBTdHJlYW0ocERldmljZSwgcFVzZXIyRGV2aWNlLCBtX25UeXBlLCBHZXRDbGllbnRSZWN0KCksIAoJCXRoaXMtPkdldEJhY2tncm91bmRDb2xvcigpLCBQV0xfREVGQVVMVF9CTEFDS0NPTE9SLCB0aGlzLT5HZXRUcmFuc3BhcmVuY3koKSk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfQ2xvc2VCb3ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ1BXTF9Ob3RlX0Nsb3NlQm94OjpDUFdMX05vdGVfQ2xvc2VCb3goKSA6IG1fYk1vdXNlRG93bihGQUxTRSkKewp9CgpDUFdMX05vdGVfQ2xvc2VCb3g6On5DUFdMX05vdGVfQ2xvc2VCb3goKQp7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0Nsb3NlQm94OjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkKewoJQ1BXTF9CdXR0b246OkRyYXdUaGlzQXBwZWFyYW5jZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UpOwoKCUNQREZfUmVjdCByY0NsaWVudCA9IHRoaXMtPkdldENsaWVudFJlY3QoKTsKCXJjQ2xpZW50ID0gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmNDbGllbnQsIDIuMGYpOwoKCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7Cglnc2QubV9MaW5lV2lkdGggPSAxLjBmOwoKCUNGWF9QYXRoRGF0YSBwYXRoQ3Jvc3M7CgoJaWYgKG1fYk1vdXNlRG93bikKCXsKCQlyY0NsaWVudC5sZWZ0ICs9IDAuNWY7CgkJcmNDbGllbnQucmlnaHQgKz0gMC41ZjsKCQlyY0NsaWVudC50b3AgLT0gMC41ZjsKCQlyY0NsaWVudC5ib3R0b20gLT0gMC41ZjsKCX0KCglwYXRoQ3Jvc3MuU2V0UG9pbnRDb3VudCg0KTsKCXBhdGhDcm9zcy5TZXRQb2ludCgwLCByY0NsaWVudC5sZWZ0LCByY0NsaWVudC5ib3R0b20sIEZYUFRfTU9WRVRPKTsKCXBhdGhDcm9zcy5TZXRQb2ludCgxLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQudG9wLCBGWFBUX0xJTkVUTyk7CglwYXRoQ3Jvc3MuU2V0UG9pbnQoMiwgcmNDbGllbnQubGVmdCwgcmNDbGllbnQudG9wLCBGWFBUX01PVkVUTyk7CglwYXRoQ3Jvc3MuU2V0UG9pbnQoMywgcmNDbGllbnQucmlnaHQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOwoJCglwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aENyb3NzLCBwVXNlcjJEZXZpY2UsICZnc2QsIAoJCTAsIENQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpLHRoaXMtPkdldFRyYW5zcGFyZW5jeSgpKSwgRlhGSUxMX0FMVEVSTkFURSk7Cn0KCkZYX0JPT0wgQ1BXTF9Ob3RlX0Nsb3NlQm94OjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCnsKCVNldEJvcmRlclN0eWxlKFBCU19JTlNFVCk7CglJbnZhbGlkYXRlUmVjdChOVUxMKTsKCgltX2JNb3VzZURvd24gPSBUUlVFOwoKCXJldHVybiBDUFdMX0J1dHRvbjo6T25MQnV0dG9uRG93bihwb2ludCxuRmxhZyk7Cn0KCkZYX0JPT0wJQ1BXTF9Ob3RlX0Nsb3NlQm94OjpPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQp7CgltX2JNb3VzZURvd24gPSBGQUxTRTsKCglTZXRCb3JkZXJTdHlsZShQQlNfQkVWRUxFRCk7CglJbnZhbGlkYXRlUmVjdChOVUxMKTsKCglyZXR1cm4gQ1BXTF9CdXR0b246Ok9uTEJ1dHRvblVwKHBvaW50LG5GbGFnKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9Db250ZW50cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpDUFdMX05vdGVfQ29udGVudHM6OkNQV0xfTm90ZV9Db250ZW50cygpIDogbV9wRWRpdChOVUxMKQp7Cn0KCkNQV0xfTm90ZV9Db250ZW50czo6fkNQV0xfTm90ZV9Db250ZW50cygpCnsKfQoKQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRDbGFzc05hbWUoKSBjb25zdAp7CglyZXR1cm4gIkNQV0xfTm90ZV9Db250ZW50cyI7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkKewoJbV9wRWRpdCA9IG5ldyBDUFdMX05vdGVfRWRpdDsKCVBXTF9DUkVBVEVQQVJBTSBlY3AgPSBjcDsKCWVjcC5wUGFyZW50V25kID0gdGhpczsKCWVjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfTVVMVElMSU5FIHwgUEVTX0FVVE9SRVRVUk4gfCBQRVNfVEVYVE9WRVJGTE9XIHwgUEVTX1VORE8gfCBQRVNfU1BFTExDSEVDSzsKCgltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwoJbV9wRWRpdC0+Q3JlYXRlKGVjcCk7CgltX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpTZXRUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGV4dCkKewoJaWYgKG1fcEVkaXQpCgl7CgkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsKCQltX3BFZGl0LT5TZXRUZXh0KHNUZXh0KTsKCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7CgkJT25Ob3RpZnkobV9wRWRpdCwgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7CQkKCX0KfQoKQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRUZXh0KCkgY29uc3QKewoJaWYgKG1fcEVkaXQpCgkJcmV0dXJuIG1fcEVkaXQtPkdldFRleHQoKTsKCglyZXR1cm4gTCIiOwp9CgpDUFdMX05vdGVJdGVtKiBDUFdMX05vdGVfQ29udGVudHM6OkNyZWF0ZVN1Ykl0ZW0oKQp7CglDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSBuZXcgQ1BXTF9Ob3RlSXRlbTsKCVBXTF9DUkVBVEVQQVJBTSBpY3AgPSB0aGlzLT5HZXRDcmVhdGlvblBhcmFtKCk7CglpY3AucFBhcmVudFduZCA9IHRoaXM7CglpY3AuZHdGbGFncyA9ICBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRSB8IFBXU19CQUNLR1JPVU5EOwoJcE5vdGVJdGVtLT5DcmVhdGUoaWNwKTsKCglwTm90ZUl0ZW0tPk9uQ3JlYXRlTm90ZUl0ZW0oKTsKCQoJcE5vdGVJdGVtLT5SZXNldFN1YmplY3ROYW1lKG1fYUNoaWxkcmVuLkdldFNpemUoKSAtIDEpOwoKCUZYX1NZU1RFTVRJTUUgc3Q7CglpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IHRoaXMtPkdldFN5c3RlbUhhbmRsZXIoKSkKCQlzdCA9IHBTSC0+R2V0TG9jYWxUaW1lKCk7CglwTm90ZUl0ZW0tPlNldERhdGVUaW1lKHN0KTsKCglwTm90ZUl0ZW0tPlNldENvbnRlbnRzKEwiIik7CgoJdGhpcy0+T25Ob3RpZnkocE5vdGVJdGVtLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsJCgoJcmV0dXJuIHBOb3RlSXRlbTsKfQoKRlhfSU5UMzIgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpDb3VudFN1Ykl0ZW1zKCkgY29uc3QKewoJcmV0dXJuIG1fYUNoaWxkcmVuLkdldFNpemUoKSAtIDE7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZV9Db250ZW50czo6R2V0U3ViSXRlbXMoRlhfSU5UMzIgaW5kZXgpIGNvbnN0CnsKCUZYX0lOVDMyIG5JbmRleCA9IGluZGV4ICsgMTsKCglpZiAobkluZGV4ID4gMCAmJiBuSW5kZXggPCBtX2FDaGlsZHJlbi5HZXRTaXplKCkpCgkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChuSW5kZXgpKQoJCXsKCQkJQVNTRVJUKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKCQkJQ1BXTF9Ob3RlSXRlbSogcEl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcENoaWxkOwoJCQlyZXR1cm4gcEl0ZW07CgkJfQoJcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpEZWxldGVTdWJJdGVtKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSkKewoJRlhfSU5UMzIgbkluZGV4ID0gdGhpcy0+R2V0SXRlbUluZGV4KChDUFdMX05vdGVJdGVtKilwTm90ZUl0ZW0pOwoKCWlmIChuSW5kZXggPiAwKQoJewoJCWlmIChDUFdMX05vdGVJdGVtKiBwUFdMTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcE5vdGVJdGVtKQoJCXsKCQkJcFBXTE5vdGVJdGVtLT5LaWxsRm9jdXMoKTsKCQkJcFBXTE5vdGVJdGVtLT5EZXN0cm95KCk7CgkJCWRlbGV0ZSBwUFdMTm90ZUl0ZW07CgkJfQoKCQlmb3IgKEZYX0lOVDMyIGk9bkluZGV4LHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQoJCXsKCQkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKCQkJewoJCQkJQVNTRVJUKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKCQkJCUNQV0xfTm90ZUl0ZW0qIHBJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsKCQkJCXBJdGVtLT5SZXNldFN1YmplY3ROYW1lKGkpOwoJCQl9CgkJfQoKCQl0aGlzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKCX0KfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRIaXROb3RlSXRlbShjb25zdCBDUERGX1BvaW50JiBwb2ludCkKewoJQ1BERl9Qb2ludCBwdCA9IHRoaXMtPlBhcmVudFRvQ2hpbGQocG9pbnQpOwoKCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQoJewoJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpCgkJewoJCQlpZiAocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpCgkJCXsKCQkJCUNQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwQ2hpbGQ7CgkJCQlpZiAoSVBXTF9Ob3RlSXRlbSogcFJldCA9IHBOb3RlSXRlbS0+R2V0SGl0Tm90ZUl0ZW0ocHQpKQoJCQkJCXJldHVybiBwUmV0OwoJCQl9CgkJfQoJfQoJcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtLCBGWF9JTlRQVFIgbFBhcmFtKQp7Cglzd2l0Y2ggKG1zZykKCXsKCWNhc2UgUE5NX05PVEVFRElUQ0hBTkdFRDoKCQl7CgkJCUZYX0lOVDMyIG5JbmRleCA9IHRoaXMtPkdldEl0ZW1JbmRleChwV25kKTsKCQkJaWYgKG5JbmRleCA8IDApIG5JbmRleCA9IDA7CgoJCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwkKCQkJdGhpcy0+UmVzZXRDb250ZW50KG5JbmRleCk7CgkJCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsKCgkJCWZvciAoRlhfSU5UMzIgaT1uSW5kZXgrMSwgc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspCgkJCXsKCQkJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpCgkJCQkJcENoaWxkLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKCQkJfQoKCQkJaWYgKENQV0xfV25kICogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQoJCQl7CgkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKCQkJfQoJCX0KCQlyZXR1cm47CgljYXNlIFBOTV9TQ1JPTExXSU5ET1c6CgkJdGhpcy0+U2V0U2Nyb2xsUG9zKENQREZfUG9pbnQoMC4wZiwgKihGWF9GTE9BVCopbFBhcmFtKSk7CgkJdGhpcy0+UmVzZXRGYWNlKCk7CgkJSW52YWxpZGF0ZVJlY3QoTlVMTCk7CgkJcmV0dXJuOwkJCgljYXNlIFBOTV9TRVRDQVJFVElORk86CgkJaWYgKFBXTF9DQVJFVF9JTkZPICogcEluZm8gPSAoUFdMX0NBUkVUX0lORk8qKXdQYXJhbSkKCQl7CgkJCVBXTF9DQVJFVF9JTkZPIG5ld0luZm8gPSAqcEluZm87CgkJCW5ld0luZm8uYlZpc2libGUgPSBUUlVFOwoJCQluZXdJbmZvLnB0SGVhZCA9IHRoaXMtPkNoaWxkVG9QYXJlbnQocEluZm8tPnB0SGVhZCk7CgkJCW5ld0luZm8ucHRGb290ID0gdGhpcy0+Q2hpbGRUb1BhcmVudChwSW5mby0+cHRGb290KTsKCgkJCWlmIChDUFdMX1duZCAqIHBQYXJlbnQgPSB0aGlzLT5HZXRQYXJlbnRXaW5kb3coKSkKCQkJewoJCQkJcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX1NFVENBUkVUSU5GTywgKEZYX0lOVFBUUikmbmV3SW5mbywgMCk7CgkJCX0KCQl9CgkJcmV0dXJuOwoJY2FzZSBQTk1fTk9URVJFU0VUOgoJCXsKCQkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsJCgkJCXRoaXMtPlJlc2V0Q29udGVudCgwKTsKCQkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOwoKCQkJZm9yIChGWF9JTlQzMiBpPTEsIHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQoJCQl7CgkJCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQoJCQkJCXBDaGlsZC0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CgkJCX0JCgoJCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwkKCQkJdGhpcy0+UmVzZXRDb250ZW50KDApOwoJCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7CgkJfQoJCXJldHVybjsKCX0KCglDUFdMX1duZDo6T25Ob3RpZnkocFduZCwgbXNnLCB3UGFyYW0sIGxQYXJhbSk7Cn0KCkZYX0JPT0wJQ1BXTF9Ob3RlX0NvbnRlbnRzOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCnsKCWlmIChDUFdMX1duZDo6T25MQnV0dG9uRG93bihwb2ludCxuRmxhZykpIHJldHVybiBUUlVFOwoKCWlmICghbV9wRWRpdC0+SXNGb2N1c2VkKCkpCgl7CgkJbV9wRWRpdC0+U2V0Rm9jdXMoKTsKCX0KCglyZXR1cm4gVFJVRTsKfQoKdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OlNldEVkaXRGb2N1cyhGWF9CT09MIGJMYXN0KQp7CglpZiAoIW1fcEVkaXQtPklzRm9jdXNlZCgpKQoJewoJCW1fcEVkaXQtPlNldEZvY3VzKCk7CgkJbV9wRWRpdC0+U2V0Q2FyZXQoYkxhc3QgPyBtX3BFZGl0LT5HZXRUb3RhbFdvcmRzKCkgOiAwKTsKCX0KfQoKQ1BXTF9FZGl0KiBDUFdMX05vdGVfQ29udGVudHM6OkdldEVkaXQoKSBjb25zdAp7CglyZXR1cm4gbV9wRWRpdDsKfQoKdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OkVuYWJsZU1vZGlmeShGWF9CT09MIGJFbmFibGVkKQp7CglpZiAoIWJFbmFibGVkKQoJCW1fcEVkaXQtPkFkZEZsYWcoUFdTX1JFQURPTkxZKTsKCWVsc2UKCQltX3BFZGl0LT5SZW1vdmVGbGFnKFBXU19SRUFET05MWSk7CgoJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspCgl7CgkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKCQl7CgkJCWlmIChwQ2hpbGQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIikKCQkJewoJCQkJQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsKCQkJCXBOb3RlSXRlbS0+RW5hYmxlTW9kaWZ5KGJFbmFibGVkKTsKCQkJfQoJCX0KCX0KfQoKdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OkVuYWJsZVJlYWQoRlhfQk9PTCBiRW5hYmxlZCkKewoJaWYgKCFiRW5hYmxlZCkKCQltX3BFZGl0LT5BZGRGbGFnKFBFU19OT1JFQUQpOwoJZWxzZQoJCW1fcEVkaXQtPlJlbW92ZUZsYWcoUEVTX05PUkVBRCk7CgoJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspCgl7CgkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKCQl7CgkJCWlmIChwQ2hpbGQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIikKCQkJewoJCQkJQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsKCQkJCXBOb3RlSXRlbS0+RW5hYmxlUmVhZChiRW5hYmxlZCk7CgkJCX0KCQl9Cgl9Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlSXRlbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpDUFdMX05vdGVJdGVtOjpDUFdMX05vdGVJdGVtKCkgOgoJbV9wU3ViamVjdChOVUxMKSwKCW1fcERhdGVUaW1lKE5VTEwpLAoJbV9wQ29udGVudHMoTlVMTCksCgltX3BQcml2YXRlRGF0YShOVUxMKSwKCW1fc0F1dGhvcihMIiIpLAoJbV9mT2xkSXRlbUhlaWdodCgwLjBmKSwKCW1fYlNpemVDaGFuZ2VkKEZBTFNFKSwKCW1fYkFsbG93TW9kaWZ5KFRSVUUpCnsKfQoKQ1BXTF9Ob3RlSXRlbTo6fkNQV0xfTm90ZUl0ZW0oKQp7Cn0KCkNGWF9CeXRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldENsYXNzTmFtZSgpIGNvbnN0CnsKCXJldHVybiAiQ1BXTF9Ob3RlSXRlbSI7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCnsKCUNQV0xfQ29sb3Igc1RleHRDb2xvcjsKCglpZiAoQ1BXTF9VdGlsczo6SXNCbGFja09yV2hpdGUodGhpcy0+R2V0QmFja2dyb3VuZENvbG9yKCkpKQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9XSElURUNPTE9SOwoJZWxzZQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9CTEFDS0NPTE9SOwoKCW1fcFN1YmplY3QgPSBuZXcgQ1BXTF9MYWJlbDsKCVBXTF9DUkVBVEVQQVJBTSBzY3AgPSBjcDsKCXNjcC5wUGFyZW50V25kID0gdGhpczsKCXNjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfTEVGVCB8IFBFU19UT1A7CglzY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CgltX3BTdWJqZWN0LT5DcmVhdGUoc2NwKTsKCgltX3BEYXRlVGltZSA9IG5ldyBDUFdMX0xhYmVsOwoJUFdMX0NSRUFURVBBUkFNIGRjcCA9IGNwOwoJZGNwLnBQYXJlbnRXbmQgPSB0aGlzOwoJZGNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBFU19SSUdIVCB8IFBFU19UT1A7CglkY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CgltX3BEYXRlVGltZS0+Q3JlYXRlKGRjcCk7CgoJbV9wQ29udGVudHMgPSBuZXcgQ1BXTF9Ob3RlX0NvbnRlbnRzOwoJUFdMX0NSRUFURVBBUkFNIGNjcCA9IGNwOwoJY2NwLnBQYXJlbnRXbmQgPSB0aGlzOwoJLy9jY3Auc0JhY2tncm91bmRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CgljY3Auc0JhY2tncm91bmRDb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZik7CgljY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUFdTX0JBQ0tHUk9VTkQ7CgltX3BDb250ZW50cy0+Q3JlYXRlKGNjcCk7CgltX3BDb250ZW50cy0+U2V0SXRlbVNwYWNlKFBPUFVQX0lURU1fU1BBQ0UpOwoJbV9wQ29udGVudHMtPlNldFRvcFNwYWNlKFBPUFVQX0lURU1fU1BBQ0UpOwoJbV9wQ29udGVudHMtPlNldEJvdHRvbVNwYWNlKFBPUFVQX0lURU1fU1BBQ0UpOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlJlUG9zQ2hpbGRXbmQoKQp7CglpZiAodGhpcy0+SXNWYWxpZCgpKQoJewoJCUFTU0VSVChtX3BTdWJqZWN0ICE9IE5VTEwpOwoJCUFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsKCQlBU1NFUlQobV9wQ29udGVudHMgIT0gTlVMTCk7CgoJCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKCgkJQ1BERl9SZWN0IHJjU3ViamVjdCA9IHJjQ2xpZW50OwoJCXJjU3ViamVjdC5sZWZ0ICs9IFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7CgkJcmNTdWJqZWN0LnRvcCA9IHJjQ2xpZW50LnRvcDsKCQlyY1N1YmplY3QucmlnaHQgPSBQV0xfTUlOKHJjU3ViamVjdC5sZWZ0ICsgbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpICsgMS4wZiwgcmNDbGllbnQucmlnaHQpOwoJCXJjU3ViamVjdC5ib3R0b20gPSByY1N1YmplY3QudG9wIC0gbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKCQlyY1N1YmplY3QuTm9ybWFsaXplKCk7CgkJbV9wU3ViamVjdC0+TW92ZShyY1N1YmplY3QsIFRSVUUsIEZBTFNFKTsKCQltX3BTdWJqZWN0LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNTdWJqZWN0KSk7CgoJCUNQREZfUmVjdCByY0RhdGUgPSByY0NsaWVudDsKCQlyY0RhdGUucmlnaHQgLT0gUE9QVVBfSVRFTV9URVhUX0lOREVOVDsKCQlyY0RhdGUubGVmdCA9IFBXTF9NQVgocmNEYXRlLnJpZ2h0IC0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSAtIDEuMGYsIHJjU3ViamVjdC5yaWdodCk7CgkJcmNEYXRlLmJvdHRvbSA9IHJjRGF0ZS50b3AgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKCQlyY0RhdGUuTm9ybWFsaXplKCk7CgkJbV9wRGF0ZVRpbWUtPk1vdmUocmNEYXRlLCBUUlVFLCBGQUxTRSk7CgkJbV9wRGF0ZVRpbWUtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0RhdGUpKTsKCgkJQ1BERl9SZWN0IHJjQ29udGVudHMgPSByY0NsaWVudDsKCQlyY0NvbnRlbnRzLmxlZnQgKz0gMS4wZjsKCQlyY0NvbnRlbnRzLnJpZ2h0IC09IDEuMGY7CgkJcmNDb250ZW50cy50b3AgPSByY0RhdGUuYm90dG9tIC0gUE9QVVBfSVRFTV9IRUFEX0JPVFRPTTsKCQlyY0NvbnRlbnRzLmJvdHRvbSArPSBQT1BVUF9JVEVNX0JPVFRPTVdJRFRIOwoJCXJjQ29udGVudHMuTm9ybWFsaXplKCk7CgkJbV9wQ29udGVudHMtPk1vdmUocmNDb250ZW50cywgVFJVRSwgRkFMU0UpOwoJCW1fcENvbnRlbnRzLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNDb250ZW50cykpOwoJfQoKCVNldENsaXBSZWN0KENQV0xfVXRpbHM6OkluZmxhdGVSZWN0KEdldFdpbmRvd1JlY3QoKSwxLjBmKSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0UHJpdmF0ZURhdGEodm9pZCogcERhdGEpCnsKCW1fcFByaXZhdGVEYXRhID0gcERhdGE7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0QmtDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcikKewoJQ1BXTF9Db2xvciBzQksgPSBjb2xvcjsKCXRoaXMtPlNldEJhY2tncm91bmRDb2xvcihzQkspOwoKCUNQV0xfQ29sb3Igc1RleHRDb2xvcjsKCglpZiAoQ1BXTF9VdGlsczo6SXNCbGFja09yV2hpdGUoc0JLKSkKCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsKCWVsc2UKCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUjsKCgl0aGlzLT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CglpZiAobV9wU3ViamVjdCkKCQltX3BTdWJqZWN0LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CglpZiAobV9wRGF0ZVRpbWUpCgkJbV9wRGF0ZVRpbWUtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKCgl0aGlzLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKCglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQoJewoJCXBOb3RpZnktPk9uU2V0QmtDb2xvcih0aGlzKTsKCX0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRTdWJqZWN0TmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpCnsKCWlmIChtX3BTdWJqZWN0KQoJewoJCW1fcFN1YmplY3QtPlNldFRleHQoc05hbWUpOwkKCX0KCglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQoJewoJCXBOb3RpZnktPk9uU2V0U3ViamVjdE5hbWUodGhpcyk7Cgl9Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0QXV0aG9yTmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpCnsKCW1fc0F1dGhvciA9IHNOYW1lOwoJUmVzZXRTdWJqZWN0TmFtZSgtMSk7CQoKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25TZXRBdXRob3JOYW1lKHRoaXMpOwoJfQp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlJlc2V0U3ViamVjdE5hbWUoRlhfSU5UMzIgbkl0ZW1JbmRleCkKewoJaWYgKG5JdGVtSW5kZXggPCAwKQoJewoJCWlmIChDUFdMX1duZCogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQoJCXsKCQkJQVNTRVJUKHBQYXJlbnQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVfQ29udGVudHMiKTsKCgkJCUNQV0xfTm90ZV9Db250ZW50cyogcENvbnRlbnRzID0gKENQV0xfTm90ZV9Db250ZW50cyopcFBhcmVudDsKCQkJbkl0ZW1JbmRleCA9IHBDb250ZW50cy0+R2V0SXRlbUluZGV4KHRoaXMpOwoJCX0KCX0KCgljb25zdCBDUFdMX05vdGUqIHBOb3RlID0gR2V0Tm90ZSgpOwoJQVNTRVJUKHBOb3RlICE9IE5VTEwpOwoKCUNGWF9XaWRlU3RyaW5nIHNTdWJqZWN0OwoJc1N1YmplY3QuRm9ybWF0KHBOb3RlLT5HZXRSZXBseVN0cmluZygpLCBuSXRlbUluZGV4KTsKCglpZiAoIW1fc0F1dGhvci5Jc0VtcHR5KCkpCgl7CgkJCgkJc1N1YmplY3QgKz0gTCIgLSAiOwoJCXNTdWJqZWN0ICs9IG1fc0F1dGhvcjsKCX0KCXRoaXMtPlNldFN1YmplY3ROYW1lKHNTdWJqZWN0KTsKCXRoaXMtPlJlUG9zQ2hpbGRXbmQoKTsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXREYXRlVGltZShGWF9TWVNURU1USU1FIHRpbWUpCnsKCW1fZHROb3RlID0gdGltZTsKCQoJQ0ZYX1dpZGVTdHJpbmcgc3dUaW1lOwoJc3dUaW1lLkZvcm1hdChMIiUwNGQtJTAyZC0lMDJkICUwMmQ6JTAyZDolMDJkIiwgdGltZS53WWVhciwgdGltZS53TW9udGgsIHRpbWUud0RheSwgdGltZS53SG91ciwgdGltZS53TWludXRlLCB0aW1lLndTZWNvbmQpOwoJaWYgKG1fcERhdGVUaW1lKQoJewoJCW1fcERhdGVUaW1lLT5TZXRUZXh0KHN3VGltZSk7Cgl9CgoJdGhpcy0+UmVQb3NDaGlsZFduZCgpOwoKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25TZXREYXRlVGltZSh0aGlzKTsKCX0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRDb250ZW50cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc0NvbnRlbnRzKQp7CglpZiAobV9wQ29udGVudHMpCgl7CgkJbV9wQ29udGVudHMtPlNldFRleHQoc0NvbnRlbnRzKTsKCX0KCglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQoJewoJCXBOb3RpZnktPk9uU2V0Q29udGVudHModGhpcyk7Cgl9Cn0KCkNQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldFBhcmVudE5vdGVJdGVtKCkgY29uc3QKewoJaWYgKENQV0xfV25kKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpCgl7CgkJaWYgKENQV0xfV25kKiBwR3JhbmQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKSkKCQl7CgkJCUFTU0VSVChwR3JhbmQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7CgkJCXJldHVybiAoQ1BXTF9Ob3RlSXRlbSopcEdyYW5kOwoJCX0KCX0KCglyZXR1cm4gTlVMTDsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0UGFyZW50SXRlbSgpIGNvbnN0CnsKCXJldHVybiBHZXRQYXJlbnROb3RlSXRlbSgpOwp9CgpDUFdMX0VkaXQqIENQV0xfTm90ZUl0ZW06OkdldEVkaXQoKSBjb25zdAp7CglpZiAobV9wQ29udGVudHMpCgkJcmV0dXJuIG1fcENvbnRlbnRzLT5HZXRFZGl0KCk7CglyZXR1cm4gTlVMTDsKfQoKdm9pZCogQ1BXTF9Ob3RlSXRlbTo6R2V0UHJpdmF0ZURhdGEoKSBjb25zdAp7CglyZXR1cm4gbV9wUHJpdmF0ZURhdGE7Cn0KCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldEF1dGhvck5hbWUoKSBjb25zdAp7CglyZXR1cm4gbV9zQXV0aG9yOyAKfQoKQ1BXTF9Db2xvciBDUFdMX05vdGVJdGVtOjpHZXRCa0NvbG9yKCkgY29uc3QKewoJcmV0dXJuIHRoaXMtPkdldEJhY2tncm91bmRDb2xvcigpOwp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRDb250ZW50cygpIGNvbnN0CnsKCWlmIChtX3BDb250ZW50cykKCQlyZXR1cm4gbV9wQ29udGVudHMtPkdldFRleHQoKTsKCglyZXR1cm4gTCIiOwp9CgpGWF9TWVNURU1USU1FIENQV0xfTm90ZUl0ZW06OkdldERhdGVUaW1lKCkgY29uc3QKewoJcmV0dXJuIG1fZHROb3RlOwp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRTdWJqZWN0TmFtZSgpIGNvbnN0CnsKCWlmIChtX3BTdWJqZWN0KQoJCXJldHVybiBtX3BTdWJqZWN0LT5HZXRUZXh0KCk7CgoJcmV0dXJuIEwiIjsKfQoKQ1BXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6Q3JlYXRlTm90ZUl0ZW0oKQp7CglpZiAobV9wQ29udGVudHMpCgkJcmV0dXJuIG1fcENvbnRlbnRzLT5DcmVhdGVTdWJJdGVtKCk7CgoJcmV0dXJuIE5VTEw7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkNyZWF0ZVN1Ykl0ZW0oKQp7CglyZXR1cm4gQ3JlYXRlTm90ZUl0ZW0oKTsKfQoKRlhfSU5UMzIgQ1BXTF9Ob3RlSXRlbTo6Q291bnRTdWJJdGVtcygpIGNvbnN0CnsKCWlmIChtX3BDb250ZW50cykKCQlyZXR1cm4gbV9wQ29udGVudHMtPkNvdW50U3ViSXRlbXMoKTsKCglyZXR1cm4gMDsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0U3ViSXRlbXMoRlhfSU5UMzIgaW5kZXgpIGNvbnN0CnsKCWlmIChtX3BDb250ZW50cykKCQlyZXR1cm4gbV9wQ29udGVudHMtPkdldFN1Ykl0ZW1zKGluZGV4KTsKCglyZXR1cm4gTlVMTDsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpEZWxldGVTdWJJdGVtKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSkKewoJdGhpcy0+S2lsbEZvY3VzKCk7CgoJaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkKCXsKCQlwTm90aWZ5LT5Pbkl0ZW1EZWxldGUocE5vdGVJdGVtKTsKCX0KCglpZiAobV9wQ29udGVudHMpCgkJbV9wQ29udGVudHMtPkRlbGV0ZVN1Ykl0ZW0ocE5vdGVJdGVtKTsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0SGl0Tm90ZUl0ZW0oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCnsKCUNQREZfUG9pbnQgcHQgPSB0aGlzLT5QYXJlbnRUb0NoaWxkKHBvaW50KTsKCglpZiAodGhpcy0+V25kSGl0VGVzdChwdCkpCgl7CgkJaWYgKG1fcENvbnRlbnRzKQoJCXsKCQkJaWYgKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IG1fcENvbnRlbnRzLT5HZXRIaXROb3RlSXRlbShwdCkpCgkJCQlyZXR1cm4gcE5vdGVJdGVtOwoJCX0KCgkJcmV0dXJuIHRoaXM7Cgl9CgoJcmV0dXJuIE5VTEw7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldEZvY3VzZWROb3RlSXRlbSgpIGNvbnN0CnsKCWlmIChjb25zdCBDUFdMX1duZCogcFduZCA9IHRoaXMtPkdldEZvY3VzZWQoKSkKCXsKCQlpZiAocFduZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfRWRpdCIpCgkJewoJCQlpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBwV25kLT5HZXRQYXJlbnRXaW5kb3coKSkKCQkJewoJCQkJQVNTRVJUKHBQYXJlbnQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVfQ29udGVudHMiKTsKCQkJCQoJCQkJaWYgKENQV0xfV25kKiBwR3JhbmQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKSkKCQkJCXsKCQkJCQlBU1NFUlQocEdyYW5kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwkJCQkJCgkJCQkJcmV0dXJuIChDUFdMX05vdGVJdGVtKilwR3JhbmQ7CgkJCQl9CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIE5VTEw7Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZUl0ZW06OkdldEl0ZW1IZWlnaHQoRlhfRkxPQVQgZkxpbWl0V2lkdGgpCnsKCWlmIChmTGltaXRXaWR0aCA+IDApCgl7CgkJaWYgKCFtX2JTaXplQ2hhbmdlZCkKCQkJcmV0dXJuIG1fZk9sZEl0ZW1IZWlnaHQ7CgoJCW1fYlNpemVDaGFuZ2VkID0gRkFMU0U7CgoJCUFTU0VSVChtX3BTdWJqZWN0ICE9IE5VTEwpOwoJCUFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsKCQlBU1NFUlQobV9wQ29udGVudHMgIT0gTlVMTCk7CgoJCUZYX0ZMT0FUIGZSZXQgPSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKCQlGWF9GTE9BVCBmQm9yZGVyV2lkdGggPSAoRlhfRkxPQVQpdGhpcy0+R2V0Qm9yZGVyV2lkdGgoKTsKCQlpZiAoZkxpbWl0V2lkdGggPiBmQm9yZGVyV2lkdGggKiAyKQoJCQlmUmV0ICs9IG1fcENvbnRlbnRzLT5HZXRDb250ZW50c0hlaWdodChmTGltaXRXaWR0aCAtIGZCb3JkZXJXaWR0aCAqIDIpOwoJCWZSZXQgKz0gUE9QVVBfSVRFTV9IRUFEX0JPVFRPTSArIFBPUFVQX0lURU1fQk9UVE9NV0lEVEggKyBmQm9yZGVyV2lkdGggKiAyOwoKCQlyZXR1cm4gbV9mT2xkSXRlbUhlaWdodCA9IGZSZXQ7Cgl9CgoJcmV0dXJuIDA7Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZUl0ZW06OkdldEl0ZW1MZWZ0TWFyZ2luKCkKewoJcmV0dXJuIFBPUFVQX0lURU1fU0lERU1BUkdJTjsKfQoKRlhfRkxPQVQgQ1BXTF9Ob3RlSXRlbTo6R2V0SXRlbVJpZ2h0TWFyZ2luKCkKewoJcmV0dXJuIFBPUFVQX0lURU1fU0lERU1BUkdJTjsKfQoKRlhfQk9PTAlDUFdMX05vdGVJdGVtOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKewoJaWYgKCFtX3BDb250ZW50cy0+V25kSGl0VGVzdChtX3BDb250ZW50cy0+UGFyZW50VG9DaGlsZChwb2ludCkpKQoJewoJCVNldE5vdGVGb2N1cyhGQUxTRSk7Cgl9CgoJQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOwoKCXJldHVybiBUUlVFOwp9CgpGWF9CT09MCUNQV0xfTm90ZUl0ZW06Ok9uUkJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCnsKCWlmICghbV9wQ29udGVudHMtPlduZEhpdFRlc3QobV9wQ29udGVudHMtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkKCXsKCQlTZXROb3RlRm9jdXMoRkFMU0UpOwoJCVBvcHVwTm90ZUl0ZW1NZW51KHBvaW50KTsKCgkJcmV0dXJuIFRSVUU7Cgl9CgoJcmV0dXJuIENQV0xfV25kOjpPblJCdXR0b25VcChwb2ludCxuRmxhZyk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSwgRlhfSU5UUFRSIGxQYXJhbSkKewoJc3dpdGNoIChtc2cpCgl7CgljYXNlIFBOTV9OT1RFRURJVENIQU5HRUQ6CQoJCW1fYlNpemVDaGFuZ2VkID0gVFJVRTsKCgkJaWYgKENQV0xfV25kKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpCgkJewoJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKCQl9CgkJcmV0dXJuOwkKCWNhc2UgUE5NX1NFVENBUkVUSU5GTzoKCQlpZiAoUFdMX0NBUkVUX0lORk8gKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKQoJCXsKCQkJUFdMX0NBUkVUX0lORk8gbmV3SW5mbyA9ICpwSW5mbzsKCQkJbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7CgkJCW5ld0luZm8ucHRIZWFkID0gdGhpcy0+Q2hpbGRUb1BhcmVudChwSW5mby0+cHRIZWFkKTsKCQkJbmV3SW5mby5wdEZvb3QgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEZvb3QpOwoKCQkJaWYgKENQV0xfV25kICogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQoJCQl7CgkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUQ0FSRVRJTkZPLCAoRlhfSU5UUFRSKSZuZXdJbmZvLCAwKTsKCQkJfQoJCX0KCQlyZXR1cm47CgljYXNlIFBOTV9OT1RFUkVTRVQ6CgkJbV9iU2l6ZUNoYW5nZWQgPSBUUlVFOwoJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKCQkKCQlyZXR1cm47Cgl9CgoJQ1BXTF9XbmQ6Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlBvcHVwTm90ZUl0ZW1NZW51KGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQp7CglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQoJewoJCUZYX0lOVDMyIHgseTsKCQlQV0x0b1duZChwb2ludCwgeCwgeSk7CgkJaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU0ggPSBHZXRTeXN0ZW1IYW5kbGVyKCkpCgkJCXBTSC0+Q2xpZW50VG9TY3JlZW4oR2V0QXR0YWNoZWRIV25kKCksIHgsIHkpOwoJCXBOb3RpZnktPk9uUG9wdXBNZW51KHRoaXMsIHgsIHkpOwoJfQp9Cgpjb25zdCBDUFdMX05vdGUqIENQV0xfTm90ZUl0ZW06OkdldE5vdGUoKSBjb25zdAp7CglpZiAoY29uc3QgQ1BXTF9XbmQqIHBSb290ID0gdGhpcy0+R2V0Um9vdFduZCgpKQoJewoJCUFTU0VSVChwUm9vdC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKCQlDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcFJvb3Q7CgkJaWYgKHBOb3RlSXRlbS0+SXNUb3BJdGVtKCkpCgkJewoJCQlyZXR1cm4gKENQV0xfTm90ZSopcE5vdGVJdGVtOwoJCX0KCX0KCglyZXR1cm4gTlVMTDsKfQoKSVBXTF9Ob3RlTm90aWZ5KiBDUFdMX05vdGVJdGVtOjpHZXROb3RlTm90aWZ5KCkgY29uc3QKewoJaWYgKGNvbnN0IENQV0xfTm90ZSogcE5vdGUgPSBHZXROb3RlKCkpCgkJcmV0dXJuIHBOb3RlLT5HZXROb3RlTm90aWZ5KCk7CgoJcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6T25DcmVhdGVOb3RlSXRlbSgpCnsKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25JdGVtQ3JlYXRlKHRoaXMpOwoJfQp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06Ok9uQ29udGVudHNWYWxpZGF0ZSgpCnsKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25TZXRDb250ZW50cyh0aGlzKTsKCX0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXROb3RlRm9jdXMoRlhfQk9PTCBiTGFzdCkKewoJbV9wQ29udGVudHMtPlNldEVkaXRGb2N1cyhiTGFzdCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6RW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpCnsKCW1fcENvbnRlbnRzLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOwoJbV9iQWxsb3dNb2RpZnkgPSBiRW5hYmxlZDsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpFbmFibGVSZWFkKEZYX0JPT0wgYkVuYWJsZWQpCnsKCW1fcENvbnRlbnRzLT5FbmFibGVSZWFkKGJFbmFibGVkKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ1BXTF9Ob3RlOjpDUFdMX05vdGUoSVBvcHVwX05vdGUqIHBQb3B1cE5vdGUsIElQV0xfTm90ZU5vdGlmeSogcE5vdGVOb3RpZnksIElQV0xfTm90ZUhhbmRsZXIqIHBOb3RlSGFuZGxlcikgOiAKCW1fcEF1dGhvcihOVUxMKSwKCW1fcEljb24oTlVMTCksCgltX3BDbG9zZUJveChOVUxMKSwKCW1fcExCQm94KE5VTEwpLAoJbV9wUkJCb3goTlVMTCksCgltX3BDb250ZW50c0JhcihOVUxMKSwKCW1fcE9wdGlvbnMoTlVMTCksCgltX3BOb3RlTm90aWZ5KHBOb3RlTm90aWZ5KSwKCW1fYlJlc2l6aW5nKEZBTFNFKSwKCW1fcmNDYXB0aW9uKDAsMCwwLDApLAoJbV9iRW5hbGJsZU5vdGlmeShUUlVFKSwKCW1fcFBvcHVwTm90ZShwUG9wdXBOb3RlKQp7Cn0KCkNQV0xfTm90ZTo6fkNQV0xfTm90ZSgpCnsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlOjpSZXBseSgpCnsKCXJldHVybiBDcmVhdGVOb3RlSXRlbSgpOwp9Cgp2b2lkIENQV0xfTm90ZTo6RW5hYmxlTm90aWZ5KEZYX0JPT0wgYkVuYWJsZWQpCnsKCW1fYkVuYWxibGVOb3RpZnkgPSBiRW5hYmxlZDsKfQoKdm9pZCBDUFdMX05vdGU6OlJlUG9zQ2hpbGRXbmQoKQp7CglSZVBvc05vdGVDaGlsZHJlbigpOwoJbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOwoJUmVzZXRTY3JvbGxCYXIoKTsKCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKCXRoaXMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOwoJLy/NrLK9CglpZiAoY29uc3QgQ1BXTF9XbmQqIHBXbmQgPSB0aGlzLT5HZXRGb2N1c2VkKCkpCgl7CgkJaWYgKHBXbmQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX0VkaXQiKQoJCXsKCQkJQ1BXTF9FZGl0KiBwRWRpdCA9IChDUFdMX0VkaXQqKXBXbmQ7CgkJCXBFZGl0LT5TZXRDYXJldChwRWRpdC0+R2V0Q2FyZXQoKSk7CgkJfQoJfQoJLy9DUERGX1BvaW50IHB0TmV3ID0gbV9wQ29udGVudHMtPkdldFNjcm9sbFBvcygpOwoJLy9tX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0TmV3LnkpOwp9CgpGWF9CT09MIENQV0xfTm90ZTo6UmVzZXRTY3JvbGxCYXIoKQp7CglGWF9CT09MIGJTY3JvbGxDaGFuZ2VkID0gRkFMU0U7CgoJaWYgKFNjcm9sbEJhclNob3VsZFZpc2libGUoKSkKCXsKCQlpZiAoIW1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkKCQl7CgkJCW1fcENvbnRlbnRzQmFyLT5TZXRWaXNpYmxlKFRSVUUpOwoJCQlpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQoJCQl7CgkJCQltX3BDb250ZW50c0Jhci0+SW52YWxpZGF0ZVJlY3QoTlVMTCk7CgkJCQliU2Nyb2xsQ2hhbmdlZCA9IFRSVUU7CgkJCX0KCQl9CQoJfQoJZWxzZQoJewoJCWlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpCgkJewoJCQltX3BDb250ZW50c0Jhci0+U2V0VmlzaWJsZShGQUxTRSk7CgkJCW1fcENvbnRlbnRzQmFyLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKCgkJCWJTY3JvbGxDaGFuZ2VkID0gVFJVRTsKCQl9Cgl9CgoJaWYgKGJTY3JvbGxDaGFuZ2VkKQoJewoJCUNQREZfUmVjdCByY05vdGUgPSB0aGlzLT5HZXRDbGllbnRSZWN0KCk7CgkJQ1BERl9SZWN0IHJjQ29udGVudHMgPSBtX3BDb250ZW50cy0+R2V0V2luZG93UmVjdCgpOwoJCXJjQ29udGVudHMucmlnaHQgPSByY05vdGUucmlnaHQgLSAzLjBmOwoJCWlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpCgkJCXJjQ29udGVudHMucmlnaHQgLT0gUFdMX1NDUk9MTEJBUl9XSURUSDsKCQltX3BDb250ZW50cy0+TW92ZShyY0NvbnRlbnRzLCBUUlVFLCBUUlVFKTsKCQltX3BDb250ZW50cy0+U2V0U2Nyb2xsUG9zKENQREZfUG9pbnQoMC4wZiwwLjBmKSk7CgkJbV9wQ29udGVudHMtPkludmFsaWRhdGVSZWN0KE5VTEwpOwoJfQoKCXJldHVybiBiU2Nyb2xsQ2hhbmdlZDsKfQoKRlhfQk9PTCBDUFdMX05vdGU6OlNjcm9sbEJhclNob3VsZFZpc2libGUoKQp7CglDUERGX1JlY3QgcmNDb250ZW50c0ZhY3QgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsQXJlYSgpOwoJQ1BERl9SZWN0IHJjQ29udGVudHNDbGllbnQgPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpOwoKCXJldHVybiByY0NvbnRlbnRzRmFjdC5IZWlnaHQoKSA+IHJjQ29udGVudHNDbGllbnQuSGVpZ2h0KCk7CQp9Cgp2b2lkIENQV0xfTm90ZTo6U2V0T3B0aW9uc1RleHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUZXh0KQp7CglpZiAobV9wT3B0aW9ucykKCQltX3BPcHRpb25zLT5TZXRUZXh0KHNUZXh0KTsKCglSZVBvc05vdGVDaGlsZHJlbigpOwp9Cgp2b2lkIENQV0xfTm90ZTo6UmVQb3NOb3RlQ2hpbGRyZW4oKQp7CglpZiAobV9iUmVzaXppbmcpIHJldHVybjsKCgltX2JSZXNpemluZyA9IFRSVUU7CgoJaWYgKHRoaXMtPklzVmFsaWQoKSkKCXsKCQlBU1NFUlQobV9wU3ViamVjdCAhPSBOVUxMKTsKCQlBU1NFUlQobV9wRGF0ZVRpbWUgIT0gTlVMTCk7CgkJQVNTRVJUKG1fcENvbnRlbnRzICE9IE5VTEwpOwoJCUFTU0VSVChtX3BBdXRob3IgIT0gTlVMTCk7CgkJQVNTRVJUKG1fcENsb3NlQm94ICE9IE5VTEwpOwoJCUFTU0VSVChtX3BJY29uICE9IE5VTEwpOwoJCUFTU0VSVChtX3BMQkJveCAhPSBOVUxMKTsKCQlBU1NFUlQobV9wUkJCb3ggIT0gTlVMTCk7CgkJQVNTRVJUKG1fcENvbnRlbnRzQmFyICE9IE5VTEwpOwoJCUFTU0VSVChtX3BPcHRpb25zICE9IE5VTEwpOwoKCQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CgoJCUNQREZfUmVjdCByY0ljb24gPSByY0NsaWVudDsKCQlyY0ljb24udG9wIC09IDIuMGY7CgkJcmNJY29uLnJpZ2h0ID0gcmNJY29uLmxlZnQgKyAxNC4wZjsKCQlyY0ljb24uYm90dG9tID0gcmNJY29uLnRvcCAtIDE0LjBmOwoJCXJjSWNvbi5Ob3JtYWxpemUoKTsKCQltX3BJY29uLT5Nb3ZlKHJjSWNvbiwgVFJVRSwgRkFMU0UpOwoJCW1fcEljb24tPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0ljb24pKTsKCgkJQ1BERl9SZWN0IHJjQ2xvc2VCb3ggPSByY0NsaWVudDsKCQlyY0Nsb3NlQm94LnJpZ2h0IC09IDEuMGY7CgkJcmNDbG9zZUJveC50b3AgLT0gMS4wZjsKCQlyY0Nsb3NlQm94LmxlZnQgPSByY0Nsb3NlQm94LnJpZ2h0IC0gMTQuMGY7CgkJcmNDbG9zZUJveC5ib3R0b20gPSByY0Nsb3NlQm94LnRvcCAtIDE0LjBmOwoJCXJjQ2xvc2VCb3guTm9ybWFsaXplKCk7CgkJbV9wQ2xvc2VCb3gtPk1vdmUocmNDbG9zZUJveCwgVFJVRSwgRkFMU0UpOwoJCW1fcENsb3NlQm94LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNDbG9zZUJveCkpOwoKCQlDUERGX1JlY3QgcmNEYXRlID0gcmNDbGllbnQ7CgkJcmNEYXRlLnJpZ2h0ID0gcmNDbG9zZUJveC5sZWZ0IC0gUE9QVVBfSVRFTV9URVhUX0lOREVOVDsKCQlyY0RhdGUubGVmdCA9IFBXTF9NQVgocmNEYXRlLnJpZ2h0IC0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSAtIDEuMGYsIHJjSWNvbi5yaWdodCArIDEuMGYpOwoJCXJjRGF0ZS50b3AgPSByY0NsaWVudC50b3AgLSAyLjBmOwoJCXJjRGF0ZS5ib3R0b20gPSByY0RhdGUudG9wIC0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CgkJcmNEYXRlLk5vcm1hbGl6ZSgpOwoJCW1fcERhdGVUaW1lLT5Nb3ZlKHJjRGF0ZSwgVFJVRSwgRkFMU0UpOwoJCW1fcERhdGVUaW1lLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNEYXRlKSk7CgoJCUNQREZfUmVjdCByY1N1YmplY3QgPSByY0NsaWVudDsKCQlyY1N1YmplY3QudG9wID0gcmNDbGllbnQudG9wIC0gMi4wZjsKCQlyY1N1YmplY3QubGVmdCA9IHJjSWNvbi5yaWdodCArIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7CgkJcmNTdWJqZWN0LnJpZ2h0ID0gUFdMX01JTihyY1N1YmplY3QubGVmdCArIG1fcFN1YmplY3QtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSArIDEuMGYsIHJjRGF0ZS5sZWZ0IC0gMS4wZik7CgkJcmNTdWJqZWN0LmJvdHRvbSA9IHJjU3ViamVjdC50b3AgLSBtX3BTdWJqZWN0LT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwoJCXJjU3ViamVjdC5Ob3JtYWxpemUoKTsKCQltX3BTdWJqZWN0LT5Nb3ZlKHJjU3ViamVjdCwgVFJVRSwgRkFMU0UpOwkKCQltX3BTdWJqZWN0LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNTdWJqZWN0KSk7CgoJCUNQREZfUmVjdCByY09wdGlvbnMgPSByY0NsaWVudDsKCQlyY09wdGlvbnMubGVmdCA9IFBXTF9NQVgocmNPcHRpb25zLnJpZ2h0IC0gbV9wT3B0aW9ucy0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpLCByY0ljb24ucmlnaHQgKyAxLjBmKTsKCQlyY09wdGlvbnMudG9wID0gcmNTdWJqZWN0LmJvdHRvbSAtIDQuMGY7CgkJcmNPcHRpb25zLmJvdHRvbSA9IHJjT3B0aW9ucy50b3AgLSBtX3BPcHRpb25zLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwoJCXJjT3B0aW9ucy5Ob3JtYWxpemUoKTsKCQltX3BPcHRpb25zLT5Nb3ZlKHJjT3B0aW9ucywgVFJVRSwgRkFMU0UpOwoJCW1fcE9wdGlvbnMtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY09wdGlvbnMpKTsKCgkJQ1BERl9SZWN0IHJjQXV0aG9yID0gcmNDbGllbnQ7CgkJcmNBdXRob3IudG9wID0gcmNTdWJqZWN0LmJvdHRvbSAtIDQuMGY7CgkJcmNBdXRob3IubGVmdCA9IHJjU3ViamVjdC5sZWZ0OwoJCXJjQXV0aG9yLnJpZ2h0ID0gUFdMX01JTihyY1N1YmplY3QubGVmdCArIG1fcEF1dGhvci0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpICsgMS4wZiwgcmNPcHRpb25zLmxlZnQgLSAxLjBmKTsKCQlyY0F1dGhvci5ib3R0b20gPSByY0F1dGhvci50b3AgLSBtX3BBdXRob3ItPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CgkJcmNBdXRob3IuTm9ybWFsaXplKCk7CgkJbV9wQXV0aG9yLT5Nb3ZlKHJjQXV0aG9yLCBUUlVFLCBGQUxTRSk7CgkJbV9wQXV0aG9yLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNBdXRob3IpKTsKCgkJQ1BERl9SZWN0IHJjTEJCb3ggPSByY0NsaWVudDsKCQlyY0xCQm94LnRvcCA9IHJjTEJCb3guYm90dG9tICsgNy4wZjsKCQlyY0xCQm94LnJpZ2h0ID0gcmNMQkJveC5sZWZ0ICsgNy4wZjsKCQlyY0xCQm94Lk5vcm1hbGl6ZSgpOwoJCW1fcExCQm94LT5Nb3ZlKHJjTEJCb3gsIFRSVUUsIEZBTFNFKTsKCQltX3BMQkJveC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjTEJCb3gpKTsKCgkJQ1BERl9SZWN0IHJjUkJCb3ggPSByY0NsaWVudDsKCQlyY1JCQm94LnRvcCA9IHJjUkJCb3guYm90dG9tICsgNy4wZjsKCQlyY1JCQm94LmxlZnQgPSByY1JCQm94LnJpZ2h0IC0gNy4wZjsKCQlyY1JCQm94Lk5vcm1hbGl6ZSgpOwoJCW1fcFJCQm94LT5Nb3ZlKHJjUkJCb3gsIFRSVUUsIEZBTFNFKTsKCQltX3BSQkJveC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjUkJCb3gpKTsKCgkJQ1BERl9SZWN0IHJjQ29udGVudHMgPSByY0NsaWVudDsKCQlyY0NvbnRlbnRzLnRvcCA9IHJjQXV0aG9yLmJvdHRvbSAtIFBPUFVQX0lURU1fSEVBRF9CT1RUT007CgkJcmNDb250ZW50cy5sZWZ0ICs9IDMuMGY7CgkJcmNDb250ZW50cy5yaWdodCAtPSAzLjBmOwoJCWlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpCgkJCXJjQ29udGVudHMucmlnaHQgLT0gUFdMX1NDUk9MTEJBUl9XSURUSDsKCQlyY0NvbnRlbnRzLmJvdHRvbSArPSAxNC4wZjsKCQlyY0NvbnRlbnRzLk5vcm1hbGl6ZSgpOwoJCW1fcENvbnRlbnRzLT5Nb3ZlKHJjQ29udGVudHMsIEZBTFNFLCBGQUxTRSk7CgkJbV9wQ29udGVudHMtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0NvbnRlbnRzKSk7CgoJCUNQREZfUmVjdCByY0NvbnRlbnRzQmFyID0gcmNDb250ZW50czsKCQlyY0NvbnRlbnRzQmFyLnJpZ2h0ID0gcmNDbGllbnQucmlnaHQgLSAzLjBmOwoJCXJjQ29udGVudHNCYXIubGVmdCA9IHJjQ29udGVudHNCYXIucmlnaHQgLSBQV0xfU0NST0xMQkFSX1dJRFRIOwoJCXJjQ29udGVudHNCYXIuTm9ybWFsaXplKCk7CgkJbV9wQ29udGVudHNCYXItPk1vdmUocmNDb250ZW50c0JhciwgVFJVRSwgRkFMU0UpOwoJCQoJCW1fcmNDYXB0aW9uID0gcmNDbGllbnQ7CgkJbV9yY0NhcHRpb24uYm90dG9tID0gcmNDb250ZW50cy50b3A7Cgl9CgoJbV9iUmVzaXppbmcgPSBGQUxTRTsKfQoKLy8wLW5vcm1hbCAvIDEtY2FwdGlvbiAvIDItbGVmdGJvdHRvbSBjb3JuZXIgLyAzLXJpZ2h0Ym90dG9tIGNvcm5lciAvIDQtY2xvc2UgLyA1LW9wdGlvbnMgCkZYX0lOVDMyIENQV0xfTm90ZTo6Tm90ZUhpdFRlc3QoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIGNvbnN0CnsKCUFTU0VSVChtX3BTdWJqZWN0ICE9IE5VTEwpOwoJQVNTRVJUKG1fcERhdGVUaW1lICE9IE5VTEwpOwoJQVNTRVJUKG1fcENvbnRlbnRzICE9IE5VTEwpOwoJQVNTRVJUKG1fcEF1dGhvciAhPSBOVUxMKTsKCUFTU0VSVChtX3BJY29uICE9IE5VTEwpOwoJQVNTRVJUKG1fcENvbnRlbnRzQmFyICE9IE5VTEwpOwoKCUFTU0VSVChtX3BDbG9zZUJveCAhPSBOVUxMKTsKCUFTU0VSVChtX3BMQkJveCAhPSBOVUxMKTsKCUFTU0VSVChtX3BSQkJveCAhPSBOVUxMKTsKCUFTU0VSVChtX3BPcHRpb25zICE9IE5VTEwpOwoKCUdldENsaWVudFJlY3QoKTsKCglpZiAobV9wU3ViamVjdC0+V25kSGl0VGVzdChtX3BTdWJqZWN0LT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAxOwoJaWYgKG1fcERhdGVUaW1lLT5XbmRIaXRUZXN0KG1fcERhdGVUaW1lLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAxOwoJaWYgKG1fcEF1dGhvci0+V25kSGl0VGVzdChtX3BBdXRob3ItPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDE7CglpZiAobV9wSWNvbi0+V25kSGl0VGVzdChtX3BJY29uLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAxOwoKCWlmIChtX3BDb250ZW50cy0+V25kSGl0VGVzdChtX3BDb250ZW50cy0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMDsKCWlmIChtX3BDb250ZW50c0Jhci0+V25kSGl0VGVzdChtX3BDb250ZW50c0Jhci0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMDsKCglpZiAobV9wQ2xvc2VCb3gtPlduZEhpdFRlc3QobV9wQ2xvc2VCb3gtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDQ7CglpZiAobV9wTEJCb3gtPlduZEhpdFRlc3QobV9wTEJCb3gtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDI7CglpZiAobV9wUkJCb3gtPlduZEhpdFRlc3QobV9wUkJCb3gtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDM7CglpZiAobV9wT3B0aW9ucy0+V25kSGl0VGVzdChtX3BPcHRpb25zLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiA1OwoKCXJldHVybiAxOwp9Cgp2b2lkIENQV0xfTm90ZTo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCnsKCUNQV0xfTm90ZUl0ZW06OkNyZWF0ZUNoaWxkV25kKGNwKTsKCglDUFdMX0NvbG9yIHNUZXh0Q29sb3I7CgoJaWYgKENQV0xfVXRpbHM6OklzQmxhY2tPcldoaXRlKHRoaXMtPkdldEJhY2tncm91bmRDb2xvcigpKSkKCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsKCWVsc2UKCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUjsKCgltX3BBdXRob3IgPSBuZXcgQ1BXTF9MYWJlbDsKCVBXTF9DUkVBVEVQQVJBTSBhY3AgPSBjcDsKCWFjcC5wUGFyZW50V25kID0gdGhpczsKCWFjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfTEVGVCB8IFBFU19UT1A7CglhY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CgltX3BBdXRob3ItPkNyZWF0ZShhY3ApOwkgCgoJbV9wQ2xvc2VCb3ggPSBuZXcgQ1BXTF9Ob3RlX0Nsb3NlQm94OwoJUFdMX0NSRUFURVBBUkFNIGNjcCA9IGNwOwoJY2NwLnBQYXJlbnRXbmQgPSB0aGlzOwoJY2NwLmR3Qm9yZGVyV2lkdGggPSAyOwoJY2NwLm5Cb3JkZXJTdHlsZSA9IFBCU19CRVZFTEVEOwoJY2NwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBXU19CT1JERVI7CgljY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CgltX3BDbG9zZUJveC0+Q3JlYXRlKGNjcCk7CgoJbV9wSWNvbiA9IG5ldyBDUFdMX05vdGVfSWNvbjsKCVBXTF9DUkVBVEVQQVJBTSBpY3AgPSBjcDsKCWljcC5wUGFyZW50V25kID0gdGhpczsKCWljcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQ7CgltX3BJY29uLT5DcmVhdGUoaWNwKTsKCgltX3BPcHRpb25zID0gbmV3IENQV0xfTm90ZV9PcHRpb25zOwoJUFdMX0NSRUFURVBBUkFNIG9jcCA9IGNwOwoJb2NwLnBQYXJlbnRXbmQgPSB0aGlzOwoJb2NwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRTsKCW9jcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsKCW1fcE9wdGlvbnMtPkNyZWF0ZShvY3ApOwoKCW1fcExCQm94ID0gbmV3IENQV0xfTm90ZV9MQkJveDsKCVBXTF9DUkVBVEVQQVJBTSBsY3AgPSBjcDsKCWxjcC5wUGFyZW50V25kID0gdGhpczsKCWxjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQ7CglsY3AuZUN1cnNvclR5cGUgPSBGWENUX05FU1c7CglsY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CgltX3BMQkJveC0+Q3JlYXRlKGxjcCk7CgoJbV9wUkJCb3ggPSBuZXcgQ1BXTF9Ob3RlX1JCQm94OwoJUFdMX0NSRUFURVBBUkFNIHJjcCA9IGNwOwoJcmNwLnBQYXJlbnRXbmQgPSB0aGlzOwoJcmNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRDsKCXJjcC5lQ3Vyc29yVHlwZSA9IEZYQ1RfTldTRTsKCXJjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsKCW1fcFJCQm94LT5DcmVhdGUocmNwKTsKCgltX3BDb250ZW50c0JhciA9IG5ldyBDUFdMX1Njcm9sbEJhcihTQlRfVlNDUk9MTCk7CglQV0xfQ1JFQVRFUEFSQU0gc2NwID0gY3A7CglzY3AucFBhcmVudFduZCA9IHRoaXM7CglzY3Auc0JhY2tncm91bmRDb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZik7CglzY3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFIHwgUFdTX0JBQ0tHUk9VTkQ7CgltX3BDb250ZW50c0Jhci0+Q3JlYXRlKHNjcCk7CgltX3BDb250ZW50c0Jhci0+U2V0Tm90aWZ5Rm9yZXZlcihUUlVFKTsKfQoKdm9pZCBDUFdMX05vdGU6OlNldFN1YmplY3ROYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkKewoJQ1BXTF9Ob3RlSXRlbTo6U2V0U3ViamVjdE5hbWUoc05hbWUpOwoJUmVQb3NDaGlsZFduZCgpOwp9Cgp2b2lkIENQV0xfTm90ZTo6U2V0QXV0aG9yTmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpCnsKCWlmIChtX3BBdXRob3IpCgl7CgkJbV9wQXV0aG9yLT5TZXRUZXh0KHNOYW1lKTsKCQlSZVBvc0NoaWxkV25kKCk7Cgl9CgoJaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkKCXsKCQlwTm90aWZ5LT5PblNldEF1dGhvck5hbWUodGhpcyk7Cgl9CQp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGU6OkdldEF1dGhvck5hbWUoKSBjb25zdAp7CglpZiAobV9wQXV0aG9yKQoJCXJldHVybiBtX3BBdXRob3ItPkdldFRleHQoKTsKCglyZXR1cm4gTCIiOwp9CgpGWF9CT09MIENQV0xfTm90ZTo6T25Nb3VzZVdoZWVsKHNob3J0IHpEZWx0YSwgY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKewoJQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsKCUNQREZfUmVjdCByY1Njcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxBcmVhKCk7CglDUERGX1JlY3QgcmNDb250ZW50cyA9IG1fcENvbnRlbnRzLT5HZXRDbGllbnRSZWN0KCk7CgoJaWYgKHJjU2Nyb2xsLnRvcCAtIHJjU2Nyb2xsLmJvdHRvbSA+IHJjQ29udGVudHMuSGVpZ2h0KCkpCgl7CgkJQ1BERl9Qb2ludCBwdE5ldyA9IHB0U2Nyb2xsOwoKCQlpZiAoekRlbHRhID4gMCkKCQkJcHROZXcueSArPSAzMDsKCQllbHNlCgkJCXB0TmV3LnkgLT0gMzA7CgoJCWlmIChwdE5ldy55ID4gcmNTY3JvbGwudG9wKQoJCQlwdE5ldy55ID0gcmNTY3JvbGwudG9wOwoJCWlmIChwdE5ldy55IDwgcmNTY3JvbGwuYm90dG9tICsgcmNDb250ZW50cy5IZWlnaHQoKSkKCQkJcHROZXcueSA9IHJjU2Nyb2xsLmJvdHRvbSArIHJjQ29udGVudHMuSGVpZ2h0KCk7CgkJaWYgKHB0TmV3LnkgPCByY1Njcm9sbC5ib3R0b20pCgkJCXB0TmV3LnkgPSByY1Njcm9sbC5ib3R0b207CgoJCWlmIChwdE5ldy55ICE9IHB0U2Nyb2xsLnkpCgkJewoJCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CgkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHROZXcueSk7CQkJCgkJCW1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUU0NST0xMUE9TLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHROZXcueSk7CgoJCQlyZXR1cm4gVFJVRTsKCQl9Cgl9CgoJcmV0dXJuIEZBTFNFOwp9Cgp2b2lkIENQV0xfTm90ZTo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSwgRlhfSU5UUFRSIGxQYXJhbSkKewoJc3dpdGNoIChtc2cpCgl7CgljYXNlIFBOTV9OT1RFRURJVENIQU5HRUQ6CgkJewoJCQlDUERGX1JlY3QgcmNTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsQXJlYSgpOwoJCQkKCgkJCVBXTF9TQ1JPTExfSU5GTyBzSW5mbzsKCQkJc0luZm8uZkNvbnRlbnRNaW4gPSByY1Njcm9sbC5ib3R0b207CgkJCXNJbmZvLmZDb250ZW50TWF4ID0gcmNTY3JvbGwudG9wOwoJCQlzSW5mby5mUGxhdGVXaWR0aCA9IG1fcENvbnRlbnRzLT5HZXRDbGllbnRSZWN0KCkuSGVpZ2h0KCk7CgkJCXNJbmZvLmZTbWFsbFN0ZXAgPSAxMy4wZjsKCQkJc0luZm8uZkJpZ1N0ZXAgPSBzSW5mby5mUGxhdGVXaWR0aDsKCgkJCWlmIChGWFNZU19tZW1jbXAoJm1fT2xkU2Nyb2xsSW5mbywgJnNJbmZvLCBzaXplb2YoUFdMX1NDUk9MTF9JTkZPKSkgIT0gMCkKCQkJewoJCQkJRlhfQk9PTCBiU2Nyb2xsQ2hhbmdlZCA9IEZBTFNFOwoKCQkJCWlmIChsUGFyYW0gPCAzKSAvL7fA1rnLwNGtu7cgbWFudGlzOjE1NzU5CgkJCQl7CgkJCQkJYlNjcm9sbENoYW5nZWQgPSBSZXNldFNjcm9sbEJhcigpOwoJCQkJCWlmIChiU2Nyb2xsQ2hhbmdlZCkKCQkJCQl7CgkJCQkJCWxQYXJhbSsrOwoJCQkJCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CgkJCQkJCXRoaXMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIGxQYXJhbSk7CgkJCQkJfQoJCQkJfQoJCQkJCgkJCQlpZiAoIWJTY3JvbGxDaGFuZ2VkKQoJCQkJewoJCQkJCWlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpCgkJCQkJewoJCQkJCQltX3BDb250ZW50c0Jhci0+T25Ob3RpZnkocFduZCwgUE5NX1NFVFNDUk9MTElORk8sIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZzSW5mbyk7CgkJCQkJCW1fT2xkU2Nyb2xsSW5mbyA9IHNJbmZvOwoKCQkJCQkJQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsKCQkJCQkJQ1BERl9Qb2ludCBwdE9sZCA9IHB0U2Nyb2xsOwoKCQkJCQkJaWYgKHB0U2Nyb2xsLnkgPiBzSW5mby5mQ29udGVudE1heCkKCQkJCQkJCXB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1heDsKCQkJCQkJaWYgKHB0U2Nyb2xsLnkgPCBzSW5mby5mQ29udGVudE1pbiArIHNJbmZvLmZQbGF0ZVdpZHRoKQoJCQkJCQkJcHRTY3JvbGwueSA9IHNJbmZvLmZDb250ZW50TWluICsgc0luZm8uZlBsYXRlV2lkdGg7CgkJCQkJCWlmIChwdFNjcm9sbC55IDwgc0luZm8uZkNvbnRlbnRNaW4pCgkJCQkJCQlwdFNjcm9sbC55ID0gc0luZm8uZkNvbnRlbnRNaW47CgoJCQkJCQlpZiAocHRPbGQueSAhPSBwdFNjcm9sbC55KQoJCQkJCQl7CgkJCQkJCQltX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0U2Nyb2xsLnkpOwoJCQkJCQkJbV9wQ29udGVudHNCYXItPkludmFsaWRhdGVSZWN0KE5VTEwpOwoJCQkJCQkJbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9TQ1JPTExXSU5ET1csIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdFNjcm9sbC55KTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJbV9wQ29udGVudHMtPkludmFsaWRhdGVSZWN0KE5VTEwpOwoKCQlyZXR1cm47CgljYXNlIFBOTV9TQ1JPTExXSU5ET1c6CgkJaWYgKG1fcENvbnRlbnRzKQoJCQltX3BDb250ZW50cy0+T25Ob3RpZnkocFduZCwgbXNnLCB3UGFyYW0sIGxQYXJhbSk7CgkJcmV0dXJuOwoJY2FzZSBQTk1fU0VUU0NST0xMUE9TOgoJCWlmIChtX3BDb250ZW50c0JhcikKCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHBXbmQsUE5NX1NFVFNDUk9MTFBPUyx3UGFyYW0sbFBhcmFtKTsKCQlyZXR1cm47Cgl9CgoJaWYgKG1zZyA9PSBQTk1fU0VUQ0FSRVRJTkZPICYmIElzVmFsaWQoKSkKCXsKCQlpZiAoUFdMX0NBUkVUX0lORk8gKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKQoJCXsKCQkJaWYgKG1fcENvbnRlbnRzKQoJCQl7CgkJCQlDUERGX1JlY3QgcmNDbGllbnQgPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpOwoJCQkJaWYgKHBJbmZvLT5wdEhlYWQueSA+IHJjQ2xpZW50LnRvcCkKCQkJCXsKCQkJCQlDUERGX1BvaW50IHB0ID0gbV9wQ29udGVudHMtPk91dFRvSW4ocEluZm8tPnB0SGVhZCk7CgkJCQkJbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9TQ1JPTExXSU5ET1csIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdC55KTsKCgkJCQkJQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsKCQkJCQltX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0U2Nyb2xsLnkpOwoKCQkJCQlyZXR1cm47CgkJCQl9CgkJCQkKCQkJCWlmIChwSW5mby0+cHRGb290LnkgPCByY0NsaWVudC5ib3R0b20pCgkJCQl7CgkJCQkJQ1BERl9Qb2ludCBwdCA9IG1fcENvbnRlbnRzLT5PdXRUb0luKHBJbmZvLT5wdEZvb3QpOwoJCQkJCXB0LnkgKz0gcmNDbGllbnQuSGVpZ2h0KCk7CgkJCQkJbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9TQ1JPTExXSU5ET1csIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdC55KTsKCgkJCQkJQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsKCQkJCQltX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0U2Nyb2xsLnkpOwoKCQkJCQlyZXR1cm47CgkJCQl9CgkJCX0KCQl9Cgl9CgoJQ1BXTF9Ob3RlSXRlbTo6T25Ob3RpZnkocFduZCwgbXNnLCB3UGFyYW0sIGxQYXJhbSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpTZXRCa0NvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKQp7CglDUFdMX05vdGVJdGVtOjpTZXRCa0NvbG9yKGNvbG9yKTsKCglDUFdMX0NvbG9yIHNCSyA9IGNvbG9yOwoJQ1BXTF9Db2xvciBzVGV4dENvbG9yOwoJaWYgKENQV0xfVXRpbHM6OklzQmxhY2tPcldoaXRlKHNCSykpCgkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CgllbHNlCgkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7CgoJaWYgKG1fcENsb3NlQm94KQoJCW1fcENsb3NlQm94LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CglpZiAobV9wQXV0aG9yKQoJCW1fcEF1dGhvci0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOwoJaWYgKG1fcE9wdGlvbnMpCgkJbV9wT3B0aW9ucy0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOwoJaWYgKG1fcExCQm94KQoJCW1fcExCQm94LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CglpZiAobV9wUkJCb3gpCgkJbV9wUkJCb3gtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKfQoKRlhfQk9PTAlDUFdMX05vdGU6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQp7CglpZiAobV9wT3B0aW9ucy0+V25kSGl0VGVzdChtX3BPcHRpb25zLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpCgl7CgkJaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IHRoaXMtPkdldE5vdGVOb3RpZnkoKSkKCQl7CgkJCUZYX0lOVDMyIHgsIHk7CgkJCVBXTHRvV25kKHBvaW50LCB4LCB5KTsKCQkJaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU0ggPSBHZXRTeXN0ZW1IYW5kbGVyKCkpCgkJCQlwU0gtPkNsaWVudFRvU2NyZWVuKEdldEF0dGFjaGVkSFduZCgpLCB4LCB5KTsKCQkJdGhpcy0+S2lsbEZvY3VzKCk7CgkJCXBOb3RpZnktPk9uUG9wdXBNZW51KHgsIHkpOwoKCQkJcmV0dXJuIFRSVUU7CgkJfQoJfQoKCXJldHVybiBDUFdMX1duZDo6T25MQnV0dG9uRG93bihwb2ludCxuRmxhZyk7Cn0KCkZYX0JPT0wJQ1BXTF9Ob3RlOjpPblJCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQp7CglyZXR1cm4gQ1BXTF9XbmQ6Ok9uUkJ1dHRvblVwKHBvaW50LG5GbGFnKTsKfQoKY29uc3QgQ1BXTF9Ob3RlKiBDUFdMX05vdGU6OkdldE5vdGUoKSBjb25zdAp7CglyZXR1cm4gdGhpczsKfQoKSVBXTF9Ob3RlTm90aWZ5KiBDUFdMX05vdGU6OkdldE5vdGVOb3RpZnkoKSBjb25zdAp7CglpZiAobV9iRW5hbGJsZU5vdGlmeSkKCQlyZXR1cm4gbV9wTm90ZU5vdGlmeTsKCglyZXR1cm4gTlVMTDsKfQoKdm9pZCBDUFdMX05vdGU6OlNldEljb25UeXBlKEZYX0lOVDMyIG5UeXBlKQp7CglpZiAobV9wSWNvbikKCQltX3BJY29uLT5TZXRJY29uVHlwZShuVHlwZSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpFbmFibGVNb2RpZnkoRlhfQk9PTCBiRW5hYmxlZCkKewoJbV9wQ29udGVudHMtPkVuYWJsZU1vZGlmeShiRW5hYmxlZCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpFbmFibGVSZWFkKEZYX0JPT0wgYkVuYWJsZWQpCnsKCW1fcENvbnRlbnRzLT5FbmFibGVSZWFkKGJFbmFibGVkKTsKfQoKQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9Ob3RlOjpHZXRSZXBseVN0cmluZygpIGNvbnN0CnsKCXJldHVybiBtX3NSZXBseVN0cmluZzsKfQoKdm9pZCBDUFdMX05vdGU6OlNldFJlcGx5U3RyaW5nKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJpbmcpCnsKCW1fc1JlcGx5U3RyaW5nID0gc3RyaW5nOwp9Cgo=