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+RW5hYmxlUmVhZChiRW5hYmxlZCk7CgkJCX0KCQl9Cgl9Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlSXRlbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpDUFdMX05vdGVJdGVtOjpDUFdMX05vdGVJdGVtKCkgOgoJbV9wUHJpdmF0ZURhdGEoTlVMTCksCgltX3BTdWJqZWN0KE5VTEwpLAoJbV9wRGF0ZVRpbWUoTlVMTCksCgltX3BDb250ZW50cyhOVUxMKSwKCW1fc0F1dGhvcihMIiIpLAoJbV9mT2xkSXRlbUhlaWdodCgwLjBmKSwKCW1fYlNpemVDaGFuZ2VkKEZBTFNFKSwKCW1fYkFsbG93TW9kaWZ5KFRSVUUpCnsKfQoKQ1BXTF9Ob3RlSXRlbTo6fkNQV0xfTm90ZUl0ZW0oKQp7Cn0KCkNGWF9CeXRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldENsYXNzTmFtZSgpIGNvbnN0CnsKCXJldHVybiAiQ1BXTF9Ob3RlSXRlbSI7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCnsKCUNQV0xfQ29sb3Igc1RleHRDb2xvcjsKCglpZiAoQ1BXTF9VdGlsczo6SXNCbGFja09yV2hpdGUodGhpcy0+R2V0QmFja2dyb3VuZENvbG9yKCkpKQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9XSElURUNPTE9SOwoJZWxzZQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9CTEFDS0NPTE9SOwoKCW1fcFN1YmplY3QgPSBuZXcgQ1BXTF9MYWJlbDsKCVBXTF9DUkVBVEVQQVJBTSBzY3AgPSBjcDsKCXNjcC5wUGFyZW50V25kID0gdGhpczsKCXNjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfTEVGVCB8IFBFU19UT1A7CglzY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CgltX3BTdWJqZWN0LT5DcmVhdGUoc2NwKTsKCgltX3BEYXRlVGltZSA9IG5ldyBDUFdMX0xhYmVsOwoJUFdMX0NSRUFURVBBUkFNIGRjcCA9IGNwOwoJZGNwLnBQYXJlbnRXbmQgPSB0aGlzOwoJZGNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBFU19SSUdIVCB8IFBFU19UT1A7CglkY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CgltX3BEYXRlVGltZS0+Q3JlYXRlKGRjcCk7CgoJbV9wQ29udGVudHMgPSBuZXcgQ1BXTF9Ob3RlX0NvbnRlbnRzOwoJUFdMX0NSRUFURVBBUkFNIGNjcCA9IGNwOwoJY2NwLnBQYXJlbnRXbmQgPSB0aGlzOwoJLy9jY3Auc0JhY2tncm91bmRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CgljY3Auc0JhY2tncm91bmRDb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZik7CgljY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUFdTX0JBQ0tHUk9VTkQ7CgltX3BDb250ZW50cy0+Q3JlYXRlKGNjcCk7CgltX3BDb250ZW50cy0+U2V0SXRlbVNwYWNlKFBPUFVQX0lURU1fU1BBQ0UpOwoJbV9wQ29udGVudHMtPlNldFRvcFNwYWNlKFBPUFVQX0lURU1fU1BBQ0UpOwoJbV9wQ29udGVudHMtPlNldEJvdHRvbVNwYWNlKFBPUFVQX0lURU1fU1BBQ0UpOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlJlUG9zQ2hpbGRXbmQoKQp7CglpZiAodGhpcy0+SXNWYWxpZCgpKQoJewoJCUFTU0VSVChtX3BTdWJqZWN0ICE9IE5VTEwpOwoJCUFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsKCQlBU1NFUlQobV9wQ29udGVudHMgIT0gTlVMTCk7CgoJCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKCgkJQ1BERl9SZWN0IHJjU3ViamVjdCA9IHJjQ2xpZW50OwoJCXJjU3ViamVjdC5sZWZ0ICs9IFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7CgkJcmNTdWJqZWN0LnRvcCA9IHJjQ2xpZW50LnRvcDsKCQlyY1N1YmplY3QucmlnaHQgPSBQV0xfTUlOKHJjU3ViamVjdC5sZWZ0ICsgbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpICsgMS4wZiwgcmNDbGllbnQucmlnaHQpOwoJCXJjU3ViamVjdC5ib3R0b20gPSByY1N1YmplY3QudG9wIC0gbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKCQlyY1N1YmplY3QuTm9ybWFsaXplKCk7CgkJbV9wU3ViamVjdC0+TW92ZShyY1N1YmplY3QsIFRSVUUsIEZBTFNFKTsKCQltX3BTdWJqZWN0LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNTdWJqZWN0KSk7CgoJCUNQREZfUmVjdCByY0RhdGUgPSByY0NsaWVudDsKCQlyY0RhdGUucmlnaHQgLT0gUE9QVVBfSVRFTV9URVhUX0lOREVOVDsKCQlyY0RhdGUubGVmdCA9IFBXTF9NQVgocmNEYXRlLnJpZ2h0IC0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSAtIDEuMGYsIHJjU3ViamVjdC5yaWdodCk7CgkJcmNEYXRlLmJvdHRvbSA9IHJjRGF0ZS50b3AgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKCQlyY0RhdGUuTm9ybWFsaXplKCk7CgkJbV9wRGF0ZVRpbWUtPk1vdmUocmNEYXRlLCBUUlVFLCBGQUxTRSk7CgkJbV9wRGF0ZVRpbWUtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0RhdGUpKTsKCgkJQ1BERl9SZWN0IHJjQ29udGVudHMgPSByY0NsaWVudDsKCQlyY0NvbnRlbnRzLmxlZnQgKz0gMS4wZjsKCQlyY0NvbnRlbnRzLnJpZ2h0IC09IDEuMGY7CgkJcmNDb250ZW50cy50b3AgPSByY0RhdGUuYm90dG9tIC0gUE9QVVBfSVRFTV9IRUFEX0JPVFRPTTsKCQlyY0NvbnRlbnRzLmJvdHRvbSArPSBQT1BVUF9JVEVNX0JPVFRPTVdJRFRIOwoJCXJjQ29udGVudHMuTm9ybWFsaXplKCk7CgkJbV9wQ29udGVudHMtPk1vdmUocmNDb250ZW50cywgVFJVRSwgRkFMU0UpOwoJCW1fcENvbnRlbnRzLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNDb250ZW50cykpOwoJfQoKCVNldENsaXBSZWN0KENQV0xfVXRpbHM6OkluZmxhdGVSZWN0KEdldFdpbmRvd1JlY3QoKSwxLjBmKSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0UHJpdmF0ZURhdGEodm9pZCogcERhdGEpCnsKCW1fcFByaXZhdGVEYXRhID0gcERhdGE7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0QmtDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcikKewoJQ1BXTF9Db2xvciBzQksgPSBjb2xvcjsKCXRoaXMtPlNldEJhY2tncm91bmRDb2xvcihzQkspOwoKCUNQV0xfQ29sb3Igc1RleHRDb2xvcjsKCglpZiAoQ1BXTF9VdGlsczo6SXNCbGFja09yV2hpdGUoc0JLKSkKCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsKCWVsc2UKCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUjsKCgl0aGlzLT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CglpZiAobV9wU3ViamVjdCkKCQltX3BTdWJqZWN0LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CglpZiAobV9wRGF0ZVRpbWUpCgkJbV9wRGF0ZVRpbWUtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKCgl0aGlzLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKCglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQoJewoJCXBOb3RpZnktPk9uU2V0QmtDb2xvcih0aGlzKTsKCX0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRTdWJqZWN0TmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpCnsKCWlmIChtX3BTdWJqZWN0KQoJewoJCW1fcFN1YmplY3QtPlNldFRleHQoc05hbWUpOwkKCX0KCglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQoJewoJCXBOb3RpZnktPk9uU2V0U3ViamVjdE5hbWUodGhpcyk7Cgl9Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0QXV0aG9yTmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpCnsKCW1fc0F1dGhvciA9IHNOYW1lOwoJUmVzZXRTdWJqZWN0TmFtZSgtMSk7CQoKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25TZXRBdXRob3JOYW1lKHRoaXMpOwoJfQp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlJlc2V0U3ViamVjdE5hbWUoRlhfSU5UMzIgbkl0ZW1JbmRleCkKewoJaWYgKG5JdGVtSW5kZXggPCAwKQoJewoJCWlmIChDUFdMX1duZCogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQoJCXsKCQkJQVNTRVJUKHBQYXJlbnQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVfQ29udGVudHMiKTsKCgkJCUNQV0xfTm90ZV9Db250ZW50cyogcENvbnRlbnRzID0gKENQV0xfTm90ZV9Db250ZW50cyopcFBhcmVudDsKCQkJbkl0ZW1JbmRleCA9IHBDb250ZW50cy0+R2V0SXRlbUluZGV4KHRoaXMpOwoJCX0KCX0KCgljb25zdCBDUFdMX05vdGUqIHBOb3RlID0gR2V0Tm90ZSgpOwoJQVNTRVJUKHBOb3RlICE9IE5VTEwpOwoKCUNGWF9XaWRlU3RyaW5nIHNTdWJqZWN0OwoJc1N1YmplY3QuRm9ybWF0KHBOb3RlLT5HZXRSZXBseVN0cmluZygpLCBuSXRlbUluZGV4KTsKCglpZiAoIW1fc0F1dGhvci5Jc0VtcHR5KCkpCgl7CgkJCgkJc1N1YmplY3QgKz0gTCIgLSAiOwoJCXNTdWJqZWN0ICs9IG1fc0F1dGhvcjsKCX0KCXRoaXMtPlNldFN1YmplY3ROYW1lKHNTdWJqZWN0KTsKCXRoaXMtPlJlUG9zQ2hpbGRXbmQoKTsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXREYXRlVGltZShGWF9TWVNURU1USU1FIHRpbWUpCnsKCW1fZHROb3RlID0gdGltZTsKCQoJQ0ZYX1dpZGVTdHJpbmcgc3dUaW1lOwoJc3dUaW1lLkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwNGQtJTAyZC0lMDJkICUwMmQ6JTAyZDolMDJkIiwgdGltZS53WWVhciwgdGltZS53TW9udGgsIHRpbWUud0RheSwgdGltZS53SG91ciwgdGltZS53TWludXRlLCB0aW1lLndTZWNvbmQpOwoJaWYgKG1fcERhdGVUaW1lKQoJewoJCW1fcERhdGVUaW1lLT5TZXRUZXh0KHN3VGltZSk7Cgl9CgoJdGhpcy0+UmVQb3NDaGlsZFduZCgpOwoKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25TZXREYXRlVGltZSh0aGlzKTsKCX0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRDb250ZW50cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc0NvbnRlbnRzKQp7CglpZiAobV9wQ29udGVudHMpCgl7CgkJbV9wQ29udGVudHMtPlNldFRleHQoc0NvbnRlbnRzKTsKCX0KCglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQoJewoJCXBOb3RpZnktPk9uU2V0Q29udGVudHModGhpcyk7Cgl9Cn0KCkNQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldFBhcmVudE5vdGVJdGVtKCkgY29uc3QKewoJaWYgKENQV0xfV25kKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpCgl7CgkJaWYgKENQV0xfV25kKiBwR3JhbmQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKSkKCQl7CgkJCUFTU0VSVChwR3JhbmQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7CgkJCXJldHVybiAoQ1BXTF9Ob3RlSXRlbSopcEdyYW5kOwoJCX0KCX0KCglyZXR1cm4gTlVMTDsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0UGFyZW50SXRlbSgpIGNvbnN0CnsKCXJldHVybiBHZXRQYXJlbnROb3RlSXRlbSgpOwp9CgpDUFdMX0VkaXQqIENQV0xfTm90ZUl0ZW06OkdldEVkaXQoKSBjb25zdAp7CglpZiAobV9wQ29udGVudHMpCgkJcmV0dXJuIG1fcENvbnRlbnRzLT5HZXRFZGl0KCk7CglyZXR1cm4gTlVMTDsKfQoKdm9pZCogQ1BXTF9Ob3RlSXRlbTo6R2V0UHJpdmF0ZURhdGEoKSBjb25zdAp7CglyZXR1cm4gbV9wUHJpdmF0ZURhdGE7Cn0KCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldEF1dGhvck5hbWUoKSBjb25zdAp7CglyZXR1cm4gbV9zQXV0aG9yOyAKfQoKQ1BXTF9Db2xvciBDUFdMX05vdGVJdGVtOjpHZXRCa0NvbG9yKCkgY29uc3QKewoJcmV0dXJuIHRoaXMtPkdldEJhY2tncm91bmRDb2xvcigpOwp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRDb250ZW50cygpIGNvbnN0CnsKCWlmIChtX3BDb250ZW50cykKCQlyZXR1cm4gbV9wQ29udGVudHMtPkdldFRleHQoKTsKCglyZXR1cm4gTCIiOwp9CgpGWF9TWVNURU1USU1FIENQV0xfTm90ZUl0ZW06OkdldERhdGVUaW1lKCkgY29uc3QKewoJcmV0dXJuIG1fZHROb3RlOwp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRTdWJqZWN0TmFtZSgpIGNvbnN0CnsKCWlmIChtX3BTdWJqZWN0KQoJCXJldHVybiBtX3BTdWJqZWN0LT5HZXRUZXh0KCk7CgoJcmV0dXJuIEwiIjsKfQoKQ1BXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6Q3JlYXRlTm90ZUl0ZW0oKQp7CglpZiAobV9wQ29udGVudHMpCgkJcmV0dXJuIG1fcENvbnRlbnRzLT5DcmVhdGVTdWJJdGVtKCk7CgoJcmV0dXJuIE5VTEw7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkNyZWF0ZVN1Ykl0ZW0oKQp7CglyZXR1cm4gQ3JlYXRlTm90ZUl0ZW0oKTsKfQoKRlhfSU5UMzIgQ1BXTF9Ob3RlSXRlbTo6Q291bnRTdWJJdGVtcygpIGNvbnN0CnsKCWlmIChtX3BDb250ZW50cykKCQlyZXR1cm4gbV9wQ29udGVudHMtPkNvdW50U3ViSXRlbXMoKTsKCglyZXR1cm4gMDsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0U3ViSXRlbXMoRlhfSU5UMzIgaW5kZXgpIGNvbnN0CnsKCWlmIChtX3BDb250ZW50cykKCQlyZXR1cm4gbV9wQ29udGVudHMtPkdldFN1Ykl0ZW1zKGluZGV4KTsKCglyZXR1cm4gTlVMTDsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpEZWxldGVTdWJJdGVtKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSkKewoJdGhpcy0+S2lsbEZvY3VzKCk7CgoJaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkKCXsKCQlwTm90aWZ5LT5Pbkl0ZW1EZWxldGUocE5vdGVJdGVtKTsKCX0KCglpZiAobV9wQ29udGVudHMpCgkJbV9wQ29udGVudHMtPkRlbGV0ZVN1Ykl0ZW0ocE5vdGVJdGVtKTsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0SGl0Tm90ZUl0ZW0oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCnsKCUNQREZfUG9pbnQgcHQgPSB0aGlzLT5QYXJlbnRUb0NoaWxkKHBvaW50KTsKCglpZiAodGhpcy0+V25kSGl0VGVzdChwdCkpCgl7CgkJaWYgKG1fcENvbnRlbnRzKQoJCXsKCQkJaWYgKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IG1fcENvbnRlbnRzLT5HZXRIaXROb3RlSXRlbShwdCkpCgkJCQlyZXR1cm4gcE5vdGVJdGVtOwoJCX0KCgkJcmV0dXJuIHRoaXM7Cgl9CgoJcmV0dXJuIE5VTEw7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldEZvY3VzZWROb3RlSXRlbSgpIGNvbnN0CnsKCWlmIChjb25zdCBDUFdMX1duZCogcFduZCA9IHRoaXMtPkdldEZvY3VzZWQoKSkKCXsKCQlpZiAocFduZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfRWRpdCIpCgkJewoJCQlpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBwV25kLT5HZXRQYXJlbnRXaW5kb3coKSkKCQkJewoJCQkJQVNTRVJUKHBQYXJlbnQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVfQ29udGVudHMiKTsKCQkJCQoJCQkJaWYgKENQV0xfV25kKiBwR3JhbmQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKSkKCQkJCXsKCQkJCQlBU1NFUlQocEdyYW5kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwkJCQkJCgkJCQkJcmV0dXJuIChDUFdMX05vdGVJdGVtKilwR3JhbmQ7CgkJCQl9CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIE5VTEw7Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZUl0ZW06OkdldEl0ZW1IZWlnaHQoRlhfRkxPQVQgZkxpbWl0V2lkdGgpCnsKCWlmIChmTGltaXRXaWR0aCA+IDApCgl7CgkJaWYgKCFtX2JTaXplQ2hhbmdlZCkKCQkJcmV0dXJuIG1fZk9sZEl0ZW1IZWlnaHQ7CgoJCW1fYlNpemVDaGFuZ2VkID0gRkFMU0U7CgoJCUFTU0VSVChtX3BTdWJqZWN0ICE9IE5VTEwpOwoJCUFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsKCQlBU1NFUlQobV9wQ29udGVudHMgIT0gTlVMTCk7CgoJCUZYX0ZMT0FUIGZSZXQgPSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKCQlGWF9GTE9BVCBmQm9yZGVyV2lkdGggPSAoRlhfRkxPQVQpdGhpcy0+R2V0Qm9yZGVyV2lkdGgoKTsKCQlpZiAoZkxpbWl0V2lkdGggPiBmQm9yZGVyV2lkdGggKiAyKQoJCQlmUmV0ICs9IG1fcENvbnRlbnRzLT5HZXRDb250ZW50c0hlaWdodChmTGltaXRXaWR0aCAtIGZCb3JkZXJXaWR0aCAqIDIpOwoJCWZSZXQgKz0gUE9QVVBfSVRFTV9IRUFEX0JPVFRPTSArIFBPUFVQX0lURU1fQk9UVE9NV0lEVEggKyBmQm9yZGVyV2lkdGggKiAyOwoKCQlyZXR1cm4gbV9mT2xkSXRlbUhlaWdodCA9IGZSZXQ7Cgl9CgoJcmV0dXJuIDA7Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZUl0ZW06OkdldEl0ZW1MZWZ0TWFyZ2luKCkKewoJcmV0dXJuIFBPUFVQX0lURU1fU0lERU1BUkdJTjsKfQoKRlhfRkxPQVQgQ1BXTF9Ob3RlSXRlbTo6R2V0SXRlbVJpZ2h0TWFyZ2luKCkKewoJcmV0dXJuIFBPUFVQX0lURU1fU0lERU1BUkdJTjsKfQoKRlhfQk9PTAlDUFdMX05vdGVJdGVtOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKewoJaWYgKCFtX3BDb250ZW50cy0+V25kSGl0VGVzdChtX3BDb250ZW50cy0+UGFyZW50VG9DaGlsZChwb2ludCkpKQoJewoJCVNldE5vdGVGb2N1cyhGQUxTRSk7Cgl9CgoJQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOwoKCXJldHVybiBUUlVFOwp9CgpGWF9CT09MCUNQV0xfTm90ZUl0ZW06Ok9uUkJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCnsKCWlmICghbV9wQ29udGVudHMtPlduZEhpdFRlc3QobV9wQ29udGVudHMtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkKCXsKCQlTZXROb3RlRm9jdXMoRkFMU0UpOwoJCVBvcHVwTm90ZUl0ZW1NZW51KHBvaW50KTsKCgkJcmV0dXJuIFRSVUU7Cgl9CgoJcmV0dXJuIENQV0xfV25kOjpPblJCdXR0b25VcChwb2ludCxuRmxhZyk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSwgRlhfSU5UUFRSIGxQYXJhbSkKewoJc3dpdGNoIChtc2cpCgl7CgljYXNlIFBOTV9OT1RFRURJVENIQU5HRUQ6CQoJCW1fYlNpemVDaGFuZ2VkID0gVFJVRTsKCgkJaWYgKENQV0xfV25kKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpCgkJewoJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKCQl9CgkJcmV0dXJuOwkKCWNhc2UgUE5NX1NFVENBUkVUSU5GTzoKCQlpZiAoUFdMX0NBUkVUX0lORk8gKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKQoJCXsKCQkJUFdMX0NBUkVUX0lORk8gbmV3SW5mbyA9ICpwSW5mbzsKCQkJbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7CgkJCW5ld0luZm8ucHRIZWFkID0gdGhpcy0+Q2hpbGRUb1BhcmVudChwSW5mby0+cHRIZWFkKTsKCQkJbmV3SW5mby5wdEZvb3QgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEZvb3QpOwoKCQkJaWYgKENQV0xfV25kICogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQoJCQl7CgkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUQ0FSRVRJTkZPLCAoRlhfSU5UUFRSKSZuZXdJbmZvLCAwKTsKCQkJfQoJCX0KCQlyZXR1cm47CgljYXNlIFBOTV9OT1RFUkVTRVQ6CgkJbV9iU2l6ZUNoYW5nZWQgPSBUUlVFOwoJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKCQkKCQlyZXR1cm47Cgl9CgoJQ1BXTF9XbmQ6Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlBvcHVwTm90ZUl0ZW1NZW51KGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQp7CglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQoJewoJCUZYX0lOVDMyIHgseTsKCQlQV0x0b1duZChwb2ludCwgeCwgeSk7CgkJaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU0ggPSBHZXRTeXN0ZW1IYW5kbGVyKCkpCgkJCXBTSC0+Q2xpZW50VG9TY3JlZW4oR2V0QXR0YWNoZWRIV25kKCksIHgsIHkpOwoJCXBOb3RpZnktPk9uUG9wdXBNZW51KHRoaXMsIHgsIHkpOwoJfQp9Cgpjb25zdCBDUFdMX05vdGUqIENQV0xfTm90ZUl0ZW06OkdldE5vdGUoKSBjb25zdAp7CglpZiAoY29uc3QgQ1BXTF9XbmQqIHBSb290ID0gdGhpcy0+R2V0Um9vdFduZCgpKQoJewoJCUFTU0VSVChwUm9vdC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKCQlDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcFJvb3Q7CgkJaWYgKHBOb3RlSXRlbS0+SXNUb3BJdGVtKCkpCgkJewoJCQlyZXR1cm4gKENQV0xfTm90ZSopcE5vdGVJdGVtOwoJCX0KCX0KCglyZXR1cm4gTlVMTDsKfQoKSVBXTF9Ob3RlTm90aWZ5KiBDUFdMX05vdGVJdGVtOjpHZXROb3RlTm90aWZ5KCkgY29uc3QKewoJaWYgKGNvbnN0IENQV0xfTm90ZSogcE5vdGUgPSBHZXROb3RlKCkpCgkJcmV0dXJuIHBOb3RlLT5HZXROb3RlTm90aWZ5KCk7CgoJcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6T25DcmVhdGVOb3RlSXRlbSgpCnsKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25JdGVtQ3JlYXRlKHRoaXMpOwoJfQp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06Ok9uQ29udGVudHNWYWxpZGF0ZSgpCnsKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25TZXRDb250ZW50cyh0aGlzKTsKCX0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXROb3RlRm9jdXMoRlhfQk9PTCBiTGFzdCkKewoJbV9wQ29udGVudHMtPlNldEVkaXRGb2N1cyhiTGFzdCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6RW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpCnsKCW1fcENvbnRlbnRzLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOwoJbV9iQWxsb3dNb2RpZnkgPSBiRW5hYmxlZDsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpFbmFibGVSZWFkKEZYX0JPT0wgYkVuYWJsZWQpCnsKCW1fcENvbnRlbnRzLT5FbmFibGVSZWFkKGJFbmFibGVkKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ1BXTF9Ob3RlOjpDUFdMX05vdGUoSVBvcHVwX05vdGUqIHBQb3B1cE5vdGUsIElQV0xfTm90ZU5vdGlmeSogcE5vdGVOb3RpZnksIElQV0xfTm90ZUhhbmRsZXIqIHBOb3RlSGFuZGxlcikgOiAKCW1fcEF1dGhvcihOVUxMKSwKCW1fcEljb24oTlVMTCksCgltX3BDbG9zZUJveChOVUxMKSwKCW1fcENvbnRlbnRzQmFyKE5VTEwpLAoJbV9wTEJCb3goTlVMTCksCgltX3BSQkJveChOVUxMKSwKCW1fcE9wdGlvbnMoTlVMTCksCgltX2JSZXNpemluZyhGQUxTRSksCgltX3JjQ2FwdGlvbigwLDAsMCwwKSwKCW1fcE5vdGVOb3RpZnkocE5vdGVOb3RpZnkpLAoJbV9iRW5hbGJsZU5vdGlmeShUUlVFKSwKCW1fcFBvcHVwTm90ZShwUG9wdXBOb3RlKSwKCW1fcE5vdGVIYW5kbGVyKHBOb3RlSGFuZGxlcikKewp9CgpDUFdMX05vdGU6On5DUFdMX05vdGUoKQp7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZTo6UmVwbHkoKQp7CglyZXR1cm4gQ3JlYXRlTm90ZUl0ZW0oKTsKfQoKdm9pZCBDUFdMX05vdGU6OkVuYWJsZU5vdGlmeShGWF9CT09MIGJFbmFibGVkKQp7CgltX2JFbmFsYmxlTm90aWZ5ID0gYkVuYWJsZWQ7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpSZVBvc0NoaWxkV25kKCkKewoJUmVQb3NOb3RlQ2hpbGRyZW4oKTsKCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKCVJlc2V0U2Nyb2xsQmFyKCk7CgltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7Cgl0aGlzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKCS8vzayyvQoJaWYgKGNvbnN0IENQV0xfV25kKiBwV25kID0gdGhpcy0+R2V0Rm9jdXNlZCgpKQoJewoJCWlmIChwV25kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9FZGl0IikKCQl7CgkJCUNQV0xfRWRpdCogcEVkaXQgPSAoQ1BXTF9FZGl0KilwV25kOwoJCQlwRWRpdC0+U2V0Q2FyZXQocEVkaXQtPkdldENhcmV0KCkpOwoJCX0KCX0KCS8vQ1BERl9Qb2ludCBwdE5ldyA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsKCS8vbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdE5ldy55KTsKfQoKRlhfQk9PTCBDUFdMX05vdGU6OlJlc2V0U2Nyb2xsQmFyKCkKewoJRlhfQk9PTCBiU2Nyb2xsQ2hhbmdlZCA9IEZBTFNFOwoKCWlmIChTY3JvbGxCYXJTaG91bGRWaXNpYmxlKCkpCgl7CgkJaWYgKCFtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpCgkJewoJCQltX3BDb250ZW50c0Jhci0+U2V0VmlzaWJsZShUUlVFKTsKCQkJaWYgKG1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkKCQkJewoJCQkJbV9wQ29udGVudHNCYXItPkludmFsaWRhdGVSZWN0KE5VTEwpOwoJCQkJYlNjcm9sbENoYW5nZWQgPSBUUlVFOwoJCQl9CgkJfQkKCX0KCWVsc2UKCXsKCQlpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQoJCXsKCQkJbV9wQ29udGVudHNCYXItPlNldFZpc2libGUoRkFMU0UpOwoJCQltX3BDb250ZW50c0Jhci0+SW52YWxpZGF0ZVJlY3QoTlVMTCk7CgoJCQliU2Nyb2xsQ2hhbmdlZCA9IFRSVUU7CgkJfQoJfQoKCWlmIChiU2Nyb2xsQ2hhbmdlZCkKCXsKCQlDUERGX1JlY3QgcmNOb3RlID0gdGhpcy0+R2V0Q2xpZW50UmVjdCgpOwoJCUNQREZfUmVjdCByY0NvbnRlbnRzID0gbV9wQ29udGVudHMtPkdldFdpbmRvd1JlY3QoKTsKCQlyY0NvbnRlbnRzLnJpZ2h0ID0gcmNOb3RlLnJpZ2h0IC0gMy4wZjsKCQlpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQoJCQlyY0NvbnRlbnRzLnJpZ2h0IC09IFBXTF9TQ1JPTExCQVJfV0lEVEg7CgkJbV9wQ29udGVudHMtPk1vdmUocmNDb250ZW50cywgVFJVRSwgVFJVRSk7CgkJbV9wQ29udGVudHMtPlNldFNjcm9sbFBvcyhDUERGX1BvaW50KDAuMGYsMC4wZikpOwoJCW1fcENvbnRlbnRzLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKCX0KCglyZXR1cm4gYlNjcm9sbENoYW5nZWQ7Cn0KCkZYX0JPT0wgQ1BXTF9Ob3RlOjpTY3JvbGxCYXJTaG91bGRWaXNpYmxlKCkKewoJQ1BERl9SZWN0IHJjQ29udGVudHNGYWN0ID0gbV9wQ29udGVudHMtPkdldFNjcm9sbEFyZWEoKTsKCUNQREZfUmVjdCByY0NvbnRlbnRzQ2xpZW50ID0gbV9wQ29udGVudHMtPkdldENsaWVudFJlY3QoKTsKCglyZXR1cm4gcmNDb250ZW50c0ZhY3QuSGVpZ2h0KCkgPiByY0NvbnRlbnRzQ2xpZW50LkhlaWdodCgpOwkKfQoKdm9pZCBDUFdMX05vdGU6OlNldE9wdGlvbnNUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGV4dCkKewoJaWYgKG1fcE9wdGlvbnMpCgkJbV9wT3B0aW9ucy0+U2V0VGV4dChzVGV4dCk7CgoJUmVQb3NOb3RlQ2hpbGRyZW4oKTsKfQoKdm9pZCBDUFdMX05vdGU6OlJlUG9zTm90ZUNoaWxkcmVuKCkKewoJaWYgKG1fYlJlc2l6aW5nKSByZXR1cm47CgoJbV9iUmVzaXppbmcgPSBUUlVFOwoKCWlmICh0aGlzLT5Jc1ZhbGlkKCkpCgl7CgkJQVNTRVJUKG1fcFN1YmplY3QgIT0gTlVMTCk7CgkJQVNTRVJUKG1fcERhdGVUaW1lICE9IE5VTEwpOwoJCUFTU0VSVChtX3BDb250ZW50cyAhPSBOVUxMKTsKCQlBU1NFUlQobV9wQXV0aG9yICE9IE5VTEwpOwoJCUFTU0VSVChtX3BDbG9zZUJveCAhPSBOVUxMKTsKCQlBU1NFUlQobV9wSWNvbiAhPSBOVUxMKTsKCQlBU1NFUlQobV9wTEJCb3ggIT0gTlVMTCk7CgkJQVNTRVJUKG1fcFJCQm94ICE9IE5VTEwpOwoJCUFTU0VSVChtX3BDb250ZW50c0JhciAhPSBOVUxMKTsKCQlBU1NFUlQobV9wT3B0aW9ucyAhPSBOVUxMKTsKCgkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOwoKCQlDUERGX1JlY3QgcmNJY29uID0gcmNDbGllbnQ7CgkJcmNJY29uLnRvcCAtPSAyLjBmOwoJCXJjSWNvbi5yaWdodCA9IHJjSWNvbi5sZWZ0ICsgMTQuMGY7CgkJcmNJY29uLmJvdHRvbSA9IHJjSWNvbi50b3AgLSAxNC4wZjsKCQlyY0ljb24uTm9ybWFsaXplKCk7CgkJbV9wSWNvbi0+TW92ZShyY0ljb24sIFRSVUUsIEZBTFNFKTsKCQltX3BJY29uLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNJY29uKSk7CgoJCUNQREZfUmVjdCByY0Nsb3NlQm94ID0gcmNDbGllbnQ7CgkJcmNDbG9zZUJveC5yaWdodCAtPSAxLjBmOwoJCXJjQ2xvc2VCb3gudG9wIC09IDEuMGY7CgkJcmNDbG9zZUJveC5sZWZ0ID0gcmNDbG9zZUJveC5yaWdodCAtIDE0LjBmOwoJCXJjQ2xvc2VCb3guYm90dG9tID0gcmNDbG9zZUJveC50b3AgLSAxNC4wZjsKCQlyY0Nsb3NlQm94Lk5vcm1hbGl6ZSgpOwoJCW1fcENsb3NlQm94LT5Nb3ZlKHJjQ2xvc2VCb3gsIFRSVUUsIEZBTFNFKTsKCQltX3BDbG9zZUJveC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjQ2xvc2VCb3gpKTsKCgkJQ1BERl9SZWN0IHJjRGF0ZSA9IHJjQ2xpZW50OwoJCXJjRGF0ZS5yaWdodCA9IHJjQ2xvc2VCb3gubGVmdCAtIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7CgkJcmNEYXRlLmxlZnQgPSBQV0xfTUFYKHJjRGF0ZS5yaWdodCAtIG1fcERhdGVUaW1lLT5HZXRDb250ZW50UmVjdCgpLldpZHRoKCkgLSAxLjBmLCByY0ljb24ucmlnaHQgKyAxLjBmKTsKCQlyY0RhdGUudG9wID0gcmNDbGllbnQudG9wIC0gMi4wZjsKCQlyY0RhdGUuYm90dG9tID0gcmNEYXRlLnRvcCAtIG1fcERhdGVUaW1lLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwoJCXJjRGF0ZS5Ob3JtYWxpemUoKTsKCQltX3BEYXRlVGltZS0+TW92ZShyY0RhdGUsIFRSVUUsIEZBTFNFKTsKCQltX3BEYXRlVGltZS0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjRGF0ZSkpOwoKCQlDUERGX1JlY3QgcmNTdWJqZWN0ID0gcmNDbGllbnQ7CgkJcmNTdWJqZWN0LnRvcCA9IHJjQ2xpZW50LnRvcCAtIDIuMGY7CgkJcmNTdWJqZWN0LmxlZnQgPSByY0ljb24ucmlnaHQgKyBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOwoJCXJjU3ViamVjdC5yaWdodCA9IFBXTF9NSU4ocmNTdWJqZWN0LmxlZnQgKyBtX3BTdWJqZWN0LT5HZXRDb250ZW50UmVjdCgpLldpZHRoKCkgKyAxLjBmLCByY0RhdGUubGVmdCAtIDEuMGYpOwoJCXJjU3ViamVjdC5ib3R0b20gPSByY1N1YmplY3QudG9wIC0gbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKCQlyY1N1YmplY3QuTm9ybWFsaXplKCk7CgkJbV9wU3ViamVjdC0+TW92ZShyY1N1YmplY3QsIFRSVUUsIEZBTFNFKTsJCgkJbV9wU3ViamVjdC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjU3ViamVjdCkpOwoKCQlDUERGX1JlY3QgcmNPcHRpb25zID0gcmNDbGllbnQ7CgkJcmNPcHRpb25zLmxlZnQgPSBQV0xfTUFYKHJjT3B0aW9ucy5yaWdodCAtIG1fcE9wdGlvbnMtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSwgcmNJY29uLnJpZ2h0ICsgMS4wZik7CgkJcmNPcHRpb25zLnRvcCA9IHJjU3ViamVjdC5ib3R0b20gLSA0LjBmOwoJCXJjT3B0aW9ucy5ib3R0b20gPSByY09wdGlvbnMudG9wIC0gbV9wT3B0aW9ucy0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKCQlyY09wdGlvbnMuTm9ybWFsaXplKCk7CgkJbV9wT3B0aW9ucy0+TW92ZShyY09wdGlvbnMsIFRSVUUsIEZBTFNFKTsKCQltX3BPcHRpb25zLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNPcHRpb25zKSk7CgoJCUNQREZfUmVjdCByY0F1dGhvciA9IHJjQ2xpZW50OwoJCXJjQXV0aG9yLnRvcCA9IHJjU3ViamVjdC5ib3R0b20gLSA0LjBmOwoJCXJjQXV0aG9yLmxlZnQgPSByY1N1YmplY3QubGVmdDsKCQlyY0F1dGhvci5yaWdodCA9IFBXTF9NSU4ocmNTdWJqZWN0LmxlZnQgKyBtX3BBdXRob3ItPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSArIDEuMGYsIHJjT3B0aW9ucy5sZWZ0IC0gMS4wZik7CgkJcmNBdXRob3IuYm90dG9tID0gcmNBdXRob3IudG9wIC0gbV9wQXV0aG9yLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwoJCXJjQXV0aG9yLk5vcm1hbGl6ZSgpOwoJCW1fcEF1dGhvci0+TW92ZShyY0F1dGhvciwgVFJVRSwgRkFMU0UpOwoJCW1fcEF1dGhvci0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjQXV0aG9yKSk7CgoJCUNQREZfUmVjdCByY0xCQm94ID0gcmNDbGllbnQ7CgkJcmNMQkJveC50b3AgPSByY0xCQm94LmJvdHRvbSArIDcuMGY7CgkJcmNMQkJveC5yaWdodCA9IHJjTEJCb3gubGVmdCArIDcuMGY7CgkJcmNMQkJveC5Ob3JtYWxpemUoKTsKCQltX3BMQkJveC0+TW92ZShyY0xCQm94LCBUUlVFLCBGQUxTRSk7CgkJbV9wTEJCb3gtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0xCQm94KSk7CgoJCUNQREZfUmVjdCByY1JCQm94ID0gcmNDbGllbnQ7CgkJcmNSQkJveC50b3AgPSByY1JCQm94LmJvdHRvbSArIDcuMGY7CgkJcmNSQkJveC5sZWZ0ID0gcmNSQkJveC5yaWdodCAtIDcuMGY7CgkJcmNSQkJveC5Ob3JtYWxpemUoKTsKCQltX3BSQkJveC0+TW92ZShyY1JCQm94LCBUUlVFLCBGQUxTRSk7CgkJbV9wUkJCb3gtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY1JCQm94KSk7CgoJCUNQREZfUmVjdCByY0NvbnRlbnRzID0gcmNDbGllbnQ7CgkJcmNDb250ZW50cy50b3AgPSByY0F1dGhvci5ib3R0b20gLSBQT1BVUF9JVEVNX0hFQURfQk9UVE9NOwoJCXJjQ29udGVudHMubGVmdCArPSAzLjBmOwoJCXJjQ29udGVudHMucmlnaHQgLT0gMy4wZjsKCQlpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQoJCQlyY0NvbnRlbnRzLnJpZ2h0IC09IFBXTF9TQ1JPTExCQVJfV0lEVEg7CgkJcmNDb250ZW50cy5ib3R0b20gKz0gMTQuMGY7CgkJcmNDb250ZW50cy5Ob3JtYWxpemUoKTsKCQltX3BDb250ZW50cy0+TW92ZShyY0NvbnRlbnRzLCBGQUxTRSwgRkFMU0UpOwoJCW1fcENvbnRlbnRzLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNDb250ZW50cykpOwoKCQlDUERGX1JlY3QgcmNDb250ZW50c0JhciA9IHJjQ29udGVudHM7CgkJcmNDb250ZW50c0Jhci5yaWdodCA9IHJjQ2xpZW50LnJpZ2h0IC0gMy4wZjsKCQlyY0NvbnRlbnRzQmFyLmxlZnQgPSByY0NvbnRlbnRzQmFyLnJpZ2h0IC0gUFdMX1NDUk9MTEJBUl9XSURUSDsKCQlyY0NvbnRlbnRzQmFyLk5vcm1hbGl6ZSgpOwoJCW1fcENvbnRlbnRzQmFyLT5Nb3ZlKHJjQ29udGVudHNCYXIsIFRSVUUsIEZBTFNFKTsKCQkKCQltX3JjQ2FwdGlvbiA9IHJjQ2xpZW50OwoJCW1fcmNDYXB0aW9uLmJvdHRvbSA9IHJjQ29udGVudHMudG9wOwoJfQoKCW1fYlJlc2l6aW5nID0gRkFMU0U7Cn0KCi8vMC1ub3JtYWwgLyAxLWNhcHRpb24gLyAyLWxlZnRib3R0b20gY29ybmVyIC8gMy1yaWdodGJvdHRvbSBjb3JuZXIgLyA0LWNsb3NlIC8gNS1vcHRpb25zIApGWF9JTlQzMiBDUFdMX05vdGU6Ok5vdGVIaXRUZXN0KGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSBjb25zdAp7CglBU1NFUlQobV9wU3ViamVjdCAhPSBOVUxMKTsKCUFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsKCUFTU0VSVChtX3BDb250ZW50cyAhPSBOVUxMKTsKCUFTU0VSVChtX3BBdXRob3IgIT0gTlVMTCk7CglBU1NFUlQobV9wSWNvbiAhPSBOVUxMKTsKCUFTU0VSVChtX3BDb250ZW50c0JhciAhPSBOVUxMKTsKCglBU1NFUlQobV9wQ2xvc2VCb3ggIT0gTlVMTCk7CglBU1NFUlQobV9wTEJCb3ggIT0gTlVMTCk7CglBU1NFUlQobV9wUkJCb3ggIT0gTlVMTCk7CglBU1NFUlQobV9wT3B0aW9ucyAhPSBOVUxMKTsKCglHZXRDbGllbnRSZWN0KCk7CgoJaWYgKG1fcFN1YmplY3QtPlduZEhpdFRlc3QobV9wU3ViamVjdC0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMTsKCWlmIChtX3BEYXRlVGltZS0+V25kSGl0VGVzdChtX3BEYXRlVGltZS0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMTsKCWlmIChtX3BBdXRob3ItPlduZEhpdFRlc3QobV9wQXV0aG9yLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAxOwoJaWYgKG1fcEljb24tPlduZEhpdFRlc3QobV9wSWNvbi0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMTsKCglpZiAobV9wQ29udGVudHMtPlduZEhpdFRlc3QobV9wQ29udGVudHMtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDA7CglpZiAobV9wQ29udGVudHNCYXItPlduZEhpdFRlc3QobV9wQ29udGVudHNCYXItPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDA7CgoJaWYgKG1fcENsb3NlQm94LT5XbmRIaXRUZXN0KG1fcENsb3NlQm94LT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiA0OwoJaWYgKG1fcExCQm94LT5XbmRIaXRUZXN0KG1fcExCQm94LT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAyOwoJaWYgKG1fcFJCQm94LT5XbmRIaXRUZXN0KG1fcFJCQm94LT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAzOwoJaWYgKG1fcE9wdGlvbnMtPlduZEhpdFRlc3QobV9wT3B0aW9ucy0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gNTsKCglyZXR1cm4gMTsKfQoKdm9pZCBDUFdMX05vdGU6OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQp7CglDUFdMX05vdGVJdGVtOjpDcmVhdGVDaGlsZFduZChjcCk7CgoJQ1BXTF9Db2xvciBzVGV4dENvbG9yOwoKCWlmIChDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZSh0aGlzLT5HZXRCYWNrZ3JvdW5kQ29sb3IoKSkpCgkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CgllbHNlCgkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7CgoJbV9wQXV0aG9yID0gbmV3IENQV0xfTGFiZWw7CglQV0xfQ1JFQVRFUEFSQU0gYWNwID0gY3A7CglhY3AucFBhcmVudFduZCA9IHRoaXM7CglhY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUEVTX0xFRlQgfCBQRVNfVE9QOwoJYWNwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOwoJbV9wQXV0aG9yLT5DcmVhdGUoYWNwKTsJIAoKCW1fcENsb3NlQm94ID0gbmV3IENQV0xfTm90ZV9DbG9zZUJveDsKCVBXTF9DUkVBVEVQQVJBTSBjY3AgPSBjcDsKCWNjcC5wUGFyZW50V25kID0gdGhpczsKCWNjcC5kd0JvcmRlcldpZHRoID0gMjsKCWNjcC5uQm9yZGVyU3R5bGUgPSBQQlNfQkVWRUxFRDsKCWNjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQV1NfQk9SREVSOwoJY2NwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOwoJbV9wQ2xvc2VCb3gtPkNyZWF0ZShjY3ApOwoKCW1fcEljb24gPSBuZXcgQ1BXTF9Ob3RlX0ljb247CglQV0xfQ1JFQVRFUEFSQU0gaWNwID0gY3A7CglpY3AucFBhcmVudFduZCA9IHRoaXM7CglpY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEOwoJbV9wSWNvbi0+Q3JlYXRlKGljcCk7CgoJbV9wT3B0aW9ucyA9IG5ldyBDUFdMX05vdGVfT3B0aW9uczsKCVBXTF9DUkVBVEVQQVJBTSBvY3AgPSBjcDsKCW9jcC5wUGFyZW50V25kID0gdGhpczsKCW9jcC5kd0ZsYWdzID0gUFdTX0NISUxEIHwgUFdTX1ZJU0lCTEU7CglvY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CgltX3BPcHRpb25zLT5DcmVhdGUob2NwKTsKCgltX3BMQkJveCA9IG5ldyBDUFdMX05vdGVfTEJCb3g7CglQV0xfQ1JFQVRFUEFSQU0gbGNwID0gY3A7CglsY3AucFBhcmVudFduZCA9IHRoaXM7CglsY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEOwoJbGNwLmVDdXJzb3JUeXBlID0gRlhDVF9ORVNXOwoJbGNwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOwoJbV9wTEJCb3gtPkNyZWF0ZShsY3ApOwoKCW1fcFJCQm94ID0gbmV3IENQV0xfTm90ZV9SQkJveDsKCVBXTF9DUkVBVEVQQVJBTSByY3AgPSBjcDsKCXJjcC5wUGFyZW50V25kID0gdGhpczsKCXJjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQ7CglyY3AuZUN1cnNvclR5cGUgPSBGWENUX05XU0U7CglyY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CgltX3BSQkJveC0+Q3JlYXRlKHJjcCk7CgoJbV9wQ29udGVudHNCYXIgPSBuZXcgQ1BXTF9TY3JvbGxCYXIoU0JUX1ZTQ1JPTEwpOwoJUFdMX0NSRUFURVBBUkFNIHNjcCA9IGNwOwoJc2NwLnBQYXJlbnRXbmQgPSB0aGlzOwoJc2NwLnNCYWNrZ3JvdW5kQ29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIDI0MC8yNTUuMGYsIDI0MC8yNTUuMGYsIDI0MC8yNTUuMGYpOwoJc2NwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRSB8IFBXU19CQUNLR1JPVU5EOwoJbV9wQ29udGVudHNCYXItPkNyZWF0ZShzY3ApOwoJbV9wQ29udGVudHNCYXItPlNldE5vdGlmeUZvcmV2ZXIoVFJVRSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpTZXRTdWJqZWN0TmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpCnsKCUNQV0xfTm90ZUl0ZW06OlNldFN1YmplY3ROYW1lKHNOYW1lKTsKCVJlUG9zQ2hpbGRXbmQoKTsKfQoKdm9pZCBDUFdMX05vdGU6OlNldEF1dGhvck5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNOYW1lKQp7CglpZiAobV9wQXV0aG9yKQoJewoJCW1fcEF1dGhvci0+U2V0VGV4dChzTmFtZSk7CgkJUmVQb3NDaGlsZFduZCgpOwoJfQoKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25TZXRBdXRob3JOYW1lKHRoaXMpOwoJfQkKfQoKQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9Ob3RlOjpHZXRBdXRob3JOYW1lKCkgY29uc3QKewoJaWYgKG1fcEF1dGhvcikKCQlyZXR1cm4gbV9wQXV0aG9yLT5HZXRUZXh0KCk7CgoJcmV0dXJuIEwiIjsKfQoKRlhfQk9PTCBDUFdMX05vdGU6Ok9uTW91c2VXaGVlbChzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCnsKCUNQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7CglDUERGX1JlY3QgcmNTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsQXJlYSgpOwoJQ1BERl9SZWN0IHJjQ29udGVudHMgPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpOwoKCWlmIChyY1Njcm9sbC50b3AgLSByY1Njcm9sbC5ib3R0b20gPiByY0NvbnRlbnRzLkhlaWdodCgpKQoJewoJCUNQREZfUG9pbnQgcHROZXcgPSBwdFNjcm9sbDsKCgkJaWYgKHpEZWx0YSA+IDApCgkJCXB0TmV3LnkgKz0gMzA7CgkJZWxzZQoJCQlwdE5ldy55IC09IDMwOwoKCQlpZiAocHROZXcueSA+IHJjU2Nyb2xsLnRvcCkKCQkJcHROZXcueSA9IHJjU2Nyb2xsLnRvcDsKCQlpZiAocHROZXcueSA8IHJjU2Nyb2xsLmJvdHRvbSArIHJjQ29udGVudHMuSGVpZ2h0KCkpCgkJCXB0TmV3LnkgPSByY1Njcm9sbC5ib3R0b20gKyByY0NvbnRlbnRzLkhlaWdodCgpOwoJCWlmIChwdE5ldy55IDwgcmNTY3JvbGwuYm90dG9tKQoJCQlwdE5ldy55ID0gcmNTY3JvbGwuYm90dG9tOwoKCQlpZiAocHROZXcueSAhPSBwdFNjcm9sbC55KQoJCXsKCQkJbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOwoJCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0TmV3LnkpOwkJCQoJCQltX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0TmV3LnkpOwoKCQkJcmV0dXJuIFRSVUU7CgkJfQoJfQoKCXJldHVybiBGQUxTRTsKfQoKdm9pZCBDUFdMX05vdGU6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0sIEZYX0lOVFBUUiBsUGFyYW0pCnsKCXN3aXRjaCAobXNnKQoJewoJY2FzZSBQTk1fTk9URUVESVRDSEFOR0VEOgoJCXsKCQkJQ1BERl9SZWN0IHJjU2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbEFyZWEoKTsKCQkJCgoJCQlQV0xfU0NST0xMX0lORk8gc0luZm87CgkJCXNJbmZvLmZDb250ZW50TWluID0gcmNTY3JvbGwuYm90dG9tOwoJCQlzSW5mby5mQ29udGVudE1heCA9IHJjU2Nyb2xsLnRvcDsKCQkJc0luZm8uZlBsYXRlV2lkdGggPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpLkhlaWdodCgpOwoJCQlzSW5mby5mU21hbGxTdGVwID0gMTMuMGY7CgkJCXNJbmZvLmZCaWdTdGVwID0gc0luZm8uZlBsYXRlV2lkdGg7CgoJCQlpZiAoRlhTWVNfbWVtY21wKCZtX09sZFNjcm9sbEluZm8sICZzSW5mbywgc2l6ZW9mKFBXTF9TQ1JPTExfSU5GTykpICE9IDApCgkJCXsKCQkJCUZYX0JPT0wgYlNjcm9sbENoYW5nZWQgPSBGQUxTRTsKCgkJCQlpZiAobFBhcmFtIDwgMykgLy+3wNa5y8DRrbu3IG1hbnRpczoxNTc1OQoJCQkJewoJCQkJCWJTY3JvbGxDaGFuZ2VkID0gUmVzZXRTY3JvbGxCYXIoKTsKCQkJCQlpZiAoYlNjcm9sbENoYW5nZWQpCgkJCQkJewoJCQkJCQlsUGFyYW0rKzsKCQkJCQkJbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOwoJCQkJCQl0aGlzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCBsUGFyYW0pOwoJCQkJCX0KCQkJCX0KCQkJCQoJCQkJaWYgKCFiU2Nyb2xsQ2hhbmdlZCkKCQkJCXsKCQkJCQlpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQoJCQkJCXsKCQkJCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHBXbmQsIFBOTV9TRVRTQ1JPTExJTkZPLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmc0luZm8pOwoJCQkJCQltX09sZFNjcm9sbEluZm8gPSBzSW5mbzsKCgkJCQkJCUNQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7CgkJCQkJCUNQREZfUG9pbnQgcHRPbGQgPSBwdFNjcm9sbDsKCgkJCQkJCWlmIChwdFNjcm9sbC55ID4gc0luZm8uZkNvbnRlbnRNYXgpCgkJCQkJCQlwdFNjcm9sbC55ID0gc0luZm8uZkNvbnRlbnRNYXg7CgkJCQkJCWlmIChwdFNjcm9sbC55IDwgc0luZm8uZkNvbnRlbnRNaW4gKyBzSW5mby5mUGxhdGVXaWR0aCkKCQkJCQkJCXB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1pbiArIHNJbmZvLmZQbGF0ZVdpZHRoOwoJCQkJCQlpZiAocHRTY3JvbGwueSA8IHNJbmZvLmZDb250ZW50TWluKQoJCQkJCQkJcHRTY3JvbGwueSA9IHNJbmZvLmZDb250ZW50TWluOwoKCQkJCQkJaWYgKHB0T2xkLnkgIT0gcHRTY3JvbGwueSkKCQkJCQkJewoJCQkJCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdFNjcm9sbC55KTsKCQkJCQkJCW1fcENvbnRlbnRzQmFyLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKCQkJCQkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHRTY3JvbGwueSk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCW1fcENvbnRlbnRzLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKCgkJcmV0dXJuOwoJY2FzZSBQTk1fU0NST0xMV0lORE9XOgoJCWlmIChtX3BDb250ZW50cykKCQkJbV9wQ29udGVudHMtPk9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOwoJCXJldHVybjsKCWNhc2UgUE5NX1NFVFNDUk9MTFBPUzoKCQlpZiAobV9wQ29udGVudHNCYXIpCgkJCW1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeShwV25kLFBOTV9TRVRTQ1JPTExQT1Msd1BhcmFtLGxQYXJhbSk7CgkJcmV0dXJuOwoJfQoKCWlmIChtc2cgPT0gUE5NX1NFVENBUkVUSU5GTyAmJiBJc1ZhbGlkKCkpCgl7CgkJaWYgKFBXTF9DQVJFVF9JTkZPICogcEluZm8gPSAoUFdMX0NBUkVUX0lORk8qKXdQYXJhbSkKCQl7CgkJCWlmIChtX3BDb250ZW50cykKCQkJewoJCQkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gbV9wQ29udGVudHMtPkdldENsaWVudFJlY3QoKTsKCQkJCWlmIChwSW5mby0+cHRIZWFkLnkgPiByY0NsaWVudC50b3ApCgkJCQl7CgkJCQkJQ1BERl9Qb2ludCBwdCA9IG1fcENvbnRlbnRzLT5PdXRUb0luKHBJbmZvLT5wdEhlYWQpOwoJCQkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHQueSk7CgoJCQkJCUNQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7CgkJCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdFNjcm9sbC55KTsKCgkJCQkJcmV0dXJuOwoJCQkJfQoJCQkJCgkJCQlpZiAocEluZm8tPnB0Rm9vdC55IDwgcmNDbGllbnQuYm90dG9tKQoJCQkJewoJCQkJCUNQREZfUG9pbnQgcHQgPSBtX3BDb250ZW50cy0+T3V0VG9JbihwSW5mby0+cHRGb290KTsKCQkJCQlwdC55ICs9IHJjQ2xpZW50LkhlaWdodCgpOwoJCQkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHQueSk7CgoJCQkJCUNQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7CgkJCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdFNjcm9sbC55KTsKCgkJCQkJcmV0dXJuOwoJCQkJfQoJCQl9CgkJfQoJfQoKCUNQV0xfTm90ZUl0ZW06Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOwp9Cgp2b2lkIENQV0xfTm90ZTo6U2V0QmtDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcikKewoJQ1BXTF9Ob3RlSXRlbTo6U2V0QmtDb2xvcihjb2xvcik7CgoJQ1BXTF9Db2xvciBzQksgPSBjb2xvcjsKCUNQV0xfQ29sb3Igc1RleHRDb2xvcjsKCWlmIChDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZShzQkspKQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9XSElURUNPTE9SOwoJZWxzZQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9CTEFDS0NPTE9SOwoKCWlmIChtX3BDbG9zZUJveCkKCQltX3BDbG9zZUJveC0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOwoJaWYgKG1fcEF1dGhvcikKCQltX3BBdXRob3ItPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKCWlmIChtX3BPcHRpb25zKQoJCW1fcE9wdGlvbnMtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKCWlmIChtX3BMQkJveCkKCQltX3BMQkJveC0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOwoJaWYgKG1fcFJCQm94KQoJCW1fcFJCQm94LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7Cn0KCkZYX0JPT0wJQ1BXTF9Ob3RlOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKewoJaWYgKG1fcE9wdGlvbnMtPlduZEhpdFRlc3QobV9wT3B0aW9ucy0+UGFyZW50VG9DaGlsZChwb2ludCkpKQoJewoJCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSB0aGlzLT5HZXROb3RlTm90aWZ5KCkpCgkJewoJCQlGWF9JTlQzMiB4LCB5OwoJCQlQV0x0b1duZChwb2ludCwgeCwgeSk7CgkJCWlmIChJRlhfU3lzdGVtSGFuZGxlciogcFNIID0gR2V0U3lzdGVtSGFuZGxlcigpKQoJCQkJcFNILT5DbGllbnRUb1NjcmVlbihHZXRBdHRhY2hlZEhXbmQoKSwgeCwgeSk7CgkJCXRoaXMtPktpbGxGb2N1cygpOwoJCQlwTm90aWZ5LT5PblBvcHVwTWVudSh4LCB5KTsKCgkJCXJldHVybiBUUlVFOwoJCX0KCX0KCglyZXR1cm4gQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOwp9CgpGWF9CT09MCUNQV0xfTm90ZTo6T25SQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKewoJcmV0dXJuIENQV0xfV25kOjpPblJCdXR0b25VcChwb2ludCxuRmxhZyk7Cn0KCmNvbnN0IENQV0xfTm90ZSogQ1BXTF9Ob3RlOjpHZXROb3RlKCkgY29uc3QKewoJcmV0dXJuIHRoaXM7Cn0KCklQV0xfTm90ZU5vdGlmeSogQ1BXTF9Ob3RlOjpHZXROb3RlTm90aWZ5KCkgY29uc3QKewoJaWYgKG1fYkVuYWxibGVOb3RpZnkpCgkJcmV0dXJuIG1fcE5vdGVOb3RpZnk7CgoJcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpTZXRJY29uVHlwZShGWF9JTlQzMiBuVHlwZSkKewoJaWYgKG1fcEljb24pCgkJbV9wSWNvbi0+U2V0SWNvblR5cGUoblR5cGUpOwp9Cgp2b2lkIENQV0xfTm90ZTo6RW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpCnsKCW1fcENvbnRlbnRzLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOwp9Cgp2b2lkIENQV0xfTm90ZTo6RW5hYmxlUmVhZChGWF9CT09MIGJFbmFibGVkKQp7CgltX3BDb250ZW50cy0+RW5hYmxlUmVhZChiRW5hYmxlZCk7Cn0KCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZTo6R2V0UmVwbHlTdHJpbmcoKSBjb25zdAp7CglyZXR1cm4gbV9zUmVwbHlTdHJpbmc7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpTZXRSZXBseVN0cmluZyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nKQp7CgltX3NSZXBseVN0cmluZyA9IHN0cmluZzsKfQoK