ZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9FZGdlLmpzIGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL0VkZ2UuanMKaW5kZXggNjE1YzhjMC4uNjIwYzcwMyAxMDA2NDQKLS0tIGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL0VkZ2UuanMKKysrIGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL0VkZ2UuanMKQEAgLTEsMzMgKzEsMzMgQEAKLS8qIENvcHlyaWdodCAyMDE2LCBIdWF3ZWkgVGVjaG5vbG9naWVzIENvLiwgTHRkLg0KLSAqDQotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7DQotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdA0KLSAqDQotICogICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wDQotICoNCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlDQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4NCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kDQotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQotICovDQotDQotdmFyIGVkZ2VDb2xvcnMgPSB7DQotICAgIHJlZDogIiNmMDAiLA0KLSAgICBncmVlbjogIiMwZjAiLA0KLSAgICBibHVlOiAiIzAwZiIsDQotICAgIHllbGxvdzogIiNmZjAiLA0KLSAgICBncmV5OiAiI2RkZCIsDQotICAgIGJsYWNrOiAiIzAwMCINCi19DQotDQotZnVuY3Rpb24gRWRnZShpZCwgbGFiZWwsIHNvdXJjZSwgdGFyZ2V0LCBzaXplLCBjb2xvcikgew0KLSAgICB0aGlzLmlkID0gaWQ7DQotICAgIHRoaXMubGFiZWwgPSBsYWJlbDsNCi0gICAgdGhpcy5zb3VyY2UgPSBzb3VyY2U7DQotICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0Ow0KLSAgICB0aGlzLnR5cGUgPSAnbGluZSc7DQotICAgIHRoaXMuc2l6ZSA9IHNpemU7DQotICAgIHRoaXMuY29sb3IgPSBlZGdlQ29sb3JzW2NvbG9yXTsNCi19DQorLyogQ29weXJpZ2h0IDIwMTYsIEh1YXdlaSBUZWNobm9sb2dpZXMgQ28uLCBMdGQuCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworIAordmFyIGVkZ2VDb2xvcnMgPSB7CisgIHJlZCA6ICIjZjAwIiwKKyAgZ3JlZW46ICIjMGYwIiwKKyAgYmx1ZTogIiMwMGYiLAorICB5ZWxsb3c6ICIjZmYwIiwKKyAgZ3JleTogIiM1NTUiLAorICBibGFjazogIiMwMDAiCit9CisKK2Z1bmN0aW9uIEVkZ2UoaWQsIGxhYmVsLCBzb3VyY2UsIHRhcmdldCwgc2l6ZSwgY29sb3IpIHsKKyAgdGhpcy5pZCA9IGlkOworICB0aGlzLmxhYmVsID0gbGFiZWw7CisgIHRoaXMuc291cmNlID0gc291cmNlOworICB0aGlzLnRhcmdldCA9IHRhcmdldDsKKyAgdGhpcy50eXBlID0gJ2xpbmUnOworICB0aGlzLnNpemUgPSBzaXplOworICB0aGlzLmNvbG9yID0gZWRnZUNvbG9yc1tjb2xvcl07Cit9CmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vTm9kZS5qcyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9Ob2RlLmpzCmluZGV4IDEyZDAxZjkuLjgyMTVjM2MgMTAwNjQ0Ci0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9Ob2RlLmpzCisrKyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9Ob2RlLmpzCkBAIC0xLDM1ICsxLDM1IEBACi0vKiBDb3B5cmlnaHQgMjAxNiwgSHVhd2VpIFRlY2hub2xvZ2llcyBDby4sIEx0ZC4NCi0gKg0KLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4NCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQNCi0gKg0KLSAqICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMA0KLSAqDQotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsDQotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuDQotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLg0KLSAqLw0KLQ0KLXZhciBpY29uID0gew0KLSAgICB0eXBlMTogImpzL3RvcG8vaW1nL05FVVAucG5nIiwNCi0gICAgdHlwZTI6ICJqcy90b3BvL2ltZy9ORVRXT1JLLnBuZyIsDQotICAgIHR5cGUzOiAianMvdG9wby9pbWcvc2l0ZS5wbmciDQotfQ0KLWZ1bmN0aW9uIE5vZGUoaWQsIGxhYmVsLCBzaXplLCB0eXBlLCB4LCB5KSB7DQotICAgIHRoaXMuaWQgPSBpZDsNCi0gICAgdGhpcy5sYWJlbCA9IGxhYmVsOw0KLSAgICB0aGlzLnR5cGUgPSAic3F1YXJlIjsNCi0gICAgdGhpcy54ID0geDsNCi0gICAgdGhpcy55ID0geTsNCi0gICAgdGhpcy5zaXplID0gc2l6ZTsNCi0gICAgdGhpcy5jb2xvciA9ICJ3aGl0ZSI7DQotICAgIHRoaXMuYm9yZGVyQ29sb3IgPSAid2hpdGUiOw0KLSAgICB0aGlzLmltYWdlID0gew0KLSAgICAgICAgdXJsOiBpY29uW3R5cGVdLA0KLSAgICAgICAgc2NhbGU6IDEuMCwNCi0gICAgICAgIGNsaXA6IDEuMA0KLSAgICB9Ow0KLX0NCisvKiBDb3B5cmlnaHQgMjAxNiwgSHVhd2VpIFRlY2hub2xvZ2llcyBDby4sIEx0ZC4KKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisgCit2YXIgaWNvbiA9IHsKKwlkZXZpY2VfaWNvbiA6ICJpbWFnZXMvdG9wby9ORVVQLnBuZyIsCisgIHNmY19kZXZpY2VfaWNvbiA6ICJpbWFnZXMvdG9wby9PVEhFUl8zLnBuZyIsCisJbmV0d29ya19pY29uIDogImltYWdlcy90b3BvL05FVFdPUksucG5nIgorfQorZnVuY3Rpb24gTm9kZShpZCwgbGFiZWwsIHNpemUsIHR5cGUsIHgsIHkpIHsKKwl0aGlzLmlkID0gaWQ7CisJdGhpcy5sYWJlbCA9IGxhYmVsOworCXRoaXMudHlwZSA9ICJzcXVhcmUiOworCXRoaXMueCA9IHg7CisJdGhpcy55ID0geTsKKwl0aGlzLnNpemUgPSBzaXplOworCXRoaXMuY29sb3IgPSAid2hpdGUiOworCXRoaXMuYm9yZGVyQ29sb3IgPSAid2hpdGUiOworCXRoaXMuaW1hZ2UgPSB7CisJCXVybCA6IGljb25bdHlwZV0sCisJCXNjYWxlIDogMS4wLAorCQljbGlwIDogMS4wCisJfTsKK30KZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9PdmVybGF5VG9wb2xvZ3kuanMgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vT3ZlcmxheVRvcG9sb2d5LmpzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdjMzVjMzgKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vT3ZlcmxheVRvcG9sb2d5LmpzCkBAIC0wLDAgKzEsMTE4IEBACisvKiBDb3B5cmlnaHQgMjAxNiwgSHVhd2VpIFRlY2hub2xvZ2llcyBDby4sIEx0ZC4KKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK2Z1bmN0aW9uIGV4dHJhY3RPdmVybGF5VlBOSWQoKQoreworICB2YXIgcGFyYW1ldGVycyA9IGxvY2F0aW9uLnNlYXJjaC5zdWJzdHJpbmcoMSkuc3BsaXQoIiYiKTsKKyAgdmFyIHRlbXAgPSBwYXJhbWV0ZXJzWzBdLnNwbGl0KCI9Iik7CisgIHZhciBpZCA9IHVuZXNjYXBlKHRlbXBbMV0pOworICAKKyAgcmV0dXJuIGlkOworfQorCitmdW5jdGlvbiBUb3BvbG9neShjb250YWluZXJJZCkgeworCisJLyoqCisJICogSU1QT1JUQU5UOiBUaGlzIG9ubHkgd29ya3Mgd2l0aCB0aGUgY2FudmFzIHJlbmRlcmVyLiBUQkQgaW4gdGhlIGZ1dHVyZQorCSAqIHdpbGwgYWxzbyBzdXBwb3J0IHRoZSBXZWJHTCByZW5kZXJlci4KKwkgKi8KKwlzaWdtYS51dGlscy5wa2coJ3NpZ21hLmNhbnZhcy5ub2RlcycpOworCisJdGhpcy5zID0gbmV3IHNpZ21hKHsKKwkJZ3JhcGggOiB7CisJCQlub2RlcyA6IFtdLAorCQkJZWRnZXMgOiBbXQorCQl9LAorCQlyZW5kZXJlciA6IHsKKwkJCS8vIElNUE9SVEFOVDoKKwkJCS8vIFRoaXMgd29ya3Mgb25seSB3aXRoIHRoZSBjYW52YXMgcmVuZGVyZXIsIHNvIHRoZQorCQkJLy8gcmVuZGVyZXIgdHlwZSBzZXQgYXMgImNhbnZhcyIgaXMgbmVjZXNzYXJ5IGhlcmUuCisJCQljb250YWluZXIgOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChjb250YWluZXJJZCksCisJCQl0eXBlIDogJ2NhbnZhcycKKwkJfSwKKwkJc2V0dGluZ3MgOiB7CisJCQltaW5Ob2RlU2l6ZSA6IDgsCisJCQltYXhOb2RlU2l6ZSA6IDY0LAorCQkJZWRnZUxhYmVsU2l6ZSA6ICdwcm9wb3J0aW9uYWwnCisJCX0KKwl9KTsKKwl0aGlzLmFkZE5vZGUgPSBhZGROb2RlOworCXRoaXMuYWRkRWRnZSA9IGFkZEVkZ2U7Cit9CisKK2Z1bmN0aW9uIGFkZE5vZGUobm9kZSkgeworCisJdGhpcy5zLmdyYXBoLmFkZE5vZGUobm9kZSk7CisKK30KKworZnVuY3Rpb24gYWRkRWRnZShlZGdlKSB7CisJdGhpcy5zLmdyYXBoLmFkZEVkZ2UoZWRnZSk7Cit9CisKK2Z1bmN0aW9uIGluaXQoKSB7CisKKwl2YXIgbm9kZTEgPSBuZXcgTm9kZSgiMSIsICJUaGluQ1BFIiwgMTYsICJkZXZpY2VfaWNvbiIsIDAuMSwgMC41KTsKKyAgdmFyIG5vZGUyID0gbmV3IE5vZGUoIjIiLCAidkNQRSIsIDE2LCAiZGV2aWNlX2ljb24iLCAwLjQsIDAuNSk7CisJdmFyIG5vZGUzID0gbmV3IE5vZGUoIjMiLCAiR1ciLCAxNiwgImRldmljZV9pY29uIiwgMC44LCAwLjUpOworCisgIHZhciBub2RlNiA9IG5ldyBOb2RlKCI2IiwgIkZXIiwgOCwgInNmY19kZXZpY2VfaWNvbiIsIDAuODUsIDAuNCk7CisgIHZhciBub2RlNyA9IG5ldyBOb2RlKCI3IiwgIkxCIiwgOCwgInNmY19kZXZpY2VfaWNvbiIsIDAuOSwgMC4zKTsKKyAgdmFyIG5vZGU4ID0gbmV3IE5vZGUoIjgiLCAiVlBDIiwgNDgsICJuZXR3b3JrX2ljb24iLCAxLjA1LCAwLjQpOworICAKKyAgdmFyIG5vZGU0ID0gbmV3IE5vZGUoIjQiLCAidkZXIiwgOCwgInNmY19kZXZpY2VfaWNvbiIsIDAuMzIsIDAuMzUpOworICB2YXIgbm9kZTUgPSBuZXcgTm9kZSgiNSIsICJ2TEIiLCA4LCAic2ZjX2RldmljZV9pY29uIiwgMC40OCwgMC4zNSk7CisKKwl2YXIgZWRnZTEgPSBuZXcgRWRnZSgiZTEiLCAiVnhMQU4iLCAiMSIsICIyIiwgMC41LCAiYmx1ZSIpOworCXZhciBlZGdlMiA9IG5ldyBFZGdlKCJlMiIsICJJUFNlYyIsICIyIiwgIjMiLCAwLjUsICJncmVlbiIpOworICAKKyAgCisgIHZhciBlZGdlMyA9IG5ldyBFZGdlKCJlMyIsICIiLCAiMiIsICI0IiwgMC41LCAiZ3JleSIpOworICB2YXIgZWRnZTQgPSBuZXcgRWRnZSgiZTQiLCAiIiwgIjQiLCAiNSIsIDAuNSwgImdyZXkiKTsKKyAgdmFyIGVkZ2U1ID0gbmV3IEVkZ2UoImU1IiwgIiIsICI1IiwgIjIiLCAwLjUsICJncmV5Iik7CisgIAorICB2YXIgZWRnZTYgPSBuZXcgRWRnZSgiZTYiLCAiIiwgIjMiLCAiNiIsIDAuNSwgImdyZXkiKTsKKyAgdmFyIGVkZ2U3ID0gbmV3IEVkZ2UoImU3IiwgIiIsICI2IiwgIjciLCAwLjUsICJncmV5Iik7CisgIHZhciBlZGdlOCA9IG5ldyBFZGdlKCJlOCIsICIiLCAiNyIsICI4IiwgMC41LCAiZ3JleSIpOworICAKKwl2YXIgdG9wb2xvZ3kgPSBuZXcgVG9wb2xvZ3koImNvbnRhaW5lciIpOworICAKKwl0b3BvbG9neS5hZGROb2RlKG5vZGUxKTsKKwl0b3BvbG9neS5hZGROb2RlKG5vZGUyKTsKKwl0b3BvbG9neS5hZGROb2RlKG5vZGUzKTsKKyAgdG9wb2xvZ3kuYWRkTm9kZShub2RlNCk7CisJdG9wb2xvZ3kuYWRkTm9kZShub2RlNSk7CisgIHRvcG9sb2d5LmFkZE5vZGUobm9kZTYpOworICB0b3BvbG9neS5hZGROb2RlKG5vZGU3KTsKKwl0b3BvbG9neS5hZGROb2RlKG5vZGU4KTsKKworCXRvcG9sb2d5LmFkZEVkZ2UoZWRnZTEpOworCXRvcG9sb2d5LmFkZEVkZ2UoZWRnZTIpOworICB0b3BvbG9neS5hZGRFZGdlKGVkZ2UzKTsKKyAgdG9wb2xvZ3kuYWRkRWRnZShlZGdlNCk7CisJdG9wb2xvZ3kuYWRkRWRnZShlZGdlNSk7CisgIAorICB0b3BvbG9neS5hZGRFZGdlKGVkZ2U2KTsKKyAgdG9wb2xvZ3kuYWRkRWRnZShlZGdlNyk7CisJdG9wb2xvZ3kuYWRkRWRnZShlZGdlOCk7CisgIAorICAKKwlDdXN0b21TaGFwZXMuaW5pdCh0b3BvbG9neS5zKTsKKwl0b3BvbG9neS5zLnJlZnJlc2goKTsKK30KKworJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKSB7CisJaW5pdCgpOworfSk7ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL1RvcG9sb2d5LmpzIGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL1RvcG9sb2d5LmpzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwNTA1OTk0Li4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9Ub3BvbG9neS5qcworKysgL2Rldi9udWxsCkBAIC0xLDExMyArMCwwIEBACi0vKiBDb3B5cmlnaHQgMjAxNiwgSHVhd2VpIFRlY2hub2xvZ2llcyBDby4sIEx0ZC4NCi0gKg0KLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4NCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQNCi0gKg0KLSAqICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMA0KLSAqDQotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsDQotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuDQotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLg0KLSAqLw0KLQ0KLWZ1bmN0aW9uIFRvcG9sb2d5KGNvbnRhaW5lcklkKSB7DQotDQotICAgIC8qKg0KLSAgICAgKiBJTVBPUlRBTlQ6IFRoaXMgb25seSB3b3JrcyB3aXRoIHRoZSBjYW52YXMgcmVuZGVyZXIuIFRCRCBpbiB0aGUgZnV0dXJlDQotICAgICAqIHdpbGwgYWxzbyBzdXBwb3J0IHRoZSBXZWJHTCByZW5kZXJlci4NCi0gICAgICovDQotICAgIHNpZ21hLnV0aWxzLnBrZygnc2lnbWEuY2FudmFzLm5vZGVzJyk7DQotDQotICAgIHRoaXMucyA9IG5ldyBzaWdtYSh7DQotICAgICAgICBncmFwaDogew0KLSAgICAgICAgICAgIG5vZGVzOiBbXSwNCi0gICAgICAgICAgICBlZGdlczogW10NCi0gICAgICAgIH0sDQotICAgICAgICByZW5kZXJlcjogew0KLSAgICAgICAgICAgIC8vIElNUE9SVEFOVDoNCi0gICAgICAgICAgICAvLyBUaGlzIHdvcmtzIG9ubHkgd2l0aCB0aGUgY2FudmFzIHJlbmRlcmVyLCBzbyB0aGUNCi0gICAgICAgICAgICAvLyByZW5kZXJlciB0eXBlIHNldCBhcyAiY2FudmFzIiBpcyBuZWNlc3NhcnkgaGVyZS4NCi0gICAgICAgICAgICBjb250YWluZXI6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGNvbnRhaW5lcklkKSwNCi0gICAgICAgICAgICB0eXBlOiAnY2FudmFzJw0KLSAgICAgICAgfSwNCi0gICAgICAgIHNldHRpbmdzOiB7DQotICAgICAgICAgICAgbWluTm9kZVNpemU6IDQsDQotICAgICAgICAgICAgbWF4Tm9kZVNpemU6IDQ4LA0KLSAgICAgICAgICAgIGVkZ2VMYWJlbFNpemU6ICdwcm9wb3J0aW9uYWwnDQotICAgICAgICB9DQotICAgIH0pOw0KLSAgICB0aGlzLmFkZE5vZGUgPSBhZGROb2RlOw0KLSAgICB0aGlzLmFkZEVkZ2UgPSBhZGRFZGdlOw0KLX0NCi0NCi1mdW5jdGlvbiBhZGROb2RlKG5vZGUpIHsNCi0NCi0gICAgdGhpcy5zLmdyYXBoLmFkZE5vZGUobm9kZSk7DQotDQotfQ0KLQ0KLWZ1bmN0aW9uIGFkZEVkZ2UoZWRnZSkgew0KLSAgICB0aGlzLnMuZ3JhcGguYWRkRWRnZShlZGdlKTsNCi19DQotDQotZnVuY3Rpb24gaW5pdCgpIHsNCi0NCi0gICAgdmFyIG5vZGUxID0gbmV3IE5vZGUoIjEiLCAiVGhpbkNQRSIsIDgsICJ0eXBlMSIsIDAuMiwgMC41KTsNCi0gICAgdmFyIG5vZGUyID0gbmV3IE5vZGUoIjIiLCAidkNQRSIsIDgsICJ0eXBlMSIsIDAuNSwgMC41KTsNCi0gICAgdmFyIG5vZGUzID0gbmV3IE5vZGUoIjMiLCAiVlBDIiwgMTYsICJ0eXBlMiIsIDAuOCwgMC41KTsNCi0NCi0gICAgdmFyIG5vZGU0ID0gbmV3IE5vZGUoIjQiLCAiU2l0ZSIsIDE2LCAidHlwZTMiLCAwLjIsIDAuNTUpOw0KLSAgICB2YXIgbm9kZTUgPSBuZXcgTm9kZSgiNSIsICJQT1AiLCAyNCwgInR5cGUzIiwgMC41LCAwLjU1KTsNCi0gICAgdmFyIG5vZGU2ID0gbmV3IE5vZGUoIjYiLCAiREMiLCAzMiwgInR5cGUzIiwgMC44LCAwLjU1KTsNCi0NCi0gICAgdmFyIG5vZGU3ID0gbmV3IE5vZGUoIjciLCAidkZXIiwgNiwgInR5cGUxIiwgMC40NSwgMC40NSk7DQotICAgIHZhciBub2RlOCA9IG5ldyBOb2RlKCI4IiwgInZMQiIsIDYsICJ0eXBlMSIsIDAuNTUsIDAuNDUpOw0KLQ0KLSAgICB2YXIgZWRnZTEgPSBuZXcgRWRnZSgiZTEiLCAiVnhMQU4iLCAiMSIsICIyIiwgMC41LCAiYmx1ZSIpOw0KLSAgICB2YXIgZWRnZTIgPSBuZXcgRWRnZSgiZTIiLCAiSVBTZWMiLCAiMiIsICIzIiwgMC41LCAiZ3JlZW4iKTsNCi0NCi0gICAgdmFyIGVkZ2UzID0gbmV3IEVkZ2UoImUzIiwgImluIiwgIjEiLCAiNCIsIDAuNSwgImdyZXkiKTsNCi0gICAgdmFyIGVkZ2U0ID0gbmV3IEVkZ2UoImU0IiwgImluIiwgIjIiLCAiNSIsIDAuNSwgImdyZXkiKTsNCi0gICAgdmFyIGVkZ2U1ID0gbmV3IEVkZ2UoImU1IiwgImluIiwgIjMiLCAiNiIsIDAuNSwgImdyZXkiKTsNCi0NCi0gICAgdmFyIGVkZ2U2ID0gbmV3IEVkZ2UoImU2IiwgIkwyVlBOIiwgIjQiLCAiNSIsIDAuNSwgImJsYWNrIik7DQotICAgIHZhciBlZGdlNyA9IG5ldyBFZGdlKCJlNyIsICJMM1ZQTiIsICI1IiwgIjYiLCAwLjUsICJibGFjayIpOw0KLQ0KLSAgICB2YXIgZWRnZTggPSBuZXcgRWRnZSgiZTgiLCAiIiwgIjIiLCAiNyIsIDAuNSwgInllbGxvdyIpOw0KLSAgICB2YXIgZWRnZTkgPSBuZXcgRWRnZSgiZTkiLCAiIiwgIjciLCAiOCIsIDAuNSwgInllbGxvdyIpOw0KLSAgICB2YXIgZWRnZTEwID0gbmV3IEVkZ2UoImUxMCIsICIiLCAiOCIsICIyIiwgMC41LCAieWVsbG93Iik7DQotDQotICAgIHZhciB0b3BvbG9neSA9IG5ldyBUb3BvbG9neSgiY29udGFpbmVyIik7DQotDQotICAgIHRvcG9sb2d5LmFkZE5vZGUobm9kZTEpOw0KLSAgICB0b3BvbG9neS5hZGROb2RlKG5vZGUyKTsNCi0gICAgdG9wb2xvZ3kuYWRkTm9kZShub2RlMyk7DQotICAgIHRvcG9sb2d5LmFkZE5vZGUobm9kZTQpOw0KLSAgICB0b3BvbG9neS5hZGROb2RlKG5vZGU1KTsNCi0gICAgdG9wb2xvZ3kuYWRkTm9kZShub2RlNik7DQotICAgIHRvcG9sb2d5LmFkZE5vZGUobm9kZTcpOw0KLSAgICB0b3BvbG9neS5hZGROb2RlKG5vZGU4KTsNCi0NCi0gICAgdG9wb2xvZ3kuYWRkRWRnZShlZGdlMSk7DQotICAgIHRvcG9sb2d5LmFkZEVkZ2UoZWRnZTIpOw0KLSAgICB0b3BvbG9neS5hZGRFZGdlKGVkZ2UzKTsNCi0gICAgdG9wb2xvZ3kuYWRkRWRnZShlZGdlNCk7DQotICAgIHRvcG9sb2d5LmFkZEVkZ2UoZWRnZTUpOw0KLQ0KLQ0KLSAgICB0b3BvbG9neS5hZGRFZGdlKGVkZ2U2KTsNCi0gICAgdG9wb2xvZ3kuYWRkRWRnZShlZGdlNyk7DQotICAgIHRvcG9sb2d5LmFkZEVkZ2UoZWRnZTgpOw0KLSAgICB0b3BvbG9neS5hZGRFZGdlKGVkZ2U5KTsNCi0gICAgdG9wb2xvZ3kuYWRkRWRnZShlZGdlMTApOw0KLQ0KLSAgICBDdXN0b21TaGFwZXMuaW5pdCh0b3BvbG9neS5zKTsNCi0gICAgdG9wb2xvZ3kucy5yZWZyZXNoKCk7DQotfQ0KLQ0KLSQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHsNCi0gICAgaW5pdCgpOw0KLX0pOwpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvTkVET1dOLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvTkVET1dOLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTliYmU1ZS4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL05FRE9XTi5wbmcKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL05FRE9XTl9zZWxlY3RlZC5wbmcgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL05FRE9XTl9zZWxlY3RlZC5wbmcKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlmYzVhYWEuLjAwMDAwMDAKLS0tIGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9ORURPV05fc2VsZWN0ZWQucG5nCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9ORVRXT1JLLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvTkVUV09SSy5wbmcKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkzMWRiZTcuLjAwMDAwMDAKLS0tIGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9ORVRXT1JLLnBuZworKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvTkVUV09SS19FREdFLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvTkVUV09SS19FREdFLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzc5YmRkNC4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL05FVFdPUktfRURHRS5wbmcKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL05FVFdPUktfc2VsZWN0ZWQucG5nIGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9ORVRXT1JLX3NlbGVjdGVkLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTMxZGJlNy4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL05FVFdPUktfc2VsZWN0ZWQucG5nCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9ORVVQLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvTkVVUC5wbmcKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI4MmVhODUuLjAwMDAwMDAKLS0tIGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9ORVVQLnBuZworKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvTkVVUF9zZWxlY3RlZC5wbmcgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL05FVVBfc2VsZWN0ZWQucG5nCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NWYwZGM4Li4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvTkVVUF9zZWxlY3RlZC5wbmcKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL09USEVSLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvT1RIRVIucG5nCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiODJlYTg1Li4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvT1RIRVIucG5nCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9PVEhFUl8wLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvT1RIRVJfMC5wbmcKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIwOTlmMDIuLjAwMDAwMDAKLS0tIGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9PVEhFUl8wLnBuZworKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvT1RIRVJfMF9zZWxlY3RlZC5wbmcgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL09USEVSXzBfc2VsZWN0ZWQucG5nCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1YTBjZjczLi4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvT1RIRVJfMF9zZWxlY3RlZC5wbmcKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL09USEVSXzEucG5nIGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9PVEhFUl8xLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWU5NThhZC4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL09USEVSXzEucG5nCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9PVEhFUl8xX3NlbGVjdGVkLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvT1RIRVJfMV9zZWxlY3RlZC5wbmcKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQyOWEwYmUuLjAwMDAwMDAKLS0tIGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9PVEhFUl8xX3NlbGVjdGVkLnBuZworKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvT1RIRVJfMi5wbmcgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL09USEVSXzIucG5nCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjOTQ3ZGUyLi4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvT1RIRVJfMi5wbmcKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL09USEVSXzJfc2VsZWN0ZWQucG5nIGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9PVEhFUl8yX3NlbGVjdGVkLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmZmOTJlMC4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL09USEVSXzJfc2VsZWN0ZWQucG5nCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9PVEhFUl8zLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvT1RIRVJfMy5wbmcKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFhM2Y1NjAuLjAwMDAwMDAKLS0tIGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9PVEhFUl8zLnBuZworKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvT1RIRVJfM19zZWxlY3RlZC5wbmcgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL09USEVSXzNfc2VsZWN0ZWQucG5nCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMDBiZjZkLi4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvT1RIRVJfM19zZWxlY3RlZC5wbmcKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL09USEVSX3NlbGVjdGVkLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvT1RIRVJfc2VsZWN0ZWQucG5nCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NWYwZGM4Li4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvT1RIRVJfc2VsZWN0ZWQucG5nCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9jbG91ZC5wbmcgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL2Nsb3VkLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTE0ZDAzMS4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL2Nsb3VkLnBuZworKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvY2xvdWRyb3V0ZS5wbmcgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL2Nsb3Vkcm91dGUucG5nCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMmQ1NTQyLi4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvY2xvdWRyb3V0ZS5wbmcKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL2Nyb3NzU3VibmV0LnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvY3Jvc3NTdWJuZXQucG5nCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MTIxNmFjLi4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvY3Jvc3NTdWJuZXQucG5nCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9kZWxldGVfYXNici5wbmcgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL2RlbGV0ZV9hc2JyLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjlhMDZiZC4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL2RlbGV0ZV9hc2JyLnBuZworKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvbWFya19zaW5rLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvbWFya19zaW5rLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjkyOWY2My4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL21hcmtfc2luay5wbmcKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL21hcmtfc291cmNlLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvbWFya19zb3VyY2UucG5nCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMGFhNWJiLi4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvbWFya19zb3VyY2UucG5nCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9uZXR3b3JrZG93bi5wbmcgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL25ldHdvcmtkb3duLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOThjNjQzNi4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL25ldHdvcmtkb3duLnBuZworKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvbm9kZV9ncmF5LnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvbm9kZV9ncmF5LnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTRjMjg3ZC4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL25vZGVfZ3JheS5wbmcKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL25vZGVfZ3JlZW4ucG5nIGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9ub2RlX2dyZWVuLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzBlOTFmNS4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL25vZGVfZ3JlZW4ucG5nCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9ub2RlX3JlZC5wbmcgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL25vZGVfcmVkLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTk1ZGY5Mi4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL25vZGVfcmVkLnBuZworKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvcm91dGVyLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvcm91dGVyLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjgyZWE4NS4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL3JvdXRlci5wbmcKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL3JvdXRlcl9zZWxlY3RlZC5wbmcgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL3JvdXRlcl9zZWxlY3RlZC5wbmcKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY1ZjBkYzguLjAwMDAwMDAKLS0tIGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9yb3V0ZXJfc2VsZWN0ZWQucG5nCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9zaXRlLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvc2l0ZS5wbmcKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGIzNTM4NTIuLjAwMDAwMDAKLS0tIGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9zaXRlLnBuZworKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvc2l0ZUljb25fZmVhdHVyZS5wbmcgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL3NpdGVJY29uX2ZlYXR1cmUucG5nCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZGRmMGEzLi4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvc2l0ZUljb25fZmVhdHVyZS5wbmcKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL3NpdGVfc2VsZWN0ZWQucG5nIGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9zaXRlX3NlbGVjdGVkLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjVjMDBhZS4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL3NpdGVfc2VsZWN0ZWQucG5nCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9zaXRlZG93bi5wbmcgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL3NpdGVkb3duLnBuZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmRiNDg1MC4uMDAwMDAwMAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL3NpdGVkb3duLnBuZworKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvc2l0ZWRvd25fc2VsZWN0ZWQucG5nIGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9zaXRlZG93bl9zZWxlY3RlZC5wbmcKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJkNWFmODMuLjAwMDAwMDAKLS0tIGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL2ltZy9zaXRlZG93bl9zZWxlY3RlZC5wbmcKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vaW1nL3UxOTYzLnBuZyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvdTE5NjMucG5nCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MzFjOWFjLi4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9pbWcvdTE5NjMucG5nCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL3NpZ21hL0xJQ0VOU0UudHh0IGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL3NpZ21hL0xJQ0VOU0UudHh0CmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4MTczOWRmLi4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9zaWdtYS9MSUNFTlNFLnR4dAorKysgL2Rldi9udWxsCkBAIC0xLDEyICswLDAgQEAKLUNvcHlyaWdodCAoQykgMjAxMy0yMDE0LCBBbGV4aXMgSmFjb215LCBodHRwOi8vc2lnbWFqcy5vcmcKLQotUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwKLXRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsCi1hbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKLQotVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCi0KLVRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAotRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKLUxJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MKLUlOIFRIRSBTT0ZUV0FSRS4KZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9zaWdtYS9qcXVlcnktMy4xLjAubWluLmpzIGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL3NpZ21hL2pxdWVyeS0zLjEuMC5taW4uanMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY2YTZhOTkuLjAwMDAwMDAKLS0tIGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL3NpZ21hL2pxdWVyeS0zLjEuMC5taW4uanMKKysrIC9kZXYvbnVsbApAQCAtMSw0ICswLDAgQEAKLS8qISBqUXVlcnkgdjMuMS4wIHwgKGMpIGpRdWVyeSBGb3VuZGF0aW9uIHwganF1ZXJ5Lm9yZy9saWNlbnNlICovCi0hZnVuY3Rpb24oYSxiKXsidXNlIHN0cmljdCI7Im9iamVjdCI9PXR5cGVvZiBtb2R1bGUmJiJvYmplY3QiPT10eXBlb2YgbW9kdWxlLmV4cG9ydHM/bW9kdWxlLmV4cG9ydHM9YS5kb2N1bWVudD9iKGEsITApOmZ1bmN0aW9uKGEpe2lmKCFhLmRvY3VtZW50KXRocm93IG5ldyBFcnJvcigialF1ZXJ5IHJlcXVpcmVzIGEgd2luZG93IHdpdGggYSBkb2N1bWVudCIpO3JldHVybiBiKGEpfTpiKGEpfSgidW5kZWZpbmVkIiE9dHlwZW9mIHdpbmRvdz93aW5kb3c6dGhpcyxmdW5jdGlvbihhLGIpeyJ1c2Ugc3RyaWN0Ijt2YXIgYz1bXSxkPWEuZG9jdW1lbnQsZT1PYmplY3QuZ2V0UHJvdG90eXBlT2YsZj1jLnNsaWNlLGc9Yy5jb25jYXQsaD1jLnB1c2gsaT1jLmluZGV4T2Ysaj17fSxrPWoudG9TdHJpbmcsbD1qLmhhc093blByb3BlcnR5LG09bC50b1N0cmluZyxuPW0uY2FsbChPYmplY3QpLG89e307ZnVuY3Rpb24gcChhLGIpe2I9Ynx8ZDt2YXIgYz1iLmNyZWF0ZUVsZW1lbnQoInNjcmlwdCIpO2MudGV4dD1hLGIuaGVhZC5hcHBlbmRDaGlsZChjKS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGMpfXZhciBxPSIzLjEuMCIscj1mdW5jdGlvbihhLGIpe3JldHVybiBuZXcgci5mbi5pbml0KGEsYil9LHM9L15bXHNcdUZFRkZceEEwXSt8W1xzXHVGRUZGXHhBMF0rJC9nLHQ9L14tbXMtLyx1PS8tKFthLXpdKS9nLHY9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYi50b1VwcGVyQ2FzZSgpfTtyLmZuPXIucHJvdG90eXBlPXtqcXVlcnk6cSxjb25zdHJ1Y3RvcjpyLGxlbmd0aDowLHRvQXJyYXk6ZnVuY3Rpb24oKXtyZXR1cm4gZi5jYWxsKHRoaXMpfSxnZXQ6ZnVuY3Rpb24oYSl7cmV0dXJuIG51bGwhPWE/YTwwP3RoaXNbYSt0aGlzLmxlbmd0aF06dGhpc1thXTpmLmNhbGwodGhpcyl9LHB1c2hTdGFjazpmdW5jdGlvbihhKXt2YXIgYj1yLm1lcmdlKHRoaXMuY29uc3RydWN0b3IoKSxhKTtyZXR1cm4gYi5wcmV2T2JqZWN0PXRoaXMsYn0sZWFjaDpmdW5jdGlvbihhKXtyZXR1cm4gci5lYWNoKHRoaXMsYSl9LG1hcDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2soci5tYXAodGhpcyxmdW5jdGlvbihiLGMpe3JldHVybiBhLmNhbGwoYixjLGIpfSkpfSxzbGljZTpmdW5jdGlvbigpe3JldHVybiB0aGlzLnB1c2hTdGFjayhmLmFwcGx5KHRoaXMsYXJndW1lbnRzKSl9LGZpcnN0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZXEoMCl9LGxhc3Q6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5lcSgtMSl9LGVxOmZ1bmN0aW9uKGEpe3ZhciBiPXRoaXMubGVuZ3RoLGM9K2ErKGE8MD9iOjApO3JldHVybiB0aGlzLnB1c2hTdGFjayhjPj0wJiZjPGI/W3RoaXNbY11dOltdKX0sZW5kOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucHJldk9iamVjdHx8dGhpcy5jb25zdHJ1Y3RvcigpfSxwdXNoOmgsc29ydDpjLnNvcnQsc3BsaWNlOmMuc3BsaWNlfSxyLmV4dGVuZD1yLmZuLmV4dGVuZD1mdW5jdGlvbigpe3ZhciBhLGIsYyxkLGUsZixnPWFyZ3VtZW50c1swXXx8e30saD0xLGk9YXJndW1lbnRzLmxlbmd0aCxqPSExO2ZvcigiYm9vbGVhbiI9PXR5cGVvZiBnJiYoaj1nLGc9YXJndW1lbnRzW2hdfHx7fSxoKyspLCJvYmplY3QiPT10eXBlb2YgZ3x8ci5pc0Z1bmN0aW9uKGcpfHwoZz17fSksaD09PWkmJihnPXRoaXMsaC0tKTtoPGk7aCsrKWlmKG51bGwhPShhPWFyZ3VtZW50c1toXSkpZm9yKGIgaW4gYSljPWdbYl0sZD1hW2JdLGchPT1kJiYoaiYmZCYmKHIuaXNQbGFpbk9iamVjdChkKXx8KGU9ci5pc0FycmF5KGQpKSk/KGU/KGU9ITEsZj1jJiZyLmlzQXJyYXkoYyk/YzpbXSk6Zj1jJiZyLmlzUGxhaW5PYmplY3QoYyk/Yzp7fSxnW2JdPXIuZXh0ZW5kKGosZixkKSk6dm9pZCAwIT09ZCYmKGdbYl09ZCkpO3JldHVybiBnfSxyLmV4dGVuZCh7ZXhwYW5kbzoialF1ZXJ5IisocStNYXRoLnJhbmRvbSgpKS5yZXBsYWNlKC9cRC9nLCIiKSxpc1JlYWR5OiEwLGVycm9yOmZ1bmN0aW9uKGEpe3Rocm93IG5ldyBFcnJvcihhKX0sbm9vcDpmdW5jdGlvbigpe30saXNGdW5jdGlvbjpmdW5jdGlvbihhKXtyZXR1cm4iZnVuY3Rpb24iPT09ci50eXBlKGEpfSxpc0FycmF5OkFycmF5LmlzQXJyYXksaXNXaW5kb3c6ZnVuY3Rpb24oYSl7cmV0dXJuIG51bGwhPWEmJmE9PT1hLndpbmRvd30saXNOdW1lcmljOmZ1bmN0aW9uKGEpe3ZhciBiPXIudHlwZShhKTtyZXR1cm4oIm51bWJlciI9PT1ifHwic3RyaW5nIj09PWIpJiYhaXNOYU4oYS1wYXJzZUZsb2F0KGEpKX0saXNQbGFpbk9iamVjdDpmdW5jdGlvbihhKXt2YXIgYixjO3JldHVybiEoIWF8fCJbb2JqZWN0IE9iamVjdF0iIT09ay5jYWxsKGEpKSYmKCEoYj1lKGEpKXx8KGM9bC5jYWxsKGIsImNvbnN0cnVjdG9yIikmJmIuY29uc3RydWN0b3IsImZ1bmN0aW9uIj09dHlwZW9mIGMmJm0uY2FsbChjKT09PW4pKX0saXNFbXB0eU9iamVjdDpmdW5jdGlvbihhKXt2YXIgYjtmb3IoYiBpbiBhKXJldHVybiExO3JldHVybiEwfSx0eXBlOmZ1bmN0aW9uKGEpe3JldHVybiBudWxsPT1hP2ErIiI6Im9iamVjdCI9PXR5cGVvZiBhfHwiZnVuY3Rpb24iPT10eXBlb2YgYT9qW2suY2FsbChhKV18fCJvYmplY3QiOnR5cGVvZiBhfSxnbG9iYWxFdmFsOmZ1bmN0aW9uKGEpe3AoYSl9LGNhbWVsQ2FzZTpmdW5jdGlvbihhKXtyZXR1cm4gYS5yZXBsYWNlKHQsIm1zLSIpLnJlcGxhY2UodSx2KX0sbm9kZU5hbWU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYS5ub2RlTmFtZSYmYS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpPT09Yi50b0xvd2VyQ2FzZSgpfSxlYWNoOmZ1bmN0aW9uKGEsYil7dmFyIGMsZD0wO2lmKHcoYSkpe2ZvcihjPWEubGVuZ3RoO2Q8YztkKyspaWYoYi5jYWxsKGFbZF0sZCxhW2RdKT09PSExKWJyZWFrfWVsc2UgZm9yKGQgaW4gYSlpZihiLmNhbGwoYVtkXSxkLGFbZF0pPT09ITEpYnJlYWs7cmV0dXJuIGF9LHRyaW06ZnVuY3Rpb24oYSl7cmV0dXJuIG51bGw9PWE/IiI6KGErIiIpLnJlcGxhY2UocywiIil9LG1ha2VBcnJheTpmdW5jdGlvbihhLGIpe3ZhciBjPWJ8fFtdO3JldHVybiBudWxsIT1hJiYodyhPYmplY3QoYSkpP3IubWVyZ2UoYywic3RyaW5nIj09dHlwZW9mIGE/W2FdOmEpOmguY2FsbChjLGEpKSxjfSxpbkFycmF5OmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbnVsbD09Yj8tMTppLmNhbGwoYixhLGMpfSxtZXJnZTpmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz0rYi5sZW5ndGgsZD0wLGU9YS5sZW5ndGg7ZDxjO2QrKylhW2UrK109YltkXTtyZXR1cm4gYS5sZW5ndGg9ZSxhfSxncmVwOmZ1bmN0aW9uKGEsYixjKXtmb3IodmFyIGQsZT1bXSxmPTAsZz1hLmxlbmd0aCxoPSFjO2Y8ZztmKyspZD0hYihhW2ZdLGYpLGQhPT1oJiZlLnB1c2goYVtmXSk7cmV0dXJuIGV9LG1hcDpmdW5jdGlvbihhLGIsYyl7dmFyIGQsZSxmPTAsaD1bXTtpZih3KGEpKWZvcihkPWEubGVuZ3RoO2Y8ZDtmKyspZT1iKGFbZl0sZixjKSxudWxsIT1lJiZoLnB1c2goZSk7ZWxzZSBmb3IoZiBpbiBhKWU9YihhW2ZdLGYsYyksbnVsbCE9ZSYmaC5wdXNoKGUpO3JldHVybiBnLmFwcGx5KFtdLGgpfSxndWlkOjEscHJveHk6ZnVuY3Rpb24oYSxiKXt2YXIgYyxkLGU7aWYoInN0cmluZyI9PXR5cGVvZiBiJiYoYz1hW2JdLGI9YSxhPWMpLHIuaXNGdW5jdGlvbihhKSlyZXR1cm4gZD1mLmNhbGwoYXJndW1lbnRzLDIpLGU9ZnVuY3Rpb24oKXtyZXR1cm4gYS5hcHBseShifHx0aGlzLGQuY29uY2F0KGYuY2FsbChhcmd1bWVudHMpKSl9LGUuZ3VpZD1hLmd1aWQ9YS5ndWlkfHxyLmd1aWQrKyxlfSxub3c6RGF0ZS5ub3csc3VwcG9ydDpvfSksImZ1bmN0aW9uIj09dHlwZW9mIFN5bWJvbCYmKHIuZm5bU3ltYm9sLml0ZXJhdG9yXT1jW1N5bWJvbC5pdGVyYXRvcl0pLHIuZWFjaCgiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvciBTeW1ib2wiLnNwbGl0KCIgIiksZnVuY3Rpb24oYSxiKXtqWyJbb2JqZWN0ICIrYisiXSJdPWIudG9Mb3dlckNhc2UoKX0pO2Z1bmN0aW9uIHcoYSl7dmFyIGI9ISFhJiYibGVuZ3RoImluIGEmJmEubGVuZ3RoLGM9ci50eXBlKGEpO3JldHVybiJmdW5jdGlvbiIhPT1jJiYhci5pc1dpbmRvdyhhKSYmKCJhcnJheSI9PT1jfHwwPT09Ynx8Im51bWJlciI9PXR5cGVvZiBiJiZiPjAmJmItMSBpbiBhKX12YXIgeD1mdW5jdGlvbihhKXt2YXIgYixjLGQsZSxmLGcsaCxpLGosayxsLG0sbixvLHAscSxyLHMsdCx1PSJzaXp6bGUiKzEqbmV3IERhdGUsdj1hLmRvY3VtZW50LHc9MCx4PTAseT1oYSgpLHo9aGEoKSxBPWhhKCksQj1mdW5jdGlvbihhLGIpe3JldHVybiBhPT09YiYmKGw9ITApLDB9LEM9e30uaGFzT3duUHJvcGVydHksRD1bXSxFPUQucG9wLEY9RC5wdXNoLEc9RC5wdXNoLEg9RC5zbGljZSxJPWZ1bmN0aW9uKGEsYil7Zm9yKHZhciBjPTAsZD1hLmxlbmd0aDtjPGQ7YysrKWlmKGFbY109PT1iKXJldHVybiBjO3JldHVybi0xfSxKPSJjaGVja2VkfHNlbGVjdGVkfGFzeW5jfGF1dG9mb2N1c3xhdXRvcGxheXxjb250cm9sc3xkZWZlcnxkaXNhYmxlZHxoaWRkZW58aXNtYXB8bG9vcHxtdWx0aXBsZXxvcGVufHJlYWRvbmx5fHJlcXVpcmVkfHNjb3BlZCIsSz0iW1xceDIwXFx0XFxyXFxuXFxmXSIsTD0iKD86XFxcXC58W1xcdy1dfFteXDAtXFx4YTBdKSsiLE09IlxcWyIrSysiKigiK0wrIikoPzoiK0srIiooWypeJHwhfl0/PSkiK0srIiooPzonKCg/OlxcXFwufFteXFxcXCddKSopJ3xcIigoPzpcXFxcLnxbXlxcXFxcIl0pKilcInwoIitMKyIpKXwpIitLKyIqXFxdIixOPSI6KCIrTCsiKSg/OlxcKCgoJygoPzpcXFxcLnxbXlxcXFwnXSkqKSd8XCIoKD86XFxcXC58W15cXFxcXCJdKSopXCIpfCgoPzpcXFxcLnxbXlxcXFwoKVtcXF1dfCIrTSsiKSopfC4qKVxcKXwpIixPPW5ldyBSZWdFeHAoSysiKyIsImciKSxQPW5ldyBSZWdFeHAoIl4iK0srIit8KCg/Ol58W15cXFxcXSkoPzpcXFxcLikqKSIrSysiKyQiLCJnIiksUT1uZXcgUmVnRXhwKCJeIitLKyIqLCIrSysiKiIpLFI9bmV3IFJlZ0V4cCgiXiIrSysiKihbPit+XXwiK0srIikiK0srIioiKSxTPW5ldyBSZWdFeHAoIj0iK0srIiooW15cXF0nXCJdKj8pIitLKyIqXFxdIiwiZyIpLFQ9bmV3IFJlZ0V4cChOKSxVPW5ldyBSZWdFeHAoIl4iK0wrIiQiKSxWPXtJRDpuZXcgUmVnRXhwKCJeIygiK0wrIikiKSxDTEFTUzpuZXcgUmVnRXhwKCJeXFwuKCIrTCsiKSIpLFRBRzpuZXcgUmVnRXhwKCJeKCIrTCsifFsqXSkiKSxBVFRSOm5ldyBSZWdFeHAoIl4iK00pLFBTRVVETzpuZXcgUmVnRXhwKCJeIitOKSxDSElMRDpuZXcgUmVnRXhwKCJeOihvbmx5fGZpcnN0fGxhc3R8bnRofG50aC1sYXN0KS0oY2hpbGR8b2YtdHlwZSkoPzpcXCgiK0srIiooZXZlbnxvZGR8KChbKy1dfCkoXFxkKilufCkiK0srIiooPzooWystXXwpIitLKyIqKFxcZCspfCkpIitLKyIqXFwpfCkiLCJpIiksYm9vbDpuZXcgUmVnRXhwKCJeKD86IitKKyIpJCIsImkiKSxuZWVkc0NvbnRleHQ6bmV3IFJlZ0V4cCgiXiIrSysiKls+K35dfDooZXZlbnxvZGR8ZXF8Z3R8bHR8bnRofGZpcnN0fGxhc3QpKD86XFwoIitLKyIqKCg/Oi1cXGQpP1xcZCopIitLKyIqXFwpfCkoPz1bXi1dfCQpIiwiaSIpfSxXPS9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbikkL2ksWD0vXmhcZCQvaSxZPS9eW157XStce1xzKlxbbmF0aXZlIFx3LyxaPS9eKD86IyhbXHctXSspfChcdyspfFwuKFtcdy1dKykpJC8sJD0vWyt+XS8sXz1uZXcgUmVnRXhwKCJcXFxcKFtcXGRhLWZdezEsNn0iK0srIj98KCIrSysiKXwuKSIsImlnIiksYWE9ZnVuY3Rpb24oYSxiLGMpe3ZhciBkPSIweCIrYi02NTUzNjtyZXR1cm4gZCE9PWR8fGM/YjpkPDA/U3RyaW5nLmZyb21DaGFyQ29kZShkKzY1NTM2KTpTdHJpbmcuZnJvbUNoYXJDb2RlKGQ+PjEwfDU1Mjk2LDEwMjMmZHw1NjMyMCl9LGJhPS8oW1wwLVx4MWZceDdmXXxeLT9cZCl8Xi0kfFteXHg4MC1cdUZGRkZcdy1dL2csY2E9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYj8iXDAiPT09YT8iXHVmZmZkIjphLnNsaWNlKDAsLTEpKyJcXCIrYS5jaGFyQ29kZUF0KGEubGVuZ3RoLTEpLnRvU3RyaW5nKDE2KSsiICI6IlxcIithfSxkYT1mdW5jdGlvbigpe20oKX0sZWE9dGEoZnVuY3Rpb24oYSl7cmV0dXJuIGEuZGlzYWJsZWQ9PT0hMH0se2RpcjoicGFyZW50Tm9kZSIsbmV4dDoibGVnZW5kIn0pO3RyeXtHLmFwcGx5KEQ9SC5jYWxsKHYuY2hpbGROb2Rlcyksdi5jaGlsZE5vZGVzKSxEW3YuY2hpbGROb2Rlcy5sZW5ndGhdLm5vZGVUeXBlfWNhdGNoKGZhKXtHPXthcHBseTpELmxlbmd0aD9mdW5jdGlvbihhLGIpe0YuYXBwbHkoYSxILmNhbGwoYikpfTpmdW5jdGlvbihhLGIpe3ZhciBjPWEubGVuZ3RoLGQ9MDt3aGlsZShhW2MrK109YltkKytdKTthLmxlbmd0aD1jLTF9fX1mdW5jdGlvbiBnYShhLGIsZCxlKXt2YXIgZixoLGosayxsLG8scixzPWImJmIub3duZXJEb2N1bWVudCx3PWI/Yi5ub2RlVHlwZTo5O2lmKGQ9ZHx8W10sInN0cmluZyIhPXR5cGVvZiBhfHwhYXx8MSE9PXcmJjkhPT13JiYxMSE9PXcpcmV0dXJuIGQ7aWYoIWUmJigoYj9iLm93bmVyRG9jdW1lbnR8fGI6dikhPT1uJiZtKGIpLGI9Ynx8bixwKSl7aWYoMTEhPT13JiYobD1aLmV4ZWMoYSkpKWlmKGY9bFsxXSl7aWYoOT09PXcpe2lmKCEoaj1iLmdldEVsZW1lbnRCeUlkKGYpKSlyZXR1cm4gZDtpZihqLmlkPT09ZilyZXR1cm4gZC5wdXNoKGopLGR9ZWxzZSBpZihzJiYoaj1zLmdldEVsZW1lbnRCeUlkKGYpKSYmdChiLGopJiZqLmlkPT09ZilyZXR1cm4gZC5wdXNoKGopLGR9ZWxzZXtpZihsWzJdKXJldHVybiBHLmFwcGx5KGQsYi5nZXRFbGVtZW50c0J5VGFnTmFtZShhKSksZDtpZigoZj1sWzNdKSYmYy5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lJiZiLmdldEVsZW1lbnRzQnlDbGFzc05hbWUpcmV0dXJuIEcuYXBwbHkoZCxiLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoZikpLGR9aWYoYy5xc2EmJiFBW2ErIiAiXSYmKCFxfHwhcS50ZXN0KGEpKSl7aWYoMSE9PXcpcz1iLHI9YTtlbHNlIGlmKCJvYmplY3QiIT09Yi5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKXsoaz1iLmdldEF0dHJpYnV0ZSgiaWQiKSk/az1rLnJlcGxhY2UoYmEsY2EpOmIuc2V0QXR0cmlidXRlKCJpZCIsaz11KSxvPWcoYSksaD1vLmxlbmd0aDt3aGlsZShoLS0pb1toXT0iIyIraysiICIrc2Eob1toXSk7cj1vLmpvaW4oIiwiKSxzPSQudGVzdChhKSYmcWEoYi5wYXJlbnROb2RlKXx8Yn1pZihyKXRyeXtyZXR1cm4gRy5hcHBseShkLHMucXVlcnlTZWxlY3RvckFsbChyKSksZH1jYXRjaCh4KXt9ZmluYWxseXtrPT09dSYmYi5yZW1vdmVBdHRyaWJ1dGUoImlkIil9fX1yZXR1cm4gaShhLnJlcGxhY2UoUCwiJDEiKSxiLGQsZSl9ZnVuY3Rpb24gaGEoKXt2YXIgYT1bXTtmdW5jdGlvbiBiKGMsZSl7cmV0dXJuIGEucHVzaChjKyIgIik+ZC5jYWNoZUxlbmd0aCYmZGVsZXRlIGJbYS5zaGlmdCgpXSxiW2MrIiAiXT1lfXJldHVybiBifWZ1bmN0aW9uIGlhKGEpe3JldHVybiBhW3VdPSEwLGF9ZnVuY3Rpb24gamEoYSl7dmFyIGI9bi5jcmVhdGVFbGVtZW50KCJmaWVsZHNldCIpO3RyeXtyZXR1cm4hIWEoYil9Y2F0Y2goYyl7cmV0dXJuITF9ZmluYWxseXtiLnBhcmVudE5vZGUmJmIucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChiKSxiPW51bGx9fWZ1bmN0aW9uIGthKGEsYil7dmFyIGM9YS5zcGxpdCgifCIpLGU9Yy5sZW5ndGg7d2hpbGUoZS0tKWQuYXR0ckhhbmRsZVtjW2VdXT1ifWZ1bmN0aW9uIGxhKGEsYil7dmFyIGM9YiYmYSxkPWMmJjE9PT1hLm5vZGVUeXBlJiYxPT09Yi5ub2RlVHlwZSYmYS5zb3VyY2VJbmRleC1iLnNvdXJjZUluZGV4O2lmKGQpcmV0dXJuIGQ7aWYoYyl3aGlsZShjPWMubmV4dFNpYmxpbmcpaWYoYz09PWIpcmV0dXJuLTE7cmV0dXJuIGE/MTotMX1mdW5jdGlvbiBtYShhKXtyZXR1cm4gZnVuY3Rpb24oYil7dmFyIGM9Yi5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO3JldHVybiJpbnB1dCI9PT1jJiZiLnR5cGU9PT1hfX1mdW5jdGlvbiBuYShhKXtyZXR1cm4gZnVuY3Rpb24oYil7dmFyIGM9Yi5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO3JldHVybigiaW5wdXQiPT09Y3x8ImJ1dHRvbiI9PT1jKSYmYi50eXBlPT09YX19ZnVuY3Rpb24gb2EoYSl7cmV0dXJuIGZ1bmN0aW9uKGIpe3JldHVybiJsYWJlbCJpbiBiJiZiLmRpc2FibGVkPT09YXx8ImZvcm0iaW4gYiYmYi5kaXNhYmxlZD09PWF8fCJmb3JtImluIGImJmIuZGlzYWJsZWQ9PT0hMSYmKGIuaXNEaXNhYmxlZD09PWF8fGIuaXNEaXNhYmxlZCE9PSFhJiYoImxhYmVsImluIGJ8fCFlYShiKSkhPT1hKX19ZnVuY3Rpb24gcGEoYSl7cmV0dXJuIGlhKGZ1bmN0aW9uKGIpe3JldHVybiBiPStiLGlhKGZ1bmN0aW9uKGMsZCl7dmFyIGUsZj1hKFtdLGMubGVuZ3RoLGIpLGc9Zi5sZW5ndGg7d2hpbGUoZy0tKWNbZT1mW2ddXSYmKGNbZV09IShkW2VdPWNbZV0pKX0pfSl9ZnVuY3Rpb24gcWEoYSl7cmV0dXJuIGEmJiJ1bmRlZmluZWQiIT10eXBlb2YgYS5nZXRFbGVtZW50c0J5VGFnTmFtZSYmYX1jPWdhLnN1cHBvcnQ9e30sZj1nYS5pc1hNTD1mdW5jdGlvbihhKXt2YXIgYj1hJiYoYS5vd25lckRvY3VtZW50fHxhKS5kb2N1bWVudEVsZW1lbnQ7cmV0dXJuISFiJiYiSFRNTCIhPT1iLm5vZGVOYW1lfSxtPWdhLnNldERvY3VtZW50PWZ1bmN0aW9uKGEpe3ZhciBiLGUsZz1hP2Eub3duZXJEb2N1bWVudHx8YTp2O3JldHVybiBnIT09biYmOT09PWcubm9kZVR5cGUmJmcuZG9jdW1lbnRFbGVtZW50PyhuPWcsbz1uLmRvY3VtZW50RWxlbWVudCxwPSFmKG4pLHYhPT1uJiYoZT1uLmRlZmF1bHRWaWV3KSYmZS50b3AhPT1lJiYoZS5hZGRFdmVudExpc3RlbmVyP2UuYWRkRXZlbnRMaXN0ZW5lcigidW5sb2FkIixkYSwhMSk6ZS5hdHRhY2hFdmVudCYmZS5hdHRhY2hFdmVudCgib251bmxvYWQiLGRhKSksYy5hdHRyaWJ1dGVzPWphKGZ1bmN0aW9uKGEpe3JldHVybiBhLmNsYXNzTmFtZT0iaSIsIWEuZ2V0QXR0cmlidXRlKCJjbGFzc05hbWUiKX0pLGMuZ2V0RWxlbWVudHNCeVRhZ05hbWU9amEoZnVuY3Rpb24oYSl7cmV0dXJuIGEuYXBwZW5kQ2hpbGQobi5jcmVhdGVDb21tZW50KCIiKSksIWEuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIioiKS5sZW5ndGh9KSxjLmdldEVsZW1lbnRzQnlDbGFzc05hbWU9WS50ZXN0KG4uZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSksYy5nZXRCeUlkPWphKGZ1bmN0aW9uKGEpe3JldHVybiBvLmFwcGVuZENoaWxkKGEpLmlkPXUsIW4uZ2V0RWxlbWVudHNCeU5hbWV8fCFuLmdldEVsZW1lbnRzQnlOYW1lKHUpLmxlbmd0aH0pLGMuZ2V0QnlJZD8oZC5maW5kLklEPWZ1bmN0aW9uKGEsYil7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiBiLmdldEVsZW1lbnRCeUlkJiZwKXt2YXIgYz1iLmdldEVsZW1lbnRCeUlkKGEpO3JldHVybiBjP1tjXTpbXX19LGQuZmlsdGVyLklEPWZ1bmN0aW9uKGEpe3ZhciBiPWEucmVwbGFjZShfLGFhKTtyZXR1cm4gZnVuY3Rpb24oYSl7cmV0dXJuIGEuZ2V0QXR0cmlidXRlKCJpZCIpPT09Yn19KTooZGVsZXRlIGQuZmluZC5JRCxkLmZpbHRlci5JRD1mdW5jdGlvbihhKXt2YXIgYj1hLnJlcGxhY2UoXyxhYSk7cmV0dXJuIGZ1bmN0aW9uKGEpe3ZhciBjPSJ1bmRlZmluZWQiIT10eXBlb2YgYS5nZXRBdHRyaWJ1dGVOb2RlJiZhLmdldEF0dHJpYnV0ZU5vZGUoImlkIik7cmV0dXJuIGMmJmMudmFsdWU9PT1ifX0pLGQuZmluZC5UQUc9Yy5nZXRFbGVtZW50c0J5VGFnTmFtZT9mdW5jdGlvbihhLGIpe3JldHVybiJ1bmRlZmluZWQiIT10eXBlb2YgYi5nZXRFbGVtZW50c0J5VGFnTmFtZT9iLmdldEVsZW1lbnRzQnlUYWdOYW1lKGEpOmMucXNhP2IucXVlcnlTZWxlY3RvckFsbChhKTp2b2lkIDB9OmZ1bmN0aW9uKGEsYil7dmFyIGMsZD1bXSxlPTAsZj1iLmdldEVsZW1lbnRzQnlUYWdOYW1lKGEpO2lmKCIqIj09PWEpe3doaWxlKGM9ZltlKytdKTE9PT1jLm5vZGVUeXBlJiZkLnB1c2goYyk7cmV0dXJuIGR9cmV0dXJuIGZ9LGQuZmluZC5DTEFTUz1jLmdldEVsZW1lbnRzQnlDbGFzc05hbWUmJmZ1bmN0aW9uKGEsYil7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiBiLmdldEVsZW1lbnRzQnlDbGFzc05hbWUmJnApcmV0dXJuIGIuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShhKX0scj1bXSxxPVtdLChjLnFzYT1ZLnRlc3Qobi5xdWVyeVNlbGVjdG9yQWxsKSkmJihqYShmdW5jdGlvbihhKXtvLmFwcGVuZENoaWxkKGEpLmlubmVySFRNTD0iPGEgaWQ9JyIrdSsiJz48L2E+PHNlbGVjdCBpZD0nIit1KyItXHJcXCcgbXNhbGxvd2NhcHR1cmU9Jyc+PG9wdGlvbiBzZWxlY3RlZD0nJz48L29wdGlvbj48L3NlbGVjdD4iLGEucXVlcnlTZWxlY3RvckFsbCgiW21zYWxsb3djYXB0dXJlXj0nJ10iKS5sZW5ndGgmJnEucHVzaCgiWypeJF09IitLKyIqKD86Jyd8XCJcIikiKSxhLnF1ZXJ5U2VsZWN0b3JBbGwoIltzZWxlY3RlZF0iKS5sZW5ndGh8fHEucHVzaCgiXFxbIitLKyIqKD86dmFsdWV8IitKKyIpIiksYS5xdWVyeVNlbGVjdG9yQWxsKCJbaWR+PSIrdSsiLV0iKS5sZW5ndGh8fHEucHVzaCgifj0iKSxhLnF1ZXJ5U2VsZWN0b3JBbGwoIjpjaGVja2VkIikubGVuZ3RofHxxLnB1c2goIjpjaGVja2VkIiksYS5xdWVyeVNlbGVjdG9yQWxsKCJhIyIrdSsiKyoiKS5sZW5ndGh8fHEucHVzaCgiLiMuK1srfl0iKX0pLGphKGZ1bmN0aW9uKGEpe2EuaW5uZXJIVE1MPSI8YSBocmVmPScnIGRpc2FibGVkPSdkaXNhYmxlZCc+PC9hPjxzZWxlY3QgZGlzYWJsZWQ9J2Rpc2FibGVkJz48b3B0aW9uLz48L3NlbGVjdD4iO3ZhciBiPW4uY3JlYXRlRWxlbWVudCgiaW5wdXQiKTtiLnNldEF0dHJpYnV0ZSgidHlwZSIsImhpZGRlbiIpLGEuYXBwZW5kQ2hpbGQoYikuc2V0QXR0cmlidXRlKCJuYW1lIiwiRCIpLGEucXVlcnlTZWxlY3RvckFsbCgiW25hbWU9ZF0iKS5sZW5ndGgmJnEucHVzaCgibmFtZSIrSysiKlsqXiR8IX5dPz0iKSwyIT09YS5xdWVyeVNlbGVjdG9yQWxsKCI6ZW5hYmxlZCIpLmxlbmd0aCYmcS5wdXNoKCI6ZW5hYmxlZCIsIjpkaXNhYmxlZCIpLG8uYXBwZW5kQ2hpbGQoYSkuZGlzYWJsZWQ9ITAsMiE9PWEucXVlcnlTZWxlY3RvckFsbCgiOmRpc2FibGVkIikubGVuZ3RoJiZxLnB1c2goIjplbmFibGVkIiwiOmRpc2FibGVkIiksYS5xdWVyeVNlbGVjdG9yQWxsKCIqLDp4IikscS5wdXNoKCIsLio6Iil9KSksKGMubWF0Y2hlc1NlbGVjdG9yPVkudGVzdChzPW8ubWF0Y2hlc3x8by53ZWJraXRNYXRjaGVzU2VsZWN0b3J8fG8ubW96TWF0Y2hlc1NlbGVjdG9yfHxvLm9NYXRjaGVzU2VsZWN0b3J8fG8ubXNNYXRjaGVzU2VsZWN0b3IpKSYmamEoZnVuY3Rpb24oYSl7Yy5kaXNjb25uZWN0ZWRNYXRjaD1zLmNhbGwoYSwiKiIpLHMuY2FsbChhLCJbcyE9JyddOngiKSxyLnB1c2goIiE9IixOKX0pLHE9cS5sZW5ndGgmJm5ldyBSZWdFeHAocS5qb2luKCJ8IikpLHI9ci5sZW5ndGgmJm5ldyBSZWdFeHAoci5qb2luKCJ8IikpLGI9WS50ZXN0KG8uY29tcGFyZURvY3VtZW50UG9zaXRpb24pLHQ9Ynx8WS50ZXN0KG8uY29udGFpbnMpP2Z1bmN0aW9uKGEsYil7dmFyIGM9OT09PWEubm9kZVR5cGU/YS5kb2N1bWVudEVsZW1lbnQ6YSxkPWImJmIucGFyZW50Tm9kZTtyZXR1cm4gYT09PWR8fCEoIWR8fDEhPT1kLm5vZGVUeXBlfHwhKGMuY29udGFpbnM/Yy5jb250YWlucyhkKTphLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uJiYxNiZhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGQpKSl9OmZ1bmN0aW9uKGEsYil7aWYoYil3aGlsZShiPWIucGFyZW50Tm9kZSlpZihiPT09YSlyZXR1cm4hMDtyZXR1cm4hMX0sQj1iP2Z1bmN0aW9uKGEsYil7aWYoYT09PWIpcmV0dXJuIGw9ITAsMDt2YXIgZD0hYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbi0hYi5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbjtyZXR1cm4gZD9kOihkPShhLm93bmVyRG9jdW1lbnR8fGEpPT09KGIub3duZXJEb2N1bWVudHx8Yik/YS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihiKToxLDEmZHx8IWMuc29ydERldGFjaGVkJiZiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGEpPT09ZD9hPT09bnx8YS5vd25lckRvY3VtZW50PT09diYmdCh2LGEpPy0xOmI9PT1ufHxiLm93bmVyRG9jdW1lbnQ9PT12JiZ0KHYsYik/MTprP0koayxhKS1JKGssYik6MDo0JmQ/LTE6MSl9OmZ1bmN0aW9uKGEsYil7aWYoYT09PWIpcmV0dXJuIGw9ITAsMDt2YXIgYyxkPTAsZT1hLnBhcmVudE5vZGUsZj1iLnBhcmVudE5vZGUsZz1bYV0saD1bYl07aWYoIWV8fCFmKXJldHVybiBhPT09bj8tMTpiPT09bj8xOmU/LTE6Zj8xOms/SShrLGEpLUkoayxiKTowO2lmKGU9PT1mKXJldHVybiBsYShhLGIpO2M9YTt3aGlsZShjPWMucGFyZW50Tm9kZSlnLnVuc2hpZnQoYyk7Yz1iO3doaWxlKGM9Yy5wYXJlbnROb2RlKWgudW5zaGlmdChjKTt3aGlsZShnW2RdPT09aFtkXSlkKys7cmV0dXJuIGQ/bGEoZ1tkXSxoW2RdKTpnW2RdPT09dj8tMTpoW2RdPT09dj8xOjB9LG4pOm59LGdhLm1hdGNoZXM9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gZ2EoYSxudWxsLG51bGwsYil9LGdhLm1hdGNoZXNTZWxlY3Rvcj1mdW5jdGlvbihhLGIpe2lmKChhLm93bmVyRG9jdW1lbnR8fGEpIT09biYmbShhKSxiPWIucmVwbGFjZShTLCI9JyQxJ10iKSxjLm1hdGNoZXNTZWxlY3RvciYmcCYmIUFbYisiICJdJiYoIXJ8fCFyLnRlc3QoYikpJiYoIXF8fCFxLnRlc3QoYikpKXRyeXt2YXIgZD1zLmNhbGwoYSxiKTtpZihkfHxjLmRpc2Nvbm5lY3RlZE1hdGNofHxhLmRvY3VtZW50JiYxMSE9PWEuZG9jdW1lbnQubm9kZVR5cGUpcmV0dXJuIGR9Y2F0Y2goZSl7fXJldHVybiBnYShiLG4sbnVsbCxbYV0pLmxlbmd0aD4wfSxnYS5jb250YWlucz1mdW5jdGlvbihhLGIpe3JldHVybihhLm93bmVyRG9jdW1lbnR8fGEpIT09biYmbShhKSx0KGEsYil9LGdhLmF0dHI9ZnVuY3Rpb24oYSxiKXsoYS5vd25lckRvY3VtZW50fHxhKSE9PW4mJm0oYSk7dmFyIGU9ZC5hdHRySGFuZGxlW2IudG9Mb3dlckNhc2UoKV0sZj1lJiZDLmNhbGwoZC5hdHRySGFuZGxlLGIudG9Mb3dlckNhc2UoKSk/ZShhLGIsIXApOnZvaWQgMDtyZXR1cm4gdm9pZCAwIT09Zj9mOmMuYXR0cmlidXRlc3x8IXA/YS5nZXRBdHRyaWJ1dGUoYik6KGY9YS5nZXRBdHRyaWJ1dGVOb2RlKGIpKSYmZi5zcGVjaWZpZWQ/Zi52YWx1ZTpudWxsfSxnYS5lc2NhcGU9ZnVuY3Rpb24oYSl7cmV0dXJuKGErIiIpLnJlcGxhY2UoYmEsY2EpfSxnYS5lcnJvcj1mdW5jdGlvbihhKXt0aHJvdyBuZXcgRXJyb3IoIlN5bnRheCBlcnJvciwgdW5yZWNvZ25pemVkIGV4cHJlc3Npb246ICIrYSl9LGdhLnVuaXF1ZVNvcnQ9ZnVuY3Rpb24oYSl7dmFyIGIsZD1bXSxlPTAsZj0wO2lmKGw9IWMuZGV0ZWN0RHVwbGljYXRlcyxrPSFjLnNvcnRTdGFibGUmJmEuc2xpY2UoMCksYS5zb3J0KEIpLGwpe3doaWxlKGI9YVtmKytdKWI9PT1hW2ZdJiYoZT1kLnB1c2goZikpO3doaWxlKGUtLSlhLnNwbGljZShkW2VdLDEpfXJldHVybiBrPW51bGwsYX0sZT1nYS5nZXRUZXh0PWZ1bmN0aW9uKGEpe3ZhciBiLGM9IiIsZD0wLGY9YS5ub2RlVHlwZTtpZihmKXtpZigxPT09Znx8OT09PWZ8fDExPT09Zil7aWYoInN0cmluZyI9PXR5cGVvZiBhLnRleHRDb250ZW50KXJldHVybiBhLnRleHRDb250ZW50O2ZvcihhPWEuZmlyc3RDaGlsZDthO2E9YS5uZXh0U2libGluZyljKz1lKGEpfWVsc2UgaWYoMz09PWZ8fDQ9PT1mKXJldHVybiBhLm5vZGVWYWx1ZX1lbHNlIHdoaWxlKGI9YVtkKytdKWMrPWUoYik7cmV0dXJuIGN9LGQ9Z2Euc2VsZWN0b3JzPXtjYWNoZUxlbmd0aDo1MCxjcmVhdGVQc2V1ZG86aWEsbWF0Y2g6VixhdHRySGFuZGxlOnt9LGZpbmQ6e30scmVsYXRpdmU6eyI+Ijp7ZGlyOiJwYXJlbnROb2RlIixmaXJzdDohMH0sIiAiOntkaXI6InBhcmVudE5vZGUifSwiKyI6e2RpcjoicHJldmlvdXNTaWJsaW5nIixmaXJzdDohMH0sIn4iOntkaXI6InByZXZpb3VzU2libGluZyJ9fSxwcmVGaWx0ZXI6e0FUVFI6ZnVuY3Rpb24oYSl7cmV0dXJuIGFbMV09YVsxXS5yZXBsYWNlKF8sYWEpLGFbM109KGFbM118fGFbNF18fGFbNV18fCIiKS5yZXBsYWNlKF8sYWEpLCJ+PSI9PT1hWzJdJiYoYVszXT0iICIrYVszXSsiICIpLGEuc2xpY2UoMCw0KX0sQ0hJTEQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGFbMV09YVsxXS50b0xvd2VyQ2FzZSgpLCJudGgiPT09YVsxXS5zbGljZSgwLDMpPyhhWzNdfHxnYS5lcnJvcihhWzBdKSxhWzRdPSsoYVs0XT9hWzVdKyhhWzZdfHwxKToyKigiZXZlbiI9PT1hWzNdfHwib2RkIj09PWFbM10pKSxhWzVdPSsoYVs3XSthWzhdfHwib2RkIj09PWFbM10pKTphWzNdJiZnYS5lcnJvcihhWzBdKSxhfSxQU0VVRE86ZnVuY3Rpb24oYSl7dmFyIGIsYz0hYVs2XSYmYVsyXTtyZXR1cm4gVi5DSElMRC50ZXN0KGFbMF0pP251bGw6KGFbM10/YVsyXT1hWzRdfHxhWzVdfHwiIjpjJiZULnRlc3QoYykmJihiPWcoYywhMCkpJiYoYj1jLmluZGV4T2YoIikiLGMubGVuZ3RoLWIpLWMubGVuZ3RoKSYmKGFbMF09YVswXS5zbGljZSgwLGIpLGFbMl09Yy5zbGljZSgwLGIpKSxhLnNsaWNlKDAsMykpfX0sZmlsdGVyOntUQUc6ZnVuY3Rpb24oYSl7dmFyIGI9YS5yZXBsYWNlKF8sYWEpLnRvTG93ZXJDYXNlKCk7cmV0dXJuIioiPT09YT9mdW5jdGlvbigpe3JldHVybiEwfTpmdW5jdGlvbihhKXtyZXR1cm4gYS5ub2RlTmFtZSYmYS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpPT09Yn19LENMQVNTOmZ1bmN0aW9uKGEpe3ZhciBiPXlbYSsiICJdO3JldHVybiBifHwoYj1uZXcgUmVnRXhwKCIoXnwiK0srIikiK2ErIigiK0srInwkKSIpKSYmeShhLGZ1bmN0aW9uKGEpe3JldHVybiBiLnRlc3QoInN0cmluZyI9PXR5cGVvZiBhLmNsYXNzTmFtZSYmYS5jbGFzc05hbWV8fCJ1bmRlZmluZWQiIT10eXBlb2YgYS5nZXRBdHRyaWJ1dGUmJmEuZ2V0QXR0cmlidXRlKCJjbGFzcyIpfHwiIil9KX0sQVRUUjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGZ1bmN0aW9uKGQpe3ZhciBlPWdhLmF0dHIoZCxhKTtyZXR1cm4gbnVsbD09ZT8iIT0iPT09YjohYnx8KGUrPSIiLCI9Ij09PWI/ZT09PWM6IiE9Ij09PWI/ZSE9PWM6Il49Ij09PWI/YyYmMD09PWUuaW5kZXhPZihjKToiKj0iPT09Yj9jJiZlLmluZGV4T2YoYyk+LTE6IiQ9Ij09PWI/YyYmZS5zbGljZSgtYy5sZW5ndGgpPT09Yzoifj0iPT09Yj8oIiAiK2UucmVwbGFjZShPLCIgIikrIiAiKS5pbmRleE9mKGMpPi0xOiJ8PSI9PT1iJiYoZT09PWN8fGUuc2xpY2UoMCxjLmxlbmd0aCsxKT09PWMrIi0iKSl9fSxDSElMRDpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBmPSJudGgiIT09YS5zbGljZSgwLDMpLGc9Imxhc3QiIT09YS5zbGljZSgtNCksaD0ib2YtdHlwZSI9PT1iO3JldHVybiAxPT09ZCYmMD09PWU/ZnVuY3Rpb24oYSl7cmV0dXJuISFhLnBhcmVudE5vZGV9OmZ1bmN0aW9uKGIsYyxpKXt2YXIgaixrLGwsbSxuLG8scD1mIT09Zz8ibmV4dFNpYmxpbmciOiJwcmV2aW91c1NpYmxpbmciLHE9Yi5wYXJlbnROb2RlLHI9aCYmYi5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLHM9IWkmJiFoLHQ9ITE7aWYocSl7aWYoZil7d2hpbGUocCl7bT1iO3doaWxlKG09bVtwXSlpZihoP20ubm9kZU5hbWUudG9Mb3dlckNhc2UoKT09PXI6MT09PW0ubm9kZVR5cGUpcmV0dXJuITE7bz1wPSJvbmx5Ij09PWEmJiFvJiYibmV4dFNpYmxpbmcifXJldHVybiEwfWlmKG89W2c/cS5maXJzdENoaWxkOnEubGFzdENoaWxkXSxnJiZzKXttPXEsbD1tW3VdfHwobVt1XT17fSksaz1sW20udW5pcXVlSURdfHwobFttLnVuaXF1ZUlEXT17fSksaj1rW2FdfHxbXSxuPWpbMF09PT13JiZqWzFdLHQ9biYmalsyXSxtPW4mJnEuY2hpbGROb2Rlc1tuXTt3aGlsZShtPSsrbiYmbSYmbVtwXXx8KHQ9bj0wKXx8by5wb3AoKSlpZigxPT09bS5ub2RlVHlwZSYmKyt0JiZtPT09Yil7a1thXT1bdyxuLHRdO2JyZWFrfX1lbHNlIGlmKHMmJihtPWIsbD1tW3VdfHwobVt1XT17fSksaz1sW20udW5pcXVlSURdfHwobFttLnVuaXF1ZUlEXT17fSksaj1rW2FdfHxbXSxuPWpbMF09PT13JiZqWzFdLHQ9biksdD09PSExKXdoaWxlKG09KytuJiZtJiZtW3BdfHwodD1uPTApfHxvLnBvcCgpKWlmKChoP20ubm9kZU5hbWUudG9Mb3dlckNhc2UoKT09PXI6MT09PW0ubm9kZVR5cGUpJiYrK3QmJihzJiYobD1tW3VdfHwobVt1XT17fSksaz1sW20udW5pcXVlSURdfHwobFttLnVuaXF1ZUlEXT17fSksa1thXT1bdyx0XSksbT09PWIpKWJyZWFrO3JldHVybiB0LT1lLHQ9PT1kfHx0JWQ9PT0wJiZ0L2Q+PTB9fX0sUFNFVURPOmZ1bmN0aW9uKGEsYil7dmFyIGMsZT1kLnBzZXVkb3NbYV18fGQuc2V0RmlsdGVyc1thLnRvTG93ZXJDYXNlKCldfHxnYS5lcnJvcigidW5zdXBwb3J0ZWQgcHNldWRvOiAiK2EpO3JldHVybiBlW3VdP2UoYik6ZS5sZW5ndGg+MT8oYz1bYSxhLCIiLGJdLGQuc2V0RmlsdGVycy5oYXNPd25Qcm9wZXJ0eShhLnRvTG93ZXJDYXNlKCkpP2lhKGZ1bmN0aW9uKGEsYyl7dmFyIGQsZj1lKGEsYiksZz1mLmxlbmd0aDt3aGlsZShnLS0pZD1JKGEsZltnXSksYVtkXT0hKGNbZF09ZltnXSl9KTpmdW5jdGlvbihhKXtyZXR1cm4gZShhLDAsYyl9KTplfX0scHNldWRvczp7bm90OmlhKGZ1bmN0aW9uKGEpe3ZhciBiPVtdLGM9W10sZD1oKGEucmVwbGFjZShQLCIkMSIpKTtyZXR1cm4gZFt1XT9pYShmdW5jdGlvbihhLGIsYyxlKXt2YXIgZixnPWQoYSxudWxsLGUsW10pLGg9YS5sZW5ndGg7d2hpbGUoaC0tKShmPWdbaF0pJiYoYVtoXT0hKGJbaF09ZikpfSk6ZnVuY3Rpb24oYSxlLGYpe3JldHVybiBiWzBdPWEsZChiLG51bGwsZixjKSxiWzBdPW51bGwsIWMucG9wKCl9fSksaGFzOmlhKGZ1bmN0aW9uKGEpe3JldHVybiBmdW5jdGlvbihiKXtyZXR1cm4gZ2EoYSxiKS5sZW5ndGg+MH19KSxjb250YWluczppYShmdW5jdGlvbihhKXtyZXR1cm4gYT1hLnJlcGxhY2UoXyxhYSksZnVuY3Rpb24oYil7cmV0dXJuKGIudGV4dENvbnRlbnR8fGIuaW5uZXJUZXh0fHxlKGIpKS5pbmRleE9mKGEpPi0xfX0pLGxhbmc6aWEoZnVuY3Rpb24oYSl7cmV0dXJuIFUudGVzdChhfHwiIil8fGdhLmVycm9yKCJ1bnN1cHBvcnRlZCBsYW5nOiAiK2EpLGE9YS5yZXBsYWNlKF8sYWEpLnRvTG93ZXJDYXNlKCksZnVuY3Rpb24oYil7dmFyIGM7ZG8gaWYoYz1wP2IubGFuZzpiLmdldEF0dHJpYnV0ZSgieG1sOmxhbmciKXx8Yi5nZXRBdHRyaWJ1dGUoImxhbmciKSlyZXR1cm4gYz1jLnRvTG93ZXJDYXNlKCksYz09PWF8fDA9PT1jLmluZGV4T2YoYSsiLSIpO3doaWxlKChiPWIucGFyZW50Tm9kZSkmJjE9PT1iLm5vZGVUeXBlKTtyZXR1cm4hMX19KSx0YXJnZXQ6ZnVuY3Rpb24oYil7dmFyIGM9YS5sb2NhdGlvbiYmYS5sb2NhdGlvbi5oYXNoO3JldHVybiBjJiZjLnNsaWNlKDEpPT09Yi5pZH0scm9vdDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PW99LGZvY3VzOmZ1bmN0aW9uKGEpe3JldHVybiBhPT09bi5hY3RpdmVFbGVtZW50JiYoIW4uaGFzRm9jdXN8fG4uaGFzRm9jdXMoKSkmJiEhKGEudHlwZXx8YS5ocmVmfHx+YS50YWJJbmRleCl9LGVuYWJsZWQ6b2EoITEpLGRpc2FibGVkOm9hKCEwKSxjaGVja2VkOmZ1bmN0aW9uKGEpe3ZhciBiPWEubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtyZXR1cm4iaW5wdXQiPT09YiYmISFhLmNoZWNrZWR8fCJvcHRpb24iPT09YiYmISFhLnNlbGVjdGVkfSxzZWxlY3RlZDpmdW5jdGlvbihhKXtyZXR1cm4gYS5wYXJlbnROb2RlJiZhLnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleCxhLnNlbGVjdGVkPT09ITB9LGVtcHR5OmZ1bmN0aW9uKGEpe2ZvcihhPWEuZmlyc3RDaGlsZDthO2E9YS5uZXh0U2libGluZylpZihhLm5vZGVUeXBlPDYpcmV0dXJuITE7cmV0dXJuITB9LHBhcmVudDpmdW5jdGlvbihhKXtyZXR1cm4hZC5wc2V1ZG9zLmVtcHR5KGEpfSxoZWFkZXI6ZnVuY3Rpb24oYSl7cmV0dXJuIFgudGVzdChhLm5vZGVOYW1lKX0saW5wdXQ6ZnVuY3Rpb24oYSl7cmV0dXJuIFcudGVzdChhLm5vZGVOYW1lKX0sYnV0dG9uOmZ1bmN0aW9uKGEpe3ZhciBiPWEubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtyZXR1cm4iaW5wdXQiPT09YiYmImJ1dHRvbiI9PT1hLnR5cGV8fCJidXR0b24iPT09Yn0sdGV4dDpmdW5jdGlvbihhKXt2YXIgYjtyZXR1cm4iaW5wdXQiPT09YS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpJiYidGV4dCI9PT1hLnR5cGUmJihudWxsPT0oYj1hLmdldEF0dHJpYnV0ZSgidHlwZSIpKXx8InRleHQiPT09Yi50b0xvd2VyQ2FzZSgpKX0sZmlyc3Q6cGEoZnVuY3Rpb24oKXtyZXR1cm5bMF19KSxsYXN0OnBhKGZ1bmN0aW9uKGEsYil7cmV0dXJuW2ItMV19KSxlcTpwYShmdW5jdGlvbihhLGIsYyl7cmV0dXJuW2M8MD9jK2I6Y119KSxldmVuOnBhKGZ1bmN0aW9uKGEsYil7Zm9yKHZhciBjPTA7YzxiO2MrPTIpYS5wdXNoKGMpO3JldHVybiBhfSksb2RkOnBhKGZ1bmN0aW9uKGEsYil7Zm9yKHZhciBjPTE7YzxiO2MrPTIpYS5wdXNoKGMpO3JldHVybiBhfSksbHQ6cGEoZnVuY3Rpb24oYSxiLGMpe2Zvcih2YXIgZD1jPDA/YytiOmM7LS1kPj0wOylhLnB1c2goZCk7cmV0dXJuIGF9KSxndDpwYShmdW5jdGlvbihhLGIsYyl7Zm9yKHZhciBkPWM8MD9jK2I6YzsrK2Q8YjspYS5wdXNoKGQpO3JldHVybiBhfSl9fSxkLnBzZXVkb3MubnRoPWQucHNldWRvcy5lcTtmb3IoYiBpbntyYWRpbzohMCxjaGVja2JveDohMCxmaWxlOiEwLHBhc3N3b3JkOiEwLGltYWdlOiEwfSlkLnBzZXVkb3NbYl09bWEoYik7Zm9yKGIgaW57c3VibWl0OiEwLHJlc2V0OiEwfSlkLnBzZXVkb3NbYl09bmEoYik7ZnVuY3Rpb24gcmEoKXt9cmEucHJvdG90eXBlPWQuZmlsdGVycz1kLnBzZXVkb3MsZC5zZXRGaWx0ZXJzPW5ldyByYSxnPWdhLnRva2VuaXplPWZ1bmN0aW9uKGEsYil7dmFyIGMsZSxmLGcsaCxpLGosaz16W2ErIiAiXTtpZihrKXJldHVybiBiPzA6ay5zbGljZSgwKTtoPWEsaT1bXSxqPWQucHJlRmlsdGVyO3doaWxlKGgpe2MmJiEoZT1RLmV4ZWMoaCkpfHwoZSYmKGg9aC5zbGljZShlWzBdLmxlbmd0aCl8fGgpLGkucHVzaChmPVtdKSksYz0hMSwoZT1SLmV4ZWMoaCkpJiYoYz1lLnNoaWZ0KCksZi5wdXNoKHt2YWx1ZTpjLHR5cGU6ZVswXS5yZXBsYWNlKFAsIiAiKX0pLGg9aC5zbGljZShjLmxlbmd0aCkpO2ZvcihnIGluIGQuZmlsdGVyKSEoZT1WW2ddLmV4ZWMoaCkpfHxqW2ddJiYhKGU9altnXShlKSl8fChjPWUuc2hpZnQoKSxmLnB1c2goe3ZhbHVlOmMsdHlwZTpnLG1hdGNoZXM6ZX0pLGg9aC5zbGljZShjLmxlbmd0aCkpO2lmKCFjKWJyZWFrfXJldHVybiBiP2gubGVuZ3RoOmg/Z2EuZXJyb3IoYSk6eihhLGkpLnNsaWNlKDApfTtmdW5jdGlvbiBzYShhKXtmb3IodmFyIGI9MCxjPWEubGVuZ3RoLGQ9IiI7YjxjO2IrKylkKz1hW2JdLnZhbHVlO3JldHVybiBkfWZ1bmN0aW9uIHRhKGEsYixjKXt2YXIgZD1iLmRpcixlPWIubmV4dCxmPWV8fGQsZz1jJiYicGFyZW50Tm9kZSI9PT1mLGg9eCsrO3JldHVybiBiLmZpcnN0P2Z1bmN0aW9uKGIsYyxlKXt3aGlsZShiPWJbZF0paWYoMT09PWIubm9kZVR5cGV8fGcpcmV0dXJuIGEoYixjLGUpfTpmdW5jdGlvbihiLGMsaSl7dmFyIGosayxsLG09W3csaF07aWYoaSl7d2hpbGUoYj1iW2RdKWlmKCgxPT09Yi5ub2RlVHlwZXx8ZykmJmEoYixjLGkpKXJldHVybiEwfWVsc2Ugd2hpbGUoYj1iW2RdKWlmKDE9PT1iLm5vZGVUeXBlfHxnKWlmKGw9Ylt1XXx8KGJbdV09e30pLGs9bFtiLnVuaXF1ZUlEXXx8KGxbYi51bmlxdWVJRF09e30pLGUmJmU9PT1iLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpYj1iW2RdfHxiO2Vsc2V7aWYoKGo9a1tmXSkmJmpbMF09PT13JiZqWzFdPT09aClyZXR1cm4gbVsyXT1qWzJdO2lmKGtbZl09bSxtWzJdPWEoYixjLGkpKXJldHVybiEwfX19ZnVuY3Rpb24gdWEoYSl7cmV0dXJuIGEubGVuZ3RoPjE/ZnVuY3Rpb24oYixjLGQpe3ZhciBlPWEubGVuZ3RoO3doaWxlKGUtLSlpZighYVtlXShiLGMsZCkpcmV0dXJuITE7cmV0dXJuITB9OmFbMF19ZnVuY3Rpb24gdmEoYSxiLGMpe2Zvcih2YXIgZD0wLGU9Yi5sZW5ndGg7ZDxlO2QrKylnYShhLGJbZF0sYyk7cmV0dXJuIGN9ZnVuY3Rpb24gd2EoYSxiLGMsZCxlKXtmb3IodmFyIGYsZz1bXSxoPTAsaT1hLmxlbmd0aCxqPW51bGwhPWI7aDxpO2grKykoZj1hW2hdKSYmKGMmJiFjKGYsZCxlKXx8KGcucHVzaChmKSxqJiZiLnB1c2goaCkpKTtyZXR1cm4gZ31mdW5jdGlvbiB4YShhLGIsYyxkLGUsZil7cmV0dXJuIGQmJiFkW3VdJiYoZD14YShkKSksZSYmIWVbdV0mJihlPXhhKGUsZikpLGlhKGZ1bmN0aW9uKGYsZyxoLGkpe3ZhciBqLGssbCxtPVtdLG49W10sbz1nLmxlbmd0aCxwPWZ8fHZhKGJ8fCIqIixoLm5vZGVUeXBlP1toXTpoLFtdKSxxPSFhfHwhZiYmYj9wOndhKHAsbSxhLGgsaSkscj1jP2V8fChmP2E6b3x8ZCk/W106ZzpxO2lmKGMmJmMocSxyLGgsaSksZCl7aj13YShyLG4pLGQoaixbXSxoLGkpLGs9ai5sZW5ndGg7d2hpbGUoay0tKShsPWpba10pJiYocltuW2tdXT0hKHFbbltrXV09bCkpfWlmKGYpe2lmKGV8fGEpe2lmKGUpe2o9W10saz1yLmxlbmd0aDt3aGlsZShrLS0pKGw9cltrXSkmJmoucHVzaChxW2tdPWwpO2UobnVsbCxyPVtdLGosaSl9az1yLmxlbmd0aDt3aGlsZShrLS0pKGw9cltrXSkmJihqPWU/SShmLGwpOm1ba10pPi0xJiYoZltqXT0hKGdbal09bCkpfX1lbHNlIHI9d2Eocj09PWc/ci5zcGxpY2UobyxyLmxlbmd0aCk6ciksZT9lKG51bGwsZyxyLGkpOkcuYXBwbHkoZyxyKX0pfWZ1bmN0aW9uIHlhKGEpe2Zvcih2YXIgYixjLGUsZj1hLmxlbmd0aCxnPWQucmVsYXRpdmVbYVswXS50eXBlXSxoPWd8fGQucmVsYXRpdmVbIiAiXSxpPWc/MTowLGs9dGEoZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT1ifSxoLCEwKSxsPXRhKGZ1bmN0aW9uKGEpe3JldHVybiBJKGIsYSk+LTF9LGgsITApLG09W2Z1bmN0aW9uKGEsYyxkKXt2YXIgZT0hZyYmKGR8fGMhPT1qKXx8KChiPWMpLm5vZGVUeXBlP2soYSxjLGQpOmwoYSxjLGQpKTtyZXR1cm4gYj1udWxsLGV9XTtpPGY7aSsrKWlmKGM9ZC5yZWxhdGl2ZVthW2ldLnR5cGVdKW09W3RhKHVhKG0pLGMpXTtlbHNle2lmKGM9ZC5maWx0ZXJbYVtpXS50eXBlXS5hcHBseShudWxsLGFbaV0ubWF0Y2hlcyksY1t1XSl7Zm9yKGU9KytpO2U8ZjtlKyspaWYoZC5yZWxhdGl2ZVthW2VdLnR5cGVdKWJyZWFrO3JldHVybiB4YShpPjEmJnVhKG0pLGk+MSYmc2EoYS5zbGljZSgwLGktMSkuY29uY2F0KHt2YWx1ZToiICI9PT1hW2ktMl0udHlwZT8iKiI6IiJ9KSkucmVwbGFjZShQLCIkMSIpLGMsaTxlJiZ5YShhLnNsaWNlKGksZSkpLGU8ZiYmeWEoYT1hLnNsaWNlKGUpKSxlPGYmJnNhKGEpKX1tLnB1c2goYyl9cmV0dXJuIHVhKG0pfWZ1bmN0aW9uIHphKGEsYil7dmFyIGM9Yi5sZW5ndGg+MCxlPWEubGVuZ3RoPjAsZj1mdW5jdGlvbihmLGcsaCxpLGspe3ZhciBsLG8scSxyPTAscz0iMCIsdD1mJiZbXSx1PVtdLHY9aix4PWZ8fGUmJmQuZmluZC5UQUcoIioiLGspLHk9dys9bnVsbD09dj8xOk1hdGgucmFuZG9tKCl8fC4xLHo9eC5sZW5ndGg7Zm9yKGsmJihqPWc9PT1ufHxnfHxrKTtzIT09eiYmbnVsbCE9KGw9eFtzXSk7cysrKXtpZihlJiZsKXtvPTAsZ3x8bC5vd25lckRvY3VtZW50PT09bnx8KG0obCksaD0hcCk7d2hpbGUocT1hW28rK10paWYocShsLGd8fG4saCkpe2kucHVzaChsKTticmVha31rJiYodz15KX1jJiYoKGw9IXEmJmwpJiZyLS0sZiYmdC5wdXNoKGwpKX1pZihyKz1zLGMmJnMhPT1yKXtvPTA7d2hpbGUocT1iW28rK10pcSh0LHUsZyxoKTtpZihmKXtpZihyPjApd2hpbGUocy0tKXRbc118fHVbc118fCh1W3NdPUUuY2FsbChpKSk7dT13YSh1KX1HLmFwcGx5KGksdSksayYmIWYmJnUubGVuZ3RoPjAmJnIrYi5sZW5ndGg+MSYmZ2EudW5pcXVlU29ydChpKX1yZXR1cm4gayYmKHc9eSxqPXYpLHR9O3JldHVybiBjP2lhKGYpOmZ9cmV0dXJuIGg9Z2EuY29tcGlsZT1mdW5jdGlvbihhLGIpe3ZhciBjLGQ9W10sZT1bXSxmPUFbYSsiICJdO2lmKCFmKXtifHwoYj1nKGEpKSxjPWIubGVuZ3RoO3doaWxlKGMtLSlmPXlhKGJbY10pLGZbdV0/ZC5wdXNoKGYpOmUucHVzaChmKTtmPUEoYSx6YShlLGQpKSxmLnNlbGVjdG9yPWF9cmV0dXJuIGZ9LGk9Z2Euc2VsZWN0PWZ1bmN0aW9uKGEsYixlLGYpe3ZhciBpLGosayxsLG0sbj0iZnVuY3Rpb24iPT10eXBlb2YgYSYmYSxvPSFmJiZnKGE9bi5zZWxlY3Rvcnx8YSk7aWYoZT1lfHxbXSwxPT09by5sZW5ndGgpe2lmKGo9b1swXT1vWzBdLnNsaWNlKDApLGoubGVuZ3RoPjImJiJJRCI9PT0oaz1qWzBdKS50eXBlJiZjLmdldEJ5SWQmJjk9PT1iLm5vZGVUeXBlJiZwJiZkLnJlbGF0aXZlW2pbMV0udHlwZV0pe2lmKGI9KGQuZmluZC5JRChrLm1hdGNoZXNbMF0ucmVwbGFjZShfLGFhKSxiKXx8W10pWzBdLCFiKXJldHVybiBlO24mJihiPWIucGFyZW50Tm9kZSksYT1hLnNsaWNlKGouc2hpZnQoKS52YWx1ZS5sZW5ndGgpfWk9Vi5uZWVkc0NvbnRleHQudGVzdChhKT8wOmoubGVuZ3RoO3doaWxlKGktLSl7aWYoaz1qW2ldLGQucmVsYXRpdmVbbD1rLnR5cGVdKWJyZWFrO2lmKChtPWQuZmluZFtsXSkmJihmPW0oay5tYXRjaGVzWzBdLnJlcGxhY2UoXyxhYSksJC50ZXN0KGpbMF0udHlwZSkmJnFhKGIucGFyZW50Tm9kZSl8fGIpKSl7aWYoai5zcGxpY2UoaSwxKSxhPWYubGVuZ3RoJiZzYShqKSwhYSlyZXR1cm4gRy5hcHBseShlLGYpLGU7YnJlYWt9fX1yZXR1cm4obnx8aChhLG8pKShmLGIsIXAsZSwhYnx8JC50ZXN0KGEpJiZxYShiLnBhcmVudE5vZGUpfHxiKSxlfSxjLnNvcnRTdGFibGU9dS5zcGxpdCgiIikuc29ydChCKS5qb2luKCIiKT09PXUsYy5kZXRlY3REdXBsaWNhdGVzPSEhbCxtKCksYy5zb3J0RGV0YWNoZWQ9amEoZnVuY3Rpb24oYSl7cmV0dXJuIDEmYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihuLmNyZWF0ZUVsZW1lbnQoImZpZWxkc2V0IikpfSksamEoZnVuY3Rpb24oYSl7cmV0dXJuIGEuaW5uZXJIVE1MPSI8YSBocmVmPScjJz48L2E+IiwiIyI9PT1hLmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlKCJocmVmIil9KXx8a2EoInR5cGV8aHJlZnxoZWlnaHR8d2lkdGgiLGZ1bmN0aW9uKGEsYixjKXtpZighYylyZXR1cm4gYS5nZXRBdHRyaWJ1dGUoYiwidHlwZSI9PT1iLnRvTG93ZXJDYXNlKCk/MToyKX0pLGMuYXR0cmlidXRlcyYmamEoZnVuY3Rpb24oYSl7cmV0dXJuIGEuaW5uZXJIVE1MPSI8aW5wdXQvPiIsYS5maXJzdENoaWxkLnNldEF0dHJpYnV0ZSgidmFsdWUiLCIiKSwiIj09PWEuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoInZhbHVlIil9KXx8a2EoInZhbHVlIixmdW5jdGlvbihhLGIsYyl7aWYoIWMmJiJpbnB1dCI9PT1hLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpcmV0dXJuIGEuZGVmYXVsdFZhbHVlfSksamEoZnVuY3Rpb24oYSl7cmV0dXJuIG51bGw9PWEuZ2V0QXR0cmlidXRlKCJkaXNhYmxlZCIpfSl8fGthKEosZnVuY3Rpb24oYSxiLGMpe3ZhciBkO2lmKCFjKXJldHVybiBhW2JdPT09ITA/Yi50b0xvd2VyQ2FzZSgpOihkPWEuZ2V0QXR0cmlidXRlTm9kZShiKSkmJmQuc3BlY2lmaWVkP2QudmFsdWU6bnVsbH0pLGdhfShhKTtyLmZpbmQ9eCxyLmV4cHI9eC5zZWxlY3RvcnMsci5leHByWyI6Il09ci5leHByLnBzZXVkb3Msci51bmlxdWVTb3J0PXIudW5pcXVlPXgudW5pcXVlU29ydCxyLnRleHQ9eC5nZXRUZXh0LHIuaXNYTUxEb2M9eC5pc1hNTCxyLmNvbnRhaW5zPXguY29udGFpbnMsci5lc2NhcGVTZWxlY3Rvcj14LmVzY2FwZTt2YXIgeT1mdW5jdGlvbihhLGIsYyl7dmFyIGQ9W10sZT12b2lkIDAhPT1jO3doaWxlKChhPWFbYl0pJiY5IT09YS5ub2RlVHlwZSlpZigxPT09YS5ub2RlVHlwZSl7aWYoZSYmcihhKS5pcyhjKSlicmVhaztkLnB1c2goYSl9cmV0dXJuIGR9LHo9ZnVuY3Rpb24oYSxiKXtmb3IodmFyIGM9W107YTthPWEubmV4dFNpYmxpbmcpMT09PWEubm9kZVR5cGUmJmEhPT1iJiZjLnB1c2goYSk7cmV0dXJuIGN9LEE9ci5leHByLm1hdGNoLm5lZWRzQ29udGV4dCxCPS9ePChbYS16XVteXC9cMD46XHgyMFx0XHJcblxmXSopW1x4MjBcdFxyXG5cZl0qXC8/Pig/OjxcL1wxPnwpJC9pLEM9L14uW146I1xbXC4sXSokLztmdW5jdGlvbiBEKGEsYixjKXtpZihyLmlzRnVuY3Rpb24oYikpcmV0dXJuIHIuZ3JlcChhLGZ1bmN0aW9uKGEsZCl7cmV0dXJuISFiLmNhbGwoYSxkLGEpIT09Y30pO2lmKGIubm9kZVR5cGUpcmV0dXJuIHIuZ3JlcChhLGZ1bmN0aW9uKGEpe3JldHVybiBhPT09YiE9PWN9KTtpZigic3RyaW5nIj09dHlwZW9mIGIpe2lmKEMudGVzdChiKSlyZXR1cm4gci5maWx0ZXIoYixhLGMpO2I9ci5maWx0ZXIoYixhKX1yZXR1cm4gci5ncmVwKGEsZnVuY3Rpb24oYSl7cmV0dXJuIGkuY2FsbChiLGEpPi0xIT09YyYmMT09PWEubm9kZVR5cGV9KX1yLmZpbHRlcj1mdW5jdGlvbihhLGIsYyl7dmFyIGQ9YlswXTtyZXR1cm4gYyYmKGE9Ijpub3QoIithKyIpIiksMT09PWIubGVuZ3RoJiYxPT09ZC5ub2RlVHlwZT9yLmZpbmQubWF0Y2hlc1NlbGVjdG9yKGQsYSk/W2RdOltdOnIuZmluZC5tYXRjaGVzKGEsci5ncmVwKGIsZnVuY3Rpb24oYSl7cmV0dXJuIDE9PT1hLm5vZGVUeXBlfSkpfSxyLmZuLmV4dGVuZCh7ZmluZDpmdW5jdGlvbihhKXt2YXIgYixjLGQ9dGhpcy5sZW5ndGgsZT10aGlzO2lmKCJzdHJpbmciIT10eXBlb2YgYSlyZXR1cm4gdGhpcy5wdXNoU3RhY2socihhKS5maWx0ZXIoZnVuY3Rpb24oKXtmb3IoYj0wO2I8ZDtiKyspaWYoci5jb250YWlucyhlW2JdLHRoaXMpKXJldHVybiEwfSkpO2ZvcihjPXRoaXMucHVzaFN0YWNrKFtdKSxiPTA7YjxkO2IrKylyLmZpbmQoYSxlW2JdLGMpO3JldHVybiBkPjE/ci51bmlxdWVTb3J0KGMpOmN9LGZpbHRlcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2soRCh0aGlzLGF8fFtdLCExKSl9LG5vdDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2soRCh0aGlzLGF8fFtdLCEwKSl9LGlzOmZ1bmN0aW9uKGEpe3JldHVybiEhRCh0aGlzLCJzdHJpbmciPT10eXBlb2YgYSYmQS50ZXN0KGEpP3IoYSk6YXx8W10sITEpLmxlbmd0aH19KTt2YXIgRSxGPS9eKD86XHMqKDxbXHdcV10rPilbXj5dKnwjKFtcdy1dKykpJC8sRz1yLmZuLmluaXQ9ZnVuY3Rpb24oYSxiLGMpe3ZhciBlLGY7aWYoIWEpcmV0dXJuIHRoaXM7aWYoYz1jfHxFLCJzdHJpbmciPT10eXBlb2YgYSl7aWYoZT0iPCI9PT1hWzBdJiYiPiI9PT1hW2EubGVuZ3RoLTFdJiZhLmxlbmd0aD49Mz9bbnVsbCxhLG51bGxdOkYuZXhlYyhhKSwhZXx8IWVbMV0mJmIpcmV0dXJuIWJ8fGIuanF1ZXJ5PyhifHxjKS5maW5kKGEpOnRoaXMuY29uc3RydWN0b3IoYikuZmluZChhKTtpZihlWzFdKXtpZihiPWIgaW5zdGFuY2VvZiByP2JbMF06YixyLm1lcmdlKHRoaXMsci5wYXJzZUhUTUwoZVsxXSxiJiZiLm5vZGVUeXBlP2Iub3duZXJEb2N1bWVudHx8YjpkLCEwKSksQi50ZXN0KGVbMV0pJiZyLmlzUGxhaW5PYmplY3QoYikpZm9yKGUgaW4gYilyLmlzRnVuY3Rpb24odGhpc1tlXSk/dGhpc1tlXShiW2VdKTp0aGlzLmF0dHIoZSxiW2VdKTtyZXR1cm4gdGhpc31yZXR1cm4gZj1kLmdldEVsZW1lbnRCeUlkKGVbMl0pLGYmJih0aGlzWzBdPWYsdGhpcy5sZW5ndGg9MSksdGhpc31yZXR1cm4gYS5ub2RlVHlwZT8odGhpc1swXT1hLHRoaXMubGVuZ3RoPTEsdGhpcyk6ci5pc0Z1bmN0aW9uKGEpP3ZvaWQgMCE9PWMucmVhZHk/Yy5yZWFkeShhKTphKHIpOnIubWFrZUFycmF5KGEsdGhpcyl9O0cucHJvdG90eXBlPXIuZm4sRT1yKGQpO3ZhciBIPS9eKD86cGFyZW50c3xwcmV2KD86VW50aWx8QWxsKSkvLEk9e2NoaWxkcmVuOiEwLGNvbnRlbnRzOiEwLG5leHQ6ITAscHJldjohMH07ci5mbi5leHRlbmQoe2hhczpmdW5jdGlvbihhKXt2YXIgYj1yKGEsdGhpcyksYz1iLmxlbmd0aDtyZXR1cm4gdGhpcy5maWx0ZXIoZnVuY3Rpb24oKXtmb3IodmFyIGE9MDthPGM7YSsrKWlmKHIuY29udGFpbnModGhpcyxiW2FdKSlyZXR1cm4hMH0pfSxjbG9zZXN0OmZ1bmN0aW9uKGEsYil7dmFyIGMsZD0wLGU9dGhpcy5sZW5ndGgsZj1bXSxnPSJzdHJpbmciIT10eXBlb2YgYSYmcihhKTtpZighQS50ZXN0KGEpKWZvcig7ZDxlO2QrKylmb3IoYz10aGlzW2RdO2MmJmMhPT1iO2M9Yy5wYXJlbnROb2RlKWlmKGMubm9kZVR5cGU8MTEmJihnP2cuaW5kZXgoYyk+LTE6MT09PWMubm9kZVR5cGUmJnIuZmluZC5tYXRjaGVzU2VsZWN0b3IoYyxhKSkpe2YucHVzaChjKTticmVha31yZXR1cm4gdGhpcy5wdXNoU3RhY2soZi5sZW5ndGg+MT9yLnVuaXF1ZVNvcnQoZik6Zil9LGluZGV4OmZ1bmN0aW9uKGEpe3JldHVybiBhPyJzdHJpbmciPT10eXBlb2YgYT9pLmNhbGwocihhKSx0aGlzWzBdKTppLmNhbGwodGhpcyxhLmpxdWVyeT9hWzBdOmEpOnRoaXNbMF0mJnRoaXNbMF0ucGFyZW50Tm9kZT90aGlzLmZpcnN0KCkucHJldkFsbCgpLmxlbmd0aDotMX0sYWRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucHVzaFN0YWNrKHIudW5pcXVlU29ydChyLm1lcmdlKHRoaXMuZ2V0KCkscihhLGIpKSkpfSxhZGRCYWNrOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmFkZChudWxsPT1hP3RoaXMucHJldk9iamVjdDp0aGlzLnByZXZPYmplY3QuZmlsdGVyKGEpKX19KTtmdW5jdGlvbiBKKGEsYil7d2hpbGUoKGE9YVtiXSkmJjEhPT1hLm5vZGVUeXBlKTtyZXR1cm4gYX1yLmVhY2goe3BhcmVudDpmdW5jdGlvbihhKXt2YXIgYj1hLnBhcmVudE5vZGU7cmV0dXJuIGImJjExIT09Yi5ub2RlVHlwZT9iOm51bGx9LHBhcmVudHM6ZnVuY3Rpb24oYSl7cmV0dXJuIHkoYSwicGFyZW50Tm9kZSIpfSxwYXJlbnRzVW50aWw6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB5KGEsInBhcmVudE5vZGUiLGMpfSxuZXh0OmZ1bmN0aW9uKGEpe3JldHVybiBKKGEsIm5leHRTaWJsaW5nIil9LHByZXY6ZnVuY3Rpb24oYSl7cmV0dXJuIEooYSwicHJldmlvdXNTaWJsaW5nIil9LG5leHRBbGw6ZnVuY3Rpb24oYSl7cmV0dXJuIHkoYSwibmV4dFNpYmxpbmciKX0scHJldkFsbDpmdW5jdGlvbihhKXtyZXR1cm4geShhLCJwcmV2aW91c1NpYmxpbmciKX0sbmV4dFVudGlsOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4geShhLCJuZXh0U2libGluZyIsYyl9LHByZXZVbnRpbDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHkoYSwicHJldmlvdXNTaWJsaW5nIixjKX0sc2libGluZ3M6ZnVuY3Rpb24oYSl7cmV0dXJuIHooKGEucGFyZW50Tm9kZXx8e30pLmZpcnN0Q2hpbGQsYSl9LGNoaWxkcmVuOmZ1bmN0aW9uKGEpe3JldHVybiB6KGEuZmlyc3RDaGlsZCl9LGNvbnRlbnRzOmZ1bmN0aW9uKGEpe3JldHVybiBhLmNvbnRlbnREb2N1bWVudHx8ci5tZXJnZShbXSxhLmNoaWxkTm9kZXMpfX0sZnVuY3Rpb24oYSxiKXtyLmZuW2FdPWZ1bmN0aW9uKGMsZCl7dmFyIGU9ci5tYXAodGhpcyxiLGMpO3JldHVybiJVbnRpbCIhPT1hLnNsaWNlKC01KSYmKGQ9YyksZCYmInN0cmluZyI9PXR5cGVvZiBkJiYoZT1yLmZpbHRlcihkLGUpKSx0aGlzLmxlbmd0aD4xJiYoSVthXXx8ci51bmlxdWVTb3J0KGUpLEgudGVzdChhKSYmZS5yZXZlcnNlKCkpLHRoaXMucHVzaFN0YWNrKGUpfX0pO3ZhciBLPS9cUysvZztmdW5jdGlvbiBMKGEpe3ZhciBiPXt9O3JldHVybiByLmVhY2goYS5tYXRjaChLKXx8W10sZnVuY3Rpb24oYSxjKXtiW2NdPSEwfSksYn1yLkNhbGxiYWNrcz1mdW5jdGlvbihhKXthPSJzdHJpbmciPT10eXBlb2YgYT9MKGEpOnIuZXh0ZW5kKHt9LGEpO3ZhciBiLGMsZCxlLGY9W10sZz1bXSxoPS0xLGk9ZnVuY3Rpb24oKXtmb3IoZT1hLm9uY2UsZD1iPSEwO2cubGVuZ3RoO2g9LTEpe2M9Zy5zaGlmdCgpO3doaWxlKCsraDxmLmxlbmd0aClmW2hdLmFwcGx5KGNbMF0sY1sxXSk9PT0hMSYmYS5zdG9wT25GYWxzZSYmKGg9Zi5sZW5ndGgsYz0hMSl9YS5tZW1vcnl8fChjPSExKSxiPSExLGUmJihmPWM/W106IiIpfSxqPXthZGQ6ZnVuY3Rpb24oKXtyZXR1cm4gZiYmKGMmJiFiJiYoaD1mLmxlbmd0aC0xLGcucHVzaChjKSksZnVuY3Rpb24gZChiKXtyLmVhY2goYixmdW5jdGlvbihiLGMpe3IuaXNGdW5jdGlvbihjKT9hLnVuaXF1ZSYmai5oYXMoYyl8fGYucHVzaChjKTpjJiZjLmxlbmd0aCYmInN0cmluZyIhPT1yLnR5cGUoYykmJmQoYyl9KX0oYXJndW1lbnRzKSxjJiYhYiYmaSgpKSx0aGlzfSxyZW1vdmU6ZnVuY3Rpb24oKXtyZXR1cm4gci5lYWNoKGFyZ3VtZW50cyxmdW5jdGlvbihhLGIpe3ZhciBjO3doaWxlKChjPXIuaW5BcnJheShiLGYsYykpPi0xKWYuc3BsaWNlKGMsMSksYzw9aCYmaC0tfSksdGhpc30saGFzOmZ1bmN0aW9uKGEpe3JldHVybiBhP3IuaW5BcnJheShhLGYpPi0xOmYubGVuZ3RoPjB9LGVtcHR5OmZ1bmN0aW9uKCl7cmV0dXJuIGYmJihmPVtdKSx0aGlzfSxkaXNhYmxlOmZ1bmN0aW9uKCl7cmV0dXJuIGU9Zz1bXSxmPWM9IiIsdGhpc30sZGlzYWJsZWQ6ZnVuY3Rpb24oKXtyZXR1cm4hZn0sbG9jazpmdW5jdGlvbigpe3JldHVybiBlPWc9W10sY3x8Ynx8KGY9Yz0iIiksdGhpc30sbG9ja2VkOmZ1bmN0aW9uKCl7cmV0dXJuISFlfSxmaXJlV2l0aDpmdW5jdGlvbihhLGMpe3JldHVybiBlfHwoYz1jfHxbXSxjPVthLGMuc2xpY2U/Yy5zbGljZSgpOmNdLGcucHVzaChjKSxifHxpKCkpLHRoaXN9LGZpcmU6ZnVuY3Rpb24oKXtyZXR1cm4gai5maXJlV2l0aCh0aGlzLGFyZ3VtZW50cyksdGhpc30sZmlyZWQ6ZnVuY3Rpb24oKXtyZXR1cm4hIWR9fTtyZXR1cm4gan07ZnVuY3Rpb24gTShhKXtyZXR1cm4gYX1mdW5jdGlvbiBOKGEpe3Rocm93IGF9ZnVuY3Rpb24gTyhhLGIsYyl7dmFyIGQ7dHJ5e2EmJnIuaXNGdW5jdGlvbihkPWEucHJvbWlzZSk/ZC5jYWxsKGEpLmRvbmUoYikuZmFpbChjKTphJiZyLmlzRnVuY3Rpb24oZD1hLnRoZW4pP2QuY2FsbChhLGIsYyk6Yi5jYWxsKHZvaWQgMCxhKX1jYXRjaChhKXtjLmNhbGwodm9pZCAwLGEpfX1yLmV4dGVuZCh7RGVmZXJyZWQ6ZnVuY3Rpb24oYil7dmFyIGM9W1sibm90aWZ5IiwicHJvZ3Jlc3MiLHIuQ2FsbGJhY2tzKCJtZW1vcnkiKSxyLkNhbGxiYWNrcygibWVtb3J5IiksMl0sWyJyZXNvbHZlIiwiZG9uZSIsci5DYWxsYmFja3MoIm9uY2UgbWVtb3J5Iiksci5DYWxsYmFja3MoIm9uY2UgbWVtb3J5IiksMCwicmVzb2x2ZWQiXSxbInJlamVjdCIsImZhaWwiLHIuQ2FsbGJhY2tzKCJvbmNlIG1lbW9yeSIpLHIuQ2FsbGJhY2tzKCJvbmNlIG1lbW9yeSIpLDEsInJlamVjdGVkIl1dLGQ9InBlbmRpbmciLGU9e3N0YXRlOmZ1bmN0aW9uKCl7cmV0dXJuIGR9LGFsd2F5czpmdW5jdGlvbigpe3JldHVybiBmLmRvbmUoYXJndW1lbnRzKS5mYWlsKGFyZ3VtZW50cyksdGhpc30sImNhdGNoIjpmdW5jdGlvbihhKXtyZXR1cm4gZS50aGVuKG51bGwsYSl9LHBpcGU6ZnVuY3Rpb24oKXt2YXIgYT1hcmd1bWVudHM7cmV0dXJuIHIuRGVmZXJyZWQoZnVuY3Rpb24oYil7ci5lYWNoKGMsZnVuY3Rpb24oYyxkKXt2YXIgZT1yLmlzRnVuY3Rpb24oYVtkWzRdXSkmJmFbZFs0XV07ZltkWzFdXShmdW5jdGlvbigpe3ZhciBhPWUmJmUuYXBwbHkodGhpcyxhcmd1bWVudHMpO2EmJnIuaXNGdW5jdGlvbihhLnByb21pc2UpP2EucHJvbWlzZSgpLnByb2dyZXNzKGIubm90aWZ5KS5kb25lKGIucmVzb2x2ZSkuZmFpbChiLnJlamVjdCk6YltkWzBdKyJXaXRoIl0odGhpcyxlP1thXTphcmd1bWVudHMpfSl9KSxhPW51bGx9KS5wcm9taXNlKCl9LHRoZW46ZnVuY3Rpb24oYixkLGUpe3ZhciBmPTA7ZnVuY3Rpb24gZyhiLGMsZCxlKXtyZXR1cm4gZnVuY3Rpb24oKXt2YXIgaD10aGlzLGk9YXJndW1lbnRzLGo9ZnVuY3Rpb24oKXt2YXIgYSxqO2lmKCEoYjxmKSl7aWYoYT1kLmFwcGx5KGgsaSksYT09PWMucHJvbWlzZSgpKXRocm93IG5ldyBUeXBlRXJyb3IoIlRoZW5hYmxlIHNlbGYtcmVzb2x1dGlvbiIpO2o9YSYmKCJvYmplY3QiPT10eXBlb2YgYXx8ImZ1bmN0aW9uIj09dHlwZW9mIGEpJiZhLnRoZW4sci5pc0Z1bmN0aW9uKGopP2U/ai5jYWxsKGEsZyhmLGMsTSxlKSxnKGYsYyxOLGUpKTooZisrLGouY2FsbChhLGcoZixjLE0sZSksZyhmLGMsTixlKSxnKGYsYyxNLGMubm90aWZ5V2l0aCkpKTooZCE9PU0mJihoPXZvaWQgMCxpPVthXSksKGV8fGMucmVzb2x2ZVdpdGgpKGgsaSkpfX0saz1lP2o6ZnVuY3Rpb24oKXt0cnl7aigpfWNhdGNoKGEpe3IuRGVmZXJyZWQuZXhjZXB0aW9uSG9vayYmci5EZWZlcnJlZC5leGNlcHRpb25Ib29rKGEsay5zdGFja1RyYWNlKSxiKzE+PWYmJihkIT09TiYmKGg9dm9pZCAwLGk9W2FdKSxjLnJlamVjdFdpdGgoaCxpKSl9fTtiP2soKTooci5EZWZlcnJlZC5nZXRTdGFja0hvb2smJihrLnN0YWNrVHJhY2U9ci5EZWZlcnJlZC5nZXRTdGFja0hvb2soKSksYS5zZXRUaW1lb3V0KGspKX19cmV0dXJuIHIuRGVmZXJyZWQoZnVuY3Rpb24oYSl7Y1swXVszXS5hZGQoZygwLGEsci5pc0Z1bmN0aW9uKGUpP2U6TSxhLm5vdGlmeVdpdGgpKSxjWzFdWzNdLmFkZChnKDAsYSxyLmlzRnVuY3Rpb24oYik/YjpNKSksY1syXVszXS5hZGQoZygwLGEsci5pc0Z1bmN0aW9uKGQpP2Q6TikpfSkucHJvbWlzZSgpfSxwcm9taXNlOmZ1bmN0aW9uKGEpe3JldHVybiBudWxsIT1hP3IuZXh0ZW5kKGEsZSk6ZX19LGY9e307cmV0dXJuIHIuZWFjaChjLGZ1bmN0aW9uKGEsYil7dmFyIGc9YlsyXSxoPWJbNV07ZVtiWzFdXT1nLmFkZCxoJiZnLmFkZChmdW5jdGlvbigpe2Q9aH0sY1szLWFdWzJdLmRpc2FibGUsY1swXVsyXS5sb2NrKSxnLmFkZChiWzNdLmZpcmUpLGZbYlswXV09ZnVuY3Rpb24oKXtyZXR1cm4gZltiWzBdKyJXaXRoIl0odGhpcz09PWY/dm9pZCAwOnRoaXMsYXJndW1lbnRzKSx0aGlzfSxmW2JbMF0rIldpdGgiXT1nLmZpcmVXaXRofSksZS5wcm9taXNlKGYpLGImJmIuY2FsbChmLGYpLGZ9LHdoZW46ZnVuY3Rpb24oYSl7dmFyIGI9YXJndW1lbnRzLmxlbmd0aCxjPWIsZD1BcnJheShjKSxlPWYuY2FsbChhcmd1bWVudHMpLGc9ci5EZWZlcnJlZCgpLGg9ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKGMpe2RbYV09dGhpcyxlW2FdPWFyZ3VtZW50cy5sZW5ndGg+MT9mLmNhbGwoYXJndW1lbnRzKTpjLC0tYnx8Zy5yZXNvbHZlV2l0aChkLGUpfX07aWYoYjw9MSYmKE8oYSxnLmRvbmUoaChjKSkucmVzb2x2ZSxnLnJlamVjdCksInBlbmRpbmciPT09Zy5zdGF0ZSgpfHxyLmlzRnVuY3Rpb24oZVtjXSYmZVtjXS50aGVuKSkpcmV0dXJuIGcudGhlbigpO3doaWxlKGMtLSlPKGVbY10saChjKSxnLnJlamVjdCk7cmV0dXJuIGcucHJvbWlzZSgpfX0pO3ZhciBQPS9eKEV2YWx8SW50ZXJuYWx8UmFuZ2V8UmVmZXJlbmNlfFN5bnRheHxUeXBlfFVSSSlFcnJvciQvO3IuRGVmZXJyZWQuZXhjZXB0aW9uSG9vaz1mdW5jdGlvbihiLGMpe2EuY29uc29sZSYmYS5jb25zb2xlLndhcm4mJmImJlAudGVzdChiLm5hbWUpJiZhLmNvbnNvbGUud2FybigialF1ZXJ5LkRlZmVycmVkIGV4Y2VwdGlvbjogIitiLm1lc3NhZ2UsYi5zdGFjayxjKX0sci5yZWFkeUV4Y2VwdGlvbj1mdW5jdGlvbihiKXthLnNldFRpbWVvdXQoZnVuY3Rpb24oKXt0aHJvdyBifSl9O3ZhciBRPXIuRGVmZXJyZWQoKTtyLmZuLnJlYWR5PWZ1bmN0aW9uKGEpe3JldHVybiBRLnRoZW4oYSlbImNhdGNoIl0oZnVuY3Rpb24oYSl7ci5yZWFkeUV4Y2VwdGlvbihhKX0pLHRoaXN9LHIuZXh0ZW5kKHtpc1JlYWR5OiExLHJlYWR5V2FpdDoxLGhvbGRSZWFkeTpmdW5jdGlvbihhKXthP3IucmVhZHlXYWl0Kys6ci5yZWFkeSghMCl9LHJlYWR5OmZ1bmN0aW9uKGEpeyhhPT09ITA/LS1yLnJlYWR5V2FpdDpyLmlzUmVhZHkpfHwoci5pc1JlYWR5PSEwLGEhPT0hMCYmLS1yLnJlYWR5V2FpdD4wfHxRLnJlc29sdmVXaXRoKGQsW3JdKSl9fSksci5yZWFkeS50aGVuPVEudGhlbjtmdW5jdGlvbiBSKCl7ZC5yZW1vdmVFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIixSKSxhLnJlbW92ZUV2ZW50TGlzdGVuZXIoImxvYWQiLFIpLHIucmVhZHkoKX0iY29tcGxldGUiPT09ZC5yZWFkeVN0YXRlfHwibG9hZGluZyIhPT1kLnJlYWR5U3RhdGUmJiFkLmRvY3VtZW50RWxlbWVudC5kb1Njcm9sbD9hLnNldFRpbWVvdXQoci5yZWFkeSk6KGQuYWRkRXZlbnRMaXN0ZW5lcigiRE9NQ29udGVudExvYWRlZCIsUiksYS5hZGRFdmVudExpc3RlbmVyKCJsb2FkIixSKSk7dmFyIFM9ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIGg9MCxpPWEubGVuZ3RoLGo9bnVsbD09YztpZigib2JqZWN0Ij09PXIudHlwZShjKSl7ZT0hMDtmb3IoaCBpbiBjKVMoYSxiLGgsY1toXSwhMCxmLGcpfWVsc2UgaWYodm9pZCAwIT09ZCYmKGU9ITAsCi1yLmlzRnVuY3Rpb24oZCl8fChnPSEwKSxqJiYoZz8oYi5jYWxsKGEsZCksYj1udWxsKTooaj1iLGI9ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBqLmNhbGwocihhKSxjKX0pKSxiKSlmb3IoO2g8aTtoKyspYihhW2hdLGMsZz9kOmQuY2FsbChhW2hdLGgsYihhW2hdLGMpKSk7cmV0dXJuIGU/YTpqP2IuY2FsbChhKTppP2IoYVswXSxjKTpmfSxUPWZ1bmN0aW9uKGEpe3JldHVybiAxPT09YS5ub2RlVHlwZXx8OT09PWEubm9kZVR5cGV8fCErYS5ub2RlVHlwZX07ZnVuY3Rpb24gVSgpe3RoaXMuZXhwYW5kbz1yLmV4cGFuZG8rVS51aWQrK31VLnVpZD0xLFUucHJvdG90eXBlPXtjYWNoZTpmdW5jdGlvbihhKXt2YXIgYj1hW3RoaXMuZXhwYW5kb107cmV0dXJuIGJ8fChiPXt9LFQoYSkmJihhLm5vZGVUeXBlP2FbdGhpcy5leHBhbmRvXT1iOk9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHRoaXMuZXhwYW5kbyx7dmFsdWU6Yixjb25maWd1cmFibGU6ITB9KSkpLGJ9LHNldDpmdW5jdGlvbihhLGIsYyl7dmFyIGQsZT10aGlzLmNhY2hlKGEpO2lmKCJzdHJpbmciPT10eXBlb2YgYillW3IuY2FtZWxDYXNlKGIpXT1jO2Vsc2UgZm9yKGQgaW4gYillW3IuY2FtZWxDYXNlKGQpXT1iW2RdO3JldHVybiBlfSxnZXQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdm9pZCAwPT09Yj90aGlzLmNhY2hlKGEpOmFbdGhpcy5leHBhbmRvXSYmYVt0aGlzLmV4cGFuZG9dW3IuY2FtZWxDYXNlKGIpXX0sYWNjZXNzOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gdm9pZCAwPT09Ynx8YiYmInN0cmluZyI9PXR5cGVvZiBiJiZ2b2lkIDA9PT1jP3RoaXMuZ2V0KGEsYik6KHRoaXMuc2V0KGEsYixjKSx2b2lkIDAhPT1jP2M6Yil9LHJlbW92ZTpmdW5jdGlvbihhLGIpe3ZhciBjLGQ9YVt0aGlzLmV4cGFuZG9dO2lmKHZvaWQgMCE9PWQpe2lmKHZvaWQgMCE9PWIpe3IuaXNBcnJheShiKT9iPWIubWFwKHIuY2FtZWxDYXNlKTooYj1yLmNhbWVsQ2FzZShiKSxiPWIgaW4gZD9bYl06Yi5tYXRjaChLKXx8W10pLGM9Yi5sZW5ndGg7d2hpbGUoYy0tKWRlbGV0ZSBkW2JbY11dfSh2b2lkIDA9PT1ifHxyLmlzRW1wdHlPYmplY3QoZCkpJiYoYS5ub2RlVHlwZT9hW3RoaXMuZXhwYW5kb109dm9pZCAwOmRlbGV0ZSBhW3RoaXMuZXhwYW5kb10pfX0saGFzRGF0YTpmdW5jdGlvbihhKXt2YXIgYj1hW3RoaXMuZXhwYW5kb107cmV0dXJuIHZvaWQgMCE9PWImJiFyLmlzRW1wdHlPYmplY3QoYil9fTt2YXIgVj1uZXcgVSxXPW5ldyBVLFg9L14oPzpce1tcd1xXXSpcfXxcW1tcd1xXXSpcXSkkLyxZPS9bQS1aXS9nO2Z1bmN0aW9uIFooYSxiLGMpe3ZhciBkO2lmKHZvaWQgMD09PWMmJjE9PT1hLm5vZGVUeXBlKWlmKGQ9ImRhdGEtIitiLnJlcGxhY2UoWSwiLSQmIikudG9Mb3dlckNhc2UoKSxjPWEuZ2V0QXR0cmlidXRlKGQpLCJzdHJpbmciPT10eXBlb2YgYyl7dHJ5e2M9InRydWUiPT09Y3x8ImZhbHNlIiE9PWMmJigibnVsbCI9PT1jP251bGw6K2MrIiI9PT1jPytjOlgudGVzdChjKT9KU09OLnBhcnNlKGMpOmMpfWNhdGNoKGUpe31XLnNldChhLGIsYyl9ZWxzZSBjPXZvaWQgMDtyZXR1cm4gY31yLmV4dGVuZCh7aGFzRGF0YTpmdW5jdGlvbihhKXtyZXR1cm4gVy5oYXNEYXRhKGEpfHxWLmhhc0RhdGEoYSl9LGRhdGE6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBXLmFjY2VzcyhhLGIsYyl9LHJlbW92ZURhdGE6ZnVuY3Rpb24oYSxiKXtXLnJlbW92ZShhLGIpfSxfZGF0YTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIFYuYWNjZXNzKGEsYixjKX0sX3JlbW92ZURhdGE6ZnVuY3Rpb24oYSxiKXtWLnJlbW92ZShhLGIpfX0pLHIuZm4uZXh0ZW5kKHtkYXRhOmZ1bmN0aW9uKGEsYil7dmFyIGMsZCxlLGY9dGhpc1swXSxnPWYmJmYuYXR0cmlidXRlcztpZih2b2lkIDA9PT1hKXtpZih0aGlzLmxlbmd0aCYmKGU9Vy5nZXQoZiksMT09PWYubm9kZVR5cGUmJiFWLmdldChmLCJoYXNEYXRhQXR0cnMiKSkpe2M9Zy5sZW5ndGg7d2hpbGUoYy0tKWdbY10mJihkPWdbY10ubmFtZSwwPT09ZC5pbmRleE9mKCJkYXRhLSIpJiYoZD1yLmNhbWVsQ2FzZShkLnNsaWNlKDUpKSxaKGYsZCxlW2RdKSkpO1Yuc2V0KGYsImhhc0RhdGFBdHRycyIsITApfXJldHVybiBlfXJldHVybiJvYmplY3QiPT10eXBlb2YgYT90aGlzLmVhY2goZnVuY3Rpb24oKXtXLnNldCh0aGlzLGEpfSk6Uyh0aGlzLGZ1bmN0aW9uKGIpe3ZhciBjO2lmKGYmJnZvaWQgMD09PWIpe2lmKGM9Vy5nZXQoZixhKSx2b2lkIDAhPT1jKXJldHVybiBjO2lmKGM9WihmLGEpLHZvaWQgMCE9PWMpcmV0dXJuIGN9ZWxzZSB0aGlzLmVhY2goZnVuY3Rpb24oKXtXLnNldCh0aGlzLGEsYil9KX0sbnVsbCxiLGFyZ3VtZW50cy5sZW5ndGg+MSxudWxsLCEwKX0scmVtb3ZlRGF0YTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7Vy5yZW1vdmUodGhpcyxhKX0pfX0pLHIuZXh0ZW5kKHtxdWV1ZTpmdW5jdGlvbihhLGIsYyl7dmFyIGQ7aWYoYSlyZXR1cm4gYj0oYnx8ImZ4IikrInF1ZXVlIixkPVYuZ2V0KGEsYiksYyYmKCFkfHxyLmlzQXJyYXkoYyk/ZD1WLmFjY2VzcyhhLGIsci5tYWtlQXJyYXkoYykpOmQucHVzaChjKSksZHx8W119LGRlcXVldWU6ZnVuY3Rpb24oYSxiKXtiPWJ8fCJmeCI7dmFyIGM9ci5xdWV1ZShhLGIpLGQ9Yy5sZW5ndGgsZT1jLnNoaWZ0KCksZj1yLl9xdWV1ZUhvb2tzKGEsYiksZz1mdW5jdGlvbigpe3IuZGVxdWV1ZShhLGIpfTsiaW5wcm9ncmVzcyI9PT1lJiYoZT1jLnNoaWZ0KCksZC0tKSxlJiYoImZ4Ij09PWImJmMudW5zaGlmdCgiaW5wcm9ncmVzcyIpLGRlbGV0ZSBmLnN0b3AsZS5jYWxsKGEsZyxmKSksIWQmJmYmJmYuZW1wdHkuZmlyZSgpfSxfcXVldWVIb29rczpmdW5jdGlvbihhLGIpe3ZhciBjPWIrInF1ZXVlSG9va3MiO3JldHVybiBWLmdldChhLGMpfHxWLmFjY2VzcyhhLGMse2VtcHR5OnIuQ2FsbGJhY2tzKCJvbmNlIG1lbW9yeSIpLmFkZChmdW5jdGlvbigpe1YucmVtb3ZlKGEsW2IrInF1ZXVlIixjXSl9KX0pfX0pLHIuZm4uZXh0ZW5kKHtxdWV1ZTpmdW5jdGlvbihhLGIpe3ZhciBjPTI7cmV0dXJuInN0cmluZyIhPXR5cGVvZiBhJiYoYj1hLGE9ImZ4IixjLS0pLGFyZ3VtZW50cy5sZW5ndGg8Yz9yLnF1ZXVlKHRoaXNbMF0sYSk6dm9pZCAwPT09Yj90aGlzOnRoaXMuZWFjaChmdW5jdGlvbigpe3ZhciBjPXIucXVldWUodGhpcyxhLGIpO3IuX3F1ZXVlSG9va3ModGhpcyxhKSwiZngiPT09YSYmImlucHJvZ3Jlc3MiIT09Y1swXSYmci5kZXF1ZXVlKHRoaXMsYSl9KX0sZGVxdWV1ZTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7ci5kZXF1ZXVlKHRoaXMsYSl9KX0sY2xlYXJRdWV1ZTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5xdWV1ZShhfHwiZngiLFtdKX0scHJvbWlzZTpmdW5jdGlvbihhLGIpe3ZhciBjLGQ9MSxlPXIuRGVmZXJyZWQoKSxmPXRoaXMsZz10aGlzLmxlbmd0aCxoPWZ1bmN0aW9uKCl7LS1kfHxlLnJlc29sdmVXaXRoKGYsW2ZdKX07InN0cmluZyIhPXR5cGVvZiBhJiYoYj1hLGE9dm9pZCAwKSxhPWF8fCJmeCI7d2hpbGUoZy0tKWM9Vi5nZXQoZltnXSxhKyJxdWV1ZUhvb2tzIiksYyYmYy5lbXB0eSYmKGQrKyxjLmVtcHR5LmFkZChoKSk7cmV0dXJuIGgoKSxlLnByb21pc2UoYil9fSk7dmFyICQ9L1srLV0/KD86XGQqXC58KVxkKyg/OltlRV1bKy1dP1xkK3wpLy5zb3VyY2UsXz1uZXcgUmVnRXhwKCJeKD86KFsrLV0pPXwpKCIrJCsiKShbYS16JV0qKSQiLCJpIiksYWE9WyJUb3AiLCJSaWdodCIsIkJvdHRvbSIsIkxlZnQiXSxiYT1mdW5jdGlvbihhLGIpe3JldHVybiBhPWJ8fGEsIm5vbmUiPT09YS5zdHlsZS5kaXNwbGF5fHwiIj09PWEuc3R5bGUuZGlzcGxheSYmci5jb250YWlucyhhLm93bmVyRG9jdW1lbnQsYSkmJiJub25lIj09PXIuY3NzKGEsImRpc3BsYXkiKX0sY2E9ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIGUsZixnPXt9O2ZvcihmIGluIGIpZ1tmXT1hLnN0eWxlW2ZdLGEuc3R5bGVbZl09YltmXTtlPWMuYXBwbHkoYSxkfHxbXSk7Zm9yKGYgaW4gYilhLnN0eWxlW2ZdPWdbZl07cmV0dXJuIGV9O2Z1bmN0aW9uIGRhKGEsYixjLGQpe3ZhciBlLGY9MSxnPTIwLGg9ZD9mdW5jdGlvbigpe3JldHVybiBkLmN1cigpfTpmdW5jdGlvbigpe3JldHVybiByLmNzcyhhLGIsIiIpfSxpPWgoKSxqPWMmJmNbM118fChyLmNzc051bWJlcltiXT8iIjoicHgiKSxrPShyLmNzc051bWJlcltiXXx8InB4IiE9PWomJitpKSYmXy5leGVjKHIuY3NzKGEsYikpO2lmKGsmJmtbM10hPT1qKXtqPWp8fGtbM10sYz1jfHxbXSxrPStpfHwxO2RvIGY9Znx8Ii41IixrLz1mLHIuc3R5bGUoYSxiLGsraik7d2hpbGUoZiE9PShmPWgoKS9pKSYmMSE9PWYmJi0tZyl9cmV0dXJuIGMmJihrPStrfHwraXx8MCxlPWNbMV0/aysoY1sxXSsxKSpjWzJdOitjWzJdLGQmJihkLnVuaXQ9aixkLnN0YXJ0PWssZC5lbmQ9ZSkpLGV9dmFyIGVhPXt9O2Z1bmN0aW9uIGZhKGEpe3ZhciBiLGM9YS5vd25lckRvY3VtZW50LGQ9YS5ub2RlTmFtZSxlPWVhW2RdO3JldHVybiBlP2U6KGI9Yy5ib2R5LmFwcGVuZENoaWxkKGMuY3JlYXRlRWxlbWVudChkKSksZT1yLmNzcyhiLCJkaXNwbGF5IiksYi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGIpLCJub25lIj09PWUmJihlPSJibG9jayIpLGVhW2RdPWUsZSl9ZnVuY3Rpb24gZ2EoYSxiKXtmb3IodmFyIGMsZCxlPVtdLGY9MCxnPWEubGVuZ3RoO2Y8ZztmKyspZD1hW2ZdLGQuc3R5bGUmJihjPWQuc3R5bGUuZGlzcGxheSxiPygibm9uZSI9PT1jJiYoZVtmXT1WLmdldChkLCJkaXNwbGF5Iil8fG51bGwsZVtmXXx8KGQuc3R5bGUuZGlzcGxheT0iIikpLCIiPT09ZC5zdHlsZS5kaXNwbGF5JiZiYShkKSYmKGVbZl09ZmEoZCkpKToibm9uZSIhPT1jJiYoZVtmXT0ibm9uZSIsVi5zZXQoZCwiZGlzcGxheSIsYykpKTtmb3IoZj0wO2Y8ZztmKyspbnVsbCE9ZVtmXSYmKGFbZl0uc3R5bGUuZGlzcGxheT1lW2ZdKTtyZXR1cm4gYX1yLmZuLmV4dGVuZCh7c2hvdzpmdW5jdGlvbigpe3JldHVybiBnYSh0aGlzLCEwKX0saGlkZTpmdW5jdGlvbigpe3JldHVybiBnYSh0aGlzKX0sdG9nZ2xlOmZ1bmN0aW9uKGEpe3JldHVybiJib29sZWFuIj09dHlwZW9mIGE/YT90aGlzLnNob3coKTp0aGlzLmhpZGUoKTp0aGlzLmVhY2goZnVuY3Rpb24oKXtiYSh0aGlzKT9yKHRoaXMpLnNob3coKTpyKHRoaXMpLmhpZGUoKX0pfX0pO3ZhciBoYT0vXig/OmNoZWNrYm94fHJhZGlvKSQvaSxpYT0vPChbYS16XVteXC9cMD5ceDIwXHRcclxuXGZdKykvaSxqYT0vXiR8XC8oPzpqYXZhfGVjbWEpc2NyaXB0L2ksa2E9e29wdGlvbjpbMSwiPHNlbGVjdCBtdWx0aXBsZT0nbXVsdGlwbGUnPiIsIjwvc2VsZWN0PiJdLHRoZWFkOlsxLCI8dGFibGU+IiwiPC90YWJsZT4iXSxjb2w6WzIsIjx0YWJsZT48Y29sZ3JvdXA+IiwiPC9jb2xncm91cD48L3RhYmxlPiJdLHRyOlsyLCI8dGFibGU+PHRib2R5PiIsIjwvdGJvZHk+PC90YWJsZT4iXSx0ZDpbMywiPHRhYmxlPjx0Ym9keT48dHI+IiwiPC90cj48L3Rib2R5PjwvdGFibGU+Il0sX2RlZmF1bHQ6WzAsIiIsIiJdfTtrYS5vcHRncm91cD1rYS5vcHRpb24sa2EudGJvZHk9a2EudGZvb3Q9a2EuY29sZ3JvdXA9a2EuY2FwdGlvbj1rYS50aGVhZCxrYS50aD1rYS50ZDtmdW5jdGlvbiBsYShhLGIpe3ZhciBjPSJ1bmRlZmluZWQiIT10eXBlb2YgYS5nZXRFbGVtZW50c0J5VGFnTmFtZT9hLmdldEVsZW1lbnRzQnlUYWdOYW1lKGJ8fCIqIik6InVuZGVmaW5lZCIhPXR5cGVvZiBhLnF1ZXJ5U2VsZWN0b3JBbGw/YS5xdWVyeVNlbGVjdG9yQWxsKGJ8fCIqIik6W107cmV0dXJuIHZvaWQgMD09PWJ8fGImJnIubm9kZU5hbWUoYSxiKT9yLm1lcmdlKFthXSxjKTpjfWZ1bmN0aW9uIG1hKGEsYil7Zm9yKHZhciBjPTAsZD1hLmxlbmd0aDtjPGQ7YysrKVYuc2V0KGFbY10sImdsb2JhbEV2YWwiLCFifHxWLmdldChiW2NdLCJnbG9iYWxFdmFsIikpfXZhciBuYT0vPHwmIz9cdys7LztmdW5jdGlvbiBvYShhLGIsYyxkLGUpe2Zvcih2YXIgZixnLGgsaSxqLGssbD1iLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSxtPVtdLG49MCxvPWEubGVuZ3RoO248bztuKyspaWYoZj1hW25dLGZ8fDA9PT1mKWlmKCJvYmplY3QiPT09ci50eXBlKGYpKXIubWVyZ2UobSxmLm5vZGVUeXBlP1tmXTpmKTtlbHNlIGlmKG5hLnRlc3QoZikpe2c9Z3x8bC5hcHBlbmRDaGlsZChiLmNyZWF0ZUVsZW1lbnQoImRpdiIpKSxoPShpYS5leGVjKGYpfHxbIiIsIiJdKVsxXS50b0xvd2VyQ2FzZSgpLGk9a2FbaF18fGthLl9kZWZhdWx0LGcuaW5uZXJIVE1MPWlbMV0rci5odG1sUHJlZmlsdGVyKGYpK2lbMl0saz1pWzBdO3doaWxlKGstLSlnPWcubGFzdENoaWxkO3IubWVyZ2UobSxnLmNoaWxkTm9kZXMpLGc9bC5maXJzdENoaWxkLGcudGV4dENvbnRlbnQ9IiJ9ZWxzZSBtLnB1c2goYi5jcmVhdGVUZXh0Tm9kZShmKSk7bC50ZXh0Q29udGVudD0iIixuPTA7d2hpbGUoZj1tW24rK10paWYoZCYmci5pbkFycmF5KGYsZCk+LTEpZSYmZS5wdXNoKGYpO2Vsc2UgaWYoaj1yLmNvbnRhaW5zKGYub3duZXJEb2N1bWVudCxmKSxnPWxhKGwuYXBwZW5kQ2hpbGQoZiksInNjcmlwdCIpLGomJm1hKGcpLGMpe2s9MDt3aGlsZShmPWdbaysrXSlqYS50ZXN0KGYudHlwZXx8IiIpJiZjLnB1c2goZil9cmV0dXJuIGx9IWZ1bmN0aW9uKCl7dmFyIGE9ZC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksYj1hLmFwcGVuZENoaWxkKGQuY3JlYXRlRWxlbWVudCgiZGl2IikpLGM9ZC5jcmVhdGVFbGVtZW50KCJpbnB1dCIpO2Muc2V0QXR0cmlidXRlKCJ0eXBlIiwicmFkaW8iKSxjLnNldEF0dHJpYnV0ZSgiY2hlY2tlZCIsImNoZWNrZWQiKSxjLnNldEF0dHJpYnV0ZSgibmFtZSIsInQiKSxiLmFwcGVuZENoaWxkKGMpLG8uY2hlY2tDbG9uZT1iLmNsb25lTm9kZSghMCkuY2xvbmVOb2RlKCEwKS5sYXN0Q2hpbGQuY2hlY2tlZCxiLmlubmVySFRNTD0iPHRleHRhcmVhPng8L3RleHRhcmVhPiIsby5ub0Nsb25lQ2hlY2tlZD0hIWIuY2xvbmVOb2RlKCEwKS5sYXN0Q2hpbGQuZGVmYXVsdFZhbHVlfSgpO3ZhciBwYT1kLmRvY3VtZW50RWxlbWVudCxxYT0vXmtleS8scmE9L14oPzptb3VzZXxwb2ludGVyfGNvbnRleHRtZW51fGRyYWd8ZHJvcCl8Y2xpY2svLHNhPS9eKFteLl0qKSg/OlwuKC4rKXwpLztmdW5jdGlvbiB0YSgpe3JldHVybiEwfWZ1bmN0aW9uIHVhKCl7cmV0dXJuITF9ZnVuY3Rpb24gdmEoKXt0cnl7cmV0dXJuIGQuYWN0aXZlRWxlbWVudH1jYXRjaChhKXt9fWZ1bmN0aW9uIHdhKGEsYixjLGQsZSxmKXt2YXIgZyxoO2lmKCJvYmplY3QiPT10eXBlb2YgYil7InN0cmluZyIhPXR5cGVvZiBjJiYoZD1kfHxjLGM9dm9pZCAwKTtmb3IoaCBpbiBiKXdhKGEsaCxjLGQsYltoXSxmKTtyZXR1cm4gYX1pZihudWxsPT1kJiZudWxsPT1lPyhlPWMsZD1jPXZvaWQgMCk6bnVsbD09ZSYmKCJzdHJpbmciPT10eXBlb2YgYz8oZT1kLGQ9dm9pZCAwKTooZT1kLGQ9YyxjPXZvaWQgMCkpLGU9PT0hMSllPXVhO2Vsc2UgaWYoIWUpcmV0dXJuIGE7cmV0dXJuIDE9PT1mJiYoZz1lLGU9ZnVuY3Rpb24oYSl7cmV0dXJuIHIoKS5vZmYoYSksZy5hcHBseSh0aGlzLGFyZ3VtZW50cyl9LGUuZ3VpZD1nLmd1aWR8fChnLmd1aWQ9ci5ndWlkKyspKSxhLmVhY2goZnVuY3Rpb24oKXtyLmV2ZW50LmFkZCh0aGlzLGIsZSxkLGMpfSl9ci5ldmVudD17Z2xvYmFsOnt9LGFkZDpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBmLGcsaCxpLGosayxsLG0sbixvLHAscT1WLmdldChhKTtpZihxKXtjLmhhbmRsZXImJihmPWMsYz1mLmhhbmRsZXIsZT1mLnNlbGVjdG9yKSxlJiZyLmZpbmQubWF0Y2hlc1NlbGVjdG9yKHBhLGUpLGMuZ3VpZHx8KGMuZ3VpZD1yLmd1aWQrKyksKGk9cS5ldmVudHMpfHwoaT1xLmV2ZW50cz17fSksKGc9cS5oYW5kbGUpfHwoZz1xLmhhbmRsZT1mdW5jdGlvbihiKXtyZXR1cm4idW5kZWZpbmVkIiE9dHlwZW9mIHImJnIuZXZlbnQudHJpZ2dlcmVkIT09Yi50eXBlP3IuZXZlbnQuZGlzcGF0Y2guYXBwbHkoYSxhcmd1bWVudHMpOnZvaWQgMH0pLGI9KGJ8fCIiKS5tYXRjaChLKXx8WyIiXSxqPWIubGVuZ3RoO3doaWxlKGotLSloPXNhLmV4ZWMoYltqXSl8fFtdLG49cD1oWzFdLG89KGhbMl18fCIiKS5zcGxpdCgiLiIpLnNvcnQoKSxuJiYobD1yLmV2ZW50LnNwZWNpYWxbbl18fHt9LG49KGU/bC5kZWxlZ2F0ZVR5cGU6bC5iaW5kVHlwZSl8fG4sbD1yLmV2ZW50LnNwZWNpYWxbbl18fHt9LGs9ci5leHRlbmQoe3R5cGU6bixvcmlnVHlwZTpwLGRhdGE6ZCxoYW5kbGVyOmMsZ3VpZDpjLmd1aWQsc2VsZWN0b3I6ZSxuZWVkc0NvbnRleHQ6ZSYmci5leHByLm1hdGNoLm5lZWRzQ29udGV4dC50ZXN0KGUpLG5hbWVzcGFjZTpvLmpvaW4oIi4iKX0sZiksKG09aVtuXSl8fChtPWlbbl09W10sbS5kZWxlZ2F0ZUNvdW50PTAsbC5zZXR1cCYmbC5zZXR1cC5jYWxsKGEsZCxvLGcpIT09ITF8fGEuYWRkRXZlbnRMaXN0ZW5lciYmYS5hZGRFdmVudExpc3RlbmVyKG4sZykpLGwuYWRkJiYobC5hZGQuY2FsbChhLGspLGsuaGFuZGxlci5ndWlkfHwoay5oYW5kbGVyLmd1aWQ9Yy5ndWlkKSksZT9tLnNwbGljZShtLmRlbGVnYXRlQ291bnQrKywwLGspOm0ucHVzaChrKSxyLmV2ZW50Lmdsb2JhbFtuXT0hMCl9fSxyZW1vdmU6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgZixnLGgsaSxqLGssbCxtLG4sbyxwLHE9Vi5oYXNEYXRhKGEpJiZWLmdldChhKTtpZihxJiYoaT1xLmV2ZW50cykpe2I9KGJ8fCIiKS5tYXRjaChLKXx8WyIiXSxqPWIubGVuZ3RoO3doaWxlKGotLSlpZihoPXNhLmV4ZWMoYltqXSl8fFtdLG49cD1oWzFdLG89KGhbMl18fCIiKS5zcGxpdCgiLiIpLnNvcnQoKSxuKXtsPXIuZXZlbnQuc3BlY2lhbFtuXXx8e30sbj0oZD9sLmRlbGVnYXRlVHlwZTpsLmJpbmRUeXBlKXx8bixtPWlbbl18fFtdLGg9aFsyXSYmbmV3IFJlZ0V4cCgiKF58XFwuKSIrby5qb2luKCJcXC4oPzouKlxcLnwpIikrIihcXC58JCkiKSxnPWY9bS5sZW5ndGg7d2hpbGUoZi0tKWs9bVtmXSwhZSYmcCE9PWsub3JpZ1R5cGV8fGMmJmMuZ3VpZCE9PWsuZ3VpZHx8aCYmIWgudGVzdChrLm5hbWVzcGFjZSl8fGQmJmQhPT1rLnNlbGVjdG9yJiYoIioqIiE9PWR8fCFrLnNlbGVjdG9yKXx8KG0uc3BsaWNlKGYsMSksay5zZWxlY3RvciYmbS5kZWxlZ2F0ZUNvdW50LS0sbC5yZW1vdmUmJmwucmVtb3ZlLmNhbGwoYSxrKSk7ZyYmIW0ubGVuZ3RoJiYobC50ZWFyZG93biYmbC50ZWFyZG93bi5jYWxsKGEsbyxxLmhhbmRsZSkhPT0hMXx8ci5yZW1vdmVFdmVudChhLG4scS5oYW5kbGUpLGRlbGV0ZSBpW25dKX1lbHNlIGZvcihuIGluIGkpci5ldmVudC5yZW1vdmUoYSxuK2Jbal0sYyxkLCEwKTtyLmlzRW1wdHlPYmplY3QoaSkmJlYucmVtb3ZlKGEsImhhbmRsZSBldmVudHMiKX19LGRpc3BhdGNoOmZ1bmN0aW9uKGEpe3ZhciBiPXIuZXZlbnQuZml4KGEpLGMsZCxlLGYsZyxoLGk9bmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpLGo9KFYuZ2V0KHRoaXMsImV2ZW50cyIpfHx7fSlbYi50eXBlXXx8W10saz1yLmV2ZW50LnNwZWNpYWxbYi50eXBlXXx8e307Zm9yKGlbMF09YixjPTE7Yzxhcmd1bWVudHMubGVuZ3RoO2MrKylpW2NdPWFyZ3VtZW50c1tjXTtpZihiLmRlbGVnYXRlVGFyZ2V0PXRoaXMsIWsucHJlRGlzcGF0Y2h8fGsucHJlRGlzcGF0Y2guY2FsbCh0aGlzLGIpIT09ITEpe2g9ci5ldmVudC5oYW5kbGVycy5jYWxsKHRoaXMsYixqKSxjPTA7d2hpbGUoKGY9aFtjKytdKSYmIWIuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSl7Yi5jdXJyZW50VGFyZ2V0PWYuZWxlbSxkPTA7d2hpbGUoKGc9Zi5oYW5kbGVyc1tkKytdKSYmIWIuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQoKSliLnJuYW1lc3BhY2UmJiFiLnJuYW1lc3BhY2UudGVzdChnLm5hbWVzcGFjZSl8fChiLmhhbmRsZU9iaj1nLGIuZGF0YT1nLmRhdGEsZT0oKHIuZXZlbnQuc3BlY2lhbFtnLm9yaWdUeXBlXXx8e30pLmhhbmRsZXx8Zy5oYW5kbGVyKS5hcHBseShmLmVsZW0saSksdm9pZCAwIT09ZSYmKGIucmVzdWx0PWUpPT09ITEmJihiLnByZXZlbnREZWZhdWx0KCksYi5zdG9wUHJvcGFnYXRpb24oKSkpfXJldHVybiBrLnBvc3REaXNwYXRjaCYmay5wb3N0RGlzcGF0Y2guY2FsbCh0aGlzLGIpLGIucmVzdWx0fX0saGFuZGxlcnM6ZnVuY3Rpb24oYSxiKXt2YXIgYyxkLGUsZixnPVtdLGg9Yi5kZWxlZ2F0ZUNvdW50LGk9YS50YXJnZXQ7aWYoaCYmaS5ub2RlVHlwZSYmKCJjbGljayIhPT1hLnR5cGV8fGlzTmFOKGEuYnV0dG9uKXx8YS5idXR0b248MSkpZm9yKDtpIT09dGhpcztpPWkucGFyZW50Tm9kZXx8dGhpcylpZigxPT09aS5ub2RlVHlwZSYmKGkuZGlzYWJsZWQhPT0hMHx8ImNsaWNrIiE9PWEudHlwZSkpe2ZvcihkPVtdLGM9MDtjPGg7YysrKWY9YltjXSxlPWYuc2VsZWN0b3IrIiAiLHZvaWQgMD09PWRbZV0mJihkW2VdPWYubmVlZHNDb250ZXh0P3IoZSx0aGlzKS5pbmRleChpKT4tMTpyLmZpbmQoZSx0aGlzLG51bGwsW2ldKS5sZW5ndGgpLGRbZV0mJmQucHVzaChmKTtkLmxlbmd0aCYmZy5wdXNoKHtlbGVtOmksaGFuZGxlcnM6ZH0pfXJldHVybiBoPGIubGVuZ3RoJiZnLnB1c2goe2VsZW06dGhpcyxoYW5kbGVyczpiLnNsaWNlKGgpfSksZ30sYWRkUHJvcDpmdW5jdGlvbihhLGIpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShyLkV2ZW50LnByb3RvdHlwZSxhLHtlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCxnZXQ6ci5pc0Z1bmN0aW9uKGIpP2Z1bmN0aW9uKCl7aWYodGhpcy5vcmlnaW5hbEV2ZW50KXJldHVybiBiKHRoaXMub3JpZ2luYWxFdmVudCl9OmZ1bmN0aW9uKCl7aWYodGhpcy5vcmlnaW5hbEV2ZW50KXJldHVybiB0aGlzLm9yaWdpbmFsRXZlbnRbYV19LHNldDpmdW5jdGlvbihiKXtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcyxhLHtlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMCx2YWx1ZTpifSl9fSl9LGZpeDpmdW5jdGlvbihhKXtyZXR1cm4gYVtyLmV4cGFuZG9dP2E6bmV3IHIuRXZlbnQoYSl9LHNwZWNpYWw6e2xvYWQ6e25vQnViYmxlOiEwfSxmb2N1czp7dHJpZ2dlcjpmdW5jdGlvbigpe2lmKHRoaXMhPT12YSgpJiZ0aGlzLmZvY3VzKXJldHVybiB0aGlzLmZvY3VzKCksITF9LGRlbGVnYXRlVHlwZToiZm9jdXNpbiJ9LGJsdXI6e3RyaWdnZXI6ZnVuY3Rpb24oKXtpZih0aGlzPT09dmEoKSYmdGhpcy5ibHVyKXJldHVybiB0aGlzLmJsdXIoKSwhMX0sZGVsZWdhdGVUeXBlOiJmb2N1c291dCJ9LGNsaWNrOnt0cmlnZ2VyOmZ1bmN0aW9uKCl7aWYoImNoZWNrYm94Ij09PXRoaXMudHlwZSYmdGhpcy5jbGljayYmci5ub2RlTmFtZSh0aGlzLCJpbnB1dCIpKXJldHVybiB0aGlzLmNsaWNrKCksITF9LF9kZWZhdWx0OmZ1bmN0aW9uKGEpe3JldHVybiByLm5vZGVOYW1lKGEudGFyZ2V0LCJhIil9fSxiZWZvcmV1bmxvYWQ6e3Bvc3REaXNwYXRjaDpmdW5jdGlvbihhKXt2b2lkIDAhPT1hLnJlc3VsdCYmYS5vcmlnaW5hbEV2ZW50JiYoYS5vcmlnaW5hbEV2ZW50LnJldHVyblZhbHVlPWEucmVzdWx0KX19fX0sci5yZW1vdmVFdmVudD1mdW5jdGlvbihhLGIsYyl7YS5yZW1vdmVFdmVudExpc3RlbmVyJiZhLnJlbW92ZUV2ZW50TGlzdGVuZXIoYixjKX0sci5FdmVudD1mdW5jdGlvbihhLGIpe3JldHVybiB0aGlzIGluc3RhbmNlb2Ygci5FdmVudD8oYSYmYS50eXBlPyh0aGlzLm9yaWdpbmFsRXZlbnQ9YSx0aGlzLnR5cGU9YS50eXBlLHRoaXMuaXNEZWZhdWx0UHJldmVudGVkPWEuZGVmYXVsdFByZXZlbnRlZHx8dm9pZCAwPT09YS5kZWZhdWx0UHJldmVudGVkJiZhLnJldHVyblZhbHVlPT09ITE/dGE6dWEsdGhpcy50YXJnZXQ9YS50YXJnZXQmJjM9PT1hLnRhcmdldC5ub2RlVHlwZT9hLnRhcmdldC5wYXJlbnROb2RlOmEudGFyZ2V0LHRoaXMuY3VycmVudFRhcmdldD1hLmN1cnJlbnRUYXJnZXQsdGhpcy5yZWxhdGVkVGFyZ2V0PWEucmVsYXRlZFRhcmdldCk6dGhpcy50eXBlPWEsYiYmci5leHRlbmQodGhpcyxiKSx0aGlzLnRpbWVTdGFtcD1hJiZhLnRpbWVTdGFtcHx8ci5ub3coKSx2b2lkKHRoaXNbci5leHBhbmRvXT0hMCkpOm5ldyByLkV2ZW50KGEsYil9LHIuRXZlbnQucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpyLkV2ZW50LGlzRGVmYXVsdFByZXZlbnRlZDp1YSxpc1Byb3BhZ2F0aW9uU3RvcHBlZDp1YSxpc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZDp1YSxpc1NpbXVsYXRlZDohMSxwcmV2ZW50RGVmYXVsdDpmdW5jdGlvbigpe3ZhciBhPXRoaXMub3JpZ2luYWxFdmVudDt0aGlzLmlzRGVmYXVsdFByZXZlbnRlZD10YSxhJiYhdGhpcy5pc1NpbXVsYXRlZCYmYS5wcmV2ZW50RGVmYXVsdCgpfSxzdG9wUHJvcGFnYXRpb246ZnVuY3Rpb24oKXt2YXIgYT10aGlzLm9yaWdpbmFsRXZlbnQ7dGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZD10YSxhJiYhdGhpcy5pc1NpbXVsYXRlZCYmYS5zdG9wUHJvcGFnYXRpb24oKX0sc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uOmZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5vcmlnaW5hbEV2ZW50O3RoaXMuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQ9dGEsYSYmIXRoaXMuaXNTaW11bGF0ZWQmJmEuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCksdGhpcy5zdG9wUHJvcGFnYXRpb24oKX19LHIuZWFjaCh7YWx0S2V5OiEwLGJ1YmJsZXM6ITAsY2FuY2VsYWJsZTohMCxjaGFuZ2VkVG91Y2hlczohMCxjdHJsS2V5OiEwLGRldGFpbDohMCxldmVudFBoYXNlOiEwLG1ldGFLZXk6ITAscGFnZVg6ITAscGFnZVk6ITAsc2hpZnRLZXk6ITAsdmlldzohMCwiY2hhciI6ITAsY2hhckNvZGU6ITAsa2V5OiEwLGtleUNvZGU6ITAsYnV0dG9uOiEwLGJ1dHRvbnM6ITAsY2xpZW50WDohMCxjbGllbnRZOiEwLG9mZnNldFg6ITAsb2Zmc2V0WTohMCxwb2ludGVySWQ6ITAscG9pbnRlclR5cGU6ITAsc2NyZWVuWDohMCxzY3JlZW5ZOiEwLHRhcmdldFRvdWNoZXM6ITAsdG9FbGVtZW50OiEwLHRvdWNoZXM6ITAsd2hpY2g6ZnVuY3Rpb24oYSl7dmFyIGI9YS5idXR0b247cmV0dXJuIG51bGw9PWEud2hpY2gmJnFhLnRlc3QoYS50eXBlKT9udWxsIT1hLmNoYXJDb2RlP2EuY2hhckNvZGU6YS5rZXlDb2RlOiFhLndoaWNoJiZ2b2lkIDAhPT1iJiZyYS50ZXN0KGEudHlwZSk/MSZiPzE6MiZiPzM6NCZiPzI6MDphLndoaWNofX0sci5ldmVudC5hZGRQcm9wKSxyLmVhY2goe21vdXNlZW50ZXI6Im1vdXNlb3ZlciIsbW91c2VsZWF2ZToibW91c2VvdXQiLHBvaW50ZXJlbnRlcjoicG9pbnRlcm92ZXIiLHBvaW50ZXJsZWF2ZToicG9pbnRlcm91dCJ9LGZ1bmN0aW9uKGEsYil7ci5ldmVudC5zcGVjaWFsW2FdPXtkZWxlZ2F0ZVR5cGU6YixiaW5kVHlwZTpiLGhhbmRsZTpmdW5jdGlvbihhKXt2YXIgYyxkPXRoaXMsZT1hLnJlbGF0ZWRUYXJnZXQsZj1hLmhhbmRsZU9iajtyZXR1cm4gZSYmKGU9PT1kfHxyLmNvbnRhaW5zKGQsZSkpfHwoYS50eXBlPWYub3JpZ1R5cGUsYz1mLmhhbmRsZXIuYXBwbHkodGhpcyxhcmd1bWVudHMpLGEudHlwZT1iKSxjfX19KSxyLmZuLmV4dGVuZCh7b246ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIHdhKHRoaXMsYSxiLGMsZCl9LG9uZTpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gd2EodGhpcyxhLGIsYyxkLDEpfSxvZmY6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkLGU7aWYoYSYmYS5wcmV2ZW50RGVmYXVsdCYmYS5oYW5kbGVPYmopcmV0dXJuIGQ9YS5oYW5kbGVPYmoscihhLmRlbGVnYXRlVGFyZ2V0KS5vZmYoZC5uYW1lc3BhY2U/ZC5vcmlnVHlwZSsiLiIrZC5uYW1lc3BhY2U6ZC5vcmlnVHlwZSxkLnNlbGVjdG9yLGQuaGFuZGxlciksdGhpcztpZigib2JqZWN0Ij09dHlwZW9mIGEpe2ZvcihlIGluIGEpdGhpcy5vZmYoZSxiLGFbZV0pO3JldHVybiB0aGlzfXJldHVybiBiIT09ITEmJiJmdW5jdGlvbiIhPXR5cGVvZiBifHwoYz1iLGI9dm9pZCAwKSxjPT09ITEmJihjPXVhKSx0aGlzLmVhY2goZnVuY3Rpb24oKXtyLmV2ZW50LnJlbW92ZSh0aGlzLGEsYyxiKX0pfX0pO3ZhciB4YT0vPCg/IWFyZWF8YnJ8Y29sfGVtYmVkfGhyfGltZ3xpbnB1dHxsaW5rfG1ldGF8cGFyYW0pKChbYS16XVteXC9cMD5ceDIwXHRcclxuXGZdKilbXj5dKilcLz4vZ2kseWE9LzxzY3JpcHR8PHN0eWxlfDxsaW5rL2ksemE9L2NoZWNrZWRccyooPzpbXj1dfD1ccyouY2hlY2tlZC4pL2ksQWE9L150cnVlXC8oLiopLyxCYT0vXlxzKjwhKD86XFtDREFUQVxbfC0tKXwoPzpcXVxdfC0tKT5ccyokL2c7ZnVuY3Rpb24gQ2EoYSxiKXtyZXR1cm4gci5ub2RlTmFtZShhLCJ0YWJsZSIpJiZyLm5vZGVOYW1lKDExIT09Yi5ub2RlVHlwZT9iOmIuZmlyc3RDaGlsZCwidHIiKT9hLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJ0Ym9keSIpWzBdfHxhOmF9ZnVuY3Rpb24gRGEoYSl7cmV0dXJuIGEudHlwZT0obnVsbCE9PWEuZ2V0QXR0cmlidXRlKCJ0eXBlIikpKyIvIithLnR5cGUsYX1mdW5jdGlvbiBFYShhKXt2YXIgYj1BYS5leGVjKGEudHlwZSk7cmV0dXJuIGI/YS50eXBlPWJbMV06YS5yZW1vdmVBdHRyaWJ1dGUoInR5cGUiKSxhfWZ1bmN0aW9uIEZhKGEsYil7dmFyIGMsZCxlLGYsZyxoLGksajtpZigxPT09Yi5ub2RlVHlwZSl7aWYoVi5oYXNEYXRhKGEpJiYoZj1WLmFjY2VzcyhhKSxnPVYuc2V0KGIsZiksaj1mLmV2ZW50cykpe2RlbGV0ZSBnLmhhbmRsZSxnLmV2ZW50cz17fTtmb3IoZSBpbiBqKWZvcihjPTAsZD1qW2VdLmxlbmd0aDtjPGQ7YysrKXIuZXZlbnQuYWRkKGIsZSxqW2VdW2NdKX1XLmhhc0RhdGEoYSkmJihoPVcuYWNjZXNzKGEpLGk9ci5leHRlbmQoe30saCksVy5zZXQoYixpKSl9fWZ1bmN0aW9uIEdhKGEsYil7dmFyIGM9Yi5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpOyJpbnB1dCI9PT1jJiZoYS50ZXN0KGEudHlwZSk/Yi5jaGVja2VkPWEuY2hlY2tlZDoiaW5wdXQiIT09YyYmInRleHRhcmVhIiE9PWN8fChiLmRlZmF1bHRWYWx1ZT1hLmRlZmF1bHRWYWx1ZSl9ZnVuY3Rpb24gSGEoYSxiLGMsZCl7Yj1nLmFwcGx5KFtdLGIpO3ZhciBlLGYsaCxpLGosayxsPTAsbT1hLmxlbmd0aCxuPW0tMSxxPWJbMF0scz1yLmlzRnVuY3Rpb24ocSk7aWYoc3x8bT4xJiYic3RyaW5nIj09dHlwZW9mIHEmJiFvLmNoZWNrQ2xvbmUmJnphLnRlc3QocSkpcmV0dXJuIGEuZWFjaChmdW5jdGlvbihlKXt2YXIgZj1hLmVxKGUpO3MmJihiWzBdPXEuY2FsbCh0aGlzLGUsZi5odG1sKCkpKSxIYShmLGIsYyxkKX0pO2lmKG0mJihlPW9hKGIsYVswXS5vd25lckRvY3VtZW50LCExLGEsZCksZj1lLmZpcnN0Q2hpbGQsMT09PWUuY2hpbGROb2Rlcy5sZW5ndGgmJihlPWYpLGZ8fGQpKXtmb3IoaD1yLm1hcChsYShlLCJzY3JpcHQiKSxEYSksaT1oLmxlbmd0aDtsPG07bCsrKWo9ZSxsIT09biYmKGo9ci5jbG9uZShqLCEwLCEwKSxpJiZyLm1lcmdlKGgsbGEoaiwic2NyaXB0IikpKSxjLmNhbGwoYVtsXSxqLGwpO2lmKGkpZm9yKGs9aFtoLmxlbmd0aC0xXS5vd25lckRvY3VtZW50LHIubWFwKGgsRWEpLGw9MDtsPGk7bCsrKWo9aFtsXSxqYS50ZXN0KGoudHlwZXx8IiIpJiYhVi5hY2Nlc3MoaiwiZ2xvYmFsRXZhbCIpJiZyLmNvbnRhaW5zKGssaikmJihqLnNyYz9yLl9ldmFsVXJsJiZyLl9ldmFsVXJsKGouc3JjKTpwKGoudGV4dENvbnRlbnQucmVwbGFjZShCYSwiIiksaykpfXJldHVybiBhfWZ1bmN0aW9uIElhKGEsYixjKXtmb3IodmFyIGQsZT1iP3IuZmlsdGVyKGIsYSk6YSxmPTA7bnVsbCE9KGQ9ZVtmXSk7ZisrKWN8fDEhPT1kLm5vZGVUeXBlfHxyLmNsZWFuRGF0YShsYShkKSksZC5wYXJlbnROb2RlJiYoYyYmci5jb250YWlucyhkLm93bmVyRG9jdW1lbnQsZCkmJm1hKGxhKGQsInNjcmlwdCIpKSxkLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZCkpO3JldHVybiBhfXIuZXh0ZW5kKHtodG1sUHJlZmlsdGVyOmZ1bmN0aW9uKGEpe3JldHVybiBhLnJlcGxhY2UoeGEsIjwkMT48LyQyPiIpfSxjbG9uZTpmdW5jdGlvbihhLGIsYyl7dmFyIGQsZSxmLGcsaD1hLmNsb25lTm9kZSghMCksaT1yLmNvbnRhaW5zKGEub3duZXJEb2N1bWVudCxhKTtpZighKG8ubm9DbG9uZUNoZWNrZWR8fDEhPT1hLm5vZGVUeXBlJiYxMSE9PWEubm9kZVR5cGV8fHIuaXNYTUxEb2MoYSkpKWZvcihnPWxhKGgpLGY9bGEoYSksZD0wLGU9Zi5sZW5ndGg7ZDxlO2QrKylHYShmW2RdLGdbZF0pO2lmKGIpaWYoYylmb3IoZj1mfHxsYShhKSxnPWd8fGxhKGgpLGQ9MCxlPWYubGVuZ3RoO2Q8ZTtkKyspRmEoZltkXSxnW2RdKTtlbHNlIEZhKGEsaCk7cmV0dXJuIGc9bGEoaCwic2NyaXB0IiksZy5sZW5ndGg+MCYmbWEoZywhaSYmbGEoYSwic2NyaXB0IikpLGh9LGNsZWFuRGF0YTpmdW5jdGlvbihhKXtmb3IodmFyIGIsYyxkLGU9ci5ldmVudC5zcGVjaWFsLGY9MDt2b2lkIDAhPT0oYz1hW2ZdKTtmKyspaWYoVChjKSl7aWYoYj1jW1YuZXhwYW5kb10pe2lmKGIuZXZlbnRzKWZvcihkIGluIGIuZXZlbnRzKWVbZF0/ci5ldmVudC5yZW1vdmUoYyxkKTpyLnJlbW92ZUV2ZW50KGMsZCxiLmhhbmRsZSk7Y1tWLmV4cGFuZG9dPXZvaWQgMH1jW1cuZXhwYW5kb10mJihjW1cuZXhwYW5kb109dm9pZCAwKX19fSksci5mbi5leHRlbmQoe2RldGFjaDpmdW5jdGlvbihhKXtyZXR1cm4gSWEodGhpcyxhLCEwKX0scmVtb3ZlOmZ1bmN0aW9uKGEpe3JldHVybiBJYSh0aGlzLGEpfSx0ZXh0OmZ1bmN0aW9uKGEpe3JldHVybiBTKHRoaXMsZnVuY3Rpb24oYSl7cmV0dXJuIHZvaWQgMD09PWE/ci50ZXh0KHRoaXMpOnRoaXMuZW1wdHkoKS5lYWNoKGZ1bmN0aW9uKCl7MSE9PXRoaXMubm9kZVR5cGUmJjExIT09dGhpcy5ub2RlVHlwZSYmOSE9PXRoaXMubm9kZVR5cGV8fCh0aGlzLnRleHRDb250ZW50PWEpfSl9LG51bGwsYSxhcmd1bWVudHMubGVuZ3RoKX0sYXBwZW5kOmZ1bmN0aW9uKCl7cmV0dXJuIEhhKHRoaXMsYXJndW1lbnRzLGZ1bmN0aW9uKGEpe2lmKDE9PT10aGlzLm5vZGVUeXBlfHwxMT09PXRoaXMubm9kZVR5cGV8fDk9PT10aGlzLm5vZGVUeXBlKXt2YXIgYj1DYSh0aGlzLGEpO2IuYXBwZW5kQ2hpbGQoYSl9fSl9LHByZXBlbmQ6ZnVuY3Rpb24oKXtyZXR1cm4gSGEodGhpcyxhcmd1bWVudHMsZnVuY3Rpb24oYSl7aWYoMT09PXRoaXMubm9kZVR5cGV8fDExPT09dGhpcy5ub2RlVHlwZXx8OT09PXRoaXMubm9kZVR5cGUpe3ZhciBiPUNhKHRoaXMsYSk7Yi5pbnNlcnRCZWZvcmUoYSxiLmZpcnN0Q2hpbGQpfX0pfSxiZWZvcmU6ZnVuY3Rpb24oKXtyZXR1cm4gSGEodGhpcyxhcmd1bWVudHMsZnVuY3Rpb24oYSl7dGhpcy5wYXJlbnROb2RlJiZ0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGEsdGhpcyl9KX0sYWZ0ZXI6ZnVuY3Rpb24oKXtyZXR1cm4gSGEodGhpcyxhcmd1bWVudHMsZnVuY3Rpb24oYSl7dGhpcy5wYXJlbnROb2RlJiZ0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGEsdGhpcy5uZXh0U2libGluZyl9KX0sZW1wdHk6ZnVuY3Rpb24oKXtmb3IodmFyIGEsYj0wO251bGwhPShhPXRoaXNbYl0pO2IrKykxPT09YS5ub2RlVHlwZSYmKHIuY2xlYW5EYXRhKGxhKGEsITEpKSxhLnRleHRDb250ZW50PSIiKTtyZXR1cm4gdGhpc30sY2xvbmU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT1udWxsIT1hJiZhLGI9bnVsbD09Yj9hOmIsdGhpcy5tYXAoZnVuY3Rpb24oKXtyZXR1cm4gci5jbG9uZSh0aGlzLGEsYil9KX0saHRtbDpmdW5jdGlvbihhKXtyZXR1cm4gUyh0aGlzLGZ1bmN0aW9uKGEpe3ZhciBiPXRoaXNbMF18fHt9LGM9MCxkPXRoaXMubGVuZ3RoO2lmKHZvaWQgMD09PWEmJjE9PT1iLm5vZGVUeXBlKXJldHVybiBiLmlubmVySFRNTDtpZigic3RyaW5nIj09dHlwZW9mIGEmJiF5YS50ZXN0KGEpJiYha2FbKGlhLmV4ZWMoYSl8fFsiIiwiIl0pWzFdLnRvTG93ZXJDYXNlKCldKXthPXIuaHRtbFByZWZpbHRlcihhKTt0cnl7Zm9yKDtjPGQ7YysrKWI9dGhpc1tjXXx8e30sMT09PWIubm9kZVR5cGUmJihyLmNsZWFuRGF0YShsYShiLCExKSksYi5pbm5lckhUTUw9YSk7Yj0wfWNhdGNoKGUpe319YiYmdGhpcy5lbXB0eSgpLmFwcGVuZChhKX0sbnVsbCxhLGFyZ3VtZW50cy5sZW5ndGgpfSxyZXBsYWNlV2l0aDpmdW5jdGlvbigpe3ZhciBhPVtdO3JldHVybiBIYSh0aGlzLGFyZ3VtZW50cyxmdW5jdGlvbihiKXt2YXIgYz10aGlzLnBhcmVudE5vZGU7ci5pbkFycmF5KHRoaXMsYSk8MCYmKHIuY2xlYW5EYXRhKGxhKHRoaXMpKSxjJiZjLnJlcGxhY2VDaGlsZChiLHRoaXMpKX0sYSl9fSksci5lYWNoKHthcHBlbmRUbzoiYXBwZW5kIixwcmVwZW5kVG86InByZXBlbmQiLGluc2VydEJlZm9yZToiYmVmb3JlIixpbnNlcnRBZnRlcjoiYWZ0ZXIiLHJlcGxhY2VBbGw6InJlcGxhY2VXaXRoIn0sZnVuY3Rpb24oYSxiKXtyLmZuW2FdPWZ1bmN0aW9uKGEpe2Zvcih2YXIgYyxkPVtdLGU9cihhKSxmPWUubGVuZ3RoLTEsZz0wO2c8PWY7ZysrKWM9Zz09PWY/dGhpczp0aGlzLmNsb25lKCEwKSxyKGVbZ10pW2JdKGMpLGguYXBwbHkoZCxjLmdldCgpKTtyZXR1cm4gdGhpcy5wdXNoU3RhY2soZCl9fSk7dmFyIEphPS9ebWFyZ2luLyxLYT1uZXcgUmVnRXhwKCJeKCIrJCsiKSg/IXB4KVthLXolXSskIiwiaSIpLExhPWZ1bmN0aW9uKGIpe3ZhciBjPWIub3duZXJEb2N1bWVudC5kZWZhdWx0VmlldztyZXR1cm4gYyYmYy5vcGVuZXJ8fChjPWEpLGMuZ2V0Q29tcHV0ZWRTdHlsZShiKX07IWZ1bmN0aW9uKCl7ZnVuY3Rpb24gYigpe2lmKGkpe2kuc3R5bGUuY3NzVGV4dD0iYm94LXNpemluZzpib3JkZXItYm94O3Bvc2l0aW9uOnJlbGF0aXZlO2Rpc3BsYXk6YmxvY2s7bWFyZ2luOmF1dG87Ym9yZGVyOjFweDtwYWRkaW5nOjFweDt0b3A6MSU7d2lkdGg6NTAlIixpLmlubmVySFRNTD0iIixwYS5hcHBlbmRDaGlsZChoKTt2YXIgYj1hLmdldENvbXB1dGVkU3R5bGUoaSk7Yz0iMSUiIT09Yi50b3AsZz0iMnB4Ij09PWIubWFyZ2luTGVmdCxlPSI0cHgiPT09Yi53aWR0aCxpLnN0eWxlLm1hcmdpblJpZ2h0PSI1MCUiLGY9IjRweCI9PT1iLm1hcmdpblJpZ2h0LHBhLnJlbW92ZUNoaWxkKGgpLGk9bnVsbH19dmFyIGMsZSxmLGcsaD1kLmNyZWF0ZUVsZW1lbnQoImRpdiIpLGk9ZC5jcmVhdGVFbGVtZW50KCJkaXYiKTtpLnN0eWxlJiYoaS5zdHlsZS5iYWNrZ3JvdW5kQ2xpcD0iY29udGVudC1ib3giLGkuY2xvbmVOb2RlKCEwKS5zdHlsZS5iYWNrZ3JvdW5kQ2xpcD0iIixvLmNsZWFyQ2xvbmVTdHlsZT0iY29udGVudC1ib3giPT09aS5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCxoLnN0eWxlLmNzc1RleHQ9ImJvcmRlcjowO3dpZHRoOjhweDtoZWlnaHQ6MDt0b3A6MDtsZWZ0Oi05OTk5cHg7cGFkZGluZzowO21hcmdpbi10b3A6MXB4O3Bvc2l0aW9uOmFic29sdXRlIixoLmFwcGVuZENoaWxkKGkpLHIuZXh0ZW5kKG8se3BpeGVsUG9zaXRpb246ZnVuY3Rpb24oKXtyZXR1cm4gYigpLGN9LGJveFNpemluZ1JlbGlhYmxlOmZ1bmN0aW9uKCl7cmV0dXJuIGIoKSxlfSxwaXhlbE1hcmdpblJpZ2h0OmZ1bmN0aW9uKCl7cmV0dXJuIGIoKSxmfSxyZWxpYWJsZU1hcmdpbkxlZnQ6ZnVuY3Rpb24oKXtyZXR1cm4gYigpLGd9fSkpfSgpO2Z1bmN0aW9uIE1hKGEsYixjKXt2YXIgZCxlLGYsZyxoPWEuc3R5bGU7cmV0dXJuIGM9Y3x8TGEoYSksYyYmKGc9Yy5nZXRQcm9wZXJ0eVZhbHVlKGIpfHxjW2JdLCIiIT09Z3x8ci5jb250YWlucyhhLm93bmVyRG9jdW1lbnQsYSl8fChnPXIuc3R5bGUoYSxiKSksIW8ucGl4ZWxNYXJnaW5SaWdodCgpJiZLYS50ZXN0KGcpJiZKYS50ZXN0KGIpJiYoZD1oLndpZHRoLGU9aC5taW5XaWR0aCxmPWgubWF4V2lkdGgsaC5taW5XaWR0aD1oLm1heFdpZHRoPWgud2lkdGg9ZyxnPWMud2lkdGgsaC53aWR0aD1kLGgubWluV2lkdGg9ZSxoLm1heFdpZHRoPWYpKSx2b2lkIDAhPT1nP2crIiI6Z31mdW5jdGlvbiBOYShhLGIpe3JldHVybntnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gYSgpP3ZvaWQgZGVsZXRlIHRoaXMuZ2V0Oih0aGlzLmdldD1iKS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fX12YXIgT2E9L14obm9uZXx0YWJsZSg/IS1jW2VhXSkuKykvLFBhPXtwb3NpdGlvbjoiYWJzb2x1dGUiLHZpc2liaWxpdHk6ImhpZGRlbiIsZGlzcGxheToiYmxvY2sifSxRYT17bGV0dGVyU3BhY2luZzoiMCIsZm9udFdlaWdodDoiNDAwIn0sUmE9WyJXZWJraXQiLCJNb3oiLCJtcyJdLFNhPWQuY3JlYXRlRWxlbWVudCgiZGl2Iikuc3R5bGU7ZnVuY3Rpb24gVGEoYSl7aWYoYSBpbiBTYSlyZXR1cm4gYTt2YXIgYj1hWzBdLnRvVXBwZXJDYXNlKCkrYS5zbGljZSgxKSxjPVJhLmxlbmd0aDt3aGlsZShjLS0paWYoYT1SYVtjXStiLGEgaW4gU2EpcmV0dXJuIGF9ZnVuY3Rpb24gVWEoYSxiLGMpe3ZhciBkPV8uZXhlYyhiKTtyZXR1cm4gZD9NYXRoLm1heCgwLGRbMl0tKGN8fDApKSsoZFszXXx8InB4Iik6Yn1mdW5jdGlvbiBWYShhLGIsYyxkLGUpe2Zvcih2YXIgZj1jPT09KGQ/ImJvcmRlciI6ImNvbnRlbnQiKT80OiJ3aWR0aCI9PT1iPzE6MCxnPTA7Zjw0O2YrPTIpIm1hcmdpbiI9PT1jJiYoZys9ci5jc3MoYSxjK2FhW2ZdLCEwLGUpKSxkPygiY29udGVudCI9PT1jJiYoZy09ci5jc3MoYSwicGFkZGluZyIrYWFbZl0sITAsZSkpLCJtYXJnaW4iIT09YyYmKGctPXIuY3NzKGEsImJvcmRlciIrYWFbZl0rIldpZHRoIiwhMCxlKSkpOihnKz1yLmNzcyhhLCJwYWRkaW5nIithYVtmXSwhMCxlKSwicGFkZGluZyIhPT1jJiYoZys9ci5jc3MoYSwiYm9yZGVyIithYVtmXSsiV2lkdGgiLCEwLGUpKSk7cmV0dXJuIGd9ZnVuY3Rpb24gV2EoYSxiLGMpe3ZhciBkLGU9ITAsZj1MYShhKSxnPSJib3JkZXItYm94Ij09PXIuY3NzKGEsImJveFNpemluZyIsITEsZik7aWYoYS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCYmKGQ9YS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVtiXSksZDw9MHx8bnVsbD09ZCl7aWYoZD1NYShhLGIsZiksKGQ8MHx8bnVsbD09ZCkmJihkPWEuc3R5bGVbYl0pLEthLnRlc3QoZCkpcmV0dXJuIGQ7ZT1nJiYoby5ib3hTaXppbmdSZWxpYWJsZSgpfHxkPT09YS5zdHlsZVtiXSksZD1wYXJzZUZsb2F0KGQpfHwwfXJldHVybiBkK1ZhKGEsYixjfHwoZz8iYm9yZGVyIjoiY29udGVudCIpLGUsZikrInB4In1yLmV4dGVuZCh7Y3NzSG9va3M6e29wYWNpdHk6e2dldDpmdW5jdGlvbihhLGIpe2lmKGIpe3ZhciBjPU1hKGEsIm9wYWNpdHkiKTtyZXR1cm4iIj09PWM/IjEiOmN9fX19LGNzc051bWJlcjp7YW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6ITAsY29sdW1uQ291bnQ6ITAsZmlsbE9wYWNpdHk6ITAsZmxleEdyb3c6ITAsZmxleFNocmluazohMCxmb250V2VpZ2h0OiEwLGxpbmVIZWlnaHQ6ITAsb3BhY2l0eTohMCxvcmRlcjohMCxvcnBoYW5zOiEwLHdpZG93czohMCx6SW5kZXg6ITAsem9vbTohMH0sY3NzUHJvcHM6eyJmbG9hdCI6ImNzc0Zsb2F0In0sc3R5bGU6ZnVuY3Rpb24oYSxiLGMsZCl7aWYoYSYmMyE9PWEubm9kZVR5cGUmJjghPT1hLm5vZGVUeXBlJiZhLnN0eWxlKXt2YXIgZSxmLGcsaD1yLmNhbWVsQ2FzZShiKSxpPWEuc3R5bGU7cmV0dXJuIGI9ci5jc3NQcm9wc1toXXx8KHIuY3NzUHJvcHNbaF09VGEoaCl8fGgpLGc9ci5jc3NIb29rc1tiXXx8ci5jc3NIb29rc1toXSx2b2lkIDA9PT1jP2cmJiJnZXQiaW4gZyYmdm9pZCAwIT09KGU9Zy5nZXQoYSwhMSxkKSk/ZTppW2JdOihmPXR5cGVvZiBjLCJzdHJpbmciPT09ZiYmKGU9Xy5leGVjKGMpKSYmZVsxXSYmKGM9ZGEoYSxiLGUpLGY9Im51bWJlciIpLG51bGwhPWMmJmM9PT1jJiYoIm51bWJlciI9PT1mJiYoYys9ZSYmZVszXXx8KHIuY3NzTnVtYmVyW2hdPyIiOiJweCIpKSxvLmNsZWFyQ2xvbmVTdHlsZXx8IiIhPT1jfHwwIT09Yi5pbmRleE9mKCJiYWNrZ3JvdW5kIil8fChpW2JdPSJpbmhlcml0IiksZyYmInNldCJpbiBnJiZ2b2lkIDA9PT0oYz1nLnNldChhLGMsZCkpfHwoaVtiXT1jKSksdm9pZCAwKX19LGNzczpmdW5jdGlvbihhLGIsYyxkKXt2YXIgZSxmLGcsaD1yLmNhbWVsQ2FzZShiKTtyZXR1cm4gYj1yLmNzc1Byb3BzW2hdfHwoci5jc3NQcm9wc1toXT1UYShoKXx8aCksZz1yLmNzc0hvb2tzW2JdfHxyLmNzc0hvb2tzW2hdLGcmJiJnZXQiaW4gZyYmKGU9Zy5nZXQoYSwhMCxjKSksdm9pZCAwPT09ZSYmKGU9TWEoYSxiLGQpKSwibm9ybWFsIj09PWUmJmIgaW4gUWEmJihlPVFhW2JdKSwiIj09PWN8fGM/KGY9cGFyc2VGbG9hdChlKSxjPT09ITB8fGlzRmluaXRlKGYpP2Z8fDA6ZSk6ZX19KSxyLmVhY2goWyJoZWlnaHQiLCJ3aWR0aCJdLGZ1bmN0aW9uKGEsYil7ci5jc3NIb29rc1tiXT17Z2V0OmZ1bmN0aW9uKGEsYyxkKXtpZihjKXJldHVybiFPYS50ZXN0KHIuY3NzKGEsImRpc3BsYXkiKSl8fGEuZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGgmJmEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGg/V2EoYSxiLGQpOmNhKGEsUGEsZnVuY3Rpb24oKXtyZXR1cm4gV2EoYSxiLGQpfSl9LHNldDpmdW5jdGlvbihhLGMsZCl7dmFyIGUsZj1kJiZMYShhKSxnPWQmJlZhKGEsYixkLCJib3JkZXItYm94Ij09PXIuY3NzKGEsImJveFNpemluZyIsITEsZiksZik7cmV0dXJuIGcmJihlPV8uZXhlYyhjKSkmJiJweCIhPT0oZVszXXx8InB4IikmJihhLnN0eWxlW2JdPWMsYz1yLmNzcyhhLGIpKSxVYShhLGMsZyl9fX0pLHIuY3NzSG9va3MubWFyZ2luTGVmdD1OYShvLnJlbGlhYmxlTWFyZ2luTGVmdCxmdW5jdGlvbihhLGIpe2lmKGIpcmV0dXJuKHBhcnNlRmxvYXQoTWEoYSwibWFyZ2luTGVmdCIpKXx8YS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0LWNhKGEse21hcmdpbkxlZnQ6MH0sZnVuY3Rpb24oKXtyZXR1cm4gYS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0fSkpKyJweCJ9KSxyLmVhY2goe21hcmdpbjoiIixwYWRkaW5nOiIiLGJvcmRlcjoiV2lkdGgifSxmdW5jdGlvbihhLGIpe3IuY3NzSG9va3NbYStiXT17ZXhwYW5kOmZ1bmN0aW9uKGMpe2Zvcih2YXIgZD0wLGU9e30sZj0ic3RyaW5nIj09dHlwZW9mIGM/Yy5zcGxpdCgiICIpOltjXTtkPDQ7ZCsrKWVbYSthYVtkXStiXT1mW2RdfHxmW2QtMl18fGZbMF07cmV0dXJuIGV9fSxKYS50ZXN0KGEpfHwoci5jc3NIb29rc1thK2JdLnNldD1VYSl9KSxyLmZuLmV4dGVuZCh7Y3NzOmZ1bmN0aW9uKGEsYil7cmV0dXJuIFModGhpcyxmdW5jdGlvbihhLGIsYyl7dmFyIGQsZSxmPXt9LGc9MDtpZihyLmlzQXJyYXkoYikpe2ZvcihkPUxhKGEpLGU9Yi5sZW5ndGg7ZzxlO2crKylmW2JbZ11dPXIuY3NzKGEsYltnXSwhMSxkKTtyZXR1cm4gZn1yZXR1cm4gdm9pZCAwIT09Yz9yLnN0eWxlKGEsYixjKTpyLmNzcyhhLGIpfSxhLGIsYXJndW1lbnRzLmxlbmd0aD4xKX19KTtmdW5jdGlvbiBYYShhLGIsYyxkLGUpe3JldHVybiBuZXcgWGEucHJvdG90eXBlLmluaXQoYSxiLGMsZCxlKX1yLlR3ZWVuPVhhLFhhLnByb3RvdHlwZT17Y29uc3RydWN0b3I6WGEsaW5pdDpmdW5jdGlvbihhLGIsYyxkLGUsZil7dGhpcy5lbGVtPWEsdGhpcy5wcm9wPWMsdGhpcy5lYXNpbmc9ZXx8ci5lYXNpbmcuX2RlZmF1bHQsdGhpcy5vcHRpb25zPWIsdGhpcy5zdGFydD10aGlzLm5vdz10aGlzLmN1cigpLHRoaXMuZW5kPWQsdGhpcy51bml0PWZ8fChyLmNzc051bWJlcltjXT8iIjoicHgiKX0sY3VyOmZ1bmN0aW9uKCl7dmFyIGE9WGEucHJvcEhvb2tzW3RoaXMucHJvcF07cmV0dXJuIGEmJmEuZ2V0P2EuZ2V0KHRoaXMpOlhhLnByb3BIb29rcy5fZGVmYXVsdC5nZXQodGhpcyl9LHJ1bjpmdW5jdGlvbihhKXt2YXIgYixjPVhhLnByb3BIb29rc1t0aGlzLnByb3BdO3JldHVybiB0aGlzLm9wdGlvbnMuZHVyYXRpb24/dGhpcy5wb3M9Yj1yLmVhc2luZ1t0aGlzLmVhc2luZ10oYSx0aGlzLm9wdGlvbnMuZHVyYXRpb24qYSwwLDEsdGhpcy5vcHRpb25zLmR1cmF0aW9uKTp0aGlzLnBvcz1iPWEsdGhpcy5ub3c9KHRoaXMuZW5kLXRoaXMuc3RhcnQpKmIrdGhpcy5zdGFydCx0aGlzLm9wdGlvbnMuc3RlcCYmdGhpcy5vcHRpb25zLnN0ZXAuY2FsbCh0aGlzLmVsZW0sdGhpcy5ub3csdGhpcyksYyYmYy5zZXQ/Yy5zZXQodGhpcyk6WGEucHJvcEhvb2tzLl9kZWZhdWx0LnNldCh0aGlzKSx0aGlzfX0sWGEucHJvdG90eXBlLmluaXQucHJvdG90eXBlPVhhLnByb3RvdHlwZSxYYS5wcm9wSG9va3M9e19kZWZhdWx0OntnZXQ6ZnVuY3Rpb24oYSl7dmFyIGI7cmV0dXJuIDEhPT1hLmVsZW0ubm9kZVR5cGV8fG51bGwhPWEuZWxlbVthLnByb3BdJiZudWxsPT1hLmVsZW0uc3R5bGVbYS5wcm9wXT9hLmVsZW1bYS5wcm9wXTooYj1yLmNzcyhhLmVsZW0sYS5wcm9wLCIiKSxiJiYiYXV0byIhPT1iP2I6MCl9LHNldDpmdW5jdGlvbihhKXtyLmZ4LnN0ZXBbYS5wcm9wXT9yLmZ4LnN0ZXBbYS5wcm9wXShhKToxIT09YS5lbGVtLm5vZGVUeXBlfHxudWxsPT1hLmVsZW0uc3R5bGVbci5jc3NQcm9wc1thLnByb3BdXSYmIXIuY3NzSG9va3NbYS5wcm9wXT9hLmVsZW1bYS5wcm9wXT1hLm5vdzpyLnN0eWxlKGEuZWxlbSxhLnByb3AsYS5ub3crYS51bml0KX19fSxYYS5wcm9wSG9va3Muc2Nyb2xsVG9wPVhhLnByb3BIb29rcy5zY3JvbGxMZWZ0PXtzZXQ6ZnVuY3Rpb24oYSl7YS5lbGVtLm5vZGVUeXBlJiZhLmVsZW0ucGFyZW50Tm9kZSYmKGEuZWxlbVthLnByb3BdPWEubm93KX19LHIuZWFzaW5nPXtsaW5lYXI6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LHN3aW5nOmZ1bmN0aW9uKGEpe3JldHVybi41LU1hdGguY29zKGEqTWF0aC5QSSkvMn0sX2RlZmF1bHQ6InN3aW5nIn0sci5meD1YYS5wcm90b3R5cGUuaW5pdCxyLmZ4LnN0ZXA9e307dmFyIFlhLFphLCRhPS9eKD86dG9nZ2xlfHNob3d8aGlkZSkkLyxfYT0vcXVldWVIb29rcyQvO2Z1bmN0aW9uIGFiKCl7WmEmJihhLnJlcXVlc3RBbmltYXRpb25GcmFtZShhYiksci5meC50aWNrKCkpfWZ1bmN0aW9uIGJiKCl7cmV0dXJuIGEuc2V0VGltZW91dChmdW5jdGlvbigpe1lhPXZvaWQgMH0pLFlhPXIubm93KCl9ZnVuY3Rpb24gY2IoYSxiKXt2YXIgYyxkPTAsZT17aGVpZ2h0OmF9O2ZvcihiPWI/MTowO2Q8NDtkKz0yLWIpYz1hYVtkXSxlWyJtYXJnaW4iK2NdPWVbInBhZGRpbmciK2NdPWE7cmV0dXJuIGImJihlLm9wYWNpdHk9ZS53aWR0aD1hKSxlfWZ1bmN0aW9uIGRiKGEsYixjKXtmb3IodmFyIGQsZT0oZ2IudHdlZW5lcnNbYl18fFtdKS5jb25jYXQoZ2IudHdlZW5lcnNbIioiXSksZj0wLGc9ZS5sZW5ndGg7ZjxnO2YrKylpZihkPWVbZl0uY2FsbChjLGIsYSkpcmV0dXJuIGR9ZnVuY3Rpb24gZWIoYSxiLGMpe3ZhciBkLGUsZixnLGgsaSxqLGssbD0id2lkdGgiaW4gYnx8ImhlaWdodCJpbiBiLG09dGhpcyxuPXt9LG89YS5zdHlsZSxwPWEubm9kZVR5cGUmJmJhKGEpLHE9Vi5nZXQoYSwiZnhzaG93Iik7Yy5xdWV1ZXx8KGc9ci5fcXVldWVIb29rcyhhLCJmeCIpLG51bGw9PWcudW5xdWV1ZWQmJihnLnVucXVldWVkPTAsaD1nLmVtcHR5LmZpcmUsZy5lbXB0eS5maXJlPWZ1bmN0aW9uKCl7Zy51bnF1ZXVlZHx8aCgpfSksZy51bnF1ZXVlZCsrLG0uYWx3YXlzKGZ1bmN0aW9uKCl7bS5hbHdheXMoZnVuY3Rpb24oKXtnLnVucXVldWVkLS0sci5xdWV1ZShhLCJmeCIpLmxlbmd0aHx8Zy5lbXB0eS5maXJlKCl9KX0pKTtmb3IoZCBpbiBiKWlmKGU9YltkXSwkYS50ZXN0KGUpKXtpZihkZWxldGUgYltkXSxmPWZ8fCJ0b2dnbGUiPT09ZSxlPT09KHA/ImhpZGUiOiJzaG93Iikpe2lmKCJzaG93IiE9PWV8fCFxfHx2b2lkIDA9PT1xW2RdKWNvbnRpbnVlO3A9ITB9bltkXT1xJiZxW2RdfHxyLnN0eWxlKGEsZCl9aWYoaT0hci5pc0VtcHR5T2JqZWN0KGIpLGl8fCFyLmlzRW1wdHlPYmplY3Qobikpe2wmJjE9PT1hLm5vZGVUeXBlJiYoYy5vdmVyZmxvdz1bby5vdmVyZmxvdyxvLm92ZXJmbG93WCxvLm92ZXJmbG93WV0saj1xJiZxLmRpc3BsYXksbnVsbD09aiYmKGo9Vi5nZXQoYSwiZGlzcGxheSIpKSxrPXIuY3NzKGEsImRpc3BsYXkiKSwibm9uZSI9PT1rJiYoaj9rPWo6KGdhKFthXSwhMCksaj1hLnN0eWxlLmRpc3BsYXl8fGosaz1yLmNzcyhhLCJkaXNwbGF5IiksZ2EoW2FdKSkpLCgiaW5saW5lIj09PWt8fCJpbmxpbmUtYmxvY2siPT09ayYmbnVsbCE9aikmJiJub25lIj09PXIuY3NzKGEsImZsb2F0IikmJihpfHwobS5kb25lKGZ1bmN0aW9uKCl7by5kaXNwbGF5PWp9KSxudWxsPT1qJiYoaz1vLmRpc3BsYXksaj0ibm9uZSI9PT1rPyIiOmspKSxvLmRpc3BsYXk9ImlubGluZS1ibG9jayIpKSxjLm92ZXJmbG93JiYoby5vdmVyZmxvdz0iaGlkZGVuIixtLmFsd2F5cyhmdW5jdGlvbigpe28ub3ZlcmZsb3c9Yy5vdmVyZmxvd1swXSxvLm92ZXJmbG93WD1jLm92ZXJmbG93WzFdLG8ub3ZlcmZsb3dZPWMub3ZlcmZsb3dbMl19KSksaT0hMTtmb3IoZCBpbiBuKWl8fChxPyJoaWRkZW4iaW4gcSYmKHA9cS5oaWRkZW4pOnE9Vi5hY2Nlc3MoYSwiZnhzaG93Iix7ZGlzcGxheTpqfSksZiYmKHEuaGlkZGVuPSFwKSxwJiZnYShbYV0sITApLG0uZG9uZShmdW5jdGlvbigpe3B8fGdhKFthXSksVi5yZW1vdmUoYSwiZnhzaG93Iik7Zm9yKGQgaW4gbilyLnN0eWxlKGEsZCxuW2RdKX0pKSxpPWRiKHA/cVtkXTowLGQsbSksZCBpbiBxfHwocVtkXT1pLnN0YXJ0LHAmJihpLmVuZD1pLnN0YXJ0LGkuc3RhcnQ9MCkpfX1mdW5jdGlvbiBmYihhLGIpe3ZhciBjLGQsZSxmLGc7Zm9yKGMgaW4gYSlpZihkPXIuY2FtZWxDYXNlKGMpLGU9YltkXSxmPWFbY10sci5pc0FycmF5KGYpJiYoZT1mWzFdLGY9YVtjXT1mWzBdKSxjIT09ZCYmKGFbZF09ZixkZWxldGUgYVtjXSksZz1yLmNzc0hvb2tzW2RdLGcmJiJleHBhbmQiaW4gZyl7Zj1nLmV4cGFuZChmKSxkZWxldGUgYVtkXTtmb3IoYyBpbiBmKWMgaW4gYXx8KGFbY109ZltjXSxiW2NdPWUpfWVsc2UgYltkXT1lfWZ1bmN0aW9uIGdiKGEsYixjKXt2YXIgZCxlLGY9MCxnPWdiLnByZWZpbHRlcnMubGVuZ3RoLGg9ci5EZWZlcnJlZCgpLmFsd2F5cyhmdW5jdGlvbigpe2RlbGV0ZSBpLmVsZW19KSxpPWZ1bmN0aW9uKCl7aWYoZSlyZXR1cm4hMTtmb3IodmFyIGI9WWF8fGJiKCksYz1NYXRoLm1heCgwLGouc3RhcnRUaW1lK2ouZHVyYXRpb24tYiksZD1jL2ouZHVyYXRpb258fDAsZj0xLWQsZz0wLGk9ai50d2VlbnMubGVuZ3RoO2c8aTtnKyspai50d2VlbnNbZ10ucnVuKGYpO3JldHVybiBoLm5vdGlmeVdpdGgoYSxbaixmLGNdKSxmPDEmJmk/YzooaC5yZXNvbHZlV2l0aChhLFtqXSksITEpfSxqPWgucHJvbWlzZSh7ZWxlbTphLHByb3BzOnIuZXh0ZW5kKHt9LGIpLG9wdHM6ci5leHRlbmQoITAse3NwZWNpYWxFYXNpbmc6e30sZWFzaW5nOnIuZWFzaW5nLl9kZWZhdWx0fSxjKSxvcmlnaW5hbFByb3BlcnRpZXM6YixvcmlnaW5hbE9wdGlvbnM6YyxzdGFydFRpbWU6WWF8fGJiKCksZHVyYXRpb246Yy5kdXJhdGlvbix0d2VlbnM6W10sY3JlYXRlVHdlZW46ZnVuY3Rpb24oYixjKXt2YXIgZD1yLlR3ZWVuKGEsai5vcHRzLGIsYyxqLm9wdHMuc3BlY2lhbEVhc2luZ1tiXXx8ai5vcHRzLmVhc2luZyk7cmV0dXJuIGoudHdlZW5zLnB1c2goZCksZH0sc3RvcDpmdW5jdGlvbihiKXt2YXIgYz0wLGQ9Yj9qLnR3ZWVucy5sZW5ndGg6MDtpZihlKXJldHVybiB0aGlzO2ZvcihlPSEwO2M8ZDtjKyspai50d2VlbnNbY10ucnVuKDEpO3JldHVybiBiPyhoLm5vdGlmeVdpdGgoYSxbaiwxLDBdKSxoLnJlc29sdmVXaXRoKGEsW2osYl0pKTpoLnJlamVjdFdpdGgoYSxbaixiXSksdGhpc319KSxrPWoucHJvcHM7Zm9yKGZiKGssai5vcHRzLnNwZWNpYWxFYXNpbmcpO2Y8ZztmKyspaWYoZD1nYi5wcmVmaWx0ZXJzW2ZdLmNhbGwoaixhLGssai5vcHRzKSlyZXR1cm4gci5pc0Z1bmN0aW9uKGQuc3RvcCkmJihyLl9xdWV1ZUhvb2tzKGouZWxlbSxqLm9wdHMucXVldWUpLnN0b3A9ci5wcm94eShkLnN0b3AsZCkpLGQ7cmV0dXJuIHIubWFwKGssZGIsaiksci5pc0Z1bmN0aW9uKGoub3B0cy5zdGFydCkmJmoub3B0cy5zdGFydC5jYWxsKGEsaiksci5meC50aW1lcihyLmV4dGVuZChpLHtlbGVtOmEsYW5pbTpqLHF1ZXVlOmoub3B0cy5xdWV1ZX0pKSxqLnByb2dyZXNzKGoub3B0cy5wcm9ncmVzcykuZG9uZShqLm9wdHMuZG9uZSxqLm9wdHMuY29tcGxldGUpLmZhaWwoai5vcHRzLmZhaWwpLmFsd2F5cyhqLm9wdHMuYWx3YXlzKX1yLkFuaW1hdGlvbj1yLmV4dGVuZChnYix7dHdlZW5lcnM6eyIqIjpbZnVuY3Rpb24oYSxiKXt2YXIgYz10aGlzLmNyZWF0ZVR3ZWVuKGEsYik7cmV0dXJuIGRhKGMuZWxlbSxhLF8uZXhlYyhiKSxjKSxjfV19LHR3ZWVuZXI6ZnVuY3Rpb24oYSxiKXtyLmlzRnVuY3Rpb24oYSk/KGI9YSxhPVsiKiJdKTphPWEubWF0Y2goSyk7Zm9yKHZhciBjLGQ9MCxlPWEubGVuZ3RoO2Q8ZTtkKyspYz1hW2RdLGdiLnR3ZWVuZXJzW2NdPWdiLnR3ZWVuZXJzW2NdfHxbXSxnYi50d2VlbmVyc1tjXS51bnNoaWZ0KGIpfSxwcmVmaWx0ZXJzOltlYl0scHJlZmlsdGVyOmZ1bmN0aW9uKGEsYil7Yj9nYi5wcmVmaWx0ZXJzLnVuc2hpZnQoYSk6Z2IucHJlZmlsdGVycy5wdXNoKGEpfX0pLHIuc3BlZWQ9ZnVuY3Rpb24oYSxiLGMpe3ZhciBlPWEmJiJvYmplY3QiPT10eXBlb2YgYT9yLmV4dGVuZCh7fSxhKTp7Y29tcGxldGU6Y3x8IWMmJmJ8fHIuaXNGdW5jdGlvbihhKSYmYSxkdXJhdGlvbjphLGVhc2luZzpjJiZifHxiJiYhci5pc0Z1bmN0aW9uKGIpJiZifTtyZXR1cm4gci5meC5vZmZ8fGQuaGlkZGVuP2UuZHVyYXRpb249MDplLmR1cmF0aW9uPSJudW1iZXIiPT10eXBlb2YgZS5kdXJhdGlvbj9lLmR1cmF0aW9uOmUuZHVyYXRpb24gaW4gci5meC5zcGVlZHM/ci5meC5zcGVlZHNbZS5kdXJhdGlvbl06ci5meC5zcGVlZHMuX2RlZmF1bHQsbnVsbCE9ZS5xdWV1ZSYmZS5xdWV1ZSE9PSEwfHwoZS5xdWV1ZT0iZngiKSxlLm9sZD1lLmNvbXBsZXRlLGUuY29tcGxldGU9ZnVuY3Rpb24oKXtyLmlzRnVuY3Rpb24oZS5vbGQpJiZlLm9sZC5jYWxsKHRoaXMpLGUucXVldWUmJnIuZGVxdWV1ZSh0aGlzLGUucXVldWUpfSxlfSxyLmZuLmV4dGVuZCh7ZmFkZVRvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiB0aGlzLmZpbHRlcihiYSkuY3NzKCJvcGFjaXR5IiwwKS5zaG93KCkuZW5kKCkuYW5pbWF0ZSh7b3BhY2l0eTpifSxhLGMsZCl9LGFuaW1hdGU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIGU9ci5pc0VtcHR5T2JqZWN0KGEpLGY9ci5zcGVlZChiLGMsZCksZz1mdW5jdGlvbigpe3ZhciBiPWdiKHRoaXMsci5leHRlbmQoe30sYSksZik7KGV8fFYuZ2V0KHRoaXMsImZpbmlzaCIpKSYmYi5zdG9wKCEwKX07cmV0dXJuIGcuZmluaXNoPWcsZXx8Zi5xdWV1ZT09PSExP3RoaXMuZWFjaChnKTp0aGlzLnF1ZXVlKGYucXVldWUsZyl9LHN0b3A6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkPWZ1bmN0aW9uKGEpe3ZhciBiPWEuc3RvcDtkZWxldGUgYS5zdG9wLGIoYyl9O3JldHVybiJzdHJpbmciIT10eXBlb2YgYSYmKGM9YixiPWEsYT12b2lkIDApLGImJmEhPT0hMSYmdGhpcy5xdWV1ZShhfHwiZngiLFtdKSx0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgYj0hMCxlPW51bGwhPWEmJmErInF1ZXVlSG9va3MiLGY9ci50aW1lcnMsZz1WLmdldCh0aGlzKTtpZihlKWdbZV0mJmdbZV0uc3RvcCYmZChnW2VdKTtlbHNlIGZvcihlIGluIGcpZ1tlXSYmZ1tlXS5zdG9wJiZfYS50ZXN0KGUpJiZkKGdbZV0pO2ZvcihlPWYubGVuZ3RoO2UtLTspZltlXS5lbGVtIT09dGhpc3x8bnVsbCE9YSYmZltlXS5xdWV1ZSE9PWF8fChmW2VdLmFuaW0uc3RvcChjKSxiPSExLGYuc3BsaWNlKGUsMSkpOyFiJiZjfHxyLmRlcXVldWUodGhpcyxhKX0pfSxmaW5pc2g6ZnVuY3Rpb24oYSl7cmV0dXJuIGEhPT0hMSYmKGE9YXx8ImZ4IiksdGhpcy5lYWNoKGZ1bmN0aW9uKCl7dmFyIGIsYz1WLmdldCh0aGlzKSxkPWNbYSsicXVldWUiXSxlPWNbYSsicXVldWVIb29rcyJdLGY9ci50aW1lcnMsZz1kP2QubGVuZ3RoOjA7Zm9yKGMuZmluaXNoPSEwLHIucXVldWUodGhpcyxhLFtdKSxlJiZlLnN0b3AmJmUuc3RvcC5jYWxsKHRoaXMsITApLGI9Zi5sZW5ndGg7Yi0tOylmW2JdLmVsZW09PT10aGlzJiZmW2JdLnF1ZXVlPT09YSYmKGZbYl0uYW5pbS5zdG9wKCEwKSxmLnNwbGljZShiLDEpKTtmb3IoYj0wO2I8ZztiKyspZFtiXSYmZFtiXS5maW5pc2gmJmRbYl0uZmluaXNoLmNhbGwodGhpcyk7ZGVsZXRlIGMuZmluaXNofSl9fSksci5lYWNoKFsidG9nZ2xlIiwic2hvdyIsImhpZGUiXSxmdW5jdGlvbihhLGIpe3ZhciBjPXIuZm5bYl07ci5mbltiXT1mdW5jdGlvbihhLGQsZSl7cmV0dXJuIG51bGw9PWF8fCJib29sZWFuIj09dHlwZW9mIGE/Yy5hcHBseSh0aGlzLGFyZ3VtZW50cyk6dGhpcy5hbmltYXRlKGNiKGIsITApLGEsZCxlKX19KSxyLmVhY2goe3NsaWRlRG93bjpjYigic2hvdyIpLHNsaWRlVXA6Y2IoImhpZGUiKSxzbGlkZVRvZ2dsZTpjYigidG9nZ2xlIiksZmFkZUluOntvcGFjaXR5OiJzaG93In0sZmFkZU91dDp7b3BhY2l0eToiaGlkZSJ9LGZhZGVUb2dnbGU6e29wYWNpdHk6InRvZ2dsZSJ9fSxmdW5jdGlvbihhLGIpe3IuZm5bYV09ZnVuY3Rpb24oYSxjLGQpe3JldHVybiB0aGlzLmFuaW1hdGUoYixhLGMsZCl9fSksci50aW1lcnM9W10sci5meC50aWNrPWZ1bmN0aW9uKCl7dmFyIGEsYj0wLGM9ci50aW1lcnM7Zm9yKFlhPXIubm93KCk7YjxjLmxlbmd0aDtiKyspYT1jW2JdLGEoKXx8Y1tiXSE9PWF8fGMuc3BsaWNlKGItLSwxKTtjLmxlbmd0aHx8ci5meC5zdG9wKCksWWE9dm9pZCAwfSxyLmZ4LnRpbWVyPWZ1bmN0aW9uKGEpe3IudGltZXJzLnB1c2goYSksYSgpP3IuZnguc3RhcnQoKTpyLnRpbWVycy5wb3AoKX0sci5meC5pbnRlcnZhbD0xMyxyLmZ4LnN0YXJ0PWZ1bmN0aW9uKCl7WmF8fChaYT1hLnJlcXVlc3RBbmltYXRpb25GcmFtZT9hLnJlcXVlc3RBbmltYXRpb25GcmFtZShhYik6YS5zZXRJbnRlcnZhbChyLmZ4LnRpY2ssci5meC5pbnRlcnZhbCkpfSxyLmZ4LnN0b3A9ZnVuY3Rpb24oKXthLmNhbmNlbEFuaW1hdGlvbkZyYW1lP2EuY2FuY2VsQW5pbWF0aW9uRnJhbWUoWmEpOmEuY2xlYXJJbnRlcnZhbChaYSksWmE9bnVsbH0sci5meC5zcGVlZHM9e3Nsb3c6NjAwLGZhc3Q6MjAwLF9kZWZhdWx0OjQwMH0sci5mbi5kZWxheT1mdW5jdGlvbihiLGMpe3JldHVybiBiPXIuZng/ci5meC5zcGVlZHNbYl18fGI6YixjPWN8fCJmeCIsdGhpcy5xdWV1ZShjLGZ1bmN0aW9uKGMsZCl7dmFyIGU9YS5zZXRUaW1lb3V0KGMsYik7ZC5zdG9wPWZ1bmN0aW9uKCl7YS5jbGVhclRpbWVvdXQoZSl9fSl9LGZ1bmN0aW9uKCl7dmFyIGE9ZC5jcmVhdGVFbGVtZW50KCJpbnB1dCIpLGI9ZC5jcmVhdGVFbGVtZW50KCJzZWxlY3QiKSxjPWIuYXBwZW5kQ2hpbGQoZC5jcmVhdGVFbGVtZW50KCJvcHRpb24iKSk7YS50eXBlPSJjaGVja2JveCIsby5jaGVja09uPSIiIT09YS52YWx1ZSxvLm9wdFNlbGVjdGVkPWMuc2VsZWN0ZWQsYT1kLmNyZWF0ZUVsZW1lbnQoImlucHV0IiksYS52YWx1ZT0idCIsYS50eXBlPSJyYWRpbyIsby5yYWRpb1ZhbHVlPSJ0Ij09PWEudmFsdWV9KCk7dmFyIGhiLGliPXIuZXhwci5hdHRySGFuZGxlO3IuZm4uZXh0ZW5kKHthdHRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIFModGhpcyxyLmF0dHIsYSxiLGFyZ3VtZW50cy5sZW5ndGg+MSl9LHJlbW92ZUF0dHI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe3IucmVtb3ZlQXR0cih0aGlzLGEpfSl9fSksci5leHRlbmQoe2F0dHI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkLGUsZj1hLm5vZGVUeXBlO2lmKDMhPT1mJiY4IT09ZiYmMiE9PWYpcmV0dXJuInVuZGVmaW5lZCI9PXR5cGVvZiBhLmdldEF0dHJpYnV0ZT9yLnByb3AoYSxiLGMpOigxPT09ZiYmci5pc1hNTERvYyhhKXx8KGU9ci5hdHRySG9va3NbYi50b0xvd2VyQ2FzZSgpXXx8KHIuZXhwci5tYXRjaC5ib29sLnRlc3QoYik/aGI6dm9pZCAwKSksdm9pZCAwIT09Yz9udWxsPT09Yz92b2lkIHIucmVtb3ZlQXR0cihhLGIpOmUmJiJzZXQiaW4gZSYmdm9pZCAwIT09KGQ9ZS5zZXQoYSxjLGIpKT9kOihhLnNldEF0dHJpYnV0ZShiLGMrIiIpLGMpOmUmJiJnZXQiaW4gZSYmbnVsbCE9PShkPWUuZ2V0KGEsYikpP2Q6KGQ9ci5maW5kLmF0dHIoYSxiKSxudWxsPT1kP3ZvaWQgMDpkKSl9LGF0dHJIb29rczp7dHlwZTp7c2V0OmZ1bmN0aW9uKGEsYil7aWYoIW8ucmFkaW9WYWx1ZSYmInJhZGlvIj09PWImJnIubm9kZU5hbWUoYSwiaW5wdXQiKSl7dmFyIGM9YS52YWx1ZTtyZXR1cm4gYS5zZXRBdHRyaWJ1dGUoInR5cGUiLGIpLGMmJihhLnZhbHVlPWMpLGJ9fX19LHJlbW92ZUF0dHI6ZnVuY3Rpb24oYSxiKXt2YXIgYyxkPTAsZT1iJiZiLm1hdGNoKEspOwotaWYoZSYmMT09PWEubm9kZVR5cGUpd2hpbGUoYz1lW2QrK10pYS5yZW1vdmVBdHRyaWJ1dGUoYyl9fSksaGI9e3NldDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGI9PT0hMT9yLnJlbW92ZUF0dHIoYSxjKTphLnNldEF0dHJpYnV0ZShjLGMpLGN9fSxyLmVhY2goci5leHByLm1hdGNoLmJvb2wuc291cmNlLm1hdGNoKC9cdysvZyksZnVuY3Rpb24oYSxiKXt2YXIgYz1pYltiXXx8ci5maW5kLmF0dHI7aWJbYl09ZnVuY3Rpb24oYSxiLGQpe3ZhciBlLGYsZz1iLnRvTG93ZXJDYXNlKCk7cmV0dXJuIGR8fChmPWliW2ddLGliW2ddPWUsZT1udWxsIT1jKGEsYixkKT9nOm51bGwsaWJbZ109ZiksZX19KTt2YXIgamI9L14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxrYj0vXig/OmF8YXJlYSkkL2k7ci5mbi5leHRlbmQoe3Byb3A6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gUyh0aGlzLHIucHJvcCxhLGIsYXJndW1lbnRzLmxlbmd0aD4xKX0scmVtb3ZlUHJvcDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7ZGVsZXRlIHRoaXNbci5wcm9wRml4W2FdfHxhXX0pfX0pLHIuZXh0ZW5kKHtwcm9wOmZ1bmN0aW9uKGEsYixjKXt2YXIgZCxlLGY9YS5ub2RlVHlwZTtpZigzIT09ZiYmOCE9PWYmJjIhPT1mKXJldHVybiAxPT09ZiYmci5pc1hNTERvYyhhKXx8KGI9ci5wcm9wRml4W2JdfHxiLGU9ci5wcm9wSG9va3NbYl0pLHZvaWQgMCE9PWM/ZSYmInNldCJpbiBlJiZ2b2lkIDAhPT0oZD1lLnNldChhLGMsYikpP2Q6YVtiXT1jOmUmJiJnZXQiaW4gZSYmbnVsbCE9PShkPWUuZ2V0KGEsYikpP2Q6YVtiXX0scHJvcEhvb2tzOnt0YWJJbmRleDp7Z2V0OmZ1bmN0aW9uKGEpe3ZhciBiPXIuZmluZC5hdHRyKGEsInRhYmluZGV4Iik7cmV0dXJuIGI/cGFyc2VJbnQoYiwxMCk6amIudGVzdChhLm5vZGVOYW1lKXx8a2IudGVzdChhLm5vZGVOYW1lKSYmYS5ocmVmPzA6LTF9fX0scHJvcEZpeDp7ImZvciI6Imh0bWxGb3IiLCJjbGFzcyI6ImNsYXNzTmFtZSJ9fSksby5vcHRTZWxlY3RlZHx8KHIucHJvcEhvb2tzLnNlbGVjdGVkPXtnZXQ6ZnVuY3Rpb24oYSl7dmFyIGI9YS5wYXJlbnROb2RlO3JldHVybiBiJiZiLnBhcmVudE5vZGUmJmIucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4LG51bGx9LHNldDpmdW5jdGlvbihhKXt2YXIgYj1hLnBhcmVudE5vZGU7YiYmKGIuc2VsZWN0ZWRJbmRleCxiLnBhcmVudE5vZGUmJmIucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4KX19KSxyLmVhY2goWyJ0YWJJbmRleCIsInJlYWRPbmx5IiwibWF4TGVuZ3RoIiwiY2VsbFNwYWNpbmciLCJjZWxsUGFkZGluZyIsInJvd1NwYW4iLCJjb2xTcGFuIiwidXNlTWFwIiwiZnJhbWVCb3JkZXIiLCJjb250ZW50RWRpdGFibGUiXSxmdW5jdGlvbigpe3IucHJvcEZpeFt0aGlzLnRvTG93ZXJDYXNlKCldPXRoaXN9KTt2YXIgbGI9L1tcdFxyXG5cZl0vZztmdW5jdGlvbiBtYihhKXtyZXR1cm4gYS5nZXRBdHRyaWJ1dGUmJmEuZ2V0QXR0cmlidXRlKCJjbGFzcyIpfHwiIn1yLmZuLmV4dGVuZCh7YWRkQ2xhc3M6ZnVuY3Rpb24oYSl7dmFyIGIsYyxkLGUsZixnLGgsaT0wO2lmKHIuaXNGdW5jdGlvbihhKSlyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKGIpe3IodGhpcykuYWRkQ2xhc3MoYS5jYWxsKHRoaXMsYixtYih0aGlzKSkpfSk7aWYoInN0cmluZyI9PXR5cGVvZiBhJiZhKXtiPWEubWF0Y2goSyl8fFtdO3doaWxlKGM9dGhpc1tpKytdKWlmKGU9bWIoYyksZD0xPT09Yy5ub2RlVHlwZSYmKCIgIitlKyIgIikucmVwbGFjZShsYiwiICIpKXtnPTA7d2hpbGUoZj1iW2crK10pZC5pbmRleE9mKCIgIitmKyIgIik8MCYmKGQrPWYrIiAiKTtoPXIudHJpbShkKSxlIT09aCYmYy5zZXRBdHRyaWJ1dGUoImNsYXNzIixoKX19cmV0dXJuIHRoaXN9LHJlbW92ZUNsYXNzOmZ1bmN0aW9uKGEpe3ZhciBiLGMsZCxlLGYsZyxoLGk9MDtpZihyLmlzRnVuY3Rpb24oYSkpcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihiKXtyKHRoaXMpLnJlbW92ZUNsYXNzKGEuY2FsbCh0aGlzLGIsbWIodGhpcykpKX0pO2lmKCFhcmd1bWVudHMubGVuZ3RoKXJldHVybiB0aGlzLmF0dHIoImNsYXNzIiwiIik7aWYoInN0cmluZyI9PXR5cGVvZiBhJiZhKXtiPWEubWF0Y2goSyl8fFtdO3doaWxlKGM9dGhpc1tpKytdKWlmKGU9bWIoYyksZD0xPT09Yy5ub2RlVHlwZSYmKCIgIitlKyIgIikucmVwbGFjZShsYiwiICIpKXtnPTA7d2hpbGUoZj1iW2crK10pd2hpbGUoZC5pbmRleE9mKCIgIitmKyIgIik+LTEpZD1kLnJlcGxhY2UoIiAiK2YrIiAiLCIgIik7aD1yLnRyaW0oZCksZSE9PWgmJmMuc2V0QXR0cmlidXRlKCJjbGFzcyIsaCl9fXJldHVybiB0aGlzfSx0b2dnbGVDbGFzczpmdW5jdGlvbihhLGIpe3ZhciBjPXR5cGVvZiBhO3JldHVybiJib29sZWFuIj09dHlwZW9mIGImJiJzdHJpbmciPT09Yz9iP3RoaXMuYWRkQ2xhc3MoYSk6dGhpcy5yZW1vdmVDbGFzcyhhKTpyLmlzRnVuY3Rpb24oYSk/dGhpcy5lYWNoKGZ1bmN0aW9uKGMpe3IodGhpcykudG9nZ2xlQ2xhc3MoYS5jYWxsKHRoaXMsYyxtYih0aGlzKSxiKSxiKX0pOnRoaXMuZWFjaChmdW5jdGlvbigpe3ZhciBiLGQsZSxmO2lmKCJzdHJpbmciPT09Yyl7ZD0wLGU9cih0aGlzKSxmPWEubWF0Y2goSyl8fFtdO3doaWxlKGI9ZltkKytdKWUuaGFzQ2xhc3MoYik/ZS5yZW1vdmVDbGFzcyhiKTplLmFkZENsYXNzKGIpfWVsc2Ugdm9pZCAwIT09YSYmImJvb2xlYW4iIT09Y3x8KGI9bWIodGhpcyksYiYmVi5zZXQodGhpcywiX19jbGFzc05hbWVfXyIsYiksdGhpcy5zZXRBdHRyaWJ1dGUmJnRoaXMuc2V0QXR0cmlidXRlKCJjbGFzcyIsYnx8YT09PSExPyIiOlYuZ2V0KHRoaXMsIl9fY2xhc3NOYW1lX18iKXx8IiIpKX0pfSxoYXNDbGFzczpmdW5jdGlvbihhKXt2YXIgYixjLGQ9MDtiPSIgIithKyIgIjt3aGlsZShjPXRoaXNbZCsrXSlpZigxPT09Yy5ub2RlVHlwZSYmKCIgIittYihjKSsiICIpLnJlcGxhY2UobGIsIiAiKS5pbmRleE9mKGIpPi0xKXJldHVybiEwO3JldHVybiExfX0pO3ZhciBuYj0vXHIvZyxvYj0vW1x4MjBcdFxyXG5cZl0rL2c7ci5mbi5leHRlbmQoe3ZhbDpmdW5jdGlvbihhKXt2YXIgYixjLGQsZT10aGlzWzBdO3tpZihhcmd1bWVudHMubGVuZ3RoKXJldHVybiBkPXIuaXNGdW5jdGlvbihhKSx0aGlzLmVhY2goZnVuY3Rpb24oYyl7dmFyIGU7MT09PXRoaXMubm9kZVR5cGUmJihlPWQ/YS5jYWxsKHRoaXMsYyxyKHRoaXMpLnZhbCgpKTphLG51bGw9PWU/ZT0iIjoibnVtYmVyIj09dHlwZW9mIGU/ZSs9IiI6ci5pc0FycmF5KGUpJiYoZT1yLm1hcChlLGZ1bmN0aW9uKGEpe3JldHVybiBudWxsPT1hPyIiOmErIiJ9KSksYj1yLnZhbEhvb2tzW3RoaXMudHlwZV18fHIudmFsSG9va3NbdGhpcy5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpXSxiJiYic2V0ImluIGImJnZvaWQgMCE9PWIuc2V0KHRoaXMsZSwidmFsdWUiKXx8KHRoaXMudmFsdWU9ZSkpfSk7aWYoZSlyZXR1cm4gYj1yLnZhbEhvb2tzW2UudHlwZV18fHIudmFsSG9va3NbZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpXSxiJiYiZ2V0ImluIGImJnZvaWQgMCE9PShjPWIuZ2V0KGUsInZhbHVlIikpP2M6KGM9ZS52YWx1ZSwic3RyaW5nIj09dHlwZW9mIGM/Yy5yZXBsYWNlKG5iLCIiKTpudWxsPT1jPyIiOmMpfX19KSxyLmV4dGVuZCh7dmFsSG9va3M6e29wdGlvbjp7Z2V0OmZ1bmN0aW9uKGEpe3ZhciBiPXIuZmluZC5hdHRyKGEsInZhbHVlIik7cmV0dXJuIG51bGwhPWI/YjpyLnRyaW0oci50ZXh0KGEpKS5yZXBsYWNlKG9iLCIgIil9fSxzZWxlY3Q6e2dldDpmdW5jdGlvbihhKXtmb3IodmFyIGIsYyxkPWEub3B0aW9ucyxlPWEuc2VsZWN0ZWRJbmRleCxmPSJzZWxlY3Qtb25lIj09PWEudHlwZSxnPWY/bnVsbDpbXSxoPWY/ZSsxOmQubGVuZ3RoLGk9ZTwwP2g6Zj9lOjA7aTxoO2krKylpZihjPWRbaV0sKGMuc2VsZWN0ZWR8fGk9PT1lKSYmIWMuZGlzYWJsZWQmJighYy5wYXJlbnROb2RlLmRpc2FibGVkfHwhci5ub2RlTmFtZShjLnBhcmVudE5vZGUsIm9wdGdyb3VwIikpKXtpZihiPXIoYykudmFsKCksZilyZXR1cm4gYjtnLnB1c2goYil9cmV0dXJuIGd9LHNldDpmdW5jdGlvbihhLGIpe3ZhciBjLGQsZT1hLm9wdGlvbnMsZj1yLm1ha2VBcnJheShiKSxnPWUubGVuZ3RoO3doaWxlKGctLSlkPWVbZ10sKGQuc2VsZWN0ZWQ9ci5pbkFycmF5KHIudmFsSG9va3Mub3B0aW9uLmdldChkKSxmKT4tMSkmJihjPSEwKTtyZXR1cm4gY3x8KGEuc2VsZWN0ZWRJbmRleD0tMSksZn19fX0pLHIuZWFjaChbInJhZGlvIiwiY2hlY2tib3giXSxmdW5jdGlvbigpe3IudmFsSG9va3NbdGhpc109e3NldDpmdW5jdGlvbihhLGIpe2lmKHIuaXNBcnJheShiKSlyZXR1cm4gYS5jaGVja2VkPXIuaW5BcnJheShyKGEpLnZhbCgpLGIpPi0xfX0sby5jaGVja09ufHwoci52YWxIb29rc1t0aGlzXS5nZXQ9ZnVuY3Rpb24oYSl7cmV0dXJuIG51bGw9PT1hLmdldEF0dHJpYnV0ZSgidmFsdWUiKT8ib24iOmEudmFsdWV9KX0pO3ZhciBwYj0vXig/OmZvY3VzaW5mb2N1c3xmb2N1c291dGJsdXIpJC87ci5leHRlbmQoci5ldmVudCx7dHJpZ2dlcjpmdW5jdGlvbihiLGMsZSxmKXt2YXIgZyxoLGksaixrLG0sbixvPVtlfHxkXSxwPWwuY2FsbChiLCJ0eXBlIik/Yi50eXBlOmIscT1sLmNhbGwoYiwibmFtZXNwYWNlIik/Yi5uYW1lc3BhY2Uuc3BsaXQoIi4iKTpbXTtpZihoPWk9ZT1lfHxkLDMhPT1lLm5vZGVUeXBlJiY4IT09ZS5ub2RlVHlwZSYmIXBiLnRlc3QocCtyLmV2ZW50LnRyaWdnZXJlZCkmJihwLmluZGV4T2YoIi4iKT4tMSYmKHE9cC5zcGxpdCgiLiIpLHA9cS5zaGlmdCgpLHEuc29ydCgpKSxrPXAuaW5kZXhPZigiOiIpPDAmJiJvbiIrcCxiPWJbci5leHBhbmRvXT9iOm5ldyByLkV2ZW50KHAsIm9iamVjdCI9PXR5cGVvZiBiJiZiKSxiLmlzVHJpZ2dlcj1mPzI6MyxiLm5hbWVzcGFjZT1xLmpvaW4oIi4iKSxiLnJuYW1lc3BhY2U9Yi5uYW1lc3BhY2U/bmV3IFJlZ0V4cCgiKF58XFwuKSIrcS5qb2luKCJcXC4oPzouKlxcLnwpIikrIihcXC58JCkiKTpudWxsLGIucmVzdWx0PXZvaWQgMCxiLnRhcmdldHx8KGIudGFyZ2V0PWUpLGM9bnVsbD09Yz9bYl06ci5tYWtlQXJyYXkoYyxbYl0pLG49ci5ldmVudC5zcGVjaWFsW3BdfHx7fSxmfHwhbi50cmlnZ2VyfHxuLnRyaWdnZXIuYXBwbHkoZSxjKSE9PSExKSl7aWYoIWYmJiFuLm5vQnViYmxlJiYhci5pc1dpbmRvdyhlKSl7Zm9yKGo9bi5kZWxlZ2F0ZVR5cGV8fHAscGIudGVzdChqK3ApfHwoaD1oLnBhcmVudE5vZGUpO2g7aD1oLnBhcmVudE5vZGUpby5wdXNoKGgpLGk9aDtpPT09KGUub3duZXJEb2N1bWVudHx8ZCkmJm8ucHVzaChpLmRlZmF1bHRWaWV3fHxpLnBhcmVudFdpbmRvd3x8YSl9Zz0wO3doaWxlKChoPW9bZysrXSkmJiFiLmlzUHJvcGFnYXRpb25TdG9wcGVkKCkpYi50eXBlPWc+MT9qOm4uYmluZFR5cGV8fHAsbT0oVi5nZXQoaCwiZXZlbnRzIil8fHt9KVtiLnR5cGVdJiZWLmdldChoLCJoYW5kbGUiKSxtJiZtLmFwcGx5KGgsYyksbT1rJiZoW2tdLG0mJm0uYXBwbHkmJlQoaCkmJihiLnJlc3VsdD1tLmFwcGx5KGgsYyksYi5yZXN1bHQ9PT0hMSYmYi5wcmV2ZW50RGVmYXVsdCgpKTtyZXR1cm4gYi50eXBlPXAsZnx8Yi5pc0RlZmF1bHRQcmV2ZW50ZWQoKXx8bi5fZGVmYXVsdCYmbi5fZGVmYXVsdC5hcHBseShvLnBvcCgpLGMpIT09ITF8fCFUKGUpfHxrJiZyLmlzRnVuY3Rpb24oZVtwXSkmJiFyLmlzV2luZG93KGUpJiYoaT1lW2tdLGkmJihlW2tdPW51bGwpLHIuZXZlbnQudHJpZ2dlcmVkPXAsZVtwXSgpLHIuZXZlbnQudHJpZ2dlcmVkPXZvaWQgMCxpJiYoZVtrXT1pKSksYi5yZXN1bHR9fSxzaW11bGF0ZTpmdW5jdGlvbihhLGIsYyl7dmFyIGQ9ci5leHRlbmQobmV3IHIuRXZlbnQsYyx7dHlwZTphLGlzU2ltdWxhdGVkOiEwfSk7ci5ldmVudC50cmlnZ2VyKGQsbnVsbCxiKX19KSxyLmZuLmV4dGVuZCh7dHJpZ2dlcjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtyLmV2ZW50LnRyaWdnZXIoYSxiLHRoaXMpfSl9LHRyaWdnZXJIYW5kbGVyOmZ1bmN0aW9uKGEsYil7dmFyIGM9dGhpc1swXTtpZihjKXJldHVybiByLmV2ZW50LnRyaWdnZXIoYSxiLGMsITApfX0pLHIuZWFjaCgiYmx1ciBmb2N1cyBmb2N1c2luIGZvY3Vzb3V0IHJlc2l6ZSBzY3JvbGwgY2xpY2sgZGJsY2xpY2sgbW91c2Vkb3duIG1vdXNldXAgbW91c2Vtb3ZlIG1vdXNlb3ZlciBtb3VzZW91dCBtb3VzZWVudGVyIG1vdXNlbGVhdmUgY2hhbmdlIHNlbGVjdCBzdWJtaXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBjb250ZXh0bWVudSIuc3BsaXQoIiAiKSxmdW5jdGlvbihhLGIpe3IuZm5bYl09ZnVuY3Rpb24oYSxjKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD4wP3RoaXMub24oYixudWxsLGEsYyk6dGhpcy50cmlnZ2VyKGIpfX0pLHIuZm4uZXh0ZW5kKHtob3ZlcjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLm1vdXNlZW50ZXIoYSkubW91c2VsZWF2ZShifHxhKX19KSxvLmZvY3VzaW49Im9uZm9jdXNpbiJpbiBhLG8uZm9jdXNpbnx8ci5lYWNoKHtmb2N1czoiZm9jdXNpbiIsYmx1cjoiZm9jdXNvdXQifSxmdW5jdGlvbihhLGIpe3ZhciBjPWZ1bmN0aW9uKGEpe3IuZXZlbnQuc2ltdWxhdGUoYixhLnRhcmdldCxyLmV2ZW50LmZpeChhKSl9O3IuZXZlbnQuc3BlY2lhbFtiXT17c2V0dXA6ZnVuY3Rpb24oKXt2YXIgZD10aGlzLm93bmVyRG9jdW1lbnR8fHRoaXMsZT1WLmFjY2VzcyhkLGIpO2V8fGQuYWRkRXZlbnRMaXN0ZW5lcihhLGMsITApLFYuYWNjZXNzKGQsYiwoZXx8MCkrMSl9LHRlYXJkb3duOmZ1bmN0aW9uKCl7dmFyIGQ9dGhpcy5vd25lckRvY3VtZW50fHx0aGlzLGU9Vi5hY2Nlc3MoZCxiKS0xO2U/Vi5hY2Nlc3MoZCxiLGUpOihkLnJlbW92ZUV2ZW50TGlzdGVuZXIoYSxjLCEwKSxWLnJlbW92ZShkLGIpKX19fSk7dmFyIHFiPWEubG9jYXRpb24scmI9ci5ub3coKSxzYj0vXD8vO3IucGFyc2VYTUw9ZnVuY3Rpb24oYil7dmFyIGM7aWYoIWJ8fCJzdHJpbmciIT10eXBlb2YgYilyZXR1cm4gbnVsbDt0cnl7Yz0obmV3IGEuRE9NUGFyc2VyKS5wYXJzZUZyb21TdHJpbmcoYiwidGV4dC94bWwiKX1jYXRjaChkKXtjPXZvaWQgMH1yZXR1cm4gYyYmIWMuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInBhcnNlcmVycm9yIikubGVuZ3RofHxyLmVycm9yKCJJbnZhbGlkIFhNTDogIitiKSxjfTt2YXIgdGI9L1xbXF0kLyx1Yj0vXHI/XG4vZyx2Yj0vXig/OnN1Ym1pdHxidXR0b258aW1hZ2V8cmVzZXR8ZmlsZSkkL2ksd2I9L14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8a2V5Z2VuKS9pO2Z1bmN0aW9uIHhiKGEsYixjLGQpe3ZhciBlO2lmKHIuaXNBcnJheShiKSlyLmVhY2goYixmdW5jdGlvbihiLGUpe2N8fHRiLnRlc3QoYSk/ZChhLGUpOnhiKGErIlsiKygib2JqZWN0Ij09dHlwZW9mIGUmJm51bGwhPWU/YjoiIikrIl0iLGUsYyxkKX0pO2Vsc2UgaWYoY3x8Im9iamVjdCIhPT1yLnR5cGUoYikpZChhLGIpO2Vsc2UgZm9yKGUgaW4gYil4YihhKyJbIitlKyJdIixiW2VdLGMsZCl9ci5wYXJhbT1mdW5jdGlvbihhLGIpe3ZhciBjLGQ9W10sZT1mdW5jdGlvbihhLGIpe3ZhciBjPXIuaXNGdW5jdGlvbihiKT9iKCk6YjtkW2QubGVuZ3RoXT1lbmNvZGVVUklDb21wb25lbnQoYSkrIj0iK2VuY29kZVVSSUNvbXBvbmVudChudWxsPT1jPyIiOmMpfTtpZihyLmlzQXJyYXkoYSl8fGEuanF1ZXJ5JiYhci5pc1BsYWluT2JqZWN0KGEpKXIuZWFjaChhLGZ1bmN0aW9uKCl7ZSh0aGlzLm5hbWUsdGhpcy52YWx1ZSl9KTtlbHNlIGZvcihjIGluIGEpeGIoYyxhW2NdLGIsZSk7cmV0dXJuIGQuam9pbigiJiIpfSxyLmZuLmV4dGVuZCh7c2VyaWFsaXplOmZ1bmN0aW9uKCl7cmV0dXJuIHIucGFyYW0odGhpcy5zZXJpYWxpemVBcnJheSgpKX0sc2VyaWFsaXplQXJyYXk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24oKXt2YXIgYT1yLnByb3AodGhpcywiZWxlbWVudHMiKTtyZXR1cm4gYT9yLm1ha2VBcnJheShhKTp0aGlzfSkuZmlsdGVyKGZ1bmN0aW9uKCl7dmFyIGE9dGhpcy50eXBlO3JldHVybiB0aGlzLm5hbWUmJiFyKHRoaXMpLmlzKCI6ZGlzYWJsZWQiKSYmd2IudGVzdCh0aGlzLm5vZGVOYW1lKSYmIXZiLnRlc3QoYSkmJih0aGlzLmNoZWNrZWR8fCFoYS50ZXN0KGEpKX0pLm1hcChmdW5jdGlvbihhLGIpe3ZhciBjPXIodGhpcykudmFsKCk7cmV0dXJuIG51bGw9PWM/bnVsbDpyLmlzQXJyYXkoYyk/ci5tYXAoYyxmdW5jdGlvbihhKXtyZXR1cm57bmFtZTpiLm5hbWUsdmFsdWU6YS5yZXBsYWNlKHViLCJcclxuIil9fSk6e25hbWU6Yi5uYW1lLHZhbHVlOmMucmVwbGFjZSh1YiwiXHJcbiIpfX0pLmdldCgpfX0pO3ZhciB5Yj0vJTIwL2csemI9LyMuKiQvLEFiPS8oWz8mXSlfPVteJl0qLyxCYj0vXiguKj8pOlsgXHRdKihbXlxyXG5dKikkL2dtLENiPS9eKD86YWJvdXR8YXBwfGFwcC1zdG9yYWdlfC4rLWV4dGVuc2lvbnxmaWxlfHJlc3x3aWRnZXQpOiQvLERiPS9eKD86R0VUfEhFQUQpJC8sRWI9L15cL1wvLyxGYj17fSxHYj17fSxIYj0iKi8iLmNvbmNhdCgiKiIpLEliPWQuY3JlYXRlRWxlbWVudCgiYSIpO0liLmhyZWY9cWIuaHJlZjtmdW5jdGlvbiBKYihhKXtyZXR1cm4gZnVuY3Rpb24oYixjKXsic3RyaW5nIiE9dHlwZW9mIGImJihjPWIsYj0iKiIpO3ZhciBkLGU9MCxmPWIudG9Mb3dlckNhc2UoKS5tYXRjaChLKXx8W107aWYoci5pc0Z1bmN0aW9uKGMpKXdoaWxlKGQ9ZltlKytdKSIrIj09PWRbMF0/KGQ9ZC5zbGljZSgxKXx8IioiLChhW2RdPWFbZF18fFtdKS51bnNoaWZ0KGMpKTooYVtkXT1hW2RdfHxbXSkucHVzaChjKX19ZnVuY3Rpb24gS2IoYSxiLGMsZCl7dmFyIGU9e30sZj1hPT09R2I7ZnVuY3Rpb24gZyhoKXt2YXIgaTtyZXR1cm4gZVtoXT0hMCxyLmVhY2goYVtoXXx8W10sZnVuY3Rpb24oYSxoKXt2YXIgaj1oKGIsYyxkKTtyZXR1cm4ic3RyaW5nIiE9dHlwZW9mIGp8fGZ8fGVbal0/Zj8hKGk9aik6dm9pZCAwOihiLmRhdGFUeXBlcy51bnNoaWZ0KGopLGcoaiksITEpfSksaX1yZXR1cm4gZyhiLmRhdGFUeXBlc1swXSl8fCFlWyIqIl0mJmcoIioiKX1mdW5jdGlvbiBMYihhLGIpe3ZhciBjLGQsZT1yLmFqYXhTZXR0aW5ncy5mbGF0T3B0aW9uc3x8e307Zm9yKGMgaW4gYil2b2lkIDAhPT1iW2NdJiYoKGVbY10/YTpkfHwoZD17fSkpW2NdPWJbY10pO3JldHVybiBkJiZyLmV4dGVuZCghMCxhLGQpLGF9ZnVuY3Rpb24gTWIoYSxiLGMpe3ZhciBkLGUsZixnLGg9YS5jb250ZW50cyxpPWEuZGF0YVR5cGVzO3doaWxlKCIqIj09PWlbMF0paS5zaGlmdCgpLHZvaWQgMD09PWQmJihkPWEubWltZVR5cGV8fGIuZ2V0UmVzcG9uc2VIZWFkZXIoIkNvbnRlbnQtVHlwZSIpKTtpZihkKWZvcihlIGluIGgpaWYoaFtlXSYmaFtlXS50ZXN0KGQpKXtpLnVuc2hpZnQoZSk7YnJlYWt9aWYoaVswXWluIGMpZj1pWzBdO2Vsc2V7Zm9yKGUgaW4gYyl7aWYoIWlbMF18fGEuY29udmVydGVyc1tlKyIgIitpWzBdXSl7Zj1lO2JyZWFrfWd8fChnPWUpfWY9Znx8Z31pZihmKXJldHVybiBmIT09aVswXSYmaS51bnNoaWZ0KGYpLGNbZl19ZnVuY3Rpb24gTmIoYSxiLGMsZCl7dmFyIGUsZixnLGgsaSxqPXt9LGs9YS5kYXRhVHlwZXMuc2xpY2UoKTtpZihrWzFdKWZvcihnIGluIGEuY29udmVydGVycylqW2cudG9Mb3dlckNhc2UoKV09YS5jb252ZXJ0ZXJzW2ddO2Y9ay5zaGlmdCgpO3doaWxlKGYpaWYoYS5yZXNwb25zZUZpZWxkc1tmXSYmKGNbYS5yZXNwb25zZUZpZWxkc1tmXV09YiksIWkmJmQmJmEuZGF0YUZpbHRlciYmKGI9YS5kYXRhRmlsdGVyKGIsYS5kYXRhVHlwZSkpLGk9ZixmPWsuc2hpZnQoKSlpZigiKiI9PT1mKWY9aTtlbHNlIGlmKCIqIiE9PWkmJmkhPT1mKXtpZihnPWpbaSsiICIrZl18fGpbIiogIitmXSwhZylmb3IoZSBpbiBqKWlmKGg9ZS5zcGxpdCgiICIpLGhbMV09PT1mJiYoZz1qW2krIiAiK2hbMF1dfHxqWyIqICIraFswXV0pKXtnPT09ITA/Zz1qW2VdOmpbZV0hPT0hMCYmKGY9aFswXSxrLnVuc2hpZnQoaFsxXSkpO2JyZWFrfWlmKGchPT0hMClpZihnJiZhWyJ0aHJvd3MiXSliPWcoYik7ZWxzZSB0cnl7Yj1nKGIpfWNhdGNoKGwpe3JldHVybntzdGF0ZToicGFyc2VyZXJyb3IiLGVycm9yOmc/bDoiTm8gY29udmVyc2lvbiBmcm9tICIraSsiIHRvICIrZn19fXJldHVybntzdGF0ZToic3VjY2VzcyIsZGF0YTpifX1yLmV4dGVuZCh7YWN0aXZlOjAsbGFzdE1vZGlmaWVkOnt9LGV0YWc6e30sYWpheFNldHRpbmdzOnt1cmw6cWIuaHJlZix0eXBlOiJHRVQiLGlzTG9jYWw6Q2IudGVzdChxYi5wcm90b2NvbCksZ2xvYmFsOiEwLHByb2Nlc3NEYXRhOiEwLGFzeW5jOiEwLGNvbnRlbnRUeXBlOiJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7IGNoYXJzZXQ9VVRGLTgiLGFjY2VwdHM6eyIqIjpIYix0ZXh0OiJ0ZXh0L3BsYWluIixodG1sOiJ0ZXh0L2h0bWwiLHhtbDoiYXBwbGljYXRpb24veG1sLCB0ZXh0L3htbCIsanNvbjoiYXBwbGljYXRpb24vanNvbiwgdGV4dC9qYXZhc2NyaXB0In0sY29udGVudHM6e3htbDovXGJ4bWxcYi8saHRtbDovXGJodG1sLyxqc29uOi9cYmpzb25cYi99LHJlc3BvbnNlRmllbGRzOnt4bWw6InJlc3BvbnNlWE1MIix0ZXh0OiJyZXNwb25zZVRleHQiLGpzb246InJlc3BvbnNlSlNPTiJ9LGNvbnZlcnRlcnM6eyIqIHRleHQiOlN0cmluZywidGV4dCBodG1sIjohMCwidGV4dCBqc29uIjpKU09OLnBhcnNlLCJ0ZXh0IHhtbCI6ci5wYXJzZVhNTH0sZmxhdE9wdGlvbnM6e3VybDohMCxjb250ZXh0OiEwfX0sYWpheFNldHVwOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGI/TGIoTGIoYSxyLmFqYXhTZXR0aW5ncyksYik6TGIoci5hamF4U2V0dGluZ3MsYSl9LGFqYXhQcmVmaWx0ZXI6SmIoRmIpLGFqYXhUcmFuc3BvcnQ6SmIoR2IpLGFqYXg6ZnVuY3Rpb24oYixjKXsib2JqZWN0Ij09dHlwZW9mIGImJihjPWIsYj12b2lkIDApLGM9Y3x8e307dmFyIGUsZixnLGgsaSxqLGssbCxtLG4sbz1yLmFqYXhTZXR1cCh7fSxjKSxwPW8uY29udGV4dHx8byxxPW8uY29udGV4dCYmKHAubm9kZVR5cGV8fHAuanF1ZXJ5KT9yKHApOnIuZXZlbnQscz1yLkRlZmVycmVkKCksdD1yLkNhbGxiYWNrcygib25jZSBtZW1vcnkiKSx1PW8uc3RhdHVzQ29kZXx8e30sdj17fSx3PXt9LHg9ImNhbmNlbGVkIix5PXtyZWFkeVN0YXRlOjAsZ2V0UmVzcG9uc2VIZWFkZXI6ZnVuY3Rpb24oYSl7dmFyIGI7aWYoayl7aWYoIWgpe2g9e307d2hpbGUoYj1CYi5leGVjKGcpKWhbYlsxXS50b0xvd2VyQ2FzZSgpXT1iWzJdfWI9aFthLnRvTG93ZXJDYXNlKCldfXJldHVybiBudWxsPT1iP251bGw6Yn0sZ2V0QWxsUmVzcG9uc2VIZWFkZXJzOmZ1bmN0aW9uKCl7cmV0dXJuIGs/ZzpudWxsfSxzZXRSZXF1ZXN0SGVhZGVyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG51bGw9PWsmJihhPXdbYS50b0xvd2VyQ2FzZSgpXT13W2EudG9Mb3dlckNhc2UoKV18fGEsdlthXT1iKSx0aGlzfSxvdmVycmlkZU1pbWVUeXBlOmZ1bmN0aW9uKGEpe3JldHVybiBudWxsPT1rJiYoby5taW1lVHlwZT1hKSx0aGlzfSxzdGF0dXNDb2RlOmZ1bmN0aW9uKGEpe3ZhciBiO2lmKGEpaWYoayl5LmFsd2F5cyhhW3kuc3RhdHVzXSk7ZWxzZSBmb3IoYiBpbiBhKXVbYl09W3VbYl0sYVtiXV07cmV0dXJuIHRoaXN9LGFib3J0OmZ1bmN0aW9uKGEpe3ZhciBiPWF8fHg7cmV0dXJuIGUmJmUuYWJvcnQoYiksQSgwLGIpLHRoaXN9fTtpZihzLnByb21pc2UoeSksby51cmw9KChifHxvLnVybHx8cWIuaHJlZikrIiIpLnJlcGxhY2UoRWIscWIucHJvdG9jb2wrIi8vIiksby50eXBlPWMubWV0aG9kfHxjLnR5cGV8fG8ubWV0aG9kfHxvLnR5cGUsby5kYXRhVHlwZXM9KG8uZGF0YVR5cGV8fCIqIikudG9Mb3dlckNhc2UoKS5tYXRjaChLKXx8WyIiXSxudWxsPT1vLmNyb3NzRG9tYWluKXtqPWQuY3JlYXRlRWxlbWVudCgiYSIpO3RyeXtqLmhyZWY9by51cmwsai5ocmVmPWouaHJlZixvLmNyb3NzRG9tYWluPUliLnByb3RvY29sKyIvLyIrSWIuaG9zdCE9ai5wcm90b2NvbCsiLy8iK2ouaG9zdH1jYXRjaCh6KXtvLmNyb3NzRG9tYWluPSEwfX1pZihvLmRhdGEmJm8ucHJvY2Vzc0RhdGEmJiJzdHJpbmciIT10eXBlb2Ygby5kYXRhJiYoby5kYXRhPXIucGFyYW0oby5kYXRhLG8udHJhZGl0aW9uYWwpKSxLYihGYixvLGMseSksaylyZXR1cm4geTtsPXIuZXZlbnQmJm8uZ2xvYmFsLGwmJjA9PT1yLmFjdGl2ZSsrJiZyLmV2ZW50LnRyaWdnZXIoImFqYXhTdGFydCIpLG8udHlwZT1vLnR5cGUudG9VcHBlckNhc2UoKSxvLmhhc0NvbnRlbnQ9IURiLnRlc3Qoby50eXBlKSxmPW8udXJsLnJlcGxhY2UoemIsIiIpLG8uaGFzQ29udGVudD9vLmRhdGEmJm8ucHJvY2Vzc0RhdGEmJjA9PT0oby5jb250ZW50VHlwZXx8IiIpLmluZGV4T2YoImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIpJiYoby5kYXRhPW8uZGF0YS5yZXBsYWNlKHliLCIrIikpOihuPW8udXJsLnNsaWNlKGYubGVuZ3RoKSxvLmRhdGEmJihmKz0oc2IudGVzdChmKT8iJiI6Ij8iKStvLmRhdGEsZGVsZXRlIG8uZGF0YSksby5jYWNoZT09PSExJiYoZj1mLnJlcGxhY2UoQWIsIiIpLG49KHNiLnRlc3QoZik/IiYiOiI/IikrIl89IityYisrICtuKSxvLnVybD1mK24pLG8uaWZNb2RpZmllZCYmKHIubGFzdE1vZGlmaWVkW2ZdJiZ5LnNldFJlcXVlc3RIZWFkZXIoIklmLU1vZGlmaWVkLVNpbmNlIixyLmxhc3RNb2RpZmllZFtmXSksci5ldGFnW2ZdJiZ5LnNldFJlcXVlc3RIZWFkZXIoIklmLU5vbmUtTWF0Y2giLHIuZXRhZ1tmXSkpLChvLmRhdGEmJm8uaGFzQ29udGVudCYmby5jb250ZW50VHlwZSE9PSExfHxjLmNvbnRlbnRUeXBlKSYmeS5zZXRSZXF1ZXN0SGVhZGVyKCJDb250ZW50LVR5cGUiLG8uY29udGVudFR5cGUpLHkuc2V0UmVxdWVzdEhlYWRlcigiQWNjZXB0IixvLmRhdGFUeXBlc1swXSYmby5hY2NlcHRzW28uZGF0YVR5cGVzWzBdXT9vLmFjY2VwdHNbby5kYXRhVHlwZXNbMF1dKygiKiIhPT1vLmRhdGFUeXBlc1swXT8iLCAiK0hiKyI7IHE9MC4wMSI6IiIpOm8uYWNjZXB0c1siKiJdKTtmb3IobSBpbiBvLmhlYWRlcnMpeS5zZXRSZXF1ZXN0SGVhZGVyKG0sby5oZWFkZXJzW21dKTtpZihvLmJlZm9yZVNlbmQmJihvLmJlZm9yZVNlbmQuY2FsbChwLHksbyk9PT0hMXx8aykpcmV0dXJuIHkuYWJvcnQoKTtpZih4PSJhYm9ydCIsdC5hZGQoby5jb21wbGV0ZSkseS5kb25lKG8uc3VjY2VzcykseS5mYWlsKG8uZXJyb3IpLGU9S2IoR2IsbyxjLHkpKXtpZih5LnJlYWR5U3RhdGU9MSxsJiZxLnRyaWdnZXIoImFqYXhTZW5kIixbeSxvXSksaylyZXR1cm4geTtvLmFzeW5jJiZvLnRpbWVvdXQ+MCYmKGk9YS5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7eS5hYm9ydCgidGltZW91dCIpfSxvLnRpbWVvdXQpKTt0cnl7az0hMSxlLnNlbmQodixBKX1jYXRjaCh6KXtpZihrKXRocm93IHo7QSgtMSx6KX19ZWxzZSBBKC0xLCJObyBUcmFuc3BvcnQiKTtmdW5jdGlvbiBBKGIsYyxkLGgpe3ZhciBqLG0sbix2LHcseD1jO2t8fChrPSEwLGkmJmEuY2xlYXJUaW1lb3V0KGkpLGU9dm9pZCAwLGc9aHx8IiIseS5yZWFkeVN0YXRlPWI+MD80OjAsaj1iPj0yMDAmJmI8MzAwfHwzMDQ9PT1iLGQmJih2PU1iKG8seSxkKSksdj1OYihvLHYseSxqKSxqPyhvLmlmTW9kaWZpZWQmJih3PXkuZ2V0UmVzcG9uc2VIZWFkZXIoIkxhc3QtTW9kaWZpZWQiKSx3JiYoci5sYXN0TW9kaWZpZWRbZl09dyksdz15LmdldFJlc3BvbnNlSGVhZGVyKCJldGFnIiksdyYmKHIuZXRhZ1tmXT13KSksMjA0PT09Ynx8IkhFQUQiPT09by50eXBlP3g9Im5vY29udGVudCI6MzA0PT09Yj94PSJub3Rtb2RpZmllZCI6KHg9di5zdGF0ZSxtPXYuZGF0YSxuPXYuZXJyb3Isaj0hbikpOihuPXgsIWImJnh8fCh4PSJlcnJvciIsYjwwJiYoYj0wKSkpLHkuc3RhdHVzPWIseS5zdGF0dXNUZXh0PShjfHx4KSsiIixqP3MucmVzb2x2ZVdpdGgocCxbbSx4LHldKTpzLnJlamVjdFdpdGgocCxbeSx4LG5dKSx5LnN0YXR1c0NvZGUodSksdT12b2lkIDAsbCYmcS50cmlnZ2VyKGo/ImFqYXhTdWNjZXNzIjoiYWpheEVycm9yIixbeSxvLGo/bTpuXSksdC5maXJlV2l0aChwLFt5LHhdKSxsJiYocS50cmlnZ2VyKCJhamF4Q29tcGxldGUiLFt5LG9dKSwtLXIuYWN0aXZlfHxyLmV2ZW50LnRyaWdnZXIoImFqYXhTdG9wIikpKX1yZXR1cm4geX0sZ2V0SlNPTjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHIuZ2V0KGEsYixjLCJqc29uIil9LGdldFNjcmlwdDpmdW5jdGlvbihhLGIpe3JldHVybiByLmdldChhLHZvaWQgMCxiLCJzY3JpcHQiKX19KSxyLmVhY2goWyJnZXQiLCJwb3N0Il0sZnVuY3Rpb24oYSxiKXtyW2JdPWZ1bmN0aW9uKGEsYyxkLGUpe3JldHVybiByLmlzRnVuY3Rpb24oYykmJihlPWV8fGQsZD1jLGM9dm9pZCAwKSxyLmFqYXgoci5leHRlbmQoe3VybDphLHR5cGU6YixkYXRhVHlwZTplLGRhdGE6YyxzdWNjZXNzOmR9LHIuaXNQbGFpbk9iamVjdChhKSYmYSkpfX0pLHIuX2V2YWxVcmw9ZnVuY3Rpb24oYSl7cmV0dXJuIHIuYWpheCh7dXJsOmEsdHlwZToiR0VUIixkYXRhVHlwZToic2NyaXB0IixjYWNoZTohMCxhc3luYzohMSxnbG9iYWw6ITEsInRocm93cyI6ITB9KX0sci5mbi5leHRlbmQoe3dyYXBBbGw6ZnVuY3Rpb24oYSl7dmFyIGI7cmV0dXJuIHRoaXNbMF0mJihyLmlzRnVuY3Rpb24oYSkmJihhPWEuY2FsbCh0aGlzWzBdKSksYj1yKGEsdGhpc1swXS5vd25lckRvY3VtZW50KS5lcSgwKS5jbG9uZSghMCksdGhpc1swXS5wYXJlbnROb2RlJiZiLmluc2VydEJlZm9yZSh0aGlzWzBdKSxiLm1hcChmdW5jdGlvbigpe3ZhciBhPXRoaXM7d2hpbGUoYS5maXJzdEVsZW1lbnRDaGlsZClhPWEuZmlyc3RFbGVtZW50Q2hpbGQ7cmV0dXJuIGF9KS5hcHBlbmQodGhpcykpLHRoaXN9LHdyYXBJbm5lcjpmdW5jdGlvbihhKXtyZXR1cm4gci5pc0Z1bmN0aW9uKGEpP3RoaXMuZWFjaChmdW5jdGlvbihiKXtyKHRoaXMpLndyYXBJbm5lcihhLmNhbGwodGhpcyxiKSl9KTp0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgYj1yKHRoaXMpLGM9Yi5jb250ZW50cygpO2MubGVuZ3RoP2Mud3JhcEFsbChhKTpiLmFwcGVuZChhKX0pfSx3cmFwOmZ1bmN0aW9uKGEpe3ZhciBiPXIuaXNGdW5jdGlvbihhKTtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKGMpe3IodGhpcykud3JhcEFsbChiP2EuY2FsbCh0aGlzLGMpOmEpfSl9LHVud3JhcDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5wYXJlbnQoYSkubm90KCJib2R5IikuZWFjaChmdW5jdGlvbigpe3IodGhpcykucmVwbGFjZVdpdGgodGhpcy5jaGlsZE5vZGVzKX0pLHRoaXN9fSksci5leHByLnBzZXVkb3MuaGlkZGVuPWZ1bmN0aW9uKGEpe3JldHVybiFyLmV4cHIucHNldWRvcy52aXNpYmxlKGEpfSxyLmV4cHIucHNldWRvcy52aXNpYmxlPWZ1bmN0aW9uKGEpe3JldHVybiEhKGEub2Zmc2V0V2lkdGh8fGEub2Zmc2V0SGVpZ2h0fHxhLmdldENsaWVudFJlY3RzKCkubGVuZ3RoKX0sci5hamF4U2V0dGluZ3MueGhyPWZ1bmN0aW9uKCl7dHJ5e3JldHVybiBuZXcgYS5YTUxIdHRwUmVxdWVzdH1jYXRjaChiKXt9fTt2YXIgT2I9ezA6MjAwLDEyMjM6MjA0fSxQYj1yLmFqYXhTZXR0aW5ncy54aHIoKTtvLmNvcnM9ISFQYiYmIndpdGhDcmVkZW50aWFscyJpbiBQYixvLmFqYXg9UGI9ISFQYixyLmFqYXhUcmFuc3BvcnQoZnVuY3Rpb24oYil7dmFyIGMsZDtpZihvLmNvcnN8fFBiJiYhYi5jcm9zc0RvbWFpbilyZXR1cm57c2VuZDpmdW5jdGlvbihlLGYpe3ZhciBnLGg9Yi54aHIoKTtpZihoLm9wZW4oYi50eXBlLGIudXJsLGIuYXN5bmMsYi51c2VybmFtZSxiLnBhc3N3b3JkKSxiLnhockZpZWxkcylmb3IoZyBpbiBiLnhockZpZWxkcyloW2ddPWIueGhyRmllbGRzW2ddO2IubWltZVR5cGUmJmgub3ZlcnJpZGVNaW1lVHlwZSYmaC5vdmVycmlkZU1pbWVUeXBlKGIubWltZVR5cGUpLGIuY3Jvc3NEb21haW58fGVbIlgtUmVxdWVzdGVkLVdpdGgiXXx8KGVbIlgtUmVxdWVzdGVkLVdpdGgiXT0iWE1MSHR0cFJlcXVlc3QiKTtmb3IoZyBpbiBlKWguc2V0UmVxdWVzdEhlYWRlcihnLGVbZ10pO2M9ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKCl7YyYmKGM9ZD1oLm9ubG9hZD1oLm9uZXJyb3I9aC5vbmFib3J0PWgub25yZWFkeXN0YXRlY2hhbmdlPW51bGwsImFib3J0Ij09PWE/aC5hYm9ydCgpOiJlcnJvciI9PT1hPyJudW1iZXIiIT10eXBlb2YgaC5zdGF0dXM/ZigwLCJlcnJvciIpOmYoaC5zdGF0dXMsaC5zdGF0dXNUZXh0KTpmKE9iW2guc3RhdHVzXXx8aC5zdGF0dXMsaC5zdGF0dXNUZXh0LCJ0ZXh0IiE9PShoLnJlc3BvbnNlVHlwZXx8InRleHQiKXx8InN0cmluZyIhPXR5cGVvZiBoLnJlc3BvbnNlVGV4dD97YmluYXJ5OmgucmVzcG9uc2V9Ont0ZXh0OmgucmVzcG9uc2VUZXh0fSxoLmdldEFsbFJlc3BvbnNlSGVhZGVycygpKSl9fSxoLm9ubG9hZD1jKCksZD1oLm9uZXJyb3I9YygiZXJyb3IiKSx2b2lkIDAhPT1oLm9uYWJvcnQ/aC5vbmFib3J0PWQ6aC5vbnJlYWR5c3RhdGVjaGFuZ2U9ZnVuY3Rpb24oKXs0PT09aC5yZWFkeVN0YXRlJiZhLnNldFRpbWVvdXQoZnVuY3Rpb24oKXtjJiZkKCl9KX0sYz1jKCJhYm9ydCIpO3RyeXtoLnNlbmQoYi5oYXNDb250ZW50JiZiLmRhdGF8fG51bGwpfWNhdGNoKGkpe2lmKGMpdGhyb3cgaX19LGFib3J0OmZ1bmN0aW9uKCl7YyYmYygpfX19KSxyLmFqYXhQcmVmaWx0ZXIoZnVuY3Rpb24oYSl7YS5jcm9zc0RvbWFpbiYmKGEuY29udGVudHMuc2NyaXB0PSExKX0pLHIuYWpheFNldHVwKHthY2NlcHRzOntzY3JpcHQ6InRleHQvamF2YXNjcmlwdCwgYXBwbGljYXRpb24vamF2YXNjcmlwdCwgYXBwbGljYXRpb24vZWNtYXNjcmlwdCwgYXBwbGljYXRpb24veC1lY21hc2NyaXB0In0sY29udGVudHM6e3NjcmlwdDovXGIoPzpqYXZhfGVjbWEpc2NyaXB0XGIvfSxjb252ZXJ0ZXJzOnsidGV4dCBzY3JpcHQiOmZ1bmN0aW9uKGEpe3JldHVybiByLmdsb2JhbEV2YWwoYSksYX19fSksci5hamF4UHJlZmlsdGVyKCJzY3JpcHQiLGZ1bmN0aW9uKGEpe3ZvaWQgMD09PWEuY2FjaGUmJihhLmNhY2hlPSExKSxhLmNyb3NzRG9tYWluJiYoYS50eXBlPSJHRVQiKX0pLHIuYWpheFRyYW5zcG9ydCgic2NyaXB0IixmdW5jdGlvbihhKXtpZihhLmNyb3NzRG9tYWluKXt2YXIgYixjO3JldHVybntzZW5kOmZ1bmN0aW9uKGUsZil7Yj1yKCI8c2NyaXB0PiIpLnByb3Aoe2NoYXJzZXQ6YS5zY3JpcHRDaGFyc2V0LHNyYzphLnVybH0pLm9uKCJsb2FkIGVycm9yIixjPWZ1bmN0aW9uKGEpe2IucmVtb3ZlKCksYz1udWxsLGEmJmYoImVycm9yIj09PWEudHlwZT80MDQ6MjAwLGEudHlwZSl9KSxkLmhlYWQuYXBwZW5kQ2hpbGQoYlswXSl9LGFib3J0OmZ1bmN0aW9uKCl7YyYmYygpfX19fSk7dmFyIFFiPVtdLFJiPS8oPSlcPyg/PSZ8JCl8XD9cPy87ci5hamF4U2V0dXAoe2pzb25wOiJjYWxsYmFjayIsanNvbnBDYWxsYmFjazpmdW5jdGlvbigpe3ZhciBhPVFiLnBvcCgpfHxyLmV4cGFuZG8rIl8iK3JiKys7cmV0dXJuIHRoaXNbYV09ITAsYX19KSxyLmFqYXhQcmVmaWx0ZXIoImpzb24ganNvbnAiLGZ1bmN0aW9uKGIsYyxkKXt2YXIgZSxmLGcsaD1iLmpzb25wIT09ITEmJihSYi50ZXN0KGIudXJsKT8idXJsIjoic3RyaW5nIj09dHlwZW9mIGIuZGF0YSYmMD09PShiLmNvbnRlbnRUeXBlfHwiIikuaW5kZXhPZigiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIikmJlJiLnRlc3QoYi5kYXRhKSYmImRhdGEiKTtpZihofHwianNvbnAiPT09Yi5kYXRhVHlwZXNbMF0pcmV0dXJuIGU9Yi5qc29ucENhbGxiYWNrPXIuaXNGdW5jdGlvbihiLmpzb25wQ2FsbGJhY2spP2IuanNvbnBDYWxsYmFjaygpOmIuanNvbnBDYWxsYmFjayxoP2JbaF09YltoXS5yZXBsYWNlKFJiLCIkMSIrZSk6Yi5qc29ucCE9PSExJiYoYi51cmwrPShzYi50ZXN0KGIudXJsKT8iJiI6Ij8iKStiLmpzb25wKyI9IitlKSxiLmNvbnZlcnRlcnNbInNjcmlwdCBqc29uIl09ZnVuY3Rpb24oKXtyZXR1cm4gZ3x8ci5lcnJvcihlKyIgd2FzIG5vdCBjYWxsZWQiKSxnWzBdfSxiLmRhdGFUeXBlc1swXT0ianNvbiIsZj1hW2VdLGFbZV09ZnVuY3Rpb24oKXtnPWFyZ3VtZW50c30sZC5hbHdheXMoZnVuY3Rpb24oKXt2b2lkIDA9PT1mP3IoYSkucmVtb3ZlUHJvcChlKTphW2VdPWYsYltlXSYmKGIuanNvbnBDYWxsYmFjaz1jLmpzb25wQ2FsbGJhY2ssUWIucHVzaChlKSksZyYmci5pc0Z1bmN0aW9uKGYpJiZmKGdbMF0pLGc9Zj12b2lkIDB9KSwic2NyaXB0In0pLG8uY3JlYXRlSFRNTERvY3VtZW50PWZ1bmN0aW9uKCl7dmFyIGE9ZC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoIiIpLmJvZHk7cmV0dXJuIGEuaW5uZXJIVE1MPSI8Zm9ybT48L2Zvcm0+PGZvcm0+PC9mb3JtPiIsMj09PWEuY2hpbGROb2Rlcy5sZW5ndGh9KCksci5wYXJzZUhUTUw9ZnVuY3Rpb24oYSxiLGMpe2lmKCJzdHJpbmciIT10eXBlb2YgYSlyZXR1cm5bXTsiYm9vbGVhbiI9PXR5cGVvZiBiJiYoYz1iLGI9ITEpO3ZhciBlLGYsZztyZXR1cm4gYnx8KG8uY3JlYXRlSFRNTERvY3VtZW50PyhiPWQuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50KCIiKSxlPWIuY3JlYXRlRWxlbWVudCgiYmFzZSIpLGUuaHJlZj1kLmxvY2F0aW9uLmhyZWYsYi5oZWFkLmFwcGVuZENoaWxkKGUpKTpiPWQpLGY9Qi5leGVjKGEpLGc9IWMmJltdLGY/W2IuY3JlYXRlRWxlbWVudChmWzFdKV06KGY9b2EoW2FdLGIsZyksZyYmZy5sZW5ndGgmJnIoZykucmVtb3ZlKCksci5tZXJnZShbXSxmLmNoaWxkTm9kZXMpKX0sci5mbi5sb2FkPWZ1bmN0aW9uKGEsYixjKXt2YXIgZCxlLGYsZz10aGlzLGg9YS5pbmRleE9mKCIgIik7cmV0dXJuIGg+LTEmJihkPXIudHJpbShhLnNsaWNlKGgpKSxhPWEuc2xpY2UoMCxoKSksci5pc0Z1bmN0aW9uKGIpPyhjPWIsYj12b2lkIDApOmImJiJvYmplY3QiPT10eXBlb2YgYiYmKGU9IlBPU1QiKSxnLmxlbmd0aD4wJiZyLmFqYXgoe3VybDphLHR5cGU6ZXx8IkdFVCIsZGF0YVR5cGU6Imh0bWwiLGRhdGE6Yn0pLmRvbmUoZnVuY3Rpb24oYSl7Zj1hcmd1bWVudHMsZy5odG1sKGQ/cigiPGRpdj4iKS5hcHBlbmQoci5wYXJzZUhUTUwoYSkpLmZpbmQoZCk6YSl9KS5hbHdheXMoYyYmZnVuY3Rpb24oYSxiKXtnLmVhY2goZnVuY3Rpb24oKXtjLmFwcGx5KHRoaXMsZnx8W2EucmVzcG9uc2VUZXh0LGIsYV0pfSl9KSx0aGlzfSxyLmVhY2goWyJhamF4U3RhcnQiLCJhamF4U3RvcCIsImFqYXhDb21wbGV0ZSIsImFqYXhFcnJvciIsImFqYXhTdWNjZXNzIiwiYWpheFNlbmQiXSxmdW5jdGlvbihhLGIpe3IuZm5bYl09ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMub24oYixhKX19KSxyLmV4cHIucHNldWRvcy5hbmltYXRlZD1mdW5jdGlvbihhKXtyZXR1cm4gci5ncmVwKHIudGltZXJzLGZ1bmN0aW9uKGIpe3JldHVybiBhPT09Yi5lbGVtfSkubGVuZ3RofTtmdW5jdGlvbiBTYihhKXtyZXR1cm4gci5pc1dpbmRvdyhhKT9hOjk9PT1hLm5vZGVUeXBlJiZhLmRlZmF1bHRWaWV3fXIub2Zmc2V0PXtzZXRPZmZzZXQ6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkLGUsZixnLGgsaSxqLGs9ci5jc3MoYSwicG9zaXRpb24iKSxsPXIoYSksbT17fTsic3RhdGljIj09PWsmJihhLnN0eWxlLnBvc2l0aW9uPSJyZWxhdGl2ZSIpLGg9bC5vZmZzZXQoKSxmPXIuY3NzKGEsInRvcCIpLGk9ci5jc3MoYSwibGVmdCIpLGo9KCJhYnNvbHV0ZSI9PT1rfHwiZml4ZWQiPT09aykmJihmK2kpLmluZGV4T2YoImF1dG8iKT4tMSxqPyhkPWwucG9zaXRpb24oKSxnPWQudG9wLGU9ZC5sZWZ0KTooZz1wYXJzZUZsb2F0KGYpfHwwLGU9cGFyc2VGbG9hdChpKXx8MCksci5pc0Z1bmN0aW9uKGIpJiYoYj1iLmNhbGwoYSxjLHIuZXh0ZW5kKHt9LGgpKSksbnVsbCE9Yi50b3AmJihtLnRvcD1iLnRvcC1oLnRvcCtnKSxudWxsIT1iLmxlZnQmJihtLmxlZnQ9Yi5sZWZ0LWgubGVmdCtlKSwidXNpbmciaW4gYj9iLnVzaW5nLmNhbGwoYSxtKTpsLmNzcyhtKX19LHIuZm4uZXh0ZW5kKHtvZmZzZXQ6ZnVuY3Rpb24oYSl7aWYoYXJndW1lbnRzLmxlbmd0aClyZXR1cm4gdm9pZCAwPT09YT90aGlzOnRoaXMuZWFjaChmdW5jdGlvbihiKXtyLm9mZnNldC5zZXRPZmZzZXQodGhpcyxhLGIpfSk7dmFyIGIsYyxkLGUsZj10aGlzWzBdO2lmKGYpcmV0dXJuIGYuZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGg/KGQ9Zi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxkLndpZHRofHxkLmhlaWdodD8oZT1mLm93bmVyRG9jdW1lbnQsYz1TYihlKSxiPWUuZG9jdW1lbnRFbGVtZW50LHt0b3A6ZC50b3ArYy5wYWdlWU9mZnNldC1iLmNsaWVudFRvcCxsZWZ0OmQubGVmdCtjLnBhZ2VYT2Zmc2V0LWIuY2xpZW50TGVmdH0pOmQpOnt0b3A6MCxsZWZ0OjB9fSxwb3NpdGlvbjpmdW5jdGlvbigpe2lmKHRoaXNbMF0pe3ZhciBhLGIsYz10aGlzWzBdLGQ9e3RvcDowLGxlZnQ6MH07cmV0dXJuImZpeGVkIj09PXIuY3NzKGMsInBvc2l0aW9uIik/Yj1jLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOihhPXRoaXMub2Zmc2V0UGFyZW50KCksYj10aGlzLm9mZnNldCgpLHIubm9kZU5hbWUoYVswXSwiaHRtbCIpfHwoZD1hLm9mZnNldCgpKSxkPXt0b3A6ZC50b3Arci5jc3MoYVswXSwiYm9yZGVyVG9wV2lkdGgiLCEwKSxsZWZ0OmQubGVmdCtyLmNzcyhhWzBdLCJib3JkZXJMZWZ0V2lkdGgiLCEwKX0pLHt0b3A6Yi50b3AtZC50b3Atci5jc3MoYywibWFyZ2luVG9wIiwhMCksbGVmdDpiLmxlZnQtZC5sZWZ0LXIuY3NzKGMsIm1hcmdpbkxlZnQiLCEwKX19fSxvZmZzZXRQYXJlbnQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24oKXt2YXIgYT10aGlzLm9mZnNldFBhcmVudDt3aGlsZShhJiYic3RhdGljIj09PXIuY3NzKGEsInBvc2l0aW9uIikpYT1hLm9mZnNldFBhcmVudDtyZXR1cm4gYXx8cGF9KX19KSxyLmVhY2goe3Njcm9sbExlZnQ6InBhZ2VYT2Zmc2V0IixzY3JvbGxUb3A6InBhZ2VZT2Zmc2V0In0sZnVuY3Rpb24oYSxiKXt2YXIgYz0icGFnZVlPZmZzZXQiPT09YjtyLmZuW2FdPWZ1bmN0aW9uKGQpe3JldHVybiBTKHRoaXMsZnVuY3Rpb24oYSxkLGUpe3ZhciBmPVNiKGEpO3JldHVybiB2b2lkIDA9PT1lP2Y/ZltiXTphW2RdOnZvaWQoZj9mLnNjcm9sbFRvKGM/Zi5wYWdlWE9mZnNldDplLGM/ZTpmLnBhZ2VZT2Zmc2V0KTphW2RdPWUpfSxhLGQsYXJndW1lbnRzLmxlbmd0aCl9fSksci5lYWNoKFsidG9wIiwibGVmdCJdLGZ1bmN0aW9uKGEsYil7ci5jc3NIb29rc1tiXT1OYShvLnBpeGVsUG9zaXRpb24sZnVuY3Rpb24oYSxjKXtpZihjKXJldHVybiBjPU1hKGEsYiksS2EudGVzdChjKT9yKGEpLnBvc2l0aW9uKClbYl0rInB4IjpjfSl9KSxyLmVhY2goe0hlaWdodDoiaGVpZ2h0IixXaWR0aDoid2lkdGgifSxmdW5jdGlvbihhLGIpe3IuZWFjaCh7cGFkZGluZzoiaW5uZXIiK2EsY29udGVudDpiLCIiOiJvdXRlciIrYX0sZnVuY3Rpb24oYyxkKXtyLmZuW2RdPWZ1bmN0aW9uKGUsZil7dmFyIGc9YXJndW1lbnRzLmxlbmd0aCYmKGN8fCJib29sZWFuIiE9dHlwZW9mIGUpLGg9Y3x8KGU9PT0hMHx8Zj09PSEwPyJtYXJnaW4iOiJib3JkZXIiKTtyZXR1cm4gUyh0aGlzLGZ1bmN0aW9uKGIsYyxlKXt2YXIgZjtyZXR1cm4gci5pc1dpbmRvdyhiKT8wPT09ZC5pbmRleE9mKCJvdXRlciIpP2JbImlubmVyIithXTpiLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudFsiY2xpZW50IithXTo5PT09Yi5ub2RlVHlwZT8oZj1iLmRvY3VtZW50RWxlbWVudCxNYXRoLm1heChiLmJvZHlbInNjcm9sbCIrYV0sZlsic2Nyb2xsIithXSxiLmJvZHlbIm9mZnNldCIrYV0sZlsib2Zmc2V0IithXSxmWyJjbGllbnQiK2FdKSk6dm9pZCAwPT09ZT9yLmNzcyhiLGMsaCk6ci5zdHlsZShiLGMsZSxoKX0sYixnP2U6dm9pZCAwLGcpfX0pfSksci5mbi5leHRlbmQoe2JpbmQ6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB0aGlzLm9uKGEsbnVsbCxiLGMpfSx1bmJpbmQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5vZmYoYSxudWxsLGIpfSxkZWxlZ2F0ZTpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gdGhpcy5vbihiLGEsYyxkKX0sdW5kZWxlZ2F0ZTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIDE9PT1hcmd1bWVudHMubGVuZ3RoP3RoaXMub2ZmKGEsIioqIik6dGhpcy5vZmYoYixhfHwiKioiLGMpfX0pLHIucGFyc2VKU09OPUpTT04ucGFyc2UsImZ1bmN0aW9uIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZCYmZGVmaW5lKCJqcXVlcnkiLFtdLGZ1bmN0aW9uKCl7cmV0dXJuIHJ9KTt2YXIgVGI9YS5qUXVlcnksVWI9YS4kO3JldHVybiByLm5vQ29uZmxpY3Q9ZnVuY3Rpb24oYil7cmV0dXJuIGEuJD09PXImJihhLiQ9VWIpLGImJmEualF1ZXJ5PT09ciYmKGEualF1ZXJ5PVRiKSxyfSxifHwoYS5qUXVlcnk9YS4kPXIpLHJ9KTsKZGlmZiAtLWdpdCBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9zaWdtYS9wbHVnaW5zL3NpZ21hLnJlbmRlcmVycy5jdXN0b21TaGFwZXMubWluLmpzIGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL3NpZ21hL3NpZ21hLnJlbmRlcmVycy5jdXN0b21TaGFwZXMubWluLmpzCnNpbWlsYXJpdHkgaW5kZXggOTclCnJlbmFtZSBmcm9tIG9wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9zaWdtYS9wbHVnaW5zL3NpZ21hLnJlbmRlcmVycy5jdXN0b21TaGFwZXMubWluLmpzCnJlbmFtZSB0byBvcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vc2lnbWEvc2lnbWEucmVuZGVyZXJzLmN1c3RvbVNoYXBlcy5taW4uanMKaW5kZXggMzYzNzY4OC4uYmNjZWIzOCAxMDA2NDQKLS0tIGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL3NpZ21hL3BsdWdpbnMvc2lnbWEucmVuZGVyZXJzLmN1c3RvbVNoYXBlcy5taW4uanMKKysrIGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL3NpZ21hL3NpZ21hLnJlbmRlcmVycy5jdXN0b21TaGFwZXMubWluLmpzCkBAIC0xICsxLDIgQEAKKy8qIHNpZ21hLnJlbmRlcmVycy5jdXN0b21TaGFwZXMuanMgLSBBIHNpZ21hIHBsdWdpbiBmb3IgY3VzdG9taXplZCBzaGFwZSBkcmF3aW5nLiAtIEF1dGhvcjogUm9uIFBlbGVnICBhbmQgSnVsaWFuIEJpbGNrZSAtIExpY2Vuc2U6IE1JVCAqLwogKGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO3ZhciBhPVtdLGI9ZnVuY3Rpb24oYixjLGQpe2EucHVzaCh7bmFtZTpiLGRyYXdTaGFwZTpjLGRyYXdCb3JkZXI6ZH0pfSxjPWZ1bmN0aW9uKCl7cmV0dXJuIGF9LGQ9ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKGIsYyxkLGUsZixnKXtnLmZpbGxTdHlsZT1mLGcuYmVnaW5QYXRoKCksYShiLGMsZCxlLGcpLGcuY2xvc2VQYXRoKCksZy5maWxsKCl9fSxlPWZ1bmN0aW9uKGEpe3JldHVybiBmdW5jdGlvbihiLGMsZCxlLGYsZyl7Zy5zdHJva2VTdHlsZT1mLGcubGluZVdpZHRoPWUvNSxnLmJlZ2luUGF0aCgpLGEoYixjLGQsZSxnKSxnLmNsb3NlUGF0aCgpLGcuc3Ryb2tlKCl9fSxmPWZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIGY9NDUqTWF0aC5QSS8xODA7ZS5tb3ZlVG8oYitkKk1hdGguc2luKGYpLGMtZCpNYXRoLmNvcyhmKSk7Zm9yKHZhciBnPTE7ND5nO2crKyllLmxpbmVUbyhiK01hdGguc2luKGYrMipNYXRoLlBJKmcvNCkqZCxjLU1hdGguY29zKGYrMipNYXRoLlBJKmcvNCkqZCl9O2IoInNxdWFyZSIsZChmKSxlKGYpKTt2YXIgZz1mdW5jdGlvbihhLGIsYyxkLGUpe2UuYXJjKGIsYyxkLDAsMipNYXRoLlBJLCEwKX07YigiY2lyY2xlIixkKGcpLGUoZykpO3ZhciBoPWZ1bmN0aW9uKGEsYixjLGQsZSl7ZS5tb3ZlVG8oYi1kLGMpLGUubGluZVRvKGIsYy1kKSxlLmxpbmVUbyhiK2QsYyksZS5saW5lVG8oYixjK2QpfTtiKCJkaWFtb25kIixkKGgpLGUoaCkpO3ZhciBpPWZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIGY9YS5jcm9zcyYmYS5jcm9zcy5saW5lV2VpZ2h0fHw1O2UubW92ZVRvKGItZCxjLWYpLGUubGluZVRvKGItZCxjK2YpLGUubGluZVRvKGItZixjK2YpLGUubGluZVRvKGItZixjK2QpLGUubGluZVRvKGIrZixjK2QpLGUubGluZVRvKGIrZixjK2YpLGUubGluZVRvKGIrZCxjK2YpLGUubGluZVRvKGIrZCxjLWYpLGUubGluZVRvKGIrZixjLWYpLGUubGluZVRvKGIrZixjLWQpLGUubGluZVRvKGItZixjLWQpLGUubGluZVRvKGItZixjLWYpfTtiKCJjcm9zcyIsZChpKSxlKGkpKTt2YXIgaj1mdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBmPWEuZXF1aWxhdGVyYWwmJmEuZXF1aWxhdGVyYWwubnVtUG9pbnRzfHw1LGc9KGEuZXF1aWxhdGVyYWwmJmEuZXF1aWxhdGVyYWwucm90YXRlfHwwKSpNYXRoLlBJLzE4MCxoPWQ7ZS5tb3ZlVG8oYitoKk1hdGguc2luKGcpLGMtaCpNYXRoLmNvcyhnKSk7Zm9yKHZhciBpPTE7Zj5pO2krKyllLmxpbmVUbyhiK01hdGguc2luKGcrMipNYXRoLlBJKmkvZikqaCxjLU1hdGguY29zKGcrMipNYXRoLlBJKmkvZikqaCl9O2IoImVxdWlsYXRlcmFsIixkKGopLGUoaikpO3ZhciBrPWZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIGY9YS5zdGFyJiZhLnN0YXIubnVtUG9pbnRzfHw1LGc9YS5zdGFyJiZhLnN0YXIuaW5uZXJSYXRpb3x8LjUsaD1kLGk9ZCpnLGo9TWF0aC5QSS9mO2UubW92ZVRvKGIsYy1kKTtmb3IodmFyIGs9MDtmPms7aysrKWUubGluZVRvKGIrTWF0aC5zaW4oaisyKk1hdGguUEkqay9mKSppLGMtTWF0aC5jb3MoaisyKk1hdGguUEkqay9mKSppKSxlLmxpbmVUbyhiK01hdGguc2luKDIqTWF0aC5QSSooaysxKS9mKSpoLGMtTWF0aC5jb3MoMipNYXRoLlBJKihrKzEpL2YpKmgpfTtiKCJzdGFyIixkKGspLGUoaykpO3ZhciBsPWZ1bmN0aW9uKGEsYixjLGQsZSxmKXtmLmZpbGxTdHlsZT0ieWVsbG93IixmLmJlZ2luUGF0aCgpLGYuYXJjKGIsYyxkLDEuMjUqTWF0aC5QSSwwLCExKSxmLmFyYyhiLGMsZCwwLC43NSpNYXRoLlBJLCExKSxmLmxpbmVUbyhiLGMpLGYuY2xvc2VQYXRoKCksZi5maWxsKCksZi5maWxsU3R5bGU9IndoaXRlIixmLnN0cm9rZVN0eWxlPSJibGFjayIsZi5iZWdpblBhdGgoKSxmLmFyYyhiK2QvMyxjLWQvMyxkLzQsMCwyKk1hdGguUEksITEpLGYuY2xvc2VQYXRoKCksZi5maWxsKCksZi5zdHJva2UoKSxmLmZpbGxTdHlsZT0iYmxhY2siLGYuYmVnaW5QYXRoKCksZi5hcmMoYis0KmQvOSxjLWQvMyxkLzgsMCwyKk1hdGguUEksITEpLGYuY2xvc2VQYXRoKCksZi5maWxsKCl9O2IoInBhY21hbiIsbCxudWxsKSx0aGlzLlNoYXBlTGlicmFyeT17ZW51bWVyYXRlOmMsdmVyc2lvbjoiMC4xIn19KS5jYWxsKHRoaXMpLGZ1bmN0aW9uKGEpeyJ1c2Ugc3RyaWN0IjtpZigidW5kZWZpbmVkIj09dHlwZW9mIHNpZ21hKXRocm93InNpZ21hIGlzIG5vdCBkZWNsYXJlZCI7aWYoInVuZGVmaW5lZCI9PXR5cGVvZiBTaGFwZUxpYnJhcnkpdGhyb3ciU2hhcGVMaWJyYXJ5IGlzIG5vdCBkZWNsYXJlZCI7c2lnbWEudXRpbHMucGtnKCJzaWdtYS5jYW52YXMubm9kZXMiKSxzaWdtYS51dGlscy5wa2coInNpZ21hLnN2Zy5ub2RlcyIpO3ZhciBiPWEsYz17fSxkPWZ1bmN0aW9uKGEpe2I9YX0sZT1mdW5jdGlvbihhLGQsZSxmLGcpe2lmKGImJmEuaW1hZ2UmJmEuaW1hZ2UudXJsKXt2YXIgaD1hLmltYWdlLnVybCxpPWEuaW1hZ2UuaHx8MSxqPWEuaW1hZ2Uud3x8MSxrPWEuaW1hZ2Uuc2NhbGV8fDEsbD1hLmltYWdlLmNsaXB8fDEsbT1jW2hdO218fChtPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIklNRyIpLG0uc3JjPWgsbS5zdGF0dXM9ImxvYWRpbmciLG0ub25lcnJvcj1mdW5jdGlvbigpe2NvbnNvbGUubG9nKCJlcnJvciBsb2FkaW5nIixoKSxtLnN0YXR1cz0iZXJyb3IifSxtLm9ubG9hZD1mdW5jdGlvbigpe2NvbnNvbGUubG9nKCJyZWRyYXcgb24gaW1hZ2UgbG9hZCIsaCksbS5zdGF0dXM9Im9rIixiLnJlZnJlc2goKX0sY1toXT1tKTt2YXIgbj1pPmo/ai9pOjEsbz1qPmk/aS9qOjEscD1mKms7Zy5zYXZlKCksZy5iZWdpblBhdGgoKSxnLmFyYyhkLGUsZipsLDAsMipNYXRoLlBJLCEwKSxnLmNsb3NlUGF0aCgpLGcuY2xpcCgpLCJvayI9PT1tLnN0YXR1cyYmZy5kcmF3SW1hZ2UobSxkK01hdGguc2luKC0wLjc4NTUpKnAqbixlLU1hdGguY29zKC0wLjc4NTUpKnAqbyxwKm4qMipNYXRoLnNpbigtMC43ODU1KSotMSxwKm8qMipNYXRoLmNvcygtMC43ODU1KSksZy5yZXN0b3JlKCl9fSxmPWZ1bmN0aW9uKGEsYyxkKXtpZihiJiZhLmltYWdlJiZhLmltYWdlLnVybCl7e3ZhciBlPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhkKCJ4bWxucyIpLCJjaXJjbGUiKSxmPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhkKCJ4bWxucyIpLCJjbGlwUGF0aCIpLGc9ZCgiY2xhc3NQcmVmaXgiKSsiLWNsaXAtcGF0aC0iK2EuaWQsaD1kb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoZCgieG1sbnMiKSwiZGVmcyIpLGk9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKGQoInhtbG5zIiksImltYWdlIik7YS5pbWFnZS51cmx9Zi5zZXRBdHRyaWJ1dGVOUyhudWxsLCJpZCIsZyksZi5hcHBlbmRDaGlsZChlKSxoLmFwcGVuZENoaWxkKGYpO3ZhciBqPS9NU0lFIFs1LTldLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpPyIiOmRvY3VtZW50LmxvY2F0aW9uLmhyZWY7aj1qLnNwbGl0KCIjIilbMF0saS5zZXRBdHRyaWJ1dGVOUyhudWxsLCJjbGFzcyIsZCgiY2xhc3NQcmVmaXgiKSsiLW5vZGUtaW1hZ2UiKSxpLnNldEF0dHJpYnV0ZU5TKG51bGwsImNsaXAtcGF0aCIsInVybCgiK2orIiMiK2crIikiKSxpLnNldEF0dHJpYnV0ZU5TKG51bGwsInBvaW50ZXItZXZlbnRzIiwibm9uZSIpLGkuc2V0QXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiLCJocmVmIixhLmltYWdlLnVybCksYy5hcHBlbmRDaGlsZChoKSxjLmFwcGVuZENoaWxkKGkpfX0sZz1mdW5jdGlvbihhLGIsYyl7c2lnbWEuY2FudmFzLm5vZGVzW2FdPWZ1bmN0aW9uKGEsZCxmKXt2YXIgZz1mKCJwcmVmaXgiKXx8IiIsaD1hW2crInNpemUiXSxpPWEuY29sb3J8fGYoImRlZmF1bHROb2RlQ29sb3IiKSxqPWEuYm9yZGVyQ29sb3J8fGksaz1hW2crIngiXSxsPWFbZysieSJdO2Quc2F2ZSgpLGImJmIoYSxrLGwsaCxpLGQpLGMmJmMoYSxrLGwsaCxqLGQpLGUoYSxrLGwsaCxkKSxkLnJlc3RvcmUoKX0sc2lnbWEuc3ZnLm5vZGVzW2FdPXtjcmVhdGU6ZnVuY3Rpb24oYSxiKXt2YXIgYz1kb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoYigieG1sbnMiKSwiZyIpLGQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKGIoInhtbG5zIiksImNpcmNsZSIpO3JldHVybiBjLnNldEF0dHJpYnV0ZU5TKG51bGwsImNsYXNzIixiKCJjbGFzc1ByZWZpeCIpKyItbm9kZS1ncm91cCIpLGMuc2V0QXR0cmlidXRlTlMobnVsbCwiZGF0YS1ub2RlLWlkIixhLmlkKSxkLnNldEF0dHJpYnV0ZU5TKG51bGwsImRhdGEtbm9kZS1pZCIsYS5pZCksZC5zZXRBdHRyaWJ1dGVOUyhudWxsLCJjbGFzcyIsYigiY2xhc3NQcmVmaXgiKSsiLW5vZGUiKSxkLnNldEF0dHJpYnV0ZU5TKG51bGwsImZpbGwiLGEuY29sb3J8fGIoImRlZmF1bHROb2RlQ29sb3IiKSksYy5hcHBlbmRDaGlsZChkKSxmKGEsYyxiKSxjfSx1cGRhdGU6ZnVuY3Rpb24oYSxiLGMpe2Zvcih2YXIgZD1jKCJjbGFzc1ByZWZpeCIpLGU9YS5pbWFnZS5jbGlwfHwxLGY9YS5pbWFnZS5ofHwxLGc9YS5pbWFnZS53fHwxLGg9YygicHJlZml4Iil8fCIiLGk9YS5pbWFnZS5zY2FsZXx8MSxqPWFbaCsic2l6ZSJdLGs9YVtoKyJ4Il0sbD1hW2grInkiXSxtPWkqaixuPWY+Zz9nL2Y6MSxvPWc+Zj9mL2c6MSxwPTAscT1iLmNoaWxkTm9kZXM7cDxxLmxlbmd0aDtwKyspe3ZhciByPXFbcF0uZ2V0QXR0cmlidXRlKCJjbGFzcyIpO3N3aXRjaChyKXtjYXNlIGQrIi1ub2RlIjpxW3BdLnNldEF0dHJpYnV0ZU5TKG51bGwsImN4IixrKSxxW3BdLnNldEF0dHJpYnV0ZU5TKG51bGwsImN5IixsKSxxW3BdLnNldEF0dHJpYnV0ZU5TKG51bGwsInIiLGopLGMoImZyZWVTdHlsZSIpfHxxW3BdLnNldEF0dHJpYnV0ZU5TKG51bGwsImZpbGwiLGEuY29sb3J8fGMoImRlZmF1bHROb2RlQ29sb3IiKSk7YnJlYWs7Y2FzZSBkKyItbm9kZS1pbWFnZSI6cVtwXS5zZXRBdHRyaWJ1dGVOUyhudWxsLCJ4IixrK01hdGguc2luKC0wLjc4NTUpKm0qbikscVtwXS5zZXRBdHRyaWJ1dGVOUyhudWxsLCJ5IixsLU1hdGguY29zKC0wLjc4NTUpKm0qbykscVtwXS5zZXRBdHRyaWJ1dGVOUyhudWxsLCJ3aWR0aCIsbSpuKjIqTWF0aC5zaW4oLTAuNzg1NSkqLTEpLHFbcF0uc2V0QXR0cmlidXRlTlMobnVsbCwiaGVpZ2h0IixtKm8qMipNYXRoLmNvcygtMC43ODU1KSk7YnJlYWs7ZGVmYXVsdDp2YXIgcz1xW3BdLmZpcnN0Q2hpbGQ7aWYobnVsbCE9cyl7dmFyIHQ9ZCsiLWNsaXAtcGF0aC0iK2EuaWQ7cy5nZXRBdHRyaWJ1dGUoImlkIik9PT10JiYocy5maXJzdENoaWxkLnNldEF0dHJpYnV0ZU5TKG51bGwsImN4IixrKSxzLmZpcnN0Q2hpbGQuc2V0QXR0cmlidXRlTlMobnVsbCwiY3kiLGwpLHMuZmlyc3RDaGlsZC5zZXRBdHRyaWJ1dGVOUyhudWxsLCJyIixlKmopKX19fWIuc3R5bGUuZGlzcGxheT0iIn19fTtTaGFwZUxpYnJhcnkuZW51bWVyYXRlKCkuZm9yRWFjaChmdW5jdGlvbihhKXtnKGEubmFtZSxhLmRyYXdTaGFwZSxhLmRyYXdCb3JkZXIpfSksdGhpcy5DdXN0b21TaGFwZXM9e2luaXQ6ZCx2ZXJzaW9uOiIwLjEifX0uY2FsbCh0aGlzKTsKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vc2lnbWEvcGx1Z2lucy9zaWdtYS5yZW5kZXJlcnMuZWRnZUxhYmVscy5taW4uanMgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vc2lnbWEvc2lnbWEucmVuZGVyZXJzLmVkZ2VMYWJlbHMubWluLmpzCnNpbWlsYXJpdHkgaW5kZXggOTUlCnJlbmFtZSBmcm9tIG9wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9zaWdtYS9wbHVnaW5zL3NpZ21hLnJlbmRlcmVycy5lZGdlTGFiZWxzLm1pbi5qcwpyZW5hbWUgdG8gb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL3NpZ21hL3NpZ21hLnJlbmRlcmVycy5lZGdlTGFiZWxzLm1pbi5qcwppbmRleCA1YjZkMDdiLi5lOTg5NGI5IDEwMDY0NAotLS0gYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vc2lnbWEvcGx1Z2lucy9zaWdtYS5yZW5kZXJlcnMuZWRnZUxhYmVscy5taW4uanMKKysrIGIvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9qcy90b3BvL3NpZ21hL3NpZ21hLnJlbmRlcmVycy5lZGdlTGFiZWxzLm1pbi5qcwpAQCAtMSArMSwyIEBACisvKiBzaWdtYS5yZW5kZXJlcnMuZWRnZUxhYmVscy5qcyAtIEEgc2lnbWEgcGx1Z2luIGZvciBlZGdlIGRyYXdpbmcgKHdpdGggbGFiZWwsIGV0Yy4pLiAtIEF1dGhvcjogU+liYXN0aWVuIEhleW1hbm4gLSBMaWNlbnNlOiBNSVQgKi8KIChmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtpZigidW5kZWZpbmVkIj09dHlwZW9mIHNpZ21hKXRocm93InNpZ21hIGlzIG5vdCBkZWNsYXJlZCI7c2lnbWEudXRpbHMucGtnKCJzaWdtYS5zZXR0aW5ncyIpO3ZhciBhPXtkZWZhdWx0RWRnZUxhYmVsQ29sb3I6IiMwMDAiLGRlZmF1bHRFZGdlTGFiZWxBY3RpdmVDb2xvcjoiIzAwMCIsZGVmYXVsdEVkZ2VMYWJlbFNpemU6MTAsZWRnZUxhYmVsU2l6ZToiZml4ZWQiLGVkZ2VMYWJlbFNpemVQb3dSYXRpbzoxLGVkZ2VMYWJlbFRocmVzaG9sZDoxfTtzaWdtYS5zZXR0aW5ncz1zaWdtYS51dGlscy5leHRlbmQoc2lnbWEuc2V0dGluZ3N8fHt9LGEpLHNpZ21hLnNldHRpbmdzLmRyYXdFZGdlTGFiZWxzPSEwfSkuY2FsbCh0aGlzKSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtpZigidW5kZWZpbmVkIj09dHlwZW9mIHNpZ21hKXRocm93InNpZ21hIGlzIG5vdCBkZWNsYXJlZCI7c2lnbWEudXRpbHMucGtnKCJzaWdtYS5jYW52YXMuZWRnZXMubGFiZWxzIiksc2lnbWEuY2FudmFzLmVkZ2VzLmxhYmVscy5jdXJ2ZT1mdW5jdGlvbihhLGIsYyxkLGUpe2lmKCJzdHJpbmciPT10eXBlb2YgYS5sYWJlbCl7dmFyIGY9ZSgicHJlZml4Iil8fCIiLGc9YVtmKyJzaXplIl18fDE7aWYoIShnPGUoImVkZ2VMYWJlbFRocmVzaG9sZCIpKSl7dmFyIGgsaSxqLGs9YltmKyJzaXplIl0sbD1iW2YrIngiXSxtPWJbZisieSJdLG49Y1tmKyJ4Il0sbz1jW2YrInkiXSxwPW4tbCxxPW8tbSxyPW4+bD8xOi0xLHM9e30sdD0uNTtiLmlkPT09Yy5pZD8ocz1zaWdtYS51dGlscy5nZXRTZWxmTG9vcENvbnRyb2xQb2ludHMobCxtLGspLGk9c2lnbWEudXRpbHMuZ2V0UG9pbnRPbkJlemllckN1cnZlKHQsbCxtLG4sbyxzLngxLHMueTEscy54MixzLnkyKSxqPU1hdGguYXRhbjIoMSwxKSk6KHM9c2lnbWEudXRpbHMuZ2V0UXVhZHJhdGljQ29udHJvbFBvaW50KGwsbSxuLG8pLGk9c2lnbWEudXRpbHMuZ2V0UG9pbnRPblF1YWRyYXRpY0N1cnZlKHQsbCxtLG4sbyxzLngscy55KSxqPU1hdGguYXRhbjIocSpyLHAqcikpLGg9ImZpeGVkIj09PWUoImVkZ2VMYWJlbFNpemUiKT9lKCJkZWZhdWx0RWRnZUxhYmVsU2l6ZSIpOmUoImRlZmF1bHRFZGdlTGFiZWxTaXplIikqZypNYXRoLnBvdyhnLC0xL2UoImVkZ2VMYWJlbFNpemVQb3dSYXRpbyIpKSxkLnNhdmUoKSxhLmFjdGl2ZT8oZC5mb250PVtlKCJhY3RpdmVGb250U3R5bGUiKSxoKyJweCIsZSgiYWN0aXZlRm9udCIpfHxlKCJmb250IildLmpvaW4oIiAiKSxkLmZpbGxTdHlsZT0iZWRnZSI9PT1lKCJlZGdlQWN0aXZlQ29sb3IiKT9hLmFjdGl2ZV9jb2xvcnx8ZSgiZGVmYXVsdEVkZ2VBY3RpdmVDb2xvciIpOmUoImRlZmF1bHRFZGdlTGFiZWxBY3RpdmVDb2xvciIpKTooZC5mb250PVtlKCJmb250U3R5bGUiKSxoKyJweCIsZSgiZm9udCIpXS5qb2luKCIgIiksZC5maWxsU3R5bGU9ImVkZ2UiPT09ZSgiZWRnZUxhYmVsQ29sb3IiKT9hLmNvbG9yfHxlKCJkZWZhdWx0RWRnZUNvbG9yIik6ZSgiZGVmYXVsdEVkZ2VMYWJlbENvbG9yIikpLGQudGV4dEFsaWduPSJjZW50ZXIiLGQudGV4dEJhc2VsaW5lPSJhbHBoYWJldGljIixkLnRyYW5zbGF0ZShpLngsaS55KSxkLnJvdGF0ZShqKSxkLmZpbGxUZXh0KGEubGFiZWwsMCwtZy8yLTMpLGQucmVzdG9yZSgpfX19fS5jYWxsKHRoaXMpLGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2lmKCJ1bmRlZmluZWQiPT10eXBlb2Ygc2lnbWEpdGhyb3cic2lnbWEgaXMgbm90IGRlY2xhcmVkIjtzaWdtYS51dGlscy5wa2coInNpZ21hLmNhbnZhcy5lZGdlcy5sYWJlbHMiKSxzaWdtYS5jYW52YXMuZWRnZXMubGFiZWxzLmN1cnZlZEFycm93PWZ1bmN0aW9uKGEsYixjLGQsZSl7c2lnbWEuY2FudmFzLmVkZ2VzLmxhYmVscy5jdXJ2ZShhLGIsYyxkLGUpfX0uY2FsbCh0aGlzKSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtpZigidW5kZWZpbmVkIj09dHlwZW9mIHNpZ21hKXRocm93InNpZ21hIGlzIG5vdCBkZWNsYXJlZCI7c2lnbWEudXRpbHMucGtnKCJzaWdtYS5jYW52YXMuZWRnZXMubGFiZWxzIiksc2lnbWEuY2FudmFzLmVkZ2VzLmxhYmVscy5kZWY9ZnVuY3Rpb24oYSxiLGMsZCxlKXtpZigic3RyaW5nIj09dHlwZW9mIGEubGFiZWwmJmIhPWMpe3ZhciBmPWUoInByZWZpeCIpfHwiIixnPWFbZisic2l6ZSJdfHwxO2lmKCEoZzxlKCJlZGdlTGFiZWxUaHJlc2hvbGQiKSkpe2lmKDA9PT1lKCJlZGdlTGFiZWxTaXplUG93UmF0aW8iKSl0aHJvdyciZWRnZUxhYmVsU2l6ZVBvd1JhdGlvIiBtdXN0IG5vdCBiZSAwLic7dmFyIGgsaT0oYltmKyJ4Il0rY1tmKyJ4Il0pLzIsaj0oYltmKyJ5Il0rY1tmKyJ5Il0pLzIsaz1jW2YrIngiXS1iW2YrIngiXSxsPWNbZisieSJdLWJbZisieSJdLG09YltmKyJ4Il08Y1tmKyJ4Il0/MTotMSxuPU1hdGguYXRhbjIobCptLGsqbSk7aD0iZml4ZWQiPT09ZSgiZWRnZUxhYmVsU2l6ZSIpP2UoImRlZmF1bHRFZGdlTGFiZWxTaXplIik6ZSgiZGVmYXVsdEVkZ2VMYWJlbFNpemUiKSpnKk1hdGgucG93KGcsLTEvZSgiZWRnZUxhYmVsU2l6ZVBvd1JhdGlvIikpLGQuc2F2ZSgpLGEuYWN0aXZlPyhkLmZvbnQ9W2UoImFjdGl2ZUZvbnRTdHlsZSIpLGgrInB4IixlKCJhY3RpdmVGb250Iil8fGUoImZvbnQiKV0uam9pbigiICIpLGQuZmlsbFN0eWxlPSJlZGdlIj09PWUoImVkZ2VBY3RpdmVDb2xvciIpP2EuYWN0aXZlX2NvbG9yfHxlKCJkZWZhdWx0RWRnZUFjdGl2ZUNvbG9yIik6ZSgiZGVmYXVsdEVkZ2VMYWJlbEFjdGl2ZUNvbG9yIikpOihkLmZvbnQ9W2UoImZvbnRTdHlsZSIpLGgrInB4IixlKCJmb250IildLmpvaW4oIiAiKSxkLmZpbGxTdHlsZT0iZWRnZSI9PT1lKCJlZGdlTGFiZWxDb2xvciIpP2EuY29sb3J8fGUoImRlZmF1bHRFZGdlQ29sb3IiKTplKCJkZWZhdWx0RWRnZUxhYmVsQ29sb3IiKSksZC50ZXh0QWxpZ249ImNlbnRlciIsZC50ZXh0QmFzZWxpbmU9ImFscGhhYmV0aWMiLGQudHJhbnNsYXRlKGksaiksZC5yb3RhdGUobiksZC5maWxsVGV4dChhLmxhYmVsLDAsLWcvMi0zKSxkLnJlc3RvcmUoKX19fX0uY2FsbCh0aGlzKTsKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL2pzL3RvcG8vc2lnbWEvc2lnbWEucmVxdWlyZS5qcyBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9zaWdtYS9zaWdtYS5yZXF1aXJlLmpzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhNGVhNzZlLi4wMDAwMDAwCi0tLSBhL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3IvanMvdG9wby9zaWdtYS9zaWdtYS5yZXF1aXJlLmpzCisrKyAvZGV2L251bGwKQEAgLTEsMTIxNjMgKzAsMCBAQAotOyhmdW5jdGlvbiAodW5kZWZpbmVkKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgdmFyIF9faW5zdGFuY2VzID0ge307Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGlzIHRoZSBzaWdtYSBpbnN0YW5jZXMgY29uc3RydWN0b3IuIE9uZSBpbnN0YW5jZSBvZiBzaWdtYSByZXByZXNlbnQKLSAgICAgKiBvbmUgZ3JhcGguIEl0IGlzIHBvc3NpYmxlIHRvIHJlcHJlc2VudCB0aGlzIGdyYXDEpSB3aXRoIHNldmVyYWwgcmVuZGVyZXJzCi0gICAgICogYXQgdGhlIHNhbWUgdGltZS4gQnkgZGVmYXVsdCwgdGhlIGRlZmF1bHQgcmVuZGVyZXIgKFdlYkdMICsgQ2FudmFzCi0gICAgICogcG9seWZpbGwpIHdpbGwgYmUgdXNlZCBhcyB0aGUgb25seSByZW5kZXJlciwgd2l0aCB0aGUgY29udGFpbmVyIHNwZWNpZmllZAotICAgICAqIGluIHRoZSBjb25maWd1cmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtICB7Pyp9ICAgIGNvbmYgVGhlIGNvbmZpZ3VyYXRpb24gb2YgdGhlIGluc3RhbmNlLiBUaGVyZSBhcmUgYSBsb3Qgb2YKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBkaWZmZXJlbnQgcmVjb2duaXplZCBmb3JtcyB0byBpbnN0YW50aWF0ZSBzaWdtYSwgY2hlY2sKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBleGFtcGxlIGZpbGVzLCBkb2N1bWVudGF0aW9uIGluIHRoaXMgZmlsZSBhbmQgdW5pdAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHRlc3RzIHRvIGtub3cgbW9yZS4KLSAgICAgKiBAcmV0dXJuIHtzaWdtYX0gICAgICBUaGUgZnJlc2ggbmV3IHNpZ21hIGluc3RhbmNlLgotICAgICAqCi0gICAgICogSW5zdGFuY2lhdGluZyBzaWdtYToKLSAgICAgKiAqKioqKioqKioqKioqKioqKioqKgotICAgICAqIElmIG5vIHBhcmFtZXRlciBpcyBnaXZlbiB0byB0aGUgY29uc3RydWN0b3IsIHRoZSBpbnN0YW5jZSB3aWxsIGJlIGNyZWF0ZWQKLSAgICAgKiB3aXRob3V0IGFueSByZW5kZXJlciBvciBjYW1lcmEuIEl0IHdpbGwganVzdCBpbnN0YW50aWF0ZSB0aGUgZ3JhcGgsIGFuZAotICAgICAqIG90aGVyIG1vZHVsZXMgd2lsbCBoYXZlIHRvIGJlIGluc3RhbnRpYXRlZCB0aHJvdWdoIHRoZSBwdWJsaWMgbWV0aG9kcywKLSAgICAgKiBsaWtlICJhZGRSZW5kZXJlciIgZXRjOgotICAgICAqCi0gICAgICogID4gczAgPSBuZXcgc2lnbWEoKTsKLSAgICAgKiAgPiBzMC5hZGRSZW5kZXJlcih7Ci0gICAqICA+ICAgdHlwZTogJ2NhbnZhcycsCi0gICAqICA+ICAgY29udGFpbmVyOiAnbXktY29udGFpbmVyLWlkJwotICAgKiAgPiB9KTsKLSAgICAgKgotICAgICAqIEluIG1vc3Qgb2YgdGhlIGNhc2VzLCBzaWdtYSB3aWxsIHNpbXBseSBiZSB1c2VkIHdpdGggdGhlIGRlZmF1bHQgcmVuZGVyZXIuCi0gICAgICogVGhlbiwgc2luY2UgdGhlIG9ubHkgcmVxdWlyZWQgcGFyYW1ldGVyIGlzIHRoZSBET00gY29udGFpbmVyLCB0aGVyZSBhcmUKLSAgICAgKiBzb21lIHNpbXBsZXIgd2F5IHRvIGNhbGwgdGhlIGNvbnN0cnVjdG9yLiBUaGUgZm91ciBmb2xsb3dpbmcgY2FsbHMgZG8gdGhlCi0gICAgICogZXhhY3Qgc2FtZSB0aGluZ3M6Ci0gICAgICoKLSAgICAgKiAgPiBzMSA9IG5ldyBzaWdtYSgnbXktY29udGFpbmVyLWlkJyk7Ci0gICAgICogID4gczIgPSBuZXcgc2lnbWEoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ215LWNvbnRhaW5lci1pZCcpKTsKLSAgICAgKiAgPiBzMyA9IG5ldyBzaWdtYSh7Ci0gICAqICA+ICAgY29udGFpbmVyOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbXktY29udGFpbmVyLWlkJykKLSAgICogID4gfSk7Ci0gICAgICogID4gczQgPSBuZXcgc2lnbWEoewotICAgKiAgPiAgIHJlbmRlcmVyczogW3sKLSAgICogID4gICAgIGNvbnRhaW5lcjogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ215LWNvbnRhaW5lci1pZCcpCi0gICAqICA+ICAgfV0KLSAgICogID4gfSk7Ci0gICAgICoKLSAgICAgKiBSZWNvZ25pemVkIHBhcmFtZXRlcnM6Ci0gICAgICogKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIEhlcmUgaXMgdGhlIGV4aGF1c3RpdmUgbGlzdCBvZiBldmVyeSBhY2NlcHRlZCBwYXJhbWV0ZXJzLCB3aGVuIGNhbGxpbmcgdGhlCi0gICAgICogY29uc3RydWN0b3Igd2l0aCB0byB0b3AgbGV2ZWwgY29uZmlndXJhdGlvbiBvYmplY3QgKGZvdXJ0aCBjYXNlIGluIHRoZQotICAgICAqIHByZXZpb3VzIGV4YW1wbGVzKToKLSAgICAgKgotICAgICAqICAgez9zdHJpbmd9IGlkICAgICAgICBUaGUgaWQgb2YgdGhlIGluc3RhbmNlLiBJdCB3aWxsIGJlIGdlbmVyYXRlZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aWNhbGx5IGlmIG5vdCBzcGVjaWZpZWQuCi0gICAgICogICB7P2FycmF5fSAgcmVuZGVyZXJzIEFuIGFycmF5IGNvbnRhaW5pbmcgb2JqZWN0cyBkZXNjcmliaW5nIHJlbmRlcmVycy4KLSAgICAgKiAgIHs/b2JqZWN0fSBncmFwaCAgICAgQW4gb2JqZWN0IGNvbnRhaW5pbmcgYW4gYXJyYXkgb2Ygbm9kZXMgYW5kIGFuIGFycmF5Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgIG9mIGVkZ2VzLCB0byBhdm9pZCBoYXZpbmcgdG8gYWRkIHRoZW0gYnkgaGFuZCBsYXRlci4KLSAgICAgKiAgIHs/b2JqZWN0fSBzZXR0aW5ncyAgQW4gb2JqZWN0IGNvbnRhaW5pbmcgaW5zdGFuY2Ugc3BlY2lmaWMgc2V0dGluZ3MgdGhhdAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICB3aWxsIG92ZXJyaWRlIHRoZSBkZWZhdWx0IG9uZXMgZGVmaW5lZCBpbiB0aGUgb2JqZWN0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgIHNpZ21hLnNldHRpbmdzLgotICAgICAqLwotICAgIHZhciBzaWdtYSA9IGZ1bmN0aW9uIChjb25mKSB7Ci0gICAgICAgIC8vIExvY2FsIHZhcmlhYmxlczoKLSAgICAgICAgLy8gKioqKioqKioqKioqKioqKgotICAgICAgICB2YXIgaSwKLSAgICAgICAgICAgIGwsCi0gICAgICAgICAgICBhLAotICAgICAgICAgICAgYywKLSAgICAgICAgICAgIG8sCi0gICAgICAgICAgICBpZDsKLQotICAgICAgICBzaWdtYS5jbGFzc2VzLmRpc3BhdGNoZXIuZXh0ZW5kKHRoaXMpOwotCi0gICAgICAgIC8vIFByaXZhdGUgYXR0cmlidXRlczoKLSAgICAgICAgLy8gKioqKioqKioqKioqKioqKioqKgotICAgICAgICB2YXIgX3NlbGYgPSB0aGlzLAotICAgICAgICAgICAgX2NvbmYgPSBjb25mIHx8IHt9OwotCi0gICAgICAgIC8vIExpdHRsZSBzaG9ydGN1dDoKLSAgICAgICAgLy8gKioqKioqKioqKioqKioqKgotICAgICAgICAvLyBUaGUgY29uZmlndXJhdGlvbiBpcyBzdXBwb3NlZCB0byBoYXZlIGEgbGlzdCBvZiB0aGUgY29uZmlndXJhdGlvbgotICAgICAgICAvLyBvYmplY3RzIGZvciBlYWNoIHJlbmRlcmVyLgotICAgICAgICAvLyAgLSBJZiB0aGVyZSBhcmUgbm8gY29uZmlndXJhdGlvbiBhdCBhbGwsIHRoZW4gbm90aGluZyBpcyBkb25lLgotICAgICAgICAvLyAgLSBJZiB0aGVyZSBhcmUgbm8gcmVuZGVyZXIgbGlzdCwgdGhlIGdpdmVuIGNvbmZpZ3VyYXRpb24gb2JqZWN0IHdpbGwgYmUKLSAgICAgICAgLy8gICAgY29uc2lkZXJlZCBhcyBkZXNjcmliaW5nIHRoZSBmaXJzdCBhbmQgb25seSByZW5kZXJlci4KLSAgICAgICAgLy8gIC0gSWYgdGhlcmUgYXJlIG5vIHJlbmRlcmVyIGxpc3Qgbm9yICJjb250YWluZXIiIG9iamVjdCwgaXQgd2lsbCBiZQotICAgICAgICAvLyAgICBjb25zaWRlcmVkIGFzIHRoZSBjb250YWluZXIgaXRzZWxmIChhIERPTSBlbGVtZW50KS4KLSAgICAgICAgLy8gIC0gSWYgdGhlIGFyZ3VtZW50IHBhc3NlZCB0byBzaWdtYSgpIGlzIGEgc3RyaW5nLCBpdCB3aWxsIGJlIGNvbnNpZGVyZWQKLSAgICAgICAgLy8gICAgYXMgdGhlIElEIG9mIHRoZSBET00gY29udGFpbmVyLgotICAgICAgICBpZiAoCi0gICAgICAgICAgICB0eXBlb2YgX2NvbmYgPT09ICdzdHJpbmcnIHx8Ci0gICAgICAgICAgICBfY29uZiBpbnN0YW5jZW9mIEhUTUxFbGVtZW50Ci0gICAgICAgICkKLSAgICAgICAgICAgIF9jb25mID0gewotICAgICAgICAgICAgICAgIHJlbmRlcmVyczogW19jb25mXQotICAgICAgICAgICAgfTsKLSAgICAgICAgZWxzZSBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKF9jb25mKSA9PT0gJ1tvYmplY3QgQXJyYXldJykKLSAgICAgICAgICAgIF9jb25mID0gewotICAgICAgICAgICAgICAgIHJlbmRlcmVyczogX2NvbmYKLSAgICAgICAgICAgIH07Ci0KLSAgICAgICAgLy8gQWxzbyBjaGVjayAicmVuZGVyZXIiIGFuZCAiY29udGFpbmVyIiBrZXlzOgotICAgICAgICBvID0gX2NvbmYucmVuZGVyZXJzIHx8IF9jb25mLnJlbmRlcmVyIHx8IF9jb25mLmNvbnRhaW5lcjsKLSAgICAgICAgaWYgKCFfY29uZi5yZW5kZXJlcnMgfHwgX2NvbmYucmVuZGVyZXJzLmxlbmd0aCA9PT0gMCkKLSAgICAgICAgICAgIGlmICgKLSAgICAgICAgICAgICAgICB0eXBlb2YgbyA9PT0gJ3N0cmluZycgfHwKLSAgICAgICAgICAgICAgICBvIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgfHwKLSAgICAgICAgICAgICAgICAodHlwZW9mIG8gPT09ICdvYmplY3QnICYmICdjb250YWluZXInIGluIG8pCi0gICAgICAgICAgICApCi0gICAgICAgICAgICAgICAgX2NvbmYucmVuZGVyZXJzID0gW29dOwotCi0gICAgICAgIC8vIFJlY2Vuc2UgdGhlIGluc3RhbmNlOgotICAgICAgICBpZiAoX2NvbmYuaWQpIHsKLSAgICAgICAgICAgIGlmIChfX2luc3RhbmNlc1tfY29uZi5pZF0pCi0gICAgICAgICAgICAgICAgdGhyb3cgJ3NpZ21hOiBJbnN0YW5jZSAiJyArIF9jb25mLmlkICsgJyIgYWxyZWFkeSBleGlzdHMuJzsKLSAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnaWQnLCB7Ci0gICAgICAgICAgICAgICAgdmFsdWU6IF9jb25mLmlkCi0gICAgICAgICAgICB9KTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlkID0gMDsKLSAgICAgICAgICAgIHdoaWxlIChfX2luc3RhbmNlc1tpZF0pCi0gICAgICAgICAgICAgICAgaWQrKzsKLSAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnaWQnLCB7Ci0gICAgICAgICAgICAgICAgdmFsdWU6ICcnICsgaWQKLSAgICAgICAgICAgIH0pOwotICAgICAgICB9Ci0gICAgICAgIF9faW5zdGFuY2VzW3RoaXMuaWRdID0gdGhpczsKLQotICAgICAgICAvLyBJbml0aWFsaXplIHNldHRpbmdzIGZ1bmN0aW9uOgotICAgICAgICB0aGlzLnNldHRpbmdzID0gbmV3IHNpZ21hLmNsYXNzZXMuY29uZmlndXJhYmxlKAotICAgICAgICAgICAgc2lnbWEuc2V0dGluZ3MsCi0gICAgICAgICAgICBfY29uZi5zZXR0aW5ncyB8fCB7fQotICAgICAgICApOwotCi0gICAgICAgIC8vIEluaXRpYWxpemUgbG9ja2VkIGF0dHJpYnV0ZXM6Ci0gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZ3JhcGgnLCB7Ci0gICAgICAgICAgICB2YWx1ZTogbmV3IHNpZ21hLmNsYXNzZXMuZ3JhcGgodGhpcy5zZXR0aW5ncyksCi0gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUKLSAgICAgICAgfSk7Ci0gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnbWlkZGxld2FyZXMnLCB7Ci0gICAgICAgICAgICB2YWx1ZTogW10sCi0gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUKLSAgICAgICAgfSk7Ci0gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnY2FtZXJhcycsIHsKLSAgICAgICAgICAgIHZhbHVlOiB7fSwKLSAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQotICAgICAgICB9KTsKLSAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdyZW5kZXJlcnMnLCB7Ci0gICAgICAgICAgICB2YWx1ZToge30sCi0gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUKLSAgICAgICAgfSk7Ci0gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncmVuZGVyZXJzUGVyQ2FtZXJhJywgewotICAgICAgICAgICAgdmFsdWU6IHt9LAotICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlCi0gICAgICAgIH0pOwotICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2NhbWVyYUZyYW1lcycsIHsKLSAgICAgICAgICAgIHZhbHVlOiB7fSwKLSAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQotICAgICAgICB9KTsKLSAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdjYW1lcmEnLCB7Ci0gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jYW1lcmFzWzBdOwotICAgICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdldmVudHMnLCB7Ci0gICAgICAgICAgICB2YWx1ZTogWwotICAgICAgICAgICAgICAgICdjbGljaycsCi0gICAgICAgICAgICAgICAgJ3JpZ2h0Q2xpY2snLAotICAgICAgICAgICAgICAgICdjbGlja1N0YWdlJywKLSAgICAgICAgICAgICAgICAnZG91YmxlQ2xpY2tTdGFnZScsCi0gICAgICAgICAgICAgICAgJ3JpZ2h0Q2xpY2tTdGFnZScsCi0gICAgICAgICAgICAgICAgJ2NsaWNrTm9kZScsCi0gICAgICAgICAgICAgICAgJ2NsaWNrTm9kZXMnLAotICAgICAgICAgICAgICAgICdkb3VibGVDbGlja05vZGUnLAotICAgICAgICAgICAgICAgICdkb3VibGVDbGlja05vZGVzJywKLSAgICAgICAgICAgICAgICAncmlnaHRDbGlja05vZGUnLAotICAgICAgICAgICAgICAgICdyaWdodENsaWNrTm9kZXMnLAotICAgICAgICAgICAgICAgICdvdmVyTm9kZScsCi0gICAgICAgICAgICAgICAgJ292ZXJOb2RlcycsCi0gICAgICAgICAgICAgICAgJ291dE5vZGUnLAotICAgICAgICAgICAgICAgICdvdXROb2RlcycsCi0gICAgICAgICAgICAgICAgJ2Rvd25Ob2RlJywKLSAgICAgICAgICAgICAgICAnZG93bk5vZGVzJywKLSAgICAgICAgICAgICAgICAndXBOb2RlJywKLSAgICAgICAgICAgICAgICAndXBOb2RlcycKLSAgICAgICAgICAgIF0sCi0gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUKLSAgICAgICAgfSk7Ci0KLSAgICAgICAgLy8gQWRkIGEgY3VzdG9tIGhhbmRsZXIsIHRvIHJlZGlzcGF0Y2ggZXZlbnRzIGZyb20gcmVuZGVyZXJzOgotICAgICAgICB0aGlzLl9oYW5kbGVyID0gKGZ1bmN0aW9uIChlKSB7Ci0gICAgICAgICAgICB2YXIgaywKLSAgICAgICAgICAgICAgICBkYXRhID0ge307Ci0KLSAgICAgICAgICAgIGZvciAoayBpbiBlLmRhdGEpCi0gICAgICAgICAgICAgICAgZGF0YVtrXSA9IGUuZGF0YVtrXTsKLQotICAgICAgICAgICAgZGF0YS5yZW5kZXJlciA9IGUudGFyZ2V0OwotICAgICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGUudHlwZSwgZGF0YSk7Ci0gICAgICAgIH0pLmJpbmQodGhpcyk7Ci0KLSAgICAgICAgLy8gSW5pdGlhbGl6ZSByZW5kZXJlcnM6Ci0gICAgICAgIGEgPSBfY29uZi5yZW5kZXJlcnMgfHwgW107Ci0gICAgICAgIGZvciAoaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgIHRoaXMuYWRkUmVuZGVyZXIoYVtpXSk7Ci0KLSAgICAgICAgLy8gSW5pdGlhbGl6ZSBtaWRkbGV3YXJlczoKLSAgICAgICAgYSA9IF9jb25mLm1pZGRsZXdhcmVzIHx8IFtdOwotICAgICAgICBmb3IgKGkgPSAwLCBsID0gYS5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICB0aGlzLm1pZGRsZXdhcmVzLnB1c2goCi0gICAgICAgICAgICAgICAgdHlwZW9mIGFbaV0gPT09ICdzdHJpbmcnID8KLSAgICAgICAgICAgICAgICAgICAgc2lnbWEubWlkZGxld2FyZXNbYVtpXV0gOgotICAgICAgICAgICAgICAgICAgICBhW2ldCi0gICAgICAgICAgICApOwotCi0gICAgICAgIC8vIENoZWNrIGlmIHRoZXJlIGlzIGFscmVhZHkgYSBncmFwaCB0byBmaWxsIGluOgotICAgICAgICBpZiAodHlwZW9mIF9jb25mLmdyYXBoID09PSAnb2JqZWN0JyAmJiBfY29uZi5ncmFwaCkgewotICAgICAgICAgICAgdGhpcy5ncmFwaC5yZWFkKF9jb25mLmdyYXBoKTsKLQotICAgICAgICAgICAgLy8gSWYgYSBncmFwaCBpcyBnaXZlbiB0byB0aGUgdG8gdGhlIGluc3RhbmNlLCB0aGUgInJlZnJlc2giIG1ldGhvZCBpcwotICAgICAgICAgICAgLy8gZGlyZWN0bHkgY2FsbGVkOgotICAgICAgICAgICAgdGhpcy5yZWZyZXNoKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBEZWFsIHdpdGggcmVzaXplOgotICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgZnVuY3Rpb24gKCkgewotICAgICAgICAgICAgaWYgKF9zZWxmLnNldHRpbmdzKQotICAgICAgICAgICAgICAgIF9zZWxmLnJlZnJlc2goKTsKLSAgICAgICAgfSk7Ci0gICAgfTsKLQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2RzIHdpbGwgaW5zdGFudGlhdGUgYW5kIHJlZmVyZW5jZSBhIG5ldyBjYW1lcmEuIElmIG5vIGlkIGlzCi0gICAgICogc3BlY2lmaWVkLCB0aGVuIGFuIGF1dG9tYXRpYyBpZCB3aWxsIGJlIGdlbmVyYXRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgez9zdHJpbmd9ICAgICAgICAgICAgICBpZCBFdmVudHVhbGx5IHRoZSBjYW1lcmEgaWQuCi0gICAgICogQHJldHVybiB7c2lnbWEuY2xhc3Nlcy5jYW1lcmF9ICAgIFRoZSBmcmVzaCBuZXcgY2FtZXJhIGluc3RhbmNlLgotICAgICAqLwotICAgIHNpZ21hLnByb3RvdHlwZS5hZGRDYW1lcmEgPSBmdW5jdGlvbiAoaWQpIHsKLSAgICAgICAgdmFyIHNlbGYgPSB0aGlzLAotICAgICAgICAgICAgY2FtZXJhOwotCi0gICAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgewotICAgICAgICAgICAgaWQgPSAwOwotICAgICAgICAgICAgd2hpbGUgKHRoaXMuY2FtZXJhc1snJyArIGlkXSkKLSAgICAgICAgICAgICAgICBpZCsrOwotICAgICAgICAgICAgaWQgPSAnJyArIGlkOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHRoaXMuY2FtZXJhc1tpZF0pCi0gICAgICAgICAgICB0aHJvdyAnc2lnbWEuYWRkQ2FtZXJhOiBUaGUgY2FtZXJhICInICsgaWQgKyAnIiBhbHJlYWR5IGV4aXN0cy4nOwotCi0gICAgICAgIGNhbWVyYSA9IG5ldyBzaWdtYS5jbGFzc2VzLmNhbWVyYShpZCwgdGhpcy5ncmFwaCwgdGhpcy5zZXR0aW5ncyk7Ci0gICAgICAgIHRoaXMuY2FtZXJhc1tpZF0gPSBjYW1lcmE7Ci0KLSAgICAgICAgLy8gQWRkIGEgcXVhZHRyZWUgdG8gdGhlIGNhbWVyYToKLSAgICAgICAgY2FtZXJhLnF1YWR0cmVlID0gbmV3IHNpZ21hLmNsYXNzZXMucXVhZCgpOwotCi0gICAgICAgIC8vIEFkZCBhbiBlZGdlcXVhZHRyZWUgdG8gdGhlIGNhbWVyYToKLSAgICAgICAgaWYgKHNpZ21hLmNsYXNzZXMuZWRnZXF1YWQgIT09IHVuZGVmaW5lZCkgewotICAgICAgICAgICAgY2FtZXJhLmVkZ2VxdWFkdHJlZSA9IG5ldyBzaWdtYS5jbGFzc2VzLmVkZ2VxdWFkKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBjYW1lcmEuYmluZCgnY29vcmRpbmF0ZXNVcGRhdGVkJywgZnVuY3Rpb24gKGUpIHsKLSAgICAgICAgICAgIHNlbGYucmVuZGVyQ2FtZXJhKGNhbWVyYSwgY2FtZXJhLmlzQW5pbWF0ZWQpOwotICAgICAgICB9KTsKLQotICAgICAgICB0aGlzLnJlbmRlcmVyc1BlckNhbWVyYVtpZF0gPSBbXTsKLQotICAgICAgICByZXR1cm4gY2FtZXJhOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBraWxscyBhIGNhbWVyYSwgYW5kIGV2ZXJ5IHJlbmRlcmVyIGF0dGFjaGVkIHRvIGl0LgotICAgICAqCi0gICAgICogQHBhcmFtICB7c3RyaW5nfGNhbWVyYX0gdiBUaGUgY2FtZXJhIHRvIGtpbGwgb3IgaXRzIElELgotICAgICAqIEByZXR1cm4ge3NpZ21hfSAgICAgICAgICAgUmV0dXJucyB0aGUgaW5zdGFuY2UuCi0gICAgICovCi0gICAgc2lnbWEucHJvdG90eXBlLmtpbGxDYW1lcmEgPSBmdW5jdGlvbiAodikgewotICAgICAgICB2ID0gdHlwZW9mIHYgPT09ICdzdHJpbmcnID8gdGhpcy5jYW1lcmFzW3ZdIDogdjsKLQotICAgICAgICBpZiAoIXYpCi0gICAgICAgICAgICB0aHJvdyAnc2lnbWEua2lsbENhbWVyYTogVGhlIGNhbWVyYSBpcyB1bmRlZmluZWQuJzsKLQotICAgICAgICB2YXIgaSwKLSAgICAgICAgICAgIGwsCi0gICAgICAgICAgICBhID0gdGhpcy5yZW5kZXJlcnNQZXJDYW1lcmFbdi5pZF07Ci0KLSAgICAgICAgZm9yIChsID0gYS5sZW5ndGgsIGkgPSBsIC0gMTsgaSA+PSAwOyBpLS0pCi0gICAgICAgICAgICB0aGlzLmtpbGxSZW5kZXJlcihhW2ldKTsKLQotICAgICAgICBkZWxldGUgdGhpcy5yZW5kZXJlcnNQZXJDYW1lcmFbdi5pZF07Ci0gICAgICAgIGRlbGV0ZSB0aGlzLmNhbWVyYUZyYW1lc1t2LmlkXTsKLSAgICAgICAgZGVsZXRlIHRoaXMuY2FtZXJhc1t2LmlkXTsKLQotICAgICAgICBpZiAodi5raWxsKQotICAgICAgICAgICAgdi5raWxsKCk7Ci0KLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kcyB3aWxsIGluc3RhbnRpYXRlIGFuZCByZWZlcmVuY2UgYSBuZXcgcmVuZGVyZXIuIFRoZSAidHlwZSIKLSAgICAgKiBhcmd1bWVudCBjYW4gYmUgdGhlIGNvbnN0cnVjdG9yIG9yIGl0cyBuYW1lIGluIHRoZSAic2lnbWEucmVuZGVyZXJzIgotICAgICAqIHBhY2thZ2UuIElmIG5vIHR5cGUgaXMgc3BlY2lmaWVkLCB0aGVuICJzaWdtYS5yZW5kZXJlcnMuZGVmIiB3aWxsIGJlIHVzZWQuCi0gICAgICogSWYgbm8gaWQgaXMgc3BlY2lmaWVkLCB0aGVuIGFuIGF1dG9tYXRpYyBpZCB3aWxsIGJlIGdlbmVyYXRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgez9vYmplY3R9ICBvcHRpb25zIEV2ZW50dWFsbHkgc29tZSBvcHRpb25zIHRvIGdpdmUgdG8gdGhlIHJlbmRlcmVyCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3IuCi0gICAgICogQHJldHVybiB7cmVuZGVyZXJ9ICAgICAgICAgVGhlIGZyZXNoIG5ldyByZW5kZXJlciBpbnN0YW5jZS4KLSAgICAgKgotICAgICAqIFJlY29nbml6ZWQgcGFyYW1ldGVyczoKLSAgICAgKiAqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogSGVyZSBpcyB0aGUgZXhoYXVzdGl2ZSBsaXN0IG9mIGV2ZXJ5IGFjY2VwdGVkIHBhcmFtZXRlcnMgaW4gdGhlICJvcHRpb25zIgotICAgICAqIG9iamVjdDoKLSAgICAgKgotICAgICAqICAgez9zdHJpbmd9ICAgICAgICAgICAgaWQgICAgIEV2ZW50dWFsbHkgdGhlIHJlbmRlcmVyIGlkLgotICAgICAqICAgez8oZnVuY3Rpb258c3RyaW5nKX0gdHlwZSAgIEV2ZW50dWFsbHkgdGhlIHJlbmRlcmVyIGNvbnN0cnVjdG9yIG9yIGl0cwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgaW4gdGhlICJzaWdtYS5yZW5kZXJlcnMiIHBhY2thZ2UuCi0gICAgICogICB7PyhjYW1lcmF8c3RyaW5nKX0gICBjYW1lcmEgRXZlbnR1YWxseSB0aGUgcmVuZGVyZXIgY2FtZXJhIG9yIGl0cwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkLgotICAgICAqLwotICAgIHNpZ21hLnByb3RvdHlwZS5hZGRSZW5kZXJlciA9IGZ1bmN0aW9uIChvcHRpb25zKSB7Ci0gICAgICAgIHZhciBpZCwKLSAgICAgICAgICAgIGZuLAotICAgICAgICAgICAgY2FtZXJhLAotICAgICAgICAgICAgcmVuZGVyZXIsCi0gICAgICAgICAgICBvID0gb3B0aW9ucyB8fCB7fTsKLQotICAgICAgICAvLyBQb2x5bW9ycGhpc206Ci0gICAgICAgIGlmICh0eXBlb2YgbyA9PT0gJ3N0cmluZycpCi0gICAgICAgICAgICBvID0gewotICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQobykKLSAgICAgICAgICAgIH07Ci0gICAgICAgIGVsc2UgaWYgKG8gaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkKLSAgICAgICAgICAgIG8gPSB7Ci0gICAgICAgICAgICAgICAgY29udGFpbmVyOiBvCi0gICAgICAgICAgICB9OwotCi0gICAgICAgIC8vIElmIHRoZSBjb250YWluZXIgc3RpbGwgaXMgYSBzdHJpbmcsIHdlIGdldCBpdCBieSBpZAotICAgICAgICBpZiAodHlwZW9mIG8uY29udGFpbmVyID09PSAnc3RyaW5nJykKLSAgICAgICAgICAgIG8uY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoby5jb250YWluZXIpOwotCi0gICAgICAgIC8vIFJlZmVyZW5jZSB0aGUgbmV3IHJlbmRlcmVyOgotICAgICAgICBpZiAoISgnaWQnIGluIG8pKSB7Ci0gICAgICAgICAgICBpZCA9IDA7Ci0gICAgICAgICAgICB3aGlsZSAodGhpcy5yZW5kZXJlcnNbJycgKyBpZF0pCi0gICAgICAgICAgICAgICAgaWQrKzsKLSAgICAgICAgICAgIGlkID0gJycgKyBpZDsKLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICBpZCA9IG8uaWQ7Ci0KLSAgICAgICAgaWYgKHRoaXMucmVuZGVyZXJzW2lkXSkKLSAgICAgICAgICAgIHRocm93ICdzaWdtYS5hZGRSZW5kZXJlcjogVGhlIHJlbmRlcmVyICInICsgaWQgKyAnIiBhbHJlYWR5IGV4aXN0cy4nOwotCi0gICAgICAgIC8vIEZpbmQgdGhlIGdvb2QgY29uc3RydWN0b3I6Ci0gICAgICAgIGZuID0gdHlwZW9mIG8udHlwZSA9PT0gJ2Z1bmN0aW9uJyA/IG8udHlwZSA6IHNpZ21hLnJlbmRlcmVyc1tvLnR5cGVdOwotICAgICAgICBmbiA9IGZuIHx8IHNpZ21hLnJlbmRlcmVycy5kZWY7Ci0KLSAgICAgICAgLy8gRmluZCB0aGUgZ29vZCBjYW1lcmE6Ci0gICAgICAgIGNhbWVyYSA9ICdjYW1lcmEnIGluIG8gPwotICAgICAgICAgICAgKAotICAgICAgICAgICAgICAgIG8uY2FtZXJhIGluc3RhbmNlb2Ygc2lnbWEuY2xhc3Nlcy5jYW1lcmEgPwotICAgICAgICAgICAgICAgICAgICBvLmNhbWVyYSA6Ci0gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFzW28uY2FtZXJhXSB8fCB0aGlzLmFkZENhbWVyYShvLmNhbWVyYSkKLSAgICAgICAgICAgICkgOgotICAgICAgICAgICAgdGhpcy5hZGRDYW1lcmEoKTsKLQotICAgICAgICBpZiAodGhpcy5jYW1lcmFzW2NhbWVyYS5pZF0gIT09IGNhbWVyYSkKLSAgICAgICAgICAgIHRocm93ICdzaWdtYS5hZGRSZW5kZXJlcjogVGhlIGNhbWVyYSBpcyBub3QgcHJvcGVybHkgcmVmZXJlbmNlZC4nOwotCi0gICAgICAgIC8vIEluc3RhbnRpYXRlOgotICAgICAgICByZW5kZXJlciA9IG5ldyBmbih0aGlzLmdyYXBoLCBjYW1lcmEsIHRoaXMuc2V0dGluZ3MsIG8pOwotICAgICAgICB0aGlzLnJlbmRlcmVyc1tpZF0gPSByZW5kZXJlcjsKLSAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlbmRlcmVyLCAnaWQnLCB7Ci0gICAgICAgICAgICB2YWx1ZTogaWQKLSAgICAgICAgfSk7Ci0KLSAgICAgICAgLy8gQmluZCBldmVudHM6Ci0gICAgICAgIGlmIChyZW5kZXJlci5iaW5kKQotICAgICAgICAgICAgcmVuZGVyZXIuYmluZCgKLSAgICAgICAgICAgICAgICBbCi0gICAgICAgICAgICAgICAgICAgICdjbGljaycsCi0gICAgICAgICAgICAgICAgICAgICdyaWdodENsaWNrJywKLSAgICAgICAgICAgICAgICAgICAgJ2NsaWNrU3RhZ2UnLAotICAgICAgICAgICAgICAgICAgICAnZG91YmxlQ2xpY2tTdGFnZScsCi0gICAgICAgICAgICAgICAgICAgICdyaWdodENsaWNrU3RhZ2UnLAotICAgICAgICAgICAgICAgICAgICAnY2xpY2tOb2RlJywKLSAgICAgICAgICAgICAgICAgICAgJ2NsaWNrTm9kZXMnLAotICAgICAgICAgICAgICAgICAgICAnY2xpY2tFZGdlJywKLSAgICAgICAgICAgICAgICAgICAgJ2NsaWNrRWRnZXMnLAotICAgICAgICAgICAgICAgICAgICAnZG91YmxlQ2xpY2tOb2RlJywKLSAgICAgICAgICAgICAgICAgICAgJ2RvdWJsZUNsaWNrTm9kZXMnLAotICAgICAgICAgICAgICAgICAgICAnZG91YmxlQ2xpY2tFZGdlJywKLSAgICAgICAgICAgICAgICAgICAgJ2RvdWJsZUNsaWNrRWRnZXMnLAotICAgICAgICAgICAgICAgICAgICAncmlnaHRDbGlja05vZGUnLAotICAgICAgICAgICAgICAgICAgICAncmlnaHRDbGlja05vZGVzJywKLSAgICAgICAgICAgICAgICAgICAgJ3JpZ2h0Q2xpY2tFZGdlJywKLSAgICAgICAgICAgICAgICAgICAgJ3JpZ2h0Q2xpY2tFZGdlcycsCi0gICAgICAgICAgICAgICAgICAgICdvdmVyTm9kZScsCi0gICAgICAgICAgICAgICAgICAgICdvdmVyTm9kZXMnLAotICAgICAgICAgICAgICAgICAgICAnb3ZlckVkZ2UnLAotICAgICAgICAgICAgICAgICAgICAnb3ZlckVkZ2VzJywKLSAgICAgICAgICAgICAgICAgICAgJ291dE5vZGUnLAotICAgICAgICAgICAgICAgICAgICAnb3V0Tm9kZXMnLAotICAgICAgICAgICAgICAgICAgICAnb3V0RWRnZScsCi0gICAgICAgICAgICAgICAgICAgICdvdXRFZGdlcycsCi0gICAgICAgICAgICAgICAgICAgICdkb3duTm9kZScsCi0gICAgICAgICAgICAgICAgICAgICdkb3duTm9kZXMnLAotICAgICAgICAgICAgICAgICAgICAnZG93bkVkZ2UnLAotICAgICAgICAgICAgICAgICAgICAnZG93bkVkZ2VzJywKLSAgICAgICAgICAgICAgICAgICAgJ3VwTm9kZScsCi0gICAgICAgICAgICAgICAgICAgICd1cE5vZGVzJywKLSAgICAgICAgICAgICAgICAgICAgJ3VwRWRnZScsCi0gICAgICAgICAgICAgICAgICAgICd1cEVkZ2VzJwotICAgICAgICAgICAgICAgIF0sCi0gICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlcgotICAgICAgICAgICAgKTsKLQotICAgICAgICAvLyBSZWZlcmVuY2UgdGhlIHJlbmRlcmVyIGJ5IGl0cyBjYW1lcmE6Ci0gICAgICAgIHRoaXMucmVuZGVyZXJzUGVyQ2FtZXJhW2NhbWVyYS5pZF0ucHVzaChyZW5kZXJlcik7Ci0KLSAgICAgICAgcmV0dXJuIHJlbmRlcmVyOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBraWxscyBhIHJlbmRlcmVyLgotICAgICAqCi0gICAgICogQHBhcmFtICB7c3RyaW5nfHJlbmRlcmVyfSB2IFRoZSByZW5kZXJlciB0byBraWxsIG9yIGl0cyBJRC4KLSAgICAgKiBAcmV0dXJuIHtzaWdtYX0gICAgICAgICAgICAgUmV0dXJucyB0aGUgaW5zdGFuY2UuCi0gICAgICovCi0gICAgc2lnbWEucHJvdG90eXBlLmtpbGxSZW5kZXJlciA9IGZ1bmN0aW9uICh2KSB7Ci0gICAgICAgIHYgPSB0eXBlb2YgdiA9PT0gJ3N0cmluZycgPyB0aGlzLnJlbmRlcmVyc1t2XSA6IHY7Ci0KLSAgICAgICAgaWYgKCF2KQotICAgICAgICAgICAgdGhyb3cgJ3NpZ21hLmtpbGxSZW5kZXJlcjogVGhlIHJlbmRlcmVyIGlzIHVuZGVmaW5lZC4nOwotCi0gICAgICAgIHZhciBhID0gdGhpcy5yZW5kZXJlcnNQZXJDYW1lcmFbdi5jYW1lcmEuaWRdLAotICAgICAgICAgICAgaSA9IGEuaW5kZXhPZih2KTsKLQotICAgICAgICBpZiAoaSA+PSAwKQotICAgICAgICAgICAgYS5zcGxpY2UoaSwgMSk7Ci0KLSAgICAgICAgaWYgKHYua2lsbCkKLSAgICAgICAgICAgIHYua2lsbCgpOwotCi0gICAgICAgIGRlbGV0ZSB0aGlzLnJlbmRlcmVyc1t2LmlkXTsKLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9OwotCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBjYWxscyB0aGUgInJlbmRlciIgbWV0aG9kIG9mIGVhY2ggcmVuZGVyZXIsIHdpdGggdGhlIHNhbWUKLSAgICAgKiBhcmd1bWVudHMgdGhhbiB0aGUgInJlbmRlciIgbWV0aG9kLCBidXQgd2lsbCBhbHNvIGNoZWNrIGlmIHRoZSByZW5kZXJlcgotICAgICAqIGhhcyBhICJwcm9jZXNzIiBtZXRob2QsIGFuZCBjYWxsIGl0IGlmIGl0IGV4aXN0cy4KLSAgICAgKgotICAgICAqIEl0IGlzIHVzZWZ1bCBmb3IgcXVhZHRyZWVzIG9yIFdlYkdMIHByb2Nlc3NpbmcsIGZvciBpbnN0YW5jZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgez9vYmplY3R9ICBvcHRpb25zIEV2ZW50dWFsbHkgc29tZSBvcHRpb25zIHRvIGdpdmUgdG8gdGhlIHJlZnJlc2gKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QuCi0gICAgICogQHJldHVybiB7c2lnbWF9ICAgICAgICAgICAgUmV0dXJucyB0aGUgaW5zdGFuY2UgaXRzZWxmLgotICAgICAqCi0gICAgICogUmVjb2duaXplZCBwYXJhbWV0ZXJzOgotICAgICAqICoqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBIZXJlIGlzIHRoZSBleGhhdXN0aXZlIGxpc3Qgb2YgZXZlcnkgYWNjZXB0ZWQgcGFyYW1ldGVycyBpbiB0aGUgIm9wdGlvbnMiCi0gICAgICogb2JqZWN0OgotICAgICAqCi0gICAgICogICB7P2Jvb2xlYW59IHNraXBJbmRleGF0aW9uIEEgZmxhZyBzcGVjaWZ5aW5nIHdldGhlciBvciBub3QgdGhlIHJlZnJlc2gKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gc2hvdWxkIHJlaW5kZXggdGhlIGdyYXBoIGluIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWFkdHJlZXMgb3Igbm90IChkZWZhdWx0OiBmYWxzZSkuCi0gICAgICovCi0gICAgc2lnbWEucHJvdG90eXBlLnJlZnJlc2ggPSBmdW5jdGlvbiAob3B0aW9ucykgewotICAgICAgICB2YXIgaSwKLSAgICAgICAgICAgIGwsCi0gICAgICAgICAgICBrLAotICAgICAgICAgICAgYSwKLSAgICAgICAgICAgIGMsCi0gICAgICAgICAgICBib3VuZHMsCi0gICAgICAgICAgICBwcmVmaXggPSAwOwotCi0gICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwotCi0gICAgICAgIC8vIENhbGwgZWFjaCBtaWRkbGV3YXJlOgotICAgICAgICBhID0gdGhpcy5taWRkbGV3YXJlcyB8fCBbXTsKLSAgICAgICAgZm9yIChpID0gMCwgbCA9IGEubGVuZ3RoOyBpIDwgbDsgaSsrKQotICAgICAgICAgICAgYVtpXS5jYWxsKAotICAgICAgICAgICAgICAgIHRoaXMsCi0gICAgICAgICAgICAgICAgKGkgPT09IDApID8gJycgOiAndG1wJyArIHByZWZpeCArICc6JywKLSAgICAgICAgICAgICAgICAoaSA9PT0gbCAtIDEpID8gJ3JlYWR5OicgOiAoJ3RtcCcgKyAoKytwcmVmaXgpICsgJzonKQotICAgICAgICAgICAgKTsKLQotICAgICAgICAvLyBUaGVuLCBmb3IgZWFjaCBjYW1lcmEsIGNhbGwgdGhlICJyZXNjYWxlIiBtaWRkbGV3YXJlLCB1bmxlc3MgdGhlCi0gICAgICAgIC8vIHNldHRpbmdzIHNwZWNpZnkgbm90IHRvOgotICAgICAgICBmb3IgKGsgaW4gdGhpcy5jYW1lcmFzKSB7Ci0gICAgICAgICAgICBjID0gdGhpcy5jYW1lcmFzW2tdOwotICAgICAgICAgICAgaWYgKAotICAgICAgICAgICAgICAgIGMuc2V0dGluZ3MoJ2F1dG9SZXNjYWxlJykgJiYKLSAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyc1BlckNhbWVyYVtjLmlkXSAmJgotICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXJzUGVyQ2FtZXJhW2MuaWRdLmxlbmd0aAotICAgICAgICAgICAgKQotICAgICAgICAgICAgICAgIHNpZ21hLm1pZGRsZXdhcmVzLnJlc2NhbGUuY2FsbCgKLSAgICAgICAgICAgICAgICAgICAgdGhpcywKLSAgICAgICAgICAgICAgICAgICAgYS5sZW5ndGggPyAncmVhZHk6JyA6ICcnLAotICAgICAgICAgICAgICAgICAgICBjLnJlYWRQcmVmaXgsCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiB0aGlzLnJlbmRlcmVyc1BlckNhbWVyYVtjLmlkXVswXS53aWR0aCwKLSAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy5yZW5kZXJlcnNQZXJDYW1lcmFbYy5pZF1bMF0uaGVpZ2h0Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHNpZ21hLm1pZGRsZXdhcmVzLmNvcHkuY2FsbCgKLSAgICAgICAgICAgICAgICAgICAgdGhpcywKLSAgICAgICAgICAgICAgICAgICAgYS5sZW5ndGggPyAncmVhZHk6JyA6ICcnLAotICAgICAgICAgICAgICAgICAgICBjLnJlYWRQcmVmaXgKLSAgICAgICAgICAgICAgICApOwotCi0gICAgICAgICAgICBpZiAoIW9wdGlvbnMuc2tpcEluZGV4YXRpb24pIHsKLSAgICAgICAgICAgICAgICAvLyBGaW5kIGdyYXBoIGJvdW5kYXJpZXM6Ci0gICAgICAgICAgICAgICAgYm91bmRzID0gc2lnbWEudXRpbHMuZ2V0Qm91bmRhcmllcygKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5ncmFwaCwKLSAgICAgICAgICAgICAgICAgICAgYy5yZWFkUHJlZml4Ci0gICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgICAgIC8vIFJlZnJlc2ggcXVhZHRyZWU6Ci0gICAgICAgICAgICAgICAgYy5xdWFkdHJlZS5pbmRleCh0aGlzLmdyYXBoLm5vZGVzKCksIHsKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4OiBjLnJlYWRQcmVmaXgsCi0gICAgICAgICAgICAgICAgICAgIGJvdW5kczogewotICAgICAgICAgICAgICAgICAgICAgICAgeDogYm91bmRzLm1pblgsCi0gICAgICAgICAgICAgICAgICAgICAgICB5OiBib3VuZHMubWluWSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBib3VuZHMubWF4WCAtIGJvdW5kcy5taW5YLAotICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBib3VuZHMubWF4WSAtIGJvdW5kcy5taW5ZCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9KTsKLQotICAgICAgICAgICAgICAgIC8vIFJlZnJlc2ggZWRnZXF1YWR0cmVlOgotICAgICAgICAgICAgICAgIGlmICgKLSAgICAgICAgICAgICAgICAgICAgYy5lZGdlcXVhZHRyZWUgIT09IHVuZGVmaW5lZCAmJgotICAgICAgICAgICAgICAgICAgICBjLnNldHRpbmdzKCdkcmF3RWRnZXMnKSAmJgotICAgICAgICAgICAgICAgICAgICBjLnNldHRpbmdzKCdlbmFibGVFZGdlSG92ZXJpbmcnKQotICAgICAgICAgICAgICAgICkgewotICAgICAgICAgICAgICAgICAgICBjLmVkZ2VxdWFkdHJlZS5pbmRleCh0aGlzLmdyYXBoLCB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXg6IGMucmVhZFByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kczogewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGJvdW5kcy5taW5YLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGJvdW5kcy5taW5ZLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBib3VuZHMubWF4WCAtIGJvdW5kcy5taW5YLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogYm91bmRzLm1heFkgLSBib3VuZHMubWluWQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDYWxsIGVhY2ggcmVuZGVyZXI6Ci0gICAgICAgIGEgPSBPYmplY3Qua2V5cyh0aGlzLnJlbmRlcmVycyk7Ci0gICAgICAgIGZvciAoaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlcmVyc1thW2ldXS5wcm9jZXNzKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MoJ3NraXBFcnJvcnMnKSkKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXJzW2FbaV1dLnByb2Nlc3MoKTsKLSAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1dhcm5pbmc6IFRoZSByZW5kZXJlciAiJyArIGFbaV0gKyAnIiBjcmFzaGVkIG9uICIucHJvY2VzcygpIicKLSAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXJzW2FbaV1dLnByb2Nlc3MoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB0aGlzLnJlbmRlcigpOwotCi0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBjYWxscyB0aGUgInJlbmRlciIgbWV0aG9kIG9mIGVhY2ggcmVuZGVyZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHtzaWdtYX0gUmV0dXJucyB0aGUgaW5zdGFuY2UgaXRzZWxmLgotICAgICAqLwotICAgIHNpZ21hLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7Ci0gICAgICAgIHZhciBpLAotICAgICAgICAgICAgbCwKLSAgICAgICAgICAgIGEsCi0gICAgICAgICAgICBwcmVmaXggPSAwOwotCi0gICAgICAgIC8vIENhbGwgZWFjaCByZW5kZXJlcjoKLSAgICAgICAgYSA9IE9iamVjdC5rZXlzKHRoaXMucmVuZGVyZXJzKTsKLSAgICAgICAgZm9yIChpID0gMCwgbCA9IGEubGVuZ3RoOyBpIDwgbDsgaSsrKQotICAgICAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MoJ3NraXBFcnJvcnMnKSkKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyc1thW2ldXS5yZW5kZXIoKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnNldHRpbmdzKCd2ZXJib3NlJykpCi0gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAnV2FybmluZzogVGhlIHJlbmRlcmVyICInICsgYVtpXSArICciIGNyYXNoZWQgb24gIi5yZW5kZXIoKSInCi0gICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyc1thW2ldXS5yZW5kZXIoKTsKLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgY2FsbHMgdGhlICJyZW5kZXIiIG1ldGhvZCBvZiBlYWNoIHJlbmRlcmVyIHRoYXQgaXMgYm91bmQgdG8KLSAgICAgKiB0aGUgc3BlY2lmaWVkIGNhbWVyYS4gVG8gaW1wcm92ZSB0aGUgcGVyZm9ybWFuY2VzLCBpZiB0aGlzIG1ldGhvZCBpcwotICAgICAqIGNhbGxlZCB0b28gb2Z0ZW4sIHRoZSBudW1iZXIgb2YgZWZmZWN0aXZlIHJlbmRlcmluZ3MgaXMgbGltaXRhdGVkIHRvIG9uZQotICAgICAqIHBlciBmcmFtZSwgdW5sZXNzIHlvdSBhcmUgdXNpbmcgdGhlICJmb3JjZSIgZmxhZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge3NpZ21hLmNsYXNzZXMuY2FtZXJhfSBjYW1lcmEgVGhlIGNhbWVyYSB0byByZW5kZXIuCi0gICAgICogQHBhcmFtICB7P2Jvb2xlYW59ICAgICAgICAgICAgIGZvcmNlICBJZiB0cnVlLCB3aWxsIHJlbmRlciB0aGUgY2FtZXJhCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3RseS4KLSAgICAgKiBAcmV0dXJuIHtzaWdtYX0gICAgICAgICAgICAgICAgICAgICAgIFJldHVybnMgdGhlIGluc3RhbmNlIGl0c2VsZi4KLSAgICAgKi8KLSAgICBzaWdtYS5wcm90b3R5cGUucmVuZGVyQ2FtZXJhID0gZnVuY3Rpb24gKGNhbWVyYSwgZm9yY2UpIHsKLSAgICAgICAgdmFyIGksCi0gICAgICAgICAgICBsLAotICAgICAgICAgICAgYSwKLSAgICAgICAgICAgIHNlbGYgPSB0aGlzOwotCi0gICAgICAgIGlmIChmb3JjZSkgewotICAgICAgICAgICAgYSA9IHRoaXMucmVuZGVyZXJzUGVyQ2FtZXJhW2NhbWVyYS5pZF07Ci0gICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gYS5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MoJ3NraXBFcnJvcnMnKSkKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFbaV0ucmVuZGVyKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnNldHRpbmdzKCd2ZXJib3NlJykpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXYXJuaW5nOiBUaGUgcmVuZGVyZXIgIicgKyBhW2ldLmlkICsgJyIgY3Jhc2hlZCBvbiAiLnJlbmRlcigpIicKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBhW2ldLnJlbmRlcigpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaWYgKCF0aGlzLmNhbWVyYUZyYW1lc1tjYW1lcmEuaWRdKSB7Ci0gICAgICAgICAgICAgICAgYSA9IHRoaXMucmVuZGVyZXJzUGVyQ2FtZXJhW2NhbWVyYS5pZF07Ci0gICAgICAgICAgICAgICAgZm9yIChpID0gMCwgbCA9IGEubGVuZ3RoOyBpIDwgbDsgaSsrKQotICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXR0aW5ncygnc2tpcEVycm9ycycpKQotICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhW2ldLnJlbmRlcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnNldHRpbmdzKCd2ZXJib3NlJykpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1dhcm5pbmc6IFRoZSByZW5kZXJlciAiJyArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhW2ldLmlkICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICciIGNyYXNoZWQgb24gIi5yZW5kZXIoKSInCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIGFbaV0ucmVuZGVyKCk7Ci0KLSAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYUZyYW1lc1tjYW1lcmEuaWRdID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmN0aW9uICgpIHsKLSAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHNlbGYuY2FtZXJhRnJhbWVzW2NhbWVyYS5pZF07Ci0gICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgY2FsbHMgdGhlICJraWxsIiBtZXRob2Qgb2YgZWFjaCBtb2R1bGUgYW5kIGRlc3Ryb3lzIGFueQotICAgICAqIHJlZmVyZW5jZSBmcm9tIHRoZSBpbnN0YW5jZS4KLSAgICAgKi8KLSAgICBzaWdtYS5wcm90b3R5cGUua2lsbCA9IGZ1bmN0aW9uICgpIHsKLSAgICAgICAgdmFyIGs7Ci0KLSAgICAgICAgLy8gRGlzcGF0Y2hpbmcgZXZlbnQKLSAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KCdraWxsJyk7Ci0KLSAgICAgICAgLy8gS2lsbCBncmFwaDoKLSAgICAgICAgdGhpcy5ncmFwaC5raWxsKCk7Ci0KLSAgICAgICAgLy8gS2lsbCBtaWRkbGV3YXJlczoKLSAgICAgICAgZGVsZXRlIHRoaXMubWlkZGxld2FyZXM7Ci0KLSAgICAgICAgLy8gS2lsbCBlYWNoIHJlbmRlcmVyOgotICAgICAgICBmb3IgKGsgaW4gdGhpcy5yZW5kZXJlcnMpCi0gICAgICAgICAgICB0aGlzLmtpbGxSZW5kZXJlcih0aGlzLnJlbmRlcmVyc1trXSk7Ci0KLSAgICAgICAgLy8gS2lsbCBlYWNoIGNhbWVyYToKLSAgICAgICAgZm9yIChrIGluIHRoaXMuY2FtZXJhcykKLSAgICAgICAgICAgIHRoaXMua2lsbENhbWVyYSh0aGlzLmNhbWVyYXNba10pOwotCi0gICAgICAgIGRlbGV0ZSB0aGlzLnJlbmRlcmVyczsKLSAgICAgICAgZGVsZXRlIHRoaXMuY2FtZXJhczsKLQotICAgICAgICAvLyBLaWxsIGV2ZXJ5dGhpbmcgZWxzZToKLSAgICAgICAgZm9yIChrIGluIHRoaXMpCi0gICAgICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShrKSkKLSAgICAgICAgICAgICAgICBkZWxldGUgdGhpc1trXTsKLQotICAgICAgICBkZWxldGUgX19pbnN0YW5jZXNbdGhpcy5pZF07Ci0gICAgfTsKLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGNsb25lIG9mIHRoZSBpbnN0YW5jZXMgb2JqZWN0IG9yIGEgc3BlY2lmaWMgcnVubmluZyBpbnN0YW5jZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgez9zdHJpbmd9IGlkIEV2ZW50dWFsbHkgYW4gaW5zdGFuY2UgSUQuCi0gICAgICogQHJldHVybiB7b2JqZWN0fSAgICAgVGhlIHJlbGF0ZWQgaW5zdGFuY2Ugb3IgYSBjbG9uZSBvZiB0aGUgaW5zdGFuY2VzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LgotICAgICAqLwotICAgIHNpZ21hLmluc3RhbmNlcyA9IGZ1bmN0aW9uIChpZCkgewotICAgICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/Ci0gICAgICAgICAgICBfX2luc3RhbmNlc1tpZF0gOgotICAgICAgICAgICAgc2lnbWEudXRpbHMuZXh0ZW5kKHt9LCBfX2luc3RhbmNlcyk7Ci0gICAgfTsKLQotCi0gICAgLyoqCi0gICAgICogVGhlIGN1cnJlbnQgdmVyc2lvbiBvZiBzaWdtYToKLSAgICAgKi8KLSAgICBzaWdtYS52ZXJzaW9uID0gJzEuMS4wJzsKLQotCi0gICAgLyoqCi0gICAgICogRVhQT1JUOgotICAgICAqICoqKioqKioKLSAgICAgKi8KLSAgICBpZiAodHlwZW9mIHRoaXMuc2lnbWEgIT09ICd1bmRlZmluZWQnKQotICAgICAgICB0aHJvdyAnQW4gb2JqZWN0IGNhbGxlZCBzaWdtYSBpcyBhbHJlYWR5IGluIHRoZSBnbG9iYWwgc2NvcGUuJzsKLQotICAgIHRoaXMuc2lnbWEgPSBzaWdtYTsKLQotfSkuY2FsbCh0aGlzKTsKLQotLyoqCi0gKiBjb25yYWQuanMgaXMgYSB0aW55IEphdmFTY3JpcHQgam9icyBzY2hlZHVsZXIsCi0gKgotICogVmVyc2lvbjogMC4xLjAKLSAqIFNvdXJjZXM6IGh0dHA6Ly9naXRodWIuY29tL2phY29teWFsL2NvbnJhZC5qcwotICogRG9jOiAgICAgaHR0cDovL2dpdGh1Yi5jb20vamFjb215YWwvY29ucmFkLmpzI3JlYWRtZQotICoKLSAqIExpY2Vuc2U6Ci0gKiAtLS0tLS0tLQotICogQ29weXJpZ2h0IMKpIDIwMTMgQWxleGlzIEphY29teSwgU2NpZW5jZXMtUG8gbcOpZGlhbGFiCi0gKgotICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQotICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvCi0gKiBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZQotICogcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yCi0gKiBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwotICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKLSAqCi0gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgotICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCi0gKgotICogVGhlIFNvZnR3YXJlIGlzIHByb3ZpZGVkICJhcyBpcyIsIHdpdGhvdXQgd2FycmFudHkgb2YgYW55IGtpbmQsIGV4cHJlc3Mgb3IKLSAqIGltcGxpZWQsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIHdhcnJhbnRpZXMgb2YgbWVyY2hhbnRhYmlsaXR5LAotICogZml0bmVzcyBmb3IgYSBwYXJ0aWN1bGFyIHB1cnBvc2UgYW5kIG5vbmluZnJpbmdlbWVudC4gSW4gbm8gZXZlbnQgc2hhbGwgdGhlCi0gKiBhdXRob3JzIG9yIGNvcHlyaWdodCBob2xkZXJzIGJlIGxpYWJsZSBmb3IgYW55IGNsYWltLCBkYW1hZ2VzIG9yIG90aGVyCi0gKiBsaWFiaWxpdHksIHdoZXRoZXIgaW4gYW4gYWN0aW9uIG9mIGNvbnRyYWN0LCB0b3J0IG9yIG90aGVyd2lzZSwgYXJpc2luZwotICogZnJvbSwgb3V0IG9mIG9yIGluIGNvbm5lY3Rpb24gd2l0aCB0aGUgc29mdHdhcmUgb3IgdGhlIHVzZSBvciBvdGhlciBkZWFsaW5ncwotICogaW4gdGhlIFNvZnR3YXJlLgotICovCi0oZnVuY3Rpb24gKGdsb2JhbCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIC8vIENoZWNrIHRoYXQgY29ucmFkLmpzIGhhcyBub3QgYmVlbiBsb2FkZWQgeWV0OgotICAgIGlmIChnbG9iYWwuY29ucmFkKQotICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvbnJhZCBhbHJlYWR5IGV4aXN0cycpOwotCi0KLSAgICAvKioKLSAgICAgKiBQUklWQVRFIFZBUklBQkxFUzoKLSAgICAgKiAqKioqKioqKioqKioqKioqKioKLSAgICAgKi8KLQotICAgIC8qKgotICAgICAqIEEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgY29ucmFkIGlzIHJ1bm5pbmcgb3Igbm90LgotICAgICAqCi0gICAgICogQHR5cGUge051bWJlcn0KLSAgICAgKi8KLSAgICB2YXIgX2xhc3RGcmFtZVRpbWU7Ci0KLSAgICAvKioKLSAgICAgKiBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIGNvbnJhZCBpcyBydW5uaW5nIG9yIG5vdC4KLSAgICAgKgotICAgICAqIEB0eXBlIHtCb29sZWFufQotICAgICAqLwotICAgIHZhciBfaXNSdW5uaW5nID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgaGFzaCBvZiByZWdpc3RlcmVkIGpvYnMuIEVhY2ggam9iIG11c3QgYXQgbGVhc3QgaGF2ZSBhIHVuaXF1ZSBJRAotICAgICAqIHVuZGVyIHRoZSBrZXkgImlkIiBhbmQgYSBmdW5jdGlvbiB1bmRlciB0aGUga2V5ICJqb2IiLiBUaGlzIGhhc2gKLSAgICAgKiBjb250YWlucyBlYWNoIHJ1bm5pbmcgam9iIGFuZCBlYWNoIHdhaXRpbmcgam9iLgotICAgICAqCi0gICAgICogQHR5cGUge09iamVjdH0KLSAgICAgKi8KLSAgICB2YXIgX2pvYnMgPSB7fTsKLQotICAgIC8qKgotICAgICAqIFRoZSBoYXNoIG9mIGN1cnJlbnRseSBydW5uaW5nIGpvYnMuCi0gICAgICoKLSAgICAgKiBAdHlwZSB7T2JqZWN0fQotICAgICAqLwotICAgIHZhciBfcnVubmluZ0pvYnMgPSB7fTsKLQotICAgIC8qKgotICAgICAqIFRoZSBhcnJheSBvZiBjdXJyZW50bHkgcnVubmluZyBqb2JzLCBzb3J0ZWQgYnkgcHJpb3JpdHkuCi0gICAgICoKLSAgICAgKiBAdHlwZSB7QXJyYXl9Ci0gICAgICovCi0gICAgdmFyIF9zb3J0ZWRCeVByaW9yaXR5Sm9icyA9IFtdOwotCi0gICAgLyoqCi0gICAgICogVGhlIGFycmF5IG9mIGN1cnJlbnRseSB3YWl0aW5nIGpvYnMuCi0gICAgICoKLSAgICAgKiBAdHlwZSB7T2JqZWN0fQotICAgICAqLwotICAgIHZhciBfd2FpdGluZ0pvYnMgPSB7fTsKLQotICAgIC8qKgotICAgICAqIFRoZSBhcnJheSBvZiBmaW5pc2hlZCBqb2JzLiBUaGV5IGFyZSBzdG9yZWQgaW4gYW4gYXJyYXksIHNpbmNlIHR3byBqb2JzCi0gICAgICogd2l0aCB0aGUgc2FtZSAiaWQiIGNhbiBoYXBwZW4gYXQgdHdvIGRpZmZlcmVudCB0aW1lcy4KLSAgICAgKgotICAgICAqIEB0eXBlIHtBcnJheX0KLSAgICAgKi8KLSAgICB2YXIgX2RvbmVKb2JzID0gW107Ci0KLSAgICAvKioKLSAgICAgKiBBIGRpcnR5IGZsYWcgdG8ga2VlcCBjb25yYWQgZnJvbSBzdGFydGluZzogSW5kZWVkLCB3aGVuIGFkZEpvYigpIGlzIGNhbGxlZAotICAgICAqIHdpdGggc2V2ZXJhbCBqb2JzLCBjb25yYWQgbXVzdCBiZSBzdGFydGVkIG9ubHkgYXQgdGhlIGVuZC4gVGhpcyBmbGFnIGtlZXBzCi0gICAgICogbWUgZnJvbSBkdXBsaWNhdGluZyB0aGUgY29kZSB0aGF0IGVmZmVjdGl2ZWx5IGFkZHMgYSBqb2IuCi0gICAgICoKLSAgICAgKiBAdHlwZSB7Qm9vbGVhbn0KLSAgICAgKi8KLSAgICB2YXIgX25vU3RhcnQgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIEFuIGhhc2ggY29udGFpbmluZyBzb21lIGdsb2JhbCBzZXR0aW5ncyBhYm91dCBob3cgY29ucmFkLmpzIHNob3VsZAotICAgICAqIGJlaGF2ZS4KLSAgICAgKgotICAgICAqIEB0eXBlIHtPYmplY3R9Ci0gICAgICovCi0gICAgdmFyIF9wYXJhbWV0ZXJzID0gewotICAgICAgICBmcmFtZUR1cmF0aW9uOiAyMCwKLSAgICAgICAgaGlzdG9yeTogdHJ1ZQotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG9iamVjdCBjb250YWlucyBldmVyeSBoYW5kbGVycyBib3VuZCB0byBjb25yYWQgZXZlbnRzLiBJdCBkb2VzIG5vdAotICAgICAqIHJlcXVpcmVhIGFueSBET00gaW1wbGVtZW50YXRpb24sIHNpbmNlIHRoZSBldmVudHMgYXJlIGFsbCBKYXZhU2NyaXB0LgotICAgICAqCi0gICAgICogQHR5cGUge09iamVjdH0KLSAgICAgKi8KLSAgICB2YXIgX2hhbmRsZXJzID0gT2JqZWN0LmNyZWF0ZShudWxsKTsKLQotCi0gICAgLyoqCi0gICAgICogUFJJVkFURSBGVU5DVElPTlM6Ci0gICAgICogKioqKioqKioqKioqKioqKioqCi0gICAgICovCi0KLSAgICAvKioKLSAgICAgKiBXaWxsIGV4ZWN1dGUgdGhlIGhhbmRsZXIgZXZlcnl0aW1lIHRoYXQgdGhlIGluZGljYXRlZCBldmVudCAob3IgdGhlCi0gICAgICogaW5kaWNhdGVkIGV2ZW50cykgd2lsbCBiZSB0cmlnZ2VyZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtzdHJpbmd8YXJyYXl8b2JqZWN0fSBldmVudHMgIFRoZSBuYW1lIG9mIHRoZSBldmVudCAob3IgdGhlIGV2ZW50cwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwYXJhdGVkIGJ5IHNwYWNlcykuCi0gICAgICogQHBhcmFtICB7ZnVuY3Rpb24oT2JqZWN0KX0gICAgaGFuZGxlciBUaGUgaGFuZGxlciB0byBiaW5kLgotICAgICAqIEByZXR1cm4ge09iamVjdH0gICAgICAgICAgICAgICAgICAgICAgUmV0dXJucyBjb25yYWQuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX2JpbmQoZXZlbnRzLCBoYW5kbGVyKSB7Ci0gICAgICAgIHZhciBpLAotICAgICAgICAgICAgaV9lbmQsCi0gICAgICAgICAgICBldmVudCwKLSAgICAgICAgICAgIGVBcnJheTsKLQotICAgICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIGVsc2UgaWYgKAotICAgICAgICAgICAgYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJgotICAgICAgICAgICAgT2JqZWN0KGFyZ3VtZW50c1swXSkgPT09IGFyZ3VtZW50c1swXQotICAgICAgICApCi0gICAgICAgICAgICBmb3IgKGV2ZW50cyBpbiBhcmd1bWVudHNbMF0pCi0gICAgICAgICAgICAgICAgX2JpbmQoZXZlbnRzLCBhcmd1bWVudHNbMF1bZXZlbnRzXSk7Ci0gICAgICAgIGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7Ci0gICAgICAgICAgICBlQXJyYXkgPQotICAgICAgICAgICAgICAgIEFycmF5LmlzQXJyYXkoZXZlbnRzKSA/Ci0gICAgICAgICAgICAgICAgICAgIGV2ZW50cyA6Ci0gICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zcGxpdCgvIC8pOwotCi0gICAgICAgICAgICBmb3IgKGkgPSAwLCBpX2VuZCA9IGVBcnJheS5sZW5ndGg7IGkgIT09IGlfZW5kOyBpICs9IDEpIHsKLSAgICAgICAgICAgICAgICBldmVudCA9IGVBcnJheVtpXTsKLQotICAgICAgICAgICAgICAgIGlmICghX2hhbmRsZXJzW2V2ZW50XSkKLSAgICAgICAgICAgICAgICAgICAgX2hhbmRsZXJzW2V2ZW50XSA9IFtdOwotCi0gICAgICAgICAgICAgICAgLy8gVXNpbmcgYW4gb2JqZWN0IGluc3RlYWQgb2YgZGlyZWN0bHkgdGhlIGhhbmRsZXIgd2lsbCBtYWtlIHBvc3NpYmxlCi0gICAgICAgICAgICAgICAgLy8gbGF0ZXIgdG8gYWRkIGZsYWdzCi0gICAgICAgICAgICAgICAgX2hhbmRsZXJzW2V2ZW50XS5wdXNoKHsKLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlcjogaGFuZGxlcgotICAgICAgICAgICAgICAgIH0pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlcyB0aGUgaGFuZGxlciBmcm9tIGEgc3BlY2lmaWVkIGV2ZW50IChvciBzcGVjaWZpZWQgZXZlbnRzKS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgez9zdHJpbmd9ICAgICAgICAgICBldmVudHMgIFRoZSBuYW1lIG9mIHRoZSBldmVudCAob3IgdGhlIGV2ZW50cwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcGFyYXRlZCBieSBzcGFjZXMpLiBJZiB1bmRlZmluZWQsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBhbGwgaGFuZGxlcnMgYXJlIHJlbW92ZWQuCi0gICAgICogQHBhcmFtICB7P2Z1bmN0aW9uKE9iamVjdCl9IGhhbmRsZXIgVGhlIGhhbmRsZXIgdG8gdW5iaW5kLiBJZiB1bmRlZmluZWQsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWFjaCBoYW5kbGVyIGJvdW5kIHRvIHRoZSBldmVudCBvciB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudHMgd2lsbCBiZSByZW1vdmVkLgotICAgICAqIEByZXR1cm4ge09iamVjdH0gICAgICAgICAgICBSZXR1cm5zIGNvbnJhZC4KLSAgICAgKi8KLSAgICBmdW5jdGlvbiBfdW5iaW5kKGV2ZW50cywgaGFuZGxlcikgewotICAgICAgICB2YXIgaSwKLSAgICAgICAgICAgIGlfZW5kLAotICAgICAgICAgICAgaiwKLSAgICAgICAgICAgIGpfZW5kLAotICAgICAgICAgICAgYSwKLSAgICAgICAgICAgIGV2ZW50LAotICAgICAgICAgICAgZUFycmF5ID0gQXJyYXkuaXNBcnJheShldmVudHMpID8KLSAgICAgICAgICAgICAgICBldmVudHMgOgotICAgICAgICAgICAgICAgIGV2ZW50cy5zcGxpdCgvIC8pOwotCi0gICAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkKLSAgICAgICAgICAgIF9oYW5kbGVycyA9IE9iamVjdC5jcmVhdGUobnVsbCk7Ci0gICAgICAgIGVsc2UgaWYgKGhhbmRsZXIpIHsKLSAgICAgICAgICAgIGZvciAoaSA9IDAsIGlfZW5kID0gZUFycmF5Lmxlbmd0aDsgaSAhPT0gaV9lbmQ7IGkgKz0gMSkgewotICAgICAgICAgICAgICAgIGV2ZW50ID0gZUFycmF5W2ldOwotICAgICAgICAgICAgICAgIGlmIChfaGFuZGxlcnNbZXZlbnRdKSB7Ci0gICAgICAgICAgICAgICAgICAgIGEgPSBbXTsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChqID0gMCwgal9lbmQgPSBfaGFuZGxlcnNbZXZlbnRdLmxlbmd0aDsgaiAhPT0gal9lbmQ7IGogKz0gMSkKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaGFuZGxlcnNbZXZlbnRdW2pdLmhhbmRsZXIgIT09IGhhbmRsZXIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYS5wdXNoKF9oYW5kbGVyc1tldmVudF1bal0pOwotCi0gICAgICAgICAgICAgICAgICAgIF9oYW5kbGVyc1tldmVudF0gPSBhOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChfaGFuZGxlcnNbZXZlbnRdICYmIF9oYW5kbGVyc1tldmVudF0ubGVuZ3RoID09PSAwKQotICAgICAgICAgICAgICAgICAgICBkZWxldGUgX2hhbmRsZXJzW2V2ZW50XTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICBmb3IgKGkgPSAwLCBpX2VuZCA9IGVBcnJheS5sZW5ndGg7IGkgIT09IGlfZW5kOyBpICs9IDEpCi0gICAgICAgICAgICAgICAgZGVsZXRlIF9oYW5kbGVyc1tlQXJyYXlbaV1dOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4ZWN1dGVzIGVhY2ggaGFuZGxlciBib3VuZCB0byB0aGUgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtzdHJpbmd9ICBldmVudHMgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IChvciB0aGUgZXZlbnRzIHNlcGFyYXRlZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBieSBzcGFjZXMpLgotICAgICAqIEBwYXJhbSAgez9PYmplY3R9IGRhdGEgICBUaGUgY29udGVudCBvZiB0aGUgZXZlbnQgKG9wdGlvbmFsKS4KLSAgICAgKiBAcmV0dXJuIHtPYmplY3R9ICAgICAgICAgUmV0dXJucyBjb25yYWQuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX2Rpc3BhdGNoKGV2ZW50cywgZGF0YSkgewotICAgICAgICB2YXIgaSwKLSAgICAgICAgICAgIGosCi0gICAgICAgICAgICBpX2VuZCwKLSAgICAgICAgICAgIGpfZW5kLAotICAgICAgICAgICAgZXZlbnQsCi0gICAgICAgICAgICBldmVudE5hbWUsCi0gICAgICAgICAgICBlQXJyYXkgPSBBcnJheS5pc0FycmF5KGV2ZW50cykgPwotICAgICAgICAgICAgICAgIGV2ZW50cyA6Ci0gICAgICAgICAgICAgICAgZXZlbnRzLnNwbGl0KC8gLyk7Ci0KLSAgICAgICAgZGF0YSA9IGRhdGEgPT09IHVuZGVmaW5lZCA/IHt9IDogZGF0YTsKLQotICAgICAgICBmb3IgKGkgPSAwLCBpX2VuZCA9IGVBcnJheS5sZW5ndGg7IGkgIT09IGlfZW5kOyBpICs9IDEpIHsKLSAgICAgICAgICAgIGV2ZW50TmFtZSA9IGVBcnJheVtpXTsKLQotICAgICAgICAgICAgaWYgKF9oYW5kbGVyc1tldmVudE5hbWVdKSB7Ci0gICAgICAgICAgICAgICAgZXZlbnQgPSB7Ci0gICAgICAgICAgICAgICAgICAgIHR5cGU6IGV2ZW50TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSB8fCB7fQotICAgICAgICAgICAgICAgIH07Ci0KLSAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBqX2VuZCA9IF9oYW5kbGVyc1tldmVudE5hbWVdLmxlbmd0aDsgaiAhPT0gal9lbmQ7IGogKz0gMSkKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9oYW5kbGVyc1tldmVudE5hbWVdW2pdLmhhbmRsZXIoZXZlbnQpOwotICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4ZWN1dGVzIHRoZSBtb3N0IHByaW9yaXRhcnkgam9iIG9uY2UsIGFuZCBkZWFscyB3aXRoIGZpbGxpbmcgdGhlIHN0YXRzCi0gICAgICogKGRvbmUsIHRpbWUsIGF2ZXJhZ2VUaW1lLCBjdXJyZW50VGltZSwgZXRjLi4uKS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gez9PYmplY3R9IFJldHVybnMgdGhlIGpvYiBvYmplY3QgaWYgaXQgaGFzIHRvIGJlIGtpbGxlZCwgbnVsbCBlbHNlLgotICAgICAqLwotICAgIGZ1bmN0aW9uIF9leGVjdXRlRmlyc3RKb2IoKSB7Ci0gICAgICAgIHZhciBpLAotICAgICAgICAgICAgbCwKLSAgICAgICAgICAgIHRlc3QsCi0gICAgICAgICAgICBraWxsLAotICAgICAgICAgICAgcHVzaGVkID0gZmFsc2UsCi0gICAgICAgICAgICB0aW1lID0gX19kYXRlTm93KCksCi0gICAgICAgICAgICBqb2IgPSBfc29ydGVkQnlQcmlvcml0eUpvYnMuc2hpZnQoKTsKLQotICAgICAgICAvLyBFeGVjdXRlIHRoZSBqb2IgYW5kIGxvb2sgYXQgdGhlIHJlc3VsdDoKLSAgICAgICAgdGVzdCA9IGpvYi5qb2IoKTsKLQotICAgICAgICAvLyBEZWFsIHdpdGggc3RhdHM6Ci0gICAgICAgIHRpbWUgPSBfX2RhdGVOb3coKSAtIHRpbWU7Ci0gICAgICAgIGpvYi5kb25lKys7Ci0gICAgICAgIGpvYi50aW1lICs9IHRpbWU7Ci0gICAgICAgIGpvYi5jdXJyZW50VGltZSArPSB0aW1lOwotICAgICAgICBqb2Iud2VpZ2h0VGltZSA9IGpvYi5jdXJyZW50VGltZSAvIChqb2Iud2VpZ2h0IHx8IDEpOwotICAgICAgICBqb2IuYXZlcmFnZVRpbWUgPSBqb2IudGltZSAvIGpvYi5kb25lOwotCi0gICAgICAgIC8vIENoZWNrIGlmIHRoZSBqb2IgaGFzIHRvIGJlIGtpbGxlZDoKLSAgICAgICAga2lsbCA9IGpvYi5jb3VudCA/IChqb2IuY291bnQgPD0gam9iLmRvbmUpIDogIXRlc3Q7Ci0KLSAgICAgICAgLy8gUmVzZXQgcHJpb3JpdGllczoKLSAgICAgICAgaWYgKCFraWxsKSB7Ci0gICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gX3NvcnRlZEJ5UHJpb3JpdHlKb2JzLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgICAgICBpZiAoX3NvcnRlZEJ5UHJpb3JpdHlKb2JzW2ldLndlaWdodFRpbWUgPiBqb2Iud2VpZ2h0VGltZSkgewotICAgICAgICAgICAgICAgICAgICBfc29ydGVkQnlQcmlvcml0eUpvYnMuc3BsaWNlKGksIDAsIGpvYik7Ci0gICAgICAgICAgICAgICAgICAgIHB1c2hlZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKCFwdXNoZWQpCi0gICAgICAgICAgICAgICAgX3NvcnRlZEJ5UHJpb3JpdHlKb2JzLnB1c2goam9iKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBraWxsID8gam9iIDogbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBY3RpdmF0ZXMgYSBqb2IsIGJ5IGFkZGluZyBpdCB0byB0aGUgX3J1bm5pbmdKb2JzIG9iamVjdCBhbmQgdGhlCi0gICAgICogX3NvcnRlZEJ5UHJpb3JpdHlKb2JzIGFycmF5LiBJdCBhbHNvIGluaXRpYWxpemVzIGl0cyBjdXJyZW50VGltZSB2YWx1ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge09iamVjdH0gam9iIFRoZSBqb2IgdG8gYWN0aXZhdGUuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX2FjdGl2YXRlSm9iKGpvYikgewotICAgICAgICB2YXIgbCA9IF9zb3J0ZWRCeVByaW9yaXR5Sm9icy5sZW5ndGg7Ci0KLSAgICAgICAgLy8gQWRkIHRoZSBqb2IgdG8gdGhlIHJ1bm5pbmcgam9iczoKLSAgICAgICAgX3J1bm5pbmdKb2JzW2pvYi5pZF0gPSBqb2I7Ci0gICAgICAgIGpvYi5zdGF0dXMgPSAncnVubmluZyc7Ci0KLSAgICAgICAgLy8gQWRkIHRoZSBqb2IgdG8gdGhlIHByaW9yaXRpZXM6Ci0gICAgICAgIGlmIChsKSB7Ci0gICAgICAgICAgICBqb2Iud2VpZ2h0VGltZSA9IF9zb3J0ZWRCeVByaW9yaXR5Sm9ic1tsIC0gMV0ud2VpZ2h0VGltZTsKLSAgICAgICAgICAgIGpvYi5jdXJyZW50VGltZSA9IGpvYi53ZWlnaHRUaW1lICogKGpvYi53ZWlnaHQgfHwgMSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBqb2IgYW5kIGRpc3BhdGNoOgotICAgICAgICBqb2Iuc3RhcnRUaW1lID0gX19kYXRlTm93KCk7Ci0gICAgICAgIF9kaXNwYXRjaCgnam9iU3RhcnRlZCcsIF9fY2xvbmUoam9iKSk7Ci0KLSAgICAgICAgX3NvcnRlZEJ5UHJpb3JpdHlKb2JzLnB1c2goam9iKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbWFpbiBsb29wIG9mIGNvbnJhZC5qczoKLSAgICAgKiAgLiBJdCBleGVjdXRlcyBqb2Igc3VjaCB0aGF0IHRoZXkgYWxsIG9jY3VwYXRlIHRoZSBzYW1lIHByb2Nlc3NpbmcgdGltZS4KLSAgICAgKiAgLiBJdCBzdG9wcyBqb2JzIHRoYXQgZG8gbm90IG5lZWQgdG8gYmUgZXhlY3V0ZWQgYW55bW9yZS4KLSAgICAgKiAgLiBJdCB0cmlnZ2VycyBjYWxsYmFja3Mgd2hlbiBpdCBpcyByZWxldmFudC4KLSAgICAgKiAgLiBJdCBzdGFydHMgd2FpdGluZyBqb2JzIHdoZW4gdGhleSBuZWVkIHRvIGJlIHN0YXJ0ZWQuCi0gICAgICogIC4gSXQgaW5qZWN0cyBmcmFtZXMgdG8ga2VlcCBhIGNvbnN0YW50IGZyYXBlcyBwZXIgc2Vjb25kIHJhdGlvLgotICAgICAqICAuIEl0IHN0b3BzIGl0c2VsZiB3aGVuIHRoZXJlIGFyZSBubyBtb3JlIGpvYnMgdG8gZXhlY3V0ZS4KLSAgICAgKi8KLSAgICBmdW5jdGlvbiBfbG9vcCgpIHsKLSAgICAgICAgdmFyIGssCi0gICAgICAgICAgICBvLAotICAgICAgICAgICAgbCwKLSAgICAgICAgICAgIGpvYiwKLSAgICAgICAgICAgIHRpbWUsCi0gICAgICAgICAgICBkZWFkSm9iOwotCi0gICAgICAgIC8vIERlYWwgd2l0aCB0aGUgbmV3bHkgYWRkZWQgam9icyAodGhlIF9qb2JzIG9iamVjdCk6Ci0gICAgICAgIGZvciAoayBpbiBfam9icykgewotICAgICAgICAgICAgam9iID0gX2pvYnNba107Ci0KLSAgICAgICAgICAgIGlmIChqb2IuYWZ0ZXIpCi0gICAgICAgICAgICAgICAgX3dhaXRpbmdKb2JzW2tdID0gam9iOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIF9hY3RpdmF0ZUpvYihqb2IpOwotCi0gICAgICAgICAgICBkZWxldGUgX2pvYnNba107Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTZXQgdGhlIF9pc1J1bm5pbmcgZmxhZyB0byBmYWxzZSBpZiB0aGVyZSBhcmUgbm8gcnVubmluZyBqb2I6Ci0gICAgICAgIF9pc1J1bm5pbmcgPSAhIV9zb3J0ZWRCeVByaW9yaXR5Sm9icy5sZW5ndGg7Ci0KLSAgICAgICAgLy8gRGVhbCB3aXRoIHRoZSBydW5uaW5nIGpvYnMgKHRoZSBfcnVubmluZ0pvYnMgb2JqZWN0KToKLSAgICAgICAgd2hpbGUgKAotICAgICAgICBfc29ydGVkQnlQcmlvcml0eUpvYnMubGVuZ3RoICYmCi0gICAgICAgIF9fZGF0ZU5vdygpIC0gX2xhc3RGcmFtZVRpbWUgPCBfcGFyYW1ldGVycy5mcmFtZUR1cmF0aW9uCi0gICAgICAgICAgICApIHsKLSAgICAgICAgICAgIGRlYWRKb2IgPSBfZXhlY3V0ZUZpcnN0Sm9iKCk7Ci0KLSAgICAgICAgICAgIC8vIERlYWwgd2l0aCB0aGUgY2FzZSB3aGVyZSB0aGUgam9iIGhhcyBlbmRlZDoKLSAgICAgICAgICAgIGlmIChkZWFkSm9iKSB7Ci0gICAgICAgICAgICAgICAgX2tpbGxKb2IoZGVhZEpvYi5pZCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3Igd2FpdGluZyBqb2JzOgotICAgICAgICAgICAgICAgIGZvciAoayBpbiBfd2FpdGluZ0pvYnMpCi0gICAgICAgICAgICAgICAgICAgIGlmIChfd2FpdGluZ0pvYnNba10uYWZ0ZXIgPT09IGRlYWRKb2IuaWQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9hY3RpdmF0ZUpvYihfd2FpdGluZ0pvYnNba10pOwotICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIF93YWl0aW5nSm9ic1trXTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ2hlY2sgaWYgY29ucmFkIHN0aWxsIGhhcyBqb2JzIHRvIGRlYWwgd2l0aCwgYW5kIGtpbGwgaXQgaWYgbm90OgotICAgICAgICBpZiAoX2lzUnVubmluZykgewotICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBfbGFzdEZyYW1lVGltZToKLSAgICAgICAgICAgIF9sYXN0RnJhbWVUaW1lID0gX19kYXRlTm93KCk7Ci0KLSAgICAgICAgICAgIF9kaXNwYXRjaCgnZW50ZXJGcmFtZScpOwotICAgICAgICAgICAgc2V0VGltZW91dChfbG9vcCwgMCk7Ci0gICAgICAgIH0gZWxzZQotICAgICAgICAgICAgX2Rpc3BhdGNoKCdzdG9wJyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyBvbmUgb3IgbW9yZSBqb2JzLCBhbmQgc3RhcnRzIHRoZSBsb29wIGlmIG5vIGpvYiB3YXMgcnVubmluZyBiZWZvcmUuIEEKLSAgICAgKiBqb2IgaXMgYXQgbGVhc3QgYSB1bmlxdWUgc3RyaW5nICJpZCIgYW5kIGEgZnVuY3Rpb24sIGFuZCB0aGVyZSBhcmUgc29tZQotICAgICAqIHBhcmFtZXRlcnMgdGhhdCB5b3UgY2FuIHNwZWNpZnkgZm9yIGVhY2ggam9iIHRvIG1vZGlmeSB0aGUgd2F5IGNvbnJhZCB3aWxsCi0gICAgICogZXhlY3V0ZSBpdC4gSWYgYSBqb2IgaXMgYWRkZWQgd2l0aCB0aGUgImlkIiBvZiBhbm90aGVyIGpvYiB0aGF0IGlzIHdhaXRpbmcKLSAgICAgKiBvciBzdGlsbCBydW5uaW5nLCBhbiBlcnJvciB3aWxsIGJlIHRocm93bi4KLSAgICAgKgotICAgICAqIFdoZW4gYSBqb2IgaXMgYWRkZWQsIGl0IGlzIHJlZmVyZW5jZWQgaW4gdGhlIF9qb2JzIG9iamVjdCwgYnkgaXRzIGlkLgotICAgICAqIFRoZW4sIGlmIGl0IGhhcyB0byBiZSBleGVjdXRlZCByaWdodCBub3csIGl0IHdpbGwgYmUgYWxzbyByZWZlcmVuY2VkIGluCi0gICAgICogdGhlIF9ydW5uaW5nSm9icyBvYmplY3QuIElmIGl0IGhhcyB0byB3YWl0LCB0aGVuIGl0IHdpbGwgYmUgYWRkZWQgaW50byB0aGUKLSAgICAgKiBfd2FpdGluZ0pvYnMgb2JqZWN0LCB1bnRpbCBpdCBjYW4gc3RhcnQuCi0gICAgICoKLSAgICAgKiBLZWVwIHJlYWRpbmcgdGhpcyBkb2N1bWVudGF0aW9uIHRvIHNlZSBob3cgdG8gY2FsbCB0aGlzIG1ldGhvZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4ge09iamVjdH0gUmV0dXJucyBjb25yYWQuCi0gICAgICoKLSAgICAgKiBBZGRpbmcgb25lIGpvYjoKLSAgICAgKiAqKioqKioqKioqKioqKioKLSAgICAgKiBCYXNpY2FsbHksIGEgam9iIGlzIGRlZmluZWQgYnkgaXRzIHN0cmluZyBpZCBhbmQgYSBmdW5jdGlvbiAodGhlIGpvYikuIEl0Ci0gICAgICogaXMgYWxzbyBwb3NzaWJsZSB0byBhZGQgc29tZSBwYXJhbWV0ZXJzOgotICAgICAqCi0gICAgICogID4gY29ucmFkLmFkZEpvYignbXlKb2JJZCcsIG15Sm9iRnVuY3Rpb24pOwotICAgICAqICA+IGNvbnJhZC5hZGRKb2IoJ215Sm9iSWQnLCB7Ci0gICAqICA+ICAgam9iOiBteUpvYkZ1bmN0aW9uLAotICAgKiAgPiAgIHNvbWVQYXJhbWV0ZXI6IHNvbWVWYWx1ZQotICAgKiAgPiB9KTsKLSAgICAgKiAgPiBjb25yYWQuYWRkSm9iKHsKLSAgICogID4gICBpZDogJ215Sm9iSWQnLAotICAgKiAgPiAgIGpvYjogbXlKb2JGdW5jdGlvbiwKLSAgICogID4gICBzb21lUGFyYW1ldGVyOiBzb21lVmFsdWUKLSAgICogID4gfSk7Ci0gICAgICoKLSAgICAgKiBBZGRpbmcgc2V2ZXJhbCBqb2JzOgotICAgICAqICoqKioqKioqKioqKioqKioqKioqCi0gICAgICogV2hlbiBhZGRpbmcgc2V2ZXJhbCBqb2JzIGF0IHRoZSBzYW1lIHRpbWUsIGl0IGlzIHBvc3NpYmxlIHRvIHNwZWNpZnkKLSAgICAgKiBwYXJhbWV0ZXJzIGZvciBlYWNoIG9uZSBpbmRpdmlkdWFsbHkgb3IgZm9yIGFsbDoKLSAgICAgKgotICAgICAqICA+IGNvbnJhZC5hZGRKb2IoWwotICAgICAqICA+ICAgewotICAgKiAgPiAgICAgaWQ6ICdteUpvYklkMScsCi0gICAqICA+ICAgICBqb2I6IG15Sm9iRnVuY3Rpb24xLAotICAgKiAgPiAgICAgc29tZVBhcmFtZXRlcjE6IHNvbWVWYWx1ZTEKLSAgICogID4gICB9LAotICAgICAqICA+ICAgewotICAgKiAgPiAgICAgaWQ6ICdteUpvYklkMicsCi0gICAqICA+ICAgICBqb2I6IG15Sm9iRnVuY3Rpb24yLAotICAgKiAgPiAgICAgc29tZVBhcmFtZXRlcjI6IHNvbWVWYWx1ZTIKLSAgICogID4gICB9Ci0gICAgICogID4gXSwgewotICAgKiAgPiAgIHNvbWVDb21tb25QYXJhbWV0ZXI6IHNvbWVDb21tb25WYWx1ZQotICAgKiAgPiB9KTsKLSAgICAgKiAgPiBjb25yYWQuYWRkSm9iKHsKLSAgICogID4gICBteUpvYklkMTogeywKLSAgICogID4gICAgIGpvYjogbXlKb2JGdW5jdGlvbjEsCi0gICAqICA+ICAgICBzb21lUGFyYW1ldGVyMTogc29tZVZhbHVlMQotICAgKiAgPiAgIH0sCi0gICAqICA+ICAgbXlKb2JJZDI6IHssCi0gICAqICA+ICAgICBqb2I6IG15Sm9iRnVuY3Rpb24yLAotICAgKiAgPiAgICAgc29tZVBhcmFtZXRlcjI6IHNvbWVWYWx1ZTIKLSAgICogID4gICB9Ci0gICAqICA+IH0sIHsKLSAgICogID4gICBzb21lQ29tbW9uUGFyYW1ldGVyOiBzb21lQ29tbW9uVmFsdWUKLSAgICogID4gfSk7Ci0gICAgICogID4gY29ucmFkLmFkZEpvYih7Ci0gICAqICA+ICAgbXlKb2JJZDE6IG15Sm9iRnVuY3Rpb24xLAotICAgKiAgPiAgIG15Sm9iSWQyOiBteUpvYkZ1bmN0aW9uMgotICAgKiAgPiB9LCB7Ci0gICAqICA+ICAgc29tZUNvbW1vblBhcmFtZXRlcjogc29tZUNvbW1vblZhbHVlCi0gICAqICA+IH0pOwotICAgICAqCi0gICAgICogIFJlY29nbml6ZWQgcGFyYW1ldGVyczoKLSAgICAgKiAgKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqICBIZXJlIGlzIHRoZSBleGhhdXN0aXZlIGxpc3Qgb2YgZXZlcnkgYWNjZXB0ZWQgcGFyYW1ldGVyczoKLSAgICAgKgotICAgICAqICAgIHs/RnVuY3Rpb259IGVuZCAgICAgIEEgY2FsbGJhY2sgdG8gZXhlY3V0ZSB3aGVuIHRoZSBqb2IgaXMgZW5kZWQuIEl0IGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgbm90IGV4ZWN1dGVkIGlmIHRoZSBqb2IgaXMga2lsbGVkIGluc3RlYWQgb2YgZW5kZWQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAibmF0dXJhbGx5Ii4KLSAgICAgKiAgICB7P0ludGVnZXJ9ICBjb3VudCAgICBUaGUgbnVtYmVyIG9mIHRpbWUgdGhlIGpvYiBoYXMgdG8gYmUgZXhlY3V0ZWQuCi0gICAgICogICAgez9OdW1iZXJ9ICAgd2VpZ2h0ICAgSWYgc3BlY2lmaWVkLCB0aGUgam9iIHdpbGwgYmUgZXhlY3V0ZWQgYXMgaXQgd2FzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgYWRkZWQgIndlaWdodCIgdGltZXMuCi0gICAgICogICAgez9TdHJpbmd9ICAgYWZ0ZXIgICAgVGhlIGlkIG9mIGFub3RoZXIgam9iIChldmVudHVhbGx5IG5vdCBhZGRlZCB5ZXQpLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIElmIHNwZWNpZmllZCwgdGhpcyBqb2Igd2lsbCBzdGFydCBvbmx5IHdoZW4gdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkICJhZnRlciIgam9iIGlzIGVuZGVkLgotICAgICAqLwotICAgIGZ1bmN0aW9uIF9hZGRKb2IodjEsIHYyKSB7Ci0gICAgICAgIHZhciBpLAotICAgICAgICAgICAgbCwKLSAgICAgICAgICAgIG87Ci0KLSAgICAgICAgLy8gQXJyYXkgb2Ygam9iczoKLSAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodjEpKSB7Ci0gICAgICAgICAgICAvLyBLZWVwIGNvbnJhZCB0byBzdGFydCB1bnRpbCB0aGUgbGFzdCBqb2IgaXMgYWRkZWQ6Ci0gICAgICAgICAgICBfbm9TdGFydCA9IHRydWU7Ci0KLSAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSB2MS5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICAgICAgX2FkZEpvYih2MVtpXS5pZCwgX19leHRlbmQodjFbaV0sIHYyKSk7Ci0KLSAgICAgICAgICAgIF9ub1N0YXJ0ID0gZmFsc2U7Ci0gICAgICAgICAgICBpZiAoIV9pc1J1bm5pbmcpIHsKLSAgICAgICAgICAgICAgICAvLyBVcGRhdGUgdGhlIF9sYXN0RnJhbWVUaW1lOgotICAgICAgICAgICAgICAgIF9sYXN0RnJhbWVUaW1lID0gX19kYXRlTm93KCk7Ci0KLSAgICAgICAgICAgICAgICBfZGlzcGF0Y2goJ3N0YXJ0Jyk7Ci0gICAgICAgICAgICAgICAgX2xvb3AoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdjEgPT09ICdvYmplY3QnKSB7Ci0gICAgICAgICAgICAvLyBPbmUgam9iIChvYmplY3QpOgotICAgICAgICAgICAgaWYgKHR5cGVvZiB2MS5pZCA9PT0gJ3N0cmluZycpCi0gICAgICAgICAgICAgICAgX2FkZEpvYih2MS5pZCwgdjEpOwotCi0gICAgICAgICAgICAvLyBIYXNoIG9mIGpvYnM6Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBLZWVwIGNvbnJhZCB0byBzdGFydCB1bnRpbCB0aGUgbGFzdCBqb2IgaXMgYWRkZWQ6Ci0gICAgICAgICAgICAgICAgX25vU3RhcnQgPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgZm9yIChpIGluIHYxKQotICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHYxW2ldID09PSAnZnVuY3Rpb24nKQotICAgICAgICAgICAgICAgICAgICAgICAgX2FkZEpvYihpLCBfX2V4dGVuZCh7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgam9iOiB2MVtpXQotICAgICAgICAgICAgICAgICAgICAgICAgfSwgdjIpKTsKLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgX2FkZEpvYihpLCBfX2V4dGVuZCh2MVtpXSwgdjIpKTsKLQotICAgICAgICAgICAgICAgIF9ub1N0YXJ0ID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgaWYgKCFfaXNSdW5uaW5nKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgX2xhc3RGcmFtZVRpbWU6Ci0gICAgICAgICAgICAgICAgICAgIF9sYXN0RnJhbWVUaW1lID0gX19kYXRlTm93KCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgX2Rpc3BhdGNoKCdzdGFydCcpOwotICAgICAgICAgICAgICAgICAgICBfbG9vcCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gT25lIGpvYiAoc3RyaW5nLCAqKToKLSAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdjEgPT09ICdzdHJpbmcnKSB7Ci0gICAgICAgICAgICBpZiAoX2hhc0pvYih2MSkpCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKAotICAgICAgICAgICAgICAgICAgICAnW2NvbnJhZC5hZGRKb2JdIEpvYiB3aXRoIGlkICInICsgdjEgKyAnIiBhbHJlYWR5IGV4aXN0cy4nCi0gICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgLy8gT25lIGpvYiAoc3RyaW5nLCBmdW5jdGlvbik6Ci0gICAgICAgICAgICBpZiAodHlwZW9mIHYyID09PSAnZnVuY3Rpb24nKSB7Ci0gICAgICAgICAgICAgICAgbyA9IHsKLSAgICAgICAgICAgICAgICAgICAgaWQ6IHYxLAotICAgICAgICAgICAgICAgICAgICBkb25lOiAwLAotICAgICAgICAgICAgICAgICAgICB0aW1lOiAwLAotICAgICAgICAgICAgICAgICAgICBzdGF0dXM6ICd3YWl0aW5nJywKLSAgICAgICAgICAgICAgICAgICAgY3VycmVudFRpbWU6IDAsCi0gICAgICAgICAgICAgICAgICAgIGF2ZXJhZ2VUaW1lOiAwLAotICAgICAgICAgICAgICAgICAgICB3ZWlnaHRUaW1lOiAwLAotICAgICAgICAgICAgICAgICAgICBqb2I6IHYyCi0gICAgICAgICAgICAgICAgfTsKLQotICAgICAgICAgICAgICAgIC8vIE9uZSBqb2IgKHN0cmluZywgb2JqZWN0KToKLSAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHYyID09PSAnb2JqZWN0JykgewotICAgICAgICAgICAgICAgIG8gPSBfX2V4dGVuZCgKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IHYxLAotICAgICAgICAgICAgICAgICAgICAgICAgZG9uZTogMCwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRpbWU6IDAsCi0gICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM6ICd3YWl0aW5nJywKLSAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRUaW1lOiAwLAotICAgICAgICAgICAgICAgICAgICAgICAgYXZlcmFnZVRpbWU6IDAsCi0gICAgICAgICAgICAgICAgICAgICAgICB3ZWlnaHRUaW1lOiAwCi0gICAgICAgICAgICAgICAgICAgIH0sCi0gICAgICAgICAgICAgICAgICAgIHYyCi0gICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgICAgIC8vIElmIG5vbmUgb2YgdGhvc2UgY2FzZXMsIHRocm93IGFuIGVycm9yOgotICAgICAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdbY29ucmFkLmFkZEpvYl0gV3JvbmcgYXJndW1lbnRzLicpOwotCi0gICAgICAgICAgICAvLyBFZmZlY3RpdmVseSBhZGQgdGhlIGpvYjoKLSAgICAgICAgICAgIF9qb2JzW3YxXSA9IG87Ci0gICAgICAgICAgICBfZGlzcGF0Y2goJ2pvYkFkZGVkJywgX19jbG9uZShvKSk7Ci0KLSAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBsb29wIGhhcyB0byBiZSBzdGFydGVkOgotICAgICAgICAgICAgaWYgKCFfaXNSdW5uaW5nICYmICFfbm9TdGFydCkgewotICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgX2xhc3RGcmFtZVRpbWU6Ci0gICAgICAgICAgICAgICAgX2xhc3RGcmFtZVRpbWUgPSBfX2RhdGVOb3coKTsKLQotICAgICAgICAgICAgICAgIF9kaXNwYXRjaCgnc3RhcnQnKTsKLSAgICAgICAgICAgICAgICBfbG9vcCgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBJZiBub25lIG9mIHRob3NlIGNhc2VzLCB0aHJvdyBhbiBlcnJvcjoKLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1tjb25yYWQuYWRkSm9iXSBXcm9uZyBhcmd1bWVudHMuJyk7Ci0KLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogS2lsbHMgb25lIG9yIG1vcmUgam9icywgaW5kaWNhdGVkIGJ5IHRoZWlyIGlkcy4gSXQgaXMgb25seSBwb3NzaWJsZSB0bwotICAgICAqIGtpbGwgcnVubmluZyBqb2JzIG9yIHdhaXRpbmcgam9icy4gSWYgeW91IHRyeSB0byBraWxsIGEgam9iIHRoYXQgZG9lcyBub3QKLSAgICAgKiBleGlzdCBvciB0aGF0IGlzIGFscmVhZHkga2lsbGVkLCBhIHdhcm5pbmcgd2lsbCBiZSB0aHJvd24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtBcnJheXxTdHJpbmd9IHYxIEEgc3RyaW5nIGpvYiBpZCBvciBhbiBhcnJheSBvZiBqb2IgaWRzLgotICAgICAqIEByZXR1cm4ge09iamVjdH0gICAgICAgUmV0dXJucyBjb25yYWQuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX2tpbGxKb2IodjEpIHsKLSAgICAgICAgdmFyIGksCi0gICAgICAgICAgICBsLAotICAgICAgICAgICAgaywKLSAgICAgICAgICAgIGEsCi0gICAgICAgICAgICBqb2IsCi0gICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwotCi0gICAgICAgIC8vIEFycmF5IG9mIGpvYiBpZHM6Ci0gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHYxKSkKLSAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSB2MS5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICAgICAgX2tpbGxKb2IodjFbaV0pOwotCi0gICAgICAgIC8vIE9uZSBqb2IncyBpZDoKLSAgICAgICAgZWxzZSBpZiAodHlwZW9mIHYxID09PSAnc3RyaW5nJykgewotICAgICAgICAgICAgYSA9IFtfcnVubmluZ0pvYnMsIF93YWl0aW5nSm9icywgX2pvYnNdOwotCi0gICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGpvYiBmcm9tIHRoZSBoYXNoZXM6Ci0gICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gYS5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICAgICAgaWYgKHYxIGluIGFbaV0pIHsKLSAgICAgICAgICAgICAgICAgICAgam9iID0gYVtpXVt2MV07Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKF9wYXJhbWV0ZXJzLmhpc3RvcnkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGpvYi5zdGF0dXMgPSAnZG9uZSc7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfZG9uZUpvYnMucHVzaChqb2IpOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgX2Rpc3BhdGNoKCdqb2JFbmRlZCcsIF9fY2xvbmUoam9iKSk7Ci0gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBhW2ldW3YxXTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGpvYi5lbmQgPT09ICdmdW5jdGlvbicpCi0gICAgICAgICAgICAgICAgICAgICAgICBqb2IuZW5kKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBwcmlvcml0aWVzIGFycmF5OgotICAgICAgICAgICAgYSA9IF9zb3J0ZWRCeVByaW9yaXR5Sm9iczsKLSAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgICAgICBpZiAoYVtpXS5pZCA9PT0gdjEpIHsKLSAgICAgICAgICAgICAgICAgICAgYS5zcGxpY2UoaSwgMSk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKCFmb3VuZCkKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1tjb25yYWQua2lsbEpvYl0gSm9iICInICsgdjEgKyAnIiBub3QgZm91bmQuJyk7Ci0KLSAgICAgICAgICAgIC8vIElmIG5vbmUgb2YgdGhvc2UgY2FzZXMsIHRocm93IGFuIGVycm9yOgotICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignW2NvbnJhZC5raWxsSm9iXSBXcm9uZyBhcmd1bWVudHMuJyk7Ci0KLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogS2lsbHMgZXZlcnkgcnVubmluZywgd2FpdGluZywgYW5kIGp1c3QgYWRkZWQgam9icy4KLSAgICAgKgotICAgICAqIEByZXR1cm4ge09iamVjdH0gUmV0dXJucyBjb25yYWQuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX2tpbGxBbGwoKSB7Ci0gICAgICAgIHZhciBrLAotICAgICAgICAgICAgam9icyA9IF9fZXh0ZW5kKF9qb2JzLCBfcnVubmluZ0pvYnMsIF93YWl0aW5nSm9icyk7Ci0KLSAgICAgICAgLy8gVGFrZSBldmVyeSBqb2JzIGFuZCBwdXNoIHRoZW0gaW50byB0aGUgX2RvbmVKb2JzIG9iamVjdDoKLSAgICAgICAgaWYgKF9wYXJhbWV0ZXJzLmhpc3RvcnkpCi0gICAgICAgICAgICBmb3IgKGsgaW4gam9icykgewotICAgICAgICAgICAgICAgIGpvYnNba10uc3RhdHVzID0gJ2RvbmUnOwotICAgICAgICAgICAgICAgIF9kb25lSm9icy5wdXNoKGpvYnNba10pOwotCi0gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBqb2JzW2tdLmVuZCA9PT0gJ2Z1bmN0aW9uJykKLSAgICAgICAgICAgICAgICAgICAgam9ic1trXS5lbmQoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAvLyBSZWluaXRpYWxpemUgdGhlIGRpZmZlcmVudCBqb2JzIGxpc3RzOgotICAgICAgICBfam9icyA9IHt9OwotICAgICAgICBfd2FpdGluZ0pvYnMgPSB7fTsKLSAgICAgICAgX3J1bm5pbmdKb2JzID0ge307Ci0gICAgICAgIF9zb3J0ZWRCeVByaW9yaXR5Sm9icyA9IFtdOwotCi0gICAgICAgIC8vIEluIGNhc2Ugc29tZSBqb2JzIGFyZSBhZGRlZCByaWdodCBhZnRlciB0aGUga2lsbDoKLSAgICAgICAgX2lzUnVubmluZyA9IGZhbHNlOwotCi0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiBhIGpvYiB3aXRoIHRoZSBzcGVjaWZpZWQgaWQgaXMgY3VycmVudGx5IHJ1bm5pbmcgb3IKLSAgICAgKiB3YWl0aW5nLCBhbmQgZmFsc2UgZWxzZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge1N0cmluZ30gIGlkIFRoZSBpZCBvZiB0aGUgam9iLgotICAgICAqIEByZXR1cm4gez9PYmplY3R9IFJldHVybnMgdGhlIGpvYiBvYmplY3QgaWYgaXQgZXhpc3RzLgotICAgICAqLwotICAgIGZ1bmN0aW9uIF9oYXNKb2IoaWQpIHsKLSAgICAgICAgdmFyIGpvYiA9IF9qb2JzW2lkXSB8fCBfcnVubmluZ0pvYnNbaWRdIHx8IF93YWl0aW5nSm9ic1tpZF07Ci0gICAgICAgIHJldHVybiBqb2IgPyBfX2V4dGVuZChqb2IpIDogbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIHNldCB0aGUgc2V0dGluZyBzcGVjaWZpZWQgYnkgInYxIiB0byB0aGUgdmFsdWUgc3BlY2lmaWVkCi0gICAgICogYnkgInYyIiBpZiBib3RoIGFyZSBnaXZlbiwgYW5kIGVsc2UgcmV0dXJuIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZQotICAgICAqIHNldHRpbmdzICJ2MSIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgdjEgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5LgotICAgICAqIEBwYXJhbSAgez8qfSAgICAgICB2MiBFdmVudHVhbGx5LCBhIHZhbHVlIHRvIHNldCB0byB0aGUgc3BlY2lmaWVkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5LgotICAgICAqIEByZXR1cm4ge09iamVjdHwqfSBSZXR1cm5zIHRoZSBzcGVjaWZpZWQgc2V0dGluZ3MgdmFsdWUgaWYgInYyIiBpcyBub3QKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgZ2l2ZW4sIGFuZCBjb25yYWQgZWxzZS4KLSAgICAgKi8KLSAgICBmdW5jdGlvbiBfc2V0dGluZ3ModjEsIHYyKSB7Ci0gICAgICAgIHZhciBvOwotCi0gICAgICAgIGlmICh0eXBlb2YgYTEgPT09ICdzdHJpbmcnICYmIGFyZ3VtZW50cy5sZW5ndGggPT09IDEpCi0gICAgICAgICAgICByZXR1cm4gX3BhcmFtZXRlcnNbYTFdOwotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIG8gPSAodHlwZW9mIGExID09PSAnb2JqZWN0JyAmJiBhcmd1bWVudHMubGVuZ3RoID09PSAxKSA/Ci0gICAgICAgICAgICBhMSB8fCB7fSA6Ci0gICAgICAgICAgICB7fTsKLSAgICAgICAgICAgIGlmICh0eXBlb2YgYTEgPT09ICdzdHJpbmcnKQotICAgICAgICAgICAgICAgIG9bYTFdID0gYTI7Ci0KLSAgICAgICAgICAgIGZvciAodmFyIGsgaW4gbykKLSAgICAgICAgICAgICAgICBpZiAob1trXSAhPT0gdW5kZWZpbmVkKQotICAgICAgICAgICAgICAgICAgICBfcGFyYW1ldGVyc1trXSA9IG9ba107Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBkZWxldGUgX3BhcmFtZXRlcnNba107Ci0KLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIGNvbnJhZCBpcyBjdXJyZW50bHkgcnVubmluZywgYW5kIGZhbHNlIGVsc2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHtCb29sZWFufSBSZXR1cm5zIF9pc1J1bm5pbmcuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX2dldElzUnVubmluZygpIHsKLSAgICAgICAgcmV0dXJuIF9pc1J1bm5pbmc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVW5yZWZlcmVuY2UgZXZlcnkgam9iIHRoYXQgaXMgc3RvcmVkIGluIHRoZSBfZG9uZUpvYnMgb2JqZWN0LiBJdCB3aWxsCi0gICAgICogbm90IGJlIHBvc3NpYmxlIGFueW1vcmUgdG8gZ2V0IHN0YXRzIGFib3V0IHRoZXNlIGpvYnMsIGJ1dCBpdCB3aWxsIHJlbGVhc2UKLSAgICAgKiB0aGUgbWVtb3J5LgotICAgICAqCi0gICAgICogQHJldHVybiB7T2JqZWN0fSBSZXR1cm5zIGNvbnJhZC4KLSAgICAgKi8KLSAgICBmdW5jdGlvbiBfY2xlYXJIaXN0b3J5KCkgewotICAgICAgICBfZG9uZUpvYnMgPSBbXTsKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHNuYXBzaG90IG9mIGV2ZXJ5IGRhdGEgYWJvdXQgam9icyB0aGF0IHdhaXQgdG8gYmUgc3RhcnRlZCwgYXJlCi0gICAgICogY3VycmVudGx5IHJ1bm5pbmcgb3IgYXJlIGRvbmUuCi0gICAgICoKLSAgICAgKiBJdCBpcyBwb3NzaWJsZSB0byBnZXQgb25seSBydW5uaW5nLCB3YWl0aW5nIG9yIGRvbmUgam9icyBieSBnaXZpbmcKLSAgICAgKiAicnVubmluZyIsICJ3YWl0aW5nIiBvciAiZG9uZSIgYXMgZmlzdCBhcmd1bWVudC4KLSAgICAgKgotICAgICAqIEl0IGlzIGFsc28gcG9zc2libGUgdG8gZ2V0IGV2ZXJ5IGpvYiB3aXRoIGEgc3BlY2lmaWVkIGlkIGJ5IGdpdmluZyBpdCBhcwotICAgICAqIGZpcnN0IGFyZ3VtZW50LiBBbHNvLCB1c2luZyBhIFJlZ0V4cCBpbnN0ZWFkIG9mIGFuIGlkIHdpbGwgcmV0dXJuIGV2ZXJ5Ci0gICAgICogam9icyB3aG9zZSBpZHMgbWF0Y2ggdGhlIFJlZ0V4cC4gQW5kIHRoZXNlIHR3byBsYXN0IHVzZSBjYXNlcyB3b3JrIGFzIHdlbGwKLSAgICAgKiBieSBnaXZpbmcgYmVmb3JlICJydW5uaW5nIiwgIndhaXRpbmciIG9yICJkb25lIi4KLSAgICAgKgotICAgICAqIEByZXR1cm4ge0FycmF5fSBUaGUgYXJyYXkgb2YgdGhlIG1hdGNoaW5nIGpvYnMuCi0gICAgICoKLSAgICAgKiBTb21lIGNhbGwgZXhhbXBsZXM6Ci0gICAgICogKioqKioqKioqKioqKioqKioqKgotICAgICAqICA+IGNvbnJhZC5nZXRTdGF0cygncnVubmluZycpCi0gICAgICogID4gY29ucmFkLmdldFN0YXRzKCd3YWl0aW5nJykKLSAgICAgKiAgPiBjb25yYWQuZ2V0U3RhdHMoJ2RvbmUnKQotICAgICAqICA+IGNvbnJhZC5nZXRTdGF0cygnbXlKb2InKQotICAgICAqICA+IGNvbnJhZC5nZXRTdGF0cygvdGVzdC8pCi0gICAgICogID4gY29ucmFkLmdldFN0YXRzKCdydW5uaW5nJywgJ215UnVubmluZ0pvYicpCi0gICAgICogID4gY29ucmFkLmdldFN0YXRzKCdydW5uaW5nJywgL3Rlc3QvKQotICAgICAqLwotICAgIGZ1bmN0aW9uIF9nZXRTdGF0cyh2MSwgdjIpIHsKLSAgICAgICAgdmFyIGEsCi0gICAgICAgICAgICBrLAotICAgICAgICAgICAgaSwKLSAgICAgICAgICAgIGwsCi0gICAgICAgICAgICBzdGF0cywKLSAgICAgICAgICAgIHBhdHRlcm4sCi0gICAgICAgICAgICBpc1BhdHRlcm5TdHJpbmc7Ci0KLSAgICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7Ci0gICAgICAgICAgICBzdGF0cyA9IFtdOwotCi0gICAgICAgICAgICBmb3IgKGsgaW4gX2pvYnMpCi0gICAgICAgICAgICAgICAgc3RhdHMucHVzaChfam9ic1trXSk7Ci0KLSAgICAgICAgICAgIGZvciAoayBpbiBfd2FpdGluZ0pvYnMpCi0gICAgICAgICAgICAgICAgc3RhdHMucHVzaChfd2FpdGluZ0pvYnNba10pOwotCi0gICAgICAgICAgICBmb3IgKGsgaW4gX3J1bm5pbmdKb2JzKQotICAgICAgICAgICAgICAgIHN0YXRzLnB1c2goX3J1bm5pbmdKb2JzW2tdKTsKLQotICAgICAgICAgICAgc3RhdHMgPSBzdGF0cy5jb25jYXQoX2RvbmVKb2JzKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICh0eXBlb2YgdjEgPT09ICdzdHJpbmcnKQotICAgICAgICAgICAgc3dpdGNoICh2MSkgewotICAgICAgICAgICAgICAgIGNhc2UgJ3dhaXRpbmcnOgotICAgICAgICAgICAgICAgICAgICBzdGF0cyA9IF9fb2JqZWN0VmFsdWVzKF93YWl0aW5nSm9icyk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgJ3J1bm5pbmcnOgotICAgICAgICAgICAgICAgICAgICBzdGF0cyA9IF9fb2JqZWN0VmFsdWVzKF9ydW5uaW5nSm9icyk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgJ2RvbmUnOgotICAgICAgICAgICAgICAgICAgICBzdGF0cyA9IF9kb25lSm9iczsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgcGF0dGVybiA9IHYxOwotICAgICAgICAgICAgfQotCi0gICAgICAgIGlmICh2MSBpbnN0YW5jZW9mIFJlZ0V4cCkKLSAgICAgICAgICAgIHBhdHRlcm4gPSB2MTsKLQotICAgICAgICBpZiAoIXBhdHRlcm4gJiYgKHR5cGVvZiB2MiA9PT0gJ3N0cmluZycgfHwgdjIgaW5zdGFuY2VvZiBSZWdFeHApKQotICAgICAgICAgICAgcGF0dGVybiA9IHYyOwotCi0gICAgICAgIC8vIEZpbHRlciBqb2JzIGlmIGEgcGF0dGVybiBpcyBnaXZlbjoKLSAgICAgICAgaWYgKHBhdHRlcm4pIHsKLSAgICAgICAgICAgIGlzUGF0dGVyblN0cmluZyA9IHR5cGVvZiBwYXR0ZXJuID09PSAnc3RyaW5nJzsKLQotICAgICAgICAgICAgaWYgKHN0YXRzIGluc3RhbmNlb2YgQXJyYXkpIHsKLSAgICAgICAgICAgICAgICBhID0gc3RhdHM7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzdGF0cyA9PT0gJ29iamVjdCcpIHsKLSAgICAgICAgICAgICAgICBhID0gW107Ci0KLSAgICAgICAgICAgICAgICBmb3IgKGsgaW4gc3RhdHMpCi0gICAgICAgICAgICAgICAgICAgIGEgPSBhLmNvbmNhdChzdGF0c1trXSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGEgPSBbXTsKLQotICAgICAgICAgICAgICAgIGZvciAoayBpbiBfam9icykKLSAgICAgICAgICAgICAgICAgICAgYS5wdXNoKF9qb2JzW2tdKTsKLQotICAgICAgICAgICAgICAgIGZvciAoayBpbiBfd2FpdGluZ0pvYnMpCi0gICAgICAgICAgICAgICAgICAgIGEucHVzaChfd2FpdGluZ0pvYnNba10pOwotCi0gICAgICAgICAgICAgICAgZm9yIChrIGluIF9ydW5uaW5nSm9icykKLSAgICAgICAgICAgICAgICAgICAgYS5wdXNoKF9ydW5uaW5nSm9ic1trXSk7Ci0KLSAgICAgICAgICAgICAgICBhID0gYS5jb25jYXQoX2RvbmVKb2JzKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgc3RhdHMgPSBbXTsKLSAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgICAgICBpZiAoaXNQYXR0ZXJuU3RyaW5nID8gYVtpXS5pZCA9PT0gcGF0dGVybiA6IGFbaV0uaWQubWF0Y2gocGF0dGVybikpCi0gICAgICAgICAgICAgICAgICAgIHN0YXRzLnB1c2goYVtpXSk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gX19jbG9uZShzdGF0cyk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUT09MUyBGVU5DVElPTlM6Ci0gICAgICogKioqKioqKioqKioqKioqKgotICAgICAqLwotCi0gICAgLyoqCi0gICAgICogVGhpcyBmdW5jdGlvbiB0YWtlcyBhbnkgbnVtYmVyIG9mIG9iamVjdHMgYXMgYXJndW1lbnRzLCBjb3BpZXMgZnJvbSBlYWNoCi0gICAgICogb2YgdGhlc2Ugb2JqZWN0cyBlYWNoIHBhaXIga2V5L3ZhbHVlIGludG8gYSBuZXcgb2JqZWN0LCBhbmQgZmluYWxseQotICAgICAqIHJldHVybnMgdGhpcyBvYmplY3QuCi0gICAgICoKLSAgICAgKiBUaGUgYXJndW1lbnRzIGFyZSBwYXJzZWQgZnJvbSB0aGUgbGFzdCBvbmUgdG8gdGhlIGZpcnN0IG9uZSwgc3VjaCB0aGF0Ci0gICAgICogd2hlbiB0d28gb2JqZWN0cyBoYXZlIGtleXMgaW4gY29tbW9uLCB0aGUgImVhcmxpZXN0IiBvYmplY3Qgd2lucy4KLSAgICAgKgotICAgICAqIEV4YW1wbGU6Ci0gICAgICogKioqKioqKioKLSAgICAgKiAgPiB2YXIgbzEgPSB7Ci0gICAqICA+ICAgICAgIGE6IDEsCi0gICAqICA+ICAgICAgIGI6IDIsCi0gICAqICA+ICAgICAgIGM6ICczJwotICAgKiAgPiAgICAgfSwKLSAgICAgKiAgPiAgICAgbzIgPSB7Ci0gICAqICA+ICAgICAgIGM6ICc0JywKLSAgICogID4gICAgICAgZDogWyA1IF0KLSAgICogID4gICAgIH07Ci0gICAgICogID4gX19leHRlbmQobzEsIG8yKTsKLSAgICAgKiAgPiAvLyBSZXR1cm5zOiB7Ci0gICAqICA+IC8vICAgYTogMSwKLSAgICogID4gLy8gICBiOiAyLAotICAgKiAgPiAvLyAgIGM6ICczJywKLSAgICogID4gLy8gICBkOiBbIDUgXQotICAgKiAgPiAvLyB9OwotICAgICAqCi0gICAgICogQHBhcmFtICB7T2JqZWN0K30gQW55IG51bWJlciBvZiBvYmplY3RzLgotICAgICAqIEByZXR1cm4ge09iamVjdH0gIFRoZSBtZXJnZWQgb2JqZWN0LgotICAgICAqLwotICAgIGZ1bmN0aW9uIF9fZXh0ZW5kKCkgewotICAgICAgICB2YXIgaSwKLSAgICAgICAgICAgIGssCi0gICAgICAgICAgICByZXMgPSB7fSwKLSAgICAgICAgICAgIGwgPSBhcmd1bWVudHMubGVuZ3RoOwotCi0gICAgICAgIGZvciAoaSA9IGwgLSAxOyBpID49IDA7IGktLSkKLSAgICAgICAgICAgIGZvciAoayBpbiBhcmd1bWVudHNbaV0pCi0gICAgICAgICAgICAgICAgcmVzW2tdID0gYXJndW1lbnRzW2ldW2tdOwotCi0gICAgICAgIHJldHVybiByZXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBmdW5jdGlvbiBzaW1wbHkgY2xvbmVzIGFuIG9iamVjdC4gVGhpcyBvYmplY3QgbXVzdCBjb250YWluIG9ubHkKLSAgICAgKiBvYmplY3RzLCBhcnJheXMgYW5kIGltbXV0YWJsZSB2YWx1ZXMuIFNpbmNlIGl0IGlzIG5vdCBwdWJsaWMsIGl0IGRvZXMgbm90Ci0gICAgICogZGVhbCB3aXRoIGN5Y2xpYyByZWZlcmVuY2VzLCBET00gZWxlbWVudHMgYW5kIGluc3RhbnRpYXRlZCBvYmplY3RzIC0gc28KLSAgICAgKiB1c2UgaXQgY2FyZWZ1bGx5LgotICAgICAqCi0gICAgICogQHBhcmFtICB7T2JqZWN0fSBUaGUgb2JqZWN0IHRvIGNsb25lLgotICAgICAqIEByZXR1cm4ge09iamVjdH0gVGhlIGNsb25lLgotICAgICAqLwotICAgIGZ1bmN0aW9uIF9fY2xvbmUoaXRlbSkgewotICAgICAgICB2YXIgcmVzdWx0LCBpLCBrLCBsOwotCi0gICAgICAgIGlmICghaXRlbSkKLSAgICAgICAgICAgIHJldHVybiBpdGVtOwotCi0gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGl0ZW0pKSB7Ci0gICAgICAgICAgICByZXN1bHQgPSBbXTsKLSAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBpdGVtLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgICAgICByZXN1bHQucHVzaChfX2Nsb25lKGl0ZW1baV0pKTsKLSAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcpIHsKLSAgICAgICAgICAgIHJlc3VsdCA9IHt9OwotICAgICAgICAgICAgZm9yIChpIGluIGl0ZW0pCi0gICAgICAgICAgICAgICAgcmVzdWx0W2ldID0gX19jbG9uZShpdGVtW2ldKTsKLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICByZXN1bHQgPSBpdGVtOwotCi0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIHRoZSB2YWx1ZXMgb2YgYW4gb2JqZWN0LgotICAgICAqCi0gICAgICogQHBhcmFtICB7T2JqZWN0fSBUaGUgb2JqZWN0LgotICAgICAqIEByZXR1cm4ge0FycmF5fSAgVGhlIGFycmF5IG9mIHZhbHVlcy4KLSAgICAgKi8KLSAgICBmdW5jdGlvbiBfX29iamVjdFZhbHVlcyhvKSB7Ci0gICAgICAgIHZhciBrLAotICAgICAgICAgICAgYSA9IFtdOwotCi0gICAgICAgIGZvciAoayBpbiBvKQotICAgICAgICAgICAgYS5wdXNoKG9ba10pOwotCi0gICAgICAgIHJldHVybiBhOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgc2hvcnQgIkRhdGUubm93KCkiIHBvbHlmaWxsLgotICAgICAqCi0gICAgICogQHJldHVybiB7TnVtYmVyfSBUaGUgY3VycmVudCB0aW1lIChpbiBtcykuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX19kYXRlTm93KCkgewotICAgICAgICByZXR1cm4gRGF0ZS5ub3cgPyBEYXRlLm5vdygpIDogbmV3IERhdGUoKS5nZXRUaW1lKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUG9seWZpbGwgZm9yIHRoZSBBcnJheS5pc0FycmF5IGZ1bmN0aW9uOgotICAgICAqLwotICAgIGlmICghQXJyYXkuaXNBcnJheSkKLSAgICAgICAgQXJyYXkuaXNBcnJheSA9IGZ1bmN0aW9uICh2KSB7Ci0gICAgICAgICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHYpID09PSAnW29iamVjdCBBcnJheV0nOwotICAgICAgICB9OwotCi0KLSAgICAvKioKLSAgICAgKiBFWFBPUlQgUFVCTElDIEFQSToKLSAgICAgKiAqKioqKioqKioqKioqKioqKioKLSAgICAgKi8KLSAgICB2YXIgY29ucmFkID0gewotICAgICAgICBoYXNKb2I6IF9oYXNKb2IsCi0gICAgICAgIGFkZEpvYjogX2FkZEpvYiwKLSAgICAgICAga2lsbEpvYjogX2tpbGxKb2IsCi0gICAgICAgIGtpbGxBbGw6IF9raWxsQWxsLAotICAgICAgICBzZXR0aW5nczogX3NldHRpbmdzLAotICAgICAgICBnZXRTdGF0czogX2dldFN0YXRzLAotICAgICAgICBpc1J1bm5pbmc6IF9nZXRJc1J1bm5pbmcsCi0gICAgICAgIGNsZWFySGlzdG9yeTogX2NsZWFySGlzdG9yeSwKLQotICAgICAgICAvLyBFdmVudHMgbWFuYWdlbWVudDoKLSAgICAgICAgYmluZDogX2JpbmQsCi0gICAgICAgIHVuYmluZDogX3VuYmluZCwKLQotICAgICAgICAvLyBWZXJzaW9uOgotICAgICAgICB2ZXJzaW9uOiAnMC4xLjAnCi0gICAgfTsKLQotICAgIGlmICh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHsKLSAgICAgICAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKQotICAgICAgICAgICAgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gY29ucmFkOwotICAgICAgICBleHBvcnRzLmNvbnJhZCA9IGNvbnJhZDsKLSAgICB9Ci0gICAgZ2xvYmFsLmNvbnJhZCA9IGNvbnJhZDsKLX0pKHRoaXMpOwotCi0vLyBIYXJkY29kZWQgZXhwb3J0IGZvciB0aGUgbm9kZS5qcyB2ZXJzaW9uOgotdmFyIHNpZ21hID0gdGhpcy5zaWdtYSwKLSAgICBjb25yYWQgPSB0aGlzLmNvbnJhZDsKLQotc2lnbWEuY29ucmFkID0gY29ucmFkOwotCi0vLyBEaXJ0eSBwb2x5ZmlsbHMgdG8gcGVybWl0IHNpZ21hIHVzYWdlIGluIG5vZGUKLWlmIChIVE1MRWxlbWVudCA9PT0gdW5kZWZpbmVkKQotICAgIHZhciBIVE1MRWxlbWVudCA9IGZ1bmN0aW9uICgpIHsKLSAgICB9OwotCi1pZiAod2luZG93ID09PSB1bmRlZmluZWQpCi0gICAgdmFyIHdpbmRvdyA9IHsKLSAgICAgICAgYWRkRXZlbnRMaXN0ZW5lcjogZnVuY3Rpb24gKCkgewotICAgICAgICB9Ci0gICAgfTsKLQotaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykgewotICAgIGlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUuZXhwb3J0cykKLSAgICAgICAgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gc2lnbWE7Ci0gICAgZXhwb3J0cy5zaWdtYSA9IHNpZ21hOwotfQotCi07KGZ1bmN0aW9uICh1bmRlZmluZWQpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBpZiAodHlwZW9mIHNpZ21hID09PSAndW5kZWZpbmVkJykKLSAgICAgICAgdGhyb3cgJ3NpZ21hIGlzIG5vdCBkZWNsYXJlZCc7Ci0KLSAgICB2YXIgX3Jvb3QgPSB0aGlzOwotCi0gICAgLy8gSW5pdGlhbGl6ZSBwYWNrYWdlczoKLSAgICBzaWdtYS51dGlscyA9IHNpZ21hLnV0aWxzIHx8IHt9OwotCi0gICAgLyoqCi0gICAgICogTUlTQyBVVElMUzoKLSAgICAgKi8KLSAgICAvKioKLSAgICAgKiBUaGlzIGZ1bmN0aW9uIHRha2VzIGFueSBudW1iZXIgb2Ygb2JqZWN0cyBhcyBhcmd1bWVudHMsIGNvcGllcyBmcm9tIGVhY2gKLSAgICAgKiBvZiB0aGVzZSBvYmplY3RzIGVhY2ggcGFpciBrZXkvdmFsdWUgaW50byBhIG5ldyBvYmplY3QsIGFuZCBmaW5hbGx5Ci0gICAgICogcmV0dXJucyB0aGlzIG9iamVjdC4KLSAgICAgKgotICAgICAqIFRoZSBhcmd1bWVudHMgYXJlIHBhcnNlZCBmcm9tIHRoZSBsYXN0IG9uZSB0byB0aGUgZmlyc3Qgb25lLCBzdWNoIHRoYXQKLSAgICAgKiB3aGVuIHNldmVyYWwgb2JqZWN0cyBoYXZlIGtleXMgaW4gY29tbW9uLCB0aGUgImVhcmxpZXN0IiBvYmplY3Qgd2lucy4KLSAgICAgKgotICAgICAqIEV4YW1wbGU6Ci0gICAgICogKioqKioqKioKLSAgICAgKiAgPiB2YXIgbzEgPSB7Ci0gICAqICA+ICAgICAgIGE6IDEsCi0gICAqICA+ICAgICAgIGI6IDIsCi0gICAqICA+ICAgICAgIGM6ICczJwotICAgKiAgPiAgICAgfSwKLSAgICAgKiAgPiAgICAgbzIgPSB7Ci0gICAqICA+ICAgICAgIGM6ICc0JywKLSAgICogID4gICAgICAgZDogWyA1IF0KLSAgICogID4gICAgIH07Ci0gICAgICogID4gc2lnbWEudXRpbHMuZXh0ZW5kKG8xLCBvMik7Ci0gICAgICogID4gLy8gUmV0dXJuczogewotICAgKiAgPiAvLyAgIGE6IDEsCi0gICAqICA+IC8vICAgYjogMiwKLSAgICogID4gLy8gICBjOiAnMycsCi0gICAqICA+IC8vICAgZDogWyA1IF0KLSAgICogID4gLy8gfTsKLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdCt9IEFueSBudW1iZXIgb2Ygb2JqZWN0cy4KLSAgICAgKiBAcmV0dXJuIHtvYmplY3R9ICBUaGUgbWVyZ2VkIG9iamVjdC4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5leHRlbmQgPSBmdW5jdGlvbiAoKSB7Ci0gICAgICAgIHZhciBpLAotICAgICAgICAgICAgaywKLSAgICAgICAgICAgIHJlcyA9IHt9LAotICAgICAgICAgICAgbCA9IGFyZ3VtZW50cy5sZW5ndGg7Ci0KLSAgICAgICAgZm9yIChpID0gbCAtIDE7IGkgPj0gMDsgaS0tKQotICAgICAgICAgICAgZm9yIChrIGluIGFyZ3VtZW50c1tpXSkKLSAgICAgICAgICAgICAgICByZXNba10gPSBhcmd1bWVudHNbaV1ba107Ci0KLSAgICAgICAgcmV0dXJuIHJlczsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogQSBzaG9ydCAiRGF0ZS5ub3coKSIgcG9seWZpbGwuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9IFRoZSBjdXJyZW50IHRpbWUgKGluIG1zKS4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5kYXRlTm93ID0gZnVuY3Rpb24gKCkgewotICAgICAgICByZXR1cm4gRGF0ZS5ub3cgPyBEYXRlLm5vdygpIDogbmV3IERhdGUoKS5nZXRUaW1lKCk7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFRha2VzIGEgcGFja2FnZSBuYW1lIGFzIHBhcmFtZXRlciBhbmQgY2hlY2tzIGF0IGVhY2ggbGViZWwgaWYgaXQgZXhpc3RzLAotICAgICAqIGFuZCBpZiBpdCBkb2VzIG5vdCwgY3JlYXRlcyBpdC4KLSAgICAgKgotICAgICAqIEV4YW1wbGU6Ci0gICAgICogKioqKioqKioKLSAgICAgKiAgPiBzaWdtYS51dGlscy5wa2coJ2EuYi5jJyk7Ci0gICAgICogID4gYS5iLmM7Ci0gICAgICogID4gLy8gT2JqZWN0IHt9OwotICAgICAqICA+Ci0gICAgICogID4gc2lnbWEudXRpbHMucGtnKCdhLmIuZCcpOwotICAgICAqICA+IGEuYjsKLSAgICAgKiAgPiAvLyBPYmplY3QgeyBjOiB7fSwgZDoge30gfTsKLSAgICAgKgotICAgICAqIEBwYXJhbSAge3N0cmluZ30gcGtnTmFtZSBUaGUgbmFtZSBvZiB0aGUgcGFja2FnZSB0byBjcmVhdGUvZmluZC4KLSAgICAgKiBAcmV0dXJuIHtvYmplY3R9ICAgICAgICAgVGhlIHJlbGF0ZWQgcGFja2FnZS4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5wa2cgPSBmdW5jdGlvbiAocGtnTmFtZSkgewotICAgICAgICByZXR1cm4gKHBrZ05hbWUgfHwgJycpLnNwbGl0KCcuJykucmVkdWNlKGZ1bmN0aW9uIChjb250ZXh0LCBvYmpOYW1lKSB7Ci0gICAgICAgICAgICByZXR1cm4gKG9iak5hbWUgaW4gY29udGV4dCkgPwotICAgICAgICAgICAgICAgIGNvbnRleHRbb2JqTmFtZV0gOgotICAgICAgICAgICAgICAgIChjb250ZXh0W29iak5hbWVdID0ge30pOwotICAgICAgICB9LCBfcm9vdCk7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSB1bmlxdWUgaW5jcmVtZW50YWwgbnVtYmVyIElELgotICAgICAqCi0gICAgICogRXhhbXBsZToKLSAgICAgKiAqKioqKioqKgotICAgICAqICA+IHNpZ21hLnV0aWxzLmlkKCk7Ci0gICAgICogID4gLy8gMTsKLSAgICAgKiAgPgotICAgICAqICA+IHNpZ21hLnV0aWxzLmlkKCk7Ci0gICAgICogID4gLy8gMjsKLSAgICAgKiAgPgotICAgICAqICA+IHNpZ21hLnV0aWxzLmlkKCk7Ci0gICAgICogID4gLy8gMzsKLSAgICAgKgotICAgICAqIEBwYXJhbSAge3N0cmluZ30gcGtnTmFtZSBUaGUgbmFtZSBvZiB0aGUgcGFja2FnZSB0byBjcmVhdGUvZmluZC4KLSAgICAgKiBAcmV0dXJuIHtvYmplY3R9ICAgICAgICAgVGhlIHJlbGF0ZWQgcGFja2FnZS4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5pZCA9IChmdW5jdGlvbiAoKSB7Ci0gICAgICAgIHZhciBpID0gMDsKLSAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsKLSAgICAgICAgICAgIHJldHVybiArK2k7Ci0gICAgICAgIH07Ci0gICAgfSkoKTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgZnVuY3Rpb24gdGFrZXMgYW4gaGV4YSBjb2xvciAoZm9yIGluc3RhbmNlICIjZmZjYzAwIiBvciAiI2ZjMCIpIG9yIGEKLSAgICAgKiByZ2IgLyByZ2JhIGNvbG9yIChsaWtlICJyZ2IoMjU1LDI1NSwxMikiIG9yICJyZ2JhKDI1NSwyNTUsMTIsMSkiKSBhbmQKLSAgICAgKiByZXR1cm5zIGFuIGludGVnZXIgZXF1YWwgdG8gInIgKiAyNTUgKiAyNTUgKyBnICogMjU1ICsgYiIsIHRvIGdhaW4gc29tZQotICAgICAqIG1lbW9yeSBpbiB0aGUgZGF0YSBnaXZlbiB0byBXZWJHTCBzaGFkZXJzLgotICAgICAqCi0gICAgICogTm90ZSB0aGF0IHRoZSBmdW5jdGlvbiBhY3R1YWxseSBjYWNoZXMgaXRzIHJlc3VsdHMgZm9yIGJldHRlciBwZXJmb3JtYW5jZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge3N0cmluZ30gdmFsIFRoZSBoZXhhIG9yIHJnYmEgY29sb3IuCi0gICAgICogQHJldHVybiB7bnVtYmVyfSAgICAgVGhlIG51bWJlciB2YWx1ZS4KLSAgICAgKi8KLSAgICB2YXIgZmxvYXRDb2xvckNhY2hlID0ge307Ci0KLSAgICBzaWdtYS51dGlscy5mbG9hdENvbG9yID0gZnVuY3Rpb24gKHZhbCkgewotCi0gICAgICAgIC8vIElzIHRoZSBjb2xvciBhbHJlYWR5IGNvbXB1dGVkPwotICAgICAgICBpZiAoZmxvYXRDb2xvckNhY2hlW3ZhbF0pCi0gICAgICAgICAgICByZXR1cm4gZmxvYXRDb2xvckNhY2hlW3ZhbF07Ci0KLSAgICAgICAgdmFyIG9yaWdpbmFsID0gdmFsLAotICAgICAgICAgICAgciA9IDAsCi0gICAgICAgICAgICBnID0gMCwKLSAgICAgICAgICAgIGIgPSAwOwotCi0gICAgICAgIGlmICh2YWxbMF0gPT09ICcjJykgewotICAgICAgICAgICAgdmFsID0gdmFsLnNsaWNlKDEpOwotCi0gICAgICAgICAgICBpZiAodmFsLmxlbmd0aCA9PT0gMykgewotICAgICAgICAgICAgICAgIHIgPSBwYXJzZUludCh2YWwuY2hhckF0KDApICsgdmFsLmNoYXJBdCgwKSwgMTYpOwotICAgICAgICAgICAgICAgIGcgPSBwYXJzZUludCh2YWwuY2hhckF0KDEpICsgdmFsLmNoYXJBdCgxKSwgMTYpOwotICAgICAgICAgICAgICAgIGIgPSBwYXJzZUludCh2YWwuY2hhckF0KDIpICsgdmFsLmNoYXJBdCgyKSwgMTYpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgciA9IHBhcnNlSW50KHZhbC5jaGFyQXQoMCkgKyB2YWwuY2hhckF0KDEpLCAxNik7Ci0gICAgICAgICAgICAgICAgZyA9IHBhcnNlSW50KHZhbC5jaGFyQXQoMikgKyB2YWwuY2hhckF0KDMpLCAxNik7Ci0gICAgICAgICAgICAgICAgYiA9IHBhcnNlSW50KHZhbC5jaGFyQXQoNCkgKyB2YWwuY2hhckF0KDUpLCAxNik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSBpZiAodmFsLm1hdGNoKC9eICpyZ2JhPyAqXCgvKSkgewotICAgICAgICAgICAgdmFsID0gdmFsLm1hdGNoKAotICAgICAgICAgICAgICAgIC9eICpyZ2JhPyAqXCggKihbMC05XSopICosICooWzAtOV0qKSAqLCAqKFswLTldKikgKigsLiopP1wpICokLwotICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIHIgPSArdmFsWzFdOwotICAgICAgICAgICAgZyA9ICt2YWxbMl07Ci0gICAgICAgICAgICBiID0gK3ZhbFszXTsKLSAgICAgICAgfQotCi0gICAgICAgIHZhciBjb2xvciA9ICgKLSAgICAgICAgICAgIHIgKiAyNTYgKiAyNTYgKwotICAgICAgICAgICAgZyAqIDI1NiArCi0gICAgICAgICAgICBiCi0gICAgICAgICk7Ci0KLSAgICAgICAgLy8gQ2FjaGluZyB0aGUgY29sb3IKLSAgICAgICAgZmxvYXRDb2xvckNhY2hlW29yaWdpbmFsXSA9IGNvbG9yOwotCi0gICAgICAgIHJldHVybiBjb2xvcjsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogUGVyZm9ybSBhIHpvb20gaW50byBhIGNhbWVyYSwgd2l0aCBvciB3aXRob3V0IGFuaW1hdGlvbiwgdG8gdGhlCi0gICAgICogY29vcmRpbmF0ZXMgaW5kaWNhdGVkIHVzaW5nIGEgc3BlY2lmaWVkIHJhdGlvLgotICAgICAqCi0gICAgICogUmVjb2duaXplZCBwYXJhbWV0ZXJzOgotICAgICAqICoqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBIZXJlIGlzIHRoZSBleGhhdXN0aXZlIGxpc3Qgb2YgZXZlcnkgYWNjZXB0ZWQgcGFyYW1ldGVycyBpbiB0aGUgYW5pbWF0aW9uCi0gICAgICogb2JqZWN0OgotICAgICAqCi0gICAgICogICB7P251bWJlcn0gZHVyYXRpb24gICAgIEFuIGFtb3VudCBvZiB0aW1lIHRoYXQgbWVhbnMgdGhlIGR1cmF0aW9uIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24uIElmIHRoaXMgcGFyYW1ldGVyIGRvZXNuJ3QgZXhpc3QgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHpvb20gd2lsbCBiZSBwZXJmb3JtZWQgd2l0aG91dCBhbmltYXRpb24uCi0gICAgICogICB7P2Z1bmN0aW9ufSBvbkNvbXBsZXRlIEEgZnVuY3Rpb24gdG8gcGVyZm9ybSBpdCBhZnRlciB0aGUgYW5pbWF0aW9uLiBJdAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxsIGJlIHBlcmZvcm1lZCBldmVuIGlmIHRoZXJlIGlzIG5vIGR1cmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIHtjYW1lcmF9ICAgICBUaGUgY2FtZXJhIHdoZXJlIHBlcmZvcm0gdGhlIHpvb20uCi0gICAgICogQHBhcmFtIHt4fSAgICAgICAgICBUaGUgWCBjb29yZGlhbnRpb24gd2hlcmUgdGhlIHpvb20gZ29lcy4KLSAgICAgKiBAcGFyYW0ge3l9ICAgICAgICAgIFRoZSBZIGNvb3JkaWFudGlvbiB3aGVyZSB0aGUgem9vbSBnb2VzLgotICAgICAqIEBwYXJhbSB7cmF0aW99ICAgICAgVGhlIHJhdGlvIHRvIGFwcGx5IGl0IHRvIHRoZSBjdXJyZW50IGNhbWVyYSByYXRpby4KLSAgICAgKiBAcGFyYW0gez9hbmltYXRpb259IEEgZGljdGlvbmFyeSB3aXRoIG9wdGlvbnMgZm9yIGEgcG9zc2libGUgYW5pbWF0aW9uLgotICAgICAqLwotICAgIHNpZ21hLnV0aWxzLnpvb21UbyA9IGZ1bmN0aW9uIChjYW1lcmEsIHgsIHksIHJhdGlvLCBhbmltYXRpb24pIHsKLSAgICAgICAgdmFyIHNldHRpbmdzID0gY2FtZXJhLnNldHRpbmdzLAotICAgICAgICAgICAgY291bnQsCi0gICAgICAgICAgICBuZXdSYXRpbywKLSAgICAgICAgICAgIGFuaW1hdGlvblNldHRpbmdzLAotICAgICAgICAgICAgY29vcmRpbmF0ZXM7Ci0KLSAgICAgICAgLy8gQ3JlYXRlIHRoZSBuZXdSYXRpbyBkZWFsaW5nIHdpdGggbWluIC8gbWF4OgotICAgICAgICBuZXdSYXRpbyA9IE1hdGgubWF4KAotICAgICAgICAgICAgc2V0dGluZ3MoJ3pvb21NaW4nKSwKLSAgICAgICAgICAgIE1hdGgubWluKAotICAgICAgICAgICAgICAgIHNldHRpbmdzKCd6b29tTWF4JyksCi0gICAgICAgICAgICAgICAgY2FtZXJhLnJhdGlvICogcmF0aW8KLSAgICAgICAgICAgICkKLSAgICAgICAgKTsKLQotICAgICAgICAvLyBDaGVjayB0aGF0IHRoZSBuZXcgcmF0aW8gaXMgZGlmZmVyZW50IGZyb20gdGhlIGluaXRpYWwgb25lOgotICAgICAgICBpZiAobmV3UmF0aW8gIT09IGNhbWVyYS5yYXRpbykgewotICAgICAgICAgICAgLy8gQ3JlYXRlIHRoZSBjb29yZGluYXRlcyB2YXJpYWJsZToKLSAgICAgICAgICAgIHJhdGlvID0gbmV3UmF0aW8gLyBjYW1lcmEucmF0aW87Ci0gICAgICAgICAgICBjb29yZGluYXRlcyA9IHsKLSAgICAgICAgICAgICAgICB4OiB4ICogKDEgLSByYXRpbykgKyBjYW1lcmEueCwKLSAgICAgICAgICAgICAgICB5OiB5ICogKDEgLSByYXRpbykgKyBjYW1lcmEueSwKLSAgICAgICAgICAgICAgICByYXRpbzogbmV3UmF0aW8KLSAgICAgICAgICAgIH07Ci0KLSAgICAgICAgICAgIGlmIChhbmltYXRpb24gJiYgYW5pbWF0aW9uLmR1cmF0aW9uKSB7Ci0gICAgICAgICAgICAgICAgLy8gQ29tcGxldGUgdGhlIGFuaW1hdGlvbiBzZXRpbmdzOgotICAgICAgICAgICAgICAgIGNvdW50ID0gc2lnbWEubWlzYy5hbmltYXRpb24ua2lsbEFsbChjYW1lcmEpOwotICAgICAgICAgICAgICAgIGFuaW1hdGlvbiA9IHNpZ21hLnV0aWxzLmV4dGVuZCgKLSAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uLAotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlYXNpbmc6IGNvdW50ID8gJ3F1YWRyYXRpY091dCcgOiAncXVhZHJhdGljSW5PdXQnCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICApOwotCi0gICAgICAgICAgICAgICAgc2lnbWEubWlzYy5hbmltYXRpb24uY2FtZXJhKGNhbWVyYSwgY29vcmRpbmF0ZXMsIGFuaW1hdGlvbik7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGNhbWVyYS5nb1RvKGNvb3JkaW5hdGVzKTsKLSAgICAgICAgICAgICAgICBpZiAoYW5pbWF0aW9uICYmIGFuaW1hdGlvbi5vbkNvbXBsZXRlKQotICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24ub25Db21wbGV0ZSgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgY29udHJvbCBwb2ludCBjb29yZGluYXRlcyBmb3IgYSBxdWFkcmF0aWMgYmV6aWVyIGN1cnZlLgotICAgICAqCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB4MSAgVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnQgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB5MSAgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnQgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB4MiAgVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50LgotICAgICAqIEBwYXJhbSAge251bWJlcn0geTIgIFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KLSAgICAgKiBAcmV0dXJuIHt4LHl9ICAgICAgICBUaGUgY29udHJvbCBwb2ludCBjb29yZGluYXRlcy4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5nZXRRdWFkcmF0aWNDb250cm9sUG9pbnQgPSBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIpIHsKLSAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgIHg6ICh4MSArIHgyKSAvIDIgKyAoeTIgLSB5MSkgLyA0LAotICAgICAgICAgICAgeTogKHkxICsgeTIpIC8gMiArICh4MSAtIHgyKSAvIDQKLSAgICAgICAgfTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogQ29tcHV0ZSB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIHBvaW50IHBvc2l0aW9uZWQKLSAgICAgKiBhdCBsZW5ndGggdCBpbiB0aGUgcXVhZHJhdGljIGJlemllciBjdXJ2ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge251bWJlcn0gdCAgSW4gWzAsMV0gdGhlIHN0ZXAgcGVyY2VudGFnZSB0byByZWFjaAotICAgICAqICAgICAgICAgICAgICAgICAgICAgdGhlIHBvaW50IGluIHRoZSBjdXJ2ZSBmcm9tIHRoZSBjb250ZXh0IHBvaW50LgotICAgICAqIEBwYXJhbSAge251bWJlcn0geDEgVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgY29udGV4dCBwb2ludC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHkxIFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGNvbnRleHQgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB4MiBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBlbmRpbmcgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB5MiBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBlbmRpbmcgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB4aSBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgotICAgICAqIEBwYXJhbSAge251bWJlcn0geWkgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgY29udHJvbCBwb2ludC4KLSAgICAgKiBAcmV0dXJuIHtvYmplY3R9ICAgIHt4LHl9LgotICAgICAqLwotICAgIHNpZ21hLnV0aWxzLmdldFBvaW50T25RdWFkcmF0aWNDdXJ2ZSA9IGZ1bmN0aW9uICh0LCB4MSwgeTEsIHgyLCB5MiwgeGksIHlpKSB7Ci0gICAgICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzU2MzQ1MjgKLSAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgIHg6IE1hdGgucG93KDEgLSB0LCAyKSAqIHgxICsgMiAqICgxIC0gdCkgKiB0ICogeGkgKyBNYXRoLnBvdyh0LCAyKSAqIHgyLAotICAgICAgICAgICAgeTogTWF0aC5wb3coMSAtIHQsIDIpICogeTEgKyAyICogKDEgLSB0KSAqIHQgKiB5aSArIE1hdGgucG93KHQsIDIpICogeTIKLSAgICAgICAgfTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogQ29tcHV0ZSB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIHBvaW50IHBvc2l0aW9uZWQKLSAgICAgKiBhdCBsZW5ndGggdCBpbiB0aGUgY3ViaWMgYmV6aWVyIGN1cnZlLgotICAgICAqCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB0ICBJbiBbMCwxXSB0aGUgc3RlcCBwZXJjZW50YWdlIHRvIHJlYWNoCi0gICAgICogICAgICAgICAgICAgICAgICAgICB0aGUgcG9pbnQgaW4gdGhlIGN1cnZlIGZyb20gdGhlIGNvbnRleHQgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB4MSBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBjb250ZXh0IHBvaW50LgotICAgICAqIEBwYXJhbSAge251bWJlcn0geTEgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgY29udGV4dCBwb2ludC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHgyIFRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHkyIFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IGN4IFRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSBjeSBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBjb250cm9sIHBvaW50LgotICAgICAqIEBwYXJhbSAge251bWJlcn0gZHggVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIGNvbnRyb2wgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSBkeSBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KLSAgICAgKiBAcmV0dXJuIHtvYmplY3R9ICAgIHt4LHl9IFRoZSBwb2ludCBhdCB0LgotICAgICAqLwotICAgIHNpZ21hLnV0aWxzLmdldFBvaW50T25CZXppZXJDdXJ2ZSA9Ci0gICAgICAgIGZ1bmN0aW9uICh0LCB4MSwgeTEsIHgyLCB5MiwgY3gsIGN5LCBkeCwgZHkpIHsKLSAgICAgICAgICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzE1Mzk3NTk2Ci0gICAgICAgICAgICAvLyBCbGVuZGluZyBmdW5jdGlvbnM6Ci0gICAgICAgICAgICB2YXIgQjBfdCA9IE1hdGgucG93KDEgLSB0LCAzKSwKLSAgICAgICAgICAgICAgICBCMV90ID0gMyAqIHQgKiBNYXRoLnBvdygxIC0gdCwgMiksCi0gICAgICAgICAgICAgICAgQjJfdCA9IDMgKiBNYXRoLnBvdyh0LCAyKSAqICgxIC0gdCksCi0gICAgICAgICAgICAgICAgQjNfdCA9IE1hdGgucG93KHQsIDMpOwotCi0gICAgICAgICAgICByZXR1cm4gewotICAgICAgICAgICAgICAgIHg6IChCMF90ICogeDEpICsgKEIxX3QgKiBjeCkgKyAoQjJfdCAqIGR4KSArIChCM190ICogeDIpLAotICAgICAgICAgICAgICAgIHk6IChCMF90ICogeTEpICsgKEIxX3QgKiBjeSkgKyAoQjJfdCAqIGR5KSArIChCM190ICogeTIpCi0gICAgICAgICAgICB9OwotICAgICAgICB9OwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgdHdvIGNvbnRyb2wgcG9pbnRzIGZvciBhIHNlbGYgbG9vcCAoaS5lLgotICAgICAqIHdoZXJlIHRoZSBzdGFydCBwb2ludCBpcyBhbHNvIHRoZSBlbmQgcG9pbnQpIGNvbXB1dGVkIGFzIGEgY3ViaWMgYmV6aWVyCi0gICAgICogY3VydmUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHggICAgVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgbm9kZS4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHkgICAgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgbm9kZS4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHNpemUgVGhlIG5vZGUgc2l6ZS4KLSAgICAgKiBAcmV0dXJuIHt4MSx5MSx4Mix5Mn0gVGhlIGNvb3JkaW5hdGVzIG9mIHRoZSB0d28gY29udHJvbCBwb2ludHMuCi0gICAgICovCi0gICAgc2lnbWEudXRpbHMuZ2V0U2VsZkxvb3BDb250cm9sUG9pbnRzID0gZnVuY3Rpb24gKHgsIHksIHNpemUpIHsKLSAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgIHgxOiB4IC0gc2l6ZSAqIDcsCi0gICAgICAgICAgICB5MTogeSwKLSAgICAgICAgICAgIHgyOiB4LAotICAgICAgICAgICAgeTI6IHkgKyBzaXplICogNwotICAgICAgICB9OwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGV1Y2xpZGlhbiBkaXN0YW5jZSBiZXR3ZWVuIHR3byBwb2ludHMgb2YgYSBwbGFuZQotICAgICAqIHdpdGggYW4gb3J0aG9ub3JtYWwgYmFzaXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHgxICBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBwb2ludC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHkxICBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBwb2ludC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHgyICBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB5MiAgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIHBvaW50LgotICAgICAqIEByZXR1cm4ge251bWJlcn0gICAgIFRoZSBldWNsaWRpYW4gZGlzdGFuY2UuCi0gICAgICovCi0gICAgc2lnbWEudXRpbHMuZ2V0RGlzdGFuY2UgPSBmdW5jdGlvbiAoeDAsIHkwLCB4MSwgeTEpIHsKLSAgICAgICAgcmV0dXJuIE1hdGguc3FydChNYXRoLnBvdyh4MSAtIHgwLCAyKSArIE1hdGgucG93KHkxIC0geTAsIDIpKTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgaW50ZXJzZWN0aW9uIHBvaW50cyBvZiB0d28gY2lyY2xlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge251bWJlcn0geDAgIFRoZSBYIGNvb3JkaW5hdGUgb2YgY2VudGVyIGxvY2F0aW9uIG9mIHRoZSBmaXJzdAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGNpcmNsZS4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHkwICBUaGUgWSBjb29yZGluYXRlIG9mIGNlbnRlciBsb2NhdGlvbiBvZiB0aGUgZmlyc3QKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBjaXJjbGUuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSByMCAgVGhlIHJhZGl1cyBvZiB0aGUgZmlyc3QgY2lyY2xlLgotICAgICAqIEBwYXJhbSAge251bWJlcn0geDEgIFRoZSBYIGNvb3JkaW5hdGUgb2YgY2VudGVyIGxvY2F0aW9uIG9mIHRoZSBzZWNvbmQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBjaXJjbGUuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB5MSAgVGhlIFkgY29vcmRpbmF0ZSBvZiBjZW50ZXIgbG9jYXRpb24gb2YgdGhlIHNlY29uZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGNpcmNsZS4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHIxICBUaGUgcmFkaXVzIG9mIHRoZSBzZWNvbmQgY2lyY2xlLgotICAgICAqIEByZXR1cm4ge3hpLHlpfSAgICAgIFRoZSBjb29yZGluYXRlcyBvZiB0aGUgaW50ZXJzZWN0aW9uIHBvaW50cy4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5nZXRDaXJjbGVJbnRlcnNlY3Rpb24gPSBmdW5jdGlvbiAoeDAsIHkwLCByMCwgeDEsIHkxLCByMSkgewotICAgICAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xMjIxOTgwMgotICAgICAgICB2YXIgYSwgZHgsIGR5LCBkLCBoLCByeCwgcnksIHgyLCB5MjsKLQotICAgICAgICAvLyBkeCBhbmQgZHkgYXJlIHRoZSB2ZXJ0aWNhbCBhbmQgaG9yaXpvbnRhbCBkaXN0YW5jZXMgYmV0d2VlbiB0aGUgY2lyY2xlCi0gICAgICAgIC8vIGNlbnRlcnM6Ci0gICAgICAgIGR4ID0geDEgLSB4MDsKLSAgICAgICAgZHkgPSB5MSAtIHkwOwotCi0gICAgICAgIC8vIERldGVybWluZSB0aGUgc3RyYWlnaHQtbGluZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBjZW50ZXJzOgotICAgICAgICBkID0gTWF0aC5zcXJ0KChkeSAqIGR5KSArIChkeCAqIGR4KSk7Ci0KLSAgICAgICAgLy8gQ2hlY2sgZm9yIHNvbHZhYmlsaXR5OgotICAgICAgICBpZiAoZCA+IChyMCArIHIxKSkgewotICAgICAgICAgICAgLy8gTm8gc29sdXRpb24uIGNpcmNsZXMgZG8gbm90IGludGVyc2VjdC4KLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZCA8IE1hdGguYWJzKHIwIC0gcjEpKSB7Ci0gICAgICAgICAgICAvLyBObyBzb2x1dGlvbi4gb25lIGNpcmNsZSBpcyBjb250YWluZWQgaW4gdGhlIG90aGVyLgotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8ncG9pbnQgMicgaXMgdGhlIHBvaW50IHdoZXJlIHRoZSBsaW5lIHRocm91Z2ggdGhlIGNpcmNsZSBpbnRlcnNlY3Rpb24KLSAgICAgICAgLy8gcG9pbnRzIGNyb3NzZXMgdGhlIGxpbmUgYmV0d2VlbiB0aGUgY2lyY2xlIGNlbnRlcnMuCi0KLSAgICAgICAgLy8gRGV0ZXJtaW5lIHRoZSBkaXN0YW5jZSBmcm9tIHBvaW50IDAgdG8gcG9pbnQgMjoKLSAgICAgICAgYSA9ICgocjAgKiByMCkgLSAocjEgKiByMSkgKyAoZCAqIGQpKSAvICgyLjAgKiBkKTsKLQotICAgICAgICAvLyBEZXRlcm1pbmUgdGhlIGNvb3JkaW5hdGVzIG9mIHBvaW50IDI6Ci0gICAgICAgIHgyID0geDAgKyAoZHggKiBhIC8gZCk7Ci0gICAgICAgIHkyID0geTAgKyAoZHkgKiBhIC8gZCk7Ci0KLSAgICAgICAgLy8gRGV0ZXJtaW5lIHRoZSBkaXN0YW5jZSBmcm9tIHBvaW50IDIgdG8gZWl0aGVyIG9mIHRoZSBpbnRlcnNlY3Rpb24KLSAgICAgICAgLy8gcG9pbnRzOgotICAgICAgICBoID0gTWF0aC5zcXJ0KChyMCAqIHIwKSAtIChhICogYSkpOwotCi0gICAgICAgIC8vIERldGVybWluZSB0aGUgb2Zmc2V0cyBvZiB0aGUgaW50ZXJzZWN0aW9uIHBvaW50cyBmcm9tIHBvaW50IDI6Ci0gICAgICAgIHJ4ID0gLWR5ICogKGggLyBkKTsKLSAgICAgICAgcnkgPSBkeCAqIChoIC8gZCk7Ci0KLSAgICAgICAgLy8gRGV0ZXJtaW5lIHRoZSBhYnNvbHV0ZSBpbnRlcnNlY3Rpb24gcG9pbnRzOgotICAgICAgICB2YXIgeGkgPSB4MiArIHJ4OwotICAgICAgICB2YXIgeGlfcHJpbWUgPSB4MiAtIHJ4OwotICAgICAgICB2YXIgeWkgPSB5MiArIHJ5OwotICAgICAgICB2YXIgeWlfcHJpbWUgPSB5MiAtIHJ5OwotCi0gICAgICAgIHJldHVybiB7eGk6IHhpLCB4aV9wcmltZTogeGlfcHJpbWUsIHlpOiB5aSwgeWlfcHJpbWU6IHlpX3ByaW1lfTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgaWYgYSBwb2ludCBpcyBvbiBhIGxpbmUgc2VnbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge251bWJlcn0geCAgICAgICBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBwb2ludCB0byBjaGVjay4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHkgICAgICAgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQgdG8gY2hlY2suCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB4MSAgICAgIFRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIGxpbmUgc3RhcnQgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB5MSAgICAgIFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGxpbmUgc3RhcnQgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB4MiAgICAgIFRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIGxpbmUgZW5kIHBvaW50LgotICAgICAqIEBwYXJhbSAge251bWJlcn0geTIgICAgICBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBsaW5lIGVuZCBwb2ludC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IGVwc2lsb24gVGhlIHByZWNpc2lvbiAoY29uc2lkZXIgdGhlIGxpbmUgdGhpY2tuZXNzKS4KLSAgICAgKiBAcmV0dXJuIHtib29sZWFufSAgICAgICAgVHJ1ZSBpZiBwb2ludCBpcyAiY2xvc2UgdG8iIHRoZSBsaW5lCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHNlZ21lbnQsIGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5pc1BvaW50T25TZWdtZW50ID0gZnVuY3Rpb24gKHgsIHksIHgxLCB5MSwgeDIsIHkyLCBlcHNpbG9uKSB7Ci0gICAgICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzMyODEyMgotICAgICAgICB2YXIgY3Jvc3NQcm9kdWN0ID0gTWF0aC5hYnMoKHkgLSB5MSkgKiAoeDIgLSB4MSkgLSAoeCAtIHgxKSAqICh5MiAtIHkxKSksCi0gICAgICAgICAgICBkID0gc2lnbWEudXRpbHMuZ2V0RGlzdGFuY2UoeDEsIHkxLCB4MiwgeTIpLAotICAgICAgICAgICAgbkNyb3NzUHJvZHVjdCA9IGNyb3NzUHJvZHVjdCAvIGQ7IC8vIG5vcm1hbGl6ZWQgY3Jvc3MgcHJvZHVjdAotCi0gICAgICAgIHJldHVybiAobkNyb3NzUHJvZHVjdCA8IGVwc2lsb24gJiYKLSAgICAgICAgTWF0aC5taW4oeDEsIHgyKSA8PSB4ICYmIHggPD0gTWF0aC5tYXgoeDEsIHgyKSAmJgotICAgICAgICBNYXRoLm1pbih5MSwgeTIpIDw9IHkgJiYgeSA8PSBNYXRoLm1heCh5MSwgeTIpKTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgaWYgYSBwb2ludCBpcyBvbiBhIHF1YWRyYXRpYyBiZXppZXIgY3VydmUgc2VnbWVudCB3aXRoIGEgdGhpY2tuZXNzLgotICAgICAqCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB4ICAgICAgIFRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50IHRvIGNoZWNrLgotICAgICAqIEBwYXJhbSAge251bWJlcn0geSAgICAgICBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBwb2ludCB0byBjaGVjay4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHgxICAgICAgVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgY3VydmUgc3RhcnQgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB5MSAgICAgIFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGN1cnZlIHN0YXJ0IHBvaW50LgotICAgICAqIEBwYXJhbSAge251bWJlcn0geDIgICAgICBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBjdXJ2ZSBlbmQgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB5MiAgICAgIFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGN1cnZlIGVuZCBwb2ludC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IGNweCAgICAgVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgY3VydmUgY29udHJvbCBwb2ludC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IGNweSAgICAgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgY3VydmUgY29udHJvbCBwb2ludC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IGVwc2lsb24gVGhlIHByZWNpc2lvbiAoY29uc2lkZXIgdGhlIGxpbmUgdGhpY2tuZXNzKS4KLSAgICAgKiBAcmV0dXJuIHtib29sZWFufSAgICAgICAgVHJ1ZSBpZiAoeCx5KSBpcyBvbiB0aGUgY3VydmUgc2VnbWVudCwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHNpZ21hLnV0aWxzLmlzUG9pbnRPblF1YWRyYXRpY0N1cnZlID0KLSAgICAgICAgZnVuY3Rpb24gKHgsIHksIHgxLCB5MSwgeDIsIHkyLCBjcHgsIGNweSwgZXBzaWxvbikgewotICAgICAgICAgICAgLy8gRmFpbHMgaWYgdGhlIHBvaW50IGlzIHRvbyBmYXIgZnJvbSB0aGUgZXh0cmVtaXRpZXMgb2YgdGhlIHNlZ21lbnQsCi0gICAgICAgICAgICAvLyBwcmV2ZW50aW5nIGZvciBtb3JlIGNvc3RseSBjb21wdXRhdGlvbjoKLSAgICAgICAgICAgIHZhciBkUDFQMiA9IHNpZ21hLnV0aWxzLmdldERpc3RhbmNlKHgxLCB5MSwgeDIsIHkyKTsKLSAgICAgICAgICAgIGlmIChNYXRoLmFicyh4IC0geDEpID4gZFAxUDIgfHwgTWF0aC5hYnMoeSAtIHkxKSA+IGRQMVAyKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB2YXIgZFAxID0gc2lnbWEudXRpbHMuZ2V0RGlzdGFuY2UoeCwgeSwgeDEsIHkxKSwKLSAgICAgICAgICAgICAgICBkUDIgPSBzaWdtYS51dGlscy5nZXREaXN0YW5jZSh4LCB5LCB4MiwgeTIpLAotICAgICAgICAgICAgICAgIHQgPSAwLjUsCi0gICAgICAgICAgICAgICAgciA9IChkUDEgPCBkUDIpID8gLTAuMDEgOiAwLjAxLAotICAgICAgICAgICAgICAgIHJUaHJlc2hvbGQgPSAwLjAwMSwKLSAgICAgICAgICAgICAgICBpID0gMTAwLAotICAgICAgICAgICAgICAgIHB0ID0gc2lnbWEudXRpbHMuZ2V0UG9pbnRPblF1YWRyYXRpY0N1cnZlKHQsIHgxLCB5MSwgeDIsIHkyLCBjcHgsIGNweSksCi0gICAgICAgICAgICAgICAgZHQgPSBzaWdtYS51dGlscy5nZXREaXN0YW5jZSh4LCB5LCBwdC54LCBwdC55KSwKLSAgICAgICAgICAgICAgICBvbGRfZHQ7Ci0KLSAgICAgICAgICAgIC8vIFRoaXMgYWxnb3JpdGhtIG1pbmltaXplcyB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgcG9pbnQgdG8gdGhlIGN1cnZlLiBJdAotICAgICAgICAgICAgLy8gZmluZCB0aGUgb3B0aW1hbCB0IHZhbHVlIHdoZXJlIHQ9MCBpcyB0aGUgc3RhcnQgcG9pbnQgYW5kIHQ9MSBpcyB0aGUgZW5kCi0gICAgICAgICAgICAvLyBwb2ludCBvZiB0aGUgY3VydmUsIHN0YXJ0aW5nIGZyb20gdD0wLjUuCi0gICAgICAgICAgICAvLyBJdCB0ZXJtaW5hdGVzIGJlY2F1c2UgaXQgcnVucyBhIG1heGltdW0gb2YgaSBpbnRlcmF0aW9ucy4KLSAgICAgICAgICAgIHdoaWxlIChpLS0gPiAwICYmCi0gICAgICAgICAgICB0ID49IDAgJiYgdCA8PSAxICYmCi0gICAgICAgICAgICAoZHQgPiBlcHNpbG9uKSAmJgotICAgICAgICAgICAgKHIgPiByVGhyZXNob2xkIHx8IHIgPCAtclRocmVzaG9sZCkpIHsKLSAgICAgICAgICAgICAgICBvbGRfZHQgPSBkdDsKLSAgICAgICAgICAgICAgICBwdCA9IHNpZ21hLnV0aWxzLmdldFBvaW50T25RdWFkcmF0aWNDdXJ2ZSh0LCB4MSwgeTEsIHgyLCB5MiwgY3B4LCBjcHkpOwotICAgICAgICAgICAgICAgIGR0ID0gc2lnbWEudXRpbHMuZ2V0RGlzdGFuY2UoeCwgeSwgcHQueCwgcHQueSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoZHQgPiBvbGRfZHQpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gbm90IHRoZSByaWdodCBkaXJlY3Rpb246Ci0gICAgICAgICAgICAgICAgICAgIC8vIGhhbGZzdGVwIGluIHRoZSBvcHBvc2l0ZSBkaXJlY3Rpb24KLSAgICAgICAgICAgICAgICAgICAgciA9IC1yIC8gMjsKLSAgICAgICAgICAgICAgICAgICAgdCArPSByOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmICh0ICsgciA8IDAgfHwgdCArIHIgPiAxKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIG9vcHMsIHdlJ3ZlIGdvbmUgdG9vIGZhcjoKLSAgICAgICAgICAgICAgICAgICAgLy8gcmV2ZXJ0IHdpdGggYSBoYWxmc3RlcAotICAgICAgICAgICAgICAgICAgICByID0gciAvIDI7Ci0gICAgICAgICAgICAgICAgICAgIGR0ID0gb2xkX2R0OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gcHJvZ3Jlc3M6Ci0gICAgICAgICAgICAgICAgICAgIHQgKz0gcjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiBkdCA8IGVwc2lsb247Ci0gICAgICAgIH07Ci0KLQotICAgIC8qKgotICAgICAqIENoZWNrIGlmIGEgcG9pbnQgaXMgb24gYSBjdWJpYyBiZXppZXIgY3VydmUgc2VnbWVudCB3aXRoIGEgdGhpY2tuZXNzLgotICAgICAqCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB4ICAgICAgIFRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50IHRvIGNoZWNrLgotICAgICAqIEBwYXJhbSAge251bWJlcn0geSAgICAgICBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBwb2ludCB0byBjaGVjay4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHgxICAgICAgVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgY3VydmUgc3RhcnQgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB5MSAgICAgIFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGN1cnZlIHN0YXJ0IHBvaW50LgotICAgICAqIEBwYXJhbSAge251bWJlcn0geDIgICAgICBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBjdXJ2ZSBlbmQgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB5MiAgICAgIFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGN1cnZlIGVuZCBwb2ludC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IGNweDEgICAgVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgMXN0IGN1cnZlIGNvbnRyb2wgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSBjcHkxICAgIFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIDFzdCBjdXJ2ZSBjb250cm9sIHBvaW50LgotICAgICAqIEBwYXJhbSAge251bWJlcn0gY3B4MiAgICBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSAybmQgY3VydmUgY29udHJvbCBwb2ludC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IGNweTIgICAgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgMm5kIGN1cnZlIGNvbnRyb2wgcG9pbnQuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSBlcHNpbG9uIFRoZSBwcmVjaXNpb24gKGNvbnNpZGVyIHRoZSBsaW5lIHRoaWNrbmVzcykuCi0gICAgICogQHJldHVybiB7Ym9vbGVhbn0gICAgICAgIFRydWUgaWYgKHgseSkgaXMgb24gdGhlIGN1cnZlIHNlZ21lbnQsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5pc1BvaW50T25CZXppZXJDdXJ2ZSA9Ci0gICAgICAgIGZ1bmN0aW9uICh4LCB5LCB4MSwgeTEsIHgyLCB5MiwgY3B4MSwgY3B5MSwgY3B4MiwgY3B5MiwgZXBzaWxvbikgewotICAgICAgICAgICAgLy8gRmFpbHMgaWYgdGhlIHBvaW50IGlzIHRvbyBmYXIgZnJvbSB0aGUgZXh0cmVtaXRpZXMgb2YgdGhlIHNlZ21lbnQsCi0gICAgICAgICAgICAvLyBwcmV2ZW50aW5nIGZvciBtb3JlIGNvc3RseSBjb21wdXRhdGlvbjoKLSAgICAgICAgICAgIHZhciBkUDFDUDEgPSBzaWdtYS51dGlscy5nZXREaXN0YW5jZSh4MSwgeTEsIGNweDEsIGNweTEpOwotICAgICAgICAgICAgaWYgKE1hdGguYWJzKHggLSB4MSkgPiBkUDFDUDEgfHwgTWF0aC5hYnMoeSAtIHkxKSA+IGRQMUNQMSkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgdmFyIGRQMSA9IHNpZ21hLnV0aWxzLmdldERpc3RhbmNlKHgsIHksIHgxLCB5MSksCi0gICAgICAgICAgICAgICAgZFAyID0gc2lnbWEudXRpbHMuZ2V0RGlzdGFuY2UoeCwgeSwgeDIsIHkyKSwKLSAgICAgICAgICAgICAgICB0ID0gMC41LAotICAgICAgICAgICAgICAgIHIgPSAoZFAxIDwgZFAyKSA/IC0wLjAxIDogMC4wMSwKLSAgICAgICAgICAgICAgICByVGhyZXNob2xkID0gMC4wMDEsCi0gICAgICAgICAgICAgICAgaSA9IDEwMCwKLSAgICAgICAgICAgICAgICBwdCA9IHNpZ21hLnV0aWxzLmdldFBvaW50T25CZXppZXJDdXJ2ZSgKLSAgICAgICAgICAgICAgICAgICAgdCwgeDEsIHkxLCB4MiwgeTIsIGNweDEsIGNweTEsIGNweDIsIGNweTIpLAotICAgICAgICAgICAgICAgIGR0ID0gc2lnbWEudXRpbHMuZ2V0RGlzdGFuY2UoeCwgeSwgcHQueCwgcHQueSksCi0gICAgICAgICAgICAgICAgb2xkX2R0OwotCi0gICAgICAgICAgICAvLyBUaGlzIGFsZ29yaXRobSBtaW5pbWl6ZXMgdGhlIGRpc3RhbmNlIGZyb20gdGhlIHBvaW50IHRvIHRoZSBjdXJ2ZS4gSXQKLSAgICAgICAgICAgIC8vIGZpbmQgdGhlIG9wdGltYWwgdCB2YWx1ZSB3aGVyZSB0PTAgaXMgdGhlIHN0YXJ0IHBvaW50IGFuZCB0PTEgaXMgdGhlIGVuZAotICAgICAgICAgICAgLy8gcG9pbnQgb2YgdGhlIGN1cnZlLCBzdGFydGluZyBmcm9tIHQ9MC41LgotICAgICAgICAgICAgLy8gSXQgdGVybWluYXRlcyBiZWNhdXNlIGl0IHJ1bnMgYSBtYXhpbXVtIG9mIGkgaW50ZXJhdGlvbnMuCi0gICAgICAgICAgICB3aGlsZSAoaS0tID4gMCAmJgotICAgICAgICAgICAgdCA+PSAwICYmIHQgPD0gMSAmJgotICAgICAgICAgICAgKGR0ID4gZXBzaWxvbikgJiYKLSAgICAgICAgICAgIChyID4gclRocmVzaG9sZCB8fCByIDwgLXJUaHJlc2hvbGQpKSB7Ci0gICAgICAgICAgICAgICAgb2xkX2R0ID0gZHQ7Ci0gICAgICAgICAgICAgICAgcHQgPSBzaWdtYS51dGlscy5nZXRQb2ludE9uQmV6aWVyQ3VydmUoCi0gICAgICAgICAgICAgICAgICAgIHQsIHgxLCB5MSwgeDIsIHkyLCBjcHgxLCBjcHkxLCBjcHgyLCBjcHkyKTsKLSAgICAgICAgICAgICAgICBkdCA9IHNpZ21hLnV0aWxzLmdldERpc3RhbmNlKHgsIHksIHB0LngsIHB0LnkpOwotCi0gICAgICAgICAgICAgICAgaWYgKGR0ID4gb2xkX2R0KSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIG5vdCB0aGUgcmlnaHQgZGlyZWN0aW9uOgotICAgICAgICAgICAgICAgICAgICAvLyBoYWxmc3RlcCBpbiB0aGUgb3Bwb3NpdGUgZGlyZWN0aW9uCi0gICAgICAgICAgICAgICAgICAgIHIgPSAtciAvIDI7Ci0gICAgICAgICAgICAgICAgICAgIHQgKz0gcjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAodCArIHIgPCAwIHx8IHQgKyByID4gMSkgewotICAgICAgICAgICAgICAgICAgICAvLyBvb3BzLCB3ZSd2ZSBnb25lIHRvbyBmYXI6Ci0gICAgICAgICAgICAgICAgICAgIC8vIHJldmVydCB3aXRoIGEgaGFsZnN0ZXAKLSAgICAgICAgICAgICAgICAgICAgciA9IHIgLyAyOwotICAgICAgICAgICAgICAgICAgICBkdCA9IG9sZF9kdDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHByb2dyZXNzOgotICAgICAgICAgICAgICAgICAgICB0ICs9IHI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gZHQgPCBlcHNpbG9uOwotICAgICAgICB9OwotCi0KLSAgICAvKioKLSAgICAgKiAqKioqKioqKioqKioKLSAgICAgKiBFVkVOVFMgVVRJTFM6Ci0gICAgICogKioqKioqKioqKioqCi0gICAgICovCi0gICAgLyoqCi0gICAgICogSGVyZSBhcmUgc29tZSB1c2VmdWwgZnVuY3Rpb25zIHRvIHVuaWZ5IGV4dHJhY3Rpb24gb2YgdGhlIGluZm9ybWF0aW9uIHdlCi0gICAgICogbmVlZCB3aXRoIG1vdXNlIGV2ZW50cyBhbmQgdG91Y2ggZXZlbnRzLCBmcm9tIGRpZmZlcmVudCBicm93c2VyczoKLSAgICAgKi8KLQotICAgIC8qKgotICAgICAqIEV4dHJhY3QgdGhlIGxvY2FsIFggcG9zaXRpb24gZnJvbSBhIG1vdXNlIG9yIHRvdWNoIGV2ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtICB7ZXZlbnR9ICBlIEEgbW91c2Ugb3IgdG91Y2ggZXZlbnQuCi0gICAgICogQHJldHVybiB7bnVtYmVyfSAgIFRoZSBsb2NhbCBYIHZhbHVlIG9mIHRoZSBtb3VzZS4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5nZXRYID0gZnVuY3Rpb24gKGUpIHsKLSAgICAgICAgcmV0dXJuICgKLSAgICAgICAgICAgIChlLm9mZnNldFggIT09IHVuZGVmaW5lZCAmJiBlLm9mZnNldFgpIHx8Ci0gICAgICAgICAgICAoZS5sYXllclggIT09IHVuZGVmaW5lZCAmJiBlLmxheWVyWCkgfHwKLSAgICAgICAgICAgIChlLmNsaWVudFggIT09IHVuZGVmaW5lZCAmJiBlLmNsaWVudFgpCi0gICAgICAgICk7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIEV4dHJhY3QgdGhlIGxvY2FsIFkgcG9zaXRpb24gZnJvbSBhIG1vdXNlIG9yIHRvdWNoIGV2ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtICB7ZXZlbnR9ICBlIEEgbW91c2Ugb3IgdG91Y2ggZXZlbnQuCi0gICAgICogQHJldHVybiB7bnVtYmVyfSAgIFRoZSBsb2NhbCBZIHZhbHVlIG9mIHRoZSBtb3VzZS4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5nZXRZID0gZnVuY3Rpb24gKGUpIHsKLSAgICAgICAgcmV0dXJuICgKLSAgICAgICAgICAgIChlLm9mZnNldFkgIT09IHVuZGVmaW5lZCAmJiBlLm9mZnNldFkpIHx8Ci0gICAgICAgICAgICAoZS5sYXllclkgIT09IHVuZGVmaW5lZCAmJiBlLmxheWVyWSkgfHwKLSAgICAgICAgICAgIChlLmNsaWVudFkgIT09IHVuZGVmaW5lZCAmJiBlLmNsaWVudFkpCi0gICAgICAgICk7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFRoZSBwaXhlbCByYXRpbyBvZiB0aGUgc2NyZWVuLiBUYWtpbmcgem9vbSBpbnRvIGFjY291bnQKLSAgICAgKgotICAgICAqIEByZXR1cm4ge251bWJlcn0gICAgICAgIFBpeGVsIHJhdGlvIG9mIHRoZSBzY3JlZW4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5nZXRQaXhlbFJhdGlvID0gZnVuY3Rpb24gKCkgewotICAgICAgICB2YXIgcmF0aW8gPSAxOwotICAgICAgICBpZiAod2luZG93LnNjcmVlbi5kZXZpY2VYRFBJICE9PSB1bmRlZmluZWQgJiYKLSAgICAgICAgICAgIHdpbmRvdy5zY3JlZW4ubG9naWNhbFhEUEkgIT09IHVuZGVmaW5lZCAmJgotICAgICAgICAgICAgd2luZG93LnNjcmVlbi5kZXZpY2VYRFBJID4gd2luZG93LnNjcmVlbi5sb2dpY2FsWERQSSkgewotICAgICAgICAgICAgcmF0aW8gPSB3aW5kb3cuc2NyZWVuLnN5c3RlbVhEUEkgLyB3aW5kb3cuc2NyZWVuLmxvZ2ljYWxYRFBJOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvICE9PSB1bmRlZmluZWQpIHsKLSAgICAgICAgICAgIHJhdGlvID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJhdGlvOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBFeHRyYWN0IHRoZSB3aWR0aCBmcm9tIGEgbW91c2Ugb3IgdG91Y2ggZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtldmVudH0gIGUgQSBtb3VzZSBvciB0b3VjaCBldmVudC4KLSAgICAgKiBAcmV0dXJuIHtudW1iZXJ9ICAgVGhlIHdpZHRoIG9mIHRoZSBldmVudCdzIHRhcmdldC4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5nZXRXaWR0aCA9IGZ1bmN0aW9uIChlKSB7Ci0gICAgICAgIHZhciB3ID0gKCFlLnRhcmdldC5vd25lclNWR0VsZW1lbnQpID8KLSAgICAgICAgICAgIGUudGFyZ2V0LndpZHRoIDoKLSAgICAgICAgICAgIGUudGFyZ2V0Lm93bmVyU1ZHRWxlbWVudC53aWR0aDsKLQotICAgICAgICByZXR1cm4gKAotICAgICAgICAgICAgKHR5cGVvZiB3ID09PSAnbnVtYmVyJyAmJiB3KSB8fAotICAgICAgICAgICAgKHcgIT09IHVuZGVmaW5lZCAmJiB3LmJhc2VWYWwgIT09IHVuZGVmaW5lZCAmJiB3LmJhc2VWYWwudmFsdWUpCi0gICAgICAgICk7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIEV4dHJhY3QgdGhlIGNlbnRlciBmcm9tIGEgbW91c2Ugb3IgdG91Y2ggZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtldmVudH0gIGUgQSBtb3VzZSBvciB0b3VjaCBldmVudC4KLSAgICAgKiBAcmV0dXJuIHtvYmplY3R9ICAgVGhlIGNlbnRlciBvZiB0aGUgZXZlbnQncyB0YXJnZXQuCi0gICAgICovCi0gICAgc2lnbWEudXRpbHMuZ2V0Q2VudGVyID0gZnVuY3Rpb24gKGUpIHsKLSAgICAgICAgdmFyIHJhdGlvID0gZS50YXJnZXQubmFtZXNwYWNlVVJJLmluZGV4T2YoJ3N2ZycpICE9PSAtMSA/IDEgOgotICAgICAgICAgICAgc2lnbWEudXRpbHMuZ2V0UGl4ZWxSYXRpbygpOwotICAgICAgICByZXR1cm4gewotICAgICAgICAgICAgeDogc2lnbWEudXRpbHMuZ2V0V2lkdGgoZSkgLyAoMiAqIHJhdGlvKSwKLSAgICAgICAgICAgIHk6IHNpZ21hLnV0aWxzLmdldEhlaWdodChlKSAvICgyICogcmF0aW8pLAotICAgICAgICB9OwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZXJ0IG1vdXNlIGNvb3JkcyB0byBzaWdtYSBjb29yZHMKLSAgICAgKgotICAgICAqIEBwYXJhbSAge2V2ZW50fSAgIGUgQSBtb3VzZSBvciB0b3VjaCBldmVudC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXI/fSB4IFRoZSB4IGNvb3JkIHRvIGNvbnZlcnQKLSAgICAgKiBAcGFyYW0gIHtudW1iZXI/fSB4IFRoZSB5IGNvb3JkIHRvIGNvbnZlcnQKLSAgICAgKgotICAgICAqIEByZXR1cm4ge29iamVjdH0gICAgVGhlIHN0YW5kYXJkaXplZCBldmVudAotICAgICAqLwotICAgIHNpZ21hLnV0aWxzLm1vdXNlQ29vcmRzID0gZnVuY3Rpb24gKGUsIHgsIHkpIHsKLSAgICAgICAgeCA9IHggfHwgc2lnbWEudXRpbHMuZ2V0WChlKTsKLSAgICAgICAgeSA9IHkgfHwgc2lnbWEudXRpbHMuZ2V0WShlKTsKLSAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgIHg6IHggLSBzaWdtYS51dGlscy5nZXRDZW50ZXIoZSkueCwKLSAgICAgICAgICAgIHk6IHkgLSBzaWdtYS51dGlscy5nZXRDZW50ZXIoZSkueSwKLSAgICAgICAgICAgIGNsaWVudFg6IGUuY2xpZW50WCwKLSAgICAgICAgICAgIGNsaWVudFk6IGUuY2xpZW50WSwKLSAgICAgICAgICAgIGN0cmxLZXk6IGUuY3RybEtleSwKLSAgICAgICAgICAgIG1ldGFLZXk6IGUubWV0YUtleSwKLSAgICAgICAgICAgIGFsdEtleTogZS5hbHRLZXksCi0gICAgICAgICAgICBzaGlmdEtleTogZS5zaGlmdEtleQotICAgICAgICB9OwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBFeHRyYWN0IHRoZSBoZWlnaHQgZnJvbSBhIG1vdXNlIG9yIHRvdWNoIGV2ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtICB7ZXZlbnR9ICBlIEEgbW91c2Ugb3IgdG91Y2ggZXZlbnQuCi0gICAgICogQHJldHVybiB7bnVtYmVyfSAgIFRoZSBoZWlnaHQgb2YgdGhlIGV2ZW50J3MgdGFyZ2V0LgotICAgICAqLwotICAgIHNpZ21hLnV0aWxzLmdldEhlaWdodCA9IGZ1bmN0aW9uIChlKSB7Ci0gICAgICAgIHZhciBoID0gKCFlLnRhcmdldC5vd25lclNWR0VsZW1lbnQpID8KLSAgICAgICAgICAgIGUudGFyZ2V0LmhlaWdodCA6Ci0gICAgICAgICAgICBlLnRhcmdldC5vd25lclNWR0VsZW1lbnQuaGVpZ2h0OwotCi0gICAgICAgIHJldHVybiAoCi0gICAgICAgICAgICAodHlwZW9mIGggPT09ICdudW1iZXInICYmIGgpIHx8Ci0gICAgICAgICAgICAoaCAhPT0gdW5kZWZpbmVkICYmIGguYmFzZVZhbCAhPT0gdW5kZWZpbmVkICYmIGguYmFzZVZhbC52YWx1ZSkKLSAgICAgICAgKTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogRXh0cmFjdCB0aGUgd2hlZWwgZGVsdGEgZnJvbSBhIG1vdXNlIG9yIHRvdWNoIGV2ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtICB7ZXZlbnR9ICBlIEEgbW91c2Ugb3IgdG91Y2ggZXZlbnQuCi0gICAgICogQHJldHVybiB7bnVtYmVyfSAgIFRoZSB3aGVlbCBkZWx0YSBvZiB0aGUgbW91c2UuCi0gICAgICovCi0gICAgc2lnbWEudXRpbHMuZ2V0RGVsdGEgPSBmdW5jdGlvbiAoZSkgewotICAgICAgICByZXR1cm4gKAotICAgICAgICAgICAgKGUud2hlZWxEZWx0YSAhPT0gdW5kZWZpbmVkICYmIGUud2hlZWxEZWx0YSkgfHwKLSAgICAgICAgICAgIChlLmRldGFpbCAhPT0gdW5kZWZpbmVkICYmIC1lLmRldGFpbCkKLSAgICAgICAgKTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgb2Zmc2V0IG9mIGEgRE9NIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtET01FbGVtZW50fSBkb20gVGhlIGVsZW1lbnQgdG8gcmV0cmlldmUgdGhlIHBvc2l0aW9uLgotICAgICAqIEByZXR1cm4ge29iamVjdH0gICAgICAgICBUaGUgb2Zmc2V0IG9mIHRoZSBET00gZWxlbWVudCAodG9wLCBsZWZ0KS4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5nZXRPZmZzZXQgPSBmdW5jdGlvbiAoZG9tKSB7Ci0gICAgICAgIHZhciBsZWZ0ID0gMCwKLSAgICAgICAgICAgIHRvcCA9IDA7Ci0KLSAgICAgICAgd2hpbGUgKGRvbSkgewotICAgICAgICAgICAgdG9wID0gdG9wICsgcGFyc2VJbnQoZG9tLm9mZnNldFRvcCk7Ci0gICAgICAgICAgICBsZWZ0ID0gbGVmdCArIHBhcnNlSW50KGRvbS5vZmZzZXRMZWZ0KTsKLSAgICAgICAgICAgIGRvbSA9IGRvbS5vZmZzZXRQYXJlbnQ7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gewotICAgICAgICAgICAgdG9wOiB0b3AsCi0gICAgICAgICAgICBsZWZ0OiBsZWZ0Ci0gICAgICAgIH07Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFNpbXVsYXRlcyBhICJkb3VibGUgY2xpY2siIGV2ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtICB7SFRNTEVsZW1lbnR9IHRhcmdldCAgIFRoZSBldmVudCB0YXJnZXQuCi0gICAgICogQHBhcmFtICB7c3RyaW5nfSAgICAgIHR5cGUgICAgIFRoZSBldmVudCB0eXBlLgotICAgICAqIEBwYXJhbSAge2Z1bmN0aW9ufSAgICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gZXhlY3V0ZS4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5kb3VibGVDbGljayA9IGZ1bmN0aW9uICh0YXJnZXQsIHR5cGUsIGNhbGxiYWNrKSB7Ci0gICAgICAgIHZhciBjbGlja3MgPSAwLAotICAgICAgICAgICAgc2VsZiA9IHRoaXMsCi0gICAgICAgICAgICBoYW5kbGVyczsKLQotICAgICAgICB0YXJnZXQuX2RvdWJsZUNsaWNrSGFuZGxlciA9IHRhcmdldC5fZG91YmxlQ2xpY2tIYW5kbGVyIHx8IHt9OwotICAgICAgICB0YXJnZXQuX2RvdWJsZUNsaWNrSGFuZGxlclt0eXBlXSA9IHRhcmdldC5fZG91YmxlQ2xpY2tIYW5kbGVyW3R5cGVdIHx8IFtdOwotICAgICAgICBoYW5kbGVycyA9IHRhcmdldC5fZG91YmxlQ2xpY2tIYW5kbGVyW3R5cGVdOwotCi0gICAgICAgIGhhbmRsZXJzLnB1c2goZnVuY3Rpb24gKGUpIHsKLSAgICAgICAgICAgIGNsaWNrcysrOwotCi0gICAgICAgICAgICBpZiAoY2xpY2tzID09PSAyKSB7Ci0gICAgICAgICAgICAgICAgY2xpY2tzID0gMDsKLSAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZSk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGNsaWNrcyA9PT0gMSkgewotICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewotICAgICAgICAgICAgICAgICAgICBjbGlja3MgPSAwOwotICAgICAgICAgICAgICAgIH0sIHNpZ21hLnNldHRpbmdzLmRvdWJsZUNsaWNrVGltZW91dCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pOwotCi0gICAgICAgIHRhcmdldC5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGhhbmRsZXJzW2hhbmRsZXJzLmxlbmd0aCAtIDFdLCBmYWxzZSk7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFVuYmluZCBzaW11bGF0ZWQgImRvdWJsZSBjbGljayIgZXZlbnRzLgotICAgICAqCi0gICAgICogQHBhcmFtICB7SFRNTEVsZW1lbnR9IHRhcmdldCAgIFRoZSBldmVudCB0YXJnZXQuCi0gICAgICogQHBhcmFtICB7c3RyaW5nfSAgICAgIHR5cGUgICAgIFRoZSBldmVudCB0eXBlLgotICAgICAqLwotICAgIHNpZ21hLnV0aWxzLnVuYmluZERvdWJsZUNsaWNrID0gZnVuY3Rpb24gKHRhcmdldCwgdHlwZSkgewotICAgICAgICB2YXIgaGFuZGxlciwKLSAgICAgICAgICAgIGhhbmRsZXJzID0gKHRhcmdldC5fZG91YmxlQ2xpY2tIYW5kbGVyIHx8IHt9KVt0eXBlXSB8fCBbXTsKLQotICAgICAgICB3aGlsZSAoKGhhbmRsZXIgPSBoYW5kbGVycy5wb3AoKSkpIHsKLSAgICAgICAgICAgIHRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGhhbmRsZXIpOwotICAgICAgICB9Ci0KLSAgICAgICAgZGVsZXRlICh0YXJnZXQuX2RvdWJsZUNsaWNrSGFuZGxlciB8fCB7fSlbdHlwZV07Ci0gICAgfTsKLQotCi0gICAgLyoqCi0gICAgICogSGVyZSBhcmUganVzdCBzb21lIG9mIHRoZSBtb3N0IGJhc2ljIGVhc2luZyBmdW5jdGlvbnMsIHVzZWQgZm9yIHRoZQotICAgICAqIGFuaW1hdGVkIGNhbWVyYSAiZ29UbyIgY2FsbHMuCi0gICAgICoKLSAgICAgKiBJZiB5b3UgbmVlZCBzb21lIG1vcmUgZWFzaW5ncyBmdW5jdGlvbnMsIGRvbid0IGhlc2l0YXRlIHRvIGFkZCB0aGVtIHRvCi0gICAgICogc2lnbWEudXRpbHMuZWFzaW5ncy4gQnV0IEkgd2lsbCBub3QgYWRkIHNvbWUgbW9yZSBoZXJlIG9yIG1lcmdlIFBScwotICAgICAqIGNvbnRhaW5pbmcsIGJlY2F1c2UgSSBkbyBub3Qgd2FudCBzaWdtYSBzb3VyY2VzIGZ1bGwgb2Ygb3ZlcmtpbGwgYW5kIG5ldmVyCi0gICAgICogdXNlZCBzdHVmZi4uLgotICAgICAqLwotICAgIHNpZ21hLnV0aWxzLmVhc2luZ3MgPSBzaWdtYS51dGlscy5lYXNpbmdzIHx8IHt9OwotICAgIHNpZ21hLnV0aWxzLmVhc2luZ3MubGluZWFyTm9uZSA9IGZ1bmN0aW9uIChrKSB7Ci0gICAgICAgIHJldHVybiBrOwotICAgIH07Ci0gICAgc2lnbWEudXRpbHMuZWFzaW5ncy5xdWFkcmF0aWNJbiA9IGZ1bmN0aW9uIChrKSB7Ci0gICAgICAgIHJldHVybiBrICogazsKLSAgICB9OwotICAgIHNpZ21hLnV0aWxzLmVhc2luZ3MucXVhZHJhdGljT3V0ID0gZnVuY3Rpb24gKGspIHsKLSAgICAgICAgcmV0dXJuIGsgKiAoMiAtIGspOwotICAgIH07Ci0gICAgc2lnbWEudXRpbHMuZWFzaW5ncy5xdWFkcmF0aWNJbk91dCA9IGZ1bmN0aW9uIChrKSB7Ci0gICAgICAgIGlmICgoayAqPSAyKSA8IDEpCi0gICAgICAgICAgICByZXR1cm4gMC41ICogayAqIGs7Ci0gICAgICAgIHJldHVybiAtMC41ICogKC0tayAqIChrIC0gMikgLSAxKTsKLSAgICB9OwotICAgIHNpZ21hLnV0aWxzLmVhc2luZ3MuY3ViaWNJbiA9IGZ1bmN0aW9uIChrKSB7Ci0gICAgICAgIHJldHVybiBrICogayAqIGs7Ci0gICAgfTsKLSAgICBzaWdtYS51dGlscy5lYXNpbmdzLmN1YmljT3V0ID0gZnVuY3Rpb24gKGspIHsKLSAgICAgICAgcmV0dXJuIC0tayAqIGsgKiBrICsgMTsKLSAgICB9OwotICAgIHNpZ21hLnV0aWxzLmVhc2luZ3MuY3ViaWNJbk91dCA9IGZ1bmN0aW9uIChrKSB7Ci0gICAgICAgIGlmICgoayAqPSAyKSA8IDEpCi0gICAgICAgICAgICByZXR1cm4gMC41ICogayAqIGsgKiBrOwotICAgICAgICByZXR1cm4gMC41ICogKChrIC09IDIpICogayAqIGsgKyAyKTsKLSAgICB9OwotCi0KLSAgICAvKioKLSAgICAgKiAqKioqKioqKioqKioKLSAgICAgKiBXRUJHTCBVVElMUzoKLSAgICAgKiAqKioqKioqKioqKioKLSAgICAgKi8KLSAgICAvKioKLSAgICAgKiBMb2FkcyBhIFdlYkdMIHNoYWRlciBhbmQgcmV0dXJucyBpdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge1dlYkdMQ29udGV4dH0gICAgICAgICAgIGdsICAgICAgICAgICBUaGUgV2ViR0xDb250ZXh0IHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gIHtzdHJpbmd9ICAgICAgICAgICAgICAgICBzaGFkZXJTb3VyY2UgVGhlIHNoYWRlciBzb3VyY2UuCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSAgICAgICAgICAgICAgICAgc2hhZGVyVHlwZSAgIFRoZSB0eXBlIG9mIHNoYWRlci4KLSAgICAgKiBAcGFyYW0gIHtmdW5jdGlvbihzdHJpbmcpOiB2b2lkfSBlcnJvciAgICAgICAgQ2FsbGJhY2sgZm9yIGVycm9ycy4KLSAgICAgKiBAcmV0dXJuIHtXZWJHTFNoYWRlcn0gICAgICAgICAgICAgICAgICAgICAgICAgVGhlIGNyZWF0ZWQgc2hhZGVyLgotICAgICAqLwotICAgIHNpZ21hLnV0aWxzLmxvYWRTaGFkZXIgPSBmdW5jdGlvbiAoZ2wsIHNoYWRlclNvdXJjZSwgc2hhZGVyVHlwZSwgZXJyb3IpIHsKLSAgICAgICAgdmFyIGNvbXBpbGVkLAotICAgICAgICAgICAgc2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKHNoYWRlclR5cGUpOwotCi0gICAgICAgIC8vIExvYWQgdGhlIHNoYWRlciBzb3VyY2UKLSAgICAgICAgZ2wuc2hhZGVyU291cmNlKHNoYWRlciwgc2hhZGVyU291cmNlKTsKLQotICAgICAgICAvLyBDb21waWxlIHRoZSBzaGFkZXIKLSAgICAgICAgZ2wuY29tcGlsZVNoYWRlcihzaGFkZXIpOwotCi0gICAgICAgIC8vIENoZWNrIHRoZSBjb21waWxlIHN0YXR1cwotICAgICAgICBjb21waWxlZCA9IGdsLmdldFNoYWRlclBhcmFtZXRlcihzaGFkZXIsIGdsLkNPTVBJTEVfU1RBVFVTKTsKLQotICAgICAgICAvLyBJZiBzb21ldGhpbmcgd2VudCB3cm9uZzoKLSAgICAgICAgaWYgKCFjb21waWxlZCkgewotICAgICAgICAgICAgaWYgKGVycm9yKSB7Ci0gICAgICAgICAgICAgICAgZXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICdFcnJvciBjb21waWxpbmcgc2hhZGVyICInICsgc2hhZGVyICsgJyI6JyArCi0gICAgICAgICAgICAgICAgICAgIGdsLmdldFNoYWRlckluZm9Mb2coc2hhZGVyKQotICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGdsLmRlbGV0ZVNoYWRlcihzaGFkZXIpOwotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gc2hhZGVyOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgcHJvZ3JhbSwgYXR0YWNoZXMgc2hhZGVycywgYmluZHMgYXR0cmliIGxvY2F0aW9ucywgbGlua3MgdGhlCi0gICAgICogcHJvZ3JhbSBhbmQgY2FsbHMgdXNlUHJvZ3JhbS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge0FycmF5LjxXZWJHTFNoYWRlcj59ICAgIHNoYWRlcnMgICBUaGUgc2hhZGVycyB0byBhdHRhY2guCi0gICAgICogQHBhcmFtICB7QXJyYXkuPHN0cmluZz59ICAgICAgICAgYXR0cmlicyAgIFRoZSBhdHRyaWJzIG5hbWVzLgotICAgICAqIEBwYXJhbSAge0FycmF5LjxudW1iZXI+fSAgICAgICAgIGxvY2F0aW9ucyBUaGUgbG9jYXRpb25zIGZvciB0aGUgYXR0cmlicy4KLSAgICAgKiBAcGFyYW0gIHtmdW5jdGlvbihzdHJpbmcpOiB2b2lkfSBlcnJvciAgICAgQ2FsbGJhY2sgZm9yIGVycm9ycy4KLSAgICAgKiBAcmV0dXJuIHtXZWJHTFByb2dyYW19ICAgICAgICAgICAgICAgICAgICAgVGhlIGNyZWF0ZWQgcHJvZ3JhbS4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5sb2FkUHJvZ3JhbSA9IGZ1bmN0aW9uIChnbCwgc2hhZGVycywgYXR0cmlicywgbG9jLCBlcnJvcikgewotICAgICAgICB2YXIgaSwKLSAgICAgICAgICAgIGxpbmtlZCwKLSAgICAgICAgICAgIHByb2dyYW0gPSBnbC5jcmVhdGVQcm9ncmFtKCk7Ci0KLSAgICAgICAgZm9yIChpID0gMDsgaSA8IHNoYWRlcnMubGVuZ3RoOyArK2kpCi0gICAgICAgICAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgc2hhZGVyc1tpXSk7Ci0KLSAgICAgICAgaWYgKGF0dHJpYnMpCi0gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYXR0cmlicy5sZW5ndGg7ICsraSkKLSAgICAgICAgICAgICAgICBnbC5iaW5kQXR0cmliTG9jYXRpb24oCi0gICAgICAgICAgICAgICAgICAgIHByb2dyYW0sCi0gICAgICAgICAgICAgICAgICAgIGxvY2F0aW9ucyA/IGxvY2F0aW9uc1tpXSA6IGksCi0gICAgICAgICAgICAgICAgICAgIG9wdF9hdHRyaWJzW2ldCi0gICAgICAgICAgICAgICAgKTsKLQotICAgICAgICBnbC5saW5rUHJvZ3JhbShwcm9ncmFtKTsKLQotICAgICAgICAvLyBDaGVjayB0aGUgbGluayBzdGF0dXMKLSAgICAgICAgbGlua2VkID0gZ2wuZ2V0UHJvZ3JhbVBhcmFtZXRlcihwcm9ncmFtLCBnbC5MSU5LX1NUQVRVUyk7Ci0gICAgICAgIGlmICghbGlua2VkKSB7Ci0gICAgICAgICAgICBpZiAoZXJyb3IpCi0gICAgICAgICAgICAgICAgZXJyb3IoJ0Vycm9yIGluIHByb2dyYW0gbGlua2luZzogJyArIGdsLmdldFByb2dyYW1JbmZvTG9nKHByb2dyYW0pKTsKLQotICAgICAgICAgICAgZ2wuZGVsZXRlUHJvZ3JhbShwcm9ncmFtKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHByb2dyYW07Ci0gICAgfTsKLQotCi0gICAgLyoqCi0gICAgICogKioqKioqKioqCi0gICAgICogTUFUUklDRVM6Ci0gICAgICogKioqKioqKioqCi0gICAgICogVGhlIGZvbGxvd2luZyB1dGlscyBhcmUganVzdCBoZXJlIHRvIGhlbHAgZ2VuZXJhdGluZyB0aGUgdHJhbnNmb3JtYXRpb24KLSAgICAgKiBtYXRyaWNlcyBmb3IgdGhlIFdlYkdMIHJlbmRlcmVycy4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLnV0aWxzLm1hdHJpY2VzJyk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgcmV0dXJucyBhIDN4MyB0cmFuc2xhdGlvbiBtYXRyaXguCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IGR4IFRoZSBYIHRyYW5zbGF0aW9uLgotICAgICAqIEBwYXJhbSAge251bWJlcn0gZHkgVGhlIFkgdHJhbnNsYXRpb24uCi0gICAgICogQHJldHVybiB7YXJyYXl9ICAgICBSZXR1cm5zIHRoZSBtYXRyaXguCi0gICAgICovCi0gICAgc2lnbWEudXRpbHMubWF0cmljZXMudHJhbnNsYXRpb24gPSBmdW5jdGlvbiAoZHgsIGR5KSB7Ci0gICAgICAgIHJldHVybiBbCi0gICAgICAgICAgICAxLCAwLCAwLAotICAgICAgICAgICAgMCwgMSwgMCwKLSAgICAgICAgICAgIGR4LCBkeSwgMQotICAgICAgICBdOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgcmV0dXJucyBhIDN4MyBvciAyeDIgcm90YXRpb24gbWF0cml4LgotICAgICAqCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSAgYW5nbGUgVGhlIHJvdGF0aW9uIGFuZ2xlLgotICAgICAqIEBwYXJhbSAge2Jvb2xlYW59IG0yICAgIElmIHRydWUsIHRoZSBmdW5jdGlvbiB3aWxsIHJldHVybiBhIDJ4MiBtYXRyaXguCi0gICAgICogQHJldHVybiB7YXJyYXl9ICAgICAgICAgUmV0dXJucyB0aGUgbWF0cml4LgotICAgICAqLwotICAgIHNpZ21hLnV0aWxzLm1hdHJpY2VzLnJvdGF0aW9uID0gZnVuY3Rpb24gKGFuZ2xlLCBtMikgewotICAgICAgICB2YXIgY29zID0gTWF0aC5jb3MoYW5nbGUpLAotICAgICAgICAgICAgc2luID0gTWF0aC5zaW4oYW5nbGUpOwotCi0gICAgICAgIHJldHVybiBtMiA/IFsKLSAgICAgICAgICAgIGNvcywgLXNpbiwKLSAgICAgICAgICAgIHNpbiwgY29zCi0gICAgICAgIF0gOiBbCi0gICAgICAgICAgICBjb3MsIC1zaW4sIDAsCi0gICAgICAgICAgICBzaW4sIGNvcywgMCwKLSAgICAgICAgICAgIDAsIDAsIDEKLSAgICAgICAgXTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhlIHJldHVybnMgYSAzeDMgb3IgMngyIGhvbW90aGV0aWMgdHJhbnNmb3JtYXRpb24gbWF0cml4LgotICAgICAqCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSAgcmF0aW8gVGhlIHNjYWxpbmcgcmF0aW8uCi0gICAgICogQHBhcmFtICB7Ym9vbGVhbn0gbTIgICAgSWYgdHJ1ZSwgdGhlIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIGEgMngyIG1hdHJpeC4KLSAgICAgKiBAcmV0dXJuIHthcnJheX0gICAgICAgICBSZXR1cm5zIHRoZSBtYXRyaXguCi0gICAgICovCi0gICAgc2lnbWEudXRpbHMubWF0cmljZXMuc2NhbGUgPSBmdW5jdGlvbiAocmF0aW8sIG0yKSB7Ci0gICAgICAgIHJldHVybiBtMiA/IFsKLSAgICAgICAgICAgIHJhdGlvLCAwLAotICAgICAgICAgICAgMCwgcmF0aW8KLSAgICAgICAgXSA6IFsKLSAgICAgICAgICAgIHJhdGlvLCAwLCAwLAotICAgICAgICAgICAgMCwgcmF0aW8sIDAsCi0gICAgICAgICAgICAwLCAwLCAxCi0gICAgICAgIF07Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFRoZSByZXR1cm5zIGEgM3gzIG9yIDJ4MiBob21vdGhldGljIHRyYW5zZm9ybWF0aW9uIG1hdHJpeC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge2FycmF5fSAgIGEgIFRoZSBmaXJzdCBtYXRyaXguCi0gICAgICogQHBhcmFtICB7YXJyYXl9ICAgYiAgVGhlIHNlY29uZCBtYXRyaXguCi0gICAgICogQHBhcmFtICB7Ym9vbGVhbn0gbTIgSWYgdHJ1ZSwgdGhlIGZ1bmN0aW9uIHdpbGwgYXNzdW1lIGJvdGggbWF0cmljZXMgYXJlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgMngyLgotICAgICAqIEByZXR1cm4ge2FycmF5fSAgICAgIFJldHVybnMgdGhlIG1hdHJpeC4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5tYXRyaWNlcy5tdWx0aXBseSA9IGZ1bmN0aW9uIChhLCBiLCBtMikgewotICAgICAgICB2YXIgbCA9IG0yID8gMiA6IDMsCi0gICAgICAgICAgICBhMDAgPSBhWzAgKiBsICsgMF0sCi0gICAgICAgICAgICBhMDEgPSBhWzAgKiBsICsgMV0sCi0gICAgICAgICAgICBhMDIgPSBhWzAgKiBsICsgMl0sCi0gICAgICAgICAgICBhMTAgPSBhWzEgKiBsICsgMF0sCi0gICAgICAgICAgICBhMTEgPSBhWzEgKiBsICsgMV0sCi0gICAgICAgICAgICBhMTIgPSBhWzEgKiBsICsgMl0sCi0gICAgICAgICAgICBhMjAgPSBhWzIgKiBsICsgMF0sCi0gICAgICAgICAgICBhMjEgPSBhWzIgKiBsICsgMV0sCi0gICAgICAgICAgICBhMjIgPSBhWzIgKiBsICsgMl0sCi0gICAgICAgICAgICBiMDAgPSBiWzAgKiBsICsgMF0sCi0gICAgICAgICAgICBiMDEgPSBiWzAgKiBsICsgMV0sCi0gICAgICAgICAgICBiMDIgPSBiWzAgKiBsICsgMl0sCi0gICAgICAgICAgICBiMTAgPSBiWzEgKiBsICsgMF0sCi0gICAgICAgICAgICBiMTEgPSBiWzEgKiBsICsgMV0sCi0gICAgICAgICAgICBiMTIgPSBiWzEgKiBsICsgMl0sCi0gICAgICAgICAgICBiMjAgPSBiWzIgKiBsICsgMF0sCi0gICAgICAgICAgICBiMjEgPSBiWzIgKiBsICsgMV0sCi0gICAgICAgICAgICBiMjIgPSBiWzIgKiBsICsgMl07Ci0KLSAgICAgICAgcmV0dXJuIG0yID8gWwotICAgICAgICAgICAgYTAwICogYjAwICsgYTAxICogYjEwLAotICAgICAgICAgICAgYTAwICogYjAxICsgYTAxICogYjExLAotICAgICAgICAgICAgYTEwICogYjAwICsgYTExICogYjEwLAotICAgICAgICAgICAgYTEwICogYjAxICsgYTExICogYjExCi0gICAgICAgIF0gOiBbCi0gICAgICAgICAgICBhMDAgKiBiMDAgKyBhMDEgKiBiMTAgKyBhMDIgKiBiMjAsCi0gICAgICAgICAgICBhMDAgKiBiMDEgKyBhMDEgKiBiMTEgKyBhMDIgKiBiMjEsCi0gICAgICAgICAgICBhMDAgKiBiMDIgKyBhMDEgKiBiMTIgKyBhMDIgKiBiMjIsCi0gICAgICAgICAgICBhMTAgKiBiMDAgKyBhMTEgKiBiMTAgKyBhMTIgKiBiMjAsCi0gICAgICAgICAgICBhMTAgKiBiMDEgKyBhMTEgKiBiMTEgKyBhMTIgKiBiMjEsCi0gICAgICAgICAgICBhMTAgKiBiMDIgKyBhMTEgKiBiMTIgKyBhMTIgKiBiMjIsCi0gICAgICAgICAgICBhMjAgKiBiMDAgKyBhMjEgKiBiMTAgKyBhMjIgKiBiMjAsCi0gICAgICAgICAgICBhMjAgKiBiMDEgKyBhMjEgKiBiMTEgKyBhMjIgKiBiMjEsCi0gICAgICAgICAgICBhMjAgKiBiMDIgKyBhMjEgKiBiMTIgKyBhMjIgKiBiMjIKLSAgICAgICAgXTsKLSAgICB9OwotfSkuY2FsbCh0aGlzKTsKLQotOyhmdW5jdGlvbiAoZ2xvYmFsKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgLyoqCi0gICAgICogaHR0cDovL3BhdWxpcmlzaC5jb20vMjAxMS9yZXF1ZXN0YW5pbWF0aW9uZnJhbWUtZm9yLXNtYXJ0LWFuaW1hdGluZy8KLSAgICAgKiBodHRwOi8vbXkub3BlcmEuY29tL2Vtb2xsZXIvYmxvZy8yMDExLzEyLzIwL3JlcXVlc3RhbmltYXRpb25mcmFtZS1mb3Itc21hcnQtZXItYW5pbWF0aW5nCi0gICAgICogcmVxdWVzdEFuaW1hdGlvbkZyYW1lIHBvbHlmaWxsIGJ5IEVyaWsgTcO2bGxlci4KLSAgICAgKiBmaXhlcyBmcm9tIFBhdWwgSXJpc2ggYW5kIFRpbm8gWmlqZGVsCi0gICAgICogTUlUIGxpY2Vuc2UKLSAgICAgKi8KLSAgICB2YXIgeCwKLSAgICAgICAgbGFzdFRpbWUgPSAwLAotICAgICAgICB2ZW5kb3JzID0gWydtcycsICdtb3onLCAnd2Via2l0JywgJ28nXTsKLQotICAgIGZvciAoeCA9IDA7IHggPCB2ZW5kb3JzLmxlbmd0aCAmJiAhZ2xvYmFsLnJlcXVlc3RBbmltYXRpb25GcmFtZTsgeCsrKSB7Ci0gICAgICAgIGdsb2JhbC5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPQotICAgICAgICAgICAgZ2xvYmFsW3ZlbmRvcnNbeF0gKyAnUmVxdWVzdEFuaW1hdGlvbkZyYW1lJ107Ci0gICAgICAgIGdsb2JhbC5jYW5jZWxBbmltYXRpb25GcmFtZSA9Ci0gICAgICAgICAgICBnbG9iYWxbdmVuZG9yc1t4XSArICdDYW5jZWxBbmltYXRpb25GcmFtZSddIHx8Ci0gICAgICAgICAgICBnbG9iYWxbdmVuZG9yc1t4XSArICdDYW5jZWxSZXF1ZXN0QW5pbWF0aW9uRnJhbWUnXTsKLSAgICB9Ci0KLSAgICBpZiAoIWdsb2JhbC5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUpCi0gICAgICAgIGdsb2JhbC5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSBmdW5jdGlvbiAoY2FsbGJhY2ssIGVsZW1lbnQpIHsKLSAgICAgICAgICAgIHZhciBjdXJyVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpLAotICAgICAgICAgICAgICAgIHRpbWVUb0NhbGwgPSBNYXRoLm1heCgwLCAxNiAtIChjdXJyVGltZSAtIGxhc3RUaW1lKSksCi0gICAgICAgICAgICAgICAgaWQgPSBnbG9iYWwuc2V0VGltZW91dCgKLSAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKCkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soY3VyclRpbWUgKyB0aW1lVG9DYWxsKTsKLSAgICAgICAgICAgICAgICAgICAgfSwKLSAgICAgICAgICAgICAgICAgICAgdGltZVRvQ2FsbAotICAgICAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIGxhc3RUaW1lID0gY3VyclRpbWUgKyB0aW1lVG9DYWxsOwotICAgICAgICAgICAgcmV0dXJuIGlkOwotICAgICAgICB9OwotCi0gICAgaWYgKCFnbG9iYWwuY2FuY2VsQW5pbWF0aW9uRnJhbWUpCi0gICAgICAgIGdsb2JhbC5jYW5jZWxBbmltYXRpb25GcmFtZSA9IGZ1bmN0aW9uIChpZCkgewotICAgICAgICAgICAgY2xlYXJUaW1lb3V0KGlkKTsKLSAgICAgICAgfTsKLQotICAgIC8qKgotICAgICAqIEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIHBvbHlmaWxsIGZvdW5kIG9uIE1ETi4KLSAgICAgKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9GdW5jdGlvbi9iaW5kI0NvbXBhdGliaWxpdHkKLSAgICAgKiBQdWJsaWMgZG9tYWluCi0gICAgICovCi0gICAgaWYgKCFGdW5jdGlvbi5wcm90b3R5cGUuYmluZCkKLSAgICAgICAgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbiAob1RoaXMpIHsKLSAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcyAhPT0gJ2Z1bmN0aW9uJykKLSAgICAgICAgICAgIC8vIENsb3Nlc3QgdGhpbmcgcG9zc2libGUgdG8gdGhlIEVDTUFTY3JpcHQgNSBpbnRlcm5hbCBJc0NhbGxhYmxlCi0gICAgICAgICAgICAvLyBmdW5jdGlvbjoKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKAotICAgICAgICAgICAgICAgICAgICAnRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgLSB3aGF0IGlzIHRyeWluZyB0byBiZSBib3VuZCBpcyBub3QgY2FsbGFibGUnCi0gICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgdmFyIGFBcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSwKLSAgICAgICAgICAgICAgICBmVG9CaW5kID0gdGhpcywKLSAgICAgICAgICAgICAgICBmTk9QLAotICAgICAgICAgICAgICAgIGZCb3VuZDsKLQotICAgICAgICAgICAgZk5PUCA9IGZ1bmN0aW9uICgpIHsKLSAgICAgICAgICAgIH07Ci0gICAgICAgICAgICBmQm91bmQgPSBmdW5jdGlvbiAoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZUb0JpbmQuYXBwbHkoCi0gICAgICAgICAgICAgICAgICAgIHRoaXMgaW5zdGFuY2VvZiBmTk9QICYmIG9UaGlzID8KLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgOgotICAgICAgICAgICAgICAgICAgICAgICAgb1RoaXMsCi0gICAgICAgICAgICAgICAgICAgIGFBcmdzLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKQotICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICB9OwotCi0gICAgICAgICAgICBmTk9QLnByb3RvdHlwZSA9IHRoaXMucHJvdG90eXBlOwotICAgICAgICAgICAgZkJvdW5kLnByb3RvdHlwZSA9IG5ldyBmTk9QKCk7Ci0KLSAgICAgICAgICAgIHJldHVybiBmQm91bmQ7Ci0gICAgICAgIH07Ci19KSh0aGlzKTsKLQotOyhmdW5jdGlvbiAodW5kZWZpbmVkKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgaWYgKHR5cGVvZiBzaWdtYSA9PT0gJ3VuZGVmaW5lZCcpCi0gICAgICAgIHRocm93ICdzaWdtYSBpcyBub3QgZGVjbGFyZWQnOwotCi0gICAgLy8gUGFja2FnZXMgaW5pdGlhbGl6YXRpb246Ci0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5zZXR0aW5ncycpOwotCi0gICAgdmFyIHNldHRpbmdzID0gewotICAgICAgICAvKioKLSAgICAgICAgICogR1JBUEggU0VUVElOR1M6Ci0gICAgICAgICAqICoqKioqKioqKioqKioqKgotICAgICAgICAgKi8KLSAgICAgICAgLy8ge2Jvb2xlYW59IEluZGljYXRlcyBpZiB0aGUgZGF0YSBoYXZlIHRvIGJlIGNsb25lZCBpbiBtZXRob2RzIHRvIGFkZAotICAgICAgICAvLyAgICAgICAgICAgbm9kZXMgb3IgZWRnZXMuCi0gICAgICAgIGNsb25lOiB0cnVlLAotICAgICAgICAvLyB7Ym9vbGVhbn0gSW5kaWNhdGVzIGlmIG5vZGVzICJpZCIgdmFsdWVzIGFuZCBlZGdlcyAiaWQiLCAic291cmNlIiBhbmQKLSAgICAgICAgLy8gICAgICAgICAgICJ0YXJnZXQiIHZhbHVlcyBtdXN0IGJlIHNldCBhcyBpbW11dGFibGUuCi0gICAgICAgIGltbXV0YWJsZTogdHJ1ZSwKLSAgICAgICAgLy8ge2Jvb2xlYW59IEluZGljYXRlcyBpZiBzaWdtYSBjYW4gbG9nIGl0cyBlcnJvcnMgYW5kIHdhcm5pbmdzLgotICAgICAgICB2ZXJib3NlOiBmYWxzZSwKLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSRU5ERVJFUlMgU0VUVElOR1M6Ci0gICAgICAgICAqICoqKioqKioqKioqKioqKioqKioKLSAgICAgICAgICovCi0gICAgICAgIC8vIHtzdHJpbmd9Ci0gICAgICAgIGNsYXNzUHJlZml4OiAnc2lnbWEnLAotICAgICAgICAvLyB7c3RyaW5nfQotICAgICAgICBkZWZhdWx0Tm9kZVR5cGU6ICdkZWYnLAotICAgICAgICAvLyB7c3RyaW5nfQotICAgICAgICBkZWZhdWx0RWRnZVR5cGU6ICdkZWYnLAotICAgICAgICAvLyB7c3RyaW5nfQotICAgICAgICBkZWZhdWx0TGFiZWxDb2xvcjogJyMwMDAnLAotICAgICAgICAvLyB7c3RyaW5nfQotICAgICAgICBkZWZhdWx0RWRnZUNvbG9yOiAnIzAwMCcsCi0gICAgICAgIC8vIHtzdHJpbmd9Ci0gICAgICAgIGRlZmF1bHROb2RlQ29sb3I6ICcjMDAwJywKLSAgICAgICAgLy8ge3N0cmluZ30KLSAgICAgICAgZGVmYXVsdExhYmVsU2l6ZTogMTQsCi0gICAgICAgIC8vIHtzdHJpbmd9IEluZGljYXRlcyBob3cgdG8gY2hvb3NlIHRoZSBlZGdlcyBjb2xvci4gQXZhaWxhYmxlIHZhbHVlczoKLSAgICAgICAgLy8gICAgICAgICAgInNvdXJjZSIsICJ0YXJnZXQiLCAiZGVmYXVsdCIKLSAgICAgICAgZWRnZUNvbG9yOiAnc291cmNlJywKLSAgICAgICAgLy8ge251bWJlcn0gRGVmaW5lcyB0aGUgbWluaW1hbCBlZGdlJ3MgYXJyb3cgZGlzcGxheSBzaXplLgotICAgICAgICBtaW5BcnJvd1NpemU6IDAsCi0gICAgICAgIC8vIHtzdHJpbmd9Ci0gICAgICAgIGZvbnQ6ICdhcmlhbCcsCi0gICAgICAgIC8vIHtzdHJpbmd9IEV4YW1wbGU6ICdib2xkJwotICAgICAgICBmb250U3R5bGU6ICcnLAotICAgICAgICAvLyB7c3RyaW5nfSBJbmRpY2F0ZXMgaG93IHRvIGNob29zZSB0aGUgbGFiZWxzIGNvbG9yLiBBdmFpbGFibGUgdmFsdWVzOgotICAgICAgICAvLyAgICAgICAgICAibm9kZSIsICJkZWZhdWx0IgotICAgICAgICBsYWJlbENvbG9yOiAnZGVmYXVsdCcsCi0gICAgICAgIC8vIHtzdHJpbmd9IEluZGljYXRlcyBob3cgdG8gY2hvb3NlIHRoZSBsYWJlbHMgc2l6ZS4gQXZhaWxhYmxlIHZhbHVlczoKLSAgICAgICAgLy8gICAgICAgICAgImZpeGVkIiwgInByb3BvcnRpb25hbCIKLSAgICAgICAgbGFiZWxTaXplOiAnZml4ZWQnLAotICAgICAgICAvLyB7c3RyaW5nfSBUaGUgcmF0aW8gYmV0d2VlbiB0aGUgZm9udCBzaXplIG9mIHRoZSBsYWJlbCBhbmQgdGhlIG5vZGUgc2l6ZS4KLSAgICAgICAgbGFiZWxTaXplUmF0aW86IDEsCi0gICAgICAgIC8vIHtudW1iZXJ9IFRoZSBtaW5pbXVtIHNpemUgYSBub2RlIG11c3QgaGF2ZSB0byBzZWUgaXRzIGxhYmVsIGRpc3BsYXllZC4KLSAgICAgICAgbGFiZWxUaHJlc2hvbGQ6IDgsCi0gICAgICAgIC8vIHtudW1iZXJ9IFRoZSBvdmVyc2FtcGxpbmcgZmFjdG9yIHVzZWQgaW4gV2ViR0wgcmVuZGVyZXIuCi0gICAgICAgIHdlYmdsT3ZlcnNhbXBsaW5nUmF0aW86IDIsCi0gICAgICAgIC8vIHtudW1iZXJ9IFRoZSBzaXplIG9mIHRoZSBib3JkZXIgb2YgaG92ZXJlZCBub2Rlcy4KLSAgICAgICAgYm9yZGVyU2l6ZTogMCwKLSAgICAgICAgLy8ge251bWJlcn0gVGhlIGRlZmF1bHQgaG92ZXJlZCBub2RlIGJvcmRlcidzIGNvbG9yLgotICAgICAgICBkZWZhdWx0Tm9kZUJvcmRlckNvbG9yOiAnIzAwMCcsCi0gICAgICAgIC8vIHtudW1iZXJ9IFRoZSBob3ZlcmVkIG5vZGUncyBsYWJlbCBmb250LiBJZiBub3Qgc3BlY2lmaWVkLCB3aWxsIGhlcml0YXRlCi0gICAgICAgIC8vICAgICAgICAgIHRoZSAiZm9udCIgdmFsdWUuCi0gICAgICAgIGhvdmVyRm9udDogJycsCi0gICAgICAgIC8vIHtib29sZWFufSBJZiB0cnVlLCB0aGVuIG9ubHkgb25lIG5vZGUgY2FuIGJlIGhvdmVyZWQgYXQgYSB0aW1lLgotICAgICAgICBzaW5nbGVIb3ZlcjogdHJ1ZSwKLSAgICAgICAgLy8ge3N0cmluZ30gRXhhbXBsZTogJ2JvbGQnCi0gICAgICAgIGhvdmVyRm9udFN0eWxlOiAnJywKLSAgICAgICAgLy8ge3N0cmluZ30gSW5kaWNhdGVzIGhvdyB0byBjaG9vc2UgdGhlIGhvdmVyZWQgbm9kZXMgc2hhZG93IGNvbG9yLgotICAgICAgICAvLyAgICAgICAgICBBdmFpbGFibGUgdmFsdWVzOiAibm9kZSIsICJkZWZhdWx0IgotICAgICAgICBsYWJlbEhvdmVyU2hhZG93OiAnZGVmYXVsdCcsCi0gICAgICAgIC8vIHtzdHJpbmd9Ci0gICAgICAgIGxhYmVsSG92ZXJTaGFkb3dDb2xvcjogJyMwMDAnLAotICAgICAgICAvLyB7c3RyaW5nfSBJbmRpY2F0ZXMgaG93IHRvIGNob29zZSB0aGUgaG92ZXJlZCBub2RlcyBjb2xvci4KLSAgICAgICAgLy8gICAgICAgICAgQXZhaWxhYmxlIHZhbHVlczogIm5vZGUiLCAiZGVmYXVsdCIKLSAgICAgICAgbm9kZUhvdmVyQ29sb3I6ICdub2RlJywKLSAgICAgICAgLy8ge3N0cmluZ30KLSAgICAgICAgZGVmYXVsdE5vZGVIb3ZlckNvbG9yOiAnIzAwMCcsCi0gICAgICAgIC8vIHtzdHJpbmd9IEluZGljYXRlcyBob3cgdG8gY2hvb3NlIHRoZSBob3ZlcmVkIG5vZGVzIGJhY2tncm91bmQgY29sb3IuCi0gICAgICAgIC8vICAgICAgICAgIEF2YWlsYWJsZSB2YWx1ZXM6ICJub2RlIiwgImRlZmF1bHQiCi0gICAgICAgIGxhYmVsSG92ZXJCR0NvbG9yOiAnZGVmYXVsdCcsCi0gICAgICAgIC8vIHtzdHJpbmd9Ci0gICAgICAgIGRlZmF1bHRIb3ZlckxhYmVsQkdDb2xvcjogJyNmZmYnLAotICAgICAgICAvLyB7c3RyaW5nfSBJbmRpY2F0ZXMgaG93IHRvIGNob29zZSB0aGUgaG92ZXJlZCBsYWJlbHMgY29sb3IuCi0gICAgICAgIC8vICAgICAgICAgIEF2YWlsYWJsZSB2YWx1ZXM6ICJub2RlIiwgImRlZmF1bHQiCi0gICAgICAgIGxhYmVsSG92ZXJDb2xvcjogJ2RlZmF1bHQnLAotICAgICAgICAvLyB7c3RyaW5nfQotICAgICAgICBkZWZhdWx0TGFiZWxIb3ZlckNvbG9yOiAnIzAwMCcsCi0gICAgICAgIC8vIHtzdHJpbmd9IEluZGljYXRlcyBob3cgdG8gY2hvb3NlIHRoZSBlZGdlcyBob3ZlciBjb2xvci4gQXZhaWxhYmxlIHZhbHVlczoKLSAgICAgICAgLy8gICAgICAgICAgImVkZ2UiLCAiZGVmYXVsdCIKLSAgICAgICAgZWRnZUhvdmVyQ29sb3I6ICdlZGdlJywKLSAgICAgICAgLy8ge251bWJlcn0gVGhlIHNpemUgbXVsdGlwbGljYXRvciBvZiBob3ZlcmVkIGVkZ2VzLgotICAgICAgICBlZGdlSG92ZXJTaXplUmF0aW86IDEsCi0gICAgICAgIC8vIHtzdHJpbmd9Ci0gICAgICAgIGRlZmF1bHRFZGdlSG92ZXJDb2xvcjogJyMwMDAnLAotICAgICAgICAvLyB7Ym9vbGVhbn0gSW5kaWNhdGVzIGlmIHRoZSBlZGdlIGV4dHJlbWl0aWVzIG11c3QgYmUgaG92ZXJlZCB3aGVuIHRoZQotICAgICAgICAvLyAgICAgICAgICAgZWRnZSBpcyBob3ZlcmVkLgotICAgICAgICBlZGdlSG92ZXJFeHRyZW1pdGllczogZmFsc2UsCi0gICAgICAgIC8vIHtib29sZWFuc30gVGhlIGRpZmZlcmVudCBkcmF3aW5nIG1vZGVzOgotICAgICAgICAvLyAgICAgICAgICAgZmFsc2U6IExheWVyZWQgbm90IGRpc3BsYXllZC4KLSAgICAgICAgLy8gICAgICAgICAgIHRydWU6IExheWVyZWQgZGlzcGxheWVkLgotICAgICAgICBkcmF3RWRnZXM6IHRydWUsCi0gICAgICAgIGRyYXdOb2RlczogdHJ1ZSwKLSAgICAgICAgZHJhd0xhYmVsczogdHJ1ZSwKLSAgICAgICAgZHJhd0VkZ2VMYWJlbHM6IGZhbHNlLAotICAgICAgICAvLyB7Ym9vbGVhbn0gSW5kaWNhdGVzIGlmIHRoZSBlZGdlcyBtdXN0IGJlIGRyYXduIGluIHNldmVyYWwgZnJhbWVzIG9yIGluCi0gICAgICAgIC8vICAgICAgICAgICBvbmUgZnJhbWUsIGFzIHRoZSBub2RlcyBhbmQgbGFiZWxzIGFyZSBkcmF3bi4KLSAgICAgICAgYmF0Y2hFZGdlc0RyYXdpbmc6IGZhbHNlLAotICAgICAgICAvLyB7Ym9vbGVhbn0gSW5kaWNhdGVzIGlmIHRoZSBlZGdlcyBtdXN0IGJlIGhpZGRlbiBkdXJpbmcgZHJhZ2dpbmcgYW5kCi0gICAgICAgIC8vICAgICAgICAgICBhbmltYXRpb25zLgotICAgICAgICBoaWRlRWRnZXNPbk1vdmU6IGZhbHNlLAotICAgICAgICAvLyB7bnVtYmVyc30gVGhlIGRpZmZlcmVudCBiYXRjaCBzaXplcywgd2hlbiBlbGVtZW50cyBhcmUgZGlzcGxheWVkIGluCi0gICAgICAgIC8vICAgICAgICAgICBzZXZlcmFsIGZyYW1lcy4KLSAgICAgICAgY2FudmFzRWRnZXNCYXRjaFNpemU6IDUwMCwKLSAgICAgICAgd2ViZ2xFZGdlc0JhdGNoU2l6ZTogMTAwMCwKLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSRVNDQUxFIFNFVFRJTkdTOgotICAgICAgICAgKiAqKioqKioqKioqKioqKioqKgotICAgICAgICAgKi8KLSAgICAgICAgLy8ge3N0cmluZ30gSW5kaWNhdGVzIG9mIHRvIHNjYWxlIHRoZSBncmFwaCByZWxhdGl2ZWx5IHRvIGl0cyBjb250YWluZXIuCi0gICAgICAgIC8vICAgICAgICAgIEF2YWlsYWJsZSB2YWx1ZXM6ICJpbnNpZGUiLCAib3V0c2lkZSIKLSAgICAgICAgc2NhbGluZ01vZGU6ICdpbnNpZGUnLAotICAgICAgICAvLyB7bnVtYmVyfSBUaGUgbWFyZ2luIHRvIGtlZXAgYXJvdW5kIHRoZSBncmFwaC4KLSAgICAgICAgc2lkZU1hcmdpbjogMCwKLSAgICAgICAgLy8ge251bWJlcn0gRGV0ZXJtaW5lIHRoZSBzaXplIG9mIHRoZSBzbWFsbGVzdCBhbmQgdGhlIGJpZ2dlc3Qgbm9kZSAvIGVkZ2VzCi0gICAgICAgIC8vICAgICAgICAgIG9uIHRoZSBzY3JlZW4uIFRoaXMgbWFwcGluZyBtYWtlcyBlYXNpZXIgdG8gZGlzcGxheSB0aGUgZ3JhcGgsCi0gICAgICAgIC8vICAgICAgICAgIGF2b2lkaW5nIHRvbyBiaWcgbm9kZXMgdGhhdCB0YWtlIGhhbGYgb2YgdGhlIHNjcmVlbiwgb3IgdG9vCi0gICAgICAgIC8vICAgICAgICAgIHNtYWxsIG9uZXMgdGhhdCBhcmUgbm90IHJlYWRhYmxlLiBJZiB0aGUgdHdvIHBhcmFtZXRlcnMgYXJlCi0gICAgICAgIC8vICAgICAgICAgIGVxdWFscywgdGhlbiB0aGUgbWluaW1hbCBkaXNwbGF5IHNpemUgd2lsbCBiZSAwLiBBbmQgaWYgdGhleQotICAgICAgICAvLyAgICAgICAgICBhcmUgYm90aCBlcXVhbCB0byAwLCB0aGVuIHRoZXJlIGlzIG5vIG1hcHBpbmcsIGFuZCB0aGUgcmFkaXVzCi0gICAgICAgIC8vICAgICAgICAgIG9mIHRoZSBub2RlcyB3aWxsIGJlIHRoZWlyIHNpemUuCi0gICAgICAgIG1pbkVkZ2VTaXplOiAwLjUsCi0gICAgICAgIG1heEVkZ2VTaXplOiAxLAotICAgICAgICBtaW5Ob2RlU2l6ZTogMSwKLSAgICAgICAgbWF4Tm9kZVNpemU6IDgsCi0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQ0FQVE9SUyBTRVRUSU5HUzoKLSAgICAgICAgICogKioqKioqKioqKioqKioqKioKLSAgICAgICAgICovCi0gICAgICAgIC8vIHtib29sZWFufQotICAgICAgICB0b3VjaEVuYWJsZWQ6IHRydWUsCi0gICAgICAgIC8vIHtib29sZWFufQotICAgICAgICBtb3VzZUVuYWJsZWQ6IHRydWUsCi0gICAgICAgIC8vIHtib29sZWFufQotICAgICAgICBtb3VzZVdoZWVsRW5hYmxlZDogdHJ1ZSwKLSAgICAgICAgLy8ge2Jvb2xlYW59Ci0gICAgICAgIGRvdWJsZUNsaWNrRW5hYmxlZDogdHJ1ZSwKLSAgICAgICAgLy8ge2Jvb2xlYW59IERlZmluZXMgd2hldGhlciB0aGUgY3VzdG9tIGV2ZW50cyBzdWNoIGFzICJjbGlja05vZGUiIGNhbiBiZQotICAgICAgICAvLyAgICAgICAgICAgdXNlZC4KLSAgICAgICAgZXZlbnRzRW5hYmxlZDogdHJ1ZSwKLSAgICAgICAgLy8ge251bWJlcn0gRGVmaW5lcyBieSBob3cgbXVjaCBtdWx0aXBsaWNhdGluZyB0aGUgem9vbWluZyBsZXZlbCB3aGVuIHRoZQotICAgICAgICAvLyAgICAgICAgICB1c2VyIHpvb21zIHdpdGggdGhlIG1vdXNlLXdoZWVsLgotICAgICAgICB6b29taW5nUmF0aW86IDEuNywKLSAgICAgICAgLy8ge251bWJlcn0gRGVmaW5lcyBieSBob3cgbXVjaCBtdWx0aXBsaWNhdGluZyB0aGUgem9vbWluZyBsZXZlbCB3aGVuIHRoZQotICAgICAgICAvLyAgICAgICAgICB1c2VyIHpvb21zIGJ5IGRvdWJsZSBjbGlja2luZy4KLSAgICAgICAgZG91YmxlQ2xpY2tab29taW5nUmF0aW86IDIuMiwKLSAgICAgICAgLy8ge251bWJlcn0gVGhlIG1pbmltdW0gem9vbWluZyBsZXZlbC4KLSAgICAgICAgem9vbU1pbjogMC4wNjI1LAotICAgICAgICAvLyB7bnVtYmVyfSBUaGUgbWF4aW11bSB6b29taW5nIGxldmVsLgotICAgICAgICB6b29tTWF4OiAyLAotICAgICAgICAvLyB7bnVtYmVyfSBUaGUgZHVyYXRpb24gb2YgYW5pbWF0aW9ucyBmb2xsb3dpbmcgYSBtb3VzZSBzY3JvbGxpbmcuCi0gICAgICAgIG1vdXNlWm9vbUR1cmF0aW9uOiAyMDAsCi0gICAgICAgIC8vIHtudW1iZXJ9IFRoZSBkdXJhdGlvbiBvZiBhbmltYXRpb25zIGZvbGxvd2luZyBhIG1vdXNlIGRvdWJsZSBjbGljay4KLSAgICAgICAgZG91YmxlQ2xpY2tab29tRHVyYXRpb246IDIwMCwKLSAgICAgICAgLy8ge251bWJlcn0gVGhlIGR1cmF0aW9uIG9mIGFuaW1hdGlvbnMgZm9sbG93aW5nIGEgbW91c2UgZHJvcHBpbmcuCi0gICAgICAgIG1vdXNlSW5lcnRpYUR1cmF0aW9uOiAyMDAsCi0gICAgICAgIC8vIHtudW1iZXJ9IFRoZSBpbmVydGlhIHBvd2VyIChtb3VzZSBjYXB0b3IpLgotICAgICAgICBtb3VzZUluZXJ0aWFSYXRpbzogMywKLSAgICAgICAgLy8ge251bWJlcn0gVGhlIGR1cmF0aW9uIG9mIGFuaW1hdGlvbnMgZm9sbG93aW5nIGEgdG91Y2ggZHJvcHBpbmcuCi0gICAgICAgIHRvdWNoSW5lcnRpYUR1cmF0aW9uOiAyMDAsCi0gICAgICAgIC8vIHtudW1iZXJ9IFRoZSBpbmVydGlhIHBvd2VyICh0b3VjaCBjYXB0b3IpLgotICAgICAgICB0b3VjaEluZXJ0aWFSYXRpbzogMywKLSAgICAgICAgLy8ge251bWJlcn0gVGhlIG1heGltdW0gdGltZSBiZXR3ZWVuIHR3byBjbGlja3MgdG8gbWFrZSBpdCBhIGRvdWJsZSBjbGljay4KLSAgICAgICAgZG91YmxlQ2xpY2tUaW1lb3V0OiAzMDAsCi0gICAgICAgIC8vIHtudW1iZXJ9IFRoZSBtYXhpbXVtIHRpbWUgYmV0d2VlbiB0d28gdGFwcyB0byBtYWtlIGl0IGEgZG91YmxlIHRhcC4KLSAgICAgICAgZG91YmxlVGFwVGltZW91dDogMzAwLAotICAgICAgICAvLyB7bnVtYmVyfSBUaGUgbWF4aW11bSB0aW1lIG9mIGRyYWdnaW5nIHRvIHRyaWdnZXIgaW50ZXJ0aWEuCi0gICAgICAgIGRyYWdUaW1lb3V0OiAyMDAsCi0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR0xPQkFMIFNFVFRJTkdTOgotICAgICAgICAgKiAqKioqKioqKioqKioqKioqCi0gICAgICAgICAqLwotICAgICAgICAvLyB7Ym9vbGVhbn0gRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBpbnN0YW5jZSBoYXMgdG8gcmVmcmVzaCBpdHNlbGYKLSAgICAgICAgLy8gICAgICAgICAgIGF1dG9tYXRpY2FsbHkgd2hlbiBhICJyZXNpemUiIGV2ZW50IGlzIGRpc3BhdGNoZWQgZnJvbSB0aGUKLSAgICAgICAgLy8gICAgICAgICAgIHdpbmRvdyBvYmplY3QuCi0gICAgICAgIGF1dG9SZXNpemU6IHRydWUsCi0gICAgICAgIC8vIHtib29sZWFufSBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlICJyZXNjYWxlIiBtaWRkbGV3YXJlIGhhcyB0byBiZSBjYWxsZWQKLSAgICAgICAgLy8gICAgICAgICAgIGF1dG9tYXRpY2FsbHkgZm9yIGVhY2ggY2FtZXJhIG9uIHJlZnJlc2guCi0gICAgICAgIGF1dG9SZXNjYWxlOiB0cnVlLAotICAgICAgICAvLyB7Ym9vbGVhbn0gSWYgc2V0IHRvIGZhbHNlLCB0aGUgY2FtZXJhIG1ldGhvZCAiZ29UbyIgd2lsbCBiYXNpY2FsbHkgZG8KLSAgICAgICAgLy8gICAgICAgICAgIG5vdGhpbmcuCi0gICAgICAgIGVuYWJsZUNhbWVyYTogdHJ1ZSwKLSAgICAgICAgLy8ge2Jvb2xlYW59IElmIHNldCB0byBmYWxzZSwgdGhlIG5vZGVzIGNhbm5vdCBiZSBob3ZlcmVkLgotICAgICAgICBlbmFibGVIb3ZlcmluZzogdHJ1ZSwKLSAgICAgICAgLy8ge2Jvb2xlYW59IElmIHNldCB0byB0cnVlLCB0aGUgZWRnZXMgY2FuIGJlIGhvdmVyZWQuCi0gICAgICAgIGVuYWJsZUVkZ2VIb3ZlcmluZzogZmFsc2UsCi0gICAgICAgIC8vIHtudW1iZXJ9IFRoZSBzaXplIG9mIHRoZSBhcmVhIGFyb3VuZCB0aGUgZWRnZXMgdG8gYWN0aXZhdGUgaG92ZXJpbmcuCi0gICAgICAgIGVkZ2VIb3ZlclByZWNpc2lvbjogNSwKLSAgICAgICAgLy8ge2Jvb2xlYW59IElmIHNldCB0byB0cnVlLCB0aGUgcmVzY2FsZSBtaWRkbGV3YXJlIHdpbGwgaWdub3JlIG5vZGUgc2l6ZXMKLSAgICAgICAgLy8gICAgICAgICAgIHRvIGRldGVybWluZSB0aGUgZ3JhcGhzIGJvdW5kaW5ncy4KLSAgICAgICAgcmVzY2FsZUlnbm9yZVNpemU6IGZhbHNlLAotICAgICAgICAvLyB7Ym9vbGVhbn0gRGV0ZXJtaW5lcyBpZiB0aGUgY29yZSBoYXMgdG8gdHJ5IHRvIGNhdGNoIGVycm9ycyBvbgotICAgICAgICAvLyAgICAgICAgICAgcmVuZGVyaW5nLgotICAgICAgICBza2lwRXJyb3JzOiBmYWxzZSwKLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBDQU1FUkEgU0VUVElOR1M6Ci0gICAgICAgICAqICoqKioqKioqKioqKioqKioKLSAgICAgICAgICovCi0gICAgICAgIC8vIHtudW1iZXJ9IFRoZSBwb3dlciBkZWdyZWVzIGFwcGxpZWQgdG8gdGhlIG5vZGVzL2VkZ2VzIHNpemUgcmVsYXRpdmVseSB0bwotICAgICAgICAvLyAgICAgICAgICB0aGUgem9vbWluZyBsZXZlbC4gQmFzaWNhbGx5OgotICAgICAgICAvLyAgICAgICAgICAgPiBvblNjcmVlblIgPSBNYXRoLnBvdyh6b29tLCBub2Rlc1Bvd1JhdGlvKSAqIFIKLSAgICAgICAgLy8gICAgICAgICAgID4gb25TY3JlZW5UID0gTWF0aC5wb3coem9vbSwgZWRnZXNQb3dSYXRpbykgKiBUCi0gICAgICAgIG5vZGVzUG93UmF0aW86IDAuNSwKLSAgICAgICAgZWRnZXNQb3dSYXRpbzogMC41LAotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEFOSU1BVElPTlMgU0VUVElOR1M6Ci0gICAgICAgICAqICoqKioqKioqKioqKioqKioqKioqCi0gICAgICAgICAqLwotICAgICAgICAvLyB7bnVtYmVyfSBUaGUgZGVmYXVsdCBhbmltYXRpb24gdGltZS4KLSAgICAgICAgYW5pbWF0aW9uc1RpbWU6IDIwMAotICAgIH07Ci0KLSAgICAvLyBFeHBvcnQgdGhlIHByZXZpb3VzbHkgZGVzaWduZWQgc2V0dGluZ3M6Ci0gICAgc2lnbWEuc2V0dGluZ3MgPSBzaWdtYS51dGlscy5leHRlbmQoc2lnbWEuc2V0dGluZ3MgfHwge30sIHNldHRpbmdzKTsKLX0pLmNhbGwodGhpcyk7Ci0KLTsoZnVuY3Rpb24gKCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIC8qKgotICAgICAqIERpc3BhdGNoZXIgY29uc3RydWN0b3IuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHtkaXNwYXRjaGVyfSBUaGUgbmV3IGRpc3BhdGNoZXIgaW5zdGFuY2UuCi0gICAgICovCi0gICAgdmFyIGRpc3BhdGNoZXIgPSBmdW5jdGlvbiAoKSB7Ci0gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnX2hhbmRsZXJzJywgewotICAgICAgICAgICAgdmFsdWU6IHt9Ci0gICAgICAgIH0pOwotICAgIH07Ci0KLQotICAgIC8qKgotICAgICAqIFdpbGwgZXhlY3V0ZSB0aGUgaGFuZGxlciBldmVyeXRpbWUgdGhhdCB0aGUgaW5kaWNhdGVkIGV2ZW50IChvciB0aGUKLSAgICAgKiBpbmRpY2F0ZWQgZXZlbnRzKSB3aWxsIGJlIHRyaWdnZXJlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge3N0cmluZ30gICAgICAgICAgIGV2ZW50cyAgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IChvciB0aGUgZXZlbnRzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXBhcmF0ZWQgYnkgc3BhY2VzKS4KLSAgICAgKiBAcGFyYW0gIHtmdW5jdGlvbihPYmplY3QpfSBoYW5kbGVyIFRoZSBoYW5kbGVyIHRvIGJpbmQuCi0gICAgICogQHJldHVybiB7ZGlzcGF0Y2hlcn0gICAgICAgICAgICAgICBSZXR1cm5zIHRoZSBpbnN0YW5jZSBpdHNlbGYuCi0gICAgICovCi0gICAgZGlzcGF0Y2hlci5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uIChldmVudHMsIGhhbmRsZXIpIHsKLSAgICAgICAgdmFyIGksCi0gICAgICAgICAgICBsLAotICAgICAgICAgICAgZXZlbnQsCi0gICAgICAgICAgICBlQXJyYXk7Ci0KLSAgICAgICAgaWYgKAotICAgICAgICAgICAgYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJgotICAgICAgICAgICAgdHlwZW9mIGFyZ3VtZW50c1swXSA9PT0gJ29iamVjdCcKLSAgICAgICAgKQotICAgICAgICAgICAgZm9yIChldmVudHMgaW4gYXJndW1lbnRzWzBdKQotICAgICAgICAgICAgICAgIHRoaXMuYmluZChldmVudHMsIGFyZ3VtZW50c1swXVtldmVudHNdKTsKLSAgICAgICAgZWxzZSBpZiAoCi0gICAgICAgICAgICBhcmd1bWVudHMubGVuZ3RoID09PSAyICYmCi0gICAgICAgICAgICB0eXBlb2YgYXJndW1lbnRzWzFdID09PSAnZnVuY3Rpb24nCi0gICAgICAgICkgewotICAgICAgICAgICAgZUFycmF5ID0gdHlwZW9mIGV2ZW50cyA9PT0gJ3N0cmluZycgPyBldmVudHMuc3BsaXQoJyAnKSA6IGV2ZW50czsKLQotICAgICAgICAgICAgZm9yIChpID0gMCwgbCA9IGVBcnJheS5sZW5ndGg7IGkgIT09IGw7IGkgKz0gMSkgewotICAgICAgICAgICAgICAgIGV2ZW50ID0gZUFycmF5W2ldOwotCi0gICAgICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCBldmVudCBpcyBub3QgJyc6Ci0gICAgICAgICAgICAgICAgaWYgKCFldmVudCkKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0KLSAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2hhbmRsZXJzW2V2ZW50XSkKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlcnNbZXZlbnRdID0gW107Ci0KLSAgICAgICAgICAgICAgICAvLyBVc2luZyBhbiBvYmplY3QgaW5zdGVhZCBvZiBkaXJlY3RseSB0aGUgaGFuZGxlciB3aWxsIG1ha2UgcG9zc2libGUKLSAgICAgICAgICAgICAgICAvLyBsYXRlciB0byBhZGQgZmxhZ3MKLSAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVyc1tldmVudF0ucHVzaCh7Ci0gICAgICAgICAgICAgICAgICAgIGhhbmRsZXI6IGhhbmRsZXIKLSAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICB0aHJvdyAnYmluZDogV3JvbmcgYXJndW1lbnRzLic7Ci0KLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFJlbW92ZXMgdGhlIGhhbmRsZXIgZnJvbSBhIHNwZWNpZmllZCBldmVudCAob3Igc3BlY2lmaWVkIGV2ZW50cykuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHs/c3RyaW5nfSAgICAgICAgICAgZXZlbnRzICBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgKG9yIHRoZSBldmVudHMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXBhcmF0ZWQgYnkgc3BhY2VzKS4gSWYgdW5kZWZpbmVkLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gYWxsIGhhbmRsZXJzIGFyZSByZW1vdmVkLgotICAgICAqIEBwYXJhbSAgez9mdW5jdGlvbihvYmplY3QpfSBoYW5kbGVyIFRoZSBoYW5kbGVyIHRvIHVuYmluZC4gSWYgdW5kZWZpbmVkLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2ggaGFuZGxlciBib3VuZCB0byB0aGUgZXZlbnQgb3IgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzIHdpbGwgYmUgcmVtb3ZlZC4KLSAgICAgKiBAcmV0dXJuIHtkaXNwYXRjaGVyfSAgICAgICAgICAgICAgICBSZXR1cm5zIHRoZSBpbnN0YW5jZSBpdHNlbGYuCi0gICAgICovCi0gICAgZGlzcGF0Y2hlci5wcm90b3R5cGUudW5iaW5kID0gZnVuY3Rpb24gKGV2ZW50cywgaGFuZGxlcikgewotICAgICAgICB2YXIgaSwKLSAgICAgICAgICAgIG4sCi0gICAgICAgICAgICBqLAotICAgICAgICAgICAgbSwKLSAgICAgICAgICAgIGssCi0gICAgICAgICAgICBhLAotICAgICAgICAgICAgZXZlbnQsCi0gICAgICAgICAgICBlQXJyYXkgPSB0eXBlb2YgZXZlbnRzID09PSAnc3RyaW5nJyA/IGV2ZW50cy5zcGxpdCgnICcpIDogZXZlbnRzOwotCi0gICAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgewotICAgICAgICAgICAgZm9yIChrIGluIHRoaXMuX2hhbmRsZXJzKQotICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9oYW5kbGVyc1trXTsKLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGhhbmRsZXIpIHsKLSAgICAgICAgICAgIGZvciAoaSA9IDAsIG4gPSBlQXJyYXkubGVuZ3RoOyBpICE9PSBuOyBpICs9IDEpIHsKLSAgICAgICAgICAgICAgICBldmVudCA9IGVBcnJheVtpXTsKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5faGFuZGxlcnNbZXZlbnRdKSB7Ci0gICAgICAgICAgICAgICAgICAgIGEgPSBbXTsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChqID0gMCwgbSA9IHRoaXMuX2hhbmRsZXJzW2V2ZW50XS5sZW5ndGg7IGogIT09IG07IGogKz0gMSkKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9oYW5kbGVyc1tldmVudF1bal0uaGFuZGxlciAhPT0gaGFuZGxlcikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhLnB1c2godGhpcy5faGFuZGxlcnNbZXZlbnRdW2pdKTsKLQotICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVyc1tldmVudF0gPSBhOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmICh0aGlzLl9oYW5kbGVyc1tldmVudF0gJiYgdGhpcy5faGFuZGxlcnNbZXZlbnRdLmxlbmd0aCA9PT0gMCkKLSAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2hhbmRsZXJzW2V2ZW50XTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICBmb3IgKGkgPSAwLCBuID0gZUFycmF5Lmxlbmd0aDsgaSAhPT0gbjsgaSArPSAxKQotICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9oYW5kbGVyc1tlQXJyYXlbaV1dOwotCi0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBFeGVjdXRlcyBlYWNoIGhhbmRsZXIgYm91bmQgdG8gdGhlIGV2ZW50Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtzdHJpbmd9ICAgICBldmVudHMgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IChvciB0aGUgZXZlbnRzIHNlcGFyYXRlZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieSBzcGFjZXMpLgotICAgICAqIEBwYXJhbSAgez9vYmplY3R9ICAgIGRhdGEgICBUaGUgY29udGVudCBvZiB0aGUgZXZlbnQgKG9wdGlvbmFsKS4KLSAgICAgKiBAcmV0dXJuIHtkaXNwYXRjaGVyfSAgICAgICAgUmV0dXJucyB0aGUgaW5zdGFuY2UgaXRzZWxmLgotICAgICAqLwotICAgIGRpc3BhdGNoZXIucHJvdG90eXBlLmRpc3BhdGNoRXZlbnQgPSBmdW5jdGlvbiAoZXZlbnRzLCBkYXRhKSB7Ci0gICAgICAgIHZhciBpLAotICAgICAgICAgICAgbiwKLSAgICAgICAgICAgIGosCi0gICAgICAgICAgICBtLAotICAgICAgICAgICAgYSwKLSAgICAgICAgICAgIGV2ZW50LAotICAgICAgICAgICAgZXZlbnROYW1lLAotICAgICAgICAgICAgc2VsZiA9IHRoaXMsCi0gICAgICAgICAgICBlQXJyYXkgPSB0eXBlb2YgZXZlbnRzID09PSAnc3RyaW5nJyA/IGV2ZW50cy5zcGxpdCgnICcpIDogZXZlbnRzOwotCi0gICAgICAgIGRhdGEgPSBkYXRhID09PSB1bmRlZmluZWQgPyB7fSA6IGRhdGE7Ci0KLSAgICAgICAgZm9yIChpID0gMCwgbiA9IGVBcnJheS5sZW5ndGg7IGkgIT09IG47IGkgKz0gMSkgewotICAgICAgICAgICAgZXZlbnROYW1lID0gZUFycmF5W2ldOwotCi0gICAgICAgICAgICBpZiAodGhpcy5faGFuZGxlcnNbZXZlbnROYW1lXSkgewotICAgICAgICAgICAgICAgIGV2ZW50ID0gc2VsZi5nZXRFdmVudChldmVudE5hbWUsIGRhdGEpOwotICAgICAgICAgICAgICAgIGEgPSBbXTsKLQotICAgICAgICAgICAgICAgIGZvciAoaiA9IDAsIG0gPSB0aGlzLl9oYW5kbGVyc1tldmVudE5hbWVdLmxlbmd0aDsgaiAhPT0gbTsgaiArPSAxKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZXJzW2V2ZW50TmFtZV1bal0uaGFuZGxlcihldmVudCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5faGFuZGxlcnNbZXZlbnROYW1lXVtqXS5vbmUpCi0gICAgICAgICAgICAgICAgICAgICAgICBhLnB1c2godGhpcy5faGFuZGxlcnNbZXZlbnROYW1lXVtqXSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlcnNbZXZlbnROYW1lXSA9IGE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFuIGV2ZW50IG9iamVjdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge3N0cmluZ30gIGV2ZW50cyBUaGUgbmFtZSBvZiB0aGUgZXZlbnQuCi0gICAgICogQHBhcmFtICB7P29iamVjdH0gZGF0YSAgIFRoZSBjb250ZW50IG9mIHRoZSBldmVudCAob3B0aW9uYWwpLgotICAgICAqIEByZXR1cm4ge29iamVjdH0gICAgICAgICBSZXR1cm5zIHRoZSBpbnN0YW5jZSBpdHNlbGYuCi0gICAgICovCi0gICAgZGlzcGF0Y2hlci5wcm90b3R5cGUuZ2V0RXZlbnQgPSBmdW5jdGlvbiAoZXZlbnQsIGRhdGEpIHsKLSAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgIHR5cGU6IGV2ZW50LAotICAgICAgICAgICAgZGF0YTogZGF0YSB8fCB7fSwKLSAgICAgICAgICAgIHRhcmdldDogdGhpcwotICAgICAgICB9OwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBBIHVzZWZ1bCBmdW5jdGlvbiB0byBkZWFsIHdpdGggaW5oZXJpdGFuY2UuIEl0IHdpbGwgbWFrZSB0aGUgdGFyZ2V0Ci0gICAgICogaW5oZXJpdCB0aGUgcHJvdG90eXBlIG9mIHRoZSBjbGFzcyBkaXNwYXRjaGVyIGFzIHdlbGwgYXMgaXRzIGNvbnN0cnVjdG9yLgotICAgICAqCi0gICAgICogQHBhcmFtIHtvYmplY3R9IHRhcmdldCBUaGUgdGFyZ2V0LgotICAgICAqLwotICAgIGRpc3BhdGNoZXIuZXh0ZW5kID0gZnVuY3Rpb24gKHRhcmdldCwgYXJncykgewotICAgICAgICB2YXIgazsKLQotICAgICAgICBmb3IgKGsgaW4gZGlzcGF0Y2hlci5wcm90b3R5cGUpCi0gICAgICAgICAgICBpZiAoZGlzcGF0Y2hlci5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkoaykpCi0gICAgICAgICAgICAgICAgdGFyZ2V0W2tdID0gZGlzcGF0Y2hlci5wcm90b3R5cGVba107Ci0KLSAgICAgICAgZGlzcGF0Y2hlci5hcHBseSh0YXJnZXQsIGFyZ3MpOwotICAgIH07Ci0KLQotICAgIC8qKgotICAgICAqIEVYUE9SVDoKLSAgICAgKiAqKioqKioqCi0gICAgICovCi0gICAgaWYgKHR5cGVvZiB0aGlzLnNpZ21hICE9PSAndW5kZWZpbmVkJykgewotICAgICAgICB0aGlzLnNpZ21hLmNsYXNzZXMgPSB0aGlzLnNpZ21hLmNsYXNzZXMgfHwge307Ci0gICAgICAgIHRoaXMuc2lnbWEuY2xhc3Nlcy5kaXNwYXRjaGVyID0gZGlzcGF0Y2hlcjsKLSAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykgewotICAgICAgICBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpCi0gICAgICAgICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBkaXNwYXRjaGVyOwotICAgICAgICBleHBvcnRzLmRpc3BhdGNoZXIgPSBkaXNwYXRjaGVyOwotICAgIH0gZWxzZQotICAgICAgICB0aGlzLmRpc3BhdGNoZXIgPSBkaXNwYXRjaGVyOwotfSkuY2FsbCh0aGlzKTsKLQotOyhmdW5jdGlvbiAoKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgLyoqCi0gICAgICogVGhpcyB1dGlscyBhaW1zIHRvIGZhY2lsaXRhdGUgdGhlIG1hbmlwdWxhdGlvbiBvZiBlYWNoIGluc3RhbmNlIHNldHRpbmcuCi0gICAgICogVXNpbmcgYSBmdW5jdGlvbiBpbnN0ZWFkIG9mIGFuIG9iamVjdCBicmluZ3MgdHdvIG1haW4gYWR2YW50YWdlczogRmlyc3QsCi0gICAgICogaXQgd2lsbCBiZSBlYXNpZXIgaW4gdGhlIGZ1dHVyZSB0byBjYXRjaCBzZXR0aW5ncyB1cGRhdGVzIHRocm91Z2ggYQotICAgICAqIGZ1bmN0aW9uIHRoYW4gYW4gb2JqZWN0LiBTZWNvbmQsIGdpdmluZyBpdCBhIGZ1bGwgb2JqZWN0IHdpbGwgIm1lcmdlIiBpdAotICAgICAqIHRvIHRoZSBzZXR0aW5ncyBvYmplY3QgcHJvcGVybHksIGtlZXBpbmcgdXMgdG8gaGF2ZSB0byBhbHdheXMgYWRkIGEgbG9vcC4KLSAgICAgKgotICAgICAqIEByZXR1cm4ge2NvbmZpZ3VyYWJsZX0gVGhlICJzZXR0aW5ncyIgZnVuY3Rpb24uCi0gICAgICovCi0gICAgdmFyIGNvbmZpZ3VyYWJsZSA9IGZ1bmN0aW9uICgpIHsKLSAgICAgICAgdmFyIGksCi0gICAgICAgICAgICBsLAotICAgICAgICAgICAgZGF0YSA9IHt9LAotICAgICAgICAgICAgZGF0YXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUaGUgbWV0aG9kIHRvIHVzZSB0byBzZXQgb3IgZ2V0IGFueSBwcm9wZXJ0eSBvZiB0aGlzIGluc3RhbmNlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtzdHJpbmd8b2JqZWN0fSAgICBhMSBJZiBpdCBpcyBhIHN0cmluZyBhbmQgaWYgYTIgaXMgdW5kZWZpbmVkLAotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGl0IHdpbGwgcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5LiBJZiBpdCBpcyBhIHN0cmluZyBhbmQgaWYgYTIgaXMKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0LCB0aGVuIGl0IHdpbGwgc2V0IGEyIGFzIHRoZSBwcm9wZXJ0eQotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZXNwb25kaW5nIHRvIGExLCBhbmQgcmV0dXJuIHRoaXMuIElmCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0IGlzIGFuIG9iamVjdCwgdGhlbiBlYWNoIHBhaXIgc3RyaW5nICsKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0KG9yIGFueSBvdGhlciB0eXBlKSB3aWxsIGJlIHNldCBhcyBhCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5LgotICAgICAgICAgKiBAcGFyYW0gIHsqP30gICAgICAgICAgICAgICBhMiBUaGUgbmV3IHByb3BlcnR5IGNvcnJlc3BvbmRpbmcgdG8gYTEgaWYgYTEKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgYSBzdHJpbmcuCi0gICAgICAgICAqIEByZXR1cm4geyp8Y29uZmlndXJhYmxlfSAgICAgIFJldHVybnMgaXRzZWxmIG9yIHRoZSBjb3JyZXNwb25kaW5nCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5LgotICAgICAgICAgKgotICAgICAgICAgKiBQb2x5bW9ycGhpc206Ci0gICAgICAgICAqICoqKioqKioqKioqKioKLSAgICAgICAgICogSGVyZSBhcmUgc29tZSBiYXNpYyB1c2UgZXhhbXBsZXM6Ci0gICAgICAgICAqCi0gICAgICAgICAqICA+IHNldHRpbmdzID0gbmV3IGNvbmZpZ3VyYWJsZSgpOwotICAgICAgICAgKiAgPiBzZXR0aW5ncygnbXlTZXR0aW5nJywgNDIpOwotICAgICAgICAgKiAgPiBzZXR0aW5ncygnbXlTZXR0aW5nJyk7IC8vIExvZ3M6IDQyCi0gICAgICAgICAqICA+IHNldHRpbmdzKCdteVNldHRpbmcnLCAxMjMpOwotICAgICAgICAgKiAgPiBzZXR0aW5ncygnbXlTZXR0aW5nJyk7IC8vIExvZ3M6IDEyMwotICAgICAgICAgKiAgPiBzZXR0aW5ncyh7bXlTZXR0aW5nOiA0NTZ9KTsKLSAgICAgICAgICogID4gc2V0dGluZ3MoJ215U2V0dGluZycpOyAvLyBMb2dzOiA0NTYKLSAgICAgICAgICoKLSAgICAgICAgICogQWxzbywgaXQgaXMgcG9zc2libGUgdG8gdXNlIHRoZSBmdW5jdGlvbiBhcyBhIGZhbGxiYWNrOgotICAgICAgICAgKiAgPiBzZXR0aW5ncyh7bXlTZXR0aW5nOiAnYWJjJ30sICdteVNldHRpbmcnKTsgIC8vIExvZ3M6ICdhYmMnCi0gICAgICAgICAqICA+IHNldHRpbmdzKHtoaXNTZXR0aW5nOiAnYWJjJ30sICdteVNldHRpbmcnKTsgLy8gTG9nczogNDU2Ci0gICAgICAgICAqLwotICAgICAgICB2YXIgc2V0dGluZ3MgPSBmdW5jdGlvbiAoYTEsIGEyKSB7Ci0gICAgICAgICAgICB2YXIgbywKLSAgICAgICAgICAgICAgICBpLAotICAgICAgICAgICAgICAgIGwsCi0gICAgICAgICAgICAgICAgazsKLQotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGExID09PSAnc3RyaW5nJykgewotICAgICAgICAgICAgICAgIGlmIChkYXRhW2ExXSAhPT0gdW5kZWZpbmVkKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVthMV07Ci0gICAgICAgICAgICAgICAgZm9yIChpID0gMCwgbCA9IGRhdGFzLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFzW2ldW2ExXSAhPT0gdW5kZWZpbmVkKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGFzW2ldW2ExXTsKLSAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkOwotICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYTEgPT09ICdvYmplY3QnICYmIHR5cGVvZiBhMiA9PT0gJ3N0cmluZycpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gKGExIHx8IHt9KVthMl0gIT09IHVuZGVmaW5lZCA/IGExW2EyXSA6IHNldHRpbmdzKGEyKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgbyA9ICh0eXBlb2YgYTEgPT09ICdvYmplY3QnICYmIGEyID09PSB1bmRlZmluZWQpID8gYTEgOiB7fTsKLQotICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYTEgPT09ICdzdHJpbmcnKQotICAgICAgICAgICAgICAgICAgICBvW2ExXSA9IGEyOwotCi0gICAgICAgICAgICAgICAgZm9yIChpID0gMCwgayA9IE9iamVjdC5rZXlzKG8pLCBsID0gay5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICAgICAgICAgIGRhdGFba1tpXV0gPSBvW2tbaV1dOwotCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH07Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgY29uZmlndXJhYmxlIGZ1bmN0aW9uLCB3aXRoIG5ldyBvYmplY3RzCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSAge29iamVjdCp9ICBBbnkgbnVtYmVyIG9mIG9iamVjdHMgdG8gc2VhcmNoIGluLgotICAgICAgICAgKiBAcmV0dXJuIHtmdW5jdGlvbn0gUmV0dXJucyB0aGUgZnVuY3Rpb24uIENoZWNrIGl0cyBkb2N1bWVudGF0aW9uIHRvIGtub3cKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgIG1vcmUgYWJvdXQgaG93IGl0IHdvcmtzLgotICAgICAgICAgKi8KLSAgICAgICAgc2V0dGluZ3MuZW1iZWRPYmplY3RzID0gZnVuY3Rpb24gKCkgewotICAgICAgICAgICAgdmFyIGFyZ3MgPSBkYXRhcy5jb25jYXQoCi0gICAgICAgICAgICAgICAgZGF0YQotICAgICAgICAgICAgKS5jb25jYXQoCi0gICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnNwbGljZS5jYWxsKGFyZ3VtZW50cywgMCkKLSAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIHJldHVybiBjb25maWd1cmFibGUuYXBwbHkoe30sIGFyZ3MpOwotICAgICAgICB9OwotCi0gICAgICAgIC8vIEluaXRpYWxpemUKLSAgICAgICAgZm9yIChpID0gMCwgbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICBzZXR0aW5ncyhhcmd1bWVudHNbaV0pOwotCi0gICAgICAgIHJldHVybiBzZXR0aW5nczsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogRVhQT1JUOgotICAgICAqICoqKioqKioKLSAgICAgKi8KLSAgICBpZiAodHlwZW9mIHRoaXMuc2lnbWEgIT09ICd1bmRlZmluZWQnKSB7Ci0gICAgICAgIHRoaXMuc2lnbWEuY2xhc3NlcyA9IHRoaXMuc2lnbWEuY2xhc3NlcyB8fCB7fTsKLSAgICAgICAgdGhpcy5zaWdtYS5jbGFzc2VzLmNvbmZpZ3VyYWJsZSA9IGNvbmZpZ3VyYWJsZTsKLSAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykgewotICAgICAgICBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpCi0gICAgICAgICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBjb25maWd1cmFibGU7Ci0gICAgICAgIGV4cG9ydHMuY29uZmlndXJhYmxlID0gY29uZmlndXJhYmxlOwotICAgIH0gZWxzZQotICAgICAgICB0aGlzLmNvbmZpZ3VyYWJsZSA9IGNvbmZpZ3VyYWJsZTsKLX0pLmNhbGwodGhpcyk7Ci0KLTsoZnVuY3Rpb24gKHVuZGVmaW5lZCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIHZhciBfbWV0aG9kcyA9IE9iamVjdC5jcmVhdGUobnVsbCksCi0gICAgICAgIF9pbmRleGVzID0gT2JqZWN0LmNyZWF0ZShudWxsKSwKLSAgICAgICAgX2luaXRCaW5kaW5ncyA9IE9iamVjdC5jcmVhdGUobnVsbCksCi0gICAgICAgIF9tZXRob2RCaW5kaW5ncyA9IE9iamVjdC5jcmVhdGUobnVsbCksCi0gICAgICAgIF9tZXRob2RCZWZvcmVCaW5kaW5ncyA9IE9iamVjdC5jcmVhdGUobnVsbCksCi0gICAgICAgIF9kZWZhdWx0U2V0dGluZ3MgPSB7Ci0gICAgICAgICAgICBpbW11dGFibGU6IHRydWUsCi0gICAgICAgICAgICBjbG9uZTogdHJ1ZQotICAgICAgICB9LAotICAgICAgICBfZGVmYXVsdFNldHRpbmdzRnVuY3Rpb24gPSBmdW5jdGlvbiAoa2V5KSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RlZmF1bHRTZXR0aW5nc1trZXldOwotICAgICAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhlIGdyYXBoIGNvbnN0cnVjdG9yLiBJdCBpbml0aWFsaXplcyB0aGUgZGF0YSBhbmQgdGhlIGluZGV4ZXMsIGFuZCBiaW5kcwotICAgICAqIHRoZSBjdXN0b20gaW5kZXhlcyBhbmQgbWV0aG9kcyB0byBpdHMgb3duIHNjb3BlLgotICAgICAqCi0gICAgICogUmVjb2duaXplZCBwYXJhbWV0ZXJzOgotICAgICAqICoqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBIZXJlIGlzIHRoZSBleGhhdXN0aXZlIGxpc3Qgb2YgZXZlcnkgYWNjZXB0ZWQgcGFyYW1ldGVycyBpbiB0aGUgc2V0dGluZ3MKLSAgICAgKiBvYmplY3Q6Ci0gICAgICoKLSAgICAgKiAgIHtib29sZWFufSBjbG9uZSAgICAgSW5kaWNhdGVzIGlmIHRoZSBkYXRhIGhhdmUgdG8gYmUgY2xvbmVkIGluIG1ldGhvZHMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgdG8gYWRkIG5vZGVzIG9yIGVkZ2VzLgotICAgICAqICAge2Jvb2xlYW59IGltbXV0YWJsZSBJbmRpY2F0ZXMgaWYgbm9kZXMgImlkIiB2YWx1ZXMgYW5kIGVkZ2VzICJpZCIsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICJzb3VyY2UiIGFuZCAidGFyZ2V0IiB2YWx1ZXMgbXVzdCBiZSBzZXQgYXMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgaW1tdXRhYmxlLgotICAgICAqCi0gICAgICogQHBhcmFtICB7P2NvbmZpZ3VyYWJsZX0gc2V0dGluZ3MgRXZlbnR1YWxseSBhIHNldHRpbmdzIGZ1bmN0aW9uLgotICAgICAqIEByZXR1cm4ge2dyYXBofSAgICAgICAgICAgICAgICAgIFRoZSBuZXcgZ3JhcGggaW5zdGFuY2UuCi0gICAgICovCi0gICAgdmFyIGdyYXBoID0gZnVuY3Rpb24gKHNldHRpbmdzKSB7Ci0gICAgICAgIHZhciBrLAotICAgICAgICAgICAgZm4sCi0gICAgICAgICAgICBkYXRhOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBEQVRBOgotICAgICAgICAgKiAqKioqKgotICAgICAgICAgKiBFdmVyeSBkYXRhIHRoYXQgaXMgY2FsbGFibGUgZnJvbSBncmFwaCBtZXRob2RzIGFyZSBzdG9yZWQgaW4gdGhpcyAiZGF0YSIKLSAgICAgICAgICogb2JqZWN0LiBUaGlzIG9iamVjdCB3aWxsIGJlIHNlcnZlZCBhcyBjb250ZXh0IGZvciBhbGwgdGhlc2UgbWV0aG9kcywKLSAgICAgICAgICogYW5kIGl0IGlzIHBvc3NpYmxlIHRvIGFkZCBvdGhlciB0eXBlIG9mIGRhdGEgaW4gaXQuCi0gICAgICAgICAqLwotICAgICAgICBkYXRhID0gewotICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgKiBTRVRUSU5HUyBGVU5DVElPTjoKLSAgICAgICAgICAgICAqICoqKioqKioqKioqKioqKioqKgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBzZXR0aW5nczogc2V0dGluZ3MgfHwgX2RlZmF1bHRTZXR0aW5nc0Z1bmN0aW9uLAotCi0gICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAqIE1BSU4gREFUQToKLSAgICAgICAgICAgICAqICoqKioqKioqKioKLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgbm9kZXNBcnJheTogW10sCi0gICAgICAgICAgICBlZGdlc0FycmF5OiBbXSwKLQotICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgKiBHTE9CQUwgSU5ERVhFUzoKLSAgICAgICAgICAgICAqICoqKioqKioqKioqKioqKgotICAgICAgICAgICAgICogVGhlc2UgaW5kZXhlcyBqdXN0IGluZGV4IGRhdGEgYnkgaWRzLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBub2Rlc0luZGV4OiBPYmplY3QuY3JlYXRlKG51bGwpLAotICAgICAgICAgICAgZWRnZXNJbmRleDogT2JqZWN0LmNyZWF0ZShudWxsKSwKLQotICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgKiBMT0NBTCBJTkRFWEVTOgotICAgICAgICAgICAgICogKioqKioqKioqKioqKioKLSAgICAgICAgICAgICAqIFRoZXNlIGluZGV4ZXMgcmVmZXIgZnJvbSBub2RlIHRvIG5vZGVzLiBFYWNoIGtleSBpcyBhbiBpZCwgYW5kIGVhY2gKLSAgICAgICAgICAgICAqIHZhbHVlIGlzIHRoZSBhcnJheSBvZiB0aGUgaWRzIG9mIHJlbGF0ZWQgbm9kZXMuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIGluTmVpZ2hib3JzSW5kZXg6IE9iamVjdC5jcmVhdGUobnVsbCksCi0gICAgICAgICAgICBvdXROZWlnaGJvcnNJbmRleDogT2JqZWN0LmNyZWF0ZShudWxsKSwKLSAgICAgICAgICAgIGFsbE5laWdoYm9yc0luZGV4OiBPYmplY3QuY3JlYXRlKG51bGwpLAotCi0gICAgICAgICAgICBpbk5laWdoYm9yc0NvdW50OiBPYmplY3QuY3JlYXRlKG51bGwpLAotICAgICAgICAgICAgb3V0TmVpZ2hib3JzQ291bnQ6IE9iamVjdC5jcmVhdGUobnVsbCksCi0gICAgICAgICAgICBhbGxOZWlnaGJvcnNDb3VudDogT2JqZWN0LmNyZWF0ZShudWxsKQotICAgICAgICB9OwotCi0gICAgICAgIC8vIEV4ZWN1dGUgYmluZGluZ3M6Ci0gICAgICAgIGZvciAoayBpbiBfaW5pdEJpbmRpbmdzKQotICAgICAgICAgICAgX2luaXRCaW5kaW5nc1trXS5jYWxsKGRhdGEpOwotCi0gICAgICAgIC8vIEFkZCBtZXRob2RzIHRvIGJvdGggdGhlIHNjb3BlIGFuZCB0aGUgZGF0YSBvYmplY3RzOgotICAgICAgICBmb3IgKGsgaW4gX21ldGhvZHMpIHsKLSAgICAgICAgICAgIGZuID0gX19iaW5kR3JhcGhNZXRob2QoaywgZGF0YSwgX21ldGhvZHNba10pOwotICAgICAgICAgICAgdGhpc1trXSA9IGZuOwotICAgICAgICAgICAgZGF0YVtrXSA9IGZuOwotICAgICAgICB9Ci0gICAgfTsKLQotCi0gICAgLyoqCi0gICAgICogQSBjdXN0b20gdG9vbCB0byBiaW5kIG1ldGhvZHMgc3VjaCB0aGF0IGZ1bmN0aW9uIHRoYXQgYXJlIGJvdW5kIHRvIGl0IHdpbGwKLSAgICAgKiBiZSBleGVjdXRlZCBhbnl0aW1lIHRoZSBtZXRob2QgaXMgY2FsbGVkLgotICAgICAqCi0gICAgICogQHBhcmFtICB7c3RyaW5nfSAgIG1ldGhvZE5hbWUgVGhlIG5hbWUgb2YgdGhlIG1ldGhvZCB0byBiaW5kLgotICAgICAqIEBwYXJhbSAge29iamVjdH0gICBzY29wZSAgICAgIFRoZSBzY29wZSB3aGVyZSB0aGUgbWV0aG9kIG11c3QgYmUgZXhlY3V0ZWQuCi0gICAgICogQHBhcmFtICB7ZnVuY3Rpb259IGZuICAgICAgICAgVGhlIG1ldGhvZCBpdHNlbGYuCi0gICAgICogQHJldHVybiB7ZnVuY3Rpb259ICAgICAgICAgICAgVGhlIG5ldyBtZXRob2QuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX19iaW5kR3JhcGhNZXRob2QobWV0aG9kTmFtZSwgc2NvcGUsIGZuKSB7Ci0gICAgICAgIHZhciByZXN1bHQgPSBmdW5jdGlvbiAoKSB7Ci0gICAgICAgICAgICB2YXIgaywKLSAgICAgICAgICAgICAgICByZXM7Ci0KLSAgICAgICAgICAgIC8vIEV4ZWN1dGUgImJlZm9yZSIgYm91bmQgZnVuY3Rpb25zOgotICAgICAgICAgICAgZm9yIChrIGluIF9tZXRob2RCZWZvcmVCaW5kaW5nc1ttZXRob2ROYW1lXSkKLSAgICAgICAgICAgICAgICBfbWV0aG9kQmVmb3JlQmluZGluZ3NbbWV0aG9kTmFtZV1ba10uYXBwbHkoc2NvcGUsIGFyZ3VtZW50cyk7Ci0KLSAgICAgICAgICAgIC8vIEFwcGx5IHRoZSBtZXRob2Q6Ci0gICAgICAgICAgICByZXMgPSBmbi5hcHBseShzY29wZSwgYXJndW1lbnRzKTsKLQotICAgICAgICAgICAgLy8gRXhlY3V0ZSBib3VuZCBmdW5jdGlvbnM6Ci0gICAgICAgICAgICBmb3IgKGsgaW4gX21ldGhvZEJpbmRpbmdzW21ldGhvZE5hbWVdKQotICAgICAgICAgICAgICAgIF9tZXRob2RCaW5kaW5nc1ttZXRob2ROYW1lXVtrXS5hcHBseShzY29wZSwgYXJndW1lbnRzKTsKLQotICAgICAgICAgICAgLy8gUmV0dXJuIHJlczoKLSAgICAgICAgICAgIHJldHVybiByZXM7Ci0gICAgICAgIH07Ci0KLSAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGN1c3RvbSB0b29sIGZ1bmN0aW9uIHJlbW92ZXMgZXZlcnkgcGFpciBrZXkvdmFsdWUgZnJvbSBhbiBoYXNoLiBUaGUKLSAgICAgKiBnb2FsIGlzIHRvIGF2b2lkIGNyZWF0aW5nIGEgbmV3IG9iamVjdCB3aGlsZSBzb21lIG90aGVyIHJlZmVyZW5jZXMgYXJlCi0gICAgICogc3RpbGwgaGFuZ2luZyBpbiBzb21lIHNjb3Blcy4uLgotICAgICAqCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSBvYmogVGhlIG9iamVjdCB0byBlbXB0eS4KLSAgICAgKiBAcmV0dXJuIHtvYmplY3R9ICAgICBUaGUgZW1wdHkgb2JqZWN0LgotICAgICAqLwotICAgIGZ1bmN0aW9uIF9fZW1wdHlPYmplY3Qob2JqKSB7Ci0gICAgICAgIHZhciBrOwotCi0gICAgICAgIGZvciAoayBpbiBvYmopCi0gICAgICAgICAgICBpZiAoISgnaGFzT3duUHJvcGVydHknIGluIG9iaikgfHwgb2JqLmhhc093blByb3BlcnR5KGspKQotICAgICAgICAgICAgICAgIGRlbGV0ZSBvYmpba107Ci0KLSAgICAgICAgcmV0dXJuIG9iajsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRoaXMgZ2xvYmFsIG1ldGhvZCBhZGRzIGEgbWV0aG9kIHRoYXQgd2lsbCBiZSBib3VuZCB0byB0aGUgZnV0dXJseSBjcmVhdGVkCi0gICAgICogZ3JhcGggaW5zdGFuY2VzLgotICAgICAqCi0gICAgICogU2luY2UgdGhlc2UgbWV0aG9kcyB3aWxsIGJlIGJvdW5kIHRvIHRoZWlyIHNjb3BlIHdoZW4gdGhlIGluc3RhbmNlcyBhcmUKLSAgICAgKiBjcmVhdGVkLCBpdCBkb2VzIG5vdCB1c2UgdGhlIHByb3RvdHlwZS4gQmVjYXVzZSBvZiB0aGF0LCBtZXRob2RzIGhhdmUgdG8KLSAgICAgKiBiZSBhZGRlZCBiZWZvcmUgaW5zdGFuY2VzIGFyZSBjcmVhdGVkIHRvIG1ha2UgdGhlbSBhdmFpbGFibGUuCi0gICAgICoKLSAgICAgKiBIZXJlIGlzIGFuIGV4YW1wbGU6Ci0gICAgICoKLSAgICAgKiAgPiBncmFwaC5hZGRNZXRob2QoJ2dldE5vZGVzQ291bnQnLCBmdW5jdGlvbigpIHsKLSAgICogID4gICByZXR1cm4gdGhpcy5ub2Rlc0FycmF5Lmxlbmd0aDsKLSAgICogID4gfSk7Ci0gICAgICogID4KLSAgICAgKiAgPiB2YXIgbXlHcmFwaCA9IG5ldyBncmFwaCgpOwotICAgICAqICA+IGNvbnNvbGUubG9nKG15R3JhcGguZ2V0Tm9kZXNDb3VudCgpKTsgLy8gb3V0cHV0cyAwCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtzdHJpbmd9ICAgbWV0aG9kTmFtZSBUaGUgbmFtZSBvZiB0aGUgbWV0aG9kLgotICAgICAqIEBwYXJhbSAge2Z1bmN0aW9ufSBmbiAgICAgICAgIFRoZSBtZXRob2QgaXRzZWxmLgotICAgICAqIEByZXR1cm4ge29iamVjdH0gICAgICAgICAgICAgIFRoZSBnbG9iYWwgZ3JhcGggY29uc3RydWN0b3IuCi0gICAgICovCi0gICAgZ3JhcGguYWRkTWV0aG9kID0gZnVuY3Rpb24gKG1ldGhvZE5hbWUsIGZuKSB7Ci0gICAgICAgIGlmICgKLSAgICAgICAgICAgIHR5cGVvZiBtZXRob2ROYW1lICE9PSAnc3RyaW5nJyB8fAotICAgICAgICAgICAgdHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nIHx8Ci0gICAgICAgICAgICBhcmd1bWVudHMubGVuZ3RoICE9PSAyCi0gICAgICAgICkKLSAgICAgICAgICAgIHRocm93ICdhZGRNZXRob2Q6IFdyb25nIGFyZ3VtZW50cy4nOwotCi0gICAgICAgIGlmIChfbWV0aG9kc1ttZXRob2ROYW1lXSB8fCBncmFwaFttZXRob2ROYW1lXSkKLSAgICAgICAgICAgIHRocm93ICdUaGUgbWV0aG9kICInICsgbWV0aG9kTmFtZSArICciIGFscmVhZHkgZXhpc3RzLic7Ci0KLSAgICAgICAgX21ldGhvZHNbbWV0aG9kTmFtZV0gPSBmbjsKLSAgICAgICAgX21ldGhvZEJpbmRpbmdzW21ldGhvZE5hbWVdID0gT2JqZWN0LmNyZWF0ZShudWxsKTsKLSAgICAgICAgX21ldGhvZEJlZm9yZUJpbmRpbmdzW21ldGhvZE5hbWVdID0gT2JqZWN0LmNyZWF0ZShudWxsKTsKLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBnbG9iYWwgbWV0aG9kIHJldHVybnMgdHJ1ZSBpZiB0aGUgbWV0aG9kIGhhcyBhbHJlYWR5IGJlZW4gYWRkZWQsIGFuZAotICAgICAqIGZhbHNlIGVsc2UuCi0gICAgICoKLSAgICAgKiBIZXJlIGFyZSBzb21lIGV4YW1wbGVzOgotICAgICAqCi0gICAgICogID4gZ3JhcGguaGFzTWV0aG9kKCdhZGROb2RlJyk7IC8vIHJldHVybnMgdHJ1ZQotICAgICAqICA+IGdyYXBoLmhhc01ldGhvZCgnaGFzTWV0aG9kJyk7IC8vIHJldHVybnMgdHJ1ZQotICAgICAqICA+IGdyYXBoLmhhc01ldGhvZCgndW5leGlzdGluZ01ldGhvZCcpOyAvLyByZXR1cm5zIGZhbHNlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtzdHJpbmd9ICBtZXRob2ROYW1lIFRoZSBuYW1lIG9mIHRoZSBtZXRob2QuCi0gICAgICogQHJldHVybiB7Ym9vbGVhbn0gICAgICAgICAgICBUaGUgcmVzdWx0LgotICAgICAqLwotICAgIGdyYXBoLmhhc01ldGhvZCA9IGZ1bmN0aW9uIChtZXRob2ROYW1lKSB7Ci0gICAgICAgIHJldHVybiAhIShfbWV0aG9kc1ttZXRob2ROYW1lXSB8fCBncmFwaFttZXRob2ROYW1lXSk7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgZ2xvYmFsIG1ldGhvZHMgYXR0YWNoZXMgYSBmdW5jdGlvbiB0byBhIG1ldGhvZC4gQW55dGltZSB0aGUgc3BlY2lmaWVkCi0gICAgICogbWV0aG9kIGlzIGNhbGxlZCwgdGhlIGF0dGFjaGVkIGZ1bmN0aW9uIGlzIGNhbGxlZCByaWdodCBhZnRlciwgd2l0aCB0aGUKLSAgICAgKiBzYW1lIGFyZ3VtZW50cyBhbmQgaW4gdGhlIHNhbWUgc2NvcGUuIFRoZSBhdHRhY2hlZCBmdW5jdGlvbiBpcyBjYWxsZWQKLSAgICAgKiByaWdodCBiZWZvcmUgaWYgdGhlIGxhc3QgYXJndW1lbnQgaXMgdHJ1ZSwgdW5sZXNzIHRoZSBtZXRob2QgaXMgdGhlIGdyYXBoCi0gICAgICogY29uc3RydWN0b3IuCi0gICAgICoKLSAgICAgKiBUbyBhdHRhY2ggYSBmdW5jdGlvbiB0byB0aGUgZ3JhcGggY29uc3RydWN0b3IsIHVzZSAnY29uc3RydWN0b3InIGFzIHRoZQotICAgICAqIG1ldGhvZCBuYW1lIChmaXJzdCBhcmd1bWVudCkuCi0gICAgICoKLSAgICAgKiBUaGUgbWFpbiBpZGVhIGlzIHRvIGhhdmUgYSBjbGVhbiB3YXkgdG8ga2VlcCBjdXN0b20gaW5kZXhlcyB1cCB0byBkYXRlLAotICAgICAqIGZvciBpbnN0YW5jZToKLSAgICAgKgotICAgICAqICA+IHZhciB0aW1lc0FkZE5vZGVDYWxsZWQgPSAwOwotICAgICAqICA+IGdyYXBoLmF0dGFjaCgnYWRkTm9kZScsICd0aW1lc0FkZE5vZGVDYWxsZWRJbmMnLCBmdW5jdGlvbigpIHsKLSAgICogID4gICB0aW1lc0FkZE5vZGVDYWxsZWQrKzsKLSAgICogID4gfSk7Ci0gICAgICogID4KLSAgICAgKiAgPiB2YXIgbXlHcmFwaCA9IG5ldyBncmFwaCgpOwotICAgICAqICA+IGNvbnNvbGUubG9nKHRpbWVzQWRkTm9kZUNhbGxlZCk7IC8vIG91dHB1dHMgMAotICAgICAqICA+Ci0gICAgICogID4gbXlHcmFwaC5hZGROb2RlKHsgaWQ6ICcxJyB9KS5hZGROb2RlKHsgaWQ6ICcyJyB9KTsKLSAgICAgKiAgPiBjb25zb2xlLmxvZyh0aW1lc0FkZE5vZGVDYWxsZWQpOyAvLyBvdXRwdXRzIDIKLSAgICAgKgotICAgICAqIFRoZSBpZGVhIGZvciBjYWxsaW5nIGEgZnVuY3Rpb24gYmVmb3JlIGlzIHRvIHByb3ZpZGUgcHJlLXByb2Nlc3NvcnMsIGZvcgotICAgICAqIGluc3RhbmNlOgotICAgICAqCi0gICAgICogID4gdmFyIGNvbG9yUGFsZXR0ZSA9IHsgUGVyc29uOiAnI0MzQ0JFMScsIFBsYWNlOiAnIzlCREVCRCcgfTsKLSAgICAgKiAgPiBncmFwaC5hdHRhY2goJ2FkZE5vZGUnLCAnYXBwbHlOb2RlQ29sb3JQYWxldHRlJywgZnVuY3Rpb24obikgewotICAgKiAgPiAgIG4uY29sb3IgPSBjb2xvclBhbGV0dGVbbi5jYXRlZ29yeV07Ci0gICAqICA+IH0sIHRydWUpOwotICAgICAqICA+Ci0gICAgICogID4gdmFyIG15R3JhcGggPSBuZXcgZ3JhcGgoKTsKLSAgICAgKiAgPiBteUdyYXBoLmFkZE5vZGUoeyBpZDogJ24wJywgY2F0ZWdvcnk6ICdQZXJzb24nIH0pOwotICAgICAqICA+IGNvbnNvbGUubG9nKG15R3JhcGgubm9kZXMoJ24wJykuY29sb3IpOyAvLyBvdXRwdXRzICcjQzNDQkUxJwotICAgICAqCi0gICAgICogQHBhcmFtICB7c3RyaW5nfSAgIG1ldGhvZE5hbWUgVGhlIG5hbWUgb2YgdGhlIHJlbGF0ZWQgbWV0aG9kIG9yCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbnN0cnVjdG9yIi4KLSAgICAgKiBAcGFyYW0gIHtzdHJpbmd9ICAga2V5ICAgICAgICBUaGUga2V5IHRvIGlkZW50aWZ5IHRoZSBmdW5jdGlvbiB0byBhdHRhY2guCi0gICAgICogQHBhcmFtICB7ZnVuY3Rpb259IGZuICAgICAgICAgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuCi0gICAgICogQHBhcmFtICB7Ym9vbGVhbn0gIGJlZm9yZSAgICAgSWYgdHJ1ZSB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkIHJpZ2h0IGJlZm9yZS4KLSAgICAgKiBAcmV0dXJuIHtvYmplY3R9ICAgICAgICAgICAgICBUaGUgZ2xvYmFsIGdyYXBoIGNvbnN0cnVjdG9yLgotICAgICAqLwotICAgIGdyYXBoLmF0dGFjaCA9IGZ1bmN0aW9uIChtZXRob2ROYW1lLCBrZXksIGZuLCBiZWZvcmUpIHsKLSAgICAgICAgaWYgKAotICAgICAgICAgICAgdHlwZW9mIG1ldGhvZE5hbWUgIT09ICdzdHJpbmcnIHx8Ci0gICAgICAgICAgICB0eXBlb2Yga2V5ICE9PSAnc3RyaW5nJyB8fAotICAgICAgICAgICAgdHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nIHx8Ci0gICAgICAgICAgICBhcmd1bWVudHMubGVuZ3RoIDwgMyB8fAotICAgICAgICAgICAgYXJndW1lbnRzLmxlbmd0aCA+IDQKLSAgICAgICAgKQotICAgICAgICAgICAgdGhyb3cgJ2F0dGFjaDogV3JvbmcgYXJndW1lbnRzLic7Ci0KLSAgICAgICAgdmFyIGJpbmRpbmdzOwotCi0gICAgICAgIGlmIChtZXRob2ROYW1lID09PSAnY29uc3RydWN0b3InKQotICAgICAgICAgICAgYmluZGluZ3MgPSBfaW5pdEJpbmRpbmdzOwotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlmIChiZWZvcmUpIHsKLSAgICAgICAgICAgICAgICBpZiAoIV9tZXRob2RCZWZvcmVCaW5kaW5nc1ttZXRob2ROYW1lXSkKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgJ1RoZSBtZXRob2QgIicgKyBtZXRob2ROYW1lICsgJyIgZG9lcyBub3QgZXhpc3QuJzsKLQotICAgICAgICAgICAgICAgIGJpbmRpbmdzID0gX21ldGhvZEJlZm9yZUJpbmRpbmdzW21ldGhvZE5hbWVdOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFfbWV0aG9kQmluZGluZ3NbbWV0aG9kTmFtZV0pCi0gICAgICAgICAgICAgICAgICAgIHRocm93ICdUaGUgbWV0aG9kICInICsgbWV0aG9kTmFtZSArICciIGRvZXMgbm90IGV4aXN0Lic7Ci0KLSAgICAgICAgICAgICAgICBiaW5kaW5ncyA9IF9tZXRob2RCaW5kaW5nc1ttZXRob2ROYW1lXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChiaW5kaW5nc1trZXldKQotICAgICAgICAgICAgdGhyb3cgJ0EgZnVuY3Rpb24gIicgKyBrZXkgKyAnIiBpcyBhbHJlYWR5IGF0dGFjaGVkICcgKwotICAgICAgICAgICAgJ3RvIHRoZSBtZXRob2QgIicgKyBtZXRob2ROYW1lICsgJyIuJzsKLQotICAgICAgICBiaW5kaW5nc1trZXldID0gZm47Ci0KLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIEFsaWFzIG9mIGF0dGFjaChtZXRob2ROYW1lLCBrZXksIGZuLCB0cnVlKS4KLSAgICAgKi8KLSAgICBncmFwaC5hdHRhY2hCZWZvcmUgPSBmdW5jdGlvbiAobWV0aG9kTmFtZSwga2V5LCBmbikgewotICAgICAgICByZXR1cm4gdGhpcy5hdHRhY2gobWV0aG9kTmFtZSwga2V5LCBmbiwgdHJ1ZSk7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kcyBpcyBqdXN0IGFuIGhlbHBlciB0byBkZWFsIHdpdGggY3VzdG9tIGluZGV4ZXMuIEl0IHRha2VzIGFzCi0gICAgICogYXJndW1lbnRzIHRoZSBuYW1lIG9mIHRoZSBpbmRleCBhbmQgYW4gb2JqZWN0IGNvbnRhaW5pbmcgYWxsIHRoZSBkaWZmZXJlbnQKLSAgICAgKiBmdW5jdGlvbnMgdG8gYmluZCB0byB0aGUgbWV0aG9kcy4KLSAgICAgKgotICAgICAqIEhlcmUgaXMgYSBiYXNpYyBleGFtcGxlLCB0aGF0IGNyZWF0ZXMgYW4gaW5kZXggdG8ga2VlcCB0aGUgbnVtYmVyIG9mIG5vZGVzCi0gICAgICogaW4gdGhlIGN1cnJlbnQgZ3JhcGguIEl0IGFsc28gYWRkcyBhIG1ldGhvZCB0byBwcm92aWRlIGEgZ2V0dGVyIG9uIHRoYXQKLSAgICAgKiBuZXcgaW5kZXg6Ci0gICAgICoKLSAgICAgKiAgPiBzaWdtYS5jbGFzc2VzLmdyYXBoLmFkZEluZGV4KCdub2Rlc0NvdW50JywgewotICAgKiAgPiAgIGNvbnN0cnVjdG9yOiBmdW5jdGlvbigpIHsKLSAgICogID4gICAgIHRoaXMubm9kZXNDb3VudCA9IDA7Ci0gICAqICA+ICAgfSwKLSAgICogID4gICBhZGROb2RlOiBmdW5jdGlvbigpIHsKLSAgICogID4gICAgIHRoaXMubm9kZXNDb3VudCsrOwotICAgKiAgPiAgIH0sCi0gICAqICA+ICAgZHJvcE5vZGU6IGZ1bmN0aW9uKCkgewotICAgKiAgPiAgICAgdGhpcy5ub2Rlc0NvdW50LS07Ci0gICAqICA+ICAgfQotICAgKiAgPiB9KTsKLSAgICAgKiAgPgotICAgICAqICA+IHNpZ21hLmNsYXNzZXMuZ3JhcGguYWRkTWV0aG9kKCdnZXROb2Rlc0NvdW50JywgZnVuY3Rpb24oKSB7Ci0gICAqICA+ICAgcmV0dXJuIHRoaXMubm9kZXNDb3VudDsKLSAgICogID4gfSk7Ci0gICAgICogID4KLSAgICAgKiAgPiB2YXIgbXlHcmFwaCA9IG5ldyBzaWdtYS5jbGFzc2VzLmdyYXBoKCk7Ci0gICAgICogID4gY29uc29sZS5sb2cobXlHcmFwaC5nZXROb2Rlc0NvdW50KCkpOyAvLyBvdXRwdXRzIDAKLSAgICAgKiAgPgotICAgICAqICA+IG15R3JhcGguYWRkTm9kZSh7IGlkOiAnMScgfSkuYWRkTm9kZSh7IGlkOiAnMicgfSk7Ci0gICAgICogID4gY29uc29sZS5sb2cobXlHcmFwaC5nZXROb2Rlc0NvdW50KCkpOyAvLyBvdXRwdXRzIDIKLSAgICAgKgotICAgICAqIEBwYXJhbSAge3N0cmluZ30gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGluZGV4LgotICAgICAqIEBwYXJhbSAge29iamVjdH0gYmluZGluZ3MgVGhlIG9iamVjdCBjb250YWluaW5nIHRoZSBmdW5jdGlvbnMgdG8gYmluZC4KLSAgICAgKiBAcmV0dXJuIHtvYmplY3R9ICAgICAgICAgIFRoZSBnbG9iYWwgZ3JhcGggY29uc3RydWN0b3IuCi0gICAgICovCi0gICAgZ3JhcGguYWRkSW5kZXggPSBmdW5jdGlvbiAobmFtZSwgYmluZGluZ3MpIHsKLSAgICAgICAgaWYgKAotICAgICAgICAgICAgdHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnIHx8Ci0gICAgICAgICAgICBPYmplY3QoYmluZGluZ3MpICE9PSBiaW5kaW5ncyB8fAotICAgICAgICAgICAgYXJndW1lbnRzLmxlbmd0aCAhPT0gMgotICAgICAgICApCi0gICAgICAgICAgICB0aHJvdyAnYWRkSW5kZXg6IFdyb25nIGFyZ3VtZW50cy4nOwotCi0gICAgICAgIGlmIChfaW5kZXhlc1tuYW1lXSkKLSAgICAgICAgICAgIHRocm93ICdUaGUgaW5kZXggIicgKyBuYW1lICsgJyIgYWxyZWFkeSBleGlzdHMuJzsKLQotICAgICAgICB2YXIgazsKLQotICAgICAgICAvLyBTdG9yZSB0aGUgYmluZGluZ3M6Ci0gICAgICAgIF9pbmRleGVzW25hbWVdID0gYmluZGluZ3M7Ci0KLSAgICAgICAgLy8gQXR0YWNoIHRoZSBiaW5kaW5nczoKLSAgICAgICAgZm9yIChrIGluIGJpbmRpbmdzKQotICAgICAgICAgICAgaWYgKHR5cGVvZiBiaW5kaW5nc1trXSAhPT0gJ2Z1bmN0aW9uJykKLSAgICAgICAgICAgICAgICB0aHJvdyAnVGhlIGJpbmRpbmdzIG11c3QgYmUgZnVuY3Rpb25zLic7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgZ3JhcGguYXR0YWNoKGssIG5hbWUsIGJpbmRpbmdzW2tdKTsKLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9OwotCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBhZGRzIGEgbm9kZSB0byB0aGUgZ3JhcGguIFRoZSBub2RlIG11c3QgYmUgYW4gb2JqZWN0LCB3aXRoIGEKLSAgICAgKiBzdHJpbmcgdW5kZXIgdGhlIGtleSAiaWQiLiBFeGNlcHQgZm9yIHRoaXMsIGl0IGlzIHBvc3NpYmxlIHRvIGFkZCBhbnkKLSAgICAgKiBvdGhlciBhdHRyaWJ1dGUsIHRoYXQgd2lsbCBiZSBwcmVzZXJ2ZWQgYWxsIGFsb25nIHRoZSBtYW5pcHVsYXRpb25zLgotICAgICAqCi0gICAgICogSWYgdGhlIGdyYXBoIG9wdGlvbiAiY2xvbmUiIGhhcyBhIHRydXRoeSB2YWx1ZSwgdGhlIG5vZGUgd2lsbCBiZSBjbG9uZWQKLSAgICAgKiB3aGVuIGFkZGVkIHRvIHRoZSBncmFwaC4gQWxzbywgaWYgdGhlIGdyYXBoIG9wdGlvbiAiaW1tdXRhYmxlIiBoYXMgYQotICAgICAqIHRydXRoeSB2YWx1ZSwgaXRzIGlkIHdpbGwgYmUgZGVmaW5lZCBhcyBpbW11dGFibGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9IG5vZGUgVGhlIG5vZGUgdG8gYWRkLgotICAgICAqIEByZXR1cm4ge29iamVjdH0gICAgICBUaGUgZ3JhcGggaW5zdGFuY2UuCi0gICAgICovCi0gICAgZ3JhcGguYWRkTWV0aG9kKCdhZGROb2RlJywgZnVuY3Rpb24gKG5vZGUpIHsKLSAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGUgbm9kZSBpcyBhbiBvYmplY3QgYW5kIGhhcyBhbiBpZDoKLSAgICAgICAgaWYgKE9iamVjdChub2RlKSAhPT0gbm9kZSB8fCBhcmd1bWVudHMubGVuZ3RoICE9PSAxKQotICAgICAgICAgICAgdGhyb3cgJ2FkZE5vZGU6IFdyb25nIGFyZ3VtZW50cy4nOwotCi0gICAgICAgIGlmICh0eXBlb2Ygbm9kZS5pZCAhPT0gJ3N0cmluZycgJiYgdHlwZW9mIG5vZGUuaWQgIT09ICdudW1iZXInKQotICAgICAgICAgICAgdGhyb3cgJ1RoZSBub2RlIG11c3QgaGF2ZSBhIHN0cmluZyBvciBudW1iZXIgaWQuJzsKLQotICAgICAgICBpZiAodGhpcy5ub2Rlc0luZGV4W25vZGUuaWRdKQotICAgICAgICAgICAgdGhyb3cgJ1RoZSBub2RlICInICsgbm9kZS5pZCArICciIGFscmVhZHkgZXhpc3RzLic7Ci0KLSAgICAgICAgdmFyIGssCi0gICAgICAgICAgICBpZCA9IG5vZGUuaWQsCi0gICAgICAgICAgICB2YWxpZE5vZGUgPSBPYmplY3QuY3JlYXRlKG51bGwpOwotCi0gICAgICAgIC8vIENoZWNrIHRoZSAiY2xvbmUiIG9wdGlvbjoKLSAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MoJ2Nsb25lJykpIHsKLSAgICAgICAgICAgIGZvciAoayBpbiBub2RlKQotICAgICAgICAgICAgICAgIGlmIChrICE9PSAnaWQnKQotICAgICAgICAgICAgICAgICAgICB2YWxpZE5vZGVba10gPSBub2RlW2tdOwotICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgIHZhbGlkTm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgLy8gQ2hlY2sgdGhlICJpbW11dGFibGUiIG9wdGlvbjoKLSAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MoJ2ltbXV0YWJsZScpKQotICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHZhbGlkTm9kZSwgJ2lkJywgewotICAgICAgICAgICAgICAgIHZhbHVlOiBpZCwKLSAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlCi0gICAgICAgICAgICB9KTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgdmFsaWROb2RlLmlkID0gaWQ7Ci0KLSAgICAgICAgLy8gQWRkIGVtcHR5IGNvbnRhaW5lcnMgZm9yIGVkZ2VzIGluZGV4ZXM6Ci0gICAgICAgIHRoaXMuaW5OZWlnaGJvcnNJbmRleFtpZF0gPSBPYmplY3QuY3JlYXRlKG51bGwpOwotICAgICAgICB0aGlzLm91dE5laWdoYm9yc0luZGV4W2lkXSA9IE9iamVjdC5jcmVhdGUobnVsbCk7Ci0gICAgICAgIHRoaXMuYWxsTmVpZ2hib3JzSW5kZXhbaWRdID0gT2JqZWN0LmNyZWF0ZShudWxsKTsKLQotICAgICAgICB0aGlzLmluTmVpZ2hib3JzQ291bnRbaWRdID0gMDsKLSAgICAgICAgdGhpcy5vdXROZWlnaGJvcnNDb3VudFtpZF0gPSAwOwotICAgICAgICB0aGlzLmFsbE5laWdoYm9yc0NvdW50W2lkXSA9IDA7Ci0KLSAgICAgICAgLy8gQWRkIHRoZSBub2RlIHRvIGluZGV4ZXM6Ci0gICAgICAgIHRoaXMubm9kZXNBcnJheS5wdXNoKHZhbGlkTm9kZSk7Ci0gICAgICAgIHRoaXMubm9kZXNJbmRleFt2YWxpZE5vZGUuaWRdID0gdmFsaWROb2RlOwotCi0gICAgICAgIC8vIFJldHVybiB0aGUgY3VycmVudCBpbnN0YW5jZToKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfSk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBhZGRzIGFuIGVkZ2UgdG8gdGhlIGdyYXBoLiBUaGUgZWRnZSBtdXN0IGJlIGFuIG9iamVjdCwgd2l0aCBhCi0gICAgICogc3RyaW5nIHVuZGVyIHRoZSBrZXkgImlkIiwgYW5kIHN0cmluZ3MgdW5kZXIgdGhlIGtleXMgInNvdXJjZSIgYW5kCi0gICAgICogInRhcmdldCIgdGhhdCBkZXNpZ24gZXhpc3Rpbmcgbm9kZXMuIEV4Y2VwdCBmb3IgdGhpcywgaXQgaXMgcG9zc2libGUgdG8KLSAgICAgKiBhZGQgYW55IG90aGVyIGF0dHJpYnV0ZSwgdGhhdCB3aWxsIGJlIHByZXNlcnZlZCBhbGwgYWxvbmcgdGhlCi0gICAgICogbWFuaXB1bGF0aW9ucy4KLSAgICAgKgotICAgICAqIElmIHRoZSBncmFwaCBvcHRpb24gImNsb25lIiBoYXMgYSB0cnV0aHkgdmFsdWUsIHRoZSBlZGdlIHdpbGwgYmUgY2xvbmVkCi0gICAgICogd2hlbiBhZGRlZCB0byB0aGUgZ3JhcGguIEFsc28sIGlmIHRoZSBncmFwaCBvcHRpb24gImltbXV0YWJsZSIgaGFzIGEKLSAgICAgKiB0cnV0aHkgdmFsdWUsIGl0cyBpZCwgc291cmNlIGFuZCB0YXJnZXQgd2lsbCBiZSBkZWZpbmVkIGFzIGltbXV0YWJsZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdH0gZWRnZSBUaGUgZWRnZSB0byBhZGQuCi0gICAgICogQHJldHVybiB7b2JqZWN0fSAgICAgIFRoZSBncmFwaCBpbnN0YW5jZS4KLSAgICAgKi8KLSAgICBncmFwaC5hZGRNZXRob2QoJ2FkZEVkZ2UnLCBmdW5jdGlvbiAoZWRnZSkgewotICAgICAgICAvLyBDaGVjayB0aGF0IHRoZSBlZGdlIGlzIGFuIG9iamVjdCBhbmQgaGFzIGFuIGlkOgotICAgICAgICBpZiAoT2JqZWN0KGVkZ2UpICE9PSBlZGdlIHx8IGFyZ3VtZW50cy5sZW5ndGggIT09IDEpCi0gICAgICAgICAgICB0aHJvdyAnYWRkRWRnZTogV3JvbmcgYXJndW1lbnRzLic7Ci0KLSAgICAgICAgaWYgKHR5cGVvZiBlZGdlLmlkICE9PSAnc3RyaW5nJyAmJiB0eXBlb2YgZWRnZS5pZCAhPT0gJ251bWJlcicpCi0gICAgICAgICAgICB0aHJvdyAnVGhlIGVkZ2UgbXVzdCBoYXZlIGEgc3RyaW5nIG9yIG51bWJlciBpZC4nOwotCi0gICAgICAgIGlmICgodHlwZW9mIGVkZ2Uuc291cmNlICE9PSAnc3RyaW5nJyAmJiB0eXBlb2YgZWRnZS5zb3VyY2UgIT09ICdudW1iZXInKSB8fCAhdGhpcy5ub2Rlc0luZGV4W2VkZ2Uuc291cmNlXSkKLSAgICAgICAgICAgIHRocm93ICdUaGUgZWRnZSBzb3VyY2UgbXVzdCBoYXZlIGFuIGV4aXN0aW5nIG5vZGUgaWQuJzsKLQotICAgICAgICBpZiAoKHR5cGVvZiBlZGdlLnRhcmdldCAhPT0gJ3N0cmluZycgJiYgdHlwZW9mIGVkZ2UudGFyZ2V0ICE9PSAnbnVtYmVyJykgfHwgIXRoaXMubm9kZXNJbmRleFtlZGdlLnRhcmdldF0pCi0gICAgICAgICAgICB0aHJvdyAnVGhlIGVkZ2UgdGFyZ2V0IG11c3QgaGF2ZSBhbiBleGlzdGluZyBub2RlIGlkLic7Ci0KLSAgICAgICAgaWYgKHRoaXMuZWRnZXNJbmRleFtlZGdlLmlkXSkKLSAgICAgICAgICAgIHRocm93ICdUaGUgZWRnZSAiJyArIGVkZ2UuaWQgKyAnIiBhbHJlYWR5IGV4aXN0cy4nOwotCi0gICAgICAgIHZhciBrLAotICAgICAgICAgICAgdmFsaWRFZGdlID0gT2JqZWN0LmNyZWF0ZShudWxsKTsKLQotICAgICAgICAvLyBDaGVjayB0aGUgImNsb25lIiBvcHRpb246Ci0gICAgICAgIGlmICh0aGlzLnNldHRpbmdzKCdjbG9uZScpKSB7Ci0gICAgICAgICAgICBmb3IgKGsgaW4gZWRnZSkKLSAgICAgICAgICAgICAgICBpZiAoayAhPT0gJ2lkJyAmJiBrICE9PSAnc291cmNlJyAmJiBrICE9PSAndGFyZ2V0JykKLSAgICAgICAgICAgICAgICAgICAgdmFsaWRFZGdlW2tdID0gZWRnZVtrXTsKLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICB2YWxpZEVkZ2UgPSBlZGdlOwotCi0gICAgICAgIC8vIENoZWNrIHRoZSAiaW1tdXRhYmxlIiBvcHRpb246Ci0gICAgICAgIGlmICh0aGlzLnNldHRpbmdzKCdpbW11dGFibGUnKSkgewotICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHZhbGlkRWRnZSwgJ2lkJywgewotICAgICAgICAgICAgICAgIHZhbHVlOiBlZGdlLmlkLAotICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUKLSAgICAgICAgICAgIH0pOwotCi0gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodmFsaWRFZGdlLCAnc291cmNlJywgewotICAgICAgICAgICAgICAgIHZhbHVlOiBlZGdlLnNvdXJjZSwKLSAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlCi0gICAgICAgICAgICB9KTsKLQotICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHZhbGlkRWRnZSwgJ3RhcmdldCcsIHsKLSAgICAgICAgICAgICAgICB2YWx1ZTogZWRnZS50YXJnZXQsCi0gICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZQotICAgICAgICAgICAgfSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB2YWxpZEVkZ2UuaWQgPSBlZGdlLmlkOwotICAgICAgICAgICAgdmFsaWRFZGdlLnNvdXJjZSA9IGVkZ2Uuc291cmNlOwotICAgICAgICAgICAgdmFsaWRFZGdlLnRhcmdldCA9IGVkZ2UudGFyZ2V0OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWRkIHRoZSBlZGdlIHRvIGluZGV4ZXM6Ci0gICAgICAgIHRoaXMuZWRnZXNBcnJheS5wdXNoKHZhbGlkRWRnZSk7Ci0gICAgICAgIHRoaXMuZWRnZXNJbmRleFt2YWxpZEVkZ2UuaWRdID0gdmFsaWRFZGdlOwotCi0gICAgICAgIGlmICghdGhpcy5pbk5laWdoYm9yc0luZGV4W3ZhbGlkRWRnZS50YXJnZXRdW3ZhbGlkRWRnZS5zb3VyY2VdKQotICAgICAgICAgICAgdGhpcy5pbk5laWdoYm9yc0luZGV4W3ZhbGlkRWRnZS50YXJnZXRdW3ZhbGlkRWRnZS5zb3VyY2VdID0KLSAgICAgICAgICAgICAgICBPYmplY3QuY3JlYXRlKG51bGwpOwotICAgICAgICB0aGlzLmluTmVpZ2hib3JzSW5kZXhbdmFsaWRFZGdlLnRhcmdldF1bdmFsaWRFZGdlLnNvdXJjZV1bdmFsaWRFZGdlLmlkXSA9Ci0gICAgICAgICAgICB2YWxpZEVkZ2U7Ci0KLSAgICAgICAgaWYgKCF0aGlzLm91dE5laWdoYm9yc0luZGV4W3ZhbGlkRWRnZS5zb3VyY2VdW3ZhbGlkRWRnZS50YXJnZXRdKQotICAgICAgICAgICAgdGhpcy5vdXROZWlnaGJvcnNJbmRleFt2YWxpZEVkZ2Uuc291cmNlXVt2YWxpZEVkZ2UudGFyZ2V0XSA9Ci0gICAgICAgICAgICAgICAgT2JqZWN0LmNyZWF0ZShudWxsKTsKLSAgICAgICAgdGhpcy5vdXROZWlnaGJvcnNJbmRleFt2YWxpZEVkZ2Uuc291cmNlXVt2YWxpZEVkZ2UudGFyZ2V0XVt2YWxpZEVkZ2UuaWRdID0KLSAgICAgICAgICAgIHZhbGlkRWRnZTsKLQotICAgICAgICBpZiAoIXRoaXMuYWxsTmVpZ2hib3JzSW5kZXhbdmFsaWRFZGdlLnNvdXJjZV1bdmFsaWRFZGdlLnRhcmdldF0pCi0gICAgICAgICAgICB0aGlzLmFsbE5laWdoYm9yc0luZGV4W3ZhbGlkRWRnZS5zb3VyY2VdW3ZhbGlkRWRnZS50YXJnZXRdID0KLSAgICAgICAgICAgICAgICBPYmplY3QuY3JlYXRlKG51bGwpOwotICAgICAgICB0aGlzLmFsbE5laWdoYm9yc0luZGV4W3ZhbGlkRWRnZS5zb3VyY2VdW3ZhbGlkRWRnZS50YXJnZXRdW3ZhbGlkRWRnZS5pZF0gPQotICAgICAgICAgICAgdmFsaWRFZGdlOwotCi0gICAgICAgIGlmICh2YWxpZEVkZ2UudGFyZ2V0ICE9PSB2YWxpZEVkZ2Uuc291cmNlKSB7Ci0gICAgICAgICAgICBpZiAoIXRoaXMuYWxsTmVpZ2hib3JzSW5kZXhbdmFsaWRFZGdlLnRhcmdldF1bdmFsaWRFZGdlLnNvdXJjZV0pCi0gICAgICAgICAgICAgICAgdGhpcy5hbGxOZWlnaGJvcnNJbmRleFt2YWxpZEVkZ2UudGFyZ2V0XVt2YWxpZEVkZ2Uuc291cmNlXSA9Ci0gICAgICAgICAgICAgICAgICAgIE9iamVjdC5jcmVhdGUobnVsbCk7Ci0gICAgICAgICAgICB0aGlzLmFsbE5laWdoYm9yc0luZGV4W3ZhbGlkRWRnZS50YXJnZXRdW3ZhbGlkRWRnZS5zb3VyY2VdW3ZhbGlkRWRnZS5pZF0gPQotICAgICAgICAgICAgICAgIHZhbGlkRWRnZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEtlZXAgY291bnRzIHVwIHRvIGRhdGU6Ci0gICAgICAgIHRoaXMuaW5OZWlnaGJvcnNDb3VudFt2YWxpZEVkZ2UudGFyZ2V0XSsrOwotICAgICAgICB0aGlzLm91dE5laWdoYm9yc0NvdW50W3ZhbGlkRWRnZS5zb3VyY2VdKys7Ci0gICAgICAgIHRoaXMuYWxsTmVpZ2hib3JzQ291bnRbdmFsaWRFZGdlLnRhcmdldF0rKzsKLSAgICAgICAgdGhpcy5hbGxOZWlnaGJvcnNDb3VudFt2YWxpZEVkZ2Uuc291cmNlXSsrOwotCi0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0pOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgZHJvcHMgYSBub2RlIGZyb20gdGhlIGdyYXBoLiBJdCBhbHNvIHJlbW92ZXMgZWFjaCBlZGdlIHRoYXQgaXMKLSAgICAgKiBib3VuZCB0byBpdCwgdGhyb3VnaCB0aGUgZHJvcEVkZ2UgbWV0aG9kLiBBbiBlcnJvciBpcyB0aHJvd24gaWYgdGhlIG5vZGUKLSAgICAgKiBkb2VzIG5vdCBleGlzdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge3N0cmluZ30gaWQgVGhlIG5vZGUgaWQuCi0gICAgICogQHJldHVybiB7b2JqZWN0fSAgICBUaGUgZ3JhcGggaW5zdGFuY2UuCi0gICAgICovCi0gICAgZ3JhcGguYWRkTWV0aG9kKCdkcm9wTm9kZScsIGZ1bmN0aW9uIChpZCkgewotICAgICAgICAvLyBDaGVjayB0aGF0IHRoZSBhcmd1bWVudHMgYXJlIHZhbGlkOgotICAgICAgICBpZiAoKHR5cGVvZiBpZCAhPT0gJ3N0cmluZycgJiYgdHlwZW9mIGlkICE9PSAnbnVtYmVyJykgfHwKLSAgICAgICAgICAgIGFyZ3VtZW50cy5sZW5ndGggIT09IDEpCi0gICAgICAgICAgICB0aHJvdyAnZHJvcE5vZGU6IFdyb25nIGFyZ3VtZW50cy4nOwotCi0gICAgICAgIGlmICghdGhpcy5ub2Rlc0luZGV4W2lkXSkKLSAgICAgICAgICAgIHRocm93ICdUaGUgbm9kZSAiJyArIGlkICsgJyIgZG9lcyBub3QgZXhpc3QuJzsKLQotICAgICAgICB2YXIgaSwgaywgbDsKLQotICAgICAgICAvLyBSZW1vdmUgdGhlIG5vZGUgZnJvbSBpbmRleGVzOgotICAgICAgICBkZWxldGUgdGhpcy5ub2Rlc0luZGV4W2lkXTsKLSAgICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMubm9kZXNBcnJheS5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICBpZiAodGhpcy5ub2Rlc0FycmF5W2ldLmlkID09PSBpZCkgewotICAgICAgICAgICAgICAgIHRoaXMubm9kZXNBcnJheS5zcGxpY2UoaSwgMSk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgLy8gUmVtb3ZlIHJlbGF0ZWQgZWRnZXM6Ci0gICAgICAgIGZvciAoaSA9IHRoaXMuZWRnZXNBcnJheS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkKLSAgICAgICAgICAgIGlmICh0aGlzLmVkZ2VzQXJyYXlbaV0uc291cmNlID09PSBpZCB8fCB0aGlzLmVkZ2VzQXJyYXlbaV0udGFyZ2V0ID09PSBpZCkKLSAgICAgICAgICAgICAgICB0aGlzLmRyb3BFZGdlKHRoaXMuZWRnZXNBcnJheVtpXS5pZCk7Ci0KLSAgICAgICAgLy8gUmVtb3ZlIHJlbGF0ZWQgZWRnZSBpbmRleGVzOgotICAgICAgICBkZWxldGUgdGhpcy5pbk5laWdoYm9yc0luZGV4W2lkXTsKLSAgICAgICAgZGVsZXRlIHRoaXMub3V0TmVpZ2hib3JzSW5kZXhbaWRdOwotICAgICAgICBkZWxldGUgdGhpcy5hbGxOZWlnaGJvcnNJbmRleFtpZF07Ci0KLSAgICAgICAgZGVsZXRlIHRoaXMuaW5OZWlnaGJvcnNDb3VudFtpZF07Ci0gICAgICAgIGRlbGV0ZSB0aGlzLm91dE5laWdoYm9yc0NvdW50W2lkXTsKLSAgICAgICAgZGVsZXRlIHRoaXMuYWxsTmVpZ2hib3JzQ291bnRbaWRdOwotCi0gICAgICAgIGZvciAoayBpbiB0aGlzLm5vZGVzSW5kZXgpIHsKLSAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmluTmVpZ2hib3JzSW5kZXhba11baWRdOwotICAgICAgICAgICAgZGVsZXRlIHRoaXMub3V0TmVpZ2hib3JzSW5kZXhba11baWRdOwotICAgICAgICAgICAgZGVsZXRlIHRoaXMuYWxsTmVpZ2hib3JzSW5kZXhba11baWRdOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfSk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBkcm9wcyBhbiBlZGdlIGZyb20gdGhlIGdyYXBoLiBBbiBlcnJvciBpcyB0aHJvd24gaWYgdGhlIGVkZ2UKLSAgICAgKiBkb2VzIG5vdCBleGlzdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge3N0cmluZ30gaWQgVGhlIGVkZ2UgaWQuCi0gICAgICogQHJldHVybiB7b2JqZWN0fSAgICBUaGUgZ3JhcGggaW5zdGFuY2UuCi0gICAgICovCi0gICAgZ3JhcGguYWRkTWV0aG9kKCdkcm9wRWRnZScsIGZ1bmN0aW9uIChpZCkgewotICAgICAgICAvLyBDaGVjayB0aGF0IHRoZSBhcmd1bWVudHMgYXJlIHZhbGlkOgotICAgICAgICBpZiAoKHR5cGVvZiBpZCAhPT0gJ3N0cmluZycgJiYgdHlwZW9mIGlkICE9PSAnbnVtYmVyJykgfHwKLSAgICAgICAgICAgIGFyZ3VtZW50cy5sZW5ndGggIT09IDEpCi0gICAgICAgICAgICB0aHJvdyAnZHJvcEVkZ2U6IFdyb25nIGFyZ3VtZW50cy4nOwotCi0gICAgICAgIGlmICghdGhpcy5lZGdlc0luZGV4W2lkXSkKLSAgICAgICAgICAgIHRocm93ICdUaGUgZWRnZSAiJyArIGlkICsgJyIgZG9lcyBub3QgZXhpc3QuJzsKLQotICAgICAgICB2YXIgaSwgbCwgZWRnZTsKLQotICAgICAgICAvLyBSZW1vdmUgdGhlIGVkZ2UgZnJvbSBpbmRleGVzOgotICAgICAgICBlZGdlID0gdGhpcy5lZGdlc0luZGV4W2lkXTsKLSAgICAgICAgZGVsZXRlIHRoaXMuZWRnZXNJbmRleFtpZF07Ci0gICAgICAgIGZvciAoaSA9IDAsIGwgPSB0aGlzLmVkZ2VzQXJyYXkubGVuZ3RoOyBpIDwgbDsgaSsrKQotICAgICAgICAgICAgaWYgKHRoaXMuZWRnZXNBcnJheVtpXS5pZCA9PT0gaWQpIHsKLSAgICAgICAgICAgICAgICB0aGlzLmVkZ2VzQXJyYXkuc3BsaWNlKGksIDEpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotCi0gICAgICAgIGRlbGV0ZSB0aGlzLmluTmVpZ2hib3JzSW5kZXhbZWRnZS50YXJnZXRdW2VkZ2Uuc291cmNlXVtlZGdlLmlkXTsKLSAgICAgICAgaWYgKCFPYmplY3Qua2V5cyh0aGlzLmluTmVpZ2hib3JzSW5kZXhbZWRnZS50YXJnZXRdW2VkZ2Uuc291cmNlXSkubGVuZ3RoKQotICAgICAgICAgICAgZGVsZXRlIHRoaXMuaW5OZWlnaGJvcnNJbmRleFtlZGdlLnRhcmdldF1bZWRnZS5zb3VyY2VdOwotCi0gICAgICAgIGRlbGV0ZSB0aGlzLm91dE5laWdoYm9yc0luZGV4W2VkZ2Uuc291cmNlXVtlZGdlLnRhcmdldF1bZWRnZS5pZF07Ci0gICAgICAgIGlmICghT2JqZWN0LmtleXModGhpcy5vdXROZWlnaGJvcnNJbmRleFtlZGdlLnNvdXJjZV1bZWRnZS50YXJnZXRdKS5sZW5ndGgpCi0gICAgICAgICAgICBkZWxldGUgdGhpcy5vdXROZWlnaGJvcnNJbmRleFtlZGdlLnNvdXJjZV1bZWRnZS50YXJnZXRdOwotCi0gICAgICAgIGRlbGV0ZSB0aGlzLmFsbE5laWdoYm9yc0luZGV4W2VkZ2Uuc291cmNlXVtlZGdlLnRhcmdldF1bZWRnZS5pZF07Ci0gICAgICAgIGlmICghT2JqZWN0LmtleXModGhpcy5hbGxOZWlnaGJvcnNJbmRleFtlZGdlLnNvdXJjZV1bZWRnZS50YXJnZXRdKS5sZW5ndGgpCi0gICAgICAgICAgICBkZWxldGUgdGhpcy5hbGxOZWlnaGJvcnNJbmRleFtlZGdlLnNvdXJjZV1bZWRnZS50YXJnZXRdOwotCi0gICAgICAgIGlmIChlZGdlLnRhcmdldCAhPT0gZWRnZS5zb3VyY2UpIHsKLSAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmFsbE5laWdoYm9yc0luZGV4W2VkZ2UudGFyZ2V0XVtlZGdlLnNvdXJjZV1bZWRnZS5pZF07Ci0gICAgICAgICAgICBpZiAoIU9iamVjdC5rZXlzKHRoaXMuYWxsTmVpZ2hib3JzSW5kZXhbZWRnZS50YXJnZXRdW2VkZ2Uuc291cmNlXSkubGVuZ3RoKQotICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmFsbE5laWdoYm9yc0luZGV4W2VkZ2UudGFyZ2V0XVtlZGdlLnNvdXJjZV07Ci0gICAgICAgIH0KLQotICAgICAgICB0aGlzLmluTmVpZ2hib3JzQ291bnRbZWRnZS50YXJnZXRdLS07Ci0gICAgICAgIHRoaXMub3V0TmVpZ2hib3JzQ291bnRbZWRnZS5zb3VyY2VdLS07Ci0gICAgICAgIHRoaXMuYWxsTmVpZ2hib3JzQ291bnRbZWRnZS5zb3VyY2VdLS07Ci0gICAgICAgIHRoaXMuYWxsTmVpZ2hib3JzQ291bnRbZWRnZS50YXJnZXRdLS07Ci0KLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfSk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBkZXN0cm95cyB0aGUgY3VycmVudCBpbnN0YW5jZS4gSXQgYmFzaWNhbGx5IGVtcHRpZXMgZWFjaCBpbmRleAotICAgICAqIGFuZCBtZXRob2RzIGF0dGFjaGVkIHRvIHRoZSBncmFwaC4KLSAgICAgKi8KLSAgICBncmFwaC5hZGRNZXRob2QoJ2tpbGwnLCBmdW5jdGlvbiAoKSB7Ci0gICAgICAgIC8vIERlbGV0ZSBhcnJheXM6Ci0gICAgICAgIHRoaXMubm9kZXNBcnJheS5sZW5ndGggPSAwOwotICAgICAgICB0aGlzLmVkZ2VzQXJyYXkubGVuZ3RoID0gMDsKLSAgICAgICAgZGVsZXRlIHRoaXMubm9kZXNBcnJheTsKLSAgICAgICAgZGVsZXRlIHRoaXMuZWRnZXNBcnJheTsKLQotICAgICAgICAvLyBEZWxldGUgaW5kZXhlczoKLSAgICAgICAgZGVsZXRlIHRoaXMubm9kZXNJbmRleDsKLSAgICAgICAgZGVsZXRlIHRoaXMuZWRnZXNJbmRleDsKLSAgICAgICAgZGVsZXRlIHRoaXMuaW5OZWlnaGJvcnNJbmRleDsKLSAgICAgICAgZGVsZXRlIHRoaXMub3V0TmVpZ2hib3JzSW5kZXg7Ci0gICAgICAgIGRlbGV0ZSB0aGlzLmFsbE5laWdoYm9yc0luZGV4OwotICAgICAgICBkZWxldGUgdGhpcy5pbk5laWdoYm9yc0NvdW50OwotICAgICAgICBkZWxldGUgdGhpcy5vdXROZWlnaGJvcnNDb3VudDsKLSAgICAgICAgZGVsZXRlIHRoaXMuYWxsTmVpZ2hib3JzQ291bnQ7Ci0gICAgfSk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBlbXB0aWVzIHRoZSBub2RlcyBhbmQgZWRnZXMgYXJyYXlzLCBhcyB3ZWxsIGFzIHRoZSBkaWZmZXJlbnQKLSAgICAgKiBpbmRleGVzLgotICAgICAqCi0gICAgICogQHJldHVybiB7b2JqZWN0fSBUaGUgZ3JhcGggaW5zdGFuY2UuCi0gICAgICovCi0gICAgZ3JhcGguYWRkTWV0aG9kKCdjbGVhcicsIGZ1bmN0aW9uICgpIHsKLSAgICAgICAgdGhpcy5ub2Rlc0FycmF5Lmxlbmd0aCA9IDA7Ci0gICAgICAgIHRoaXMuZWRnZXNBcnJheS5sZW5ndGggPSAwOwotCi0gICAgICAgIC8vIER1ZSB0byBHQyBpc3N1ZXMsIEkgcHJlZmVyIG5vdCB0byBjcmVhdGUgbmV3IG9iamVjdC4gVGhlc2Ugb2JqZWN0cyBhcmUKLSAgICAgICAgLy8gb25seSBhdmFpbGFibGUgZnJvbSB0aGUgbWV0aG9kcyBhbmQgYXR0YWNoZWQgZnVuY3Rpb25zLCBidXQgc3RpbGwsIGl0IGlzCi0gICAgICAgIC8vIGJldHRlciB0byBwcmV2ZW50IGdob3N0IHJlZmVyZW5jZXMgdG8gdW5yZWxldmFudCBkYXRhLi4uCi0gICAgICAgIF9fZW1wdHlPYmplY3QodGhpcy5ub2Rlc0luZGV4KTsKLSAgICAgICAgX19lbXB0eU9iamVjdCh0aGlzLmVkZ2VzSW5kZXgpOwotICAgICAgICBfX2VtcHR5T2JqZWN0KHRoaXMubm9kZXNJbmRleCk7Ci0gICAgICAgIF9fZW1wdHlPYmplY3QodGhpcy5pbk5laWdoYm9yc0luZGV4KTsKLSAgICAgICAgX19lbXB0eU9iamVjdCh0aGlzLm91dE5laWdoYm9yc0luZGV4KTsKLSAgICAgICAgX19lbXB0eU9iamVjdCh0aGlzLmFsbE5laWdoYm9yc0luZGV4KTsKLSAgICAgICAgX19lbXB0eU9iamVjdCh0aGlzLmluTmVpZ2hib3JzQ291bnQpOwotICAgICAgICBfX2VtcHR5T2JqZWN0KHRoaXMub3V0TmVpZ2hib3JzQ291bnQpOwotICAgICAgICBfX2VtcHR5T2JqZWN0KHRoaXMuYWxsTmVpZ2hib3JzQ291bnQpOwotCi0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0pOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgcmVhZHMgYW4gb2JqZWN0IGFuZCBhZGRzIHRoZSBub2RlcyBhbmQgZWRnZXMsIHRocm91Z2ggdGhlCi0gICAgICogcHJvcGVyIG1ldGhvZHMgImFkZE5vZGUiIGFuZCAiYWRkRWRnZSIuCi0gICAgICoKLSAgICAgKiBIZXJlIGlzIGFuIGV4YW1wbGU6Ci0gICAgICoKLSAgICAgKiAgPiB2YXIgbXlHcmFwaCA9IG5ldyBncmFwaCgpOwotICAgICAqICA+IG15R3JhcGgucmVhZCh7Ci0gICAqICA+ICAgbm9kZXM6IFsKLSAgICogID4gICAgIHsgaWQ6ICduMCcgfSwKLSAgICogID4gICAgIHsgaWQ6ICduMScgfQotICAgKiAgPiAgIF0sCi0gICAqICA+ICAgZWRnZXM6IFsKLSAgICogID4gICAgIHsKLSAgICogID4gICAgICAgaWQ6ICdlMCcsCi0gICAqICA+ICAgICAgIHNvdXJjZTogJ24wJywKLSAgICogID4gICAgICAgdGFyZ2V0OiAnbjEnCi0gICAqICA+ICAgICB9Ci0gICAqICA+ICAgXQotICAgKiAgPiB9KTsKLSAgICAgKiAgPgotICAgICAqICA+IGNvbnNvbGUubG9nKAotICAgICAqICA+ICAgbXlHcmFwaC5ub2RlcygpLmxlbmd0aCwKLSAgICAgKiAgPiAgIG15R3JhcGguZWRnZXMoKS5sZW5ndGgKLSAgICAgKiAgPiApOyAvLyBvdXRwdXRzIDIgMQotICAgICAqCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSBnIFRoZSBncmFwaCBvYmplY3QuCi0gICAgICogQHJldHVybiB7b2JqZWN0fSAgIFRoZSBncmFwaCBpbnN0YW5jZS4KLSAgICAgKi8KLSAgICBncmFwaC5hZGRNZXRob2QoJ3JlYWQnLCBmdW5jdGlvbiAoZykgewotICAgICAgICB2YXIgaSwKLSAgICAgICAgICAgIGEsCi0gICAgICAgICAgICBsOwotCi0gICAgICAgIGEgPSBnLm5vZGVzIHx8IFtdOwotICAgICAgICBmb3IgKGkgPSAwLCBsID0gYS5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICB0aGlzLmFkZE5vZGUoYVtpXSk7Ci0KLSAgICAgICAgYSA9IGcuZWRnZXMgfHwgW107Ci0gICAgICAgIGZvciAoaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgIHRoaXMuYWRkRWRnZShhW2ldKTsKLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9KTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kcyByZXR1cm5zIG9uZSBvciBzZXZlcmFsIG5vZGVzLCBkZXBlbmRpbmcgb24gaG93IGl0IGlzIGNhbGxlZC4KLSAgICAgKgotICAgICAqIFRvIGdldCB0aGUgYXJyYXkgb2Ygbm9kZXMsIGNhbGwgIm5vZGVzIiB3aXRob3V0IGFyZ3VtZW50LiBUbyBnZXQgYQotICAgICAqIHNwZWNpZmljIG5vZGUsIGNhbGwgaXQgd2l0aCB0aGUgaWQgb2YgdGhlIG5vZGUuIFRoZSBnZXQgbXVsdGlwbGUgbm9kZSwKLSAgICAgKiBjYWxsIGl0IHdpdGggYW4gYXJyYXkgb2YgaWRzLCBhbmQgaXQgd2lsbCByZXR1cm4gdGhlIGFycmF5IG9mIG5vZGVzLCBpbgotICAgICAqIHRoZSBzYW1lIG9yZGVyLgotICAgICAqCi0gICAgICogQHBhcmFtICB7PyhzdHJpbmd8YXJyYXkpfSB2IEV2ZW50dWFsbHkgb25lIGlkLCBhbiBhcnJheSBvZiBpZHMuCi0gICAgICogQHJldHVybiB7b2JqZWN0fGFycmF5fSAgICAgIFRoZSByZWxhdGVkIG5vZGUgb3IgYXJyYXkgb2Ygbm9kZXMuCi0gICAgICovCi0gICAgZ3JhcGguYWRkTWV0aG9kKCdub2RlcycsIGZ1bmN0aW9uICh2KSB7Ci0gICAgICAgIC8vIENsb25lIHRoZSBhcnJheSBvZiBub2RlcyBhbmQgcmV0dXJuIGl0OgotICAgICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpCi0gICAgICAgICAgICByZXR1cm4gdGhpcy5ub2Rlc0FycmF5LnNsaWNlKDApOwotCi0gICAgICAgIC8vIFJldHVybiB0aGUgcmVsYXRlZCBub2RlOgotICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJgotICAgICAgICAgICAgKHR5cGVvZiB2ID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgdiA9PT0gJ251bWJlcicpKQotICAgICAgICAgICAgcmV0dXJuIHRoaXMubm9kZXNJbmRleFt2XTsKLQotICAgICAgICAvLyBSZXR1cm4gYW4gYXJyYXkgb2YgdGhlIHJlbGF0ZWQgbm9kZToKLSAgICAgICAgaWYgKAotICAgICAgICAgICAgYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJgotICAgICAgICAgICAgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHYpID09PSAnW29iamVjdCBBcnJheV0nCi0gICAgICAgICkgewotICAgICAgICAgICAgdmFyIGksCi0gICAgICAgICAgICAgICAgbCwKLSAgICAgICAgICAgICAgICBhID0gW107Ci0KLSAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSB2Lmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZbaV0gPT09ICdzdHJpbmcnIHx8IHR5cGVvZiB2W2ldID09PSAnbnVtYmVyJykKLSAgICAgICAgICAgICAgICAgICAgYS5wdXNoKHRoaXMubm9kZXNJbmRleFt2W2ldXSk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICB0aHJvdyAnbm9kZXM6IFdyb25nIGFyZ3VtZW50cy4nOwotCi0gICAgICAgICAgICByZXR1cm4gYTsKLSAgICAgICAgfQotCi0gICAgICAgIHRocm93ICdub2RlczogV3JvbmcgYXJndW1lbnRzLic7Ci0gICAgfSk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZHMgcmV0dXJucyB0aGUgZGVncmVlIG9mIG9uZSBvciBzZXZlcmFsIG5vZGVzLCBkZXBlbmRpbmcgb24gaG93Ci0gICAgICogaXQgaXMgY2FsbGVkLiBJdCBpcyBhbHNvIHBvc3NpYmxlIHRvIGdldCBpbmNvbWluZyBvciBvdXRjb21pbmcgZGVncmVlcwotICAgICAqIGluc3RlYWQgYnkgc3BlY2lmeWluZyAnaW4nIG9yICdvdXQnIGFzIGEgc2Vjb25kIGFyZ3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtICB7c3RyaW5nfGFycmF5fSB2ICAgICBPbmUgaWQsIGFuIGFycmF5IG9mIGlkcy4KLSAgICAgKiBAcGFyYW0gIHs/c3RyaW5nfSAgICAgIHdoaWNoIFdoaWNoIGRlZ3JlZSBpcyByZXF1aXJlZC4gVmFsdWVzIGFyZSAnaW4nLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ291dCcsIGFuZCBieSBkZWZhdWx0IHRoZSBub3JtYWwgZGVncmVlLgotICAgICAqIEByZXR1cm4ge251bWJlcnxhcnJheX0gICAgICAgVGhlIHJlbGF0ZWQgZGVncmVlIG9yIGFycmF5IG9mIGRlZ3JlZXMuCi0gICAgICovCi0gICAgZ3JhcGguYWRkTWV0aG9kKCdkZWdyZWUnLCBmdW5jdGlvbiAodiwgd2hpY2gpIHsKLSAgICAgICAgLy8gQ2hlY2sgd2hpY2ggZGVncmVlIGlzIHJlcXVpcmVkOgotICAgICAgICB3aGljaCA9IHsKLSAgICAgICAgICAgICAgICAnaW4nOiB0aGlzLmluTmVpZ2hib3JzQ291bnQsCi0gICAgICAgICAgICAgICAgJ291dCc6IHRoaXMub3V0TmVpZ2hib3JzQ291bnQKLSAgICAgICAgICAgIH1bd2hpY2ggfHwgJyddIHx8IHRoaXMuYWxsTmVpZ2hib3JzQ291bnQ7Ci0KLSAgICAgICAgLy8gUmV0dXJuIHRoZSByZWxhdGVkIG5vZGU6Ci0gICAgICAgIGlmICh0eXBlb2YgdiA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHYgPT09ICdudW1iZXInKQotICAgICAgICAgICAgcmV0dXJuIHdoaWNoW3ZdOwotCi0gICAgICAgIC8vIFJldHVybiBhbiBhcnJheSBvZiB0aGUgcmVsYXRlZCBub2RlOgotICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHYpID09PSAnW29iamVjdCBBcnJheV0nKSB7Ci0gICAgICAgICAgICB2YXIgaSwKLSAgICAgICAgICAgICAgICBsLAotICAgICAgICAgICAgICAgIGEgPSBbXTsKLQotICAgICAgICAgICAgZm9yIChpID0gMCwgbCA9IHYubGVuZ3RoOyBpIDwgbDsgaSsrKQotICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdltpXSA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHZbaV0gPT09ICdudW1iZXInKQotICAgICAgICAgICAgICAgICAgICBhLnB1c2god2hpY2hbdltpXV0pOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgJ2RlZ3JlZTogV3JvbmcgYXJndW1lbnRzLic7Ci0KLSAgICAgICAgICAgIHJldHVybiBhOwotICAgICAgICB9Ci0KLSAgICAgICAgdGhyb3cgJ2RlZ3JlZTogV3JvbmcgYXJndW1lbnRzLic7Ci0gICAgfSk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZHMgcmV0dXJucyBvbmUgb3Igc2V2ZXJhbCBlZGdlcywgZGVwZW5kaW5nIG9uIGhvdyBpdCBpcyBjYWxsZWQuCi0gICAgICoKLSAgICAgKiBUbyBnZXQgdGhlIGFycmF5IG9mIGVkZ2VzLCBjYWxsICJlZGdlcyIgd2l0aG91dCBhcmd1bWVudC4gVG8gZ2V0IGEKLSAgICAgKiBzcGVjaWZpYyBlZGdlLCBjYWxsIGl0IHdpdGggdGhlIGlkIG9mIHRoZSBlZGdlLiBUaGUgZ2V0IG11bHRpcGxlIGVkZ2UsCi0gICAgICogY2FsbCBpdCB3aXRoIGFuIGFycmF5IG9mIGlkcywgYW5kIGl0IHdpbGwgcmV0dXJuIHRoZSBhcnJheSBvZiBlZGdlcywgaW4KLSAgICAgKiB0aGUgc2FtZSBvcmRlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgez8oc3RyaW5nfGFycmF5KX0gdiBFdmVudHVhbGx5IG9uZSBpZCwgYW4gYXJyYXkgb2YgaWRzLgotICAgICAqIEByZXR1cm4ge29iamVjdHxhcnJheX0gICAgICBUaGUgcmVsYXRlZCBlZGdlIG9yIGFycmF5IG9mIGVkZ2VzLgotICAgICAqLwotICAgIGdyYXBoLmFkZE1ldGhvZCgnZWRnZXMnLCBmdW5jdGlvbiAodikgewotICAgICAgICAvLyBDbG9uZSB0aGUgYXJyYXkgb2YgZWRnZXMgYW5kIHJldHVybiBpdDoKLSAgICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKQotICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWRnZXNBcnJheS5zbGljZSgwKTsKLQotICAgICAgICAvLyBSZXR1cm4gdGhlIHJlbGF0ZWQgZWRnZToKLSAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEgJiYKLSAgICAgICAgICAgICh0eXBlb2YgdiA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHYgPT09ICdudW1iZXInKSkKLSAgICAgICAgICAgIHJldHVybiB0aGlzLmVkZ2VzSW5kZXhbdl07Ci0KLSAgICAgICAgLy8gUmV0dXJuIGFuIGFycmF5IG9mIHRoZSByZWxhdGVkIGVkZ2U6Ci0gICAgICAgIGlmICgKLSAgICAgICAgICAgIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgJiYKLSAgICAgICAgICAgIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2KSA9PT0gJ1tvYmplY3QgQXJyYXldJwotICAgICAgICApIHsKLSAgICAgICAgICAgIHZhciBpLAotICAgICAgICAgICAgICAgIGwsCi0gICAgICAgICAgICAgICAgYSA9IFtdOwotCi0gICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gdi5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2W2ldID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgdltpXSA9PT0gJ251bWJlcicpCi0gICAgICAgICAgICAgICAgICAgIGEucHVzaCh0aGlzLmVkZ2VzSW5kZXhbdltpXV0pOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgJ2VkZ2VzOiBXcm9uZyBhcmd1bWVudHMuJzsKLQotICAgICAgICAgICAgcmV0dXJuIGE7Ci0gICAgICAgIH0KLQotICAgICAgICB0aHJvdyAnZWRnZXM6IFdyb25nIGFyZ3VtZW50cy4nOwotICAgIH0pOwotCi0KLSAgICAvKioKLSAgICAgKiBFWFBPUlQ6Ci0gICAgICogKioqKioqKgotICAgICAqLwotICAgIGlmICh0eXBlb2Ygc2lnbWEgIT09ICd1bmRlZmluZWQnKSB7Ci0gICAgICAgIHNpZ21hLmNsYXNzZXMgPSBzaWdtYS5jbGFzc2VzIHx8IE9iamVjdC5jcmVhdGUobnVsbCk7Ci0gICAgICAgIHNpZ21hLmNsYXNzZXMuZ3JhcGggPSBncmFwaDsKLSAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykgewotICAgICAgICBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpCi0gICAgICAgICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBncmFwaDsKLSAgICAgICAgZXhwb3J0cy5ncmFwaCA9IGdyYXBoOwotICAgIH0gZWxzZQotICAgICAgICB0aGlzLmdyYXBoID0gZ3JhcGg7Ci19KS5jYWxsKHRoaXMpOwotCi07KGZ1bmN0aW9uICh1bmRlZmluZWQpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBpZiAodHlwZW9mIHNpZ21hID09PSAndW5kZWZpbmVkJykKLSAgICAgICAgdGhyb3cgJ3NpZ21hIGlzIG5vdCBkZWNsYXJlZCc7Ci0KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLmNsYXNzZXMnKTsKLQotICAgIC8qKgotICAgICAqIFRoZSBjYW1lcmEgY29uc3RydWN0b3IuIEl0IGp1c3QgaW5pdGlhbGl6ZXMgaXRzIGF0dHJpYnV0ZXMgYW5kIG1ldGhvZHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtzdHJpbmd9ICAgICAgIGlkICAgICAgIFRoZSBpZC4KLSAgICAgKiBAcGFyYW0gIHtzaWdtYS5jbGFzc2VzLmdyYXBofSAgZ3JhcGggICAgVGhlIGdyYXBoLgotICAgICAqIEBwYXJhbSAge2NvbmZpZ3VyYWJsZX0gc2V0dGluZ3MgVGhlIHNldHRpbmdzIGZ1bmN0aW9uLgotICAgICAqIEBwYXJhbSAgez9vYmplY3R9ICAgICAgb3B0aW9ucyAgRXZlbnR1YWxseSBzb21lIG92ZXJyaWRpbmcgb3B0aW9ucy4KLSAgICAgKiBAcmV0dXJuIHtjYW1lcmF9ICAgICAgICAgICAgICAgIFJldHVybnMgdGhlIGZyZXNoIG5ldyBjYW1lcmEgaW5zdGFuY2UuCi0gICAgICovCi0gICAgc2lnbWEuY2xhc3Nlcy5jYW1lcmEgPSBmdW5jdGlvbiAoaWQsIGdyYXBoLCBzZXR0aW5ncywgb3B0aW9ucykgewotICAgICAgICBzaWdtYS5jbGFzc2VzLmRpc3BhdGNoZXIuZXh0ZW5kKHRoaXMpOwotCi0gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZ3JhcGgnLCB7Ci0gICAgICAgICAgICB2YWx1ZTogZ3JhcGgKLSAgICAgICAgfSk7Ci0gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnaWQnLCB7Ci0gICAgICAgICAgICB2YWx1ZTogaWQKLSAgICAgICAgfSk7Ci0gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncmVhZFByZWZpeCcsIHsKLSAgICAgICAgICAgIHZhbHVlOiAncmVhZF9jYW0nICsgaWQgKyAnOicKLSAgICAgICAgfSk7Ci0gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncHJlZml4JywgewotICAgICAgICAgICAgdmFsdWU6ICdjYW0nICsgaWQgKyAnOicKLSAgICAgICAgfSk7Ci0KLSAgICAgICAgdGhpcy54ID0gMDsKLSAgICAgICAgdGhpcy55ID0gMDsKLSAgICAgICAgdGhpcy5yYXRpbyA9IDE7Ci0gICAgICAgIHRoaXMuYW5nbGUgPSAwOwotICAgICAgICB0aGlzLmlzQW5pbWF0ZWQgPSBmYWxzZTsKLSAgICAgICAgdGhpcy5zZXR0aW5ncyA9ICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcgJiYgb3B0aW9ucykgPwotICAgICAgICAgICAgc2V0dGluZ3MuZW1iZWRPYmplY3Qob3B0aW9ucykgOgotICAgICAgICAgICAgc2V0dGluZ3M7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFVwZGF0ZXMgdGhlIGNhbWVyYSBwb3NpdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdH0gY29vcmRpbmF0ZXMgVGhlIG5ldyBjb29yZGluYXRlcyBvYmplY3QuCi0gICAgICogQHJldHVybiB7Y2FtZXJhfSAgICAgICAgICAgICBSZXR1cm5zIHRoZSBjYW1lcmEuCi0gICAgICovCi0gICAgc2lnbWEuY2xhc3Nlcy5jYW1lcmEucHJvdG90eXBlLmdvVG8gPSBmdW5jdGlvbiAoY29vcmRpbmF0ZXMpIHsKLSAgICAgICAgaWYgKCF0aGlzLnNldHRpbmdzKCdlbmFibGVDYW1lcmEnKSkKLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotCi0gICAgICAgIHZhciBpLAotICAgICAgICAgICAgbCwKLSAgICAgICAgICAgIGMgPSBjb29yZGluYXRlcyB8fCB7fSwKLSAgICAgICAgICAgIGtleXMgPSBbJ3gnLCAneScsICdyYXRpbycsICdhbmdsZSddOwotCi0gICAgICAgIGZvciAoaSA9IDAsIGwgPSBrZXlzLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgIGlmIChjW2tleXNbaV1dICE9PSB1bmRlZmluZWQpIHsKLSAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNba2V5c1tpXV0gPT09ICdudW1iZXInICYmICFpc05hTihjW2tleXNbaV1dKSkKLSAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IGNba2V5c1tpXV07Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICB0aHJvdyAnVmFsdWUgZm9yICInICsga2V5c1tpXSArICciIGlzIG5vdCBhIG51bWJlci4nOwotICAgICAgICAgICAgfQotCi0gICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudCgnY29vcmRpbmF0ZXNVcGRhdGVkJyk7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCB0YWtlcyBhIGdyYXBoIGFuZCBjb21wdXRlcyBmb3IgZWFjaCBub2RlIGFuZCBlZGdlcyBpdHMKLSAgICAgKiBjb29yZGluYXRlcyByZWxhdGl2ZWx5IHRvIHRoZSBjZW50ZXIgb2YgdGhlIGNhbWVyYS4gQmFzaWNhbGx5LCBpdCB3aWxsCi0gICAgICogY29tcHV0ZSB0aGUgY29vcmRpbmF0ZXMgdGhhdCB3aWxsIGJlIHVzZWQgYnkgdGhlIGdyYXBoaWMgcmVuZGVyZXJzLgotICAgICAqCi0gICAgICogU2luY2UgaXQgc2hvdWxkIGJlIHBvc3NpYmxlIHRvIHVzZSBkaWZmZXJlbnQgY2FtZXJhcyBhbmQgZGlmZmVyZW50Ci0gICAgICogcmVuZGVyZXJzLCBpdCBpcyBwb3NzaWJsZSB0byBzcGVjaWZ5IGEgcHJlZml4IHRvIHB1dCBiZWZvcmUgdGhlIG5ldwotICAgICAqIGNvb3JkaW5hdGVzICh0byBnZXQgc29tZXRoaW5nIGxpa2UgIm5vZGUuY2FtZXJhMV94IikKLSAgICAgKgotICAgICAqIEBwYXJhbSAgez9zdHJpbmd9IHJlYWQgICAgVGhlIHByZWZpeCBvZiB0aGUgY29vcmRpbmF0ZXMgdG8gcmVhZC4KLSAgICAgKiBAcGFyYW0gIHs/c3RyaW5nfSB3cml0ZSAgIFRoZSBwcmVmaXggb2YgdGhlIGNvb3JkaW5hdGVzIHRvIHdyaXRlLgotICAgICAqIEBwYXJhbSAgez9vYmplY3R9IG9wdGlvbnMgRXZlbnR1YWxseSBhbiBvYmplY3Qgb2Ygb3B0aW9ucy4gVGhvc2UgY2FuIGJlOgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBBIHJlc3RyaWN0ZWQgbm9kZXMgYXJyYXkuCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAtIEEgcmVzdHJpY3RlZCBlZGdlcyBhcnJheS4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gQSB3aWR0aC4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gQSBoZWlnaHQuCi0gICAgICogQHJldHVybiB7Y2FtZXJhfSAgICAgICAgUmV0dXJucyB0aGUgY2FtZXJhLgotICAgICAqLwotICAgIHNpZ21hLmNsYXNzZXMuY2FtZXJhLnByb3RvdHlwZS5hcHBseVZpZXcgPSBmdW5jdGlvbiAocmVhZCwgd3JpdGUsIG9wdGlvbnMpIHsKLSAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307Ci0gICAgICAgIHdyaXRlID0gd3JpdGUgIT09IHVuZGVmaW5lZCA/IHdyaXRlIDogdGhpcy5wcmVmaXg7Ci0gICAgICAgIHJlYWQgPSByZWFkICE9PSB1bmRlZmluZWQgPyByZWFkIDogdGhpcy5yZWFkUHJlZml4OwotCi0gICAgICAgIHZhciBub2RlcyA9IG9wdGlvbnMubm9kZXMgfHwgdGhpcy5ncmFwaC5ub2RlcygpLAotICAgICAgICAgICAgZWRnZXMgPSBvcHRpb25zLmVkZ2VzIHx8IHRoaXMuZ3JhcGguZWRnZXMoKTsKLQotICAgICAgICB2YXIgaSwKLSAgICAgICAgICAgIGwsCi0gICAgICAgICAgICBub2RlLAotICAgICAgICAgICAgY29zID0gTWF0aC5jb3ModGhpcy5hbmdsZSksCi0gICAgICAgICAgICBzaW4gPSBNYXRoLnNpbih0aGlzLmFuZ2xlKSwKLSAgICAgICAgICAgIG5vZGVSYXRpbyA9IE1hdGgucG93KHRoaXMucmF0aW8sIHRoaXMuc2V0dGluZ3MoJ25vZGVzUG93UmF0aW8nKSksCi0gICAgICAgICAgICBlZGdlUmF0aW8gPSBNYXRoLnBvdyh0aGlzLnJhdGlvLCB0aGlzLnNldHRpbmdzKCdlZGdlc1Bvd1JhdGlvJykpLAotICAgICAgICAgICAgeE9mZnNldCA9IChvcHRpb25zLndpZHRoIHx8IDApIC8gMiwKLSAgICAgICAgICAgIHlPZmZzZXQgPSAob3B0aW9ucy5oZWlnaHQgfHwgMCkgLyAyOwotCi0gICAgICAgIGZvciAoaSA9IDAsIGwgPSBub2Rlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKLSAgICAgICAgICAgIG5vZGUgPSBub2Rlc1tpXTsKLSAgICAgICAgICAgIG5vZGVbd3JpdGUgKyAneCddID0KLSAgICAgICAgICAgICAgICAoCi0gICAgICAgICAgICAgICAgICAgICgobm9kZVtyZWFkICsgJ3gnXSB8fCAwKSAtIHRoaXMueCkgKiBjb3MgKwotICAgICAgICAgICAgICAgICAgICAoKG5vZGVbcmVhZCArICd5J10gfHwgMCkgLSB0aGlzLnkpICogc2luCi0gICAgICAgICAgICAgICAgKSAvIHRoaXMucmF0aW8gKyB4T2Zmc2V0OwotICAgICAgICAgICAgbm9kZVt3cml0ZSArICd5J10gPQotICAgICAgICAgICAgICAgICgKLSAgICAgICAgICAgICAgICAgICAgKChub2RlW3JlYWQgKyAneSddIHx8IDApIC0gdGhpcy55KSAqIGNvcyAtCi0gICAgICAgICAgICAgICAgICAgICgobm9kZVtyZWFkICsgJ3gnXSB8fCAwKSAtIHRoaXMueCkgKiBzaW4KLSAgICAgICAgICAgICAgICApIC8gdGhpcy5yYXRpbyArIHlPZmZzZXQ7Ci0gICAgICAgICAgICBub2RlW3dyaXRlICsgJ3NpemUnXSA9Ci0gICAgICAgICAgICAgICAgKG5vZGVbcmVhZCArICdzaXplJ10gfHwgMCkgLwotICAgICAgICAgICAgICAgIG5vZGVSYXRpbzsKLSAgICAgICAgfQotCi0gICAgICAgIGZvciAoaSA9IDAsIGwgPSBlZGdlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKLSAgICAgICAgICAgIGVkZ2VzW2ldW3dyaXRlICsgJ3NpemUnXSA9Ci0gICAgICAgICAgICAgICAgKGVkZ2VzW2ldW3JlYWQgKyAnc2l6ZSddIHx8IDApIC8KLSAgICAgICAgICAgICAgICBlZGdlUmF0aW87Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBmdW5jdGlvbiBjb252ZXJ0cyB0aGUgY29vcmRpbmF0ZXMgb2YgYSBwb2ludCBmcm9tIHRoZSBmcmFtZSBvZiB0aGUKLSAgICAgKiBjYW1lcmEgdG8gdGhlIGZyYW1lIG9mIHRoZSBncmFwaC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge251bWJlcn0geCBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBwb2ludCBpbiB0aGUgZnJhbWUgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgIGNhbWVyYS4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHkgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQgaW4gdGhlIGZyYW1lIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICBjYW1lcmEuCi0gICAgICogQHJldHVybiB7b2JqZWN0fSAgIFRoZSBwb2ludCBjb29yZGluYXRlcyBpbiB0aGUgZnJhbWUgb2YgdGhlIGdyYXBoLgotICAgICAqLwotICAgIHNpZ21hLmNsYXNzZXMuY2FtZXJhLnByb3RvdHlwZS5ncmFwaFBvc2l0aW9uID0gZnVuY3Rpb24gKHgsIHksIHZlY3RvcikgewotICAgICAgICB2YXIgWCA9IDAsCi0gICAgICAgICAgICBZID0gMCwKLSAgICAgICAgICAgIGNvcyA9IE1hdGguY29zKHRoaXMuYW5nbGUpLAotICAgICAgICAgICAgc2luID0gTWF0aC5zaW4odGhpcy5hbmdsZSk7Ci0KLSAgICAgICAgLy8gUmV2ZXJ0IHRoZSBvcmlnaW4gZGlmZmVyZW50aWFsIHZlY3RvcjoKLSAgICAgICAgaWYgKCF2ZWN0b3IpIHsKLSAgICAgICAgICAgIFggPSAtKHRoaXMueCAqIGNvcyArIHRoaXMueSAqIHNpbikgLyB0aGlzLnJhdGlvOwotICAgICAgICAgICAgWSA9IC0odGhpcy55ICogY29zIC0gdGhpcy54ICogc2luKSAvIHRoaXMucmF0aW87Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gewotICAgICAgICAgICAgeDogKHggKiBjb3MgKyB5ICogc2luKSAvIHRoaXMucmF0aW8gKyBYLAotICAgICAgICAgICAgeTogKHkgKiBjb3MgLSB4ICogc2luKSAvIHRoaXMucmF0aW8gKyBZCi0gICAgICAgIH07Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgZnVuY3Rpb24gY29udmVydHMgdGhlIGNvb3JkaW5hdGVzIG9mIGEgcG9pbnQgZnJvbSB0aGUgZnJhbWUgb2YgdGhlCi0gICAgICogZ3JhcGggdG8gdGhlIGZyYW1lIG9mIHRoZSBjYW1lcmEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHggVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQgaW4gdGhlIGZyYW1lIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICBncmFwaC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHkgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQgaW4gdGhlIGZyYW1lIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICBncmFwaC4KLSAgICAgKiBAcmV0dXJuIHtvYmplY3R9ICAgVGhlIHBvaW50IGNvb3JkaW5hdGVzIGluIHRoZSBmcmFtZSBvZiB0aGUgY2FtZXJhLgotICAgICAqLwotICAgIHNpZ21hLmNsYXNzZXMuY2FtZXJhLnByb3RvdHlwZS5jYW1lcmFQb3NpdGlvbiA9IGZ1bmN0aW9uICh4LCB5LCB2ZWN0b3IpIHsKLSAgICAgICAgdmFyIFggPSAwLAotICAgICAgICAgICAgWSA9IDAsCi0gICAgICAgICAgICBjb3MgPSBNYXRoLmNvcyh0aGlzLmFuZ2xlKSwKLSAgICAgICAgICAgIHNpbiA9IE1hdGguc2luKHRoaXMuYW5nbGUpOwotCi0gICAgICAgIC8vIFJldmVydCB0aGUgb3JpZ2luIGRpZmZlcmVudGlhbCB2ZWN0b3I6Ci0gICAgICAgIGlmICghdmVjdG9yKSB7Ci0gICAgICAgICAgICBYID0gLSh0aGlzLnggKiBjb3MgKyB0aGlzLnkgKiBzaW4pIC8gdGhpcy5yYXRpbzsKLSAgICAgICAgICAgIFkgPSAtKHRoaXMueSAqIGNvcyAtIHRoaXMueCAqIHNpbikgLyB0aGlzLnJhdGlvOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgIHg6ICgoeCAtIFgpICogY29zIC0gKHkgLSBZKSAqIHNpbikgKiB0aGlzLnJhdGlvLAotICAgICAgICAgICAgeTogKCh5IC0gWSkgKiBjb3MgKyAoeCAtIFgpICogc2luKSAqIHRoaXMucmF0aW8KLSAgICAgICAgfTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4IG9mIHRoZSBjYW1lcmEuIFRoaXMgaXMKLSAgICAgKiBlc3BlY2lhbGx5IHVzZWZ1bCB0byBhcHBseSB0aGUgY2FtZXJhIHZpZXcgZGlyZWN0bHkgaW4gc2hhZGVycywgaW4gY2FzZSBvZgotICAgICAqIFdlYkdMIHJlbmRlcmluZy4KLSAgICAgKgotICAgICAqIEByZXR1cm4ge2FycmF5fSBUaGUgdHJhbnNmb3JtYXRpb24gbWF0cml4LgotICAgICAqLwotICAgIHNpZ21hLmNsYXNzZXMuY2FtZXJhLnByb3RvdHlwZS5nZXRNYXRyaXggPSBmdW5jdGlvbiAoKSB7Ci0gICAgICAgIHZhciBzY2FsZSA9IHNpZ21hLnV0aWxzLm1hdHJpY2VzLnNjYWxlKDEgLyB0aGlzLnJhdGlvKSwKLSAgICAgICAgICAgIHJvdGF0aW9uID0gc2lnbWEudXRpbHMubWF0cmljZXMucm90YXRpb24odGhpcy5hbmdsZSksCi0gICAgICAgICAgICB0cmFuc2xhdGlvbiA9IHNpZ21hLnV0aWxzLm1hdHJpY2VzLnRyYW5zbGF0aW9uKC10aGlzLngsIC10aGlzLnkpLAotICAgICAgICAgICAgbWF0cml4ID0gc2lnbWEudXRpbHMubWF0cmljZXMubXVsdGlwbHkoCi0gICAgICAgICAgICAgICAgdHJhbnNsYXRpb24sCi0gICAgICAgICAgICAgICAgc2lnbWEudXRpbHMubWF0cmljZXMubXVsdGlwbHkoCi0gICAgICAgICAgICAgICAgICAgIHJvdGF0aW9uLAotICAgICAgICAgICAgICAgICAgICBzY2FsZQotICAgICAgICAgICAgICAgICkKLSAgICAgICAgICAgICk7Ci0KLSAgICAgICAgcmV0dXJuIG1hdHJpeDsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGFraW5nIGEgd2lkdGggYW5kIGEgaGVpZ2h0IGFzIHBhcmFtZXRlcnMsIHRoaXMgbWV0aG9kIHJldHVybnMgdGhlCi0gICAgICogY29vcmRpbmF0ZXMgb2YgdGhlIHJlY3RhbmdsZSByZXByZXNlbnRpbmcgdGhlIGNhbWVyYSBvbiBzY3JlZW4sIGluIHRoZQotICAgICAqIGdyYXBoJ3MgcmVmZXJlbnRpZWwuCi0gICAgICoKLSAgICAgKiBUbyBrZWVwIGRpc3BsYXlpbmcgbGFiZWxzIG9mIG5vZGVzIGdvaW5nIG91dCBvZiB0aGUgc2NyZWVuLCB0aGUgbWV0aG9kCi0gICAgICoga2VlcHMgYSBtYXJnaW4gYXJvdW5kIHRoZSBzY3JlZW4gaW4gdGhlIHJldHVybmVkIHJlY3RhbmdsZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge251bWJlcn0gd2lkdGggIFRoZSB3aWR0aCBvZiB0aGUgc2NyZWVuLgotICAgICAqIEBwYXJhbSAge251bWJlcn0gaGVpZ2h0IFRoZSBoZWlnaHQgb2YgdGhlIHNjcmVlbi4KLSAgICAgKiBAcmV0dXJuIHtvYmplY3R9ICAgICAgICBUaGUgcmVjdGFuZ2xlIGFzIHgxLCB5MSwgeDIgYW5kIHkyLCByZXByZXNlbnRpbmcKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB0d28gb3Bwb3NpdGUgcG9pbnRzLgotICAgICAqLwotICAgIHNpZ21hLmNsYXNzZXMuY2FtZXJhLnByb3RvdHlwZS5nZXRSZWN0YW5nbGUgPSBmdW5jdGlvbiAod2lkdGgsIGhlaWdodCkgewotICAgICAgICB2YXIgd2lkdGhWZWN0ID0gdGhpcy5jYW1lcmFQb3NpdGlvbih3aWR0aCwgMCwgdHJ1ZSksCi0gICAgICAgICAgICBoZWlnaHRWZWN0ID0gdGhpcy5jYW1lcmFQb3NpdGlvbigwLCBoZWlnaHQsIHRydWUpLAotICAgICAgICAgICAgY2VudGVyVmVjdCA9IHRoaXMuY2FtZXJhUG9zaXRpb24od2lkdGggLyAyLCBoZWlnaHQgLyAyLCB0cnVlKSwKLSAgICAgICAgICAgIG1hcmdpblggPSB0aGlzLmNhbWVyYVBvc2l0aW9uKHdpZHRoIC8gNCwgMCwgdHJ1ZSkueCwKLSAgICAgICAgICAgIG1hcmdpblkgPSB0aGlzLmNhbWVyYVBvc2l0aW9uKDAsIGhlaWdodCAvIDQsIHRydWUpLnk7Ci0KLSAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgIHgxOiB0aGlzLnggLSBjZW50ZXJWZWN0LnggLSBtYXJnaW5YLAotICAgICAgICAgICAgeTE6IHRoaXMueSAtIGNlbnRlclZlY3QueSAtIG1hcmdpblksCi0gICAgICAgICAgICB4MjogdGhpcy54IC0gY2VudGVyVmVjdC54ICsgbWFyZ2luWCArIHdpZHRoVmVjdC54LAotICAgICAgICAgICAgeTI6IHRoaXMueSAtIGNlbnRlclZlY3QueSAtIG1hcmdpblkgKyB3aWR0aFZlY3QueSwKLSAgICAgICAgICAgIGhlaWdodDogTWF0aC5zcXJ0KAotICAgICAgICAgICAgICAgIE1hdGgucG93KGhlaWdodFZlY3QueCwgMikgKwotICAgICAgICAgICAgICAgIE1hdGgucG93KGhlaWdodFZlY3QueSArIDIgKiBtYXJnaW5ZLCAyKQotICAgICAgICAgICAgKQotICAgICAgICB9OwotICAgIH07Ci19KS5jYWxsKHRoaXMpOwotCi07KGZ1bmN0aW9uICh1bmRlZmluZWQpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICAvKioKLSAgICAgKiBTaWdtYSBRdWFkdHJlZSBNb2R1bGUKLSAgICAgKiA9PT09PT09PT09PT09PT09PT09PT0KLSAgICAgKgotICAgICAqIEF1dGhvcjogR3VpbGxhdW1lIFBsaXF1ZSAoWW9tZ3VpdGhlcmVhbCkKLSAgICAgKiBWZXJzaW9uOiAwLjIKLSAgICAgKi8KLQotCi0gICAgLyoqCi0gICAgICogUXVhZCBHZW9tZXRyaWMgT3BlcmF0aW9ucwotICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgKgotICAgICAqIEEgdXNlZnVsIGJhdGNoIG9mIGdlb21ldHJpYyBvcGVyYXRpb25zIHVzZWQgYnkgdGhlIHF1YWR0cmVlLgotICAgICAqLwotCi0gICAgdmFyIF9nZW9tID0gewotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUcmFuc2Zvcm1zIGEgZ3JhcGggbm9kZSB3aXRoIHgsIHkgYW5kIHNpemUgaW50byBhbgotICAgICAgICAgKiBheGlzLWFsaWduZWQgc3F1YXJlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9IEEgZ3JhcGggbm9kZSB3aXRoIGF0IGxlYXN0IGEgcG9pbnQgKHgsIHkpIGFuZCBhIHNpemUuCi0gICAgICAgICAqIEByZXR1cm4ge29iamVjdH0gQSBzcXVhcmU6IHR3byBwb2ludHMgKHgxLCB5MSksICh4MiwgeTIpIGFuZCBoZWlnaHQuCi0gICAgICAgICAqLwotICAgICAgICBwb2ludFRvU3F1YXJlOiBmdW5jdGlvbiAobikgewotICAgICAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgICAgICB4MTogbi54IC0gbi5zaXplLAotICAgICAgICAgICAgICAgIHkxOiBuLnkgLSBuLnNpemUsCi0gICAgICAgICAgICAgICAgeDI6IG4ueCArIG4uc2l6ZSwKLSAgICAgICAgICAgICAgICB5Mjogbi55IC0gbi5zaXplLAotICAgICAgICAgICAgICAgIGhlaWdodDogbi5zaXplICogMgotICAgICAgICAgICAgfTsKLSAgICAgICAgfSwKLQotICAgICAgICAvKioKLSAgICAgICAgICogQ2hlY2tzIHdoZXRoZXIgYSByZWN0YW5nbGUgaXMgYXhpcy1hbGlnbmVkLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICBBIHJlY3RhbmdsZSBkZWZpbmVkIGJ5IHR3byBwb2ludHMKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgKHgxLCB5MSkgYW5kICh4MiwgeTIpLgotICAgICAgICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSByZWN0YW5nbGUgaXMgYXhpcy1hbGlnbmVkLgotICAgICAgICAgKi8KLSAgICAgICAgaXNBeGlzQWxpZ25lZDogZnVuY3Rpb24gKHIpIHsKLSAgICAgICAgICAgIHJldHVybiByLngxID09PSByLngyIHx8IHIueTEgPT09IHIueTI7Ci0gICAgICAgIH0sCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbXB1dGUgdG9wIHBvaW50cyBvZiBhbiBheGlzLWFsaWduZWQgcmVjdGFuZ2xlLiBUaGlzIGlzIHVzZWZ1bCBpbgotICAgICAgICAgKiBjYXNlcyB3aGVuIHRoZSByZWN0YW5nbGUgaGFzIGJlZW4gcm90YXRlZCAobGVmdCwgcmlnaHQgb3IgYm90dG9tIHVwKSBhbmQKLSAgICAgICAgICogbGF0ZXIgb3BlcmF0aW9ucyBuZWVkIHRvIGtub3cgdGhlIHRvcCBwb2ludHMuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSAge29iamVjdH0gQW4gYXhpcy1hbGlnbmVkIHJlY3RhbmdsZSBkZWZpbmVkIGJ5IHR3byBwb2ludHMKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAoeDEsIHkxKSwgKHgyLCB5MikgYW5kIGhlaWdodC4KLSAgICAgICAgICogQHJldHVybiB7b2JqZWN0fSBBIHJlY3RhbmdsZTogdHdvIHBvaW50cyAoeDEsIHkxKSwgKHgyLCB5MikgYW5kIGhlaWdodC4KLSAgICAgICAgICovCi0gICAgICAgIGF4aXNBbGlnbmVkVG9wUG9pbnRzOiBmdW5jdGlvbiAocikgewotCi0gICAgICAgICAgICAvLyBCYXNpYwotICAgICAgICAgICAgaWYgKHIueTEgPT09IHIueTIgJiYgci54MSA8IHIueDIpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHI7Ci0KLSAgICAgICAgICAgIC8vIFJvdGF0ZWQgdG8gcmlnaHQKLSAgICAgICAgICAgIGlmIChyLngxID09PSByLngyICYmIHIueTIgPiByLnkxKQotICAgICAgICAgICAgICAgIHJldHVybiB7Ci0gICAgICAgICAgICAgICAgICAgIHgxOiByLngxIC0gci5oZWlnaHQsIHkxOiByLnkxLAotICAgICAgICAgICAgICAgICAgICB4Mjogci54MSwgeTI6IHIueTEsCi0gICAgICAgICAgICAgICAgICAgIGhlaWdodDogci5oZWlnaHQKLSAgICAgICAgICAgICAgICB9OwotCi0gICAgICAgICAgICAvLyBSb3RhdGVkIHRvIGxlZnQKLSAgICAgICAgICAgIGlmIChyLngxID09PSByLngyICYmIHIueTIgPCByLnkxKQotICAgICAgICAgICAgICAgIHJldHVybiB7Ci0gICAgICAgICAgICAgICAgICAgIHgxOiByLngxLCB5MTogci55MiwKLSAgICAgICAgICAgICAgICAgICAgeDI6IHIueDIgKyByLmhlaWdodCwgeTI6IHIueTIsCi0gICAgICAgICAgICAgICAgICAgIGhlaWdodDogci5oZWlnaHQKLSAgICAgICAgICAgICAgICB9OwotCi0gICAgICAgICAgICAvLyBCb3R0b20ncyB1cAotICAgICAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgICAgICB4MTogci54MiwgeTE6IHIueTEgLSByLmhlaWdodCwKLSAgICAgICAgICAgICAgICB4Mjogci54MSwgeTI6IHIueTEgLSByLmhlaWdodCwKLSAgICAgICAgICAgICAgICBoZWlnaHQ6IHIuaGVpZ2h0Ci0gICAgICAgICAgICB9OwotICAgICAgICB9LAotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHZXQgY29vcmRpbmF0ZXMgb2YgYSByZWN0YW5nbGUncyBsb3dlciBsZWZ0IGNvcm5lciBmcm9tIGl0cyB0b3AgcG9pbnRzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9IEEgcmVjdGFuZ2xlIGRlZmluZWQgYnkgdHdvIHBvaW50cyAoeDEsIHkxKSBhbmQgKHgyLCB5MikuCi0gICAgICAgICAqIEByZXR1cm4ge29iamVjdH0gQ29vcmRpbmF0ZXMgb2YgdGhlIGNvcm5lciAoeCwgeSkuCi0gICAgICAgICAqLwotICAgICAgICBsb3dlckxlZnRDb29yOiBmdW5jdGlvbiAocikgewotICAgICAgICAgICAgdmFyIHdpZHRoID0gKAotICAgICAgICAgICAgICAgIE1hdGguc3FydCgKLSAgICAgICAgICAgICAgICAgICAgTWF0aC5wb3coci54MiAtIHIueDEsIDIpICsKLSAgICAgICAgICAgICAgICAgICAgTWF0aC5wb3coci55MiAtIHIueTEsIDIpCi0gICAgICAgICAgICAgICAgKQotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgICAgICB4OiByLngxIC0gKHIueTIgLSByLnkxKSAqIHIuaGVpZ2h0IC8gd2lkdGgsCi0gICAgICAgICAgICAgICAgeTogci55MSArIChyLngyIC0gci54MSkgKiByLmhlaWdodCAvIHdpZHRoCi0gICAgICAgICAgICB9OwotICAgICAgICB9LAotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHZXQgY29vcmRpbmF0ZXMgb2YgYSByZWN0YW5nbGUncyBsb3dlciByaWdodCBjb3JuZXIgZnJvbSBpdHMgdG9wIHBvaW50cwotICAgICAgICAgKiBhbmQgaXRzIGxvd2VyIGxlZnQgY29ybmVyLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9IEEgcmVjdGFuZ2xlIGRlZmluZWQgYnkgdHdvIHBvaW50cyAoeDEsIHkxKSBhbmQgKHgyLCB5MikuCi0gICAgICAgICAqIEBwYXJhbSAge29iamVjdH0gQSBjb3JuZXIncyBjb29yZGluYXRlcyAoeCwgeSkuCi0gICAgICAgICAqIEByZXR1cm4ge29iamVjdH0gQ29vcmRpbmF0ZXMgb2YgdGhlIGNvcm5lciAoeCwgeSkuCi0gICAgICAgICAqLwotICAgICAgICBsb3dlclJpZ2h0Q29vcjogZnVuY3Rpb24gKHIsIGxsYykgewotICAgICAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgICAgICB4OiBsbGMueCAtIHIueDEgKyByLngyLAotICAgICAgICAgICAgICAgIHk6IGxsYy55IC0gci55MSArIHIueTIKLSAgICAgICAgICAgIH07Ci0gICAgICAgIH0sCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdldCB0aGUgY29vcmRpbmF0ZXMgb2YgYWxsIHRoZSBjb3JuZXJzIG9mIGEgcmVjdGFuZ2xlIGZyb20gaXRzIHRvcCBwb2ludC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtICB7b2JqZWN0fSBBIHJlY3RhbmdsZSBkZWZpbmVkIGJ5IHR3byBwb2ludHMgKHgxLCB5MSkgYW5kICh4MiwgeTIpLgotICAgICAgICAgKiBAcmV0dXJuIHthcnJheX0gIEFuIGFycmF5IG9mIHRoZSBmb3VyIGNvcm5lcnMnIGNvb3JkaW5hdGVzICh4LCB5KS4KLSAgICAgICAgICovCi0gICAgICAgIHJlY3RhbmdsZUNvcm5lcnM6IGZ1bmN0aW9uIChyKSB7Ci0gICAgICAgICAgICB2YXIgbGxjID0gdGhpcy5sb3dlckxlZnRDb29yKHIpLAotICAgICAgICAgICAgICAgIGxyYyA9IHRoaXMubG93ZXJSaWdodENvb3IociwgbGxjKTsKLQotICAgICAgICAgICAgcmV0dXJuIFsKLSAgICAgICAgICAgICAgICB7eDogci54MSwgeTogci55MX0sCi0gICAgICAgICAgICAgICAge3g6IHIueDIsIHk6IHIueTJ9LAotICAgICAgICAgICAgICAgIHt4OiBsbGMueCwgeTogbGxjLnl9LAotICAgICAgICAgICAgICAgIHt4OiBscmMueCwgeTogbHJjLnl9Ci0gICAgICAgICAgICBdOwotICAgICAgICB9LAotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTcGxpdCBhIHNxdWFyZSBkZWZpbmVkIGJ5IGl0cyBib3VuZGFyaWVzIGludG8gZm91ci4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtICB7b2JqZWN0fSBCb3VuZGFyaWVzIG9mIHRoZSBzcXVhcmUgKHgsIHksIHdpZHRoLCBoZWlnaHQpLgotICAgICAgICAgKiBAcmV0dXJuIHthcnJheX0gIEFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIGZvdXIgbmV3IHNxdWFyZXMsIHRoZW1zZWx2ZXMKLSAgICAgICAgICogICAgICAgICAgICAgICAgICBkZWZpbmVkIGJ5IGFuIGFycmF5IG9mIHRoZWlyIGZvdXIgY29ybmVycyAoeCwgeSkuCi0gICAgICAgICAqLwotICAgICAgICBzcGxpdFNxdWFyZTogZnVuY3Rpb24gKGIpIHsKLSAgICAgICAgICAgIHJldHVybiBbCi0gICAgICAgICAgICAgICAgWwotICAgICAgICAgICAgICAgICAgICB7eDogYi54LCB5OiBiLnl9LAotICAgICAgICAgICAgICAgICAgICB7eDogYi54ICsgYi53aWR0aCAvIDIsIHk6IGIueX0sCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLngsIHk6IGIueSArIGIuaGVpZ2h0IC8gMn0sCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLnggKyBiLndpZHRoIC8gMiwgeTogYi55ICsgYi5oZWlnaHQgLyAyfQotICAgICAgICAgICAgICAgIF0sCi0gICAgICAgICAgICAgICAgWwotICAgICAgICAgICAgICAgICAgICB7eDogYi54ICsgYi53aWR0aCAvIDIsIHk6IGIueX0sCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLnggKyBiLndpZHRoLCB5OiBiLnl9LAotICAgICAgICAgICAgICAgICAgICB7eDogYi54ICsgYi53aWR0aCAvIDIsIHk6IGIueSArIGIuaGVpZ2h0IC8gMn0sCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLnggKyBiLndpZHRoLCB5OiBiLnkgKyBiLmhlaWdodCAvIDJ9Ci0gICAgICAgICAgICAgICAgXSwKLSAgICAgICAgICAgICAgICBbCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLngsIHk6IGIueSArIGIuaGVpZ2h0IC8gMn0sCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLnggKyBiLndpZHRoIC8gMiwgeTogYi55ICsgYi5oZWlnaHQgLyAyfSwKLSAgICAgICAgICAgICAgICAgICAge3g6IGIueCwgeTogYi55ICsgYi5oZWlnaHR9LAotICAgICAgICAgICAgICAgICAgICB7eDogYi54ICsgYi53aWR0aCAvIDIsIHk6IGIueSArIGIuaGVpZ2h0fQotICAgICAgICAgICAgICAgIF0sCi0gICAgICAgICAgICAgICAgWwotICAgICAgICAgICAgICAgICAgICB7eDogYi54ICsgYi53aWR0aCAvIDIsIHk6IGIueSArIGIuaGVpZ2h0IC8gMn0sCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLnggKyBiLndpZHRoLCB5OiBiLnkgKyBiLmhlaWdodCAvIDJ9LAotICAgICAgICAgICAgICAgICAgICB7eDogYi54ICsgYi53aWR0aCAvIDIsIHk6IGIueSArIGIuaGVpZ2h0fSwKLSAgICAgICAgICAgICAgICAgICAge3g6IGIueCArIGIud2lkdGgsIHk6IGIueSArIGIuaGVpZ2h0fQotICAgICAgICAgICAgICAgIF0KLSAgICAgICAgICAgIF07Ci0gICAgICAgIH0sCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbXB1dGUgdGhlIGZvdXIgYXhpcyBiZXR3ZWVuIGNvcm5lcnMgb2YgcmVjdGFuZ2xlIEEgYW5kIGNvcm5lcnMgb2YKLSAgICAgICAgICogcmVjdGFuZ2xlIEIuIFRoaXMgaXMgbmVlZGVkIGxhdGVyIHRvIGNoZWNrIGFuIGV2ZW50dWFsIGNvbGxpc2lvbi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtICB7YXJyYXl9IEFuIGFycmF5IG9mIHJlY3RhbmdsZSBBJ3MgZm91ciBjb3JuZXJzICh4LCB5KS4KLSAgICAgICAgICogQHBhcmFtICB7YXJyYXl9IEFuIGFycmF5IG9mIHJlY3RhbmdsZSBCJ3MgZm91ciBjb3JuZXJzICh4LCB5KS4KLSAgICAgICAgICogQHJldHVybiB7YXJyYXl9IEFuIGFycmF5IG9mIGZvdXIgYXhpcyBkZWZpbmVkIGJ5IHRoZWlyIGNvb3JkaW5hdGVzICh4LHkpLgotICAgICAgICAgKi8KLSAgICAgICAgYXhpczogZnVuY3Rpb24gKGMxLCBjMikgewotICAgICAgICAgICAgcmV0dXJuIFsKLSAgICAgICAgICAgICAgICB7eDogYzFbMV0ueCAtIGMxWzBdLngsIHk6IGMxWzFdLnkgLSBjMVswXS55fSwKLSAgICAgICAgICAgICAgICB7eDogYzFbMV0ueCAtIGMxWzNdLngsIHk6IGMxWzFdLnkgLSBjMVszXS55fSwKLSAgICAgICAgICAgICAgICB7eDogYzJbMF0ueCAtIGMyWzJdLngsIHk6IGMyWzBdLnkgLSBjMlsyXS55fSwKLSAgICAgICAgICAgICAgICB7eDogYzJbMF0ueCAtIGMyWzFdLngsIHk6IGMyWzBdLnkgLSBjMlsxXS55fQotICAgICAgICAgICAgXTsKLSAgICAgICAgfSwKLQotICAgICAgICAvKioKLSAgICAgICAgICogUHJvamVjdCBhIHJlY3RhbmdsZSdzIGNvcm5lciBvbiBhbiBheGlzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9IENvb3JkaW5hdGVzIG9mIGEgY29ybmVyICh4LCB5KS4KLSAgICAgICAgICogQHBhcmFtICB7b2JqZWN0fSBDb29yZGluYXRlcyBvZiBhbiBheGlzICh4LCB5KS4KLSAgICAgICAgICogQHJldHVybiB7b2JqZWN0fSBUaGUgcHJvamVjdGlvbiBkZWZpbmVkIGJ5IGNvb3JkaW5hdGVzICh4LCB5KS4KLSAgICAgICAgICovCi0gICAgICAgIHByb2plY3Rpb246IGZ1bmN0aW9uIChjLCBhKSB7Ci0gICAgICAgICAgICB2YXIgbCA9ICgKLSAgICAgICAgICAgICAgICAoYy54ICogYS54ICsgYy55ICogYS55KSAvCi0gICAgICAgICAgICAgICAgKE1hdGgucG93KGEueCwgMikgKyBNYXRoLnBvdyhhLnksIDIpKQotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgICAgICB4OiBsICogYS54LAotICAgICAgICAgICAgICAgIHk6IGwgKiBhLnkKLSAgICAgICAgICAgIH07Ci0gICAgICAgIH0sCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENoZWNrIHdoZXRoZXIgdHdvIHJlY3RhbmdsZXMgY29sbGlkZSBvbiBvbmUgcGFydGljdWxhciBheGlzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgQW4gYXhpcycgY29vcmRpbmF0ZXMgKHgsIHkpLgotICAgICAgICAgKiBAcGFyYW0gIHthcnJheX0gICAgUmVjdGFuZ2xlIEEncyBjb3JuZXJzLgotICAgICAgICAgKiBAcGFyYW0gIHthcnJheX0gICAgUmVjdGFuZ2xlIEIncyBjb3JuZXJzLgotICAgICAgICAgKiBAcmV0dXJuIHtib29sZWFufSAgVHJ1ZSBpZiB0aGUgcmVjdGFuZ2xlcyBjb2xsaWRlIG9uIHRoZSBheGlzLgotICAgICAgICAgKi8KLSAgICAgICAgYXhpc0NvbGxpc2lvbjogZnVuY3Rpb24gKGEsIGMxLCBjMikgewotICAgICAgICAgICAgdmFyIHNjMSA9IFtdLAotICAgICAgICAgICAgICAgIHNjMiA9IFtdOwotCi0gICAgICAgICAgICBmb3IgKHZhciBjaSA9IDA7IGNpIDwgNDsgY2krKykgewotICAgICAgICAgICAgICAgIHZhciBwMSA9IHRoaXMucHJvamVjdGlvbihjMVtjaV0sIGEpLAotICAgICAgICAgICAgICAgICAgICBwMiA9IHRoaXMucHJvamVjdGlvbihjMltjaV0sIGEpOwotCi0gICAgICAgICAgICAgICAgc2MxLnB1c2gocDEueCAqIGEueCArIHAxLnkgKiBhLnkpOwotICAgICAgICAgICAgICAgIHNjMi5wdXNoKHAyLnggKiBhLnggKyBwMi55ICogYS55KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgdmFyIG1heGMxID0gTWF0aC5tYXguYXBwbHkoTWF0aCwgc2MxKSwKLSAgICAgICAgICAgICAgICBtYXhjMiA9IE1hdGgubWF4LmFwcGx5KE1hdGgsIHNjMiksCi0gICAgICAgICAgICAgICAgbWluYzEgPSBNYXRoLm1pbi5hcHBseShNYXRoLCBzYzEpLAotICAgICAgICAgICAgICAgIG1pbmMyID0gTWF0aC5taW4uYXBwbHkoTWF0aCwgc2MyKTsKLQotICAgICAgICAgICAgcmV0dXJuIChtaW5jMiA8PSBtYXhjMSAmJiBtYXhjMiA+PSBtaW5jMSk7Ci0gICAgICAgIH0sCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENoZWNrIHdoZXRoZXIgdHdvIHJlY3RhbmdsZXMgY29sbGlkZSBvbiBlYWNoIG9uZSBvZiB0aGVpciBmb3VyIGF4aXMuIElmCi0gICAgICAgICAqIGFsbCBheGlzIGNvbGxpZGUsIHRoZW4gdGhlIHR3byByZWN0YW5nbGVzIGRvIGNvbGxpZGUgb24gdGhlIHBsYW5lLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHthcnJheX0gICAgUmVjdGFuZ2xlIEEncyBjb3JuZXJzLgotICAgICAgICAgKiBAcGFyYW0gIHthcnJheX0gICAgUmVjdGFuZ2xlIEIncyBjb3JuZXJzLgotICAgICAgICAgKiBAcmV0dXJuIHtib29sZWFufSAgVHJ1ZSBpZiB0aGUgcmVjdGFuZ2xlcyBjb2xsaWRlLgotICAgICAgICAgKi8KLSAgICAgICAgY29sbGlzaW9uOiBmdW5jdGlvbiAoYzEsIGMyKSB7Ci0gICAgICAgICAgICB2YXIgYXhpcyA9IHRoaXMuYXhpcyhjMSwgYzIpLAotICAgICAgICAgICAgICAgIGNvbCA9IHRydWU7Ci0KLSAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKQotICAgICAgICAgICAgICAgIGNvbCA9IGNvbCAmJiB0aGlzLmF4aXNDb2xsaXNpb24oYXhpc1tpXSwgYzEsIGMyKTsKLQotICAgICAgICAgICAgcmV0dXJuIGNvbDsKLSAgICAgICAgfQotICAgIH07Ci0KLQotICAgIC8qKgotICAgICAqIFF1YWQgRnVuY3Rpb25zCi0gICAgICogLS0tLS0tLS0tLS0tCi0gICAgICoKLSAgICAgKiBUaGUgUXVhZHRyZWUgZnVuY3Rpb25zIHRoZW1zZWx2ZXMuCi0gICAgICogRm9yIGVhY2ggb2YgdGhvc2UgZnVuY3Rpb25zLCB3ZSBjb25zaWRlciB0aGF0IGluIGEgc3BsaXR0ZWQgcXVhZCwgdGhlCi0gICAgICogaW5kZXggb2YgZWFjaCBub2RlIGlzIHRoZSBmb2xsb3dpbmc6Ci0gICAgICogMDogdG9wIGxlZnQKLSAgICAgKiAxOiB0b3AgcmlnaHQKLSAgICAgKiAyOiBib3R0b20gbGVmdAotICAgICAqIDM6IGJvdHRvbSByaWdodAotICAgICAqCi0gICAgICogTW9yZW92ZXIsIHRoZSBoZXJlYWZ0ZXIgcXVhZCdzIHBoaWxvc29waHkgaXMgdG8gY29uc2lkZXIgdGhhdCBpZiBhbiBlbGVtZW50Ci0gICAgICogY29sbGlkZXMgd2l0aCBtb3JlIHRoYW4gb25lIG5vZGVzLCB0aGlzIGVsZW1lbnQgYmVsb25ncyB0byBlYWNoIG9mIHRoZQotICAgICAqIG5vZGVzIGl0IGNvbGxpZGVzIHdpdGggd2hlcmUgb3RoZXIgd291bGQgbGV0IGl0IGxpZSBvbiBhIGhpZ2hlciBub2RlLgotICAgICAqLwotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBpbmRleCBvZiB0aGUgbm9kZSBjb250YWluaW5nIHRoZSBwb2ludCBpbiB0aGUgcXVhZAotICAgICAqCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgcG9pbnQgICAgICBBIHBvaW50IGRlZmluZWQgYnkgY29vcmRpbmF0ZXMgKHgsIHkpLgotICAgICAqIEBwYXJhbSAge29iamVjdH0gIHF1YWRCb3VuZHMgQm91bmRhcmllcyBvZiB0aGUgcXVhZCAoeCwgeSwgd2lkdGgsIGhlaWd0aCkuCi0gICAgICogQHJldHVybiB7aW50ZWdlcn0gICAgICAgICAgICBUaGUgaW5kZXggb2YgdGhlIG5vZGUgY29udGFpbmluZyB0aGUgcG9pbnQuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX3F1YWRJbmRleChwb2ludCwgcXVhZEJvdW5kcykgewotICAgICAgICB2YXIgeG1wID0gcXVhZEJvdW5kcy54ICsgcXVhZEJvdW5kcy53aWR0aCAvIDIsCi0gICAgICAgICAgICB5bXAgPSBxdWFkQm91bmRzLnkgKyBxdWFkQm91bmRzLmhlaWdodCAvIDIsCi0gICAgICAgICAgICB0b3AgPSAocG9pbnQueSA8IHltcCksCi0gICAgICAgICAgICBsZWZ0ID0gKHBvaW50LnggPCB4bXApOwotCi0gICAgICAgIGlmICh0b3ApIHsKLSAgICAgICAgICAgIGlmIChsZWZ0KQotICAgICAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKGxlZnQpCi0gICAgICAgICAgICAgICAgcmV0dXJuIDI7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgcmV0dXJuIDM7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgYSBsaXN0IG9mIGluZGV4ZXMgb2Ygbm9kZXMgY29udGFpbmluZyBhbiBheGlzLWFsaWduZWQgcmVjdGFuZ2xlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICByZWN0YW5nbGUgICBBIHJlY3RhbmdsZSBkZWZpbmVkIGJ5IHR3byBwb2ludHMgKHgxLCB5MSksCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHgyLCB5MikgYW5kIGhlaWdodC4KLSAgICAgKiBAcGFyYW0gIHthcnJheX0gICBxdWFkQ29ybmVycyBBbiBhcnJheSBvZiB0aGUgcXVhZCBub2RlcycgY29ybmVycy4KLSAgICAgKiBAcmV0dXJuIHthcnJheX0gICAgICAgICAgICAgICBBbiBhcnJheSBvZiBpbmRleGVzIGNvbnRhaW5pbmcgb25lIHRvCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91ciBpbnRlZ2Vycy4KLSAgICAgKi8KLSAgICBmdW5jdGlvbiBfcXVhZEluZGV4ZXMocmVjdGFuZ2xlLCBxdWFkQ29ybmVycykgewotICAgICAgICB2YXIgaW5kZXhlcyA9IFtdOwotCi0gICAgICAgIC8vIEl0ZXJhdGluZyB0aHJvdWdoIHF1YWRzCi0gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKQotICAgICAgICAgICAgaWYgKChyZWN0YW5nbGUueDIgPj0gcXVhZENvcm5lcnNbaV1bMF0ueCkgJiYKLSAgICAgICAgICAgICAgICAocmVjdGFuZ2xlLngxIDw9IHF1YWRDb3JuZXJzW2ldWzFdLngpICYmCi0gICAgICAgICAgICAgICAgKHJlY3RhbmdsZS55MSArIHJlY3RhbmdsZS5oZWlnaHQgPj0gcXVhZENvcm5lcnNbaV1bMF0ueSkgJiYKLSAgICAgICAgICAgICAgICAocmVjdGFuZ2xlLnkxIDw9IHF1YWRDb3JuZXJzW2ldWzJdLnkpKQotICAgICAgICAgICAgICAgIGluZGV4ZXMucHVzaChpKTsKLQotICAgICAgICByZXR1cm4gaW5kZXhlczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgYSBsaXN0IG9mIGluZGV4ZXMgb2Ygbm9kZXMgY29udGFpbmluZyBhIG5vbi1heGlzLWFsaWduZWQgcmVjdGFuZ2xlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHthcnJheX0gIGNvcm5lcnMgICAgICBBbiBhcnJheSBjb250YWluaW5nIGVhY2ggY29ybmVyIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY3RhbmdsZSBkZWZpbmVkIGJ5IGl0cyBjb29yZGluYXRlcyAoeCwgeSkuCi0gICAgICogQHBhcmFtICB7YXJyYXl9ICBxdWFkQ29ybmVycyAgQW4gYXJyYXkgb2YgdGhlIHF1YWQgbm9kZXMnIGNvcm5lcnMuCi0gICAgICogQHJldHVybiB7YXJyYXl9ICAgICAgICAgICAgICAgQW4gYXJyYXkgb2YgaW5kZXhlcyBjb250YWluaW5nIG9uZSB0bwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdXIgaW50ZWdlcnMuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX3F1YWRDb2xsaXNpb24oY29ybmVycywgcXVhZENvcm5lcnMpIHsKLSAgICAgICAgdmFyIGluZGV4ZXMgPSBbXTsKLQotICAgICAgICAvLyBJdGVyYXRpbmcgdGhyb3VnaCBxdWFkcwotICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykKLSAgICAgICAgICAgIGlmIChfZ2VvbS5jb2xsaXNpb24oY29ybmVycywgcXVhZENvcm5lcnNbaV0pKQotICAgICAgICAgICAgICAgIGluZGV4ZXMucHVzaChpKTsKLQotICAgICAgICByZXR1cm4gaW5kZXhlczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTdWJkaXZpZGUgYSBxdWFkIGJ5IGNyZWF0aW5nIGEgbm9kZSBhdCBhIHByZWNpc2UgaW5kZXguIFRoZSBmdW5jdGlvbiBkb2VzCi0gICAgICogbm90IGdlbmVyYXRlIGFsbCBmb3VyIG5vZGVzIG5vdCB0byBwb3RlbnRpYWxseSBjcmVhdGUgdW51c2VkIG5vZGVzLgotICAgICAqCi0gICAgICogQHBhcmFtICB7aW50ZWdlcn0gIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgbm9kZSB0byBjcmVhdGUuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgIHF1YWQgIFRoZSBxdWFkIG9iamVjdCB0byBzdWJkaXZpZGUuCi0gICAgICogQHJldHVybiB7b2JqZWN0fSAgICAgICAgIEEgbmV3IHF1YWQgcmVwcmVzZW50aW5nIHRoZSBub2RlIGNyZWF0ZWQuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX3F1YWRTdWJkaXZpZGUoaW5kZXgsIHF1YWQpIHsKLSAgICAgICAgdmFyIG5leHQgPSBxdWFkLmxldmVsICsgMSwKLSAgICAgICAgICAgIHN1YncgPSBNYXRoLnJvdW5kKHF1YWQuYm91bmRzLndpZHRoIC8gMiksCi0gICAgICAgICAgICBzdWJoID0gTWF0aC5yb3VuZChxdWFkLmJvdW5kcy5oZWlnaHQgLyAyKSwKLSAgICAgICAgICAgIHF4ID0gTWF0aC5yb3VuZChxdWFkLmJvdW5kcy54KSwKLSAgICAgICAgICAgIHF5ID0gTWF0aC5yb3VuZChxdWFkLmJvdW5kcy55KSwKLSAgICAgICAgICAgIHgsCi0gICAgICAgICAgICB5OwotCi0gICAgICAgIHN3aXRjaCAoaW5kZXgpIHsKLSAgICAgICAgICAgIGNhc2UgMDoKLSAgICAgICAgICAgICAgICB4ID0gcXg7Ci0gICAgICAgICAgICAgICAgeSA9IHF5OwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSAxOgotICAgICAgICAgICAgICAgIHggPSBxeCArIHN1Ync7Ci0gICAgICAgICAgICAgICAgeSA9IHF5OwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSAyOgotICAgICAgICAgICAgICAgIHggPSBxeDsKLSAgICAgICAgICAgICAgICB5ID0gcXkgKyBzdWJoOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSAzOgotICAgICAgICAgICAgICAgIHggPSBxeCArIHN1Ync7Ci0gICAgICAgICAgICAgICAgeSA9IHF5ICsgc3ViaDsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBfcXVhZFRyZWUoCi0gICAgICAgICAgICB7eDogeCwgeTogeSwgd2lkdGg6IHN1YncsIGhlaWdodDogc3ViaH0sCi0gICAgICAgICAgICBuZXh0LAotICAgICAgICAgICAgcXVhZC5tYXhFbGVtZW50cywKLSAgICAgICAgICAgIHF1YWQubWF4TGV2ZWwKLSAgICAgICAgKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWN1cnNpdmVseSBpbnNlcnQgYW4gZWxlbWVudCBpbnRvIHRoZSBxdWFkdHJlZS4gT25seSBwb2ludHMKLSAgICAgKiB3aXRoIHNpemUsIGkuZS4gYXhpcy1hbGlnbmVkIHNxdWFyZXMsIG1heSBiZSBpbnNlcnRlZCB3aXRoIHRoaXMKLSAgICAgKiBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICBlbCAgICAgICAgIFRoZSBlbGVtZW50IHRvIGluc2VydCBpbiB0aGUgcXVhZHRyZWUuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgc2l6ZWRQb2ludCBBIHNpemVkIHBvaW50IGRlZmluZWQgYnkgdHdvIHRvcCBwb2ludHMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh4MSwgeTEpLCAoeDIsIHkyKSBhbmQgaGVpZ2h0LgotICAgICAqIEBwYXJhbSAge29iamVjdH0gIHF1YWQgICAgICAgVGhlIHF1YWQgaW4gd2hpY2ggdG8gaW5zZXJ0IHRoZSBlbGVtZW50LgotICAgICAqIEByZXR1cm4ge3VuZGVmaW5lZH0gICAgICAgICAgVGhlIGZ1bmN0aW9uIGRvZXMgbm90IHJldHVybiBhbnl0aGluZy4KLSAgICAgKi8KLSAgICBmdW5jdGlvbiBfcXVhZEluc2VydChlbCwgc2l6ZWRQb2ludCwgcXVhZCkgewotICAgICAgICBpZiAocXVhZC5sZXZlbCA8IHF1YWQubWF4TGV2ZWwpIHsKLQotICAgICAgICAgICAgLy8gU2VhcmNoaW5nIGFwcHJvcHJpYXRlIHF1YWRzCi0gICAgICAgICAgICB2YXIgaW5kZXhlcyA9IF9xdWFkSW5kZXhlcyhzaXplZFBvaW50LCBxdWFkLmNvcm5lcnMpOwotCi0gICAgICAgICAgICAvLyBJdGVyYXRpbmcKLSAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gaW5kZXhlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKLQotICAgICAgICAgICAgICAgIC8vIFN1YmRpdmlkaW5nIGlmIG5lY2Vzc2FyeQotICAgICAgICAgICAgICAgIGlmIChxdWFkLm5vZGVzW2luZGV4ZXNbaV1dID09PSB1bmRlZmluZWQpCi0gICAgICAgICAgICAgICAgICAgIHF1YWQubm9kZXNbaW5kZXhlc1tpXV0gPSBfcXVhZFN1YmRpdmlkZShpbmRleGVzW2ldLCBxdWFkKTsKLQotICAgICAgICAgICAgICAgIC8vIFJlY3Vyc2lvbgotICAgICAgICAgICAgICAgIF9xdWFkSW5zZXJ0KGVsLCBzaXplZFBvaW50LCBxdWFkLm5vZGVzW2luZGV4ZXNbaV1dKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLQotICAgICAgICAgICAgLy8gUHVzaGluZyB0aGUgZWxlbWVudCBpbiBhIGxlYWYgbm9kZQotICAgICAgICAgICAgcXVhZC5lbGVtZW50cy5wdXNoKGVsKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlY3Vyc2l2ZWx5IHJldHJpZXZlIGV2ZXJ5IGVsZW1lbnRzIGhlbGQgYnkgdGhlIG5vZGUgY29udGFpbmluZyB0aGUKLSAgICAgKiBzZWFyY2hlZCBwb2ludC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdH0gIHBvaW50IFRoZSBzZWFyY2hlZCBwb2ludCAoeCwgeSkuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgcXVhZCAgVGhlIHNlYXJjaGVkIHF1YWQuCi0gICAgICogQHJldHVybiB7YXJyYXl9ICAgICAgICAgQW4gYXJyYXkgb2YgZWxlbWVudHMgY29udGFpbmVkIGluIHRoZSByZWxldmFudAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX3F1YWRSZXRyaWV2ZVBvaW50KHBvaW50LCBxdWFkKSB7Ci0gICAgICAgIGlmIChxdWFkLmxldmVsIDwgcXVhZC5tYXhMZXZlbCkgewotICAgICAgICAgICAgdmFyIGluZGV4ID0gX3F1YWRJbmRleChwb2ludCwgcXVhZC5ib3VuZHMpOwotCi0gICAgICAgICAgICAvLyBJZiBub2RlIGRvZXMgbm90IGV4aXN0IHdlIHJldHVybiBhbiBlbXB0eSBsaXN0Ci0gICAgICAgICAgICBpZiAocXVhZC5ub2Rlc1tpbmRleF0gIT09IHVuZGVmaW5lZCkgewotICAgICAgICAgICAgICAgIHJldHVybiBfcXVhZFJldHJpZXZlUG9pbnQocG9pbnQsIHF1YWQubm9kZXNbaW5kZXhdKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBbXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBxdWFkLmVsZW1lbnRzOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjdXJzaXZlbHkgcmV0cmlldmUgZXZlcnkgZWxlbWVudHMgY29udGFpbmVkIHdpdGhpbiBhbiByZWN0YW5ndWxhciBhcmVhCi0gICAgICogdGhhdCBtYXkgb3IgbWF5IG5vdCBiZSBheGlzLWFsaWduZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtvYmplY3R8YXJyYXl9IHJlY3REYXRhICAgICAgIFRoZSBzZWFyY2hlZCBhcmVhIGRlZmluZWQgZWl0aGVyIGJ5Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbiBhcnJheSBvZiBmb3VyIGNvcm5lcnMgKHgsIHkpIGluCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgY2FzZSBvZiBhIG5vbi1heGlzLWFsaWduZWQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY3RhbmdsZSBvciBhbiBvYmplY3Qgd2l0aCB0d28gdG9wCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2ludHMgKHgxLCB5MSksICh4MiwgeTIpIGFuZCBoZWlnaHQuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICBxdWFkICAgICAgICAgICBUaGUgc2VhcmNoZWQgcXVhZC4KLSAgICAgKiBAcGFyYW0gIHtmdW5jdGlvbn0gICAgIGNvbGxpc2lvbkZ1bmMgIFRoZSBjb2xsaXNpb24gZnVuY3Rpb24gdXNlZCB0byBzZWFyY2gKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBub2RlIGluZGV4ZXMuCi0gICAgICogQHBhcmFtICB7YXJyYXk/fSAgICAgICBlbHMgICAgICAgICAgICBUaGUgcmV0cmlldmVkIGVsZW1lbnRzLgotICAgICAqIEByZXR1cm4ge2FycmF5fSAgICAgICAgICAgICAgICAgICAgICAgQW4gYXJyYXkgb2YgZWxlbWVudHMgY29udGFpbmVkIGluIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJlYS4KLSAgICAgKi8KLSAgICBmdW5jdGlvbiBfcXVhZFJldHJpZXZlQXJlYShyZWN0RGF0YSwgcXVhZCwgY29sbGlzaW9uRnVuYywgZWxzKSB7Ci0gICAgICAgIGVscyA9IGVscyB8fCB7fTsKLQotICAgICAgICBpZiAocXVhZC5sZXZlbCA8IHF1YWQubWF4TGV2ZWwpIHsKLSAgICAgICAgICAgIHZhciBpbmRleGVzID0gY29sbGlzaW9uRnVuYyhyZWN0RGF0YSwgcXVhZC5jb3JuZXJzKTsKLQotICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBpbmRleGVzLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgICAgICBpZiAocXVhZC5ub2Rlc1tpbmRleGVzW2ldXSAhPT0gdW5kZWZpbmVkKQotICAgICAgICAgICAgICAgICAgICBfcXVhZFJldHJpZXZlQXJlYSgKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlY3REYXRhLAotICAgICAgICAgICAgICAgICAgICAgICAgcXVhZC5ub2Rlc1tpbmRleGVzW2ldXSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxpc2lvbkZ1bmMsCi0gICAgICAgICAgICAgICAgICAgICAgICBlbHMKLSAgICAgICAgICAgICAgICAgICAgKTsKLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICBmb3IgKHZhciBqID0gMCwgbSA9IHF1YWQuZWxlbWVudHMubGVuZ3RoOyBqIDwgbTsgaisrKQotICAgICAgICAgICAgICAgIGlmIChlbHNbcXVhZC5lbGVtZW50c1tqXS5pZF0gPT09IHVuZGVmaW5lZCkKLSAgICAgICAgICAgICAgICAgICAgZWxzW3F1YWQuZWxlbWVudHNbal0uaWRdID0gcXVhZC5lbGVtZW50c1tqXTsKLQotICAgICAgICByZXR1cm4gZWxzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgdGhlIHF1YWR0cmVlIG9iamVjdCBpdHNlbGYuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgYm91bmRzICAgICAgIFRoZSBib3VuZGFyaWVzIG9mIHRoZSBxdWFkIGRlZmluZWQgYnkgYW4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbiAoeCwgeSksIHdpZHRoIGFuZCBoZWlndGguCi0gICAgICogQHBhcmFtICB7aW50ZWdlcn0gIGxldmVsICAgICAgICBUaGUgbGV2ZWwgb2YgdGhlIHF1YWQgaW4gdGhlIHRyZWUuCi0gICAgICogQHBhcmFtICB7aW50ZWdlcn0gIG1heEVsZW1lbnRzICBUaGUgbWF4IG51bWJlciBvZiBlbGVtZW50IGluIGEgbGVhZiBub2RlLgotICAgICAqIEBwYXJhbSAge2ludGVnZXJ9ICBtYXhMZXZlbCAgICAgVGhlIG1heCByZWN1cnNpb24gbGV2ZWwgb2YgdGhlIHRyZWUuCi0gICAgICogQHJldHVybiB7b2JqZWN0fSAgICAgICAgICAgICAgICBUaGUgcXVhZHRyZWUgb2JqZWN0LgotICAgICAqLwotICAgIGZ1bmN0aW9uIF9xdWFkVHJlZShib3VuZHMsIGxldmVsLCBtYXhFbGVtZW50cywgbWF4TGV2ZWwpIHsKLSAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgIGxldmVsOiBsZXZlbCB8fCAwLAotICAgICAgICAgICAgYm91bmRzOiBib3VuZHMsCi0gICAgICAgICAgICBjb3JuZXJzOiBfZ2VvbS5zcGxpdFNxdWFyZShib3VuZHMpLAotICAgICAgICAgICAgbWF4RWxlbWVudHM6IG1heEVsZW1lbnRzIHx8IDIwLAotICAgICAgICAgICAgbWF4TGV2ZWw6IG1heExldmVsIHx8IDQsCi0gICAgICAgICAgICBlbGVtZW50czogW10sCi0gICAgICAgICAgICBub2RlczogW10KLSAgICAgICAgfTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNpZ21hIFF1YWQgQ29uc3RydWN0b3IKLSAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICoKLSAgICAgKiBUaGUgcXVhZCBBUEkgYXMgZXhwb3NlZCB0byBzaWdtYS4KLSAgICAgKi8KLQotICAgIC8qKgotICAgICAqIFRoZSBxdWFkIGNvcmUgdGhhdCB3aWxsIGJlY29tZSB0aGUgc2lnbWEgaW50ZXJmYWNlIHdpdGggdGhlIHF1YWR0cmVlLgotICAgICAqCi0gICAgICogcHJvcGVydHkge29iamVjdH0gX3RyZWUgIFByb3BlcnR5IGhvbGRpbmcgdGhlIHF1YWR0cmVlIG9iamVjdC4KLSAgICAgKiBwcm9wZXJ0eSB7b2JqZWN0fSBfZ2VvbSAgRXhwb3NpdGlvbiBvZiB0aGUgX2dlb20gbmFtZXNwYWNlIGZvciB0ZXN0aW5nLgotICAgICAqIHByb3BlcnR5IHtvYmplY3R9IF9jYWNoZSBDYWNoZSBmb3IgdGhlIGFyZWEgbWV0aG9kLgotICAgICAqLwotICAgIHZhciBxdWFkID0gZnVuY3Rpb24gKCkgewotICAgICAgICB0aGlzLl9nZW9tID0gX2dlb207Ci0gICAgICAgIHRoaXMuX3RyZWUgPSBudWxsOwotICAgICAgICB0aGlzLl9jYWNoZSA9IHsKLSAgICAgICAgICAgIHF1ZXJ5OiBmYWxzZSwKLSAgICAgICAgICAgIHJlc3VsdDogZmFsc2UKLSAgICAgICAgfTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogSW5kZXggYSBncmFwaCBieSBpbnNlcnRpbmcgaXRzIG5vZGVzIGludG8gdGhlIHF1YWR0cmVlLgotICAgICAqCi0gICAgICogQHBhcmFtICB7YXJyYXl9ICBub2RlcyAgIEFuIGFycmF5IG9mIG5vZGVzIHRvIGluZGV4LgotICAgICAqIEBwYXJhbSAge29iamVjdH0gcGFyYW1zICBBbiBvYmplY3Qgb2YgcGFyYW1ldGVycyB3aXRoIGF0IGxlYXN0IHRoZSBxdWFkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kcy4KLSAgICAgKiBAcmV0dXJuIHtvYmplY3R9ICAgICAgICAgVGhlIHF1YWR0cmVlIG9iamVjdC4KLSAgICAgKgotICAgICAqIFBhcmFtZXRlcnM6Ci0gICAgICogLS0tLS0tLS0tLQotICAgICAqIGJvdW5kczogICAgICB7b2JqZWN0fSAgIGJvdW5kYXJpZXMgb2YgdGhlIHF1YWQgZGVmaW5lZCBieSBpdHMgb3JpZ2luICh4LCB5KQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoIGFuZCBoZWlndGguCi0gICAgICogcHJlZml4OiAgICAgIHtzdHJpbmc/fSAgYSBwcmVmaXggZm9yIG5vZGUgZ2VvbWV0cmljIGF0dHJpYnV0ZXMuCi0gICAgICogbWF4RWxlbWVudHM6IHtpbnRlZ2VyP30gdGhlIG1heCBudW1iZXIgb2YgZWxlbWVudHMgaW4gYSBsZWFmIG5vZGUuCi0gICAgICogbWF4TGV2ZWw6ICAgIHtpbnRlZ2VyP30gdGhlIG1heCByZWN1cnNpb24gbGV2ZWwgb2YgdGhlIHRyZWUuCi0gICAgICovCi0gICAgcXVhZC5wcm90b3R5cGUuaW5kZXggPSBmdW5jdGlvbiAobm9kZXMsIHBhcmFtcykgewotCi0gICAgICAgIC8vIEVuZm9yY2luZyBwcmVzZW5jZSBvZiBib3VuZGFyaWVzCi0gICAgICAgIGlmICghcGFyYW1zLmJvdW5kcykKLSAgICAgICAgICAgIHRocm93ICdzaWdtYS5jbGFzc2VzLnF1YWQuaW5kZXg6IGJvdW5kcyBpbmZvcm1hdGlvbiBub3QgZ2l2ZW4uJzsKLQotICAgICAgICAvLyBQcmVmaXgKLSAgICAgICAgdmFyIHByZWZpeCA9IHBhcmFtcy5wcmVmaXggfHwgJyc7Ci0KLSAgICAgICAgLy8gQnVpbGRpbmcgdGhlIHRyZWUKLSAgICAgICAgdGhpcy5fdHJlZSA9IF9xdWFkVHJlZSgKLSAgICAgICAgICAgIHBhcmFtcy5ib3VuZHMsCi0gICAgICAgICAgICAwLAotICAgICAgICAgICAgcGFyYW1zLm1heEVsZW1lbnRzLAotICAgICAgICAgICAgcGFyYW1zLm1heExldmVsCi0gICAgICAgICk7Ci0KLSAgICAgICAgLy8gSW5zZXJ0aW5nIGdyYXBoIG5vZGVzIGludG8gdGhlIHRyZWUKLSAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBub2Rlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKLQotICAgICAgICAgICAgLy8gSW5zZXJ0aW5nIG5vZGUKLSAgICAgICAgICAgIF9xdWFkSW5zZXJ0KAotICAgICAgICAgICAgICAgIG5vZGVzW2ldLAotICAgICAgICAgICAgICAgIF9nZW9tLnBvaW50VG9TcXVhcmUoewotICAgICAgICAgICAgICAgICAgICB4OiBub2Rlc1tpXVtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgICAgICAgICB5OiBub2Rlc1tpXVtwcmVmaXggKyAneSddLAotICAgICAgICAgICAgICAgICAgICBzaXplOiBub2Rlc1tpXVtwcmVmaXggKyAnc2l6ZSddCi0gICAgICAgICAgICAgICAgfSksCi0gICAgICAgICAgICAgICAgdGhpcy5fdHJlZQotICAgICAgICAgICAgKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJlc2V0IGNhY2hlOgotICAgICAgICB0aGlzLl9jYWNoZSA9IHsKLSAgICAgICAgICAgIHF1ZXJ5OiBmYWxzZSwKLSAgICAgICAgICAgIHJlc3VsdDogZmFsc2UKLSAgICAgICAgfTsKLQotICAgICAgICAvLyByZW1vdmU/Ci0gICAgICAgIHJldHVybiB0aGlzLl90cmVlOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZSBldmVyeSBncmFwaCBub2RlcyBoZWxkIGJ5IHRoZSBxdWFkdHJlZSBub2RlIGNvbnRhaW5pbmcgdGhlCi0gICAgICogc2VhcmNoZWQgcG9pbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHggb2YgdGhlIHBvaW50LgotICAgICAqIEBwYXJhbSAge251bWJlcn0geSBvZiB0aGUgcG9pbnQuCi0gICAgICogQHJldHVybiB7YXJyYXl9ICBBbiBhcnJheSBvZiBub2RlcyByZXRyaWV2ZWQuCi0gICAgICovCi0gICAgcXVhZC5wcm90b3R5cGUucG9pbnQgPSBmdW5jdGlvbiAoeCwgeSkgewotICAgICAgICByZXR1cm4gdGhpcy5fdHJlZSA/Ci0gICAgICAgIF9xdWFkUmV0cmlldmVQb2ludCh7eDogeCwgeTogeX0sIHRoaXMuX3RyZWUpIHx8IFtdIDoKLSAgICAgICAgICAgIFtdOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZSBldmVyeSBncmFwaCBub2RlcyB3aXRoaW4gYSByZWN0YW5ndWxhciBhcmVhLiBUaGUgbWV0aG9kcyBrZWVwIHRoZQotICAgICAqIGxhc3QgYXJlYSBxdWVyaWVkIGluIGNhY2hlIGZvciBvcHRpbWl6YXRpb24gcmVhc29uIGFuZCB3aWxsIGFjdCBkaWZmZXJlbnRseQotICAgICAqIGZvciB0aGUgc2FtZSByZWFzb24gaWYgdGhlIGFyZWEgaXMgYXhpcy1hbGlnbmVkIG9yIG5vdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdH0gQSByZWN0YW5nbGUgZGVmaW5lZCBieSB0d28gdG9wIHBvaW50cyAoeDEsIHkxKSwgKHgyLCB5MikKLSAgICAgKiAgICAgICAgICAgICAgICAgIGFuZCBoZWlnaHQuCi0gICAgICogQHJldHVybiB7YXJyYXl9ICBBbiBhcnJheSBvZiBub2RlcyByZXRyaWV2ZWQuCi0gICAgICovCi0gICAgcXVhZC5wcm90b3R5cGUuYXJlYSA9IGZ1bmN0aW9uIChyZWN0KSB7Ci0gICAgICAgIHZhciBzZXJpYWxpemVkID0gSlNPTi5zdHJpbmdpZnkocmVjdCksCi0gICAgICAgICAgICBjb2xsaXNpb25GdW5jLAotICAgICAgICAgICAgcmVjdERhdGE7Ci0KLSAgICAgICAgLy8gUmV0dXJuaW5nIGNhY2hlPwotICAgICAgICBpZiAodGhpcy5fY2FjaGUucXVlcnkgPT09IHNlcmlhbGl6ZWQpCi0gICAgICAgICAgICByZXR1cm4gdGhpcy5fY2FjaGUucmVzdWx0OwotCi0gICAgICAgIC8vIEF4aXMgYWxpZ25lZCA/Ci0gICAgICAgIGlmIChfZ2VvbS5pc0F4aXNBbGlnbmVkKHJlY3QpKSB7Ci0gICAgICAgICAgICBjb2xsaXNpb25GdW5jID0gX3F1YWRJbmRleGVzOwotICAgICAgICAgICAgcmVjdERhdGEgPSBfZ2VvbS5heGlzQWxpZ25lZFRvcFBvaW50cyhyZWN0KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGNvbGxpc2lvbkZ1bmMgPSBfcXVhZENvbGxpc2lvbjsKLSAgICAgICAgICAgIHJlY3REYXRhID0gX2dlb20ucmVjdGFuZ2xlQ29ybmVycyhyZWN0KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJldHJpZXZpbmcgbm9kZXMKLSAgICAgICAgdmFyIG5vZGVzID0gdGhpcy5fdHJlZSA/Ci0gICAgICAgICAgICBfcXVhZFJldHJpZXZlQXJlYSgKLSAgICAgICAgICAgICAgICByZWN0RGF0YSwKLSAgICAgICAgICAgICAgICB0aGlzLl90cmVlLAotICAgICAgICAgICAgICAgIGNvbGxpc2lvbkZ1bmMKLSAgICAgICAgICAgICkgOgotICAgICAgICAgICAgW107Ci0KLSAgICAgICAgLy8gT2JqZWN0IHRvIGFycmF5Ci0gICAgICAgIHZhciBub2Rlc0FycmF5ID0gW107Ci0gICAgICAgIGZvciAodmFyIGkgaW4gbm9kZXMpCi0gICAgICAgICAgICBub2Rlc0FycmF5LnB1c2gobm9kZXNbaV0pOwotCi0gICAgICAgIC8vIENhY2hpbmcKLSAgICAgICAgdGhpcy5fY2FjaGUucXVlcnkgPSBzZXJpYWxpemVkOwotICAgICAgICB0aGlzLl9jYWNoZS5yZXN1bHQgPSBub2Rlc0FycmF5OwotCi0gICAgICAgIHJldHVybiBub2Rlc0FycmF5OwotICAgIH07Ci0KLQotICAgIC8qKgotICAgICAqIEVYUE9SVDoKLSAgICAgKiAqKioqKioqCi0gICAgICovCi0gICAgaWYgKHR5cGVvZiB0aGlzLnNpZ21hICE9PSAndW5kZWZpbmVkJykgewotICAgICAgICB0aGlzLnNpZ21hLmNsYXNzZXMgPSB0aGlzLnNpZ21hLmNsYXNzZXMgfHwge307Ci0gICAgICAgIHRoaXMuc2lnbWEuY2xhc3Nlcy5xdWFkID0gcXVhZDsKLSAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykgewotICAgICAgICBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpCi0gICAgICAgICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBxdWFkOwotICAgICAgICBleHBvcnRzLnF1YWQgPSBxdWFkOwotICAgIH0gZWxzZQotICAgICAgICB0aGlzLnF1YWQgPSBxdWFkOwotfSkuY2FsbCh0aGlzKTsKLQotOyhmdW5jdGlvbiAodW5kZWZpbmVkKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgLyoqCi0gICAgICogU2lnbWEgUXVhZHRyZWUgTW9kdWxlIGZvciBlZGdlcwotICAgICAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgICAgKgotICAgICAqIEF1dGhvcjogU8OpYmFzdGllbiBIZXltYW5uLAotICAgICAqICAgZnJvbSB0aGUgcXVhZCBvZiBHdWlsbGF1bWUgUGxpcXVlIChZb21ndWl0aGVyZWFsKQotICAgICAqIFZlcnNpb246IDAuMgotICAgICAqLwotCi0KLSAgICAvKioKLSAgICAgKiBRdWFkIEdlb21ldHJpYyBPcGVyYXRpb25zCi0gICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAqCi0gICAgICogQSB1c2VmdWwgYmF0Y2ggb2YgZ2VvbWV0cmljIG9wZXJhdGlvbnMgdXNlZCBieSB0aGUgcXVhZHRyZWUuCi0gICAgICovCi0KLSAgICB2YXIgX2dlb20gPSB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRyYW5zZm9ybXMgYSBncmFwaCBub2RlIHdpdGggeCwgeSBhbmQgc2l6ZSBpbnRvIGFuCi0gICAgICAgICAqIGF4aXMtYWxpZ25lZCBzcXVhcmUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSAge29iamVjdH0gQSBncmFwaCBub2RlIHdpdGggYXQgbGVhc3QgYSBwb2ludCAoeCwgeSkgYW5kIGEgc2l6ZS4KLSAgICAgICAgICogQHJldHVybiB7b2JqZWN0fSBBIHNxdWFyZTogdHdvIHBvaW50cyAoeDEsIHkxKSwgKHgyLCB5MikgYW5kIGhlaWdodC4KLSAgICAgICAgICovCi0gICAgICAgIHBvaW50VG9TcXVhcmU6IGZ1bmN0aW9uIChuKSB7Ci0gICAgICAgICAgICByZXR1cm4gewotICAgICAgICAgICAgICAgIHgxOiBuLnggLSBuLnNpemUsCi0gICAgICAgICAgICAgICAgeTE6IG4ueSAtIG4uc2l6ZSwKLSAgICAgICAgICAgICAgICB4Mjogbi54ICsgbi5zaXplLAotICAgICAgICAgICAgICAgIHkyOiBuLnkgLSBuLnNpemUsCi0gICAgICAgICAgICAgICAgaGVpZ2h0OiBuLnNpemUgKiAyCi0gICAgICAgICAgICB9OwotICAgICAgICB9LAotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUcmFuc2Zvcm1zIGEgZ3JhcGggZWRnZSB3aXRoIHgxLCB5MSwgeDIsIHkyIGFuZCBzaXplIGludG8gYW4KLSAgICAgICAgICogYXhpcy1hbGlnbmVkIHNxdWFyZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtICB7b2JqZWN0fSBBIGdyYXBoIGVkZ2Ugd2l0aCBhdCBsZWFzdCB0d28gcG9pbnRzCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgKHgxLCB5MSksICh4MiwgeTIpIGFuZCBhIHNpemUuCi0gICAgICAgICAqIEByZXR1cm4ge29iamVjdH0gQSBzcXVhcmU6IHR3byBwb2ludHMgKHgxLCB5MSksICh4MiwgeTIpIGFuZCBoZWlnaHQuCi0gICAgICAgICAqLwotICAgICAgICBsaW5lVG9TcXVhcmU6IGZ1bmN0aW9uIChlKSB7Ci0gICAgICAgICAgICBpZiAoZS55MSA8IGUueTIpIHsKLSAgICAgICAgICAgICAgICAvLyAoZS54MSwgZS55MSkgb24gdG9wCi0gICAgICAgICAgICAgICAgaWYgKGUueDEgPCBlLngyKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIChlLngxLCBlLnkxKSBvbiBsZWZ0Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB4MTogZS54MSAtIGUuc2l6ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHkxOiBlLnkxIC0gZS5zaXplLAotICAgICAgICAgICAgICAgICAgICAgICAgeDI6IGUueDIgKyBlLnNpemUsCi0gICAgICAgICAgICAgICAgICAgICAgICB5MjogZS55MSAtIGUuc2l6ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogZS55MiAtIGUueTEgKyBlLnNpemUgKiAyCi0gICAgICAgICAgICAgICAgICAgIH07Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIChlLngxLCBlLnkxKSBvbiByaWdodAotICAgICAgICAgICAgICAgIHJldHVybiB7Ci0gICAgICAgICAgICAgICAgICAgIHgxOiBlLngyIC0gZS5zaXplLAotICAgICAgICAgICAgICAgICAgICB5MTogZS55MSAtIGUuc2l6ZSwKLSAgICAgICAgICAgICAgICAgICAgeDI6IGUueDEgKyBlLnNpemUsCi0gICAgICAgICAgICAgICAgICAgIHkyOiBlLnkxIC0gZS5zaXplLAotICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGUueTIgLSBlLnkxICsgZS5zaXplICogMgotICAgICAgICAgICAgICAgIH07Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIChlLngyLCBlLnkyKSBvbiB0b3AKLSAgICAgICAgICAgIGlmIChlLngxIDwgZS54MikgewotICAgICAgICAgICAgICAgIC8vIChlLngxLCBlLnkxKSBvbiBsZWZ0Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgICAgICAgICAgeDE6IGUueDEgLSBlLnNpemUsCi0gICAgICAgICAgICAgICAgICAgIHkxOiBlLnkyIC0gZS5zaXplLAotICAgICAgICAgICAgICAgICAgICB4MjogZS54MiArIGUuc2l6ZSwKLSAgICAgICAgICAgICAgICAgICAgeTI6IGUueTIgLSBlLnNpemUsCi0gICAgICAgICAgICAgICAgICAgIGhlaWdodDogZS55MSAtIGUueTIgKyBlLnNpemUgKiAyCi0gICAgICAgICAgICAgICAgfTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIChlLngyLCBlLnkyKSBvbiByaWdodAotICAgICAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgICAgICB4MTogZS54MiAtIGUuc2l6ZSwKLSAgICAgICAgICAgICAgICB5MTogZS55MiAtIGUuc2l6ZSwKLSAgICAgICAgICAgICAgICB4MjogZS54MSArIGUuc2l6ZSwKLSAgICAgICAgICAgICAgICB5MjogZS55MiAtIGUuc2l6ZSwKLSAgICAgICAgICAgICAgICBoZWlnaHQ6IGUueTEgLSBlLnkyICsgZS5zaXplICogMgotICAgICAgICAgICAgfTsKLSAgICAgICAgfSwKLQotICAgICAgICAvKioKLSAgICAgICAgICogVHJhbnNmb3JtcyBhIGdyYXBoIGVkZ2Ugb2YgdHlwZSAnY3VydmUnIHdpdGggeDEsIHkxLCB4MiwgeTIsCi0gICAgICAgICAqIGNvbnRyb2wgcG9pbnQgYW5kIHNpemUgaW50byBhbiBheGlzLWFsaWduZWQgc3F1YXJlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9IGUgIEEgZ3JhcGggZWRnZSB3aXRoIGF0IGxlYXN0IHR3byBwb2ludHMKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAoeDEsIHkxKSwgKHgyLCB5MikgYW5kIGEgc2l6ZS4KLSAgICAgICAgICogQHBhcmFtICB7b2JqZWN0fSBjcCBBIGNvbnRyb2wgcG9pbnQgKHgseSkuCi0gICAgICAgICAqIEByZXR1cm4ge29iamVjdH0gICAgQSBzcXVhcmU6IHR3byBwb2ludHMgKHgxLCB5MSksICh4MiwgeTIpIGFuZCBoZWlnaHQuCi0gICAgICAgICAqLwotICAgICAgICBxdWFkcmF0aWNDdXJ2ZVRvU3F1YXJlOiBmdW5jdGlvbiAoZSwgY3ApIHsKLSAgICAgICAgICAgIHZhciBwdCA9IHNpZ21hLnV0aWxzLmdldFBvaW50T25RdWFkcmF0aWNDdXJ2ZSgKLSAgICAgICAgICAgICAgICAwLjUsCi0gICAgICAgICAgICAgICAgZS54MSwKLSAgICAgICAgICAgICAgICBlLnkxLAotICAgICAgICAgICAgICAgIGUueDIsCi0gICAgICAgICAgICAgICAgZS55MiwKLSAgICAgICAgICAgICAgICBjcC54LAotICAgICAgICAgICAgICAgIGNwLnkKLSAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIC8vIEJvdW5kaW5nIGJveCBvZiB0aGUgdHdvIHBvaW50cyBhbmQgdGhlIHBvaW50IGF0IHRoZSBtaWRkbGUgb2YgdGhlCi0gICAgICAgICAgICAvLyBjdXJ2ZToKLSAgICAgICAgICAgIHZhciBtaW5YID0gTWF0aC5taW4oZS54MSwgZS54MiwgcHQueCksCi0gICAgICAgICAgICAgICAgbWF4WCA9IE1hdGgubWF4KGUueDEsIGUueDIsIHB0LngpLAotICAgICAgICAgICAgICAgIG1pblkgPSBNYXRoLm1pbihlLnkxLCBlLnkyLCBwdC55KSwKLSAgICAgICAgICAgICAgICBtYXhZID0gTWF0aC5tYXgoZS55MSwgZS55MiwgcHQueSk7Ci0KLSAgICAgICAgICAgIHJldHVybiB7Ci0gICAgICAgICAgICAgICAgeDE6IG1pblggLSBlLnNpemUsCi0gICAgICAgICAgICAgICAgeTE6IG1pblkgLSBlLnNpemUsCi0gICAgICAgICAgICAgICAgeDI6IG1heFggKyBlLnNpemUsCi0gICAgICAgICAgICAgICAgeTI6IG1pblkgLSBlLnNpemUsCi0gICAgICAgICAgICAgICAgaGVpZ2h0OiBtYXhZIC0gbWluWSArIGUuc2l6ZSAqIDIKLSAgICAgICAgICAgIH07Ci0gICAgICAgIH0sCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRyYW5zZm9ybXMgYSBncmFwaCBzZWxmIGxvb3AgaW50byBhbiBheGlzLWFsaWduZWQgc3F1YXJlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9IG4gQSBncmFwaCBub2RlIHdpdGggYSBwb2ludCAoeCwgeSkgYW5kIGEgc2l6ZS4KLSAgICAgICAgICogQHJldHVybiB7b2JqZWN0fSAgIEEgc3F1YXJlOiB0d28gcG9pbnRzICh4MSwgeTEpLCAoeDIsIHkyKSBhbmQgaGVpZ2h0LgotICAgICAgICAgKi8KLSAgICAgICAgc2VsZkxvb3BUb1NxdWFyZTogZnVuY3Rpb24gKG4pIHsKLSAgICAgICAgICAgIC8vIEZpdHRpbmcgdG8gdGhlIGN1cnZlIGlzIHRvbyBjb3N0bHksIHdlIGNvbXB1dGUgYSBsYXJnZXIgYm91bmRpbmcgYm94Ci0gICAgICAgICAgICAvLyB1c2luZyB0aGUgY29udHJvbCBwb2ludHM6Ci0gICAgICAgICAgICB2YXIgY3AgPSBzaWdtYS51dGlscy5nZXRTZWxmTG9vcENvbnRyb2xQb2ludHMobi54LCBuLnksIG4uc2l6ZSk7Ci0KLSAgICAgICAgICAgIC8vIEJvdW5kaW5nIGJveCBvZiB0aGUgcG9pbnQgYW5kIHRoZSB0d28gY29udHJvbCBwb2ludHM6Ci0gICAgICAgICAgICB2YXIgbWluWCA9IE1hdGgubWluKG4ueCwgY3AueDEsIGNwLngyKSwKLSAgICAgICAgICAgICAgICBtYXhYID0gTWF0aC5tYXgobi54LCBjcC54MSwgY3AueDIpLAotICAgICAgICAgICAgICAgIG1pblkgPSBNYXRoLm1pbihuLnksIGNwLnkxLCBjcC55MiksCi0gICAgICAgICAgICAgICAgbWF4WSA9IE1hdGgubWF4KG4ueSwgY3AueTEsIGNwLnkyKTsKLQotICAgICAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgICAgICB4MTogbWluWCAtIG4uc2l6ZSwKLSAgICAgICAgICAgICAgICB5MTogbWluWSAtIG4uc2l6ZSwKLSAgICAgICAgICAgICAgICB4MjogbWF4WCArIG4uc2l6ZSwKLSAgICAgICAgICAgICAgICB5MjogbWluWSAtIG4uc2l6ZSwKLSAgICAgICAgICAgICAgICBoZWlnaHQ6IG1heFkgLSBtaW5ZICsgbi5zaXplICogMgotICAgICAgICAgICAgfTsKLSAgICAgICAgfSwKLQotICAgICAgICAvKioKLSAgICAgICAgICogQ2hlY2tzIHdoZXRoZXIgYSByZWN0YW5nbGUgaXMgYXhpcy1hbGlnbmVkLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICBBIHJlY3RhbmdsZSBkZWZpbmVkIGJ5IHR3byBwb2ludHMKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgKHgxLCB5MSkgYW5kICh4MiwgeTIpLgotICAgICAgICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSByZWN0YW5nbGUgaXMgYXhpcy1hbGlnbmVkLgotICAgICAgICAgKi8KLSAgICAgICAgaXNBeGlzQWxpZ25lZDogZnVuY3Rpb24gKHIpIHsKLSAgICAgICAgICAgIHJldHVybiByLngxID09PSByLngyIHx8IHIueTEgPT09IHIueTI7Ci0gICAgICAgIH0sCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbXB1dGUgdG9wIHBvaW50cyBvZiBhbiBheGlzLWFsaWduZWQgcmVjdGFuZ2xlLiBUaGlzIGlzIHVzZWZ1bCBpbgotICAgICAgICAgKiBjYXNlcyB3aGVuIHRoZSByZWN0YW5nbGUgaGFzIGJlZW4gcm90YXRlZCAobGVmdCwgcmlnaHQgb3IgYm90dG9tIHVwKSBhbmQKLSAgICAgICAgICogbGF0ZXIgb3BlcmF0aW9ucyBuZWVkIHRvIGtub3cgdGhlIHRvcCBwb2ludHMuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSAge29iamVjdH0gQW4gYXhpcy1hbGlnbmVkIHJlY3RhbmdsZSBkZWZpbmVkIGJ5IHR3byBwb2ludHMKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAoeDEsIHkxKSwgKHgyLCB5MikgYW5kIGhlaWdodC4KLSAgICAgICAgICogQHJldHVybiB7b2JqZWN0fSBBIHJlY3RhbmdsZTogdHdvIHBvaW50cyAoeDEsIHkxKSwgKHgyLCB5MikgYW5kIGhlaWdodC4KLSAgICAgICAgICovCi0gICAgICAgIGF4aXNBbGlnbmVkVG9wUG9pbnRzOiBmdW5jdGlvbiAocikgewotCi0gICAgICAgICAgICAvLyBCYXNpYwotICAgICAgICAgICAgaWYgKHIueTEgPT09IHIueTIgJiYgci54MSA8IHIueDIpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHI7Ci0KLSAgICAgICAgICAgIC8vIFJvdGF0ZWQgdG8gcmlnaHQKLSAgICAgICAgICAgIGlmIChyLngxID09PSByLngyICYmIHIueTIgPiByLnkxKQotICAgICAgICAgICAgICAgIHJldHVybiB7Ci0gICAgICAgICAgICAgICAgICAgIHgxOiByLngxIC0gci5oZWlnaHQsIHkxOiByLnkxLAotICAgICAgICAgICAgICAgICAgICB4Mjogci54MSwgeTI6IHIueTEsCi0gICAgICAgICAgICAgICAgICAgIGhlaWdodDogci5oZWlnaHQKLSAgICAgICAgICAgICAgICB9OwotCi0gICAgICAgICAgICAvLyBSb3RhdGVkIHRvIGxlZnQKLSAgICAgICAgICAgIGlmIChyLngxID09PSByLngyICYmIHIueTIgPCByLnkxKQotICAgICAgICAgICAgICAgIHJldHVybiB7Ci0gICAgICAgICAgICAgICAgICAgIHgxOiByLngxLCB5MTogci55MiwKLSAgICAgICAgICAgICAgICAgICAgeDI6IHIueDIgKyByLmhlaWdodCwgeTI6IHIueTIsCi0gICAgICAgICAgICAgICAgICAgIGhlaWdodDogci5oZWlnaHQKLSAgICAgICAgICAgICAgICB9OwotCi0gICAgICAgICAgICAvLyBCb3R0b20ncyB1cAotICAgICAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgICAgICB4MTogci54MiwgeTE6IHIueTEgLSByLmhlaWdodCwKLSAgICAgICAgICAgICAgICB4Mjogci54MSwgeTI6IHIueTEgLSByLmhlaWdodCwKLSAgICAgICAgICAgICAgICBoZWlnaHQ6IHIuaGVpZ2h0Ci0gICAgICAgICAgICB9OwotICAgICAgICB9LAotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHZXQgY29vcmRpbmF0ZXMgb2YgYSByZWN0YW5nbGUncyBsb3dlciBsZWZ0IGNvcm5lciBmcm9tIGl0cyB0b3AgcG9pbnRzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9IEEgcmVjdGFuZ2xlIGRlZmluZWQgYnkgdHdvIHBvaW50cyAoeDEsIHkxKSBhbmQgKHgyLCB5MikuCi0gICAgICAgICAqIEByZXR1cm4ge29iamVjdH0gQ29vcmRpbmF0ZXMgb2YgdGhlIGNvcm5lciAoeCwgeSkuCi0gICAgICAgICAqLwotICAgICAgICBsb3dlckxlZnRDb29yOiBmdW5jdGlvbiAocikgewotICAgICAgICAgICAgdmFyIHdpZHRoID0gKAotICAgICAgICAgICAgICAgIE1hdGguc3FydCgKLSAgICAgICAgICAgICAgICAgICAgTWF0aC5wb3coci54MiAtIHIueDEsIDIpICsKLSAgICAgICAgICAgICAgICAgICAgTWF0aC5wb3coci55MiAtIHIueTEsIDIpCi0gICAgICAgICAgICAgICAgKQotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgICAgICB4OiByLngxIC0gKHIueTIgLSByLnkxKSAqIHIuaGVpZ2h0IC8gd2lkdGgsCi0gICAgICAgICAgICAgICAgeTogci55MSArIChyLngyIC0gci54MSkgKiByLmhlaWdodCAvIHdpZHRoCi0gICAgICAgICAgICB9OwotICAgICAgICB9LAotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHZXQgY29vcmRpbmF0ZXMgb2YgYSByZWN0YW5nbGUncyBsb3dlciByaWdodCBjb3JuZXIgZnJvbSBpdHMgdG9wIHBvaW50cwotICAgICAgICAgKiBhbmQgaXRzIGxvd2VyIGxlZnQgY29ybmVyLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9IEEgcmVjdGFuZ2xlIGRlZmluZWQgYnkgdHdvIHBvaW50cyAoeDEsIHkxKSBhbmQgKHgyLCB5MikuCi0gICAgICAgICAqIEBwYXJhbSAge29iamVjdH0gQSBjb3JuZXIncyBjb29yZGluYXRlcyAoeCwgeSkuCi0gICAgICAgICAqIEByZXR1cm4ge29iamVjdH0gQ29vcmRpbmF0ZXMgb2YgdGhlIGNvcm5lciAoeCwgeSkuCi0gICAgICAgICAqLwotICAgICAgICBsb3dlclJpZ2h0Q29vcjogZnVuY3Rpb24gKHIsIGxsYykgewotICAgICAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgICAgICB4OiBsbGMueCAtIHIueDEgKyByLngyLAotICAgICAgICAgICAgICAgIHk6IGxsYy55IC0gci55MSArIHIueTIKLSAgICAgICAgICAgIH07Ci0gICAgICAgIH0sCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdldCB0aGUgY29vcmRpbmF0ZXMgb2YgYWxsIHRoZSBjb3JuZXJzIG9mIGEgcmVjdGFuZ2xlIGZyb20gaXRzIHRvcCBwb2ludC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtICB7b2JqZWN0fSBBIHJlY3RhbmdsZSBkZWZpbmVkIGJ5IHR3byBwb2ludHMgKHgxLCB5MSkgYW5kICh4MiwgeTIpLgotICAgICAgICAgKiBAcmV0dXJuIHthcnJheX0gIEFuIGFycmF5IG9mIHRoZSBmb3VyIGNvcm5lcnMnIGNvb3JkaW5hdGVzICh4LCB5KS4KLSAgICAgICAgICovCi0gICAgICAgIHJlY3RhbmdsZUNvcm5lcnM6IGZ1bmN0aW9uIChyKSB7Ci0gICAgICAgICAgICB2YXIgbGxjID0gdGhpcy5sb3dlckxlZnRDb29yKHIpLAotICAgICAgICAgICAgICAgIGxyYyA9IHRoaXMubG93ZXJSaWdodENvb3IociwgbGxjKTsKLQotICAgICAgICAgICAgcmV0dXJuIFsKLSAgICAgICAgICAgICAgICB7eDogci54MSwgeTogci55MX0sCi0gICAgICAgICAgICAgICAge3g6IHIueDIsIHk6IHIueTJ9LAotICAgICAgICAgICAgICAgIHt4OiBsbGMueCwgeTogbGxjLnl9LAotICAgICAgICAgICAgICAgIHt4OiBscmMueCwgeTogbHJjLnl9Ci0gICAgICAgICAgICBdOwotICAgICAgICB9LAotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTcGxpdCBhIHNxdWFyZSBkZWZpbmVkIGJ5IGl0cyBib3VuZGFyaWVzIGludG8gZm91ci4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtICB7b2JqZWN0fSBCb3VuZGFyaWVzIG9mIHRoZSBzcXVhcmUgKHgsIHksIHdpZHRoLCBoZWlnaHQpLgotICAgICAgICAgKiBAcmV0dXJuIHthcnJheX0gIEFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIGZvdXIgbmV3IHNxdWFyZXMsIHRoZW1zZWx2ZXMKLSAgICAgICAgICogICAgICAgICAgICAgICAgICBkZWZpbmVkIGJ5IGFuIGFycmF5IG9mIHRoZWlyIGZvdXIgY29ybmVycyAoeCwgeSkuCi0gICAgICAgICAqLwotICAgICAgICBzcGxpdFNxdWFyZTogZnVuY3Rpb24gKGIpIHsKLSAgICAgICAgICAgIHJldHVybiBbCi0gICAgICAgICAgICAgICAgWwotICAgICAgICAgICAgICAgICAgICB7eDogYi54LCB5OiBiLnl9LAotICAgICAgICAgICAgICAgICAgICB7eDogYi54ICsgYi53aWR0aCAvIDIsIHk6IGIueX0sCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLngsIHk6IGIueSArIGIuaGVpZ2h0IC8gMn0sCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLnggKyBiLndpZHRoIC8gMiwgeTogYi55ICsgYi5oZWlnaHQgLyAyfQotICAgICAgICAgICAgICAgIF0sCi0gICAgICAgICAgICAgICAgWwotICAgICAgICAgICAgICAgICAgICB7eDogYi54ICsgYi53aWR0aCAvIDIsIHk6IGIueX0sCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLnggKyBiLndpZHRoLCB5OiBiLnl9LAotICAgICAgICAgICAgICAgICAgICB7eDogYi54ICsgYi53aWR0aCAvIDIsIHk6IGIueSArIGIuaGVpZ2h0IC8gMn0sCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLnggKyBiLndpZHRoLCB5OiBiLnkgKyBiLmhlaWdodCAvIDJ9Ci0gICAgICAgICAgICAgICAgXSwKLSAgICAgICAgICAgICAgICBbCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLngsIHk6IGIueSArIGIuaGVpZ2h0IC8gMn0sCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLnggKyBiLndpZHRoIC8gMiwgeTogYi55ICsgYi5oZWlnaHQgLyAyfSwKLSAgICAgICAgICAgICAgICAgICAge3g6IGIueCwgeTogYi55ICsgYi5oZWlnaHR9LAotICAgICAgICAgICAgICAgICAgICB7eDogYi54ICsgYi53aWR0aCAvIDIsIHk6IGIueSArIGIuaGVpZ2h0fQotICAgICAgICAgICAgICAgIF0sCi0gICAgICAgICAgICAgICAgWwotICAgICAgICAgICAgICAgICAgICB7eDogYi54ICsgYi53aWR0aCAvIDIsIHk6IGIueSArIGIuaGVpZ2h0IC8gMn0sCi0gICAgICAgICAgICAgICAgICAgIHt4OiBiLnggKyBiLndpZHRoLCB5OiBiLnkgKyBiLmhlaWdodCAvIDJ9LAotICAgICAgICAgICAgICAgICAgICB7eDogYi54ICsgYi53aWR0aCAvIDIsIHk6IGIueSArIGIuaGVpZ2h0fSwKLSAgICAgICAgICAgICAgICAgICAge3g6IGIueCArIGIud2lkdGgsIHk6IGIueSArIGIuaGVpZ2h0fQotICAgICAgICAgICAgICAgIF0KLSAgICAgICAgICAgIF07Ci0gICAgICAgIH0sCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbXB1dGUgdGhlIGZvdXIgYXhpcyBiZXR3ZWVuIGNvcm5lcnMgb2YgcmVjdGFuZ2xlIEEgYW5kIGNvcm5lcnMgb2YKLSAgICAgICAgICogcmVjdGFuZ2xlIEIuIFRoaXMgaXMgbmVlZGVkIGxhdGVyIHRvIGNoZWNrIGFuIGV2ZW50dWFsIGNvbGxpc2lvbi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtICB7YXJyYXl9IEFuIGFycmF5IG9mIHJlY3RhbmdsZSBBJ3MgZm91ciBjb3JuZXJzICh4LCB5KS4KLSAgICAgICAgICogQHBhcmFtICB7YXJyYXl9IEFuIGFycmF5IG9mIHJlY3RhbmdsZSBCJ3MgZm91ciBjb3JuZXJzICh4LCB5KS4KLSAgICAgICAgICogQHJldHVybiB7YXJyYXl9IEFuIGFycmF5IG9mIGZvdXIgYXhpcyBkZWZpbmVkIGJ5IHRoZWlyIGNvb3JkaW5hdGVzICh4LHkpLgotICAgICAgICAgKi8KLSAgICAgICAgYXhpczogZnVuY3Rpb24gKGMxLCBjMikgewotICAgICAgICAgICAgcmV0dXJuIFsKLSAgICAgICAgICAgICAgICB7eDogYzFbMV0ueCAtIGMxWzBdLngsIHk6IGMxWzFdLnkgLSBjMVswXS55fSwKLSAgICAgICAgICAgICAgICB7eDogYzFbMV0ueCAtIGMxWzNdLngsIHk6IGMxWzFdLnkgLSBjMVszXS55fSwKLSAgICAgICAgICAgICAgICB7eDogYzJbMF0ueCAtIGMyWzJdLngsIHk6IGMyWzBdLnkgLSBjMlsyXS55fSwKLSAgICAgICAgICAgICAgICB7eDogYzJbMF0ueCAtIGMyWzFdLngsIHk6IGMyWzBdLnkgLSBjMlsxXS55fQotICAgICAgICAgICAgXTsKLSAgICAgICAgfSwKLQotICAgICAgICAvKioKLSAgICAgICAgICogUHJvamVjdCBhIHJlY3RhbmdsZSdzIGNvcm5lciBvbiBhbiBheGlzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9IENvb3JkaW5hdGVzIG9mIGEgY29ybmVyICh4LCB5KS4KLSAgICAgICAgICogQHBhcmFtICB7b2JqZWN0fSBDb29yZGluYXRlcyBvZiBhbiBheGlzICh4LCB5KS4KLSAgICAgICAgICogQHJldHVybiB7b2JqZWN0fSBUaGUgcHJvamVjdGlvbiBkZWZpbmVkIGJ5IGNvb3JkaW5hdGVzICh4LCB5KS4KLSAgICAgICAgICovCi0gICAgICAgIHByb2plY3Rpb246IGZ1bmN0aW9uIChjLCBhKSB7Ci0gICAgICAgICAgICB2YXIgbCA9ICgKLSAgICAgICAgICAgICAgICAoYy54ICogYS54ICsgYy55ICogYS55KSAvCi0gICAgICAgICAgICAgICAgKE1hdGgucG93KGEueCwgMikgKyBNYXRoLnBvdyhhLnksIDIpKQotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgICAgICB4OiBsICogYS54LAotICAgICAgICAgICAgICAgIHk6IGwgKiBhLnkKLSAgICAgICAgICAgIH07Ci0gICAgICAgIH0sCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENoZWNrIHdoZXRoZXIgdHdvIHJlY3RhbmdsZXMgY29sbGlkZSBvbiBvbmUgcGFydGljdWxhciBheGlzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgQW4gYXhpcycgY29vcmRpbmF0ZXMgKHgsIHkpLgotICAgICAgICAgKiBAcGFyYW0gIHthcnJheX0gICAgUmVjdGFuZ2xlIEEncyBjb3JuZXJzLgotICAgICAgICAgKiBAcGFyYW0gIHthcnJheX0gICAgUmVjdGFuZ2xlIEIncyBjb3JuZXJzLgotICAgICAgICAgKiBAcmV0dXJuIHtib29sZWFufSAgVHJ1ZSBpZiB0aGUgcmVjdGFuZ2xlcyBjb2xsaWRlIG9uIHRoZSBheGlzLgotICAgICAgICAgKi8KLSAgICAgICAgYXhpc0NvbGxpc2lvbjogZnVuY3Rpb24gKGEsIGMxLCBjMikgewotICAgICAgICAgICAgdmFyIHNjMSA9IFtdLAotICAgICAgICAgICAgICAgIHNjMiA9IFtdOwotCi0gICAgICAgICAgICBmb3IgKHZhciBjaSA9IDA7IGNpIDwgNDsgY2krKykgewotICAgICAgICAgICAgICAgIHZhciBwMSA9IHRoaXMucHJvamVjdGlvbihjMVtjaV0sIGEpLAotICAgICAgICAgICAgICAgICAgICBwMiA9IHRoaXMucHJvamVjdGlvbihjMltjaV0sIGEpOwotCi0gICAgICAgICAgICAgICAgc2MxLnB1c2gocDEueCAqIGEueCArIHAxLnkgKiBhLnkpOwotICAgICAgICAgICAgICAgIHNjMi5wdXNoKHAyLnggKiBhLnggKyBwMi55ICogYS55KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgdmFyIG1heGMxID0gTWF0aC5tYXguYXBwbHkoTWF0aCwgc2MxKSwKLSAgICAgICAgICAgICAgICBtYXhjMiA9IE1hdGgubWF4LmFwcGx5KE1hdGgsIHNjMiksCi0gICAgICAgICAgICAgICAgbWluYzEgPSBNYXRoLm1pbi5hcHBseShNYXRoLCBzYzEpLAotICAgICAgICAgICAgICAgIG1pbmMyID0gTWF0aC5taW4uYXBwbHkoTWF0aCwgc2MyKTsKLQotICAgICAgICAgICAgcmV0dXJuIChtaW5jMiA8PSBtYXhjMSAmJiBtYXhjMiA+PSBtaW5jMSk7Ci0gICAgICAgIH0sCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENoZWNrIHdoZXRoZXIgdHdvIHJlY3RhbmdsZXMgY29sbGlkZSBvbiBlYWNoIG9uZSBvZiB0aGVpciBmb3VyIGF4aXMuIElmCi0gICAgICAgICAqIGFsbCBheGlzIGNvbGxpZGUsIHRoZW4gdGhlIHR3byByZWN0YW5nbGVzIGRvIGNvbGxpZGUgb24gdGhlIHBsYW5lLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHthcnJheX0gICAgUmVjdGFuZ2xlIEEncyBjb3JuZXJzLgotICAgICAgICAgKiBAcGFyYW0gIHthcnJheX0gICAgUmVjdGFuZ2xlIEIncyBjb3JuZXJzLgotICAgICAgICAgKiBAcmV0dXJuIHtib29sZWFufSAgVHJ1ZSBpZiB0aGUgcmVjdGFuZ2xlcyBjb2xsaWRlLgotICAgICAgICAgKi8KLSAgICAgICAgY29sbGlzaW9uOiBmdW5jdGlvbiAoYzEsIGMyKSB7Ci0gICAgICAgICAgICB2YXIgYXhpcyA9IHRoaXMuYXhpcyhjMSwgYzIpLAotICAgICAgICAgICAgICAgIGNvbCA9IHRydWU7Ci0KLSAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKQotICAgICAgICAgICAgICAgIGNvbCA9IGNvbCAmJiB0aGlzLmF4aXNDb2xsaXNpb24oYXhpc1tpXSwgYzEsIGMyKTsKLQotICAgICAgICAgICAgcmV0dXJuIGNvbDsKLSAgICAgICAgfQotICAgIH07Ci0KLQotICAgIC8qKgotICAgICAqIFF1YWQgRnVuY3Rpb25zCi0gICAgICogLS0tLS0tLS0tLS0tCi0gICAgICoKLSAgICAgKiBUaGUgUXVhZHRyZWUgZnVuY3Rpb25zIHRoZW1zZWx2ZXMuCi0gICAgICogRm9yIGVhY2ggb2YgdGhvc2UgZnVuY3Rpb25zLCB3ZSBjb25zaWRlciB0aGF0IGluIGEgc3BsaXR0ZWQgcXVhZCwgdGhlCi0gICAgICogaW5kZXggb2YgZWFjaCBub2RlIGlzIHRoZSBmb2xsb3dpbmc6Ci0gICAgICogMDogdG9wIGxlZnQKLSAgICAgKiAxOiB0b3AgcmlnaHQKLSAgICAgKiAyOiBib3R0b20gbGVmdAotICAgICAqIDM6IGJvdHRvbSByaWdodAotICAgICAqCi0gICAgICogTW9yZW92ZXIsIHRoZSBoZXJlYWZ0ZXIgcXVhZCdzIHBoaWxvc29waHkgaXMgdG8gY29uc2lkZXIgdGhhdCBpZiBhbiBlbGVtZW50Ci0gICAgICogY29sbGlkZXMgd2l0aCBtb3JlIHRoYW4gb25lIG5vZGVzLCB0aGlzIGVsZW1lbnQgYmVsb25ncyB0byBlYWNoIG9mIHRoZQotICAgICAqIG5vZGVzIGl0IGNvbGxpZGVzIHdpdGggd2hlcmUgb3RoZXIgd291bGQgbGV0IGl0IGxpZSBvbiBhIGhpZ2hlciBub2RlLgotICAgICAqLwotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBpbmRleCBvZiB0aGUgbm9kZSBjb250YWluaW5nIHRoZSBwb2ludCBpbiB0aGUgcXVhZAotICAgICAqCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgcG9pbnQgICAgICBBIHBvaW50IGRlZmluZWQgYnkgY29vcmRpbmF0ZXMgKHgsIHkpLgotICAgICAqIEBwYXJhbSAge29iamVjdH0gIHF1YWRCb3VuZHMgQm91bmRhcmllcyBvZiB0aGUgcXVhZCAoeCwgeSwgd2lkdGgsIGhlaWd0aCkuCi0gICAgICogQHJldHVybiB7aW50ZWdlcn0gICAgICAgICAgICBUaGUgaW5kZXggb2YgdGhlIG5vZGUgY29udGFpbmluZyB0aGUgcG9pbnQuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX3F1YWRJbmRleChwb2ludCwgcXVhZEJvdW5kcykgewotICAgICAgICB2YXIgeG1wID0gcXVhZEJvdW5kcy54ICsgcXVhZEJvdW5kcy53aWR0aCAvIDIsCi0gICAgICAgICAgICB5bXAgPSBxdWFkQm91bmRzLnkgKyBxdWFkQm91bmRzLmhlaWdodCAvIDIsCi0gICAgICAgICAgICB0b3AgPSAocG9pbnQueSA8IHltcCksCi0gICAgICAgICAgICBsZWZ0ID0gKHBvaW50LnggPCB4bXApOwotCi0gICAgICAgIGlmICh0b3ApIHsKLSAgICAgICAgICAgIGlmIChsZWZ0KQotICAgICAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKGxlZnQpCi0gICAgICAgICAgICAgICAgcmV0dXJuIDI7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgcmV0dXJuIDM7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgYSBsaXN0IG9mIGluZGV4ZXMgb2Ygbm9kZXMgY29udGFpbmluZyBhbiBheGlzLWFsaWduZWQgcmVjdGFuZ2xlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICByZWN0YW5nbGUgICBBIHJlY3RhbmdsZSBkZWZpbmVkIGJ5IHR3byBwb2ludHMgKHgxLCB5MSksCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHgyLCB5MikgYW5kIGhlaWdodC4KLSAgICAgKiBAcGFyYW0gIHthcnJheX0gICBxdWFkQ29ybmVycyBBbiBhcnJheSBvZiB0aGUgcXVhZCBub2RlcycgY29ybmVycy4KLSAgICAgKiBAcmV0dXJuIHthcnJheX0gICAgICAgICAgICAgICBBbiBhcnJheSBvZiBpbmRleGVzIGNvbnRhaW5pbmcgb25lIHRvCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91ciBpbnRlZ2Vycy4KLSAgICAgKi8KLSAgICBmdW5jdGlvbiBfcXVhZEluZGV4ZXMocmVjdGFuZ2xlLCBxdWFkQ29ybmVycykgewotICAgICAgICB2YXIgaW5kZXhlcyA9IFtdOwotCi0gICAgICAgIC8vIEl0ZXJhdGluZyB0aHJvdWdoIHF1YWRzCi0gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKQotICAgICAgICAgICAgaWYgKChyZWN0YW5nbGUueDIgPj0gcXVhZENvcm5lcnNbaV1bMF0ueCkgJiYKLSAgICAgICAgICAgICAgICAocmVjdGFuZ2xlLngxIDw9IHF1YWRDb3JuZXJzW2ldWzFdLngpICYmCi0gICAgICAgICAgICAgICAgKHJlY3RhbmdsZS55MSArIHJlY3RhbmdsZS5oZWlnaHQgPj0gcXVhZENvcm5lcnNbaV1bMF0ueSkgJiYKLSAgICAgICAgICAgICAgICAocmVjdGFuZ2xlLnkxIDw9IHF1YWRDb3JuZXJzW2ldWzJdLnkpKQotICAgICAgICAgICAgICAgIGluZGV4ZXMucHVzaChpKTsKLQotICAgICAgICByZXR1cm4gaW5kZXhlczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgYSBsaXN0IG9mIGluZGV4ZXMgb2Ygbm9kZXMgY29udGFpbmluZyBhIG5vbi1heGlzLWFsaWduZWQgcmVjdGFuZ2xlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHthcnJheX0gIGNvcm5lcnMgICAgICBBbiBhcnJheSBjb250YWluaW5nIGVhY2ggY29ybmVyIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY3RhbmdsZSBkZWZpbmVkIGJ5IGl0cyBjb29yZGluYXRlcyAoeCwgeSkuCi0gICAgICogQHBhcmFtICB7YXJyYXl9ICBxdWFkQ29ybmVycyAgQW4gYXJyYXkgb2YgdGhlIHF1YWQgbm9kZXMnIGNvcm5lcnMuCi0gICAgICogQHJldHVybiB7YXJyYXl9ICAgICAgICAgICAgICAgQW4gYXJyYXkgb2YgaW5kZXhlcyBjb250YWluaW5nIG9uZSB0bwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdXIgaW50ZWdlcnMuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX3F1YWRDb2xsaXNpb24oY29ybmVycywgcXVhZENvcm5lcnMpIHsKLSAgICAgICAgdmFyIGluZGV4ZXMgPSBbXTsKLQotICAgICAgICAvLyBJdGVyYXRpbmcgdGhyb3VnaCBxdWFkcwotICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykKLSAgICAgICAgICAgIGlmIChfZ2VvbS5jb2xsaXNpb24oY29ybmVycywgcXVhZENvcm5lcnNbaV0pKQotICAgICAgICAgICAgICAgIGluZGV4ZXMucHVzaChpKTsKLQotICAgICAgICByZXR1cm4gaW5kZXhlczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTdWJkaXZpZGUgYSBxdWFkIGJ5IGNyZWF0aW5nIGEgbm9kZSBhdCBhIHByZWNpc2UgaW5kZXguIFRoZSBmdW5jdGlvbiBkb2VzCi0gICAgICogbm90IGdlbmVyYXRlIGFsbCBmb3VyIG5vZGVzIG5vdCB0byBwb3RlbnRpYWxseSBjcmVhdGUgdW51c2VkIG5vZGVzLgotICAgICAqCi0gICAgICogQHBhcmFtICB7aW50ZWdlcn0gIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgbm9kZSB0byBjcmVhdGUuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgIHF1YWQgIFRoZSBxdWFkIG9iamVjdCB0byBzdWJkaXZpZGUuCi0gICAgICogQHJldHVybiB7b2JqZWN0fSAgICAgICAgIEEgbmV3IHF1YWQgcmVwcmVzZW50aW5nIHRoZSBub2RlIGNyZWF0ZWQuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX3F1YWRTdWJkaXZpZGUoaW5kZXgsIHF1YWQpIHsKLSAgICAgICAgdmFyIG5leHQgPSBxdWFkLmxldmVsICsgMSwKLSAgICAgICAgICAgIHN1YncgPSBNYXRoLnJvdW5kKHF1YWQuYm91bmRzLndpZHRoIC8gMiksCi0gICAgICAgICAgICBzdWJoID0gTWF0aC5yb3VuZChxdWFkLmJvdW5kcy5oZWlnaHQgLyAyKSwKLSAgICAgICAgICAgIHF4ID0gTWF0aC5yb3VuZChxdWFkLmJvdW5kcy54KSwKLSAgICAgICAgICAgIHF5ID0gTWF0aC5yb3VuZChxdWFkLmJvdW5kcy55KSwKLSAgICAgICAgICAgIHgsCi0gICAgICAgICAgICB5OwotCi0gICAgICAgIHN3aXRjaCAoaW5kZXgpIHsKLSAgICAgICAgICAgIGNhc2UgMDoKLSAgICAgICAgICAgICAgICB4ID0gcXg7Ci0gICAgICAgICAgICAgICAgeSA9IHF5OwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSAxOgotICAgICAgICAgICAgICAgIHggPSBxeCArIHN1Ync7Ci0gICAgICAgICAgICAgICAgeSA9IHF5OwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSAyOgotICAgICAgICAgICAgICAgIHggPSBxeDsKLSAgICAgICAgICAgICAgICB5ID0gcXkgKyBzdWJoOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSAzOgotICAgICAgICAgICAgICAgIHggPSBxeCArIHN1Ync7Ci0gICAgICAgICAgICAgICAgeSA9IHF5ICsgc3ViaDsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBfcXVhZFRyZWUoCi0gICAgICAgICAgICB7eDogeCwgeTogeSwgd2lkdGg6IHN1YncsIGhlaWdodDogc3ViaH0sCi0gICAgICAgICAgICBuZXh0LAotICAgICAgICAgICAgcXVhZC5tYXhFbGVtZW50cywKLSAgICAgICAgICAgIHF1YWQubWF4TGV2ZWwKLSAgICAgICAgKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWN1cnNpdmVseSBpbnNlcnQgYW4gZWxlbWVudCBpbnRvIHRoZSBxdWFkdHJlZS4gT25seSBwb2ludHMKLSAgICAgKiB3aXRoIHNpemUsIGkuZS4gYXhpcy1hbGlnbmVkIHNxdWFyZXMsIG1heSBiZSBpbnNlcnRlZCB3aXRoIHRoaXMKLSAgICAgKiBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICBlbCAgICAgICAgIFRoZSBlbGVtZW50IHRvIGluc2VydCBpbiB0aGUgcXVhZHRyZWUuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgc2l6ZWRQb2ludCBBIHNpemVkIHBvaW50IGRlZmluZWQgYnkgdHdvIHRvcCBwb2ludHMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh4MSwgeTEpLCAoeDIsIHkyKSBhbmQgaGVpZ2h0LgotICAgICAqIEBwYXJhbSAge29iamVjdH0gIHF1YWQgICAgICAgVGhlIHF1YWQgaW4gd2hpY2ggdG8gaW5zZXJ0IHRoZSBlbGVtZW50LgotICAgICAqIEByZXR1cm4ge3VuZGVmaW5lZH0gICAgICAgICAgVGhlIGZ1bmN0aW9uIGRvZXMgbm90IHJldHVybiBhbnl0aGluZy4KLSAgICAgKi8KLSAgICBmdW5jdGlvbiBfcXVhZEluc2VydChlbCwgc2l6ZWRQb2ludCwgcXVhZCkgewotICAgICAgICBpZiAocXVhZC5sZXZlbCA8IHF1YWQubWF4TGV2ZWwpIHsKLQotICAgICAgICAgICAgLy8gU2VhcmNoaW5nIGFwcHJvcHJpYXRlIHF1YWRzCi0gICAgICAgICAgICB2YXIgaW5kZXhlcyA9IF9xdWFkSW5kZXhlcyhzaXplZFBvaW50LCBxdWFkLmNvcm5lcnMpOwotCi0gICAgICAgICAgICAvLyBJdGVyYXRpbmcKLSAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gaW5kZXhlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKLQotICAgICAgICAgICAgICAgIC8vIFN1YmRpdmlkaW5nIGlmIG5lY2Vzc2FyeQotICAgICAgICAgICAgICAgIGlmIChxdWFkLm5vZGVzW2luZGV4ZXNbaV1dID09PSB1bmRlZmluZWQpCi0gICAgICAgICAgICAgICAgICAgIHF1YWQubm9kZXNbaW5kZXhlc1tpXV0gPSBfcXVhZFN1YmRpdmlkZShpbmRleGVzW2ldLCBxdWFkKTsKLQotICAgICAgICAgICAgICAgIC8vIFJlY3Vyc2lvbgotICAgICAgICAgICAgICAgIF9xdWFkSW5zZXJ0KGVsLCBzaXplZFBvaW50LCBxdWFkLm5vZGVzW2luZGV4ZXNbaV1dKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLQotICAgICAgICAgICAgLy8gUHVzaGluZyB0aGUgZWxlbWVudCBpbiBhIGxlYWYgbm9kZQotICAgICAgICAgICAgcXVhZC5lbGVtZW50cy5wdXNoKGVsKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlY3Vyc2l2ZWx5IHJldHJpZXZlIGV2ZXJ5IGVsZW1lbnRzIGhlbGQgYnkgdGhlIG5vZGUgY29udGFpbmluZyB0aGUKLSAgICAgKiBzZWFyY2hlZCBwb2ludC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdH0gIHBvaW50IFRoZSBzZWFyY2hlZCBwb2ludCAoeCwgeSkuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgcXVhZCAgVGhlIHNlYXJjaGVkIHF1YWQuCi0gICAgICogQHJldHVybiB7YXJyYXl9ICAgICAgICAgQW4gYXJyYXkgb2YgZWxlbWVudHMgY29udGFpbmVkIGluIHRoZSByZWxldmFudAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuCi0gICAgICovCi0gICAgZnVuY3Rpb24gX3F1YWRSZXRyaWV2ZVBvaW50KHBvaW50LCBxdWFkKSB7Ci0gICAgICAgIGlmIChxdWFkLmxldmVsIDwgcXVhZC5tYXhMZXZlbCkgewotICAgICAgICAgICAgdmFyIGluZGV4ID0gX3F1YWRJbmRleChwb2ludCwgcXVhZC5ib3VuZHMpOwotCi0gICAgICAgICAgICAvLyBJZiBub2RlIGRvZXMgbm90IGV4aXN0IHdlIHJldHVybiBhbiBlbXB0eSBsaXN0Ci0gICAgICAgICAgICBpZiAocXVhZC5ub2Rlc1tpbmRleF0gIT09IHVuZGVmaW5lZCkgewotICAgICAgICAgICAgICAgIHJldHVybiBfcXVhZFJldHJpZXZlUG9pbnQocG9pbnQsIHF1YWQubm9kZXNbaW5kZXhdKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBbXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBxdWFkLmVsZW1lbnRzOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjdXJzaXZlbHkgcmV0cmlldmUgZXZlcnkgZWxlbWVudHMgY29udGFpbmVkIHdpdGhpbiBhbiByZWN0YW5ndWxhciBhcmVhCi0gICAgICogdGhhdCBtYXkgb3IgbWF5IG5vdCBiZSBheGlzLWFsaWduZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtvYmplY3R8YXJyYXl9IHJlY3REYXRhICAgICAgIFRoZSBzZWFyY2hlZCBhcmVhIGRlZmluZWQgZWl0aGVyIGJ5Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbiBhcnJheSBvZiBmb3VyIGNvcm5lcnMgKHgsIHkpIGluCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgY2FzZSBvZiBhIG5vbi1heGlzLWFsaWduZWQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY3RhbmdsZSBvciBhbiBvYmplY3Qgd2l0aCB0d28gdG9wCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2ludHMgKHgxLCB5MSksICh4MiwgeTIpIGFuZCBoZWlnaHQuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICBxdWFkICAgICAgICAgICBUaGUgc2VhcmNoZWQgcXVhZC4KLSAgICAgKiBAcGFyYW0gIHtmdW5jdGlvbn0gICAgIGNvbGxpc2lvbkZ1bmMgIFRoZSBjb2xsaXNpb24gZnVuY3Rpb24gdXNlZCB0byBzZWFyY2gKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBub2RlIGluZGV4ZXMuCi0gICAgICogQHBhcmFtICB7YXJyYXk/fSAgICAgICBlbHMgICAgICAgICAgICBUaGUgcmV0cmlldmVkIGVsZW1lbnRzLgotICAgICAqIEByZXR1cm4ge2FycmF5fSAgICAgICAgICAgICAgICAgICAgICAgQW4gYXJyYXkgb2YgZWxlbWVudHMgY29udGFpbmVkIGluIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJlYS4KLSAgICAgKi8KLSAgICBmdW5jdGlvbiBfcXVhZFJldHJpZXZlQXJlYShyZWN0RGF0YSwgcXVhZCwgY29sbGlzaW9uRnVuYywgZWxzKSB7Ci0gICAgICAgIGVscyA9IGVscyB8fCB7fTsKLQotICAgICAgICBpZiAocXVhZC5sZXZlbCA8IHF1YWQubWF4TGV2ZWwpIHsKLSAgICAgICAgICAgIHZhciBpbmRleGVzID0gY29sbGlzaW9uRnVuYyhyZWN0RGF0YSwgcXVhZC5jb3JuZXJzKTsKLQotICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBpbmRleGVzLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgICAgICBpZiAocXVhZC5ub2Rlc1tpbmRleGVzW2ldXSAhPT0gdW5kZWZpbmVkKQotICAgICAgICAgICAgICAgICAgICBfcXVhZFJldHJpZXZlQXJlYSgKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlY3REYXRhLAotICAgICAgICAgICAgICAgICAgICAgICAgcXVhZC5ub2Rlc1tpbmRleGVzW2ldXSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxpc2lvbkZ1bmMsCi0gICAgICAgICAgICAgICAgICAgICAgICBlbHMKLSAgICAgICAgICAgICAgICAgICAgKTsKLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICBmb3IgKHZhciBqID0gMCwgbSA9IHF1YWQuZWxlbWVudHMubGVuZ3RoOyBqIDwgbTsgaisrKQotICAgICAgICAgICAgICAgIGlmIChlbHNbcXVhZC5lbGVtZW50c1tqXS5pZF0gPT09IHVuZGVmaW5lZCkKLSAgICAgICAgICAgICAgICAgICAgZWxzW3F1YWQuZWxlbWVudHNbal0uaWRdID0gcXVhZC5lbGVtZW50c1tqXTsKLQotICAgICAgICByZXR1cm4gZWxzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgdGhlIHF1YWR0cmVlIG9iamVjdCBpdHNlbGYuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgYm91bmRzICAgICAgIFRoZSBib3VuZGFyaWVzIG9mIHRoZSBxdWFkIGRlZmluZWQgYnkgYW4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbiAoeCwgeSksIHdpZHRoIGFuZCBoZWlndGguCi0gICAgICogQHBhcmFtICB7aW50ZWdlcn0gIGxldmVsICAgICAgICBUaGUgbGV2ZWwgb2YgdGhlIHF1YWQgaW4gdGhlIHRyZWUuCi0gICAgICogQHBhcmFtICB7aW50ZWdlcn0gIG1heEVsZW1lbnRzICBUaGUgbWF4IG51bWJlciBvZiBlbGVtZW50IGluIGEgbGVhZiBub2RlLgotICAgICAqIEBwYXJhbSAge2ludGVnZXJ9ICBtYXhMZXZlbCAgICAgVGhlIG1heCByZWN1cnNpb24gbGV2ZWwgb2YgdGhlIHRyZWUuCi0gICAgICogQHJldHVybiB7b2JqZWN0fSAgICAgICAgICAgICAgICBUaGUgcXVhZHRyZWUgb2JqZWN0LgotICAgICAqLwotICAgIGZ1bmN0aW9uIF9xdWFkVHJlZShib3VuZHMsIGxldmVsLCBtYXhFbGVtZW50cywgbWF4TGV2ZWwpIHsKLSAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgIGxldmVsOiBsZXZlbCB8fCAwLAotICAgICAgICAgICAgYm91bmRzOiBib3VuZHMsCi0gICAgICAgICAgICBjb3JuZXJzOiBfZ2VvbS5zcGxpdFNxdWFyZShib3VuZHMpLAotICAgICAgICAgICAgbWF4RWxlbWVudHM6IG1heEVsZW1lbnRzIHx8IDQwLAotICAgICAgICAgICAgbWF4TGV2ZWw6IG1heExldmVsIHx8IDgsCi0gICAgICAgICAgICBlbGVtZW50czogW10sCi0gICAgICAgICAgICBub2RlczogW10KLSAgICAgICAgfTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNpZ21hIFF1YWQgQ29uc3RydWN0b3IKLSAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICoKLSAgICAgKiBUaGUgZWRnZXF1YWQgQVBJIGFzIGV4cG9zZWQgdG8gc2lnbWEuCi0gICAgICovCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZWRnZXF1YWQgY29yZSB0aGF0IHdpbGwgYmVjb21lIHRoZSBzaWdtYSBpbnRlcmZhY2Ugd2l0aCB0aGUgcXVhZHRyZWUuCi0gICAgICoKLSAgICAgKiBwcm9wZXJ0eSB7b2JqZWN0fSBfdHJlZSAgICAgUHJvcGVydHkgaG9sZGluZyB0aGUgcXVhZHRyZWUgb2JqZWN0LgotICAgICAqIHByb3BlcnR5IHtvYmplY3R9IF9nZW9tICAgICBFeHBvc2l0aW9uIG9mIHRoZSBfZ2VvbSBuYW1lc3BhY2UgZm9yIHRlc3RpbmcuCi0gICAgICogcHJvcGVydHkge29iamVjdH0gX2NhY2hlICAgIENhY2hlIGZvciB0aGUgYXJlYSBtZXRob2QuCi0gICAgICogcHJvcGVydHkge2Jvb2xlYW59IF9lbmFibGVkIENhbiBpbmRleCBhbmQgcmV0cmVpdmUgZWxlbWVudHMuCi0gICAgICovCi0gICAgdmFyIGVkZ2VxdWFkID0gZnVuY3Rpb24gKCkgewotICAgICAgICB0aGlzLl9nZW9tID0gX2dlb207Ci0gICAgICAgIHRoaXMuX3RyZWUgPSBudWxsOwotICAgICAgICB0aGlzLl9jYWNoZSA9IHsKLSAgICAgICAgICAgIHF1ZXJ5OiBmYWxzZSwKLSAgICAgICAgICAgIHJlc3VsdDogZmFsc2UKLSAgICAgICAgfTsKLSAgICAgICAgdGhpcy5fZW5hYmxlZCA9IHRydWU7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIEluZGV4IGEgZ3JhcGggYnkgaW5zZXJ0aW5nIGl0cyBlZGdlcyBpbnRvIHRoZSBxdWFkdHJlZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdH0gZ3JhcGggICBBIGdyYXBoIGluc3RhbmNlLgotICAgICAqIEBwYXJhbSAge29iamVjdH0gcGFyYW1zICBBbiBvYmplY3Qgb2YgcGFyYW1ldGVycyB3aXRoIGF0IGxlYXN0IHRoZSBxdWFkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kcy4KLSAgICAgKiBAcmV0dXJuIHtvYmplY3R9ICAgICAgICAgVGhlIHF1YWR0cmVlIG9iamVjdC4KLSAgICAgKgotICAgICAqIFBhcmFtZXRlcnM6Ci0gICAgICogLS0tLS0tLS0tLQotICAgICAqIGJvdW5kczogICAgICB7b2JqZWN0fSAgIGJvdW5kYXJpZXMgb2YgdGhlIHF1YWQgZGVmaW5lZCBieSBpdHMgb3JpZ2luICh4LCB5KQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoIGFuZCBoZWlndGguCi0gICAgICogcHJlZml4OiAgICAgIHtzdHJpbmc/fSAgYSBwcmVmaXggZm9yIGVkZ2UgZ2VvbWV0cmljIGF0dHJpYnV0ZXMuCi0gICAgICogbWF4RWxlbWVudHM6IHtpbnRlZ2VyP30gdGhlIG1heCBudW1iZXIgb2YgZWxlbWVudHMgaW4gYSBsZWFmIG5vZGUuCi0gICAgICogbWF4TGV2ZWw6ICAgIHtpbnRlZ2VyP30gdGhlIG1heCByZWN1cnNpb24gbGV2ZWwgb2YgdGhlIHRyZWUuCi0gICAgICovCi0gICAgZWRnZXF1YWQucHJvdG90eXBlLmluZGV4ID0gZnVuY3Rpb24gKGdyYXBoLCBwYXJhbXMpIHsKLSAgICAgICAgaWYgKCF0aGlzLl9lbmFibGVkKQotICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RyZWU7Ci0KLSAgICAgICAgLy8gRW5mb3JjaW5nIHByZXNlbmNlIG9mIGJvdW5kYXJpZXMKLSAgICAgICAgaWYgKCFwYXJhbXMuYm91bmRzKQotICAgICAgICAgICAgdGhyb3cgJ3NpZ21hLmNsYXNzZXMuZWRnZXF1YWQuaW5kZXg6IGJvdW5kcyBpbmZvcm1hdGlvbiBub3QgZ2l2ZW4uJzsKLQotICAgICAgICAvLyBQcmVmaXgKLSAgICAgICAgdmFyIHByZWZpeCA9IHBhcmFtcy5wcmVmaXggfHwgJycsCi0gICAgICAgICAgICBjcCwKLSAgICAgICAgICAgIHNvdXJjZSwKLSAgICAgICAgICAgIHRhcmdldCwKLSAgICAgICAgICAgIG4sCi0gICAgICAgICAgICBlOwotCi0gICAgICAgIC8vIEJ1aWxkaW5nIHRoZSB0cmVlCi0gICAgICAgIHRoaXMuX3RyZWUgPSBfcXVhZFRyZWUoCi0gICAgICAgICAgICBwYXJhbXMuYm91bmRzLAotICAgICAgICAgICAgMCwKLSAgICAgICAgICAgIHBhcmFtcy5tYXhFbGVtZW50cywKLSAgICAgICAgICAgIHBhcmFtcy5tYXhMZXZlbAotICAgICAgICApOwotCi0gICAgICAgIHZhciBlZGdlcyA9IGdyYXBoLmVkZ2VzKCk7Ci0KLSAgICAgICAgLy8gSW5zZXJ0aW5nIGdyYXBoIGVkZ2VzIGludG8gdGhlIHRyZWUKLSAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBlZGdlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKLSAgICAgICAgICAgIHNvdXJjZSA9IGdyYXBoLm5vZGVzKGVkZ2VzW2ldLnNvdXJjZSk7Ci0gICAgICAgICAgICB0YXJnZXQgPSBncmFwaC5ub2RlcyhlZGdlc1tpXS50YXJnZXQpOwotICAgICAgICAgICAgZSA9IHsKLSAgICAgICAgICAgICAgICB4MTogc291cmNlW3ByZWZpeCArICd4J10sCi0gICAgICAgICAgICAgICAgeTE6IHNvdXJjZVtwcmVmaXggKyAneSddLAotICAgICAgICAgICAgICAgIHgyOiB0YXJnZXRbcHJlZml4ICsgJ3gnXSwKLSAgICAgICAgICAgICAgICB5MjogdGFyZ2V0W3ByZWZpeCArICd5J10sCi0gICAgICAgICAgICAgICAgc2l6ZTogZWRnZXNbaV1bcHJlZml4ICsgJ3NpemUnXSB8fCAwCi0gICAgICAgICAgICB9OwotCi0gICAgICAgICAgICAvLyBJbnNlcnRpbmcgZWRnZQotICAgICAgICAgICAgaWYgKGVkZ2VzW2ldLnR5cGUgPT09ICdjdXJ2ZScgfHwgZWRnZXNbaV0udHlwZSA9PT0gJ2N1cnZlZEFycm93JykgewotICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuaWQgPT09IHRhcmdldC5pZCkgewotICAgICAgICAgICAgICAgICAgICBuID0gewotICAgICAgICAgICAgICAgICAgICAgICAgeDogc291cmNlW3ByZWZpeCArICd4J10sCi0gICAgICAgICAgICAgICAgICAgICAgICB5OiBzb3VyY2VbcHJlZml4ICsgJ3knXSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHNpemU6IHNvdXJjZVtwcmVmaXggKyAnc2l6ZSddIHx8IDAKLSAgICAgICAgICAgICAgICAgICAgfTsKLSAgICAgICAgICAgICAgICAgICAgX3F1YWRJbnNlcnQoCi0gICAgICAgICAgICAgICAgICAgICAgICBlZGdlc1tpXSwKLSAgICAgICAgICAgICAgICAgICAgICAgIF9nZW9tLnNlbGZMb29wVG9TcXVhcmUobiksCi0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGNwID0gc2lnbWEudXRpbHMuZ2V0UXVhZHJhdGljQ29udHJvbFBvaW50KGUueDEsIGUueTEsIGUueDIsIGUueTIpOwotICAgICAgICAgICAgICAgICAgICBfcXVhZEluc2VydCgKLSAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2VzW2ldLAotICAgICAgICAgICAgICAgICAgICAgICAgX2dlb20ucXVhZHJhdGljQ3VydmVUb1NxdWFyZShlLCBjcCksCi0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBfcXVhZEluc2VydCgKLSAgICAgICAgICAgICAgICAgICAgZWRnZXNbaV0sCi0gICAgICAgICAgICAgICAgICAgIF9nZW9tLmxpbmVUb1NxdWFyZShlKSwKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5fdHJlZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBSZXNldCBjYWNoZToKLSAgICAgICAgdGhpcy5fY2FjaGUgPSB7Ci0gICAgICAgICAgICBxdWVyeTogZmFsc2UsCi0gICAgICAgICAgICByZXN1bHQ6IGZhbHNlCi0gICAgICAgIH07Ci0KLSAgICAgICAgLy8gcmVtb3ZlPwotICAgICAgICByZXR1cm4gdGhpcy5fdHJlZTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogUmV0cmlldmUgZXZlcnkgZ3JhcGggZWRnZXMgaGVsZCBieSB0aGUgcXVhZHRyZWUgbm9kZSBjb250YWluaW5nIHRoZQotICAgICAqIHNlYXJjaGVkIHBvaW50LgotICAgICAqCi0gICAgICogQHBhcmFtICB7bnVtYmVyfSB4IG9mIHRoZSBwb2ludC4KLSAgICAgKiBAcGFyYW0gIHtudW1iZXJ9IHkgb2YgdGhlIHBvaW50LgotICAgICAqIEByZXR1cm4ge2FycmF5fSAgQW4gYXJyYXkgb2YgZWRnZXMgcmV0cmlldmVkLgotICAgICAqLwotICAgIGVkZ2VxdWFkLnByb3RvdHlwZS5wb2ludCA9IGZ1bmN0aW9uICh4LCB5KSB7Ci0gICAgICAgIGlmICghdGhpcy5fZW5hYmxlZCkKLSAgICAgICAgICAgIHJldHVybiBbXTsKLQotICAgICAgICByZXR1cm4gdGhpcy5fdHJlZSA/Ci0gICAgICAgIF9xdWFkUmV0cmlldmVQb2ludCh7eDogeCwgeTogeX0sIHRoaXMuX3RyZWUpIHx8IFtdIDoKLSAgICAgICAgICAgIFtdOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZSBldmVyeSBncmFwaCBlZGdlcyB3aXRoaW4gYSByZWN0YW5ndWxhciBhcmVhLiBUaGUgbWV0aG9kcyBrZWVwIHRoZQotICAgICAqIGxhc3QgYXJlYSBxdWVyaWVkIGluIGNhY2hlIGZvciBvcHRpbWl6YXRpb24gcmVhc29uIGFuZCB3aWxsIGFjdCBkaWZmZXJlbnRseQotICAgICAqIGZvciB0aGUgc2FtZSByZWFzb24gaWYgdGhlIGFyZWEgaXMgYXhpcy1hbGlnbmVkIG9yIG5vdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdH0gQSByZWN0YW5nbGUgZGVmaW5lZCBieSB0d28gdG9wIHBvaW50cyAoeDEsIHkxKSwgKHgyLCB5MikKLSAgICAgKiAgICAgICAgICAgICAgICAgIGFuZCBoZWlnaHQuCi0gICAgICogQHJldHVybiB7YXJyYXl9ICBBbiBhcnJheSBvZiBlZGdlcyByZXRyaWV2ZWQuCi0gICAgICovCi0gICAgZWRnZXF1YWQucHJvdG90eXBlLmFyZWEgPSBmdW5jdGlvbiAocmVjdCkgewotICAgICAgICBpZiAoIXRoaXMuX2VuYWJsZWQpCi0gICAgICAgICAgICByZXR1cm4gW107Ci0KLSAgICAgICAgdmFyIHNlcmlhbGl6ZWQgPSBKU09OLnN0cmluZ2lmeShyZWN0KSwKLSAgICAgICAgICAgIGNvbGxpc2lvbkZ1bmMsCi0gICAgICAgICAgICByZWN0RGF0YTsKLQotICAgICAgICAvLyBSZXR1cm5pbmcgY2FjaGU/Ci0gICAgICAgIGlmICh0aGlzLl9jYWNoZS5xdWVyeSA9PT0gc2VyaWFsaXplZCkKLSAgICAgICAgICAgIHJldHVybiB0aGlzLl9jYWNoZS5yZXN1bHQ7Ci0KLSAgICAgICAgLy8gQXhpcyBhbGlnbmVkID8KLSAgICAgICAgaWYgKF9nZW9tLmlzQXhpc0FsaWduZWQocmVjdCkpIHsKLSAgICAgICAgICAgIGNvbGxpc2lvbkZ1bmMgPSBfcXVhZEluZGV4ZXM7Ci0gICAgICAgICAgICByZWN0RGF0YSA9IF9nZW9tLmF4aXNBbGlnbmVkVG9wUG9pbnRzKHJlY3QpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgY29sbGlzaW9uRnVuYyA9IF9xdWFkQ29sbGlzaW9uOwotICAgICAgICAgICAgcmVjdERhdGEgPSBfZ2VvbS5yZWN0YW5nbGVDb3JuZXJzKHJlY3QpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUmV0cmlldmluZyBlZGdlcwotICAgICAgICB2YXIgZWRnZXMgPSB0aGlzLl90cmVlID8KLSAgICAgICAgICAgIF9xdWFkUmV0cmlldmVBcmVhKAotICAgICAgICAgICAgICAgIHJlY3REYXRhLAotICAgICAgICAgICAgICAgIHRoaXMuX3RyZWUsCi0gICAgICAgICAgICAgICAgY29sbGlzaW9uRnVuYwotICAgICAgICAgICAgKSA6Ci0gICAgICAgICAgICBbXTsKLQotICAgICAgICAvLyBPYmplY3QgdG8gYXJyYXkKLSAgICAgICAgdmFyIGVkZ2VzQXJyYXkgPSBbXTsKLSAgICAgICAgZm9yICh2YXIgaSBpbiBlZGdlcykKLSAgICAgICAgICAgIGVkZ2VzQXJyYXkucHVzaChlZGdlc1tpXSk7Ci0KLSAgICAgICAgLy8gQ2FjaGluZwotICAgICAgICB0aGlzLl9jYWNoZS5xdWVyeSA9IHNlcmlhbGl6ZWQ7Ci0gICAgICAgIHRoaXMuX2NhY2hlLnJlc3VsdCA9IGVkZ2VzQXJyYXk7Ci0KLSAgICAgICAgcmV0dXJuIGVkZ2VzQXJyYXk7Ci0gICAgfTsKLQotCi0gICAgLyoqCi0gICAgICogRVhQT1JUOgotICAgICAqICoqKioqKioKLSAgICAgKi8KLSAgICBpZiAodHlwZW9mIHRoaXMuc2lnbWEgIT09ICd1bmRlZmluZWQnKSB7Ci0gICAgICAgIHRoaXMuc2lnbWEuY2xhc3NlcyA9IHRoaXMuc2lnbWEuY2xhc3NlcyB8fCB7fTsKLSAgICAgICAgdGhpcy5zaWdtYS5jbGFzc2VzLmVkZ2VxdWFkID0gZWRnZXF1YWQ7Ci0gICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHsKLSAgICAgICAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKQotICAgICAgICAgICAgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZWRnZXF1YWQ7Ci0gICAgICAgIGV4cG9ydHMuZWRnZXF1YWQgPSBlZGdlcXVhZDsKLSAgICB9IGVsc2UKLSAgICAgICAgdGhpcy5lZGdlcXVhZCA9IGVkZ2VxdWFkOwotfSkuY2FsbCh0aGlzKTsKLQotOyhmdW5jdGlvbiAodW5kZWZpbmVkKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgaWYgKHR5cGVvZiBzaWdtYSA9PT0gJ3VuZGVmaW5lZCcpCi0gICAgICAgIHRocm93ICdzaWdtYSBpcyBub3QgZGVjbGFyZWQnOwotCi0gICAgLy8gSW5pdGlhbGl6ZSBwYWNrYWdlczoKLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLmNhcHRvcnMnKTsKLQotICAgIC8qKgotICAgICAqIFRoZSB1c2VyIGlucHV0cyBkZWZhdWx0IGNhcHRvci4gSXQgZGVhbHMgd2l0aCBtb3VzZSBldmVudHMsIGtleWJvYXJkcwotICAgICAqIGV2ZW50cyBhbmQgdG91Y2ggZXZlbnRzLgotICAgICAqCi0gICAgICogQHBhcmFtICB7RE9NRWxlbWVudH0gICB0YXJnZXQgICBUaGUgRE9NIGVsZW1lbnQgd2hlcmUgdGhlIGxpc3RlbmVycyB3aWxsIGJlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3VuZC4KLSAgICAgKiBAcGFyYW0gIHtjYW1lcmF9ICAgICAgIGNhbWVyYSAgIFRoZSBjYW1lcmEgcmVsYXRlZCB0byB0aGUgdGFyZ2V0LgotICAgICAqIEBwYXJhbSAge2NvbmZpZ3VyYWJsZX0gc2V0dGluZ3MgVGhlIHNldHRpbmdzIGZ1bmN0aW9uLgotICAgICAqIEByZXR1cm4ge3NpZ21hLmNhcHRvcn0gICAgICAgICAgVGhlIGZyZXNoIG5ldyBjYXB0b3IgaW5zdGFuY2UuCi0gICAgICovCi0gICAgc2lnbWEuY2FwdG9ycy5tb3VzZSA9IGZ1bmN0aW9uICh0YXJnZXQsIGNhbWVyYSwgc2V0dGluZ3MpIHsKLSAgICAgICAgdmFyIF9zZWxmID0gdGhpcywKLSAgICAgICAgICAgIF90YXJnZXQgPSB0YXJnZXQsCi0gICAgICAgICAgICBfY2FtZXJhID0gY2FtZXJhLAotICAgICAgICAgICAgX3NldHRpbmdzID0gc2V0dGluZ3MsCi0KLSAgICAgICAgICAgIC8vIENBTUVSQSBNQU5BR0VNRU5UOgotICAgICAgICAgICAgLy8gKioqKioqKioqKioqKioqKioqCi0gICAgICAgICAgICAvLyBUaGUgY2FtZXJhIHBvc2l0aW9uIHdoZW4gdGhlIHVzZXIgc3RhcnRzIGRyYWdnaW5nOgotICAgICAgICAgICAgX3N0YXJ0Q2FtZXJhWCwKLSAgICAgICAgICAgIF9zdGFydENhbWVyYVksCi0gICAgICAgICAgICBfc3RhcnRDYW1lcmFBbmdsZSwKLQotICAgICAgICAgICAgLy8gVGhlIGxhdGVzdCBzdGFnZSBwb3NpdGlvbjoKLSAgICAgICAgICAgIF9sYXN0Q2FtZXJhWCwKLSAgICAgICAgICAgIF9sYXN0Q2FtZXJhWSwKLSAgICAgICAgICAgIF9sYXN0Q2FtZXJhQW5nbGUsCi0gICAgICAgICAgICBfbGFzdENhbWVyYVJhdGlvLAotCi0gICAgICAgICAgICAvLyBNT1VTRSBNQU5BR0VNRU5UOgotICAgICAgICAgICAgLy8gKioqKioqKioqKioqKioqKioKLSAgICAgICAgICAgIC8vIFRoZSBtb3VzZSBwb3NpdGlvbiB3aGVuIHRoZSB1c2VyIHN0YXJ0cyBkcmFnZ2luZzoKLSAgICAgICAgICAgIF9zdGFydE1vdXNlWCwKLSAgICAgICAgICAgIF9zdGFydE1vdXNlWSwKLQotICAgICAgICAgICAgX2lzTW91c2VEb3duLAotICAgICAgICAgICAgX2lzTW92aW5nLAotICAgICAgICAgICAgX2hhc0RyYWdnZWQsCi0gICAgICAgICAgICBfZG93blN0YXJ0VGltZSwKLSAgICAgICAgICAgIF9tb3ZpbmdUaW1lb3V0SWQ7Ci0KLSAgICAgICAgc2lnbWEuY2xhc3Nlcy5kaXNwYXRjaGVyLmV4dGVuZCh0aGlzKTsKLQotICAgICAgICBzaWdtYS51dGlscy5kb3VibGVDbGljayhfdGFyZ2V0LCAnY2xpY2snLCBfZG91YmxlQ2xpY2tIYW5kbGVyKTsKLSAgICAgICAgX3RhcmdldC5hZGRFdmVudExpc3RlbmVyKCdET01Nb3VzZVNjcm9sbCcsIF93aGVlbEhhbmRsZXIsIGZhbHNlKTsKLSAgICAgICAgX3RhcmdldC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXdoZWVsJywgX3doZWVsSGFuZGxlciwgZmFsc2UpOwotICAgICAgICBfdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIF9tb3ZlSGFuZGxlciwgZmFsc2UpOwotICAgICAgICBfdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIF9kb3duSGFuZGxlciwgZmFsc2UpOwotICAgICAgICBfdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgX2NsaWNrSGFuZGxlciwgZmFsc2UpOwotICAgICAgICBfdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3V0JywgX291dEhhbmRsZXIsIGZhbHNlKTsKLSAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIF91cEhhbmRsZXIsIGZhbHNlKTsKLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUaGlzIG1ldGhvZCB1bmJpbmRzIGV2ZXJ5IGhhbmRsZXJzIHRoYXQgbWFrZXMgdGhlIGNhcHRvciB3b3JrLgotICAgICAgICAgKi8KLSAgICAgICAgdGhpcy5raWxsID0gZnVuY3Rpb24gKCkgewotICAgICAgICAgICAgc2lnbWEudXRpbHMudW5iaW5kRG91YmxlQ2xpY2soX3RhcmdldCwgJ2NsaWNrJyk7Ci0gICAgICAgICAgICBfdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ0RPTU1vdXNlU2Nyb2xsJywgX3doZWVsSGFuZGxlcik7Ci0gICAgICAgICAgICBfdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNld2hlZWwnLCBfd2hlZWxIYW5kbGVyKTsKLSAgICAgICAgICAgIF90YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgX21vdmVIYW5kbGVyKTsKLSAgICAgICAgICAgIF90YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgX2Rvd25IYW5kbGVyKTsKLSAgICAgICAgICAgIF90YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBfY2xpY2tIYW5kbGVyKTsKLSAgICAgICAgICAgIF90YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VvdXQnLCBfb3V0SGFuZGxlcik7Ci0gICAgICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgX3VwSGFuZGxlcik7Ci0gICAgICAgIH07Ci0KLQotICAgICAgICAvLyBNT1VTRSBFVkVOVFM6Ci0gICAgICAgIC8vICoqKioqKioqKioqKioKLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhlIGhhbmRsZXIgbGlzdGVuaW5nIHRvIHRoZSAnbW92ZScgbW91c2UgZXZlbnQuIEl0IHdpbGwgZWZmZWN0aXZlbHkKLSAgICAgICAgICogZHJhZyB0aGUgZ3JhcGguCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSB7ZXZlbnR9IGUgQSBtb3VzZSBldmVudC4KLSAgICAgICAgICovCi0gICAgICAgIGZ1bmN0aW9uIF9tb3ZlSGFuZGxlcihlKSB7Ci0gICAgICAgICAgICB2YXIgeCwKLSAgICAgICAgICAgICAgICB5LAotICAgICAgICAgICAgICAgIHBvczsKLQotICAgICAgICAgICAgLy8gRGlzcGF0Y2ggZXZlbnQ6Ci0gICAgICAgICAgICBpZiAoX3NldHRpbmdzKCdtb3VzZUVuYWJsZWQnKSkgewotICAgICAgICAgICAgICAgIF9zZWxmLmRpc3BhdGNoRXZlbnQoJ21vdXNlbW92ZScsCi0gICAgICAgICAgICAgICAgICAgIHNpZ21hLnV0aWxzLm1vdXNlQ29vcmRzKGUpKTsKLQotICAgICAgICAgICAgICAgIGlmIChfaXNNb3VzZURvd24pIHsKLSAgICAgICAgICAgICAgICAgICAgX2lzTW92aW5nID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgX2hhc0RyYWdnZWQgPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChfbW92aW5nVGltZW91dElkKQotICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF9tb3ZpbmdUaW1lb3V0SWQpOwotCi0gICAgICAgICAgICAgICAgICAgIF9tb3ZpbmdUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9pc01vdmluZyA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICB9LCBfc2V0dGluZ3MoJ2RyYWdUaW1lb3V0JykpOwotCi0gICAgICAgICAgICAgICAgICAgIHNpZ21hLm1pc2MuYW5pbWF0aW9uLmtpbGxBbGwoX2NhbWVyYSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgX2NhbWVyYS5pc01vdmluZyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIHBvcyA9IF9jYW1lcmEuY2FtZXJhUG9zaXRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBzaWdtYS51dGlscy5nZXRYKGUpIC0gX3N0YXJ0TW91c2VYLAotICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWEudXRpbHMuZ2V0WShlKSAtIF9zdGFydE1vdXNlWSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRydWUKLSAgICAgICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgICAgICAgICB4ID0gX3N0YXJ0Q2FtZXJhWCAtIHBvcy54OwotICAgICAgICAgICAgICAgICAgICB5ID0gX3N0YXJ0Q2FtZXJhWSAtIHBvcy55OwotCi0gICAgICAgICAgICAgICAgICAgIGlmICh4ICE9PSBfY2FtZXJhLnggfHwgeSAhPT0gX2NhbWVyYS55KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfbGFzdENhbWVyYVggPSBfY2FtZXJhLng7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfbGFzdENhbWVyYVkgPSBfY2FtZXJhLnk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIF9jYW1lcmEuZ29Ubyh7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogeCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiB5Ci0gICAgICAgICAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGlmIChlLnByZXZlbnREZWZhdWx0KQotICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOwotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICBlLnJldHVyblZhbHVlID0gZmFsc2U7Ci0KLSAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUaGUgaGFuZGxlciBsaXN0ZW5pbmcgdG8gdGhlICd1cCcgbW91c2UgZXZlbnQuIEl0IHdpbGwgc3RvcCBkcmFnZ2luZyB0aGUKLSAgICAgICAgICogZ3JhcGguCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSB7ZXZlbnR9IGUgQSBtb3VzZSBldmVudC4KLSAgICAgICAgICovCi0gICAgICAgIGZ1bmN0aW9uIF91cEhhbmRsZXIoZSkgewotICAgICAgICAgICAgaWYgKF9zZXR0aW5ncygnbW91c2VFbmFibGVkJykgJiYgX2lzTW91c2VEb3duKSB7Ci0gICAgICAgICAgICAgICAgX2lzTW91c2VEb3duID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgaWYgKF9tb3ZpbmdUaW1lb3V0SWQpCi0gICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChfbW92aW5nVGltZW91dElkKTsKLQotICAgICAgICAgICAgICAgIF9jYW1lcmEuaXNNb3ZpbmcgPSBmYWxzZTsKLQotICAgICAgICAgICAgICAgIHZhciB4ID0gc2lnbWEudXRpbHMuZ2V0WChlKSwKLSAgICAgICAgICAgICAgICAgICAgeSA9IHNpZ21hLnV0aWxzLmdldFkoZSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoX2lzTW92aW5nKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNpZ21hLm1pc2MuYW5pbWF0aW9uLmtpbGxBbGwoX2NhbWVyYSk7Ci0gICAgICAgICAgICAgICAgICAgIHNpZ21hLm1pc2MuYW5pbWF0aW9uLmNhbWVyYSgKLSAgICAgICAgICAgICAgICAgICAgICAgIF9jYW1lcmEsCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogX2NhbWVyYS54ICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2V0dGluZ3MoJ21vdXNlSW5lcnRpYVJhdGlvJykgKiAoX2NhbWVyYS54IC0gX2xhc3RDYW1lcmFYKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBfY2FtZXJhLnkgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zZXR0aW5ncygnbW91c2VJbmVydGlhUmF0aW8nKSAqIChfY2FtZXJhLnkgLSBfbGFzdENhbWVyYVkpCi0gICAgICAgICAgICAgICAgICAgICAgICB9LAotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhc2luZzogJ3F1YWRyYXRpY091dCcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IF9zZXR0aW5ncygnbW91c2VJbmVydGlhRHVyYXRpb24nKQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoCi0gICAgICAgICAgICAgICAgICAgIF9zdGFydE1vdXNlWCAhPT0geCB8fAotICAgICAgICAgICAgICAgICAgICBfc3RhcnRNb3VzZVkgIT09IHkKLSAgICAgICAgICAgICAgICApCi0gICAgICAgICAgICAgICAgICAgIF9jYW1lcmEuZ29Ubyh7Ci0gICAgICAgICAgICAgICAgICAgICAgICB4OiBfY2FtZXJhLngsCi0gICAgICAgICAgICAgICAgICAgICAgICB5OiBfY2FtZXJhLnkKLSAgICAgICAgICAgICAgICAgICAgfSk7Ci0KLSAgICAgICAgICAgICAgICBfc2VsZi5kaXNwYXRjaEV2ZW50KCdtb3VzZXVwJywKLSAgICAgICAgICAgICAgICAgICAgc2lnbWEudXRpbHMubW91c2VDb29yZHMoZSkpOwotCi0gICAgICAgICAgICAgICAgLy8gVXBkYXRlIF9pc01vdmluZyBmbGFnOgotICAgICAgICAgICAgICAgIF9pc01vdmluZyA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSBoYW5kbGVyIGxpc3RlbmluZyB0byB0aGUgJ2Rvd24nIG1vdXNlIGV2ZW50LiBJdCB3aWxsIHN0YXJ0IG9ic2VydmluZwotICAgICAgICAgKiB0aGUgbW91c2UgcG9zaXRpb24gZm9yIGRyYWdnaW5nIHRoZSBncmFwaC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHtldmVudH0gZSBBIG1vdXNlIGV2ZW50LgotICAgICAgICAgKi8KLSAgICAgICAgZnVuY3Rpb24gX2Rvd25IYW5kbGVyKGUpIHsKLSAgICAgICAgICAgIGlmIChfc2V0dGluZ3MoJ21vdXNlRW5hYmxlZCcpKSB7Ci0gICAgICAgICAgICAgICAgX3N0YXJ0Q2FtZXJhWCA9IF9jYW1lcmEueDsKLSAgICAgICAgICAgICAgICBfc3RhcnRDYW1lcmFZID0gX2NhbWVyYS55OwotCi0gICAgICAgICAgICAgICAgX2xhc3RDYW1lcmFYID0gX2NhbWVyYS54OwotICAgICAgICAgICAgICAgIF9sYXN0Q2FtZXJhWSA9IF9jYW1lcmEueTsKLQotICAgICAgICAgICAgICAgIF9zdGFydE1vdXNlWCA9IHNpZ21hLnV0aWxzLmdldFgoZSk7Ci0gICAgICAgICAgICAgICAgX3N0YXJ0TW91c2VZID0gc2lnbWEudXRpbHMuZ2V0WShlKTsKLQotICAgICAgICAgICAgICAgIF9oYXNEcmFnZ2VkID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgX2Rvd25TdGFydFRpbWUgPSAobmV3IERhdGUoKSkuZ2V0VGltZSgpOwotCi0gICAgICAgICAgICAgICAgc3dpdGNoIChlLndoaWNoKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1pZGRsZSBtb3VzZSBidXR0b24gcHJlc3NlZAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90aGluZy4KLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIDM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBSaWdodCBtb3VzZSBidXR0b24gcHJlc3NlZAotICAgICAgICAgICAgICAgICAgICAgICAgX3NlbGYuZGlzcGF0Y2hFdmVudCgncmlnaHRjbGljaycsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWEudXRpbHMubW91c2VDb29yZHMoZSwgX3N0YXJ0TW91c2VYLCBfc3RhcnRNb3VzZVkpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAvLyBjYXNlIDE6Ci0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBMZWZ0IG1vdXNlIGJ1dHRvbiBwcmVzc2VkCi0gICAgICAgICAgICAgICAgICAgICAgICBfaXNNb3VzZURvd24gPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBfc2VsZi5kaXNwYXRjaEV2ZW50KCdtb3VzZWRvd24nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ21hLnV0aWxzLm1vdXNlQ29vcmRzKGUsIF9zdGFydE1vdXNlWCwgX3N0YXJ0TW91c2VZKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSBoYW5kbGVyIGxpc3RlbmluZyB0byB0aGUgJ291dCcgbW91c2UgZXZlbnQuIEl0IHdpbGwganVzdCByZWRpc3BhdGNoCi0gICAgICAgICAqIHRoZSBldmVudC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHtldmVudH0gZSBBIG1vdXNlIGV2ZW50LgotICAgICAgICAgKi8KLSAgICAgICAgZnVuY3Rpb24gX291dEhhbmRsZXIoZSkgewotICAgICAgICAgICAgaWYgKF9zZXR0aW5ncygnbW91c2VFbmFibGVkJykpCi0gICAgICAgICAgICAgICAgX3NlbGYuZGlzcGF0Y2hFdmVudCgnbW91c2VvdXQnKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUaGUgaGFuZGxlciBsaXN0ZW5pbmcgdG8gdGhlICdjbGljaycgbW91c2UgZXZlbnQuIEl0IHdpbGwgcmVkaXNwYXRjaCB0aGUKLSAgICAgICAgICogY2xpY2sgZXZlbnQsIGJ1dCB3aXRoIG5vcm1hbGl6ZWQgWCBhbmQgWSBjb29yZGluYXRlcy4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHtldmVudH0gZSBBIG1vdXNlIGV2ZW50LgotICAgICAgICAgKi8KLSAgICAgICAgZnVuY3Rpb24gX2NsaWNrSGFuZGxlcihlKSB7Ci0gICAgICAgICAgICBpZiAoX3NldHRpbmdzKCdtb3VzZUVuYWJsZWQnKSkgewotICAgICAgICAgICAgICAgIHZhciBldmVudCA9IHNpZ21hLnV0aWxzLm1vdXNlQ29vcmRzKGUpOwotICAgICAgICAgICAgICAgIGV2ZW50LmlzRHJhZ2dpbmcgPQotICAgICAgICAgICAgICAgICAgICAoKChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkgLSBfZG93blN0YXJ0VGltZSkgPiAxMDApICYmIF9oYXNEcmFnZ2VkOwotICAgICAgICAgICAgICAgIF9zZWxmLmRpc3BhdGNoRXZlbnQoJ2NsaWNrJywgZXZlbnQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoZS5wcmV2ZW50RGVmYXVsdCkKLSAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlOwotCi0gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpOwotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSBoYW5kbGVyIGxpc3RlbmluZyB0byB0aGUgZG91YmxlIGNsaWNrIGN1c3RvbSBldmVudC4gSXQgd2lsbAotICAgICAgICAgKiBiYXNpY2FsbHkgem9vbSBpbnRvIHRoZSBncmFwaC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHtldmVudH0gZSBBIG1vdXNlIGV2ZW50LgotICAgICAgICAgKi8KLSAgICAgICAgZnVuY3Rpb24gX2RvdWJsZUNsaWNrSGFuZGxlcihlKSB7Ci0gICAgICAgICAgICB2YXIgcG9zLAotICAgICAgICAgICAgICAgIHJhdGlvLAotICAgICAgICAgICAgICAgIGFuaW1hdGlvbjsKLQotICAgICAgICAgICAgaWYgKF9zZXR0aW5ncygnbW91c2VFbmFibGVkJykpIHsKLSAgICAgICAgICAgICAgICByYXRpbyA9IDEgLyBfc2V0dGluZ3MoJ2RvdWJsZUNsaWNrWm9vbWluZ1JhdGlvJyk7Ci0KLSAgICAgICAgICAgICAgICBfc2VsZi5kaXNwYXRjaEV2ZW50KCdkb3VibGVjbGljaycsCi0gICAgICAgICAgICAgICAgICAgIHNpZ21hLnV0aWxzLm1vdXNlQ29vcmRzKGUsIF9zdGFydE1vdXNlWCwgX3N0YXJ0TW91c2VZKSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoX3NldHRpbmdzKCdkb3VibGVDbGlja0VuYWJsZWQnKSkgewotICAgICAgICAgICAgICAgICAgICBwb3MgPSBfY2FtZXJhLmNhbWVyYVBvc2l0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWEudXRpbHMuZ2V0WChlKSAtIHNpZ21hLnV0aWxzLmdldENlbnRlcihlKS54LAotICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWEudXRpbHMuZ2V0WShlKSAtIHNpZ21hLnV0aWxzLmdldENlbnRlcihlKS55LAotICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZQotICAgICAgICAgICAgICAgICAgICApOwotCi0gICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbiA9IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBfc2V0dGluZ3MoJ2RvdWJsZUNsaWNrWm9vbUR1cmF0aW9uJykKLSAgICAgICAgICAgICAgICAgICAgfTsKLQotICAgICAgICAgICAgICAgICAgICBzaWdtYS51dGlscy56b29tVG8oX2NhbWVyYSwgcG9zLngsIHBvcy55LCByYXRpbywgYW5pbWF0aW9uKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoZS5wcmV2ZW50RGVmYXVsdCkKLSAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlOwotCi0gICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhlIGhhbmRsZXIgbGlzdGVuaW5nIHRvIHRoZSAnd2hlZWwnIG1vdXNlIGV2ZW50LiBJdCB3aWxsIGJhc2ljYWxseSB6b29tCi0gICAgICAgICAqIGluIG9yIG5vdCBpbnRvIHRoZSBncmFwaC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHtldmVudH0gZSBBIG1vdXNlIGV2ZW50LgotICAgICAgICAgKi8KLSAgICAgICAgZnVuY3Rpb24gX3doZWVsSGFuZGxlcihlKSB7Ci0gICAgICAgICAgICB2YXIgcG9zLAotICAgICAgICAgICAgICAgIHJhdGlvLAotICAgICAgICAgICAgICAgIGFuaW1hdGlvbjsKLQotICAgICAgICAgICAgaWYgKF9zZXR0aW5ncygnbW91c2VFbmFibGVkJykgJiYgX3NldHRpbmdzKCdtb3VzZVdoZWVsRW5hYmxlZCcpKSB7Ci0gICAgICAgICAgICAgICAgcmF0aW8gPSBzaWdtYS51dGlscy5nZXREZWx0YShlKSA+IDAgPwotICAgICAgICAgICAgICAgIDEgLyBfc2V0dGluZ3MoJ3pvb21pbmdSYXRpbycpIDoKLSAgICAgICAgICAgICAgICAgICAgX3NldHRpbmdzKCd6b29taW5nUmF0aW8nKTsKLQotICAgICAgICAgICAgICAgIHBvcyA9IF9jYW1lcmEuY2FtZXJhUG9zaXRpb24oCi0gICAgICAgICAgICAgICAgICAgIHNpZ21hLnV0aWxzLmdldFgoZSkgLSBzaWdtYS51dGlscy5nZXRDZW50ZXIoZSkueCwKLSAgICAgICAgICAgICAgICAgICAgc2lnbWEudXRpbHMuZ2V0WShlKSAtIHNpZ21hLnV0aWxzLmdldENlbnRlcihlKS55LAotICAgICAgICAgICAgICAgICAgICB0cnVlCi0gICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgICAgIGFuaW1hdGlvbiA9IHsKLSAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IF9zZXR0aW5ncygnbW91c2Vab29tRHVyYXRpb24nKQotICAgICAgICAgICAgICAgIH07Ci0KLSAgICAgICAgICAgICAgICBzaWdtYS51dGlscy56b29tVG8oX2NhbWVyYSwgcG9zLngsIHBvcy55LCByYXRpbywgYW5pbWF0aW9uKTsKLQotICAgICAgICAgICAgICAgIGlmIChlLnByZXZlbnREZWZhdWx0KQotICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBlLnJldHVyblZhbHVlID0gZmFsc2U7Ci0KLSAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH07Ci19KS5jYWxsKHRoaXMpOwotCi07KGZ1bmN0aW9uICh1bmRlZmluZWQpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBpZiAodHlwZW9mIHNpZ21hID09PSAndW5kZWZpbmVkJykKLSAgICAgICAgdGhyb3cgJ3NpZ21hIGlzIG5vdCBkZWNsYXJlZCc7Ci0KLSAgICAvLyBJbml0aWFsaXplIHBhY2thZ2VzOgotICAgIHNpZ21hLnV0aWxzLnBrZygnc2lnbWEuY2FwdG9ycycpOwotCi0gICAgLyoqCi0gICAgICogVGhlIHVzZXIgaW5wdXRzIGRlZmF1bHQgY2FwdG9yLiBJdCBkZWFscyB3aXRoIG1vdXNlIGV2ZW50cywga2V5Ym9hcmRzCi0gICAgICogZXZlbnRzIGFuZCB0b3VjaCBldmVudHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtET01FbGVtZW50fSAgIHRhcmdldCAgIFRoZSBET00gZWxlbWVudCB3aGVyZSB0aGUgbGlzdGVuZXJzIHdpbGwgYmUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kLgotICAgICAqIEBwYXJhbSAge2NhbWVyYX0gICAgICAgY2FtZXJhICAgVGhlIGNhbWVyYSByZWxhdGVkIHRvIHRoZSB0YXJnZXQuCi0gICAgICogQHBhcmFtICB7Y29uZmlndXJhYmxlfSBzZXR0aW5ncyBUaGUgc2V0dGluZ3MgZnVuY3Rpb24uCi0gICAgICogQHJldHVybiB7c2lnbWEuY2FwdG9yfSAgICAgICAgICBUaGUgZnJlc2ggbmV3IGNhcHRvciBpbnN0YW5jZS4KLSAgICAgKi8KLSAgICBzaWdtYS5jYXB0b3JzLnRvdWNoID0gZnVuY3Rpb24gKHRhcmdldCwgY2FtZXJhLCBzZXR0aW5ncykgewotICAgICAgICB2YXIgX3NlbGYgPSB0aGlzLAotICAgICAgICAgICAgX3RhcmdldCA9IHRhcmdldCwKLSAgICAgICAgICAgIF9jYW1lcmEgPSBjYW1lcmEsCi0gICAgICAgICAgICBfc2V0dGluZ3MgPSBzZXR0aW5ncywKLQotICAgICAgICAgICAgLy8gQ0FNRVJBIE1BTkFHRU1FTlQ6Ci0gICAgICAgICAgICAvLyAqKioqKioqKioqKioqKioqKioKLSAgICAgICAgICAgIC8vIFRoZSBjYW1lcmEgcG9zaXRpb24gd2hlbiB0aGUgdXNlciBzdGFydHMgZHJhZ2dpbmc6Ci0gICAgICAgICAgICBfc3RhcnRDYW1lcmFYLAotICAgICAgICAgICAgX3N0YXJ0Q2FtZXJhWSwKLSAgICAgICAgICAgIF9zdGFydENhbWVyYUFuZ2xlLAotICAgICAgICAgICAgX3N0YXJ0Q2FtZXJhUmF0aW8sCi0KLSAgICAgICAgICAgIC8vIFRoZSBsYXRlc3Qgc3RhZ2UgcG9zaXRpb246Ci0gICAgICAgICAgICBfbGFzdENhbWVyYVgsCi0gICAgICAgICAgICBfbGFzdENhbWVyYVksCi0gICAgICAgICAgICBfbGFzdENhbWVyYUFuZ2xlLAotICAgICAgICAgICAgX2xhc3RDYW1lcmFSYXRpbywKLQotICAgICAgICAgICAgLy8gVE9VQ0ggTUFOQUdFTUVOVDoKLSAgICAgICAgICAgIC8vICoqKioqKioqKioqKioqKioqCi0gICAgICAgICAgICAvLyBUb3VjaGVzIHRoYXQgYXJlIGRvd246Ci0gICAgICAgICAgICBfZG93blRvdWNoZXMgPSBbXSwKLQotICAgICAgICAgICAgX3N0YXJ0VG91Y2hYMCwKLSAgICAgICAgICAgIF9zdGFydFRvdWNoWTAsCi0gICAgICAgICAgICBfc3RhcnRUb3VjaFgxLAotICAgICAgICAgICAgX3N0YXJ0VG91Y2hZMSwKLSAgICAgICAgICAgIF9zdGFydFRvdWNoQW5nbGUsCi0gICAgICAgICAgICBfc3RhcnRUb3VjaERpc3RhbmNlLAotCi0gICAgICAgICAgICBfdG91Y2hNb2RlLAotCi0gICAgICAgICAgICBfaXNNb3ZpbmcsCi0gICAgICAgICAgICBfZG91YmxlVGFwLAotICAgICAgICAgICAgX21vdmluZ1RpbWVvdXRJZDsKLQotICAgICAgICBzaWdtYS5jbGFzc2VzLmRpc3BhdGNoZXIuZXh0ZW5kKHRoaXMpOwotCi0gICAgICAgIHNpZ21hLnV0aWxzLmRvdWJsZUNsaWNrKF90YXJnZXQsICd0b3VjaHN0YXJ0JywgX2RvdWJsZVRhcEhhbmRsZXIpOwotICAgICAgICBfdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBfaGFuZGxlU3RhcnQsIGZhbHNlKTsKLSAgICAgICAgX3RhcmdldC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIF9oYW5kbGVMZWF2ZSwgZmFsc2UpOwotICAgICAgICBfdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoY2FuY2VsJywgX2hhbmRsZUxlYXZlLCBmYWxzZSk7Ci0gICAgICAgIF90YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hsZWF2ZScsIF9oYW5kbGVMZWF2ZSwgZmFsc2UpOwotICAgICAgICBfdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIF9oYW5kbGVNb3ZlLCBmYWxzZSk7Ci0KLSAgICAgICAgZnVuY3Rpb24gcG9zaXRpb24oZSkgewotICAgICAgICAgICAgdmFyIG9mZnNldCA9IHNpZ21hLnV0aWxzLmdldE9mZnNldChfdGFyZ2V0KTsKLQotICAgICAgICAgICAgcmV0dXJuIHsKLSAgICAgICAgICAgICAgICB4OiBlLnBhZ2VYIC0gb2Zmc2V0LmxlZnQsCi0gICAgICAgICAgICAgICAgeTogZS5wYWdlWSAtIG9mZnNldC50b3AKLSAgICAgICAgICAgIH07Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhpcyBtZXRob2QgdW5iaW5kcyBldmVyeSBoYW5kbGVycyB0aGF0IG1ha2VzIHRoZSBjYXB0b3Igd29yay4KLSAgICAgICAgICovCi0gICAgICAgIHRoaXMua2lsbCA9IGZ1bmN0aW9uICgpIHsKLSAgICAgICAgICAgIHNpZ21hLnV0aWxzLnVuYmluZERvdWJsZUNsaWNrKF90YXJnZXQsICd0b3VjaHN0YXJ0Jyk7Ci0gICAgICAgICAgICBfdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBfaGFuZGxlU3RhcnQpOwotICAgICAgICAgICAgX3RhcmdldC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIF9oYW5kbGVMZWF2ZSk7Ci0gICAgICAgICAgICBfdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoY2FuY2VsJywgX2hhbmRsZUxlYXZlKTsKLSAgICAgICAgICAgIF90YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hsZWF2ZScsIF9oYW5kbGVMZWF2ZSk7Ci0gICAgICAgICAgICBfdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIF9oYW5kbGVNb3ZlKTsKLSAgICAgICAgfTsKLQotICAgICAgICAvLyBUT1VDSCBFVkVOVFM6Ci0gICAgICAgIC8vICoqKioqKioqKioqKioKLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSBoYW5kbGVyIGxpc3RlbmluZyB0byB0aGUgJ3RvdWNoc3RhcnQnIGV2ZW50LiBJdCB3aWxsIHNldCB0aGUgdG91Y2gKLSAgICAgICAgICogbW9kZSAoIl90b3VjaE1vZGUiKSBhbmQgc3RhcnQgb2JzZXJ2aW5nIHRoZSB1c2VyIHRvdWNoIG1vdmVzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0ge2V2ZW50fSBlIEEgdG91Y2ggZXZlbnQuCi0gICAgICAgICAqLwotICAgICAgICBmdW5jdGlvbiBfaGFuZGxlU3RhcnQoZSkgewotICAgICAgICAgICAgaWYgKF9zZXR0aW5ncygndG91Y2hFbmFibGVkJykpIHsKLSAgICAgICAgICAgICAgICB2YXIgeDAsCi0gICAgICAgICAgICAgICAgICAgIHgxLAotICAgICAgICAgICAgICAgICAgICB5MCwKLSAgICAgICAgICAgICAgICAgICAgeTEsCi0gICAgICAgICAgICAgICAgICAgIHBvczAsCi0gICAgICAgICAgICAgICAgICAgIHBvczE7Ci0KLSAgICAgICAgICAgICAgICBfZG93blRvdWNoZXMgPSBlLnRvdWNoZXM7Ci0KLSAgICAgICAgICAgICAgICBzd2l0Y2ggKF9kb3duVG91Y2hlcy5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSAxOgotICAgICAgICAgICAgICAgICAgICAgICAgX2NhbWVyYS5pc01vdmluZyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfdG91Y2hNb2RlID0gMTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgX3N0YXJ0Q2FtZXJhWCA9IF9jYW1lcmEueDsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9zdGFydENhbWVyYVkgPSBfY2FtZXJhLnk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIF9sYXN0Q2FtZXJhWCA9IF9jYW1lcmEueDsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9sYXN0Q2FtZXJhWSA9IF9jYW1lcmEueTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgcG9zMCA9IHBvc2l0aW9uKF9kb3duVG91Y2hlc1swXSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfc3RhcnRUb3VjaFgwID0gcG9zMC54OwotICAgICAgICAgICAgICAgICAgICAgICAgX3N0YXJ0VG91Y2hZMCA9IHBvczAueTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKLSAgICAgICAgICAgICAgICAgICAgICAgIF9jYW1lcmEuaXNNb3ZpbmcgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgX3RvdWNoTW9kZSA9IDI7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHBvczAgPSBwb3NpdGlvbihfZG93blRvdWNoZXNbMF0pOwotICAgICAgICAgICAgICAgICAgICAgICAgcG9zMSA9IHBvc2l0aW9uKF9kb3duVG91Y2hlc1sxXSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB4MCA9IHBvczAueDsKLSAgICAgICAgICAgICAgICAgICAgICAgIHkwID0gcG9zMC55OwotICAgICAgICAgICAgICAgICAgICAgICAgeDEgPSBwb3MxLng7Ci0gICAgICAgICAgICAgICAgICAgICAgICB5MSA9IHBvczEueTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgX2xhc3RDYW1lcmFYID0gX2NhbWVyYS54OwotICAgICAgICAgICAgICAgICAgICAgICAgX2xhc3RDYW1lcmFZID0gX2NhbWVyYS55OwotCi0gICAgICAgICAgICAgICAgICAgICAgICBfc3RhcnRDYW1lcmFBbmdsZSA9IF9jYW1lcmEuYW5nbGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfc3RhcnRDYW1lcmFSYXRpbyA9IF9jYW1lcmEucmF0aW87Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIF9zdGFydENhbWVyYVggPSBfY2FtZXJhLng7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfc3RhcnRDYW1lcmFZID0gX2NhbWVyYS55OwotCi0gICAgICAgICAgICAgICAgICAgICAgICBfc3RhcnRUb3VjaFgwID0geDA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfc3RhcnRUb3VjaFkwID0geTA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfc3RhcnRUb3VjaFgxID0geDE7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfc3RhcnRUb3VjaFkxID0geTE7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIF9zdGFydFRvdWNoQW5nbGUgPSBNYXRoLmF0YW4yKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zdGFydFRvdWNoWTEgLSBfc3RhcnRUb3VjaFkwLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zdGFydFRvdWNoWDEgLSBfc3RhcnRUb3VjaFgwCi0gICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgICAgICAgICAgX3N0YXJ0VG91Y2hEaXN0YW5jZSA9IE1hdGguc3FydCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoX3N0YXJ0VG91Y2hZMSAtIF9zdGFydFRvdWNoWTApICoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoX3N0YXJ0VG91Y2hZMSAtIF9zdGFydFRvdWNoWTApICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoX3N0YXJ0VG91Y2hYMSAtIF9zdGFydFRvdWNoWDApICoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoX3N0YXJ0VG91Y2hYMSAtIF9zdGFydFRvdWNoWDApCi0gICAgICAgICAgICAgICAgICAgICAgICApOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSBoYW5kbGVyIGxpc3RlbmluZyB0byB0aGUgJ3RvdWNoZW5kJywgJ3RvdWNoY2FuY2VsJyBhbmQgJ3RvdWNobGVhdmUnCi0gICAgICAgICAqIGV2ZW50LiBJdCB3aWxsIHVwZGF0ZSB0aGUgdG91Y2ggbW9kZSBpZiB0aGVyZSBhcmUgc3RpbGwgYXQgbGVhc3Qgb25lCi0gICAgICAgICAqIGZpbmdlciwgYW5kIHN0b3AgZHJhZ2dpbmcgZWxzZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHtldmVudH0gZSBBIHRvdWNoIGV2ZW50LgotICAgICAgICAgKi8KLSAgICAgICAgZnVuY3Rpb24gX2hhbmRsZUxlYXZlKGUpIHsKLSAgICAgICAgICAgIGlmIChfc2V0dGluZ3MoJ3RvdWNoRW5hYmxlZCcpKSB7Ci0gICAgICAgICAgICAgICAgX2Rvd25Ub3VjaGVzID0gZS50b3VjaGVzOwotICAgICAgICAgICAgICAgIHZhciBpbmVydGlhUmF0aW8gPSBfc2V0dGluZ3MoJ3RvdWNoSW5lcnRpYVJhdGlvJyk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoX21vdmluZ1RpbWVvdXRJZCkgewotICAgICAgICAgICAgICAgICAgICBfaXNNb3ZpbmcgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF9tb3ZpbmdUaW1lb3V0SWQpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHN3aXRjaCAoX3RvdWNoTW9kZSkgewotICAgICAgICAgICAgICAgICAgICBjYXNlIDI6Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZS50b3VjaGVzLmxlbmd0aCA9PT0gMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9oYW5kbGVTdGFydChlKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqLwotICAgICAgICAgICAgICAgICAgICBjYXNlIDE6Ci0gICAgICAgICAgICAgICAgICAgICAgICBfY2FtZXJhLmlzTW92aW5nID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfc2VsZi5kaXNwYXRjaEV2ZW50KCdzdG9wRHJhZycpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzTW92aW5nKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2RvdWJsZVRhcCA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ21hLm1pc2MuYW5pbWF0aW9uLmNhbWVyYSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NhbWVyYSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogX2NhbWVyYS54ICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZXJ0aWFSYXRpbyAqIChfY2FtZXJhLnggLSBfbGFzdENhbWVyYVgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogX2NhbWVyYS55ICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZXJ0aWFSYXRpbyAqIChfY2FtZXJhLnkgLSBfbGFzdENhbWVyYVkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhc2luZzogJ3F1YWRyYXRpY091dCcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbjogX3NldHRpbmdzKCd0b3VjaEluZXJ0aWFEdXJhdGlvbicpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICBfaXNNb3ZpbmcgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIF90b3VjaE1vZGUgPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSBoYW5kbGVyIGxpc3RlbmluZyB0byB0aGUgJ3RvdWNobW92ZScgZXZlbnQuIEl0IHdpbGwgZWZmZWN0aXZlbHkgZHJhZwotICAgICAgICAgKiB0aGUgZ3JhcGgsIGFuZCBldmVudHVhbGx5IHpvb21zIGFuZCB0dXJuIGl0IGlmIHRoZSB1c2VyIGlzIHVzaW5nIHR3bwotICAgICAgICAgKiBmaW5nZXJzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0ge2V2ZW50fSBlIEEgdG91Y2ggZXZlbnQuCi0gICAgICAgICAqLwotICAgICAgICBmdW5jdGlvbiBfaGFuZGxlTW92ZShlKSB7Ci0gICAgICAgICAgICBpZiAoIV9kb3VibGVUYXAgJiYgX3NldHRpbmdzKCd0b3VjaEVuYWJsZWQnKSkgewotICAgICAgICAgICAgICAgIHZhciB4MCwKLSAgICAgICAgICAgICAgICAgICAgeDEsCi0gICAgICAgICAgICAgICAgICAgIHkwLAotICAgICAgICAgICAgICAgICAgICB5MSwKLSAgICAgICAgICAgICAgICAgICAgY29zLAotICAgICAgICAgICAgICAgICAgICBzaW4sCi0gICAgICAgICAgICAgICAgICAgIGVuZCwKLSAgICAgICAgICAgICAgICAgICAgcG9zMCwKLSAgICAgICAgICAgICAgICAgICAgcG9zMSwKLSAgICAgICAgICAgICAgICAgICAgZGlmZiwKLSAgICAgICAgICAgICAgICAgICAgc3RhcnQsCi0gICAgICAgICAgICAgICAgICAgIGRBbmdsZSwKLSAgICAgICAgICAgICAgICAgICAgZFJhdGlvLAotICAgICAgICAgICAgICAgICAgICBuZXdTdGFnZVgsCi0gICAgICAgICAgICAgICAgICAgIG5ld1N0YWdlWSwKLSAgICAgICAgICAgICAgICAgICAgbmV3U3RhZ2VSYXRpbywKLSAgICAgICAgICAgICAgICAgICAgbmV3U3RhZ2VBbmdsZTsKLQotICAgICAgICAgICAgICAgIF9kb3duVG91Y2hlcyA9IGUudG91Y2hlczsKLSAgICAgICAgICAgICAgICBfaXNNb3ZpbmcgPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgaWYgKF9tb3ZpbmdUaW1lb3V0SWQpCi0gICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChfbW92aW5nVGltZW91dElkKTsKLQotICAgICAgICAgICAgICAgIF9tb3ZpbmdUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKLSAgICAgICAgICAgICAgICAgICAgX2lzTW92aW5nID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfSwgX3NldHRpbmdzKCdkcmFnVGltZW91dCcpKTsKLQotICAgICAgICAgICAgICAgIHN3aXRjaCAoX3RvdWNoTW9kZSkgewotICAgICAgICAgICAgICAgICAgICBjYXNlIDE6Ci0gICAgICAgICAgICAgICAgICAgICAgICBwb3MwID0gcG9zaXRpb24oX2Rvd25Ub3VjaGVzWzBdKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHgwID0gcG9zMC54OwotICAgICAgICAgICAgICAgICAgICAgICAgeTAgPSBwb3MwLnk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGRpZmYgPSBfY2FtZXJhLmNhbWVyYVBvc2l0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgwIC0gX3N0YXJ0VG91Y2hYMCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB5MCAtIF9zdGFydFRvdWNoWTAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZQotICAgICAgICAgICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgbmV3U3RhZ2VYID0gX3N0YXJ0Q2FtZXJhWCAtIGRpZmYueDsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ld1N0YWdlWSA9IF9zdGFydENhbWVyYVkgLSBkaWZmLnk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdTdGFnZVggIT09IF9jYW1lcmEueCB8fCBuZXdTdGFnZVkgIT09IF9jYW1lcmEueSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sYXN0Q2FtZXJhWCA9IF9jYW1lcmEueDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbGFzdENhbWVyYVkgPSBfY2FtZXJhLnk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY2FtZXJhLmdvVG8oewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBuZXdTdGFnZVgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IG5ld1N0YWdlWQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NlbGYuZGlzcGF0Y2hFdmVudCgnbW91c2Vtb3ZlJywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWEudXRpbHMubW91c2VDb29yZHMoZSwgcG9zMC54LCBwb3MwLnkpKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zZWxmLmRpc3BhdGNoRXZlbnQoJ2RyYWcnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIDI6Ci0gICAgICAgICAgICAgICAgICAgICAgICBwb3MwID0gcG9zaXRpb24oX2Rvd25Ub3VjaGVzWzBdKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBvczEgPSBwb3NpdGlvbihfZG93blRvdWNoZXNbMV0pOwotICAgICAgICAgICAgICAgICAgICAgICAgeDAgPSBwb3MwLng7Ci0gICAgICAgICAgICAgICAgICAgICAgICB5MCA9IHBvczAueTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHgxID0gcG9zMS54OwotICAgICAgICAgICAgICAgICAgICAgICAgeTEgPSBwb3MxLnk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ID0gX2NhbWVyYS5jYW1lcmFQb3NpdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoX3N0YXJ0VG91Y2hYMCArIF9zdGFydFRvdWNoWDEpIC8gMiAtCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWEudXRpbHMuZ2V0Q2VudGVyKGUpLngsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKF9zdGFydFRvdWNoWTAgKyBfc3RhcnRUb3VjaFkxKSAvIDIgLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ21hLnV0aWxzLmdldENlbnRlcihlKS55LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUKLSAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbmQgPSBfY2FtZXJhLmNhbWVyYVBvc2l0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICh4MCArIHgxKSAvIDIgLSBzaWdtYS51dGlscy5nZXRDZW50ZXIoZSkueCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoeTAgKyB5MSkgLyAyIC0gc2lnbWEudXRpbHMuZ2V0Q2VudGVyKGUpLnksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZQotICAgICAgICAgICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgZEFuZ2xlID0gTWF0aC5hdGFuMih5MSAtIHkwLCB4MSAtIHgwKSAtIF9zdGFydFRvdWNoQW5nbGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkUmF0aW8gPSBNYXRoLnNxcnQoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh5MSAtIHkwKSAqICh5MSAtIHkwKSArICh4MSAtIHgwKSAqICh4MSAtIHgwKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgLyBfc3RhcnRUb3VjaERpc3RhbmNlOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBUcmFuc2xhdGlvbjoKLSAgICAgICAgICAgICAgICAgICAgICAgIHgwID0gc3RhcnQueDsKLSAgICAgICAgICAgICAgICAgICAgICAgIHkwID0gc3RhcnQueTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSG9tb3RoZXRpYyB0cmFuc2Zvcm1hdGlvbjoKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ld1N0YWdlUmF0aW8gPSBfc3RhcnRDYW1lcmFSYXRpbyAvIGRSYXRpbzsKLSAgICAgICAgICAgICAgICAgICAgICAgIHgwID0geDAgKiBkUmF0aW87Ci0gICAgICAgICAgICAgICAgICAgICAgICB5MCA9IHkwICogZFJhdGlvOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBSb3RhdGlvbjoKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ld1N0YWdlQW5nbGUgPSBfc3RhcnRDYW1lcmFBbmdsZSAtIGRBbmdsZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvcyA9IE1hdGguY29zKC1kQW5nbGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgc2luID0gTWF0aC5zaW4oLWRBbmdsZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB4MSA9IHgwICogY29zICsgeTAgKiBzaW47Ci0gICAgICAgICAgICAgICAgICAgICAgICB5MSA9IHkwICogY29zIC0geDAgKiBzaW47Ci0gICAgICAgICAgICAgICAgICAgICAgICB4MCA9IHgxOwotICAgICAgICAgICAgICAgICAgICAgICAgeTAgPSB5MTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmluYWxpemU6Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXdTdGFnZVggPSB4MCAtIGVuZC54ICsgX3N0YXJ0Q2FtZXJhWDsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ld1N0YWdlWSA9IHkwIC0gZW5kLnkgKyBfc3RhcnRDYW1lcmFZOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3U3RhZ2VSYXRpbyAhPT0gX2NhbWVyYS5yYXRpbyB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1N0YWdlQW5nbGUgIT09IF9jYW1lcmEuYW5nbGUgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdTdGFnZVggIT09IF9jYW1lcmEueCB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1N0YWdlWSAhPT0gX2NhbWVyYS55Ci0gICAgICAgICAgICAgICAgICAgICAgICApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbGFzdENhbWVyYVggPSBfY2FtZXJhLng7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2xhc3RDYW1lcmFZID0gX2NhbWVyYS55OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sYXN0Q2FtZXJhQW5nbGUgPSBfY2FtZXJhLmFuZ2xlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sYXN0Q2FtZXJhUmF0aW8gPSBfY2FtZXJhLnJhdGlvOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NhbWVyYS5nb1RvKHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogbmV3U3RhZ2VYLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBuZXdTdGFnZVksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuZ2xlOiBuZXdTdGFnZUFuZ2xlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXRpbzogbmV3U3RhZ2VSYXRpbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NlbGYuZGlzcGF0Y2hFdmVudCgnZHJhZycpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSBoYW5kbGVyIGxpc3RlbmluZyB0byB0aGUgZG91YmxlIHRhcCBjdXN0b20gZXZlbnQuIEl0IHdpbGwKLSAgICAgICAgICogYmFzaWNhbGx5IHpvb20gaW50byB0aGUgZ3JhcGguCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSB7ZXZlbnR9IGUgQSB0b3VjaCBldmVudC4KLSAgICAgICAgICovCi0gICAgICAgIGZ1bmN0aW9uIF9kb3VibGVUYXBIYW5kbGVyKGUpIHsKLSAgICAgICAgICAgIHZhciBwb3MsCi0gICAgICAgICAgICAgICAgcmF0aW8sCi0gICAgICAgICAgICAgICAgYW5pbWF0aW9uOwotCi0gICAgICAgICAgICBpZiAoZS50b3VjaGVzICYmIGUudG91Y2hlcy5sZW5ndGggPT09IDEgJiYgX3NldHRpbmdzKCd0b3VjaEVuYWJsZWQnKSkgewotICAgICAgICAgICAgICAgIF9kb3VibGVUYXAgPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgcmF0aW8gPSAxIC8gX3NldHRpbmdzKCdkb3VibGVDbGlja1pvb21pbmdSYXRpbycpOwotCi0gICAgICAgICAgICAgICAgcG9zID0gcG9zaXRpb24oZS50b3VjaGVzWzBdKTsKLSAgICAgICAgICAgICAgICBfc2VsZi5kaXNwYXRjaEV2ZW50KCdkb3VibGVjbGljaycsCi0gICAgICAgICAgICAgICAgICAgIHNpZ21hLnV0aWxzLm1vdXNlQ29vcmRzKGUsIHBvcy54LCBwb3MueSkpOwotCi0gICAgICAgICAgICAgICAgaWYgKF9zZXR0aW5ncygnZG91YmxlQ2xpY2tFbmFibGVkJykpIHsKLSAgICAgICAgICAgICAgICAgICAgcG9zID0gX2NhbWVyYS5jYW1lcmFQb3NpdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIHBvcy54IC0gc2lnbWEudXRpbHMuZ2V0Q2VudGVyKGUpLngsCi0gICAgICAgICAgICAgICAgICAgICAgICBwb3MueSAtIHNpZ21hLnV0aWxzLmdldENlbnRlcihlKS55LAotICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZQotICAgICAgICAgICAgICAgICAgICApOwotCi0gICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbiA9IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBfc2V0dGluZ3MoJ2RvdWJsZUNsaWNrWm9vbUR1cmF0aW9uJyksCi0gICAgICAgICAgICAgICAgICAgICAgICBvbkNvbXBsZXRlOiBmdW5jdGlvbiAoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2RvdWJsZVRhcCA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9OwotCi0gICAgICAgICAgICAgICAgICAgIHNpZ21hLnV0aWxzLnpvb21UbyhfY2FtZXJhLCBwb3MueCwgcG9zLnksIHJhdGlvLCBhbmltYXRpb24pOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChlLnByZXZlbnREZWZhdWx0KQotICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBlLnJldHVyblZhbHVlID0gZmFsc2U7Ci0KLSAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH07Ci19KS5jYWxsKHRoaXMpOwotCi07KGZ1bmN0aW9uICh1bmRlZmluZWQpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBpZiAodHlwZW9mIHNpZ21hID09PSAndW5kZWZpbmVkJykKLSAgICAgICAgdGhyb3cgJ3NpZ21hIGlzIG5vdCBkZWNsYXJlZCc7Ci0KLSAgICBpZiAodHlwZW9mIGNvbnJhZCA9PT0gJ3VuZGVmaW5lZCcpCi0gICAgICAgIHRocm93ICdjb25yYWQgaXMgbm90IGRlY2xhcmVkJzsKLQotICAgIC8vIEluaXRpYWxpemUgcGFja2FnZXM6Ci0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5yZW5kZXJlcnMnKTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgdGhlIGNvbnN0cnVjdG9yIG9mIHRoZSBjYW52YXMgc2lnbWEncyByZW5kZXJlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge3NpZ21hLmNsYXNzZXMuZ3JhcGh9ICAgICAgICAgICAgZ3JhcGggICAgVGhlIGdyYXBoIHRvIHJlbmRlci4KLSAgICAgKiBAcGFyYW0gIHtzaWdtYS5jbGFzc2VzLmNhbWVyYX0gICAgICAgICAgIGNhbWVyYSAgIFRoZSBjYW1lcmEuCi0gICAgICogQHBhcmFtICB7Y29uZmlndXJhYmxlfSAgICAgICAgICAgc2V0dGluZ3MgVGhlIHNpZ21hIGluc3RhbmNlIHNldHRpbmdzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24uCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgb2JqZWN0ICAgVGhlIG9wdGlvbnMgb2JqZWN0LgotICAgICAqIEByZXR1cm4ge3NpZ21hLnJlbmRlcmVycy5jYW52YXN9ICAgICAgICAgIFRoZSByZW5kZXJlciBpbnN0YW5jZS4KLSAgICAgKi8KLSAgICBzaWdtYS5yZW5kZXJlcnMuY2FudmFzID0gZnVuY3Rpb24gKGdyYXBoLCBjYW1lcmEsIHNldHRpbmdzLCBvcHRpb25zKSB7Ci0gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpCi0gICAgICAgICAgICB0aHJvdyAnc2lnbWEucmVuZGVyZXJzLmNhbnZhczogV3JvbmcgYXJndW1lbnRzLic7Ci0KLSAgICAgICAgaWYgKCEob3B0aW9ucy5jb250YWluZXIgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpCi0gICAgICAgICAgICB0aHJvdyAnQ29udGFpbmVyIG5vdCBmb3VuZC4nOwotCi0gICAgICAgIHZhciBrLAotICAgICAgICAgICAgaSwKLSAgICAgICAgICAgIGwsCi0gICAgICAgICAgICBhLAotICAgICAgICAgICAgZm4sCi0gICAgICAgICAgICBzZWxmID0gdGhpczsKLQotICAgICAgICBzaWdtYS5jbGFzc2VzLmRpc3BhdGNoZXIuZXh0ZW5kKHRoaXMpOwotCi0gICAgICAgIC8vIEluaXRpYWxpemUgbWFpbiBhdHRyaWJ1dGVzOgotICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2NvbnJhZElkJywgewotICAgICAgICAgICAgdmFsdWU6IHNpZ21hLnV0aWxzLmlkKCkKLSAgICAgICAgfSk7Ci0gICAgICAgIHRoaXMuZ3JhcGggPSBncmFwaDsKLSAgICAgICAgdGhpcy5jYW1lcmEgPSBjYW1lcmE7Ci0gICAgICAgIHRoaXMuY29udGV4dHMgPSB7fTsKLSAgICAgICAgdGhpcy5kb21FbGVtZW50cyA9IHt9OwotICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zOwotICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMub3B0aW9ucy5jb250YWluZXI7Ci0gICAgICAgIHRoaXMuc2V0dGluZ3MgPSAoCi0gICAgICAgICAgICB0eXBlb2Ygb3B0aW9ucy5zZXR0aW5ncyA9PT0gJ29iamVjdCcgJiYKLSAgICAgICAgICAgIG9wdGlvbnMuc2V0dGluZ3MKLSAgICAgICAgKSA/Ci0gICAgICAgICAgICBzZXR0aW5ncy5lbWJlZE9iamVjdHMob3B0aW9ucy5zZXR0aW5ncykgOgotICAgICAgICAgICAgc2V0dGluZ3M7Ci0KLSAgICAgICAgLy8gTm9kZSBpbmRleGVzOgotICAgICAgICB0aGlzLm5vZGVzT25TY3JlZW4gPSBbXTsKLSAgICAgICAgdGhpcy5lZGdlc09uU2NyZWVuID0gW107Ci0KLSAgICAgICAgLy8gQ29ucmFkIHJlbGF0ZWQgYXR0cmlidXRlczoKLSAgICAgICAgdGhpcy5qb2JzID0ge307Ci0KLSAgICAgICAgLy8gRmluZCB0aGUgcHJlZml4OgotICAgICAgICB0aGlzLm9wdGlvbnMucHJlZml4ID0gJ3JlbmRlcmVyJyArIHRoaXMuY29ucmFkSWQgKyAnOic7Ci0KLSAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGUgRE9NIGVsZW1lbnRzOgotICAgICAgICBpZiAoCi0gICAgICAgICAgICAhdGhpcy5zZXR0aW5ncygnYmF0Y2hFZGdlc0RyYXdpbmcnKQotICAgICAgICApIHsKLSAgICAgICAgICAgIHRoaXMuaW5pdERPTSgnY2FudmFzJywgJ3NjZW5lJyk7Ci0gICAgICAgICAgICB0aGlzLmNvbnRleHRzLmVkZ2VzID0gdGhpcy5jb250ZXh0cy5zY2VuZTsKLSAgICAgICAgICAgIHRoaXMuY29udGV4dHMubm9kZXMgPSB0aGlzLmNvbnRleHRzLnNjZW5lOwotICAgICAgICAgICAgdGhpcy5jb250ZXh0cy5sYWJlbHMgPSB0aGlzLmNvbnRleHRzLnNjZW5lOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdGhpcy5pbml0RE9NKCdjYW52YXMnLCAnZWRnZXMnKTsKLSAgICAgICAgICAgIHRoaXMuaW5pdERPTSgnY2FudmFzJywgJ3NjZW5lJyk7Ci0gICAgICAgICAgICB0aGlzLmNvbnRleHRzLm5vZGVzID0gdGhpcy5jb250ZXh0cy5zY2VuZTsKLSAgICAgICAgICAgIHRoaXMuY29udGV4dHMubGFiZWxzID0gdGhpcy5jb250ZXh0cy5zY2VuZTsKLSAgICAgICAgfQotCi0gICAgICAgIHRoaXMuaW5pdERPTSgnY2FudmFzJywgJ21vdXNlJyk7Ci0gICAgICAgIHRoaXMuY29udGV4dHMuaG92ZXIgPSB0aGlzLmNvbnRleHRzLm1vdXNlOwotCi0gICAgICAgIC8vIEluaXRpYWxpemUgY2FwdG9yczoKLSAgICAgICAgdGhpcy5jYXB0b3JzID0gW107Ci0gICAgICAgIGEgPSB0aGlzLm9wdGlvbnMuY2FwdG9ycyB8fCBbc2lnbWEuY2FwdG9ycy5tb3VzZSwgc2lnbWEuY2FwdG9ycy50b3VjaF07Ci0gICAgICAgIGZvciAoaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykgewotICAgICAgICAgICAgZm4gPSB0eXBlb2YgYVtpXSA9PT0gJ2Z1bmN0aW9uJyA/IGFbaV0gOiBzaWdtYS5jYXB0b3JzW2FbaV1dOwotICAgICAgICAgICAgdGhpcy5jYXB0b3JzLnB1c2goCi0gICAgICAgICAgICAgICAgbmV3IGZuKAotICAgICAgICAgICAgICAgICAgICB0aGlzLmRvbUVsZW1lbnRzLm1vdXNlLAotICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYSwKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXR0aW5ncwotICAgICAgICAgICAgICAgICkKLSAgICAgICAgICAgICk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBEZWFsIHdpdGggc2lnbWEgZXZlbnRzOgotICAgICAgICBzaWdtYS5taXNjLmJpbmRFdmVudHMuY2FsbCh0aGlzLCB0aGlzLm9wdGlvbnMucHJlZml4KTsKLSAgICAgICAgc2lnbWEubWlzYy5kcmF3SG92ZXJzLmNhbGwodGhpcywgdGhpcy5vcHRpb25zLnByZWZpeCk7Ci0KLSAgICAgICAgdGhpcy5yZXNpemUoZmFsc2UpOwotICAgIH07Ci0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHJlbmRlcnMgdGhlIGdyYXBoIG9uIHRoZSBjYW52YXNlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgez9vYmplY3R9ICAgICAgICAgICAgICAgIG9wdGlvbnMgRXZlbnR1YWxseSBhbiBvYmplY3Qgb2Ygb3B0aW9ucy4KLSAgICAgKiBAcmV0dXJuIHtzaWdtYS5yZW5kZXJlcnMuY2FudmFzfSAgICAgICAgIFJldHVybnMgdGhlIGluc3RhbmNlIGl0c2VsZi4KLSAgICAgKi8KLSAgICBzaWdtYS5yZW5kZXJlcnMuY2FudmFzLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAob3B0aW9ucykgewotICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKLQotICAgICAgICB2YXIgYSwKLSAgICAgICAgICAgIGksCi0gICAgICAgICAgICBrLAotICAgICAgICAgICAgbCwKLSAgICAgICAgICAgIG8sCi0gICAgICAgICAgICBpZCwKLSAgICAgICAgICAgIGVuZCwKLSAgICAgICAgICAgIGpvYiwKLSAgICAgICAgICAgIHN0YXJ0LAotICAgICAgICAgICAgZWRnZXMsCi0gICAgICAgICAgICByZW5kZXJlcnMsCi0gICAgICAgICAgICByZW5kZXJlclR5cGUsCi0gICAgICAgICAgICBiYXRjaFNpemUsCi0gICAgICAgICAgICB0ZW1wR0NPLAotICAgICAgICAgICAgaW5kZXggPSB7fSwKLSAgICAgICAgICAgIGdyYXBoID0gdGhpcy5ncmFwaCwKLSAgICAgICAgICAgIG5vZGVzID0gdGhpcy5ncmFwaC5ub2RlcywKLSAgICAgICAgICAgIHByZWZpeCA9IHRoaXMub3B0aW9ucy5wcmVmaXggfHwgJycsCi0gICAgICAgICAgICBkcmF3RWRnZXMgPSB0aGlzLnNldHRpbmdzKG9wdGlvbnMsICdkcmF3RWRnZXMnKSwKLSAgICAgICAgICAgIGRyYXdOb2RlcyA9IHRoaXMuc2V0dGluZ3Mob3B0aW9ucywgJ2RyYXdOb2RlcycpLAotICAgICAgICAgICAgZHJhd0xhYmVscyA9IHRoaXMuc2V0dGluZ3Mob3B0aW9ucywgJ2RyYXdMYWJlbHMnKSwKLSAgICAgICAgICAgIGRyYXdFZGdlTGFiZWxzID0gdGhpcy5zZXR0aW5ncyhvcHRpb25zLCAnZHJhd0VkZ2VMYWJlbHMnKSwKLSAgICAgICAgICAgIGVtYmVkU2V0dGluZ3MgPSB0aGlzLnNldHRpbmdzLmVtYmVkT2JqZWN0cyhvcHRpb25zLCB7Ci0gICAgICAgICAgICAgICAgcHJlZml4OiB0aGlzLm9wdGlvbnMucHJlZml4Ci0gICAgICAgICAgICB9KTsKLQotICAgICAgICAvLyBDYWxsIHRoZSByZXNpemUgZnVuY3Rpb246Ci0gICAgICAgIHRoaXMucmVzaXplKGZhbHNlKTsKLQotICAgICAgICAvLyBDaGVjayB0aGUgJ2hpZGVFZGdlc09uTW92ZScgc2V0dGluZzoKLSAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3Mob3B0aW9ucywgJ2hpZGVFZGdlc09uTW92ZScpKQotICAgICAgICAgICAgaWYgKHRoaXMuY2FtZXJhLmlzQW5pbWF0ZWQgfHwgdGhpcy5jYW1lcmEuaXNNb3ZpbmcpCi0gICAgICAgICAgICAgICAgZHJhd0VkZ2VzID0gZmFsc2U7Ci0KLSAgICAgICAgLy8gQXBwbHkgdGhlIGNhbWVyYSdzIHZpZXc6Ci0gICAgICAgIHRoaXMuY2FtZXJhLmFwcGx5VmlldygKLSAgICAgICAgICAgIHVuZGVmaW5lZCwKLSAgICAgICAgICAgIHRoaXMub3B0aW9ucy5wcmVmaXgsCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMud2lkdGgsCi0gICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLmhlaWdodAotICAgICAgICAgICAgfQotICAgICAgICApOwotCi0gICAgICAgIC8vIENsZWFyIGNhbnZhc2VzOgotICAgICAgICB0aGlzLmNsZWFyKCk7Ci0KLSAgICAgICAgLy8gS2lsbCBydW5uaW5nIGpvYnM6Ci0gICAgICAgIGZvciAoayBpbiB0aGlzLmpvYnMpCi0gICAgICAgICAgICBpZiAoY29ucmFkLmhhc0pvYihrKSkKLSAgICAgICAgICAgICAgICBjb25yYWQua2lsbEpvYihrKTsKLQotICAgICAgICAvLyBGaW5kIHdoaWNoIG5vZGVzIGFyZSBvbiBzY3JlZW46Ci0gICAgICAgIHRoaXMuZWRnZXNPblNjcmVlbiA9IFtdOwotICAgICAgICB0aGlzLm5vZGVzT25TY3JlZW4gPSB0aGlzLmNhbWVyYS5xdWFkdHJlZS5hcmVhKAotICAgICAgICAgICAgdGhpcy5jYW1lcmEuZ2V0UmVjdGFuZ2xlKHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KQotICAgICAgICApOwotCi0gICAgICAgIGZvciAoYSA9IHRoaXMubm9kZXNPblNjcmVlbiwgaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgIGluZGV4W2FbaV0uaWRdID0gYVtpXTsKLQotICAgICAgICAvLyBEcmF3IGVkZ2VzOgotICAgICAgICAvLyAtIElmIHNldHRpbmdzKCdiYXRjaEVkZ2VzRHJhd2luZycpIGlzIHRydWUsIHRoZSBlZGdlcyBhcmUgZGlzcGxheWVkIHBlcgotICAgICAgICAvLyAgIGJhdGNoZXMuIElmIG5vdCwgdGhleSBhcmUgZHJhd24gaW4gb25lIGZyYW1lLgotICAgICAgICBpZiAoZHJhd0VkZ2VzKSB7Ci0gICAgICAgICAgICAvLyBGaXJzdCwgbGV0J3MgaWRlbnRpZnkgd2hpY2ggZWRnZXMgdG8gZHJhdy4gVG8gZG8gdGhpcywgd2UganVzdCBrZWVwCi0gICAgICAgICAgICAvLyBldmVyeSBlZGdlcyB0aGF0IGhhdmUgYXQgbGVhc3Qgb25lIGV4dHJlbWl0eSBkaXNwbGF5ZWQgYWNjb3JkaW5nIHRvCi0gICAgICAgICAgICAvLyB0aGUgcXVhZHRyZWUgYW5kIHRoZSAiaGlkZGVuIiBhdHRyaWJ1dGUuIFdlIGFsc28gZG8gbm90IGtlZXAgaGlkZGVuCi0gICAgICAgICAgICAvLyBlZGdlcy4KLSAgICAgICAgICAgIGZvciAoYSA9IGdyYXBoLmVkZ2VzKCksIGkgPSAwLCBsID0gYS5sZW5ndGg7IGkgPCBsOyBpKyspIHsKLSAgICAgICAgICAgICAgICBvID0gYVtpXTsKLSAgICAgICAgICAgICAgICBpZiAoCi0gICAgICAgICAgICAgICAgICAgIChpbmRleFtvLnNvdXJjZV0gfHwgaW5kZXhbby50YXJnZXRdKSAmJgotICAgICAgICAgICAgICAgICAgICAoIW8uaGlkZGVuICYmICFub2RlcyhvLnNvdXJjZSkuaGlkZGVuICYmICFub2RlcyhvLnRhcmdldCkuaGlkZGVuKQotICAgICAgICAgICAgICAgICkKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5lZGdlc09uU2NyZWVuLnB1c2gobyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIElmIHRoZSAiYmF0Y2hFZGdlc0RyYXdpbmciIHNldHRpbmdzIGlzIHRydWUsIGVkZ2VzIGFyZSBiYXRjaGVkOgotICAgICAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3Mob3B0aW9ucywgJ2JhdGNoRWRnZXNEcmF3aW5nJykpIHsKLSAgICAgICAgICAgICAgICBpZCA9ICdlZGdlc18nICsgdGhpcy5jb25yYWRJZDsKLSAgICAgICAgICAgICAgICBiYXRjaFNpemUgPSBlbWJlZFNldHRpbmdzKCdjYW52YXNFZGdlc0JhdGNoU2l6ZScpOwotCi0gICAgICAgICAgICAgICAgZWRnZXMgPSB0aGlzLmVkZ2VzT25TY3JlZW47Ci0gICAgICAgICAgICAgICAgbCA9IGVkZ2VzLmxlbmd0aDsKLQotICAgICAgICAgICAgICAgIHN0YXJ0ID0gMDsKLSAgICAgICAgICAgICAgICBlbmQgPSBNYXRoLm1pbihlZGdlcy5sZW5ndGgsIHN0YXJ0ICsgYmF0Y2hTaXplKTsKLQotICAgICAgICAgICAgICAgIGpvYiA9IGZ1bmN0aW9uICgpIHsKLSAgICAgICAgICAgICAgICAgICAgdGVtcEdDTyA9IHRoaXMuY29udGV4dHMuZWRnZXMuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uOwotICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHRzLmVkZ2VzLmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICdkZXN0aW5hdGlvbi1vdmVyJzsKLQotICAgICAgICAgICAgICAgICAgICByZW5kZXJlcnMgPSBzaWdtYS5jYW52YXMuZWRnZXM7Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG8gPSBlZGdlc1tpXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIChyZW5kZXJlcnNbCi0gICAgICAgICAgICAgICAgICAgICAgICBvLnR5cGUgfHwgdGhpcy5zZXR0aW5ncyhvcHRpb25zLCAnZGVmYXVsdEVkZ2VUeXBlJykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBdIHx8IHJlbmRlcmVycy5kZWYpKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JhcGgubm9kZXMoby5zb3VyY2UpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyYXBoLm5vZGVzKG8udGFyZ2V0KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHRzLmVkZ2VzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkU2V0dGluZ3MKLSAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyBEcmF3IGVkZ2UgbGFiZWxzOgotICAgICAgICAgICAgICAgICAgICBpZiAoZHJhd0VkZ2VMYWJlbHMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlcmVycyA9IHNpZ21hLmNhbnZhcy5lZGdlcy5sYWJlbHM7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbyA9IGVkZ2VzW2ldOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghby5oaWRkZW4pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW5kZXJlcnNbCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG8udHlwZSB8fCB0aGlzLnNldHRpbmdzKG9wdGlvbnMsICdkZWZhdWx0RWRnZVR5cGUnKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXSB8fCByZW5kZXJlcnMuZGVmKSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmFwaC5ub2RlcyhvLnNvdXJjZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmFwaC5ub2RlcyhvLnRhcmdldCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHRzLmxhYmVscywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkU2V0dGluZ3MKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIC8vIFJlc3RvcmUgb3JpZ2luYWwgZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uOgotICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHRzLmVkZ2VzLmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9IHRlbXBHQ087Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gQ2F0Y2ggam9iJ3MgZW5kOgotICAgICAgICAgICAgICAgICAgICBpZiAoZW5kID09PSBlZGdlcy5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmpvYnNbaWRdOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgc3RhcnQgPSBlbmQgKyAxOwotICAgICAgICAgICAgICAgICAgICBlbmQgPSBNYXRoLm1pbihlZGdlcy5sZW5ndGgsIHN0YXJ0ICsgYmF0Y2hTaXplKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfTsKLQotICAgICAgICAgICAgICAgIHRoaXMuam9ic1tpZF0gPSBqb2I7Ci0gICAgICAgICAgICAgICAgY29ucmFkLmFkZEpvYihpZCwgam9iLmJpbmQodGhpcykpOwotCi0gICAgICAgICAgICAgICAgLy8gSWYgbm90LCB0aGV5IGFyZSBkcmF3biBpbiBvbmUgZnJhbWU6Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJlbmRlcmVycyA9IHNpZ21hLmNhbnZhcy5lZGdlczsKLSAgICAgICAgICAgICAgICBmb3IgKGEgPSB0aGlzLmVkZ2VzT25TY3JlZW4sIGkgPSAwLCBsID0gYS5sZW5ndGg7IGkgPCBsOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgbyA9IGFbaV07Ci0gICAgICAgICAgICAgICAgICAgIChyZW5kZXJlcnNbCi0gICAgICAgICAgICAgICAgICAgIG8udHlwZSB8fCB0aGlzLnNldHRpbmdzKG9wdGlvbnMsICdkZWZhdWx0RWRnZVR5cGUnKQotICAgICAgICAgICAgICAgICAgICAgICAgXSB8fCByZW5kZXJlcnMuZGVmKSgKLSAgICAgICAgICAgICAgICAgICAgICAgIG8sCi0gICAgICAgICAgICAgICAgICAgICAgICBncmFwaC5ub2RlcyhvLnNvdXJjZSksCi0gICAgICAgICAgICAgICAgICAgICAgICBncmFwaC5ub2RlcyhvLnRhcmdldCksCi0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHRzLmVkZ2VzLAotICAgICAgICAgICAgICAgICAgICAgICAgZW1iZWRTZXR0aW5ncwotICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIERyYXcgZWRnZSBsYWJlbHM6Ci0gICAgICAgICAgICAgICAgLy8gLSBObyBiYXRjaGluZwotICAgICAgICAgICAgICAgIGlmIChkcmF3RWRnZUxhYmVscykgewotICAgICAgICAgICAgICAgICAgICByZW5kZXJlcnMgPSBzaWdtYS5jYW52YXMuZWRnZXMubGFiZWxzOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGEgPSB0aGlzLmVkZ2VzT25TY3JlZW4sIGkgPSAwLCBsID0gYS5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFbaV0uaGlkZGVuKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW5kZXJlcnNbCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYVtpXS50eXBlIHx8IHRoaXMuc2V0dGluZ3Mob3B0aW9ucywgJ2RlZmF1bHRFZGdlVHlwZScpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0gfHwgcmVuZGVyZXJzLmRlZikoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFbaV0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyYXBoLm5vZGVzKGFbaV0uc291cmNlKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JhcGgubm9kZXMoYVtpXS50YXJnZXQpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHRzLmxhYmVscywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1iZWRTZXR0aW5ncwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gRHJhdyBub2RlczoKLSAgICAgICAgLy8gLSBObyBiYXRjaGluZwotICAgICAgICBpZiAoZHJhd05vZGVzKSB7Ci0gICAgICAgICAgICByZW5kZXJlcnMgPSBzaWdtYS5jYW52YXMubm9kZXM7Ci0gICAgICAgICAgICBmb3IgKGEgPSB0aGlzLm5vZGVzT25TY3JlZW4sIGkgPSAwLCBsID0gYS5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICAgICAgaWYgKCFhW2ldLmhpZGRlbikKLSAgICAgICAgICAgICAgICAgICAgKHJlbmRlcmVyc1sKLSAgICAgICAgICAgICAgICAgICAgYVtpXS50eXBlIHx8IHRoaXMuc2V0dGluZ3Mob3B0aW9ucywgJ2RlZmF1bHROb2RlVHlwZScpCi0gICAgICAgICAgICAgICAgICAgICAgICBdIHx8IHJlbmRlcmVycy5kZWYpKAotICAgICAgICAgICAgICAgICAgICAgICAgYVtpXSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dHMubm9kZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICBlbWJlZFNldHRpbmdzCi0gICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBEcmF3IGxhYmVsczoKLSAgICAgICAgLy8gLSBObyBiYXRjaGluZwotICAgICAgICBpZiAoZHJhd0xhYmVscykgewotICAgICAgICAgICAgcmVuZGVyZXJzID0gc2lnbWEuY2FudmFzLmxhYmVsczsKLSAgICAgICAgICAgIGZvciAoYSA9IHRoaXMubm9kZXNPblNjcmVlbiwgaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgICAgICBpZiAoIWFbaV0uaGlkZGVuKQotICAgICAgICAgICAgICAgICAgICAocmVuZGVyZXJzWwotICAgICAgICAgICAgICAgICAgICBhW2ldLnR5cGUgfHwgdGhpcy5zZXR0aW5ncyhvcHRpb25zLCAnZGVmYXVsdE5vZGVUeXBlJykKLSAgICAgICAgICAgICAgICAgICAgICAgIF0gfHwgcmVuZGVyZXJzLmRlZikoCi0gICAgICAgICAgICAgICAgICAgICAgICBhW2ldLAotICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0cy5sYWJlbHMsCi0gICAgICAgICAgICAgICAgICAgICAgICBlbWJlZFNldHRpbmdzCi0gICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgIH0KLQotICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoJ3JlbmRlcicpOwotCi0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBjcmVhdGVzIGEgRE9NIGVsZW1lbnQgb2YgdGhlIHNwZWNpZmllZCB0eXBlLCBzd2l0Y2hlcyBpdHMKLSAgICAgKiBwb3NpdGlvbiB0byAiYWJzb2x1dGUiLCByZWZlcmVuY2VzIGl0IHRvIHRoZSBkb21FbGVtZW50cyBhdHRyaWJ1dGUsIGFuZAotICAgICAqIGZpbmFsbHkgYXBwZW5kcyBpdCB0byB0aGUgY29udGFpbmVyLgotICAgICAqCi0gICAgICogQHBhcmFtICB7c3RyaW5nfSB0YWcgVGhlIGxhYmVsIHRhZy4KLSAgICAgKiBAcGFyYW0gIHtzdHJpbmd9IGlkICBUaGUgaWQgb2YgdGhlIGVsZW1lbnQgKHRvIHN0b3JlIGl0IGluICJkb21FbGVtZW50cyIpLgotICAgICAqLwotICAgIHNpZ21hLnJlbmRlcmVycy5jYW52YXMucHJvdG90eXBlLmluaXRET00gPSBmdW5jdGlvbiAodGFnLCBpZCkgewotICAgICAgICB2YXIgZG9tID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWcpOwotCi0gICAgICAgIGRvbS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7Ci0gICAgICAgIGRvbS5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ3NpZ21hLScgKyBpZCk7Ci0KLSAgICAgICAgdGhpcy5kb21FbGVtZW50c1tpZF0gPSBkb207Ci0gICAgICAgIHRoaXMuY29udGFpbmVyLmFwcGVuZENoaWxkKGRvbSk7Ci0KLSAgICAgICAgaWYgKHRhZy50b0xvd2VyQ2FzZSgpID09PSAnY2FudmFzJykKLSAgICAgICAgICAgIHRoaXMuY29udGV4dHNbaWRdID0gZG9tLmdldENvbnRleHQoJzJkJyk7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHJlc2l6ZXMgZWFjaCBET00gZWxlbWVudHMgaW4gdGhlIGNvbnRhaW5lciBhbmQgc3RvcmVzIHRoZSBuZXcKLSAgICAgKiBkaW1lbnNpb25zLiBUaGVuLCBpdCByZW5kZXJzIHRoZSBncmFwaC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgez9udW1iZXJ9ICAgICAgICAgICAgICAgIHdpZHRoICBUaGUgbmV3IHdpZHRoIG9mIHRoZSBjb250YWluZXIuCi0gICAgICogQHBhcmFtICB7P251bWJlcn0gICAgICAgICAgICAgICAgaGVpZ2h0IFRoZSBuZXcgaGVpZ2h0IG9mIHRoZSBjb250YWluZXIuCi0gICAgICogQHJldHVybiB7c2lnbWEucmVuZGVyZXJzLmNhbnZhc30gICAgICAgIFJldHVybnMgdGhlIGluc3RhbmNlIGl0c2VsZi4KLSAgICAgKi8KLSAgICBzaWdtYS5yZW5kZXJlcnMuY2FudmFzLnByb3RvdHlwZS5yZXNpemUgPSBmdW5jdGlvbiAodywgaCkgewotICAgICAgICB2YXIgaywKLSAgICAgICAgICAgIG9sZFdpZHRoID0gdGhpcy53aWR0aCwKLSAgICAgICAgICAgIG9sZEhlaWdodCA9IHRoaXMuaGVpZ2h0LAotICAgICAgICAgICAgcGl4ZWxSYXRpbyA9IHNpZ21hLnV0aWxzLmdldFBpeGVsUmF0aW8oKTsKLQotICAgICAgICBpZiAodyAhPT0gdW5kZWZpbmVkICYmIGggIT09IHVuZGVmaW5lZCkgewotICAgICAgICAgICAgdGhpcy53aWR0aCA9IHc7Ci0gICAgICAgICAgICB0aGlzLmhlaWdodCA9IGg7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy5jb250YWluZXIub2Zmc2V0V2lkdGg7Ci0gICAgICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMuY29udGFpbmVyLm9mZnNldEhlaWdodDsKLQotICAgICAgICAgICAgdyA9IHRoaXMud2lkdGg7Ci0gICAgICAgICAgICBoID0gdGhpcy5oZWlnaHQ7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAob2xkV2lkdGggIT09IHRoaXMud2lkdGggfHwgb2xkSGVpZ2h0ICE9PSB0aGlzLmhlaWdodCkgewotICAgICAgICAgICAgZm9yIChrIGluIHRoaXMuZG9tRWxlbWVudHMpIHsKLSAgICAgICAgICAgICAgICB0aGlzLmRvbUVsZW1lbnRzW2tdLnN0eWxlLndpZHRoID0gdyArICdweCc7Ci0gICAgICAgICAgICAgICAgdGhpcy5kb21FbGVtZW50c1trXS5zdHlsZS5oZWlnaHQgPSBoICsgJ3B4JzsKLQotICAgICAgICAgICAgICAgIGlmICh0aGlzLmRvbUVsZW1lbnRzW2tdLnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2NhbnZhcycpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5kb21FbGVtZW50c1trXS5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgKHcgKiBwaXhlbFJhdGlvKSArICdweCcpOwotICAgICAgICAgICAgICAgICAgICB0aGlzLmRvbUVsZW1lbnRzW2tdLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgKGggKiBwaXhlbFJhdGlvKSArICdweCcpOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChwaXhlbFJhdGlvICE9PSAxKQotICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0c1trXS5zY2FsZShwaXhlbFJhdGlvLCBwaXhlbFJhdGlvKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgY2xlYXJzIGVhY2ggY2FudmFzLgotICAgICAqCi0gICAgICogQHJldHVybiB7c2lnbWEucmVuZGVyZXJzLmNhbnZhc30gUmV0dXJucyB0aGUgaW5zdGFuY2UgaXRzZWxmLgotICAgICAqLwotICAgIHNpZ21hLnJlbmRlcmVycy5jYW52YXMucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkgewotICAgICAgICBmb3IgKHZhciBrIGluIHRoaXMuY29udGV4dHMpIHsKLSAgICAgICAgICAgIHRoaXMuY29udGV4dHNba10uY2xlYXJSZWN0KDAsIDAsIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBraWxscyBjb250ZXh0cyBhbmQgb3RoZXIgYXR0cmlidXRlcy4KLSAgICAgKi8KLSAgICBzaWdtYS5yZW5kZXJlcnMuY2FudmFzLnByb3RvdHlwZS5raWxsID0gZnVuY3Rpb24gKCkgewotICAgICAgICB2YXIgaywKLSAgICAgICAgICAgIGNhcHRvcjsKLQotICAgICAgICAvLyBLaWxsIGNhcHRvcnM6Ci0gICAgICAgIHdoaWxlICgoY2FwdG9yID0gdGhpcy5jYXB0b3JzLnBvcCgpKSkKLSAgICAgICAgICAgIGNhcHRvci5raWxsKCk7Ci0gICAgICAgIGRlbGV0ZSB0aGlzLmNhcHRvcnM7Ci0KLSAgICAgICAgLy8gS2lsbCBjb250ZXh0czoKLSAgICAgICAgZm9yIChrIGluIHRoaXMuZG9tRWxlbWVudHMpIHsKLSAgICAgICAgICAgIHRoaXMuZG9tRWxlbWVudHNba10ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLmRvbUVsZW1lbnRzW2tdKTsKLSAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmRvbUVsZW1lbnRzW2tdOwotICAgICAgICAgICAgZGVsZXRlIHRoaXMuY29udGV4dHNba107Ci0gICAgICAgIH0KLSAgICAgICAgZGVsZXRlIHRoaXMuZG9tRWxlbWVudHM7Ci0gICAgICAgIGRlbGV0ZSB0aGlzLmNvbnRleHRzOwotICAgIH07Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBsYWJlbHMsIG5vZGVzIGFuZCBlZGdlcyByZW5kZXJlcnMgYXJlIHN0b3JlZCBpbiB0aGUgdGhyZWUgZm9sbG93aW5nCi0gICAgICogb2JqZWN0cy4gV2hlbiBhbiBlbGVtZW50IGlzIGRyYXduLCBpdHMgdHlwZSB3aWxsIGJlIGNoZWNrZWQgYW5kIGlmIGEKLSAgICAgKiByZW5kZXJlciB3aXRoIHRoZSBzYW1lIG5hbWUgZXhpc3RzLCBpdCB3aWxsIGJlIHVzZWQuIElmIG5vdCBmb3VuZCwgdGhlCi0gICAgICogZGVmYXVsdCByZW5kZXJlciB3aWxsIGJlIHVzZWQgaW5zdGVhZC4KLSAgICAgKgotICAgICAqIFRoZXkgYXJlIHN0b3JlZCBpbiBkaWZmZXJlbnQgZmlsZXMsIGluIHRoZSAiLi9jYW52YXMiIGZvbGRlci4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLmNhbnZhcy5ub2RlcycpOwotICAgIHNpZ21hLnV0aWxzLnBrZygnc2lnbWEuY2FudmFzLmVkZ2VzJyk7Ci0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5jYW52YXMubGFiZWxzJyk7Ci19KS5jYWxsKHRoaXMpOwotCi07KGZ1bmN0aW9uICh1bmRlZmluZWQpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBpZiAodHlwZW9mIHNpZ21hID09PSAndW5kZWZpbmVkJykKLSAgICAgICAgdGhyb3cgJ3NpZ21hIGlzIG5vdCBkZWNsYXJlZCc7Ci0KLSAgICAvLyBJbml0aWFsaXplIHBhY2thZ2VzOgotICAgIHNpZ21hLnV0aWxzLnBrZygnc2lnbWEucmVuZGVyZXJzJyk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHRoZSBjb25zdHJ1Y3RvciBvZiB0aGUgY2FudmFzIHNpZ21hJ3MgcmVuZGVyZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtzaWdtYS5jbGFzc2VzLmdyYXBofSAgICAgICAgICAgIGdyYXBoICAgIFRoZSBncmFwaCB0byByZW5kZXIuCi0gICAgICogQHBhcmFtICB7c2lnbWEuY2xhc3Nlcy5jYW1lcmF9ICAgICAgICAgICBjYW1lcmEgICBUaGUgY2FtZXJhLgotICAgICAqIEBwYXJhbSAge2NvbmZpZ3VyYWJsZX0gICAgICAgICAgIHNldHRpbmdzIFRoZSBzaWdtYSBpbnN0YW5jZSBzZXR0aW5ncwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uLgotICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgIG9iamVjdCAgIFRoZSBvcHRpb25zIG9iamVjdC4KLSAgICAgKiBAcmV0dXJuIHtzaWdtYS5yZW5kZXJlcnMuY2FudmFzfSAgICAgICAgICBUaGUgcmVuZGVyZXIgaW5zdGFuY2UuCi0gICAgICovCi0gICAgc2lnbWEucmVuZGVyZXJzLndlYmdsID0gZnVuY3Rpb24gKGdyYXBoLCBjYW1lcmEsIHNldHRpbmdzLCBvcHRpb25zKSB7Ci0gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpCi0gICAgICAgICAgICB0aHJvdyAnc2lnbWEucmVuZGVyZXJzLndlYmdsOiBXcm9uZyBhcmd1bWVudHMuJzsKLQotICAgICAgICBpZiAoIShvcHRpb25zLmNvbnRhaW5lciBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkKLSAgICAgICAgICAgIHRocm93ICdDb250YWluZXIgbm90IGZvdW5kLic7Ci0KLSAgICAgICAgdmFyIGssCi0gICAgICAgICAgICBpLAotICAgICAgICAgICAgbCwKLSAgICAgICAgICAgIGEsCi0gICAgICAgICAgICBmbiwKLSAgICAgICAgICAgIF9zZWxmID0gdGhpczsKLQotICAgICAgICBzaWdtYS5jbGFzc2VzLmRpc3BhdGNoZXIuZXh0ZW5kKHRoaXMpOwotCi0gICAgICAgIC8vIENvbnJhZCByZWxhdGVkIGF0dHJpYnV0ZXM6Ci0gICAgICAgIHRoaXMuam9icyA9IHt9OwotCi0gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnY29ucmFkSWQnLCB7Ci0gICAgICAgICAgICB2YWx1ZTogc2lnbWEudXRpbHMuaWQoKQotICAgICAgICB9KTsKLQotICAgICAgICAvLyBJbml0aWFsaXplIG1haW4gYXR0cmlidXRlczoKLSAgICAgICAgdGhpcy5ncmFwaCA9IGdyYXBoOwotICAgICAgICB0aGlzLmNhbWVyYSA9IGNhbWVyYTsKLSAgICAgICAgdGhpcy5jb250ZXh0cyA9IHt9OwotICAgICAgICB0aGlzLmRvbUVsZW1lbnRzID0ge307Ci0gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7Ci0gICAgICAgIHRoaXMuY29udGFpbmVyID0gdGhpcy5vcHRpb25zLmNvbnRhaW5lcjsKLSAgICAgICAgdGhpcy5zZXR0aW5ncyA9ICgKLSAgICAgICAgICAgIHR5cGVvZiBvcHRpb25zLnNldHRpbmdzID09PSAnb2JqZWN0JyAmJgotICAgICAgICAgICAgb3B0aW9ucy5zZXR0aW5ncwotICAgICAgICApID8KLSAgICAgICAgICAgIHNldHRpbmdzLmVtYmVkT2JqZWN0cyhvcHRpb25zLnNldHRpbmdzKSA6Ci0gICAgICAgICAgICBzZXR0aW5nczsKLQotICAgICAgICAvLyBGaW5kIHRoZSBwcmVmaXg6Ci0gICAgICAgIHRoaXMub3B0aW9ucy5wcmVmaXggPSB0aGlzLmNhbWVyYS5yZWFkUHJlZml4OwotCi0gICAgICAgIC8vIEluaXRpYWxpemUgcHJvZ3JhbXMgaGFzaAotICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ25vZGVQcm9ncmFtcycsIHsKLSAgICAgICAgICAgIHZhbHVlOiB7fQotICAgICAgICB9KTsKLSAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdlZGdlUHJvZ3JhbXMnLCB7Ci0gICAgICAgICAgICB2YWx1ZToge30KLSAgICAgICAgfSk7Ci0gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnbm9kZUZsb2F0QXJyYXlzJywgewotICAgICAgICAgICAgdmFsdWU6IHt9Ci0gICAgICAgIH0pOwotICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2VkZ2VGbG9hdEFycmF5cycsIHsKLSAgICAgICAgICAgIHZhbHVlOiB7fQotICAgICAgICB9KTsKLSAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdlZGdlSW5kaWNlc0FycmF5cycsIHsKLSAgICAgICAgICAgIHZhbHVlOiB7fQotICAgICAgICB9KTsKLQotICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBET00gZWxlbWVudHM6Ci0gICAgICAgIGlmICh0aGlzLnNldHRpbmdzKG9wdGlvbnMsICdiYXRjaEVkZ2VzRHJhd2luZycpKSB7Ci0gICAgICAgICAgICB0aGlzLmluaXRET00oJ2NhbnZhcycsICdlZGdlcycsIHRydWUpOwotICAgICAgICAgICAgdGhpcy5pbml0RE9NKCdjYW52YXMnLCAnbm9kZXMnLCB0cnVlKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHRoaXMuaW5pdERPTSgnY2FudmFzJywgJ3NjZW5lJywgdHJ1ZSk7Ci0gICAgICAgICAgICB0aGlzLmNvbnRleHRzLm5vZGVzID0gdGhpcy5jb250ZXh0cy5zY2VuZTsKLSAgICAgICAgICAgIHRoaXMuY29udGV4dHMuZWRnZXMgPSB0aGlzLmNvbnRleHRzLnNjZW5lOwotICAgICAgICB9Ci0KLSAgICAgICAgdGhpcy5pbml0RE9NKCdjYW52YXMnLCAnbGFiZWxzJyk7Ci0gICAgICAgIHRoaXMuaW5pdERPTSgnY2FudmFzJywgJ21vdXNlJyk7Ci0gICAgICAgIHRoaXMuY29udGV4dHMuaG92ZXIgPSB0aGlzLmNvbnRleHRzLm1vdXNlOwotCi0gICAgICAgIC8vIEluaXRpYWxpemUgY2FwdG9yczoKLSAgICAgICAgdGhpcy5jYXB0b3JzID0gW107Ci0gICAgICAgIGEgPSB0aGlzLm9wdGlvbnMuY2FwdG9ycyB8fCBbc2lnbWEuY2FwdG9ycy5tb3VzZSwgc2lnbWEuY2FwdG9ycy50b3VjaF07Ci0gICAgICAgIGZvciAoaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykgewotICAgICAgICAgICAgZm4gPSB0eXBlb2YgYVtpXSA9PT0gJ2Z1bmN0aW9uJyA/IGFbaV0gOiBzaWdtYS5jYXB0b3JzW2FbaV1dOwotICAgICAgICAgICAgdGhpcy5jYXB0b3JzLnB1c2goCi0gICAgICAgICAgICAgICAgbmV3IGZuKAotICAgICAgICAgICAgICAgICAgICB0aGlzLmRvbUVsZW1lbnRzLm1vdXNlLAotICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYSwKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXR0aW5ncwotICAgICAgICAgICAgICAgICkKLSAgICAgICAgICAgICk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBEZWFsIHdpdGggc2lnbWEgZXZlbnRzOgotICAgICAgICBzaWdtYS5taXNjLmJpbmRFdmVudHMuY2FsbCh0aGlzLCB0aGlzLmNhbWVyYS5wcmVmaXgpOwotICAgICAgICBzaWdtYS5taXNjLmRyYXdIb3ZlcnMuY2FsbCh0aGlzLCB0aGlzLmNhbWVyYS5wcmVmaXgpOwotCi0gICAgICAgIHRoaXMucmVzaXplKCk7Ci0gICAgfTsKLQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgd2lsbCBnZW5lcmF0ZSB0aGUgbm9kZXMgYW5kIGVkZ2VzIGZsb2F0IGFycmF5cy4gVGhpcyBzdGVwIGlzCi0gICAgICogc2VwYXJhdGVkIGZyb20gdGhlICJyZW5kZXIiIG1ldGhvZCwgYmVjYXVzZSB0byBrZWVwIFdlYkdMIGVmZmljaWVudCwgc2luY2UKLSAgICAgKiBhbGwgdGhlIGNhbWVyYSBhbmQgbWlkZGxld2FyZXMgYXJlIG1vZGVsaXNlZCBhcyBtYXRyaWNlcyBhbmQgdGhleSBkbyBub3QKLSAgICAgKiByZXF1aXJlIHRoZSBmbG9hdCBhcnJheXMgdG8gYmUgcmVnZW5lcmF0ZWQuCi0gICAgICoKLSAgICAgKiBCYXNpY2FsbHksIHdoZW4gdGhlIHVzZXIgbW92ZXMgdGhlIGNhbWVyYSBvciBhcHBsaWVzIHNvbWUgc3BlY2lmaWMgbGluZWFyCi0gICAgICogdHJhbnNmb3JtYXRpb25zLCB0aGlzIHByb2Nlc3Mgc3RlcCB3aWxsIGJlIHNraXBwZWQsIGFuZCB0aGUgInJlbmRlciIKLSAgICAgKiBtZXRob2Qgd2lsbCBlZmZpY2llbnRseSByZWZyZXNoIHRoZSByZW5kZXJpbmcuCi0gICAgICoKLSAgICAgKiBBbmQgd2hlbiB0aGUgdXNlciBtb2RpZmllcyB0aGUgZ3JhcGggY29sb3JzIG9yIHBvc2l0aW9ucyAoYXBwbHlpbmcgYSBuZXcKLSAgICAgKiBsYXlvdXQgb3IgZmlsdGVyaW5nIHRoZSBjb2xvcnMsIGZvciBpbnN0YW5jZSksIHRoaXMgInByb2Nlc3MiIHN0ZXAgd2lsbCBiZQotICAgICAqIHJlcXVpcmVkIHRvIHJlZ2VuZXJhdGUgdGhlIGZsb2F0IGFycmF5cy4KLSAgICAgKgotICAgICAqIEByZXR1cm4ge3NpZ21hLnJlbmRlcmVycy53ZWJnbH0gUmV0dXJucyB0aGUgaW5zdGFuY2UgaXRzZWxmLgotICAgICAqLwotICAgIHNpZ21hLnJlbmRlcmVycy53ZWJnbC5wcm90b3R5cGUucHJvY2VzcyA9IGZ1bmN0aW9uICgpIHsKLSAgICAgICAgdmFyIGEsCi0gICAgICAgICAgICBpLAotICAgICAgICAgICAgbCwKLSAgICAgICAgICAgIGssCi0gICAgICAgICAgICB0eXBlLAotICAgICAgICAgICAgcmVuZGVyZXIsCi0gICAgICAgICAgICBncmFwaCA9IHRoaXMuZ3JhcGgsCi0gICAgICAgICAgICBvcHRpb25zID0gc2lnbWEudXRpbHMuZXh0ZW5kKG9wdGlvbnMsIHRoaXMub3B0aW9ucyksCi0gICAgICAgICAgICBkZWZhdWx0RWRnZVR5cGUgPSB0aGlzLnNldHRpbmdzKG9wdGlvbnMsICdkZWZhdWx0RWRnZVR5cGUnKSwKLSAgICAgICAgICAgIGRlZmF1bHROb2RlVHlwZSA9IHRoaXMuc2V0dGluZ3Mob3B0aW9ucywgJ2RlZmF1bHROb2RlVHlwZScpOwotCi0gICAgICAgIC8vIEVtcHR5IGZsb2F0IGFycmF5czoKLSAgICAgICAgZm9yIChrIGluIHRoaXMubm9kZUZsb2F0QXJyYXlzKQotICAgICAgICAgICAgZGVsZXRlIHRoaXMubm9kZUZsb2F0QXJyYXlzW2tdOwotCi0gICAgICAgIGZvciAoayBpbiB0aGlzLmVkZ2VGbG9hdEFycmF5cykKLSAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmVkZ2VGbG9hdEFycmF5c1trXTsKLQotICAgICAgICBmb3IgKGsgaW4gdGhpcy5lZGdlSW5kaWNlc0FycmF5cykKLSAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmVkZ2VJbmRpY2VzQXJyYXlzW2tdOwotCi0gICAgICAgIC8vIFNvcnQgZWRnZXMgYW5kIG5vZGVzIHBlciB0eXBlczoKLSAgICAgICAgZm9yIChhID0gZ3JhcGguZWRnZXMoKSwgaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykgewotICAgICAgICAgICAgdHlwZSA9IGFbaV0udHlwZSB8fCBkZWZhdWx0RWRnZVR5cGU7Ci0gICAgICAgICAgICBrID0gKHR5cGUgJiYgc2lnbWEud2ViZ2wuZWRnZXNbdHlwZV0pID8gdHlwZSA6ICdkZWYnOwotCi0gICAgICAgICAgICBpZiAoIXRoaXMuZWRnZUZsb2F0QXJyYXlzW2tdKQotICAgICAgICAgICAgICAgIHRoaXMuZWRnZUZsb2F0QXJyYXlzW2tdID0gewotICAgICAgICAgICAgICAgICAgICBlZGdlczogW10KLSAgICAgICAgICAgICAgICB9OwotCi0gICAgICAgICAgICB0aGlzLmVkZ2VGbG9hdEFycmF5c1trXS5lZGdlcy5wdXNoKGFbaV0pOwotICAgICAgICB9Ci0KLSAgICAgICAgZm9yIChhID0gZ3JhcGgubm9kZXMoKSwgaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykgewotICAgICAgICAgICAgdHlwZSA9IGFbaV0udHlwZSB8fCBkZWZhdWx0Tm9kZVR5cGU7Ci0gICAgICAgICAgICBrID0gKHR5cGUgJiYgc2lnbWEud2ViZ2wubm9kZXNbdHlwZV0pID8gdHlwZSA6ICdkZWYnOwotCi0gICAgICAgICAgICBpZiAoIXRoaXMubm9kZUZsb2F0QXJyYXlzW2tdKQotICAgICAgICAgICAgICAgIHRoaXMubm9kZUZsb2F0QXJyYXlzW2tdID0gewotICAgICAgICAgICAgICAgICAgICBub2RlczogW10KLSAgICAgICAgICAgICAgICB9OwotCi0gICAgICAgICAgICB0aGlzLm5vZGVGbG9hdEFycmF5c1trXS5ub2Rlcy5wdXNoKGFbaV0pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUHVzaCBlZGdlczoKLSAgICAgICAgZm9yIChrIGluIHRoaXMuZWRnZUZsb2F0QXJyYXlzKSB7Ci0gICAgICAgICAgICByZW5kZXJlciA9IHNpZ21hLndlYmdsLmVkZ2VzW2tdOwotICAgICAgICAgICAgYSA9IHRoaXMuZWRnZUZsb2F0QXJyYXlzW2tdLmVkZ2VzOwotCi0gICAgICAgICAgICAvLyBDcmVhdGluZyB0aGUgbmVjZXNzYXJ5IGFycmF5cwotICAgICAgICAgICAgdGhpcy5lZGdlRmxvYXRBcnJheXNba10uYXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KAotICAgICAgICAgICAgICAgIGEubGVuZ3RoICogcmVuZGVyZXIuUE9JTlRTICogcmVuZGVyZXIuQVRUUklCVVRFUwotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgZm9yIChpID0gMCwgbCA9IGEubGVuZ3RoOyBpIDwgbDsgaSsrKSB7Ci0KLSAgICAgICAgICAgICAgICAvLyBKdXN0IGNoZWNrIHRoYXQgdGhlIGVkZ2UgYW5kIGJvdGggaXRzIGV4dHJlbWl0aWVzIGFyZSB2aXNpYmxlOgotICAgICAgICAgICAgICAgIGlmICgKLSAgICAgICAgICAgICAgICAgICAgIWFbaV0uaGlkZGVuICYmICFncmFwaC5ub2RlcyhhW2ldLnNvdXJjZSkuaGlkZGVuICYmICFncmFwaC5ub2RlcyhhW2ldLnRhcmdldCkuaGlkZGVuCi0gICAgICAgICAgICAgICAgKQotICAgICAgICAgICAgICAgICAgICByZW5kZXJlci5hZGRFZGdlKAotICAgICAgICAgICAgICAgICAgICAgICAgYVtpXSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGdyYXBoLm5vZGVzKGFbaV0uc291cmNlKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGdyYXBoLm5vZGVzKGFbaV0udGFyZ2V0KSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWRnZUZsb2F0QXJyYXlzW2tdLmFycmF5LAotICAgICAgICAgICAgICAgICAgICAgICAgaSAqIHJlbmRlcmVyLlBPSU5UUyAqIHJlbmRlcmVyLkFUVFJJQlVURVMsCi0gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0dGluZ3MKLSAgICAgICAgICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKHR5cGVvZiByZW5kZXJlci5jb21wdXRlSW5kaWNlcyA9PT0gJ2Z1bmN0aW9uJykKLSAgICAgICAgICAgICAgICB0aGlzLmVkZ2VJbmRpY2VzQXJyYXlzW2tdID0gcmVuZGVyZXIuY29tcHV0ZUluZGljZXMoCi0gICAgICAgICAgICAgICAgICAgIHRoaXMuZWRnZUZsb2F0QXJyYXlzW2tdLmFycmF5Ci0gICAgICAgICAgICAgICAgKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFB1c2ggbm9kZXM6Ci0gICAgICAgIGZvciAoayBpbiB0aGlzLm5vZGVGbG9hdEFycmF5cykgewotICAgICAgICAgICAgcmVuZGVyZXIgPSBzaWdtYS53ZWJnbC5ub2Rlc1trXTsKLSAgICAgICAgICAgIGEgPSB0aGlzLm5vZGVGbG9hdEFycmF5c1trXS5ub2RlczsKLQotICAgICAgICAgICAgLy8gQ3JlYXRpbmcgdGhlIG5lY2Vzc2FyeSBhcnJheXMKLSAgICAgICAgICAgIHRoaXMubm9kZUZsb2F0QXJyYXlzW2tdLmFycmF5ID0gbmV3IEZsb2F0MzJBcnJheSgKLSAgICAgICAgICAgICAgICBhLmxlbmd0aCAqIHJlbmRlcmVyLlBPSU5UUyAqIHJlbmRlcmVyLkFUVFJJQlVURVMKLSAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykgewotICAgICAgICAgICAgICAgIGlmICghdGhpcy5ub2RlRmxvYXRBcnJheXNba10uYXJyYXkpCi0gICAgICAgICAgICAgICAgICAgIHRoaXMubm9kZUZsb2F0QXJyYXlzW2tdLmFycmF5ID0gbmV3IEZsb2F0MzJBcnJheSgKLSAgICAgICAgICAgICAgICAgICAgICAgIGEubGVuZ3RoICogcmVuZGVyZXIuUE9JTlRTICogcmVuZGVyZXIuQVRUUklCVVRFUwotICAgICAgICAgICAgICAgICAgICApOwotCi0gICAgICAgICAgICAgICAgLy8gSnVzdCBjaGVjayB0aGF0IHRoZSBlZGdlIGFuZCBib3RoIGl0cyBleHRyZW1pdGllcyBhcmUgdmlzaWJsZToKLSAgICAgICAgICAgICAgICBpZiAoCi0gICAgICAgICAgICAgICAgICAgICFhW2ldLmhpZGRlbgotICAgICAgICAgICAgICAgICkKLSAgICAgICAgICAgICAgICAgICAgcmVuZGVyZXIuYWRkTm9kZSgKLSAgICAgICAgICAgICAgICAgICAgICAgIGFbaV0sCi0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5vZGVGbG9hdEFycmF5c1trXS5hcnJheSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGkgKiByZW5kZXJlci5QT0lOVFMgKiByZW5kZXJlci5BVFRSSUJVVEVTLAotICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5wcmVmaXgsCi0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldHRpbmdzCi0gICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9OwotCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCByZW5kZXJzIHRoZSBncmFwaC4gSXQgYmFzaWNhbGx5IGNhbGxzIGVhY2ggcHJvZ3JhbSAoYW5kCi0gICAgICogZ2VuZXJhdGUgdGhlbSBpZiB0aGV5IGRvIG5vdCBleGlzdCB5ZXQpIHRvIHJlbmRlciBub2RlcyBhbmQgZWRnZXMsIGJhdGNoZWQKLSAgICAgKiBwZXIgcmVuZGVyZXIuCi0gICAgICoKLSAgICAgKiBBcyBpbiB0aGUgY2FudmFzIHJlbmRlcmVyLCBpdCBpcyBwb3NzaWJsZSB0byBkaXNwbGF5IGVkZ2VzLCBub2RlcyBhbmQgLyBvcgotICAgICAqIGxhYmVscyBpbiBiYXRjaGVzLCB0byBtYWtlIHRoZSB3aG9sZSB0aGluZyB3YXkgbW9yZSBzY2FsYWJsZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgez9vYmplY3R9ICAgICAgICAgICAgICAgcGFyYW1zIEV2ZW50dWFsbHkgYW4gb2JqZWN0IG9mIG9wdGlvbnMuCi0gICAgICogQHJldHVybiB7c2lnbWEucmVuZGVyZXJzLndlYmdsfSAgICAgICAgUmV0dXJucyB0aGUgaW5zdGFuY2UgaXRzZWxmLgotICAgICAqLwotICAgIHNpZ21hLnJlbmRlcmVycy53ZWJnbC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKHBhcmFtcykgewotICAgICAgICB2YXIgYSwKLSAgICAgICAgICAgIGksCi0gICAgICAgICAgICBsLAotICAgICAgICAgICAgaywKLSAgICAgICAgICAgIG8sCi0gICAgICAgICAgICBwcm9ncmFtLAotICAgICAgICAgICAgcmVuZGVyZXIsCi0gICAgICAgICAgICBzZWxmID0gdGhpcywKLSAgICAgICAgICAgIGdyYXBoID0gdGhpcy5ncmFwaCwKLSAgICAgICAgICAgIG5vZGVzR2wgPSB0aGlzLmNvbnRleHRzLm5vZGVzLAotICAgICAgICAgICAgZWRnZXNHbCA9IHRoaXMuY29udGV4dHMuZWRnZXMsCi0gICAgICAgICAgICBtYXRyaXggPSB0aGlzLmNhbWVyYS5nZXRNYXRyaXgoKSwKLSAgICAgICAgICAgIG9wdGlvbnMgPSBzaWdtYS51dGlscy5leHRlbmQocGFyYW1zLCB0aGlzLm9wdGlvbnMpLAotICAgICAgICAgICAgZHJhd0xhYmVscyA9IHRoaXMuc2V0dGluZ3Mob3B0aW9ucywgJ2RyYXdMYWJlbHMnKSwKLSAgICAgICAgICAgIGRyYXdFZGdlcyA9IHRoaXMuc2V0dGluZ3Mob3B0aW9ucywgJ2RyYXdFZGdlcycpLAotICAgICAgICAgICAgZHJhd05vZGVzID0gdGhpcy5zZXR0aW5ncyhvcHRpb25zLCAnZHJhd05vZGVzJyk7Ci0KLSAgICAgICAgLy8gQ2FsbCB0aGUgcmVzaXplIGZ1bmN0aW9uOgotICAgICAgICB0aGlzLnJlc2l6ZShmYWxzZSk7Ci0KLSAgICAgICAgLy8gQ2hlY2sgdGhlICdoaWRlRWRnZXNPbk1vdmUnIHNldHRpbmc6Ci0gICAgICAgIGlmICh0aGlzLnNldHRpbmdzKG9wdGlvbnMsICdoaWRlRWRnZXNPbk1vdmUnKSkKLSAgICAgICAgICAgIGlmICh0aGlzLmNhbWVyYS5pc0FuaW1hdGVkIHx8IHRoaXMuY2FtZXJhLmlzTW92aW5nKQotICAgICAgICAgICAgICAgIGRyYXdFZGdlcyA9IGZhbHNlOwotCi0gICAgICAgIC8vIENsZWFyIGNhbnZhc2VzOgotICAgICAgICB0aGlzLmNsZWFyKCk7Ci0KLSAgICAgICAgLy8gVHJhbnNsYXRlIG1hdHJpeCB0byBbd2lkdGgvMiwgaGVpZ2h0LzJdOgotICAgICAgICBtYXRyaXggPSBzaWdtYS51dGlscy5tYXRyaWNlcy5tdWx0aXBseSgKLSAgICAgICAgICAgIG1hdHJpeCwKLSAgICAgICAgICAgIHNpZ21hLnV0aWxzLm1hdHJpY2VzLnRyYW5zbGF0aW9uKHRoaXMud2lkdGggLyAyLCB0aGlzLmhlaWdodCAvIDIpCi0gICAgICAgICk7Ci0KLSAgICAgICAgLy8gS2lsbCBydW5uaW5nIGpvYnM6Ci0gICAgICAgIGZvciAoayBpbiB0aGlzLmpvYnMpCi0gICAgICAgICAgICBpZiAoY29ucmFkLmhhc0pvYihrKSkKLSAgICAgICAgICAgICAgICBjb25yYWQua2lsbEpvYihrKTsKLQotICAgICAgICBpZiAoZHJhd0VkZ2VzKSB7Ci0gICAgICAgICAgICBpZiAodGhpcy5zZXR0aW5ncyhvcHRpb25zLCAnYmF0Y2hFZGdlc0RyYXdpbmcnKSkKLSAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKCkgewotICAgICAgICAgICAgICAgICAgICB2YXIgYSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGssCi0gICAgICAgICAgICAgICAgICAgICAgICBpLAotICAgICAgICAgICAgICAgICAgICAgICAgaWQsCi0gICAgICAgICAgICAgICAgICAgICAgICBqb2IsCi0gICAgICAgICAgICAgICAgICAgICAgICBhcnIsCi0gICAgICAgICAgICAgICAgICAgICAgICBlbmQsCi0gICAgICAgICAgICAgICAgICAgICAgICBzdGFydCwKLSAgICAgICAgICAgICAgICAgICAgICAgIGluZGljZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJlciwKLSAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoU2l6ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRQcm9ncmFtOwotCi0gICAgICAgICAgICAgICAgICAgIGlkID0gJ2VkZ2VzXycgKyB0aGlzLmNvbnJhZElkOwotICAgICAgICAgICAgICAgICAgICBiYXRjaFNpemUgPSB0aGlzLnNldHRpbmdzKG9wdGlvbnMsICd3ZWJnbEVkZ2VzQmF0Y2hTaXplJyk7Ci0gICAgICAgICAgICAgICAgICAgIGEgPSBPYmplY3Qua2V5cyh0aGlzLmVkZ2VGbG9hdEFycmF5cyk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKCFhLmxlbmd0aCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICAgICAgaSA9IDA7Ci0gICAgICAgICAgICAgICAgICAgIHJlbmRlcmVyID0gc2lnbWEud2ViZ2wuZWRnZXNbYVtpXV07Ci0gICAgICAgICAgICAgICAgICAgIGFyciA9IHRoaXMuZWRnZUZsb2F0QXJyYXlzW2FbaV1dLmFycmF5OwotICAgICAgICAgICAgICAgICAgICBpbmRpY2VzID0gdGhpcy5lZGdlSW5kaWNlc0FycmF5c1thW2ldXTsKLSAgICAgICAgICAgICAgICAgICAgc3RhcnQgPSAwOwotICAgICAgICAgICAgICAgICAgICBlbmQgPSBNYXRoLm1pbigKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ICsgYmF0Y2hTaXplICogcmVuZGVyZXIuUE9JTlRTLAotICAgICAgICAgICAgICAgICAgICAgICAgYXJyLmxlbmd0aCAvIHJlbmRlcmVyLkFUVFJJQlVURVMKLSAgICAgICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgICAgICAgICBqb2IgPSBmdW5jdGlvbiAoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBwcm9ncmFtOgotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmVkZ2VQcm9ncmFtc1thW2ldXSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVkZ2VQcm9ncmFtc1thW2ldXSA9IHJlbmRlcmVyLmluaXRQcm9ncmFtKGVkZ2VzR2wpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhcnQgPCBlbmQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlZGdlc0dsLnVzZVByb2dyYW0odGhpcy5lZGdlUHJvZ3JhbXNbYVtpXV0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlcmVyLnJlbmRlcigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWRnZXNHbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZGdlUHJvZ3JhbXNbYVtpXV0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3M6IHRoaXMuc2V0dGluZ3MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXg6IG1hdHJpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiB0aGlzLndpZHRoLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLmhlaWdodCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhdGlvOiB0aGlzLmNhbWVyYS5yYXRpbywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxpbmdSYXRpbzogdGhpcy5zZXR0aW5ncygKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd3ZWJnbE92ZXJzYW1wbGluZ1JhdGlvJwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0OiBzdGFydCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50OiBlbmQgLSBzdGFydCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGljZXNEYXRhOiBpbmRpY2VzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBDYXRjaCBqb2IncyBlbmQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kID49IGFyci5sZW5ndGggLyByZW5kZXJlci5BVFRSSUJVVEVTICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PT0gYS5sZW5ndGggLSAxCi0gICAgICAgICAgICAgICAgICAgICAgICApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5qb2JzW2lkXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbmQgPj0gYXJyLmxlbmd0aCAvIHJlbmRlcmVyLkFUVFJJQlVURVMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyID0gdGhpcy5lZGdlRmxvYXRBcnJheXNbYVtpXV0uYXJyYXk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVuZGVyZXIgPSBzaWdtYS53ZWJnbC5lZGdlc1thW2ldXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kID0gTWF0aC5taW4oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ICsgYmF0Y2hTaXplICogcmVuZGVyZXIuUE9JTlRTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIubGVuZ3RoIC8gcmVuZGVyZXIuQVRUUklCVVRFUwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ID0gZW5kOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZCA9IE1hdGgubWluKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydCArIGJhdGNoU2l6ZSAqIHJlbmRlcmVyLlBPSU5UUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyLmxlbmd0aCAvIHJlbmRlcmVyLkFUVFJJQlVURVMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgfTsKLQotICAgICAgICAgICAgICAgICAgICB0aGlzLmpvYnNbaWRdID0gam9iOwotICAgICAgICAgICAgICAgICAgICBjb25yYWQuYWRkSm9iKGlkLCBqb2IuYmluZCh0aGlzKSk7Ci0gICAgICAgICAgICAgICAgfSkuY2FsbCh0aGlzKTsKLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZvciAoayBpbiB0aGlzLmVkZ2VGbG9hdEFycmF5cykgewotICAgICAgICAgICAgICAgICAgICByZW5kZXJlciA9IHNpZ21hLndlYmdsLmVkZ2VzW2tdOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIHByb2dyYW06Ci0gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5lZGdlUHJvZ3JhbXNba10pCi0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVkZ2VQcm9ncmFtc1trXSA9IHJlbmRlcmVyLmluaXRQcm9ncmFtKGVkZ2VzR2wpOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIFJlbmRlcgotICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5lZGdlRmxvYXRBcnJheXNba10pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2VzR2wudXNlUHJvZ3JhbSh0aGlzLmVkZ2VQcm9ncmFtc1trXSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJlci5yZW5kZXIoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWRnZXNHbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVkZ2VQcm9ncmFtc1trXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVkZ2VGbG9hdEFycmF5c1trXS5hcnJheSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHRpbmdzOiB0aGlzLnNldHRpbmdzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXg6IG1hdHJpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMud2lkdGgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy5oZWlnaHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhdGlvOiB0aGlzLmNhbWVyYS5yYXRpbywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGluZ1JhdGlvOiB0aGlzLnNldHRpbmdzKG9wdGlvbnMsICd3ZWJnbE92ZXJzYW1wbGluZ1JhdGlvJyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGljZXNEYXRhOiB0aGlzLmVkZ2VJbmRpY2VzQXJyYXlzW2tdCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChkcmF3Tm9kZXMpIHsKLSAgICAgICAgICAgIC8vIEVuYWJsZSBibGVuZGluZzoKLSAgICAgICAgICAgIG5vZGVzR2wuYmxlbmRGdW5jKG5vZGVzR2wuU1JDX0FMUEhBLCBub2Rlc0dsLk9ORV9NSU5VU19TUkNfQUxQSEEpOwotICAgICAgICAgICAgbm9kZXNHbC5lbmFibGUobm9kZXNHbC5CTEVORCk7Ci0KLSAgICAgICAgICAgIGZvciAoayBpbiB0aGlzLm5vZGVGbG9hdEFycmF5cykgewotICAgICAgICAgICAgICAgIHJlbmRlcmVyID0gc2lnbWEud2ViZ2wubm9kZXNba107Ci0KLSAgICAgICAgICAgICAgICAvLyBDaGVjayBwcm9ncmFtOgotICAgICAgICAgICAgICAgIGlmICghdGhpcy5ub2RlUHJvZ3JhbXNba10pCi0gICAgICAgICAgICAgICAgICAgIHRoaXMubm9kZVByb2dyYW1zW2tdID0gcmVuZGVyZXIuaW5pdFByb2dyYW0obm9kZXNHbCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBSZW5kZXIKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5ub2RlRmxvYXRBcnJheXNba10pIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZXNHbC51c2VQcm9ncmFtKHRoaXMubm9kZVByb2dyYW1zW2tdKTsKLSAgICAgICAgICAgICAgICAgICAgcmVuZGVyZXIucmVuZGVyKAotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXNHbCwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubm9kZVByb2dyYW1zW2tdLAotICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5ub2RlRmxvYXRBcnJheXNba10uYXJyYXksCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3M6IHRoaXMuc2V0dGluZ3MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0cml4OiBtYXRyaXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMud2lkdGgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLmhlaWdodCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXRpbzogdGhpcy5jYW1lcmEucmF0aW8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGluZ1JhdGlvOiB0aGlzLnNldHRpbmdzKG9wdGlvbnMsICd3ZWJnbE92ZXJzYW1wbGluZ1JhdGlvJykKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZHJhd0xhYmVscykgewotICAgICAgICAgICAgYSA9IHRoaXMuY2FtZXJhLnF1YWR0cmVlLmFyZWEoCi0gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmEuZ2V0UmVjdGFuZ2xlKHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KQotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgLy8gQXBwbHkgY2FtZXJhIHZpZXcgdG8gdGhlc2Ugbm9kZXM6Ci0gICAgICAgICAgICB0aGlzLmNhbWVyYS5hcHBseVZpZXcoCi0gICAgICAgICAgICAgICAgdW5kZWZpbmVkLAotICAgICAgICAgICAgICAgIHVuZGVmaW5lZCwKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGVzOiBhLAotICAgICAgICAgICAgICAgICAgICBlZGdlczogW10sCi0gICAgICAgICAgICAgICAgICAgIHdpZHRoOiB0aGlzLndpZHRoLAotICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMuaGVpZ2h0Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgbyA9IGZ1bmN0aW9uIChrZXkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5zZXR0aW5ncyh7Ci0gICAgICAgICAgICAgICAgICAgIHByZWZpeDogc2VsZi5jYW1lcmEucHJlZml4Ci0gICAgICAgICAgICAgICAgfSwga2V5KTsKLSAgICAgICAgICAgIH07Ci0KLSAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgICAgICBpZiAoIWFbaV0uaGlkZGVuKQotICAgICAgICAgICAgICAgICAgICAoCi0gICAgICAgICAgICAgICAgICAgICAgICBzaWdtYS5jYW52YXMubGFiZWxzWwotICAgICAgICAgICAgICAgICAgICAgICAgYVtpXS50eXBlIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldHRpbmdzKG9wdGlvbnMsICdkZWZhdWx0Tm9kZVR5cGUnKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0gfHwgc2lnbWEuY2FudmFzLmxhYmVscy5kZWYKLSAgICAgICAgICAgICAgICAgICAgKShhW2ldLCB0aGlzLmNvbnRleHRzLmxhYmVscywgbyk7Ci0gICAgICAgIH0KLQotICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoJ3JlbmRlcicpOwotCi0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH07Ci0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBET00gZWxlbWVudCBvZiB0aGUgc3BlY2lmaWVkIHR5cGUsIHN3aXRjaGVzIGl0cwotICAgICAqIHBvc2l0aW9uIHRvICJhYnNvbHV0ZSIsIHJlZmVyZW5jZXMgaXQgdG8gdGhlIGRvbUVsZW1lbnRzIGF0dHJpYnV0ZSwgYW5kCi0gICAgICogZmluYWxseSBhcHBlbmRzIGl0IHRvIHRoZSBjb250YWluZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtzdHJpbmd9ICAgdGFnICAgVGhlIGxhYmVsIHRhZy4KLSAgICAgKiBAcGFyYW0gIHtzdHJpbmd9ICAgaWQgICAgVGhlIGlkIG9mIHRoZSBlbGVtZW50ICh0byBzdG9yZSBpdCBpbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAiZG9tRWxlbWVudHMiKS4KLSAgICAgKiBAcGFyYW0gIHs/Ym9vbGVhbn0gd2ViZ2wgV2lsbCBpbml0IHRoZSBXZWJHTCBjb250ZXh0IGlmIHRydWUuCi0gICAgICovCi0gICAgc2lnbWEucmVuZGVyZXJzLndlYmdsLnByb3RvdHlwZS5pbml0RE9NID0gZnVuY3Rpb24gKHRhZywgaWQsIHdlYmdsKSB7Ci0gICAgICAgIHZhciBnbCwKLSAgICAgICAgICAgIGRvbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnKSwKLSAgICAgICAgICAgIHNlbGYgPSB0aGlzOwotCi0gICAgICAgIGRvbS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7Ci0gICAgICAgIGRvbS5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ3NpZ21hLScgKyBpZCk7Ci0KLSAgICAgICAgdGhpcy5kb21FbGVtZW50c1tpZF0gPSBkb207Ci0gICAgICAgIHRoaXMuY29udGFpbmVyLmFwcGVuZENoaWxkKGRvbSk7Ci0KLSAgICAgICAgaWYgKHRhZy50b0xvd2VyQ2FzZSgpID09PSAnY2FudmFzJykgewotICAgICAgICAgICAgdGhpcy5jb250ZXh0c1tpZF0gPSBkb20uZ2V0Q29udGV4dCh3ZWJnbCA/ICdleHBlcmltZW50YWwtd2ViZ2wnIDogJzJkJywgewotICAgICAgICAgICAgICAgIHByZXNlcnZlRHJhd2luZ0J1ZmZlcjogdHJ1ZQotICAgICAgICAgICAgfSk7Ci0KLSAgICAgICAgICAgIC8vIEFkZGluZyB3ZWJnbCBjb250ZXh0IGxvc3MgbGlzdGVuZXJzCi0gICAgICAgICAgICBpZiAod2ViZ2wpIHsKLSAgICAgICAgICAgICAgICBkb20uYWRkRXZlbnRMaXN0ZW5lcignd2ViZ2xjb250ZXh0bG9zdCcsIGZ1bmN0aW9uIChlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTsKLSAgICAgICAgICAgICAgICB9LCBmYWxzZSk7Ci0KLSAgICAgICAgICAgICAgICBkb20uYWRkRXZlbnRMaXN0ZW5lcignd2ViZ2xjb250ZXh0cmVzdG9yZWQnLCBmdW5jdGlvbiAoZSkgewotICAgICAgICAgICAgICAgICAgICBzZWxmLnJlbmRlcigpOwotICAgICAgICAgICAgICAgIH0sIGZhbHNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCByZXNpemVzIGVhY2ggRE9NIGVsZW1lbnRzIGluIHRoZSBjb250YWluZXIgYW5kIHN0b3JlcyB0aGUgbmV3Ci0gICAgICogZGltZW5zaW9ucy4gVGhlbiwgaXQgcmVuZGVycyB0aGUgZ3JhcGguCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHs/bnVtYmVyfSAgICAgICAgICAgICAgIHdpZHRoICBUaGUgbmV3IHdpZHRoIG9mIHRoZSBjb250YWluZXIuCi0gICAgICogQHBhcmFtICB7P251bWJlcn0gICAgICAgICAgICAgICBoZWlnaHQgVGhlIG5ldyBoZWlnaHQgb2YgdGhlIGNvbnRhaW5lci4KLSAgICAgKiBAcmV0dXJuIHtzaWdtYS5yZW5kZXJlcnMud2ViZ2x9ICAgICAgICBSZXR1cm5zIHRoZSBpbnN0YW5jZSBpdHNlbGYuCi0gICAgICovCi0gICAgc2lnbWEucmVuZGVyZXJzLndlYmdsLnByb3RvdHlwZS5yZXNpemUgPSBmdW5jdGlvbiAodywgaCkgewotICAgICAgICB2YXIgaywKLSAgICAgICAgICAgIG9sZFdpZHRoID0gdGhpcy53aWR0aCwKLSAgICAgICAgICAgIG9sZEhlaWdodCA9IHRoaXMuaGVpZ2h0LAotICAgICAgICAgICAgcGl4ZWxSYXRpbyA9IHNpZ21hLnV0aWxzLmdldFBpeGVsUmF0aW8oKTsKLQotICAgICAgICBpZiAodyAhPT0gdW5kZWZpbmVkICYmIGggIT09IHVuZGVmaW5lZCkgewotICAgICAgICAgICAgdGhpcy53aWR0aCA9IHc7Ci0gICAgICAgICAgICB0aGlzLmhlaWdodCA9IGg7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy5jb250YWluZXIub2Zmc2V0V2lkdGg7Ci0gICAgICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMuY29udGFpbmVyLm9mZnNldEhlaWdodDsKLQotICAgICAgICAgICAgdyA9IHRoaXMud2lkdGg7Ci0gICAgICAgICAgICBoID0gdGhpcy5oZWlnaHQ7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAob2xkV2lkdGggIT09IHRoaXMud2lkdGggfHwgb2xkSGVpZ2h0ICE9PSB0aGlzLmhlaWdodCkgewotICAgICAgICAgICAgZm9yIChrIGluIHRoaXMuZG9tRWxlbWVudHMpIHsKLSAgICAgICAgICAgICAgICB0aGlzLmRvbUVsZW1lbnRzW2tdLnN0eWxlLndpZHRoID0gdyArICdweCc7Ci0gICAgICAgICAgICAgICAgdGhpcy5kb21FbGVtZW50c1trXS5zdHlsZS5oZWlnaHQgPSBoICsgJ3B4JzsKLQotICAgICAgICAgICAgICAgIGlmICh0aGlzLmRvbUVsZW1lbnRzW2tdLnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2NhbnZhcycpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gSWYgc2ltcGxlIDJEIGNhbnZhczoKLSAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dHNba10gJiYgdGhpcy5jb250ZXh0c1trXS5zY2FsZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kb21FbGVtZW50c1trXS5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgKHcgKiBwaXhlbFJhdGlvKSArICdweCcpOwotICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kb21FbGVtZW50c1trXS5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIChoICogcGl4ZWxSYXRpbykgKyAncHgnKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBpeGVsUmF0aW8gIT09IDEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0c1trXS5zY2FsZShwaXhlbFJhdGlvLCBwaXhlbFJhdGlvKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZG9tRWxlbWVudHNba10uc2V0QXR0cmlidXRlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICd3aWR0aCcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHcgKiB0aGlzLnNldHRpbmdzKCd3ZWJnbE92ZXJzYW1wbGluZ1JhdGlvJykpICsgJ3B4JwotICAgICAgICAgICAgICAgICAgICAgICAgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZG9tRWxlbWVudHNba10uc2V0QXR0cmlidXRlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICdoZWlnaHQnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChoICogdGhpcy5zZXR0aW5ncygnd2ViZ2xPdmVyc2FtcGxpbmdSYXRpbycpKSArICdweCcKLSAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTY2FsZToKLSAgICAgICAgZm9yIChrIGluIHRoaXMuY29udGV4dHMpCi0gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0c1trXSAmJiB0aGlzLmNvbnRleHRzW2tdLnZpZXdwb3J0KQotICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dHNba10udmlld3BvcnQoCi0gICAgICAgICAgICAgICAgICAgIDAsCi0gICAgICAgICAgICAgICAgICAgIDAsCi0gICAgICAgICAgICAgICAgICAgIHRoaXMud2lkdGggKiB0aGlzLnNldHRpbmdzKCd3ZWJnbE92ZXJzYW1wbGluZ1JhdGlvJyksCi0gICAgICAgICAgICAgICAgICAgIHRoaXMuaGVpZ2h0ICogdGhpcy5zZXR0aW5ncygnd2ViZ2xPdmVyc2FtcGxpbmdSYXRpbycpCi0gICAgICAgICAgICAgICAgKTsKLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgY2xlYXJzIGVhY2ggY2FudmFzLgotICAgICAqCi0gICAgICogQHJldHVybiB7c2lnbWEucmVuZGVyZXJzLndlYmdsfSBSZXR1cm5zIHRoZSBpbnN0YW5jZSBpdHNlbGYuCi0gICAgICovCi0gICAgc2lnbWEucmVuZGVyZXJzLndlYmdsLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHsKLSAgICAgICAgdGhpcy5jb250ZXh0cy5sYWJlbHMuY2xlYXJSZWN0KDAsIDAsIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KTsKLSAgICAgICAgdGhpcy5jb250ZXh0cy5ub2Rlcy5jbGVhcih0aGlzLmNvbnRleHRzLm5vZGVzLkNPTE9SX0JVRkZFUl9CSVQpOwotICAgICAgICB0aGlzLmNvbnRleHRzLmVkZ2VzLmNsZWFyKHRoaXMuY29udGV4dHMuZWRnZXMuQ09MT1JfQlVGRkVSX0JJVCk7Ci0KLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGtpbGxzIGNvbnRleHRzIGFuZCBvdGhlciBhdHRyaWJ1dGVzLgotICAgICAqLwotICAgIHNpZ21hLnJlbmRlcmVycy53ZWJnbC5wcm90b3R5cGUua2lsbCA9IGZ1bmN0aW9uICgpIHsKLSAgICAgICAgdmFyIGssCi0gICAgICAgICAgICBjYXB0b3I7Ci0KLSAgICAgICAgLy8gS2lsbCBjYXB0b3JzOgotICAgICAgICB3aGlsZSAoKGNhcHRvciA9IHRoaXMuY2FwdG9ycy5wb3AoKSkpCi0gICAgICAgICAgICBjYXB0b3Iua2lsbCgpOwotICAgICAgICBkZWxldGUgdGhpcy5jYXB0b3JzOwotCi0gICAgICAgIC8vIEtpbGwgY29udGV4dHM6Ci0gICAgICAgIGZvciAoayBpbiB0aGlzLmRvbUVsZW1lbnRzKSB7Ci0gICAgICAgICAgICB0aGlzLmRvbUVsZW1lbnRzW2tdLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5kb21FbGVtZW50c1trXSk7Ci0gICAgICAgICAgICBkZWxldGUgdGhpcy5kb21FbGVtZW50c1trXTsKLSAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNvbnRleHRzW2tdOwotICAgICAgICB9Ci0gICAgICAgIGRlbGV0ZSB0aGlzLmRvbUVsZW1lbnRzOwotICAgICAgICBkZWxldGUgdGhpcy5jb250ZXh0czsKLSAgICB9OwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgb2JqZWN0ICJzaWdtYS53ZWJnbC5ub2RlcyIgY29udGFpbnMgdGhlIGRpZmZlcmVudCBXZWJHTCBub2RlCi0gICAgICogcmVuZGVyZXJzLiBUaGUgZGVmYXVsdCBvbmUgZHJhdyBub2RlcyBhcyBkaXNjcy4gSGVyZSBhcmUgdGhlIGF0dHJpYnV0ZXMKLSAgICAgKiBhbnkgbm9kZSByZW5kZXJlciBtdXN0IGhhdmU6Ci0gICAgICoKLSAgICAgKiB7bnVtYmVyfSAgIFBPSU5UUyAgICAgIFRoZSBudW1iZXIgb2YgcG9pbnRzIHJlcXVpcmVkIHRvIGRyYXcgYSBub2RlLgotICAgICAqIHtudW1iZXJ9ICAgQVRUUklCVVRFUyAgVGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIG5lZWRlZCB0byBkcmF3IG9uZSBwb2ludC4KLSAgICAgKiB7ZnVuY3Rpb259IGFkZE5vZGUgICAgIEEgZnVuY3Rpb24gdGhhdCBhZGRzIGEgbm9kZSB0byB0aGUgZGF0YSBzdGFjayB0aGF0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICB3aWxsIGJlIGdpdmVuIHRvIHRoZSBidWZmZXIuIEhlcmUgaXMgdGhlIGFyZ3VtZW50czoKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgID4ge29iamVjdH0gICAgICAgbm9kZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgPiB7bnVtYmVyfSAgICAgICBpbmRleCAgIFRoZSBub2RlIGluZGV4IGluIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzIGFycmF5LgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgPiB7RmxvYXQzMkFycmF5fSBkYXRhICAgIFRoZSBzdGFjay4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgID4ge29iamVjdH0gICAgICAgb3B0aW9ucyBTb21lIG9wdGlvbnMuCi0gICAgICoge2Z1bmN0aW9ufSByZW5kZXIgICAgICBUaGUgZnVuY3Rpb24gdGhhdCB3aWxsIGVmZmVjdGl2ZWx5IHJlbmRlciB0aGUgbm9kZXMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIGludG8gdGhlIGJ1ZmZlci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgID4ge1dlYkdMUmVuZGVyaW5nQ29udGV4dH0gZ2wKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgID4ge1dlYkdMUHJvZ3JhbX0gICAgICAgICAgcHJvZ3JhbQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgPiB7RmxvYXQzMkFycmF5fSBkYXRhICAgIFRoZSBzdGFjayB0byBnaXZlIHRvIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgID4ge29iamVjdH0gICAgICAgcGFyYW1zICBBbiBvYmplY3QgY29udGFpbmluZyBzb21lCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucywgbGlrZSB3aWR0aCwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQsIHRoZSBjYW1lcmEgcmF0aW8uCi0gICAgICoge2Z1bmN0aW9ufSBpbml0UHJvZ3JhbSBUaGUgZnVuY3Rpb24gdGhhdCB3aWxsIGluaXRpYXRlIHRoZSBwcm9ncmFtLCB3aXRoCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICB0aGUgcmVsZXZhbnQgc2hhZGVycyBhbmQgcGFyYW1ldGVycy4gSXQgbXVzdCByZXR1cm4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBuZXdseSBjcmVhdGVkIHByb2dyYW0uCi0gICAgICoKLSAgICAgKiBDaGVjayBzaWdtYS53ZWJnbC5ub2Rlcy5kZWYgb3Igc2lnbWEud2ViZ2wubm9kZXMuZmFzdCB0byBzZWUgaG93IGl0Ci0gICAgICogd29ya3MgbW9yZSBwcmVjaXNlbHkuCi0gICAgICovCi0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS53ZWJnbC5ub2RlcycpOwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgb2JqZWN0ICJzaWdtYS53ZWJnbC5lZGdlcyIgY29udGFpbnMgdGhlIGRpZmZlcmVudCBXZWJHTCBlZGdlCi0gICAgICogcmVuZGVyZXJzLiBUaGUgZGVmYXVsdCBvbmUgZHJhdyBlZGdlcyBhcyBkaXJlY3QgbGluZXMuIEhlcmUgYXJlIHRoZQotICAgICAqIGF0dHJpYnV0ZXMgYW55IGVkZ2UgcmVuZGVyZXIgbXVzdCBoYXZlOgotICAgICAqCi0gICAgICoge251bWJlcn0gICBQT0lOVFMgICAgICBUaGUgbnVtYmVyIG9mIHBvaW50cyByZXF1aXJlZCB0byBkcmF3IGFuIGVkZ2UuCi0gICAgICoge251bWJlcn0gICBBVFRSSUJVVEVTICBUaGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgbmVlZGVkIHRvIGRyYXcgb25lIHBvaW50LgotICAgICAqIHtmdW5jdGlvbn0gYWRkRWRnZSAgICAgQSBmdW5jdGlvbiB0aGF0IGFkZHMgYW4gZWRnZSB0byB0aGUgZGF0YSBzdGFjayB0aGF0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICB3aWxsIGJlIGdpdmVuIHRvIHRoZSBidWZmZXIuIEhlcmUgaXMgdGhlIGFyZ3VtZW50czoKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgID4ge29iamVjdH0gICAgICAgZWRnZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgPiB7b2JqZWN0fSAgICAgICBzb3VyY2UKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgID4ge29iamVjdH0gICAgICAgdGFyZ2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICA+IHtGbG9hdDMyQXJyYXl9IGRhdGEgICAgVGhlIHN0YWNrLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgPiB7b2JqZWN0fSAgICAgICBvcHRpb25zIFNvbWUgb3B0aW9ucy4KLSAgICAgKiB7ZnVuY3Rpb259IHJlbmRlciAgICAgIFRoZSBmdW5jdGlvbiB0aGF0IHdpbGwgZWZmZWN0aXZlbHkgcmVuZGVyIHRoZSBlZGdlcwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgaW50byB0aGUgYnVmZmVyLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgPiB7V2ViR0xSZW5kZXJpbmdDb250ZXh0fSBnbAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgPiB7V2ViR0xQcm9ncmFtfSAgICAgICAgICBwcm9ncmFtCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICA+IHtGbG9hdDMyQXJyYXl9IGRhdGEgICAgVGhlIHN0YWNrIHRvIGdpdmUgdG8gdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgPiB7b2JqZWN0fSAgICAgICBwYXJhbXMgIEFuIG9iamVjdCBjb250YWluaW5nIHNvbWUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLCBsaWtlIHdpZHRoLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCwgdGhlIGNhbWVyYSByYXRpby4KLSAgICAgKiB7ZnVuY3Rpb259IGluaXRQcm9ncmFtIFRoZSBmdW5jdGlvbiB0aGF0IHdpbGwgaW5pdGlhdGUgdGhlIHByb2dyYW0sIHdpdGgKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRoZSByZWxldmFudCBzaGFkZXJzIGFuZCBwYXJhbWV0ZXJzLiBJdCBtdXN0IHJldHVybgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgdGhlIG5ld2x5IGNyZWF0ZWQgcHJvZ3JhbS4KLSAgICAgKgotICAgICAqIENoZWNrIHNpZ21hLndlYmdsLmVkZ2VzLmRlZiBvciBzaWdtYS53ZWJnbC5lZGdlcy5mYXN0IHRvIHNlZSBob3cgaXQKLSAgICAgKiB3b3JrcyBtb3JlIHByZWNpc2VseS4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLndlYmdsLmVkZ2VzJyk7Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBvYmplY3QgInNpZ21hLmNhbnZhcy5sYWJlbHMiIGNvbnRhaW5zIHRoZSBkaWZmZXJlbnQKLSAgICAgKiBsYWJlbCByZW5kZXJlcnMgZm9yIHRoZSBXZWJHTCByZW5kZXJlci4gU2luY2UgZGlzcGxheWluZyB0ZXh0cyBpbiBXZWJHTCBpcwotICAgICAqIGRlZmluaXRlbHkgcGFpbmZ1bCBhbmQgc2luY2UgdGhlcmUgYSB3YXkgbGVzcyBsYWJlbHMgdG8gZGlzcGxheSB0aGFuIG5vZGVzCi0gICAgICogb3IgZWRnZXMsIHRoZSBkZWZhdWx0IHJlbmRlcmVyIHNpbXBseSByZW5kZXJzIHRoZW0gaW4gYSBjYW52YXMuCi0gICAgICoKLSAgICAgKiBBIGxhYmVscyByZW5kZXJlciBpcyBhIHNpbXBsZSBmdW5jdGlvbiwgdGFraW5nIGFzIGFyZ3VtZW50cyB0aGUgcmVsYXRlZAotICAgICAqIG5vZGUsIHRoZSByZW5kZXJlciBhbmQgYSBzZXR0aW5ncyBmdW5jdGlvbi4KLSAgICAgKi8KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLmNhbnZhcy5sYWJlbHMnKTsKLX0pLmNhbGwodGhpcyk7Ci0KLTsoZnVuY3Rpb24gKHVuZGVmaW5lZCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIGlmICh0eXBlb2Ygc2lnbWEgPT09ICd1bmRlZmluZWQnKQotICAgICAgICB0aHJvdyAnc2lnbWEgaXMgbm90IGRlY2xhcmVkJzsKLQotICAgIGlmICh0eXBlb2YgY29ucmFkID09PSAndW5kZWZpbmVkJykKLSAgICAgICAgdGhyb3cgJ2NvbnJhZCBpcyBub3QgZGVjbGFyZWQnOwotCi0gICAgLy8gSW5pdGlhbGl6ZSBwYWNrYWdlczoKLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLnJlbmRlcmVycycpOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBmdW5jdGlvbiBpcyB0aGUgY29uc3RydWN0b3Igb2YgdGhlIHN2ZyBzaWdtYSdzIHJlbmRlcmVyLgotICAgICAqCi0gICAgICogQHBhcmFtICB7c2lnbWEuY2xhc3Nlcy5ncmFwaH0gICAgICAgICAgICBncmFwaCAgICBUaGUgZ3JhcGggdG8gcmVuZGVyLgotICAgICAqIEBwYXJhbSAge3NpZ21hLmNsYXNzZXMuY2FtZXJhfSAgICAgICAgICAgY2FtZXJhICAgVGhlIGNhbWVyYS4KLSAgICAgKiBAcGFyYW0gIHtjb25maWd1cmFibGV9ICAgICAgICAgICBzZXR0aW5ncyBUaGUgc2lnbWEgaW5zdGFuY2Ugc2V0dGluZ3MKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbi4KLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICBvYmplY3QgICBUaGUgb3B0aW9ucyBvYmplY3QuCi0gICAgICogQHJldHVybiB7c2lnbWEucmVuZGVyZXJzLnN2Z30gICAgICAgICAgICAgVGhlIHJlbmRlcmVyIGluc3RhbmNlLgotICAgICAqLwotICAgIHNpZ21hLnJlbmRlcmVycy5zdmcgPSBmdW5jdGlvbiAoZ3JhcGgsIGNhbWVyYSwgc2V0dGluZ3MsIG9wdGlvbnMpIHsKLSAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0JykKLSAgICAgICAgICAgIHRocm93ICdzaWdtYS5yZW5kZXJlcnMuc3ZnOiBXcm9uZyBhcmd1bWVudHMuJzsKLQotICAgICAgICBpZiAoIShvcHRpb25zLmNvbnRhaW5lciBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkKLSAgICAgICAgICAgIHRocm93ICdDb250YWluZXIgbm90IGZvdW5kLic7Ci0KLSAgICAgICAgdmFyIGksCi0gICAgICAgICAgICBsLAotICAgICAgICAgICAgYSwKLSAgICAgICAgICAgIGZuLAotICAgICAgICAgICAgc2VsZiA9IHRoaXM7Ci0KLSAgICAgICAgc2lnbWEuY2xhc3Nlcy5kaXNwYXRjaGVyLmV4dGVuZCh0aGlzKTsKLQotICAgICAgICAvLyBJbml0aWFsaXplIG1haW4gYXR0cmlidXRlczoKLSAgICAgICAgdGhpcy5ncmFwaCA9IGdyYXBoOwotICAgICAgICB0aGlzLmNhbWVyYSA9IGNhbWVyYTsKLSAgICAgICAgdGhpcy5kb21FbGVtZW50cyA9IHsKLSAgICAgICAgICAgIGdyYXBoOiBudWxsLAotICAgICAgICAgICAgZ3JvdXBzOiB7fSwKLSAgICAgICAgICAgIG5vZGVzOiB7fSwKLSAgICAgICAgICAgIGVkZ2VzOiB7fSwKLSAgICAgICAgICAgIGxhYmVsczoge30sCi0gICAgICAgICAgICBob3ZlcnM6IHt9Ci0gICAgICAgIH07Ci0gICAgICAgIHRoaXMubWVhc3VyZW1lbnRDYW52YXMgPSBudWxsOwotICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zOwotICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMub3B0aW9ucy5jb250YWluZXI7Ci0gICAgICAgIHRoaXMuc2V0dGluZ3MgPSAoCi0gICAgICAgICAgICB0eXBlb2Ygb3B0aW9ucy5zZXR0aW5ncyA9PT0gJ29iamVjdCcgJiYKLSAgICAgICAgICAgIG9wdGlvbnMuc2V0dGluZ3MKLSAgICAgICAgKSA/Ci0gICAgICAgICAgICBzZXR0aW5ncy5lbWJlZE9iamVjdHMob3B0aW9ucy5zZXR0aW5ncykgOgotICAgICAgICAgICAgc2V0dGluZ3M7Ci0KLSAgICAgICAgLy8gSXMgdGhlIHJlbmRlcmVyIG1lYW50IHRvIGJlIGZyZWVzdHlsZT8KLSAgICAgICAgdGhpcy5zZXR0aW5ncygnZnJlZVN0eWxlJywgISF0aGlzLm9wdGlvbnMuZnJlZVN0eWxlKTsKLQotICAgICAgICAvLyBTVkcgeG1sbnMKLSAgICAgICAgdGhpcy5zZXR0aW5ncygneG1sbnMnLCAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnKTsKLQotICAgICAgICAvLyBJbmRleGVzOgotICAgICAgICB0aGlzLm5vZGVzT25TY3JlZW4gPSBbXTsKLSAgICAgICAgdGhpcy5lZGdlc09uU2NyZWVuID0gW107Ci0KLSAgICAgICAgLy8gRmluZCB0aGUgcHJlZml4OgotICAgICAgICB0aGlzLm9wdGlvbnMucHJlZml4ID0gJ3JlbmRlcmVyJyArIHNpZ21hLnV0aWxzLmlkKCkgKyAnOic7Ci0KLSAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGUgRE9NIGVsZW1lbnRzCi0gICAgICAgIHRoaXMuaW5pdERPTSgnc3ZnJyk7Ci0KLSAgICAgICAgLy8gSW5pdGlhbGl6ZSBjYXB0b3JzOgotICAgICAgICB0aGlzLmNhcHRvcnMgPSBbXTsKLSAgICAgICAgYSA9IHRoaXMub3B0aW9ucy5jYXB0b3JzIHx8IFtzaWdtYS5jYXB0b3JzLm1vdXNlLCBzaWdtYS5jYXB0b3JzLnRvdWNoXTsKLSAgICAgICAgZm9yIChpID0gMCwgbCA9IGEubGVuZ3RoOyBpIDwgbDsgaSsrKSB7Ci0gICAgICAgICAgICBmbiA9IHR5cGVvZiBhW2ldID09PSAnZnVuY3Rpb24nID8gYVtpXSA6IHNpZ21hLmNhcHRvcnNbYVtpXV07Ci0gICAgICAgICAgICB0aGlzLmNhcHRvcnMucHVzaCgKLSAgICAgICAgICAgICAgICBuZXcgZm4oCi0gICAgICAgICAgICAgICAgICAgIHRoaXMuZG9tRWxlbWVudHMuZ3JhcGgsCi0gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhLAotICAgICAgICAgICAgICAgICAgICB0aGlzLnNldHRpbmdzCi0gICAgICAgICAgICAgICAgKQotICAgICAgICAgICAgKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEJpbmQgcmVzaXplOgotICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgZnVuY3Rpb24gKCkgewotICAgICAgICAgICAgc2VsZi5yZXNpemUoKTsKLSAgICAgICAgfSk7Ci0KLSAgICAgICAgLy8gRGVhbCB3aXRoIHNpZ21hIGV2ZW50czoKLSAgICAgICAgLy8gVE9ETzoga2VlcCBhbiBvcHRpb24gdG8gb3ZlcnJpZGUgdGhlIERPTSBldmVudHM/Ci0gICAgICAgIHNpZ21hLm1pc2MuYmluZERPTUV2ZW50cy5jYWxsKHRoaXMsIHRoaXMuZG9tRWxlbWVudHMuZ3JhcGgpOwotICAgICAgICB0aGlzLmJpbmRIb3ZlcnModGhpcy5vcHRpb25zLnByZWZpeCk7Ci0KLSAgICAgICAgLy8gUmVzaXplCi0gICAgICAgIHRoaXMucmVzaXplKGZhbHNlKTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgcmVuZGVycyB0aGUgZ3JhcGggb24gdGhlIHN2ZyBzY2VuZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgez9vYmplY3R9ICAgICAgICAgICAgICAgIG9wdGlvbnMgRXZlbnR1YWxseSBhbiBvYmplY3Qgb2Ygb3B0aW9ucy4KLSAgICAgKiBAcmV0dXJuIHtzaWdtYS5yZW5kZXJlcnMuc3ZnfSAgICAgICAgICAgIFJldHVybnMgdGhlIGluc3RhbmNlIGl0c2VsZi4KLSAgICAgKi8KLSAgICBzaWdtYS5yZW5kZXJlcnMuc3ZnLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAob3B0aW9ucykgewotICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKLQotICAgICAgICB2YXIgYSwKLSAgICAgICAgICAgIGksCi0gICAgICAgICAgICBrLAotICAgICAgICAgICAgZSwKLSAgICAgICAgICAgIGwsCi0gICAgICAgICAgICBvLAotICAgICAgICAgICAgc291cmNlLAotICAgICAgICAgICAgdGFyZ2V0LAotICAgICAgICAgICAgc3RhcnQsCi0gICAgICAgICAgICBlZGdlcywKLSAgICAgICAgICAgIHJlbmRlcmVycywKLSAgICAgICAgICAgIHN1YnJlbmRlcmVycywKLSAgICAgICAgICAgIGluZGV4ID0ge30sCi0gICAgICAgICAgICBncmFwaCA9IHRoaXMuZ3JhcGgsCi0gICAgICAgICAgICBub2RlcyA9IHRoaXMuZ3JhcGgubm9kZXMsCi0gICAgICAgICAgICBwcmVmaXggPSB0aGlzLm9wdGlvbnMucHJlZml4IHx8ICcnLAotICAgICAgICAgICAgZHJhd0VkZ2VzID0gdGhpcy5zZXR0aW5ncyhvcHRpb25zLCAnZHJhd0VkZ2VzJyksCi0gICAgICAgICAgICBkcmF3Tm9kZXMgPSB0aGlzLnNldHRpbmdzKG9wdGlvbnMsICdkcmF3Tm9kZXMnKSwKLSAgICAgICAgICAgIGRyYXdMYWJlbHMgPSB0aGlzLnNldHRpbmdzKG9wdGlvbnMsICdkcmF3TGFiZWxzJyksCi0gICAgICAgICAgICBlbWJlZFNldHRpbmdzID0gdGhpcy5zZXR0aW5ncy5lbWJlZE9iamVjdHMob3B0aW9ucywgewotICAgICAgICAgICAgICAgIHByZWZpeDogdGhpcy5vcHRpb25zLnByZWZpeCwKLSAgICAgICAgICAgICAgICBmb3JjZUxhYmVsczogdGhpcy5vcHRpb25zLmZvcmNlTGFiZWxzCi0gICAgICAgICAgICB9KTsKLQotICAgICAgICAvLyBDaGVjayB0aGUgJ2hpZGVFZGdlc09uTW92ZScgc2V0dGluZzoKLSAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3Mob3B0aW9ucywgJ2hpZGVFZGdlc09uTW92ZScpKQotICAgICAgICAgICAgaWYgKHRoaXMuY2FtZXJhLmlzQW5pbWF0ZWQgfHwgdGhpcy5jYW1lcmEuaXNNb3ZpbmcpCi0gICAgICAgICAgICAgICAgZHJhd0VkZ2VzID0gZmFsc2U7Ci0KLSAgICAgICAgLy8gQXBwbHkgdGhlIGNhbWVyYSdzIHZpZXc6Ci0gICAgICAgIHRoaXMuY2FtZXJhLmFwcGx5VmlldygKLSAgICAgICAgICAgIHVuZGVmaW5lZCwKLSAgICAgICAgICAgIHRoaXMub3B0aW9ucy5wcmVmaXgsCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMud2lkdGgsCi0gICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLmhlaWdodAotICAgICAgICAgICAgfQotICAgICAgICApOwotCi0gICAgICAgIC8vIEhpZGluZyBldmVyeXRoaW5nCi0gICAgICAgIC8vIFRPRE86IGZpbmQgYSBtb3JlIHNlbnNpYmxlIHdheSB0byBwZXJmb3JtIHRoaXMgb3BlcmF0aW9uCi0gICAgICAgIHRoaXMuaGlkZURPTUVsZW1lbnRzKHRoaXMuZG9tRWxlbWVudHMubm9kZXMpOwotICAgICAgICB0aGlzLmhpZGVET01FbGVtZW50cyh0aGlzLmRvbUVsZW1lbnRzLmVkZ2VzKTsKLSAgICAgICAgdGhpcy5oaWRlRE9NRWxlbWVudHModGhpcy5kb21FbGVtZW50cy5sYWJlbHMpOwotCi0gICAgICAgIC8vIEZpbmQgd2hpY2ggbm9kZXMgYXJlIG9uIHNjcmVlbgotICAgICAgICB0aGlzLmVkZ2VzT25TY3JlZW4gPSBbXTsKLSAgICAgICAgdGhpcy5ub2Rlc09uU2NyZWVuID0gdGhpcy5jYW1lcmEucXVhZHRyZWUuYXJlYSgKLSAgICAgICAgICAgIHRoaXMuY2FtZXJhLmdldFJlY3RhbmdsZSh0aGlzLndpZHRoLCB0aGlzLmhlaWdodCkKLSAgICAgICAgKTsKLQotICAgICAgICAvLyBOb2RlIGluZGV4Ci0gICAgICAgIGZvciAoYSA9IHRoaXMubm9kZXNPblNjcmVlbiwgaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgIGluZGV4W2FbaV0uaWRdID0gYVtpXTsKLQotICAgICAgICAvLyBGaW5kIHdoaWNoIGVkZ2VzIGFyZSBvbiBzY3JlZW4KLSAgICAgICAgZm9yIChhID0gZ3JhcGguZWRnZXMoKSwgaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykgewotICAgICAgICAgICAgbyA9IGFbaV07Ci0gICAgICAgICAgICBpZiAoCi0gICAgICAgICAgICAgICAgKGluZGV4W28uc291cmNlXSB8fCBpbmRleFtvLnRhcmdldF0pICYmCi0gICAgICAgICAgICAgICAgKCFvLmhpZGRlbiAmJiAhbm9kZXMoby5zb3VyY2UpLmhpZGRlbiAmJiAhbm9kZXMoby50YXJnZXQpLmhpZGRlbikKLSAgICAgICAgICAgICkKLSAgICAgICAgICAgICAgICB0aGlzLmVkZ2VzT25TY3JlZW4ucHVzaChvKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIERpc3BsYXkgbm9kZXMKLSAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgcmVuZGVyZXJzID0gc2lnbWEuc3ZnLm5vZGVzOwotICAgICAgICBzdWJyZW5kZXJlcnMgPSBzaWdtYS5zdmcubGFiZWxzOwotCi0gICAgICAgIC8vLS0gRmlyc3Qgd2UgY3JlYXRlIHRoZSBub2RlcyB3aGljaCBhcmUgbm90IGFscmVhZHkgY3JlYXRlZAotICAgICAgICBpZiAoZHJhd05vZGVzKQotICAgICAgICAgICAgZm9yIChhID0gdGhpcy5ub2Rlc09uU2NyZWVuLCBpID0gMCwgbCA9IGEubGVuZ3RoOyBpIDwgbDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFhW2ldLmhpZGRlbiAmJiAhdGhpcy5kb21FbGVtZW50cy5ub2Rlc1thW2ldLmlkXSkgewotCi0gICAgICAgICAgICAgICAgICAgIC8vIE5vZGUKLSAgICAgICAgICAgICAgICAgICAgZSA9IChyZW5kZXJlcnNbYVtpXS50eXBlXSB8fCByZW5kZXJlcnMuZGVmKS5jcmVhdGUoCi0gICAgICAgICAgICAgICAgICAgICAgICBhW2ldLAotICAgICAgICAgICAgICAgICAgICAgICAgZW1iZWRTZXR0aW5ncwotICAgICAgICAgICAgICAgICAgICApOwotCi0gICAgICAgICAgICAgICAgICAgIHRoaXMuZG9tRWxlbWVudHMubm9kZXNbYVtpXS5pZF0gPSBlOwotICAgICAgICAgICAgICAgICAgICB0aGlzLmRvbUVsZW1lbnRzLmdyb3Vwcy5ub2Rlcy5hcHBlbmRDaGlsZChlKTsKLQotICAgICAgICAgICAgICAgICAgICAvLyBMYWJlbAotICAgICAgICAgICAgICAgICAgICBlID0gKHN1YnJlbmRlcmVyc1thW2ldLnR5cGVdIHx8IHN1YnJlbmRlcmVycy5kZWYpLmNyZWF0ZSgKLSAgICAgICAgICAgICAgICAgICAgICAgIGFbaV0sCi0gICAgICAgICAgICAgICAgICAgICAgICBlbWJlZFNldHRpbmdzCi0gICAgICAgICAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgICAgICAgICAgdGhpcy5kb21FbGVtZW50cy5sYWJlbHNbYVtpXS5pZF0gPSBlOwotICAgICAgICAgICAgICAgICAgICB0aGlzLmRvbUVsZW1lbnRzLmdyb3Vwcy5sYWJlbHMuYXBwZW5kQ2hpbGQoZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgIC8vLS0gU2Vjb25kIHdlIHVwZGF0ZSB0aGUgbm9kZXMKLSAgICAgICAgaWYgKGRyYXdOb2RlcykKLSAgICAgICAgICAgIGZvciAoYSA9IHRoaXMubm9kZXNPblNjcmVlbiwgaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykgewotCi0gICAgICAgICAgICAgICAgaWYgKGFbaV0uaGlkZGVuKQotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICAgICAgICAgIC8vIE5vZGUKLSAgICAgICAgICAgICAgICAocmVuZGVyZXJzW2FbaV0udHlwZV0gfHwgcmVuZGVyZXJzLmRlZikudXBkYXRlKAotICAgICAgICAgICAgICAgICAgICBhW2ldLAotICAgICAgICAgICAgICAgICAgICB0aGlzLmRvbUVsZW1lbnRzLm5vZGVzW2FbaV0uaWRdLAotICAgICAgICAgICAgICAgICAgICBlbWJlZFNldHRpbmdzCi0gICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgICAgIC8vIExhYmVsCi0gICAgICAgICAgICAgICAgKHN1YnJlbmRlcmVyc1thW2ldLnR5cGVdIHx8IHN1YnJlbmRlcmVycy5kZWYpLnVwZGF0ZSgKLSAgICAgICAgICAgICAgICAgICAgYVtpXSwKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5kb21FbGVtZW50cy5sYWJlbHNbYVtpXS5pZF0sCi0gICAgICAgICAgICAgICAgICAgIGVtYmVkU2V0dGluZ3MKLSAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgfQotCi0gICAgICAgIC8vIERpc3BsYXkgZWRnZXMKLSAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgcmVuZGVyZXJzID0gc2lnbWEuc3ZnLmVkZ2VzOwotCi0gICAgICAgIC8vLS0gRmlyc3Qgd2UgY3JlYXRlIHRoZSBlZGdlcyB3aGljaCBhcmUgbm90IGFscmVhZHkgY3JlYXRlZAotICAgICAgICBpZiAoZHJhd0VkZ2VzKQotICAgICAgICAgICAgZm9yIChhID0gdGhpcy5lZGdlc09uU2NyZWVuLCBpID0gMCwgbCA9IGEubGVuZ3RoOyBpIDwgbDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmRvbUVsZW1lbnRzLmVkZ2VzW2FbaV0uaWRdKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNvdXJjZSA9IG5vZGVzKGFbaV0uc291cmNlKTsKLSAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gbm9kZXMoYVtpXS50YXJnZXQpOwotCi0gICAgICAgICAgICAgICAgICAgIGUgPSAocmVuZGVyZXJzW2FbaV0udHlwZV0gfHwgcmVuZGVyZXJzLmRlZikuY3JlYXRlKAotICAgICAgICAgICAgICAgICAgICAgICAgYVtpXSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCwKLSAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkU2V0dGluZ3MKLSAgICAgICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgICAgICAgICB0aGlzLmRvbUVsZW1lbnRzLmVkZ2VzW2FbaV0uaWRdID0gZTsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5kb21FbGVtZW50cy5ncm91cHMuZWRnZXMuYXBwZW5kQ2hpbGQoZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgIC8vLS0gU2Vjb25kIHdlIHVwZGF0ZSB0aGUgZWRnZXMKLSAgICAgICAgaWYgKGRyYXdFZGdlcykKLSAgICAgICAgICAgIGZvciAoYSA9IHRoaXMuZWRnZXNPblNjcmVlbiwgaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykgewotICAgICAgICAgICAgICAgIHNvdXJjZSA9IG5vZGVzKGFbaV0uc291cmNlKTsKLSAgICAgICAgICAgICAgICB0YXJnZXQgPSBub2RlcyhhW2ldLnRhcmdldCk7Ci0KLSAgICAgICAgICAgICAgICAocmVuZGVyZXJzW2FbaV0udHlwZV0gfHwgcmVuZGVyZXJzLmRlZikudXBkYXRlKAotICAgICAgICAgICAgICAgICAgICBhW2ldLAotICAgICAgICAgICAgICAgICAgICB0aGlzLmRvbUVsZW1lbnRzLmVkZ2VzW2FbaV0uaWRdLAotICAgICAgICAgICAgICAgICAgICBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgIHRhcmdldCwKLSAgICAgICAgICAgICAgICAgICAgZW1iZWRTZXR0aW5ncwotICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KCdyZW5kZXInKTsKLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgY3JlYXRlcyBhIERPTSBlbGVtZW50IG9mIHRoZSBzcGVjaWZpZWQgdHlwZSwgc3dpdGNoZXMgaXRzCi0gICAgICogcG9zaXRpb24gdG8gImFic29sdXRlIiwgcmVmZXJlbmNlcyBpdCB0byB0aGUgZG9tRWxlbWVudHMgYXR0cmlidXRlLCBhbmQKLSAgICAgKiBmaW5hbGx5IGFwcGVuZHMgaXQgdG8gdGhlIGNvbnRhaW5lci4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge3N0cmluZ30gdGFnIFRoZSBsYWJlbCB0YWcuCi0gICAgICogQHBhcmFtICB7c3RyaW5nfSBpZCAgVGhlIGlkIG9mIHRoZSBlbGVtZW50ICh0byBzdG9yZSBpdCBpbiAiZG9tRWxlbWVudHMiKS4KLSAgICAgKi8KLSAgICBzaWdtYS5yZW5kZXJlcnMuc3ZnLnByb3RvdHlwZS5pbml0RE9NID0gZnVuY3Rpb24gKHRhZykgewotICAgICAgICB2YXIgZG9tID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHRoaXMuc2V0dGluZ3MoJ3htbG5zJyksIHRhZyksCi0gICAgICAgICAgICBjID0gdGhpcy5zZXR0aW5ncygnY2xhc3NQcmVmaXgnKSwKLSAgICAgICAgICAgIGcsCi0gICAgICAgICAgICBsLAotICAgICAgICAgICAgaTsKLQotICAgICAgICBkb20uc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnOwotICAgICAgICBkb20uc2V0QXR0cmlidXRlKCdjbGFzcycsIGMgKyAnLXN2ZycpOwotCi0gICAgICAgIC8vIFNldHRpbmcgU1ZHIG5hbWVzcGFjZQotICAgICAgICBkb20uc2V0QXR0cmlidXRlKCd4bWxucycsIHRoaXMuc2V0dGluZ3MoJ3htbG5zJykpOwotICAgICAgICBkb20uc2V0QXR0cmlidXRlKCd4bWxuczp4bGluaycsICdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rJyk7Ci0gICAgICAgIGRvbS5zZXRBdHRyaWJ1dGUoJ3ZlcnNpb24nLCAnMS4xJyk7Ci0KLSAgICAgICAgLy8gQ3JlYXRpbmcgdGhlIG1lYXN1cmVtZW50IGNhbnZhcwotICAgICAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7Ci0gICAgICAgIGNhbnZhcy5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgYyArICctbWVhc3VyZW1lbnQtY2FudmFzJyk7Ci0KLSAgICAgICAgLy8gQXBwZW5kaW5nIGVsZW1lbnRzCi0gICAgICAgIHRoaXMuZG9tRWxlbWVudHMuZ3JhcGggPSB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZChkb20pOwotCi0gICAgICAgIC8vIENyZWF0aW5nIGdyb3VwcwotICAgICAgICB2YXIgZ3JvdXBzID0gWydlZGdlcycsICdub2RlcycsICdsYWJlbHMnLCAnaG92ZXJzJ107Ci0gICAgICAgIGZvciAoaSA9IDAsIGwgPSBncm91cHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7Ci0gICAgICAgICAgICBnID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHRoaXMuc2V0dGluZ3MoJ3htbG5zJyksICdnJyk7Ci0KLSAgICAgICAgICAgIGcuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2lkJywgYyArICctZ3JvdXAtJyArIGdyb3Vwc1tpXSk7Ci0gICAgICAgICAgICBnLnNldEF0dHJpYnV0ZU5TKG51bGwsICdjbGFzcycsIGMgKyAnLWdyb3VwJyk7Ci0KLSAgICAgICAgICAgIHRoaXMuZG9tRWxlbWVudHMuZ3JvdXBzW2dyb3Vwc1tpXV0gPQotICAgICAgICAgICAgICAgIHRoaXMuZG9tRWxlbWVudHMuZ3JhcGguYXBwZW5kQ2hpbGQoZyk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBBcHBlbmRpbmcgbWVhc3VyZW1lbnQgY2FudmFzCi0gICAgICAgIHRoaXMuY29udGFpbmVyLmFwcGVuZENoaWxkKGNhbnZhcyk7Ci0gICAgICAgIHRoaXMubWVhc3VyZW1lbnRDYW52YXMgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaGlkZXMgYSBiYXRjaCBvZiBTVkcgRE9NIGVsZW1lbnRzLgotICAgICAqCi0gICAgICogQHBhcmFtICB7YXJyYXl9ICAgICAgICAgICAgICAgICAgZWxlbWVudHMgIEFuIGFycmF5IG9mIGVsZW1lbnRzIHRvIGhpZGUuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgcmVuZGVyZXIgIFRoZSByZW5kZXJlciB0byB1c2UuCi0gICAgICogQHJldHVybiB7c2lnbWEucmVuZGVyZXJzLnN2Z30gICAgICAgICAgICAgIFJldHVybnMgdGhlIGluc3RhbmNlIGl0c2VsZi4KLSAgICAgKi8KLSAgICBzaWdtYS5yZW5kZXJlcnMuc3ZnLnByb3RvdHlwZS5oaWRlRE9NRWxlbWVudHMgPSBmdW5jdGlvbiAoZWxlbWVudHMpIHsKLSAgICAgICAgdmFyIG8sCi0gICAgICAgICAgICBpOwotCi0gICAgICAgIGZvciAoaSBpbiBlbGVtZW50cykgewotICAgICAgICAgICAgbyA9IGVsZW1lbnRzW2ldOwotICAgICAgICAgICAgc2lnbWEuc3ZnLnV0aWxzLmhpZGUobyk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgYmluZHMgdGhlIGhvdmVyIGV2ZW50cyB0byB0aGUgcmVuZGVyZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtzdHJpbmd9IHByZWZpeCBUaGUgcmVuZGVyZXIgcHJlZml4LgotICAgICAqLwotICAgIC8vIFRPRE86IGFkZCBvcHRpb24gYWJvdXQgd2hldGhlciB0byBkaXNwbGF5IGhvdmVycyBvciBub3QKLSAgICBzaWdtYS5yZW5kZXJlcnMuc3ZnLnByb3RvdHlwZS5iaW5kSG92ZXJzID0gZnVuY3Rpb24gKHByZWZpeCkgewotICAgICAgICB2YXIgcmVuZGVyZXJzID0gc2lnbWEuc3ZnLmhvdmVycywKLSAgICAgICAgICAgIHNlbGYgPSB0aGlzLAotICAgICAgICAgICAgaG92ZXJlZE5vZGU7Ci0KLSAgICAgICAgZnVuY3Rpb24gb3Zlck5vZGUoZSkgewotICAgICAgICAgICAgdmFyIG5vZGUgPSBlLmRhdGEubm9kZSwKLSAgICAgICAgICAgICAgICBlbWJlZFNldHRpbmdzID0gc2VsZi5zZXR0aW5ncy5lbWJlZE9iamVjdHMoewotICAgICAgICAgICAgICAgICAgICBwcmVmaXg6IHByZWZpeAotICAgICAgICAgICAgICAgIH0pOwotCi0gICAgICAgICAgICBpZiAoIWVtYmVkU2V0dGluZ3MoJ2VuYWJsZUhvdmVyaW5nJykpCi0gICAgICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgICAgICB2YXIgaG92ZXIgPSAocmVuZGVyZXJzW25vZGUudHlwZV0gfHwgcmVuZGVyZXJzLmRlZikuY3JlYXRlKAotICAgICAgICAgICAgICAgIG5vZGUsCi0gICAgICAgICAgICAgICAgc2VsZi5kb21FbGVtZW50cy5ub2Rlc1tub2RlLmlkXSwKLSAgICAgICAgICAgICAgICBzZWxmLm1lYXN1cmVtZW50Q2FudmFzLAotICAgICAgICAgICAgICAgIGVtYmVkU2V0dGluZ3MKLSAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIHNlbGYuZG9tRWxlbWVudHMuaG92ZXJzW25vZGUuaWRdID0gaG92ZXI7Ci0KLSAgICAgICAgICAgIC8vIEluc2VydGluZyB0aGUgaG92ZXIgaW4gdGhlIGRvbQotICAgICAgICAgICAgc2VsZi5kb21FbGVtZW50cy5ncm91cHMuaG92ZXJzLmFwcGVuZENoaWxkKGhvdmVyKTsKLSAgICAgICAgICAgIGhvdmVyZWROb2RlID0gbm9kZTsKLSAgICAgICAgfQotCi0gICAgICAgIGZ1bmN0aW9uIG91dE5vZGUoZSkgewotICAgICAgICAgICAgdmFyIG5vZGUgPSBlLmRhdGEubm9kZSwKLSAgICAgICAgICAgICAgICBlbWJlZFNldHRpbmdzID0gc2VsZi5zZXR0aW5ncy5lbWJlZE9iamVjdHMoewotICAgICAgICAgICAgICAgICAgICBwcmVmaXg6IHByZWZpeAotICAgICAgICAgICAgICAgIH0pOwotCi0gICAgICAgICAgICBpZiAoIWVtYmVkU2V0dGluZ3MoJ2VuYWJsZUhvdmVyaW5nJykpCi0gICAgICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgICAgICAvLyBEZWxldGluZyBlbGVtZW50Ci0gICAgICAgICAgICBzZWxmLmRvbUVsZW1lbnRzLmdyb3Vwcy5ob3ZlcnMucmVtb3ZlQ2hpbGQoCi0gICAgICAgICAgICAgICAgc2VsZi5kb21FbGVtZW50cy5ob3ZlcnNbbm9kZS5pZF0KLSAgICAgICAgICAgICk7Ci0gICAgICAgICAgICBob3ZlcmVkTm9kZSA9IG51bGw7Ci0gICAgICAgICAgICBkZWxldGUgc2VsZi5kb21FbGVtZW50cy5ob3ZlcnNbbm9kZS5pZF07Ci0KLSAgICAgICAgICAgIC8vIFJlaW5zdGF0ZQotICAgICAgICAgICAgc2VsZi5kb21FbGVtZW50cy5ncm91cHMubm9kZXMuYXBwZW5kQ2hpbGQoCi0gICAgICAgICAgICAgICAgc2VsZi5kb21FbGVtZW50cy5ub2Rlc1tub2RlLmlkXQotICAgICAgICAgICAgKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE9QVElNSVpFOiBwZXJmb3JtIGEgcmVhbCB1cGRhdGUgcmF0aGVyIHRoYW4gYSBkZWxldGlvbgotICAgICAgICBmdW5jdGlvbiB1cGRhdGUoKSB7Ci0gICAgICAgICAgICBpZiAoIWhvdmVyZWROb2RlKQotICAgICAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAgICAgdmFyIGVtYmVkU2V0dGluZ3MgPSBzZWxmLnNldHRpbmdzLmVtYmVkT2JqZWN0cyh7Ci0gICAgICAgICAgICAgICAgcHJlZml4OiBwcmVmaXgKLSAgICAgICAgICAgIH0pOwotCi0gICAgICAgICAgICAvLyBEZWxldGluZyBlbGVtZW50IGJlZm9yZSB1cGRhdGUKLSAgICAgICAgICAgIHNlbGYuZG9tRWxlbWVudHMuZ3JvdXBzLmhvdmVycy5yZW1vdmVDaGlsZCgKLSAgICAgICAgICAgICAgICBzZWxmLmRvbUVsZW1lbnRzLmhvdmVyc1tob3ZlcmVkTm9kZS5pZF0KLSAgICAgICAgICAgICk7Ci0gICAgICAgICAgICBkZWxldGUgc2VsZi5kb21FbGVtZW50cy5ob3ZlcnNbaG92ZXJlZE5vZGUuaWRdOwotCi0gICAgICAgICAgICB2YXIgaG92ZXIgPSAocmVuZGVyZXJzW2hvdmVyZWROb2RlLnR5cGVdIHx8IHJlbmRlcmVycy5kZWYpLmNyZWF0ZSgKLSAgICAgICAgICAgICAgICBob3ZlcmVkTm9kZSwKLSAgICAgICAgICAgICAgICBzZWxmLmRvbUVsZW1lbnRzLm5vZGVzW2hvdmVyZWROb2RlLmlkXSwKLSAgICAgICAgICAgICAgICBzZWxmLm1lYXN1cmVtZW50Q2FudmFzLAotICAgICAgICAgICAgICAgIGVtYmVkU2V0dGluZ3MKLSAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIHNlbGYuZG9tRWxlbWVudHMuaG92ZXJzW2hvdmVyZWROb2RlLmlkXSA9IGhvdmVyOwotCi0gICAgICAgICAgICAvLyBJbnNlcnRpbmcgdGhlIGhvdmVyIGluIHRoZSBkb20KLSAgICAgICAgICAgIHNlbGYuZG9tRWxlbWVudHMuZ3JvdXBzLmhvdmVycy5hcHBlbmRDaGlsZChob3Zlcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBCaW5kaW5nIGV2ZW50cwotICAgICAgICB0aGlzLmJpbmQoJ292ZXJOb2RlJywgb3Zlck5vZGUpOwotICAgICAgICB0aGlzLmJpbmQoJ291dE5vZGUnLCBvdXROb2RlKTsKLQotICAgICAgICAvLyBVcGRhdGUgb24gcmVuZGVyCi0gICAgICAgIHRoaXMuYmluZCgncmVuZGVyJywgdXBkYXRlKTsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgcmVzaXplcyBlYWNoIERPTSBlbGVtZW50cyBpbiB0aGUgY29udGFpbmVyIGFuZCBzdG9yZXMgdGhlIG5ldwotICAgICAqIGRpbWVuc2lvbnMuIFRoZW4sIGl0IHJlbmRlcnMgdGhlIGdyYXBoLgotICAgICAqCi0gICAgICogQHBhcmFtICB7P251bWJlcn0gICAgICAgICAgICAgICAgd2lkdGggIFRoZSBuZXcgd2lkdGggb2YgdGhlIGNvbnRhaW5lci4KLSAgICAgKiBAcGFyYW0gIHs/bnVtYmVyfSAgICAgICAgICAgICAgICBoZWlnaHQgVGhlIG5ldyBoZWlnaHQgb2YgdGhlIGNvbnRhaW5lci4KLSAgICAgKiBAcmV0dXJuIHtzaWdtYS5yZW5kZXJlcnMuc3ZnfSAgICAgICAgICAgUmV0dXJucyB0aGUgaW5zdGFuY2UgaXRzZWxmLgotICAgICAqLwotICAgIHNpZ21hLnJlbmRlcmVycy5zdmcucHJvdG90eXBlLnJlc2l6ZSA9IGZ1bmN0aW9uICh3LCBoKSB7Ci0gICAgICAgIHZhciBvbGRXaWR0aCA9IHRoaXMud2lkdGgsCi0gICAgICAgICAgICBvbGRIZWlnaHQgPSB0aGlzLmhlaWdodCwKLSAgICAgICAgICAgIHBpeGVsUmF0aW8gPSAxOwotCi0gICAgICAgIGlmICh3ICE9PSB1bmRlZmluZWQgJiYgaCAhPT0gdW5kZWZpbmVkKSB7Ci0gICAgICAgICAgICB0aGlzLndpZHRoID0gdzsKLSAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gaDsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHRoaXMud2lkdGggPSB0aGlzLmNvbnRhaW5lci5vZmZzZXRXaWR0aDsKLSAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy5jb250YWluZXIub2Zmc2V0SGVpZ2h0OwotCi0gICAgICAgICAgICB3ID0gdGhpcy53aWR0aDsKLSAgICAgICAgICAgIGggPSB0aGlzLmhlaWdodDsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChvbGRXaWR0aCAhPT0gdGhpcy53aWR0aCB8fCBvbGRIZWlnaHQgIT09IHRoaXMuaGVpZ2h0KSB7Ci0gICAgICAgICAgICB0aGlzLmRvbUVsZW1lbnRzLmdyYXBoLnN0eWxlLndpZHRoID0gdyArICdweCc7Ci0gICAgICAgICAgICB0aGlzLmRvbUVsZW1lbnRzLmdyYXBoLnN0eWxlLmhlaWdodCA9IGggKyAncHgnOwotCi0gICAgICAgICAgICBpZiAodGhpcy5kb21FbGVtZW50cy5ncmFwaC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdzdmcnKSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5kb21FbGVtZW50cy5ncmFwaC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgKHcgKiBwaXhlbFJhdGlvKSk7Ci0gICAgICAgICAgICAgICAgdGhpcy5kb21FbGVtZW50cy5ncmFwaC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIChoICogcGl4ZWxSYXRpbykpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfTsKLQotCi0gICAgLyoqCi0gICAgICogVGhlIGxhYmVscywgbm9kZXMgYW5kIGVkZ2VzIHJlbmRlcmVycyBhcmUgc3RvcmVkIGluIHRoZSB0aHJlZSBmb2xsb3dpbmcKLSAgICAgKiBvYmplY3RzLiBXaGVuIGFuIGVsZW1lbnQgaXMgZHJhd24sIGl0cyB0eXBlIHdpbGwgYmUgY2hlY2tlZCBhbmQgaWYgYQotICAgICAqIHJlbmRlcmVyIHdpdGggdGhlIHNhbWUgbmFtZSBleGlzdHMsIGl0IHdpbGwgYmUgdXNlZC4gSWYgbm90IGZvdW5kLCB0aGUKLSAgICAgKiBkZWZhdWx0IHJlbmRlcmVyIHdpbGwgYmUgdXNlZCBpbnN0ZWFkLgotICAgICAqCi0gICAgICogVGhleSBhcmUgc3RvcmVkIGluIGRpZmZlcmVudCBmaWxlcywgaW4gdGhlICIuL3N2ZyIgZm9sZGVyLgotICAgICAqLwotICAgIHNpZ21hLnV0aWxzLnBrZygnc2lnbWEuc3ZnLm5vZGVzJyk7Ci0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5zdmcuZWRnZXMnKTsKLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLnN2Zy5sYWJlbHMnKTsKLX0pLmNhbGwodGhpcyk7Ci0KLTsoZnVuY3Rpb24gKGdsb2JhbCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIGlmICh0eXBlb2Ygc2lnbWEgPT09ICd1bmRlZmluZWQnKQotICAgICAgICB0aHJvdyAnc2lnbWEgaXMgbm90IGRlY2xhcmVkJzsKLQotICAgIC8vIEluaXRpYWxpemUgcGFja2FnZXM6Ci0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5yZW5kZXJlcnMnKTsKLQotICAgIC8vIENoZWNrIGlmIFdlYkdMIGlzIGVuYWJsZWQ6Ci0gICAgdmFyIGNhbnZhcywKLSAgICAgICAgd2ViZ2wgPSAhIWdsb2JhbC5XZWJHTFJlbmRlcmluZ0NvbnRleHQ7Ci0gICAgaWYgKHdlYmdsKSB7Ci0gICAgICAgIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgd2ViZ2wgPSAhISgKLSAgICAgICAgICAgICAgICBjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wnKSB8fAotICAgICAgICAgICAgICAgIGNhbnZhcy5nZXRDb250ZXh0KCdleHBlcmltZW50YWwtd2ViZ2wnKQotICAgICAgICAgICAgKTsKLSAgICAgICAgfSBjYXRjaCAoZSkgewotICAgICAgICAgICAgd2ViZ2wgPSBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIENvcHkgdGhlIGdvb2QgcmVuZGVyZXI6Ci0gICAgc2lnbWEucmVuZGVyZXJzLmRlZiA9IHdlYmdsID8KLSAgICAgICAgc2lnbWEucmVuZGVyZXJzLndlYmdsIDoKLSAgICAgICAgc2lnbWEucmVuZGVyZXJzLmNhbnZhczsKLX0pKHRoaXMpOwotCi07KGZ1bmN0aW9uICgpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLndlYmdsLm5vZGVzJyk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG5vZGUgcmVuZGVyZXIgd2lsbCBkaXNwbGF5IG5vZGVzIGFzIGRpc2NzLCBzaGFwZWQgaW4gdHJpYW5nbGVzIHdpdGgKLSAgICAgKiB0aGUgZ2wuVFJJQU5HTEVTIGRpc3BsYXkgbW9kZS4gU28sIHRvIGJlIG1vcmUgcHJlY2lzZSwgdG8gZHJhdyBvbmUgbm9kZSwKLSAgICAgKiBpdCB3aWxsIHN0b3JlIHRocmVlIHRpbWVzIHRoZSBjZW50ZXIgb2Ygbm9kZSwgd2l0aCB0aGUgY29sb3IgYW5kIHRoZSBzaXplLAotICAgICAqIGFuZCBhbiBhbmdsZSBpbmRpY2F0aW5nIHdoaWNoICJjb3JuZXIiIG9mIHRoZSB0cmlhbmdsZSB0byBkcmF3LgotICAgICAqCi0gICAgICogVGhlIGZyYWdtZW50IHNoYWRlciBkb2VzIG5vdCBkZWFsIHdpdGggYW50aS1hbGlhc2luZywgc28gbWFrZSBzdXJlIHRoYXQKLSAgICAgKiB5b3UgZGVhbCB3aXRoIGl0IHNvbWV3aGVyZSBlbHNlIGluIHRoZSBjb2RlIChieSBkZWZhdWx0LCB0aGUgV2ViR0wKLSAgICAgKiByZW5kZXJlciB3aWxsIG92ZXJzYW1wbGUgdGhlIHJlbmRlcmluZyB0aHJvdWdoIHRoZSB3ZWJnbE92ZXJzYW1wbGluZ1JhdGlvCi0gICAgICogdmFsdWUpLgotICAgICAqLwotICAgIHNpZ21hLndlYmdsLm5vZGVzLmRlZiA9IHsKLSAgICAgICAgUE9JTlRTOiAzLAotICAgICAgICBBVFRSSUJVVEVTOiA1LAotICAgICAgICBhZGROb2RlOiBmdW5jdGlvbiAobm9kZSwgZGF0YSwgaSwgcHJlZml4LCBzZXR0aW5ncykgewotICAgICAgICAgICAgdmFyIGNvbG9yID0gc2lnbWEudXRpbHMuZmxvYXRDb2xvcigKLSAgICAgICAgICAgICAgICBub2RlLmNvbG9yIHx8IHNldHRpbmdzKCdkZWZhdWx0Tm9kZUNvbG9yJykKLSAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IG5vZGVbcHJlZml4ICsgJ3gnXTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IG5vZGVbcHJlZml4ICsgJ3knXTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IG5vZGVbcHJlZml4ICsgJ3NpemUnXTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IGNvbG9yOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMDsKLQotICAgICAgICAgICAgZGF0YVtpKytdID0gbm9kZVtwcmVmaXggKyAneCddOwotICAgICAgICAgICAgZGF0YVtpKytdID0gbm9kZVtwcmVmaXggKyAneSddOwotICAgICAgICAgICAgZGF0YVtpKytdID0gbm9kZVtwcmVmaXggKyAnc2l6ZSddOwotICAgICAgICAgICAgZGF0YVtpKytdID0gY29sb3I7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAyICogTWF0aC5QSSAvIDM7Ci0KLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IG5vZGVbcHJlZml4ICsgJ3gnXTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IG5vZGVbcHJlZml4ICsgJ3knXTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IG5vZGVbcHJlZml4ICsgJ3NpemUnXTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IGNvbG9yOwotICAgICAgICAgICAgZGF0YVtpKytdID0gNCAqIE1hdGguUEkgLyAzOwotICAgICAgICB9LAotICAgICAgICByZW5kZXI6IGZ1bmN0aW9uIChnbCwgcHJvZ3JhbSwgZGF0YSwgcGFyYW1zKSB7Ci0gICAgICAgICAgICB2YXIgYnVmZmVyOwotCi0gICAgICAgICAgICAvLyBEZWZpbmUgYXR0cmlidXRlczoKLSAgICAgICAgICAgIHZhciBwb3NpdGlvbkxvY2F0aW9uID0KLSAgICAgICAgICAgICAgICAgICAgZ2wuZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbSwgJ2FfcG9zaXRpb24nKSwKLSAgICAgICAgICAgICAgICBzaXplTG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAnYV9zaXplJyksCi0gICAgICAgICAgICAgICAgY29sb3JMb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sICdhX2NvbG9yJyksCi0gICAgICAgICAgICAgICAgYW5nbGVMb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sICdhX2FuZ2xlJyksCi0gICAgICAgICAgICAgICAgcmVzb2x1dGlvbkxvY2F0aW9uID0KLSAgICAgICAgICAgICAgICAgICAgZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sICd1X3Jlc29sdXRpb24nKSwKLSAgICAgICAgICAgICAgICBtYXRyaXhMb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCAndV9tYXRyaXgnKSwKLSAgICAgICAgICAgICAgICByYXRpb0xvY2F0aW9uID0KLSAgICAgICAgICAgICAgICAgICAgZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sICd1X3JhdGlvJyksCi0gICAgICAgICAgICAgICAgc2NhbGVMb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCAndV9zY2FsZScpOwotCi0gICAgICAgICAgICBidWZmZXIgPSBnbC5jcmVhdGVCdWZmZXIoKTsKLSAgICAgICAgICAgIGdsLmJpbmRCdWZmZXIoZ2wuQVJSQVlfQlVGRkVSLCBidWZmZXIpOwotICAgICAgICAgICAgZ2wuYnVmZmVyRGF0YShnbC5BUlJBWV9CVUZGRVIsIGRhdGEsIGdsLkRZTkFNSUNfRFJBVyk7Ci0KLSAgICAgICAgICAgIGdsLnVuaWZvcm0yZihyZXNvbHV0aW9uTG9jYXRpb24sIHBhcmFtcy53aWR0aCwgcGFyYW1zLmhlaWdodCk7Ci0gICAgICAgICAgICBnbC51bmlmb3JtMWYoCi0gICAgICAgICAgICAgICAgcmF0aW9Mb2NhdGlvbiwKLSAgICAgICAgICAgICAgICAxIC8gTWF0aC5wb3cocGFyYW1zLnJhdGlvLCBwYXJhbXMuc2V0dGluZ3MoJ25vZGVzUG93UmF0aW8nKSkKLSAgICAgICAgICAgICk7Ci0gICAgICAgICAgICBnbC51bmlmb3JtMWYoc2NhbGVMb2NhdGlvbiwgcGFyYW1zLnNjYWxpbmdSYXRpbyk7Ci0gICAgICAgICAgICBnbC51bmlmb3JtTWF0cml4M2Z2KG1hdHJpeExvY2F0aW9uLCBmYWxzZSwgcGFyYW1zLm1hdHJpeCk7Ci0KLSAgICAgICAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHBvc2l0aW9uTG9jYXRpb24pOwotICAgICAgICAgICAgZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkoc2l6ZUxvY2F0aW9uKTsKLSAgICAgICAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KGNvbG9yTG9jYXRpb24pOwotICAgICAgICAgICAgZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkoYW5nbGVMb2NhdGlvbik7Ci0KLSAgICAgICAgICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIoCi0gICAgICAgICAgICAgICAgcG9zaXRpb25Mb2NhdGlvbiwKLSAgICAgICAgICAgICAgICAyLAotICAgICAgICAgICAgICAgIGdsLkZMT0FULAotICAgICAgICAgICAgICAgIGZhbHNlLAotICAgICAgICAgICAgICAgIHRoaXMuQVRUUklCVVRFUyAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCwKLSAgICAgICAgICAgICAgICAwCi0gICAgICAgICAgICApOwotICAgICAgICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcigKLSAgICAgICAgICAgICAgICBzaXplTG9jYXRpb24sCi0gICAgICAgICAgICAgICAgMSwKLSAgICAgICAgICAgICAgICBnbC5GTE9BVCwKLSAgICAgICAgICAgICAgICBmYWxzZSwKLSAgICAgICAgICAgICAgICB0aGlzLkFUVFJJQlVURVMgKiBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQsCi0gICAgICAgICAgICAgICAgOAotICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIoCi0gICAgICAgICAgICAgICAgY29sb3JMb2NhdGlvbiwKLSAgICAgICAgICAgICAgICAxLAotICAgICAgICAgICAgICAgIGdsLkZMT0FULAotICAgICAgICAgICAgICAgIGZhbHNlLAotICAgICAgICAgICAgICAgIHRoaXMuQVRUUklCVVRFUyAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCwKLSAgICAgICAgICAgICAgICAxMgotICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIoCi0gICAgICAgICAgICAgICAgYW5nbGVMb2NhdGlvbiwKLSAgICAgICAgICAgICAgICAxLAotICAgICAgICAgICAgICAgIGdsLkZMT0FULAotICAgICAgICAgICAgICAgIGZhbHNlLAotICAgICAgICAgICAgICAgIHRoaXMuQVRUUklCVVRFUyAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCwKLSAgICAgICAgICAgICAgICAxNgotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgZ2wuZHJhd0FycmF5cygKLSAgICAgICAgICAgICAgICBnbC5UUklBTkdMRVMsCi0gICAgICAgICAgICAgICAgcGFyYW1zLnN0YXJ0IHx8IDAsCi0gICAgICAgICAgICAgICAgcGFyYW1zLmNvdW50IHx8IChkYXRhLmxlbmd0aCAvIHRoaXMuQVRUUklCVVRFUykKLSAgICAgICAgICAgICk7Ci0gICAgICAgIH0sCi0gICAgICAgIGluaXRQcm9ncmFtOiBmdW5jdGlvbiAoZ2wpIHsKLSAgICAgICAgICAgIHZhciB2ZXJ0ZXhTaGFkZXIsCi0gICAgICAgICAgICAgICAgZnJhZ21lbnRTaGFkZXIsCi0gICAgICAgICAgICAgICAgcHJvZ3JhbTsKLQotICAgICAgICAgICAgdmVydGV4U2hhZGVyID0gc2lnbWEudXRpbHMubG9hZFNoYWRlcigKLSAgICAgICAgICAgICAgICBnbCwKLSAgICAgICAgICAgICAgICBbCi0gICAgICAgICAgICAgICAgICAgICdhdHRyaWJ1dGUgdmVjMiBhX3Bvc2l0aW9uOycsCi0gICAgICAgICAgICAgICAgICAgICdhdHRyaWJ1dGUgZmxvYXQgYV9zaXplOycsCi0gICAgICAgICAgICAgICAgICAgICdhdHRyaWJ1dGUgZmxvYXQgYV9jb2xvcjsnLAotICAgICAgICAgICAgICAgICAgICAnYXR0cmlidXRlIGZsb2F0IGFfYW5nbGU7JywKLQotICAgICAgICAgICAgICAgICAgICAndW5pZm9ybSB2ZWMyIHVfcmVzb2x1dGlvbjsnLAotICAgICAgICAgICAgICAgICAgICAndW5pZm9ybSBmbG9hdCB1X3JhdGlvOycsCi0gICAgICAgICAgICAgICAgICAgICd1bmlmb3JtIGZsb2F0IHVfc2NhbGU7JywKLSAgICAgICAgICAgICAgICAgICAgJ3VuaWZvcm0gbWF0MyB1X21hdHJpeDsnLAotCi0gICAgICAgICAgICAgICAgICAgICd2YXJ5aW5nIHZlYzQgY29sb3I7JywKLSAgICAgICAgICAgICAgICAgICAgJ3ZhcnlpbmcgdmVjMiBjZW50ZXI7JywKLSAgICAgICAgICAgICAgICAgICAgJ3ZhcnlpbmcgZmxvYXQgcmFkaXVzOycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ3ZvaWQgbWFpbigpIHsnLAotICAgICAgICAgICAgICAgICAgICAvLyBNdWx0aXBseSB0aGUgcG9pbnQgc2l6ZSB0d2ljZToKLSAgICAgICAgICAgICAgICAgICAgJ3JhZGl1cyA9IGFfc2l6ZSAqIHVfcmF0aW87JywKLQotICAgICAgICAgICAgICAgICAgICAvLyBTY2FsZSBmcm9tIFtbLTEgMV0gWy0xIDFdXSB0byB0aGUgY29udGFpbmVyOgotICAgICAgICAgICAgICAgICAgICAndmVjMiBwb3NpdGlvbiA9ICh1X21hdHJpeCAqIHZlYzMoYV9wb3NpdGlvbiwgMSkpLnh5OycsCi0gICAgICAgICAgICAgICAgICAgIC8vICdjZW50ZXIgPSAocG9zaXRpb24gLyB1X3Jlc29sdXRpb24gKiAyLjAgLSAxLjApICogdmVjMigxLCAtMSk7JywKLSAgICAgICAgICAgICAgICAgICAgJ2NlbnRlciA9IHBvc2l0aW9uICogdV9zY2FsZTsnLAotICAgICAgICAgICAgICAgICAgICAnY2VudGVyID0gdmVjMihjZW50ZXIueCwgdV9zY2FsZSAqIHVfcmVzb2x1dGlvbi55IC0gY2VudGVyLnkpOycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ3Bvc2l0aW9uID0gcG9zaXRpb24gKycsCi0gICAgICAgICAgICAgICAgICAgICcyLjAgKiByYWRpdXMgKiB2ZWMyKGNvcyhhX2FuZ2xlKSwgc2luKGFfYW5nbGUpKTsnLAotICAgICAgICAgICAgICAgICAgICAncG9zaXRpb24gPSAocG9zaXRpb24gLyB1X3Jlc29sdXRpb24gKiAyLjAgLSAxLjApICogdmVjMigxLCAtMSk7JywKLQotICAgICAgICAgICAgICAgICAgICAncmFkaXVzID0gcmFkaXVzICogdV9zY2FsZTsnLAotCi0gICAgICAgICAgICAgICAgICAgICdnbF9Qb3NpdGlvbiA9IHZlYzQocG9zaXRpb24sIDAsIDEpOycsCi0KLSAgICAgICAgICAgICAgICAgICAgLy8gRXh0cmFjdCB0aGUgY29sb3I6Ci0gICAgICAgICAgICAgICAgICAgICdmbG9hdCBjID0gYV9jb2xvcjsnLAotICAgICAgICAgICAgICAgICAgICAnY29sb3IuYiA9IG1vZChjLCAyNTYuMCk7IGMgPSBmbG9vcihjIC8gMjU2LjApOycsCi0gICAgICAgICAgICAgICAgICAgICdjb2xvci5nID0gbW9kKGMsIDI1Ni4wKTsgYyA9IGZsb29yKGMgLyAyNTYuMCk7JywKLSAgICAgICAgICAgICAgICAgICAgJ2NvbG9yLnIgPSBtb2QoYywgMjU2LjApOyBjID0gZmxvb3IoYyAvIDI1Ni4wKTsgY29sb3IgLz0gMjU1LjA7JywKLSAgICAgICAgICAgICAgICAgICAgJ2NvbG9yLmEgPSAxLjA7JywKLSAgICAgICAgICAgICAgICAgICAgJ30nCi0gICAgICAgICAgICAgICAgXS5qb2luKCdcbicpLAotICAgICAgICAgICAgICAgIGdsLlZFUlRFWF9TSEFERVIKLSAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIGZyYWdtZW50U2hhZGVyID0gc2lnbWEudXRpbHMubG9hZFNoYWRlcigKLSAgICAgICAgICAgICAgICBnbCwKLSAgICAgICAgICAgICAgICBbCi0gICAgICAgICAgICAgICAgICAgICdwcmVjaXNpb24gbWVkaXVtcCBmbG9hdDsnLAotCi0gICAgICAgICAgICAgICAgICAgICd2YXJ5aW5nIHZlYzQgY29sb3I7JywKLSAgICAgICAgICAgICAgICAgICAgJ3ZhcnlpbmcgdmVjMiBjZW50ZXI7JywKLSAgICAgICAgICAgICAgICAgICAgJ3ZhcnlpbmcgZmxvYXQgcmFkaXVzOycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ3ZvaWQgbWFpbih2b2lkKSB7JywKLSAgICAgICAgICAgICAgICAgICAgJ3ZlYzQgY29sb3IwID0gdmVjNCgwLjAsIDAuMCwgMC4wLCAwLjApOycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ3ZlYzIgbSA9IGdsX0ZyYWdDb29yZC54eSAtIGNlbnRlcjsnLAotICAgICAgICAgICAgICAgICAgICAnZmxvYXQgZGlmZiA9IHJhZGl1cyAtIHNxcnQobS54ICogbS54ICsgbS55ICogbS55KTsnLAotCi0gICAgICAgICAgICAgICAgICAgIC8vIEhlcmUgaXMgaG93IHdlIGRyYXcgYSBkaXNjIGluc3RlYWQgb2YgYSBzcXVhcmU6Ci0gICAgICAgICAgICAgICAgICAgICdpZiAoZGlmZiA+IDAuMCknLAotICAgICAgICAgICAgICAgICAgICAnZ2xfRnJhZ0NvbG9yID0gY29sb3I7JywKLSAgICAgICAgICAgICAgICAgICAgJ2Vsc2UnLAotICAgICAgICAgICAgICAgICAgICAnZ2xfRnJhZ0NvbG9yID0gY29sb3IwOycsCi0gICAgICAgICAgICAgICAgICAgICd9JwotICAgICAgICAgICAgICAgIF0uam9pbignXG4nKSwKLSAgICAgICAgICAgICAgICBnbC5GUkFHTUVOVF9TSEFERVIKLSAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIHByb2dyYW0gPSBzaWdtYS51dGlscy5sb2FkUHJvZ3JhbShnbCwgW3ZlcnRleFNoYWRlciwgZnJhZ21lbnRTaGFkZXJdKTsKLQotICAgICAgICAgICAgcmV0dXJuIHByb2dyYW07Ci0gICAgICAgIH0KLSAgICB9OwotfSkoKTsKLQotOyhmdW5jdGlvbiAoKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS53ZWJnbC5ub2RlcycpOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBub2RlIHJlbmRlcmVyIHdpbGwgZGlzcGxheSBub2RlcyBpbiB0aGUgZmFzdGVzdCB3YXk6IE5vZGVzIGFyZSBiYXNpYwotICAgICAqIHNxdWFyZXMsIGRyYXduIHRocm91Z2ggdGhlIGdsLlBPSU5UUyBkcmF3aW5nIG1ldGhvZC4gVGhlIHNpemUgb2YgdGhlIG5vZGVzCi0gICAgICogYXJlIHJlcHJlc2VudGVkIHdpdGggdGhlICJnbF9Qb2ludFNpemUiIHZhbHVlIGluIHRoZSB2ZXJ0ZXggc2hhZGVyLgotICAgICAqCi0gICAgICogSXQgaXMgdGhlIGZhc3Rlc3Qgbm9kZSByZW5kZXJlciBoZXJlIHNpbmNlIHRoZSBidWZmZXIganVzdCB0YWtlcyBvbmUgbGluZQotICAgICAqIHRvIGRyYXcgZWFjaCBub2RlICh3aXRoIGF0dHJpYnV0ZXMgIngiLCAieSIsICJzaXplIiBhbmQgImNvbG9yIikuCi0gICAgICoKLSAgICAgKiBOZXZlcnRoZWxlc3MsIHRoaXMgbWV0aG9kIGhhcyBzb21lIHByb2JsZW1zLCBlc3BlY2lhbGx5IGR1ZSB0byBzb21lIGlzc3VlcwotICAgICAqIHdpdGggdGhlIGdsLlBPSU5UUzoKLSAgICAgKiAgLSBGaXJzdCwgaWYgdGhlIGNlbnRlciBvZiBhIG5vZGUgaXMgb3V0c2lkZSB0aGUgc2NlbmUsIHRoZSBwb2ludCB3aWxsIG5vdAotICAgICAqICAgIGJlIGRyYXduLCBldmVuIGlmIGl0IHNob3VsZCBiZSBwYXJ0bHkgb24gc2NyZWVuLgotICAgICAqICAtIEkgdHJpZWQgYXBwbHlpbmcgYSBmcmFnbWVudCBzaGFkZXIgc2ltaWxhciB0byB0aGUgb25lIGluIHRoZSBkZWZhdWx0Ci0gICAgICogICAgbm9kZSByZW5kZXJlciB0byBkaXNwbGF5IHRoZW0gYXMgZGlzY3MsIGJ1dCBpdCBkaWQgbm90IHdvcmsgZmluZSBvbgotICAgICAqICAgIHNvbWUgY29tcHV0ZXJzIHNldHRpbmdzLCBmaWxsaW5nIHRoZSBkaXNjcyB3aXRoIHdlaXJkIGdyYWRpZW50cyBub3QKLSAgICAgKiAgICBkZXBlbmRpbmcgb24gdGhlIGFjdHVhbCBjb2xvci4KLSAgICAgKi8KLSAgICBzaWdtYS53ZWJnbC5ub2Rlcy5mYXN0ID0gewotICAgICAgICBQT0lOVFM6IDEsCi0gICAgICAgIEFUVFJJQlVURVM6IDQsCi0gICAgICAgIGFkZE5vZGU6IGZ1bmN0aW9uIChub2RlLCBkYXRhLCBpLCBwcmVmaXgsIHNldHRpbmdzKSB7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSBub2RlW3ByZWZpeCArICd4J107Ci0gICAgICAgICAgICBkYXRhW2krK10gPSBub2RlW3ByZWZpeCArICd5J107Ci0gICAgICAgICAgICBkYXRhW2krK10gPSBub2RlW3ByZWZpeCArICdzaXplJ107Ci0gICAgICAgICAgICBkYXRhW2krK10gPSBzaWdtYS51dGlscy5mbG9hdENvbG9yKAotICAgICAgICAgICAgICAgIG5vZGUuY29sb3IgfHwgc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKQotICAgICAgICAgICAgKTsKLSAgICAgICAgfSwKLSAgICAgICAgcmVuZGVyOiBmdW5jdGlvbiAoZ2wsIHByb2dyYW0sIGRhdGEsIHBhcmFtcykgewotICAgICAgICAgICAgdmFyIGJ1ZmZlcjsKLQotICAgICAgICAgICAgLy8gRGVmaW5lIGF0dHJpYnV0ZXM6Ci0gICAgICAgICAgICB2YXIgcG9zaXRpb25Mb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sICdhX3Bvc2l0aW9uJyksCi0gICAgICAgICAgICAgICAgc2l6ZUxvY2F0aW9uID0KLSAgICAgICAgICAgICAgICAgICAgZ2wuZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbSwgJ2Ffc2l6ZScpLAotICAgICAgICAgICAgICAgIGNvbG9yTG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAnYV9jb2xvcicpLAotICAgICAgICAgICAgICAgIHJlc29sdXRpb25Mb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCAndV9yZXNvbHV0aW9uJyksCi0gICAgICAgICAgICAgICAgbWF0cml4TG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgJ3VfbWF0cml4JyksCi0gICAgICAgICAgICAgICAgcmF0aW9Mb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCAndV9yYXRpbycpLAotICAgICAgICAgICAgICAgIHNjYWxlTG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgJ3Vfc2NhbGUnKTsKLQotICAgICAgICAgICAgYnVmZmVyID0gZ2wuY3JlYXRlQnVmZmVyKCk7Ci0gICAgICAgICAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgYnVmZmVyKTsKLSAgICAgICAgICAgIGdsLmJ1ZmZlckRhdGEoZ2wuQVJSQVlfQlVGRkVSLCBkYXRhLCBnbC5EWU5BTUlDX0RSQVcpOwotCi0gICAgICAgICAgICBnbC51bmlmb3JtMmYocmVzb2x1dGlvbkxvY2F0aW9uLCBwYXJhbXMud2lkdGgsIHBhcmFtcy5oZWlnaHQpOwotICAgICAgICAgICAgZ2wudW5pZm9ybTFmKAotICAgICAgICAgICAgICAgIHJhdGlvTG9jYXRpb24sCi0gICAgICAgICAgICAgICAgMSAvIE1hdGgucG93KHBhcmFtcy5yYXRpbywgcGFyYW1zLnNldHRpbmdzKCdub2Rlc1Bvd1JhdGlvJykpCi0gICAgICAgICAgICApOwotICAgICAgICAgICAgZ2wudW5pZm9ybTFmKHNjYWxlTG9jYXRpb24sIHBhcmFtcy5zY2FsaW5nUmF0aW8pOwotICAgICAgICAgICAgZ2wudW5pZm9ybU1hdHJpeDNmdihtYXRyaXhMb2NhdGlvbiwgZmFsc2UsIHBhcmFtcy5tYXRyaXgpOwotCi0gICAgICAgICAgICBnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShwb3NpdGlvbkxvY2F0aW9uKTsKLSAgICAgICAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHNpemVMb2NhdGlvbik7Ci0gICAgICAgICAgICBnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShjb2xvckxvY2F0aW9uKTsKLQotICAgICAgICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcigKLSAgICAgICAgICAgICAgICBwb3NpdGlvbkxvY2F0aW9uLAotICAgICAgICAgICAgICAgIDIsCi0gICAgICAgICAgICAgICAgZ2wuRkxPQVQsCi0gICAgICAgICAgICAgICAgZmFsc2UsCi0gICAgICAgICAgICAgICAgdGhpcy5BVFRSSUJVVEVTICogRmxvYXQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5ULAotICAgICAgICAgICAgICAgIDAKLSAgICAgICAgICAgICk7Ci0gICAgICAgICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKAotICAgICAgICAgICAgICAgIHNpemVMb2NhdGlvbiwKLSAgICAgICAgICAgICAgICAxLAotICAgICAgICAgICAgICAgIGdsLkZMT0FULAotICAgICAgICAgICAgICAgIGZhbHNlLAotICAgICAgICAgICAgICAgIHRoaXMuQVRUUklCVVRFUyAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCwKLSAgICAgICAgICAgICAgICA4Ci0gICAgICAgICAgICApOwotICAgICAgICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcigKLSAgICAgICAgICAgICAgICBjb2xvckxvY2F0aW9uLAotICAgICAgICAgICAgICAgIDEsCi0gICAgICAgICAgICAgICAgZ2wuRkxPQVQsCi0gICAgICAgICAgICAgICAgZmFsc2UsCi0gICAgICAgICAgICAgICAgdGhpcy5BVFRSSUJVVEVTICogRmxvYXQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5ULAotICAgICAgICAgICAgICAgIDEyCi0gICAgICAgICAgICApOwotCi0gICAgICAgICAgICBnbC5kcmF3QXJyYXlzKAotICAgICAgICAgICAgICAgIGdsLlBPSU5UUywKLSAgICAgICAgICAgICAgICBwYXJhbXMuc3RhcnQgfHwgMCwKLSAgICAgICAgICAgICAgICBwYXJhbXMuY291bnQgfHwgKGRhdGEubGVuZ3RoIC8gdGhpcy5BVFRSSUJVVEVTKQotICAgICAgICAgICAgKTsKLSAgICAgICAgfSwKLSAgICAgICAgaW5pdFByb2dyYW06IGZ1bmN0aW9uIChnbCkgewotICAgICAgICAgICAgdmFyIHZlcnRleFNoYWRlciwKLSAgICAgICAgICAgICAgICBmcmFnbWVudFNoYWRlciwKLSAgICAgICAgICAgICAgICBwcm9ncmFtOwotCi0gICAgICAgICAgICB2ZXJ0ZXhTaGFkZXIgPSBzaWdtYS51dGlscy5sb2FkU2hhZGVyKAotICAgICAgICAgICAgICAgIGdsLAotICAgICAgICAgICAgICAgIFsKLSAgICAgICAgICAgICAgICAgICAgJ2F0dHJpYnV0ZSB2ZWMyIGFfcG9zaXRpb247JywKLSAgICAgICAgICAgICAgICAgICAgJ2F0dHJpYnV0ZSBmbG9hdCBhX3NpemU7JywKLSAgICAgICAgICAgICAgICAgICAgJ2F0dHJpYnV0ZSBmbG9hdCBhX2NvbG9yOycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ3VuaWZvcm0gdmVjMiB1X3Jlc29sdXRpb247JywKLSAgICAgICAgICAgICAgICAgICAgJ3VuaWZvcm0gZmxvYXQgdV9yYXRpbzsnLAotICAgICAgICAgICAgICAgICAgICAndW5pZm9ybSBmbG9hdCB1X3NjYWxlOycsCi0gICAgICAgICAgICAgICAgICAgICd1bmlmb3JtIG1hdDMgdV9tYXRyaXg7JywKLQotICAgICAgICAgICAgICAgICAgICAndmFyeWluZyB2ZWM0IGNvbG9yOycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ3ZvaWQgbWFpbigpIHsnLAotICAgICAgICAgICAgICAgICAgICAvLyBTY2FsZSBmcm9tIFtbLTEgMV0gWy0xIDFdXSB0byB0aGUgY29udGFpbmVyOgotICAgICAgICAgICAgICAgICAgICAnZ2xfUG9zaXRpb24gPSB2ZWM0KCcsCi0gICAgICAgICAgICAgICAgICAgICcoKHVfbWF0cml4ICogdmVjMyhhX3Bvc2l0aW9uLCAxKSkueHkgLycsCi0gICAgICAgICAgICAgICAgICAgICd1X3Jlc29sdXRpb24gKiAyLjAgLSAxLjApICogdmVjMigxLCAtMSksJywKLSAgICAgICAgICAgICAgICAgICAgJzAsJywKLSAgICAgICAgICAgICAgICAgICAgJzEnLAotICAgICAgICAgICAgICAgICAgICAnKTsnLAotCi0gICAgICAgICAgICAgICAgICAgIC8vIE11bHRpcGx5IHRoZSBwb2ludCBzaXplIHR3aWNlOgotICAgICAgICAgICAgICAgICAgICAvLyAgLSB4IFNDQUxJTkdfUkFUSU8gdG8gY29ycmVjdCB0aGUgY2FudmFzIHNjYWxpbmcKLSAgICAgICAgICAgICAgICAgICAgLy8gIC0geCAyIHRvIGNvcnJlY3QgdGhlIGZvcm11bGFlCi0gICAgICAgICAgICAgICAgICAgICdnbF9Qb2ludFNpemUgPSBhX3NpemUgKiB1X3JhdGlvICogdV9zY2FsZSAqIDIuMDsnLAotCi0gICAgICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgdGhlIGNvbG9yOgotICAgICAgICAgICAgICAgICAgICAnZmxvYXQgYyA9IGFfY29sb3I7JywKLSAgICAgICAgICAgICAgICAgICAgJ2NvbG9yLmIgPSBtb2QoYywgMjU2LjApOyBjID0gZmxvb3IoYyAvIDI1Ni4wKTsnLAotICAgICAgICAgICAgICAgICAgICAnY29sb3IuZyA9IG1vZChjLCAyNTYuMCk7IGMgPSBmbG9vcihjIC8gMjU2LjApOycsCi0gICAgICAgICAgICAgICAgICAgICdjb2xvci5yID0gbW9kKGMsIDI1Ni4wKTsgYyA9IGZsb29yKGMgLyAyNTYuMCk7IGNvbG9yIC89IDI1NS4wOycsCi0gICAgICAgICAgICAgICAgICAgICdjb2xvci5hID0gMS4wOycsCi0gICAgICAgICAgICAgICAgICAgICd9JwotICAgICAgICAgICAgICAgIF0uam9pbignXG4nKSwKLSAgICAgICAgICAgICAgICBnbC5WRVJURVhfU0hBREVSCi0gICAgICAgICAgICApOwotCi0gICAgICAgICAgICBmcmFnbWVudFNoYWRlciA9IHNpZ21hLnV0aWxzLmxvYWRTaGFkZXIoCi0gICAgICAgICAgICAgICAgZ2wsCi0gICAgICAgICAgICAgICAgWwotICAgICAgICAgICAgICAgICAgICAncHJlY2lzaW9uIG1lZGl1bXAgZmxvYXQ7JywKLQotICAgICAgICAgICAgICAgICAgICAndmFyeWluZyB2ZWM0IGNvbG9yOycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ3ZvaWQgbWFpbih2b2lkKSB7JywKLSAgICAgICAgICAgICAgICAgICAgJ2Zsb2F0IGJvcmRlciA9IDAuMDE7JywKLSAgICAgICAgICAgICAgICAgICAgJ2Zsb2F0IHJhZGl1cyA9IDAuNTsnLAotCi0gICAgICAgICAgICAgICAgICAgICd2ZWM0IGNvbG9yMCA9IHZlYzQoMC4wLCAwLjAsIDAuMCwgMC4wKTsnLAotICAgICAgICAgICAgICAgICAgICAndmVjMiBtID0gZ2xfUG9pbnRDb29yZCAtIHZlYzIoMC41LCAwLjUpOycsCi0gICAgICAgICAgICAgICAgICAgICdmbG9hdCBkaXN0ID0gcmFkaXVzIC0gc3FydChtLnggKiBtLnggKyBtLnkgKiBtLnkpOycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ2Zsb2F0IHQgPSAwLjA7JywKLSAgICAgICAgICAgICAgICAgICAgJ2lmIChkaXN0ID4gYm9yZGVyKScsCi0gICAgICAgICAgICAgICAgICAgICd0ID0gMS4wOycsCi0gICAgICAgICAgICAgICAgICAgICdlbHNlIGlmIChkaXN0ID4gMC4wKScsCi0gICAgICAgICAgICAgICAgICAgICd0ID0gZGlzdCAvIGJvcmRlcjsnLAotCi0gICAgICAgICAgICAgICAgICAgICdnbF9GcmFnQ29sb3IgPSBtaXgoY29sb3IwLCBjb2xvciwgdCk7JywKLSAgICAgICAgICAgICAgICAgICAgJ30nCi0gICAgICAgICAgICAgICAgXS5qb2luKCdcbicpLAotICAgICAgICAgICAgICAgIGdsLkZSQUdNRU5UX1NIQURFUgotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgcHJvZ3JhbSA9IHNpZ21hLnV0aWxzLmxvYWRQcm9ncmFtKGdsLCBbdmVydGV4U2hhZGVyLCBmcmFnbWVudFNoYWRlcl0pOwotCi0gICAgICAgICAgICByZXR1cm4gcHJvZ3JhbTsKLSAgICAgICAgfQotICAgIH07Ci19KSgpOwotCi07KGZ1bmN0aW9uICgpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLndlYmdsLmVkZ2VzJyk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGVkZ2UgcmVuZGVyZXIgd2lsbCBkaXNwbGF5IGVkZ2VzIGFzIGxpbmVzIGdvaW5nIGZyb20gdGhlIHNvdXJjZSBub2RlCi0gICAgICogdG8gdGhlIHRhcmdldCBub2RlLiBUbyBkZWFsIHdpdGggZWRnZSB0aGlja25lc3NlcywgdGhlIGxpbmVzIGFyZSBtYWRlIG9mCi0gICAgICogdHdvIHRyaWFuZ2xlcyBmb3JtaW5nIHJlY3RhbmdsZXMsIHdpdGggdGhlIGdsLlRSSUFOR0xFUyBkcmF3aW5nIG1vZGUuCi0gICAgICoKLSAgICAgKiBJdCBpcyBleHBlbnNpdmUsIHNpbmNlIGRyYXdpbmcgYSBzaW5nbGUgZWRnZSByZXF1aXJlcyA2IHBvaW50cywgZWFjaAotICAgICAqIGhhdmluZyA3IGF0dHJpYnV0ZXMgKHNvdXJjZSBwb3NpdGlvbiwgdGFyZ2V0IHBvc2l0aW9uLCB0aGlja25lc3MsIGNvbG9yCi0gICAgICogYW5kIGEgZmxhZyBpbmRpY2F0aW5nIHdoaWNoIHZlcnRpY2Ugb2YgdGhlIHJlY3RhbmdsZSBpdCBpcykuCi0gICAgICovCi0gICAgc2lnbWEud2ViZ2wuZWRnZXMuZGVmID0gewotICAgICAgICBQT0lOVFM6IDYsCi0gICAgICAgIEFUVFJJQlVURVM6IDcsCi0gICAgICAgIGFkZEVkZ2U6IGZ1bmN0aW9uIChlZGdlLCBzb3VyY2UsIHRhcmdldCwgZGF0YSwgaSwgcHJlZml4LCBzZXR0aW5ncykgewotICAgICAgICAgICAgdmFyIHcgPSAoZWRnZVtwcmVmaXggKyAnc2l6ZSddIHx8IDEpIC8gMiwKLSAgICAgICAgICAgICAgICB4MSA9IHNvdXJjZVtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgICAgIHkxID0gc291cmNlW3ByZWZpeCArICd5J10sCi0gICAgICAgICAgICAgICAgeDIgPSB0YXJnZXRbcHJlZml4ICsgJ3gnXSwKLSAgICAgICAgICAgICAgICB5MiA9IHRhcmdldFtwcmVmaXggKyAneSddLAotICAgICAgICAgICAgICAgIGNvbG9yID0gZWRnZS5jb2xvcjsKLQotICAgICAgICAgICAgaWYgKCFjb2xvcikKLSAgICAgICAgICAgICAgICBzd2l0Y2ggKHNldHRpbmdzKCdlZGdlQ29sb3InKSkgewotICAgICAgICAgICAgICAgICAgICBjYXNlICdzb3VyY2UnOgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBzb3VyY2UuY29sb3IgfHwgc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlICd0YXJnZXQnOgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSB0YXJnZXQuY29sb3IgfHwgc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBzZXR0aW5ncygnZGVmYXVsdEVkZ2VDb2xvcicpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBOb3JtYWxpemUgY29sb3I6Ci0gICAgICAgICAgICBjb2xvciA9IHNpZ21hLnV0aWxzLmZsb2F0Q29sb3IoY29sb3IpOwotCi0gICAgICAgICAgICBkYXRhW2krK10gPSB4MTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHkxOwotICAgICAgICAgICAgZGF0YVtpKytdID0geDI7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB5MjsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHc7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAwLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSBjb2xvcjsKLQotICAgICAgICAgICAgZGF0YVtpKytdID0geDI7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB5MjsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHgxOwotICAgICAgICAgICAgZGF0YVtpKytdID0geTE7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB3OwotICAgICAgICAgICAgZGF0YVtpKytdID0gMS4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gY29sb3I7Ci0KLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHgyOwotICAgICAgICAgICAgZGF0YVtpKytdID0geTI7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB4MTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHkxOwotICAgICAgICAgICAgZGF0YVtpKytdID0gdzsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IDAuMDsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IGNvbG9yOwotCi0gICAgICAgICAgICBkYXRhW2krK10gPSB4MjsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHkyOwotICAgICAgICAgICAgZGF0YVtpKytdID0geDE7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB5MTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHc7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAwLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSBjb2xvcjsKLQotICAgICAgICAgICAgZGF0YVtpKytdID0geDE7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB5MTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHgyOwotICAgICAgICAgICAgZGF0YVtpKytdID0geTI7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB3OwotICAgICAgICAgICAgZGF0YVtpKytdID0gMS4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gY29sb3I7Ci0KLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHgxOwotICAgICAgICAgICAgZGF0YVtpKytdID0geTE7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB4MjsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHkyOwotICAgICAgICAgICAgZGF0YVtpKytdID0gdzsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IDAuMDsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IGNvbG9yOwotICAgICAgICB9LAotICAgICAgICByZW5kZXI6IGZ1bmN0aW9uIChnbCwgcHJvZ3JhbSwgZGF0YSwgcGFyYW1zKSB7Ci0gICAgICAgICAgICB2YXIgYnVmZmVyOwotCi0gICAgICAgICAgICAvLyBEZWZpbmUgYXR0cmlidXRlczoKLSAgICAgICAgICAgIHZhciBjb2xvckxvY2F0aW9uID0KLSAgICAgICAgICAgICAgICAgICAgZ2wuZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbSwgJ2FfY29sb3InKSwKLSAgICAgICAgICAgICAgICBwb3NpdGlvbkxvY2F0aW9uMSA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sICdhX3Bvc2l0aW9uMScpLAotICAgICAgICAgICAgICAgIHBvc2l0aW9uTG9jYXRpb24yID0KLSAgICAgICAgICAgICAgICAgICAgZ2wuZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbSwgJ2FfcG9zaXRpb24yJyksCi0gICAgICAgICAgICAgICAgdGhpY2tuZXNzTG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAnYV90aGlja25lc3MnKSwKLSAgICAgICAgICAgICAgICBtaW51c0xvY2F0aW9uID0KLSAgICAgICAgICAgICAgICAgICAgZ2wuZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbSwgJ2FfbWludXMnKSwKLSAgICAgICAgICAgICAgICByZXNvbHV0aW9uTG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgJ3VfcmVzb2x1dGlvbicpLAotICAgICAgICAgICAgICAgIG1hdHJpeExvY2F0aW9uID0KLSAgICAgICAgICAgICAgICAgICAgZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sICd1X21hdHJpeCcpLAotICAgICAgICAgICAgICAgIG1hdHJpeEhhbGZQaUxvY2F0aW9uID0KLSAgICAgICAgICAgICAgICAgICAgZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sICd1X21hdHJpeEhhbGZQaScpLAotICAgICAgICAgICAgICAgIG1hdHJpeEhhbGZQaU1pbnVzTG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgJ3VfbWF0cml4SGFsZlBpTWludXMnKSwKLSAgICAgICAgICAgICAgICByYXRpb0xvY2F0aW9uID0KLSAgICAgICAgICAgICAgICAgICAgZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sICd1X3JhdGlvJyksCi0gICAgICAgICAgICAgICAgc2NhbGVMb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCAndV9zY2FsZScpOwotCi0gICAgICAgICAgICBidWZmZXIgPSBnbC5jcmVhdGVCdWZmZXIoKTsKLSAgICAgICAgICAgIGdsLmJpbmRCdWZmZXIoZ2wuQVJSQVlfQlVGRkVSLCBidWZmZXIpOwotICAgICAgICAgICAgZ2wuYnVmZmVyRGF0YShnbC5BUlJBWV9CVUZGRVIsIGRhdGEsIGdsLlNUQVRJQ19EUkFXKTsKLQotICAgICAgICAgICAgZ2wudW5pZm9ybTJmKHJlc29sdXRpb25Mb2NhdGlvbiwgcGFyYW1zLndpZHRoLCBwYXJhbXMuaGVpZ2h0KTsKLSAgICAgICAgICAgIGdsLnVuaWZvcm0xZigKLSAgICAgICAgICAgICAgICByYXRpb0xvY2F0aW9uLAotICAgICAgICAgICAgICAgIHBhcmFtcy5yYXRpbyAvIE1hdGgucG93KHBhcmFtcy5yYXRpbywgcGFyYW1zLnNldHRpbmdzKCdlZGdlc1Bvd1JhdGlvJykpCi0gICAgICAgICAgICApOwotICAgICAgICAgICAgZ2wudW5pZm9ybTFmKHNjYWxlTG9jYXRpb24sIHBhcmFtcy5zY2FsaW5nUmF0aW8pOwotICAgICAgICAgICAgZ2wudW5pZm9ybU1hdHJpeDNmdihtYXRyaXhMb2NhdGlvbiwgZmFsc2UsIHBhcmFtcy5tYXRyaXgpOwotICAgICAgICAgICAgZ2wudW5pZm9ybU1hdHJpeDJmdigKLSAgICAgICAgICAgICAgICBtYXRyaXhIYWxmUGlMb2NhdGlvbiwKLSAgICAgICAgICAgICAgICBmYWxzZSwKLSAgICAgICAgICAgICAgICBzaWdtYS51dGlscy5tYXRyaWNlcy5yb3RhdGlvbihNYXRoLlBJIC8gMiwgdHJ1ZSkKLSAgICAgICAgICAgICk7Ci0gICAgICAgICAgICBnbC51bmlmb3JtTWF0cml4MmZ2KAotICAgICAgICAgICAgICAgIG1hdHJpeEhhbGZQaU1pbnVzTG9jYXRpb24sCi0gICAgICAgICAgICAgICAgZmFsc2UsCi0gICAgICAgICAgICAgICAgc2lnbWEudXRpbHMubWF0cmljZXMucm90YXRpb24oLU1hdGguUEkgLyAyLCB0cnVlKQotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkoY29sb3JMb2NhdGlvbik7Ci0gICAgICAgICAgICBnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShwb3NpdGlvbkxvY2F0aW9uMSk7Ci0gICAgICAgICAgICBnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShwb3NpdGlvbkxvY2F0aW9uMik7Ci0gICAgICAgICAgICBnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheSh0aGlja25lc3NMb2NhdGlvbik7Ci0gICAgICAgICAgICBnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShtaW51c0xvY2F0aW9uKTsKLQotICAgICAgICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcihwb3NpdGlvbkxvY2F0aW9uMSwKLSAgICAgICAgICAgICAgICAyLAotICAgICAgICAgICAgICAgIGdsLkZMT0FULAotICAgICAgICAgICAgICAgIGZhbHNlLAotICAgICAgICAgICAgICAgIHRoaXMuQVRUUklCVVRFUyAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCwKLSAgICAgICAgICAgICAgICAwCi0gICAgICAgICAgICApOwotICAgICAgICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcihwb3NpdGlvbkxvY2F0aW9uMiwKLSAgICAgICAgICAgICAgICAyLAotICAgICAgICAgICAgICAgIGdsLkZMT0FULAotICAgICAgICAgICAgICAgIGZhbHNlLAotICAgICAgICAgICAgICAgIHRoaXMuQVRUUklCVVRFUyAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCwKLSAgICAgICAgICAgICAgICA4Ci0gICAgICAgICAgICApOwotICAgICAgICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcih0aGlja25lc3NMb2NhdGlvbiwKLSAgICAgICAgICAgICAgICAxLAotICAgICAgICAgICAgICAgIGdsLkZMT0FULAotICAgICAgICAgICAgICAgIGZhbHNlLAotICAgICAgICAgICAgICAgIHRoaXMuQVRUUklCVVRFUyAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCwKLSAgICAgICAgICAgICAgICAxNgotICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIobWludXNMb2NhdGlvbiwKLSAgICAgICAgICAgICAgICAxLAotICAgICAgICAgICAgICAgIGdsLkZMT0FULAotICAgICAgICAgICAgICAgIGZhbHNlLAotICAgICAgICAgICAgICAgIHRoaXMuQVRUUklCVVRFUyAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCwKLSAgICAgICAgICAgICAgICAyMAotICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIoY29sb3JMb2NhdGlvbiwKLSAgICAgICAgICAgICAgICAxLAotICAgICAgICAgICAgICAgIGdsLkZMT0FULAotICAgICAgICAgICAgICAgIGZhbHNlLAotICAgICAgICAgICAgICAgIHRoaXMuQVRUUklCVVRFUyAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCwKLSAgICAgICAgICAgICAgICAyNAotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgZ2wuZHJhd0FycmF5cygKLSAgICAgICAgICAgICAgICBnbC5UUklBTkdMRVMsCi0gICAgICAgICAgICAgICAgcGFyYW1zLnN0YXJ0IHx8IDAsCi0gICAgICAgICAgICAgICAgcGFyYW1zLmNvdW50IHx8IChkYXRhLmxlbmd0aCAvIHRoaXMuQVRUUklCVVRFUykKLSAgICAgICAgICAgICk7Ci0gICAgICAgIH0sCi0gICAgICAgIGluaXRQcm9ncmFtOiBmdW5jdGlvbiAoZ2wpIHsKLSAgICAgICAgICAgIHZhciB2ZXJ0ZXhTaGFkZXIsCi0gICAgICAgICAgICAgICAgZnJhZ21lbnRTaGFkZXIsCi0gICAgICAgICAgICAgICAgcHJvZ3JhbTsKLQotICAgICAgICAgICAgdmVydGV4U2hhZGVyID0gc2lnbWEudXRpbHMubG9hZFNoYWRlcigKLSAgICAgICAgICAgICAgICBnbCwKLSAgICAgICAgICAgICAgICBbCi0gICAgICAgICAgICAgICAgICAgICdhdHRyaWJ1dGUgdmVjMiBhX3Bvc2l0aW9uMTsnLAotICAgICAgICAgICAgICAgICAgICAnYXR0cmlidXRlIHZlYzIgYV9wb3NpdGlvbjI7JywKLSAgICAgICAgICAgICAgICAgICAgJ2F0dHJpYnV0ZSBmbG9hdCBhX3RoaWNrbmVzczsnLAotICAgICAgICAgICAgICAgICAgICAnYXR0cmlidXRlIGZsb2F0IGFfbWludXM7JywKLSAgICAgICAgICAgICAgICAgICAgJ2F0dHJpYnV0ZSBmbG9hdCBhX2NvbG9yOycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ3VuaWZvcm0gdmVjMiB1X3Jlc29sdXRpb247JywKLSAgICAgICAgICAgICAgICAgICAgJ3VuaWZvcm0gZmxvYXQgdV9yYXRpbzsnLAotICAgICAgICAgICAgICAgICAgICAndW5pZm9ybSBmbG9hdCB1X3NjYWxlOycsCi0gICAgICAgICAgICAgICAgICAgICd1bmlmb3JtIG1hdDMgdV9tYXRyaXg7JywKLSAgICAgICAgICAgICAgICAgICAgJ3VuaWZvcm0gbWF0MiB1X21hdHJpeEhhbGZQaTsnLAotICAgICAgICAgICAgICAgICAgICAndW5pZm9ybSBtYXQyIHVfbWF0cml4SGFsZlBpTWludXM7JywKLQotICAgICAgICAgICAgICAgICAgICAndmFyeWluZyB2ZWM0IGNvbG9yOycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ3ZvaWQgbWFpbigpIHsnLAotICAgICAgICAgICAgICAgICAgICAvLyBGaW5kIHRoZSBnb29kIHBvaW50OgotICAgICAgICAgICAgICAgICAgICAndmVjMiBwb3NpdGlvbiA9IGFfdGhpY2tuZXNzICogdV9yYXRpbyAqJywKLSAgICAgICAgICAgICAgICAgICAgJ25vcm1hbGl6ZShhX3Bvc2l0aW9uMiAtIGFfcG9zaXRpb24xKTsnLAotCi0gICAgICAgICAgICAgICAgICAgICdtYXQyIG1hdHJpeCA9IGFfbWludXMgKiB1X21hdHJpeEhhbGZQaU1pbnVzICsnLAotICAgICAgICAgICAgICAgICAgICAnKDEuMCAtIGFfbWludXMpICogdV9tYXRyaXhIYWxmUGk7JywKLQotICAgICAgICAgICAgICAgICAgICAncG9zaXRpb24gPSBtYXRyaXggKiBwb3NpdGlvbiArIGFfcG9zaXRpb24xOycsCi0KLSAgICAgICAgICAgICAgICAgICAgLy8gU2NhbGUgZnJvbSBbWy0xIDFdIFstMSAxXV0gdG8gdGhlIGNvbnRhaW5lcjoKLSAgICAgICAgICAgICAgICAgICAgJ2dsX1Bvc2l0aW9uID0gdmVjNCgnLAotICAgICAgICAgICAgICAgICAgICAnKCh1X21hdHJpeCAqIHZlYzMocG9zaXRpb24sIDEpKS54eSAvJywKLSAgICAgICAgICAgICAgICAgICAgJ3VfcmVzb2x1dGlvbiAqIDIuMCAtIDEuMCkgKiB2ZWMyKDEsIC0xKSwnLAotICAgICAgICAgICAgICAgICAgICAnMCwnLAotICAgICAgICAgICAgICAgICAgICAnMScsCi0gICAgICAgICAgICAgICAgICAgICcpOycsCi0KLSAgICAgICAgICAgICAgICAgICAgLy8gRXh0cmFjdCB0aGUgY29sb3I6Ci0gICAgICAgICAgICAgICAgICAgICdmbG9hdCBjID0gYV9jb2xvcjsnLAotICAgICAgICAgICAgICAgICAgICAnY29sb3IuYiA9IG1vZChjLCAyNTYuMCk7IGMgPSBmbG9vcihjIC8gMjU2LjApOycsCi0gICAgICAgICAgICAgICAgICAgICdjb2xvci5nID0gbW9kKGMsIDI1Ni4wKTsgYyA9IGZsb29yKGMgLyAyNTYuMCk7JywKLSAgICAgICAgICAgICAgICAgICAgJ2NvbG9yLnIgPSBtb2QoYywgMjU2LjApOyBjID0gZmxvb3IoYyAvIDI1Ni4wKTsgY29sb3IgLz0gMjU1LjA7JywKLSAgICAgICAgICAgICAgICAgICAgJ2NvbG9yLmEgPSAxLjA7JywKLSAgICAgICAgICAgICAgICAgICAgJ30nCi0gICAgICAgICAgICAgICAgXS5qb2luKCdcbicpLAotICAgICAgICAgICAgICAgIGdsLlZFUlRFWF9TSEFERVIKLSAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIGZyYWdtZW50U2hhZGVyID0gc2lnbWEudXRpbHMubG9hZFNoYWRlcigKLSAgICAgICAgICAgICAgICBnbCwKLSAgICAgICAgICAgICAgICBbCi0gICAgICAgICAgICAgICAgICAgICdwcmVjaXNpb24gbWVkaXVtcCBmbG9hdDsnLAotCi0gICAgICAgICAgICAgICAgICAgICd2YXJ5aW5nIHZlYzQgY29sb3I7JywKLQotICAgICAgICAgICAgICAgICAgICAndm9pZCBtYWluKHZvaWQpIHsnLAotICAgICAgICAgICAgICAgICAgICAnZ2xfRnJhZ0NvbG9yID0gY29sb3I7JywKLSAgICAgICAgICAgICAgICAgICAgJ30nCi0gICAgICAgICAgICAgICAgXS5qb2luKCdcbicpLAotICAgICAgICAgICAgICAgIGdsLkZSQUdNRU5UX1NIQURFUgotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgcHJvZ3JhbSA9IHNpZ21hLnV0aWxzLmxvYWRQcm9ncmFtKGdsLCBbdmVydGV4U2hhZGVyLCBmcmFnbWVudFNoYWRlcl0pOwotCi0gICAgICAgICAgICByZXR1cm4gcHJvZ3JhbTsKLSAgICAgICAgfQotICAgIH07Ci19KSgpOwotCi07KGZ1bmN0aW9uICgpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLndlYmdsLmVkZ2VzJyk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGVkZ2UgcmVuZGVyZXIgd2lsbCBkaXNwbGF5IGVkZ2VzIGFzIGxpbmVzIHdpdGggdGhlIGdsLkxJTkVTIGRpc3BsYXkKLSAgICAgKiBtb2RlLiBTaW5jZSB0aGlzIG1vZGUgZG9lcyBub3Qgc3VwcG9ydCB3ZWxsIHRoaWNrbmVzcywgZWRnZXMgYXJlIGFsbCBkcmF3bgotICAgICAqIHdpdGggdGhlIHNhbWUgdGhpY2tuZXNzICgzcHgpLCBpbmRlcGVuZGFudGx5IG9mIHRoZSBlZGdlIGF0dHJpYnV0ZXMgb3IgdGhlCi0gICAgICogem9vbWluZyByYXRpby4KLSAgICAgKi8KLSAgICBzaWdtYS53ZWJnbC5lZGdlcy5mYXN0ID0gewotICAgICAgICBQT0lOVFM6IDIsCi0gICAgICAgIEFUVFJJQlVURVM6IDMsCi0gICAgICAgIGFkZEVkZ2U6IGZ1bmN0aW9uIChlZGdlLCBzb3VyY2UsIHRhcmdldCwgZGF0YSwgaSwgcHJlZml4LCBzZXR0aW5ncykgewotICAgICAgICAgICAgdmFyIHcgPSAoZWRnZVtwcmVmaXggKyAnc2l6ZSddIHx8IDEpIC8gMiwKLSAgICAgICAgICAgICAgICB4MSA9IHNvdXJjZVtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgICAgIHkxID0gc291cmNlW3ByZWZpeCArICd5J10sCi0gICAgICAgICAgICAgICAgeDIgPSB0YXJnZXRbcHJlZml4ICsgJ3gnXSwKLSAgICAgICAgICAgICAgICB5MiA9IHRhcmdldFtwcmVmaXggKyAneSddLAotICAgICAgICAgICAgICAgIGNvbG9yID0gZWRnZS5jb2xvcjsKLQotICAgICAgICAgICAgaWYgKCFjb2xvcikKLSAgICAgICAgICAgICAgICBzd2l0Y2ggKHNldHRpbmdzKCdlZGdlQ29sb3InKSkgewotICAgICAgICAgICAgICAgICAgICBjYXNlICdzb3VyY2UnOgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBzb3VyY2UuY29sb3IgfHwgc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlICd0YXJnZXQnOgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSB0YXJnZXQuY29sb3IgfHwgc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBzZXR0aW5ncygnZGVmYXVsdEVkZ2VDb2xvcicpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBOb3JtYWxpemUgY29sb3I6Ci0gICAgICAgICAgICBjb2xvciA9IHNpZ21hLnV0aWxzLmZsb2F0Q29sb3IoY29sb3IpOwotCi0gICAgICAgICAgICBkYXRhW2krK10gPSB4MTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHkxOwotICAgICAgICAgICAgZGF0YVtpKytdID0gY29sb3I7Ci0KLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHgyOwotICAgICAgICAgICAgZGF0YVtpKytdID0geTI7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSBjb2xvcjsKLSAgICAgICAgfSwKLSAgICAgICAgcmVuZGVyOiBmdW5jdGlvbiAoZ2wsIHByb2dyYW0sIGRhdGEsIHBhcmFtcykgewotICAgICAgICAgICAgdmFyIGJ1ZmZlcjsKLQotICAgICAgICAgICAgLy8gRGVmaW5lIGF0dHJpYnV0ZXM6Ci0gICAgICAgICAgICB2YXIgY29sb3JMb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sICdhX2NvbG9yJyksCi0gICAgICAgICAgICAgICAgcG9zaXRpb25Mb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sICdhX3Bvc2l0aW9uJyksCi0gICAgICAgICAgICAgICAgcmVzb2x1dGlvbkxvY2F0aW9uID0KLSAgICAgICAgICAgICAgICAgICAgZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sICd1X3Jlc29sdXRpb24nKSwKLSAgICAgICAgICAgICAgICBtYXRyaXhMb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCAndV9tYXRyaXgnKTsKLQotICAgICAgICAgICAgYnVmZmVyID0gZ2wuY3JlYXRlQnVmZmVyKCk7Ci0gICAgICAgICAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgYnVmZmVyKTsKLSAgICAgICAgICAgIGdsLmJ1ZmZlckRhdGEoZ2wuQVJSQVlfQlVGRkVSLCBkYXRhLCBnbC5EWU5BTUlDX0RSQVcpOwotCi0gICAgICAgICAgICBnbC51bmlmb3JtMmYocmVzb2x1dGlvbkxvY2F0aW9uLCBwYXJhbXMud2lkdGgsIHBhcmFtcy5oZWlnaHQpOwotICAgICAgICAgICAgZ2wudW5pZm9ybU1hdHJpeDNmdihtYXRyaXhMb2NhdGlvbiwgZmFsc2UsIHBhcmFtcy5tYXRyaXgpOwotCi0gICAgICAgICAgICBnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShwb3NpdGlvbkxvY2F0aW9uKTsKLSAgICAgICAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KGNvbG9yTG9jYXRpb24pOwotCi0gICAgICAgICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHBvc2l0aW9uTG9jYXRpb24sCi0gICAgICAgICAgICAgICAgMiwKLSAgICAgICAgICAgICAgICBnbC5GTE9BVCwKLSAgICAgICAgICAgICAgICBmYWxzZSwKLSAgICAgICAgICAgICAgICB0aGlzLkFUVFJJQlVURVMgKiBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQsCi0gICAgICAgICAgICAgICAgMAotICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIoY29sb3JMb2NhdGlvbiwKLSAgICAgICAgICAgICAgICAxLAotICAgICAgICAgICAgICAgIGdsLkZMT0FULAotICAgICAgICAgICAgICAgIGZhbHNlLAotICAgICAgICAgICAgICAgIHRoaXMuQVRUUklCVVRFUyAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCwKLSAgICAgICAgICAgICAgICA4Ci0gICAgICAgICAgICApOwotCi0gICAgICAgICAgICBnbC5saW5lV2lkdGgoMyk7Ci0gICAgICAgICAgICBnbC5kcmF3QXJyYXlzKAotICAgICAgICAgICAgICAgIGdsLkxJTkVTLAotICAgICAgICAgICAgICAgIHBhcmFtcy5zdGFydCB8fCAwLAotICAgICAgICAgICAgICAgIHBhcmFtcy5jb3VudCB8fCAoZGF0YS5sZW5ndGggLyB0aGlzLkFUVFJJQlVURVMpCi0gICAgICAgICAgICApOwotICAgICAgICB9LAotICAgICAgICBpbml0UHJvZ3JhbTogZnVuY3Rpb24gKGdsKSB7Ci0gICAgICAgICAgICB2YXIgdmVydGV4U2hhZGVyLAotICAgICAgICAgICAgICAgIGZyYWdtZW50U2hhZGVyLAotICAgICAgICAgICAgICAgIHByb2dyYW07Ci0KLSAgICAgICAgICAgIHZlcnRleFNoYWRlciA9IHNpZ21hLnV0aWxzLmxvYWRTaGFkZXIoCi0gICAgICAgICAgICAgICAgZ2wsCi0gICAgICAgICAgICAgICAgWwotICAgICAgICAgICAgICAgICAgICAnYXR0cmlidXRlIHZlYzIgYV9wb3NpdGlvbjsnLAotICAgICAgICAgICAgICAgICAgICAnYXR0cmlidXRlIGZsb2F0IGFfY29sb3I7JywKLQotICAgICAgICAgICAgICAgICAgICAndW5pZm9ybSB2ZWMyIHVfcmVzb2x1dGlvbjsnLAotICAgICAgICAgICAgICAgICAgICAndW5pZm9ybSBtYXQzIHVfbWF0cml4OycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ3ZhcnlpbmcgdmVjNCBjb2xvcjsnLAotCi0gICAgICAgICAgICAgICAgICAgICd2b2lkIG1haW4oKSB7JywKLSAgICAgICAgICAgICAgICAgICAgLy8gU2NhbGUgZnJvbSBbWy0xIDFdIFstMSAxXV0gdG8gdGhlIGNvbnRhaW5lcjoKLSAgICAgICAgICAgICAgICAgICAgJ2dsX1Bvc2l0aW9uID0gdmVjNCgnLAotICAgICAgICAgICAgICAgICAgICAnKCh1X21hdHJpeCAqIHZlYzMoYV9wb3NpdGlvbiwgMSkpLnh5IC8nLAotICAgICAgICAgICAgICAgICAgICAndV9yZXNvbHV0aW9uICogMi4wIC0gMS4wKSAqIHZlYzIoMSwgLTEpLCcsCi0gICAgICAgICAgICAgICAgICAgICcwLCcsCi0gICAgICAgICAgICAgICAgICAgICcxJywKLSAgICAgICAgICAgICAgICAgICAgJyk7JywKLQotICAgICAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IHRoZSBjb2xvcjoKLSAgICAgICAgICAgICAgICAgICAgJ2Zsb2F0IGMgPSBhX2NvbG9yOycsCi0gICAgICAgICAgICAgICAgICAgICdjb2xvci5iID0gbW9kKGMsIDI1Ni4wKTsgYyA9IGZsb29yKGMgLyAyNTYuMCk7JywKLSAgICAgICAgICAgICAgICAgICAgJ2NvbG9yLmcgPSBtb2QoYywgMjU2LjApOyBjID0gZmxvb3IoYyAvIDI1Ni4wKTsnLAotICAgICAgICAgICAgICAgICAgICAnY29sb3IuciA9IG1vZChjLCAyNTYuMCk7IGMgPSBmbG9vcihjIC8gMjU2LjApOyBjb2xvciAvPSAyNTUuMDsnLAotICAgICAgICAgICAgICAgICAgICAnY29sb3IuYSA9IDEuMDsnLAotICAgICAgICAgICAgICAgICAgICAnfScKLSAgICAgICAgICAgICAgICBdLmpvaW4oJ1xuJyksCi0gICAgICAgICAgICAgICAgZ2wuVkVSVEVYX1NIQURFUgotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgZnJhZ21lbnRTaGFkZXIgPSBzaWdtYS51dGlscy5sb2FkU2hhZGVyKAotICAgICAgICAgICAgICAgIGdsLAotICAgICAgICAgICAgICAgIFsKLSAgICAgICAgICAgICAgICAgICAgJ3ByZWNpc2lvbiBtZWRpdW1wIGZsb2F0OycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ3ZhcnlpbmcgdmVjNCBjb2xvcjsnLAotCi0gICAgICAgICAgICAgICAgICAgICd2b2lkIG1haW4odm9pZCkgeycsCi0gICAgICAgICAgICAgICAgICAgICdnbF9GcmFnQ29sb3IgPSBjb2xvcjsnLAotICAgICAgICAgICAgICAgICAgICAnfScKLSAgICAgICAgICAgICAgICBdLmpvaW4oJ1xuJyksCi0gICAgICAgICAgICAgICAgZ2wuRlJBR01FTlRfU0hBREVSCi0gICAgICAgICAgICApOwotCi0gICAgICAgICAgICBwcm9ncmFtID0gc2lnbWEudXRpbHMubG9hZFByb2dyYW0oZ2wsIFt2ZXJ0ZXhTaGFkZXIsIGZyYWdtZW50U2hhZGVyXSk7Ci0KLSAgICAgICAgICAgIHJldHVybiBwcm9ncmFtOwotICAgICAgICB9Ci0gICAgfTsKLX0pKCk7Ci0KLTsoZnVuY3Rpb24gKCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIHNpZ21hLnV0aWxzLnBrZygnc2lnbWEud2ViZ2wuZWRnZXMnKTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgZWRnZSByZW5kZXJlciB3aWxsIGRpc3BsYXkgZWRnZXMgYXMgYXJyb3dzIGdvaW5nIGZyb20gdGhlIHNvdXJjZSBub2RlCi0gICAgICogdG8gdGhlIHRhcmdldCBub2RlLiBUbyBkZWFsIHdpdGggZWRnZSB0aGlja25lc3NlcywgdGhlIGxpbmVzIGFyZSBtYWRlIG9mCi0gICAgICogdGhyZWUgdHJpYW5nbGVzOiB0d28gZm9ybWluZyByZWN0YW5nbGVzLCB3aXRoIHRoZSBnbC5UUklBTkdMRVMgZHJhd2luZwotICAgICAqIG1vZGUuCi0gICAgICoKLSAgICAgKiBJdCBpcyBleHBlbnNpdmUsIHNpbmNlIGRyYXdpbmcgYSBzaW5nbGUgZWRnZSByZXF1aXJlcyA5IHBvaW50cywgZWFjaAotICAgICAqIGhhdmluZyBhIGxvdCBvZiBhdHRyaWJ1dGVzLgotICAgICAqLwotICAgIHNpZ21hLndlYmdsLmVkZ2VzLmFycm93ID0gewotICAgICAgICBQT0lOVFM6IDksCi0gICAgICAgIEFUVFJJQlVURVM6IDExLAotICAgICAgICBhZGRFZGdlOiBmdW5jdGlvbiAoZWRnZSwgc291cmNlLCB0YXJnZXQsIGRhdGEsIGksIHByZWZpeCwgc2V0dGluZ3MpIHsKLSAgICAgICAgICAgIHZhciB3ID0gKGVkZ2VbcHJlZml4ICsgJ3NpemUnXSB8fCAxKSAvIDIsCi0gICAgICAgICAgICAgICAgeDEgPSBzb3VyY2VbcHJlZml4ICsgJ3gnXSwKLSAgICAgICAgICAgICAgICB5MSA9IHNvdXJjZVtwcmVmaXggKyAneSddLAotICAgICAgICAgICAgICAgIHgyID0gdGFyZ2V0W3ByZWZpeCArICd4J10sCi0gICAgICAgICAgICAgICAgeTIgPSB0YXJnZXRbcHJlZml4ICsgJ3knXSwKLSAgICAgICAgICAgICAgICB0YXJnZXRTaXplID0gdGFyZ2V0W3ByZWZpeCArICdzaXplJ10sCi0gICAgICAgICAgICAgICAgY29sb3IgPSBlZGdlLmNvbG9yOwotCi0gICAgICAgICAgICBpZiAoIWNvbG9yKQotICAgICAgICAgICAgICAgIHN3aXRjaCAoc2V0dGluZ3MoJ2VkZ2VDb2xvcicpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3NvdXJjZSc6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IHNvdXJjZS5jb2xvciB8fCBzZXR0aW5ncygnZGVmYXVsdE5vZGVDb2xvcicpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3RhcmdldCc6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IHRhcmdldC5jb2xvciB8fCBzZXR0aW5ncygnZGVmYXVsdE5vZGVDb2xvcicpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IHNldHRpbmdzKCdkZWZhdWx0RWRnZUNvbG9yJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIE5vcm1hbGl6ZSBjb2xvcjoKLSAgICAgICAgICAgIGNvbG9yID0gc2lnbWEudXRpbHMuZmxvYXRDb2xvcihjb2xvcik7Ci0KLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHgxOwotICAgICAgICAgICAgZGF0YVtpKytdID0geTE7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB4MjsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHkyOwotICAgICAgICAgICAgZGF0YVtpKytdID0gdzsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHRhcmdldFNpemU7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAwLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAwLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAwLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAwLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSBjb2xvcjsKLQotICAgICAgICAgICAgZGF0YVtpKytdID0geDI7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB5MjsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHgxOwotICAgICAgICAgICAgZGF0YVtpKytdID0geTE7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB3OwotICAgICAgICAgICAgZGF0YVtpKytdID0gdGFyZ2V0U2l6ZTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IDEuMDsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IDEuMDsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IDAuMDsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IDAuMDsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IGNvbG9yOwotCi0gICAgICAgICAgICBkYXRhW2krK10gPSB4MjsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHkyOwotICAgICAgICAgICAgZGF0YVtpKytdID0geDE7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB5MTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHc7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB0YXJnZXRTaXplOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMS4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMC4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMC4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMC4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gY29sb3I7Ci0KLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHgyOwotICAgICAgICAgICAgZGF0YVtpKytdID0geTI7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB4MTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHkxOwotICAgICAgICAgICAgZGF0YVtpKytdID0gdzsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHRhcmdldFNpemU7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAxLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAwLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAwLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAwLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSBjb2xvcjsKLQotICAgICAgICAgICAgZGF0YVtpKytdID0geDE7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB5MTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHgyOwotICAgICAgICAgICAgZGF0YVtpKytdID0geTI7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB3OwotICAgICAgICAgICAgZGF0YVtpKytdID0gdGFyZ2V0U2l6ZTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IDAuMDsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IDEuMDsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IDAuMDsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IDAuMDsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IGNvbG9yOwotCi0gICAgICAgICAgICBkYXRhW2krK10gPSB4MTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHkxOwotICAgICAgICAgICAgZGF0YVtpKytdID0geDI7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB5MjsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHc7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB0YXJnZXRTaXplOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMC4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMC4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMC4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMC4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gY29sb3I7Ci0KLSAgICAgICAgICAgIC8vIEFycm93IGhlYWQ6Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB4MjsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHkyOwotICAgICAgICAgICAgZGF0YVtpKytdID0geDE7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB5MTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHc7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB0YXJnZXRTaXplOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMS4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMC4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMS4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gLTEuMDsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IGNvbG9yOwotCi0gICAgICAgICAgICBkYXRhW2krK10gPSB4MjsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHkyOwotICAgICAgICAgICAgZGF0YVtpKytdID0geDE7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB5MTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHc7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB0YXJnZXRTaXplOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMS4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMC4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMS4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gMC4wOwotICAgICAgICAgICAgZGF0YVtpKytdID0gY29sb3I7Ci0KLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHgyOwotICAgICAgICAgICAgZGF0YVtpKytdID0geTI7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSB4MTsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHkxOwotICAgICAgICAgICAgZGF0YVtpKytdID0gdzsKLSAgICAgICAgICAgIGRhdGFbaSsrXSA9IHRhcmdldFNpemU7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAxLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAwLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAxLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSAxLjA7Ci0gICAgICAgICAgICBkYXRhW2krK10gPSBjb2xvcjsKLSAgICAgICAgfSwKLSAgICAgICAgcmVuZGVyOiBmdW5jdGlvbiAoZ2wsIHByb2dyYW0sIGRhdGEsIHBhcmFtcykgewotICAgICAgICAgICAgdmFyIGJ1ZmZlcjsKLQotICAgICAgICAgICAgLy8gRGVmaW5lIGF0dHJpYnV0ZXM6Ci0gICAgICAgICAgICB2YXIgcG9zaXRpb25Mb2NhdGlvbjEgPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAnYV9wb3MxJyksCi0gICAgICAgICAgICAgICAgcG9zaXRpb25Mb2NhdGlvbjIgPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAnYV9wb3MyJyksCi0gICAgICAgICAgICAgICAgdGhpY2tuZXNzTG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAnYV90aGlja25lc3MnKSwKLSAgICAgICAgICAgICAgICB0YXJnZXRTaXplTG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAnYV90U2l6ZScpLAotICAgICAgICAgICAgICAgIGRlbGF5TG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAnYV9kZWxheScpLAotICAgICAgICAgICAgICAgIG1pbnVzTG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAnYV9taW51cycpLAotICAgICAgICAgICAgICAgIGhlYWRMb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sICdhX2hlYWQnKSwKLSAgICAgICAgICAgICAgICBoZWFkUG9zaXRpb25Mb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sICdhX2hlYWRQb3NpdGlvbicpLAotICAgICAgICAgICAgICAgIGNvbG9yTG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAnYV9jb2xvcicpLAotICAgICAgICAgICAgICAgIHJlc29sdXRpb25Mb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCAndV9yZXNvbHV0aW9uJyksCi0gICAgICAgICAgICAgICAgbWF0cml4TG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgJ3VfbWF0cml4JyksCi0gICAgICAgICAgICAgICAgbWF0cml4SGFsZlBpTG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgJ3VfbWF0cml4SGFsZlBpJyksCi0gICAgICAgICAgICAgICAgbWF0cml4SGFsZlBpTWludXNMb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCAndV9tYXRyaXhIYWxmUGlNaW51cycpLAotICAgICAgICAgICAgICAgIHJhdGlvTG9jYXRpb24gPQotICAgICAgICAgICAgICAgICAgICBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgJ3VfcmF0aW8nKSwKLSAgICAgICAgICAgICAgICBub2RlUmF0aW9Mb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCAndV9ub2RlUmF0aW8nKSwKLSAgICAgICAgICAgICAgICBhcnJvd0hlYWRMb2NhdGlvbiA9Ci0gICAgICAgICAgICAgICAgICAgIGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCAndV9hcnJvd0hlYWQnKSwKLSAgICAgICAgICAgICAgICBzY2FsZUxvY2F0aW9uID0KLSAgICAgICAgICAgICAgICAgICAgZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sICd1X3NjYWxlJyk7Ci0KLSAgICAgICAgICAgIGJ1ZmZlciA9IGdsLmNyZWF0ZUJ1ZmZlcigpOwotICAgICAgICAgICAgZ2wuYmluZEJ1ZmZlcihnbC5BUlJBWV9CVUZGRVIsIGJ1ZmZlcik7Ci0gICAgICAgICAgICBnbC5idWZmZXJEYXRhKGdsLkFSUkFZX0JVRkZFUiwgZGF0YSwgZ2wuU1RBVElDX0RSQVcpOwotCi0gICAgICAgICAgICBnbC51bmlmb3JtMmYocmVzb2x1dGlvbkxvY2F0aW9uLCBwYXJhbXMud2lkdGgsIHBhcmFtcy5oZWlnaHQpOwotICAgICAgICAgICAgZ2wudW5pZm9ybTFmKAotICAgICAgICAgICAgICAgIHJhdGlvTG9jYXRpb24sCi0gICAgICAgICAgICAgICAgcGFyYW1zLnJhdGlvIC8gTWF0aC5wb3cocGFyYW1zLnJhdGlvLCBwYXJhbXMuc2V0dGluZ3MoJ2VkZ2VzUG93UmF0aW8nKSkKLSAgICAgICAgICAgICk7Ci0gICAgICAgICAgICBnbC51bmlmb3JtMWYoCi0gICAgICAgICAgICAgICAgbm9kZVJhdGlvTG9jYXRpb24sCi0gICAgICAgICAgICAgICAgTWF0aC5wb3cocGFyYW1zLnJhdGlvLCBwYXJhbXMuc2V0dGluZ3MoJ25vZGVzUG93UmF0aW8nKSkgLwotICAgICAgICAgICAgICAgIHBhcmFtcy5yYXRpbwotICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIGdsLnVuaWZvcm0xZihhcnJvd0hlYWRMb2NhdGlvbiwgNS4wKTsKLSAgICAgICAgICAgIGdsLnVuaWZvcm0xZihzY2FsZUxvY2F0aW9uLCBwYXJhbXMuc2NhbGluZ1JhdGlvKTsKLSAgICAgICAgICAgIGdsLnVuaWZvcm1NYXRyaXgzZnYobWF0cml4TG9jYXRpb24sIGZhbHNlLCBwYXJhbXMubWF0cml4KTsKLSAgICAgICAgICAgIGdsLnVuaWZvcm1NYXRyaXgyZnYoCi0gICAgICAgICAgICAgICAgbWF0cml4SGFsZlBpTG9jYXRpb24sCi0gICAgICAgICAgICAgICAgZmFsc2UsCi0gICAgICAgICAgICAgICAgc2lnbWEudXRpbHMubWF0cmljZXMucm90YXRpb24oTWF0aC5QSSAvIDIsIHRydWUpCi0gICAgICAgICAgICApOwotICAgICAgICAgICAgZ2wudW5pZm9ybU1hdHJpeDJmdigKLSAgICAgICAgICAgICAgICBtYXRyaXhIYWxmUGlNaW51c0xvY2F0aW9uLAotICAgICAgICAgICAgICAgIGZhbHNlLAotICAgICAgICAgICAgICAgIHNpZ21hLnV0aWxzLm1hdHJpY2VzLnJvdGF0aW9uKC1NYXRoLlBJIC8gMiwgdHJ1ZSkKLSAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHBvc2l0aW9uTG9jYXRpb24xKTsKLSAgICAgICAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHBvc2l0aW9uTG9jYXRpb24yKTsKLSAgICAgICAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHRoaWNrbmVzc0xvY2F0aW9uKTsKLSAgICAgICAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHRhcmdldFNpemVMb2NhdGlvbik7Ci0gICAgICAgICAgICBnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShkZWxheUxvY2F0aW9uKTsKLSAgICAgICAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KG1pbnVzTG9jYXRpb24pOwotICAgICAgICAgICAgZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkoaGVhZExvY2F0aW9uKTsKLSAgICAgICAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KGhlYWRQb3NpdGlvbkxvY2F0aW9uKTsKLSAgICAgICAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KGNvbG9yTG9jYXRpb24pOwotCi0gICAgICAgICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHBvc2l0aW9uTG9jYXRpb24xLAotICAgICAgICAgICAgICAgIDIsCi0gICAgICAgICAgICAgICAgZ2wuRkxPQVQsCi0gICAgICAgICAgICAgICAgZmFsc2UsCi0gICAgICAgICAgICAgICAgdGhpcy5BVFRSSUJVVEVTICogRmxvYXQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5ULAotICAgICAgICAgICAgICAgIDAKLSAgICAgICAgICAgICk7Ci0gICAgICAgICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHBvc2l0aW9uTG9jYXRpb24yLAotICAgICAgICAgICAgICAgIDIsCi0gICAgICAgICAgICAgICAgZ2wuRkxPQVQsCi0gICAgICAgICAgICAgICAgZmFsc2UsCi0gICAgICAgICAgICAgICAgdGhpcy5BVFRSSUJVVEVTICogRmxvYXQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5ULAotICAgICAgICAgICAgICAgIDgKLSAgICAgICAgICAgICk7Ci0gICAgICAgICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHRoaWNrbmVzc0xvY2F0aW9uLAotICAgICAgICAgICAgICAgIDEsCi0gICAgICAgICAgICAgICAgZ2wuRkxPQVQsCi0gICAgICAgICAgICAgICAgZmFsc2UsCi0gICAgICAgICAgICAgICAgdGhpcy5BVFRSSUJVVEVTICogRmxvYXQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5ULAotICAgICAgICAgICAgICAgIDE2Ci0gICAgICAgICAgICApOwotICAgICAgICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcih0YXJnZXRTaXplTG9jYXRpb24sCi0gICAgICAgICAgICAgICAgMSwKLSAgICAgICAgICAgICAgICBnbC5GTE9BVCwKLSAgICAgICAgICAgICAgICBmYWxzZSwKLSAgICAgICAgICAgICAgICB0aGlzLkFUVFJJQlVURVMgKiBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQsCi0gICAgICAgICAgICAgICAgMjAKLSAgICAgICAgICAgICk7Ci0gICAgICAgICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKGRlbGF5TG9jYXRpb24sCi0gICAgICAgICAgICAgICAgMSwKLSAgICAgICAgICAgICAgICBnbC5GTE9BVCwKLSAgICAgICAgICAgICAgICBmYWxzZSwKLSAgICAgICAgICAgICAgICB0aGlzLkFUVFJJQlVURVMgKiBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQsCi0gICAgICAgICAgICAgICAgMjQKLSAgICAgICAgICAgICk7Ci0gICAgICAgICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKG1pbnVzTG9jYXRpb24sCi0gICAgICAgICAgICAgICAgMSwKLSAgICAgICAgICAgICAgICBnbC5GTE9BVCwKLSAgICAgICAgICAgICAgICBmYWxzZSwKLSAgICAgICAgICAgICAgICB0aGlzLkFUVFJJQlVURVMgKiBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQsCi0gICAgICAgICAgICAgICAgMjgKLSAgICAgICAgICAgICk7Ci0gICAgICAgICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKGhlYWRMb2NhdGlvbiwKLSAgICAgICAgICAgICAgICAxLAotICAgICAgICAgICAgICAgIGdsLkZMT0FULAotICAgICAgICAgICAgICAgIGZhbHNlLAotICAgICAgICAgICAgICAgIHRoaXMuQVRUUklCVVRFUyAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCwKLSAgICAgICAgICAgICAgICAzMgotICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIoaGVhZFBvc2l0aW9uTG9jYXRpb24sCi0gICAgICAgICAgICAgICAgMSwKLSAgICAgICAgICAgICAgICBnbC5GTE9BVCwKLSAgICAgICAgICAgICAgICBmYWxzZSwKLSAgICAgICAgICAgICAgICB0aGlzLkFUVFJJQlVURVMgKiBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQsCi0gICAgICAgICAgICAgICAgMzYKLSAgICAgICAgICAgICk7Ci0gICAgICAgICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKGNvbG9yTG9jYXRpb24sCi0gICAgICAgICAgICAgICAgMSwKLSAgICAgICAgICAgICAgICBnbC5GTE9BVCwKLSAgICAgICAgICAgICAgICBmYWxzZSwKLSAgICAgICAgICAgICAgICB0aGlzLkFUVFJJQlVURVMgKiBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQsCi0gICAgICAgICAgICAgICAgNDAKLSAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIGdsLmRyYXdBcnJheXMoCi0gICAgICAgICAgICAgICAgZ2wuVFJJQU5HTEVTLAotICAgICAgICAgICAgICAgIHBhcmFtcy5zdGFydCB8fCAwLAotICAgICAgICAgICAgICAgIHBhcmFtcy5jb3VudCB8fCAoZGF0YS5sZW5ndGggLyB0aGlzLkFUVFJJQlVURVMpCi0gICAgICAgICAgICApOwotICAgICAgICB9LAotICAgICAgICBpbml0UHJvZ3JhbTogZnVuY3Rpb24gKGdsKSB7Ci0gICAgICAgICAgICB2YXIgdmVydGV4U2hhZGVyLAotICAgICAgICAgICAgICAgIGZyYWdtZW50U2hhZGVyLAotICAgICAgICAgICAgICAgIHByb2dyYW07Ci0KLSAgICAgICAgICAgIHZlcnRleFNoYWRlciA9IHNpZ21hLnV0aWxzLmxvYWRTaGFkZXIoCi0gICAgICAgICAgICAgICAgZ2wsCi0gICAgICAgICAgICAgICAgWwotICAgICAgICAgICAgICAgICAgICAnYXR0cmlidXRlIHZlYzIgYV9wb3MxOycsCi0gICAgICAgICAgICAgICAgICAgICdhdHRyaWJ1dGUgdmVjMiBhX3BvczI7JywKLSAgICAgICAgICAgICAgICAgICAgJ2F0dHJpYnV0ZSBmbG9hdCBhX3RoaWNrbmVzczsnLAotICAgICAgICAgICAgICAgICAgICAnYXR0cmlidXRlIGZsb2F0IGFfdFNpemU7JywKLSAgICAgICAgICAgICAgICAgICAgJ2F0dHJpYnV0ZSBmbG9hdCBhX2RlbGF5OycsCi0gICAgICAgICAgICAgICAgICAgICdhdHRyaWJ1dGUgZmxvYXQgYV9taW51czsnLAotICAgICAgICAgICAgICAgICAgICAnYXR0cmlidXRlIGZsb2F0IGFfaGVhZDsnLAotICAgICAgICAgICAgICAgICAgICAnYXR0cmlidXRlIGZsb2F0IGFfaGVhZFBvc2l0aW9uOycsCi0gICAgICAgICAgICAgICAgICAgICdhdHRyaWJ1dGUgZmxvYXQgYV9jb2xvcjsnLAotCi0gICAgICAgICAgICAgICAgICAgICd1bmlmb3JtIHZlYzIgdV9yZXNvbHV0aW9uOycsCi0gICAgICAgICAgICAgICAgICAgICd1bmlmb3JtIGZsb2F0IHVfcmF0aW87JywKLSAgICAgICAgICAgICAgICAgICAgJ3VuaWZvcm0gZmxvYXQgdV9ub2RlUmF0aW87JywKLSAgICAgICAgICAgICAgICAgICAgJ3VuaWZvcm0gZmxvYXQgdV9hcnJvd0hlYWQ7JywKLSAgICAgICAgICAgICAgICAgICAgJ3VuaWZvcm0gZmxvYXQgdV9zY2FsZTsnLAotICAgICAgICAgICAgICAgICAgICAndW5pZm9ybSBtYXQzIHVfbWF0cml4OycsCi0gICAgICAgICAgICAgICAgICAgICd1bmlmb3JtIG1hdDIgdV9tYXRyaXhIYWxmUGk7JywKLSAgICAgICAgICAgICAgICAgICAgJ3VuaWZvcm0gbWF0MiB1X21hdHJpeEhhbGZQaU1pbnVzOycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ3ZhcnlpbmcgdmVjNCBjb2xvcjsnLAotCi0gICAgICAgICAgICAgICAgICAgICd2b2lkIG1haW4oKSB7JywKLSAgICAgICAgICAgICAgICAgICAgLy8gRmluZCB0aGUgZ29vZCBwb2ludDoKLSAgICAgICAgICAgICAgICAgICAgJ3ZlYzIgcG9zID0gbm9ybWFsaXplKGFfcG9zMiAtIGFfcG9zMSk7JywKLQotICAgICAgICAgICAgICAgICAgICAnbWF0MiBtYXRyaXggPSAoMS4wIC0gYV9oZWFkKSAqJywKLSAgICAgICAgICAgICAgICAgICAgJygnLAotICAgICAgICAgICAgICAgICAgICAnYV9taW51cyAqIHVfbWF0cml4SGFsZlBpTWludXMgKycsCi0gICAgICAgICAgICAgICAgICAgICcoMS4wIC0gYV9taW51cykgKiB1X21hdHJpeEhhbGZQaScsCi0gICAgICAgICAgICAgICAgICAgICcpICsgYV9oZWFkICogKCcsCi0gICAgICAgICAgICAgICAgICAgICdhX2hlYWRQb3NpdGlvbiAqIHVfbWF0cml4SGFsZlBpTWludXMgKiAwLjYgKycsCi0gICAgICAgICAgICAgICAgICAgICcoYV9oZWFkUG9zaXRpb24gKiBhX2hlYWRQb3NpdGlvbiAtIDEuMCkgKiBtYXQyKDEuMCknLAotICAgICAgICAgICAgICAgICAgICAnKTsnLAotCi0gICAgICAgICAgICAgICAgICAgICdwb3MgPSBhX3BvczEgKyAoJywKLSAgICAgICAgICAgICAgICAgICAgLy8gRGVhbCB3aXRoIGJvZHk6Ci0gICAgICAgICAgICAgICAgICAgICcoMS4wIC0gYV9oZWFkKSAqIGFfdGhpY2tuZXNzICogdV9yYXRpbyAqIG1hdHJpeCAqIHBvcyArJywKLSAgICAgICAgICAgICAgICAgICAgLy8gRGVhbCB3aXRoIGhlYWQ6Ci0gICAgICAgICAgICAgICAgICAgICdhX2hlYWQgKiB1X2Fycm93SGVhZCAqIGFfdGhpY2tuZXNzICogdV9yYXRpbyAqIG1hdHJpeCAqIHBvcyArJywKLSAgICAgICAgICAgICAgICAgICAgLy8gRGVhbCB3aXRoIGRlbGF5OgotICAgICAgICAgICAgICAgICAgICAnYV9kZWxheSAqIHBvcyAqICgnLAotICAgICAgICAgICAgICAgICAgICAnYV90U2l6ZSAvIHVfbm9kZVJhdGlvICsnLAotICAgICAgICAgICAgICAgICAgICAndV9hcnJvd0hlYWQgKiBhX3RoaWNrbmVzcyAqIHVfcmF0aW8nLAotICAgICAgICAgICAgICAgICAgICAnKScsCi0gICAgICAgICAgICAgICAgICAgICcpOycsCi0KLSAgICAgICAgICAgICAgICAgICAgLy8gU2NhbGUgZnJvbSBbWy0xIDFdIFstMSAxXV0gdG8gdGhlIGNvbnRhaW5lcjoKLSAgICAgICAgICAgICAgICAgICAgJ2dsX1Bvc2l0aW9uID0gdmVjNCgnLAotICAgICAgICAgICAgICAgICAgICAnKCh1X21hdHJpeCAqIHZlYzMocG9zLCAxKSkueHkgLycsCi0gICAgICAgICAgICAgICAgICAgICd1X3Jlc29sdXRpb24gKiAyLjAgLSAxLjApICogdmVjMigxLCAtMSksJywKLSAgICAgICAgICAgICAgICAgICAgJzAsJywKLSAgICAgICAgICAgICAgICAgICAgJzEnLAotICAgICAgICAgICAgICAgICAgICAnKTsnLAotCi0gICAgICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgdGhlIGNvbG9yOgotICAgICAgICAgICAgICAgICAgICAnZmxvYXQgYyA9IGFfY29sb3I7JywKLSAgICAgICAgICAgICAgICAgICAgJ2NvbG9yLmIgPSBtb2QoYywgMjU2LjApOyBjID0gZmxvb3IoYyAvIDI1Ni4wKTsnLAotICAgICAgICAgICAgICAgICAgICAnY29sb3IuZyA9IG1vZChjLCAyNTYuMCk7IGMgPSBmbG9vcihjIC8gMjU2LjApOycsCi0gICAgICAgICAgICAgICAgICAgICdjb2xvci5yID0gbW9kKGMsIDI1Ni4wKTsgYyA9IGZsb29yKGMgLyAyNTYuMCk7IGNvbG9yIC89IDI1NS4wOycsCi0gICAgICAgICAgICAgICAgICAgICdjb2xvci5hID0gMS4wOycsCi0gICAgICAgICAgICAgICAgICAgICd9JwotICAgICAgICAgICAgICAgIF0uam9pbignXG4nKSwKLSAgICAgICAgICAgICAgICBnbC5WRVJURVhfU0hBREVSCi0gICAgICAgICAgICApOwotCi0gICAgICAgICAgICBmcmFnbWVudFNoYWRlciA9IHNpZ21hLnV0aWxzLmxvYWRTaGFkZXIoCi0gICAgICAgICAgICAgICAgZ2wsCi0gICAgICAgICAgICAgICAgWwotICAgICAgICAgICAgICAgICAgICAncHJlY2lzaW9uIG1lZGl1bXAgZmxvYXQ7JywKLQotICAgICAgICAgICAgICAgICAgICAndmFyeWluZyB2ZWM0IGNvbG9yOycsCi0KLSAgICAgICAgICAgICAgICAgICAgJ3ZvaWQgbWFpbih2b2lkKSB7JywKLSAgICAgICAgICAgICAgICAgICAgJ2dsX0ZyYWdDb2xvciA9IGNvbG9yOycsCi0gICAgICAgICAgICAgICAgICAgICd9JwotICAgICAgICAgICAgICAgIF0uam9pbignXG4nKSwKLSAgICAgICAgICAgICAgICBnbC5GUkFHTUVOVF9TSEFERVIKLSAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIHByb2dyYW0gPSBzaWdtYS51dGlscy5sb2FkUHJvZ3JhbShnbCwgW3ZlcnRleFNoYWRlciwgZnJhZ21lbnRTaGFkZXJdKTsKLQotICAgICAgICAgICAgcmV0dXJuIHByb2dyYW07Ci0gICAgICAgIH0KLSAgICB9OwotfSkoKTsKLQotOyhmdW5jdGlvbiAodW5kZWZpbmVkKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgaWYgKHR5cGVvZiBzaWdtYSA9PT0gJ3VuZGVmaW5lZCcpCi0gICAgICAgIHRocm93ICdzaWdtYSBpcyBub3QgZGVjbGFyZWQnOwotCi0gICAgLy8gSW5pdGlhbGl6ZSBwYWNrYWdlczoKLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLmNhbnZhcy5sYWJlbHMnKTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbGFiZWwgcmVuZGVyZXIgd2lsbCBqdXN0IGRpc3BsYXkgdGhlIGxhYmVsIG9uIHRoZSByaWdodCBvZiB0aGUgbm9kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgICAgbm9kZSAgICAgVGhlIG5vZGUgb2JqZWN0LgotICAgICAqIEBwYXJhbSAge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCAgVGhlIGNhbnZhcyBjb250ZXh0LgotICAgICAqIEBwYXJhbSAge2NvbmZpZ3VyYWJsZX0gICAgICAgICAgICAgc2V0dGluZ3MgVGhlIHNldHRpbmdzIGZ1bmN0aW9uLgotICAgICAqLwotICAgIHNpZ21hLmNhbnZhcy5sYWJlbHMuZGVmID0gZnVuY3Rpb24gKG5vZGUsIGNvbnRleHQsIHNldHRpbmdzKSB7Ci0gICAgICAgIHZhciBmb250U2l6ZSwKLSAgICAgICAgICAgIHByZWZpeCA9IHNldHRpbmdzKCdwcmVmaXgnKSB8fCAnJywKLSAgICAgICAgICAgIHNpemUgPSBub2RlW3ByZWZpeCArICdzaXplJ107Ci0KLSAgICAgICAgaWYgKHNpemUgPCBzZXR0aW5ncygnbGFiZWxUaHJlc2hvbGQnKSkKLSAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICBpZiAoIW5vZGUubGFiZWwgfHwgdHlwZW9mIG5vZGUubGFiZWwgIT09ICdzdHJpbmcnKQotICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgIGZvbnRTaXplID0gKHNldHRpbmdzKCdsYWJlbFNpemUnKSA9PT0gJ2ZpeGVkJykgPwotICAgICAgICAgICAgc2V0dGluZ3MoJ2RlZmF1bHRMYWJlbFNpemUnKSA6Ci0gICAgICAgIHNldHRpbmdzKCdsYWJlbFNpemVSYXRpbycpICogc2l6ZTsKLQotICAgICAgICBjb250ZXh0LmZvbnQgPSAoc2V0dGluZ3MoJ2ZvbnRTdHlsZScpID8gc2V0dGluZ3MoJ2ZvbnRTdHlsZScpICsgJyAnIDogJycpICsKLSAgICAgICAgICAgIGZvbnRTaXplICsgJ3B4ICcgKyBzZXR0aW5ncygnZm9udCcpOwotICAgICAgICBjb250ZXh0LmZpbGxTdHlsZSA9IChzZXR0aW5ncygnbGFiZWxDb2xvcicpID09PSAnbm9kZScpID8KLSAgICAgICAgICAgIChub2RlLmNvbG9yIHx8IHNldHRpbmdzKCdkZWZhdWx0Tm9kZUNvbG9yJykpIDoKLSAgICAgICAgICAgIHNldHRpbmdzKCdkZWZhdWx0TGFiZWxDb2xvcicpOwotCi0gICAgICAgIGNvbnRleHQuZmlsbFRleHQoCi0gICAgICAgICAgICBub2RlLmxhYmVsLAotICAgICAgICAgICAgTWF0aC5yb3VuZChub2RlW3ByZWZpeCArICd4J10gKyBzaXplICsgMyksCi0gICAgICAgICAgICBNYXRoLnJvdW5kKG5vZGVbcHJlZml4ICsgJ3knXSArIGZvbnRTaXplIC8gMykKLSAgICAgICAgKTsKLSAgICB9OwotfSkuY2FsbCh0aGlzKTsKLQotOyhmdW5jdGlvbiAodW5kZWZpbmVkKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgaWYgKHR5cGVvZiBzaWdtYSA9PT0gJ3VuZGVmaW5lZCcpCi0gICAgICAgIHRocm93ICdzaWdtYSBpcyBub3QgZGVjbGFyZWQnOwotCi0gICAgLy8gSW5pdGlhbGl6ZSBwYWNrYWdlczoKLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLmNhbnZhcy5ob3ZlcnMnKTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgaG92ZXIgcmVuZGVyZXIgd2lsbCBiYXNpY2FsbHkgZGlzcGxheSB0aGUgbGFiZWwgd2l0aCBhIGJhY2tncm91bmQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIG5vZGUgICAgIFRoZSBub2RlIG9iamVjdC4KLSAgICAgKiBAcGFyYW0gIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgIFRoZSBjYW52YXMgY29udGV4dC4KLSAgICAgKiBAcGFyYW0gIHtjb25maWd1cmFibGV9ICAgICAgICAgICAgIHNldHRpbmdzIFRoZSBzZXR0aW5ncyBmdW5jdGlvbi4KLSAgICAgKi8KLSAgICBzaWdtYS5jYW52YXMuaG92ZXJzLmRlZiA9IGZ1bmN0aW9uIChub2RlLCBjb250ZXh0LCBzZXR0aW5ncykgewotICAgICAgICB2YXIgeCwKLSAgICAgICAgICAgIHksCi0gICAgICAgICAgICB3LAotICAgICAgICAgICAgaCwKLSAgICAgICAgICAgIGUsCi0gICAgICAgICAgICBmb250U3R5bGUgPSBzZXR0aW5ncygnaG92ZXJGb250U3R5bGUnKSB8fCBzZXR0aW5ncygnZm9udFN0eWxlJyksCi0gICAgICAgICAgICBwcmVmaXggPSBzZXR0aW5ncygncHJlZml4JykgfHwgJycsCi0gICAgICAgICAgICBzaXplID0gbm9kZVtwcmVmaXggKyAnc2l6ZSddLAotICAgICAgICAgICAgZm9udFNpemUgPSAoc2V0dGluZ3MoJ2xhYmVsU2l6ZScpID09PSAnZml4ZWQnKSA/Ci0gICAgICAgICAgICAgICAgc2V0dGluZ3MoJ2RlZmF1bHRMYWJlbFNpemUnKSA6Ci0gICAgICAgICAgICBzZXR0aW5ncygnbGFiZWxTaXplUmF0aW8nKSAqIHNpemU7Ci0KLSAgICAgICAgLy8gTGFiZWwgYmFja2dyb3VuZDoKLSAgICAgICAgY29udGV4dC5mb250ID0gKGZvbnRTdHlsZSA/IGZvbnRTdHlsZSArICcgJyA6ICcnKSArCi0gICAgICAgICAgICBmb250U2l6ZSArICdweCAnICsgKHNldHRpbmdzKCdob3ZlckZvbnQnKSB8fCBzZXR0aW5ncygnZm9udCcpKTsKLQotICAgICAgICBjb250ZXh0LmJlZ2luUGF0aCgpOwotICAgICAgICBjb250ZXh0LmZpbGxTdHlsZSA9IHNldHRpbmdzKCdsYWJlbEhvdmVyQkdDb2xvcicpID09PSAnbm9kZScgPwotICAgICAgICAgICAgKG5vZGUuY29sb3IgfHwgc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKSkgOgotICAgICAgICAgICAgc2V0dGluZ3MoJ2RlZmF1bHRIb3ZlckxhYmVsQkdDb2xvcicpOwotCi0gICAgICAgIGlmIChub2RlLmxhYmVsICYmIHNldHRpbmdzKCdsYWJlbEhvdmVyU2hhZG93JykpIHsKLSAgICAgICAgICAgIGNvbnRleHQuc2hhZG93T2Zmc2V0WCA9IDA7Ci0gICAgICAgICAgICBjb250ZXh0LnNoYWRvd09mZnNldFkgPSAwOwotICAgICAgICAgICAgY29udGV4dC5zaGFkb3dCbHVyID0gODsKLSAgICAgICAgICAgIGNvbnRleHQuc2hhZG93Q29sb3IgPSBzZXR0aW5ncygnbGFiZWxIb3ZlclNoYWRvd0NvbG9yJyk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobm9kZS5sYWJlbCAmJiB0eXBlb2Ygbm9kZS5sYWJlbCA9PT0gJ3N0cmluZycpIHsKLSAgICAgICAgICAgIHggPSBNYXRoLnJvdW5kKG5vZGVbcHJlZml4ICsgJ3gnXSAtIGZvbnRTaXplIC8gMiAtIDIpOwotICAgICAgICAgICAgeSA9IE1hdGgucm91bmQobm9kZVtwcmVmaXggKyAneSddIC0gZm9udFNpemUgLyAyIC0gMik7Ci0gICAgICAgICAgICB3ID0gTWF0aC5yb3VuZCgKLSAgICAgICAgICAgICAgICBjb250ZXh0Lm1lYXN1cmVUZXh0KG5vZGUubGFiZWwpLndpZHRoICsgZm9udFNpemUgLyAyICsgc2l6ZSArIDcKLSAgICAgICAgICAgICk7Ci0gICAgICAgICAgICBoID0gTWF0aC5yb3VuZChmb250U2l6ZSArIDQpOwotICAgICAgICAgICAgZSA9IE1hdGgucm91bmQoZm9udFNpemUgLyAyICsgMik7Ci0KLSAgICAgICAgICAgIGNvbnRleHQubW92ZVRvKHgsIHkgKyBlKTsKLSAgICAgICAgICAgIGNvbnRleHQuYXJjVG8oeCwgeSwgeCArIGUsIHksIGUpOwotICAgICAgICAgICAgY29udGV4dC5saW5lVG8oeCArIHcsIHkpOwotICAgICAgICAgICAgY29udGV4dC5saW5lVG8oeCArIHcsIHkgKyBoKTsKLSAgICAgICAgICAgIGNvbnRleHQubGluZVRvKHggKyBlLCB5ICsgaCk7Ci0gICAgICAgICAgICBjb250ZXh0LmFyY1RvKHgsIHkgKyBoLCB4LCB5ICsgaCAtIGUsIGUpOwotICAgICAgICAgICAgY29udGV4dC5saW5lVG8oeCwgeSArIGUpOwotCi0gICAgICAgICAgICBjb250ZXh0LmNsb3NlUGF0aCgpOwotICAgICAgICAgICAgY29udGV4dC5maWxsKCk7Ci0KLSAgICAgICAgICAgIGNvbnRleHQuc2hhZG93T2Zmc2V0WCA9IDA7Ci0gICAgICAgICAgICBjb250ZXh0LnNoYWRvd09mZnNldFkgPSAwOwotICAgICAgICAgICAgY29udGV4dC5zaGFkb3dCbHVyID0gMDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE5vZGUgYm9yZGVyOgotICAgICAgICBpZiAoc2V0dGluZ3MoJ2JvcmRlclNpemUnKSA+IDApIHsKLSAgICAgICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7Ci0gICAgICAgICAgICBjb250ZXh0LmZpbGxTdHlsZSA9IHNldHRpbmdzKCdub2RlQm9yZGVyQ29sb3InKSA9PT0gJ25vZGUnID8KLSAgICAgICAgICAgICAgICAobm9kZS5jb2xvciB8fCBzZXR0aW5ncygnZGVmYXVsdE5vZGVDb2xvcicpKSA6Ci0gICAgICAgICAgICAgICAgc2V0dGluZ3MoJ2RlZmF1bHROb2RlQm9yZGVyQ29sb3InKTsKLSAgICAgICAgICAgIGNvbnRleHQuYXJjKAotICAgICAgICAgICAgICAgIG5vZGVbcHJlZml4ICsgJ3gnXSwKLSAgICAgICAgICAgICAgICBub2RlW3ByZWZpeCArICd5J10sCi0gICAgICAgICAgICAgICAgc2l6ZSArIHNldHRpbmdzKCdib3JkZXJTaXplJyksCi0gICAgICAgICAgICAgICAgMCwKLSAgICAgICAgICAgICAgICBNYXRoLlBJICogMiwKLSAgICAgICAgICAgICAgICB0cnVlCi0gICAgICAgICAgICApOwotICAgICAgICAgICAgY29udGV4dC5jbG9zZVBhdGgoKTsKLSAgICAgICAgICAgIGNvbnRleHQuZmlsbCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gTm9kZToKLSAgICAgICAgdmFyIG5vZGVSZW5kZXJlciA9IHNpZ21hLmNhbnZhcy5ub2Rlc1tub2RlLnR5cGVdIHx8IHNpZ21hLmNhbnZhcy5ub2Rlcy5kZWY7Ci0gICAgICAgIG5vZGVSZW5kZXJlcihub2RlLCBjb250ZXh0LCBzZXR0aW5ncyk7Ci0KLSAgICAgICAgLy8gRGlzcGxheSB0aGUgbGFiZWw6Ci0gICAgICAgIGlmIChub2RlLmxhYmVsICYmIHR5cGVvZiBub2RlLmxhYmVsID09PSAnc3RyaW5nJykgewotICAgICAgICAgICAgY29udGV4dC5maWxsU3R5bGUgPSAoc2V0dGluZ3MoJ2xhYmVsSG92ZXJDb2xvcicpID09PSAnbm9kZScpID8KLSAgICAgICAgICAgICAgICAobm9kZS5jb2xvciB8fCBzZXR0aW5ncygnZGVmYXVsdE5vZGVDb2xvcicpKSA6Ci0gICAgICAgICAgICAgICAgc2V0dGluZ3MoJ2RlZmF1bHRMYWJlbEhvdmVyQ29sb3InKTsKLQotICAgICAgICAgICAgY29udGV4dC5maWxsVGV4dCgKLSAgICAgICAgICAgICAgICBub2RlLmxhYmVsLAotICAgICAgICAgICAgICAgIE1hdGgucm91bmQobm9kZVtwcmVmaXggKyAneCddICsgc2l6ZSArIDMpLAotICAgICAgICAgICAgICAgIE1hdGgucm91bmQobm9kZVtwcmVmaXggKyAneSddICsgZm9udFNpemUgLyAzKQotICAgICAgICAgICAgKTsKLSAgICAgICAgfQotICAgIH07Ci19KS5jYWxsKHRoaXMpOwotCi07KGZ1bmN0aW9uICgpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLmNhbnZhcy5ub2RlcycpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGRlZmF1bHQgbm9kZSByZW5kZXJlci4gSXQgcmVuZGVycyB0aGUgbm9kZSBhcyBhIHNpbXBsZSBkaXNjLgotICAgICAqCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgICBub2RlICAgICBUaGUgbm9kZSBvYmplY3QuCi0gICAgICogQHBhcmFtICB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0ICBUaGUgY2FudmFzIGNvbnRleHQuCi0gICAgICogQHBhcmFtICB7Y29uZmlndXJhYmxlfSAgICAgICAgICAgICBzZXR0aW5ncyBUaGUgc2V0dGluZ3MgZnVuY3Rpb24uCi0gICAgICovCi0gICAgc2lnbWEuY2FudmFzLm5vZGVzLmRlZiA9IGZ1bmN0aW9uIChub2RlLCBjb250ZXh0LCBzZXR0aW5ncykgewotICAgICAgICB2YXIgcHJlZml4ID0gc2V0dGluZ3MoJ3ByZWZpeCcpIHx8ICcnOwotCi0gICAgICAgIGNvbnRleHQuZmlsbFN0eWxlID0gbm9kZS5jb2xvciB8fCBzZXR0aW5ncygnZGVmYXVsdE5vZGVDb2xvcicpOwotICAgICAgICBjb250ZXh0LmJlZ2luUGF0aCgpOwotICAgICAgICBjb250ZXh0LmFyYygKLSAgICAgICAgICAgIG5vZGVbcHJlZml4ICsgJ3gnXSwKLSAgICAgICAgICAgIG5vZGVbcHJlZml4ICsgJ3knXSwKLSAgICAgICAgICAgIG5vZGVbcHJlZml4ICsgJ3NpemUnXSwKLSAgICAgICAgICAgIDAsCi0gICAgICAgICAgICBNYXRoLlBJICogMiwKLSAgICAgICAgICAgIHRydWUKLSAgICAgICAgKTsKLQotICAgICAgICBjb250ZXh0LmNsb3NlUGF0aCgpOwotICAgICAgICBjb250ZXh0LmZpbGwoKTsKLSAgICB9OwotfSkoKTsKLQotOyhmdW5jdGlvbiAoKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5jYW52YXMuZWRnZXMnKTsKLQotICAgIC8qKgotICAgICAqIFRoZSBkZWZhdWx0IGVkZ2UgcmVuZGVyZXIuIEl0IHJlbmRlcnMgdGhlIGVkZ2UgYXMgYSBzaW1wbGUgbGluZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgICAgZWRnZSAgICAgICAgIFRoZSBlZGdlIG9iamVjdC4KLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIHNvdXJjZSBub2RlICBUaGUgZWRnZSBzb3VyY2Ugbm9kZS4KLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIHRhcmdldCBub2RlICBUaGUgZWRnZSB0YXJnZXQgbm9kZS4KLSAgICAgKiBAcGFyYW0gIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgICAgICBUaGUgY2FudmFzIGNvbnRleHQuCi0gICAgICogQHBhcmFtICB7Y29uZmlndXJhYmxlfSAgICAgICAgICAgICBzZXR0aW5ncyAgICAgVGhlIHNldHRpbmdzIGZ1bmN0aW9uLgotICAgICAqLwotICAgIHNpZ21hLmNhbnZhcy5lZGdlcy5kZWYgPSBmdW5jdGlvbiAoZWRnZSwgc291cmNlLCB0YXJnZXQsIGNvbnRleHQsIHNldHRpbmdzKSB7Ci0gICAgICAgIHZhciBjb2xvciA9IGVkZ2UuY29sb3IsCi0gICAgICAgICAgICBwcmVmaXggPSBzZXR0aW5ncygncHJlZml4JykgfHwgJycsCi0gICAgICAgICAgICBzaXplID0gZWRnZVtwcmVmaXggKyAnc2l6ZSddIHx8IDEsCi0gICAgICAgICAgICBlZGdlQ29sb3IgPSBzZXR0aW5ncygnZWRnZUNvbG9yJyksCi0gICAgICAgICAgICBkZWZhdWx0Tm9kZUNvbG9yID0gc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKSwKLSAgICAgICAgICAgIGRlZmF1bHRFZGdlQ29sb3IgPSBzZXR0aW5ncygnZGVmYXVsdEVkZ2VDb2xvcicpOwotCi0gICAgICAgIGlmICghY29sb3IpCi0gICAgICAgICAgICBzd2l0Y2ggKGVkZ2VDb2xvcikgewotICAgICAgICAgICAgICAgIGNhc2UgJ3NvdXJjZSc6Ci0gICAgICAgICAgICAgICAgICAgIGNvbG9yID0gc291cmNlLmNvbG9yIHx8IGRlZmF1bHROb2RlQ29sb3I7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgJ3RhcmdldCc6Ci0gICAgICAgICAgICAgICAgICAgIGNvbG9yID0gdGFyZ2V0LmNvbG9yIHx8IGRlZmF1bHROb2RlQ29sb3I7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgIGNvbG9yID0gZGVmYXVsdEVkZ2VDb2xvcjsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgY29udGV4dC5zdHJva2VTdHlsZSA9IGNvbG9yOwotICAgICAgICBjb250ZXh0LmxpbmVXaWR0aCA9IHNpemU7Ci0gICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7Ci0gICAgICAgIGNvbnRleHQubW92ZVRvKAotICAgICAgICAgICAgc291cmNlW3ByZWZpeCArICd4J10sCi0gICAgICAgICAgICBzb3VyY2VbcHJlZml4ICsgJ3knXQotICAgICAgICApOwotICAgICAgICBjb250ZXh0LmxpbmVUbygKLSAgICAgICAgICAgIHRhcmdldFtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgdGFyZ2V0W3ByZWZpeCArICd5J10KLSAgICAgICAgKTsKLSAgICAgICAgY29udGV4dC5zdHJva2UoKTsKLSAgICB9OwotfSkoKTsKLQotOyhmdW5jdGlvbiAoKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5jYW52YXMuZWRnZXMnKTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgZWRnZSByZW5kZXJlciB3aWxsIGRpc3BsYXkgZWRnZXMgYXMgY3VydmVzLgotICAgICAqCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgICBlZGdlICAgICAgICAgVGhlIGVkZ2Ugb2JqZWN0LgotICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgICAgc291cmNlIG5vZGUgIFRoZSBlZGdlIHNvdXJjZSBub2RlLgotICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgICAgdGFyZ2V0IG5vZGUgIFRoZSBlZGdlIHRhcmdldCBub2RlLgotICAgICAqIEBwYXJhbSAge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCAgICAgIFRoZSBjYW52YXMgY29udGV4dC4KLSAgICAgKiBAcGFyYW0gIHtjb25maWd1cmFibGV9ICAgICAgICAgICAgIHNldHRpbmdzICAgICBUaGUgc2V0dGluZ3MgZnVuY3Rpb24uCi0gICAgICovCi0gICAgc2lnbWEuY2FudmFzLmVkZ2VzLmN1cnZlID0gZnVuY3Rpb24gKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb250ZXh0LCBzZXR0aW5ncykgewotICAgICAgICB2YXIgY29sb3IgPSBlZGdlLmNvbG9yLAotICAgICAgICAgICAgcHJlZml4ID0gc2V0dGluZ3MoJ3ByZWZpeCcpIHx8ICcnLAotICAgICAgICAgICAgc2l6ZSA9IGVkZ2VbcHJlZml4ICsgJ3NpemUnXSB8fCAxLAotICAgICAgICAgICAgZWRnZUNvbG9yID0gc2V0dGluZ3MoJ2VkZ2VDb2xvcicpLAotICAgICAgICAgICAgZGVmYXVsdE5vZGVDb2xvciA9IHNldHRpbmdzKCdkZWZhdWx0Tm9kZUNvbG9yJyksCi0gICAgICAgICAgICBkZWZhdWx0RWRnZUNvbG9yID0gc2V0dGluZ3MoJ2RlZmF1bHRFZGdlQ29sb3InKSwKLSAgICAgICAgICAgIGNwID0ge30sCi0gICAgICAgICAgICBzU2l6ZSA9IHNvdXJjZVtwcmVmaXggKyAnc2l6ZSddLAotICAgICAgICAgICAgc1ggPSBzb3VyY2VbcHJlZml4ICsgJ3gnXSwKLSAgICAgICAgICAgIHNZID0gc291cmNlW3ByZWZpeCArICd5J10sCi0gICAgICAgICAgICB0WCA9IHRhcmdldFtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgdFkgPSB0YXJnZXRbcHJlZml4ICsgJ3knXTsKLQotICAgICAgICBjcCA9IChzb3VyY2UuaWQgPT09IHRhcmdldC5pZCkgPwotICAgICAgICAgICAgc2lnbWEudXRpbHMuZ2V0U2VsZkxvb3BDb250cm9sUG9pbnRzKHNYLCBzWSwgc1NpemUpIDoKLSAgICAgICAgICAgIHNpZ21hLnV0aWxzLmdldFF1YWRyYXRpY0NvbnRyb2xQb2ludChzWCwgc1ksIHRYLCB0WSk7Ci0KLSAgICAgICAgaWYgKCFjb2xvcikKLSAgICAgICAgICAgIHN3aXRjaCAoZWRnZUNvbG9yKSB7Ci0gICAgICAgICAgICAgICAgY2FzZSAnc291cmNlJzoKLSAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBzb3VyY2UuY29sb3IgfHwgZGVmYXVsdE5vZGVDb2xvcjsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSAndGFyZ2V0JzoKLSAgICAgICAgICAgICAgICAgICAgY29sb3IgPSB0YXJnZXQuY29sb3IgfHwgZGVmYXVsdE5vZGVDb2xvcjsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBkZWZhdWx0RWRnZUNvbG9yOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICBjb250ZXh0LnN0cm9rZVN0eWxlID0gY29sb3I7Ci0gICAgICAgIGNvbnRleHQubGluZVdpZHRoID0gc2l6ZTsKLSAgICAgICAgY29udGV4dC5iZWdpblBhdGgoKTsKLSAgICAgICAgY29udGV4dC5tb3ZlVG8oc1gsIHNZKTsKLSAgICAgICAgaWYgKHNvdXJjZS5pZCA9PT0gdGFyZ2V0LmlkKSB7Ci0gICAgICAgICAgICBjb250ZXh0LmJlemllckN1cnZlVG8oY3AueDEsIGNwLnkxLCBjcC54MiwgY3AueTIsIHRYLCB0WSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBjb250ZXh0LnF1YWRyYXRpY0N1cnZlVG8oY3AueCwgY3AueSwgdFgsIHRZKTsKLSAgICAgICAgfQotICAgICAgICBjb250ZXh0LnN0cm9rZSgpOwotICAgIH07Ci19KSgpOwotCi07KGZ1bmN0aW9uICgpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLmNhbnZhcy5lZGdlcycpOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBlZGdlIHJlbmRlcmVyIHdpbGwgZGlzcGxheSBlZGdlcyBhcyBhcnJvd3MgZ29pbmcgZnJvbSB0aGUgc291cmNlIG5vZGUKLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgICAgZWRnZSAgICAgICAgIFRoZSBlZGdlIG9iamVjdC4KLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIHNvdXJjZSBub2RlICBUaGUgZWRnZSBzb3VyY2Ugbm9kZS4KLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIHRhcmdldCBub2RlICBUaGUgZWRnZSB0YXJnZXQgbm9kZS4KLSAgICAgKiBAcGFyYW0gIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgICAgICBUaGUgY2FudmFzIGNvbnRleHQuCi0gICAgICogQHBhcmFtICB7Y29uZmlndXJhYmxlfSAgICAgICAgICAgICBzZXR0aW5ncyAgICAgVGhlIHNldHRpbmdzIGZ1bmN0aW9uLgotICAgICAqLwotICAgIHNpZ21hLmNhbnZhcy5lZGdlcy5hcnJvdyA9IGZ1bmN0aW9uIChlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29udGV4dCwgc2V0dGluZ3MpIHsKLSAgICAgICAgdmFyIGNvbG9yID0gZWRnZS5jb2xvciwKLSAgICAgICAgICAgIHByZWZpeCA9IHNldHRpbmdzKCdwcmVmaXgnKSB8fCAnJywKLSAgICAgICAgICAgIGVkZ2VDb2xvciA9IHNldHRpbmdzKCdlZGdlQ29sb3InKSwKLSAgICAgICAgICAgIGRlZmF1bHROb2RlQ29sb3IgPSBzZXR0aW5ncygnZGVmYXVsdE5vZGVDb2xvcicpLAotICAgICAgICAgICAgZGVmYXVsdEVkZ2VDb2xvciA9IHNldHRpbmdzKCdkZWZhdWx0RWRnZUNvbG9yJyksCi0gICAgICAgICAgICBzaXplID0gZWRnZVtwcmVmaXggKyAnc2l6ZSddIHx8IDEsCi0gICAgICAgICAgICB0U2l6ZSA9IHRhcmdldFtwcmVmaXggKyAnc2l6ZSddLAotICAgICAgICAgICAgc1ggPSBzb3VyY2VbcHJlZml4ICsgJ3gnXSwKLSAgICAgICAgICAgIHNZID0gc291cmNlW3ByZWZpeCArICd5J10sCi0gICAgICAgICAgICB0WCA9IHRhcmdldFtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgdFkgPSB0YXJnZXRbcHJlZml4ICsgJ3knXSwKLSAgICAgICAgICAgIGFTaXplID0gTWF0aC5tYXgoc2l6ZSAqIDIuNSwgc2V0dGluZ3MoJ21pbkFycm93U2l6ZScpKSwKLSAgICAgICAgICAgIGQgPSBNYXRoLnNxcnQoTWF0aC5wb3codFggLSBzWCwgMikgKyBNYXRoLnBvdyh0WSAtIHNZLCAyKSksCi0gICAgICAgICAgICBhWCA9IHNYICsgKHRYIC0gc1gpICogKGQgLSBhU2l6ZSAtIHRTaXplKSAvIGQsCi0gICAgICAgICAgICBhWSA9IHNZICsgKHRZIC0gc1kpICogKGQgLSBhU2l6ZSAtIHRTaXplKSAvIGQsCi0gICAgICAgICAgICB2WCA9ICh0WCAtIHNYKSAqIGFTaXplIC8gZCwKLSAgICAgICAgICAgIHZZID0gKHRZIC0gc1kpICogYVNpemUgLyBkOwotCi0gICAgICAgIGlmICghY29sb3IpCi0gICAgICAgICAgICBzd2l0Y2ggKGVkZ2VDb2xvcikgewotICAgICAgICAgICAgICAgIGNhc2UgJ3NvdXJjZSc6Ci0gICAgICAgICAgICAgICAgICAgIGNvbG9yID0gc291cmNlLmNvbG9yIHx8IGRlZmF1bHROb2RlQ29sb3I7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgJ3RhcmdldCc6Ci0gICAgICAgICAgICAgICAgICAgIGNvbG9yID0gdGFyZ2V0LmNvbG9yIHx8IGRlZmF1bHROb2RlQ29sb3I7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgIGNvbG9yID0gZGVmYXVsdEVkZ2VDb2xvcjsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgY29udGV4dC5zdHJva2VTdHlsZSA9IGNvbG9yOwotICAgICAgICBjb250ZXh0LmxpbmVXaWR0aCA9IHNpemU7Ci0gICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7Ci0gICAgICAgIGNvbnRleHQubW92ZVRvKHNYLCBzWSk7Ci0gICAgICAgIGNvbnRleHQubGluZVRvKAotICAgICAgICAgICAgYVgsCi0gICAgICAgICAgICBhWQotICAgICAgICApOwotICAgICAgICBjb250ZXh0LnN0cm9rZSgpOwotCi0gICAgICAgIGNvbnRleHQuZmlsbFN0eWxlID0gY29sb3I7Ci0gICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7Ci0gICAgICAgIGNvbnRleHQubW92ZVRvKGFYICsgdlgsIGFZICsgdlkpOwotICAgICAgICBjb250ZXh0LmxpbmVUbyhhWCArIHZZICogMC42LCBhWSAtIHZYICogMC42KTsKLSAgICAgICAgY29udGV4dC5saW5lVG8oYVggLSB2WSAqIDAuNiwgYVkgKyB2WCAqIDAuNik7Ci0gICAgICAgIGNvbnRleHQubGluZVRvKGFYICsgdlgsIGFZICsgdlkpOwotICAgICAgICBjb250ZXh0LmNsb3NlUGF0aCgpOwotICAgICAgICBjb250ZXh0LmZpbGwoKTsKLSAgICB9OwotfSkoKTsKLQotOyhmdW5jdGlvbiAoKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5jYW52YXMuZWRnZXMnKTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgZWRnZSByZW5kZXJlciB3aWxsIGRpc3BsYXkgZWRnZXMgYXMgY3VydmVzIHdpdGggYXJyb3cgaGVhZGluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgICAgZWRnZSAgICAgICAgIFRoZSBlZGdlIG9iamVjdC4KLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIHNvdXJjZSBub2RlICBUaGUgZWRnZSBzb3VyY2Ugbm9kZS4KLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIHRhcmdldCBub2RlICBUaGUgZWRnZSB0YXJnZXQgbm9kZS4KLSAgICAgKiBAcGFyYW0gIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgICAgICBUaGUgY2FudmFzIGNvbnRleHQuCi0gICAgICogQHBhcmFtICB7Y29uZmlndXJhYmxlfSAgICAgICAgICAgICBzZXR0aW5ncyAgICAgVGhlIHNldHRpbmdzIGZ1bmN0aW9uLgotICAgICAqLwotICAgIHNpZ21hLmNhbnZhcy5lZGdlcy5jdXJ2ZWRBcnJvdyA9Ci0gICAgICAgIGZ1bmN0aW9uIChlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29udGV4dCwgc2V0dGluZ3MpIHsKLSAgICAgICAgICAgIHZhciBjb2xvciA9IGVkZ2UuY29sb3IsCi0gICAgICAgICAgICAgICAgcHJlZml4ID0gc2V0dGluZ3MoJ3ByZWZpeCcpIHx8ICcnLAotICAgICAgICAgICAgICAgIGVkZ2VDb2xvciA9IHNldHRpbmdzKCdlZGdlQ29sb3InKSwKLSAgICAgICAgICAgICAgICBkZWZhdWx0Tm9kZUNvbG9yID0gc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKSwKLSAgICAgICAgICAgICAgICBkZWZhdWx0RWRnZUNvbG9yID0gc2V0dGluZ3MoJ2RlZmF1bHRFZGdlQ29sb3InKSwKLSAgICAgICAgICAgICAgICBjcCA9IHt9LAotICAgICAgICAgICAgICAgIHNpemUgPSBlZGdlW3ByZWZpeCArICdzaXplJ10gfHwgMSwKLSAgICAgICAgICAgICAgICB0U2l6ZSA9IHRhcmdldFtwcmVmaXggKyAnc2l6ZSddLAotICAgICAgICAgICAgICAgIHNYID0gc291cmNlW3ByZWZpeCArICd4J10sCi0gICAgICAgICAgICAgICAgc1kgPSBzb3VyY2VbcHJlZml4ICsgJ3knXSwKLSAgICAgICAgICAgICAgICB0WCA9IHRhcmdldFtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgICAgIHRZID0gdGFyZ2V0W3ByZWZpeCArICd5J10sCi0gICAgICAgICAgICAgICAgYVNpemUgPSBNYXRoLm1heChzaXplICogMi41LCBzZXR0aW5ncygnbWluQXJyb3dTaXplJykpLAotICAgICAgICAgICAgICAgIGQsCi0gICAgICAgICAgICAgICAgYVgsCi0gICAgICAgICAgICAgICAgYVksCi0gICAgICAgICAgICAgICAgdlgsCi0gICAgICAgICAgICAgICAgdlk7Ci0KLSAgICAgICAgICAgIGNwID0gKHNvdXJjZS5pZCA9PT0gdGFyZ2V0LmlkKSA/Ci0gICAgICAgICAgICAgICAgc2lnbWEudXRpbHMuZ2V0U2VsZkxvb3BDb250cm9sUG9pbnRzKHNYLCBzWSwgdFNpemUpIDoKLSAgICAgICAgICAgICAgICBzaWdtYS51dGlscy5nZXRRdWFkcmF0aWNDb250cm9sUG9pbnQoc1gsIHNZLCB0WCwgdFkpOwotCi0gICAgICAgICAgICBpZiAoc291cmNlLmlkID09PSB0YXJnZXQuaWQpIHsKLSAgICAgICAgICAgICAgICBkID0gTWF0aC5zcXJ0KE1hdGgucG93KHRYIC0gY3AueDEsIDIpICsgTWF0aC5wb3codFkgLSBjcC55MSwgMikpOwotICAgICAgICAgICAgICAgIGFYID0gY3AueDEgKyAodFggLSBjcC54MSkgKiAoZCAtIGFTaXplIC0gdFNpemUpIC8gZDsKLSAgICAgICAgICAgICAgICBhWSA9IGNwLnkxICsgKHRZIC0gY3AueTEpICogKGQgLSBhU2l6ZSAtIHRTaXplKSAvIGQ7Ci0gICAgICAgICAgICAgICAgdlggPSAodFggLSBjcC54MSkgKiBhU2l6ZSAvIGQ7Ci0gICAgICAgICAgICAgICAgdlkgPSAodFkgLSBjcC55MSkgKiBhU2l6ZSAvIGQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBkID0gTWF0aC5zcXJ0KE1hdGgucG93KHRYIC0gY3AueCwgMikgKyBNYXRoLnBvdyh0WSAtIGNwLnksIDIpKTsKLSAgICAgICAgICAgICAgICBhWCA9IGNwLnggKyAodFggLSBjcC54KSAqIChkIC0gYVNpemUgLSB0U2l6ZSkgLyBkOwotICAgICAgICAgICAgICAgIGFZID0gY3AueSArICh0WSAtIGNwLnkpICogKGQgLSBhU2l6ZSAtIHRTaXplKSAvIGQ7Ci0gICAgICAgICAgICAgICAgdlggPSAodFggLSBjcC54KSAqIGFTaXplIC8gZDsKLSAgICAgICAgICAgICAgICB2WSA9ICh0WSAtIGNwLnkpICogYVNpemUgLyBkOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoIWNvbG9yKQotICAgICAgICAgICAgICAgIHN3aXRjaCAoZWRnZUNvbG9yKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3NvdXJjZSc6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IHNvdXJjZS5jb2xvciB8fCBkZWZhdWx0Tm9kZUNvbG9yOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3RhcmdldCc6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IHRhcmdldC5jb2xvciB8fCBkZWZhdWx0Tm9kZUNvbG9yOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGRlZmF1bHRFZGdlQ29sb3I7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSBjb2xvcjsKLSAgICAgICAgICAgIGNvbnRleHQubGluZVdpZHRoID0gc2l6ZTsKLSAgICAgICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7Ci0gICAgICAgICAgICBjb250ZXh0Lm1vdmVUbyhzWCwgc1kpOwotICAgICAgICAgICAgaWYgKHNvdXJjZS5pZCA9PT0gdGFyZ2V0LmlkKSB7Ci0gICAgICAgICAgICAgICAgY29udGV4dC5iZXppZXJDdXJ2ZVRvKGNwLngyLCBjcC55MiwgY3AueDEsIGNwLnkxLCBhWCwgYVkpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBjb250ZXh0LnF1YWRyYXRpY0N1cnZlVG8oY3AueCwgY3AueSwgYVgsIGFZKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNvbnRleHQuc3Ryb2tlKCk7Ci0KLSAgICAgICAgICAgIGNvbnRleHQuZmlsbFN0eWxlID0gY29sb3I7Ci0gICAgICAgICAgICBjb250ZXh0LmJlZ2luUGF0aCgpOwotICAgICAgICAgICAgY29udGV4dC5tb3ZlVG8oYVggKyB2WCwgYVkgKyB2WSk7Ci0gICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhhWCArIHZZICogMC42LCBhWSAtIHZYICogMC42KTsKLSAgICAgICAgICAgIGNvbnRleHQubGluZVRvKGFYIC0gdlkgKiAwLjYsIGFZICsgdlggKiAwLjYpOwotICAgICAgICAgICAgY29udGV4dC5saW5lVG8oYVggKyB2WCwgYVkgKyB2WSk7Ci0gICAgICAgICAgICBjb250ZXh0LmNsb3NlUGF0aCgpOwotICAgICAgICAgICAgY29udGV4dC5maWxsKCk7Ci0gICAgICAgIH07Ci19KSgpOwotCi07KGZ1bmN0aW9uICgpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLmNhbnZhcy5lZGdlaG92ZXJzJyk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGhvdmVyIHJlbmRlcmVyIHdpbGwgZGlzcGxheSB0aGUgZWRnZSB3aXRoIGEgZGlmZmVyZW50IGNvbG9yIG9yIHNpemUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIGVkZ2UgICAgICAgICBUaGUgZWRnZSBvYmplY3QuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgICBzb3VyY2Ugbm9kZSAgVGhlIGVkZ2Ugc291cmNlIG5vZGUuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgICB0YXJnZXQgbm9kZSAgVGhlIGVkZ2UgdGFyZ2V0IG5vZGUuCi0gICAgICogQHBhcmFtICB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0ICAgICAgVGhlIGNhbnZhcyBjb250ZXh0LgotICAgICAqIEBwYXJhbSAge2NvbmZpZ3VyYWJsZX0gICAgICAgICAgICAgc2V0dGluZ3MgICAgIFRoZSBzZXR0aW5ncyBmdW5jdGlvbi4KLSAgICAgKi8KLSAgICBzaWdtYS5jYW52YXMuZWRnZWhvdmVycy5kZWYgPQotICAgICAgICBmdW5jdGlvbiAoZWRnZSwgc291cmNlLCB0YXJnZXQsIGNvbnRleHQsIHNldHRpbmdzKSB7Ci0gICAgICAgICAgICB2YXIgY29sb3IgPSBlZGdlLmNvbG9yLAotICAgICAgICAgICAgICAgIHByZWZpeCA9IHNldHRpbmdzKCdwcmVmaXgnKSB8fCAnJywKLSAgICAgICAgICAgICAgICBzaXplID0gZWRnZVtwcmVmaXggKyAnc2l6ZSddIHx8IDEsCi0gICAgICAgICAgICAgICAgZWRnZUNvbG9yID0gc2V0dGluZ3MoJ2VkZ2VDb2xvcicpLAotICAgICAgICAgICAgICAgIGRlZmF1bHROb2RlQ29sb3IgPSBzZXR0aW5ncygnZGVmYXVsdE5vZGVDb2xvcicpLAotICAgICAgICAgICAgICAgIGRlZmF1bHRFZGdlQ29sb3IgPSBzZXR0aW5ncygnZGVmYXVsdEVkZ2VDb2xvcicpOwotCi0gICAgICAgICAgICBpZiAoIWNvbG9yKQotICAgICAgICAgICAgICAgIHN3aXRjaCAoZWRnZUNvbG9yKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3NvdXJjZSc6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IHNvdXJjZS5jb2xvciB8fCBkZWZhdWx0Tm9kZUNvbG9yOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3RhcmdldCc6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IHRhcmdldC5jb2xvciB8fCBkZWZhdWx0Tm9kZUNvbG9yOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGRlZmF1bHRFZGdlQ29sb3I7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChzZXR0aW5ncygnZWRnZUhvdmVyQ29sb3InKSA9PT0gJ2VkZ2UnKSB7Ci0gICAgICAgICAgICAgICAgY29sb3IgPSBlZGdlLmhvdmVyX2NvbG9yIHx8IGNvbG9yOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBjb2xvciA9IGVkZ2UuaG92ZXJfY29sb3IgfHwgc2V0dGluZ3MoJ2RlZmF1bHRFZGdlSG92ZXJDb2xvcicpIHx8IGNvbG9yOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2l6ZSAqPSBzZXR0aW5ncygnZWRnZUhvdmVyU2l6ZVJhdGlvJyk7Ci0KLSAgICAgICAgICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSBjb2xvcjsKLSAgICAgICAgICAgIGNvbnRleHQubGluZVdpZHRoID0gc2l6ZTsKLSAgICAgICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7Ci0gICAgICAgICAgICBjb250ZXh0Lm1vdmVUbygKLSAgICAgICAgICAgICAgICBzb3VyY2VbcHJlZml4ICsgJ3gnXSwKLSAgICAgICAgICAgICAgICBzb3VyY2VbcHJlZml4ICsgJ3knXQotICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIGNvbnRleHQubGluZVRvKAotICAgICAgICAgICAgICAgIHRhcmdldFtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgICAgIHRhcmdldFtwcmVmaXggKyAneSddCi0gICAgICAgICAgICApOwotICAgICAgICAgICAgY29udGV4dC5zdHJva2UoKTsKLSAgICAgICAgfTsKLX0pKCk7Ci0KLTsoZnVuY3Rpb24gKCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIHNpZ21hLnV0aWxzLnBrZygnc2lnbWEuY2FudmFzLmVkZ2Vob3ZlcnMnKTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgaG92ZXIgcmVuZGVyZXIgd2lsbCBkaXNwbGF5IHRoZSBlZGdlIHdpdGggYSBkaWZmZXJlbnQgY29sb3Igb3Igc2l6ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgICAgZWRnZSAgICAgICAgIFRoZSBlZGdlIG9iamVjdC4KLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIHNvdXJjZSBub2RlICBUaGUgZWRnZSBzb3VyY2Ugbm9kZS4KLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIHRhcmdldCBub2RlICBUaGUgZWRnZSB0YXJnZXQgbm9kZS4KLSAgICAgKiBAcGFyYW0gIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgICAgICBUaGUgY2FudmFzIGNvbnRleHQuCi0gICAgICogQHBhcmFtICB7Y29uZmlndXJhYmxlfSAgICAgICAgICAgICBzZXR0aW5ncyAgICAgVGhlIHNldHRpbmdzIGZ1bmN0aW9uLgotICAgICAqLwotICAgIHNpZ21hLmNhbnZhcy5lZGdlaG92ZXJzLmN1cnZlID0KLSAgICAgICAgZnVuY3Rpb24gKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb250ZXh0LCBzZXR0aW5ncykgewotICAgICAgICAgICAgdmFyIGNvbG9yID0gZWRnZS5jb2xvciwKLSAgICAgICAgICAgICAgICBwcmVmaXggPSBzZXR0aW5ncygncHJlZml4JykgfHwgJycsCi0gICAgICAgICAgICAgICAgc2l6ZSA9IHNldHRpbmdzKCdlZGdlSG92ZXJTaXplUmF0aW8nKSAqIChlZGdlW3ByZWZpeCArICdzaXplJ10gfHwgMSksCi0gICAgICAgICAgICAgICAgZWRnZUNvbG9yID0gc2V0dGluZ3MoJ2VkZ2VDb2xvcicpLAotICAgICAgICAgICAgICAgIGRlZmF1bHROb2RlQ29sb3IgPSBzZXR0aW5ncygnZGVmYXVsdE5vZGVDb2xvcicpLAotICAgICAgICAgICAgICAgIGRlZmF1bHRFZGdlQ29sb3IgPSBzZXR0aW5ncygnZGVmYXVsdEVkZ2VDb2xvcicpLAotICAgICAgICAgICAgICAgIGNwID0ge30sCi0gICAgICAgICAgICAgICAgc1NpemUgPSBzb3VyY2VbcHJlZml4ICsgJ3NpemUnXSwKLSAgICAgICAgICAgICAgICBzWCA9IHNvdXJjZVtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgICAgIHNZID0gc291cmNlW3ByZWZpeCArICd5J10sCi0gICAgICAgICAgICAgICAgdFggPSB0YXJnZXRbcHJlZml4ICsgJ3gnXSwKLSAgICAgICAgICAgICAgICB0WSA9IHRhcmdldFtwcmVmaXggKyAneSddOwotCi0gICAgICAgICAgICBjcCA9IChzb3VyY2UuaWQgPT09IHRhcmdldC5pZCkgPwotICAgICAgICAgICAgICAgIHNpZ21hLnV0aWxzLmdldFNlbGZMb29wQ29udHJvbFBvaW50cyhzWCwgc1ksIHNTaXplKSA6Ci0gICAgICAgICAgICAgICAgc2lnbWEudXRpbHMuZ2V0UXVhZHJhdGljQ29udHJvbFBvaW50KHNYLCBzWSwgdFgsIHRZKTsKLQotICAgICAgICAgICAgaWYgKCFjb2xvcikKLSAgICAgICAgICAgICAgICBzd2l0Y2ggKGVkZ2VDb2xvcikgewotICAgICAgICAgICAgICAgICAgICBjYXNlICdzb3VyY2UnOgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBzb3VyY2UuY29sb3IgfHwgZGVmYXVsdE5vZGVDb2xvcjsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlICd0YXJnZXQnOgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSB0YXJnZXQuY29sb3IgfHwgZGVmYXVsdE5vZGVDb2xvcjsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBkZWZhdWx0RWRnZUNvbG9yOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoc2V0dGluZ3MoJ2VkZ2VIb3ZlckNvbG9yJykgPT09ICdlZGdlJykgewotICAgICAgICAgICAgICAgIGNvbG9yID0gZWRnZS5ob3Zlcl9jb2xvciB8fCBjb2xvcjsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgY29sb3IgPSBlZGdlLmhvdmVyX2NvbG9yIHx8IHNldHRpbmdzKCdkZWZhdWx0RWRnZUhvdmVyQ29sb3InKSB8fCBjb2xvcjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgY29udGV4dC5zdHJva2VTdHlsZSA9IGNvbG9yOwotICAgICAgICAgICAgY29udGV4dC5saW5lV2lkdGggPSBzaXplOwotICAgICAgICAgICAgY29udGV4dC5iZWdpblBhdGgoKTsKLSAgICAgICAgICAgIGNvbnRleHQubW92ZVRvKHNYLCBzWSk7Ci0gICAgICAgICAgICBpZiAoc291cmNlLmlkID09PSB0YXJnZXQuaWQpIHsKLSAgICAgICAgICAgICAgICBjb250ZXh0LmJlemllckN1cnZlVG8oY3AueDEsIGNwLnkxLCBjcC54MiwgY3AueTIsIHRYLCB0WSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGNvbnRleHQucXVhZHJhdGljQ3VydmVUbyhjcC54LCBjcC55LCB0WCwgdFkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY29udGV4dC5zdHJva2UoKTsKLSAgICAgICAgfTsKLX0pKCk7Ci0KLTsoZnVuY3Rpb24gKCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIHNpZ21hLnV0aWxzLnBrZygnc2lnbWEuY2FudmFzLmVkZ2Vob3ZlcnMnKTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgaG92ZXIgcmVuZGVyZXIgd2lsbCBkaXNwbGF5IHRoZSBlZGdlIHdpdGggYSBkaWZmZXJlbnQgY29sb3Igb3Igc2l6ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgICAgZWRnZSAgICAgICAgIFRoZSBlZGdlIG9iamVjdC4KLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIHNvdXJjZSBub2RlICBUaGUgZWRnZSBzb3VyY2Ugbm9kZS4KLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIHRhcmdldCBub2RlICBUaGUgZWRnZSB0YXJnZXQgbm9kZS4KLSAgICAgKiBAcGFyYW0gIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgICAgICBUaGUgY2FudmFzIGNvbnRleHQuCi0gICAgICogQHBhcmFtICB7Y29uZmlndXJhYmxlfSAgICAgICAgICAgICBzZXR0aW5ncyAgICAgVGhlIHNldHRpbmdzIGZ1bmN0aW9uLgotICAgICAqLwotICAgIHNpZ21hLmNhbnZhcy5lZGdlaG92ZXJzLmFycm93ID0KLSAgICAgICAgZnVuY3Rpb24gKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb250ZXh0LCBzZXR0aW5ncykgewotICAgICAgICAgICAgdmFyIGNvbG9yID0gZWRnZS5jb2xvciwKLSAgICAgICAgICAgICAgICBwcmVmaXggPSBzZXR0aW5ncygncHJlZml4JykgfHwgJycsCi0gICAgICAgICAgICAgICAgZWRnZUNvbG9yID0gc2V0dGluZ3MoJ2VkZ2VDb2xvcicpLAotICAgICAgICAgICAgICAgIGRlZmF1bHROb2RlQ29sb3IgPSBzZXR0aW5ncygnZGVmYXVsdE5vZGVDb2xvcicpLAotICAgICAgICAgICAgICAgIGRlZmF1bHRFZGdlQ29sb3IgPSBzZXR0aW5ncygnZGVmYXVsdEVkZ2VDb2xvcicpLAotICAgICAgICAgICAgICAgIHNpemUgPSBlZGdlW3ByZWZpeCArICdzaXplJ10gfHwgMSwKLSAgICAgICAgICAgICAgICB0U2l6ZSA9IHRhcmdldFtwcmVmaXggKyAnc2l6ZSddLAotICAgICAgICAgICAgICAgIHNYID0gc291cmNlW3ByZWZpeCArICd4J10sCi0gICAgICAgICAgICAgICAgc1kgPSBzb3VyY2VbcHJlZml4ICsgJ3knXSwKLSAgICAgICAgICAgICAgICB0WCA9IHRhcmdldFtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgICAgIHRZID0gdGFyZ2V0W3ByZWZpeCArICd5J107Ci0KLSAgICAgICAgICAgIHNpemUgPSAoZWRnZS5ob3ZlcikgPwotICAgICAgICAgICAgc2V0dGluZ3MoJ2VkZ2VIb3ZlclNpemVSYXRpbycpICogc2l6ZSA6IHNpemU7Ci0gICAgICAgICAgICB2YXIgYVNpemUgPSBzaXplICogMi41LAotICAgICAgICAgICAgICAgIGQgPSBNYXRoLnNxcnQoTWF0aC5wb3codFggLSBzWCwgMikgKyBNYXRoLnBvdyh0WSAtIHNZLCAyKSksCi0gICAgICAgICAgICAgICAgYVggPSBzWCArICh0WCAtIHNYKSAqIChkIC0gYVNpemUgLSB0U2l6ZSkgLyBkLAotICAgICAgICAgICAgICAgIGFZID0gc1kgKyAodFkgLSBzWSkgKiAoZCAtIGFTaXplIC0gdFNpemUpIC8gZCwKLSAgICAgICAgICAgICAgICB2WCA9ICh0WCAtIHNYKSAqIGFTaXplIC8gZCwKLSAgICAgICAgICAgICAgICB2WSA9ICh0WSAtIHNZKSAqIGFTaXplIC8gZDsKLQotICAgICAgICAgICAgaWYgKCFjb2xvcikKLSAgICAgICAgICAgICAgICBzd2l0Y2ggKGVkZ2VDb2xvcikgewotICAgICAgICAgICAgICAgICAgICBjYXNlICdzb3VyY2UnOgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBzb3VyY2UuY29sb3IgfHwgZGVmYXVsdE5vZGVDb2xvcjsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlICd0YXJnZXQnOgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSB0YXJnZXQuY29sb3IgfHwgZGVmYXVsdE5vZGVDb2xvcjsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBkZWZhdWx0RWRnZUNvbG9yOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoc2V0dGluZ3MoJ2VkZ2VIb3ZlckNvbG9yJykgPT09ICdlZGdlJykgewotICAgICAgICAgICAgICAgIGNvbG9yID0gZWRnZS5ob3Zlcl9jb2xvciB8fCBjb2xvcjsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgY29sb3IgPSBlZGdlLmhvdmVyX2NvbG9yIHx8IHNldHRpbmdzKCdkZWZhdWx0RWRnZUhvdmVyQ29sb3InKSB8fCBjb2xvcjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgY29udGV4dC5zdHJva2VTdHlsZSA9IGNvbG9yOwotICAgICAgICAgICAgY29udGV4dC5saW5lV2lkdGggPSBzaXplOwotICAgICAgICAgICAgY29udGV4dC5iZWdpblBhdGgoKTsKLSAgICAgICAgICAgIGNvbnRleHQubW92ZVRvKHNYLCBzWSk7Ci0gICAgICAgICAgICBjb250ZXh0LmxpbmVUbygKLSAgICAgICAgICAgICAgICBhWCwKLSAgICAgICAgICAgICAgICBhWQotICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIGNvbnRleHQuc3Ryb2tlKCk7Ci0KLSAgICAgICAgICAgIGNvbnRleHQuZmlsbFN0eWxlID0gY29sb3I7Ci0gICAgICAgICAgICBjb250ZXh0LmJlZ2luUGF0aCgpOwotICAgICAgICAgICAgY29udGV4dC5tb3ZlVG8oYVggKyB2WCwgYVkgKyB2WSk7Ci0gICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhhWCArIHZZICogMC42LCBhWSAtIHZYICogMC42KTsKLSAgICAgICAgICAgIGNvbnRleHQubGluZVRvKGFYIC0gdlkgKiAwLjYsIGFZICsgdlggKiAwLjYpOwotICAgICAgICAgICAgY29udGV4dC5saW5lVG8oYVggKyB2WCwgYVkgKyB2WSk7Ci0gICAgICAgICAgICBjb250ZXh0LmNsb3NlUGF0aCgpOwotICAgICAgICAgICAgY29udGV4dC5maWxsKCk7Ci0gICAgICAgIH07Ci19KSgpOwotCi07KGZ1bmN0aW9uICgpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLmNhbnZhcy5lZGdlaG92ZXJzJyk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGhvdmVyIHJlbmRlcmVyIHdpbGwgZGlzcGxheSB0aGUgZWRnZSB3aXRoIGEgZGlmZmVyZW50IGNvbG9yIG9yIHNpemUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIGVkZ2UgICAgICAgICBUaGUgZWRnZSBvYmplY3QuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgICBzb3VyY2Ugbm9kZSAgVGhlIGVkZ2Ugc291cmNlIG5vZGUuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgICB0YXJnZXQgbm9kZSAgVGhlIGVkZ2UgdGFyZ2V0IG5vZGUuCi0gICAgICogQHBhcmFtICB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0ICAgICAgVGhlIGNhbnZhcyBjb250ZXh0LgotICAgICAqIEBwYXJhbSAge2NvbmZpZ3VyYWJsZX0gICAgICAgICAgICAgc2V0dGluZ3MgICAgIFRoZSBzZXR0aW5ncyBmdW5jdGlvbi4KLSAgICAgKi8KLSAgICBzaWdtYS5jYW52YXMuZWRnZWhvdmVycy5jdXJ2ZWRBcnJvdyA9Ci0gICAgICAgIGZ1bmN0aW9uIChlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29udGV4dCwgc2V0dGluZ3MpIHsKLSAgICAgICAgICAgIHZhciBjb2xvciA9IGVkZ2UuY29sb3IsCi0gICAgICAgICAgICAgICAgcHJlZml4ID0gc2V0dGluZ3MoJ3ByZWZpeCcpIHx8ICcnLAotICAgICAgICAgICAgICAgIGVkZ2VDb2xvciA9IHNldHRpbmdzKCdlZGdlQ29sb3InKSwKLSAgICAgICAgICAgICAgICBkZWZhdWx0Tm9kZUNvbG9yID0gc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKSwKLSAgICAgICAgICAgICAgICBkZWZhdWx0RWRnZUNvbG9yID0gc2V0dGluZ3MoJ2RlZmF1bHRFZGdlQ29sb3InKSwKLSAgICAgICAgICAgICAgICBjcCA9IHt9LAotICAgICAgICAgICAgICAgIHNpemUgPSBzZXR0aW5ncygnZWRnZUhvdmVyU2l6ZVJhdGlvJykgKiAoZWRnZVtwcmVmaXggKyAnc2l6ZSddIHx8IDEpLAotICAgICAgICAgICAgICAgIHRTaXplID0gdGFyZ2V0W3ByZWZpeCArICdzaXplJ10sCi0gICAgICAgICAgICAgICAgc1ggPSBzb3VyY2VbcHJlZml4ICsgJ3gnXSwKLSAgICAgICAgICAgICAgICBzWSA9IHNvdXJjZVtwcmVmaXggKyAneSddLAotICAgICAgICAgICAgICAgIHRYID0gdGFyZ2V0W3ByZWZpeCArICd4J10sCi0gICAgICAgICAgICAgICAgdFkgPSB0YXJnZXRbcHJlZml4ICsgJ3knXSwKLSAgICAgICAgICAgICAgICBkLAotICAgICAgICAgICAgICAgIGFTaXplLAotICAgICAgICAgICAgICAgIGFYLAotICAgICAgICAgICAgICAgIGFZLAotICAgICAgICAgICAgICAgIHZYLAotICAgICAgICAgICAgICAgIHZZOwotCi0gICAgICAgICAgICBjcCA9IChzb3VyY2UuaWQgPT09IHRhcmdldC5pZCkgPwotICAgICAgICAgICAgICAgIHNpZ21hLnV0aWxzLmdldFNlbGZMb29wQ29udHJvbFBvaW50cyhzWCwgc1ksIHRTaXplKSA6Ci0gICAgICAgICAgICAgICAgc2lnbWEudXRpbHMuZ2V0UXVhZHJhdGljQ29udHJvbFBvaW50KHNYLCBzWSwgdFgsIHRZKTsKLQotICAgICAgICAgICAgaWYgKHNvdXJjZS5pZCA9PT0gdGFyZ2V0LmlkKSB7Ci0gICAgICAgICAgICAgICAgZCA9IE1hdGguc3FydChNYXRoLnBvdyh0WCAtIGNwLngxLCAyKSArIE1hdGgucG93KHRZIC0gY3AueTEsIDIpKTsKLSAgICAgICAgICAgICAgICBhU2l6ZSA9IHNpemUgKiAyLjU7Ci0gICAgICAgICAgICAgICAgYVggPSBjcC54MSArICh0WCAtIGNwLngxKSAqIChkIC0gYVNpemUgLSB0U2l6ZSkgLyBkOwotICAgICAgICAgICAgICAgIGFZID0gY3AueTEgKyAodFkgLSBjcC55MSkgKiAoZCAtIGFTaXplIC0gdFNpemUpIC8gZDsKLSAgICAgICAgICAgICAgICB2WCA9ICh0WCAtIGNwLngxKSAqIGFTaXplIC8gZDsKLSAgICAgICAgICAgICAgICB2WSA9ICh0WSAtIGNwLnkxKSAqIGFTaXplIC8gZDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGQgPSBNYXRoLnNxcnQoTWF0aC5wb3codFggLSBjcC54LCAyKSArIE1hdGgucG93KHRZIC0gY3AueSwgMikpOwotICAgICAgICAgICAgICAgIGFTaXplID0gc2l6ZSAqIDIuNTsKLSAgICAgICAgICAgICAgICBhWCA9IGNwLnggKyAodFggLSBjcC54KSAqIChkIC0gYVNpemUgLSB0U2l6ZSkgLyBkOwotICAgICAgICAgICAgICAgIGFZID0gY3AueSArICh0WSAtIGNwLnkpICogKGQgLSBhU2l6ZSAtIHRTaXplKSAvIGQ7Ci0gICAgICAgICAgICAgICAgdlggPSAodFggLSBjcC54KSAqIGFTaXplIC8gZDsKLSAgICAgICAgICAgICAgICB2WSA9ICh0WSAtIGNwLnkpICogYVNpemUgLyBkOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoIWNvbG9yKQotICAgICAgICAgICAgICAgIHN3aXRjaCAoZWRnZUNvbG9yKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3NvdXJjZSc6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IHNvdXJjZS5jb2xvciB8fCBkZWZhdWx0Tm9kZUNvbG9yOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3RhcmdldCc6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IHRhcmdldC5jb2xvciB8fCBkZWZhdWx0Tm9kZUNvbG9yOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGRlZmF1bHRFZGdlQ29sb3I7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChzZXR0aW5ncygnZWRnZUhvdmVyQ29sb3InKSA9PT0gJ2VkZ2UnKSB7Ci0gICAgICAgICAgICAgICAgY29sb3IgPSBlZGdlLmhvdmVyX2NvbG9yIHx8IGNvbG9yOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBjb2xvciA9IGVkZ2UuaG92ZXJfY29sb3IgfHwgc2V0dGluZ3MoJ2RlZmF1bHRFZGdlSG92ZXJDb2xvcicpIHx8IGNvbG9yOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBjb250ZXh0LnN0cm9rZVN0eWxlID0gY29sb3I7Ci0gICAgICAgICAgICBjb250ZXh0LmxpbmVXaWR0aCA9IHNpemU7Ci0gICAgICAgICAgICBjb250ZXh0LmJlZ2luUGF0aCgpOwotICAgICAgICAgICAgY29udGV4dC5tb3ZlVG8oc1gsIHNZKTsKLSAgICAgICAgICAgIGlmIChzb3VyY2UuaWQgPT09IHRhcmdldC5pZCkgewotICAgICAgICAgICAgICAgIGNvbnRleHQuYmV6aWVyQ3VydmVUbyhjcC54MiwgY3AueTIsIGNwLngxLCBjcC55MSwgYVgsIGFZKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgY29udGV4dC5xdWFkcmF0aWNDdXJ2ZVRvKGNwLngsIGNwLnksIGFYLCBhWSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjb250ZXh0LnN0cm9rZSgpOwotCi0gICAgICAgICAgICBjb250ZXh0LmZpbGxTdHlsZSA9IGNvbG9yOwotICAgICAgICAgICAgY29udGV4dC5iZWdpblBhdGgoKTsKLSAgICAgICAgICAgIGNvbnRleHQubW92ZVRvKGFYICsgdlgsIGFZICsgdlkpOwotICAgICAgICAgICAgY29udGV4dC5saW5lVG8oYVggKyB2WSAqIDAuNiwgYVkgLSB2WCAqIDAuNik7Ci0gICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhhWCAtIHZZICogMC42LCBhWSArIHZYICogMC42KTsKLSAgICAgICAgICAgIGNvbnRleHQubGluZVRvKGFYICsgdlgsIGFZICsgdlkpOwotICAgICAgICAgICAgY29udGV4dC5jbG9zZVBhdGgoKTsKLSAgICAgICAgICAgIGNvbnRleHQuZmlsbCgpOwotICAgICAgICB9OwotfSkoKTsKLQotOyhmdW5jdGlvbiAodW5kZWZpbmVkKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgaWYgKHR5cGVvZiBzaWdtYSA9PT0gJ3VuZGVmaW5lZCcpCi0gICAgICAgIHRocm93ICdzaWdtYSBpcyBub3QgZGVjbGFyZWQnOwotCi0gICAgLy8gSW5pdGlhbGl6ZSBwYWNrYWdlczoKLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLmNhbnZhcy5leHRyZW1pdGllcycpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGRlZmF1bHQgcmVuZGVyZXIgZm9yIGhvdmVyZWQgZWRnZSBleHRyZW1pdGllcy4gSXQgcmVuZGVycyB0aGUgZWRnZQotICAgICAqIGV4dHJlbWl0aWVzIGFzIGhvdmVyZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIGVkZ2UgICAgICAgICBUaGUgZWRnZSBvYmplY3QuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgICBzb3VyY2Ugbm9kZSAgVGhlIGVkZ2Ugc291cmNlIG5vZGUuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgICB0YXJnZXQgbm9kZSAgVGhlIGVkZ2UgdGFyZ2V0IG5vZGUuCi0gICAgICogQHBhcmFtICB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0ICAgICAgVGhlIGNhbnZhcyBjb250ZXh0LgotICAgICAqIEBwYXJhbSAge2NvbmZpZ3VyYWJsZX0gICAgICAgICAgICAgc2V0dGluZ3MgICAgIFRoZSBzZXR0aW5ncyBmdW5jdGlvbi4KLSAgICAgKi8KLSAgICBzaWdtYS5jYW52YXMuZXh0cmVtaXRpZXMuZGVmID0KLSAgICAgICAgZnVuY3Rpb24gKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb250ZXh0LCBzZXR0aW5ncykgewotICAgICAgICAgICAgLy8gU291cmNlIE5vZGU6Ci0gICAgICAgICAgICAoCi0gICAgICAgICAgICAgICAgc2lnbWEuY2FudmFzLmhvdmVyc1tzb3VyY2UudHlwZV0gfHwKLSAgICAgICAgICAgICAgICBzaWdtYS5jYW52YXMuaG92ZXJzLmRlZgotICAgICAgICAgICAgKSgKLSAgICAgICAgICAgICAgICBzb3VyY2UsIGNvbnRleHQsIHNldHRpbmdzCi0gICAgICAgICAgICApOwotCi0gICAgICAgICAgICAvLyBUYXJnZXQgTm9kZToKLSAgICAgICAgICAgICgKLSAgICAgICAgICAgICAgICBzaWdtYS5jYW52YXMuaG92ZXJzW3RhcmdldC50eXBlXSB8fAotICAgICAgICAgICAgICAgIHNpZ21hLmNhbnZhcy5ob3ZlcnMuZGVmCi0gICAgICAgICAgICApKAotICAgICAgICAgICAgICAgIHRhcmdldCwgY29udGV4dCwgc2V0dGluZ3MKLSAgICAgICAgICAgICk7Ci0gICAgICAgIH07Ci19KS5jYWxsKHRoaXMpOwotCi07KGZ1bmN0aW9uICgpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLnN2Zy51dGlscycpOwotCi0gICAgLyoqCi0gICAgICogU29tZSB1c2VmdWwgZnVuY3Rpb25zIHVzZWQgYnkgc2lnbWEncyBTVkcgcmVuZGVyZXIuCi0gICAgICovCi0gICAgc2lnbWEuc3ZnLnV0aWxzID0gewotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTVkcgRWxlbWVudCBzaG93LgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtET01FbGVtZW50fSAgICAgICAgICAgICAgIGVsZW1lbnQgICBUaGUgRE9NIGVsZW1lbnQgdG8gc2hvdy4KLSAgICAgICAgICovCi0gICAgICAgIHNob3c6IGZ1bmN0aW9uIChlbGVtZW50KSB7Ci0gICAgICAgICAgICBlbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnJzsKLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9LAotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTVkcgRWxlbWVudCBoaWRlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtET01FbGVtZW50fSAgICAgICAgICAgICAgIGVsZW1lbnQgICBUaGUgRE9NIGVsZW1lbnQgdG8gaGlkZS4KLSAgICAgICAgICovCi0gICAgICAgIGhpZGU6IGZ1bmN0aW9uIChlbGVtZW50KSB7Ci0gICAgICAgICAgICBlbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7Ci0gICAgICAgICAgICByZXR1cm4gdGhpczsKLSAgICAgICAgfQotICAgIH07Ci19KSgpOwotCi07KGZ1bmN0aW9uICgpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLnN2Zy5ub2RlcycpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGRlZmF1bHQgbm9kZSByZW5kZXJlci4gSXQgcmVuZGVycyB0aGUgbm9kZSBhcyBhIHNpbXBsZSBkaXNjLgotICAgICAqLwotICAgIHNpZ21hLnN2Zy5ub2Rlcy5kZWYgPSB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNWRyBFbGVtZW50IGNyZWF0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIG5vZGUgICAgIFRoZSBub2RlIG9iamVjdC4KLSAgICAgICAgICogQHBhcmFtICB7Y29uZmlndXJhYmxlfSAgICAgICAgICAgICBzZXR0aW5ncyBUaGUgc2V0dGluZ3MgZnVuY3Rpb24uCi0gICAgICAgICAqLwotICAgICAgICBjcmVhdGU6IGZ1bmN0aW9uIChub2RlLCBzZXR0aW5ncykgewotICAgICAgICAgICAgdmFyIHByZWZpeCA9IHNldHRpbmdzKCdwcmVmaXgnKSB8fCAnJywKLSAgICAgICAgICAgICAgICBjaXJjbGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc2V0dGluZ3MoJ3htbG5zJyksICdjaXJjbGUnKTsKLQotICAgICAgICAgICAgLy8gRGVmaW5pbmcgdGhlIG5vZGUncyBjaXJjbGUKLSAgICAgICAgICAgIGNpcmNsZS5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZGF0YS1ub2RlLWlkJywgbm9kZS5pZCk7Ci0gICAgICAgICAgICBjaXJjbGUuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2NsYXNzJywgc2V0dGluZ3MoJ2NsYXNzUHJlZml4JykgKyAnLW5vZGUnKTsKLSAgICAgICAgICAgIGNpcmNsZS5zZXRBdHRyaWJ1dGVOUygKLSAgICAgICAgICAgICAgICBudWxsLCAnZmlsbCcsIG5vZGUuY29sb3IgfHwgc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKSk7Ci0KLSAgICAgICAgICAgIC8vIFJldHVybmluZyB0aGUgRE9NIEVsZW1lbnQKLSAgICAgICAgICAgIHJldHVybiBjaXJjbGU7Ci0gICAgICAgIH0sCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNWRyBFbGVtZW50IHVwZGF0ZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgICBub2RlICAgICBUaGUgbm9kZSBvYmplY3QuCi0gICAgICAgICAqIEBwYXJhbSAge0RPTUVsZW1lbnR9ICAgICAgICAgICAgICAgY2lyY2xlICAgVGhlIG5vZGUgRE9NIGVsZW1lbnQuCi0gICAgICAgICAqIEBwYXJhbSAge2NvbmZpZ3VyYWJsZX0gICAgICAgICAgICAgc2V0dGluZ3MgVGhlIHNldHRpbmdzIGZ1bmN0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAobm9kZSwgY2lyY2xlLCBzZXR0aW5ncykgewotICAgICAgICAgICAgdmFyIHByZWZpeCA9IHNldHRpbmdzKCdwcmVmaXgnKSB8fCAnJzsKLQotICAgICAgICAgICAgLy8gQXBwbHlpbmcgY2hhbmdlcwotICAgICAgICAgICAgLy8gVE9ETzogb3B0aW1pemUgLSBjaGVjayBpZiBuZWNlc3NhcnkKLSAgICAgICAgICAgIGNpcmNsZS5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnY3gnLCBub2RlW3ByZWZpeCArICd4J10pOwotICAgICAgICAgICAgY2lyY2xlLnNldEF0dHJpYnV0ZU5TKG51bGwsICdjeScsIG5vZGVbcHJlZml4ICsgJ3knXSk7Ci0gICAgICAgICAgICBjaXJjbGUuc2V0QXR0cmlidXRlTlMobnVsbCwgJ3InLCBub2RlW3ByZWZpeCArICdzaXplJ10pOwotCi0gICAgICAgICAgICAvLyBVcGRhdGluZyBvbmx5IGlmIG5vdCBmcmVlc3R5bGUKLSAgICAgICAgICAgIGlmICghc2V0dGluZ3MoJ2ZyZWVTdHlsZScpKQotICAgICAgICAgICAgICAgIGNpcmNsZS5zZXRBdHRyaWJ1dGVOUygKLSAgICAgICAgICAgICAgICAgICAgbnVsbCwgJ2ZpbGwnLCBub2RlLmNvbG9yIHx8IHNldHRpbmdzKCdkZWZhdWx0Tm9kZUNvbG9yJykpOwotCi0gICAgICAgICAgICAvLyBTaG93aW5nCi0gICAgICAgICAgICBjaXJjbGUuc3R5bGUuZGlzcGxheSA9ICcnOwotCi0gICAgICAgICAgICByZXR1cm4gdGhpczsKLSAgICAgICAgfQotICAgIH07Ci19KSgpOwotCi07KGZ1bmN0aW9uICgpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLnN2Zy5lZGdlcycpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGRlZmF1bHQgZWRnZSByZW5kZXJlci4gSXQgcmVuZGVycyB0aGUgbm9kZSBhcyBhIHNpbXBsZSBsaW5lLgotICAgICAqLwotICAgIHNpZ21hLnN2Zy5lZGdlcy5kZWYgPSB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNWRyBFbGVtZW50IGNyZWF0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIGVkZ2UgICAgICAgVGhlIGVkZ2Ugb2JqZWN0LgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIHNvdXJjZSAgICAgVGhlIHNvdXJjZSBub2RlIG9iamVjdC4KLSAgICAgICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgICB0YXJnZXQgICAgIFRoZSB0YXJnZXQgbm9kZSBvYmplY3QuCi0gICAgICAgICAqIEBwYXJhbSAge2NvbmZpZ3VyYWJsZX0gICAgICAgICAgICAgc2V0dGluZ3MgICBUaGUgc2V0dGluZ3MgZnVuY3Rpb24uCi0gICAgICAgICAqLwotICAgICAgICBjcmVhdGU6IGZ1bmN0aW9uIChlZGdlLCBzb3VyY2UsIHRhcmdldCwgc2V0dGluZ3MpIHsKLSAgICAgICAgICAgIHZhciBjb2xvciA9IGVkZ2UuY29sb3IsCi0gICAgICAgICAgICAgICAgcHJlZml4ID0gc2V0dGluZ3MoJ3ByZWZpeCcpIHx8ICcnLAotICAgICAgICAgICAgICAgIGVkZ2VDb2xvciA9IHNldHRpbmdzKCdlZGdlQ29sb3InKSwKLSAgICAgICAgICAgICAgICBkZWZhdWx0Tm9kZUNvbG9yID0gc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKSwKLSAgICAgICAgICAgICAgICBkZWZhdWx0RWRnZUNvbG9yID0gc2V0dGluZ3MoJ2RlZmF1bHRFZGdlQ29sb3InKTsKLQotICAgICAgICAgICAgaWYgKCFjb2xvcikKLSAgICAgICAgICAgICAgICBzd2l0Y2ggKGVkZ2VDb2xvcikgewotICAgICAgICAgICAgICAgICAgICBjYXNlICdzb3VyY2UnOgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBzb3VyY2UuY29sb3IgfHwgZGVmYXVsdE5vZGVDb2xvcjsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlICd0YXJnZXQnOgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSB0YXJnZXQuY29sb3IgfHwgZGVmYXVsdE5vZGVDb2xvcjsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBkZWZhdWx0RWRnZUNvbG9yOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB2YXIgbGluZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzZXR0aW5ncygneG1sbnMnKSwgJ2xpbmUnKTsKLQotICAgICAgICAgICAgLy8gQXR0cmlidXRlcwotICAgICAgICAgICAgbGluZS5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZGF0YS1lZGdlLWlkJywgZWRnZS5pZCk7Ci0gICAgICAgICAgICBsaW5lLnNldEF0dHJpYnV0ZU5TKG51bGwsICdjbGFzcycsIHNldHRpbmdzKCdjbGFzc1ByZWZpeCcpICsgJy1lZGdlJyk7Ci0gICAgICAgICAgICBsaW5lLnNldEF0dHJpYnV0ZU5TKG51bGwsICdzdHJva2UnLCBjb2xvcik7Ci0KLSAgICAgICAgICAgIHJldHVybiBsaW5lOwotICAgICAgICB9LAotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTVkcgRWxlbWVudCB1cGRhdGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgICAgZWRnZSAgICAgICBUaGUgZWRnZSBvYmplY3QuCi0gICAgICAgICAqIEBwYXJhbSAge0RPTUVsZW1lbnR9ICAgICAgICAgICAgICAgbGluZSAgICAgICBUaGUgbGluZSBET00gRWxlbWVudC4KLSAgICAgICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgICBzb3VyY2UgICAgIFRoZSBzb3VyY2Ugbm9kZSBvYmplY3QuCi0gICAgICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgICAgdGFyZ2V0ICAgICBUaGUgdGFyZ2V0IG5vZGUgb2JqZWN0LgotICAgICAgICAgKiBAcGFyYW0gIHtjb25maWd1cmFibGV9ICAgICAgICAgICAgIHNldHRpbmdzICAgVGhlIHNldHRpbmdzIGZ1bmN0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAoZWRnZSwgbGluZSwgc291cmNlLCB0YXJnZXQsIHNldHRpbmdzKSB7Ci0gICAgICAgICAgICB2YXIgcHJlZml4ID0gc2V0dGluZ3MoJ3ByZWZpeCcpIHx8ICcnOwotCi0gICAgICAgICAgICBsaW5lLnNldEF0dHJpYnV0ZU5TKG51bGwsICdzdHJva2Utd2lkdGgnLCBlZGdlW3ByZWZpeCArICdzaXplJ10gfHwgMSk7Ci0gICAgICAgICAgICBsaW5lLnNldEF0dHJpYnV0ZU5TKG51bGwsICd4MScsIHNvdXJjZVtwcmVmaXggKyAneCddKTsKLSAgICAgICAgICAgIGxpbmUuc2V0QXR0cmlidXRlTlMobnVsbCwgJ3kxJywgc291cmNlW3ByZWZpeCArICd5J10pOwotICAgICAgICAgICAgbGluZS5zZXRBdHRyaWJ1dGVOUyhudWxsLCAneDInLCB0YXJnZXRbcHJlZml4ICsgJ3gnXSk7Ci0gICAgICAgICAgICBsaW5lLnNldEF0dHJpYnV0ZU5TKG51bGwsICd5MicsIHRhcmdldFtwcmVmaXggKyAneSddKTsKLQotICAgICAgICAgICAgLy8gU2hvd2luZwotICAgICAgICAgICAgbGluZS5zdHlsZS5kaXNwbGF5ID0gJyc7Ci0KLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0gICAgfTsKLX0pKCk7Ci0KLTsoZnVuY3Rpb24gKCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIHNpZ21hLnV0aWxzLnBrZygnc2lnbWEuc3ZnLmVkZ2VzJyk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgY3VydmUgZWRnZSByZW5kZXJlci4gSXQgcmVuZGVycyB0aGUgbm9kZSBhcyBhIGJlemllciBjdXJ2ZS4KLSAgICAgKi8KLSAgICBzaWdtYS5zdmcuZWRnZXMuY3VydmUgPSB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNWRyBFbGVtZW50IGNyZWF0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIGVkZ2UgICAgICAgVGhlIGVkZ2Ugb2JqZWN0LgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIHNvdXJjZSAgICAgVGhlIHNvdXJjZSBub2RlIG9iamVjdC4KLSAgICAgICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgICB0YXJnZXQgICAgIFRoZSB0YXJnZXQgbm9kZSBvYmplY3QuCi0gICAgICAgICAqIEBwYXJhbSAge2NvbmZpZ3VyYWJsZX0gICAgICAgICAgICAgc2V0dGluZ3MgICBUaGUgc2V0dGluZ3MgZnVuY3Rpb24uCi0gICAgICAgICAqLwotICAgICAgICBjcmVhdGU6IGZ1bmN0aW9uIChlZGdlLCBzb3VyY2UsIHRhcmdldCwgc2V0dGluZ3MpIHsKLSAgICAgICAgICAgIHZhciBjb2xvciA9IGVkZ2UuY29sb3IsCi0gICAgICAgICAgICAgICAgcHJlZml4ID0gc2V0dGluZ3MoJ3ByZWZpeCcpIHx8ICcnLAotICAgICAgICAgICAgICAgIGVkZ2VDb2xvciA9IHNldHRpbmdzKCdlZGdlQ29sb3InKSwKLSAgICAgICAgICAgICAgICBkZWZhdWx0Tm9kZUNvbG9yID0gc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKSwKLSAgICAgICAgICAgICAgICBkZWZhdWx0RWRnZUNvbG9yID0gc2V0dGluZ3MoJ2RlZmF1bHRFZGdlQ29sb3InKTsKLQotICAgICAgICAgICAgaWYgKCFjb2xvcikKLSAgICAgICAgICAgICAgICBzd2l0Y2ggKGVkZ2VDb2xvcikgewotICAgICAgICAgICAgICAgICAgICBjYXNlICdzb3VyY2UnOgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBzb3VyY2UuY29sb3IgfHwgZGVmYXVsdE5vZGVDb2xvcjsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlICd0YXJnZXQnOgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSB0YXJnZXQuY29sb3IgfHwgZGVmYXVsdE5vZGVDb2xvcjsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBkZWZhdWx0RWRnZUNvbG9yOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB2YXIgcGF0aCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzZXR0aW5ncygneG1sbnMnKSwgJ3BhdGgnKTsKLQotICAgICAgICAgICAgLy8gQXR0cmlidXRlcwotICAgICAgICAgICAgcGF0aC5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZGF0YS1lZGdlLWlkJywgZWRnZS5pZCk7Ci0gICAgICAgICAgICBwYXRoLnNldEF0dHJpYnV0ZU5TKG51bGwsICdjbGFzcycsIHNldHRpbmdzKCdjbGFzc1ByZWZpeCcpICsgJy1lZGdlJyk7Ci0gICAgICAgICAgICBwYXRoLnNldEF0dHJpYnV0ZU5TKG51bGwsICdzdHJva2UnLCBjb2xvcik7Ci0KLSAgICAgICAgICAgIHJldHVybiBwYXRoOwotICAgICAgICB9LAotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTVkcgRWxlbWVudCB1cGRhdGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgICAgZWRnZSAgICAgICBUaGUgZWRnZSBvYmplY3QuCi0gICAgICAgICAqIEBwYXJhbSAge0RPTUVsZW1lbnR9ICAgICAgICAgICAgICAgbGluZSAgICAgICBUaGUgbGluZSBET00gRWxlbWVudC4KLSAgICAgICAgICogQHBhcmFtICB7b2JqZWN0fSAgICAgICAgICAgICAgICAgICBzb3VyY2UgICAgIFRoZSBzb3VyY2Ugbm9kZSBvYmplY3QuCi0gICAgICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgICAgdGFyZ2V0ICAgICBUaGUgdGFyZ2V0IG5vZGUgb2JqZWN0LgotICAgICAgICAgKiBAcGFyYW0gIHtjb25maWd1cmFibGV9ICAgICAgICAgICAgIHNldHRpbmdzICAgVGhlIHNldHRpbmdzIGZ1bmN0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAoZWRnZSwgcGF0aCwgc291cmNlLCB0YXJnZXQsIHNldHRpbmdzKSB7Ci0gICAgICAgICAgICB2YXIgcHJlZml4ID0gc2V0dGluZ3MoJ3ByZWZpeCcpIHx8ICcnOwotCi0gICAgICAgICAgICBwYXRoLnNldEF0dHJpYnV0ZU5TKG51bGwsICdzdHJva2Utd2lkdGgnLCBlZGdlW3ByZWZpeCArICdzaXplJ10gfHwgMSk7Ci0KLSAgICAgICAgICAgIC8vIENvbnRyb2wgcG9pbnQKLSAgICAgICAgICAgIHZhciBjeCA9IChzb3VyY2VbcHJlZml4ICsgJ3gnXSArIHRhcmdldFtwcmVmaXggKyAneCddKSAvIDIgKwotICAgICAgICAgICAgICAgICAgICAodGFyZ2V0W3ByZWZpeCArICd5J10gLSBzb3VyY2VbcHJlZml4ICsgJ3knXSkgLyA0LAotICAgICAgICAgICAgICAgIGN5ID0gKHNvdXJjZVtwcmVmaXggKyAneSddICsgdGFyZ2V0W3ByZWZpeCArICd5J10pIC8gMiArCi0gICAgICAgICAgICAgICAgICAgIChzb3VyY2VbcHJlZml4ICsgJ3gnXSAtIHRhcmdldFtwcmVmaXggKyAneCddKSAvIDQ7Ci0KLSAgICAgICAgICAgIC8vIFBhdGgKLSAgICAgICAgICAgIHZhciBwID0gJ00nICsgc291cmNlW3ByZWZpeCArICd4J10gKyAnLCcgKyBzb3VyY2VbcHJlZml4ICsgJ3knXSArICcgJyArCi0gICAgICAgICAgICAgICAgJ1EnICsgY3ggKyAnLCcgKyBjeSArICcgJyArCi0gICAgICAgICAgICAgICAgdGFyZ2V0W3ByZWZpeCArICd4J10gKyAnLCcgKyB0YXJnZXRbcHJlZml4ICsgJ3knXTsKLQotICAgICAgICAgICAgLy8gVXBkYXRpbmcgYXR0cmlidXRlcwotICAgICAgICAgICAgcGF0aC5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZCcsIHApOwotICAgICAgICAgICAgcGF0aC5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsICdub25lJyk7Ci0KLSAgICAgICAgICAgIC8vIFNob3dpbmcKLSAgICAgICAgICAgIHBhdGguc3R5bGUuZGlzcGxheSA9ICcnOwotCi0gICAgICAgICAgICByZXR1cm4gdGhpczsKLSAgICAgICAgfQotICAgIH07Ci19KSgpOwotCi07KGZ1bmN0aW9uICh1bmRlZmluZWQpIHsKLSAgICAndXNlIHN0cmljdCc7Ci0KLSAgICBpZiAodHlwZW9mIHNpZ21hID09PSAndW5kZWZpbmVkJykKLSAgICAgICAgdGhyb3cgJ3NpZ21hIGlzIG5vdCBkZWNsYXJlZCc7Ci0KLSAgICAvLyBJbml0aWFsaXplIHBhY2thZ2VzOgotICAgIHNpZ21hLnV0aWxzLnBrZygnc2lnbWEuc3ZnLmxhYmVscycpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGRlZmF1bHQgbGFiZWwgcmVuZGVyZXIuIEl0IHJlbmRlcnMgdGhlIGxhYmVsIGFzIGEgc2ltcGxlIHRleHQuCi0gICAgICovCi0gICAgc2lnbWEuc3ZnLmxhYmVscy5kZWYgPSB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNWRyBFbGVtZW50IGNyZWF0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gIHtvYmplY3R9ICAgICAgICAgICAgICAgICAgIG5vZGUgICAgICAgVGhlIG5vZGUgb2JqZWN0LgotICAgICAgICAgKiBAcGFyYW0gIHtjb25maWd1cmFibGV9ICAgICAgICAgICAgIHNldHRpbmdzICAgVGhlIHNldHRpbmdzIGZ1bmN0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAgY3JlYXRlOiBmdW5jdGlvbiAobm9kZSwgc2V0dGluZ3MpIHsKLSAgICAgICAgICAgIHZhciBwcmVmaXggPSBzZXR0aW5ncygncHJlZml4JykgfHwgJycsCi0gICAgICAgICAgICAgICAgc2l6ZSA9IG5vZGVbcHJlZml4ICsgJ3NpemUnXSwKLSAgICAgICAgICAgICAgICB0ZXh0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHNldHRpbmdzKCd4bWxucycpLCAndGV4dCcpOwotCi0gICAgICAgICAgICB2YXIgZm9udFNpemUgPSAoc2V0dGluZ3MoJ2xhYmVsU2l6ZScpID09PSAnZml4ZWQnKSA/Ci0gICAgICAgICAgICAgICAgc2V0dGluZ3MoJ2RlZmF1bHRMYWJlbFNpemUnKSA6Ci0gICAgICAgICAgICBzZXR0aW5ncygnbGFiZWxTaXplUmF0aW8nKSAqIHNpemU7Ci0KLSAgICAgICAgICAgIHZhciBmb250Q29sb3IgPSAoc2V0dGluZ3MoJ2xhYmVsQ29sb3InKSA9PT0gJ25vZGUnKSA/Ci0gICAgICAgICAgICAgICAgKG5vZGUuY29sb3IgfHwgc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKSkgOgotICAgICAgICAgICAgICAgIHNldHRpbmdzKCdkZWZhdWx0TGFiZWxDb2xvcicpOwotCi0gICAgICAgICAgICB0ZXh0LnNldEF0dHJpYnV0ZU5TKG51bGwsICdkYXRhLWxhYmVsLXRhcmdldCcsIG5vZGUuaWQpOwotICAgICAgICAgICAgdGV4dC5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnY2xhc3MnLCBzZXR0aW5ncygnY2xhc3NQcmVmaXgnKSArICctbGFiZWwnKTsKLSAgICAgICAgICAgIHRleHQuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2ZvbnQtc2l6ZScsIGZvbnRTaXplKTsKLSAgICAgICAgICAgIHRleHQuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2ZvbnQtZmFtaWx5Jywgc2V0dGluZ3MoJ2ZvbnQnKSk7Ci0gICAgICAgICAgICB0ZXh0LnNldEF0dHJpYnV0ZU5TKG51bGwsICdmaWxsJywgZm9udENvbG9yKTsKLQotICAgICAgICAgICAgdGV4dC5pbm5lckhUTUwgPSBub2RlLmxhYmVsOwotICAgICAgICAgICAgdGV4dC50ZXh0Q29udGVudCA9IG5vZGUubGFiZWw7Ci0KLSAgICAgICAgICAgIHJldHVybiB0ZXh0OwotICAgICAgICB9LAotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTVkcgRWxlbWVudCB1cGRhdGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgICAgICAgICAgbm9kZSAgICAgVGhlIG5vZGUgb2JqZWN0LgotICAgICAgICAgKiBAcGFyYW0gIHtET01FbGVtZW50fSAgICAgICAgICAgICAgIHRleHQgICAgIFRoZSBsYWJlbCBET00gZWxlbWVudC4KLSAgICAgICAgICogQHBhcmFtICB7Y29uZmlndXJhYmxlfSAgICAgICAgICAgICBzZXR0aW5ncyBUaGUgc2V0dGluZ3MgZnVuY3Rpb24uCi0gICAgICAgICAqLwotICAgICAgICB1cGRhdGU6IGZ1bmN0aW9uIChub2RlLCB0ZXh0LCBzZXR0aW5ncykgewotICAgICAgICAgICAgdmFyIHByZWZpeCA9IHNldHRpbmdzKCdwcmVmaXgnKSB8fCAnJywKLSAgICAgICAgICAgICAgICBzaXplID0gbm9kZVtwcmVmaXggKyAnc2l6ZSddOwotCi0gICAgICAgICAgICB2YXIgZm9udFNpemUgPSAoc2V0dGluZ3MoJ2xhYmVsU2l6ZScpID09PSAnZml4ZWQnKSA/Ci0gICAgICAgICAgICAgICAgc2V0dGluZ3MoJ2RlZmF1bHRMYWJlbFNpemUnKSA6Ci0gICAgICAgICAgICBzZXR0aW5ncygnbGFiZWxTaXplUmF0aW8nKSAqIHNpemU7Ci0KLSAgICAgICAgICAgIC8vIENhc2Ugd2hlbiB3ZSBkb24ndCB3YW50IHRvIGRpc3BsYXkgdGhlIGxhYmVsCi0gICAgICAgICAgICBpZiAoIXNldHRpbmdzKCdmb3JjZUxhYmVscycpICYmIHNpemUgPCBzZXR0aW5ncygnbGFiZWxUaHJlc2hvbGQnKSkKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0KLSAgICAgICAgICAgIGlmICh0eXBlb2Ygbm9kZS5sYWJlbCAhPT0gJ3N0cmluZycpCi0gICAgICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgICAgICAvLyBVcGRhdGluZwotICAgICAgICAgICAgdGV4dC5zZXRBdHRyaWJ1dGVOUyhudWxsLCAneCcsCi0gICAgICAgICAgICAgICAgTWF0aC5yb3VuZChub2RlW3ByZWZpeCArICd4J10gKyBzaXplICsgMykpOwotICAgICAgICAgICAgdGV4dC5zZXRBdHRyaWJ1dGVOUyhudWxsLCAneScsCi0gICAgICAgICAgICAgICAgTWF0aC5yb3VuZChub2RlW3ByZWZpeCArICd5J10gKyBmb250U2l6ZSAvIDMpKTsKLQotICAgICAgICAgICAgLy8gU2hvd2luZwotICAgICAgICAgICAgdGV4dC5zdHlsZS5kaXNwbGF5ID0gJyc7Ci0KLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0gICAgfTsKLX0pLmNhbGwodGhpcyk7Ci0KLTsoZnVuY3Rpb24gKHVuZGVmaW5lZCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIGlmICh0eXBlb2Ygc2lnbWEgPT09ICd1bmRlZmluZWQnKQotICAgICAgICB0aHJvdyAnc2lnbWEgaXMgbm90IGRlY2xhcmVkJzsKLQotICAgIC8vIEluaXRpYWxpemUgcGFja2FnZXM6Ci0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5zdmcuaG92ZXJzJyk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZGVmYXVsdCBob3ZlciByZW5kZXJlci4KLSAgICAgKi8KLSAgICBzaWdtYS5zdmcuaG92ZXJzLmRlZiA9IHsKLQotICAgICAgICAvKioKLSAgICAgICAgICogU1ZHIEVsZW1lbnQgY3JlYXRpb24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgIG5vZGUgICAgICAgICAgICAgICBUaGUgbm9kZSBvYmplY3QuCi0gICAgICAgICAqIEBwYXJhbSAge0NhbnZhc0VsZW1lbnR9ICAgIG1lYXN1cmVtZW50Q2FudmFzICBBIGZha2UgY2FudmFzIGhhbmRsZWQgYnkKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHN2ZyB0byBwZXJmb3JtIHNvbWUgbWVhc3VyZW1lbnRzIGFuZAotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXNzZWQgYnkgdGhlIHJlbmRlcmVyLgotICAgICAgICAgKiBAcGFyYW0gIHtET01FbGVtZW50fSAgICAgICBub2RlQ2lyY2xlICAgICAgICAgVGhlIG5vZGUgRE9NIEVsZW1lbnQuCi0gICAgICAgICAqIEBwYXJhbSAge2NvbmZpZ3VyYWJsZX0gICAgIHNldHRpbmdzICAgICAgICAgICBUaGUgc2V0dGluZ3MgZnVuY3Rpb24uCi0gICAgICAgICAqLwotICAgICAgICBjcmVhdGU6IGZ1bmN0aW9uIChub2RlLCBub2RlQ2lyY2xlLCBtZWFzdXJlbWVudENhbnZhcywgc2V0dGluZ3MpIHsKLQotICAgICAgICAgICAgLy8gRGVmaW5pbmcgdmlzdWFsIHByb3BlcnRpZXMKLSAgICAgICAgICAgIHZhciB4LAotICAgICAgICAgICAgICAgIHksCi0gICAgICAgICAgICAgICAgdywKLSAgICAgICAgICAgICAgICBoLAotICAgICAgICAgICAgICAgIGUsCi0gICAgICAgICAgICAgICAgZCwKLSAgICAgICAgICAgICAgICBmb250U3R5bGUgPSBzZXR0aW5ncygnaG92ZXJGb250U3R5bGUnKSB8fCBzZXR0aW5ncygnZm9udFN0eWxlJyksCi0gICAgICAgICAgICAgICAgcHJlZml4ID0gc2V0dGluZ3MoJ3ByZWZpeCcpIHx8ICcnLAotICAgICAgICAgICAgICAgIHNpemUgPSBub2RlW3ByZWZpeCArICdzaXplJ10sCi0gICAgICAgICAgICAgICAgZm9udFNpemUgPSAoc2V0dGluZ3MoJ2xhYmVsU2l6ZScpID09PSAnZml4ZWQnKSA/Ci0gICAgICAgICAgICAgICAgICAgIHNldHRpbmdzKCdkZWZhdWx0TGFiZWxTaXplJykgOgotICAgICAgICAgICAgICAgIHNldHRpbmdzKCdsYWJlbFNpemVSYXRpbycpICogc2l6ZSwKLSAgICAgICAgICAgICAgICBmb250Q29sb3IgPSAoc2V0dGluZ3MoJ2xhYmVsSG92ZXJDb2xvcicpID09PSAnbm9kZScpID8KLSAgICAgICAgICAgICAgICAgICAgKG5vZGUuY29sb3IgfHwgc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKSkgOgotICAgICAgICAgICAgICAgICAgICBzZXR0aW5ncygnZGVmYXVsdExhYmVsSG92ZXJDb2xvcicpOwotCi0gICAgICAgICAgICAvLyBDcmVhdGluZyBlbGVtZW50cwotICAgICAgICAgICAgdmFyIGdyb3VwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHNldHRpbmdzKCd4bWxucycpLCAnZycpLAotICAgICAgICAgICAgICAgIHJlY3RhbmdsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzZXR0aW5ncygneG1sbnMnKSwgJ3JlY3QnKSwKLSAgICAgICAgICAgICAgICBjaXJjbGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc2V0dGluZ3MoJ3htbG5zJyksICdjaXJjbGUnKSwKLSAgICAgICAgICAgICAgICB0ZXh0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHNldHRpbmdzKCd4bWxucycpLCAndGV4dCcpOwotCi0gICAgICAgICAgICAvLyBEZWZpbmluZyBwcm9wZXJ0aWVzCi0gICAgICAgICAgICBncm91cC5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnY2xhc3MnLCBzZXR0aW5ncygnY2xhc3NQcmVmaXgnKSArICctaG92ZXInKTsKLSAgICAgICAgICAgIGdyb3VwLnNldEF0dHJpYnV0ZU5TKG51bGwsICdkYXRhLW5vZGUtaWQnLCBub2RlLmlkKTsKLQotICAgICAgICAgICAgaWYgKHR5cGVvZiBub2RlLmxhYmVsID09PSAnc3RyaW5nJykgewotCi0gICAgICAgICAgICAgICAgLy8gVGV4dAotICAgICAgICAgICAgICAgIHRleHQuaW5uZXJIVE1MID0gbm9kZS5sYWJlbDsKLSAgICAgICAgICAgICAgICB0ZXh0LnRleHRDb250ZW50ID0gbm9kZS5sYWJlbDsKLSAgICAgICAgICAgICAgICB0ZXh0LnNldEF0dHJpYnV0ZU5TKAotICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAnY2xhc3MnLAotICAgICAgICAgICAgICAgICAgICBzZXR0aW5ncygnY2xhc3NQcmVmaXgnKSArICctaG92ZXItbGFiZWwnKTsKLSAgICAgICAgICAgICAgICB0ZXh0LnNldEF0dHJpYnV0ZU5TKG51bGwsICdmb250LXNpemUnLCBmb250U2l6ZSk7Ci0gICAgICAgICAgICAgICAgdGV4dC5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZm9udC1mYW1pbHknLCBzZXR0aW5ncygnZm9udCcpKTsKLSAgICAgICAgICAgICAgICB0ZXh0LnNldEF0dHJpYnV0ZU5TKG51bGwsICdmaWxsJywgZm9udENvbG9yKTsKLSAgICAgICAgICAgICAgICB0ZXh0LnNldEF0dHJpYnV0ZU5TKG51bGwsICd4JywKLSAgICAgICAgICAgICAgICAgICAgTWF0aC5yb3VuZChub2RlW3ByZWZpeCArICd4J10gKyBzaXplICsgMykpOwotICAgICAgICAgICAgICAgIHRleHQuc2V0QXR0cmlidXRlTlMobnVsbCwgJ3knLAotICAgICAgICAgICAgICAgICAgICBNYXRoLnJvdW5kKG5vZGVbcHJlZml4ICsgJ3knXSArIGZvbnRTaXplIC8gMykpOwotCi0gICAgICAgICAgICAgICAgLy8gTWVhc3VyZXMKLSAgICAgICAgICAgICAgICAvLyBPUFRJTUlaRTogRmluZCBhIGJldHRlciB3YXkgdGhhbiBhIG1lYXN1cmVtZW50IGNhbnZhcwotICAgICAgICAgICAgICAgIHggPSBNYXRoLnJvdW5kKG5vZGVbcHJlZml4ICsgJ3gnXSAtIGZvbnRTaXplIC8gMiAtIDIpOwotICAgICAgICAgICAgICAgIHkgPSBNYXRoLnJvdW5kKG5vZGVbcHJlZml4ICsgJ3knXSAtIGZvbnRTaXplIC8gMiAtIDIpOwotICAgICAgICAgICAgICAgIHcgPSBNYXRoLnJvdW5kKAotICAgICAgICAgICAgICAgICAgICBtZWFzdXJlbWVudENhbnZhcy5tZWFzdXJlVGV4dChub2RlLmxhYmVsKS53aWR0aCArCi0gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplIC8gMiArIHNpemUgKyA5Ci0gICAgICAgICAgICAgICAgKTsKLSAgICAgICAgICAgICAgICBoID0gTWF0aC5yb3VuZChmb250U2l6ZSArIDQpOwotICAgICAgICAgICAgICAgIGUgPSBNYXRoLnJvdW5kKGZvbnRTaXplIC8gMiArIDIpOwotCi0gICAgICAgICAgICAgICAgLy8gQ2lyY2xlCi0gICAgICAgICAgICAgICAgY2lyY2xlLnNldEF0dHJpYnV0ZU5TKAotICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAnY2xhc3MnLAotICAgICAgICAgICAgICAgICAgICBzZXR0aW5ncygnY2xhc3NQcmVmaXgnKSArICctaG92ZXItYXJlYScpOwotICAgICAgICAgICAgICAgIGNpcmNsZS5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsICcjZmZmJyk7Ci0gICAgICAgICAgICAgICAgY2lyY2xlLnNldEF0dHJpYnV0ZU5TKG51bGwsICdjeCcsIG5vZGVbcHJlZml4ICsgJ3gnXSk7Ci0gICAgICAgICAgICAgICAgY2lyY2xlLnNldEF0dHJpYnV0ZU5TKG51bGwsICdjeScsIG5vZGVbcHJlZml4ICsgJ3knXSk7Ci0gICAgICAgICAgICAgICAgY2lyY2xlLnNldEF0dHJpYnV0ZU5TKG51bGwsICdyJywgZSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBSZWN0YW5nbGUKLSAgICAgICAgICAgICAgICByZWN0YW5nbGUuc2V0QXR0cmlidXRlTlMoCi0gICAgICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICdjbGFzcycsCi0gICAgICAgICAgICAgICAgICAgIHNldHRpbmdzKCdjbGFzc1ByZWZpeCcpICsgJy1ob3Zlci1hcmVhJyk7Ci0gICAgICAgICAgICAgICAgcmVjdGFuZ2xlLnNldEF0dHJpYnV0ZU5TKG51bGwsICdmaWxsJywgJyNmZmYnKTsKLSAgICAgICAgICAgICAgICByZWN0YW5nbGUuc2V0QXR0cmlidXRlTlMobnVsbCwgJ3gnLCBub2RlW3ByZWZpeCArICd4J10gKyBlIC8gNCk7Ci0gICAgICAgICAgICAgICAgcmVjdGFuZ2xlLnNldEF0dHJpYnV0ZU5TKG51bGwsICd5Jywgbm9kZVtwcmVmaXggKyAneSddIC0gZSk7Ci0gICAgICAgICAgICAgICAgcmVjdGFuZ2xlLnNldEF0dHJpYnV0ZU5TKG51bGwsICd3aWR0aCcsIHcpOwotICAgICAgICAgICAgICAgIHJlY3RhbmdsZS5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnaGVpZ2h0JywgaCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIEFwcGVuZGluZyBjaGlsZHMKLSAgICAgICAgICAgIGdyb3VwLmFwcGVuZENoaWxkKGNpcmNsZSk7Ci0gICAgICAgICAgICBncm91cC5hcHBlbmRDaGlsZChyZWN0YW5nbGUpOwotICAgICAgICAgICAgZ3JvdXAuYXBwZW5kQ2hpbGQodGV4dCk7Ci0gICAgICAgICAgICBncm91cC5hcHBlbmRDaGlsZChub2RlQ2lyY2xlKTsKLQotICAgICAgICAgICAgcmV0dXJuIGdyb3VwOwotICAgICAgICB9Ci0gICAgfTsKLX0pLmNhbGwodGhpcyk7Ci0KLTsoZnVuY3Rpb24gKHVuZGVmaW5lZCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIGlmICh0eXBlb2Ygc2lnbWEgPT09ICd1bmRlZmluZWQnKQotICAgICAgICB0aHJvdyAnc2lnbWEgaXMgbm90IGRlY2xhcmVkJzsKLQotICAgIC8vIEluaXRpYWxpemUgcGFja2FnZXM6Ci0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5taWRkbGV3YXJlcycpOwotICAgIHNpZ21hLnV0aWxzLnBrZygnc2lnbWEudXRpbHMnKTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWlkZGxld2FyZSB3aWxsIHJlc2NhbGUgdGhlIGdyYXBoIHN1Y2ggdGhhdCBpdCB0YWtlcyBhbiBvcHRpbWFsIHNwYWNlCi0gICAgICogb24gdGhlIHJlbmRlcmVyLgotICAgICAqCi0gICAgICogQXMgZWFjaCBtaWRkbGV3YXJlLCB0aGlzIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGluIHRoZSBzY29wZSBvZiB0aGUgc2lnbWEKLSAgICAgKiBpbnN0YW5jZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB7P3N0cmluZ30gcmVhZFByZWZpeCAgVGhlIHJlYWQgcHJlZml4LgotICAgICAqIEBwYXJhbSB7P3N0cmluZ30gd3JpdGVQcmVmaXggVGhlIHdyaXRlIHByZWZpeC4KLSAgICAgKiBAcGFyYW0ge29iamVjdH0gIG9wdGlvbnMgICAgIFRoZSBwYXJhbWV0ZXJzLgotICAgICAqLwotICAgIHNpZ21hLm1pZGRsZXdhcmVzLnJlc2NhbGUgPSBmdW5jdGlvbiAocmVhZFByZWZpeCwgd3JpdGVQcmVmaXgsIG9wdGlvbnMpIHsKLSAgICAgICAgdmFyIGksCi0gICAgICAgICAgICBsLAotICAgICAgICAgICAgYSwKLSAgICAgICAgICAgIGIsCi0gICAgICAgICAgICBjLAotICAgICAgICAgICAgZCwKLSAgICAgICAgICAgIHNjYWxlLAotICAgICAgICAgICAgbWFyZ2luLAotICAgICAgICAgICAgbiA9IHRoaXMuZ3JhcGgubm9kZXMoKSwKLSAgICAgICAgICAgIGUgPSB0aGlzLmdyYXBoLmVkZ2VzKCksCi0gICAgICAgICAgICBzZXR0aW5ncyA9IHRoaXMuc2V0dGluZ3MuZW1iZWRPYmplY3RzKG9wdGlvbnMgfHwge30pLAotICAgICAgICAgICAgYm91bmRzID0gc2V0dGluZ3MoJ2JvdW5kcycpIHx8IHNpZ21hLnV0aWxzLmdldEJvdW5kYXJpZXMoCi0gICAgICAgICAgICAgICAgICAgIHRoaXMuZ3JhcGgsCi0gICAgICAgICAgICAgICAgICAgIHJlYWRQcmVmaXgsCi0gICAgICAgICAgICAgICAgICAgIHRydWUKLSAgICAgICAgICAgICAgICApLAotICAgICAgICAgICAgbWluWCA9IGJvdW5kcy5taW5YLAotICAgICAgICAgICAgbWluWSA9IGJvdW5kcy5taW5ZLAotICAgICAgICAgICAgbWF4WCA9IGJvdW5kcy5tYXhYLAotICAgICAgICAgICAgbWF4WSA9IGJvdW5kcy5tYXhZLAotICAgICAgICAgICAgc2l6ZU1heCA9IGJvdW5kcy5zaXplTWF4LAotICAgICAgICAgICAgd2VpZ2h0TWF4ID0gYm91bmRzLndlaWdodE1heCwKLSAgICAgICAgICAgIHcgPSBzZXR0aW5ncygnd2lkdGgnKSB8fCAxLAotICAgICAgICAgICAgaCA9IHNldHRpbmdzKCdoZWlnaHQnKSB8fCAxLAotICAgICAgICAgICAgcmVzY2FsZVNldHRpbmdzID0gc2V0dGluZ3MoJ2F1dG9SZXNjYWxlJyksCi0gICAgICAgICAgICB2YWxpZFNldHRpbmdzID0gewotICAgICAgICAgICAgICAgIG5vZGVQb3NpdGlvbjogMSwKLSAgICAgICAgICAgICAgICBub2RlU2l6ZTogMSwKLSAgICAgICAgICAgICAgICBlZGdlU2l6ZTogMQotICAgICAgICAgICAgfTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogV2hhdCBlbGVtZW50cyBzaG91bGQgd2UgcmVzY2FsZT8KLSAgICAgICAgICovCi0gICAgICAgIGlmICghKHJlc2NhbGVTZXR0aW5ncyBpbnN0YW5jZW9mIEFycmF5KSkKLSAgICAgICAgICAgIHJlc2NhbGVTZXR0aW5ncyA9IFsnbm9kZVBvc2l0aW9uJywgJ25vZGVTaXplJywgJ2VkZ2VTaXplJ107Ci0KLSAgICAgICAgZm9yIChpID0gMCwgbCA9IHJlc2NhbGVTZXR0aW5ncy5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICBpZiAoIXZhbGlkU2V0dGluZ3NbcmVzY2FsZVNldHRpbmdzW2ldXSkKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICdUaGUgcmVzY2FsZSBzZXR0aW5nICInICsgcmVzY2FsZVNldHRpbmdzW2ldICsgJyIgaXMgbm90IHJlY29nbml6ZWQuJwotICAgICAgICAgICAgICAgICk7Ci0KLSAgICAgICAgdmFyIG5wID0gfnJlc2NhbGVTZXR0aW5ncy5pbmRleE9mKCdub2RlUG9zaXRpb24nKSwKLSAgICAgICAgICAgIG5zID0gfnJlc2NhbGVTZXR0aW5ncy5pbmRleE9mKCdub2RlU2l6ZScpLAotICAgICAgICAgICAgZXMgPSB+cmVzY2FsZVNldHRpbmdzLmluZGV4T2YoJ2VkZ2VTaXplJyk7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEZpcnN0LCB3ZSBjb21wdXRlIHRoZSBzY2FsaW5nIHJhdGlvLCB3aXRob3V0IGNvbnNpZGVyaW5nIHRoZSBzaXplcwotICAgICAgICAgKiBvZiB0aGUgbm9kZXMgOiBFYWNoIG5vZGUgd2lsbCBoYXZlIGl0cyBjZW50ZXIgaW4gdGhlIGNhbnZhcywgYnV0IG1pZ2h0Ci0gICAgICAgICAqIGJlIHBhcnRpYWxseSBvdXQgb2YgaXQuCi0gICAgICAgICAqLwotICAgICAgICBzY2FsZSA9IHNldHRpbmdzKCdzY2FsaW5nTW9kZScpID09PSAnb3V0c2lkZScgPwotICAgICAgICAgICAgTWF0aC5tYXgoCi0gICAgICAgICAgICAgICAgdyAvIE1hdGgubWF4KG1heFggLSBtaW5YLCAxKSwKLSAgICAgICAgICAgICAgICBoIC8gTWF0aC5tYXgobWF4WSAtIG1pblksIDEpCi0gICAgICAgICAgICApIDoKLSAgICAgICAgICAgIE1hdGgubWluKAotICAgICAgICAgICAgICAgIHcgLyBNYXRoLm1heChtYXhYIC0gbWluWCwgMSksCi0gICAgICAgICAgICAgICAgaCAvIE1hdGgubWF4KG1heFkgLSBtaW5ZLCAxKQotICAgICAgICAgICAgKTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhlbiwgd2UgY29ycmVjdCB0aGF0IHNjYWxpbmcgcmF0aW8gY29uc2lkZXJpbmcgYSBtYXJnaW4sIHdoaWNoIGlzCi0gICAgICAgICAqIGJhc2ljYWxseSB0aGUgc2l6ZSBvZiB0aGUgYmlnZ2VzdCBub2RlLgotICAgICAgICAgKiBUaGlzIGhhcyB0byBiZSBkb25lIGFzIGEgY29ycmVjdGlvbiBzaW5jZSB0byBjb21wYXJlIHRoZSBzaXplIG9mIHRoZQotICAgICAgICAgKiBiaWdnZXN0IG5vZGUgdG8gdGhlIFggYW5kIFkgdmFsdWVzLCB3ZSBoYXZlIHRvIGZpcnN0IGdldCBhbgotICAgICAgICAgKiBhcHByb3hpbWF0aW9uIG9mIHRoZSBzY2FsaW5nIHJhdGlvLgotICAgICAgICAgKiovCi0gICAgICAgIG1hcmdpbiA9Ci0gICAgICAgICAgICAoCi0gICAgICAgICAgICAgICAgc2V0dGluZ3MoJ3Jlc2NhbGVJZ25vcmVTaXplJykgPwotICAgICAgICAgICAgICAgICAgICAwIDoKLSAgICAgICAgICAgICAgICAoc2V0dGluZ3MoJ21heE5vZGVTaXplJykgfHwgc2l6ZU1heCkgLyBzY2FsZQotICAgICAgICAgICAgKSArCi0gICAgICAgICAgICAoc2V0dGluZ3MoJ3NpZGVNYXJnaW4nKSB8fCAwKTsKLSAgICAgICAgbWF4WCArPSBtYXJnaW47Ci0gICAgICAgIG1pblggLT0gbWFyZ2luOwotICAgICAgICBtYXhZICs9IG1hcmdpbjsKLSAgICAgICAgbWluWSAtPSBtYXJnaW47Ci0KLSAgICAgICAgLy8gRml4IHRoZSBzY2FsaW5nIHdpdGggdGhlIG5ldyBleHRyZW1hOgotICAgICAgICBzY2FsZSA9IHNldHRpbmdzKCdzY2FsaW5nTW9kZScpID09PSAnb3V0c2lkZScgPwotICAgICAgICAgICAgTWF0aC5tYXgoCi0gICAgICAgICAgICAgICAgdyAvIE1hdGgubWF4KG1heFggLSBtaW5YLCAxKSwKLSAgICAgICAgICAgICAgICBoIC8gTWF0aC5tYXgobWF4WSAtIG1pblksIDEpCi0gICAgICAgICAgICApIDoKLSAgICAgICAgICAgIE1hdGgubWluKAotICAgICAgICAgICAgICAgIHcgLyBNYXRoLm1heChtYXhYIC0gbWluWCwgMSksCi0gICAgICAgICAgICAgICAgaCAvIE1hdGgubWF4KG1heFkgLSBtaW5ZLCAxKQotICAgICAgICAgICAgKTsKLQotICAgICAgICAvLyBTaXplIGhvbW90aGV0aWMgcGFyYW1ldGVyczoKLSAgICAgICAgaWYgKCFzZXR0aW5ncygnbWF4Tm9kZVNpemUnKSAmJiAhc2V0dGluZ3MoJ21pbk5vZGVTaXplJykpIHsKLSAgICAgICAgICAgIGEgPSAxOwotICAgICAgICAgICAgYiA9IDA7Ci0gICAgICAgIH0gZWxzZSBpZiAoc2V0dGluZ3MoJ21heE5vZGVTaXplJykgPT09IHNldHRpbmdzKCdtaW5Ob2RlU2l6ZScpKSB7Ci0gICAgICAgICAgICBhID0gMDsKLSAgICAgICAgICAgIGIgPSArc2V0dGluZ3MoJ21heE5vZGVTaXplJyk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBhID0gKHNldHRpbmdzKCdtYXhOb2RlU2l6ZScpIC0gc2V0dGluZ3MoJ21pbk5vZGVTaXplJykpIC8gc2l6ZU1heDsKLSAgICAgICAgICAgIGIgPSArc2V0dGluZ3MoJ21pbk5vZGVTaXplJyk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIXNldHRpbmdzKCdtYXhFZGdlU2l6ZScpICYmICFzZXR0aW5ncygnbWluRWRnZVNpemUnKSkgewotICAgICAgICAgICAgYyA9IDE7Ci0gICAgICAgICAgICBkID0gMDsKLSAgICAgICAgfSBlbHNlIGlmIChzZXR0aW5ncygnbWF4RWRnZVNpemUnKSA9PT0gc2V0dGluZ3MoJ21pbkVkZ2VTaXplJykpIHsKLSAgICAgICAgICAgIGMgPSAwOwotICAgICAgICAgICAgZCA9ICtzZXR0aW5ncygnbWluRWRnZVNpemUnKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGMgPSAoc2V0dGluZ3MoJ21heEVkZ2VTaXplJykgLSBzZXR0aW5ncygnbWluRWRnZVNpemUnKSkgLyB3ZWlnaHRNYXg7Ci0gICAgICAgICAgICBkID0gK3NldHRpbmdzKCdtaW5FZGdlU2l6ZScpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUmVzY2FsZSB0aGUgbm9kZXMgYW5kIGVkZ2VzOgotICAgICAgICBmb3IgKGkgPSAwLCBsID0gZS5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICBlW2ldW3dyaXRlUHJlZml4ICsgJ3NpemUnXSA9Ci0gICAgICAgICAgICAgICAgZVtpXVtyZWFkUHJlZml4ICsgJ3NpemUnXSAqIChlcyA/IGMgOiAxKSArIChlcyA/IGQgOiAwKTsKLQotICAgICAgICBmb3IgKGkgPSAwLCBsID0gbi5sZW5ndGg7IGkgPCBsOyBpKyspIHsKLSAgICAgICAgICAgIG5baV1bd3JpdGVQcmVmaXggKyAnc2l6ZSddID0KLSAgICAgICAgICAgICAgICBuW2ldW3JlYWRQcmVmaXggKyAnc2l6ZSddICogKG5zID8gYSA6IDEpICsgKG5zID8gYiA6IDApOwotICAgICAgICAgICAgbltpXVt3cml0ZVByZWZpeCArICd4J10gPQotICAgICAgICAgICAgICAgIChuW2ldW3JlYWRQcmVmaXggKyAneCddIC0gKG1heFggKyBtaW5YKSAvIDIpICogKG5wID8gc2NhbGUgOiAxKTsKLSAgICAgICAgICAgIG5baV1bd3JpdGVQcmVmaXggKyAneSddID0KLSAgICAgICAgICAgICAgICAobltpXVtyZWFkUHJlZml4ICsgJ3knXSAtIChtYXhZICsgbWluWSkgLyAyKSAqIChucCA/IHNjYWxlIDogMSk7Ci0gICAgICAgIH0KLSAgICB9OwotCi0gICAgc2lnbWEudXRpbHMuZ2V0Qm91bmRhcmllcyA9IGZ1bmN0aW9uIChncmFwaCwgcHJlZml4LCBkb0VkZ2VzKSB7Ci0gICAgICAgIHZhciBpLAotICAgICAgICAgICAgbCwKLSAgICAgICAgICAgIGUgPSBncmFwaC5lZGdlcygpLAotICAgICAgICAgICAgbiA9IGdyYXBoLm5vZGVzKCksCi0gICAgICAgICAgICB3ZWlnaHRNYXggPSAtSW5maW5pdHksCi0gICAgICAgICAgICBzaXplTWF4ID0gLUluZmluaXR5LAotICAgICAgICAgICAgbWluWCA9IEluZmluaXR5LAotICAgICAgICAgICAgbWluWSA9IEluZmluaXR5LAotICAgICAgICAgICAgbWF4WCA9IC1JbmZpbml0eSwKLSAgICAgICAgICAgIG1heFkgPSAtSW5maW5pdHk7Ci0KLSAgICAgICAgaWYgKGRvRWRnZXMpCi0gICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gZS5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICAgICAgd2VpZ2h0TWF4ID0gTWF0aC5tYXgoZVtpXVtwcmVmaXggKyAnc2l6ZSddLCB3ZWlnaHRNYXgpOwotCi0gICAgICAgIGZvciAoaSA9IDAsIGwgPSBuLmxlbmd0aDsgaSA8IGw7IGkrKykgewotICAgICAgICAgICAgc2l6ZU1heCA9IE1hdGgubWF4KG5baV1bcHJlZml4ICsgJ3NpemUnXSwgc2l6ZU1heCk7Ci0gICAgICAgICAgICBtYXhYID0gTWF0aC5tYXgobltpXVtwcmVmaXggKyAneCddLCBtYXhYKTsKLSAgICAgICAgICAgIG1pblggPSBNYXRoLm1pbihuW2ldW3ByZWZpeCArICd4J10sIG1pblgpOwotICAgICAgICAgICAgbWF4WSA9IE1hdGgubWF4KG5baV1bcHJlZml4ICsgJ3knXSwgbWF4WSk7Ci0gICAgICAgICAgICBtaW5ZID0gTWF0aC5taW4obltpXVtwcmVmaXggKyAneSddLCBtaW5ZKTsKLSAgICAgICAgfQotCi0gICAgICAgIHdlaWdodE1heCA9IHdlaWdodE1heCB8fCAxOwotICAgICAgICBzaXplTWF4ID0gc2l6ZU1heCB8fCAxOwotCi0gICAgICAgIHJldHVybiB7Ci0gICAgICAgICAgICB3ZWlnaHRNYXg6IHdlaWdodE1heCwKLSAgICAgICAgICAgIHNpemVNYXg6IHNpemVNYXgsCi0gICAgICAgICAgICBtaW5YOiBtaW5YLAotICAgICAgICAgICAgbWluWTogbWluWSwKLSAgICAgICAgICAgIG1heFg6IG1heFgsCi0gICAgICAgICAgICBtYXhZOiBtYXhZCi0gICAgICAgIH07Ci0gICAgfTsKLX0pLmNhbGwodGhpcyk7Ci0KLTsoZnVuY3Rpb24gKHVuZGVmaW5lZCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIGlmICh0eXBlb2Ygc2lnbWEgPT09ICd1bmRlZmluZWQnKQotICAgICAgICB0aHJvdyAnc2lnbWEgaXMgbm90IGRlY2xhcmVkJzsKLQotICAgIC8vIEluaXRpYWxpemUgcGFja2FnZXM6Ci0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5taWRkbGV3YXJlcycpOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtaWRkbGV3YXJlIHdpbGwganVzdCBjb3B5IHRoZSBncmFwaGljIHByb3BlcnRpZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gez9zdHJpbmd9IHJlYWRQcmVmaXggIFRoZSByZWFkIHByZWZpeC4KLSAgICAgKiBAcGFyYW0gez9zdHJpbmd9IHdyaXRlUHJlZml4IFRoZSB3cml0ZSBwcmVmaXguCi0gICAgICovCi0gICAgc2lnbWEubWlkZGxld2FyZXMuY29weSA9IGZ1bmN0aW9uIChyZWFkUHJlZml4LCB3cml0ZVByZWZpeCkgewotICAgICAgICB2YXIgaSwKLSAgICAgICAgICAgIGwsCi0gICAgICAgICAgICBhOwotCi0gICAgICAgIGlmICh3cml0ZVByZWZpeCArICcnID09PSByZWFkUHJlZml4ICsgJycpCi0gICAgICAgICAgICByZXR1cm47Ci0KLSAgICAgICAgYSA9IHRoaXMuZ3JhcGgubm9kZXMoKTsKLSAgICAgICAgZm9yIChpID0gMCwgbCA9IGEubGVuZ3RoOyBpIDwgbDsgaSsrKSB7Ci0gICAgICAgICAgICBhW2ldW3dyaXRlUHJlZml4ICsgJ3gnXSA9IGFbaV1bcmVhZFByZWZpeCArICd4J107Ci0gICAgICAgICAgICBhW2ldW3dyaXRlUHJlZml4ICsgJ3knXSA9IGFbaV1bcmVhZFByZWZpeCArICd5J107Ci0gICAgICAgICAgICBhW2ldW3dyaXRlUHJlZml4ICsgJ3NpemUnXSA9IGFbaV1bcmVhZFByZWZpeCArICdzaXplJ107Ci0gICAgICAgIH0KLQotICAgICAgICBhID0gdGhpcy5ncmFwaC5lZGdlcygpOwotICAgICAgICBmb3IgKGkgPSAwLCBsID0gYS5sZW5ndGg7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICBhW2ldW3dyaXRlUHJlZml4ICsgJ3NpemUnXSA9IGFbaV1bcmVhZFByZWZpeCArICdzaXplJ107Ci0gICAgfTsKLX0pLmNhbGwodGhpcyk7Ci0KLTsoZnVuY3Rpb24gKHVuZGVmaW5lZCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIGlmICh0eXBlb2Ygc2lnbWEgPT09ICd1bmRlZmluZWQnKQotICAgICAgICB0aHJvdyAnc2lnbWEgaXMgbm90IGRlY2xhcmVkJzsKLQotICAgIC8vIEluaXRpYWxpemUgcGFja2FnZXM6Ci0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5taXNjLmFuaW1hdGlvbi5ydW5uaW5nJyk7Ci0KLSAgICAvKioKLSAgICAgKiBHZW5lcmF0ZXMgYSB1bmlxdWUgSUQgZm9yIHRoZSBhbmltYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFJldHVybnMgdGhlIG5ldyBJRC4KLSAgICAgKi8KLSAgICB2YXIgX2dldElEID0gKGZ1bmN0aW9uICgpIHsKLSAgICAgICAgdmFyIGlkID0gMDsKLSAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsKLSAgICAgICAgICAgIHJldHVybiAnJyArICgrK2lkKTsKLSAgICAgICAgfTsKLSAgICB9KSgpOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBmdW5jdGlvbiBhbmltYXRlcyBhIGNhbWVyYS4gSXQgaGFzIHRvIGJlIGNhbGxlZCB3aXRoIHRoZSBjYW1lcmEgdG8KLSAgICAgKiBhbmltYXRlLCB0aGUgdmFsdWVzIG9mIHRoZSBjb29yZGluYXRlcyB0byByZWFjaCBhbmQgZXZlbnR1YWxseSBzb21lCi0gICAgICogb3B0aW9ucy4gSXQgcmV0dXJucyBhIG51bWJlciBpZCwgdGhhdCB5b3UgY2FuIHVzZSB0byBraWxsIHRoZSBhbmltYXRpb24sCi0gICAgICogd2l0aCB0aGUgbWV0aG9kIHNpZ21hLm1pc2MuYW5pbWF0aW9uLmtpbGwoaWQpLgotICAgICAqCi0gICAgICogVGhlIGF2YWlsYWJsZSBvcHRpb25zIGFyZToKLSAgICAgKgotICAgICAqICAgez9udW1iZXJ9ICAgICAgICAgICAgZHVyYXRpb24gICBUaGUgZHVyYXRpb24gb2YgdGhlIGFuaW1hdGlvbi4KLSAgICAgKiAgIHs/ZnVuY3Rpb259ICAgICAgICAgIG9uTmV3RnJhbWUgQSBjYWxsYmFjayB0byBleGVjdXRlIHdoZW4gdGhlIGFuaW1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRlciBhIG5ldyBmcmFtZS4KLSAgICAgKiAgIHs/ZnVuY3Rpb259ICAgICAgICAgIG9uQ29tcGxldGUgQSBjYWxsYmFjayB0byBleGVjdXRlIHdoZW4gdGhlIGFuaW1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBjb21wbGV0ZWQgb3Iga2lsbGVkLgotICAgICAqICAgez8oc3RyaW5nfGZ1bmN0aW9uKX0gZWFzaW5nICAgICBUaGUgbmFtZSBvZiBhIGZ1bmN0aW9uIGZyb20gdGhlIHBhY2thZ2UKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWEudXRpbHMuZWFzaW5ncywgb3IgYSBjdXN0b20gZWFzaW5nCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtICB7Y2FtZXJhfSAgY2FtZXJhICBUaGUgY2FtZXJhIHRvIGFuaW1hdGUuCi0gICAgICogQHBhcmFtICB7b2JqZWN0fSAgdGFyZ2V0ICBUaGUgY29vcmRpbmF0ZXMgdG8gcmVhY2guCi0gICAgICogQHBhcmFtICB7P29iamVjdH0gb3B0aW9ucyBFdmVudHVhbGx5IGFuIG9iamVjdCB0byBzcGVjaWZ5IHNvbWUgb3B0aW9ucyB0bwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZ1bmN0aW9uLiBUaGUgYXZhaWxhYmxlIG9wdGlvbnMgYXJlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVzZW50ZWQgaW4gdGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBmdW5jdGlvbi4KLSAgICAgKiBAcmV0dXJuIHtudW1iZXJ9ICAgICAgICAgIFRoZSBhbmltYXRpb24gaWQsIHRvIG1ha2UgaXQgZWFzeSB0byBraWxsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdWdoIHRoZSBtZXRob2QgInNpZ21hLm1pc2MuYW5pbWF0aW9uLmtpbGwiLgotICAgICAqLwotICAgIHNpZ21hLm1pc2MuYW5pbWF0aW9uLmNhbWVyYSA9IGZ1bmN0aW9uIChjYW1lcmEsIHZhbCwgb3B0aW9ucykgewotICAgICAgICBpZiAoCi0gICAgICAgICAgICAhKGNhbWVyYSBpbnN0YW5jZW9mIHNpZ21hLmNsYXNzZXMuY2FtZXJhKSB8fAotICAgICAgICAgICAgdHlwZW9mIHZhbCAhPT0gJ29iamVjdCcgfHwgIXZhbAotICAgICAgICApCi0gICAgICAgICAgICB0aHJvdyAnYW5pbWF0aW9uLmNhbWVyYTogV3JvbmcgYXJndW1lbnRzLic7Ci0KLSAgICAgICAgaWYgKAotICAgICAgICAgICAgdHlwZW9mIHZhbC54ICE9PSAnbnVtYmVyJyAmJgotICAgICAgICAgICAgdHlwZW9mIHZhbC55ICE9PSAnbnVtYmVyJyAmJgotICAgICAgICAgICAgdHlwZW9mIHZhbC5yYXRpbyAhPT0gJ251bWJlcicgJiYKLSAgICAgICAgICAgIHR5cGVvZiB2YWwuYW5nbGUgIT09ICdudW1iZXInCi0gICAgICAgICkKLSAgICAgICAgICAgIHRocm93ICdUaGVyZSBtdXN0IGJlIGF0IGxlYXN0IG9uZSB2YWxpZCBjb29yZGluYXRlIGluIHRoZSBnaXZlbiB2YWwuJzsKLQotICAgICAgICB2YXIgZm4sCi0gICAgICAgICAgICBpZCwKLSAgICAgICAgICAgIGFuaW0sCi0gICAgICAgICAgICBlYXNpbmcsCi0gICAgICAgICAgICBkdXJhdGlvbiwKLSAgICAgICAgICAgIGluaXRpYWxWYWwsCi0gICAgICAgICAgICBvID0gb3B0aW9ucyB8fCB7fSwKLSAgICAgICAgICAgIHN0YXJ0ID0gc2lnbWEudXRpbHMuZGF0ZU5vdygpOwotCi0gICAgICAgIC8vIFN0b3JlIGluaXRpYWwgdmFsdWVzOgotICAgICAgICBpbml0aWFsVmFsID0gewotICAgICAgICAgICAgeDogY2FtZXJhLngsCi0gICAgICAgICAgICB5OiBjYW1lcmEueSwKLSAgICAgICAgICAgIHJhdGlvOiBjYW1lcmEucmF0aW8sCi0gICAgICAgICAgICBhbmdsZTogY2FtZXJhLmFuZ2xlCi0gICAgICAgIH07Ci0KLSAgICAgICAgZHVyYXRpb24gPSBvLmR1cmF0aW9uOwotICAgICAgICBlYXNpbmcgPSB0eXBlb2Ygby5lYXNpbmcgIT09ICdmdW5jdGlvbicgPwotICAgICAgICAgICAgc2lnbWEudXRpbHMuZWFzaW5nc1tvLmVhc2luZyB8fCAncXVhZHJhdGljSW5PdXQnXSA6Ci0gICAgICAgICAgICBvLmVhc2luZzsKLQotICAgICAgICBmbiA9IGZ1bmN0aW9uICgpIHsKLSAgICAgICAgICAgIHZhciBjb2VmLAotICAgICAgICAgICAgICAgIHQgPSBvLmR1cmF0aW9uID8gKHNpZ21hLnV0aWxzLmRhdGVOb3coKSAtIHN0YXJ0KSAvIG8uZHVyYXRpb24gOiAxOwotCi0gICAgICAgICAgICAvLyBJZiB0aGUgYW5pbWF0aW9uIGlzIG92ZXI6Ci0gICAgICAgICAgICBpZiAodCA+PSAxKSB7Ci0gICAgICAgICAgICAgICAgY2FtZXJhLmlzQW5pbWF0ZWQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICBjYW1lcmEuZ29Ubyh7Ci0gICAgICAgICAgICAgICAgICAgIHg6IHZhbC54ICE9PSB1bmRlZmluZWQgPyB2YWwueCA6IGluaXRpYWxWYWwueCwKLSAgICAgICAgICAgICAgICAgICAgeTogdmFsLnkgIT09IHVuZGVmaW5lZCA/IHZhbC55IDogaW5pdGlhbFZhbC55LAotICAgICAgICAgICAgICAgICAgICByYXRpbzogdmFsLnJhdGlvICE9PSB1bmRlZmluZWQgPyB2YWwucmF0aW8gOiBpbml0aWFsVmFsLnJhdGlvLAotICAgICAgICAgICAgICAgICAgICBhbmdsZTogdmFsLmFuZ2xlICE9PSB1bmRlZmluZWQgPyB2YWwuYW5nbGUgOiBpbml0aWFsVmFsLmFuZ2xlCi0gICAgICAgICAgICAgICAgfSk7Ci0KLSAgICAgICAgICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZShpZCk7Ci0gICAgICAgICAgICAgICAgZGVsZXRlIHNpZ21hLm1pc2MuYW5pbWF0aW9uLnJ1bm5pbmdbaWRdOwotCi0gICAgICAgICAgICAgICAgLy8gQ2hlY2sgY2FsbGJhY2tzOgotICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygby5vbkNvbXBsZXRlID09PSAnZnVuY3Rpb24nKQotICAgICAgICAgICAgICAgICAgICBvLm9uQ29tcGxldGUoKTsKLQotICAgICAgICAgICAgICAgIC8vIEVsc2UsIGxldCdzIGtlZXAgZ29pbmc6Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGNvZWYgPSBlYXNpbmcodCk7Ci0gICAgICAgICAgICAgICAgY2FtZXJhLmlzQW5pbWF0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIGNhbWVyYS5nb1RvKHsKLSAgICAgICAgICAgICAgICAgICAgeDogdmFsLnggIT09IHVuZGVmaW5lZCA/Ci0gICAgICAgICAgICAgICAgICAgIGluaXRpYWxWYWwueCArICh2YWwueCAtIGluaXRpYWxWYWwueCkgKiBjb2VmIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGluaXRpYWxWYWwueCwKLSAgICAgICAgICAgICAgICAgICAgeTogdmFsLnkgIT09IHVuZGVmaW5lZCA/Ci0gICAgICAgICAgICAgICAgICAgIGluaXRpYWxWYWwueSArICh2YWwueSAtIGluaXRpYWxWYWwueSkgKiBjb2VmIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGluaXRpYWxWYWwueSwKLSAgICAgICAgICAgICAgICAgICAgcmF0aW86IHZhbC5yYXRpbyAhPT0gdW5kZWZpbmVkID8KLSAgICAgICAgICAgICAgICAgICAgaW5pdGlhbFZhbC5yYXRpbyArICh2YWwucmF0aW8gLSBpbml0aWFsVmFsLnJhdGlvKSAqIGNvZWYgOgotICAgICAgICAgICAgICAgICAgICAgICAgaW5pdGlhbFZhbC5yYXRpbywKLSAgICAgICAgICAgICAgICAgICAgYW5nbGU6IHZhbC5hbmdsZSAhPT0gdW5kZWZpbmVkID8KLSAgICAgICAgICAgICAgICAgICAgaW5pdGlhbFZhbC5hbmdsZSArICh2YWwuYW5nbGUgLSBpbml0aWFsVmFsLmFuZ2xlKSAqIGNvZWYgOgotICAgICAgICAgICAgICAgICAgICAgICAgaW5pdGlhbFZhbC5hbmdsZQotICAgICAgICAgICAgICAgIH0pOwotCi0gICAgICAgICAgICAgICAgLy8gQ2hlY2sgY2FsbGJhY2tzOgotICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygby5vbk5ld0ZyYW1lID09PSAnZnVuY3Rpb24nKQotICAgICAgICAgICAgICAgICAgICBvLm9uTmV3RnJhbWUoKTsKLQotICAgICAgICAgICAgICAgIGFuaW0uZnJhbWVJZCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShmbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH07Ci0KLSAgICAgICAgaWQgPSBfZ2V0SUQoKTsKLSAgICAgICAgYW5pbSA9IHsKLSAgICAgICAgICAgIGZyYW1lSWQ6IHJlcXVlc3RBbmltYXRpb25GcmFtZShmbiksCi0gICAgICAgICAgICB0YXJnZXQ6IGNhbWVyYSwKLSAgICAgICAgICAgIHR5cGU6ICdjYW1lcmEnLAotICAgICAgICAgICAgb3B0aW9uczogbywKLSAgICAgICAgICAgIGZuOiBmbgotICAgICAgICB9OwotICAgICAgICBzaWdtYS5taXNjLmFuaW1hdGlvbi5ydW5uaW5nW2lkXSA9IGFuaW07Ci0KLSAgICAgICAgcmV0dXJuIGlkOwotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBLaWxscyBhIHJ1bm5pbmcgYW5pbWF0aW9uLiBJdCB0cmlnZ2VycyB0aGUgZXZlbnR1YWwgb25Db21wbGV0ZSBjYWxsYmFjay4KLSAgICAgKgotICAgICAqIEBwYXJhbSAge251bWJlcn0gaWQgIFRoZSBpZCBvZiB0aGUgYW5pbWF0aW9uIHRvIGtpbGwuCi0gICAgICogQHJldHVybiB7b2JqZWN0fSAgICAgUmV0dXJucyB0aGUgc2lnbWEubWlzYy5hbmltYXRpb24gcGFja2FnZS4KLSAgICAgKi8KLSAgICBzaWdtYS5taXNjLmFuaW1hdGlvbi5raWxsID0gZnVuY3Rpb24gKGlkKSB7Ci0gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICE9PSAxIHx8IHR5cGVvZiBpZCAhPT0gJ251bWJlcicpCi0gICAgICAgICAgICB0aHJvdyAnYW5pbWF0aW9uLmtpbGw6IFdyb25nIGFyZ3VtZW50cy4nOwotCi0gICAgICAgIHZhciBvID0gc2lnbWEubWlzYy5hbmltYXRpb24ucnVubmluZ1tpZF07Ci0KLSAgICAgICAgaWYgKG8pIHsKLSAgICAgICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKGlkKTsKLSAgICAgICAgICAgIGRlbGV0ZSBzaWdtYS5taXNjLmFuaW1hdGlvbi5ydW5uaW5nW28uZnJhbWVJZF07Ci0KLSAgICAgICAgICAgIGlmIChvLnR5cGUgPT09ICdjYW1lcmEnKQotICAgICAgICAgICAgICAgIG8udGFyZ2V0LmlzQW5pbWF0ZWQgPSBmYWxzZTsKLQotICAgICAgICAgICAgLy8gQ2hlY2sgY2FsbGJhY2tzOgotICAgICAgICAgICAgaWYgKHR5cGVvZiAoby5vcHRpb25zIHx8IHt9KS5vbkNvbXBsZXRlID09PSAnZnVuY3Rpb24nKQotICAgICAgICAgICAgICAgIG8ub3B0aW9ucy5vbkNvbXBsZXRlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogS2lsbHMgZXZlcnkgcnVubmluZyBhbmltYXRpb25zLCBvciBvbmx5IHRoZSBvbmUgd2l0aCB0aGUgc3BlY2lmaWVkIHR5cGUsCi0gICAgICogaWYgYSBzdHJpbmcgcGFyYW1ldGVyIGlzIGdpdmVuLgotICAgICAqCi0gICAgICogQHBhcmFtICB7PyhzdHJpbmd8b2JqZWN0KX0gZmlsdGVyIEEgc3RyaW5nIHRvIGZpbHRlciB0aGUgYW5pbWF0aW9ucyB0byBraWxsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uIHRoZWlyIHR5cGUgKGV4YW1wbGU6ICJjYW1lcmEiKSwgb3IgYW4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0IHRvIGZpbHRlciBvbiB0aGVpciB0YXJnZXQuCi0gICAgICogQHJldHVybiB7bnVtYmVyfSAgICAgICAgICAgICAgICAgIFJldHVybnMgdGhlIG51bWJlciBvZiBhbmltYXRpb25zIGtpbGxlZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0IHdheS4KLSAgICAgKi8KLSAgICBzaWdtYS5taXNjLmFuaW1hdGlvbi5raWxsQWxsID0gZnVuY3Rpb24gKGZpbHRlcikgewotICAgICAgICB2YXIgbywKLSAgICAgICAgICAgIGlkLAotICAgICAgICAgICAgY291bnQgPSAwLAotICAgICAgICAgICAgdHlwZSA9IHR5cGVvZiBmaWx0ZXIgPT09ICdzdHJpbmcnID8gZmlsdGVyIDogbnVsbCwKLSAgICAgICAgICAgIHRhcmdldCA9IHR5cGVvZiBmaWx0ZXIgPT09ICdvYmplY3QnID8gZmlsdGVyIDogbnVsbCwKLSAgICAgICAgICAgIHJ1bm5pbmcgPSBzaWdtYS5taXNjLmFuaW1hdGlvbi5ydW5uaW5nOwotCi0gICAgICAgIGZvciAoaWQgaW4gcnVubmluZykKLSAgICAgICAgICAgIGlmICgKLSAgICAgICAgICAgICAgICAoIXR5cGUgfHwgcnVubmluZ1tpZF0udHlwZSA9PT0gdHlwZSkgJiYKLSAgICAgICAgICAgICAgICAoIXRhcmdldCB8fCBydW5uaW5nW2lkXS50YXJnZXQgPT09IHRhcmdldCkKLSAgICAgICAgICAgICkgewotICAgICAgICAgICAgICAgIG8gPSBzaWdtYS5taXNjLmFuaW1hdGlvbi5ydW5uaW5nW2lkXTsKLSAgICAgICAgICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZShvLmZyYW1lSWQpOwotICAgICAgICAgICAgICAgIGRlbGV0ZSBzaWdtYS5taXNjLmFuaW1hdGlvbi5ydW5uaW5nW2lkXTsKLQotICAgICAgICAgICAgICAgIGlmIChvLnR5cGUgPT09ICdjYW1lcmEnKQotICAgICAgICAgICAgICAgICAgICBvLnRhcmdldC5pc0FuaW1hdGVkID0gZmFsc2U7Ci0KLSAgICAgICAgICAgICAgICAvLyBJbmNyZW1lbnQgY291bnRlcjoKLSAgICAgICAgICAgICAgICBjb3VudCsrOwotCi0gICAgICAgICAgICAgICAgLy8gQ2hlY2sgY2FsbGJhY2tzOgotICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgKG8ub3B0aW9ucyB8fCB7fSkub25Db21wbGV0ZSA9PT0gJ2Z1bmN0aW9uJykKLSAgICAgICAgICAgICAgICAgICAgby5vcHRpb25zLm9uQ29tcGxldGUoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICByZXR1cm4gY291bnQ7Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgInRydWUiIGlmIGFueSBhbmltYXRpb24gdGhhdCBpcyBjdXJyZW50bHkgc3RpbGwgcnVubmluZyBtYXRjaGVzCi0gICAgICogdGhlIGZpbHRlciBnaXZlbiB0byB0aGUgZnVuY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHtzdHJpbmd8b2JqZWN0fSBmaWx0ZXIgQSBzdHJpbmcgdG8gZmlsdGVyIHRoZSBhbmltYXRpb25zIHRvIGtpbGwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb24gdGhlaXIgdHlwZSAoZXhhbXBsZTogImNhbWVyYSIpLCBvciBhbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QgdG8gZmlsdGVyIG9uIHRoZWlyIHRhcmdldC4KLSAgICAgKiBAcmV0dXJuIHtib29sZWFufSAgICAgICAgICAgICAgUmV0dXJucyB0cnVlIGlmIGFueSBydW5uaW5nIGFuaW1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaGVzLgotICAgICAqLwotICAgIHNpZ21hLm1pc2MuYW5pbWF0aW9uLmhhcyA9IGZ1bmN0aW9uIChmaWx0ZXIpIHsKLSAgICAgICAgdmFyIGlkLAotICAgICAgICAgICAgdHlwZSA9IHR5cGVvZiBmaWx0ZXIgPT09ICdzdHJpbmcnID8gZmlsdGVyIDogbnVsbCwKLSAgICAgICAgICAgIHRhcmdldCA9IHR5cGVvZiBmaWx0ZXIgPT09ICdvYmplY3QnID8gZmlsdGVyIDogbnVsbCwKLSAgICAgICAgICAgIHJ1bm5pbmcgPSBzaWdtYS5taXNjLmFuaW1hdGlvbi5ydW5uaW5nOwotCi0gICAgICAgIGZvciAoaWQgaW4gcnVubmluZykKLSAgICAgICAgICAgIGlmICgKLSAgICAgICAgICAgICAgICAoIXR5cGUgfHwgcnVubmluZ1tpZF0udHlwZSA9PT0gdHlwZSkgJiYKLSAgICAgICAgICAgICAgICAoIXRhcmdldCB8fCBydW5uaW5nW2lkXS50YXJnZXQgPT09IHRhcmdldCkKLSAgICAgICAgICAgICkKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfTsKLX0pLmNhbGwodGhpcyk7Ci0KLTsoZnVuY3Rpb24gKHVuZGVmaW5lZCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIGlmICh0eXBlb2Ygc2lnbWEgPT09ICd1bmRlZmluZWQnKQotICAgICAgICB0aHJvdyAnc2lnbWEgaXMgbm90IGRlY2xhcmVkJzsKLQotICAgIC8vIEluaXRpYWxpemUgcGFja2FnZXM6Ci0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5taXNjJyk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGhlbHBlciB3aWxsIGJpbmQgYW55IG5vLURPTSByZW5kZXJlciAoZm9yIGluc3RhbmNlIGNhbnZhcyBvciBXZWJHTCkKLSAgICAgKiB0byBpdHMgY2FwdG9ycywgdG8gcHJvcGVybHkgZGlzcGF0Y2ggdGhlIGdvb2QgZXZlbnRzIHRvIHRoZSBzaWdtYSBpbnN0YW5jZQotICAgICAqIHRvIG1hbmFnZSBjbGlja2luZywgaG92ZXJpbmcgZXRjLi4uCi0gICAgICoKLSAgICAgKiBJdCBoYXMgdG8gYmUgY2FsbGVkIGluIHRoZSBzY29wZSBvZiB0aGUgcmVsYXRlZCByZW5kZXJlci4KLSAgICAgKi8KLSAgICBzaWdtYS5taXNjLmJpbmRFdmVudHMgPSBmdW5jdGlvbiAocHJlZml4KSB7Ci0gICAgICAgIHZhciBpLAotICAgICAgICAgICAgbCwKLSAgICAgICAgICAgIG1YLAotICAgICAgICAgICAgbVksCi0gICAgICAgICAgICBjYXB0b3IsCi0gICAgICAgICAgICBzZWxmID0gdGhpczsKLQotICAgICAgICBmdW5jdGlvbiBnZXROb2RlcyhlKSB7Ci0gICAgICAgICAgICBpZiAoZSkgewotICAgICAgICAgICAgICAgIG1YID0gJ3gnIGluIGUuZGF0YSA/IGUuZGF0YS54IDogbVg7Ci0gICAgICAgICAgICAgICAgbVkgPSAneScgaW4gZS5kYXRhID8gZS5kYXRhLnkgOiBtWTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgdmFyIGksCi0gICAgICAgICAgICAgICAgaiwKLSAgICAgICAgICAgICAgICBsLAotICAgICAgICAgICAgICAgIG4sCi0gICAgICAgICAgICAgICAgeCwKLSAgICAgICAgICAgICAgICB5LAotICAgICAgICAgICAgICAgIHMsCi0gICAgICAgICAgICAgICAgaW5zZXJ0ZWQsCi0gICAgICAgICAgICAgICAgc2VsZWN0ZWQgPSBbXSwKLSAgICAgICAgICAgICAgICBtb2RpZmllZFggPSBtWCArIHNlbGYud2lkdGggLyAyLAotICAgICAgICAgICAgICAgIG1vZGlmaWVkWSA9IG1ZICsgc2VsZi5oZWlnaHQgLyAyLAotICAgICAgICAgICAgICAgIHBvaW50ID0gc2VsZi5jYW1lcmEuY2FtZXJhUG9zaXRpb24oCi0gICAgICAgICAgICAgICAgICAgIG1YLAotICAgICAgICAgICAgICAgICAgICBtWQotICAgICAgICAgICAgICAgICksCi0gICAgICAgICAgICAgICAgbm9kZXMgPSBzZWxmLmNhbWVyYS5xdWFkdHJlZS5wb2ludCgKLSAgICAgICAgICAgICAgICAgICAgcG9pbnQueCwKLSAgICAgICAgICAgICAgICAgICAgcG9pbnQueQotICAgICAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgIGlmIChub2Rlcy5sZW5ndGgpCi0gICAgICAgICAgICAgICAgZm9yIChpID0gMCwgbCA9IG5vZGVzLmxlbmd0aDsgaSA8IGw7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBuID0gbm9kZXNbaV07Ci0gICAgICAgICAgICAgICAgICAgIHggPSBuW3ByZWZpeCArICd4J107Ci0gICAgICAgICAgICAgICAgICAgIHkgPSBuW3ByZWZpeCArICd5J107Ci0gICAgICAgICAgICAgICAgICAgIHMgPSBuW3ByZWZpeCArICdzaXplJ107Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKAotICAgICAgICAgICAgICAgICAgICAgICAgIW4uaGlkZGVuICYmCi0gICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmllZFggPiB4IC0gcyAmJgotICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZWRYIDwgeCArIHMgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmaWVkWSA+IHkgLSBzICYmCi0gICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmllZFkgPCB5ICsgcyAmJgotICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5zcXJ0KAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGgucG93KG1vZGlmaWVkWCAtIHgsIDIpICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXRoLnBvdyhtb2RpZmllZFkgLSB5LCAyKQotICAgICAgICAgICAgICAgICAgICAgICAgKSA8IHMKLSAgICAgICAgICAgICAgICAgICAgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnNlcnQgdGhlIG5vZGU6Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnRlZCA9IGZhbHNlOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgc2VsZWN0ZWQubGVuZ3RoOyBqKyspCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG4uc2l6ZSA+IHNlbGVjdGVkW2pdLnNpemUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQuc3BsaWNlKGosIDAsIG4pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnRlZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpbnNlcnRlZCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZC5wdXNoKG4pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gc2VsZWN0ZWQ7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIGZ1bmN0aW9uIGdldEVkZ2VzKGUpIHsKLSAgICAgICAgICAgIGlmICghc2VsZi5zZXR0aW5ncygnZW5hYmxlRWRnZUhvdmVyaW5nJykpIHsKLSAgICAgICAgICAgICAgICAvLyBObyBldmVudCBpZiB0aGUgc2V0dGluZyBpcyBvZmY6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFtdOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB2YXIgaXNDYW52YXMgPSAoCi0gICAgICAgICAgICBzaWdtYS5yZW5kZXJlcnMuY2FudmFzICYmIHNlbGYgaW5zdGFuY2VvZiBzaWdtYS5yZW5kZXJlcnMuY2FudmFzKTsKLQotICAgICAgICAgICAgaWYgKCFpc0NhbnZhcykgewotICAgICAgICAgICAgICAgIC8vIEEgcXVpY2sgaGFyZGNvZGVkIHJ1bGUgdG8gcHJldmVudCBwZW9wbGUgZnJvbSB1c2luZyB0aGlzIGZlYXR1cmUKLSAgICAgICAgICAgICAgICAvLyB3aXRoIHRoZSBXZWJHTCByZW5kZXJlciAod2hpY2ggaXMgbm90IGdvb2QgZW5vdWdoIGF0IHRoZSBtb21lbnQpOgotICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgJ1RoZSBlZGdlIGV2ZW50cyBmZWF0dXJlIGlzIG5vdCBjb21wYXRpYmxlIHdpdGggdGhlIFdlYkdMIHJlbmRlcmVyJwotICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChlKSB7Ci0gICAgICAgICAgICAgICAgbVggPSAneCcgaW4gZS5kYXRhID8gZS5kYXRhLnggOiBtWDsKLSAgICAgICAgICAgICAgICBtWSA9ICd5JyBpbiBlLmRhdGEgPyBlLmRhdGEueSA6IG1ZOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB2YXIgaSwKLSAgICAgICAgICAgICAgICBqLAotICAgICAgICAgICAgICAgIGwsCi0gICAgICAgICAgICAgICAgYSwKLSAgICAgICAgICAgICAgICBlZGdlLAotICAgICAgICAgICAgICAgIHMsCi0gICAgICAgICAgICAgICAgbWF4RXBzaWxvbiA9IHNlbGYuc2V0dGluZ3MoJ2VkZ2VIb3ZlclByZWNpc2lvbicpLAotICAgICAgICAgICAgICAgIHNvdXJjZSwKLSAgICAgICAgICAgICAgICB0YXJnZXQsCi0gICAgICAgICAgICAgICAgY3AsCi0gICAgICAgICAgICAgICAgbm9kZUluZGV4ID0ge30sCi0gICAgICAgICAgICAgICAgaW5zZXJ0ZWQsCi0gICAgICAgICAgICAgICAgc2VsZWN0ZWQgPSBbXSwKLSAgICAgICAgICAgICAgICBtb2RpZmllZFggPSBtWCArIHNlbGYud2lkdGggLyAyLAotICAgICAgICAgICAgICAgIG1vZGlmaWVkWSA9IG1ZICsgc2VsZi5oZWlnaHQgLyAyLAotICAgICAgICAgICAgICAgIHBvaW50ID0gc2VsZi5jYW1lcmEuY2FtZXJhUG9zaXRpb24oCi0gICAgICAgICAgICAgICAgICAgIG1YLAotICAgICAgICAgICAgICAgICAgICBtWQotICAgICAgICAgICAgICAgICksCi0gICAgICAgICAgICAgICAgZWRnZXMgPSBbXTsKLQotICAgICAgICAgICAgaWYgKGlzQ2FudmFzKSB7Ci0gICAgICAgICAgICAgICAgdmFyIG5vZGVzT25TY3JlZW4gPSBzZWxmLmNhbWVyYS5xdWFkdHJlZS5hcmVhKAotICAgICAgICAgICAgICAgICAgICBzZWxmLmNhbWVyYS5nZXRSZWN0YW5nbGUoc2VsZi53aWR0aCwgc2VsZi5oZWlnaHQpCi0gICAgICAgICAgICAgICAgKTsKLSAgICAgICAgICAgICAgICBmb3IgKGEgPSBub2Rlc09uU2NyZWVuLCBpID0gMCwgbCA9IGEubGVuZ3RoOyBpIDwgbDsgaSsrKQotICAgICAgICAgICAgICAgICAgICBub2RlSW5kZXhbYVtpXS5pZF0gPSBhW2ldOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoc2VsZi5jYW1lcmEuZWRnZXF1YWR0cmVlICE9PSB1bmRlZmluZWQpIHsKLSAgICAgICAgICAgICAgICBlZGdlcyA9IHNlbGYuY2FtZXJhLmVkZ2VxdWFkdHJlZS5wb2ludCgKLSAgICAgICAgICAgICAgICAgICAgcG9pbnQueCwKLSAgICAgICAgICAgICAgICAgICAgcG9pbnQueQotICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZ1bmN0aW9uIGluc2VydEVkZ2Uoc2VsZWN0ZWQsIGVkZ2UpIHsKLSAgICAgICAgICAgICAgICBpbnNlcnRlZCA9IGZhbHNlOwotCi0gICAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IHNlbGVjdGVkLmxlbmd0aDsgaisrKQotICAgICAgICAgICAgICAgICAgICBpZiAoZWRnZS5zaXplID4gc2VsZWN0ZWRbal0uc2l6ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQuc3BsaWNlKGosIDAsIGVkZ2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgaW5zZXJ0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmICghaW5zZXJ0ZWQpCi0gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkLnB1c2goZWRnZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChlZGdlcy5sZW5ndGgpCi0gICAgICAgICAgICAgICAgZm9yIChpID0gMCwgbCA9IGVkZ2VzLmxlbmd0aDsgaSA8IGw7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBlZGdlID0gZWRnZXNbaV07Ci0gICAgICAgICAgICAgICAgICAgIHNvdXJjZSA9IHNlbGYuZ3JhcGgubm9kZXMoZWRnZS5zb3VyY2UpOwotICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPSBzZWxmLmdyYXBoLm5vZGVzKGVkZ2UudGFyZ2V0KTsKLSAgICAgICAgICAgICAgICAgICAgLy8gKEhBQ0spIHdlIGNhbid0IGdldCBlZGdlW3ByZWZpeCArICdzaXplJ10gb24gV2ViR0wgcmVuZGVyZXI6Ci0gICAgICAgICAgICAgICAgICAgIHMgPSBlZGdlW3ByZWZpeCArICdzaXplJ10gfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2VbJ3JlYWRfJyArIHByZWZpeCArICdzaXplJ107Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gRmlyc3QsIGxldCdzIGlkZW50aWZ5IHdoaWNoIGVkZ2VzIGFyZSBkcmF3bi4gVG8gZG8gdGhpcywgd2Uga2VlcAotICAgICAgICAgICAgICAgICAgICAvLyBldmVyeSBlZGdlcyB0aGF0IGhhdmUgYXQgbGVhc3Qgb25lIGV4dHJlbWl0eSBkaXNwbGF5ZWQgYWNjb3JkaW5nIHRvCi0gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBxdWFkdHJlZSBhbmQgdGhlICJoaWRkZW4iIGF0dHJpYnV0ZS4gV2UgYWxzbyBkbyBub3Qga2VlcCBoaWRkZW4KLSAgICAgICAgICAgICAgICAgICAgLy8gZWRnZXMuCi0gICAgICAgICAgICAgICAgICAgIC8vIFRoZW4sIGxldCdzIGNoZWNrIGlmIHRoZSBtb3VzZSBpcyBvbiB0aGUgZWRnZSAod2Ugc3VwcG9zZSB0aGF0IGl0Ci0gICAgICAgICAgICAgICAgICAgIC8vIGlzIGEgbGluZSBzZWdtZW50KS4KLQotICAgICAgICAgICAgICAgICAgICBpZiAoCi0gICAgICAgICAgICAgICAgICAgICAgICAhZWRnZS5oaWRkZW4gJiYgIXNvdXJjZS5oaWRkZW4gJiYgIXRhcmdldC5oaWRkZW4gJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICghaXNDYW52YXMgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIChub2RlSW5kZXhbZWRnZS5zb3VyY2VdIHx8IG5vZGVJbmRleFtlZGdlLnRhcmdldF0pKSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWEudXRpbHMuZ2V0RGlzdGFuY2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlW3ByZWZpeCArICd4J10sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlW3ByZWZpeCArICd5J10sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZWRYLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmaWVkWSkgPiBzb3VyY2VbcHJlZml4ICsgJ3NpemUnXSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWEudXRpbHMuZ2V0RGlzdGFuY2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3ByZWZpeCArICd4J10sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3ByZWZpeCArICd5J10sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZWRYLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmaWVkWSkgPiB0YXJnZXRbcHJlZml4ICsgJ3NpemUnXQotICAgICAgICAgICAgICAgICAgICApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlZGdlLnR5cGUgPT0gJ2N1cnZlJyB8fCBlZGdlLnR5cGUgPT0gJ2N1cnZlZEFycm93JykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuaWQgPT09IHRhcmdldC5pZCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcCA9IHNpZ21hLnV0aWxzLmdldFNlbGZMb29wQ29udHJvbFBvaW50cygKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZVtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlW3ByZWZpeCArICd5J10sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VbcHJlZml4ICsgJ3NpemUnXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWdtYS51dGlscy5pc1BvaW50T25CZXppZXJDdXJ2ZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmllZFgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZWRZLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZVtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZVtwcmVmaXggKyAneSddLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFtwcmVmaXggKyAneSddLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwLngxLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwLnkxLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwLngyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwLnkyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGgubWF4KHMsIG1heEVwc2lsb24pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnRFZGdlKHNlbGVjdGVkLCBlZGdlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3AgPSBzaWdtYS51dGlscy5nZXRRdWFkcmF0aWNDb250cm9sUG9pbnQoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VbcHJlZml4ICsgJ3gnXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZVtwcmVmaXggKyAneSddLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3ByZWZpeCArICd4J10sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRbcHJlZml4ICsgJ3knXSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ21hLnV0aWxzLmlzUG9pbnRPblF1YWRyYXRpY0N1cnZlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmaWVkWCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmllZFksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlW3ByZWZpeCArICd4J10sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlW3ByZWZpeCArICd5J10sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3ByZWZpeCArICd4J10sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3ByZWZpeCArICd5J10sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3AueCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcC55LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGgubWF4KHMsIG1heEVwc2lsb24pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnRFZGdlKHNlbGVjdGVkLCBlZGdlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWEudXRpbHMuaXNQb2ludE9uU2VnbWVudCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZWRYLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmllZFksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZVtwcmVmaXggKyAneCddLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VbcHJlZml4ICsgJ3knXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3ByZWZpeCArICd4J10sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFtwcmVmaXggKyAneSddLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXRoLm1heChzLCBtYXhFcHNpbG9uKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnRFZGdlKHNlbGVjdGVkLCBlZGdlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGVkOwotICAgICAgICB9Ci0KLQotICAgICAgICBmdW5jdGlvbiBiaW5kQ2FwdG9yKGNhcHRvcikgewotICAgICAgICAgICAgdmFyIG5vZGVzLAotICAgICAgICAgICAgICAgIGVkZ2VzLAotICAgICAgICAgICAgICAgIG92ZXJOb2RlcyA9IHt9LAotICAgICAgICAgICAgICAgIG92ZXJFZGdlcyA9IHt9OwotCi0gICAgICAgICAgICBmdW5jdGlvbiBvbkNsaWNrKGUpIHsKLSAgICAgICAgICAgICAgICBpZiAoIXNlbGYuc2V0dGluZ3MoJ2V2ZW50c0VuYWJsZWQnKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KCdjbGljaycsIGUuZGF0YSk7Ci0KLSAgICAgICAgICAgICAgICBub2RlcyA9IGdldE5vZGVzKGUpOwotICAgICAgICAgICAgICAgIGVkZ2VzID0gZ2V0RWRnZXMoZSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAobm9kZXMubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgnY2xpY2tOb2RlJywgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogbm9kZXNbMF0sCi0gICAgICAgICAgICAgICAgICAgICAgICBjYXB0b3I6IGUuZGF0YQotICAgICAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KCdjbGlja05vZGVzJywgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogbm9kZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICBjYXB0b3I6IGUuZGF0YQotICAgICAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVkZ2VzLmxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoJ2NsaWNrRWRnZScsIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2U6IGVkZ2VzWzBdLAotICAgICAgICAgICAgICAgICAgICAgICAgY2FwdG9yOiBlLmRhdGEKLSAgICAgICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgnY2xpY2tFZGdlcycsIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2U6IGVkZ2VzLAotICAgICAgICAgICAgICAgICAgICAgICAgY2FwdG9yOiBlLmRhdGEKLSAgICAgICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgnY2xpY2tTdGFnZScsIHtjYXB0b3I6IGUuZGF0YX0pOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmdW5jdGlvbiBvbkRvdWJsZUNsaWNrKGUpIHsKLSAgICAgICAgICAgICAgICBpZiAoIXNlbGYuc2V0dGluZ3MoJ2V2ZW50c0VuYWJsZWQnKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KCdkb3VibGVDbGljaycsIGUuZGF0YSk7Ci0KLSAgICAgICAgICAgICAgICBub2RlcyA9IGdldE5vZGVzKGUpOwotICAgICAgICAgICAgICAgIGVkZ2VzID0gZ2V0RWRnZXMoZSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAobm9kZXMubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgnZG91YmxlQ2xpY2tOb2RlJywgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogbm9kZXNbMF0sCi0gICAgICAgICAgICAgICAgICAgICAgICBjYXB0b3I6IGUuZGF0YQotICAgICAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KCdkb3VibGVDbGlja05vZGVzJywgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogbm9kZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICBjYXB0b3I6IGUuZGF0YQotICAgICAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVkZ2VzLmxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoJ2RvdWJsZUNsaWNrRWRnZScsIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2U6IGVkZ2VzWzBdLAotICAgICAgICAgICAgICAgICAgICAgICAgY2FwdG9yOiBlLmRhdGEKLSAgICAgICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgnZG91YmxlQ2xpY2tFZGdlcycsIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2U6IGVkZ2VzLAotICAgICAgICAgICAgICAgICAgICAgICAgY2FwdG9yOiBlLmRhdGEKLSAgICAgICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgnZG91YmxlQ2xpY2tTdGFnZScsIHtjYXB0b3I6IGUuZGF0YX0pOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmdW5jdGlvbiBvblJpZ2h0Q2xpY2soZSkgewotICAgICAgICAgICAgICAgIGlmICghc2VsZi5zZXR0aW5ncygnZXZlbnRzRW5hYmxlZCcpKQotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0KLSAgICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoJ3JpZ2h0Q2xpY2snLCBlLmRhdGEpOwotCi0gICAgICAgICAgICAgICAgbm9kZXMgPSBnZXROb2RlcyhlKTsKLSAgICAgICAgICAgICAgICBlZGdlcyA9IGdldEVkZ2VzKGUpOwotCi0gICAgICAgICAgICAgICAgaWYgKG5vZGVzLmxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoJ3JpZ2h0Q2xpY2tOb2RlJywgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogbm9kZXNbMF0sCi0gICAgICAgICAgICAgICAgICAgICAgICBjYXB0b3I6IGUuZGF0YQotICAgICAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KCdyaWdodENsaWNrTm9kZXMnLCB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2RlOiBub2RlcywKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRvcjogZS5kYXRhCi0gICAgICAgICAgICAgICAgICAgIH0pOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZWRnZXMubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgncmlnaHRDbGlja0VkZ2UnLCB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlZGdlOiBlZGdlc1swXSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRvcjogZS5kYXRhCi0gICAgICAgICAgICAgICAgICAgIH0pOwotICAgICAgICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoJ3JpZ2h0Q2xpY2tFZGdlcycsIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2U6IGVkZ2VzLAotICAgICAgICAgICAgICAgICAgICAgICAgY2FwdG9yOiBlLmRhdGEKLSAgICAgICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgncmlnaHRDbGlja1N0YWdlJywge2NhcHRvcjogZS5kYXRhfSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZ1bmN0aW9uIG9uT3V0KGUpIHsKLSAgICAgICAgICAgICAgICBpZiAoIXNlbGYuc2V0dGluZ3MoJ2V2ZW50c0VuYWJsZWQnKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgICAgICAgICAgdmFyIGssCi0gICAgICAgICAgICAgICAgICAgIGksCi0gICAgICAgICAgICAgICAgICAgIGwsCi0gICAgICAgICAgICAgICAgICAgIGxlLAotICAgICAgICAgICAgICAgICAgICBvdXROb2RlcyA9IFtdLAotICAgICAgICAgICAgICAgICAgICBvdXRFZGdlcyA9IFtdOwotCi0gICAgICAgICAgICAgICAgZm9yIChrIGluIG92ZXJOb2RlcykKLSAgICAgICAgICAgICAgICAgICAgb3V0Tm9kZXMucHVzaChvdmVyTm9kZXNba10pOwotCi0gICAgICAgICAgICAgICAgb3Zlck5vZGVzID0ge307Ci0gICAgICAgICAgICAgICAgLy8gRGlzcGF0Y2ggYm90aCBzaW5nbGUgYW5kIG11bHRpIGV2ZW50czoKLSAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gb3V0Tm9kZXMubGVuZ3RoOyBpIDwgbDsgaSsrKQotICAgICAgICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoJ291dE5vZGUnLCB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2RlOiBvdXROb2Rlc1tpXSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRvcjogZS5kYXRhCi0gICAgICAgICAgICAgICAgICAgIH0pOwotICAgICAgICAgICAgICAgIGlmIChvdXROb2Rlcy5sZW5ndGgpCi0gICAgICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgnb3V0Tm9kZXMnLCB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2Rlczogb3V0Tm9kZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICBjYXB0b3I6IGUuZGF0YQotICAgICAgICAgICAgICAgICAgICB9KTsKLQotICAgICAgICAgICAgICAgIG92ZXJFZGdlcyA9IHt9OwotICAgICAgICAgICAgICAgIC8vIERpc3BhdGNoIGJvdGggc2luZ2xlIGFuZCBtdWx0aSBldmVudHM6Ci0gICAgICAgICAgICAgICAgZm9yIChpID0gMCwgbGUgPSBvdXRFZGdlcy5sZW5ndGg7IGkgPCBsZTsgaSsrKQotICAgICAgICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoJ291dEVkZ2UnLCB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlZGdlOiBvdXRFZGdlc1tpXSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRvcjogZS5kYXRhCi0gICAgICAgICAgICAgICAgICAgIH0pOwotICAgICAgICAgICAgICAgIGlmIChvdXRFZGdlcy5sZW5ndGgpCi0gICAgICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgnb3V0RWRnZXMnLCB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlZGdlczogb3V0RWRnZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICBjYXB0b3I6IGUuZGF0YQotICAgICAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZnVuY3Rpb24gb25Nb3ZlKGUpIHsKLSAgICAgICAgICAgICAgICBpZiAoIXNlbGYuc2V0dGluZ3MoJ2V2ZW50c0VuYWJsZWQnKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgICAgICAgICAgbm9kZXMgPSBnZXROb2RlcyhlKTsKLSAgICAgICAgICAgICAgICBlZGdlcyA9IGdldEVkZ2VzKGUpOwotCi0gICAgICAgICAgICAgICAgdmFyIGksCi0gICAgICAgICAgICAgICAgICAgIGssCi0gICAgICAgICAgICAgICAgICAgIG5vZGUsCi0gICAgICAgICAgICAgICAgICAgIGVkZ2UsCi0gICAgICAgICAgICAgICAgICAgIG5ld091dE5vZGVzID0gW10sCi0gICAgICAgICAgICAgICAgICAgIG5ld092ZXJOb2RlcyA9IFtdLAotICAgICAgICAgICAgICAgICAgICBjdXJyZW50T3Zlck5vZGVzID0ge30sCi0gICAgICAgICAgICAgICAgICAgIGwgPSBub2Rlcy5sZW5ndGgsCi0gICAgICAgICAgICAgICAgICAgIG5ld091dEVkZ2VzID0gW10sCi0gICAgICAgICAgICAgICAgICAgIG5ld092ZXJFZGdlcyA9IFtdLAotICAgICAgICAgICAgICAgICAgICBjdXJyZW50T3ZlckVkZ2VzID0ge30sCi0gICAgICAgICAgICAgICAgICAgIGxlID0gZWRnZXMubGVuZ3RoOwotCi0gICAgICAgICAgICAgICAgLy8gQ2hlY2sgbmV3bHkgb3ZlcnJlZCBub2RlczoKLSAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGUgPSBub2Rlc1tpXTsKLSAgICAgICAgICAgICAgICAgICAgY3VycmVudE92ZXJOb2Rlc1tub2RlLmlkXSA9IG5vZGU7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghb3Zlck5vZGVzW25vZGUuaWRdKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXdPdmVyTm9kZXMucHVzaChub2RlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJOb2Rlc1tub2RlLmlkXSA9IG5vZGU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBDaGVjayBubyBtb3JlIG92ZXJyZWQgbm9kZXM6Ci0gICAgICAgICAgICAgICAgZm9yIChrIGluIG92ZXJOb2RlcykKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFjdXJyZW50T3Zlck5vZGVzW2tdKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXdPdXROb2Rlcy5wdXNoKG92ZXJOb2Rlc1trXSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgb3Zlck5vZGVzW2tdOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBEaXNwYXRjaCBib3RoIHNpbmdsZSBhbmQgbXVsdGkgZXZlbnRzOgotICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBuZXdPdmVyTm9kZXMubGVuZ3RoOyBpIDwgbDsgaSsrKQotICAgICAgICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoJ292ZXJOb2RlJywgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogbmV3T3Zlck5vZGVzW2ldLAotICAgICAgICAgICAgICAgICAgICAgICAgY2FwdG9yOiBlLmRhdGEKLSAgICAgICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgICAgICAgICAgZm9yIChpID0gMCwgbCA9IG5ld091dE5vZGVzLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KCdvdXROb2RlJywgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogbmV3T3V0Tm9kZXNbaV0sCi0gICAgICAgICAgICAgICAgICAgICAgICBjYXB0b3I6IGUuZGF0YQotICAgICAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgICAgICAgICBpZiAobmV3T3Zlck5vZGVzLmxlbmd0aCkKLSAgICAgICAgICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KCdvdmVyTm9kZXMnLCB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2RlczogbmV3T3Zlck5vZGVzLAotICAgICAgICAgICAgICAgICAgICAgICAgY2FwdG9yOiBlLmRhdGEKLSAgICAgICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgICAgICAgICAgaWYgKG5ld091dE5vZGVzLmxlbmd0aCkKLSAgICAgICAgICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KCdvdXROb2RlcycsIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzOiBuZXdPdXROb2RlcywKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRvcjogZS5kYXRhCi0gICAgICAgICAgICAgICAgICAgIH0pOwotCi0gICAgICAgICAgICAgICAgLy8gQ2hlY2sgbmV3bHkgb3ZlcnJlZCBlZGdlczoKLSAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGU7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBlZGdlID0gZWRnZXNbaV07Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRPdmVyRWRnZXNbZWRnZS5pZF0gPSBlZGdlOwotICAgICAgICAgICAgICAgICAgICBpZiAoIW92ZXJFZGdlc1tlZGdlLmlkXSkgewotICAgICAgICAgICAgICAgICAgICAgICAgbmV3T3ZlckVkZ2VzLnB1c2goZWRnZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvdmVyRWRnZXNbZWRnZS5pZF0gPSBlZGdlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gQ2hlY2sgbm8gbW9yZSBvdmVycmVkIGVkZ2VzOgotICAgICAgICAgICAgICAgIGZvciAoayBpbiBvdmVyRWRnZXMpCi0gICAgICAgICAgICAgICAgICAgIGlmICghY3VycmVudE92ZXJFZGdlc1trXSkgewotICAgICAgICAgICAgICAgICAgICAgICAgbmV3T3V0RWRnZXMucHVzaChvdmVyRWRnZXNba10pOwotICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIG92ZXJFZGdlc1trXTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gRGlzcGF0Y2ggYm90aCBzaW5nbGUgYW5kIG11bHRpIGV2ZW50czoKLSAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsZSA9IG5ld092ZXJFZGdlcy5sZW5ndGg7IGkgPCBsZTsgaSsrKQotICAgICAgICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoJ292ZXJFZGdlJywgewotICAgICAgICAgICAgICAgICAgICAgICAgZWRnZTogbmV3T3ZlckVkZ2VzW2ldLAotICAgICAgICAgICAgICAgICAgICAgICAgY2FwdG9yOiBlLmRhdGEKLSAgICAgICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgICAgICAgICAgZm9yIChpID0gMCwgbGUgPSBuZXdPdXRFZGdlcy5sZW5ndGg7IGkgPCBsZTsgaSsrKQotICAgICAgICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoJ291dEVkZ2UnLCB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlZGdlOiBuZXdPdXRFZGdlc1tpXSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRvcjogZS5kYXRhCi0gICAgICAgICAgICAgICAgICAgIH0pOwotICAgICAgICAgICAgICAgIGlmIChuZXdPdmVyRWRnZXMubGVuZ3RoKQotICAgICAgICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoJ292ZXJFZGdlcycsIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2VzOiBuZXdPdmVyRWRnZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICBjYXB0b3I6IGUuZGF0YQotICAgICAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgICAgICAgICBpZiAobmV3T3V0RWRnZXMubGVuZ3RoKQotICAgICAgICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoJ291dEVkZ2VzJywgewotICAgICAgICAgICAgICAgICAgICAgICAgZWRnZXM6IG5ld091dEVkZ2VzLAotICAgICAgICAgICAgICAgICAgICAgICAgY2FwdG9yOiBlLmRhdGEKLSAgICAgICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIEJpbmQgZXZlbnRzOgotICAgICAgICAgICAgY2FwdG9yLmJpbmQoJ2NsaWNrJywgb25DbGljayk7Ci0gICAgICAgICAgICBjYXB0b3IuYmluZCgnbW91c2Vkb3duJywgb25Nb3ZlKTsKLSAgICAgICAgICAgIGNhcHRvci5iaW5kKCdtb3VzZXVwJywgb25Nb3ZlKTsKLSAgICAgICAgICAgIGNhcHRvci5iaW5kKCdtb3VzZW1vdmUnLCBvbk1vdmUpOwotICAgICAgICAgICAgY2FwdG9yLmJpbmQoJ21vdXNlb3V0Jywgb25PdXQpOwotICAgICAgICAgICAgY2FwdG9yLmJpbmQoJ2RvdWJsZWNsaWNrJywgb25Eb3VibGVDbGljayk7Ci0gICAgICAgICAgICBjYXB0b3IuYmluZCgncmlnaHRjbGljaycsIG9uUmlnaHRDbGljayk7Ci0gICAgICAgICAgICBzZWxmLmJpbmQoJ3JlbmRlcicsIG9uTW92ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5jYXB0b3JzLmxlbmd0aDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgIGJpbmRDYXB0b3IodGhpcy5jYXB0b3JzW2ldKTsKLSAgICB9OwotfSkuY2FsbCh0aGlzKTsKLQotOyhmdW5jdGlvbiAodW5kZWZpbmVkKSB7Ci0gICAgJ3VzZSBzdHJpY3QnOwotCi0gICAgaWYgKHR5cGVvZiBzaWdtYSA9PT0gJ3VuZGVmaW5lZCcpCi0gICAgICAgIHRocm93ICdzaWdtYSBpcyBub3QgZGVjbGFyZWQnOwotCi0gICAgLy8gSW5pdGlhbGl6ZSBwYWNrYWdlczoKLSAgICBzaWdtYS51dGlscy5wa2coJ3NpZ21hLm1pc2MnKTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgaGVscGVyIHdpbGwgYmluZCBhbnkgRE9NIHJlbmRlcmVyIChmb3IgaW5zdGFuY2Ugc3ZnKQotICAgICAqIHRvIGl0cyBjYXB0b3JzLCB0byBwcm9wZXJseSBkaXNwYXRjaCB0aGUgZ29vZCBldmVudHMgdG8gdGhlIHNpZ21hIGluc3RhbmNlCi0gICAgICogdG8gbWFuYWdlIGNsaWNraW5nLCBob3ZlcmluZyBldGMuLi4KLSAgICAgKgotICAgICAqIEl0IGhhcyB0byBiZSBjYWxsZWQgaW4gdGhlIHNjb3BlIG9mIHRoZSByZWxhdGVkIHJlbmRlcmVyLgotICAgICAqLwotICAgIHNpZ21hLm1pc2MuYmluZERPTUV2ZW50cyA9IGZ1bmN0aW9uIChjb250YWluZXIpIHsKLSAgICAgICAgdmFyIHNlbGYgPSB0aGlzLAotICAgICAgICAgICAgZ3JhcGggPSB0aGlzLmdyYXBoOwotCi0gICAgICAgIC8vIERPTUVsZW1lbnQgYWJzdHJhY3Rpb24KLSAgICAgICAgZnVuY3Rpb24gRWxlbWVudChkb21FbGVtZW50KSB7Ci0KLSAgICAgICAgICAgIC8vIEhlbHBlcnMKLSAgICAgICAgICAgIHRoaXMuYXR0ciA9IGZ1bmN0aW9uIChhdHRyTmFtZSkgewotICAgICAgICAgICAgICAgIHJldHVybiBkb21FbGVtZW50LmdldEF0dHJpYnV0ZU5TKG51bGwsIGF0dHJOYW1lKTsKLSAgICAgICAgICAgIH07Ci0KLSAgICAgICAgICAgIC8vIFByb3BlcnRpZXMKLSAgICAgICAgICAgIHRoaXMudGFnID0gZG9tRWxlbWVudC50YWdOYW1lOwotICAgICAgICAgICAgdGhpcy5jbGFzcyA9IHRoaXMuYXR0cignY2xhc3MnKTsKLSAgICAgICAgICAgIHRoaXMuaWQgPSB0aGlzLmF0dHIoJ2lkJyk7Ci0KLSAgICAgICAgICAgIC8vIE1ldGhvZHMKLSAgICAgICAgICAgIHRoaXMuaXNOb2RlID0gZnVuY3Rpb24gKCkgewotICAgICAgICAgICAgICAgIHJldHVybiAhIX50aGlzLmNsYXNzLmluZGV4T2Yoc2VsZi5zZXR0aW5ncygnY2xhc3NQcmVmaXgnKSArICctbm9kZScpOwotICAgICAgICAgICAgfTsKLQotICAgICAgICAgICAgdGhpcy5pc0VkZ2UgPSBmdW5jdGlvbiAoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICEhfnRoaXMuY2xhc3MuaW5kZXhPZihzZWxmLnNldHRpbmdzKCdjbGFzc1ByZWZpeCcpICsgJy1lZGdlJyk7Ci0gICAgICAgICAgICB9OwotCi0gICAgICAgICAgICB0aGlzLmlzSG92ZXIgPSBmdW5jdGlvbiAoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICEhfnRoaXMuY2xhc3MuaW5kZXhPZihzZWxmLnNldHRpbmdzKCdjbGFzc1ByZWZpeCcpICsgJy1ob3ZlcicpOwotICAgICAgICAgICAgfTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIENsaWNrCi0gICAgICAgIGZ1bmN0aW9uIGNsaWNrKGUpIHsKLSAgICAgICAgICAgIGlmICghc2VsZi5zZXR0aW5ncygnZXZlbnRzRW5hYmxlZCcpKQotICAgICAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAgICAgLy8gR2VuZXJpYyBldmVudAotICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KCdjbGljaycsIGUpOwotCi0gICAgICAgICAgICAvLyBBcmUgd2Ugb24gYSBub2RlPwotICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBuZXcgRWxlbWVudChlLnRhcmdldCk7Ci0KLSAgICAgICAgICAgIGlmIChlbGVtZW50LmlzTm9kZSgpKQotICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgnY2xpY2tOb2RlJywgewotICAgICAgICAgICAgICAgICAgICBub2RlOiBncmFwaC5ub2RlcyhlbGVtZW50LmF0dHIoJ2RhdGEtbm9kZS1pZCcpKQotICAgICAgICAgICAgICAgIH0pOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgnY2xpY2tTdGFnZScpOwotCi0gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7Ci0gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gRG91YmxlIGNsaWNrCi0gICAgICAgIGZ1bmN0aW9uIGRvdWJsZUNsaWNrKGUpIHsKLSAgICAgICAgICAgIGlmICghc2VsZi5zZXR0aW5ncygnZXZlbnRzRW5hYmxlZCcpKQotICAgICAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAgICAgLy8gR2VuZXJpYyBldmVudAotICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KCdkb3VibGVDbGljaycsIGUpOwotCi0gICAgICAgICAgICAvLyBBcmUgd2Ugb24gYSBub2RlPwotICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBuZXcgRWxlbWVudChlLnRhcmdldCk7Ci0KLSAgICAgICAgICAgIGlmIChlbGVtZW50LmlzTm9kZSgpKQotICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgnZG91YmxlQ2xpY2tOb2RlJywgewotICAgICAgICAgICAgICAgICAgICBub2RlOiBncmFwaC5ub2RlcyhlbGVtZW50LmF0dHIoJ2RhdGEtbm9kZS1pZCcpKQotICAgICAgICAgICAgICAgIH0pOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgnZG91YmxlQ2xpY2tTdGFnZScpOwotCi0gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7Ci0gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gT24gb3ZlcgotICAgICAgICBmdW5jdGlvbiBvbk92ZXIoZSkgewotICAgICAgICAgICAgdmFyIHRhcmdldCA9IGUudG9FbGVtZW50IHx8IGUudGFyZ2V0OwotCi0gICAgICAgICAgICBpZiAoIXNlbGYuc2V0dGluZ3MoJ2V2ZW50c0VuYWJsZWQnKSB8fCAhdGFyZ2V0KQotICAgICAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAgICAgdmFyIGVsID0gbmV3IEVsZW1lbnQodGFyZ2V0KTsKLQotICAgICAgICAgICAgaWYgKGVsLmlzTm9kZSgpKSB7Ci0gICAgICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KCdvdmVyTm9kZScsIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZTogZ3JhcGgubm9kZXMoZWwuYXR0cignZGF0YS1ub2RlLWlkJykpCi0gICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChlbC5pc0VkZ2UoKSkgewotICAgICAgICAgICAgICAgIHZhciBlZGdlID0gZ3JhcGguZWRnZXMoZWwuYXR0cignZGF0YS1lZGdlLWlkJykpOwotICAgICAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudCgnb3ZlckVkZ2UnLCB7Ci0gICAgICAgICAgICAgICAgICAgIGVkZ2U6IGVkZ2UsCi0gICAgICAgICAgICAgICAgICAgIHNvdXJjZTogZ3JhcGgubm9kZXMoZWRnZS5zb3VyY2UpLAotICAgICAgICAgICAgICAgICAgICB0YXJnZXQ6IGdyYXBoLm5vZGVzKGVkZ2UudGFyZ2V0KQotICAgICAgICAgICAgICAgIH0pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gT24gb3V0Ci0gICAgICAgIGZ1bmN0aW9uIG9uT3V0KGUpIHsKLSAgICAgICAgICAgIHZhciB0YXJnZXQgPSBlLmZyb21FbGVtZW50IHx8IGUub3JpZ2luYWxUYXJnZXQ7Ci0KLSAgICAgICAgICAgIGlmICghc2VsZi5zZXR0aW5ncygnZXZlbnRzRW5hYmxlZCcpKQotICAgICAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAgICAgdmFyIGVsID0gbmV3IEVsZW1lbnQodGFyZ2V0KTsKLQotICAgICAgICAgICAgaWYgKGVsLmlzTm9kZSgpKSB7Ci0gICAgICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KCdvdXROb2RlJywgewotICAgICAgICAgICAgICAgICAgICBub2RlOiBncmFwaC5ub2RlcyhlbC5hdHRyKCdkYXRhLW5vZGUtaWQnKSkKLSAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGVsLmlzRWRnZSgpKSB7Ci0gICAgICAgICAgICAgICAgdmFyIGVkZ2UgPSBncmFwaC5lZGdlcyhlbC5hdHRyKCdkYXRhLWVkZ2UtaWQnKSk7Ci0gICAgICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KCdvdXRFZGdlJywgewotICAgICAgICAgICAgICAgICAgICBlZGdlOiBlZGdlLAotICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IGdyYXBoLm5vZGVzKGVkZ2Uuc291cmNlKSwKLSAgICAgICAgICAgICAgICAgICAgdGFyZ2V0OiBncmFwaC5ub2RlcyhlZGdlLnRhcmdldCkKLSAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJlZ2lzdGVyaW5nIEV2ZW50czoKLQotICAgICAgICAvLyBDbGljawotICAgICAgICBjb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBjbGljaywgZmFsc2UpOwotICAgICAgICBzaWdtYS51dGlscy5kb3VibGVDbGljayhjb250YWluZXIsICdjbGljaycsIGRvdWJsZUNsaWNrKTsKLQotICAgICAgICAvLyBUb3VjaCBjb3VudGVycGFydHMKLSAgICAgICAgY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBjbGljaywgZmFsc2UpOwotICAgICAgICBzaWdtYS51dGlscy5kb3VibGVDbGljayhjb250YWluZXIsICd0b3VjaHN0YXJ0JywgZG91YmxlQ2xpY2spOwotCi0gICAgICAgIC8vIE1vdXNlb3ZlcgotICAgICAgICBjb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgb25PdmVyLCB0cnVlKTsKLQotICAgICAgICAvLyBNb3VzZW91dAotICAgICAgICBjb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdXQnLCBvbk91dCwgdHJ1ZSk7Ci0gICAgfTsKLX0pLmNhbGwodGhpcyk7Ci0KLTsoZnVuY3Rpb24gKHVuZGVmaW5lZCkgewotICAgICd1c2Ugc3RyaWN0JzsKLQotICAgIGlmICh0eXBlb2Ygc2lnbWEgPT09ICd1bmRlZmluZWQnKQotICAgICAgICB0aHJvdyAnc2lnbWEgaXMgbm90IGRlY2xhcmVkJzsKLQotICAgIC8vIEluaXRpYWxpemUgcGFja2FnZXM6Ci0gICAgc2lnbWEudXRpbHMucGtnKCdzaWdtYS5taXNjJyk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBsaXN0ZW5zIHRvICJvdmVyTm9kZSIsICJvdXROb2RlIiwgIm92ZXJFZGdlIiBhbmQgIm91dEVkZ2UiCi0gICAgICogZXZlbnRzIGZyb20gYSByZW5kZXJlciBhbmQgcmVuZGVycyB0aGUgbm9kZXMgZGlmZmVyZW50bHkgb24gdGhlIHRvcCBsYXllci4KLSAgICAgKiBUaGUgZ29hbCBpcyB0byBtYWtlIGFueSBub2RlIGxhYmVsIHJlYWRhYmxlIHdpdGggdGhlIG1vdXNlLCBhbmQgdG8KLSAgICAgKiBoaWdobGlnaHQgaG92ZXJlZCBub2RlcyBhbmQgZWRnZXMuCi0gICAgICoKLSAgICAgKiBJdCBoYXMgdG8gYmUgY2FsbGVkIGluIHRoZSBzY29wZSBvZiB0aGUgcmVsYXRlZCByZW5kZXJlci4KLSAgICAgKi8KLSAgICBzaWdtYS5taXNjLmRyYXdIb3ZlcnMgPSBmdW5jdGlvbiAocHJlZml4KSB7Ci0gICAgICAgIHZhciBzZWxmID0gdGhpcywKLSAgICAgICAgICAgIGhvdmVyZWROb2RlcyA9IHt9LAotICAgICAgICAgICAgaG92ZXJlZEVkZ2VzID0ge307Ci0KLSAgICAgICAgdGhpcy5iaW5kKCdvdmVyTm9kZScsIGZ1bmN0aW9uIChldmVudCkgewotICAgICAgICAgICAgdmFyIG5vZGUgPSBldmVudC5kYXRhLm5vZGU7Ci0gICAgICAgICAgICBpZiAoIW5vZGUuaGlkZGVuKSB7Ci0gICAgICAgICAgICAgICAgaG92ZXJlZE5vZGVzW25vZGUuaWRdID0gbm9kZTsKLSAgICAgICAgICAgICAgICBkcmF3KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pOwotCi0gICAgICAgIHRoaXMuYmluZCgnb3V0Tm9kZScsIGZ1bmN0aW9uIChldmVudCkgewotICAgICAgICAgICAgZGVsZXRlIGhvdmVyZWROb2Rlc1tldmVudC5kYXRhLm5vZGUuaWRdOwotICAgICAgICAgICAgZHJhdygpOwotICAgICAgICB9KTsKLQotICAgICAgICB0aGlzLmJpbmQoJ292ZXJFZGdlJywgZnVuY3Rpb24gKGV2ZW50KSB7Ci0gICAgICAgICAgICB2YXIgZWRnZSA9IGV2ZW50LmRhdGEuZWRnZTsKLSAgICAgICAgICAgIGlmICghZWRnZS5oaWRkZW4pIHsKLSAgICAgICAgICAgICAgICBob3ZlcmVkRWRnZXNbZWRnZS5pZF0gPSBlZGdlOwotICAgICAgICAgICAgICAgIGRyYXcoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0KLSAgICAgICAgdGhpcy5iaW5kKCdvdXRFZGdlJywgZnVuY3Rpb24gKGV2ZW50KSB7Ci0gICAgICAgICAgICBkZWxldGUgaG92ZXJlZEVkZ2VzW2V2ZW50LmRhdGEuZWRnZS5pZF07Ci0gICAgICAgICAgICBkcmF3KCk7Ci0gICAgICAgIH0pOwotCi0gICAgICAgIHRoaXMuYmluZCgncmVuZGVyJywgZnVuY3Rpb24gKGV2ZW50KSB7Ci0gICAgICAgICAgICBkcmF3KCk7Ci0gICAgICAgIH0pOwotCi0gICAgICAgIGZ1bmN0aW9uIGRyYXcoKSB7Ci0KLSAgICAgICAgICAgIHZhciBrLAotICAgICAgICAgICAgICAgIHNvdXJjZSwKLSAgICAgICAgICAgICAgICB0YXJnZXQsCi0gICAgICAgICAgICAgICAgaG92ZXJlZE5vZGUsCi0gICAgICAgICAgICAgICAgaG92ZXJlZEVkZ2UsCi0gICAgICAgICAgICAgICAgYyA9IHNlbGYuY29udGV4dHMuaG92ZXIuY2FudmFzLAotICAgICAgICAgICAgICAgIGRlZmF1bHROb2RlVHlwZSA9IHNlbGYuc2V0dGluZ3MoJ2RlZmF1bHROb2RlVHlwZScpLAotICAgICAgICAgICAgICAgIGRlZmF1bHRFZGdlVHlwZSA9IHNlbGYuc2V0dGluZ3MoJ2RlZmF1bHRFZGdlVHlwZScpLAotICAgICAgICAgICAgICAgIG5vZGVSZW5kZXJlcnMgPSBzaWdtYS5jYW52YXMuaG92ZXJzLAotICAgICAgICAgICAgICAgIGVkZ2VSZW5kZXJlcnMgPSBzaWdtYS5jYW52YXMuZWRnZWhvdmVycywKLSAgICAgICAgICAgICAgICBleHRyZW1pdGllc1JlbmRlcmVycyA9IHNpZ21hLmNhbnZhcy5leHRyZW1pdGllcywKLSAgICAgICAgICAgICAgICBlbWJlZFNldHRpbmdzID0gc2VsZi5zZXR0aW5ncy5lbWJlZE9iamVjdHMoewotICAgICAgICAgICAgICAgICAgICBwcmVmaXg6IHByZWZpeAotICAgICAgICAgICAgICAgIH0pOwotCi0gICAgICAgICAgICAvLyBDbGVhciBzZWxmLmNvbnRleHRzLmhvdmVyOgotICAgICAgICAgICAgc2VsZi5jb250ZXh0cy5ob3Zlci5jbGVhclJlY3QoMCwgMCwgYy53aWR0aCwgYy5oZWlnaHQpOwotCi0gICAgICAgICAgICAvLyBOb2RlIHJlbmRlcjogc2luZ2xlIGhvdmVyCi0gICAgICAgICAgICBpZiAoCi0gICAgICAgICAgICAgICAgZW1iZWRTZXR0aW5ncygnZW5hYmxlSG92ZXJpbmcnKSAmJgotICAgICAgICAgICAgICAgIGVtYmVkU2V0dGluZ3MoJ3NpbmdsZUhvdmVyJykgJiYKLSAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyhob3ZlcmVkTm9kZXMpLmxlbmd0aAotICAgICAgICAgICAgKSB7Ci0gICAgICAgICAgICAgICAgaG92ZXJlZE5vZGUgPSBob3ZlcmVkTm9kZXNbT2JqZWN0LmtleXMoaG92ZXJlZE5vZGVzKVswXV07Ci0gICAgICAgICAgICAgICAgKAotICAgICAgICAgICAgICAgICAgICBub2RlUmVuZGVyZXJzW2hvdmVyZWROb2RlLnR5cGVdIHx8Ci0gICAgICAgICAgICAgICAgICAgIG5vZGVSZW5kZXJlcnNbZGVmYXVsdE5vZGVUeXBlXSB8fAotICAgICAgICAgICAgICAgICAgICBub2RlUmVuZGVyZXJzLmRlZgotICAgICAgICAgICAgICAgICkoCi0gICAgICAgICAgICAgICAgICAgIGhvdmVyZWROb2RlLAotICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbnRleHRzLmhvdmVyLAotICAgICAgICAgICAgICAgICAgICBlbWJlZFNldHRpbmdzCi0gICAgICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gTm9kZSByZW5kZXI6IG11bHRpcGxlIGhvdmVyCi0gICAgICAgICAgICBpZiAoCi0gICAgICAgICAgICAgICAgZW1iZWRTZXR0aW5ncygnZW5hYmxlSG92ZXJpbmcnKSAmJiAhZW1iZWRTZXR0aW5ncygnc2luZ2xlSG92ZXInKQotICAgICAgICAgICAgKQotICAgICAgICAgICAgICAgIGZvciAoayBpbiBob3ZlcmVkTm9kZXMpCi0gICAgICAgICAgICAgICAgICAgICgKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVSZW5kZXJlcnNbaG92ZXJlZE5vZGVzW2tdLnR5cGVdIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2RlUmVuZGVyZXJzW2RlZmF1bHROb2RlVHlwZV0gfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVSZW5kZXJlcnMuZGVmCi0gICAgICAgICAgICAgICAgICAgICkoCi0gICAgICAgICAgICAgICAgICAgICAgICBob3ZlcmVkTm9kZXNba10sCi0gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbnRleHRzLmhvdmVyLAotICAgICAgICAgICAgICAgICAgICAgICAgZW1iZWRTZXR0aW5ncwotICAgICAgICAgICAgICAgICAgICApOwotCi0gICAgICAgICAgICAvLyBFZGdlIHJlbmRlcjogc2luZ2xlIGhvdmVyCi0gICAgICAgICAgICBpZiAoCi0gICAgICAgICAgICAgICAgZW1iZWRTZXR0aW5ncygnZW5hYmxlRWRnZUhvdmVyaW5nJykgJiYKLSAgICAgICAgICAgICAgICBlbWJlZFNldHRpbmdzKCdzaW5nbGVIb3ZlcicpICYmCi0gICAgICAgICAgICAgICAgT2JqZWN0LmtleXMoaG92ZXJlZEVkZ2VzKS5sZW5ndGgKLSAgICAgICAgICAgICkgewotICAgICAgICAgICAgICAgIGhvdmVyZWRFZGdlID0gaG92ZXJlZEVkZ2VzW09iamVjdC5rZXlzKGhvdmVyZWRFZGdlcylbMF1dOwotICAgICAgICAgICAgICAgIHNvdXJjZSA9IHNlbGYuZ3JhcGgubm9kZXMoaG92ZXJlZEVkZ2Uuc291cmNlKTsKLSAgICAgICAgICAgICAgICB0YXJnZXQgPSBzZWxmLmdyYXBoLm5vZGVzKGhvdmVyZWRFZGdlLnRhcmdldCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoIWhvdmVyZWRFZGdlLmhpZGRlbikgewotICAgICAgICAgICAgICAgICAgICAoCi0gICAgICAgICAgICAgICAgICAgICAgICBlZGdlUmVuZGVyZXJzW2hvdmVyZWRFZGdlLnR5cGVdIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICBlZGdlUmVuZGVyZXJzW2RlZmF1bHRFZGdlVHlwZV0gfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2VSZW5kZXJlcnMuZGVmCi0gICAgICAgICAgICAgICAgICAgICkoCi0gICAgICAgICAgICAgICAgICAgICAgICBob3ZlcmVkRWRnZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCwKLSAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY29udGV4dHMuaG92ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICBlbWJlZFNldHRpbmdzCi0gICAgICAgICAgICAgICAgICAgICk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGVtYmVkU2V0dGluZ3MoJ2VkZ2VIb3ZlckV4dHJlbWl0aWVzJykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyZW1pdGllc1JlbmRlcmVyc1tob3ZlcmVkRWRnZS50eXBlXSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJlbWl0aWVzUmVuZGVyZXJzLmRlZgotICAgICAgICAgICAgICAgICAgICAgICAgKSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3ZlcmVkRWRnZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY29udGV4dHMuaG92ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1iZWRTZXR0aW5ncwotICAgICAgICAgICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXZvaWQgZWRnZXMgcmVuZGVyZWQgb3ZlciBub2RlczoKLSAgICAgICAgICAgICAgICAgICAgICAgICgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWdtYS5jYW52YXMubm9kZXNbc291cmNlLnR5cGVdIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWEuY2FudmFzLm5vZGVzLmRlZgotICAgICAgICAgICAgICAgICAgICAgICAgKSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jb250ZXh0cy5ob3ZlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbWJlZFNldHRpbmdzCi0gICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgICAgICAgICAgKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ21hLmNhbnZhcy5ub2Rlc1t0YXJnZXQudHlwZV0gfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWdtYS5jYW52YXMubm9kZXMuZGVmCi0gICAgICAgICAgICAgICAgICAgICAgICApKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbnRleHRzLmhvdmVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkU2V0dGluZ3MKLSAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIEVkZ2UgcmVuZGVyOiBtdWx0aXBsZSBob3ZlcgotICAgICAgICAgICAgaWYgKAotICAgICAgICAgICAgICAgIGVtYmVkU2V0dGluZ3MoJ2VuYWJsZUVkZ2VIb3ZlcmluZycpICYmICFlbWJlZFNldHRpbmdzKCdzaW5nbGVIb3ZlcicpCi0gICAgICAgICAgICApIHsKLSAgICAgICAgICAgICAgICBmb3IgKGsgaW4gaG92ZXJlZEVkZ2VzKSB7Ci0gICAgICAgICAgICAgICAgICAgIGhvdmVyZWRFZGdlID0gaG92ZXJlZEVkZ2VzW2tdOwotICAgICAgICAgICAgICAgICAgICBzb3VyY2UgPSBzZWxmLmdyYXBoLm5vZGVzKGhvdmVyZWRFZGdlLnNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IHNlbGYuZ3JhcGgubm9kZXMoaG92ZXJlZEVkZ2UudGFyZ2V0KTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoIWhvdmVyZWRFZGdlLmhpZGRlbikgewotICAgICAgICAgICAgICAgICAgICAgICAgKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2VSZW5kZXJlcnNbaG92ZXJlZEVkZ2UudHlwZV0gfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlZGdlUmVuZGVyZXJzW2RlZmF1bHRFZGdlVHlwZV0gfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlZGdlUmVuZGVyZXJzLmRlZgotICAgICAgICAgICAgICAgICAgICAgICAgKSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3ZlcmVkRWRnZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY29udGV4dHMuaG92ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1iZWRTZXR0aW5ncwotICAgICAgICAgICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVtYmVkU2V0dGluZ3MoJ2VkZ2VIb3ZlckV4dHJlbWl0aWVzJykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJlbWl0aWVzUmVuZGVyZXJzW2hvdmVyZWRFZGdlLnR5cGVdIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJlbWl0aWVzUmVuZGVyZXJzLmRlZgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICkoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvdmVyZWRFZGdlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jb250ZXh0cy5ob3ZlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1iZWRTZXR0aW5ncwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF2b2lkIGVkZ2VzIHJlbmRlcmVkIG92ZXIgbm9kZXM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWdtYS5jYW52YXMubm9kZXNbc291cmNlLnR5cGVdIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ21hLmNhbnZhcy5ub2Rlcy5kZWYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICApKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY29udGV4dHMuaG92ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkU2V0dGluZ3MKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWEuY2FudmFzLm5vZGVzW3RhcmdldC50eXBlXSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWdtYS5jYW52YXMubm9kZXMuZGVmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbnRleHRzLmhvdmVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbWJlZFNldHRpbmdzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH07Ci19KS5jYWxsKHRoaXMpOwpkaWZmIC0tZ2l0IGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9vdmVybGF5dnBuX3RvcG8uaHRtbCBiL29wZW5vLXBvcnRhbC9wb3J0YWwtbGlmZWN5Y2xlbWdyL3NyYy9tYWluL3dlYmFwcC9saWZlY3ljbGVtZ3Ivb3ZlcmxheXZwbl90b3BvLmh0bWwKaW5kZXggNWI0YmNkMS4uYjYxNjdiMSAxMDA2NDQKLS0tIGEvb3Blbm8tcG9ydGFsL3BvcnRhbC1saWZlY3ljbGVtZ3Ivc3JjL21haW4vd2ViYXBwL2xpZmVjeWNsZW1nci9vdmVybGF5dnBuX3RvcG8uaHRtbAorKysgYi9vcGVuby1wb3J0YWwvcG9ydGFsLWxpZmVjeWNsZW1nci9zcmMvbWFpbi93ZWJhcHAvbGlmZWN5Y2xlbWdyL292ZXJsYXl2cG5fdG9wby5odG1sCkBAIC0xLDQyICsxLDYxIEBACi08IS0tDQotDQotICAgIENvcHlyaWdodCAyMDE2LCBIdWF3ZWkgVGVjaG5vbG9naWVzIENvLiwgTHRkLg0KLQ0KLSAgICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsNCi0gICAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KLSAgICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQNCi0NCi0gICAgICAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCi0NCi0gICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KLSAgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLA0KLSAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4NCi0gICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KLSAgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4NCi0NCi0tLT4NCi0NCi08IURPQ1RZUEUgaHRtbD4NCi08aHRtbD4NCi08aGVhZD4NCi0gICAgPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCi0gICAgICAgICNjb250YWluZXIgew0KLSAgICAgICAgICAgIHRvcDogMDsNCi0gICAgICAgICAgICBib3R0b206IDA7DQotICAgICAgICAgICAgbGVmdDogMDsNCi0gICAgICAgICAgICByaWdodDogMDsNCi0gICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7DQotICAgICAgICB9DQotICAgIDwvc3R5bGU+DQotPC9oZWFkPg0KLTxib2R5Pg0KLTxkaXYgaWQ9ImNvbnRhaW5lciI+PC9kaXY+DQotPHNjcmlwdCBzcmM9ImpzL3RvcG8vc2lnbWEvc2lnbWEubWluLmpzIj48L3NjcmlwdD4NCi08c2NyaXB0IHNyYz0ianMvdG9wby9zaWdtYS9qcXVlcnktMy4xLjAubWluLmpzIj48L3NjcmlwdD4NCi08c2NyaXB0IHNyYz0ianMvdG9wby9zaWdtYS9wbHVnaW5zL3NpZ21hLnJlbmRlcmVycy5jdXN0b21TaGFwZXMubWluLmpzIj48L3NjcmlwdD4NCi08c2NyaXB0IHNyYz0ianMvdG9wby9zaWdtYS9wbHVnaW5zL3NpZ21hLnJlbmRlcmVycy5lZGdlTGFiZWxzLm1pbi5qcyI+PC9zY3JpcHQ+DQotPHNjcmlwdCBzcmM9ImpzL3RvcG8vTm9kZS5qcyI+PC9zY3JpcHQ+DQotPHNjcmlwdCBzcmM9ImpzL3RvcG8vRWRnZS5qcyI+PC9zY3JpcHQ+DQotPHNjcmlwdCBzcmM9ImpzL3RvcG8vVG9wb2xvZ3kuanMiPjwvc2NyaXB0Pg0KLTwvYm9keT4NCis8IS0tCisKKyAgICBDb3B5cmlnaHQgMjAxNiwgSHVhd2VpIFRlY2hub2xvZ2llcyBDby4sIEx0ZC4KKworICAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAgICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKy0tPgorCis8IURPQ1RZUEUgaHRtbD4KKzxodG1sPgorPGhlYWQ+Cis8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgorICAjY29udGFpbmVyIHsKKyAgICAgIHRvcDogNTVweDsKKyAgICAgIGJvdHRvbTogMDsKKyAgICAgIGxlZnQ6IDA7CisgICAgICByaWdodDogMDsKKyAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTsKKyAgfQorICAjdGl0bGUgeworICAgICAgZm9udC1zaXplOiAzMHB4OworICAgICAgdGV4dC1hbGlnbjogY2VudGVyOworICB9Cis8L3N0eWxlPgorPC9oZWFkPgorCis8Ym9keT4KKzxkaXYgaWQ9InRpdGxlIj48L2Rpdj4KKzxoci8+Cis8ZGl2IGlkPSJjb250YWluZXIiPjwvZGl2PgorCisKKzxzY3JpcHQgc3JjPSJqcy9qcXVlcnktMS4xMS4yLm1pbi5qcyI+PC9zY3JpcHQ+CisKKzxzY3JpcHQgc3JjPSJqcy90b3BvL3NpZ21hL3NpZ21hLm1pbi5qcyI+PC9zY3JpcHQ+Cis8c2NyaXB0IHNyYz0ianMvdG9wby9zaWdtYS9zaWdtYS5yZW5kZXJlcnMuY3VzdG9tU2hhcGVzLm1pbi5qcyI+PC9zY3JpcHQ+Cis8c2NyaXB0IHNyYz0ianMvdG9wby9zaWdtYS9zaWdtYS5yZW5kZXJlcnMuZWRnZUxhYmVscy5taW4uanMiPjwvc2NyaXB0PgorCis8c2NyaXB0IHNyYz0ianMvdG9wby9Ob2RlLmpzIj48L3NjcmlwdD4KKzxzY3JpcHQgc3JjPSJqcy90b3BvL0VkZ2UuanMiPjwvc2NyaXB0PgorPHNjcmlwdCBzcmM9ImpzL3RvcG8vT3ZlcmxheVRvcG9sb2d5LmpzIj48L3NjcmlwdD4KKworPCEtLSBVcGRhdGUgdGhlIHRpdGxlIHdpdGggdGhlIGlkIG9mIE92ZXJsYXkgVlBOIC0tPgorPHNjcmlwdCBsYW5ndWFnZT0iSmF2YVNjcmlwdCI+CisgIHZhciBpZCA9IGV4dHJhY3RPdmVybGF5VlBOSWQoKTsKKyAgdmFyIHRpdGxlU3RyID0gIlRvcG9sb2d5IG9mIE92ZXJsYXkgVlBOIDogIi5jb25jYXQoIjxiPiIsIGlkLCAiPC9iPiIpOworICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgidGl0bGUiKS5pbm5lckhUTUwgPSB0aXRsZVN0cjsKKzwvc2NyaXB0PgorPC9ib2R5PgorCiA8L2h0bWw+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2VydmljZWdhdGV3YXkvZGVwbG95bWVudC9wb20ueG1sIGIvc2VydmljZWdhdGV3YXkvZGVwbG95bWVudC9wb20ueG1sCmluZGV4IDg4ZDZmNGUuLjJmMDI1ZTkgMTAwNjQ0Ci0tLSBhL3NlcnZpY2VnYXRld2F5L2RlcGxveW1lbnQvcG9tLnhtbAorKysgYi9zZXJ2aWNlZ2F0ZXdheS9kZXBsb3ltZW50L3BvbS54bWwKQEAgLTE4LDIyICsxOCw5NyBAQAogICAgIDxtb2RlbFZlcnNpb24+NC4wLjA8L21vZGVsVmVyc2lvbj4KICAgICA8cGFyZW50PgogICAgICAgICA8Z3JvdXBJZD5vcmcub3Blbm8uZ3NvLmd1aTwvZ3JvdXBJZD4KLSAgICAgICAgPGFydGlmYWN0SWQ+c2VydmljZWdhdGV3YXk8L2FydGlmYWN0SWQ+CisgICAgICAgIDxhcnRpZmFjdElkPnNlcnZpY2UtZ2F0ZXdheS1yb290PC9hcnRpZmFjdElkPgogICAgICAgICA8dmVyc2lvbj4xLjAuMC1TTkFQU0hPVDwvdmVyc2lvbj4KICAgICA8L3BhcmVudD4KIAotICAgIDxhcnRpZmFjdElkPmRlcGxveW1lbnQ8L2FydGlmYWN0SWQ+Ci0gICAgPG5hbWU+ZGVwbG95bWVudDwvbmFtZT4KLSAgICA8cGFja2FnaW5nPmphcjwvcGFja2FnaW5nPgorICAgIDxhcnRpZmFjdElkPnNlcnZpY2UtZ2F0ZXdheS1kZXBsb3ltZW50PC9hcnRpZmFjdElkPgorICAgIDxuYW1lPlNlcnZpY2VHYXRld2F5Um9vdERlcGxveW1lbnQ8L25hbWU+CisgICAgPHBhY2thZ2luZz5wb208L3BhY2thZ2luZz4KIAogICAgIDxwcm9wZXJ0aWVzPgogICAgICAgICA8cHJvamVjdC5idWlsZC5zb3VyY2VFbmNvZGluZz5VVEYtODwvcHJvamVjdC5idWlsZC5zb3VyY2VFbmNvZGluZz4KICAgICA8L3Byb3BlcnRpZXM+Ci0gICAgPGRlcGVuZGVuY2llcz4KLSAgICAgICAgPGRlcGVuZGVuY3k+Ci0gICAgICAgICAgICA8Z3JvdXBJZD5vcmcub3Blbm8uY29tbW9uLXNlcnZpY2VzLmNvbW1vbi11dGlsaXRpZXM8L2dyb3VwSWQ+Ci0gICAgICAgICAgICA8YXJ0aWZhY3RJZD5jb21tb25saWItY2JiPC9hcnRpZmFjdElkPgotICAgICAgICAgICAgPHZlcnNpb24+MS4wLjAtU05BUFNIT1Q8L3ZlcnNpb24+Ci0gICAgICAgIDwvZGVwZW5kZW5jeT4KLSAgICA8L2RlcGVuZGVuY2llcz4KKworICAgIDxidWlsZD4KKyAgICAgICAgPHBsdWdpbk1hbmFnZW1lbnQ+CisgICAgICAgICAgICA8cGx1Z2lucz4KKyAgICAgICAgICAgICAgICA8cGx1Z2luPgorICAgICAgICAgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuY29kZWhhdXMuZ21hdmVuPC9ncm91cElkPgorICAgICAgICAgICAgICAgICAgICA8YXJ0aWZhY3RJZD5ncm9vdnktbWF2ZW4tcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgICAgICAgICA8dmVyc2lvbj4yLjA8L3ZlcnNpb24+CisgICAgICAgICAgICAgICAgPC9wbHVnaW4+CisgICAgICAgICAgICA8L3BsdWdpbnM+CisgICAgICAgIDwvcGx1Z2luTWFuYWdlbWVudD4KKyAgICAgICAgPHBsdWdpbnM+CisgICAgICAgICAgICA8cGx1Z2luPgorICAgICAgICAgICAgICAgIDxncm91cElkPm9yZy5jb2RlaGF1cy5nbWF2ZW48L2dyb3VwSWQ+CisgICAgICAgICAgICAgICAgPGFydGlmYWN0SWQ+Z21hdmVuLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgICAgICA8dmVyc2lvbj4xLjU8L3ZlcnNpb24+CisgICAgICAgICAgICAgICAgPGV4ZWN1dGlvbnM+CisgICAgICAgICAgICAgICAgICAgIDxleGVjdXRpb24+CisgICAgICAgICAgICAgICAgICAgICAgICA8aWQ+U2VydmljZUdhdGV3YXkgcGFja2FnZTwvaWQ+CisgICAgICAgICAgICAgICAgICAgICAgICA8cGhhc2U+cGFja2FnZTwvcGhhc2U+CisgICAgICAgICAgICAgICAgICAgICAgICA8Z29hbHM+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGdvYWw+ZXhlY3V0ZTwvZ29hbD4KKyAgICAgICAgICAgICAgICAgICAgICAgIDwvZ29hbHM+CisgICAgICAgICAgICAgICAgICAgICAgICA8Y29uZmlndXJhdGlvbj4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c291cmNlPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqKioqKioqIEdvaW5nIHRvIG1ha2UgcmVsZWFzZSB6aXAgKioqKioqKioiKQorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGxveUZvbGRlciA9ICIke3Byb2plY3QuYnVpbGQuZGlyZWN0b3J5fS9kZXBsb3lvdXRwdXQiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGxveVVuemlwID0gIiR7cHJvamVjdC5idWlsZC5kaXJlY3Rvcnl9L2RlcGxveXVuemlwIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRmaWxlTmFtZSA9ICJTZXJ2aWNlR2F0ZXdheS0uJHtwcm9qZWN0LnZlcnNpb259LnppcCIKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQuZGVsZXRlKGRpcjogIiR7ZGVwbG95Rm9sZGVyfSIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFudC5ta2RpcihkaXI6ICIke2RlcGxveUZvbGRlcn0iKQorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFudC5kZWxldGUoZGlyOiAiJHtkZXBsb3lVbnppcH0iKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQubWtkaXIoZGlyOiAiJHtkZXBsb3lVbnppcH0iKQorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFudC5ta2RpcihkaXI6ICIke2RlcGxveVVuemlwfS93ZWJhcHBzL1JPT1QiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQubWtkaXIoZGlyOiAiJHtkZXBsb3lVbnppcH0vd2ViYXBwcy9vcGVub3VpI3NlcnZpY2VnYXRld2F5I3YxIikKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQuY29weSh0b2RpcjogIiR7ZGVwbG95VW56aXB9IikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc2V0KGRpcjogIiR7YmFzZWRpcn0vc3JjL21haW4vcmVsZWFzZSIpeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNsdWRlKG5hbWU6ICIqKi8uZ2l0aWdub3JlIikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW50LmNvcHkodG9kaXI6ICIke2RlcGxveVVuemlwfS93ZWJhcHBzL1JPT1QiKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzZXQoZGlyOiAiJHtwcm9qZWN0LmJ1aWxkLmRpcmVjdG9yeX0vLi4vLi4vc2VydmljZS90YXJnZXQvUk9PVCIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQuemlwKGRlc3RmaWxlOiAiJHtkZXBsb3lGb2xkZXJ9LyR7b3V0ZmlsZU5hbWV9IikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc2V0KGRpcjogIiR7ZGVwbG95VW56aXB9IikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqKioqKioqIGNvbXBsZXRlZC4gKioqKioqKioqKioqIikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NvdXJjZT4KKyAgICAgICAgICAgICAgICAgICAgICAgIDwvY29uZmlndXJhdGlvbj4KKyAgICAgICAgICAgICAgICAgICAgPC9leGVjdXRpb24+CisgICAgICAgICAgICAgICAgPC9leGVjdXRpb25zPgorICAgICAgICAgICAgPC9wbHVnaW4+CisgICAgICAgICAgICAgPHBsdWdpbj4KKyAgICAgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuY29kZWhhdXMubW9qbzwvZ3JvdXBJZD4KKyAgICAgICAgICAgICAgICA8YXJ0aWZhY3RJZD5idWlsZC1oZWxwZXItbWF2ZW4tcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgICAgIDxleGVjdXRpb25zPgorICAgICAgICAgICAgICAgICAgICA8ZXhlY3V0aW9uPgorICAgICAgICAgICAgICAgICAgICAgICAgPGlkPmF0dGFjaC1hcnRpZmFjdHM8L2lkPgorICAgICAgICAgICAgICAgICAgICAgICAgPHBoYXNlPnBhY2thZ2U8L3BoYXNlPgorICAgICAgICAgICAgICAgICAgICAgICAgPGdvYWxzPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxnb2FsPmF0dGFjaC1hcnRpZmFjdDwvZ29hbD4KKyAgICAgICAgICAgICAgICAgICAgICAgIDwvZ29hbHM+CisgICAgICAgICAgICAgICAgICAgICAgICA8Y29uZmlndXJhdGlvbj4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YXJ0aWZhY3RzPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YXJ0aWZhY3Q+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZmlsZT4ke3Byb2plY3QuYnVpbGQuZGlyZWN0b3J5fS9kZXBsb3lvdXRwdXQvU2VydmljZUdhdGV3YXktLiR7cHJvamVjdC52ZXJzaW9ufS56aXA8L2ZpbGU+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHlwZT56aXA8L3R5cGU+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYXJ0aWZhY3Q+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hcnRpZmFjdHM+CisgICAgICAgICAgICAgICAgICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICAgICAgICAgIDwvZXhlY3V0aW9uPgorICAgICAgICAgICAgICAgIDwvZXhlY3V0aW9ucz4KKyAgICAgICAgICAgIDwvcGx1Z2luPgorICAgICAgICA8L3BsdWdpbnM+CisgICAgPC9idWlsZD4KIDwvcHJvamVjdD4KZGlmZiAtLWdpdCBhL3NlcnZpY2VnYXRld2F5L2RlcGxveW1lbnQvc3JjL21haW4vcmVsZWFzZS9iaW4vc3RhcnQuc2ggYi9zZXJ2aWNlZ2F0ZXdheS9kZXBsb3ltZW50L3NyYy9tYWluL3JlbGVhc2UvYmluL3N0YXJ0LnNoCmluZGV4IDIzNWIzMTkuLjUyMWVmM2IgMTAwNjQ0Ci0tLSBhL3NlcnZpY2VnYXRld2F5L2RlcGxveW1lbnQvc3JjL21haW4vcmVsZWFzZS9iaW4vc3RhcnQuc2gKKysrIGIvc2VydmljZWdhdGV3YXkvZGVwbG95bWVudC9zcmMvbWFpbi9yZWxlYXNlL2Jpbi9zdGFydC5zaApAQCAtMTQsNiArMTQsOCBAQAogIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICMqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAjIS9iaW4vYmFzaAorbWtkaXIgbG9ncworbWtkaXIgdGVtcAogY2QgLi4KIGV4cG9ydCBDQVRBTElOQV9CQVNFPSQoY2QgYGRpcm5hbWUgJDBgOyBwd2QpCi1jYXRhbGluYS5zaCBzdGFydApcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKKyRDQVRBTElOQV9IT01FL2Jpbi9jYXRhbGluYS5zaCBzdGFydApcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NlcnZpY2VnYXRld2F5L2RlcGxveW1lbnQvc3JjL21haW4vcmVsZWFzZS9iaW4vc3RvcC5zaCBiL3NlcnZpY2VnYXRld2F5L2RlcGxveW1lbnQvc3JjL21haW4vcmVsZWFzZS9iaW4vc3RvcC5zaAppbmRleCBiY2M2MDQzLi4zNjVkYTAwIDEwMDY0NAotLS0gYS9zZXJ2aWNlZ2F0ZXdheS9kZXBsb3ltZW50L3NyYy9tYWluL3JlbGVhc2UvYmluL3N0b3Auc2gKKysrIGIvc2VydmljZWdhdGV3YXkvZGVwbG95bWVudC9zcmMvbWFpbi9yZWxlYXNlL2Jpbi9zdG9wLnNoCkBAIC0xNiw0ICsxNiw0IEBACiAjIS9iaW4vYmFzaAogY2QgLi4KIGV4cG9ydCBDQVRBTElOQV9CQVNFPSQoY2QgYGRpcm5hbWUgJDBgOyBwd2QpCi1jYXRhbGluYS5zaCBzdG9wClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQorJENBVEFMSU5BX0hPTUUvYmluL2NhdGFsaW5hLnNoIHN0b3AKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zZXJ2aWNlZ2F0ZXdheS9wb20ueG1sIGIvc2VydmljZWdhdGV3YXkvcG9tLnhtbAppbmRleCAzODM2ZGQ1Li40YjJlZDQ1IDEwMDY0NAotLS0gYS9zZXJ2aWNlZ2F0ZXdheS9wb20ueG1sCisrKyBiL3NlcnZpY2VnYXRld2F5L3BvbS54bWwKQEAgLTIxLDI3MSArMjEsMTI5IEBACiAgICAgICA8YXJ0aWZhY3RJZD5nc28tZ3VpPC9hcnRpZmFjdElkPgogICAgICAgPHZlcnNpb24+MS4wLjAtU05BUFNIT1Q8L3ZlcnNpb24+CiAgICAgPC9wYXJlbnQ+Ci0gICAgPGFydGlmYWN0SWQ+c2VydmljZWdhdGV3YXk8L2FydGlmYWN0SWQ+Ci0gICAgPG5hbWU+c2VydmljZWdhdGV3YXk8L25hbWU+CisgICAgPGdyb3VwSWQ+b3JnLm9wZW5vLmdzby5ndWk8L2dyb3VwSWQ+CisgICAgPGFydGlmYWN0SWQ+c2VydmljZS1nYXRld2F5LXJvb3Q8L2FydGlmYWN0SWQ+CisgICAgPHZlcnNpb24+MS4wLjAtU05BUFNIT1Q8L3ZlcnNpb24+CisgICAgPG5hbWU+U2VydmljZUdhdGV3YXlSb290PC9uYW1lPgogICAgIDxwYWNrYWdpbmc+cG9tPC9wYWNrYWdpbmc+CiAKICAgICA8cHJvcGVydGllcz4KICAgICAgICAgPHByb2plY3QuYnVpbGQuc291cmNlRW5jb2Rpbmc+VVRGLTg8L3Byb2plY3QuYnVpbGQuc291cmNlRW5jb2Rpbmc+CisgICAgICAgIDxjeGYudmVyc2lvbj4zLjEuNjwvY3hmLnZlcnNpb24+CiAgICAgPC9wcm9wZXJ0aWVzPgogICAgIDxtb2R1bGVzPgogICAgICAgICA8bW9kdWxlPnNlcnZpY2U8L21vZHVsZT4KICAgICAgICAgPG1vZHVsZT5kZXBsb3ltZW50PC9tb2R1bGU+CiAgICAgPC9tb2R1bGVzPgorICAgIDxzY20+CisgICAgICAgIDx0YWc+SEVBRDwvdGFnPgorICAgIDwvc2NtPgorICAgICAgICA8ZGVwZW5kZW5jaWVzPgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPm9yZy5vcGVuby5jb21tb24tc2VydmljZXMuY29tbW9uLXV0aWxpdGllczwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPmNvbW1vbmxpYi1jYmI8L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8dmVyc2lvbj4xLjAuMC1TTkFQU0hPVDwvdmVyc2lvbj4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPm9yZy5vcGVuby5jb21tb24tc2VydmljZXMuY29tbW9uLXV0aWxpdGllczwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPmNvbW1vbmxpYi1yZXN0Y2xpZW50PC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+MS4wLjAtU05BUFNIT1Q8L3ZlcnNpb24+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLmN4ZjwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPmN4Zi1ydC1mcm9udGVuZC1qYXhyczwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjMuMS42PC92ZXJzaW9uPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+Y29tbW9ucy1odHRwY2xpZW50PC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+Y29tbW9ucy1odHRwY2xpZW50PC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+My4xPC92ZXJzaW9uPgorICAgICAgICA8L2RlcGVuZGVuY3k+CiAKLSAgICA8cHJvZmlsZXM+Ci0gICAgICAgIDxwcm9maWxlPgotICAgICAgICAgICAgPGFjdGl2YXRpb24+Ci0gICAgICAgICAgICAgICAgPGZpbGU+Ci0gICAgICAgICAgICAgICAgICAgIDxleGlzdHM+c3JjL21haW4vcmVsZWFzZS9wdWI8L2V4aXN0cz4KLSAgICAgICAgICAgICAgICA8L2ZpbGU+Ci0gICAgICAgICAgICA8L2FjdGl2YXRpb24+Ci0gICAgICAgICAgICA8YnVpbGQ+Ci0gICAgICAgICAgICAgICAgPHBsdWdpbnM+Ci0gICAgICAgICAgICAgICAgICAgIDxwbHVnaW4+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLm1hdmVuLnBsdWdpbnM8L2dyb3VwSWQ+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1jb21waWxlci1wbHVnaW48L2FydGlmYWN0SWQ+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8dmVyc2lvbj4zLjM8L3ZlcnNpb24+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8Y29uZmlndXJhdGlvbj4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c291cmNlPjEuODwvc291cmNlPgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YXJnZXQ+MS44PC90YXJnZXQ+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8L2NvbmZpZ3VyYXRpb24+Ci0gICAgICAgICAgICAgICAgICAgIDwvcGx1Z2luPgotICAgICAgICAgICAgICAgICAgICA8cGx1Z2luPgotICAgICAgICAgICAgICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgotICAgICAgICAgICAgICAgICAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tZGVwZW5kZW5jeS1wbHVnaW48L2FydGlmYWN0SWQ+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8dmVyc2lvbj4yLjEwPC92ZXJzaW9uPgotICAgICAgICAgICAgICAgICAgICAgICAgPGV4ZWN1dGlvbnM+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGV4ZWN1dGlvbj4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlkPmNvcHktZGVwZW5kZW5jaWVzPC9pZD4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBoYXNlPnBhY2thZ2U8L3BoYXNlPgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Z29hbHM+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Z29hbD5jb3B5LWRlcGVuZGVuY2llczwvZ29hbD4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9nb2Fscz4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3V0cHV0RGlyZWN0b3J5PiR7cHJvamVjdC5idWlsZC5kaXJlY3Rvcnl9L2RlcGxveWRlcGVuZGVuY2lzPC9vdXRwdXREaXJlY3Rvcnk+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3ZlcldyaXRlUmVsZWFzZXM+ZmFsc2U8L292ZXJXcml0ZVJlbGVhc2VzPgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG92ZXJXcml0ZVNuYXBzaG90cz5mYWxzZTwvb3ZlcldyaXRlU25hcHNob3RzPgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG92ZXJXcml0ZUlmTmV3ZXI+dHJ1ZTwvb3ZlcldyaXRlSWZOZXdlcj4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbmNsdWRlU2NvcGU+Y29tcGlsZTwvaW5jbHVkZVNjb3BlPgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGluY2x1ZGVTY29wZT5ydW50aW1lPC9pbmNsdWRlU2NvcGU+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvY29uZmlndXJhdGlvbj4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2V4ZWN1dGlvbj4KLSAgICAgICAgICAgICAgICAgICAgICAgIDwvZXhlY3V0aW9ucz4KLSAgICAgICAgICAgICAgICAgICAgPC9wbHVnaW4+Ci0gICAgICAgICAgICAgICAgICAgIDxwbHVnaW4+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuY29kZWhhdXMuZ21hdmVuPC9ncm91cElkPgotICAgICAgICAgICAgICAgICAgICAgICAgPGFydGlmYWN0SWQ+Z21hdmVuLXBsdWdpbjwvYXJ0aWZhY3RJZD4KLSAgICAgICAgICAgICAgICAgICAgICAgIDx2ZXJzaW9uPjEuNTwvdmVyc2lvbj4KLSAgICAgICAgICAgICAgICAgICAgICAgIDxleGVjdXRpb25zPgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxleGVjdXRpb24+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpZD5tYWtlIG5ldyBqYXI8L2lkPgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGhhc2U+cGFja2FnZTwvcGhhc2U+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxnb2Fscz4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxnb2FsPmV4ZWN1dGU8L2dvYWw+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZ29hbHM+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjb25maWd1cmF0aW9uPgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNvdXJjZT4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlIFN0cmluZyBnZXRXZWJDb250ZXh0RnJvbU1hbmlmZXN0KEZpbGUgd2FyRmlsZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjb250ZXh0ID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqYXZhLnV0aWwuamFyLkphckZpbGUgamFyRmlsZSA9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqYXJGaWxlID0gbmV3IGphdmEudXRpbC5qYXIuSmFyRmlsZSh3YXJGaWxlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0ID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqYXJGaWxlLmdldE1hbmlmZXN0KCkuZ2V0TWFpbkF0dHJpYnV0ZXMoKS5nZXRWYWx1ZSgiV2ViQ29udGV4dC1OYW1lIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IGNvbnRleHQgPT0gbnVsbCA/ICJST09UIiA6IGNvbnRleHQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IGNvbnRleHQucmVwbGFjZSgiXCIsICIvIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IGNvbnRleHQucmVwbGFjZUFsbCgiWy9dezIsfSIsICIvIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IGNvbnRleHQuZW5kc1dpdGgoIi8iKSA/IGNvbnRleHQuc3Vic3RyaW5nKDAsIGNvbnRleHQubGVuZ3RoKCkgLSAxKSA6IGNvbnRleHQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IGNvbnRleHQuc3RhcnRzV2l0aCgiLyIpID8gY29udGV4dC5zdWJzdHJpbmcoMSwgY29udGV4dC5sZW5ndGgoKSkgOiBjb250ZXh0OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQgPSBjb250ZXh0LnJlcGxhY2VBbGwoIi8iLCAiIyIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tY29udGV4dCBlcm9yOiAiLGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQgPSAiUk9PVCI7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoamFyRmlsZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamFyRmlsZS5jbG9zZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tY29udGV4dCBpczogIiArIGNvbnRleHQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMSIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdCBjb250ZXh0cz1uZXcgQXJyYXlMaXN0KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwbG95ZGVwZW5kZW5jaXNkaXIgPSAiJHtwcm9qZWN0LmJ1aWxkLmRpcmVjdG9yeX0vZGVwbG95ZGVwZW5kZW5jaXMiOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuemlwZGlyID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJHtwcm9qZWN0LmJ1aWxkLmRpcmVjdG9yeX0vZGVwbG95dW56aXAiOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dGRpciA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiR7cHJvamVjdC5idWlsZC5kaXJlY3Rvcnl9L2RlcGxveW91dHB1dCI7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb3VyY2VzZGlyID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJHtwcm9qZWN0LmJhc2VkaXJ9L3NyYy9tYWluL3JlbGVhc2UiOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGphcnNkaXIgPSAiJHt1bnppcGRpcn0vbGliIjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b29scGF0aCA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiR7cHJvamVjdC5idWlsZC5kaXJlY3Rvcnl9L2RlcGxveW91dHB1dGphcnMiOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0yIikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQgPSBuZXcgQW50QnVpbGRlcigpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW50LmRlbGV0ZShkaXI6ICIke3VuemlwZGlyfSIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW50Lm1rZGlyKGRpcjogIiR7dW56aXBkaXJ9IikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQubWtkaXIoZGlyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xwYXRoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFudC5kZWxldGUoZGlyOiAiJHtvdXRwdXRkaXJ9IikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQubWtkaXIoZGlyOiAiJHtvdXRwdXRkaXJ9IikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQuZGVsZXRlKGRpcjogIiR7amFyc2Rpcn0iKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFudC5ta2RpcihkaXI6ICIke2phcnNkaXJ9IikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRGaWxlTmFtZSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiR7cHJvamVjdC5uYW1lfSIKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMyIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYobmV3Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZSgiJHtkZXBsb3lkZXBlbmRlbmNpc2Rpcn0iKS5leGlzdHMoKSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChGaWxlIGZpbGUgOiBuZXcgRmlsZSgiJHtkZXBsb3lkZXBlbmRlbmNpc2Rpcn0iKS5saXN0RmlsZXMoKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGZpbGVQYXRoID0gZmlsZS5nZXRBYnNvbHV0ZVBhdGgoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZSA9IGZpbGUuZ2V0TmFtZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWxlTmFtZS5lbmRzV2l0aCgiLndhciIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IGdldFdlYkNvbnRleHRGcm9tTWFuaWZlc3QoZmlsZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQubWtkaXIoZGlyOiAiJHt1bnppcGRpcn0vd2ViYXBwcy8iICsgY29udGV4dCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQudW56aXAoc3JjOiBmaWxlUGF0aCwgZGVzdDogIiR7dW56aXBkaXJ9L3dlYmFwcHMvIiArIGNvbnRleHQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW50LmNvcHkodG9kaXI6IHRvb2xwYXRoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXNldChkaXI6ICIke3VuemlwZGlyfS93ZWJhcHBzLyIgKyBjb250ZXh0ICsgIi9XRUItSU5GL2xpYiIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlKG5hbWU6ICIqLmphciIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0cy5hZGQodG9vbHBhdGgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW50LmNvcHkodG9kaXI6IHRvb2xwYXRoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXNldChkaXI6ICIke2RlcGxveWRlcGVuZGVuY2lzZGlyfSIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlKG5hbWU6ICIqLmphciIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLm9wZW5vLmdzbzwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm9yZy5vcGVuby5nc28uY29tbXN2Yy5jb21tb248L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8dmVyc2lvbj4xLjAuMC1TTkFQU0hPVDwvdmVyc2lvbj4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPm9yZy5zcHJpbmdmcmFtZXdvcms8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5zcHJpbmctYmVhbnM8L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8dmVyc2lvbj4zLjEuMC5SRUxFQVNFPC92ZXJzaW9uPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLnNwcmluZ2ZyYW1ld29yazwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPnNwcmluZy1jb250ZXh0PC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+My4xLjAuUkVMRUFTRTwvdmVyc2lvbj4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPm9yZy5zcHJpbmdmcmFtZXdvcms8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5zcHJpbmctamRiYzwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjMuMS4wLlJFTEVBU0U8L3ZlcnNpb24+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuc3ByaW5nZnJhbWV3b3JrPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+c3ByaW5nLXdlYjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjMuMS4wLlJFTEVBU0U8L3ZlcnNpb24+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5vcmcub3NnaTwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm9yZy5vc2dpLmNvcmU8L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8dmVyc2lvbj40LjEuMDwvdmVyc2lvbj4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPm9yZy5teWJhdGlzPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+bXliYXRpczwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjMuMi43PC92ZXJzaW9uPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLm15YmF0aXM8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5teWJhdGlzLXNwcmluZzwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjEuMi4wPC92ZXJzaW9uPgorICAgICAgICAgICAgPHR5cGU+amFyPC90eXBlPgorICAgICAgICAgICAgPHNjb3BlPmNvbXBpbGU8L3Njb3BlPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+Y29tLm1jaGFuZ2U8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5jM3AwPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+MC45LjIuMTwvdmVyc2lvbj4KKyAgICAgICAgICAgIDx0eXBlPmphcjwvdHlwZT4KKyAgICAgICAgICAgIDxzY29wZT5jb21waWxlPC9zY29wZT4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPm9yZy5jb2RlaGF1cy5qYWNrc29uPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+amFja3Nvbi1qYXhyczwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjEuOS4yPC92ZXJzaW9uPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+amF2YXguc2VydmxldDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPmphdmF4LnNlcnZsZXQtYXBpPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+My4xLjA8L3ZlcnNpb24+CisgICAgICAgIDwvZGVwZW5kZW5jeT4gICAgICAgIAorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPmNvbS5nb29nbGVjb2RlLmptb2NraXQ8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5qbW9ja2l0PC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+MS4xPC92ZXJzaW9uPgorICAgICAgICAgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+anVuaXQ8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5qdW5pdDwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjQuMTI8L3ZlcnNpb24+CisgICAgICAgICAgICA8c2NvcGU+dGVzdDwvc2NvcGU+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuam1vY2tpdDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPmptb2NraXQtY292ZXJhZ2U8L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8dmVyc2lvbj4xLjE4PC92ZXJzaW9uPgorICAgICAgICAgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+Y29tLmgyZGF0YWJhc2U8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5oMjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjEuNC4xOTA8L3ZlcnNpb24+CisgICAgICAgICAgICA8c2NvcGU+dGVzdDwvc2NvcGU+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICA8L2RlcGVuZGVuY2llcz4KIAogCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS00IikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQuY29weSh0b2RpcjogdG9vbHBhdGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc2V0KGRpcjogIiR7cHJvamVjdC5idWlsZC5kaXJlY3Rvcnl9IikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1ZGUobmFtZTogIiouamFyIikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW50LmNvcHkodG9kaXI6ICIke3VuemlwZGlyfSIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc2V0KGRpcjogIiR7cmVzb3VyY2VzZGlyfSIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlKG5hbWU6ICIqKiIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY29tcGlsZSBweXRob24gLnB5IGZpbGVzLiAqLwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tNS0tLS0tLS0tLS0tLS0tLS0tLSIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHl0aG9uRmlsZSA9ICIke3Byb2plY3QuYmFzZWRpcn0vc3JjL21haW4vcHl0aG9uIjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihuZXcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlKHB5dGhvbkZpbGUpLmV4aXN0cygpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQuZXhlYyhkaXI6ICIke3Byb2plY3QuYmFzZWRpcn0vc3JjL21haW4vcHl0aG9uIiwgZXhlY3V0YWJsZTogInB5dGhvbiIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcodmFsdWU6ICItbSIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnKHZhbHVlOiAiY29tcGlsZWFsbCIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnKHZhbHVlOiAiLiIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW50LmNvcHkodG9kaXI6ICIke3VuemlwZGlyfSIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc2V0KGRpcjogIiR7cHJvamVjdC5iYXNlZGlyfS9zcmMvbWFpbi9weXRob24iKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVkZShuYW1lOiAiKiovKi4qIikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNsdWRlKG5hbWU6ICIqKi8qLnB5IikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZWUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0mZ3Q7Jmd0OyZndDsiK2VlZS50b1N0cmluZygpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjb3B5IGFsbCBkZXBlbmRlbmNpZXMgdG8gJEFQUF9ST09UL2xpYi4gKi8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTYtLS0tLS0tLS0tLS0tLS0tLS0iKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcihTdHJpbmcgdGVtUGF0aCA6IGNvbnRleHRzKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihuZXcgRmlsZSh0ZW1QYXRoKS5leGlzdHMoKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKEZpbGUgZmlsZSA6IG5ldyBGaWxlKHRlbVBhdGgpLmxpc3RGaWxlcygpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZU5hbWUgPSBmaWxlLmdldE5hbWUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZU5hbWUuZW5kc1dpdGgoIi5qYXIiKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFudC5jb3B5KGZpbGU6IGZpbGUuZ2V0QWJzb2x1dGVQYXRoKCksIHRvZGlyOiAiJHtqYXJzZGlyfSIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGRlcGxveSB0aGUgdXB6aXAgZmlsZSB0byAke291dHB1dGRpcn0vJHtvdXRwdXRGaWxlTmFtZX0gKi8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTctLS0tLS0tLS0tLS0tLS0tLS0iKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dEZpbGVOYW1lID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRGaWxlTmFtZS5lbmRzV2l0aCgiRGVwbG95bWVudCIpP291dHB1dEZpbGVOYW1lOm91dHB1dEZpbGVOYW1lKyJEZXBsb3ltZW50IjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRGaWxlTmFtZSA9IG91dHB1dEZpbGVOYW1lLnN1YnN0cmluZygwLCBvdXRwdXRGaWxlTmFtZS5sZW5ndGgoKSAtCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRlcGxveW1lbnQiLmxlbmd0aCgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRGaWxlTmFtZSA9IG91dHB1dEZpbGVOYW1lICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLSR7cHJvamVjdC52ZXJzaW9ufS56aXAiOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0RmlsZU5hbWUgPSBvdXRwdXRGaWxlTmFtZS5yZXBsYWNlKCItU05BUFNIT1QiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIuIiArIG5ldyBqYXZhLnRleHQuU2ltcGxlRGF0ZUZvcm1hdCgieXl5eU1NZGRISG1tc3MiKS5mb3JtYXQoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IERhdGUoKSkpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW50LmRlbGV0ZShkaXI6ICIke3VuemlwZGlyfS93ZWJhcHBzL1JPT1QvV0VCLUlORi9saWIiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQubWtkaXIoZGlyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIke3VuemlwZGlyfS93ZWJhcHBzL1JPT1QvV0VCLUlORi9saWIiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnQuY29weSh0b2RpcjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJHt1bnppcGRpcn0vd2ViYXBwcy9ST09UL1dFQi1JTkYvbGliIikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzZXQoZGlyOiAiJHt1bnppcGRpcn0vbGliIikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1ZGUobmFtZTogIm9yZy5vcGVuby5jb21tb24tc2VydmljZXMuY29tbW9uLXV0aWxpdGllcy5jb21tb25saWIuZGItKi5qYXIiKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1ZGUobmFtZTogIm9yZy5vcGVuby5jb21tb24tc2VydmljZXMuY29tbW9uLXV0aWxpdGllcy5jb21tb25saWIuY2JiLSouamFyIikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW50LmRlbGV0ZSgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc2V0KGRpcjogIiR7dW56aXBkaXJ9L2xpYiIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlKG5hbWU6ICJvcmcub3Blbm8uY29tbW9uLXNlcnZpY2VzLmNvbW1vbi11dGlsaXRpZXMuY29tbW9ubGliLmRiLSouamFyIikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlKG5hbWU6ICJvcmcub3Blbm8uY29tbW9uLXNlcnZpY2VzLmNvbW1vbi11dGlsaXRpZXMuY29tbW9ubGliLmNiYi0qLmphciIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGdlbmVyYXRlIGRlcGVuZGVuY2llcy5saXN0IGluICRBUFBfUk9PVC9saWIuIFJlcXVpcmVtZW50IGZvciBpbnN0YWxsIGRpc2sgc2l6ZS4gKi8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTgtLS0tLS0tLS0tLS0tLS0tLS0iKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGVuZGVuY2llc1BhdGg9IiR7dW56aXBkaXJ9L2xpYiI7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWYgd3JpdGVyID0gbmV3IEZpbGUoZGVwZW5kZW5jaWVzUGF0aCsiL2RlcGVuZGVuY2llcy5saXN0IikubmV3V3JpdGVyKCdVVEYtOCcpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgZmlsZU5hbWUgOiBuZXcgRmlsZShkZXBlbmRlbmNpZXNQYXRoKS5saXN0KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZU5hbWUuZW5kc1dpdGgoIi5qYXIiKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZUxpbmUoZmlsZU5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLmNsb3NlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBtYWtlIHRoZSBhcmNoaXZlLiAqLwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tOS0tLS0tLS0tLS0tLS0tLS0tLSIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW50LnppcChkZXN0ZmlsZToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJHtvdXRwdXRkaXJ9LyR7b3V0cHV0RmlsZU5hbWV9IikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzZXQoZGlyOiAiJHt1bnppcGRpcn0iKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjbHVkZShuYW1lOiAiKiovLmdpdGlnbm9yZSIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tZG9uZSIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NvdXJjZT4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9jb25maWd1cmF0aW9uPgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZXhlY3V0aW9uPgotICAgICAgICAgICAgICAgICAgICAgICAgPC9leGVjdXRpb25zPgotICAgICAgICAgICAgICAgICAgICA8L3BsdWdpbj4KLSAgICAgICAgICAgICAgICA8L3BsdWdpbnM+Ci0gICAgICAgICAgICA8L2J1aWxkPgotICAgICAgICA8L3Byb2ZpbGU+Ci0gICAgPC9wcm9maWxlcz4KIDwvcHJvamVjdD4KZGlmZiAtLWdpdCBhL3NlcnZpY2VnYXRld2F5L3NlcnZpY2UvcG9tLnhtbCBiL3NlcnZpY2VnYXRld2F5L3NlcnZpY2UvcG9tLnhtbAppbmRleCAzZmY2ZmRjLi5iMGNkNTUxIDEwMDY0NAotLS0gYS9zZXJ2aWNlZ2F0ZXdheS9zZXJ2aWNlL3BvbS54bWwKKysrIGIvc2VydmljZWdhdGV3YXkvc2VydmljZS9wb20ueG1sCkBAIC0xNywxNTUgKzE3LDYzIEBACiA8cHJvamVjdCB4bWxucz0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIgogICAgIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIGh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL3hzZC9tYXZlbi00LjAuMC54c2QiPgogICAgIDxtb2RlbFZlcnNpb24+NC4wLjA8L21vZGVsVmVyc2lvbj4KLSAgICA8cGFyZW50PgorICAgIDxwYXJlbnQ+IAogICAgICAgICA8Z3JvdXBJZD5vcmcub3Blbm8uZ3NvLmd1aTwvZ3JvdXBJZD4KLSAgICAgICAgPGFydGlmYWN0SWQ+c2VydmljZWdhdGV3YXk8L2FydGlmYWN0SWQ+CisgICAgICAgIDxhcnRpZmFjdElkPnNlcnZpY2UtZ2F0ZXdheS1yb290PC9hcnRpZmFjdElkPgogICAgICAgICA8dmVyc2lvbj4xLjAuMC1TTkFQU0hPVDwvdmVyc2lvbj4KICAgICA8L3BhcmVudD4KIAotICAgIDxhcnRpZmFjdElkPnNlcnZpY2U8L2FydGlmYWN0SWQ+Ci0gICAgPG5hbWU+c2VydmljZTwvbmFtZT4KKyAgICA8YXJ0aWZhY3RJZD5zZXJ2aWNlLWdhdGV3YXktc2VydmljZTwvYXJ0aWZhY3RJZD4KKyAgICA8bmFtZT5TZXJ2aWNlR2F0ZXdheVNlcnZpY2U8L25hbWU+CiAgICAgPHBhY2thZ2luZz53YXI8L3BhY2thZ2luZz4KLQotICAgIDxkZXBlbmRlbmNpZXM+Ci0gICAgICAgIDxkZXBlbmRlbmN5PgotICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLm9wZW5vLmNvbW1vbi1zZXJ2aWNlcy5jb21tb24tdXRpbGl0aWVzPC9ncm91cElkPgotICAgICAgICAgICAgPGFydGlmYWN0SWQ+Y29tbW9ubGliLWNiYjwvYXJ0aWZhY3RJZD4KLSAgICAgICAgICAgIDx2ZXJzaW9uPjEuMC4wLVNOQVBTSE9UPC92ZXJzaW9uPgotICAgICAgICA8L2RlcGVuZGVuY3k+Ci0gICAgICAgIDwhLS0gcm9hIC0tPgotICAgICAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgICAgIDxncm91cElkPm9yZy5vcGVuby5jb21tb24tc2VydmljZXMuY29tbW9uLXV0aWxpdGllczwvZ3JvdXBJZD4KLSAgICAgICAgICAgIDxhcnRpZmFjdElkPmNvbW1vbmxpYi1yZXN0Y2xpZW50PC9hcnRpZmFjdElkPgotICAgICAgICAgICAgPHZlcnNpb24+MS4wLjAtU05BUFNIT1Q8L3ZlcnNpb24+Ci0gICAgICAgIDwvZGVwZW5kZW5jeT4KLSAgICAgICAgPGRlcGVuZGVuY3k+Ci0gICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLmN4ZjwvZ3JvdXBJZD4KLSAgICAgICAgICAgIDxhcnRpZmFjdElkPmN4Zi1ydC1mcm9udGVuZC1qYXhyczwvYXJ0aWZhY3RJZD4KLSAgICAgICAgICAgIDx2ZXJzaW9uPjMuMS42PC92ZXJzaW9uPgotICAgICAgICA8L2RlcGVuZGVuY3k+Ci0gICAgICAgIDxkZXBlbmRlbmN5PgotICAgICAgICAgICAgPGdyb3VwSWQ+Y29tbW9ucy1odHRwY2xpZW50PC9ncm91cElkPgotICAgICAgICAgICAgPGFydGlmYWN0SWQ+Y29tbW9ucy1odHRwY2xpZW50PC9hcnRpZmFjdElkPgotICAgICAgICAgICAgPHZlcnNpb24+My4xPC92ZXJzaW9uPgotICAgICAgICA8L2RlcGVuZGVuY3k+Ci0KLSAgICAgICAgPGRlcGVuZGVuY3k+Ci0gICAgICAgICAgICA8Z3JvdXBJZD5vcmcub3Blbm8uZ3NvPC9ncm91cElkPgotICAgICAgICAgICAgPGFydGlmYWN0SWQ+b3JnLm9wZW5vLmdzby5jb21tc3ZjLmNvbW1vbjwvYXJ0aWZhY3RJZD4KLSAgICAgICAgICAgIDx2ZXJzaW9uPjEuMC4wLVNOQVBTSE9UPC92ZXJzaW9uPgotICAgICAgICA8L2RlcGVuZGVuY3k+Ci0gICAgICAgIDxkZXBlbmRlbmN5PgotICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLnNwcmluZ2ZyYW1ld29yazwvZ3JvdXBJZD4KLSAgICAgICAgICAgIDxhcnRpZmFjdElkPnNwcmluZy1iZWFuczwvYXJ0aWZhY3RJZD4KLSAgICAgICAgICAgIDx2ZXJzaW9uPjMuMS4wLlJFTEVBU0U8L3ZlcnNpb24+Ci0gICAgICAgIDwvZGVwZW5kZW5jeT4KLSAgICAgICAgPGRlcGVuZGVuY3k+Ci0gICAgICAgICAgICA8Z3JvdXBJZD5vcmcuc3ByaW5nZnJhbWV3b3JrPC9ncm91cElkPgotICAgICAgICAgICAgPGFydGlmYWN0SWQ+c3ByaW5nLWNvbnRleHQ8L2FydGlmYWN0SWQ+Ci0gICAgICAgICAgICA8dmVyc2lvbj4zLjEuMC5SRUxFQVNFPC92ZXJzaW9uPgotICAgICAgICA8L2RlcGVuZGVuY3k+Ci0gICAgICAgIDxkZXBlbmRlbmN5PgotICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLnNwcmluZ2ZyYW1ld29yazwvZ3JvdXBJZD4KLSAgICAgICAgICAgIDxhcnRpZmFjdElkPnNwcmluZy1qZGJjPC9hcnRpZmFjdElkPgotICAgICAgICAgICAgPHZlcnNpb24+My4xLjAuUkVMRUFTRTwvdmVyc2lvbj4KLSAgICAgICAgPC9kZXBlbmRlbmN5PgotICAgICAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgICAgIDxncm91cElkPm9yZy5zcHJpbmdmcmFtZXdvcms8L2dyb3VwSWQ+Ci0gICAgICAgICAgICA8YXJ0aWZhY3RJZD5zcHJpbmctd2ViPC9hcnRpZmFjdElkPgotICAgICAgICAgICAgPHZlcnNpb24+My4xLjAuUkVMRUFTRTwvdmVyc2lvbj4KLSAgICAgICAgPC9kZXBlbmRlbmN5PgotICAgICAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgICAgIDxncm91cElkPm9yZy5vc2dpPC9ncm91cElkPgotICAgICAgICAgICAgPGFydGlmYWN0SWQ+b3JnLm9zZ2kuY29yZTwvYXJ0aWZhY3RJZD4KLSAgICAgICAgICAgIDx2ZXJzaW9uPjQuMS4wPC92ZXJzaW9uPgotICAgICAgICA8L2RlcGVuZGVuY3k+Ci0gICAgICAgIDxkZXBlbmRlbmN5PgotICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLm15YmF0aXM8L2dyb3VwSWQ+Ci0gICAgICAgICAgICA8YXJ0aWZhY3RJZD5teWJhdGlzPC9hcnRpZmFjdElkPgotICAgICAgICAgICAgPHZlcnNpb24+My4yLjc8L3ZlcnNpb24+Ci0gICAgICAgIDwvZGVwZW5kZW5jeT4KLSAgICAgICAgPGRlcGVuZGVuY3k+Ci0gICAgICAgICAgICA8Z3JvdXBJZD5vcmcubXliYXRpczwvZ3JvdXBJZD4KLSAgICAgICAgICAgIDxhcnRpZmFjdElkPm15YmF0aXMtc3ByaW5nPC9hcnRpZmFjdElkPgotICAgICAgICAgICAgPHZlcnNpb24+MS4yLjA8L3ZlcnNpb24+Ci0gICAgICAgICAgICA8dHlwZT5qYXI8L3R5cGU+Ci0gICAgICAgICAgICA8c2NvcGU+Y29tcGlsZTwvc2NvcGU+Ci0gICAgICAgIDwvZGVwZW5kZW5jeT4KLSAgICAgICAgPGRlcGVuZGVuY3k+Ci0gICAgICAgICAgICA8Z3JvdXBJZD5jb20ubWNoYW5nZTwvZ3JvdXBJZD4KLSAgICAgICAgICAgIDxhcnRpZmFjdElkPmMzcDA8L2FydGlmYWN0SWQ+Ci0gICAgICAgICAgICA8dmVyc2lvbj4wLjkuMi4xPC92ZXJzaW9uPgotICAgICAgICAgICAgPHR5cGU+amFyPC90eXBlPgotICAgICAgICAgICAgPHNjb3BlPmNvbXBpbGU8L3Njb3BlPgotICAgICAgICA8L2RlcGVuZGVuY3k+Ci0gICAgICAgIDxkZXBlbmRlbmN5PgotICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmNvZGVoYXVzLmphY2tzb248L2dyb3VwSWQ+Ci0gICAgICAgICAgICA8YXJ0aWZhY3RJZD5qYWNrc29uLWpheHJzPC9hcnRpZmFjdElkPgotICAgICAgICAgICAgPHZlcnNpb24+MS45LjI8L3ZlcnNpb24+Ci0gICAgICAgIDwvZGVwZW5kZW5jeT4KLSAgICAgICAgPGRlcGVuZGVuY3k+Ci0gICAgICAgICAgICA8Z3JvdXBJZD5qYXZheC5zZXJ2bGV0PC9ncm91cElkPgotICAgICAgICAgICAgPGFydGlmYWN0SWQ+amF2YXguc2VydmxldC1hcGk8L2FydGlmYWN0SWQ+Ci0gICAgICAgICAgICA8dmVyc2lvbj4zLjEuMDwvdmVyc2lvbj4KLSAgICAgICAgPC9kZXBlbmRlbmN5PiAgICAgICAgCi0gICAgICAgIDxkZXBlbmRlbmN5PgotICAgICAgICAgICAgPGdyb3VwSWQ+Y29tLmdvb2dsZWNvZGUuam1vY2tpdDwvZ3JvdXBJZD4KLSAgICAgICAgICAgIDxhcnRpZmFjdElkPmptb2NraXQ8L2FydGlmYWN0SWQ+Ci0gICAgICAgICAgICA8dmVyc2lvbj4xLjE8L3ZlcnNpb24+Ci0gICAgICAgICAgICA8c2NvcGU+dGVzdDwvc2NvcGU+Ci0gICAgICAgIDwvZGVwZW5kZW5jeT4KLSAgICAgICAgPGRlcGVuZGVuY3k+Ci0gICAgICAgICAgICA8Z3JvdXBJZD5qdW5pdDwvZ3JvdXBJZD4KLSAgICAgICAgICAgIDxhcnRpZmFjdElkPmp1bml0PC9hcnRpZmFjdElkPgotICAgICAgICAgICAgPHZlcnNpb24+NC4xMjwvdmVyc2lvbj4KLSAgICAgICAgICAgIDxzY29wZT50ZXN0PC9zY29wZT4KLSAgICAgICAgPC9kZXBlbmRlbmN5PgotICAgICAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgICAgIDxncm91cElkPm9yZy5qbW9ja2l0PC9ncm91cElkPgotICAgICAgICAgICAgPGFydGlmYWN0SWQ+am1vY2tpdC1jb3ZlcmFnZTwvYXJ0aWZhY3RJZD4KLSAgICAgICAgICAgIDx2ZXJzaW9uPjEuMTg8L3ZlcnNpb24+Ci0gICAgICAgICAgICA8c2NvcGU+dGVzdDwvc2NvcGU+Ci0gICAgICAgIDwvZGVwZW5kZW5jeT4KLSAgICAgICAgPGRlcGVuZGVuY3k+Ci0gICAgICAgICAgICA8Z3JvdXBJZD5jb20uaDJkYXRhYmFzZTwvZ3JvdXBJZD4KLSAgICAgICAgICAgIDxhcnRpZmFjdElkPmgyPC9hcnRpZmFjdElkPgotICAgICAgICAgICAgPHZlcnNpb24+MS40LjE5MDwvdmVyc2lvbj4KLSAgICAgICAgICAgIDxzY29wZT50ZXN0PC9zY29wZT4KLSAgICAgICAgPC9kZXBlbmRlbmN5PgotICAgIDwvZGVwZW5kZW5jaWVzPgotICAgIAorICAgIDxwcm9wZXJ0aWVzPgorICAgICAgICA8cHJvamVjdC5idWlsZC5zb3VyY2VFbmNvZGluZz5VVEYtODwvcHJvamVjdC5idWlsZC5zb3VyY2VFbmNvZGluZz4KKyAgICAgICAgPGN4Zi52ZXJzaW9uPjMuMS42PC9jeGYudmVyc2lvbj4KKyAgICAgICAgPHNsZjRqLnZlcnNpb24+MS42LjE8L3NsZjRqLnZlcnNpb24+CisgICAgICAgICA8bWF2ZW4udGVzdC5za2lwPmZhbHNlPC9tYXZlbi50ZXN0LnNraXA+CisgICAgICAgICA8bWF2ZW4udGVzdC5mYWlsdXJlLmlnbm9yZT5mYWxzZTwvbWF2ZW4udGVzdC5mYWlsdXJlLmlnbm9yZT4KKyAgICA8L3Byb3BlcnRpZXM+CisgICAKKyAgICA8cHJvZmlsZXM+CisgICAgICAgIDxwcm9maWxlPgorICAgICAgICAgICAgPGlkPmFsbC10ZXN0czwvaWQ+CisgICAgICAgICAgICA8cHJvcGVydGllcz4KKyAgICAgICAgICAgICAgICA8YnVpbGQucHJvZmlsZS5pZD5hbGwtdGVzdHM8L2J1aWxkLnByb2ZpbGUuaWQ+CisgICAgICAgICAgICAgICAgPHNraXAudW5pdC50ZXN0cz5mYWxzZTwvc2tpcC51bml0LnRlc3RzPgorICAgICAgICAgICAgPC9wcm9wZXJ0aWVzPgorICAgICAgICA8L3Byb2ZpbGU+CisgICAgPC9wcm9maWxlcz4KICAgICA8YnVpbGQ+CisgICAgICAgIDxmaW5hbE5hbWU+Uk9PVDwvZmluYWxOYW1lPgogICAgICAgICA8cGx1Z2lucz4KKyAgICAgICAgCTxwbHVnaW4+CisgICAgICAgICAgICAJPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorICAgICAgICAgICAgCTxhcnRpZmFjdElkPm1hdmVuLWNvbXBpbGVyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIAk8dmVyc2lvbj4zLjE8L3ZlcnNpb24+CisgICAgICAgICAgICAJPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICAgICAJCTxzb3VyY2U+MS44PC9zb3VyY2U+CisgICAgICAgICAgICAgICAgCTx0YXJnZXQ+MS44PC90YXJnZXQ+CisgICAgICAgICAgICAJPC9jb25maWd1cmF0aW9uPgorICAgICAgICAJPC9wbHVnaW4+CisgICAgICAgICAgICA8IS0tIFVzZWQgZm9yIHVuaXQgdGVzdHMgLS0+CiAgICAgICAgICAgICA8cGx1Z2luPgogICAgICAgICAgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUubWF2ZW4ucGx1Z2luczwvZ3JvdXBJZD4KICAgICAgICAgICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1zdXJlZmlyZS1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgICAgICAgICAgPHZlcnNpb24+Mi4xOS4xPC92ZXJzaW9uPgogICAgICAgICAgICAgICAgIDxjb25maWd1cmF0aW9uPgotICAgICAgICAgICAgICAgICAgICA8YXJnTGluZT4tWFg6LVVzZVNwbGl0VmVyaWZpZXI8L2FyZ0xpbmU+Ci0gICAgICAgICAgICAgICAgICAgIDxza2lwVGVzdHM+dHJ1ZTwvc2tpcFRlc3RzPgorICAgICAgICAgICAgICAgICAgICA8Zm9ya01vZGU+YWx3YXlzPC9mb3JrTW9kZT4KKyAgICAgICAgICAgICAgICAgICAgPGFyZ0xpbmU+JHtzdXJlZmlyZUFyZ0xpbmV9PC9hcmdMaW5lPgorICAgICAgICAgICAgICAgICAgICA8c2tpcD4ke21hdmVuLnRlc3Quc2tpcH08L3NraXA+CisgICAgICAgICAgICAgICAgICAgIDwhLS0gCisgICAgICAgICAgICAgICAgICAgIDx0ZXN0RmFpbHVyZUlnbm9yZT4ke21hdmVuLnRlc3QuZmFpbHVyZS5pZ25vcmV9PC90ZXN0RmFpbHVyZUlnbm9yZT4KKyAgICAgICAgICAgICAgICAgICAgIC0tPgogICAgICAgICAgICAgICAgICAgICA8dGVzdEZhaWx1cmVJZ25vcmU+dHJ1ZTwvdGVzdEZhaWx1cmVJZ25vcmU+CisgICAgICAgICAgICAgICAgICAgIDwhLS0gRXhjbHVkZXMgaW50ZWdyYXRpb24gdGVzdHMgd2hlbiB1bml0IHRlc3RzIGFyZSBydW4uIC0tPgogICAgICAgICAgICAgICAgICAgICA8ZXhjbHVkZXM+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8ZXhjbHVkZT4ke2V4Y2x1ZGVzRmlsZX08L2V4Y2x1ZGU+CisgICAgICAgICAgICAgICAgICAgICAgICA8ZXhjbHVkZT4qKi9JVCouamF2YTwvZXhjbHVkZT4KICAgICAgICAgICAgICAgICAgICAgPC9leGNsdWRlcz4KICAgICAgICAgICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CiAgICAgICAgICAgICA8L3BsdWdpbj4KLSAgICAgICAgICAgIAotICAgICAgICAgICAgPHBsdWdpbj4KLSAgICAgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuY29kZWhhdXMubW9qbzwvZ3JvdXBJZD4KLSAgICAgICAgICAgICAgICA8YXJ0aWZhY3RJZD5jb2JlcnR1cmEtbWF2ZW4tcGx1Z2luPC9hcnRpZmFjdElkPgotICAgICAgICAgICAgICAgIDx2ZXJzaW9uPjIuNzwvdmVyc2lvbj4KLSAgICAgICAgICAgICAgICA8Y29uZmlndXJhdGlvbj4KLSAgICAgICAgICAgICAgICAgICAgPGZvcm1hdHM+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8Zm9ybWF0Pmh0bWw8L2Zvcm1hdD4KLSAgICAgICAgICAgICAgICAgICAgICAgIDxmb3JtYXQ+eG1sPC9mb3JtYXQ+Ci0gICAgICAgICAgICAgICAgICAgIDwvZm9ybWF0cz4KLSAgICAgICAgICAgICAgICAgICAgPGluc3RydW1lbnRhdGlvbj4KLSAgICAgICAgICAgICAgICAgICAgICAgIDxleGNsdWRlcz4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZXhjbHVkZT5vcmcvKiovKlRlc3QuY2xhc3M8L2V4Y2x1ZGU+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8L2V4Y2x1ZGVzPgotICAgICAgICAgICAgICAgICAgICA8L2luc3RydW1lbnRhdGlvbj4KLSAgICAgICAgICAgICAgICA8L2NvbmZpZ3VyYXRpb24+Ci0gICAgICAgICAgICA8L3BsdWdpbj4KICAgICAgICAgPC9wbHVnaW5zPgogICAgIDwvYnVpbGQ+CiA8L3Byb2plY3Q+CmRpZmYgLS1naXQgYS9zZXJ2aWNlZ2F0ZXdheS9zZXJ2aWNlL3NyYy9tYWluL2phdmEvb3JnL29wZW5vL2dzby9ndWkvc2VydmljZWdhdGV3YXkvcm9hL2ltcGwvU2VydmljZUdhdGV3YXlSb2FNb2R1bGVJbXBsLmphdmEgYi9zZXJ2aWNlZ2F0ZXdheS9zZXJ2aWNlL3NyYy9tYWluL2phdmEvb3JnL29wZW5vL2dzby9ndWkvc2VydmljZWdhdGV3YXkvcm9hL2ltcGwvU2VydmljZUdhdGV3YXlSb2FNb2R1bGVJbXBsLmphdmEKaW5kZXggZmYzMzc1MS4uM2M0N2M2NSAxMDA2NDQKLS0tIGEvc2VydmljZWdhdGV3YXkvc2VydmljZS9zcmMvbWFpbi9qYXZhL29yZy9vcGVuby9nc28vZ3VpL3NlcnZpY2VnYXRld2F5L3JvYS9pbXBsL1NlcnZpY2VHYXRld2F5Um9hTW9kdWxlSW1wbC5qYXZhCisrKyBiL3NlcnZpY2VnYXRld2F5L3NlcnZpY2Uvc3JjL21haW4vamF2YS9vcmcvb3Blbm8vZ3NvL2d1aS9zZXJ2aWNlZ2F0ZXdheS9yb2EvaW1wbC9TZXJ2aWNlR2F0ZXdheVJvYU1vZHVsZUltcGwuamF2YQpAQCAtMTI0LDQgKzEyNCwxNSBAQAogCiAgICAgICAgIHJldHVybiBSZXNwb25zZS5hY2NlcHRlZCgpLmVudGl0eShyZXN1bHQpLmJ1aWxkKCk7CiAgICAgfQorCisJcHVibGljIElTZXJ2aWNlR2F0ZXdheSBnZXRTZXJ2aWNlR2F0ZXdheSgpIAorCXsKKwkJcmV0dXJuIHNlcnZpY2VHYXRld2F5OworCX0KKworCXB1YmxpYyB2b2lkIHNldFNlcnZpY2VHYXRld2F5KElTZXJ2aWNlR2F0ZXdheSBzZXJ2aWNlR2F0ZXdheSkgCisJeworCQl0aGlzLnNlcnZpY2VHYXRld2F5ID0gc2VydmljZUdhdGV3YXk7CisJfQorICAgIAogfQpkaWZmIC0tZ2l0IGEvc2VydmljZWdhdGV3YXkvc2VydmljZS9zcmMvbWFpbi9yZXNvdXJjZXMvbG9nNGoucHJvcGVydGllcyBiL3NlcnZpY2VnYXRld2F5L3NlcnZpY2Uvc3JjL21haW4vcmVzb3VyY2VzL2xvZzRqLnByb3BlcnRpZXMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWUzYjk0NgotLS0gL2Rldi9udWxsCisrKyBiL3NlcnZpY2VnYXRld2F5L3NlcnZpY2Uvc3JjL21haW4vcmVzb3VyY2VzL2xvZzRqLnByb3BlcnRpZXMKQEAgLTAsMCArMSwyMSBAQAorIyBDb3B5cmlnaHQgMjAxNiBIdWF3ZWkgVGVjaG5vbG9naWVzIENvLiwgTHRkLgorCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisjICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9nNGoucm9vdExvZ2dlcj1JTkZPLHJvb3QKK2xvZzRqLmFwcGVuZGVyLnJvb3QuQXBwZW5kPXRydWUKK2xvZzRqLmFwcGVuZGVyLnJvb3QuRmlsZT0ke2NhdGFsaW5hLmJhc2V9L2xvZ3Mvc2VydmljZWdhdGV3YXkubG9nCitsb2c0ai5hcHBlbmRlci5yb290LmxheW91dC5Db252ZXJzaW9uUGF0dGVybj0lZCAlLTVwIFsldF1bJVh7bW9kdWxlSUR9XVslQyAlTF0gJW0lbgorbG9nNGouYXBwZW5kZXIucm9vdC5sYXlvdXQ9b3JnLmFwYWNoZS5sb2c0ai5QYXR0ZXJuTGF5b3V0Citsb2c0ai5hcHBlbmRlci5yb290Lk1heEJhY2t1cEluZGV4PTUwCitsb2c0ai5hcHBlbmRlci5yb290Lk1heEZpbGVTaXplPTIwTUIKK2xvZzRqLmFwcGVuZGVyLnJvb3Q9b3JnLmFwYWNoZS5sb2c0ai5Sb2xsaW5nRmlsZUFwcGVuZGVyClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2VydmljZWdhdGV3YXkvc2VydmljZS9zcmMvbWFpbi9yZXNvdXJjZXMvc3ByaW5nL3NlcnZpY2UueG1sIGIvc2VydmljZWdhdGV3YXkvc2VydmljZS9zcmMvbWFpbi9yZXNvdXJjZXMvc3ByaW5nL3NlcnZpY2UueG1sCmluZGV4IGMzMjhkODYuLjM5ZTVlYTcgMTAwNjQ0Ci0tLSBhL3NlcnZpY2VnYXRld2F5L3NlcnZpY2Uvc3JjL21haW4vcmVzb3VyY2VzL3NwcmluZy9zZXJ2aWNlLnhtbAorKysgYi9zZXJ2aWNlZ2F0ZXdheS9zZXJ2aWNlL3NyYy9tYWluL3Jlc291cmNlcy9zcHJpbmcvc2VydmljZS54bWwKQEAgLTI2LDcgKzI2LDYgQEAKICAgICBodHRwOi8vd3d3Lmh1YXdlaS5jb20vc2NoZW1hL29tcy9vbXMueHNkCiAgICAgaHR0cDovL2N4Zi5hcGFjaGUub3JnL2pheHJzIAogICAgIGh0dHA6Ly9jeGYuYXBhY2hlLm9yZy9zY2hlbWFzL2pheHJzLnhzZCI+Ci0KICAgICA8IS0tIHRoZXNlIGFyZSBpbmNsdWRlZCBpbiB0aGUgZGVwZW5kZW5jeSBqYXIgLS0+CiAgICAgPGltcG9ydCByZXNvdXJjZT0iY2xhc3NwYXRoOk1FVEEtSU5GL2N4Zi9jeGYueG1sIiAvPgogICAgIDxpbXBvcnQgcmVzb3VyY2U9ImNsYXNzcGF0aDpNRVRBLUlORi9jeGYvY3hmLXNlcnZsZXQueG1sIiAvPgpAQCAtMzUsOCArMzQsNyBAQAogICAgIDxqYXhyczpzZXJ2ZXIgaWQ9InNhbXBsZVNlcnZlciIgYWRkcmVzcz0iLyI+ICAgIAogICAgICAgICA8IS0tIHJlZ2lzdGVyaW5nIGJlYW5zIC0tPgogICAgICAgICA8amF4cnM6c2VydmljZUJlYW5zPgotICAgICAgICAgICAgPHJlZiBiZWFuPSJTZXJ2aWNlbWdyUm9hTW9kdWxlSW1wbCI+PC9yZWY+Ci0gICAgICAgICAgICA8cmVmIGJlYW49IlNlcnZpY2VQYWNrYWdlTW9kdWxlSW1wbCI+PC9yZWY+CisgICAgICAgICAgICA8cmVmIGJlYW49InNlcnZpY2VHYXRld2F5Um9hTW9kdWxlSW1wbCI+PC9yZWY+ICAgICAgICAgICAgCiAgICAgICAgIDwvamF4cnM6c2VydmljZUJlYW5zPgogICAgICAgICA8IS0tIHJlZ2lzdGVyaW5nIHByb3ZpZGVycyAtLT4KICAgICAgICAgPGpheHJzOnByb3ZpZGVycz4KQEAgLTY1LDkgKzYzLDEwIEBACiAgICAgPGJlYW4gaWQ9IkFjdGl2YXRvciIgY2xhc3M9Im9yZy5vcGVuby5nc28uZ3VpLnNlcnZpY2VnYXRld2F5LmFjdGl2YXRvci5BY3RpdmF0b3IiIGluaXQtbWV0aG9kPSJzdGFydCIgZGVzdHJveS1tZXRob2Q9InN0b3AiPgogICAgIDwvYmVhbj4KICAgICAKLSAgICA8YmVhbiBpZD0iU2VydmljR2F0ZXdheVJvYU1vZHVsZUltcGwiIGNsYXNzPSJvcmcub3Blbm8uZ3NvLmd1aS5zZXJ2aWNlZ2F0ZXdheS5yb2EuaW1wbC5TZXJ2aWNHYXRld2F5Um9hTW9kdWxlSW1wbCI+Ci0gICAgICAgIDxwcm9wZXJ0eSBuYW1lPSJTZXJ2aWNlR2F0ZXdheSIgcmVmPSJTZXJ2aWNlR2F0ZXdheSI+PC9wcm9wZXJ0eT4KKyAgICA8YmVhbiBpZD0ic2VydmljZUdhdGV3YXlSb2FNb2R1bGVJbXBsIiBjbGFzcz0ib3JnLm9wZW5vLmdzby5ndWkuc2VydmljZWdhdGV3YXkucm9hLmltcGwuU2VydmljZUdhdGV3YXlSb2FNb2R1bGVJbXBsIj4KKyAgICAgICAgPHByb3BlcnR5IG5hbWU9InNlcnZpY2VHYXRld2F5IiByZWY9InNlcnZpY2VHYXRld2F5Ij48L3Byb3BlcnR5PgogICAgIDwvYmVhbj4gICAgCi0gICAgCi0gICAgPC9iZWFuPgorCQorCTxiZWFuIGlkPSJzZXJ2aWNlR2F0ZXdheSIgY2xhc3M9Im9yZy5vcGVuby5nc28uZ3VpLnNlcnZpY2VnYXRld2F5LnNlcnZpY2UuaW1wbC5TZXJ2aWNlR2F0ZXdheUltcGwiPiAgICAgICAgCisgICAgPC9iZWFuPiAgCiA8L2JlYW5zPgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUK