LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogWW91IG1heSBhbWVuZCBhbmQgZGlzdHJpYnV0ZSBhcyB5b3UgbGlrZSwgYnV0IGRvbid0IHJlbW92ZSB0aGlzIGhlYWRlciEKICoKICogRVBQbHVzIHByb3ZpZGVzIHNlcnZlci1zaWRlIGdlbmVyYXRpb24gb2YgRXhjZWwgMjAwNy8yMDEwIHNwcmVhZHNoZWV0cy4KICogU2VlIGh0dHA6Ly93d3cuY29kZXBsZXguY29tL0VQUGx1cyBmb3IgZGV0YWlscy4KICoKICogQ29weXJpZ2h0IChDKSAyMDExICBKYW4gS+RsbG1hbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIAogKiBTZWUgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBUaGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGNhbiBiZSB2aWV3ZWQgYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9sZ3BsLWxpY2Vuc2UucGhwCiAqIElmIHlvdSB1bmZhbWlsaWFyIHdpdGggdGhpcyBsaWNlbnNlIG9yIGhhdmUgcXVlc3Rpb25zIGFib3V0IGl0LCBoZXJlIGlzIGFuIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtZmFxLmh0bWwKICoKICogQWxsIGNvZGUgYW5kIGV4ZWN1dGFibGVzIGFyZSBwcm92aWRlZCAiYXMgaXMiIHdpdGggbm8gd2FycmFudHkgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCiAqIFRoZSBhdXRob3IgYWNjZXB0cyBubyBsaWFiaWxpdHkgZm9yIGFueSBkYW1hZ2Ugb3IgbG9zcyBvZiBidXNpbmVzcyB0aGF0IHRoaXMgcHJvZHVjdCBtYXkgY2F1c2UuCiAqCiAqIENvZGUgY2hhbmdlIG5vdGVzOgogKiAKICogQXV0aG9yCQkJCQkJCUNoYW5nZQkJCQkJCURhdGUKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSmFuIEvkbGxtYW4JCSAgICAgICAgICAgICAgICBJbml0aWFsIFJlbGVhc2UJCSAgICAgICAgMjAwOS0xMC0wMQogKiBKYW4gS+RsbG1hbiAgICAgICAgICAgICAgICAgICAgICBUb3RhbCByZXdyaXRlICAgICAgICAgICAgICAgMjAxMC0wMy0wMQogKiBKYW4gS+RsbG1hbgkJTGljZW5zZSBjaGFuZ2VkIEdQTC0tPkxHUEwgMjAxMS0xMi0yNwogKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp1c2luZyBTeXN0ZW07CnVzaW5nIFN5c3RlbS5YbWw7CnVzaW5nIFN5c3RlbS5UZXh0LlJlZ3VsYXJFeHByZXNzaW9uczsKdXNpbmcgU3lzdGVtLkRyYXdpbmc7CnVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwp1c2luZyBPZmZpY2VPcGVuWG1sLkRyYXdpbmcuVm1sOwp1c2luZyBTeXN0ZW0uSU87CnVzaW5nIE9mZmljZU9wZW5YbWwuRHJhd2luZzsKdXNpbmcgT2ZmaWNlT3BlblhtbC5VdGlsczsKbmFtZXNwYWNlIE9mZmljZU9wZW5YbWwKeyAgICAKICAgIC8vLyA8c3VtbWFyeT4KICAgIC8vLyBIb3cgYSBwaWN0dXJlIHdpbGwgYmUgYWxpZ25lZCBpbiB0aGUgaGVhZGVyL2Zvb3RlcgogICAgLy8vIDwvc3VtbWFyeT4KICAgIHB1YmxpYyBlbnVtIFBpY3R1cmVBbGlnbm1lbnQKICAgIHsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBwaWN0dXJlIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGxlZnQgYWxpZ25lZCB0ZXh0CiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBMZWZ0LAogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVGhlIHBpY3R1cmUgd2lsbCBiZSBhZGRlZCB0byB0aGUgY2VudGVyZWQgdGV4dAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgQ2VudGVyZWQsCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgcGljdHVyZSB3aWxsIGJlIGFkZGVkIHRvIHRoZSByaWdodCBhbGlnbmVkIHRleHQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIFJpZ2h0CiAgICB9CiAgICAjcmVnaW9uIGNsYXNzIEV4Y2VsSGVhZGVyRm9vdGVyVGV4dAoJLy8vIDxzdW1tYXJ5PgogICAgLy8vIFByaW50IGhlYWRlciBhbmQgZm9vdGVyIAogICAgLy8vIDwvc3VtbWFyeT4KCXB1YmxpYyBjbGFzcyBFeGNlbEhlYWRlckZvb3RlclRleHQKCXsKICAgICAgICBFeGNlbFdvcmtzaGVldCBfd3M7CiAgICAgICAgc3RyaW5nIF9oZjsKICAgICAgICBpbnRlcm5hbCBFeGNlbEhlYWRlckZvb3RlclRleHQoWG1sTm9kZSBUZXh0Tm9kZSwgRXhjZWxXb3Jrc2hlZXQgd3MsIHN0cmluZyBoZikKICAgICAgICB7CiAgICAgICAgICAgIF93cyA9IHdzOwogICAgICAgICAgICBfaGYgPSBoZjsKICAgICAgICAgICAgaWYgKFRleHROb2RlID09IG51bGwgfHwgc3RyaW5nLklzTnVsbE9yRW1wdHkoVGV4dE5vZGUuSW5uZXJUZXh0KSkgcmV0dXJuOwogICAgICAgICAgICBzdHJpbmcgdGV4dCA9IFRleHROb2RlLklubmVyVGV4dDsKICAgICAgICAgICAgc3RyaW5nIGNvZGUgPSB0ZXh0LlN1YnN0cmluZygwLCAyKTsgIAogICAgICAgICAgICBpbnQgc3RhcnRQb3M9MjsKICAgICAgICAgICAgZm9yIChpbnQgcG9zPXN0YXJ0UG9zO3Bvczx0ZXh0Lkxlbmd0aC0yO3BvcysrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJpbmcgbmV3Q29kZSA9IHRleHQuU3Vic3RyaW5nKHBvcywgMik7CiAgICAgICAgICAgICAgICBpZiAobmV3Q29kZSA9PSAiJkMiIHx8IG5ld0NvZGUgPT0gIiZSIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBTZXRUZXh0KGNvZGUsIHRleHQuU3Vic3RyaW5nKHN0YXJ0UG9zLCBwb3Mtc3RhcnRQb3MpKTsKICAgICAgICAgICAgICAgICAgICBzdGFydFBvcyA9IHBvcysyOwogICAgICAgICAgICAgICAgICAgIHBvcyA9IHN0YXJ0UG9zOwogICAgICAgICAgICAgICAgICAgIGNvZGUgPSBuZXdDb2RlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIFNldFRleHQoY29kZSwgdGV4dC5TdWJzdHJpbmcoc3RhcnRQb3MsIHRleHQuTGVuZ3RoIC0gc3RhcnRQb3MpKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIFNldFRleHQoc3RyaW5nIGNvZGUsIHN0cmluZyB0ZXh0KQogICAgICAgIHsKICAgICAgICAgICAgc3dpdGNoIChjb2RlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlICImTCI6CiAgICAgICAgICAgICAgICAgICAgTGVmdEFsaWduZWRUZXh0PXRleHQ7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICImQyI6CiAgICAgICAgICAgICAgICAgICAgQ2VudGVyZWRUZXh0PXRleHQ7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIFJpZ2h0QWxpZ25lZFRleHQ9dGV4dDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCQkvLy8gPHN1bW1hcnk+CgkJLy8vIEdldC9zZXQgdGhlIHRleHQgdG8gYXBwZWFyIG9uIHRoZSBsZWZ0IGhhbmQgc2lkZSBvZiB0aGUgaGVhZGVyIChvciBmb290ZXIpIG9uIHRoZSB3b3Jrc2hlZXQuCgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgc3RyaW5nIExlZnRBbGlnbmVkVGV4dCA9IG51bGw7CgkJLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBHZXQvc2V0IHRoZSB0ZXh0IHRvIGFwcGVhciBpbiB0aGUgY2VudGVyIG9mIHRoZSBoZWFkZXIgKG9yIGZvb3Rlcikgb24gdGhlIHdvcmtzaGVldC4KCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBzdHJpbmcgQ2VudGVyZWRUZXh0ID0gbnVsbDsKCQkvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldC9zZXQgdGhlIHRleHQgdG8gYXBwZWFyIG9uIHRoZSByaWdodCBoYW5kIHNpZGUgb2YgdGhlIGhlYWRlciAob3IgZm9vdGVyKSBvbiB0aGUgd29ya3NoZWV0LgoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIHN0cmluZyBSaWdodEFsaWduZWRUZXh0ID0gbnVsbDsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEluc2VydHMgYSBwaWN0dXJlIGF0IHRoZSBlbmQgb2YgdGhlIHRleHQgaW4gdGhlIGhlYWRlciBvciBmb290ZXIKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iUGljdHVyZSI+VGhlIGltYWdlIG9iamVjdCBjb250YWluaW5nIHRoZSBQaWN0dXJlPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IkFsaWdubWVudCI+QWxpZ25tZW50LiBUaGUgaW1hZ2Ugb2JqZWN0IHdpbGwgYmUgaW5zZXJ0ZWQgYXQgdGhlIGVuZCBvZiB0aGUgVGV4dC48L3BhcmFtPgogICAgICAgIHB1YmxpYyBFeGNlbFZtbERyYXdpbmdQaWN0dXJlIEluc2VydFBpY3R1cmUoSW1hZ2UgUGljdHVyZSwgUGljdHVyZUFsaWdubWVudCBBbGlnbm1lbnQpCiAgICAgICAgewogICAgICAgICAgICBzdHJpbmcgaWQgPSBWYWxpZGF0ZUltYWdlKEFsaWdubWVudCk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0FkZCB0aGUgaW1hZ2UKICAgICAgICAgICAgSW1hZ2VDb252ZXJ0ZXIgaWMgPSBuZXcgSW1hZ2VDb252ZXJ0ZXIoKTsKICAgICAgICAgICAgYnl0ZVtdIGltZyA9IChieXRlW10paWMuQ29udmVydFRvKFBpY3R1cmUsIHR5cGVvZihieXRlW10pKTsKICAgICAgICAgICAgdmFyIGlpID0gX3dzLldvcmtib29rLl9wYWNrYWdlLkFkZEltYWdlKGltZyk7CgogICAgICAgICAgICByZXR1cm4gQWRkSW1hZ2UoUGljdHVyZSwgaWQsIGlpKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBJbnNlcnRzIGEgcGljdHVyZSBhdCB0aGUgZW5kIG9mIHRoZSB0ZXh0IGluIHRoZSBoZWFkZXIgb3IgZm9vdGVyCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlBpY3R1cmVGaWxlIj5UaGUgaW1hZ2Ugb2JqZWN0IGNvbnRhaW5pbmcgdGhlIFBpY3R1cmU8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iQWxpZ25tZW50Ij5BbGlnbm1lbnQuIFRoZSBpbWFnZSBvYmplY3Qgd2lsbCBiZSBpbnNlcnRlZCBhdCB0aGUgZW5kIG9mIHRoZSBUZXh0LjwvcGFyYW0+CiAgICAgICAgcHVibGljIEV4Y2VsVm1sRHJhd2luZ1BpY3R1cmUgSW5zZXJ0UGljdHVyZShGaWxlSW5mbyBQaWN0dXJlRmlsZSwgUGljdHVyZUFsaWdubWVudCBBbGlnbm1lbnQpCiAgICAgICAgewogICAgICAgICAgICBzdHJpbmcgaWQgPSBWYWxpZGF0ZUltYWdlKEFsaWdubWVudCk7CgogICAgICAgICAgICBJbWFnZSBQaWN0dXJlOwogICAgICAgICAgICB0cnkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFQaWN0dXJlRmlsZS5FeGlzdHMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBGaWxlTm90Rm91bmRFeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiezB9IGlzIG1pc3NpbmciLCBQaWN0dXJlRmlsZS5GdWxsTmFtZSkpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFBpY3R1cmUgPSBJbWFnZS5Gcm9tRmlsZShQaWN0dXJlRmlsZS5GdWxsTmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBJbnZhbGlkRGF0YUV4Y2VwdGlvbigiRmlsZSBpcyBub3QgYSBzdXBwb3J0ZWQgaW1hZ2UtZmlsZSBvciBpcyBjb3JydXB0IiwgZXgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSW1hZ2VDb252ZXJ0ZXIgaWMgPSBuZXcgSW1hZ2VDb252ZXJ0ZXIoKTsKICAgICAgICAgICAgc3RyaW5nIGNvbnRlbnRUeXBlID0gRXhjZWxQaWN0dXJlLkdldENvbnRlbnRUeXBlKFBpY3R1cmVGaWxlLkV4dGVuc2lvbik7CiAgICAgICAgICAgIHZhciB1cmlQaWMgPSBYbWxIZWxwZXIuR2V0TmV3VXJpKF93cy5fcGFja2FnZS5QYWNrYWdlLCAiL3hsL21lZGlhLyIrUGljdHVyZUZpbGUuTmFtZS5TdWJzdHJpbmcoMCwgUGljdHVyZUZpbGUuTmFtZS5MZW5ndGgtUGljdHVyZUZpbGUuRXh0ZW5zaW9uLkxlbmd0aCkgKyAiezB9IiArIFBpY3R1cmVGaWxlLkV4dGVuc2lvbik7CiAgICAgICAgICAgIGJ5dGVbXSBpbWdCeXRlcyA9IChieXRlW10paWMuQ29udmVydFRvKFBpY3R1cmUsIHR5cGVvZihieXRlW10pKTsKICAgICAgICAgICAgdmFyIGlpID0gX3dzLldvcmtib29rLl9wYWNrYWdlLkFkZEltYWdlKGltZ0J5dGVzLCB1cmlQaWMsIGNvbnRlbnRUeXBlKTsKCiAgICAgICAgICAgIHJldHVybiBBZGRJbWFnZShQaWN0dXJlLCBpZCwgaWkpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBFeGNlbFZtbERyYXdpbmdQaWN0dXJlIEFkZEltYWdlKEltYWdlIFBpY3R1cmUsIHN0cmluZyBpZCwgRXhjZWxQYWNrYWdlLkltYWdlSW5mbyBpaSkKICAgICAgICB7CiAgICAgICAgICAgIGRvdWJsZSB3aWR0aCA9IFBpY3R1cmUuV2lkdGggKiA3MiAvIFBpY3R1cmUuSG9yaXpvbnRhbFJlc29sdXRpb24sICAgICAgLy9QaXhlbCAtLT4gUG9pbnRzCiAgICAgICAgICAgICAgICAgICBoZWlnaHQgPSBQaWN0dXJlLkhlaWdodCAqIDcyIC8gUGljdHVyZS5WZXJ0aWNhbFJlc29sdXRpb247ICAgICAgLy9QaXhlbCAtLT4gUG9pbnRzCiAgICAgICAgICAgIC8vQWRkIFZNTC1kcmF3aW5nICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiBfd3MuSGVhZGVyRm9vdGVyLlBpY3R1cmVzLkFkZChpZCwgaWkuVXJpLCAiIiwgd2lkdGgsIGhlaWdodCk7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgc3RyaW5nIFZhbGlkYXRlSW1hZ2UoUGljdHVyZUFsaWdubWVudCBBbGlnbm1lbnQpCiAgICAgICAgewogICAgICAgICAgICBzdHJpbmcgaWQgPSBzdHJpbmcuQ29uY2F0KEFsaWdubWVudC5Ub1N0cmluZygpWzBdLCBfaGYpOwogICAgICAgICAgICBmb3JlYWNoIChFeGNlbFZtbERyYXdpbmdQaWN0dXJlIGltYWdlIGluIF93cy5IZWFkZXJGb290ZXIuUGljdHVyZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChpbWFnZS5JZCA9PSBpZCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIkEgcGljdHVyZSBhbHJlYWR5IGV4aXN0cyBpbiB0aGlzIHNlY3Rpb24iKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9BZGQgdGhlIGltYWdlIHBsYWNlaG9sZGVyIHRvIHRoZSBlbmQgb2YgdGhlIHRleHQKICAgICAgICAgICAgc3dpdGNoIChBbGlnbm1lbnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgUGljdHVyZUFsaWdubWVudC5MZWZ0OgogICAgICAgICAgICAgICAgICAgIExlZnRBbGlnbmVkVGV4dCArPSBFeGNlbEhlYWRlckZvb3Rlci5JbWFnZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgUGljdHVyZUFsaWdubWVudC5DZW50ZXJlZDoKICAgICAgICAgICAgICAgICAgICBDZW50ZXJlZFRleHQgKz0gRXhjZWxIZWFkZXJGb290ZXIuSW1hZ2U7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIFJpZ2h0QWxpZ25lZFRleHQgKz0gRXhjZWxIZWFkZXJGb290ZXIuSW1hZ2U7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGlkOwogICAgICAgIH0KCX0KCSNlbmRyZWdpb24KCgkjcmVnaW9uIEV4Y2VsSGVhZGVyRm9vdGVyCgkvLy8gPHN1bW1hcnk+CgkvLy8gUmVwcmVzZW50cyB0aGUgSGVhZGVyIGFuZCBGb290ZXIgb24gYW4gRXhjZWwgV29ya3NoZWV0CgkvLy8gPC9zdW1tYXJ5PgoJcHVibGljIHNlYWxlZCBjbGFzcyBFeGNlbEhlYWRlckZvb3RlciA6IFhtbEhlbHBlcgoJewoJCSNyZWdpb24gU3RhdGljIFByb3BlcnRpZXMKCQkvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBjb2RlIGZvciAiY3VycmVudCBwYWdlICMiCgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgY29uc3Qgc3RyaW5nIFBhZ2VOdW1iZXIgPSBAIiZQIjsKCQkvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBjb2RlIGZvciAidG90YWwgcGFnZXMiCgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgY29uc3Qgc3RyaW5nIE51bWJlck9mUGFnZXMgPSBAIiZOIjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBjb2RlIGZvciAidGV4dCBmb250IGNvbG9yIgogICAgICAgIC8vLyBSR0IgQ29sb3IgaXMgc3BlY2lmaWVkIGFzIFJSR0dCQgogICAgICAgIC8vLyBUaGVtZSBDb2xvciBpcyBzcGVjaWZpZWQgYXMgVFRTTk4gd2hlcmUgVFQgaXMgdGhlIHRoZW1lIGNvbG9yIElkLCBTIGlzIGVpdGhlciAiKyIgb3IgIi0iIG9mIHRoZSB0aW50L3NoYWRlIHZhbHVlLCBOTiBpcyB0aGUgdGludC9zaGFkZSB2YWx1ZS4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBjb25zdCBzdHJpbmcgRm9udENvbG9yID0gQCImSyI7CgkJLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgY29kZSBmb3IgInNoZWV0IHRhYiBuYW1lIgoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIGNvbnN0IHN0cmluZyBTaGVldE5hbWUgPSBAIiZBIjsKCQkvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBjb2RlIGZvciAidGhpcyB3b3JrYm9vaydzIGZpbGUgcGF0aCIKCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBjb25zdCBzdHJpbmcgRmlsZVBhdGggPSBAIiZaIjsKCQkvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBjb2RlIGZvciAidGhpcyB3b3JrYm9vaydzIGZpbGUgbmFtZSIKCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBjb25zdCBzdHJpbmcgRmlsZU5hbWUgPSBAIiZGIjsKCQkvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBjb2RlIGZvciAiZGF0ZSIKCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBjb25zdCBzdHJpbmcgQ3VycmVudERhdGUgPSBAIiZEIjsKCQkvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBjb2RlIGZvciAidGltZSIKCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBjb25zdCBzdHJpbmcgQ3VycmVudFRpbWUgPSBAIiZUIjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBjb2RlIGZvciAicGljdHVyZSBhcyBiYWNrZ3JvdW5kIgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIGNvbnN0IHN0cmluZyBJbWFnZSA9IEAiJkciOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVGhlIGNvZGUgZm9yICJvdXRsaW5lIHN0eWxlIgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIGNvbnN0IHN0cmluZyBPdXRsaW5lU3R5bGUgPSBAIiZPIjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBjb2RlIGZvciAic2hhZG93IHN0eWxlIgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIGNvbnN0IHN0cmluZyBTaGFkb3dTdHlsZSA9IEAiJkgiOwoJCSNlbmRyZWdpb24KCgkJI3JlZ2lvbiBFeGNlbEhlYWRlckZvb3RlciBQcml2YXRlIFByb3BlcnRpZXMKCQlpbnRlcm5hbCBFeGNlbEhlYWRlckZvb3RlclRleHQgX29kZEhlYWRlcjsKICAgICAgICBpbnRlcm5hbCBFeGNlbEhlYWRlckZvb3RlclRleHQgX29kZEZvb3RlcjsKCQlpbnRlcm5hbCBFeGNlbEhlYWRlckZvb3RlclRleHQgX2V2ZW5IZWFkZXI7CiAgICAgICAgaW50ZXJuYWwgRXhjZWxIZWFkZXJGb290ZXJUZXh0IF9ldmVuRm9vdGVyOwogICAgICAgIGludGVybmFsIEV4Y2VsSGVhZGVyRm9vdGVyVGV4dCBfZmlyc3RIZWFkZXI7CiAgICAgICAgaW50ZXJuYWwgRXhjZWxIZWFkZXJGb290ZXJUZXh0IF9maXJzdEZvb3RlcjsKICAgICAgICBwcml2YXRlIEV4Y2VsV29ya3NoZWV0IF93czsKICAgICAgICAjZW5kcmVnaW9uCgoJCSNyZWdpb24gRXhjZWxIZWFkZXJGb290ZXIgQ29uc3RydWN0b3IKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIEV4Y2VsSGVhZGVyRm9vdGVyIENvbnN0cnVjdG9yCgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9Im5hbWVTcGFjZU1hbmFnZXIiPjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJ0b3BOb2RlIj48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0id3MiPlRoZSB3b3Jrc2hlZXQ8L3BhcmFtPgoJCWludGVybmFsIEV4Y2VsSGVhZGVyRm9vdGVyKFhtbE5hbWVzcGFjZU1hbmFnZXIgbmFtZVNwYWNlTWFuYWdlciwgWG1sTm9kZSB0b3BOb2RlLCBFeGNlbFdvcmtzaGVldCB3cykgOgogICAgICAgICAgICBiYXNlKG5hbWVTcGFjZU1hbmFnZXIsIHRvcE5vZGUpCgkJewogICAgICAgICAgICBfd3MgPSB3czsKICAgICAgICAgICAgU2NoZW1hTm9kZU9yZGVyID0gbmV3IHN0cmluZ1tdIHsgImhlYWRlckZvb3RlciIsICJvZGRIZWFkZXIiLCAib2RkRm9vdGVyIiwgImV2ZW5IZWFkZXIiLCAiZXZlbkZvb3RlciIsICJmaXJzdEhlYWRlciIsICJmaXJzdEZvb3RlciIgfTsKCQl9CgkJI2VuZHJlZ2lvbgoKCQkjcmVnaW9uIGFsaWduV2l0aE1hcmdpbnMKICAgICAgICBjb25zdCBzdHJpbmcgYWxpZ25XaXRoTWFyZ2luc1BhdGg9IkBhbGlnbldpdGhNYXJnaW5zIjsKICAgICAgICAvLy8gPHN1bW1hcnk+CgkJLy8vIEdldHMvc2V0cyB0aGUgYWxpZ25XaXRoTWFyZ2lucyBhdHRyaWJ1dGUKCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBib29sIEFsaWduV2l0aE1hcmdpbnMKCQl7CgkJCWdldAoJCQl7CiAgICAgICAgICAgICAgICByZXR1cm4gR2V0WG1sTm9kZUJvb2woYWxpZ25XaXRoTWFyZ2luc1BhdGgpOwoJCQl9CgkJCXNldAoJCQl7CiAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKGFsaWduV2l0aE1hcmdpbnNQYXRoLCB2YWx1ZSA/ICIxIiA6ICIwIik7CgkJCX0KCQl9CgkJI2VuZHJlZ2lvbgoKICAgICAgICAjcmVnaW9uIGRpZmZlcmVudE9kZEV2ZW4KICAgICAgICBjb25zdCBzdHJpbmcgZGlmZmVyZW50T2RkRXZlblBhdGggPSAiQGRpZmZlcmVudE9kZEV2ZW4iOwogICAgICAgIC8vLyA8c3VtbWFyeT4KCQkvLy8gR2V0cy9zZXRzIHRoZSBmbGFnIHRoYXQgdGVsbHMgRXhjZWwgdG8gZGlzcGxheSBkaWZmZXJlbnQgaGVhZGVycyBhbmQgZm9vdGVycyBvbiBvZGQgYW5kIGV2ZW4gcGFnZXMuCgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgYm9vbCBkaWZmZXJlbnRPZGRFdmVuCgkJewoJCQlnZXQKCQkJewogICAgICAgICAgICAgICAgcmV0dXJuIEdldFhtbE5vZGVCb29sKGRpZmZlcmVudE9kZEV2ZW5QYXRoKTsKCQkJfQoJCQlzZXQKCQkJewogICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZyhkaWZmZXJlbnRPZGRFdmVuUGF0aCwgdmFsdWUgPyAiMSIgOiAiMCIpOwoJCQl9CgkJfQoJCSNlbmRyZWdpb24KCgkJI3JlZ2lvbiBkaWZmZXJlbnRGaXJzdAogICAgICAgIGNvbnN0IHN0cmluZyBkaWZmZXJlbnRGaXJzdFBhdGggPSAiQGRpZmZlcmVudEZpcnN0IjsKCgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBHZXRzL3NldHMgdGhlIGZsYWcgdGhhdCB0ZWxscyBFeGNlbCB0byBkaXNwbGF5IGRpZmZlcmVudCBoZWFkZXJzIGFuZCBmb290ZXJzIG9uIHRoZSBmaXJzdCBwYWdlIG9mIHRoZSB3b3Jrc2hlZXQuCgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgYm9vbCBkaWZmZXJlbnRGaXJzdAoJCXsKCQkJZ2V0CgkJCXsKICAgICAgICAgICAgICAgIHJldHVybiBHZXRYbWxOb2RlQm9vbChkaWZmZXJlbnRGaXJzdFBhdGgpOwoJCQl9CgkJCXNldAoJCQl7CiAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKGRpZmZlcmVudEZpcnN0UGF0aCwgdmFsdWUgPyAiMSIgOiAiMCIpOwoJCQl9CgkJfQoJCSNlbmRyZWdpb24KCgkJI3JlZ2lvbiBFeGNlbEhlYWRlckZvb3RlciBQdWJsaWMgUHJvcGVydGllcwoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gUHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBoZWFkZXIgb24gb2RkIG51bWJlcmVkIHBhZ2VzIG9mIHRoZSBkb2N1bWVudC4KCQkvLy8gSWYgeW91IHdhbnQgdGhlIHNhbWUgaGVhZGVyIG9uIGJvdGggb2RkIGFuZCBldmVuIHBhZ2VzLCB0aGVuIG9ubHkgc2V0IHZhbHVlcyBpbiB0aGlzIEV4Y2VsSGVhZGVyRm9vdGVyVGV4dCBjbGFzcy4KCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBFeGNlbEhlYWRlckZvb3RlclRleHQgT2RkSGVhZGVyIAogICAgICAgIHsgCiAgICAgICAgICAgIGdldCAKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF9vZGRIZWFkZXIgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfb2RkSGVhZGVyID0gbmV3IEV4Y2VsSGVhZGVyRm9vdGVyVGV4dChUb3BOb2RlLlNlbGVjdFNpbmdsZU5vZGUoImQ6b2RkSGVhZGVyIiwgTmFtZVNwYWNlTWFuYWdlciksIF93cywgIkgiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfb2RkSGVhZGVyOyB9IAogICAgICAgIH0KCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgZm9vdGVyIG9uIG9kZCBudW1iZXJlZCBwYWdlcyBvZiB0aGUgZG9jdW1lbnQuCgkJLy8vIElmIHlvdSB3YW50IHRoZSBzYW1lIGZvb3RlciBvbiBib3RoIG9kZCBhbmQgZXZlbiBwYWdlcywgdGhlbiBvbmx5IHNldCB2YWx1ZXMgaW4gdGhpcyBFeGNlbEhlYWRlckZvb3RlclRleHQgY2xhc3MuCgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgRXhjZWxIZWFkZXJGb290ZXJUZXh0IE9kZEZvb3RlciAKICAgICAgICB7IAogICAgICAgICAgICBnZXQgCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfb2RkRm9vdGVyID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX29kZEZvb3RlciA9IG5ldyBFeGNlbEhlYWRlckZvb3RlclRleHQoVG9wTm9kZS5TZWxlY3RTaW5nbGVOb2RlKCJkOm9kZEZvb3RlciIsIE5hbWVTcGFjZU1hbmFnZXIpLCBfd3MsICJGIik7IDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfb2RkRm9vdGVyOyAKICAgICAgICAgICAgfSAKICAgICAgICB9CgkJLy8gZXZlbkhlYWRlciBhbmQgZXZlbkZvb3RlciBzZXQgZGlmZmVyZW50T2RkRXZlbiA9IHRydWUKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgaGVhZGVyIG9uIGV2ZW4gbnVtYmVyZWQgcGFnZXMgb2YgdGhlIGRvY3VtZW50LgoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIEV4Y2VsSGVhZGVyRm9vdGVyVGV4dCBFdmVuSGVhZGVyIAogICAgICAgIHsgCiAgICAgICAgICAgIGdldCAKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF9ldmVuSGVhZGVyID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX2V2ZW5IZWFkZXIgPSBuZXcgRXhjZWxIZWFkZXJGb290ZXJUZXh0KFRvcE5vZGUuU2VsZWN0U2luZ2xlTm9kZSgiZDpldmVuSGVhZGVyIiwgTmFtZVNwYWNlTWFuYWdlciksIF93cywgIkhFVkVOIik7CiAgICAgICAgICAgICAgICAgICAgZGlmZmVyZW50T2RkRXZlbiA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX2V2ZW5IZWFkZXI7IAogICAgICAgICAgICB9IAogICAgICAgIH0KCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgZm9vdGVyIG9uIGV2ZW4gbnVtYmVyZWQgcGFnZXMgb2YgdGhlIGRvY3VtZW50LgoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIEV4Y2VsSGVhZGVyRm9vdGVyVGV4dCBFdmVuRm9vdGVyCiAgICAgICAgeyAKICAgICAgICAgICAgZ2V0IAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX2V2ZW5Gb290ZXIgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfZXZlbkZvb3RlciA9IG5ldyBFeGNlbEhlYWRlckZvb3RlclRleHQoVG9wTm9kZS5TZWxlY3RTaW5nbGVOb2RlKCJkOmV2ZW5Gb290ZXIiLCBOYW1lU3BhY2VNYW5hZ2VyKSwgX3dzLCAiRkVWRU4iKTsKICAgICAgICAgICAgICAgICAgICBkaWZmZXJlbnRPZGRFdmVuID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfZXZlbkZvb3RlciA7IAogICAgICAgICAgICB9IAogICAgICAgIH0KCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgaGVhZGVyIG9uIHRoZSBmaXJzdCBwYWdlIG9mIHRoZSBkb2N1bWVudC4KCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBFeGNlbEhlYWRlckZvb3RlclRleHQgRmlyc3RIZWFkZXIKICAgICAgICB7IAogICAgICAgICAgICBnZXQgCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfZmlyc3RIZWFkZXIgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfZmlyc3RIZWFkZXIgPSBuZXcgRXhjZWxIZWFkZXJGb290ZXJUZXh0KFRvcE5vZGUuU2VsZWN0U2luZ2xlTm9kZSgiZDpmaXJzdEhlYWRlciIsIE5hbWVTcGFjZU1hbmFnZXIpLCBfd3MsICJIRklSU1QiKTsgCiAgICAgICAgICAgICAgICAgICAgIGRpZmZlcmVudEZpcnN0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfZmlyc3RIZWFkZXI7IAogICAgICAgICAgICB9IAogICAgICAgIH0KCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgZm9vdGVyIG9uIHRoZSBmaXJzdCBwYWdlIG9mIHRoZSBkb2N1bWVudC4KCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBFeGNlbEhlYWRlckZvb3RlclRleHQgRmlyc3RGb290ZXIKICAgICAgICB7IAogICAgICAgICAgICBnZXQgCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfZmlyc3RGb290ZXIgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfZmlyc3RGb290ZXIgPSBuZXcgRXhjZWxIZWFkZXJGb290ZXJUZXh0KFRvcE5vZGUuU2VsZWN0U2luZ2xlTm9kZSgiZDpmaXJzdEZvb3RlciIsIE5hbWVTcGFjZU1hbmFnZXIpLCBfd3MsICJGRklSU1QiKTsgCiAgICAgICAgICAgICAgICAgICAgZGlmZmVyZW50Rmlyc3QgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF9maXJzdEZvb3RlcjsgCiAgICAgICAgICAgIH0gCiAgICAgICAgfQogICAgICAgIHByaXZhdGUgRXhjZWxWbWxEcmF3aW5nUGljdHVyZUNvbGxlY3Rpb24gX3ZtbERyYXdpbmdzSEYgPSBudWxsOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVm1sIGRyYXdpbmdzLiBVbmRlcmxheWluZyBvYmplY3QgZm9yIEhlYWRlciBmb290ZXIgaW1hZ2VzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxWbWxEcmF3aW5nUGljdHVyZUNvbGxlY3Rpb24gUGljdHVyZXMKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX3ZtbERyYXdpbmdzSEYgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdm1sTm9kZSA9IF93cy5Xb3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiZDp3b3Jrc2hlZXQvZDpsZWdhY3lEcmF3aW5nSEYvQHI6aWQiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgICAgICAgICBpZiAodm1sTm9kZSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZtbERyYXdpbmdzSEYgPSBuZXcgRXhjZWxWbWxEcmF3aW5nUGljdHVyZUNvbGxlY3Rpb24oX3dzLl9wYWNrYWdlLCBfd3MsIG51bGwpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3dzLlBhcnQuUmVsYXRpb25zaGlwRXhpc3RzKHZtbE5vZGUuVmFsdWUpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVsID0gX3dzLlBhcnQuR2V0UmVsYXRpb25zaGlwKHZtbE5vZGUuVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZtbFVyaSA9IFVyaUhlbHBlci5SZXNvbHZlUGFydFVyaShyZWwuU291cmNlVXJpLCByZWwuVGFyZ2V0VXJpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdm1sRHJhd2luZ3NIRiA9IG5ldyBFeGNlbFZtbERyYXdpbmdQaWN0dXJlQ29sbGVjdGlvbihfd3MuX3BhY2thZ2UsIF93cywgdm1sVXJpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92bWxEcmF3aW5nc0hGLlJlbElkID0gcmVsLklkOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF92bWxEcmF3aW5nc0hGOwogICAgICAgICAgICB9CiAgICAgICAgfQoJCSNlbmRyZWdpb24KCQkjcmVnaW9uIFNhdmUgIC8vICBFeGNlbEhlYWRlckZvb3RlcgoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gU2F2ZXMgdGhlIGhlYWRlciBhbmQgZm9vdGVyIGluZm9ybWF0aW9uIHRvIHRoZSB3b3Jrc2hlZXQgWE1MCgkJLy8vIDwvc3VtbWFyeT4KCQlpbnRlcm5hbCB2b2lkIFNhdmUoKQoJCXsKCQkJaWYgKF9vZGRIZWFkZXIgIT0gbnVsbCkKCQkJewogICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiZDpvZGRIZWFkZXIiLCBHZXRUZXh0KE9kZEhlYWRlcikpOwoJCQl9CgkJCWlmIChfb2RkRm9vdGVyICE9IG51bGwpCgkJCXsKICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoImQ6b2RkRm9vdGVyIiwgR2V0VGV4dChPZGRGb290ZXIpKTsKCQkJfQoKCQkJLy8gb25seSBzZXQgZXZlbkhlYWRlciBhbmQgZXZlbkZvb3RlciAKCQkJaWYgKGRpZmZlcmVudE9kZEV2ZW4pCgkJCXsKCQkJCWlmIChfZXZlbkhlYWRlciAhPSBudWxsKQoJCQkJewogICAgICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoImQ6ZXZlbkhlYWRlciIsIEdldFRleHQoRXZlbkhlYWRlcikpOwoJCQkJfQoJCQkJaWYgKF9ldmVuRm9vdGVyICE9IG51bGwpCgkJCQl7CiAgICAgICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiZDpldmVuRm9vdGVyIiwgR2V0VGV4dChFdmVuRm9vdGVyKSk7CgkJCQl9CgkJCX0KCgkJCS8vIG9ubHkgc2V0IGZpcnN0SGVhZGVyIGFuZCBmaXJzdEZvb3RlcgoJCQlpZiAoZGlmZmVyZW50Rmlyc3QpCgkJCXsKCQkJCWlmIChfZmlyc3RIZWFkZXIgIT0gbnVsbCkKCQkJCXsKICAgICAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJkOmZpcnN0SGVhZGVyIiwgR2V0VGV4dChGaXJzdEhlYWRlcikpOwoJCQkJfQoJCQkJaWYgKF9maXJzdEZvb3RlciAhPSBudWxsKQoJCQkJewogICAgICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoImQ6Zmlyc3RGb290ZXIiLCBHZXRUZXh0KEZpcnN0Rm9vdGVyKSk7CgkJCQl9CgkJCX0KCQl9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBTYXZlSGVhZGVyRm9vdGVySW1hZ2VzKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChfdm1sRHJhd2luZ3NIRiAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX3ZtbERyYXdpbmdzSEYuQ291bnQgPT0gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoX3ZtbERyYXdpbmdzSEYuVXJpICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfd3MuUGFydC5EZWxldGVSZWxhdGlvbnNoaXAoX3ZtbERyYXdpbmdzSEYuUmVsSWQpOwogICAgICAgICAgICAgICAgICAgICAgICBfd3MuX3BhY2thZ2UuUGFja2FnZS5EZWxldGVQYXJ0KF92bWxEcmF3aW5nc0hGLlVyaSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChfdm1sRHJhd2luZ3NIRi5VcmkgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92bWxEcmF3aW5nc0hGLlVyaSA9IFhtbEhlbHBlci5HZXROZXdVcmkoX3dzLl9wYWNrYWdlLlBhY2thZ2UsIEAiL3hsL2RyYXdpbmdzL3ZtbERyYXdpbmd7MH0udm1sIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChfdm1sRHJhd2luZ3NIRi5QYXJ0ID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfdm1sRHJhd2luZ3NIRi5QYXJ0ID0gX3dzLl9wYWNrYWdlLlBhY2thZ2UuQ3JlYXRlUGFydChfdm1sRHJhd2luZ3NIRi5VcmksICJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQudm1sRHJhd2luZyIsIF93cy5fcGFja2FnZS5Db21wcmVzc2lvbik7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWwgPSBfd3MuUGFydC5DcmVhdGVSZWxhdGlvbnNoaXAoVXJpSGVscGVyLkdldFJlbGF0aXZlVXJpKF93cy5Xb3Jrc2hlZXRVcmksIF92bWxEcmF3aW5nc0hGLlVyaSksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcyArICIvdm1sRHJhd2luZyIpOwogICAgICAgICAgICAgICAgICAgICAgICBfd3MuU2V0SEZMZWdhY3lEcmF3aW5nUmVsKHJlbC5JZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIF92bWxEcmF3aW5nc0hGLlJlbElkID0gcmVsLklkOwogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoIChFeGNlbFZtbERyYXdpbmdQaWN0dXJlIGRyYXcgaW4gX3ZtbERyYXdpbmdzSEYpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbCA9IF92bWxEcmF3aW5nc0hGLlBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaShfdm1sRHJhd2luZ3NIRi5VcmksIGRyYXcuSW1hZ2VVcmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMgKyAiL2ltYWdlIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcmF3LlJlbElkID0gcmVsLklkOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF92bWxEcmF3aW5nc0hGLlZtbERyYXdpbmdYbWwuU2F2ZShfdm1sRHJhd2luZ3NIRi5QYXJ0LkdldFN0cmVhbSgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCQlwcml2YXRlIHN0cmluZyBHZXRUZXh0KEV4Y2VsSGVhZGVyRm9vdGVyVGV4dCBoZWFkZXJGb290ZXIpCgkJewoJCQlzdHJpbmcgcmV0ID0gIiI7CgkJCWlmIChoZWFkZXJGb290ZXIuTGVmdEFsaWduZWRUZXh0ICE9IG51bGwpCgkJCQlyZXQgKz0gIiZMIiArIGhlYWRlckZvb3Rlci5MZWZ0QWxpZ25lZFRleHQ7CgkJCWlmIChoZWFkZXJGb290ZXIuQ2VudGVyZWRUZXh0ICE9IG51bGwpCgkJCQlyZXQgKz0gIiZDIiArIGhlYWRlckZvb3Rlci5DZW50ZXJlZFRleHQ7CgkJCWlmIChoZWFkZXJGb290ZXIuUmlnaHRBbGlnbmVkVGV4dCAhPSBudWxsKQoJCQkJcmV0ICs9ICImUiIgKyBoZWFkZXJGb290ZXIuUmlnaHRBbGlnbmVkVGV4dDsKCQkJcmV0dXJuIHJldDsKCQl9CgkJI2VuZHJlZ2lvbgoJfQoJI2VuZHJlZ2lvbgp9Cg==