LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfc3cuaHh4IgoKI2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPGFsZ29yaXRobT4KCiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvY2hhcnQvQ2hhcnREYXRhUm93U291cmNlLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9jaGFydDIvZGF0YS9MYWJlbE9yaWdpbi5ocHA+CiNpbmNsdWRlIDxjcHB1aGVscGVyL2ludGVyZmFjZWNvbnRhaW5lci5oeHg+CiNpbmNsdWRlIDx2b3MvbXV0ZXguaHh4PgojaW5jbHVkZSA8b3NsL211dGV4Lmh4eD4KI2luY2x1ZGUgPHZjbC9zdmFwcC5oeHg+CiNpbmNsdWRlIDxzdmwvemZvcmxpc3QuaHh4PiAgICAgLy8gU3ZOdW1iZXJGb3JtYXR0ZXIKI2luY2x1ZGUgPHN2eC9jaGFydGhlbHBlci5oeHg+CgojaW5jbHVkZSA8dG9vbHMvbGluay5oeHg+CgojaW5jbHVkZSA8WE1MUmFuZ2VIZWxwZXIuaHh4PgojaW5jbHVkZSA8dW5vY2hhcnQuaHh4PgojaW5jbHVkZSA8c3d0YWJsZS5oeHg+CiNpbmNsdWRlIDx1bm9wcm5tcy5oeHg+CiNpbmNsdWRlIDx1bm9tYXAuaHh4PgojaW5jbHVkZSA8dW5vbWlkLmg+CiNpbmNsdWRlIDx1bm9jcnNyLmh4eD4KI2luY2x1ZGUgPHVub3RibC5oeHg+CiNpbmNsdWRlIDxkb2MuaHh4PgojaW5jbHVkZSA8ZnJtZm10Lmh4eD4KI2luY2x1ZGUgPGRvY3NoLmh4eD4KI2luY2x1ZGUgPG5kb2xlLmh4eD4KI2luY2x1ZGUgPHN3dGFibGUuaHh4PgojaW5jbHVkZSA8c3d0eXBlcy5oeHg+CiNpZm5kZWYgX1VOT0NPUkVfSFJDCiNpbmNsdWRlIDx1bm9jb3JlLmhyYz4KI2VuZGlmCgojaW5jbHVkZSA8ZG9jYXJ5Lmh4eD4KCiNkZWZpbmUgU05fREFUQV9QUk9WSURFUiAgICAgICAgICAgICJjb20uc3VuLnN0YXIuY2hhcnQyLmRhdGEuRGF0YVByb3ZpZGVyIgojZGVmaW5lIFNOX0RBVEFfU09VUkNFICAgICAgICAgICAgICAiY29tLnN1bi5zdGFyLmNoYXJ0Mi5kYXRhLkRhdGFTb3VyY2UiCiNkZWZpbmUgU05fREFUQV9TRVFVRU5DRSAgICAgICAgICAgICJjb20uc3VuLnN0YXIuY2hhcnQyLmRhdGEuRGF0YVNlcXVlbmNlIgojZGVmaW5lIFNOX0xBQkVMRURfREFUQV9TRVFVRU5DRSAgICAiY29tLnN1bi5zdGFyLmNoYXJ0Mi5kYXRhLkxhYmVsZWREYXRhU2VxdWVuY2UiCgojZGVmaW5lIERJUkVDVElPTl9ET05UX0tOT1cgICAgIC0xCiNkZWZpbmUgRElSRUNUSU9OX0hBU19FUlJPUiAgICAgLTIKI2RlZmluZSBESVJFQ1RJT05fQ09MUyAgICAgICAgICAgMAojZGVmaW5lIERJUkVDVElPTl9ST1dTICAgICAgICAgICAxCgp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3RhcjsKdXNpbmcgOjpydGw6Ok9VU3RyaW5nOwoKLy8gZnJvbSB1bm90YmwuY3h4CmV4dGVybiB2b2lkIGxjbF9HZXRDZWxsUG9zaXRpb24oIGNvbnN0IFN0cmluZyAmckNlbGxOYW1lLCBzYWxfSW50MzIgJnJDb2x1bW4sIHNhbF9JbnQzMiAmclJvdyk7CmV4dGVybiBTdHJpbmcgbGNsX0dldENlbGxOYW1lKCBzYWxfSW50MzIgbkNvbHVtbiwgc2FsX0ludDMyIG5Sb3cgKTsKZXh0ZXJuIGludCBsY2xfQ29tcGFyZUNlbGxzQnlDb2xGaXJzdCggY29uc3QgU3RyaW5nICZyQ2VsbE5hbWUxLCBjb25zdCBTdHJpbmcgJnJDZWxsTmFtZTIgKTsKZXh0ZXJuIGludCBsY2xfQ29tcGFyZUNlbGxzQnlSb3dGaXJzdCggY29uc3QgU3RyaW5nICZyQ2VsbE5hbWUxLCBjb25zdCBTdHJpbmcgJnJDZWxsTmFtZTIgKTsKZXh0ZXJuIGludCBsY2xfQ29tcGFyZUNlbGxSYW5nZXMoCiAgICAgICAgY29uc3QgU3RyaW5nICZyUmFuZ2UxU3RhcnRDZWxsLCBjb25zdCBTdHJpbmcgJnJSYW5nZTFFbmRDZWxsLAogICAgICAgIGNvbnN0IFN0cmluZyAmclJhbmdlMlN0YXJ0Q2VsbCwgY29uc3QgU3RyaW5nICZyUmFuZ2UyRW5kQ2VsbCwKICAgICAgICBzYWxfQm9vbCBiQ21wQ29sc0ZpcnN0ICk7CmV4dGVybiB2b2lkIGxjbF9Ob3JtYWxpemVSYW5nZSggU3RyaW5nICZyQ2VsbDEsIFN0cmluZyAmckNlbGwyICk7CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgovL3N0YXRpYwp2b2lkIFN3Q2hhcnRIZWxwZXI6OkRvVXBkYXRlQWxsQ2hhcnRzKCBTd0RvYyogcERvYyApCnsKICAgIGlmICghcERvYykKICAgICAgICByZXR1cm47CgogICAgdW5vOjpSZWZlcmVuY2U8IGZyYW1lOjpYTW9kZWwgPiB4UmVzOwoKICAgIFN3T0xFTm9kZSAqcE9OZDsKICAgIFN3U3RhcnROb2RlICpwU3ROZDsKICAgIFN3Tm9kZUluZGV4IGFJZHgoICpwRG9jLT5HZXROb2RlcygpLkdldEVuZE9mQXV0b3RleHQoKS5TdGFydE9mU2VjdGlvbk5vZGUoKSwgMSApOwogICAgd2hpbGUoIDAgIT0gKHBTdE5kID0gYUlkeC5HZXROb2RlKCkuR2V0U3RhcnROb2RlKCkpICkKICAgIHsKICAgICAgICBhSWR4Kys7CiAgICAgICAgaWYgKDAgIT0gKCBwT05kID0gYUlkeC5HZXROb2RlKCkuR2V0T0xFTm9kZSgpICkgJiYKICAgICAgICAgICAgQ2hhcnRIZWxwZXI6OklzQ2hhcnQoIHBPTmQtPkdldE9MRU9iaigpLkdldE9iamVjdCgpICkgKQogICAgICAgIHsKICAgICAgICAgICAgLy8gTG9hZCB0aGUgb2JqZWN0IGFuZCBzZXQgbW9kaWZpZWQKCiAgICAgICAgICAgIHVubzo6UmVmZXJlbmNlIDwgZW1iZWQ6OlhFbWJlZGRlZE9iamVjdCA+IHhJUCA9IHBPTmQtPkdldE9MRU9iaigpLkdldE9sZVJlZigpOwogICAgICAgICAgICBpZiAoIHN2dDo6RW1iZWRkZWRPYmplY3RSZWY6OlRyeVJ1bm5pbmdTdGF0ZSggeElQICkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB1bm86OlJlZmVyZW5jZTwgdXRpbDo6WE1vZGlmaWFibGUgPiB4TW9kaWYoIHhJUC0+Z2V0Q29tcG9uZW50KCksIHVubzo6VU5PX1FVRVJZX1RIUk9XICk7CiAgICAgICAgICAgICAgICAgICAgeE1vZGlmLT5zZXRNb2RpZmllZCggc2FsX1RydWUgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhdGNoICggdW5vOjpFeGNlcHRpb24mICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGFJZHguQXNzaWduKCAqcFN0TmQtPkVuZE9mU2VjdGlvbk5vZGUoKSwgKyAxICk7CiAgICB9Cn0KCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KClN3Q2hhcnRMb2NrQ29udHJvbGxlcl9IZWxwZXI6OlN3Q2hhcnRMb2NrQ29udHJvbGxlcl9IZWxwZXIoIFN3RG9jICpwRG9jdW1lbnQgKSA6CiAgICBwRG9jKCBwRG9jdW1lbnQgKQp7CiAgICBhVW5sb2NrVGltZXIuU2V0VGltZW91dCggMTUwMCApOwogICAgYVVubG9ja1RpbWVyLlNldFRpbWVvdXRIZGwoIExJTksoIHRoaXMsIFN3Q2hhcnRMb2NrQ29udHJvbGxlcl9IZWxwZXIsIERvVW5sb2NrQWxsQ2hhcnRzICkpOwp9CgoKU3dDaGFydExvY2tDb250cm9sbGVyX0hlbHBlcjo6flN3Q2hhcnRMb2NrQ29udHJvbGxlcl9IZWxwZXIoKQp7CiAgICBpZiAocERvYykgICAvLyBzdGlsbCBjb25uZWN0ZWQ/CiAgICAgICAgRGlzY29ubmVjdCgpOwp9CgoKdm9pZCBTd0NoYXJ0TG9ja0NvbnRyb2xsZXJfSGVscGVyOjpTdGFydE9yQ29udGludWVMb2NraW5nKCkKewogICAgaWYgKCFiSXNMb2NrZWQpCiAgICAgICAgTG9ja0FsbENoYXJ0cygpOwogICAgYVVubG9ja1RpbWVyLlN0YXJ0KCk7ICAgLy8gc3RhcnQgb3IgY29udGludWUgdGltZSBvZiBsb2NraW5nCn0KCgp2b2lkIFN3Q2hhcnRMb2NrQ29udHJvbGxlcl9IZWxwZXI6OkRpc2Nvbm5lY3QoKQp7CiAgICBhVW5sb2NrVGltZXIuU3RvcCgpOwogICAgVW5sb2NrQWxsQ2hhcnRzKCk7CiAgICBwRG9jID0gMDsKfQoKCnZvaWQgU3dDaGFydExvY2tDb250cm9sbGVyX0hlbHBlcjo6TG9ja1VubG9ja0FsbENoYXJ0cyggc2FsX0Jvb2wgYkxvY2sgKQp7CiAgICBpZiAoIXBEb2MpCiAgICAgICAgcmV0dXJuOwoKICAgIGNvbnN0IFN3RnJtRm10cyYgclRibEZtdHMgPSAqcERvYy0+R2V0VGJsRnJtRm10cygpOwogICAgZm9yKCBzYWxfdUludDE2IG4gPSAwOyBuIDwgclRibEZtdHMuQ291bnQoKTsgKytuICkKICAgIHsKICAgICAgICBTd1RhYmxlKiBwVG1wVGJsOwogICAgICAgIGNvbnN0IFN3VGFibGVOb2RlKiBwVGJsTmQ7CiAgICAgICAgU3dGcm1GbXQqIHBGbXQgPSByVGJsRm10c1sgbiBdOwoKICAgICAgICBpZiggMCAhPSAoIHBUbXBUYmwgPSBTd1RhYmxlOjpGaW5kVGFibGUoIHBGbXQgKSApICYmCiAgICAgICAgICAgIDAgIT0gKCBwVGJsTmQgPSBwVG1wVGJsLT5HZXRUYWJsZU5vZGUoKSApICYmCiAgICAgICAgICAgIHBUYmxOZC0+R2V0Tm9kZXMoKS5Jc0RvY05vZGVzKCkgKQogICAgICAgIHsKICAgICAgICAgICAgdW5vOjpSZWZlcmVuY2U8IGZyYW1lOjpYTW9kZWwgPiB4UmVzOwoKICAgICAgICAgICAgU3RyaW5nIGFOYW1lKCBwVG1wVGJsLT5HZXRGcm1GbXQoKS0+R2V0TmFtZSgpICk7CiAgICAgICAgICAgIFN3T0xFTm9kZSAqcE9OZDsKICAgICAgICAgICAgU3dTdGFydE5vZGUgKnBTdE5kOwogICAgICAgICAgICBTd05vZGVJbmRleCBhSWR4KCAqcERvYy0+R2V0Tm9kZXMoKS5HZXRFbmRPZkF1dG90ZXh0KCkuU3RhcnRPZlNlY3Rpb25Ob2RlKCksIDEgKTsKICAgICAgICAgICAgd2hpbGUoIDAgIT0gKHBTdE5kID0gYUlkeC5HZXROb2RlKCkuR2V0U3RhcnROb2RlKCkpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYUlkeCsrOwogICAgICAgICAgICAgICAgaWYgKDAgIT0gKCBwT05kID0gYUlkeC5HZXROb2RlKCkuR2V0T0xFTm9kZSgpICkgJiYKICAgICAgICAgICAgICAgICAgICBwT05kLT5HZXRDaGFydFRibE5hbWUoKS5MZW4oKSA+IDAgLyogaXMgY2hhcnQgb2JqZWN0PyAqLykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB1bm86OlJlZmVyZW5jZSA8IGVtYmVkOjpYRW1iZWRkZWRPYmplY3QgPiB4SVAgPSBwT05kLT5HZXRPTEVPYmooKS5HZXRPbGVSZWYoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIHN2dDo6RW1iZWRkZWRPYmplY3RSZWY6OlRyeVJ1bm5pbmdTdGF0ZSggeElQICkgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgeFJlcyA9IHVubzo6UmVmZXJlbmNlIDwgZnJhbWU6OlhNb2RlbCA+KCB4SVAtPmdldENvbXBvbmVudCgpLCB1bm86OlVOT19RVUVSWSApOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoeFJlcy5pcygpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYkxvY2spCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeFJlcy0+bG9ja0NvbnRyb2xsZXJzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeFJlcy0+dW5sb2NrQ29udHJvbGxlcnMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGFJZHguQXNzaWduKCAqcFN0TmQtPkVuZE9mU2VjdGlvbk5vZGUoKSwgKyAxICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgYklzTG9ja2VkID0gYkxvY2s7Cn0KCgpJTVBMX0xJTksoIFN3Q2hhcnRMb2NrQ29udHJvbGxlcl9IZWxwZXIsIERvVW5sb2NrQWxsQ2hhcnRzLCBUaW1lciAqLCAvKnBUaW1lciovICkKewogICAgVW5sb2NrQWxsQ2hhcnRzKCk7CiAgICByZXR1cm4gMDsKfQoKCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCnN0YXRpYyBvc2w6Ok11dGV4ICYgICAgR2V0Q2hhcnRNdXRleCgpCnsKICAgIHN0YXRpYyBvc2w6Ok11dGV4ICAgYU11dGV4OwogICAgcmV0dXJuIGFNdXRleDsKfQoKCnN0YXRpYyB2b2lkIExhdW5jaE1vZGlmaWVkRXZlbnQoCgkJOjpjcHB1OjpPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyICZySUNILAoJCWNvbnN0IHVubzo6UmVmZXJlbmNlPCB1bm86OlhJbnRlcmZhY2UgPiAmcnhJICkKewogICAgbGFuZzo6RXZlbnRPYmplY3QgYUV2dE9iaiggcnhJICk7CiAgICBjcHB1OjpPSW50ZXJmYWNlSXRlcmF0b3JIZWxwZXIgYUl0KCBySUNIICk7CiAgICB3aGlsZSAoYUl0Lmhhc01vcmVFbGVtZW50cygpKQogICAgewogICAgICAgIHVubzo6UmVmZXJlbmNlPCB1dGlsOjpYTW9kaWZ5TGlzdGVuZXIgPiB4UmVmKCBhSXQubmV4dCgpLCB1bm86OlVOT19RVUVSWSApOwogICAgICAgIGlmICh4UmVmLmlzKCkpCiAgICAgICAgICAgIHhSZWYtPm1vZGlmaWVkKCBhRXZ0T2JqICk7CiAgICB9Cn0KCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCi8vIHJDZWxsUmFuZ2VOYW1lIG5lZWRzIHRvIGJlIG9mIG9uZSBvZiB0aGUgZm9sbG93aW5nIGZvcm1hdHM6Ci8vIC0gZS5nLiAiQTI6RTUiIG9yCi8vIC0gZS5nLiAiVGFibGUxLkEyOkU1IgpzYWxfQm9vbCBGaWxsUmFuZ2VEZXNjcmlwdG9yKAogICAgICAgIFN3UmFuZ2VEZXNjcmlwdG9yICZyRGVzYywKICAgICAgICBjb25zdCBTdHJpbmcgJnJDZWxsUmFuZ2VOYW1lICkKewoJeHViX1N0ckxlbiBuVG9rZW4gPSBTVFJJTkdfTk9URk9VTkQgPT0gckNlbGxSYW5nZU5hbWUuU2VhcmNoKCcuJykgPyAwIDogMTsKCVN0cmluZyBhQ2VsbFJhbmdlTm9UYWJsZU5hbWUoIHJDZWxsUmFuZ2VOYW1lLkdldFRva2VuKCBuVG9rZW4sICcuJyApICk7CiAgICBTdHJpbmcgYVRMTmFtZSggYUNlbGxSYW5nZU5vVGFibGVOYW1lLkdldFRva2VuKDAsICc6JykgKTsgIC8vIG5hbWUgb2YgdG9wIGxlZnQgY2VsbAogICAgU3RyaW5nIGFCUk5hbWUoIGFDZWxsUmFuZ2VOb1RhYmxlTmFtZS5HZXRUb2tlbigxLCAnOicpICk7ICAvLyBuYW1lIG9mIGJvdHRvbSByaWdodCBjZWxsCiAgICBpZighYVRMTmFtZS5MZW4oKSB8fCAhYUJSTmFtZS5MZW4oKSkKICAgICAgICByZXR1cm4gc2FsX0ZhbHNlOwoKICAgIHJEZXNjLm5Ub3AgPSByRGVzYy5uTGVmdCA9IHJEZXNjLm5Cb3R0b20gPSByRGVzYy5uUmlnaHQgPSAtMTsKICAgIGxjbF9HZXRDZWxsUG9zaXRpb24oIGFUTE5hbWUsIHJEZXNjLm5MZWZ0LCAgckRlc2MublRvcCApOwogICAgbGNsX0dldENlbGxQb3NpdGlvbiggYUJSTmFtZSwgckRlc2MublJpZ2h0LCByRGVzYy5uQm90dG9tICk7CiAgICByRGVzYy5Ob3JtYWxpemUoKTsKICAgIERCR19BU1NFUlQoIHJEZXNjLm5Ub3AgICAgIT0gLTEgJiYKICAgICAgICAgICAgICAgIHJEZXNjLm5MZWZ0ICAgIT0gLTEgJiYKICAgICAgICAgICAgICAgIHJEZXNjLm5Cb3R0b20gIT0gLTEgJiYKICAgICAgICAgICAgICAgIHJEZXNjLm5SaWdodCAgIT0gLTEsCiAgICAgICAgICAgICJmYWlsZWQgdG8gZ2V0IHJhbmdlIGRlc2NyaXB0b3IiICk7CiAgICBEQkdfQVNTRVJUKCByRGVzYy5uVG9wIDw9IHJEZXNjLm5Cb3R0b20gICYmICByRGVzYy5uTGVmdCA8PSByRGVzYy5uUmlnaHQsCiAgICAgICAgICAgICJpbnZhbGlkIHJhbmdlIGRlc2NyaXB0b3IiKTsKICAgIHJldHVybiBzYWxfVHJ1ZTsKfQoKCnN0YXRpYyBTdHJpbmcgR2V0Q2VsbFJhbmdlTmFtZSggU3dGcm1GbXQgJnJUYmxGbXQsIFN3VW5vQ3JzciAmclRibENyc3IgKQp7CiAgICBTdHJpbmcgYVJlczsKCiAgICAvLyEhIHNlZSBhbHNvIFN3WFRleHRUYWJsZUN1cnNvcjo6Z2V0UmFuZ2VOYW1lCgogICAgU3dVbm9UYWJsZUNyc3IqIHBVbm9UYmxDcnNyID0gZHluYW1pY19jYXN0PFN3VW5vVGFibGVDcnNyKj4oJnJUYmxDcnNyKTsKICAgIGlmICghcFVub1RibENyc3IpCiAgICAgICAgcmV0dXJuIFN0cmluZygpOwogICAgcFVub1RibENyc3ItPk1ha2VCb3hTZWxzKCk7CgogICAgY29uc3QgU3dTdGFydE5vZGUqICBwU3RhcnQ7CiAgICBjb25zdCBTd1RhYmxlQm94KiAgIHBTdGFydEJveCAgID0gMDsKICAgIGNvbnN0IFN3VGFibGVCb3gqICAgcEVuZEJveCAgICAgPSAwOwoKICAgIHBTdGFydCA9IHBVbm9UYmxDcnNyLT5HZXRQb2ludCgpLT5uTm9kZS5HZXROb2RlKCkuRmluZFRhYmxlQm94U3RhcnROb2RlKCk7CiAgICBpZiAocFN0YXJ0KQogICAgewogICAgICAgIGNvbnN0IFN3VGFibGUqIHBUYWJsZSA9IFN3VGFibGU6OkZpbmRUYWJsZSggJnJUYmxGbXQgKTsKICAgICAgICBwRW5kQm94ID0gcFRhYmxlLT5HZXRUYmxCb3goIHBTdGFydC0+R2V0SW5kZXgoKSk7CiAgICAgICAgYVJlcyA9IHBFbmRCb3gtPkdldE5hbWUoKTsKCiAgICAgICAgaWYocFVub1RibENyc3ItPkhhc01hcmsoKSkKICAgICAgICB7CiAgICAgICAgICAgIHBTdGFydCA9IHBVbm9UYmxDcnNyLT5HZXRNYXJrKCktPm5Ob2RlLkdldE5vZGUoKS5GaW5kVGFibGVCb3hTdGFydE5vZGUoKTsKICAgICAgICAgICAgcFN0YXJ0Qm94ID0gcFRhYmxlLT5HZXRUYmxCb3goIHBTdGFydC0+R2V0SW5kZXgoKSk7CiAgICAgICAgfQogICAgICAgIERCR19BU1NFUlQoIHBTdGFydEJveCwgInN0YXJ0IGJveCBub3QgZm91bmQiICk7CiAgICAgICAgREJHX0FTU0VSVCggcEVuZEJveCwgImVuZCBib3ggbm90IGZvdW5kIiApOwogICAgICAgIC8vIG5lZWQgdG8gc3dpdGNoIHN0YXJ0IGFuZCBlbmQ/CiAgICAgICAgaWYgKCpwVW5vVGJsQ3Jzci0+R2V0UG9pbnQoKSA8ICpwVW5vVGJsQ3Jzci0+R2V0TWFyaygpKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgU3dUYWJsZUJveCogcFRtcEJveCA9IHBTdGFydEJveDsKICAgICAgICAgICAgcFN0YXJ0Qm94ID0gcEVuZEJveDsKICAgICAgICAgICAgcEVuZEJveCA9IHBUbXBCb3g7CiAgICAgICAgfQoKICAgICAgICBhUmVzID0gcFN0YXJ0Qm94LT5HZXROYW1lKCk7CiAgICAgICAgYVJlcyArPSAoc2FsX1VuaWNvZGUpJzonOwogICAgICAgIGlmIChwRW5kQm94KQogICAgICAgICAgICBhUmVzICs9IHBFbmRCb3gtPkdldE5hbWUoKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGFSZXMgKz0gcFN0YXJ0Qm94LT5HZXROYW1lKCk7CiAgICB9CgogICAgcmV0dXJuIGFSZXM7Cn0KCgpzdGF0aWMgU3RyaW5nIEdldFJhbmdlUmVwRnJvbVRhYmxlQW5kQ2VsbHMoIGNvbnN0IFN0cmluZyAmclRhYmxlTmFtZSwKICAgICAgICBjb25zdCBTdHJpbmcgJnJTdGFydENlbGwsIGNvbnN0IFN0cmluZyAmckVuZENlbGwsCiAgICAgICAgc2FsX0Jvb2wgYkZvcmNlRW5kQ2VsbE5hbWUgKQp7CiAgICBEQkdfQVNTRVJUKCByVGFibGVOYW1lLkxlbigpLCAidGFibGUgbmFtZSBtaXNzaW5nIiApOwogICAgREJHX0FTU0VSVCggclN0YXJ0Q2VsbC5MZW4oKSwgImNlbGwgbmFtZSBtaXNzaW5nIiApOwogICAgU3RyaW5nIGFSZXMoIHJUYWJsZU5hbWUgKTsKICAgIGFSZXMgKz0gKHNhbF9Vbmljb2RlKSAnLic7CiAgICBhUmVzICs9IHJTdGFydENlbGw7CgogICAgaWYgKHJFbmRDZWxsLkxlbigpKQogICAgewogICAgICAgIGFSZXMgKz0gKHNhbF9Vbmljb2RlKSAnOic7CiAgICAgICAgYVJlcyArPSByRW5kQ2VsbDsKICAgIH0KICAgIGVsc2UgaWYgKGJGb3JjZUVuZENlbGxOYW1lKQogICAgewogICAgICAgIGFSZXMgKz0gKHNhbF9Vbmljb2RlKSAnOic7CiAgICAgICAgYVJlcyArPSByU3RhcnRDZWxsOwogICAgfQoKICAgIHJldHVybiBhUmVzOwp9CgoKc3RhdGljIHNhbF9Cb29sIEdldFRhYmxlQW5kQ2VsbHNGcm9tUmFuZ2VSZXAoCiAgICAgICAgY29uc3QgT1VTdHJpbmcgJnJSYW5nZVJlcHJlc2VudGF0aW9uLAogICAgICAgIFN0cmluZyAmclRibE5hbWUsCiAgICAgICAgU3RyaW5nICZyU3RhcnRDZWxsLAogICAgICAgIFN0cmluZyAmckVuZENlbGwsCiAgICAgICAgc2FsX0Jvb2wgYlNvcnRTdGFydEVuZENlbGxzID0gc2FsX1RydWUgKQp7CiAgICAvLyBwYXJzZSByYW5nZSByZXByZXNlbnRhdGlvbiBmb3IgdGFibGUgbmFtZSBhbmQgY2VsbC9yYW5nZSBuYW1lcwogICAgLy8gYWNjZXB0ZWQgZm9ybWF0IHN0aCBsaWtlOiAiVGFibGUxLkEyOkM1IiAsICJUYWJsZTIuQTIuMTpCMy4yIgogICAgU3RyaW5nIGFUYmxOYW1lOyAgICAvLyB0YWJsZSBuYW1lCiAgICBPVVN0cmluZyBhUmFuZ2U7ICAgIC8vIGNlbGwgcmFuZ2UKICAgIFN0cmluZyBhU3RhcnRDZWxsOyAgLy8gbmFtZSBvZiB0b3AgbGVmdCBjZWxsCiAgICBTdHJpbmcgYUVuZENlbGw7ICAgIC8vIG5hbWUgb2YgYm90dG9tIHJpZ2h0IGNlbGwKICAgIHNhbF9JbnQzMiBuSWR4ID0gclJhbmdlUmVwcmVzZW50YXRpb24uaW5kZXhPZiggJy4nICk7CiAgICBpZiAobklkeCA+PSAwKQogICAgewogICAgICAgIGFUYmxOYW1lID0gclJhbmdlUmVwcmVzZW50YXRpb24uY29weSggMCwgbklkeCApOwogICAgICAgIGFSYW5nZSA9IHJSYW5nZVJlcHJlc2VudGF0aW9uLmNvcHkoIG5JZHggKyAxICk7CgkJc2FsX0ludDMyIG5Qb3MgPSBhUmFuZ2UuaW5kZXhPZiggJzonICk7CiAgICAgICAgaWYgKG5Qb3MgPj0gMCkgLy8gYSBjZWxsLXJhbmdlIGxpa2UgIlRhYmxlMS5BMjpENCIKICAgICAgICB7CiAgICAgICAgICAgIGFTdGFydENlbGwgPSBhUmFuZ2UuY29weSggMCwgblBvcyApOwogICAgICAgICAgICBhRW5kQ2VsbCAgID0gYVJhbmdlLmNvcHkoIG5Qb3MgKyAxICk7CgogICAgICAgICAgICAvLyBuZWVkIHRvIHN3aXRjaCBzdGFydCBhbmQgZW5kIGNlbGwgPwogICAgICAgICAgICAvLyAoZG9lcyBub3QgY2hlY2sgZm9yIG5vcm1hbGl6YXRpb24gaGVyZSkKICAgICAgICAgICAgaWYgKGJTb3J0U3RhcnRFbmRDZWxscyAmJiAxID09IGxjbF9Db21wYXJlQ2VsbHNCeUNvbEZpcnN0KCBhU3RhcnRDZWxsLCBhRW5kQ2VsbCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTdHJpbmcgYVRtcCggYVN0YXJ0Q2VsbCApOwogICAgICAgICAgICAgICAgYVN0YXJ0Q2VsbCAgPSBhRW5kQ2VsbDsKICAgICAgICAgICAgICAgIGFFbmRDZWxsICAgID0gYVRtcDsKICAgICAgICAgICAgfQogICAgICAgIH0KCQllbHNlCS8vIGEgc2luZ2xlIGNlbGwgbGlrZSBpbiAiVGFibGUxLkIzIgoJCXsKCQkJYVN0YXJ0Q2VsbCA9IGFFbmRDZWxsID0gYVJhbmdlOwoJCX0KICAgIH0KCiAgICBzYWxfQm9vbCBiU3VjY2VzcyA9IGFUYmxOYW1lLkxlbigpICE9IDAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgYVN0YXJ0Q2VsbC5MZW4oKSAhPSAwICYmIGFFbmRDZWxsLkxlbigpICE9IDA7CiAgICBpZiAoYlN1Y2Nlc3MpCiAgICB7CiAgICAgICAgclRibE5hbWUgICAgPSBhVGJsTmFtZTsKICAgICAgICByU3RhcnRDZWxsICA9IGFTdGFydENlbGw7CiAgICAgICAgckVuZENlbGwgICAgPSBhRW5kQ2VsbDsKICAgIH0KICAgIHJldHVybiBiU3VjY2VzczsKfQoKCnN0YXRpYyB2b2lkIEdldFRhYmxlQnlOYW1lKCBjb25zdCBTd0RvYyAmckRvYywgY29uc3QgU3RyaW5nICZyVGFibGVOYW1lLAogICAgICAgIFN3RnJtRm10ICoqcHBUYmxGbXQsIFN3VGFibGUgKipwcFRhYmxlKQp7CiAgICBTd0ZybUZtdCAqcFRibEZtdCA9IE5VTEw7CgogICAgLy8gZmluZCBmcmFtZSBmb3JtYXQgb2YgdGFibGUKICAgIC8vISBzZWUgU3dYVGV4dFRhYmxlczo6Z2V0QnlOYW1lCiAgICBzYWxfdUludDE2IG5Db3VudCA9IHJEb2MuR2V0VGJsRnJtRm10Q291bnQoc2FsX1RydWUpOwogICAgZm9yIChzYWxfdUludDE2IGkgPSAwOyBpIDwgbkNvdW50ICYmICFwVGJsRm10OyArK2kpCiAgICB7CiAgICAgICAgU3dGcm1GbXQmIHJUYmxGbXQgPSByRG9jLkdldFRibEZybUZtdChpLCBzYWxfVHJ1ZSk7CiAgICAgICAgaWYoclRhYmxlTmFtZSA9PSByVGJsRm10LkdldE5hbWUoKSkKICAgICAgICAgICAgcFRibEZtdCA9ICZyVGJsRm10OwogICAgfQoKICAgIGlmIChwcFRibEZtdCkKICAgICAgICAqcHBUYmxGbXQgPSBwVGJsRm10OwoKICAgIGlmIChwcFRhYmxlKQogICAgICAgICpwcFRhYmxlID0gcFRibEZtdCA/IFN3VGFibGU6OkZpbmRUYWJsZSggcFRibEZtdCApIDogMDsKfQoKCnN0YXRpYyB2b2lkIEdldEZvcm1hdEFuZENyZWF0ZUN1cnNvckZyb21SYW5nZVJlcCgKICAgICAgICBjb25zdCBTd0RvYyAgICAqcERvYywKICAgICAgICBjb25zdCBPVVN0cmluZyAmclJhbmdlUmVwcmVzZW50YXRpb24sICAgLy8gbXVzdCBiZSBhIHNpbmdsZSByYW5nZSAoaS5lLiBzbyBjYWxsZWQgc3ViLXJhbmdlKQogICAgICAgIFN3RnJtRm10ICAgICoqcHBUYmxGbXQsICAgICAvLyB3aWxsIGJlIHNldCB0byB0aGUgdGFibGUgZm9ybWF0IG9mIHRoZSB0YWJsZSB1c2VkIGluIHRoZSByYW5nZSByZXByZXNlbnRhdGlvbgogICAgICAgIFN3VW5vQ3JzciAgICoqcHBVbm9DcnNyICkgICAvLyB3aWxsIGJlIHNldCB0byBjdXJzb3Igc3Bhbm5pbmcgdGhlIGNlbGwgcmFuZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKGN1cnNvciB3aWxsIGJlIGNyZWF0ZWQhKQp7CiAgICBTdHJpbmcgYVRibE5hbWU7ICAgIC8vIHRhYmxlIG5hbWUKICAgIFN0cmluZyBhU3RhcnRDZWxsOyAgLy8gbmFtZSBvZiB0b3AgbGVmdCBjZWxsCiAgICBTdHJpbmcgYUVuZENlbGw7ICAgIC8vIG5hbWUgb2YgYm90dG9tIHJpZ2h0IGNlbGwKICAgIHNhbF9Cb29sIGJOYW1lc0ZvdW5kID0gR2V0VGFibGVBbmRDZWxsc0Zyb21SYW5nZVJlcCggclJhbmdlUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhVGJsTmFtZSwgYVN0YXJ0Q2VsbCwgYUVuZENlbGwgKTsKCiAgICBpZiAoIWJOYW1lc0ZvdW5kKQogICAgewoJCWlmIChwcFRibEZtdCkKCQkJKnBwVGJsRm10ICAgPSBOVUxMOwoJCWlmIChwcFVub0Nyc3IpCgkJCSpwcFVub0Nyc3IgID0gTlVMTDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBTd0ZybUZtdCAqcFRibEZtdCA9IE5VTEw7CgogICAgICAgIC8vIGlzIHRoZSBjb3JyZWN0IHRhYmxlIGZvcm1hdCBhbHJlYWR5IHByb3ZpZGVkPwogICAgICAgIGlmICgqcHBUYmxGbXQgIT0gTlVMTCAgJiYgICgqcHBUYmxGbXQpLT5HZXROYW1lKCkgPT0gYVRibE5hbWUpCiAgICAgICAgICAgIHBUYmxGbXQgPSAqcHBUYmxGbXQ7CiAgICAgICAgZWxzZSBpZiAocHBUYmxGbXQpCiAgICAgICAgICAgIEdldFRhYmxlQnlOYW1lKCAqcERvYywgYVRibE5hbWUsICZwVGJsRm10LCBOVUxMICk7CgoJCWlmIChwcFRibEZtdCkKCQkJKnBwVGJsRm10ID0gcFRibEZtdDsKCiAgICAgICAgaWYgKHBwVW5vQ3JzciAhPSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgKnBwVW5vQ3JzciA9IE5VTEw7ICAvLyBkZWZhdWx0IHJlc3VsdCBpbiBjYXNlIG9mIGZhaWx1cmUKCiAgICAgICAgICAgIFN3VGFibGUgKnBUYWJsZSA9IHBUYmxGbXQgPyBTd1RhYmxlOjpGaW5kVGFibGUoIHBUYmxGbXQgKSA6IDA7CiAgICAgICAgICAgIC8vIGNyZWF0ZSBuZXcgU3dVbm9DcnNyIHNwYW5uaW5nIHRoZSBzcGVjaWZpZWQgcmFuZ2UKICAgICAgICAgICAgLy8hIHNlZSBhbHNvIFN3WFRleHRUYWJsZTo6R2V0UmFuZ2VCeU5hbWUKICAgICAgICAgICAgLy8gLS0+IE9EIDIwMDctMDgtMDMgI2k4MDMxNCMKICAgICAgICAgICAgLy8gcGVyZm9ybSB2YWxpZGF0aW9uIGNoZWNrLiBUaHVzLCBwYXNzIDx0cnVlPiBhcyAybmQgcGFyYW1ldGVyIHRvIDxTd1RhYmxlOjpHZXRUYmxCb3goLi4pPgogICAgICAgICAgICBjb25zdCBTd1RhYmxlQm94KiBwVExCb3ggPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcFRhYmxlID8gcFRhYmxlLT5HZXRUYmxCb3goIGFTdGFydENlbGwsIHRydWUgKSA6IDA7CiAgICAgICAgICAgIC8vIDwtLQogICAgICAgICAgICBpZihwVExCb3gpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGhpZXIgbXVlc3NlbiBkaWUgQWN0aW9ucyBhdWZnZWhvYmVuIHdlcmRlbgogICAgICAgICAgICAgICAgVW5vQWN0aW9uUmVtb3ZlQ29udGV4dCBhUmVtb3ZlQ29udGV4dChwVGJsRm10LT5HZXREb2MoKSk7CiAgICAgICAgICAgICAgICBjb25zdCBTd1N0YXJ0Tm9kZSogcFN0dE5kID0gcFRMQm94LT5HZXRTdHROZCgpOwogICAgICAgICAgICAgICAgU3dQb3NpdGlvbiBhUG9zKCpwU3R0TmQpOwogICAgICAgICAgICAgICAgLy8gc2V0IGN1cnNvciB0byB0b3AgbGVmdCBib3ggb2YgcmFuZ2UKICAgICAgICAgICAgICAgIFN3VW5vQ3JzciogcFVub0Nyc3IgPSBwVGJsRm10LT5HZXREb2MoKS0+Q3JlYXRlVW5vQ3JzcihhUG9zLCBzYWxfVHJ1ZSk7CiAgICAgICAgICAgICAgICBwVW5vQ3Jzci0+TW92ZSggZm5Nb3ZlRm9yd2FyZCwgZm5Hb05vZGUgKTsKICAgICAgICAgICAgICAgIHBVbm9DcnNyLT5TZXRSZW1haW5JblNlY3Rpb24oIHNhbF9GYWxzZSApOwogICAgICAgICAgICAgICAgLy8gLS0+IE9EIDIwMDctMDgtMDMgI2k4MDMxNCMKICAgICAgICAgICAgICAgIC8vIHBlcmZvcm0gdmFsaWRhdGlvbiBjaGVjay4gVGh1cywgcGFzcyA8dHJ1ZT4gYXMgMm5kIHBhcmFtZXRlciB0byA8U3dUYWJsZTo6R2V0VGJsQm94KC4uKT4KICAgICAgICAgICAgICAgIGNvbnN0IFN3VGFibGVCb3gqIHBCUkJveCA9IHBUYWJsZS0+R2V0VGJsQm94KCBhRW5kQ2VsbCwgdHJ1ZSApOwogICAgICAgICAgICAgICAgLy8gPC0tCiAgICAgICAgICAgICAgICBpZihwQlJCb3gpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcFVub0Nyc3ItPlNldE1hcmsoKTsKICAgICAgICAgICAgICAgICAgICBwVW5vQ3Jzci0+R2V0UG9pbnQoKS0+bk5vZGUgPSAqcEJSQm94LT5HZXRTdHROZCgpOwogICAgICAgICAgICAgICAgICAgIHBVbm9DcnNyLT5Nb3ZlKCBmbk1vdmVGb3J3YXJkLCBmbkdvTm9kZSApOwogICAgICAgICAgICAgICAgICAgIFN3VW5vVGFibGVDcnNyKiBwQ3JzciA9CiAgICAgICAgICAgICAgICAgICAgICAgIGR5bmFtaWNfY2FzdDxTd1Vub1RhYmxlQ3Jzcio+KHBVbm9DcnNyKTsKICAgICAgICAgICAgICAgICAgICBwQ3Jzci0+TWFrZUJveFNlbHMoKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHBwVW5vQ3JzcikKICAgICAgICAgICAgICAgICAgICAgICAgKnBwVW5vQ3JzciA9IHBDcnNyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBwVW5vQ3JzcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKCnN0YXRpYyBzYWxfQm9vbCBHZXRTdWJyYW5nZXMoIGNvbnN0IE9VU3RyaW5nICZyUmFuZ2VSZXByZXNlbnRhdGlvbiwKICAgICAgICB1bm86OlNlcXVlbmNlPCBPVVN0cmluZyA+ICZyU3ViUmFuZ2VzLCBzYWxfQm9vbCBiTm9ybWFsaXplICkKewogICAgc2FsX0Jvb2wgYlJlcyA9IHNhbF9UcnVlOwogICAgU3RyaW5nIGFSYW5nZXNTdHIoIHJSYW5nZVJlcHJlc2VudGF0aW9uICk7CiAgICB4dWJfU3RyTGVuIG5MZW4gPSBhUmFuZ2VzU3RyLkdldFRva2VuQ291bnQoICc7JyApOwogICAgdW5vOjpTZXF1ZW5jZTwgT1VTdHJpbmcgPiBhUmFuZ2VzKCBuTGVuICk7CgogICAgc2FsX0ludDMyIG5DbnQgPSAwOwogICAgaWYgKG5MZW4gIT0gMCkKICAgIHsKICAgICAgICBPVVN0cmluZyAqcFJhbmdlcyA9IGFSYW5nZXMuZ2V0QXJyYXkoKTsKICAgICAgICBTdHJpbmcgYUZpcnN0VGFibGU7CiAgICAgICAgZm9yICggeHViX1N0ckxlbiBpID0gMDsgIGkgPCBuTGVuICYmIGJSZXM7ICArK2kpCiAgICAgICAgewogICAgICAgICAgICBTdHJpbmcgYVJhbmdlKCBhUmFuZ2VzU3RyLkdldFRva2VuKCBpLCAnOycgKSApOwogICAgICAgICAgICBpZiAoYVJhbmdlLkxlbigpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwUmFuZ2VzW25DbnRdID0gYVJhbmdlOwoKICAgICAgICAgICAgICAgIFN0cmluZyBhVGFibGVOYW1lLCBhU3RhcnRDZWxsLCBhRW5kQ2VsbDsKICAgICAgICAgICAgICAgIGJSZXMgJj0gR2V0VGFibGVBbmRDZWxsc0Zyb21SYW5nZVJlcCggYVJhbmdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFUYWJsZU5hbWUsIGFTdGFydENlbGwsIGFFbmRDZWxsICk7CgogICAgICAgICAgICAgICAgaWYgKGJOb3JtYWxpemUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbGNsX05vcm1hbGl6ZVJhbmdlKCBhU3RhcnRDZWxsLCBhRW5kQ2VsbCApOwogICAgICAgICAgICAgICAgICAgIHBSYW5nZXNbbkNudF0gPSBHZXRSYW5nZVJlcEZyb21UYWJsZUFuZENlbGxzKCBhVGFibGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhU3RhcnRDZWxsLCBhRW5kQ2VsbCwgc2FsX1RydWUgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgdG8gdXNlIG9ubHkgYSBzaW5nbGUgdGFibGUKICAgICAgICAgICAgICAgIGlmIChuQ250ID09IDApCiAgICAgICAgICAgICAgICAgICAgYUZpcnN0VGFibGUgPSBhVGFibGVOYW1lOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGJSZXMgJj0gYUZpcnN0VGFibGUgPT0gYVRhYmxlTmFtZTsKCiAgICAgICAgICAgICAgICArK25DbnQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBhUmFuZ2VzLnJlYWxsb2MoIG5DbnQgKTsKCiAgICByU3ViUmFuZ2VzID0gYVJhbmdlczsKICAgIHJldHVybiBiUmVzOwp9CgoKc3RhdGljIHZvaWQgU29ydFN1YnJhbmdlcyggdW5vOjpTZXF1ZW5jZTwgT1VTdHJpbmcgPiAmclN1YlJhbmdlcywgc2FsX0Jvb2wgYkNtcEJ5Q29sdW1uICkKewogICAgc2FsX0ludDMyIG5MZW4gPSByU3ViUmFuZ2VzLmdldExlbmd0aCgpOwogICAgT1VTdHJpbmcgKnBTdWJSYW5nZXMgPSByU3ViUmFuZ2VzLmdldEFycmF5KCk7CgogICAgU3RyaW5nIGFTbWFsbGVzdFRibE5hbWU7CiAgICBTdHJpbmcgYVNtYWxsZXN0U3RhcnRDZWxsOwogICAgU3RyaW5nIGFTbWFsbGVzdEVuZENlbGw7CgogICAgZm9yIChzYWxfSW50MzIgaSA9IDA7ICBpIDwgbkxlbjsgICsraSkKICAgIHsKCQlzYWxfSW50MzIgbklkeE9mU21hbGxlc3QgPSBpOwoJCUdldFRhYmxlQW5kQ2VsbHNGcm9tUmFuZ2VSZXAoIHBTdWJSYW5nZXNbbklkeE9mU21hbGxlc3RdLAoJCQkJYVNtYWxsZXN0VGJsTmFtZSwgYVNtYWxsZXN0U3RhcnRDZWxsLCBhU21hbGxlc3RFbmRDZWxsICk7CgkJaWYgKGFTbWFsbGVzdEVuZENlbGwuTGVuKCkgPT0gMCkKCQkJYVNtYWxsZXN0RW5kQ2VsbCA9IGFTbWFsbGVzdFN0YXJ0Q2VsbDsKCiAgICAgICAgZm9yIChzYWxfSW50MzIgayA9IGkrMTsgIGsgPCBuTGVuOyAgKytrKQogICAgICAgIHsKICAgICAgICAgICAgLy8gZ2V0IGNlbGwgbmFtZXMgZm9yIHN1YiByYW5nZQogICAgICAgICAgICBTdHJpbmcgYVRibE5hbWU7CiAgICAgICAgICAgIFN0cmluZyBhU3RhcnRDZWxsOwogICAgICAgICAgICBTdHJpbmcgYUVuZENlbGw7CiAgICAgICAgICAgIEdldFRhYmxlQW5kQ2VsbHNGcm9tUmFuZ2VSZXAoIHBTdWJSYW5nZXNba10sCiAgICAgICAgICAgICAgICAgICAgYVRibE5hbWUsIGFTdGFydENlbGwsIGFFbmRDZWxsICk7CiAgICAgICAgICAgIGlmIChhRW5kQ2VsbC5MZW4oKSA9PSAwKQogICAgICAgICAgICAgICAgYUVuZENlbGwgPSBhU3RhcnRDZWxsOwoKICAgICAgICAgICAgLy8gY29tcGFyZSBjZWxsIHJhbmdlcyAoIGlzIHRoZSBuZXcgb25lIHNtYWxsZXI/ICkKICAgICAgICAgICAgaWYgKC0xID09IGxjbF9Db21wYXJlQ2VsbFJhbmdlcyggYVN0YXJ0Q2VsbCwgYUVuZENlbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVNtYWxsZXN0U3RhcnRDZWxsLCBhU21hbGxlc3RFbmRDZWxsLCBiQ21wQnlDb2x1bW4gKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbklkeE9mU21hbGxlc3QgPSBrOwogICAgICAgICAgICAgICAgYVNtYWxsZXN0VGJsTmFtZSAgICA9IGFUYmxOYW1lOwogICAgICAgICAgICAgICAgYVNtYWxsZXN0U3RhcnRDZWxsICA9IGFTdGFydENlbGw7CiAgICAgICAgICAgICAgICBhU21hbGxlc3RFbmRDZWxsICAgID0gYUVuZENlbGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIG1vdmUgc21hbGxlc3QgZWxlbWVudCB0byB0aGUgc3RhcnQgb2YgdGhlIG5vdCBzb3J0ZWQgYXJlYQogICAgICAgIE9VU3RyaW5nIGFUbXAoIHBTdWJSYW5nZXNbIG5JZHhPZlNtYWxsZXN0IF0gKTsKICAgICAgICBwU3ViUmFuZ2VzWyBuSWR4T2ZTbWFsbGVzdCBdID0gcFN1YlJhbmdlc1sgaSBdOwogICAgICAgIHBTdWJSYW5nZXNbIGkgXSA9IGFUbXA7CiAgICB9Cn0KCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KClN3Q2hhcnREYXRhUHJvdmlkZXI6OlN3Q2hhcnREYXRhUHJvdmlkZXIoIGNvbnN0IFN3RG9jKiBwU3dEb2MgKSA6CiAgICBhRXZ0TGlzdGVuZXJzKCBHZXRDaGFydE11dGV4KCkgKSwKICAgIHBEb2MoIHBTd0RvYyApCnsKICAgIGJEaXNwb3NlZCA9IHNhbF9GYWxzZTsKfQoKClN3Q2hhcnREYXRhUHJvdmlkZXI6On5Td0NoYXJ0RGF0YVByb3ZpZGVyKCkKewp9Cgp1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYRGF0YVNvdXJjZSA+IFN3Q2hhcnREYXRhUHJvdmlkZXI6OkltcGxfY3JlYXRlRGF0YVNvdXJjZSgKICAgICAgICBjb25zdCB1bm86OlNlcXVlbmNlPCBiZWFuczo6UHJvcGVydHlWYWx1ZSA+JiByQXJndW1lbnRzLCBzYWxfQm9vbCBiVGVzdE9ubHkgKQogICAgdGhyb3cgKGxhbmc6OklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgdW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIGlmIChiRGlzcG9zZWQpCiAgICAgICAgdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCiAgICB1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYRGF0YVNvdXJjZSA+IHhSZXM7CgogICAgaWYgKCFwRG9jKQogICAgICAgIHRocm93IHVubzo6UnVudGltZUV4Y2VwdGlvbigpOwoKICAgIC8vIGdldCBhcmd1bWVudHMKICAgIE9VU3RyaW5nIGFSYW5nZVJlcHJlc2VudGF0aW9uOwogICAgdW5vOjpTZXF1ZW5jZTwgc2FsX0ludDMyID4gYVNlcXVlbmNlTWFwcGluZzsKICAgIHNhbF9Cb29sIGJGaXJzdElzTGFiZWwgICAgICA9IHNhbF9GYWxzZTsKICAgIHNhbF9Cb29sIGJEdGFTcmNJc0NvbHVtbnMgICA9IHNhbF9UcnVlOyAvLyB0cnVlIDogRGF0YVNvdXJjZSB3aWxsIGJlIHNlcXVlbmNlIG9mIGNvbHVtbnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmYWxzZTogRGF0YVNvdXJjZSB3aWxsIGJlIHNlcXVlbmNlIG9mIHJvd3MKICAgIE9VU3RyaW5nIGFDaGFydE9sZU9iamVjdE5hbWU7Ly93b3JrIGFyb3VuZCB3cm9uZyB3cml0ZXIgcmFuZ2VzICggc2VlIElzc3VlIDU4NDY0ICkKICAgIHNhbF9JbnQzMiBuQXJncyA9IHJBcmd1bWVudHMuZ2V0TGVuZ3RoKCk7CiAgICBEQkdfQVNTRVJUKCBuQXJncyAhPSAwLCAibm8gcHJvcGVydGllcyBwcm92aWRlZCIgKTsKICAgIGlmIChuQXJncyA9PSAwKQogICAgICAgIHJldHVybiB4UmVzOwogICAgY29uc3QgYmVhbnM6OlByb3BlcnR5VmFsdWUgKnBBcmcgPSByQXJndW1lbnRzLmdldENvbnN0QXJyYXkoKTsKICAgIGZvciAoc2FsX0ludDMyIGkgPSAwOyAgaSA8IG5BcmdzOyAgKytpKQogICAgewogICAgICAgIGlmIChwQXJnW2ldLk5hbWUuZXF1YWxzQXNjaWkoICJEYXRhUm93U291cmNlIiApKQogICAgICAgIHsKICAgICAgICAgICAgY2hhcnQ6OkNoYXJ0RGF0YVJvd1NvdXJjZSBlU291cmNlOwogICAgICAgICAgICBpZiAoIShwQXJnW2ldLlZhbHVlID4+PSBlU291cmNlKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc2FsX0ludDMyIG5UbXAgPSAwOwogICAgICAgICAgICAgICAgaWYgKCEocEFyZ1tpXS5WYWx1ZSA+Pj0gblRtcCkpCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgICAgICAgICBlU291cmNlID0gc3RhdGljX2Nhc3Q8IGNoYXJ0OjpDaGFydERhdGFSb3dTb3VyY2UgPiggblRtcCApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJEdGFTcmNJc0NvbHVtbnMgPSBlU291cmNlID09IGNoYXJ0OjpDaGFydERhdGFSb3dTb3VyY2VfQ09MVU1OUzsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAocEFyZ1tpXS5OYW1lLmVxdWFsc0FzY2lpKCAiRmlyc3RDZWxsQXNMYWJlbCIgKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghKHBBcmdbaV0uVmFsdWUgPj49IGJGaXJzdElzTGFiZWwpKQogICAgICAgICAgICAgICAgdGhyb3cgbGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHBBcmdbaV0uTmFtZS5lcXVhbHNBc2NpaSggIkNlbGxSYW5nZVJlcHJlc2VudGF0aW9uIiApKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEocEFyZ1tpXS5WYWx1ZSA+Pj0gYVJhbmdlUmVwcmVzZW50YXRpb24pKQogICAgICAgICAgICAgICAgdGhyb3cgbGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHBBcmdbaV0uTmFtZS5lcXVhbHNBc2NpaSggIlNlcXVlbmNlTWFwcGluZyIgKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghKHBBcmdbaV0uVmFsdWUgPj49IGFTZXF1ZW5jZU1hcHBpbmcpKQogICAgICAgICAgICAgICAgdGhyb3cgbGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHBBcmdbaV0uTmFtZS5lcXVhbHNBc2NpaSggIkNoYXJ0T2xlT2JqZWN0TmFtZSIgKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghKHBBcmdbaV0uVmFsdWUgPj49IGFDaGFydE9sZU9iamVjdE5hbWUpKQogICAgICAgICAgICAgICAgdGhyb3cgbGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQoJfQoKCXVubzo6U2VxdWVuY2U8IE9VU3RyaW5nID4gYVN1YlJhbmdlczsKICAgIC8vIGdldCBzdWItcmFuZ2VzIGFuZCBjaGVjayB0aGF0IHRoZXkgYWxsIGFyZSBmcm9tIHRoZSB2ZXJ5IHNhbWUgdGFibGUKICAgIHNhbF9Cb29sIGJPayA9IEdldFN1YnJhbmdlcyggYVJhbmdlUmVwcmVzZW50YXRpb24sIGFTdWJSYW5nZXMsIHNhbF9UcnVlICk7CgogICAgaWYgKCFiT2sgJiYgcERvYyAmJiBhQ2hhcnRPbGVPYmplY3ROYW1lLmdldExlbmd0aCgpICkKICAgIHsKICAgICAgICAvL3RyeSB0byBjb3JyZWN0IHRoZSByYW5nZSBoZXJlCiAgICAgICAgLy93b3JrIGFyb3VuZCB3cm9uZyB3cml0ZXIgcmFuZ2VzICggc2VlIElzc3VlIDU4NDY0ICkKICAgICAgICBTdHJpbmcgYUNoYXJ0VGFibGVOYW1lOwoKICAgICAgICBjb25zdCBTd05vZGVzJiByTm9kZXMgPSBwRG9jLT5HZXROb2RlcygpOwogICAgICAgIGZvciggc2FsX3VMb25nIG5OID0gck5vZGVzLkNvdW50KCk7IG5OLS07ICkKICAgICAgICB7CiAgICAgICAgICAgIFN3Tm9kZVB0ciBwTm9kZSA9IHJOb2Rlc1tuTl07CiAgICAgICAgICAgIGlmKCAhcE5vZGUgKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGNvbnN0IFN3T0xFTm9kZSogcE9sZU5vZGUgPSBwTm9kZS0+R2V0T0xFTm9kZSgpOwogICAgICAgICAgICBpZiggIXBPbGVOb2RlICkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBjb25zdCBTd09MRU9iaiYgck9PYmogPSBwT2xlTm9kZS0+R2V0T0xFT2JqKCk7CiAgICAgICAgICAgIGlmKCBhQ2hhcnRPbGVPYmplY3ROYW1lLmVxdWFscyggck9PYmouR2V0Q3VycmVudFBlcnNpc3ROYW1lKCkgKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGFDaGFydFRhYmxlTmFtZSA9IHBPbGVOb2RlLT5HZXRDaGFydFRibE5hbWUoKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiggYUNoYXJ0VGFibGVOYW1lLkxlbigpICkKICAgICAgICB7CiAgICAgICAgICAgIC8vdGhlIHdyb25nIHJhbmdlIGlzIHN0aWxsIHNoaWZ0ZWQgb25lIHJvdyBkb3duCiAgICAgICAgICAgIC8vdGh1cyB0aGUgZmlyc3Qgcm93IGlzIG1pc3NpbmcgYW5kIGFuIGludmFsaWQgcm93IGF0IHRoZSBlbmQgaXMgYWRkZWQuCiAgICAgICAgICAgIC8vVGhlcmVmb3JlIHdlIG5lZWQgdG8gc2hpZnQgdGhlIHJhbmdlIG9uZSByb3cgdXAKICAgICAgICAgICAgU3dSYW5nZURlc2NyaXB0b3IgYURlc2M7CiAgICAgICAgICAgIGlmIChhUmFuZ2VSZXByZXNlbnRhdGlvbi5nZXRMZW5ndGgoKSA9PSAwKQogICAgICAgICAgICAgICAgcmV0dXJuIHhSZXM7ICAgICAgICAvLyB3ZSBjYW4ndCBoYW5kbGUgdGhpcyB0aHVzIHJldHVybmluZyBhbiBlbXB0eSByZWZlcmVuY2VzCiAgICAgICAgICAgIGFSYW5nZVJlcHJlc2VudGF0aW9uID0gYVJhbmdlUmVwcmVzZW50YXRpb24uY29weSggMSApOyAgICAvLyBnZXQgcmlkIG9mICcuJyB0byBoYXZlIG9ubHkgdGhlIGNlbGwgcmFuZ2UgbGVmdAogICAgICAgICAgICBGaWxsUmFuZ2VEZXNjcmlwdG9yKCBhRGVzYywgYVJhbmdlUmVwcmVzZW50YXRpb24gKTsKICAgICAgICAgICAgYURlc2MuTm9ybWFsaXplKCk7CiAgICAgICAgICAgIGlmIChhRGVzYy5uVG9wIDw9IDApICAgIC8vIG5vIGNoYW5jZSB0byBzaGlmdCB0aGUgcmFuZ2Ugb25lIHJvdyB1cD8KICAgICAgICAgICAgICAgIHJldHVybiB4UmVzOyAgICAgICAgLy8gd2UgY2FuJ3QgaGFuZGxlIHRoaXMgdGh1cyByZXR1cm5pbmcgYW4gZW1wdHkgcmVmZXJlbmNlcwogICAgICAgICAgICBhRGVzYy5uVG9wICAgICAgLT0gMTsKICAgICAgICAgICAgYURlc2MubkJvdHRvbSAgIC09IDE7CgogICAgICAgICAgICBTdHJpbmcgYU5ld1N0YXJ0Q2VsbCggbGNsX0dldENlbGxOYW1lKCBhRGVzYy5uTGVmdCwgYURlc2MublRvcCApICk7CiAgICAgICAgICAgIFN0cmluZyBhTmV3RW5kQ2VsbCggbGNsX0dldENlbGxOYW1lKCBhRGVzYy5uUmlnaHQsIGFEZXNjLm5Cb3R0b20gKSApOwogICAgICAgICAgICBhUmFuZ2VSZXByZXNlbnRhdGlvbiA9IEdldFJhbmdlUmVwRnJvbVRhYmxlQW5kQ2VsbHMoCiAgICAgICAgICAgICAgICAgICAgICAgIGFDaGFydFRhYmxlTmFtZSwgYU5ld1N0YXJ0Q2VsbCwgYU5ld0VuZENlbGwsIHNhbF9UcnVlICk7CiAgICAgICAgICAgIGJPayA9IEdldFN1YnJhbmdlcyggYVJhbmdlUmVwcmVzZW50YXRpb24sIGFTdWJSYW5nZXMsIHNhbF9UcnVlICk7CiAgICAgICAgfQogICAgfQogICAgaWYgKCFiT2spICAgIC8vIGRpZmZlcmVudCB0YWJsZXMgdXNlZCwgb3IgaW5jb3JyZWN0IHJhbmdlIHNwZWNpZmllcnMKICAgICAgICB0aHJvdyBsYW5nOjpJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCiAgICBTb3J0U3VicmFuZ2VzKCBhU3ViUmFuZ2VzLCBiRHRhU3JjSXNDb2x1bW5zICk7CiAgICBjb25zdCBPVVN0cmluZyAqcFN1YlJhbmdlcyA9IGFTdWJSYW5nZXMuZ2V0Q29uc3RBcnJheSgpOwojaWYgT1NMX0RFQlVHX0xFVkVMID4gMQogICAgewogICAgICAgIHNhbF9JbnQzMiBuU1IgPSBhU3ViUmFuZ2VzLmdldExlbmd0aCgpOwogICAgICAgIE9VU3RyaW5nICpwU1IgPSBhU3ViUmFuZ2VzLmdldEFycmF5KCk7CiAgICAgICAgT1VTdHJpbmcgYVJnOwogICAgICAgIGZvciAoc2FsX0ludDMyIGkgPSAwOyAgaSA8IG5TUjsgICsraSkKICAgICAgICB7CiAgICAgICAgICAgIGFSZyA9IHBTUltpXTsKICAgICAgICB9CiAgICB9CiNlbmRpZgoKICAgIC8vIGdldCB0YWJsZSBmb3JtYXQgZm9yIHRoYXQgc2luZ2xlIHRhYmxlIGZyb20gYWJvdmUKICAgIFN3RnJtRm10ICAgICpwVGJsRm10ICA9IDA7ICAgICAgLy8gcG9pbnRlciB0byB0YWJsZSBmb3JtYXQKICAgIFN3VW5vQ3JzciAgICpwVW5vQ3JzciA9IDA7ICAgICAgLy8gaGVyZSByZXF1aXJlZCB0byBjaGVjayBpZiB0aGUgY2VsbHMgaW4gdGhlIHJhbmdlIGRvIGFjdHVhbGx5IGV4aXN0CiAgICBzdGQ6OmF1dG9fcHRyPCBTd1Vub0Nyc3IgPiBwQXV0byggcFVub0Nyc3IgKTsgIC8vIHRvIGVuZCBsaWZldGltZSBvZiBvYmplY3QgcG9pbnRlZCB0byBieSBwVW5vQ3JzcgogICAgaWYgKGFTdWJSYW5nZXMuZ2V0TGVuZ3RoKCkgPiAwKQogICAgICAgIEdldEZvcm1hdEFuZENyZWF0ZUN1cnNvckZyb21SYW5nZVJlcCggcERvYywgcFN1YlJhbmdlc1swXSwgJnBUYmxGbXQsICZwVW5vQ3JzciApOwogICAgaWYgKCFwVGJsRm10IHx8ICFwVW5vQ3JzcikKICAgICAgICB0aHJvdyBsYW5nOjpJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCiAgICBpZihwVGJsRm10KQogICAgewogICAgICAgIFN3VGFibGUqIHBUYWJsZSA9IFN3VGFibGU6OkZpbmRUYWJsZSggcFRibEZtdCApOwogICAgICAgIGlmKHBUYWJsZS0+SXNUYmxDb21wbGV4KCkpCiAgICAgICAgICAgIHJldHVybiB4UmVzOyAgICAvLyB3ZSBjYW4ndCBoYW5kbGUgdGhpcyB0aHVzIHJldHVybmluZyBhbiBlbXB0eSByZWZlcmVuY2VzCiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLy8gZ2V0IGEgY2hhcmFjdGVyIG1hcCBpbiB0aGUgc2l6ZSBvZiB0aGUgdGFibGUgdG8gbWFyawogICAgICAgICAgICAvLyBhbGwgdGhlIHJhbmdlcyB0byB1c2UgaW4KICAgICAgICAgICAgc2FsX0ludDMyIG5Sb3dzID0gcFRhYmxlLT5HZXRUYWJMaW5lcygpLkNvdW50KCk7CiAgICAgICAgICAgIHNhbF9JbnQzMiBuQ29scyA9IHBUYWJsZS0+R2V0VGFiTGluZXMoKS5HZXRPYmplY3QoMCktPkdldFRhYkJveGVzKCkuQ291bnQoKTsKICAgICAgICAgICAgc3RkOjp2ZWN0b3I8IHN0ZDo6dmVjdG9yPCBzYWxfQ2hhciA+ID4gYU1hcCggblJvd3MgKTsKICAgICAgICAgICAgZm9yIChzYWxfSW50MzIgaSA9IDA7ICBpIDwgblJvd3M7ICArK2kpCiAgICAgICAgICAgICAgICBhTWFwW2ldLnJlc2l6ZSggbkNvbHMgKTsKCiAgICAgICAgICAgIC8vIGl0ZXJhdGUgb3ZlciBzdWJyYW5nZXMgYW5kIG1hcmsgdXNlZCBjZWxscyBpbiBhYm92ZSBtYXAKICAgICAgICAgICAgLy8hISBieSBwcm9jZWVkaW5nIHRoaXMgd2F5IHdlIGF1dG9tYXRpY2FsbHkgZ2V0IHJpZCBvZgogICAgICAgICAgICAvLyEhIG11bHRpcGxlIGxpc3RlZCBvciBvdmVybGFwcGluZyBjZWxsIHJhbmdlcyB3aGljaCBzaG91bGQKICAgICAgICAgICAgLy8hISBqdXN0IGJlIGlnbm9yZWQgc2lsZW50bHkKICAgICAgICAgICAgc2FsX0ludDMyIG5TdWJSYW5nZXMgPSBhU3ViUmFuZ2VzLmdldExlbmd0aCgpOwogICAgICAgICAgICBmb3IgKHNhbF9JbnQzMiBpID0gMDsgIGkgPCBuU3ViUmFuZ2VzOyAgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTdHJpbmcgYVRibE5hbWUsIGFTdGFydENlbGwsIGFFbmRDZWxsOwogICAgICAgICAgICAgICAgc2FsX0Jvb2wgYk9rMiA9IEdldFRhYmxlQW5kQ2VsbHNGcm9tUmFuZ2VSZXAoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTdWJSYW5nZXNbaV0sIGFUYmxOYW1lLCBhU3RhcnRDZWxsLCBhRW5kQ2VsbCApOwogICAgICAgICAgICAgICAgKHZvaWQpIGJPazI7CiAgICAgICAgICAgICAgICBEQkdfQVNTRVJUKCBiT2syLCAiZmFpbGVkIHRvIGdldCB0YWJsZSBhbmQgc3RhcnQvZW5kIGNlbGxzIiApOwoKICAgICAgICAgICAgICAgIHNhbF9JbnQzMiBuU3RhcnRSb3csIG5TdGFydENvbCwgbkVuZFJvdywgbkVuZENvbDsKICAgICAgICAgICAgICAgIGxjbF9HZXRDZWxsUG9zaXRpb24oIGFTdGFydENlbGwsIG5TdGFydENvbCwgblN0YXJ0Um93ICk7CiAgICAgICAgICAgICAgICBsY2xfR2V0Q2VsbFBvc2l0aW9uKCBhRW5kQ2VsbCwgICBuRW5kQ29sLCAgIG5FbmRSb3cgKTsKICAgICAgICAgICAgICAgIERCR19BU1NFUlQoIG5TdGFydFJvdyA8PSBuRW5kUm93ICYmIG5TdGFydENvbCA8PSBuRW5kQ29sLAogICAgICAgICAgICAgICAgICAgICAgICAiY2VsbCByYW5nZSBub3Qgbm9ybWFsaXplZCIpOwoKICAgICAgICAgICAgICAgIC8vIHRlc3QgaWYgdGhlIHJhbmdlcyBzcGFuIG1vcmUgdGhhbiB0aGUgYXZhaWxhYmxlIGNlbGxzCiAgICAgICAgICAgICAgICBpZiggblN0YXJ0Um93IDwgMCB8fCBuRW5kUm93ID49IG5Sb3dzIHx8CiAgICAgICAgICAgICAgICAgICAgblN0YXJ0Q29sIDwgMCB8fCBuRW5kQ29sID49IG5Db2xzICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBsYW5nOjpJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciAoc2FsX0ludDMyIGsxID0gblN0YXJ0Um93OyAgazEgPD0gbkVuZFJvdzsgICsrazEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChzYWxfSW50MzIgazIgPSBuU3RhcnRDb2w7ICBrMiA8PSBuRW5kQ29sOyAgKytrMikKICAgICAgICAgICAgICAgICAgICAgICAgYU1hcFtrMV1bazJdID0gJ3gnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyBmaW5kIGxhYmVsIGFuZCBkYXRhIHNlcXVlbmNlcyB0byB1c2UKICAgICAgICAgICAgLy8KICAgICAgICAgICAgc2FsX0ludDMyIG9pOyAgLy8gb3V0ZXIgaW5kZXggKHNsb3dlciBjaGFuZ2luZyBpbmRleCkKICAgICAgICAgICAgc2FsX0ludDMyIGlpOyAgLy8gaW5uZXIgaW5kZXggKGZhc3RlciBjaGFuZ2luZyBpbmRleCkKICAgICAgICAgICAgc2FsX0ludDMyIG9pRW5kID0gYkR0YVNyY0lzQ29sdW1ucyA/IG5Db2xzIDogblJvd3M7CiAgICAgICAgICAgIHNhbF9JbnQzMiBpaUVuZCA9IGJEdGFTcmNJc0NvbHVtbnMgPyBuUm93cyA6IG5Db2xzOwogICAgICAgICAgICBzdGQ6OnZlY3Rvcjwgc2FsX0ludDMyID4gYUxhYmVsSWR4KCBvaUVuZCApOwogICAgICAgICAgICBzdGQ6OnZlY3Rvcjwgc2FsX0ludDMyID4gYURhdGFTdGFydElkeCggb2lFbmQgKTsKICAgICAgICAgICAgc3RkOjp2ZWN0b3I8IHNhbF9JbnQzMiA+IGFEYXRhTGVuKCBvaUVuZCApOwogICAgICAgICAgICBmb3IgKG9pID0gMDsgIG9pIDwgb2lFbmQ7ICArK29pKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhTGFiZWxJZHhbb2ldICAgICAgID0gLTE7CiAgICAgICAgICAgICAgICBhRGF0YVN0YXJ0SWR4W29pXSAgID0gLTE7CiAgICAgICAgICAgICAgICBhRGF0YUxlbltvaV0gICAgICAgID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLwogICAgICAgICAgICBmb3IgKG9pID0gMDsgIG9pIDwgb2lFbmQ7ICArK29pKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpaSA9IDA7CiAgICAgICAgICAgICAgICB3aGlsZSAoaWkgPCBpaUVuZCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzYWxfQ2hhciAmckNoYXIgPSBiRHRhU3JjSXNDb2x1bW5zID8gYU1hcFtpaV1bb2ldIDogYU1hcFtvaV1baWldOwoKICAgICAgICAgICAgICAgICAgICAvLyBsYWJlbCBzaG91bGQgYmUgdXNlZCBidXQgaXMgbm90IHlldCBmb3VuZD8KICAgICAgICAgICAgICAgICAgICBpZiAockNoYXIgPT0gJ3gnICYmIGJGaXJzdElzTGFiZWwgJiYgYUxhYmVsSWR4W29pXSA9PSAtMSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFMYWJlbElkeFtvaV0gPSBpaTsKICAgICAgICAgICAgICAgICAgICAgICAgckNoYXIgPSAnTCc7ICAgIC8vIHNldHRpbmcgYSBkaWZmZXJlbnQgY2hhciBmb3IgbGFiZWxzIGhlcmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ha2VzIHRoZSB0ZXN0IGZvciB0aGUgZGF0YSBzZXF1ZW5jZSBiZWxvdwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZWFzaWVyCiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBmaW5kIGRhdGEgc2VxdWVuY2UKICAgICAgICAgICAgICAgICAgICBpZiAockNoYXIgPT0gJ3gnICYmIGFEYXRhU3RhcnRJZHhbb2ldID09IC0xKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYURhdGFTdGFydElkeFtvaV0gPSBpaTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldCBsZW5ndGggb2YgZGF0YSBzZXF1ZW5jZQogICAgICAgICAgICAgICAgICAgICAgICBzYWxfSW50MzIgbkwgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBzYWxfQ2hhciBjOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaWk8IGlpRW5kICYmICd4JyA9PSAoYyA9IGJEdGFTcmNJc0NvbHVtbnMgPyBhTWFwW2lpXVtvaV0gOiBhTWFwW29pXVtpaV0pKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICArK25MOyAgICsraWk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYURhdGFMZW5bb2ldID0gbkw7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IHRoZXJlIGlzIG5vIG90aGVyIHNlcGFyYXRlIHNlcXVlbmNlIG9mIGRhdGEKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG8gYmUgZm91bmQgYmVjYXVzZSB0aGF0IGlzIG5vdCBzdXBwb3J0ZWQKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGlpIDwgaWlFbmQpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgneCcgPT0gKGMgPSBiRHRhU3JjSXNDb2x1bW5zID8gYU1hcFtpaV1bb2ldIDogYU1hcFtvaV1baWldKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBsYW5nOjpJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsraWk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICArK2lpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBtYWtlIHNvbWUgb3RoZXIgY29uc2lzdGVuY3kgY2hlY2tzIHdoaWxlIGNhbGN1bGF0aW5nCiAgICAgICAgICAgIC8vIHRoZSBudW1iZXIgb2YgWExhYmVsZWREYXRhU2VxdWVuY2UgdG8gYnVpbGQ6CiAgICAgICAgICAgIC8vIC0gbGFiZWxzIHNob3VsZCBhbHdheXMgYmUgdXNlZCBvciBub3QgYXQgYWxsCiAgICAgICAgICAgIC8vIC0gdGhlIGRhdGEgc2VxdWVuY2VzIHNob3VsZCBoYXZlIGVxdWFsIG5vbi16ZXJvIGxlbmd0aAogICAgICAgICAgICBzYWxfSW50MzIgbk51bUxEUyA9IDA7CiAgICAgICAgICAgIGlmIChvaUVuZCA+IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNhbF9JbnQzMiBuRmlyc3RTZXFMZW4gPSAwOwogICAgICAgICAgICAgICAgc2FsX0ludDMyIG5GaXJzdFNlcUxhYmVsSWR4ID0gLTE7CiAgICAgICAgICAgICAgICBmb3IgKG9pID0gMDsgIG9pIDwgb2lFbmQ7ICArK29pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNhbF9Cb29sIGJGaXJzdEZvdW5kID0gc2FsX0ZhbHNlOwogICAgICAgICAgICAgICAgICAgIC8vIHJvdy9jb2wgdXNlZCBhdCBhbGw/CiAgICAgICAgICAgICAgICAgICAgaWYgKGFEYXRhU3RhcnRJZHhbb2ldICE9IC0xICYmCiAgICAgICAgICAgICAgICAgICAgICAgICghYkZpcnN0SXNMYWJlbCB8fCBhTGFiZWxJZHhbb2ldICE9IC0xKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICsrbk51bUxEUzsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFiRmlyc3RGb3VuZCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbkZpcnN0U2VxTGVuICAgICAgICA9IGFEYXRhTGVuW29pXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5GaXJzdFNlcUxhYmVsSWR4ICAgPSBhTGFiZWxJZHhbb2ldOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYkZpcnN0Rm91bmQgPSBzYWxfVHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuRmlyc3RTZXFMZW4gIT0gYURhdGFMZW5bb2ldIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkZpcnN0U2VxTGFiZWxJZHggIT0gYUxhYmVsSWR4W29pXSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBsYW5nOjpJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobk51bUxEUyA9PSAwKQogICAgICAgICAgICAgICAgdGhyb3cgbGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CgogICAgICAgICAgICAvLyBub3cgd2Ugc2hvdWxkIGhhdmUgYWxsIG5lY2Vzc2FyeSBkYXRhIHRvIGJ1aWxkIGEgcHJvcGVyIERhdGFTb3VyY2UKICAgICAgICAgICAgLy8gdGh1cyBpZiB3ZSBjYW1lIHRoaXMgZmFyIHRoZXJlIHNob3VsZCBiZSBubyBmdXJ0aGVyIHByb2JsZW0KICAgICAgICAgICAgaWYgKGJUZXN0T25seSkKICAgICAgICAgICAgICAgIHJldHVybiB4UmVzOyAgICAvLyBoYXZlIGNyZWF0ZURhdGFTb3VyY2VQb3NzaWJsZSByZXR1cm4gdHJ1ZQoKICAgICAgICAgICAgLy8gY3JlYXRlIGRhdGEgc291cmNlIGZyb20gZm91bmQgbGFiZWwgYW5kIGRhdGEgc2VxdWVuY2VzCiAgICAgICAgICAgIHVubzo6U2VxdWVuY2U8IHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPiA+IGFMYWJlbFNlcXMoIG5OdW1MRFMgKTsKICAgICAgICAgICAgdW5vOjpSZWZlcmVuY2U8IGNoYXJ0Mjo6ZGF0YTo6WERhdGFTZXF1ZW5jZSA+ICpwTGFiZWxTZXFzID0gYUxhYmVsU2Vxcy5nZXRBcnJheSgpOwogICAgICAgICAgICB1bm86OlNlcXVlbmNlPCB1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYRGF0YVNlcXVlbmNlID4gPiBhRGF0YVNlcXMoIG5OdW1MRFMgKTsKICAgICAgICAgICAgdW5vOjpSZWZlcmVuY2U8IGNoYXJ0Mjo6ZGF0YTo6WERhdGFTZXF1ZW5jZSA+ICpwRGF0YVNlcXMgPSBhRGF0YVNlcXMuZ2V0QXJyYXkoKTsKICAgICAgICAgICAgc2FsX0ludDMyIG5TZXFzSWR4ID0gMDsKICAgICAgICAgICAgZm9yIChvaSA9IDA7ICBvaSA8IG9pRW5kOyAgKytvaSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gcm93L2NvbCBub3QgdXNlZD8gKHNlZSBpZi1zdGF0ZW1lbnQgYWJvdmUgd2hlcmUgbk51bUxEUyB3YXMgY291bnRlZCkKICAgICAgICAgICAgICAgIGlmICghKGFEYXRhU3RhcnRJZHhbb2ldICE9IC0xICYmCiAgICAgICAgICAgICAgICAgICAgICAgICghYkZpcnN0SXNMYWJlbCB8fCBhTGFiZWxJZHhbb2ldICE9IC0xKSkpCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAgICAgLy8gZ2V0IGNlbGwgcmFuZ2VzIGZvciBsYWJlbCBhbmQgZGF0YQogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIFN3UmFuZ2VEZXNjcmlwdG9yIGFMYWJlbERlc2M7CiAgICAgICAgICAgICAgICBTd1JhbmdlRGVzY3JpcHRvciBhRGF0YURlc2M7CiAgICAgICAgICAgICAgICBpZiAoYkR0YVNyY0lzQ29sdW1ucykgICAvLyB1c2UgY29sdW1ucwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFMYWJlbERlc2MublRvcCAgICAgPSBhTGFiZWxJZHhbb2ldOwogICAgICAgICAgICAgICAgICAgIGFMYWJlbERlc2MubkxlZnQgICAgPSBvaTsKICAgICAgICAgICAgICAgICAgICBhTGFiZWxEZXNjLm5Cb3R0b20gID0gYUxhYmVsRGVzYy5uVG9wOwogICAgICAgICAgICAgICAgICAgIGFMYWJlbERlc2MublJpZ2h0ICAgPSBvaTsKCiAgICAgICAgICAgICAgICAgICAgYURhdGFEZXNjLm5Ub3AgICAgICA9IGFEYXRhU3RhcnRJZHhbb2ldOwogICAgICAgICAgICAgICAgICAgIGFEYXRhRGVzYy5uTGVmdCAgICAgPSBvaTsKICAgICAgICAgICAgICAgICAgICBhRGF0YURlc2MubkJvdHRvbSAgID0gYURhdGFEZXNjLm5Ub3AgKyBhRGF0YUxlbltvaV0gLSAxOwogICAgICAgICAgICAgICAgICAgIGFEYXRhRGVzYy5uUmlnaHQgICAgPSBvaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgICAgLy8gdXNlIHJvd3MKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBhTGFiZWxEZXNjLm5Ub3AgICAgID0gb2k7CiAgICAgICAgICAgICAgICAgICAgYUxhYmVsRGVzYy5uTGVmdCAgICA9IGFMYWJlbElkeFtvaV07CiAgICAgICAgICAgICAgICAgICAgYUxhYmVsRGVzYy5uQm90dG9tICA9IG9pOwogICAgICAgICAgICAgICAgICAgIGFMYWJlbERlc2MublJpZ2h0ICAgPSBhTGFiZWxEZXNjLm5MZWZ0OwoKICAgICAgICAgICAgICAgICAgICBhRGF0YURlc2MublRvcCAgICAgID0gb2k7CiAgICAgICAgICAgICAgICAgICAgYURhdGFEZXNjLm5MZWZ0ICAgICA9IGFEYXRhU3RhcnRJZHhbb2ldOwogICAgICAgICAgICAgICAgICAgIGFEYXRhRGVzYy5uQm90dG9tICAgPSBvaTsKICAgICAgICAgICAgICAgICAgICBhRGF0YURlc2MublJpZ2h0ICAgID0gYURhdGFEZXNjLm5MZWZ0ICsgYURhdGFMZW5bb2ldIC0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFN0cmluZyBhQmFzZU5hbWUoIHBUYmxGbXQtPkdldE5hbWUoKSApOwogICAgICAgICAgICAgICAgYUJhc2VOYW1lICs9ICcuJzsKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICBTdHJpbmcgYUxhYmVsUmFuZ2U7CiAgICAgICAgICAgICAgICBpZiAoYUxhYmVsSWR4W29pXSAhPSAtMSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBhTGFiZWxSYW5nZSArPSBhQmFzZU5hbWU7CiAgICAgICAgICAgICAgICAgICAgYUxhYmVsUmFuZ2UgKz0gbGNsX0dldENlbGxOYW1lKCBhTGFiZWxEZXNjLm5MZWZ0LCBhTGFiZWxEZXNjLm5Ub3AgKTsKICAgICAgICAgICAgICAgICAgICBhTGFiZWxSYW5nZSArPSAnOic7CiAgICAgICAgICAgICAgICAgICAgYUxhYmVsUmFuZ2UgKz0gbGNsX0dldENlbGxOYW1lKCBhTGFiZWxEZXNjLm5SaWdodCwgYUxhYmVsRGVzYy5uQm90dG9tICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgU3RyaW5nIGFEYXRhUmFuZ2U7CiAgICAgICAgICAgICAgICBpZiAoYURhdGFTdGFydElkeFtvaV0gIT0gLTEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYURhdGFSYW5nZSArPSBhQmFzZU5hbWU7CiAgICAgICAgICAgICAgICAgICAgYURhdGFSYW5nZSArPSBsY2xfR2V0Q2VsbE5hbWUoIGFEYXRhRGVzYy5uTGVmdCwgYURhdGFEZXNjLm5Ub3AgKTsKICAgICAgICAgICAgICAgICAgICBhRGF0YVJhbmdlICs9ICc6JzsKICAgICAgICAgICAgICAgICAgICBhRGF0YVJhbmdlICs9IGxjbF9HZXRDZWxsTmFtZSggYURhdGFEZXNjLm5SaWdodCwgYURhdGFEZXNjLm5Cb3R0b20gKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBnZXQgY3Vyc29ycyBzcGFubmluZyB0aGUgY2VsbCByYW5nZXMgZm9yIGxhYmVsIGFuZCBkYXRhCiAgICAgICAgICAgICAgICBTd1Vub0Nyc3IgICAqcExhYmVsVW5vQ3JzciAgPSAwOwogICAgICAgICAgICAgICAgU3dVbm9DcnNyICAgKnBEYXRhVW5vQ3JzciAgID0gMDsKICAgICAgICAgICAgICAgIEdldEZvcm1hdEFuZENyZWF0ZUN1cnNvckZyb21SYW5nZVJlcCggcERvYywgYUxhYmVsUmFuZ2UsICZwVGJsRm10LCAmcExhYmVsVW5vQ3Jzcik7CiAgICAgICAgICAgICAgICBHZXRGb3JtYXRBbmRDcmVhdGVDdXJzb3JGcm9tUmFuZ2VSZXAoIHBEb2MsIGFEYXRhUmFuZ2UsICAmcFRibEZtdCwgJnBEYXRhVW5vQ3Jzcik7CgogICAgICAgICAgICAgICAgLy8gY3JlYXRlIFhEYXRhU2VxdWVuY2UncyBmcm9tIGN1cnNvcnMKCQkJCWlmIChwTGFiZWxVbm9DcnNyKQogICAgICAgICAgICAgICAgICAgIHBMYWJlbFNlcXNbIG5TZXFzSWR4IF0gPSBuZXcgU3dDaGFydERhdGFTZXF1ZW5jZSggKnRoaXMsICpwVGJsRm10LCBwTGFiZWxVbm9DcnNyICk7CiAgICAgICAgICAgICAgICBEQkdfQVNTRVJUKCBwRGF0YVVub0Nyc3IsICJwb2ludGVyIHRvIGRhdGEgc2VxdWVuY2UgbWlzc2luZyIgKTsKCQkJCWlmIChwRGF0YVVub0Nyc3IpCiAgICAgICAgICAgICAgICAgICAgcERhdGFTZXFzIFsgblNlcXNJZHggXSA9IG5ldyBTd0NoYXJ0RGF0YVNlcXVlbmNlKCAqdGhpcywgKnBUYmxGbXQsIHBEYXRhVW5vQ3JzciApOwogICAgICAgICAgICAgICAgaWYgKHBMYWJlbFVub0Nyc3IgfHwgcERhdGFVbm9DcnNyKQogICAgICAgICAgICAgICAgICAgICsrblNlcXNJZHg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgREJHX0FTU0VSVCggblNlcXNJZHggPT0gbk51bUxEUywKICAgICAgICAgICAgICAgICAgICAibWlzbWF0Y2ggYmV0d2VlbiBzZXF1ZW5jZSBzaXplIGFuZCBudW0sYmVyIG9mIGVudHJpZXMiICk7CgogICAgICAgICAgICAvLyBidWlsZCBkYXRhIHNvdXJjZSBmcm9tIGRhdGEgYW5kIGxhYmVsIHNlcXVlbmNlcwogICAgICAgICAgICB1bm86OlNlcXVlbmNlPCB1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYTGFiZWxlZERhdGFTZXF1ZW5jZSA+ID4gYUxEUyggbk51bUxEUyApOwogICAgICAgICAgICB1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYTGFiZWxlZERhdGFTZXF1ZW5jZSA+ICpwTERTID0gYUxEUy5nZXRBcnJheSgpOwogICAgICAgICAgICBmb3IgKHNhbF9JbnQzMiBpID0gMDsgIGkgPCBuTnVtTERTOyAgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTd0NoYXJ0TGFiZWxlZERhdGFTZXF1ZW5jZSAqcExhYmVsZWREdGFTZXEgPSBuZXcgU3dDaGFydExhYmVsZWREYXRhU2VxdWVuY2U7CiAgICAgICAgICAgICAgICBwTGFiZWxlZER0YVNlcS0+c2V0TGFiZWwoIHBMYWJlbFNlcXNbaV0gKTsKICAgICAgICAgICAgICAgIHBMYWJlbGVkRHRhU2VxLT5zZXRWYWx1ZXMoIHBEYXRhU2Vxc1tpXSApOwogICAgICAgICAgICAgICAgcExEU1tpXSA9IHBMYWJlbGVkRHRhU2VxOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBhcHBseSAnU2VxdWVuY2VNYXBwaW5nJyBpZiBpdCB3YXMgcHJvdmlkZWQKICAgICAgICAgICAgc2FsX0ludDMyIG5TZXF1ZW5jZU1hcHBpbmdMZW4gPSBhU2VxdWVuY2VNYXBwaW5nLmdldExlbmd0aCgpOwogICAgICAgICAgICBpZiAoblNlcXVlbmNlTWFwcGluZ0xlbikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc2FsX0ludDMyICpwU2VxdWVuY2VNYXBwaW5nID0gYVNlcXVlbmNlTWFwcGluZy5nZXRBcnJheSgpOwogICAgICAgICAgICAgICAgdW5vOjpTZXF1ZW5jZTwgdW5vOjpSZWZlcmVuY2U8IGNoYXJ0Mjo6ZGF0YTo6WExhYmVsZWREYXRhU2VxdWVuY2UgPiA+IGFPbGRfTERTKCBhTERTICk7CiAgICAgICAgICAgICAgICB1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYTGFiZWxlZERhdGFTZXF1ZW5jZSA+ICpwT2xkX0xEUyA9IGFPbGRfTERTLmdldEFycmF5KCk7CgogICAgICAgICAgICAgICAgc2FsX0ludDMyIG5OZXdDbnQgPSAwOwogICAgICAgICAgICAgICAgZm9yIChzYWxfSW50MzIgaSA9IDA7ICBpIDwgblNlcXVlbmNlTWFwcGluZ0xlbjsgICsraSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IGluZGV4IHRvIGJlIHVzZWQgaXMgdmFsaWQKICAgICAgICAgICAgICAgICAgICAvLyBhbmQgaGFzIG5vdCB5ZXQgYmVlbiB1c2VkCiAgICAgICAgICAgICAgICAgICAgc2FsX0ludDMyIG5JZHggPSBwU2VxdWVuY2VNYXBwaW5nW2ldOwogICAgICAgICAgICAgICAgICAgIGlmICgwIDw9IG5JZHggJiYgbklkeCA8IG5OdW1MRFMgJiYgcE9sZF9MRFNbbklkeF0uaXMoKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBMRFNbbk5ld0NudCsrXSA9IHBPbGRfTERTW25JZHhdOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWFyayBpbmRleCBhcyBiZWluZyB1c2VkIGFscmVhZHkgKGF2b2lkcyBkdXBsaWNhdGUgZW50cmllcykKICAgICAgICAgICAgICAgICAgICAgICAgcE9sZF9MRFNbbklkeF0uY2xlYXIoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBhZGQgbm90IHlldCB1c2VkICdvbGQnIHNlcXVlbmNlcyB0byBuZXcgb25lCiAgICAgICAgICAgICAgICBmb3IgKHNhbF9JbnQzMiBpID0gMDsgIGkgPCBuTnVtTERTOyAgKytpKQogICAgICAgICAgICAgICAgewojaWYgT1NMX0RFQlVHX0xFVkVMID4gMQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXBPbGRfTERTW2ldLmlzKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID0gaTsKI2VuZGlmCiAgICAgICAgICAgICAgICAgICAgaWYgKHBPbGRfTERTW2ldLmlzKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHBMRFNbbk5ld0NudCsrXSA9IHBPbGRfTERTW2ldOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgREJHX0FTU0VSVCggbk5ld0NudCA9PSBuTnVtTERTLCAidW5leHBlY3RlZCBzaXplIG9mIHJlc3VsdGluZyBzZXF1ZW5jZSIgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgeFJlcyA9IG5ldyBTd0NoYXJ0RGF0YVNvdXJjZSggYUxEUyApOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4geFJlczsKfQoKc2FsX0Jvb2wgU0FMX0NBTEwgU3dDaGFydERhdGFQcm92aWRlcjo6Y3JlYXRlRGF0YVNvdXJjZVBvc3NpYmxlKAogICAgICAgIGNvbnN0IHVubzo6U2VxdWVuY2U8IGJlYW5zOjpQcm9wZXJ0eVZhbHVlID4mIHJBcmd1bWVudHMgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgdm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgogICAgc2FsX0Jvb2wgYlBvc3NpYmxlID0gc2FsX1RydWU7CiAgICB0cnkKICAgIHsKICAgICAgICBJbXBsX2NyZWF0ZURhdGFTb3VyY2UoIHJBcmd1bWVudHMsIHNhbF9UcnVlICk7CiAgICB9CiAgICBjYXRjaCAobGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICYpCiAgICB7CiAgICAgICAgYlBvc3NpYmxlID0gc2FsX0ZhbHNlOwogICAgfQoKICAgIHJldHVybiBiUG9zc2libGU7Cn0KCnVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU291cmNlID4gU0FMX0NBTEwgU3dDaGFydERhdGFQcm92aWRlcjo6Y3JlYXRlRGF0YVNvdXJjZSgKICAgICAgICBjb25zdCB1bm86OlNlcXVlbmNlPCBiZWFuczo6UHJvcGVydHlWYWx1ZSA+JiByQXJndW1lbnRzICkKICAgIHRocm93IChsYW5nOjpJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgdm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CiAgICByZXR1cm4gSW1wbF9jcmVhdGVEYXRhU291cmNlKCByQXJndW1lbnRzICk7Cn0KCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLyBTd0NoYXJ0RGF0YVByb3ZpZGVyOjpHZXRCcm9rZW5DZWxsUmFuZ2VGb3JFeHBvcnQKLy8KLy8gZml4IGZvciAjaTc5MDA5Ci8vIHdlIG5lZWQgdG8gcmV0dXJuIGEgcHJvcGVydHkgdGhhdCBoYXMgdGhlIHNhbWUgdmFsdWUgYXMgdGhlIHByb3BlcnR5Ci8vICdDZWxsUmFuZ2VSZXByZXNlbnRhdGlvbicgYnV0IGZvciBhbGwgcm93cyB3aGljaCBhcmUgaW5jcmVhc2VkIGJ5IG9uZS4KLy8gRS5nLiBUYWJsZTE6QTE6RDUgLT4gVGFibGUxOkEyOkQ2Ci8vIFNpbmNlIHRoZSBwcm9ibGVtIGlzIG9ubHkgZm9yIG9sZCBjaGFydHMgd2hpY2ggZGlkIG5vdCBzdXBwb3J0IG11bHRpcGxlCi8vIHdlIGRvIG5vdCBuZWVkIHRvIHByb3ZpZGUgdGhhdCBwcm9wZXJ0eS9zdHJpbmcgaWYgdGhlICdDZWxsUmFuZ2VSZXByZXNlbnRhdGlvbicKLy8gY29udGFpbnMgbXVsdGlwbGUgcmFuZ2VzLgpPVVN0cmluZyBTd0NoYXJ0RGF0YVByb3ZpZGVyOjpHZXRCcm9rZW5DZWxsUmFuZ2VGb3JFeHBvcnQoCiAgICBjb25zdCBPVVN0cmluZyAmckNlbGxSYW5nZVJlcHJlc2VudGF0aW9uICkKewogICAgT1VTdHJpbmcgYVJlczsKCiAgICAvLyBjaGVjayB0aGF0IHdlIGRvIG5vdCBoYXZlIG11bHRpcGxlIHJhbmdlcwogICAgaWYgKC0xID09IHJDZWxsUmFuZ2VSZXByZXNlbnRhdGlvbi5pbmRleE9mKCAnOycgKSkKICAgIHsKICAgICAgICAvLyBnZXQgY3VycmVudCBjZWxsIGFuZCB0YWJsZSBuYW1lcwogICAgICAgIFN0cmluZyBhVGJsTmFtZSwgYVN0YXJ0Q2VsbCwgYUVuZENlbGw7CiAgICAgICAgR2V0VGFibGVBbmRDZWxsc0Zyb21SYW5nZVJlcCggckNlbGxSYW5nZVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICBhVGJsTmFtZSwgYVN0YXJ0Q2VsbCwgYUVuZENlbGwsIHNhbF9GYWxzZSApOwogICAgICAgIHNhbF9JbnQzMiBuU3RhcnRDb2wgPSAtMSwgblN0YXJ0Um93ID0gLTEsIG5FbmRDb2wgPSAtMSwgbkVuZFJvdyA9IC0xOwogICAgICAgIGxjbF9HZXRDZWxsUG9zaXRpb24oIGFTdGFydENlbGwsIG5TdGFydENvbCwgblN0YXJ0Um93ICk7CiAgICAgICAgbGNsX0dldENlbGxQb3NpdGlvbiggYUVuZENlbGwsIG5FbmRDb2wsIG5FbmRSb3cgKTsKCiAgICAgICAgLy8gZ2V0IG5ldyBjZWxsIG5hbWVzCiAgICAgICAgKytuU3RhcnRSb3c7CiAgICAgICAgKytuRW5kUm93OwogICAgICAgIGFTdGFydENlbGwgPSBsY2xfR2V0Q2VsbE5hbWUoIG5TdGFydENvbCwgblN0YXJ0Um93ICk7CiAgICAgICAgYUVuZENlbGwgICA9IGxjbF9HZXRDZWxsTmFtZSggbkVuZENvbCwgbkVuZFJvdyApOwoKICAgICAgICBhUmVzID0gR2V0UmFuZ2VSZXBGcm9tVGFibGVBbmRDZWxscyggYVRibE5hbWUsCiAgICAgICAgICAgICAgICBhU3RhcnRDZWxsLCBhRW5kQ2VsbCwgc2FsX0ZhbHNlICk7CiAgICB9CgogICAgcmV0dXJuIGFSZXM7Cn0KCnVubzo6U2VxdWVuY2U8IGJlYW5zOjpQcm9wZXJ0eVZhbHVlID4gU0FMX0NBTEwgU3dDaGFydERhdGFQcm92aWRlcjo6ZGV0ZWN0QXJndW1lbnRzKAogICAgICAgIGNvbnN0IHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU291cmNlID4mIHhEYXRhU291cmNlICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIHZvczo6T0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwogICAgaWYgKGJEaXNwb3NlZCkKICAgICAgICB0aHJvdyBsYW5nOjpEaXNwb3NlZEV4Y2VwdGlvbigpOwoKICAgIHVubzo6U2VxdWVuY2U8IGJlYW5zOjpQcm9wZXJ0eVZhbHVlID4gYVJlc3VsdDsKICAgIGlmICgheERhdGFTb3VyY2UuaXMoKSkKICAgICAgICByZXR1cm4gYVJlc3VsdDsKCiAgICBjb25zdCB1bm86OlNlcXVlbmNlPCB1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYTGFiZWxlZERhdGFTZXF1ZW5jZSA+ID4gYURTX0xEUyggeERhdGFTb3VyY2UtPmdldERhdGFTZXF1ZW5jZXMoKSApOwogICAgY29uc3QgdW5vOjpSZWZlcmVuY2U8IGNoYXJ0Mjo6ZGF0YTo6WExhYmVsZWREYXRhU2VxdWVuY2UgPiAqcERTX0xEUyA9IGFEU19MRFMuZ2V0Q29uc3RBcnJheSgpOwogICAgc2FsX0ludDMyIG5OdW1EU19MRFMgPSBhRFNfTERTLmdldExlbmd0aCgpOwoKICAgIGlmIChuTnVtRFNfTERTID09IDApCgl7CgkgICAgREJHX1dBUk5JTkcoICJYTGFiZWxlZERhdGFTZXF1ZW5jZSBpbiBkYXRhIHNvdXJjZSBjb250YWlucyAwIGVudHJpZXMiICk7CiAgICAgICAgcmV0dXJuIGFSZXN1bHQ7Cgl9CgogICAgU3dGcm1GbXQgKnBUYWJsZUZtdCA9IDA7CiAgICBTd1RhYmxlICAqcFRhYmxlICAgID0gMDsKICAgIFN0cmluZyAgICBhVGFibGVOYW1lOwogICAgc2FsX0ludDMyIG5UYWJsZVJvd3MgPSAwOwogICAgc2FsX0ludDMyIG5UYWJsZUNvbHMgPSAwOwoKICAgIC8vIGRhdGEgdXNlZCB0byBidWlsZCAnQ2VsbFJhbmdlUmVwcmVzZW50YXRpb24nIGZyb20gbGF0ZXIgb24KICAgIHN0ZDo6dmVjdG9yPCBzdGQ6OnZlY3Rvcjwgc2FsX0NoYXIgPiA+IGFNYXA7CgogICAgdW5vOjpTZXF1ZW5jZTwgc2FsX0ludDMyID4gYVNlcXVlbmNlTWFwcGluZyggbk51bURTX0xEUyApOwogICAgc2FsX0ludDMyICpwU2VxdWVuY2VNYXBwaW5nID0gYVNlcXVlbmNlTWFwcGluZy5nZXRBcnJheSgpOwoKICAgIFN0cmluZyBhQ2VsbFJhbmdlczsKICAgIHNhbF9JbnQxNiBuRHRhU3JjSXNDb2x1bW5zID0gLTE7Ly8gLTE6IGRvbid0IGtub3cgeWV0LCAwOiBmYWxzZSwgMTogdHJ1ZSAgLTI6IG5laXRoZXIKICAgIHNhbF9JbnQzMiBuTGFiZWxTZXFMZW4gID0gLTE7ICAgLy8gdXNlZCB0byBzZWUgaWYgbGFiZWxzIGFyZSBhbHdheXMgdXNlZCBvciBub3QgYW5kIGhhdmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGV4cGVjdGVkIHNpemUgb2YgMSAoaS5lLiBpZiBGaXJzdENlbGxBc0xhYmVsIGNhbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBiZSBkZXRlcm1pbmVkKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAtMTogZG9uJ3Qga25vdyB5ZXQsIDA6IG5vdCB1c2VkLCAxOiBhbHdheXMgYSBzaW5nbGUgbGFiZSBjZWxsLCAuLi4KCQkJCQkJCQkJLy8gLTI6IG5laXRoZXIvZmFpbGVkCi8vICAgICBzYWxfSW50MzIgblZhbHVlc1NlcUxlbiA9IC0xOyAgIC8vIHVzZWQgdG8gc2VlIGlmIGFsbCB2YWx1ZSBzZXF1ZW5jZXMgaGF2ZSB0aGUgc2FtZSBzaXplCiAgICBmb3IgKHNhbF9JbnQzMiBuRFMxID0gMDsgIG5EUzEgPCBuTnVtRFNfTERTOyAgKytuRFMxKQogICAgewogICAgICAgIHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhMYWJlbGVkRGF0YVNlcXVlbmNlID4geExhYmVsZWREYXRhU2VxdWVuY2UoIHBEU19MRFNbbkRTMV0gKTsKICAgICAgICBpZiggIXhMYWJlbGVkRGF0YVNlcXVlbmNlLmlzKCkgKQogICAgICAgIHsKICAgICAgICAgICAgREJHX0VSUk9SKCJnb3QgTlVMTCBmb3IgWExhYmVsZWREYXRhU2VxdWVuY2UgZnJvbSBEYXRhIHNvdXJjZSIpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgY29uc3QgdW5vOjpSZWZlcmVuY2U8IGNoYXJ0Mjo6ZGF0YTo6WERhdGFTZXF1ZW5jZSA+IHhDdXJMYWJlbCggeExhYmVsZWREYXRhU2VxdWVuY2UtPmdldExhYmVsKCksIHVubzo6VU5PX1FVRVJZICk7CiAgICAgICAgY29uc3QgdW5vOjpSZWZlcmVuY2U8IGNoYXJ0Mjo6ZGF0YTo6WERhdGFTZXF1ZW5jZSA+IHhDdXJWYWx1ZXMoIHhMYWJlbGVkRGF0YVNlcXVlbmNlLT5nZXRWYWx1ZXMoKSwgdW5vOjpVTk9fUVVFUlkgKTsKCiAgICAgICAgLy8gZ2V0IHNlcXVlbmNlIGxlbmd0aHMgZm9yIGxhYmVsIGFuZCB2YWx1ZXMuCgkJLy8gKDAgbGVuZ3RoIGlzIE9rKQogICAgICAgIHNhbF9JbnQzMiBuQ3VyTGFiZWxTZXFMZW4gICA9IC0xOwogICAgICAgIHNhbF9JbnQzMiBuQ3VyVmFsdWVzU2VxTGVuICA9IC0xOwogICAgICAgIGlmICh4Q3VyTGFiZWwuaXMoKSkKICAgICAgICAgICAgbkN1ckxhYmVsU2VxTGVuID0geEN1ckxhYmVsLT5nZXREYXRhKCkuZ2V0TGVuZ3RoKCk7CiAgICAgICAgaWYgKHhDdXJWYWx1ZXMuaXMoKSkKICAgICAgICAgICAgbkN1clZhbHVlc1NlcUxlbiA9IHhDdXJWYWx1ZXMtPmdldERhdGEoKS5nZXRMZW5ndGgoKTsKCgkJLy8gY2hlY2sgZm9yIGNvbnNpc3RlbnQgdXNlIG9mICdmaXJzdCBjZWxsIGFzIGxhYmVsJwoJCWlmIChuTGFiZWxTZXFMZW4gPT0gLTEpCQkvLyBzZXQgaW5pdGlhbCB2YWx1ZSB0byBjb21wYXJlIHdpdGggYmVsb3cgZnVydGhlciBvbgoJCQluTGFiZWxTZXFMZW4gPSBuQ3VyTGFiZWxTZXFMZW47CgkJaWYgKG5MYWJlbFNlcUxlbiAhPSBuQ3VyTGFiZWxTZXFMZW4pCgkJCW5MYWJlbFNlcUxlbiA9IC0yOwkvLyBmYWlsZWQgLyBubyBjb25zaXN0ZW50IHVzZSBvZiBsYWJlbCBjZWxscwoKICAgICAgICAvLyBnZXQgdGFibGUgYW5kIGNlbGwgbmFtZXMgZm9yIGxhYmVsIGFuZCB2YWx1ZXMgZGF0YSBzZXF1ZW5jZXMKICAgICAgICAvLyAoc3RhcnQgYW5kIGVuZCBjZWxsIHdpbGwgYmUgc29ydGVkLCBpLmUuIHN0YXJ0IGNlbGwgPD0gZW5kIGNlbGwpCiAgICAgICAgU3RyaW5nIGFMYWJlbFRibE5hbWUsIGFMYWJlbFN0YXJ0Q2VsbCwgYUxhYmVsRW5kQ2VsbDsKICAgICAgICBTdHJpbmcgYVZhbHVlc1RibE5hbWUsIGFWYWx1ZXNTdGFydENlbGwsIGFWYWx1ZXNFbmRDZWxsOwogICAgICAgIFN0cmluZyBhTGFiZWxSYW5nZSwgYVZhbHVlc1JhbmdlOwoJCWlmICh4Q3VyTGFiZWwuaXMoKSkKCQkJYUxhYmVsUmFuZ2UgPSB4Q3VyTGFiZWwtPmdldFNvdXJjZVJhbmdlUmVwcmVzZW50YXRpb24oKTsKCQlpZiAoeEN1clZhbHVlcy5pcygpKQoJCQlhVmFsdWVzUmFuZ2UgPSB4Q3VyVmFsdWVzLT5nZXRTb3VyY2VSYW5nZVJlcHJlc2VudGF0aW9uKCk7CiAgICAgICAgaWYgKChhTGFiZWxSYW5nZS5MZW4oKSAmJiAhR2V0VGFibGVBbmRDZWxsc0Zyb21SYW5nZVJlcCggYUxhYmVsUmFuZ2UsCiAgICAgICAgICAgICAgICBhTGFiZWxUYmxOYW1lLCBhTGFiZWxTdGFydENlbGwsIGFMYWJlbEVuZENlbGwgKSkgIHx8CiAgICAgICAgICAgICFHZXRUYWJsZUFuZENlbGxzRnJvbVJhbmdlUmVwKCBhVmFsdWVzUmFuZ2UsCiAgICAgICAgICAgICAgICBhVmFsdWVzVGJsTmFtZSwgYVZhbHVlc1N0YXJ0Q2VsbCwgYVZhbHVlc0VuZENlbGwgKSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBhUmVzdWx0OyAvLyBmYWlsZWQgLT4gcmV0dXJuIGVtcHR5IHByb3BlcnR5IHNlcXVlbmNlCiAgICAgICAgfQoKICAgICAgICAvLyBtYWtlIHN1cmUgYWxsIHNlcXVlbmNlcyB1c2UgdGhlIHNhbWUgdGFibGUKICAgICAgICBpZiAoIWFUYWJsZU5hbWUuTGVuKCkpCiAgICAgICAgICAgIGFUYWJsZU5hbWUgPSBhVmFsdWVzVGJsTmFtZTsgIC8vIGdldCBpbml0aWFsIHZhbHVlIHRvIGNvbXBhcmUgd2l0aAogICAgICAgIGlmICghYVRhYmxlTmFtZS5MZW4oKSB8fAogICAgICAgICAgICAgYVRhYmxlTmFtZSAhPSBhVmFsdWVzVGJsTmFtZSB8fAogICAgICAgICAgICAoYUxhYmVsVGJsTmFtZS5MZW4oKSAmJiBhVGFibGVOYW1lICE9IGFMYWJlbFRibE5hbWUpKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGFSZXN1bHQ7IC8vIGZhaWxlZCAtPiByZXR1cm4gZW1wdHkgcHJvcGVydHkgc2VxdWVuY2UKICAgICAgICB9CgoKICAgICAgICAvLyB0cnkgdG8gZ2V0ICdEYXRhUm93U291cmNlJyB2YWx1ZSAoUk9XUyBvciBDT0xVTU5TKSBmcm9tIGluc3BlY3RpbmcKICAgICAgICAvLyBmaXJzdCBhbmQgbGFzdCBjZWxsIHVzZWQgaW4gYm90aCBzZXF1ZW5jZXMKCQkvLwogICAgICAgIHNhbF9JbnQzMiBuRmlyc3RDb2wgPSAtMSwgbkZpcnN0Um93ID0gLTEsIG5MYXN0Q29sID0gLTEsIG5MYXN0Um93ID0gLTE7CiAgICAgICAgU3RyaW5nIGFDZWxsKCBhTGFiZWxTdGFydENlbGwuTGVuKCkgPyBhTGFiZWxTdGFydENlbGwgOiBhVmFsdWVzU3RhcnRDZWxsICk7CiAgICAgICAgREJHX0FTU0VSVCggYUNlbGwuTGVuKCkgLCAic3RhcnQgY2VsbCBtaXNzaW5nPyIgKTsKICAgICAgICBsY2xfR2V0Q2VsbFBvc2l0aW9uKCBhQ2VsbCwgbkZpcnN0Q29sLCBuRmlyc3RSb3cpOwogICAgICAgIGxjbF9HZXRDZWxsUG9zaXRpb24oIGFWYWx1ZXNFbmRDZWxsLCBuTGFzdENvbCwgbkxhc3RSb3cpOwogICAgICAgIC8vCiAgICAgICAgc2FsX0ludDE2IG5EaXJlY3Rpb24gPSAtMTsgIC8vIC0xOiBub3QgeWV0IHNldCwgIDA6IGNvbHVtbnMsICAxOiByb3dzLCAtMjogZmFpbGVkCiAgICAgICAgaWYgKG5GaXJzdENvbCA9PSBuTGFzdENvbCAmJiBuRmlyc3RSb3cgPT0gbkxhc3RSb3cpIC8vIGEgc2luZ2xlIGNlbGwuLi4KICAgICAgICB7CiAgICAgICAgICAgIERCR19BU1NFUlQoIG5DdXJMYWJlbFNlcUxlbiA9PSAwICYmIG5DdXJWYWx1ZXNTZXFMZW4gPT0gMSwKICAgICAgICAgICAgICAgICAgICAidHJ5aW5nIHRvIGRldGVybWluZSAnRGF0YVJvd1NvdXJjZSc6IHNvbWV0aGluZydzIGZpc2h5Li4uIHNob3VsZCBoYXZlIGJlZW4gYSBzaW5nbGUgY2VsbCIpOwogICAgICAgICAgICBuRGlyZWN0aW9uID0gMDsgICAgIC8vIGRlZmF1bHQgZGlyZWN0aW9uIGZvciBhIHNpbmdsZSBjZWxsIHNob3VsZCBiZSAnY29sdW1ucycKICAgICAgICB9CiAgICAgICAgZWxzZSAgICAvLyBtb3JlIHRoYW4gb25lIGNlbGwgaXMgYXZhaWxhYmFsZSAoaW4gdmFsdWVzIGFuZCBsYWJlbCB0b2dldGhlciEpCiAgICAgICAgewogICAgICAgICAgICBpZiAobkZpcnN0Q29sID09IG5MYXN0Q29sICYmIG5GaXJzdFJvdyAhPSBuTGFzdFJvdykKICAgICAgICAgICAgICAgIG5EaXJlY3Rpb24gPSAxOwogICAgICAgICAgICBlbHNlIGlmIChuRmlyc3RDb2wgIT0gbkxhc3RDb2wgJiYgbkZpcnN0Um93ID09IG5MYXN0Um93KQogICAgICAgICAgICAgICAgbkRpcmVjdGlvbiA9IDA7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgREJHX0VSUk9SKCAidHJ5aW5nIHRvIGRldGVybWluZSAnRGF0YVJvd1NvdXJjZSc6IHVuZXhwZWN0ZWQgY2FzZSBmb3VuZCIgKTsKICAgICAgICAgICAgICAgIG5EaXJlY3Rpb24gPSAtMjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBjaGVjayBmb3IgY29uc2lzdGVudCBkaXJlY3Rpb24gb2YgZGF0YSBzb3VyY2UKICAgICAgICBpZiAobkR0YVNyY0lzQ29sdW1ucyA9PSAtMSkgICAgIC8vIHNldCBpbml0aWFsIHZhbHVlIHRvIGNvbXBhcmUgd2l0aCBiZWxvdwogICAgICAgICAgICBuRHRhU3JjSXNDb2x1bW5zID0gbkRpcmVjdGlvbjsKICAgICAgICBpZiAobkR0YVNyY0lzQ29sdW1ucyAhPSBuRGlyZWN0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgbkR0YVNyY0lzQ29sdW1ucyA9IC0yOwkvLyBmYWlsZWQKICAgICAgICB9CgoKCQlpZiAobkR0YVNyY0lzQ29sdW1ucyA9PSAwIHx8IG5EdGFTcmNJc0NvbHVtbnMgPT0gMSkKCQl7CgkJCS8vIGJ1aWxkIGRhdGEgdG8gb2J0YWluICdTZXF1ZW5jZU1hcHBpbmcnIGxhdGVyIG9uCgkJCS8vCgkJCURCR19BU1NFUlQoIG5EdGFTcmNJc0NvbHVtbnMgPT0gMCAgfHwgICAvKiByb3dzICovCgkJCQkJCW5EdGFTcmNJc0NvbHVtbnMgPT0gMSwgICAgICAvKiBjb2x1bW5zICovCgkJCQkJInVuZXhwZWN0ZWQgdmFsdWUgZm9yICduRHRhU3JjSXNDb2x1bW5zJyIgKTsKCQkJcFNlcXVlbmNlTWFwcGluZ1tuRFMxXSA9IG5EdGFTcmNJc0NvbHVtbnMgPyBuRmlyc3RDb2wgOiBuRmlyc3RSb3c7CgoKCQkJLy8gYnVpbGQgZGF0YSB1c2VkIHRvIGRldGVybWluZSAnQ2VsbFJhbmdlUmVwcmVzZW50YXRpb24nIGxhdGVyIG9uCgkJCS8vCgkJCUdldFRhYmxlQnlOYW1lKCAqcERvYywgYVRhYmxlTmFtZSwgJnBUYWJsZUZtdCwgJnBUYWJsZSApOwoJCQlpZiAoIXBUYWJsZSB8fCBwVGFibGUtPklzVGJsQ29tcGxleCgpKQoJCQkJcmV0dXJuIGFSZXN1bHQ7IC8vIGZhaWxlZCAtPiByZXR1cm4gZW1wdHkgcHJvcGVydHkgc2VxdWVuY2UKCQkJblRhYmxlUm93cyA9IHBUYWJsZS0+R2V0VGFiTGluZXMoKS5Db3VudCgpOwoJCQluVGFibGVDb2xzID0gcFRhYmxlLT5HZXRUYWJMaW5lcygpLkdldE9iamVjdCgwKS0+R2V0VGFiQm94ZXMoKS5Db3VudCgpOwoJCQlhTWFwLnJlc2l6ZSggblRhYmxlUm93cyApOwogICAgICAgICAgICBmb3IgKHNhbF9JbnQzMiBpID0gMDsgIGkgPCBuVGFibGVSb3dzOyAgKytpKQoJCQkJYU1hcFtpXS5yZXNpemUoIG5UYWJsZUNvbHMgKTsKCQkJLy8KCQkJaWYgKGFMYWJlbFN0YXJ0Q2VsbC5MZW4oKSAmJiBhTGFiZWxFbmRDZWxsLkxlbigpKQoJCQl7CgkJCQlzYWxfSW50MzIgblN0YXJ0Q29sID0gLTEsIG5TdGFydFJvdyA9IC0xLCBuRW5kQ29sID0gLTEsIG5FbmRSb3cgPSAtMTsKCQkJCWxjbF9HZXRDZWxsUG9zaXRpb24oIGFMYWJlbFN0YXJ0Q2VsbCwgblN0YXJ0Q29sLCBuU3RhcnRSb3cgKTsKCQkJCWxjbF9HZXRDZWxsUG9zaXRpb24oIGFMYWJlbEVuZENlbGwsICAgbkVuZENvbCwgICBuRW5kUm93ICk7CgkJCQlpZiAoblN0YXJ0Um93IDwgMCB8fCBuRW5kUm93ID49IG5UYWJsZVJvd3MgfHwKCQkJCQluU3RhcnRDb2wgPCAwIHx8IG5FbmRDb2wgPj0gblRhYmxlQ29scykKCQkJCXsKCQkJCQlyZXR1cm4gYVJlc3VsdDsgLy8gZmFpbGVkIC0+IHJldHVybiBlbXB0eSBwcm9wZXJ0eSBzZXF1ZW5jZQoJCQkJfQogICAgICAgICAgICAgICAgZm9yIChzYWxfSW50MzIgaSA9IG5TdGFydFJvdzsgIGkgPD0gbkVuZFJvdzsgICsraSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHNhbF9JbnQzMiBrID0gblN0YXJ0Q29sOyAgayA8PSBuRW5kQ29sOyAgKytrKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2FsX0NoYXIgJnJDaGFyID0gYU1hcFtpXVtrXTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJDaGFyID09ICdcMCcpICAgLy8gY2hlY2sgZm9yIG92ZXJsYXBwaW5nIHZhbHVlcyBhbmQvb3IgbGFiZWxzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByQ2hhciA9ICdMJzsKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFSZXN1bHQ7IC8vIGZhaWxlZCAtPiByZXR1cm4gZW1wdHkgcHJvcGVydHkgc2VxdWVuY2UKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgkJCX0KCQkJaWYgKGFWYWx1ZXNTdGFydENlbGwuTGVuKCkgJiYgYVZhbHVlc0VuZENlbGwuTGVuKCkpCgkJCXsKCQkJCXNhbF9JbnQzMiBuU3RhcnRDb2wgPSAtMSwgblN0YXJ0Um93ID0gLTEsIG5FbmRDb2wgPSAtMSwgbkVuZFJvdyA9IC0xOwoJCQkJbGNsX0dldENlbGxQb3NpdGlvbiggYVZhbHVlc1N0YXJ0Q2VsbCwgblN0YXJ0Q29sLCBuU3RhcnRSb3cgKTsKCQkJCWxjbF9HZXRDZWxsUG9zaXRpb24oIGFWYWx1ZXNFbmRDZWxsLCAgIG5FbmRDb2wsICAgbkVuZFJvdyApOwoJCQkJaWYgKG5TdGFydFJvdyA8IDAgfHwgbkVuZFJvdyA+PSBuVGFibGVSb3dzIHx8CgkJCQkJblN0YXJ0Q29sIDwgMCB8fCBuRW5kQ29sID49IG5UYWJsZUNvbHMpCgkJCQl7CgkJCQkJcmV0dXJuIGFSZXN1bHQ7IC8vIGZhaWxlZCAtPiByZXR1cm4gZW1wdHkgcHJvcGVydHkgc2VxdWVuY2UKCQkJCX0KICAgICAgICAgICAgICAgIGZvciAoc2FsX0ludDMyIGkgPSBuU3RhcnRSb3c7ICBpIDw9IG5FbmRSb3c7ICArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChzYWxfSW50MzIgayA9IG5TdGFydENvbDsgIGsgPD0gbkVuZENvbDsgICsraykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNhbF9DaGFyICZyQ2hhciA9IGFNYXBbaV1ba107CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyQ2hhciA9PSAnXDAnKSAgIC8vIGNoZWNrIGZvciBvdmVybGFwcGluZyB2YWx1ZXMgYW5kL29yIGxhYmVscwogICAgICAgICAgICAgICAgICAgICAgICAgICAgckNoYXIgPSAneCc7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhUmVzdWx0OyAvLyBmYWlsZWQgLT4gcmV0dXJuIGVtcHR5IHByb3BlcnR5IHNlcXVlbmNlCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoJCQl9CgkJfQoKI2lmIE9TTF9ERUJVR19MRVZFTCA+IDEKICAgICAgICAvLyBkbyBzb21lIGV4dHJhIHNhbml0eSBjaGVja2luZyB0aGF0IHRoZSBsZW5ndGggb2YgdGhlIHNlcXVlbmNlcwogICAgICAgIC8vIG1hdGNoZXMgdGhlaXIgcmFuZ2UgcmVwcmVzZW50YXRpb24KICAgICAgICB7CiAgICAgICAgICAgIHNhbF9JbnQzMiBuU3RhcnRSb3cgPSAtMSwgblN0YXJ0Q29sID0gLTEsIG5FbmRSb3cgPSAtMSwgbkVuZENvbCA9IC0xOwogICAgICAgICAgICBpZiAoeEN1ckxhYmVsLmlzKCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxjbF9HZXRDZWxsUG9zaXRpb24oIGFMYWJlbFN0YXJ0Q2VsbCwgblN0YXJ0Q29sLCBuU3RhcnRSb3cpOwogICAgICAgICAgICAgICAgbGNsX0dldENlbGxQb3NpdGlvbiggYUxhYmVsRW5kQ2VsbCwgICBuRW5kQ29sLCAgIG5FbmRSb3cpOwogICAgICAgICAgICAgICAgREJHX0FTU0VSVCggKG5TdGFydENvbCA9PSBuRW5kQ29sICYmIChuRW5kUm93IC0gblN0YXJ0Um93ICsgMSkgPT0geEN1ckxhYmVsLT5nZXREYXRhKCkuZ2V0TGVuZ3RoKCkpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoblN0YXJ0Um93ID09IG5FbmRSb3cgJiYgKG5FbmRDb2wgLSBuU3RhcnRDb2wgKyAxKSA9PSB4Q3VyTGFiZWwtPmdldERhdGEoKS5nZXRMZW5ndGgoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICJsYWJlbCBzZXF1ZW5jZSBsZW5ndGggZG9lcyBub3QgbWF0Y2ggcmFuZ2UgcmVwcmVzZW50YXRpb24hIiApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh4Q3VyVmFsdWVzLmlzKCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxjbF9HZXRDZWxsUG9zaXRpb24oIGFWYWx1ZXNTdGFydENlbGwsIG5TdGFydENvbCwgblN0YXJ0Um93KTsKICAgICAgICAgICAgICAgIGxjbF9HZXRDZWxsUG9zaXRpb24oIGFWYWx1ZXNFbmRDZWxsLCAgIG5FbmRDb2wsICAgbkVuZFJvdyk7CiAgICAgICAgICAgICAgICBEQkdfQVNTRVJUKCAoblN0YXJ0Q29sID09IG5FbmRDb2wgJiYgKG5FbmRSb3cgLSBuU3RhcnRSb3cgKyAxKSA9PSB4Q3VyVmFsdWVzLT5nZXREYXRhKCkuZ2V0TGVuZ3RoKCkpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoblN0YXJ0Um93ID09IG5FbmRSb3cgJiYgKG5FbmRDb2wgLSBuU3RhcnRDb2wgKyAxKSA9PSB4Q3VyVmFsdWVzLT5nZXREYXRhKCkuZ2V0TGVuZ3RoKCkpLAogICAgICAgICAgICAgICAgICAgICAgICAidmFsdWUgc2VxdWVuY2UgbGVuZ3RoIGRvZXMgbm90IG1hdGNoIHJhbmdlIHJlcHJlc2VudGF0aW9uISIgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KI2VuZGlmCiAgICB9IC8vIGZvcgoKCiAgICAvLyBidWlsZCB2YWx1ZSBmb3IgJ0NlbGxSYW5nZVJlcHJlc2VudGF0aW9uJwogICAgLy8KICAgIFN0cmluZyBhQ2VsbFJhbmdlQmFzZSggYVRhYmxlTmFtZSApOwogICAgYUNlbGxSYW5nZUJhc2UgKz0gJy4nOwogICAgU3RyaW5nIGFDdXJSYW5nZTsKICAgIGZvciAoc2FsX0ludDMyIGkgPSAwOyAgaSA8IG5UYWJsZVJvd3M7ICArK2kpCgl7CiAgICAgICAgZm9yIChzYWxfSW50MzIgayA9IDA7ICBrIDwgblRhYmxlQ29sczsgICsraykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChhTWFwW2ldW2tdICE9ICdcMCcpICAvLyB0b3AtbGVmdCBjZWxsIG9mIGEgc3ViLXJhbmdlIGZvdW5kCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGZpbmQgcmVjdGFuZ3VsYXIgc3ViLXJhbmdlIHRvIHVzZQogICAgICAgICAgICAgICAgc2FsX0ludDMyIG5Sb3dJbmRleDEgPSBpOyAgIC8vIHJvdyBpbmRleAogICAgICAgICAgICAgICAgc2FsX0ludDMyIG5Db2xJbmRleDEgPSBrOyAgIC8vIGNvbHVtbiBpbmRleAogICAgICAgICAgICAgICAgc2FsX0ludDMyIG5Sb3dTdWJMZW4gPSAwOwogICAgICAgICAgICAgICAgc2FsX0ludDMyIG5Db2xTdWJMZW4gPSAwOwogICAgICAgICAgICAgICAgd2hpbGUgKG5Sb3dJbmRleDEgPCBuVGFibGVSb3dzICYmIGFNYXBbblJvd0luZGV4MSsrXVtrXSAhPSAnXDAnKQogICAgICAgICAgICAgICAgICAgICsrblJvd1N1YkxlbjsKICAgICAgICAgICAgICAgIC8vIGJlIGF3YXJlIG9mIHNoaWZ0ZWQgc2VxdWVuY2VzIQogICAgICAgICAgICAgICAgLy8gKGFjY29yZGluZyB0byB0aGUgY2hlY2tzIGRvbmUgcHJpb3IgdGhlIGxlbmd0aCBzaG91bGQgYmUgb2spCiAgICAgICAgICAgICAgICB3aGlsZSAobkNvbEluZGV4MSA8IG5UYWJsZUNvbHMgJiYgYU1hcFtpXVtuQ29sSW5kZXgxXSAhPSAnXDAnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGFNYXBbaSArIG5Sb3dTdWJMZW4tMV1bbkNvbEluZGV4MV0gIT0gJ1wwJykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICArK25Db2xJbmRleDE7CiAgICAgICAgICAgICAgICAgICAgKytuQ29sU3ViTGVuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgU3RyaW5nIGFTdGFydENlbGwoIGxjbF9HZXRDZWxsTmFtZSggaywgaSApICk7CiAgICAgICAgICAgICAgICBTdHJpbmcgYUVuZENlbGwoIGxjbF9HZXRDZWxsTmFtZSggayArIG5Db2xTdWJMZW4gLSAxLCBpICsgblJvd1N1YkxlbiAtIDEpICk7CiAgICAgICAgICAgICAgICBhQ3VyUmFuZ2UgPSBhQ2VsbFJhbmdlQmFzZTsKICAgICAgICAgICAgICAgIGFDdXJSYW5nZSArPSBhU3RhcnRDZWxsOwogICAgICAgICAgICAgICAgYUN1clJhbmdlICs9ICc6JzsKICAgICAgICAgICAgICAgIGFDdXJSYW5nZSArPSBhRW5kQ2VsbDsKICAgICAgICAgICAgICAgIGlmIChhQ2VsbFJhbmdlcy5MZW4oKSkKICAgICAgICAgICAgICAgICAgICBhQ2VsbFJhbmdlcyArPSAnOyc7CiAgICAgICAgICAgICAgICBhQ2VsbFJhbmdlcyArPSBhQ3VyUmFuZ2U7CgogICAgICAgICAgICAgICAgLy8gY2xlYXIgYWxyZWFkeSBmb3VuZCBzdWItcmFuZ2UgZnJvbSBtYXAKICAgICAgICAgICAgICAgIGZvciAoc2FsX0ludDMyIG5Sb3dJbmRleDIgPSAwOyAgblJvd0luZGV4MiA8IG5Sb3dTdWJMZW47ICArK25Sb3dJbmRleDIpCiAgICAgICAgICAgICAgICAgICAgZm9yIChzYWxfSW50MzIgbkNvbHVtbkluZGV4MiA9IDA7ICBuQ29sdW1uSW5kZXgyIDwgbkNvbFN1YkxlbjsgICsrbkNvbHVtbkluZGV4MikKICAgICAgICAgICAgICAgICAgICAgICAgYU1hcFtpICsgblJvd0luZGV4Ml1bayArIG5Db2x1bW5JbmRleDJdID0gJ1wwJzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIC8vIHRvIGJlIG5pY2UgdG8gdGhlIHVzZXIgd2Ugbm93IHNvcnQgdGhlIGNlbGwgcmFuZ2VzIGFjY29yZGluZyB0bwogICAgLy8gcm93cyBvciBjb2x1bW5zIGRlcGVuZGluZyBvbiB0aGUgZGlyZWN0aW9uIHVzZWQgaW4gdGhlIGRhdGEgc291cmNlCiAgICB1bm86OlNlcXVlbmNlPCBPVVN0cmluZyA+IGFTb3J0ZWRSYW5nZXM7CiAgICBHZXRTdWJyYW5nZXMoIGFDZWxsUmFuZ2VzLCBhU29ydGVkUmFuZ2VzLCBzYWxfRmFsc2UgLypzdWIgcmFuZ2VzIHNob3VsZCBhbHJlYWR5IGJlIG5vcm1hbGl6ZWQqLyApOwogICAgU29ydFN1YnJhbmdlcyggYVNvcnRlZFJhbmdlcywgKG5EdGFTcmNJc0NvbHVtbnMgPT0gMSkgKTsKICAgIHNhbF9JbnQzMiBuU29ydGVkUmFuZ2VzID0gYVNvcnRlZFJhbmdlcy5nZXRMZW5ndGgoKTsKICAgIGNvbnN0IE9VU3RyaW5nICpwU29ydGVkUmFuZ2VzID0gYVNvcnRlZFJhbmdlcy5nZXRDb25zdEFycmF5KCk7CiAgICBPVVN0cmluZyBhU29ydGVkQ2VsbFJhbmdlczsKICAgIGZvciAoc2FsX0ludDMyIGkgPSAwOyAgaSA8IG5Tb3J0ZWRSYW5nZXM7ICArK2kpCiAgICB7CiAgICAgICAgaWYgKGFTb3J0ZWRDZWxsUmFuZ2VzLmdldExlbmd0aCgpKQogICAgICAgICAgICBhU29ydGVkQ2VsbFJhbmdlcyArPSBPVVN0cmluZzo6dmFsdWVPZiggKHNhbF9Vbmljb2RlKSAnOycpOwogICAgICAgIGFTb3J0ZWRDZWxsUmFuZ2VzICs9IHBTb3J0ZWRSYW5nZXNbaV07CiAgICB9CgoKICAgIC8vIGJ1aWxkIHZhbHVlIGZvciAnU2VxdWVuY2VNYXBwaW5nJwogICAgLy8KICAgIHVubzo6U2VxdWVuY2U8IHNhbF9JbnQzMiA+IGFTb3J0ZWRNYXBwaW5nKCBhU2VxdWVuY2VNYXBwaW5nICk7CiAgICBzYWxfSW50MzIgKnBTb3J0ZWRNYXBwaW5nID0gYVNvcnRlZE1hcHBpbmcuZ2V0QXJyYXkoKTsKICAgIHN0ZDo6c29ydCggcFNvcnRlZE1hcHBpbmcsIHBTb3J0ZWRNYXBwaW5nICsgYVNvcnRlZE1hcHBpbmcuZ2V0TGVuZ3RoKCkgKTsKICAgIERCR19BU1NFUlQoIGFTb3J0ZWRNYXBwaW5nLmdldExlbmd0aCgpID09IG5OdW1EU19MRFMsICJ1bmV4cGVjdGVkIHNpemUgb2Ygc2VxdWVuY2UiICk7CglzYWxfQm9vbCBiTmVlZFNlcXVlbmNlTWFwcGluZyA9IHNhbF9GYWxzZTsKICAgIGZvciAoc2FsX0ludDMyIGkgPSAwOyAgaSA8IG5OdW1EU19MRFM7ICArK2kpCiAgICB7CiAgICAgICAgc2FsX0ludDMyICpwSXQgPSBzdGQ6OmZpbmQoIHBTb3J0ZWRNYXBwaW5nLCBwU29ydGVkTWFwcGluZyArIG5OdW1EU19MRFMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTZXF1ZW5jZU1hcHBpbmdbaV0gKTsKICAgICAgICBEQkdfQVNTRVJUKCBwSXQsICJpbmRleCBub3QgZm91bmQiICk7CiAgICAgICAgaWYgKCFwSXQpCiAgICAgICAgICAgIHJldHVybiBhUmVzdWx0OyAvLyBmYWlsZWQgLT4gcmV0dXJuIGVtcHR5IHByb3BlcnR5IHNlcXVlbmNlCiAgICAgICAgcFNlcXVlbmNlTWFwcGluZ1tpXSA9IHBJdCAtIHBTb3J0ZWRNYXBwaW5nOwoJCQoJCWlmIChpICE9IHBTZXF1ZW5jZU1hcHBpbmdbaV0pCgkJCWJOZWVkU2VxdWVuY2VNYXBwaW5nID0gc2FsX1RydWU7CiAgICB9CgoJLy8gY2hlY2sgaWYgJ1NlcXVlbmNlTWFwcGluZycgaXMgYWN0dWFsbHkgbm90IHJlcXVpcmVkLi4uCgkvLyAoZG9uJ3Qgd3JpdGUgdW5uZWNlc3NhcnkgcHJvcGVydGllcyB0byB0aGUgWE1MIGZpbGUpCglpZiAoIWJOZWVkU2VxdWVuY2VNYXBwaW5nKQoJCWFTZXF1ZW5jZU1hcHBpbmcucmVhbGxvYygwKTsKCgojaWZkZWYgVExfTk9UX1VTRUQgIC8vIGluIHRoZSBlbmQgY2hhcnQyIGRpZCBub3Qgd2FudCB0byBoYXZlIHRoZSBzZXF1ZW5jZSBtaW5pbWl6ZWQKICAgIC8vIHRyeSB0byBzaG9ydGVuIHRoZSAnU2VxdWVuY2VNYXBwaW5nJyBhcyBtdWNoIGFzIHBvc3NpYmxlCiAgICBzYWxfSW50MzIgazsKICAgIGZvciAoayA9IG5OdW1EU19MRFMgLSAxOyAgayA+PSAwOyAgLS1rKQogICAgewogICAgICAgIGlmIChwU2VxdWVuY2VNYXBwaW5nW2tdICE9IGspCiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgYVNlcXVlbmNlTWFwcGluZy5yZWFsbG9jKCBrICsgMSApOwojZW5kaWYKCgogICAgLy8KICAgIC8vIGJ1aWxkIHJlc3VsdGluZyBwcm9wZXJ0aWVzCiAgICAvLwogICAgREJHX0FTU0VSVChuTGFiZWxTZXFMZW4gPj0gMCB8fCBuTGFiZWxTZXFMZW4gPT0gLTIgLypub3QgdXNlZCovLAogICAgICAgICAgICAidW5leHBlY3RlZCB2YWx1ZSBmb3IgJ25MYWJlbFNlcUxlbiciICk7CiAgICBzYWxfQm9vbCBiRmlyc3RDZWxsSXNMYWJlbCA9IHNhbF9GYWxzZTsgICAgIC8vIGRlZmF1bHQgdmFsdWUgaWYgJ25MYWJlbFNlcUxlbicgY291bGQgbm90IHByb3Blcmx5IGRldGVybWluZWQKICAgIGlmIChuTGFiZWxTZXFMZW4gPiAwKSAvLyA9PSAwIG1lYW5zIG5vIGxhYmVsIHNlcXVlbmNlIGluIHVzZQogICAgICAgIGJGaXJzdENlbGxJc0xhYmVsID0gc2FsX1RydWU7CgkvLwogICAgREJHX0FTU0VSVCggYVNvcnRlZENlbGxSYW5nZXMuZ2V0TGVuZ3RoKCksICJDZWxsUmFuZ2VSZXByZXNlbnRhdGlvbiBtaXNzaW5nIiApOwogICAgT1VTdHJpbmcgYUJyb2tlbkNlbGxSYW5nZUZvckV4cG9ydCggR2V0QnJva2VuQ2VsbFJhbmdlRm9yRXhwb3J0KCBhU29ydGVkQ2VsbFJhbmdlcyApICk7CgkvLwogICAgYVJlc3VsdC5yZWFsbG9jKDUpOwogICAgc2FsX0ludDMyIG5Qcm9wcyA9IDA7CiAgICBhUmVzdWx0W25Qcm9wcyAgXS5OYW1lID0gQzJVKCJGaXJzdENlbGxBc0xhYmVsIik7CiAgICBhUmVzdWx0W25Qcm9wcysrXS5WYWx1ZSA8PD0gYkZpcnN0Q2VsbElzTGFiZWw7CiAgICBhUmVzdWx0W25Qcm9wcyAgXS5OYW1lID0gQzJVKCJDZWxsUmFuZ2VSZXByZXNlbnRhdGlvbiIpOwogICAgYVJlc3VsdFtuUHJvcHMrK10uVmFsdWUgPDw9IGFTb3J0ZWRDZWxsUmFuZ2VzOwogICAgaWYgKDAgIT0gYUJyb2tlbkNlbGxSYW5nZUZvckV4cG9ydC5nZXRMZW5ndGgoKSkKICAgIHsKICAgICAgICBhUmVzdWx0W25Qcm9wcyAgXS5OYW1lID0gQzJVKCJCcm9rZW5DZWxsUmFuZ2VGb3JFeHBvcnQiKTsKICAgICAgICBhUmVzdWx0W25Qcm9wcysrXS5WYWx1ZSA8PD0gYUJyb2tlbkNlbGxSYW5nZUZvckV4cG9ydDsKICAgIH0KCWlmIChuRHRhU3JjSXNDb2x1bW5zID09IDAgfHwgbkR0YVNyY0lzQ29sdW1ucyA9PSAxKQoJewoJCWNoYXJ0OjpDaGFydERhdGFSb3dTb3VyY2UgZURhdGFSb3dTb3VyY2UgPSAobkR0YVNyY0lzQ29sdW1ucyA9PSAxKSA/CgkJCQkJY2hhcnQ6OkNoYXJ0RGF0YVJvd1NvdXJjZV9DT0xVTU5TIDogY2hhcnQ6OkNoYXJ0RGF0YVJvd1NvdXJjZV9ST1dTOwoJCWFSZXN1bHRbblByb3BzICBdLk5hbWUgPSBDMlUoIkRhdGFSb3dTb3VyY2UiKTsKCQlhUmVzdWx0W25Qcm9wcysrXS5WYWx1ZSA8PD0gZURhdGFSb3dTb3VyY2U7CgoJCWlmIChhU2VxdWVuY2VNYXBwaW5nLmdldExlbmd0aCgpICE9IDApCgkJewoJCQlhUmVzdWx0W25Qcm9wcyAgXS5OYW1lID0gQzJVKCJTZXF1ZW5jZU1hcHBpbmciKTsKCQkJYVJlc3VsdFtuUHJvcHMrK10uVmFsdWUgPDw9IGFTZXF1ZW5jZU1hcHBpbmc7CgkJfQoJfQoJYVJlc3VsdC5yZWFsbG9jKCBuUHJvcHMgKTsKCiAgICByZXR1cm4gYVJlc3VsdDsKfQoKdW5vOjpSZWZlcmVuY2U8IGNoYXJ0Mjo6ZGF0YTo6WERhdGFTZXF1ZW5jZSA+IFN3Q2hhcnREYXRhUHJvdmlkZXI6OkltcGxfY3JlYXRlRGF0YVNlcXVlbmNlQnlSYW5nZVJlcHJlc2VudGF0aW9uKAogICAgICAgIGNvbnN0IE9VU3RyaW5nJiByUmFuZ2VSZXByZXNlbnRhdGlvbiwgc2FsX0Jvb2wgYlRlc3RPbmx5ICkKICAgIHRocm93IChsYW5nOjpJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgaWYgKGJEaXNwb3NlZCkKICAgICAgICB0aHJvdyBsYW5nOjpEaXNwb3NlZEV4Y2VwdGlvbigpOwoKICAgIFN3RnJtRm10ICAgICpwVGJsRm10ICAgID0gMDsgICAgLy8gcG9pbnRlciB0byB0YWJsZSBmb3JtYXQKICAgIFN3VW5vQ3JzciAgICpwVW5vQ3JzciAgID0gMDsgICAgLy8gcG9pbnRlciB0byBuZXcgY3JlYXRlZCBjdXJzb3Igc3Bhbm5pbmcgdGhlIGNlbGwgcmFuZ2UKICAgIEdldEZvcm1hdEFuZENyZWF0ZUN1cnNvckZyb21SYW5nZVJlcCggcERvYywgclJhbmdlUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwVGJsRm10LCAmcFVub0Nyc3IgKTsKICAgIGlmICghcFRibEZtdCB8fCAhcFVub0Nyc3IpCiAgICAgICAgdGhyb3cgbGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CgogICAgLy8gY2hlY2sgdGhhdCBjdXJzb3JzIHBvaW50IGFuZCBtYXJrIGFyZSBpbiBhIHNpbmdsZSByb3cgb3IgY29sdW1uLgogICAgU3RyaW5nIGFDZWxsUmFuZ2UoIEdldENlbGxSYW5nZU5hbWUoICpwVGJsRm10LCAqcFVub0Nyc3IgKSApOwogICAgU3dSYW5nZURlc2NyaXB0b3IgYURlc2M7CiAgICBGaWxsUmFuZ2VEZXNjcmlwdG9yKCBhRGVzYywgYUNlbGxSYW5nZSApOwogICAgaWYgKGFEZXNjLm5Ub3AgIT0gYURlc2MubkJvdHRvbSAgJiYgIGFEZXNjLm5MZWZ0ICE9IGFEZXNjLm5SaWdodCkKICAgICAgICB0aHJvdyBsYW5nOjpJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCiAgICBEQkdfQVNTRVJUKCBwVGJsRm10ICYmIHBVbm9DcnNyLCAidGFibGUgZm9ybWF0IG9yIGN1cnNvciBtaXNzaW5nIiApOwogICAgdW5vOjpSZWZlcmVuY2U8IGNoYXJ0Mjo6ZGF0YTo6WERhdGFTZXF1ZW5jZSA+IHhEYXRhU2VxOwogICAgaWYgKCFiVGVzdE9ubHkpCiAgICAgICAgeERhdGFTZXEgPSBuZXcgU3dDaGFydERhdGFTZXF1ZW5jZSggKnRoaXMsICpwVGJsRm10LCBwVW5vQ3JzciApOwoKICAgIHJldHVybiB4RGF0YVNlcTsKfQoKc2FsX0Jvb2wgU0FMX0NBTEwgU3dDaGFydERhdGFQcm92aWRlcjo6Y3JlYXRlRGF0YVNlcXVlbmNlQnlSYW5nZVJlcHJlc2VudGF0aW9uUG9zc2libGUoCiAgICAgICAgY29uc3QgT1VTdHJpbmcmIHJSYW5nZVJlcHJlc2VudGF0aW9uICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIHZvczo6T0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwoKICAgIHNhbF9Cb29sIGJQb3NzaWJsZSA9IHNhbF9UcnVlOwogICAgdHJ5CiAgICB7CiAgICAgICAgSW1wbF9jcmVhdGVEYXRhU2VxdWVuY2VCeVJhbmdlUmVwcmVzZW50YXRpb24oIHJSYW5nZVJlcHJlc2VudGF0aW9uLCBzYWxfVHJ1ZSApOwogICAgfQogICAgY2F0Y2ggKGxhbmc6OklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAmKQogICAgewogICAgICAgIGJQb3NzaWJsZSA9IHNhbF9GYWxzZTsKICAgIH0KCiAgICByZXR1cm4gYlBvc3NpYmxlOwp9Cgp1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYRGF0YVNlcXVlbmNlID4gU0FMX0NBTEwgU3dDaGFydERhdGFQcm92aWRlcjo6Y3JlYXRlRGF0YVNlcXVlbmNlQnlSYW5nZVJlcHJlc2VudGF0aW9uKAogICAgICAgIGNvbnN0IE9VU3RyaW5nJiByUmFuZ2VSZXByZXNlbnRhdGlvbiApCiAgICB0aHJvdyAobGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCB1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIHZvczo6T0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwogICAgcmV0dXJuIEltcGxfY3JlYXRlRGF0YVNlcXVlbmNlQnlSYW5nZVJlcHJlc2VudGF0aW9uKCByUmFuZ2VSZXByZXNlbnRhdGlvbiApOwp9CgoKdW5vOjpSZWZlcmVuY2U8IHNoZWV0OjpYUmFuZ2VTZWxlY3Rpb24gPiBTQUxfQ0FMTCBTd0NoYXJ0RGF0YVByb3ZpZGVyOjpnZXRSYW5nZVNlbGVjdGlvbiggICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIC8vIG5vdGU6IGl0IGlzIG5vIGVycm9yIHRvIHJldHVybiBub3RoaW5nIGhlcmUKICAgIHJldHVybiB1bm86OlJlZmVyZW5jZTwgc2hlZXQ6OlhSYW5nZVNlbGVjdGlvbiA+KCk7Cn0KCgp2b2lkIFNBTF9DQUxMIFN3Q2hhcnREYXRhUHJvdmlkZXI6OmRpc3Bvc2UoICApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICBzYWxfQm9vbCBiTXVzdERpc3Bvc2UoIHNhbF9GYWxzZSApOwoJewoJCW9zbDo6TXV0ZXhHdWFyZCAgYUd1YXJkKCBHZXRDaGFydE11dGV4KCkgKTsKICAgICAgICBiTXVzdERpc3Bvc2UgPSAhYkRpc3Bvc2VkOwoJCWlmICghYkRpc3Bvc2VkKQoJCQliRGlzcG9zZWQgPSBzYWxfVHJ1ZTsKCX0KICAgIGlmIChiTXVzdERpc3Bvc2UpCiAgICB7CiAgICAgICAgLy8gZGlzcG9zZSBhbGwgZGF0YS1zZXF1ZW5jZXMKICAgICAgICBNYXBfU2V0X0RhdGFTZXF1ZW5jZVJlZl90OjppdGVyYXRvciBhSXQoIGFEYXRhU2VxdWVuY2VzLmJlZ2luKCkgKTsKICAgICAgICB3aGlsZSAoYUl0ICE9IGFEYXRhU2VxdWVuY2VzLmVuZCgpKQoJCXsKICAgICAgICAgICAgRGlzcG9zZUFsbERhdGFTZXF1ZW5jZXMoICgqYUl0KS5maXJzdCApOwoJCQkrK2FJdDsKCQl9CgkJLy8gcmVsZWFzZSBhbGwgcmVmZXJlbmNlcyB0byBkYXRhLXNlcXVlbmNlcwoJCWFEYXRhU2VxdWVuY2VzLmNsZWFyKCk7CgoJCS8vIHJlcXVpcmUgbGlzdGVuZXJzIHRvIHJlbGVhc2UgcmVmZXJlbmNlcyB0byB0aGlzIG9iamVjdAogICAgICAgIGxhbmc6OkV2ZW50T2JqZWN0IGFFdnRPYmooIGR5bmFtaWNfY2FzdDwgY2hhcnQyOjpkYXRhOjpYRGF0YVNlcXVlbmNlICogPih0aGlzKSApOwogICAgICAgIGFFdnRMaXN0ZW5lcnMuZGlzcG9zZUFuZENsZWFyKCBhRXZ0T2JqICk7CiAgICB9Cn0KCgp2b2lkIFNBTF9DQUxMIFN3Q2hhcnREYXRhUHJvdmlkZXI6OmFkZEV2ZW50TGlzdGVuZXIoCiAgICAgICAgY29uc3QgdW5vOjpSZWZlcmVuY2U8IGxhbmc6OlhFdmVudExpc3RlbmVyID4mIHJ4TGlzdGVuZXIgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgb3NsOjpNdXRleEd1YXJkICBhR3VhcmQoIEdldENoYXJ0TXV0ZXgoKSApOwogICAgaWYgKCFiRGlzcG9zZWQgJiYgcnhMaXN0ZW5lci5pcygpKQogICAgICAgIGFFdnRMaXN0ZW5lcnMuYWRkSW50ZXJmYWNlKCByeExpc3RlbmVyICk7Cn0KCgp2b2lkIFNBTF9DQUxMIFN3Q2hhcnREYXRhUHJvdmlkZXI6OnJlbW92ZUV2ZW50TGlzdGVuZXIoCiAgICAgICAgY29uc3QgdW5vOjpSZWZlcmVuY2U8IGxhbmc6OlhFdmVudExpc3RlbmVyID4mIHJ4TGlzdGVuZXIgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgb3NsOjpNdXRleEd1YXJkICBhR3VhcmQoIEdldENoYXJ0TXV0ZXgoKSApOwogICAgaWYgKCFiRGlzcG9zZWQgJiYgcnhMaXN0ZW5lci5pcygpKQogICAgICAgIGFFdnRMaXN0ZW5lcnMucmVtb3ZlSW50ZXJmYWNlKCByeExpc3RlbmVyICk7Cn0KCgoKT1VTdHJpbmcgU0FMX0NBTEwgU3dDaGFydERhdGFQcm92aWRlcjo6Z2V0SW1wbGVtZW50YXRpb25OYW1lKCAgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgcmV0dXJuIEMyVSgiU3dDaGFydERhdGFQcm92aWRlciIpOwp9CgoKc2FsX0Jvb2wgU0FMX0NBTEwgU3dDaGFydERhdGFQcm92aWRlcjo6c3VwcG9ydHNTZXJ2aWNlKAogICAgICAgIGNvbnN0IE9VU3RyaW5nJiByU2VydmljZU5hbWUgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgdm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CiAgICByZXR1cm4gclNlcnZpY2VOYW1lLmVxdWFsc0FzY2lpKCBTTl9EQVRBX1BST1ZJREVSICk7Cn0KCgp1bm86OlNlcXVlbmNlPCBPVVN0cmluZyA+IFNBTF9DQUxMIFN3Q2hhcnREYXRhUHJvdmlkZXI6OmdldFN1cHBvcnRlZFNlcnZpY2VOYW1lcyggICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIHZvczo6T0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwogICAgdW5vOjpTZXF1ZW5jZTwgT1VTdHJpbmcgPiBhUmVzKDEpOwogICAgYVJlcy5nZXRBcnJheSgpWzBdID0gQzJVKCBTTl9EQVRBX1BST1ZJREVSICk7CiAgICByZXR1cm4gYVJlczsKfQoKCnZvaWQgU3dDaGFydERhdGFQcm92aWRlcjo6TW9kaWZ5KCBjb25zdCBTZnhQb29sSXRlbSogcE9sZCwgY29uc3QgU2Z4UG9vbEl0ZW0gKnBOZXcpCnsKICAgIC8vIGFjdHVhbGx5IHRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIHN1cGVyZmx1b3VzIChuZWVkIHRvIGNoZWNrIGxhdGVyKQogICAgQ2xpZW50TW9kaWZ5KHRoaXMsIHBPbGQsIHBOZXcgKTsKfQoKCnZvaWQgU3dDaGFydERhdGFQcm92aWRlcjo6QWRkRGF0YVNlcXVlbmNlKCBjb25zdCBTd1RhYmxlICZyVGFibGUsIHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPiAmcnhEYXRhU2VxdWVuY2UgKQp7CiAgICBhRGF0YVNlcXVlbmNlc1sgJnJUYWJsZSBdLmluc2VydCggcnhEYXRhU2VxdWVuY2UgKTsKfQoKCnZvaWQgU3dDaGFydERhdGFQcm92aWRlcjo6UmVtb3ZlRGF0YVNlcXVlbmNlKCBjb25zdCBTd1RhYmxlICZyVGFibGUsIHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPiAmcnhEYXRhU2VxdWVuY2UgKQp7CiAgICBhRGF0YVNlcXVlbmNlc1sgJnJUYWJsZSBdLmVyYXNlKCByeERhdGFTZXF1ZW5jZSApOwp9CgoKdm9pZCBTd0NoYXJ0RGF0YVByb3ZpZGVyOjpJbnZhbGlkYXRlVGFibGUoIGNvbnN0IFN3VGFibGUgKnBUYWJsZSApCnsKICAgIERCR19BU1NFUlQoIHBUYWJsZSwgInRhYmxlIHBvaW50ZXIgaXMgTlVMTCIgKTsKICAgIGlmIChwVGFibGUpCiAgICB7CgkJaWYgKCFiRGlzcG9zZWQpCgkgICAgICAgcFRhYmxlLT5HZXRGcm1GbXQoKS0+R2V0RG9jKCktPkdldENoYXJ0Q29udHJvbGxlckhlbHBlcigpLlN0YXJ0T3JDb250aW51ZUxvY2tpbmcoKTsKCgkJY29uc3QgU2V0X0RhdGFTZXF1ZW5jZVJlZl90ICZyU2V0ID0gYURhdGFTZXF1ZW5jZXNbIHBUYWJsZSBdOwogICAgICAgIFNldF9EYXRhU2VxdWVuY2VSZWZfdDo6Y29uc3RfaXRlcmF0b3IgYUl0KCByU2V0LmJlZ2luKCkgKTsKICAgICAgICB3aGlsZSAoYUl0ICE9IHJTZXQuZW5kKCkpCiAgICAgICAgewovLyAgICAgICAgICAgIHVubzo6UmVmZXJlbmNlPCB1dGlsOjpYTW9kaWZpYWJsZSA+IHhSZWYoIHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPigqYUl0KSwgdW5vOjpVTk9fUVVFUlkgKTsKICAgICAgICAgICAgdW5vOjpSZWZlcmVuY2U8IGNoYXJ0Mjo6ZGF0YTo6WERhdGFTZXF1ZW5jZSA+IHhUZW1wKCphSXQpOyAgLy8gdGVtcG9yYXJ5IG5lZWRlZCBmb3IgZysrIDMuMy41CiAgICAgICAgICAgIHVubzo6UmVmZXJlbmNlPCB1dGlsOjpYTW9kaWZpYWJsZSA+IHhSZWYoIHhUZW1wLCB1bm86OlVOT19RVUVSWSApOwogICAgICAgICAgICBpZiAoeFJlZi5pcygpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBtYXJrIHRoZSBzZXF1ZW5jZSBhcyAnZGlydHknIGFuZCBub3RpZnkgbGlzdGVuZXJzCiAgICAgICAgICAgICAgICB4UmVmLT5zZXRNb2RpZmllZCggc2FsX1RydWUgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICArK2FJdDsKICAgICAgICB9CiAgICB9Cn0KCgpzYWxfQm9vbCBTd0NoYXJ0RGF0YVByb3ZpZGVyOjpEZWxldGVCb3goIGNvbnN0IFN3VGFibGUgKnBUYWJsZSwgY29uc3QgU3dUYWJsZUJveCAmckJveCApCnsKICAgIHNhbF9Cb29sIGJSZXMgPSBzYWxfRmFsc2U7CiAgICBEQkdfQVNTRVJUKCBwVGFibGUsICJ0YWJsZSBwb2ludGVyIGlzIE5VTEwiICk7CiAgICBpZiAocFRhYmxlKQogICAgewoJCWlmICghYkRpc3Bvc2VkKQoJICAgICAgICBwVGFibGUtPkdldEZybUZtdCgpLT5HZXREb2MoKS0+R2V0Q2hhcnRDb250cm9sbGVySGVscGVyKCkuU3RhcnRPckNvbnRpbnVlTG9ja2luZygpOwoKICAgICAgICBTZXRfRGF0YVNlcXVlbmNlUmVmX3QgJnJTZXQgPSBhRGF0YVNlcXVlbmNlc1sgcFRhYmxlIF07CgogICAgICAgIC8vIGl0ZXJhdGUgb3ZlciBhbGwgZGF0YS1zZXF1ZW5jZXMgZm9yIHRoYXQgdGFibGUuLi4KICAgICAgICBTZXRfRGF0YVNlcXVlbmNlUmVmX3Q6Oml0ZXJhdG9yIGFJdCggclNldC5iZWdpbigpICk7CiAgICAgICAgU2V0X0RhdGFTZXF1ZW5jZVJlZl90OjppdGVyYXRvciBhRW5kSXQoIHJTZXQuZW5kKCkgKTsKICAgICAgICBTZXRfRGF0YVNlcXVlbmNlUmVmX3Q6Oml0ZXJhdG9yIGFEZWxJdDsgICAgIC8vIGl0ZXJhdG9yIHVzZWQgZm9yIGRlbGV0aW9uIHdoZW4gYXBwcm9wcmlhdGUKICAgICAgICB3aGlsZSAoYUl0ICE9IGFFbmRJdCkKICAgICAgICB7CgkJCVN3Q2hhcnREYXRhU2VxdWVuY2UgKnBEYXRhU2VxID0gMDsKICAgICAgICAgICAgc2FsX0Jvb2wgYk5vd0VtcHR5ID0gc2FsX0ZhbHNlOwogICAgICAgICAgICBzYWxfQm9vbCBiU2VxRGlzcG9zZWQgPSBzYWxfRmFsc2U7CgogICAgICAgICAgICAvLyBjaGVjayBpZiB3ZWFrIHJlZmVyZW5jZSBpcyBzdGlsbCB2YWxpZC4uLgovLyAgICAgICAgICAgIHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPiB4UmVmKCB1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYRGF0YVNlcXVlbmNlPigqYUl0KSwgdW5vOjpVTk9fUVVFUlkgKTsKICAgICAgICAgICAgdW5vOjpSZWZlcmVuY2U8IGNoYXJ0Mjo6ZGF0YTo6WERhdGFTZXF1ZW5jZSA+IHhUZW1wKCphSXQpOyAgLy8gdGVtcG9yYXJ5IG5lZWRlZCBmb3IgZysrIDMuMy41CiAgICAgICAgICAgIHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPiB4UmVmKCB4VGVtcCwgdW5vOjpVTk9fUVVFUlkgKTsKICAgICAgICAgICAgaWYgKHhSZWYuaXMoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gdGhlbiBkZWxldGUgdGhhdCB0YWJsZSBib3ggKGNoZWNrIGlmIGltcGxlbWVudGF0aW9uIGN1cnNvciBuZWVkcyB0byBiZSBhZGp1c3RlZCkKICAgICAgICAgICAgICAgIHBEYXRhU2VxID0gc3RhdGljX2Nhc3Q8IFN3Q2hhcnREYXRhU2VxdWVuY2UgKiA+KCB4UmVmLmdldCgpICk7CiAgICAgICAgICAgICAgICBpZiAocERhdGFTZXEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgICAgICAgICAgewojaWYgT1NMX0RFQlVHX0xFVkVMID4gMQogICAgICAgICAgICAgICAgICAgIE9VU3RyaW5nIGFSYW5nZVN0ciggcERhdGFTZXEtPmdldFNvdXJjZVJhbmdlUmVwcmVzZW50YXRpb24oKSApOwojZW5kaWYKICAgICAgICAgICAgICAgICAgICBiTm93RW1wdHkgPSBwRGF0YVNlcS0+RGVsZXRlQm94KCByQm94ICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNhdGNoIChsYW5nOjpEaXNwb3NlZEV4Y2VwdGlvbiYpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBiTm93RW1wdHkgPSBzYWxfVHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgYlNlcURpc3Bvc2VkID0gc2FsX1RydWU7CiAgICAgICAgICAgICAgICAgICAgfQoJCQkJCQogICAgICAgICAgICAgICAgICAgIGlmIChiTm93RW1wdHkpCiAgICAgICAgICAgICAgICAgICAgICAgIGFEZWxJdCA9IGFJdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICArK2FJdDsKCiAgICAgICAgICAgIGlmIChiTm93RW1wdHkpCgkJCXsKICAgICAgICAgICAgICAgIHJTZXQuZXJhc2UoIGFEZWxJdCApOwogICAgICAgICAgICAgICAgaWYgKHBEYXRhU2VxICYmICFiU2VxRGlzcG9zZWQpCiAgICAgICAgICAgICAgICAgICAgcERhdGFTZXEtPmRpc3Bvc2UoKTsgICAgLy8gdGhlIGN1cnJlbnQgd2F5IHRvIHRlbGwgY2hhcnQgdGhhdCBzdGguIGdvdCByZW1vdmVkCgkJCX0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gYlJlczsKfQoKCnZvaWQgU3dDaGFydERhdGFQcm92aWRlcjo6RGlzcG9zZUFsbERhdGFTZXF1ZW5jZXMoIGNvbnN0IFN3VGFibGUgKnBUYWJsZSApCnsKICAgIERCR19BU1NFUlQoIHBUYWJsZSwgInRhYmxlIHBvaW50ZXIgaXMgTlVMTCIgKTsKICAgIGlmIChwVGFibGUpCiAgICB7CgkJaWYgKCFiRGlzcG9zZWQpCgkJCXBUYWJsZS0+R2V0RnJtRm10KCktPkdldERvYygpLT5HZXRDaGFydENvbnRyb2xsZXJIZWxwZXIoKS5TdGFydE9yQ29udGludWVMb2NraW5nKCk7CgogICAgICAgIC8vISBtYWtlIGEgY29weSBvZiB0aGUgU1RMIGNvbnRhaW5lciEgCiAgICAgICAgLy8hIFRoaXMgaXMgbmVjZXNzYXJ5IHNpbmNlIGNhbGxpbmcgJ2Rpc3Bvc2UnIHdpbGwgaW1wbGljaXRseSByZW1vdmUgYW4gZWxlbWVudCAKICAgICAgICAvLyEgb2YgdGhlIG9yaWdpbmFsIGNvbnRhaW5lciwgYW5kIHRodXMgYW55IGl0ZXJhdG9yIGluIHRoZSBvcmlnaW5hbCBjb250YWluZXIKICAgICAgICAvLyEgd291bGQgYmVjb21lIGludmFsaWQuCiAgICAgICAgY29uc3QgU2V0X0RhdGFTZXF1ZW5jZVJlZl90IGFTZXQoIGFEYXRhU2VxdWVuY2VzWyBwVGFibGUgXSApOwoKICAgICAgICBTZXRfRGF0YVNlcXVlbmNlUmVmX3Q6OmNvbnN0X2l0ZXJhdG9yIGFJdCggYVNldC5iZWdpbigpICk7CiAgICAgICAgU2V0X0RhdGFTZXF1ZW5jZVJlZl90Ojpjb25zdF9pdGVyYXRvciBhRW5kSXQoIGFTZXQuZW5kKCkgKTsKICAgICAgICB3aGlsZSAoYUl0ICE9IGFFbmRJdCkKICAgICAgICB7Ci8vICAgICAgICAgICAgdW5vOjpSZWZlcmVuY2U8IGxhbmc6OlhDb21wb25lbnQgPiB4UmVmKCB1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYRGF0YVNlcXVlbmNlID4oKmFJdCksIHVubzo6VU5PX1FVRVJZICk7CiAgICAgICAgICAgIHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPiB4VGVtcCgqYUl0KTsgIC8vIHRlbXBvcmFyeSBuZWVkZWQgZm9yIGcrKyAzLjMuNQogICAgICAgICAgICB1bm86OlJlZmVyZW5jZTwgbGFuZzo6WENvbXBvbmVudCA+IHhSZWYoIHhUZW1wLCB1bm86OlVOT19RVUVSWSApOwogICAgICAgICAgICBpZiAoeFJlZi5pcygpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB4UmVmLT5kaXNwb3NlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKythSXQ7CiAgICAgICAgfQogICAgfQp9CgoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLyBTd0NoYXJ0RGF0YVByb3ZpZGVyOjpBZGRSb3dDb2xzIHRyaWVzIHRvIG5vdGlmeSBjaGFydHMgb2YgYWRkZWQgY29sdW1ucwovLyBvciByb3dzIGFuZCBleHRlbmRzIHRoZSB2YWx1ZSBzZXF1ZW5jZSByZXNwZWN0aXZlbHkgKGlmIHBvc3NpYmxlKS4KLy8gSWYgdGhvc2UgY2FuIGJlIGFkZGVkIHRvIHRoZSBlbmQgb2YgZXhpc3RpbmcgdmFsdWUgZGF0YS1zZXF1ZW5jZXMgdGhvc2UKLy8gc2VxdWVuY2VzIGdldCBtb2ZkaWZpZWQgYWNjb3JkaW5nbHkgYW5kIHdpbGwgc2VuZCBhIG1vZGlmaWNhdGlvbgovLyBub3RpZmljYXRpb24gKGNhbGxpbmcgJ3NldE1vZGlmaWVkJykuCi8vCi8vIFNpbmNlIHRoaXMgZnVuY3Rpb24gaXMgYSB3b3JrLWFyb3VuZCBmb3Igbm9uIGV4aXN0ZW50IFdyaXRlciBjb3JlIGZ1bmN0aW9uYWxpdHkKLy8gKG5vIGFyYml0cmFyeSBtdWx0aS1zZWxlY3Rpb24gaW4gdGFibGVzIHRoYXQgY2FuIGJlIHVzZWQgdG8gZGVmaW5lIGEKLy8gZGF0YS1zZXF1ZW5jZSkgdGhpcyBmdW5jdGlvbiB3aWxsIGJlIHNvbWV3aGF0IHVucmVsaWFibGUuCi8vIEZvciBleGFtcGxlIHdlIHdpbGwgb25seSB0cnkgdG8gYWRhcHQgdmFsdWUgc2VxdWVuY2VzLiBGb3IgdGhpcyB3ZSBhc3N1bWUKLy8gdGhhdCBhIHNlcXVlbmNlIG9mIGxlbmd0aCAxIGlzIGEgbGFiZWwgc2VxdWVuY2UgYW5kIHRob3NlIHdpdGggbGVuZ3RoID49IDIKLy8gd2UgcHJlc3VtZSB0byBiZSB2YWx1ZSBzZXF1ZW5jZXMuIEFsc28gbmV3IGNlbGxzIGNhbiBvbmx5IGJlIGFkZGVkIGluIHRoZQovLyBkaXJlY3Rpb24gdGhlIHZhbHVlIHNlcXVlbmNlIGlzIGFscmVhZHkgcG9pbnRpbmcgKHJvd3MgLyBjb2xzKSBhbmQgYXQgdGhlCi8vIHN0YXJ0IG9yIGVuZCBvZiB0aGUgdmFsdWVzIGRhdGEtc2VxdWVuY2UuCi8vIE5vdGhpbmcgbmVlZHMgdG8gYmUgZG9uZSBpZiB0aGUgbmV3IGNlbGxzIGFyZSBpbiBiZXR3ZWVuIHRoZSB0YWJsZSBjdXJzb3JzCi8vIHBvaW50IGFuZCBtYXJrIHNpbmNlIGRhdGEtc2VxdWVuY2UgYXJlIGNvbnNpZGVyZWQgdG8gY29uc2lzdCBvZiBhbGwgY2VsbHMKLy8gYmV0d2VlbiB0aG9zZS4KLy8gTmV3IHJvd3MvY29scyBuZWVkIHRvIGJlIGFkZGVkIGFscmVhZHkgdG8gdGhlIHRhYmxlIGJlZm9yZSBjYWxsaW5nCi8vIHRoaXMgZnVuY3Rpb24uCi8vCnZvaWQgU3dDaGFydERhdGFQcm92aWRlcjo6QWRkUm93Q29scygKICAgICAgICBjb25zdCBTd1RhYmxlICZyVGFibGUsCiAgICAgICAgY29uc3QgU3dTZWxCb3hlcyYgckJveGVzLAogICAgICAgIHNhbF91SW50MTYgbkxpbmVzLCBzYWxfQm9vbCBiQmVoaW5kICkKewoJaWYgKHJUYWJsZS5Jc1RibENvbXBsZXgoKSkKCQlyZXR1cm47CgoJY29uc3Qgc2FsX3VJbnQxNiBuQm94ZXMJCT0gckJveGVzLkNvdW50KCk7CiAgICBpZiAobkJveGVzIDwgMSB8fCBuTGluZXMgPCAxKQogICAgICAgIHJldHVybjsKCglTd1RhYmxlQm94KiBwRmlyc3RCb3gJPSAqKCByQm94ZXMuR2V0RGF0YSgpICsgMCApOwoJU3dUYWJsZUJveCogcExhc3RCb3gJPSAqKCByQm94ZXMuR2V0RGF0YSgpICsgbkJveGVzIC0gMSApOwoKICAgIHNhbF9JbnQzMiBuRmlyc3RDb2wgPSAtMSwgbkZpcnN0Um93ID0gLTEsIG5MYXN0Q29sID0gLTEsIG5MYXN0Um93ID0gLTE7CglpZiAocEZpcnN0Qm94ICYmIHBMYXN0Qm94KQoJewogICAgICAgIGxjbF9HZXRDZWxsUG9zaXRpb24oIHBGaXJzdEJveC0+R2V0TmFtZSgpLCBuRmlyc3RDb2wsIG5GaXJzdFJvdyAgKTsKICAgICAgICBsY2xfR2V0Q2VsbFBvc2l0aW9uKCBwTGFzdEJveC0+R2V0TmFtZSgpLCAgbkxhc3RDb2wsICBuTGFzdFJvdyApOwoKICAgICAgICBib29sIGJBZGRDb2xzID0gZmFsc2U7ICAvLyBkZWZhdWx0OyBhbHNvIHRvIGJlIHVzZWQgaWYgbkJveGVzID09IDEgOi0vCiAgICAgICAgaWYgKG5GaXJzdENvbCA9PSBuTGFzdENvbCAmJiBuRmlyc3RSb3cgIT0gbkxhc3RSb3cpCiAgICAgICAgICAgIGJBZGRDb2xzID0gdHJ1ZTsKICAgICAgICBpZiAobkZpcnN0Q29sID09IG5MYXN0Q29sIHx8IG5GaXJzdFJvdyA9PSBuTGFzdFJvdykKCQl7CgkJCS8vZ2V0IHJhbmdlIG9mIGluZGljZXMgaW4gY29sL3Jvd3MgZm9yIG5ldyBjZWxscwogICAgICAgICAgICBzYWxfSW50MzIgbkZpcnN0TmV3Q29sID0gbkZpcnN0Q29sOwogICAgICAgICAgICBzYWxfSW50MzIgbkxhc3ROZXdDb2wgID0gbkxhc3RDb2w7CiAgICAgICAgICAgIHNhbF9JbnQzMiBuRmlyc3ROZXdSb3cgPSBiQmVoaW5kID8gIG5GaXJzdFJvdyArIDEgOiBuRmlyc3RSb3cgLSBuTGluZXM7CiAgICAgICAgICAgIHNhbF9JbnQzMiBuTGFzdE5ld1JvdyAgPSBuRmlyc3ROZXdSb3cgLSAxICsgbkxpbmVzOwogICAgICAgICAgICBpZiAoYkFkZENvbHMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIERCR19BU1NFUlQoIG5GaXJzdENvbCA9PSBuTGFzdENvbCwgImNvbHVtbiBpbmRpY2VzIHNlZW0gYnJva2VuIiApOwogICAgICAgICAgICAgICAgbkZpcnN0TmV3Q29sID0gYkJlaGluZCA/ICBuRmlyc3RDb2wgKyAxIDogbkZpcnN0Q29sIC0gbkxpbmVzOwogICAgICAgICAgICAgICAgbkxhc3ROZXdDb2wgID0gbkZpcnN0TmV3Q29sIC0gMSArIG5MaW5lczsKICAgICAgICAgICAgICAgIG5GaXJzdE5ld1JvdyA9IG5GaXJzdFJvdzsKICAgICAgICAgICAgICAgIG5MYXN0TmV3Um93ICA9IG5MYXN0Um93OwogICAgICAgICAgICB9CgoJCQkvLyBpdGVyYXRlIG92ZXIgYWxsIGRhdGEtc2VxdWVuY2VzIGZvciB0aGUgdGFibGUKCQkJY29uc3QgU2V0X0RhdGFTZXF1ZW5jZVJlZl90ICZyU2V0ID0gYURhdGFTZXF1ZW5jZXNbICZyVGFibGUgXTsKCQkJU2V0X0RhdGFTZXF1ZW5jZVJlZl90Ojpjb25zdF9pdGVyYXRvciBhSXQoIHJTZXQuYmVnaW4oKSApOwoJCQl3aGlsZSAoYUl0ICE9IHJTZXQuZW5kKCkpCgkJCXsKLy8gICAgICAgICAgICAgICB1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYVGV4dHVhbERhdGFTZXF1ZW5jZSA+IHhSZWYoIHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPigqYUl0KSwgdW5vOjpVTk9fUVVFUlkgKTsKICAgICAgICAgICAgICAgIHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPiB4VGVtcCgqYUl0KTsgIC8vIHRlbXBvcmFyeSBuZWVkZWQgZm9yIGcrKyAzLjMuNQogICAgICAgICAgICAgICAgdW5vOjpSZWZlcmVuY2U8IGNoYXJ0Mjo6ZGF0YTo6WFRleHR1YWxEYXRhU2VxdWVuY2UgPiB4UmVmKCB4VGVtcCwgdW5vOjpVTk9fUVVFUlkgKTsKICAgICAgICAgICAgICAgIGlmICh4UmVmLmlzKCkpCgkJCQl7CgkJCQkJY29uc3Qgc2FsX0ludDMyIG5MZW4gPSB4UmVmLT5nZXRUZXh0dWFsRGF0YSgpLmdldExlbmd0aCgpOwoJCQkJCWlmIChuTGVuID4gMSkgLy8gdmFsdWUgZGF0YS1zZXF1ZW5jZSA/CgkJCQkJewoJCQkJCQlTd0NoYXJ0RGF0YVNlcXVlbmNlICpwRGF0YVNlcSA9IDA7CgkJCQkJCXVubzo6UmVmZXJlbmNlPCBsYW5nOjpYVW5vVHVubmVsID4geFR1bm5lbCggeFJlZiwgdW5vOjpVTk9fUVVFUlkgKTsKCQkJCQkJaWYoeFR1bm5lbC5pcygpKQoJCQkJCQl7CgkJCQkJCQlwRGF0YVNlcSA9IHJlaW50ZXJwcmV0X2Nhc3Q8IFN3Q2hhcnREYXRhU2VxdWVuY2UgKiA+KAoJCQkJCQkJCQlzYWw6OnN0YXRpY19pbnRfY2FzdDwgc2FsX0ludFB0ciA+KCB4VHVubmVsLT5nZXRTb21ldGhpbmcoIFN3Q2hhcnREYXRhU2VxdWVuY2U6OmdldFVub1R1bm5lbElkKCkgKSkpOwoKCQkJCQkJCWlmIChwRGF0YVNlcSkKCQkJCQkJCXsKCQkJCQkJCQlTd1JhbmdlRGVzY3JpcHRvciBhRGVzYzsKCQkJCQkJCQlwRGF0YVNlcS0+RmlsbFJhbmdlRGVzYyggYURlc2MgKTsKCgkJCQkJCQkJY2hhcnQ6OkNoYXJ0RGF0YVJvd1NvdXJjZSBlRFJTb3VyY2UgPSBjaGFydDo6Q2hhcnREYXRhUm93U291cmNlX0NPTFVNTlM7CgkJCQkJCQkJaWYgKGFEZXNjLm5Ub3AgPT0gYURlc2MubkJvdHRvbSAmJiBhRGVzYy5uTGVmdCAhPSBhRGVzYy5uUmlnaHQpCgkJCQkJCQkJCWVEUlNvdXJjZSA9IGNoYXJ0OjpDaGFydERhdGFSb3dTb3VyY2VfUk9XUzsKCgkJCQkJCQkJaWYgKCFiQWRkQ29scyAmJiBlRFJTb3VyY2UgPT0gY2hhcnQ6OkNoYXJ0RGF0YVJvd1NvdXJjZV9DT0xVTU5TKQoJCQkJCQkJCXsKCQkJCQkJCQkJLy8gYWRkIHJvd3M6IGV4dGVuZCBhZmZlY3RlZCBjb2x1bW5zIGJ5IG5ld2x5IGFkZGVkIHJvdyBjZWxscwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRGF0YVNlcS0+RXh0ZW5kVG8oIHRydWUsIG5GaXJzdE5ld1JvdywgbkxpbmVzICk7CgkJCQkJCQkJfQoJCQkJCQkJCWVsc2UgaWYgKGJBZGRDb2xzICYmIGVEUlNvdXJjZSA9PSBjaGFydDo6Q2hhcnREYXRhUm93U291cmNlX1JPV1MpCgkJCQkJCQkJewoJCQkJCQkJCQkvLyBhZGQgY29sczogZXh0ZW5kIGFmZmVjdGVkIHJvd3MgYnkgbmV3bHkgYWRkZWQgY29sdW1uIGNlbGxzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBEYXRhU2VxLT5FeHRlbmRUbyggZmFsc2UsIG5GaXJzdE5ld0NvbCwgbkxpbmVzICk7CgkJCQkJCQkJfQoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQkJKythSXQ7CgkJCX0KCgkJfQoJfQp9CgoKLy8gWFJhbmdlWE1MQ29udmVyc2lvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnJ0bDo6T1VTdHJpbmcgU0FMX0NBTEwgU3dDaGFydERhdGFQcm92aWRlcjo6Y29udmVydFJhbmdlVG9YTUwoIGNvbnN0IHJ0bDo6T1VTdHJpbmcmIHJSYW5nZVJlcHJlc2VudGF0aW9uICkKICAgIHRocm93ICggdW5vOjpSdW50aW1lRXhjZXB0aW9uLCBsYW5nOjpJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIGlmIChiRGlzcG9zZWQpCiAgICAgICAgdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCiAgICBTdHJpbmcgYVJlczsKICAgIFN0cmluZyBhUmFuZ2VSZXByZXNlbnRhdGlvbiggclJhbmdlUmVwcmVzZW50YXRpb24gKTsKCiAgICAvLyBtdWx0aXBsZSByYW5nZXMgYXJlIGRlbGltZXRlZCBieSBhICc7JyBsaWtlIGluCiAgICAvLyAiVGFibGUxLkExOkE0O1RhYmxlMS5DMjpDNSIgdGhlIHNhbWUgdGFibGUgbXVzdCBiZSB1c2VkIGluIGFsbCByYW5nZXMhCiAgICB4dWJfU3RyTGVuIG5OdW1SYW5nZXMgPSBhUmFuZ2VSZXByZXNlbnRhdGlvbi5HZXRUb2tlbkNvdW50KCAnOycgKTsKICAgIFN3VGFibGUqIHBGaXJzdEZvdW5kVGFibGUgPSAwOyAgLy8gdG8gY2hlY2sgdGhhdCBvbmx5IG9uZSB0YWJsZSB3aWxsIGJlIHVzZWQKICAgIGZvciAoc2FsX3VJbnQxNiBpID0gMDsgIGkgPCBuTnVtUmFuZ2VzOyAgKytpKQogICAgewogICAgICAgIFN0cmluZyBhUmFuZ2UoIGFSYW5nZVJlcHJlc2VudGF0aW9uLkdldFRva2VuKGksICc7JykgKTsKICAgICAgICBTd0ZybUZtdCAgICAqcFRibEZtdCAgPSAwOyAgICAgIC8vIHBvaW50ZXIgdG8gdGFibGUgZm9ybWF0CiAgICAgICAgLy8gQk06IEZvciB3aGF0IHNob3VsZCB0aGUgY2hlY2sgYmUgbmVjZXNzYXJ5PyBmb3IgI2k3OTAwOSMgaXQgaXMgcmVxdWlyZWQgdGhhdCBOTyBjaGVjayBpcyBkb25lCi8vICAgICAgICAgU3dVbm9DcnNyICAgKnBVbm9DcnNyID0gMDsgICAgICAvLyBoZXJlIHJlcXVpcmVkIHRvIGNoZWNrIGlmIHRoZSBjZWxscyBpbiB0aGUgcmFuZ2UgZG8gYWN0dWFsbHkgZXhpc3QKLy8gICAgICAgICBzdGQ6OmF1dG9fcHRyPCBTd1Vub0Nyc3IgPiBwQXV0byggcFVub0Nyc3IgKTsgIC8vIHRvIGVuZCBsaWZldGltZSBvZiBvYmplY3QgcG9pbnRlZCB0byBieSBwVW5vQ3JzcgogICAgICAgIEdldEZvcm1hdEFuZENyZWF0ZUN1cnNvckZyb21SYW5nZVJlcCggcERvYywgYVJhbmdlLCAmcFRibEZtdCwgTlVMTCApOwogICAgICAgIGlmICghcFRibEZtdCkKICAgICAgICAgICAgdGhyb3cgbGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7Ci8vICAgIGlmICghcFVub0Nyc3IpCi8vICAgICAgICB0aHJvdyB1bm86OlJ1bnRpbWVFeGNlcHRpb24oKTsKICAgICAgICBTd1RhYmxlKiBwVGFibGUgPSBTd1RhYmxlOjpGaW5kVGFibGUoIHBUYmxGbXQgKTsKICAgICAgICBpZiAgKHBUYWJsZS0+SXNUYmxDb21wbGV4KCkpCiAgICAgICAgICAgIHRocm93IHVubzo6UnVudGltZUV4Y2VwdGlvbigpOwoKICAgICAgICAvLyBjaGVjayB0aGF0IHRoZXJlIGlzIG9ubHkgb25lIHRhYmxlIHVzZWQgaW4gYWxsIHJhbmdlcwogICAgICAgIGlmICghcEZpcnN0Rm91bmRUYWJsZSkKICAgICAgICAgICAgcEZpcnN0Rm91bmRUYWJsZSA9IHBUYWJsZTsKICAgICAgICBpZiAocFRhYmxlICE9IHBGaXJzdEZvdW5kVGFibGUpCiAgICAgICAgICAgIHRocm93IGxhbmc6OklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwoKICAgICAgICBTdHJpbmcgYVRibE5hbWU7CiAgICAgICAgU3RyaW5nIGFTdGFydENlbGw7CiAgICAgICAgU3RyaW5nIGFFbmRDZWxsOwogICAgICAgIGlmICghR2V0VGFibGVBbmRDZWxsc0Zyb21SYW5nZVJlcCggYVJhbmdlLCBhVGJsTmFtZSwgYVN0YXJ0Q2VsbCwgYUVuZENlbGwgKSkKICAgICAgICAgICAgdGhyb3cgbGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CgogICAgICAgIHNhbF9JbnQzMiBuQ29sLCBuUm93OwogICAgICAgIGxjbF9HZXRDZWxsUG9zaXRpb24oIGFTdGFydENlbGwsIG5Db2wsIG5Sb3cgKTsKICAgICAgICBpZiAobkNvbCA8IDAgfHwgblJvdyA8IDApCiAgICAgICAgICAgIHRocm93IHVubzo6UnVudGltZUV4Y2VwdGlvbigpOwoKICAgICAgICAvLyEhIGZvbGxvd2luZyBvYmplY3RzL2Z1bmN0aW9ucyBhcmUgaW1wbGVtZW50ZWQgaW4gWE1MUmFuZ2VIZWxwZXIuP3h4CiAgICAgICAgLy8hISB3aGljaCBpcyBhIGNvcHkgb2YgdGhlIHJlc3BlY3RpdmUgZmlsZSBmcm9tIGNoYXJ0MiAhIQogICAgICAgIFhNTFJhbmdlSGVscGVyOjpDZWxsUmFuZ2UgYUNlbGxSYW5nZTsKICAgICAgICBhQ2VsbFJhbmdlLmFUYWJsZU5hbWUgPSBhVGJsTmFtZTsKICAgICAgICBhQ2VsbFJhbmdlLmFVcHBlckxlZnQubkNvbHVtbiAgID0gbkNvbDsKICAgICAgICBhQ2VsbFJhbmdlLmFVcHBlckxlZnQublJvdyAgICAgID0gblJvdzsKICAgICAgICBhQ2VsbFJhbmdlLmFVcHBlckxlZnQuYklzRW1wdHkgID0gZmFsc2U7CiAgICAgICAgaWYgKGFTdGFydENlbGwgIT0gYUVuZENlbGwgJiYgYUVuZENlbGwuTGVuKCkgIT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIGxjbF9HZXRDZWxsUG9zaXRpb24oIGFFbmRDZWxsLCBuQ29sLCBuUm93ICk7CiAgICAgICAgICAgIGlmIChuQ29sIDwgMCB8fCBuUm93IDwgMCkKICAgICAgICAgICAgICAgIHRocm93IHVubzo6UnVudGltZUV4Y2VwdGlvbigpOwoKICAgICAgICAgICAgYUNlbGxSYW5nZS5hTG93ZXJSaWdodC5uQ29sdW1uICAgPSBuQ29sOwogICAgICAgICAgICBhQ2VsbFJhbmdlLmFMb3dlclJpZ2h0Lm5Sb3cgICAgICA9IG5Sb3c7CiAgICAgICAgICAgIGFDZWxsUmFuZ2UuYUxvd2VyUmlnaHQuYklzRW1wdHkgID0gZmFsc2U7CiAgICAgICAgfQogICAgICAgIFN0cmluZyBhVG1wKCBYTUxSYW5nZUhlbHBlcjo6Z2V0WE1MU3RyaW5nRnJvbUNlbGxSYW5nZSggYUNlbGxSYW5nZSApICk7CiAgICAgICAgaWYgKGFSZXMuTGVuKCkpIC8vIGluIGNhc2Ugb2YgbXVsdGlwbGUgcmFuZ2VzIGFkZCBkZWxpbWV0ZXIKICAgICAgICAgICAgYVJlcy5BcHBlbmRBc2NpaSggIiAiICk7CiAgICAgICAgYVJlcyArPSBhVG1wOwogICAgfQoKICAgIHJldHVybiBhUmVzOwp9CgpydGw6Ok9VU3RyaW5nIFNBTF9DQUxMIFN3Q2hhcnREYXRhUHJvdmlkZXI6OmNvbnZlcnRSYW5nZUZyb21YTUwoIGNvbnN0IHJ0bDo6T1VTdHJpbmcmIHJYTUxSYW5nZSApCiAgICB0aHJvdyAoIHVubzo6UnVudGltZUV4Y2VwdGlvbiwgbGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICkKewogICAgdm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CiAgICBpZiAoYkRpc3Bvc2VkKQogICAgICAgIHRocm93IGxhbmc6OkRpc3Bvc2VkRXhjZXB0aW9uKCk7CgogICAgU3RyaW5nIGFSZXM7CiAgICBTdHJpbmcgYVhNTFJhbmdlKCByWE1MUmFuZ2UgKTsKCiAgICAvLyBtdWx0aXBsZSByYW5nZXMgYXJlIGRlbGltZXRlZCBieSBhICcgJyBsaWtlIGluCiAgICAvLyAiVGFibGUxLiRBJDE6LiRBJDQgVGFibGUxLiRDJDI6LiRDJDUiIHRoZSBzYW1lIHRhYmxlIG11c3QgYmUgdXNlZCBpbiBhbGwgcmFuZ2VzIQogICAgeHViX1N0ckxlbiBuTnVtUmFuZ2VzID0gYVhNTFJhbmdlLkdldFRva2VuQ291bnQoICcgJyApOwogICAgcnRsOjpPVVN0cmluZyBhRmlyc3RGb3VuZFRhYmxlOyAvLyB0byBjaGVjayB0aGF0IG9ubHkgb25lIHRhYmxlIHdpbGwgYmUgdXNlZAogICAgZm9yIChzYWxfdUludDE2IGkgPSAwOyAgaSA8IG5OdW1SYW5nZXM7ICArK2kpCiAgICB7CiAgICAgICAgU3RyaW5nIGFSYW5nZSggYVhNTFJhbmdlLkdldFRva2VuKGksICcgJykgKTsKCiAgICAgICAgLy8hISBmb2xsb3dpbmcgb2JqZWN0cyBhbmQgZnVuY3Rpb24gYXJlIGltcGxlbWVudGVkIGluIFhNTFJhbmdlSGVscGVyLj94eAogICAgICAgIC8vISEgd2hpY2ggaXMgYSBjb3B5IG9mIHRoZSByZXNwZWN0aXZlIGZpbGUgZnJvbSBjaGFydDIgISEKICAgICAgICBYTUxSYW5nZUhlbHBlcjo6Q2VsbFJhbmdlIGFDZWxsUmFuZ2UoIFhNTFJhbmdlSGVscGVyOjpnZXRDZWxsUmFuZ2VGcm9tWE1MU3RyaW5nKCBhUmFuZ2UgKSk7CgogICAgICAgIC8vIGNoZWNrIHRoYXQgdGhlcmUgaXMgb25seSBvbmUgdGFibGUgdXNlZCBpbiBhbGwgcmFuZ2VzCiAgICAgICAgaWYgKGFGaXJzdEZvdW5kVGFibGUuZ2V0TGVuZ3RoKCkgPT0gMCkKICAgICAgICAgICAgYUZpcnN0Rm91bmRUYWJsZSA9IGFDZWxsUmFuZ2UuYVRhYmxlTmFtZTsKICAgICAgICBpZiAoYUNlbGxSYW5nZS5hVGFibGVOYW1lICE9IGFGaXJzdEZvdW5kVGFibGUpCiAgICAgICAgICAgIHRocm93IGxhbmc6OklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwoKICAgICAgICBPVVN0cmluZyBhVG1wKCBhQ2VsbFJhbmdlLmFUYWJsZU5hbWUgKTsKICAgICAgICBhVG1wICs9IE9VU3RyaW5nOjp2YWx1ZU9mKChzYWxfVW5pY29kZSkgJy4nKTsKICAgICAgICBhVG1wICs9IGxjbF9HZXRDZWxsTmFtZSggYUNlbGxSYW5nZS5hVXBwZXJMZWZ0Lm5Db2x1bW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFDZWxsUmFuZ2UuYVVwcGVyTGVmdC5uUm93ICk7CiAgICAgICAgLy8gZG9lcyBjZWxsIHJhbmdlIGNvbnNpc3Qgb2YgbW9yZSB0aGFuIGEgc2luZ2xlIGNlbGw/CiAgICAgICAgaWYgKCFhQ2VsbFJhbmdlLmFMb3dlclJpZ2h0LmJJc0VtcHR5KQogICAgICAgIHsKICAgICAgICAgICAgYVRtcCArPSBPVVN0cmluZzo6dmFsdWVPZigoc2FsX1VuaWNvZGUpICc6Jyk7CiAgICAgICAgICAgIGFUbXAgKz0gbGNsX0dldENlbGxOYW1lKCBhQ2VsbFJhbmdlLmFMb3dlclJpZ2h0Lm5Db2x1bW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhQ2VsbFJhbmdlLmFMb3dlclJpZ2h0Lm5Sb3cgKTsKICAgICAgICB9CgogICAgICAgIGlmIChhUmVzLkxlbigpKSAvLyBpbiBjYXNlIG9mIG11bHRpcGxlIHJhbmdlcyBhZGQgZGVsaW1ldGVyCiAgICAgICAgICAgIGFSZXMuQXBwZW5kQXNjaWkoICI7IiApOwogICAgICAgIGFSZXMgKz0gU3RyaW5nKGFUbXApOwogICAgfQoKICAgIHJldHVybiBhUmVzOwp9CgoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKU3dDaGFydERhdGFTb3VyY2U6OlN3Q2hhcnREYXRhU291cmNlKAogICAgICAgIGNvbnN0IHVubzo6U2VxdWVuY2U8IHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhMYWJlbGVkRGF0YVNlcXVlbmNlID4gPiAmckxEUyApIDoKICAgIGFMRFMoIHJMRFMgKQp7Cn0KCgpTd0NoYXJ0RGF0YVNvdXJjZTo6flN3Q2hhcnREYXRhU291cmNlKCkKewovLyAgICBkZWxldGUgcFRibENyc3I7Cn0KCgp1bm86OlNlcXVlbmNlPCB1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYTGFiZWxlZERhdGFTZXF1ZW5jZSA+ID4gU0FMX0NBTEwgU3dDaGFydERhdGFTb3VyY2U6OmdldERhdGFTZXF1ZW5jZXMoICApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIHJldHVybiBhTERTOwp9CgoKT1VTdHJpbmcgU0FMX0NBTEwgU3dDaGFydERhdGFTb3VyY2U6OmdldEltcGxlbWVudGF0aW9uTmFtZSggICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIHZvczo6T0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwogICAgcmV0dXJuIEMyVSgiU3dDaGFydERhdGFTb3VyY2UiKTsKfQoKCnNhbF9Cb29sIFNBTF9DQUxMIFN3Q2hhcnREYXRhU291cmNlOjpzdXBwb3J0c1NlcnZpY2UoCiAgICAgICAgY29uc3QgT1VTdHJpbmcmIHJTZXJ2aWNlTmFtZSApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIHJldHVybiByU2VydmljZU5hbWUuZXF1YWxzQXNjaWkoIFNOX0RBVEFfU09VUkNFICk7Cn0KCgp1bm86OlNlcXVlbmNlPCBPVVN0cmluZyA+IFNBTF9DQUxMIFN3Q2hhcnREYXRhU291cmNlOjpnZXRTdXBwb3J0ZWRTZXJ2aWNlTmFtZXMoICApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIHVubzo6U2VxdWVuY2U8IE9VU3RyaW5nID4gYVJlcygxKTsKICAgIGFSZXMuZ2V0QXJyYXkoKVswXSA9IEMyVSggU05fREFUQV9TT1VSQ0UgKTsKICAgIHJldHVybiBhUmVzOwp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgpTd0NoYXJ0RGF0YVNlcXVlbmNlOjpTd0NoYXJ0RGF0YVNlcXVlbmNlKAogICAgICAgIFN3Q2hhcnREYXRhUHJvdmlkZXIgJnJQcm92aWRlciwKICAgICAgICBTd0ZybUZtdCAgICZyVGJsRm10LAogICAgICAgIFN3VW5vQ3JzciAgKnBUYWJsZUN1cnNvciApIDoKICAgIFN3Q2xpZW50KCAmclRibEZtdCApLAogICAgYUV2dExpc3RlbmVycyggR2V0Q2hhcnRNdXRleCgpICksCiAgICBhTW9kaWZ5TGlzdGVuZXJzKCBHZXRDaGFydE11dGV4KCkgKSwKICAgIGFSb3dMYWJlbFRleHQoIFNXX1JFUyggU1RSX0NIQVJUMl9ST1dfTEFCRUxfVEVYVCApICksCiAgICBhQ29sTGFiZWxUZXh0KCBTV19SRVMoIFNUUl9DSEFSVDJfQ09MX0xBQkVMX1RFWFQgKSApLAogICAgeERhdGFQcm92aWRlciggJnJQcm92aWRlciApLAogICAgcERhdGFQcm92aWRlciggJnJQcm92aWRlciApLAogICAgcFRibENyc3IoIHBUYWJsZUN1cnNvciApLAogICAgYUN1cnNvckRlcGVuZCggdGhpcywgcFRhYmxlQ3Vyc29yICksCiAgICBfcFByb3BTZXQoIGFTd01hcFByb3ZpZGVyLkdldFByb3BlcnR5U2V0KCBQUk9QRVJUWV9NQVBfQ0hBUlQyX0RBVEFfU0VRVUVOQ0UgKSApCnsKICAgIGJEaXNwb3NlZCA9IHNhbF9GYWxzZTsKCiAgICBhY3F1aXJlKCk7CiAgICB0cnkKICAgIHsKICAgICAgICBjb25zdCBTd1RhYmxlKiBwVGFibGUgPSBTd1RhYmxlOjpGaW5kVGFibGUoICZyVGJsRm10ICk7CiAgICAgICAgaWYgKHBUYWJsZSkKICAgICAgICB7CiAgICAgICAgICAgIHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPiB4UmVmKCBkeW5hbWljX2Nhc3Q8IGNoYXJ0Mjo6ZGF0YTo6WERhdGFTZXF1ZW5jZSAqID4odGhpcyksIHVubzo6VU5PX1FVRVJZICk7CiAgICAgICAgICAgIHBEYXRhUHJvdmlkZXItPkFkZERhdGFTZXF1ZW5jZSggKnBUYWJsZSwgeFJlZiApOwogICAgICAgICAgICBwRGF0YVByb3ZpZGVyLT5hZGRFdmVudExpc3RlbmVyKCBkeW5hbWljX2Nhc3Q8IGxhbmc6OlhFdmVudExpc3RlbmVyICogPih0aGlzKSApOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgREJHX0VSUk9SKCAidGFibGUgbWlzc2luZyIgKTsKICAgICAgICB9CiAgICB9CiAgICBjYXRjaCAodW5vOjpSdW50aW1lRXhjZXB0aW9uICYpCiAgICB7CiAgICAgICAgdGhyb3c7CiAgICB9CiAgICBjYXRjaCAodW5vOjpFeGNlcHRpb24gJikKICAgIHsKICAgIH0KICAgIHJlbGVhc2UoKTsKCiNpZiBPU0xfREVCVUdfTEVWRUwgPiAxCiAgICBPVVN0cmluZyBhUmFuZ2VTdHIoIGdldFNvdXJjZVJhbmdlUmVwcmVzZW50YXRpb24oKSApOwoKCS8vIGNoZWNrIGlmIGl0IGNhbiBwcm9wZXJseSBjb252ZXJ0IGludG8gYSBTd1Vub1RhYmxlQ3JzcgoJLy8gd2hpY2ggaXMgcmVxdWlyZWQgZm9yIHNvbWUgZnVuY3Rpb25zCiAgICBTd1Vub1RhYmxlQ3JzciogcFVub1RibENyc3IgPSBkeW5hbWljX2Nhc3Q8U3dVbm9UYWJsZUNyc3IqPihwVGJsQ3Jzcik7CiAgICBEQkdfQVNTRVJUKHBVbm9UYmxDcnNyLCAiU3dDaGFydERhdGFTZXF1ZW5jZTogY3Vyc29yIG5vdCBTd1Vub1RhYmxlQ3JzciIpOwogICAgKHZvaWQpIHBVbm9UYmxDcnNyOwojZW5kaWYKfQoKClN3Q2hhcnREYXRhU2VxdWVuY2U6OlN3Q2hhcnREYXRhU2VxdWVuY2UoIGNvbnN0IFN3Q2hhcnREYXRhU2VxdWVuY2UgJnJPYmogKSA6CiAgICBTd0NoYXJ0RGF0YVNlcXVlbmNlQmFzZUNsYXNzKCksCiAgICBTd0NsaWVudCggck9iai5HZXRGcm1GbXQoKSApLAogICAgYUV2dExpc3RlbmVycyggR2V0Q2hhcnRNdXRleCgpICksCiAgICBhTW9kaWZ5TGlzdGVuZXJzKCBHZXRDaGFydE11dGV4KCkgKSwKICAgIGFSb2xlKCByT2JqLmFSb2xlICksCiAgICBhUm93TGFiZWxUZXh0KCBTV19SRVMoU1RSX0NIQVJUMl9ST1dfTEFCRUxfVEVYVCkgKSwKICAgIGFDb2xMYWJlbFRleHQoIFNXX1JFUyhTVFJfQ0hBUlQyX0NPTF9MQUJFTF9URVhUKSApLAogICAgeERhdGFQcm92aWRlciggck9iai5wRGF0YVByb3ZpZGVyICksCiAgICBwRGF0YVByb3ZpZGVyKCByT2JqLnBEYXRhUHJvdmlkZXIgKSwKICAgIHBUYmxDcnNyKCByT2JqLnBUYmxDcnNyLT5DbG9uZSgpICksCiAgICBhQ3Vyc29yRGVwZW5kKCB0aGlzLCBwVGJsQ3JzciApLAogICAgX3BQcm9wU2V0KCByT2JqLl9wUHJvcFNldCApCnsKICAgIGJEaXNwb3NlZCA9IHNhbF9GYWxzZTsKCiAgICBhY3F1aXJlKCk7CiAgICB0cnkKICAgIHsKICAgICAgICBjb25zdCBTd1RhYmxlKiBwVGFibGUgPSBTd1RhYmxlOjpGaW5kVGFibGUoIEdldEZybUZtdCgpICk7CiAgICAgICAgaWYgKHBUYWJsZSkKICAgICAgICB7CiAgICAgICAgICAgIHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPiB4UmVmKCBkeW5hbWljX2Nhc3Q8IGNoYXJ0Mjo6ZGF0YTo6WERhdGFTZXF1ZW5jZSAqID4odGhpcyksIHVubzo6VU5PX1FVRVJZICk7CiAgICAgICAgICAgIHBEYXRhUHJvdmlkZXItPkFkZERhdGFTZXF1ZW5jZSggKnBUYWJsZSwgeFJlZiApOwogICAgICAgICAgICBwRGF0YVByb3ZpZGVyLT5hZGRFdmVudExpc3RlbmVyKCBkeW5hbWljX2Nhc3Q8IGxhbmc6OlhFdmVudExpc3RlbmVyICogPih0aGlzKSApOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgREJHX0VSUk9SKCAidGFibGUgbWlzc2luZyIgKTsKICAgICAgICB9CiAgICB9CiAgICBjYXRjaCAodW5vOjpSdW50aW1lRXhjZXB0aW9uICYpCiAgICB7CiAgICAgICAgdGhyb3c7CiAgICB9CiAgICBjYXRjaCAodW5vOjpFeGNlcHRpb24gJikKICAgIHsKICAgIH0KICAgIHJlbGVhc2UoKTsKCiNpZiBPU0xfREVCVUdfTEVWRUwgPiAxCiAgICBPVVN0cmluZyBhUmFuZ2VTdHIoIGdldFNvdXJjZVJhbmdlUmVwcmVzZW50YXRpb24oKSApOwoKICAgIC8vIGNoZWNrIGlmIGl0IGNhbiBwcm9wZXJseSBjb252ZXJ0IGludG8gYSBTd1Vub1RhYmxlQ3JzcgoJLy8gd2hpY2ggaXMgcmVxdWlyZWQgZm9yIHNvbWUgZnVuY3Rpb25zCiAgICBTd1Vub1RhYmxlQ3JzciogcFVub1RibENyc3IgPSBkeW5hbWljX2Nhc3Q8U3dVbm9UYWJsZUNyc3IqPihwVGJsQ3Jzcik7CiAgICBEQkdfQVNTRVJUKHBVbm9UYmxDcnNyLCAiU3dDaGFydERhdGFTZXF1ZW5jZTogY3Vyc29yIG5vdCBTd1Vub1RhYmxlQ3JzciIpOwogICAgKHZvaWQpIHBVbm9UYmxDcnNyOwojZW5kaWYKfQoKClN3Q2hhcnREYXRhU2VxdWVuY2U6On5Td0NoYXJ0RGF0YVNlcXVlbmNlKCkKewogICAgLy8gc2luY2UgdGhlIGRhdGEtcHJvdmlkZXIgaG9sZHMgb25seSB3ZWFrIHJlZmVyZW5jZXMgdG8gdGhlIGRhdGEtc2VxdWVuY2UKICAgIC8vIHRoZXJlIHNob3VsZCBiZSBubyBuZWVkIGhlcmUgdG8gcmVsZWFzZSB0aGVtIGV4cGxpY2l0bHkuLi4KCiAgICBkZWxldGUgcFRibENyc3I7Cn0KCgpjb25zdCB1bm86OlNlcXVlbmNlPCBzYWxfSW50OCA+ICYgU3dDaGFydERhdGFTZXF1ZW5jZTo6Z2V0VW5vVHVubmVsSWQoKQp7CiAgICBzdGF0aWMgdW5vOjpTZXF1ZW5jZTwgc2FsX0ludDggPiBhU2VxID0gOjpDcmVhdGVVbm9UdW5uZWxJZCgpOwogICAgcmV0dXJuIGFTZXE7Cn0KCgpzYWxfSW50NjQgU0FMX0NBTEwgU3dDaGFydERhdGFTZXF1ZW5jZTo6Z2V0U29tZXRoaW5nKCBjb25zdCB1bm86OlNlcXVlbmNlPCBzYWxfSW50OCA+ICZySWQgKQogICAgdGhyb3codW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICBpZiggcklkLmdldExlbmd0aCgpID09IDE2CiAgICAgICAgJiYgMCA9PSBydGxfY29tcGFyZU1lbW9yeSggZ2V0VW5vVHVubmVsSWQoKS5nZXRDb25zdEFycmF5KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBySWQuZ2V0Q29uc3RBcnJheSgpLCAxNiApICkKICAgIHsKICAgICAgICByZXR1cm4gc2FsOjpzdGF0aWNfaW50X2Nhc3Q8IHNhbF9JbnQ2NCA+KCByZWludGVycHJldF9jYXN0PCBzYWxfSW50UHRyID4odGhpcykgKTsKICAgIH0KICAgIHJldHVybiAwOwp9CgoKdW5vOjpTZXF1ZW5jZTwgdW5vOjpBbnkgPiBTQUxfQ0FMTCBTd0NoYXJ0RGF0YVNlcXVlbmNlOjpnZXREYXRhKCAgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgdm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CiAgICBpZiAoYkRpc3Bvc2VkKQogICAgICAgIHRocm93IGxhbmc6OkRpc3Bvc2VkRXhjZXB0aW9uKCk7CgogICAgdW5vOjpTZXF1ZW5jZTwgdW5vOjpBbnkgPiBhUmVzOwogICAgU3dGcm1GbXQqIHBUYmxGbXQgPSBHZXRGcm1GbXQoKTsKICAgIGlmKHBUYmxGbXQpCiAgICB7CiAgICAgICAgU3dUYWJsZSogcFRhYmxlID0gU3dUYWJsZTo6RmluZFRhYmxlKCBwVGJsRm10ICk7CiAgICAgICAgaWYoIXBUYWJsZS0+SXNUYmxDb21wbGV4KCkpCiAgICAgICAgewogICAgICAgICAgICBTd1JhbmdlRGVzY3JpcHRvciBhRGVzYzsKICAgICAgICAgICAgaWYgKEZpbGxSYW5nZURlc2NyaXB0b3IoIGFEZXNjLCBHZXRDZWxsUmFuZ2VOYW1lKCAqcFRibEZtdCwgKnBUYmxDcnNyICkgKSkKICAgICAgICAgICAgewoJCQkJLy8hISBtYWtlIGNvcHkgb2YgcFRibENyc3IgKFN3VW5vQ3JzciApCgkJCQkvLyBrZWVwIG9yaWdpbmFsIGN1cnNvciBhbmQgbWFrZSBjb3B5IG9mIGl0IHRoYXQgZ2V0cyBoYW5kZWQKCQkJCS8vIG92ZXIgdG8gdGhlIFN3WENlbGxSYW5nZSBvYmplY3Qgd2hpY2ggdGFrZXMgb3duZXJzaGlwIGFuZAoJCQkJLy8gdGh1cyB3aWxsIGRlc3Ryb3kgdGhlIGNvcHkgbGF0ZXIuCiAgICAgICAgICAgICAgICBTd1hDZWxsUmFuZ2UgYVJhbmdlKCBwVGJsQ3Jzci0+Q2xvbmUoKSwgKnBUYmxGbXQsIGFEZXNjICk7CiAgICAgICAgICAgICAgICBhUmFuZ2UuR2V0RGF0YVNlcXVlbmNlKCAmYVJlcywgMCwgMCApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGFSZXM7Cn0KCgpPVVN0cmluZyBTQUxfQ0FMTCBTd0NoYXJ0RGF0YVNlcXVlbmNlOjpnZXRTb3VyY2VSYW5nZVJlcHJlc2VudGF0aW9uKCAgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgdm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CiAgICBpZiAoYkRpc3Bvc2VkKQogICAgICAgIHRocm93IGxhbmc6OkRpc3Bvc2VkRXhjZXB0aW9uKCk7CgogICAgU3RyaW5nIGFSZXM7CiAgICBTd0ZybUZtdCogcFRibEZtdCA9IEdldEZybUZtdCgpOwogICAgaWYgKHBUYmxGbXQpCiAgICB7CiAgICAgICAgYVJlcyA9IHBUYmxGbXQtPkdldE5hbWUoKTsKICAgICAgICBTdHJpbmcgYUNlbGxSYW5nZSggR2V0Q2VsbFJhbmdlTmFtZSggKnBUYmxGbXQsICpwVGJsQ3JzciApICk7CiAgICAgICAgREJHX0FTU0VSVCggYUNlbGxSYW5nZS5MZW4oKSAhPSAwLCAiZmFpbGVkIHRvIGdldCBjZWxsIHJhbmdlIiApOwogICAgICAgIGFSZXMgKz0gKHNhbF9Vbmljb2RlKSAnLic7CiAgICAgICAgYVJlcyArPSBhQ2VsbFJhbmdlOwogICAgfQogICAgcmV0dXJuIGFSZXM7Cn0KCnVubzo6U2VxdWVuY2U8IE9VU3RyaW5nID4gU0FMX0NBTEwgU3dDaGFydERhdGFTZXF1ZW5jZTo6Z2VuZXJhdGVMYWJlbCgKICAgICAgICBjaGFydDI6OmRhdGE6OkxhYmVsT3JpZ2luIGVMYWJlbE9yaWdpbiApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIGlmIChiRGlzcG9zZWQpCiAgICAgICAgdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCiAgICB1bm86OlNlcXVlbmNlPCBPVVN0cmluZyA+IGFMYWJlbHM7CgogICAgewogICAgICAgIFN3UmFuZ2VEZXNjcmlwdG9yIGFEZXNjOwogICAgICAgIHNhbF9Cb29sIGJPayBzYWxfRmFsc2U7CiAgICAgICAgU3dGcm1GbXQqIHBUYmxGbXQgPSBHZXRGcm1GbXQoKTsKICAgICAgICBTd1RhYmxlKiBwVGFibGUgPSBwVGJsRm10ID8gU3dUYWJsZTo6RmluZFRhYmxlKCBwVGJsRm10ICkgOiAwOwogICAgICAgIGlmICghcFRibEZtdCB8fCAhcFRhYmxlIHx8IHBUYWJsZS0+SXNUYmxDb21wbGV4KCkpCiAgICAgICAgICAgIHRocm93IHVubzo6UnVudGltZUV4Y2VwdGlvbigpOwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFN0cmluZyBhQ2VsbFJhbmdlKCBHZXRDZWxsUmFuZ2VOYW1lKCAqcFRibEZtdCwgKnBUYmxDcnNyICkgKTsKICAgICAgICAgICAgREJHX0FTU0VSVCggYUNlbGxSYW5nZS5MZW4oKSAhPSAwLCAiZmFpbGVkIHRvIGdldCBjZWxsIHJhbmdlIiApOwogICAgICAgICAgICBiT2sgPSBGaWxsUmFuZ2VEZXNjcmlwdG9yKCBhRGVzYywgYUNlbGxSYW5nZSApOwogICAgICAgICAgICBEQkdfQVNTRVJUKCBiT2ssICJmYWxpZWQgdG8gZ2V0IFN3UmFuZ2VEZXNjcmlwdG9yIiApOwogICAgICAgIH0KICAgICAgICBpZiAoYk9rKQogICAgICAgIHsKICAgICAgICAgICAgYURlc2MuTm9ybWFsaXplKCk7CiAgICAgICAgICAgIHNhbF9JbnQzMiBuQ29sU3BhbiA9IGFEZXNjLm5SaWdodCAtIGFEZXNjLm5MZWZ0ICsgMTsKICAgICAgICAgICAgc2FsX0ludDMyIG5Sb3dTcGFuID0gYURlc2MubkJvdHRvbSAtIGFEZXNjLm5Ub3AgKyAxOwogICAgICAgICAgICBEQkdfQVNTRVJUKCBuQ29sU3BhbiA9PSAxIHx8IG5Sb3dTcGFuID09IDEsCiAgICAgICAgICAgICAgICAgICAgInVuZXhwZWN0ZWQgcmFuZ2Ugb2Ygc2VsZWN0ZWQgY2VsbHMiICk7CgogICAgICAgICAgICBTdHJpbmcgYVR4dDsgICAgLy8gbGFiZWwgdGV4dCB0byBiZSByZXR1cm5lZAogICAgICAgICAgICBzYWxfQm9vbCBiUmV0dXJuRW1wdHlUeHQgPSBzYWxfRmFsc2U7CiAgICAgICAgICAgIHNhbF9Cb29sIGJVc2VDb2wgPSBzYWxfVHJ1ZTsKICAgICAgICAgICAgaWYgKGVMYWJlbE9yaWdpbiA9PSBjaGFydDI6OmRhdGE6OkxhYmVsT3JpZ2luX0NPTFVNTikKICAgICAgICAgICAgICAgIGJVc2VDb2wgPSBzYWxfVHJ1ZTsKICAgICAgICAgICAgZWxzZSBpZiAoZUxhYmVsT3JpZ2luID09IGNoYXJ0Mjo6ZGF0YTo6TGFiZWxPcmlnaW5fUk9XKQogICAgICAgICAgICAgICAgYlVzZUNvbCA9IHNhbF9GYWxzZTsKICAgICAgICAgICAgZWxzZSBpZiAoZUxhYmVsT3JpZ2luID09IGNoYXJ0Mjo6ZGF0YTo6TGFiZWxPcmlnaW5fU0hPUlRfU0lERSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYlVzZUNvbCA9IG5Db2xTcGFuIDwgblJvd1NwYW47CiAgICAgICAgICAgICAgICBiUmV0dXJuRW1wdHlUeHQgPSBuQ29sU3BhbiA9PSBuUm93U3BhbjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChlTGFiZWxPcmlnaW4gPT0gY2hhcnQyOjpkYXRhOjpMYWJlbE9yaWdpbl9MT05HX1NJREUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGJVc2VDb2wgPSBuQ29sU3BhbiA+IG5Sb3dTcGFuOwogICAgICAgICAgICAgICAgYlJldHVybkVtcHR5VHh0ID0gbkNvbFNwYW4gPT0gblJvd1NwYW47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBEQkdfRVJST1IoICJ1bmV4cGVjdGVkIGNhc2UiICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGJ1aWxkIGxhYmVsIHNlcXVlbmNlCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIHNhbF9JbnQzMiBuU2VxTGVuID0gYlVzZUNvbCA/IG5Db2xTcGFuIDogblJvd1NwYW47CiAgICAgICAgICAgIGFMYWJlbHMucmVhbGxvYyggblNlcUxlbiApOwogICAgICAgICAgICBPVVN0cmluZyAqcExhYmVscyA9IGFMYWJlbHMuZ2V0QXJyYXkoKTsKICAgICAgICAgICAgZm9yIChzYWxfSW50MzIgaSA9IDA7ICBpIDwgblNlcUxlbjsgICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFiUmV0dXJuRW1wdHlUeHQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYVR4dCA9IGJVc2VDb2wgPyBhQ29sTGFiZWxUZXh0IDogYVJvd0xhYmVsVGV4dDsKICAgICAgICAgICAgICAgICAgICBzYWxfSW50MzIgbkNvbCA9IGFEZXNjLm5MZWZ0OwogICAgICAgICAgICAgICAgICAgIHNhbF9JbnQzMiBuUm93ID0gYURlc2MublRvcDsKICAgICAgICAgICAgICAgICAgICBpZiAoYlVzZUNvbCkKICAgICAgICAgICAgICAgICAgICAgICAgbkNvbCA9IG5Db2wgKyBpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgblJvdyA9IG5Sb3cgKyBpOwogICAgICAgICAgICAgICAgICAgIFN0cmluZyBhQ2VsbE5hbWUoIGxjbF9HZXRDZWxsTmFtZSggbkNvbCwgblJvdyApICk7CgogICAgICAgICAgICAgICAgICAgIHh1Yl9TdHJMZW4gbkxlbiA9IGFDZWxsTmFtZS5MZW4oKTsKICAgICAgICAgICAgICAgICAgICBpZiAobkxlbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNhbF9Vbmljb2RlICpwQnVmID0gYUNlbGxOYW1lLkdldEJ1ZmZlcigpOwogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzYWxfVW5pY29kZSAqcEVuZCA9IHBCdWYgKyBuTGVuOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocEJ1ZiA8IHBFbmQgJiYgISgnMCcgPD0gKnBCdWYgJiYgKnBCdWYgPD0gJzknKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsrcEJ1ZjsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RhcnQgb2YgbnVtYmVyIGZvdW5kPwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocEJ1ZiA8IHBFbmQgJiYgKCcwJyA8PSAqcEJ1ZiAmJiAqcEJ1ZiA8PSAnOScpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYVJwbGM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYU5ldzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiVXNlQ29sKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewoJCQkJCQkJCWFScGxjID0gU3RyaW5nOjpDcmVhdGVGcm9tQXNjaWkoICIlQ09MVU1OTEVUVEVSIiApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFOZXcgPSBTdHJpbmcoIGFDZWxsTmFtZS5HZXRCdWZmZXIoKSwgc3RhdGljX2Nhc3Q8eHViX1N0ckxlbj4ocEJ1ZiAtIGFDZWxsTmFtZS5HZXRCdWZmZXIoKSkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhUnBsYyA9IFN0cmluZzo6Q3JlYXRlRnJvbUFzY2lpKCAiJVJPV05VTUJFUiIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhTmV3ID0gU3RyaW5nKCBwQnVmLCBzdGF0aWNfY2FzdDx4dWJfU3RyTGVuPigoYUNlbGxOYW1lLkdldEJ1ZmZlcigpICsgbkxlbikgLSBwQnVmKSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeHViX1N0ckxlbiBuUG9zID0gYVR4dC5TZWFyY2goIGFScGxjICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoblBvcyAhPSBTVFJJTkdfTk9URk9VTkQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVR4dCA9IGFUeHQuUmVwbGFjZSggblBvcywgYVJwbGMuTGVuKCksIGFOZXcgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHBMYWJlbHNbaV0gPSBhVHh0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBhTGFiZWxzOwp9Cgo6OnNhbF9JbnQzMiBTQUxfQ0FMTCBTd0NoYXJ0RGF0YVNlcXVlbmNlOjpnZXROdW1iZXJGb3JtYXRLZXlCeUluZGV4KAogICAgOjpzYWxfSW50MzIgLypuSW5kZXgqLyApCiAgICB0aHJvdyAobGFuZzo6SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiwKICAgICAgICAgICB1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIHJldHVybiAwOwp9CgoKCnVubzo6U2VxdWVuY2U8IE9VU3RyaW5nID4gU0FMX0NBTEwgU3dDaGFydERhdGFTZXF1ZW5jZTo6Z2V0VGV4dHVhbERhdGEoICApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIGlmIChiRGlzcG9zZWQpCiAgICAgICAgdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCiAgICB1bm86OlNlcXVlbmNlPCBPVVN0cmluZyA+IGFSZXM7CiAgICBTd0ZybUZtdCogcFRibEZtdCA9IEdldEZybUZtdCgpOwogICAgaWYocFRibEZtdCkKICAgIHsKICAgICAgICBTd1RhYmxlKiBwVGFibGUgPSBTd1RhYmxlOjpGaW5kVGFibGUoIHBUYmxGbXQgKTsKICAgICAgICBpZighcFRhYmxlLT5Jc1RibENvbXBsZXgoKSkKICAgICAgICB7CiAgICAgICAgICAgIFN3UmFuZ2VEZXNjcmlwdG9yIGFEZXNjOwogICAgICAgICAgICBpZiAoRmlsbFJhbmdlRGVzY3JpcHRvciggYURlc2MsIEdldENlbGxSYW5nZU5hbWUoICpwVGJsRm10LCAqcFRibENyc3IgKSApKQogICAgICAgICAgICB7CgkJCQkvLyEhIG1ha2UgY29weSBvZiBwVGJsQ3JzciAoU3dVbm9DcnNyICkKCQkJCS8vIGtlZXAgb3JpZ2luYWwgY3Vyc29yIGFuZCBtYWtlIGNvcHkgb2YgaXQgdGhhdCBnZXRzIGhhbmRlZAoJCQkJLy8gb3ZlciB0byB0aGUgU3dYQ2VsbFJhbmdlIG9iamVjdCB3aGljaCB0YWtlcyBvd25lcnNoaXAgYW5kCgkJCQkvLyB0aHVzIHdpbGwgZGVzdHJveSB0aGUgY29weSBsYXRlci4KICAgICAgICAgICAgICAgIFN3WENlbGxSYW5nZSBhUmFuZ2UoIHBUYmxDcnNyLT5DbG9uZSgpLCAqcFRibEZtdCwgYURlc2MgKTsKICAgICAgICAgICAgICAgIGFSYW5nZS5HZXREYXRhU2VxdWVuY2UoIDAsICZhUmVzLCAwICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gYVJlczsKfQoKCnVubzo6U2VxdWVuY2U8IGRvdWJsZSA+IFNBTF9DQUxMIFN3Q2hhcnREYXRhU2VxdWVuY2U6OmdldE51bWVyaWNhbERhdGEoICApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIGlmIChiRGlzcG9zZWQpCiAgICAgICAgdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCiAgICB1bm86OlNlcXVlbmNlPCBkb3VibGUgPiBhUmVzOwogICAgU3dGcm1GbXQqIHBUYmxGbXQgPSBHZXRGcm1GbXQoKTsKICAgIGlmKHBUYmxGbXQpCiAgICB7CiAgICAgICAgU3dUYWJsZSogcFRhYmxlID0gU3dUYWJsZTo6RmluZFRhYmxlKCBwVGJsRm10ICk7CiAgICAgICAgaWYoIXBUYWJsZS0+SXNUYmxDb21wbGV4KCkpCiAgICAgICAgewogICAgICAgICAgICBTd1JhbmdlRGVzY3JpcHRvciBhRGVzYzsKICAgICAgICAgICAgaWYgKEZpbGxSYW5nZURlc2NyaXB0b3IoIGFEZXNjLCBHZXRDZWxsUmFuZ2VOYW1lKCAqcFRibEZtdCwgKnBUYmxDcnNyICkgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8hISBtYWtlIGNvcHkgb2YgcFRibENyc3IgKFN3VW5vQ3JzciApCiAgICAgICAgICAgICAgICAvLyBrZWVwIG9yaWdpbmFsIGN1cnNvciBhbmQgbWFrZSBjb3B5IG9mIGl0IHRoYXQgZ2V0cyBoYW5kZWQKICAgICAgICAgICAgICAgIC8vIG92ZXIgdG8gdGhlIFN3WENlbGxSYW5nZSBvYmplY3Qgd2hpY2ggdGFrZXMgb3duZXJzaGlwIGFuZAogICAgICAgICAgICAgICAgLy8gdGh1cyB3aWxsIGRlc3Ryb3kgdGhlIGNvcHkgbGF0ZXIuCiAgICAgICAgICAgICAgICBTd1hDZWxsUmFuZ2UgYVJhbmdlKCBwVGJsQ3Jzci0+Q2xvbmUoKSwgKnBUYmxGbXQsIGFEZXNjICk7CgogICAgICAgICAgICAgICAgLy8gZ2V0IG51bWVyaWNhbCB2YWx1ZXMgYW5kIG1ha2UgYW4gZWZmb3J0IHRvIHJldHVybiB0aGUKICAgICAgICAgICAgICAgIC8vIG51bWVyaWNhbCB2YWx1ZSBmb3IgdGV4dCBmb3JtYXR0ZWQgY2VsbHMKICAgICAgICAgICAgICAgIGFSYW5nZS5HZXREYXRhU2VxdWVuY2UoIDAsIDAsICZhUmVzLCBzYWxfVHJ1ZSApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGFSZXM7Cn0KCgp1bm86OlJlZmVyZW5jZTwgdXRpbDo6WENsb25lYWJsZSA+IFNBTF9DQUxMIFN3Q2hhcnREYXRhU2VxdWVuY2U6OmNyZWF0ZUNsb25lKCAgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgdm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CiAgICBpZiAoYkRpc3Bvc2VkKQogICAgICAgIHRocm93IGxhbmc6OkRpc3Bvc2VkRXhjZXB0aW9uKCk7CiAgICByZXR1cm4gbmV3IFN3Q2hhcnREYXRhU2VxdWVuY2UoICp0aGlzICk7Cn0KCgp1bm86OlJlZmVyZW5jZTwgYmVhbnM6OlhQcm9wZXJ0eVNldEluZm8gPiBTQUxfQ0FMTCBTd0NoYXJ0RGF0YVNlcXVlbmNlOjpnZXRQcm9wZXJ0eVNldEluZm8oICApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIGlmIChiRGlzcG9zZWQpCiAgICAgICAgdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCiAgICBzdGF0aWMgdW5vOjpSZWZlcmVuY2U8IGJlYW5zOjpYUHJvcGVydHlTZXRJbmZvID4geFJlcyA9IF9wUHJvcFNldC0+Z2V0UHJvcGVydHlTZXRJbmZvKCk7CiAgICByZXR1cm4geFJlczsKfQoKCnZvaWQgU0FMX0NBTEwgU3dDaGFydERhdGFTZXF1ZW5jZTo6c2V0UHJvcGVydHlWYWx1ZSgKICAgICAgICBjb25zdCBPVVN0cmluZyYgclByb3BlcnR5TmFtZSwKICAgICAgICBjb25zdCB1bm86OkFueSYgclZhbHVlICkKICAgIHRocm93IChiZWFuczo6VW5rbm93blByb3BlcnR5RXhjZXB0aW9uLCBiZWFuczo6UHJvcGVydHlWZXRvRXhjZXB0aW9uLCBsYW5nOjpJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIGxhbmc6OldyYXBwZWRUYXJnZXRFeGNlcHRpb24sIHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgdm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CiAgICBpZiAoYkRpc3Bvc2VkKQogICAgICAgIHRocm93IGxhbmc6OkRpc3Bvc2VkRXhjZXB0aW9uKCk7CgogICAgaWYgKHJQcm9wZXJ0eU5hbWUuZXF1YWxzQXNjaWkoIFNXX1BST1BfTkFNRV9TVFIoIFVOT19OQU1FX1JPTEUgKSkpCiAgICB7CiAgICAgICAgaWYgKCAhKHJWYWx1ZSA+Pj0gYVJvbGUpICkKICAgICAgICAgICAgdGhyb3cgbGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICB9CiAgICBlbHNlCiAgICAgICAgdGhyb3cgYmVhbnM6OlVua25vd25Qcm9wZXJ0eUV4Y2VwdGlvbigpOwp9CgoKdW5vOjpBbnkgU0FMX0NBTEwgU3dDaGFydERhdGFTZXF1ZW5jZTo6Z2V0UHJvcGVydHlWYWx1ZSgKICAgICAgICBjb25zdCBPVVN0cmluZyYgclByb3BlcnR5TmFtZSApCiAgICB0aHJvdyAoYmVhbnM6OlVua25vd25Qcm9wZXJ0eUV4Y2VwdGlvbiwgbGFuZzo6V3JhcHBlZFRhcmdldEV4Y2VwdGlvbiwgdW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIGlmIChiRGlzcG9zZWQpCiAgICAgICAgdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCiAgICB1bm86OkFueSBhUmVzOwogICAgaWYgKHJQcm9wZXJ0eU5hbWUuZXF1YWxzQXNjaWkoIFNXX1BST1BfTkFNRV9TVFIoIFVOT19OQU1FX1JPTEUgKSkpCiAgICAgICAgYVJlcyA8PD0gYVJvbGU7CiAgICBlbHNlCiAgICAgICAgdGhyb3cgYmVhbnM6OlVua25vd25Qcm9wZXJ0eUV4Y2VwdGlvbigpOwoKICAgIHJldHVybiBhUmVzOwp9CgoKdm9pZCBTQUxfQ0FMTCBTd0NoYXJ0RGF0YVNlcXVlbmNlOjphZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKAogICAgICAgIGNvbnN0IE9VU3RyaW5nJiAvKnJQcm9wZXJ0eU5hbWUqLywKICAgICAgICBjb25zdCB1bm86OlJlZmVyZW5jZTwgYmVhbnM6OlhQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyID4mIC8qeExpc3RlbmVyKi8gKQogICAgdGhyb3cgKGJlYW5zOjpVbmtub3duUHJvcGVydHlFeGNlcHRpb24sIGxhbmc6OldyYXBwZWRUYXJnZXRFeGNlcHRpb24sIHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgLy92b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIERCR19FUlJPUiggIm5vdCBpbXBsZW1lbnRlZCIgKTsKfQoKCnZvaWQgU0FMX0NBTEwgU3dDaGFydERhdGFTZXF1ZW5jZTo6cmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcigKICAgICAgICBjb25zdCBPVVN0cmluZyYgLypyUHJvcGVydHlOYW1lKi8sCiAgICAgICAgY29uc3QgdW5vOjpSZWZlcmVuY2U8IGJlYW5zOjpYUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciA+JiAvKnhMaXN0ZW5lciovICkKICAgIHRocm93IChiZWFuczo6VW5rbm93blByb3BlcnR5RXhjZXB0aW9uLCBsYW5nOjpXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCB1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIC8vdm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CiAgICBEQkdfRVJST1IoICJub3QgaW1wbGVtZW50ZWQiICk7Cn0KCgp2b2lkIFNBTF9DQUxMIFN3Q2hhcnREYXRhU2VxdWVuY2U6OmFkZFZldG9hYmxlQ2hhbmdlTGlzdGVuZXIoCiAgICAgICAgY29uc3QgT1VTdHJpbmcmIC8qclByb3BlcnR5TmFtZSovLAogICAgICAgIGNvbnN0IHVubzo6UmVmZXJlbmNlPCBiZWFuczo6WFZldG9hYmxlQ2hhbmdlTGlzdGVuZXIgPiYgLyp4TGlzdGVuZXIqLyApCiAgICB0aHJvdyAoYmVhbnM6OlVua25vd25Qcm9wZXJ0eUV4Y2VwdGlvbiwgbGFuZzo6V3JhcHBlZFRhcmdldEV4Y2VwdGlvbiwgdW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICAvL3Zvczo6T0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwogICAgREJHX0VSUk9SKCAibm90IGltcGxlbWVudGVkIiApOwp9CgoKdm9pZCBTQUxfQ0FMTCBTd0NoYXJ0RGF0YVNlcXVlbmNlOjpyZW1vdmVWZXRvYWJsZUNoYW5nZUxpc3RlbmVyKAogICAgICAgIGNvbnN0IE9VU3RyaW5nJiAvKnJQcm9wZXJ0eU5hbWUqLywKICAgICAgICBjb25zdCB1bm86OlJlZmVyZW5jZTwgYmVhbnM6OlhWZXRvYWJsZUNoYW5nZUxpc3RlbmVyID4mIC8qeExpc3RlbmVyKi8gKQogICAgdGhyb3cgKGJlYW5zOjpVbmtub3duUHJvcGVydHlFeGNlcHRpb24sIGxhbmc6OldyYXBwZWRUYXJnZXRFeGNlcHRpb24sIHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgLy92b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIERCR19FUlJPUiggIm5vdCBpbXBsZW1lbnRlZCIgKTsKfQoKCk9VU3RyaW5nIFNBTF9DQUxMIFN3Q2hhcnREYXRhU2VxdWVuY2U6OmdldEltcGxlbWVudGF0aW9uTmFtZSggICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIHJldHVybiBDMlUoIlN3Q2hhcnREYXRhU2VxdWVuY2UiKTsKfQoKCnNhbF9Cb29sIFNBTF9DQUxMIFN3Q2hhcnREYXRhU2VxdWVuY2U6OnN1cHBvcnRzU2VydmljZSgKICAgICAgICBjb25zdCBPVVN0cmluZyYgclNlcnZpY2VOYW1lICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIHJldHVybiByU2VydmljZU5hbWUuZXF1YWxzQXNjaWkoIFNOX0RBVEFfU0VRVUVOQ0UgKTsKfQoKCnVubzo6U2VxdWVuY2U8IE9VU3RyaW5nID4gU0FMX0NBTEwgU3dDaGFydERhdGFTZXF1ZW5jZTo6Z2V0U3VwcG9ydGVkU2VydmljZU5hbWVzKCAgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgdm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CiAgICB1bm86OlNlcXVlbmNlPCBPVVN0cmluZyA+IGFSZXMoMSk7CiAgICBhUmVzLmdldEFycmF5KClbMF0gPSBDMlUoIFNOX0RBVEFfU0VRVUVOQ0UgKTsKICAgIHJldHVybiBhUmVzOwp9CgoKdm9pZCBTd0NoYXJ0RGF0YVNlcXVlbmNlOjpNb2RpZnkoIGNvbnN0IFNmeFBvb2xJdGVtKiBwT2xkLCBjb25zdCBTZnhQb29sSXRlbSAqcE5ldykKewogICAgQ2xpZW50TW9kaWZ5KHRoaXMsIHBPbGQsIHBOZXcgKTsKCiAgICAvLyB0YWJsZSB3YXMgZGVsZXRlZCBvciBjdXJzb3Igd2FzIGRlbGV0ZWQKICAgIGlmKCFHZXRSZWdpc3RlcmVkSW4oKSB8fCAhYUN1cnNvckRlcGVuZC5HZXRSZWdpc3RlcmVkSW4oKSkKCXsKICAgICAgICBwVGJsQ3JzciA9IDA7CiAgICAgICAgZGlzcG9zZSgpOwoJfQoJZWxzZQoJewogICAgICAgIHNldE1vZGlmaWVkKCBzYWxfVHJ1ZSApOwoJfQp9CgoKc2FsX0Jvb2wgU0FMX0NBTEwgU3dDaGFydERhdGFTZXF1ZW5jZTo6aXNNb2RpZmllZCggICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIHZvczo6T0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwogICAgaWYgKGJEaXNwb3NlZCkKICAgICAgICB0aHJvdyBsYW5nOjpEaXNwb3NlZEV4Y2VwdGlvbigpOwoKICAgIHJldHVybiBzYWxfVHJ1ZTsKfQoKCnZvaWQgU0FMX0NBTEwgU3dDaGFydERhdGFTZXF1ZW5jZTo6c2V0TW9kaWZpZWQoCiAgICAgICAgOjpzYWxfQm9vbCBiTW9kaWZpZWQgKQogICAgdGhyb3cgKGJlYW5zOjpQcm9wZXJ0eVZldG9FeGNlcHRpb24sIHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgdm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CiAgICBpZiAoYkRpc3Bvc2VkKQogICAgICAgIHRocm93IGxhbmc6OkRpc3Bvc2VkRXhjZXB0aW9uKCk7CgogICAgaWYgKGJNb2RpZmllZCkKCQlMYXVuY2hNb2RpZmllZEV2ZW50KCBhTW9kaWZ5TGlzdGVuZXJzLCBkeW5hbWljX2Nhc3Q8IFhNb2RpZnlCcm9hZGNhc3RlciAqID4odGhpcykgKTsKfQoKCnZvaWQgU0FMX0NBTEwgU3dDaGFydERhdGFTZXF1ZW5jZTo6YWRkTW9kaWZ5TGlzdGVuZXIoCiAgICAgICAgY29uc3QgdW5vOjpSZWZlcmVuY2U8IHV0aWw6OlhNb2RpZnlMaXN0ZW5lciA+JiByeExpc3RlbmVyICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIG9zbDo6TXV0ZXhHdWFyZCAgYUd1YXJkKCBHZXRDaGFydE11dGV4KCkgKTsKICAgIGlmICghYkRpc3Bvc2VkICYmIHJ4TGlzdGVuZXIuaXMoKSkKICAgICAgICBhTW9kaWZ5TGlzdGVuZXJzLmFkZEludGVyZmFjZSggcnhMaXN0ZW5lciApOwp9CgoKdm9pZCBTQUxfQ0FMTCBTd0NoYXJ0RGF0YVNlcXVlbmNlOjpyZW1vdmVNb2RpZnlMaXN0ZW5lcigKICAgICAgICBjb25zdCB1bm86OlJlZmVyZW5jZTwgdXRpbDo6WE1vZGlmeUxpc3RlbmVyID4mIHJ4TGlzdGVuZXIgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgb3NsOjpNdXRleEd1YXJkICBhR3VhcmQoIEdldENoYXJ0TXV0ZXgoKSApOwogICAgaWYgKCFiRGlzcG9zZWQgJiYgcnhMaXN0ZW5lci5pcygpKQogICAgICAgIGFNb2RpZnlMaXN0ZW5lcnMucmVtb3ZlSW50ZXJmYWNlKCByeExpc3RlbmVyICk7Cn0KCgp2b2lkIFNBTF9DQUxMIFN3Q2hhcnREYXRhU2VxdWVuY2U6OmRpc3Bvc2luZyggY29uc3QgbGFuZzo6RXZlbnRPYmplY3QmIHJTb3VyY2UgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgaWYgKGJEaXNwb3NlZCkKICAgICAgICB0aHJvdyBsYW5nOjpEaXNwb3NlZEV4Y2VwdGlvbigpOwogICAgaWYgKHJTb3VyY2UuU291cmNlID09IHhEYXRhUHJvdmlkZXIpCiAgICB7CiAgICAgICAgcERhdGFQcm92aWRlciA9IDA7CiAgICAgICAgeERhdGFQcm92aWRlci5jbGVhcigpOwogICAgfQp9CgoKdm9pZCBTQUxfQ0FMTCBTd0NoYXJ0RGF0YVNlcXVlbmNlOjpkaXNwb3NlKCAgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgc2FsX0Jvb2wgYk11c3REaXNwb3NlKCBzYWxfRmFsc2UgKTsKCXsKCQlvc2w6Ok11dGV4R3VhcmQgIGFHdWFyZCggR2V0Q2hhcnRNdXRleCgpICk7CiAgICAgICAgYk11c3REaXNwb3NlID0gIWJEaXNwb3NlZDsKCQlpZiAoIWJEaXNwb3NlZCkKCQkJYkRpc3Bvc2VkID0gc2FsX1RydWU7Cgl9CiAgICBpZiAoYk11c3REaXNwb3NlKQogICAgewogICAgICAgIGJEaXNwb3NlZCA9IHNhbF9UcnVlOwogICAgICAgIGlmIChwRGF0YVByb3ZpZGVyKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgU3dUYWJsZSogcFRhYmxlID0gU3dUYWJsZTo6RmluZFRhYmxlKCBHZXRGcm1GbXQoKSApOwogICAgICAgICAgICBpZiAocFRhYmxlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYRGF0YVNlcXVlbmNlID4geFJlZiggZHluYW1pY19jYXN0PCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgKiA+KHRoaXMpLCB1bm86OlVOT19RVUVSWSApOwogICAgICAgICAgICAgICAgcERhdGFQcm92aWRlci0+UmVtb3ZlRGF0YVNlcXVlbmNlKCAqcFRhYmxlLCB4UmVmICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBEQkdfRVJST1IoICJ0YWJsZSBtaXNzaW5nIiApOwogICAgICAgICAgICB9CgkJCgkJLy9Db21tZW50OiBUaGUgYnVnIGlzIGNyYXNoZWQgZm9yIGFuIGV4Y2VwdGlvbiB0aHJldyBvdXQgaW4gU3dDaGFyRGF0YVNlcXVlbmNlOjpzZXRNb2RpZmllZCgpLCBqdXN0IGJlY2F1c2UKCQkvL3RoZSBTd0NoYXJEYXRhU2VxdWVuY2Ugb2JqZWN0IGhhcyBiZWVuIGRpc3Bvc2VkLiBBY3R1YWxseSwgdGhlIGZvcm1lciBkZXNpZ24gb2YgU3dDbGllbnQgd2lsbCBkaXNiYW5kIAoJCS8vaXRzZWxmIGZyb20gdGhlIG5vdGlmaWNhdGlvbiBsaXN0IGluIGl0cyBkZXN0cnVjdGlvbi4gQnV0IHRoZSBTd0NoYXJEYXRhU2VxZW5jZSB3b250IGJlIGRlc3RydWN0ZWQgYnV0IGRpc3Bvc2VkCgkJLy9pbiBjb2RlICh0aGUgZGF0YSBtZW1iZXIgU3dDaGFydERhdGFTZXF1ZW5jZTo6YkRpc3Bvc2VkIHdpbGwgYmUgc2V0IHRvIFRSVUUpLCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gY2xpZW50CgkJLy9hbmQgbW9kaWZpY2F0aW9uIGFyZSBub3QgcmVsZWFzZWQuIFNvIGFueSBub3RpZmljYXRpb24gZnJvbSBtb2RpZnkgb2JqZWN0IHdpbGwgbGVhZCBzYWlkIGV4Y2VwdGlvbiB0aHJldyBvdXQuCgkJLy9SZWNvcnJlY3QgdGhlIGxvZ2ljIG9mIGNvZGUgaW4gU3dDaGFydERhdGFTZXF1ZW5jZTo6RGlzcG9zZSgpLCByZWxlYXNlIHRoZSByZWxhdGlvbnNoaXAgaW5zaWRlLi4uCgkJU3dNb2RpZnkqIHBSZWdpc3RlcmVkSW4gPSBHZXRSZWdpc3RlcmVkSW5Ob25Db25zdCgpOwoJCWlmIChwUmVnaXN0ZXJlZEluICYmIHBSZWdpc3RlcmVkSW4tPkdldERlcGVuZHMoKSkKCQl7CgkJCXBSZWdpc3RlcmVkSW4tPlJlbW92ZSh0aGlzKTsKCQkJcFRibENyc3IgPSBOVUxMOwoJCX0KCQkKICAgICAgICB9CgogICAgICAgIC8vIHJlcXVpcmUgbGlzdGVuZXJzIHRvIHJlbGVhc2UgcmVmZXJlbmNlcyB0byB0aGlzIG9iamVjdAogICAgICAgIGxhbmc6OkV2ZW50T2JqZWN0IGFFdnRPYmooIGR5bmFtaWNfY2FzdDwgY2hhcnQyOjpkYXRhOjpYRGF0YVNlcXVlbmNlICogPih0aGlzKSApOwogICAgICAgIGFNb2RpZnlMaXN0ZW5lcnMuZGlzcG9zZUFuZENsZWFyKCBhRXZ0T2JqICk7CiAgICAgICAgYUV2dExpc3RlbmVycy5kaXNwb3NlQW5kQ2xlYXIoIGFFdnRPYmogKTsKICAgIH0KfQoKCnZvaWQgU0FMX0NBTEwgU3dDaGFydERhdGFTZXF1ZW5jZTo6YWRkRXZlbnRMaXN0ZW5lcigKICAgICAgICBjb25zdCB1bm86OlJlZmVyZW5jZTwgbGFuZzo6WEV2ZW50TGlzdGVuZXIgPiYgcnhMaXN0ZW5lciApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICBvc2w6Ok11dGV4R3VhcmQgIGFHdWFyZCggR2V0Q2hhcnRNdXRleCgpICk7CiAgICBpZiAoIWJEaXNwb3NlZCAmJiByeExpc3RlbmVyLmlzKCkpCiAgICAgICAgYUV2dExpc3RlbmVycy5hZGRJbnRlcmZhY2UoIHJ4TGlzdGVuZXIgKTsKfQoKCnZvaWQgU0FMX0NBTEwgU3dDaGFydERhdGFTZXF1ZW5jZTo6cmVtb3ZlRXZlbnRMaXN0ZW5lcigKICAgICAgICBjb25zdCB1bm86OlJlZmVyZW5jZTwgbGFuZzo6WEV2ZW50TGlzdGVuZXIgPiYgcnhMaXN0ZW5lciApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICBvc2w6Ok11dGV4R3VhcmQgIGFHdWFyZCggR2V0Q2hhcnRNdXRleCgpICk7CiAgICBpZiAoIWJEaXNwb3NlZCAmJiByeExpc3RlbmVyLmlzKCkpCiAgICAgICAgYUV2dExpc3RlbmVycy5yZW1vdmVJbnRlcmZhY2UoIHJ4TGlzdGVuZXIgKTsKfQoKCnNhbF9Cb29sIFN3Q2hhcnREYXRhU2VxdWVuY2U6OkRlbGV0ZUJveCggY29uc3QgU3dUYWJsZUJveCAmckJveCApCnsKCWlmIChiRGlzcG9zZWQpCgkJdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCiNpZiBPU0xfREVCVUdfTEVWRUwgPiAxCglTdHJpbmcgYUJveE5hbWUoIHJCb3guR2V0TmFtZSgpICk7CiNlbmRpZgoKICAgIC8vIHRvIGJlIHNldCBpZiB0aGUgbGFzdCBib3ggb2YgdGhlIGRhdGEtc2VxdWVuY2Ugd2FzIHJlbW92ZWQgaGVyZQogICAgc2FsX0Jvb2wgYk5vd0VtcHR5ID0gc2FsX0ZhbHNlOwoKICAgIC8vIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBjdXJzb3IgZ2V0cyBhZmZlY3RlZCAoaS5lLiB0aGV3IGJveCB3aGVyZSBpdCBpcyBsb2NhdGVkCiAgICAvLyBpbiBnZXRzIHJlbW92ZWQpIHdlIG5lZWQgdG8gbW92ZSBpdCBiZWZvcmUgdGhhdC4uLiAob3RoZXJ3aXNlIGl0IGRvZXMgbm90IG5lZWQgdG8gY2hhbmdlKQogICAgLy8KICAgIGNvbnN0IFN3U3RhcnROb2RlKiBwUG9pbnRTdGFydE5vZGUgPSBwVGJsQ3Jzci0+R2V0UG9pbnQoKS0+bk5vZGUuR2V0Tm9kZSgpLkZpbmRUYWJsZUJveFN0YXJ0Tm9kZSgpOwogICAgY29uc3QgU3dTdGFydE5vZGUqIHBNYXJrU3RhcnROb2RlICA9IHBUYmxDcnNyLT5HZXRNYXJrKCktPm5Ob2RlLkdldE5vZGUoKS5GaW5kVGFibGVCb3hTdGFydE5vZGUoKTsKICAgIC8vCiAgICBpZiAoIXBUYmxDcnNyLT5IYXNNYXJrKCkgfHwgKHBQb2ludFN0YXJ0Tm9kZSA9PSByQm94LkdldFN0dE5kKCkgICYmICBwTWFya1N0YXJ0Tm9kZSA9PSByQm94LkdldFN0dE5kKCkpKQogICAgewogICAgICAgIGJOb3dFbXB0eSA9IHNhbF9UcnVlOwogICAgfQogICAgZWxzZSBpZiAocFBvaW50U3RhcnROb2RlID09IHJCb3guR2V0U3R0TmQoKSAgfHwgIHBNYXJrU3RhcnROb2RlID09IHJCb3guR2V0U3R0TmQoKSkKICAgIHsKICAgICAgICBzYWxfSW50MzIgblBvaW50Um93ID0gLTEsIG5Qb2ludENvbCA9IC0xOwogICAgICAgIHNhbF9JbnQzMiBuTWFya1JvdyAgPSAtMSwgbk1hcmtDb2wgID0gLTE7CiAgICAgICAgY29uc3QgU3dUYWJsZSogcFRhYmxlID0gU3dUYWJsZTo6RmluZFRhYmxlKCBHZXRGcm1GbXQoKSApOwogICAgICAgIFN0cmluZyBhUG9pbnRDZWxsTmFtZSggcFRhYmxlLT5HZXRUYmxCb3goIHBQb2ludFN0YXJ0Tm9kZS0+R2V0SW5kZXgoKSApLT5HZXROYW1lKCkgKTsKCQlTdHJpbmcgYU1hcmtDZWxsTmFtZSggcFRhYmxlLT5HZXRUYmxCb3goIHBNYXJrU3RhcnROb2RlLT5HZXRJbmRleCgpICktPkdldE5hbWUoKSApOwoKICAgICAgICBsY2xfR2V0Q2VsbFBvc2l0aW9uKCBhUG9pbnRDZWxsTmFtZSwgblBvaW50Q29sLCBuUG9pbnRSb3cgKTsKICAgICAgICBsY2xfR2V0Q2VsbFBvc2l0aW9uKCBhTWFya0NlbGxOYW1lLCAgbk1hcmtDb2wsICBuTWFya1JvdyApOwogICAgICAgIERCR19BU1NFUlQoIG5Qb2ludFJvdyA+PSAwICYmIG5Qb2ludENvbCA+PSAwLCAiaW52YWxpZCByb3cgYW5kIGNvbCIgKTsKICAgICAgICBEQkdfQVNTRVJUKCBuTWFya1JvdyA+PSAwICYmIG5NYXJrQ29sID49IDAsICJpbnZhbGlkIHJvdyBhbmQgY29sIiApOwoKICAgICAgICAvLyBtb3ZlIHZlcnRpY2FsIG9yIGhvcml6b250YWw/CiAgICAgICAgREJHX0FTU0VSVCggblBvaW50Um93ID09IG5NYXJrUm93IHx8IG5Qb2ludENvbCA9PSBuTWFya0NvbCwKICAgICAgICAgICAgICAgICJyb3cvY29sIGluZGljZXMgbm90IG1hdGNoaW5nIiApOwogICAgICAgIERCR19BU1NFUlQoIG5Qb2ludFJvdyAhPSBuTWFya1JvdyB8fCBuUG9pbnRDb2wgIT0gbk1hcmtDb2wsCiAgICAgICAgICAgICAgICAicG9pbnQgYW5kIG1hcmsgYXJlIGlkZW50aWNhbCIgKTsKICAgICAgICBzYWxfQm9vbCBiTW92ZVZlcnRpY2FsICAgICAgPSAoblBvaW50Q29sID09IG5NYXJrQ29sKTsKICAgICAgICBzYWxfQm9vbCBiTW92ZUhvcml6b250YWwgICAgPSAoblBvaW50Um93ID09IG5NYXJrUm93KTsKCiAgICAgICAgLy8gZ2V0IG1vdmVtZW50IGRpcmVjdGlvbgogICAgICAgIHNhbF9Cb29sIGJNb3ZlTGVmdCAgPSBzYWxfRmFsc2U7ICAgIC8vIG1vdmUgbGVmdCBvciByaWdodD8KICAgICAgICBzYWxfQm9vbCBiTW92ZVVwICAgID0gc2FsX0ZhbHNlOyAgICAvLyBtb3ZlIHVwIG9yIGRvd24/CiAgICAgICAgaWYgKGJNb3ZlVmVydGljYWwpCiAgICAgICAgewogICAgICAgICAgICBpZiAocFBvaW50U3RhcnROb2RlID09IHJCb3guR2V0U3R0TmQoKSkgLy8gbW92ZSBwb2ludD8KICAgICAgICAgICAgICAgIGJNb3ZlVXAgPSBuUG9pbnRSb3cgPiBuTWFya1JvdzsKICAgICAgICAgICAgZWxzZSAgICAvLyBtb3ZlIG1hcmsKICAgICAgICAgICAgICAgIGJNb3ZlVXAgPSBuTWFya1JvdyA+IG5Qb2ludFJvdzsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoYk1vdmVIb3Jpem9udGFsKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHBQb2ludFN0YXJ0Tm9kZSA9PSByQm94LkdldFN0dE5kKCkpIC8vIG1vdmUgcG9pbnQ/CiAgICAgICAgICAgICAgICBiTW92ZUxlZnQgPSBuUG9pbnRDb2wgPiBuTWFya0NvbDsKICAgICAgICAgICAgZWxzZSAgICAvLyBtb3ZlIG1hcmsKICAgICAgICAgICAgICAgIGJNb3ZlTGVmdCA9IG5NYXJrQ29sID4gblBvaW50Q29sOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgREJHX0VSUk9SKCAibmVpdGhlciB2ZXJ0aWNhbCBub3IgaG9yaXpvbnRhbCBtb3ZlbWVudCIgKTsKICAgICAgICB9CgogICAgICAgIC8vIGdldCBuZXcgYm94IChwb3NpdGlvbikgdG8gdXNlLi4uCiAgICAgICAgc2FsX0ludDMyIG5Sb3cgPSAocFBvaW50U3RhcnROb2RlID09IHJCb3guR2V0U3R0TmQoKSkgPyBuUG9pbnRSb3cgOiBuTWFya1JvdzsKICAgICAgICBzYWxfSW50MzIgbkNvbCA9IChwUG9pbnRTdGFydE5vZGUgPT0gckJveC5HZXRTdHROZCgpKSA/IG5Qb2ludENvbCA6IG5NYXJrQ29sOwoJCWlmIChiTW92ZVZlcnRpY2FsKQoJCQluUm93ICs9IGJNb3ZlVXAgPyAtMSA6ICsxOwoJCWlmIChiTW92ZUhvcml6b250YWwpCgkJCW5Db2wgKz0gYk1vdmVMZWZ0ID8gLTEgOiArMTsKICAgICAgICBTdHJpbmcgYU5ld0NlbGxOYW1lID0gbGNsX0dldENlbGxOYW1lKCBuQ29sLCBuUm93ICk7CiAgICAgICAgU3dUYWJsZUJveCogcE5ld0JveCA9IChTd1RhYmxlQm94KikgcFRhYmxlLT5HZXRUYmxCb3goIGFOZXdDZWxsTmFtZSApOwoKICAgICAgICBpZiAocE5ld0JveCkgICAgLy8gc2V0IG5ldyBwb3NpdGlvbiAoY2VsbCByYW5nZSkgdG8gdXNlCiAgICAgICAgewogICAgICAgICAgICAvLyBTbyBlcmjkbHQgbWFuIGRlbiBlcnN0ZW4gSW5oYWx0c25vZGUgaW4gZWluZXIgZ2VnZWJlbmVuIFplbGxlOgogICAgICAgICAgICAvLyBadW7kY2hzdCBlaW5lbiBTd05vZGVJbmRleCBhdWYgZGVuIE5vZGUgaGludGVyIGRlbSBTd1N0YXJ0Tm9kZSBkZXIgQm94Li4uCiAgICAgICAgICAgIFN3Tm9kZUluZGV4IGFJZHgoICpwTmV3Qm94LT5HZXRTdHROZCgpLCArMSApOwogICAgICAgICAgICAvLyBEaWVzIGthbm4gZWluIFN3Q250bnROb2RlIHNlaW4sIGthbm4gYWJlciBhdWNoIGVpbiBUYWJlbGxlbiBvZGVyIFNlY3Rpb25ub2RlIHNlaW4sCiAgICAgICAgICAgIC8vIGRlc2hhbGIgZGFzIEdvTmV4dDsKICAgICAgICAgICAgU3dDbnRudE5vZGUgKnBDTmQgPSBhSWR4LkdldE5vZGUoKS5HZXRDbnRudE5vZGUoKTsKICAgICAgICAgICAgaWYgKCFwQ05kKQogICAgICAgICAgICAgICAgcENOZCA9IEdldEZybUZtdCgpLT5HZXREb2MoKS0+R2V0Tm9kZXMoKS5Hb05leHQoICZhSWR4ICk7CiAgICAgICAgICAgIC8vdW5kIGRhbWl0IGthbm4gbWFuIHouQi4gZWluZSBTd1Bvc2l0aW9uIGVyemV1Z2VuOgogICAgICAgICAgICBTd1Bvc2l0aW9uIGFOZXdQb3MoICpwQ05kICk7ICAgLy8gbmV3IHBvc2l0aW9uIHRvIGJldXNlZCB3aXRoIGN1cnNvcgoKICAgICAgICAgICAgLy8gaWYgdGhlIG1hcmsgaXMgdG8gYmUgY2hhbmdlZCBtYWtlIHN1cmUgdGhlcmUgaXMgb25lLi4uCiAgICAgICAgICAgIGlmIChwTWFya1N0YXJ0Tm9kZSA9PSByQm94LkdldFN0dE5kKCkgJiYgIXBUYmxDcnNyLT5IYXNNYXJrKCkpCiAgICAgICAgICAgICAgICBwVGJsQ3Jzci0+U2V0TWFyaygpOwoKICAgICAgICAgICAgLy8gc2V0IGN1cnNvciB0byBuZXcgcG9zaXRpb24uLi4KICAgICAgICAgICAgU3dQb3NpdGlvbiAqcFBvcyA9IChwUG9pbnRTdGFydE5vZGUgPT0gckJveC5HZXRTdHROZCgpKSA/CiAgICAgICAgICAgICAgICAgICAgICAgIHBUYmxDcnNyLT5HZXRQb2ludCgpIDogcFRibENyc3ItPkdldE1hcmsoKTsKICAgICAgICAgICAgaWYgKHBQb3MpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHBQb3MtPm5Ob2RlICAgICA9IGFOZXdQb3Mubk5vZGU7CiAgICAgICAgICAgICAgICBwUG9zLT5uQ29udGVudCAgPSBhTmV3UG9zLm5Db250ZW50OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgREJHX0VSUk9SKCAibmVpdGhlciBwb2ludCBub3IgbWFyayBhdmFpbGFibGUgZm9yIGNoYW5nZSIgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgREJHX0VSUk9SKCAiZmFpbGVkIHRvIGdldCBwb3NpdGlvbiIgKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIGJOb3dFbXB0eTsKfQoKCnZvaWQgU3dDaGFydERhdGFTZXF1ZW5jZTo6RmlsbFJhbmdlRGVzYyggU3dSYW5nZURlc2NyaXB0b3IgJnJSYW5nZURlc2MgKSBjb25zdAp7CiAgICBTd0ZybUZtdCogcFRibEZtdCA9IEdldEZybUZtdCgpOwogICAgaWYocFRibEZtdCkKICAgIHsKICAgICAgICBTd1RhYmxlKiBwVGFibGUgPSBTd1RhYmxlOjpGaW5kVGFibGUoIHBUYmxGbXQgKTsKICAgICAgICBpZighcFRhYmxlLT5Jc1RibENvbXBsZXgoKSkKICAgICAgICB7CiAgICAgICAgICAgIEZpbGxSYW5nZURlc2NyaXB0b3IoIHJSYW5nZURlc2MsIEdldENlbGxSYW5nZU5hbWUoICpwVGJsRm10LCAqcFRibENyc3IgKSApOwogICAgICAgIH0KICAgIH0KfQoKLyoqClN3Q2hhcnREYXRhU2VxdWVuY2U6OkV4dGVuZFRvCgpleHRlbmRzIHRoZSBkYXRhLXNlcXVlbmNlIGJ5IG5ldyBjZWxscyBhZGRlZCBhdCB0aGUgZW5kIG9mIHRoZSBkaXJlY3Rpb24KdGhlIGRhdGEtc2VxdWVuY2UgcG9pbnRzIHRvLgpJZiB0aGUgY2VsbHMgYXJlIGFscmVhZHkgd2l0aGluIHRoZSByYW5nZSBvZiB0aGUgc2VxdWVuY2Ugbm90aGluZyBuZWVkcwp0byBiZSBkb25lLgpJZiB0aGUgY2VsbHMgYXJlIGJleW9uZCB0aGUgZW5kIG9mIHRoZSBzZXF1ZW5jZSAoYXJlIG5vdCBhZGphY2VudCB0byB0aGUKY3VycmVudCBsYXN0IGNlbGwpIG5vdGhpbmcgY2FuIGJlIGRvbmUuIE9ubHkgaWYgdGhlIGNlbGxzIGFyZSBhZGphY2VudCB0bwp0aGUgbGFzdCBjZWxsIHRoZXkgY2FuIGJlIGFkZGVkLgoKQHJldHVybnMgICAgIHRydWUgaWYgdGhlIGRhdGEtc2VxdWVuY2Ugd2FzIGNoYW5nZWQuCkBwYXJhbSAgICAgICBiRXh0ZW5kQ29scwogICAgICAgICAgICAgc3BlY2lmaWVzIGlmIGNvbHVtbnMgb3Igcm93cyBhcmUgdG8gYmUgZXh0ZW5kZWQKQHBhcmFtICAgICAgIG5GaXJzdE5ldwogICAgICAgICAgICAgaW5kZXggb2YgZmlyc3QgbmV3IHJvdy9jb2wgdG8gYmUgaW5jbHVkZWQgaW4gZGF0YS1zZXF1ZW5jZQpAcGFyYW0gICAgICAgbkxhc3ROZXcKICAgICAgICAgICAgIGluZGV4IG9mIGxhc3QgbmV3IHJvdy9jb2wgdG8gYmUgaW5jbHVkZWQgaW4gZGF0YS1zZXF1ZW5jZQoqLwpib29sIFN3Q2hhcnREYXRhU2VxdWVuY2U6OkV4dGVuZFRvKCBib29sIGJFeHRlbmRDb2wsCiAgICAgICAgc2FsX0ludDMyIG5GaXJzdE5ldywgc2FsX0ludDMyIG5Db3VudCApCnsKICAgIGJvb2wgYkNoYW5nZWQgPSBmYWxzZTsKCiAgICBTd1Vub1RhYmxlQ3JzciogcFVub1RibENyc3IgPSBkeW5hbWljX2Nhc3Q8U3dVbm9UYWJsZUNyc3IqPihwVGJsQ3Jzcik7CiAgICAvL3BVbm9UYmxDcnNyLT5NYWtlQm94U2VscygpOwoKICAgIGNvbnN0IFN3U3RhcnROb2RlICpwU3RhcnROZCAgPSAwOwogICAgY29uc3QgU3dUYWJsZUJveCAgKnBTdGFydEJveCA9IDA7CiAgICBjb25zdCBTd1RhYmxlQm94ICAqcEVuZEJveCAgID0gMDsKCiAgICBjb25zdCBTd1RhYmxlKiBwVGFibGUgPSBTd1RhYmxlOjpGaW5kVGFibGUoIEdldEZybUZtdCgpICk7CglEQkdfQVNTRVJUKCAhcFRhYmxlLT5Jc1RibENvbXBsZXgoKSwgInRhYmxlIHRvbyBjb21wbGV4IiApOwoJaWYgKG5Db3VudCA8IDEgfHwgbkZpcnN0TmV3IDwgMCB8fCBwVGFibGUtPklzVGJsQ29tcGxleCgpKQoJCXJldHVybiBmYWxzZTsKCgkvLwoJLy8gZ2V0IHJhbmdlIGRlc2NyaXB0b3IgKGNlbGwgcmFuZ2UpIGZvciBjdXJyZW50IGRhdGEtc2VxdWVuY2UKCS8vCiAgICBwU3RhcnROZCA9IHBVbm9UYmxDcnNyLT5HZXRQb2ludCgpLT5uTm9kZS5HZXROb2RlKCkuRmluZFRhYmxlQm94U3RhcnROb2RlKCk7CiAgICBwRW5kQm94ID0gcFRhYmxlLT5HZXRUYmxCb3goIHBTdGFydE5kLT5HZXRJbmRleCgpICk7CiAgICBjb25zdCBTdHJpbmcgYUVuZEJveCggcEVuZEJveC0+R2V0TmFtZSgpICk7CgkvLwogICAgcFN0YXJ0TmQgPSBwVW5vVGJsQ3Jzci0+R2V0TWFyaygpLT5uTm9kZS5HZXROb2RlKCkuRmluZFRhYmxlQm94U3RhcnROb2RlKCk7CiAgICBwU3RhcnRCb3ggPSBwVGFibGUtPkdldFRibEJveCggcFN0YXJ0TmQtPkdldEluZGV4KCkgKTsKICAgIGNvbnN0IFN0cmluZyBhU3RhcnRCb3goIHBTdGFydEJveC0+R2V0TmFtZSgpICk7CgkvLwogICAgU3RyaW5nIGFDZWxsUmFuZ2UoIGFTdGFydEJveCApOyAgICAgLy8gbm90ZSB0aGF0IGNlbGwgcmFuZ2UgaGVyZSB0YWtlcyB0aGUgbmV3bHkgYWRkZWQgcm93cy9jb2xzIGFscmVhZHkgaW50byBhY2NvdW50CiAgICBhQ2VsbFJhbmdlLkFwcGVuZEFzY2lpKCAiOiIgKTsKICAgIGFDZWxsUmFuZ2UgKz0gYUVuZEJveDsKICAgIFN3UmFuZ2VEZXNjcmlwdG9yIGFEZXNjOwogICAgRmlsbFJhbmdlRGVzY3JpcHRvciggYURlc2MsIGFDZWxsUmFuZ2UgKTsKCiAgICBTdHJpbmcgYU5ld1N0YXJ0Q2VsbDsKICAgIFN0cmluZyBhTmV3RW5kQ2VsbDsKICAgIGlmIChiRXh0ZW5kQ29sICYmIGFEZXNjLm5Cb3R0b20gKyAxID09IG5GaXJzdE5ldykKICAgIHsKICAgICAgICAvLyBuZXcgY29sdW1uIGNlbGxzIGFkamFjZW50IHRvIHRoZSBib3R0b20gb2YgdGhlCgkJLy8gY3VycmVudCBkYXRhLXNlcXVlbmNlIHRvIGJlIGFkZGVkLi4uCiAgICAgICAgREJHX0FTU0VSVCggYURlc2MubkxlZnQgPT0gYURlc2MublJpZ2h0LCAiZGF0YS1zZXF1ZW5jZSBpcyBub3QgYSBjb2x1bW4iICk7CiAgICAgICAgYU5ld1N0YXJ0Q2VsbCA9IGxjbF9HZXRDZWxsTmFtZShhRGVzYy5uTGVmdCwgIGFEZXNjLm5Ub3ApOwogICAgICAgIGFOZXdFbmRDZWxsICAgPSBsY2xfR2V0Q2VsbE5hbWUoYURlc2MublJpZ2h0LCBhRGVzYy5uQm90dG9tICsgbkNvdW50KTsKCQliQ2hhbmdlZCA9IHRydWU7CiAgICB9CiAgICBlbHNlIGlmIChiRXh0ZW5kQ29sICYmIGFEZXNjLm5Ub3AgLSBuQ291bnQgPT0gbkZpcnN0TmV3KQogICAgewogICAgICAgIC8vIG5ldyBjb2x1bW4gY2VsbHMgYWRqYWNlbnQgdG8gdGhlIHRvcCBvZiB0aGUKCQkvLyBjdXJyZW50IGRhdGEtc2VxdWVuY2UgdG8gYmUgYWRkZWQuLi4KICAgICAgICBEQkdfQVNTRVJUKCBhRGVzYy5uTGVmdCA9PSBhRGVzYy5uUmlnaHQsICJkYXRhLXNlcXVlbmNlIGlzIG5vdCBhIGNvbHVtbiIgKTsKICAgICAgICBhTmV3U3RhcnRDZWxsID0gbGNsX0dldENlbGxOYW1lKGFEZXNjLm5MZWZ0LCAgYURlc2MublRvcCAtIG5Db3VudCk7CiAgICAgICAgYU5ld0VuZENlbGwgICA9IGxjbF9HZXRDZWxsTmFtZShhRGVzYy5uUmlnaHQsIGFEZXNjLm5Cb3R0b20pOwoJCWJDaGFuZ2VkID0gdHJ1ZTsKICAgIH0KICAgIGVsc2UgaWYgKCFiRXh0ZW5kQ29sICYmIGFEZXNjLm5SaWdodCArIDEgPT0gbkZpcnN0TmV3KQogICAgewogICAgICAgIC8vIG5ldyByb3cgY2VsbHMgYWRqYWNlbnQgdG8gdGhlIHJpZ2h0IG9mIHRoZQoJCS8vIGN1cnJlbnQgZGF0YS1zZXF1ZW5jZSB0byBiZSBhZGRlZC4uLgogICAgICAgIERCR19BU1NFUlQoIGFEZXNjLm5Ub3AgPT0gYURlc2MubkJvdHRvbSwgImRhdGEtc2VxdWVuY2UgaXMgbm90IGEgcm93IiApOwogICAgICAgIGFOZXdTdGFydENlbGwgPSBsY2xfR2V0Q2VsbE5hbWUoYURlc2MubkxlZnQsIGFEZXNjLm5Ub3ApOwogICAgICAgIGFOZXdFbmRDZWxsICAgPSBsY2xfR2V0Q2VsbE5hbWUoYURlc2MublJpZ2h0ICsgbkNvdW50LCBhRGVzYy5uQm90dG9tKTsKCQliQ2hhbmdlZCA9IHRydWU7CiAgICB9CiAgICBlbHNlIGlmICghYkV4dGVuZENvbCAmJiBhRGVzYy5uTGVmdCAtIG5Db3VudCA9PSBuRmlyc3ROZXcpCiAgICB7CiAgICAgICAgLy8gbmV3IHJvdyBjZWxscyBhZGphY2VudCB0byB0aGUgbGVmdCBvZiB0aGUKCQkvLyBjdXJyZW50IGRhdGEtc2VxdWVuY2UgdG8gYmUgYWRkZWQuLi4KICAgICAgICBEQkdfQVNTRVJUKCBhRGVzYy5uVG9wID09IGFEZXNjLm5Cb3R0b20sICJkYXRhLXNlcXVlbmNlIGlzIG5vdCBhIHJvdyIgKTsKICAgICAgICBhTmV3U3RhcnRDZWxsID0gbGNsX0dldENlbGxOYW1lKGFEZXNjLm5MZWZ0IC0gbkNvdW50LCBhRGVzYy5uVG9wKTsKICAgICAgICBhTmV3RW5kQ2VsbCAgID0gbGNsX0dldENlbGxOYW1lKGFEZXNjLm5SaWdodCwgYURlc2MubkJvdHRvbSk7CgkJYkNoYW5nZWQgPSB0cnVlOwogICAgfQoKCWlmIChiQ2hhbmdlZCkKCXsKCQkvLyBtb3ZlIHRhYmxlIGN1cnNvciB0byBuZXcgc3RhcnQgYW5kIGVuZCBvZiBkYXRhLXNlcXVlbmNlCiAgICAgICAgY29uc3QgU3dUYWJsZUJveCAqcE5ld1N0YXJ0Qm94ID0gcFRhYmxlLT5HZXRUYmxCb3goIGFOZXdTdGFydENlbGwgKTsKICAgICAgICBjb25zdCBTd1RhYmxlQm94ICpwTmV3RW5kQm94ICAgPSBwVGFibGUtPkdldFRibEJveCggYU5ld0VuZENlbGwgKTsKICAgICAgICBwVW5vVGJsQ3Jzci0+U2V0TWFyaygpOwogICAgICAgIHBVbm9UYmxDcnNyLT5HZXRQb2ludCgpLT5uTm9kZSA9ICpwTmV3RW5kQm94LT5HZXRTdHROZCgpOwogICAgICAgIHBVbm9UYmxDcnNyLT5HZXRNYXJrKCktPm5Ob2RlICA9ICpwTmV3U3RhcnRCb3gtPkdldFN0dE5kKCk7CiAgICAgICAgcFVub1RibENyc3ItPk1vdmUoIGZuTW92ZUZvcndhcmQsIGZuR29Ob2RlICk7CiAgICAgICAgcFVub1RibENyc3ItPk1ha2VCb3hTZWxzKCk7Cgl9CgogICAgcmV0dXJuIGJDaGFuZ2VkOwp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgpTd0NoYXJ0TGFiZWxlZERhdGFTZXF1ZW5jZTo6U3dDaGFydExhYmVsZWREYXRhU2VxdWVuY2UoKSA6CiAgICBhRXZ0TGlzdGVuZXJzKCBHZXRDaGFydE11dGV4KCkgKSwKICAgIGFNb2RpZnlMaXN0ZW5lcnMoIEdldENoYXJ0TXV0ZXgoKSApCnsKICAgIGJEaXNwb3NlZCA9IHNhbF9GYWxzZTsKfQoKClN3Q2hhcnRMYWJlbGVkRGF0YVNlcXVlbmNlOjp+U3dDaGFydExhYmVsZWREYXRhU2VxdWVuY2UoKQp7Cn0KCgp1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYRGF0YVNlcXVlbmNlID4gU0FMX0NBTEwgU3dDaGFydExhYmVsZWREYXRhU2VxdWVuY2U6OmdldFZhbHVlcyggICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIHZvczo6T0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwogICAgaWYgKGJEaXNwb3NlZCkKICAgICAgICB0aHJvdyBsYW5nOjpEaXNwb3NlZEV4Y2VwdGlvbigpOwogICAgcmV0dXJuIHhEYXRhOwp9CgoKdm9pZCBTd0NoYXJ0TGFiZWxlZERhdGFTZXF1ZW5jZTo6U2V0RGF0YVNlcXVlbmNlKAoJCXVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPiYgcnhEZXN0LAoJCWNvbnN0IHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPiYgcnhTb3VyY2UpCnsKICAgIHVubzo6UmVmZXJlbmNlPCB1dGlsOjpYTW9kaWZ5TGlzdGVuZXIgPiAgeE1MKCBkeW5hbWljX2Nhc3Q8IHV0aWw6OlhNb2RpZnlMaXN0ZW5lciogPih0aGlzKSwgdW5vOjpVTk9fUVVFUlkgKTsKICAgIHVubzo6UmVmZXJlbmNlPCBsYW5nOjpYRXZlbnRMaXN0ZW5lciA+ICAgeEVMKCBkeW5hbWljX2Nhc3Q8IGxhbmc6OlhFdmVudExpc3RlbmVyKiA+KHRoaXMpLCB1bm86OlVOT19RVUVSWSApOwoKICAgIC8vIHN0b3AgbGlzdGVuaW5nIHRvIG9sZCBkYXRhLXNlcXVlbmNlCiAgICB1bm86OlJlZmVyZW5jZTwgdXRpbDo6WE1vZGlmeUJyb2FkY2FzdGVyID4geE1CKCByeERlc3QsIHVubzo6VU5PX1FVRVJZICk7CiAgICBpZiAoeE1CLmlzKCkpCiAgICAgICAgeE1CLT5yZW1vdmVNb2RpZnlMaXN0ZW5lciggeE1MICk7CiAgICB1bm86OlJlZmVyZW5jZTwgbGFuZzo6WENvbXBvbmVudCA+IHhDKCByeERlc3QsIHVubzo6VU5PX1FVRVJZICk7CiAgICBpZiAoeEMuaXMoKSkKICAgICAgICB4Qy0+cmVtb3ZlRXZlbnRMaXN0ZW5lciggeEVMICk7CgogICAgcnhEZXN0ID0gcnhTb3VyY2U7CgogICAgLy8gc3RhcnQgbGlzdGVuaW5nIHRvIG5ldyBkYXRhLXNlcXVlbmNlCiAgICB4QyA9IHVubzo6UmVmZXJlbmNlPCBsYW5nOjpYQ29tcG9uZW50ID4oIHJ4RGVzdCwgdW5vOjpVTk9fUVVFUlkgKTsKICAgIGlmICh4Qy5pcygpKQogICAgICAgIHhDLT5hZGRFdmVudExpc3RlbmVyKCB4RUwgKTsKICAgIHhNQiA9IHVubzo6UmVmZXJlbmNlPCB1dGlsOjpYTW9kaWZ5QnJvYWRjYXN0ZXIgPiggcnhEZXN0LCB1bm86OlVOT19RVUVSWSApOwogICAgaWYgKHhNQi5pcygpKQogICAgICAgIHhNQi0+YWRkTW9kaWZ5TGlzdGVuZXIoIHhNTCApOwp9CgoKdm9pZCBTQUxfQ0FMTCBTd0NoYXJ0TGFiZWxlZERhdGFTZXF1ZW5jZTo6c2V0VmFsdWVzKAogICAgICAgIGNvbnN0IHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPiYgcnhTZXF1ZW5jZSApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIGlmIChiRGlzcG9zZWQpCiAgICAgICAgdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCiAgICBpZiAoeERhdGEgIT0gcnhTZXF1ZW5jZSkKICAgIHsKCQlTZXREYXRhU2VxdWVuY2UoIHhEYXRhLCByeFNlcXVlbmNlICk7CiAgICAgICAgLy8gaW5mb3JtIGxpc3RlbmVycyBvZiBjaGFuZ2VzCgkJTGF1bmNoTW9kaWZpZWRFdmVudCggYU1vZGlmeUxpc3RlbmVycywgZHluYW1pY19jYXN0PCBYTW9kaWZ5QnJvYWRjYXN0ZXIgKiA+KHRoaXMpICk7CiAgICB9Cn0KCgp1bm86OlJlZmVyZW5jZTwgY2hhcnQyOjpkYXRhOjpYRGF0YVNlcXVlbmNlID4gU0FMX0NBTEwgU3dDaGFydExhYmVsZWREYXRhU2VxdWVuY2U6OmdldExhYmVsKCAgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgdm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CiAgICBpZiAoYkRpc3Bvc2VkKQogICAgICAgIHRocm93IGxhbmc6OkRpc3Bvc2VkRXhjZXB0aW9uKCk7CiAgICByZXR1cm4geExhYmVsczsKfQoKCnZvaWQgU0FMX0NBTEwgU3dDaGFydExhYmVsZWREYXRhU2VxdWVuY2U6OnNldExhYmVsKAogICAgICAgIGNvbnN0IHVubzo6UmVmZXJlbmNlPCBjaGFydDI6OmRhdGE6OlhEYXRhU2VxdWVuY2UgPiYgcnhTZXF1ZW5jZSApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIGlmIChiRGlzcG9zZWQpCiAgICAgICAgdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCiAgICBpZiAoeExhYmVscyAhPSByeFNlcXVlbmNlKQogICAgewoJCVNldERhdGFTZXF1ZW5jZSggeExhYmVscywgcnhTZXF1ZW5jZSApOwogICAgICAgIC8vIGluZm9ybSBsaXN0ZW5lcnMgb2YgY2hhbmdlcwoJCUxhdW5jaE1vZGlmaWVkRXZlbnQoIGFNb2RpZnlMaXN0ZW5lcnMsIGR5bmFtaWNfY2FzdDwgWE1vZGlmeUJyb2FkY2FzdGVyICogPih0aGlzKSApOwogICAgfQp9CgoKdW5vOjpSZWZlcmVuY2U8IHV0aWw6OlhDbG9uZWFibGUgPiBTQUxfQ0FMTCBTd0NoYXJ0TGFiZWxlZERhdGFTZXF1ZW5jZTo6Y3JlYXRlQ2xvbmUoICApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIGlmIChiRGlzcG9zZWQpCiAgICAgICAgdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCiAgICB1bm86OlJlZmVyZW5jZTwgdXRpbDo6WENsb25lYWJsZSA+IHhSZXM7CgogICAgdW5vOjpSZWZlcmVuY2U8IHV0aWw6OlhDbG9uZWFibGUgPiB4RGF0YUNsb25lYWJsZSggeERhdGEsIHVubzo6VU5PX1FVRVJZICk7CiAgICB1bm86OlJlZmVyZW5jZTwgdXRpbDo6WENsb25lYWJsZSA+IHhMYWJlbHNDbG9uZWFibGUoIHhMYWJlbHMsIHVubzo6VU5PX1FVRVJZICk7CiAgICBTd0NoYXJ0TGFiZWxlZERhdGFTZXF1ZW5jZSAqcFJlcyA9IG5ldyBTd0NoYXJ0TGFiZWxlZERhdGFTZXF1ZW5jZSgpOwogICAgaWYgKHhEYXRhQ2xvbmVhYmxlLmlzKCkpCiAgICB7CiAgICAgICAgdW5vOjpSZWZlcmVuY2U8IGNoYXJ0Mjo6ZGF0YTo6WERhdGFTZXF1ZW5jZSA+IHhEYXRhQ2xvbmUoIHhEYXRhQ2xvbmVhYmxlLT5jcmVhdGVDbG9uZSgpLCB1bm86OlVOT19RVUVSWSApOwogICAgICAgIHBSZXMtPnNldFZhbHVlcyggeERhdGFDbG9uZSApOwogICAgfQoKICAgIGlmICh4TGFiZWxzQ2xvbmVhYmxlLmlzKCkpCiAgICB7CiAgICAgICAgdW5vOjpSZWZlcmVuY2U8IGNoYXJ0Mjo6ZGF0YTo6WERhdGFTZXF1ZW5jZSA+IHhMYWJlbHNDbG9uZSggeExhYmVsc0Nsb25lYWJsZS0+Y3JlYXRlQ2xvbmUoKSwgdW5vOjpVTk9fUVVFUlkgKTsKICAgICAgICBwUmVzLT5zZXRMYWJlbCggeExhYmVsc0Nsb25lICk7CiAgICB9CiAgICB4UmVzID0gcFJlczsKICAgIHJldHVybiB4UmVzOwp9CgoKT1VTdHJpbmcgU0FMX0NBTEwgU3dDaGFydExhYmVsZWREYXRhU2VxdWVuY2U6OmdldEltcGxlbWVudGF0aW9uTmFtZSggICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIHJldHVybiBDMlUoIlN3Q2hhcnRMYWJlbGVkRGF0YVNlcXVlbmNlIik7Cn0KCgpzYWxfQm9vbCBTQUxfQ0FMTCBTd0NoYXJ0TGFiZWxlZERhdGFTZXF1ZW5jZTo6c3VwcG9ydHNTZXJ2aWNlKAogICAgICAgIGNvbnN0IE9VU3RyaW5nJiByU2VydmljZU5hbWUgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgcmV0dXJuIHJTZXJ2aWNlTmFtZS5lcXVhbHNBc2NpaSggU05fTEFCRUxFRF9EQVRBX1NFUVVFTkNFICk7Cn0KCgp1bm86OlNlcXVlbmNlPCBPVVN0cmluZyA+IFNBTF9DQUxMIFN3Q2hhcnRMYWJlbGVkRGF0YVNlcXVlbmNlOjpnZXRTdXBwb3J0ZWRTZXJ2aWNlTmFtZXMoICApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICB2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKICAgIHVubzo6U2VxdWVuY2U8IE9VU3RyaW5nID4gYVJlcygxKTsKICAgIGFSZXMuZ2V0QXJyYXkoKVswXSA9IEMyVSggU05fTEFCRUxFRF9EQVRBX1NFUVVFTkNFICk7CiAgICByZXR1cm4gYVJlczsKfQoKCnZvaWQgU0FMX0NBTEwgU3dDaGFydExhYmVsZWREYXRhU2VxdWVuY2U6OmRpc3Bvc2luZygKICAgICAgICBjb25zdCBsYW5nOjpFdmVudE9iamVjdCYgclNvdXJjZSApCiAgICB0aHJvdyAodW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CiAgICBvc2w6Ok11dGV4R3VhcmQgIGFHdWFyZCggR2V0Q2hhcnRNdXRleCgpICk7CiAgICB1bm86OlJlZmVyZW5jZTwgdW5vOjpYSW50ZXJmYWNlID4geFJlZiggclNvdXJjZS5Tb3VyY2UgKTsKICAgIGlmICh4UmVmID09IHhEYXRhKQogICAgICAgIHhEYXRhLmNsZWFyKCk7CiAgICBpZiAoeFJlZiA9PSB4TGFiZWxzKQogICAgICAgIHhMYWJlbHMuY2xlYXIoKTsKICAgIGlmICgheERhdGEuaXMoKSAmJiAheExhYmVscy5pcygpKQogICAgICAgIGRpc3Bvc2UoKTsKfQoKCnZvaWQgU0FMX0NBTEwgU3dDaGFydExhYmVsZWREYXRhU2VxdWVuY2U6Om1vZGlmaWVkKAogICAgICAgIGNvbnN0IGxhbmc6OkV2ZW50T2JqZWN0JiByRXZlbnQgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgaWYgKHJFdmVudC5Tb3VyY2UgPT0geERhdGEgfHwgckV2ZW50LlNvdXJjZSA9PSB4TGFiZWxzKQogICAgewoJCUxhdW5jaE1vZGlmaWVkRXZlbnQoIGFNb2RpZnlMaXN0ZW5lcnMsIGR5bmFtaWNfY2FzdDwgWE1vZGlmeUJyb2FkY2FzdGVyICogPih0aGlzKSApOwogICAgfQp9CgoKdm9pZCBTQUxfQ0FMTCBTd0NoYXJ0TGFiZWxlZERhdGFTZXF1ZW5jZTo6YWRkTW9kaWZ5TGlzdGVuZXIoCiAgICAgICAgY29uc3QgdW5vOjpSZWZlcmVuY2U8IHV0aWw6OlhNb2RpZnlMaXN0ZW5lciA+JiByeExpc3RlbmVyICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIG9zbDo6TXV0ZXhHdWFyZCAgYUd1YXJkKCBHZXRDaGFydE11dGV4KCkgKTsKICAgIGlmICghYkRpc3Bvc2VkICYmIHJ4TGlzdGVuZXIuaXMoKSkKICAgICAgICBhTW9kaWZ5TGlzdGVuZXJzLmFkZEludGVyZmFjZSggcnhMaXN0ZW5lciApOwp9CgoKdm9pZCBTQUxfQ0FMTCBTd0NoYXJ0TGFiZWxlZERhdGFTZXF1ZW5jZTo6cmVtb3ZlTW9kaWZ5TGlzdGVuZXIoCiAgICAgICAgY29uc3QgdW5vOjpSZWZlcmVuY2U8IHV0aWw6OlhNb2RpZnlMaXN0ZW5lciA+JiByeExpc3RlbmVyICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIG9zbDo6TXV0ZXhHdWFyZCAgYUd1YXJkKCBHZXRDaGFydE11dGV4KCkgKTsKICAgIGlmICghYkRpc3Bvc2VkICYmIHJ4TGlzdGVuZXIuaXMoKSkKICAgICAgICBhTW9kaWZ5TGlzdGVuZXJzLnJlbW92ZUludGVyZmFjZSggcnhMaXN0ZW5lciApOwp9CgoKdm9pZCBTQUxfQ0FMTCBTd0NoYXJ0TGFiZWxlZERhdGFTZXF1ZW5jZTo6ZGlzcG9zZSggICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIHNhbF9Cb29sIGJNdXN0RGlzcG9zZSggc2FsX0ZhbHNlICk7Cgl7CgkJb3NsOjpNdXRleEd1YXJkICBhR3VhcmQoIEdldENoYXJ0TXV0ZXgoKSApOwogICAgICAgIGJNdXN0RGlzcG9zZSA9ICFiRGlzcG9zZWQ7CgkJaWYgKCFiRGlzcG9zZWQpCgkJCWJEaXNwb3NlZCA9IHNhbF9UcnVlOwoJfQogICAgaWYgKGJNdXN0RGlzcG9zZSkKICAgIHsKICAgICAgICBiRGlzcG9zZWQgPSBzYWxfVHJ1ZTsKCiAgICAgICAgLy8gcmVxdWlyZSBsaXN0ZW5lcnMgdG8gcmVsZWFzZSByZWZlcmVuY2VzIHRvIHRoaXMgb2JqZWN0CiAgICAgICAgbGFuZzo6RXZlbnRPYmplY3QgYUV2dE9iaiggZHluYW1pY19jYXN0PCBjaGFydDI6OmRhdGE6OlhMYWJlbGVkRGF0YVNlcXVlbmNlICogPih0aGlzKSApOwogICAgICAgIGFNb2RpZnlMaXN0ZW5lcnMuZGlzcG9zZUFuZENsZWFyKCBhRXZ0T2JqICk7CiAgICAgICAgYUV2dExpc3RlbmVycy5kaXNwb3NlQW5kQ2xlYXIoIGFFdnRPYmogKTsKICAgIH0KfQoKCnZvaWQgU0FMX0NBTEwgU3dDaGFydExhYmVsZWREYXRhU2VxdWVuY2U6OmFkZEV2ZW50TGlzdGVuZXIoCiAgICAgICAgY29uc3QgdW5vOjpSZWZlcmVuY2U8IGxhbmc6OlhFdmVudExpc3RlbmVyID4mIHJ4TGlzdGVuZXIgKQogICAgdGhyb3cgKHVubzo6UnVudGltZUV4Y2VwdGlvbikKewogICAgb3NsOjpNdXRleEd1YXJkICBhR3VhcmQoIEdldENoYXJ0TXV0ZXgoKSApOwogICAgaWYgKCFiRGlzcG9zZWQgJiYgcnhMaXN0ZW5lci5pcygpKQogICAgICAgIGFFdnRMaXN0ZW5lcnMuYWRkSW50ZXJmYWNlKCByeExpc3RlbmVyICk7Cn0KCgp2b2lkIFNBTF9DQUxMIFN3Q2hhcnRMYWJlbGVkRGF0YVNlcXVlbmNlOjpyZW1vdmVFdmVudExpc3RlbmVyKAogICAgICAgIGNvbnN0IHVubzo6UmVmZXJlbmNlPCBsYW5nOjpYRXZlbnRMaXN0ZW5lciA+JiByeExpc3RlbmVyICkKICAgIHRocm93ICh1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIG9zbDo6TXV0ZXhHdWFyZCAgYUd1YXJkKCBHZXRDaGFydE11dGV4KCkgKTsKICAgIGlmICghYkRpc3Bvc2VkICYmIHJ4TGlzdGVuZXIuaXMoKSkKICAgICAgICBhRXZ0TGlzdGVuZXJzLnJlbW92ZUludGVyZmFjZSggcnhMaXN0ZW5lciApOwp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCg==