LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBBdXRob3IgICAgOiAgQW5ndXMgSm9obnNvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBWZXJzaW9uICAgOiAgNi40LjAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBEYXRlICAgICAgOiAgMiBKdWx5IDIwMTUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBXZWJzaXRlICAgOiAgaHR0cDovL3d3dy5hbmd1c2ouY29tICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBDb3B5cmlnaHQgOiAgQW5ndXMgSm9obnNvbiAyMDEwLTIwMTUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBMaWNlbnNlOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBVc2UsIG1vZGlmaWNhdGlvbiAmIGRpc3RyaWJ1dGlvbiBpcyBzdWJqZWN0IHRvIEJvb3N0IFNvZnR3YXJlIExpY2Vuc2UgVmVyIDEuICoKKiBodHRwOi8vd3d3LmJvb3N0Lm9yZy9MSUNFTlNFXzFfMC50eHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBBdHRyaWJ1dGlvbnM6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBUaGUgY29kZSBpbiB0aGlzIGxpYnJhcnkgaXMgYW4gZXh0ZW5zaW9uIG9mIEJhbGEgVmF0dGkncyBjbGlwcGluZyBhbGdvcml0aG06ICoKKiAiQSBnZW5lcmljIHNvbHV0aW9uIHRvIHBvbHlnb24gY2xpcHBpbmciICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBDb21tdW5pY2F0aW9ucyBvZiB0aGUgQUNNLCBWb2wgMzUsIElzc3VlIDcgKEp1bHkgMTk5MikgcHAgNTYtNjMuICAgICAgICAgICAgICoKKiBodHRwOi8vcG9ydGFsLmFjbS5vcmcvY2l0YXRpb24uY2ZtP2lkPTEyOTkwNiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBDb21wdXRlciBncmFwaGljcyBhbmQgZ2VvbWV0cmljIG1vZGVsaW5nOiBpbXBsZW1lbnRhdGlvbiBhbmQgYWxnb3JpdGhtcyAgICAgICoKKiBCeSBNYXggSy4gQWdvc3RvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBTcHJpbmdlcjsgMSBlZGl0aW9uIChKYW51YXJ5IDQsIDIwMDUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBodHRwOi8vYm9va3MuZ29vZ2xlLmNvbS9ib29rcz9xPXZhdHRpK2NsaXBwaW5nK2Fnb3N0b24gICAgICAgICAgICAgICAgICAgICAgICoKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBTZWUgYWxzbzogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiAiUG9seWdvbiBPZmZzZXR0aW5nIGJ5IENvbXB1dGluZyBXaW5kaW5nIE51bWJlcnMiICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBQYXBlciBuby4gREVUQzIwMDUtODU1MTMgcHAuIDU2NS01NzUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBBU01FIDIwMDUgSW50ZXJuYXRpb25hbCBEZXNpZ24gRW5naW5lZXJpbmcgVGVjaG5pY2FsIENvbmZlcmVuY2VzICAgICAgICAgICAgICoKKiBhbmQgQ29tcHV0ZXJzIGFuZCBJbmZvcm1hdGlvbiBpbiBFbmdpbmVlcmluZyBDb25mZXJlbmNlIChJREVUQy9DSUUyMDA1KSAgICAgICoKKiBTZXB0ZW1iZXIgMjQtMjgsIDIwMDUgLCBMb25nIEJlYWNoLCBDYWxpZm9ybmlhLCBVU0EgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBodHRwOi8vd3d3Lm1lLmJlcmtlbGV5LmVkdS9+bWNtYWlucy9wdWJzL0RBQzA1T2Zmc2V0UG9seWdvbi5wZGYgICAgICAgICAgICAgICoKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiogVGhpcyBpcyBhIHRyYW5zbGF0aW9uIG9mIHRoZSBEZWxwaGkgQ2xpcHBlciBsaWJyYXJ5IGFuZCB0aGUgbmFtaW5nIHN0eWxlICAgICAqCiogdXNlZCBoYXMgcmV0YWluZWQgYSBEZWxwaGkgZmxhdm91ci4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAiY2xpcHBlci5oIgojaW5jbHVkZSA8Y21hdGg+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxzdGRleGNlcHQ+CiNpbmNsdWRlIDxjc3RyaW5nPgojaW5jbHVkZSA8Y3N0ZGxpYj4KI2luY2x1ZGUgPG9zdHJlYW0+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgoKbmFtZXNwYWNlIFF0Q2xpcHBlckxpYiB7CgpzdGF0aWMgZG91YmxlIGNvbnN0IHBpID0gMy4xNDE1OTI2NTM1ODk3OTMyMzg7CnN0YXRpYyBkb3VibGUgY29uc3QgdHdvX3BpID0gcGkgKjI7CnN0YXRpYyBkb3VibGUgY29uc3QgZGVmX2FyY190b2xlcmFuY2UgPSAwLjI1OwoKZW51bSBEaXJlY3Rpb24geyBkUmlnaHRUb0xlZnQsIGRMZWZ0VG9SaWdodCB9OwoKc3RhdGljIGludCBjb25zdCBVbmFzc2lnbmVkID0gLTE7ICAvL2VkZ2Ugbm90IGN1cnJlbnRseSAnb3duaW5nJyBhIHNvbHV0aW9uCnN0YXRpYyBpbnQgY29uc3QgU2tpcCA9IC0yOyAgICAgICAgLy9lZGdlIHRoYXQgd291bGQgb3RoZXJ3aXNlIGNsb3NlIGEgcGF0aAoKI2RlZmluZSBIT1JJWk9OVEFMICgtMS4wRSs0MCkKI2RlZmluZSBUT0xFUkFOQ0UgKDEuMGUtMjApCiNkZWZpbmUgTkVBUl9aRVJPKHZhbCkgKCgodmFsKSA+IC1UT0xFUkFOQ0UpICYmICgodmFsKSA8IFRPTEVSQU5DRSkpCgpzdHJ1Y3QgVEVkZ2UgewogIEludFBvaW50IEJvdDsKICBJbnRQb2ludCBDdXJyOyAvL2N1cnJlbnQgKHVwZGF0ZWQgZm9yIGV2ZXJ5IG5ldyBzY2FuYmVhbSkKICBJbnRQb2ludCBUb3A7CiAgZG91YmxlIER4OwogIFBvbHlUeXBlIFBvbHlUeXA7CiAgRWRnZVNpZGUgU2lkZTsgLy9zaWRlIG9ubHkgcmVmZXJzIHRvIGN1cnJlbnQgc2lkZSBvZiBzb2x1dGlvbiBwb2x5CiAgaW50IFdpbmREZWx0YTsgLy8xIG9yIC0xIGRlcGVuZGluZyBvbiB3aW5kaW5nIGRpcmVjdGlvbgogIGludCBXaW5kQ250OwogIGludCBXaW5kQ250MjsgLy93aW5kaW5nIGNvdW50IG9mIHRoZSBvcHBvc2l0ZSBwb2x5dHlwZQogIGludCBPdXRJZHg7CiAgVEVkZ2UgKk5leHQ7CiAgVEVkZ2UgKlByZXY7CiAgVEVkZ2UgKk5leHRJbkxNTDsKICBURWRnZSAqTmV4dEluQUVMOwogIFRFZGdlICpQcmV2SW5BRUw7CiAgVEVkZ2UgKk5leHRJblNFTDsKICBURWRnZSAqUHJldkluU0VMOwp9OwoKc3RydWN0IEludGVyc2VjdE5vZGUgewogIFRFZGdlICAgICAgICAgICpFZGdlMTsKICBURWRnZSAgICAgICAgICAqRWRnZTI7CiAgSW50UG9pbnQgICAgICAgIFB0Owp9OwoKc3RydWN0IExvY2FsTWluaW11bSB7CiAgY0ludCAgICAgICAgICBZOwogIFRFZGdlICAgICAgICAqTGVmdEJvdW5kOwogIFRFZGdlICAgICAgICAqUmlnaHRCb3VuZDsKfTsKCnN0cnVjdCBPdXRQdDsKCi8vT3V0UmVjOiBjb250YWlucyBhIHBhdGggaW4gdGhlIGNsaXBwaW5nIHNvbHV0aW9uLiBFZGdlcyBpbiB0aGUgQUVMIHdpbGwKLy9jYXJyeSBhIHBvaW50ZXIgdG8gYW4gT3V0UmVjIHdoZW4gdGhleSBhcmUgcGFydCBvZiB0aGUgY2xpcHBpbmcgc29sdXRpb24uCnN0cnVjdCBPdXRSZWMgewogIGludCAgICAgICBJZHg7CiAgYm9vbCAgICAgIElzSG9sZTsKICBib29sICAgICAgSXNPcGVuOwogIE91dFJlYyAgICpGaXJzdExlZnQ7ICAvL3NlZSBjb21tZW50cyBpbiBjbGlwcGVyLnBhcwogIFBvbHlOb2RlICpQb2x5TmQ7CiAgT3V0UHQgICAgKlB0czsKICBPdXRQdCAgICAqQm90dG9tUHQ7Cn07CgpzdHJ1Y3QgT3V0UHQgewogIGludCAgICAgICBJZHg7CiAgSW50UG9pbnQgIFB0OwogIE91dFB0ICAgICpOZXh0OwogIE91dFB0ICAgICpQcmV2Owp9OwoKc3RydWN0IEpvaW4gewogIE91dFB0ICAgICpPdXRQdDE7CiAgT3V0UHQgICAgKk91dFB0MjsKICBJbnRQb2ludCAgT2ZmUHQ7Cn07CgpzdHJ1Y3QgTG9jTWluU29ydGVyCnsKICBpbmxpbmUgYm9vbCBvcGVyYXRvcigpKGNvbnN0IExvY2FsTWluaW11bSYgbG9jTWluMSwgY29uc3QgTG9jYWxNaW5pbXVtJiBsb2NNaW4yKQogIHsKICAgIHJldHVybiBsb2NNaW4yLlkgPCBsb2NNaW4xLlk7CiAgfQp9OwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmlubGluZSBjSW50IFJvdW5kKGRvdWJsZSB2YWwpCnsKICBpZiAoKHZhbCA8IDApKSByZXR1cm4gc3RhdGljX2Nhc3Q8Y0ludD4odmFsIC0gMC41KTsgCiAgZWxzZSByZXR1cm4gc3RhdGljX2Nhc3Q8Y0ludD4odmFsICsgMC41KTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaW5saW5lIGNJbnQgQWJzKGNJbnQgdmFsKQp7CiAgcmV0dXJuIHZhbCA8IDAgPyAtdmFsIDogdmFsOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBQb2x5VHJlZSBtZXRob2RzIC4uLgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBQb2x5VHJlZTo6Q2xlYXIoKQp7CiAgICBmb3IgKFBvbHlOb2Rlczo6c2l6ZV90eXBlIGkgPSAwOyBpIDwgQWxsTm9kZXMuc2l6ZSgpOyArK2kpCiAgICAgIGRlbGV0ZSBBbGxOb2Rlc1tpXTsKICAgIEFsbE5vZGVzLnJlc2l6ZSgwKTsgCiAgICBDaGlsZHMucmVzaXplKDApOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpQb2x5Tm9kZSogUG9seVRyZWU6OkdldEZpcnN0KCkgY29uc3QKewogIGlmICghQ2hpbGRzLmVtcHR5KCkpCiAgICAgIHJldHVybiBDaGlsZHNbMF07CiAgZWxzZQogICAgICByZXR1cm4gMDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaW50IFBvbHlUcmVlOjpUb3RhbCgpIGNvbnN0CnsKICBpbnQgcmVzdWx0ID0gKGludClBbGxOb2Rlcy5zaXplKCk7CiAgLy93aXRoIG5lZ2F0aXZlIG9mZnNldHMsIGlnbm9yZSB0aGUgaGlkZGVuIG91dGVyIHBvbHlnb24gLi4uCiAgaWYgKHJlc3VsdCA+IDAgJiYgQ2hpbGRzWzBdICE9IEFsbE5vZGVzWzBdKSByZXN1bHQtLTsKICByZXR1cm4gcmVzdWx0Owp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBQb2x5Tm9kZSBtZXRob2RzIC4uLgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKUG9seU5vZGU6OlBvbHlOb2RlKCk6IENoaWxkcygpLCBQYXJlbnQoMCksIEluZGV4KDApLCBtX0lzT3BlbihmYWxzZSkKewp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgppbnQgUG9seU5vZGU6OkNoaWxkQ291bnQoKSBjb25zdAp7CiAgcmV0dXJuIChpbnQpQ2hpbGRzLnNpemUoKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBQb2x5Tm9kZTo6QWRkQ2hpbGQoUG9seU5vZGUmIGNoaWxkKQp7CiAgdW5zaWduZWQgY250ID0gKHVuc2lnbmVkKUNoaWxkcy5zaXplKCk7CiAgQ2hpbGRzLnB1c2hfYmFjaygmY2hpbGQpOwogIGNoaWxkLlBhcmVudCA9IHRoaXM7CiAgY2hpbGQuSW5kZXggPSBjbnQ7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KClBvbHlOb2RlKiBQb2x5Tm9kZTo6R2V0TmV4dCgpIGNvbnN0CnsgCiAgaWYgKCFDaGlsZHMuZW1wdHkoKSkgCiAgICAgIHJldHVybiBDaGlsZHNbMF07IAogIGVsc2UKICAgICAgcmV0dXJuIEdldE5leHRTaWJsaW5nVXAoKTsgICAgCn0gIAovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKUG9seU5vZGUqIFBvbHlOb2RlOjpHZXROZXh0U2libGluZ1VwKCkgY29uc3QKeyAKICBpZiAoIVBhcmVudCkgLy9wcm90ZWN0cyBhZ2FpbnN0IFBvbHlUcmVlLkdldE5leHRTaWJsaW5nVXAoKQogICAgICByZXR1cm4gMDsKICBlbHNlIGlmIChJbmRleCA9PSBQYXJlbnQtPkNoaWxkcy5zaXplKCkgLSAxKQogICAgICByZXR1cm4gUGFyZW50LT5HZXROZXh0U2libGluZ1VwKCk7CiAgZWxzZQogICAgICByZXR1cm4gUGFyZW50LT5DaGlsZHNbSW5kZXggKyAxXTsKfSAgCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpib29sIFBvbHlOb2RlOjpJc0hvbGUoKSBjb25zdAp7IAogIGJvb2wgcmVzdWx0ID0gdHJ1ZTsKICBQb2x5Tm9kZSogbm9kZSA9IFBhcmVudDsKICB3aGlsZSAobm9kZSkKICB7CiAgICAgIHJlc3VsdCA9ICFyZXN1bHQ7CiAgICAgIG5vZGUgPSBub2RlLT5QYXJlbnQ7CiAgfQogIHJldHVybiByZXN1bHQ7Cn0gIAovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBQb2x5Tm9kZTo6SXNPcGVuKCkgY29uc3QKeyAKICByZXR1cm4gbV9Jc09wZW47Cn0gIAovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKI2lmbmRlZiB1c2VfaW50MzIKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIEludDEyOCBjbGFzcyAoZW5hYmxlcyBzYWZlIG1hdGggb24gc2lnbmVkIDY0Yml0IGludGVnZXJzKQovLyBlZyBJbnQxMjggdmFsMSgobG9uZzY0KTkyMjMzNzIwMzY4NTQ3NzU4MDcpOyAvL2llIDJeNjMgLTEKLy8gICAgSW50MTI4IHZhbDIoKGxvbmc2NCk5MjIzMzcyMDM2ODU0Nzc1ODA3KTsKLy8gICAgSW50MTI4IHZhbDMgPSB2YWwxICogdmFsMjsKLy8gICAgdmFsMy5Bc1N0cmluZyA9PiAiODUwNzA1OTE3MzAyMzQ2MTU4NDczOTY5MDc3ODQyMzI1MDEyNDkiICg4LjVlKzM3KQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKY2xhc3MgSW50MTI4CnsKICBwdWJsaWM6CiAgICB1bG9uZzY0IGxvOwogICAgbG9uZzY0IGhpOwoKICAgIEludDEyOChsb25nNjQgX2xvID0gMCkKICAgIHsKICAgICAgbG8gPSAodWxvbmc2NClfbG87ICAgCiAgICAgIGlmIChfbG8gPCAwKSAgaGkgPSAtMTsgZWxzZSBoaSA9IDA7IAogICAgfQoKCiAgICBJbnQxMjgoY29uc3QgSW50MTI4ICZ2YWwpOiBsbyh2YWwubG8pLCBoaSh2YWwuaGkpe30KCiAgICBJbnQxMjgoY29uc3QgbG9uZzY0JiBfaGksIGNvbnN0IHVsb25nNjQmIF9sbyk6IGxvKF9sbyksIGhpKF9oaSl7fQogICAgCiAgICBJbnQxMjgmIG9wZXJhdG9yID0gKGNvbnN0IGxvbmc2NCAmdmFsKQogICAgewogICAgICBsbyA9ICh1bG9uZzY0KXZhbDsKICAgICAgaWYgKHZhbCA8IDApIGhpID0gLTE7IGVsc2UgaGkgPSAwOwogICAgICByZXR1cm4gKnRoaXM7CiAgICB9CgogICAgYm9vbCBvcGVyYXRvciA9PSAoY29uc3QgSW50MTI4ICZ2YWwpIGNvbnN0CiAgICAgIHtyZXR1cm4gKGhpID09IHZhbC5oaSAmJiBsbyA9PSB2YWwubG8pO30KCiAgICBib29sIG9wZXJhdG9yICE9IChjb25zdCBJbnQxMjggJnZhbCkgY29uc3QKICAgICAgeyByZXR1cm4gISgqdGhpcyA9PSB2YWwpO30KCiAgICBib29sIG9wZXJhdG9yID4gKGNvbnN0IEludDEyOCAmdmFsKSBjb25zdAogICAgewogICAgICBpZiAoaGkgIT0gdmFsLmhpKQogICAgICAgIHJldHVybiBoaSA+IHZhbC5oaTsKICAgICAgZWxzZQogICAgICAgIHJldHVybiBsbyA+IHZhbC5sbzsKICAgIH0KCiAgICBib29sIG9wZXJhdG9yIDwgKGNvbnN0IEludDEyOCAmdmFsKSBjb25zdAogICAgewogICAgICBpZiAoaGkgIT0gdmFsLmhpKQogICAgICAgIHJldHVybiBoaSA8IHZhbC5oaTsKICAgICAgZWxzZQogICAgICAgIHJldHVybiBsbyA8IHZhbC5sbzsKICAgIH0KCiAgICBib29sIG9wZXJhdG9yID49IChjb25zdCBJbnQxMjggJnZhbCkgY29uc3QKICAgICAgeyByZXR1cm4gISgqdGhpcyA8IHZhbCk7fQoKICAgIGJvb2wgb3BlcmF0b3IgPD0gKGNvbnN0IEludDEyOCAmdmFsKSBjb25zdAogICAgICB7IHJldHVybiAhKCp0aGlzID4gdmFsKTt9CgogICAgSW50MTI4JiBvcGVyYXRvciArPSAoY29uc3QgSW50MTI4ICZyaHMpCiAgICB7CiAgICAgIGhpICs9IHJocy5oaTsKICAgICAgbG8gKz0gcmhzLmxvOwogICAgICBpZiAobG8gPCByaHMubG8pIGhpKys7CiAgICAgIHJldHVybiAqdGhpczsKICAgIH0KCiAgICBJbnQxMjggb3BlcmF0b3IgKyAoY29uc3QgSW50MTI4ICZyaHMpIGNvbnN0CiAgICB7CiAgICAgIEludDEyOCByZXN1bHQoKnRoaXMpOwogICAgICByZXN1bHQrPSByaHM7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgSW50MTI4JiBvcGVyYXRvciAtPSAoY29uc3QgSW50MTI4ICZyaHMpCiAgICB7CiAgICAgICp0aGlzICs9IC1yaHM7CiAgICAgIHJldHVybiAqdGhpczsKICAgIH0KCiAgICBJbnQxMjggb3BlcmF0b3IgLSAoY29uc3QgSW50MTI4ICZyaHMpIGNvbnN0CiAgICB7CiAgICAgIEludDEyOCByZXN1bHQoKnRoaXMpOwogICAgICByZXN1bHQgLT0gcmhzOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIEludDEyOCBvcGVyYXRvci0oKSBjb25zdCAvL3VuYXJ5IG5lZ2F0aW9uCiAgICB7CiAgICAgIGlmIChsbyA9PSAwKQogICAgICAgIHJldHVybiBJbnQxMjgoLWhpLCAwKTsKICAgICAgZWxzZQogICAgICAgIHJldHVybiBJbnQxMjgofmhpLCB+bG8gKyAxKTsKICAgIH0KCiAgICBvcGVyYXRvciBkb3VibGUoKSBjb25zdAogICAgewogICAgICBjb25zdCBkb3VibGUgc2hpZnQ2NCA9IDE4NDQ2NzQ0MDczNzA5NTUxNjE2LjA7IC8vMl42NAogICAgICBpZiAoaGkgPCAwKQogICAgICB7CiAgICAgICAgaWYgKGxvID09IDApIHJldHVybiAoZG91YmxlKWhpICogc2hpZnQ2NDsKICAgICAgICBlbHNlIHJldHVybiAtKGRvdWJsZSkofmxvICsgfmhpICogc2hpZnQ2NCk7CiAgICAgIH0KICAgICAgZWxzZQogICAgICAgIHJldHVybiAoZG91YmxlKShsbyArIGhpICogc2hpZnQ2NCk7CiAgICB9Cgp9OwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKSW50MTI4IEludDEyOE11bCAobG9uZzY0IGxocywgbG9uZzY0IHJocykKewogIGJvb2wgbmVnYXRlID0gKGxocyA8IDApICE9IChyaHMgPCAwKTsKCiAgaWYgKGxocyA8IDApIGxocyA9IC1saHM7CiAgdWxvbmc2NCBpbnQxSGkgPSB1bG9uZzY0KGxocykgPj4gMzI7CiAgdWxvbmc2NCBpbnQxTG8gPSB1bG9uZzY0KGxocyAmIDB4RkZGRkZGRkYpOwoKICBpZiAocmhzIDwgMCkgcmhzID0gLXJoczsKICB1bG9uZzY0IGludDJIaSA9IHVsb25nNjQocmhzKSA+PiAzMjsKICB1bG9uZzY0IGludDJMbyA9IHVsb25nNjQocmhzICYgMHhGRkZGRkZGRik7CgogIC8vbmI6IHNlZSBjb21tZW50cyBpbiBjbGlwcGVyLnBhcwogIHVsb25nNjQgYSA9IGludDFIaSAqIGludDJIaTsKICB1bG9uZzY0IGIgPSBpbnQxTG8gKiBpbnQyTG87CiAgdWxvbmc2NCBjID0gaW50MUhpICogaW50MkxvICsgaW50MUxvICogaW50MkhpOwoKICBJbnQxMjggdG1wOwogIHRtcC5oaSA9IGxvbmc2NChhICsgKGMgPj4gMzIpKTsKICB0bXAubG8gPSBsb25nNjQoYyA8PCAzMik7CiAgdG1wLmxvICs9IGxvbmc2NChiKTsKICBpZiAodG1wLmxvIDwgYikgdG1wLmhpKys7CiAgaWYgKG5lZ2F0ZSkgdG1wID0gLXRtcDsKICByZXR1cm4gdG1wOwp9OwojZW5kaWYKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIE1pc2NlbGxhbmVvdXMgZ2xvYmFsIGZ1bmN0aW9ucwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBPcmllbnRhdGlvbihjb25zdCBQYXRoICZwb2x5KQp7CiAgICByZXR1cm4gQXJlYShwb2x5KSA+PSAwOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpkb3VibGUgQXJlYShjb25zdCBQYXRoICZwb2x5KQp7CiAgaW50IHNpemUgPSAoaW50KXBvbHkuc2l6ZSgpOwogIGlmIChzaXplIDwgMykgcmV0dXJuIDA7CgogIGRvdWJsZSBhID0gMDsKICBmb3IgKGludCBpID0gMCwgaiA9IHNpemUgLTE7IGkgPCBzaXplOyArK2kpCiAgewogICAgYSArPSAoKGRvdWJsZSlwb2x5W2pdLlggKyBwb2x5W2ldLlgpICogKChkb3VibGUpcG9seVtqXS5ZIC0gcG9seVtpXS5ZKTsKICAgIGogPSBpOwogIH0KICByZXR1cm4gLWEgKiAwLjU7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmRvdWJsZSBBcmVhKGNvbnN0IE91dFB0ICpvcCkKewogIGNvbnN0IE91dFB0ICpzdGFydE9wID0gb3A7CiAgaWYgKCFvcCkgcmV0dXJuIDA7CiAgZG91YmxlIGEgPSAwOwogIGRvIHsKICAgIGEgKz0gIChkb3VibGUpKG9wLT5QcmV2LT5QdC5YICsgb3AtPlB0LlgpICogKGRvdWJsZSkob3AtPlByZXYtPlB0LlkgLSBvcC0+UHQuWSk7CiAgICBvcCA9IG9wLT5OZXh0OwogIH0gd2hpbGUgKG9wICE9IHN0YXJ0T3ApOwogIHJldHVybiBhICogMC41Owp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpkb3VibGUgQXJlYShjb25zdCBPdXRSZWMgJm91dFJlYykKewogIHJldHVybiBBcmVhKG91dFJlYy5QdHMpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpib29sIFBvaW50SXNWZXJ0ZXgoY29uc3QgSW50UG9pbnQgJlB0LCBPdXRQdCAqcHApCnsKICBPdXRQdCAqcHAyID0gcHA7CiAgZG8KICB7CiAgICBpZiAocHAyLT5QdCA9PSBQdCkgcmV0dXJuIHRydWU7CiAgICBwcDIgPSBwcDItPk5leHQ7CiAgfQogIHdoaWxlIChwcDIgIT0gcHApOwogIHJldHVybiBmYWxzZTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLy9TZWUgIlRoZSBQb2ludCBpbiBQb2x5Z29uIFByb2JsZW0gZm9yIEFyYml0cmFyeSBQb2x5Z29ucyIgYnkgSG9ybWFubiAmIEFnYXRob3MKLy9odHRwOi8vY2l0ZXNlZXJ4LmlzdC5wc3UuZWR1L3ZpZXdkb2MvZG93bmxvYWQ/ZG9pPTEwLjEuMS44OC41NDk4JnJlcD1yZXAxJnR5cGU9cGRmCmludCBQb2ludEluUG9seWdvbihjb25zdCBJbnRQb2ludCAmcHQsIGNvbnN0IFBhdGggJnBhdGgpCnsKICAvL3JldHVybnMgMCBpZiBmYWxzZSwgKzEgaWYgdHJ1ZSwgLTEgaWYgcHQgT04gcG9seWdvbiBib3VuZGFyeQogIGludCByZXN1bHQgPSAwOwogIHNpemVfdCBjbnQgPSBwYXRoLnNpemUoKTsKICBpZiAoY250IDwgMykgcmV0dXJuIDA7CiAgSW50UG9pbnQgaXAgPSBwYXRoWzBdOwogIGZvcihzaXplX3QgaSA9IDE7IGkgPD0gY250OyArK2kpCiAgewogICAgSW50UG9pbnQgaXBOZXh0ID0gKGkgPT0gY250ID8gcGF0aFswXSA6IHBhdGhbaV0pOwogICAgaWYgKGlwTmV4dC5ZID09IHB0LlkpCiAgICB7CiAgICAgICAgaWYgKChpcE5leHQuWCA9PSBwdC5YKSB8fCAoaXAuWSA9PSBwdC5ZICYmIAogICAgICAgICAgKChpcE5leHQuWCA+IHB0LlgpID09IChpcC5YIDwgcHQuWCkpKSkgcmV0dXJuIC0xOwogICAgfQogICAgaWYgKChpcC5ZIDwgcHQuWSkgIT0gKGlwTmV4dC5ZIDwgcHQuWSkpCiAgICB7CiAgICAgIGlmIChpcC5YID49IHB0LlgpCiAgICAgIHsKICAgICAgICBpZiAoaXBOZXh0LlggPiBwdC5YKSByZXN1bHQgPSAxIC0gcmVzdWx0OwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICBkb3VibGUgZCA9IChkb3VibGUpKGlwLlggLSBwdC5YKSAqIChpcE5leHQuWSAtIHB0LlkpIC0gCiAgICAgICAgICAgIChkb3VibGUpKGlwTmV4dC5YIC0gcHQuWCkgKiAoaXAuWSAtIHB0LlkpOwogICAgICAgICAgaWYgKCFkKSByZXR1cm4gLTE7CiAgICAgICAgICBpZiAoKGQgPiAwKSA9PSAoaXBOZXh0LlkgPiBpcC5ZKSkgcmVzdWx0ID0gMSAtIHJlc3VsdDsKICAgICAgICB9CiAgICAgIH0gZWxzZQogICAgICB7CiAgICAgICAgaWYgKGlwTmV4dC5YID4gcHQuWCkKICAgICAgICB7CiAgICAgICAgICBkb3VibGUgZCA9IChkb3VibGUpKGlwLlggLSBwdC5YKSAqIChpcE5leHQuWSAtIHB0LlkpIC0gCiAgICAgICAgICAgIChkb3VibGUpKGlwTmV4dC5YIC0gcHQuWCkgKiAoaXAuWSAtIHB0LlkpOwogICAgICAgICAgaWYgKCFkKSByZXR1cm4gLTE7CiAgICAgICAgICBpZiAoKGQgPiAwKSA9PSAoaXBOZXh0LlkgPiBpcC5ZKSkgcmVzdWx0ID0gMSAtIHJlc3VsdDsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGlwID0gaXBOZXh0OwogIH0gCiAgcmV0dXJuIHJlc3VsdDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaW50IFBvaW50SW5Qb2x5Z29uIChjb25zdCBJbnRQb2ludCAmcHQsIE91dFB0ICpvcCkKewogIC8vcmV0dXJucyAwIGlmIGZhbHNlLCArMSBpZiB0cnVlLCAtMSBpZiBwdCBPTiBwb2x5Z29uIGJvdW5kYXJ5CiAgaW50IHJlc3VsdCA9IDA7CiAgT3V0UHQqIHN0YXJ0T3AgPSBvcDsKICBmb3IoOzspCiAgewogICAgaWYgKG9wLT5OZXh0LT5QdC5ZID09IHB0LlkpCiAgICB7CiAgICAgICAgaWYgKChvcC0+TmV4dC0+UHQuWCA9PSBwdC5YKSB8fCAob3AtPlB0LlkgPT0gcHQuWSAmJiAKICAgICAgICAgICgob3AtPk5leHQtPlB0LlggPiBwdC5YKSA9PSAob3AtPlB0LlggPCBwdC5YKSkpKSByZXR1cm4gLTE7CiAgICB9CiAgICBpZiAoKG9wLT5QdC5ZIDwgcHQuWSkgIT0gKG9wLT5OZXh0LT5QdC5ZIDwgcHQuWSkpCiAgICB7CiAgICAgIGlmIChvcC0+UHQuWCA+PSBwdC5YKQogICAgICB7CiAgICAgICAgaWYgKG9wLT5OZXh0LT5QdC5YID4gcHQuWCkgcmVzdWx0ID0gMSAtIHJlc3VsdDsKICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgZG91YmxlIGQgPSAoZG91YmxlKShvcC0+UHQuWCAtIHB0LlgpICogKG9wLT5OZXh0LT5QdC5ZIC0gcHQuWSkgLSAKICAgICAgICAgICAgKGRvdWJsZSkob3AtPk5leHQtPlB0LlggLSBwdC5YKSAqIChvcC0+UHQuWSAtIHB0LlkpOwogICAgICAgICAgaWYgKCFkKSByZXR1cm4gLTE7CiAgICAgICAgICBpZiAoKGQgPiAwKSA9PSAob3AtPk5leHQtPlB0LlkgPiBvcC0+UHQuWSkpIHJlc3VsdCA9IDEgLSByZXN1bHQ7CiAgICAgICAgfQogICAgICB9IGVsc2UKICAgICAgewogICAgICAgIGlmIChvcC0+TmV4dC0+UHQuWCA+IHB0LlgpCiAgICAgICAgewogICAgICAgICAgZG91YmxlIGQgPSAoZG91YmxlKShvcC0+UHQuWCAtIHB0LlgpICogKG9wLT5OZXh0LT5QdC5ZIC0gcHQuWSkgLSAKICAgICAgICAgICAgKGRvdWJsZSkob3AtPk5leHQtPlB0LlggLSBwdC5YKSAqIChvcC0+UHQuWSAtIHB0LlkpOwogICAgICAgICAgaWYgKCFkKSByZXR1cm4gLTE7CiAgICAgICAgICBpZiAoKGQgPiAwKSA9PSAob3AtPk5leHQtPlB0LlkgPiBvcC0+UHQuWSkpIHJlc3VsdCA9IDEgLSByZXN1bHQ7CiAgICAgICAgfQogICAgICB9CiAgICB9IAogICAgb3AgPSBvcC0+TmV4dDsKICAgIGlmIChzdGFydE9wID09IG9wKSBicmVhazsKICB9IAogIHJldHVybiByZXN1bHQ7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmJvb2wgUG9seTJDb250YWluc1BvbHkxKE91dFB0ICpPdXRQdDEsIE91dFB0ICpPdXRQdDIpCnsKICBPdXRQdCogb3AgPSBPdXRQdDE7CiAgZG8KICB7CiAgICAvL25iOiBQb2ludEluUG9seWdvbiByZXR1cm5zIDAgaWYgZmFsc2UsICsxIGlmIHRydWUsIC0xIGlmIHB0IG9uIHBvbHlnb24KICAgIGludCByZXMgPSBQb2ludEluUG9seWdvbihvcC0+UHQsIE91dFB0Mik7CiAgICBpZiAocmVzID49IDApIHJldHVybiByZXMgPiAwOwogICAgb3AgPSBvcC0+TmV4dDsgCiAgfQogIHdoaWxlIChvcCAhPSBPdXRQdDEpOwogIHJldHVybiB0cnVlOyAKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmJvb2wgU2xvcGVzRXF1YWwoY29uc3QgVEVkZ2UgJmUxLCBjb25zdCBURWRnZSAmZTIsIGJvb2wgVXNlRnVsbEludDY0UmFuZ2UpCnsKI2lmbmRlZiB1c2VfaW50MzIKICBpZiAoVXNlRnVsbEludDY0UmFuZ2UpCiAgICByZXR1cm4gSW50MTI4TXVsKGUxLlRvcC5ZIC0gZTEuQm90LlksIGUyLlRvcC5YIC0gZTIuQm90LlgpID09IAogICAgSW50MTI4TXVsKGUxLlRvcC5YIC0gZTEuQm90LlgsIGUyLlRvcC5ZIC0gZTIuQm90LlkpOwogIGVsc2UgCiNlbmRpZgogICAgcmV0dXJuIChlMS5Ub3AuWSAtIGUxLkJvdC5ZKSAqIChlMi5Ub3AuWCAtIGUyLkJvdC5YKSA9PSAKICAgIChlMS5Ub3AuWCAtIGUxLkJvdC5YKSAqIChlMi5Ub3AuWSAtIGUyLkJvdC5ZKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBTbG9wZXNFcXVhbChjb25zdCBJbnRQb2ludCBwdDEsIGNvbnN0IEludFBvaW50IHB0MiwKICBjb25zdCBJbnRQb2ludCBwdDMsIGJvb2wgVXNlRnVsbEludDY0UmFuZ2UpCnsKI2lmbmRlZiB1c2VfaW50MzIKICBpZiAoVXNlRnVsbEludDY0UmFuZ2UpCiAgICByZXR1cm4gSW50MTI4TXVsKHB0MS5ZLXB0Mi5ZLCBwdDIuWC1wdDMuWCkgPT0gSW50MTI4TXVsKHB0MS5YLXB0Mi5YLCBwdDIuWS1wdDMuWSk7CiAgZWxzZSAKI2VuZGlmCiAgICByZXR1cm4gKHB0MS5ZLXB0Mi5ZKSoocHQyLlgtcHQzLlgpID09IChwdDEuWC1wdDIuWCkqKHB0Mi5ZLXB0My5ZKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBTbG9wZXNFcXVhbChjb25zdCBJbnRQb2ludCBwdDEsIGNvbnN0IEludFBvaW50IHB0MiwKICBjb25zdCBJbnRQb2ludCBwdDMsIGNvbnN0IEludFBvaW50IHB0NCwgYm9vbCBVc2VGdWxsSW50NjRSYW5nZSkKewojaWZuZGVmIHVzZV9pbnQzMgogIGlmIChVc2VGdWxsSW50NjRSYW5nZSkKICAgIHJldHVybiBJbnQxMjhNdWwocHQxLlktcHQyLlksIHB0My5YLXB0NC5YKSA9PSBJbnQxMjhNdWwocHQxLlgtcHQyLlgsIHB0My5ZLXB0NC5ZKTsKICBlbHNlIAojZW5kaWYKICAgIHJldHVybiAocHQxLlktcHQyLlkpKihwdDMuWC1wdDQuWCkgPT0gKHB0MS5YLXB0Mi5YKSoocHQzLlktcHQ0LlkpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgppbmxpbmUgYm9vbCBJc0hvcml6b250YWwoVEVkZ2UgJmUpCnsKICByZXR1cm4gZS5EeCA9PSBIT1JJWk9OVEFMOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgppbmxpbmUgZG91YmxlIEdldER4KGNvbnN0IEludFBvaW50IHB0MSwgY29uc3QgSW50UG9pbnQgcHQyKQp7CiAgcmV0dXJuIChwdDEuWSA9PSBwdDIuWSkgPwogICAgSE9SSVpPTlRBTCA6IChkb3VibGUpKHB0Mi5YIC0gcHQxLlgpIC8gKHB0Mi5ZIC0gcHQxLlkpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgppbmxpbmUgdm9pZCBTZXREeChURWRnZSAmZSkKewogIGNJbnQgZHkgID0gKGUuVG9wLlkgLSBlLkJvdC5ZKTsKICBpZiAoZHkgPT0gMCkgZS5EeCA9IEhPUklaT05UQUw7CiAgZWxzZSBlLkR4ID0gKGRvdWJsZSkoZS5Ub3AuWCAtIGUuQm90LlgpIC8gZHk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmlubGluZSB2b2lkIFN3YXBTaWRlcyhURWRnZSAmRWRnZTEsIFRFZGdlICZFZGdlMikKewogIEVkZ2VTaWRlIFNpZGUgPSAgRWRnZTEuU2lkZTsKICBFZGdlMS5TaWRlID0gRWRnZTIuU2lkZTsKICBFZGdlMi5TaWRlID0gU2lkZTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaW5saW5lIHZvaWQgU3dhcFBvbHlJbmRleGVzKFRFZGdlICZFZGdlMSwgVEVkZ2UgJkVkZ2UyKQp7CiAgaW50IE91dElkeCA9ICBFZGdlMS5PdXRJZHg7CiAgRWRnZTEuT3V0SWR4ID0gRWRnZTIuT3V0SWR4OwogIEVkZ2UyLk91dElkeCA9IE91dElkeDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaW5saW5lIGNJbnQgVG9wWChURWRnZSAmZWRnZSwgY29uc3QgY0ludCBjdXJyZW50WSkKewogIHJldHVybiAoIGN1cnJlbnRZID09IGVkZ2UuVG9wLlkgKSA/CiAgICBlZGdlLlRvcC5YIDogZWRnZS5Cb3QuWCArIFJvdW5kKGVkZ2UuRHggKihjdXJyZW50WSAtIGVkZ2UuQm90LlkpKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBJbnRlcnNlY3RQb2ludChURWRnZSAmRWRnZTEsIFRFZGdlICZFZGdlMiwgSW50UG9pbnQgJmlwKQp7CiNpZmRlZiB1c2VfeHl6ICAKICBpcC5aID0gMDsKI2VuZGlmCgogIGRvdWJsZSBiMSwgYjI7CiAgaWYgKEVkZ2UxLkR4ID09IEVkZ2UyLkR4KQogIHsKICAgIGlwLlkgPSBFZGdlMS5DdXJyLlk7CiAgICBpcC5YID0gVG9wWChFZGdlMSwgaXAuWSk7CiAgICByZXR1cm47CiAgfQogIGVsc2UgaWYgKEVkZ2UxLkR4ID09IDApCiAgewogICAgaXAuWCA9IEVkZ2UxLkJvdC5YOwogICAgaWYgKElzSG9yaXpvbnRhbChFZGdlMikpCiAgICAgIGlwLlkgPSBFZGdlMi5Cb3QuWTsKICAgIGVsc2UKICAgIHsKICAgICAgYjIgPSBFZGdlMi5Cb3QuWSAtIChFZGdlMi5Cb3QuWCAvIEVkZ2UyLkR4KTsKICAgICAgaXAuWSA9IFJvdW5kKGlwLlggLyBFZGdlMi5EeCArIGIyKTsKICAgIH0KICB9CiAgZWxzZSBpZiAoRWRnZTIuRHggPT0gMCkKICB7CiAgICBpcC5YID0gRWRnZTIuQm90Llg7CiAgICBpZiAoSXNIb3Jpem9udGFsKEVkZ2UxKSkKICAgICAgaXAuWSA9IEVkZ2UxLkJvdC5ZOwogICAgZWxzZQogICAgewogICAgICBiMSA9IEVkZ2UxLkJvdC5ZIC0gKEVkZ2UxLkJvdC5YIC8gRWRnZTEuRHgpOwogICAgICBpcC5ZID0gUm91bmQoaXAuWCAvIEVkZ2UxLkR4ICsgYjEpOwogICAgfQogIH0gCiAgZWxzZSAKICB7CiAgICBiMSA9IEVkZ2UxLkJvdC5YIC0gRWRnZTEuQm90LlkgKiBFZGdlMS5EeDsKICAgIGIyID0gRWRnZTIuQm90LlggLSBFZGdlMi5Cb3QuWSAqIEVkZ2UyLkR4OwogICAgZG91YmxlIHEgPSAoYjItYjEpIC8gKEVkZ2UxLkR4IC0gRWRnZTIuRHgpOwogICAgaXAuWSA9IFJvdW5kKHEpOwogICAgaWYgKHN0ZDo6ZmFicyhFZGdlMS5EeCkgPCBzdGQ6OmZhYnMoRWRnZTIuRHgpKQogICAgICBpcC5YID0gUm91bmQoRWRnZTEuRHggKiBxICsgYjEpOwogICAgZWxzZSAKICAgICAgaXAuWCA9IFJvdW5kKEVkZ2UyLkR4ICogcSArIGIyKTsKICB9CgogIGlmIChpcC5ZIDwgRWRnZTEuVG9wLlkgfHwgaXAuWSA8IEVkZ2UyLlRvcC5ZKSAKICB7CiAgICBpZiAoRWRnZTEuVG9wLlkgPiBFZGdlMi5Ub3AuWSkKICAgICAgaXAuWSA9IEVkZ2UxLlRvcC5ZOwogICAgZWxzZQogICAgICBpcC5ZID0gRWRnZTIuVG9wLlk7CiAgICBpZiAoc3RkOjpmYWJzKEVkZ2UxLkR4KSA8IHN0ZDo6ZmFicyhFZGdlMi5EeCkpCiAgICAgIGlwLlggPSBUb3BYKEVkZ2UxLCBpcC5ZKTsKICAgIGVsc2UKICAgICAgaXAuWCA9IFRvcFgoRWRnZTIsIGlwLlkpOwogIH0gCiAgLy9maW5hbGx5LCBkb24ndCBhbGxvdyAnaXAnIHRvIGJlIEJFTE9XIGN1cnIuWSAoaWUgYm90dG9tIG9mIHNjYW5iZWFtKSAuLi4KICBpZiAoaXAuWSA+IEVkZ2UxLkN1cnIuWSkKICB7CiAgICBpcC5ZID0gRWRnZTEuQ3Vyci5ZOwogICAgLy91c2UgdGhlIG1vcmUgdmVydGljYWwgZWRnZSB0byBkZXJpdmUgWCAuLi4KICAgIGlmIChzdGQ6OmZhYnMoRWRnZTEuRHgpID4gc3RkOjpmYWJzKEVkZ2UyLkR4KSkKICAgICAgaXAuWCA9IFRvcFgoRWRnZTIsIGlwLlkpOyBlbHNlCiAgICAgIGlwLlggPSBUb3BYKEVkZ2UxLCBpcC5ZKTsKICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgUmV2ZXJzZVBvbHlQdExpbmtzKE91dFB0ICpwcCkKewogIGlmICghcHApIHJldHVybjsKICBPdXRQdCAqcHAxLCAqcHAyOwogIHBwMSA9IHBwOwogIGRvIHsKICBwcDIgPSBwcDEtPk5leHQ7CiAgcHAxLT5OZXh0ID0gcHAxLT5QcmV2OwogIHBwMS0+UHJldiA9IHBwMjsKICBwcDEgPSBwcDI7CiAgfSB3aGlsZSggcHAxICE9IHBwICk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgRGlzcG9zZU91dFB0cyhPdXRQdComIHBwKQp7CiAgaWYgKHBwID09IDApIHJldHVybjsKICAgIHBwLT5QcmV2LT5OZXh0ID0gMDsKICB3aGlsZSggcHAgKQogIHsKICAgIE91dFB0ICp0bXBQcCA9IHBwOwogICAgcHAgPSBwcC0+TmV4dDsKICAgIGRlbGV0ZSB0bXBQcDsKICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmlubGluZSB2b2lkIEluaXRFZGdlKFRFZGdlKiBlLCBURWRnZSogZU5leHQsIFRFZGdlKiBlUHJldiwgY29uc3QgSW50UG9pbnQmIFB0KQp7CiAgc3RkOjptZW1zZXQoZSwgMCwgc2l6ZW9mKFRFZGdlKSk7CiAgZS0+TmV4dCA9IGVOZXh0OwogIGUtPlByZXYgPSBlUHJldjsKICBlLT5DdXJyID0gUHQ7CiAgZS0+T3V0SWR4ID0gVW5hc3NpZ25lZDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBJbml0RWRnZTIoVEVkZ2UmIGUsIFBvbHlUeXBlIFB0KQp7CiAgaWYgKGUuQ3Vyci5ZID49IGUuTmV4dC0+Q3Vyci5ZKQogIHsKICAgIGUuQm90ID0gZS5DdXJyOwogICAgZS5Ub3AgPSBlLk5leHQtPkN1cnI7CiAgfSBlbHNlCiAgewogICAgZS5Ub3AgPSBlLkN1cnI7CiAgICBlLkJvdCA9IGUuTmV4dC0+Q3VycjsKICB9CiAgU2V0RHgoZSk7CiAgZS5Qb2x5VHlwID0gUHQ7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KClRFZGdlKiBSZW1vdmVFZGdlKFRFZGdlKiBlKQp7CiAgLy9yZW1vdmVzIGUgZnJvbSBkb3VibGVfbGlua2VkX2xpc3QgKGJ1dCB3aXRob3V0IHJlbW92aW5nIGZyb20gbWVtb3J5KQogIGUtPlByZXYtPk5leHQgPSBlLT5OZXh0OwogIGUtPk5leHQtPlByZXYgPSBlLT5QcmV2OwogIFRFZGdlKiByZXN1bHQgPSBlLT5OZXh0OwogIGUtPlByZXYgPSAwOyAvL2ZsYWcgYXMgcmVtb3ZlZCAoc2VlIENsaXBwZXJCYXNlLkNsZWFyKQogIHJldHVybiByZXN1bHQ7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmlubGluZSB2b2lkIFJldmVyc2VIb3Jpem9udGFsKFRFZGdlICZlKQp7CiAgLy9zd2FwIGhvcml6b250YWwgZWRnZXMnIFRvcCBhbmQgQm90dG9tIHgncyBzbyB0aGV5IGZvbGxvdyB0aGUgbmF0dXJhbAogIC8vcHJvZ3Jlc3Npb24gb2YgdGhlIGJvdW5kcyAtIGllIHNvIHRoZWlyIHhib3RzIHdpbGwgYWxpZ24gd2l0aCB0aGUKICAvL2Fkam9pbmluZyBsb3dlciBlZGdlLiBbSGVscGZ1bCBpbiB0aGUgUHJvY2Vzc0hvcml6b250YWwoKSBtZXRob2QuXQogIHN0ZDo6c3dhcChlLlRvcC5YLCBlLkJvdC5YKTsKI2lmZGVmIHVzZV94eXogIAogIHN0ZDo6c3dhcChlLlRvcC5aLCBlLkJvdC5aKTsKI2VuZGlmCn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU3dhcFBvaW50cyhJbnRQb2ludCAmcHQxLCBJbnRQb2ludCAmcHQyKQp7CiAgSW50UG9pbnQgdG1wID0gcHQxOwogIHB0MSA9IHB0MjsKICBwdDIgPSB0bXA7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmJvb2wgR2V0T3ZlcmxhcFNlZ21lbnQoSW50UG9pbnQgcHQxYSwgSW50UG9pbnQgcHQxYiwgSW50UG9pbnQgcHQyYSwKICBJbnRQb2ludCBwdDJiLCBJbnRQb2ludCAmcHQxLCBJbnRQb2ludCAmcHQyKQp7CiAgLy9wcmVjb25kaXRpb246IHNlZ21lbnRzIGFyZSBDb2xsaW5lYXIuCiAgaWYgKEFicyhwdDFhLlggLSBwdDFiLlgpID4gQWJzKHB0MWEuWSAtIHB0MWIuWSkpCiAgewogICAgaWYgKHB0MWEuWCA+IHB0MWIuWCkgU3dhcFBvaW50cyhwdDFhLCBwdDFiKTsKICAgIGlmIChwdDJhLlggPiBwdDJiLlgpIFN3YXBQb2ludHMocHQyYSwgcHQyYik7CiAgICBpZiAocHQxYS5YID4gcHQyYS5YKSBwdDEgPSBwdDFhOyBlbHNlIHB0MSA9IHB0MmE7CiAgICBpZiAocHQxYi5YIDwgcHQyYi5YKSBwdDIgPSBwdDFiOyBlbHNlIHB0MiA9IHB0MmI7CiAgICByZXR1cm4gcHQxLlggPCBwdDIuWDsKICB9IGVsc2UKICB7CiAgICBpZiAocHQxYS5ZIDwgcHQxYi5ZKSBTd2FwUG9pbnRzKHB0MWEsIHB0MWIpOwogICAgaWYgKHB0MmEuWSA8IHB0MmIuWSkgU3dhcFBvaW50cyhwdDJhLCBwdDJiKTsKICAgIGlmIChwdDFhLlkgPCBwdDJhLlkpIHB0MSA9IHB0MWE7IGVsc2UgcHQxID0gcHQyYTsKICAgIGlmIChwdDFiLlkgPiBwdDJiLlkpIHB0MiA9IHB0MWI7IGVsc2UgcHQyID0gcHQyYjsKICAgIHJldHVybiBwdDEuWSA+IHB0Mi5ZOwogIH0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBGaXJzdElzQm90dG9tUHQoY29uc3QgT3V0UHQqIGJ0bVB0MSwgY29uc3QgT3V0UHQqIGJ0bVB0MikKewogIE91dFB0ICpwID0gYnRtUHQxLT5QcmV2OwogIHdoaWxlICgocC0+UHQgPT0gYnRtUHQxLT5QdCkgJiYgKHAgIT0gYnRtUHQxKSkgcCA9IHAtPlByZXY7CiAgZG91YmxlIGR4MXAgPSBzdGQ6OmZhYnMoR2V0RHgoYnRtUHQxLT5QdCwgcC0+UHQpKTsKICBwID0gYnRtUHQxLT5OZXh0OwogIHdoaWxlICgocC0+UHQgPT0gYnRtUHQxLT5QdCkgJiYgKHAgIT0gYnRtUHQxKSkgcCA9IHAtPk5leHQ7CiAgZG91YmxlIGR4MW4gPSBzdGQ6OmZhYnMoR2V0RHgoYnRtUHQxLT5QdCwgcC0+UHQpKTsKCiAgcCA9IGJ0bVB0Mi0+UHJldjsKICB3aGlsZSAoKHAtPlB0ID09IGJ0bVB0Mi0+UHQpICYmIChwICE9IGJ0bVB0MikpIHAgPSBwLT5QcmV2OwogIGRvdWJsZSBkeDJwID0gc3RkOjpmYWJzKEdldER4KGJ0bVB0Mi0+UHQsIHAtPlB0KSk7CiAgcCA9IGJ0bVB0Mi0+TmV4dDsKICB3aGlsZSAoKHAtPlB0ID09IGJ0bVB0Mi0+UHQpICYmIChwICE9IGJ0bVB0MikpIHAgPSBwLT5OZXh0OwogIGRvdWJsZSBkeDJuID0gc3RkOjpmYWJzKEdldER4KGJ0bVB0Mi0+UHQsIHAtPlB0KSk7CgogIGlmIChzdGQ6Om1heChkeDFwLCBkeDFuKSA9PSBzdGQ6Om1heChkeDJwLCBkeDJuKSAmJgogICAgc3RkOjptaW4oZHgxcCwgZHgxbikgPT0gc3RkOjptaW4oZHgycCwgZHgybikpCiAgICAgIHJldHVybiBBcmVhKGJ0bVB0MSkgPiAwOyAvL2lmIG90aGVyd2lzZSBpZGVudGljYWwgdXNlIG9yaWVudGF0aW9uCiAgZWxzZQogICAgcmV0dXJuIChkeDFwID49IGR4MnAgJiYgZHgxcCA+PSBkeDJuKSB8fCAoZHgxbiA+PSBkeDJwICYmIGR4MW4gPj0gZHgybik7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCk91dFB0KiBHZXRCb3R0b21QdChPdXRQdCAqcHApCnsKICBPdXRQdCogZHVwcyA9IDA7CiAgT3V0UHQqIHAgPSBwcC0+TmV4dDsKICB3aGlsZSAocCAhPSBwcCkKICB7CiAgICBpZiAocC0+UHQuWSA+IHBwLT5QdC5ZKQogICAgewogICAgICBwcCA9IHA7CiAgICAgIGR1cHMgPSAwOwogICAgfQogICAgZWxzZSBpZiAocC0+UHQuWSA9PSBwcC0+UHQuWSAmJiBwLT5QdC5YIDw9IHBwLT5QdC5YKQogICAgewogICAgICBpZiAocC0+UHQuWCA8IHBwLT5QdC5YKQogICAgICB7CiAgICAgICAgZHVwcyA9IDA7CiAgICAgICAgcHAgPSBwOwogICAgICB9IGVsc2UKICAgICAgewogICAgICAgIGlmIChwLT5OZXh0ICE9IHBwICYmIHAtPlByZXYgIT0gcHApIGR1cHMgPSBwOwogICAgICB9CiAgICB9CiAgICBwID0gcC0+TmV4dDsKICB9CiAgaWYgKGR1cHMpCiAgewogICAgLy90aGVyZSBhcHBlYXJzIHRvIGJlIGF0IGxlYXN0IDIgdmVydGljZXMgYXQgQm90dG9tUHQgc28gLi4uCiAgICB3aGlsZSAoZHVwcyAhPSBwKQogICAgewogICAgICBpZiAoIUZpcnN0SXNCb3R0b21QdChwLCBkdXBzKSkgcHAgPSBkdXBzOwogICAgICBkdXBzID0gZHVwcy0+TmV4dDsKICAgICAgd2hpbGUgKGR1cHMtPlB0ICE9IHBwLT5QdCkgZHVwcyA9IGR1cHMtPk5leHQ7CiAgICB9CiAgfQogIHJldHVybiBwcDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBQdDJJc0JldHdlZW5QdDFBbmRQdDMoY29uc3QgSW50UG9pbnQgcHQxLAogIGNvbnN0IEludFBvaW50IHB0MiwgY29uc3QgSW50UG9pbnQgcHQzKQp7CiAgaWYgKChwdDEgPT0gcHQzKSB8fCAocHQxID09IHB0MikgfHwgKHB0MyA9PSBwdDIpKQogICAgcmV0dXJuIGZhbHNlOwogIGVsc2UgaWYgKHB0MS5YICE9IHB0My5YKQogICAgcmV0dXJuIChwdDIuWCA+IHB0MS5YKSA9PSAocHQyLlggPCBwdDMuWCk7CiAgZWxzZQogICAgcmV0dXJuIChwdDIuWSA+IHB0MS5ZKSA9PSAocHQyLlkgPCBwdDMuWSk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmJvb2wgSG9yelNlZ21lbnRzT3ZlcmxhcChjSW50IHNlZzFhLCBjSW50IHNlZzFiLCBjSW50IHNlZzJhLCBjSW50IHNlZzJiKQp7CiAgaWYgKHNlZzFhID4gc2VnMWIpIHN0ZDo6c3dhcChzZWcxYSwgc2VnMWIpOwogIGlmIChzZWcyYSA+IHNlZzJiKSBzdGQ6OnN3YXAoc2VnMmEsIHNlZzJiKTsKICByZXR1cm4gKHNlZzFhIDwgc2VnMmIpICYmIChzZWcyYSA8IHNlZzFiKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gQ2xpcHBlckJhc2UgY2xhc3MgbWV0aG9kcyAuLi4KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkNsaXBwZXJCYXNlOjpDbGlwcGVyQmFzZSgpIC8vY29uc3RydWN0b3IKewogIG1fQ3VycmVudExNID0gbV9NaW5pbWFMaXN0LmJlZ2luKCk7IC8vYmVnaW4oKSA9PSBlbmQoKSBoZXJlCiAgbV9Vc2VGdWxsUmFuZ2UgPSBmYWxzZTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKQ2xpcHBlckJhc2U6On5DbGlwcGVyQmFzZSgpIC8vZGVzdHJ1Y3Rvcgp7CiAgQ2xlYXIoKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBSYW5nZVRlc3QoY29uc3QgSW50UG9pbnQmIFB0LCBib29sJiB1c2VGdWxsUmFuZ2UpCnsKICBpZiAodXNlRnVsbFJhbmdlKQogIHsKICAgIGlmIChQdC5YID4gaGlSYW5nZSB8fCBQdC5ZID4gaGlSYW5nZSB8fCAtUHQuWCA+IGhpUmFuZ2UgfHwgLVB0LlkgPiBoaVJhbmdlKSAKICAgICAgdGhyb3cgY2xpcHBlckV4Y2VwdGlvbigiQ29vcmRpbmF0ZSBvdXRzaWRlIGFsbG93ZWQgcmFuZ2UiKTsKICB9CiAgZWxzZSBpZiAoUHQuWCA+IGxvUmFuZ2V8fCBQdC5ZID4gbG9SYW5nZSB8fCAtUHQuWCA+IGxvUmFuZ2UgfHwgLVB0LlkgPiBsb1JhbmdlKSAKICB7CiAgICB1c2VGdWxsUmFuZ2UgPSB0cnVlOwogICAgUmFuZ2VUZXN0KFB0LCB1c2VGdWxsUmFuZ2UpOwogIH0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKVEVkZ2UqIEZpbmROZXh0TG9jTWluKFRFZGdlKiBFKQp7CiAgZm9yICg7OykKICB7CiAgICB3aGlsZSAoRS0+Qm90ICE9IEUtPlByZXYtPkJvdCB8fCBFLT5DdXJyID09IEUtPlRvcCkgRSA9IEUtPk5leHQ7CiAgICBpZiAoIUlzSG9yaXpvbnRhbCgqRSkgJiYgIUlzSG9yaXpvbnRhbCgqRS0+UHJldikpIGJyZWFrOwogICAgd2hpbGUgKElzSG9yaXpvbnRhbCgqRS0+UHJldikpIEUgPSBFLT5QcmV2OwogICAgVEVkZ2UqIEUyID0gRTsKICAgIHdoaWxlIChJc0hvcml6b250YWwoKkUpKSBFID0gRS0+TmV4dDsKICAgIGlmIChFLT5Ub3AuWSA9PSBFLT5QcmV2LT5Cb3QuWSkgY29udGludWU7IC8vaWUganVzdCBhbiBpbnRlcm1lZGlhdGUgaG9yei4KICAgIGlmIChFMi0+UHJldi0+Qm90LlggPCBFLT5Cb3QuWCkgRSA9IEUyOwogICAgYnJlYWs7CiAgfQogIHJldHVybiBFOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpURWRnZSogQ2xpcHBlckJhc2U6OlByb2Nlc3NCb3VuZChURWRnZSogRSwgYm9vbCBOZXh0SXNGb3J3YXJkKQp7CiAgVEVkZ2UgKlJlc3VsdCA9IEU7CiAgVEVkZ2UgKkhvcnogPSAwOwoKICBpZiAoRS0+T3V0SWR4ID09IFNraXApCiAgewogICAgLy9pZiBlZGdlcyBzdGlsbCByZW1haW4gaW4gdGhlIGN1cnJlbnQgYm91bmQgYmV5b25kIHRoZSBza2lwIGVkZ2UgdGhlbgogICAgLy9jcmVhdGUgYW5vdGhlciBMb2NNaW4gYW5kIGNhbGwgUHJvY2Vzc0JvdW5kIG9uY2UgbW9yZQogICAgaWYgKE5leHRJc0ZvcndhcmQpCiAgICB7CiAgICAgIHdoaWxlIChFLT5Ub3AuWSA9PSBFLT5OZXh0LT5Cb3QuWSkgRSA9IEUtPk5leHQ7CiAgICAgIC8vZG9uJ3QgaW5jbHVkZSB0b3AgaG9yaXpvbnRhbHMgd2hlbiBwYXJzaW5nIGEgYm91bmQgYSBzZWNvbmQgdGltZSwKICAgICAgLy90aGV5IHdpbGwgYmUgY29udGFpbmVkIGluIHRoZSBvcHBvc2l0ZSBib3VuZCAuLi4KICAgICAgd2hpbGUgKEUgIT0gUmVzdWx0ICYmIElzSG9yaXpvbnRhbCgqRSkpIEUgPSBFLT5QcmV2OwogICAgfQogICAgZWxzZQogICAgewogICAgICB3aGlsZSAoRS0+VG9wLlkgPT0gRS0+UHJldi0+Qm90LlkpIEUgPSBFLT5QcmV2OwogICAgICB3aGlsZSAoRSAhPSBSZXN1bHQgJiYgSXNIb3Jpem9udGFsKCpFKSkgRSA9IEUtPk5leHQ7CiAgICB9CgogICAgaWYgKEUgPT0gUmVzdWx0KQogICAgewogICAgICBpZiAoTmV4dElzRm9yd2FyZCkgUmVzdWx0ID0gRS0+TmV4dDsKICAgICAgZWxzZSBSZXN1bHQgPSBFLT5QcmV2OwogICAgfQogICAgZWxzZQogICAgewogICAgICAvL3RoZXJlIGFyZSBtb3JlIGVkZ2VzIGluIHRoZSBib3VuZCBiZXlvbmQgcmVzdWx0IHN0YXJ0aW5nIHdpdGggRQogICAgICBpZiAoTmV4dElzRm9yd2FyZCkKICAgICAgICBFID0gUmVzdWx0LT5OZXh0OwogICAgICBlbHNlCiAgICAgICAgRSA9IFJlc3VsdC0+UHJldjsKICAgICAgTWluaW1hTGlzdDo6dmFsdWVfdHlwZSBsb2NNaW47CiAgICAgIGxvY01pbi5ZID0gRS0+Qm90Llk7CiAgICAgIGxvY01pbi5MZWZ0Qm91bmQgPSAwOwogICAgICBsb2NNaW4uUmlnaHRCb3VuZCA9IEU7CiAgICAgIEUtPldpbmREZWx0YSA9IDA7CiAgICAgIFJlc3VsdCA9IFByb2Nlc3NCb3VuZChFLCBOZXh0SXNGb3J3YXJkKTsKICAgICAgbV9NaW5pbWFMaXN0LnB1c2hfYmFjayhsb2NNaW4pOwogICAgfQogICAgcmV0dXJuIFJlc3VsdDsKICB9CgogIFRFZGdlICpFU3RhcnQ7CgogIGlmIChJc0hvcml6b250YWwoKkUpKQogIHsKICAgIC8vV2UgbmVlZCB0byBiZSBjYXJlZnVsIHdpdGggb3BlbiBwYXRocyBiZWNhdXNlIHRoaXMgbWF5IG5vdCBiZSBhCiAgICAvL3RydWUgbG9jYWwgbWluaW1hIChpZSBFIG1heSBiZSBmb2xsb3dpbmcgYSBza2lwIGVkZ2UpLgogICAgLy9BbHNvLCBjb25zZWN1dGl2ZSBob3J6LiBlZGdlcyBtYXkgc3RhcnQgaGVhZGluZyBsZWZ0IGJlZm9yZSBnb2luZyByaWdodC4KICAgIGlmIChOZXh0SXNGb3J3YXJkKSAKICAgICAgRVN0YXJ0ID0gRS0+UHJldjsKICAgIGVsc2UgCiAgICAgIEVTdGFydCA9IEUtPk5leHQ7CiAgICBpZiAoSXNIb3Jpem9udGFsKCpFU3RhcnQpKSAvL2llIGFuIGFkam9pbmluZyBob3Jpem9udGFsIHNraXAgZWRnZQogICAgICB7CiAgICAgICAgaWYgKEVTdGFydC0+Qm90LlggIT0gRS0+Qm90LlggJiYgRVN0YXJ0LT5Ub3AuWCAhPSBFLT5Cb3QuWCkKICAgICAgICAgIFJldmVyc2VIb3Jpem9udGFsKCpFKTsKICAgICAgfQogICAgICBlbHNlIGlmIChFU3RhcnQtPkJvdC5YICE9IEUtPkJvdC5YKQogICAgICAgIFJldmVyc2VIb3Jpem9udGFsKCpFKTsKICB9CiAgCiAgRVN0YXJ0ID0gRTsKICBpZiAoTmV4dElzRm9yd2FyZCkKICB7CiAgICB3aGlsZSAoUmVzdWx0LT5Ub3AuWSA9PSBSZXN1bHQtPk5leHQtPkJvdC5ZICYmIFJlc3VsdC0+TmV4dC0+T3V0SWR4ICE9IFNraXApCiAgICAgIFJlc3VsdCA9IFJlc3VsdC0+TmV4dDsKICAgIGlmIChJc0hvcml6b250YWwoKlJlc3VsdCkgJiYgUmVzdWx0LT5OZXh0LT5PdXRJZHggIT0gU2tpcCkKICAgIHsKICAgICAgLy9uYjogYXQgdGhlIHRvcCBvZiBhIGJvdW5kLCBob3Jpem9udGFscyBhcmUgYWRkZWQgdG8gdGhlIGJvdW5kCiAgICAgIC8vb25seSB3aGVuIHRoZSBwcmVjZWRpbmcgZWRnZSBhdHRhY2hlcyB0byB0aGUgaG9yaXpvbnRhbCdzIGxlZnQgdmVydGV4CiAgICAgIC8vdW5sZXNzIGEgU2tpcCBlZGdlIGlzIGVuY291bnRlcmVkIHdoZW4gdGhhdCBiZWNvbWVzIHRoZSB0b3AgZGl2aWRlCiAgICAgIEhvcnogPSBSZXN1bHQ7CiAgICAgIHdoaWxlIChJc0hvcml6b250YWwoKkhvcnotPlByZXYpKSBIb3J6ID0gSG9yei0+UHJldjsKICAgICAgaWYgKEhvcnotPlByZXYtPlRvcC5YID4gUmVzdWx0LT5OZXh0LT5Ub3AuWCkgUmVzdWx0ID0gSG9yei0+UHJldjsKICAgIH0KICAgIHdoaWxlIChFICE9IFJlc3VsdCkgCiAgICB7CiAgICAgIEUtPk5leHRJbkxNTCA9IEUtPk5leHQ7CiAgICAgIGlmIChJc0hvcml6b250YWwoKkUpICYmIEUgIT0gRVN0YXJ0ICYmCiAgICAgICAgRS0+Qm90LlggIT0gRS0+UHJldi0+VG9wLlgpIFJldmVyc2VIb3Jpem9udGFsKCpFKTsKICAgICAgRSA9IEUtPk5leHQ7CiAgICB9CiAgICBpZiAoSXNIb3Jpem9udGFsKCpFKSAmJiBFICE9IEVTdGFydCAmJiBFLT5Cb3QuWCAhPSBFLT5QcmV2LT5Ub3AuWCkgCiAgICAgIFJldmVyc2VIb3Jpem9udGFsKCpFKTsKICAgIFJlc3VsdCA9IFJlc3VsdC0+TmV4dDsgLy9tb3ZlIHRvIHRoZSBlZGdlIGp1c3QgYmV5b25kIGN1cnJlbnQgYm91bmQKICB9IGVsc2UKICB7CiAgICB3aGlsZSAoUmVzdWx0LT5Ub3AuWSA9PSBSZXN1bHQtPlByZXYtPkJvdC5ZICYmIFJlc3VsdC0+UHJldi0+T3V0SWR4ICE9IFNraXApIAogICAgICBSZXN1bHQgPSBSZXN1bHQtPlByZXY7CiAgICBpZiAoSXNIb3Jpem9udGFsKCpSZXN1bHQpICYmIFJlc3VsdC0+UHJldi0+T3V0SWR4ICE9IFNraXApCiAgICB7CiAgICAgIEhvcnogPSBSZXN1bHQ7CiAgICAgIHdoaWxlIChJc0hvcml6b250YWwoKkhvcnotPk5leHQpKSBIb3J6ID0gSG9yei0+TmV4dDsKICAgICAgaWYgKEhvcnotPk5leHQtPlRvcC5YID09IFJlc3VsdC0+UHJldi0+VG9wLlggfHwKICAgICAgICAgIEhvcnotPk5leHQtPlRvcC5YID4gUmVzdWx0LT5QcmV2LT5Ub3AuWCkgUmVzdWx0ID0gSG9yei0+TmV4dDsKICAgIH0KCiAgICB3aGlsZSAoRSAhPSBSZXN1bHQpCiAgICB7CiAgICAgIEUtPk5leHRJbkxNTCA9IEUtPlByZXY7CiAgICAgIGlmIChJc0hvcml6b250YWwoKkUpICYmIEUgIT0gRVN0YXJ0ICYmIEUtPkJvdC5YICE9IEUtPk5leHQtPlRvcC5YKSAKICAgICAgICBSZXZlcnNlSG9yaXpvbnRhbCgqRSk7CiAgICAgIEUgPSBFLT5QcmV2OwogICAgfQogICAgaWYgKElzSG9yaXpvbnRhbCgqRSkgJiYgRSAhPSBFU3RhcnQgJiYgRS0+Qm90LlggIT0gRS0+TmV4dC0+VG9wLlgpIAogICAgICBSZXZlcnNlSG9yaXpvbnRhbCgqRSk7CiAgICBSZXN1bHQgPSBSZXN1bHQtPlByZXY7IC8vbW92ZSB0byB0aGUgZWRnZSBqdXN0IGJleW9uZCBjdXJyZW50IGJvdW5kCiAgfQoKICByZXR1cm4gUmVzdWx0Owp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpib29sIENsaXBwZXJCYXNlOjpBZGRQYXRoKGNvbnN0IFBhdGggJnBnLCBQb2x5VHlwZSBQb2x5VHlwLCBib29sIENsb3NlZCkKewojaWZkZWYgdXNlX2xpbmVzCiAgaWYgKCFDbG9zZWQgJiYgUG9seVR5cCA9PSBwdENsaXApCiAgICB0aHJvdyBjbGlwcGVyRXhjZXB0aW9uKCJBZGRQYXRoOiBPcGVuIHBhdGhzIG11c3QgYmUgc3ViamVjdC4iKTsKI2Vsc2UKICBpZiAoIUNsb3NlZCkKICAgIHRocm93IGNsaXBwZXJFeGNlcHRpb24oIkFkZFBhdGg6IE9wZW4gcGF0aHMgaGF2ZSBiZWVuIGRpc2FibGVkLiIpOwojZW5kaWYKCiAgaW50IGhpZ2hJID0gKGludClwZy5zaXplKCkgLTE7CiAgaWYgKENsb3NlZCkgd2hpbGUgKGhpZ2hJID4gMCAmJiAocGdbaGlnaEldID09IHBnWzBdKSkgLS1oaWdoSTsKICB3aGlsZSAoaGlnaEkgPiAwICYmIChwZ1toaWdoSV0gPT0gcGdbaGlnaEkgLTFdKSkgLS1oaWdoSTsKICBpZiAoKENsb3NlZCAmJiBoaWdoSSA8IDIpIHx8ICghQ2xvc2VkICYmIGhpZ2hJIDwgMSkpIHJldHVybiBmYWxzZTsKCiAgLy9jcmVhdGUgYSBuZXcgZWRnZSBhcnJheSAuLi4KICBURWRnZSAqZWRnZXMgPSBuZXcgVEVkZ2UgW2hpZ2hJICsxXTsKCiAgYm9vbCBJc0ZsYXQgPSB0cnVlOwogIC8vMS4gQmFzaWMgKGZpcnN0KSBlZGdlIGluaXRpYWxpemF0aW9uIC4uLgogIHRyeQogIHsKICAgIGVkZ2VzWzFdLkN1cnIgPSBwZ1sxXTsKICAgIFJhbmdlVGVzdChwZ1swXSwgbV9Vc2VGdWxsUmFuZ2UpOwogICAgUmFuZ2VUZXN0KHBnW2hpZ2hJXSwgbV9Vc2VGdWxsUmFuZ2UpOwogICAgSW5pdEVkZ2UoJmVkZ2VzWzBdLCAmZWRnZXNbMV0sICZlZGdlc1toaWdoSV0sIHBnWzBdKTsKICAgIEluaXRFZGdlKCZlZGdlc1toaWdoSV0sICZlZGdlc1swXSwgJmVkZ2VzW2hpZ2hJLTFdLCBwZ1toaWdoSV0pOwogICAgZm9yIChpbnQgaSA9IGhpZ2hJIC0gMTsgaSA+PSAxOyAtLWkpCiAgICB7CiAgICAgIFJhbmdlVGVzdChwZ1tpXSwgbV9Vc2VGdWxsUmFuZ2UpOwogICAgICBJbml0RWRnZSgmZWRnZXNbaV0sICZlZGdlc1tpKzFdLCAmZWRnZXNbaS0xXSwgcGdbaV0pOwogICAgfQogIH0KICBjYXRjaCguLi4pCiAgewogICAgZGVsZXRlIFtdIGVkZ2VzOwogICAgdGhyb3c7IC8vcmFuZ2UgdGVzdCBmYWlscwogIH0KICBURWRnZSAqZVN0YXJ0ID0gJmVkZ2VzWzBdOwoKICAvLzIuIFJlbW92ZSBkdXBsaWNhdGUgdmVydGljZXMsIGFuZCAod2hlbiBjbG9zZWQpIGNvbGxpbmVhciBlZGdlcyAuLi4KICBURWRnZSAqRSA9IGVTdGFydCwgKmVMb29wU3RvcCA9IGVTdGFydDsKICBmb3IgKDs7KQogIHsKICAgIC8vbmI6IGFsbG93cyBtYXRjaGluZyBzdGFydCBhbmQgZW5kIHBvaW50cyB3aGVuIG5vdCBDbG9zZWQgLi4uCiAgICBpZiAoRS0+Q3VyciA9PSBFLT5OZXh0LT5DdXJyICYmIChDbG9zZWQgfHwgRS0+TmV4dCAhPSBlU3RhcnQpKQogICAgewogICAgICBpZiAoRSA9PSBFLT5OZXh0KSBicmVhazsKICAgICAgaWYgKEUgPT0gZVN0YXJ0KSBlU3RhcnQgPSBFLT5OZXh0OwogICAgICBFID0gUmVtb3ZlRWRnZShFKTsKICAgICAgZUxvb3BTdG9wID0gRTsKICAgICAgY29udGludWU7CiAgICB9CiAgICBpZiAoRS0+UHJldiA9PSBFLT5OZXh0KSAKICAgICAgYnJlYWs7IC8vb25seSB0d28gdmVydGljZXMKICAgIGVsc2UgaWYgKENsb3NlZCAmJgogICAgICBTbG9wZXNFcXVhbChFLT5QcmV2LT5DdXJyLCBFLT5DdXJyLCBFLT5OZXh0LT5DdXJyLCBtX1VzZUZ1bGxSYW5nZSkgJiYgCiAgICAgICghbV9QcmVzZXJ2ZUNvbGxpbmVhciB8fAogICAgICAhUHQySXNCZXR3ZWVuUHQxQW5kUHQzKEUtPlByZXYtPkN1cnIsIEUtPkN1cnIsIEUtPk5leHQtPkN1cnIpKSkKICAgIHsKICAgICAgLy9Db2xsaW5lYXIgZWRnZXMgYXJlIGFsbG93ZWQgZm9yIG9wZW4gcGF0aHMgYnV0IGluIGNsb3NlZCBwYXRocwogICAgICAvL3RoZSBkZWZhdWx0IGlzIHRvIG1lcmdlIGFkamFjZW50IGNvbGxpbmVhciBlZGdlcyBpbnRvIGEgc2luZ2xlIGVkZ2UuCiAgICAgIC8vSG93ZXZlciwgaWYgdGhlIFByZXNlcnZlQ29sbGluZWFyIHByb3BlcnR5IGlzIGVuYWJsZWQsIG9ubHkgb3ZlcmxhcHBpbmcKICAgICAgLy9jb2xsaW5lYXIgZWRnZXMgKGllIHNwaWtlcykgd2lsbCBiZSByZW1vdmVkIGZyb20gY2xvc2VkIHBhdGhzLgogICAgICBpZiAoRSA9PSBlU3RhcnQpIGVTdGFydCA9IEUtPk5leHQ7CiAgICAgIEUgPSBSZW1vdmVFZGdlKEUpOwogICAgICBFID0gRS0+UHJldjsKICAgICAgZUxvb3BTdG9wID0gRTsKICAgICAgY29udGludWU7CiAgICB9CiAgICBFID0gRS0+TmV4dDsKICAgIGlmICgoRSA9PSBlTG9vcFN0b3ApIHx8ICghQ2xvc2VkICYmIEUtPk5leHQgPT0gZVN0YXJ0KSkgYnJlYWs7CiAgfQoKICBpZiAoKCFDbG9zZWQgJiYgKEUgPT0gRS0+TmV4dCkpIHx8IChDbG9zZWQgJiYgKEUtPlByZXYgPT0gRS0+TmV4dCkpKQogIHsKICAgIGRlbGV0ZSBbXSBlZGdlczsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIGlmICghQ2xvc2VkKQogIHsgCiAgICBtX0hhc09wZW5QYXRocyA9IHRydWU7CiAgICBlU3RhcnQtPlByZXYtPk91dElkeCA9IFNraXA7CiAgfQoKICAvLzMuIERvIHNlY29uZCBzdGFnZSBvZiBlZGdlIGluaXRpYWxpemF0aW9uIC4uLgogIEUgPSBlU3RhcnQ7CiAgZG8KICB7CiAgICBJbml0RWRnZTIoKkUsIFBvbHlUeXApOwogICAgRSA9IEUtPk5leHQ7CiAgICBpZiAoSXNGbGF0ICYmIEUtPkN1cnIuWSAhPSBlU3RhcnQtPkN1cnIuWSkgSXNGbGF0ID0gZmFsc2U7CiAgfQogIHdoaWxlIChFICE9IGVTdGFydCk7CgogIC8vNC4gRmluYWxseSwgYWRkIGVkZ2UgYm91bmRzIHRvIExvY2FsTWluaW1hIGxpc3QgLi4uCgogIC8vVG90YWxseSBmbGF0IHBhdGhzIG11c3QgYmUgaGFuZGxlZCBkaWZmZXJlbnRseSB3aGVuIGFkZGluZyB0aGVtCiAgLy90byBMb2NhbE1pbmltYSBsaXN0IHRvIGF2b2lkIGVuZGxlc3MgbG9vcHMgZXRjIC4uLgogIGlmIChJc0ZsYXQpIAogIHsKICAgIGlmIChDbG9zZWQpIAogICAgewogICAgICBkZWxldGUgW10gZWRnZXM7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIEUtPlByZXYtPk91dElkeCA9IFNraXA7CiAgICBNaW5pbWFMaXN0Ojp2YWx1ZV90eXBlIGxvY01pbjsKICAgIGxvY01pbi5ZID0gRS0+Qm90Llk7CiAgICBsb2NNaW4uTGVmdEJvdW5kID0gMDsKICAgIGxvY01pbi5SaWdodEJvdW5kID0gRTsKICAgIGxvY01pbi5SaWdodEJvdW5kLT5TaWRlID0gZXNSaWdodDsKICAgIGxvY01pbi5SaWdodEJvdW5kLT5XaW5kRGVsdGEgPSAwOwogICAgZm9yICg7OykKICAgIHsKICAgICAgaWYgKEUtPkJvdC5YICE9IEUtPlByZXYtPlRvcC5YKSBSZXZlcnNlSG9yaXpvbnRhbCgqRSk7CiAgICAgIGlmIChFLT5OZXh0LT5PdXRJZHggPT0gU2tpcCkgYnJlYWs7CiAgICAgIEUtPk5leHRJbkxNTCA9IEUtPk5leHQ7CiAgICAgIEUgPSBFLT5OZXh0OwogICAgfQogICAgbV9NaW5pbWFMaXN0LnB1c2hfYmFjayhsb2NNaW4pOwogICAgbV9lZGdlcy5wdXNoX2JhY2soZWRnZXMpOwoJICByZXR1cm4gdHJ1ZTsKICB9CgogIG1fZWRnZXMucHVzaF9iYWNrKGVkZ2VzKTsKICBib29sIGxlZnRCb3VuZElzRm9yd2FyZDsKICBURWRnZSogRU1pbiA9IDA7CgogIC8vd29ya2Fyb3VuZCB0byBhdm9pZCBhbiBlbmRsZXNzIGxvb3AgaW4gdGhlIHdoaWxlIGxvb3AgYmVsb3cgd2hlbgogIC8vb3BlbiBwYXRocyBoYXZlIG1hdGNoaW5nIHN0YXJ0IGFuZCBlbmQgcG9pbnRzIC4uLgogIGlmIChFLT5QcmV2LT5Cb3QgPT0gRS0+UHJldi0+VG9wKSBFID0gRS0+TmV4dDsKCiAgZm9yICg7OykKICB7CiAgICBFID0gRmluZE5leHRMb2NNaW4oRSk7CiAgICBpZiAoRSA9PSBFTWluKSBicmVhazsKICAgIGVsc2UgaWYgKCFFTWluKSBFTWluID0gRTsKCiAgICAvL0UgYW5kIEUuUHJldiBub3cgc2hhcmUgYSBsb2NhbCBtaW5pbWEgKGxlZnQgYWxpZ25lZCBpZiBob3Jpem9udGFsKS4KICAgIC8vQ29tcGFyZSB0aGVpciBzbG9wZXMgdG8gZmluZCB3aGljaCBzdGFydHMgd2hpY2ggYm91bmQgLi4uCiAgICBNaW5pbWFMaXN0Ojp2YWx1ZV90eXBlIGxvY01pbjsKICAgIGxvY01pbi5ZID0gRS0+Qm90Llk7CiAgICBpZiAoRS0+RHggPCBFLT5QcmV2LT5EeCkgCiAgICB7CiAgICAgIGxvY01pbi5MZWZ0Qm91bmQgPSBFLT5QcmV2OwogICAgICBsb2NNaW4uUmlnaHRCb3VuZCA9IEU7CiAgICAgIGxlZnRCb3VuZElzRm9yd2FyZCA9IGZhbHNlOyAvL1EubmV4dEluTE1MID0gUS5wcmV2CiAgICB9IGVsc2UKICAgIHsKICAgICAgbG9jTWluLkxlZnRCb3VuZCA9IEU7CiAgICAgIGxvY01pbi5SaWdodEJvdW5kID0gRS0+UHJldjsKICAgICAgbGVmdEJvdW5kSXNGb3J3YXJkID0gdHJ1ZTsgLy9RLm5leHRJbkxNTCA9IFEubmV4dAogICAgfQoKICAgIGlmICghQ2xvc2VkKSBsb2NNaW4uTGVmdEJvdW5kLT5XaW5kRGVsdGEgPSAwOwogICAgZWxzZSBpZiAobG9jTWluLkxlZnRCb3VuZC0+TmV4dCA9PSBsb2NNaW4uUmlnaHRCb3VuZCkKICAgICAgbG9jTWluLkxlZnRCb3VuZC0+V2luZERlbHRhID0gLTE7CiAgICBlbHNlIGxvY01pbi5MZWZ0Qm91bmQtPldpbmREZWx0YSA9IDE7CiAgICBsb2NNaW4uUmlnaHRCb3VuZC0+V2luZERlbHRhID0gLWxvY01pbi5MZWZ0Qm91bmQtPldpbmREZWx0YTsKCiAgICBFID0gUHJvY2Vzc0JvdW5kKGxvY01pbi5MZWZ0Qm91bmQsIGxlZnRCb3VuZElzRm9yd2FyZCk7CiAgICBpZiAoRS0+T3V0SWR4ID09IFNraXApIEUgPSBQcm9jZXNzQm91bmQoRSwgbGVmdEJvdW5kSXNGb3J3YXJkKTsKCiAgICBURWRnZSogRTIgPSBQcm9jZXNzQm91bmQobG9jTWluLlJpZ2h0Qm91bmQsICFsZWZ0Qm91bmRJc0ZvcndhcmQpOwogICAgaWYgKEUyLT5PdXRJZHggPT0gU2tpcCkgRTIgPSBQcm9jZXNzQm91bmQoRTIsICFsZWZ0Qm91bmRJc0ZvcndhcmQpOwoKICAgIGlmIChsb2NNaW4uTGVmdEJvdW5kLT5PdXRJZHggPT0gU2tpcCkKICAgICAgbG9jTWluLkxlZnRCb3VuZCA9IDA7CiAgICBlbHNlIGlmIChsb2NNaW4uUmlnaHRCb3VuZC0+T3V0SWR4ID09IFNraXApCiAgICAgIGxvY01pbi5SaWdodEJvdW5kID0gMDsKICAgIG1fTWluaW1hTGlzdC5wdXNoX2JhY2sobG9jTWluKTsKICAgIGlmICghbGVmdEJvdW5kSXNGb3J3YXJkKSBFID0gRTI7CiAgfQogIHJldHVybiB0cnVlOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpib29sIENsaXBwZXJCYXNlOjpBZGRQYXRocyhjb25zdCBQYXRocyAmcHBnLCBQb2x5VHlwZSBQb2x5VHlwLCBib29sIENsb3NlZCkKewogIGJvb2wgcmVzdWx0ID0gZmFsc2U7CiAgZm9yIChQYXRoczo6c2l6ZV90eXBlIGkgPSAwOyBpIDwgcHBnLnNpemUoKTsgKytpKQogICAgaWYgKEFkZFBhdGgocHBnW2ldLCBQb2x5VHlwLCBDbG9zZWQpKSByZXN1bHQgPSB0cnVlOwogIHJldHVybiByZXN1bHQ7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlckJhc2U6OkNsZWFyKCkKewogIERpc3Bvc2VMb2NhbE1pbmltYUxpc3QoKTsKICBmb3IgKEVkZ2VMaXN0OjpzaXplX3R5cGUgaSA9IDA7IGkgPCBtX2VkZ2VzLnNpemUoKTsgKytpKQogIHsKICAgIFRFZGdlKiBlZGdlcyA9IG1fZWRnZXNbaV07CiAgICBkZWxldGUgW10gZWRnZXM7CiAgfQogIG1fZWRnZXMuY2xlYXIoKTsKICBtX1VzZUZ1bGxSYW5nZSA9IGZhbHNlOwogIG1fSGFzT3BlblBhdGhzID0gZmFsc2U7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlckJhc2U6OlJlc2V0KCkKewogIG1fQ3VycmVudExNID0gbV9NaW5pbWFMaXN0LmJlZ2luKCk7CiAgaWYgKG1fQ3VycmVudExNID09IG1fTWluaW1hTGlzdC5lbmQoKSkgcmV0dXJuOyAvL2llIG5vdGhpbmcgdG8gcHJvY2VzcwogIHN0ZDo6c29ydChtX01pbmltYUxpc3QuYmVnaW4oKSwgbV9NaW5pbWFMaXN0LmVuZCgpLCBMb2NNaW5Tb3J0ZXIoKSk7CgogIG1fU2NhbmJlYW0gPSBTY2FuYmVhbUxpc3QoKTsgLy9jbGVhcnMvcmVzZXRzIHByaW9yaXR5X3F1ZXVlCiAgLy9yZXNldCBhbGwgZWRnZXMgLi4uCiAgZm9yIChNaW5pbWFMaXN0OjppdGVyYXRvciBsbSA9IG1fTWluaW1hTGlzdC5iZWdpbigpOyBsbSAhPSBtX01pbmltYUxpc3QuZW5kKCk7ICsrbG0pCiAgewogICAgSW5zZXJ0U2NhbmJlYW0obG0tPlkpOwogICAgVEVkZ2UqIGUgPSBsbS0+TGVmdEJvdW5kOwogICAgaWYgKGUpCiAgICB7CiAgICAgIGUtPkN1cnIgPSBlLT5Cb3Q7CiAgICAgIGUtPlNpZGUgPSBlc0xlZnQ7CiAgICAgIGUtPk91dElkeCA9IFVuYXNzaWduZWQ7CiAgICB9CgogICAgZSA9IGxtLT5SaWdodEJvdW5kOwogICAgaWYgKGUpCiAgICB7CiAgICAgIGUtPkN1cnIgPSBlLT5Cb3Q7CiAgICAgIGUtPlNpZGUgPSBlc1JpZ2h0OwogICAgICBlLT5PdXRJZHggPSBVbmFzc2lnbmVkOwogICAgfQogIH0KICBtX0FjdGl2ZUVkZ2VzID0gMDsKICBtX0N1cnJlbnRMTSA9IG1fTWluaW1hTGlzdC5iZWdpbigpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXJCYXNlOjpEaXNwb3NlTG9jYWxNaW5pbWFMaXN0KCkKewogIG1fTWluaW1hTGlzdC5jbGVhcigpOwogIG1fQ3VycmVudExNID0gbV9NaW5pbWFMaXN0LmJlZ2luKCk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmJvb2wgQ2xpcHBlckJhc2U6OlBvcExvY2FsTWluaW1hKGNJbnQgWSwgY29uc3QgTG9jYWxNaW5pbXVtICombG9jTWluKQp7CiAgaWYgKG1fQ3VycmVudExNID09IG1fTWluaW1hTGlzdC5lbmQoKSB8fCAoKm1fQ3VycmVudExNKS5ZICE9IFkpIHJldHVybiBmYWxzZTsKICBsb2NNaW4gPSAmKCptX0N1cnJlbnRMTSk7CiAgKyttX0N1cnJlbnRMTTsKICByZXR1cm4gdHJ1ZTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKSW50UmVjdCBDbGlwcGVyQmFzZTo6R2V0Qm91bmRzKCkKewogIEludFJlY3QgcmVzdWx0OwogIE1pbmltYUxpc3Q6Oml0ZXJhdG9yIGxtID0gbV9NaW5pbWFMaXN0LmJlZ2luKCk7CiAgaWYgKGxtID09IG1fTWluaW1hTGlzdC5lbmQoKSkKICB7CiAgICByZXN1bHQubGVmdCA9IHJlc3VsdC50b3AgPSByZXN1bHQucmlnaHQgPSByZXN1bHQuYm90dG9tID0gMDsKICAgIHJldHVybiByZXN1bHQ7CiAgfQogIHJlc3VsdC5sZWZ0ID0gbG0tPkxlZnRCb3VuZC0+Qm90Llg7CiAgcmVzdWx0LnRvcCA9IGxtLT5MZWZ0Qm91bmQtPkJvdC5ZOwogIHJlc3VsdC5yaWdodCA9IGxtLT5MZWZ0Qm91bmQtPkJvdC5YOwogIHJlc3VsdC5ib3R0b20gPSBsbS0+TGVmdEJvdW5kLT5Cb3QuWTsKICB3aGlsZSAobG0gIT0gbV9NaW5pbWFMaXN0LmVuZCgpKQogIHsKICAgIC8vdG9kbyAtIG5lZWRzIGZpeGluZyBmb3Igb3BlbiBwYXRocwogICAgcmVzdWx0LmJvdHRvbSA9IHN0ZDo6bWF4KHJlc3VsdC5ib3R0b20sIGxtLT5MZWZ0Qm91bmQtPkJvdC5ZKTsKICAgIFRFZGdlKiBlID0gbG0tPkxlZnRCb3VuZDsKICAgIGZvciAoOzspIHsKICAgICAgVEVkZ2UqIGJvdHRvbUUgPSBlOwogICAgICB3aGlsZSAoZS0+TmV4dEluTE1MKQogICAgICB7CiAgICAgICAgaWYgKGUtPkJvdC5YIDwgcmVzdWx0LmxlZnQpIHJlc3VsdC5sZWZ0ID0gZS0+Qm90Llg7CiAgICAgICAgaWYgKGUtPkJvdC5YID4gcmVzdWx0LnJpZ2h0KSByZXN1bHQucmlnaHQgPSBlLT5Cb3QuWDsKICAgICAgICBlID0gZS0+TmV4dEluTE1MOwogICAgICB9CiAgICAgIHJlc3VsdC5sZWZ0ID0gc3RkOjptaW4ocmVzdWx0LmxlZnQsIGUtPkJvdC5YKTsKICAgICAgcmVzdWx0LnJpZ2h0ID0gc3RkOjptYXgocmVzdWx0LnJpZ2h0LCBlLT5Cb3QuWCk7CiAgICAgIHJlc3VsdC5sZWZ0ID0gc3RkOjptaW4ocmVzdWx0LmxlZnQsIGUtPlRvcC5YKTsKICAgICAgcmVzdWx0LnJpZ2h0ID0gc3RkOjptYXgocmVzdWx0LnJpZ2h0LCBlLT5Ub3AuWCk7CiAgICAgIHJlc3VsdC50b3AgPSBzdGQ6Om1pbihyZXN1bHQudG9wLCBlLT5Ub3AuWSk7CiAgICAgIGlmIChib3R0b21FID09IGxtLT5MZWZ0Qm91bmQpIGUgPSBsbS0+UmlnaHRCb3VuZDsKICAgICAgZWxzZSBicmVhazsKICAgIH0KICAgICsrbG07CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlckJhc2U6Okluc2VydFNjYW5iZWFtKGNvbnN0IGNJbnQgWSkKewogIG1fU2NhbmJlYW0ucHVzaChZKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBDbGlwcGVyQmFzZTo6UG9wU2NhbmJlYW0oY0ludCAmWSkKewogIGlmIChtX1NjYW5iZWFtLmVtcHR5KCkpIHJldHVybiBmYWxzZTsKICBZID0gbV9TY2FuYmVhbS50b3AoKTsKICBtX1NjYW5iZWFtLnBvcCgpOwogIHdoaWxlICghbV9TY2FuYmVhbS5lbXB0eSgpICYmIFkgPT0gbV9TY2FuYmVhbS50b3AoKSkgeyBtX1NjYW5iZWFtLnBvcCgpOyB9IC8vIFBvcCBkdXBsaWNhdGVzLgogIHJldHVybiB0cnVlOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXJCYXNlOjpEaXNwb3NlQWxsT3V0UmVjcygpewogIGZvciAoUG9seU91dExpc3Q6OnNpemVfdHlwZSBpID0gMDsgaSA8IG1fUG9seU91dHMuc2l6ZSgpOyArK2kpCiAgICBEaXNwb3NlT3V0UmVjKGkpOwogIG1fUG9seU91dHMuY2xlYXIoKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBDbGlwcGVyQmFzZTo6RGlzcG9zZU91dFJlYyhQb2x5T3V0TGlzdDo6c2l6ZV90eXBlIGluZGV4KQp7CiAgT3V0UmVjICpvdXRSZWMgPSBtX1BvbHlPdXRzW2luZGV4XTsKICBpZiAob3V0UmVjLT5QdHMpIERpc3Bvc2VPdXRQdHMob3V0UmVjLT5QdHMpOwogIGRlbGV0ZSBvdXRSZWM7CiAgbV9Qb2x5T3V0c1tpbmRleF0gPSAwOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXJCYXNlOjpEZWxldGVGcm9tQUVMKFRFZGdlICplKQp7CiAgVEVkZ2UqIEFlbFByZXYgPSBlLT5QcmV2SW5BRUw7CiAgVEVkZ2UqIEFlbE5leHQgPSBlLT5OZXh0SW5BRUw7CiAgaWYgKCFBZWxQcmV2ICYmICAhQWVsTmV4dCAmJiAoZSAhPSBtX0FjdGl2ZUVkZ2VzKSkgcmV0dXJuOyAvL2FscmVhZHkgZGVsZXRlZAogIGlmIChBZWxQcmV2KSBBZWxQcmV2LT5OZXh0SW5BRUwgPSBBZWxOZXh0OwogIGVsc2UgbV9BY3RpdmVFZGdlcyA9IEFlbE5leHQ7CiAgaWYgKEFlbE5leHQpIEFlbE5leHQtPlByZXZJbkFFTCA9IEFlbFByZXY7CiAgZS0+TmV4dEluQUVMID0gMDsKICBlLT5QcmV2SW5BRUwgPSAwOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpPdXRSZWMqIENsaXBwZXJCYXNlOjpDcmVhdGVPdXRSZWMoKQp7CiAgT3V0UmVjKiByZXN1bHQgPSBuZXcgT3V0UmVjOwogIHJlc3VsdC0+SXNIb2xlID0gZmFsc2U7CiAgcmVzdWx0LT5Jc09wZW4gPSBmYWxzZTsKICByZXN1bHQtPkZpcnN0TGVmdCA9IDA7CiAgcmVzdWx0LT5QdHMgPSAwOwogIHJlc3VsdC0+Qm90dG9tUHQgPSAwOwogIHJlc3VsdC0+UG9seU5kID0gMDsKICBtX1BvbHlPdXRzLnB1c2hfYmFjayhyZXN1bHQpOwogIHJlc3VsdC0+SWR4ID0gKGludCltX1BvbHlPdXRzLnNpemUoKSAtIDE7CiAgcmV0dXJuIHJlc3VsdDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBDbGlwcGVyQmFzZTo6U3dhcFBvc2l0aW9uc0luQUVMKFRFZGdlICpFZGdlMSwgVEVkZ2UgKkVkZ2UyKQp7CiAgLy9jaGVjayB0aGF0IG9uZSBvciBvdGhlciBlZGdlIGhhc24ndCBhbHJlYWR5IGJlZW4gcmVtb3ZlZCBmcm9tIEFFTCAuLi4KICBpZiAoRWRnZTEtPk5leHRJbkFFTCA9PSBFZGdlMS0+UHJldkluQUVMIHx8CiAgICBFZGdlMi0+TmV4dEluQUVMID09IEVkZ2UyLT5QcmV2SW5BRUwpIHJldHVybjsKCiAgaWYgKEVkZ2UxLT5OZXh0SW5BRUwgPT0gRWRnZTIpCiAgewogICAgVEVkZ2UqIE5leHQgPSBFZGdlMi0+TmV4dEluQUVMOwogICAgaWYgKE5leHQpIE5leHQtPlByZXZJbkFFTCA9IEVkZ2UxOwogICAgVEVkZ2UqIFByZXYgPSBFZGdlMS0+UHJldkluQUVMOwogICAgaWYgKFByZXYpIFByZXYtPk5leHRJbkFFTCA9IEVkZ2UyOwogICAgRWRnZTItPlByZXZJbkFFTCA9IFByZXY7CiAgICBFZGdlMi0+TmV4dEluQUVMID0gRWRnZTE7CiAgICBFZGdlMS0+UHJldkluQUVMID0gRWRnZTI7CiAgICBFZGdlMS0+TmV4dEluQUVMID0gTmV4dDsKICB9CiAgZWxzZSBpZiAoRWRnZTItPk5leHRJbkFFTCA9PSBFZGdlMSkKICB7CiAgICBURWRnZSogTmV4dCA9IEVkZ2UxLT5OZXh0SW5BRUw7CiAgICBpZiAoTmV4dCkgTmV4dC0+UHJldkluQUVMID0gRWRnZTI7CiAgICBURWRnZSogUHJldiA9IEVkZ2UyLT5QcmV2SW5BRUw7CiAgICBpZiAoUHJldikgUHJldi0+TmV4dEluQUVMID0gRWRnZTE7CiAgICBFZGdlMS0+UHJldkluQUVMID0gUHJldjsKICAgIEVkZ2UxLT5OZXh0SW5BRUwgPSBFZGdlMjsKICAgIEVkZ2UyLT5QcmV2SW5BRUwgPSBFZGdlMTsKICAgIEVkZ2UyLT5OZXh0SW5BRUwgPSBOZXh0OwogIH0KICBlbHNlCiAgewogICAgVEVkZ2UqIE5leHQgPSBFZGdlMS0+TmV4dEluQUVMOwogICAgVEVkZ2UqIFByZXYgPSBFZGdlMS0+UHJldkluQUVMOwogICAgRWRnZTEtPk5leHRJbkFFTCA9IEVkZ2UyLT5OZXh0SW5BRUw7CiAgICBpZiAoRWRnZTEtPk5leHRJbkFFTCkgRWRnZTEtPk5leHRJbkFFTC0+UHJldkluQUVMID0gRWRnZTE7CiAgICBFZGdlMS0+UHJldkluQUVMID0gRWRnZTItPlByZXZJbkFFTDsKICAgIGlmIChFZGdlMS0+UHJldkluQUVMKSBFZGdlMS0+UHJldkluQUVMLT5OZXh0SW5BRUwgPSBFZGdlMTsKICAgIEVkZ2UyLT5OZXh0SW5BRUwgPSBOZXh0OwogICAgaWYgKEVkZ2UyLT5OZXh0SW5BRUwpIEVkZ2UyLT5OZXh0SW5BRUwtPlByZXZJbkFFTCA9IEVkZ2UyOwogICAgRWRnZTItPlByZXZJbkFFTCA9IFByZXY7CiAgICBpZiAoRWRnZTItPlByZXZJbkFFTCkgRWRnZTItPlByZXZJbkFFTC0+TmV4dEluQUVMID0gRWRnZTI7CiAgfQoKICBpZiAoIUVkZ2UxLT5QcmV2SW5BRUwpIG1fQWN0aXZlRWRnZXMgPSBFZGdlMTsKICBlbHNlIGlmICghRWRnZTItPlByZXZJbkFFTCkgbV9BY3RpdmVFZGdlcyA9IEVkZ2UyOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXJCYXNlOjpVcGRhdGVFZGdlSW50b0FFTChURWRnZSAqJmUpCnsKICBpZiAoIWUtPk5leHRJbkxNTCkgCiAgICB0aHJvdyBjbGlwcGVyRXhjZXB0aW9uKCJVcGRhdGVFZGdlSW50b0FFTDogaW52YWxpZCBjYWxsIik7CgogIGUtPk5leHRJbkxNTC0+T3V0SWR4ID0gZS0+T3V0SWR4OwogIFRFZGdlKiBBZWxQcmV2ID0gZS0+UHJldkluQUVMOwogIFRFZGdlKiBBZWxOZXh0ID0gZS0+TmV4dEluQUVMOwogIGlmIChBZWxQcmV2KSBBZWxQcmV2LT5OZXh0SW5BRUwgPSBlLT5OZXh0SW5MTUw7CiAgZWxzZSBtX0FjdGl2ZUVkZ2VzID0gZS0+TmV4dEluTE1MOwogIGlmIChBZWxOZXh0KSBBZWxOZXh0LT5QcmV2SW5BRUwgPSBlLT5OZXh0SW5MTUw7CiAgZS0+TmV4dEluTE1MLT5TaWRlID0gZS0+U2lkZTsKICBlLT5OZXh0SW5MTUwtPldpbmREZWx0YSA9IGUtPldpbmREZWx0YTsKICBlLT5OZXh0SW5MTUwtPldpbmRDbnQgPSBlLT5XaW5kQ250OwogIGUtPk5leHRJbkxNTC0+V2luZENudDIgPSBlLT5XaW5kQ250MjsKICBlID0gZS0+TmV4dEluTE1MOwogIGUtPkN1cnIgPSBlLT5Cb3Q7CiAgZS0+UHJldkluQUVMID0gQWVsUHJldjsKICBlLT5OZXh0SW5BRUwgPSBBZWxOZXh0OwogIGlmICghSXNIb3Jpem9udGFsKCplKSkgSW5zZXJ0U2NhbmJlYW0oZS0+VG9wLlkpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpib29sIENsaXBwZXJCYXNlOjpMb2NhbE1pbmltYVBlbmRpbmcoKQp7CiAgcmV0dXJuIChtX0N1cnJlbnRMTSAhPSBtX01pbmltYUxpc3QuZW5kKCkpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBUQ2xpcHBlciBtZXRob2RzIC4uLgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKQ2xpcHBlcjo6Q2xpcHBlcihpbnQgaW5pdE9wdGlvbnMpIDogQ2xpcHBlckJhc2UoKSAvL2NvbnN0cnVjdG9yCnsKICBtX0V4ZWN1dGVMb2NrZWQgPSBmYWxzZTsKICBtX1VzZUZ1bGxSYW5nZSA9IGZhbHNlOwogIG1fUmV2ZXJzZU91dHB1dCA9ICgoaW5pdE9wdGlvbnMgJiBpb1JldmVyc2VTb2x1dGlvbikgIT0gMCk7CiAgbV9TdHJpY3RTaW1wbGUgPSAoKGluaXRPcHRpb25zICYgaW9TdHJpY3RseVNpbXBsZSkgIT0gMCk7CiAgbV9QcmVzZXJ2ZUNvbGxpbmVhciA9ICgoaW5pdE9wdGlvbnMgJiBpb1ByZXNlcnZlQ29sbGluZWFyKSAhPSAwKTsKICBtX0hhc09wZW5QYXRocyA9IGZhbHNlOwojaWZkZWYgdXNlX3h5eiAgCiAgbV9aRmlsbCA9IDA7CiNlbmRpZgp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojaWZkZWYgdXNlX3h5eiAgCnZvaWQgQ2xpcHBlcjo6WkZpbGxGdW5jdGlvbihaRmlsbENhbGxiYWNrIHpGaWxsRnVuYykKeyAgCiAgbV9aRmlsbCA9IHpGaWxsRnVuYzsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojZW5kaWYKCmJvb2wgQ2xpcHBlcjo6RXhlY3V0ZShDbGlwVHlwZSBjbGlwVHlwZSwgUGF0aHMgJnNvbHV0aW9uLCBQb2x5RmlsbFR5cGUgZmlsbFR5cGUpCnsKICAgIHJldHVybiBFeGVjdXRlKGNsaXBUeXBlLCBzb2x1dGlvbiwgZmlsbFR5cGUsIGZpbGxUeXBlKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBDbGlwcGVyOjpFeGVjdXRlKENsaXBUeXBlIGNsaXBUeXBlLCBQb2x5VHJlZSAmcG9seXRyZWUsIFBvbHlGaWxsVHlwZSBmaWxsVHlwZSkKewogICAgcmV0dXJuIEV4ZWN1dGUoY2xpcFR5cGUsIHBvbHl0cmVlLCBmaWxsVHlwZSwgZmlsbFR5cGUpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpib29sIENsaXBwZXI6OkV4ZWN1dGUoQ2xpcFR5cGUgY2xpcFR5cGUsIFBhdGhzICZzb2x1dGlvbiwKICAgIFBvbHlGaWxsVHlwZSBzdWJqRmlsbFR5cGUsIFBvbHlGaWxsVHlwZSBjbGlwRmlsbFR5cGUpCnsKICBpZiggbV9FeGVjdXRlTG9ja2VkICkgcmV0dXJuIGZhbHNlOwogIGlmIChtX0hhc09wZW5QYXRocykKICAgIHRocm93IGNsaXBwZXJFeGNlcHRpb24oIkVycm9yOiBQb2x5VHJlZSBzdHJ1Y3QgaXMgbmVlZGVkIGZvciBvcGVuIHBhdGggY2xpcHBpbmcuIik7CiAgbV9FeGVjdXRlTG9ja2VkID0gdHJ1ZTsKICBzb2x1dGlvbi5yZXNpemUoMCk7CiAgbV9TdWJqRmlsbFR5cGUgPSBzdWJqRmlsbFR5cGU7CiAgbV9DbGlwRmlsbFR5cGUgPSBjbGlwRmlsbFR5cGU7CiAgbV9DbGlwVHlwZSA9IGNsaXBUeXBlOwogIG1fVXNpbmdQb2x5VHJlZSA9IGZhbHNlOwogIGJvb2wgc3VjY2VlZGVkID0gRXhlY3V0ZUludGVybmFsKCk7CiAgaWYgKHN1Y2NlZWRlZCkgQnVpbGRSZXN1bHQoc29sdXRpb24pOwogIERpc3Bvc2VBbGxPdXRSZWNzKCk7CiAgbV9FeGVjdXRlTG9ja2VkID0gZmFsc2U7CiAgcmV0dXJuIHN1Y2NlZWRlZDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBDbGlwcGVyOjpFeGVjdXRlKENsaXBUeXBlIGNsaXBUeXBlLCBQb2x5VHJlZSYgcG9seXRyZWUsCiAgICBQb2x5RmlsbFR5cGUgc3ViakZpbGxUeXBlLCBQb2x5RmlsbFR5cGUgY2xpcEZpbGxUeXBlKQp7CiAgaWYoIG1fRXhlY3V0ZUxvY2tlZCApIHJldHVybiBmYWxzZTsKICBtX0V4ZWN1dGVMb2NrZWQgPSB0cnVlOwogIG1fU3ViakZpbGxUeXBlID0gc3ViakZpbGxUeXBlOwogIG1fQ2xpcEZpbGxUeXBlID0gY2xpcEZpbGxUeXBlOwogIG1fQ2xpcFR5cGUgPSBjbGlwVHlwZTsKICBtX1VzaW5nUG9seVRyZWUgPSB0cnVlOwogIGJvb2wgc3VjY2VlZGVkID0gRXhlY3V0ZUludGVybmFsKCk7CiAgaWYgKHN1Y2NlZWRlZCkgQnVpbGRSZXN1bHQyKHBvbHl0cmVlKTsKICBEaXNwb3NlQWxsT3V0UmVjcygpOwogIG1fRXhlY3V0ZUxvY2tlZCA9IGZhbHNlOwogIHJldHVybiBzdWNjZWVkZWQ7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6Rml4SG9sZUxpbmthZ2UoT3V0UmVjICZvdXRyZWMpCnsKICAvL3NraXAgT3V0UmVjcyB0aGF0IChhKSBjb250YWluIG91dGVybW9zdCBwb2x5Z29ucyBvcgogIC8vKGIpIGFscmVhZHkgaGF2ZSB0aGUgY29ycmVjdCBvd25lci9jaGlsZCBsaW5rYWdlIC4uLgogIGlmICghb3V0cmVjLkZpcnN0TGVmdCB8fCAgICAgICAgICAgICAgICAKICAgICAgKG91dHJlYy5Jc0hvbGUgIT0gb3V0cmVjLkZpcnN0TGVmdC0+SXNIb2xlICYmCiAgICAgIG91dHJlYy5GaXJzdExlZnQtPlB0cykpIHJldHVybjsKCiAgT3V0UmVjKiBvcmZsID0gb3V0cmVjLkZpcnN0TGVmdDsKICB3aGlsZSAob3JmbCAmJiAoKG9yZmwtPklzSG9sZSA9PSBvdXRyZWMuSXNIb2xlKSB8fCAhb3JmbC0+UHRzKSkKICAgICAgb3JmbCA9IG9yZmwtPkZpcnN0TGVmdDsKICBvdXRyZWMuRmlyc3RMZWZ0ID0gb3JmbDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBDbGlwcGVyOjpFeGVjdXRlSW50ZXJuYWwoKQp7CiAgYm9vbCBzdWNjZWVkZWQgPSB0cnVlOwogIHRyeSB7CiAgICBSZXNldCgpOwogICAgbV9NYXhpbWEgPSBNYXhpbWFMaXN0KCk7CiAgICBtX1NvcnRlZEVkZ2VzID0gMDsKCiAgICBzdWNjZWVkZWQgPSB0cnVlOwogICAgY0ludCBib3RZLCB0b3BZOwogICAgaWYgKCFQb3BTY2FuYmVhbShib3RZKSkgcmV0dXJuIGZhbHNlOwogICAgSW5zZXJ0TG9jYWxNaW5pbWFJbnRvQUVMKGJvdFkpOwogICAgd2hpbGUgKFBvcFNjYW5iZWFtKHRvcFkpIHx8IExvY2FsTWluaW1hUGVuZGluZygpKQogICAgewogICAgICBQcm9jZXNzSG9yaXpvbnRhbHMoKTsKCSAgICBDbGVhckdob3N0Sm9pbnMoKTsKICAgICAgaWYgKCFQcm9jZXNzSW50ZXJzZWN0aW9ucyh0b3BZKSkKICAgICAgewogICAgICAgIHN1Y2NlZWRlZCA9IGZhbHNlOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIFByb2Nlc3NFZGdlc0F0VG9wT2ZTY2FuYmVhbSh0b3BZKTsKICAgICAgYm90WSA9IHRvcFk7CiAgICAgIEluc2VydExvY2FsTWluaW1hSW50b0FFTChib3RZKTsKICAgIH0KICB9CiAgY2F0Y2goLi4uKSAKICB7CiAgICBzdWNjZWVkZWQgPSBmYWxzZTsKICB9CgogIGlmIChzdWNjZWVkZWQpCiAgewogICAgLy9maXggb3JpZW50YXRpb25zIC4uLgogICAgZm9yIChQb2x5T3V0TGlzdDo6c2l6ZV90eXBlIGkgPSAwOyBpIDwgbV9Qb2x5T3V0cy5zaXplKCk7ICsraSkKICAgIHsKICAgICAgT3V0UmVjICpvdXRSZWMgPSBtX1BvbHlPdXRzW2ldOwogICAgICBpZiAoIW91dFJlYy0+UHRzIHx8IG91dFJlYy0+SXNPcGVuKSBjb250aW51ZTsKICAgICAgaWYgKChvdXRSZWMtPklzSG9sZSBeIG1fUmV2ZXJzZU91dHB1dCkgPT0gKEFyZWEoKm91dFJlYykgPiAwKSkKICAgICAgICBSZXZlcnNlUG9seVB0TGlua3Mob3V0UmVjLT5QdHMpOwogICAgfQoKICAgIGlmICghbV9Kb2lucy5lbXB0eSgpKSBKb2luQ29tbW9uRWRnZXMoKTsKCiAgICAvL3VuZm9ydHVuYXRlbHkgRml4dXBPdXRQb2x5Z29uKCkgbXVzdCBiZSBkb25lIGFmdGVyIEpvaW5Db21tb25FZGdlcygpCiAgICBmb3IgKFBvbHlPdXRMaXN0OjpzaXplX3R5cGUgaSA9IDA7IGkgPCBtX1BvbHlPdXRzLnNpemUoKTsgKytpKQogICAgewogICAgICBPdXRSZWMgKm91dFJlYyA9IG1fUG9seU91dHNbaV07CiAgICAgIGlmICghb3V0UmVjLT5QdHMpIGNvbnRpbnVlOwogICAgICBpZiAob3V0UmVjLT5Jc09wZW4pCiAgICAgICAgRml4dXBPdXRQb2x5bGluZSgqb3V0UmVjKTsKICAgICAgZWxzZQogICAgICAgIEZpeHVwT3V0UG9seWdvbigqb3V0UmVjKTsKICAgIH0KCiAgICBpZiAobV9TdHJpY3RTaW1wbGUpIERvU2ltcGxlUG9seWdvbnMoKTsKICB9CgogIENsZWFySm9pbnMoKTsKICBDbGVhckdob3N0Sm9pbnMoKTsKICByZXR1cm4gc3VjY2VlZGVkOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXI6OlNldFdpbmRpbmdDb3VudChURWRnZSAmZWRnZSkKewogIFRFZGdlICplID0gZWRnZS5QcmV2SW5BRUw7CiAgLy9maW5kIHRoZSBlZGdlIG9mIHRoZSBzYW1lIHBvbHl0eXBlIHRoYXQgaW1tZWRpYXRlbHkgcHJlY2VlZHMgJ2VkZ2UnIGluIEFFTAogIHdoaWxlIChlICAmJiAoKGUtPlBvbHlUeXAgIT0gZWRnZS5Qb2x5VHlwKSB8fCAoZS0+V2luZERlbHRhID09IDApKSkgZSA9IGUtPlByZXZJbkFFTDsKICBpZiAoIWUpCiAgewogICAgaWYgKGVkZ2UuV2luZERlbHRhID09IDApCiAgICB7CiAgICAgIFBvbHlGaWxsVHlwZSBwZnQgPSAoZWRnZS5Qb2x5VHlwID09IHB0U3ViamVjdCA/IG1fU3ViakZpbGxUeXBlIDogbV9DbGlwRmlsbFR5cGUpOwogICAgICBlZGdlLldpbmRDbnQgPSAocGZ0ID09IHBmdE5lZ2F0aXZlID8gLTEgOiAxKTsKICAgIH0KICAgIGVsc2UKICAgICAgZWRnZS5XaW5kQ250ID0gZWRnZS5XaW5kRGVsdGE7CiAgICBlZGdlLldpbmRDbnQyID0gMDsKICAgIGUgPSBtX0FjdGl2ZUVkZ2VzOyAvL2llIGdldCByZWFkeSB0byBjYWxjIFdpbmRDbnQyCiAgfSAgIAogIGVsc2UgaWYgKGVkZ2UuV2luZERlbHRhID09IDAgJiYgbV9DbGlwVHlwZSAhPSBjdFVuaW9uKQogIHsKICAgIGVkZ2UuV2luZENudCA9IDE7CiAgICBlZGdlLldpbmRDbnQyID0gZS0+V2luZENudDI7CiAgICBlID0gZS0+TmV4dEluQUVMOyAvL2llIGdldCByZWFkeSB0byBjYWxjIFdpbmRDbnQyCiAgfQogIGVsc2UgaWYgKElzRXZlbk9kZEZpbGxUeXBlKGVkZ2UpKQogIHsKICAgIC8vRXZlbk9kZCBmaWxsaW5nIC4uLgogICAgaWYgKGVkZ2UuV2luZERlbHRhID09IDApCiAgICB7CiAgICAgIC8vYXJlIHdlIGluc2lkZSBhIHN1YmogcG9seWdvbiAuLi4KICAgICAgYm9vbCBJbnNpZGUgPSB0cnVlOwogICAgICBURWRnZSAqZTIgPSBlLT5QcmV2SW5BRUw7CiAgICAgIHdoaWxlIChlMikKICAgICAgewogICAgICAgIGlmIChlMi0+UG9seVR5cCA9PSBlLT5Qb2x5VHlwICYmIGUyLT5XaW5kRGVsdGEgIT0gMCkgCiAgICAgICAgICBJbnNpZGUgPSAhSW5zaWRlOwogICAgICAgIGUyID0gZTItPlByZXZJbkFFTDsKICAgICAgfQogICAgICBlZGdlLldpbmRDbnQgPSAoSW5zaWRlID8gMCA6IDEpOwogICAgfQogICAgZWxzZQogICAgewogICAgICBlZGdlLldpbmRDbnQgPSBlZGdlLldpbmREZWx0YTsKICAgIH0KICAgIGVkZ2UuV2luZENudDIgPSBlLT5XaW5kQ250MjsKICAgIGUgPSBlLT5OZXh0SW5BRUw7IC8vaWUgZ2V0IHJlYWR5IHRvIGNhbGMgV2luZENudDIKICB9IAogIGVsc2UKICB7CiAgICAvL25vblplcm8sIFBvc2l0aXZlIG9yIE5lZ2F0aXZlIGZpbGxpbmcgLi4uCiAgICBpZiAoZS0+V2luZENudCAqIGUtPldpbmREZWx0YSA8IDApCiAgICB7CiAgICAgIC8vcHJldiBlZGdlIGlzICdkZWNyZWFzaW5nJyBXaW5kQ291bnQgKFdDKSB0b3dhcmQgemVybwogICAgICAvL3NvIHdlJ3JlIG91dHNpZGUgdGhlIHByZXZpb3VzIHBvbHlnb24gLi4uCiAgICAgIGlmIChBYnMoZS0+V2luZENudCkgPiAxKQogICAgICB7CiAgICAgICAgLy9vdXRzaWRlIHByZXYgcG9seSBidXQgc3RpbGwgaW5zaWRlIGFub3RoZXIuCiAgICAgICAgLy93aGVuIHJldmVyc2luZyBkaXJlY3Rpb24gb2YgcHJldiBwb2x5IHVzZSB0aGUgc2FtZSBXQyAKICAgICAgICBpZiAoZS0+V2luZERlbHRhICogZWRnZS5XaW5kRGVsdGEgPCAwKSBlZGdlLldpbmRDbnQgPSBlLT5XaW5kQ250OwogICAgICAgIC8vb3RoZXJ3aXNlIGNvbnRpbnVlIHRvICdkZWNyZWFzZScgV0MgLi4uCiAgICAgICAgZWxzZSBlZGdlLldpbmRDbnQgPSBlLT5XaW5kQ250ICsgZWRnZS5XaW5kRGVsdGE7CiAgICAgIH0gCiAgICAgIGVsc2UKICAgICAgICAvL25vdyBvdXRzaWRlIGFsbCBwb2x5cyBvZiBzYW1lIHBvbHl0eXBlIHNvIHNldCBvd24gV0MgLi4uCiAgICAgICAgZWRnZS5XaW5kQ250ID0gKGVkZ2UuV2luZERlbHRhID09IDAgPyAxIDogZWRnZS5XaW5kRGVsdGEpOwogICAgfSBlbHNlCiAgICB7CiAgICAgIC8vcHJldiBlZGdlIGlzICdpbmNyZWFzaW5nJyBXaW5kQ291bnQgKFdDKSBhd2F5IGZyb20gemVybwogICAgICAvL3NvIHdlJ3JlIGluc2lkZSB0aGUgcHJldmlvdXMgcG9seWdvbiAuLi4KICAgICAgaWYgKGVkZ2UuV2luZERlbHRhID09IDApIAogICAgICAgIGVkZ2UuV2luZENudCA9IChlLT5XaW5kQ250IDwgMCA/IGUtPldpbmRDbnQgLSAxIDogZS0+V2luZENudCArIDEpOwogICAgICAvL2lmIHdpbmQgZGlyZWN0aW9uIGlzIHJldmVyc2luZyBwcmV2IHRoZW4gdXNlIHNhbWUgV0MKICAgICAgZWxzZSBpZiAoZS0+V2luZERlbHRhICogZWRnZS5XaW5kRGVsdGEgPCAwKSBlZGdlLldpbmRDbnQgPSBlLT5XaW5kQ250OwogICAgICAvL290aGVyd2lzZSBhZGQgdG8gV0MgLi4uCiAgICAgIGVsc2UgZWRnZS5XaW5kQ250ID0gZS0+V2luZENudCArIGVkZ2UuV2luZERlbHRhOwogICAgfQogICAgZWRnZS5XaW5kQ250MiA9IGUtPldpbmRDbnQyOwogICAgZSA9IGUtPk5leHRJbkFFTDsgLy9pZSBnZXQgcmVhZHkgdG8gY2FsYyBXaW5kQ250MgogIH0KCiAgLy91cGRhdGUgV2luZENudDIgLi4uCiAgaWYgKElzRXZlbk9kZEFsdEZpbGxUeXBlKGVkZ2UpKQogIHsKICAgIC8vRXZlbk9kZCBmaWxsaW5nIC4uLgogICAgd2hpbGUgKGUgIT0gJmVkZ2UpCiAgICB7CiAgICAgIGlmIChlLT5XaW5kRGVsdGEgIT0gMCkKICAgICAgICBlZGdlLldpbmRDbnQyID0gKGVkZ2UuV2luZENudDIgPT0gMCA/IDEgOiAwKTsKICAgICAgZSA9IGUtPk5leHRJbkFFTDsKICAgIH0KICB9IGVsc2UKICB7CiAgICAvL25vblplcm8sIFBvc2l0aXZlIG9yIE5lZ2F0aXZlIGZpbGxpbmcgLi4uCiAgICB3aGlsZSAoIGUgIT0gJmVkZ2UgKQogICAgewogICAgICBlZGdlLldpbmRDbnQyICs9IGUtPldpbmREZWx0YTsKICAgICAgZSA9IGUtPk5leHRJbkFFTDsKICAgIH0KICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmJvb2wgQ2xpcHBlcjo6SXNFdmVuT2RkRmlsbFR5cGUoY29uc3QgVEVkZ2UmIGVkZ2UpIGNvbnN0CnsKICBpZiAoZWRnZS5Qb2x5VHlwID09IHB0U3ViamVjdCkKICAgIHJldHVybiBtX1N1YmpGaWxsVHlwZSA9PSBwZnRFdmVuT2RkOyBlbHNlCiAgICByZXR1cm4gbV9DbGlwRmlsbFR5cGUgPT0gcGZ0RXZlbk9kZDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBDbGlwcGVyOjpJc0V2ZW5PZGRBbHRGaWxsVHlwZShjb25zdCBURWRnZSYgZWRnZSkgY29uc3QKewogIGlmIChlZGdlLlBvbHlUeXAgPT0gcHRTdWJqZWN0KQogICAgcmV0dXJuIG1fQ2xpcEZpbGxUeXBlID09IHBmdEV2ZW5PZGQ7IGVsc2UKICAgIHJldHVybiBtX1N1YmpGaWxsVHlwZSA9PSBwZnRFdmVuT2RkOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpib29sIENsaXBwZXI6OklzQ29udHJpYnV0aW5nKGNvbnN0IFRFZGdlJiBlZGdlKSBjb25zdAp7CiAgUG9seUZpbGxUeXBlIHBmdCwgcGZ0MjsKICBpZiAoZWRnZS5Qb2x5VHlwID09IHB0U3ViamVjdCkKICB7CiAgICBwZnQgPSBtX1N1YmpGaWxsVHlwZTsKICAgIHBmdDIgPSBtX0NsaXBGaWxsVHlwZTsKICB9IGVsc2UKICB7CiAgICBwZnQgPSBtX0NsaXBGaWxsVHlwZTsKICAgIHBmdDIgPSBtX1N1YmpGaWxsVHlwZTsKICB9CgogIHN3aXRjaChwZnQpCiAgewogICAgY2FzZSBwZnRFdmVuT2RkOiAKICAgICAgLy9yZXR1cm4gZmFsc2UgaWYgYSBzdWJqIGxpbmUgaGFzIGJlZW4gZmxhZ2dlZCBhcyBpbnNpZGUgYSBzdWJqIHBvbHlnb24KICAgICAgaWYgKGVkZ2UuV2luZERlbHRhID09IDAgJiYgZWRnZS5XaW5kQ250ICE9IDEpIHJldHVybiBmYWxzZTsKICAgICAgYnJlYWs7CiAgICBjYXNlIHBmdE5vblplcm86CiAgICAgIGlmIChBYnMoZWRnZS5XaW5kQ250KSAhPSAxKSByZXR1cm4gZmFsc2U7CiAgICAgIGJyZWFrOwogICAgY2FzZSBwZnRQb3NpdGl2ZTogCiAgICAgIGlmIChlZGdlLldpbmRDbnQgIT0gMSkgcmV0dXJuIGZhbHNlOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6IC8vcGZ0TmVnYXRpdmUKICAgICAgaWYgKGVkZ2UuV2luZENudCAhPSAtMSkgcmV0dXJuIGZhbHNlOwogIH0KCiAgc3dpdGNoKG1fQ2xpcFR5cGUpCiAgewogICAgY2FzZSBjdEludGVyc2VjdGlvbjoKICAgICAgc3dpdGNoKHBmdDIpCiAgICAgIHsKICAgICAgICBjYXNlIHBmdEV2ZW5PZGQ6IAogICAgICAgIGNhc2UgcGZ0Tm9uWmVybzogCiAgICAgICAgICByZXR1cm4gKGVkZ2UuV2luZENudDIgIT0gMCk7CiAgICAgICAgY2FzZSBwZnRQb3NpdGl2ZTogCiAgICAgICAgICByZXR1cm4gKGVkZ2UuV2luZENudDIgPiAwKTsKICAgICAgICBkZWZhdWx0OiAKICAgICAgICAgIHJldHVybiAoZWRnZS5XaW5kQ250MiA8IDApOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgY2FzZSBjdFVuaW9uOgogICAgICBzd2l0Y2gocGZ0MikKICAgICAgewogICAgICAgIGNhc2UgcGZ0RXZlbk9kZDogCiAgICAgICAgY2FzZSBwZnROb25aZXJvOiAKICAgICAgICAgIHJldHVybiAoZWRnZS5XaW5kQ250MiA9PSAwKTsKICAgICAgICBjYXNlIHBmdFBvc2l0aXZlOiAKICAgICAgICAgIHJldHVybiAoZWRnZS5XaW5kQ250MiA8PSAwKTsKICAgICAgICBkZWZhdWx0OiAKICAgICAgICAgIHJldHVybiAoZWRnZS5XaW5kQ250MiA+PSAwKTsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgY3REaWZmZXJlbmNlOgogICAgICBpZiAoZWRnZS5Qb2x5VHlwID09IHB0U3ViamVjdCkKICAgICAgICBzd2l0Y2gocGZ0MikKICAgICAgICB7CiAgICAgICAgICBjYXNlIHBmdEV2ZW5PZGQ6IAogICAgICAgICAgY2FzZSBwZnROb25aZXJvOiAKICAgICAgICAgICAgcmV0dXJuIChlZGdlLldpbmRDbnQyID09IDApOwogICAgICAgICAgY2FzZSBwZnRQb3NpdGl2ZTogCiAgICAgICAgICAgIHJldHVybiAoZWRnZS5XaW5kQ250MiA8PSAwKTsKICAgICAgICAgIGRlZmF1bHQ6IAogICAgICAgICAgICByZXR1cm4gKGVkZ2UuV2luZENudDIgPj0gMCk7CiAgICAgICAgfQogICAgICBlbHNlCiAgICAgICAgc3dpdGNoKHBmdDIpCiAgICAgICAgewogICAgICAgICAgY2FzZSBwZnRFdmVuT2RkOiAKICAgICAgICAgIGNhc2UgcGZ0Tm9uWmVybzogCiAgICAgICAgICAgIHJldHVybiAoZWRnZS5XaW5kQ250MiAhPSAwKTsKICAgICAgICAgIGNhc2UgcGZ0UG9zaXRpdmU6IAogICAgICAgICAgICByZXR1cm4gKGVkZ2UuV2luZENudDIgPiAwKTsKICAgICAgICAgIGRlZmF1bHQ6IAogICAgICAgICAgICByZXR1cm4gKGVkZ2UuV2luZENudDIgPCAwKTsKICAgICAgICB9CiAgICAgIGJyZWFrOwogICAgY2FzZSBjdFhvcjoKICAgICAgaWYgKGVkZ2UuV2luZERlbHRhID09IDApIC8vWE9yIGFsd2F5cyBjb250cmlidXRpbmcgdW5sZXNzIG9wZW4KICAgICAgICBzd2l0Y2gocGZ0MikKICAgICAgICB7CiAgICAgICAgICBjYXNlIHBmdEV2ZW5PZGQ6IAogICAgICAgICAgY2FzZSBwZnROb25aZXJvOiAKICAgICAgICAgICAgcmV0dXJuIChlZGdlLldpbmRDbnQyID09IDApOwogICAgICAgICAgY2FzZSBwZnRQb3NpdGl2ZTogCiAgICAgICAgICAgIHJldHVybiAoZWRnZS5XaW5kQ250MiA8PSAwKTsKICAgICAgICAgIGRlZmF1bHQ6IAogICAgICAgICAgICByZXR1cm4gKGVkZ2UuV2luZENudDIgPj0gMCk7CiAgICAgICAgfQogICAgICBlbHNlIAogICAgICAgIHJldHVybiB0cnVlOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiB0cnVlOwogIH0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKT3V0UHQqIENsaXBwZXI6OkFkZExvY2FsTWluUG9seShURWRnZSAqZTEsIFRFZGdlICplMiwgY29uc3QgSW50UG9pbnQgJlB0KQp7CiAgT3V0UHQqIHJlc3VsdDsKICBURWRnZSAqZSwgKnByZXZFOwogIGlmIChJc0hvcml6b250YWwoKmUyKSB8fCAoIGUxLT5EeCA+IGUyLT5EeCApKQogIHsKICAgIHJlc3VsdCA9IEFkZE91dFB0KGUxLCBQdCk7CiAgICBlMi0+T3V0SWR4ID0gZTEtPk91dElkeDsKICAgIGUxLT5TaWRlID0gZXNMZWZ0OwogICAgZTItPlNpZGUgPSBlc1JpZ2h0OwogICAgZSA9IGUxOwogICAgaWYgKGUtPlByZXZJbkFFTCA9PSBlMikKICAgICAgcHJldkUgPSBlMi0+UHJldkluQUVMOyAKICAgIGVsc2UKICAgICAgcHJldkUgPSBlLT5QcmV2SW5BRUw7CiAgfSBlbHNlCiAgewogICAgcmVzdWx0ID0gQWRkT3V0UHQoZTIsIFB0KTsKICAgIGUxLT5PdXRJZHggPSBlMi0+T3V0SWR4OwogICAgZTEtPlNpZGUgPSBlc1JpZ2h0OwogICAgZTItPlNpZGUgPSBlc0xlZnQ7CiAgICBlID0gZTI7CiAgICBpZiAoZS0+UHJldkluQUVMID09IGUxKQogICAgICAgIHByZXZFID0gZTEtPlByZXZJbkFFTDsKICAgIGVsc2UKICAgICAgICBwcmV2RSA9IGUtPlByZXZJbkFFTDsKICB9CgogIGlmIChwcmV2RSAmJiBwcmV2RS0+T3V0SWR4ID49IDApCiAgewogICAgY0ludCB4UHJldiA9IFRvcFgoKnByZXZFLCBQdC5ZKTsKICAgIGNJbnQgeEUgPSBUb3BYKCplLCBQdC5ZKTsKICAgIGlmICh4UHJldiA9PSB4RSAmJiAoZS0+V2luZERlbHRhICE9IDApICYmIChwcmV2RS0+V2luZERlbHRhICE9IDApICYmCiAgICAgIFNsb3Blc0VxdWFsKEludFBvaW50KHhQcmV2LCBQdC5ZKSwgcHJldkUtPlRvcCwgSW50UG9pbnQoeEUsIFB0LlkpLCBlLT5Ub3AsIG1fVXNlRnVsbFJhbmdlKSkKICAgIHsKICAgICAgT3V0UHQqIG91dFB0ID0gQWRkT3V0UHQocHJldkUsIFB0KTsKICAgICAgQWRkSm9pbihyZXN1bHQsIG91dFB0LCBlLT5Ub3ApOwogICAgfQogIH0KICByZXR1cm4gcmVzdWx0Owp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXI6OkFkZExvY2FsTWF4UG9seShURWRnZSAqZTEsIFRFZGdlICplMiwgY29uc3QgSW50UG9pbnQgJlB0KQp7CiAgQWRkT3V0UHQoIGUxLCBQdCApOwogIGlmIChlMi0+V2luZERlbHRhID09IDApIEFkZE91dFB0KGUyLCBQdCk7CiAgaWYoIGUxLT5PdXRJZHggPT0gZTItPk91dElkeCApCiAgewogICAgZTEtPk91dElkeCA9IFVuYXNzaWduZWQ7CiAgICBlMi0+T3V0SWR4ID0gVW5hc3NpZ25lZDsKICB9CiAgZWxzZSBpZiAoZTEtPk91dElkeCA8IGUyLT5PdXRJZHgpIAogICAgQXBwZW5kUG9seWdvbihlMSwgZTIpOyAKICBlbHNlIAogICAgQXBwZW5kUG9seWdvbihlMiwgZTEpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXI6OkFkZEVkZ2VUb1NFTChURWRnZSAqZWRnZSkKewogIC8vU0VMIHBvaW50ZXJzIGluIFBFZGdlIGFyZSByZXVzZWQgdG8gYnVpbGQgYSBsaXN0IG9mIGhvcml6b250YWwgZWRnZXMuCiAgLy9Ib3dldmVyLCB3ZSBkb24ndCBuZWVkIHRvIHdvcnJ5IGFib3V0IG9yZGVyIHdpdGggaG9yaXpvbnRhbCBlZGdlIHByb2Nlc3NpbmcuCiAgaWYoICFtX1NvcnRlZEVkZ2VzICkKICB7CiAgICBtX1NvcnRlZEVkZ2VzID0gZWRnZTsKICAgIGVkZ2UtPlByZXZJblNFTCA9IDA7CiAgICBlZGdlLT5OZXh0SW5TRUwgPSAwOwogIH0KICBlbHNlCiAgewogICAgZWRnZS0+TmV4dEluU0VMID0gbV9Tb3J0ZWRFZGdlczsKICAgIGVkZ2UtPlByZXZJblNFTCA9IDA7CiAgICBtX1NvcnRlZEVkZ2VzLT5QcmV2SW5TRUwgPSBlZGdlOwogICAgbV9Tb3J0ZWRFZGdlcyA9IGVkZ2U7CiAgfQp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpib29sIENsaXBwZXI6OlBvcEVkZ2VGcm9tU0VMKFRFZGdlIComZWRnZSkKewogIGlmICghbV9Tb3J0ZWRFZGdlcykgcmV0dXJuIGZhbHNlOwogIGVkZ2UgPSBtX1NvcnRlZEVkZ2VzOwogIERlbGV0ZUZyb21TRUwobV9Tb3J0ZWRFZGdlcyk7CiAgcmV0dXJuIHRydWU7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6Q29weUFFTFRvU0VMKCkKewogIFRFZGdlKiBlID0gbV9BY3RpdmVFZGdlczsKICBtX1NvcnRlZEVkZ2VzID0gZTsKICB3aGlsZSAoIGUgKQogIHsKICAgIGUtPlByZXZJblNFTCA9IGUtPlByZXZJbkFFTDsKICAgIGUtPk5leHRJblNFTCA9IGUtPk5leHRJbkFFTDsKICAgIGUgPSBlLT5OZXh0SW5BRUw7CiAgfQp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXI6OkFkZEpvaW4oT3V0UHQgKm9wMSwgT3V0UHQgKm9wMiwgY29uc3QgSW50UG9pbnQgT2ZmUHQpCnsKICBKb2luKiBqID0gbmV3IEpvaW47CiAgai0+T3V0UHQxID0gb3AxOwogIGotPk91dFB0MiA9IG9wMjsKICBqLT5PZmZQdCA9IE9mZlB0OwogIG1fSm9pbnMucHVzaF9iYWNrKGopOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXI6OkNsZWFySm9pbnMoKQp7CiAgZm9yIChKb2luTGlzdDo6c2l6ZV90eXBlIGkgPSAwOyBpIDwgbV9Kb2lucy5zaXplKCk7IGkrKykKICAgIGRlbGV0ZSBtX0pvaW5zW2ldOwogIG1fSm9pbnMucmVzaXplKDApOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXI6OkNsZWFyR2hvc3RKb2lucygpCnsKICBmb3IgKEpvaW5MaXN0OjpzaXplX3R5cGUgaSA9IDA7IGkgPCBtX0dob3N0Sm9pbnMuc2l6ZSgpOyBpKyspCiAgICBkZWxldGUgbV9HaG9zdEpvaW5zW2ldOwogIG1fR2hvc3RKb2lucy5yZXNpemUoMCk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6QWRkR2hvc3RKb2luKE91dFB0ICpvcCwgY29uc3QgSW50UG9pbnQgT2ZmUHQpCnsKICBKb2luKiBqID0gbmV3IEpvaW47CiAgai0+T3V0UHQxID0gb3A7CiAgai0+T3V0UHQyID0gMDsKICBqLT5PZmZQdCA9IE9mZlB0OwogIG1fR2hvc3RKb2lucy5wdXNoX2JhY2soaik7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6SW5zZXJ0TG9jYWxNaW5pbWFJbnRvQUVMKGNvbnN0IGNJbnQgYm90WSkKewogIGNvbnN0IExvY2FsTWluaW11bSAqbG07CiAgd2hpbGUgKFBvcExvY2FsTWluaW1hKGJvdFksIGxtKSkKICB7CiAgICBURWRnZSogbGIgPSBsbS0+TGVmdEJvdW5kOwogICAgVEVkZ2UqIHJiID0gbG0tPlJpZ2h0Qm91bmQ7CiAgICAKICAgIE91dFB0ICpPcDEgPSAwOwogICAgaWYgKCFsYikKICAgIHsKICAgICAgLy9uYjogZG9uJ3QgaW5zZXJ0IExCIGludG8gZWl0aGVyIEFFTCBvciBTRUwKICAgICAgSW5zZXJ0RWRnZUludG9BRUwocmIsIDApOwogICAgICBTZXRXaW5kaW5nQ291bnQoKnJiKTsKICAgICAgaWYgKElzQ29udHJpYnV0aW5nKCpyYikpCiAgICAgICAgT3AxID0gQWRkT3V0UHQocmIsIHJiLT5Cb3QpOyAKICAgIH0gCiAgICBlbHNlIGlmICghcmIpCiAgICB7CiAgICAgIEluc2VydEVkZ2VJbnRvQUVMKGxiLCAwKTsKICAgICAgU2V0V2luZGluZ0NvdW50KCpsYik7CiAgICAgIGlmIChJc0NvbnRyaWJ1dGluZygqbGIpKQogICAgICAgIE9wMSA9IEFkZE91dFB0KGxiLCBsYi0+Qm90KTsKICAgICAgSW5zZXJ0U2NhbmJlYW0obGItPlRvcC5ZKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgSW5zZXJ0RWRnZUludG9BRUwobGIsIDApOwogICAgICBJbnNlcnRFZGdlSW50b0FFTChyYiwgbGIpOwogICAgICBTZXRXaW5kaW5nQ291bnQoICpsYiApOwogICAgICByYi0+V2luZENudCA9IGxiLT5XaW5kQ250OwogICAgICByYi0+V2luZENudDIgPSBsYi0+V2luZENudDI7CiAgICAgIGlmIChJc0NvbnRyaWJ1dGluZygqbGIpKQogICAgICAgIE9wMSA9IEFkZExvY2FsTWluUG9seShsYiwgcmIsIGxiLT5Cb3QpOyAgICAgIAogICAgICBJbnNlcnRTY2FuYmVhbShsYi0+VG9wLlkpOwogICAgfQoKICAgICBpZiAocmIpCiAgICAgewoJCSBpZiAoSXNIb3Jpem9udGFsKCpyYikpCgkJIHsKCQkJIEFkZEVkZ2VUb1NFTChyYik7CgkJCSBpZiAocmItPk5leHRJbkxNTCkgCgkJCQkgSW5zZXJ0U2NhbmJlYW0ocmItPk5leHRJbkxNTC0+VG9wLlkpOwoJCSB9CgkJIGVsc2UgSW5zZXJ0U2NhbmJlYW0oIHJiLT5Ub3AuWSApOwogICAgIH0KCiAgICBpZiAoIWxiIHx8ICFyYikgY29udGludWU7CgogICAgLy9pZiBhbnkgb3V0cHV0IHBvbHlnb25zIHNoYXJlIGFuIGVkZ2UsIHRoZXknbGwgbmVlZCBqb2luaW5nIGxhdGVyIC4uLgogICAgaWYgKE9wMSAmJiBJc0hvcml6b250YWwoKnJiKSAmJiAKICAgICAgbV9HaG9zdEpvaW5zLnNpemUoKSA+IDAgJiYgKHJiLT5XaW5kRGVsdGEgIT0gMCkpCiAgICB7CiAgICAgIGZvciAoSm9pbkxpc3Q6OnNpemVfdHlwZSBpID0gMDsgaSA8IG1fR2hvc3RKb2lucy5zaXplKCk7ICsraSkKICAgICAgewogICAgICAgIEpvaW4qIGpyID0gbV9HaG9zdEpvaW5zW2ldOwogICAgICAgIC8vaWYgdGhlIGhvcml6b250YWwgUmIgYW5kIGEgJ2dob3N0JyBob3Jpem9udGFsIG92ZXJsYXAsIHRoZW4gY29udmVydAogICAgICAgIC8vdGhlICdnaG9zdCcgam9pbiB0byBhIHJlYWwgam9pbiByZWFkeSBmb3IgbGF0ZXIgLi4uCiAgICAgICAgaWYgKEhvcnpTZWdtZW50c092ZXJsYXAoanItPk91dFB0MS0+UHQuWCwganItPk9mZlB0LlgsIHJiLT5Cb3QuWCwgcmItPlRvcC5YKSkKICAgICAgICAgIEFkZEpvaW4oanItPk91dFB0MSwgT3AxLCBqci0+T2ZmUHQpOwogICAgICB9CiAgICB9CgogICAgaWYgKGxiLT5PdXRJZHggPj0gMCAmJiBsYi0+UHJldkluQUVMICYmIAogICAgICBsYi0+UHJldkluQUVMLT5DdXJyLlggPT0gbGItPkJvdC5YICYmCiAgICAgIGxiLT5QcmV2SW5BRUwtPk91dElkeCA+PSAwICYmCiAgICAgIFNsb3Blc0VxdWFsKGxiLT5QcmV2SW5BRUwtPkJvdCwgbGItPlByZXZJbkFFTC0+VG9wLCBsYi0+Q3VyciwgbGItPlRvcCwgbV9Vc2VGdWxsUmFuZ2UpICYmCiAgICAgIChsYi0+V2luZERlbHRhICE9IDApICYmIChsYi0+UHJldkluQUVMLT5XaW5kRGVsdGEgIT0gMCkpCiAgICB7CiAgICAgICAgT3V0UHQgKk9wMiA9IEFkZE91dFB0KGxiLT5QcmV2SW5BRUwsIGxiLT5Cb3QpOwogICAgICAgIEFkZEpvaW4oT3AxLCBPcDIsIGxiLT5Ub3ApOwogICAgfQoKICAgIGlmKGxiLT5OZXh0SW5BRUwgIT0gcmIpCiAgICB7CgogICAgICBpZiAocmItPk91dElkeCA+PSAwICYmIHJiLT5QcmV2SW5BRUwtPk91dElkeCA+PSAwICYmCiAgICAgICAgU2xvcGVzRXF1YWwocmItPlByZXZJbkFFTC0+Q3VyciwgcmItPlByZXZJbkFFTC0+VG9wLCByYi0+Q3VyciwgcmItPlRvcCwgbV9Vc2VGdWxsUmFuZ2UpICYmCiAgICAgICAgKHJiLT5XaW5kRGVsdGEgIT0gMCkgJiYgKHJiLT5QcmV2SW5BRUwtPldpbmREZWx0YSAhPSAwKSkKICAgICAgewogICAgICAgICAgT3V0UHQgKk9wMiA9IEFkZE91dFB0KHJiLT5QcmV2SW5BRUwsIHJiLT5Cb3QpOwogICAgICAgICAgQWRkSm9pbihPcDEsIE9wMiwgcmItPlRvcCk7CiAgICAgIH0KCiAgICAgIFRFZGdlKiBlID0gbGItPk5leHRJbkFFTDsKICAgICAgaWYgKGUpCiAgICAgIHsKICAgICAgICB3aGlsZSggZSAhPSByYiApCiAgICAgICAgewogICAgICAgICAgLy9uYjogRm9yIGNhbGN1bGF0aW5nIHdpbmRpbmcgY291bnRzIGV0YywgSW50ZXJzZWN0RWRnZXMoKSBhc3N1bWVzCiAgICAgICAgICAvL3RoYXQgcGFyYW0xIHdpbGwgYmUgdG8gdGhlIFJpZ2h0IG9mIHBhcmFtMiBBQk9WRSB0aGUgaW50ZXJzZWN0aW9uIC4uLgogICAgICAgICAgSW50ZXJzZWN0RWRnZXMocmIgLCBlICwgbGItPkN1cnIpOyAvL29yZGVyIGltcG9ydGFudCBoZXJlCiAgICAgICAgICBlID0gZS0+TmV4dEluQUVMOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgCiAgfQp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXI6OkRlbGV0ZUZyb21TRUwoVEVkZ2UgKmUpCnsKICBURWRnZSogU2VsUHJldiA9IGUtPlByZXZJblNFTDsKICBURWRnZSogU2VsTmV4dCA9IGUtPk5leHRJblNFTDsKICBpZiggIVNlbFByZXYgJiYgICFTZWxOZXh0ICYmIChlICE9IG1fU29ydGVkRWRnZXMpICkgcmV0dXJuOyAvL2FscmVhZHkgZGVsZXRlZAogIGlmKCBTZWxQcmV2ICkgU2VsUHJldi0+TmV4dEluU0VMID0gU2VsTmV4dDsKICBlbHNlIG1fU29ydGVkRWRnZXMgPSBTZWxOZXh0OwogIGlmKCBTZWxOZXh0ICkgU2VsTmV4dC0+UHJldkluU0VMID0gU2VsUHJldjsKICBlLT5OZXh0SW5TRUwgPSAwOwogIGUtPlByZXZJblNFTCA9IDA7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiNpZmRlZiB1c2VfeHl6CnZvaWQgQ2xpcHBlcjo6U2V0WihJbnRQb2ludCYgcHQsIFRFZGdlJiBlMSwgVEVkZ2UmIGUyKQp7CiAgaWYgKHB0LlogIT0gMCB8fCAhbV9aRmlsbCkgcmV0dXJuOwogIGVsc2UgaWYgKHB0ID09IGUxLkJvdCkgcHQuWiA9IGUxLkJvdC5aOwogIGVsc2UgaWYgKHB0ID09IGUxLlRvcCkgcHQuWiA9IGUxLlRvcC5aOwogIGVsc2UgaWYgKHB0ID09IGUyLkJvdCkgcHQuWiA9IGUyLkJvdC5aOwogIGVsc2UgaWYgKHB0ID09IGUyLlRvcCkgcHQuWiA9IGUyLlRvcC5aOwogIGVsc2UgKCptX1pGaWxsKShlMS5Cb3QsIGUxLlRvcCwgZTIuQm90LCBlMi5Ub3AsIHB0KTsgCn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KI2VuZGlmCgp2b2lkIENsaXBwZXI6OkludGVyc2VjdEVkZ2VzKFRFZGdlICplMSwgVEVkZ2UgKmUyLCBJbnRQb2ludCAmUHQpCnsKICBib29sIGUxQ29udHJpYnV0aW5nID0gKCBlMS0+T3V0SWR4ID49IDAgKTsKICBib29sIGUyQ29udHJpYnV0aW5nID0gKCBlMi0+T3V0SWR4ID49IDAgKTsKCiNpZmRlZiB1c2VfeHl6CiAgICAgICAgU2V0WihQdCwgKmUxLCAqZTIpOwojZW5kaWYKCiNpZmRlZiB1c2VfbGluZXMKICAvL2lmIGVpdGhlciBlZGdlIGlzIG9uIGFuIE9QRU4gcGF0aCAuLi4KICBpZiAoZTEtPldpbmREZWx0YSA9PSAwIHx8IGUyLT5XaW5kRGVsdGEgPT0gMCkKICB7CiAgICAvL2lnbm9yZSBzdWJqZWN0LXN1YmplY3Qgb3BlbiBwYXRoIGludGVyc2VjdGlvbnMgVU5MRVNTIHRoZXkKICAgIC8vYXJlIGJvdGggb3BlbiBwYXRocywgQU5EIHRoZXkgYXJlIGJvdGggJ2NvbnRyaWJ1dGluZyBtYXhpbWFzJyAuLi4KCWlmIChlMS0+V2luZERlbHRhID09IDAgJiYgZTItPldpbmREZWx0YSA9PSAwKSByZXR1cm47CgogICAgLy9pZiBpbnRlcnNlY3RpbmcgYSBzdWJqIGxpbmUgd2l0aCBhIHN1YmogcG9seSAuLi4KICAgIGVsc2UgaWYgKGUxLT5Qb2x5VHlwID09IGUyLT5Qb2x5VHlwICYmIAogICAgICBlMS0+V2luZERlbHRhICE9IGUyLT5XaW5kRGVsdGEgJiYgbV9DbGlwVHlwZSA9PSBjdFVuaW9uKQogICAgewogICAgICBpZiAoZTEtPldpbmREZWx0YSA9PSAwKQogICAgICB7CiAgICAgICAgaWYgKGUyQ29udHJpYnV0aW5nKQogICAgICAgIHsKICAgICAgICAgIEFkZE91dFB0KGUxLCBQdCk7CiAgICAgICAgICBpZiAoZTFDb250cmlidXRpbmcpIGUxLT5PdXRJZHggPSBVbmFzc2lnbmVkOwogICAgICAgIH0KICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICBpZiAoZTFDb250cmlidXRpbmcpCiAgICAgICAgewogICAgICAgICAgQWRkT3V0UHQoZTIsIFB0KTsKICAgICAgICAgIGlmIChlMkNvbnRyaWJ1dGluZykgZTItPk91dElkeCA9IFVuYXNzaWduZWQ7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChlMS0+UG9seVR5cCAhPSBlMi0+UG9seVR5cCkKICAgIHsKICAgICAgLy90b2dnbGUgc3ViaiBvcGVuIHBhdGggT3V0SWR4IG9uL29mZiB3aGVuIEFicyhjbGlwLlduZENudCkgPT0gMSAuLi4KICAgICAgaWYgKChlMS0+V2luZERlbHRhID09IDApICYmIGFicyhlMi0+V2luZENudCkgPT0gMSAmJiAKICAgICAgICAobV9DbGlwVHlwZSAhPSBjdFVuaW9uIHx8IGUyLT5XaW5kQ250MiA9PSAwKSkKICAgICAgewogICAgICAgIEFkZE91dFB0KGUxLCBQdCk7CiAgICAgICAgaWYgKGUxQ29udHJpYnV0aW5nKSBlMS0+T3V0SWR4ID0gVW5hc3NpZ25lZDsKICAgICAgfQogICAgICBlbHNlIGlmICgoZTItPldpbmREZWx0YSA9PSAwKSAmJiAoYWJzKGUxLT5XaW5kQ250KSA9PSAxKSAmJiAKICAgICAgICAobV9DbGlwVHlwZSAhPSBjdFVuaW9uIHx8IGUxLT5XaW5kQ250MiA9PSAwKSkKICAgICAgewogICAgICAgIEFkZE91dFB0KGUyLCBQdCk7CiAgICAgICAgaWYgKGUyQ29udHJpYnV0aW5nKSBlMi0+T3V0SWR4ID0gVW5hc3NpZ25lZDsKICAgICAgfQogICAgfQogICAgcmV0dXJuOwogIH0KI2VuZGlmCgogIC8vdXBkYXRlIHdpbmRpbmcgY291bnRzLi4uCiAgLy9hc3N1bWVzIHRoYXQgZTEgd2lsbCBiZSB0byB0aGUgUmlnaHQgb2YgZTIgQUJPVkUgdGhlIGludGVyc2VjdGlvbgogIGlmICggZTEtPlBvbHlUeXAgPT0gZTItPlBvbHlUeXAgKQogIHsKICAgIGlmICggSXNFdmVuT2RkRmlsbFR5cGUoICplMSkgKQogICAgewogICAgICBpbnQgb2xkRTFXaW5kQ250ID0gZTEtPldpbmRDbnQ7CiAgICAgIGUxLT5XaW5kQ250ID0gZTItPldpbmRDbnQ7CiAgICAgIGUyLT5XaW5kQ250ID0gb2xkRTFXaW5kQ250OwogICAgfSBlbHNlCiAgICB7CiAgICAgIGlmIChlMS0+V2luZENudCArIGUyLT5XaW5kRGVsdGEgPT0gMCApIGUxLT5XaW5kQ250ID0gLWUxLT5XaW5kQ250OwogICAgICBlbHNlIGUxLT5XaW5kQ250ICs9IGUyLT5XaW5kRGVsdGE7CiAgICAgIGlmICggZTItPldpbmRDbnQgLSBlMS0+V2luZERlbHRhID09IDAgKSBlMi0+V2luZENudCA9IC1lMi0+V2luZENudDsKICAgICAgZWxzZSBlMi0+V2luZENudCAtPSBlMS0+V2luZERlbHRhOwogICAgfQogIH0gZWxzZQogIHsKICAgIGlmICghSXNFdmVuT2RkRmlsbFR5cGUoKmUyKSkgZTEtPldpbmRDbnQyICs9IGUyLT5XaW5kRGVsdGE7CiAgICBlbHNlIGUxLT5XaW5kQ250MiA9ICggZTEtPldpbmRDbnQyID09IDAgKSA/IDEgOiAwOwogICAgaWYgKCFJc0V2ZW5PZGRGaWxsVHlwZSgqZTEpKSBlMi0+V2luZENudDIgLT0gZTEtPldpbmREZWx0YTsKICAgIGVsc2UgZTItPldpbmRDbnQyID0gKCBlMi0+V2luZENudDIgPT0gMCApID8gMSA6IDA7CiAgfQoKICBQb2x5RmlsbFR5cGUgZTFGaWxsVHlwZSwgZTJGaWxsVHlwZSwgZTFGaWxsVHlwZTIsIGUyRmlsbFR5cGUyOwogIGlmIChlMS0+UG9seVR5cCA9PSBwdFN1YmplY3QpCiAgewogICAgZTFGaWxsVHlwZSA9IG1fU3ViakZpbGxUeXBlOwogICAgZTFGaWxsVHlwZTIgPSBtX0NsaXBGaWxsVHlwZTsKICB9IGVsc2UKICB7CiAgICBlMUZpbGxUeXBlID0gbV9DbGlwRmlsbFR5cGU7CiAgICBlMUZpbGxUeXBlMiA9IG1fU3ViakZpbGxUeXBlOwogIH0KICBpZiAoZTItPlBvbHlUeXAgPT0gcHRTdWJqZWN0KQogIHsKICAgIGUyRmlsbFR5cGUgPSBtX1N1YmpGaWxsVHlwZTsKICAgIGUyRmlsbFR5cGUyID0gbV9DbGlwRmlsbFR5cGU7CiAgfSBlbHNlCiAgewogICAgZTJGaWxsVHlwZSA9IG1fQ2xpcEZpbGxUeXBlOwogICAgZTJGaWxsVHlwZTIgPSBtX1N1YmpGaWxsVHlwZTsKICB9CgogIGNJbnQgZTFXYywgZTJXYzsKICBzd2l0Y2ggKGUxRmlsbFR5cGUpCiAgewogICAgY2FzZSBwZnRQb3NpdGl2ZTogZTFXYyA9IGUxLT5XaW5kQ250OyBicmVhazsKICAgIGNhc2UgcGZ0TmVnYXRpdmU6IGUxV2MgPSAtZTEtPldpbmRDbnQ7IGJyZWFrOwogICAgZGVmYXVsdDogZTFXYyA9IEFicyhlMS0+V2luZENudCk7CiAgfQogIHN3aXRjaChlMkZpbGxUeXBlKQogIHsKICAgIGNhc2UgcGZ0UG9zaXRpdmU6IGUyV2MgPSBlMi0+V2luZENudDsgYnJlYWs7CiAgICBjYXNlIHBmdE5lZ2F0aXZlOiBlMldjID0gLWUyLT5XaW5kQ250OyBicmVhazsKICAgIGRlZmF1bHQ6IGUyV2MgPSBBYnMoZTItPldpbmRDbnQpOwogIH0KCiAgaWYgKCBlMUNvbnRyaWJ1dGluZyAmJiBlMkNvbnRyaWJ1dGluZyApCiAgewogICAgaWYgKChlMVdjICE9IDAgJiYgZTFXYyAhPSAxKSB8fCAoZTJXYyAhPSAwICYmIGUyV2MgIT0gMSkgfHwKICAgICAgKGUxLT5Qb2x5VHlwICE9IGUyLT5Qb2x5VHlwICYmIG1fQ2xpcFR5cGUgIT0gY3RYb3IpICkKICAgIHsKICAgICAgQWRkTG9jYWxNYXhQb2x5KGUxLCBlMiwgUHQpOyAKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgQWRkT3V0UHQoZTEsIFB0KTsKICAgICAgQWRkT3V0UHQoZTIsIFB0KTsKICAgICAgU3dhcFNpZGVzKCAqZTEgLCAqZTIgKTsKICAgICAgU3dhcFBvbHlJbmRleGVzKCAqZTEgLCAqZTIgKTsKICAgIH0KICB9CiAgZWxzZSBpZiAoIGUxQ29udHJpYnV0aW5nICkKICB7CiAgICBpZiAoZTJXYyA9PSAwIHx8IGUyV2MgPT0gMSkgCiAgICB7CiAgICAgIEFkZE91dFB0KGUxLCBQdCk7CiAgICAgIFN3YXBTaWRlcygqZTEsICplMik7CiAgICAgIFN3YXBQb2x5SW5kZXhlcygqZTEsICplMik7CiAgICB9CiAgfQogIGVsc2UgaWYgKCBlMkNvbnRyaWJ1dGluZyApCiAgewogICAgaWYgKGUxV2MgPT0gMCB8fCBlMVdjID09IDEpIAogICAgewogICAgICBBZGRPdXRQdChlMiwgUHQpOwogICAgICBTd2FwU2lkZXMoKmUxLCAqZTIpOwogICAgICBTd2FwUG9seUluZGV4ZXMoKmUxLCAqZTIpOwogICAgfQogIH0gCiAgZWxzZSBpZiAoIChlMVdjID09IDAgfHwgZTFXYyA9PSAxKSAmJiAoZTJXYyA9PSAwIHx8IGUyV2MgPT0gMSkpCiAgewogICAgLy9uZWl0aGVyIGVkZ2UgaXMgY3VycmVudGx5IGNvbnRyaWJ1dGluZyAuLi4KCiAgICBjSW50IGUxV2MyLCBlMldjMjsKICAgIHN3aXRjaCAoZTFGaWxsVHlwZTIpCiAgICB7CiAgICAgIGNhc2UgcGZ0UG9zaXRpdmU6IGUxV2MyID0gZTEtPldpbmRDbnQyOyBicmVhazsKICAgICAgY2FzZSBwZnROZWdhdGl2ZSA6IGUxV2MyID0gLWUxLT5XaW5kQ250MjsgYnJlYWs7CiAgICAgIGRlZmF1bHQ6IGUxV2MyID0gQWJzKGUxLT5XaW5kQ250Mik7CiAgICB9CiAgICBzd2l0Y2ggKGUyRmlsbFR5cGUyKQogICAgewogICAgICBjYXNlIHBmdFBvc2l0aXZlOiBlMldjMiA9IGUyLT5XaW5kQ250MjsgYnJlYWs7CiAgICAgIGNhc2UgcGZ0TmVnYXRpdmU6IGUyV2MyID0gLWUyLT5XaW5kQ250MjsgYnJlYWs7CiAgICAgIGRlZmF1bHQ6IGUyV2MyID0gQWJzKGUyLT5XaW5kQ250Mik7CiAgICB9CgogICAgaWYgKGUxLT5Qb2x5VHlwICE9IGUyLT5Qb2x5VHlwKQogICAgewogICAgICBBZGRMb2NhbE1pblBvbHkoZTEsIGUyLCBQdCk7CiAgICB9CiAgICBlbHNlIGlmIChlMVdjID09IDEgJiYgZTJXYyA9PSAxKQogICAgICBzd2l0Y2goIG1fQ2xpcFR5cGUgKSB7CiAgICAgICAgY2FzZSBjdEludGVyc2VjdGlvbjoKICAgICAgICAgIGlmIChlMVdjMiA+IDAgJiYgZTJXYzIgPiAwKQogICAgICAgICAgICBBZGRMb2NhbE1pblBvbHkoZTEsIGUyLCBQdCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGN0VW5pb246CiAgICAgICAgICBpZiAoIGUxV2MyIDw9IDAgJiYgZTJXYzIgPD0gMCApCiAgICAgICAgICAgIEFkZExvY2FsTWluUG9seShlMSwgZTIsIFB0KTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgY3REaWZmZXJlbmNlOgogICAgICAgICAgaWYgKCgoZTEtPlBvbHlUeXAgPT0gcHRDbGlwKSAmJiAoZTFXYzIgPiAwKSAmJiAoZTJXYzIgPiAwKSkgfHwKICAgICAgICAgICAgICAoKGUxLT5Qb2x5VHlwID09IHB0U3ViamVjdCkgJiYgKGUxV2MyIDw9IDApICYmIChlMldjMiA8PSAwKSkpCiAgICAgICAgICAgICAgICBBZGRMb2NhbE1pblBvbHkoZTEsIGUyLCBQdCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGN0WG9yOgogICAgICAgICAgQWRkTG9jYWxNaW5Qb2x5KGUxLCBlMiwgUHQpOwogICAgICB9CiAgICBlbHNlCiAgICAgIFN3YXBTaWRlcyggKmUxLCAqZTIgKTsKICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6U2V0SG9sZVN0YXRlKFRFZGdlICplLCBPdXRSZWMgKm91dHJlYykKewogIFRFZGdlICplMiA9IGUtPlByZXZJbkFFTDsKICBURWRnZSAqZVRtcCA9IDA7CiAgd2hpbGUgKGUyKQogIHsKICAgIGlmIChlMi0+T3V0SWR4ID49IDAgJiYgZTItPldpbmREZWx0YSAhPSAwKQogICAgewogICAgICBpZiAoIWVUbXApIGVUbXAgPSBlMjsKICAgICAgZWxzZSBpZiAoZVRtcC0+T3V0SWR4ID09IGUyLT5PdXRJZHgpIGVUbXAgPSAwOyAgICAgICAgCiAgICB9CiAgICBlMiA9IGUyLT5QcmV2SW5BRUw7CiAgfQogIGlmICghZVRtcCkKICB7CiAgICBvdXRyZWMtPkZpcnN0TGVmdCA9IDA7CiAgICBvdXRyZWMtPklzSG9sZSA9IGZhbHNlOwogIH0KICBlbHNlCiAgewogICAgb3V0cmVjLT5GaXJzdExlZnQgPSBtX1BvbHlPdXRzW2VUbXAtPk91dElkeF07CiAgICBvdXRyZWMtPklzSG9sZSA9ICFvdXRyZWMtPkZpcnN0TGVmdC0+SXNIb2xlOwogIH0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKT3V0UmVjKiBHZXRMb3dlcm1vc3RSZWMoT3V0UmVjICpvdXRSZWMxLCBPdXRSZWMgKm91dFJlYzIpCnsKICAvL3dvcmsgb3V0IHdoaWNoIHBvbHlnb24gZnJhZ21lbnQgaGFzIHRoZSBjb3JyZWN0IGhvbGUgc3RhdGUgLi4uCiAgaWYgKCFvdXRSZWMxLT5Cb3R0b21QdCkgCiAgICBvdXRSZWMxLT5Cb3R0b21QdCA9IEdldEJvdHRvbVB0KG91dFJlYzEtPlB0cyk7CiAgaWYgKCFvdXRSZWMyLT5Cb3R0b21QdCkgCiAgICBvdXRSZWMyLT5Cb3R0b21QdCA9IEdldEJvdHRvbVB0KG91dFJlYzItPlB0cyk7CiAgT3V0UHQgKk91dFB0MSA9IG91dFJlYzEtPkJvdHRvbVB0OwogIE91dFB0ICpPdXRQdDIgPSBvdXRSZWMyLT5Cb3R0b21QdDsKICBpZiAoT3V0UHQxLT5QdC5ZID4gT3V0UHQyLT5QdC5ZKSByZXR1cm4gb3V0UmVjMTsKICBlbHNlIGlmIChPdXRQdDEtPlB0LlkgPCBPdXRQdDItPlB0LlkpIHJldHVybiBvdXRSZWMyOwogIGVsc2UgaWYgKE91dFB0MS0+UHQuWCA8IE91dFB0Mi0+UHQuWCkgcmV0dXJuIG91dFJlYzE7CiAgZWxzZSBpZiAoT3V0UHQxLT5QdC5YID4gT3V0UHQyLT5QdC5YKSByZXR1cm4gb3V0UmVjMjsKICBlbHNlIGlmIChPdXRQdDEtPk5leHQgPT0gT3V0UHQxKSByZXR1cm4gb3V0UmVjMjsKICBlbHNlIGlmIChPdXRQdDItPk5leHQgPT0gT3V0UHQyKSByZXR1cm4gb3V0UmVjMTsKICBlbHNlIGlmIChGaXJzdElzQm90dG9tUHQoT3V0UHQxLCBPdXRQdDIpKSByZXR1cm4gb3V0UmVjMTsKICBlbHNlIHJldHVybiBvdXRSZWMyOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpib29sIE91dFJlYzFSaWdodE9mT3V0UmVjMihPdXRSZWMqIG91dFJlYzEsIE91dFJlYyogb3V0UmVjMikKewogIGRvCiAgewogICAgb3V0UmVjMSA9IG91dFJlYzEtPkZpcnN0TGVmdDsKICAgIGlmIChvdXRSZWMxID09IG91dFJlYzIpIHJldHVybiB0cnVlOwogIH0gd2hpbGUgKG91dFJlYzEpOwogIHJldHVybiBmYWxzZTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKT3V0UmVjKiBDbGlwcGVyOjpHZXRPdXRSZWMoaW50IElkeCkKewogIE91dFJlYyogb3V0cmVjID0gbV9Qb2x5T3V0c1tJZHhdOwogIHdoaWxlIChvdXRyZWMgIT0gbV9Qb2x5T3V0c1tvdXRyZWMtPklkeF0pCiAgICBvdXRyZWMgPSBtX1BvbHlPdXRzW291dHJlYy0+SWR4XTsKICByZXR1cm4gb3V0cmVjOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXI6OkFwcGVuZFBvbHlnb24oVEVkZ2UgKmUxLCBURWRnZSAqZTIpCnsKICAvL2dldCB0aGUgc3RhcnQgYW5kIGVuZHMgb2YgYm90aCBvdXRwdXQgcG9seWdvbnMgLi4uCiAgT3V0UmVjICpvdXRSZWMxID0gbV9Qb2x5T3V0c1tlMS0+T3V0SWR4XTsKICBPdXRSZWMgKm91dFJlYzIgPSBtX1BvbHlPdXRzW2UyLT5PdXRJZHhdOwoKICBPdXRSZWMgKmhvbGVTdGF0ZVJlYzsKICBpZiAoT3V0UmVjMVJpZ2h0T2ZPdXRSZWMyKG91dFJlYzEsIG91dFJlYzIpKQogICAgaG9sZVN0YXRlUmVjID0gb3V0UmVjMjsKICBlbHNlIGlmIChPdXRSZWMxUmlnaHRPZk91dFJlYzIob3V0UmVjMiwgb3V0UmVjMSkpCiAgICBob2xlU3RhdGVSZWMgPSBvdXRSZWMxOwogIGVsc2UgCiAgICBob2xlU3RhdGVSZWMgPSBHZXRMb3dlcm1vc3RSZWMob3V0UmVjMSwgb3V0UmVjMik7CgogIC8vZ2V0IHRoZSBzdGFydCBhbmQgZW5kcyBvZiBib3RoIG91dHB1dCBwb2x5Z29ucyBhbmQKICAvL2pvaW4gZTIgcG9seSBvbnRvIGUxIHBvbHkgYW5kIGRlbGV0ZSBwb2ludGVycyB0byBlMiAuLi4KCiAgT3V0UHQqIHAxX2xmdCA9IG91dFJlYzEtPlB0czsKICBPdXRQdCogcDFfcnQgPSBwMV9sZnQtPlByZXY7CiAgT3V0UHQqIHAyX2xmdCA9IG91dFJlYzItPlB0czsKICBPdXRQdCogcDJfcnQgPSBwMl9sZnQtPlByZXY7CgogIC8vam9pbiBlMiBwb2x5IG9udG8gZTEgcG9seSBhbmQgZGVsZXRlIHBvaW50ZXJzIHRvIGUyIC4uLgogIGlmKCAgZTEtPlNpZGUgPT0gZXNMZWZ0ICkKICB7CiAgICBpZiggIGUyLT5TaWRlID09IGVzTGVmdCApCiAgICB7CiAgICAgIC8veiB5IHggYSBiIGMKICAgICAgUmV2ZXJzZVBvbHlQdExpbmtzKHAyX2xmdCk7CiAgICAgIHAyX2xmdC0+TmV4dCA9IHAxX2xmdDsKICAgICAgcDFfbGZ0LT5QcmV2ID0gcDJfbGZ0OwogICAgICBwMV9ydC0+TmV4dCA9IHAyX3J0OwogICAgICBwMl9ydC0+UHJldiA9IHAxX3J0OwogICAgICBvdXRSZWMxLT5QdHMgPSBwMl9ydDsKICAgIH0gZWxzZQogICAgewogICAgICAvL3ggeSB6IGEgYiBjCiAgICAgIHAyX3J0LT5OZXh0ID0gcDFfbGZ0OwogICAgICBwMV9sZnQtPlByZXYgPSBwMl9ydDsKICAgICAgcDJfbGZ0LT5QcmV2ID0gcDFfcnQ7CiAgICAgIHAxX3J0LT5OZXh0ID0gcDJfbGZ0OwogICAgICBvdXRSZWMxLT5QdHMgPSBwMl9sZnQ7CiAgICB9CiAgfSBlbHNlCiAgewogICAgaWYoICBlMi0+U2lkZSA9PSBlc1JpZ2h0ICkKICAgIHsKICAgICAgLy9hIGIgYyB6IHkgeAogICAgICBSZXZlcnNlUG9seVB0TGlua3MocDJfbGZ0KTsKICAgICAgcDFfcnQtPk5leHQgPSBwMl9ydDsKICAgICAgcDJfcnQtPlByZXYgPSBwMV9ydDsKICAgICAgcDJfbGZ0LT5OZXh0ID0gcDFfbGZ0OwogICAgICBwMV9sZnQtPlByZXYgPSBwMl9sZnQ7CiAgICB9IGVsc2UKICAgIHsKICAgICAgLy9hIGIgYyB4IHkgegogICAgICBwMV9ydC0+TmV4dCA9IHAyX2xmdDsKICAgICAgcDJfbGZ0LT5QcmV2ID0gcDFfcnQ7CiAgICAgIHAxX2xmdC0+UHJldiA9IHAyX3J0OwogICAgICBwMl9ydC0+TmV4dCA9IHAxX2xmdDsKICAgIH0KICB9CgogIG91dFJlYzEtPkJvdHRvbVB0ID0gMDsKICBpZiAoaG9sZVN0YXRlUmVjID09IG91dFJlYzIpCiAgewogICAgaWYgKG91dFJlYzItPkZpcnN0TGVmdCAhPSBvdXRSZWMxKQogICAgICBvdXRSZWMxLT5GaXJzdExlZnQgPSBvdXRSZWMyLT5GaXJzdExlZnQ7CiAgICBvdXRSZWMxLT5Jc0hvbGUgPSBvdXRSZWMyLT5Jc0hvbGU7CiAgfQogIG91dFJlYzItPlB0cyA9IDA7CiAgb3V0UmVjMi0+Qm90dG9tUHQgPSAwOwogIG91dFJlYzItPkZpcnN0TGVmdCA9IG91dFJlYzE7CgogIGludCBPS0lkeCA9IGUxLT5PdXRJZHg7CiAgaW50IE9ic29sZXRlSWR4ID0gZTItPk91dElkeDsKCiAgZTEtPk91dElkeCA9IFVuYXNzaWduZWQ7IC8vbmI6IHNhZmUgYmVjYXVzZSB3ZSBvbmx5IGdldCBoZXJlIHZpYSBBZGRMb2NhbE1heFBvbHkKICBlMi0+T3V0SWR4ID0gVW5hc3NpZ25lZDsKCiAgVEVkZ2UqIGUgPSBtX0FjdGl2ZUVkZ2VzOwogIHdoaWxlKCBlICkKICB7CiAgICBpZiggZS0+T3V0SWR4ID09IE9ic29sZXRlSWR4ICkKICAgIHsKICAgICAgZS0+T3V0SWR4ID0gT0tJZHg7CiAgICAgIGUtPlNpZGUgPSBlMS0+U2lkZTsKICAgICAgYnJlYWs7CiAgICB9CiAgICBlID0gZS0+TmV4dEluQUVMOwogIH0KCiAgb3V0UmVjMi0+SWR4ID0gb3V0UmVjMS0+SWR4Owp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpPdXRQdCogQ2xpcHBlcjo6QWRkT3V0UHQoVEVkZ2UgKmUsIGNvbnN0IEludFBvaW50ICZwdCkKewogIGlmKCAgZS0+T3V0SWR4IDwgMCApCiAgewogICAgT3V0UmVjICpvdXRSZWMgPSBDcmVhdGVPdXRSZWMoKTsKICAgIG91dFJlYy0+SXNPcGVuID0gKGUtPldpbmREZWx0YSA9PSAwKTsKICAgIE91dFB0KiBuZXdPcCA9IG5ldyBPdXRQdDsKICAgIG91dFJlYy0+UHRzID0gbmV3T3A7CiAgICBuZXdPcC0+SWR4ID0gb3V0UmVjLT5JZHg7CiAgICBuZXdPcC0+UHQgPSBwdDsKICAgIG5ld09wLT5OZXh0ID0gbmV3T3A7CiAgICBuZXdPcC0+UHJldiA9IG5ld09wOwogICAgaWYgKCFvdXRSZWMtPklzT3BlbikKICAgICAgU2V0SG9sZVN0YXRlKGUsIG91dFJlYyk7CiAgICBlLT5PdXRJZHggPSBvdXRSZWMtPklkeDsKICAgIHJldHVybiBuZXdPcDsKICB9IGVsc2UKICB7CiAgICBPdXRSZWMgKm91dFJlYyA9IG1fUG9seU91dHNbZS0+T3V0SWR4XTsKICAgIC8vT3V0UmVjLlB0cyBpcyB0aGUgJ0xlZnQtbW9zdCcgcG9pbnQgJiBPdXRSZWMuUHRzLlByZXYgaXMgdGhlICdSaWdodC1tb3N0JwogICAgT3V0UHQqIG9wID0gb3V0UmVjLT5QdHM7CgoJYm9vbCBUb0Zyb250ID0gKGUtPlNpZGUgPT0gZXNMZWZ0KTsKCWlmIChUb0Zyb250ICYmIChwdCA9PSBvcC0+UHQpKSByZXR1cm4gb3A7CiAgICBlbHNlIGlmICghVG9Gcm9udCAmJiAocHQgPT0gb3AtPlByZXYtPlB0KSkgcmV0dXJuIG9wLT5QcmV2OwoKICAgIE91dFB0KiBuZXdPcCA9IG5ldyBPdXRQdDsKICAgIG5ld09wLT5JZHggPSBvdXRSZWMtPklkeDsKICAgIG5ld09wLT5QdCA9IHB0OwogICAgbmV3T3AtPk5leHQgPSBvcDsKICAgIG5ld09wLT5QcmV2ID0gb3AtPlByZXY7CiAgICBuZXdPcC0+UHJldi0+TmV4dCA9IG5ld09wOwogICAgb3AtPlByZXYgPSBuZXdPcDsKICAgIGlmIChUb0Zyb250KSBvdXRSZWMtPlB0cyA9IG5ld09wOwogICAgcmV0dXJuIG5ld09wOwogIH0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKT3V0UHQqIENsaXBwZXI6OkdldExhc3RPdXRQdChURWRnZSAqZSkKewoJT3V0UmVjICpvdXRSZWMgPSBtX1BvbHlPdXRzW2UtPk91dElkeF07CglpZiAoZS0+U2lkZSA9PSBlc0xlZnQpCgkJcmV0dXJuIG91dFJlYy0+UHRzOwoJZWxzZQoJCXJldHVybiBvdXRSZWMtPlB0cy0+UHJldjsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBDbGlwcGVyOjpQcm9jZXNzSG9yaXpvbnRhbHMoKQp7CiAgVEVkZ2UqIGhvcnpFZGdlOwogIHdoaWxlIChQb3BFZGdlRnJvbVNFTChob3J6RWRnZSkpCiAgICBQcm9jZXNzSG9yaXpvbnRhbChob3J6RWRnZSk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmlubGluZSBib29sIElzTWluaW1hKFRFZGdlICplKQp7CiAgcmV0dXJuIGUgICYmIChlLT5QcmV2LT5OZXh0SW5MTUwgIT0gZSkgJiYgKGUtPk5leHQtPk5leHRJbkxNTCAhPSBlKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaW5saW5lIGJvb2wgSXNNYXhpbWEoVEVkZ2UgKmUsIGNvbnN0IGNJbnQgWSkKewogIHJldHVybiBlICYmIGUtPlRvcC5ZID09IFkgJiYgIWUtPk5leHRJbkxNTDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaW5saW5lIGJvb2wgSXNJbnRlcm1lZGlhdGUoVEVkZ2UgKmUsIGNvbnN0IGNJbnQgWSkKewogIHJldHVybiBlLT5Ub3AuWSA9PSBZICYmIGUtPk5leHRJbkxNTDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKVEVkZ2UgKkdldE1heGltYVBhaXIoVEVkZ2UgKmUpCnsKICBpZiAoKGUtPk5leHQtPlRvcCA9PSBlLT5Ub3ApICYmICFlLT5OZXh0LT5OZXh0SW5MTUwpCiAgICByZXR1cm4gZS0+TmV4dDsKICBlbHNlIGlmICgoZS0+UHJldi0+VG9wID09IGUtPlRvcCkgJiYgIWUtPlByZXYtPk5leHRJbkxNTCkKICAgIHJldHVybiBlLT5QcmV2OwogIGVsc2UgcmV0dXJuIDA7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KClRFZGdlICpHZXRNYXhpbWFQYWlyRXgoVEVkZ2UgKmUpCnsKICAvL2FzIEdldE1heGltYVBhaXIoKSBidXQgcmV0dXJucyAwIGlmIE1heFBhaXIgaXNuJ3QgaW4gQUVMICh1bmxlc3MgaXQncyBob3Jpem9udGFsKQogIFRFZGdlKiByZXN1bHQgPSBHZXRNYXhpbWFQYWlyKGUpOwogIGlmIChyZXN1bHQgJiYgKHJlc3VsdC0+T3V0SWR4ID09IFNraXAgfHwKICAgIChyZXN1bHQtPk5leHRJbkFFTCA9PSByZXN1bHQtPlByZXZJbkFFTCAmJiAhSXNIb3Jpem9udGFsKCpyZXN1bHQpKSkpIHJldHVybiAwOwogIHJldHVybiByZXN1bHQ7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6U3dhcFBvc2l0aW9uc0luU0VMKFRFZGdlICpFZGdlMSwgVEVkZ2UgKkVkZ2UyKQp7CiAgaWYoICAhKCBFZGdlMS0+TmV4dEluU0VMICkgJiYgICEoIEVkZ2UxLT5QcmV2SW5TRUwgKSApIHJldHVybjsKICBpZiggICEoIEVkZ2UyLT5OZXh0SW5TRUwgKSAmJiAgISggRWRnZTItPlByZXZJblNFTCApICkgcmV0dXJuOwoKICBpZiggIEVkZ2UxLT5OZXh0SW5TRUwgPT0gRWRnZTIgKQogIHsKICAgIFRFZGdlKiBOZXh0ID0gRWRnZTItPk5leHRJblNFTDsKICAgIGlmKCBOZXh0ICkgTmV4dC0+UHJldkluU0VMID0gRWRnZTE7CiAgICBURWRnZSogUHJldiA9IEVkZ2UxLT5QcmV2SW5TRUw7CiAgICBpZiggUHJldiApIFByZXYtPk5leHRJblNFTCA9IEVkZ2UyOwogICAgRWRnZTItPlByZXZJblNFTCA9IFByZXY7CiAgICBFZGdlMi0+TmV4dEluU0VMID0gRWRnZTE7CiAgICBFZGdlMS0+UHJldkluU0VMID0gRWRnZTI7CiAgICBFZGdlMS0+TmV4dEluU0VMID0gTmV4dDsKICB9CiAgZWxzZSBpZiggIEVkZ2UyLT5OZXh0SW5TRUwgPT0gRWRnZTEgKQogIHsKICAgIFRFZGdlKiBOZXh0ID0gRWRnZTEtPk5leHRJblNFTDsKICAgIGlmKCBOZXh0ICkgTmV4dC0+UHJldkluU0VMID0gRWRnZTI7CiAgICBURWRnZSogUHJldiA9IEVkZ2UyLT5QcmV2SW5TRUw7CiAgICBpZiggUHJldiApIFByZXYtPk5leHRJblNFTCA9IEVkZ2UxOwogICAgRWRnZTEtPlByZXZJblNFTCA9IFByZXY7CiAgICBFZGdlMS0+TmV4dEluU0VMID0gRWRnZTI7CiAgICBFZGdlMi0+UHJldkluU0VMID0gRWRnZTE7CiAgICBFZGdlMi0+TmV4dEluU0VMID0gTmV4dDsKICB9CiAgZWxzZQogIHsKICAgIFRFZGdlKiBOZXh0ID0gRWRnZTEtPk5leHRJblNFTDsKICAgIFRFZGdlKiBQcmV2ID0gRWRnZTEtPlByZXZJblNFTDsKICAgIEVkZ2UxLT5OZXh0SW5TRUwgPSBFZGdlMi0+TmV4dEluU0VMOwogICAgaWYoIEVkZ2UxLT5OZXh0SW5TRUwgKSBFZGdlMS0+TmV4dEluU0VMLT5QcmV2SW5TRUwgPSBFZGdlMTsKICAgIEVkZ2UxLT5QcmV2SW5TRUwgPSBFZGdlMi0+UHJldkluU0VMOwogICAgaWYoIEVkZ2UxLT5QcmV2SW5TRUwgKSBFZGdlMS0+UHJldkluU0VMLT5OZXh0SW5TRUwgPSBFZGdlMTsKICAgIEVkZ2UyLT5OZXh0SW5TRUwgPSBOZXh0OwogICAgaWYoIEVkZ2UyLT5OZXh0SW5TRUwgKSBFZGdlMi0+TmV4dEluU0VMLT5QcmV2SW5TRUwgPSBFZGdlMjsKICAgIEVkZ2UyLT5QcmV2SW5TRUwgPSBQcmV2OwogICAgaWYoIEVkZ2UyLT5QcmV2SW5TRUwgKSBFZGdlMi0+UHJldkluU0VMLT5OZXh0SW5TRUwgPSBFZGdlMjsKICB9CgogIGlmKCAhRWRnZTEtPlByZXZJblNFTCApIG1fU29ydGVkRWRnZXMgPSBFZGdlMTsKICBlbHNlIGlmKCAhRWRnZTItPlByZXZJblNFTCApIG1fU29ydGVkRWRnZXMgPSBFZGdlMjsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKVEVkZ2UqIEdldE5leHRJbkFFTChURWRnZSAqZSwgRGlyZWN0aW9uIGRpcikKewogIHJldHVybiBkaXIgPT0gZExlZnRUb1JpZ2h0ID8gZS0+TmV4dEluQUVMIDogZS0+UHJldkluQUVMOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIEdldEhvcnpEaXJlY3Rpb24oVEVkZ2UmIEhvcnpFZGdlLCBEaXJlY3Rpb24mIERpciwgY0ludCYgTGVmdCwgY0ludCYgUmlnaHQpCnsKICBpZiAoSG9yekVkZ2UuQm90LlggPCBIb3J6RWRnZS5Ub3AuWCkKICB7CiAgICBMZWZ0ID0gSG9yekVkZ2UuQm90Llg7CiAgICBSaWdodCA9IEhvcnpFZGdlLlRvcC5YOwogICAgRGlyID0gZExlZnRUb1JpZ2h0OwogIH0gZWxzZQogIHsKICAgIExlZnQgPSBIb3J6RWRnZS5Ub3AuWDsKICAgIFJpZ2h0ID0gSG9yekVkZ2UuQm90Llg7CiAgICBEaXIgPSBkUmlnaHRUb0xlZnQ7CiAgfQp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIE5vdGVzOiBIb3Jpem9udGFsIGVkZ2VzIChIRXMpIGF0IHNjYW5saW5lIGludGVyc2VjdGlvbnMgKGllIGF0IHRoZSBUb3Agb3IgICAgKgoqIEJvdHRvbSBvZiBhIHNjYW5iZWFtKSBhcmUgcHJvY2Vzc2VkIGFzIGlmIGxheWVyZWQuIFRoZSBvcmRlciBpbiB3aGljaCBIRXMgICAgKgoqIGFyZSBwcm9jZXNzZWQgZG9lc24ndCBtYXR0ZXIuIEhFcyBpbnRlcnNlY3Qgd2l0aCBvdGhlciBIRSBCb3QuWHMgb25seSBbI10gICAgKgoqIChvciB0aGV5IGNvdWxkIGludGVyc2VjdCB3aXRoIFRvcC5YcyBvbmx5LCBpZSBFSVRIRVIgQm90LlhzIE9SIFRvcC5YcyksICAgICAgKgoqIGFuZCB3aXRoIG90aGVyIG5vbi1ob3Jpem9udGFsIGVkZ2VzIFsqXS4gT25jZSB0aGVzZSBpbnRlcnNlY3Rpb25zIGFyZSAgICAgICAgKgoqIHByb2Nlc3NlZCwgaW50ZXJtZWRpYXRlIEhFcyB0aGVuICdwcm9tb3RlJyB0aGUgRWRnZSBhYm92ZSAoTmV4dEluTE1MKSBpbnRvICAgKgoqIHRoZSBBRUwuIFRoZXNlICdwcm9tb3RlZCcgZWRnZXMgbWF5IGluIHR1cm4gaW50ZXJzZWN0IFslXSB3aXRoIG90aGVyIEhFcy4gICAgKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdm9pZCBDbGlwcGVyOjpQcm9jZXNzSG9yaXpvbnRhbChURWRnZSAqaG9yekVkZ2UpCnsKICBEaXJlY3Rpb24gZGlyOwogIGNJbnQgaG9yekxlZnQsIGhvcnpSaWdodDsKICBib29sIElzT3BlbiA9IChob3J6RWRnZS0+V2luZERlbHRhID09IDApOwoKICBHZXRIb3J6RGlyZWN0aW9uKCpob3J6RWRnZSwgZGlyLCBob3J6TGVmdCwgaG9yelJpZ2h0KTsKCiAgVEVkZ2UqIGVMYXN0SG9yeiA9IGhvcnpFZGdlLCAqZU1heFBhaXIgPSAwOwogIHdoaWxlIChlTGFzdEhvcnotPk5leHRJbkxNTCAmJiBJc0hvcml6b250YWwoKmVMYXN0SG9yei0+TmV4dEluTE1MKSkgCiAgICBlTGFzdEhvcnogPSBlTGFzdEhvcnotPk5leHRJbkxNTDsKICBpZiAoIWVMYXN0SG9yei0+TmV4dEluTE1MKQogICAgZU1heFBhaXIgPSBHZXRNYXhpbWFQYWlyKGVMYXN0SG9yeik7CgogIE1heGltYUxpc3Q6OmNvbnN0X2l0ZXJhdG9yIG1heEl0OwogIE1heGltYUxpc3Q6OmNvbnN0X3JldmVyc2VfaXRlcmF0b3IgbWF4Uml0OwogIGlmIChtX01heGltYS5zaXplKCkgPiAwKQogIHsKICAgICAgLy9nZXQgdGhlIGZpcnN0IG1heGltYSBpbiByYW5nZSAoWCkgLi4uCiAgICAgIGlmIChkaXIgPT0gZExlZnRUb1JpZ2h0KQogICAgICB7CiAgICAgICAgICBtYXhJdCA9IG1fTWF4aW1hLmJlZ2luKCk7CiAgICAgICAgICB3aGlsZSAobWF4SXQgIT0gbV9NYXhpbWEuZW5kKCkgJiYgKm1heEl0IDw9IGhvcnpFZGdlLT5Cb3QuWCkgbWF4SXQrKzsKICAgICAgICAgIGlmIChtYXhJdCAhPSBtX01heGltYS5lbmQoKSAmJiAqbWF4SXQgPj0gZUxhc3RIb3J6LT5Ub3AuWCkKICAgICAgICAgICAgICBtYXhJdCA9IG1fTWF4aW1hLmVuZCgpOwogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgICAgbWF4Uml0ID0gbV9NYXhpbWEucmJlZ2luKCk7CiAgICAgICAgICB3aGlsZSAobWF4Uml0ICE9IG1fTWF4aW1hLnJlbmQoKSAmJiAqbWF4Uml0ID4gaG9yekVkZ2UtPkJvdC5YKSBtYXhSaXQrKzsKICAgICAgICAgIGlmIChtYXhSaXQgIT0gbV9NYXhpbWEucmVuZCgpICYmICptYXhSaXQgPD0gZUxhc3RIb3J6LT5Ub3AuWCkKICAgICAgICAgICAgICBtYXhSaXQgPSBtX01heGltYS5yZW5kKCk7CiAgICAgIH0KICB9CgogIE91dFB0KiBvcDEgPSAwOwoKICBmb3IgKDs7KSAvL2xvb3AgdGhyb3VnaCBjb25zZWMuIGhvcml6b250YWwgZWRnZXMKICB7CgkJICAKICAgIGJvb2wgSXNMYXN0SG9yeiA9IChob3J6RWRnZSA9PSBlTGFzdEhvcnopOwogICAgVEVkZ2UqIGUgPSBHZXROZXh0SW5BRUwoaG9yekVkZ2UsIGRpcik7CiAgICB3aGlsZShlKQogICAgewoKICAgICAgICAvL3RoaXMgY29kZSBibG9jayBpbnNlcnRzIGV4dHJhIGNvb3JkcyBpbnRvIGhvcml6b250YWwgZWRnZXMgKGluIG91dHB1dAogICAgICAgIC8vcG9seWdvbnMpIHdoZXJlZXZlciBtYXhpbWEgdG91Y2ggdGhlc2UgaG9yaXpvbnRhbCBlZGdlcy4gVGhpcyBoZWxwcwogICAgICAgIC8vJ3NpbXBsaWZ5aW5nJyBwb2x5Z29ucyAoaWUgaWYgdGhlIFNpbXBsaWZ5IHByb3BlcnR5IGlzIHNldCkuCiAgICAgICAgaWYgKG1fTWF4aW1hLnNpemUoKSA+IDApCiAgICAgICAgewogICAgICAgICAgICBpZiAoZGlyID09IGRMZWZ0VG9SaWdodCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgd2hpbGUgKG1heEl0ICE9IG1fTWF4aW1hLmVuZCgpICYmICptYXhJdCA8IGUtPkN1cnIuWCkgCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIGlmIChob3J6RWRnZS0+T3V0SWR4ID49IDAgJiYgIUlzT3BlbikKICAgICAgICAgICAgICAgICAgICBBZGRPdXRQdChob3J6RWRnZSwgSW50UG9pbnQoKm1heEl0LCBob3J6RWRnZS0+Qm90LlkpKTsKICAgICAgICAgICAgICAgICAgbWF4SXQrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHdoaWxlIChtYXhSaXQgIT0gbV9NYXhpbWEucmVuZCgpICYmICptYXhSaXQgPiBlLT5DdXJyLlgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIGlmIChob3J6RWRnZS0+T3V0SWR4ID49IDAgJiYgIUlzT3BlbikKICAgICAgICAgICAgICAgICAgICBBZGRPdXRQdChob3J6RWRnZSwgSW50UG9pbnQoKm1heFJpdCwgaG9yekVkZ2UtPkJvdC5ZKSk7CiAgICAgICAgICAgICAgICAgIG1heFJpdCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgaWYgKChkaXIgPT0gZExlZnRUb1JpZ2h0ICYmIGUtPkN1cnIuWCA+IGhvcnpSaWdodCkgfHwKCQkJKGRpciA9PSBkUmlnaHRUb0xlZnQgJiYgZS0+Q3Vyci5YIDwgaG9yekxlZnQpKSBicmVhazsKCgkJLy9BbHNvIGJyZWFrIGlmIHdlJ3ZlIGdvdCB0byB0aGUgZW5kIG9mIGFuIGludGVybWVkaWF0ZSBob3Jpem9udGFsIGVkZ2UgLi4uCgkJLy9uYjogU21hbGxlciBEeCdzIGFyZSB0byB0aGUgcmlnaHQgb2YgbGFyZ2VyIER4J3MgQUJPVkUgdGhlIGhvcml6b250YWwuCgkJaWYgKGUtPkN1cnIuWCA9PSBob3J6RWRnZS0+VG9wLlggJiYgaG9yekVkZ2UtPk5leHRJbkxNTCAmJiAKCQkJZS0+RHggPCBob3J6RWRnZS0+TmV4dEluTE1MLT5EeCkgYnJlYWs7CgogICAgaWYgKGhvcnpFZGdlLT5PdXRJZHggPj0gMCAmJiAhSXNPcGVuKSAgLy9ub3RlOiBtYXkgYmUgZG9uZSBtdWx0aXBsZSB0aW1lcwoJCXsKICAgICAgICAgICAgb3AxID0gQWRkT3V0UHQoaG9yekVkZ2UsIGUtPkN1cnIpOwoJCQlURWRnZSogZU5leHRIb3J6ID0gbV9Tb3J0ZWRFZGdlczsKCQkJd2hpbGUgKGVOZXh0SG9yeikKCQkJewoJCQkJaWYgKGVOZXh0SG9yei0+T3V0SWR4ID49IDAgJiYKCQkJCQlIb3J6U2VnbWVudHNPdmVybGFwKGhvcnpFZGdlLT5Cb3QuWCwKCQkJCQlob3J6RWRnZS0+VG9wLlgsIGVOZXh0SG9yei0+Qm90LlgsIGVOZXh0SG9yei0+VG9wLlgpKQoJCQkJewogICAgICAgICAgICAgICAgICAgIE91dFB0KiBvcDIgPSBHZXRMYXN0T3V0UHQoZU5leHRIb3J6KTsKICAgICAgICAgICAgICAgICAgICBBZGRKb2luKG9wMiwgb3AxLCBlTmV4dEhvcnotPlRvcCk7CgkJCQl9CgkJCQllTmV4dEhvcnogPSBlTmV4dEhvcnotPk5leHRJblNFTDsKCQkJfQoJCQlBZGRHaG9zdEpvaW4ob3AxLCBob3J6RWRnZS0+Qm90KTsKCQl9CgkJCgkJLy9PSywgc28gZmFyIHdlJ3JlIHN0aWxsIGluIHJhbmdlIG9mIHRoZSBob3Jpem9udGFsIEVkZ2UgIGJ1dCBtYWtlIHN1cmUKICAgICAgICAvL3dlJ3JlIGF0IHRoZSBsYXN0IG9mIGNvbnNlYy4gaG9yaXpvbnRhbHMgd2hlbiBtYXRjaGluZyB3aXRoIGVNYXhQYWlyCiAgICAgICAgaWYoZSA9PSBlTWF4UGFpciAmJiBJc0xhc3RIb3J6KQogICAgICAgIHsKICAgICAgICAgIGlmIChob3J6RWRnZS0+T3V0SWR4ID49IDApCiAgICAgICAgICAgIEFkZExvY2FsTWF4UG9seShob3J6RWRnZSwgZU1heFBhaXIsIGhvcnpFZGdlLT5Ub3ApOwogICAgICAgICAgRGVsZXRlRnJvbUFFTChob3J6RWRnZSk7CiAgICAgICAgICBEZWxldGVGcm9tQUVMKGVNYXhQYWlyKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCgkJaWYoZGlyID09IGRMZWZ0VG9SaWdodCkKICAgICAgICB7CiAgICAgICAgICBJbnRQb2ludCBQdCA9IEludFBvaW50KGUtPkN1cnIuWCwgaG9yekVkZ2UtPkN1cnIuWSk7CiAgICAgICAgICBJbnRlcnNlY3RFZGdlcyhob3J6RWRnZSwgZSwgUHQpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgSW50UG9pbnQgUHQgPSBJbnRQb2ludChlLT5DdXJyLlgsIGhvcnpFZGdlLT5DdXJyLlkpOwogICAgICAgICAgSW50ZXJzZWN0RWRnZXMoIGUsIGhvcnpFZGdlLCBQdCk7CiAgICAgICAgfQogICAgICAgIFRFZGdlKiBlTmV4dCA9IEdldE5leHRJbkFFTChlLCBkaXIpOwogICAgICAgIFN3YXBQb3NpdGlvbnNJbkFFTCggaG9yekVkZ2UsIGUgKTsKICAgICAgICBlID0gZU5leHQ7CiAgICB9IC8vZW5kIHdoaWxlKGUpCgoJLy9CcmVhayBvdXQgb2YgbG9vcCBpZiBIb3J6RWRnZS5OZXh0SW5MTUwgaXMgbm90IGFsc28gaG9yaXpvbnRhbCAuLi4KCWlmICghaG9yekVkZ2UtPk5leHRJbkxNTCB8fCAhSXNIb3Jpem9udGFsKCpob3J6RWRnZS0+TmV4dEluTE1MKSkgYnJlYWs7CgoJVXBkYXRlRWRnZUludG9BRUwoaG9yekVkZ2UpOwogICAgaWYgKGhvcnpFZGdlLT5PdXRJZHggPj0gMCkgQWRkT3V0UHQoaG9yekVkZ2UsIGhvcnpFZGdlLT5Cb3QpOwogICAgR2V0SG9yekRpcmVjdGlvbigqaG9yekVkZ2UsIGRpciwgaG9yekxlZnQsIGhvcnpSaWdodCk7CgogIH0gLy9lbmQgZm9yICg7OykKCiAgaWYgKGhvcnpFZGdlLT5PdXRJZHggPj0gMCAmJiAhb3AxKQogIHsKICAgICAgb3AxID0gR2V0TGFzdE91dFB0KGhvcnpFZGdlKTsKICAgICAgVEVkZ2UqIGVOZXh0SG9yeiA9IG1fU29ydGVkRWRnZXM7CiAgICAgIHdoaWxlIChlTmV4dEhvcnopCiAgICAgIHsKICAgICAgICAgIGlmIChlTmV4dEhvcnotPk91dElkeCA+PSAwICYmCiAgICAgICAgICAgICAgSG9yelNlZ21lbnRzT3ZlcmxhcChob3J6RWRnZS0+Qm90LlgsCiAgICAgICAgICAgICAgaG9yekVkZ2UtPlRvcC5YLCBlTmV4dEhvcnotPkJvdC5YLCBlTmV4dEhvcnotPlRvcC5YKSkKICAgICAgICAgIHsKICAgICAgICAgICAgICBPdXRQdCogb3AyID0gR2V0TGFzdE91dFB0KGVOZXh0SG9yeik7CiAgICAgICAgICAgICAgQWRkSm9pbihvcDIsIG9wMSwgZU5leHRIb3J6LT5Ub3ApOwogICAgICAgICAgfQogICAgICAgICAgZU5leHRIb3J6ID0gZU5leHRIb3J6LT5OZXh0SW5TRUw7CiAgICAgIH0KICAgICAgQWRkR2hvc3RKb2luKG9wMSwgaG9yekVkZ2UtPlRvcCk7CiAgfQoKICBpZiAoaG9yekVkZ2UtPk5leHRJbkxNTCkKICB7CiAgICBpZihob3J6RWRnZS0+T3V0SWR4ID49IDApCiAgICB7CiAgICAgIG9wMSA9IEFkZE91dFB0KCBob3J6RWRnZSwgaG9yekVkZ2UtPlRvcCk7CiAgICAgIFVwZGF0ZUVkZ2VJbnRvQUVMKGhvcnpFZGdlKTsKICAgICAgaWYgKGhvcnpFZGdlLT5XaW5kRGVsdGEgPT0gMCkgcmV0dXJuOwogICAgICAvL25iOiBIb3J6RWRnZSBpcyBubyBsb25nZXIgaG9yaXpvbnRhbCBoZXJlCiAgICAgIFRFZGdlKiBlUHJldiA9IGhvcnpFZGdlLT5QcmV2SW5BRUw7CiAgICAgIFRFZGdlKiBlTmV4dCA9IGhvcnpFZGdlLT5OZXh0SW5BRUw7CiAgICAgIGlmIChlUHJldiAmJiBlUHJldi0+Q3Vyci5YID09IGhvcnpFZGdlLT5Cb3QuWCAmJgogICAgICAgIGVQcmV2LT5DdXJyLlkgPT0gaG9yekVkZ2UtPkJvdC5ZICYmIGVQcmV2LT5XaW5kRGVsdGEgIT0gMCAmJgogICAgICAgIChlUHJldi0+T3V0SWR4ID49IDAgJiYgZVByZXYtPkN1cnIuWSA+IGVQcmV2LT5Ub3AuWSAmJgogICAgICAgIFNsb3Blc0VxdWFsKCpob3J6RWRnZSwgKmVQcmV2LCBtX1VzZUZ1bGxSYW5nZSkpKQogICAgICB7CiAgICAgICAgT3V0UHQqIG9wMiA9IEFkZE91dFB0KGVQcmV2LCBob3J6RWRnZS0+Qm90KTsKICAgICAgICBBZGRKb2luKG9wMSwgb3AyLCBob3J6RWRnZS0+VG9wKTsKICAgICAgfQogICAgICBlbHNlIGlmIChlTmV4dCAmJiBlTmV4dC0+Q3Vyci5YID09IGhvcnpFZGdlLT5Cb3QuWCAmJgogICAgICAgIGVOZXh0LT5DdXJyLlkgPT0gaG9yekVkZ2UtPkJvdC5ZICYmIGVOZXh0LT5XaW5kRGVsdGEgIT0gMCAmJgogICAgICAgIGVOZXh0LT5PdXRJZHggPj0gMCAmJiBlTmV4dC0+Q3Vyci5ZID4gZU5leHQtPlRvcC5ZICYmCiAgICAgICAgU2xvcGVzRXF1YWwoKmhvcnpFZGdlLCAqZU5leHQsIG1fVXNlRnVsbFJhbmdlKSkKICAgICAgewogICAgICAgIE91dFB0KiBvcDIgPSBBZGRPdXRQdChlTmV4dCwgaG9yekVkZ2UtPkJvdCk7CiAgICAgICAgQWRkSm9pbihvcDEsIG9wMiwgaG9yekVkZ2UtPlRvcCk7CiAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgICAgVXBkYXRlRWRnZUludG9BRUwoaG9yekVkZ2UpOyAKICB9CiAgZWxzZQogIHsKICAgIGlmIChob3J6RWRnZS0+T3V0SWR4ID49IDApIEFkZE91dFB0KGhvcnpFZGdlLCBob3J6RWRnZS0+VG9wKTsKICAgIERlbGV0ZUZyb21BRUwoaG9yekVkZ2UpOwogIH0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBDbGlwcGVyOjpQcm9jZXNzSW50ZXJzZWN0aW9ucyhjb25zdCBjSW50IHRvcFkpCnsKICBpZiggIW1fQWN0aXZlRWRnZXMgKSByZXR1cm4gdHJ1ZTsKICB0cnkgewogICAgQnVpbGRJbnRlcnNlY3RMaXN0KHRvcFkpOwogICAgc2l6ZV90IElsU2l6ZSA9IG1fSW50ZXJzZWN0TGlzdC5zaXplKCk7CiAgICBpZiAoSWxTaXplID09IDApIHJldHVybiB0cnVlOwogICAgaWYgKElsU2l6ZSA9PSAxIHx8IEZpeHVwSW50ZXJzZWN0aW9uT3JkZXIoKSkgUHJvY2Vzc0ludGVyc2VjdExpc3QoKTsKICAgIGVsc2UgcmV0dXJuIGZhbHNlOwogIH0KICBjYXRjaCguLi4pIAogIHsKICAgIG1fU29ydGVkRWRnZXMgPSAwOwogICAgRGlzcG9zZUludGVyc2VjdE5vZGVzKCk7CiAgICB0aHJvdyBjbGlwcGVyRXhjZXB0aW9uKCJQcm9jZXNzSW50ZXJzZWN0aW9ucyBlcnJvciIpOwogIH0KICBtX1NvcnRlZEVkZ2VzID0gMDsKICByZXR1cm4gdHJ1ZTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBDbGlwcGVyOjpEaXNwb3NlSW50ZXJzZWN0Tm9kZXMoKQp7CiAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBtX0ludGVyc2VjdExpc3Quc2l6ZSgpOyArK2kgKQogICAgZGVsZXRlIG1fSW50ZXJzZWN0TGlzdFtpXTsKICBtX0ludGVyc2VjdExpc3QuY2xlYXIoKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBDbGlwcGVyOjpCdWlsZEludGVyc2VjdExpc3QoY29uc3QgY0ludCB0b3BZKQp7CiAgaWYgKCAhbV9BY3RpdmVFZGdlcyApIHJldHVybjsKCiAgLy9wcmVwYXJlIGZvciBzb3J0aW5nIC4uLgogIFRFZGdlKiBlID0gbV9BY3RpdmVFZGdlczsKICBtX1NvcnRlZEVkZ2VzID0gZTsKICB3aGlsZSggZSApCiAgewogICAgZS0+UHJldkluU0VMID0gZS0+UHJldkluQUVMOwogICAgZS0+TmV4dEluU0VMID0gZS0+TmV4dEluQUVMOwogICAgZS0+Q3Vyci5YID0gVG9wWCggKmUsIHRvcFkgKTsKICAgIGUgPSBlLT5OZXh0SW5BRUw7CiAgfQoKICAvL2J1YmJsZXNvcnQgLi4uCiAgYm9vbCBpc01vZGlmaWVkOwogIGRvCiAgewogICAgaXNNb2RpZmllZCA9IGZhbHNlOwogICAgZSA9IG1fU29ydGVkRWRnZXM7CiAgICB3aGlsZSggZS0+TmV4dEluU0VMICkKICAgIHsKICAgICAgVEVkZ2UgKmVOZXh0ID0gZS0+TmV4dEluU0VMOwogICAgICBJbnRQb2ludCBQdDsKICAgICAgaWYoZS0+Q3Vyci5YID4gZU5leHQtPkN1cnIuWCkKICAgICAgewogICAgICAgIEludGVyc2VjdFBvaW50KCplLCAqZU5leHQsIFB0KTsKICAgICAgICBpZiAoUHQuWSA8IHRvcFkpIFB0ID0gSW50UG9pbnQoVG9wWCgqZSwgdG9wWSksIHRvcFkpOwogICAgICAgIEludGVyc2VjdE5vZGUgKiBuZXdOb2RlID0gbmV3IEludGVyc2VjdE5vZGU7CiAgICAgICAgbmV3Tm9kZS0+RWRnZTEgPSBlOwogICAgICAgIG5ld05vZGUtPkVkZ2UyID0gZU5leHQ7CiAgICAgICAgbmV3Tm9kZS0+UHQgPSBQdDsKICAgICAgICBtX0ludGVyc2VjdExpc3QucHVzaF9iYWNrKG5ld05vZGUpOwoKICAgICAgICBTd2FwUG9zaXRpb25zSW5TRUwoZSwgZU5leHQpOwogICAgICAgIGlzTW9kaWZpZWQgPSB0cnVlOwogICAgICB9CiAgICAgIGVsc2UKICAgICAgICBlID0gZU5leHQ7CiAgICB9CiAgICBpZiggZS0+UHJldkluU0VMICkgZS0+UHJldkluU0VMLT5OZXh0SW5TRUwgPSAwOwogICAgZWxzZSBicmVhazsKICB9CiAgd2hpbGUgKCBpc01vZGlmaWVkICk7CiAgbV9Tb3J0ZWRFZGdlcyA9IDA7IC8vaW1wb3J0YW50Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgp2b2lkIENsaXBwZXI6OlByb2Nlc3NJbnRlcnNlY3RMaXN0KCkKewogIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbV9JbnRlcnNlY3RMaXN0LnNpemUoKTsgKytpKQogIHsKICAgIEludGVyc2VjdE5vZGUqIGlOb2RlID0gbV9JbnRlcnNlY3RMaXN0W2ldOwogICAgewogICAgICBJbnRlcnNlY3RFZGdlcyggaU5vZGUtPkVkZ2UxLCBpTm9kZS0+RWRnZTIsIGlOb2RlLT5QdCk7CiAgICAgIFN3YXBQb3NpdGlvbnNJbkFFTCggaU5vZGUtPkVkZ2UxICwgaU5vZGUtPkVkZ2UyICk7CiAgICB9CiAgICBkZWxldGUgaU5vZGU7CiAgfQogIG1fSW50ZXJzZWN0TGlzdC5jbGVhcigpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpib29sIEludGVyc2VjdExpc3RTb3J0KEludGVyc2VjdE5vZGUqIG5vZGUxLCBJbnRlcnNlY3ROb2RlKiBub2RlMikKewogIHJldHVybiBub2RlMi0+UHQuWSA8IG5vZGUxLT5QdC5ZOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgppbmxpbmUgYm9vbCBFZGdlc0FkamFjZW50KGNvbnN0IEludGVyc2VjdE5vZGUgJmlub2RlKQp7CiAgcmV0dXJuIChpbm9kZS5FZGdlMS0+TmV4dEluU0VMID09IGlub2RlLkVkZ2UyKSB8fAogICAgKGlub2RlLkVkZ2UxLT5QcmV2SW5TRUwgPT0gaW5vZGUuRWRnZTIpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpib29sIENsaXBwZXI6OkZpeHVwSW50ZXJzZWN0aW9uT3JkZXIoKQp7CiAgLy9wcmUtY29uZGl0aW9uOiBpbnRlcnNlY3Rpb25zIGFyZSBzb3J0ZWQgQm90dG9tLW1vc3QgZmlyc3QuCiAgLy9Ob3cgaXQncyBjcnVjaWFsIHRoYXQgaW50ZXJzZWN0aW9ucyBhcmUgbWFkZSBvbmx5IGJldHdlZW4gYWRqYWNlbnQgZWRnZXMsCiAgLy9zbyB0byBlbnN1cmUgdGhpcyB0aGUgb3JkZXIgb2YgaW50ZXJzZWN0aW9ucyBtYXkgbmVlZCBhZGp1c3RpbmcgLi4uCiAgQ29weUFFTFRvU0VMKCk7CiAgc3RkOjpzb3J0KG1fSW50ZXJzZWN0TGlzdC5iZWdpbigpLCBtX0ludGVyc2VjdExpc3QuZW5kKCksIEludGVyc2VjdExpc3RTb3J0KTsKICBzaXplX3QgY250ID0gbV9JbnRlcnNlY3RMaXN0LnNpemUoKTsKICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGNudDsgKytpKSAKICB7CiAgICBpZiAoIUVkZ2VzQWRqYWNlbnQoKm1fSW50ZXJzZWN0TGlzdFtpXSkpCiAgICB7CiAgICAgIHNpemVfdCBqID0gaSArIDE7CiAgICAgIHdoaWxlIChqIDwgY250ICYmICFFZGdlc0FkamFjZW50KCptX0ludGVyc2VjdExpc3Rbal0pKSBqKys7CiAgICAgIGlmIChqID09IGNudCkgIHJldHVybiBmYWxzZTsKICAgICAgc3RkOjpzd2FwKG1fSW50ZXJzZWN0TGlzdFtpXSwgbV9JbnRlcnNlY3RMaXN0W2pdKTsKICAgIH0KICAgIFN3YXBQb3NpdGlvbnNJblNFTChtX0ludGVyc2VjdExpc3RbaV0tPkVkZ2UxLCBtX0ludGVyc2VjdExpc3RbaV0tPkVkZ2UyKTsKICB9CiAgcmV0dXJuIHRydWU7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6RG9NYXhpbWEoVEVkZ2UgKmUpCnsKICBURWRnZSogZU1heFBhaXIgPSBHZXRNYXhpbWFQYWlyRXgoZSk7CiAgaWYgKCFlTWF4UGFpcikKICB7CiAgICBpZiAoZS0+T3V0SWR4ID49IDApCiAgICAgIEFkZE91dFB0KGUsIGUtPlRvcCk7CiAgICBEZWxldGVGcm9tQUVMKGUpOwogICAgcmV0dXJuOwogIH0KCiAgVEVkZ2UqIGVOZXh0ID0gZS0+TmV4dEluQUVMOwogIHdoaWxlKGVOZXh0ICYmIGVOZXh0ICE9IGVNYXhQYWlyKQogIHsKICAgIEludGVyc2VjdEVkZ2VzKGUsIGVOZXh0LCBlLT5Ub3ApOwogICAgU3dhcFBvc2l0aW9uc0luQUVMKGUsIGVOZXh0KTsKICAgIGVOZXh0ID0gZS0+TmV4dEluQUVMOwogIH0KCiAgaWYoZS0+T3V0SWR4ID09IFVuYXNzaWduZWQgJiYgZU1heFBhaXItPk91dElkeCA9PSBVbmFzc2lnbmVkKQogIHsKICAgIERlbGV0ZUZyb21BRUwoZSk7CiAgICBEZWxldGVGcm9tQUVMKGVNYXhQYWlyKTsKICB9CiAgZWxzZSBpZiggZS0+T3V0SWR4ID49IDAgJiYgZU1heFBhaXItPk91dElkeCA+PSAwICkKICB7CiAgICBpZiAoZS0+T3V0SWR4ID49IDApIEFkZExvY2FsTWF4UG9seShlLCBlTWF4UGFpciwgZS0+VG9wKTsKICAgIERlbGV0ZUZyb21BRUwoZSk7CiAgICBEZWxldGVGcm9tQUVMKGVNYXhQYWlyKTsKICB9CiNpZmRlZiB1c2VfbGluZXMKICBlbHNlIGlmIChlLT5XaW5kRGVsdGEgPT0gMCkKICB7CiAgICBpZiAoZS0+T3V0SWR4ID49IDApIAogICAgewogICAgICBBZGRPdXRQdChlLCBlLT5Ub3ApOwogICAgICBlLT5PdXRJZHggPSBVbmFzc2lnbmVkOwogICAgfQogICAgRGVsZXRlRnJvbUFFTChlKTsKCiAgICBpZiAoZU1heFBhaXItPk91dElkeCA+PSAwKQogICAgewogICAgICBBZGRPdXRQdChlTWF4UGFpciwgZS0+VG9wKTsKICAgICAgZU1heFBhaXItPk91dElkeCA9IFVuYXNzaWduZWQ7CiAgICB9CiAgICBEZWxldGVGcm9tQUVMKGVNYXhQYWlyKTsKICB9IAojZW5kaWYKICBlbHNlIHRocm93IGNsaXBwZXJFeGNlcHRpb24oIkRvTWF4aW1hIGVycm9yIik7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6UHJvY2Vzc0VkZ2VzQXRUb3BPZlNjYW5iZWFtKGNvbnN0IGNJbnQgdG9wWSkKewogIFRFZGdlKiBlID0gbV9BY3RpdmVFZGdlczsKICB3aGlsZSggZSApCiAgewogICAgLy8xLiBwcm9jZXNzIG1heGltYSwgdHJlYXRpbmcgdGhlbSBhcyBpZiB0aGV5J3JlICdiZW50JyBob3Jpem9udGFsIGVkZ2VzLAogICAgLy8gICBidXQgZXhjbHVkZSBtYXhpbWEgd2l0aCBob3Jpem9udGFsIGVkZ2VzLiBuYjogZSBjYW4ndCBiZSBhIGhvcml6b250YWwuCiAgICBib29sIElzTWF4aW1hRWRnZSA9IElzTWF4aW1hKGUsIHRvcFkpOwoKICAgIGlmKElzTWF4aW1hRWRnZSkKICAgIHsKICAgICAgVEVkZ2UqIGVNYXhQYWlyID0gR2V0TWF4aW1hUGFpckV4KGUpOwogICAgICBJc01heGltYUVkZ2UgPSAoIWVNYXhQYWlyIHx8ICFJc0hvcml6b250YWwoKmVNYXhQYWlyKSk7CiAgICB9CgogICAgaWYoSXNNYXhpbWFFZGdlKQogICAgewogICAgICBpZiAobV9TdHJpY3RTaW1wbGUpIG1fTWF4aW1hLnB1c2hfYmFjayhlLT5Ub3AuWCk7CiAgICAgIFRFZGdlKiBlUHJldiA9IGUtPlByZXZJbkFFTDsKICAgICAgRG9NYXhpbWEoZSk7CiAgICAgIGlmKCAhZVByZXYgKSBlID0gbV9BY3RpdmVFZGdlczsKICAgICAgZWxzZSBlID0gZVByZXYtPk5leHRJbkFFTDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgLy8yLiBwcm9tb3RlIGhvcml6b250YWwgZWRnZXMsIG90aGVyd2lzZSB1cGRhdGUgQ3Vyci5YIGFuZCBDdXJyLlkgLi4uCiAgICAgIGlmIChJc0ludGVybWVkaWF0ZShlLCB0b3BZKSAmJiBJc0hvcml6b250YWwoKmUtPk5leHRJbkxNTCkpCiAgICAgIHsKICAgICAgICBVcGRhdGVFZGdlSW50b0FFTChlKTsKICAgICAgICBpZiAoZS0+T3V0SWR4ID49IDApCiAgICAgICAgICBBZGRPdXRQdChlLCBlLT5Cb3QpOwogICAgICAgIEFkZEVkZ2VUb1NFTChlKTsKICAgICAgfSAKICAgICAgZWxzZQogICAgICB7CiAgICAgICAgZS0+Q3Vyci5YID0gVG9wWCggKmUsIHRvcFkgKTsKICAgICAgICBlLT5DdXJyLlkgPSB0b3BZOwogICAgICB9CgogICAgICAvL1doZW4gU3RyaWN0bHlTaW1wbGUgYW5kICdlJyBpcyBiZWluZyB0b3VjaGVkIGJ5IGFub3RoZXIgZWRnZSwgdGhlbgogICAgICAvL21ha2Ugc3VyZSBib3RoIGVkZ2VzIGhhdmUgYSB2ZXJ0ZXggaGVyZSAuLi4KICAgICAgaWYgKG1fU3RyaWN0U2ltcGxlKQogICAgICB7ICAKICAgICAgICBURWRnZSogZVByZXYgPSBlLT5QcmV2SW5BRUw7CiAgICAgICAgaWYgKChlLT5PdXRJZHggPj0gMCkgJiYgKGUtPldpbmREZWx0YSAhPSAwKSAmJiBlUHJldiAmJiAoZVByZXYtPk91dElkeCA+PSAwKSAmJgogICAgICAgICAgKGVQcmV2LT5DdXJyLlggPT0gZS0+Q3Vyci5YKSAmJiAoZVByZXYtPldpbmREZWx0YSAhPSAwKSkKICAgICAgICB7CiAgICAgICAgICBJbnRQb2ludCBwdCA9IGUtPkN1cnI7CiNpZmRlZiB1c2VfeHl6CiAgICAgICAgICBTZXRaKHB0LCAqZVByZXYsICplKTsKI2VuZGlmCiAgICAgICAgICBPdXRQdCogb3AgPSBBZGRPdXRQdChlUHJldiwgcHQpOwogICAgICAgICAgT3V0UHQqIG9wMiA9IEFkZE91dFB0KGUsIHB0KTsKICAgICAgICAgIEFkZEpvaW4ob3AsIG9wMiwgcHQpOyAvL1N0cmljdGx5U2ltcGxlICh0eXBlLTMpIGpvaW4KICAgICAgICB9CiAgICAgIH0KCiAgICAgIGUgPSBlLT5OZXh0SW5BRUw7CiAgICB9CiAgfQoKICAvLzMuIFByb2Nlc3MgaG9yaXpvbnRhbHMgYXQgdGhlIFRvcCBvZiB0aGUgc2NhbmJlYW0gLi4uCiAgbV9NYXhpbWEuc29ydCgpOwogIFByb2Nlc3NIb3Jpem9udGFscygpOwogIG1fTWF4aW1hLmNsZWFyKCk7CgogIC8vNC4gUHJvbW90ZSBpbnRlcm1lZGlhdGUgdmVydGljZXMgLi4uCiAgZSA9IG1fQWN0aXZlRWRnZXM7CiAgd2hpbGUoZSkKICB7CiAgICBpZihJc0ludGVybWVkaWF0ZShlLCB0b3BZKSkKICAgIHsKICAgICAgT3V0UHQqIG9wID0gMDsKICAgICAgaWYoIGUtPk91dElkeCA+PSAwICkgCiAgICAgICAgb3AgPSBBZGRPdXRQdChlLCBlLT5Ub3ApOwogICAgICBVcGRhdGVFZGdlSW50b0FFTChlKTsKCiAgICAgIC8vaWYgb3V0cHV0IHBvbHlnb25zIHNoYXJlIGFuIGVkZ2UsIHRoZXknbGwgbmVlZCBqb2luaW5nIGxhdGVyIC4uLgogICAgICBURWRnZSogZVByZXYgPSBlLT5QcmV2SW5BRUw7CiAgICAgIFRFZGdlKiBlTmV4dCA9IGUtPk5leHRJbkFFTDsKICAgICAgaWYgKGVQcmV2ICYmIGVQcmV2LT5DdXJyLlggPT0gZS0+Qm90LlggJiYKICAgICAgICBlUHJldi0+Q3Vyci5ZID09IGUtPkJvdC5ZICYmIG9wICYmCiAgICAgICAgZVByZXYtPk91dElkeCA+PSAwICYmIGVQcmV2LT5DdXJyLlkgPiBlUHJldi0+VG9wLlkgJiYKICAgICAgICBTbG9wZXNFcXVhbChlLT5DdXJyLCBlLT5Ub3AsIGVQcmV2LT5DdXJyLCBlUHJldi0+VG9wLCBtX1VzZUZ1bGxSYW5nZSkgJiYKICAgICAgICAoZS0+V2luZERlbHRhICE9IDApICYmIChlUHJldi0+V2luZERlbHRhICE9IDApKQogICAgICB7CiAgICAgICAgT3V0UHQqIG9wMiA9IEFkZE91dFB0KGVQcmV2LCBlLT5Cb3QpOwogICAgICAgIEFkZEpvaW4ob3AsIG9wMiwgZS0+VG9wKTsKICAgICAgfQogICAgICBlbHNlIGlmIChlTmV4dCAmJiBlTmV4dC0+Q3Vyci5YID09IGUtPkJvdC5YICYmCiAgICAgICAgZU5leHQtPkN1cnIuWSA9PSBlLT5Cb3QuWSAmJiBvcCAmJgogICAgICAgIGVOZXh0LT5PdXRJZHggPj0gMCAmJiBlTmV4dC0+Q3Vyci5ZID4gZU5leHQtPlRvcC5ZICYmCiAgICAgICAgU2xvcGVzRXF1YWwoZS0+Q3VyciwgZS0+VG9wLCBlTmV4dC0+Q3VyciwgZU5leHQtPlRvcCwgbV9Vc2VGdWxsUmFuZ2UpICYmCiAgICAgICAgKGUtPldpbmREZWx0YSAhPSAwKSAmJiAoZU5leHQtPldpbmREZWx0YSAhPSAwKSkKICAgICAgewogICAgICAgIE91dFB0KiBvcDIgPSBBZGRPdXRQdChlTmV4dCwgZS0+Qm90KTsKICAgICAgICBBZGRKb2luKG9wLCBvcDIsIGUtPlRvcCk7CiAgICAgIH0KICAgIH0KICAgIGUgPSBlLT5OZXh0SW5BRUw7CiAgfQp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXI6OkZpeHVwT3V0UG9seWxpbmUoT3V0UmVjICZvdXRyZWMpCnsKICBPdXRQdCAqcHAgPSBvdXRyZWMuUHRzOwogIE91dFB0ICpsYXN0UFAgPSBwcC0+UHJldjsKICB3aGlsZSAocHAgIT0gbGFzdFBQKQogIHsKICAgIHBwID0gcHAtPk5leHQ7CiAgICBpZiAocHAtPlB0ID09IHBwLT5QcmV2LT5QdCkKICAgIHsKICAgICAgaWYgKHBwID09IGxhc3RQUCkgbGFzdFBQID0gcHAtPlByZXY7CiAgICAgIE91dFB0ICp0bXBQUCA9IHBwLT5QcmV2OwogICAgICB0bXBQUC0+TmV4dCA9IHBwLT5OZXh0OwogICAgICBwcC0+TmV4dC0+UHJldiA9IHRtcFBQOwogICAgICBkZWxldGUgcHA7CiAgICAgIHBwID0gdG1wUFA7CiAgICB9CiAgfQoKICBpZiAocHAgPT0gcHAtPlByZXYpCiAgewogICAgRGlzcG9zZU91dFB0cyhwcCk7CiAgICBvdXRyZWMuUHRzID0gMDsKICAgIHJldHVybjsKICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6Rml4dXBPdXRQb2x5Z29uKE91dFJlYyAmb3V0cmVjKQp7CiAgICAvL0ZpeHVwT3V0UG9seWdvbigpIC0gcmVtb3ZlcyBkdXBsaWNhdGUgcG9pbnRzIGFuZCBzaW1wbGlmaWVzIGNvbnNlY3V0aXZlCiAgICAvL3BhcmFsbGVsIGVkZ2VzIGJ5IHJlbW92aW5nIHRoZSBtaWRkbGUgdmVydGV4LgogICAgT3V0UHQgKmxhc3RPSyA9IDA7CiAgICBvdXRyZWMuQm90dG9tUHQgPSAwOwogICAgT3V0UHQgKnBwID0gb3V0cmVjLlB0czsKICAgIGJvb2wgcHJlc2VydmVDb2wgPSBtX1ByZXNlcnZlQ29sbGluZWFyIHx8IG1fU3RyaWN0U2ltcGxlOwoKICAgIGZvciAoOzspCiAgICB7CiAgICAgICAgaWYgKHBwLT5QcmV2ID09IHBwIHx8IHBwLT5QcmV2ID09IHBwLT5OZXh0KQogICAgICAgIHsKICAgICAgICAgICAgRGlzcG9zZU91dFB0cyhwcCk7CiAgICAgICAgICAgIG91dHJlYy5QdHMgPSAwOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvL3Rlc3QgZm9yIGR1cGxpY2F0ZSBwb2ludHMgYW5kIGNvbGxpbmVhciBlZGdlcyAuLi4KICAgICAgICBpZiAoKHBwLT5QdCA9PSBwcC0+TmV4dC0+UHQpIHx8IChwcC0+UHQgPT0gcHAtPlByZXYtPlB0KSB8fAogICAgICAgICAgICAoU2xvcGVzRXF1YWwocHAtPlByZXYtPlB0LCBwcC0+UHQsIHBwLT5OZXh0LT5QdCwgbV9Vc2VGdWxsUmFuZ2UpICYmCiAgICAgICAgICAgICghcHJlc2VydmVDb2wgfHwgIVB0MklzQmV0d2VlblB0MUFuZFB0MyhwcC0+UHJldi0+UHQsIHBwLT5QdCwgcHAtPk5leHQtPlB0KSkpKQogICAgICAgIHsKICAgICAgICAgICAgbGFzdE9LID0gMDsKICAgICAgICAgICAgT3V0UHQgKnRtcCA9IHBwOwogICAgICAgICAgICBwcC0+UHJldi0+TmV4dCA9IHBwLT5OZXh0OwogICAgICAgICAgICBwcC0+TmV4dC0+UHJldiA9IHBwLT5QcmV2OwogICAgICAgICAgICBwcCA9IHBwLT5QcmV2OwogICAgICAgICAgICBkZWxldGUgdG1wOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChwcCA9PSBsYXN0T0spIGJyZWFrOwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmICghbGFzdE9LKSBsYXN0T0sgPSBwcDsKICAgICAgICAgICAgcHAgPSBwcC0+TmV4dDsKICAgICAgICB9CiAgICB9CiAgICBvdXRyZWMuUHRzID0gcHA7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmludCBQb2ludENvdW50KE91dFB0ICpQdHMpCnsKICAgIGlmICghUHRzKSByZXR1cm4gMDsKICAgIGludCByZXN1bHQgPSAwOwogICAgT3V0UHQqIHAgPSBQdHM7CiAgICBkbwogICAgewogICAgICAgIHJlc3VsdCsrOwogICAgICAgIHAgPSBwLT5OZXh0OwogICAgfQogICAgd2hpbGUgKHAgIT0gUHRzKTsKICAgIHJldHVybiByZXN1bHQ7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6QnVpbGRSZXN1bHQoUGF0aHMgJnBvbHlzKQp7CiAgcG9seXMucmVzZXJ2ZShtX1BvbHlPdXRzLnNpemUoKSk7CiAgZm9yIChQb2x5T3V0TGlzdDo6c2l6ZV90eXBlIGkgPSAwOyBpIDwgbV9Qb2x5T3V0cy5zaXplKCk7ICsraSkKICB7CiAgICBpZiAoIW1fUG9seU91dHNbaV0tPlB0cykgY29udGludWU7CiAgICBQYXRoIHBnOwogICAgT3V0UHQqIHAgPSBtX1BvbHlPdXRzW2ldLT5QdHMtPlByZXY7CiAgICBpbnQgY250ID0gUG9pbnRDb3VudChwKTsKICAgIGlmIChjbnQgPCAyKSBjb250aW51ZTsKICAgIHBnLnJlc2VydmUoY250KTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY250OyArK2kpCiAgICB7CiAgICAgIHBnLnB1c2hfYmFjayhwLT5QdCk7CiAgICAgIHAgPSBwLT5QcmV2OwogICAgfQogICAgcG9seXMucHVzaF9iYWNrKHBnKTsKICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6QnVpbGRSZXN1bHQyKFBvbHlUcmVlJiBwb2x5dHJlZSkKewogICAgcG9seXRyZWUuQ2xlYXIoKTsKICAgIHBvbHl0cmVlLkFsbE5vZGVzLnJlc2VydmUobV9Qb2x5T3V0cy5zaXplKCkpOwogICAgLy9hZGQgZWFjaCBvdXRwdXQgcG9seWdvbi9jb250b3VyIHRvIHBvbHl0cmVlIC4uLgogICAgZm9yIChQb2x5T3V0TGlzdDo6c2l6ZV90eXBlIGkgPSAwOyBpIDwgbV9Qb2x5T3V0cy5zaXplKCk7IGkrKykKICAgIHsKICAgICAgICBPdXRSZWMqIG91dFJlYyA9IG1fUG9seU91dHNbaV07CiAgICAgICAgaW50IGNudCA9IFBvaW50Q291bnQob3V0UmVjLT5QdHMpOwogICAgICAgIGlmICgob3V0UmVjLT5Jc09wZW4gJiYgY250IDwgMikgfHwgKCFvdXRSZWMtPklzT3BlbiAmJiBjbnQgPCAzKSkgY29udGludWU7CiAgICAgICAgRml4SG9sZUxpbmthZ2UoKm91dFJlYyk7CiAgICAgICAgUG9seU5vZGUqIHBuID0gbmV3IFBvbHlOb2RlKCk7CiAgICAgICAgLy9uYjogcG9seXRyZWUgdGFrZXMgb3duZXJzaGlwIG9mIGFsbCB0aGUgUG9seU5vZGVzCiAgICAgICAgcG9seXRyZWUuQWxsTm9kZXMucHVzaF9iYWNrKHBuKTsKICAgICAgICBvdXRSZWMtPlBvbHlOZCA9IHBuOwogICAgICAgIHBuLT5QYXJlbnQgPSAwOwogICAgICAgIHBuLT5JbmRleCA9IDA7CiAgICAgICAgcG4tPkNvbnRvdXIucmVzZXJ2ZShjbnQpOwogICAgICAgIE91dFB0ICpvcCA9IG91dFJlYy0+UHRzLT5QcmV2OwogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgY250OyBqKyspCiAgICAgICAgewogICAgICAgICAgICBwbi0+Q29udG91ci5wdXNoX2JhY2sob3AtPlB0KTsKICAgICAgICAgICAgb3AgPSBvcC0+UHJldjsKICAgICAgICB9CiAgICB9CgogICAgLy9maXh1cCBQb2x5Tm9kZSBsaW5rcyBldGMgLi4uCiAgICBwb2x5dHJlZS5DaGlsZHMucmVzZXJ2ZShtX1BvbHlPdXRzLnNpemUoKSk7CiAgICBmb3IgKFBvbHlPdXRMaXN0OjpzaXplX3R5cGUgaSA9IDA7IGkgPCBtX1BvbHlPdXRzLnNpemUoKTsgaSsrKQogICAgewogICAgICAgIE91dFJlYyogb3V0UmVjID0gbV9Qb2x5T3V0c1tpXTsKICAgICAgICBpZiAoIW91dFJlYy0+UG9seU5kKSBjb250aW51ZTsKICAgICAgICBpZiAob3V0UmVjLT5Jc09wZW4pIAogICAgICAgIHsKICAgICAgICAgIG91dFJlYy0+UG9seU5kLT5tX0lzT3BlbiA9IHRydWU7CiAgICAgICAgICBwb2x5dHJlZS5BZGRDaGlsZCgqb3V0UmVjLT5Qb2x5TmQpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChvdXRSZWMtPkZpcnN0TGVmdCAmJiBvdXRSZWMtPkZpcnN0TGVmdC0+UG9seU5kKSAKICAgICAgICAgIG91dFJlYy0+Rmlyc3RMZWZ0LT5Qb2x5TmQtPkFkZENoaWxkKCpvdXRSZWMtPlBvbHlOZCk7CiAgICAgICAgZWxzZQogICAgICAgICAgcG9seXRyZWUuQWRkQ2hpbGQoKm91dFJlYy0+UG9seU5kKTsKICAgIH0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBTd2FwSW50ZXJzZWN0Tm9kZXMoSW50ZXJzZWN0Tm9kZSAmaW50MSwgSW50ZXJzZWN0Tm9kZSAmaW50MikKewogIC8vanVzdCBzd2FwIHRoZSBjb250ZW50cyAoYmVjYXVzZSBmSW50ZXJzZWN0Tm9kZXMgaXMgYSBzaW5nbGUtbGlua2VkLWxpc3QpCiAgSW50ZXJzZWN0Tm9kZSBpbm9kZSA9IGludDE7IC8vZ2V0cyBhIGNvcHkgb2YgSW50MQogIGludDEuRWRnZTEgPSBpbnQyLkVkZ2UxOwogIGludDEuRWRnZTIgPSBpbnQyLkVkZ2UyOwogIGludDEuUHQgPSBpbnQyLlB0OwogIGludDIuRWRnZTEgPSBpbm9kZS5FZGdlMTsKICBpbnQyLkVkZ2UyID0gaW5vZGUuRWRnZTI7CiAgaW50Mi5QdCA9IGlub2RlLlB0Owp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgppbmxpbmUgYm9vbCBFMkluc2VydHNCZWZvcmVFMShURWRnZSAmZTEsIFRFZGdlICZlMikKewogIGlmIChlMi5DdXJyLlggPT0gZTEuQ3Vyci5YKSAKICB7CiAgICBpZiAoZTIuVG9wLlkgPiBlMS5Ub3AuWSkKICAgICAgcmV0dXJuIGUyLlRvcC5YIDwgVG9wWChlMSwgZTIuVG9wLlkpOyAKICAgICAgZWxzZSByZXR1cm4gZTEuVG9wLlggPiBUb3BYKGUyLCBlMS5Ub3AuWSk7CiAgfSAKICBlbHNlIHJldHVybiBlMi5DdXJyLlggPCBlMS5DdXJyLlg7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmJvb2wgR2V0T3ZlcmxhcChjb25zdCBjSW50IGExLCBjb25zdCBjSW50IGEyLCBjb25zdCBjSW50IGIxLCBjb25zdCBjSW50IGIyLCAKICAgIGNJbnQmIExlZnQsIGNJbnQmIFJpZ2h0KQp7CiAgaWYgKGExIDwgYTIpCiAgewogICAgaWYgKGIxIDwgYjIpIHtMZWZ0ID0gc3RkOjptYXgoYTEsYjEpOyBSaWdodCA9IHN0ZDo6bWluKGEyLGIyKTt9CiAgICBlbHNlIHtMZWZ0ID0gc3RkOjptYXgoYTEsYjIpOyBSaWdodCA9IHN0ZDo6bWluKGEyLGIxKTt9CiAgfSAKICBlbHNlCiAgewogICAgaWYgKGIxIDwgYjIpIHtMZWZ0ID0gc3RkOjptYXgoYTIsYjEpOyBSaWdodCA9IHN0ZDo6bWluKGExLGIyKTt9CiAgICBlbHNlIHtMZWZ0ID0gc3RkOjptYXgoYTIsYjIpOyBSaWdodCA9IHN0ZDo6bWluKGExLGIxKTt9CiAgfQogIHJldHVybiBMZWZ0IDwgUmlnaHQ7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmlubGluZSB2b2lkIFVwZGF0ZU91dFB0SWR4cyhPdXRSZWMmIG91dHJlYykKeyAgCiAgT3V0UHQqIG9wID0gb3V0cmVjLlB0czsKICBkbwogIHsKICAgIG9wLT5JZHggPSBvdXRyZWMuSWR4OwogICAgb3AgPSBvcC0+UHJldjsKICB9CiAgd2hpbGUob3AgIT0gb3V0cmVjLlB0cyk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6SW5zZXJ0RWRnZUludG9BRUwoVEVkZ2UgKmVkZ2UsIFRFZGdlKiBzdGFydEVkZ2UpCnsKICBpZighbV9BY3RpdmVFZGdlcykKICB7CiAgICBlZGdlLT5QcmV2SW5BRUwgPSAwOwogICAgZWRnZS0+TmV4dEluQUVMID0gMDsKICAgIG1fQWN0aXZlRWRnZXMgPSBlZGdlOwogIH0KICBlbHNlIGlmKCFzdGFydEVkZ2UgJiYgRTJJbnNlcnRzQmVmb3JlRTEoKm1fQWN0aXZlRWRnZXMsICplZGdlKSkKICB7CiAgICAgIGVkZ2UtPlByZXZJbkFFTCA9IDA7CiAgICAgIGVkZ2UtPk5leHRJbkFFTCA9IG1fQWN0aXZlRWRnZXM7CiAgICAgIG1fQWN0aXZlRWRnZXMtPlByZXZJbkFFTCA9IGVkZ2U7CiAgICAgIG1fQWN0aXZlRWRnZXMgPSBlZGdlOwogIH0gCiAgZWxzZQogIHsKICAgIGlmKCFzdGFydEVkZ2UpIHN0YXJ0RWRnZSA9IG1fQWN0aXZlRWRnZXM7CiAgICB3aGlsZShzdGFydEVkZ2UtPk5leHRJbkFFTCAgJiYgCiAgICAgICFFMkluc2VydHNCZWZvcmVFMSgqc3RhcnRFZGdlLT5OZXh0SW5BRUwgLCAqZWRnZSkpCiAgICAgICAgc3RhcnRFZGdlID0gc3RhcnRFZGdlLT5OZXh0SW5BRUw7CiAgICBlZGdlLT5OZXh0SW5BRUwgPSBzdGFydEVkZ2UtPk5leHRJbkFFTDsKICAgIGlmKHN0YXJ0RWRnZS0+TmV4dEluQUVMKSBzdGFydEVkZ2UtPk5leHRJbkFFTC0+UHJldkluQUVMID0gZWRnZTsKICAgIGVkZ2UtPlByZXZJbkFFTCA9IHN0YXJ0RWRnZTsKICAgIHN0YXJ0RWRnZS0+TmV4dEluQUVMID0gZWRnZTsKICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpPdXRQdCogRHVwT3V0UHQoT3V0UHQqIG91dFB0LCBib29sIEluc2VydEFmdGVyKQp7CiAgT3V0UHQqIHJlc3VsdCA9IG5ldyBPdXRQdDsKICByZXN1bHQtPlB0ID0gb3V0UHQtPlB0OwogIHJlc3VsdC0+SWR4ID0gb3V0UHQtPklkeDsKICBpZiAoSW5zZXJ0QWZ0ZXIpCiAgewogICAgcmVzdWx0LT5OZXh0ID0gb3V0UHQtPk5leHQ7CiAgICByZXN1bHQtPlByZXYgPSBvdXRQdDsKICAgIG91dFB0LT5OZXh0LT5QcmV2ID0gcmVzdWx0OwogICAgb3V0UHQtPk5leHQgPSByZXN1bHQ7CiAgfSAKICBlbHNlCiAgewogICAgcmVzdWx0LT5QcmV2ID0gb3V0UHQtPlByZXY7CiAgICByZXN1bHQtPk5leHQgPSBvdXRQdDsKICAgIG91dFB0LT5QcmV2LT5OZXh0ID0gcmVzdWx0OwogICAgb3V0UHQtPlByZXYgPSByZXN1bHQ7CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmJvb2wgSm9pbkhvcnooT3V0UHQqIG9wMSwgT3V0UHQqIG9wMWIsIE91dFB0KiBvcDIsIE91dFB0KiBvcDJiLAogIGNvbnN0IEludFBvaW50IFB0LCBib29sIERpc2NhcmRMZWZ0KQp7CiAgRGlyZWN0aW9uIERpcjEgPSAob3AxLT5QdC5YID4gb3AxYi0+UHQuWCA/IGRSaWdodFRvTGVmdCA6IGRMZWZ0VG9SaWdodCk7CiAgRGlyZWN0aW9uIERpcjIgPSAob3AyLT5QdC5YID4gb3AyYi0+UHQuWCA/IGRSaWdodFRvTGVmdCA6IGRMZWZ0VG9SaWdodCk7CiAgaWYgKERpcjEgPT0gRGlyMikgcmV0dXJuIGZhbHNlOwoKICAvL1doZW4gRGlzY2FyZExlZnQsIHdlIHdhbnQgT3AxYiB0byBiZSBvbiB0aGUgTGVmdCBvZiBPcDEsIG90aGVyd2lzZSB3ZQogIC8vd2FudCBPcDFiIHRvIGJlIG9uIHRoZSBSaWdodC4gKEFuZCBsaWtld2lzZSB3aXRoIE9wMiBhbmQgT3AyYi4pCiAgLy9TbywgdG8gZmFjaWxpdGF0ZSB0aGlzIHdoaWxlIGluc2VydGluZyBPcDFiIGFuZCBPcDJiIC4uLgogIC8vd2hlbiBEaXNjYXJkTGVmdCwgbWFrZSBzdXJlIHdlJ3JlIEFUIG9yIFJJR0hUIG9mIFB0IGJlZm9yZSBhZGRpbmcgT3AxYiwKICAvL290aGVyd2lzZSBtYWtlIHN1cmUgd2UncmUgQVQgb3IgTEVGVCBvZiBQdC4gKExpa2V3aXNlIHdpdGggT3AyYi4pCiAgaWYgKERpcjEgPT0gZExlZnRUb1JpZ2h0KSAKICB7CiAgICB3aGlsZSAob3AxLT5OZXh0LT5QdC5YIDw9IFB0LlggJiYgCiAgICAgIG9wMS0+TmV4dC0+UHQuWCA+PSBvcDEtPlB0LlggJiYgb3AxLT5OZXh0LT5QdC5ZID09IFB0LlkpICAKICAgICAgICBvcDEgPSBvcDEtPk5leHQ7CiAgICBpZiAoRGlzY2FyZExlZnQgJiYgKG9wMS0+UHQuWCAhPSBQdC5YKSkgb3AxID0gb3AxLT5OZXh0OwogICAgb3AxYiA9IER1cE91dFB0KG9wMSwgIURpc2NhcmRMZWZ0KTsKICAgIGlmIChvcDFiLT5QdCAhPSBQdCkgCiAgICB7CiAgICAgIG9wMSA9IG9wMWI7CiAgICAgIG9wMS0+UHQgPSBQdDsKICAgICAgb3AxYiA9IER1cE91dFB0KG9wMSwgIURpc2NhcmRMZWZ0KTsKICAgIH0KICB9IAogIGVsc2UKICB7CiAgICB3aGlsZSAob3AxLT5OZXh0LT5QdC5YID49IFB0LlggJiYgCiAgICAgIG9wMS0+TmV4dC0+UHQuWCA8PSBvcDEtPlB0LlggJiYgb3AxLT5OZXh0LT5QdC5ZID09IFB0LlkpIAogICAgICAgIG9wMSA9IG9wMS0+TmV4dDsKICAgIGlmICghRGlzY2FyZExlZnQgJiYgKG9wMS0+UHQuWCAhPSBQdC5YKSkgb3AxID0gb3AxLT5OZXh0OwogICAgb3AxYiA9IER1cE91dFB0KG9wMSwgRGlzY2FyZExlZnQpOwogICAgaWYgKG9wMWItPlB0ICE9IFB0KQogICAgewogICAgICBvcDEgPSBvcDFiOwogICAgICBvcDEtPlB0ID0gUHQ7CiAgICAgIG9wMWIgPSBEdXBPdXRQdChvcDEsIERpc2NhcmRMZWZ0KTsKICAgIH0KICB9CgogIGlmIChEaXIyID09IGRMZWZ0VG9SaWdodCkKICB7CiAgICB3aGlsZSAob3AyLT5OZXh0LT5QdC5YIDw9IFB0LlggJiYgCiAgICAgIG9wMi0+TmV4dC0+UHQuWCA+PSBvcDItPlB0LlggJiYgb3AyLT5OZXh0LT5QdC5ZID09IFB0LlkpCiAgICAgICAgb3AyID0gb3AyLT5OZXh0OwogICAgaWYgKERpc2NhcmRMZWZ0ICYmIChvcDItPlB0LlggIT0gUHQuWCkpIG9wMiA9IG9wMi0+TmV4dDsKICAgIG9wMmIgPSBEdXBPdXRQdChvcDIsICFEaXNjYXJkTGVmdCk7CiAgICBpZiAob3AyYi0+UHQgIT0gUHQpCiAgICB7CiAgICAgIG9wMiA9IG9wMmI7CiAgICAgIG9wMi0+UHQgPSBQdDsKICAgICAgb3AyYiA9IER1cE91dFB0KG9wMiwgIURpc2NhcmRMZWZ0KTsKICAgIH07CiAgfSBlbHNlCiAgewogICAgd2hpbGUgKG9wMi0+TmV4dC0+UHQuWCA+PSBQdC5YICYmIAogICAgICBvcDItPk5leHQtPlB0LlggPD0gb3AyLT5QdC5YICYmIG9wMi0+TmV4dC0+UHQuWSA9PSBQdC5ZKSAKICAgICAgICBvcDIgPSBvcDItPk5leHQ7CiAgICBpZiAoIURpc2NhcmRMZWZ0ICYmIChvcDItPlB0LlggIT0gUHQuWCkpIG9wMiA9IG9wMi0+TmV4dDsKICAgIG9wMmIgPSBEdXBPdXRQdChvcDIsIERpc2NhcmRMZWZ0KTsKICAgIGlmIChvcDJiLT5QdCAhPSBQdCkKICAgIHsKICAgICAgb3AyID0gb3AyYjsKICAgICAgb3AyLT5QdCA9IFB0OwogICAgICBvcDJiID0gRHVwT3V0UHQob3AyLCBEaXNjYXJkTGVmdCk7CiAgICB9OwogIH07CgogIGlmICgoRGlyMSA9PSBkTGVmdFRvUmlnaHQpID09IERpc2NhcmRMZWZ0KQogIHsKICAgIG9wMS0+UHJldiA9IG9wMjsKICAgIG9wMi0+TmV4dCA9IG9wMTsKICAgIG9wMWItPk5leHQgPSBvcDJiOwogICAgb3AyYi0+UHJldiA9IG9wMWI7CiAgfQogIGVsc2UKICB7CiAgICBvcDEtPk5leHQgPSBvcDI7CiAgICBvcDItPlByZXYgPSBvcDE7CiAgICBvcDFiLT5QcmV2ID0gb3AyYjsKICAgIG9wMmItPk5leHQgPSBvcDFiOwogIH0KICByZXR1cm4gdHJ1ZTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBDbGlwcGVyOjpKb2luUG9pbnRzKEpvaW4gKmosIE91dFJlYyogb3V0UmVjMSwgT3V0UmVjKiBvdXRSZWMyKQp7CiAgT3V0UHQgKm9wMSA9IGotPk91dFB0MSwgKm9wMWI7CiAgT3V0UHQgKm9wMiA9IGotPk91dFB0MiwgKm9wMmI7CgogIC8vVGhlcmUgYXJlIDMga2luZHMgb2Ygam9pbnMgZm9yIG91dHB1dCBwb2x5Z29ucyAuLi4KICAvLzEuIEhvcml6b250YWwgam9pbnMgd2hlcmUgSm9pbi5PdXRQdDEgJiBKb2luLk91dFB0MiBhcmUgdmVydGljZXMgYW55d2hlcmUKICAvL2Fsb25nIChob3Jpem9udGFsKSBjb2xsaW5lYXIgZWRnZXMgKCYgSm9pbi5PZmZQdCBpcyBvbiB0aGUgc2FtZSBob3Jpem9udGFsKS4KICAvLzIuIE5vbi1ob3Jpem9udGFsIGpvaW5zIHdoZXJlIEpvaW4uT3V0UHQxICYgSm9pbi5PdXRQdDIgYXJlIGF0IHRoZSBzYW1lCiAgLy9sb2NhdGlvbiBhdCB0aGUgQm90dG9tIG9mIHRoZSBvdmVybGFwcGluZyBzZWdtZW50ICgmIEpvaW4uT2ZmUHQgaXMgYWJvdmUpLgogIC8vMy4gU3RyaWN0U2ltcGxlIGpvaW5zIHdoZXJlIGVkZ2VzIHRvdWNoIGJ1dCBhcmUgbm90IGNvbGxpbmVhciBhbmQgd2hlcmUKICAvL0pvaW4uT3V0UHQxLCBKb2luLk91dFB0MiAmIEpvaW4uT2ZmUHQgYWxsIHNoYXJlIHRoZSBzYW1lIHBvaW50LgogIGJvb2wgaXNIb3Jpem9udGFsID0gKGotPk91dFB0MS0+UHQuWSA9PSBqLT5PZmZQdC5ZKTsKCiAgaWYgKGlzSG9yaXpvbnRhbCAgJiYgKGotPk9mZlB0ID09IGotPk91dFB0MS0+UHQpICYmCiAgKGotPk9mZlB0ID09IGotPk91dFB0Mi0+UHQpKQogIHsKICAgIC8vU3RyaWN0bHkgU2ltcGxlIGpvaW4gLi4uCiAgICBpZiAob3V0UmVjMSAhPSBvdXRSZWMyKSByZXR1cm4gZmFsc2U7CiAgICBvcDFiID0gai0+T3V0UHQxLT5OZXh0OwogICAgd2hpbGUgKG9wMWIgIT0gb3AxICYmIChvcDFiLT5QdCA9PSBqLT5PZmZQdCkpIAogICAgICBvcDFiID0gb3AxYi0+TmV4dDsKICAgIGJvb2wgcmV2ZXJzZTEgPSAob3AxYi0+UHQuWSA+IGotPk9mZlB0LlkpOwogICAgb3AyYiA9IGotPk91dFB0Mi0+TmV4dDsKICAgIHdoaWxlIChvcDJiICE9IG9wMiAmJiAob3AyYi0+UHQgPT0gai0+T2ZmUHQpKSAKICAgICAgb3AyYiA9IG9wMmItPk5leHQ7CiAgICBib29sIHJldmVyc2UyID0gKG9wMmItPlB0LlkgPiBqLT5PZmZQdC5ZKTsKICAgIGlmIChyZXZlcnNlMSA9PSByZXZlcnNlMikgcmV0dXJuIGZhbHNlOwogICAgaWYgKHJldmVyc2UxKQogICAgewogICAgICBvcDFiID0gRHVwT3V0UHQob3AxLCBmYWxzZSk7CiAgICAgIG9wMmIgPSBEdXBPdXRQdChvcDIsIHRydWUpOwogICAgICBvcDEtPlByZXYgPSBvcDI7CiAgICAgIG9wMi0+TmV4dCA9IG9wMTsKICAgICAgb3AxYi0+TmV4dCA9IG9wMmI7CiAgICAgIG9wMmItPlByZXYgPSBvcDFiOwogICAgICBqLT5PdXRQdDEgPSBvcDE7CiAgICAgIGotPk91dFB0MiA9IG9wMWI7CiAgICAgIHJldHVybiB0cnVlOwogICAgfSBlbHNlCiAgICB7CiAgICAgIG9wMWIgPSBEdXBPdXRQdChvcDEsIHRydWUpOwogICAgICBvcDJiID0gRHVwT3V0UHQob3AyLCBmYWxzZSk7CiAgICAgIG9wMS0+TmV4dCA9IG9wMjsKICAgICAgb3AyLT5QcmV2ID0gb3AxOwogICAgICBvcDFiLT5QcmV2ID0gb3AyYjsKICAgICAgb3AyYi0+TmV4dCA9IG9wMWI7CiAgICAgIGotPk91dFB0MSA9IG9wMTsKICAgICAgai0+T3V0UHQyID0gb3AxYjsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfSAKICBlbHNlIGlmIChpc0hvcml6b250YWwpCiAgewogICAgLy90cmVhdCBob3Jpem9udGFsIGpvaW5zIGRpZmZlcmVudGx5IHRvIG5vbi1ob3Jpem9udGFsIGpvaW5zIHNpbmNlIHdpdGgKICAgIC8vdGhlbSB3ZSdyZSBub3QgeWV0IHN1cmUgd2hlcmUgdGhlIG92ZXJsYXBwaW5nIGlzLiBPdXRQdDEuUHQgJiBPdXRQdDIuUHQKICAgIC8vbWF5IGJlIGFueXdoZXJlIGFsb25nIHRoZSBob3Jpem9udGFsIGVkZ2UuCiAgICBvcDFiID0gb3AxOwogICAgd2hpbGUgKG9wMS0+UHJldi0+UHQuWSA9PSBvcDEtPlB0LlkgJiYgb3AxLT5QcmV2ICE9IG9wMWIgJiYgb3AxLT5QcmV2ICE9IG9wMikKICAgICAgb3AxID0gb3AxLT5QcmV2OwogICAgd2hpbGUgKG9wMWItPk5leHQtPlB0LlkgPT0gb3AxYi0+UHQuWSAmJiBvcDFiLT5OZXh0ICE9IG9wMSAmJiBvcDFiLT5OZXh0ICE9IG9wMikKICAgICAgb3AxYiA9IG9wMWItPk5leHQ7CiAgICBpZiAob3AxYi0+TmV4dCA9PSBvcDEgfHwgb3AxYi0+TmV4dCA9PSBvcDIpIHJldHVybiBmYWxzZTsgLy9hIGZsYXQgJ3BvbHlnb24nCgogICAgb3AyYiA9IG9wMjsKICAgIHdoaWxlIChvcDItPlByZXYtPlB0LlkgPT0gb3AyLT5QdC5ZICYmIG9wMi0+UHJldiAhPSBvcDJiICYmIG9wMi0+UHJldiAhPSBvcDFiKQogICAgICBvcDIgPSBvcDItPlByZXY7CiAgICB3aGlsZSAob3AyYi0+TmV4dC0+UHQuWSA9PSBvcDJiLT5QdC5ZICYmIG9wMmItPk5leHQgIT0gb3AyICYmIG9wMmItPk5leHQgIT0gb3AxKQogICAgICBvcDJiID0gb3AyYi0+TmV4dDsKICAgIGlmIChvcDJiLT5OZXh0ID09IG9wMiB8fCBvcDJiLT5OZXh0ID09IG9wMSkgcmV0dXJuIGZhbHNlOyAvL2EgZmxhdCAncG9seWdvbicKCiAgICBjSW50IExlZnQsIFJpZ2h0OwogICAgLy9PcDEgLS0+IE9wMWIgJiBPcDIgLS0+IE9wMmIgYXJlIHRoZSBleHRyZW1pdGVzIG9mIHRoZSBob3Jpem9udGFsIGVkZ2VzCiAgICBpZiAoIUdldE92ZXJsYXAob3AxLT5QdC5YLCBvcDFiLT5QdC5YLCBvcDItPlB0LlgsIG9wMmItPlB0LlgsIExlZnQsIFJpZ2h0KSkKICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIC8vRGlzY2FyZExlZnRTaWRlOiB3aGVuIG92ZXJsYXBwaW5nIGVkZ2VzIGFyZSBqb2luZWQsIGEgc3Bpa2Ugd2lsbCBjcmVhdGVkCiAgICAvL3doaWNoIG5lZWRzIHRvIGJlIGNsZWFuZWQgdXAuIEhvd2V2ZXIsIHdlIGRvbid0IHdhbnQgT3AxIG9yIE9wMiBjYXVnaHQgdXAKICAgIC8vb24gdGhlIGRpc2NhcmQgU2lkZSBhcyBlaXRoZXIgbWF5IHN0aWxsIGJlIG5lZWRlZCBmb3Igb3RoZXIgam9pbnMgLi4uCiAgICBJbnRQb2ludCBQdDsKICAgIGJvb2wgRGlzY2FyZExlZnRTaWRlOwogICAgaWYgKG9wMS0+UHQuWCA+PSBMZWZ0ICYmIG9wMS0+UHQuWCA8PSBSaWdodCkgCiAgICB7CiAgICAgIFB0ID0gb3AxLT5QdDsgRGlzY2FyZExlZnRTaWRlID0gKG9wMS0+UHQuWCA+IG9wMWItPlB0LlgpOwogICAgfSAKICAgIGVsc2UgaWYgKG9wMi0+UHQuWCA+PSBMZWZ0JiYgb3AyLT5QdC5YIDw9IFJpZ2h0KSAKICAgIHsKICAgICAgUHQgPSBvcDItPlB0OyBEaXNjYXJkTGVmdFNpZGUgPSAob3AyLT5QdC5YID4gb3AyYi0+UHQuWCk7CiAgICB9IAogICAgZWxzZSBpZiAob3AxYi0+UHQuWCA+PSBMZWZ0ICYmIG9wMWItPlB0LlggPD0gUmlnaHQpCiAgICB7CiAgICAgIFB0ID0gb3AxYi0+UHQ7IERpc2NhcmRMZWZ0U2lkZSA9IG9wMWItPlB0LlggPiBvcDEtPlB0Llg7CiAgICB9IAogICAgZWxzZQogICAgewogICAgICBQdCA9IG9wMmItPlB0OyBEaXNjYXJkTGVmdFNpZGUgPSAob3AyYi0+UHQuWCA+IG9wMi0+UHQuWCk7CiAgICB9CiAgICBqLT5PdXRQdDEgPSBvcDE7IGotPk91dFB0MiA9IG9wMjsKICAgIHJldHVybiBKb2luSG9yeihvcDEsIG9wMWIsIG9wMiwgb3AyYiwgUHQsIERpc2NhcmRMZWZ0U2lkZSk7CiAgfSBlbHNlCiAgewogICAgLy9uYjogRm9yIG5vbi1ob3Jpem9udGFsIGpvaW5zIC4uLgogICAgLy8gICAgMS4gSnIuT3V0UHQxLlB0LlkgPT0gSnIuT3V0UHQyLlB0LlkKICAgIC8vICAgIDIuIEpyLk91dFB0MS5QdCA+IEpyLk9mZlB0LlkKCiAgICAvL21ha2Ugc3VyZSB0aGUgcG9seWdvbnMgYXJlIGNvcnJlY3RseSBvcmllbnRlZCAuLi4KICAgIG9wMWIgPSBvcDEtPk5leHQ7CiAgICB3aGlsZSAoKG9wMWItPlB0ID09IG9wMS0+UHQpICYmIChvcDFiICE9IG9wMSkpIG9wMWIgPSBvcDFiLT5OZXh0OwogICAgYm9vbCBSZXZlcnNlMSA9ICgob3AxYi0+UHQuWSA+IG9wMS0+UHQuWSkgfHwKICAgICAgIVNsb3Blc0VxdWFsKG9wMS0+UHQsIG9wMWItPlB0LCBqLT5PZmZQdCwgbV9Vc2VGdWxsUmFuZ2UpKTsKICAgIGlmIChSZXZlcnNlMSkKICAgIHsKICAgICAgb3AxYiA9IG9wMS0+UHJldjsKICAgICAgd2hpbGUgKChvcDFiLT5QdCA9PSBvcDEtPlB0KSAmJiAob3AxYiAhPSBvcDEpKSBvcDFiID0gb3AxYi0+UHJldjsKICAgICAgaWYgKChvcDFiLT5QdC5ZID4gb3AxLT5QdC5ZKSB8fAogICAgICAgICFTbG9wZXNFcXVhbChvcDEtPlB0LCBvcDFiLT5QdCwgai0+T2ZmUHQsIG1fVXNlRnVsbFJhbmdlKSkgcmV0dXJuIGZhbHNlOwogICAgfTsKICAgIG9wMmIgPSBvcDItPk5leHQ7CiAgICB3aGlsZSAoKG9wMmItPlB0ID09IG9wMi0+UHQpICYmIChvcDJiICE9IG9wMikpb3AyYiA9IG9wMmItPk5leHQ7CiAgICBib29sIFJldmVyc2UyID0gKChvcDJiLT5QdC5ZID4gb3AyLT5QdC5ZKSB8fAogICAgICAhU2xvcGVzRXF1YWwob3AyLT5QdCwgb3AyYi0+UHQsIGotPk9mZlB0LCBtX1VzZUZ1bGxSYW5nZSkpOwogICAgaWYgKFJldmVyc2UyKQogICAgewogICAgICBvcDJiID0gb3AyLT5QcmV2OwogICAgICB3aGlsZSAoKG9wMmItPlB0ID09IG9wMi0+UHQpICYmIChvcDJiICE9IG9wMikpIG9wMmIgPSBvcDJiLT5QcmV2OwogICAgICBpZiAoKG9wMmItPlB0LlkgPiBvcDItPlB0LlkpIHx8CiAgICAgICAgIVNsb3Blc0VxdWFsKG9wMi0+UHQsIG9wMmItPlB0LCBqLT5PZmZQdCwgbV9Vc2VGdWxsUmFuZ2UpKSByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgaWYgKChvcDFiID09IG9wMSkgfHwgKG9wMmIgPT0gb3AyKSB8fCAob3AxYiA9PSBvcDJiKSB8fAogICAgICAoKG91dFJlYzEgPT0gb3V0UmVjMikgJiYgKFJldmVyc2UxID09IFJldmVyc2UyKSkpIHJldHVybiBmYWxzZTsKCiAgICBpZiAoUmV2ZXJzZTEpCiAgICB7CiAgICAgIG9wMWIgPSBEdXBPdXRQdChvcDEsIGZhbHNlKTsKICAgICAgb3AyYiA9IER1cE91dFB0KG9wMiwgdHJ1ZSk7CiAgICAgIG9wMS0+UHJldiA9IG9wMjsKICAgICAgb3AyLT5OZXh0ID0gb3AxOwogICAgICBvcDFiLT5OZXh0ID0gb3AyYjsKICAgICAgb3AyYi0+UHJldiA9IG9wMWI7CiAgICAgIGotPk91dFB0MSA9IG9wMTsKICAgICAgai0+T3V0UHQyID0gb3AxYjsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9IGVsc2UKICAgIHsKICAgICAgb3AxYiA9IER1cE91dFB0KG9wMSwgdHJ1ZSk7CiAgICAgIG9wMmIgPSBEdXBPdXRQdChvcDIsIGZhbHNlKTsKICAgICAgb3AxLT5OZXh0ID0gb3AyOwogICAgICBvcDItPlByZXYgPSBvcDE7CiAgICAgIG9wMWItPlByZXYgPSBvcDJiOwogICAgICBvcDJiLT5OZXh0ID0gb3AxYjsKICAgICAgai0+T3V0UHQxID0gb3AxOwogICAgICBqLT5PdXRQdDIgPSBvcDFiOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgT3V0UmVjKiBQYXJzZUZpcnN0TGVmdChPdXRSZWMqIEZpcnN0TGVmdCkKewogIHdoaWxlIChGaXJzdExlZnQgJiYgIUZpcnN0TGVmdC0+UHRzKQogICAgRmlyc3RMZWZ0ID0gRmlyc3RMZWZ0LT5GaXJzdExlZnQ7CiAgcmV0dXJuIEZpcnN0TGVmdDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBDbGlwcGVyOjpGaXh1cEZpcnN0TGVmdHMxKE91dFJlYyogT2xkT3V0UmVjLCBPdXRSZWMqIE5ld091dFJlYykKeyAKICAvL3Rlc3RzIGlmIE5ld091dFJlYyBjb250YWlucyB0aGUgcG9seWdvbiBiZWZvcmUgcmVhc3NpZ25pbmcgRmlyc3RMZWZ0CiAgZm9yIChQb2x5T3V0TGlzdDo6c2l6ZV90eXBlIGkgPSAwOyBpIDwgbV9Qb2x5T3V0cy5zaXplKCk7ICsraSkKICB7CiAgICBPdXRSZWMqIG91dFJlYyA9IG1fUG9seU91dHNbaV07CiAgICBPdXRSZWMqIGZpcnN0TGVmdCA9IFBhcnNlRmlyc3RMZWZ0KG91dFJlYy0+Rmlyc3RMZWZ0KTsKICAgIGlmIChvdXRSZWMtPlB0cyAgJiYgZmlyc3RMZWZ0ID09IE9sZE91dFJlYykKICAgIHsKICAgICAgaWYgKFBvbHkyQ29udGFpbnNQb2x5MShvdXRSZWMtPlB0cywgTmV3T3V0UmVjLT5QdHMpKQogICAgICAgIG91dFJlYy0+Rmlyc3RMZWZ0ID0gTmV3T3V0UmVjOwogICAgfQogIH0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6Rml4dXBGaXJzdExlZnRzMihPdXRSZWMqIElubmVyT3V0UmVjLCBPdXRSZWMqIE91dGVyT3V0UmVjKQp7CiAgLy9BIHBvbHlnb24gaGFzIHNwbGl0IGludG8gdHdvIHN1Y2ggdGhhdCBvbmUgaXMgbm93IHRoZSBpbm5lciBvZiB0aGUgb3RoZXIuCiAgLy9JdCdzIHBvc3NpYmxlIHRoYXQgdGhlc2UgcG9seWdvbnMgbm93IHdyYXAgYXJvdW5kIG90aGVyIHBvbHlnb25zLCBzbyBjaGVjawogIC8vZXZlcnkgcG9seWdvbiB0aGF0J3MgYWxzbyBjb250YWluZWQgYnkgT3V0ZXJPdXRSZWMncyBGaXJzdExlZnQgY29udGFpbmVyCiAgLy8oaW5jbHVkaW5nIDApIHRvIHNlZSBpZiB0aGV5J3ZlIGJlY29tZSBpbm5lciB0byB0aGUgbmV3IGlubmVyIHBvbHlnb24gLi4uCiAgT3V0UmVjKiBvcmZsID0gT3V0ZXJPdXRSZWMtPkZpcnN0TGVmdDsKICBmb3IgKFBvbHlPdXRMaXN0OjpzaXplX3R5cGUgaSA9IDA7IGkgPCBtX1BvbHlPdXRzLnNpemUoKTsgKytpKQogIHsKICAgIE91dFJlYyogb3V0UmVjID0gbV9Qb2x5T3V0c1tpXTsKCiAgICBpZiAoIW91dFJlYy0+UHRzIHx8IG91dFJlYyA9PSBPdXRlck91dFJlYyB8fCBvdXRSZWMgPT0gSW5uZXJPdXRSZWMpCiAgICAgIGNvbnRpbnVlOwogICAgT3V0UmVjKiBmaXJzdExlZnQgPSBQYXJzZUZpcnN0TGVmdChvdXRSZWMtPkZpcnN0TGVmdCk7CiAgICBpZiAoZmlyc3RMZWZ0ICE9IG9yZmwgJiYgZmlyc3RMZWZ0ICE9IElubmVyT3V0UmVjICYmIGZpcnN0TGVmdCAhPSBPdXRlck91dFJlYykKICAgICAgY29udGludWU7CiAgICBpZiAoUG9seTJDb250YWluc1BvbHkxKG91dFJlYy0+UHRzLCBJbm5lck91dFJlYy0+UHRzKSkKICAgICAgb3V0UmVjLT5GaXJzdExlZnQgPSBJbm5lck91dFJlYzsKICAgIGVsc2UgaWYgKFBvbHkyQ29udGFpbnNQb2x5MShvdXRSZWMtPlB0cywgT3V0ZXJPdXRSZWMtPlB0cykpCiAgICAgIG91dFJlYy0+Rmlyc3RMZWZ0ID0gT3V0ZXJPdXRSZWM7CiAgICBlbHNlIGlmIChvdXRSZWMtPkZpcnN0TGVmdCA9PSBJbm5lck91dFJlYyB8fCBvdXRSZWMtPkZpcnN0TGVmdCA9PSBPdXRlck91dFJlYykKICAgICAgb3V0UmVjLT5GaXJzdExlZnQgPSBvcmZsOwogIH0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBDbGlwcGVyOjpGaXh1cEZpcnN0TGVmdHMzKE91dFJlYyogT2xkT3V0UmVjLCBPdXRSZWMqIE5ld091dFJlYykKewogIC8vcmVhc3NpZ25zIEZpcnN0TGVmdCBXSVRIT1VUIHRlc3RpbmcgaWYgTmV3T3V0UmVjIGNvbnRhaW5zIHRoZSBwb2x5Z29uCiAgZm9yIChQb2x5T3V0TGlzdDo6c2l6ZV90eXBlIGkgPSAwOyBpIDwgbV9Qb2x5T3V0cy5zaXplKCk7ICsraSkKICB7CiAgICBPdXRSZWMqIG91dFJlYyA9IG1fUG9seU91dHNbaV07CiAgICBPdXRSZWMqIGZpcnN0TGVmdCA9IFBhcnNlRmlyc3RMZWZ0KG91dFJlYy0+Rmlyc3RMZWZ0KTsKICAgIGlmIChvdXRSZWMtPlB0cyAmJiBvdXRSZWMtPkZpcnN0TGVmdCA9PSBPbGRPdXRSZWMpCiAgICAgIG91dFJlYy0+Rmlyc3RMZWZ0ID0gTmV3T3V0UmVjOwogIH0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6Sm9pbkNvbW1vbkVkZ2VzKCkKewogIGZvciAoSm9pbkxpc3Q6OnNpemVfdHlwZSBpID0gMDsgaSA8IG1fSm9pbnMuc2l6ZSgpOyBpKyspCiAgewogICAgSm9pbiogam9pbiA9IG1fSm9pbnNbaV07CgogICAgT3V0UmVjICpvdXRSZWMxID0gR2V0T3V0UmVjKGpvaW4tPk91dFB0MS0+SWR4KTsKICAgIE91dFJlYyAqb3V0UmVjMiA9IEdldE91dFJlYyhqb2luLT5PdXRQdDItPklkeCk7CgogICAgaWYgKCFvdXRSZWMxLT5QdHMgfHwgIW91dFJlYzItPlB0cykgY29udGludWU7CiAgICBpZiAob3V0UmVjMS0+SXNPcGVuIHx8IG91dFJlYzItPklzT3BlbikgY29udGludWU7CgogICAgLy9nZXQgdGhlIHBvbHlnb24gZnJhZ21lbnQgd2l0aCB0aGUgY29ycmVjdCBob2xlIHN0YXRlIChGaXJzdExlZnQpCiAgICAvL2JlZm9yZSBjYWxsaW5nIEpvaW5Qb2ludHMoKSAuLi4KICAgIE91dFJlYyAqaG9sZVN0YXRlUmVjOwogICAgaWYgKG91dFJlYzEgPT0gb3V0UmVjMikgaG9sZVN0YXRlUmVjID0gb3V0UmVjMTsKICAgIGVsc2UgaWYgKE91dFJlYzFSaWdodE9mT3V0UmVjMihvdXRSZWMxLCBvdXRSZWMyKSkgaG9sZVN0YXRlUmVjID0gb3V0UmVjMjsKICAgIGVsc2UgaWYgKE91dFJlYzFSaWdodE9mT3V0UmVjMihvdXRSZWMyLCBvdXRSZWMxKSkgaG9sZVN0YXRlUmVjID0gb3V0UmVjMTsKICAgIGVsc2UgaG9sZVN0YXRlUmVjID0gR2V0TG93ZXJtb3N0UmVjKG91dFJlYzEsIG91dFJlYzIpOwoKICAgIGlmICghSm9pblBvaW50cyhqb2luLCBvdXRSZWMxLCBvdXRSZWMyKSkgY29udGludWU7CgogICAgaWYgKG91dFJlYzEgPT0gb3V0UmVjMikKICAgIHsKICAgICAgLy9pbnN0ZWFkIG9mIGpvaW5pbmcgdHdvIHBvbHlnb25zLCB3ZSd2ZSBqdXN0IGNyZWF0ZWQgYSBuZXcgb25lIGJ5CiAgICAgIC8vc3BsaXR0aW5nIG9uZSBwb2x5Z29uIGludG8gdHdvLgogICAgICBvdXRSZWMxLT5QdHMgPSBqb2luLT5PdXRQdDE7CiAgICAgIG91dFJlYzEtPkJvdHRvbVB0ID0gMDsKICAgICAgb3V0UmVjMiA9IENyZWF0ZU91dFJlYygpOwogICAgICBvdXRSZWMyLT5QdHMgPSBqb2luLT5PdXRQdDI7CgogICAgICAvL3VwZGF0ZSBhbGwgT3V0UmVjMi5QdHMgSWR4J3MgLi4uCiAgICAgIFVwZGF0ZU91dFB0SWR4cygqb3V0UmVjMik7CgogICAgICBpZiAoUG9seTJDb250YWluc1BvbHkxKG91dFJlYzItPlB0cywgb3V0UmVjMS0+UHRzKSkKICAgICAgewogICAgICAgIC8vb3V0UmVjMSBjb250YWlucyBvdXRSZWMyIC4uLgogICAgICAgIG91dFJlYzItPklzSG9sZSA9ICFvdXRSZWMxLT5Jc0hvbGU7CiAgICAgICAgb3V0UmVjMi0+Rmlyc3RMZWZ0ID0gb3V0UmVjMTsKCiAgICAgICAgaWYgKG1fVXNpbmdQb2x5VHJlZSkgRml4dXBGaXJzdExlZnRzMihvdXRSZWMyLCBvdXRSZWMxKTsKCiAgICAgICAgaWYgKChvdXRSZWMyLT5Jc0hvbGUgXiBtX1JldmVyc2VPdXRwdXQpID09IChBcmVhKCpvdXRSZWMyKSA+IDApKQogICAgICAgICAgUmV2ZXJzZVBvbHlQdExpbmtzKG91dFJlYzItPlB0cyk7CiAgICAgICAgICAgIAogICAgICB9IGVsc2UgaWYgKFBvbHkyQ29udGFpbnNQb2x5MShvdXRSZWMxLT5QdHMsIG91dFJlYzItPlB0cykpCiAgICAgIHsKICAgICAgICAvL291dFJlYzIgY29udGFpbnMgb3V0UmVjMSAuLi4KICAgICAgICBvdXRSZWMyLT5Jc0hvbGUgPSBvdXRSZWMxLT5Jc0hvbGU7CiAgICAgICAgb3V0UmVjMS0+SXNIb2xlID0gIW91dFJlYzItPklzSG9sZTsKICAgICAgICBvdXRSZWMyLT5GaXJzdExlZnQgPSBvdXRSZWMxLT5GaXJzdExlZnQ7CiAgICAgICAgb3V0UmVjMS0+Rmlyc3RMZWZ0ID0gb3V0UmVjMjsKCiAgICAgICAgaWYgKG1fVXNpbmdQb2x5VHJlZSkgRml4dXBGaXJzdExlZnRzMihvdXRSZWMxLCBvdXRSZWMyKTsKCiAgICAgICAgaWYgKChvdXRSZWMxLT5Jc0hvbGUgXiBtX1JldmVyc2VPdXRwdXQpID09IChBcmVhKCpvdXRSZWMxKSA+IDApKQogICAgICAgICAgUmV2ZXJzZVBvbHlQdExpbmtzKG91dFJlYzEtPlB0cyk7CiAgICAgIH0gCiAgICAgIGVsc2UKICAgICAgewogICAgICAgIC8vdGhlIDIgcG9seWdvbnMgYXJlIGNvbXBsZXRlbHkgc2VwYXJhdGUgLi4uCiAgICAgICAgb3V0UmVjMi0+SXNIb2xlID0gb3V0UmVjMS0+SXNIb2xlOwogICAgICAgIG91dFJlYzItPkZpcnN0TGVmdCA9IG91dFJlYzEtPkZpcnN0TGVmdDsKCiAgICAgICAgLy9maXh1cCBGaXJzdExlZnQgcG9pbnRlcnMgdGhhdCBtYXkgbmVlZCByZWFzc2lnbmluZyB0byBPdXRSZWMyCiAgICAgICAgaWYgKG1fVXNpbmdQb2x5VHJlZSkgRml4dXBGaXJzdExlZnRzMShvdXRSZWMxLCBvdXRSZWMyKTsKICAgICAgfQogICAgIAogICAgfSBlbHNlCiAgICB7CiAgICAgIC8vam9pbmVkIDIgcG9seWdvbnMgdG9nZXRoZXIgLi4uCgogICAgICBvdXRSZWMyLT5QdHMgPSAwOwogICAgICBvdXRSZWMyLT5Cb3R0b21QdCA9IDA7CiAgICAgIG91dFJlYzItPklkeCA9IG91dFJlYzEtPklkeDsKCiAgICAgIG91dFJlYzEtPklzSG9sZSA9IGhvbGVTdGF0ZVJlYy0+SXNIb2xlOwogICAgICBpZiAoaG9sZVN0YXRlUmVjID09IG91dFJlYzIpIAogICAgICAgIG91dFJlYzEtPkZpcnN0TGVmdCA9IG91dFJlYzItPkZpcnN0TGVmdDsKICAgICAgb3V0UmVjMi0+Rmlyc3RMZWZ0ID0gb3V0UmVjMTsKCiAgICAgIGlmIChtX1VzaW5nUG9seVRyZWUpIEZpeHVwRmlyc3RMZWZ0czMob3V0UmVjMiwgb3V0UmVjMSk7CiAgICB9CiAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBDbGlwcGVyT2Zmc2V0IHN1cHBvcnQgZnVuY3Rpb25zIC4uLgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKRG91YmxlUG9pbnQgR2V0VW5pdE5vcm1hbChjb25zdCBJbnRQb2ludCAmcHQxLCBjb25zdCBJbnRQb2ludCAmcHQyKQp7CiAgaWYocHQyLlggPT0gcHQxLlggJiYgcHQyLlkgPT0gcHQxLlkpIAogICAgcmV0dXJuIERvdWJsZVBvaW50KDAsIDApOwoKICBkb3VibGUgRHggPSAoZG91YmxlKShwdDIuWCAtIHB0MS5YKTsKICBkb3VibGUgZHkgPSAoZG91YmxlKShwdDIuWSAtIHB0MS5ZKTsKICBkb3VibGUgZiA9IDEgKjEuMC8gc3RkOjpzcXJ0KCBEeCpEeCArIGR5KmR5ICk7CiAgRHggKj0gZjsKICBkeSAqPSBmOwogIHJldHVybiBEb3VibGVQb2ludChkeSwgLUR4KTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gQ2xpcHBlck9mZnNldCBjbGFzcwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKQ2xpcHBlck9mZnNldDo6Q2xpcHBlck9mZnNldChkb3VibGUgbWl0ZXJMaW1pdCwgZG91YmxlIGFyY1RvbGVyYW5jZSkKewogIHRoaXMtPk1pdGVyTGltaXQgPSBtaXRlckxpbWl0OwogIHRoaXMtPkFyY1RvbGVyYW5jZSA9IGFyY1RvbGVyYW5jZTsKICBtX2xvd2VzdC5YID0gLTE7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkNsaXBwZXJPZmZzZXQ6On5DbGlwcGVyT2Zmc2V0KCkKewogIENsZWFyKCk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlck9mZnNldDo6Q2xlYXIoKQp7CiAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX3BvbHlOb2Rlcy5DaGlsZENvdW50KCk7ICsraSkKICAgIGRlbGV0ZSBtX3BvbHlOb2Rlcy5DaGlsZHNbaV07CiAgbV9wb2x5Tm9kZXMuQ2hpbGRzLmNsZWFyKCk7CiAgbV9sb3dlc3QuWCA9IC0xOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXJPZmZzZXQ6OkFkZFBhdGgoY29uc3QgUGF0aCYgcGF0aCwgSm9pblR5cGUgam9pblR5cGUsIEVuZFR5cGUgZW5kVHlwZSkKewogIGludCBoaWdoSSA9IChpbnQpcGF0aC5zaXplKCkgLSAxOwogIGlmIChoaWdoSSA8IDApIHJldHVybjsKICBQb2x5Tm9kZSogbmV3Tm9kZSA9IG5ldyBQb2x5Tm9kZSgpOwogIG5ld05vZGUtPm1fam9pbnR5cGUgPSBqb2luVHlwZTsKICBuZXdOb2RlLT5tX2VuZHR5cGUgPSBlbmRUeXBlOwoKICAvL3N0cmlwIGR1cGxpY2F0ZSBwb2ludHMgZnJvbSBwYXRoIGFuZCBhbHNvIGdldCBpbmRleCB0byB0aGUgbG93ZXN0IHBvaW50IC4uLgogIGlmIChlbmRUeXBlID09IGV0Q2xvc2VkTGluZSB8fCBlbmRUeXBlID09IGV0Q2xvc2VkUG9seWdvbikKICAgIHdoaWxlIChoaWdoSSA+IDAgJiYgcGF0aFswXSA9PSBwYXRoW2hpZ2hJXSkgaGlnaEktLTsKICBuZXdOb2RlLT5Db250b3VyLnJlc2VydmUoaGlnaEkgKyAxKTsKICBuZXdOb2RlLT5Db250b3VyLnB1c2hfYmFjayhwYXRoWzBdKTsKICBpbnQgaiA9IDAsIGsgPSAwOwogIGZvciAoaW50IGkgPSAxOyBpIDw9IGhpZ2hJOyBpKyspCiAgICBpZiAobmV3Tm9kZS0+Q29udG91cltqXSAhPSBwYXRoW2ldKQogICAgewogICAgICBqKys7CiAgICAgIG5ld05vZGUtPkNvbnRvdXIucHVzaF9iYWNrKHBhdGhbaV0pOwogICAgICBpZiAocGF0aFtpXS5ZID4gbmV3Tm9kZS0+Q29udG91cltrXS5ZIHx8CiAgICAgICAgKHBhdGhbaV0uWSA9PSBuZXdOb2RlLT5Db250b3VyW2tdLlkgJiYKICAgICAgICBwYXRoW2ldLlggPCBuZXdOb2RlLT5Db250b3VyW2tdLlgpKSBrID0gajsKICAgIH0KICBpZiAoZW5kVHlwZSA9PSBldENsb3NlZFBvbHlnb24gJiYgaiA8IDIpCiAgewogICAgZGVsZXRlIG5ld05vZGU7CiAgICByZXR1cm47CiAgfQogIG1fcG9seU5vZGVzLkFkZENoaWxkKCpuZXdOb2RlKTsKCiAgLy9pZiB0aGlzIHBhdGgncyBsb3dlc3QgcHQgaXMgbG93ZXIgdGhhbiBhbGwgdGhlIG90aGVycyB0aGVuIHVwZGF0ZSBtX2xvd2VzdAogIGlmIChlbmRUeXBlICE9IGV0Q2xvc2VkUG9seWdvbikgcmV0dXJuOwogIGlmIChtX2xvd2VzdC5YIDwgMCkKICAgIG1fbG93ZXN0ID0gSW50UG9pbnQobV9wb2x5Tm9kZXMuQ2hpbGRDb3VudCgpIC0gMSwgayk7CiAgZWxzZQogIHsKICAgIEludFBvaW50IGlwID0gbV9wb2x5Tm9kZXMuQ2hpbGRzWyhpbnQpbV9sb3dlc3QuWF0tPkNvbnRvdXJbKGludCltX2xvd2VzdC5ZXTsKICAgIGlmIChuZXdOb2RlLT5Db250b3VyW2tdLlkgPiBpcC5ZIHx8CiAgICAgIChuZXdOb2RlLT5Db250b3VyW2tdLlkgPT0gaXAuWSAmJgogICAgICBuZXdOb2RlLT5Db250b3VyW2tdLlggPCBpcC5YKSkKICAgICAgbV9sb3dlc3QgPSBJbnRQb2ludChtX3BvbHlOb2Rlcy5DaGlsZENvdW50KCkgLSAxLCBrKTsKICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlck9mZnNldDo6QWRkUGF0aHMoY29uc3QgUGF0aHMmIHBhdGhzLCBKb2luVHlwZSBqb2luVHlwZSwgRW5kVHlwZSBlbmRUeXBlKQp7CiAgZm9yIChQYXRoczo6c2l6ZV90eXBlIGkgPSAwOyBpIDwgcGF0aHMuc2l6ZSgpOyArK2kpCiAgICBBZGRQYXRoKHBhdGhzW2ldLCBqb2luVHlwZSwgZW5kVHlwZSk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlck9mZnNldDo6Rml4T3JpZW50YXRpb25zKCkKewogIC8vZml4dXAgb3JpZW50YXRpb25zIG9mIGFsbCBjbG9zZWQgcGF0aHMgaWYgdGhlIG9yaWVudGF0aW9uIG9mIHRoZQogIC8vY2xvc2VkIHBhdGggd2l0aCB0aGUgbG93ZXJtb3N0IHZlcnRleCBpcyB3cm9uZyAuLi4KICBpZiAobV9sb3dlc3QuWCA+PSAwICYmIAogICAgIU9yaWVudGF0aW9uKG1fcG9seU5vZGVzLkNoaWxkc1soaW50KW1fbG93ZXN0LlhdLT5Db250b3VyKSkKICB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fcG9seU5vZGVzLkNoaWxkQ291bnQoKTsgKytpKQogICAgewogICAgICBQb2x5Tm9kZSYgbm9kZSA9ICptX3BvbHlOb2Rlcy5DaGlsZHNbaV07CiAgICAgIGlmIChub2RlLm1fZW5kdHlwZSA9PSBldENsb3NlZFBvbHlnb24gfHwKICAgICAgICAobm9kZS5tX2VuZHR5cGUgPT0gZXRDbG9zZWRMaW5lICYmIE9yaWVudGF0aW9uKG5vZGUuQ29udG91cikpKQogICAgICAgICAgUmV2ZXJzZVBhdGgobm9kZS5Db250b3VyKTsKICAgIH0KICB9IGVsc2UKICB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fcG9seU5vZGVzLkNoaWxkQ291bnQoKTsgKytpKQogICAgewogICAgICBQb2x5Tm9kZSYgbm9kZSA9ICptX3BvbHlOb2Rlcy5DaGlsZHNbaV07CiAgICAgIGlmIChub2RlLm1fZW5kdHlwZSA9PSBldENsb3NlZExpbmUgJiYgIU9yaWVudGF0aW9uKG5vZGUuQ29udG91cikpCiAgICAgICAgUmV2ZXJzZVBhdGgobm9kZS5Db250b3VyKTsKICAgIH0KICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlck9mZnNldDo6RXhlY3V0ZShQYXRocyYgc29sdXRpb24sIGRvdWJsZSBkZWx0YSkKewogIHNvbHV0aW9uLmNsZWFyKCk7CiAgRml4T3JpZW50YXRpb25zKCk7CiAgRG9PZmZzZXQoZGVsdGEpOwogIAogIC8vbm93IGNsZWFuIHVwICdjb3JuZXJzJyAuLi4KICBDbGlwcGVyIGNscHI7CiAgY2xwci5BZGRQYXRocyhtX2Rlc3RQb2x5cywgcHRTdWJqZWN0LCB0cnVlKTsKICBpZiAoZGVsdGEgPiAwKQogIHsKICAgIGNscHIuRXhlY3V0ZShjdFVuaW9uLCBzb2x1dGlvbiwgcGZ0UG9zaXRpdmUsIHBmdFBvc2l0aXZlKTsKICB9CiAgZWxzZQogIHsKICAgIEludFJlY3QgciA9IGNscHIuR2V0Qm91bmRzKCk7CiAgICBQYXRoIG91dGVyKDQpOwogICAgb3V0ZXJbMF0gPSBJbnRQb2ludChyLmxlZnQgLSAxMCwgci5ib3R0b20gKyAxMCk7CiAgICBvdXRlclsxXSA9IEludFBvaW50KHIucmlnaHQgKyAxMCwgci5ib3R0b20gKyAxMCk7CiAgICBvdXRlclsyXSA9IEludFBvaW50KHIucmlnaHQgKyAxMCwgci50b3AgLSAxMCk7CiAgICBvdXRlclszXSA9IEludFBvaW50KHIubGVmdCAtIDEwLCByLnRvcCAtIDEwKTsKCiAgICBjbHByLkFkZFBhdGgob3V0ZXIsIHB0U3ViamVjdCwgdHJ1ZSk7CiAgICBjbHByLlJldmVyc2VTb2x1dGlvbih0cnVlKTsKICAgIGNscHIuRXhlY3V0ZShjdFVuaW9uLCBzb2x1dGlvbiwgcGZ0TmVnYXRpdmUsIHBmdE5lZ2F0aXZlKTsKICAgIGlmIChzb2x1dGlvbi5zaXplKCkgPiAwKSBzb2x1dGlvbi5lcmFzZShzb2x1dGlvbi5iZWdpbigpKTsKICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlck9mZnNldDo6RXhlY3V0ZShQb2x5VHJlZSYgc29sdXRpb24sIGRvdWJsZSBkZWx0YSkKewogIHNvbHV0aW9uLkNsZWFyKCk7CiAgRml4T3JpZW50YXRpb25zKCk7CiAgRG9PZmZzZXQoZGVsdGEpOwoKICAvL25vdyBjbGVhbiB1cCAnY29ybmVycycgLi4uCiAgQ2xpcHBlciBjbHByOwogIGNscHIuQWRkUGF0aHMobV9kZXN0UG9seXMsIHB0U3ViamVjdCwgdHJ1ZSk7CiAgaWYgKGRlbHRhID4gMCkKICB7CiAgICBjbHByLkV4ZWN1dGUoY3RVbmlvbiwgc29sdXRpb24sIHBmdFBvc2l0aXZlLCBwZnRQb3NpdGl2ZSk7CiAgfQogIGVsc2UKICB7CiAgICBJbnRSZWN0IHIgPSBjbHByLkdldEJvdW5kcygpOwogICAgUGF0aCBvdXRlcig0KTsKICAgIG91dGVyWzBdID0gSW50UG9pbnQoci5sZWZ0IC0gMTAsIHIuYm90dG9tICsgMTApOwogICAgb3V0ZXJbMV0gPSBJbnRQb2ludChyLnJpZ2h0ICsgMTAsIHIuYm90dG9tICsgMTApOwogICAgb3V0ZXJbMl0gPSBJbnRQb2ludChyLnJpZ2h0ICsgMTAsIHIudG9wIC0gMTApOwogICAgb3V0ZXJbM10gPSBJbnRQb2ludChyLmxlZnQgLSAxMCwgci50b3AgLSAxMCk7CgogICAgY2xwci5BZGRQYXRoKG91dGVyLCBwdFN1YmplY3QsIHRydWUpOwogICAgY2xwci5SZXZlcnNlU29sdXRpb24odHJ1ZSk7CiAgICBjbHByLkV4ZWN1dGUoY3RVbmlvbiwgc29sdXRpb24sIHBmdE5lZ2F0aXZlLCBwZnROZWdhdGl2ZSk7CiAgICAvL3JlbW92ZSB0aGUgb3V0ZXIgUG9seU5vZGUgcmVjdGFuZ2xlIC4uLgogICAgaWYgKHNvbHV0aW9uLkNoaWxkQ291bnQoKSA9PSAxICYmIHNvbHV0aW9uLkNoaWxkc1swXS0+Q2hpbGRDb3VudCgpID4gMCkKICAgIHsKICAgICAgUG9seU5vZGUqIG91dGVyTm9kZSA9IHNvbHV0aW9uLkNoaWxkc1swXTsKICAgICAgc29sdXRpb24uQ2hpbGRzLnJlc2VydmUob3V0ZXJOb2RlLT5DaGlsZENvdW50KCkpOwogICAgICBzb2x1dGlvbi5DaGlsZHNbMF0gPSBvdXRlck5vZGUtPkNoaWxkc1swXTsKICAgICAgc29sdXRpb24uQ2hpbGRzWzBdLT5QYXJlbnQgPSBvdXRlck5vZGUtPlBhcmVudDsKICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBvdXRlck5vZGUtPkNoaWxkQ291bnQoKTsgKytpKQogICAgICAgIHNvbHV0aW9uLkFkZENoaWxkKCpvdXRlck5vZGUtPkNoaWxkc1tpXSk7CiAgICB9CiAgICBlbHNlCiAgICAgIHNvbHV0aW9uLkNsZWFyKCk7CiAgfQp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIENsaXBwZXJPZmZzZXQ6OkRvT2Zmc2V0KGRvdWJsZSBkZWx0YSkKewogIG1fZGVzdFBvbHlzLmNsZWFyKCk7CiAgbV9kZWx0YSA9IGRlbHRhOwoKICAvL2lmIFplcm8gb2Zmc2V0LCBqdXN0IGNvcHkgYW55IENMT1NFRCBwb2x5Z29ucyB0byBtX3AgYW5kIHJldHVybiAuLi4KICBpZiAoTkVBUl9aRVJPKGRlbHRhKSkgCiAgewogICAgbV9kZXN0UG9seXMucmVzZXJ2ZShtX3BvbHlOb2Rlcy5DaGlsZENvdW50KCkpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX3BvbHlOb2Rlcy5DaGlsZENvdW50KCk7IGkrKykKICAgIHsKICAgICAgUG9seU5vZGUmIG5vZGUgPSAqbV9wb2x5Tm9kZXMuQ2hpbGRzW2ldOwogICAgICBpZiAobm9kZS5tX2VuZHR5cGUgPT0gZXRDbG9zZWRQb2x5Z29uKQogICAgICAgIG1fZGVzdFBvbHlzLnB1c2hfYmFjayhub2RlLkNvbnRvdXIpOwogICAgfQogICAgcmV0dXJuOwogIH0KCiAgLy9zZWUgb2Zmc2V0X3RyaWdpbm9tZXRyeTMuc3ZnIGluIHRoZSBkb2N1bWVudGF0aW9uIGZvbGRlciAuLi4KICBpZiAoTWl0ZXJMaW1pdCA+IDIpIG1fbWl0ZXJMaW0gPSAyLyhNaXRlckxpbWl0ICogTWl0ZXJMaW1pdCk7CiAgZWxzZSBtX21pdGVyTGltID0gMC41OwoKICBkb3VibGUgeTsKICBpZiAoQXJjVG9sZXJhbmNlIDw9IDAuMCkgeSA9IGRlZl9hcmNfdG9sZXJhbmNlOwogIGVsc2UgaWYgKEFyY1RvbGVyYW5jZSA+IHN0ZDo6ZmFicyhkZWx0YSkgKiBkZWZfYXJjX3RvbGVyYW5jZSkgCiAgICB5ID0gc3RkOjpmYWJzKGRlbHRhKSAqIGRlZl9hcmNfdG9sZXJhbmNlOwogIGVsc2UgeSA9IEFyY1RvbGVyYW5jZTsKICAvL3NlZSBvZmZzZXRfdHJpZ2lub21ldHJ5Mi5zdmcgaW4gdGhlIGRvY3VtZW50YXRpb24gZm9sZGVyIC4uLgogIGRvdWJsZSBzdGVwcyA9IHBpIC8gc3RkOjphY29zKDEgLSB5IC8gc3RkOjpmYWJzKGRlbHRhKSk7CiAgaWYgKHN0ZXBzID4gc3RkOjpmYWJzKGRlbHRhKSAqIHBpKSAKICAgIHN0ZXBzID0gc3RkOjpmYWJzKGRlbHRhKSAqIHBpOyAgLy9pZSBleGNlc3NpdmUgcHJlY2lzaW9uIGNoZWNrCiAgbV9zaW4gPSBzdGQ6OnNpbih0d29fcGkgLyBzdGVwcyk7CiAgbV9jb3MgPSBzdGQ6OmNvcyh0d29fcGkgLyBzdGVwcyk7CiAgbV9TdGVwc1BlclJhZCA9IHN0ZXBzIC8gdHdvX3BpOwogIGlmIChkZWx0YSA8IDAuMCkgbV9zaW4gPSAtbV9zaW47CgogIG1fZGVzdFBvbHlzLnJlc2VydmUobV9wb2x5Tm9kZXMuQ2hpbGRDb3VudCgpICogMik7CiAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX3BvbHlOb2Rlcy5DaGlsZENvdW50KCk7IGkrKykKICB7CiAgICBQb2x5Tm9kZSYgbm9kZSA9ICptX3BvbHlOb2Rlcy5DaGlsZHNbaV07CiAgICBtX3NyY1BvbHkgPSBub2RlLkNvbnRvdXI7CgogICAgaW50IGxlbiA9IChpbnQpbV9zcmNQb2x5LnNpemUoKTsKICAgIGlmIChsZW4gPT0gMCB8fCAoZGVsdGEgPD0gMCAmJiAobGVuIDwgMyB8fCBub2RlLm1fZW5kdHlwZSAhPSBldENsb3NlZFBvbHlnb24pKSkKICAgICAgICBjb250aW51ZTsKCiAgICBtX2Rlc3RQb2x5LmNsZWFyKCk7CiAgICBpZiAobGVuID09IDEpCiAgICB7CiAgICAgIGlmIChub2RlLm1fam9pbnR5cGUgPT0ganRSb3VuZCkKICAgICAgewogICAgICAgIGRvdWJsZSBYID0gMS4wLCBZID0gMC4wOwogICAgICAgIGZvciAoY0ludCBqID0gMTsgaiA8PSBzdGVwczsgaisrKQogICAgICAgIHsKICAgICAgICAgIG1fZGVzdFBvbHkucHVzaF9iYWNrKEludFBvaW50KAogICAgICAgICAgICBSb3VuZChtX3NyY1BvbHlbMF0uWCArIFggKiBkZWx0YSksCiAgICAgICAgICAgIFJvdW5kKG1fc3JjUG9seVswXS5ZICsgWSAqIGRlbHRhKSkpOwogICAgICAgICAgZG91YmxlIFgyID0gWDsKICAgICAgICAgIFggPSBYICogbV9jb3MgLSBtX3NpbiAqIFk7CiAgICAgICAgICBZID0gWDIgKiBtX3NpbiArIFkgKiBtX2NvczsKICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CiAgICAgICAgZG91YmxlIFggPSAtMS4wLCBZID0gLTEuMDsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IDQ7ICsraikKICAgICAgICB7CiAgICAgICAgICBtX2Rlc3RQb2x5LnB1c2hfYmFjayhJbnRQb2ludCgKICAgICAgICAgICAgUm91bmQobV9zcmNQb2x5WzBdLlggKyBYICogZGVsdGEpLAogICAgICAgICAgICBSb3VuZChtX3NyY1BvbHlbMF0uWSArIFkgKiBkZWx0YSkpKTsKICAgICAgICAgIGlmIChYIDwgMCkgWCA9IDE7CiAgICAgICAgICBlbHNlIGlmIChZIDwgMCkgWSA9IDE7CiAgICAgICAgICBlbHNlIFggPSAtMTsKICAgICAgICB9CiAgICAgIH0KICAgICAgbV9kZXN0UG9seXMucHVzaF9iYWNrKG1fZGVzdFBvbHkpOwogICAgICBjb250aW51ZTsKICAgIH0KICAgIC8vYnVpbGQgbV9ub3JtYWxzIC4uLgogICAgbV9ub3JtYWxzLmNsZWFyKCk7CiAgICBtX25vcm1hbHMucmVzZXJ2ZShsZW4pOwogICAgZm9yIChpbnQgaiA9IDA7IGogPCBsZW4gLSAxOyArK2opCiAgICAgIG1fbm9ybWFscy5wdXNoX2JhY2soR2V0VW5pdE5vcm1hbChtX3NyY1BvbHlbal0sIG1fc3JjUG9seVtqICsgMV0pKTsKICAgIGlmIChub2RlLm1fZW5kdHlwZSA9PSBldENsb3NlZExpbmUgfHwgbm9kZS5tX2VuZHR5cGUgPT0gZXRDbG9zZWRQb2x5Z29uKQogICAgICBtX25vcm1hbHMucHVzaF9iYWNrKEdldFVuaXROb3JtYWwobV9zcmNQb2x5W2xlbiAtIDFdLCBtX3NyY1BvbHlbMF0pKTsKICAgIGVsc2UKICAgICAgbV9ub3JtYWxzLnB1c2hfYmFjayhEb3VibGVQb2ludChtX25vcm1hbHNbbGVuIC0gMl0pKTsKCiAgICBpZiAobm9kZS5tX2VuZHR5cGUgPT0gZXRDbG9zZWRQb2x5Z29uKQogICAgewogICAgICBpbnQgayA9IGxlbiAtIDE7CiAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbGVuOyArK2opCiAgICAgICAgT2Zmc2V0UG9pbnQoaiwgaywgbm9kZS5tX2pvaW50eXBlKTsKICAgICAgbV9kZXN0UG9seXMucHVzaF9iYWNrKG1fZGVzdFBvbHkpOwogICAgfQogICAgZWxzZSBpZiAobm9kZS5tX2VuZHR5cGUgPT0gZXRDbG9zZWRMaW5lKQogICAgewogICAgICBpbnQgayA9IGxlbiAtIDE7CiAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbGVuOyArK2opCiAgICAgICAgT2Zmc2V0UG9pbnQoaiwgaywgbm9kZS5tX2pvaW50eXBlKTsKICAgICAgbV9kZXN0UG9seXMucHVzaF9iYWNrKG1fZGVzdFBvbHkpOwogICAgICBtX2Rlc3RQb2x5LmNsZWFyKCk7CiAgICAgIC8vcmUtYnVpbGQgbV9ub3JtYWxzIC4uLgogICAgICBEb3VibGVQb2ludCBuID0gbV9ub3JtYWxzW2xlbiAtMV07CiAgICAgIGZvciAoaW50IGogPSBsZW4gLSAxOyBqID4gMDsgai0tKQogICAgICAgIG1fbm9ybWFsc1tqXSA9IERvdWJsZVBvaW50KC1tX25vcm1hbHNbaiAtIDFdLlgsIC1tX25vcm1hbHNbaiAtIDFdLlkpOwogICAgICBtX25vcm1hbHNbMF0gPSBEb3VibGVQb2ludCgtbi5YLCAtbi5ZKTsKICAgICAgayA9IDA7CiAgICAgIGZvciAoaW50IGogPSBsZW4gLSAxOyBqID49IDA7IGotLSkKICAgICAgICBPZmZzZXRQb2ludChqLCBrLCBub2RlLm1fam9pbnR5cGUpOwogICAgICBtX2Rlc3RQb2x5cy5wdXNoX2JhY2sobV9kZXN0UG9seSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgIGludCBrID0gMDsKICAgICAgZm9yIChpbnQgaiA9IDE7IGogPCBsZW4gLSAxOyArK2opCiAgICAgICAgT2Zmc2V0UG9pbnQoaiwgaywgbm9kZS5tX2pvaW50eXBlKTsKCiAgICAgIEludFBvaW50IHB0MTsKICAgICAgaWYgKG5vZGUubV9lbmR0eXBlID09IGV0T3BlbkJ1dHQpCiAgICAgIHsKICAgICAgICBpbnQgaiA9IGxlbiAtIDE7CiAgICAgICAgcHQxID0gSW50UG9pbnQoKGNJbnQpUm91bmQobV9zcmNQb2x5W2pdLlggKyBtX25vcm1hbHNbal0uWCAqCiAgICAgICAgICBkZWx0YSksIChjSW50KVJvdW5kKG1fc3JjUG9seVtqXS5ZICsgbV9ub3JtYWxzW2pdLlkgKiBkZWx0YSkpOwogICAgICAgIG1fZGVzdFBvbHkucHVzaF9iYWNrKHB0MSk7CiAgICAgICAgcHQxID0gSW50UG9pbnQoKGNJbnQpUm91bmQobV9zcmNQb2x5W2pdLlggLSBtX25vcm1hbHNbal0uWCAqCiAgICAgICAgICBkZWx0YSksIChjSW50KVJvdW5kKG1fc3JjUG9seVtqXS5ZIC0gbV9ub3JtYWxzW2pdLlkgKiBkZWx0YSkpOwogICAgICAgIG1fZGVzdFBvbHkucHVzaF9iYWNrKHB0MSk7CiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CiAgICAgICAgaW50IGogPSBsZW4gLSAxOwogICAgICAgIGsgPSBsZW4gLSAyOwogICAgICAgIG1fc2luQSA9IDA7CiAgICAgICAgbV9ub3JtYWxzW2pdID0gRG91YmxlUG9pbnQoLW1fbm9ybWFsc1tqXS5YLCAtbV9ub3JtYWxzW2pdLlkpOwogICAgICAgIGlmIChub2RlLm1fZW5kdHlwZSA9PSBldE9wZW5TcXVhcmUpCiAgICAgICAgICBEb1NxdWFyZShqLCBrKTsKICAgICAgICBlbHNlCiAgICAgICAgICBEb1JvdW5kKGosIGspOwogICAgICB9CgogICAgICAvL3JlLWJ1aWxkIG1fbm9ybWFscyAuLi4KICAgICAgZm9yIChpbnQgaiA9IGxlbiAtIDE7IGogPiAwOyBqLS0pCiAgICAgICAgbV9ub3JtYWxzW2pdID0gRG91YmxlUG9pbnQoLW1fbm9ybWFsc1tqIC0gMV0uWCwgLW1fbm9ybWFsc1tqIC0gMV0uWSk7CiAgICAgIG1fbm9ybWFsc1swXSA9IERvdWJsZVBvaW50KC1tX25vcm1hbHNbMV0uWCwgLW1fbm9ybWFsc1sxXS5ZKTsKCiAgICAgIGsgPSBsZW4gLSAxOwogICAgICBmb3IgKGludCBqID0gayAtIDE7IGogPiAwOyAtLWopIE9mZnNldFBvaW50KGosIGssIG5vZGUubV9qb2ludHlwZSk7CgogICAgICBpZiAobm9kZS5tX2VuZHR5cGUgPT0gZXRPcGVuQnV0dCkKICAgICAgewogICAgICAgIHB0MSA9IEludFBvaW50KChjSW50KVJvdW5kKG1fc3JjUG9seVswXS5YIC0gbV9ub3JtYWxzWzBdLlggKiBkZWx0YSksCiAgICAgICAgICAoY0ludClSb3VuZChtX3NyY1BvbHlbMF0uWSAtIG1fbm9ybWFsc1swXS5ZICogZGVsdGEpKTsKICAgICAgICBtX2Rlc3RQb2x5LnB1c2hfYmFjayhwdDEpOwogICAgICAgIHB0MSA9IEludFBvaW50KChjSW50KVJvdW5kKG1fc3JjUG9seVswXS5YICsgbV9ub3JtYWxzWzBdLlggKiBkZWx0YSksCiAgICAgICAgICAoY0ludClSb3VuZChtX3NyY1BvbHlbMF0uWSArIG1fbm9ybWFsc1swXS5ZICogZGVsdGEpKTsKICAgICAgICBtX2Rlc3RQb2x5LnB1c2hfYmFjayhwdDEpOwogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgIGsgPSAxOwogICAgICAgIG1fc2luQSA9IDA7CiAgICAgICAgaWYgKG5vZGUubV9lbmR0eXBlID09IGV0T3BlblNxdWFyZSkKICAgICAgICAgIERvU3F1YXJlKDAsIDEpOwogICAgICAgIGVsc2UKICAgICAgICAgIERvUm91bmQoMCwgMSk7CiAgICAgIH0KICAgICAgbV9kZXN0UG9seXMucHVzaF9iYWNrKG1fZGVzdFBvbHkpOwogICAgfQogIH0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBDbGlwcGVyT2Zmc2V0OjpPZmZzZXRQb2ludChpbnQgaiwgaW50JiBrLCBKb2luVHlwZSBqb2ludHlwZSkKewogIC8vY3Jvc3MgcHJvZHVjdCAuLi4KICBtX3NpbkEgPSAobV9ub3JtYWxzW2tdLlggKiBtX25vcm1hbHNbal0uWSAtIG1fbm9ybWFsc1tqXS5YICogbV9ub3JtYWxzW2tdLlkpOwogIGlmIChzdGQ6OmZhYnMobV9zaW5BICogbV9kZWx0YSkgPCAxLjApIAogIHsKICAgIC8vZG90IHByb2R1Y3QgLi4uCiAgICBkb3VibGUgY29zQSA9IChtX25vcm1hbHNba10uWCAqIG1fbm9ybWFsc1tqXS5YICsgbV9ub3JtYWxzW2pdLlkgKiBtX25vcm1hbHNba10uWSApOyAKICAgIGlmIChjb3NBID4gMCkgLy8gYW5nbGUgPT4gMCBkZWdyZWVzCiAgICB7CiAgICAgIG1fZGVzdFBvbHkucHVzaF9iYWNrKEludFBvaW50KFJvdW5kKG1fc3JjUG9seVtqXS5YICsgbV9ub3JtYWxzW2tdLlggKiBtX2RlbHRhKSwKICAgICAgICBSb3VuZChtX3NyY1BvbHlbal0uWSArIG1fbm9ybWFsc1trXS5ZICogbV9kZWx0YSkpKTsKICAgICAgcmV0dXJuOyAKICAgIH0KICAgIC8vZWxzZSBhbmdsZSA9PiAxODAgZGVncmVlcyAgIAogIH0KICBlbHNlIGlmIChtX3NpbkEgPiAxLjApIG1fc2luQSA9IDEuMDsKICBlbHNlIGlmIChtX3NpbkEgPCAtMS4wKSBtX3NpbkEgPSAtMS4wOwoKICBpZiAobV9zaW5BICogbV9kZWx0YSA8IDApCiAgewogICAgbV9kZXN0UG9seS5wdXNoX2JhY2soSW50UG9pbnQoUm91bmQobV9zcmNQb2x5W2pdLlggKyBtX25vcm1hbHNba10uWCAqIG1fZGVsdGEpLAogICAgICBSb3VuZChtX3NyY1BvbHlbal0uWSArIG1fbm9ybWFsc1trXS5ZICogbV9kZWx0YSkpKTsKICAgIG1fZGVzdFBvbHkucHVzaF9iYWNrKG1fc3JjUG9seVtqXSk7CiAgICBtX2Rlc3RQb2x5LnB1c2hfYmFjayhJbnRQb2ludChSb3VuZChtX3NyY1BvbHlbal0uWCArIG1fbm9ybWFsc1tqXS5YICogbV9kZWx0YSksCiAgICAgIFJvdW5kKG1fc3JjUG9seVtqXS5ZICsgbV9ub3JtYWxzW2pdLlkgKiBtX2RlbHRhKSkpOwogIH0KICBlbHNlCiAgICBzd2l0Y2ggKGpvaW50eXBlKQogICAgewogICAgICBjYXNlIGp0TWl0ZXI6CiAgICAgICAgewogICAgICAgICAgZG91YmxlIHIgPSAxICsgKG1fbm9ybWFsc1tqXS5YICogbV9ub3JtYWxzW2tdLlggKwogICAgICAgICAgICBtX25vcm1hbHNbal0uWSAqIG1fbm9ybWFsc1trXS5ZKTsKICAgICAgICAgIGlmIChyID49IG1fbWl0ZXJMaW0pIERvTWl0ZXIoaiwgaywgcik7IGVsc2UgRG9TcXVhcmUoaiwgayk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIGNhc2UganRTcXVhcmU6IERvU3F1YXJlKGosIGspOyBicmVhazsKICAgICAgY2FzZSBqdFJvdW5kOiBEb1JvdW5kKGosIGspOyBicmVhazsKICAgIH0KICBrID0gajsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBDbGlwcGVyT2Zmc2V0OjpEb1NxdWFyZShpbnQgaiwgaW50IGspCnsKICBkb3VibGUgZHggPSBzdGQ6OnRhbihzdGQ6OmF0YW4yKG1fc2luQSwKICAgICAgbV9ub3JtYWxzW2tdLlggKiBtX25vcm1hbHNbal0uWCArIG1fbm9ybWFsc1trXS5ZICogbV9ub3JtYWxzW2pdLlkpIC8gNCk7CiAgbV9kZXN0UG9seS5wdXNoX2JhY2soSW50UG9pbnQoCiAgICAgIFJvdW5kKG1fc3JjUG9seVtqXS5YICsgbV9kZWx0YSAqIChtX25vcm1hbHNba10uWCAtIG1fbm9ybWFsc1trXS5ZICogZHgpKSwKICAgICAgUm91bmQobV9zcmNQb2x5W2pdLlkgKyBtX2RlbHRhICogKG1fbm9ybWFsc1trXS5ZICsgbV9ub3JtYWxzW2tdLlggKiBkeCkpKSk7CiAgbV9kZXN0UG9seS5wdXNoX2JhY2soSW50UG9pbnQoCiAgICAgIFJvdW5kKG1fc3JjUG9seVtqXS5YICsgbV9kZWx0YSAqIChtX25vcm1hbHNbal0uWCArIG1fbm9ybWFsc1tqXS5ZICogZHgpKSwKICAgICAgUm91bmQobV9zcmNQb2x5W2pdLlkgKyBtX2RlbHRhICogKG1fbm9ybWFsc1tqXS5ZIC0gbV9ub3JtYWxzW2pdLlggKiBkeCkpKSk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlck9mZnNldDo6RG9NaXRlcihpbnQgaiwgaW50IGssIGRvdWJsZSByKQp7CiAgZG91YmxlIHEgPSBtX2RlbHRhIC8gcjsKICBtX2Rlc3RQb2x5LnB1c2hfYmFjayhJbnRQb2ludChSb3VuZChtX3NyY1BvbHlbal0uWCArIChtX25vcm1hbHNba10uWCArIG1fbm9ybWFsc1tqXS5YKSAqIHEpLAogICAgICBSb3VuZChtX3NyY1BvbHlbal0uWSArIChtX25vcm1hbHNba10uWSArIG1fbm9ybWFsc1tqXS5ZKSAqIHEpKSk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlck9mZnNldDo6RG9Sb3VuZChpbnQgaiwgaW50IGspCnsKICBkb3VibGUgYSA9IHN0ZDo6YXRhbjIobV9zaW5BLAogIG1fbm9ybWFsc1trXS5YICogbV9ub3JtYWxzW2pdLlggKyBtX25vcm1hbHNba10uWSAqIG1fbm9ybWFsc1tqXS5ZKTsKICBpbnQgc3RlcHMgPSBzdGQ6Om1heCgoaW50KVJvdW5kKG1fU3RlcHNQZXJSYWQgKiBzdGQ6OmZhYnMoYSkpLCAxKTsKCiAgZG91YmxlIFggPSBtX25vcm1hbHNba10uWCwgWSA9IG1fbm9ybWFsc1trXS5ZLCBYMjsKICBmb3IgKGludCBpID0gMDsgaSA8IHN0ZXBzOyArK2kpCiAgewogICAgbV9kZXN0UG9seS5wdXNoX2JhY2soSW50UG9pbnQoCiAgICAgICAgUm91bmQobV9zcmNQb2x5W2pdLlggKyBYICogbV9kZWx0YSksCiAgICAgICAgUm91bmQobV9zcmNQb2x5W2pdLlkgKyBZICogbV9kZWx0YSkpKTsKICAgIFgyID0gWDsKICAgIFggPSBYICogbV9jb3MgLSBtX3NpbiAqIFk7CiAgICBZID0gWDIgKiBtX3NpbiArIFkgKiBtX2NvczsKICB9CiAgbV9kZXN0UG9seS5wdXNoX2JhY2soSW50UG9pbnQoCiAgUm91bmQobV9zcmNQb2x5W2pdLlggKyBtX25vcm1hbHNbal0uWCAqIG1fZGVsdGEpLAogIFJvdW5kKG1fc3JjUG9seVtqXS5ZICsgbV9ub3JtYWxzW2pdLlkgKiBtX2RlbHRhKSkpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBNaXNjZWxsYW5lb3VzIHB1YmxpYyBmdW5jdGlvbnMKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xpcHBlcjo6RG9TaW1wbGVQb2x5Z29ucygpCnsKICBQb2x5T3V0TGlzdDo6c2l6ZV90eXBlIGkgPSAwOwogIHdoaWxlIChpIDwgbV9Qb2x5T3V0cy5zaXplKCkpIAogIHsKICAgIE91dFJlYyogb3V0cmVjID0gbV9Qb2x5T3V0c1tpKytdOwogICAgT3V0UHQqIG9wID0gb3V0cmVjLT5QdHM7CiAgICBpZiAoIW9wIHx8IG91dHJlYy0+SXNPcGVuKSBjb250aW51ZTsKICAgIGRvIC8vZm9yIGVhY2ggUHQgaW4gUG9seWdvbiB1bnRpbCBkdXBsaWNhdGUgZm91bmQgZG8gLi4uCiAgICB7CiAgICAgIE91dFB0KiBvcDIgPSBvcC0+TmV4dDsKICAgICAgd2hpbGUgKG9wMiAhPSBvdXRyZWMtPlB0cykgCiAgICAgIHsKICAgICAgICBpZiAoKG9wLT5QdCA9PSBvcDItPlB0KSAmJiBvcDItPk5leHQgIT0gb3AgJiYgb3AyLT5QcmV2ICE9IG9wKSAKICAgICAgICB7CiAgICAgICAgICAvL3NwbGl0IHRoZSBwb2x5Z29uIGludG8gdHdvIC4uLgogICAgICAgICAgT3V0UHQqIG9wMyA9IG9wLT5QcmV2OwogICAgICAgICAgT3V0UHQqIG9wNCA9IG9wMi0+UHJldjsKICAgICAgICAgIG9wLT5QcmV2ID0gb3A0OwogICAgICAgICAgb3A0LT5OZXh0ID0gb3A7CiAgICAgICAgICBvcDItPlByZXYgPSBvcDM7CiAgICAgICAgICBvcDMtPk5leHQgPSBvcDI7CgogICAgICAgICAgb3V0cmVjLT5QdHMgPSBvcDsKICAgICAgICAgIE91dFJlYyogb3V0cmVjMiA9IENyZWF0ZU91dFJlYygpOwogICAgICAgICAgb3V0cmVjMi0+UHRzID0gb3AyOwogICAgICAgICAgVXBkYXRlT3V0UHRJZHhzKCpvdXRyZWMyKTsKICAgICAgICAgIGlmIChQb2x5MkNvbnRhaW5zUG9seTEob3V0cmVjMi0+UHRzLCBvdXRyZWMtPlB0cykpCiAgICAgICAgICB7CiAgICAgICAgICAgIC8vT3V0UmVjMiBpcyBjb250YWluZWQgYnkgT3V0UmVjMSAuLi4KICAgICAgICAgICAgb3V0cmVjMi0+SXNIb2xlID0gIW91dHJlYy0+SXNIb2xlOwogICAgICAgICAgICBvdXRyZWMyLT5GaXJzdExlZnQgPSBvdXRyZWM7CiAgICAgICAgICAgIGlmIChtX1VzaW5nUG9seVRyZWUpIEZpeHVwRmlyc3RMZWZ0czIob3V0cmVjMiwgb3V0cmVjKTsKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UKICAgICAgICAgICAgaWYgKFBvbHkyQ29udGFpbnNQb2x5MShvdXRyZWMtPlB0cywgb3V0cmVjMi0+UHRzKSkKICAgICAgICAgIHsKICAgICAgICAgICAgLy9PdXRSZWMxIGlzIGNvbnRhaW5lZCBieSBPdXRSZWMyIC4uLgogICAgICAgICAgICBvdXRyZWMyLT5Jc0hvbGUgPSBvdXRyZWMtPklzSG9sZTsKICAgICAgICAgICAgb3V0cmVjLT5Jc0hvbGUgPSAhb3V0cmVjMi0+SXNIb2xlOwogICAgICAgICAgICBvdXRyZWMyLT5GaXJzdExlZnQgPSBvdXRyZWMtPkZpcnN0TGVmdDsKICAgICAgICAgICAgb3V0cmVjLT5GaXJzdExlZnQgPSBvdXRyZWMyOwogICAgICAgICAgICBpZiAobV9Vc2luZ1BvbHlUcmVlKSBGaXh1cEZpcnN0TGVmdHMyKG91dHJlYywgb3V0cmVjMik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgewogICAgICAgICAgICAvL3RoZSAyIHBvbHlnb25zIGFyZSBzZXBhcmF0ZSAuLi4KICAgICAgICAgICAgb3V0cmVjMi0+SXNIb2xlID0gb3V0cmVjLT5Jc0hvbGU7CiAgICAgICAgICAgIG91dHJlYzItPkZpcnN0TGVmdCA9IG91dHJlYy0+Rmlyc3RMZWZ0OwogICAgICAgICAgICBpZiAobV9Vc2luZ1BvbHlUcmVlKSBGaXh1cEZpcnN0TGVmdHMxKG91dHJlYywgb3V0cmVjMik7CiAgICAgICAgICAgIH0KICAgICAgICAgIG9wMiA9IG9wOyAvL2llIGdldCByZWFkeSBmb3IgdGhlIE5leHQgaXRlcmF0aW9uCiAgICAgICAgfQogICAgICAgIG9wMiA9IG9wMi0+TmV4dDsKICAgICAgfQogICAgICBvcCA9IG9wLT5OZXh0OwogICAgfQogICAgd2hpbGUgKG9wICE9IG91dHJlYy0+UHRzKTsKICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgUmV2ZXJzZVBhdGgoUGF0aCYgcCkKewogIHN0ZDo6cmV2ZXJzZShwLmJlZ2luKCksIHAuZW5kKCkpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIFJldmVyc2VQYXRocyhQYXRocyYgcCkKewogIGZvciAoUGF0aHM6OnNpemVfdHlwZSBpID0gMDsgaSA8IHAuc2l6ZSgpOyArK2kpCiAgICBSZXZlcnNlUGF0aChwW2ldKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBTaW1wbGlmeVBvbHlnb24oY29uc3QgUGF0aCAmaW5fcG9seSwgUGF0aHMgJm91dF9wb2x5cywgUG9seUZpbGxUeXBlIGZpbGxUeXBlKQp7CiAgQ2xpcHBlciBjOwogIGMuU3RyaWN0bHlTaW1wbGUodHJ1ZSk7CiAgYy5BZGRQYXRoKGluX3BvbHksIHB0U3ViamVjdCwgdHJ1ZSk7CiAgYy5FeGVjdXRlKGN0VW5pb24sIG91dF9wb2x5cywgZmlsbFR5cGUsIGZpbGxUeXBlKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBTaW1wbGlmeVBvbHlnb25zKGNvbnN0IFBhdGhzICZpbl9wb2x5cywgUGF0aHMgJm91dF9wb2x5cywgUG9seUZpbGxUeXBlIGZpbGxUeXBlKQp7CiAgQ2xpcHBlciBjOwogIGMuU3RyaWN0bHlTaW1wbGUodHJ1ZSk7CiAgYy5BZGRQYXRocyhpbl9wb2x5cywgcHRTdWJqZWN0LCB0cnVlKTsKICBjLkV4ZWN1dGUoY3RVbmlvbiwgb3V0X3BvbHlzLCBmaWxsVHlwZSwgZmlsbFR5cGUpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIFNpbXBsaWZ5UG9seWdvbnMoUGF0aHMgJnBvbHlzLCBQb2x5RmlsbFR5cGUgZmlsbFR5cGUpCnsKICBTaW1wbGlmeVBvbHlnb25zKHBvbHlzLCBwb2x5cywgZmlsbFR5cGUpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgppbmxpbmUgZG91YmxlIERpc3RhbmNlU3FyZChjb25zdCBJbnRQb2ludCYgcHQxLCBjb25zdCBJbnRQb2ludCYgcHQyKQp7CiAgZG91YmxlIER4ID0gKChkb3VibGUpcHQxLlggLSBwdDIuWCk7CiAgZG91YmxlIGR5ID0gKChkb3VibGUpcHQxLlkgLSBwdDIuWSk7CiAgcmV0dXJuIChEeCpEeCArIGR5KmR5KTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKZG91YmxlIERpc3RhbmNlRnJvbUxpbmVTcXJkKAogIGNvbnN0IEludFBvaW50JiBwdCwgY29uc3QgSW50UG9pbnQmIGxuMSwgY29uc3QgSW50UG9pbnQmIGxuMikKewogIC8vVGhlIGVxdWF0aW9uIG9mIGEgbGluZSBpbiBnZW5lcmFsIGZvcm0gKEF4ICsgQnkgKyBDID0gMCkKICAvL2dpdmVuIDIgcG9pbnRzICh4uSx5uSkgJiAoeLIsebIpIGlzIC4uLgogIC8vKHm5IC0gebIpeCArICh4siAtIHi5KXkgKyAoebIgLSB5uSl4uSAtICh4siAtIHi5KXm5ID0gMAogIC8vQSA9ICh5uSAtIHmyKTsgQiA9ICh4siAtIHi5KTsgQyA9ICh5siAtIHm5KXi5IC0gKHiyIC0geLkpebkKICAvL3BlcnBlbmRpY3VsYXIgZGlzdGFuY2Ugb2YgcG9pbnQgKHizLHmzKSA9IChBeLMgKyBCebMgKyBDKS9TcXJ0KEGyICsgQrIpCiAgLy9zZWUgaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9QZXJwZW5kaWN1bGFyX2Rpc3RhbmNlCiAgZG91YmxlIEEgPSBkb3VibGUobG4xLlkgLSBsbjIuWSk7CiAgZG91YmxlIEIgPSBkb3VibGUobG4yLlggLSBsbjEuWCk7CiAgZG91YmxlIEMgPSBBICogbG4xLlggICsgQiAqIGxuMS5ZOwogIEMgPSBBICogcHQuWCArIEIgKiBwdC5ZIC0gQzsKICByZXR1cm4gKEMgKiBDKSAvIChBICogQSArIEIgKiBCKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYm9vbCBTbG9wZXNOZWFyQ29sbGluZWFyKGNvbnN0IEludFBvaW50JiBwdDEsIAogICAgY29uc3QgSW50UG9pbnQmIHB0MiwgY29uc3QgSW50UG9pbnQmIHB0MywgZG91YmxlIGRpc3RTcXJkKQp7CiAgLy90aGlzIGZ1bmN0aW9uIGlzIG1vcmUgYWNjdXJhdGUgd2hlbiB0aGUgcG9pbnQgdGhhdCdzIGdlb21ldHJpY2FsbHkKICAvL2JldHdlZW4gdGhlIG90aGVyIDIgcG9pbnRzIGlzIHRoZSBvbmUgdGhhdCdzIHRlc3RlZCBmb3IgZGlzdGFuY2UuCiAgLy9pZSBtYWtlcyBpdCBtb3JlIGxpa2VseSB0byBwaWNrIHVwICdzcGlrZXMnIC4uLgoJaWYgKEFicyhwdDEuWCAtIHB0Mi5YKSA+IEFicyhwdDEuWSAtIHB0Mi5ZKSkKCXsKICAgIGlmICgocHQxLlggPiBwdDIuWCkgPT0gKHB0MS5YIDwgcHQzLlgpKQogICAgICByZXR1cm4gRGlzdGFuY2VGcm9tTGluZVNxcmQocHQxLCBwdDIsIHB0MykgPCBkaXN0U3FyZDsKICAgIGVsc2UgaWYgKChwdDIuWCA+IHB0MS5YKSA9PSAocHQyLlggPCBwdDMuWCkpCiAgICAgIHJldHVybiBEaXN0YW5jZUZyb21MaW5lU3FyZChwdDIsIHB0MSwgcHQzKSA8IGRpc3RTcXJkOwoJCWVsc2UKCSAgICByZXR1cm4gRGlzdGFuY2VGcm9tTGluZVNxcmQocHQzLCBwdDEsIHB0MikgPCBkaXN0U3FyZDsKCX0KCWVsc2UKCXsKICAgIGlmICgocHQxLlkgPiBwdDIuWSkgPT0gKHB0MS5ZIDwgcHQzLlkpKQogICAgICByZXR1cm4gRGlzdGFuY2VGcm9tTGluZVNxcmQocHQxLCBwdDIsIHB0MykgPCBkaXN0U3FyZDsKICAgIGVsc2UgaWYgKChwdDIuWSA+IHB0MS5ZKSA9PSAocHQyLlkgPCBwdDMuWSkpCiAgICAgIHJldHVybiBEaXN0YW5jZUZyb21MaW5lU3FyZChwdDIsIHB0MSwgcHQzKSA8IGRpc3RTcXJkOwoJCWVsc2UKICAgICAgcmV0dXJuIERpc3RhbmNlRnJvbUxpbmVTcXJkKHB0MywgcHQxLCBwdDIpIDwgZGlzdFNxcmQ7Cgl9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmJvb2wgUG9pbnRzQXJlQ2xvc2UoSW50UG9pbnQgcHQxLCBJbnRQb2ludCBwdDIsIGRvdWJsZSBkaXN0U3FyZCkKewogICAgZG91YmxlIER4ID0gKGRvdWJsZSlwdDEuWCAtIHB0Mi5YOwogICAgZG91YmxlIGR5ID0gKGRvdWJsZSlwdDEuWSAtIHB0Mi5ZOwogICAgcmV0dXJuICgoRHggKiBEeCkgKyAoZHkgKiBkeSkgPD0gZGlzdFNxcmQpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpPdXRQdCogRXhjbHVkZU9wKE91dFB0KiBvcCkKewogIE91dFB0KiByZXN1bHQgPSBvcC0+UHJldjsKICByZXN1bHQtPk5leHQgPSBvcC0+TmV4dDsKICBvcC0+TmV4dC0+UHJldiA9IHJlc3VsdDsKICByZXN1bHQtPklkeCA9IDA7CiAgcmV0dXJuIHJlc3VsdDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBDbGVhblBvbHlnb24oY29uc3QgUGF0aCYgaW5fcG9seSwgUGF0aCYgb3V0X3BvbHksIGRvdWJsZSBkaXN0YW5jZSkKewogIC8vZGlzdGFuY2UgPSBwcm94aW1pdHkgaW4gdW5pdHMvcGl4ZWxzIGJlbG93IHdoaWNoIHZlcnRpY2VzCiAgLy93aWxsIGJlIHN0cmlwcGVkLiBEZWZhdWx0IH49IHNxcnQoMikuCiAgCiAgc2l6ZV90IHNpemUgPSBpbl9wb2x5LnNpemUoKTsKICAKICBpZiAoc2l6ZSA9PSAwKSAKICB7CiAgICBvdXRfcG9seS5jbGVhcigpOwogICAgcmV0dXJuOwogIH0KCiAgT3V0UHQqIG91dFB0cyA9IG5ldyBPdXRQdFtzaXplXTsKICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IHNpemU7ICsraSkKICB7CiAgICBvdXRQdHNbaV0uUHQgPSBpbl9wb2x5W2ldOwogICAgb3V0UHRzW2ldLk5leHQgPSAmb3V0UHRzWyhpICsgMSkgJSBzaXplXTsKICAgIG91dFB0c1tpXS5OZXh0LT5QcmV2ID0gJm91dFB0c1tpXTsKICAgIG91dFB0c1tpXS5JZHggPSAwOwogIH0KCiAgZG91YmxlIGRpc3RTcXJkID0gZGlzdGFuY2UgKiBkaXN0YW5jZTsKICBPdXRQdCogb3AgPSAmb3V0UHRzWzBdOwogIHdoaWxlIChvcC0+SWR4ID09IDAgJiYgb3AtPk5leHQgIT0gb3AtPlByZXYpIAogIHsKICAgIGlmIChQb2ludHNBcmVDbG9zZShvcC0+UHQsIG9wLT5QcmV2LT5QdCwgZGlzdFNxcmQpKQogICAgewogICAgICBvcCA9IEV4Y2x1ZGVPcChvcCk7CiAgICAgIHNpemUtLTsKICAgIH0gCiAgICBlbHNlIGlmIChQb2ludHNBcmVDbG9zZShvcC0+UHJldi0+UHQsIG9wLT5OZXh0LT5QdCwgZGlzdFNxcmQpKQogICAgewogICAgICBFeGNsdWRlT3Aob3AtPk5leHQpOwogICAgICBvcCA9IEV4Y2x1ZGVPcChvcCk7CiAgICAgIHNpemUgLT0gMjsKICAgIH0KICAgIGVsc2UgaWYgKFNsb3Blc05lYXJDb2xsaW5lYXIob3AtPlByZXYtPlB0LCBvcC0+UHQsIG9wLT5OZXh0LT5QdCwgZGlzdFNxcmQpKQogICAgewogICAgICBvcCA9IEV4Y2x1ZGVPcChvcCk7CiAgICAgIHNpemUtLTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgb3AtPklkeCA9IDE7CiAgICAgIG9wID0gb3AtPk5leHQ7CiAgICB9CiAgfQoKICBpZiAoc2l6ZSA8IDMpIHNpemUgPSAwOwogIG91dF9wb2x5LnJlc2l6ZShzaXplKTsKICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IHNpemU7ICsraSkKICB7CiAgICBvdXRfcG9seVtpXSA9IG9wLT5QdDsKICAgIG9wID0gb3AtPk5leHQ7CiAgfQogIGRlbGV0ZSBbXSBvdXRQdHM7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xlYW5Qb2x5Z29uKFBhdGgmIHBvbHksIGRvdWJsZSBkaXN0YW5jZSkKewogIENsZWFuUG9seWdvbihwb2x5LCBwb2x5LCBkaXN0YW5jZSk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xlYW5Qb2x5Z29ucyhjb25zdCBQYXRocyYgaW5fcG9seXMsIFBhdGhzJiBvdXRfcG9seXMsIGRvdWJsZSBkaXN0YW5jZSkKewogIG91dF9wb2x5cy5yZXNpemUoaW5fcG9seXMuc2l6ZSgpKTsKICBmb3IgKFBhdGhzOjpzaXplX3R5cGUgaSA9IDA7IGkgPCBpbl9wb2x5cy5zaXplKCk7ICsraSkKICAgIENsZWFuUG9seWdvbihpbl9wb2x5c1tpXSwgb3V0X3BvbHlzW2ldLCBkaXN0YW5jZSk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xlYW5Qb2x5Z29ucyhQYXRocyYgcG9seXMsIGRvdWJsZSBkaXN0YW5jZSkKewogIENsZWFuUG9seWdvbnMocG9seXMsIHBvbHlzLCBkaXN0YW5jZSk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgTWlua293c2tpKGNvbnN0IFBhdGgmIHBvbHksIGNvbnN0IFBhdGgmIHBhdGgsIAogIFBhdGhzJiBzb2x1dGlvbiwgYm9vbCBpc1N1bSwgYm9vbCBpc0Nsb3NlZCkKewogIGludCBkZWx0YSA9IChpc0Nsb3NlZCA/IDEgOiAwKTsKICBzaXplX3QgcG9seUNudCA9IHBvbHkuc2l6ZSgpOwogIHNpemVfdCBwYXRoQ250ID0gcGF0aC5zaXplKCk7CiAgUGF0aHMgcHA7CiAgcHAucmVzZXJ2ZShwYXRoQ250KTsKICBpZiAoaXNTdW0pCiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IHBhdGhDbnQ7ICsraSkKICAgIHsKICAgICAgUGF0aCBwOwogICAgICBwLnJlc2VydmUocG9seUNudCk7CiAgICAgIGZvciAoc2l6ZV90IGogPSAwOyBqIDwgcG9seS5zaXplKCk7ICsraikKICAgICAgICBwLnB1c2hfYmFjayhJbnRQb2ludChwYXRoW2ldLlggKyBwb2x5W2pdLlgsIHBhdGhbaV0uWSArIHBvbHlbal0uWSkpOwogICAgICBwcC5wdXNoX2JhY2socCk7CiAgICB9CiAgZWxzZQogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBwYXRoQ250OyArK2kpCiAgICB7CiAgICAgIFBhdGggcDsKICAgICAgcC5yZXNlcnZlKHBvbHlDbnQpOwogICAgICBmb3IgKHNpemVfdCBqID0gMDsgaiA8IHBvbHkuc2l6ZSgpOyArK2opCiAgICAgICAgcC5wdXNoX2JhY2soSW50UG9pbnQocGF0aFtpXS5YIC0gcG9seVtqXS5YLCBwYXRoW2ldLlkgLSBwb2x5W2pdLlkpKTsKICAgICAgcHAucHVzaF9iYWNrKHApOwogICAgfQoKICBzb2x1dGlvbi5jbGVhcigpOwogIHNvbHV0aW9uLnJlc2VydmUoKHBhdGhDbnQgKyBkZWx0YSkgKiAocG9seUNudCArIDEpKTsKICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IHBhdGhDbnQgLSAxICsgZGVsdGE7ICsraSkKICAgIGZvciAoc2l6ZV90IGogPSAwOyBqIDwgcG9seUNudDsgKytqKQogICAgewogICAgICBQYXRoIHF1YWQ7CiAgICAgIHF1YWQucmVzZXJ2ZSg0KTsKICAgICAgcXVhZC5wdXNoX2JhY2socHBbaSAlIHBhdGhDbnRdW2ogJSBwb2x5Q250XSk7CiAgICAgIHF1YWQucHVzaF9iYWNrKHBwWyhpICsgMSkgJSBwYXRoQ250XVtqICUgcG9seUNudF0pOwogICAgICBxdWFkLnB1c2hfYmFjayhwcFsoaSArIDEpICUgcGF0aENudF1bKGogKyAxKSAlIHBvbHlDbnRdKTsKICAgICAgcXVhZC5wdXNoX2JhY2socHBbaSAlIHBhdGhDbnRdWyhqICsgMSkgJSBwb2x5Q250XSk7CiAgICAgIGlmICghT3JpZW50YXRpb24ocXVhZCkpIFJldmVyc2VQYXRoKHF1YWQpOwogICAgICBzb2x1dGlvbi5wdXNoX2JhY2socXVhZCk7CiAgICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgTWlua293c2tpU3VtKGNvbnN0IFBhdGgmIHBhdHRlcm4sIGNvbnN0IFBhdGgmIHBhdGgsIFBhdGhzJiBzb2x1dGlvbiwgYm9vbCBwYXRoSXNDbG9zZWQpCnsKICBNaW5rb3dza2kocGF0dGVybiwgcGF0aCwgc29sdXRpb24sIHRydWUsIHBhdGhJc0Nsb3NlZCk7CiAgQ2xpcHBlciBjOwogIGMuQWRkUGF0aHMoc29sdXRpb24sIHB0U3ViamVjdCwgdHJ1ZSk7CiAgYy5FeGVjdXRlKGN0VW5pb24sIHNvbHV0aW9uLCBwZnROb25aZXJvLCBwZnROb25aZXJvKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBUcmFuc2xhdGVQYXRoKGNvbnN0IFBhdGgmIGlucHV0LCBQYXRoJiBvdXRwdXQsIGNvbnN0IEludFBvaW50IGRlbHRhKQp7CiAgLy9wcmVjb25kaXRpb246IGlucHV0ICE9IG91dHB1dAogIG91dHB1dC5yZXNpemUoaW5wdXQuc2l6ZSgpKTsKICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGlucHV0LnNpemUoKTsgKytpKQogICAgb3V0cHV0W2ldID0gSW50UG9pbnQoaW5wdXRbaV0uWCArIGRlbHRhLlgsIGlucHV0W2ldLlkgKyBkZWx0YS5ZKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBNaW5rb3dza2lTdW0oY29uc3QgUGF0aCYgcGF0dGVybiwgY29uc3QgUGF0aHMmIHBhdGhzLCBQYXRocyYgc29sdXRpb24sIGJvb2wgcGF0aElzQ2xvc2VkKQp7CiAgQ2xpcHBlciBjOwogIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgcGF0aHMuc2l6ZSgpOyArK2kpCiAgewogICAgUGF0aHMgdG1wOwogICAgTWlua293c2tpKHBhdHRlcm4sIHBhdGhzW2ldLCB0bXAsIHRydWUsIHBhdGhJc0Nsb3NlZCk7CiAgICBjLkFkZFBhdGhzKHRtcCwgcHRTdWJqZWN0LCB0cnVlKTsKICAgIGlmIChwYXRoSXNDbG9zZWQpCiAgICB7CiAgICAgIFBhdGggdG1wMjsKICAgICAgVHJhbnNsYXRlUGF0aChwYXRoc1tpXSwgdG1wMiwgcGF0dGVyblswXSk7CiAgICAgIGMuQWRkUGF0aCh0bXAyLCBwdENsaXAsIHRydWUpOwogICAgfQogIH0KICAgIGMuRXhlY3V0ZShjdFVuaW9uLCBzb2x1dGlvbiwgcGZ0Tm9uWmVybywgcGZ0Tm9uWmVybyk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgTWlua293c2tpRGlmZihjb25zdCBQYXRoJiBwb2x5MSwgY29uc3QgUGF0aCYgcG9seTIsIFBhdGhzJiBzb2x1dGlvbikKewogIE1pbmtvd3NraShwb2x5MSwgcG9seTIsIHNvbHV0aW9uLCBmYWxzZSwgdHJ1ZSk7CiAgQ2xpcHBlciBjOwogIGMuQWRkUGF0aHMoc29sdXRpb24sIHB0U3ViamVjdCwgdHJ1ZSk7CiAgYy5FeGVjdXRlKGN0VW5pb24sIHNvbHV0aW9uLCBwZnROb25aZXJvLCBwZnROb25aZXJvKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKZW51bSBOb2RlVHlwZSB7bnRBbnksIG50T3BlbiwgbnRDbG9zZWR9OwoKdm9pZCBBZGRQb2x5Tm9kZVRvUGF0aHMoY29uc3QgUG9seU5vZGUmIHBvbHlub2RlLCBOb2RlVHlwZSBub2RldHlwZSwgUGF0aHMmIHBhdGhzKQp7CiAgYm9vbCBtYXRjaCA9IHRydWU7CiAgaWYgKG5vZGV0eXBlID09IG50Q2xvc2VkKSBtYXRjaCA9ICFwb2x5bm9kZS5Jc09wZW4oKTsKICBlbHNlIGlmIChub2RldHlwZSA9PSBudE9wZW4pIHJldHVybjsKCiAgaWYgKCFwb2x5bm9kZS5Db250b3VyLmVtcHR5KCkgJiYgbWF0Y2gpCiAgICBwYXRocy5wdXNoX2JhY2socG9seW5vZGUuQ29udG91cik7CiAgZm9yIChpbnQgaSA9IDA7IGkgPCBwb2x5bm9kZS5DaGlsZENvdW50KCk7ICsraSkKICAgIEFkZFBvbHlOb2RlVG9QYXRocygqcG9seW5vZGUuQ2hpbGRzW2ldLCBub2RldHlwZSwgcGF0aHMpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIFBvbHlUcmVlVG9QYXRocyhjb25zdCBQb2x5VHJlZSYgcG9seXRyZWUsIFBhdGhzJiBwYXRocykKewogIHBhdGhzLnJlc2l6ZSgwKTsgCiAgcGF0aHMucmVzZXJ2ZShwb2x5dHJlZS5Ub3RhbCgpKTsKICBBZGRQb2x5Tm9kZVRvUGF0aHMocG9seXRyZWUsIG50QW55LCBwYXRocyk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgQ2xvc2VkUGF0aHNGcm9tUG9seVRyZWUoY29uc3QgUG9seVRyZWUmIHBvbHl0cmVlLCBQYXRocyYgcGF0aHMpCnsKICBwYXRocy5yZXNpemUoMCk7IAogIHBhdGhzLnJlc2VydmUocG9seXRyZWUuVG90YWwoKSk7CiAgQWRkUG9seU5vZGVUb1BhdGhzKHBvbHl0cmVlLCBudENsb3NlZCwgcGF0aHMpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIE9wZW5QYXRoc0Zyb21Qb2x5VHJlZShQb2x5VHJlZSYgcG9seXRyZWUsIFBhdGhzJiBwYXRocykKewogIHBhdGhzLnJlc2l6ZSgwKTsgCiAgcGF0aHMucmVzZXJ2ZShwb2x5dHJlZS5Ub3RhbCgpKTsKICAvL09wZW4gcGF0aHMgYXJlIHRvcCBsZXZlbCBvbmx5LCBzbyAuLi4KICBmb3IgKGludCBpID0gMDsgaSA8IHBvbHl0cmVlLkNoaWxkQ291bnQoKTsgKytpKQogICAgaWYgKHBvbHl0cmVlLkNoaWxkc1tpXS0+SXNPcGVuKCkpCiAgICAgIHBhdGhzLnB1c2hfYmFjayhwb2x5dHJlZS5DaGlsZHNbaV0tPkNvbnRvdXIpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yIDw8KHN0ZDo6b3N0cmVhbSAmcywgY29uc3QgSW50UG9pbnQgJnApCnsKICBzIDw8ICIoIiA8PCBwLlggPDwgIiwiIDw8IHAuWSA8PCAiKSI7CiAgcmV0dXJuIHM7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnN0ZDo6b3N0cmVhbSYgb3BlcmF0b3IgPDwoc3RkOjpvc3RyZWFtICZzLCBjb25zdCBQYXRoICZwKQp7CiAgaWYgKHAuZW1wdHkoKSkgcmV0dXJuIHM7CiAgUGF0aDo6c2l6ZV90eXBlIGxhc3QgPSBwLnNpemUoKSAtMTsKICBmb3IgKFBhdGg6OnNpemVfdHlwZSBpID0gMDsgaSA8IGxhc3Q7IGkrKykKICAgIHMgPDwgIigiIDw8IHBbaV0uWCA8PCAiLCIgPDwgcFtpXS5ZIDw8ICIpLCAiOwogIHMgPDwgIigiIDw8IHBbbGFzdF0uWCA8PCAiLCIgPDwgcFtsYXN0XS5ZIDw8ICIpXG4iOwogIHJldHVybiBzOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yIDw8KHN0ZDo6b3N0cmVhbSAmcywgY29uc3QgUGF0aHMgJnApCnsKICBmb3IgKFBhdGhzOjpzaXplX3R5cGUgaSA9IDA7IGkgPCBwLnNpemUoKTsgaSsrKQogICAgcyA8PCBwW2ldOwogIHMgPDwgIlxuIjsKICByZXR1cm4gczsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKfSAvL1F0Q2xpcHBlckxpYiBuYW1lc3BhY2UK