LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogWW91IG1heSBhbWVuZCBhbmQgZGlzdHJpYnV0ZSBhcyB5b3UgbGlrZSwgYnV0IGRvbid0IHJlbW92ZSB0aGlzIGhlYWRlciEKICoKICogRVBQbHVzIHByb3ZpZGVzIHNlcnZlci1zaWRlIGdlbmVyYXRpb24gb2YgRXhjZWwgMjAwNy8yMDEwIHNwcmVhZHNoZWV0cy4KICogU2VlIGh0dHA6Ly93d3cuY29kZXBsZXguY29tL0VQUGx1cyBmb3IgZGV0YWlscy4KICoKICogQ29weXJpZ2h0IChDKSAyMDExICBKYW4gS+RsbG1hbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIAogKiBTZWUgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBUaGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGNhbiBiZSB2aWV3ZWQgYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9sZ3BsLWxpY2Vuc2UucGhwCiAqIElmIHlvdSB1bmZhbWlsaWFyIHdpdGggdGhpcyBsaWNlbnNlIG9yIGhhdmUgcXVlc3Rpb25zIGFib3V0IGl0LCBoZXJlIGlzIGFuIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtZmFxLmh0bWwKICoKICogQWxsIGNvZGUgYW5kIGV4ZWN1dGFibGVzIGFyZSBwcm92aWRlZCAiYXMgaXMiIHdpdGggbm8gd2FycmFudHkgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCiAqIFRoZSBhdXRob3IgYWNjZXB0cyBubyBsaWFiaWxpdHkgZm9yIGFueSBkYW1hZ2Ugb3IgbG9zcyBvZiBidXNpbmVzcyB0aGF0IHRoaXMgcHJvZHVjdCBtYXkgY2F1c2UuCiAqCiAqIENvZGUgY2hhbmdlIG5vdGVzOgogKiAKICogQXV0aG9yCQkJCQkJCUNoYW5nZQkJCQkJCURhdGUKICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEphbiBL5GxsbWFuCQkgICAgSW5pdGlhbCBSZWxlYXNlCQkgICAgICAgIDIwMDktMTAtMDEKICogSmFuIEvkbGxtYW4JCSAgICBMaWNlbnNlIGNoYW5nZWQgR1BMLS0+TEdQTCAyMDExLTEyLTI3CiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp1c2luZyBTeXN0ZW07CnVzaW5nIFN5c3RlbS5YbWw7CnVzaW5nIFN5c3RlbS5MaW5xOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZy5FeGNlbC5GdW5jdGlvbnMuTG9naWNhbDsKdXNpbmcgZHJhdz1TeXN0ZW0uRHJhd2luZzsKdXNpbmcgT2ZmaWNlT3BlblhtbC5TdHlsZTsKdXNpbmcgT2ZmaWNlT3BlblhtbC5TdHlsZS5YbWxBY2Nlc3M7CnVzaW5nIE9mZmljZU9wZW5YbWwuU3R5bGUuRHhmOwp1c2luZyBPZmZpY2VPcGVuWG1sLkNvbmRpdGlvbmFsRm9ybWF0dGluZzsKbmFtZXNwYWNlIE9mZmljZU9wZW5YbWwKewoJLy8vIDxzdW1tYXJ5PgoJLy8vIENvbnRhaW50cyBhbGwgc2hhcmVkIGNlbGwgc3R5bGVzIGZvciBhIHdvcmtib29rCgkvLy8gPC9zdW1tYXJ5PgogICAgcHVibGljIHNlYWxlZCBjbGFzcyBFeGNlbFN0eWxlcyA6IFhtbEhlbHBlcgogICAgewogICAgICAgIGNvbnN0IHN0cmluZyBOdW1iZXJGb3JtYXRzUGF0aCA9ICJkOnN0eWxlU2hlZXQvZDpudW1GbXRzIjsKICAgICAgICBjb25zdCBzdHJpbmcgRm9udHNQYXRoID0gImQ6c3R5bGVTaGVldC9kOmZvbnRzIjsKICAgICAgICBjb25zdCBzdHJpbmcgRmlsbHNQYXRoID0gImQ6c3R5bGVTaGVldC9kOmZpbGxzIjsKICAgICAgICBjb25zdCBzdHJpbmcgQm9yZGVyc1BhdGggPSAiZDpzdHlsZVNoZWV0L2Q6Ym9yZGVycyI7CiAgICAgICAgY29uc3Qgc3RyaW5nIENlbGxTdHlsZVhmc1BhdGggPSAiZDpzdHlsZVNoZWV0L2Q6Y2VsbFN0eWxlWGZzIjsKICAgICAgICBjb25zdCBzdHJpbmcgQ2VsbFhmc1BhdGggPSAiZDpzdHlsZVNoZWV0L2Q6Y2VsbFhmcyI7CiAgICAgICAgY29uc3Qgc3RyaW5nIENlbGxTdHlsZXNQYXRoID0gImQ6c3R5bGVTaGVldC9kOmNlbGxTdHlsZXMiOwogICAgICAgIGNvbnN0IHN0cmluZyBkeGZzUGF0aCA9ICJkOnN0eWxlU2hlZXQvZDpkeGZzIjsKCiAgICAgICAgLy9pbnRlcm5hbCBEaWN0aW9uYXJ5PGludCwgRXhjZWxYZnM+IFN0eWxlcyA9IG5ldyBEaWN0aW9uYXJ5PGludCwgRXhjZWxYZnM+KCk7CiAgICAgICAgWG1sRG9jdW1lbnQgX3N0eWxlWG1sOwogICAgICAgIEV4Y2VsV29ya2Jvb2sgX3diOwogICAgICAgIFhtbE5hbWVzcGFjZU1hbmFnZXIgX25hbWVTcGFjZU1hbmFnZXI7CiAgICAgICAgaW50ZXJuYWwgaW50IF9uZXh0RGZ4TnVtRm10SUQgPSAxNjQ7CiAgICAgICAgaW50ZXJuYWwgRXhjZWxTdHlsZXMoWG1sTmFtZXNwYWNlTWFuYWdlciBOYW1lU3BhY2VNYW5hZ2VyLCBYbWxEb2N1bWVudCB4bWwsIEV4Y2VsV29ya2Jvb2sgd2IpIDoKICAgICAgICAgICAgYmFzZShOYW1lU3BhY2VNYW5hZ2VyLCB4bWwpCiAgICAgICAgeyAgICAgICAKICAgICAgICAgICAgX3N0eWxlWG1sPXhtbDsKICAgICAgICAgICAgX3diID0gd2I7CiAgICAgICAgICAgIF9uYW1lU3BhY2VNYW5hZ2VyID0gTmFtZVNwYWNlTWFuYWdlcjsKICAgICAgICAgICAgU2NoZW1hTm9kZU9yZGVyID0gbmV3IHN0cmluZ1tdIHsgIm51bUZtdHMiLCAiZm9udHMiLCAiZmlsbHMiLCAiYm9yZGVycyIsICJjZWxsU3R5bGVYZnMiLCAiY2VsbFhmcyIsICJjZWxsU3R5bGVzIiwgImR4ZnMiIH07CiAgICAgICAgICAgIExvYWRGcm9tRG9jdW1lbnQoKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBMb2FkcyB0aGUgc3R5bGUgWE1MIHRvIG1lbW9yeQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHJpdmF0ZSB2b2lkIExvYWRGcm9tRG9jdW1lbnQoKQogICAgICAgIHsKICAgICAgICAgICAgLy9OdW1iZXJGb3JtYXRzCiAgICAgICAgICAgIEV4Y2VsTnVtYmVyRm9ybWF0WG1sLkFkZEJ1aWxkSW4oTmFtZVNwYWNlTWFuYWdlciwgTnVtYmVyRm9ybWF0cyk7CiAgICAgICAgICAgIFhtbE5vZGUgbnVtTm9kZSA9IF9zdHlsZVhtbC5TZWxlY3RTaW5nbGVOb2RlKE51bWJlckZvcm1hdHNQYXRoLCBfbmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgIGlmIChudW1Ob2RlICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKFhtbE5vZGUgbiBpbiBudW1Ob2RlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEV4Y2VsTnVtYmVyRm9ybWF0WG1sIG5mID0gbmV3IEV4Y2VsTnVtYmVyRm9ybWF0WG1sKF9uYW1lU3BhY2VNYW5hZ2VyLCBuKTsKICAgICAgICAgICAgICAgICAgICBOdW1iZXJGb3JtYXRzLkFkZChuZi5JZCwgbmYpOwogICAgICAgICAgICAgICAgICAgIGlmIChuZi5OdW1GbXRJZCA+PSBOdW1iZXJGb3JtYXRzLk5leHRJZCkgTnVtYmVyRm9ybWF0cy5OZXh0SWQ9bmYuTnVtRm10SWQrMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9Gb250cwogICAgICAgICAgICBYbWxOb2RlIGZvbnROb2RlID0gX3N0eWxlWG1sLlNlbGVjdFNpbmdsZU5vZGUoRm9udHNQYXRoLCBfbmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgIGZvcmVhY2ggKFhtbE5vZGUgbiBpbiBmb250Tm9kZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRXhjZWxGb250WG1sIGYgPSBuZXcgRXhjZWxGb250WG1sKF9uYW1lU3BhY2VNYW5hZ2VyLCBuKTsKICAgICAgICAgICAgICAgIEZvbnRzLkFkZChmLklkLCBmKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9GaWxscwogICAgICAgICAgICBYbWxOb2RlIGZpbGxOb2RlID0gX3N0eWxlWG1sLlNlbGVjdFNpbmdsZU5vZGUoRmlsbHNQYXRoLCBfbmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgIGZvcmVhY2ggKFhtbE5vZGUgbiBpbiBmaWxsTm9kZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRXhjZWxGaWxsWG1sIGY7CiAgICAgICAgICAgICAgICBpZiAobi5GaXJzdENoaWxkICE9IG51bGwgJiYgbi5GaXJzdENoaWxkLkxvY2FsTmFtZSA9PSAiZ3JhZGllbnRGaWxsIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmID0gbmV3IEV4Y2VsR3JhZGllbnRGaWxsWG1sKF9uYW1lU3BhY2VNYW5hZ2VyLCBuKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmID0gbmV3IEV4Y2VsRmlsbFhtbChfbmFtZVNwYWNlTWFuYWdlciwgbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBGaWxscy5BZGQoZi5JZCwgZik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vQm9yZGVycwogICAgICAgICAgICBYbWxOb2RlIGJvcmRlck5vZGUgPSBfc3R5bGVYbWwuU2VsZWN0U2luZ2xlTm9kZShCb3JkZXJzUGF0aCwgX25hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICBmb3JlYWNoIChYbWxOb2RlIG4gaW4gYm9yZGVyTm9kZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRXhjZWxCb3JkZXJYbWwgYiA9IG5ldyBFeGNlbEJvcmRlclhtbChfbmFtZVNwYWNlTWFuYWdlciwgbik7CiAgICAgICAgICAgICAgICBCb3JkZXJzLkFkZChiLklkLCBiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9jZWxsU3R5bGVYZnMKICAgICAgICAgICAgWG1sTm9kZSBzdHlsZVhmc05vZGUgPSBfc3R5bGVYbWwuU2VsZWN0U2luZ2xlTm9kZShDZWxsU3R5bGVYZnNQYXRoLCBfbmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgIGlmIChzdHlsZVhmc05vZGUgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoWG1sTm9kZSBuIGluIHN0eWxlWGZzTm9kZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFeGNlbFhmcyBpdGVtID0gbmV3IEV4Y2VsWGZzKF9uYW1lU3BhY2VNYW5hZ2VyLCBuLCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICBDZWxsU3R5bGVYZnMuQWRkKGl0ZW0uSWQsIGl0ZW0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBYbWxOb2RlIHN0eWxlTm9kZSA9IF9zdHlsZVhtbC5TZWxlY3RTaW5nbGVOb2RlKENlbGxYZnNQYXRoLCBfbmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3R5bGVOb2RlLkNoaWxkTm9kZXMuQ291bnQ7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWG1sTm9kZSBuID0gc3R5bGVOb2RlLkNoaWxkTm9kZXNbaV07CiAgICAgICAgICAgICAgICBFeGNlbFhmcyBpdGVtID0gbmV3IEV4Y2VsWGZzKF9uYW1lU3BhY2VNYW5hZ2VyLCBuLCB0aGlzKTsKICAgICAgICAgICAgICAgIENlbGxYZnMuQWRkKGl0ZW0uSWQsIGl0ZW0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvL2NlbGxTdHlsZQogICAgICAgICAgICBYbWxOb2RlIG5hbWVkU3R5bGVOb2RlID0gX3N0eWxlWG1sLlNlbGVjdFNpbmdsZU5vZGUoQ2VsbFN0eWxlc1BhdGgsIF9uYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgaWYgKG5hbWVkU3R5bGVOb2RlICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKFhtbE5vZGUgbiBpbiBuYW1lZFN0eWxlTm9kZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFeGNlbE5hbWVkU3R5bGVYbWwgaXRlbSA9IG5ldyBFeGNlbE5hbWVkU3R5bGVYbWwoX25hbWVTcGFjZU1hbmFnZXIsIG4sIHRoaXMpOwogICAgICAgICAgICAgICAgICAgIE5hbWVkU3R5bGVzLkFkZChpdGVtLk5hbWUsIGl0ZW0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvL2R4ZnNQYXRoCiAgICAgICAgICAgIFhtbE5vZGUgZHhmc05vZGUgPSBfc3R5bGVYbWwuU2VsZWN0U2luZ2xlTm9kZShkeGZzUGF0aCwgX25hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICBpZiAoZHhmc05vZGUgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoWG1sTm9kZSB4IGluIGR4ZnNOb2RlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEV4Y2VsRHhmU3R5bGVDb25kaXRpb25hbEZvcm1hdHRpbmcgaXRlbSA9IG5ldyBFeGNlbER4ZlN0eWxlQ29uZGl0aW9uYWxGb3JtYXR0aW5nKF9uYW1lU3BhY2VNYW5hZ2VyLCB4LCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICBEeGZzLkFkZChpdGVtLklkLCBpdGVtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbCBFeGNlbFN0eWxlIEdldFN0eWxlT2JqZWN0KGludCBJZCxpbnQgUG9zaXRpb25JRCwgc3RyaW5nIEFkZHJlc3MpCiAgICAgICAgewogICAgICAgICAgICBpZiAoSWQgPCAwKSBJZCA9IDA7CiAgICAgICAgICAgIHJldHVybiBuZXcgRXhjZWxTdHlsZSh0aGlzLCBQcm9wZXJ0eUNoYW5nZSwgUG9zaXRpb25JRCwgQWRkcmVzcywgSWQpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEhhbmRlbHMgY2hhbmdlcyBvZiBwcm9wZXJ0aWVzIG9uIHRoZSBzdHlsZSBvYmplY3RzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNlbmRlciI+PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImUiPjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBpbnRlcm5hbCBpbnQgUHJvcGVydHlDaGFuZ2UoU3R5bGVCYXNlIHNlbmRlciwgU3R5bGUuU3R5bGVDaGFuZ2VFdmVudEFyZ3MgZSkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBhZGRyZXNzID0gbmV3IEV4Y2VsQWRkcmVzc0Jhc2UoZS5BZGRyZXNzKTsKICAgICAgICAgICAgdmFyIHdzID0gX3diLldvcmtzaGVldHNbZS5Qb3NpdGlvbklEXTsKICAgICAgICAgICAgRGljdGlvbmFyeTxpbnQsIGludD4gc3R5bGVDYXNoZSA9IG5ldyBEaWN0aW9uYXJ5PGludCwgaW50PigpOwogICAgICAgICAgICAvL1NldCBzaW5nbGUgYWRkcmVzcwogICAgICAgICAgICBsb2NrICh3cy5fc3R5bGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTZXRTdHlsZUFkZHJlc3Moc2VuZGVyLCBlLCBhZGRyZXNzLCB3cywgcmVmIHN0eWxlQ2FzaGUpOwogICAgICAgICAgICAgICAgaWYgKGFkZHJlc3MuQWRkcmVzc2VzICE9IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy9IYW5kbGUgbXVsdGlhZGRyZXNzZXMKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgaW5uZXJBZGRyZXNzIGluIGFkZHJlc3MuQWRkcmVzc2VzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgU2V0U3R5bGVBZGRyZXNzKHNlbmRlciwgZSwgaW5uZXJBZGRyZXNzLCB3cywgcmVmIHN0eWxlQ2FzaGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBTZXRTdHlsZUFkZHJlc3MoU3R5bGVCYXNlIHNlbmRlciwgU3R5bGUuU3R5bGVDaGFuZ2VFdmVudEFyZ3MgZSwgRXhjZWxBZGRyZXNzQmFzZSBhZGRyZXNzLCBFeGNlbFdvcmtzaGVldCB3cywgcmVmIERpY3Rpb25hcnk8aW50LCBpbnQ+IHN0eWxlQ2FzaGUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoYWRkcmVzcy5TdGFydC5Db2x1bW4gPT0gMCB8fCBhZGRyZXNzLlN0YXJ0LlJvdyA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEV4Y2VwdGlvbigiZXJyb3IgYWRkcmVzcyIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL0NvbHVtbnMKICAgICAgICAgICAgZWxzZSBpZiAoYWRkcmVzcy5TdGFydC5Sb3cgPT0gMSAmJiBhZGRyZXNzLkVuZC5Sb3cgPT0gRXhjZWxQYWNrYWdlLk1heFJvd3MpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEV4Y2VsQ29sdW1uIGNvbHVtbjsKICAgICAgICAgICAgICAgIGludCBjb2wgPSBhZGRyZXNzLlN0YXJ0LkNvbHVtbiwgcm93ID0gMDsKICAgICAgICAgICAgICAgIC8vR2V0IHRoZSBzdGFydGNvbHVtbgogICAgICAgICAgICAgICAgaWYgKCF3cy5fdmFsdWVzLkV4aXN0cygwLCBhZGRyZXNzLlN0YXJ0LkNvbHVtbikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY29sdW1uID0gd3MuQ29sdW1uKGFkZHJlc3MuU3RhcnQuQ29sdW1uKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjb2x1bW4gPSAoRXhjZWxDb2x1bW4pd3MuX3ZhbHVlcy5HZXRWYWx1ZSgwLCBhZGRyZXNzLlN0YXJ0LkNvbHVtbik7CiAgICAgICAgICAgICAgICB9CgoKICAgICAgICAgICAgICAgIHdoaWxlIChjb2x1bW4uQ29sdW1uTWluIDw9IGFkZHJlc3MuRW5kLkNvbHVtbikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY29sdW1uLkNvbHVtbk1heCA+IGFkZHJlc3MuRW5kLkNvbHVtbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdDb2wgPSB3cy5Db3B5Q29sdW1uKGNvbHVtbiwgYWRkcmVzcy5FbmQuQ29sdW1uICsgMSwgY29sdW1uLkNvbHVtbk1heCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbi5Db2x1bW5NYXggPSBhZGRyZXNzLkVuZC5Db2x1bW47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBzID0gd3MuX3N0eWxlcy5HZXRWYWx1ZSgwLCBjb2x1bW4uQ29sdW1uTWluKTsKICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGVDYXNoZS5Db250YWluc0tleShzKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdzLlNldFN0eWxlKDAsIGNvbHVtbi5Db2x1bW5NaW4sIHN0eWxlQ2FzaGVbc10pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBFeGNlbFhmcyBzdCA9IENlbGxYZnNbc107CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBuZXdJZCA9IHN0LkdldE5ld0lEKENlbGxYZnMsIHNlbmRlciwgZS5TdHlsZUNsYXNzLCBlLlN0eWxlUHJvcGVydHksIGUuVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICBzdHlsZUNhc2hlLkFkZChzLCBuZXdJZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHdzLlNldFN0eWxlKDAsIGNvbHVtbi5Db2x1bW5NaW4sIG5ld0lkKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vaW5kZXgrKzsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCF3cy5fdmFsdWVzLk5leHRDZWxsKHJlZiByb3csIHJlZiBjb2wpIHx8IHJvdyA+IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW4uX2NvbHVtbk1heCA9IGFkZHJlc3MuRW5kLkNvbHVtbjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbiA9ICh3cy5fdmFsdWVzLkdldFZhbHVlKDAsIGNvbCkgYXMgRXhjZWxDb2x1bW4pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoY29sdW1uLl9jb2x1bW5NYXggPCBhZGRyZXNzLkVuZC5Db2x1bW4pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5ld0NvbCA9IHdzLkNvbHVtbihjb2x1bW4uX2NvbHVtbk1heCArIDEpIGFzIEV4Y2VsQ29sdW1uOwogICAgICAgICAgICAgICAgICAgIG5ld0NvbC5fY29sdW1uTWF4ID0gYWRkcmVzcy5FbmQuQ29sdW1uOwoKICAgICAgICAgICAgICAgICAgICB2YXIgcyA9IHdzLl9zdHlsZXMuR2V0VmFsdWUoMCwgY29sdW1uLkNvbHVtbk1pbik7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0eWxlQ2FzaGUuQ29udGFpbnNLZXkocykpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB3cy5TZXRTdHlsZSgwLCBjb2x1bW4uQ29sdW1uTWluLCBzdHlsZUNhc2hlW3NdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxYZnMgc3QgPSBDZWxsWGZzW3NdOwogICAgICAgICAgICAgICAgICAgICAgICBpbnQgbmV3SWQgPSBzdC5HZXROZXdJRChDZWxsWGZzLCBzZW5kZXIsIGUuU3R5bGVDbGFzcywgZS5TdHlsZVByb3BlcnR5LCBlLlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGVDYXNoZS5BZGQocywgbmV3SWQpOwogICAgICAgICAgICAgICAgICAgICAgICB3cy5TZXRTdHlsZSgwLCBjb2x1bW4uQ29sdW1uTWluLCBuZXdJZCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBjb2x1bW4uX2NvbHVtbk1heCA9IGFkZHJlc3MuRW5kLkNvbHVtbjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvL1NldCBmb3IgaW5kaXZpZHVhbCBjZWxscyBpbiB0aGUgc3Bhbi4gV2UgbG9vcCBhbGwgY2VsbHMgaGVyZSBzaW5jZSB0aGUgY2VsbHMgYXJlIHNvcnRlZCB3aXRoIGNvbHVtbnMgZmlyc3QuCiAgICAgICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPGludD4od3MuX3N0eWxlcywgMSwgYWRkcmVzcy5fZnJvbUNvbCwgYWRkcmVzcy5fdG9Sb3csIGFkZHJlc3MuX3RvQ29sKTsKICAgICAgICAgICAgICAgIHdoaWxlIChjc2UuTmV4dCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjc2UuQ29sdW1uID49IGFkZHJlc3MuU3RhcnQuQ29sdW1uICYmCiAgICAgICAgICAgICAgICAgICAgICAgIGNzZS5Db2x1bW4gPD0gYWRkcmVzcy5FbmQuQ29sdW1uKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0eWxlQ2FzaGUuQ29udGFpbnNLZXkoY3NlLlZhbHVlKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3MuU2V0U3R5bGUoY3NlLlJvdywgY3NlLkNvbHVtbiwgc3R5bGVDYXNoZVtjc2UuVmFsdWVdKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VsWGZzIHN0ID0gQ2VsbFhmc1tjc2UuVmFsdWVdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5ld0lkID0gc3QuR2V0TmV3SUQoQ2VsbFhmcywgc2VuZGVyLCBlLlN0eWxlQ2xhc3MsIGUuU3R5bGVQcm9wZXJ0eSwgZS5WYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZUNhc2hlLkFkZChjc2UuVmFsdWUsIG5ld0lkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzZS5WYWx1ZSA9IG5ld0lkOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy93cy5TZXRTdHlsZShjc2UuUm93LCBjc2UuQ29sdW1uLCBuZXdJZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy9VcGRhdGUgY2VsbHMgd2l0aCBzdHlsZWQgY29sdW1ucwogICAgICAgICAgICAgICAgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPGludD4od3MuX3N0eWxlcywgMSwgMCwgYWRkcmVzcy5fdG9Sb3csIDApOwogICAgICAgICAgICAgICAgd2hpbGUgKGNzZS5OZXh0KCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgYyA9IGFkZHJlc3MuX2Zyb21Sb3c7IGMgPD0gYWRkcmVzcy5fdG9Db2w7IGMrKykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghd3MuX3N0eWxlcy5FeGlzdHMoY3NlLlJvdywgYykpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHlsZUNhc2hlLkNvbnRhaW5zS2V5KGNzZS5WYWx1ZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3MuU2V0U3R5bGUoY3NlLlJvdywgYywgc3R5bGVDYXNoZVtjc2UuVmFsdWVdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeGNlbFhmcyBzdCA9IENlbGxYZnNbY3NlLlZhbHVlXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbmV3SWQgPSBzdC5HZXROZXdJRChDZWxsWGZzLCBzZW5kZXIsIGUuU3R5bGVDbGFzcywgZS5TdHlsZVByb3BlcnR5LCBlLlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZUNhc2hlLkFkZChjc2UuVmFsdWUsIG5ld0lkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cy5TZXRTdHlsZShjc2UuUm93LCBjLCBuZXdJZCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vUm93cwogICAgICAgICAgICBlbHNlIGlmIChhZGRyZXNzLlN0YXJ0LkNvbHVtbiA9PSAxICYmIGFkZHJlc3MuRW5kLkNvbHVtbiA9PSBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChpbnQgcm93TnVtID0gYWRkcmVzcy5TdGFydC5Sb3c7IHJvd051bSA8PSBhZGRyZXNzLkVuZC5Sb3c7IHJvd051bSsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciBzID0gd3MuX3N0eWxlcy5HZXRWYWx1ZShyb3dOdW0sIDApOwogICAgICAgICAgICAgICAgICAgIGlmIChzID09IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvL2l0ZXJhdGUgYWxsIGNvbHVtbnMgYW5kIHNldCB0aGUgcm93IHRvIHRoZSBzdHlsZSBvZiB0aGUgbGFzdCBjb2x1bW4KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxpbnQ+KHdzLl9zdHlsZXMsIDAsIDEsIDAsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNzZS5OZXh0KCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBjc2UuVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IHdzLl92YWx1ZXMuR2V0VmFsdWUoY3NlLlJvdywgY3NlLkNvbHVtbikgYXMgRXhjZWxDb2x1bW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYyAhPSBudWxsICYmIGMuQ29sdW1uTWF4IDwgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgY29sID0gYy5Db2x1bW5NaW47IGNvbCA8IGMuQ29sdW1uTWF4OyBjb2wrKykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghd3MuX3N0eWxlcy5FeGlzdHMocm93TnVtLCBjb2wpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cy5fc3R5bGVzLlNldFZhbHVlKHJvd051bSwgY29sLCBzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB3cy5TZXRTdHlsZShyb3dOdW0sIDAsIHMpOwogICAgICAgICAgICAgICAgICAgICAgICBjc2UuRGlzcG9zZSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGVDYXNoZS5Db250YWluc0tleShzKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdzLlNldFN0eWxlKHJvd051bSwgMCwgc3R5bGVDYXNoZVtzXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VsWGZzIHN0ID0gQ2VsbFhmc1tzXTsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5ld0lkID0gc3QuR2V0TmV3SUQoQ2VsbFhmcywgc2VuZGVyLCBlLlN0eWxlQ2xhc3MsIGUuU3R5bGVQcm9wZXJ0eSwgZS5WYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlQ2FzaGUuQWRkKHMsIG5ld0lkKTsKICAgICAgICAgICAgICAgICAgICAgICAgd3MuX3N0eWxlcy5TZXRWYWx1ZShyb3dOdW0sIDAsIG5ld0lkKTsKICAgICAgICAgICAgICAgICAgICAgICAgd3MuU2V0U3R5bGUocm93TnVtLCAwLCBuZXdJZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vVXBkYXRlIGluZGl2aWR1YWwgY2VsbHMgCiAgICAgICAgICAgICAgICB2YXIgY3NlMiA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxpbnQ+KHdzLl9zdHlsZXMsIGFkZHJlc3MuX2Zyb21Sb3csIGFkZHJlc3MuX2Zyb21Db2wsIGFkZHJlc3MuX3RvUm93LCBhZGRyZXNzLl90b0NvbCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoY3NlMi5OZXh0KCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHMgPSBjc2UyLlZhbHVlOwogICAgICAgICAgICAgICAgICAgIGlmIChzdHlsZUNhc2hlLkNvbnRhaW5zS2V5KHMpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgd3MuU2V0U3R5bGUoY3NlMi5Sb3csIGNzZTIuQ29sdW1uLCBzdHlsZUNhc2hlW3NdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxYZnMgc3QgPSBDZWxsWGZzW3NdOwogICAgICAgICAgICAgICAgICAgICAgICBpbnQgbmV3SWQgPSBzdC5HZXROZXdJRChDZWxsWGZzLCBzZW5kZXIsIGUuU3R5bGVDbGFzcywgZS5TdHlsZVByb3BlcnR5LCBlLlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGVDYXNoZS5BZGQocywgbmV3SWQpOwogICAgICAgICAgICAgICAgICAgICAgICBjc2UyLlZhbHVlID0gbmV3SWQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vVXBkYXRlIGNlbGxzIHdpdGggc3R5bGVkIHJvd3MKICAgICAgICAgICAgICAgIGNzZTIgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8aW50Pih3cy5fc3R5bGVzLCAwLCAxLCAwLCBhZGRyZXNzLl90b0NvbCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoY3NlMi5OZXh0KCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgciA9IGFkZHJlc3MuX2Zyb21Sb3c7IHIgPD0gYWRkcmVzcy5fdG9Sb3c7IHIrKykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghd3MuX3N0eWxlcy5FeGlzdHMociwgY3NlMi5Db2x1bW4pKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcyA9IGNzZTIuVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGVDYXNoZS5Db250YWluc0tleShzKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cy5TZXRTdHlsZShyLCBjc2UyLkNvbHVtbiwgc3R5bGVDYXNoZVtzXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxYZnMgc3QgPSBDZWxsWGZzW3NdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuZXdJZCA9IHN0LkdldE5ld0lEKENlbGxYZnMsIHNlbmRlciwgZS5TdHlsZUNsYXNzLCBlLlN0eWxlUHJvcGVydHksIGUuVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlQ2FzaGUuQWRkKHMsIG5ld0lkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cy5TZXRTdHlsZShyLCBjc2UyLkNvbHVtbiwgbmV3SWQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgICAgICAgICAgICAgLy9DZWxscmFuZ2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChpbnQgY29sID0gYWRkcmVzcy5TdGFydC5Db2x1bW47IGNvbCA8PSBhZGRyZXNzLkVuZC5Db2x1bW47IGNvbCsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHJvdyA9IGFkZHJlc3MuU3RhcnQuUm93OyByb3cgPD0gYWRkcmVzcy5FbmQuUm93OyByb3crKykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzID0gR2V0U3R5bGVJZCh3cywgcm93LCBjb2wpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGVDYXNoZS5Db250YWluc0tleShzKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3MuU2V0U3R5bGUocm93LCBjb2wsIHN0eWxlQ2FzaGVbc10pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxYZnMgc3QgPSBDZWxsWGZzW3NdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5ld0lkID0gc3QuR2V0TmV3SUQoQ2VsbFhmcywgc2VuZGVyLCBlLlN0eWxlQ2xhc3MsIGUuU3R5bGVQcm9wZXJ0eSwgZS5WYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZUNhc2hlLkFkZChzLCBuZXdJZCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cy5TZXRTdHlsZShyb3csIGNvbCwgbmV3SWQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpbnRlcm5hbCBpbnQgR2V0U3R5bGVJZChFeGNlbFdvcmtzaGVldCB3cywgaW50IHJvdywgaW50IGNvbCkKICAgICAgICB7CiAgICAgICAgICAgIGludCB2PTA7CiAgICAgICAgICAgIGlmICh3cy5fc3R5bGVzLkV4aXN0cyhyb3csIGNvbCwgcmVmIHYpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh3cy5fc3R5bGVzLkV4aXN0cyhyb3csIDAsIHJlZiB2KSkgLy9GaXJzdCBSb3cKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgLy8gdGhlbiBjb2x1bW4KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAod3MuX3N0eWxlcy5FeGlzdHMoMCwgY29sLCByZWYgdikpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdjsgCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpbnQgcj0wLGM9Y29sOwogICAgICAgICAgICAgICAgICAgICAgICBpZih3cy5fdmFsdWVzLlByZXZDZWxsKHJlZiByLHJlZiBjKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbHVtbj13cy5fdmFsdWVzLkdldFZhbHVlKDAsYykgYXMgRXhjZWxDb2x1bW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29sdW1uICE9IG51bGwgJiYgY29sdW1uLkNvbHVtbk1heCA+PSBjb2wpIC8vRml4ZXMgaXNzdWUgMTUxNzQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gd3MuX3N0eWxlcy5HZXRWYWx1ZSgwLCBjKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBIYW5kbGVzIHByb3BlcnR5IGNoYW5nZXMgb24gTmFtZWQgc3R5bGVzLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzZW5kZXIiPjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJlIj48L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+CiAgICAgICAgaW50ZXJuYWwgaW50IE5hbWVkU3R5bGVQcm9wZXJ0eUNoYW5nZShTdHlsZUJhc2Ugc2VuZGVyLCBTdHlsZS5TdHlsZUNoYW5nZUV2ZW50QXJncyBlKQogICAgICAgIHsKCiAgICAgICAgICAgIGludCBpbmRleCA9IE5hbWVkU3R5bGVzLkZpbmRJbmRleEJ5SUQoZS5BZGRyZXNzKTsKICAgICAgICAgICAgaWYgKGluZGV4ID49IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCBuZXdJZCA9IENlbGxTdHlsZVhmc1tOYW1lZFN0eWxlc1tpbmRleF0uU3R5bGVYZklkXS5HZXROZXdJRChDZWxsU3R5bGVYZnMsIHNlbmRlciwgZS5TdHlsZUNsYXNzLCBlLlN0eWxlUHJvcGVydHksIGUuVmFsdWUpOwogICAgICAgICAgICAgICAgaW50IHByZXZJeD1OYW1lZFN0eWxlc1tpbmRleF0uU3R5bGVYZklkOwogICAgICAgICAgICAgICAgTmFtZWRTdHlsZXNbaW5kZXhdLlN0eWxlWGZJZCA9IG5ld0lkOwogICAgICAgICAgICAgICAgTmFtZWRTdHlsZXNbaW5kZXhdLlN0eWxlLkluZGV4ID0gbmV3SWQ7CgogICAgICAgICAgICAgICAgTmFtZWRTdHlsZXNbaW5kZXhdLlhmSWQgPSBpbnQuTWluVmFsdWU7CiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgc3R5bGUgaW4gQ2VsbFhmcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGUuWGZJZCA9PSBwcmV2SXgpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdHlsZS5YZklkID0gbmV3SWQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgRXhjZWxTdHlsZUNvbGxlY3Rpb248RXhjZWxOdW1iZXJGb3JtYXRYbWw+IE51bWJlckZvcm1hdHMgPSBuZXcgRXhjZWxTdHlsZUNvbGxlY3Rpb248RXhjZWxOdW1iZXJGb3JtYXRYbWw+KCk7CiAgICAgICAgcHVibGljIEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsRm9udFhtbD4gRm9udHMgPSBuZXcgRXhjZWxTdHlsZUNvbGxlY3Rpb248RXhjZWxGb250WG1sPigpOwogICAgICAgIHB1YmxpYyBFeGNlbFN0eWxlQ29sbGVjdGlvbjxFeGNlbEZpbGxYbWw+IEZpbGxzID0gbmV3IEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsRmlsbFhtbD4oKTsKICAgICAgICBwdWJsaWMgRXhjZWxTdHlsZUNvbGxlY3Rpb248RXhjZWxCb3JkZXJYbWw+IEJvcmRlcnMgPSBuZXcgRXhjZWxTdHlsZUNvbGxlY3Rpb248RXhjZWxCb3JkZXJYbWw+KCk7CiAgICAgICAgcHVibGljIEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsWGZzPiBDZWxsU3R5bGVYZnMgPSBuZXcgRXhjZWxTdHlsZUNvbGxlY3Rpb248RXhjZWxYZnM+KCk7CiAgICAgICAgcHVibGljIEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsWGZzPiBDZWxsWGZzID0gbmV3IEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsWGZzPigpOwogICAgICAgIHB1YmxpYyBFeGNlbFN0eWxlQ29sbGVjdGlvbjxFeGNlbE5hbWVkU3R5bGVYbWw+IE5hbWVkU3R5bGVzID0gbmV3IEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsTmFtZWRTdHlsZVhtbD4oKTsKICAgICAgICBwdWJsaWMgRXhjZWxTdHlsZUNvbGxlY3Rpb248RXhjZWxEeGZTdHlsZUNvbmRpdGlvbmFsRm9ybWF0dGluZz4gRHhmcyA9IG5ldyBFeGNlbFN0eWxlQ29sbGVjdGlvbjxFeGNlbER4ZlN0eWxlQ29uZGl0aW9uYWxGb3JtYXR0aW5nPigpOwogICAgICAgIAogICAgICAgIGludGVybmFsIHN0cmluZyBJZAogICAgICAgIHsKICAgICAgICAgICAgZ2V0IHsgcmV0dXJuICIiOyB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgRXhjZWxOYW1lZFN0eWxlWG1sIENyZWF0ZU5hbWVkU3R5bGUoc3RyaW5nIG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gQ3JlYXRlTmFtZWRTdHlsZShuYW1lLCBudWxsKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIEV4Y2VsTmFtZWRTdHlsZVhtbCBDcmVhdGVOYW1lZFN0eWxlKHN0cmluZyBuYW1lLCBFeGNlbFN0eWxlIFRlbXBsYXRlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKF93Yi5TdHlsZXMuTmFtZWRTdHlsZXMuRXhpc3RzS2V5KG5hbWUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKHN0cmluZy5Gb3JtYXQoIktleSB7MH0gYWxyZWFkeSBleGlzdHMgaW4gY29sbGVjdGlvbiIsIG5hbWUpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgRXhjZWxOYW1lZFN0eWxlWG1sIHN0eWxlOwogICAgICAgICAgICBzdHlsZSA9IG5ldyBFeGNlbE5hbWVkU3R5bGVYbWwoTmFtZVNwYWNlTWFuYWdlciwgdGhpcyk7CiAgICAgICAgICAgIGludCB4ZklkQ29weSwgcG9zaXRpb25JRDsKICAgICAgICAgICAgRXhjZWxTdHlsZXMgc3R5bGVzOwogICAgICAgICAgICBpZiAoVGVtcGxhdGUgPT0gbnVsbCkKICAgICAgICAgICAgewovLyAgICAgICAgICAgICAgICBzdHlsZS5TdHlsZSA9IG5ldyBFeGNlbFN0eWxlKHRoaXMsIE5hbWVkU3R5bGVQcm9wZXJ0eUNoYW5nZSwgLTEsIG5hbWUsIDApOwogICAgICAgICAgICAgICAgeGZJZENvcHkgPSAwOwogICAgICAgICAgICAgICAgcG9zaXRpb25JRCA9IC0xOwogICAgICAgICAgICAgICAgc3R5bGVzID0gdGhpczsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChUZW1wbGF0ZS5Qb3NpdGlvbklEIDwgMCAmJiBUZW1wbGF0ZS5TdHlsZXM9PXRoaXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeGZJZENvcHkgPSBUZW1wbGF0ZS5JbmRleDsKICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbklEPVRlbXBsYXRlLlBvc2l0aW9uSUQ7CiAgICAgICAgICAgICAgICAgICAgc3R5bGVzID0gdGhpczsKICAgICAgICAgICAgICAgICAgICAvL3N0eWxlLlN0eWxlID0gbmV3IEV4Y2VsU3R5bGUodGhpcywgTmFtZWRTdHlsZVByb3BlcnR5Q2hhbmdlLCBUZW1wbGF0ZS5Qb3NpdGlvbklELCBuYW1lLCBUZW1wbGF0ZS5JbmRleCk7CiAgICAgICAgICAgICAgICAgICAgLy9zdHlsZS5TdHlsZVhmSWQgPSBUZW1wbGF0ZS5JbmRleDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4ZklkQ29weSA9IFRlbXBsYXRlLlhmSWQ7CiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25JRCA9IC0xOwogICAgICAgICAgICAgICAgICAgIHN0eWxlcyA9IFRlbXBsYXRlLlN0eWxlczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvL0Nsb25lIG5hbWVkc3R5bGUKICAgICAgICAgICAgaW50IHN0eWxlWGZJZCA9IENsb25lU3R5bGUoc3R5bGVzLCB4ZklkQ29weSwgdHJ1ZSk7CiAgICAgICAgICAgIC8vQ2xvc2UgY2VsbHMgc3R5bGUKICAgICAgICAgICAgQ2VsbFN0eWxlWGZzW3N0eWxlWGZJZF0uWGZJZCA9IENlbGxTdHlsZVhmcy5Db3VudC0xOwogICAgICAgICAgICBpbnQgeGZpZCA9IENsb25lU3R5bGUoc3R5bGVzLCB4ZklkQ29weSwgZmFsc2UsIHRydWUpOyAvL0Fsd2F5cyBhZGQgYSBuZXcgc3R5bGUgKFdlIGNyZWF0ZSBhIG5ldyBuYW1lZCBzdHlsZSBoZXJlKQogICAgICAgICAgICBDZWxsWGZzW3hmaWRdLlhmSWQgPSBzdHlsZVhmSWQ7CiAgICAgICAgICAgIHN0eWxlLlN0eWxlID0gbmV3IEV4Y2VsU3R5bGUodGhpcywgTmFtZWRTdHlsZVByb3BlcnR5Q2hhbmdlLCBwb3NpdGlvbklELCBuYW1lLCBzdHlsZVhmSWQpOwogICAgICAgICAgICBzdHlsZS5TdHlsZVhmSWQgPSBzdHlsZVhmSWQ7CiAgICAgICAgICAgIAogICAgICAgICAgICBzdHlsZS5OYW1lID0gbmFtZTsKICAgICAgICAgICAgaW50IGl4ID1fd2IuU3R5bGVzLk5hbWVkU3R5bGVzLkFkZChzdHlsZS5OYW1lLCBzdHlsZSk7CiAgICAgICAgICAgIHN0eWxlLlN0eWxlLlNldEluZGV4KGl4KTsKICAgICAgICAgICAgLy9zdHlsZS5TdHlsZS5YZklkID0gaXg7CiAgICAgICAgICAgIHJldHVybiBzdHlsZTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHZvaWQgVXBkYXRlWG1sKCkKICAgICAgICB7CiAgICAgICAgICAgIFJlbW92ZVVudXNlZFN0eWxlcygpOwoKICAgICAgICAgICAgLy9OdW1iZXJGb3JtYXQKICAgICAgICAgICAgWG1sTm9kZSBuZk5vZGU9X3N0eWxlWG1sLlNlbGVjdFNpbmdsZU5vZGUoTnVtYmVyRm9ybWF0c1BhdGgsIF9uYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgaWYgKG5mTm9kZSA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDcmVhdGVOb2RlKE51bWJlckZvcm1hdHNQYXRoLCB0cnVlKTsKICAgICAgICAgICAgICAgIG5mTm9kZSA9IF9zdHlsZVhtbC5TZWxlY3RTaW5nbGVOb2RlKE51bWJlckZvcm1hdHNQYXRoLCBfbmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBuZk5vZGUuUmVtb3ZlQWxsKCk7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CgogICAgICAgICAgICBpbnQgY291bnQgPSAwOwogICAgICAgICAgICBpbnQgbm9ybWFsSXggPSBOYW1lZFN0eWxlcy5GaW5kSW5kZXhCeUlEKCJOb3JtYWwiKTsKICAgICAgICAgICAgaWYgKE5hbWVkU3R5bGVzLkNvdW50ID4gMCAmJiBub3JtYWxJeD49MCAmJiBOYW1lZFN0eWxlc1tub3JtYWxJeF0uU3R5bGUuTnVtYmVyZm9ybWF0Lk51bUZtdElEID49IDE2NCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRXhjZWxOdW1iZXJGb3JtYXRYbWwgbmYgPSBOdW1iZXJGb3JtYXRzW051bWJlckZvcm1hdHMuRmluZEluZGV4QnlJRChOYW1lZFN0eWxlc1tub3JtYWxJeF0uU3R5bGUuTnVtYmVyZm9ybWF0LklkKV07CiAgICAgICAgICAgICAgICBuZk5vZGUuQXBwZW5kQ2hpbGQobmYuQ3JlYXRlWG1sTm9kZShfc3R5bGVYbWwuQ3JlYXRlRWxlbWVudCgibnVtRm10IiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pKSk7CiAgICAgICAgICAgICAgICBuZi5uZXdJRCA9IGNvdW50Kys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAoRXhjZWxOdW1iZXJGb3JtYXRYbWwgbmYgaW4gTnVtYmVyRm9ybWF0cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoIW5mLkJ1aWxkSW4gLyomJiBuZi5uZXdJRDwwKi8pIC8vQnVpbGRpbiBmb3JtYXRzIGFyZSBub3QgdXBkYXRlZC4KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBuZk5vZGUuQXBwZW5kQ2hpbGQobmYuQ3JlYXRlWG1sTm9kZShfc3R5bGVYbWwuQ3JlYXRlRWxlbWVudCgibnVtRm10IiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pKSk7CiAgICAgICAgICAgICAgICAgICAgbmYubmV3SUQgPSBjb3VudDsKICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIChuZk5vZGUgYXMgWG1sRWxlbWVudCkuU2V0QXR0cmlidXRlKCJjb3VudCIsIGNvdW50LlRvU3RyaW5nKCkpOwoKICAgICAgICAgICAgLy9Gb250CiAgICAgICAgICAgIGNvdW50PTA7CiAgICAgICAgICAgIFhtbE5vZGUgZm50Tm9kZSA9IF9zdHlsZVhtbC5TZWxlY3RTaW5nbGVOb2RlKEZvbnRzUGF0aCwgX25hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICBmbnROb2RlLlJlbW92ZUFsbCgpOwoKICAgICAgICAgICAgLy9Ob3JtYWwgc2hvdWxkIGJlIGZpcnN0IGluIHRoZSBjb2xsZWN0aW9uCiAgICAgICAgICAgIGlmIChOYW1lZFN0eWxlcy5Db3VudCA+IDAgJiYgbm9ybWFsSXggPj0gMCAmJiBOYW1lZFN0eWxlc1tub3JtYWxJeF0uU3R5bGUuRm9udC5JbmRleCA+IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEV4Y2VsRm9udFhtbCBmbnQgPSBGb250c1tOYW1lZFN0eWxlc1tub3JtYWxJeF0uU3R5bGUuRm9udC5JbmRleF07CiAgICAgICAgICAgICAgICBmbnROb2RlLkFwcGVuZENoaWxkKGZudC5DcmVhdGVYbWxOb2RlKF9zdHlsZVhtbC5DcmVhdGVFbGVtZW50KCJmb250IiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pKSk7CiAgICAgICAgICAgICAgICBmbnQubmV3SUQgPSBjb3VudCsrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoIChFeGNlbEZvbnRYbWwgZm50IGluIEZvbnRzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZm50LnVzZUNudCA+IDAvKiAmJiBmbnQubmV3SUQ8MCovKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZudE5vZGUuQXBwZW5kQ2hpbGQoZm50LkNyZWF0ZVhtbE5vZGUoX3N0eWxlWG1sLkNyZWF0ZUVsZW1lbnQoImZvbnQiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbikpKTsKICAgICAgICAgICAgICAgICAgICBmbnQubmV3SUQgPSBjb3VudDsKICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIChmbnROb2RlIGFzIFhtbEVsZW1lbnQpLlNldEF0dHJpYnV0ZSgiY291bnQiLCBjb3VudC5Ub1N0cmluZygpKTsKCgogICAgICAgICAgICAvL0ZpbGxzCiAgICAgICAgICAgIGNvdW50ID0gMDsKICAgICAgICAgICAgWG1sTm9kZSBmaWxsc05vZGUgPSBfc3R5bGVYbWwuU2VsZWN0U2luZ2xlTm9kZShGaWxsc1BhdGgsIF9uYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgZmlsbHNOb2RlLlJlbW92ZUFsbCgpOwogICAgICAgICAgICBGaWxsc1swXS51c2VDbnQgPSAxOyAgICAvL011c3QgZXhpc3QgKG5vbmUpOyAgCiAgICAgICAgICAgIEZpbGxzWzFdLnVzZUNudCA9IDE7ICAgIC8vTXVzdCBleGlzdCAoZ3JheTEyNSk7CiAgICAgICAgICAgIGZvcmVhY2ggKEV4Y2VsRmlsbFhtbCBmaWxsIGluIEZpbGxzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZmlsbC51c2VDbnQgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZpbGxzTm9kZS5BcHBlbmRDaGlsZChmaWxsLkNyZWF0ZVhtbE5vZGUoX3N0eWxlWG1sLkNyZWF0ZUVsZW1lbnQoImZpbGwiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbikpKTsKICAgICAgICAgICAgICAgICAgICBmaWxsLm5ld0lEID0gY291bnQ7CiAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgKGZpbGxzTm9kZSBhcyBYbWxFbGVtZW50KS5TZXRBdHRyaWJ1dGUoImNvdW50IiwgY291bnQuVG9TdHJpbmcoKSk7CgogICAgICAgICAgICAvL0JvcmRlcnMKICAgICAgICAgICAgY291bnQgPSAwOwogICAgICAgICAgICBYbWxOb2RlIGJvcmRlcnNOb2RlID0gX3N0eWxlWG1sLlNlbGVjdFNpbmdsZU5vZGUoQm9yZGVyc1BhdGgsIF9uYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgYm9yZGVyc05vZGUuUmVtb3ZlQWxsKCk7CiAgICAgICAgICAgIEJvcmRlcnNbMF0udXNlQ250ID0gMTsgICAgLy9NdXN0IGV4aXN0IGJsYW5rOwogICAgICAgICAgICBmb3JlYWNoIChFeGNlbEJvcmRlclhtbCBib3JkZXIgaW4gQm9yZGVycykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGJvcmRlci51c2VDbnQgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGJvcmRlcnNOb2RlLkFwcGVuZENoaWxkKGJvcmRlci5DcmVhdGVYbWxOb2RlKF9zdHlsZVhtbC5DcmVhdGVFbGVtZW50KCJib3JkZXIiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbikpKTsKICAgICAgICAgICAgICAgICAgICBib3JkZXIubmV3SUQgPSBjb3VudDsKICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIChib3JkZXJzTm9kZSBhcyBYbWxFbGVtZW50KS5TZXRBdHRyaWJ1dGUoImNvdW50IiwgY291bnQuVG9TdHJpbmcoKSk7CgogICAgICAgICAgICBYbWxOb2RlIHN0eWxlWGZzTm9kZSA9IF9zdHlsZVhtbC5TZWxlY3RTaW5nbGVOb2RlKENlbGxTdHlsZVhmc1BhdGgsIF9uYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgaWYgKHN0eWxlWGZzTm9kZSA9PSBudWxsICYmIE5hbWVkU3R5bGVzLkNvdW50ID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ3JlYXRlTm9kZShDZWxsU3R5bGVYZnNQYXRoKTsKICAgICAgICAgICAgICAgIHN0eWxlWGZzTm9kZSA9IF9zdHlsZVhtbC5TZWxlY3RTaW5nbGVOb2RlKENlbGxTdHlsZVhmc1BhdGgsIF9uYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoTmFtZWRTdHlsZXMuQ291bnQgPiAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHlsZVhmc05vZGUuUmVtb3ZlQWxsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9OYW1lZFN0eWxlcwogICAgICAgICAgICBjb3VudCA9IG5vcm1hbEl4ID4gLTEgPyAxIDogMDsgIC8vSWYgd2UgaGF2ZSBhIG5vcm1hbCBzdHlsZSwgd2UgbWFrZSBzdXJlIGl0J3MgYWRkZWQgZmlyc3QuCgogICAgICAgICAgICBYbWxOb2RlIGNlbGxTdHlsZU5vZGUgPSBfc3R5bGVYbWwuU2VsZWN0U2luZ2xlTm9kZShDZWxsU3R5bGVzUGF0aCwgX25hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICBpZihjZWxsU3R5bGVOb2RlIT1udWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjZWxsU3R5bGVOb2RlLlJlbW92ZUFsbCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFhtbE5vZGUgY2VsbFhmc05vZGUgPSBfc3R5bGVYbWwuU2VsZWN0U2luZ2xlTm9kZShDZWxsWGZzUGF0aCwgX25hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICBjZWxsWGZzTm9kZS5SZW1vdmVBbGwoKTsKCiAgICAgICAgICAgIGlmIChOYW1lZFN0eWxlcy5Db3VudCA+IDAgJiYgbm9ybWFsSXggPj0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTmFtZWRTdHlsZXNbbm9ybWFsSXhdLm5ld0lEID0gMDsKICAgICAgICAgICAgICAgIEFkZE5hbWVkU3R5bGUoMCwgc3R5bGVYZnNOb2RlLCBjZWxsWGZzTm9kZSwgTmFtZWRTdHlsZXNbbm9ybWFsSXhdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoIChFeGNlbE5hbWVkU3R5bGVYbWwgc3R5bGUgaW4gTmFtZWRTdHlsZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghc3R5bGUuTmFtZS5FcXVhbHMoIm5vcm1hbCIsIFN0cmluZ0NvbXBhcmlzb24uSW52YXJpYW50Q3VsdHVyZUlnbm9yZUNhc2UpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEFkZE5hbWVkU3R5bGUoY291bnQrKywgc3R5bGVYZnNOb2RlLCBjZWxsWGZzTm9kZSwgc3R5bGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0eWxlLm5ld0lEID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNlbGxTdHlsZU5vZGUuQXBwZW5kQ2hpbGQoc3R5bGUuQ3JlYXRlWG1sTm9kZShfc3R5bGVYbWwuQ3JlYXRlRWxlbWVudCgiY2VsbFN0eWxlIiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNlbGxTdHlsZU5vZGUhPW51bGwpIChjZWxsU3R5bGVOb2RlIGFzIFhtbEVsZW1lbnQpLlNldEF0dHJpYnV0ZSgiY291bnQiLCBjb3VudC5Ub1N0cmluZygpKTsKICAgICAgICAgICAgaWYgKHN0eWxlWGZzTm9kZSAhPSBudWxsKSAoc3R5bGVYZnNOb2RlIGFzIFhtbEVsZW1lbnQpLlNldEF0dHJpYnV0ZSgiY291bnQiLCBjb3VudC5Ub1N0cmluZygpKTsKCiAgICAgICAgICAgIC8vQ2VsbFN0eWxlCiAgICAgICAgICAgIGludCB4Zml4ID0gMDsKICAgICAgICAgICAgZm9yZWFjaCAoRXhjZWxYZnMgeGYgaW4gQ2VsbFhmcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHhmLnVzZUNudCA+IDAgJiYgIShub3JtYWxJeCA+PSAwICYmIE5hbWVkU3R5bGVzW25vcm1hbEl4XS5YZklkID09IHhmaXgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNlbGxYZnNOb2RlLkFwcGVuZENoaWxkKHhmLkNyZWF0ZVhtbE5vZGUoX3N0eWxlWG1sLkNyZWF0ZUVsZW1lbnQoInhmIiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pKSk7CiAgICAgICAgICAgICAgICAgICAgeGYubmV3SUQgPSBjb3VudDsKICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgeGZpeCsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIChjZWxsWGZzTm9kZSBhcyBYbWxFbGVtZW50KS5TZXRBdHRyaWJ1dGUoImNvdW50IiwgY291bnQuVG9TdHJpbmcoKSk7CgogICAgICAgICAgICAvL1NldCBkeGYgc3R5bGluZyBmb3IgY29uZGl0aW9uYWwgRm9ybWF0dGluZwogICAgICAgICAgICBYbWxOb2RlIGR4ZnNOb2RlID0gX3N0eWxlWG1sLlNlbGVjdFNpbmdsZU5vZGUoZHhmc1BhdGgsIF9uYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgZm9yZWFjaCAodmFyIHdzIGluIF93Yi5Xb3Jrc2hlZXRzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAod3MgaXMgRXhjZWxDaGFydHNoZWV0KSBjb250aW51ZTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBjZiBpbiB3cy5Db25kaXRpb25hbEZvcm1hdHRpbmcpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNmLlN0eWxlLkhhc1ZhbHVlKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGl4ID0gRHhmcy5GaW5kSW5kZXhCeUlEKGNmLlN0eWxlLklkKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl4IDwgMCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChFeGNlbENvbmRpdGlvbmFsRm9ybWF0dGluZ1J1bGUpY2YpLkR4ZklkID0gRHhmcy5Db3VudDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIER4ZnMuQWRkKGNmLlN0eWxlLklkLCBjZi5TdHlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbSA9ICgoWG1sRG9jdW1lbnQpVG9wTm9kZSkuQ3JlYXRlRWxlbWVudCgiZCIsICJkeGYiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZi5TdHlsZS5DcmVhdGVOb2RlcyhuZXcgWG1sSGVscGVySW5zdGFuY2UoTmFtZVNwYWNlTWFuYWdlciwgZWxlbSksICIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4ZnNOb2RlLkFwcGVuZENoaWxkKGVsZW0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChFeGNlbENvbmRpdGlvbmFsRm9ybWF0dGluZ1J1bGUpY2YpLkR4ZklkID0gaXg7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGR4ZnNOb2RlICE9IG51bGwpIChkeGZzTm9kZSBhcyBYbWxFbGVtZW50KS5TZXRBdHRyaWJ1dGUoImNvdW50IiwgRHhmcy5Db3VudC5Ub1N0cmluZygpKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBBZGROYW1lZFN0eWxlKGludCBpZCwgWG1sTm9kZSBzdHlsZVhmc05vZGUsWG1sTm9kZSBjZWxsWGZzTm9kZSwgRXhjZWxOYW1lZFN0eWxlWG1sIHN0eWxlKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHN0eWxlWGZzID0gQ2VsbFN0eWxlWGZzW3N0eWxlLlN0eWxlWGZJZF07CiAgICAgICAgICAgIHN0eWxlWGZzTm9kZS5BcHBlbmRDaGlsZChzdHlsZVhmcy5DcmVhdGVYbWxOb2RlKF9zdHlsZVhtbC5DcmVhdGVFbGVtZW50KCJ4ZiIsIEV4Y2VsUGFja2FnZS5zY2hlbWFNYWluKSwgdHJ1ZSkpOwogICAgICAgICAgICBzdHlsZVhmcy5uZXdJRCA9IGlkOwogICAgICAgICAgICBzdHlsZVhmcy5YZklkID0gc3R5bGUuU3R5bGVYZklkOwoKICAgICAgICAgICAgdmFyIGl4ID0gQ2VsbFhmcy5GaW5kSW5kZXhCeUlEKHN0eWxlWGZzLklkKTsKICAgICAgICAgICAgaWYgKGl4IDwgMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2VsbFhmc05vZGUuQXBwZW5kQ2hpbGQoc3R5bGVYZnMuQ3JlYXRlWG1sTm9kZShfc3R5bGVYbWwuQ3JlYXRlRWxlbWVudCgieGYiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbikpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKGlkPDApIENlbGxYZnNbaXhdLlhmSWQgPSBpZDsKICAgICAgICAgICAgICAgIGNlbGxYZnNOb2RlLkFwcGVuZENoaWxkKENlbGxYZnNbaXhdLkNyZWF0ZVhtbE5vZGUoX3N0eWxlWG1sLkNyZWF0ZUVsZW1lbnQoInhmIiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pKSk7CiAgICAgICAgICAgICAgICBDZWxsWGZzW2l4XS51c2VDbnQgPSAwOwogICAgICAgICAgICAgICAgQ2VsbFhmc1tpeF0ubmV3SUQgPSBpZDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHN0eWxlLlhmSWQgPj0gMCkKICAgICAgICAgICAgICAgIHN0eWxlLlhmSWQgPSBDZWxsWGZzW3N0eWxlLlhmSWRdLm5ld0lEOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBzdHlsZS5YZklkID0gMDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBSZW1vdmVVbnVzZWRTdHlsZXMoKQogICAgICAgIHsKICAgICAgICAgICAgQ2VsbFhmc1swXS51c2VDbnQgPSAxOyAvL0ZpcnN0IGl0ZW0gaXMgYWxsd2F5cyB1c2VkLgogICAgICAgICAgICBmb3JlYWNoIChFeGNlbFdvcmtzaGVldCBzaGVldCBpbiBfd2IuV29ya3NoZWV0cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxpbnQ+KHNoZWV0Ll9zdHlsZXMpOwogICAgICAgICAgICAgICAgd2hpbGUoY3NlLk5leHQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdiA9IGNzZS5WYWx1ZTsKICAgICAgICAgICAgICAgICAgICBpZiAodiA+PSAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgQ2VsbFhmc1t2XS51c2VDbnQrKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAoRXhjZWxOYW1lZFN0eWxlWG1sIG5zIGluIE5hbWVkU3R5bGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDZWxsU3R5bGVYZnNbbnMuU3R5bGVYZklkXS51c2VDbnQrKzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoRXhjZWxYZnMgeGYgaW4gQ2VsbFhmcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHhmLnVzZUNudCA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHhmLkZvbnRJZCA+PSAwKSBGb250c1t4Zi5Gb250SWRdLnVzZUNudCsrOwogICAgICAgICAgICAgICAgICAgIGlmICh4Zi5GaWxsSWQgPj0gMCkgRmlsbHNbeGYuRmlsbElkXS51c2VDbnQrKzsKICAgICAgICAgICAgICAgICAgICBpZiAoeGYuQm9yZGVySWQgPj0gMCkgQm9yZGVyc1t4Zi5Cb3JkZXJJZF0udXNlQ250Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAoRXhjZWxYZnMgeGYgaW4gQ2VsbFN0eWxlWGZzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoeGYudXNlQ250ID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoeGYuRm9udElkID49IDApIEZvbnRzW3hmLkZvbnRJZF0udXNlQ250Kys7CiAgICAgICAgICAgICAgICAgICAgaWYgKHhmLkZpbGxJZCA+PSAwKSBGaWxsc1t4Zi5GaWxsSWRdLnVzZUNudCsrOwogICAgICAgICAgICAgICAgICAgIGlmICh4Zi5Cb3JkZXJJZCA+PSAwKSBCb3JkZXJzW3hmLkJvcmRlcklkXS51c2VDbnQrKzsgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIGludCBHZXRTdHlsZUlkRnJvbU5hbWUoc3RyaW5nIE5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpbnQgaSA9IE5hbWVkU3R5bGVzLkZpbmRJbmRleEJ5SUQoTmFtZSk7CiAgICAgICAgICAgIGlmIChpID49IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCBpZCA9IE5hbWVkU3R5bGVzW2ldLlhmSWQ7CiAgICAgICAgICAgICAgICBpZiAoaWQgPCAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGludCBzdHlsZVhmSWQ9TmFtZWRTdHlsZXNbaV0uU3R5bGVYZklkOwogICAgICAgICAgICAgICAgICAgIEV4Y2VsWGZzIG5ld1N0eWxlID0gQ2VsbFN0eWxlWGZzW3N0eWxlWGZJZF0uQ29weSgpOwogICAgICAgICAgICAgICAgICAgIG5ld1N0eWxlLlhmSWQgPSBzdHlsZVhmSWQ7CiAgICAgICAgICAgICAgICAgICAgaWQgPSBDZWxsWGZzLkZpbmRJbmRleEJ5SUQobmV3U3R5bGUuSWQpOwogICAgICAgICAgICAgICAgICAgIGlmIChpZCA8IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZCA9IENlbGxYZnMuQWRkKG5ld1N0eWxlLklkLCBuZXdTdHlsZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIE5hbWVkU3R5bGVzW2ldLlhmSWQ9aWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gaWQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgIC8vdGhyb3cobmV3IEV4Y2VwdGlvbigiTmFtZWQgc3R5bGUgZG9lcyBub3QgZXhpc3QiKSk7ICAgICAgICAJICAgICAgICAgCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICNyZWdpb24gWG1sSGVscEZ1bmN0aW9ucwogICAgICAgIHByaXZhdGUgaW50IEdldFhtbE5vZGVJbnQoWG1sTm9kZSBub2RlKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGk7CiAgICAgICAgICAgIGlmIChpbnQuVHJ5UGFyc2UoR2V0WG1sTm9kZShub2RlKSwgb3V0IGkpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgc3RyaW5nIEdldFhtbE5vZGUoWG1sTm9kZSBub2RlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChub2RlLlZhbHVlICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBub2RlLlZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgICAgICB9CiAgICAgICAgfQoKI2VuZHJlZ2lvbgogICAgICAgIGludGVybmFsIGludCBDbG9uZVN0eWxlKEV4Y2VsU3R5bGVzIHN0eWxlLCBpbnQgc3R5bGVJRCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBDbG9uZVN0eWxlKHN0eWxlLCBzdHlsZUlELCBmYWxzZSwgZmFsc2UpOwogICAgICAgIH0KICAgICAgICBpbnRlcm5hbCBpbnQgQ2xvbmVTdHlsZShFeGNlbFN0eWxlcyBzdHlsZSwgaW50IHN0eWxlSUQsIGJvb2wgaXNOYW1lZFN0eWxlKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIENsb25lU3R5bGUoc3R5bGUsIHN0eWxlSUQsIGlzTmFtZWRTdHlsZSwgZmFsc2UpOwogICAgICAgIH0KICAgICAgICBpbnRlcm5hbCBpbnQgQ2xvbmVTdHlsZShFeGNlbFN0eWxlcyBzdHlsZSwgaW50IHN0eWxlSUQsIGJvb2wgaXNOYW1lZFN0eWxlLCBib29sIGFsbHdheXNBZGQpCiAgICAgICAgewogICAgICAgICAgICBFeGNlbFhmcyB4ZnM7CiAgICAgICAgICAgIGxvY2sgKHN0eWxlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoaXNOYW1lZFN0eWxlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHhmcyA9IHN0eWxlLkNlbGxTdHlsZVhmc1tzdHlsZUlEXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4ZnMgPSBzdHlsZS5DZWxsWGZzW3N0eWxlSURdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgRXhjZWxYZnMgbmV3WGZzID0geGZzLkNvcHkodGhpcyk7CiAgICAgICAgICAgICAgICAvL051bWJlcmZvcm1hdAogICAgICAgICAgICAgICAgaWYgKHhmcy5OdW1iZXJGb3JtYXRJZCA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy9yYWtlMzY6IFR3byBwcm9ibGVtcyBoZXJlLi4uCiAgICAgICAgICAgICAgICAgICAgLy9yYWtlMzY6ICAxLiB0aGUgZmlyc3QgdGltZSB0aHJvdWdoIHdoZW4gZm9ybWF0IHN0YXlzIGVxdWFsIHRvIFN0cmluZy5FbXB0eSwgaXQgYWRkcyBhIHN0cmluZy5lbXB0eSB0byB0aGUgbGlzdCBvZiBOdW1iZXIgRm9ybWF0cwogICAgICAgICAgICAgICAgICAgIC8vcmFrZTM2OiAgMi4gd2hlbiBhZGRpbmcgYSBzZWNvbmQgc2hlZXQsIGlmIHRoZSBudW1iZXJmb3JtYXRpZCA9PSAxNjQsIGl0IGZpbmRzIHRoZSAxNjQgYWRkZWQgYnkgcHJldmlvdXMgc2hlZXRzIGJ1dCB3YXMgdXNpbmcgdGhlIGFycmF5IGluZGV4CiAgICAgICAgICAgICAgICAgICAgLy9yYWtlMzY6ICAgICAgZm9yIHRoZSBudW1iZXJmb3JtYXRpZAoKICAgICAgICAgICAgICAgICAgICBzdHJpbmcgZm9ybWF0ID0gc3RyaW5nLkVtcHR5OwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBmbXQgaW4gc3R5bGUuTnVtYmVyRm9ybWF0cykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmbXQuTnVtRm10SWQgPT0geGZzLk51bWJlckZvcm1hdElkKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQgPSBmbXQuRm9ybWF0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy9yYWtlMzY6IERvbid0IGFkZCBhbm90aGVyIGZvcm1hdCBpZiBpdCdzIGJsYW5rCiAgICAgICAgICAgICAgICAgICAgaWYgKCFTdHJpbmcuSXNOdWxsT3JFbXB0eShmb3JtYXQpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGl4ID0gTnVtYmVyRm9ybWF0cy5GaW5kSW5kZXhCeUlEKGZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpeCA8IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpdGVtID0gbmV3IEV4Y2VsTnVtYmVyRm9ybWF0WG1sKE5hbWVTcGFjZU1hbmFnZXIpIHsgRm9ybWF0ID0gZm9ybWF0LCBOdW1GbXRJZCA9IE51bWJlckZvcm1hdHMuTmV4dElkKysgfTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bWJlckZvcm1hdHMuQWRkKGZvcm1hdCwgaXRlbSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3Jha2UzNjogVXNlIHRoZSBqdXN0IGFkZGVkIGZvcm1hdCBpZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3WGZzLk51bWJlckZvcm1hdElkID0gaXRlbS5OdW1GbXRJZDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcmFrZTM2OiBVc2UgdGhlIGZvcm1hdCBpZCBkZWZpbmVkIGJ5IHRoZSBpbmRleC4uLiBub3QgdGhlIGluZGV4IGl0c2VsZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3WGZzLk51bWJlckZvcm1hdElkID0gTnVtYmVyRm9ybWF0c1tpeF0uTnVtRm10SWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy9Gb250CiAgICAgICAgICAgICAgICBpZiAoeGZzLkZvbnRJZCA+IC0xKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGludCBpeCA9IEZvbnRzLkZpbmRJbmRleEJ5SUQoeGZzLkZvbnQuSWQpOwogICAgICAgICAgICAgICAgICAgIGlmIChpeCA8IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBFeGNlbEZvbnRYbWwgaXRlbSA9IHN0eWxlLkZvbnRzW3hmcy5Gb250SWRdLkNvcHkoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaXggPSBGb250cy5BZGQoeGZzLkZvbnQuSWQsIGl0ZW0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBuZXdYZnMuRm9udElkID0gaXg7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy9Cb3JkZXIKICAgICAgICAgICAgICAgIGlmICh4ZnMuQm9yZGVySWQgPiAtMSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnQgaXggPSBCb3JkZXJzLkZpbmRJbmRleEJ5SUQoeGZzLkJvcmRlci5JZCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGl4IDwgMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VsQm9yZGVyWG1sIGl0ZW0gPSBzdHlsZS5Cb3JkZXJzW3hmcy5Cb3JkZXJJZF0uQ29weSgpOwogICAgICAgICAgICAgICAgICAgICAgICBpeCA9IEJvcmRlcnMuQWRkKHhmcy5Cb3JkZXIuSWQsIGl0ZW0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBuZXdYZnMuQm9yZGVySWQgPSBpeDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvL0ZpbGwKICAgICAgICAgICAgICAgIGlmICh4ZnMuRmlsbElkID4gLTEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaW50IGl4ID0gRmlsbHMuRmluZEluZGV4QnlJRCh4ZnMuRmlsbC5JZCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGl4IDwgMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpdGVtID0gc3R5bGUuRmlsbHNbeGZzLkZpbGxJZF0uQ29weSgpOwogICAgICAgICAgICAgICAgICAgICAgICBpeCA9IEZpbGxzLkFkZCh4ZnMuRmlsbC5JZCwgaXRlbSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG5ld1hmcy5GaWxsSWQgPSBpeDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvL05hbWVkIHN0eWxlIHJlZmVyZW5jZQogICAgICAgICAgICAgICAgaWYgKHhmcy5YZklkID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaWQgPSBzdHlsZS5DZWxsU3R5bGVYZnNbeGZzLlhmSWRdLklkOwogICAgICAgICAgICAgICAgICAgIHZhciBuZXdJZCA9IENlbGxTdHlsZVhmcy5GaW5kSW5kZXhCeUlEKGlkKTsKICAgICAgICAgICAgICAgICAgICBpZiAobmV3SWQgPj0gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1hmcy5YZklkID0gbmV3SWQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoc3R5bGUuX3diIT1fd2IgJiYgYWxsd2F5c0FkZD09ZmFsc2UpIC8vTm90IHRoZSBzYW1lIHdvcmtib29rLCBjb3B5IHRoZSBuYW1lZHN0eWxlIHRvIHRoZSB3b3JrYm9vayBvciBtYXRjaCB0aGUgaWQKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuc0ZpbmQgPSBzdHlsZS5OYW1lZFN0eWxlcy5Ub0RpY3Rpb25hcnkoZCA9PiAoZC5TdHlsZVhmSWQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5zRmluZC5Db250YWluc0tleSh4ZnMuWGZJZCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdCA9IG5zRmluZFt4ZnMuWGZJZF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoTmFtZWRTdHlsZXMuRXhpc3RzS2V5KHN0Lk5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1hmcy5YZklkID0gTmFtZWRTdHlsZXMuRmluZEluZGV4QnlJRChzdC5OYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbnMgPSBDcmVhdGVOYW1lZFN0eWxlKHN0Lk5hbWUsIHN0LlN0eWxlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdYZnMuWGZJZCA9IE5hbWVkU3R5bGVzLkNvdW50IC0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpbnQgaW5kZXg7CiAgICAgICAgICAgICAgICBpZiAoaXNOYW1lZFN0eWxlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGluZGV4ID0gQ2VsbFN0eWxlWGZzLkFkZChuZXdYZnMuSWQsIG5ld1hmcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGFsbHdheXNBZGQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IENlbGxYZnMuQWRkKG5ld1hmcy5JZCwgbmV3WGZzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBDZWxsWGZzLkZpbmRJbmRleEJ5SUQobmV3WGZzLklkKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgMCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBDZWxsWGZzLkFkZChuZXdYZnMuSWQsIG5ld1hmcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXg7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0K