Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCgojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCIKI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0J1dHRvbi5oIgojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQ2FyZXQuaCIKI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXQuaCIKI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXQuaCIKI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXRDdHJsLmgiCiNpbmNsdWRlICJmcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9MYWJlbC5oIgojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGlzdEN0cmwuaCIKI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX05vdGUuaCIKI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5oIgojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmgiCiNpbmNsdWRlICJmcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oIgojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfV25kLmgiCgojZGVmaW5lIFBPUFVQX0lURU1fSEVBRF9CT1RUT00gMy4wZgojZGVmaW5lIFBPUFVQX0lURU1fQk9UVE9NV0lEVEggMS4wZgojZGVmaW5lIFBPUFVQX0lURU1fU0lERU1BUkdJTiAzLjBmCiNkZWZpbmUgUE9QVVBfSVRFTV9TUEFDRSA0LjBmCiNkZWZpbmUgUE9QVVBfSVRFTV9URVhUX0lOREVOVCAyLjBmCiNkZWZpbmUgUE9QVVBfSVRFTV9CT1JERVJDT0xPUiBcCiAgQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLCA4MCAvIDI1NS4wZiwgODAgLyAyNTUuMGYsIDgwIC8gMjU1LjBmKQoKI2RlZmluZSBJc0Zsb2F0WmVybyhmKSAoKGYpIDwgMC4wMDAxICYmIChmKSA+IC0wLjAwMDEpCiNkZWZpbmUgSXNGbG9hdEJpZ2dlcihmYSwgZmIpICgoZmEpID4gKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQojZGVmaW5lIElzRmxvYXRTbWFsbGVyKGZhLCBmYikgKChmYSkgPCAoZmIpICYmICFJc0Zsb2F0WmVybygoZmEpIC0gKGZiKSkpCiNkZWZpbmUgSXNGbG9hdEVxdWFsKGZhLCBmYikgSXNGbG9hdFplcm8oKGZhKSAtIChmYikpCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9PcHRpb25zCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCkNQV0xfTm90ZV9PcHRpb25zOjpDUFdMX05vdGVfT3B0aW9ucygpIDogbV9wVGV4dChOVUxMKSB7fQoKQ1BXTF9Ob3RlX09wdGlvbnM6On5DUFdMX05vdGVfT3B0aW9ucygpIHt9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpTZXRUZXh0Q29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpIHsKICBDUFdMX1duZDo6U2V0VGV4dENvbG9yKGNvbG9yKTsKCiAgaWYgKG1fcFRleHQpCiAgICBtX3BUZXh0LT5TZXRUZXh0Q29sb3IoY29sb3IpOwp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpSZVBvc0NoaWxkV25kKCkgewogIGlmIChJc1ZhbGlkKCkpIHsKICAgIENQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKCiAgICBpZiAocmNDbGllbnQuV2lkdGgoKSA+IDE1LjBmKSB7CiAgICAgIHJjQ2xpZW50LnJpZ2h0IC09IDE1LjBmOwogICAgICBtX3BUZXh0LT5Nb3ZlKHJjQ2xpZW50LCBUUlVFLCBGQUxTRSk7CiAgICAgIG1fcFRleHQtPlNldFZpc2libGUoVFJVRSk7CiAgICB9IGVsc2UgewogICAgICBtX3BUZXh0LT5Nb3ZlKENQREZfUmVjdCgwLCAwLCAwLCAwKSwgVFJVRSwgRkFMU0UpOwogICAgICBtX3BUZXh0LT5TZXRWaXNpYmxlKEZBTFNFKTsKICAgIH0KICB9Cn0KCnZvaWQgQ1BXTF9Ob3RlX09wdGlvbnM6OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3ApIHsKICBtX3BUZXh0ID0gbmV3IENQV0xfTGFiZWw7CiAgUFdMX0NSRUFURVBBUkFNIHRjcCA9IGNwOwogIHRjcC5wUGFyZW50V25kID0gdGhpczsKICB0Y3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFOwogIG1fcFRleHQtPkNyZWF0ZSh0Y3ApOwp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpTZXRUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGV4dCkgewogIG1fcFRleHQtPlNldFRleHQoc1RleHQuY19zdHIoKSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlX09wdGlvbnM6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ZYX01hdHJpeCogcFVzZXIyRGV2aWNlKSB7CiAgQ1BXTF9XbmQ6OkRyYXdUaGlzQXBwZWFyYW5jZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UpOwoKICBDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CiAgcmNDbGllbnQubGVmdCA9IHJjQ2xpZW50LnJpZ2h0IC0gMTUuMGY7CgogIENQREZfUG9pbnQgcHRDZW50ZXIgPSBDUERGX1BvaW50KChyY0NsaWVudC5sZWZ0ICsgcmNDbGllbnQucmlnaHQpICogMC41ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmNDbGllbnQudG9wICsgcmNDbGllbnQuYm90dG9tKSAqIDAuNWYpOwoKICBDUERGX1BvaW50IHB0MShwdENlbnRlci54IC0gMi4wZiwgcHRDZW50ZXIueSArIDIuMGYgKiAwLjVmKTsKICBDUERGX1BvaW50IHB0MihwdENlbnRlci54ICsgMi4wZiwgcHRDZW50ZXIueSArIDIuMGYgKiAwLjVmKTsKICBDUERGX1BvaW50IHB0MyhwdENlbnRlci54LCBwdENlbnRlci55IC0gMy4wZiAqIDAuNWYpOwoKICBDRlhfUGF0aERhdGEgcGF0aDsKCiAgcGF0aC5TZXRQb2ludENvdW50KDQpOwogIHBhdGguU2V0UG9pbnQoMCwgcHQxLngsIHB0MS55LCBGWFBUX01PVkVUTyk7CiAgcGF0aC5TZXRQb2ludCgxLCBwdDIueCwgcHQyLnksIEZYUFRfTElORVRPKTsKICBwYXRoLlNldFBvaW50KDIsIHB0My54LCBwdDMueSwgRlhQVF9MSU5FVE8pOwogIHBhdGguU2V0UG9pbnQoMywgcHQxLngsIHB0MS55LCBGWFBUX0xJTkVUTyk7CgogIHBEZXZpY2UtPkRyYXdQYXRoKAogICAgICAmcGF0aCwgcFVzZXIyRGV2aWNlLCBOVUxMLAogICAgICBDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSwgR2V0VHJhbnNwYXJlbmN5KCkpLCAwLAogICAgICBGWEZJTExfQUxURVJOQVRFKTsKfQoKQ1BERl9SZWN0IENQV0xfTm90ZV9PcHRpb25zOjpHZXRDb250ZW50UmVjdCgpIGNvbnN0IHsKICBDUERGX1JlY3QgcmNUZXh0ID0gbV9wVGV4dC0+R2V0Q29udGVudFJlY3QoKTsKICByY1RleHQucmlnaHQgKz0gMTUuMGY7CiAgcmV0dXJuIHJjVGV4dDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfRWRpdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCgpDUFdMX05vdGVfRWRpdDo6Q1BXTF9Ob3RlX0VkaXQoKQogICAgOiBtX2JFbmFibGVOb3RpZnkoVFJVRSksCiAgICAgIG1fZk9sZEl0ZW1IZWlnaHQoMC4wZiksCiAgICAgIG1fYlNpemVDaGFuZ2VkKEZBTFNFKSwKICAgICAgbV9mT2xkTWluKDAuMGYpLAogICAgICBtX2ZPbGRNYXgoMC4wZikge30KCkNQV0xfTm90ZV9FZGl0Ojp+Q1BXTF9Ob3RlX0VkaXQoKSB7fQoKdm9pZCBDUFdMX05vdGVfRWRpdDo6UmVQb3NDaGlsZFduZCgpIHsKICBtX2JFbmFibGVOb3RpZnkgPSBGQUxTRTsKICBDUFdMX0VkaXQ6OlJlUG9zQ2hpbGRXbmQoKTsKICBtX2JFbmFibGVOb3RpZnkgPSBUUlVFOwoKICBtX2ZPbGRJdGVtSGVpZ2h0ID0gR2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKfQoKdm9pZCBDUFdMX05vdGVfRWRpdDo6U2V0VGV4dChjb25zdCBGWF9XQ0hBUiogY3NUZXh0KSB7CiAgbV9iRW5hYmxlTm90aWZ5ID0gRkFMU0U7CiAgQ1BXTF9FZGl0OjpTZXRUZXh0KGNzVGV4dCk7CiAgbV9iRW5hYmxlTm90aWZ5ID0gVFJVRTsKICBtX2ZPbGRJdGVtSGVpZ2h0ID0gR2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKfQoKdm9pZCBDUFdMX05vdGVfRWRpdDo6T25TZXRGb2N1cygpIHsKICBtX2JFbmFibGVOb3RpZnkgPSBGQUxTRTsKICBDUFdMX0VkaXQ6Ok9uU2V0Rm9jdXMoKTsKICBtX2JFbmFibGVOb3RpZnkgPSBUUlVFOwoKICBFbmFibGVTcGVsbENoZWNrKFRSVUUpOwp9Cgp2b2lkIENQV0xfTm90ZV9FZGl0OjpPbktpbGxGb2N1cygpIHsKICBFbmFibGVTcGVsbENoZWNrKEZBTFNFKTsKCiAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpIHsKICAgIGlmIChDUFdMX1duZCogcEdyYW5kID0gcFBhcmVudC0+R2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgQVNTRVJUKHBHcmFuZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKCiAgICAgIENQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwR3JhbmQ7CgogICAgICBwTm90ZUl0ZW0tPk9uQ29udGVudHNWYWxpZGF0ZSgpOwogICAgfQogIH0KCiAgQ1BXTF9FZGl0OjpPbktpbGxGb2N1cygpOwp9Cgp2b2lkIENQV0xfTm90ZV9FZGl0OjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgbXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRwdHJfdCB3UGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHB0cl90IGxQYXJhbSkgewogIGlmIChtX2JFbmFibGVOb3RpZnkpIHsKICAgIGlmICh3UGFyYW0gPT0gU0JUX1ZTQ1JPTEwpIHsKICAgICAgc3dpdGNoIChtc2cpIHsKICAgICAgICBjYXNlIFBOTV9TRVRTQ1JPTExJTkZPOgogICAgICAgICAgaWYgKFBXTF9TQ1JPTExfSU5GTyogcEluZm8gPSAoUFdMX1NDUk9MTF9JTkZPKilsUGFyYW0pIHsKICAgICAgICAgICAgaWYgKCFJc0Zsb2F0RXF1YWwocEluZm8tPmZDb250ZW50TWF4LCBtX2ZPbGRNYXgpIHx8CiAgICAgICAgICAgICAgICAhSXNGbG9hdEVxdWFsKHBJbmZvLT5mQ29udGVudE1pbiwgbV9mT2xkTWluKSkgewogICAgICAgICAgICAgIG1fYlNpemVDaGFuZ2VkID0gVFJVRTsKICAgICAgICAgICAgICBpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBHZXRQYXJlbnRXaW5kb3coKSkgewogICAgICAgICAgICAgICAgcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICBtX2ZPbGRNYXggPSBwSW5mby0+ZkNvbnRlbnRNYXg7CiAgICAgICAgICAgICAgbV9mT2xkTWluID0gcEluZm8tPmZDb250ZW50TWluOwogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICBDUFdMX0VkaXQ6Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOwoKICBpZiAobV9iRW5hYmxlTm90aWZ5KSB7CiAgICBzd2l0Y2ggKG1zZykgewogICAgICBjYXNlIFBOTV9TRVRDQVJFVElORk86CiAgICAgICAgaWYgKFBXTF9DQVJFVF9JTkZPKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKSB7CiAgICAgICAgICBQV0xfQ0FSRVRfSU5GTyBuZXdJbmZvID0gKnBJbmZvOwogICAgICAgICAgbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7CiAgICAgICAgICBuZXdJbmZvLnB0SGVhZCA9IENoaWxkVG9QYXJlbnQocEluZm8tPnB0SGVhZCk7CiAgICAgICAgICBuZXdJbmZvLnB0Rm9vdCA9IENoaWxkVG9QYXJlbnQocEluZm8tPnB0Rm9vdCk7CgogICAgICAgICAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgICAgICAgcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX1NFVENBUkVUSU5GTywgKGludHB0cl90KSZuZXdJbmZvLCAwKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgpGWF9GTE9BVCBDUFdMX05vdGVfRWRpdDo6R2V0SXRlbUhlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCkgewogIGlmIChmTGltaXRXaWR0aCA+IDApIHsKICAgIGlmICghbV9iU2l6ZUNoYW5nZWQpCiAgICAgIHJldHVybiBtX2ZPbGRJdGVtSGVpZ2h0OwoKICAgIG1fYlNpemVDaGFuZ2VkID0gRkFMU0U7CgogICAgRW5hYmxlTm90aWZ5KEZBTFNFKTsKICAgIEVuYWJsZVJlZnJlc2goRkFMU0UpOwogICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsKCiAgICBNb3ZlKENQREZfUmVjdCgwLCAwLCBmTGltaXRXaWR0aCwgMCksIFRSVUUsIEZBTFNFKTsKICAgIEZYX0ZMT0FUIGZSZXQgPSBHZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwoKICAgIG1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsKICAgIEVuYWJsZU5vdGlmeShUUlVFKTsKICAgIEVuYWJsZVJlZnJlc2goVFJVRSk7CgogICAgcmV0dXJuIGZSZXQ7CiAgfQoKICByZXR1cm4gMDsKfQoKRlhfRkxPQVQgQ1BXTF9Ob3RlX0VkaXQ6OkdldEl0ZW1MZWZ0TWFyZ2luKCkgewogIHJldHVybiBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOwp9CgpGWF9GTE9BVCBDUFdMX05vdGVfRWRpdDo6R2V0SXRlbVJpZ2h0TWFyZ2luKCkgewogIHJldHVybiBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfTEJCb3gKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKQ1BXTF9Ob3RlX0xCQm94OjpDUFdMX05vdGVfTEJCb3goKSB7fQoKQ1BXTF9Ob3RlX0xCQm94Ojp+Q1BXTF9Ob3RlX0xCQm94KCkge30KCnZvaWQgQ1BXTF9Ob3RlX0xCQm94OjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDRlhfTWF0cml4KiBwVXNlcjJEZXZpY2UpIHsKICBDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CgogIENGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7CiAgZ3NkLm1fTGluZVdpZHRoID0gMS4wZjsKCiAgQ0ZYX1BhdGhEYXRhIHBhdGhDcm9zczsKCiAgcGF0aENyb3NzLlNldFBvaW50Q291bnQoNCk7CiAgcGF0aENyb3NzLlNldFBvaW50KDAsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LnRvcCwgRlhQVF9NT1ZFVE8pOwogIHBhdGhDcm9zcy5TZXRQb2ludCgxLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7CiAgcGF0aENyb3NzLlNldFBvaW50KDIsIHJjQ2xpZW50LmxlZnQsCiAgICAgICAgICAgICAgICAgICAgIHJjQ2xpZW50LmJvdHRvbSArIHJjQ2xpZW50LkhlaWdodCgpICogMC41ZiwgRlhQVF9NT1ZFVE8pOwogIHBhdGhDcm9zcy5TZXRQb2ludCgzLCByY0NsaWVudC5sZWZ0ICsgcmNDbGllbnQuV2lkdGgoKSAqIDAuNWYsCiAgICAgICAgICAgICAgICAgICAgIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOwoKICBwRGV2aWNlLT5EcmF3UGF0aCgKICAgICAgJnBhdGhDcm9zcywgcFVzZXIyRGV2aWNlLCAmZ3NkLCAwLAogICAgICBDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSwgR2V0VHJhbnNwYXJlbmN5KCkpLAogICAgICBGWEZJTExfQUxURVJOQVRFKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX1JCQm94CiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCkNQV0xfTm90ZV9SQkJveDo6Q1BXTF9Ob3RlX1JCQm94KCkge30KCkNQV0xfTm90ZV9SQkJveDo6fkNQV0xfTm90ZV9SQkJveCgpIHt9Cgp2b2lkIENQV0xfTm90ZV9SQkJveDo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ZYX01hdHJpeCogcFVzZXIyRGV2aWNlKSB7CiAgQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOwoKICBDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOwogIGdzZC5tX0xpbmVXaWR0aCA9IDEuMGY7CgogIENGWF9QYXRoRGF0YSBwYXRoQ3Jvc3M7CgogIHBhdGhDcm9zcy5TZXRQb2ludENvdW50KDQpOwogIHBhdGhDcm9zcy5TZXRQb2ludCgwLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQudG9wLCBGWFBUX01PVkVUTyk7CiAgcGF0aENyb3NzLlNldFBvaW50KDEsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOwogIHBhdGhDcm9zcy5TZXRQb2ludCgyLCByY0NsaWVudC5yaWdodCwKICAgICAgICAgICAgICAgICAgICAgcmNDbGllbnQuYm90dG9tICsgcmNDbGllbnQuSGVpZ2h0KCkgKiAwLjVmLCBGWFBUX01PVkVUTyk7CiAgcGF0aENyb3NzLlNldFBvaW50KDMsIHJjQ2xpZW50LmxlZnQgKyByY0NsaWVudC5XaWR0aCgpICogMC41ZiwKICAgICAgICAgICAgICAgICAgICAgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7CgogIHBEZXZpY2UtPkRyYXdQYXRoKAogICAgICAmcGF0aENyb3NzLCBwVXNlcjJEZXZpY2UsICZnc2QsIDAsCiAgICAgIENQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpLCBHZXRUcmFuc3BhcmVuY3koKSksCiAgICAgIEZYRklMTF9BTFRFUk5BVEUpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX0ljb24KICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ1BXTF9Ob3RlX0ljb246OkNQV0xfTm90ZV9JY29uKCkgOiBtX25UeXBlKDApIHt9CgpDUFdMX05vdGVfSWNvbjo6fkNQV0xfTm90ZV9JY29uKCkge30KCnZvaWQgQ1BXTF9Ob3RlX0ljb246OlNldEljb25UeXBlKGludDMyX3QgblR5cGUpIHsKICBtX25UeXBlID0gblR5cGU7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0ljb246OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ZYX01hdHJpeCogcFVzZXIyRGV2aWNlKSB7CiAgQ1BXTF9VdGlsczo6RHJhd0ljb25BcHBTdHJlYW0ocERldmljZSwgcFVzZXIyRGV2aWNlLCBtX25UeXBlLCBHZXRDbGllbnRSZWN0KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0QmFja2dyb3VuZENvbG9yKCksIFBXTF9ERUZBVUxUX0JMQUNLQ09MT1IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0VHJhbnNwYXJlbmN5KCkpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX0Nsb3NlQm94CiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCkNQV0xfTm90ZV9DbG9zZUJveDo6Q1BXTF9Ob3RlX0Nsb3NlQm94KCkgOiBtX2JNb3VzZURvd24oRkFMU0UpIHt9CgpDUFdMX05vdGVfQ2xvc2VCb3g6On5DUFdMX05vdGVfQ2xvc2VCb3goKSB7fQoKdm9pZCBDUFdMX05vdGVfQ2xvc2VCb3g6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENGWF9NYXRyaXgqIHBVc2VyMkRldmljZSkgewogIENQV0xfQnV0dG9uOjpEcmF3VGhpc0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlKTsKCiAgQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOwogIHJjQ2xpZW50ID0gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmNDbGllbnQsIDIuMGYpOwoKICBDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOwogIGdzZC5tX0xpbmVXaWR0aCA9IDEuMGY7CgogIENGWF9QYXRoRGF0YSBwYXRoQ3Jvc3M7CgogIGlmIChtX2JNb3VzZURvd24pIHsKICAgIHJjQ2xpZW50LmxlZnQgKz0gMC41ZjsKICAgIHJjQ2xpZW50LnJpZ2h0ICs9IDAuNWY7CiAgICByY0NsaWVudC50b3AgLT0gMC41ZjsKICAgIHJjQ2xpZW50LmJvdHRvbSAtPSAwLjVmOwogIH0KCiAgcGF0aENyb3NzLlNldFBvaW50Q291bnQoNCk7CiAgcGF0aENyb3NzLlNldFBvaW50KDAsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9NT1ZFVE8pOwogIHBhdGhDcm9zcy5TZXRQb2ludCgxLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQudG9wLCBGWFBUX0xJTkVUTyk7CiAgcGF0aENyb3NzLlNldFBvaW50KDIsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LnRvcCwgRlhQVF9NT1ZFVE8pOwogIHBhdGhDcm9zcy5TZXRQb2ludCgzLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7CgogIHBEZXZpY2UtPkRyYXdQYXRoKAogICAgICAmcGF0aENyb3NzLCBwVXNlcjJEZXZpY2UsICZnc2QsIDAsCiAgICAgIENQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpLCBHZXRUcmFuc3BhcmVuY3koKSksCiAgICAgIEZYRklMTF9BTFRFUk5BVEUpOwp9CgpGWF9CT09MIENQV0xfTm90ZV9DbG9zZUJveDo6T25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50JiBwb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgbkZsYWcpIHsKICBTZXRCb3JkZXJTdHlsZShQQlNfSU5TRVQpOwogIEludmFsaWRhdGVSZWN0KE5VTEwpOwoKICBtX2JNb3VzZURvd24gPSBUUlVFOwoKICByZXR1cm4gQ1BXTF9CdXR0b246Ok9uTEJ1dHRvbkRvd24ocG9pbnQsIG5GbGFnKTsKfQoKRlhfQk9PTCBDUFdMX05vdGVfQ2xvc2VCb3g6Ok9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQmIHBvaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgbkZsYWcpIHsKICBtX2JNb3VzZURvd24gPSBGQUxTRTsKCiAgU2V0Qm9yZGVyU3R5bGUoUEJTX0JFVkVMRUQpOwogIEludmFsaWRhdGVSZWN0KE5VTEwpOwoKICByZXR1cm4gQ1BXTF9CdXR0b246Ok9uTEJ1dHRvblVwKHBvaW50LCBuRmxhZyk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfQ29udGVudHMKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ1BXTF9Ob3RlX0NvbnRlbnRzOjpDUFdMX05vdGVfQ29udGVudHMoKSA6IG1fcEVkaXQoTlVMTCkge30KCkNQV0xfTm90ZV9Db250ZW50czo6fkNQV0xfTm90ZV9Db250ZW50cygpIHt9CgpDRlhfQnl0ZVN0cmluZyBDUFdMX05vdGVfQ29udGVudHM6OkdldENsYXNzTmFtZSgpIGNvbnN0IHsKICByZXR1cm4gIkNQV0xfTm90ZV9Db250ZW50cyI7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0mIGNwKSB7CiAgbV9wRWRpdCA9IG5ldyBDUFdMX05vdGVfRWRpdDsKICBQV0xfQ1JFQVRFUEFSQU0gZWNwID0gY3A7CiAgZWNwLnBQYXJlbnRXbmQgPSB0aGlzOwogIGVjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfTVVMVElMSU5FIHwgUEVTX0FVVE9SRVRVUk4gfAogICAgICAgICAgICAgICAgUEVTX1RFWFRPVkVSRkxPVyB8IFBFU19VTkRPIHwgUEVTX1NQRUxMQ0hFQ0s7CgogIG1fcEVkaXQtPkVuYWJsZU5vdGlmeShGQUxTRSk7CiAgbV9wRWRpdC0+Q3JlYXRlKGVjcCk7CiAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOwp9Cgp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6U2V0VGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RleHQpIHsKICBpZiAobV9wRWRpdCkgewogICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsKICAgIG1fcEVkaXQtPlNldFRleHQoc1RleHQuY19zdHIoKSk7CiAgICBtX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7CiAgICBPbk5vdGlmeShtX3BFZGl0LCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKICB9Cn0KCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZV9Db250ZW50czo6R2V0VGV4dCgpIGNvbnN0IHsKICBpZiAobV9wRWRpdCkKICAgIHJldHVybiBtX3BFZGl0LT5HZXRUZXh0KCk7CgogIHJldHVybiBMIiI7Cn0KCkNQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZV9Db250ZW50czo6Q3JlYXRlU3ViSXRlbSgpIHsKICBDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSBuZXcgQ1BXTF9Ob3RlSXRlbTsKICBQV0xfQ1JFQVRFUEFSQU0gaWNwID0gR2V0Q3JlYXRpb25QYXJhbSgpOwogIGljcC5wUGFyZW50V25kID0gdGhpczsKICBpY3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFIHwgUFdTX0JBQ0tHUk9VTkQ7CiAgcE5vdGVJdGVtLT5DcmVhdGUoaWNwKTsKCiAgcE5vdGVJdGVtLT5PbkNyZWF0ZU5vdGVJdGVtKCk7CgogIHBOb3RlSXRlbS0+UmVzZXRTdWJqZWN0TmFtZShtX2FDaGlsZHJlbi5HZXRTaXplKCkgLSAxKTsKCiAgRlhfU1lTVEVNVElNRSBzdDsKICBpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkKICAgIHN0ID0gcFNILT5HZXRMb2NhbFRpbWUoKTsKICBwTm90ZUl0ZW0tPlNldERhdGVUaW1lKHN0KTsKCiAgcE5vdGVJdGVtLT5TZXRDb250ZW50cyhMIiIpOwoKICBPbk5vdGlmeShwTm90ZUl0ZW0sIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOwoKICByZXR1cm4gcE5vdGVJdGVtOwp9CgppbnQzMl90IENQV0xfTm90ZV9Db250ZW50czo6Q291bnRTdWJJdGVtcygpIGNvbnN0IHsKICByZXR1cm4gbV9hQ2hpbGRyZW4uR2V0U2l6ZSgpIC0gMTsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRTdWJJdGVtcyhpbnQzMl90IGluZGV4KSBjb25zdCB7CiAgaW50MzJfdCBuSW5kZXggPSBpbmRleCArIDE7CgogIGlmIChuSW5kZXggPiAwICYmIG5JbmRleCA8IG1fYUNoaWxkcmVuLkdldFNpemUoKSkKICAgIGlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQobkluZGV4KSkgewogICAgICBBU1NFUlQocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwogICAgICBDUFdMX05vdGVJdGVtKiBwSXRlbSA9IChDUFdMX05vdGVJdGVtKilwQ2hpbGQ7CiAgICAgIHJldHVybiBwSXRlbTsKICAgIH0KICByZXR1cm4gTlVMTDsKfQoKdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OkRlbGV0ZVN1Ykl0ZW0oSVBXTF9Ob3RlSXRlbSogcE5vdGVJdGVtKSB7CiAgaW50MzJfdCBuSW5kZXggPSBHZXRJdGVtSW5kZXgoKENQV0xfTm90ZUl0ZW0qKXBOb3RlSXRlbSk7CgogIGlmIChuSW5kZXggPiAwKSB7CiAgICBpZiAoQ1BXTF9Ob3RlSXRlbSogcFBXTE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBOb3RlSXRlbSkgewogICAgICBwUFdMTm90ZUl0ZW0tPktpbGxGb2N1cygpOwogICAgICBwUFdMTm90ZUl0ZW0tPkRlc3Ryb3koKTsKICAgICAgZGVsZXRlIHBQV0xOb3RlSXRlbTsKICAgIH0KCiAgICBmb3IgKGludDMyX3QgaSA9IG5JbmRleCwgc3ogPSBtX2FDaGlsZHJlbi5HZXRTaXplKCk7IGkgPCBzejsgaSsrKSB7CiAgICAgIGlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpIHsKICAgICAgICBBU1NFUlQocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwogICAgICAgIENQV0xfTm90ZUl0ZW0qIHBJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsKICAgICAgICBwSXRlbS0+UmVzZXRTdWJqZWN0TmFtZShpKTsKICAgICAgfQogICAgfQoKICAgIE9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOwogIH0KfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRIaXROb3RlSXRlbShjb25zdCBDUERGX1BvaW50JiBwb2ludCkgewogIENQREZfUG9pbnQgcHQgPSBQYXJlbnRUb0NoaWxkKHBvaW50KTsKCiAgZm9yIChpbnQzMl90IGkgPSAwLCBzeiA9IG1fYUNoaWxkcmVuLkdldFNpemUoKTsgaSA8IHN6OyBpKyspIHsKICAgIGlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpIHsKICAgICAgaWYgKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKSB7CiAgICAgICAgQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsKICAgICAgICBpZiAoSVBXTF9Ob3RlSXRlbSogcFJldCA9IHBOb3RlSXRlbS0+R2V0SGl0Tm90ZUl0ZW0ocHQpKQogICAgICAgICAgcmV0dXJuIHBSZXQ7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0RXT1JEIG1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHB0cl90IHdQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHB0cl90IGxQYXJhbSkgewogIHN3aXRjaCAobXNnKSB7CiAgICBjYXNlIFBOTV9OT1RFRURJVENIQU5HRUQ6IHsKICAgICAgaW50MzJfdCBuSW5kZXggPSBHZXRJdGVtSW5kZXgocFduZCk7CiAgICAgIGlmIChuSW5kZXggPCAwKQogICAgICAgIG5JbmRleCA9IDA7CgogICAgICBtX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwogICAgICBSZXNldENvbnRlbnQobkluZGV4KTsKICAgICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOwoKICAgICAgZm9yIChpbnQzMl90IGkgPSBuSW5kZXggKyAxLCBzeiA9IG1fYUNoaWxkcmVuLkdldFNpemUoKTsgaSA8IHN6OyBpKyspIHsKICAgICAgICBpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQogICAgICAgICAgcENoaWxkLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKICAgICAgfQoKICAgICAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgICBwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKICAgICAgfQogICAgfQogICAgICByZXR1cm47CiAgICBjYXNlIFBOTV9TQ1JPTExXSU5ET1c6CiAgICAgIFNldFNjcm9sbFBvcyhDUERGX1BvaW50KDAuMGYsICooRlhfRkxPQVQqKWxQYXJhbSkpOwogICAgICBSZXNldEZhY2UoKTsKICAgICAgSW52YWxpZGF0ZVJlY3QoTlVMTCk7CiAgICAgIHJldHVybjsKICAgIGNhc2UgUE5NX1NFVENBUkVUSU5GTzoKICAgICAgaWYgKFBXTF9DQVJFVF9JTkZPKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKSB7CiAgICAgICAgUFdMX0NBUkVUX0lORk8gbmV3SW5mbyA9ICpwSW5mbzsKICAgICAgICBuZXdJbmZvLmJWaXNpYmxlID0gVFJVRTsKICAgICAgICBuZXdJbmZvLnB0SGVhZCA9IENoaWxkVG9QYXJlbnQocEluZm8tPnB0SGVhZCk7CiAgICAgICAgbmV3SW5mby5wdEZvb3QgPSBDaGlsZFRvUGFyZW50KHBJbmZvLT5wdEZvb3QpOwoKICAgICAgICBpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBHZXRQYXJlbnRXaW5kb3coKSkgewogICAgICAgICAgcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX1NFVENBUkVUSU5GTywgKGludHB0cl90KSZuZXdJbmZvLCAwKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuOwogICAgY2FzZSBQTk1fTk9URVJFU0VUOiB7CiAgICAgIG1fcEVkaXQtPkVuYWJsZU5vdGlmeShGQUxTRSk7CiAgICAgIFJlc2V0Q29udGVudCgwKTsKICAgICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOwoKICAgICAgZm9yIChpbnQzMl90IGkgPSAxLCBzeiA9IG1fYUNoaWxkcmVuLkdldFNpemUoKTsgaSA8IHN6OyBpKyspIHsKICAgICAgICBpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQogICAgICAgICAgcENoaWxkLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKICAgICAgfQoKICAgICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsKICAgICAgUmVzZXRDb250ZW50KDApOwogICAgICBtX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7CiAgICB9CiAgICAgIHJldHVybjsKICB9CgogIENQV0xfV25kOjpPbk5vdGlmeShwV25kLCBtc2csIHdQYXJhbSwgbFBhcmFtKTsKfQoKRlhfQk9PTCBDUFdMX05vdGVfQ29udGVudHM6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0RXT1JEIG5GbGFnKSB7CiAgaWYgKENQV0xfV25kOjpPbkxCdXR0b25Eb3duKHBvaW50LCBuRmxhZykpCiAgICByZXR1cm4gVFJVRTsKCiAgaWYgKCFtX3BFZGl0LT5Jc0ZvY3VzZWQoKSkgewogICAgbV9wRWRpdC0+U2V0Rm9jdXMoKTsKICB9CgogIHJldHVybiBUUlVFOwp9Cgp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6U2V0RWRpdEZvY3VzKEZYX0JPT0wgYkxhc3QpIHsKICBpZiAoIW1fcEVkaXQtPklzRm9jdXNlZCgpKSB7CiAgICBtX3BFZGl0LT5TZXRGb2N1cygpOwogICAgbV9wRWRpdC0+U2V0Q2FyZXQoYkxhc3QgPyBtX3BFZGl0LT5HZXRUb3RhbFdvcmRzKCkgOiAwKTsKICB9Cn0KCkNQV0xfRWRpdCogQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRFZGl0KCkgY29uc3QgewogIHJldHVybiBtX3BFZGl0Owp9Cgp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6RW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpIHsKICBpZiAoIWJFbmFibGVkKQogICAgbV9wRWRpdC0+QWRkRmxhZyhQV1NfUkVBRE9OTFkpOwogIGVsc2UKICAgIG1fcEVkaXQtPlJlbW92ZUZsYWcoUFdTX1JFQURPTkxZKTsKCiAgZm9yIChpbnQzMl90IGkgPSAwLCBzeiA9IG1fYUNoaWxkcmVuLkdldFNpemUoKTsgaSA8IHN6OyBpKyspIHsKICAgIGlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpIHsKICAgICAgaWYgKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKSB7CiAgICAgICAgQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsKICAgICAgICBwTm90ZUl0ZW0tPkVuYWJsZU1vZGlmeShiRW5hYmxlZCk7CiAgICAgIH0KICAgIH0KICB9Cn0KCnZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpFbmFibGVSZWFkKEZYX0JPT0wgYkVuYWJsZWQpIHsKICBpZiAoIWJFbmFibGVkKQogICAgbV9wRWRpdC0+QWRkRmxhZyhQRVNfTk9SRUFEKTsKICBlbHNlCiAgICBtX3BFZGl0LT5SZW1vdmVGbGFnKFBFU19OT1JFQUQpOwoKICBmb3IgKGludDMyX3QgaSA9IDAsIHN6ID0gbV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpIDwgc3o7IGkrKykgewogICAgaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkgewogICAgICBpZiAocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpIHsKICAgICAgICBDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcENoaWxkOwogICAgICAgIHBOb3RlSXRlbS0+RW5hYmxlUmVhZChiRW5hYmxlZCk7CiAgICAgIH0KICAgIH0KICB9Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlSXRlbQogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpDUFdMX05vdGVJdGVtOjpDUFdMX05vdGVJdGVtKCkKICAgIDogbV9wU3ViamVjdChOVUxMKSwKICAgICAgbV9wRGF0ZVRpbWUoTlVMTCksCiAgICAgIG1fcENvbnRlbnRzKE5VTEwpLAogICAgICBtX3BQcml2YXRlRGF0YShOVUxMKSwKICAgICAgbV9zQXV0aG9yKEwiIiksCiAgICAgIG1fZk9sZEl0ZW1IZWlnaHQoMC4wZiksCiAgICAgIG1fYlNpemVDaGFuZ2VkKEZBTFNFKSwKICAgICAgbV9iQWxsb3dNb2RpZnkoVFJVRSkge30KCkNQV0xfTm90ZUl0ZW06On5DUFdMX05vdGVJdGVtKCkge30KCkNGWF9CeXRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldENsYXNzTmFtZSgpIGNvbnN0IHsKICByZXR1cm4gIkNQV0xfTm90ZUl0ZW0iOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3ApIHsKICBDUFdMX0NvbG9yIHNUZXh0Q29sb3I7CgogIGlmIChDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZShHZXRCYWNrZ3JvdW5kQ29sb3IoKSkpCiAgICBzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsKICBlbHNlCiAgICBzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUjsKCiAgbV9wU3ViamVjdCA9IG5ldyBDUFdMX0xhYmVsOwogIFBXTF9DUkVBVEVQQVJBTSBzY3AgPSBjcDsKICBzY3AucFBhcmVudFduZCA9IHRoaXM7CiAgc2NwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBFU19MRUZUIHwgUEVTX1RPUDsKICBzY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CiAgbV9wU3ViamVjdC0+Q3JlYXRlKHNjcCk7CgogIG1fcERhdGVUaW1lID0gbmV3IENQV0xfTGFiZWw7CiAgUFdMX0NSRUFURVBBUkFNIGRjcCA9IGNwOwogIGRjcC5wUGFyZW50V25kID0gdGhpczsKICBkY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUEVTX1JJR0hUIHwgUEVTX1RPUDsKICBkY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CiAgbV9wRGF0ZVRpbWUtPkNyZWF0ZShkY3ApOwoKICBtX3BDb250ZW50cyA9IG5ldyBDUFdMX05vdGVfQ29udGVudHM7CiAgUFdMX0NSRUFURVBBUkFNIGNjcCA9IGNwOwogIGNjcC5wUGFyZW50V25kID0gdGhpczsKICAvLyBjY3Auc0JhY2tncm91bmRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CiAgY2NwLnNCYWNrZ3JvdW5kQ29sb3IgPQogICAgICBDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIDI0MCAvIDI1NS4wZiwgMjQwIC8gMjU1LjBmLCAyNDAgLyAyNTUuMGYpOwogIGNjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQV1NfQkFDS0dST1VORDsKICBtX3BDb250ZW50cy0+Q3JlYXRlKGNjcCk7CiAgbV9wQ29udGVudHMtPlNldEl0ZW1TcGFjZShQT1BVUF9JVEVNX1NQQUNFKTsKICBtX3BDb250ZW50cy0+U2V0VG9wU3BhY2UoUE9QVVBfSVRFTV9TUEFDRSk7CiAgbV9wQ29udGVudHMtPlNldEJvdHRvbVNwYWNlKFBPUFVQX0lURU1fU1BBQ0UpOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlJlUG9zQ2hpbGRXbmQoKSB7CiAgaWYgKElzVmFsaWQoKSkgewogICAgQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOwoKICAgIENQREZfUmVjdCByY1N1YmplY3QgPSByY0NsaWVudDsKICAgIHJjU3ViamVjdC5sZWZ0ICs9IFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7CiAgICByY1N1YmplY3QudG9wID0gcmNDbGllbnQudG9wOwogICAgcmNTdWJqZWN0LnJpZ2h0ID0KICAgICAgICBQV0xfTUlOKHJjU3ViamVjdC5sZWZ0ICsgbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpICsgMS4wZiwKICAgICAgICAgICAgICAgIHJjQ2xpZW50LnJpZ2h0KTsKICAgIHJjU3ViamVjdC5ib3R0b20gPSByY1N1YmplY3QudG9wIC0gbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKICAgIHJjU3ViamVjdC5Ob3JtYWxpemUoKTsKICAgIG1fcFN1YmplY3QtPk1vdmUocmNTdWJqZWN0LCBUUlVFLCBGQUxTRSk7CiAgICBtX3BTdWJqZWN0LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNTdWJqZWN0KSk7CgogICAgQ1BERl9SZWN0IHJjRGF0ZSA9IHJjQ2xpZW50OwogICAgcmNEYXRlLnJpZ2h0IC09IFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7CiAgICByY0RhdGUubGVmdCA9CiAgICAgICAgUFdMX01BWChyY0RhdGUucmlnaHQgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpIC0gMS4wZiwKICAgICAgICAgICAgICAgIHJjU3ViamVjdC5yaWdodCk7CiAgICByY0RhdGUuYm90dG9tID0gcmNEYXRlLnRvcCAtIG1fcERhdGVUaW1lLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwogICAgcmNEYXRlLk5vcm1hbGl6ZSgpOwogICAgbV9wRGF0ZVRpbWUtPk1vdmUocmNEYXRlLCBUUlVFLCBGQUxTRSk7CiAgICBtX3BEYXRlVGltZS0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjRGF0ZSkpOwoKICAgIENQREZfUmVjdCByY0NvbnRlbnRzID0gcmNDbGllbnQ7CiAgICByY0NvbnRlbnRzLmxlZnQgKz0gMS4wZjsKICAgIHJjQ29udGVudHMucmlnaHQgLT0gMS4wZjsKICAgIHJjQ29udGVudHMudG9wID0gcmNEYXRlLmJvdHRvbSAtIFBPUFVQX0lURU1fSEVBRF9CT1RUT007CiAgICByY0NvbnRlbnRzLmJvdHRvbSArPSBQT1BVUF9JVEVNX0JPVFRPTVdJRFRIOwogICAgcmNDb250ZW50cy5Ob3JtYWxpemUoKTsKICAgIG1fcENvbnRlbnRzLT5Nb3ZlKHJjQ29udGVudHMsIFRSVUUsIEZBTFNFKTsKICAgIG1fcENvbnRlbnRzLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNDb250ZW50cykpOwogIH0KCiAgU2V0Q2xpcFJlY3QoQ1BXTF9VdGlsczo6SW5mbGF0ZVJlY3QoR2V0V2luZG93UmVjdCgpLCAxLjBmKSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0UHJpdmF0ZURhdGEodm9pZCogcERhdGEpIHsKICBtX3BQcml2YXRlRGF0YSA9IHBEYXRhOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlNldEJrQ29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpIHsKICBDUFdMX0NvbG9yIHNCSyA9IGNvbG9yOwogIFNldEJhY2tncm91bmRDb2xvcihzQkspOwoKICBDUFdMX0NvbG9yIHNUZXh0Q29sb3I7CgogIGlmIChDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZShzQkspKQogICAgc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CiAgZWxzZQogICAgc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7CgogIFNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKICBpZiAobV9wU3ViamVjdCkKICAgIG1fcFN1YmplY3QtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKICBpZiAobV9wRGF0ZVRpbWUpCiAgICBtX3BEYXRlVGltZS0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOwoKICBJbnZhbGlkYXRlUmVjdChudWxscHRyKTsKCiAgaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkgewogICAgcE5vdGlmeS0+T25TZXRCa0NvbG9yKHRoaXMpOwogIH0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRTdWJqZWN0TmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpIHsKICBpZiAobV9wU3ViamVjdCkgewogICAgbV9wU3ViamVjdC0+U2V0VGV4dChzTmFtZS5jX3N0cigpKTsKICB9CgogIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgIHBOb3RpZnktPk9uU2V0U3ViamVjdE5hbWUodGhpcyk7CiAgfQp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlNldEF1dGhvck5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNOYW1lKSB7CiAgbV9zQXV0aG9yID0gc05hbWU7CiAgUmVzZXRTdWJqZWN0TmFtZSgtMSk7CgogIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgIHBOb3RpZnktPk9uU2V0QXV0aG9yTmFtZSh0aGlzKTsKICB9Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6UmVzZXRTdWJqZWN0TmFtZShpbnQzMl90IG5JdGVtSW5kZXgpIHsKICBpZiAobkl0ZW1JbmRleCA8IDApIHsKICAgIGlmIChDUFdMX1duZCogcFBhcmVudCA9IEdldFBhcmVudFdpbmRvdygpKSB7CiAgICAgIEFTU0VSVChwUGFyZW50LT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlX0NvbnRlbnRzIik7CgogICAgICBDUFdMX05vdGVfQ29udGVudHMqIHBDb250ZW50cyA9IChDUFdMX05vdGVfQ29udGVudHMqKXBQYXJlbnQ7CiAgICAgIG5JdGVtSW5kZXggPSBwQ29udGVudHMtPkdldEl0ZW1JbmRleCh0aGlzKTsKICAgIH0KICB9CgogIGNvbnN0IENQV0xfTm90ZSogcE5vdGUgPSBHZXROb3RlKCk7CiAgQ0ZYX1dpZGVTdHJpbmcgc1N1YmplY3Q7CiAgc1N1YmplY3QuRm9ybWF0KHBOb3RlLT5HZXRSZXBseVN0cmluZygpLmNfc3RyKCksIG5JdGVtSW5kZXgpOwoKICBpZiAoIW1fc0F1dGhvci5Jc0VtcHR5KCkpIHsKICAgIHNTdWJqZWN0ICs9IEwiIC0gIjsKICAgIHNTdWJqZWN0ICs9IG1fc0F1dGhvcjsKICB9CiAgU2V0U3ViamVjdE5hbWUoc1N1YmplY3QpOwogIFJlUG9zQ2hpbGRXbmQoKTsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXREYXRlVGltZShGWF9TWVNURU1USU1FIHRpbWUpIHsKICBtX2R0Tm90ZSA9IHRpbWU7CgogIENGWF9XaWRlU3RyaW5nIHN3VGltZTsKICBzd1RpbWUuRm9ybWF0KEwiJTA0ZC0lMDJkLSUwMmQgJTAyZDolMDJkOiUwMmQiLCB0aW1lLndZZWFyLCB0aW1lLndNb250aCwKICAgICAgICAgICAgICAgIHRpbWUud0RheSwgdGltZS53SG91ciwgdGltZS53TWludXRlLCB0aW1lLndTZWNvbmQpOwogIGlmIChtX3BEYXRlVGltZSkgewogICAgbV9wRGF0ZVRpbWUtPlNldFRleHQoc3dUaW1lLmNfc3RyKCkpOwogIH0KCiAgUmVQb3NDaGlsZFduZCgpOwoKICBpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKSB7CiAgICBwTm90aWZ5LT5PblNldERhdGVUaW1lKHRoaXMpOwogIH0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRDb250ZW50cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc0NvbnRlbnRzKSB7CiAgaWYgKG1fcENvbnRlbnRzKSB7CiAgICBtX3BDb250ZW50cy0+U2V0VGV4dChzQ29udGVudHMpOwogIH0KCiAgaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkgewogICAgcE5vdGlmeS0+T25TZXRDb250ZW50cyh0aGlzKTsKICB9Cn0KCkNQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldFBhcmVudE5vdGVJdGVtKCkgY29uc3QgewogIGlmIChDUFdMX1duZCogcFBhcmVudCA9IEdldFBhcmVudFdpbmRvdygpKSB7CiAgICBpZiAoQ1BXTF9XbmQqIHBHcmFuZCA9IHBQYXJlbnQtPkdldFBhcmVudFdpbmRvdygpKSB7CiAgICAgIEFTU0VSVChwR3JhbmQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7CiAgICAgIHJldHVybiAoQ1BXTF9Ob3RlSXRlbSopcEdyYW5kOwogICAgfQogIH0KCiAgcmV0dXJuIE5VTEw7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldFBhcmVudEl0ZW0oKSBjb25zdCB7CiAgcmV0dXJuIEdldFBhcmVudE5vdGVJdGVtKCk7Cn0KCkNQV0xfRWRpdCogQ1BXTF9Ob3RlSXRlbTo6R2V0RWRpdCgpIGNvbnN0IHsKICBpZiAobV9wQ29udGVudHMpCiAgICByZXR1cm4gbV9wQ29udGVudHMtPkdldEVkaXQoKTsKICByZXR1cm4gTlVMTDsKfQoKdm9pZCogQ1BXTF9Ob3RlSXRlbTo6R2V0UHJpdmF0ZURhdGEoKSBjb25zdCB7CiAgcmV0dXJuIG1fcFByaXZhdGVEYXRhOwp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRBdXRob3JOYW1lKCkgY29uc3QgewogIHJldHVybiBtX3NBdXRob3I7Cn0KCkNQV0xfQ29sb3IgQ1BXTF9Ob3RlSXRlbTo6R2V0QmtDb2xvcigpIGNvbnN0IHsKICByZXR1cm4gR2V0QmFja2dyb3VuZENvbG9yKCk7Cn0KCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldENvbnRlbnRzKCkgY29uc3QgewogIGlmIChtX3BDb250ZW50cykKICAgIHJldHVybiBtX3BDb250ZW50cy0+R2V0VGV4dCgpOwoKICByZXR1cm4gTCIiOwp9CgpGWF9TWVNURU1USU1FIENQV0xfTm90ZUl0ZW06OkdldERhdGVUaW1lKCkgY29uc3QgewogIHJldHVybiBtX2R0Tm90ZTsKfQoKQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9Ob3RlSXRlbTo6R2V0U3ViamVjdE5hbWUoKSBjb25zdCB7CiAgaWYgKG1fcFN1YmplY3QpCiAgICByZXR1cm4gbV9wU3ViamVjdC0+R2V0VGV4dCgpOwoKICByZXR1cm4gTCIiOwp9CgpDUFdMX05vdGVJdGVtKiBDUFdMX05vdGVJdGVtOjpDcmVhdGVOb3RlSXRlbSgpIHsKICBpZiAobV9wQ29udGVudHMpCiAgICByZXR1cm4gbV9wQ29udGVudHMtPkNyZWF0ZVN1Ykl0ZW0oKTsKCiAgcmV0dXJuIE5VTEw7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkNyZWF0ZVN1Ykl0ZW0oKSB7CiAgcmV0dXJuIENyZWF0ZU5vdGVJdGVtKCk7Cn0KCmludDMyX3QgQ1BXTF9Ob3RlSXRlbTo6Q291bnRTdWJJdGVtcygpIGNvbnN0IHsKICBpZiAobV9wQ29udGVudHMpCiAgICByZXR1cm4gbV9wQ29udGVudHMtPkNvdW50U3ViSXRlbXMoKTsKCiAgcmV0dXJuIDA7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldFN1Ykl0ZW1zKGludDMyX3QgaW5kZXgpIGNvbnN0IHsKICBpZiAobV9wQ29udGVudHMpCiAgICByZXR1cm4gbV9wQ29udGVudHMtPkdldFN1Ykl0ZW1zKGluZGV4KTsKCiAgcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6RGVsZXRlU3ViSXRlbShJUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0pIHsKICBLaWxsRm9jdXMoKTsKCiAgaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkgewogICAgcE5vdGlmeS0+T25JdGVtRGVsZXRlKHBOb3RlSXRlbSk7CiAgfQoKICBpZiAobV9wQ29udGVudHMpCiAgICBtX3BDb250ZW50cy0+RGVsZXRlU3ViSXRlbShwTm90ZUl0ZW0pOwp9CgpJUFdMX05vdGVJdGVtKiBDUFdMX05vdGVJdGVtOjpHZXRIaXROb3RlSXRlbShjb25zdCBDUERGX1BvaW50JiBwb2ludCkgewogIENQREZfUG9pbnQgcHQgPSBQYXJlbnRUb0NoaWxkKHBvaW50KTsKCiAgaWYgKFduZEhpdFRlc3QocHQpKSB7CiAgICBpZiAobV9wQ29udGVudHMpIHsKICAgICAgaWYgKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IG1fcENvbnRlbnRzLT5HZXRIaXROb3RlSXRlbShwdCkpCiAgICAgICAgcmV0dXJuIHBOb3RlSXRlbTsKICAgIH0KCiAgICByZXR1cm4gdGhpczsKICB9CgogIHJldHVybiBOVUxMOwp9CgpJUFdMX05vdGVJdGVtKiBDUFdMX05vdGVJdGVtOjpHZXRGb2N1c2VkTm90ZUl0ZW0oKSBjb25zdCB7CiAgaWYgKGNvbnN0IENQV0xfV25kKiBwV25kID0gR2V0Rm9jdXNlZCgpKSB7CiAgICBpZiAocFduZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfRWRpdCIpIHsKICAgICAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gcFduZC0+R2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgICBBU1NFUlQocFBhcmVudC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZV9Db250ZW50cyIpOwoKICAgICAgICBpZiAoQ1BXTF9XbmQqIHBHcmFuZCA9IHBQYXJlbnQtPkdldFBhcmVudFdpbmRvdygpKSB7CiAgICAgICAgICBBU1NFUlQocEdyYW5kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwogICAgICAgICAgcmV0dXJuIChDUFdMX05vdGVJdGVtKilwR3JhbmQ7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gTlVMTDsKfQoKRlhfRkxPQVQgQ1BXTF9Ob3RlSXRlbTo6R2V0SXRlbUhlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCkgewogIGlmIChmTGltaXRXaWR0aCA+IDApIHsKICAgIGlmICghbV9iU2l6ZUNoYW5nZWQpCiAgICAgIHJldHVybiBtX2ZPbGRJdGVtSGVpZ2h0OwoKICAgIG1fYlNpemVDaGFuZ2VkID0gRkFMU0U7CgogICAgRlhfRkxPQVQgZlJldCA9IG1fcERhdGVUaW1lLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwogICAgRlhfRkxPQVQgZkJvcmRlcldpZHRoID0gKEZYX0ZMT0FUKUdldEJvcmRlcldpZHRoKCk7CiAgICBpZiAoZkxpbWl0V2lkdGggPiBmQm9yZGVyV2lkdGggKiAyKQogICAgICBmUmV0ICs9IG1fcENvbnRlbnRzLT5HZXRDb250ZW50c0hlaWdodChmTGltaXRXaWR0aCAtIGZCb3JkZXJXaWR0aCAqIDIpOwogICAgZlJldCArPSBQT1BVUF9JVEVNX0hFQURfQk9UVE9NICsgUE9QVVBfSVRFTV9CT1RUT01XSURUSCArIGZCb3JkZXJXaWR0aCAqIDI7CgogICAgcmV0dXJuIG1fZk9sZEl0ZW1IZWlnaHQgPSBmUmV0OwogIH0KCiAgcmV0dXJuIDA7Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZUl0ZW06OkdldEl0ZW1MZWZ0TWFyZ2luKCkgewogIHJldHVybiBQT1BVUF9JVEVNX1NJREVNQVJHSU47Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZUl0ZW06OkdldEl0ZW1SaWdodE1hcmdpbigpIHsKICByZXR1cm4gUE9QVVBfSVRFTV9TSURFTUFSR0lOOwp9CgpGWF9CT09MIENQV0xfTm90ZUl0ZW06Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKSB7CiAgaWYgKCFtX3BDb250ZW50cy0+V25kSGl0VGVzdChtX3BDb250ZW50cy0+UGFyZW50VG9DaGlsZChwb2ludCkpKSB7CiAgICBTZXROb3RlRm9jdXMoRkFMU0UpOwogIH0KCiAgQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsIG5GbGFnKTsKCiAgcmV0dXJuIFRSVUU7Cn0KCkZYX0JPT0wgQ1BXTF9Ob3RlSXRlbTo6T25SQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKSB7CiAgaWYgKCFtX3BDb250ZW50cy0+V25kSGl0VGVzdChtX3BDb250ZW50cy0+UGFyZW50VG9DaGlsZChwb2ludCkpKSB7CiAgICBTZXROb3RlRm9jdXMoRkFMU0UpOwogICAgUG9wdXBOb3RlSXRlbU1lbnUocG9pbnQpOwoKICAgIHJldHVybiBUUlVFOwogIH0KCiAgcmV0dXJuIENQV0xfV25kOjpPblJCdXR0b25VcChwb2ludCwgbkZsYWcpOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0RXT1JEIG1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRwdHJfdCB3UGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50cHRyX3QgbFBhcmFtKSB7CiAgc3dpdGNoIChtc2cpIHsKICAgIGNhc2UgUE5NX05PVEVFRElUQ0hBTkdFRDoKICAgICAgbV9iU2l6ZUNoYW5nZWQgPSBUUlVFOwoKICAgICAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgICBwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKICAgICAgfQogICAgICByZXR1cm47CiAgICBjYXNlIFBOTV9TRVRDQVJFVElORk86CiAgICAgIGlmIChQV0xfQ0FSRVRfSU5GTyogcEluZm8gPSAoUFdMX0NBUkVUX0lORk8qKXdQYXJhbSkgewogICAgICAgIFBXTF9DQVJFVF9JTkZPIG5ld0luZm8gPSAqcEluZm87CiAgICAgICAgbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7CiAgICAgICAgbmV3SW5mby5wdEhlYWQgPSBDaGlsZFRvUGFyZW50KHBJbmZvLT5wdEhlYWQpOwogICAgICAgIG5ld0luZm8ucHRGb290ID0gQ2hpbGRUb1BhcmVudChwSW5mby0+cHRGb290KTsKCiAgICAgICAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgICAgIHBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRDQVJFVElORk8sIChpbnRwdHJfdCkmbmV3SW5mbywgMCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIGNhc2UgUE5NX05PVEVSRVNFVDoKICAgICAgbV9iU2l6ZUNoYW5nZWQgPSBUUlVFOwogICAgICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CgogICAgICByZXR1cm47CiAgfQoKICBDUFdMX1duZDo6T25Ob3RpZnkocFduZCwgbXNnLCB3UGFyYW0sIGxQYXJhbSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6UG9wdXBOb3RlSXRlbU1lbnUoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIHsKICBpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKSB7CiAgICBpbnQzMl90IHgsIHk7CiAgICBQV0x0b1duZChwb2ludCwgeCwgeSk7CiAgICBpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkKICAgICAgcFNILT5DbGllbnRUb1NjcmVlbihHZXRBdHRhY2hlZEhXbmQoKSwgeCwgeSk7CiAgICBwTm90aWZ5LT5PblBvcHVwTWVudSh0aGlzLCB4LCB5KTsKICB9Cn0KCmNvbnN0IENQV0xfTm90ZSogQ1BXTF9Ob3RlSXRlbTo6R2V0Tm90ZSgpIGNvbnN0IHsKICBpZiAoY29uc3QgQ1BXTF9XbmQqIHBSb290ID0gR2V0Um9vdFduZCgpKSB7CiAgICBBU1NFUlQocFJvb3QtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7CiAgICBDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcFJvb3Q7CiAgICBpZiAocE5vdGVJdGVtLT5Jc1RvcEl0ZW0oKSkgewogICAgICByZXR1cm4gKENQV0xfTm90ZSopcE5vdGVJdGVtOwogICAgfQogIH0KCiAgcmV0dXJuIE5VTEw7Cn0KCklQV0xfTm90ZU5vdGlmeSogQ1BXTF9Ob3RlSXRlbTo6R2V0Tm90ZU5vdGlmeSgpIGNvbnN0IHsKICBpZiAoY29uc3QgQ1BXTF9Ob3RlKiBwTm90ZSA9IEdldE5vdGUoKSkKICAgIHJldHVybiBwTm90ZS0+R2V0Tm90ZU5vdGlmeSgpOwoKICByZXR1cm4gTlVMTDsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpPbkNyZWF0ZU5vdGVJdGVtKCkgewogIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgIHBOb3RpZnktPk9uSXRlbUNyZWF0ZSh0aGlzKTsKICB9Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6T25Db250ZW50c1ZhbGlkYXRlKCkgewogIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgIHBOb3RpZnktPk9uU2V0Q29udGVudHModGhpcyk7CiAgfQp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlNldE5vdGVGb2N1cyhGWF9CT09MIGJMYXN0KSB7CiAgbV9wQ29udGVudHMtPlNldEVkaXRGb2N1cyhiTGFzdCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6RW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpIHsKICBtX3BDb250ZW50cy0+RW5hYmxlTW9kaWZ5KGJFbmFibGVkKTsKICBtX2JBbGxvd01vZGlmeSA9IGJFbmFibGVkOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OkVuYWJsZVJlYWQoRlhfQk9PTCBiRW5hYmxlZCkgewogIG1fcENvbnRlbnRzLT5FbmFibGVSZWFkKGJFbmFibGVkKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGUKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ1BXTF9Ob3RlOjpDUFdMX05vdGUoSVBvcHVwX05vdGUqIHBQb3B1cE5vdGUsCiAgICAgICAgICAgICAgICAgICAgIElQV0xfTm90ZU5vdGlmeSogcE5vdGVOb3RpZnksCiAgICAgICAgICAgICAgICAgICAgIElQV0xfTm90ZUhhbmRsZXIqIHBOb3RlSGFuZGxlcikKICAgIDogbV9wQXV0aG9yKE5VTEwpLAogICAgICBtX3BJY29uKE5VTEwpLAogICAgICBtX3BDbG9zZUJveChOVUxMKSwKICAgICAgbV9wTEJCb3goTlVMTCksCiAgICAgIG1fcFJCQm94KE5VTEwpLAogICAgICBtX3BDb250ZW50c0JhcihOVUxMKSwKICAgICAgbV9wT3B0aW9ucyhOVUxMKSwKICAgICAgbV9wTm90ZU5vdGlmeShwTm90ZU5vdGlmeSksCiAgICAgIG1fYlJlc2l6aW5nKEZBTFNFKSwKICAgICAgbV9yY0NhcHRpb24oMCwgMCwgMCwgMCksCiAgICAgIG1fYkVuYWxibGVOb3RpZnkoVFJVRSksCiAgICAgIG1fcFBvcHVwTm90ZShwUG9wdXBOb3RlKSB7fQoKQ1BXTF9Ob3RlOjp+Q1BXTF9Ob3RlKCkge30KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZTo6UmVwbHkoKSB7CiAgcmV0dXJuIENyZWF0ZU5vdGVJdGVtKCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpFbmFibGVOb3RpZnkoRlhfQk9PTCBiRW5hYmxlZCkgewogIG1fYkVuYWxibGVOb3RpZnkgPSBiRW5hYmxlZDsKfQoKdm9pZCBDUFdMX05vdGU6OlJlUG9zQ2hpbGRXbmQoKSB7CiAgUmVQb3NOb3RlQ2hpbGRyZW4oKTsKICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CiAgUmVzZXRTY3JvbGxCYXIoKTsKICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CiAgT25Ob3RpZnkodGhpcywgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7CiAgaWYgKGNvbnN0IENQV0xfV25kKiBwV25kID0gR2V0Rm9jdXNlZCgpKSB7CiAgICBpZiAocFduZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfRWRpdCIpIHsKICAgICAgQ1BXTF9FZGl0KiBwRWRpdCA9IChDUFdMX0VkaXQqKXBXbmQ7CiAgICAgIHBFZGl0LT5TZXRDYXJldChwRWRpdC0+R2V0Q2FyZXQoKSk7CiAgICB9CiAgfQp9CgpGWF9CT09MIENQV0xfTm90ZTo6UmVzZXRTY3JvbGxCYXIoKSB7CiAgRlhfQk9PTCBiU2Nyb2xsQ2hhbmdlZCA9IEZBTFNFOwoKICBpZiAoU2Nyb2xsQmFyU2hvdWxkVmlzaWJsZSgpKSB7CiAgICBpZiAoIW1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkgewogICAgICBtX3BDb250ZW50c0Jhci0+U2V0VmlzaWJsZShUUlVFKTsKICAgICAgaWYgKG1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkgewogICAgICAgIG1fcENvbnRlbnRzQmFyLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKICAgICAgICBiU2Nyb2xsQ2hhbmdlZCA9IFRSVUU7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgewogICAgaWYgKG1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkgewogICAgICBtX3BDb250ZW50c0Jhci0+U2V0VmlzaWJsZShGQUxTRSk7CiAgICAgIG1fcENvbnRlbnRzQmFyLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKCiAgICAgIGJTY3JvbGxDaGFuZ2VkID0gVFJVRTsKICAgIH0KICB9CgogIGlmIChiU2Nyb2xsQ2hhbmdlZCkgewogICAgQ1BERl9SZWN0IHJjTm90ZSA9IEdldENsaWVudFJlY3QoKTsKICAgIENQREZfUmVjdCByY0NvbnRlbnRzID0gbV9wQ29udGVudHMtPkdldFdpbmRvd1JlY3QoKTsKICAgIHJjQ29udGVudHMucmlnaHQgPSByY05vdGUucmlnaHQgLSAzLjBmOwogICAgaWYgKG1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkKICAgICAgcmNDb250ZW50cy5yaWdodCAtPSBQV0xfU0NST0xMQkFSX1dJRFRIOwogICAgbV9wQ29udGVudHMtPk1vdmUocmNDb250ZW50cywgVFJVRSwgVFJVRSk7CiAgICBtX3BDb250ZW50cy0+U2V0U2Nyb2xsUG9zKENQREZfUG9pbnQoMC4wZiwgMC4wZikpOwogICAgbV9wQ29udGVudHMtPkludmFsaWRhdGVSZWN0KE5VTEwpOwogIH0KCiAgcmV0dXJuIGJTY3JvbGxDaGFuZ2VkOwp9CgpGWF9CT09MIENQV0xfTm90ZTo6U2Nyb2xsQmFyU2hvdWxkVmlzaWJsZSgpIHsKICBDUERGX1JlY3QgcmNDb250ZW50c0ZhY3QgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsQXJlYSgpOwogIENQREZfUmVjdCByY0NvbnRlbnRzQ2xpZW50ID0gbV9wQ29udGVudHMtPkdldENsaWVudFJlY3QoKTsKCiAgcmV0dXJuIHJjQ29udGVudHNGYWN0LkhlaWdodCgpID4gcmNDb250ZW50c0NsaWVudC5IZWlnaHQoKTsKfQoKdm9pZCBDUFdMX05vdGU6OlNldE9wdGlvbnNUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGV4dCkgewogIGlmIChtX3BPcHRpb25zKQogICAgbV9wT3B0aW9ucy0+U2V0VGV4dChzVGV4dCk7CgogIFJlUG9zTm90ZUNoaWxkcmVuKCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpSZVBvc05vdGVDaGlsZHJlbigpIHsKICBpZiAobV9iUmVzaXppbmcpCiAgICByZXR1cm47CgogIG1fYlJlc2l6aW5nID0gVFJVRTsKCiAgaWYgKElzVmFsaWQoKSkgewogICAgQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOwoKICAgIENQREZfUmVjdCByY0ljb24gPSByY0NsaWVudDsKICAgIHJjSWNvbi50b3AgLT0gMi4wZjsKICAgIHJjSWNvbi5yaWdodCA9IHJjSWNvbi5sZWZ0ICsgMTQuMGY7CiAgICByY0ljb24uYm90dG9tID0gcmNJY29uLnRvcCAtIDE0LjBmOwogICAgcmNJY29uLk5vcm1hbGl6ZSgpOwogICAgbV9wSWNvbi0+TW92ZShyY0ljb24sIFRSVUUsIEZBTFNFKTsKICAgIG1fcEljb24tPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0ljb24pKTsKCiAgICBDUERGX1JlY3QgcmNDbG9zZUJveCA9IHJjQ2xpZW50OwogICAgcmNDbG9zZUJveC5yaWdodCAtPSAxLjBmOwogICAgcmNDbG9zZUJveC50b3AgLT0gMS4wZjsKICAgIHJjQ2xvc2VCb3gubGVmdCA9IHJjQ2xvc2VCb3gucmlnaHQgLSAxNC4wZjsKICAgIHJjQ2xvc2VCb3guYm90dG9tID0gcmNDbG9zZUJveC50b3AgLSAxNC4wZjsKICAgIHJjQ2xvc2VCb3guTm9ybWFsaXplKCk7CiAgICBtX3BDbG9zZUJveC0+TW92ZShyY0Nsb3NlQm94LCBUUlVFLCBGQUxTRSk7CiAgICBtX3BDbG9zZUJveC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjQ2xvc2VCb3gpKTsKCiAgICBDUERGX1JlY3QgcmNEYXRlID0gcmNDbGllbnQ7CiAgICByY0RhdGUucmlnaHQgPSByY0Nsb3NlQm94LmxlZnQgLSBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOwogICAgcmNEYXRlLmxlZnQgPQogICAgICAgIFBXTF9NQVgocmNEYXRlLnJpZ2h0IC0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSAtIDEuMGYsCiAgICAgICAgICAgICAgICByY0ljb24ucmlnaHQgKyAxLjBmKTsKICAgIHJjRGF0ZS50b3AgPSByY0NsaWVudC50b3AgLSAyLjBmOwogICAgcmNEYXRlLmJvdHRvbSA9IHJjRGF0ZS50b3AgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKICAgIHJjRGF0ZS5Ob3JtYWxpemUoKTsKICAgIG1fcERhdGVUaW1lLT5Nb3ZlKHJjRGF0ZSwgVFJVRSwgRkFMU0UpOwogICAgbV9wRGF0ZVRpbWUtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0RhdGUpKTsKCiAgICBDUERGX1JlY3QgcmNTdWJqZWN0ID0gcmNDbGllbnQ7CiAgICByY1N1YmplY3QudG9wID0gcmNDbGllbnQudG9wIC0gMi4wZjsKICAgIHJjU3ViamVjdC5sZWZ0ID0gcmNJY29uLnJpZ2h0ICsgUE9QVVBfSVRFTV9URVhUX0lOREVOVDsKICAgIHJjU3ViamVjdC5yaWdodCA9CiAgICAgICAgUFdMX01JTihyY1N1YmplY3QubGVmdCArIG1fcFN1YmplY3QtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSArIDEuMGYsCiAgICAgICAgICAgICAgICByY0RhdGUubGVmdCAtIDEuMGYpOwogICAgcmNTdWJqZWN0LmJvdHRvbSA9IHJjU3ViamVjdC50b3AgLSBtX3BTdWJqZWN0LT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwogICAgcmNTdWJqZWN0Lk5vcm1hbGl6ZSgpOwogICAgbV9wU3ViamVjdC0+TW92ZShyY1N1YmplY3QsIFRSVUUsIEZBTFNFKTsKICAgIG1fcFN1YmplY3QtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY1N1YmplY3QpKTsKCiAgICBDUERGX1JlY3QgcmNPcHRpb25zID0gcmNDbGllbnQ7CiAgICByY09wdGlvbnMubGVmdCA9CiAgICAgICAgUFdMX01BWChyY09wdGlvbnMucmlnaHQgLSBtX3BPcHRpb25zLT5HZXRDb250ZW50UmVjdCgpLldpZHRoKCksCiAgICAgICAgICAgICAgICByY0ljb24ucmlnaHQgKyAxLjBmKTsKICAgIHJjT3B0aW9ucy50b3AgPSByY1N1YmplY3QuYm90dG9tIC0gNC4wZjsKICAgIHJjT3B0aW9ucy5ib3R0b20gPSByY09wdGlvbnMudG9wIC0gbV9wT3B0aW9ucy0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKICAgIHJjT3B0aW9ucy5Ob3JtYWxpemUoKTsKICAgIG1fcE9wdGlvbnMtPk1vdmUocmNPcHRpb25zLCBUUlVFLCBGQUxTRSk7CiAgICBtX3BPcHRpb25zLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNPcHRpb25zKSk7CgogICAgQ1BERl9SZWN0IHJjQXV0aG9yID0gcmNDbGllbnQ7CiAgICByY0F1dGhvci50b3AgPSByY1N1YmplY3QuYm90dG9tIC0gNC4wZjsKICAgIHJjQXV0aG9yLmxlZnQgPSByY1N1YmplY3QubGVmdDsKICAgIHJjQXV0aG9yLnJpZ2h0ID0KICAgICAgICBQV0xfTUlOKHJjU3ViamVjdC5sZWZ0ICsgbV9wQXV0aG9yLT5HZXRDb250ZW50UmVjdCgpLldpZHRoKCkgKyAxLjBmLAogICAgICAgICAgICAgICAgcmNPcHRpb25zLmxlZnQgLSAxLjBmKTsKICAgIHJjQXV0aG9yLmJvdHRvbSA9IHJjQXV0aG9yLnRvcCAtIG1fcEF1dGhvci0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKICAgIHJjQXV0aG9yLk5vcm1hbGl6ZSgpOwogICAgbV9wQXV0aG9yLT5Nb3ZlKHJjQXV0aG9yLCBUUlVFLCBGQUxTRSk7CiAgICBtX3BBdXRob3ItPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0F1dGhvcikpOwoKICAgIENQREZfUmVjdCByY0xCQm94ID0gcmNDbGllbnQ7CiAgICByY0xCQm94LnRvcCA9IHJjTEJCb3guYm90dG9tICsgNy4wZjsKICAgIHJjTEJCb3gucmlnaHQgPSByY0xCQm94LmxlZnQgKyA3LjBmOwogICAgcmNMQkJveC5Ob3JtYWxpemUoKTsKICAgIG1fcExCQm94LT5Nb3ZlKHJjTEJCb3gsIFRSVUUsIEZBTFNFKTsKICAgIG1fcExCQm94LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNMQkJveCkpOwoKICAgIENQREZfUmVjdCByY1JCQm94ID0gcmNDbGllbnQ7CiAgICByY1JCQm94LnRvcCA9IHJjUkJCb3guYm90dG9tICsgNy4wZjsKICAgIHJjUkJCb3gubGVmdCA9IHJjUkJCb3gucmlnaHQgLSA3LjBmOwogICAgcmNSQkJveC5Ob3JtYWxpemUoKTsKICAgIG1fcFJCQm94LT5Nb3ZlKHJjUkJCb3gsIFRSVUUsIEZBTFNFKTsKICAgIG1fcFJCQm94LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNSQkJveCkpOwoKICAgIENQREZfUmVjdCByY0NvbnRlbnRzID0gcmNDbGllbnQ7CiAgICByY0NvbnRlbnRzLnRvcCA9IHJjQXV0aG9yLmJvdHRvbSAtIFBPUFVQX0lURU1fSEVBRF9CT1RUT007CiAgICByY0NvbnRlbnRzLmxlZnQgKz0gMy4wZjsKICAgIHJjQ29udGVudHMucmlnaHQgLT0gMy4wZjsKICAgIGlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpCiAgICAgIHJjQ29udGVudHMucmlnaHQgLT0gUFdMX1NDUk9MTEJBUl9XSURUSDsKICAgIHJjQ29udGVudHMuYm90dG9tICs9IDE0LjBmOwogICAgcmNDb250ZW50cy5Ob3JtYWxpemUoKTsKICAgIG1fcENvbnRlbnRzLT5Nb3ZlKHJjQ29udGVudHMsIEZBTFNFLCBGQUxTRSk7CiAgICBtX3BDb250ZW50cy0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjQ29udGVudHMpKTsKCiAgICBDUERGX1JlY3QgcmNDb250ZW50c0JhciA9IHJjQ29udGVudHM7CiAgICByY0NvbnRlbnRzQmFyLnJpZ2h0ID0gcmNDbGllbnQucmlnaHQgLSAzLjBmOwogICAgcmNDb250ZW50c0Jhci5sZWZ0ID0gcmNDb250ZW50c0Jhci5yaWdodCAtIFBXTF9TQ1JPTExCQVJfV0lEVEg7CiAgICByY0NvbnRlbnRzQmFyLk5vcm1hbGl6ZSgpOwogICAgbV9wQ29udGVudHNCYXItPk1vdmUocmNDb250ZW50c0JhciwgVFJVRSwgRkFMU0UpOwoKICAgIG1fcmNDYXB0aW9uID0gcmNDbGllbnQ7CiAgICBtX3JjQ2FwdGlvbi5ib3R0b20gPSByY0NvbnRlbnRzLnRvcDsKICB9CgogIG1fYlJlc2l6aW5nID0gRkFMU0U7Cn0KCi8vIFRPRE8odGhlc3RpZyk6IE1ha2UgdGhpcyByZXR1cm4gYW4gZW51bS4KLy8gMC1ub3JtYWwgLyAxLWNhcHRpb24gLyAyLWxlZnRib3R0b20gY29ybmVyIC8gMy1yaWdodGJvdHRvbSBjb3JuZXIgLyA0LWNsb3NlIC8KLy8gNS1vcHRpb25zCmludDMyX3QgQ1BXTF9Ob3RlOjpOb3RlSGl0VGVzdChjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3QgewogIEdldENsaWVudFJlY3QoKTsKCiAgaWYgKG1fcFN1YmplY3QtPlduZEhpdFRlc3QobV9wU3ViamVjdC0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDE7CiAgaWYgKG1fcERhdGVUaW1lLT5XbmRIaXRUZXN0KG1fcERhdGVUaW1lLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpCiAgICByZXR1cm4gMTsKICBpZiAobV9wQXV0aG9yLT5XbmRIaXRUZXN0KG1fcEF1dGhvci0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDE7CiAgaWYgKG1fcEljb24tPlduZEhpdFRlc3QobV9wSWNvbi0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDE7CgogIGlmIChtX3BDb250ZW50cy0+V25kSGl0VGVzdChtX3BDb250ZW50cy0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDA7CiAgaWYgKG1fcENvbnRlbnRzQmFyLT5XbmRIaXRUZXN0KG1fcENvbnRlbnRzQmFyLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpCiAgICByZXR1cm4gMDsKCiAgaWYgKG1fcENsb3NlQm94LT5XbmRIaXRUZXN0KG1fcENsb3NlQm94LT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpCiAgICByZXR1cm4gNDsKICBpZiAobV9wTEJCb3gtPlduZEhpdFRlc3QobV9wTEJCb3gtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkKICAgIHJldHVybiAyOwogIGlmIChtX3BSQkJveC0+V25kSGl0VGVzdChtX3BSQkJveC0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDM7CiAgaWYgKG1fcE9wdGlvbnMtPlduZEhpdFRlc3QobV9wT3B0aW9ucy0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDU7CgogIHJldHVybiAxOwp9Cgp2b2lkIENQV0xfTm90ZTo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNJiBjcCkgewogIENQV0xfTm90ZUl0ZW06OkNyZWF0ZUNoaWxkV25kKGNwKTsKCiAgQ1BXTF9Db2xvciBzVGV4dENvbG9yOwoKICBpZiAoQ1BXTF9VdGlsczo6SXNCbGFja09yV2hpdGUoR2V0QmFja2dyb3VuZENvbG9yKCkpKQogICAgc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CiAgZWxzZQogICAgc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7CgogIG1fcEF1dGhvciA9IG5ldyBDUFdMX0xhYmVsOwogIFBXTF9DUkVBVEVQQVJBTSBhY3AgPSBjcDsKICBhY3AucFBhcmVudFduZCA9IHRoaXM7CiAgYWNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBFU19MRUZUIHwgUEVTX1RPUDsKICBhY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CiAgbV9wQXV0aG9yLT5DcmVhdGUoYWNwKTsKCiAgbV9wQ2xvc2VCb3ggPSBuZXcgQ1BXTF9Ob3RlX0Nsb3NlQm94OwogIFBXTF9DUkVBVEVQQVJBTSBjY3AgPSBjcDsKICBjY3AucFBhcmVudFduZCA9IHRoaXM7CiAgY2NwLmR3Qm9yZGVyV2lkdGggPSAyOwogIGNjcC5uQm9yZGVyU3R5bGUgPSBQQlNfQkVWRUxFRDsKICBjY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUFdTX0JPUkRFUjsKICBjY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CiAgbV9wQ2xvc2VCb3gtPkNyZWF0ZShjY3ApOwoKICBtX3BJY29uID0gbmV3IENQV0xfTm90ZV9JY29uOwogIFBXTF9DUkVBVEVQQVJBTSBpY3AgPSBjcDsKICBpY3AucFBhcmVudFduZCA9IHRoaXM7CiAgaWNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRDsKICBtX3BJY29uLT5DcmVhdGUoaWNwKTsKCiAgbV9wT3B0aW9ucyA9IG5ldyBDUFdMX05vdGVfT3B0aW9uczsKICBQV0xfQ1JFQVRFUEFSQU0gb2NwID0gY3A7CiAgb2NwLnBQYXJlbnRXbmQgPSB0aGlzOwogIG9jcC5kd0ZsYWdzID0gUFdTX0NISUxEIHwgUFdTX1ZJU0lCTEU7CiAgb2NwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOwogIG1fcE9wdGlvbnMtPkNyZWF0ZShvY3ApOwoKICBtX3BMQkJveCA9IG5ldyBDUFdMX05vdGVfTEJCb3g7CiAgUFdMX0NSRUFURVBBUkFNIGxjcCA9IGNwOwogIGxjcC5wUGFyZW50V25kID0gdGhpczsKICBsY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEOwogIGxjcC5lQ3Vyc29yVHlwZSA9IEZYQ1RfTkVTVzsKICBsY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CiAgbV9wTEJCb3gtPkNyZWF0ZShsY3ApOwoKICBtX3BSQkJveCA9IG5ldyBDUFdMX05vdGVfUkJCb3g7CiAgUFdMX0NSRUFURVBBUkFNIHJjcCA9IGNwOwogIHJjcC5wUGFyZW50V25kID0gdGhpczsKICByY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEOwogIHJjcC5lQ3Vyc29yVHlwZSA9IEZYQ1RfTldTRTsKICByY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CiAgbV9wUkJCb3gtPkNyZWF0ZShyY3ApOwoKICBtX3BDb250ZW50c0JhciA9IG5ldyBDUFdMX1Njcm9sbEJhcihTQlRfVlNDUk9MTCk7CiAgUFdMX0NSRUFURVBBUkFNIHNjcCA9IGNwOwogIHNjcC5wUGFyZW50V25kID0gdGhpczsKICBzY3Auc0JhY2tncm91bmRDb2xvciA9CiAgICAgIENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgMjQwIC8gMjU1LjBmLCAyNDAgLyAyNTUuMGYsIDI0MCAvIDI1NS4wZik7CiAgc2NwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRSB8IFBXU19CQUNLR1JPVU5EOwogIG1fcENvbnRlbnRzQmFyLT5DcmVhdGUoc2NwKTsKICBtX3BDb250ZW50c0Jhci0+U2V0Tm90aWZ5Rm9yZXZlcihUUlVFKTsKfQoKdm9pZCBDUFdMX05vdGU6OlNldFN1YmplY3ROYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkgewogIENQV0xfTm90ZUl0ZW06OlNldFN1YmplY3ROYW1lKHNOYW1lKTsKICBSZVBvc0NoaWxkV25kKCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpTZXRBdXRob3JOYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkgewogIGlmIChtX3BBdXRob3IpIHsKICAgIG1fcEF1dGhvci0+U2V0VGV4dChzTmFtZS5jX3N0cigpKTsKICAgIFJlUG9zQ2hpbGRXbmQoKTsKICB9CgogIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgIHBOb3RpZnktPk9uU2V0QXV0aG9yTmFtZSh0aGlzKTsKICB9Cn0KCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZTo6R2V0QXV0aG9yTmFtZSgpIGNvbnN0IHsKICBpZiAobV9wQXV0aG9yKQogICAgcmV0dXJuIG1fcEF1dGhvci0+R2V0VGV4dCgpOwoKICByZXR1cm4gTCIiOwp9CgpGWF9CT09MIENQV0xfTm90ZTo6T25Nb3VzZVdoZWVsKHNob3J0IHpEZWx0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDUERGX1BvaW50JiBwb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWF9EV09SRCBuRmxhZykgewogIENQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7CiAgQ1BERl9SZWN0IHJjU2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbEFyZWEoKTsKICBDUERGX1JlY3QgcmNDb250ZW50cyA9IG1fcENvbnRlbnRzLT5HZXRDbGllbnRSZWN0KCk7CgogIGlmIChyY1Njcm9sbC50b3AgLSByY1Njcm9sbC5ib3R0b20gPiByY0NvbnRlbnRzLkhlaWdodCgpKSB7CiAgICBDUERGX1BvaW50IHB0TmV3ID0gcHRTY3JvbGw7CgogICAgaWYgKHpEZWx0YSA+IDApCiAgICAgIHB0TmV3LnkgKz0gMzA7CiAgICBlbHNlCiAgICAgIHB0TmV3LnkgLT0gMzA7CgogICAgaWYgKHB0TmV3LnkgPiByY1Njcm9sbC50b3ApCiAgICAgIHB0TmV3LnkgPSByY1Njcm9sbC50b3A7CiAgICBpZiAocHROZXcueSA8IHJjU2Nyb2xsLmJvdHRvbSArIHJjQ29udGVudHMuSGVpZ2h0KCkpCiAgICAgIHB0TmV3LnkgPSByY1Njcm9sbC5ib3R0b20gKyByY0NvbnRlbnRzLkhlaWdodCgpOwogICAgaWYgKHB0TmV3LnkgPCByY1Njcm9sbC5ib3R0b20pCiAgICAgIHB0TmV3LnkgPSByY1Njcm9sbC5ib3R0b207CgogICAgaWYgKHB0TmV3LnkgIT0gcHRTY3JvbGwueSkgewogICAgICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CiAgICAgIG1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRwdHJfdCkmcHROZXcueSk7CiAgICAgIG1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUU0NST0xMUE9TLCBTQlRfVlNDUk9MTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRwdHJfdCkmcHROZXcueSk7CgogICAgICByZXR1cm4gVFJVRTsKICAgIH0KICB9CgogIHJldHVybiBGQUxTRTsKfQoKdm9pZCBDUFdMX05vdGU6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLAogICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgbXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgaW50cHRyX3Qgd1BhcmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgaW50cHRyX3QgbFBhcmFtKSB7CiAgc3dpdGNoIChtc2cpIHsKICAgIGNhc2UgUE5NX05PVEVFRElUQ0hBTkdFRDogewogICAgICBDUERGX1JlY3QgcmNTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsQXJlYSgpOwoKICAgICAgUFdMX1NDUk9MTF9JTkZPIHNJbmZvOwogICAgICBzSW5mby5mQ29udGVudE1pbiA9IHJjU2Nyb2xsLmJvdHRvbTsKICAgICAgc0luZm8uZkNvbnRlbnRNYXggPSByY1Njcm9sbC50b3A7CiAgICAgIHNJbmZvLmZQbGF0ZVdpZHRoID0gbV9wQ29udGVudHMtPkdldENsaWVudFJlY3QoKS5IZWlnaHQoKTsKICAgICAgc0luZm8uZlNtYWxsU3RlcCA9IDEzLjBmOwogICAgICBzSW5mby5mQmlnU3RlcCA9IHNJbmZvLmZQbGF0ZVdpZHRoOwoKICAgICAgaWYgKEZYU1lTX21lbWNtcCgmbV9PbGRTY3JvbGxJbmZvLCAmc0luZm8sIHNpemVvZihQV0xfU0NST0xMX0lORk8pKSAhPQogICAgICAgICAgMCkgewogICAgICAgIEZYX0JPT0wgYlNjcm9sbENoYW5nZWQgPSBGQUxTRTsKCiAgICAgICAgaWYgKGxQYXJhbSA8IDMpICAvL7fA1rnLwNGtu7cgbWFudGlzOjE1NzU5CiAgICAgICAgewogICAgICAgICAgYlNjcm9sbENoYW5nZWQgPSBSZXNldFNjcm9sbEJhcigpOwogICAgICAgICAgaWYgKGJTY3JvbGxDaGFuZ2VkKSB7CiAgICAgICAgICAgIGxQYXJhbSsrOwogICAgICAgICAgICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CiAgICAgICAgICAgIE9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIGxQYXJhbSk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWJTY3JvbGxDaGFuZ2VkKSB7CiAgICAgICAgICBpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKSB7CiAgICAgICAgICAgIG1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeShwV25kLCBQTk1fU0VUU0NST0xMSU5GTywgU0JUX1ZTQ1JPTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50cHRyX3QpJnNJbmZvKTsKICAgICAgICAgICAgbV9PbGRTY3JvbGxJbmZvID0gc0luZm87CgogICAgICAgICAgICBDUERGX1BvaW50IHB0U2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbFBvcygpOwogICAgICAgICAgICBDUERGX1BvaW50IHB0T2xkID0gcHRTY3JvbGw7CgogICAgICAgICAgICBpZiAocHRTY3JvbGwueSA+IHNJbmZvLmZDb250ZW50TWF4KQogICAgICAgICAgICAgIHB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1heDsKICAgICAgICAgICAgaWYgKHB0U2Nyb2xsLnkgPCBzSW5mby5mQ29udGVudE1pbiArIHNJbmZvLmZQbGF0ZVdpZHRoKQogICAgICAgICAgICAgIHB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1pbiArIHNJbmZvLmZQbGF0ZVdpZHRoOwogICAgICAgICAgICBpZiAocHRTY3JvbGwueSA8IHNJbmZvLmZDb250ZW50TWluKQogICAgICAgICAgICAgIHB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1pbjsKCiAgICAgICAgICAgIGlmIChwdE9sZC55ICE9IHB0U2Nyb2xsLnkpIHsKICAgICAgICAgICAgICBtX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRwdHJfdCkmcHRTY3JvbGwueSk7CiAgICAgICAgICAgICAgbV9wQ29udGVudHNCYXItPkludmFsaWRhdGVSZWN0KE5VTEwpOwogICAgICAgICAgICAgIG1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludHB0cl90KSZwdFNjcm9sbC55KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgICAgbV9wQ29udGVudHMtPkludmFsaWRhdGVSZWN0KE5VTEwpOwoKICAgICAgcmV0dXJuOwogICAgY2FzZSBQTk1fU0NST0xMV0lORE9XOgogICAgICBpZiAobV9wQ29udGVudHMpCiAgICAgICAgbV9wQ29udGVudHMtPk9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgICByZXR1cm47CiAgICBjYXNlIFBOTV9TRVRTQ1JPTExQT1M6CiAgICAgIGlmIChtX3BDb250ZW50c0JhcikKICAgICAgICBtX3BDb250ZW50c0Jhci0+T25Ob3RpZnkocFduZCwgUE5NX1NFVFNDUk9MTFBPUywgd1BhcmFtLCBsUGFyYW0pOwogICAgICByZXR1cm47CiAgfQoKICBpZiAobXNnID09IFBOTV9TRVRDQVJFVElORk8gJiYgSXNWYWxpZCgpKSB7CiAgICBpZiAoUFdMX0NBUkVUX0lORk8qIHBJbmZvID0gKFBXTF9DQVJFVF9JTkZPKil3UGFyYW0pIHsKICAgICAgaWYgKG1fcENvbnRlbnRzKSB7CiAgICAgICAgQ1BERl9SZWN0IHJjQ2xpZW50ID0gbV9wQ29udGVudHMtPkdldENsaWVudFJlY3QoKTsKICAgICAgICBpZiAocEluZm8tPnB0SGVhZC55ID4gcmNDbGllbnQudG9wKSB7CiAgICAgICAgICBDUERGX1BvaW50IHB0ID0gbV9wQ29udGVudHMtPk91dFRvSW4ocEluZm8tPnB0SGVhZCk7CiAgICAgICAgICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludHB0cl90KSZwdC55KTsKCiAgICAgICAgICBDUERGX1BvaW50IHB0U2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbFBvcygpOwogICAgICAgICAgbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRwdHJfdCkmcHRTY3JvbGwueSk7CgogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKHBJbmZvLT5wdEZvb3QueSA8IHJjQ2xpZW50LmJvdHRvbSkgewogICAgICAgICAgQ1BERl9Qb2ludCBwdCA9IG1fcENvbnRlbnRzLT5PdXRUb0luKHBJbmZvLT5wdEZvb3QpOwogICAgICAgICAgcHQueSArPSByY0NsaWVudC5IZWlnaHQoKTsKICAgICAgICAgIG1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50cHRyX3QpJnB0LnkpOwoKICAgICAgICAgIENQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7CiAgICAgICAgICBtX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludHB0cl90KSZwdFNjcm9sbC55KTsKCiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICBDUFdMX05vdGVJdGVtOjpPbk5vdGlmeShwV25kLCBtc2csIHdQYXJhbSwgbFBhcmFtKTsKfQoKdm9pZCBDUFdMX05vdGU6OlNldEJrQ29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpIHsKICBDUFdMX05vdGVJdGVtOjpTZXRCa0NvbG9yKGNvbG9yKTsKCiAgQ1BXTF9Db2xvciBzQksgPSBjb2xvcjsKICBDUFdMX0NvbG9yIHNUZXh0Q29sb3I7CiAgaWYgKENQV0xfVXRpbHM6OklzQmxhY2tPcldoaXRlKHNCSykpCiAgICBzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsKICBlbHNlCiAgICBzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUjsKCiAgaWYgKG1fcENsb3NlQm94KQogICAgbV9wQ2xvc2VCb3gtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKICBpZiAobV9wQXV0aG9yKQogICAgbV9wQXV0aG9yLT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CiAgaWYgKG1fcE9wdGlvbnMpCiAgICBtX3BPcHRpb25zLT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CiAgaWYgKG1fcExCQm94KQogICAgbV9wTEJCb3gtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKICBpZiAobV9wUkJCb3gpCiAgICBtX3BSQkJveC0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOwp9CgpGWF9CT09MIENQV0xfTm90ZTo6T25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50JiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpIHsKICBpZiAobV9wT3B0aW9ucy0+V25kSGl0VGVzdChtX3BPcHRpb25zLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHsKICAgIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgICAgaW50MzJfdCB4LCB5OwogICAgICBQV0x0b1duZChwb2ludCwgeCwgeSk7CiAgICAgIGlmIChJRlhfU3lzdGVtSGFuZGxlciogcFNIID0gR2V0U3lzdGVtSGFuZGxlcigpKQogICAgICAgIHBTSC0+Q2xpZW50VG9TY3JlZW4oR2V0QXR0YWNoZWRIV25kKCksIHgsIHkpOwogICAgICBLaWxsRm9jdXMoKTsKICAgICAgcE5vdGlmeS0+T25Qb3B1cE1lbnUoeCwgeSk7CgogICAgICByZXR1cm4gVFJVRTsKICAgIH0KICB9CgogIHJldHVybiBDUFdMX1duZDo6T25MQnV0dG9uRG93bihwb2ludCwgbkZsYWcpOwp9CgpGWF9CT09MIENQV0xfTm90ZTo6T25SQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKSB7CiAgcmV0dXJuIENQV0xfV25kOjpPblJCdXR0b25VcChwb2ludCwgbkZsYWcpOwp9Cgpjb25zdCBDUFdMX05vdGUqIENQV0xfTm90ZTo6R2V0Tm90ZSgpIGNvbnN0IHsKICByZXR1cm4gdGhpczsKfQoKSVBXTF9Ob3RlTm90aWZ5KiBDUFdMX05vdGU6OkdldE5vdGVOb3RpZnkoKSBjb25zdCB7CiAgaWYgKG1fYkVuYWxibGVOb3RpZnkpCiAgICByZXR1cm4gbV9wTm90ZU5vdGlmeTsKCiAgcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpTZXRJY29uVHlwZShpbnQzMl90IG5UeXBlKSB7CiAgaWYgKG1fcEljb24pCiAgICBtX3BJY29uLT5TZXRJY29uVHlwZShuVHlwZSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpFbmFibGVNb2RpZnkoRlhfQk9PTCBiRW5hYmxlZCkgewogIG1fcENvbnRlbnRzLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOwp9Cgp2b2lkIENQV0xfTm90ZTo6RW5hYmxlUmVhZChGWF9CT09MIGJFbmFibGVkKSB7CiAgbV9wQ29udGVudHMtPkVuYWJsZVJlYWQoYkVuYWJsZWQpOwp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGU6OkdldFJlcGx5U3RyaW5nKCkgY29uc3QgewogIHJldHVybiBtX3NSZXBseVN0cmluZzsKfQoKdm9pZCBDUFdMX05vdGU6OlNldFJlcGx5U3RyaW5nKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJpbmcpIHsKICBtX3NSZXBseVN0cmluZyA9IHN0cmluZzsKfQo=