dmFyIHRpbnltY2UgPSB7CgltYWpvclZlcnNpb24gOiAnMycsCgltaW5vclZlcnNpb24gOiAnMi41JywKCXJlbGVhc2VEYXRlIDogJzIwMDktMDYtMjknLAoKCV9pbml0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgQUpTLmxvZygidGlueW1jZS5faW5pdCIpOwoJCXZhciB0ID0gdGhpcywgZCA9IGRvY3VtZW50LCB3ID0gd2luZG93LCBuYSA9IG5hdmlnYXRvciwgdWEgPSBuYS51c2VyQWdlbnQsIGksIG5sLCBuLCBiYXNlLCBwLCB2OwoKCQkvLyBCcm93c2VyIGNoZWNrcwoJCXQuaXNPcGVyYSA9IHcub3BlcmEgJiYgb3BlcmEuYnVpbGROdW1iZXI7CgkJdC5pc1dlYktpdCA9IC9XZWJLaXQvLnRlc3QodWEpOwoJCXQuaXNJRSA9ICF0LmlzV2ViS2l0ICYmICF0LmlzT3BlcmEgJiYgKC9NU0lFL2dpKS50ZXN0KHVhKSAmJiAoL0V4cGxvcmVyL2dpKS50ZXN0KG5hLmFwcE5hbWUpOwoJCXQuaXNJRTYgPSB0LmlzSUUgJiYgL01TSUUgWzU2XS8udGVzdCh1YSk7CgkJdC5pc0dlY2tvID0gIXQuaXNXZWJLaXQgJiYgL0dlY2tvLy50ZXN0KHVhKTsKCQl0LmlzTWFjID0gdWEuaW5kZXhPZignTWFjJykgIT0gLTE7CgkJdC5pc0FpciA9IC9hZG9iZWFpci9pLnRlc3QodWEpOwoKCQkvLyBUaW55TUNFIC5ORVQgd2ViY29udHJvbCBtaWdodCBiZSBzZXR0aW5nIHRoZSB2YWx1ZXMgZm9yIFRpbnlNQ0UKCQlpZiAody50aW55TUNFUHJlSW5pdCkgewoJCQl0LnN1ZmZpeCA9IHRpbnlNQ0VQcmVJbml0LnN1ZmZpeDsKCQkJdC5iYXNlVVJMID0gdGlueU1DRVByZUluaXQuYmFzZTsKCQkJdC5xdWVyeSA9IHRpbnlNQ0VQcmVJbml0LnF1ZXJ5OwoJCQlyZXR1cm47CgkJfQoKCQkvLyBHZXQgc3VmZml4IGFuZCBiYXNlCgkJdC5zdWZmaXggPSAnJzsKCgkJLy8gSWYgYmFzZSBlbGVtZW50IGZvdW5kLCBhZGQgdGhhdCBpbmZyb250IG9mIGJhc2VVUkwKCQlubCA9IGQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2Jhc2UnKTsKICAgICAgICBmb3IgKGk9MDsgaTxubC5sZW5ndGg7IGkrKykgewoJCQlpZiAodiA9IG5sW2ldLmhyZWYpIHsKCQkJCS8vIEhvc3Qgb25seSB2YWx1ZSBsaWtlIGh0dHA6Ly9zaXRlLmNvbSBvciBodHRwOi8vc2l0ZS5jb206ODAwOAoJCQkJaWYgKC9eaHR0cHM/OlwvXC9bXlwvXSskLy50ZXN0KHYpKQoJCQkJCXYgKz0gJy8nOwoKCQkJCWJhc2UgPSB2ID8gdi5tYXRjaCgvLipcLy8pWzBdIDogJyc7IC8vIEdldCBvbmx5IGRpcmVjdG9yeQoJCQl9CgkJfQoKICAgICAgICAvLyBBVExBU1NJQU4gLSBnZXQgYmFzZSBmcm9tIGRvY3VtZW50LmxvY2F0aW9uIGFuZCBvdXIgd2VicmVzb3VyY2UgY2FsbGVkIHRpbnltY2UtcmVzb3VyY2VzCiAgICAgICAgaWYgKCFiYXNlKSB7CiAgICAgICAgICAgIHZhciBsID0gZG9jdW1lbnQubG9jYXRpb247CiAgICAgICAgICAgIGJhc2UgPSBsLnByb3RvY29sICsgIi8vIiArIGwuaG9zdG5hbWUgKyAobC5wb3J0ID8gIjoiICsgbC5wb3J0IDogIiIpOwogICAgICAgIH0KCgoJCWZ1bmN0aW9uIGdldEJhc2UobikgewoJCQlpZiAobi5zcmMgJiYgL3RpbnlfbWNlKHxfZ3ppcHxfanF1ZXJ5fF9wcm90b3R5cGUpKF9kZXZ8X3NyYyk/LmpzLy50ZXN0KG4uc3JjKSB8fCAvdGlueW1jZXBsdWdpbi8udGVzdChuLnNyYykpIHsKCQkJCWlmICgvXyhzcmN8ZGV2KVwuanMvZy50ZXN0KG4uc3JjKSkKCQkJCQl0LnN1ZmZpeCA9ICdfc3JjJzsKCgkJCQlpZiAoKHAgPSBuLnNyYy5pbmRleE9mKCc/JykpICE9IC0xKQoJCQkJCXQucXVlcnkgPSBuLnNyYy5zdWJzdHJpbmcocCArIDEpOwoKCQkJCXQuYmFzZVVSTCA9IG4uc3JjLnN1YnN0cmluZygwLCBuLnNyYy5pbmRleE9mKCcvZG93bmxvYWQvJykpOwoKCQkJCS8vIElmIHBhdGggdG8gc2NyaXB0IGlzIHJlbGF0aXZlIGFuZCBhIGJhc2UgaHJlZiB3YXMgZm91bmQgYWRkIHRoYXQgb25lIGluZnJvbnQKCQkJCWlmIChiYXNlICYmIHQuYmFzZVVSTC5pbmRleE9mKCc6Ly8nKSA9PSAtMSkKCQkJCQl0LmJhc2VVUkwgPSBiYXNlICsgdC5iYXNlVVJMOwoKICAgICAgICAgICAgICAgIC8vIEFUTEFTU0lBTiAtIHdlIG5lZWQgdG8gY2hhbmdlIHRoZSBiYXNlIHRvIHRoaXMgcGx1Z2luIHJlc291cmNlLCBub3QgdGhlIGVkaXQgcGFnZSB1cmwKICAgICAgICAgICAgICAgIHQuYmFzZVVSTCArPSAiL2Rvd25sb2FkL3Jlc291cmNlcy9jb20uYXRsYXNzaWFuLmNvbmZsdWVuY2UudGlueW1jZXBsdWdpbi90aW55bWNlc291cmNlIjsKICAgICAgICAgICAgICAgIHJldHVybiB0LmJhc2VVUkw7CgkJCX0KCgkJCXJldHVybiBudWxsOwoJCX07CgogICAgICAgIC8vIENoZWNrIGRvY3VtZW50CgkJbmwgPSBkLmdldEVsZW1lbnRzQnlUYWdOYW1lKCdzY3JpcHQnKTsKCQlmb3IgKGk9MDsgaTxubC5sZW5ndGg7IGkrKykgewoJCQlpZiAoZ2V0QmFzZShubFtpXSkpCgkJCQlyZXR1cm47CgkJfQoKCQkvLyBDaGVjayBoZWFkCgkJbiA9IGQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXTsKCQlpZiAobikgewoJCQlubCA9IG4uZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NjcmlwdCcpOwoJCQlmb3IgKGk9MDsgaTxubC5sZW5ndGg7IGkrKykgewoJCQkJaWYgKGdldEJhc2UobmxbaV0pKQoJCQkJCXJldHVybjsKCQkJfQoJCX0KCQkKCQlyZXR1cm47CiAgICB9LAoKCWlzIDogZnVuY3Rpb24obywgdCkgewoJCXZhciBuID0gdHlwZW9mKG8pOwoKCQlpZiAoIXQpCgkJCXJldHVybiBuICE9ICd1bmRlZmluZWQnOwoKCQlpZiAodCA9PSAnYXJyYXknICYmIChvLmhhc093blByb3BlcnR5ICYmIG8gaW5zdGFuY2VvZiBBcnJheSkpCgkJCXJldHVybiB0cnVlOwoKCQlyZXR1cm4gbiA9PSB0OwoJfSwKCgoJZWFjaCA6IGZ1bmN0aW9uKG8sIGNiLCBzKSB7CgkJdmFyIG4sIGw7CgoJCWlmICghbykKCQkJcmV0dXJuIDA7CgoJCXMgPSBzIHx8IG87CgoJCWlmICh0eXBlb2Yoby5sZW5ndGgpICE9ICd1bmRlZmluZWQnKSB7CgkJCS8vIEluZGV4ZWQgYXJyYXlzLCBuZWVkZWQgZm9yIFNhZmFyaQoJCQlmb3IgKG49MCwgbCA9IG8ubGVuZ3RoOyBuPGw7IG4rKykgewoJCQkJaWYgKGNiLmNhbGwocywgb1tuXSwgbiwgbykgPT09IGZhbHNlKQoJCQkJCXJldHVybiAwOwoJCQl9CgkJfSBlbHNlIHsKCQkJLy8gSGFzaHRhYmxlcwoJCQlmb3IgKG4gaW4gbykgewoJCQkJaWYgKG8uaGFzT3duUHJvcGVydHkobikpIHsKCQkJCQlpZiAoY2IuY2FsbChzLCBvW25dLCBuLCBvKSA9PT0gZmFsc2UpCgkJCQkJCXJldHVybiAwOwoJCQkJfQoJCQl9CgkJfQoKCQlyZXR1cm4gMTsKCX0sCgoJbWFwIDogZnVuY3Rpb24oYSwgZikgewoJCXZhciBvID0gW107CgoJCXRpbnltY2UuZWFjaChhLCBmdW5jdGlvbih2KSB7CgkJCW8ucHVzaChmKHYpKTsKCQl9KTsKCgkJcmV0dXJuIG87Cgl9LAoKCWdyZXAgOiBmdW5jdGlvbihhLCBmKSB7CgkJdmFyIG8gPSBbXTsKCgkJdGlueW1jZS5lYWNoKGEsIGZ1bmN0aW9uKHYpIHsKCQkJaWYgKCFmIHx8IGYodikpCgkJCQlvLnB1c2godik7CgkJfSk7CgoJCXJldHVybiBvOwoJfSwKCglpbkFycmF5IDogZnVuY3Rpb24oYSwgdikgewoJCXZhciBpLCBsOwoKCQlpZiAoYSkgewoJCQlmb3IgKGkgPSAwLCBsID0gYS5sZW5ndGg7IGkgPCBsOyBpKyspIHsKCQkJCWlmIChhW2ldID09PSB2KQoJCQkJCXJldHVybiBpOwoJCQl9CgkJfQoKCQlyZXR1cm4gLTE7Cgl9LAoKCWV4dGVuZCA6IGZ1bmN0aW9uKG8sIGUpIHsKCQl2YXIgaSwgYSA9IGFyZ3VtZW50czsKCgkJZm9yIChpPTE7IGk8YS5sZW5ndGg7IGkrKykgewoJCQllID0gYVtpXTsKCgkJCXRpbnltY2UuZWFjaChlLCBmdW5jdGlvbih2LCBuKSB7CgkJCQlpZiAodHlwZW9mKHYpICE9PSAndW5kZWZpbmVkJykKCQkJCQlvW25dID0gdjsKCQkJfSk7CgkJfQoKCQlyZXR1cm4gbzsKCX0sCgoKCXRyaW0gOiBmdW5jdGlvbihzKSB7CgkJcmV0dXJuIChzID8gJycgKyBzIDogJycpLnJlcGxhY2UoL15ccyp8XHMqJC9nLCAnJyk7Cgl9LAoKCWNyZWF0ZSA6IGZ1bmN0aW9uKHMsIHApIHsKCQl2YXIgdCA9IHRoaXMsIHNwLCBucywgY24sIHNjbiwgYywgZGUgPSAwOwoKCQkvLyBQYXJzZSA6IDxwcmVmaXg+IDxjbGFzcz46PHN1cGVyIGNsYXNzPgoJCXMgPSAvXigoc3RhdGljKSApPyhbXHcuXSspKDooW1x3Ll0rKSk/Ly5leGVjKHMpOwoJCWNuID0gc1szXS5tYXRjaCgvKF58XC4pKFx3KykkL2kpWzJdOyAvLyBDbGFzcyBuYW1lCgoJCS8vIENyZWF0ZSBuYW1lc3BhY2UgZm9yIG5ldyBjbGFzcwoJCW5zID0gdC5jcmVhdGVOUyhzWzNdLnJlcGxhY2UoL1wuXHcrJC8sICcnKSk7CgoJCS8vIENsYXNzIGFscmVhZHkgZXhpc3RzCgkJaWYgKG5zW2NuXSkKCQkJcmV0dXJuOwoKCQkvLyBNYWtlIHB1cmUgc3RhdGljIGNsYXNzCgkJaWYgKHNbMl0gPT0gJ3N0YXRpYycpIHsKCQkJbnNbY25dID0gcDsKCgkJCWlmICh0aGlzLm9uQ3JlYXRlKQoJCQkJdGhpcy5vbkNyZWF0ZShzWzJdLCBzWzNdLCBuc1tjbl0pOwoKCQkJcmV0dXJuOwoJCX0KCgkJLy8gQ3JlYXRlIGRlZmF1bHQgY29uc3RydWN0b3IKCQlpZiAoIXBbY25dKSB7CgkJCXBbY25dID0gZnVuY3Rpb24oKSB7fTsKCQkJZGUgPSAxOwoJCX0KCgkJLy8gQWRkIGNvbnN0cnVjdG9yIGFuZCBtZXRob2RzCgkJbnNbY25dID0gcFtjbl07CgkJdC5leHRlbmQobnNbY25dLnByb3RvdHlwZSwgcCk7CgoJCS8vIEV4dGVuZAoJCWlmIChzWzVdKSB7CgkJCXNwID0gdC5yZXNvbHZlKHNbNV0pLnByb3RvdHlwZTsKCQkJc2NuID0gc1s1XS5tYXRjaCgvXC4oXHcrKSQvaSlbMV07IC8vIENsYXNzIG5hbWUKCgkJCS8vIEV4dGVuZCBjb25zdHJ1Y3RvcgoJCQljID0gbnNbY25dOwoJCQlpZiAoZGUpIHsKCQkJCS8vIEFkZCBwYXNzdGhyb3VnaCBjb25zdHJ1Y3RvcgoJCQkJbnNbY25dID0gZnVuY3Rpb24oKSB7CgkJCQkJcmV0dXJuIHNwW3Njbl0uYXBwbHkodGhpcywgYXJndW1lbnRzKTsKCQkJCX07CgkJCX0gZWxzZSB7CgkJCQkvLyBBZGQgaW5oZXJpdCBjb25zdHJ1Y3RvcgoJCQkJbnNbY25dID0gZnVuY3Rpb24oKSB7CgkJCQkJdGhpcy5wYXJlbnQgPSBzcFtzY25dOwoJCQkJCXJldHVybiBjLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CgkJCQl9OwoJCQl9CgkJCW5zW2NuXS5wcm90b3R5cGVbY25dID0gbnNbY25dOwoKCQkJLy8gQWRkIHN1cGVyIG1ldGhvZHMKCQkJdC5lYWNoKHNwLCBmdW5jdGlvbihmLCBuKSB7CgkJCQluc1tjbl0ucHJvdG90eXBlW25dID0gc3Bbbl07CgkJCX0pOwoKCQkJLy8gQWRkIG92ZXJyaWRkZW4gbWV0aG9kcwoJCQl0LmVhY2gocCwgZnVuY3Rpb24oZiwgbikgewoJCQkJLy8gRXh0ZW5kIG1ldGhvZHMgaWYgbmVlZGVkCgkJCQlpZiAoc3Bbbl0pIHsKCQkJCQluc1tjbl0ucHJvdG90eXBlW25dID0gZnVuY3Rpb24oKSB7CgkJCQkJCXRoaXMucGFyZW50ID0gc3Bbbl07CgkJCQkJCXJldHVybiBmLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CgkJCQkJfTsKCQkJCX0gZWxzZSB7CgkJCQkJaWYgKG4gIT0gY24pCgkJCQkJCW5zW2NuXS5wcm90b3R5cGVbbl0gPSBmOwoJCQkJfQoJCQl9KTsKCQl9CgoJCS8vIEFkZCBzdGF0aWMgbWV0aG9kcwoJCXQuZWFjaChwWydzdGF0aWMnXSwgZnVuY3Rpb24oZiwgbikgewoJCQluc1tjbl1bbl0gPSBmOwoJCX0pOwoKCQlpZiAodGhpcy5vbkNyZWF0ZSkKCQkJdGhpcy5vbkNyZWF0ZShzWzJdLCBzWzNdLCBuc1tjbl0ucHJvdG90eXBlKTsKCX0sCgoJd2FsayA6IGZ1bmN0aW9uKG8sIGYsIG4sIHMpIHsKCQlzID0gcyB8fCB0aGlzOwoKCQlpZiAobykgewoJCQlpZiAobikKCQkJCW8gPSBvW25dOwoKCQkJdGlueW1jZS5lYWNoKG8sIGZ1bmN0aW9uKG8sIGkpIHsKCQkJCWlmIChmLmNhbGwocywgbywgaSwgbikgPT09IGZhbHNlKQoJCQkJCXJldHVybiBmYWxzZTsKCgkJCQl0aW55bWNlLndhbGsobywgZiwgbiwgcyk7CgkJCX0pOwoJCX0KCX0sCgoJY3JlYXRlTlMgOiBmdW5jdGlvbihuLCBvKSB7CgkJdmFyIGksIHY7CgoJCW8gPSBvIHx8IHdpbmRvdzsKCgkJbiA9IG4uc3BsaXQoJy4nKTsKCQlmb3IgKGk9MDsgaTxuLmxlbmd0aDsgaSsrKSB7CgkJCXYgPSBuW2ldOwoKCQkJaWYgKCFvW3ZdKQoJCQkJb1t2XSA9IHt9OwoKCQkJbyA9IG9bdl07CgkJfQoKCQlyZXR1cm4gbzsKCX0sCgoJcmVzb2x2ZSA6IGZ1bmN0aW9uKG4sIG8pIHsKCQl2YXIgaSwgbDsKCgkJbyA9IG8gfHwgd2luZG93OwoKCQluID0gbi5zcGxpdCgnLicpOwoJCWZvciAoaT0wLCBsID0gbi5sZW5ndGg7IGk8bDsgaSsrKSB7CgkJCW8gPSBvW25baV1dOwoKCQkJaWYgKCFvKQoJCQkJYnJlYWs7CgkJfQoKCQlyZXR1cm4gbzsKCX0sCgoJYWRkVW5sb2FkIDogZnVuY3Rpb24oZiwgcykgewoJCXZhciB0ID0gdGhpcywgdyA9IHdpbmRvdzsKCgkJZiA9IHtmdW5jIDogZiwgc2NvcGUgOiBzIHx8IHRoaXN9OwoKCQlpZiAoIXQudW5sb2FkcykgewoJCQlmdW5jdGlvbiB1bmxvYWQoKSB7CgkJCQl2YXIgbGkgPSB0LnVubG9hZHMsIG8sIG47CgoJCQkJaWYgKGxpKSB7CgkJCQkJLy8gQ2FsbCB1bmxvYWQgaGFuZGxlcnMKCQkJCQlmb3IgKG4gaW4gbGkpIHsKCQkJCQkJbyA9IGxpW25dOwoKCQkJCQkJaWYgKG8gJiYgby5mdW5jKQoJCQkJCQkJby5mdW5jLmNhbGwoby5zY29wZSwgMSk7IC8vIFNlbmQgaW4gb25lIGFyZyB0byBkaXN0aW5jdCB1bmxvYWQgYW5kIHVzZXIgZGVzdHJveQoJCQkJCX0KCgkJCQkJLy8gRGV0YWNoIHVubG9hZCBmdW5jdGlvbgoJCQkJCWlmICh3LmRldGFjaEV2ZW50KSB7CgkJCQkJCXcuZGV0YWNoRXZlbnQoJ29uYmVmb3JldW5sb2FkJywgZmFrZVVubG9hZCk7CgkJCQkJCXcuZGV0YWNoRXZlbnQoJ29udW5sb2FkJywgdW5sb2FkKTsKCQkJCQl9IGVsc2UgaWYgKHcucmVtb3ZlRXZlbnRMaXN0ZW5lcikKCQkJCQkJdy5yZW1vdmVFdmVudExpc3RlbmVyKCd1bmxvYWQnLCB1bmxvYWQsIGZhbHNlKTsKCgkJCQkJLy8gRGVzdHJveSByZWZlcmVuY2VzCgkJCQkJdC51bmxvYWRzID0gbyA9IGxpID0gdyA9IHVubG9hZCA9IDA7CgoJCQkJCS8vIFJ1biBnYXJiYXJnZSBjb2xsZWN0b3Igb24gSUUKCQkJCQlpZiAod2luZG93LkNvbGxlY3RHYXJiYWdlKQoJCQkJCQl3aW5kb3cuQ29sbGVjdEdhcmJhZ2UoKTsKCQkJCX0KCQkJfTsKCgkJCWZ1bmN0aW9uIGZha2VVbmxvYWQoKSB7CgkJCQl2YXIgZCA9IGRvY3VtZW50OwoKCQkJCS8vIElzIHRoZXJlIHRoaW5ncyBzdGlsbCBsb2FkaW5nLCB0aGVuIGRvIHNvbWUgbWFnaWMKCQkJCWlmIChkLnJlYWR5U3RhdGUgPT0gJ2ludGVyYWN0aXZlJykgewoJCQkJCWZ1bmN0aW9uIHN0b3AoKSB7CgkJCQkJCS8vIFByZXZlbnQgbWVtb3J5IGxlYWsKCQkJCQkJZC5kZXRhY2hFdmVudCgnb25zdG9wJywgc3RvcCk7CgoJCQkJCQkvLyBDYWxsIHVubG9hZCBoYW5kbGVyCgkJCQkJCWlmICh1bmxvYWQpCgkJCQkJCQl1bmxvYWQoKTsKCgkJCQkJCWQgPSAwOwoJCQkJCX07CgoJCQkJCS8vIEZpcmUgdW5sb2FkIHdoZW4gdGhlIGN1cnJlbnRseSBsb2FkaW5nIHBhZ2UgaXMgc3RvcHBlZAoJCQkJCWlmIChkKQoJCQkJCQlkLmF0dGFjaEV2ZW50KCdvbnN0b3AnLCBzdG9wKTsKCgkJCQkJLy8gUmVtb3ZlIG9uc3RvcCBsaXN0ZW5lciBhZnRlciBhIHdoaWxlIHRvIHByZXZlbnQgdGhlIHVubG9hZCBmdW5jdGlvbgoJCQkJCS8vIHRvIGV4ZWN1dGUgaWYgdGhlIHVzZXIgcHJlc3NlcyBjYW5jZWwgaW4gYW4gb25iZWZvcmV1bmxvYWQKCQkJCQkvLyBjb25maXJtIGRpYWxvZyBhbmQgdGhlbiBwcmVzc2VzIHRoZSBicm93c2VyIHN0b3AgYnV0dG9uCgkJCQkJd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7CgkJCQkJCWlmIChkKQoJCQkJCQkJZC5kZXRhY2hFdmVudCgnb25zdG9wJywgc3RvcCk7CgkJCQkJfSwgMCk7CgkJCQl9CgkJCX07CgoJCQkvLyBBdHRhY2ggdW5sb2FkIGhhbmRsZXIKCQkJaWYgKHcuYXR0YWNoRXZlbnQpIHsKCQkJCXcuYXR0YWNoRXZlbnQoJ29udW5sb2FkJywgdW5sb2FkKTsKCQkJCXcuYXR0YWNoRXZlbnQoJ29uYmVmb3JldW5sb2FkJywgZmFrZVVubG9hZCk7CgkJCX0gZWxzZSBpZiAody5hZGRFdmVudExpc3RlbmVyKQoJCQkJdy5hZGRFdmVudExpc3RlbmVyKCd1bmxvYWQnLCB1bmxvYWQsIGZhbHNlKTsKCgkJCS8vIFNldHVwIGluaXRpYWwgdW5sb2FkIGhhbmRsZXIgYXJyYXkKCQkJdC51bmxvYWRzID0gW2ZdOwoJCX0gZWxzZQoJCQl0LnVubG9hZHMucHVzaChmKTsKCgkJcmV0dXJuIGY7Cgl9LAoKCXJlbW92ZVVubG9hZCA6IGZ1bmN0aW9uKGYpIHsKCQl2YXIgdSA9IHRoaXMudW5sb2FkcywgciA9IG51bGw7CgoJCXRpbnltY2UuZWFjaCh1LCBmdW5jdGlvbihvLCBpKSB7CgkJCWlmIChvICYmIG8uZnVuYyA9PSBmKSB7CgkJCQl1LnNwbGljZShpLCAxKTsKCQkJCXIgPSBmOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJfSk7CgoJCXJldHVybiByOwoJfSwKCglleHBsb2RlIDogZnVuY3Rpb24ocywgZCkgewoJCXJldHVybiBzID8gdGlueW1jZS5tYXAocy5zcGxpdChkIHx8ICcsJyksIHRpbnltY2UudHJpbSkgOiBzOwoJfSwKCglfYWRkVmVyIDogZnVuY3Rpb24odSkgewoJCXZhciB2OwoKCQlpZiAoIXRoaXMucXVlcnkpCgkJCXJldHVybiB1OwoKCQl2ID0gKHUuaW5kZXhPZignPycpID09IC0xID8gJz8nIDogJyYnKSArIHRoaXMucXVlcnk7CgoJCWlmICh1LmluZGV4T2YoJyMnKSA9PSAtMSkKCQkJcmV0dXJuIHUgKyB2OwoKCQlyZXR1cm4gdS5yZXBsYWNlKCcjJywgdiArICcjJyk7Cgl9CgoJfTsKCi8vIFJlcXVpcmVkIGZvciBHWmlwIEFKQVggbG9hZGluZwp3aW5kb3cudGlueW1jZSA9IHRpbnltY2U7CgovLyBJbml0aWFsaXplIHRoZSBBUEkKdGlueW1jZS5faW5pdCgpOwp0aW55bWNlLmNyZWF0ZSgndGlueW1jZS51dGlsLkRpc3BhdGNoZXInLCB7CglzY29wZSA6IG51bGwsCglsaXN0ZW5lcnMgOiBudWxsLAoKCURpc3BhdGNoZXIgOiBmdW5jdGlvbihzKSB7CgkJdGhpcy5zY29wZSA9IHMgfHwgdGhpczsKCQl0aGlzLmxpc3RlbmVycyA9IFtdOwoJfSwKCglhZGQgOiBmdW5jdGlvbihjYiwgcykgewoJCXRoaXMubGlzdGVuZXJzLnB1c2goe2NiIDogY2IsIHNjb3BlIDogcyB8fCB0aGlzLnNjb3BlfSk7CgoJCXJldHVybiBjYjsKCX0sCgoJYWRkVG9Ub3AgOiBmdW5jdGlvbihjYiwgcykgewoJCXRoaXMubGlzdGVuZXJzLnVuc2hpZnQoe2NiIDogY2IsIHNjb3BlIDogcyB8fCB0aGlzLnNjb3BlfSk7CgoJCXJldHVybiBjYjsKCX0sCgoJcmVtb3ZlIDogZnVuY3Rpb24oY2IpIHsKCQl2YXIgbCA9IHRoaXMubGlzdGVuZXJzLCBvID0gbnVsbDsKCgkJdGlueW1jZS5lYWNoKGwsIGZ1bmN0aW9uKGMsIGkpIHsKCQkJaWYgKGNiID09IGMuY2IpIHsKCQkJCW8gPSBjYjsKCQkJCWwuc3BsaWNlKGksIDEpOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJfSk7CgoJCXJldHVybiBvOwoJfSwKCglkaXNwYXRjaCA6IGZ1bmN0aW9uKCkgewoJCXZhciBzLCBhID0gYXJndW1lbnRzLCBpLCBsaSA9IHRoaXMubGlzdGVuZXJzLCBjOwoKCQkvLyBOZWVkcyB0byBiZSBhIHJlYWwgbG9vcCBzaW5jZSB0aGUgbGlzdGVuZXIgY291bnQgbWlnaHQgY2hhbmdlIHdoaWxlIGxvb3BpbmcKCQkvLyBBbmQgdGhpcyBpcyBhbHNvIG1vcmUgZWZmaWNpZW50CgkJZm9yIChpID0gMDsgaTxsaS5sZW5ndGg7IGkrKykgewoJCQljID0gbGlbaV07CgkJCXMgPSBjLmNiLmFwcGx5KGMuc2NvcGUsIGEpOwoKCQkJaWYgKHMgPT09IGZhbHNlKQoJCQkJYnJlYWs7CgkJfQoKCQlyZXR1cm4gczsKCX0KCgl9KTsKKGZ1bmN0aW9uKCkgewoJdmFyIGVhY2ggPSB0aW55bWNlLmVhY2g7CgoJdGlueW1jZS5jcmVhdGUoJ2h0dHA6Ly8xMC4yMC4xNjAuMTk4L3dpa2kvcy9lbi8yMTY2LzM0LzMuNS45L18vZG93bmxvYWQvYmF0Y2gvY29tLmF0bGFzc2lhbi5jb25mbHVlbmNlLnRpbnltY2VwbHVnaW46ZWRpdG9yLXJlc291cmNlcy90aW55bWNlLnV0aWwuVVJJJywgewoJCVVSSSA6IGZ1bmN0aW9uKHUsIHMpIHsKCQkJdmFyIHQgPSB0aGlzLCBvLCBhLCBiOwoKCQkJLy8gVHJpbSB3aGl0ZXNwYWNlCgkJCXUgPSB0aW55bWNlLnRyaW0odSk7CgoJCQkvLyBEZWZhdWx0IHNldHRpbmdzCgkJCXMgPSB0LnNldHRpbmdzID0gcyB8fCB7fTsKCgkJCS8vIFN0cmFuZ2UgYXBwIHByb3RvY29sIG9yIGxvY2FsIGFuY2hvcgoJCQlpZiAoL14obWFpbHRvfHRlbHxuZXdzfGphdmFzY3JpcHR8YWJvdXQpOi9pLnRlc3QodSkgfHwgL15ccyojLy50ZXN0KHUpKSB7CgkJCQl0LnNvdXJjZSA9IHU7CgkJCQlyZXR1cm47CgkJCX0KCgkJCS8vIEFic29sdXRlIHBhdGggd2l0aCBubyBob3N0LCBmYWtlIGhvc3QgYW5kIHByb3RvY29sCgkJCWlmICh1LmluZGV4T2YoJy8nKSA9PT0gMCAmJiB1LmluZGV4T2YoJy8vJykgIT09IDApIHsKICAgICAgICAgICAgICAgIEFKUy5sb2coIlVSSS5VUkkgQWJzb2x1dGUgcGF0aCB3aXRoIG5vIGhvc3QgdSA6ICIgKyB1KTsKCQkJCXUgPSAocy5iYXNlX3VyaSA/IHMuYmFzZV91cmkucHJvdG9jb2wgfHwgJ2h0dHAnIDogJ2h0dHAnKSArICc6Ly9tY2VfaG9zdCcgKyB1OwoJCQl9CgoJCQkvLyBSZWxhdGl2ZSBwYXRoIGh0dHA6Ly8gb3IgcHJvdG9jb2wgcmVsYXRpdmUgLy9wYXRoCgkJCWlmICghL15cdyo6P1wvXC8vLnRlc3QodSkpIHsKCQkJCUFKUy5sb2coIlVSSS5VUkkgcmVsYXRpdmUgcGF0aCB3aXRoIG5vIGhvc3QgdSA6ICIgKyB1KTsKCQkJCXUgPSAocy5iYXNlX3VyaS5wcm90b2NvbCB8fCAnaHR0cCcpICsgJzovL21jZV9ob3N0JyArIHQudG9BYnNQYXRoKHMuYmFzZV91cmkucGF0aCwgdSk7CgkJCX0KCgkJCS8vIFBhcnNlIFVSTCAoQ3JlZGl0cyBnb2VzIHRvIFN0ZWF2ZSwgaHR0cDovL2Jsb2cuc3RldmVubGV2aXRoYW4uY29tL2FyY2hpdmVzL3BhcnNldXJpKQoJCQl1ID0gdS5yZXBsYWNlKC9AQC9nLCAnKG1jZV9hdCknKTsgLy8gWm9wZSAzIHdvcmthcm91bmQsIHRoZXkgdXNlIEBAc29tZXRoaW5nCgkJCXUgPSAvXig/Oig/IVteOkBdKzpbXjpAXC9dKkApKFteOlwvPyMuXSspOik/KD86XC9cLyk/KCg/OigoW146QFwvXSopOj8oW146QFwvXSopKT9AKT8oW146XC8/I10qKSg/OjooXGQqKSk/KSgoKFwvKD86W14/I10oPyFbXj8jXC9dKlwuW14/I1wvLl0rKD86Wz8jXXwkKSkpKlwvPyk/KFtePyNcL10qKSkoPzpcPyhbXiNdKikpPyg/OiMoLiopKT8pLy5leGVjKHUpOwoJCQllYWNoKFsic291cmNlIiwicHJvdG9jb2wiLCJhdXRob3JpdHkiLCJ1c2VySW5mbyIsInVzZXIiLCJwYXNzd29yZCIsImhvc3QiLCJwb3J0IiwicmVsYXRpdmUiLCJwYXRoIiwiZGlyZWN0b3J5IiwiZmlsZSIsInF1ZXJ5IiwiYW5jaG9yIl0sIGZ1bmN0aW9uKHYsIGkpIHsKCQkJCXZhciBzID0gdVtpXTsKCgkJCQkvLyBab3BlIDMgd29ya2Fyb3VuZCwgdGhleSB1c2UgQEBzb21ldGhpbmcKCQkJCWlmIChzKQoJCQkJCXMgPSBzLnJlcGxhY2UoL1wobWNlX2F0XCkvZywgJ0BAJyk7CgoJCQkJdFt2XSA9IHM7CgkJCX0pOwoKCQkJaWYgKGIgPSBzLmJhc2VfdXJpKSB7CgkJCQlpZiAoIXQucHJvdG9jb2wpCgkJCQkJdC5wcm90b2NvbCA9IGIucHJvdG9jb2w7CgoJCQkJaWYgKCF0LnVzZXJJbmZvKQoJCQkJCXQudXNlckluZm8gPSBiLnVzZXJJbmZvOwoKCQkJCWlmICghdC5wb3J0ICYmIHQuaG9zdCA9PSAnbWNlX2hvc3QnKQoJCQkJCXQucG9ydCA9IGIucG9ydDsKCgkJCQlpZiAoIXQuaG9zdCB8fCB0Lmhvc3QgPT0gJ21jZV9ob3N0JykKCQkJCQl0Lmhvc3QgPSBiLmhvc3Q7CgoJCQkJdC5zb3VyY2UgPSAnJzsKCQkJfQoKCQkJLy90LnBhdGggPSB0LnBhdGggfHwgJy8nOwoJCX0sCgoJCXNldFBhdGggOiBmdW5jdGlvbihwKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXAgPSAvXiguKj8pXC8/KFx3Kyk/JC8uZXhlYyhwKTsKCgkJCS8vIFVwZGF0ZSBwYXRoIHBhcnRzCgkJCXQucGF0aCA9IHBbMF07CgkJCXQuZGlyZWN0b3J5ID0gcFsxXTsKCQkJdC5maWxlID0gcFsyXTsKCgkJCS8vIFJlYnVpbGQgc291cmNlCgkJCXQuc291cmNlID0gJyc7CgkJCXQuZ2V0VVJJKCk7CgkJfSwKCgkJdG9SZWxhdGl2ZSA6IGZ1bmN0aW9uKHUpIHsKCQkJdmFyIHQgPSB0aGlzLCBvOwoKCQkJaWYgKHUgPT09ICIuLyIpCgkJCQlyZXR1cm4gdTsKCgkJCXUgPSBuZXcgdGlueW1jZS51dGlsLlVSSSh1LCB7YmFzZV91cmkgOiB0fSk7CgoJCQkvLyBOb3Qgb24gc2FtZSBkb21haW4vcG9ydCBvciBwcm90b2NvbAoJCQlpZiAoKHUuaG9zdCAhPSAnbWNlX2hvc3QnICYmIHQuaG9zdCAhPSB1Lmhvc3QgJiYgdS5ob3N0KSB8fCB0LnBvcnQgIT0gdS5wb3J0IHx8IHQucHJvdG9jb2wgIT0gdS5wcm90b2NvbCkKCQkJCXJldHVybiB1LmdldFVSSSgpOwoKCQkJbyA9IHQudG9SZWxQYXRoKHQucGF0aCwgdS5wYXRoKTsKCgkJCS8vIEFkZCBxdWVyeQoJCQlpZiAodS5xdWVyeSkKCQkJCW8gKz0gJz8nICsgdS5xdWVyeTsKCgkJCS8vIEFkZCBhbmNob3IKCQkJaWYgKHUuYW5jaG9yKQoJCQkJbyArPSAnIycgKyB1LmFuY2hvcjsKCgkJCXJldHVybiBvOwoJCX0sCgoJCXRvQWJzb2x1dGUgOiBmdW5jdGlvbih1LCBuaCkgewoJCQl2YXIgdSA9IG5ldyB0aW55bWNlLnV0aWwuVVJJKHUsIHtiYXNlX3VyaSA6IHRoaXN9KTsKCgkJCXJldHVybiB1LmdldFVSSSh0aGlzLmhvc3QgPT0gdS5ob3N0ID8gbmggOiAwKTsKCQl9LAoKCQl0b1JlbFBhdGggOiBmdW5jdGlvbihiYXNlLCBwYXRoKSB7CgkJCXZhciBpdGVtcywgYnAgPSAwLCBvdXQgPSAnJywgaSwgbDsKCgkJCS8vIFNwbGl0IHRoZSBwYXRocwoJCQliYXNlID0gYmFzZS5zdWJzdHJpbmcoMCwgYmFzZS5sYXN0SW5kZXhPZignLycpKTsKCQkJYmFzZSA9IGJhc2Uuc3BsaXQoJy8nKTsKCQkJaXRlbXMgPSBwYXRoLnNwbGl0KCcvJyk7CgoJCQlpZiAoYmFzZS5sZW5ndGggPj0gaXRlbXMubGVuZ3RoKSB7CgkJCQlmb3IgKGkgPSAwLCBsID0gYmFzZS5sZW5ndGg7IGkgPCBsOyBpKyspIHsKCQkJCQlpZiAoaSA+PSBpdGVtcy5sZW5ndGggfHwgYmFzZVtpXSAhPSBpdGVtc1tpXSkgewoJCQkJCQlicCA9IGkgKyAxOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCX0KCgkJCWlmIChiYXNlLmxlbmd0aCA8IGl0ZW1zLmxlbmd0aCkgewoJCQkJZm9yIChpID0gMCwgbCA9IGl0ZW1zLmxlbmd0aDsgaSA8IGw7IGkrKykgewoJCQkJCWlmIChpID49IGJhc2UubGVuZ3RoIHx8IGJhc2VbaV0gIT0gaXRlbXNbaV0pIHsKCQkJCQkJYnAgPSBpICsgMTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQl9CgoJCQlpZiAoYnAgPT0gMSkKCQkJCXJldHVybiBwYXRoOwoKCQkJZm9yIChpID0gMCwgbCA9IGJhc2UubGVuZ3RoIC0gKGJwIC0gMSk7IGkgPCBsOyBpKyspCgkJCQlvdXQgKz0gIi4uLyI7CgoJCQlmb3IgKGkgPSBicCAtIDEsIGwgPSBpdGVtcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKCQkJCWlmIChpICE9IGJwIC0gMSkKCQkJCQlvdXQgKz0gIi8iICsgaXRlbXNbaV07CgkJCQllbHNlCgkJCQkJb3V0ICs9IGl0ZW1zW2ldOwoJCQl9CgoJCQlyZXR1cm4gb3V0OwoJCX0sCgoJCXRvQWJzUGF0aCA6IGZ1bmN0aW9uKGJhc2UsIHBhdGgpIHsKCQkJdmFyIGksIG5iID0gMCwgbyA9IFtdLCB0cjsKCgkJCS8vIFNwbGl0IHBhdGhzCgkJCXRyID0gL1wvJC8udGVzdChwYXRoKSA/ICcvJyA6ICcnOwoJCQliYXNlID0gYmFzZS5zcGxpdCgnLycpOwoJCQlwYXRoID0gcGF0aC5zcGxpdCgnLycpOwoKCQkJLy8gUmVtb3ZlIGVtcHR5IGNodW5rcwoJCQllYWNoKGJhc2UsIGZ1bmN0aW9uKGspIHsKCQkJCWlmIChrKQoJCQkJCW8ucHVzaChrKTsKCQkJfSk7CgoJCQliYXNlID0gbzsKCgkJCS8vIE1lcmdlIHJlbFVSTFBhcnRzIGNodW5rcwoJCQlmb3IgKGkgPSBwYXRoLmxlbmd0aCAtIDEsIG8gPSBbXTsgaSA+PSAwOyBpLS0pIHsKCQkJCS8vIElnbm9yZSBlbXB0eSBvciAuCgkJCQlpZiAocGF0aFtpXS5sZW5ndGggPT0gMCB8fCBwYXRoW2ldID09ICIuIikKCQkJCQljb250aW51ZTsKCgkJCQkvLyBJcyBwYXJlbnQKCQkJCWlmIChwYXRoW2ldID09ICcuLicpIHsKCQkJCQluYisrOwoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCS8vIE1vdmUgdXAKCQkJCWlmIChuYiA+IDApIHsKCQkJCQluYi0tOwoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCW8ucHVzaChwYXRoW2ldKTsKCQkJfQoKCQkJaSA9IGJhc2UubGVuZ3RoIC0gbmI7CgoJCQkvLyBJZiAvYS9iL2Mgb3IgLwoJCQlpZiAoaSA8PSAwKQoJCQkJcmV0dXJuICcvJyArIG8ucmV2ZXJzZSgpLmpvaW4oJy8nKSArIHRyOwoKCQkJcmV0dXJuICcvJyArIGJhc2Uuc2xpY2UoMCwgaSkuam9pbignLycpICsgJy8nICsgby5yZXZlcnNlKCkuam9pbignLycpICsgdHI7CgkJfSwKCgkJZ2V0VVJJIDogZnVuY3Rpb24obmgpIHsKCQkJdmFyIHMsIHQgPSB0aGlzOwoKCQkJLy8gUmVidWlsZCBzb3VyY2UKCQkJaWYgKCF0LnNvdXJjZSB8fCBuaCkgewoJCQkJcyA9ICcnOwoKCQkJCWlmICghbmgpIHsKCQkJCQlpZiAodC5wcm90b2NvbCkKCQkJCQkJcyArPSB0LnByb3RvY29sICsgJzovLyc7CgoJCQkJCWlmICh0LnVzZXJJbmZvKQoJCQkJCQlzICs9IHQudXNlckluZm8gKyAnQCc7CgoJCQkJCWlmICh0Lmhvc3QpCgkJCQkJCXMgKz0gdC5ob3N0OwoKCQkJCQlpZiAodC5wb3J0KQoJCQkJCQlzICs9ICc6JyArIHQucG9ydDsKCQkJCX0KCgkJCQlpZiAodC5wYXRoKQoJCQkJCXMgKz0gdC5wYXRoOwoKCQkJCWlmICh0LnF1ZXJ5KQoJCQkJCXMgKz0gJz8nICsgdC5xdWVyeTsKCgkJCQlpZiAodC5hbmNob3IpCgkJCQkJcyArPSAnIycgKyB0LmFuY2hvcjsKCgkJCQl0LnNvdXJjZSA9IHM7CgkJCX0KCgkJCXJldHVybiB0LnNvdXJjZTsKCQl9CgoJCX0pOwp9KSgpOwooZnVuY3Rpb24oKSB7Cgl2YXIgZWFjaCA9IHRpbnltY2UuZWFjaDsKCgl0aW55bWNlLmNyZWF0ZSgnc3RhdGljIHRpbnltY2UudXRpbC5Db29raWUnLCB7CgkJZ2V0SGFzaCA6IGZ1bmN0aW9uKG4pIHsKCQkJdmFyIHYgPSB0aGlzLmdldChuKSwgaDsKCgkJCWlmICh2KSB7CgkJCQllYWNoKHYuc3BsaXQoJyYnKSwgZnVuY3Rpb24odikgewoJCQkJCXYgPSB2LnNwbGl0KCc9Jyk7CgkJCQkJaCA9IGggfHwge307CgkJCQkJaFt1bmVzY2FwZSh2WzBdKV0gPSB1bmVzY2FwZSh2WzFdKTsKCQkJCX0pOwoJCQl9CgoJCQlyZXR1cm4gaDsKCQl9LAoKCQlzZXRIYXNoIDogZnVuY3Rpb24obiwgdiwgZSwgcCwgZCwgcykgewoJCQl2YXIgbyA9ICcnOwoKCQkJZWFjaCh2LCBmdW5jdGlvbih2LCBrKSB7CgkJCQlvICs9ICghbyA/ICcnIDogJyYnKSArIGVzY2FwZShrKSArICc9JyArIGVzY2FwZSh2KTsKCQkJfSk7CgoJCQl0aGlzLnNldChuLCBvLCBlLCBwLCBkLCBzKTsKCQl9LAoKCQlnZXQgOiBmdW5jdGlvbihuKSB7CgkJCXZhciBjID0gZG9jdW1lbnQuY29va2llLCBlLCBwID0gbiArICI9IiwgYjsKCgkJCS8vIFN0cmljdCBtb2RlCgkJCWlmICghYykKCQkJCXJldHVybjsKCgkJCWIgPSBjLmluZGV4T2YoIjsgIiArIHApOwoKCQkJaWYgKGIgPT0gLTEpIHsKCQkJCWIgPSBjLmluZGV4T2YocCk7CgoJCQkJaWYgKGIgIT0gMCkKCQkJCQlyZXR1cm4gbnVsbDsKCQkJfSBlbHNlCgkJCQliICs9IDI7CgoJCQllID0gYy5pbmRleE9mKCI7IiwgYik7CgoJCQlpZiAoZSA9PSAtMSkKCQkJCWUgPSBjLmxlbmd0aDsKCgkJCXJldHVybiB1bmVzY2FwZShjLnN1YnN0cmluZyhiICsgcC5sZW5ndGgsIGUpKTsKCQl9LAoKCQlzZXQgOiBmdW5jdGlvbihuLCB2LCBlLCBwLCBkLCBzKSB7CgkJCWRvY3VtZW50LmNvb2tpZSA9IG4gKyAiPSIgKyBlc2NhcGUodikgKwoJCQkJKChlKSA/ICI7IGV4cGlyZXM9IiArIGUudG9HTVRTdHJpbmcoKSA6ICIiKSArCgkJCQkoKHApID8gIjsgcGF0aD0iICsgZXNjYXBlKHApIDogIiIpICsKCQkJCSgoZCkgPyAiOyBkb21haW49IiArIGQgOiAiIikgKwoJCQkJKChzKSA/ICI7IHNlY3VyZSIgOiAiIik7CgkJfSwKCgkJcmVtb3ZlIDogZnVuY3Rpb24obiwgcCkgewoJCQl2YXIgZCA9IG5ldyBEYXRlKCk7CgoJCQlkLnNldFRpbWUoZC5nZXRUaW1lKCkgLSAxMDAwKTsKCgkJCXRoaXMuc2V0KG4sICcnLCBkLCBwLCBkKTsKCQl9CgoJCX0pOwp9KSgpOwp0aW55bWNlLmNyZWF0ZSgnaHR0cDovLzEwLjIwLjE2MC4xOTgvd2lraS9zL2VuLzIxNjYvMzQvMy41LjkvXy9kb3dubG9hZC9iYXRjaC9jb20uYXRsYXNzaWFuLmNvbmZsdWVuY2UudGlueW1jZXBsdWdpbjplZGl0b3ItcmVzb3VyY2VzL3N0YXRpYyB0aW55bWNlLnV0aWwuSlNPTicsIHsKCXNlcmlhbGl6ZSA6IGZ1bmN0aW9uKG8pIHsKCQl2YXIgaSwgdiwgcyA9IHRpbnltY2UudXRpbC5KU09OLnNlcmlhbGl6ZSwgdDsKCgkJaWYgKG8gPT0gbnVsbCkKCQkJcmV0dXJuICdudWxsJzsKCgkJdCA9IHR5cGVvZiBvOwoKCQlpZiAodCA9PSAnc3RyaW5nJykgewoJCQl2ID0gJ1xiYlx0dFxublxmZlxyclwiIlwnXCdcXFxcJzsKCgkJCXJldHVybiAnIicgKyBvLnJlcGxhY2UoLyhbXHUwMDgwLVx1RkZGRlx4MDAtXHgxZlwiXSkvZywgZnVuY3Rpb24oYSwgYikgewoJCQkJaSA9IHYuaW5kZXhPZihiKTsKCgkJCQlpZiAoaSArIDEpCgkJCQkJcmV0dXJuICdcXCcgKyB2LmNoYXJBdChpICsgMSk7CgoJCQkJYSA9IGIuY2hhckNvZGVBdCgpLnRvU3RyaW5nKDE2KTsKCgkJCQlyZXR1cm4gJ1xcdScgKyAnMDAwMCcuc3Vic3RyaW5nKGEubGVuZ3RoKSArIGE7CgkJCX0pICsgJyInOwoJCX0KCgkJaWYgKHQgPT0gJ29iamVjdCcpIHsKCQkJaWYgKG8uaGFzT3duUHJvcGVydHkgJiYgbyBpbnN0YW5jZW9mIEFycmF5KSB7CgkJCQkJZm9yIChpPTAsIHYgPSAnWyc7IGk8by5sZW5ndGg7IGkrKykKCQkJCQkJdiArPSAoaSA+IDAgPyAnLCcgOiAnJykgKyBzKG9baV0pOwoKCQkJCQlyZXR1cm4gdiArICddJzsKCQkJCX0KCgkJCQl2ID0gJ3snOwoKCQkJCWZvciAoaSBpbiBvKQoJCQkJCXYgKz0gdHlwZW9mIG9baV0gIT0gJ2Z1bmN0aW9uJyA/ICh2Lmxlbmd0aCA+IDEgPyAnLCInIDogJyInKSArIGkgKyAnIjonICsgcyhvW2ldKSA6ICcnOwoKCQkJCXJldHVybiB2ICsgJ30nOwoJCX0KCgkJcmV0dXJuICcnICsgbzsKCX0sCgoJcGFyc2UgOiBmdW5jdGlvbihzKSB7CgkJdHJ5IHsKCQkJcmV0dXJuIGV2YWwoJygnICsgcyArICcpJyk7CgkJfSBjYXRjaCAoZXgpIHsKCQkJLy8gSWdub3JlCgkJfQoJfQoKCX0pOwp0aW55bWNlLmNyZWF0ZSgnaHR0cDovLzEwLjIwLjE2MC4xOTgvd2lraS9zL2VuLzIxNjYvMzQvMy41LjkvXy9kb3dubG9hZC9iYXRjaC9jb20uYXRsYXNzaWFuLmNvbmZsdWVuY2UudGlueW1jZXBsdWdpbjplZGl0b3ItcmVzb3VyY2VzL3N0YXRpYyB0aW55bWNlLnV0aWwuWEhSJywgewoJc2VuZCA6IGZ1bmN0aW9uKG8pIHsKCQl2YXIgeCwgdCwgdyA9IHdpbmRvdywgYyA9IDA7CgoJCS8vIERlZmF1bHQgc2V0dGluZ3MKCQlvLnNjb3BlID0gby5zY29wZSB8fCB0aGlzOwoJCW8uc3VjY2Vzc19zY29wZSA9IG8uc3VjY2Vzc19zY29wZSB8fCBvLnNjb3BlOwoJCW8uZXJyb3Jfc2NvcGUgPSBvLmVycm9yX3Njb3BlIHx8IG8uc2NvcGU7CgkJby5hc3luYyA9IG8uYXN5bmMgPT09IGZhbHNlID8gZmFsc2UgOiB0cnVlOwoJCW8uZGF0YSA9IG8uZGF0YSB8fCAnJzsKCgkJZnVuY3Rpb24gZ2V0KHMpIHsKCQkJeCA9IDA7CgoJCQl0cnkgewoJCQkJeCA9IG5ldyBBY3RpdmVYT2JqZWN0KHMpOwoJCQl9IGNhdGNoIChleCkgewoJCQl9CgoJCQlyZXR1cm4geDsKCQl9OwoKCQl4ID0gdy5YTUxIdHRwUmVxdWVzdCA/IG5ldyBYTUxIdHRwUmVxdWVzdCgpIDogZ2V0KCdNaWNyb3NvZnQuWE1MSFRUUCcpIHx8IGdldCgnTXN4bWwyLlhNTEhUVFAnKTsKCgkJaWYgKHgpIHsKCQkJaWYgKHgub3ZlcnJpZGVNaW1lVHlwZSkKCQkJCXgub3ZlcnJpZGVNaW1lVHlwZShvLmNvbnRlbnRfdHlwZSk7CgoJCQl4Lm9wZW4oby50eXBlIHx8IChvLmRhdGEgPyAnUE9TVCcgOiAnR0VUJyksIG8udXJsLCBvLmFzeW5jKTsKCgkJCWlmIChvLmNvbnRlbnRfdHlwZSkKCQkJCXguc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC1UeXBlJywgby5jb250ZW50X3R5cGUpOwoKCQkJeC5zZW5kKG8uZGF0YSk7CgoJCQlmdW5jdGlvbiByZWFkeSgpIHsKCQkJCWlmICghby5hc3luYyB8fCB4LnJlYWR5U3RhdGUgPT0gNCB8fCBjKysgPiAxMDAwMCkgewoJCQkJCWlmIChvLnN1Y2Nlc3MgJiYgYyA8IDEwMDAwICYmIHguc3RhdHVzID09IDIwMCkKCQkJCQkJby5zdWNjZXNzLmNhbGwoby5zdWNjZXNzX3Njb3BlLCAnJyArIHgucmVzcG9uc2VUZXh0LCB4LCBvKTsKCQkJCQllbHNlIGlmIChvLmVycm9yKQoJCQkJCQlvLmVycm9yLmNhbGwoby5lcnJvcl9zY29wZSwgYyA+IDEwMDAwID8gJ1RJTUVEX09VVCcgOiAnR0VORVJBTCcsIHgsIG8pOwoKCQkJCQl4ID0gbnVsbDsKCQkJCX0gZWxzZQoJCQkJCXcuc2V0VGltZW91dChyZWFkeSwgMTApOwoJCQl9OwoKCQkJLy8gU3luY3Jvbm91cyByZXF1ZXN0CgkJCWlmICghby5hc3luYykKCQkJCXJldHVybiByZWFkeSgpOwoKCQkJLy8gV2FpdCBmb3IgcmVzcG9uc2UsIG9uUmVhZHlTdGF0ZUNoYW5nZSBjYW4gbm90IGJlIHVzZWQgc2luY2UgaXQgbGVha3MgbWVtb3J5IGluIElFCgkJCXQgPSB3LnNldFRpbWVvdXQocmVhZHksIDEwKTsKCQl9CgoJCX0KfSk7CihmdW5jdGlvbigpIHsKCXZhciBleHRlbmQgPSB0aW55bWNlLmV4dGVuZCwgSlNPTiA9IHRpbnltY2UudXRpbC5KU09OLCBYSFIgPSB0aW55bWNlLnV0aWwuWEhSOwoKCXRpbnltY2UuY3JlYXRlKCd0aW55bWNlLnV0aWwuSlNPTlJlcXVlc3QnLCB7CgkJSlNPTlJlcXVlc3QgOiBmdW5jdGlvbihzKSB7CgkJCXRoaXMuc2V0dGluZ3MgPSBleHRlbmQoewoJCQl9LCBzKTsKCQkJdGhpcy5jb3VudCA9IDA7CgkJfSwKCgkJc2VuZCA6IGZ1bmN0aW9uKG8pIHsKCQkJdmFyIGVjYiA9IG8uZXJyb3IsIHNjYiA9IG8uc3VjY2VzczsKCgkJCW8gPSBleHRlbmQodGhpcy5zZXR0aW5ncywgbyk7CgoJCQlvLnN1Y2Nlc3MgPSBmdW5jdGlvbihjLCB4KSB7CgkJCQljID0gSlNPTi5wYXJzZShjKTsKCgkJCQlpZiAodHlwZW9mKGMpID09ICd1bmRlZmluZWQnKSB7CgkJCQkJYyA9IHsKCQkJCQkJZXJyb3IgOiAnSlNPTiBQYXJzZSBlcnJvci4nCgkJCQkJfTsKCQkJCX0KCgkJCQlpZiAoYy5lcnJvcikKCQkJCQllY2IuY2FsbChvLmVycm9yX3Njb3BlIHx8IG8uc2NvcGUsIGMuZXJyb3IsIHgpOwoJCQkJZWxzZQoJCQkJCXNjYi5jYWxsKG8uc3VjY2Vzc19zY29wZSB8fCBvLnNjb3BlLCBjLnJlc3VsdCk7CgkJCX07CgoJCQlvLmVycm9yID0gZnVuY3Rpb24odHksIHgpIHsKCQkJCWVjYi5jYWxsKG8uZXJyb3Jfc2NvcGUgfHwgby5zY29wZSwgdHksIHgpOwoJCQl9OwoKCQkJby5kYXRhID0gSlNPTi5zZXJpYWxpemUoewoJCQkJaWQgOiBvLmlkIHx8ICdjJyArICh0aGlzLmNvdW50KyspLAoJCQkJbWV0aG9kIDogby5tZXRob2QsCgkJCQlwYXJhbXMgOiBvLnBhcmFtcwoJCQl9KTsKCgkJCS8vIEpTT04gY29udGVudCB0eXBlIGZvciBSdWJ5IG9uIHJhaWxzLiBCdWc6ICMxODgzMjg3CgkJCW8uY29udGVudF90eXBlID0gJ2FwcGxpY2F0aW9uL2pzb24nOwoKCQkJWEhSLnNlbmQobyk7CgkJfSwKCgkJJ3N0YXRpYycgOiB7CgkJCXNlbmRSUEMgOiBmdW5jdGlvbihvKSB7CgkJCQlyZXR1cm4gbmV3IHRpbnltY2UudXRpbC5KU09OUmVxdWVzdCgpLnNlbmQobyk7CgkJCX0KCQl9CgoJCX0pOwp9KCkpOyhmdW5jdGlvbih0aW55bWNlKSB7CgkvLyBTaG9ydGVuIG5hbWVzCgl2YXIgZWFjaCA9IHRpbnltY2UuZWFjaCwgaXMgPSB0aW55bWNlLmlzOwoJdmFyIGlzV2ViS2l0ID0gdGlueW1jZS5pc1dlYktpdCwgaXNJRSA9IHRpbnltY2UuaXNJRTsKCgl0aW55bWNlLmNyZWF0ZSgndGlueW1jZS5kb20uRE9NVXRpbHMnLCB7CgkJZG9jIDogbnVsbCwKCQlyb290IDogbnVsbCwKCQlmaWxlcyA6IG51bGwsCgkJcGl4ZWxTdHlsZXMgOiAvXih0b3B8bGVmdHxib3R0b218cmlnaHR8d2lkdGh8aGVpZ2h0fGJvcmRlcldpZHRoKSQvLAoJCXByb3BzIDogewoJCQkiZm9yIiA6ICJodG1sRm9yIiwKCQkJImNsYXNzIiA6ICJjbGFzc05hbWUiLAoJCQljbGFzc05hbWUgOiAiY2xhc3NOYW1lIiwKCQkJY2hlY2tlZCA6ICJjaGVja2VkIiwKCQkJZGlzYWJsZWQgOiAiZGlzYWJsZWQiLAoJCQltYXhsZW5ndGggOiAibWF4TGVuZ3RoIiwKCQkJcmVhZG9ubHkgOiAicmVhZE9ubHkiLAoJCQlzZWxlY3RlZCA6ICJzZWxlY3RlZCIsCgkJCXZhbHVlIDogInZhbHVlIiwKCQkJaWQgOiAiaWQiLAoJCQluYW1lIDogIm5hbWUiLAoJCQl0eXBlIDogInR5cGUiCgkJfSwKCgkJRE9NVXRpbHMgOiBmdW5jdGlvbihkLCBzKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXQuZG9jID0gZDsKCQkJdC53aW4gPSB3aW5kb3c7CgkJCXQuZmlsZXMgPSB7fTsKCQkJdC5jc3NGbGlja2VyID0gZmFsc2U7CgkJCXQuY291bnRlciA9IDA7CgkJCXQuYm94TW9kZWwgPSAhdGlueW1jZS5pc0lFIHx8IGQuY29tcGF0TW9kZSA9PSAiQ1NTMUNvbXBhdCI7IAoJCQl0LnN0ZE1vZGUgPSBkLmRvY3VtZW50TW9kZSA9PT0gODsKCgkJCXQuc2V0dGluZ3MgPSBzID0gdGlueW1jZS5leHRlbmQoewoJCQkJa2VlcF92YWx1ZXMgOiBmYWxzZSwKCQkJCWhleF9jb2xvcnMgOiAxLAoJCQkJcHJvY2Vzc19odG1sIDogMQoJCQl9LCBzKTsKCgkJCS8vIEZpeCBJRTZTUDIgZmxpY2tlciBhbmQgY2hlY2sgaXQgZmFpbGVkIGZvciBwcmUgU1AyCgkJCWlmICh0aW55bWNlLmlzSUU2KSB7CgkJCQl0cnkgewoJCQkJCWQuZXhlY0NvbW1hbmQoJ0JhY2tncm91bmRJbWFnZUNhY2hlJywgZmFsc2UsIHRydWUpOwoJCQkJfSBjYXRjaCAoZSkgewoJCQkJCXQuY3NzRmxpY2tlciA9IHRydWU7CgkJCQl9CgkJCX0KCgkJCXRpbnltY2UuYWRkVW5sb2FkKHQuZGVzdHJveSwgdCk7CgkJfSwKCgkJZ2V0Um9vdCA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXMsIHMgPSB0LnNldHRpbmdzOwoKCQkJcmV0dXJuIChzICYmIHQuZ2V0KHMucm9vdF9lbGVtZW50KSkgfHwgdC5kb2MuYm9keTsKCQl9LAoKCQlnZXRWaWV3UG9ydCA6IGZ1bmN0aW9uKHcpIHsKCQkJdmFyIGQsIGI7CgoJCQl3ID0gIXcgPyB0aGlzLndpbiA6IHc7CgkJCWQgPSB3LmRvY3VtZW50OwoJCQliID0gdGhpcy5ib3hNb2RlbCA/IGQuZG9jdW1lbnRFbGVtZW50IDogZC5ib2R5OwoKCQkJLy8gUmV0dXJucyB2aWV3cG9ydCBzaXplIGV4Y2x1ZGluZyBzY3JvbGxiYXJzCgkJCXJldHVybiB7CgkJCQl4IDogdy5wYWdlWE9mZnNldCB8fCBiLnNjcm9sbExlZnQsCgkJCQl5IDogdy5wYWdlWU9mZnNldCB8fCBiLnNjcm9sbFRvcCwKCQkJCXcgOiB3LmlubmVyV2lkdGggfHwgYi5jbGllbnRXaWR0aCwKCQkJCWggOiB3LmlubmVySGVpZ2h0IHx8IGIuY2xpZW50SGVpZ2h0CgkJCX07CgkJfSwKCgkJZ2V0UmVjdCA6IGZ1bmN0aW9uKGUpIHsKCQkJdmFyIHAsIHQgPSB0aGlzLCBzcjsKCgkJCWUgPSB0LmdldChlKTsKCQkJcCA9IHQuZ2V0UG9zKGUpOwoJCQlzciA9IHQuZ2V0U2l6ZShlKTsKCgkJCXJldHVybiB7CgkJCQl4IDogcC54LAoJCQkJeSA6IHAueSwKCQkJCXcgOiBzci53LAoJCQkJaCA6IHNyLmgKCQkJfTsKCQl9LAoKCQlnZXRTaXplIDogZnVuY3Rpb24oZSkgewoJCQl2YXIgdCA9IHRoaXMsIHcsIGg7CgoJCQllID0gdC5nZXQoZSk7CgkJCXcgPSB0LmdldFN0eWxlKGUsICd3aWR0aCcpOwoJCQloID0gdC5nZXRTdHlsZShlLCAnaGVpZ2h0Jyk7CgoJCQkvLyBOb24gcGl4ZWwgdmFsdWUsIHRoZW4gZm9yY2Ugb2Zmc2V0L2NsaWVudFdpZHRoCgkJCWlmICh3LmluZGV4T2YoJ3B4JykgPT09IC0xKQoJCQkJdyA9IDA7CgoJCQkvLyBOb24gcGl4ZWwgdmFsdWUsIHRoZW4gZm9yY2Ugb2Zmc2V0L2NsaWVudFdpZHRoCgkJCWlmIChoLmluZGV4T2YoJ3B4JykgPT09IC0xKQoJCQkJaCA9IDA7CgoJCQlyZXR1cm4gewoJCQkJdyA6IHBhcnNlSW50KHcpIHx8IGUub2Zmc2V0V2lkdGggfHwgZS5jbGllbnRXaWR0aCwKCQkJCWggOiBwYXJzZUludChoKSB8fCBlLm9mZnNldEhlaWdodCB8fCBlLmNsaWVudEhlaWdodAoJCQl9OwoJCX0sCgoJCWdldFBhcmVudCA6IGZ1bmN0aW9uKG4sIGYsIHIpIHsKCQkJcmV0dXJuIHRoaXMuZ2V0UGFyZW50cyhuLCBmLCByLCBmYWxzZSk7CgkJfSwKCgkJZ2V0UGFyZW50cyA6IGZ1bmN0aW9uKG4sIGYsIHIsIGMpIHsKCQkJdmFyIHQgPSB0aGlzLCBuYSwgc2UgPSB0LnNldHRpbmdzLCBvID0gW107CgoJCQluID0gdC5nZXQobik7CgkJCWMgPSBjID09PSB1bmRlZmluZWQ7CgoJCQlpZiAoc2Uuc3RyaWN0X3Jvb3QpCgkJCQlyID0gciB8fCB0LmdldFJvb3QoKTsKCgkJCS8vIFdyYXAgbm9kZSBuYW1lIGFzIGZ1bmMKCQkJaWYgKGlzKGYsICdzdHJpbmcnKSkgewoJCQkJbmEgPSBmOwoKCQkJCWlmIChmID09PSAnKicpIHsKCQkJCQlmID0gZnVuY3Rpb24obikge3JldHVybiBuLm5vZGVUeXBlID09IDE7fTsKCQkJCX0gZWxzZSB7CgkJCQkJZiA9IGZ1bmN0aW9uKG4pIHsKCQkJCQkJcmV0dXJuIHQuaXMobiwgbmEpOwoJCQkJCX07CgkJCQl9CgkJCX0KCgkJCXdoaWxlIChuKSB7CgkJCQlpZiAobiA9PSByIHx8ICFuLm5vZGVUeXBlIHx8IG4ubm9kZVR5cGUgPT09IDkpCgkJCQkJYnJlYWs7CgoJCQkJaWYgKCFmIHx8IGYobikpIHsKCQkJCQlpZiAoYykKCQkJCQkJby5wdXNoKG4pOwoJCQkJCWVsc2UKCQkJCQkJcmV0dXJuIG47CgkJCQl9CgoJCQkJbiA9IG4ucGFyZW50Tm9kZTsKCQkJfQoKCQkJcmV0dXJuIGMgPyBvIDogbnVsbDsKCQl9LAoKCQlnZXQgOiBmdW5jdGlvbihlKSB7CgkJCXZhciBuOwoKCQkJaWYgKGUgJiYgdGhpcy5kb2MgJiYgdHlwZW9mKGUpID09ICdzdHJpbmcnKSB7CgkJCQluID0gZTsKCQkJCWUgPSB0aGlzLmRvYy5nZXRFbGVtZW50QnlJZChlKTsKCgkJCQkvLyBJRSBhbmQgT3BlcmEgcmV0dXJucyBtZXRhIGVsZW1lbnRzIHdoZW4gdGhleSBtYXRjaCB0aGUgc3BlY2lmaWVkIGlucHV0IElELCBidXQgZ2V0RWxlbWVudHNCeU5hbWUgc2VlbXMgdG8gZG8gdGhlIHRyaWNrCgkJCQlpZiAoZSAmJiBlLmlkICE9PSBuKQoJCQkJCXJldHVybiB0aGlzLmRvYy5nZXRFbGVtZW50c0J5TmFtZShuKVsxXTsKCQkJfQoKCQkJcmV0dXJuIGU7CgkJfSwKCgoJCXNlbGVjdCA6IGZ1bmN0aW9uKHBhLCBzKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXJldHVybiB0aW55bWNlLmRvbS5TaXp6bGUocGEsIHQuZ2V0KHMpIHx8IHQuZ2V0KHQuc2V0dGluZ3Mucm9vdF9lbGVtZW50KSB8fCB0LmRvYywgW10pOwoJCX0sCgoJCWlzIDogZnVuY3Rpb24obiwgcGF0dCkgewoJCQlyZXR1cm4gdGlueW1jZS5kb20uU2l6emxlLm1hdGNoZXMocGF0dCwgbi5ub2RlVHlwZSA/IFtuXSA6IG4pLmxlbmd0aCA+IDA7CgkJfSwKCgoJCWFkZCA6IGZ1bmN0aW9uKHAsIG4sIGEsIGgsIGMpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJcmV0dXJuIHRoaXMucnVuKHAsIGZ1bmN0aW9uKHApIHsKCQkJCXZhciBlLCBrOwoKCQkJCWUgPSBpcyhuLCAnc3RyaW5nJykgPyB0LmRvYy5jcmVhdGVFbGVtZW50KG4pIDogbjsKCQkJCXQuc2V0QXR0cmlicyhlLCBhKTsKCgkJCQlpZiAoaCkgewoJCQkJCWlmIChoLm5vZGVUeXBlKQoJCQkJCQllLmFwcGVuZENoaWxkKGgpOwoJCQkJCWVsc2UKCQkJCQkJdC5zZXRIVE1MKGUsIGgpOwoJCQkJfQoKCQkJCXJldHVybiAhYyA/IHAuYXBwZW5kQ2hpbGQoZSkgOiBlOwoJCQl9KTsKCQl9LAoKCQljcmVhdGUgOiBmdW5jdGlvbihuLCBhLCBoKSB7CgkJCXJldHVybiB0aGlzLmFkZCh0aGlzLmRvYy5jcmVhdGVFbGVtZW50KG4pLCBuLCBhLCBoLCAxKTsKCQl9LAoKCQljcmVhdGVIVE1MIDogZnVuY3Rpb24obiwgYSwgaCkgewoJCQl2YXIgbyA9ICcnLCB0ID0gdGhpcywgazsKCgkJCW8gKz0gJzwnICsgbjsKCgkJCWZvciAoayBpbiBhKSB7CgkJCQlpZiAoYS5oYXNPd25Qcm9wZXJ0eShrKSkKCQkJCQlvICs9ICcgJyArIGsgKyAnPSInICsgdC5lbmNvZGUoYVtrXSkgKyAnIic7CgkJCX0KCgkJCWlmICh0aW55bWNlLmlzKGgpKQoJCQkJcmV0dXJuIG8gKyAnPicgKyBoICsgJzwvJyArIG4gKyAnPic7CgoJCQlyZXR1cm4gbyArICcgLz4nOwoJCX0sCgoJCXJlbW92ZSA6IGZ1bmN0aW9uKG4sIGspIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJcmV0dXJuIHRoaXMucnVuKG4sIGZ1bmN0aW9uKG4pIHsKCQkJCXZhciBwLCBnLCBpOwoKCQkJCXAgPSBuLnBhcmVudE5vZGU7CgoJCQkJaWYgKCFwKQoJCQkJCXJldHVybiBudWxsOwoKCQkJCWlmIChrKSB7CgkJCQkJZm9yIChpID0gbi5jaGlsZE5vZGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKQoJCQkJCQl0Lmluc2VydEFmdGVyKG4uY2hpbGROb2Rlc1tpXSwgbik7CgoJCQkJCS8vZWFjaChuLmNoaWxkTm9kZXMsIGZ1bmN0aW9uKGMpIHsKCQkJCQkvLwlwLmluc2VydEJlZm9yZShjLmNsb25lTm9kZSh0cnVlKSwgbik7CgkJCQkJLy99KTsKCQkJCX0KCgkJCQkvLyBGaXggSUUgcHN1ZWRvIGxlYWsKCQkJCWlmICh0LmZpeFBzdWVkb0xlYWtzKSB7CgkJCQkJcCA9IG4uY2xvbmVOb2RlKHRydWUpOwoJCQkJCWsgPSAnSUVMZWFrR2FyYmFnZUJpbic7CgkJCQkJZyA9IHQuZ2V0KGspIHx8IHQuYWRkKHQuZG9jLmJvZHksICdkaXYnLCB7aWQgOiBrLCBzdHlsZSA6ICdkaXNwbGF5Om5vbmUnfSk7CgkJCQkJZy5hcHBlbmRDaGlsZChuKTsKCQkJCQlnLmlubmVySFRNTCA9ICcnOwoKCQkJCQlyZXR1cm4gcDsKCQkJCX0KCgkJCQlyZXR1cm4gcC5yZW1vdmVDaGlsZChuKTsKCQkJfSk7CgkJfSwKCgkJc2V0U3R5bGUgOiBmdW5jdGlvbihuLCBuYSwgdikgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQlyZXR1cm4gdC5ydW4obiwgZnVuY3Rpb24oZSkgewoJCQkJdmFyIHMsIGk7CgoJCQkJcyA9IGUuc3R5bGU7CgoJCQkJLy8gQ2FtZWxjYXNlIGl0LCBpZiBuZWVkZWQKCQkJCW5hID0gbmEucmVwbGFjZSgvLShcRCkvZywgZnVuY3Rpb24oYSwgYil7CgkJCQkJcmV0dXJuIGIudG9VcHBlckNhc2UoKTsKCQkJCX0pOwoKCQkJCS8vIERlZmF1bHQgcHggc3VmZml4IG9uIHRoZXNlCgkJCQlpZiAodC5waXhlbFN0eWxlcy50ZXN0KG5hKSAmJiAodGlueW1jZS5pcyh2LCAnbnVtYmVyJykgfHwgL15bXC0wLTlcLl0rJC8udGVzdCh2KSkpCgkJCQkJdiArPSAncHgnOwoKCQkJCXN3aXRjaCAobmEpIHsKCQkJCQljYXNlICdvcGFjaXR5JzoKCQkJCQkJLy8gSUUgc3BlY2lmaWMgb3BhY2l0eQoJCQkJCQlpZiAoaXNJRSkgewoJCQkJCQkJcy5maWx0ZXIgPSB2ID09PSAnJyA/ICcnIDogImFscGhhKG9wYWNpdHk9IiArICh2ICogMTAwKSArICIpIjsKCgkJCQkJCQlpZiAoIW4uY3VycmVudFN0eWxlIHx8ICFuLmN1cnJlbnRTdHlsZS5oYXNMYXlvdXQpCgkJCQkJCQkJcy5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7CgkJCQkJCX0KCgkJCQkJCS8vIEZpeCBmb3Igb2xkZXIgYnJvd3NlcnMKCQkJCQkJc1tuYV0gPSBzWyctbW96LW9wYWNpdHknXSA9IHNbJy1raHRtbC1vcGFjaXR5J10gPSB2IHx8ICcnOwoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAnZmxvYXQnOgoJCQkJCQlpc0lFID8gcy5zdHlsZUZsb2F0ID0gdiA6IHMuY3NzRmxvYXQgPSB2OwoJCQkJCQlicmVhazsKCgkJCQkJZGVmYXVsdDoKCQkJCQkJc1tuYV0gPSB2IHx8ICcnOwoJCQkJfQoKCQkJCS8vIEZvcmNlIHVwZGF0ZSBvZiB0aGUgc3R5bGUgZGF0YQoJCQkJaWYgKHQuc2V0dGluZ3MudXBkYXRlX3N0eWxlcykKCQkJCQl0LnNldEF0dHJpYihlLCAnbWNlX3N0eWxlJyk7CgkJCX0pOwoJCX0sCgoJCWdldFN0eWxlIDogZnVuY3Rpb24obiwgbmEsIGMpIHsKCQkJbiA9IHRoaXMuZ2V0KG4pOwoKCQkJaWYgKCFuKQoJCQkJcmV0dXJuIGZhbHNlOwoKCQkJLy8gR2Vja28KCQkJaWYgKHRoaXMuZG9jLmRlZmF1bHRWaWV3ICYmIGMpIHsKCQkJCS8vIFJlbW92ZSBjYW1lbGNhc2UKCQkJCW5hID0gbmEucmVwbGFjZSgvW0EtWl0vZywgZnVuY3Rpb24oYSl7CgkJCQkJcmV0dXJuICctJyArIGE7CgkJCQl9KTsKCgkJCQl0cnkgewoJCQkJCXJldHVybiB0aGlzLmRvYy5kZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlKG4sIG51bGwpLmdldFByb3BlcnR5VmFsdWUobmEpOwoJCQkJfSBjYXRjaCAoZXgpIHsKCQkJCQkvLyBPbGQgc2FmYXJpIG1pZ2h0IGZhaWwKCQkJCQlyZXR1cm4gbnVsbDsKCQkJCX0KCQkJfQoKCQkJLy8gQ2FtZWxjYXNlIGl0LCBpZiBuZWVkZWQKCQkJbmEgPSBuYS5yZXBsYWNlKC8tKFxEKS9nLCBmdW5jdGlvbihhLCBiKXsKCQkJCXJldHVybiBiLnRvVXBwZXJDYXNlKCk7CgkJCX0pOwoKCQkJaWYgKG5hID09ICdmbG9hdCcpCgkJCQluYSA9IGlzSUUgPyAnc3R5bGVGbG9hdCcgOiAnY3NzRmxvYXQnOwoKCQkJLy8gSUUgJiBPcGVyYQoJCQlpZiAobi5jdXJyZW50U3R5bGUgJiYgYykKCQkJCXJldHVybiBuLmN1cnJlbnRTdHlsZVtuYV07CgoJCQlyZXR1cm4gbi5zdHlsZVtuYV07CgkJfSwKCgkJc2V0U3R5bGVzIDogZnVuY3Rpb24oZSwgbykgewoJCQl2YXIgdCA9IHRoaXMsIHMgPSB0LnNldHRpbmdzLCBvbDsKCgkJCW9sID0gcy51cGRhdGVfc3R5bGVzOwoJCQlzLnVwZGF0ZV9zdHlsZXMgPSAwOwoKCQkJZWFjaChvLCBmdW5jdGlvbih2LCBuKSB7CgkJCQl0LnNldFN0eWxlKGUsIG4sIHYpOwoJCQl9KTsKCgkJCS8vIFVwZGF0ZSBzdHlsZSBpbmZvCgkJCXMudXBkYXRlX3N0eWxlcyA9IG9sOwoJCQlpZiAocy51cGRhdGVfc3R5bGVzKQoJCQkJdC5zZXRBdHRyaWIoZSwgcy5jc3NUZXh0KTsKCQl9LAoKCQlzZXRBdHRyaWIgOiBmdW5jdGlvbihlLCBuLCB2KSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCS8vIFdoYXRzIHRoZSBwb2ludAoJCQlpZiAoIWUgfHwgIW4pCgkJCQlyZXR1cm47CgoJCQkvLyBTdHJpY3QgWE1MIG1vZGUKCQkJaWYgKHQuc2V0dGluZ3Muc3RyaWN0KQoJCQkJbiA9IG4udG9Mb3dlckNhc2UoKTsKCgkJCXJldHVybiB0aGlzLnJ1bihlLCBmdW5jdGlvbihlKSB7CgkJCQl2YXIgcyA9IHQuc2V0dGluZ3M7CgoJCQkJc3dpdGNoIChuKSB7CgkJCQkJY2FzZSAic3R5bGUiOgoJCQkJCQlpZiAoIWlzKHYsICdzdHJpbmcnKSkgewoJCQkJCQkJZWFjaCh2LCBmdW5jdGlvbih2LCBuKSB7CgkJCQkJCQkJdC5zZXRTdHlsZShlLCBuLCB2KTsKCQkJCQkJCX0pOwoKCQkJCQkJCXJldHVybjsKCQkJCQkJfQoKCQkJCQkJLy8gTm8gbWNlX3N0eWxlIGZvciBlbGVtZW50cyB3aXRoIHRoZXNlIHNpbmNlIHRoZXkgbWlnaHQgZ2V0IHJlc2l6ZWQgYnkgdGhlIHVzZXIKCQkJCQkJaWYgKHMua2VlcF92YWx1ZXMpIHsKCQkJCQkJCWlmICh2ICYmICF0Ll9pc1Jlcyh2KSkKCQkJCQkJCQllLnNldEF0dHJpYnV0ZSgnbWNlX3N0eWxlJywgdiwgMik7CgkJCQkJCQllbHNlCgkJCQkJCQkJZS5yZW1vdmVBdHRyaWJ1dGUoJ21jZV9zdHlsZScsIDIpOwoJCQkJCQl9CgoJCQkJCQllLnN0eWxlLmNzc1RleHQgPSB2OwoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAiY2xhc3MiOgoJCQkJCQllLmNsYXNzTmFtZSA9IHYgfHwgJyc7IC8vIEZpeCBJRSBudWxsIGJ1ZwoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAic3JjIjoKCQkJCQljYXNlICJocmVmIjoKCQkJCQkJaWYgKHMua2VlcF92YWx1ZXMpIHsKCQkJCQkJCWlmIChzLnVybF9jb252ZXJ0ZXIpCgkJCQkJCQkJdiA9IHMudXJsX2NvbnZlcnRlci5jYWxsKHMudXJsX2NvbnZlcnRlcl9zY29wZSB8fCB0LCB2LCBuLCBlKTsKCgkJCQkJCQl0LnNldEF0dHJpYihlLCAnbWNlXycgKyBuLCB2LCAyKTsKCQkJCQkJfQoKCQkJCQkJYnJlYWs7CgoJCQkJCWNhc2UgInNoYXBlIjoKCQkJCQkJZS5zZXRBdHRyaWJ1dGUoJ21jZV9zdHlsZScsIHYpOwoJCQkJCQlicmVhazsKCQkJCX0KCgkJCQlpZiAoaXModikgJiYgdiAhPT0gbnVsbCAmJiB2Lmxlbmd0aCAhPT0gMCkKCQkJCQllLnNldEF0dHJpYnV0ZShuLCAnJyArIHYsIDIpOwoJCQkJZWxzZQoJCQkJCWUucmVtb3ZlQXR0cmlidXRlKG4sIDIpOwoJCQl9KTsKCQl9LAoKCQlzZXRBdHRyaWJzIDogZnVuY3Rpb24oZSwgbykgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQlyZXR1cm4gdGhpcy5ydW4oZSwgZnVuY3Rpb24oZSkgewoJCQkJZWFjaChvLCBmdW5jdGlvbih2LCBuKSB7CgkJCQkJdC5zZXRBdHRyaWIoZSwgbiwgdik7CgkJCQl9KTsKCQkJfSk7CgkJfSwKCgkJZ2V0QXR0cmliIDogZnVuY3Rpb24oZSwgbiwgZHYpIHsKCQkJdmFyIHYsIHQgPSB0aGlzOwoKCQkJZSA9IHQuZ2V0KGUpOwoKCQkJaWYgKCFlIHx8IGUubm9kZVR5cGUgIT09IDEpCgkJCQlyZXR1cm4gZmFsc2U7CgoJCQlpZiAoIWlzKGR2KSkKCQkJCWR2ID0gJyc7CgoJCQkvLyBUcnkgdGhlIG1jZSB2YXJpYW50IGZvciB0aGVzZQoJCQlpZiAoL14oc3JjfGhyZWZ8c3R5bGV8Y29vcmRzfHNoYXBlKSQvLnRlc3QobikpIHsKCQkJCXYgPSBlLmdldEF0dHJpYnV0ZSgibWNlXyIgKyBuKTsKCgkJCQlpZiAodikKCQkJCQlyZXR1cm4gdjsKCQkJfQoKCQkJaWYgKGlzSUUgJiYgdC5wcm9wc1tuXSkgewoJCQkJdiA9IGVbdC5wcm9wc1tuXV07CgkJCQl2ID0gdiAmJiB2Lm5vZGVWYWx1ZSA/IHYubm9kZVZhbHVlIDogdjsKCQkJfQoKCQkJaWYgKCF2KQoJCQkJdiA9IGUuZ2V0QXR0cmlidXRlKG4sIDIpOwoKCQkJaWYgKG4gPT09ICdzdHlsZScpIHsKCQkJCXYgPSB2IHx8IGUuc3R5bGUuY3NzVGV4dDsKCgkJCQlpZiAodikgewoJCQkJCXYgPSB0LnNlcmlhbGl6ZVN0eWxlKHQucGFyc2VTdHlsZSh2KSk7CgoJCQkJCWlmICh0LnNldHRpbmdzLmtlZXBfdmFsdWVzICYmICF0Ll9pc1Jlcyh2KSkKCQkJCQkJZS5zZXRBdHRyaWJ1dGUoJ21jZV9zdHlsZScsIHYpOwoJCQkJfQoJCQl9CgoJCQkvLyBSZW1vdmUgQXBwbGUgYW5kIFdlYktpdCBzdHVmZgoJCQlpZiAoaXNXZWJLaXQgJiYgbiA9PT0gImNsYXNzIiAmJiB2KQoJCQkJdiA9IHYucmVwbGFjZSgvKGFwcGxlfHdlYmtpdClcLVthLXpcLV0rL2dpLCAnJyk7CgoJCQkvLyBIYW5kbGUgSUUgaXNzdWVzCgkJCWlmIChpc0lFKSB7CgkJCQlzd2l0Y2ggKG4pIHsKCQkJCQljYXNlICdyb3dzcGFuJzoKCQkJCQljYXNlICdjb2xzcGFuJzoKCQkJCQkJLy8gSUUgcmV0dXJucyAxIGFzIGRlZmF1bHQgdmFsdWUKCQkJCQkJaWYgKHYgPT09IDEpCgkJCQkJCQl2ID0gJyc7CgoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAnc2l6ZSc6CgkJCQkJCS8vIElFIHJldHVybnMgKzAgYXMgZGVmYXVsdCB2YWx1ZSBmb3Igc2l6ZQoJCQkJCQlpZiAodiA9PT0gJyswJyB8fCB2ID09PSAyMCB8fCB2ID09PSAwKQoJCQkJCQkJdiA9ICcnOwoKCQkJCQkJYnJlYWs7CgoJCQkJCWNhc2UgJ3dpZHRoJzoKCQkJCQljYXNlICdoZWlnaHQnOgoJCQkJCWNhc2UgJ3ZzcGFjZSc6CgkJCQkJY2FzZSAnY2hlY2tlZCc6CgkJCQkJY2FzZSAnZGlzYWJsZWQnOgoJCQkJCWNhc2UgJ3JlYWRvbmx5JzoKCQkJCQkJaWYgKHYgPT09IDApCgkJCQkJCQl2ID0gJyc7CgoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAnaHNwYWNlJzoKCQkJCQkJLy8gSUUgcmV0dXJucyAtMSBhcyBkZWZhdWx0IHZhbHVlCgkJCQkJCWlmICh2ID09PSAtMSkKCQkJCQkJCXYgPSAnJzsKCgkJCQkJCWJyZWFrOwoKCQkJCQljYXNlICdtYXhsZW5ndGgnOgoJCQkJCWNhc2UgJ3RhYmluZGV4JzoKCQkJCQkJLy8gSUUgcmV0dXJucyBkZWZhdWx0IHZhbHVlCgkJCQkJCWlmICh2ID09PSAzMjc2OCB8fCB2ID09PSAyMTQ3NDgzNjQ3IHx8IHYgPT09ICczMjc2OCcpCgkJCQkJCQl2ID0gJyc7CgoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAnbXVsdGlwbGUnOgoJCQkJCWNhc2UgJ2NvbXBhY3QnOgoJCQkJCWNhc2UgJ25vc2hhZGUnOgoJCQkJCWNhc2UgJ25vd3JhcCc6CgkJCQkJCWlmICh2ID09PSA2NTUzNSkKCQkJCQkJCXJldHVybiBuOwoKCQkJCQkJcmV0dXJuIGR2OwoKCQkJCQljYXNlICdzaGFwZSc6CgkJCQkJCXYgPSB2LnRvTG93ZXJDYXNlKCk7CgkJCQkJCWJyZWFrOwoKCQkJCQlkZWZhdWx0OgoJCQkJCQkvLyBJRSBoYXMgb2RkIGFub255bW91cyBmdW5jdGlvbiBmb3IgZXZlbnQgYXR0cmlidXRlcwoJCQkJCQlpZiAobi5pbmRleE9mKCdvbicpID09PSAwICYmIHYpCgkJCQkJCQl2ID0gKCcnICsgdikucmVwbGFjZSgvXmZ1bmN0aW9uXHMrXHcrXChcKVxzK1x7XHMrKC4qKVxzK1x9JC8sICckMScpOwoJCQkJfQoJCQl9CgoJCQlyZXR1cm4gKHYgIT09IHVuZGVmaW5lZCAmJiB2ICE9PSBudWxsICYmIHYgIT09ICcnKSA/ICcnICsgdiA6IGR2OwoJCX0sCgoJCWdldFBvcyA6IGZ1bmN0aW9uKG4sIHJvKSB7CgkJCXZhciB0ID0gdGhpcywgeCA9IDAsIHkgPSAwLCBlLCBkID0gdC5kb2MsIHI7CgoJCQluID0gdC5nZXQobik7CgkJCXJvID0gcm8gfHwgZC5ib2R5OwoKCQkJaWYgKG4pIHsKCQkJCS8vIFVzZSBnZXRCb3VuZGluZ0NsaWVudFJlY3Qgb24gSUUsIE9wZXJhIGhhcyBpdCBidXQgaXQncyBub3QgcGVyZmVjdAoJCQkJaWYgKGlzSUUgJiYgIXQuc3RkTW9kZSkgewoJCQkJCW4gPSBuLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwoJCQkJCWUgPSB0LmJveE1vZGVsID8gZC5kb2N1bWVudEVsZW1lbnQgOiBkLmJvZHk7CgkJCQkJeCA9IHQuZ2V0U3R5bGUodC5zZWxlY3QoJ2h0bWwnKVswXSwgJ2JvcmRlcldpZHRoJyk7IC8vIFJlbW92ZSBib3JkZXIKCQkJCQl4ID0gKHggPT0gJ21lZGl1bScgfHwgdC5ib3hNb2RlbCAmJiAhdC5pc0lFNikgJiYgMiB8fCB4OwoJCQkJCW4udG9wICs9IHQud2luLnNlbGYgIT0gdC53aW4udG9wID8gMiA6IDA7IC8vIElFIGFkZHMgc29tZSBzdHJhbmdlIGV4dHJhIGNvcmQgaWYgdXNlZCBpbiBhIGZyYW1lc2V0CgoJCQkJCXJldHVybiB7eCA6IG4ubGVmdCArIGUuc2Nyb2xsTGVmdCAtIHgsIHkgOiBuLnRvcCArIGUuc2Nyb2xsVG9wIC0geH07CgkJCQl9CgoJCQkJciA9IG47CgkJCQl3aGlsZSAociAmJiByICE9IHJvICYmIHIubm9kZVR5cGUpIHsKCQkJCQl4ICs9IHIub2Zmc2V0TGVmdCB8fCAwOwoJCQkJCXkgKz0gci5vZmZzZXRUb3AgfHwgMDsKCQkJCQlyID0gci5vZmZzZXRQYXJlbnQ7CgkJCQl9CgoJCQkJciA9IG4ucGFyZW50Tm9kZTsKCQkJCXdoaWxlIChyICYmIHIgIT0gcm8gJiYgci5ub2RlVHlwZSkgewoJCQkJCXggLT0gci5zY3JvbGxMZWZ0IHx8IDA7CgkJCQkJeSAtPSByLnNjcm9sbFRvcCB8fCAwOwoJCQkJCXIgPSByLnBhcmVudE5vZGU7CgkJCQl9CgkJCX0KCgkJCXJldHVybiB7eCA6IHgsIHkgOiB5fTsKCQl9LAoKCQlwYXJzZVN0eWxlIDogZnVuY3Rpb24oc3QpIHsKCQkJdmFyIHQgPSB0aGlzLCBzID0gdC5zZXR0aW5ncywgbyA9IHt9OwoKCQkJaWYgKCFzdCkKCQkJCXJldHVybiBvOwoKCQkJZnVuY3Rpb24gY29tcHJlc3MocCwgcywgb3QpIHsKCQkJCXZhciB0LCByLCBiLCBsOwoKCQkJCS8vIEdldCB2YWx1ZXMgYW5kIGNoZWNrIGl0IGl0IG5lZWRzIGNvbXByZXNzaW5nCgkJCQl0ID0gb1twICsgJy10b3AnICsgc107CgkJCQlpZiAoIXQpCgkJCQkJcmV0dXJuOwoKCQkJCXIgPSBvW3AgKyAnLXJpZ2h0JyArIHNdOwoJCQkJaWYgKHQgIT0gcikKCQkJCQlyZXR1cm47CgoJCQkJYiA9IG9bcCArICctYm90dG9tJyArIHNdOwoJCQkJaWYgKHIgIT0gYikKCQkJCQlyZXR1cm47CgoJCQkJbCA9IG9bcCArICctbGVmdCcgKyBzXTsKCQkJCWlmIChiICE9IGwpCgkJCQkJcmV0dXJuOwoKCQkJCS8vIENvbXByZXNzCgkJCQlvW290XSA9IGw7CgkJCQlkZWxldGUgb1twICsgJy10b3AnICsgc107CgkJCQlkZWxldGUgb1twICsgJy1yaWdodCcgKyBzXTsKCQkJCWRlbGV0ZSBvW3AgKyAnLWJvdHRvbScgKyBzXTsKCQkJCWRlbGV0ZSBvW3AgKyAnLWxlZnQnICsgc107CgkJCX07CgoJCQlmdW5jdGlvbiBjb21wcmVzczIodGEsIGEsIGIsIGMpIHsKCQkJCXZhciB0OwoKCQkJCXQgPSBvW2FdOwoJCQkJaWYgKCF0KQoJCQkJCXJldHVybjsKCgkJCQl0ID0gb1tiXTsKCQkJCWlmICghdCkKCQkJCQlyZXR1cm47CgoJCQkJdCA9IG9bY107CgkJCQlpZiAoIXQpCgkJCQkJcmV0dXJuOwoKCQkJCS8vIENvbXByZXNzCgkJCQlvW3RhXSA9IG9bYV0gKyAnICcgKyBvW2JdICsgJyAnICsgb1tjXTsKCQkJCWRlbGV0ZSBvW2FdOwoJCQkJZGVsZXRlIG9bYl07CgkJCQlkZWxldGUgb1tjXTsKCQkJfTsKCgkJCXN0ID0gc3QucmVwbGFjZSgvJigjP1thLXowLTldKyk7L2csICcmJDFfTUNFX1NFTUlfJyk7IC8vIFByb3RlY3QgZW50aXRpZXMKCgkJCWVhY2goc3Quc3BsaXQoJzsnKSwgZnVuY3Rpb24odikgewoJCQkJdmFyIHN2LCB1ciA9IFtdOwoKCQkJCWlmICh2KSB7CgkJCQkJdiA9IHYucmVwbGFjZSgvX01DRV9TRU1JXy9nLCAnOycpOyAvLyBSZXN0b3JlIGVudGl0aWVzCgkJCQkJdiA9IHYucmVwbGFjZSgvdXJsXChbXlwpXStcKS9nLCBmdW5jdGlvbih2KSB7dXIucHVzaCh2KTtyZXR1cm4gJ3VybCgnICsgdXIubGVuZ3RoICsgJyknO30pOwoJCQkJCXYgPSB2LnNwbGl0KCc6Jyk7CgkJCQkJc3YgPSB0aW55bWNlLnRyaW0odlsxXSk7CgkJCQkJc3YgPSBzdi5yZXBsYWNlKC91cmxcKChbXlwpXSspXCkvZywgZnVuY3Rpb24oYSwgYikge3JldHVybiB1cltwYXJzZUludChiKSAtIDFdO30pOwoKCQkJCQlzdiA9IHN2LnJlcGxhY2UoL3JnYlwoW15cKV0rXCkvZywgZnVuY3Rpb24odikgewoJCQkJCQlyZXR1cm4gdC50b0hleCh2KTsKCQkJCQl9KTsKCgkJCQkJaWYgKHMudXJsX2NvbnZlcnRlcikgewoJCQkJCQlzdiA9IHN2LnJlcGxhY2UoL3VybFwoW1wnXCJdPyhbXlwpXCdcIl0rKVtcJ1wiXT9cKS9nLCBmdW5jdGlvbih4LCBjKSB7CgkJCQkJCQlyZXR1cm4gJ3VybCgnICsgcy51cmxfY29udmVydGVyLmNhbGwocy51cmxfY29udmVydGVyX3Njb3BlIHx8IHQsIHQuZGVjb2RlKGMpLCAnc3R5bGUnLCBudWxsKSArICcpJzsKCQkJCQkJfSk7CgkJCQkJfQoKCQkJCQlvW3RpbnltY2UudHJpbSh2WzBdKS50b0xvd2VyQ2FzZSgpXSA9IHN2OwoJCQkJfQoJCQl9KTsKCgkJCWNvbXByZXNzKCJib3JkZXIiLCAiIiwgImJvcmRlciIpOwoJCQljb21wcmVzcygiYm9yZGVyIiwgIi13aWR0aCIsICJib3JkZXItd2lkdGgiKTsKCQkJY29tcHJlc3MoImJvcmRlciIsICItY29sb3IiLCAiYm9yZGVyLWNvbG9yIik7CgkJCWNvbXByZXNzKCJib3JkZXIiLCAiLXN0eWxlIiwgImJvcmRlci1zdHlsZSIpOwoJCQljb21wcmVzcygicGFkZGluZyIsICIiLCAicGFkZGluZyIpOwoJCQljb21wcmVzcygibWFyZ2luIiwgIiIsICJtYXJnaW4iKTsKCQkJY29tcHJlc3MyKCdib3JkZXInLCAnYm9yZGVyLXdpZHRoJywgJ2JvcmRlci1zdHlsZScsICdib3JkZXItY29sb3InKTsKCgkJCWlmIChpc0lFKSB7CgkJCQkvLyBSZW1vdmUgcG9pbnRsZXNzIGJvcmRlcgoJCQkJaWYgKG8uYm9yZGVyID09ICdtZWRpdW0gbm9uZScpCgkJCQkJby5ib3JkZXIgPSAnJzsKCQkJfQoKCQkJcmV0dXJuIG87CgkJfSwKCgkJc2VyaWFsaXplU3R5bGUgOiBmdW5jdGlvbihvKSB7CgkJCXZhciBzID0gJyc7CgoJCQllYWNoKG8sIGZ1bmN0aW9uKHYsIGspIHsKCQkJCWlmIChrICYmIHYpIHsKCQkJCQlpZiAodGlueW1jZS5pc0dlY2tvICYmIGsuaW5kZXhPZignLW1vei0nKSA9PT0gMCkKCQkJCQkJcmV0dXJuOwoKCQkJCQlzd2l0Y2ggKGspIHsKCQkJCQkJY2FzZSAnY29sb3InOgoJCQkJCQljYXNlICdiYWNrZ3JvdW5kLWNvbG9yJzoKCQkJCQkJCXYgPSB2LnRvTG93ZXJDYXNlKCk7CgkJCQkJCQlicmVhazsKCQkJCQl9CgoJCQkJCXMgKz0gKHMgPyAnICcgOiAnJykgKyBrICsgJzogJyArIHYgKyAnOyc7CgkJCQl9CgkJCX0pOwoKCQkJcmV0dXJuIHM7CgkJfSwKCgkJbG9hZENTUyA6IGZ1bmN0aW9uKHUpIHsKCQkJdmFyIHQgPSB0aGlzLCBkID0gdC5kb2MsIGhlYWQ7CgoJCQlpZiAoIXUpCgkJCQl1ID0gJyc7CgoJCQloZWFkID0gdC5zZWxlY3QoJ2hlYWQnKVswXTsKCgkJCWVhY2godS5zcGxpdCgnLCcpLCBmdW5jdGlvbih1KSB7CgkJCQl2YXIgbGluazsKCgkJCQlpZiAodC5maWxlc1t1XSkKCQkJCQlyZXR1cm47CgoJCQkJdC5maWxlc1t1XSA9IHRydWU7CgkJCQlsaW5rID0gdC5jcmVhdGUoJ2xpbmsnLCB7cmVsIDogJ3N0eWxlc2hlZXQnLCBocmVmIDogdGlueW1jZS5fYWRkVmVyKHUpfSk7CgoJCQkJLy8gSUUgOCBoYXMgYSBidWcgd2hlcmUgZHluYW1pY2FsbHkgbG9hZGluZyBzdHlsZXNoZWV0cyB3b3VsZCBwcm9kdWNlIGEgMSBpdGVtIHJlbWFpbmluZyBidWcKCQkJCS8vIFRoaXMgZml4IHNlZW1zIHRvIHJlc29sdmUgdGhhdCBpc3N1ZSBieSByZWFsY2luZyB0aGUgZG9jdW1lbnQgb25lcyBhIHN0eWxlc2hlZXQgZmluaXNoZXMgbG9hZGluZwoJCQkJLy8gSXQncyB1Z2x5IGJ1dCBpdCBzZWVtcyB0byB3b3JrIGZpbmUuCgkJCQlpZiAoaXNJRSAmJiBkLmRvY3VtZW50TW9kZSkgewoJCQkJCWxpbmsub25sb2FkID0gZnVuY3Rpb24oKSB7CgkJCQkJCWQucmVjYWxjKCk7CgkJCQkJCWxpbmsub25sb2FkID0gbnVsbDsKCQkJCQl9OwoJCQkJfQoKCQkJCWhlYWQuYXBwZW5kQ2hpbGQobGluayk7CgkJCX0pOwoJCX0sCgoJCWFkZENsYXNzIDogZnVuY3Rpb24oZSwgYykgewoJCQlyZXR1cm4gdGhpcy5ydW4oZSwgZnVuY3Rpb24oZSkgewoJCQkJdmFyIG87CgoJCQkJaWYgKCFjKQoJCQkJCXJldHVybiAwOwoKCQkJCWlmICh0aGlzLmhhc0NsYXNzKGUsIGMpKQoJCQkJCXJldHVybiBlLmNsYXNzTmFtZTsKCgkJCQlvID0gdGhpcy5yZW1vdmVDbGFzcyhlLCBjKTsKCgkJCQlyZXR1cm4gZS5jbGFzc05hbWUgPSAobyAhPSAnJyA/IChvICsgJyAnKSA6ICcnKSArIGM7CgkJCX0pOwoJCX0sCgoJCXJlbW92ZUNsYXNzIDogZnVuY3Rpb24oZSwgYykgewoJCQl2YXIgdCA9IHRoaXMsIHJlOwoKCQkJcmV0dXJuIHQucnVuKGUsIGZ1bmN0aW9uKGUpIHsKCQkJCXZhciB2OwoKCQkJCWlmICh0Lmhhc0NsYXNzKGUsIGMpKSB7CgkJCQkJaWYgKCFyZSkKCQkJCQkJcmUgPSBuZXcgUmVnRXhwKCIoXnxcXHMrKSIgKyBjICsgIihcXHMrfCQpIiwgImciKTsKCgkJCQkJdiA9IGUuY2xhc3NOYW1lLnJlcGxhY2UocmUsICcgJyk7CgoJCQkJCXJldHVybiBlLmNsYXNzTmFtZSA9IHRpbnltY2UudHJpbSh2ICE9ICcgJyA/IHYgOiAnJyk7CgkJCQl9CgoJCQkJcmV0dXJuIGUuY2xhc3NOYW1lOwoJCQl9KTsKCQl9LAoKCQloYXNDbGFzcyA6IGZ1bmN0aW9uKG4sIGMpIHsKCQkJbiA9IHRoaXMuZ2V0KG4pOwoKCQkJaWYgKCFuIHx8ICFjKQoJCQkJcmV0dXJuIGZhbHNlOwoKCQkJcmV0dXJuICgnICcgKyBuLmNsYXNzTmFtZSArICcgJykuaW5kZXhPZignICcgKyBjICsgJyAnKSAhPT0gLTE7CgkJfSwKCgkJc2hvdyA6IGZ1bmN0aW9uKGUpIHsKCQkJcmV0dXJuIHRoaXMuc2V0U3R5bGUoZSwgJ2Rpc3BsYXknLCAnYmxvY2snKTsKCQl9LAoKCQloaWRlIDogZnVuY3Rpb24oZSkgewoJCQlyZXR1cm4gdGhpcy5zZXRTdHlsZShlLCAnZGlzcGxheScsICdub25lJyk7CgkJfSwKCgkJaXNIaWRkZW4gOiBmdW5jdGlvbihlKSB7CgkJCWUgPSB0aGlzLmdldChlKTsKCgkJCXJldHVybiAhZSB8fCBlLnN0eWxlLmRpc3BsYXkgPT0gJ25vbmUnIHx8IHRoaXMuZ2V0U3R5bGUoZSwgJ2Rpc3BsYXknKSA9PSAnbm9uZSc7CgkJfSwKCgkJdW5pcXVlSWQgOiBmdW5jdGlvbihwKSB7CgkJCXJldHVybiAoIXAgPyAnbWNlXycgOiBwKSArICh0aGlzLmNvdW50ZXIrKyk7CgkJfSwKCgkJc2V0SFRNTCA6IGZ1bmN0aW9uKGUsIGgpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJcmV0dXJuIHRoaXMucnVuKGUsIGZ1bmN0aW9uKGUpIHsKCQkJCXZhciB4LCBpLCBubCwgbiwgcCwgeDsKCgkJCQloID0gdC5wcm9jZXNzSFRNTChoKTsKCgkJCQlpZiAoaXNJRSkgewoJCQkJCWZ1bmN0aW9uIHNldCgpIHsKCQkJCQkJdHJ5IHsKCQkJCQkJCS8vIElFIHdpbGwgcmVtb3ZlIGNvbW1lbnRzIGZyb20gdGhlIGJlZ2lubmluZwoJCQkJCQkJLy8gdW5sZXNzIHlvdSBwYWRkIHRoZSBjb250ZW50cyB3aXRoIHNvbWV0aGluZwoJCQkJCQkJZS5pbm5lckhUTUwgPSAnPGJyIC8+JyArIGg7CgkJCQkJCQllLnJlbW92ZUNoaWxkKGUuZmlyc3RDaGlsZCk7CgkJCQkJCX0gY2F0Y2ggKGV4KSB7CgkJCQkJCQkvLyBJRSBzb21ldGltZXMgcHJvZHVjZXMgYW4gdW5rbm93biBydW50aW1lIGVycm9yIG9uIGlubmVySFRNTCBpZiBpdCdzIGFuIGJsb2NrIGVsZW1lbnQgd2l0aGluIGEgYmxvY2sgZWxlbWVudCBmb3IgZXhhbXBsZSBhIGRpdiBpbnNpZGUgYSBwCgkJCQkJCQkvLyBUaGlzIHNlZW1zIHRvIGZpeCB0aGlzIHByb2JsZW0KCgkJCQkJCQkvLyBSZW1vdmUgYWxsIGNoaWxkIG5vZGVzCgkJCQkJCQl3aGlsZSAoZS5maXJzdENoaWxkKQoJCQkJCQkJCWUuZmlyc3RDaGlsZC5yZW1vdmVOb2RlKCk7CgoJCQkJCQkJLy8gQ3JlYXRlIG5ldyBkaXYgd2l0aCBIVE1MIGNvbnRlbnRzIGFuZCBhIEJSIGluZnJvbnQgdG8ga2VlcCBjb21tZW50cwoJCQkJCQkJeCA9IHQuY3JlYXRlKCdkaXYnKTsKCQkJCQkJCXguaW5uZXJIVE1MID0gJzxiciAvPicgKyBoOwoKCQkJCQkJCS8vIEFkZCBhbGwgY2hpbGRyZW4gZnJvbSBkaXYgdG8gdGFyZ2V0CgkJCQkJCQllYWNoICh4LmNoaWxkTm9kZXMsIGZ1bmN0aW9uKG4sIGkpIHsKCQkJCQkJCQkvLyBTa2lwIGJyIGVsZW1lbnQKCQkJCQkJCQlpZiAoaSkKCQkJCQkJCQkJZS5hcHBlbmRDaGlsZChuKTsKCQkJCQkJCX0pOwoJCQkJCQl9CgkJCQkJfTsKCgkJCQkJLy8gSUUgaGFzIGEgc2VyaW91cyBidWcgd2hlbiBpdCBjb21lcyB0byBwYXJhZ3JhcGhzIGl0IGNhbiBwcm9kdWNlIGFuIGludmFsaWQKCQkJCQkvLyBET00gdHJlZSBpZiBjb250ZW50cyBsaWtlIHRoaXMgPHA+PHVsPjxsaT5JdGVtIDE8L2xpPjwvdWw+PC9wPiBpcyBpbnNlcnRlZAoJCQkJCS8vIEl0IHNlZW1zIHRvIGJlIHRoYXQgSUUgZG9lc24ndCBsaWtlIGEgcm9vdCBibG9jayBlbGVtZW50IHBsYWNlZCBpbnNpZGUgYW5vdGhlciByb290IGJsb2NrIGVsZW1lbnQKCQkJCQlpZiAodC5zZXR0aW5ncy5maXhfaWVfcGFyYWdyYXBocykKCQkJCQkJaCA9IGgucmVwbGFjZSgvPHA+PFwvcD58PHAoW14+XSspPjxcL3A+fDxwW15cLytdXC8+L2dpLCAnPHAkMSBtY2Vfa2VlcD0idHJ1ZSI+Jm5ic3A7PC9wPicpOwoKCQkJCQlzZXQoKTsKCgkJCQkJaWYgKHQuc2V0dGluZ3MuZml4X2llX3BhcmFncmFwaHMpIHsKCQkJCQkJLy8gQ2hlY2sgZm9yIG9kZCBwYXJhZ3JhcGhzIHRoaXMgaXMgYSBzaWduIG9mIGEgYnJva2VuIERPTQoJCQkJCQlubCA9IGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKCQkJCQkJZm9yIChpID0gbmwubGVuZ3RoIC0gMSwgeCA9IDA7IGkgPj0gMDsgaS0tKSB7CgkJCQkJCQluID0gbmxbaV07CgoJCQkJCQkJaWYgKCFuLmhhc0NoaWxkTm9kZXMoKSkgewoJCQkJCQkJCWlmICghbi5tY2Vfa2VlcCkgewoJCQkJCQkJCQl4ID0gMTsgLy8gSXMgYnJva2VuCgkJCQkJCQkJCWJyZWFrOwoJCQkJCQkJCX0KCgkJCQkJCQkJbi5yZW1vdmVBdHRyaWJ1dGUoJ21jZV9rZWVwJyk7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgoJCQkJCS8vIFRpbWUgdG8gZml4IHRoZSBtYWRuZXNzIElFIGxlZnQgdXMKCQkJCQlpZiAoeCkgewoJCQkJCQkvLyBTbyBpZiB3ZSByZXBsYWNlIHRoZSBwIGVsZW1lbnRzIHdpdGggZGl2cyBhbmQgbWFyayB0aGVtIGFuZCB0aGVuIHJlcGxhY2UgdGhlbSBiYWNrIHRvIHBhcmFncmFwaHMKCQkJCQkJLy8gYWZ0ZXIgd2UgdXNlIGlubmVySFRNTCB3ZSBjYW4gZml4IHRoZSBET00gdHJlZQoJCQkJCQloID0gaC5yZXBsYWNlKC88cCAoW14+XSspPnw8cD4vZywgJzxkaXYgJDEgbWNlX3RtcD0iMSI+Jyk7CgkJCQkJCWggPSBoLnJlcGxhY2UoLzxcL3A+L2csICc8L2Rpdj4nKTsKCgkJCQkJCS8vIFNldCB0aGUgbmV3IEhUTUwgd2l0aCBESVZzCgkJCQkJCXNldCgpOwoKCQkJCQkJLy8gUmVwbGFjZSBhbGwgRElWIGVsZW1lbnRzIHdpdGggaGUgbWNlX3RtcCBhdHRpYnV0ZSBiYWNrIHRvIHBhcmFncmFwaHMKCQkJCQkJLy8gVGhpcyBpcyBuZWVkZWQgc2luY2UgSUUgaGFzIGEgYW5ub3lpbmcgYnVnIHNlZSBhYm92ZSBmb3IgZGV0YWlscwoJCQkJCQkvLyBUaGlzIGlzIGEgc2xvdyBwcm9jZXNzIGJ1dCBpdCBoYXMgdG8gYmUgZG9uZS4gOigKCQkJCQkJaWYgKHQuc2V0dGluZ3MuZml4X2llX3BhcmFncmFwaHMpIHsKCQkJCQkJCW5sID0gZS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiRElWIik7CgkJCQkJCQlmb3IgKGkgPSBubC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgewoJCQkJCQkJCW4gPSBubFtpXTsKCgkJCQkJCQkJLy8gSXMgaXQgYSB0ZW1wIGRpdgoJCQkJCQkJCWlmIChuLm1jZV90bXApIHsKCQkJCQkJCQkJLy8gQ3JlYXRlIG5ldyBwYXJhZ3JhcGgKCQkJCQkJCQkJcCA9IHQuZG9jLmNyZWF0ZUVsZW1lbnQoJ3AnKTsKCgkJCQkJCQkJCS8vIENvcHkgYWxsIGF0dHJpYnV0ZXMKCQkJCQkJCQkJbi5jbG9uZU5vZGUoZmFsc2UpLm91dGVySFRNTC5yZXBsYWNlKC8oW2EtejAtOVwtX10rKT0vZ2ksIGZ1bmN0aW9uKGEsIGIpIHsKCQkJCQkJCQkJCXZhciB2OwoKCQkJCQkJCQkJCWlmIChiICE9PSAnbWNlX3RtcCcpIHsKCQkJCQkJCQkJCQl2ID0gbi5nZXRBdHRyaWJ1dGUoYik7CgoJCQkJCQkJCQkJCWlmICghdiAmJiBiID09PSAnY2xhc3MnKQoJCQkJCQkJCQkJCQl2ID0gbi5jbGFzc05hbWU7CgoJCQkJCQkJCQkJCXAuc2V0QXR0cmlidXRlKGIsIHYpOwoJCQkJCQkJCQkJfQoJCQkJCQkJCQl9KTsKCgkJCQkJCQkJCS8vIEFwcGVuZCBhbGwgY2hpbGRyZW4gdG8gbmV3IHBhcmFncmFwaAoJCQkJCQkJCQlmb3IgKHggPSAwOyB4PG4uY2hpbGROb2Rlcy5sZW5ndGg7IHgrKykKCQkJCQkJCQkJCXAuYXBwZW5kQ2hpbGQobi5jaGlsZE5vZGVzW3hdLmNsb25lTm9kZSh0cnVlKSk7CgoJCQkJCQkJCQkvLyBSZXBsYWNlIGRpdiB3aXRoIG5ldyBwYXJhZ3JhcGgKCQkJCQkJCQkJbi5zd2FwTm9kZShwKTsKCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9IGVsc2UKCQkJCQllLmlubmVySFRNTCA9IGg7CgoJCQkJcmV0dXJuIGg7CgkJCX0pOwoJCX0sCgoJCXByb2Nlc3NIVE1MIDogZnVuY3Rpb24oaCkgewoJCQl2YXIgdCA9IHRoaXMsIHMgPSB0LnNldHRpbmdzOwoKCQkJaWYgKCFzLnByb2Nlc3NfaHRtbCkKCQkJCXJldHVybiBoOwoKCQkJLy8gQ29udmVydCBzdHJvbmcgYW5kIGVtIHRvIGIgYW5kIGkgaW4gRkYgc2luY2UgaXQgY2FuJ3QgaGFuZGxlIHRoZW0KCQkJaWYgKHRpbnltY2UuaXNHZWNrbykgewoJCQkJaCA9IGgucmVwbGFjZSgvPChcLz8pc3Ryb25nPnw8c3Ryb25nKCBbXj5dKyk+L2dpLCAnPCQxYiQyPicpOwoJCQkJaCA9IGgucmVwbGFjZSgvPChcLz8pZW0+fDxlbSggW14+XSspPi9naSwgJzwkMWkkMj4nKTsKCQkJfSBlbHNlIGlmIChpc0lFKSB7CgkJCQloID0gaC5yZXBsYWNlKC8mYXBvczsvZywgJyYjMzk7Jyk7IC8vIElFIGNhbid0IGhhbmRsZSBhcG9zCgkJCQloID0gaC5yZXBsYWNlKC9ccysoZGlzYWJsZWR8Y2hlY2tlZHxyZWFkb25seXxzZWxlY3RlZClccyo9XHMqW1wiXCddPyhmYWxzZXwwKVtcIlwnXT8vZ2ksICcnKTsgLy8gSUUgZG9lc24ndCBoYW5kbGUgZGVmYXVsdCB2YWx1ZXMgY29ycmVjdAoJCQl9CgoJCQkvLyBGaXggc29tZSBpc3N1ZXMKCQkJaCA9IGgucmVwbGFjZSgvPGEoICkoW14+XSspXC8+fDxhXC8+L2dpLCAnPGEkMSQyPjwvYT4nKTsgLy8gRm9yY2Ugb3BlbgoKCQkJLy8gU3RvcmUgYXdheSBzcmMgYW5kIGhyZWYgaW4gbWNlX3NyYyBhbmQgbWNlX2hyZWYgc2luY2UgYnJvd3NlcnMgbWVzcyB0aGVtIHVwCgkJCWlmIChzLmtlZXBfdmFsdWVzKSB7CgkJCQkvLyBXcmFwIHNjcmlwdHMgYW5kIHN0eWxlcyBpbiBjb21tZW50cyBmb3Igc2VyaWFsaXphdGlvbiBwdXJwb3NlcwoJCQkJaWYgKC88c2NyaXB0fG5vc2NyaXB0fHN0eWxlLy50ZXN0KGgpKSB7CgkJCQkJZnVuY3Rpb24gdHJpbShzKSB7CgkJCQkJCS8vIFJlbW92ZSBwcmVmaXggYW5kIHN1ZmZpeCBjb2RlIGZvciBlbGVtZW50CgkJCQkJCXMgPSBzLnJlcGxhY2UoLyg8IS0tXFtDREFUQVxbfFxdXF0tLT4pL2csICdcbicpOwoJCQkJCQlzID0gcy5yZXBsYWNlKC9eW1xyXG5dKnxbXHJcbl0qJC9nLCAnJyk7CgkJCQkJCXMgPSBzLnJlcGxhY2UoL15ccyooXC9cL1xzKjwhLS18XC9cL1xzKjwhXFtDREFUQVxbfDwhLS18PCFcW0NEQVRBXFspW1xyXG5dKi9nLCAnJyk7CgkJCQkJCXMgPSBzLnJlcGxhY2UoL1xzKihcL1wvXHMqXF1cXT58XC9cL1xzKi0tPnxcXVxdPnwtLT58XF1cXS0tPilccyokL2csICcnKTsKCgkJCQkJCXJldHVybiBzOwoJCQkJCX07CgoJCQkJCS8vIFdyYXAgdGhlIHNjcmlwdCBjb250ZW50cyBpbiBDREFUQSBhbmQga2VlcCB0aGVtIGZyb20gZXhlY3V0aW5nCgkJCQkJaCA9IGgucmVwbGFjZSgvPHNjcmlwdChbXj5dK3wpPihbXHNcU10qPyk8XC9zY3JpcHQ+L2csIGZ1bmN0aW9uKHYsIGF0dHJpYnMsIHRleHQpIHsKCQkJCQkJLy8gRm9yY2UgdHlwZSBhdHRyaWJ1dGUKCQkJCQkJaWYgKCFhdHRyaWJzKQoJCQkJCQkJYXR0cmlicyA9ICcgdHlwZT0idGV4dC9qYXZhc2NyaXB0Iic7CgoJCQkJCQkvLyBQcmVmaXggc2NyaXB0IHR5cGUvbGFuZ3VhZ2UgYXR0cmlidXRlIHZhbHVlcyB3aXRoIG1jZS0gdG8gcHJldmVudCBpdCBmcm9tIGV4ZWN1dGluZwoJCQkJCQlhdHRyaWJzID0gYXR0cmlicy5yZXBsYWNlKC8odHlwZXxsYW5ndWFnZSk9XCI/LywgJyQmbWNlLScpOwoJCQkJCQlhdHRyaWJzID0gYXR0cmlicy5yZXBsYWNlKC9zcmM9XCIoW15cIl0rKVwiPy8sIGZ1bmN0aW9uKGEsIHVybCkgewoJCQkJCQkJaWYgKHMudXJsX2NvbnZlcnRlcikKCQkJCQkJCQl1cmwgPSB0LmVuY29kZShzLnVybF9jb252ZXJ0ZXIuY2FsbChzLnVybF9jb252ZXJ0ZXJfc2NvcGUgfHwgdCwgdC5kZWNvZGUodXJsKSwgJ3NyYycsICdzY3JpcHQnKSk7CgoJCQkJCQkJcmV0dXJuICdtY2Vfc3JjPSInICsgdXJsICsgJyInOwoJCQkJCQl9KTsKCgkJCQkJCS8vIFdyYXAgdGV4dCBjb250ZW50cwoJCQkJCQlpZiAodGlueW1jZS50cmltKHRleHQpKQoJCQkJCQkJdGV4dCA9ICc8IS0tXG4nICsgdHJpbSh0ZXh0KSArICdcbi8vIC0tPic7CgoJCQkJCQlyZXR1cm4gJzxtY2U6c2NyaXB0JyArIGF0dHJpYnMgKyAnPicgKyB0ZXh0ICsgJzwvbWNlOnNjcmlwdD4nOwoJCQkJCX0pOwoKCQkJCQkvLyBXcmFwIHN0eWxlIGVsZW1lbnRzCgkJCQkJaCA9IGgucmVwbGFjZSgvPHN0eWxlKFtePl0rfCk+KFtcc1xTXSo/KTxcL3N0eWxlPi9nLCBmdW5jdGlvbih2LCBhdHRyaWJzLCB0ZXh0KSB7CgkJCQkJCS8vIFdyYXAgdGV4dCBjb250ZW50cwoJCQkJCQlpZiAodGV4dCkKCQkJCQkJCXRleHQgPSAnPCEtLVxuJyArIHRyaW0odGV4dCkgKyAnXG4tLT4nOwoKCQkJCQkJcmV0dXJuICc8bWNlOnN0eWxlJyArIGF0dHJpYnMgKyAnPicgKyB0ZXh0ICsgJzwvbWNlOnN0eWxlPjxzdHlsZSAnICsgYXR0cmlicyArICcgbWNlX2JvZ3VzPSIxIj4nICsgdGV4dCArICc8L3N0eWxlPic7CgkJCQkJfSk7CgoJCQkJCS8vIFdyYXAgbm9zY3JpcHQgZWxlbWVudHMKCQkJCQloID0gaC5yZXBsYWNlKC88bm9zY3JpcHQoW14+XSt8KT4oW1xzXFNdKj8pPFwvbm9zY3JpcHQ+L2csIGZ1bmN0aW9uKHYsIGF0dHJpYnMsIHRleHQpIHsKCQkJCQkJcmV0dXJuICc8bWNlOm5vc2NyaXB0JyArIGF0dHJpYnMgKyAnPjwhLS0nICsgdC5lbmNvZGUodGV4dCkucmVwbGFjZSgvLS0vZywgJyYjNDU7JiM0NTsnKSArICctLT48L21jZTpub3NjcmlwdD4nOwoJCQkJCX0pOwoJCQkJfQoKCQkJCWggPSBoLnJlcGxhY2UoLzwhXFtDREFUQVxbKFtcc1xTXSspXF1cXT4vZywgJzwhLS1bQ0RBVEFbJDFdXS0tPicpOwoKCQkJCS8vIFByb2Nlc3MgYWxsIHRhZ3Mgd2l0aCBzcmMsIGhyZWYgb3Igc3R5bGUKCQkJCWggPSBoLnJlcGxhY2UoLzwoW1x3Ol0rKSBbXj5dKihzcmN8aHJlZnxzdHlsZXxzaGFwZXxjb29yZHMpW14+XSo+L2dpLCBmdW5jdGlvbihhLCBuKSB7CgkJCQkJZnVuY3Rpb24gaGFuZGxlKG0sIGIsIGMpIHsKCQkJCQkJdmFyIHUgPSBjOwoKCQkJCQkJLy8gVGFnIGFscmVhZHkgZ290IGEgbWNlXyB2ZXJzaW9uCgkJCQkJCWlmIChhLmluZGV4T2YoJ21jZV8nICsgYikgIT0gLTEpCgkJCQkJCQlyZXR1cm4gbTsKCgkJCQkJCWlmIChiID09ICdzdHlsZScpIHsKCQkJCQkJCS8vIE5vIG1jZV9zdHlsZSBmb3IgZWxlbWVudHMgd2l0aCB0aGVzZSBzaW5jZSB0aGV5IG1pZ2h0IGdldCByZXNpemVkIGJ5IHRoZSB1c2VyCgkJCQkJCQlpZiAodC5faXNSZXMoYykpCgkJCQkJCQkJcmV0dXJuIG07CgoJCQkJCQkJaWYgKHMuaGV4X2NvbG9ycykgewoJCQkJCQkJCXUgPSB1LnJlcGxhY2UoL3JnYlwoW15cKV0rXCkvZywgZnVuY3Rpb24odikgewoJCQkJCQkJCQlyZXR1cm4gdC50b0hleCh2KTsKCQkJCQkJCQl9KTsKCQkJCQkJCX0KCgkJCQkJCQlpZiAocy51cmxfY29udmVydGVyKSB7CgkJCQkJCQkJdSA9IHUucmVwbGFjZSgvdXJsXChbXCdcIl0/KFteXClcJ1wiXSspXCkvZywgZnVuY3Rpb24oeCwgYykgewoJCQkJCQkJCQlyZXR1cm4gJ3VybCgnICsgdC5lbmNvZGUocy51cmxfY29udmVydGVyLmNhbGwocy51cmxfY29udmVydGVyX3Njb3BlIHx8IHQsIHQuZGVjb2RlKGMpLCBiLCBuKSkgKyAnKSc7CgkJCQkJCQkJfSk7CgkJCQkJCQl9CgkJCQkJCX0gZWxzZSBpZiAoYiAhPSAnY29vcmRzJyAmJiBiICE9ICdzaGFwZScpIHsKCQkJCQkJCWlmIChzLnVybF9jb252ZXJ0ZXIpCgkJCQkJCQkJdSA9IHQuZW5jb2RlKHMudXJsX2NvbnZlcnRlci5jYWxsKHMudXJsX2NvbnZlcnRlcl9zY29wZSB8fCB0LCB0LmRlY29kZShjKSwgYiwgbikpOwoJCQkJCQl9CgoJCQkJCQlyZXR1cm4gJyAnICsgYiArICc9IicgKyBjICsgJyIgbWNlXycgKyBiICsgJz0iJyArIHUgKyAnIic7CgkJCQkJfTsKCgkJCQkJYSA9IGEucmVwbGFjZSgvIChzcmN8aHJlZnxzdHlsZXxjb29yZHN8c2hhcGUpPVtcIl0oW15cIl0rKVtcIl0vZ2ksIGhhbmRsZSk7IC8vIFczQwoJCQkJCWEgPSBhLnJlcGxhY2UoLyAoc3JjfGhyZWZ8c3R5bGV8Y29vcmRzfHNoYXBlKT1bXCddKFteXCddKylbXCddL2dpLCBoYW5kbGUpOyAvLyBXM0MKCgkJCQkJcmV0dXJuIGEucmVwbGFjZSgvIChzcmN8aHJlZnxzdHlsZXxjb29yZHN8c2hhcGUpPShbXlxzXCJcJz5dKykvZ2ksIGhhbmRsZSk7IC8vIElFCgkJCQl9KTsKCQkJfQoKCQkJcmV0dXJuIGg7CgkJfSwKCgkJZ2V0T3V0ZXJIVE1MIDogZnVuY3Rpb24oZSkgewoJCQl2YXIgZDsKCgkJCWUgPSB0aGlzLmdldChlKTsKCgkJCWlmICghZSkKCQkJCXJldHVybiBudWxsOwoKCQkJaWYgKGUub3V0ZXJIVE1MICE9PSB1bmRlZmluZWQpCgkJCQlyZXR1cm4gZS5vdXRlckhUTUw7CgoJCQlkID0gKGUub3duZXJEb2N1bWVudCB8fCB0aGlzLmRvYykuY3JlYXRlRWxlbWVudCgiYm9keSIpOwoJCQlkLmFwcGVuZENoaWxkKGUuY2xvbmVOb2RlKHRydWUpKTsKCgkJCXJldHVybiBkLmlubmVySFRNTDsKCQl9LAoKCQlzZXRPdXRlckhUTUwgOiBmdW5jdGlvbihlLCBoLCBkKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXJldHVybiB0aGlzLnJ1bihlLCBmdW5jdGlvbihlKSB7CgkJCQl2YXIgbiwgdHA7CgoJCQkJZSA9IHQuZ2V0KGUpOwoJCQkJZCA9IGQgfHwgZS5vd25lckRvY3VtZW50IHx8IHQuZG9jOwoKCQkJCWlmIChpc0lFICYmIGUubm9kZVR5cGUgPT0gMSkKCQkJCQllLm91dGVySFRNTCA9IGg7CgkJCQllbHNlIHsKCQkJCQl0cCA9IGQuY3JlYXRlRWxlbWVudCgiYm9keSIpOwoJCQkJCXRwLmlubmVySFRNTCA9IGg7CgoJCQkJCW4gPSB0cC5sYXN0Q2hpbGQ7CgkJCQkJd2hpbGUgKG4pIHsKCQkJCQkJdC5pbnNlcnRBZnRlcihuLmNsb25lTm9kZSh0cnVlKSwgZSk7CgkJCQkJCW4gPSBuLnByZXZpb3VzU2libGluZzsKCQkJCQl9CgoJCQkJCXQucmVtb3ZlKGUpOwoJCQkJfQoJCQl9KTsKCQl9LAoKCQlkZWNvZGUgOiBmdW5jdGlvbihzKSB7CgkJCXZhciBlLCBuLCB2OwoKCQkJLy8gTG9vayBmb3IgZW50aXRpZXMgdG8gZGVjb2RlCgkJCWlmICgvJlteO10rOy8udGVzdChzKSkgewoJCQkJLy8gRGVjb2RlIHRoZSBlbnRpdGllcyB1c2luZyBhIGRpdiBlbGVtZW50IG5vdCBzdXBlciBlZmZpY2llbnQgYnV0IGxlc3MgY29kZQoJCQkJZSA9IHRoaXMuZG9jLmNyZWF0ZUVsZW1lbnQoImRpdiIpOwoJCQkJZS5pbm5lckhUTUwgPSBzOwoJCQkJbiA9IGUuZmlyc3RDaGlsZDsKCQkJCXYgPSAnJzsKCgkJCQlpZiAobikgewoJCQkJCWRvIHsKCQkJCQkJdiArPSBuLm5vZGVWYWx1ZTsKCQkJCQl9IHdoaWxlIChuLm5leHRTaWJsaW5nKTsKCQkJCX0KCgkJCQlyZXR1cm4gdiB8fCBzOwoJCQl9CgoJCQlyZXR1cm4gczsKCQl9LAoKCQllbmNvZGUgOiBmdW5jdGlvbihzKSB7CgkJCXJldHVybiBzID8gKCcnICsgcykucmVwbGFjZSgvWzw+JlwiXS9nLCBmdW5jdGlvbiAoYywgYikgewoJCQkJc3dpdGNoIChjKSB7CgkJCQkJY2FzZSAnJic6CgkJCQkJCXJldHVybiAnJmFtcDsnOwoKCQkJCQljYXNlICciJzoKCQkJCQkJcmV0dXJuICcmcXVvdDsnOwoKCQkJCQljYXNlICc8JzoKCQkJCQkJcmV0dXJuICcmbHQ7JzsKCgkJCQkJY2FzZSAnPic6CgkJCQkJCXJldHVybiAnJmd0Oyc7CgkJCQl9CgoJCQkJcmV0dXJuIGM7CgkJCX0pIDogczsKCQl9LAoKCQlpbnNlcnRBZnRlciA6IGZ1bmN0aW9uKG4sIHIpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJciA9IHQuZ2V0KHIpOwoKCQkJcmV0dXJuIHRoaXMucnVuKG4sIGZ1bmN0aW9uKG4pIHsKCQkJCXZhciBwLCBuczsKCgkJCQlwID0gci5wYXJlbnROb2RlOwoJCQkJbnMgPSByLm5leHRTaWJsaW5nOwoKCQkJCWlmIChucykKCQkJCQlwLmluc2VydEJlZm9yZShuLCBucyk7CgkJCQllbHNlCgkJCQkJcC5hcHBlbmRDaGlsZChuKTsKCgkJCQlyZXR1cm4gbjsKCQkJfSk7CgkJfSwKCgkJaXNCbG9jayA6IGZ1bmN0aW9uKG4pIHsKCQkJaWYgKG4ubm9kZVR5cGUgJiYgbi5ub2RlVHlwZSAhPT0gMSkKCQkJCXJldHVybiBmYWxzZTsKCgkJCW4gPSBuLm5vZGVOYW1lIHx8IG47CgoJCQlyZXR1cm4gL14oSFsxLTZdfEhSfFB8RElWfEFERFJFU1N8UFJFfEZPUk18VEFCTEV8TEl8T0x8VUx8VFJ8VER8Q0FQVElPTnxCTE9DS1FVT1RFfENFTlRFUnxETHxEVHxERHxESVJ8RklFTERTRVR8Tk9TQ1JJUFR8Tk9GUkFNRVN8TUVOVXxJU0lOREVYfFNBTVApJC8udGVzdChuKTsKCQl9LAoKCQlyZXBsYWNlIDogZnVuY3Rpb24obiwgbywgaykgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQlpZiAoaXMobywgJ2FycmF5JykpCgkJCQluID0gbi5jbG9uZU5vZGUodHJ1ZSk7CgoJCQlyZXR1cm4gdC5ydW4obywgZnVuY3Rpb24obykgewoJCQkJaWYgKGspIHsKCQkJCQllYWNoKG8uY2hpbGROb2RlcywgZnVuY3Rpb24oYykgewoJCQkJCQluLmFwcGVuZENoaWxkKGMuY2xvbmVOb2RlKHRydWUpKTsKCQkJCQl9KTsKCQkJCX0KCgkJCQkvLyBGaXggSUUgcHN1ZWRvIGxlYWsgZm9yIGVsZW1lbnRzIHNpbmNlIHJlcGxhY2luZyBlbGVtZW50cyBpZiBmYWlybHkgY29tbW9uCgkJCQkvLyBXaWxsIGJyZWFrIHBhcmVudE5vZGUgZm9yIHNvbWUgdW5rbm93biByZWFzb24KCQkJCWlmICh0LmZpeFBzdWVkb0xlYWtzICYmIG8ubm9kZVR5cGUgPT09IDEpIHsKCQkJCQlvLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG4sIG8pOwoJCQkJCXQucmVtb3ZlKG8pOwoJCQkJCXJldHVybiBuOwoJCQkJfQoKCQkJCXJldHVybiBvLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG4sIG8pOwoJCQl9KTsKCQl9LAoKCQlmaW5kQ29tbW9uQW5jZXN0b3IgOiBmdW5jdGlvbihhLCBiKSB7CgkJCXZhciBwcyA9IGEsIHBlOwoKCQkJd2hpbGUgKHBzKSB7CgkJCQlwZSA9IGI7CgoJCQkJd2hpbGUgKHBlICYmIHBzICE9IHBlKQoJCQkJCXBlID0gcGUucGFyZW50Tm9kZTsKCgkJCQlpZiAocHMgPT0gcGUpCgkJCQkJYnJlYWs7CgoJCQkJcHMgPSBwcy5wYXJlbnROb2RlOwoJCQl9CgoJCQlpZiAoIXBzICYmIGEub3duZXJEb2N1bWVudCkKCQkJCXJldHVybiBhLm93bmVyRG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50OwoKCQkJcmV0dXJuIHBzOwoJCX0sCgoJCXRvSGV4IDogZnVuY3Rpb24ocykgewoJCQl2YXIgYyA9IC9eXHMqcmdiXHMqP1woXHMqPyhbMC05XSspXHMqPyxccyo/KFswLTldKylccyo/LFxzKj8oWzAtOV0rKVxzKj9cKVxzKiQvaS5leGVjKHMpOwoKCQkJZnVuY3Rpb24gaGV4KHMpIHsKCQkJCXMgPSBwYXJzZUludChzKS50b1N0cmluZygxNik7CgoJCQkJcmV0dXJuIHMubGVuZ3RoID4gMSA/IHMgOiAnMCcgKyBzOyAvLyAwIC0+IDAwCgkJCX07CgoJCQlpZiAoYykgewoJCQkJcyA9ICcjJyArIGhleChjWzFdKSArIGhleChjWzJdKSArIGhleChjWzNdKTsKCgkJCQlyZXR1cm4gczsKCQkJfQoKCQkJcmV0dXJuIHM7CgkJfSwKCgkJZ2V0Q2xhc3NlcyA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXMsIGNsID0gW10sIGksIGxvID0ge30sIGYgPSB0LnNldHRpbmdzLmNsYXNzX2ZpbHRlciwgb3Y7CgoJCQlpZiAodC5jbGFzc2VzKQoJCQkJcmV0dXJuIHQuY2xhc3NlczsKCgkJCWZ1bmN0aW9uIGFkZENsYXNzZXMocykgewoJCQkJLy8gSUUgc3R5bGUgaW1wb3J0cwoJCQkJZWFjaChzLmltcG9ydHMsIGZ1bmN0aW9uKHIpIHsKCQkJCQlhZGRDbGFzc2VzKHIpOwoJCQkJfSk7CgoJCQkJZWFjaChzLmNzc1J1bGVzIHx8IHMucnVsZXMsIGZ1bmN0aW9uKHIpIHsKCQkJCQkvLyBSZWFsIHR5cGUgb3IgZmFrZSBpdCBvbiBJRQoJCQkJCXN3aXRjaCAoci50eXBlIHx8IDEpIHsKCQkJCQkJLy8gUnVsZQoJCQkJCQljYXNlIDE6CgkJCQkJCQlpZiAoci5zZWxlY3RvclRleHQpIHsKCQkJCQkJCQllYWNoKHIuc2VsZWN0b3JUZXh0LnNwbGl0KCcsJyksIGZ1bmN0aW9uKHYpIHsKCQkJCQkJCQkJdiA9IHYucmVwbGFjZSgvXlxzKnxccyokfF5cc1wuL2csICIiKTsKCgkJCQkJCQkJCS8vIElzIGludGVybmFsIG9yIGl0IGRvZXNuJ3QgY29udGFpbiBhIGNsYXNzCgkJCQkJCQkJCWlmICgvXC5tY2UvLnRlc3QodikgfHwgIS9cLltcd1wtXSskLy50ZXN0KHYpKQoJCQkJCQkJCQkJcmV0dXJuOwoKCQkJCQkJCQkJLy8gUmVtb3ZlIGV2ZXJ5dGhpbmcgYnV0IGNsYXNzIG5hbWUKCQkJCQkJCQkJb3YgPSB2OwoJCQkJCQkJCQl2ID0gdi5yZXBsYWNlKC8uKlwuKFthLXowLTlfXC1dKykuKi9pLCAnJDEnKTsKCgkJCQkJCQkJCS8vIEZpbHRlciBjbGFzc2VzCgkJCQkJCQkJCWlmIChmICYmICEodiA9IGYodiwgb3YpKSkKCQkJCQkJCQkJCXJldHVybjsKCgkJCQkJCQkJCWlmICghbG9bdl0pIHsKCQkJCQkJCQkJCWNsLnB1c2goeydjbGFzcycgOiB2fSk7CgkJCQkJCQkJCQlsb1t2XSA9IDE7CgkJCQkJCQkJCX0KCQkJCQkJCQl9KTsKCQkJCQkJCX0KCQkJCQkJCWJyZWFrOwoKCQkJCQkJLy8gSW1wb3J0CgkJCQkJCWNhc2UgMzoKCQkJCQkJCWFkZENsYXNzZXMoci5zdHlsZVNoZWV0KTsKCQkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCX0pOwoJCQl9OwoKCQkJdHJ5IHsKCQkJCWVhY2godC5kb2Muc3R5bGVTaGVldHMsIGFkZENsYXNzZXMpOwoJCQl9IGNhdGNoIChleCkgewoJCQkJLy8gSWdub3JlCgkJCX0KCgkJCWlmIChjbC5sZW5ndGggPiAwKQoJCQkJdC5jbGFzc2VzID0gY2w7CgoJCQlyZXR1cm4gY2w7CgkJfSwKCgkJcnVuIDogZnVuY3Rpb24oZSwgZiwgcykgewoJCQl2YXIgdCA9IHRoaXMsIG87CgoJCQlpZiAodC5kb2MgJiYgdHlwZW9mKGUpID09PSAnc3RyaW5nJykKCQkJCWUgPSB0LmdldChlKTsKCgkJCWlmICghZSkKCQkJCXJldHVybiBmYWxzZTsKCgkJCXMgPSBzIHx8IHRoaXM7CgkJCWlmICghZS5ub2RlVHlwZSAmJiAoZS5sZW5ndGggfHwgZS5sZW5ndGggPT09IDApKSB7CgkJCQlvID0gW107CgoJCQkJZWFjaChlLCBmdW5jdGlvbihlLCBpKSB7CgkJCQkJaWYgKGUpIHsKCQkJCQkJaWYgKHR5cGVvZihlKSA9PSAnc3RyaW5nJykKCQkJCQkJCWUgPSB0LmRvYy5nZXRFbGVtZW50QnlJZChlKTsKCgkJCQkJCW8ucHVzaChmLmNhbGwocywgZSwgaSkpOwoJCQkJCX0KCQkJCX0pOwoKCQkJCXJldHVybiBvOwoJCQl9CgoJCQlyZXR1cm4gZi5jYWxsKHMsIGUpOwoJCX0sCgoJCWdldEF0dHJpYnMgOiBmdW5jdGlvbihuKSB7CgkJCXZhciBvOwoKCQkJbiA9IHRoaXMuZ2V0KG4pOwoKCQkJaWYgKCFuKQoJCQkJcmV0dXJuIFtdOwoKCQkJaWYgKGlzSUUpIHsKCQkJCW8gPSBbXTsKCgkJCQkvLyBPYmplY3Qgd2lsbCB0aHJvdyBleGNlcHRpb24gaW4gSUUKCQkJCWlmIChuLm5vZGVOYW1lID09ICdPQkpFQ1QnKQoJCQkJCXJldHVybiBuLmF0dHJpYnV0ZXM7CgoJCQkJLy8gSXQncyBjcmF6eSB0aGF0IHRoaXMgaXMgZmFzdGVyIGluIElFIGJ1dCBpdCdzIGJlY2F1c2UgaXQgcmV0dXJucyBhbGwgYXR0cmlidXRlcyBhbGwgdGhlIHRpbWUKCQkJCW4uY2xvbmVOb2RlKGZhbHNlKS5vdXRlckhUTUwucmVwbGFjZSgvKFthLXowLTlcOlwtX10rKT0vZ2ksIGZ1bmN0aW9uKGEsIGIpIHsKCQkJCQlvLnB1c2goe3NwZWNpZmllZCA6IDEsIG5vZGVOYW1lIDogYn0pOwoJCQkJfSk7CgoJCQkJcmV0dXJuIG87CgkJCX0KCgkJCXJldHVybiBuLmF0dHJpYnV0ZXM7CgkJfSwKCgkJZGVzdHJveSA6IGZ1bmN0aW9uKHMpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJaWYgKHQuZXZlbnRzKQoJCQkJdC5ldmVudHMuZGVzdHJveSgpOwoKCQkJdC53aW4gPSB0LmRvYyA9IHQucm9vdCA9IHQuZXZlbnRzID0gbnVsbDsKCgkJCS8vIE1hbnVhbCBkZXN0cm95IHRoZW4gcmVtb3ZlIHVubG9hZCBoYW5kbGVyCgkJCWlmICghcykKCQkJCXRpbnltY2UucmVtb3ZlVW5sb2FkKHQuZGVzdHJveSk7CgkJfSwKCgkJY3JlYXRlUm5nIDogZnVuY3Rpb24oKSB7CgkJCXZhciBkID0gdGhpcy5kb2M7CgoJCQlyZXR1cm4gZC5jcmVhdGVSYW5nZSA/IGQuY3JlYXRlUmFuZ2UoKSA6IG5ldyB0aW55bWNlLmRvbS5SYW5nZSh0aGlzKTsKCQl9LAoKCQlzcGxpdCA6IGZ1bmN0aW9uKHBlLCBlLCByZSkgewoJCQl2YXIgdCA9IHRoaXMsIHIgPSB0LmNyZWF0ZVJuZygpLCBiZWYsIGFmdCwgcGE7CgoJCQkvLyBXM0MgdmFsaWQgYnJvd3NlcnMgdGVuZCB0byBsZWF2ZSBlbXB0eSBub2RlcyB0byB0aGUgbGVmdC9yaWdodCBzaWRlIG9mIHRoZSBjb250ZW50cywgdGhpcyBtYWtlcyBzZW5jZQoJCQkvLyBidXQgd2UgZG9uJ3Qgd2FudCB0aGF0IGluIG91ciBjb2RlIHNpbmNlIGl0IHNlcnZlcyBubyBwdXJwb3NlCgkJCS8vIEZvciBleGFtcGxlIGlmIHRoaXMgaXMgY2hvcHBlZDoKCQkJLy8gICA8cD50ZXh0IDE8c3Bhbj48Yj5DSE9QPC9iPjwvc3Bhbj50ZXh0IDI8L3A+CgkJCS8vIHdvdWxkIHByb2R1Y2U6CgkJCS8vICAgPHA+dGV4dCAxPHNwYW4+PC9zcGFuPjwvcD48Yj5DSE9QPC9iPjxwPjxzcGFuPjwvc3Bhbj50ZXh0IDI8L3A+CgkJCS8vIHRoaXMgZnVuY3Rpb24gd2lsbCB0aGVuIHRyaW0gb2YgZW1wdHkgZWRnZXMgYW5kIHByb2R1Y2U6CgkJCS8vICAgPHA+dGV4dCAxPC9wPjxiPkNIT1A8L2I+PHA+dGV4dCAyPC9wPgoJCQlmdW5jdGlvbiB0cmltRWRnZShuLCBuYSkgewoJCQkJbiA9IG5bbmFdOwoKCQkJCWlmIChuICYmIG5bbmFdICYmIG5bbmFdLm5vZGVUeXBlID09IDEgJiYgaXNFbXB0eShuW25hXSkpCgkJCQkJdC5yZW1vdmUobltuYV0pOwoJCQl9OwoKCQkJZnVuY3Rpb24gaXNFbXB0eShuKSB7CgkJCQluID0gdC5nZXRPdXRlckhUTUwobik7CgkJCQluID0gbi5yZXBsYWNlKC88KGltZ3xocnx0YWJsZSkvZ2ksICctJyk7IC8vIEtlZXAgdGhlc2UgY29udmVydCB0aGVtIHRvIC0gY2hhcnMKCQkJCW4gPSBuLnJlcGxhY2UoLzxbXj5dKz4vZywgJycpOyAvLyBSZW1vdmUgYWxsIHRhZ3MKCgkJCQlyZXR1cm4gbi5yZXBsYWNlKC9bIFx0XHJcbl0rfCZuYnNwO3wmIzE2MDsvZywgJycpID09ICcnOwoJCQl9OwoKCQkJaWYgKHBlICYmIGUpIHsKCQkJCS8vIEdldCBiZWZvcmUgY2h1bmsKCQkJCXIuc2V0U3RhcnRCZWZvcmUocGUpOwoJCQkJci5zZXRFbmRCZWZvcmUoZSk7CgkJCQliZWYgPSByLmV4dHJhY3RDb250ZW50cygpOwoKCQkJCS8vIEdldCBhZnRlciBjaHVuawoJCQkJciA9IHQuY3JlYXRlUm5nKCk7CgkJCQlyLnNldFN0YXJ0QWZ0ZXIoZSk7CgkJCQlyLnNldEVuZEFmdGVyKHBlKTsKCQkJCWFmdCA9IHIuZXh0cmFjdENvbnRlbnRzKCk7CgoJCQkJLy8gSW5zZXJ0IGNodW5rcyBhbmQgcmVtb3ZlIHBhcmVudAoJCQkJcGEgPSBwZS5wYXJlbnROb2RlOwoKCQkJCS8vIFJlbW92ZSByaWdodCBzaWRlIGVkZ2Ugb2YgdGhlIGJlZm9yZSBjb250ZW50cwoJCQkJdHJpbUVkZ2UoYmVmLCAnbGFzdENoaWxkJyk7CgoJCQkJaWYgKCFpc0VtcHR5KGJlZikpCgkJCQkJcGEuaW5zZXJ0QmVmb3JlKGJlZiwgcGUpOwoKCQkJCWlmIChyZSkKCQkJCQlwYS5yZXBsYWNlQ2hpbGQocmUsIGUpOwoJCQkJZWxzZQoJCQkJCXBhLmluc2VydEJlZm9yZShlLCBwZSk7CgoJCQkJLy8gUmVtb3ZlIGxlZnQgc2l0ZSBlZGdlIG9mIHRoZSBhZnRlciBjb250ZW50cwoJCQkJdHJpbUVkZ2UoYWZ0LCAnZmlyc3RDaGlsZCcpOwoKCQkJCWlmICghaXNFbXB0eShhZnQpKQoJCQkJCXBhLmluc2VydEJlZm9yZShhZnQsIHBlKTsKCgkJCQl0LnJlbW92ZShwZSk7CgoJCQkJcmV0dXJuIHJlIHx8IGU7CgkJCX0KCQl9LAoKCQliaW5kIDogZnVuY3Rpb24odGFyZ2V0LCBuYW1lLCBmdW5jLCBzY29wZSkgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQlpZiAoIXQuZXZlbnRzKQoJCQkJdC5ldmVudHMgPSBuZXcgdGlueW1jZS5kb20uRXZlbnRVdGlscygpOwoKCQkJcmV0dXJuIHQuZXZlbnRzLmFkZCh0YXJnZXQsIG5hbWUsIGZ1bmMsIHNjb3BlIHx8IHRoaXMpOwoJCX0sCgoJCXVuYmluZCA6IGZ1bmN0aW9uKHRhcmdldCwgbmFtZSwgZnVuYykgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQlpZiAoIXQuZXZlbnRzKQoJCQkJdC5ldmVudHMgPSBuZXcgdGlueW1jZS5kb20uRXZlbnRVdGlscygpOwoKCQkJcmV0dXJuIHQuZXZlbnRzLnJlbW92ZSh0YXJnZXQsIG5hbWUsIGZ1bmMpOwoJCX0sCgoKCQlfaXNSZXMgOiBmdW5jdGlvbihjKSB7CgkJCS8vIElzIGxpdmUgcmVzaXpibGUgZWxlbWVudAoJCQlyZXR1cm4gL14odG9wfGxlZnR8Ym90dG9tfHJpZ2h0fHdpZHRofGhlaWdodCkvaS50ZXN0KGMpIHx8IC87XHMqKHRvcHxsZWZ0fGJvdHRvbXxyaWdodHx3aWR0aHxoZWlnaHQpL2kudGVzdChjKTsKCQl9CgoJCS8qCgkJd2FsayA6IGZ1bmN0aW9uKG4sIGYsIHMpIHsKCQkJdmFyIGQgPSB0aGlzLmRvYywgdzsKCgkJCWlmIChkLmNyZWF0ZVRyZWVXYWxrZXIpIHsKCQkJCXcgPSBkLmNyZWF0ZVRyZWVXYWxrZXIobiwgTm9kZUZpbHRlci5TSE9XX1RFWFQsIG51bGwsIGZhbHNlKTsKCgkJCQl3aGlsZSAoKG4gPSB3Lm5leHROb2RlKCkpICE9IG51bGwpCgkJCQkJZi5jYWxsKHMgfHwgdGhpcywgbik7CgkJCX0gZWxzZQoJCQkJdGlueW1jZS53YWxrKG4sIGYsICdjaGlsZE5vZGVzJywgcyk7CgkJfQoJCSovCgoJCS8qCgkJdG9SR0IgOiBmdW5jdGlvbihzKSB7CgkJCXZhciBjID0gL15ccyo/IyhbMC05QS1GXXsyfSkoWzAtOUEtRl17MSwyfSkoWzAtOUEtRl17Mn0pP1xzKj8kLy5leGVjKHMpOwoKCQkJaWYgKGMpIHsKCQkJCS8vICNGRkYgLT4gI0ZGRkZGRgoJCQkJaWYgKCFpcyhjWzNdKSkKCQkJCQljWzNdID0gY1syXSA9IGNbMV07CgoJCQkJcmV0dXJuICJyZ2IoIiArIHBhcnNlSW50KGNbMV0sIDE2KSArICIsIiArIHBhcnNlSW50KGNbMl0sIDE2KSArICIsIiArIHBhcnNlSW50KGNbM10sIDE2KSArICIpIjsKCQkJfQoKCQkJcmV0dXJuIHM7CgkJfQoJCSovCgoJCX0pOwoKCS8vIFNldHVwIHBhZ2UgRE9NCgl0aW55bWNlLkRPTSA9IG5ldyB0aW55bWNlLmRvbS5ET01VdGlscyhkb2N1bWVudCwge3Byb2Nlc3NfaHRtbCA6IDB9KTsKfSkodGlueW1jZSk7CihmdW5jdGlvbihucykgewoJLy8gVHJhdmVyc2UgY29uc3RhbnRzCgl2YXIgRVhUUkFDVCA9IDAsIENMT05FID0gMSwgREVMRVRFID0gMiwgZXh0ZW5kID0gdGlueW1jZS5leHRlbmQ7CgoJZnVuY3Rpb24gaW5kZXhPZihjaGlsZCwgcGFyZW50KSB7CgkJdmFyIGksIG5vZGU7CgoJCWlmIChjaGlsZC5wYXJlbnROb2RlICE9IHBhcmVudCkKCQkJcmV0dXJuIC0xOwoKCQlmb3IgKG5vZGUgPSBwYXJlbnQuZmlyc3RDaGlsZCwgaSA9IDA7IG5vZGUgIT0gY2hpbGQ7IG5vZGUgPSBub2RlLm5leHRTaWJsaW5nKQoJCQlpKys7CgoJCXJldHVybiBpOwoJfTsKCglmdW5jdGlvbiBub2RlSW5kZXgobikgewoJCXZhciBpID0gMDsKCgkJd2hpbGUgKG4ucHJldmlvdXNTaWJsaW5nKSB7CgkJCWkrKzsKCQkJbiA9IG4ucHJldmlvdXNTaWJsaW5nOwoJCX0KCgkJcmV0dXJuIGk7Cgl9OwoKCWZ1bmN0aW9uIGdldFNlbGVjdGVkTm9kZShjb250YWluZXIsIG9mZnNldCkgewoJCXZhciBjaGlsZDsKCgkJaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PSAzIC8qIFRFWFRfTk9ERSAqLykKCQkJcmV0dXJuIGNvbnRhaW5lcjsKCgkJaWYgKG9mZnNldCA8IDApCgkJCXJldHVybiBjb250YWluZXI7CgoJCWNoaWxkID0gY29udGFpbmVyLmZpcnN0Q2hpbGQ7CgkJd2hpbGUgKGNoaWxkICE9IG51bGwgJiYgb2Zmc2V0ID4gMCkgewoJCQktLW9mZnNldDsKCQkJY2hpbGQgPSBjaGlsZC5uZXh0U2libGluZzsKCQl9CgoJCWlmIChjaGlsZCAhPSBudWxsKQoJCQlyZXR1cm4gY2hpbGQ7CgoJCXJldHVybiBjb250YWluZXI7Cgl9OwoKCS8vIFJhbmdlIGNvbnN0cnVjdG9yCglmdW5jdGlvbiBSYW5nZShkb20pIHsKCQl2YXIgZCA9IGRvbS5kb2M7CgoJCWV4dGVuZCh0aGlzLCB7CgkJCWRvbSA6IGRvbSwKCgkJCS8vIEluaXRhbCBzdGF0ZXMKCQkJc3RhcnRDb250YWluZXIgOiBkLAoJCQlzdGFydE9mZnNldCA6IDAsCgkJCWVuZENvbnRhaW5lciA6IGQsCgkJCWVuZE9mZnNldCA6IDAsCgkJCWNvbGxhcHNlZCA6IHRydWUsCgkJCWNvbW1vbkFuY2VzdG9yQ29udGFpbmVyIDogZCwKCgkJCS8vIFJhbmdlIGNvbnN0YW50cwoJCQlTVEFSVF9UT19TVEFSVCA6IDAsCgkJCVNUQVJUX1RPX0VORCA6IDEsCgkJCUVORF9UT19FTkQgOiAyLAoJCQlFTkRfVE9fU1RBUlQgOiAzCgkJfSk7Cgl9OwoKCS8vIEFkZCByYW5nZSBtZXRob2RzCglleHRlbmQoUmFuZ2UucHJvdG90eXBlLCB7CgkJc2V0U3RhcnQgOiBmdW5jdGlvbihuLCBvKSB7CgkJCXRoaXMuX3NldEVuZFBvaW50KHRydWUsIG4sIG8pOwoJCX0sCgoJCXNldEVuZCA6IGZ1bmN0aW9uKG4sIG8pIHsKCQkJdGhpcy5fc2V0RW5kUG9pbnQoZmFsc2UsIG4sIG8pOwoJCX0sCgoJCXNldFN0YXJ0QmVmb3JlIDogZnVuY3Rpb24obikgewoJCQl0aGlzLnNldFN0YXJ0KG4ucGFyZW50Tm9kZSwgbm9kZUluZGV4KG4pKTsKCQl9LAoKCQlzZXRTdGFydEFmdGVyIDogZnVuY3Rpb24obikgewoJCQl0aGlzLnNldFN0YXJ0KG4ucGFyZW50Tm9kZSwgbm9kZUluZGV4KG4pICsgMSk7CgkJfSwKCgkJc2V0RW5kQmVmb3JlIDogZnVuY3Rpb24obikgewoJCQl0aGlzLnNldEVuZChuLnBhcmVudE5vZGUsIG5vZGVJbmRleChuKSk7CgkJfSwKCgkJc2V0RW5kQWZ0ZXIgOiBmdW5jdGlvbihuKSB7CgkJCXRoaXMuc2V0RW5kKG4ucGFyZW50Tm9kZSwgbm9kZUluZGV4KG4pICsgMSk7CgkJfSwKCgkJY29sbGFwc2UgOiBmdW5jdGlvbih0cykgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQlpZiAodHMpIHsKCQkJCXQuZW5kQ29udGFpbmVyID0gdC5zdGFydENvbnRhaW5lcjsKCQkJCXQuZW5kT2Zmc2V0ID0gdC5zdGFydE9mZnNldDsKCQkJfSBlbHNlIHsKCQkJCXQuc3RhcnRDb250YWluZXIgPSB0LmVuZENvbnRhaW5lcjsKCQkJCXQuc3RhcnRPZmZzZXQgPSB0LmVuZE9mZnNldDsKCQkJfQoKCQkJdC5jb2xsYXBzZWQgPSB0cnVlOwoJCX0sCgoJCXNlbGVjdE5vZGUgOiBmdW5jdGlvbihuKSB7CgkJCXRoaXMuc2V0U3RhcnRCZWZvcmUobik7CgkJCXRoaXMuc2V0RW5kQWZ0ZXIobik7CgkJfSwKCgkJc2VsZWN0Tm9kZUNvbnRlbnRzIDogZnVuY3Rpb24obikgewoJCQl0aGlzLnNldFN0YXJ0KG4sIDApOwoJCQl0aGlzLnNldEVuZChuLCBuLm5vZGVUeXBlID09PSAxID8gbi5jaGlsZE5vZGVzLmxlbmd0aCA6IG4ubm9kZVZhbHVlLmxlbmd0aCk7CgkJfSwKCgkJY29tcGFyZUJvdW5kYXJ5UG9pbnRzIDogZnVuY3Rpb24oaCwgcikgewoJCQl2YXIgdCA9IHRoaXMsIHNjID0gdC5zdGFydENvbnRhaW5lciwgc28gPSB0LnN0YXJ0T2Zmc2V0LCBlYyA9IHQuZW5kQ29udGFpbmVyLCBlbyA9IHQuZW5kT2Zmc2V0OwoKCQkJLy8gQ2hlY2sgU1RBUlRfVE9fU1RBUlQKCQkJaWYgKGggPT09IDApCgkJCQlyZXR1cm4gdC5fY29tcGFyZUJvdW5kYXJ5UG9pbnRzKHNjLCBzbywgc2MsIHNvKTsKCgkJCS8vIENoZWNrIFNUQVJUX1RPX0VORAoJCQlpZiAoaCA9PT0gMSkKCQkJCXJldHVybiB0Ll9jb21wYXJlQm91bmRhcnlQb2ludHMoc2MsIHNvLCBlYywgZW8pOwoKCQkJLy8gQ2hlY2sgRU5EX1RPX0VORAoJCQlpZiAoaCA9PT0gMikKCQkJCXJldHVybiB0Ll9jb21wYXJlQm91bmRhcnlQb2ludHMoZWMsIGVvLCBlYywgZW8pOwoKCQkJLy8gQ2hlY2sgRU5EX1RPX1NUQVJUCgkJCWlmIChoID09PSAzKQoJCQkJcmV0dXJuIHQuX2NvbXBhcmVCb3VuZGFyeVBvaW50cyhlYywgZW8sIHNjLCBzbyk7CgkJfSwKCgkJZGVsZXRlQ29udGVudHMgOiBmdW5jdGlvbigpIHsKCQkJdGhpcy5fdHJhdmVyc2UoREVMRVRFKTsKCQl9LAoKCQlleHRyYWN0Q29udGVudHMgOiBmdW5jdGlvbigpIHsKCQkJcmV0dXJuIHRoaXMuX3RyYXZlcnNlKEVYVFJBQ1QpOwoJCX0sCgoJCWNsb25lQ29udGVudHMgOiBmdW5jdGlvbigpIHsKCQkJcmV0dXJuIHRoaXMuX3RyYXZlcnNlKENMT05FKTsKCQl9LAoKCQlpbnNlcnROb2RlIDogZnVuY3Rpb24obikgewoJCQl2YXIgdCA9IHRoaXMsIG5uLCBvOwoKCQkJLy8gTm9kZSBpcyBURVhUX05PREUgb3IgQ0RBVEEKCQkJaWYgKG4ubm9kZVR5cGUgPT09IDMgfHwgbi5ub2RlVHlwZSA9PT0gNCkgewoJCQkJbm4gPSB0LnN0YXJ0Q29udGFpbmVyLnNwbGl0VGV4dCh0LnN0YXJ0T2Zmc2V0KTsKCQkJCXQuc3RhcnRDb250YWluZXIucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobiwgbm4pOwoJCQl9IGVsc2UgewoJCQkJLy8gSW5zZXJ0IGVsZW1lbnQgbm9kZQoJCQkJaWYgKHQuc3RhcnRDb250YWluZXIuY2hpbGROb2Rlcy5sZW5ndGggPiAwKQoJCQkJCW8gPSB0LnN0YXJ0Q29udGFpbmVyLmNoaWxkTm9kZXNbdC5zdGFydE9mZnNldF07CgoJCQkJdC5zdGFydENvbnRhaW5lci5pbnNlcnRCZWZvcmUobiwgbyk7CgkJCX0KCQl9LAoKCQlzdXJyb3VuZENvbnRlbnRzIDogZnVuY3Rpb24obikgewoJCQl2YXIgdCA9IHRoaXMsIGYgPSB0LmV4dHJhY3RDb250ZW50cygpOwoKCQkJdC5pbnNlcnROb2RlKG4pOwoJCQluLmFwcGVuZENoaWxkKGYpOwoJCQl0LnNlbGVjdE5vZGUobik7CgkJfSwKCgkJY2xvbmVSYW5nZSA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQlyZXR1cm4gZXh0ZW5kKG5ldyBSYW5nZSh0LmRvbSksIHsKCQkJCXN0YXJ0Q29udGFpbmVyIDogdC5zdGFydENvbnRhaW5lciwKCQkJCXN0YXJ0T2Zmc2V0IDogdC5zdGFydE9mZnNldCwKCQkJCWVuZENvbnRhaW5lciA6IHQuZW5kQ29udGFpbmVyLAoJCQkJZW5kT2Zmc2V0IDogdC5lbmRPZmZzZXQsCgkJCQljb2xsYXBzZWQgOiB0LmNvbGxhcHNlZCwKCQkJCWNvbW1vbkFuY2VzdG9yQ29udGFpbmVyIDogdC5jb21tb25BbmNlc3RvckNvbnRhaW5lcgoJCQl9KTsKCQl9LAoKLyoKCQlkZXRhY2ggOiBmdW5jdGlvbigpIHsKCQkJLy8gTm90IGltcGxlbWVudGVkCgkJfSwKKi8KCQkvLyBJbnRlcm5hbCBtZXRob2RzCgoJCV9pc0NvbGxhcHNlZCA6IGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gKHRoaXMuc3RhcnRDb250YWluZXIgPT0gdGhpcy5lbmRDb250YWluZXIgJiYgdGhpcy5zdGFydE9mZnNldCA9PSB0aGlzLmVuZE9mZnNldCk7CgkJfSwKCgkJX2NvbXBhcmVCb3VuZGFyeVBvaW50cyA6IGZ1bmN0aW9uIChjb250YWluZXJBLCBvZmZzZXRBLCBjb250YWluZXJCLCBvZmZzZXRCKSB7CgkJCXZhciBjLCBvZmZzZXRDLCBuLCBjbW5Sb290LCBjaGlsZEEsIGNoaWxkQjsKCgkJCS8vIEluIHRoZSBmaXJzdCBjYXNlIHRoZSBib3VuZGFyeS1wb2ludHMgaGF2ZSB0aGUgc2FtZSBjb250YWluZXIuIEEgaXMgYmVmb3JlIEIgCgkJCS8vIGlmIGl0cyBvZmZzZXQgaXMgbGVzcyB0aGFuIHRoZSBvZmZzZXQgb2YgQiwgQSBpcyBlcXVhbCB0byBCIGlmIGl0cyBvZmZzZXQgaXMgCgkJCS8vIGVxdWFsIHRvIHRoZSBvZmZzZXQgb2YgQiwgYW5kIEEgaXMgYWZ0ZXIgQiBpZiBpdHMgb2Zmc2V0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgCgkJCS8vIG9mZnNldCBvZiBCLgoJCQlpZiAoY29udGFpbmVyQSA9PSBjb250YWluZXJCKSB7CgkJCQlpZiAob2Zmc2V0QSA9PSBvZmZzZXRCKSB7CgkJCQkJcmV0dXJuIDA7IC8vIGVxdWFsCgkJCQl9IGVsc2UgaWYgKG9mZnNldEEgPCBvZmZzZXRCKSB7CgkJCQkJcmV0dXJuIC0xOyAvLyBiZWZvcmUKCQkJCX0gZWxzZSB7CgkJCQkJcmV0dXJuIDE7IC8vIGFmdGVyCgkJCQl9CgkJCX0KCgkJCS8vIEluIHRoZSBzZWNvbmQgY2FzZSBhIGNoaWxkIG5vZGUgQyBvZiB0aGUgY29udGFpbmVyIG9mIEEgaXMgYW4gYW5jZXN0b3IgCgkJCS8vIGNvbnRhaW5lciBvZiBCLiBJbiB0aGlzIGNhc2UsIEEgaXMgYmVmb3JlIEIgaWYgdGhlIG9mZnNldCBvZiBBIGlzIGxlc3MgdGhhbiBvciAKCQkJLy8gZXF1YWwgdG8gdGhlIGluZGV4IG9mIHRoZSBjaGlsZCBub2RlIEMgYW5kIEEgaXMgYWZ0ZXIgQiBvdGhlcndpc2UuCgkJCWMgPSBjb250YWluZXJCOwoJCQl3aGlsZSAoYyAmJiBjLnBhcmVudE5vZGUgIT0gY29udGFpbmVyQSkgewoJCQkJYyA9IGMucGFyZW50Tm9kZTsKCQkJfQoJCQlpZiAoYykgewoJCQkJb2Zmc2V0QyA9IDA7CgkJCQluID0gY29udGFpbmVyQS5maXJzdENoaWxkOwoKCQkJCXdoaWxlIChuICE9IGMgJiYgb2Zmc2V0QyA8IG9mZnNldEEpIHsKCQkJCQlvZmZzZXRDKys7CgkJCQkJbiA9IG4ubmV4dFNpYmxpbmc7CgkJCQl9CgoJCQkJaWYgKG9mZnNldEEgPD0gb2Zmc2V0QykgewoJCQkJCXJldHVybiAtMTsgLy8gYmVmb3JlCgkJCQl9IGVsc2UgewoJCQkJCXJldHVybiAxOyAvLyBhZnRlcgoJCQkJfQoJCQl9CgoJCQkvLyBJbiB0aGUgdGhpcmQgY2FzZSBhIGNoaWxkIG5vZGUgQyBvZiB0aGUgY29udGFpbmVyIG9mIEIgaXMgYW4gYW5jZXN0b3IgY29udGFpbmVyIAoJCQkvLyBvZiBBLiBJbiB0aGlzIGNhc2UsIEEgaXMgYmVmb3JlIEIgaWYgdGhlIGluZGV4IG9mIHRoZSBjaGlsZCBub2RlIEMgaXMgbGVzcyB0aGFuIAoJCQkvLyB0aGUgb2Zmc2V0IG9mIEIgYW5kIEEgaXMgYWZ0ZXIgQiBvdGhlcndpc2UuCgkJCWMgPSBjb250YWluZXJBOwoJCQl3aGlsZSAoYyAmJiBjLnBhcmVudE5vZGUgIT0gY29udGFpbmVyQikgewoJCQkJYyA9IGMucGFyZW50Tm9kZTsKCQkJfQoKCQkJaWYgKGMpIHsKCQkJCW9mZnNldEMgPSAwOwoJCQkJbiA9IGNvbnRhaW5lckIuZmlyc3RDaGlsZDsKCgkJCQl3aGlsZSAobiAhPSBjICYmIG9mZnNldEMgPCBvZmZzZXRCKSB7CgkJCQkJb2Zmc2V0QysrOwoJCQkJCW4gPSBuLm5leHRTaWJsaW5nOwoJCQkJfQoKCQkJCWlmIChvZmZzZXRDIDwgb2Zmc2V0QikgewoJCQkJCXJldHVybiAtMTsgLy8gYmVmb3JlCgkJCQl9IGVsc2UgewoJCQkJCXJldHVybiAxOyAvLyBhZnRlcgoJCQkJfQoJCQl9CgoJCQkvLyBJbiB0aGUgZm91cnRoIGNhc2UsIG5vbmUgb2YgdGhyZWUgb3RoZXIgY2FzZXMgaG9sZDogdGhlIGNvbnRhaW5lcnMgb2YgQSBhbmQgQiAKCQkJLy8gYXJlIHNpYmxpbmdzIG9yIGRlc2NlbmRhbnRzIG9mIHNpYmxpbmcgbm9kZXMuIEluIHRoaXMgY2FzZSwgQSBpcyBiZWZvcmUgQiBpZiAKCQkJLy8gdGhlIGNvbnRhaW5lciBvZiBBIGlzIGJlZm9yZSB0aGUgY29udGFpbmVyIG9mIEIgaW4gYSBwcmUtb3JkZXIgdHJhdmVyc2FsIG9mIHRoZQoJCQkvLyBSYW5nZXMnIGNvbnRleHQgdHJlZSBhbmQgQSBpcyBhZnRlciBCIG90aGVyd2lzZS4KCQkJY21uUm9vdCA9IHRoaXMuZG9tLmZpbmRDb21tb25BbmNlc3Rvcihjb250YWluZXJBLCBjb250YWluZXJCKTsKCQkJY2hpbGRBID0gY29udGFpbmVyQTsKCgkJCXdoaWxlIChjaGlsZEEgJiYgY2hpbGRBLnBhcmVudE5vZGUgIT0gY21uUm9vdCkgewoJCQkJY2hpbGRBID0gY2hpbGRBLnBhcmVudE5vZGU7ICAKCQkJfQoKCQkJaWYgKCFjaGlsZEEpIHsKCQkJCWNoaWxkQSA9IGNtblJvb3Q7CgkJCX0KCgkJCWNoaWxkQiA9IGNvbnRhaW5lckI7CgkJCXdoaWxlIChjaGlsZEIgJiYgY2hpbGRCLnBhcmVudE5vZGUgIT0gY21uUm9vdCkgewoJCQkJY2hpbGRCID0gY2hpbGRCLnBhcmVudE5vZGU7CgkJCX0KCgkJCWlmICghY2hpbGRCKSB7CgkJCQljaGlsZEIgPSBjbW5Sb290OwoJCQl9CgoJCQlpZiAoY2hpbGRBID09IGNoaWxkQikgewoJCQkJcmV0dXJuIDA7IC8vIGVxdWFsCgkJCX0KCgkJCW4gPSBjbW5Sb290LmZpcnN0Q2hpbGQ7CgkJCXdoaWxlIChuKSB7CgkJCQlpZiAobiA9PSBjaGlsZEEpIHsKCQkJCQlyZXR1cm4gLTE7IC8vIGJlZm9yZQoJCQkJfQoKCQkJCWlmIChuID09IGNoaWxkQikgewoJCQkJCXJldHVybiAxOyAvLyBhZnRlcgoJCQkJfQoKCQkJCW4gPSBuLm5leHRTaWJsaW5nOwoJCQl9CgkJfSwKCgkJX3NldEVuZFBvaW50IDogZnVuY3Rpb24oc3QsIG4sIG8pIHsKCQkJdmFyIHQgPSB0aGlzLCBlYywgc2M7CgoJCQlpZiAoc3QpIHsKCQkJCXQuc3RhcnRDb250YWluZXIgPSBuOwoJCQkJdC5zdGFydE9mZnNldCA9IG87CgkJCX0gZWxzZSB7CgkJCQl0LmVuZENvbnRhaW5lciA9IG47CgkJCQl0LmVuZE9mZnNldCA9IG87CgkJCX0KCgkJCS8vIElmIG9uZSBib3VuZGFyeS1wb2ludCBvZiBhIFJhbmdlIGlzIHNldCB0byBoYXZlIGEgcm9vdCBjb250YWluZXIgCgkJCS8vIG90aGVyIHRoYW4gdGhlIGN1cnJlbnQgb25lIGZvciB0aGUgUmFuZ2UsIHRoZSBSYW5nZSBpcyBjb2xsYXBzZWQgdG8gCgkJCS8vIHRoZSBuZXcgcG9zaXRpb24uIFRoaXMgZW5mb3JjZXMgdGhlIHJlc3RyaWN0aW9uIHRoYXQgYm90aCBib3VuZGFyeS0KCQkJLy8gcG9pbnRzIG9mIGEgUmFuZ2UgbXVzdCBoYXZlIHRoZSBzYW1lIHJvb3QgY29udGFpbmVyLgoJCQllYyA9IHQuZW5kQ29udGFpbmVyOwoJCQl3aGlsZSAoZWMucGFyZW50Tm9kZSkKCQkJCWVjID0gZWMucGFyZW50Tm9kZTsKCgkJCXNjID0gdC5zdGFydENvbnRhaW5lcjsKCQkJd2hpbGUgKHNjLnBhcmVudE5vZGUpCgkJCQlzYyA9IHNjLnBhcmVudE5vZGU7CgoJCQlpZiAoc2MgIT0gZWMpIHsKCQkJCXQuY29sbGFwc2Uoc3QpOwoJCQl9IGVsc2UgewoJCQkJLy8gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIGEgUmFuZ2UgaXMgZ3VhcmFudGVlZCB0byBuZXZlciBiZSBhZnRlciB0aGUgCgkJCQkvLyBlbmQgcG9zaXRpb24uIFRvIGVuZm9yY2UgdGhpcyByZXN0cmljdGlvbiwgaWYgdGhlIHN0YXJ0IGlzIHNldCB0byAKCQkJCS8vIGJlIGF0IGEgcG9zaXRpb24gYWZ0ZXIgdGhlIGVuZCwgdGhlIFJhbmdlIGlzIGNvbGxhcHNlZCB0byB0aGF0IAoJCQkJLy8gcG9zaXRpb24uCgkJCQlpZiAodC5fY29tcGFyZUJvdW5kYXJ5UG9pbnRzKHQuc3RhcnRDb250YWluZXIsIHQuc3RhcnRPZmZzZXQsIHQuZW5kQ29udGFpbmVyLCB0LmVuZE9mZnNldCkgPiAwKQoJCQkJCXQuY29sbGFwc2Uoc3QpOwoJCQl9CgoJCQl0LmNvbGxhcHNlZCA9IHQuX2lzQ29sbGFwc2VkKCk7CgkJCXQuY29tbW9uQW5jZXN0b3JDb250YWluZXIgPSB0LmRvbS5maW5kQ29tbW9uQW5jZXN0b3IodC5zdGFydENvbnRhaW5lciwgdC5lbmRDb250YWluZXIpOwoJCX0sCgoJCS8vIFRoaXMgY29kZSBpcyBoZWF2aWx5ICJpbnNwaXJlZCIgYnkgdGhlIEFwYWNoZSBYZXJjZXMgaW1wbGVtZW50YXRpb24uIEkgaG9wZSB0aGV5IGRvbid0IG1pbmQuIDopCgoJCV90cmF2ZXJzZSA6IGZ1bmN0aW9uKGhvdykgewoJCQl2YXIgdCA9IHRoaXMsIGMsIGVuZENvbnRhaW5lckRlcHRoID0gMCwgc3RhcnRDb250YWluZXJEZXB0aCA9IDAsIHAsIGRlcHRoRGlmZiwgc3RhcnROb2RlLCBlbmROb2RlLCBzcCwgZXA7CgoJCQlpZiAodC5zdGFydENvbnRhaW5lciA9PSB0LmVuZENvbnRhaW5lcikKCQkJCXJldHVybiB0Ll90cmF2ZXJzZVNhbWVDb250YWluZXIoaG93KTsKCgkJCWZvciAoYyA9IHQuZW5kQ29udGFpbmVyLCBwID0gYy5wYXJlbnROb2RlOyBwICE9IG51bGw7IGMgPSBwLCBwID0gcC5wYXJlbnROb2RlKSB7CgkJCQlpZiAocCA9PSB0LnN0YXJ0Q29udGFpbmVyKQoJCQkJCXJldHVybiB0Ll90cmF2ZXJzZUNvbW1vblN0YXJ0Q29udGFpbmVyKGMsIGhvdyk7CgoJCQkJKytlbmRDb250YWluZXJEZXB0aDsKCQkJfQoKCQkJZm9yIChjID0gdC5zdGFydENvbnRhaW5lciwgcCA9IGMucGFyZW50Tm9kZTsgcCAhPSBudWxsOyBjID0gcCwgcCA9IHAucGFyZW50Tm9kZSkgewoJCQkJaWYgKHAgPT0gdC5lbmRDb250YWluZXIpCgkJCQkJcmV0dXJuIHQuX3RyYXZlcnNlQ29tbW9uRW5kQ29udGFpbmVyKGMsIGhvdyk7CgoJCQkJKytzdGFydENvbnRhaW5lckRlcHRoOwoJCQl9CgoJCQlkZXB0aERpZmYgPSBzdGFydENvbnRhaW5lckRlcHRoIC0gZW5kQ29udGFpbmVyRGVwdGg7CgoJCQlzdGFydE5vZGUgPSB0LnN0YXJ0Q29udGFpbmVyOwoJCQl3aGlsZSAoZGVwdGhEaWZmID4gMCkgewoJCQkJc3RhcnROb2RlID0gc3RhcnROb2RlLnBhcmVudE5vZGU7CgkJCQlkZXB0aERpZmYtLTsKCQkJfQoKCQkJZW5kTm9kZSA9IHQuZW5kQ29udGFpbmVyOwoJCQl3aGlsZSAoZGVwdGhEaWZmIDwgMCkgewoJCQkJZW5kTm9kZSA9IGVuZE5vZGUucGFyZW50Tm9kZTsKCQkJCWRlcHRoRGlmZisrOwoJCQl9CgoJCQkvLyBhc2NlbmQgdGhlIGFuY2VzdG9yIGhpZXJhcmNoeSB1bnRpbCB3ZSBoYXZlIGEgY29tbW9uIHBhcmVudC4KCQkJZm9yIChzcCA9IHN0YXJ0Tm9kZS5wYXJlbnROb2RlLCBlcCA9IGVuZE5vZGUucGFyZW50Tm9kZTsgc3AgIT0gZXA7IHNwID0gc3AucGFyZW50Tm9kZSwgZXAgPSBlcC5wYXJlbnROb2RlKSB7CgkJCQlzdGFydE5vZGUgPSBzcDsKCQkJCWVuZE5vZGUgPSBlcDsKCQkJfQoKCQkJcmV0dXJuIHQuX3RyYXZlcnNlQ29tbW9uQW5jZXN0b3JzKHN0YXJ0Tm9kZSwgZW5kTm9kZSwgaG93KTsKCQl9LAoKCQlfdHJhdmVyc2VTYW1lQ29udGFpbmVyIDogZnVuY3Rpb24oaG93KSB7CgkJCXZhciB0ID0gdGhpcywgZnJhZywgcywgc3ViLCBuLCBjbnQsIHNpYmxpbmcsIHhmZXJOb2RlOwoKCQkJaWYgKGhvdyAhPSBERUxFVEUpCgkJCQlmcmFnID0gdC5kb20uZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKCgkJCS8vIElmIHNlbGVjdGlvbiBpcyBlbXB0eSwganVzdCByZXR1cm4gdGhlIGZyYWdtZW50CgkJCWlmICh0LnN0YXJ0T2Zmc2V0ID09IHQuZW5kT2Zmc2V0KQoJCQkJcmV0dXJuIGZyYWc7CgoJCQkvLyBUZXh0IG5vZGUgbmVlZHMgc3BlY2lhbCBjYXNlIGhhbmRsaW5nCgkJCWlmICh0LnN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlID09IDMgLyogVEVYVF9OT0RFICovKSB7CgkJCQkvLyBnZXQgdGhlIHN1YnN0cmluZwoJCQkJcyA9IHQuc3RhcnRDb250YWluZXIubm9kZVZhbHVlOwoJCQkJc3ViID0gcy5zdWJzdHJpbmcodC5zdGFydE9mZnNldCwgdC5lbmRPZmZzZXQpOwoKCQkJCS8vIHNldCB0aGUgb3JpZ2luYWwgdGV4dCBub2RlIHRvIGl0cyBuZXcgdmFsdWUKCQkJCWlmIChob3cgIT0gQ0xPTkUpIHsKCQkJCQl0LnN0YXJ0Q29udGFpbmVyLmRlbGV0ZURhdGEodC5zdGFydE9mZnNldCwgdC5lbmRPZmZzZXQgLSB0LnN0YXJ0T2Zmc2V0KTsKCgkJCQkJLy8gTm90aGluZyBpcyBwYXJ0aWFsbHkgc2VsZWN0ZWQsIHNvIGNvbGxhcHNlIHRvIHN0YXJ0IHBvaW50CgkJCQkJdC5jb2xsYXBzZSh0cnVlKTsKCQkJCX0KCgkJCQlpZiAoaG93ID09IERFTEVURSkKCQkJCQlyZXR1cm4gbnVsbDsKCgkJCQlmcmFnLmFwcGVuZENoaWxkKHQuZG9tLmRvYy5jcmVhdGVUZXh0Tm9kZShzdWIpKTsKCQkJCXJldHVybiBmcmFnOwoJCQl9CgoJCQkvLyBDb3B5IG5vZGVzIGJldHdlZW4gdGhlIHN0YXJ0L2VuZCBvZmZzZXRzLgoJCQluID0gZ2V0U2VsZWN0ZWROb2RlKHQuc3RhcnRDb250YWluZXIsIHQuc3RhcnRPZmZzZXQpOwoJCQljbnQgPSB0LmVuZE9mZnNldCAtIHQuc3RhcnRPZmZzZXQ7CgoJCQl3aGlsZSAoY250ID4gMCkgewoJCQkJc2libGluZyA9IG4ubmV4dFNpYmxpbmc7CgkJCQl4ZmVyTm9kZSA9IHQuX3RyYXZlcnNlRnVsbHlTZWxlY3RlZChuLCBob3cpOwoKCQkJCWlmIChmcmFnKQoJCQkJCWZyYWcuYXBwZW5kQ2hpbGQoIHhmZXJOb2RlICk7CgoJCQkJLS1jbnQ7CgkJCQluID0gc2libGluZzsKCQkJfQoKCQkJLy8gTm90aGluZyBpcyBwYXJ0aWFsbHkgc2VsZWN0ZWQsIHNvIGNvbGxhcHNlIHRvIHN0YXJ0IHBvaW50CgkJCWlmIChob3cgIT0gQ0xPTkUpCgkJCQl0LmNvbGxhcHNlKHRydWUpOwoKCQkJcmV0dXJuIGZyYWc7CgkJfSwKCgkJX3RyYXZlcnNlQ29tbW9uU3RhcnRDb250YWluZXIgOiBmdW5jdGlvbihlbmRBbmNlc3RvciwgaG93KSB7CgkJCXZhciB0ID0gdGhpcywgZnJhZywgbiwgZW5kSWR4LCBjbnQsIHNpYmxpbmcsIHhmZXJOb2RlOwoKCQkJaWYgKGhvdyAhPSBERUxFVEUpCgkJCQlmcmFnID0gdC5kb20uZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKCgkJCW4gPSB0Ll90cmF2ZXJzZVJpZ2h0Qm91bmRhcnkoZW5kQW5jZXN0b3IsIGhvdyk7CgoJCQlpZiAoZnJhZykKCQkJCWZyYWcuYXBwZW5kQ2hpbGQobik7CgoJCQllbmRJZHggPSBpbmRleE9mKGVuZEFuY2VzdG9yLCB0LnN0YXJ0Q29udGFpbmVyKTsKCQkJY250ID0gZW5kSWR4IC0gdC5zdGFydE9mZnNldDsKCgkJCWlmIChjbnQgPD0gMCkgewoJCQkJLy8gQ29sbGFwc2UgdG8ganVzdCBiZWZvcmUgdGhlIGVuZEFuY2VzdG9yLCB3aGljaCAKCQkJCS8vIGlzIHBhcnRpYWxseSBzZWxlY3RlZC4KCQkJCWlmIChob3cgIT0gQ0xPTkUpIHsKCQkJCQl0LnNldEVuZEJlZm9yZShlbmRBbmNlc3Rvcik7CgkJCQkJdC5jb2xsYXBzZShmYWxzZSk7CgkJCQl9CgoJCQkJcmV0dXJuIGZyYWc7CgkJCX0KCgkJCW4gPSBlbmRBbmNlc3Rvci5wcmV2aW91c1NpYmxpbmc7CgkJCXdoaWxlIChjbnQgPiAwKSB7CgkJCQlzaWJsaW5nID0gbi5wcmV2aW91c1NpYmxpbmc7CgkJCQl4ZmVyTm9kZSA9IHQuX3RyYXZlcnNlRnVsbHlTZWxlY3RlZChuLCBob3cpOwoKCQkJCWlmIChmcmFnKQoJCQkJCWZyYWcuaW5zZXJ0QmVmb3JlKHhmZXJOb2RlLCBmcmFnLmZpcnN0Q2hpbGQpOwoKCQkJCS0tY250OwoJCQkJbiA9IHNpYmxpbmc7CgkJCX0KCgkJCS8vIENvbGxhcHNlIHRvIGp1c3QgYmVmb3JlIHRoZSBlbmRBbmNlc3Rvciwgd2hpY2ggCgkJCS8vIGlzIHBhcnRpYWxseSBzZWxlY3RlZC4KCQkJaWYgKGhvdyAhPSBDTE9ORSkgewoJCQkJdC5zZXRFbmRCZWZvcmUoZW5kQW5jZXN0b3IpOwoJCQkJdC5jb2xsYXBzZShmYWxzZSk7CgkJCX0KCgkJCXJldHVybiBmcmFnOwoJCX0sCgoJCV90cmF2ZXJzZUNvbW1vbkVuZENvbnRhaW5lciA6IGZ1bmN0aW9uKHN0YXJ0QW5jZXN0b3IsIGhvdykgewoJCQl2YXIgdCA9IHRoaXMsIGZyYWcsIHN0YXJ0SWR4LCBuLCBjbnQsIHNpYmxpbmcsIHhmZXJOb2RlOwoKCQkJaWYgKGhvdyAhPSBERUxFVEUpCgkJCQlmcmFnID0gdC5kb20uZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKCgkJCW4gPSB0Ll90cmF2ZXJzZUxlZnRCb3VuZGFyeShzdGFydEFuY2VzdG9yLCBob3cpOwoJCQlpZiAoZnJhZykKCQkJCWZyYWcuYXBwZW5kQ2hpbGQobik7CgoJCQlzdGFydElkeCA9IGluZGV4T2Yoc3RhcnRBbmNlc3RvciwgdC5lbmRDb250YWluZXIpOwoJCQkrK3N0YXJ0SWR4OyAgLy8gQmVjYXVzZSB3ZSBhbHJlYWR5IHRyYXZlcnNlZCBpdC4uLi4KCgkJCWNudCA9IHQuZW5kT2Zmc2V0IC0gc3RhcnRJZHg7CgkJCW4gPSBzdGFydEFuY2VzdG9yLm5leHRTaWJsaW5nOwoJCQl3aGlsZSAoY250ID4gMCkgewoJCQkJc2libGluZyA9IG4ubmV4dFNpYmxpbmc7CgkJCQl4ZmVyTm9kZSA9IHQuX3RyYXZlcnNlRnVsbHlTZWxlY3RlZChuLCBob3cpOwoKCQkJCWlmIChmcmFnKQoJCQkJCWZyYWcuYXBwZW5kQ2hpbGQoeGZlck5vZGUpOwoKCQkJCS0tY250OwoJCQkJbiA9IHNpYmxpbmc7CgkJCX0KCgkJCWlmIChob3cgIT0gQ0xPTkUpIHsKCQkJCXQuc2V0U3RhcnRBZnRlcihzdGFydEFuY2VzdG9yKTsKCQkJCXQuY29sbGFwc2UodHJ1ZSk7CgkJCX0KCgkJCXJldHVybiBmcmFnOwoJCX0sCgoJCV90cmF2ZXJzZUNvbW1vbkFuY2VzdG9ycyA6IGZ1bmN0aW9uKHN0YXJ0QW5jZXN0b3IsIGVuZEFuY2VzdG9yLCBob3cpIHsKCQkJdmFyIHQgPSB0aGlzLCBuLCBmcmFnLCBjb21tb25QYXJlbnQsIHN0YXJ0T2Zmc2V0LCBlbmRPZmZzZXQsIGNudCwgc2libGluZywgbmV4dFNpYmxpbmc7CgoJCQlpZiAoaG93ICE9IERFTEVURSkKCQkJCWZyYWcgPSB0LmRvbS5kb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOwoKCQkJbiA9IHQuX3RyYXZlcnNlTGVmdEJvdW5kYXJ5KHN0YXJ0QW5jZXN0b3IsIGhvdyk7CgkJCWlmIChmcmFnKQoJCQkJZnJhZy5hcHBlbmRDaGlsZChuKTsKCgkJCWNvbW1vblBhcmVudCA9IHN0YXJ0QW5jZXN0b3IucGFyZW50Tm9kZTsKCQkJc3RhcnRPZmZzZXQgPSBpbmRleE9mKHN0YXJ0QW5jZXN0b3IsIGNvbW1vblBhcmVudCk7CgkJCWVuZE9mZnNldCA9IGluZGV4T2YoZW5kQW5jZXN0b3IsIGNvbW1vblBhcmVudCk7CgkJCSsrc3RhcnRPZmZzZXQ7CgoJCQljbnQgPSBlbmRPZmZzZXQgLSBzdGFydE9mZnNldDsKCQkJc2libGluZyA9IHN0YXJ0QW5jZXN0b3IubmV4dFNpYmxpbmc7CgoJCQl3aGlsZSAoY250ID4gMCkgewoJCQkJbmV4dFNpYmxpbmcgPSBzaWJsaW5nLm5leHRTaWJsaW5nOwoJCQkJbiA9IHQuX3RyYXZlcnNlRnVsbHlTZWxlY3RlZChzaWJsaW5nLCBob3cpOwoKCQkJCWlmIChmcmFnKQoJCQkJCWZyYWcuYXBwZW5kQ2hpbGQobik7CgoJCQkJc2libGluZyA9IG5leHRTaWJsaW5nOwoJCQkJLS1jbnQ7CgkJCX0KCgkJCW4gPSB0Ll90cmF2ZXJzZVJpZ2h0Qm91bmRhcnkoZW5kQW5jZXN0b3IsIGhvdyk7CgoJCQlpZiAoZnJhZykKCQkJCWZyYWcuYXBwZW5kQ2hpbGQobik7CgoJCQlpZiAoaG93ICE9IENMT05FKSB7CgkJCQl0LnNldFN0YXJ0QWZ0ZXIoc3RhcnRBbmNlc3Rvcik7CgkJCQl0LmNvbGxhcHNlKHRydWUpOwoJCQl9CgoJCQlyZXR1cm4gZnJhZzsKCQl9LAoKCQlfdHJhdmVyc2VSaWdodEJvdW5kYXJ5IDogZnVuY3Rpb24ocm9vdCwgaG93KSB7CgkJCXZhciB0ID0gdGhpcywgbmV4dCA9IGdldFNlbGVjdGVkTm9kZSh0LmVuZENvbnRhaW5lciwgdC5lbmRPZmZzZXQgLSAxKSwgcGFyZW50LCBjbG9uZWRQYXJlbnQsIHByZXZTaWJsaW5nLCBjbG9uZWRDaGlsZCwgY2xvbmVkR3JhbmRQYXJlbnQ7CgkJCXZhciBpc0Z1bGx5U2VsZWN0ZWQgPSBuZXh0ICE9IHQuZW5kQ29udGFpbmVyOwoKCQkJaWYgKG5leHQgPT0gcm9vdCkKCQkJCXJldHVybiB0Ll90cmF2ZXJzZU5vZGUobmV4dCwgaXNGdWxseVNlbGVjdGVkLCBmYWxzZSwgaG93KTsKCgkJCXBhcmVudCA9IG5leHQucGFyZW50Tm9kZTsKCQkJY2xvbmVkUGFyZW50ID0gdC5fdHJhdmVyc2VOb2RlKHBhcmVudCwgZmFsc2UsIGZhbHNlLCBob3cpOwoKCQkJd2hpbGUgKHBhcmVudCAhPSBudWxsKSB7CgkJCQl3aGlsZSAobmV4dCAhPSBudWxsKSB7CgkJCQkJcHJldlNpYmxpbmcgPSBuZXh0LnByZXZpb3VzU2libGluZzsKCQkJCQljbG9uZWRDaGlsZCA9IHQuX3RyYXZlcnNlTm9kZShuZXh0LCBpc0Z1bGx5U2VsZWN0ZWQsIGZhbHNlLCBob3cpOwoKCQkJCQlpZiAoaG93ICE9IERFTEVURSkKCQkJCQkJY2xvbmVkUGFyZW50Lmluc2VydEJlZm9yZShjbG9uZWRDaGlsZCwgY2xvbmVkUGFyZW50LmZpcnN0Q2hpbGQpOwoKCQkJCQlpc0Z1bGx5U2VsZWN0ZWQgPSB0cnVlOwoJCQkJCW5leHQgPSBwcmV2U2libGluZzsKCQkJCX0KCgkJCQlpZiAocGFyZW50ID09IHJvb3QpCgkJCQkJcmV0dXJuIGNsb25lZFBhcmVudDsKCgkJCQluZXh0ID0gcGFyZW50LnByZXZpb3VzU2libGluZzsKCQkJCXBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlOwoKCQkJCWNsb25lZEdyYW5kUGFyZW50ID0gdC5fdHJhdmVyc2VOb2RlKHBhcmVudCwgZmFsc2UsIGZhbHNlLCBob3cpOwoKCQkJCWlmIChob3cgIT0gREVMRVRFKQoJCQkJCWNsb25lZEdyYW5kUGFyZW50LmFwcGVuZENoaWxkKGNsb25lZFBhcmVudCk7CgoJCQkJY2xvbmVkUGFyZW50ID0gY2xvbmVkR3JhbmRQYXJlbnQ7CgkJCX0KCgkJCS8vIHNob3VsZCBuZXZlciBvY2N1cgoJCQlyZXR1cm4gbnVsbDsKCQl9LAoKCQlfdHJhdmVyc2VMZWZ0Qm91bmRhcnkgOiBmdW5jdGlvbihyb290LCBob3cpIHsKCQkJdmFyIHQgPSB0aGlzLCBuZXh0ID0gZ2V0U2VsZWN0ZWROb2RlKHQuc3RhcnRDb250YWluZXIsIHQuc3RhcnRPZmZzZXQpOwoJCQl2YXIgaXNGdWxseVNlbGVjdGVkID0gbmV4dCAhPSB0LnN0YXJ0Q29udGFpbmVyLCBwYXJlbnQsIGNsb25lZFBhcmVudCwgbmV4dFNpYmxpbmcsIGNsb25lZENoaWxkLCBjbG9uZWRHcmFuZFBhcmVudDsKCgkJCWlmIChuZXh0ID09IHJvb3QpCgkJCQlyZXR1cm4gdC5fdHJhdmVyc2VOb2RlKG5leHQsIGlzRnVsbHlTZWxlY3RlZCwgdHJ1ZSwgaG93KTsKCgkJCXBhcmVudCA9IG5leHQucGFyZW50Tm9kZTsKCQkJY2xvbmVkUGFyZW50ID0gdC5fdHJhdmVyc2VOb2RlKHBhcmVudCwgZmFsc2UsIHRydWUsIGhvdyk7CgoJCQl3aGlsZSAocGFyZW50ICE9IG51bGwpIHsKCQkJCXdoaWxlIChuZXh0ICE9IG51bGwpIHsKCQkJCQluZXh0U2libGluZyA9IG5leHQubmV4dFNpYmxpbmc7CgkJCQkJY2xvbmVkQ2hpbGQgPSB0Ll90cmF2ZXJzZU5vZGUobmV4dCwgaXNGdWxseVNlbGVjdGVkLCB0cnVlLCBob3cpOwoKCQkJCQlpZiAoaG93ICE9IERFTEVURSkKCQkJCQkJY2xvbmVkUGFyZW50LmFwcGVuZENoaWxkKGNsb25lZENoaWxkKTsKCgkJCQkJaXNGdWxseVNlbGVjdGVkID0gdHJ1ZTsKCQkJCQluZXh0ID0gbmV4dFNpYmxpbmc7CgkJCQl9CgoJCQkJaWYgKHBhcmVudCA9PSByb290KQoJCQkJCXJldHVybiBjbG9uZWRQYXJlbnQ7CgoJCQkJbmV4dCA9IHBhcmVudC5uZXh0U2libGluZzsKCQkJCXBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlOwoKCQkJCWNsb25lZEdyYW5kUGFyZW50ID0gdC5fdHJhdmVyc2VOb2RlKHBhcmVudCwgZmFsc2UsIHRydWUsIGhvdyk7CgoJCQkJaWYgKGhvdyAhPSBERUxFVEUpCgkJCQkJY2xvbmVkR3JhbmRQYXJlbnQuYXBwZW5kQ2hpbGQoY2xvbmVkUGFyZW50KTsKCgkJCQljbG9uZWRQYXJlbnQgPSBjbG9uZWRHcmFuZFBhcmVudDsKCQkJfQoKCQkJLy8gc2hvdWxkIG5ldmVyIG9jY3VyCgkJCXJldHVybiBudWxsOwoJCX0sCgoJCV90cmF2ZXJzZU5vZGUgOiBmdW5jdGlvbihuLCBpc0Z1bGx5U2VsZWN0ZWQsIGlzTGVmdCwgaG93KSB7CgkJCXZhciB0ID0gdGhpcywgdHh0VmFsdWUsIG5ld05vZGVWYWx1ZSwgb2xkTm9kZVZhbHVlLCBvZmZzZXQsIG5ld05vZGU7CgoJCQlpZiAoaXNGdWxseVNlbGVjdGVkKQoJCQkJcmV0dXJuIHQuX3RyYXZlcnNlRnVsbHlTZWxlY3RlZChuLCBob3cpOwoKCQkJaWYgKG4ubm9kZVR5cGUgPT0gMyAvKiBURVhUX05PREUgKi8pIHsKCQkJCXR4dFZhbHVlID0gbi5ub2RlVmFsdWU7CgoJCQkJaWYgKGlzTGVmdCkgewoJCQkJCW9mZnNldCA9IHQuc3RhcnRPZmZzZXQ7CgkJCQkJbmV3Tm9kZVZhbHVlID0gdHh0VmFsdWUuc3Vic3RyaW5nKG9mZnNldCk7CgkJCQkJb2xkTm9kZVZhbHVlID0gdHh0VmFsdWUuc3Vic3RyaW5nKDAsIG9mZnNldCk7CgkJCQl9IGVsc2UgewoJCQkJCW9mZnNldCA9IHQuZW5kT2Zmc2V0OwoJCQkJCW5ld05vZGVWYWx1ZSA9IHR4dFZhbHVlLnN1YnN0cmluZygwLCBvZmZzZXQpOwoJCQkJCW9sZE5vZGVWYWx1ZSA9IHR4dFZhbHVlLnN1YnN0cmluZyhvZmZzZXQpOwoJCQkJfQoKCQkJCWlmIChob3cgIT0gQ0xPTkUpCgkJCQkJbi5ub2RlVmFsdWUgPSBvbGROb2RlVmFsdWU7CgoJCQkJaWYgKGhvdyA9PSBERUxFVEUpCgkJCQkJcmV0dXJuIG51bGw7CgoJCQkJbmV3Tm9kZSA9IG4uY2xvbmVOb2RlKGZhbHNlKTsKCQkJCW5ld05vZGUubm9kZVZhbHVlID0gbmV3Tm9kZVZhbHVlOwoKCQkJCXJldHVybiBuZXdOb2RlOwoJCQl9CgoJCQlpZiAoaG93ID09IERFTEVURSkKCQkJCXJldHVybiBudWxsOwoKCQkJcmV0dXJuIG4uY2xvbmVOb2RlKGZhbHNlKTsKCQl9LAoKCQlfdHJhdmVyc2VGdWxseVNlbGVjdGVkIDogZnVuY3Rpb24obiwgaG93KSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCWlmIChob3cgIT0gREVMRVRFKQoJCQkJcmV0dXJuIGhvdyA9PSBDTE9ORSA/IG4uY2xvbmVOb2RlKHRydWUpIDogbjsKCgkJCW4ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChuKTsKCQkJcmV0dXJuIG51bGw7CgkJfQoJfSk7CgoJbnMuUmFuZ2UgPSBSYW5nZTsKfSkodGlueW1jZS5kb20pOwooZnVuY3Rpb24oKSB7CglmdW5jdGlvbiBTZWxlY3Rpb24oc2VsZWN0aW9uKSB7CgkJdmFyIHQgPSB0aGlzLCBpbnZpc2libGVDaGFyID0gJ1x1RkVGRicsIHJhbmdlLCBsYXN0SUVSbmc7CgoJCWZ1bmN0aW9uIGNvbXBhcmVSYW5nZXMocm5nMSwgcm5nMikgewoJCQlpZiAocm5nMSAmJiBybmcyKSB7CgkJCQkvLyBCb3RoIGFyZSBjb250cm9sIHJhbmdlcyBhbmQgdGhlIHNlbGVjdGVkIGVsZW1lbnQgbWF0Y2hlcwoJCQkJaWYgKHJuZzEuaXRlbSAmJiBybmcyLml0ZW0gJiYgcm5nMS5pdGVtKDApID09PSBybmcyLml0ZW0oMCkpCgkJCQkJcmV0dXJuIDE7CgoJCQkJLy8gQm90aCBhcmUgdGV4dCByYW5nZXMgYW5kIHRoZSByYW5nZSBtYXRjaGVzCgkJCQlpZiAocm5nMS5pc0VxdWFsICYmIHJuZzIuaXNFcXVhbCAmJiBybmcyLmlzRXF1YWwocm5nMSkpCgkJCQkJcmV0dXJuIDE7CgkJCX0KCgkJCXJldHVybiAwOwoJCX07CgoJCWZ1bmN0aW9uIGdldFJhbmdlKCkgewoJCQl2YXIgZG9tID0gc2VsZWN0aW9uLmRvbSwgaWVSYW5nZSA9IHNlbGVjdGlvbi5nZXRSbmcoKSwgZG9tUmFuZ2UgPSBkb20uY3JlYXRlUm5nKCksIHN0YXJ0UG9zLCBlbmRQb3MsIGVsZW1lbnQsIHNjLCBlYywgY29sbGFwc2VkOwoKCQkJZnVuY3Rpb24gZmluZEluZGV4KGVsZW1lbnQpIHsKCQkJCXZhciBubCA9IGVsZW1lbnQucGFyZW50Tm9kZS5jaGlsZE5vZGVzLCBpOwoKCQkJCWZvciAoaSA9IG5sLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7CgkJCQkJaWYgKG5sW2ldID09IGVsZW1lbnQpCgkJCQkJCXJldHVybiBpOwoJCQkJfQoKCQkJCXJldHVybiAtMTsKCQkJfTsKCgkJCWZ1bmN0aW9uIGZpbmRFbmRQb2ludChzdGFydCkgewoJCQkJdmFyIHJuZyA9IGllUmFuZ2UuZHVwbGljYXRlKCksIHBhcmVudCwgaSwgbmwsIG4sIG9mZnNldCA9IDAsIGluZGV4ID0gMCwgcG9zLCB0bXBSbmc7CgoJCQkJLy8gSW5zZXJ0IG1hcmtlciBjaGFyYWN0ZXIKCQkJCXJuZy5jb2xsYXBzZShzdGFydCk7CgkJCQlwYXJlbnQgPSBybmcucGFyZW50RWxlbWVudCgpOwoJCQkJcm5nLnBhc3RlSFRNTChpbnZpc2libGVDaGFyKTsgLy8gTmVlZHMgdG8gYmUgYSBwYXN0ZUhUTUwgaW5zdGVhZCBvZiAudGV4dCA9IHNpbmNlIElFIGhhcyBhIGJ1ZyB3aXRoIG5vZGVWYWx1ZQoKCQkJCS8vIEZpbmQgbWFya2VyIGNoYXJhY3RlcgoJCQkJbmwgPSBwYXJlbnQuY2hpbGROb2RlczsKCQkJCWZvciAoaSA9IDA7IGkgPCBubC5sZW5ndGg7IGkrKykgewoJCQkJCW4gPSBubFtpXTsKCgkJCQkJLy8gQ2FsY3VsYXRlIG5vZGUgaW5kZXggZXhjbHVkaW5nIHRleHQgbm9kZSBmcmFnbWVudGF0aW9uCgkJCQkJaWYgKGkgPiAwICYmIChuLm5vZGVUeXBlICE9PSAzIHx8IG5sW2kgLSAxXS5ub2RlVHlwZSAhPT0gMykpCgkJCQkJCWluZGV4Kys7CgoJCQkJCS8vIElmIHRleHQgbm9kZSB0aGVuIGNhbGN1bGF0ZSBvZmZzZXQKCQkJCQlpZiAobi5ub2RlVHlwZSA9PT0gMykgewoJCQkJCQkvLyBMb29rIGZvciBtYXJrZXIKCQkJCQkJcG9zID0gbi5ub2RlVmFsdWUuaW5kZXhPZihpbnZpc2libGVDaGFyKTsKCQkJCQkJaWYgKHBvcyAhPT0gLTEpIHsKCQkJCQkJCW9mZnNldCArPSBwb3M7CgkJCQkJCQlicmVhazsKCQkJCQkJfQoKCQkJCQkJb2Zmc2V0ICs9IG4ubm9kZVZhbHVlLmxlbmd0aDsKCQkJCQl9IGVsc2UKCQkJCQkJb2Zmc2V0ID0gMDsKCQkJCX0KCgkJCQkvLyBSZW1vdmUgbWFya2VyIGNoYXJhY3RlcgoJCQkJcm5nLm1vdmVTdGFydCgnY2hhcmFjdGVyJywgLTEpOwoJCQkJcm5nLnRleHQgPSAnJzsKCgkJCQlyZXR1cm4ge2luZGV4IDogaW5kZXgsIG9mZnNldCA6IG9mZnNldCwgcGFyZW50IDogcGFyZW50fTsKCQkJfTsKCgkJCS8vIElmIHNlbGVjdGlvbiBpcyBvdXRzaWRlIHRoZSBjdXJyZW50IGRvY3VtZW50IGp1c3QgcmV0dXJuIGFuIGVtcHR5IHJhbmdlCgkJCWVsZW1lbnQgPSBpZVJhbmdlLml0ZW0gPyBpZVJhbmdlLml0ZW0oMCkgOiBpZVJhbmdlLnBhcmVudEVsZW1lbnQoKTsKCQkJaWYgKGVsZW1lbnQub3duZXJEb2N1bWVudCAhPSBkb20uZG9jKQoJCQkJcmV0dXJuIGRvbVJhbmdlOwoKCQkJLy8gSGFuZGxlIGNvbnRyb2wgc2VsZWN0aW9uIG9yIHRleHQgc2VsZWN0aW9uIG9mIGEgaW1hZ2UKCQkJaWYgKGllUmFuZ2UuaXRlbSB8fCAhZWxlbWVudC5oYXNDaGlsZE5vZGVzKCkpIHsKCQkJCWRvbVJhbmdlLnNldFN0YXJ0KGVsZW1lbnQucGFyZW50Tm9kZSwgZmluZEluZGV4KGVsZW1lbnQpKTsKCQkJCWRvbVJhbmdlLnNldEVuZChkb21SYW5nZS5zdGFydENvbnRhaW5lciwgZG9tUmFuZ2Uuc3RhcnRPZmZzZXQgKyAxKTsKCgkJCQlyZXR1cm4gZG9tUmFuZ2U7CgkJCX0KCgkJCS8vIENoZWNrIGNvbGxhcHNlZCBzdGF0ZQoJCQljb2xsYXBzZWQgPSBzZWxlY3Rpb24uaXNDb2xsYXBzZWQoKTsKCgkJCS8vIEZpbmQgc3RhcnQgYW5kIGVuZCBwb3MgaW5kZXggYW5kIG9mZnNldAoJCQlzdGFydFBvcyA9IGZpbmRFbmRQb2ludCh0cnVlKTsKCQkJZW5kUG9zID0gZmluZEVuZFBvaW50KGZhbHNlKTsKCgkJCS8vIE5vcm1hbGl6ZSB0aGUgZWxlbWVudHMgdG8gYXZvaWQgZnJhZ21lbnRlZCBkb20KCQkJc3RhcnRQb3MucGFyZW50Lm5vcm1hbGl6ZSgpOwoJCQllbmRQb3MucGFyZW50Lm5vcm1hbGl6ZSgpOwoKCQkJLy8gU2V0IHN0YXJ0IGNvbnRhaW5lciBhbmQgb2Zmc2V0CgkJCXNjID0gc3RhcnRQb3MucGFyZW50LmNoaWxkTm9kZXNbTWF0aC5taW4oc3RhcnRQb3MuaW5kZXgsIHN0YXJ0UG9zLnBhcmVudC5jaGlsZE5vZGVzLmxlbmd0aCAtIDEpXTsKCgkJCWlmIChzYy5ub2RlVHlwZSAhPSAzKQoJCQkJZG9tUmFuZ2Uuc2V0U3RhcnQoc3RhcnRQb3MucGFyZW50LCBzdGFydFBvcy5pbmRleCk7CgkJCWVsc2UKCQkJCWRvbVJhbmdlLnNldFN0YXJ0KHN0YXJ0UG9zLnBhcmVudC5jaGlsZE5vZGVzW3N0YXJ0UG9zLmluZGV4XSwgc3RhcnRQb3Mub2Zmc2V0KTsKCgkJCS8vIFNldCBlbmQgY29udGFpbmVyIGFuZCBvZmZzZXQKCQkJZWMgPSBlbmRQb3MucGFyZW50LmNoaWxkTm9kZXNbTWF0aC5taW4oZW5kUG9zLmluZGV4LCBlbmRQb3MucGFyZW50LmNoaWxkTm9kZXMubGVuZ3RoIC0gMSldOwoKCQkJaWYgKGVjLm5vZGVUeXBlICE9IDMpIHsKCQkJCWlmICghY29sbGFwc2VkKQoJCQkJCWVuZFBvcy5pbmRleCsrOwoKCQkJCWRvbVJhbmdlLnNldEVuZChlbmRQb3MucGFyZW50LCBlbmRQb3MuaW5kZXgpOwoJCQl9IGVsc2UKCQkJCWRvbVJhbmdlLnNldEVuZChlbmRQb3MucGFyZW50LmNoaWxkTm9kZXNbZW5kUG9zLmluZGV4XSwgZW5kUG9zLm9mZnNldCk7CgoJCQkvLyBJZiBub3QgY29sbGFwc2VkIHRoZW4gbWFrZSBzdXJlIG9mZnNldHMgYXJlIHZhbGlkCgkJCWlmICghY29sbGFwc2VkKSB7CgkJCQlzYyA9IGRvbVJhbmdlLnN0YXJ0Q29udGFpbmVyOwoJCQkJaWYgKHNjLm5vZGVUeXBlID09IDEpCgkJCQkJZG9tUmFuZ2Uuc2V0U3RhcnQoc2MsIE1hdGgubWluKGRvbVJhbmdlLnN0YXJ0T2Zmc2V0LCBzYy5jaGlsZE5vZGVzLmxlbmd0aCkpOwoKCQkJCWVjID0gZG9tUmFuZ2UuZW5kQ29udGFpbmVyOwoJCQkJaWYgKGVjLm5vZGVUeXBlID09IDEpCgkJCQkJZG9tUmFuZ2Uuc2V0RW5kKGVjLCBNYXRoLm1pbihkb21SYW5nZS5lbmRPZmZzZXQsIGVjLmNoaWxkTm9kZXMubGVuZ3RoKSk7CgkJCX0KCgkJCS8vIFJlc3RvcmUgc2VsZWN0aW9uIHRvIG5ldyByYW5nZQoJCQl0LmFkZFJhbmdlKGRvbVJhbmdlKTsKCgkJCXJldHVybiBkb21SYW5nZTsKCQl9OwoKCQl0aGlzLmFkZFJhbmdlID0gZnVuY3Rpb24ocm5nKSB7CgkJCXZhciBpZVJuZywgYm9keSA9IHNlbGVjdGlvbi5kb20uZG9jLmJvZHksIHN0YXJ0UG9zLCBlbmRQb3MsIHNjLCBzbywgZWMsIGVvOwoKCQkJLy8gU2V0dXAgc29tZSBzaG9ydGVyIHZlcnNpb25zCgkJCXNjID0gcm5nLnN0YXJ0Q29udGFpbmVyOwoJCQlzbyA9IHJuZy5zdGFydE9mZnNldDsKCQkJZWMgPSBybmcuZW5kQ29udGFpbmVyOwoJCQllbyA9IHJuZy5lbmRPZmZzZXQ7CgkJCWllUm5nID0gYm9keS5jcmVhdGVUZXh0UmFuZ2UoKTsKCgkJCS8vIEZpbmQgZWxlbWVudAoJCQlzYyA9IHNjLm5vZGVUeXBlID09IDEgPyBzYy5jaGlsZE5vZGVzW01hdGgubWluKHNvLCBzYy5jaGlsZE5vZGVzLmxlbmd0aCAtIDEpXSA6IHNjOwoJCQllYyA9IGVjLm5vZGVUeXBlID09IDEgPyBlYy5jaGlsZE5vZGVzW01hdGgubWluKHNvID09IGVvID8gZW8gOiBlbyAtIDEsIGVjLmNoaWxkTm9kZXMubGVuZ3RoIC0gMSldIDogZWM7CgoJCQkvLyBTaW5nbGUgZWxlbWVudCBzZWxlY3Rpb24KCQkJaWYgKHNjID09IGVjICYmIHNjLm5vZGVUeXBlID09IDEpIHsKCQkJCS8vIE1ha2UgY29udHJvbCBzZWxlY3Rpb24gZm9yIHNvbWUgZWxlbWVudHMKCQkJCWlmICgvXihJTUd8VEFCTEUpJC8udGVzdChzYy5ub2RlTmFtZSkgJiYgc28gIT0gZW8pIHsKCQkJCQlpZVJuZyA9IGJvZHkuY3JlYXRlQ29udHJvbFJhbmdlKCk7CgkJCQkJaWVSbmcuYWRkRWxlbWVudChzYyk7CgkJCQl9IGVsc2UgewoJCQkJCWllUm5nID0gYm9keS5jcmVhdGVUZXh0UmFuZ2UoKTsKCgkJCQkJLy8gUGFkZCBlbXB0eSBlbGVtZW50cyB3aXRoIGludmlzaWJsZSBjaGFyYWN0ZXIKCQkJCQlpZiAoIXNjLmhhc0NoaWxkTm9kZXMoKSAmJiBzYy5jYW5IYXZlSFRNTCkKCQkJCQkJc2MuaW5uZXJIVE1MID0gaW52aXNpYmxlQ2hhcjsKCgkJCQkJLy8gU2VsZWN0IGVsZW1lbnQgY29udGVudHMKCQkJCQlpZVJuZy5tb3ZlVG9FbGVtZW50VGV4dChzYyk7CgoJCQkJCS8vIElmIGl0J3Mgb25seSBjb250YWluaW5nIGEgcGFkZGluZyByZW1vdmUgaXQgc28gdGhlIGNhcmV0IHJlbWFpbnMKCQkJCQlpZiAoc2MuaW5uZXJIVE1MID09IGludmlzaWJsZUNoYXIpIHsKCQkJCQkJaWVSbmcuY29sbGFwc2UodHJ1ZSk7CgkJCQkJCXNjLnJlbW92ZUNoaWxkKHNjLmZpcnN0Q2hpbGQpOwoJCQkJCX0KCQkJCX0KCgkJCQlpZiAoc28gPT0gZW8pCgkJCQkJaWVSbmcuY29sbGFwc2UoZW8gPD0gcm5nLmVuZENvbnRhaW5lci5jaGlsZE5vZGVzLmxlbmd0aCAtIDEpOwoKCQkJCWllUm5nLnNlbGVjdCgpOwoKCQkJCXJldHVybjsKCQkJfQoKCQkJZnVuY3Rpb24gZ2V0Q2hhclBvcyhjb250YWluZXIsIG9mZnNldCkgewoJCQkJdmFyIG5vZGVWYWwsIHJuZywgcG9zOwoKCQkJCWlmIChjb250YWluZXIubm9kZVR5cGUgIT0gMykKCQkJCQlyZXR1cm4gLTE7CgoJCQkJbm9kZVZhbCA9IGNvbnRhaW5lci5ub2RlVmFsdWU7CgkJCQlybmcgPSBib2R5LmNyZWF0ZVRleHRSYW5nZSgpOwoKCQkJCS8vIEluc2VydCBtYXJrZXIgYXQgb2Zmc2V0IHBvc2l0aW9uCgkJCQljb250YWluZXIubm9kZVZhbHVlID0gbm9kZVZhbC5zdWJzdHJpbmcoMCwgb2Zmc2V0KSArIGludmlzaWJsZUNoYXIgKyBub2RlVmFsLnN1YnN0cmluZyhvZmZzZXQpOwoKCQkJCS8vIEZpbmQgY2hhciBwb3Mgb2YgbWFya2VyIGFuZCByZW1vdmUgaXQKCQkJCXJuZy5tb3ZlVG9FbGVtZW50VGV4dChjb250YWluZXIucGFyZW50Tm9kZSk7CgkJCQlybmcuZmluZFRleHQoaW52aXNpYmxlQ2hhcik7CgkJCQlwb3MgPSBNYXRoLmFicyhybmcubW92ZVN0YXJ0KCdjaGFyYWN0ZXInLCAtMHhGRkZGRikpOwoJCQkJY29udGFpbmVyLm5vZGVWYWx1ZSA9IG5vZGVWYWw7CgoJCQkJcmV0dXJuIHBvczsKCQkJfTsKCgkJCS8vIENvbGxhcHNlZCByYW5nZQoJCQlpZiAocm5nLmNvbGxhcHNlZCkgewoJCQkJcG9zID0gZ2V0Q2hhclBvcyhzYywgc28pOwoKCQkJCWllUm5nID0gYm9keS5jcmVhdGVUZXh0UmFuZ2UoKTsKCQkJCWllUm5nLm1vdmUoJ2NoYXJhY3RlcicsIHBvcyk7CgkJCQlpZVJuZy5zZWxlY3QoKTsKCgkJCQlyZXR1cm47CgkJCX0gZWxzZSB7CgkJCQkvLyBJZiBzYW1lIHRleHQgY29udGFpbmVyCgkJCQlpZiAoc2MgPT0gZWMgJiYgc2Mubm9kZVR5cGUgPT0gMykgewoJCQkJCXN0YXJ0UG9zID0gZ2V0Q2hhclBvcyhzYywgc28pOwoKCQkJCQlpZVJuZy5tb3ZlKCdjaGFyYWN0ZXInLCBzdGFydFBvcyk7CgkJCQkJaWVSbmcubW92ZUVuZCgnY2hhcmFjdGVyJywgZW8gLSBzbyk7CgkJCQkJaWVSbmcuc2VsZWN0KCk7CgoJCQkJCXJldHVybjsKCQkJCX0KCgkJCQkvLyBHZXQgY2FyZXQgcG9zaXRpb25zCgkJCQlzdGFydFBvcyA9IGdldENoYXJQb3Moc2MsIHNvKTsKCQkJCWVuZFBvcyA9IGdldENoYXJQb3MoZWMsIGVvKTsKCQkJCWllUm5nID0gYm9keS5jcmVhdGVUZXh0UmFuZ2UoKTsKCgkJCQkvLyBNb3ZlIHN0YXJ0IG9mIHJhbmdlIHRvIHN0YXJ0IGNoYXJhY3RlciBwb3NpdGlvbiBvciBzdGFydCBlbGVtZW50CgkJCQlpZiAoc3RhcnRQb3MgPT0gLTEpIHsKCQkJCQlpZVJuZy5tb3ZlVG9FbGVtZW50VGV4dChzYyk7CgkJCQkJc3RhcnRQb3MgPSAwOwoJCQkJfSBlbHNlCgkJCQkJaWVSbmcubW92ZSgnY2hhcmFjdGVyJywgc3RhcnRQb3MpOwoKCQkJCS8vIE1vdmUgZW5kIG9mIHJhbmdlIHRvIGVuZCBjaGFyYWN0ZXIgcG9zaXRpb24gb3IgZW5kIGVsZW1lbnQKCQkJCXRtcFJuZyA9IGJvZHkuY3JlYXRlVGV4dFJhbmdlKCk7CgoJCQkJaWYgKGVuZFBvcyA9PSAtMSkKCQkJCQl0bXBSbmcubW92ZVRvRWxlbWVudFRleHQoZWMpOwoJCQkJZWxzZQoJCQkJCXRtcFJuZy5tb3ZlKCdjaGFyYWN0ZXInLCBlbmRQb3MpOwoKCQkJCWllUm5nLnNldEVuZFBvaW50KCdFbmRUb0VuZCcsIHRtcFJuZyk7CgkJCQlpZVJuZy5zZWxlY3QoKTsKCgkJCQlyZXR1cm47CgkJCX0KCQl9OwoKCQl0aGlzLmdldFJhbmdlQXQgPSBmdW5jdGlvbigpIHsKCQkJLy8gU2V0dXAgbmV3IHJhbmdlIGlmIHRoZSBjYWNoZSBpcyBlbXB0eQoJCQlpZiAoIXJhbmdlIHx8ICFjb21wYXJlUmFuZ2VzKGxhc3RJRVJuZywgc2VsZWN0aW9uLmdldFJuZygpKSkgewoJCQkJcmFuZ2UgPSBnZXRSYW5nZSgpOwoKCQkJCS8vIFN0b3JlIGF3YXkgdGV4dCByYW5nZSBmb3IgbmV4dCBjYWxsCgkJCQlsYXN0SUVSbmcgPSBzZWxlY3Rpb24uZ2V0Um5nKCk7CgkJCX0KCgkJCS8vIFJldHVybiBjYWNoZWQgcmFuZ2UKCQkJcmV0dXJuIHJhbmdlOwoJCX07CgoJCXRoaXMuZGVzdHJveSA9IGZ1bmN0aW9uKCkgewoJCQkvLyBEZXN0cm95IGNhY2hlZCByYW5nZSBhbmQgbGFzdCBJRSByYW5nZSB0byBhdm9pZCBtZW1vcnkgbGVha3MKCQkJbGFzdElFUm5nID0gcmFuZ2UgPSBudWxsOwoJCX07Cgl9OwoKCS8vIEV4cG9zZSB0aGUgc2VsZWN0aW9uIG9iamVjdAoJdGlueW1jZS5kb20uVHJpZGVudFNlbGVjdGlvbiA9IFNlbGVjdGlvbjsKfSkoKTsKCi8qCiAqIFNpenpsZSBDU1MgU2VsZWN0b3IgRW5naW5lIC0gdjEuMAogKiAgQ29weXJpZ2h0IDIwMDksIFRoZSBEb2pvIEZvdW5kYXRpb24KICogIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQsIEJTRCwgYW5kIEdQTCBMaWNlbnNlcy4KICogIE1vcmUgaW5mb3JtYXRpb246IGh0dHA6Ly9zaXp6bGVqcy5jb20vCiAqLwooZnVuY3Rpb24oKXsKCnZhciBjaHVua2VyID0gLygoPzpcKCg/OlwoW14oKV0rXCl8W14oKV0rKStcKXxcWyg/OlxbW15bXF1dKlxdfFsnIl1bXiciXSpbJyJdfFteW1xdJyJdKykrXF18XFwufFteID4rfiwoXFtcXF0rKSt8Wz4rfl0pKFxzKixccyopPy9nLAoJZG9uZSA9IDAsCgl0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcsCgloYXNEdXBsaWNhdGUgPSBmYWxzZTsKCnZhciBTaXp6bGUgPSBmdW5jdGlvbihzZWxlY3RvciwgY29udGV4dCwgcmVzdWx0cywgc2VlZCkgewoJcmVzdWx0cyA9IHJlc3VsdHMgfHwgW107Cgl2YXIgb3JpZ0NvbnRleHQgPSBjb250ZXh0ID0gY29udGV4dCB8fCBkb2N1bWVudDsKCglpZiAoIGNvbnRleHQubm9kZVR5cGUgIT09IDEgJiYgY29udGV4dC5ub2RlVHlwZSAhPT0gOSApIHsKCQlyZXR1cm4gW107Cgl9CgkKCWlmICggIXNlbGVjdG9yIHx8IHR5cGVvZiBzZWxlY3RvciAhPT0gInN0cmluZyIgKSB7CgkJcmV0dXJuIHJlc3VsdHM7Cgl9CgoJdmFyIHBhcnRzID0gW10sIG0sIHNldCwgY2hlY2tTZXQsIGNoZWNrLCBtb2RlLCBleHRyYSwgcHJ1bmUgPSB0cnVlLCBjb250ZXh0WE1MID0gaXNYTUwoY29udGV4dCk7CgkKCS8vIFJlc2V0IHRoZSBwb3NpdGlvbiBvZiB0aGUgY2h1bmtlciByZWdleHAgKHN0YXJ0IGZyb20gaGVhZCkKCWNodW5rZXIubGFzdEluZGV4ID0gMDsKCQoJd2hpbGUgKCAobSA9IGNodW5rZXIuZXhlYyhzZWxlY3RvcikpICE9PSBudWxsICkgewoJCXBhcnRzLnB1c2goIG1bMV0gKTsKCQkKCQlpZiAoIG1bMl0gKSB7CgkJCWV4dHJhID0gUmVnRXhwLnJpZ2h0Q29udGV4dDsKCQkJYnJlYWs7CgkJfQoJfQoKCWlmICggcGFydHMubGVuZ3RoID4gMSAmJiBvcmlnUE9TLmV4ZWMoIHNlbGVjdG9yICkgKSB7CgkJaWYgKCBwYXJ0cy5sZW5ndGggPT09IDIgJiYgRXhwci5yZWxhdGl2ZVsgcGFydHNbMF0gXSApIHsKCQkJc2V0ID0gcG9zUHJvY2VzcyggcGFydHNbMF0gKyBwYXJ0c1sxXSwgY29udGV4dCApOwoJCX0gZWxzZSB7CgkJCXNldCA9IEV4cHIucmVsYXRpdmVbIHBhcnRzWzBdIF0gPwoJCQkJWyBjb250ZXh0IF0gOgoJCQkJU2l6emxlKCBwYXJ0cy5zaGlmdCgpLCBjb250ZXh0ICk7CgoJCQl3aGlsZSAoIHBhcnRzLmxlbmd0aCApIHsKCQkJCXNlbGVjdG9yID0gcGFydHMuc2hpZnQoKTsKCgkJCQlpZiAoIEV4cHIucmVsYXRpdmVbIHNlbGVjdG9yIF0gKQoJCQkJCXNlbGVjdG9yICs9IHBhcnRzLnNoaWZ0KCk7CgoJCQkJc2V0ID0gcG9zUHJvY2Vzcyggc2VsZWN0b3IsIHNldCApOwoJCQl9CgkJfQoJfSBlbHNlIHsKCQkvLyBUYWtlIGEgc2hvcnRjdXQgYW5kIHNldCB0aGUgY29udGV4dCBpZiB0aGUgcm9vdCBzZWxlY3RvciBpcyBhbiBJRAoJCS8vIChidXQgbm90IGlmIGl0J2xsIGJlIGZhc3RlciBpZiB0aGUgaW5uZXIgc2VsZWN0b3IgaXMgYW4gSUQpCgkJaWYgKCAhc2VlZCAmJiBwYXJ0cy5sZW5ndGggPiAxICYmIGNvbnRleHQubm9kZVR5cGUgPT09IDkgJiYgIWNvbnRleHRYTUwgJiYKCQkJCUV4cHIubWF0Y2guSUQudGVzdChwYXJ0c1swXSkgJiYgIUV4cHIubWF0Y2guSUQudGVzdChwYXJ0c1twYXJ0cy5sZW5ndGggLSAxXSkgKSB7CgkJCXZhciByZXQgPSBTaXp6bGUuZmluZCggcGFydHMuc2hpZnQoKSwgY29udGV4dCwgY29udGV4dFhNTCApOwoJCQljb250ZXh0ID0gcmV0LmV4cHIgPyBTaXp6bGUuZmlsdGVyKCByZXQuZXhwciwgcmV0LnNldCApWzBdIDogcmV0LnNldFswXTsKCQl9CgoJCWlmICggY29udGV4dCApIHsKCQkJdmFyIHJldCA9IHNlZWQgPwoJCQkJeyBleHByOiBwYXJ0cy5wb3AoKSwgc2V0OiBtYWtlQXJyYXkoc2VlZCkgfSA6CgkJCQlTaXp6bGUuZmluZCggcGFydHMucG9wKCksIHBhcnRzLmxlbmd0aCA9PT0gMSAmJiAocGFydHNbMF0gPT09ICJ+IiB8fCBwYXJ0c1swXSA9PT0gIisiKSAmJiBjb250ZXh0LnBhcmVudE5vZGUgPyBjb250ZXh0LnBhcmVudE5vZGUgOiBjb250ZXh0LCBjb250ZXh0WE1MICk7CgkJCXNldCA9IHJldC5leHByID8gU2l6emxlLmZpbHRlciggcmV0LmV4cHIsIHJldC5zZXQgKSA6IHJldC5zZXQ7CgoJCQlpZiAoIHBhcnRzLmxlbmd0aCA+IDAgKSB7CgkJCQljaGVja1NldCA9IG1ha2VBcnJheShzZXQpOwoJCQl9IGVsc2UgewoJCQkJcHJ1bmUgPSBmYWxzZTsKCQkJfQoKCQkJd2hpbGUgKCBwYXJ0cy5sZW5ndGggKSB7CgkJCQl2YXIgY3VyID0gcGFydHMucG9wKCksIHBvcCA9IGN1cjsKCgkJCQlpZiAoICFFeHByLnJlbGF0aXZlWyBjdXIgXSApIHsKCQkJCQljdXIgPSAiIjsKCQkJCX0gZWxzZSB7CgkJCQkJcG9wID0gcGFydHMucG9wKCk7CgkJCQl9CgoJCQkJaWYgKCBwb3AgPT0gbnVsbCApIHsKCQkJCQlwb3AgPSBjb250ZXh0OwoJCQkJfQoKCQkJCUV4cHIucmVsYXRpdmVbIGN1ciBdKCBjaGVja1NldCwgcG9wLCBjb250ZXh0WE1MICk7CgkJCX0KCQl9IGVsc2UgewoJCQljaGVja1NldCA9IHBhcnRzID0gW107CgkJfQoJfQoKCWlmICggIWNoZWNrU2V0ICkgewoJCWNoZWNrU2V0ID0gc2V0OwoJfQoKCWlmICggIWNoZWNrU2V0ICkgewoJCXRocm93ICJTeW50YXggZXJyb3IsIHVucmVjb2duaXplZCBleHByZXNzaW9uOiAiICsgKGN1ciB8fCBzZWxlY3Rvcik7Cgl9CgoJaWYgKCB0b1N0cmluZy5jYWxsKGNoZWNrU2V0KSA9PT0gIltvYmplY3QgQXJyYXldIiApIHsKCQlpZiAoICFwcnVuZSApIHsKCQkJcmVzdWx0cy5wdXNoLmFwcGx5KCByZXN1bHRzLCBjaGVja1NldCApOwoJCX0gZWxzZSBpZiAoIGNvbnRleHQgJiYgY29udGV4dC5ub2RlVHlwZSA9PT0gMSApIHsKCQkJZm9yICggdmFyIGkgPSAwOyBjaGVja1NldFtpXSAhPSBudWxsOyBpKysgKSB7CgkJCQlpZiAoIGNoZWNrU2V0W2ldICYmIChjaGVja1NldFtpXSA9PT0gdHJ1ZSB8fCBjaGVja1NldFtpXS5ub2RlVHlwZSA9PT0gMSAmJiBjb250YWlucyhjb250ZXh0LCBjaGVja1NldFtpXSkpICkgewoJCQkJCXJlc3VsdHMucHVzaCggc2V0W2ldICk7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQlmb3IgKCB2YXIgaSA9IDA7IGNoZWNrU2V0W2ldICE9IG51bGw7IGkrKyApIHsKCQkJCWlmICggY2hlY2tTZXRbaV0gJiYgY2hlY2tTZXRbaV0ubm9kZVR5cGUgPT09IDEgKSB7CgkJCQkJcmVzdWx0cy5wdXNoKCBzZXRbaV0gKTsKCQkJCX0KCQkJfQoJCX0KCX0gZWxzZSB7CgkJbWFrZUFycmF5KCBjaGVja1NldCwgcmVzdWx0cyApOwoJfQoKCWlmICggZXh0cmEgKSB7CgkJU2l6emxlKCBleHRyYSwgb3JpZ0NvbnRleHQsIHJlc3VsdHMsIHNlZWQgKTsKCQlTaXp6bGUudW5pcXVlU29ydCggcmVzdWx0cyApOwoJfQoKCXJldHVybiByZXN1bHRzOwp9OwoKU2l6emxlLnVuaXF1ZVNvcnQgPSBmdW5jdGlvbihyZXN1bHRzKXsKCWlmICggc29ydE9yZGVyICkgewoJCWhhc0R1cGxpY2F0ZSA9IGZhbHNlOwoJCXJlc3VsdHMuc29ydChzb3J0T3JkZXIpOwoKCQlpZiAoIGhhc0R1cGxpY2F0ZSApIHsKCQkJZm9yICggdmFyIGkgPSAxOyBpIDwgcmVzdWx0cy5sZW5ndGg7IGkrKyApIHsKCQkJCWlmICggcmVzdWx0c1tpXSA9PT0gcmVzdWx0c1tpLTFdICkgewoJCQkJCXJlc3VsdHMuc3BsaWNlKGktLSwgMSk7CgkJCQl9CgkJCX0KCQl9Cgl9Cn07CgpTaXp6bGUubWF0Y2hlcyA9IGZ1bmN0aW9uKGV4cHIsIHNldCl7CglyZXR1cm4gU2l6emxlKGV4cHIsIG51bGwsIG51bGwsIHNldCk7Cn07CgpTaXp6bGUuZmluZCA9IGZ1bmN0aW9uKGV4cHIsIGNvbnRleHQsIGlzWE1MKXsKCXZhciBzZXQsIG1hdGNoOwoKCWlmICggIWV4cHIgKSB7CgkJcmV0dXJuIFtdOwoJfQoKCWZvciAoIHZhciBpID0gMCwgbCA9IEV4cHIub3JkZXIubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCXZhciB0eXBlID0gRXhwci5vcmRlcltpXSwgbWF0Y2g7CgkJCgkJaWYgKCAobWF0Y2ggPSBFeHByLm1hdGNoWyB0eXBlIF0uZXhlYyggZXhwciApKSApIHsKCQkJdmFyIGxlZnQgPSBSZWdFeHAubGVmdENvbnRleHQ7CgoJCQlpZiAoIGxlZnQuc3Vic3RyKCBsZWZ0Lmxlbmd0aCAtIDEgKSAhPT0gIlxcIiApIHsKCQkJCW1hdGNoWzFdID0gKG1hdGNoWzFdIHx8ICIiKS5yZXBsYWNlKC9cXC9nLCAiIik7CgkJCQlzZXQgPSBFeHByLmZpbmRbIHR5cGUgXSggbWF0Y2gsIGNvbnRleHQsIGlzWE1MICk7CgkJCQlpZiAoIHNldCAhPSBudWxsICkgewoJCQkJCWV4cHIgPSBleHByLnJlcGxhY2UoIEV4cHIubWF0Y2hbIHR5cGUgXSwgIiIgKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCX0KCglpZiAoICFzZXQgKSB7CgkJc2V0ID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpOwoJfQoKCXJldHVybiB7c2V0OiBzZXQsIGV4cHI6IGV4cHJ9Owp9OwoKU2l6emxlLmZpbHRlciA9IGZ1bmN0aW9uKGV4cHIsIHNldCwgaW5wbGFjZSwgbm90KXsKCXZhciBvbGQgPSBleHByLCByZXN1bHQgPSBbXSwgY3VyTG9vcCA9IHNldCwgbWF0Y2gsIGFueUZvdW5kLAoJCWlzWE1MRmlsdGVyID0gc2V0ICYmIHNldFswXSAmJiBpc1hNTChzZXRbMF0pOwoKCXdoaWxlICggZXhwciAmJiBzZXQubGVuZ3RoICkgewoJCWZvciAoIHZhciB0eXBlIGluIEV4cHIuZmlsdGVyICkgewoJCQlpZiAoIChtYXRjaCA9IEV4cHIubWF0Y2hbIHR5cGUgXS5leGVjKCBleHByICkpICE9IG51bGwgKSB7CgkJCQl2YXIgZmlsdGVyID0gRXhwci5maWx0ZXJbIHR5cGUgXSwgZm91bmQsIGl0ZW07CgkJCQlhbnlGb3VuZCA9IGZhbHNlOwoKCQkJCWlmICggY3VyTG9vcCA9PSByZXN1bHQgKSB7CgkJCQkJcmVzdWx0ID0gW107CgkJCQl9CgoJCQkJaWYgKCBFeHByLnByZUZpbHRlclsgdHlwZSBdICkgewoJCQkJCW1hdGNoID0gRXhwci5wcmVGaWx0ZXJbIHR5cGUgXSggbWF0Y2gsIGN1ckxvb3AsIGlucGxhY2UsIHJlc3VsdCwgbm90LCBpc1hNTEZpbHRlciApOwoKCQkJCQlpZiAoICFtYXRjaCApIHsKCQkJCQkJYW55Rm91bmQgPSBmb3VuZCA9IHRydWU7CgkJCQkJfSBlbHNlIGlmICggbWF0Y2ggPT09IHRydWUgKSB7CgkJCQkJCWNvbnRpbnVlOwoJCQkJCX0KCQkJCX0KCgkJCQlpZiAoIG1hdGNoICkgewoJCQkJCWZvciAoIHZhciBpID0gMDsgKGl0ZW0gPSBjdXJMb29wW2ldKSAhPSBudWxsOyBpKysgKSB7CgkJCQkJCWlmICggaXRlbSApIHsKCQkJCQkJCWZvdW5kID0gZmlsdGVyKCBpdGVtLCBtYXRjaCwgaSwgY3VyTG9vcCApOwoJCQkJCQkJdmFyIHBhc3MgPSBub3QgXiAhIWZvdW5kOwoKCQkJCQkJCWlmICggaW5wbGFjZSAmJiBmb3VuZCAhPSBudWxsICkgewoJCQkJCQkJCWlmICggcGFzcyApIHsKCQkJCQkJCQkJYW55Rm91bmQgPSB0cnVlOwoJCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkJCWN1ckxvb3BbaV0gPSBmYWxzZTsKCQkJCQkJCQl9CgkJCQkJCQl9IGVsc2UgaWYgKCBwYXNzICkgewoJCQkJCQkJCXJlc3VsdC5wdXNoKCBpdGVtICk7CgkJCQkJCQkJYW55Rm91bmQgPSB0cnVlOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJfQoKCQkJCWlmICggZm91bmQgIT09IHVuZGVmaW5lZCApIHsKCQkJCQlpZiAoICFpbnBsYWNlICkgewoJCQkJCQljdXJMb29wID0gcmVzdWx0OwoJCQkJCX0KCgkJCQkJZXhwciA9IGV4cHIucmVwbGFjZSggRXhwci5tYXRjaFsgdHlwZSBdLCAiIiApOwoKCQkJCQlpZiAoICFhbnlGb3VuZCApIHsKCQkJCQkJcmV0dXJuIFtdOwoJCQkJCX0KCgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9CgoJCS8vIEltcHJvcGVyIGV4cHJlc3Npb24KCQlpZiAoIGV4cHIgPT0gb2xkICkgewoJCQlpZiAoIGFueUZvdW5kID09IG51bGwgKSB7CgkJCQl0aHJvdyAiU3ludGF4IGVycm9yLCB1bnJlY29nbml6ZWQgZXhwcmVzc2lvbjogIiArIGV4cHI7CgkJCX0gZWxzZSB7CgkJCQlicmVhazsKCQkJfQoJCX0KCgkJb2xkID0gZXhwcjsKCX0KCglyZXR1cm4gY3VyTG9vcDsKfTsKCnZhciBFeHByID0gU2l6emxlLnNlbGVjdG9ycyA9IHsKCW9yZGVyOiBbICJJRCIsICJOQU1FIiwgIlRBRyIgXSwKCW1hdGNoOiB7CgkJSUQ6IC8jKCg/Oltcd1x1MDBjMC1cdUZGRkZfLV18XFwuKSspLywKCQlDTEFTUzogL1wuKCg/Oltcd1x1MDBjMC1cdUZGRkZfLV18XFwuKSspLywKCQlOQU1FOiAvXFtuYW1lPVsnIl0qKCg/Oltcd1x1MDBjMC1cdUZGRkZfLV18XFwuKSspWyciXSpcXS8sCgkJQVRUUjogL1xbXHMqKCg/Oltcd1x1MDBjMC1cdUZGRkZfLV18XFwuKSspXHMqKD86KFxTPz0pXHMqKFsnIl0qKSguKj8pXDN8KVxzKlxdLywKCQlUQUc6IC9eKCg/Oltcd1x1MDBjMC1cdUZGRkZcKl8tXXxcXC4pKykvLAoJCUNISUxEOiAvOihvbmx5fG50aHxsYXN0fGZpcnN0KS1jaGlsZCg/OlwoKGV2ZW58b2RkfFtcZG4rLV0qKVwpKT8vLAoJCVBPUzogLzoobnRofGVxfGd0fGx0fGZpcnN0fGxhc3R8ZXZlbnxvZGQpKD86XCgoXGQqKVwpKT8oPz1bXi1dfCQpLywKCQlQU0VVRE86IC86KCg/Oltcd1x1MDBjMC1cdUZGRkZfLV18XFwuKSspKD86XCgoWyciXSopKCg/OlwoW15cKV0rXCl8W15cMlwoXCldKikrKVwyXCkpPy8KCX0sCglhdHRyTWFwOiB7CgkJImNsYXNzIjogImNsYXNzTmFtZSIsCgkJImZvciI6ICJodG1sRm9yIgoJfSwKCWF0dHJIYW5kbGU6IHsKCQlocmVmOiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKCJocmVmIik7CgkJfQoJfSwKCXJlbGF0aXZlOiB7CgkJIisiOiBmdW5jdGlvbihjaGVja1NldCwgcGFydCwgaXNYTUwpewoJCQl2YXIgaXNQYXJ0U3RyID0gdHlwZW9mIHBhcnQgPT09ICJzdHJpbmciLAoJCQkJaXNUYWcgPSBpc1BhcnRTdHIgJiYgIS9cVy8udGVzdChwYXJ0KSwKCQkJCWlzUGFydFN0ck5vdFRhZyA9IGlzUGFydFN0ciAmJiAhaXNUYWc7CgoJCQlpZiAoIGlzVGFnICYmICFpc1hNTCApIHsKCQkJCXBhcnQgPSBwYXJ0LnRvVXBwZXJDYXNlKCk7CgkJCX0KCgkJCWZvciAoIHZhciBpID0gMCwgbCA9IGNoZWNrU2V0Lmxlbmd0aCwgZWxlbTsgaSA8IGw7IGkrKyApIHsKCQkJCWlmICggKGVsZW0gPSBjaGVja1NldFtpXSkgKSB7CgkJCQkJd2hpbGUgKCAoZWxlbSA9IGVsZW0ucHJldmlvdXNTaWJsaW5nKSAmJiBlbGVtLm5vZGVUeXBlICE9PSAxICkge30KCgkJCQkJY2hlY2tTZXRbaV0gPSBpc1BhcnRTdHJOb3RUYWcgfHwgZWxlbSAmJiBlbGVtLm5vZGVOYW1lID09PSBwYXJ0ID8KCQkJCQkJZWxlbSB8fCBmYWxzZSA6CgkJCQkJCWVsZW0gPT09IHBhcnQ7CgkJCQl9CgkJCX0KCgkJCWlmICggaXNQYXJ0U3RyTm90VGFnICkgewoJCQkJU2l6emxlLmZpbHRlciggcGFydCwgY2hlY2tTZXQsIHRydWUgKTsKCQkJfQoJCX0sCgkJIj4iOiBmdW5jdGlvbihjaGVja1NldCwgcGFydCwgaXNYTUwpewoJCQl2YXIgaXNQYXJ0U3RyID0gdHlwZW9mIHBhcnQgPT09ICJzdHJpbmciOwoKCQkJaWYgKCBpc1BhcnRTdHIgJiYgIS9cVy8udGVzdChwYXJ0KSApIHsKCQkJCXBhcnQgPSBpc1hNTCA/IHBhcnQgOiBwYXJ0LnRvVXBwZXJDYXNlKCk7CgoJCQkJZm9yICggdmFyIGkgPSAwLCBsID0gY2hlY2tTZXQubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCQkJCXZhciBlbGVtID0gY2hlY2tTZXRbaV07CgkJCQkJaWYgKCBlbGVtICkgewoJCQkJCQl2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlOwoJCQkJCQljaGVja1NldFtpXSA9IHBhcmVudC5ub2RlTmFtZSA9PT0gcGFydCA/IHBhcmVudCA6IGZhbHNlOwoJCQkJCX0KCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWZvciAoIHZhciBpID0gMCwgbCA9IGNoZWNrU2V0Lmxlbmd0aDsgaSA8IGw7IGkrKyApIHsKCQkJCQl2YXIgZWxlbSA9IGNoZWNrU2V0W2ldOwoJCQkJCWlmICggZWxlbSApIHsKCQkJCQkJY2hlY2tTZXRbaV0gPSBpc1BhcnRTdHIgPwoJCQkJCQkJZWxlbS5wYXJlbnROb2RlIDoKCQkJCQkJCWVsZW0ucGFyZW50Tm9kZSA9PT0gcGFydDsKCQkJCQl9CgkJCQl9CgoJCQkJaWYgKCBpc1BhcnRTdHIgKSB7CgkJCQkJU2l6emxlLmZpbHRlciggcGFydCwgY2hlY2tTZXQsIHRydWUgKTsKCQkJCX0KCQkJfQoJCX0sCgkJIiI6IGZ1bmN0aW9uKGNoZWNrU2V0LCBwYXJ0LCBpc1hNTCl7CgkJCXZhciBkb25lTmFtZSA9IGRvbmUrKywgY2hlY2tGbiA9IGRpckNoZWNrOwoKCQkJaWYgKCAhcGFydC5tYXRjaCgvXFcvKSApIHsKCQkJCXZhciBub2RlQ2hlY2sgPSBwYXJ0ID0gaXNYTUwgPyBwYXJ0IDogcGFydC50b1VwcGVyQ2FzZSgpOwoJCQkJY2hlY2tGbiA9IGRpck5vZGVDaGVjazsKCQkJfQoKCQkJY2hlY2tGbigicGFyZW50Tm9kZSIsIHBhcnQsIGRvbmVOYW1lLCBjaGVja1NldCwgbm9kZUNoZWNrLCBpc1hNTCk7CgkJfSwKCQkifiI6IGZ1bmN0aW9uKGNoZWNrU2V0LCBwYXJ0LCBpc1hNTCl7CgkJCXZhciBkb25lTmFtZSA9IGRvbmUrKywgY2hlY2tGbiA9IGRpckNoZWNrOwoKCQkJaWYgKCB0eXBlb2YgcGFydCA9PT0gInN0cmluZyIgJiYgIXBhcnQubWF0Y2goL1xXLykgKSB7CgkJCQl2YXIgbm9kZUNoZWNrID0gcGFydCA9IGlzWE1MID8gcGFydCA6IHBhcnQudG9VcHBlckNhc2UoKTsKCQkJCWNoZWNrRm4gPSBkaXJOb2RlQ2hlY2s7CgkJCX0KCgkJCWNoZWNrRm4oInByZXZpb3VzU2libGluZyIsIHBhcnQsIGRvbmVOYW1lLCBjaGVja1NldCwgbm9kZUNoZWNrLCBpc1hNTCk7CgkJfQoJfSwKCWZpbmQ6IHsKCQlJRDogZnVuY3Rpb24obWF0Y2gsIGNvbnRleHQsIGlzWE1MKXsKCQkJaWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50QnlJZCAhPT0gInVuZGVmaW5lZCIgJiYgIWlzWE1MICkgewoJCQkJdmFyIG0gPSBjb250ZXh0LmdldEVsZW1lbnRCeUlkKG1hdGNoWzFdKTsKCQkJCXJldHVybiBtID8gW21dIDogW107CgkJCX0KCQl9LAoJCU5BTUU6IGZ1bmN0aW9uKG1hdGNoLCBjb250ZXh0LCBpc1hNTCl7CgkJCWlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeU5hbWUgIT09ICJ1bmRlZmluZWQiICkgewoJCQkJdmFyIHJldCA9IFtdLCByZXN1bHRzID0gY29udGV4dC5nZXRFbGVtZW50c0J5TmFtZShtYXRjaFsxXSk7CgoJCQkJZm9yICggdmFyIGkgPSAwLCBsID0gcmVzdWx0cy5sZW5ndGg7IGkgPCBsOyBpKysgKSB7CgkJCQkJaWYgKCByZXN1bHRzW2ldLmdldEF0dHJpYnV0ZSgibmFtZSIpID09PSBtYXRjaFsxXSApIHsKCQkJCQkJcmV0LnB1c2goIHJlc3VsdHNbaV0gKTsKCQkJCQl9CgkJCQl9CgoJCQkJcmV0dXJuIHJldC5sZW5ndGggPT09IDAgPyBudWxsIDogcmV0OwoJCQl9CgkJfSwKCQlUQUc6IGZ1bmN0aW9uKG1hdGNoLCBjb250ZXh0KXsKCQkJcmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUobWF0Y2hbMV0pOwoJCX0KCX0sCglwcmVGaWx0ZXI6IHsKCQlDTEFTUzogZnVuY3Rpb24obWF0Y2gsIGN1ckxvb3AsIGlucGxhY2UsIHJlc3VsdCwgbm90LCBpc1hNTCl7CgkJCW1hdGNoID0gIiAiICsgbWF0Y2hbMV0ucmVwbGFjZSgvXFwvZywgIiIpICsgIiAiOwoKCQkJaWYgKCBpc1hNTCApIHsKCQkJCXJldHVybiBtYXRjaDsKCQkJfQoKCQkJZm9yICggdmFyIGkgPSAwLCBlbGVtOyAoZWxlbSA9IGN1ckxvb3BbaV0pICE9IG51bGw7IGkrKyApIHsKCQkJCWlmICggZWxlbSApIHsKCQkJCQlpZiAoIG5vdCBeIChlbGVtLmNsYXNzTmFtZSAmJiAoIiAiICsgZWxlbS5jbGFzc05hbWUgKyAiICIpLmluZGV4T2YobWF0Y2gpID49IDApICkgewoJCQkJCQlpZiAoICFpbnBsYWNlICkKCQkJCQkJCXJlc3VsdC5wdXNoKCBlbGVtICk7CgkJCQkJfSBlbHNlIGlmICggaW5wbGFjZSApIHsKCQkJCQkJY3VyTG9vcFtpXSA9IGZhbHNlOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJcmV0dXJuIGZhbHNlOwoJCX0sCgkJSUQ6IGZ1bmN0aW9uKG1hdGNoKXsKCQkJcmV0dXJuIG1hdGNoWzFdLnJlcGxhY2UoL1xcL2csICIiKTsKCQl9LAoJCVRBRzogZnVuY3Rpb24obWF0Y2gsIGN1ckxvb3ApewoJCQlmb3IgKCB2YXIgaSA9IDA7IGN1ckxvb3BbaV0gPT09IGZhbHNlOyBpKysgKXt9CgkJCXJldHVybiBjdXJMb29wW2ldICYmIGlzWE1MKGN1ckxvb3BbaV0pID8gbWF0Y2hbMV0gOiBtYXRjaFsxXS50b1VwcGVyQ2FzZSgpOwoJCX0sCgkJQ0hJTEQ6IGZ1bmN0aW9uKG1hdGNoKXsKCQkJaWYgKCBtYXRjaFsxXSA9PSAibnRoIiApIHsKCQkJCS8vIHBhcnNlIGVxdWF0aW9ucyBsaWtlICdldmVuJywgJ29kZCcsICc1JywgJzJuJywgJzNuKzInLCAnNG4tMScsICctbis2JwoJCQkJdmFyIHRlc3QgPSAvKC0/KShcZCopbigoPzpcK3wtKT9cZCopLy5leGVjKAoJCQkJCW1hdGNoWzJdID09ICJldmVuIiAmJiAiMm4iIHx8IG1hdGNoWzJdID09ICJvZGQiICYmICIybisxIiB8fAoJCQkJCSEvXEQvLnRlc3QoIG1hdGNoWzJdICkgJiYgIjBuKyIgKyBtYXRjaFsyXSB8fCBtYXRjaFsyXSk7CgoJCQkJLy8gY2FsY3VsYXRlIHRoZSBudW1iZXJzIChmaXJzdCluKyhsYXN0KSBpbmNsdWRpbmcgaWYgdGhleSBhcmUgbmVnYXRpdmUKCQkJCW1hdGNoWzJdID0gKHRlc3RbMV0gKyAodGVzdFsyXSB8fCAxKSkgLSAwOwoJCQkJbWF0Y2hbM10gPSB0ZXN0WzNdIC0gMDsKCQkJfQoKCQkJLy8gVE9ETzogTW92ZSB0byBub3JtYWwgY2FjaGluZyBzeXN0ZW0KCQkJbWF0Y2hbMF0gPSBkb25lKys7CgoJCQlyZXR1cm4gbWF0Y2g7CgkJfSwKCQlBVFRSOiBmdW5jdGlvbihtYXRjaCwgY3VyTG9vcCwgaW5wbGFjZSwgcmVzdWx0LCBub3QsIGlzWE1MKXsKCQkJdmFyIG5hbWUgPSBtYXRjaFsxXS5yZXBsYWNlKC9cXC9nLCAiIik7CgkJCQoJCQlpZiAoICFpc1hNTCAmJiBFeHByLmF0dHJNYXBbbmFtZV0gKSB7CgkJCQltYXRjaFsxXSA9IEV4cHIuYXR0ck1hcFtuYW1lXTsKCQkJfQoKCQkJaWYgKCBtYXRjaFsyXSA9PT0gIn49IiApIHsKCQkJCW1hdGNoWzRdID0gIiAiICsgbWF0Y2hbNF0gKyAiICI7CgkJCX0KCgkJCXJldHVybiBtYXRjaDsKCQl9LAoJCVBTRVVETzogZnVuY3Rpb24obWF0Y2gsIGN1ckxvb3AsIGlucGxhY2UsIHJlc3VsdCwgbm90KXsKCQkJaWYgKCBtYXRjaFsxXSA9PT0gIm5vdCIgKSB7CgkJCQkvLyBJZiB3ZSdyZSBkZWFsaW5nIHdpdGggYSBjb21wbGV4IGV4cHJlc3Npb24sIG9yIGEgc2ltcGxlIG9uZQoJCQkJaWYgKCBtYXRjaFszXS5tYXRjaChjaHVua2VyKS5sZW5ndGggPiAxIHx8IC9eXHcvLnRlc3QobWF0Y2hbM10pICkgewoJCQkJCW1hdGNoWzNdID0gU2l6emxlKG1hdGNoWzNdLCBudWxsLCBudWxsLCBjdXJMb29wKTsKCQkJCX0gZWxzZSB7CgkJCQkJdmFyIHJldCA9IFNpenpsZS5maWx0ZXIobWF0Y2hbM10sIGN1ckxvb3AsIGlucGxhY2UsIHRydWUgXiBub3QpOwoJCQkJCWlmICggIWlucGxhY2UgKSB7CgkJCQkJCXJlc3VsdC5wdXNoLmFwcGx5KCByZXN1bHQsIHJldCApOwoJCQkJCX0KCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgkJCX0gZWxzZSBpZiAoIEV4cHIubWF0Y2guUE9TLnRlc3QoIG1hdGNoWzBdICkgfHwgRXhwci5tYXRjaC5DSElMRC50ZXN0KCBtYXRjaFswXSApICkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQkJCgkJCXJldHVybiBtYXRjaDsKCQl9LAoJCVBPUzogZnVuY3Rpb24obWF0Y2gpewoJCQltYXRjaC51bnNoaWZ0KCB0cnVlICk7CgkJCXJldHVybiBtYXRjaDsKCQl9Cgl9LAoJZmlsdGVyczogewoJCWVuYWJsZWQ6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gZmFsc2UgJiYgZWxlbS50eXBlICE9PSAiaGlkZGVuIjsKCQl9LAoJCWRpc2FibGVkOiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IHRydWU7CgkJfSwKCQljaGVja2VkOiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuIGVsZW0uY2hlY2tlZCA9PT0gdHJ1ZTsKCQl9LAoJCXNlbGVjdGVkOiBmdW5jdGlvbihlbGVtKXsKCQkJLy8gQWNjZXNzaW5nIHRoaXMgcHJvcGVydHkgbWFrZXMgc2VsZWN0ZWQtYnktZGVmYXVsdAoJCQkvLyBvcHRpb25zIGluIFNhZmFyaSB3b3JrIHByb3Blcmx5CgkJCWVsZW0ucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4OwoJCQlyZXR1cm4gZWxlbS5zZWxlY3RlZCA9PT0gdHJ1ZTsKCQl9LAoJCXBhcmVudDogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAhIWVsZW0uZmlyc3RDaGlsZDsKCQl9LAoJCWVtcHR5OiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuICFlbGVtLmZpcnN0Q2hpbGQ7CgkJfSwKCQloYXM6IGZ1bmN0aW9uKGVsZW0sIGksIG1hdGNoKXsKCQkJcmV0dXJuICEhU2l6emxlKCBtYXRjaFszXSwgZWxlbSApLmxlbmd0aDsKCQl9LAoJCWhlYWRlcjogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAvaFxkL2kudGVzdCggZWxlbS5ub2RlTmFtZSApOwoJCX0sCgkJdGV4dDogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAidGV4dCIgPT09IGVsZW0udHlwZTsKCQl9LAoJCXJhZGlvOiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuICJyYWRpbyIgPT09IGVsZW0udHlwZTsKCQl9LAoJCWNoZWNrYm94OiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuICJjaGVja2JveCIgPT09IGVsZW0udHlwZTsKCQl9LAoJCWZpbGU6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gImZpbGUiID09PSBlbGVtLnR5cGU7CgkJfSwKCQlwYXNzd29yZDogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAicGFzc3dvcmQiID09PSBlbGVtLnR5cGU7CgkJfSwKCQlzdWJtaXQ6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gInN1Ym1pdCIgPT09IGVsZW0udHlwZTsKCQl9LAoJCWltYWdlOiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuICJpbWFnZSIgPT09IGVsZW0udHlwZTsKCQl9LAoJCXJlc2V0OiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuICJyZXNldCIgPT09IGVsZW0udHlwZTsKCQl9LAoJCWJ1dHRvbjogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAiYnV0dG9uIiA9PT0gZWxlbS50eXBlIHx8IGVsZW0ubm9kZU5hbWUudG9VcHBlckNhc2UoKSA9PT0gIkJVVFRPTiI7CgkJfSwKCQlpbnB1dDogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAvaW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbi9pLnRlc3QoZWxlbS5ub2RlTmFtZSk7CgkJfQoJfSwKCXNldEZpbHRlcnM6IHsKCQlmaXJzdDogZnVuY3Rpb24oZWxlbSwgaSl7CgkJCXJldHVybiBpID09PSAwOwoJCX0sCgkJbGFzdDogZnVuY3Rpb24oZWxlbSwgaSwgbWF0Y2gsIGFycmF5KXsKCQkJcmV0dXJuIGkgPT09IGFycmF5Lmxlbmd0aCAtIDE7CgkJfSwKCQlldmVuOiBmdW5jdGlvbihlbGVtLCBpKXsKCQkJcmV0dXJuIGkgJSAyID09PSAwOwoJCX0sCgkJb2RkOiBmdW5jdGlvbihlbGVtLCBpKXsKCQkJcmV0dXJuIGkgJSAyID09PSAxOwoJCX0sCgkJbHQ6IGZ1bmN0aW9uKGVsZW0sIGksIG1hdGNoKXsKCQkJcmV0dXJuIGkgPCBtYXRjaFszXSAtIDA7CgkJfSwKCQlndDogZnVuY3Rpb24oZWxlbSwgaSwgbWF0Y2gpewoJCQlyZXR1cm4gaSA+IG1hdGNoWzNdIC0gMDsKCQl9LAoJCW50aDogZnVuY3Rpb24oZWxlbSwgaSwgbWF0Y2gpewoJCQlyZXR1cm4gbWF0Y2hbM10gLSAwID09IGk7CgkJfSwKCQllcTogZnVuY3Rpb24oZWxlbSwgaSwgbWF0Y2gpewoJCQlyZXR1cm4gbWF0Y2hbM10gLSAwID09IGk7CgkJfQoJfSwKCWZpbHRlcjogewoJCVBTRVVETzogZnVuY3Rpb24oZWxlbSwgbWF0Y2gsIGksIGFycmF5KXsKCQkJdmFyIG5hbWUgPSBtYXRjaFsxXSwgZmlsdGVyID0gRXhwci5maWx0ZXJzWyBuYW1lIF07CgoJCQlpZiAoIGZpbHRlciApIHsKCQkJCXJldHVybiBmaWx0ZXIoIGVsZW0sIGksIG1hdGNoLCBhcnJheSApOwoJCQl9IGVsc2UgaWYgKCBuYW1lID09PSAiY29udGFpbnMiICkgewoJCQkJcmV0dXJuIChlbGVtLnRleHRDb250ZW50IHx8IGVsZW0uaW5uZXJUZXh0IHx8ICIiKS5pbmRleE9mKG1hdGNoWzNdKSA+PSAwOwoJCQl9IGVsc2UgaWYgKCBuYW1lID09PSAibm90IiApIHsKCQkJCXZhciBub3QgPSBtYXRjaFszXTsKCgkJCQlmb3IgKCB2YXIgaSA9IDAsIGwgPSBub3QubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCQkJCWlmICggbm90W2ldID09PSBlbGVtICkgewoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJfQoJCQkJfQoKCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJfSwKCQlDSElMRDogZnVuY3Rpb24oZWxlbSwgbWF0Y2gpewoJCQl2YXIgdHlwZSA9IG1hdGNoWzFdLCBub2RlID0gZWxlbTsKCQkJc3dpdGNoICh0eXBlKSB7CgkJCQljYXNlICdvbmx5JzoKCQkJCWNhc2UgJ2ZpcnN0JzoKCQkJCQl3aGlsZSAobm9kZSA9IG5vZGUucHJldmlvdXNTaWJsaW5nKSAgewoJCQkJCQlpZiAoIG5vZGUubm9kZVR5cGUgPT09IDEgKSByZXR1cm4gZmFsc2U7CgkJCQkJfQoJCQkJCWlmICggdHlwZSA9PSAnZmlyc3QnKSByZXR1cm4gdHJ1ZTsKCQkJCQlub2RlID0gZWxlbTsKCQkJCWNhc2UgJ2xhc3QnOgoJCQkJCXdoaWxlIChub2RlID0gbm9kZS5uZXh0U2libGluZykgIHsKCQkJCQkJaWYgKCBub2RlLm5vZGVUeXBlID09PSAxICkgcmV0dXJuIGZhbHNlOwoJCQkJCX0KCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCWNhc2UgJ250aCc6CgkJCQkJdmFyIGZpcnN0ID0gbWF0Y2hbMl0sIGxhc3QgPSBtYXRjaFszXTsKCgkJCQkJaWYgKCBmaXJzdCA9PSAxICYmIGxhc3QgPT0gMCApIHsKCQkJCQkJcmV0dXJuIHRydWU7CgkJCQkJfQoJCQkJCQoJCQkJCXZhciBkb25lTmFtZSA9IG1hdGNoWzBdLAoJCQkJCQlwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7CgkKCQkJCQlpZiAoIHBhcmVudCAmJiAocGFyZW50LnNpemNhY2hlICE9PSBkb25lTmFtZSB8fCAhZWxlbS5ub2RlSW5kZXgpICkgewoJCQkJCQl2YXIgY291bnQgPSAwOwoJCQkJCQlmb3IgKCBub2RlID0gcGFyZW50LmZpcnN0Q2hpbGQ7IG5vZGU7IG5vZGUgPSBub2RlLm5leHRTaWJsaW5nICkgewoJCQkJCQkJaWYgKCBub2RlLm5vZGVUeXBlID09PSAxICkgewoJCQkJCQkJCW5vZGUubm9kZUluZGV4ID0gKytjb3VudDsKCQkJCQkJCX0KCQkJCQkJfSAKCQkJCQkJcGFyZW50LnNpemNhY2hlID0gZG9uZU5hbWU7CgkJCQkJfQoJCQkJCQoJCQkJCXZhciBkaWZmID0gZWxlbS5ub2RlSW5kZXggLSBsYXN0OwoJCQkJCWlmICggZmlyc3QgPT0gMCApIHsKCQkJCQkJcmV0dXJuIGRpZmYgPT0gMDsKCQkJCQl9IGVsc2UgewoJCQkJCQlyZXR1cm4gKCBkaWZmICUgZmlyc3QgPT0gMCAmJiBkaWZmIC8gZmlyc3QgPj0gMCApOwoJCQkJCX0KCQkJfQoJCX0sCgkJSUQ6IGZ1bmN0aW9uKGVsZW0sIG1hdGNoKXsKCQkJcmV0dXJuIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgZWxlbS5nZXRBdHRyaWJ1dGUoImlkIikgPT09IG1hdGNoOwoJCX0sCgkJVEFHOiBmdW5jdGlvbihlbGVtLCBtYXRjaCl7CgkJCXJldHVybiAobWF0Y2ggPT09ICIqIiAmJiBlbGVtLm5vZGVUeXBlID09PSAxKSB8fCBlbGVtLm5vZGVOYW1lID09PSBtYXRjaDsKCQl9LAoJCUNMQVNTOiBmdW5jdGlvbihlbGVtLCBtYXRjaCl7CgkJCXJldHVybiAoIiAiICsgKGVsZW0uY2xhc3NOYW1lIHx8IGVsZW0uZ2V0QXR0cmlidXRlKCJjbGFzcyIpKSArICIgIikKCQkJCS5pbmRleE9mKCBtYXRjaCApID4gLTE7CgkJfSwKCQlBVFRSOiBmdW5jdGlvbihlbGVtLCBtYXRjaCl7CgkJCXZhciBuYW1lID0gbWF0Y2hbMV0sCgkJCQlyZXN1bHQgPSBFeHByLmF0dHJIYW5kbGVbIG5hbWUgXSA/CgkJCQkJRXhwci5hdHRySGFuZGxlWyBuYW1lIF0oIGVsZW0gKSA6CgkJCQkJZWxlbVsgbmFtZSBdICE9IG51bGwgPwoJCQkJCQllbGVtWyBuYW1lIF0gOgoJCQkJCQllbGVtLmdldEF0dHJpYnV0ZSggbmFtZSApLAoJCQkJdmFsdWUgPSByZXN1bHQgKyAiIiwKCQkJCXR5cGUgPSBtYXRjaFsyXSwKCQkJCWNoZWNrID0gbWF0Y2hbNF07CgoJCQlyZXR1cm4gcmVzdWx0ID09IG51bGwgPwoJCQkJdHlwZSA9PT0gIiE9IiA6CgkJCQl0eXBlID09PSAiPSIgPwoJCQkJdmFsdWUgPT09IGNoZWNrIDoKCQkJCXR5cGUgPT09ICIqPSIgPwoJCQkJdmFsdWUuaW5kZXhPZihjaGVjaykgPj0gMCA6CgkJCQl0eXBlID09PSAifj0iID8KCQkJCSgiICIgKyB2YWx1ZSArICIgIikuaW5kZXhPZihjaGVjaykgPj0gMCA6CgkJCQkhY2hlY2sgPwoJCQkJdmFsdWUgJiYgcmVzdWx0ICE9PSBmYWxzZSA6CgkJCQl0eXBlID09PSAiIT0iID8KCQkJCXZhbHVlICE9IGNoZWNrIDoKCQkJCXR5cGUgPT09ICJePSIgPwoJCQkJdmFsdWUuaW5kZXhPZihjaGVjaykgPT09IDAgOgoJCQkJdHlwZSA9PT0gIiQ9IiA/CgkJCQl2YWx1ZS5zdWJzdHIodmFsdWUubGVuZ3RoIC0gY2hlY2subGVuZ3RoKSA9PT0gY2hlY2sgOgoJCQkJdHlwZSA9PT0gInw9IiA/CgkJCQl2YWx1ZSA9PT0gY2hlY2sgfHwgdmFsdWUuc3Vic3RyKDAsIGNoZWNrLmxlbmd0aCArIDEpID09PSBjaGVjayArICItIiA6CgkJCQlmYWxzZTsKCQl9LAoJCVBPUzogZnVuY3Rpb24oZWxlbSwgbWF0Y2gsIGksIGFycmF5KXsKCQkJdmFyIG5hbWUgPSBtYXRjaFsyXSwgZmlsdGVyID0gRXhwci5zZXRGaWx0ZXJzWyBuYW1lIF07CgoJCQlpZiAoIGZpbHRlciApIHsKCQkJCXJldHVybiBmaWx0ZXIoIGVsZW0sIGksIG1hdGNoLCBhcnJheSApOwoJCQl9CgkJfQoJfQp9OwoKdmFyIG9yaWdQT1MgPSBFeHByLm1hdGNoLlBPUzsKCmZvciAoIHZhciB0eXBlIGluIEV4cHIubWF0Y2ggKSB7CglFeHByLm1hdGNoWyB0eXBlIF0gPSBuZXcgUmVnRXhwKCBFeHByLm1hdGNoWyB0eXBlIF0uc291cmNlICsgLyg/IVteXFtdKlxdKSg/IVteXChdKlwpKS8uc291cmNlICk7Cn0KCnZhciBtYWtlQXJyYXkgPSBmdW5jdGlvbihhcnJheSwgcmVzdWx0cykgewoJYXJyYXkgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCggYXJyYXkgKTsKCglpZiAoIHJlc3VsdHMgKSB7CgkJcmVzdWx0cy5wdXNoLmFwcGx5KCByZXN1bHRzLCBhcnJheSApOwoJCXJldHVybiByZXN1bHRzOwoJfQoJCglyZXR1cm4gYXJyYXk7Cn07CgovLyBQZXJmb3JtIGEgc2ltcGxlIGNoZWNrIHRvIGRldGVybWluZSBpZiB0aGUgYnJvd3NlciBpcyBjYXBhYmxlIG9mCi8vIGNvbnZlcnRpbmcgYSBOb2RlTGlzdCB0byBhbiBhcnJheSB1c2luZyBidWlsdGluIG1ldGhvZHMuCnRyeSB7CglBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCggZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNoaWxkTm9kZXMgKTsKCi8vIFByb3ZpZGUgYSBmYWxsYmFjayBtZXRob2QgaWYgaXQgZG9lcyBub3Qgd29yawp9IGNhdGNoKGUpewoJbWFrZUFycmF5ID0gZnVuY3Rpb24oYXJyYXksIHJlc3VsdHMpIHsKCQl2YXIgcmV0ID0gcmVzdWx0cyB8fCBbXTsKCgkJaWYgKCB0b1N0cmluZy5jYWxsKGFycmF5KSA9PT0gIltvYmplY3QgQXJyYXldIiApIHsKCQkJQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoIHJldCwgYXJyYXkgKTsKCQl9IGVsc2UgewoJCQlpZiAoIHR5cGVvZiBhcnJheS5sZW5ndGggPT09ICJudW1iZXIiICkgewoJCQkJZm9yICggdmFyIGkgPSAwLCBsID0gYXJyYXkubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCQkJCXJldC5wdXNoKCBhcnJheVtpXSApOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJZm9yICggdmFyIGkgPSAwOyBhcnJheVtpXTsgaSsrICkgewoJCQkJCXJldC5wdXNoKCBhcnJheVtpXSApOwoJCQkJfQoJCQl9CgkJfQoKCQlyZXR1cm4gcmV0OwoJfTsKfQoKdmFyIHNvcnRPcmRlcjsKCmlmICggZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uICkgewoJc29ydE9yZGVyID0gZnVuY3Rpb24oIGEsIGIgKSB7CgkJdmFyIHJldCA9IGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oYikgJiA0ID8gLTEgOiBhID09PSBiID8gMCA6IDE7CgkJaWYgKCByZXQgPT09IDAgKSB7CgkJCWhhc0R1cGxpY2F0ZSA9IHRydWU7CgkJfQoJCXJldHVybiByZXQ7Cgl9Owp9IGVsc2UgaWYgKCAic291cmNlSW5kZXgiIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCApIHsKCXNvcnRPcmRlciA9IGZ1bmN0aW9uKCBhLCBiICkgewoJCXZhciByZXQgPSBhLnNvdXJjZUluZGV4IC0gYi5zb3VyY2VJbmRleDsKCQlpZiAoIHJldCA9PT0gMCApIHsKCQkJaGFzRHVwbGljYXRlID0gdHJ1ZTsKCQl9CgkJcmV0dXJuIHJldDsKCX07Cn0gZWxzZSBpZiAoIGRvY3VtZW50LmNyZWF0ZVJhbmdlICkgewoJc29ydE9yZGVyID0gZnVuY3Rpb24oIGEsIGIgKSB7CgkJdmFyIGFSYW5nZSA9IGEub3duZXJEb2N1bWVudC5jcmVhdGVSYW5nZSgpLCBiUmFuZ2UgPSBiLm93bmVyRG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTsKCQlhUmFuZ2Uuc2V0U3RhcnQoYSwgMCk7CgkJYVJhbmdlLnNldEVuZChhLCAwKTsKCQliUmFuZ2Uuc2V0U3RhcnQoYiwgMCk7CgkJYlJhbmdlLnNldEVuZChiLCAwKTsKCQl2YXIgcmV0ID0gYVJhbmdlLmNvbXBhcmVCb3VuZGFyeVBvaW50cyhSYW5nZS5TVEFSVF9UT19FTkQsIGJSYW5nZSk7CgkJaWYgKCByZXQgPT09IDAgKSB7CgkJCWhhc0R1cGxpY2F0ZSA9IHRydWU7CgkJfQoJCXJldHVybiByZXQ7Cgl9Owp9CgovLyBDaGVjayB0byBzZWUgaWYgdGhlIGJyb3dzZXIgcmV0dXJucyBlbGVtZW50cyBieSBuYW1lIHdoZW4KLy8gcXVlcnlpbmcgYnkgZ2V0RWxlbWVudEJ5SWQgKGFuZCBwcm92aWRlIGEgd29ya2Fyb3VuZCkKKGZ1bmN0aW9uKCl7CgkvLyBXZSdyZSBnb2luZyB0byBpbmplY3QgYSBmYWtlIGlucHV0IGVsZW1lbnQgd2l0aCBhIHNwZWNpZmllZCBuYW1lCgl2YXIgZm9ybSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpLAoJCWlkID0gInNjcmlwdCIgKyAobmV3IERhdGUpLmdldFRpbWUoKTsKCWZvcm0uaW5uZXJIVE1MID0gIjxhIG5hbWU9JyIgKyBpZCArICInLz4iOwoKCS8vIEluamVjdCBpdCBpbnRvIHRoZSByb290IGVsZW1lbnQsIGNoZWNrIGl0cyBzdGF0dXMsIGFuZCByZW1vdmUgaXQgcXVpY2tseQoJdmFyIHJvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7Cglyb290Lmluc2VydEJlZm9yZSggZm9ybSwgcm9vdC5maXJzdENoaWxkICk7CgoJLy8gVGhlIHdvcmthcm91bmQgaGFzIHRvIGRvIGFkZGl0aW9uYWwgY2hlY2tzIGFmdGVyIGEgZ2V0RWxlbWVudEJ5SWQKCS8vIFdoaWNoIHNsb3dzIHRoaW5ncyBkb3duIGZvciBvdGhlciBicm93c2VycyAoaGVuY2UgdGhlIGJyYW5jaGluZykKCWlmICggISFkb2N1bWVudC5nZXRFbGVtZW50QnlJZCggaWQgKSApIHsKCQlFeHByLmZpbmQuSUQgPSBmdW5jdGlvbihtYXRjaCwgY29udGV4dCwgaXNYTUwpewoJCQlpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRCeUlkICE9PSAidW5kZWZpbmVkIiAmJiAhaXNYTUwgKSB7CgkJCQl2YXIgbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQobWF0Y2hbMV0pOwoJCQkJcmV0dXJuIG0gPyBtLmlkID09PSBtYXRjaFsxXSB8fCB0eXBlb2YgbS5nZXRBdHRyaWJ1dGVOb2RlICE9PSAidW5kZWZpbmVkIiAmJiBtLmdldEF0dHJpYnV0ZU5vZGUoImlkIikubm9kZVZhbHVlID09PSBtYXRjaFsxXSA/IFttXSA6IHVuZGVmaW5lZCA6IFtdOwoJCQl9CgkJfTsKCgkJRXhwci5maWx0ZXIuSUQgPSBmdW5jdGlvbihlbGVtLCBtYXRjaCl7CgkJCXZhciBub2RlID0gdHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlTm9kZSAhPT0gInVuZGVmaW5lZCIgJiYgZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKCJpZCIpOwoJCQlyZXR1cm4gZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiBub2RlICYmIG5vZGUubm9kZVZhbHVlID09PSBtYXRjaDsKCQl9OwoJfQoKCXJvb3QucmVtb3ZlQ2hpbGQoIGZvcm0gKTsKfSkoKTsKCihmdW5jdGlvbigpewoJLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSBicm93c2VyIHJldHVybnMgb25seSBlbGVtZW50cwoJLy8gd2hlbiBkb2luZyBnZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpCgoJLy8gQ3JlYXRlIGEgZmFrZSBlbGVtZW50Cgl2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CglkaXYuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUNvbW1lbnQoIiIpICk7CgoJLy8gTWFrZSBzdXJlIG5vIGNvbW1lbnRzIGFyZSBmb3VuZAoJaWYgKCBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIioiKS5sZW5ndGggPiAwICkgewoJCUV4cHIuZmluZC5UQUcgPSBmdW5jdGlvbihtYXRjaCwgY29udGV4dCl7CgkJCXZhciByZXN1bHRzID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZShtYXRjaFsxXSk7CgoJCQkvLyBGaWx0ZXIgb3V0IHBvc3NpYmxlIGNvbW1lbnRzCgkJCWlmICggbWF0Y2hbMV0gPT09ICIqIiApIHsKCQkJCXZhciB0bXAgPSBbXTsKCgkJCQlmb3IgKCB2YXIgaSA9IDA7IHJlc3VsdHNbaV07IGkrKyApIHsKCQkJCQlpZiAoIHJlc3VsdHNbaV0ubm9kZVR5cGUgPT09IDEgKSB7CgkJCQkJCXRtcC5wdXNoKCByZXN1bHRzW2ldICk7CgkJCQkJfQoJCQkJfQoKCQkJCXJlc3VsdHMgPSB0bXA7CgkJCX0KCgkJCXJldHVybiByZXN1bHRzOwoJCX07Cgl9CgoJLy8gQ2hlY2sgdG8gc2VlIGlmIGFuIGF0dHJpYnV0ZSByZXR1cm5zIG5vcm1hbGl6ZWQgaHJlZiBhdHRyaWJ1dGVzCglkaXYuaW5uZXJIVE1MID0gIjxhIGhyZWY9JyMnPjwvYT4iOwoJaWYgKCBkaXYuZmlyc3RDaGlsZCAmJiB0eXBlb2YgZGl2LmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlICE9PSAidW5kZWZpbmVkIiAmJgoJCQlkaXYuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoImhyZWYiKSAhPT0gIiMiICkgewoJCUV4cHIuYXR0ckhhbmRsZS5ocmVmID0gZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSgiaHJlZiIsIDIpOwoJCX07Cgl9Cn0pKCk7CgppZiAoIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwgKSAoZnVuY3Rpb24oKXsKCXZhciBvbGRTaXp6bGUgPSBTaXp6bGUsIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpOwoJZGl2LmlubmVySFRNTCA9ICI8cCBjbGFzcz0nVEVTVCc+PC9wPiI7CgoJLy8gU2FmYXJpIGNhbid0IGhhbmRsZSB1cHBlcmNhc2Ugb3IgdW5pY29kZSBjaGFyYWN0ZXJzIHdoZW4KCS8vIGluIHF1aXJrcyBtb2RlLgoJaWYgKCBkaXYucXVlcnlTZWxlY3RvckFsbCAmJiBkaXYucXVlcnlTZWxlY3RvckFsbCgiLlRFU1QiKS5sZW5ndGggPT09IDAgKSB7CgkJcmV0dXJuOwoJfQoJCglTaXp6bGUgPSBmdW5jdGlvbihxdWVyeSwgY29udGV4dCwgZXh0cmEsIHNlZWQpewoJCWNvbnRleHQgPSBjb250ZXh0IHx8IGRvY3VtZW50OwoKCQkvLyBPbmx5IHVzZSBxdWVyeVNlbGVjdG9yQWxsIG9uIG5vbi1YTUwgZG9jdW1lbnRzCgkJLy8gKElEIHNlbGVjdG9ycyBkb24ndCB3b3JrIGluIG5vbi1IVE1MIGRvY3VtZW50cykKCQlpZiAoICFzZWVkICYmIGNvbnRleHQubm9kZVR5cGUgPT09IDkgJiYgIWlzWE1MKGNvbnRleHQpICkgewoJCQl0cnkgewoJCQkJcmV0dXJuIG1ha2VBcnJheSggY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KSwgZXh0cmEgKTsKCQkJfSBjYXRjaChlKXt9CgkJfQoJCQoJCXJldHVybiBvbGRTaXp6bGUocXVlcnksIGNvbnRleHQsIGV4dHJhLCBzZWVkKTsKCX07CgoJZm9yICggdmFyIHByb3AgaW4gb2xkU2l6emxlICkgewoJCVNpenpsZVsgcHJvcCBdID0gb2xkU2l6emxlWyBwcm9wIF07Cgl9Cn0pKCk7CgppZiAoIGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgKSAoZnVuY3Rpb24oKXsKCXZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKCWRpdi5pbm5lckhUTUwgPSAiPGRpdiBjbGFzcz0ndGVzdCBlJz48L2Rpdj48ZGl2IGNsYXNzPSd0ZXN0Jz48L2Rpdj4iOwoKCS8vIE9wZXJhIGNhbid0IGZpbmQgYSBzZWNvbmQgY2xhc3NuYW1lIChpbiA5LjYpCglpZiAoIGRpdi5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCJlIikubGVuZ3RoID09PSAwICkKCQlyZXR1cm47CgoJLy8gU2FmYXJpIGNhY2hlcyBjbGFzcyBhdHRyaWJ1dGVzLCBkb2Vzbid0IGNhdGNoIGNoYW5nZXMgKGluIDMuMikKCWRpdi5sYXN0Q2hpbGQuY2xhc3NOYW1lID0gImUiOwoKCWlmICggZGl2LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoImUiKS5sZW5ndGggPT09IDEgKQoJCXJldHVybjsKCglFeHByLm9yZGVyLnNwbGljZSgxLCAwLCAiQ0xBU1MiKTsKCUV4cHIuZmluZC5DTEFTUyA9IGZ1bmN0aW9uKG1hdGNoLCBjb250ZXh0LCBpc1hNTCkgewoJCWlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAhPT0gInVuZGVmaW5lZCIgJiYgIWlzWE1MICkgewoJCQlyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKG1hdGNoWzFdKTsKCQl9Cgl9Owp9KSgpOwoKZnVuY3Rpb24gZGlyTm9kZUNoZWNrKCBkaXIsIGN1ciwgZG9uZU5hbWUsIGNoZWNrU2V0LCBub2RlQ2hlY2ssIGlzWE1MICkgewoJdmFyIHNpYkRpciA9IGRpciA9PSAicHJldmlvdXNTaWJsaW5nIiAmJiAhaXNYTUw7Cglmb3IgKCB2YXIgaSA9IDAsIGwgPSBjaGVja1NldC5sZW5ndGg7IGkgPCBsOyBpKysgKSB7CgkJdmFyIGVsZW0gPSBjaGVja1NldFtpXTsKCQlpZiAoIGVsZW0gKSB7CgkJCWlmICggc2liRGlyICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKXsKCQkJCWVsZW0uc2l6Y2FjaGUgPSBkb25lTmFtZTsKCQkJCWVsZW0uc2l6c2V0ID0gaTsKCQkJfQoJCQllbGVtID0gZWxlbVtkaXJdOwoJCQl2YXIgbWF0Y2ggPSBmYWxzZTsKCgkJCXdoaWxlICggZWxlbSApIHsKCQkJCWlmICggZWxlbS5zaXpjYWNoZSA9PT0gZG9uZU5hbWUgKSB7CgkJCQkJbWF0Y2ggPSBjaGVja1NldFtlbGVtLnNpenNldF07CgkJCQkJYnJlYWs7CgkJCQl9CgoJCQkJaWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICYmICFpc1hNTCApewoJCQkJCWVsZW0uc2l6Y2FjaGUgPSBkb25lTmFtZTsKCQkJCQllbGVtLnNpenNldCA9IGk7CgkJCQl9CgoJCQkJaWYgKCBlbGVtLm5vZGVOYW1lID09PSBjdXIgKSB7CgkJCQkJbWF0Y2ggPSBlbGVtOwoJCQkJCWJyZWFrOwoJCQkJfQoKCQkJCWVsZW0gPSBlbGVtW2Rpcl07CgkJCX0KCgkJCWNoZWNrU2V0W2ldID0gbWF0Y2g7CgkJfQoJfQp9CgpmdW5jdGlvbiBkaXJDaGVjayggZGlyLCBjdXIsIGRvbmVOYW1lLCBjaGVja1NldCwgbm9kZUNoZWNrLCBpc1hNTCApIHsKCXZhciBzaWJEaXIgPSBkaXIgPT0gInByZXZpb3VzU2libGluZyIgJiYgIWlzWE1MOwoJZm9yICggdmFyIGkgPSAwLCBsID0gY2hlY2tTZXQubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCXZhciBlbGVtID0gY2hlY2tTZXRbaV07CgkJaWYgKCBlbGVtICkgewoJCQlpZiAoIHNpYkRpciAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkgewoJCQkJZWxlbS5zaXpjYWNoZSA9IGRvbmVOYW1lOwoJCQkJZWxlbS5zaXpzZXQgPSBpOwoJCQl9CgkJCWVsZW0gPSBlbGVtW2Rpcl07CgkJCXZhciBtYXRjaCA9IGZhbHNlOwoKCQkJd2hpbGUgKCBlbGVtICkgewoJCQkJaWYgKCBlbGVtLnNpemNhY2hlID09PSBkb25lTmFtZSApIHsKCQkJCQltYXRjaCA9IGNoZWNrU2V0W2VsZW0uc2l6c2V0XTsKCQkJCQlicmVhazsKCQkJCX0KCgkJCQlpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7CgkJCQkJaWYgKCAhaXNYTUwgKSB7CgkJCQkJCWVsZW0uc2l6Y2FjaGUgPSBkb25lTmFtZTsKCQkJCQkJZWxlbS5zaXpzZXQgPSBpOwoJCQkJCX0KCQkJCQlpZiAoIHR5cGVvZiBjdXIgIT09ICJzdHJpbmciICkgewoJCQkJCQlpZiAoIGVsZW0gPT09IGN1ciApIHsKCQkJCQkJCW1hdGNoID0gdHJ1ZTsKCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgoJCQkJCX0gZWxzZSBpZiAoIFNpenpsZS5maWx0ZXIoIGN1ciwgW2VsZW1dICkubGVuZ3RoID4gMCApIHsKCQkJCQkJbWF0Y2ggPSBlbGVtOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgoJCQkJZWxlbSA9IGVsZW1bZGlyXTsKCQkJfQoKCQkJY2hlY2tTZXRbaV0gPSBtYXRjaDsKCQl9Cgl9Cn0KCnZhciBjb250YWlucyA9IGRvY3VtZW50LmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uID8gIGZ1bmN0aW9uKGEsIGIpewoJcmV0dXJuIGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oYikgJiAxNjsKfSA6IGZ1bmN0aW9uKGEsIGIpewoJcmV0dXJuIGEgIT09IGIgJiYgKGEuY29udGFpbnMgPyBhLmNvbnRhaW5zKGIpIDogdHJ1ZSk7Cn07Cgp2YXIgaXNYTUwgPSBmdW5jdGlvbihlbGVtKXsKCXJldHVybiBlbGVtLm5vZGVUeXBlID09PSA5ICYmIGVsZW0uZG9jdW1lbnRFbGVtZW50Lm5vZGVOYW1lICE9PSAiSFRNTCIgfHwKCQkhIWVsZW0ub3duZXJEb2N1bWVudCAmJiBlbGVtLm93bmVyRG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50Lm5vZGVOYW1lICE9PSAiSFRNTCI7Cn07Cgp2YXIgcG9zUHJvY2VzcyA9IGZ1bmN0aW9uKHNlbGVjdG9yLCBjb250ZXh0KXsKCXZhciB0bXBTZXQgPSBbXSwgbGF0ZXIgPSAiIiwgbWF0Y2gsCgkJcm9vdCA9IGNvbnRleHQubm9kZVR5cGUgPyBbY29udGV4dF0gOiBjb250ZXh0OwoKCS8vIFBvc2l0aW9uIHNlbGVjdG9ycyBtdXN0IGJlIGRvbmUgYWZ0ZXIgdGhlIGZpbHRlcgoJLy8gQW5kIHNvIG11c3QgOm5vdChwb3NpdGlvbmFsKSBzbyB3ZSBtb3ZlIGFsbCBQU0VVRE9zIHRvIHRoZSBlbmQKCXdoaWxlICggKG1hdGNoID0gRXhwci5tYXRjaC5QU0VVRE8uZXhlYyggc2VsZWN0b3IgKSkgKSB7CgkJbGF0ZXIgKz0gbWF0Y2hbMF07CgkJc2VsZWN0b3IgPSBzZWxlY3Rvci5yZXBsYWNlKCBFeHByLm1hdGNoLlBTRVVETywgIiIgKTsKCX0KCglzZWxlY3RvciA9IEV4cHIucmVsYXRpdmVbc2VsZWN0b3JdID8gc2VsZWN0b3IgKyAiKiIgOiBzZWxlY3RvcjsKCglmb3IgKCB2YXIgaSA9IDAsIGwgPSByb290Lmxlbmd0aDsgaSA8IGw7IGkrKyApIHsKCQlTaXp6bGUoIHNlbGVjdG9yLCByb290W2ldLCB0bXBTZXQgKTsKCX0KCglyZXR1cm4gU2l6emxlLmZpbHRlciggbGF0ZXIsIHRtcFNldCApOwp9OwoKLy8gRVhQT1NFCgp3aW5kb3cudGlueW1jZS5kb20uU2l6emxlID0gU2l6emxlOwoKfSkoKTsKCihmdW5jdGlvbih0aW55bWNlKSB7CgkvLyBTaG9ydGVuIG5hbWVzCgl2YXIgZWFjaCA9IHRpbnltY2UuZWFjaCwgRE9NID0gdGlueW1jZS5ET00sIGlzSUUgPSB0aW55bWNlLmlzSUUsIGlzV2ViS2l0ID0gdGlueW1jZS5pc1dlYktpdCwgRXZlbnQ7CgoJdGlueW1jZS5jcmVhdGUoJ3RpbnltY2UuZG9tLkV2ZW50VXRpbHMnLCB7CgkJRXZlbnRVdGlscyA6IGZ1bmN0aW9uKCkgewoJCQl0aGlzLmluaXRzID0gW107CgkJCXRoaXMuZXZlbnRzID0gW107CgkJfSwKCgkJYWRkIDogZnVuY3Rpb24obywgbiwgZiwgcykgewoJCQl2YXIgY2IsIHQgPSB0aGlzLCBlbCA9IHQuZXZlbnRzLCByOwoKCQkJaWYgKG4gaW5zdGFuY2VvZiBBcnJheSkgewoJCQkJciA9IFtdOwoKCQkJCWVhY2gobiwgZnVuY3Rpb24obikgewoJCQkJCXIucHVzaCh0LmFkZChvLCBuLCBmLCBzKSk7CgkJCQl9KTsKCgkJCQlyZXR1cm4gcjsKCQkJfQoKCQkJLy8gSGFuZGxlIGFycmF5CgkJCWlmIChvICYmIG8uaGFzT3duUHJvcGVydHkgJiYgbyBpbnN0YW5jZW9mIEFycmF5KSB7CgkJCQlyID0gW107CgoJCQkJZWFjaChvLCBmdW5jdGlvbihvKSB7CgkJCQkJbyA9IERPTS5nZXQobyk7CgkJCQkJci5wdXNoKHQuYWRkKG8sIG4sIGYsIHMpKTsKCQkJCX0pOwoKCQkJCXJldHVybiByOwoJCQl9CgoJCQlvID0gRE9NLmdldChvKTsKCgkJCWlmICghbykKCQkJCXJldHVybjsKCgkJCS8vIFNldHVwIGV2ZW50IGNhbGxiYWNrCgkJCWNiID0gZnVuY3Rpb24oZSkgewoJCQkJLy8gSXMgYWxsIGV2ZW50cyBkaXNhYmxlZAoJCQkJaWYgKHQuZGlzYWJsZWQpCgkJCQkJcmV0dXJuOwoKCQkJCWUgPSBlIHx8IHdpbmRvdy5ldmVudDsKCgkJCQkvLyBQYXRjaCBpbiB0YXJnZXQsIHByZXZlbnREZWZhdWx0IGFuZCBzdG9wUHJvcGFnYXRpb24gaW4gSUUgaXQncyBXM0MgdmFsaWQKCQkJCWlmIChlICYmIGlzSUUpIHsKCQkJCQlpZiAoIWUudGFyZ2V0KQoJCQkJCQllLnRhcmdldCA9IGUuc3JjRWxlbWVudDsKCgkJCQkJLy8gUGF0Y2ggaW4gcHJldmVudERlZmF1bHQsIHN0b3BQcm9wYWdhdGlvbiBtZXRob2RzIGZvciBXM0MgY29tcGF0aWJpbGl0eQoJCQkJCXRpbnltY2UuZXh0ZW5kKGUsIHQuX3N0b3BwZXJzKTsKCQkJCX0KCgkJCQlpZiAoIXMpCgkJCQkJcmV0dXJuIGYoZSk7CgoJCQkJcmV0dXJuIGYuY2FsbChzLCBlKTsKCQkJfTsKCgkJCWlmIChuID09ICd1bmxvYWQnKSB7CgkJCQl0aW55bWNlLnVubG9hZHMudW5zaGlmdCh7ZnVuYyA6IGNifSk7CgkJCQlyZXR1cm4gY2I7CgkJCX0KCgkJCWlmIChuID09ICdpbml0JykgewoJCQkJaWYgKHQuZG9tTG9hZGVkKQoJCQkJCWNiKCk7CgkJCQllbHNlCgkJCQkJdC5pbml0cy5wdXNoKGNiKTsKCgkJCQlyZXR1cm4gY2I7CgkJCX0KCgkJCS8vIFN0b3JlIGF3YXkgbGlzdGVuZXIgcmVmZXJlbmNlCgkJCWVsLnB1c2goewoJCQkJb2JqIDogbywKCQkJCW5hbWUgOiBuLAoJCQkJZnVuYyA6IGYsCgkJCQljZnVuYyA6IGNiLAoJCQkJc2NvcGUgOiBzCgkJCX0pOwoKCQkJdC5fYWRkKG8sIG4sIGNiKTsKCgkJCXJldHVybiBmOwoJCX0sCgoJCXJlbW92ZSA6IGZ1bmN0aW9uKG8sIG4sIGYpIHsKCQkJdmFyIHQgPSB0aGlzLCBhID0gdC5ldmVudHMsIHMgPSBmYWxzZSwgcjsKCgkJCS8vIEhhbmRsZSBhcnJheQoJCQlpZiAobyAmJiBvLmhhc093blByb3BlcnR5ICYmIG8gaW5zdGFuY2VvZiBBcnJheSkgewoJCQkJciA9IFtdOwoKCQkJCWVhY2gobywgZnVuY3Rpb24obykgewoJCQkJCW8gPSBET00uZ2V0KG8pOwoJCQkJCXIucHVzaCh0LnJlbW92ZShvLCBuLCBmKSk7CgkJCQl9KTsKCgkJCQlyZXR1cm4gcjsKCQkJfQoKCQkJbyA9IERPTS5nZXQobyk7CgoJCQllYWNoKGEsIGZ1bmN0aW9uKGUsIGkpIHsKCQkJCWlmIChlLm9iaiA9PSBvICYmIGUubmFtZSA9PSBuICYmICghZiB8fCAoZS5mdW5jID09IGYgfHwgZS5jZnVuYyA9PSBmKSkpIHsKCQkJCQlhLnNwbGljZShpLCAxKTsKCQkJCQl0Ll9yZW1vdmUobywgbiwgZS5jZnVuYyk7CgkJCQkJcyA9IHRydWU7CgkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoJCQl9KTsKCgkJCXJldHVybiBzOwoJCX0sCgoJCWNsZWFyIDogZnVuY3Rpb24obykgewoJCQl2YXIgdCA9IHRoaXMsIGEgPSB0LmV2ZW50cywgaSwgZTsKCgkJCWlmIChvKSB7CgkJCQlvID0gRE9NLmdldChvKTsKCgkJCQlmb3IgKGkgPSBhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7CgkJCQkJZSA9IGFbaV07CgoJCQkJCWlmIChlLm9iaiA9PT0gbykgewoJCQkJCQl0Ll9yZW1vdmUoZS5vYmosIGUubmFtZSwgZS5jZnVuYyk7CgkJCQkJCWUub2JqID0gZS5jZnVuYyA9IG51bGw7CgkJCQkJCWEuc3BsaWNlKGksIDEpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0sCgoJCWNhbmNlbCA6IGZ1bmN0aW9uKGUpIHsKCQkJaWYgKCFlKQoJCQkJcmV0dXJuIGZhbHNlOwoKCQkJdGhpcy5zdG9wKGUpOwoKCQkJcmV0dXJuIHRoaXMucHJldmVudChlKTsKCQl9LAoKCQlzdG9wIDogZnVuY3Rpb24oZSkgewoJCQlpZiAoZS5zdG9wUHJvcGFnYXRpb24pCgkJCQllLnN0b3BQcm9wYWdhdGlvbigpOwoJCQllbHNlCgkJCQllLmNhbmNlbEJ1YmJsZSA9IHRydWU7CgoJCQlyZXR1cm4gZmFsc2U7CgkJfSwKCgkJcHJldmVudCA6IGZ1bmN0aW9uKGUpIHsKCQkJaWYgKGUucHJldmVudERlZmF1bHQpCgkJCQllLnByZXZlbnREZWZhdWx0KCk7CgkJCWVsc2UKCQkJCWUucmV0dXJuVmFsdWUgPSBmYWxzZTsKCgkJCXJldHVybiBmYWxzZTsKCQl9LAoKCQlkZXN0cm95IDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCWVhY2godC5ldmVudHMsIGZ1bmN0aW9uKGUsIGkpIHsKCQkJCXQuX3JlbW92ZShlLm9iaiwgZS5uYW1lLCBlLmNmdW5jKTsKCQkJCWUub2JqID0gZS5jZnVuYyA9IG51bGw7CgkJCX0pOwoKCQkJdC5ldmVudHMgPSBbXTsKCQkJdCA9IG51bGw7CgkJfSwKCgkJX2FkZCA6IGZ1bmN0aW9uKG8sIG4sIGYpIHsKCQkJaWYgKG8uYXR0YWNoRXZlbnQpCgkJCQlvLmF0dGFjaEV2ZW50KCdvbicgKyBuLCBmKTsKCQkJZWxzZSBpZiAoby5hZGRFdmVudExpc3RlbmVyKQoJCQkJby5hZGRFdmVudExpc3RlbmVyKG4sIGYsIGZhbHNlKTsKCQkJZWxzZQoJCQkJb1snb24nICsgbl0gPSBmOwoJCX0sCgoJCV9yZW1vdmUgOiBmdW5jdGlvbihvLCBuLCBmKSB7CgkJCWlmIChvKSB7CgkJCQl0cnkgewoJCQkJCWlmIChvLmRldGFjaEV2ZW50KQoJCQkJCQlvLmRldGFjaEV2ZW50KCdvbicgKyBuLCBmKTsKCQkJCQllbHNlIGlmIChvLnJlbW92ZUV2ZW50TGlzdGVuZXIpCgkJCQkJCW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihuLCBmLCBmYWxzZSk7CgkJCQkJZWxzZQoJCQkJCQlvWydvbicgKyBuXSA9IG51bGw7CgkJCQl9IGNhdGNoIChleCkgewoJCQkJCS8vIE1pZ2h0IGZhaWwgd2l0aCBwZXJtaXNzaW9uIGRlbmluZWQgb24gSUUgc28gd2UganVzdCBpZ25vcmUgdGhhdAoJCQkJfQoJCQl9CgkJfSwKCgkJX3BhZ2VJbml0IDogZnVuY3Rpb24od2luKSB7CgkJCUFKUy5sb2coIkV2ZW50Ol9wYWdlSW5pdCBzdGFydGluZyIpOwoJCQl2YXIgdCA9IHRoaXM7CgoJCQkvLyBLZWVwIGl0IGZyb20gcnVubmluZyBtb3JlIHRoYW4gb25jZQoJCQlpZiAodC5kb21Mb2FkZWQpCgkJCQlyZXR1cm47CgoJCQl0LmRvbUxvYWRlZCA9IHRydWU7CgoJCQllYWNoKHQuaW5pdHMsIGZ1bmN0aW9uKGMpIHsKCQkJCWMoKTsKCQkJfSk7CgoJCQl0LmluaXRzID0gW107CgkJfSwKCgkJX3dhaXQgOiBmdW5jdGlvbih3aW4pIHsKCQkJdmFyIHQgPSB0aGlzLCBkb2MgPSB3aW4uZG9jdW1lbnQ7CgoJCQkvLyBObyBuZWVkIHNpbmNlIHRoZSBkb2N1bWVudCBpcyBhbHJlYWR5IGxvYWRlZAoJCQlpZiAod2luLnRpbnlNQ0VfR1ogJiYgdGlueU1DRV9HWi5sb2FkZWQpIHsKCQkJCXQuZG9tTG9hZGVkID0gMTsKCQkJCXJldHVybjsKCQkJfQoKCQkJLy8gVXNlIElFIG1ldGhvZAoJCQlpZiAoZG9jLmF0dGFjaEV2ZW50KSB7CgkJCQlkb2MuYXR0YWNoRXZlbnQoIm9ucmVhZHlzdGF0ZWNoYW5nZSIsIGZ1bmN0aW9uKCkgewoJCQkJCWlmIChkb2MucmVhZHlTdGF0ZSA9PT0gImNvbXBsZXRlIikgewoJCQkJCQlkb2MuZGV0YWNoRXZlbnQoIm9ucmVhZHlzdGF0ZWNoYW5nZSIsIGFyZ3VtZW50cy5jYWxsZWUpOwoJCQkJCQl0Ll9wYWdlSW5pdCh3aW4pOwoJCQkJCX0KCQkJCX0pOwoKCQkJCWlmIChkb2MuZG9jdW1lbnRFbGVtZW50LmRvU2Nyb2xsICYmIHdpbiA9PSB3aW4udG9wKSB7CgkJCQkJKGZ1bmN0aW9uKCkgewoJCQkJCQlpZiAodC5kb21Mb2FkZWQpCgkJCQkJCQlyZXR1cm47CgoJCQkJCQl0cnkgewoJCQkJCQkJLy8gSWYgSUUgaXMgdXNlZCwgdXNlIHRoZSB0cmljayBieSBEaWVnbyBQZXJpbmkKCQkJCQkJCS8vIGh0dHA6Ly9qYXZhc2NyaXB0Lm53Ym94LmNvbS9JRUNvbnRlbnRMb2FkZWQvCgkJCQkJCQlkb2MuZG9jdW1lbnRFbGVtZW50LmRvU2Nyb2xsKCJsZWZ0Iik7CgkJCQkJCX0gY2F0Y2ggKGV4KSB7CgkJCQkJCQlzZXRUaW1lb3V0KGFyZ3VtZW50cy5jYWxsZWUsIDApOwoJCQkJCQkJcmV0dXJuOwoJCQkJCQl9CgoJCQkJCQl0Ll9wYWdlSW5pdCh3aW4pOwoJCQkJCX0pKCk7CgkJCQl9CgkJCX0gZWxzZSBpZiAoZG9jLmFkZEV2ZW50TGlzdGVuZXIpIHsKCQkJCXQuX2FkZCh3aW4sICdET01Db250ZW50TG9hZGVkJywgZnVuY3Rpb24oKSB7CgkJCQkJdC5fcGFnZUluaXQod2luKTsKCQkJCX0pOwoJCQl9CgoJCQl0Ll9hZGQod2luLCAnbG9hZCcsIGZ1bmN0aW9uKCkgewoJCQkJdC5fcGFnZUluaXQod2luKTsKCQkJfSk7CgkJfSwKCgkJX3N0b3BwZXJzIDogewoJCQlwcmV2ZW50RGVmYXVsdCA6ICBmdW5jdGlvbigpIHsKCQkJCXRoaXMucmV0dXJuVmFsdWUgPSBmYWxzZTsKCQkJfSwKCgkJCXN0b3BQcm9wYWdhdGlvbiA6IGZ1bmN0aW9uKCkgewoJCQkJdGhpcy5jYW5jZWxCdWJibGUgPSB0cnVlOwoJCQl9CgkJfQoKCQl9KTsKCgkvLyBTaG9ydGVuIG5hbWUgYW5kIHNldHVwIGdsb2JhbCBpbnN0YW5jZQoJRXZlbnQgPSB0aW55bWNlLmRvbS5FdmVudCA9IG5ldyB0aW55bWNlLmRvbS5FdmVudFV0aWxzKCk7CgoJLy8gRGlzcGF0Y2ggRE9NIGNvbnRlbnQgbG9hZGVkIGV2ZW50IGZvciBJRSBhbmQgU2FmYXJpCglFdmVudC5fd2FpdCh3aW5kb3cpOwoKCXRpbnltY2UuYWRkVW5sb2FkKGZ1bmN0aW9uKCkgewoJCUV2ZW50LmRlc3Ryb3koKTsKCX0pOwp9KSh0aW55bWNlKTsKKGZ1bmN0aW9uKHRpbnltY2UpIHsKCXZhciBlYWNoID0gdGlueW1jZS5lYWNoOwoKCXRpbnltY2UuY3JlYXRlKCd0aW55bWNlLmRvbS5FbGVtZW50JywgewoJCUVsZW1lbnQgOiBmdW5jdGlvbihpZCwgcykgewoJCQl2YXIgdCA9IHRoaXMsIGRvbSwgZWw7CgoJCQlzID0gcyB8fCB7fTsKCQkJdC5pZCA9IGlkOwoJCQl0LmRvbSA9IGRvbSA9IHMuZG9tIHx8IHRpbnltY2UuRE9NOwoJCQl0LnNldHRpbmdzID0gczsKCgkJCS8vIE9ubHkgSUUgbGVha3MgRE9NIHJlZmVyZW5jZXMsIHRoaXMgaXMgYSBsb3QgZmFzdGVyCgkJCWlmICghdGlueW1jZS5pc0lFKQoJCQkJZWwgPSB0LmRvbS5nZXQodC5pZCk7CgoJCQllYWNoKFsKCQkJCSdnZXRQb3MnLAoJCQkJJ2dldFJlY3QnLAoJCQkJJ2dldFBhcmVudCcsCgkJCQknYWRkJywKCQkJCSdzZXRTdHlsZScsCgkJCQknZ2V0U3R5bGUnLAoJCQkJJ3NldFN0eWxlcycsCgkJCQknc2V0QXR0cmliJywKCQkJCSdzZXRBdHRyaWJzJywKCQkJCSdnZXRBdHRyaWInLAoJCQkJJ2FkZENsYXNzJywKCQkJCSdyZW1vdmVDbGFzcycsCgkJCQknaGFzQ2xhc3MnLAoJCQkJJ2dldE91dGVySFRNTCcsCgkJCQknc2V0T3V0ZXJIVE1MJywKCQkJCSdyZW1vdmUnLAoJCQkJJ3Nob3cnLAoJCQkJJ2hpZGUnLAoJCQkJJ2lzSGlkZGVuJywKCQkJCSdzZXRIVE1MJywKCQkJCSdnZXQnCgkJCV0sIGZ1bmN0aW9uKGspIHsKCQkJCXRba10gPSBmdW5jdGlvbigpIHsKCQkJCQl2YXIgYSA9IFtpZF0sIGk7CgoJCQkJCWZvciAoaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspCgkJCQkJCWEucHVzaChhcmd1bWVudHNbaV0pOwoKCQkJCQlhID0gZG9tW2tdLmFwcGx5KGRvbSwgYSk7CgkJCQkJdC51cGRhdGUoayk7CgoJCQkJCXJldHVybiBhOwoJCQkJfTsKCQkJfSk7CgkJfSwKCgkJb24gOiBmdW5jdGlvbihuLCBmLCBzKSB7CgkJCXJldHVybiB0aW55bWNlLmRvbS5FdmVudC5hZGQodGhpcy5pZCwgbiwgZiwgcyk7CgkJfSwKCgkJZ2V0WFkgOiBmdW5jdGlvbigpIHsKCQkJcmV0dXJuIHsKCQkJCXggOiBwYXJzZUludCh0aGlzLmdldFN0eWxlKCdsZWZ0JykpLAoJCQkJeSA6IHBhcnNlSW50KHRoaXMuZ2V0U3R5bGUoJ3RvcCcpKQoJCQl9OwoJCX0sCgoJCWdldFNpemUgOiBmdW5jdGlvbigpIHsKCQkJdmFyIG4gPSB0aGlzLmRvbS5nZXQodGhpcy5pZCk7CgoJCQlyZXR1cm4gewoJCQkJdyA6IHBhcnNlSW50KHRoaXMuZ2V0U3R5bGUoJ3dpZHRoJykgfHwgbi5jbGllbnRXaWR0aCksCgkJCQloIDogcGFyc2VJbnQodGhpcy5nZXRTdHlsZSgnaGVpZ2h0JykgfHwgbi5jbGllbnRIZWlnaHQpCgkJCX07CgkJfSwKCgkJbW92ZVRvIDogZnVuY3Rpb24oeCwgeSkgewoJCQl0aGlzLnNldFN0eWxlcyh7bGVmdCA6IHgsIHRvcCA6IHl9KTsKCQl9LAoKCQltb3ZlQnkgOiBmdW5jdGlvbih4LCB5KSB7CgkJCXZhciBwID0gdGhpcy5nZXRYWSgpOwoKCQkJdGhpcy5tb3ZlVG8ocC54ICsgeCwgcC55ICsgeSk7CgkJfSwKCgkJcmVzaXplVG8gOiBmdW5jdGlvbih3LCBoKSB7CgkJCXRoaXMuc2V0U3R5bGVzKHt3aWR0aCA6IHcsIGhlaWdodCA6IGh9KTsKCQl9LAoKCQlyZXNpemVCeSA6IGZ1bmN0aW9uKHcsIGgpIHsKCQkJdmFyIHMgPSB0aGlzLmdldFNpemUoKTsKCgkJCXRoaXMucmVzaXplVG8ocy53ICsgdywgcy5oICsgaCk7CgkJfSwKCgkJdXBkYXRlIDogZnVuY3Rpb24oaykgewoJCQl2YXIgdCA9IHRoaXMsIGIsIGRvbSA9IHQuZG9tOwoKCQkJaWYgKHRpbnltY2UuaXNJRTYgJiYgdC5zZXR0aW5ncy5ibG9ja2VyKSB7CgkJCQlrID0gayB8fCAnJzsKCgkJCQkvLyBJZ25vcmUgZ2V0dGVycwoJCQkJaWYgKGsuaW5kZXhPZignZ2V0JykgPT09IDAgfHwgay5pbmRleE9mKCdoYXMnKSA9PT0gMCB8fCBrLmluZGV4T2YoJ2lzJykgPT09IDApCgkJCQkJcmV0dXJuOwoKCQkJCS8vIFJlbW92ZSBibG9ja2VyIG9uIHJlbW92ZQoJCQkJaWYgKGsgPT0gJ3JlbW92ZScpIHsKCQkJCQlkb20ucmVtb3ZlKHQuYmxvY2tlcik7CgkJCQkJcmV0dXJuOwoJCQkJfQoKCQkJCWlmICghdC5ibG9ja2VyKSB7CgkJCQkJdC5ibG9ja2VyID0gZG9tLnVuaXF1ZUlkKCk7CgkJCQkJYiA9IGRvbS5hZGQodC5zZXR0aW5ncy5jb250YWluZXIgfHwgZG9tLmdldFJvb3QoKSwgJ2lmcmFtZScsIHtpZCA6IHQuYmxvY2tlciwgc3R5bGUgOiAncG9zaXRpb246YWJzb2x1dGU7JywgZnJhbWVCb3JkZXIgOiAwLCBzcmMgOiAnamF2YXNjcmlwdDoiIid9KTsKCQkJCQlkb20uc2V0U3R5bGUoYiwgJ29wYWNpdHknLCAwKTsKCQkJCX0gZWxzZQoJCQkJCWIgPSBkb20uZ2V0KHQuYmxvY2tlcik7CgoJCQkJZG9tLnNldFN0eWxlKGIsICdsZWZ0JywgdC5nZXRTdHlsZSgnbGVmdCcsIDEpKTsKCQkJCWRvbS5zZXRTdHlsZShiLCAndG9wJywgdC5nZXRTdHlsZSgndG9wJywgMSkpOwoJCQkJZG9tLnNldFN0eWxlKGIsICd3aWR0aCcsIHQuZ2V0U3R5bGUoJ3dpZHRoJywgMSkpOwoJCQkJZG9tLnNldFN0eWxlKGIsICdoZWlnaHQnLCB0LmdldFN0eWxlKCdoZWlnaHQnLCAxKSk7CgkJCQlkb20uc2V0U3R5bGUoYiwgJ2Rpc3BsYXknLCB0LmdldFN0eWxlKCdkaXNwbGF5JywgMSkpOwoJCQkJZG9tLnNldFN0eWxlKGIsICd6SW5kZXgnLCBwYXJzZUludCh0LmdldFN0eWxlKCd6SW5kZXgnLCAxKSB8fCAwKSAtIDEpOwoJCQl9CgkJfQoKCQl9KTsKfSkodGlueW1jZSk7CihmdW5jdGlvbih0aW55bWNlKSB7CglmdW5jdGlvbiB0cmltTmwocykgewoJCXJldHVybiBzLnJlcGxhY2UoL1tcblxyXSsvZywgJycpOwoJfTsKCgkvLyBTaG9ydGVuIG5hbWVzCgl2YXIgaXMgPSB0aW55bWNlLmlzLCBpc0lFID0gdGlueW1jZS5pc0lFLCBlYWNoID0gdGlueW1jZS5lYWNoOwoKICAgIC8vIEFUTEFTU0lBTiAtIG5lZWQgdG8gY2F0Y2ggZWxlbWVudHMgYXMgd2VsbCBhcyBUZXh0Tm9kZXMgYmVjYXVzZSBvdXIgaW5zZXJ0IGNvZGUgbWlnaHQgbGVhdmUgdGhlIGN1cnNvciBpbiBhbgogICAgLy8gZWxlbWVudCBhbmQgbmVlZCB0byBjaGVjayB0aGUgYm9va21hcmsgZm9yIGEgdGVzdC4KCXZhciBhdGxhc3NpYW5Ob2RlRmlsdGVyID0gewogICAgICAgIGFjY2VwdE5vZGU6IGZ1bmN0aW9uKG5vZGUpIHsKICAgICAgICAgICAgcmV0dXJuIChub2RlLm5vZGVUeXBlID09IDEgfHwgbm9kZS5ub2RlVHlwZSA9PSAzKSA/IE5vZGVGaWx0ZXIuRklMVEVSX0FDQ0VQVCA6IE5vZGVGaWx0ZXIuRklMVEVSX1NLSVA7CiAgICAgICAgfQogICAgfTsKCgl0aW55bWNlLmNyZWF0ZSgndGlueW1jZS5kb20uU2VsZWN0aW9uJywgewoJCVNlbGVjdGlvbiA6IGZ1bmN0aW9uKGRvbSwgd2luLCBzZXJpYWxpemVyKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXQuZG9tID0gZG9tOwoJCQl0LndpbiA9IHdpbjsKCQkJdC5zZXJpYWxpemVyID0gc2VyaWFsaXplcjsKCgkJCS8vIEFkZCBldmVudHMKCQkJZWFjaChbCgkJCQknb25CZWZvcmVTZXRDb250ZW50JywKCQkJCSdvbkJlZm9yZUdldENvbnRlbnQnLAoJCQkJJ29uU2V0Q29udGVudCcsCgkJCQknb25HZXRDb250ZW50JwoJCQldLCBmdW5jdGlvbihlKSB7CgkJCQl0W2VdID0gbmV3IHRpbnltY2UudXRpbC5EaXNwYXRjaGVyKHQpOwoJCQl9KTsKCgkJCS8vIE5vIFczQyBSYW5nZSBzdXBwb3J0CgkJCWlmICghdC53aW4uZ2V0U2VsZWN0aW9uKQoJCQkJdC50cmlkZW50U2VsID0gbmV3IHRpbnltY2UuZG9tLlRyaWRlbnRTZWxlY3Rpb24odCk7CgoJCQkvLyBQcmV2ZW50IGxlYWtzCgkJCXRpbnltY2UuYWRkVW5sb2FkKHQuZGVzdHJveSwgdCk7CgkJfSwKCgkJZ2V0Q29udGVudCA6IGZ1bmN0aW9uKHMpIHsKCQkJdmFyIHQgPSB0aGlzLCByID0gdC5nZXRSbmcoKSwgZSA9IHQuZG9tLmNyZWF0ZSgiYm9keSIpLCBzZSA9IHQuZ2V0U2VsKCksIHdiLCB3YSwgbjsKCgkJCXMgPSBzIHx8IHt9OwoJCQl3YiA9IHdhID0gJyc7CgkJCXMuZ2V0ID0gdHJ1ZTsKCQkJcy5mb3JtYXQgPSBzLmZvcm1hdCB8fCAnaHRtbCc7CgkJCXQub25CZWZvcmVHZXRDb250ZW50LmRpc3BhdGNoKHQsIHMpOwoKCQkJaWYgKHMuZm9ybWF0ID09ICd0ZXh0JykKCQkJCXJldHVybiB0LmlzQ29sbGFwc2VkKCkgPyAnJyA6IChyLnRleHQgfHwgKHNlLnRvU3RyaW5nID8gc2UudG9TdHJpbmcoKSA6ICcnKSk7CgoJCQlpZiAoci5jbG9uZUNvbnRlbnRzKSB7CgkJCQluID0gci5jbG9uZUNvbnRlbnRzKCk7CgoJCQkJaWYgKG4pCgkJCQkJZS5hcHBlbmRDaGlsZChuKTsKCQkJfSBlbHNlIGlmIChpcyhyLml0ZW0pIHx8IGlzKHIuaHRtbFRleHQpKQoJCQkJZS5pbm5lckhUTUwgPSByLml0ZW0gPyByLml0ZW0oMCkub3V0ZXJIVE1MIDogci5odG1sVGV4dDsKCQkJZWxzZQoJCQkJZS5pbm5lckhUTUwgPSByLnRvU3RyaW5nKCk7CgoJCQkvLyBLZWVwIHdoaXRlc3BhY2UgYmVmb3JlIGFuZCBhZnRlcgoJCQlpZiAoL15ccy8udGVzdChlLmlubmVySFRNTCkpCgkJCQl3YiA9ICcgJzsKCgkJCWlmICgvXHMrJC8udGVzdChlLmlubmVySFRNTCkpCgkJCQl3YSA9ICcgJzsKCgkJCXMuZ2V0SW5uZXIgPSB0cnVlOwoKCQkJcy5jb250ZW50ID0gdC5pc0NvbGxhcHNlZCgpID8gJycgOiB3YiArIHQuc2VyaWFsaXplci5zZXJpYWxpemUoZSwgcykgKyB3YTsKCQkJdC5vbkdldENvbnRlbnQuZGlzcGF0Y2godCwgcyk7CgoJCQlyZXR1cm4gcy5jb250ZW50OwoJCX0sCgoJCXNldENvbnRlbnQgOiBmdW5jdGlvbihoLCBzKSB7CgkJCXZhciB0ID0gdGhpcywgciA9IHQuZ2V0Um5nKCksIGMsIGQgPSB0Lndpbi5kb2N1bWVudDsKCgkJCXMgPSBzIHx8IHtmb3JtYXQgOiAnaHRtbCd9OwoJCQlzLnNldCA9IHRydWU7CgkJCWggPSBzLmNvbnRlbnQgPSB0LmRvbS5wcm9jZXNzSFRNTChoKTsKCgkJCS8vIERpc3BhdGNoIGJlZm9yZSBzZXQgY29udGVudCBldmVudAoJCQl0Lm9uQmVmb3JlU2V0Q29udGVudC5kaXNwYXRjaCh0LCBzKTsKCQkJaCA9IHMuY29udGVudDsKCgkJCWlmIChyLmluc2VydE5vZGUpIHsKCQkJCS8vIE1ha2UgY2FyZXQgbWFya2VyIHNpbmNlIGluc2VydE5vZGUgcGxhY2VzIHRoZSBjYXJldCBpbiB0aGUgYmVnaW5uaW5nIG9mIHRleHQgYWZ0ZXIgaW5zZXJ0CgkJCQloICs9ICc8c3BhbiBpZD0iX19jYXJldCI+Xzwvc3Bhbj4nOwoKCQkJCS8vIERlbGV0ZSBhbmQgaW5zZXJ0IG5ldyBub2RlCgkJCQlyLmRlbGV0ZUNvbnRlbnRzKCk7CgkJCQlyLmluc2VydE5vZGUodC5nZXRSbmcoKS5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQoaCkpOwoKCQkJCS8vIE1vdmUgdG8gY2FyZXQgbWFya2VyCgkJCQljID0gdC5kb20uZ2V0KCdfX2NhcmV0Jyk7CgoJCQkJLy8gTWFrZSBzdXJlIHdlIHdyYXAgaXQgY29tcGxlYXRseSwgT3BlcmEgZmFpbHMgd2l0aCBhIHNpbXBsZSBzZWxlY3QgY2FsbAoJCQkJciA9IGQuY3JlYXRlUmFuZ2UoKTsKCQkJCXIuc2V0U3RhcnRCZWZvcmUoYyk7CgkJCQlyLnNldEVuZEFmdGVyKGMpOwoJCQkJdC5zZXRSbmcocik7CgoJCQkJLy8gRGVsZXRlIHRoZSBtYXJrZXIsIGFuZCBob3BlZnVsbHkgdGhlIGNhcmV0IGdldHMgcGxhY2VkIGluIHRoZSByaWdodCBsb2NhdGlvbgoJCQkJLy8gUmVtb3ZlZCB0aGlzIHNpbmNlIGl0IHNlZW1zIHRvIHJlbW92ZSAmbmJzcDsgaW4gRkYgYW5kIHNpbXBseSBkZWxldGluZyBpdAoJCQkJLy8gZG9lc24ndCBzZWVtIHRvIGFmZmVjdCB0aGUgY2FyZXQgcG9zaXRpb24gaW4gYW55IGJyb3dzZXIKCQkJCS8vZC5leGVjQ29tbWFuZCgnRGVsZXRlJywgZmFsc2UsIG51bGwpOwoKCQkJCS8vIFJlbW92ZSB0aGUgY2FyZXQgcG9zaXRpb24KCQkJCXQuZG9tLnJlbW92ZSgnX19jYXJldCcpOwoJCQl9IGVsc2UgewoJCQkJaWYgKHIuaXRlbSkgewoJCQkJCS8vIERlbGV0ZSBjb250ZW50IGFuZCBnZXQgY2FyZXQgdGV4dCBzZWxlY3Rpb24KCQkJCQlkLmV4ZWNDb21tYW5kKCdEZWxldGUnLCBmYWxzZSwgbnVsbCk7CgkJCQkJciA9IHQuZ2V0Um5nKCk7CgkJCQl9CgoJCQkJci5wYXN0ZUhUTUwoaCk7CgkJCX0KCgkJCS8vIERpc3BhdGNoIHNldCBjb250ZW50IGV2ZW50CgkJCXQub25TZXRDb250ZW50LmRpc3BhdGNoKHQsIHMpOwoJCX0sCgoJCWdldFN0YXJ0IDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpcywgciA9IHQuZ2V0Um5nKCksIGU7CgoJCQlpZiAoaXNJRSkgewoJCQkJaWYgKHIuaXRlbSkKCQkJCQlyZXR1cm4gci5pdGVtKDApOwoKCQkJCXIgPSByLmR1cGxpY2F0ZSgpOwoJCQkJci5jb2xsYXBzZSgxKTsKCQkJCWUgPSByLnBhcmVudEVsZW1lbnQoKTsKCgkJCQlpZiAoZSAmJiBlLm5vZGVOYW1lID09ICdCT0RZJykKCQkJCQlyZXR1cm4gZS5maXJzdENoaWxkOwoKCQkJCXJldHVybiBlOwoJCQl9IGVsc2UgewoJCQkJZSA9IHIuc3RhcnRDb250YWluZXI7CgoJCQkJaWYgKGUubm9kZU5hbWUgPT0gJ0JPRFknKQoJCQkJCXJldHVybiBlLmZpcnN0Q2hpbGQ7CgoJCQkJcmV0dXJuIHQuZG9tLmdldFBhcmVudChlLCAnKicpOwoJCQl9CgkJfSwKCgkJZ2V0RW5kIDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpcywgciA9IHQuZ2V0Um5nKCksIGU7CgoJCQlpZiAoaXNJRSkgewoJCQkJaWYgKHIuaXRlbSkKCQkJCQlyZXR1cm4gci5pdGVtKDApOwoKCQkJCXIgPSByLmR1cGxpY2F0ZSgpOwoJCQkJci5jb2xsYXBzZSgwKTsKCQkJCWUgPSByLnBhcmVudEVsZW1lbnQoKTsKCgkJCQlpZiAoZSAmJiBlLm5vZGVOYW1lID09ICdCT0RZJykKCQkJCQlyZXR1cm4gZS5sYXN0Q2hpbGQ7CgoJCQkJcmV0dXJuIGU7CgkJCX0gZWxzZSB7CgkJCQllID0gci5lbmRDb250YWluZXI7CgoJCQkJaWYgKGUubm9kZU5hbWUgPT0gJ0JPRFknKQoJCQkJCXJldHVybiBlLmxhc3RDaGlsZDsKCgkJCQlyZXR1cm4gdC5kb20uZ2V0UGFyZW50KGUsICcqJyk7CgkJCX0KCQl9LAoKCQlnZXRCb29rbWFyayA6IGZ1bmN0aW9uKHNpKSB7CgkJCXZhciB0ID0gdGhpcywgciA9IHQuZ2V0Um5nKCksIHRyLCBzeCwgc3ksIHZwID0gdC5kb20uZ2V0Vmlld1BvcnQodC53aW4pLCBlLCBzcCwgYnAsIGxlLCBjID0gLTB4RkZGRkZGLCBzLCBybyA9IHQuZG9tLmdldFJvb3QoKSwgd2IgPSAwLCB3YSA9IDAsIG52OwoJCQlzeCA9IHZwLng7CgkJCXN5ID0gdnAueTsKCgkJCS8vIFNpbXBsZSBib29rbWFyayBmYXN0IGJ1dCBub3QgYXMgcGVyc2lzdGVudAoJCQlpZiAoc2kpCgkJCQlyZXR1cm4ge3JuZyA6IHIsIHNjcm9sbFggOiBzeCwgc2Nyb2xsWSA6IHN5fTsKCgkJCS8vIEhhbmRsZSBJRQoJCQlpZiAoaXNJRSkgewoJCQkJLy8gQ29udHJvbCBzZWxlY3Rpb24KCQkJCWlmIChyLml0ZW0pIHsKCQkJCQllID0gci5pdGVtKDApOwoKCQkJCQllYWNoKHQuZG9tLnNlbGVjdChlLm5vZGVOYW1lKSwgZnVuY3Rpb24obiwgaSkgewoJCQkJCQlpZiAoZSA9PSBuKSB7CgkJCQkJCQlzcCA9IGk7CgkJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJCX0KCQkJCQl9KTsKCgkJCQkJcmV0dXJuIHsKCQkJCQkJdGFnIDogZS5ub2RlTmFtZSwKCQkJCQkJaW5kZXggOiBzcCwKCQkJCQkJc2Nyb2xsWCA6IHN4LAoJCQkJCQlzY3JvbGxZIDogc3kKCQkJCQl9OwoJCQkJfQoKCQkJCS8vIFRleHQgc2VsZWN0aW9uCgkJCQl0ciA9IHQuZG9tLmRvYy5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpOwoJCQkJdHIubW92ZVRvRWxlbWVudFRleHQocm8pOwoJCQkJdHIuY29sbGFwc2UodHJ1ZSk7CgkJCQlicCA9IE1hdGguYWJzKHRyLm1vdmUoJ2NoYXJhY3RlcicsIGMpKTsKCgkJCQl0ciA9IHIuZHVwbGljYXRlKCk7CgkJCQl0ci5jb2xsYXBzZSh0cnVlKTsKCQkJCXNwID0gTWF0aC5hYnModHIubW92ZSgnY2hhcmFjdGVyJywgYykpOwoKCQkJCXRyID0gci5kdXBsaWNhdGUoKTsKCQkJCXRyLmNvbGxhcHNlKGZhbHNlKTsKCQkJCWxlID0gTWF0aC5hYnModHIubW92ZSgnY2hhcmFjdGVyJywgYykpIC0gc3A7CgoJCQkJcmV0dXJuIHsKCQkJCQlzdGFydCA6IHNwIC0gYnAsCgkJCQkJbGVuZ3RoIDogbGUsCgkJCQkJc2Nyb2xsWCA6IHN4LAoJCQkJCXNjcm9sbFkgOiBzeQoJCQkJfTsKCQkJfQoKCQkJLy8gSGFuZGxlIFczQwoJCQllID0gdC5nZXROb2RlKCk7CgkJCXMgPSB0LmdldFNlbCgpOwoKCQkJaWYgKCFzKQoJCQkJcmV0dXJuIG51bGw7CgoJCQkvLyBJbWFnZSBzZWxlY3Rpb24KCQkJaWYgKGUgJiYgZS5ub2RlTmFtZSA9PSAnSU1HJykgewoJCQkJcmV0dXJuIHsKCQkJCQlzY3JvbGxYIDogc3gsCgkJCQkJc2Nyb2xsWSA6IHN5CgkJCQl9OwoJCQl9CgoJCQkvLyBUZXh0IHNlbGVjdGlvbgoKCQkJZnVuY3Rpb24gZ2V0UG9zKHIsIHNuLCBlbikgewogICAgICAgICAgICAgICAgLy8gQVRMQVNTSUFOIC0gdXNlIGN1c3RvbSBmaWx0ZXIKICAgICAgICAgICAgICAgIHZhciB3ID0gdC5kb20uZG9jLmNyZWF0ZVRyZWVXYWxrZXIociwgTm9kZUZpbHRlci5TSE9XX0FMTCwgYXRsYXNzaWFuTm9kZUZpbHRlciwgZmFsc2UpLCBuLCBwID0gMCwgZCA9IHt9OwoKCQkJCXdoaWxlICgobiA9IHcubmV4dE5vZGUoKSkgIT0gbnVsbCkgewoJCQkJCWlmIChuID09IHNuKQoJCQkJCQlkLnN0YXJ0ID0gcDsKCgkJCQkJaWYgKG4gPT0gZW4pIHsKCQkJCQkJZC5lbmQgPSBwOwoJCQkJCQlyZXR1cm4gZDsKCQkJCQl9CgoJCQkJCXAgKz0gdHJpbU5sKG4ubm9kZVZhbHVlIHx8ICcnKS5sZW5ndGg7CgkJCQl9CgoJCQkJcmV0dXJuIG51bGw7CgkJCX07CgoJCQkvLyBDYXJldCBvciBzZWxlY3Rpb24KCQkJaWYgKHMuYW5jaG9yTm9kZSA9PSBzLmZvY3VzTm9kZSAmJiBzLmFuY2hvck9mZnNldCA9PSBzLmZvY3VzT2Zmc2V0KSB7CgkJCQllID0gZ2V0UG9zKHJvLCBzLmFuY2hvck5vZGUsIHMuZm9jdXNOb2RlKTsKCgkJCQlpZiAoIWUpCgkJCQkJcmV0dXJuIHtzY3JvbGxYIDogc3gsIHNjcm9sbFkgOiBzeX07CgoJCQkJLy8gQ291bnQgd2hpdGVzcGFjZSBiZWZvcmUKICAgICAgICAgICAgICAgIC8vIEFUTEFTU0lBTiAtIHVzZSB0ZXh0IGJlZm9yZSBjYXJldCwgbm90IHRoZSB3aG9sZSB2YWx1ZQogICAgICAgICAgICAgICAgaWYgKHMuYW5jaG9yTm9kZS5ub2RlVmFsdWUgJiYgcy5hbmNob3JPZmZzZXQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dEJlZm9yZUNhcmV0ID0gcy5hbmNob3JOb2RlLm5vZGVWYWx1ZS5zdWJzdHIoMCwgcy5hbmNob3JPZmZzZXQpOwoJCQkJICAgIHRyaW1ObCh0ZXh0QmVmb3JlQ2FyZXQpLnJlcGxhY2UoL15ccysvLCBmdW5jdGlvbihhKSB7d2IgPSBhLmxlbmd0aDt9KTsKICAgICAgICAgICAgICAgIH0KCgkJCQlyZXR1cm4gewoJCQkJCXN0YXJ0IDogTWF0aC5tYXgoZS5zdGFydCArIHMuYW5jaG9yT2Zmc2V0IC0gd2IsIDApLAoJCQkJCWVuZCA6IE1hdGgubWF4KGUuZW5kICsgcy5mb2N1c09mZnNldCAtIHdiLCAwKSwKCQkJCQlzY3JvbGxYIDogc3gsCgkJCQkJc2Nyb2xsWSA6IHN5LAoJCQkJCWJlZyA6IHMuYW5jaG9yT2Zmc2V0IC0gd2IgPT0gMAoJCQkJfTsKCQkJfSBlbHNlIHsKCQkJCWUgPSBnZXRQb3Mocm8sIHIuc3RhcnRDb250YWluZXIsIHIuZW5kQ29udGFpbmVyKTsKCgkJCQkvLyBDb3VudCB3aGl0ZXNwYWNlIGJlZm9yZSBzdGFydCBhbmQgZW5kIGNvbnRhaW5lcgoJCQkJLy8oci5zdGFydENvbnRhaW5lci5ub2RlVmFsdWUgfHwgJycpLnJlcGxhY2UoL15ccysvLCBmdW5jdGlvbihhKSB7d2IgPSBhLmxlbmd0aDt9KTsKCQkJCS8vKHIuZW5kQ29udGFpbmVyLm5vZGVWYWx1ZSB8fCAnJykucmVwbGFjZSgvXlxzKy8sIGZ1bmN0aW9uKGEpIHt3YSA9IGEubGVuZ3RoO30pOwoKCQkJCWlmICghZSkKCQkJCQlyZXR1cm4ge3Njcm9sbFggOiBzeCwgc2Nyb2xsWSA6IHN5fTsKCgkJCQlyZXR1cm4gewoJCQkJCXN0YXJ0IDogTWF0aC5tYXgoZS5zdGFydCArIHIuc3RhcnRPZmZzZXQgLSB3YiwgMCksCgkJCQkJZW5kIDogTWF0aC5tYXgoZS5lbmQgKyByLmVuZE9mZnNldCAtIHdhLCAwKSwKCQkJCQlzY3JvbGxYIDogc3gsCgkJCQkJc2Nyb2xsWSA6IHN5LAoJCQkJCWJlZyA6IHIuc3RhcnRPZmZzZXQgLSB3YiA9PSAwCgkJCQl9OwoJCQl9CgkJfSwKCgkJbW92ZVRvQm9va21hcmsgOiBmdW5jdGlvbihiKSB7CgkJCXZhciB0ID0gdGhpcywgciA9IHQuZ2V0Um5nKCksIHJvID0gdC5kb20uZ2V0Um9vdCgpLCBzZCwgbnZsLCBudjsKCgkJCWZ1bmN0aW9uIGdldFBvcyhyLCBzcCwgZXApIHsKICAgICAgICAgICAgICAgIC8vIEFUTEFTU0lBTiAtIHVzZSBjdXN0b20gZmlsdGVyCiAgICAgICAgICAgICAgICB2YXIgdyA9IHQuZG9tLmRvYy5jcmVhdGVUcmVlV2Fsa2VyKHIsIE5vZGVGaWx0ZXIuU0hPV19BTEwsIGF0bGFzc2lhbk5vZGVGaWx0ZXIsIGZhbHNlKSwgbiwgcCA9IDAsIGQgPSB7fSwgbywgdiwgd2EsIHdiOwoKCQkJCXdoaWxlICgobiA9IHcubmV4dE5vZGUoKSkgIT0gbnVsbCkgewoJCQkJCXdhID0gd2IgPSAwOwoKCQkJCQludiA9IG4ubm9kZVZhbHVlIHx8ICcnOwoJCQkJCS8vbnYucmVwbGFjZSgvXlxzK1teXHNdLywgZnVuY3Rpb24oYSkge3diID0gYS5sZW5ndGggLSAxO30pOwoJCQkJCS8vbnYucmVwbGFjZSgvW15cc11ccyskLywgZnVuY3Rpb24oYSkge3dhID0gYS5sZW5ndGggLSAxO30pOwoKCQkJCQludmwgPSB0cmltTmwobnYpLmxlbmd0aDsKCQkJCQlwICs9IG52bDsKCgkJCQkJaWYgKHAgPj0gc3AgJiYgIWQuc3RhcnROb2RlKSB7CgkJCQkJCW8gPSBzcCAtIChwIC0gbnZsKTsKCgkJCQkJCS8vIEZpeCBmb3Igb2RkIHF1aXJrIGluIEZGCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFUTEFTU0lBTiAtIG5vZGUgdmFsdWUgbGVuZ3RoIG1heSBiZSAwIGZvciBlbXB0eSA8cD4KCQkJCQkJaWYgKGIuYmVnICYmIG52bCAmJiBvID49IG52bCkKCQkJCQkJCWNvbnRpbnVlOwoKCQkJCQkJZC5zdGFydE5vZGUgPSBuOwoJCQkJCQlkLnN0YXJ0T2Zmc2V0ID0gbyArIHdiOwoJCQkJCX0KCgkJCQkJaWYgKHAgPj0gZXApIHsKCQkJCQkJZC5lbmROb2RlID0gbjsKCQkJCQkJZC5lbmRPZmZzZXQgPSBlcCAtIChwIC0gbnZsKSArIHdiOwoJCQkJCQlyZXR1cm4gZDsKCQkJCQl9CgkJCQl9CgoJCQkJcmV0dXJuIG51bGw7CgkJCX07CgoJCQlpZiAoIWIpCgkJCQlyZXR1cm4gZmFsc2U7CgogICAgICAgICAgICB0Lndpbi5zY3JvbGxUbyhiLnNjcm9sbFgsIGIuc2Nyb2xsWSk7CgogICAgICAgICAgICAvLyBBVExBU1NJQU4gLSBzZWxlY3Rpb24gbmVlZHMgdG8gYmUgcmV0cmlldmVkIGZyb20gd2luZG93ICphZnRlciogc2Nyb2xsIG9yIHRoZSByYW5nZSB3aWxsIG5vdCBiZSBzZXQgY29ycmVjdGx5LgogICAgICAgICAgICB2YXIgcyA9IHQuZ2V0U2VsKCk7CgoJCQkvLyBIYW5kbGUgZXhwbG9yZXIKCQkJaWYgKGlzSUUpIHsKCQkJCS8vIEhhbmRsZSBzaW1wbGUKCQkJCWlmIChyID0gYi5ybmcpIHsKCQkJCQl0cnkgewoJCQkJCQlyLnNlbGVjdCgpOwoJCQkJCX0gY2F0Y2ggKGV4KSB7CgkJCQkJCS8vIElnbm9yZQoJCQkJCX0KCgkJCQkJcmV0dXJuIHRydWU7CgkJCQl9CgoJCQkJdC53aW4uZm9jdXMoKTsKCgkJCQkvLyBIYW5kbGUgY29udHJvbCBib29rbWFyawoJCQkJaWYgKGIudGFnKSB7CgkJCQkJciA9IHJvLmNyZWF0ZUNvbnRyb2xSYW5nZSgpOwoKCQkJCQllYWNoKHQuZG9tLnNlbGVjdChiLnRhZyksIGZ1bmN0aW9uKG4sIGkpIHsKCQkJCQkJaWYgKGkgPT0gYi5pbmRleCkKCQkJCQkJCXIuYWRkRWxlbWVudChuKTsKCQkJCQl9KTsKCQkJCX0gZWxzZSB7CgkJCQkJLy8gVHJ5L2NhdGNoIG5lZWRlZCBzaW5jZSB0aGlzIG9wZXJhdGlvbiBicmVha3Mgd2hlbiBUaW55TUNFIGlzIHBsYWNlZCBpbiBoaWRkZW4gZGl2cy90YWJzCgkJCQkJdHJ5IHsKCQkJCQkJLy8gSW5jb3JyZWN0IGJvb2ttYXJrCgkJCQkJCWlmIChiLnN0YXJ0IDwgMCkKCQkJCQkJCXJldHVybiB0cnVlOwoKCQkJCQkJciA9IHMuY3JlYXRlUmFuZ2UoKTsKCQkJCQkJci5tb3ZlVG9FbGVtZW50VGV4dChybyk7CgkJCQkJCXIuY29sbGFwc2UodHJ1ZSk7CgkJCQkJCXIubW92ZVN0YXJ0KCdjaGFyYWN0ZXInLCBiLnN0YXJ0KTsKCQkJCQkJci5tb3ZlRW5kKCdjaGFyYWN0ZXInLCBiLmxlbmd0aCk7CgkJCQkJfSBjYXRjaCAoZXgyKSB7CgkJCQkJCXJldHVybiB0cnVlOwoJCQkJCX0KCQkJCX0KCgkJCQl0cnkgewoJCQkJCXIuc2VsZWN0KCk7CgkJCQl9IGNhdGNoIChleCkgewoJCQkJCS8vIE5lZWRlZCBmb3Igc29tZSBvZGQgSUUgYnVnICMxODQzMzA2CgkJCQl9CgoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCgkJCS8vIEhhbmRsZSBXM0MKCQkJaWYgKCFzKQoJCQkJcmV0dXJuIGZhbHNlOwoKCQkJLy8gSGFuZGxlIHNpbXBsZQoJCQlpZiAoYi5ybmcpIHsKCQkJCXMucmVtb3ZlQWxsUmFuZ2VzKCk7CgkJCQlzLmFkZFJhbmdlKGIucm5nKTsKCQkJfSBlbHNlIHsKCQkJCWlmIChpcyhiLnN0YXJ0KSAmJiBpcyhiLmVuZCkpIHsKCQkJCQl0cnkgewoJCQkJCQlzZCA9IGdldFBvcyhybywgYi5zdGFydCwgYi5lbmQpOwoKCQkJCQkJaWYgKHNkKSB7CgkJCQkJCQlyID0gdC5kb20uZG9jLmNyZWF0ZVJhbmdlKCk7CgkJCQkJCQlyLnNldFN0YXJ0KHNkLnN0YXJ0Tm9kZSwgc2Quc3RhcnRPZmZzZXQpOwoJCQkJCQkJci5zZXRFbmQoc2QuZW5kTm9kZSwgc2QuZW5kT2Zmc2V0KTsKCQkJCQkJCXMucmVtb3ZlQWxsUmFuZ2VzKCk7CgkJCQkJCQlzLmFkZFJhbmdlKHIpOwoJCQkJCQl9CgoJCQkJCQlpZiAoIXRpbnltY2UuaXNPcGVyYSkKCQkJCQkJCXQud2luLmZvY3VzKCk7CgkJCQkJfSBjYXRjaCAoZXgpIHsKCQkJCQkJLy8gSWdub3JlCgkJCQkJfQoJCQkJfQoJCQl9CgkJfSwKCgkJc2VsZWN0IDogZnVuY3Rpb24obiwgYykgewoJCQl2YXIgdCA9IHRoaXMsIHIgPSB0LmdldFJuZygpLCBzID0gdC5nZXRTZWwoKSwgYiwgZm4sIGxuLCBkID0gdC53aW4uZG9jdW1lbnQ7CgoJCQlmdW5jdGlvbiBmaW5kKG4sIHN0YXJ0KSB7CgkJCQl2YXIgd2Fsa2VyLCBvOwoKCQkJCWlmIChuKSB7CgkJCQkJd2Fsa2VyID0gZC5jcmVhdGVUcmVlV2Fsa2VyKG4sIE5vZGVGaWx0ZXIuU0hPV19URVhULCBudWxsLCBmYWxzZSk7CgoJCQkJCS8vIEZpbmQgZmlyc3QvbGFzdCBub24gZW1wdHkgdGV4dCBub2RlCgkJCQkJd2hpbGUgKG4gPSB3YWxrZXIubmV4dE5vZGUoKSkgewoJCQkJCQlvID0gbjsKCgkJCQkJCWlmICh0aW55bWNlLnRyaW0obi5ub2RlVmFsdWUpLmxlbmd0aCAhPSAwKSB7CgkJCQkJCQlpZiAoc3RhcnQpCgkJCQkJCQkJcmV0dXJuIG47CgkJCQkJCQllbHNlCgkJCQkJCQkJbyA9IG47CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgoJCQkJcmV0dXJuIG87CgkJCX07CgoJCQlpZiAoaXNJRSkgewoJCQkJdHJ5IHsKCQkJCQliID0gZC5ib2R5OwoKCQkJCQlpZiAoL14oSU1HfFRBQkxFKSQvLnRlc3Qobi5ub2RlTmFtZSkpIHsKCQkJCQkJciA9IGIuY3JlYXRlQ29udHJvbFJhbmdlKCk7CgkJCQkJCXIuYWRkRWxlbWVudChuKTsKCQkJCQl9IGVsc2UgewoJCQkJCQlyID0gYi5jcmVhdGVUZXh0UmFuZ2UoKTsKCQkJCQkJci5tb3ZlVG9FbGVtZW50VGV4dChuKTsKCQkJCQl9CgoJCQkJCXIuc2VsZWN0KCk7CgkJCQl9IGNhdGNoIChleCkgewoJCQkJCS8vIFRocm93cyBpbGxpZ2FsIGFncnVtZW50IGluIElFIHNvbWUgdGltZXMKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWlmIChjKSB7CgkJCQkJZm4gPSBmaW5kKG4sIDEpIHx8IHQuZG9tLnNlbGVjdCgnYnI6Zmlyc3QnLCBuKVswXTsKCQkJCQlsbiA9IGZpbmQobiwgMCkgfHwgdC5kb20uc2VsZWN0KCdicjpsYXN0JywgbilbMF07CgoJCQkJCWlmIChmbiAmJiBsbikgewoJCQkJCQlyID0gZC5jcmVhdGVSYW5nZSgpOwoKCQkJCQkJaWYgKGZuLm5vZGVOYW1lID09ICdCUicpCgkJCQkJCQlyLnNldFN0YXJ0QmVmb3JlKGZuKTsKCQkJCQkJZWxzZQoJCQkJCQkJci5zZXRTdGFydChmbiwgMCk7CgoJCQkJCQlpZiAobG4ubm9kZU5hbWUgPT0gJ0JSJykKCQkJCQkJCXIuc2V0RW5kQmVmb3JlKGxuKTsKCQkJCQkJZWxzZQoJCQkJCQkJci5zZXRFbmQobG4sIGxuLm5vZGVWYWx1ZS5sZW5ndGgpOwoJCQkJCX0gZWxzZQoJCQkJCQlyLnNlbGVjdE5vZGUobik7CgkJCQl9IGVsc2UKCQkJCQlyLnNlbGVjdE5vZGUobik7CgoJCQkJdC5zZXRSbmcocik7CgkJCX0KCgkJCXJldHVybiBuOwoJCX0sCgoJCWlzQ29sbGFwc2VkIDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpcywgciA9IHQuZ2V0Um5nKCksIHMgPSB0LmdldFNlbCgpOwoKCQkJaWYgKCFyIHx8IHIuaXRlbSkKCQkJCXJldHVybiBmYWxzZTsKCgkJCXJldHVybiAhcyB8fCByLmJvdW5kaW5nV2lkdGggPT0gMCB8fCByLmNvbGxhcHNlZDsKCQl9LAoKCQljb2xsYXBzZSA6IGZ1bmN0aW9uKGIpIHsKCQkJdmFyIHQgPSB0aGlzLCByID0gdC5nZXRSbmcoKSwgbjsKCgkJCS8vIENvbnRyb2wgcmFuZ2Ugb24gSUUKCQkJaWYgKHIuaXRlbSkgewoJCQkJbiA9IHIuaXRlbSgwKTsKCQkJCXIgPSB0aGlzLndpbi5kb2N1bWVudC5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpOwoJCQkJci5tb3ZlVG9FbGVtZW50VGV4dChuKTsKCQkJfQoKCQkJci5jb2xsYXBzZSghIWIpOwoJCQl0LnNldFJuZyhyKTsKCQl9LAoKCQlnZXRTZWwgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCB3ID0gdGhpcy53aW47CgoJCQlyZXR1cm4gdy5nZXRTZWxlY3Rpb24gPyB3LmdldFNlbGVjdGlvbigpIDogdy5kb2N1bWVudC5zZWxlY3Rpb247CgkJfSwKCgkJZ2V0Um5nIDogZnVuY3Rpb24odzNjKSB7CgkJCXZhciB0ID0gdGhpcywgcywgcjsKCgkJCS8vIEZvdW5kIHRyaWRlbnRTZWwgb2JqZWN0IHRoZW4gd2UgbmVlZCB0byB1c2UgdGhhdCBvbmUKCQkJaWYgKHczYyAmJiB0LnRyaWRlbnRTZWwpCgkJCQlyZXR1cm4gdC50cmlkZW50U2VsLmdldFJhbmdlQXQoMCk7CgoJCQl0cnkgewoJCQkJaWYgKHMgPSB0LmdldFNlbCgpKQoJCQkJCXIgPSBzLnJhbmdlQ291bnQgPiAwID8gcy5nZXRSYW5nZUF0KDApIDogKHMuY3JlYXRlUmFuZ2UgPyBzLmNyZWF0ZVJhbmdlKCkgOiB0Lndpbi5kb2N1bWVudC5jcmVhdGVSYW5nZSgpKTsKCQkJfSBjYXRjaCAoZXgpIHsKCQkJCS8vIElFIHRocm93cyB1bnNwZWNpZmllZCBlcnJvciBoZXJlIGlmIFRpbnlNQ0UgaXMgcGxhY2VkIGluIGEgZnJhbWUvaWZyYW1lCgkJCX0KCgkJCS8vIE5vIHJhbmdlIGZvdW5kIHRoZW4gY3JlYXRlIGFuIGVtcHR5IG9uZQoJCQkvLyBUaGlzIGNhbiBvY2N1ciB3aGVuIHRoZSBlZGl0b3IgaXMgcGxhY2VkIGluIGEgaGlkZGVuIGNvbnRhaW5lciBlbGVtZW50IG9uIEdlY2tvCgkJCS8vIE9yIG9uIElFIHdoZW4gdGhlcmUgd2FzIGFuIGV4Y2VwdGlvbgoJCQlpZiAoIXIpCgkJCQlyID0gaXNJRSA/IHQud2luLmRvY3VtZW50LmJvZHkuY3JlYXRlVGV4dFJhbmdlKCkgOiB0Lndpbi5kb2N1bWVudC5jcmVhdGVSYW5nZSgpOwoKCQkJcmV0dXJuIHI7CgkJfSwKCgkJc2V0Um5nIDogZnVuY3Rpb24ocikgewoJCQl2YXIgcywgdCA9IHRoaXM7CgoJCQlpZiAoIXQudHJpZGVudFNlbCkgewoJCQkJcyA9IHQuZ2V0U2VsKCk7CgoJCQkJaWYgKHMpIHsKCQkJCQlzLnJlbW92ZUFsbFJhbmdlcygpOwoJCQkJCXMuYWRkUmFuZ2Uocik7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQkvLyBJcyBXM0MgUmFuZ2UKCQkJCWlmIChyLmNsb25lUmFuZ2UpIHsKCQkJCQl0LnRyaWRlbnRTZWwuYWRkUmFuZ2Uocik7CgkJCQkJcmV0dXJuOwoJCQkJfQoKCQkJCS8vIElzIElFIHNwZWNpZmljIHJhbmdlCgkJCQl0cnkgewoJCQkJCXIuc2VsZWN0KCk7CgkJCQl9IGNhdGNoIChleCkgewoJCQkJCS8vIE5lZWRlZCBmb3Igc29tZSBvZGQgSUUgYnVnICMxODQzMzA2CgkJCQl9CgkJCX0KCQl9LAoKCQlzZXROb2RlIDogZnVuY3Rpb24obikgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQl0LnNldENvbnRlbnQodC5kb20uZ2V0T3V0ZXJIVE1MKG4pKTsKCgkJCXJldHVybiBuOwoJCX0sCgoJCWdldE5vZGUgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCByID0gdC5nZXRSbmcoKSwgcyA9IHQuZ2V0U2VsKCksIGU7CgoJCQlpZiAoIWlzSUUpIHsKCQkJCS8vIFJhbmdlIG1heWJlIGxvc3QgYWZ0ZXIgdGhlIGVkaXRvciBpcyBtYWRlIHZpc2libGUgYWdhaW4KCQkJCWlmICghcikKCQkJCQlyZXR1cm4gdC5kb20uZ2V0Um9vdCgpOwoKCQkJCWUgPSByLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyOwoKCQkJCS8vIEhhbmRsZSBzZWxlY3Rpb24gYSBpbWFnZSBvciBvdGhlciBjb250cm9sIGxpa2UgZWxlbWVudCBzdWNoIGFzIGFuY2hvcnMKCQkJCWlmICghci5jb2xsYXBzZWQpIHsKCQkJCQkvLyBJZiB0aGUgYW5jaG9yIG5vZGUgaXMgYSBlbGVtZW50IGluc3RlYWQgb2YgYSB0ZXh0IG5vZGUgdGhlbiByZXR1cm4gdGhpcyBlbGVtZW50CgkJCQkJaWYgKHRpbnltY2UuaXNXZWJLaXQgJiYgcy5hbmNob3JOb2RlICYmIHMuYW5jaG9yTm9kZS5ub2RlVHlwZSA9PSAxKSAKCQkJCQkJcmV0dXJuIHMuYW5jaG9yTm9kZS5jaGlsZE5vZGVzW3MuYW5jaG9yT2Zmc2V0XTsgCgoJCQkJCWlmIChyLnN0YXJ0Q29udGFpbmVyID09IHIuZW5kQ29udGFpbmVyKSB7CgkJCQkJCWlmIChyLnN0YXJ0T2Zmc2V0IC0gci5lbmRPZmZzZXQgPCAyKSB7CgkJCQkJCQlpZiAoci5zdGFydENvbnRhaW5lci5oYXNDaGlsZE5vZGVzKCkpCgkJCQkJCQkJZSA9IHIuc3RhcnRDb250YWluZXIuY2hpbGROb2Rlc1tyLnN0YXJ0T2Zmc2V0XTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCgkJCQlyZXR1cm4gdC5kb20uZ2V0UGFyZW50KGUsICcqJyk7CgkJCX0KCgkJCXJldHVybiByLml0ZW0gPyByLml0ZW0oMCkgOiByLnBhcmVudEVsZW1lbnQoKTsKCQl9LAoKCQlnZXRTZWxlY3RlZEJsb2NrcyA6IGZ1bmN0aW9uKHN0LCBlbikgewoJCQl2YXIgdCA9IHRoaXMsIGRvbSA9IHQuZG9tLCBzYiwgZWIsIG4sIGJsID0gW107CgoJCQlzYiA9IGRvbS5nZXRQYXJlbnQoc3QgfHwgdC5nZXRTdGFydCgpLCBkb20uaXNCbG9jayk7CgkJCWViID0gZG9tLmdldFBhcmVudChlbiB8fCB0LmdldEVuZCgpLCBkb20uaXNCbG9jayk7CgoJCQlpZiAoc2IpCgkJCQlibC5wdXNoKHNiKTsKCgkJCWlmIChzYiAmJiBlYiAmJiBzYiAhPSBlYikgewoJCQkJbiA9IHNiOwoKCQkJCXdoaWxlICgobiA9IG4ubmV4dFNpYmxpbmcpICYmIG4gIT0gZWIpIHsKCQkJCQlpZiAoZG9tLmlzQmxvY2sobikpCgkJCQkJCWJsLnB1c2gobik7CgkJCQl9CgkJCX0KCgkJCWlmIChlYiAmJiBzYiAhPSBlYikKCQkJCWJsLnB1c2goZWIpOwoKCQkJcmV0dXJuIGJsOwoJCX0sCgoJCWRlc3Ryb3kgOiBmdW5jdGlvbihzKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXQud2luID0gbnVsbDsKCgkJCWlmICh0LnRyaWRlbnRTZWwpCgkJCQl0LnRyaWRlbnRTZWwuZGVzdHJveSgpOwoKCQkJLy8gTWFudWFsIGRlc3Ryb3kgdGhlbiByZW1vdmUgdW5sb2FkIGhhbmRsZXIKCQkJaWYgKCFzKQoJCQkJdGlueW1jZS5yZW1vdmVVbmxvYWQodC5kZXN0cm95KTsKCQl9CgoJCX0pOwp9KSh0aW55bWNlKTsKKGZ1bmN0aW9uKHRpbnltY2UpIHsKCXRpbnltY2UuY3JlYXRlKCd0aW55bWNlLmRvbS5YTUxXcml0ZXInLCB7CgkJbm9kZSA6IG51bGwsCgoJCVhNTFdyaXRlciA6IGZ1bmN0aW9uKHMpIHsKCQkJLy8gR2V0IFhNTCBkb2N1bWVudAoJCQlmdW5jdGlvbiBnZXRYTUwoKSB7CgkJCQl2YXIgaSA9IGRvY3VtZW50LmltcGxlbWVudGF0aW9uOwoKCQkJCWlmICghaSB8fCAhaS5jcmVhdGVEb2N1bWVudCkgewoJCQkJCS8vIFRyeSBJRSBvYmplY3RzCgkJCQkJdHJ5IHtyZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01TWE1MMi5ET01Eb2N1bWVudCcpO30gY2F0Y2ggKGV4KSB7fQoJCQkJCXRyeSB7cmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWG1sRG9tJyk7fSBjYXRjaCAoZXgpIHt9CgkJCQl9IGVsc2UKCQkJCQlyZXR1cm4gaS5jcmVhdGVEb2N1bWVudCgnJywgJycsIG51bGwpOwoJCQl9OwoKCQkJdGhpcy5kb2MgPSBnZXRYTUwoKTsKCgkJCS8vIFNpbmNlIE9wZXJhIGFuZCBXZWJLaXQgZG9lc24ndCBlc2NhcGUgPiBpbnRvICZndDsgd2UgbmVlZCB0byBkbyBpdCBvdXIgc2VsZiB0byBub3JtYWxpemUgdGhlIG91dHB1dCBmb3IgYWxsIGJyb3dzZXJzCgkJCXRoaXMudmFsaWQgPSB0aW55bWNlLmlzT3BlcmEgfHwgdGlueW1jZS5pc1dlYktpdDsKCgkJCXRoaXMucmVzZXQoKTsKCQl9LAoKCQlyZXNldCA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXMsIGQgPSB0LmRvYzsKCgkJCWlmIChkLmZpcnN0Q2hpbGQpCgkJCQlkLnJlbW92ZUNoaWxkKGQuZmlyc3RDaGlsZCk7CgoJCQl0Lm5vZGUgPSBkLmFwcGVuZENoaWxkKGQuY3JlYXRlRWxlbWVudCgiaHRtbCIpKTsKCQl9LAoKCQl3cml0ZVN0YXJ0RWxlbWVudCA6IGZ1bmN0aW9uKG4pIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJdC5ub2RlID0gdC5ub2RlLmFwcGVuZENoaWxkKHQuZG9jLmNyZWF0ZUVsZW1lbnQobikpOwoJCX0sCgoJCXdyaXRlQXR0cmlidXRlIDogZnVuY3Rpb24obiwgdikgewoJCQlpZiAodGhpcy52YWxpZCkKCQkJCXYgPSB2LnJlcGxhY2UoLz4vZywgJyVNQ0dUJScpOwoKCQkJdGhpcy5ub2RlLnNldEF0dHJpYnV0ZShuLCB2KTsKCQl9LAoKCQl3cml0ZUVuZEVsZW1lbnQgOiBmdW5jdGlvbigpIHsKCQkJdGhpcy5ub2RlID0gdGhpcy5ub2RlLnBhcmVudE5vZGU7CgkJfSwKCgkJd3JpdGVGdWxsRW5kRWxlbWVudCA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXMsIG4gPSB0Lm5vZGU7CgoJCQluLmFwcGVuZENoaWxkKHQuZG9jLmNyZWF0ZVRleHROb2RlKCIiKSk7CgkJCXQubm9kZSA9IG4ucGFyZW50Tm9kZTsKCQl9LAoKCQl3cml0ZVRleHQgOiBmdW5jdGlvbih2KSB7CgkJCWlmICh0aGlzLnZhbGlkKQoJCQkJdiA9IHYucmVwbGFjZSgvPi9nLCAnJU1DR1QlJyk7CgoJCQl0aGlzLm5vZGUuYXBwZW5kQ2hpbGQodGhpcy5kb2MuY3JlYXRlVGV4dE5vZGUodikpOwoJCX0sCgoJCXdyaXRlQ0RBVEEgOiBmdW5jdGlvbih2KSB7CgkJCXRoaXMubm9kZS5hcHBlbmRDaGlsZCh0aGlzLmRvYy5jcmVhdGVDREFUQVNlY3Rpb24odikpOwoJCX0sCgoJCXdyaXRlQ29tbWVudCA6IGZ1bmN0aW9uKHYpIHsKCQkJLy8gRml4IGZvciBidWcgIzIwMzU2OTQKCQkJaWYgKHRpbnltY2UuaXNJRSkKCQkJCXYgPSB2LnJlcGxhY2UoL15cLXxcLSQvZywgJyAnKTsKCgkJCXRoaXMubm9kZS5hcHBlbmRDaGlsZCh0aGlzLmRvYy5jcmVhdGVDb21tZW50KHYucmVwbGFjZSgvXC1cLS9nLCAnICcpKSk7CgkJfSwKCgkJZ2V0Q29udGVudCA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgaDsKCgkJCWggPSB0aGlzLmRvYy54bWwgfHwgbmV3IFhNTFNlcmlhbGl6ZXIoKS5zZXJpYWxpemVUb1N0cmluZyh0aGlzLmRvYyk7CgkJCWggPSBoLnJlcGxhY2UoLzxcP1teP10rXD8+fDxodG1sPnw8XC9odG1sPnw8aHRtbFwvPnw8IURPQ1RZUEVbXj5dKz4vZywgJycpOwoJCQloID0gaC5yZXBsYWNlKC8gP1wvPi9nLCAnIC8+Jyk7CgoJCQlpZiAodGhpcy52YWxpZCkKCQkJCWggPSBoLnJlcGxhY2UoL1wlTUNHVCUvZywgJyZndDsnKTsKCgkJCXJldHVybiBoOwoJCX0KCgkJfSk7Cn0pKHRpbnltY2UpOwooZnVuY3Rpb24odGlueW1jZSkgewoJdGlueW1jZS5jcmVhdGUoJ3RpbnltY2UuZG9tLlN0cmluZ1dyaXRlcicsIHsKCQlzdHIgOiBudWxsLAoJCXRhZ3MgOiBudWxsLAoJCWNvdW50IDogMCwKCQlzZXR0aW5ncyA6IG51bGwsCgkJaW5kZW50IDogbnVsbCwKCgkJU3RyaW5nV3JpdGVyIDogZnVuY3Rpb24ocykgewoJCQl0aGlzLnNldHRpbmdzID0gdGlueW1jZS5leHRlbmQoewoJCQkJaW5kZW50X2NoYXIgOiAnICcsCgkJCQlpbmRlbnRhdGlvbiA6IDAKCQkJfSwgcyk7CgoJCQl0aGlzLnJlc2V0KCk7CgkJfSwKCgkJcmVzZXQgOiBmdW5jdGlvbigpIHsKCQkJdGhpcy5pbmRlbnQgPSAnJzsKCQkJdGhpcy5zdHIgPSAiIjsKCQkJdGhpcy50YWdzID0gW107CgkJCXRoaXMuY291bnQgPSAwOwoJCX0sCgoJCXdyaXRlU3RhcnRFbGVtZW50IDogZnVuY3Rpb24obikgewoJCQl0aGlzLl93cml0ZUF0dHJpYnV0ZXNFbmQoKTsKCQkJdGhpcy53cml0ZVJhdygnPCcgKyBuKTsKCQkJdGhpcy50YWdzLnB1c2gobik7CgkJCXRoaXMuaW5BdHRyID0gdHJ1ZTsKCQkJdGhpcy5jb3VudCsrOwoJCQl0aGlzLmVsZW1lbnRDb3VudCA9IHRoaXMuY291bnQ7CgkJfSwKCgkJd3JpdGVBdHRyaWJ1dGUgOiBmdW5jdGlvbihuLCB2KSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXQud3JpdGVSYXcoIiAiICsgdC5lbmNvZGUobikgKyAnPSInICsgdC5lbmNvZGUodikgKyAnIicpOwoJCX0sCgoJCXdyaXRlRW5kRWxlbWVudCA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgbjsKCgkJCWlmICh0aGlzLnRhZ3MubGVuZ3RoID4gMCkgewoJCQkJbiA9IHRoaXMudGFncy5wb3AoKTsKCgkJCQlpZiAodGhpcy5fd3JpdGVBdHRyaWJ1dGVzRW5kKDEpKQoJCQkJCXRoaXMud3JpdGVSYXcoJzwvJyArIG4gKyAnPicpOwoKCQkJCWlmICh0aGlzLnNldHRpbmdzLmluZGVudGF0aW9uID4gMCkKCQkJCQl0aGlzLndyaXRlUmF3KCdcbicpOwoJCQl9CgkJfSwKCgkJd3JpdGVGdWxsRW5kRWxlbWVudCA6IGZ1bmN0aW9uKCkgewoJCQlpZiAodGhpcy50YWdzLmxlbmd0aCA+IDApIHsKCQkJCXRoaXMuX3dyaXRlQXR0cmlidXRlc0VuZCgpOwoJCQkJdGhpcy53cml0ZVJhdygnPC8nICsgdGhpcy50YWdzLnBvcCgpICsgJz4nKTsKCgkJCQlpZiAodGhpcy5zZXR0aW5ncy5pbmRlbnRhdGlvbiA+IDApCgkJCQkJdGhpcy53cml0ZVJhdygnXG4nKTsKCQkJfQoJCX0sCgoJCXdyaXRlVGV4dCA6IGZ1bmN0aW9uKHYpIHsKCQkJdGhpcy5fd3JpdGVBdHRyaWJ1dGVzRW5kKCk7CgkJCXRoaXMud3JpdGVSYXcodGhpcy5lbmNvZGUodikpOwoJCQl0aGlzLmNvdW50Kys7CgkJfSwKCgkJd3JpdGVDREFUQSA6IGZ1bmN0aW9uKHYpIHsKCQkJdGhpcy5fd3JpdGVBdHRyaWJ1dGVzRW5kKCk7CgkJCXRoaXMud3JpdGVSYXcoJzwhW0NEQVRBWycgKyB2ICsgJ11dPicpOwoJCQl0aGlzLmNvdW50Kys7CgkJfSwKCgkJd3JpdGVDb21tZW50IDogZnVuY3Rpb24odikgewoJCQl0aGlzLl93cml0ZUF0dHJpYnV0ZXNFbmQoKTsKCQkJdGhpcy53cml0ZVJhdygnPCEtLSAnICsgdiArICctLT4nKTsKCQkJdGhpcy5jb3VudCsrOwoJCX0sCgoJCXdyaXRlUmF3IDogZnVuY3Rpb24odikgewoJCQl0aGlzLnN0ciArPSB2OwoJCX0sCgoJCWVuY29kZSA6IGZ1bmN0aW9uKHMpIHsKCQkJcmV0dXJuIHMucmVwbGFjZSgvWzw+JiJdL2csIGZ1bmN0aW9uKHYpIHsKCQkJCXN3aXRjaCAodikgewoJCQkJCWNhc2UgJzwnOgoJCQkJCQlyZXR1cm4gJyZsdDsnOwoKCQkJCQljYXNlICc+JzoKCQkJCQkJcmV0dXJuICcmZ3Q7JzsKCgkJCQkJY2FzZSAnJic6CgkJCQkJCXJldHVybiAnJmFtcDsnOwoKCQkJCQljYXNlICciJzoKCQkJCQkJcmV0dXJuICcmcXVvdDsnOwoJCQkJfQoKCQkJCXJldHVybiB2OwoJCQl9KTsKCQl9LAoKCQlnZXRDb250ZW50IDogZnVuY3Rpb24oKSB7CgkJCXJldHVybiB0aGlzLnN0cjsKCQl9LAoKCQlfd3JpdGVBdHRyaWJ1dGVzRW5kIDogZnVuY3Rpb24ocykgewoJCQlpZiAoIXRoaXMuaW5BdHRyKQoJCQkJcmV0dXJuOwoKCQkJdGhpcy5pbkF0dHIgPSBmYWxzZTsKCgkJCWlmIChzICYmIHRoaXMuZWxlbWVudENvdW50ID09IHRoaXMuY291bnQpIHsKCQkJCXRoaXMud3JpdGVSYXcoJyAvPicpOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgoJCQl0aGlzLndyaXRlUmF3KCc+Jyk7CgoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCX0pOwp9KSh0aW55bWNlKTsKKGZ1bmN0aW9uKHRpbnltY2UpIHsKCS8vIFNob3J0ZW4gbmFtZXMKCXZhciBleHRlbmQgPSB0aW55bWNlLmV4dGVuZCwgZWFjaCA9IHRpbnltY2UuZWFjaCwgRGlzcGF0Y2hlciA9IHRpbnltY2UudXRpbC5EaXNwYXRjaGVyLCBpc0lFID0gdGlueW1jZS5pc0lFLCBpc0dlY2tvID0gdGlueW1jZS5pc0dlY2tvOwoKCWZ1bmN0aW9uIHdpbGRjYXJkVG9SRShzKSB7CgkJcmV0dXJuIHMucmVwbGFjZSgvKFs/KypdKS9nLCAnLiQxJyk7Cgl9OwoKCXRpbnltY2UuY3JlYXRlKCd0aW55bWNlLmRvbS5TZXJpYWxpemVyJywgewoJCVNlcmlhbGl6ZXIgOiBmdW5jdGlvbihzKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXQua2V5ID0gMDsKCQkJdC5vblByZVByb2Nlc3MgPSBuZXcgRGlzcGF0Y2hlcih0KTsKCQkJdC5vblBvc3RQcm9jZXNzID0gbmV3IERpc3BhdGNoZXIodCk7CgoJCQl0cnkgewoJCQkJdC53cml0ZXIgPSBuZXcgdGlueW1jZS5kb20uWE1MV3JpdGVyKCk7CgkJCX0gY2F0Y2ggKGV4KSB7CgkJCQkvLyBJRSBtaWdodCB0aHJvdyBleGNlcHRpb24gaWYgQWN0aXZlWCBpcyBkaXNhYmxlZCBzbyB3ZSB0aGVuIHN3aXRjaCB0byB0aGUgc2xpZ2h0bHkgc2xvd2VyIFN0cmluZ1dyaXRlcgoJCQkJdC53cml0ZXIgPSBuZXcgdGlueW1jZS5kb20uU3RyaW5nV3JpdGVyKCk7CgkJCX0KCgkJCS8vIERlZmF1bHQgc2V0dGluZ3MKCQkJdC5zZXR0aW5ncyA9IHMgPSBleHRlbmQoewoJCQkJZG9tIDogdGlueW1jZS5ET00sCgkJCQl2YWxpZF9ub2RlcyA6IDAsCgkJCQlub2RlX2ZpbHRlciA6IDAsCgkJCQlhdHRyX2ZpbHRlciA6IDAsCgkJCQlpbnZhbGlkX2F0dHJzIDogL14obWNlX3xfbW96X3xzaXpzZXR8c2l6Y2FjaGUpLywKCQkJCWNsb3NlZCA6IC9eKGJyfGhyfGlucHV0fG1ldGF8aW1nfGxpbmt8cGFyYW18YXJlYSkkLywKCQkJCWVudGl0eV9lbmNvZGluZyA6ICduYW1lZCcsCgkJCQllbnRpdGllcyA6ICcxNjAsbmJzcCwxNjEsaWV4Y2wsMTYyLGNlbnQsMTYzLHBvdW5kLDE2NCxjdXJyZW4sMTY1LHllbiwxNjYsYnJ2YmFyLDE2NyxzZWN0LDE2OCx1bWwsMTY5LGNvcHksMTcwLG9yZGYsMTcxLGxhcXVvLDE3Mixub3QsMTczLHNoeSwxNzQscmVnLDE3NSxtYWNyLDE3NixkZWcsMTc3LHBsdXNtbiwxNzgsc3VwMiwxNzksc3VwMywxODAsYWN1dGUsMTgxLG1pY3JvLDE4MixwYXJhLDE4MyxtaWRkb3QsMTg0LGNlZGlsLDE4NSxzdXAxLDE4NixvcmRtLDE4NyxyYXF1bywxODgsZnJhYzE0LDE4OSxmcmFjMTIsMTkwLGZyYWMzNCwxOTEsaXF1ZXN0LDE5MixBZ3JhdmUsMTkzLEFhY3V0ZSwxOTQsQWNpcmMsMTk1LEF0aWxkZSwxOTYsQXVtbCwxOTcsQXJpbmcsMTk4LEFFbGlnLDE5OSxDY2VkaWwsMjAwLEVncmF2ZSwyMDEsRWFjdXRlLDIwMixFY2lyYywyMDMsRXVtbCwyMDQsSWdyYXZlLDIwNSxJYWN1dGUsMjA2LEljaXJjLDIwNyxJdW1sLDIwOCxFVEgsMjA5LE50aWxkZSwyMTAsT2dyYXZlLDIxMSxPYWN1dGUsMjEyLE9jaXJjLDIxMyxPdGlsZGUsMjE0LE91bWwsMjE1LHRpbWVzLDIxNixPc2xhc2gsMjE3LFVncmF2ZSwyMTgsVWFjdXRlLDIxOSxVY2lyYywyMjAsVXVtbCwyMjEsWWFjdXRlLDIyMixUSE9STiwyMjMsc3psaWcsMjI0LGFncmF2ZSwyMjUsYWFjdXRlLDIyNixhY2lyYywyMjcsYXRpbGRlLDIyOCxhdW1sLDIyOSxhcmluZywyMzAsYWVsaWcsMjMxLGNjZWRpbCwyMzIsZWdyYXZlLDIzMyxlYWN1dGUsMjM0LGVjaXJjLDIzNSxldW1sLDIzNixpZ3JhdmUsMjM3LGlhY3V0ZSwyMzgsaWNpcmMsMjM5LGl1bWwsMjQwLGV0aCwyNDEsbnRpbGRlLDI0MixvZ3JhdmUsMjQzLG9hY3V0ZSwyNDQsb2NpcmMsMjQ1LG90aWxkZSwyNDYsb3VtbCwyNDcsZGl2aWRlLDI0OCxvc2xhc2gsMjQ5LHVncmF2ZSwyNTAsdWFjdXRlLDI1MSx1Y2lyYywyNTIsdXVtbCwyNTMseWFjdXRlLDI1NCx0aG9ybiwyNTUseXVtbCw0MDIsZm5vZiw5MTMsQWxwaGEsOTE0LEJldGEsOTE1LEdhbW1hLDkxNixEZWx0YSw5MTcsRXBzaWxvbiw5MTgsWmV0YSw5MTksRXRhLDkyMCxUaGV0YSw5MjEsSW90YSw5MjIsS2FwcGEsOTIzLExhbWJkYSw5MjQsTXUsOTI1LE51LDkyNixYaSw5MjcsT21pY3Jvbiw5MjgsUGksOTI5LFJobyw5MzEsU2lnbWEsOTMyLFRhdSw5MzMsVXBzaWxvbiw5MzQsUGhpLDkzNSxDaGksOTM2LFBzaSw5MzcsT21lZ2EsOTQ1LGFscGhhLDk0NixiZXRhLDk0NyxnYW1tYSw5NDgsZGVsdGEsOTQ5LGVwc2lsb24sOTUwLHpldGEsOTUxLGV0YSw5NTIsdGhldGEsOTUzLGlvdGEsOTU0LGthcHBhLDk1NSxsYW1iZGEsOTU2LG11LDk1NyxudSw5NTgseGksOTU5LG9taWNyb24sOTYwLHBpLDk2MSxyaG8sOTYyLHNpZ21hZiw5NjMsc2lnbWEsOTY0LHRhdSw5NjUsdXBzaWxvbiw5NjYscGhpLDk2NyxjaGksOTY4LHBzaSw5Njksb21lZ2EsOTc3LHRoZXRhc3ltLDk3OCx1cHNpaCw5ODIscGl2LDgyMjYsYnVsbCw4MjMwLGhlbGxpcCw4MjQyLHByaW1lLDgyNDMsUHJpbWUsODI1NCxvbGluZSw4MjYwLGZyYXNsLDg0NzIsd2VpZXJwLDg0NjUsaW1hZ2UsODQ3NixyZWFsLDg0ODIsdHJhZGUsODUwMSxhbGVmc3ltLDg1OTIsbGFyciw4NTkzLHVhcnIsODU5NCxyYXJyLDg1OTUsZGFyciw4NTk2LGhhcnIsODYyOSxjcmFyciw4NjU2LGxBcnIsODY1Nyx1QXJyLDg2NTgsckFyciw4NjU5LGRBcnIsODY2MCxoQXJyLDg3MDQsZm9yYWxsLDg3MDYscGFydCw4NzA3LGV4aXN0LDg3MDksZW1wdHksODcxMSxuYWJsYSw4NzEyLGlzaW4sODcxMyxub3Rpbiw4NzE1LG5pLDg3MTkscHJvZCw4NzIxLHN1bSw4NzIyLG1pbnVzLDg3MjcsbG93YXN0LDg3MzAscmFkaWMsODczMyxwcm9wLDg3MzQsaW5maW4sODczNixhbmcsODc0MyxhbmQsODc0NCxvciw4NzQ1LGNhcCw4NzQ2LGN1cCw4NzQ3LGludCw4NzU2LHRoZXJlNCw4NzY0LHNpbSw4NzczLGNvbmcsODc3Nixhc3ltcCw4ODAwLG5lLDg4MDEsZXF1aXYsODgwNCxsZSw4ODA1LGdlLDg4MzQsc3ViLDg4MzUsc3VwLDg4MzYsbnN1Yiw4ODM4LHN1YmUsODgzOSxzdXBlLDg4NTMsb3BsdXMsODg1NSxvdGltZXMsODg2OSxwZXJwLDg5MDEsc2RvdCw4OTY4LGxjZWlsLDg5NjkscmNlaWwsODk3MCxsZmxvb3IsODk3MSxyZmxvb3IsOTAwMSxsYW5nLDkwMDIscmFuZyw5Njc0LGxveiw5ODI0LHNwYWRlcyw5ODI3LGNsdWJzLDk4MjksaGVhcnRzLDk4MzAsZGlhbXMsMzM4LE9FbGlnLDMzOSxvZWxpZywzNTIsU2Nhcm9uLDM1MyxzY2Fyb24sMzc2LFl1bWwsNzEwLGNpcmMsNzMyLHRpbGRlLDgxOTQsZW5zcCw4MTk1LGVtc3AsODIwMSx0aGluc3AsODIwNCx6d25qLDgyMDUsendqLDgyMDYsbHJtLDgyMDcscmxtLDgyMTEsbmRhc2gsODIxMixtZGFzaCw4MjE2LGxzcXVvLDgyMTcscnNxdW8sODIxOCxzYnF1byw4MjIwLGxkcXVvLDgyMjEscmRxdW8sODIyMixiZHF1byw4MjI0LGRhZ2dlciw4MjI1LERhZ2dlciw4MjQwLHBlcm1pbCw4MjQ5LGxzYXF1byw4MjUwLHJzYXF1byw4MzY0LGV1cm8nLAoJCQkJYm9vbF9hdHRycyA6IC8oY2hlY2tlZHxkaXNhYmxlZHxyZWFkb25seXxzZWxlY3RlZHxub3dyYXApLywKCQkJCXZhbGlkX2VsZW1lbnRzIDogJypbKl0nLAoJCQkJZXh0ZW5kZWRfdmFsaWRfZWxlbWVudHMgOiAwLAoJCQkJdmFsaWRfY2hpbGRfZWxlbWVudHMgOiAwLAoJCQkJaW52YWxpZF9lbGVtZW50cyA6IDAsCgkJCQlmaXhfdGFibGVfZWxlbWVudHMgOiAxLAoJCQkJZml4X2xpc3RfZWxlbWVudHMgOiB0cnVlLAoJCQkJZml4X2NvbnRlbnRfZHVwbGljYXRpb24gOiB0cnVlLAoJCQkJY29udmVydF9mb250c190b19zcGFucyA6IGZhbHNlLAoJCQkJZm9udF9zaXplX2NsYXNzZXMgOiAwLAoJCQkJZm9udF9zaXplX3N0eWxlX3ZhbHVlcyA6IDAsCgkJCQlhcHBseV9zb3VyY2VfZm9ybWF0dGluZyA6IDAsCgkJCQlpbmRlbnRfbW9kZSA6ICdzaW1wbGUnLAoJCQkJaW5kZW50X2NoYXIgOiAnXHQnLAoJCQkJaW5kZW50X2xldmVscyA6IDEsCgkJCQlyZW1vdmVfbGluZWJyZWFrcyA6IDEsCgkJCQlyZW1vdmVfcmVkdW5kYW50X2JycyA6IDEsCgkJCQllbGVtZW50X2Zvcm1hdCA6ICd4aHRtbCcKCQkJfSwgcyk7CgoJCQl0LmRvbSA9IHMuZG9tOwoKCQkJaWYgKHMucmVtb3ZlX3JlZHVuZGFudF9icnMpIHsKCQkJCXQub25Qb3N0UHJvY2Vzcy5hZGQoZnVuY3Rpb24oc2UsIG8pIHsKCQkJCQkvLyBSZW1vdmUgc2luZ2xlIEJSIGF0IGVuZCBvZiBibG9jayBlbGVtZW50cyBzaW5jZSB0aGV5IGdldCByZW5kZXJlZAoJCQkJCW8uY29udGVudCA9IG8uY29udGVudC5yZXBsYWNlKC8oPGJyIFwvPlxzKikrPFwvKHB8aFsxLTZdfGRpdnxsaSk+L2dpLCBmdW5jdGlvbihhLCBiLCBjKSB7CgkJCQkJCS8vIENoZWNrIGlmIGl0J3MgYSBzaW5nbGUgZWxlbWVudAoJCQkJCQlpZiAoL148YnIgXC8+XHMqPFwvLy50ZXN0KGEpKQoJCQkJCQkJcmV0dXJuICc8LycgKyBjICsgJz4nOwoKCQkJCQkJcmV0dXJuIGE7CgkJCQkJfSk7CgkJCQl9KTsKCQkJfQoKCQkJLy8gUmVtb3ZlIFhIVE1MIGVsZW1lbnQgZW5kaW5ncyBpLmUuIHByb2R1Y2UgY3JhcCA6KSBYSFRNTCBpcyBiZXR0ZXIKCQkJaWYgKHMuZWxlbWVudF9mb3JtYXQgPT0gJ2h0bWwnKSB7CgkJCQl0Lm9uUG9zdFByb2Nlc3MuYWRkKGZ1bmN0aW9uKHNlLCBvKSB7CgkJCQkJby5jb250ZW50ID0gby5jb250ZW50LnJlcGxhY2UoLzwoW14+XSspIFwvPi9nLCAnPCQxPicpOwoJCQkJfSk7CgkJCX0KCgkJCWlmIChzLmZpeF9saXN0X2VsZW1lbnRzKSB7CgkJCQl0Lm9uUHJlUHJvY2Vzcy5hZGQoZnVuY3Rpb24oc2UsIG8pIHsKCQkJCQl2YXIgbmwsIHgsIGEgPSBbJ29sJywgJ3VsJ10sIGksIG4sIHAsIHIgPSAvXihPTHxVTCkkLywgbnA7CgoJCQkJCWZ1bmN0aW9uIHByZXZOb2RlKGUsIG4pIHsKCQkJCQkJdmFyIGEgPSBuLnNwbGl0KCcsJyksIGk7CgoJCQkJCQl3aGlsZSAoKGUgPSBlLnByZXZpb3VzU2libGluZykgIT0gbnVsbCkgewoJCQkJCQkJZm9yIChpPTA7IGk8YS5sZW5ndGg7IGkrKykgewoJCQkJCQkJCWlmIChlLm5vZGVOYW1lID09IGFbaV0pCgkJCQkJCQkJCXJldHVybiBlOwoJCQkJCQkJfQoJCQkJCQl9CgoJCQkJCQlyZXR1cm4gbnVsbDsKCQkJCQl9OwoKCQkJCQlmb3IgKHg9MDsgeDxhLmxlbmd0aDsgeCsrKSB7CgkJCQkJCW5sID0gdC5kb20uc2VsZWN0KGFbeF0sIG8ubm9kZSk7CgoJCQkJCQlmb3IgKGk9MDsgaTxubC5sZW5ndGg7IGkrKykgewoJCQkJCQkJbiA9IG5sW2ldOwoJCQkJCQkJcCA9IG4ucGFyZW50Tm9kZTsKCgkJCQkJCQlpZiAoci50ZXN0KHAubm9kZU5hbWUpKSB7CgkJCQkJCQkJbnAgPSBwcmV2Tm9kZShuLCAnTEknKTsKCgkJCQkJCQkJaWYgKCFucCkgewoJCQkJCQkJCQlucCA9IHQuZG9tLmNyZWF0ZSgnbGknKTsKCQkJCQkJCQkJbnAuaW5uZXJIVE1MID0gJyZuYnNwOyc7CgkJCQkJCQkJCW5wLmFwcGVuZENoaWxkKG4pOwoJCQkJCQkJCQlwLmluc2VydEJlZm9yZShucCwgcC5maXJzdENoaWxkKTsKCQkJCQkJCQl9IGVsc2UKCQkJCQkJCQkJbnAuYXBwZW5kQ2hpbGQobik7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9KTsKCQkJfQoKCQkJaWYgKHMuZml4X3RhYmxlX2VsZW1lbnRzKSB7CgkJCQl0Lm9uUHJlUHJvY2Vzcy5hZGQoZnVuY3Rpb24oc2UsIG8pIHsKCQkJCQllYWNoKHQuZG9tLnNlbGVjdCgncCB0YWJsZScsIG8ubm9kZSksIGZ1bmN0aW9uKG4pIHsKCQkJCQkJLy8gSUUgaGFzIGEgb2RkIGJ1ZyB3aGVyZSB0YWJsZXMgaW5zaWRlIHBhcmFncmFwaHMgc29tZXRpbWVzIGdldHMgd3JhcHBlZCBpbiBhIEJPRFkgYW5kIGRvY3VtZW50RnJhZ2VtZW50IGVsZW1lbnQKCQkJCQkJLy8gVGhpcyBoYWNrIHNlZW1zIHRvIHJlc29sdmUgdGhhdCBpc3N1ZS4gVGhpcyB3aWxsIG5vcm1hbGx5IG5vdCBoYXBwZWQgc2luY2UgeW91ciBjb250ZW50cyBzaG91bGQgYmUgdmFsaWQgaW4gdGhlIGZpcnN0IHBsYWNlCgkJCQkJCWlmIChpc0lFKQoJCQkJCQkJbi5vdXRlckhUTUwgPSBuLm91dGVySFRNTDsKCgkJCQkJCXQuZG9tLnNwbGl0KHQuZG9tLmdldFBhcmVudChuLCAncCcpLCBuKTsKCQkJCQl9KTsKCQkJCX0pOwoJCQl9CgkJfSwKCgkJc2V0RW50aXRpZXMgOiBmdW5jdGlvbihzKSB7CgkJCXZhciB0ID0gdGhpcywgYSwgaSwgbCA9IHt9LCByZSA9ICcnLCB2OwoKCQkJLy8gTm8gbmVlZCB0byBzZXR1cCBtb3JlIHRoYW4gb25jZQoJCQlpZiAodC5lbnRpdHlMb29rdXApCgkJCQlyZXR1cm47CgoJCQkvLyBCdWlsZCByZWdleCBhbmQgbG9va3VwIGFycmF5CgkJCWEgPSBzLnNwbGl0KCcsJyk7CgkJCWZvciAoaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSArPSAyKSB7CgkJCQl2ID0gYVtpXTsKCgkJCQkvLyBEb24ndCBhZGQgZGVmYXVsdCAmYW1wOyAmcXVvdDsgZXRjLgoJCQkJaWYgKHYgPT0gMzQgfHwgdiA9PSAzOCB8fCB2ID09IDYwIHx8IHYgPT0gNjIpCgkJCQkJY29udGludWU7CgoJCQkJbFtTdHJpbmcuZnJvbUNoYXJDb2RlKGFbaV0pXSA9IGFbaSArIDFdOwoKCQkJCXYgPSBwYXJzZUludChhW2ldKS50b1N0cmluZygxNik7CgkJCQlyZSArPSAnXFx1JyArICcwMDAwJy5zdWJzdHJpbmcodi5sZW5ndGgpICsgdjsKCQkJfQoKCQkJaWYgKCFyZSkgewoJCQkJdC5zZXR0aW5ncy5lbnRpdHlfZW5jb2RpbmcgPSAncmF3JzsKCQkJCXJldHVybjsKCQkJfQoKCQkJdC5lbnRpdGllc1JFID0gbmV3IFJlZ0V4cCgnWycgKyByZSArICddJywgJ2cnKTsKCQkJdC5lbnRpdHlMb29rdXAgPSBsOwoJCX0sCgoJCXNldFZhbGlkQ2hpbGRSdWxlcyA6IGZ1bmN0aW9uKHMpIHsKCQkJdGhpcy5jaGlsZFJ1bGVzID0gbnVsbDsKCQkJdGhpcy5hZGRWYWxpZENoaWxkUnVsZXMocyk7CgkJfSwKCgkJYWRkVmFsaWRDaGlsZFJ1bGVzIDogZnVuY3Rpb24ocykgewoJCQl2YXIgdCA9IHRoaXMsIGluc3QsIGludHIsIGJsb2M7CgoJCQlpZiAoIXMpCgkJCQlyZXR1cm47CgoJCQlpbnN0ID0gJ0F8QlJ8U1BBTnxCRE98TUFQfE9CSkVDVHxJTUd8VFR8SXxCfEJJR3xTTUFMTHxFTXxTVFJPTkd8REZOfENPREV8UXxTQU1QfEtCRHxWQVJ8Q0lURXxBQkJSfEFDUk9OWU18U1VCfFNVUHwjdGV4dHwjY29tbWVudCc7CgkJCWludHIgPSAnQXxCUnxTUEFOfEJET3xPQkpFQ1R8QVBQTEVUfElNR3xNQVB8SUZSQU1FfFRUfEl8QnxVfFN8U1RSSUtFfEJJR3xTTUFMTHxGT05UfEJBU0VGT05UfEVNfFNUUk9OR3xERk58Q09ERXxRfFNBTVB8S0JEfFZBUnxDSVRFfEFCQlJ8QUNST05ZTXxTVUJ8U1VQfElOUFVUfFNFTEVDVHxURVhUQVJFQXxMQUJFTHxCVVRUT058I3RleHR8I2NvbW1lbnQnOwoJCQlibG9jID0gJ0hbMS02XXxQfERJVnxBRERSRVNTfFBSRXxGT1JNfFRBQkxFfExJfE9MfFVMfFREfENBUFRJT058QkxPQ0tRVU9URXxDRU5URVJ8REx8RFR8RER8RElSfEZJRUxEU0VUfEZPUk18Tk9TQ1JJUFR8Tk9GUkFNRVN8TUVOVXxJU0lOREVYfFNBTVAnOwoKCQkJZWFjaChzLnNwbGl0KCcsJyksIGZ1bmN0aW9uKHMpIHsKCQkJCXZhciBwID0gcy5zcGxpdCgvXFt8XF0vKSwgcmU7CgoJCQkJcyA9ICcnOwoJCQkJZWFjaChwWzFdLnNwbGl0KCd8JyksIGZ1bmN0aW9uKHYpIHsKCQkJCQlpZiAocykKCQkJCQkJcyArPSAnfCc7CgoJCQkJCXN3aXRjaCAodikgewoJCQkJCQljYXNlICclaXRyYW5zJzoKCQkJCQkJCXYgPSBpbnRyOwoJCQkJCQkJYnJlYWs7CgoJCQkJCQljYXNlICclaXRyYW5zX25hJzoKCQkJCQkJCXYgPSBpbnRyLnN1YnN0cmluZygyKTsKCQkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSAnJWlzdHJpY3QnOgoJCQkJCQkJdiA9IGluc3Q7CgkJCQkJCQlicmVhazsKCgkJCQkJCWNhc2UgJyVpc3RyaWN0X25hJzoKCQkJCQkJCXYgPSBpbnN0LnN1YnN0cmluZygyKTsKCQkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSAnJWJ0cmFucyc6CgkJCQkJCQl2ID0gYmxvYzsKCQkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSAnJWJzdHJpY3QnOgoJCQkJCQkJdiA9IGJsb2M7CgkJCQkJCQlicmVhazsKCQkJCQl9CgoJCQkJCXMgKz0gdjsKCQkJCX0pOwoJCQkJcmUgPSBuZXcgUmVnRXhwKCdeKCcgKyBzLnRvTG93ZXJDYXNlKCkgKyAnKSQnLCAnaScpOwoKCQkJCWVhY2gocFswXS5zcGxpdCgnLycpLCBmdW5jdGlvbihzKSB7CgkJCQkJdC5jaGlsZFJ1bGVzID0gdC5jaGlsZFJ1bGVzIHx8IHt9OwoJCQkJCXQuY2hpbGRSdWxlc1tzXSA9IHJlOwoJCQkJfSk7CgkJCX0pOwoKCQkJLy8gQnVpbGQgcmVnZXgKCQkJcyA9ICcnOwoJCQllYWNoKHQuY2hpbGRSdWxlcywgZnVuY3Rpb24odiwgaykgewoJCQkJaWYgKHMpCgkJCQkJcyArPSAnfCc7CgoJCQkJcyArPSBrOwoJCQl9KTsKCgkJCXQucGFyZW50RWxlbWVudHNSRSA9IG5ldyBSZWdFeHAoJ14oJyArIHMudG9Mb3dlckNhc2UoKSArICcpJCcsICdpJyk7CgoJCQkvKmNvbnNvbGUuZGVidWcodC5wYXJlbnRFbGVtZW50c1JFLnRvU3RyaW5nKCkpOwoJCQllYWNoKHQuY2hpbGRSdWxlcywgZnVuY3Rpb24odikgewoJCQkJY29uc29sZS5kZWJ1Zyh2LnRvU3RyaW5nKCkpOwoJCQl9KTsqLwoJCX0sCgoJCXNldFJ1bGVzIDogZnVuY3Rpb24ocykgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQl0Ll9zZXR1cCgpOwoJCQl0LnJ1bGVzID0ge307CgkJCXQud2lsZFJ1bGVzID0gW107CgkJCXQudmFsaWRFbGVtZW50cyA9IHt9OwoKCQkJcmV0dXJuIHQuYWRkUnVsZXMocyk7CgkJfSwKCgkJYWRkUnVsZXMgOiBmdW5jdGlvbihzKSB7CgkJCXZhciB0ID0gdGhpcywgZHI7CgoJCQlpZiAoIXMpCgkJCQlyZXR1cm47CgoJCQl0Ll9zZXR1cCgpOwoKCQkJZWFjaChzLnNwbGl0KCcsJyksIGZ1bmN0aW9uKHMpIHsKCQkJCXZhciBwID0gcy5zcGxpdCgvXFt8XF0vKSwgdG4gPSBwWzBdLnNwbGl0KCcvJyksIHJhLCBhdCwgd2F0LCB2YSA9IFtdOwoKCQkJCS8vIEV4dGVuZCB3aXRoIGRlZmF1bHQgcnVsZXMKCQkJCWlmIChkcikKCQkJCQlhdCA9IHRpbnltY2UuZXh0ZW5kKFtdLCBkci5hdHRyaWJzKTsKCgkJCQkvLyBQYXJzZSBhdHRyaWJ1dGVzCgkJCQlpZiAocC5sZW5ndGggPiAxKSB7CgkJCQkJZWFjaChwWzFdLnNwbGl0KCd8JyksIGZ1bmN0aW9uKHMpIHsKCQkJCQkJdmFyIGFyID0ge30sIGk7CgoJCQkJCQlhdCA9IGF0IHx8IFtdOwoKCQkJCQkJLy8gUGFyc2UgYXR0cmlidXRlIHJ1bGUKCQkJCQkJcyA9IHMucmVwbGFjZSgvOjovZywgJ34nKTsKCQkJCQkJcyA9IC9eKFshXC1dKT8oW1x3Ki4/fl9cLV0rfCkoWz06PF0pPyguKyk/JC8uZXhlYyhzKTsKCQkJCQkJc1syXSA9IHNbMl0ucmVwbGFjZSgvfi9nLCAnOicpOwoKCQkJCQkJLy8gQWRkIHJlcXVpcmVkIGF0dHJpYnV0ZXMKCQkJCQkJaWYgKHNbMV0gPT0gJyEnKSB7CgkJCQkJCQlyYSA9IHJhIHx8IFtdOwoJCQkJCQkJcmEucHVzaChzWzJdKTsKCQkJCQkJfQoKCQkJCQkJLy8gUmVtb3ZlIGluaGVyaXRlZCBhdHRyaWJ1dGVzCgkJCQkJCWlmIChzWzFdID09ICctJykgewoJCQkJCQkJZm9yIChpID0gMDsgaSA8YXQubGVuZ3RoOyBpKyspIHsKCQkJCQkJCQlpZiAoYXRbaV0ubmFtZSA9PSBzWzJdKSB7CgkJCQkJCQkJCWF0LnNwbGljZShpLCAxKTsKCQkJCQkJCQkJcmV0dXJuOwoJCQkJCQkJCX0KCQkJCQkJCX0KCQkJCQkJfQoKCQkJCQkJc3dpdGNoIChzWzNdKSB7CgkJCQkJCQkvLyBBZGQgZGVmYXVsdCBhdHRyaWIgdmFsdWVzCgkJCQkJCQljYXNlICc9JzoKCQkJCQkJCQlhci5kZWZhdWx0VmFsID0gc1s0XSB8fCAnJzsKCQkJCQkJCQlicmVhazsKCgkJCQkJCQkvLyBBZGQgZm9yY2VkIGF0dHJpYiB2YWx1ZXMKCQkJCQkJCWNhc2UgJzonOgoJCQkJCQkJCWFyLmZvcmNlZFZhbCA9IHNbNF07CgkJCQkJCQkJYnJlYWs7CgoJCQkJCQkJLy8gQWRkIHZhbGlkYXRpb24gdmFsdWVzCgkJCQkJCQljYXNlICc8JzoKCQkJCQkJCQlhci52YWxpZFZhbHMgPSBzWzRdLnNwbGl0KCc/Jyk7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCgkJCQkJCWlmICgvWyouP10vLnRlc3Qoc1syXSkpIHsKCQkJCQkJCXdhdCA9IHdhdCB8fCBbXTsKCQkJCQkJCWFyLm5hbWVSRSA9IG5ldyBSZWdFeHAoJ14nICsgd2lsZGNhcmRUb1JFKHNbMl0pICsgJyQnKTsKCQkJCQkJCXdhdC5wdXNoKGFyKTsKCQkJCQkJfSBlbHNlIHsKCQkJCQkJCWFyLm5hbWUgPSBzWzJdOwoJCQkJCQkJYXQucHVzaChhcik7CgkJCQkJCX0KCgkJCQkJCXZhLnB1c2goc1syXSk7CgkJCQkJfSk7CgkJCQl9CgoJCQkJLy8gSGFuZGxlIGVsZW1lbnQgbmFtZXMKCQkJCWVhY2godG4sIGZ1bmN0aW9uKHMsIGkpIHsKCQkJCQl2YXIgcHIgPSBzLmNoYXJBdCgwKSwgeCA9IDEsIHJ1ID0ge307CgoJCQkJCS8vIEV4dGVuZCB3aXRoIGRlZmF1bHQgcnVsZSBkYXRhCgkJCQkJaWYgKGRyKSB7CgkJCQkJCWlmIChkci5ub0VtcHR5KQoJCQkJCQkJcnUubm9FbXB0eSA9IGRyLm5vRW1wdHk7CgoJCQkJCQlpZiAoZHIuZnVsbEVuZCkKCQkJCQkJCXJ1LmZ1bGxFbmQgPSBkci5mdWxsRW5kOwoKCQkJCQkJaWYgKGRyLnBhZGQpCgkJCQkJCQlydS5wYWRkID0gZHIucGFkZDsKCQkJCQl9CgoJCQkJCS8vIEhhbmRsZSBwcmVmaXhlcwoJCQkJCXN3aXRjaCAocHIpIHsKCQkJCQkJY2FzZSAnLSc6CgkJCQkJCQlydS5ub0VtcHR5ID0gdHJ1ZTsKCQkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSAnKyc6CgkJCQkJCQlydS5mdWxsRW5kID0gdHJ1ZTsKCQkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSAnIyc6CgkJCQkJCQlydS5wYWRkID0gdHJ1ZTsKCQkJCQkJCWJyZWFrOwoKCQkJCQkJZGVmYXVsdDoKCQkJCQkJCXggPSAwOwoJCQkJCX0KCgkJCQkJdG5baV0gPSBzID0gcy5zdWJzdHJpbmcoeCk7CgkJCQkJdC52YWxpZEVsZW1lbnRzW3NdID0gMTsKCgkJCQkJLy8gQWRkIGVsZW1lbnQgbmFtZSBvciBlbGVtZW50IHJlZ2V4CgkJCQkJaWYgKC9bKi4/XS8udGVzdCh0blswXSkpIHsKCQkJCQkJcnUubmFtZVJFID0gbmV3IFJlZ0V4cCgnXicgKyB3aWxkY2FyZFRvUkUodG5bMF0pICsgJyQnKTsKCQkJCQkJdC53aWxkUnVsZXMgPSB0LndpbGRSdWxlcyB8fCB7fTsKCQkJCQkJdC53aWxkUnVsZXMucHVzaChydSk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJcnUubmFtZSA9IHRuWzBdOwoKCQkJCQkJLy8gU3RvcmUgYXdheSBkZWZhdWx0IHJ1bGUKCQkJCQkJaWYgKHRuWzBdID09ICdAJykKCQkJCQkJCWRyID0gcnU7CgoJCQkJCQl0LnJ1bGVzW3NdID0gcnU7CgkJCQkJfQoKCQkJCQlydS5hdHRyaWJzID0gYXQ7CgoJCQkJCWlmIChyYSkKCQkJCQkJcnUucmVxdWlyZWRBdHRyaWJzID0gcmE7CgoJCQkJCWlmICh3YXQpIHsKCQkJCQkJLy8gQnVpbGQgdmFsaWQgYXR0cmlidXRlcyByZWdleHAKCQkJCQkJcyA9ICcnOwoJCQkJCQllYWNoKHZhLCBmdW5jdGlvbih2KSB7CgkJCQkJCQlpZiAocykKCQkJCQkJCQlzICs9ICd8JzsKCgkJCQkJCQlzICs9ICcoJyArIHdpbGRjYXJkVG9SRSh2KSArICcpJzsKCQkJCQkJfSk7CgkJCQkJCXJ1LnZhbGlkQXR0cmlic1JFID0gbmV3IFJlZ0V4cCgnXicgKyBzLnRvTG93ZXJDYXNlKCkgKyAnJCcpOwoJCQkJCQlydS53aWxkQXR0cmlicyA9IHdhdDsKCQkJCQl9CgkJCQl9KTsKCQkJfSk7CgoJCQkvLyBCdWlsZCB2YWxpZCBlbGVtZW50cyByZWdleHAKCQkJcyA9ICcnOwoJCQllYWNoKHQudmFsaWRFbGVtZW50cywgZnVuY3Rpb24odiwgaykgewoJCQkJaWYgKHMpCgkJCQkJcyArPSAnfCc7CgoJCQkJaWYgKGsgIT0gJ0AnKQoJCQkJCXMgKz0gazsKCQkJfSk7CgkJCXQudmFsaWRFbGVtZW50c1JFID0gbmV3IFJlZ0V4cCgnXignICsgd2lsZGNhcmRUb1JFKHMudG9Mb3dlckNhc2UoKSkgKyAnKSQnKTsKCgkJCS8vY29uc29sZS5kZWJ1Zyh0LnZhbGlkRWxlbWVudHNSRS50b1N0cmluZygpKTsKCQkJLy9jb25zb2xlLmRpcih0LnJ1bGVzKTsKCQkJLy9jb25zb2xlLmRpcih0LndpbGRSdWxlcyk7CgkJfSwKCgkJZmluZFJ1bGUgOiBmdW5jdGlvbihuKSB7CgkJCXZhciB0ID0gdGhpcywgcmwgPSB0LnJ1bGVzLCBpLCByOwoKCQkJdC5fc2V0dXAoKTsKCgkJCS8vIEV4YWN0IG1hdGNoCgkJCXIgPSBybFtuXTsKCQkJaWYgKHIpCgkJCQlyZXR1cm4gcjsKCgkJCS8vIFRyeSB3aWxkY2FyZHMKCQkJcmwgPSB0LndpbGRSdWxlczsKCQkJZm9yIChpID0gMDsgaSA8IHJsLmxlbmd0aDsgaSsrKSB7CgkJCQlpZiAocmxbaV0ubmFtZVJFLnRlc3QobikpCgkJCQkJcmV0dXJuIHJsW2ldOwoJCQl9CgoJCQlyZXR1cm4gbnVsbDsKCQl9LAoKCQlmaW5kQXR0cmliUnVsZSA6IGZ1bmN0aW9uKHJ1LCBuKSB7CgkJCXZhciBpLCB3YSA9IHJ1LndpbGRBdHRyaWJzOwoKCQkJZm9yIChpID0gMDsgaSA8IHdhLmxlbmd0aDsgaSsrKSB7CgkJCQlpZiAod2FbaV0ubmFtZVJFLnRlc3QobikpCgkJCQkJcmV0dXJuIHdhW2ldOwoJCQl9CgoJCQlyZXR1cm4gbnVsbDsKCQl9LAoKCQlzZXJpYWxpemUgOiBmdW5jdGlvbihuLCBvKSB7CgkJCXZhciBoLCB0ID0gdGhpcywgZG9jOwoKCQkJdC5fc2V0dXAoKTsKCQkJbyA9IG8gfHwge307CgkJCW8uZm9ybWF0ID0gby5mb3JtYXQgfHwgJ2h0bWwnOwoJCQluID0gbi5jbG9uZU5vZGUodHJ1ZSk7CgkJCXQucHJvY2Vzc09iaiA9IG87CgoJCQkvLyBOb2RlcyBuZWVkcyB0byBiZSBhdHRhY2hlZCB0byBzb21ldGhpbmcgaW4gV2ViS2l0IGR1ZSB0byBhIGJ1ZyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjU1NzEKCQkJaWYgKHRpbnltY2UuaXNXZWJLaXQpIHsKCQkJCWRvYyA9IG4ub3duZXJEb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoIiIpOwoJCQkJZG9jLmJvZHkuYXBwZW5kQ2hpbGQobik7CgkJCX0KCgkJCXQua2V5ID0gJycgKyAocGFyc2VJbnQodC5rZXkpICsgMSk7CgoJCQkvLyBQcmUgcHJvY2VzcwoJCQlpZiAoIW8ubm9fZXZlbnRzKSB7CgkJCQlvLm5vZGUgPSBuOwoJCQkJdC5vblByZVByb2Nlc3MuZGlzcGF0Y2godCwgbyk7CgkJCX0KCgkJCS8vIFNlcmlhbGl6ZSBIVE1MIERPTSBpbnRvIGEgc3RyaW5nCgkJCXQud3JpdGVyLnJlc2V0KCk7CgkJCXQuX3NlcmlhbGl6ZU5vZGUobiwgby5nZXRJbm5lcik7CgoJCQkvLyBQb3N0IHByb2Nlc3MKCQkJby5jb250ZW50ID0gdC53cml0ZXIuZ2V0Q29udGVudCgpOwoKCQkJaWYgKCFvLm5vX2V2ZW50cykKCQkJCXQub25Qb3N0UHJvY2Vzcy5kaXNwYXRjaCh0LCBvKTsKCgkJCXQuX3Bvc3RQcm9jZXNzKG8pOwoJCQlvLm5vZGUgPSBudWxsOwoKCQkJcmV0dXJuIHRpbnltY2UudHJpbShvLmNvbnRlbnQpOwoJCX0sCgoJCS8vIEludGVybmFsIGZ1bmN0aW9ucwoKCQlfcG9zdFByb2Nlc3MgOiBmdW5jdGlvbihvKSB7CgkJCXZhciB0ID0gdGhpcywgcyA9IHQuc2V0dGluZ3MsIGggPSBvLmNvbnRlbnQsIHNjID0gW10sIHA7CgoJCQlpZiAoby5mb3JtYXQgPT0gJ2h0bWwnKSB7CgkJCQkvLyBQcm90ZWN0IHNvbWUgZWxlbWVudHMKCQkJCXAgPSB0Ll9wcm90ZWN0KHsKCQkJCQljb250ZW50IDogaCwKCQkJCQlwYXR0ZXJucyA6IFsKCQkJCQkJe3BhdHRlcm4gOiAvKDxzY3JpcHRbXj5dKj4pKC4qPykoPFwvc2NyaXB0PikvZ30sCgkJCQkJCXtwYXR0ZXJuIDogLyg8bm9zY3JpcHRbXj5dKj4pKC4qPykoPFwvbm9zY3JpcHQ+KS9nfSwKCQkJCQkJe3BhdHRlcm4gOiAvKDxzdHlsZVtePl0qPikoLio/KSg8XC9zdHlsZT4pL2d9LAoJCQkJCQl7cGF0dGVybiA6IC8oPHByZVtePl0qPikoLio/KSg8XC9wcmU+KS9nLCBlbmNvZGUgOiAxfSwKCQkJCQkJe3BhdHRlcm4gOiAvKDwhLS1cW0NEQVRBXFspKC4qPykoXF1cXS0tPikvZ30KCQkJCQldCgkJCQl9KTsKCgkJCQloID0gcC5jb250ZW50OwoKCQkJCS8vIEVudGl0eSBlbmNvZGUKCQkJCWlmIChzLmVudGl0eV9lbmNvZGluZyAhPT0gJ3JhdycpCgkJCQkJaCA9IHQuX2VuY29kZShoKTsKCgkJCQkvLyBVc2UgQlIgaW5zdGVhZCBvZiAmbmJzcDsgcGFkZGVkIFAgZWxlbWVudHMgaW5zaWRlIGVkaXRvciBhbmQgdXNlIDxwPiZuYnNwOzwvcD4gb3V0c2lkZSBlZGl0b3IKLyoJCQkJaWYgKG8uc2V0KQoJCQkJCWggPSBoLnJlcGxhY2UoLzxwPlxzKygmbmJzcDt8JiMxNjA7fFx1MDBhMHw8YnIgXC8+KVxzKzxcL3A+L2csICc8cD48YnIgLz48L3A+Jyk7CgkJCQllbHNlCgkJCQkJaCA9IGgucmVwbGFjZSgvPHA+XHMrKCZuYnNwO3wmIzE2MDt8XHUwMGEwfDxiciBcLz4pXHMrPFwvcD4vZywgJzxwPiQxPC9wPicpOyovCgoJCQkJLy8gU2luY2UgR2Vja28gYW5kIFNhZmFyaSBrZWVwcyB3aGl0ZXNwYWNlIGluIHRoZSBET00gd2UgbmVlZCB0bwoJCQkJLy8gcmVtb3ZlIGl0IGlub3JkZXIgdG8gbWF0Y2ggb3RoZXIgYnJvd3NlcnMuIEJ1dCBJIHRoaW5rIEdlY2tvIGFuZCBTYWZhcmkgaXMgcmlnaHQuCgkJCQkvLyBUaGlzIHByb2Nlc3MgaXMgb25seSBkb25lIHdoZW4gZ2V0dGluZyBjb250ZW50cyBvdXQgZnJvbSB0aGUgZWRpdG9yLgoJCQkJaWYgKCFvLnNldCkgewoJCQkJCS8vIFdlIG5lZWQgdG8gcmVwbGFjZSBwYXJhZ3JhcGggd2hpdGVzcGFjZSB3aXRoIGFuIG5ic3AgYmVmb3JlIGluZGVudGF0aW9uIHRvIGtlZXAgdGhlIFx1MDBhMCBjaGFyCgkJCQkJaCA9IGgucmVwbGFjZSgvPHA+XHMrPFwvcD58PHAoW14+XSspPlxzKzxcL3A+L2csIHMuZW50aXR5X2VuY29kaW5nID09ICdudW1lcmljJyA/ICc8cCQxPiYjMTYwOzwvcD4nIDogJzxwJDE+Jm5ic3A7PC9wPicpOwoKCQkJCQlpZiAocy5yZW1vdmVfbGluZWJyZWFrcykgewoJCQkJCQloID0gaC5yZXBsYWNlKC9ccj9cbnxcci9nLCAnICcpOwoJCQkJCQloID0gaC5yZXBsYWNlKC8oPFtePl0rPilccysvZywgJyQxICcpOwoJCQkJCQloID0gaC5yZXBsYWNlKC9ccysoPFwvW14+XSs+KS9nLCAnICQxJyk7CgkJCQkJCWggPSBoLnJlcGxhY2UoLzwocHxoWzEtNl18YmxvY2txdW90ZXxocnxkaXZ8dGFibGV8dGJvZHl8dHJ8dGR8Ym9keXxoZWFkfGh0bWx8dGl0bGV8bWV0YXxzdHlsZXxwcmV8c2NyaXB0fGxpbmt8b2JqZWN0KSAoW14+XSspPlxzKy9nLCAnPCQxICQyPicpOyAvLyBUcmltIGJsb2NrIHN0YXJ0CgkJCQkJCWggPSBoLnJlcGxhY2UoLzwocHxoWzEtNl18YmxvY2txdW90ZXxocnxkaXZ8dGFibGV8dGJvZHl8dHJ8dGR8Ym9keXxoZWFkfGh0bWx8dGl0bGV8bWV0YXxzdHlsZXxwcmV8c2NyaXB0fGxpbmt8b2JqZWN0KT5ccysvZywgJzwkMT4nKTsgLy8gVHJpbSBibG9jayBzdGFydAoJCQkJCQloID0gaC5yZXBsYWNlKC9ccys8XC8ocHxoWzEtNl18YmxvY2txdW90ZXxocnxkaXZ8dGFibGV8dGJvZHl8dHJ8dGR8Ym9keXxoZWFkfGh0bWx8dGl0bGV8bWV0YXxzdHlsZXxwcmV8c2NyaXB0fGxpbmt8b2JqZWN0KT4vZywgJzwvJDE+Jyk7IC8vIFRyaW0gYmxvY2sgZW5kCgkJCQkJfQoKCQkJCQkvLyBTaW1wbGUgaW5kZW50YXRpb24KCQkJCQlpZiAocy5hcHBseV9zb3VyY2VfZm9ybWF0dGluZyAmJiBzLmluZGVudF9tb2RlID09ICdzaW1wbGUnKSB7CgkJCQkJCS8vIEFkZCBsaW5lIGJyZWFrcyBiZWZvcmUgYW5kIGFmdGVyIGJsb2NrIGVsZW1lbnRzCgkJCQkJCWggPSBoLnJlcGxhY2UoLzwoXC8/KSh1bHxocnx0YWJsZXxtZXRhfGxpbmt8dGJvZHl8dHJ8b2JqZWN0fGJvZHl8aGVhZHxodG1sfG1hcCkofFtePl0rKT5ccyovZywgJ1xuPCQxJDIkMz5cbicpOwoJCQkJCQloID0gaC5yZXBsYWNlKC9ccyo8KHB8aFsxLTZdfGJsb2NrcXVvdGV8ZGl2fHRpdGxlfHN0eWxlfHByZXxzY3JpcHR8dGR8bGl8YXJlYSkofFtePl0rKT4vZywgJ1xuPCQxJDI+Jyk7CgkJCQkJCWggPSBoLnJlcGxhY2UoLzxcLyhwfGhbMS02XXxibG9ja3F1b3RlfGRpdnx0aXRsZXxzdHlsZXxwcmV8c2NyaXB0fHRkfGxpKT5ccyovZywgJzwvJDE+XG4nKTsKCQkJCQkJaCA9IGgucmVwbGFjZSgvXG5cbi9nLCAnXG4nKTsKCQkJCQl9CgkJCQl9CgoJCQkJaCA9IHQuX3VucHJvdGVjdChoLCBwKTsKCgkJCQkvLyBSZXN0b3JlIENEQVRBIHNlY3Rpb25zCgkJCQloID0gaC5yZXBsYWNlKC88IS0tXFtDREFUQVxbKFtcc1xTXSspXF1cXS0tPi9nLCAnPCFbQ0RBVEFbJDFdXT4nKTsKCgkJCQkvLyBSZXN0b3JlIHNjcmlwdHMKCQkJCWggPSBoLnJlcGxhY2UoLyh0eXBlfGxhbmd1YWdlKT1cIm1jZS0vZywgJyQxPSInKTsKCgkJCQkvLyBSZXN0b3JlIHRoZSBcdTAwYTAgY2hhcmFjdGVyIGlmIHJhdyBtb2RlIGlzIGVuYWJsZWQKCQkJCWlmIChzLmVudGl0eV9lbmNvZGluZyA9PSAncmF3JykKCQkJCQloID0gaC5yZXBsYWNlKC88cD4mbmJzcDs8XC9wPnw8cChbXj5dKyk+Jm5ic3A7PFwvcD4vZywgJzxwJDE+XHUwMGEwPC9wPicpOwoKCQkJCS8vIFJlc3RvcmUgbm9zY3JpcHQgZWxlbWVudHMKCQkJCWggPSBoLnJlcGxhY2UoLzxub3NjcmlwdChbXj5dK3wpPihbXHNcU10qPyk8XC9ub3NjcmlwdD4vZywgZnVuY3Rpb24odiwgYXR0cmlicywgdGV4dCkgewoJCQkJCXJldHVybiAnPG5vc2NyaXB0JyArIGF0dHJpYnMgKyAnPicgKyB0LmRvbS5kZWNvZGUodGV4dC5yZXBsYWNlKC88IS0tfC0tPi9nLCAnJykpICsgJzwvbm9zY3JpcHQ+JzsKCQkJCX0pOwoJCQl9CgoJCQlvLmNvbnRlbnQgPSBoOwoJCX0sCgoJCV9zZXJpYWxpemVOb2RlIDogZnVuY3Rpb24obiwgaW5uKSB7CgkJCXZhciB0ID0gdGhpcywgcyA9IHQuc2V0dGluZ3MsIHcgPSB0LndyaXRlciwgaGMsIGVsLCBjbiwgaSwgbCwgYSwgYXQsIG5vLCB2LCBubiwgcnUsIGFyLCBpdiwgY2xvc2VkOwoKCQkJaWYgKCFzLm5vZGVfZmlsdGVyIHx8IHMubm9kZV9maWx0ZXIobikpIHsKCQkJCXN3aXRjaCAobi5ub2RlVHlwZSkgewoJCQkJCWNhc2UgMTogLy8gRWxlbWVudAoJCQkJCQlpZiAobi5oYXNBdHRyaWJ1dGUgPyBuLmhhc0F0dHJpYnV0ZSgnbWNlX2JvZ3VzJykgOiBuLmdldEF0dHJpYnV0ZSgnbWNlX2JvZ3VzJykpCgkJCQkJCQlyZXR1cm47CgoJCQkJCQlpdiA9IGZhbHNlOwoJCQkJCQloYyA9IG4uaGFzQ2hpbGROb2RlcygpOwoJCQkJCQlubiA9IG4uZ2V0QXR0cmlidXRlKCdtY2VfbmFtZScpIHx8IG4ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTsKCgkJCQkJCS8vIEFkZCBjb3JyZWN0IHByZWZpeCBvbiBJRQoJCQkJCQlpZiAoaXNJRSkgewoJCQkJCQkJaWYgKG4uc2NvcGVOYW1lICE9PSAnSFRNTCcgJiYgbi5zY29wZU5hbWUgIT09ICdodG1sJykKCQkJCQkJCQlubiA9IG4uc2NvcGVOYW1lICsgJzonICsgbm47CgkJCQkJCX0KCgkJCQkJCS8vIFJlbW92ZSBtY2UgcHJlZml4IG9uIElFIG5lZWRlZCBmb3IgdGhlIGFiYnIgZWxlbWVudAoJCQkJCQlpZiAobm4uaW5kZXhPZignbWNlOicpID09PSAwKQoJCQkJCQkJbm4gPSBubi5zdWJzdHJpbmcoNCk7CgoJCQkJCQkvLyBDaGVjayBpZiB2YWxpZAoJCQkJCQlpZiAoIXQudmFsaWRFbGVtZW50c1JFIHx8ICF0LnZhbGlkRWxlbWVudHNSRS50ZXN0KG5uKSB8fCAodC5pbnZhbGlkRWxlbWVudHNSRSAmJiB0LmludmFsaWRFbGVtZW50c1JFLnRlc3Qobm4pKSB8fCBpbm4pIHsKCQkJCQkJCWl2ID0gdHJ1ZTsKCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgoJCQkJCQlpZiAoaXNJRSkgewoJCQkJCQkJLy8gRml4IElFIGNvbnRlbnQgZHVwbGljYXRpb24gKERPTSBjYW4gaGF2ZSBtdWx0aXBsZSBjb3BpZXMgb2YgdGhlIHNhbWUgbm9kZSkKCQkJCQkJCWlmIChzLmZpeF9jb250ZW50X2R1cGxpY2F0aW9uKSB7CgkJCQkJCQkJaWYgKG4ubWNlX3NlcmlhbGl6ZWQgPT0gdC5rZXkpCgkJCQkJCQkJCXJldHVybjsKCgkJCQkJCQkJbi5tY2Vfc2VyaWFsaXplZCA9IHQua2V5OwoJCQkJCQkJfQoKCQkJCQkJCS8vIElFIHNvbWV0aW1lcyBhZGRzIGEgLyBpbmZyb250IG9mIHRoZSBub2RlIG5hbWUKCQkJCQkJCWlmIChubi5jaGFyQXQoMCkgPT0gJy8nKQoJCQkJCQkJCW5uID0gbm4uc3Vic3RyaW5nKDEpOwoJCQkJCQl9IGVsc2UgaWYgKGlzR2Vja28pIHsKCQkJCQkJCS8vIElnbm9yZSBiciBlbGVtZW50cwoJCQkJCQkJaWYgKG4ubm9kZU5hbWUgPT09ICdCUicgJiYgbi5nZXRBdHRyaWJ1dGUoJ3R5cGUnKSA9PSAnX21veicpCgkJCQkJCQkJcmV0dXJuOwoJCQkJCQl9CgoJCQkJCQkvLyBDaGVjayBpZiB2YWxpZCBjaGlsZAoJCQkJCQlpZiAodC5jaGlsZFJ1bGVzKSB7CgkJCQkJCQlpZiAodC5wYXJlbnRFbGVtZW50c1JFLnRlc3QodC5lbGVtZW50TmFtZSkpIHsKCQkJCQkJCQlpZiAoIXQuY2hpbGRSdWxlc1t0LmVsZW1lbnROYW1lXS50ZXN0KG5uKSkgewoJCQkJCQkJCQlpdiA9IHRydWU7CgkJCQkJCQkJCWJyZWFrOwoJCQkJCQkJCX0KCQkJCQkJCX0KCgkJCQkJCQl0LmVsZW1lbnROYW1lID0gbm47CgkJCQkJCX0KCgkJCQkJCXJ1ID0gdC5maW5kUnVsZShubik7CgkJCQkJCW5uID0gcnUubmFtZSB8fCBubjsKCQkJCQkJY2xvc2VkID0gcy5jbG9zZWQudGVzdChubik7CgoJCQkJCQkvLyBTa2lwIGVtcHR5IG5vZGVzIG9yIGVtcHR5IG5vZGUgbmFtZSBpbiBJRQoJCQkJCQlpZiAoKCFoYyAmJiBydS5ub0VtcHR5KSB8fCAoaXNJRSAmJiAhbm4pKSB7CgkJCQkJCQlpdiA9IHRydWU7CgkJCQkJCQlicmVhazsKCQkJCQkJfQoKCQkJCQkJLy8gQ2hlY2sgcmVxdWlyZWQKCQkJCQkJaWYgKHJ1LnJlcXVpcmVkQXR0cmlicykgewoJCQkJCQkJYSA9IHJ1LnJlcXVpcmVkQXR0cmliczsKCgkJCQkJCQlmb3IgKGkgPSBhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7CgkJCQkJCQkJaWYgKHRoaXMuZG9tLmdldEF0dHJpYihuLCBhW2ldKSAhPT0gJycpCgkJCQkJCQkJCWJyZWFrOwoJCQkJCQkJfQoKCQkJCQkJCS8vIE5vbmUgb2YgdGhlIHJlcXVpcmVkIHdhcyB0aGVyZQoJCQkJCQkJaWYgKGkgPT0gLTEpIHsKCQkJCQkJCQlpdiA9IHRydWU7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQl9CgkJCQkJCX0KCgkJCQkJCXcud3JpdGVTdGFydEVsZW1lbnQobm4pOwoKCQkJCQkJLy8gQWRkIG9yZGVyZWQgYXR0cmlidXRlcwoJCQkJCQlpZiAocnUuYXR0cmlicykgewoJCQkJCQkJZm9yIChpPTAsIGF0ID0gcnUuYXR0cmlicywgbCA9IGF0Lmxlbmd0aDsgaTxsOyBpKyspIHsKCQkJCQkJCQlhID0gYXRbaV07CgkJCQkJCQkJdiA9IHQuX2dldEF0dHJpYihuLCBhKTsKCgkJCQkJCQkJaWYgKHYgIT09IG51bGwpCgkJCQkJCQkJCXcud3JpdGVBdHRyaWJ1dGUoYS5uYW1lLCB2KTsKCQkJCQkJCX0KCQkJCQkJfQoKCQkJCQkJLy8gQWRkIHdpbGQgYXR0cmlidXRlcwoJCQkJCQlpZiAocnUudmFsaWRBdHRyaWJzUkUpIHsKCQkJCQkJCWF0ID0gdC5kb20uZ2V0QXR0cmlicyhuKTsKCQkJCQkJCWZvciAoaT1hdC5sZW5ndGgtMTsgaT4tMTsgaS0tKSB7CgkJCQkJCQkJbm8gPSBhdFtpXTsKCgkJCQkJCQkJaWYgKG5vLnNwZWNpZmllZCkgewoJCQkJCQkJCQlhID0gbm8ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTsKCgkJCQkJCQkJCWlmIChzLmludmFsaWRfYXR0cnMudGVzdChhKSB8fCAhcnUudmFsaWRBdHRyaWJzUkUudGVzdChhKSkKCQkJCQkJCQkJCWNvbnRpbnVlOwoKCQkJCQkJCQkJYXIgPSB0LmZpbmRBdHRyaWJSdWxlKHJ1LCBhKTsKCQkJCQkJCQkJdiA9IHQuX2dldEF0dHJpYihuLCBhciwgYSk7CgoJCQkJCQkJCQlpZiAodiAhPT0gbnVsbCkKCQkJCQkJCQkJCXcud3JpdGVBdHRyaWJ1dGUoYSwgdik7CgkJCQkJCQkJfQoJCQkJCQkJfQoJCQkJCQl9CgoJCQkJCQkvLyBXcml0ZSB0ZXh0IGZyb20gc2NyaXB0CgkJCQkJCWlmIChubiA9PT0gJ3NjcmlwdCcgJiYgdGlueW1jZS50cmltKG4uaW5uZXJIVE1MKSkgewoJCQkJCQkJdy53cml0ZVRleHQoJy8vICcpOyAvLyBQYWRkIGl0IHdpdGggYSBjb21tZW50IHNvIGl0IHdpbGwgcGFyc2Ugb24gb2xkZXIgYnJvd3NlcnMKCQkJCQkJCXcud3JpdGVDREFUQShuLmlubmVySFRNTC5yZXBsYWNlKC88IS0tfC0tPnw8XFtDREFUQVxbfFxdXF0+L2csICcnKSk7IC8vIFJlbW92ZSBjb21tZW50cyBhbmQgY2RhdGEgc3R1Y3R1cmVzCgkJCQkJCQloYyA9IGZhbHNlOwoJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCgkJCQkJCS8vIFBhZGQgZW1wdHkgbm9kZXMgd2l0aCBhICZuYnNwOwoJCQkJCQlpZiAocnUucGFkZCkgewoJCQkJCQkJLy8gSWYgaXQgaGFzIG9ubHkgb25lIGJvZ3VzIGNoaWxkLCBwYWRkIGl0IGFueXdheSB3b3JrYXJvdW5kIGZvciA8dGQ+PGJyIC8+PC90ZD4gYnVnCgkJCQkJCQlpZiAoaGMgJiYgKGNuID0gbi5maXJzdENoaWxkKSAmJiBjbi5ub2RlVHlwZSA9PT0gMSAmJiBuLmNoaWxkTm9kZXMubGVuZ3RoID09PSAxKSB7CgkJCQkJCQkJaWYgKGNuLmhhc0F0dHJpYnV0ZSA/IGNuLmhhc0F0dHJpYnV0ZSgnbWNlX2JvZ3VzJykgOiBjbi5nZXRBdHRyaWJ1dGUoJ21jZV9ib2d1cycpKQoJCQkJCQkJCQl3LndyaXRlVGV4dCgnXHUwMGEwJyk7CgkJCQkJCQl9IGVsc2UgaWYgKCFoYykKCQkJCQkJCQl3LndyaXRlVGV4dCgnXHUwMGEwJyk7IC8vIE5vIGNoaWxkcmVuIHRoZW4gcGFkZCBpdAoJCQkJCQl9CgoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAzOiAvLyBUZXh0CgkJCQkJCS8vIENoZWNrIGlmIHZhbGlkIGNoaWxkCgkJCQkJCWlmICh0LmNoaWxkUnVsZXMgJiYgdC5wYXJlbnRFbGVtZW50c1JFLnRlc3QodC5lbGVtZW50TmFtZSkpIHsKCQkJCQkJCWlmICghdC5jaGlsZFJ1bGVzW3QuZWxlbWVudE5hbWVdLnRlc3Qobi5ub2RlTmFtZSkpCgkJCQkJCQkJcmV0dXJuOwoJCQkJCQl9CgoJCQkJCQlyZXR1cm4gdy53cml0ZVRleHQobi5ub2RlVmFsdWUpOwoKCQkJCQljYXNlIDQ6IC8vIENEQVRBCgkJCQkJCXJldHVybiB3LndyaXRlQ0RBVEEobi5ub2RlVmFsdWUpOwoKCQkJCQljYXNlIDg6IC8vIENvbW1lbnQKCQkJCQkJcmV0dXJuIHcud3JpdGVDb21tZW50KG4ubm9kZVZhbHVlKTsKCQkJCX0KCQkJfSBlbHNlIGlmIChuLm5vZGVUeXBlID09IDEpCgkJCQloYyA9IG4uaGFzQ2hpbGROb2RlcygpOwoKCQkJaWYgKGhjICYmICFjbG9zZWQpIHsKCQkJCWNuID0gbi5maXJzdENoaWxkOwoKCQkJCXdoaWxlIChjbikgewoJCQkJCXQuX3NlcmlhbGl6ZU5vZGUoY24pOwoJCQkJCXQuZWxlbWVudE5hbWUgPSBubjsKCQkJCQljbiA9IGNuLm5leHRTaWJsaW5nOwoJCQkJfQoJCQl9CgoJCQkvLyBXcml0ZSBlbGVtZW50IGVuZAoJCQlpZiAoIWl2KSB7CgkJCQlpZiAoIWNsb3NlZCkKCQkJCQl3LndyaXRlRnVsbEVuZEVsZW1lbnQoKTsKCQkJCWVsc2UKCQkJCQl3LndyaXRlRW5kRWxlbWVudCgpOwoJCQl9CgkJfSwKCgkJX3Byb3RlY3QgOiBmdW5jdGlvbihvKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCW8uaXRlbXMgPSBvLml0ZW1zIHx8IFtdOwoKCQkJZnVuY3Rpb24gZW5jKHMpIHsKCQkJCXJldHVybiBzLnJlcGxhY2UoL1tcclxuXFxdL2csIGZ1bmN0aW9uKGMpIHsKCQkJCQlpZiAoYyA9PT0gJ1xuJykKCQkJCQkJcmV0dXJuICdcXG4nOwoJCQkJCWVsc2UgaWYgKGMgPT09ICdcXCcpCgkJCQkJCXJldHVybiAnXFxcXCc7CgoJCQkJCXJldHVybiAnXFxyJzsKCQkJCX0pOwoJCQl9OwoKCQkJZnVuY3Rpb24gZGVjKHMpIHsKCQkJCXJldHVybiBzLnJlcGxhY2UoL1xcW1xccm5dL2csIGZ1bmN0aW9uKGMpIHsKCQkJCQlpZiAoYyA9PT0gJ1xcbicpCgkJCQkJCXJldHVybiAnXG4nOwoJCQkJCWVsc2UgaWYgKGMgPT09ICdcXFxcJykKCQkJCQkJcmV0dXJuICdcXCc7CgoJCQkJCXJldHVybiAnXHInOwoJCQkJfSk7CgkJCX07CgoJCQllYWNoKG8ucGF0dGVybnMsIGZ1bmN0aW9uKHApIHsKCQkJCW8uY29udGVudCA9IGRlYyhlbmMoby5jb250ZW50KS5yZXBsYWNlKHAucGF0dGVybiwgZnVuY3Rpb24oeCwgYSwgYiwgYykgewoJCQkJCWIgPSBkZWMoYik7CgoJCQkJCWlmIChwLmVuY29kZSkKCQkJCQkJYiA9IHQuX2VuY29kZShiKTsKCgkJCQkJby5pdGVtcy5wdXNoKGIpOwoJCQkJCXJldHVybiBhICsgJzwhLS1tY2U6JyArIChvLml0ZW1zLmxlbmd0aCAtIDEpICsgJy0tPicgKyBjOwoJCQkJfSkpOwoJCQl9KTsKCgkJCXJldHVybiBvOwoJCX0sCgoJCV91bnByb3RlY3QgOiBmdW5jdGlvbihoLCBvKSB7CgkJCWggPSBoLnJlcGxhY2UoL1w8IS0tbWNlOihbMC05XSspLS1cPi9nLCBmdW5jdGlvbihhLCBiKSB7CgkJCQlyZXR1cm4gby5pdGVtc1twYXJzZUludChiKV07CgkJCX0pOwoKCQkJby5pdGVtcyA9IFtdOwoKCQkJcmV0dXJuIGg7CgkJfSwKCgkJX2VuY29kZSA6IGZ1bmN0aW9uKGgpIHsKCQkJdmFyIHQgPSB0aGlzLCBzID0gdC5zZXR0aW5ncywgbDsKCgkJCS8vIEVudGl0eSBlbmNvZGUKCQkJaWYgKHMuZW50aXR5X2VuY29kaW5nICE9PSAncmF3JykgewoJCQkJaWYgKHMuZW50aXR5X2VuY29kaW5nLmluZGV4T2YoJ25hbWVkJykgIT0gLTEpIHsKCQkJCQl0LnNldEVudGl0aWVzKHMuZW50aXRpZXMpOwoJCQkJCWwgPSB0LmVudGl0eUxvb2t1cDsKCgkJCQkJaCA9IGgucmVwbGFjZSh0LmVudGl0aWVzUkUsIGZ1bmN0aW9uKGEpIHsKCQkJCQkJdmFyIHY7CgoJCQkJCQlpZiAodiA9IGxbYV0pCgkJCQkJCQlhID0gJyYnICsgdiArICc7JzsKCgkJCQkJCXJldHVybiBhOwoJCQkJCX0pOwoJCQkJfQoKCQkJCWlmIChzLmVudGl0eV9lbmNvZGluZy5pbmRleE9mKCdudW1lcmljJykgIT0gLTEpIHsKCQkJCQloID0gaC5yZXBsYWNlKC9bXHUwMDdFLVx1RkZGRl0vZywgZnVuY3Rpb24oYSkgewoJCQkJCQlyZXR1cm4gJyYjJyArIGEuY2hhckNvZGVBdCgwKSArICc7JzsKCQkJCQl9KTsKCQkJCX0KCQkJfQoKCQkJcmV0dXJuIGg7CgkJfSwKCgkJX3NldHVwIDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpcywgcyA9IHRoaXMuc2V0dGluZ3M7CgoJCQlpZiAodC5kb25lKQoJCQkJcmV0dXJuOwoKCQkJdC5kb25lID0gMTsKCgkJCXQuc2V0UnVsZXMocy52YWxpZF9lbGVtZW50cyk7CgkJCXQuYWRkUnVsZXMocy5leHRlbmRlZF92YWxpZF9lbGVtZW50cyk7CgkJCXQuYWRkVmFsaWRDaGlsZFJ1bGVzKHMudmFsaWRfY2hpbGRfZWxlbWVudHMpOwoKCQkJaWYgKHMuaW52YWxpZF9lbGVtZW50cykKCQkJCXQuaW52YWxpZEVsZW1lbnRzUkUgPSBuZXcgUmVnRXhwKCdeKCcgKyB3aWxkY2FyZFRvUkUocy5pbnZhbGlkX2VsZW1lbnRzLnJlcGxhY2UoLywvZywgJ3wnKS50b0xvd2VyQ2FzZSgpKSArICcpJCcpOwoKCQkJaWYgKHMuYXR0cmliX3ZhbHVlX2ZpbHRlcikKCQkJCXQuYXR0cmliVmFsdWVGaWx0ZXIgPSBzLmF0dHJpYlZhbHVlRmlsdGVyOwoJCX0sCgoJCV9nZXRBdHRyaWIgOiBmdW5jdGlvbihuLCBhLCBuYSkgewoJCQl2YXIgaSwgdjsKCgkJCW5hID0gbmEgfHwgYS5uYW1lOwoKCQkJaWYgKGEuZm9yY2VkVmFsICYmICh2ID0gYS5mb3JjZWRWYWwpKSB7CgkJCQlpZiAodiA9PT0gJ3skdWlkfScpCgkJCQkJcmV0dXJuIHRoaXMuZG9tLnVuaXF1ZUlkKCk7CgoJCQkJcmV0dXJuIHY7CgkJCX0KCgkJCXYgPSB0aGlzLmRvbS5nZXRBdHRyaWIobiwgbmEpOwoKCQkJLy8gQm9vbCBhdHRyCgkJCWlmICh0aGlzLnNldHRpbmdzLmJvb2xfYXR0cnMudGVzdChuYSkgJiYgdikgewoJCQkJdiA9ICgnJyArIHYpLnRvTG93ZXJDYXNlKCk7CgoJCQkJaWYgKHYgPT09ICdmYWxzZScgfHwgdiA9PT0gJzAnKQoJCQkJCXJldHVybiBudWxsOwoKCQkJCXYgPSBuYTsKCQkJfQoKCQkJc3dpdGNoIChuYSkgewoJCQkJY2FzZSAncm93c3Bhbic6CgkJCQljYXNlICdjb2xzcGFuJzoKCQkJCQkvLyBXaGF0cyB0aGUgcG9pbnQ/IFJlbW92ZSB1c2xlc3MgYXR0cmlidXRlIHZhbHVlCgkJCQkJaWYgKHYgPT0gJzEnKQoJCQkJCQl2ID0gJyc7CgoJCQkJCWJyZWFrOwoJCQl9CgoJCQlpZiAodGhpcy5hdHRyaWJWYWx1ZUZpbHRlcikKCQkJCXYgPSB0aGlzLmF0dHJpYlZhbHVlRmlsdGVyKG5hLCB2LCBuKTsKCgkJCWlmIChhLnZhbGlkVmFscykgewoJCQkJZm9yIChpID0gYS52YWxpZFZhbHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHsKCQkJCQlpZiAodiA9PSBhLnZhbGlkVmFsc1tpXSkKCQkJCQkJYnJlYWs7CgkJCQl9CgoJCQkJaWYgKGkgPT0gLTEpCgkJCQkJcmV0dXJuIG51bGw7CgkJCX0KCgkJCWlmICh2ID09PSAnJyAmJiB0eXBlb2YoYS5kZWZhdWx0VmFsKSAhPSAndW5kZWZpbmVkJykgewoJCQkJdiA9IGEuZGVmYXVsdFZhbDsKCgkJCQlpZiAodiA9PT0gJ3skdWlkfScpCgkJCQkJcmV0dXJuIHRoaXMuZG9tLnVuaXF1ZUlkKCk7CgoJCQkJcmV0dXJuIHY7CgkJCX0gZWxzZSB7CgkJCQkvLyBSZW1vdmUgaW50ZXJuYWwgbWNlSXRlbVhYIGNsYXNzZXMgd2hlbiBjb250ZW50IGlzIGV4dHJhY3RlZCBmcm9tIGVkaXRvcgoJCQkJaWYgKG5hID09ICdjbGFzcycgJiYgdGhpcy5wcm9jZXNzT2JqLmdldCkKCQkJCQl2ID0gdi5yZXBsYWNlKC9ccz9tY2VJdGVtXHcrXHM/L2csICcnKTsKCQkJfQoKCQkJaWYgKHYgPT09ICcnKQoJCQkJcmV0dXJuIG51bGw7CgoKCQkJcmV0dXJuIHY7CgkJfQoKCQl9KTsKfSkodGlueW1jZSk7CihmdW5jdGlvbih0aW55bWNlKSB7Cgl2YXIgZWFjaCA9IHRpbnltY2UuZWFjaCwgRXZlbnQgPSB0aW55bWNlLmRvbS5FdmVudDsKCgl0aW55bWNlLmNyZWF0ZSgndGlueW1jZS5kb20uU2NyaXB0TG9hZGVyJywgewoJCVNjcmlwdExvYWRlciA6IGZ1bmN0aW9uKHMpIHsKCQkJdGhpcy5zZXR0aW5ncyA9IHMgfHwge307CgkJCXRoaXMucXVldWUgPSBbXTsKCQkJdGhpcy5sb29rdXAgPSB7fTsKCQl9LAoKCQlpc0RvbmUgOiBmdW5jdGlvbih1KSB7CgkJCXJldHVybiB0aGlzLmxvb2t1cFt1XSA/IHRoaXMubG9va3VwW3VdLnN0YXRlID09IDIgOiAwOwoJCX0sCgoJCW1hcmtEb25lIDogZnVuY3Rpb24odSkgewoJCQl0aGlzLmxvb2t1cFt1XSA9IHtzdGF0ZSA6IDIsIHVybCA6IHV9OwoJCX0sCgoJCWFkZCA6IGZ1bmN0aW9uKHUsIGNiLCBzLCBwcikgewoJCQl2YXIgdCA9IHRoaXMsIGxvID0gdC5sb29rdXAsIG87CgoJCQlpZiAobyA9IGxvW3VdKSB7CgkJCQkvLyBJcyBsb2FkZWQgZmlyZSBjYWxsYmFjawoJCQkJaWYgKGNiICYmIG8uc3RhdGUgPT0gMikKCQkJCQljYi5jYWxsKHMgfHwgdGhpcyk7CgoJCQkJcmV0dXJuIG87CgkJCX0KCgkJCW8gPSB7c3RhdGUgOiAwLCB1cmwgOiB1LCBmdW5jIDogY2IsIHNjb3BlIDogcyB8fCB0aGlzfTsKCgkJCWlmIChwcikKCQkJCXQucXVldWUudW5zaGlmdChvKTsKCQkJZWxzZQoJCQkJdC5xdWV1ZS5wdXNoKG8pOwoKCQkJbG9bdV0gPSBvOwoKCQkJcmV0dXJuIG87CgkJfSwKCgkJbG9hZCA6IGZ1bmN0aW9uKHUsIGNiLCBzKSB7CgkJCXZhciB0ID0gdGhpcywgbzsKCgkJCWlmIChvID0gdC5sb29rdXBbdV0pIHsKCQkJCS8vIElzIGxvYWRlZCBmaXJlIGNhbGxiYWNrCgkJCQlpZiAoY2IgJiYgby5zdGF0ZSA9PSAyKQoJCQkJCWNiLmNhbGwocyB8fCB0KTsKCgkJCQlyZXR1cm4gbzsKCQkJfQoKCQkJZnVuY3Rpb24gbG9hZFNjcmlwdCh1KSB7CgkJCQlpZiAoRXZlbnQuZG9tTG9hZGVkIHx8IHQuc2V0dGluZ3Muc3RyaWN0X21vZGUpIHsKCQkJCQl0aW55bWNlLnV0aWwuWEhSLnNlbmQoewoJCQkJCQl1cmwgOiB0aW55bWNlLl9hZGRWZXIodSksCgkJCQkJCWVycm9yIDogdC5zZXR0aW5ncy5lcnJvciwKCQkJCQkJYXN5bmMgOiBmYWxzZSwKCQkJCQkJc3VjY2VzcyA6IGZ1bmN0aW9uKGNvKSB7CgkJCQkJCQl0LmV2YWwoY28pOwoJCQkJCQl9CgkJCQkJfSk7CgkJCQl9IGVsc2UKCQkJCQlkb2N1bWVudC53cml0ZSgnPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iJyArIHRpbnltY2UuX2FkZFZlcih1KSArICciPjwvc2NyaXB0PicpOwoJCQl9OwoKCQkJaWYgKCF0aW55bWNlLmlzKHUsICdzdHJpbmcnKSkgewoJCQkJZWFjaCh1LCBmdW5jdGlvbih1KSB7CgkJCQkJbG9hZFNjcmlwdCh1KTsKCQkJCX0pOwoKCQkJCWlmIChjYikKCQkJCQljYi5jYWxsKHMgfHwgdCk7CgkJCX0gZWxzZSB7CgkJCQlsb2FkU2NyaXB0KHUpOwoKCQkJCWlmIChjYikKCQkJCQljYi5jYWxsKHMgfHwgdCk7CgkJCX0KCQl9LAoKCQlsb2FkUXVldWUgOiBmdW5jdGlvbihjYiwgcykgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQlpZiAoIXQucXVldWVMb2FkaW5nKSB7CgkJCQl0LnF1ZXVlTG9hZGluZyA9IDE7CgkJCQl0LnF1ZXVlQ2FsbGJhY2tzID0gW107CgoJCQkJdC5sb2FkU2NyaXB0cyh0LnF1ZXVlLCBmdW5jdGlvbigpIHsKCQkJCQl0LnF1ZXVlTG9hZGluZyA9IDA7CgoJCQkJCWlmIChjYikKCQkJCQkJY2IuY2FsbChzIHx8IHQpOwoKCQkJCQllYWNoKHQucXVldWVDYWxsYmFja3MsIGZ1bmN0aW9uKG8pIHsKCQkJCQkJby5mdW5jLmNhbGwoby5zY29wZSk7CgkJCQkJfSk7CgkJCQl9KTsKCQkJfSBlbHNlIGlmIChjYikKCQkJCXQucXVldWVDYWxsYmFja3MucHVzaCh7ZnVuYyA6IGNiLCBzY29wZSA6IHMgfHwgdH0pOwoJCX0sCgoJCWV2YWwgOiBmdW5jdGlvbihjbykgewoJCQl2YXIgdyA9IHdpbmRvdzsKCgkJCS8vIEV2YWx1YXRlIHNjcmlwdAoJCQlpZiAoIXcuZXhlY1NjcmlwdCkgewoJCQkJdHJ5IHsKCQkJCQlldmFsLmNhbGwodywgY28pOwoJCQkJfSBjYXRjaCAoZXgpIHsKCQkJCQlldmFsKGNvLCB3KTsgLy8gRmlyZWZveCAzLjBhOAoJCQkJfQoJCQl9IGVsc2UKCQkJCXcuZXhlY1NjcmlwdChjbyk7IC8vIElFCgkJfSwKCgkJbG9hZFNjcmlwdHMgOiBmdW5jdGlvbihzYywgY2IsIHMpIHsKCQkJdmFyIHQgPSB0aGlzLCBsbyA9IHQubG9va3VwOwoKCQkJZnVuY3Rpb24gZG9uZShvKSB7CgkJCQlvLnN0YXRlID0gMjsgLy8gSGFzIGJlZW4gbG9hZGVkCgoJCQkJLy8gUnVuIGNhbGxiYWNrCgkJCQlpZiAoby5mdW5jKQoJCQkJCW8uZnVuYy5jYWxsKG8uc2NvcGUgfHwgdCk7CgkJCX07CgoJCQlmdW5jdGlvbiBhbGxEb25lKCkgewoJCQkJdmFyIGw7CgoJCQkJLy8gQ2hlY2sgaWYgYWxsIGZpbGVzIGFyZSBsb2FkZWQKCQkJCWwgPSBzYy5sZW5ndGg7CgkJCQllYWNoKHNjLCBmdW5jdGlvbihvKSB7CgkJCQkJbyA9IGxvW28udXJsXTsKCgkJCQkJaWYgKG8uc3RhdGUgPT09IDIpIHsvLyBJdCBoYXMgZmluaXNoZWQgbG9hZGluZwoJCQkJCQlkb25lKG8pOwoJCQkJCQlsLS07CgkJCQkJfSBlbHNlCgkJCQkJCWxvYWQobyk7CgkJCQl9KTsKCgkJCQkvLyBUaGV5IGFyZSBhbGwgbG9hZGVkCgkJCQlpZiAobCA9PT0gMCAmJiBjYikgewoJCQkJCWNiLmNhbGwocyB8fCB0KTsKCQkJCQljYiA9IDA7CgkJCQl9CgkJCX07CgoJCQlmdW5jdGlvbiBsb2FkKG8pIHsKCQkJCWlmIChvLnN0YXRlID4gMCkKCQkJCQlyZXR1cm47CgoJCQkJby5zdGF0ZSA9IDE7IC8vIElzIGxvYWRpbmcKCgkJCQl0aW55bWNlLmRvbS5TY3JpcHRMb2FkZXIubG9hZFNjcmlwdChvLnVybCwgZnVuY3Rpb24oKSB7CgkJCQkJZG9uZShvKTsKCQkJCQlhbGxEb25lKCk7CgkJCQl9KTsKCgkJCQkvKgoJCQkJdGlueW1jZS51dGlsLlhIUi5zZW5kKHsKCQkJCQl1cmwgOiBvLnVybCwKCQkJCQllcnJvciA6IHQuc2V0dGluZ3MuZXJyb3IsCgkJCQkJc3VjY2VzcyA6IGZ1bmN0aW9uKGNvKSB7CgkJCQkJCXQuZXZhbChjbyk7CgkJCQkJCWRvbmUobyk7CgkJCQkJCWFsbERvbmUoKTsKCQkJCQl9CgkJCQl9KTsKCQkJCSovCgkJCX07CgoJCQllYWNoKHNjLCBmdW5jdGlvbihvKSB7CgkJCQl2YXIgdSA9IG8udXJsOwoKCQkJCS8vIEFkZCB0byBxdWV1ZSBpZiBuZWVkZWQKCQkJCWlmICghbG9bdV0pIHsKCQkJCQlsb1t1XSA9IG87CgkJCQkJdC5xdWV1ZS5wdXNoKG8pOwoJCQkJfSBlbHNlCgkJCQkJbyA9IGxvW3VdOwoKCQkJCS8vIElzIGFscmVhZHkgbG9hZGluZyBvciBoYXMgYmVlbiBsb2FkZWQKCQkJCWlmIChvLnN0YXRlID4gMCkKCQkJCQlyZXR1cm47CgoJCQkJaWYgKCFFdmVudC5kb21Mb2FkZWQgJiYgIXQuc2V0dGluZ3Muc3RyaWN0X21vZGUpIHsKCQkJCQl2YXIgaXgsIG9sID0gJyc7CgoJCQkJCS8vIEFkZCBvbmxvYWQgZXZlbnRzCgkJCQkJaWYgKGNiIHx8IG8uZnVuYykgewoJCQkJCQlvLnN0YXRlID0gMTsgLy8gSXMgbG9hZGluZwoKCQkJCQkJaXggPSB0aW55bWNlLmRvbS5TY3JpcHRMb2FkZXIuX2FkZE9uTG9hZChmdW5jdGlvbigpIHsKCQkJCQkJCWRvbmUobyk7CgkJCQkJCQlhbGxEb25lKCk7CgkJCQkJCX0pOwoKCQkJCQkJaWYgKHRpbnltY2UuaXNJRSkKCQkJCQkJCW9sID0gJyBvbnJlYWR5c3RhdGVjaGFuZ2U9Iic7CgkJCQkJCWVsc2UKCQkJCQkJCW9sID0gJyBvbmxvYWQ9Iic7CgoJCQkJCQlvbCArPSAndGlueW1jZS5kb20uU2NyaXB0TG9hZGVyLl9vbkxvYWQodGhpcyxcJycgKyB1ICsgJ1wnLCcgKyBpeCArICcpOyInOwoJCQkJCX0KCgkJCQkJZG9jdW1lbnQud3JpdGUoJzxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9IicgKyB0aW55bWNlLl9hZGRWZXIodSkgKyAnIicgKyBvbCArICc+PC9zY3JpcHQ+Jyk7CgoJCQkJCWlmICghby5mdW5jKQoJCQkJCQlkb25lKG8pOwoJCQkJfSBlbHNlCgkJCQkJbG9hZChvKTsKCQkJfSk7CgoJCQlhbGxEb25lKCk7CgkJfSwKCgkJLy8gU3RhdGljIG1ldGhvZHMKCQknc3RhdGljJyA6IHsKCQkJX2FkZE9uTG9hZCA6IGZ1bmN0aW9uKGYpIHsKCQkJCXZhciB0ID0gdGhpczsKCgkJCQl0Ll9mdW5jcyA9IHQuX2Z1bmNzIHx8IFtdOwoJCQkJdC5fZnVuY3MucHVzaChmKTsKCgkJCQlyZXR1cm4gdC5fZnVuY3MubGVuZ3RoIC0gMTsKCQkJfSwKCgkJCV9vbkxvYWQgOiBmdW5jdGlvbihlLCB1LCBpeCkgewoJCQkJaWYgKCF0aW55bWNlLmlzSUUgfHwgZS5yZWFkeVN0YXRlID09ICdjb21wbGV0ZScpCgkJCQkJdGhpcy5fZnVuY3NbaXhdLmNhbGwodGhpcyk7CgkJCX0sCgoJCQlsb2FkU2NyaXB0IDogZnVuY3Rpb24odSwgY2IpIHsKCQkJCXZhciBpZCA9IHRpbnltY2UuRE9NLnVuaXF1ZUlkKCksIGU7CgoJCQkJZnVuY3Rpb24gZG9uZSgpIHsKCQkJCQlFdmVudC5jbGVhcihpZCk7CgkJCQkJdGlueW1jZS5ET00ucmVtb3ZlKGlkKTsKCgkJCQkJaWYgKGNiKSB7CgkJCQkJCWNiLmNhbGwoZG9jdW1lbnQsIHUpOwoJCQkJCQljYiA9IDA7CgkJCQkJfQoJCQkJfTsKCgkJCQlpZiAodGlueW1jZS5pc0lFKSB7Ci8qCQkJCQlFdmVudC5hZGQoZSwgJ3JlYWR5c3RhdGVjaGFuZ2UnLCBmdW5jdGlvbihlKSB7CgkJCQkJCWlmIChlLnRhcmdldCAmJiBlLnRhcmdldC5yZWFkeVN0YXRlID09ICdjb21wbGV0ZScpCgkJCQkJCQlkb25lKCk7CgkJCQkJfSk7Ki8KCgkJCQkJdGlueW1jZS51dGlsLlhIUi5zZW5kKHsKCQkJCQkJdXJsIDogdGlueW1jZS5fYWRkVmVyKHUpLAoJCQkJCQlhc3luYyA6IGZhbHNlLAoJCQkJCQlzdWNjZXNzIDogZnVuY3Rpb24oY28pIHsKCQkJCQkJCXdpbmRvdy5leGVjU2NyaXB0KGNvKTsKCQkJCQkJCWRvbmUoKTsKCQkJCQkJfQoJCQkJCX0pOwoJCQkJfSBlbHNlIHsKCQkJCQllID0gdGlueW1jZS5ET00uY3JlYXRlKCdzY3JpcHQnLCB7aWQgOiBpZCwgdHlwZSA6ICd0ZXh0L2phdmFzY3JpcHQnLCBzcmMgOiB0aW55bWNlLl9hZGRWZXIodSl9KTsKCQkJCQlFdmVudC5hZGQoZSwgJ2xvYWQnLCBkb25lKTsKCgkJCQkJLy8gQ2hlY2sgZm9yIGhlYWQgb3IgYm9keQoJCQkJCShkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdIHx8IGRvY3VtZW50LmJvZHkpLmFwcGVuZENoaWxkKGUpOwoJCQkJfQoJCQl9CgkJfQoKCQl9KTsKCgkvLyBHbG9iYWwgc2NyaXB0IGxvYWRlcgoJdGlueW1jZS5TY3JpcHRMb2FkZXIgPSBuZXcgdGlueW1jZS5kb20uU2NyaXB0TG9hZGVyKCk7Cn0pKHRpbnltY2UpOwooZnVuY3Rpb24odGlueW1jZSkgewoJLy8gU2hvcnRlbiBjbGFzcyBuYW1lcwoJdmFyIERPTSA9IHRpbnltY2UuRE9NLCBpcyA9IHRpbnltY2UuaXM7CgoJdGlueW1jZS5jcmVhdGUoJ3RpbnltY2UudWkuQ29udHJvbCcsIHsKCQlDb250cm9sIDogZnVuY3Rpb24oaWQsIHMpIHsKCQkJdGhpcy5pZCA9IGlkOwoJCQl0aGlzLnNldHRpbmdzID0gcyA9IHMgfHwge307CgkJCXRoaXMucmVuZGVyZWQgPSBmYWxzZTsKCQkJdGhpcy5vblJlbmRlciA9IG5ldyB0aW55bWNlLnV0aWwuRGlzcGF0Y2hlcih0aGlzKTsKCQkJdGhpcy5jbGFzc1ByZWZpeCA9ICcnOwoJCQl0aGlzLnNjb3BlID0gcy5zY29wZSB8fCB0aGlzOwoJCQl0aGlzLmRpc2FibGVkID0gMDsKCQkJdGhpcy5hY3RpdmUgPSAwOwoJCX0sCgoJCXNldERpc2FibGVkIDogZnVuY3Rpb24ocykgewoJCQl2YXIgZTsKCgkJCWlmIChzICE9IHRoaXMuZGlzYWJsZWQpIHsKCQkJCWUgPSBET00uZ2V0KHRoaXMuaWQpOwoKCQkJCS8vIEFkZCBhY2Nlc3NpYmlsaXR5IHRpdGxlIGZvciB1bmF2YWlsYWJsZSBhY3Rpb25zCgkJCQlpZiAoZSAmJiB0aGlzLnNldHRpbmdzLnVuYXZhaWxhYmxlX3ByZWZpeCkgewoJCQkJCWlmIChzKSB7CgkJCQkJCXRoaXMucHJldlRpdGxlID0gZS50aXRsZTsKCQkJCQkJZS50aXRsZSA9IHRoaXMuc2V0dGluZ3MudW5hdmFpbGFibGVfcHJlZml4ICsgIjogIiArIGUudGl0bGU7CgkJCQkJfSBlbHNlCgkJCQkJCWUudGl0bGUgPSB0aGlzLnByZXZUaXRsZTsKCQkJCX0KCgkJCQl0aGlzLnNldFN0YXRlKCdEaXNhYmxlZCcsIHMpOwoJCQkJdGhpcy5zZXRTdGF0ZSgnRW5hYmxlZCcsICFzKTsKCQkJCXRoaXMuZGlzYWJsZWQgPSBzOwoJCQl9CgkJfSwKCgkJaXNEaXNhYmxlZCA6IGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gdGhpcy5kaXNhYmxlZDsKCQl9LAoKCQlzZXRBY3RpdmUgOiBmdW5jdGlvbihzKSB7CgkJCWlmIChzICE9IHRoaXMuYWN0aXZlKSB7CgkJCQl0aGlzLnNldFN0YXRlKCdBY3RpdmUnLCBzKTsKCQkJCXRoaXMuYWN0aXZlID0gczsKCQkJfQoJCX0sCgoJCWlzQWN0aXZlIDogZnVuY3Rpb24oKSB7CgkJCXJldHVybiB0aGlzLmFjdGl2ZTsKCQl9LAoKCQlzZXRTdGF0ZSA6IGZ1bmN0aW9uKGMsIHMpIHsKCQkJdmFyIG4gPSBET00uZ2V0KHRoaXMuaWQpOwoKCQkJYyA9IHRoaXMuY2xhc3NQcmVmaXggKyBjOwoKCQkJaWYgKHMpCgkJCQlET00uYWRkQ2xhc3MobiwgYyk7CgkJCWVsc2UKCQkJCURPTS5yZW1vdmVDbGFzcyhuLCBjKTsKCQl9LAoKCQlpc1JlbmRlcmVkIDogZnVuY3Rpb24oKSB7CgkJCXJldHVybiB0aGlzLnJlbmRlcmVkOwoJCX0sCgoJCXJlbmRlckhUTUwgOiBmdW5jdGlvbigpIHsKCQl9LAoKCQlyZW5kZXJUbyA6IGZ1bmN0aW9uKG4pIHsKCQkJRE9NLnNldEhUTUwobiwgdGhpcy5yZW5kZXJIVE1MKCkpOwoJCX0sCgoJCXBvc3RSZW5kZXIgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCBiOwoKCQkJLy8gU2V0IHBlbmRpbmcgc3RhdGVzCgkJCWlmIChpcyh0LmRpc2FibGVkKSkgewoJCQkJYiA9IHQuZGlzYWJsZWQ7CgkJCQl0LmRpc2FibGVkID0gLTE7CgkJCQl0LnNldERpc2FibGVkKGIpOwoJCQl9CgoJCQlpZiAoaXModC5hY3RpdmUpKSB7CgkJCQliID0gdC5hY3RpdmU7CgkJCQl0LmFjdGl2ZSA9IC0xOwoJCQkJdC5zZXRBY3RpdmUoYik7CgkJCX0KCQl9LAoKCQlyZW1vdmUgOiBmdW5jdGlvbigpIHsKCQkJRE9NLnJlbW92ZSh0aGlzLmlkKTsKCQkJdGhpcy5kZXN0cm95KCk7CgkJfSwKCgkJZGVzdHJveSA6IGZ1bmN0aW9uKCkgewoJCQl0aW55bWNlLmRvbS5FdmVudC5jbGVhcih0aGlzLmlkKTsKCQl9CgoJCX0pOwp9KSh0aW55bWNlKTt0aW55bWNlLmNyZWF0ZSgndGlueW1jZS51aS5Db250YWluZXI6dGlueW1jZS51aS5Db250cm9sJywgewoJQ29udGFpbmVyIDogZnVuY3Rpb24oaWQsIHMpIHsKCQl0aGlzLnBhcmVudChpZCwgcyk7CgkJdGhpcy5jb250cm9scyA9IFtdOwoJCXRoaXMubG9va3VwID0ge307Cgl9LAoKCWFkZCA6IGZ1bmN0aW9uKGMpIHsKCQl0aGlzLmxvb2t1cFtjLmlkXSA9IGM7CgkJdGhpcy5jb250cm9scy5wdXNoKGMpOwoKCQlyZXR1cm4gYzsKCX0sCgoJZ2V0IDogZnVuY3Rpb24obikgewoJCXJldHVybiB0aGlzLmxvb2t1cFtuXTsKCX0KCgl9KTsKCnRpbnltY2UuY3JlYXRlKCd0aW55bWNlLnVpLlNlcGFyYXRvcjp0aW55bWNlLnVpLkNvbnRyb2wnLCB7CglTZXBhcmF0b3IgOiBmdW5jdGlvbihpZCwgcykgewoJCXRoaXMucGFyZW50KGlkLCBzKTsKCQl0aGlzLmNsYXNzUHJlZml4ID0gJ21jZVNlcGFyYXRvcic7Cgl9LAoKCXJlbmRlckhUTUwgOiBmdW5jdGlvbigpIHsKCQlyZXR1cm4gdGlueW1jZS5ET00uY3JlYXRlSFRNTCgnc3BhbicsIHsnY2xhc3MnIDogdGhpcy5jbGFzc1ByZWZpeH0pOwoJfQoKCX0pOwooZnVuY3Rpb24odGlueW1jZSkgewoJdmFyIGlzID0gdGlueW1jZS5pcywgRE9NID0gdGlueW1jZS5ET00sIGVhY2ggPSB0aW55bWNlLmVhY2gsIHdhbGsgPSB0aW55bWNlLndhbGs7CgoJdGlueW1jZS5jcmVhdGUoJ3RpbnltY2UudWkuTWVudUl0ZW06dGlueW1jZS51aS5Db250cm9sJywgewoJCU1lbnVJdGVtIDogZnVuY3Rpb24oaWQsIHMpIHsKCQkJdGhpcy5wYXJlbnQoaWQsIHMpOwoJCQl0aGlzLmNsYXNzUHJlZml4ID0gJ21jZU1lbnVJdGVtJzsKCQl9LAoKCQlzZXRTZWxlY3RlZCA6IGZ1bmN0aW9uKHMpIHsKCQkJdGhpcy5zZXRTdGF0ZSgnU2VsZWN0ZWQnLCBzKTsKCQkJdGhpcy5zZWxlY3RlZCA9IHM7CgkJfSwKCgkJaXNTZWxlY3RlZCA6IGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gdGhpcy5zZWxlY3RlZDsKCQl9LAoKCQlwb3N0UmVuZGVyIDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXQucGFyZW50KCk7CgoJCQkvLyBTZXQgcGVuZGluZyBzdGF0ZQoJCQlpZiAoaXModC5zZWxlY3RlZCkpCgkJCQl0LnNldFNlbGVjdGVkKHQuc2VsZWN0ZWQpOwoJCX0KCgkJfSk7Cn0pKHRpbnltY2UpOwooZnVuY3Rpb24odGlueW1jZSkgewoJdmFyIGlzID0gdGlueW1jZS5pcywgRE9NID0gdGlueW1jZS5ET00sIGVhY2ggPSB0aW55bWNlLmVhY2gsIHdhbGsgPSB0aW55bWNlLndhbGs7CgoJdGlueW1jZS5jcmVhdGUoJ3RpbnltY2UudWkuTWVudTp0aW55bWNlLnVpLk1lbnVJdGVtJywgewoJCU1lbnUgOiBmdW5jdGlvbihpZCwgcykgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQl0LnBhcmVudChpZCwgcyk7CgkJCXQuaXRlbXMgPSB7fTsKCQkJdC5jb2xsYXBzZWQgPSBmYWxzZTsKCQkJdC5tZW51Q291bnQgPSAwOwoJCQl0Lm9uQWRkSXRlbSA9IG5ldyB0aW55bWNlLnV0aWwuRGlzcGF0Y2hlcih0aGlzKTsKCQl9LAoKCQlleHBhbmQgOiBmdW5jdGlvbihkKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCWlmIChkKSB7CgkJCQl3YWxrKHQsIGZ1bmN0aW9uKG8pIHsKCQkJCQlpZiAoby5leHBhbmQpCgkJCQkJCW8uZXhwYW5kKCk7CgkJCQl9LCAnaXRlbXMnLCB0KTsKCQkJfQoKCQkJdC5jb2xsYXBzZWQgPSBmYWxzZTsKCQl9LAoKCQljb2xsYXBzZSA6IGZ1bmN0aW9uKGQpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJaWYgKGQpIHsKCQkJCXdhbGsodCwgZnVuY3Rpb24obykgewoJCQkJCWlmIChvLmNvbGxhcHNlKQoJCQkJCQlvLmNvbGxhcHNlKCk7CgkJCQl9LCAnaXRlbXMnLCB0KTsKCQkJfQoKCQkJdC5jb2xsYXBzZWQgPSB0cnVlOwoJCX0sCgoJCWlzQ29sbGFwc2VkIDogZnVuY3Rpb24oKSB7CgkJCXJldHVybiB0aGlzLmNvbGxhcHNlZDsKCQl9LAoKCQlhZGQgOiBmdW5jdGlvbihvKSB7CgkJCWlmICghby5zZXR0aW5ncykKCQkJCW8gPSBuZXcgdGlueW1jZS51aS5NZW51SXRlbShvLmlkIHx8IERPTS51bmlxdWVJZCgpLCBvKTsKCgkJCXRoaXMub25BZGRJdGVtLmRpc3BhdGNoKHRoaXMsIG8pOwoKCQkJcmV0dXJuIHRoaXMuaXRlbXNbby5pZF0gPSBvOwoJCX0sCgoJCWFkZFNlcGFyYXRvciA6IGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gdGhpcy5hZGQoe3NlcGFyYXRvciA6IHRydWV9KTsKCQl9LAoKCQlhZGRNZW51IDogZnVuY3Rpb24obykgewoJCQlpZiAoIW8uY29sbGFwc2UpCgkJCQlvID0gdGhpcy5jcmVhdGVNZW51KG8pOwoKCQkJdGhpcy5tZW51Q291bnQrKzsKCgkJCXJldHVybiB0aGlzLmFkZChvKTsKCQl9LAoKCQloYXNNZW51cyA6IGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gdGhpcy5tZW51Q291bnQgIT09IDA7CgkJfSwKCgkJcmVtb3ZlIDogZnVuY3Rpb24obykgewoJCQlkZWxldGUgdGhpcy5pdGVtc1tvLmlkXTsKCQl9LAoKCQlyZW1vdmVBbGwgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJd2Fsayh0LCBmdW5jdGlvbihvKSB7CgkJCQlpZiAoby5yZW1vdmVBbGwpCgkJCQkJby5yZW1vdmVBbGwoKTsKCQkJCWVsc2UKCQkJCQlvLnJlbW92ZSgpOwoKCQkJCW8uZGVzdHJveSgpOwoJCQl9LCAnaXRlbXMnLCB0KTsKCgkJCXQuaXRlbXMgPSB7fTsKCQl9LAoKCQljcmVhdGVNZW51IDogZnVuY3Rpb24obykgewoJCQl2YXIgbSA9IG5ldyB0aW55bWNlLnVpLk1lbnUoby5pZCB8fCBET00udW5pcXVlSWQoKSwgbyk7CgoJCQltLm9uQWRkSXRlbS5hZGQodGhpcy5vbkFkZEl0ZW0uZGlzcGF0Y2gsIHRoaXMub25BZGRJdGVtKTsKCgkJCXJldHVybiBtOwoJCX0KCgkJfSk7Cn0pKHRpbnltY2UpOyhmdW5jdGlvbih0aW55bWNlKSB7Cgl2YXIgaXMgPSB0aW55bWNlLmlzLCBET00gPSB0aW55bWNlLkRPTSwgZWFjaCA9IHRpbnltY2UuZWFjaCwgRXZlbnQgPSB0aW55bWNlLmRvbS5FdmVudCwgRWxlbWVudCA9IHRpbnltY2UuZG9tLkVsZW1lbnQ7CgoJdGlueW1jZS5jcmVhdGUoJ3RpbnltY2UudWkuRHJvcE1lbnU6dGlueW1jZS51aS5NZW51JywgewoJCURyb3BNZW51IDogZnVuY3Rpb24oaWQsIHMpIHsKCQkJcyA9IHMgfHwge307CgkJCXMuY29udGFpbmVyID0gcy5jb250YWluZXIgfHwgRE9NLmRvYy5ib2R5OwoJCQlzLm9mZnNldF94ID0gcy5vZmZzZXRfeCB8fCAwOwoJCQlzLm9mZnNldF95ID0gcy5vZmZzZXRfeSB8fCAwOwoJCQlzLnZwX29mZnNldF94ID0gcy52cF9vZmZzZXRfeCB8fCAwOwoJCQlzLnZwX29mZnNldF95ID0gcy52cF9vZmZzZXRfeSB8fCAwOwoKCQkJaWYgKGlzKHMuaWNvbnMpICYmICFzLmljb25zKQoJCQkJc1snY2xhc3MnXSArPSAnIG1jZU5vSWNvbnMnOwoKCQkJdGhpcy5wYXJlbnQoaWQsIHMpOwoJCQl0aGlzLm9uU2hvd01lbnUgPSBuZXcgdGlueW1jZS51dGlsLkRpc3BhdGNoZXIodGhpcyk7CgkJCXRoaXMub25IaWRlTWVudSA9IG5ldyB0aW55bWNlLnV0aWwuRGlzcGF0Y2hlcih0aGlzKTsKCQkJdGhpcy5jbGFzc1ByZWZpeCA9ICdtY2VNZW51JzsKCQl9LAoKCQljcmVhdGVNZW51IDogZnVuY3Rpb24ocykgewoJCQl2YXIgdCA9IHRoaXMsIGNzID0gdC5zZXR0aW5ncywgbTsKCgkJCXMuY29udGFpbmVyID0gcy5jb250YWluZXIgfHwgY3MuY29udGFpbmVyOwoJCQlzLnBhcmVudCA9IHQ7CgkJCXMuY29uc3RyYWluID0gcy5jb25zdHJhaW4gfHwgY3MuY29uc3RyYWluOwoJCQlzWydjbGFzcyddID0gc1snY2xhc3MnXSB8fCBjc1snY2xhc3MnXTsKCQkJcy52cF9vZmZzZXRfeCA9IHMudnBfb2Zmc2V0X3ggfHwgY3MudnBfb2Zmc2V0X3g7CgkJCXMudnBfb2Zmc2V0X3kgPSBzLnZwX29mZnNldF95IHx8IGNzLnZwX29mZnNldF95OwoJCQltID0gbmV3IHRpbnltY2UudWkuRHJvcE1lbnUocy5pZCB8fCBET00udW5pcXVlSWQoKSwgcyk7CgoJCQltLm9uQWRkSXRlbS5hZGQodC5vbkFkZEl0ZW0uZGlzcGF0Y2gsIHQub25BZGRJdGVtKTsKCgkJCXJldHVybiBtOwoJCX0sCgoJCXVwZGF0ZSA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXMsIHMgPSB0LnNldHRpbmdzLCB0YiA9IERPTS5nZXQoJ21lbnVfJyArIHQuaWQgKyAnX3RibCcpLCBjbyA9IERPTS5nZXQoJ21lbnVfJyArIHQuaWQgKyAnX2NvJyksIHR3LCB0aDsKCgkJCXR3ID0gcy5tYXhfd2lkdGggPyBNYXRoLm1pbih0Yi5jbGllbnRXaWR0aCwgcy5tYXhfd2lkdGgpIDogdGIuY2xpZW50V2lkdGg7CgkJCXRoID0gcy5tYXhfaGVpZ2h0ID8gTWF0aC5taW4odGIuY2xpZW50SGVpZ2h0LCBzLm1heF9oZWlnaHQpIDogdGIuY2xpZW50SGVpZ2h0OwoKCQkJaWYgKCFET00uYm94TW9kZWwpCgkJCQl0LmVsZW1lbnQuc2V0U3R5bGVzKHt3aWR0aCA6IHR3ICsgMiwgaGVpZ2h0IDogdGggKyAyfSk7CgkJCWVsc2UKCQkJCXQuZWxlbWVudC5zZXRTdHlsZXMoe3dpZHRoIDogdHcsIGhlaWdodCA6IHRofSk7CgoJCQlpZiAocy5tYXhfd2lkdGgpCgkJCQlET00uc2V0U3R5bGUoY28sICd3aWR0aCcsIHR3KTsKCgkJCWlmIChzLm1heF9oZWlnaHQpIHsKCQkJCURPTS5zZXRTdHlsZShjbywgJ2hlaWdodCcsIHRoKTsKCgkJCQlpZiAodGIuY2xpZW50SGVpZ2h0IDwgcy5tYXhfaGVpZ2h0KQoJCQkJCURPTS5zZXRTdHlsZShjbywgJ292ZXJmbG93JywgJ2hpZGRlbicpOwoJCQl9CgkJfSwKCgkJc2hvd01lbnUgOiBmdW5jdGlvbih4LCB5LCBweCkgewoJCQl2YXIgdCA9IHRoaXMsIHMgPSB0LnNldHRpbmdzLCBjbywgdnAgPSBET00uZ2V0Vmlld1BvcnQoKSwgdywgaCwgbXgsIG15LCBvdCA9IDIsIGRtLCB0YiwgY3AgPSB0LmNsYXNzUHJlZml4OwoKCQkJdC5jb2xsYXBzZSgxKTsKCgkJCWlmICh0LmlzTWVudVZpc2libGUpCgkJCQlyZXR1cm47CgoJaWYgKCF0LnJlbmRlcmVkKSB7CgkJCQljbyA9IERPTS5hZGQodC5zZXR0aW5ncy5jb250YWluZXIsIHQucmVuZGVyTm9kZSgpKTsKCgkJCQllYWNoKHQuaXRlbXMsIGZ1bmN0aW9uKG8pIHsKCQkJCQlvLnBvc3RSZW5kZXIoKTsKCQkJCX0pOwoKCQkJCXQuZWxlbWVudCA9IG5ldyBFbGVtZW50KCdtZW51XycgKyB0LmlkLCB7YmxvY2tlciA6IDEsIGNvbnRhaW5lciA6IHMuY29udGFpbmVyfSk7CgkJCX0gZWxzZQoJCQkJY28gPSBET00uZ2V0KCdtZW51XycgKyB0LmlkKTsKCgkJCS8vIE1vdmUgbGF5ZXIgb3V0IG9mIHNpZ2h0IHVubGVzcyBpdCdzIE9wZXJhIHNpbmNlIGl0IHNjcm9sbHMgdG8gdG9wIG9mIHBhZ2UgZHVlIHRvIGFuIGJ1ZwoJCQlpZiAoIXRpbnltY2UuaXNPcGVyYSkKCQkJCURPTS5zZXRTdHlsZXMoY28sIHtsZWZ0IDogLTB4RkZGRiAsIHRvcCA6IC0weEZGRkZ9KTsKCgkJCURPTS5zaG93KGNvKTsKCQkJdC51cGRhdGUoKTsKCgkJCXggKz0gcy5vZmZzZXRfeCB8fCAwOwoJCQl5ICs9IHMub2Zmc2V0X3kgfHwgMDsKCQkJdnAudyAtPSA0OwoJCQl2cC5oIC09IDQ7CgoJCQkvLyBNb3ZlIGluc2lkZSB2aWV3cG9ydCBpZiBub3Qgc3VibWVudQoJCQlpZiAocy5jb25zdHJhaW4pIHsKCQkJCXcgPSBjby5jbGllbnRXaWR0aCAtIG90OwoJCQkJaCA9IGNvLmNsaWVudEhlaWdodCAtIG90OwoJCQkJbXggPSB2cC54ICsgdnAudzsKCQkJCW15ID0gdnAueSArIHZwLmg7CgoJCQkJaWYgKCh4ICsgcy52cF9vZmZzZXRfeCArIHcpID4gbXgpCgkJCQkJeCA9IHB4ID8gcHggLSB3IDogTWF0aC5tYXgoMCwgKG14IC0gcy52cF9vZmZzZXRfeCkgLSB3KTsKCgkJCQlpZiAoKHkgKyBzLnZwX29mZnNldF95ICsgaCkgPiBteSkKCQkJCQl5ID0gTWF0aC5tYXgoMCwgKG15IC0gcy52cF9vZmZzZXRfeSkgLSBoKTsKCQkJfQoKCQkJRE9NLnNldFN0eWxlcyhjbywge2xlZnQgOiB4ICwgdG9wIDogeX0pOwoJCQl0LmVsZW1lbnQudXBkYXRlKCk7CgoJCQl0LmlzTWVudVZpc2libGUgPSAxOwoJCQl0Lm1vdXNlQ2xpY2tGdW5jID0gRXZlbnQuYWRkKGNvLCAnY2xpY2snLCBmdW5jdGlvbihlKSB7CgkJCQl2YXIgbTsKCgkJCQllID0gZS50YXJnZXQ7CgoJCQkJaWYgKGUgJiYgKGUgPSBET00uZ2V0UGFyZW50KGUsICd0cicpKSAmJiAhRE9NLmhhc0NsYXNzKGUsIGNwICsgJ0l0ZW1TdWInKSkgewoJCQkJCW0gPSB0Lml0ZW1zW2UuaWRdOwoKCQkJCQlpZiAobS5pc0Rpc2FibGVkKCkpCgkJCQkJCXJldHVybjsKCgkJCQkJZG0gPSB0OwoKCQkJCQl3aGlsZSAoZG0pIHsKCQkJCQkJaWYgKGRtLmhpZGVNZW51KQoJCQkJCQkJZG0uaGlkZU1lbnUoKTsKCgkJCQkJCWRtID0gZG0uc2V0dGluZ3MucGFyZW50OwoJCQkJCX0KCgkJCQkJaWYgKG0uc2V0dGluZ3Mub25jbGljaykKCQkJCQkJbS5zZXR0aW5ncy5vbmNsaWNrKGUpOwoKCQkJCQlyZXR1cm4gRXZlbnQuY2FuY2VsKGUpOyAvLyBDYW5jZWwgdG8gZml4IG9uYmVmb3JldW5sb2FkIHByb2JsZW0KCQkJCX0KCQkJfSk7CgoJCQlpZiAodC5oYXNNZW51cygpKSB7CgkJCQl0Lm1vdXNlT3ZlckZ1bmMgPSBFdmVudC5hZGQoY28sICdtb3VzZW92ZXInLCBmdW5jdGlvbihlKSB7CgkJCQkJdmFyIG0sIHIsIG1pOwoKCQkJCQllID0gZS50YXJnZXQ7CgkJCQkJaWYgKGUgJiYgKGUgPSBET00uZ2V0UGFyZW50KGUsICd0cicpKSkgewoJCQkJCQltID0gdC5pdGVtc1tlLmlkXTsKCgkJCQkJCWlmICh0Lmxhc3RNZW51KQoJCQkJCQkJdC5sYXN0TWVudS5jb2xsYXBzZSgxKTsKCgkJCQkJCWlmIChtLmlzRGlzYWJsZWQoKSkKCQkJCQkJCXJldHVybjsKCgkJCQkJCWlmIChlICYmIERPTS5oYXNDbGFzcyhlLCBjcCArICdJdGVtU3ViJykpIHsKCQkJCQkJCS8vcCA9IERPTS5nZXRQb3Mocy5jb250YWluZXIpOwoJCQkJCQkJciA9IERPTS5nZXRSZWN0KGUpOwoJCQkJCQkJbS5zaG93TWVudSgoci54ICsgci53IC0gb3QpLCByLnkgLSBvdCwgci54KTsKCQkJCQkJCXQubGFzdE1lbnUgPSBtOwoJCQkJCQkJRE9NLmFkZENsYXNzKERPTS5nZXQobS5pZCkuZmlyc3RDaGlsZCwgY3AgKyAnSXRlbUFjdGl2ZScpOwoJCQkJCQl9CgkJCQkJfQoJCQkJfSk7CgkJCX0KCgkJCXQub25TaG93TWVudS5kaXNwYXRjaCh0KTsKCiAgICAgICAgICAgaWYgKHMua2V5Ym9hcmRfZm9jdXMpIHsKCQkJCUV2ZW50LmFkZChjbywgJ2tleWRvd24nLCB0Ll9rZXlIYW5kbGVyLCB0KTsKCQkJCURPTS5zZWxlY3QoJ2EnLCAnbWVudV8nICsgdC5pZClbMF0uZm9jdXMoKTsgLy8gU2VsZWN0IGZpcnN0IGxpbmsKCQkJCXQuX2ZvY3VzSWR4ID0gMDsKCQkJfQogICAgICAgIH0sCgoJCWhpZGVNZW51IDogZnVuY3Rpb24oYykgewoJCQl2YXIgdCA9IHRoaXMsIGNvID0gRE9NLmdldCgnbWVudV8nICsgdC5pZCksIGU7CgoJCQlpZiAoIXQuaXNNZW51VmlzaWJsZSkKCQkJCXJldHVybjsKCgkJCUV2ZW50LnJlbW92ZShjbywgJ21vdXNlb3ZlcicsIHQubW91c2VPdmVyRnVuYyk7CgkJCUV2ZW50LnJlbW92ZShjbywgJ2NsaWNrJywgdC5tb3VzZUNsaWNrRnVuYyk7CgkJCUV2ZW50LnJlbW92ZShjbywgJ2tleWRvd24nLCB0Ll9rZXlIYW5kbGVyKTsKCQkJRE9NLmhpZGUoY28pOwoJCQl0LmlzTWVudVZpc2libGUgPSAwOwoKCQkJaWYgKCFjKQoJCQkJdC5jb2xsYXBzZSgxKTsKCgkJCWlmICh0LmVsZW1lbnQpCgkJCQl0LmVsZW1lbnQuaGlkZSgpOwoKCQkJaWYgKGUgPSBET00uZ2V0KHQuaWQpKQoJCQkJRE9NLnJlbW92ZUNsYXNzKGUuZmlyc3RDaGlsZCwgdC5jbGFzc1ByZWZpeCArICdJdGVtQWN0aXZlJyk7CgoJCQl0Lm9uSGlkZU1lbnUuZGlzcGF0Y2godCk7CgkJfSwKCgkJYWRkIDogZnVuY3Rpb24obykgewoJCQl2YXIgdCA9IHRoaXMsIGNvOwoKCQkJbyA9IHQucGFyZW50KG8pOwoKCQkJaWYgKHQuaXNSZW5kZXJlZCAmJiAoY28gPSBET00uZ2V0KCdtZW51XycgKyB0LmlkKSkpCgkJCQl0Ll9hZGQoRE9NLnNlbGVjdCgndGJvZHknLCBjbylbMF0sIG8pOwoKCQkJcmV0dXJuIG87CgkJfSwKCgkJY29sbGFwc2UgOiBmdW5jdGlvbihkKSB7CgkJCXRoaXMucGFyZW50KGQpOwoJCQl0aGlzLmhpZGVNZW51KDEpOwoJCX0sCgoJCXJlbW92ZSA6IGZ1bmN0aW9uKG8pIHsKCQkJRE9NLnJlbW92ZShvLmlkKTsKCQkJdGhpcy5kZXN0cm95KCk7CgoJCQlyZXR1cm4gdGhpcy5wYXJlbnQobyk7CgkJfSwKCgkJZGVzdHJveSA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXMsIGNvID0gRE9NLmdldCgnbWVudV8nICsgdC5pZCk7CgoJCQlFdmVudC5yZW1vdmUoY28sICdtb3VzZW92ZXInLCB0Lm1vdXNlT3ZlckZ1bmMpOwoJCQlFdmVudC5yZW1vdmUoY28sICdjbGljaycsIHQubW91c2VDbGlja0Z1bmMpOwoKCQkJaWYgKHQuZWxlbWVudCkKCQkJCXQuZWxlbWVudC5yZW1vdmUoKTsKCgkJCURPTS5yZW1vdmUoY28pOwoJCX0sCgoJCXJlbmRlck5vZGUgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCBzID0gdC5zZXR0aW5ncywgbiwgdGIsIGNvLCB3OwoKCQkJdyA9IERPTS5jcmVhdGUoJ2RpdicsIHtpZCA6ICdtZW51XycgKyB0LmlkLCAnY2xhc3MnIDogc1snY2xhc3MnXSwgJ3N0eWxlJyA6ICdwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0OjA7dG9wOjA7ei1pbmRleDoyMDAwMDAnfSk7CgkJCWNvID0gRE9NLmFkZCh3LCAnZGl2Jywge2lkIDogJ21lbnVfJyArIHQuaWQgKyAnX2NvJywgJ2NsYXNzJyA6IHQuY2xhc3NQcmVmaXggKyAoc1snY2xhc3MnXSA/ICcgJyArIHNbJ2NsYXNzJ10gOiAnJyl9KTsKCQkJdC5lbGVtZW50ID0gbmV3IEVsZW1lbnQoJ21lbnVfJyArIHQuaWQsIHtibG9ja2VyIDogMSwgY29udGFpbmVyIDogcy5jb250YWluZXJ9KTsKCgkJCWlmIChzLm1lbnVfbGluZSkKCQkJCURPTS5hZGQoY28sICdzcGFuJywgeydjbGFzcycgOiB0LmNsYXNzUHJlZml4ICsgJ0xpbmUnfSk7CgovLwkJCW4gPSBET00uYWRkKGNvLCAnZGl2Jywge2lkIDogJ21lbnVfJyArIHQuaWQgKyAnX2NvJywgJ2NsYXNzJyA6ICdtY2VNZW51Q29udGFpbmVyJ30pOwoJCQluID0gRE9NLmFkZChjbywgJ3RhYmxlJywge2lkIDogJ21lbnVfJyArIHQuaWQgKyAnX3RibCcsIGJvcmRlciA6IDAsIGNlbGxQYWRkaW5nIDogMCwgY2VsbFNwYWNpbmcgOiAwfSk7CgkJCXRiID0gRE9NLmFkZChuLCAndGJvZHknKTsKCgkJCWVhY2godC5pdGVtcywgZnVuY3Rpb24obykgewoJCQkJdC5fYWRkKHRiLCBvKTsKCQkJfSk7CgoJCQl0LnJlbmRlcmVkID0gdHJ1ZTsKCgkJCXJldHVybiB3OwoJCX0sCgoJCS8vIEludGVybmFsIGZ1bmN0aW9ucwoKCQlfa2V5SGFuZGxlciA6IGZ1bmN0aW9uKGUpIHsKCQkJdmFyIHQgPSB0aGlzLCBrYyA9IGUua2V5Q29kZTsKCgkJCWZ1bmN0aW9uIGZvY3VzKGQpIHsKCQkJCXZhciBpID0gdC5fZm9jdXNJZHggKyBkLCBlID0gRE9NLnNlbGVjdCgnYScsICdtZW51XycgKyB0LmlkKVtpXTsKCgkJCQlpZiAoZSkgewoJCQkJCXQuX2ZvY3VzSWR4ID0gaTsKCQkJCQllLmZvY3VzKCk7CgkJCQl9CgkJCX07CgoJCQlzd2l0Y2ggKGtjKSB7CgkJCQljYXNlIDM4OgoJCQkJCWZvY3VzKC0xKTsgLy8gU2VsZWN0IGZpcnN0IGxpbmsKCQkJCQlyZXR1cm47CgoJCQkJY2FzZSA0MDoKCQkJCQlmb2N1cygxKTsKCQkJCQlyZXR1cm47CgoJCQkJY2FzZSAxMzoKCQkJCQlyZXR1cm47CgoJCQkJY2FzZSAyNzoKCQkJCQlyZXR1cm4gdGhpcy5oaWRlTWVudSgpOwoJCQl9CgkJfSwKCgkJX2FkZCA6IGZ1bmN0aW9uKHRiLCBvKSB7CgkJCXZhciBuLCBzID0gby5zZXR0aW5ncywgYSwgcm8sIGl0LCBjcCA9IHRoaXMuY2xhc3NQcmVmaXgsIGljOwoKCQkJaWYgKHMuc2VwYXJhdG9yKSB7CgkJCQlybyA9IERPTS5hZGQodGIsICd0cicsIHtpZCA6IG8uaWQsICdjbGFzcycgOiBjcCArICdJdGVtU2VwYXJhdG9yJ30pOwoJCQkJRE9NLmFkZChybywgJ3RkJywgeydjbGFzcycgOiBjcCArICdJdGVtU2VwYXJhdG9yJ30pOwoKCQkJCWlmIChuID0gcm8ucHJldmlvdXNTaWJsaW5nKQoJCQkJCURPTS5hZGRDbGFzcyhuLCAnbWNlTGFzdCcpOwoKCQkJCXJldHVybjsKCQkJfQoKCQkJbiA9IHJvID0gRE9NLmFkZCh0YiwgJ3RyJywge2lkIDogby5pZCwgJ2NsYXNzJyA6IGNwICsgJ0l0ZW0gJyArIGNwICsgJ0l0ZW1FbmFibGVkJ30pOwoJCQluID0gaXQgPSBET00uYWRkKG4sICd0ZCcpOwoJCQluID0gYSA9IERPTS5hZGQobiwgJ2EnLCB7aHJlZiA6ICdqYXZhc2NyaXB0OjsnLCBvbmNsaWNrIDogInJldHVybiBmYWxzZTsiLCBvbm1vdXNlZG93biA6ICdyZXR1cm4gZmFsc2U7J30pOwoKCQkJRE9NLmFkZENsYXNzKGl0LCBzWydjbGFzcyddKTsKLy8JCQluID0gRE9NLmFkZChuLCAnc3BhbicsIHsnY2xhc3MnIDogJ2l0ZW0nfSk7CgoJCQlpYyA9IERPTS5hZGQobiwgJ3NwYW4nLCB7J2NsYXNzJyA6ICdtY2VJY29uJyArIChzLmljb24gPyAnIG1jZV8nICsgcy5pY29uIDogJycpfSk7CgoJCQlpZiAocy5pY29uX3NyYykKCQkJCURPTS5hZGQoaWMsICdpbWcnLCB7c3JjIDogcy5pY29uX3NyY30pOwoKCQkJbiA9IERPTS5hZGQobiwgcy5lbGVtZW50IHx8ICdzcGFuJywgeydjbGFzcycgOiAnbWNlVGV4dCcsIHRpdGxlIDogby5zZXR0aW5ncy50aXRsZX0sIG8uc2V0dGluZ3MudGl0bGUpOwoKCQkJaWYgKG8uc2V0dGluZ3Muc3R5bGUpCgkJCQlET00uc2V0QXR0cmliKG4sICdzdHlsZScsIG8uc2V0dGluZ3Muc3R5bGUpOwoKCQkJaWYgKHRiLmNoaWxkTm9kZXMubGVuZ3RoID09IDEpCgkJCQlET00uYWRkQ2xhc3Mocm8sICdtY2VGaXJzdCcpOwoKCQkJaWYgKChuID0gcm8ucHJldmlvdXNTaWJsaW5nKSAmJiBET00uaGFzQ2xhc3MobiwgY3AgKyAnSXRlbVNlcGFyYXRvcicpKQoJCQkJRE9NLmFkZENsYXNzKHJvLCAnbWNlRmlyc3QnKTsKCgkJCWlmIChvLmNvbGxhcHNlKQoJCQkJRE9NLmFkZENsYXNzKHJvLCBjcCArICdJdGVtU3ViJyk7CgoJCQlpZiAobiA9IHJvLnByZXZpb3VzU2libGluZykKCQkJCURPTS5yZW1vdmVDbGFzcyhuLCAnbWNlTGFzdCcpOwoKCQkJRE9NLmFkZENsYXNzKHJvLCAnbWNlTGFzdCcpOwoJCX0KCgkJfSk7Cn0pKHRpbnltY2UpOyhmdW5jdGlvbih0aW55bWNlKSB7Cgl2YXIgRE9NID0gdGlueW1jZS5ET007CgoJdGlueW1jZS5jcmVhdGUoJ3RpbnltY2UudWkuQnV0dG9uOnRpbnltY2UudWkuQ29udHJvbCcsIHsKCQlCdXR0b24gOiBmdW5jdGlvbihpZCwgcykgewoJCQl0aGlzLnBhcmVudChpZCwgcyk7CgkJCXRoaXMuY2xhc3NQcmVmaXggPSAnbWNlQnV0dG9uJzsKCQl9LAoKCQlyZW5kZXJIVE1MIDogZnVuY3Rpb24oKSB7CgkJCXZhciBjcCA9IHRoaXMuY2xhc3NQcmVmaXgsIHMgPSB0aGlzLnNldHRpbmdzLCBoLCBsOwoKCQkJbCA9IERPTS5lbmNvZGUocy5sYWJlbCB8fCAnJyk7CgkJCWggPSAnPGEgaWQ9IicgKyB0aGlzLmlkICsgJyIgaHJlZj0iamF2YXNjcmlwdDo7IiBjbGFzcz0iJyArIGNwICsgJyAnICsgY3AgKyAnRW5hYmxlZCAnICsgc1snY2xhc3MnXSArIChsID8gJyAnICsgY3AgKyAnTGFiZWxsZWQnIDogJycpICsnIiBvbm1vdXNlZG93bj0icmV0dXJuIGZhbHNlOyIgb25jbGljaz0icmV0dXJuIGZhbHNlOyIgdGl0bGU9IicgKyBET00uZW5jb2RlKHMudGl0bGUpICsgJyI+JzsKCgkJCWlmIChzLmltYWdlKQoJCQkJaCArPSAnPGltZyBjbGFzcz0ibWNlSWNvbiIgc3JjPSInICsgcy5pbWFnZSArICciIC8+JyArIGwgKyAnPC9hPic7CgkJCWVsc2UKCQkJCWggKz0gJzxzcGFuIGNsYXNzPSJtY2VJY29uICcgKyBzWydjbGFzcyddICsgJyI+PC9zcGFuPicgKyAobCA/ICc8c3BhbiBjbGFzcz0iJyArIGNwICsgJ0xhYmVsIj4nICsgbCArICc8L3NwYW4+JyA6ICcnKSArICc8L2E+JzsKCgkJCXJldHVybiBoOwoJCX0sCgoJCXBvc3RSZW5kZXIgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCBzID0gdC5zZXR0aW5nczsKCgkJCXRpbnltY2UuZG9tLkV2ZW50LmFkZCh0LmlkLCAnY2xpY2snLCBmdW5jdGlvbihlKSB7CgkJCQlpZiAoIXQuaXNEaXNhYmxlZCgpKQoJCQkJCXJldHVybiBzLm9uY2xpY2suY2FsbChzLnNjb3BlLCBlKTsKCQkJfSk7CgkJfQoKCQl9KTsKfSkodGlueW1jZSk7CihmdW5jdGlvbih0aW55bWNlKSB7Cgl2YXIgRE9NID0gdGlueW1jZS5ET00sIEV2ZW50ID0gdGlueW1jZS5kb20uRXZlbnQsIGVhY2ggPSB0aW55bWNlLmVhY2gsIERpc3BhdGNoZXIgPSB0aW55bWNlLnV0aWwuRGlzcGF0Y2hlcjsKCgl0aW55bWNlLmNyZWF0ZSgndGlueW1jZS51aS5MaXN0Qm94OnRpbnltY2UudWkuQ29udHJvbCcsIHsKCQlMaXN0Qm94IDogZnVuY3Rpb24oaWQsIHMpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJdC5wYXJlbnQoaWQsIHMpOwoJCQl0Lml0ZW1zID0gW107CgkJCXQub25DaGFuZ2UgPSBuZXcgRGlzcGF0Y2hlcih0KTsKCQkJdC5vblBvc3RSZW5kZXIgPSBuZXcgRGlzcGF0Y2hlcih0KTsKCQkJdC5vbkFkZCA9IG5ldyBEaXNwYXRjaGVyKHQpOwoJCQl0Lm9uUmVuZGVyTWVudSA9IG5ldyB0aW55bWNlLnV0aWwuRGlzcGF0Y2hlcih0aGlzKTsKCQkJdC5jbGFzc1ByZWZpeCA9ICdtY2VMaXN0Qm94JzsKCQl9LAoKCQlzZWxlY3QgOiBmdW5jdGlvbih2YSkgewoJCQl2YXIgdCA9IHRoaXMsIGZ2LCBmOwoKCQkJaWYgKHZhID09IHVuZGVmaW5lZCkKCQkJCXJldHVybiB0LnNlbGVjdEJ5SW5kZXgoLTEpOwoKCQkJLy8gSXMgc3RyaW5nIG9yIG51bWJlciBtYWtlIGZ1bmN0aW9uIHNlbGVjdG9yCgkJCWlmICh2YSAmJiB2YS5jYWxsKQoJCQkJZiA9IHZhOwoJCQllbHNlIHsKCQkJCWYgPSBmdW5jdGlvbih2KSB7CgkJCQkJcmV0dXJuIHYgPT0gdmE7CgkJCQl9OwoJCQl9CgoJCQkvLyBEbyB3ZSBuZWVkIHRvIGRvIHNvbWV0aGluZz8KCQkJaWYgKHZhICE9IHQuc2VsZWN0ZWRWYWx1ZSkgewoJCQkJLy8gRmluZCBpdGVtCgkJCQllYWNoKHQuaXRlbXMsIGZ1bmN0aW9uKG8sIGkpIHsKCQkJCQlpZiAoZihvLnZhbHVlKSkgewoJCQkJCQlmdiA9IDE7CgkJCQkJCXQuc2VsZWN0QnlJbmRleChpKTsKCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCX0KCQkJCX0pOwoKCQkJCWlmICghZnYpCgkJCQkJdC5zZWxlY3RCeUluZGV4KC0xKTsKCQkJfQoJCX0sCgoJCXNlbGVjdEJ5SW5kZXggOiBmdW5jdGlvbihpZHgpIHsKCQkJdmFyIHQgPSB0aGlzLCBlLCBvOwoKCQkJaWYgKGlkeCAhPSB0LnNlbGVjdGVkSW5kZXgpIHsKCQkJCWUgPSBET00uZ2V0KHQuaWQgKyAnX3RleHQnKTsKCQkJCW8gPSB0Lml0ZW1zW2lkeF07CgoJCQkJaWYgKG8pIHsKCQkJCQl0LnNlbGVjdGVkVmFsdWUgPSBvLnZhbHVlOwoJCQkJCXQuc2VsZWN0ZWRJbmRleCA9IGlkeDsKCQkJCQlET00uc2V0SFRNTChlLCBET00uZW5jb2RlKG8udGl0bGUpKTsKCQkJCQlET00ucmVtb3ZlQ2xhc3MoZSwgJ21jZVRpdGxlJyk7CgkJCQl9IGVsc2UgewoJCQkJCURPTS5zZXRIVE1MKGUsIERPTS5lbmNvZGUodC5zZXR0aW5ncy50aXRsZSkpOwoJCQkJCURPTS5hZGRDbGFzcyhlLCAnbWNlVGl0bGUnKTsKCQkJCQl0LnNlbGVjdGVkVmFsdWUgPSB0LnNlbGVjdGVkSW5kZXggPSBudWxsOwoJCQkJfQoKCQkJCWUgPSAwOwoJCQl9CgkJfSwKCgkJYWRkIDogZnVuY3Rpb24obiwgdiwgbykgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQlvID0gbyB8fCB7fTsKCQkJbyA9IHRpbnltY2UuZXh0ZW5kKG8sIHsKCQkJCXRpdGxlIDogbiwKCQkJCXZhbHVlIDogdgoJCQl9KTsKCgkJCXQuaXRlbXMucHVzaChvKTsKCQkJdC5vbkFkZC5kaXNwYXRjaCh0LCBvKTsKCQl9LAoKCQlnZXRMZW5ndGggOiBmdW5jdGlvbigpIHsKCQkJcmV0dXJuIHRoaXMuaXRlbXMubGVuZ3RoOwoJCX0sCgoJCXJlbmRlckhUTUwgOiBmdW5jdGlvbigpIHsKCQkJdmFyIGggPSAnJywgdCA9IHRoaXMsIHMgPSB0LnNldHRpbmdzLCBjcCA9IHQuY2xhc3NQcmVmaXg7CgoJCQloID0gJzx0YWJsZSBpZD0iJyArIHQuaWQgKyAnIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIGNsYXNzPSInICsgY3AgKyAnICcgKyBjcCArICdFbmFibGVkJyArIChzWydjbGFzcyddID8gKCcgJyArIHNbJ2NsYXNzJ10pIDogJycpICsgJyI+PHRib2R5Pjx0cj4nOwoJCQloICs9ICc8dGQ+JyArIERPTS5jcmVhdGVIVE1MKCdhJywge2lkIDogdC5pZCArICdfdGV4dCcsIGhyZWYgOiAnamF2YXNjcmlwdDo7JywgJ2NsYXNzJyA6ICdtY2VUZXh0Jywgb25jbGljayA6ICJyZXR1cm4gZmFsc2U7Iiwgb25tb3VzZWRvd24gOiAncmV0dXJuIGZhbHNlOyd9LCBET00uZW5jb2RlKHQuc2V0dGluZ3MudGl0bGUpKSArICc8L3RkPic7CgkJCWggKz0gJzx0ZD4nICsgRE9NLmNyZWF0ZUhUTUwoJ2EnLCB7aWQgOiB0LmlkICsgJ19vcGVuJywgdGFiaW5kZXggOiAtMSwgaHJlZiA6ICdqYXZhc2NyaXB0OjsnLCAnY2xhc3MnIDogJ21jZU9wZW4nLCBvbmNsaWNrIDogInJldHVybiBmYWxzZTsiLCBvbm1vdXNlZG93biA6ICdyZXR1cm4gZmFsc2U7J30sICc8c3Bhbj48L3NwYW4+JykgKyAnPC90ZD4nOwoJCQloICs9ICc8L3RyPjwvdGJvZHk+PC90YWJsZT4nOwoKCQkJcmV0dXJuIGg7CgkJfSwKCgkJc2hvd01lbnUgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCBwMSwgcDIsIGUgPSBET00uZ2V0KHRoaXMuaWQpLCBtOwoKCQkJaWYgKHQuaXNEaXNhYmxlZCgpIHx8IHQuaXRlbXMubGVuZ3RoID09IDApCgkJCQlyZXR1cm47CgoJCQlpZiAodC5tZW51ICYmIHQubWVudS5pc01lbnVWaXNpYmxlKQoJCQkJcmV0dXJuIHQuaGlkZU1lbnUoKTsKCgkJCWlmICghdC5pc01lbnVSZW5kZXJlZCkgewoJCQkJdC5yZW5kZXJNZW51KCk7CgkJCQl0LmlzTWVudVJlbmRlcmVkID0gdHJ1ZTsKCQkJfQoKCQkJcDEgPSBET00uZ2V0UG9zKHRoaXMuc2V0dGluZ3MubWVudV9jb250YWluZXIpOwoJCQlwMiA9IERPTS5nZXRQb3MoZSk7CgoJCQltID0gdC5tZW51OwoJCQltLnNldHRpbmdzLm9mZnNldF94ID0gcDIueDsKCQkJbS5zZXR0aW5ncy5vZmZzZXRfeSA9IHAyLnk7CgkJCW0uc2V0dGluZ3Mua2V5Ym9hcmRfZm9jdXMgPSAhdGlueW1jZS5pc09wZXJhOyAvLyBPcGVyYSBpcyBidWdneSB3aGVuIGl0IGNvbWVzIHRvIGF1dG8gZm9jdXMKCgkJCS8vIFNlbGVjdCBpbiBtZW51CgkJCWlmICh0Lm9sZElEKQoJCQkJbS5pdGVtc1t0Lm9sZElEXS5zZXRTZWxlY3RlZCgwKTsKCgkJCWVhY2godC5pdGVtcywgZnVuY3Rpb24obykgewoJCQkJaWYgKG8udmFsdWUgPT09IHQuc2VsZWN0ZWRWYWx1ZSkgewoJCQkJCW0uaXRlbXNbby5pZF0uc2V0U2VsZWN0ZWQoMSk7CgkJCQkJdC5vbGRJRCA9IG8uaWQ7CgkJCQl9CgkJCX0pOwoKCQkJbS5zaG93TWVudSgwLCBlLmNsaWVudEhlaWdodCk7CgoJCQlFdmVudC5hZGQoRE9NLmRvYywgJ21vdXNlZG93bicsIHQuaGlkZU1lbnUsIHQpOwoJCQlET00uYWRkQ2xhc3ModC5pZCwgdC5jbGFzc1ByZWZpeCArICdTZWxlY3RlZCcpOwoKCQkJLy9ET00uZ2V0KHQuaWQgKyAnX3RleHQnKS5mb2N1cygpOwoJCX0sCgoJCWhpZGVNZW51IDogZnVuY3Rpb24oZSkgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQkvLyBQcmV2ZW50IGRvdWJsZSB0b29nbGVzIGJ5IGNhbmNlbGluZyB0aGUgbW91c2UgY2xpY2sgZXZlbnQgdG8gdGhlIGJ1dHRvbgoJCQlpZiAoZSAmJiBlLnR5cGUgPT0gIm1vdXNlZG93biIgJiYgKGUudGFyZ2V0LmlkID09IHQuaWQgKyAnX3RleHQnIHx8IGUudGFyZ2V0LmlkID09IHQuaWQgKyAnX29wZW4nKSkKCQkJCXJldHVybjsKCgkJCWlmICghZSB8fCAhRE9NLmdldFBhcmVudChlLnRhcmdldCwgJy5tY2VNZW51JykpIHsKCQkJCURPTS5yZW1vdmVDbGFzcyh0LmlkLCB0LmNsYXNzUHJlZml4ICsgJ1NlbGVjdGVkJyk7CgkJCQlFdmVudC5yZW1vdmUoRE9NLmRvYywgJ21vdXNlZG93bicsIHQuaGlkZU1lbnUsIHQpOwoKCQkJCWlmICh0Lm1lbnUpCgkJCQkJdC5tZW51LmhpZGVNZW51KCk7CgkJCX0KCQl9LAoKCQlyZW5kZXJNZW51IDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpcywgbTsKCgkJCW0gPSB0LnNldHRpbmdzLmNvbnRyb2xfbWFuYWdlci5jcmVhdGVEcm9wTWVudSh0LmlkICsgJ19tZW51JywgewoJCQkJbWVudV9saW5lIDogMSwKCQkJCSdjbGFzcycgOiB0LmNsYXNzUHJlZml4ICsgJ01lbnUgbWNlTm9JY29ucycKICAgICAgICAgICAgICAgIC8vIEFUTEFTU0lBTiAtIGRvbid0IGxpbWl0IGhlaWdodCBvciB3aWR0aCwgbW9yZSB1c2VmdWwgdG8gcmV2ZWFsIG9wdGlvbnMKICAgICAgICAgICAgICAgIC8vLCBtYXhfd2lkdGggOiAxNTAsCgkJCQkvLyBtYXhfaGVpZ2h0IDogMTUwCgkJCX0pOwoKCQkJbS5vbkhpZGVNZW51LmFkZCh0LmhpZGVNZW51LCB0KTsKCgkJCW0uYWRkKHsKCQkJCXRpdGxlIDogdC5zZXR0aW5ncy50aXRsZSwKCQkJCSdjbGFzcycgOiAnbWNlTWVudUl0ZW1UaXRsZScsCgkJCQlvbmNsaWNrIDogZnVuY3Rpb24oKSB7CgkJCQkJaWYgKHQuc2V0dGluZ3Mub25zZWxlY3QoJycpICE9PSBmYWxzZSkKCQkJCQkJdC5zZWxlY3QoJycpOyAvLyBNdXN0IGJlIHJ1bm5lZCBhZnRlcgoJCQkJfQoJCQl9KTsKCgkJCWVhY2godC5pdGVtcywgZnVuY3Rpb24obykgewoJCQkJby5pZCA9IERPTS51bmlxdWVJZCgpOwoJCQkJby5vbmNsaWNrID0gZnVuY3Rpb24oKSB7CgkJCQkJaWYgKHQuc2V0dGluZ3Mub25zZWxlY3Qoby52YWx1ZSkgIT09IGZhbHNlKQoJCQkJCQl0LnNlbGVjdChvLnZhbHVlKTsgLy8gTXVzdCBiZSBydW5uZWQgYWZ0ZXIKCQkJCX07CgoJCQkJbS5hZGQobyk7CgkJCX0pOwoKCQkJdC5vblJlbmRlck1lbnUuZGlzcGF0Y2godCwgbSk7CgkJCXQubWVudSA9IG07CgkJfSwKCgkJcG9zdFJlbmRlciA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXMsIGNwID0gdC5jbGFzc1ByZWZpeDsKCgkJCUV2ZW50LmFkZCh0LmlkLCAnY2xpY2snLCB0LnNob3dNZW51LCB0KTsKCQkJRXZlbnQuYWRkKHQuaWQgKyAnX3RleHQnLCAnZm9jdXMnLCBmdW5jdGlvbihlKSB7CgkJCQlpZiAoIXQuX2ZvY3VzZWQpIHsKCQkJCQl0LmtleURvd25IYW5kbGVyID0gRXZlbnQuYWRkKHQuaWQgKyAnX3RleHQnLCAna2V5ZG93bicsIGZ1bmN0aW9uKGUpIHsKCQkJCQkJdmFyIGlkeCA9IC0xLCB2LCBrYyA9IGUua2V5Q29kZTsKCgkJCQkJCS8vIEZpbmQgY3VycmVudCBpbmRleAoJCQkJCQllYWNoKHQuaXRlbXMsIGZ1bmN0aW9uKHYsIGkpIHsKCQkJCQkJCWlmICh0LnNlbGVjdGVkVmFsdWUgPT0gdi52YWx1ZSkKCQkJCQkJCQlpZHggPSBpOwoJCQkJCQl9KTsKCgkJCQkJCS8vIE1vdmUgdXAvZG93bgoJCQkJCQlpZiAoa2MgPT0gMzgpCgkJCQkJCQl2ID0gdC5pdGVtc1tpZHggLSAxXTsKCQkJCQkJZWxzZSBpZiAoa2MgPT0gNDApCgkJCQkJCQl2ID0gdC5pdGVtc1tpZHggKyAxXTsKCQkJCQkJZWxzZSBpZiAoa2MgPT0gMTMpIHsKCQkJCQkJCS8vIEZha2Ugc2VsZWN0IG9uIGVudGVyCgkJCQkJCQl2ID0gdC5zZWxlY3RlZFZhbHVlOwoJCQkJCQkJdC5zZWxlY3RlZFZhbHVlID0gbnVsbDsgLy8gTmVlZHMgdG8gYmUgbnVsbCB0byBmYWtlIGNoYW5nZQoJCQkJCQkJdC5zZXR0aW5ncy5vbnNlbGVjdCh2KTsKCQkJCQkJCXJldHVybiBFdmVudC5jYW5jZWwoZSk7CgkJCQkJCX0KCgkJCQkJCWlmICh2KSB7CgkJCQkJCQl0LmhpZGVNZW51KCk7CgkJCQkJCQl0LnNlbGVjdCh2LnZhbHVlKTsKCQkJCQkJfQoJCQkJCX0pOwoJCQkJfQoKCQkJCXQuX2ZvY3VzZWQgPSAxOwoJCQl9KTsKCQkJRXZlbnQuYWRkKHQuaWQgKyAnX3RleHQnLCAnYmx1cicsIGZ1bmN0aW9uKCkge0V2ZW50LnJlbW92ZSh0LmlkICsgJ190ZXh0JywgJ2tleWRvd24nLCB0LmtleURvd25IYW5kbGVyKTsgdC5fZm9jdXNlZCA9IDA7fSk7CgoJCQkvLyBPbGQgSUUgZG9lc24ndCBoYXZlIGhvdmVyIG9uIGFsbCBlbGVtZW50cwoJCQlpZiAodGlueW1jZS5pc0lFNiB8fCAhRE9NLmJveE1vZGVsKSB7CgkJCQlFdmVudC5hZGQodC5pZCwgJ21vdXNlb3ZlcicsIGZ1bmN0aW9uKCkgewoJCQkJCWlmICghRE9NLmhhc0NsYXNzKHQuaWQsIGNwICsgJ0Rpc2FibGVkJykpCgkJCQkJCURPTS5hZGRDbGFzcyh0LmlkLCBjcCArICdIb3ZlcicpOwoJCQkJfSk7CgoJCQkJRXZlbnQuYWRkKHQuaWQsICdtb3VzZW91dCcsIGZ1bmN0aW9uKCkgewoJCQkJCWlmICghRE9NLmhhc0NsYXNzKHQuaWQsIGNwICsgJ0Rpc2FibGVkJykpCgkJCQkJCURPTS5yZW1vdmVDbGFzcyh0LmlkLCBjcCArICdIb3ZlcicpOwoJCQkJfSk7CgkJCX0KCgkJCXQub25Qb3N0UmVuZGVyLmRpc3BhdGNoKHQsIERPTS5nZXQodC5pZCkpOwoJCX0sCgoJCWRlc3Ryb3kgOiBmdW5jdGlvbigpIHsKCQkJdGhpcy5wYXJlbnQoKTsKCgkJCUV2ZW50LmNsZWFyKHRoaXMuaWQgKyAnX3RleHQnKTsKCQkJRXZlbnQuY2xlYXIodGhpcy5pZCArICdfb3BlbicpOwoJCX0KCgkJfSk7Cn0pKHRpbnltY2UpOyhmdW5jdGlvbih0aW55bWNlKSB7Cgl2YXIgRE9NID0gdGlueW1jZS5ET00sIEV2ZW50ID0gdGlueW1jZS5kb20uRXZlbnQsIGVhY2ggPSB0aW55bWNlLmVhY2gsIERpc3BhdGNoZXIgPSB0aW55bWNlLnV0aWwuRGlzcGF0Y2hlcjsKCgl0aW55bWNlLmNyZWF0ZSgndGlueW1jZS51aS5OYXRpdmVMaXN0Qm94OnRpbnltY2UudWkuTGlzdEJveCcsIHsKCQlOYXRpdmVMaXN0Qm94IDogZnVuY3Rpb24oaWQsIHMpIHsKCQkJdGhpcy5wYXJlbnQoaWQsIHMpOwoJCQl0aGlzLmNsYXNzUHJlZml4ID0gJ21jZU5hdGl2ZUxpc3RCb3gnOwoJCX0sCgoJCXNldERpc2FibGVkIDogZnVuY3Rpb24ocykgewoJCQlET00uZ2V0KHRoaXMuaWQpLmRpc2FibGVkID0gczsKCQl9LAoKCQlpc0Rpc2FibGVkIDogZnVuY3Rpb24oKSB7CgkJCXJldHVybiBET00uZ2V0KHRoaXMuaWQpLmRpc2FibGVkOwoJCX0sCgoJCXNlbGVjdCA6IGZ1bmN0aW9uKHZhKSB7CgkJCXZhciB0ID0gdGhpcywgZnYsIGY7CgoJCQlpZiAodmEgPT0gdW5kZWZpbmVkKQoJCQkJcmV0dXJuIHQuc2VsZWN0QnlJbmRleCgtMSk7CgoJCQkvLyBJcyBzdHJpbmcgb3IgbnVtYmVyIG1ha2UgZnVuY3Rpb24gc2VsZWN0b3IKCQkJaWYgKHZhICYmIHZhLmNhbGwpCgkJCQlmID0gdmE7CgkJCWVsc2UgewoJCQkJZiA9IGZ1bmN0aW9uKHYpIHsKCQkJCQlyZXR1cm4gdiA9PSB2YTsKCQkJCX07CgkJCX0KCgkJCS8vIERvIHdlIG5lZWQgdG8gZG8gc29tZXRoaW5nPwoJCQlpZiAodmEgIT0gdC5zZWxlY3RlZFZhbHVlKSB7CgkJCQkvLyBGaW5kIGl0ZW0KCQkJCWVhY2godC5pdGVtcywgZnVuY3Rpb24obywgaSkgewoJCQkJCWlmIChmKG8udmFsdWUpKSB7CgkJCQkJCWZ2ID0gMTsKCQkJCQkJdC5zZWxlY3RCeUluZGV4KGkpOwoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJfQoJCQkJfSk7CgoJCQkJaWYgKCFmdikKCQkJCQl0LnNlbGVjdEJ5SW5kZXgoLTEpOwoJCQl9CgkJfSwKCgkJc2VsZWN0QnlJbmRleCA6IGZ1bmN0aW9uKGlkeCkgewoJCQlET00uZ2V0KHRoaXMuaWQpLnNlbGVjdGVkSW5kZXggPSBpZHggKyAxOwoJCQl0aGlzLnNlbGVjdGVkVmFsdWUgPSB0aGlzLml0ZW1zW2lkeF0gPyB0aGlzLml0ZW1zW2lkeF0udmFsdWUgOiBudWxsOwoJCX0sCgoJCWFkZCA6IGZ1bmN0aW9uKG4sIHYsIGEpIHsKCQkJdmFyIG8sIHQgPSB0aGlzOwoKCQkJYSA9IGEgfHwge307CgkJCWEudmFsdWUgPSB2OwoKCQkJaWYgKHQuaXNSZW5kZXJlZCgpKQoJCQkJRE9NLmFkZChET00uZ2V0KHRoaXMuaWQpLCAnb3B0aW9uJywgYSwgbik7CgoJCQlvID0gewoJCQkJdGl0bGUgOiBuLAoJCQkJdmFsdWUgOiB2LAoJCQkJYXR0cmlicyA6IGEKCQkJfTsKCgkJCXQuaXRlbXMucHVzaChvKTsKCQkJdC5vbkFkZC5kaXNwYXRjaCh0LCBvKTsKCQl9LAoKCQlnZXRMZW5ndGggOiBmdW5jdGlvbigpIHsKCQkJcmV0dXJuIERPTS5nZXQodGhpcy5pZCkub3B0aW9ucy5sZW5ndGggLSAxOwoJCX0sCgoJCXJlbmRlckhUTUwgOiBmdW5jdGlvbigpIHsKCQkJdmFyIGgsIHQgPSB0aGlzOwoKCQkJaCA9IERPTS5jcmVhdGVIVE1MKCdvcHRpb24nLCB7dmFsdWUgOiAnJ30sICctLSAnICsgdC5zZXR0aW5ncy50aXRsZSArICcgLS0nKTsKCgkJCWVhY2godC5pdGVtcywgZnVuY3Rpb24oaXQpIHsKCQkJCWggKz0gRE9NLmNyZWF0ZUhUTUwoJ29wdGlvbicsIHt2YWx1ZSA6IGl0LnZhbHVlfSwgaXQudGl0bGUpOwoJCQl9KTsKCgkJCWggPSBET00uY3JlYXRlSFRNTCgnc2VsZWN0Jywge2lkIDogdC5pZCwgJ2NsYXNzJyA6ICdtY2VOYXRpdmVMaXN0Qm94J30sIGgpOwoKCQkJcmV0dXJuIGg7CgkJfSwKCgkJcG9zdFJlbmRlciA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXMsIGNoOwoKCQkJdC5yZW5kZXJlZCA9IHRydWU7CgoJCQlmdW5jdGlvbiBvbkNoYW5nZShlKSB7CgkJCQl2YXIgdiA9IHQuaXRlbXNbZS50YXJnZXQuc2VsZWN0ZWRJbmRleCAtIDFdOwoKCQkJCWlmICh2ICYmICh2ID0gdi52YWx1ZSkpIHsKCQkJCQl0Lm9uQ2hhbmdlLmRpc3BhdGNoKHQsIHYpOwoKCQkJCQlpZiAodC5zZXR0aW5ncy5vbnNlbGVjdCkKCQkJCQkJdC5zZXR0aW5ncy5vbnNlbGVjdCh2KTsKCQkJCX0KCQkJfTsKCgkJCUV2ZW50LmFkZCh0LmlkLCAnY2hhbmdlJywgb25DaGFuZ2UpOwoKCQkJLy8gQWNjZXNzaWJpbGl0eSBrZXloYW5kbGVyCgkJCUV2ZW50LmFkZCh0LmlkLCAna2V5ZG93bicsIGZ1bmN0aW9uKGUpIHsKCQkJCXZhciBiZjsKCgkJCQlFdmVudC5yZW1vdmUodC5pZCwgJ2NoYW5nZScsIGNoKTsKCgkJCQliZiA9IEV2ZW50LmFkZCh0LmlkLCAnYmx1cicsIGZ1bmN0aW9uKCkgewoJCQkJCUV2ZW50LmFkZCh0LmlkLCAnY2hhbmdlJywgb25DaGFuZ2UpOwoJCQkJCUV2ZW50LnJlbW92ZSh0LmlkLCAnYmx1cicsIGJmKTsKCQkJCX0pOwoKCQkJCWlmIChlLmtleUNvZGUgPT0gMTMgfHwgZS5rZXlDb2RlID09IDMyKSB7CgkJCQkJb25DaGFuZ2UoZSk7CgkJCQkJcmV0dXJuIEV2ZW50LmNhbmNlbChlKTsKCQkJCX0KCQkJfSk7CgoJCQl0Lm9uUG9zdFJlbmRlci5kaXNwYXRjaCh0LCBET00uZ2V0KHQuaWQpKTsKCQl9CgoJCX0pOwp9KSh0aW55bWNlKTsoZnVuY3Rpb24odGlueW1jZSkgewoJdmFyIERPTSA9IHRpbnltY2UuRE9NLCBFdmVudCA9IHRpbnltY2UuZG9tLkV2ZW50LCBlYWNoID0gdGlueW1jZS5lYWNoOwoKCXRpbnltY2UuY3JlYXRlKCd0aW55bWNlLnVpLk1lbnVCdXR0b246dGlueW1jZS51aS5CdXR0b24nLCB7CgkJTWVudUJ1dHRvbiA6IGZ1bmN0aW9uKGlkLCBzKSB7CgkJCXRoaXMucGFyZW50KGlkLCBzKTsKCQkJdGhpcy5vblJlbmRlck1lbnUgPSBuZXcgdGlueW1jZS51dGlsLkRpc3BhdGNoZXIodGhpcyk7CgkJCXMubWVudV9jb250YWluZXIgPSBzLm1lbnVfY29udGFpbmVyIHx8IERPTS5kb2MuYm9keTsKCQl9LAoKCQlzaG93TWVudSA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXMsIHAxLCBwMiwgZSA9IERPTS5nZXQodC5pZCksIG07CgoJCQlpZiAodC5pc0Rpc2FibGVkKCkpCgkJCQlyZXR1cm47CgoJCQlpZiAoIXQuaXNNZW51UmVuZGVyZWQpIHsKCQkJCXQucmVuZGVyTWVudSgpOwoJCQkJdC5pc01lbnVSZW5kZXJlZCA9IHRydWU7CgkJCX0KCgkJCWlmICh0LmlzTWVudVZpc2libGUpCgkJCQlyZXR1cm4gdC5oaWRlTWVudSgpOwoKCQkJcDEgPSBET00uZ2V0UG9zKHQuc2V0dGluZ3MubWVudV9jb250YWluZXIpOwoJCQlwMiA9IERPTS5nZXRQb3MoZSk7CgoJCQltID0gdC5tZW51OwoJCQltLnNldHRpbmdzLm9mZnNldF94ID0gcDIueDsKCQkJbS5zZXR0aW5ncy5vZmZzZXRfeSA9IHAyLnk7CgkJCW0uc2V0dGluZ3MudnBfb2Zmc2V0X3ggPSBwMi54OwoJCQltLnNldHRpbmdzLnZwX29mZnNldF95ID0gcDIueTsKCQkJbS5zZXR0aW5ncy5rZXlib2FyZF9mb2N1cyA9IHQuX2ZvY3VzZWQ7CgkJCW0uc2hvd01lbnUoMCwgZS5jbGllbnRIZWlnaHQpOwoKCQkJRXZlbnQuYWRkKERPTS5kb2MsICdtb3VzZWRvd24nLCB0LmhpZGVNZW51LCB0KTsKCQkJdC5zZXRTdGF0ZSgnU2VsZWN0ZWQnLCAxKTsKCgkJCXQuaXNNZW51VmlzaWJsZSA9IDE7CgkJfSwKCgkJcmVuZGVyTWVudSA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXMsIG07CgoJCQltID0gdC5zZXR0aW5ncy5jb250cm9sX21hbmFnZXIuY3JlYXRlRHJvcE1lbnUodC5pZCArICdfbWVudScsIHsKCQkJCW1lbnVfbGluZSA6IDEsCgkJCQknY2xhc3MnIDogdGhpcy5jbGFzc1ByZWZpeCArICdNZW51JywKCQkJCWljb25zIDogdC5zZXR0aW5ncy5pY29ucwoJCQl9KTsKCgkJCW0ub25IaWRlTWVudS5hZGQodC5oaWRlTWVudSwgdCk7CgoJCQl0Lm9uUmVuZGVyTWVudS5kaXNwYXRjaCh0LCBtKTsKCQkJdC5tZW51ID0gbTsKCQl9LAoKCQloaWRlTWVudSA6IGZ1bmN0aW9uKGUpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJLy8gUHJldmVudCBkb3VibGUgdG9vZ2xlcyBieSBjYW5jZWxpbmcgdGhlIG1vdXNlIGNsaWNrIGV2ZW50IHRvIHRoZSBidXR0b24KCQkJaWYgKGUgJiYgZS50eXBlID09ICJtb3VzZWRvd24iICYmIERPTS5nZXRQYXJlbnQoZS50YXJnZXQsIGZ1bmN0aW9uKGUpIHtyZXR1cm4gZS5pZCA9PT0gdC5pZCB8fCBlLmlkID09PSB0LmlkICsgJ19vcGVuJzt9KSkKCQkJCXJldHVybjsKCgkJCWlmICghZSB8fCAhRE9NLmdldFBhcmVudChlLnRhcmdldCwgJy5tY2VNZW51JykpIHsKCQkJCXQuc2V0U3RhdGUoJ1NlbGVjdGVkJywgMCk7CgkJCQlFdmVudC5yZW1vdmUoRE9NLmRvYywgJ21vdXNlZG93bicsIHQuaGlkZU1lbnUsIHQpOwoJCQkJaWYgKHQubWVudSkKCQkJCQl0Lm1lbnUuaGlkZU1lbnUoKTsKCQkJfQoKCQkJdC5pc01lbnVWaXNpYmxlID0gMDsKCQl9LAoKCQlwb3N0UmVuZGVyIDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpcywgcyA9IHQuc2V0dGluZ3M7CgoJCQlFdmVudC5hZGQodC5pZCwgJ2NsaWNrJywgZnVuY3Rpb24oKSB7CgkJCQlpZiAoIXQuaXNEaXNhYmxlZCgpKSB7CgkJCQkJaWYgKHMub25jbGljaykKCQkJCQkJcy5vbmNsaWNrKHQudmFsdWUpOwoKCQkJCQl0LnNob3dNZW51KCk7CgkJCQl9CgkJCX0pOwoJCX0KCgkJfSk7Cn0pKHRpbnltY2UpOwooZnVuY3Rpb24odGlueW1jZSkgewoJdmFyIERPTSA9IHRpbnltY2UuRE9NLCBFdmVudCA9IHRpbnltY2UuZG9tLkV2ZW50LCBlYWNoID0gdGlueW1jZS5lYWNoOwoKCXRpbnltY2UuY3JlYXRlKCd0aW55bWNlLnVpLlNwbGl0QnV0dG9uOnRpbnltY2UudWkuTWVudUJ1dHRvbicsIHsKCQlTcGxpdEJ1dHRvbiA6IGZ1bmN0aW9uKGlkLCBzKSB7CgkJCXRoaXMucGFyZW50KGlkLCBzKTsKCQkJdGhpcy5jbGFzc1ByZWZpeCA9ICdtY2VTcGxpdEJ1dHRvbic7CgkJfSwKCgkJcmVuZGVySFRNTCA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgaCwgdCA9IHRoaXMsIHMgPSB0LnNldHRpbmdzLCBoMTsKCgkJCWggPSAnPHRib2R5Pjx0cj4nOwoKCQkJaWYgKHMuaW1hZ2UpCgkJCQloMSA9IERPTS5jcmVhdGVIVE1MKCdpbWcgJywge3NyYyA6IHMuaW1hZ2UsICdjbGFzcycgOiAnbWNlQWN0aW9uICcgKyBzWydjbGFzcyddfSk7CgkJCWVsc2UKCQkJCWgxID0gRE9NLmNyZWF0ZUhUTUwoJ3NwYW4nLCB7J2NsYXNzJyA6ICdtY2VBY3Rpb24gJyArIHNbJ2NsYXNzJ119LCAnJyk7CgoJCQloICs9ICc8dGQ+JyArIERPTS5jcmVhdGVIVE1MKCdhJywge2lkIDogdC5pZCArICdfYWN0aW9uJywgaHJlZiA6ICdqYXZhc2NyaXB0OjsnLCAnY2xhc3MnIDogJ21jZUFjdGlvbiAnICsgc1snY2xhc3MnXSwgb25jbGljayA6ICJyZXR1cm4gZmFsc2U7Iiwgb25tb3VzZWRvd24gOiAncmV0dXJuIGZhbHNlOycsIHRpdGxlIDogcy50aXRsZX0sIGgxKSArICc8L3RkPic7CgoJCQloMSA9IERPTS5jcmVhdGVIVE1MKCdzcGFuJywgeydjbGFzcycgOiAnbWNlT3BlbiAnICsgc1snY2xhc3MnXX0pOwoJCQloICs9ICc8dGQ+JyArIERPTS5jcmVhdGVIVE1MKCdhJywge2lkIDogdC5pZCArICdfb3BlbicsIGhyZWYgOiAnamF2YXNjcmlwdDo7JywgJ2NsYXNzJyA6ICdtY2VPcGVuICcgKyBzWydjbGFzcyddLCBvbmNsaWNrIDogInJldHVybiBmYWxzZTsiLCBvbm1vdXNlZG93biA6ICdyZXR1cm4gZmFsc2U7JywgdGl0bGUgOiBzLnRpdGxlfSwgaDEpICsgJzwvdGQ+JzsKCgkJCWggKz0gJzwvdHI+PC90Ym9keT4nOwoKCQkJcmV0dXJuIERPTS5jcmVhdGVIVE1MKCd0YWJsZScsIHtpZCA6IHQuaWQsICdjbGFzcycgOiAnbWNlU3BsaXRCdXR0b24gbWNlU3BsaXRCdXR0b25FbmFibGVkICcgKyBzWydjbGFzcyddLCBjZWxscGFkZGluZyA6ICcwJywgY2VsbHNwYWNpbmcgOiAnMCcsIG9ubW91c2Vkb3duIDogJ3JldHVybiBmYWxzZTsnLCB0aXRsZSA6IHMudGl0bGV9LCBoKTsKCQl9LAoKCQlwb3N0UmVuZGVyIDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpcywgcyA9IHQuc2V0dGluZ3M7CgoJCQlpZiAocy5vbmNsaWNrKSB7CgkJCQlFdmVudC5hZGQodC5pZCArICdfYWN0aW9uJywgJ2NsaWNrJywgZnVuY3Rpb24oKSB7CgkJCQkJaWYgKCF0LmlzRGlzYWJsZWQoKSkKCQkJCQkJcy5vbmNsaWNrKHQudmFsdWUpOwoJCQkJfSk7CgkJCX0KCgkJCUV2ZW50LmFkZCh0LmlkICsgJ19vcGVuJywgJ2NsaWNrJywgdC5zaG93TWVudSwgdCk7CgkJCUV2ZW50LmFkZCh0LmlkICsgJ19vcGVuJywgJ2ZvY3VzJywgZnVuY3Rpb24oKSB7dC5fZm9jdXNlZCA9IDE7fSk7CgkJCUV2ZW50LmFkZCh0LmlkICsgJ19vcGVuJywgJ2JsdXInLCBmdW5jdGlvbigpIHt0Ll9mb2N1c2VkID0gMDt9KTsKCgkJCS8vIE9sZCBJRSBkb2Vzbid0IGhhdmUgaG92ZXIgb24gYWxsIGVsZW1lbnRzCgkJCWlmICh0aW55bWNlLmlzSUU2IHx8ICFET00uYm94TW9kZWwpIHsKCQkJCUV2ZW50LmFkZCh0LmlkLCAnbW91c2VvdmVyJywgZnVuY3Rpb24oKSB7CgkJCQkJaWYgKCFET00uaGFzQ2xhc3ModC5pZCwgJ21jZVNwbGl0QnV0dG9uRGlzYWJsZWQnKSkKCQkJCQkJRE9NLmFkZENsYXNzKHQuaWQsICdtY2VTcGxpdEJ1dHRvbkhvdmVyJyk7CgkJCQl9KTsKCgkJCQlFdmVudC5hZGQodC5pZCwgJ21vdXNlb3V0JywgZnVuY3Rpb24oKSB7CgkJCQkJaWYgKCFET00uaGFzQ2xhc3ModC5pZCwgJ21jZVNwbGl0QnV0dG9uRGlzYWJsZWQnKSkKCQkJCQkJRE9NLnJlbW92ZUNsYXNzKHQuaWQsICdtY2VTcGxpdEJ1dHRvbkhvdmVyJyk7CgkJCQl9KTsKCQkJfQoJCX0sCgoJCWRlc3Ryb3kgOiBmdW5jdGlvbigpIHsKCQkJdGhpcy5wYXJlbnQoKTsKCgkJCUV2ZW50LmNsZWFyKHRoaXMuaWQgKyAnX2FjdGlvbicpOwoJCQlFdmVudC5jbGVhcih0aGlzLmlkICsgJ19vcGVuJyk7CgkJfQoKCQl9KTsKfSkodGlueW1jZSk7CihmdW5jdGlvbih0aW55bWNlKSB7Cgl2YXIgRE9NID0gdGlueW1jZS5ET00sIEV2ZW50ID0gdGlueW1jZS5kb20uRXZlbnQsIGlzID0gdGlueW1jZS5pcywgZWFjaCA9IHRpbnltY2UuZWFjaDsKCgl0aW55bWNlLmNyZWF0ZSgndGlueW1jZS51aS5Db2xvclNwbGl0QnV0dG9uOnRpbnltY2UudWkuU3BsaXRCdXR0b24nLCB7CgkJQ29sb3JTcGxpdEJ1dHRvbiA6IGZ1bmN0aW9uKGlkLCBzKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXQucGFyZW50KGlkLCBzKTsKCgkJCXQuc2V0dGluZ3MgPSBzID0gdGlueW1jZS5leHRlbmQoewoJCQkJY29sb3JzIDogJzAwMDAwMCw5OTMzMDAsMzMzMzAwLDAwMzMwMCwwMDMzNjYsMDAwMDgwLDMzMzM5OSwzMzMzMzMsODAwMDAwLEZGNjYwMCw4MDgwMDAsMDA4MDAwLDAwODA4MCwwMDAwRkYsNjY2Njk5LDgwODA4MCxGRjAwMDAsRkY5OTAwLDk5Q0MwMCwzMzk5NjYsMzNDQ0NDLDMzNjZGRiw4MDAwODAsOTk5OTk5LEZGMDBGRixGRkNDMDAsRkZGRjAwLDAwRkYwMCwwMEZGRkYsMDBDQ0ZGLDk5MzM2NixDMEMwQzAsRkY5OUNDLEZGQ0M5OSxGRkZGOTksQ0NGRkNDLENDRkZGRiw5OUNDRkYsQ0M5OUZGLEZGRkZGRicsCgkJCQlncmlkX3dpZHRoIDogOCwKCQkJCWRlZmF1bHRfY29sb3IgOiAnIzg4ODg4OCcKCQkJfSwgdC5zZXR0aW5ncyk7CgoJCQl0Lm9uU2hvd01lbnUgPSBuZXcgdGlueW1jZS51dGlsLkRpc3BhdGNoZXIodCk7CgkJCXQub25IaWRlTWVudSA9IG5ldyB0aW55bWNlLnV0aWwuRGlzcGF0Y2hlcih0KTsKCgkJCXQudmFsdWUgPSBzLmRlZmF1bHRfY29sb3I7CgkJfSwKCgkJc2hvd01lbnUgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCByLCBwLCBlLCBwMjsKCgkJCWlmICh0LmlzRGlzYWJsZWQoKSkKCQkJCXJldHVybjsKCgkJCWlmICghdC5pc01lbnVSZW5kZXJlZCkgewoJCQkJdC5yZW5kZXJNZW51KCk7CgkJCQl0LmlzTWVudVJlbmRlcmVkID0gdHJ1ZTsKCQkJfQoKCQkJaWYgKHQuaXNNZW51VmlzaWJsZSkKCQkJCXJldHVybiB0LmhpZGVNZW51KCk7CgoJCQllID0gRE9NLmdldCh0LmlkKTsKCQkJRE9NLnNob3codC5pZCArICdfbWVudScpOwoJCQlET00uYWRkQ2xhc3MoZSwgJ21jZVNwbGl0QnV0dG9uU2VsZWN0ZWQnKTsKCQkJcDIgPSBET00uZ2V0UG9zKGUpOwoJCQlET00uc2V0U3R5bGVzKHQuaWQgKyAnX21lbnUnLCB7CgkJCQlsZWZ0IDogcDIueCwKCQkJCXRvcCA6IHAyLnkgKyBlLmNsaWVudEhlaWdodCwKCQkJCXpJbmRleCA6IDIwMDAwMAoJCQl9KTsKCQkJZSA9IDA7CgoJCQlFdmVudC5hZGQoRE9NLmRvYywgJ21vdXNlZG93bicsIHQuaGlkZU1lbnUsIHQpOwoJCQl0Lm9uU2hvd01lbnUuZGlzcGF0Y2godCk7CgoJCQlpZiAodC5fZm9jdXNlZCkgewoJCQkJdC5fa2V5SGFuZGxlciA9IEV2ZW50LmFkZCh0LmlkICsgJ19tZW51JywgJ2tleWRvd24nLCBmdW5jdGlvbihlKSB7CgkJCQkJaWYgKGUua2V5Q29kZSA9PSAyNykKCQkJCQkJdC5oaWRlTWVudSgpOwoJCQkJfSk7CgoJCQkJRE9NLnNlbGVjdCgnYScsIHQuaWQgKyAnX21lbnUnKVswXS5mb2N1cygpOyAvLyBTZWxlY3QgZmlyc3QgbGluawoJCQl9CgoJCQl0LmlzTWVudVZpc2libGUgPSAxOwoJCX0sCgoJCWhpZGVNZW51IDogZnVuY3Rpb24oZSkgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQkvLyBQcmV2ZW50IGRvdWJsZSB0b29nbGVzIGJ5IGNhbmNlbGluZyB0aGUgbW91c2UgY2xpY2sgZXZlbnQgdG8gdGhlIGJ1dHRvbgoJCQlpZiAoZSAmJiBlLnR5cGUgPT0gIm1vdXNlZG93biIgJiYgRE9NLmdldFBhcmVudChlLnRhcmdldCwgZnVuY3Rpb24oZSkge3JldHVybiBlLmlkID09PSB0LmlkICsgJ19vcGVuJzt9KSkKCQkJCXJldHVybjsKCgkJCWlmICghZSB8fCAhRE9NLmdldFBhcmVudChlLnRhcmdldCwgJy5tY2VTcGxpdEJ1dHRvbk1lbnUnKSkgewoJCQkJRE9NLnJlbW92ZUNsYXNzKHQuaWQsICdtY2VTcGxpdEJ1dHRvblNlbGVjdGVkJyk7CgkJCQlFdmVudC5yZW1vdmUoRE9NLmRvYywgJ21vdXNlZG93bicsIHQuaGlkZU1lbnUsIHQpOwoJCQkJRXZlbnQucmVtb3ZlKHQuaWQgKyAnX21lbnUnLCAna2V5ZG93bicsIHQuX2tleUhhbmRsZXIpOwoJCQkJRE9NLmhpZGUodC5pZCArICdfbWVudScpOwoJCQl9CgoJCQl0Lm9uSGlkZU1lbnUuZGlzcGF0Y2godCk7CgoJCQl0LmlzTWVudVZpc2libGUgPSAwOwoJCX0sCgoJCXJlbmRlck1lbnUgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCBtLCBpID0gMCwgcyA9IHQuc2V0dGluZ3MsIG4sIHRiLCB0ciwgdzsKCgkJCXcgPSBET00uYWRkKHMubWVudV9jb250YWluZXIsICdkaXYnLCB7aWQgOiB0LmlkICsgJ19tZW51JywgJ2NsYXNzJyA6IHNbJ21lbnVfY2xhc3MnXSArICcgJyArIHNbJ2NsYXNzJ10sIHN0eWxlIDogJ3Bvc2l0aW9uOmFic29sdXRlO2xlZnQ6MDt0b3A6LTEwMDBweDsnfSk7CgkJCW0gPSBET00uYWRkKHcsICdkaXYnLCB7J2NsYXNzJyA6IHNbJ2NsYXNzJ10gKyAnIG1jZVNwbGl0QnV0dG9uTWVudSd9KTsKCQkJRE9NLmFkZChtLCAnc3BhbicsIHsnY2xhc3MnIDogJ21jZU1lbnVMaW5lJ30pOwoKCQkJbiA9IERPTS5hZGQobSwgJ3RhYmxlJywgeydjbGFzcycgOiAnbWNlQ29sb3JTcGxpdE1lbnUnfSk7CgkJCXRiID0gRE9NLmFkZChuLCAndGJvZHknKTsKCgkJCS8vIEdlbmVyYXRlIGNvbG9yIGdyaWQKCQkJaSA9IDA7CgkJCWVhY2goaXMocy5jb2xvcnMsICdhcnJheScpID8gcy5jb2xvcnMgOiBzLmNvbG9ycy5zcGxpdCgnLCcpLCBmdW5jdGlvbihjKSB7CgkJCQljID0gYy5yZXBsYWNlKC9eIy8sICcnKTsKCgkJCQlpZiAoIWktLSkgewoJCQkJCXRyID0gRE9NLmFkZCh0YiwgJ3RyJyk7CgkJCQkJaSA9IHMuZ3JpZF93aWR0aCAtIDE7CgkJCQl9CgoJCQkJbiA9IERPTS5hZGQodHIsICd0ZCcpOwoKCQkJCW4gPSBET00uYWRkKG4sICdhJywgewoJCQkJCWhyZWYgOiAnamF2YXNjcmlwdDo7JywKCQkJCQlzdHlsZSA6IHsKCQkJCQkJYmFja2dyb3VuZENvbG9yIDogJyMnICsgYwoJCQkJCX0sCgkJCQkJbWNlX2NvbG9yIDogJyMnICsgYwoJCQkJfSk7CgkJCX0pOwoKCQkJaWYgKHMubW9yZV9jb2xvcnNfZnVuYykgewoJCQkJbiA9IERPTS5hZGQodGIsICd0cicpOwoJCQkJbiA9IERPTS5hZGQobiwgJ3RkJywge2NvbHNwYW4gOiBzLmdyaWRfd2lkdGgsICdjbGFzcycgOiAnbWNlTW9yZUNvbG9ycyd9KTsKCQkJCW4gPSBET00uYWRkKG4sICdhJywge2lkIDogdC5pZCArICdfbW9yZScsIGhyZWYgOiAnamF2YXNjcmlwdDo7Jywgb25jbGljayA6ICdyZXR1cm4gZmFsc2U7JywgJ2NsYXNzJyA6ICdtY2VNb3JlQ29sb3JzJ30sIHMubW9yZV9jb2xvcnNfdGl0bGUpOwoKCQkJCUV2ZW50LmFkZChuLCAnY2xpY2snLCBmdW5jdGlvbihlKSB7CgkJCQkJcy5tb3JlX2NvbG9yc19mdW5jLmNhbGwocy5tb3JlX2NvbG9yc19zY29wZSB8fCB0aGlzKTsKCQkJCQlyZXR1cm4gRXZlbnQuY2FuY2VsKGUpOyAvLyBDYW5jZWwgdG8gZml4IG9uYmVmb3JldW5sb2FkIHByb2JsZW0KCQkJCX0pOwoJCQl9CgoJCQlET00uYWRkQ2xhc3MobSwgJ21jZUNvbG9yU3BsaXRNZW51Jyk7CgoJCQlFdmVudC5hZGQodC5pZCArICdfbWVudScsICdjbGljaycsIGZ1bmN0aW9uKGUpIHsKCQkJCXZhciBjOwoKCQkJCWUgPSBlLnRhcmdldDsKCgkJCQlpZiAoZS5ub2RlTmFtZSA9PSAnQScgJiYgKGMgPSBlLmdldEF0dHJpYnV0ZSgnbWNlX2NvbG9yJykpKQoJCQkJCXQuc2V0Q29sb3IoYyk7CgoJCQkJcmV0dXJuIEV2ZW50LmNhbmNlbChlKTsgLy8gUHJldmVudCBJRSBhdXRvIHNhdmUgd2FybmluZwoJCQl9KTsKCgkJCXJldHVybiB3OwoJCX0sCgoJCXNldENvbG9yIDogZnVuY3Rpb24oYykgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQlET00uc2V0U3R5bGUodC5pZCArICdfcHJldmlldycsICdiYWNrZ3JvdW5kQ29sb3InLCBjKTsKCgkJCXQudmFsdWUgPSBjOwoJCQl0LmhpZGVNZW51KCk7CgkJCXQuc2V0dGluZ3Mub25zZWxlY3QoYyk7CgkJfSwKCgkJcG9zdFJlbmRlciA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXMsIGlkID0gdC5pZDsKCgkJCXQucGFyZW50KCk7CgkJCURPTS5hZGQoaWQgKyAnX2FjdGlvbicsICdkaXYnLCB7aWQgOiBpZCArICdfcHJldmlldycsICdjbGFzcycgOiAnbWNlQ29sb3JQcmV2aWV3J30pOwoJCQlET00uc2V0U3R5bGUodC5pZCArICdfcHJldmlldycsICdiYWNrZ3JvdW5kQ29sb3InLCB0LnZhbHVlKTsKCQl9LAoKCQlkZXN0cm95IDogZnVuY3Rpb24oKSB7CgkJCXRoaXMucGFyZW50KCk7CgoJCQlFdmVudC5jbGVhcih0aGlzLmlkICsgJ19tZW51Jyk7CgkJCUV2ZW50LmNsZWFyKHRoaXMuaWQgKyAnX21vcmUnKTsKCQkJRE9NLnJlbW92ZSh0aGlzLmlkICsgJ19tZW51Jyk7CgkJfQoKCQl9KTsKfSkodGlueW1jZSk7CnRpbnltY2UuY3JlYXRlKCd0aW55bWNlLnVpLlRvb2xiYXI6dGlueW1jZS51aS5Db250YWluZXInLCB7CglyZW5kZXJIVE1MIDogZnVuY3Rpb24oKSB7CgkJdmFyIHQgPSB0aGlzLCBoID0gJycsIGMsIGNvLCBkb20gPSB0aW55bWNlLkRPTSwgcyA9IHQuc2V0dGluZ3MsIGksIHByLCBueCwgY2w7CgoJCWNsID0gdC5jb250cm9sczsKCQlmb3IgKGk9MDsgaTxjbC5sZW5ndGg7IGkrKykgewoJCQkvLyBHZXQgY3VycmVudCBjb250cm9sLCBwcmV2IGNvbnRyb2wsIG5leHQgY29udHJvbCBhbmQgaWYgdGhlIGNvbnRyb2wgaXMgYSBsaXN0IGJveCBvciBub3QKCQkJY28gPSBjbFtpXTsKCQkJcHIgPSBjbFtpIC0gMV07CgkJCW54ID0gY2xbaSArIDFdOwoKCQkJLy8gQWRkIHRvb2xiYXIgc3RhcnQKCQkJaWYgKGkgPT09IDApIHsKCQkJCWMgPSAnbWNlVG9vbGJhclN0YXJ0JzsKCgkJCQlpZiAoY28uQnV0dG9uKQoJCQkJCWMgKz0gJyBtY2VUb29sYmFyU3RhcnRCdXR0b24nOwoJCQkJZWxzZSBpZiAoY28uU3BsaXRCdXR0b24pCgkJCQkJYyArPSAnIG1jZVRvb2xiYXJTdGFydFNwbGl0QnV0dG9uJzsKCQkJCWVsc2UgaWYgKGNvLkxpc3RCb3gpCgkJCQkJYyArPSAnIG1jZVRvb2xiYXJTdGFydExpc3RCb3gnOwoKCQkJCWggKz0gZG9tLmNyZWF0ZUhUTUwoJ3RkJywgeydjbGFzcycgOiBjfSwgZG9tLmNyZWF0ZUhUTUwoJ3NwYW4nLCBudWxsLCAnPCEtLSBJRSAtLT4nKSk7CgkJCX0KCgkJCS8vIEFkZCB0b29sYmFyIGVuZCBiZWZvcmUgbGlzdCBib3ggYW5kIGFmdGVyIHRoZSBwcmV2aW91cyBidXR0b24KCQkJLy8gVGhpcyBpcyB0byBmaXggdGhlIG8yazcgZWRpdG9yIHNraW5zCgkJCWlmIChwciAmJiBjby5MaXN0Qm94KSB7CgkJCQlpZiAocHIuQnV0dG9uIHx8IHByLlNwbGl0QnV0dG9uKQoJCQkJCWggKz0gZG9tLmNyZWF0ZUhUTUwoJ3RkJywgeydjbGFzcycgOiAnbWNlVG9vbGJhckVuZCd9LCBkb20uY3JlYXRlSFRNTCgnc3BhbicsIG51bGwsICc8IS0tIElFIC0tPicpKTsKCQkJfQoKCQkJLy8gUmVuZGVyIGNvbnRyb2wgSFRNTAoKCQkJLy8gSUUgOCBxdWljayBmaXgsIG5lZWRlZCB0byBwcm9wZXJ0bHkgZ2VuZXJhdGUgYSBoaXQgYXJlYSBmb3IgYW5jaG9ycwoJCQlpZiAoZG9tLnN0ZE1vZGUpCgkJCQloICs9ICc8dGQgc3R5bGU9InBvc2l0aW9uOiByZWxhdGl2ZSI+JyArIGNvLnJlbmRlckhUTUwoKSArICc8L3RkPic7CgkJCWVsc2UKCQkJCWggKz0gJzx0ZD4nICsgY28ucmVuZGVySFRNTCgpICsgJzwvdGQ+JzsKCgkJCS8vIEFkZCB0b29sYmFyIHN0YXJ0IGFmdGVyIGxpc3QgYm94IGFuZCBiZWZvcmUgdGhlIG5leHQgYnV0dG9uCgkJCS8vIFRoaXMgaXMgdG8gZml4IHRoZSBvMms3IGVkaXRvciBza2lucwoJCQlpZiAobnggJiYgY28uTGlzdEJveCkgewoJCQkJaWYgKG54LkJ1dHRvbiB8fCBueC5TcGxpdEJ1dHRvbikKCQkJCQloICs9IGRvbS5jcmVhdGVIVE1MKCd0ZCcsIHsnY2xhc3MnIDogJ21jZVRvb2xiYXJTdGFydCd9LCBkb20uY3JlYXRlSFRNTCgnc3BhbicsIG51bGwsICc8IS0tIElFIC0tPicpKTsKCQkJfQoJCX0KCgkJYyA9ICdtY2VUb29sYmFyRW5kJzsKCgkJaWYgKGNvLkJ1dHRvbikKCQkJYyArPSAnIG1jZVRvb2xiYXJFbmRCdXR0b24nOwoJCWVsc2UgaWYgKGNvLlNwbGl0QnV0dG9uKQoJCQljICs9ICcgbWNlVG9vbGJhckVuZFNwbGl0QnV0dG9uJzsKCQllbHNlIGlmIChjby5MaXN0Qm94KQoJCQljICs9ICcgbWNlVG9vbGJhckVuZExpc3RCb3gnOwoKCQloICs9IGRvbS5jcmVhdGVIVE1MKCd0ZCcsIHsnY2xhc3MnIDogY30sIGRvbS5jcmVhdGVIVE1MKCdzcGFuJywgbnVsbCwgJzwhLS0gSUUgLS0+JykpOwoKCQlyZXR1cm4gZG9tLmNyZWF0ZUhUTUwoJ3RhYmxlJywge2lkIDogdC5pZCwgJ2NsYXNzJyA6ICdtY2VUb29sYmFyJyArIChzWydjbGFzcyddID8gJyAnICsgc1snY2xhc3MnXSA6ICcnKSwgY2VsbHBhZGRpbmcgOiAnMCcsIGNlbGxzcGFjaW5nIDogJzAnLCBhbGlnbiA6IHQuc2V0dGluZ3MuYWxpZ24gfHwgJyd9LCAnPHRib2R5Pjx0cj4nICsgaCArICc8L3RyPjwvdGJvZHk+Jyk7Cgl9CgoJfSk7CihmdW5jdGlvbih0aW55bWNlKSB7Cgl2YXIgRGlzcGF0Y2hlciA9IHRpbnltY2UudXRpbC5EaXNwYXRjaGVyLCBlYWNoID0gdGlueW1jZS5lYWNoOwoKCXRpbnltY2UuY3JlYXRlKCd0aW55bWNlLkFkZE9uTWFuYWdlcicsIHsKCQlpdGVtcyA6IFtdLAoJCXVybHMgOiB7fSwKCQlsb29rdXAgOiB7fSwKCQlvbkFkZCA6IG5ldyBEaXNwYXRjaGVyKHRoaXMpLAoKCQlnZXQgOiBmdW5jdGlvbihuKSB7CgkJCXJldHVybiB0aGlzLmxvb2t1cFtuXTsKCQl9LAoKCQlyZXF1aXJlTGFuZ1BhY2sgOiBmdW5jdGlvbihuKSB7CgkJCXZhciB1LCBzID0gdGlueW1jZS5FZGl0b3JNYW5hZ2VyLnNldHRpbmdzOwoKCQkJaWYgKHMgJiYgcy5sYW5ndWFnZSkgewoJCQkJdSA9IHRoaXMudXJsc1tuXSArICcvbGFuZ3MvJyArIHMubGFuZ3VhZ2UgKyAnLmpzJzsKCgkJCQlpZiAoIXRpbnltY2UuZG9tLkV2ZW50LmRvbUxvYWRlZCAmJiAhcy5zdHJpY3RfbW9kZSkKCQkJCQl0aW55bWNlLlNjcmlwdExvYWRlci5sb2FkKHUpOwoJCQkJZWxzZQoJCQkJCXRpbnltY2UuU2NyaXB0TG9hZGVyLmFkZCh1KTsKCQkJfQoJCX0sCgoJCWFkZCA6IGZ1bmN0aW9uKGlkLCBvKSB7CgkJCXRoaXMuaXRlbXMucHVzaChvKTsKCQkJdGhpcy5sb29rdXBbaWRdID0gbzsKCQkJdGhpcy5vbkFkZC5kaXNwYXRjaCh0aGlzLCBpZCwgbyk7CgoJCQlyZXR1cm4gbzsKCQl9LAoKCQlsb2FkIDogZnVuY3Rpb24obiwgdSwgY2IsIHMpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJaWYgKHQudXJsc1tuXSkKCQkJCXJldHVybjsKCgkJCWlmICh1LmluZGV4T2YoJy8nKSAhPSAwICYmIHUuaW5kZXhPZignOi8vJykgPT0gLTEpCgkJCQl1ID0gdGlueW1jZS5iYXNlVVJMICsgJy8nICsgIHU7CgoJCQl0LnVybHNbbl0gPSB1LnN1YnN0cmluZygwLCB1Lmxhc3RJbmRleE9mKCcvJykpOwogICAgICAgICAgICAvLyBBVExBU1NJQU4gLSBXZSBsb2FkIHRoZSBzY3JpcHRzIHZpYSByZXF1aXJlUmVzb3VyY2VzCiAgICAgICAgICAgIC8vdGlueW1jZS5TY3JpcHRMb2FkZXIuYWRkKHUsIGNiLCBzKTsKICAgICAgICAgICAgQUpTLmxvZygiU2NyaXB0IGZvciBbIiArIG4gKyAiXSB3aWxsIG5vdCBiZSBsb2FkZWQgYnkgVGlueU1DRS4gUGxlYXNlIHVzZSBBdGxhc3NpYW4ncyByZXF1aXJlUmVzb3VyY2UuIik7CiAgICAgICAgfQoKCQl9KTsKCgkvLyBDcmVhdGUgcGx1Z2luIGFuZCB0aGVtZSBtYW5hZ2VycwoJdGlueW1jZS5QbHVnaW5NYW5hZ2VyID0gbmV3IHRpbnltY2UuQWRkT25NYW5hZ2VyKCk7Cgl0aW55bWNlLlRoZW1lTWFuYWdlciA9IG5ldyB0aW55bWNlLkFkZE9uTWFuYWdlcigpOwp9KHRpbnltY2UpKTsoZnVuY3Rpb24odGlueW1jZSkgewoJLy8gU2hvcnRlbiBuYW1lcwoJdmFyIGVhY2ggPSB0aW55bWNlLmVhY2gsIGV4dGVuZCA9IHRpbnltY2UuZXh0ZW5kLCBET00gPSB0aW55bWNlLkRPTSwgRXZlbnQgPSB0aW55bWNlLmRvbS5FdmVudCwgVGhlbWVNYW5hZ2VyID0gdGlueW1jZS5UaGVtZU1hbmFnZXIsIFBsdWdpbk1hbmFnZXIgPSB0aW55bWNlLlBsdWdpbk1hbmFnZXIsIGV4cGxvZGUgPSB0aW55bWNlLmV4cGxvZGU7CgoJdGlueW1jZS5jcmVhdGUoJ3N0YXRpYyB0aW55bWNlLkVkaXRvck1hbmFnZXInLCB7CgkJZWRpdG9ycyA6IHt9LAoJCWkxOG4gOiB7fSwKCQlhY3RpdmVFZGl0b3IgOiBudWxsLAoKCQlwcmVJbml0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIEFKUy5sb2coIkVkaXRvck1hbmFnZXIucHJlSW5pdCIpOwoJCQl2YXIgdCA9IHRoaXMsIGxvID0gd2luZG93LmxvY2F0aW9uOwoKICAgICAgICAgICAgLy9BVExBU1NJQU4gLSBVc2UgdGhlIFRpbnlNQ0UgcGx1Z2luIHVybCBhcyB0aGUgZG9jdW1lbnQgYmFzZQoJCQkvLyBTZXR1cCBzb21lIFVSTHMgd2hlcmUgdGhlIGVkaXRvciBBUEkgaXMgbG9jYXRlZCBhbmQgd2hlcmUgdGhlIGRvY3VtZW50IGlzCgkJCXRpbnltY2UuZG9jdW1lbnRCYXNlVVJMID0gIHRpbnltY2UuYmFzZVVSTDsKCQkJQUpTLmxvZygidGlueW1jZS5kb2N1bWVudEJhc2VVUkwgPSAiICsgdGlueW1jZS5kb2N1bWVudEJhc2VVUkwpOwoJCQlpZiAoIS9bXC9cXF0kLy50ZXN0KHRpbnltY2UuZG9jdW1lbnRCYXNlVVJMKSkKCQkJCXRpbnltY2UuZG9jdW1lbnRCYXNlVVJMICs9ICcvJzsKCiAgICAgICAgICAgIHZhciBwYXJ0cyA9IHRpbnltY2UuZG9jdW1lbnRCYXNlVVJMLm1hdGNoKC8oLiopXC9zXC8uKlwvXyhcL1teXD9dKikuKi8pOwogICAgICAgICAgICBpZiAocGFydHMubGVuZ3RoID09IDMpIHsgLy8gd2UgcmVtb3ZlIHRoZSBjYWNoaW5nIHBhcnQgb2YgdGhlIHVybAogICAgICAgICAgICAgICAgdGlueW1jZS5kb2N1bWVudEJhc2VVUkwgPSBwYXJ0c1sxXSArIHBhcnRzWzJdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEFKUy5sb2coIkVkaXRvck1hbmFnZXIucHJlSW5pdCB0aW55bWNlLmRvY3VtZW50QmFzZVVSTD0iICsgdGlueW1jZS5kb2N1bWVudEJhc2VVUkwpOwoKCQkJdGlueW1jZS5iYXNlVVJMID0gbmV3IHRpbnltY2UudXRpbC5VUkkodGlueW1jZS5kb2N1bWVudEJhc2VVUkwpLnRvQWJzb2x1dGUodGlueW1jZS5iYXNlVVJMKTsKCQkJdGlueW1jZS5FZGl0b3JNYW5hZ2VyLmJhc2VVUkkgPSBuZXcgdGlueW1jZS51dGlsLlVSSSh0aW55bWNlLmJhc2VVUkwpOwoKCQkJLy8gQWRkIGJlZm9yZSB1bmxvYWQgbGlzdGVuZXIKCQkJLy8gVGhpcyB3YXMgcmVxdWlyZWQgc2luY2UgSUUgd2FzIGxlYWtpbmcgbWVtb3J5IGlmIHlvdSBhZGRlZCBhbmQgcmVtb3ZlZCBiZWZvcmV1bmxvYWQgbGlzdGVuZXJzCgkJCS8vIHdpdGggYXR0YWNoRXZlbnQvZGV0YXRjaEV2ZW50IHNvIHRoaXMgb25seSBhZGRzIG9uZSBsaXN0ZW5lciBhbmQgaW5zdGFuY2VzIGNhbiB0aGUgYXR0YWNoIHRvIHRoZSBvbkJlZm9yZVVubG9hZCBldmVudAoJCQl0Lm9uQmVmb3JlVW5sb2FkID0gbmV3IHRpbnltY2UudXRpbC5EaXNwYXRjaGVyKHQpOwoKCQkJLy8gTXVzdCBiZSBvbiB3aW5kb3cgb3IgSUUgd2lsbCBsZWFrIGlmIHRoZSBlZGl0b3IgaXMgcGxhY2VkIGluIGZyYW1lIG9yIGlmcmFtZQoJCQlFdmVudC5hZGQod2luZG93LCAnYmVmb3JldW5sb2FkJywgZnVuY3Rpb24oZSkgewoJCQkJdC5vbkJlZm9yZVVubG9hZC5kaXNwYXRjaCh0LCBlKTsKCQkJfSk7CgkJfSwKCgkJaW5pdCA6IGZ1bmN0aW9uKHMpIHsKICAgICAgICAgICAgQUpTLmxvZygiaHR0cDovLzEwLjIwLjE2MC4xOTgvd2lraS9zL2VuLzIxNjYvMzQvMy41LjkvXy9kb3dubG9hZC9iYXRjaC9jb20uYXRsYXNzaWFuLmNvbmZsdWVuY2UudGlueW1jZXBsdWdpbjplZGl0b3ItcmVzb3VyY2VzL0VkaXRvck1hbmFnZXIuaW5pdCIpOwoJCQl2YXIgdCA9IHRoaXMsIHBsLCBzbCA9IHRpbnltY2UuU2NyaXB0TG9hZGVyLCBjLCBlLCBlbCA9IFtdLCBlZDsKCgkJCWZ1bmN0aW9uIGV4ZWNDYWxsYmFjayhzZSwgbiwgcykgewoJCQkJdmFyIGYgPSBzZVtuXTsKCgkJCQlpZiAoIWYpCgkJCQkJcmV0dXJuOwoKCQkJCWlmICh0aW55bWNlLmlzKGYsICdzdHJpbmcnKSkgewoJCQkJCXMgPSBmLnJlcGxhY2UoL1wuXHcrJC8sICcnKTsKCQkJCQlzID0gcyA/IHRpbnltY2UucmVzb2x2ZShzKSA6IDA7CgkJCQkJZiA9IHRpbnltY2UucmVzb2x2ZShmKTsKCQkJCX0KCgkJCQlyZXR1cm4gZi5hcHBseShzIHx8IHRoaXMsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMikpOwoJCQl9OwoKCQkJcyA9IGV4dGVuZCh7CgkJCQl0aGVtZSA6ICJzaW1wbGUiLAoJCQkJbGFuZ3VhZ2UgOiAiZW4iLAoJCQkJc3RyaWN0X2xvYWRpbmdfbW9kZSA6IGRvY3VtZW50LmNvbnRlbnRUeXBlID09ICdhcHBsaWNhdGlvbi94aHRtbCt4bWwnCgkJCX0sIHMpOwoKCQkJdC5zZXR0aW5ncyA9IHM7CgogICAgICAgICAgICAvLyBBVExBU1NJQU4gLSBObyBuZWVkIHRvIGxvYWQgYW55IHNjcmlwdHMsIGFsbCBsb2FkZWQgdmlhICNyZXF1aXJlUmVzb3VyY2UKCiAgICAgICAgICAgIC8vIEFUTEFTU0lBTiAtIEluIHRpbnlNQ0UgdGhlIGZvbGxvd2luZyBibG9jayBpcyBhZGRlZCBhcyBhbiBvbkluaXQgZXZlbnQgZm9yICJsZWdhY3kiIHJlYXNvbnMgdGhhdCBkb24ndAogICAgICAgICAgICAvLyBhcHBseSB0byB1cywgc28gd2UganVzdCBleGVjdXRlIGl0LgogICAgICAgICAgICB7CgkJCQl2YXIgbCwgY287CgoJCQkJZXhlY0NhbGxiYWNrKHMsICdvbnBhZ2Vsb2FkJyk7CgoJCQkJLy8gVmVyaWZ5IHRoYXQgaXQncyBhIHZhbGlkIGJyb3dzZXIKCQkJCWlmIChzLmJyb3dzZXJzKSB7CgkJCQkJbCA9IGZhbHNlOwoKCQkJCQllYWNoKGV4cGxvZGUocy5icm93c2VycyksIGZ1bmN0aW9uKHYpIHsKCQkJCQkJc3dpdGNoICh2KSB7CgkJCQkJCQljYXNlICdpZSc6CgkJCQkJCQljYXNlICdtc2llJzoKCQkJCQkJCQlpZiAodGlueW1jZS5pc0lFKQoJCQkJCQkJCQlsID0gdHJ1ZTsKCQkJCQkJCQlicmVhazsKCgkJCQkJCQljYXNlICdnZWNrbyc6CgkJCQkJCQkJaWYgKHRpbnltY2UuaXNHZWNrbykKCQkJCQkJCQkJbCA9IHRydWU7CgkJCQkJCQkJYnJlYWs7CgoJCQkJCQkJY2FzZSAnc2FmYXJpJzoKCQkJCQkJCWNhc2UgJ3dlYmtpdCc6CgkJCQkJCQkJaWYgKHRpbnltY2UuaXNXZWJLaXQpCgkJCQkJCQkJCWwgPSB0cnVlOwoJCQkJCQkJCWJyZWFrOwoKCQkJCQkJCWNhc2UgJ29wZXJhJzoKCQkJCQkJCQlpZiAodGlueW1jZS5pc09wZXJhKQoJCQkJCQkJCQlsID0gdHJ1ZTsKCgkJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9KTsKCgkJCQkJLy8gTm90IGEgdmFsaWQgb25lCgkJCQkJaWYgKCFsKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQoKCQkJCXN3aXRjaCAocy5tb2RlKSB7CgkJCQkJY2FzZSAiZXhhY3QiOgoJCQkJCQlsID0gcy5lbGVtZW50cyB8fCAnJzsKCgkJCQkJCWlmKGwubGVuZ3RoID4gMCkgewoJCQkJCQkJZWFjaChleHBsb2RlKGwpLCBmdW5jdGlvbih2KSB7CgkJCQkJCQkJaWYgKERPTS5nZXQodikpIHsKCQkJCQkJCQkJZWQgPSBuZXcgdGlueW1jZS5FZGl0b3Iodiwgcyk7CgkJCQkJCQkJCWVsLnB1c2goZWQpOwoJCQkJCQkJCQllZC5yZW5kZXIoMSk7CgkJCQkJCQkJfSBlbHNlIHsKCQkJCQkJCQkJYyA9IDA7CgoJCQkJCQkJCQllYWNoKGRvY3VtZW50LmZvcm1zLCBmdW5jdGlvbihmKSB7CgkJCQkJCQkJCQllYWNoKGYuZWxlbWVudHMsIGZ1bmN0aW9uKGUpIHsKCQkJCQkJCQkJCQlpZiAoZS5uYW1lID09PSB2KSB7CgkJCQkJCQkJCQkJCXYgPSAnbWNlX2VkaXRvcl8nICsgYzsKCQkJCQkJCQkJCQkJRE9NLnNldEF0dHJpYihlLCAnaWQnLCB2KTsKCgkJCQkJCQkJCQkJCWVkID0gbmV3IHRpbnltY2UuRWRpdG9yKHYsIHMpOwoJCQkJCQkJCQkJCQllbC5wdXNoKGVkKTsKCQkJCQkJCQkJCQkJZWQucmVuZGVyKDEpOwoJCQkJCQkJCQkJCX0KCQkJCQkJCQkJCX0pOwoJCQkJCQkJCQl9KTsKCQkJCQkJCQl9CgkJCQkJCQl9KTsKCQkJCQkJfQoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAidGV4dGFyZWFzIjoKCQkJCQljYXNlICJzcGVjaWZpY190ZXh0YXJlYXMiOgoJCQkJCQlmdW5jdGlvbiBoYXNDbGFzcyhuLCBjKSB7CgkJCQkJCQlyZXR1cm4gYy5jb25zdHJ1Y3RvciA9PT0gUmVnRXhwID8gYy50ZXN0KG4uY2xhc3NOYW1lKSA6IERPTS5oYXNDbGFzcyhuLCBjKTsKCQkJCQkJfTsKCgkJCQkJCWVhY2goRE9NLnNlbGVjdCgndGV4dGFyZWEnKSwgZnVuY3Rpb24odikgewoJCQkJCQkJaWYgKHMuZWRpdG9yX2Rlc2VsZWN0b3IgJiYgaGFzQ2xhc3Modiwgcy5lZGl0b3JfZGVzZWxlY3RvcikpCgkJCQkJCQkJcmV0dXJuOwoKCQkJCQkJCWlmICghcy5lZGl0b3Jfc2VsZWN0b3IgfHwgaGFzQ2xhc3Modiwgcy5lZGl0b3Jfc2VsZWN0b3IpKSB7CgkJCQkJCQkJLy8gQ2FuIHdlIHVzZSB0aGUgbmFtZQoJCQkJCQkJCWUgPSBET00uZ2V0KHYubmFtZSk7CgkJCQkJCQkJaWYgKCF2LmlkICYmICFlKQoJCQkJCQkJCQl2LmlkID0gdi5uYW1lOwoKCQkJCQkJCQkvLyBHZW5lcmF0ZSB1bmlxdWUgbmFtZSBpZiBtaXNzaW5nIG9yIGFscmVhZHkgZXhpc3RzCgkJCQkJCQkJaWYgKCF2LmlkIHx8IHQuZ2V0KHYuaWQpKQoJCQkJCQkJCQl2LmlkID0gRE9NLnVuaXF1ZUlkKCk7CgoJCQkJCQkJCWVkID0gbmV3IHRpbnltY2UuRWRpdG9yKHYuaWQsIHMpOwoJCQkJCQkJCWVsLnB1c2goZWQpOwoJCQkJCQkJCWVkLnJlbmRlcigxKTsKCQkJCQkJCX0KCQkJCQkJfSk7CgkJCQkJCWJyZWFrOwoJCQkJfQoKCQkJCS8vIENhbGwgb25Jbml0IHdoZW4gYWxsIGVkaXRvcnMgYXJlIGluaXRpYWxpemVkCgkJCQlpZiAocy5vbmluaXQpIHsKCQkJCQlsID0gY28gPSAwOwoKCQkJCQllYWNoIChlbCwgZnVuY3Rpb24oZWQpIHsKCQkJCQkJY28rKzsKCgkJCQkJCWlmICghZWQuaW5pdGlhbGl6ZWQpIHsKCQkJCQkJCS8vIFdhaXQgZm9yIGl0CgkJCQkJCQllZC5vbkluaXQuYWRkKGZ1bmN0aW9uKCkgewoJCQkJCQkJCWwrKzsKCgkJCQkJCQkJLy8gQWxsIGRvbmUKCQkJCQkJCQlpZiAobCA9PSBjbykKCQkJCQkJCQkJZXhlY0NhbGxiYWNrKHMsICdvbmluaXQnKTsKCQkJCQkJCX0pOwoJCQkJCQl9IGVsc2UKCQkJCQkJCWwrKzsKCgkJCQkJCS8vIEFsbCBkb25lCgkJCQkJCWlmIChsID09IGNvKQoJCQkJCQkJZXhlY0NhbGxiYWNrKHMsICdvbmluaXQnKTsKCQkJCQl9KTsKCQkJCX0KICAgICAgICAgICAgICAgIEFKUy5sb2coImZpbmlzaCBzLm9uaW5pdCIpOwogICAgICAgICAgICB9CgkJfSwKCgkJZ2V0IDogZnVuY3Rpb24oaWQpIHsKCQkJcmV0dXJuIHRoaXMuZWRpdG9yc1tpZF07CgkJfSwKCgkJZ2V0SW5zdGFuY2VCeUlkIDogZnVuY3Rpb24oaWQpIHsKCQkJcmV0dXJuIHRoaXMuZ2V0KGlkKTsKCQl9LAoKCQlhZGQgOiBmdW5jdGlvbihlKSB7CgkJCXRoaXMuZWRpdG9yc1tlLmlkXSA9IGU7CgkJCXRoaXMuX3NldEFjdGl2ZShlKTsKCgkJCXJldHVybiBlOwoJCX0sCgoJCXJlbW92ZSA6IGZ1bmN0aW9uKGUpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJLy8gTm90IGluIHRoZSBjb2xsZWN0aW9uCgkJCWlmICghdC5lZGl0b3JzW2UuaWRdKQoJCQkJcmV0dXJuIG51bGw7CgoJCQlkZWxldGUgdC5lZGl0b3JzW2UuaWRdOwoKCQkJLy8gU2VsZWN0IGFub3RoZXIgZWRpdG9yIHNpbmNlIHRoZSBhY3RpdmUgb25lIHdhcyByZW1vdmVkCgkJCWlmICh0LmFjdGl2ZUVkaXRvciA9PSBlKSB7CgkJCQl0Ll9zZXRBY3RpdmUobnVsbCk7CgoJCQkJZWFjaCh0LmVkaXRvcnMsIGZ1bmN0aW9uKGUpIHsKCQkJCQl0Ll9zZXRBY3RpdmUoZSk7CgkJCQkJcmV0dXJuIGZhbHNlOyAvLyBCcmVhawoJCQkJfSk7CgkJCX0KCgkJCWUuZGVzdHJveSgpOwoKCQkJcmV0dXJuIGU7CgkJfSwKCgkJZXhlY0NvbW1hbmQgOiBmdW5jdGlvbihjLCB1LCB2KSB7CgkJCXZhciB0ID0gdGhpcywgZWQgPSB0LmdldCh2KSwgdzsKCgkJCS8vIE1hbmFnZXIgY29tbWFuZHMKCQkJc3dpdGNoIChjKSB7CgkJCQljYXNlICJtY2VGb2N1cyI6CgkJCQkJZWQuZm9jdXMoKTsKCQkJCQlyZXR1cm4gdHJ1ZTsKCgkJCQljYXNlICJtY2VBZGRFZGl0b3IiOgoJCQkJY2FzZSAibWNlQWRkQ29udHJvbCI6CgkJCQkJaWYgKCF0LmdldCh2KSkKCQkJCQkJbmV3IHRpbnltY2UuRWRpdG9yKHYsIHQuc2V0dGluZ3MpLnJlbmRlcigpOwoKCQkJCQlyZXR1cm4gdHJ1ZTsKCgkJCQljYXNlICJtY2VBZGRGcmFtZUNvbnRyb2wiOgoJCQkJCXcgPSB2LndpbmRvdzsKCgkJCQkJLy8gQWRkIHRpbnlNQ0UgZ2xvYmFsIGluc3RhbmNlIGFuZCB0aW55bWNlIG5hbWVzcGFjZSB0byBzcGVjaWZpZWQgd2luZG93CgkJCQkJdy50aW55TUNFID0gdGlueU1DRTsKCQkJCQl3LnRpbnltY2UgPSB0aW55bWNlOwoKCQkJCQl0aW55bWNlLkRPTS5kb2MgPSB3LmRvY3VtZW50OwoJCQkJCXRpbnltY2UuRE9NLndpbiA9IHc7CgoJCQkJCWVkID0gbmV3IHRpbnltY2UuRWRpdG9yKHYuZWxlbWVudF9pZCwgdik7CgkJCQkJZWQucmVuZGVyKCk7CgoJCQkJCS8vIEZpeCBJRSBtZW1vcnkgbGVha3MKCQkJCQlpZiAodGlueW1jZS5pc0lFKSB7CgkJCQkJCWZ1bmN0aW9uIGNscigpIHsKCQkJCQkJCWVkLmRlc3Ryb3koKTsKCQkJCQkJCXcuZGV0YWNoRXZlbnQoJ29udW5sb2FkJywgY2xyKTsKCQkJCQkJCXcgPSB3LnRpbnlNQ0UgPSB3LnRpbnltY2UgPSBudWxsOyAvLyBJRSBsZWFrCgkJCQkJCX07CgoJCQkJCQl3LmF0dGFjaEV2ZW50KCdvbnVubG9hZCcsIGNscik7CgkJCQkJfQoKCQkJCQl2LnBhZ2Vfd2luZG93ID0gbnVsbDsKCgkJCQkJcmV0dXJuIHRydWU7CgoJCQkJY2FzZSAibWNlUmVtb3ZlRWRpdG9yIjoKCQkJCWNhc2UgIm1jZVJlbW92ZUNvbnRyb2wiOgoJCQkJCWlmIChlZCkKCQkJCQkJZWQucmVtb3ZlKCk7CgoJCQkJCXJldHVybiB0cnVlOwoKCQkJCWNhc2UgJ21jZVRvZ2dsZUVkaXRvcic6CgkJCQkJaWYgKCFlZCkgewoJCQkJCQl0LmV4ZWNDb21tYW5kKCdtY2VBZGRDb250cm9sJywgMCwgdik7CgkJCQkJCXJldHVybiB0cnVlOwoJCQkJCX0KCgkJCQkJaWYgKGVkLmlzSGlkZGVuKCkpCgkJCQkJCWVkLnNob3coKTsKCQkJCQllbHNlCgkJCQkJCWVkLmhpZGUoKTsKCgkJCQkJcmV0dXJuIHRydWU7CgkJCX0KCgkJCS8vIFJ1biBjb21tYW5kIG9uIGFjdGl2ZSBlZGl0b3IKCQkJaWYgKHQuYWN0aXZlRWRpdG9yKQoJCQkJcmV0dXJuIHQuYWN0aXZlRWRpdG9yLmV4ZWNDb21tYW5kKGMsIHUsIHYpOwoKCQkJcmV0dXJuIGZhbHNlOwoJCX0sCgoJCWV4ZWNJbnN0YW5jZUNvbW1hbmQgOiBmdW5jdGlvbihpZCwgYywgdSwgdikgewoJCQl2YXIgZWQgPSB0aGlzLmdldChpZCk7CgoJCQlpZiAoZWQpCgkJCQlyZXR1cm4gZWQuZXhlY0NvbW1hbmQoYywgdSwgdik7CgoJCQlyZXR1cm4gZmFsc2U7CgkJfSwKCgkJdHJpZ2dlclNhdmUgOiBmdW5jdGlvbigpIHsKCQkJZWFjaCh0aGlzLmVkaXRvcnMsIGZ1bmN0aW9uKGUpIHsKCQkJCWUuc2F2ZSgpOwoJCQl9KTsKCQl9LAoKCQlhZGRJMThuIDogZnVuY3Rpb24ocCwgbykgewoJCQl2YXIgbG8sIGkxOG4gPSB0aGlzLmkxOG47CgoJCQlpZiAoIXRpbnltY2UuaXMocCwgJ3N0cmluZycpKSB7CgkJCQllYWNoKHAsIGZ1bmN0aW9uKG8sIGxjKSB7CgkJCQkJZWFjaChvLCBmdW5jdGlvbihvLCBnKSB7CgkJCQkJCWVhY2gobywgZnVuY3Rpb24obywgaykgewoJCQkJCQkJaWYgKGcgPT09ICdjb21tb24nKQoJCQkJCQkJCWkxOG5bbGMgKyAnLicgKyBrXSA9IG87CgkJCQkJCQllbHNlCgkJCQkJCQkJaTE4bltsYyArICcuJyArIGcgKyAnLicgKyBrXSA9IG87CgkJCQkJCX0pOwoJCQkJCX0pOwoJCQkJfSk7CgkJCX0gZWxzZSB7CgkJCQllYWNoKG8sIGZ1bmN0aW9uKG8sIGspIHsKCQkJCQlpMThuW3AgKyAnLicgKyBrXSA9IG87CgkJCQl9KTsKCQkJfQoJCX0sCgoJCS8vIFByaXZhdGUgbWV0aG9kcwoKCQlfc2V0QWN0aXZlIDogZnVuY3Rpb24oZSkgewoJCQl0aGlzLnNlbGVjdGVkSW5zdGFuY2UgPSB0aGlzLmFjdGl2ZUVkaXRvciA9IGU7CgkJfQoKCQl9KTsKCgl0aW55bWNlLkVkaXRvck1hbmFnZXIucHJlSW5pdCgpOwp9KSh0aW55bWNlKTsKCi8vIFNob3J0IGZvciBlZGl0b3IgbWFuYWdlciB3aW5kb3cudGlueU1DRSBpcyBuZWVkZWQgd2hlbiBUaW55TUNFIGdldHMgbG9hZGVkIHRob3VnaCBhIFhIUiBjYWxsCnZhciB0aW55TUNFID0gd2luZG93LnRpbnlNQ0UgPSB0aW55bWNlLkVkaXRvck1hbmFnZXI7CihmdW5jdGlvbih0aW55bWNlKSB7Cgl2YXIgRE9NID0gdGlueW1jZS5ET00sIEV2ZW50ID0gdGlueW1jZS5kb20uRXZlbnQsIGV4dGVuZCA9IHRpbnltY2UuZXh0ZW5kLCBEaXNwYXRjaGVyID0gdGlueW1jZS51dGlsLkRpc3BhdGNoZXI7Cgl2YXIgZWFjaCA9IHRpbnltY2UuZWFjaCwgaXNHZWNrbyA9IHRpbnltY2UuaXNHZWNrbywgaXNJRSA9IHRpbnltY2UuaXNJRSwgaXNXZWJLaXQgPSB0aW55bWNlLmlzV2ViS2l0OwoJdmFyIGlzID0gdGlueW1jZS5pcywgVGhlbWVNYW5hZ2VyID0gdGlueW1jZS5UaGVtZU1hbmFnZXIsIFBsdWdpbk1hbmFnZXIgPSB0aW55bWNlLlBsdWdpbk1hbmFnZXIsIEVkaXRvck1hbmFnZXIgPSB0aW55bWNlLkVkaXRvck1hbmFnZXI7Cgl2YXIgaW5BcnJheSA9IHRpbnltY2UuaW5BcnJheSwgZ3JlcCA9IHRpbnltY2UuZ3JlcCwgZXhwbG9kZSA9IHRpbnltY2UuZXhwbG9kZTsKCgl0aW55bWNlLmNyZWF0ZSgndGlueW1jZS5FZGl0b3InLCB7CgkJRWRpdG9yIDogZnVuY3Rpb24oaWQsIHMpIHsKICAgICAgICAgICAgQUpTLmxvZygiRWRpdG9yOiBjcmVhdGluZyBFZGl0b3IiKTsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJdC5pZCA9IHQuZWRpdG9ySWQgPSBpZDsKCQkJdC5leGVjQ29tbWFuZHMgPSB7fTsKCQkJdC5xdWVyeVN0YXRlQ29tbWFuZHMgPSB7fTsKCQkJdC5xdWVyeVZhbHVlQ29tbWFuZHMgPSB7fTsKCQkJdC5wbHVnaW5zID0ge307CgoJCQkvLyBBZGQgZXZlbnRzIHRvIHRoZSBlZGl0b3IKCQkJZWFjaChbCgkJCQknb25QcmVJbml0JywKCQkJCSdvbkJlZm9yZVJlbmRlclVJJywKCQkJCSdvblBvc3RSZW5kZXInLAoJCQkJJ29uSW5pdCcsCgkJCQknb25SZW1vdmUnLAoJCQkJJ29uQWN0aXZhdGUnLAoJCQkJJ29uRGVhY3RpdmF0ZScsCgkJCQknb25DbGljaycsCgkJCQknb25FdmVudCcsCgkJCQknb25Nb3VzZVVwJywKCQkJCSdvbk1vdXNlRG93bicsCgkJCQknb25EYmxDbGljaycsCgkJCQknb25LZXlEb3duJywKCQkJCSdvbktleVVwJywKCQkJCSdvbktleVByZXNzJywKCQkJCSdvbkNvbnRleHRNZW51JywKCQkJCSdvblN1Ym1pdCcsCgkJCQknb25SZXNldCcsCgkJCQknb25QYXN0ZScsCgkJCQknb25QcmVQcm9jZXNzJywKCQkJCSdvblBvc3RQcm9jZXNzJywKCQkJCSdvbkJlZm9yZVNldENvbnRlbnQnLAoJCQkJJ29uQmVmb3JlR2V0Q29udGVudCcsCgkJCQknb25TZXRDb250ZW50JywKCQkJCSdvbkdldENvbnRlbnQnLAoJCQkJJ29uTG9hZENvbnRlbnQnLAoJCQkJJ29uU2F2ZUNvbnRlbnQnLAoJCQkJJ29uTm9kZUNoYW5nZScsCgkJCQknb25DaGFuZ2UnLAoJCQkJJ29uQmVmb3JlRXhlY0NvbW1hbmQnLAoJCQkJJ29uRXhlY0NvbW1hbmQnLAoJCQkJJ29uVW5kbycsCgkJCQknb25SZWRvJywKCQkJCSdvblZpc3VhbEFpZCcsCgkJCQknb25TZXRQcm9ncmVzc1N0YXRlJwoJCQldLCBmdW5jdGlvbihlKSB7CgkJCQl0W2VdID0gbmV3IERpc3BhdGNoZXIodCk7CgkJCX0pOwoKCQkJLy8gRGVmYXVsdCBlZGl0b3IgY29uZmlnCgkJCXQuc2V0dGluZ3MgPSBzID0gZXh0ZW5kKHsKCQkJCWlkIDogaWQsCgkJCQlsYW5ndWFnZSA6ICdlbicsCgkJCQlkb2NzX2xhbmd1YWdlIDogJ2VuJywKCQkJCXRoZW1lIDogJ3NpbXBsZScsCgkJCQlza2luIDogJ2RlZmF1bHQnLAoJCQkJZGVsdGFfd2lkdGggOiAwLAoJCQkJZGVsdGFfaGVpZ2h0IDogMCwKCQkJCXBvcHVwX2NzcyA6ICcnLAoJCQkJcGx1Z2lucyA6ICcnLAoJCQkJZG9jdW1lbnRfYmFzZV91cmwgOiB0aW55bWNlLmRvY3VtZW50QmFzZVVSTCwKCQkJCWFkZF9mb3JtX3N1Ym1pdF90cmlnZ2VyIDogMSwKCQkJCXN1Ym1pdF9wYXRjaCA6IDEsCgkJCQlhZGRfdW5sb2FkX3RyaWdnZXIgOiAxLAoJCQkJY29udmVydF91cmxzIDogMSwKCQkJCXJlbGF0aXZlX3VybHMgOiAxLAoJCQkJcmVtb3ZlX3NjcmlwdF9ob3N0IDogMSwKCQkJCXRhYmxlX2lubGluZV9lZGl0aW5nIDogMCwKCQkJCW9iamVjdF9yZXNpemluZyA6IDEsCgkJCQljbGVhbnVwIDogMSwKCQkJCWFjY2Vzc2liaWxpdHlfZm9jdXMgOiAxLAoJCQkJY3VzdG9tX3Nob3J0Y3V0cyA6IDEsCgkJCQljdXN0b21fdW5kb19yZWRvX2tleWJvYXJkX3Nob3J0Y3V0cyA6IDEsCgkJCQljdXN0b21fdW5kb19yZWRvX3Jlc3RvcmVfc2VsZWN0aW9uIDogMSwKCQkJCWN1c3RvbV91bmRvX3JlZG8gOiAxLAoJCQkJZG9jdHlwZSA6ICc8IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wMSBUcmFuc2l0aW9uYWwvL0VOIj4nLAoJCQkJdmlzdWFsX3RhYmxlX2NsYXNzIDogJ21jZUl0ZW1UYWJsZScsCgkJCQl2aXN1YWwgOiAxLAoJCQkJaW5saW5lX3N0eWxlcyA6IHRydWUsCgkJCQljb252ZXJ0X2ZvbnRzX3RvX3NwYW5zIDogdHJ1ZSwKCQkJCWZvbnRfc2l6ZV9zdHlsZV92YWx1ZXMgOiAneHgtc21hbGwseC1zbWFsbCxzbWFsbCxtZWRpdW0sbGFyZ2UseC1sYXJnZSx4eC1sYXJnZScsCgkJCQlhcHBseV9zb3VyY2VfZm9ybWF0dGluZyA6IDEsCgkJCQlkaXJlY3Rpb25hbGl0eSA6ICdsdHInLAoJCQkJZm9yY2VkX3Jvb3RfYmxvY2sgOiAncCcsCgkJCQl2YWxpZF9lbGVtZW50cyA6ICdAW2lkfGNsYXNzfHN0eWxlfHRpdGxlfGRpcjxsdHI/cnRsfGxhbmd8eG1sOjpsYW5nfG9uY2xpY2t8b25kYmxjbGlja3xvbm1vdXNlZG93bnxvbm1vdXNldXB8b25tb3VzZW92ZXJ8b25tb3VzZW1vdmV8b25tb3VzZW91dHxvbmtleXByZXNzfG9ua2V5ZG93bnxvbmtleXVwXSxhW3JlbHxyZXZ8Y2hhcnNldHxocmVmbGFuZ3x0YWJpbmRleHxhY2Nlc3NrZXl8dHlwZXxuYW1lfGhyZWZ8dGFyZ2V0fHRpdGxlfGNsYXNzfG9uZm9jdXN8b25ibHVyXSxzdHJvbmcvYixlbS9pLHN0cmlrZSx1LCNwW2FsaWduXSwtb2xbdHlwZXxjb21wYWN0XSwtdWxbdHlwZXxjb21wYWN0XSwtbGksYnIsaW1nW2xvbmdkZXNjfHVzZW1hcHxzcmN8Ym9yZGVyfGFsdD18dGl0bGV8aHNwYWNlfHZzcGFjZXx3aWR0aHxoZWlnaHR8YWxpZ25dLC1zdWIsLXN1cCwtYmxvY2txdW90ZVtjaXRlXSwtdGFibGVbYm9yZGVyPTB8Y2VsbHNwYWNpbmd8Y2VsbHBhZGRpbmd8d2lkdGh8ZnJhbWV8cnVsZXN8aGVpZ2h0fGFsaWdufHN1bW1hcnl8Ymdjb2xvcnxiYWNrZ3JvdW5kfGJvcmRlcmNvbG9yXSwtdHJbcm93c3Bhbnx3aWR0aHxoZWlnaHR8YWxpZ258dmFsaWdufGJnY29sb3J8YmFja2dyb3VuZHxib3JkZXJjb2xvcl0sdGJvZHksdGhlYWQsdGZvb3QsI3RkW2NvbHNwYW58cm93c3Bhbnx3aWR0aHxoZWlnaHR8YWxpZ258dmFsaWdufGJnY29sb3J8YmFja2dyb3VuZHxib3JkZXJjb2xvcnxzY29wZV0sI3RoW2NvbHNwYW58cm93c3Bhbnx3aWR0aHxoZWlnaHR8YWxpZ258dmFsaWdufHNjb3BlXSxjYXB0aW9uLC1kaXYsLXNwYW4sLWNvZGUsLXByZSxhZGRyZXNzLC1oMSwtaDIsLWgzLC1oNCwtaDUsLWg2LGhyW3NpemV8bm9zaGFkZV0sLWZvbnRbZmFjZXxzaXplfGNvbG9yXSxkZCxkbCxkdCxjaXRlLGFiYnIsYWNyb255bSxkZWxbZGF0ZXRpbWV8Y2l0ZV0saW5zW2RhdGV0aW1lfGNpdGVdLG9iamVjdFtjbGFzc2lkfHdpZHRofGhlaWdodHxjb2RlYmFzZXwqXSxwYXJhbVtuYW1lfHZhbHVlXSxlbWJlZFt0eXBlfHdpZHRofGhlaWdodHxzcmN8Kl0sc2NyaXB0W3NyY3x0eXBlXSxtYXBbbmFtZV0sYXJlYVtzaGFwZXxjb29yZHN8aHJlZnxhbHR8dGFyZ2V0XSxiZG8sYnV0dG9uLGNvbFthbGlnbnxjaGFyfGNoYXJvZmZ8c3Bhbnx2YWxpZ258d2lkdGhdLGNvbGdyb3VwW2FsaWdufGNoYXJ8Y2hhcm9mZnxzcGFufHZhbGlnbnx3aWR0aF0sZGZuLGZpZWxkc2V0LGZvcm1bYWN0aW9ufGFjY2VwdHxhY2NlcHQtY2hhcnNldHxlbmN0eXBlfG1ldGhvZF0saW5wdXRbYWNjZXB0fGFsdHxjaGVja2VkfGRpc2FibGVkfG1heGxlbmd0aHxuYW1lfHJlYWRvbmx5fHNpemV8c3JjfHR5cGV8dmFsdWV8dGFiaW5kZXh8YWNjZXNza2V5XSxrYmQsbGFiZWxbZm9yXSxsZWdlbmQsbm9zY3JpcHQsb3B0Z3JvdXBbbGFiZWx8ZGlzYWJsZWRdLG9wdGlvbltkaXNhYmxlZHxsYWJlbHxzZWxlY3RlZHx2YWx1ZV0scVtjaXRlXSxzYW1wLHNlbGVjdFtkaXNhYmxlZHxtdWx0aXBsZXxuYW1lfHNpemVdLHNtYWxsLHRleHRhcmVhW2NvbHN8cm93c3xkaXNhYmxlZHxuYW1lfHJlYWRvbmx5XSx0dCx2YXIsYmlnJywKCQkJCWhpZGRlbl9pbnB1dCA6IDEsCgkJCQlwYWRkX2VtcHR5X2VkaXRvciA6IDEsCgkJCQlyZW5kZXJfdWkgOiAxLAoJCQkJaW5pdF90aGVtZSA6IDEsCgkJCQlmb3JjZV9wX25ld2xpbmVzIDogMSwKCQkJCWluZGVudGF0aW9uIDogJzMwcHgnLAoJCQkJa2VlcF9zdHlsZXMgOiAxLAoJCQkJZml4X3RhYmxlX2VsZW1lbnRzIDogMSwKCQkJCXJlbW92ZWZvcm1hdF9zZWxlY3RvciA6ICdzcGFuLGIsc3Ryb25nLGVtLGksZm9udCx1LHN0cmlrZScKCQkJfSwgcyk7CgoJCQkvLyBTZXR1cCBVUklzCgkJCXQuZG9jdW1lbnRCYXNlVVJJID0gbmV3IHRpbnltY2UudXRpbC5VUkkocy5kb2N1bWVudF9iYXNlX3VybCB8fCB0aW55bWNlLmRvY3VtZW50QmFzZVVSTCwgewoJCQkJYmFzZV91cmkgOiB0aW55TUNFLmJhc2VVUkkKCQkJfSk7CgkJCXQuYmFzZVVSSSA9IEVkaXRvck1hbmFnZXIuYmFzZVVSSTsKCgkJCS8vIENhbGwgc2V0dXAKCQkJdC5leGVjQ2FsbGJhY2soJ3NldHVwJywgdCk7CgkJfSwKCgkJcmVuZGVyIDogZnVuY3Rpb24obnN0KSB7CiAgICAgICAgICAgIEFKUy5sb2coIkVkaXRvcjpyZW5kZXIgc3RhcnRpbmciKTsKICAgICAgICAgICAgdmFyIHQgPSB0aGlzLCBzID0gdC5zZXR0aW5ncywgaWQgPSB0LmlkLCBzbCA9IHRpbnltY2UuU2NyaXB0TG9hZGVyOwoJCQkvLyBBVExBU1NJQU4gLSBObyBuZWVkIGZvciB0aGlzIGFzIHdlIGluaXRpYWxpc2UgVGlueU1DRSBvbiBET00gcmVhZHkKICAgICAgICAgICAgLy8gUGFnZSBpcyBub3QgbG9hZGVkIHlldCwgd2FpdCBmb3IgaXQKLy8JCQlpZiAoIUV2ZW50LmRvbUxvYWRlZCkgewovLyAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygiIUV2ZW50LmRvbUxvYWRlZCIpOwovLyAgICAgICAgICAgICAgICBFdmVudC5hZGQoZG9jdW1lbnQsICdpbml0JywgZnVuY3Rpb24oKSB7Ci8vCQkJCQl0LnJlbmRlcigpOwovLwkJCQl9KTsKLy8JCQkJcmV0dXJuOwovLwkJCX0KCgkJCS8vIEZvcmNlIHN0cmljdCBsb2FkaW5nIG1vZGUgaWYgcmVuZGVyIHVzIGNhbGxlZCBieSB1c2VyIGFuZCBub3QgaW50ZXJuYWxseQoJCQlpZiAoIW5zdCkgewoJCQkJcy5zdHJpY3RfbG9hZGluZ19tb2RlID0gMTsKCQkJCXRpbnlNQ0Uuc2V0dGluZ3MgPSBzOwoJCQl9CgoJCQkvLyBFbGVtZW50IG5vdCBmb3VuZCwgdGhlbiBza2lwIGluaXRpYWxpemF0aW9uCgkJCWlmICghdC5nZXRFbGVtZW50KCkpCiAgICAgICAgICAgICAgICByZXR1cm47CgoJCQlpZiAocy5zdHJpY3RfbG9hZGluZ19tb2RlKSB7CgkJCQlzbC5zZXR0aW5ncy5zdHJpY3RfbW9kZSA9IHMuc3RyaWN0X2xvYWRpbmdfbW9kZTsKCQkJCXRpbnltY2UuRE9NLnNldHRpbmdzLnN0cmljdCA9IDE7CgkJCX0KCgkJCS8vIEFkZCBoaWRkZW4gaW5wdXQgZm9yIG5vbiBpbnB1dCBlbGVtZW50cyBpbnNpZGUgZm9ybSBlbGVtZW50cwoJCQlpZiAoIS9URVhUQVJFQXxJTlBVVC9pLnRlc3QodC5nZXRFbGVtZW50KCkubm9kZU5hbWUpICYmIHMuaGlkZGVuX2lucHV0ICYmIERPTS5nZXRQYXJlbnQoaWQsICdmb3JtJykpCgkJCQlET00uaW5zZXJ0QWZ0ZXIoRE9NLmNyZWF0ZSgnaW5wdXQnLCB7dHlwZSA6ICdoaWRkZW4nLCBuYW1lIDogaWR9KSwgaWQpOwoKCQkJaWYgKHRpbnltY2UuV2luZG93TWFuYWdlcikKCQkJCXQud2luZG93TWFuYWdlciA9IG5ldyB0aW55bWNlLldpbmRvd01hbmFnZXIodCk7CgoJCQlpZiAocy5lbmNvZGluZyA9PSAneG1sJykgewoJCQkJdC5vbkdldENvbnRlbnQuYWRkKGZ1bmN0aW9uKGVkLCBvKSB7CgkJCQkJaWYgKG8uc2F2ZSkKCQkJCQkJby5jb250ZW50ID0gRE9NLmVuY29kZShvLmNvbnRlbnQpOwoJCQkJfSk7CgkJCX0KCgkJCWlmIChzLmFkZF9mb3JtX3N1Ym1pdF90cmlnZ2VyKSB7CgkJCQl0Lm9uU3VibWl0LmFkZFRvVG9wKGZ1bmN0aW9uKCkgewoJCQkJCWlmICh0LmluaXRpYWxpemVkKSB7CgkJCQkJCXQuc2F2ZSgpOwoJCQkJCQl0LmlzTm90RGlydHkgPSAxOwoJCQkJCX0KCQkJCX0pOwoJCQl9CgoJCQlpZiAocy5hZGRfdW5sb2FkX3RyaWdnZXIpIHsKCQkJCXQuX2JlZm9yZVVubG9hZCA9IHRpbnlNQ0Uub25CZWZvcmVVbmxvYWQuYWRkKGZ1bmN0aW9uKCkgewoJCQkJCWlmICh0LmluaXRpYWxpemVkICYmICF0LmRlc3Ryb3llZCAmJiAhdC5pc0hpZGRlbigpKQoJCQkJCQl0LnNhdmUoe2Zvcm1hdCA6ICdyYXcnLCBub19ldmVudHMgOiB0cnVlfSk7CgkJCQl9KTsKCQkJfQoKCQkJdGlueW1jZS5hZGRVbmxvYWQodC5kZXN0cm95LCB0KTsKCgkJCWlmIChzLnN1Ym1pdF9wYXRjaCkgewoJCQkJdC5vbkJlZm9yZVJlbmRlclVJLmFkZChmdW5jdGlvbigpIHsKCQkJCQl2YXIgbiA9IHQuZ2V0RWxlbWVudCgpLmZvcm07CgoJCQkJCWlmICghbikKCQkJCQkJcmV0dXJuOwoKCQkJCQkvLyBBbHJlYWR5IHBhdGNoZWQKCQkJCQlpZiAobi5fbWNlT2xkU3VibWl0KQoJCQkJCQlyZXR1cm47CgoJCQkJCS8vIENoZWNrIHBhZ2UgdXNlcyBpZD0ic3VibWl0IiBvciBuYW1lPSJzdWJtaXQiIGZvciBpdCdzIHN1Ym1pdCBidXR0b24KCQkJCQlpZiAoIW4uc3VibWl0Lm5vZGVUeXBlICYmICFuLnN1Ym1pdC5sZW5ndGgpIHsKCQkJCQkJdC5mb3JtRWxlbWVudCA9IG47CgkJCQkJCW4uX21jZU9sZFN1Ym1pdCA9IG4uc3VibWl0OwoJCQkJCQluLnN1Ym1pdCA9IGZ1bmN0aW9uKCkgewoJCQkJCQkJLy8gU2F2ZSBhbGwgaW5zdGFuY2VzCgkJCQkJCQlFZGl0b3JNYW5hZ2VyLnRyaWdnZXJTYXZlKCk7CgkJCQkJCQl0LmlzTm90RGlydHkgPSAxOwoKCQkJCQkJCXJldHVybiB0LmZvcm1FbGVtZW50Ll9tY2VPbGRTdWJtaXQodC5mb3JtRWxlbWVudCk7CgkJCQkJCX07CgkJCQkJfQoKCQkJCQluID0gbnVsbDsKCQkJCX0pOwoJCQl9CgogICAgICAgICAgICAvLyBBVExBU1NJQU4gLSBEb24ndCBhY3R1YWxseSBsb2FkIGFueXRoaW5nIC0gc2NyaXB0cyBhcmUgYWxsIGxvYWRlZCB2aWEgI3JlcXVpcmVSZXNvdXJjZQoJCQkvLyBMb2FkIHNjcmlwdHMKCQkJZnVuY3Rpb24gbG9hZFNjcmlwdHMoKSB7Ci8vCQkJCWlmIChzLmxhbmd1YWdlKQovLwkJCQkJc2wuYWRkKHRpbnltY2UuYmFzZVVSTCArICcvbGFuZ3MvJyArIHMubGFuZ3VhZ2UgKyAnLmpzJyk7CgoJCQkJaWYgKHMudGhlbWUgJiYgcy50aGVtZS5jaGFyQXQoMCkgIT0gJy0nICYmICFUaGVtZU1hbmFnZXIudXJsc1tzLnRoZW1lXSkKCQkJCQlUaGVtZU1hbmFnZXIubG9hZChzLnRoZW1lLCAndGhlbWVzLycgKyBzLnRoZW1lICsgJy9lZGl0b3JfdGVtcGxhdGUnICsgdGlueW1jZS5zdWZmaXggKyAnLmpzJyk7CgoJCQkJZWFjaChleHBsb2RlKHMucGx1Z2lucyksIGZ1bmN0aW9uKHApIHsKCQkJCQlpZiAocCAmJiBwLmNoYXJBdCgwKSAhPSAnLScgJiYgIVBsdWdpbk1hbmFnZXIudXJsc1twXSkgewoJCQkJCQkvLyBTa2lwIHNhZmFyaSBwbHVnaW4gZm9yIG90aGVyIGJyb3dzZXJzCgkJCQkJCWlmICghaXNXZWJLaXQgJiYgcCA9PSAnc2FmYXJpJykKCQkJCQkJCXJldHVybjsKCgkJCQkJCVBsdWdpbk1hbmFnZXIubG9hZChwLCAncGx1Z2lucy8nICsgcCArICcvZWRpdG9yX3BsdWdpbicgKyB0aW55bWNlLnN1ZmZpeCArICcuanMnKTsKCQkJCQl9CgkJCQl9KTsKICAgICAgICAgICAgICAgIC8vQVRMQVNTSUFOIC0gTm8gbmVlZCB0byB1c2UgdGhlIHNjcmlwdCBsb2FkZXIsIGp1c3QgaW5pdCBpbW1lZGlhdGVseQoJCQkJLy8gSW5pdCB3aGVuIHF1ZSBpcyBsb2FkZWQKLy8JCQkJc2wubG9hZFF1ZXVlKGZ1bmN0aW9uKCkgewoJCQkJCWlmICghdC5yZW1vdmVkKQoJCQkJCQl0LmluaXQoKTsKLy8JCQkJfSk7CgkJCX07CgoJCQkvLyBMb2FkIGNvbXBhdDJ4IGZpcnN0CgkJCWlmIChzLnBsdWdpbnMuaW5kZXhPZignY29tcGF0MngnKSAhPSAtMSkgewoJCQkJUGx1Z2luTWFuYWdlci5sb2FkKCdjb21wYXQyeCcsICdwbHVnaW5zL2NvbXBhdDJ4L2VkaXRvcl9wbHVnaW4nICsgdGlueW1jZS5zdWZmaXggKyAnLmpzJyk7CgkJCQlzbC5sb2FkUXVldWUobG9hZFNjcmlwdHMpOwoJCQl9IGVsc2UKCQkJCWxvYWRTY3JpcHRzKCk7CgkJfSwKCgkJaW5pdCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBBSlMubG9nKCJFZGl0b3I6aW5pdCBzdGFydGluZyIpOwoJCQl2YXIgbiwgdCA9IHRoaXMsIHMgPSB0LnNldHRpbmdzLCB3LCBoLCBlID0gdC5nZXRFbGVtZW50KCksIG8sIHRpLCB1LCBiaSwgYmMsIHJlOwoKCQkJRWRpdG9yTWFuYWdlci5hZGQodCk7CgoJCQkvLyBDcmVhdGUgdGhlbWUKCQkJaWYgKHMudGhlbWUpIHsKCQkJCXMudGhlbWUgPSBzLnRoZW1lLnJlcGxhY2UoLy0vLCAnJyk7CgkJCQlvID0gVGhlbWVNYW5hZ2VyLmdldChzLnRoZW1lKTsKCQkJCXQudGhlbWUgPSBuZXcgbygpOwoKCQkJCWlmICh0LnRoZW1lLmluaXQgJiYgcy5pbml0X3RoZW1lKQoJCQkJCXQudGhlbWUuaW5pdCh0LCBUaGVtZU1hbmFnZXIudXJsc1tzLnRoZW1lXSB8fCB0aW55bWNlLmRvY3VtZW50QmFzZVVSTC5yZXBsYWNlKC9cLyQvLCAnJykpOwoJCQl9CgoJCQkvLyBDcmVhdGUgYWxsIHBsdWdpbnMKCQkJZWFjaChleHBsb2RlKHMucGx1Z2lucy5yZXBsYWNlKC9cLS9nLCAnJykpLCBmdW5jdGlvbihwKSB7CgkJCQl2YXIgYyA9IFBsdWdpbk1hbmFnZXIuZ2V0KHApLCB1ID0gUGx1Z2luTWFuYWdlci51cmxzW3BdIHx8IHRpbnltY2UuZG9jdW1lbnRCYXNlVVJMLnJlcGxhY2UoL1wvJC8sICcnKSwgcG87CgoJCQkJaWYgKGMpIHsKCQkJCQlwbyA9IG5ldyBjKHQsIHUpOwoKCQkJCQl0LnBsdWdpbnNbcF0gPSBwbzsKCgkJCQkJaWYgKHBvLmluaXQpCgkJCQkJCXBvLmluaXQodCwgdSk7CgkJCQl9CgkJCX0pOwoKCQkJLy8gU2V0dXAgcG9wdXAgQ1NTIHBhdGgocykKCQkJaWYgKHMucG9wdXBfY3NzICE9PSBmYWxzZSkgewoJCQkJaWYgKHMucG9wdXBfY3NzKQoJCQkJCXMucG9wdXBfY3NzID0gdC5kb2N1bWVudEJhc2VVUkkudG9BYnNvbHV0ZShzLnBvcHVwX2Nzcyk7CgkJCQllbHNlCgkJCQkJcy5wb3B1cF9jc3MgPSB0LmJhc2VVUkkudG9BYnNvbHV0ZSgidGhlbWVzLyIgKyBzLnRoZW1lICsgIi9za2lucy8iICsgcy5za2luICsgIi9kaWFsb2cuY3NzIik7CgkJCX0KCgkJCWlmIChzLnBvcHVwX2Nzc19hZGQpCgkJCQlzLnBvcHVwX2NzcyArPSAnLCcgKyB0LmRvY3VtZW50QmFzZVVSSS50b0Fic29sdXRlKHMucG9wdXBfY3NzX2FkZCk7CgoJCQkvLyBTZXR1cCBjb250cm9sIGZhY3RvcnkKCQkJdC5jb250cm9sTWFuYWdlciA9IG5ldyB0aW55bWNlLkNvbnRyb2xNYW5hZ2VyKHQpOwoJCQl0LnVuZG9NYW5hZ2VyID0gbmV3IHRpbnltY2UuVW5kb01hbmFnZXIodCk7CgoJCQkvLyBQYXNzIHRocm91Z2gKCQkJdC51bmRvTWFuYWdlci5vbkFkZC5hZGQoZnVuY3Rpb24odW0sIGwpIHsKCQkJCWlmICghbC5pbml0aWFsKQoJCQkJCXJldHVybiB0Lm9uQ2hhbmdlLmRpc3BhdGNoKHQsIGwsIHVtKTsKCQkJfSk7CgoJCQl0LnVuZG9NYW5hZ2VyLm9uVW5kby5hZGQoZnVuY3Rpb24odW0sIGwpIHsKCQkJCXJldHVybiB0Lm9uVW5kby5kaXNwYXRjaCh0LCBsLCB1bSk7CgkJCX0pOwoKCQkJdC51bmRvTWFuYWdlci5vblJlZG8uYWRkKGZ1bmN0aW9uKHVtLCBsKSB7CgkJCQlyZXR1cm4gdC5vblJlZG8uZGlzcGF0Y2godCwgbCwgdW0pOwoJCQl9KTsKCgkJCWlmIChzLmN1c3RvbV91bmRvX3JlZG8pIHsKCQkJCXQub25FeGVjQ29tbWFuZC5hZGQoZnVuY3Rpb24oZWQsIGNtZCwgdWksIHZhbCwgYSkgewoJCQkJCWlmIChjbWQgIT0gJ1VuZG8nICYmIGNtZCAhPSAnUmVkbycgJiYgY21kICE9ICdtY2VSZXBhaW50JyAmJiAoIWEgfHwgIWEuc2tpcF91bmRvKSkKCQkJCQkJdC51bmRvTWFuYWdlci5hZGQoKTsKCQkJCX0pOwoJCQl9CgoJCQl0Lm9uRXhlY0NvbW1hbmQuYWRkKGZ1bmN0aW9uKGVkLCBjKSB7CgkJCQkvLyBEb24ndCByZWZyZXNoIHRoZSBzZWxlY3QgbGlzdHMgdW50aWwgY2FyZXQgbW92ZQoJCQkJaWYgKCEvXihGb250TmFtZXxGb250U2l6ZSkkLy50ZXN0KGMpKQoJCQkJCXQubm9kZUNoYW5nZWQoKTsKCQkJfSk7CgoJCQkvLyBSZW1vdmUgZ2hvc3Qgc2VsZWN0aW9ucyBvbiBpbWFnZXMgYW5kIHRhYmxlcyBpbiBHZWNrbwoJCQlpZiAoaXNHZWNrbykgewoJCQkJZnVuY3Rpb24gcmVwYWludChhLCBvKSB7CgkJCQkJaWYgKCFvIHx8ICFvLmluaXRpYWwpCgkJCQkJCXQuZXhlY0NvbW1hbmQoJ21jZVJlcGFpbnQnKTsKCQkJCX07CgoJCQkJdC5vblVuZG8uYWRkKHJlcGFpbnQpOwoJCQkJdC5vblJlZG8uYWRkKHJlcGFpbnQpOwoJCQkJdC5vblNldENvbnRlbnQuYWRkKHJlcGFpbnQpOwoJCQl9CgoJCQkvLyBFbmFibGVzIHVzZXJzIHRvIG92ZXJyaWRlIHRoZSBjb250cm9sIGZhY3RvcnkKCQkJdC5vbkJlZm9yZVJlbmRlclVJLmRpc3BhdGNoKHQsIHQuY29udHJvbE1hbmFnZXIpOwoKCQkJLy8gTWVhc3VyZSBib3gKCQkJaWYgKHMucmVuZGVyX3VpKSB7CgkJCQl3ID0gcy53aWR0aCB8fCBlLnN0eWxlLndpZHRoIHx8IGUub2Zmc2V0V2lkdGg7CgkJCQloID0gcy5oZWlnaHQgfHwgZS5zdHlsZS5oZWlnaHQgfHwgZS5vZmZzZXRIZWlnaHQ7CgkJCQl0Lm9yZ0Rpc3BsYXkgPSBlLnN0eWxlLmRpc3BsYXk7CgkJCQlyZSA9IC9eWzAtOVwuXSsofHB4KSQvaTsKCgkJCQlpZiAocmUudGVzdCgnJyArIHcpKQoJCQkJCXcgPSBNYXRoLm1heChwYXJzZUludCh3KSArIChvLmRlbHRhV2lkdGggfHwgMCksIDEwMCk7CgoJCQkJaWYgKHJlLnRlc3QoJycgKyBoKSkKCQkJCQloID0gTWF0aC5tYXgocGFyc2VJbnQoaCkgKyAoby5kZWx0YUhlaWdodCB8fCAwKSwgMTAwKTsKCgkJCQkvLyBSZW5kZXIgVUkKCQkJCW8gPSB0LnRoZW1lLnJlbmRlclVJKHsKCQkJCQl0YXJnZXROb2RlIDogZSwKCQkJCQl3aWR0aCA6IHcsCgkJCQkJaGVpZ2h0IDogaCwKCQkJCQlkZWx0YVdpZHRoIDogcy5kZWx0YV93aWR0aCwKCQkJCQlkZWx0YUhlaWdodCA6IHMuZGVsdGFfaGVpZ2h0CgkJCQl9KTsKCgkJCQl0LmVkaXRvckNvbnRhaW5lciA9IG8uZWRpdG9yQ29udGFpbmVyOwoJCQl9CgoKCQkJLy8gVXNlciBzcGVjaWZpZWQgYSBkb2N1bWVudC5kb21haW4gdmFsdWUKCQkJaWYgKGRvY3VtZW50LmRvbWFpbiAmJiBsb2NhdGlvbi5ob3N0bmFtZSAhPSBkb2N1bWVudC5kb21haW4pCgkJCQl0aW55bWNlLnJlbGF4ZWREb21haW4gPSBkb2N1bWVudC5kb21haW47CgoJCQkvLyBSZXNpemUgZWRpdG9yCgkJCURPTS5zZXRTdHlsZXMoby5zaXplQ29udGFpbmVyIHx8IG8uZWRpdG9yQ29udGFpbmVyLCB7CgkJCQl3aWR0aCA6IHcsCgkJCQloZWlnaHQgOiBoCgkJCX0pOwoKCQkJaCA9IChvLmlmcmFtZUhlaWdodCB8fCBoKSArICh0eXBlb2YoaCkgPT0gJ251bWJlcicgPyAoby5kZWx0YUhlaWdodCB8fCAwKSA6ICcnKTsKCQkJaWYgKGggPCAxMDApCgkJCQloID0gMTAwOwoKICAgICAgICAgICAgLy8gQVRMQVNTSUFOIC0gdXNlIHRoZSB1c2VyJ3MgY3VycmVudCBiYXNlIHVybCBmb3IgdGhlIGlmcmFtZQogICAgICAgICAgICBBSlMubG9nKCJFZGl0b3I6aW5pdCBpZnJhbWUgYmFzZSBocmVmPSIgKyBBSlMuRWRpdG9yLkFkYXB0ZXIuZ2V0Q3VycmVudEJhc2VVcmwoKSk7CgoJCQl0LmlmcmFtZUhUTUwgPSBzLmRvY3R5cGUgKyAnPGh0bWw+PGhlYWQgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPic7CgoJCQkvLyBXZSBvbmx5IG5lZWQgdG8gb3ZlcnJpZGUgcGF0aHMgaWYgd2UgaGF2ZSB0bwoJCQkvLyBJRSBoYXMgYSBidWcgd2hlcmUgaXQgcmVtb3ZlIHNpdGUgYWJzb2x1dGUgdXJscyB0byByZWxhdGl2ZSBvbmVzIGlmIHRoaXMgaXMgc3BlY2lmaWVkCgkJCWlmIChzLmRvY3VtZW50X2Jhc2VfdXJsICE9IHRpbnltY2UuZG9jdW1lbnRCYXNlVVJMKQoJCQkJdC5pZnJhbWVIVE1MICs9ICc8YmFzZSBocmVmPSInICsgQUpTLkVkaXRvci5BZGFwdGVyLmdldEN1cnJlbnRCYXNlVXJsKCkgKyAnIiAvPic7CgoJCQl0LmlmcmFtZUhUTUwgKz0gJzxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPic7CgoJCQlpZiAodGlueW1jZS5yZWxheGVkRG9tYWluKQoJCQkJdC5pZnJhbWVIVE1MICs9ICc8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+ZG9jdW1lbnQuZG9tYWluID0gIicgKyB0aW55bWNlLnJlbGF4ZWREb21haW4gKyAnIjs8L3NjcmlwdD4nOwoKCQkJYmkgPSBzLmJvZHlfaWQgfHwgJ3RpbnltY2UnOwoJCQlpZiAoYmkuaW5kZXhPZignPScpICE9IC0xKSB7CgkJCQliaSA9IHQuZ2V0UGFyYW0oJ2JvZHlfaWQnLCAnJywgJ2hhc2gnKTsKCQkJCWJpID0gYmlbdC5pZF0gfHwgYmk7CgkJCX0KCgkJCWJjID0gcy5ib2R5X2NsYXNzIHx8ICcnOwoJCQlpZiAoYmMuaW5kZXhPZignPScpICE9IC0xKSB7CgkJCQliYyA9IHQuZ2V0UGFyYW0oJ2JvZHlfY2xhc3MnLCAnJywgJ2hhc2gnKTsKCQkJCWJjID0gYmNbdC5pZF0gfHwgJyc7CgkJCX0KCgkJCXQuaWZyYW1lSFRNTCArPSAnPC9oZWFkPjxib2R5IGlkPSInICsgYmkgKyAnIiBjbGFzcz0ibWNlQ29udGVudEJvZHkgJyArIGJjICsgJyI+PC9ib2R5PjwvaHRtbD4nOwoKCQkJLy8gRG9tYWluIHJlbGF4aW5nIGVuYWJsZWQsIHRoZW4gc2V0IGRvY3VtZW50IGRvbWFpbgoJCQlpZiAodGlueW1jZS5yZWxheGVkRG9tYWluKSB7CgkJCQkvLyBXZSBuZWVkIHRvIHdyaXRlIHRoZSBjb250ZW50cyBoZXJlIGluIElFIHNpbmNlIG11bHRpcGxlIHdyaXRlcyBtZXNzZXMgdXAgcmVmcmVzaCBidXR0b24gYW5kIGJhY2sgYnV0dG9uCgkJCQlpZiAoaXNJRSB8fCAodGlueW1jZS5pc09wZXJhICYmIHBhcnNlRmxvYXQob3BlcmEudmVyc2lvbigpKSA+PSA5LjUpKQoJCQkJCXUgPSAnamF2YXNjcmlwdDooZnVuY3Rpb24oKXtkb2N1bWVudC5vcGVuKCk7ZG9jdW1lbnQuZG9tYWluPSInICsgZG9jdW1lbnQuZG9tYWluICsgJyI7dmFyIGVkID0gd2luZG93LnBhcmVudC50aW55TUNFLmdldCgiJyArIHQuaWQgKyAnIik7ZG9jdW1lbnQud3JpdGUoZWQuaWZyYW1lSFRNTCk7ZG9jdW1lbnQuY2xvc2UoKTtlZC5zZXR1cElmcmFtZSgpO30pKCknOwoJCQkJZWxzZSBpZiAodGlueW1jZS5pc09wZXJhKQoJCQkJCXUgPSAnamF2YXNjcmlwdDooZnVuY3Rpb24oKXtkb2N1bWVudC5vcGVuKCk7ZG9jdW1lbnQuZG9tYWluPSInICsgZG9jdW1lbnQuZG9tYWluICsgJyI7ZG9jdW1lbnQuY2xvc2UoKTtlZC5zZXR1cElmcmFtZSgpO30pKCknOwkJCQkJCgkJCX0KCgkJCS8vIENyZWF0ZSBpZnJhbWUKCQkJbiA9IERPTS5hZGQoby5pZnJhbWVDb250YWluZXIsICdpZnJhbWUnLCB7CgkJCQlpZCA6IHQuaWQgKyAiX2lmciIsCgkJCQlzcmMgOiB1IHx8ICdqYXZhc2NyaXB0OiIiJywgLy8gV29ya2Fyb3VuZCBmb3IgSFRUUFMgd2FybmluZyBpbiBJRTYvNwoJCQkJZnJhbWVCb3JkZXIgOiAnMCcsCgkJCQlzdHlsZSA6IHsKCQkJCQl3aWR0aCA6ICcxMDAlJywKCQkJCQloZWlnaHQgOiBoCgkJCQl9CgkJCX0pOwoKCQkJdC5jb250ZW50QXJlYUNvbnRhaW5lciA9IG8uaWZyYW1lQ29udGFpbmVyOwoJCQlET00uZ2V0KG8uZWRpdG9yQ29udGFpbmVyKS5zdHlsZS5kaXNwbGF5ID0gdC5vcmdEaXNwbGF5OwoJCQlET00uZ2V0KHQuaWQpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CgoJCQlpZiAoIWlzSUUgfHwgIXRpbnltY2UucmVsYXhlZERvbWFpbikKCQkJCXQuc2V0dXBJZnJhbWUoKTsKCgkJCWUgPSBuID0gbyA9IG51bGw7IC8vIENsZWFudXAKICAgICAgICAgICAgQUpTLmxvZygiRWRpdG9yOmluaXQgZmluaXNoZWQgcmVuZGVyaW5nIGVkaXRvciEhISIpOwoJCX0sCgoJCXNldHVwSWZyYW1lIDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpcywgcyA9IHQuc2V0dGluZ3MsIGUgPSBET00uZ2V0KHQuaWQpLCBkID0gdC5nZXREb2MoKSwgaCwgYjsKICAgICAgICAgICAgQUpTLmxvZygiRWRpdG9yOnNldHVwSWZyYW1lIGlzSUU9IiArIGlzSUUpOwoKCQkJLy8gU2V0dXAgaWZyYW1lIGJvZHkKCQkJaWYgKCFpc0lFIHx8ICF0aW55bWNlLnJlbGF4ZWREb21haW4pIHsKCQkJCWQub3BlbigpOwoJCQkJZC53cml0ZSh0LmlmcmFtZUhUTUwpOwoJCQkJZC5jbG9zZSgpOwoJCQl9CgoJCQkvLyBEZXNpZ24gbW9kZSBuZWVkcyB0byBiZSBhZGRlZCBoZXJlIEN0cmwrQSB3aWxsIGZhaWwgb3RoZXJ3aXNlCgkJCWlmICghaXNJRSkgewoJCQkJdHJ5IHsKCQkJCQlpZiAoIXMucmVhZG9ubHkpCgkJCQkJCWQuZGVzaWduTW9kZSA9ICdPbic7CgkJCQl9IGNhdGNoIChleCkgewoJCQkJCS8vIFdpbGwgZmFpbCBvbiBHZWNrbyBpZiB0aGUgZWRpdG9yIGlzIHBsYWNlZCBpbiBhbiBoaWRkZW4gY29udGFpbmVyIGVsZW1lbnQKCQkJCQkvLyBUaGUgZGVzaWduIG1vZGUgd2lsbCBiZSBzZXQgb25lcyB0aGUgZWRpdG9yIGlzIGZvY3VzZWQKCQkJCX0KCQkJfQoKCQkJLy8gSUUgbmVlZHMgdG8gdXNlIGNvbnRlbnRFZGl0YWJsZSBvciBpdCB3aWxsIGRpc3BsYXkgbm9uIHNlY3VyZSBpdGVtcyBmb3IgSFRUUFMKCQkJaWYgKGlzSUUpIHsKCQkJCS8vIEl0IHdpbGwgbm90IHN0ZWFsIGZvY3VzIGlmIHdlIGhpZGUgaXQgd2hpbGUgc2V0dGluZyBjb250ZW50RWRpdGFibGUKCQkJCWIgPSB0LmdldEJvZHkoKTsKCQkJCURPTS5oaWRlKGIpOwoKCQkJCWlmICghcy5yZWFkb25seSkKCQkJCQliLmNvbnRlbnRFZGl0YWJsZSA9IHRydWU7CgoJCQkJRE9NLnNob3coYik7CgkJCX0KCgkJCS8vIFNldHVwIG9iamVjdHMKCQkJdC5kb20gPSBuZXcgdGlueW1jZS5ET00uRE9NVXRpbHModC5nZXREb2MoKSwgewoJCQkJa2VlcF92YWx1ZXMgOiB0cnVlLAoJCQkJdXJsX2NvbnZlcnRlciA6IHQuY29udmVydFVSTCwKCQkJCXVybF9jb252ZXJ0ZXJfc2NvcGUgOiB0LAoJCQkJaGV4X2NvbG9ycyA6IHMuZm9yY2VfaGV4X3N0eWxlX2NvbG9ycywKCQkJCWNsYXNzX2ZpbHRlciA6IHMuY2xhc3NfZmlsdGVyLAoJCQkJdXBkYXRlX3N0eWxlcyA6IDEsCgkJCQlmaXhfaWVfcGFyYWdyYXBocyA6IDEKCQkJfSk7CgoJCQl0LnNlcmlhbGl6ZXIgPSBuZXcgdGlueW1jZS5kb20uU2VyaWFsaXplcih7CgkJCQllbnRpdHlfZW5jb2RpbmcgOiBzLmVudGl0eV9lbmNvZGluZywKCQkJCWVudGl0aWVzIDogcy5lbnRpdGllcywKCQkJCXZhbGlkX2VsZW1lbnRzIDogcy52ZXJpZnlfaHRtbCA9PT0gZmFsc2UgPyAnKlsqXScgOiBzLnZhbGlkX2VsZW1lbnRzLAoJCQkJZXh0ZW5kZWRfdmFsaWRfZWxlbWVudHMgOiBzLmV4dGVuZGVkX3ZhbGlkX2VsZW1lbnRzLAoJCQkJdmFsaWRfY2hpbGRfZWxlbWVudHMgOiBzLnZhbGlkX2NoaWxkX2VsZW1lbnRzLAoJCQkJaW52YWxpZF9lbGVtZW50cyA6IHMuaW52YWxpZF9lbGVtZW50cywKCQkJCWZpeF90YWJsZV9lbGVtZW50cyA6IHMuZml4X3RhYmxlX2VsZW1lbnRzLAoJCQkJZml4X2xpc3RfZWxlbWVudHMgOiBzLmZpeF9saXN0X2VsZW1lbnRzLAoJCQkJZml4X2NvbnRlbnRfZHVwbGljYXRpb24gOiBzLmZpeF9jb250ZW50X2R1cGxpY2F0aW9uLAoJCQkJY29udmVydF9mb250c190b19zcGFucyA6IHMuY29udmVydF9mb250c190b19zcGFucywKCQkJCWZvbnRfc2l6ZV9jbGFzc2VzICA6IHMuZm9udF9zaXplX2NsYXNzZXMsCgkJCQlmb250X3NpemVfc3R5bGVfdmFsdWVzIDogcy5mb250X3NpemVfc3R5bGVfdmFsdWVzLAoJCQkJYXBwbHlfc291cmNlX2Zvcm1hdHRpbmcgOiBzLmFwcGx5X3NvdXJjZV9mb3JtYXR0aW5nLAoJCQkJcmVtb3ZlX2xpbmVicmVha3MgOiBzLnJlbW92ZV9saW5lYnJlYWtzLAoJCQkJZWxlbWVudF9mb3JtYXQgOiBzLmVsZW1lbnRfZm9ybWF0LAoJCQkJZG9tIDogdC5kb20KCQkJfSk7CgoJCQl0LnNlbGVjdGlvbiA9IG5ldyB0aW55bWNlLmRvbS5TZWxlY3Rpb24odC5kb20sIHQuZ2V0V2luKCksIHQuc2VyaWFsaXplcik7CgkJCXQuZm9yY2VCbG9ja3MgPSBuZXcgdGlueW1jZS5Gb3JjZUJsb2Nrcyh0LCB7CgkJCQlmb3JjZWRfcm9vdF9ibG9jayA6IHMuZm9yY2VkX3Jvb3RfYmxvY2sKCQkJfSk7CgkJCXQuZWRpdG9yQ29tbWFuZHMgPSBuZXcgdGlueW1jZS5FZGl0b3JDb21tYW5kcyh0KTsKCgkJCS8vIFBhc3MgdGhyb3VnaAoJCQl0LnNlcmlhbGl6ZXIub25QcmVQcm9jZXNzLmFkZChmdW5jdGlvbihzZSwgbykgewoJCQkJcmV0dXJuIHQub25QcmVQcm9jZXNzLmRpc3BhdGNoKHQsIG8sIHNlKTsKCQkJfSk7CgoJCQl0LnNlcmlhbGl6ZXIub25Qb3N0UHJvY2Vzcy5hZGQoZnVuY3Rpb24oc2UsIG8pIHsKCQkJCXJldHVybiB0Lm9uUG9zdFByb2Nlc3MuZGlzcGF0Y2godCwgbywgc2UpOwoJCQl9KTsKCgkJCXQub25QcmVJbml0LmRpc3BhdGNoKHQpOwoKCQkJaWYgKCFzLmdlY2tvX3NwZWxsY2hlY2spCgkJCQl0LmdldEJvZHkoKS5zcGVsbGNoZWNrID0gMDsKCgkJCWlmICghcy5yZWFkb25seSkKCQkJCXQuX2FkZEV2ZW50cygpOwoKCQkJdC5jb250cm9sTWFuYWdlci5vblBvc3RSZW5kZXIuZGlzcGF0Y2godCwgdC5jb250cm9sTWFuYWdlcik7CgkJCXQub25Qb3N0UmVuZGVyLmRpc3BhdGNoKHQpOwogICAgICAgICAgICBBSlMubG9nKCJFZGl0b3I6c2V0dXBJZnJhbWUgYWZ0ZXIgcG9zdCByZW5kZXIiKTsKCgkJCWlmIChzLmRpcmVjdGlvbmFsaXR5KQoJCQkJdC5nZXRCb2R5KCkuZGlyID0gcy5kaXJlY3Rpb25hbGl0eTsKCgkJCWlmIChzLm5vd3JhcCkKCQkJCXQuZ2V0Qm9keSgpLnN0eWxlLndoaXRlU3BhY2UgPSAibm93cmFwIjsKCgkJCWlmIChzLmN1c3RvbV9lbGVtZW50cykgewoJCQkJZnVuY3Rpb24gaGFuZGxlQ3VzdG9tKGVkLCBvKSB7CgkJCQkJZWFjaChleHBsb2RlKHMuY3VzdG9tX2VsZW1lbnRzKSwgZnVuY3Rpb24odikgewoJCQkJCQl2YXIgbjsKCgkJCQkJCWlmICh2LmluZGV4T2YoJ34nKSA9PT0gMCkgewoJCQkJCQkJdiA9IHYuc3Vic3RyaW5nKDEpOwoJCQkJCQkJbiA9ICdzcGFuJzsKCQkJCQkJfSBlbHNlCgkJCQkJCQluID0gJ2Rpdic7CgoJCQkJCQlvLmNvbnRlbnQgPSBvLmNvbnRlbnQucmVwbGFjZShuZXcgUmVnRXhwKCc8KCcgKyB2ICsgJykoW14+XSopPicsICdnJyksICc8JyArIG4gKyAnIG1jZV9uYW1lPSIkMSIkMj4nKTsKCQkJCQkJby5jb250ZW50ID0gby5jb250ZW50LnJlcGxhY2UobmV3IFJlZ0V4cCgnPC8oJyArIHYgKyAnKT4nLCAnZycpLCAnPC8nICsgbiArICc+Jyk7CgkJCQkJfSk7CgkJCQl9OwoKCQkJCXQub25CZWZvcmVTZXRDb250ZW50LmFkZChoYW5kbGVDdXN0b20pOwoJCQkJdC5vblBvc3RQcm9jZXNzLmFkZChmdW5jdGlvbihlZCwgbykgewoJCQkJCWlmIChvLnNldCkKCQkJCQkJaGFuZGxlQ3VzdG9tKGVkLCBvKTsKCQkJCX0pOwoJCQl9CgoJCQlpZiAocy5oYW5kbGVfbm9kZV9jaGFuZ2VfY2FsbGJhY2spIHsKCQkJCXQub25Ob2RlQ2hhbmdlLmFkZChmdW5jdGlvbihlZCwgY20sIG4pIHsKCQkJCQl0LmV4ZWNDYWxsYmFjaygnaGFuZGxlX25vZGVfY2hhbmdlX2NhbGxiYWNrJywgdC5pZCwgbiwgLTEsIC0xLCB0cnVlLCB0LnNlbGVjdGlvbi5pc0NvbGxhcHNlZCgpKTsKCQkJCX0pOwoJCQl9CgoJCQlpZiAocy5zYXZlX2NhbGxiYWNrKSB7CgkJCQl0Lm9uU2F2ZUNvbnRlbnQuYWRkKGZ1bmN0aW9uKGVkLCBvKSB7CgkJCQkJdmFyIGggPSB0LmV4ZWNDYWxsYmFjaygnc2F2ZV9jYWxsYmFjaycsIHQuaWQsIG8uY29udGVudCwgdC5nZXRCb2R5KCkpOwoKCQkJCQlpZiAoaCkKCQkJCQkJby5jb250ZW50ID0gaDsKCQkJCX0pOwoJCQl9CgoJCQlpZiAocy5vbmNoYW5nZV9jYWxsYmFjaykgewoJCQkJdC5vbkNoYW5nZS5hZGQoZnVuY3Rpb24oZWQsIGwpIHsKCQkJCQl0LmV4ZWNDYWxsYmFjaygnb25jaGFuZ2VfY2FsbGJhY2snLCB0LCBsKTsKCQkJCX0pOwoJCQl9CgoJCQlpZiAocy5jb252ZXJ0X25ld2xpbmVzX3RvX2JycykgewoJCQkJdC5vbkJlZm9yZVNldENvbnRlbnQuYWRkKGZ1bmN0aW9uKGVkLCBvKSB7CgkJCQkJaWYgKG8uaW5pdGlhbCkKCQkJCQkJby5jb250ZW50ID0gby5jb250ZW50LnJlcGxhY2UoL1xyP1xuL2csICc8YnIgLz4nKTsKCQkJCX0pOwoJCQl9CgoJCQlpZiAocy5maXhfbmVzdGluZyAmJiBpc0lFKSB7CgkJCQl0Lm9uQmVmb3JlU2V0Q29udGVudC5hZGQoZnVuY3Rpb24oZWQsIG8pIHsKCQkJCQlvLmNvbnRlbnQgPSB0Ll9maXhOZXN0aW5nKG8uY29udGVudCk7CgkJCQl9KTsKCQkJfQoKCQkJaWYgKHMucHJlZm9ybWF0dGVkKSB7CgkJCQl0Lm9uUG9zdFByb2Nlc3MuYWRkKGZ1bmN0aW9uKGVkLCBvKSB7CgkJCQkJby5jb250ZW50ID0gby5jb250ZW50LnJlcGxhY2UoL15ccyo8cHJlLio/Pi8sICcnKTsKCQkJCQlvLmNvbnRlbnQgPSBvLmNvbnRlbnQucmVwbGFjZSgvPFwvcHJlPlxzKiQvLCAnJyk7CgoJCQkJCWlmIChvLnNldCkKCQkJCQkJby5jb250ZW50ID0gJzxwcmUgY2xhc3M9Im1jZUl0ZW1IaWRkZW4iPicgKyBvLmNvbnRlbnQgKyAnPC9wcmU+JzsKCQkJCX0pOwoJCQl9CgoJCQlpZiAocy52ZXJpZnlfY3NzX2NsYXNzZXMpIHsKCQkJCXQuc2VyaWFsaXplci5hdHRyaWJWYWx1ZUZpbHRlciA9IGZ1bmN0aW9uKG4sIHYpIHsKCQkJCQl2YXIgcywgY2w7CgoJCQkJCWlmIChuID09ICdjbGFzcycpIHsKCQkJCQkJLy8gQnVpbGQgcmVnZXhwIGZvciBjbGFzc2VzCgkJCQkJCWlmICghdC5jbGFzc2VzUkUpIHsKCQkJCQkJCWNsID0gdC5kb20uZ2V0Q2xhc3NlcygpOwoKCQkJCQkJCWlmIChjbC5sZW5ndGggPiAwKSB7CgkJCQkJCQkJcyA9ICcnOwoKCQkJCQkJCQllYWNoIChjbCwgZnVuY3Rpb24obykgewoJCQkJCQkJCQlzICs9IChzID8gJ3wnIDogJycpICsgb1snY2xhc3MnXTsKCQkJCQkJCQl9KTsKCgkJCQkJCQkJdC5jbGFzc2VzUkUgPSBuZXcgUmVnRXhwKCcoJyArIHMgKyAnKScsICdnaScpOwoJCQkJCQkJfQoJCQkJCQl9CgoJCQkJCQlyZXR1cm4gIXQuY2xhc3Nlc1JFIHx8IC8oXGJtY2VJdGVtXHcrXGJ8XGJtY2VUZW1wXHcrXGIpL2cudGVzdCh2KSB8fCB0LmNsYXNzZXNSRS50ZXN0KHYpID8gdiA6ICcnOwoJCQkJCX0KCgkJCQkJcmV0dXJuIHY7CgkJCQl9OwoJCQl9CgoJCQlpZiAocy5jb252ZXJ0X2ZvbnRzX3RvX3NwYW5zKQoJCQkJdC5fY29udmVydEZvbnRzKCk7CgoJCQlpZiAocy5pbmxpbmVfc3R5bGVzKQoJCQkJdC5fY29udmVydElubGluZUVsZW1lbnRzKCk7CgoJCQlpZiAocy5jbGVhbnVwX2NhbGxiYWNrKSB7CgkJCQl0Lm9uQmVmb3JlU2V0Q29udGVudC5hZGQoZnVuY3Rpb24oZWQsIG8pIHsKCQkJCQlvLmNvbnRlbnQgPSB0LmV4ZWNDYWxsYmFjaygnY2xlYW51cF9jYWxsYmFjaycsICdpbnNlcnRfdG9fZWRpdG9yJywgby5jb250ZW50LCBvKTsKCQkJCX0pOwoKCQkJCXQub25QcmVQcm9jZXNzLmFkZChmdW5jdGlvbihlZCwgbykgewoJCQkJCWlmIChvLnNldCkKCQkJCQkJdC5leGVjQ2FsbGJhY2soJ2NsZWFudXBfY2FsbGJhY2snLCAnaW5zZXJ0X3RvX2VkaXRvcl9kb20nLCBvLm5vZGUsIG8pOwoKCQkJCQlpZiAoby5nZXQpCgkJCQkJCXQuZXhlY0NhbGxiYWNrKCdjbGVhbnVwX2NhbGxiYWNrJywgJ2dldF9mcm9tX2VkaXRvcl9kb20nLCBvLm5vZGUsIG8pOwoJCQkJfSk7CgoJCQkJdC5vblBvc3RQcm9jZXNzLmFkZChmdW5jdGlvbihlZCwgbykgewoJCQkJCWlmIChvLnNldCkKCQkJCQkJby5jb250ZW50ID0gdC5leGVjQ2FsbGJhY2soJ2NsZWFudXBfY2FsbGJhY2snLCAnaW5zZXJ0X3RvX2VkaXRvcicsIG8uY29udGVudCwgbyk7CgoJCQkJCWlmIChvLmdldCkKCQkJCQkJby5jb250ZW50ID0gdC5leGVjQ2FsbGJhY2soJ2NsZWFudXBfY2FsbGJhY2snLCAnZ2V0X2Zyb21fZWRpdG9yJywgby5jb250ZW50LCBvKTsKCQkJCX0pOwoJCQl9CgoJCQlpZiAocy5zYXZlX2NhbGxiYWNrKSB7CgkJCQl0Lm9uR2V0Q29udGVudC5hZGQoZnVuY3Rpb24oZWQsIG8pIHsKCQkJCQlpZiAoby5zYXZlKQoJCQkJCQlvLmNvbnRlbnQgPSB0LmV4ZWNDYWxsYmFjaygnc2F2ZV9jYWxsYmFjaycsIHQuaWQsIG8uY29udGVudCwgdC5nZXRCb2R5KCkpOwoJCQkJfSk7CgkJCX0KCgkJCWlmIChzLmhhbmRsZV9ldmVudF9jYWxsYmFjaykgewoJCQkJdC5vbkV2ZW50LmFkZChmdW5jdGlvbihlZCwgZSwgbykgewoJCQkJCWlmICh0LmV4ZWNDYWxsYmFjaygnaGFuZGxlX2V2ZW50X2NhbGxiYWNrJywgZSwgZWQsIG8pID09PSBmYWxzZSkKCQkJCQkJRXZlbnQuY2FuY2VsKGUpOwoJCQkJfSk7CgkJCX0KCgkJCS8vIEFkZCB2aXN1YWwgYWlkcyB3aGVuIG5ldyBjb250ZW50cyBpcyBhZGRlZAoJCQl0Lm9uU2V0Q29udGVudC5hZGQoZnVuY3Rpb24oKSB7CgkJCQl0LmFkZFZpc3VhbCh0LmdldEJvZHkoKSk7CgkJCX0pOwoKCQkJLy8gUmVtb3ZlIGVtcHR5IGNvbnRlbnRzCgkJCWlmIChzLnBhZGRfZW1wdHlfZWRpdG9yKSB7CgkJCQl0Lm9uUG9zdFByb2Nlc3MuYWRkKGZ1bmN0aW9uKGVkLCBvKSB7CgkJCQkJby5jb250ZW50ID0gby5jb250ZW50LnJlcGxhY2UoL14oPHBbXj5dKj4oJm5ic3A7fCYjMTYwO3xcc3xcdTAwYTB8KTxcL3A+W1xyXG5dKnw8YnIgXC8+W1xyXG5dKikkLywgJycpOwoJCQkJfSk7CgkJCX0KCgkJCWlmIChpc0dlY2tvKSB7CgkJCQkvLyBGaXggZ2Vja28gbGluayBidWcsIHdoZW4gYSBsaW5rIGlzIHBsYWNlZCBhdCB0aGUgZW5kIG9mIGJsb2NrIGVsZW1lbnRzIHRoZXJlIGlzCgkJCQkvLyBubyB3YXkgdG8gbW92ZSB0aGUgY2FyZXQgYmVoaW5kIHRoZSBsaW5rLiBUaGlzIGZpeCBhZGRzIGEgYm9ndXMgYnIgZWxlbWVudCBhZnRlciB0aGUgbGluawoJCQkJZnVuY3Rpb24gZml4TGlua3MoZWQsIG8pIHsKCQkJCQllYWNoKGVkLmRvbS5zZWxlY3QoJ2EnKSwgZnVuY3Rpb24obikgewoJCQkJCQl2YXIgcG4gPSBuLnBhcmVudE5vZGU7CgoJCQkJCQlpZiAoZWQuZG9tLmlzQmxvY2socG4pICYmIHBuLmxhc3RDaGlsZCA9PT0gbikKCQkJCQkJCWVkLmRvbS5hZGQocG4sICdicicsIHsnbWNlX2JvZ3VzJyA6IDF9KTsKCQkJCQl9KTsKCQkJCX07CgoJCQkJdC5vbkV4ZWNDb21tYW5kLmFkZChmdW5jdGlvbihlZCwgY21kKSB7CgkJCQkJaWYgKGNtZCA9PT0gJ0NyZWF0ZUxpbmsnKQoJCQkJCQlmaXhMaW5rcyhlZCk7CgkJCQl9KTsKCgkJCQl0Lm9uU2V0Q29udGVudC5hZGQodC5zZWxlY3Rpb24ub25TZXRDb250ZW50LmFkZChmaXhMaW5rcykpOwoKCQkJCWlmICghcy5yZWFkb25seSkgewoJCQkJCXRyeSB7CgkJCQkJCS8vIERlc2lnbiBtb2RlIG11c3QgYmUgc2V0IGhlcmUgb25jZSBhZ2FpbiB0byBmaXggYSBidWcgd2hlcmUKCQkJCQkJLy8gQ3RybCtBL0RlbGV0ZS9CYWNrc3BhY2UgZGlkbid0IHdvcmsgaWYgdGhlIGVkaXRvciB3YXMgYWRkZWQgdXNpbmcgbWNlQWRkQ29udHJvbCB0aGVuIHJlbW92ZWQgdGhlbiBhZGRlZCBhZ2FpbgoJCQkJCQlkLmRlc2lnbk1vZGUgPSAnT2ZmJzsKCQkJCQkJZC5kZXNpZ25Nb2RlID0gJ09uJzsKCQkJCQl9IGNhdGNoIChleCkgewoJCQkJCQkvLyBXaWxsIGZhaWwgb24gR2Vja28gaWYgdGhlIGVkaXRvciBpcyBwbGFjZWQgaW4gYW4gaGlkZGVuIGNvbnRhaW5lciBlbGVtZW50CgkJCQkJCS8vIFRoZSBkZXNpZ24gbW9kZSB3aWxsIGJlIHNldCBvbmVzIHRoZSBlZGl0b3IgaXMgZm9jdXNlZAoJCQkJCX0KCQkJCX0KCQkJfQovLyBBVExBU1NJQU4gLSBzZWVtcyB0byB3b3JrIGZpbmUgaW4gRkYsIHJlbW92aW5nIHNldFRpbWVvdXQgaW1wcm92ZXMgcGVyZm9ybWFuY2UgaW4gSUUKCQkJLy8gQSBzbWFsbCB0aW1lb3V0IHdhcyBuZWVkZWQgc2luY2UgZmlyZWZveCB3aWxsIHJlbW92ZS4gQnVnOiAjMTgzODMwNAovLwkJCXNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewoJCQkJaWYgKHQucmVtb3ZlZCkKCQkJCQlyZXR1cm47CgogICAgICAgICAgICAgICAgLy8gQVRMQVNTSUFOIC0gd2UgbmVlZCBhbiBldmVudCBob29rIHdoZXJlIHRoZSBFZGl0b3IgZXhpc3RzIGJ1dCBpcyBub3QgeWV0IGluaXRpYWxpemVkCiAgICAgICAgICAgICAgICBBSlMubG9nKCJBSlMuRWRpdG9yLkFkYXB0ZXIub25TZXRDb250ZW50IGF0dGFjaGVkIHRvIEVkaXRvci5vblNldENvbnRlbnQiKTsKICAgICAgICAgICAgICAgIHQub25TZXRDb250ZW50LmFkZFRvVG9wKEFKUy5FZGl0b3IuQWRhcHRlci5vblNldENvbnRlbnQpOwoKCQkJCXQubG9hZCh7aW5pdGlhbCA6IHRydWUsIGZvcm1hdCA6IChzLmNsZWFudXBfb25fc3RhcnR1cCA/ICdodG1sJyA6ICdyYXcnKX0pOwoJCQkJdC5zdGFydENvbnRlbnQgPSB0LmdldENvbnRlbnQoe2Zvcm1hdCA6ICdyYXcnfSk7CgkJCQl0LnVuZG9NYW5hZ2VyLmFkZCh7aW5pdGlhbCA6IHRydWV9KTsKCQkJCXQuaW5pdGlhbGl6ZWQgPSB0cnVlOwoKCQkJCXQub25Jbml0LmRpc3BhdGNoKHQpOwoJCQkJdC5leGVjQ2FsbGJhY2soJ3NldHVwY29udGVudF9jYWxsYmFjaycsIHQuaWQsIHQuZ2V0Qm9keSgpLCB0LmdldERvYygpKTsKCQkJCXQuZXhlY0NhbGxiYWNrKCdpbml0X2luc3RhbmNlX2NhbGxiYWNrJywgdCk7CgkJCQl0LmZvY3VzKHRydWUpOwoJCQkJdC5ub2RlQ2hhbmdlZCh7aW5pdGlhbCA6IDF9KTsKCgkJCQkvLyBMb2FkIHNwZWNpZmllZCBjb250ZW50IENTUyBsYXN0CgkJCQlpZiAocy5jb250ZW50X2NzcykgewoJCQkJCXRpbnltY2UuZWFjaChleHBsb2RlKHMuY29udGVudF9jc3MpLCBmdW5jdGlvbih1KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEFKUy5sb2coIkFib3V0IHRvIGxvYWQgY29udGVudCBjc3M6ICIgKyB0LmRvY3VtZW50QmFzZVVSSS50b0Fic29sdXRlKHUpKTsKCQkJCQkJdC5kb20ubG9hZENTUyh0LmRvY3VtZW50QmFzZVVSSS50b0Fic29sdXRlKHUpKTsKCQkJCQl9KTsKCQkJCX0KCgkJCQkvLyBIYW5kbGUgYXV0byBmb2N1cwoJCQkJaWYgKHMuYXV0b19mb2N1cykgewoJCQkJCXNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewoJCQkJCQl2YXIgZWQgPSBFZGl0b3JNYW5hZ2VyLmdldChzLmF1dG9fZm9jdXMpOwoKCQkJCQkJZWQuc2VsZWN0aW9uLnNlbGVjdChlZC5nZXRCb2R5KCksIDEpOwoJCQkJCQllZC5zZWxlY3Rpb24uY29sbGFwc2UoMSk7CgkJCQkJCWVkLmdldFdpbigpLmZvY3VzKCk7CgkJCQkJfSwgMTAwKTsKCQkJCX0KLy8JCQl9LCAxKTsKCQoJCQllID0gbnVsbDsKCQl9LAoKCgkJZm9jdXMgOiBmdW5jdGlvbihzZikgewoJCQl2YXIgb2VkLCB0ID0gdGhpcywgY2UgPSB0LnNldHRpbmdzLmNvbnRlbnRfZWRpdGFibGU7CgoJCQlpZiAoIXNmKSB7CgkJCQkvLyBJcyBub3QgY29udGVudCBlZGl0YWJsZSBvciB0aGUgc2VsZWN0aW9uIGlzIG91dHNpZGUgdGhlIGFyZWEgaW4gSUUKCQkJCS8vIHRoZSBJRSBzdGF0ZW1lbnQgaXMgbmVlZGVkIHRvIGF2b2lkIGJsdXJpbmcgaWYgZWxlbWVudCBzZWxlY3Rpb25zIGluc2lkZSBsYXllcnMgc2luY2UKCQkJCS8vIHRoZSBsYXllciBpcyBsaWtlIGl0J3Mgb3duIGRvY3VtZW50IGluIElFCgkJCQlpZiAoIWNlICYmICghaXNJRSB8fCB0LnNlbGVjdGlvbi5nZXROb2RlKCkub3duZXJEb2N1bWVudCAhPSB0LmdldERvYygpKSkKCQkJCQl0LmdldFdpbigpLmZvY3VzKCk7CgoJCQl9CgoJCQlpZiAoRWRpdG9yTWFuYWdlci5hY3RpdmVFZGl0b3IgIT0gdCkgewoJCQkJaWYgKChvZWQgPSBFZGl0b3JNYW5hZ2VyLmFjdGl2ZUVkaXRvcikgIT0gbnVsbCkKCQkJCQlvZWQub25EZWFjdGl2YXRlLmRpc3BhdGNoKG9lZCwgdCk7CgoJCQkJdC5vbkFjdGl2YXRlLmRpc3BhdGNoKHQsIG9lZCk7CgkJCX0KCgkJCUVkaXRvck1hbmFnZXIuX3NldEFjdGl2ZSh0KTsKCQl9LAoKCQlleGVjQ2FsbGJhY2sgOiBmdW5jdGlvbihuKSB7CgkJCXZhciB0ID0gdGhpcywgZiA9IHQuc2V0dGluZ3Nbbl0sIHM7CgoJCQlpZiAoIWYpCgkJCQlyZXR1cm47CgoJCQkvLyBMb29rIHRocm91Z2ggbG9va3VwCgkJCWlmICh0LmNhbGxiYWNrTG9va3VwICYmIChzID0gdC5jYWxsYmFja0xvb2t1cFtuXSkpIHsKCQkJCWYgPSBzLmZ1bmM7CgkJCQlzID0gcy5zY29wZTsKCQkJfQoKCQkJaWYgKGlzKGYsICdzdHJpbmcnKSkgewoJCQkJcyA9IGYucmVwbGFjZSgvXC5cdyskLywgJycpOwoJCQkJcyA9IHMgPyB0aW55bWNlLnJlc29sdmUocykgOiAwOwoJCQkJZiA9IHRpbnltY2UucmVzb2x2ZShmKTsKCQkJCXQuY2FsbGJhY2tMb29rdXAgPSB0LmNhbGxiYWNrTG9va3VwIHx8IHt9OwoJCQkJdC5jYWxsYmFja0xvb2t1cFtuXSA9IHtmdW5jIDogZiwgc2NvcGUgOiBzfTsKCQkJfQoKCQkJcmV0dXJuIGYuYXBwbHkocyB8fCB0LCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKTsKCQl9LAoKCQl0cmFuc2xhdGUgOiBmdW5jdGlvbihzKSB7CgkJCXZhciBjID0gdGhpcy5zZXR0aW5ncy5sYW5ndWFnZSB8fCAnZW4nLCBpMThuID0gRWRpdG9yTWFuYWdlci5pMThuOwoKCQkJaWYgKCFzKQoJCQkJcmV0dXJuICcnOwoKCQkJcmV0dXJuIGkxOG5bYyArICcuJyArIHNdIHx8IHMucmVwbGFjZSgve1wjKFtefV0rKVx9L2csIGZ1bmN0aW9uKGEsIGIpIHsKCQkJCXJldHVybiBpMThuW2MgKyAnLicgKyBiXSB8fCAneyMnICsgYiArICd9JzsKCQkJfSk7CgkJfSwKCgkJZ2V0TGFuZyA6IGZ1bmN0aW9uKG4sIGR2KSB7CgkJCXJldHVybiBFZGl0b3JNYW5hZ2VyLmkxOG5bKHRoaXMuc2V0dGluZ3MubGFuZ3VhZ2UgfHwgJ2VuJykgKyAnLicgKyBuXSB8fCAoaXMoZHYpID8gZHYgOiAneyMnICsgbiArICd9Jyk7CgkJfSwKCgkJZ2V0UGFyYW0gOiBmdW5jdGlvbihuLCBkdiwgdHkpIHsKCQkJdmFyIHRyID0gdGlueW1jZS50cmltLCB2ID0gaXModGhpcy5zZXR0aW5nc1tuXSkgPyB0aGlzLnNldHRpbmdzW25dIDogZHYsIG87CgoJCQlpZiAodHkgPT09ICdoYXNoJykgewoJCQkJbyA9IHt9OwoKCQkJCWlmIChpcyh2LCAnc3RyaW5nJykpIHsKCQkJCQllYWNoKHYuaW5kZXhPZignPScpID4gMCA/IHYuc3BsaXQoL1s7LF0oPyFbXj07LF0qKD86WzssXXwkKSkvKSA6IHYuc3BsaXQoJywnKSwgZnVuY3Rpb24odikgewoJCQkJCQl2ID0gdi5zcGxpdCgnPScpOwoKCQkJCQkJaWYgKHYubGVuZ3RoID4gMSkKCQkJCQkJCW9bdHIodlswXSldID0gdHIodlsxXSk7CgkJCQkJCWVsc2UKCQkJCQkJCW9bdHIodlswXSldID0gdHIodik7CgkJCQkJfSk7CgkJCQl9IGVsc2UKCQkJCQlvID0gdjsKCgkJCQlyZXR1cm4gbzsKCQkJfQoKCQkJcmV0dXJuIHY7CgkJfSwKCgkJbm9kZUNoYW5nZWQgOiBmdW5jdGlvbihvKSB7CgkJCXZhciB0ID0gdGhpcywgcyA9IHQuc2VsZWN0aW9uLCBuID0gcy5nZXROb2RlKCkgfHwgdC5nZXRCb2R5KCk7CgoJCQkvLyBGaXggZm9yIGJ1ZyAjMTg5NjU3NyBpdCBzZWVtcyB0aGF0IHRoaXMgY2FuIG5vdCBiZSBmaXJlZCB3aGlsZSB0aGUgZWRpdG9yIGlzIGxvYWRpbmcKCQkJaWYgKHQuaW5pdGlhbGl6ZWQpIHsKCQkJCXQub25Ob2RlQ2hhbmdlLmRpc3BhdGNoKAoJCQkJCXQsCgkJCQkJbyA/IG8uY29udHJvbE1hbmFnZXIgfHwgdC5jb250cm9sTWFuYWdlciA6IHQuY29udHJvbE1hbmFnZXIsCgkJCQkJaXNJRSAmJiBuLm93bmVyRG9jdW1lbnQgIT0gdC5nZXREb2MoKSA/IHQuZ2V0Qm9keSgpIDogbiwgLy8gRml4IGZvciBJRSBpbml0aWFsIHN0YXRlCgkJCQkJcy5pc0NvbGxhcHNlZCgpLAoJCQkJCW8KCQkJCSk7CgkJCX0KCQl9LAoKCQlhZGRCdXR0b24gOiBmdW5jdGlvbihuLCBzKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXQuYnV0dG9ucyA9IHQuYnV0dG9ucyB8fCB7fTsKCQkJdC5idXR0b25zW25dID0gczsKCQl9LAoKCQlhZGRDb21tYW5kIDogZnVuY3Rpb24obiwgZiwgcykgewoJCQl0aGlzLmV4ZWNDb21tYW5kc1tuXSA9IHtmdW5jIDogZiwgc2NvcGUgOiBzIHx8IHRoaXN9OwoJCX0sCgoJCWFkZFF1ZXJ5U3RhdGVIYW5kbGVyIDogZnVuY3Rpb24obiwgZiwgcykgewoJCQl0aGlzLnF1ZXJ5U3RhdGVDb21tYW5kc1tuXSA9IHtmdW5jIDogZiwgc2NvcGUgOiBzIHx8IHRoaXN9OwoJCX0sCgoJCWFkZFF1ZXJ5VmFsdWVIYW5kbGVyIDogZnVuY3Rpb24obiwgZiwgcykgewoJCQl0aGlzLnF1ZXJ5VmFsdWVDb21tYW5kc1tuXSA9IHtmdW5jIDogZiwgc2NvcGUgOiBzIHx8IHRoaXN9OwoJCX0sCgoJCWFkZFNob3J0Y3V0IDogZnVuY3Rpb24ocGEsIGRlc2MsIGNtZF9mdW5jLCBzYykgewoJCQl2YXIgdCA9IHRoaXMsIGM7CgoJCQlpZiAoIXQuc2V0dGluZ3MuY3VzdG9tX3Nob3J0Y3V0cykKCQkJCXJldHVybiBmYWxzZTsKCgkJCXQuc2hvcnRjdXRzID0gdC5zaG9ydGN1dHMgfHwge307CgoJCQlpZiAoaXMoY21kX2Z1bmMsICdzdHJpbmcnKSkgewoJCQkJYyA9IGNtZF9mdW5jOwoKCQkJCWNtZF9mdW5jID0gZnVuY3Rpb24oKSB7CgkJCQkJdC5leGVjQ29tbWFuZChjLCBmYWxzZSwgbnVsbCk7CgkJCQl9OwoJCQl9CgoJCQlpZiAoaXMoY21kX2Z1bmMsICdvYmplY3QnKSkgewoJCQkJYyA9IGNtZF9mdW5jOwoKCQkJCWNtZF9mdW5jID0gZnVuY3Rpb24oKSB7CgkJCQkJdC5leGVjQ29tbWFuZChjWzBdLCBjWzFdLCBjWzJdKTsKCQkJCX07CgkJCX0KCgkJCWVhY2goZXhwbG9kZShwYSksIGZ1bmN0aW9uKHBhKSB7CgkJCQl2YXIgbyA9IHsKCQkJCQlmdW5jIDogY21kX2Z1bmMsCgkJCQkJc2NvcGUgOiBzYyB8fCB0aGlzLAoJCQkJCWRlc2MgOiBkZXNjLAoJCQkJCWFsdCA6IGZhbHNlLAoJCQkJCWN0cmwgOiBmYWxzZSwKCQkJCQlzaGlmdCA6IGZhbHNlCgkJCQl9OwoKCQkJCWVhY2goZXhwbG9kZShwYSwgJysnKSwgZnVuY3Rpb24odikgewoJCQkJCXN3aXRjaCAodikgewoJCQkJCQljYXNlICdhbHQnOgoJCQkJCQljYXNlICdjdHJsJzoKCQkJCQkJY2FzZSAnc2hpZnQnOgoJCQkJCQkJb1t2XSA9IHRydWU7CgkJCQkJCQlicmVhazsKCgkJCQkJCWRlZmF1bHQ6CgkJCQkJCQlvLmNoYXJDb2RlID0gdi5jaGFyQ29kZUF0KDApOwoJCQkJCQkJby5rZXlDb2RlID0gdi50b1VwcGVyQ2FzZSgpLmNoYXJDb2RlQXQoMCk7CgkJCQkJfQoJCQkJfSk7CgoJCQkJdC5zaG9ydGN1dHNbKG8uY3RybCA/ICdjdHJsJyA6ICcnKSArICcsJyArIChvLmFsdCA/ICdhbHQnIDogJycpICsgJywnICsgKG8uc2hpZnQgPyAnc2hpZnQnIDogJycpICsgJywnICsgby5rZXlDb2RlXSA9IG87CgkJCX0pOwoKCQkJcmV0dXJuIHRydWU7CgkJfSwKCgkJZXhlY0NvbW1hbmQgOiBmdW5jdGlvbihjbWQsIHVpLCB2YWwsIGEpIHsKCQkJdmFyIHQgPSB0aGlzLCBzID0gMCwgbywgc3Q7CgoJCQlpZiAoIS9eKG1jZUFkZFVuZG9MZXZlbHxtY2VFbmRVbmRvTGV2ZWx8bWNlQmVnaW5VbmRvTGV2ZWx8bWNlUmVwYWludHxTZWxlY3RBbGwpJC8udGVzdChjbWQpICYmICghYSB8fCAhYS5za2lwX2ZvY3VzKSkKCQkJCXQuZm9jdXMoKTsKCgkJCW8gPSB7fTsKCQkJdC5vbkJlZm9yZUV4ZWNDb21tYW5kLmRpc3BhdGNoKHQsIGNtZCwgdWksIHZhbCwgbyk7CgkJCWlmIChvLnRlcm1pbmF0ZSkKCQkJCXJldHVybiBmYWxzZTsKCgkJCS8vIENvbW1hbmQgY2FsbGJhY2sKCQkJaWYgKHQuZXhlY0NhbGxiYWNrKCdleGVjY29tbWFuZF9jYWxsYmFjaycsIHQuaWQsIHQuc2VsZWN0aW9uLmdldE5vZGUoKSwgY21kLCB1aSwgdmFsKSkgewoJCQkJdC5vbkV4ZWNDb21tYW5kLmRpc3BhdGNoKHQsIGNtZCwgdWksIHZhbCwgYSk7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoKCQkJLy8gUmVnaXN0cmVkIGNvbW1hbmRzCgkJCWlmIChvID0gdC5leGVjQ29tbWFuZHNbY21kXSkgewoJCQkJc3QgPSBvLmZ1bmMuY2FsbChvLnNjb3BlLCB1aSwgdmFsKTsKCgkJCQkvLyBGYWxsIHRocm91Z2ggb24gdHJ1ZQoJCQkJaWYgKHN0ICE9PSB0cnVlKSB7CgkJCQkJdC5vbkV4ZWNDb21tYW5kLmRpc3BhdGNoKHQsIGNtZCwgdWksIHZhbCwgYSk7CgkJCQkJcmV0dXJuIHN0OwoJCQkJfQoJCQl9CgoJCQkvLyBQbHVnaW4gY29tbWFuZHMKCQkJZWFjaCh0LnBsdWdpbnMsIGZ1bmN0aW9uKHApIHsKCQkJCWlmIChwLmV4ZWNDb21tYW5kICYmIHAuZXhlY0NvbW1hbmQoY21kLCB1aSwgdmFsKSkgewoJCQkJCXQub25FeGVjQ29tbWFuZC5kaXNwYXRjaCh0LCBjbWQsIHVpLCB2YWwsIGEpOwoJCQkJCXMgPSAxOwoJCQkJCXJldHVybiBmYWxzZTsKCQkJCX0KCQkJfSk7CgoJCQlpZiAocykKCQkJCXJldHVybiB0cnVlOwoKCQkJLy8gVGhlbWUgY29tbWFuZHMKCQkJaWYgKHQudGhlbWUgJiYgdC50aGVtZS5leGVjQ29tbWFuZCAmJiB0LnRoZW1lLmV4ZWNDb21tYW5kKGNtZCwgdWksIHZhbCkpIHsKCQkJCXQub25FeGVjQ29tbWFuZC5kaXNwYXRjaCh0LCBjbWQsIHVpLCB2YWwsIGEpOwoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCgkJCS8vIEV4ZWN1dGUgZ2xvYmFsIGNvbW1hbmRzCgkJCWlmICh0aW55bWNlLkdsb2JhbENvbW1hbmRzLmV4ZWNDb21tYW5kKHQsIGNtZCwgdWksIHZhbCkpIHsKCQkJCXQub25FeGVjQ29tbWFuZC5kaXNwYXRjaCh0LCBjbWQsIHVpLCB2YWwsIGEpOwoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCgkJCS8vIEVkaXRvciBjb21tYW5kcwoJCQlpZiAodC5lZGl0b3JDb21tYW5kcy5leGVjQ29tbWFuZChjbWQsIHVpLCB2YWwpKSB7CgkJCQl0Lm9uRXhlY0NvbW1hbmQuZGlzcGF0Y2godCwgY21kLCB1aSwgdmFsLCBhKTsKCQkJCXJldHVybiB0cnVlOwoJCQl9CgoJCQkvLyBCcm93c2VyIGNvbW1hbmRzCgkJCXQuZ2V0RG9jKCkuZXhlY0NvbW1hbmQoY21kLCB1aSwgdmFsKTsKCQkJdC5vbkV4ZWNDb21tYW5kLmRpc3BhdGNoKHQsIGNtZCwgdWksIHZhbCwgYSk7CgkJfSwKCgkJcXVlcnlDb21tYW5kU3RhdGUgOiBmdW5jdGlvbihjKSB7CgkJCXZhciB0ID0gdGhpcywgbywgczsKCgkJCS8vIElzIGhpZGRlbiB0aGVuIHJldHVybiB1bmRlZmluZWQKCQkJaWYgKHQuX2lzSGlkZGVuKCkpCgkJCQlyZXR1cm47CgoJCQkvLyBSZWdpc3RyZWQgY29tbWFuZHMKCQkJaWYgKG8gPSB0LnF1ZXJ5U3RhdGVDb21tYW5kc1tjXSkgewoJCQkJcyA9IG8uZnVuYy5jYWxsKG8uc2NvcGUpOwoKCQkJCS8vIEZhbGwgdGhvdWdoIG9uIHRydWUKCQkJCWlmIChzICE9PSB0cnVlKQoJCQkJCXJldHVybiBzOwoJCQl9CgoJCQkvLyBSZWdpc3RyZWQgY29tbWFuZHMKCQkJbyA9IHQuZWRpdG9yQ29tbWFuZHMucXVlcnlDb21tYW5kU3RhdGUoYyk7CgkJCWlmIChvICE9PSAtMSkKCQkJCXJldHVybiBvOwoKCQkJLy8gQnJvd3NlciBjb21tYW5kcwoJCQl0cnkgewoJCQkJcmV0dXJuIHRoaXMuZ2V0RG9jKCkucXVlcnlDb21tYW5kU3RhdGUoYyk7CgkJCX0gY2F0Y2ggKGV4KSB7CgkJCQkvLyBGYWlscyBzb21ldGltZXMgc2VlIGJ1ZzogMTg5NjU3NwoJCQl9CgkJfSwKCgkJcXVlcnlDb21tYW5kVmFsdWUgOiBmdW5jdGlvbihjKSB7CgkJCXZhciB0ID0gdGhpcywgbywgczsKCgkJCS8vIElzIGhpZGRlbiB0aGVuIHJldHVybiB1bmRlZmluZWQKCQkJaWYgKHQuX2lzSGlkZGVuKCkpCgkJCQlyZXR1cm47CgoJCQkvLyBSZWdpc3RyZWQgY29tbWFuZHMKCQkJaWYgKG8gPSB0LnF1ZXJ5VmFsdWVDb21tYW5kc1tjXSkgewoJCQkJcyA9IG8uZnVuYy5jYWxsKG8uc2NvcGUpOwoKCQkJCS8vIEZhbGwgdGhvdWdoIG9uIHRydWUKCQkJCWlmIChzICE9PSB0cnVlKQoJCQkJCXJldHVybiBzOwoJCQl9CgoJCQkvLyBSZWdpc3RyZWQgY29tbWFuZHMKCQkJbyA9IHQuZWRpdG9yQ29tbWFuZHMucXVlcnlDb21tYW5kVmFsdWUoYyk7CgkJCWlmIChpcyhvKSkKCQkJCXJldHVybiBvOwoKCQkJLy8gQnJvd3NlciBjb21tYW5kcwoJCQl0cnkgewoJCQkJcmV0dXJuIHRoaXMuZ2V0RG9jKCkucXVlcnlDb21tYW5kVmFsdWUoYyk7CgkJCX0gY2F0Y2ggKGV4KSB7CgkJCQkvLyBGYWlscyBzb21ldGltZXMgc2VlIGJ1ZzogMTg5NjU3NwoJCQl9CgkJfSwKCgkJc2hvdyA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQlET00uc2hvdyh0LmdldENvbnRhaW5lcigpKTsKCQkJRE9NLmhpZGUodC5pZCk7CgkJCXQubG9hZCgpOwoJCX0sCgoJCWhpZGUgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCBkID0gdC5nZXREb2MoKTsKCgkJCS8vIEZpeGVkIGJ1ZyB3aGVyZSBJRSBoYXMgYSBibGlua2luZyBjdXJzb3IgbGVmdCBmcm9tIHRoZSBlZGl0b3IKCQkJaWYgKGlzSUUgJiYgZCkKCQkJCWQuZXhlY0NvbW1hbmQoJ1NlbGVjdEFsbCcpOwoKCQkJLy8gV2UgbXVzdCBzYXZlIGJlZm9yZSB3ZSBoaWRlIHNvIFNhZmFyaSBkb2Vzbid0IGNyYXNoCgkJCXQuc2F2ZSgpOwoJCQlET00uaGlkZSh0LmdldENvbnRhaW5lcigpKTsKCQkJRE9NLnNldFN0eWxlKHQuaWQsICdkaXNwbGF5JywgdC5vcmdEaXNwbGF5KTsKCQl9LAoKCQlpc0hpZGRlbiA6IGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gIURPTS5pc0hpZGRlbih0aGlzLmlkKTsKCQl9LAoKCQlzZXRQcm9ncmVzc1N0YXRlIDogZnVuY3Rpb24oYiwgdGksIG8pIHsKCQkJdGhpcy5vblNldFByb2dyZXNzU3RhdGUuZGlzcGF0Y2godGhpcywgYiwgdGksIG8pOwoKCQkJcmV0dXJuIGI7CgkJfSwKCgkJbG9hZCA6IGZ1bmN0aW9uKG8pIHsKCQkJdmFyIHQgPSB0aGlzLCBlID0gdC5nZXRFbGVtZW50KCksIGg7CgoJCQlpZiAoZSkgewoJCQkJbyA9IG8gfHwge307CgkJCQlvLmxvYWQgPSB0cnVlOwoKCQkJCS8vIERvdWJsZSBlbmNvZGUgZXhpc3RpbmcgZW50aXRpZXMgaW4gdGhlIHZhbHVlCgkJCQloID0gdC5zZXRDb250ZW50KGlzKGUudmFsdWUpID8gZS52YWx1ZSA6IGUuaW5uZXJIVE1MLCBvKTsKCQkJCW8uZWxlbWVudCA9IGU7CgoJCQkJaWYgKCFvLm5vX2V2ZW50cykKCQkJCQl0Lm9uTG9hZENvbnRlbnQuZGlzcGF0Y2godCwgbyk7CgoJCQkJby5lbGVtZW50ID0gZSA9IG51bGw7CgoJCQkJcmV0dXJuIGg7CgkJCX0KCQl9LAoKCQlzYXZlIDogZnVuY3Rpb24obykgewoJCQl2YXIgdCA9IHRoaXMsIGUgPSB0LmdldEVsZW1lbnQoKSwgaCwgZjsKCgkJCWlmICghZSB8fCAhdC5pbml0aWFsaXplZCkKCQkJCXJldHVybjsKCgkJCW8gPSBvIHx8IHt9OwoJCQlvLnNhdmUgPSB0cnVlOwoKCQkJLy8gQWRkIHVuZG8gbGV2ZWwgd2lsbCB0cmlnZ2VyIG9uY2hhbmdlIGV2ZW50CgkJCWlmICghby5ub19ldmVudHMpIHsKCQkJCXQudW5kb01hbmFnZXIudHlwaW5nID0gMDsKCQkJCXQudW5kb01hbmFnZXIuYWRkKCk7CgkJCX0KCgkJCW8uZWxlbWVudCA9IGU7CgkJCWggPSBvLmNvbnRlbnQgPSB0LmdldENvbnRlbnQobyk7CgoJCQlpZiAoIW8ubm9fZXZlbnRzKQoJCQkJdC5vblNhdmVDb250ZW50LmRpc3BhdGNoKHQsIG8pOwoKCQkJaCA9IG8uY29udGVudDsKCgkJCWlmICghL1RFWFRBUkVBfElOUFVUL2kudGVzdChlLm5vZGVOYW1lKSkgewoJCQkJZS5pbm5lckhUTUwgPSBoOwoKCQkJCS8vIFVwZGF0ZSBoaWRkZW4gZm9ybSBlbGVtZW50CgkJCQlpZiAoZiA9IERPTS5nZXRQYXJlbnQodC5pZCwgJ2Zvcm0nKSkgewoJCQkJCWVhY2goZi5lbGVtZW50cywgZnVuY3Rpb24oZSkgewoJCQkJCQlpZiAoZS5uYW1lID09IHQuaWQpIHsKCQkJCQkJCWUudmFsdWUgPSBoOwoJCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCQl9CgkJCQkJfSk7CgkJCQl9CgkJCX0gZWxzZQoJCQkJZS52YWx1ZSA9IGg7CgoJCQlvLmVsZW1lbnQgPSBlID0gbnVsbDsKCgkJCXJldHVybiBoOwoJCX0sCgoJCXNldENvbnRlbnQgOiBmdW5jdGlvbihoLCBvKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCW8gPSBvIHx8IHt9OwoJCQlvLmZvcm1hdCA9IG8uZm9ybWF0IHx8ICdodG1sJzsKCQkJby5zZXQgPSB0cnVlOwoJCQlvLmNvbnRlbnQgPSBoOwoKCQkJaWYgKCFvLm5vX2V2ZW50cykKCQkJCXQub25CZWZvcmVTZXRDb250ZW50LmRpc3BhdGNoKHQsIG8pOwoKCQkJLy8gUGFkZCBlbXB0eSBjb250ZW50IGluIEdlY2tvIGFuZCBTYWZhcmkuIENvbW1hbmRzIHdpbGwgb3RoZXJ3aXNlIGZhaWwgb24gdGhlIGNvbnRlbnQKCQkJLy8gSXQgd2lsbCBhbHNvIGJlIGltcG9zc2libGUgdG8gcGxhY2UgdGhlIGNhcmV0IGluIHRoZSBlZGl0b3IgdW5sZXNzIHRoZXJlIGlzIGEgQlIgZWxlbWVudCBwcmVzZW50CgkJCWlmICghdGlueW1jZS5pc0lFICYmIChoLmxlbmd0aCA9PT0gMCB8fCAvXlxzKyQvLnRlc3QoaCkpKSB7CgkJCQlvLmNvbnRlbnQgPSB0LmRvbS5zZXRIVE1MKHQuZ2V0Qm9keSgpLCAnPGJyIG1jZV9ib2d1cz0iMSIgLz4nKTsKCQkJCW8uZm9ybWF0ID0gJ3Jhdyc7CgkJCX0KICAgICAgICAgICAgLy8gQVRMQVNTSUFOIC0gYWxzbyBwYWRkIHRoZSBlbmQgb2YgYSB0YWJsZSBpZiBpdCBpcyB0aGUgbGFzdCB0aGluZyBpbiBHZWNrbwogICAgICAgICAgICBlbHNlIGlmICh0aW55bWNlLmlzR2Vja28gJiYgQUpTLiQudHJpbShoKS5tYXRjaCgiPFwvdGFibGU+JCIpKSB7CiAgICAgICAgICAgICAgICBvLmNvbnRlbnQgKz0gIjxiciBtY2VfYm9ndXM9JzEnIC8+IjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgby5jb250ZW50ID0gdC5kb20uc2V0SFRNTCh0LmdldEJvZHkoKSwgdGlueW1jZS50cmltKG8uY29udGVudCkpOwoKCQkJaWYgKG8uZm9ybWF0ICE9ICdyYXcnICYmIHQuc2V0dGluZ3MuY2xlYW51cCkgewoJCQkJby5nZXRJbm5lciA9IHRydWU7CgkJCQlvLmNvbnRlbnQgPSB0LmRvbS5zZXRIVE1MKHQuZ2V0Qm9keSgpLCB0LnNlcmlhbGl6ZXIuc2VyaWFsaXplKHQuZ2V0Qm9keSgpLCBvKSk7CgkJCX0KCgkJCWlmICghby5ub19ldmVudHMpCgkJCQl0Lm9uU2V0Q29udGVudC5kaXNwYXRjaCh0LCBvKTsKCgkJCXJldHVybiBvLmNvbnRlbnQ7CgkJfSwKCgkJZ2V0Q29udGVudCA6IGZ1bmN0aW9uKG8pIHsKCQkJdmFyIHQgPSB0aGlzLCBoLCBuOwoKCQkJbyA9IG8gfHwge307CgkJCW8uZm9ybWF0ID0gby5mb3JtYXQgfHwgJ2h0bWwnOwoJCQlvLmdldCA9IHRydWU7CgoJCQlpZiAoIW8ubm9fZXZlbnRzKQoJCQkJdC5vbkJlZm9yZUdldENvbnRlbnQuZGlzcGF0Y2godCwgbyk7CgogICAgICAgICAgICAvLyBBVExBU1NJQU4gLSBzaW1pbGFyIHRvIHRoZSBvblNldENvbnRlbnQgaG9vayBhYm92ZSwgdGhpcyBjYXRjaGVzIHRoZSBFZGl0b3IgSFRNTCBiZWZvcmUgaXQgaXMgcHJvY2Vzc2VkCiAgICAgICAgICAgIG4gPSB0LmdldEJvZHkoKS5jbG9uZU5vZGUodHJ1ZSk7CiAgICAgICAgICAgIEFKUy5FZGl0b3IuQWRhcHRlci5vbkJlZm9yZUdldENvbnRlbnQobik7CgoJCQlpZiAoby5mb3JtYXQgIT0gJ3JhdycgJiYgdC5zZXR0aW5ncy5jbGVhbnVwKSB7CgkJCQlvLmdldElubmVyID0gdHJ1ZTsKCQkJCWggPSB0LnNlcmlhbGl6ZXIuc2VyaWFsaXplKG4sIG8pOwoJCQl9IGVsc2UKCQkJCWggPSBuLmlubmVySFRNTDsKCgkJCWggPSBoLnJlcGxhY2UoL15ccyp8XHMqJC9nLCAnJyk7CgkJCW8uY29udGVudCA9IGg7CgoJCQlpZiAoIW8ubm9fZXZlbnRzKQoJCQkJdC5vbkdldENvbnRlbnQuZGlzcGF0Y2godCwgbyk7CgoJCQlyZXR1cm4gby5jb250ZW50OwoJCX0sCgoJCWlzRGlydHkgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJcmV0dXJuIHRpbnltY2UudHJpbSh0LnN0YXJ0Q29udGVudCkgIT0gdGlueW1jZS50cmltKHQuZ2V0Q29udGVudCh7Zm9ybWF0IDogJ3JhdycsIG5vX2V2ZW50cyA6IDF9KSkgJiYgIXQuaXNOb3REaXJ0eTsKCQl9LAoKICAgICAgICBzZXREaXJ0eSA6IGZ1bmN0aW9uKGRpcnR5KSB7CiAgICAgICAgICAgIHZhciB0ID0gdGhpczsKCiAgICAgICAgICAgIHQuaXNOb3REaXJ0eSA9IGRpcnR5ID8gMCA6IDE7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0Q29udGFpbmVyIDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCWlmICghdC5jb250YWluZXIpCgkJCQl0LmNvbnRhaW5lciA9IERPTS5nZXQodC5lZGl0b3JDb250YWluZXIgfHwgdC5pZCArICdfcGFyZW50Jyk7CgoJCQlyZXR1cm4gdC5jb250YWluZXI7CgkJfSwKCgkJZ2V0Q29udGVudEFyZWFDb250YWluZXIgOiBmdW5jdGlvbigpIHsKCQkJcmV0dXJuIHRoaXMuY29udGVudEFyZWFDb250YWluZXI7CgkJfSwKCgkJZ2V0RWxlbWVudCA6IGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gRE9NLmdldCh0aGlzLnNldHRpbmdzLmNvbnRlbnRfZWxlbWVudCB8fCB0aGlzLmlkKTsKCQl9LAoKCQlnZXRXaW4gOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCBlOwoKCQkJaWYgKCF0LmNvbnRlbnRXaW5kb3cpIHsKCQkJCWUgPSBET00uZ2V0KHQuaWQgKyAiX2lmciIpOwoKCQkJCWlmIChlKQoJCQkJCXQuY29udGVudFdpbmRvdyA9IGUuY29udGVudFdpbmRvdzsKCQkJfQoKCQkJcmV0dXJuIHQuY29udGVudFdpbmRvdzsKCQl9LAoKCQlnZXREb2MgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCB3OwoKCQkJaWYgKCF0LmNvbnRlbnREb2N1bWVudCkgewoJCQkJdyA9IHQuZ2V0V2luKCk7CgoJCQkJaWYgKHcpCgkJCQkJdC5jb250ZW50RG9jdW1lbnQgPSB3LmRvY3VtZW50OwoJCQl9CgoJCQlyZXR1cm4gdC5jb250ZW50RG9jdW1lbnQ7CgkJfSwKCgkJZ2V0Qm9keSA6IGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gdGhpcy5ib2R5RWxlbWVudCB8fCB0aGlzLmdldERvYygpLmJvZHk7CgkJfSwKCgkJY29udmVydFVSTCA6IGZ1bmN0aW9uKHUsIG4sIGUpIHsKCQkJdmFyIHQgPSB0aGlzLCBzID0gdC5zZXR0aW5nczsKCgkJCS8vIFVzZSBjYWxsYmFjayBpbnN0ZWFkCgkJCWlmIChzLnVybGNvbnZlcnRlcl9jYWxsYmFjaykKCQkJCXJldHVybiB0LmV4ZWNDYWxsYmFjaygndXJsY29udmVydGVyX2NhbGxiYWNrJywgdSwgZSwgdHJ1ZSwgbik7CgoJCQkvLyBEb24ndCBjb252ZXJ0IGxpbmsgaHJlZiBzaW5jZSB0aGF0cyB0aGUgQ1NTIGZpbGVzIHRoYXQgZ2V0cyBsb2FkZWQgaW50byB0aGUgZWRpdG9yIGFsc28gc2tpcCBsb2NhbCBmaWxlIFVSTHMKCQkJaWYgKCFzLmNvbnZlcnRfdXJscyB8fCAoZSAmJiBlLm5vZGVOYW1lID09ICdMSU5LJykgfHwgdS5pbmRleE9mKCdmaWxlOicpID09PSAwKQoJCQkJcmV0dXJuIHU7CgoJCQkvLyBDb252ZXJ0IHRvIHJlbGF0aXZlCgkJCWlmIChzLnJlbGF0aXZlX3VybHMpCgkJCQlyZXR1cm4gdC5kb2N1bWVudEJhc2VVUkkudG9SZWxhdGl2ZSh1KTsKCgkJCS8vIENvbnZlcnQgdG8gYWJzb2x1dGUKCQkJdSA9IHQuZG9jdW1lbnRCYXNlVVJJLnRvQWJzb2x1dGUodSwgcy5yZW1vdmVfc2NyaXB0X2hvc3QpOwoKCQkJcmV0dXJuIHU7CgkJfSwKCgkJYWRkVmlzdWFsIDogZnVuY3Rpb24oZSkgewoJCQl2YXIgdCA9IHRoaXMsIHMgPSB0LnNldHRpbmdzOwoKCQkJZSA9IGUgfHwgdC5nZXRCb2R5KCk7CgoJCQlpZiAoIWlzKHQuaGFzVmlzdWFsKSkKCQkJCXQuaGFzVmlzdWFsID0gcy52aXN1YWw7CgoJCQllYWNoKHQuZG9tLnNlbGVjdCgndGFibGUsYScsIGUpLCBmdW5jdGlvbihlKSB7CgkJCQl2YXIgdjsKCgkJCQlzd2l0Y2ggKGUubm9kZU5hbWUpIHsKCQkJCQljYXNlICdUQUJMRSc6CgkJCQkJCXYgPSB0LmRvbS5nZXRBdHRyaWIoZSwgJ2JvcmRlcicpOwoKCQkJCQkJaWYgKCF2IHx8IHYgPT0gJzAnKSB7CgkJCQkJCQlpZiAodC5oYXNWaXN1YWwpCgkJCQkJCQkJdC5kb20uYWRkQ2xhc3MoZSwgcy52aXN1YWxfdGFibGVfY2xhc3MpOwoJCQkJCQkJZWxzZQoJCQkJCQkJCXQuZG9tLnJlbW92ZUNsYXNzKGUsIHMudmlzdWFsX3RhYmxlX2NsYXNzKTsKCQkJCQkJfQoKCQkJCQkJcmV0dXJuOwoKCQkJCQljYXNlICdBJzoKCQkJCQkJdiA9IHQuZG9tLmdldEF0dHJpYihlLCAnbmFtZScpOwoKCQkJCQkJaWYgKHYpIHsKCQkJCQkJCWlmICh0Lmhhc1Zpc3VhbCkKCQkJCQkJCQl0LmRvbS5hZGRDbGFzcyhlLCAnbWNlSXRlbUFuY2hvcicpOwoJCQkJCQkJZWxzZQoJCQkJCQkJCXQuZG9tLnJlbW92ZUNsYXNzKGUsICdtY2VJdGVtQW5jaG9yJyk7CgkJCQkJCX0KCgkJCQkJCXJldHVybjsKCQkJCX0KCQkJfSk7CgoJCQl0Lm9uVmlzdWFsQWlkLmRpc3BhdGNoKHQsIGUsIHQuaGFzVmlzdWFsKTsKCQl9LAoKCQlyZW1vdmUgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCBlID0gdC5nZXRDb250YWluZXIoKTsKCgkJCXQucmVtb3ZlZCA9IDE7IC8vIENhbmNlbHMgcG9zdCByZW1vdmUgZXZlbnQgZXhlY3V0aW9uCgkJCXQuaGlkZSgpOwoKCQkJdC5leGVjQ2FsbGJhY2soJ3JlbW92ZV9pbnN0YW5jZV9jYWxsYmFjaycsIHQpOwoJCQl0Lm9uUmVtb3ZlLmRpc3BhdGNoKHQpOwoKCQkJLy8gQ2xlYXIgYWxsIGV4ZWNDb21tYW5kIGxpc3RlbmVycyB0aGlzIGlzIHJlcXVpcmVkIHRvIGF2b2lkIGVycm9ycyBpZiB0aGUgZWRpdG9yIHdhcyByZW1vdmVkIGluc2lkZSBhbm90aGVyIGNvbW1hbmQKCQkJdC5vbkV4ZWNDb21tYW5kLmxpc3RlbmVycyA9IFtdOwoKCQkJRWRpdG9yTWFuYWdlci5yZW1vdmUodCk7CgkJCURPTS5yZW1vdmUoZSk7CgkJfSwKCgkJZGVzdHJveSA6IGZ1bmN0aW9uKHMpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJLy8gT25lIHRpbWUgaXMgZW5vdWdoCgkJCWlmICh0LmRlc3Ryb3llZCkKCQkJCXJldHVybjsKCgkJCWlmICghcykgewoJCQkJdGlueW1jZS5yZW1vdmVVbmxvYWQodC5kZXN0cm95KTsKCQkJCXRpbnlNQ0Uub25CZWZvcmVVbmxvYWQucmVtb3ZlKHQuX2JlZm9yZVVubG9hZCk7CgoJCQkJLy8gTWFudWFsIGRlc3Ryb3kKCQkJCWlmICh0LnRoZW1lICYmIHQudGhlbWUuZGVzdHJveSkKCQkJCQl0LnRoZW1lLmRlc3Ryb3koKTsKCgkJCQkvLyBEZXN0cm95IGNvbnRyb2xzLCBzZWxlY3Rpb24gYW5kIGRvbQoJCQkJdC5jb250cm9sTWFuYWdlci5kZXN0cm95KCk7CgkJCQl0LnNlbGVjdGlvbi5kZXN0cm95KCk7CgkJCQl0LmRvbS5kZXN0cm95KCk7CgoJCQkJLy8gUmVtb3ZlIGFsbCBldmVudHMKCgkJCQkvLyBEb24ndCBjbGVhciB0aGUgd2luZG93IG9yIGRvY3VtZW50IGlmIGNvbnRlbnQgZWRpdGFibGUKCQkJCS8vIGlzIGVuYWJsZWQgc2luY2Ugb3RoZXIgaW5zdGFuY2VzIG1pZ2h0IHN0aWxsIGJlIHByZXNlbnQKCQkJCWlmICghdC5zZXR0aW5ncy5jb250ZW50X2VkaXRhYmxlKSB7CgkJCQkJRXZlbnQuY2xlYXIodC5nZXRXaW4oKSk7CgkJCQkJRXZlbnQuY2xlYXIodC5nZXREb2MoKSk7CgkJCQl9CgoJCQkJRXZlbnQuY2xlYXIodC5nZXRCb2R5KCkpOwoJCQkJRXZlbnQuY2xlYXIodC5mb3JtRWxlbWVudCk7CgkJCX0KCgkJCWlmICh0LmZvcm1FbGVtZW50KSB7CgkJCQl0LmZvcm1FbGVtZW50LnN1Ym1pdCA9IHQuZm9ybUVsZW1lbnQuX21jZU9sZFN1Ym1pdDsKCQkJCXQuZm9ybUVsZW1lbnQuX21jZU9sZFN1Ym1pdCA9IG51bGw7CgkJCX0KCgkJCXQuY29udGVudEFyZWFDb250YWluZXIgPSB0LmZvcm1FbGVtZW50ID0gdC5jb250YWluZXIgPSB0LnNldHRpbmdzLmNvbnRlbnRfZWxlbWVudCA9IHQuYm9keUVsZW1lbnQgPSB0LmNvbnRlbnREb2N1bWVudCA9IHQuY29udGVudFdpbmRvdyA9IG51bGw7CgoJCQlpZiAodC5zZWxlY3Rpb24pCgkJCQl0LnNlbGVjdGlvbiA9IHQuc2VsZWN0aW9uLndpbiA9IHQuc2VsZWN0aW9uLmRvbSA9IHQuc2VsZWN0aW9uLmRvbS5kb2MgPSBudWxsOwoKCQkJdC5kZXN0cm95ZWQgPSAxOwoJCX0sCgoJCS8vIEludGVybmFsIGZ1bmN0aW9ucwoKCQlfYWRkRXZlbnRzIDogZnVuY3Rpb24oKSB7CgkJCS8vICdmb2N1cycsICdibHVyJywgJ2RibGNsaWNrJywgJ2JlZm9yZWRlYWN0aXZhdGUnLCBzdWJtaXQsIHJlc2V0CgkJCXZhciB0ID0gdGhpcywgaSwgcyA9IHQuc2V0dGluZ3MsIGxvID0gewoJCQkJbW91c2V1cCA6ICdvbk1vdXNlVXAnLAoJCQkJbW91c2Vkb3duIDogJ29uTW91c2VEb3duJywKCQkJCWNsaWNrIDogJ29uQ2xpY2snLAoJCQkJa2V5dXAgOiAnb25LZXlVcCcsCgkJCQlrZXlkb3duIDogJ29uS2V5RG93bicsCgkJCQlrZXlwcmVzcyA6ICdvbktleVByZXNzJywKCQkJCXN1Ym1pdCA6ICdvblN1Ym1pdCcsCgkJCQlyZXNldCA6ICdvblJlc2V0JywKCQkJCWNvbnRleHRtZW51IDogJ29uQ29udGV4dE1lbnUnLAoJCQkJZGJsY2xpY2sgOiAnb25EYmxDbGljaycsCgkJCQlwYXN0ZSA6ICdvblBhc3RlJyAvLyBEb2Vzbid0IHdvcmsgaW4gYWxsIGJyb3dzZXJzIHlldAoJCQl9OwoKCQkJZnVuY3Rpb24gZXZlbnRIYW5kbGVyKGUsIG8pIHsKCQkJCXZhciB0eSA9IGUudHlwZTsKCgkJCQkvLyBEb24ndCBmaXJlIGV2ZW50cyB3aGVuIGl0J3MgcmVtb3ZlZAoJCQkJaWYgKHQucmVtb3ZlZCkKCQkJCQlyZXR1cm47CgoJCQkJLy8gR2VuZXJpYyBldmVudCBoYW5kbGVyCgkJCQlpZiAodC5vbkV2ZW50LmRpc3BhdGNoKHQsIGUsIG8pICE9PSBmYWxzZSkgewoJCQkJCS8vIFNwZWNpZmljIGV2ZW50IGhhbmRsZXIKCQkJCQl0W2xvW2UuZmFrZVR5cGUgfHwgZS50eXBlXV0uZGlzcGF0Y2godCwgZSwgbyk7CgkJCQl9CgkJCX07CgoJCQkvLyBBZGQgRE9NIGV2ZW50cwoJCQllYWNoKGxvLCBmdW5jdGlvbih2LCBrKSB7CgkJCQlzd2l0Y2ggKGspIHsKCQkJCQljYXNlICdjb250ZXh0bWVudSc6CgkJCQkJCWlmICh0aW55bWNlLmlzT3BlcmEpIHsKCQkJCQkJCS8vIEZha2UgY29udGV4dG1lbnUgb24gT3BlcmEKCQkJCQkJCXQuZG9tLmJpbmQodC5nZXRCb2R5KCksICdtb3VzZWRvd24nLCBmdW5jdGlvbihlKSB7CgkJCQkJCQkJaWYgKGUuY3RybEtleSkgewoJCQkJCQkJCQllLmZha2VUeXBlID0gJ2NvbnRleHRtZW51JzsKCQkJCQkJCQkJZXZlbnRIYW5kbGVyKGUpOwoJCQkJCQkJCX0KCQkJCQkJCX0pOwoJCQkJCQl9IGVsc2UKCQkJCQkJCXQuZG9tLmJpbmQodC5nZXRCb2R5KCksIGssIGV2ZW50SGFuZGxlcik7CgkJCQkJCWJyZWFrOwoKCQkJCQljYXNlICdwYXN0ZSc6CgkJCQkJCXQuZG9tLmJpbmQodC5nZXRCb2R5KCksIGssIGZ1bmN0aW9uKGUpIHsKCQkJCQkJCWV2ZW50SGFuZGxlcihlKTsKCQkJCQkJfSk7CgkJCQkJCWJyZWFrOwoKCQkJCQljYXNlICdzdWJtaXQnOgoJCQkJCWNhc2UgJ3Jlc2V0JzoKCQkJCQkJdC5kb20uYmluZCh0LmdldEVsZW1lbnQoKS5mb3JtIHx8IERPTS5nZXRQYXJlbnQodC5pZCwgJ2Zvcm0nKSwgaywgZXZlbnRIYW5kbGVyKTsKCQkJCQkJYnJlYWs7CgoJCQkJCWRlZmF1bHQ6CgkJCQkJCXQuZG9tLmJpbmQocy5jb250ZW50X2VkaXRhYmxlID8gdC5nZXRCb2R5KCkgOiB0LmdldERvYygpLCBrLCBldmVudEhhbmRsZXIpOwoJCQkJfQoJCQl9KTsKCgkJCXQuZG9tLmJpbmQocy5jb250ZW50X2VkaXRhYmxlID8gdC5nZXRCb2R5KCkgOiAoaXNHZWNrbyA/IHQuZ2V0RG9jKCkgOiB0LmdldFdpbigpKSwgJ2ZvY3VzJywgZnVuY3Rpb24oZSkgewoJCQkJdC5mb2N1cyh0cnVlKTsKCQkJfSk7CgoKCQkJLy8gRml4ZXMgYnVnIHdoZXJlIGEgc3BlY2lmaWVkIGRvY3VtZW50X2Jhc2VfdXJpIGNvdWxkIHJlc3VsdCBpbiBicm9rZW4gaW1hZ2VzCgkJCS8vIFRoaXMgd2lsbCBhbHNvIGZpeCBkcmFnIGRyb3Agb2YgaW1hZ2VzIGluIEdlY2tvCgkJCWlmICh0aW55bWNlLmlzR2Vja28pIHsKCQkJCS8vIENvbnZlcnQgYWxsIGltYWdlcyB0byBhYnNvbHV0ZSBVUkxzCi8qCQkJCXQub25TZXRDb250ZW50LmFkZChmdW5jdGlvbihlZCwgbykgewoJCQkJCWVhY2goZWQuZG9tLnNlbGVjdCgnaW1nJyksIGZ1bmN0aW9uKGUpIHsKCQkJCQkJdmFyIHY7CgoJCQkJCQlpZiAodiA9IGUuZ2V0QXR0cmlidXRlKCdtY2Vfc3JjJykpCgkJCQkJCQllLnNyYyA9IHQuZG9jdW1lbnRCYXNlVVJJLnRvQWJzb2x1dGUodik7CgkJCQkJfSkKCQkJCX0pOyovCgoJCQkJdC5kb20uYmluZCh0LmdldERvYygpLCAnRE9NTm9kZUluc2VydGVkJywgZnVuY3Rpb24oZSkgewoJCQkJCXZhciB2OwoKCQkJCQllID0gZS50YXJnZXQ7CgoJCQkJCWlmIChlLm5vZGVUeXBlID09PSAxICYmIGUubm9kZU5hbWUgPT09ICdJTUcnICYmICh2ID0gZS5nZXRBdHRyaWJ1dGUoJ21jZV9zcmMnKSkpCgkJCQkJCWUuc3JjID0gdC5kb2N1bWVudEJhc2VVUkkudG9BYnNvbHV0ZSh2KTsKCQkJCX0pOwoJCQl9CgoJCQkvLyBTZXQgdmFyaW91cyBtaWRhcyBvcHRpb25zIGluIEdlY2tvCgkJCWlmIChpc0dlY2tvKSB7CgkJCQlmdW5jdGlvbiBzZXRPcHRzKCkgewoJCQkJCXZhciB0ID0gdGhpcywgZCA9IHQuZ2V0RG9jKCksIHMgPSB0LnNldHRpbmdzOwoKCQkJCQlpZiAoaXNHZWNrbyAmJiAhcy5yZWFkb25seSkgewoJCQkJCQlpZiAodC5faXNIaWRkZW4oKSkgewoJCQkJCQkJdHJ5IHsKCQkJCQkJCQlpZiAoIXMuY29udGVudF9lZGl0YWJsZSkKCQkJCQkJCQkJZC5kZXNpZ25Nb2RlID0gJ09uJzsKCQkJCQkJCX0gY2F0Y2ggKGV4KSB7CgkJCQkJCQkJLy8gRmFpbHMgaWYgaXQncyBoaWRkZW4KCQkJCQkJCX0KCQkJCQkJfQoKCQkJCQkJdHJ5IHsKCQkJCQkJCS8vIFRyeSBuZXcgR2Vja28gbWV0aG9kCgkJCQkJCQlkLmV4ZWNDb21tYW5kKCJzdHlsZVdpdGhDU1MiLCAwLCBmYWxzZSk7CgkJCQkJCX0gY2F0Y2ggKGV4KSB7CgkJCQkJCQkvLyBVc2Ugb2xkIG1ldGhvZAoJCQkJCQkJaWYgKCF0Ll9pc0hpZGRlbigpKQoJCQkJCQkJCXRyeSB7ZC5leGVjQ29tbWFuZCgidXNlQ1NTIiwgMCwgdHJ1ZSk7fSBjYXRjaCAoZXgpIHt9CgkJCQkJCX0KCgkJCQkJCWlmICghcy50YWJsZV9pbmxpbmVfZWRpdGluZykKCQkJCQkJCXRyeSB7ZC5leGVjQ29tbWFuZCgnZW5hYmxlSW5saW5lVGFibGVFZGl0aW5nJywgZmFsc2UsIGZhbHNlKTt9IGNhdGNoIChleCkge30KCgkJCQkJCWlmICghcy5vYmplY3RfcmVzaXppbmcpCgkJCQkJCQl0cnkge2QuZXhlY0NvbW1hbmQoJ2VuYWJsZU9iamVjdFJlc2l6aW5nJywgZmFsc2UsIGZhbHNlKTt9IGNhdGNoIChleCkge30KCQkJCQl9CgkJCQl9OwoKCQkJCXQub25CZWZvcmVFeGVjQ29tbWFuZC5hZGQoc2V0T3B0cyk7CgkJCQl0Lm9uTW91c2VEb3duLmFkZChzZXRPcHRzKTsKCQkJfQoKCQkJLy8gQWRkIG5vZGUgY2hhbmdlIGhhbmRsZXJzCgkJCXQub25Nb3VzZVVwLmFkZCh0Lm5vZGVDaGFuZ2VkKTsKCQkJdC5vbkNsaWNrLmFkZCh0Lm5vZGVDaGFuZ2VkKTsKCQkJdC5vbktleVVwLmFkZChmdW5jdGlvbihlZCwgZSkgewoJCQkJdmFyIGMgPSBlLmtleUNvZGU7CgoJCQkJaWYgKChjID49IDMzICYmIGMgPD0gMzYpIHx8IChjID49IDM3ICYmIGMgPD0gNDApIHx8IGMgPT0gMTMgfHwgYyA9PSA0NSB8fCBjID09IDQ2IHx8IGMgPT0gOCB8fCAodGlueW1jZS5pc01hYyAmJiAoYyA9PSA5MSB8fCBjID09IDkzKSkgfHwgZS5jdHJsS2V5KQoJCQkJCXQubm9kZUNoYW5nZWQoKTsKCQkJfSk7CgoJCQkvLyBBZGQgcmVzZXQgaGFuZGxlcgoJCQl0Lm9uUmVzZXQuYWRkKGZ1bmN0aW9uKCkgewoJCQkJdC5zZXRDb250ZW50KHQuc3RhcnRDb250ZW50LCB7Zm9ybWF0IDogJ3Jhdyd9KTsKCQkJfSk7CgoJCQkvLyBBZGQgc2hvcnRjdXRzCgkJCWlmIChzLmN1c3RvbV9zaG9ydGN1dHMpIHsKCQkJCWlmIChzLmN1c3RvbV91bmRvX3JlZG9fa2V5Ym9hcmRfc2hvcnRjdXRzKSB7CgkJCQkJdC5hZGRTaG9ydGN1dCgnY3RybCt6JywgdC5nZXRMYW5nKCd1bmRvX2Rlc2MnKSwgJ1VuZG8nKTsKCQkJCQl0LmFkZFNob3J0Y3V0KCdjdHJsK3knLCB0LmdldExhbmcoJ3JlZG9fZGVzYycpLCAnUmVkbycpOwoJCQkJfQoKCQkJCS8vIEFkZCBkZWZhdWx0IHNob3J0Y3V0cyBmb3IgZ2Vja28gYW5kIHdlYmtpdAoJCQkJaWYgKGlzR2Vja28gfHwgaXNXZWJLaXQpIHsKCQkJCQl0LmFkZFNob3J0Y3V0KCdjdHJsK2InLCB0LmdldExhbmcoJ2JvbGRfZGVzYycpLCAnQm9sZCcpOwoJCQkJCXQuYWRkU2hvcnRjdXQoJ2N0cmwraScsIHQuZ2V0TGFuZygnaXRhbGljX2Rlc2MnKSwgJ0l0YWxpYycpOwoJCQkJCXQuYWRkU2hvcnRjdXQoJ2N0cmwrdScsIHQuZ2V0TGFuZygndW5kZXJsaW5lX2Rlc2MnKSwgJ1VuZGVybGluZScpOwoJCQkJfQoKCQkJCS8vIEJsb2NrRm9ybWF0IHNob3J0Y3V0cyBrZXlzCgkJCQlmb3IgKGk9MTsgaTw9NjsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gRm9yIHNhZmFyaSBjb21wYXRpYmlsaXR5IHdlIGFkZCB0aGVzZSBzaG9ydGN1dHMgYm90aCB3aXRoIGFuZCB3aXRob3V0IHRoZSBhbHQvb3B0aW9uIGtleQoJCQkJCXQuYWRkU2hvcnRjdXQoJ2N0cmwrYWx0KycgKyBpICsgJyxjdHJsKycgKyBpLCAnJywgWydGb3JtYXRCbG9jaycsIGZhbHNlLCAnaCcgKyBpXSk7IC8vIEFUTEFTU0lBTiAtIG91ciBmb3JtYXQgYmxvY2sgbWV0aG9kIGV4cGVjdHMgaHRtbCB0YWcgbmFtZXMKICAgICAgICAgICAgICAgIH0KCgkJCQl0LmFkZFNob3J0Y3V0KCdjdHJsK2FsdCs3LGN0cmwrNycsICcnLCBbJ0Zvcm1hdEJsb2NrJywgZmFsc2UsICdwJ10pOyAvLyBBVExBU1NJQU4gLSBhZGRlZCBjdHJsK2FsdCs3IGFzIGEgc2hvcnRjdXQuCiAgICAgICAgICAgICAgICAvLyBBVExBU1NJQU4gLSBub3Qgc3VwcG9ydGVkCi8vCQkJCXQuYWRkU2hvcnRjdXQoJ2N0cmwrOCcsICcnLCBbJ0Zvcm1hdEJsb2NrJywgZmFsc2UsICc8ZGl2PiddKTsKLy8JCQkJdC5hZGRTaG9ydGN1dCgnY3RybCs5JywgJycsIFsnRm9ybWF0QmxvY2snLCBmYWxzZSwgJzxhZGRyZXNzPiddKTsKCgkJCQlmdW5jdGlvbiBmaW5kKGUpIHsKCQkJCQl2YXIgdiA9IG51bGw7CgoJCQkJCWlmICghZS5hbHRLZXkgJiYgIWUuY3RybEtleSAmJiAhZS5tZXRhS2V5KQoJCQkJCQlyZXR1cm4gdjsKCgkJCQkJZWFjaCh0LnNob3J0Y3V0cywgZnVuY3Rpb24obykgewogICAgICAgICAgICAgICAgICAgICAgICAvL1dlIGFsbG93IGJvdGggdGhlIGNtZCBhbmQgY3RybCBtb2RpZmllcnMgb24gT1NYCgkJCQkJCWlmICh0aW55bWNlLmlzTWFjICYmIChvLmN0cmwgIT0gZS5tZXRhS2V5ICYmIG8uY3RybCAhPSBlLmN0cmxLZXkpKQoJCQkJCQkJcmV0dXJuOwoJCQkJCQllbHNlIGlmICghdGlueW1jZS5pc01hYyAmJiBvLmN0cmwgIT0gZS5jdHJsS2V5KQoJCQkJCQkJcmV0dXJuOwoJCQkJCQlpZiAoby5hbHQgIT0gZS5hbHRLZXkpCgkJCQkJCQlyZXR1cm47CgoJCQkJCQlpZiAoby5zaGlmdCAhPSBlLnNoaWZ0S2V5KQoJCQkJCQkJcmV0dXJuOwoKCQkJCQkJaWYgKGUua2V5Q29kZSA9PSBvLmtleUNvZGUgfHwgKGUuY2hhckNvZGUgJiYgZS5jaGFyQ29kZSA9PSBvLmNoYXJDb2RlKSkgewoJCQkJCQkJdiA9IG87CgkJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJCX0KCQkJCQl9KTsKCgkJCQkJcmV0dXJuIHY7CgkJCQl9OwoKCQkJCXQub25LZXlVcC5hZGQoZnVuY3Rpb24oZWQsIGUpIHsKCQkJCQl2YXIgbyA9IGZpbmQoZSk7CgoJCQkJCWlmIChvKQoJCQkJCQlyZXR1cm4gRXZlbnQuY2FuY2VsKGUpOwoJCQkJfSk7CgoJCQkJdC5vbktleVByZXNzLmFkZChmdW5jdGlvbihlZCwgZSkgewoJCQkJCXZhciBvID0gZmluZChlKTsKCgkJCQkJaWYgKG8pCgkJCQkJCXJldHVybiBFdmVudC5jYW5jZWwoZSk7CgkJCQl9KTsKCgkJCQl0Lm9uS2V5RG93bi5hZGQoZnVuY3Rpb24oZWQsIGUpIHsKCQkJCQl2YXIgbyA9IGZpbmQoZSk7CgoJCQkJCWlmIChvKSB7CgkJCQkJCW8uZnVuYy5jYWxsKG8uc2NvcGUpOwoJCQkJCQlyZXR1cm4gRXZlbnQuY2FuY2VsKGUpOwoJCQkJCX0KCQkJCX0pOwoJCQl9CgoJCQlpZiAodGlueW1jZS5pc0lFKSB7CgkJCQkvLyBGaXggc28gcmVzaXplIHdpbGwgb25seSB1cGRhdGUgdGhlIHdpZHRoIGFuZCBoZWlnaHQgYXR0cmlidXRlcyBub3QgdGhlIHN0eWxlcyBvZiBhbiBpbWFnZQoJCQkJLy8gSXQgd2lsbCBhbHNvIGJsb2NrIG1jZUl0ZW1Ob1Jlc2l6ZSBpdGVtcwoJCQkJdC5kb20uYmluZCh0LmdldERvYygpLCAnY29udHJvbHNlbGVjdCcsIGZ1bmN0aW9uKGUpIHsKCQkJCQl2YXIgcmUgPSB0LnJlc2l6ZUluZm8sIGNiOwoKCQkJCQllID0gZS50YXJnZXQ7CgoJCQkJCS8vIERvbid0IGRvIHRoaXMgYWN0aW9uIGZvciBub24gaW1hZ2UgZWxlbWVudHMKCQkJCQlpZiAoZS5ub2RlTmFtZSAhPT0gJ0lNRycpCgkJCQkJCXJldHVybjsKCgkJCQkJaWYgKHJlKQoJCQkJCQl0LmRvbS51bmJpbmQocmUubm9kZSwgcmUuZXYsIHJlLmNiKTsKCgkJCQkJaWYgKCF0LmRvbS5oYXNDbGFzcyhlLCAnbWNlSXRlbU5vUmVzaXplJykpIHsKCQkJCQkJZXYgPSAncmVzaXplZW5kJzsKCQkJCQkJY2IgPSB0LmRvbS5iaW5kKGUsIGV2LCBmdW5jdGlvbihlKSB7CgkJCQkJCQl2YXIgdjsKCgkJCQkJCQllID0gZS50YXJnZXQ7CgoJCQkJCQkJaWYgKHYgPSB0LmRvbS5nZXRTdHlsZShlLCAnd2lkdGgnKSkgewoJCQkJCQkJCXQuZG9tLnNldEF0dHJpYihlLCAnd2lkdGgnLCB2LnJlcGxhY2UoL1teMC05JV0rL2csICcnKSk7CgkJCQkJCQkJdC5kb20uc2V0U3R5bGUoZSwgJ3dpZHRoJywgJycpOwoJCQkJCQkJfQoKCQkJCQkJCWlmICh2ID0gdC5kb20uZ2V0U3R5bGUoZSwgJ2hlaWdodCcpKSB7CgkJCQkJCQkJdC5kb20uc2V0QXR0cmliKGUsICdoZWlnaHQnLCB2LnJlcGxhY2UoL1teMC05JV0rL2csICcnKSk7CgkJCQkJCQkJdC5kb20uc2V0U3R5bGUoZSwgJ2hlaWdodCcsICcnKTsKCQkJCQkJCX0KCQkJCQkJfSk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJZXYgPSAncmVzaXplc3RhcnQnOwoJCQkJCQljYiA9IHQuZG9tLmJpbmQoZSwgJ3Jlc2l6ZXN0YXJ0JywgRXZlbnQuY2FuY2VsLCBFdmVudCk7CgkJCQkJfQoKCQkJCQlyZSA9IHQucmVzaXplSW5mbyA9IHsKCQkJCQkJbm9kZSA6IGUsCgkJCQkJCWV2IDogZXYsCgkJCQkJCWNiIDogY2IKCQkJCQl9OwoJCQkJfSk7CgoJCQkJdC5vbktleURvd24uYWRkKGZ1bmN0aW9uKGVkLCBlKSB7CgkJCQkJc3dpdGNoIChlLmtleUNvZGUpIHsKCQkJCQkJY2FzZSA4OgoJCQkJCQkJLy8gRml4IElFIGNvbnRyb2wgKyBiYWNrc3BhY2UgYnJvd3NlciBidWcKCQkJCQkJCWlmICh0LnNlbGVjdGlvbi5nZXRSbmcoKS5pdGVtKSB7CgkJCQkJCQkJdC5zZWxlY3Rpb24uZ2V0Um5nKCkuaXRlbSgwKS5yZW1vdmVOb2RlKCk7CgkJCQkJCQkJcmV0dXJuIEV2ZW50LmNhbmNlbChlKTsKCQkJCQkJCX0KCQkJCQl9CgkJCQl9KTsKCgkJCQkvKmlmICh0LmRvbS5ib3hNb2RlbCkgewoJCQkJCXQuZ2V0Qm9keSgpLnN0eWxlLmhlaWdodCA9ICcxMDAlJzsKCgkJCQkJRXZlbnQuYWRkKHQuZ2V0V2luKCksICdyZXNpemUnLCBmdW5jdGlvbihlKSB7CgkJCQkJCXZhciBkb2NFbG0gPSB0LmdldERvYygpLmRvY3VtZW50RWxlbWVudDsKCgkJCQkJCWRvY0VsbS5zdHlsZS5oZWlnaHQgPSAoZG9jRWxtLm9mZnNldEhlaWdodCAtIDEwKSArICdweCc7CgkJCQkJfSk7CgkJCQl9Ki8KCQkJfQoKCQkJaWYgKHRpbnltY2UuaXNPcGVyYSkgewoJCQkJdC5vbkNsaWNrLmFkZChmdW5jdGlvbihlZCwgZSkgewoJCQkJCUV2ZW50LnByZXZlbnQoZSk7CgkJCQl9KTsKCQkJfQoKCQkJLy8gQWRkIGN1c3RvbSB1bmRvL3JlZG8gaGFuZGxlcnMKCQkJaWYgKHMuY3VzdG9tX3VuZG9fcmVkbykgewoJCQkJZnVuY3Rpb24gYWRkVW5kbygpIHsKCQkJCQl0LnVuZG9NYW5hZ2VyLnR5cGluZyA9IDA7CgkJCQkJdC51bmRvTWFuYWdlci5hZGQoKTsKCQkJCX07CgoJCQkJLy8gQWRkIHVuZG8gbGV2ZWwgb24gZWRpdG9yIGJsdXIKCQkJCWlmICh0aW55bWNlLmlzSUUpIHsKCQkJCQl0LmRvbS5iaW5kKHQuZ2V0V2luKCksICdibHVyJywgZnVuY3Rpb24oZSkgewoJCQkJCQl2YXIgbjsKCgkJCQkJCS8vIENoZWNrIGFkZGVkIGZvciBmdWxsc2NyZWVuIGJ1ZwoJCQkJCQlpZiAodC5zZWxlY3Rpb24pIHsKCQkJCQkJCW4gPSB0LnNlbGVjdGlvbi5nZXROb2RlKCk7CgoJCQkJCQkJLy8gQWRkIHVuZG8gbGV2ZWwgaXMgc2VsZWN0aW9uIHdhcyBsb3N0IHRvIGFub3RoZXIgZG9jdW1lbnQKCQkJCQkJCWlmICghdC5yZW1vdmVkICYmIG4ub3duZXJEb2N1bWVudCAmJiBuLm93bmVyRG9jdW1lbnQgIT0gdC5nZXREb2MoKSkKCQkJCQkJCQlhZGRVbmRvKCk7CgkJCQkJCX0KCQkJCQl9KTsKCQkJCX0gZWxzZSB7CgkJCQkJdC5kb20uYmluZCh0LmdldERvYygpLCAnYmx1cicsIGZ1bmN0aW9uKCkgewoJCQkJCQlpZiAodC5zZWxlY3Rpb24gJiYgIXQucmVtb3ZlZCkKCQkJCQkJCWFkZFVuZG8oKTsKCQkJCQl9KTsKCQkJCX0KCgkJCQl0Lm9uTW91c2VEb3duLmFkZChhZGRVbmRvKTsKCgkJCQl0Lm9uS2V5VXAuYWRkKGZ1bmN0aW9uKGVkLCBlKSB7CgkJCQkJaWYgKChlLmtleUNvZGUgPj0gMzMgJiYgZS5rZXlDb2RlIDw9IDM2KSB8fCAoZS5rZXlDb2RlID49IDM3ICYmIGUua2V5Q29kZSA8PSA0MCkgfHwgZS5rZXlDb2RlID09IDEzIHx8IGUua2V5Q29kZSA9PSA0NSB8fCBlLmN0cmxLZXkpIHsKCQkJCQkJdC51bmRvTWFuYWdlci50eXBpbmcgPSAwOwoJCQkJCQl0LnVuZG9NYW5hZ2VyLmFkZCgpOwoJCQkJCX0KCQkJCX0pOwoKCQkJCXQub25LZXlEb3duLmFkZChmdW5jdGlvbihlZCwgZSkgewoJCQkJCS8vIElzIGNhcmFjdGVyIHBvc2l0b24ga2V5cwoJCQkJCWlmICgoZS5rZXlDb2RlID49IDMzICYmIGUua2V5Q29kZSA8PSAzNikgfHwgKGUua2V5Q29kZSA+PSAzNyAmJiBlLmtleUNvZGUgPD0gNDApIHx8IGUua2V5Q29kZSA9PSAxMyB8fCBlLmtleUNvZGUgPT0gNDUpIHsKCQkJCQkJaWYgKHQudW5kb01hbmFnZXIudHlwaW5nKSB7CgkJCQkJCQl0LnVuZG9NYW5hZ2VyLmFkZCgpOwoJCQkJCQkJdC51bmRvTWFuYWdlci50eXBpbmcgPSAwOwoJCQkJCQl9CgoJCQkJCQlyZXR1cm47CgkJCQkJfQoKCQkJCQlpZiAoIXQudW5kb01hbmFnZXIudHlwaW5nKSB7CgkJCQkJCXQudW5kb01hbmFnZXIuYWRkKCk7CgkJCQkJCXQudW5kb01hbmFnZXIudHlwaW5nID0gMTsKCQkJCQl9CgkJCQl9KTsKCQkJfQoJCX0sCgoJCV9jb252ZXJ0SW5saW5lRWxlbWVudHMgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCBzID0gdC5zZXR0aW5ncywgZG9tID0gdC5kb20sIHYsIGUsIG5hLCBzdCwgc3A7CgoJCQlmdW5jdGlvbiBjb252ZXJ0KGVkLCBvKSB7CgkJCQlpZiAoIXMuaW5saW5lX3N0eWxlcykKCQkJCQlyZXR1cm47CgoJCQkJaWYgKG8uZ2V0KSB7CgkJCQkJZWFjaCh0LmRvbS5zZWxlY3QoJ3RhYmxlLHUsc3RyaWtlJywgby5ub2RlKSwgZnVuY3Rpb24obikgewoJCQkJCQlzd2l0Y2ggKG4ubm9kZU5hbWUpIHsKCQkJCQkJCWNhc2UgJ1RBQkxFJzoKCQkJCQkJCQlpZiAodiA9IGRvbS5nZXRBdHRyaWIobiwgJ2hlaWdodCcpKSB7CgkJCQkJCQkJCWRvbS5zZXRTdHlsZShuLCAnaGVpZ2h0Jywgdik7CgkJCQkJCQkJCWRvbS5zZXRBdHRyaWIobiwgJ2hlaWdodCcsICcnKTsKCQkJCQkJCQl9CgkJCQkJCQkJYnJlYWs7CgoJCQkJCQkJY2FzZSAnVSc6CgkJCQkJCQljYXNlICdTVFJJS0UnOgoJCQkJCQkJCS8vc3AgPSBkb20uY3JlYXRlKCdzcGFuJywge3N0eWxlIDogZG9tLmdldEF0dHJpYihuLCAnc3R5bGUnKX0pOwoJCQkJCQkJCW4uc3R5bGUudGV4dERlY29yYXRpb24gPSBuLm5vZGVOYW1lID09ICdVJyA/ICd1bmRlcmxpbmUnIDogJ2xpbmUtdGhyb3VnaCc7CgkJCQkJCQkJZG9tLnNldEF0dHJpYihuLCAnbWNlX3N0eWxlJywgJycpOwoJCQkJCQkJCWRvbS5zZXRBdHRyaWIobiwgJ21jZV9uYW1lJywgJ3NwYW4nKTsKCQkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCX0pOwoJCQkJfSBlbHNlIGlmIChvLnNldCkgewoJCQkJCWVhY2godC5kb20uc2VsZWN0KCd0YWJsZSxzcGFuJywgby5ub2RlKS5yZXZlcnNlKCksIGZ1bmN0aW9uKG4pIHsKCQkJCQkJaWYgKG4ubm9kZU5hbWUgPT0gJ1RBQkxFJykgewoJCQkJCQkJaWYgKHYgPSBkb20uZ2V0U3R5bGUobiwgJ2hlaWdodCcpKQoJCQkJCQkJCWRvbS5zZXRBdHRyaWIobiwgJ2hlaWdodCcsIHYucmVwbGFjZSgvW14wLTklXSsvZywgJycpKTsKCQkJCQkJfSBlbHNlIHsKCQkJCQkJCS8vIENvbnZlcnQgc3BhbnMgdG8gZWxlbWVudHMKCQkJCQkJCWlmIChuLnN0eWxlLnRleHREZWNvcmF0aW9uID09ICd1bmRlcmxpbmUnKQoJCQkJCQkJCW5hID0gJ3UnOwoJCQkJCQkJZWxzZSBpZiAobi5zdHlsZS50ZXh0RGVjb3JhdGlvbiA9PSAnbGluZS10aHJvdWdoJykKCQkJCQkJCQluYSA9ICdzdHJpa2UnOwoJCQkJCQkJZWxzZQoJCQkJCQkJCW5hID0gJyc7CgoJCQkJCQkJaWYgKG5hKSB7CgkJCQkJCQkJbi5zdHlsZS50ZXh0RGVjb3JhdGlvbiA9ICcnOwoJCQkJCQkJCWRvbS5zZXRBdHRyaWIobiwgJ21jZV9zdHlsZScsICcnKTsKCgkJCQkJCQkJZSA9IGRvbS5jcmVhdGUobmEsIHsKCQkJCQkJCQkJc3R5bGUgOiBkb20uZ2V0QXR0cmliKG4sICdzdHlsZScpCgkJCQkJCQkJfSk7CgoJCQkJCQkJCWRvbS5yZXBsYWNlKGUsIG4sIDEpOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfSk7CgkJCQl9CgkJCX07CgoJCQl0Lm9uUHJlUHJvY2Vzcy5hZGQoY29udmVydCk7CgoJCQlpZiAoIXMuY2xlYW51cF9vbl9zdGFydHVwKSB7CgkJCQl0Lm9uU2V0Q29udGVudC5hZGQoZnVuY3Rpb24oZWQsIG8pIHsKCQkJCQlpZiAoby5pbml0aWFsKQoJCQkJCQljb252ZXJ0KHQsIHtub2RlIDogdC5nZXRCb2R5KCksIHNldCA6IDF9KTsKCQkJCX0pOwoJCQl9CgkJfSwKCgkJX2NvbnZlcnRGb250cyA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXMsIHMgPSB0LnNldHRpbmdzLCBkb20gPSB0LmRvbSwgZnosIGZ6biwgc2wsIGNsOwoKCQkJLy8gTm8gbmVlZAoJCQlpZiAoIXMuaW5saW5lX3N0eWxlcykKCQkJCXJldHVybjsKCgkJCS8vIEZvbnQgcHQgdmFsdWVzIGFuZCBmb250IHNpemUgbmFtZXMKCQkJZnogPSBbOCwgMTAsIDEyLCAxNCwgMTgsIDI0LCAzNl07CgkJCWZ6biA9IFsneHgtc21hbGwnLCAneC1zbWFsbCcsJ3NtYWxsJywnbWVkaXVtJywnbGFyZ2UnLCd4LWxhcmdlJywgJ3h4LWxhcmdlJ107CgoJCQlpZiAoc2wgPSBzLmZvbnRfc2l6ZV9zdHlsZV92YWx1ZXMpCgkJCQlzbCA9IGV4cGxvZGUoc2wpOwoKCQkJaWYgKGNsID0gcy5mb250X3NpemVfY2xhc3NlcykKCQkJCWNsID0gZXhwbG9kZShjbCk7CgoJCQlmdW5jdGlvbiBwcm9jZXNzKG5vKSB7CgkJCQl2YXIgbiwgc3AsIG5sLCB4OwoKCQkJCS8vIEtlZXAgdW5pdCB0ZXN0cyBoYXBweQoJCQkJaWYgKCFzLmlubGluZV9zdHlsZXMpCgkJCQkJcmV0dXJuOwoKCQkJCW5sID0gdC5kb20uc2VsZWN0KCdmb250Jywgbm8pOwoJCQkJZm9yICh4ID0gbmwubGVuZ3RoIC0gMTsgeCA+PSAwOyB4LS0pIHsKCQkJCQluID0gbmxbeF07CgoJCQkJCXNwID0gZG9tLmNyZWF0ZSgnc3BhbicsIHsKCQkJCQkJc3R5bGUgOiBkb20uZ2V0QXR0cmliKG4sICdzdHlsZScpLAoJCQkJCQknY2xhc3MnIDogZG9tLmdldEF0dHJpYihuLCAnY2xhc3MnKQoJCQkJCX0pOwoKCQkJCQlkb20uc2V0U3R5bGVzKHNwLCB7CgkJCQkJCWZvbnRGYW1pbHkgOiBkb20uZ2V0QXR0cmliKG4sICdmYWNlJyksCgkJCQkJCWNvbG9yIDogZG9tLmdldEF0dHJpYihuLCAnY29sb3InKSwKCQkJCQkJYmFja2dyb3VuZENvbG9yIDogbi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IKCQkJCQl9KTsKCgkJCQkJaWYgKG4uc2l6ZSkgewoJCQkJCQlpZiAoc2wpCgkJCQkJCQlkb20uc2V0U3R5bGUoc3AsICdmb250U2l6ZScsIHNsW3BhcnNlSW50KG4uc2l6ZSkgLSAxXSk7CgkJCQkJCWVsc2UKCQkJCQkJCWRvbS5zZXRBdHRyaWIoc3AsICdjbGFzcycsIGNsW3BhcnNlSW50KG4uc2l6ZSkgLSAxXSk7CgkJCQkJfQoKCQkJCQlkb20uc2V0QXR0cmliKHNwLCAnbWNlX3N0eWxlJywgJycpOwoJCQkJCWRvbS5yZXBsYWNlKHNwLCBuLCAxKTsKCQkJCX0KCQkJfTsKCgkJCS8vIFJ1biBvbiBjbGVhbnVwCgkJCXQub25QcmVQcm9jZXNzLmFkZChmdW5jdGlvbihlZCwgbykgewoJCQkJaWYgKG8uZ2V0KQoJCQkJCXByb2Nlc3Moby5ub2RlKTsKCQkJfSk7CgoJCQl0Lm9uU2V0Q29udGVudC5hZGQoZnVuY3Rpb24oZWQsIG8pIHsKCQkJCWlmIChvLmluaXRpYWwpCgkJCQkJcHJvY2VzcyhvLm5vZGUpOwoJCQl9KTsKCQl9LAoKCQlfaXNIaWRkZW4gOiBmdW5jdGlvbigpIHsKCQkJdmFyIHM7CgoJCQlpZiAoIWlzR2Vja28pCgkJCQlyZXR1cm4gMDsKCgkJCS8vIFdlaXJkLCB3aGVyZXMgdGhhdCBjdXJzb3Igc2VsZWN0aW9uPwoJCQlzID0gdGhpcy5zZWxlY3Rpb24uZ2V0U2VsKCk7CgkJCXJldHVybiAoIXMgfHwgIXMucmFuZ2VDb3VudCB8fCBzLnJhbmdlQ291bnQgPT0gMCk7CgkJfSwKCgkJLy8gRml4IGZvciBidWcgIzE4NjcyOTIKCQlfZml4TmVzdGluZyA6IGZ1bmN0aW9uKHMpIHsKCQkJdmFyIGQgPSBbXSwgaTsKCgkJCXMgPSBzLnJlcGxhY2UoLzwoXC8pPyhbXlxzPl0rKVtePl0qPz4vZywgZnVuY3Rpb24oYSwgYiwgYykgewoJCQkJdmFyIGU7CgoJCQkJLy8gSGFuZGxlIGVuZCBlbGVtZW50CgkJCQlpZiAoYiA9PT0gJy8nKSB7CgkJCQkJaWYgKCFkLmxlbmd0aCkKCQkJCQkJcmV0dXJuICcnOwoKCQkJCQlpZiAoYyAhPT0gZFtkLmxlbmd0aCAtIDFdLnRhZykgewoJCQkJCQlmb3IgKGk9ZC5sZW5ndGggLSAxOyBpPj0wOyBpLS0pIHsKCQkJCQkJCWlmIChkW2ldLnRhZyA9PT0gYykgewoJCQkJCQkJCWRbaV0uY2xvc2UgPSAxOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJfQoJCQkJCQl9CgoJCQkJCQlyZXR1cm4gJyc7CgkJCQkJfSBlbHNlIHsKCQkJCQkJZC5wb3AoKTsKCgkJCQkJCWlmIChkLmxlbmd0aCAmJiBkW2QubGVuZ3RoIC0gMV0uY2xvc2UpIHsKCQkJCQkJCWEgPSBhICsgJzwvJyArIGRbZC5sZW5ndGggLSAxXS50YWcgKyAnPic7CgkJCQkJCQlkLnBvcCgpOwoJCQkJCQl9CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQkvLyBJZ25vcmUgdGhlc2UKCQkJCQlpZiAoL14oYnJ8aHJ8aW5wdXR8bWV0YXxpbWd8bGlua3xwYXJhbSkkL2kudGVzdChjKSkKCQkJCQkJcmV0dXJuIGE7CgoJCQkJCS8vIElnbm9yZSBjbG9zZWQgb25lcwoJCQkJCWlmICgvXC8+JC8udGVzdChhKSkKCQkJCQkJcmV0dXJuIGE7CgoJCQkJCWQucHVzaCh7dGFnIDogY30pOyAvLyBQdXNoIHN0YXJ0IGVsZW1lbnQKCQkJCX0KCgkJCQlyZXR1cm4gYTsKCQkJfSk7CgoJCQkvLyBFbmQgYWxsIG9wZW4gdGFncwoJCQlmb3IgKGk9ZC5sZW5ndGggLSAxOyBpPj0wOyBpLS0pCgkJCQlzICs9ICc8LycgKyBkW2ldLnRhZyArICc+JzsKCgkJCXJldHVybiBzOwoJCX0KCgkJfSk7Cn0pKHRpbnltY2UpOwooZnVuY3Rpb24odGlueW1jZSkgewoJdmFyIGVhY2ggPSB0aW55bWNlLmVhY2gsIGlzSUUgPSB0aW55bWNlLmlzSUUsIGlzR2Vja28gPSB0aW55bWNlLmlzR2Vja28sIGlzT3BlcmEgPSB0aW55bWNlLmlzT3BlcmEsIGlzV2ViS2l0ID0gdGlueW1jZS5pc1dlYktpdDsKCgl0aW55bWNlLmNyZWF0ZSgndGlueW1jZS5FZGl0b3JDb21tYW5kcycsIHsKCQlFZGl0b3JDb21tYW5kcyA6IGZ1bmN0aW9uKGVkKSB7CgkJCXRoaXMuZWRpdG9yID0gZWQ7CgkJfSwKCgkJZXhlY0NvbW1hbmQgOiBmdW5jdGlvbihjbWQsIHVpLCB2YWwpIHsKCQkJdmFyIHQgPSB0aGlzLCBlZCA9IHQuZWRpdG9yLCBmOwoKCQkJc3dpdGNoIChjbWQpIHsKCQkJCS8vIElnbm9yZSB0aGVzZQoJCQkJY2FzZSAnbWNlUmVzZXREZXNpZ25Nb2RlJzoKCQkJCWNhc2UgJ21jZUJlZ2luVW5kb0xldmVsJzoKCQkJCQlyZXR1cm4gdHJ1ZTsKCgkJCQkvLyBJZ25vcmUgdGhlc2UKCQkJCWNhc2UgJ3VubGluayc6CgkJCQkJdC5VbkxpbmsoKTsKCQkJCQlyZXR1cm4gdHJ1ZTsKCgkJCQkvLyBCdW5kbGUgdGhlc2UgdG9nZXRoZXIKCQkJCWNhc2UgJ0p1c3RpZnlMZWZ0JzoKCQkJCWNhc2UgJ0p1c3RpZnlDZW50ZXInOgoJCQkJY2FzZSAnSnVzdGlmeVJpZ2h0JzoKCQkJCWNhc2UgJ0p1c3RpZnlGdWxsJzoKCQkJCQl0Lm1jZUp1c3RpZnkoY21kLCBjbWQuc3Vic3RyaW5nKDcpLnRvTG93ZXJDYXNlKCkpOwoJCQkJCXJldHVybiB0cnVlOwoKCQkJCWRlZmF1bHQ6CgkJCQkJZiA9IHRoaXNbY21kXTsKCgkJCQkJaWYgKGYpIHsKCQkJCQkJZi5jYWxsKHRoaXMsIHVpLCB2YWwpOwoJCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCQl9CgkJCX0KCgkJCXJldHVybiBmYWxzZTsKCQl9LAoKCQlJbmRlbnQgOiBmdW5jdGlvbigpIHsKCQkJdmFyIGVkID0gdGhpcy5lZGl0b3IsIGQgPSBlZC5kb20sIHMgPSBlZC5zZWxlY3Rpb24sIGUsIGl2LCBpdTsKCgkJCS8vIFNldHVwIGluZGVudCBsZXZlbAoJCQlpdiA9IGVkLnNldHRpbmdzLmluZGVudGF0aW9uOwoJCQlpdSA9IC9bYS16JV0rJC9pLmV4ZWMoaXYpOwoJCQlpdiA9IHBhcnNlSW50KGl2KTsKCgkJCWlmIChlZC5zZXR0aW5ncy5pbmxpbmVfc3R5bGVzICYmICghdGhpcy5xdWVyeVN0YXRlSW5zZXJ0VW5vcmRlcmVkTGlzdCgpICYmICF0aGlzLnF1ZXJ5U3RhdGVJbnNlcnRPcmRlcmVkTGlzdCgpKSkgewoJCQkJZWFjaChzLmdldFNlbGVjdGVkQmxvY2tzKCksIGZ1bmN0aW9uKGUpIHsKCQkJCQlkLnNldFN0eWxlKGUsICdwYWRkaW5nTGVmdCcsIChwYXJzZUludChlLnN0eWxlLnBhZGRpbmdMZWZ0IHx8IDApICsgaXYpICsgaXUpOwoJCQkJfSk7CgoJCQkJcmV0dXJuOwoJCQl9CgoJCQllZC5nZXREb2MoKS5leGVjQ29tbWFuZCgnSW5kZW50JywgZmFsc2UsIG51bGwpOwoKCQkJaWYgKGlzSUUpIHsKCQkJCWQuZ2V0UGFyZW50KHMuZ2V0Tm9kZSgpLCBmdW5jdGlvbihuKSB7CgkJCQkJaWYgKG4ubm9kZU5hbWUgPT0gJ0JMT0NLUVVPVEUnKSB7CgkJCQkJCW4uZGlyID0gbi5zdHlsZS5jc3NUZXh0ID0gJyc7CgkJCQkJfQoJCQkJfSk7CgkJCX0KCQl9LAoKCQlPdXRkZW50IDogZnVuY3Rpb24oKSB7CgkJCXZhciBlZCA9IHRoaXMuZWRpdG9yLCBkID0gZWQuZG9tLCBzID0gZWQuc2VsZWN0aW9uLCBlLCB2LCBpdiwgaXU7CgoJCQkvLyBTZXR1cCBpbmRlbnQgbGV2ZWwKCQkJaXYgPSBlZC5zZXR0aW5ncy5pbmRlbnRhdGlvbjsKCQkJaXUgPSAvW2EteiVdKyQvaS5leGVjKGl2KTsKCQkJaXYgPSBwYXJzZUludChpdik7CgoJCQlpZiAoZWQuc2V0dGluZ3MuaW5saW5lX3N0eWxlcyAmJiAoIXRoaXMucXVlcnlTdGF0ZUluc2VydFVub3JkZXJlZExpc3QoKSAmJiAhdGhpcy5xdWVyeVN0YXRlSW5zZXJ0T3JkZXJlZExpc3QoKSkpIHsKCQkJCWVhY2gocy5nZXRTZWxlY3RlZEJsb2NrcygpLCBmdW5jdGlvbihlKSB7CgkJCQkJdiA9IE1hdGgubWF4KDAsIHBhcnNlSW50KGUuc3R5bGUucGFkZGluZ0xlZnQgfHwgMCkgLSBpdik7CgkJCQkJZC5zZXRTdHlsZShlLCAncGFkZGluZ0xlZnQnLCB2ID8gdiArIGl1IDogJycpOwoJCQkJfSk7CgoJCQkJcmV0dXJuOwoJCQl9CgoJCQllZC5nZXREb2MoKS5leGVjQ29tbWFuZCgnT3V0ZGVudCcsIGZhbHNlLCBudWxsKTsKCQl9LAoKLyoKCQltY2VTZXRBdHRyaWJ1dGUgOiBmdW5jdGlvbih1LCB2KSB7CgkJCXZhciBlZCA9IHRoaXMuZWRpdG9yLCBkID0gZWQuZG9tLCBlOwoKCQkJaWYgKGUgPSBkLmdldFBhcmVudChlZC5zZWxlY3Rpb24uZ2V0Tm9kZSgpLCBkLmlzQmxvY2spKQoJCQkJZC5zZXRBdHRyaWIoZSwgdi5uYW1lLCB2LnZhbHVlKTsKCQl9LAoqLwoJCW1jZVNldENvbnRlbnQgOiBmdW5jdGlvbih1LCB2KSB7CgkJCXRoaXMuZWRpdG9yLnNldENvbnRlbnQodik7CgkJfSwKCgkJbWNlVG9nZ2xlVmlzdWFsQWlkIDogZnVuY3Rpb24oKSB7CgkJCXZhciBlZCA9IHRoaXMuZWRpdG9yOwoKCQkJZWQuaGFzVmlzdWFsID0gIWVkLmhhc1Zpc3VhbDsKCQkJZWQuYWRkVmlzdWFsKCk7CgkJfSwKCgkJbWNlUmVwbGFjZUNvbnRlbnQgOiBmdW5jdGlvbih1LCB2KSB7CgkJCXZhciBzID0gdGhpcy5lZGl0b3Iuc2VsZWN0aW9uOwoKCQkJcy5zZXRDb250ZW50KHYucmVwbGFjZSgvXHtcJHNlbGVjdGlvblx9L2csIHMuZ2V0Q29udGVudCh7Zm9ybWF0IDogJ3RleHQnfSkpKTsKCQl9LAoKCQltY2VJbnNlcnRMaW5rIDogZnVuY3Rpb24odSwgdikgewoJCQl2YXIgZWQgPSB0aGlzLmVkaXRvciwgcyA9IGVkLnNlbGVjdGlvbiwgZSA9IGVkLmRvbS5nZXRQYXJlbnQocy5nZXROb2RlKCksICdhJyk7CgoJCQlpZiAodGlueW1jZS5pcyh2LCAnc3RyaW5nJykpCgkJCQl2ID0ge2hyZWYgOiB2fTsKCgkJCWZ1bmN0aW9uIHNldChlKSB7CgkJCQllYWNoKHYsIGZ1bmN0aW9uKHYsIGspIHsKCQkJCQllZC5kb20uc2V0QXR0cmliKGUsIGssIHYpOwoJCQkJfSk7CgkJCX07CgoJCQlpZiAoIWUpIHsKCQkJCWVkLmV4ZWNDb21tYW5kKCdDcmVhdGVMaW5rJywgZmFsc2UsICdqYXZhc2NyaXB0Om1jdG1wKDApOycpOwoJCQkJZWFjaChlZC5kb20uc2VsZWN0KCdhW2hyZWY9amF2YXNjcmlwdDptY3RtcCgwKTtdJyksIGZ1bmN0aW9uKGUpIHsKCQkJCQlzZXQoZSk7CgkJCQl9KTsKCQkJfSBlbHNlIHsKCQkJCWlmICh2LmhyZWYpCgkJCQkJc2V0KGUpOwoJCQkJZWxzZQoJCQkJCWVkLmRvbS5yZW1vdmUoZSwgMSk7CgkJCX0KCQl9LAoKCQlVbkxpbmsgOiBmdW5jdGlvbigpIHsKCQkJdmFyIGVkID0gdGhpcy5lZGl0b3IsIHMgPSBlZC5zZWxlY3Rpb247CgoJCQlpZiAocy5pc0NvbGxhcHNlZCgpKQoJCQkJcy5zZWxlY3Qocy5nZXROb2RlKCkpOwoKCQkJZWQuZ2V0RG9jKCkuZXhlY0NvbW1hbmQoJ3VubGluaycsIGZhbHNlLCBudWxsKTsKCQkJcy5jb2xsYXBzZSgwKTsKCQl9LAoKCQlGb250TmFtZSA6IGZ1bmN0aW9uKHUsIHYpIHsKCQkJdmFyIHQgPSB0aGlzLCBlZCA9IHQuZWRpdG9yLCBzID0gZWQuc2VsZWN0aW9uLCBlOwoKCQkJaWYgKCF2KSB7CgkJCQlpZiAocy5pc0NvbGxhcHNlZCgpKQoJCQkJCXMuc2VsZWN0KHMuZ2V0Tm9kZSgpKTsKCQkJfSBlbHNlIHsKCQkJCWlmIChlZC5zZXR0aW5ncy5jb252ZXJ0X2ZvbnRzX3RvX3NwYW5zKQoJCQkJCXQuX2FwcGx5SW5saW5lU3R5bGUoJ3NwYW4nLCB7c3R5bGUgOiB7Zm9udEZhbWlseSA6IHZ9fSk7CgkJCQllbHNlCgkJCQkJZWQuZ2V0RG9jKCkuZXhlY0NvbW1hbmQoJ0ZvbnROYW1lJywgZmFsc2UsIHYpOwoJCQl9CgkJfSwKCgkJRm9udFNpemUgOiBmdW5jdGlvbih1LCB2KSB7CgkJCXZhciBlZCA9IHRoaXMuZWRpdG9yLCBzID0gZWQuc2V0dGluZ3MsIGZjLCBmczsKCgkJCS8vIFVzZSBzdHlsZSBvcHRpb25zIGluc3RlYWQKCQkJaWYgKHMuY29udmVydF9mb250c190b19zcGFucyAmJiB2ID49IDEgJiYgdiA8PSA3KSB7CgkJCQlmcyA9IHRpbnltY2UuZXhwbG9kZShzLmZvbnRfc2l6ZV9zdHlsZV92YWx1ZXMpOwoJCQkJZmMgPSB0aW55bWNlLmV4cGxvZGUocy5mb250X3NpemVfY2xhc3Nlcyk7CgoJCQkJaWYgKGZjKQoJCQkJCXYgPSBmY1t2IC0gMV0gfHwgdjsKCQkJCWVsc2UKCQkJCQl2ID0gZnNbdiAtIDFdIHx8IHY7CgkJCX0KCgkJCWlmICh2ID49IDEgJiYgdiA8PSA3KQoJCQkJZWQuZ2V0RG9jKCkuZXhlY0NvbW1hbmQoJ0ZvbnRTaXplJywgZmFsc2UsIHYpOwoJCQllbHNlCgkJCQl0aGlzLl9hcHBseUlubGluZVN0eWxlKCdzcGFuJywge3N0eWxlIDoge2ZvbnRTaXplIDogdn19KTsKCQl9LAoKCQlxdWVyeUNvbW1hbmRWYWx1ZSA6IGZ1bmN0aW9uKGMpIHsKCQkJdmFyIGYgPSB0aGlzWydxdWVyeVZhbHVlJyArIGNdOwoKCQkJaWYgKGYpCgkJCQlyZXR1cm4gZi5jYWxsKHRoaXMsIGMpOwoKCQkJcmV0dXJuIGZhbHNlOwoJCX0sCgoJCXF1ZXJ5Q29tbWFuZFN0YXRlIDogZnVuY3Rpb24oY21kKSB7CgkJCXZhciBmOwoKCQkJc3dpdGNoIChjbWQpIHsKCQkJCS8vIEJ1bmRsZSB0aGVzZSB0b2dldGhlcgoJCQkJY2FzZSAnSnVzdGlmeUxlZnQnOgoJCQkJY2FzZSAnSnVzdGlmeUNlbnRlcic6CgkJCQljYXNlICdKdXN0aWZ5UmlnaHQnOgoJCQkJY2FzZSAnSnVzdGlmeUZ1bGwnOgoJCQkJCXJldHVybiB0aGlzLnF1ZXJ5U3RhdGVKdXN0aWZ5KGNtZCwgY21kLnN1YnN0cmluZyg3KS50b0xvd2VyQ2FzZSgpKTsKCgkJCQlkZWZhdWx0OgoJCQkJCWlmIChmID0gdGhpc1sncXVlcnlTdGF0ZScgKyBjbWRdKQoJCQkJCQlyZXR1cm4gZi5jYWxsKHRoaXMsIGNtZCk7CgkJCX0KCgkJCXJldHVybiAtMTsKCQl9LAoKCQlfcXVlcnlTdGF0ZSA6IGZ1bmN0aW9uKGMpIHsKCQkJdHJ5IHsKCQkJCXJldHVybiB0aGlzLmVkaXRvci5nZXREb2MoKS5xdWVyeUNvbW1hbmRTdGF0ZShjKTsKCQkJfSBjYXRjaCAoZXgpIHsKCQkJCS8vIElnbm9yZSBleGNlcHRpb24KCQkJfQoJCX0sCgoJCV9xdWVyeVZhbCA6IGZ1bmN0aW9uKGMpIHsKCQkJdHJ5IHsKCQkJCXJldHVybiB0aGlzLmVkaXRvci5nZXREb2MoKS5xdWVyeUNvbW1hbmRWYWx1ZShjKTsKCQkJfSBjYXRjaCAoZXgpIHsKCQkJCS8vIElnbm9yZSBleGNlcHRpb24KCQkJfQoJCX0sCgoJCXF1ZXJ5VmFsdWVGb250U2l6ZSA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgZWQgPSB0aGlzLmVkaXRvciwgdiA9IDAsIHA7CgoJCQlpZiAocCA9IGVkLmRvbS5nZXRQYXJlbnQoZWQuc2VsZWN0aW9uLmdldE5vZGUoKSwgJ3NwYW4nKSkKCQkJCXYgPSBwLnN0eWxlLmZvbnRTaXplOwoKCQkJaWYgKCF2ICYmIChpc09wZXJhIHx8IGlzV2ViS2l0KSkgewoJCQkJaWYgKHAgPSBlZC5kb20uZ2V0UGFyZW50KGVkLnNlbGVjdGlvbi5nZXROb2RlKCksICdmb250JykpCgkJCQkJdiA9IHAuc2l6ZTsKCgkJCQlyZXR1cm4gdjsKCQkJfQoKCQkJcmV0dXJuIHYgfHwgdGhpcy5fcXVlcnlWYWwoJ0ZvbnRTaXplJyk7CgkJfSwKCgkJcXVlcnlWYWx1ZUZvbnROYW1lIDogZnVuY3Rpb24oKSB7CgkJCXZhciBlZCA9IHRoaXMuZWRpdG9yLCB2ID0gMCwgcDsKCgkJCWlmIChwID0gZWQuZG9tLmdldFBhcmVudChlZC5zZWxlY3Rpb24uZ2V0Tm9kZSgpLCAnZm9udCcpKQoJCQkJdiA9IHAuZmFjZTsKCgkJCWlmIChwID0gZWQuZG9tLmdldFBhcmVudChlZC5zZWxlY3Rpb24uZ2V0Tm9kZSgpLCAnc3BhbicpKQoJCQkJdiA9IHAuc3R5bGUuZm9udEZhbWlseS5yZXBsYWNlKC8sIC9nLCAnLCcpLnJlcGxhY2UoL1tcJ1wiXS9nLCAnJykudG9Mb3dlckNhc2UoKTsKCgkJCWlmICghdikKCQkJCXYgPSB0aGlzLl9xdWVyeVZhbCgnRm9udE5hbWUnKTsKCgkJCXJldHVybiB2OwoJCX0sCgoJCW1jZUp1c3RpZnkgOiBmdW5jdGlvbihjLCB2KSB7CgkJCXZhciBlZCA9IHRoaXMuZWRpdG9yLCBzZSA9IGVkLnNlbGVjdGlvbiwgbiA9IHNlLmdldE5vZGUoKSwgbm4gPSBuLm5vZGVOYW1lLCBibCwgbmIsIGRvbSA9IGVkLmRvbSwgcm07CgoJCQlpZiAoZWQuc2V0dGluZ3MuaW5saW5lX3N0eWxlcyAmJiB0aGlzLnF1ZXJ5U3RhdGVKdXN0aWZ5KGMsIHYpKQoJCQkJcm0gPSAxOwoKCQkJYmwgPSBkb20uZ2V0UGFyZW50KG4sIGVkLmRvbS5pc0Jsb2NrKTsKCgkJCWlmIChubiA9PSAnSU1HJykgewoJCQkJaWYgKHYgPT0gJ2Z1bGwnKQoJCQkJCXJldHVybjsKCgkJCQlpZiAocm0pIHsKCQkJCQlpZiAodiA9PSAnY2VudGVyJykKCQkJCQkJZG9tLnNldFN0eWxlKGJsIHx8IG4ucGFyZW50Tm9kZSwgJ3RleHRBbGlnbicsICcnKTsKCgkJCQkJZG9tLnNldFN0eWxlKG4sICdmbG9hdCcsICcnKTsKCQkJCQl0aGlzLm1jZVJlcGFpbnQoKTsKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJaWYgKHYgPT0gJ2NlbnRlcicpIHsKCQkJCQkvLyBEbyBub3QgY2hhbmdlIHRhYmxlIGVsZW1lbnRzCgkJCQkJaWYgKGJsICYmIC9eKFREfFRIKSQvLnRlc3QoYmwubm9kZU5hbWUpKQoJCQkJCQlibCA9IDA7CgoJCQkJCWlmICghYmwgfHwgYmwuY2hpbGROb2Rlcy5sZW5ndGggPiAxKSB7CgkJCQkJCW5iID0gZG9tLmNyZWF0ZSgncCcpOwoJCQkJCQluYi5hcHBlbmRDaGlsZChuLmNsb25lTm9kZShmYWxzZSkpOwoKCQkJCQkJaWYgKGJsKQoJCQkJCQkJZG9tLmluc2VydEFmdGVyKG5iLCBibCk7CgkJCQkJCWVsc2UKCQkJCQkJCWRvbS5pbnNlcnRBZnRlcihuYiwgbik7CgoJCQkJCQlkb20ucmVtb3ZlKG4pOwoJCQkJCQluID0gbmIuZmlyc3RDaGlsZDsKCQkJCQkJYmwgPSBuYjsKCQkJCQl9CgoJCQkJCWRvbS5zZXRTdHlsZShibCwgJ3RleHRBbGlnbicsIHYpOwoJCQkJCWRvbS5zZXRTdHlsZShuLCAnZmxvYXQnLCAnJyk7CgkJCQl9IGVsc2UgewoJCQkJCWRvbS5zZXRTdHlsZShuLCAnZmxvYXQnLCB2KTsKCQkJCQlkb20uc2V0U3R5bGUoYmwgfHwgbi5wYXJlbnROb2RlLCAndGV4dEFsaWduJywgJycpOwoJCQkJfQoKCQkJCXRoaXMubWNlUmVwYWludCgpOwoJCQkJcmV0dXJuOwoJCQl9CgoJCQkvLyBIYW5kbGUgdGhlIGFsaWdubWVudCBvdXRzZWxmcywgbGVzcyBxdWlya3MgaW4gYWxsIGJyb3dzZXJzCgkJCWlmIChlZC5zZXR0aW5ncy5pbmxpbmVfc3R5bGVzICYmIGVkLnNldHRpbmdzLmZvcmNlZF9yb290X2Jsb2NrKSB7CgkJCQlpZiAocm0pCgkJCQkJdiA9ICcnOwoKCQkJCWVhY2goc2UuZ2V0U2VsZWN0ZWRCbG9ja3MoZG9tLmdldFBhcmVudChzZS5nZXRTdGFydCgpLCBkb20uaXNCbG9jayksIGRvbS5nZXRQYXJlbnQoc2UuZ2V0RW5kKCksIGRvbS5pc0Jsb2NrKSksIGZ1bmN0aW9uKGUpIHsKCQkJCQlkb20uc2V0QXR0cmliKGUsICdhbGlnbicsICcnKTsKCQkJCQlkb20uc2V0U3R5bGUoZSwgJ3RleHRBbGlnbicsIHYgPT0gJ2Z1bGwnID8gJ2p1c3RpZnknIDogdik7CgkJCQl9KTsKCgkJCQlyZXR1cm47CgkJCX0gZWxzZSBpZiAoIXJtKQoJCQkJZWQuZ2V0RG9jKCkuZXhlY0NvbW1hbmQoYywgZmFsc2UsIG51bGwpOwoKCQkJaWYgKGVkLnNldHRpbmdzLmlubGluZV9zdHlsZXMpIHsKCQkJCWlmIChybSkgewoJCQkJCWRvbS5nZXRQYXJlbnQoZWQuc2VsZWN0aW9uLmdldE5vZGUoKSwgZnVuY3Rpb24obikgewoJCQkJCQlpZiAobi5zdHlsZSAmJiBuLnN0eWxlLnRleHRBbGlnbikKCQkJCQkJCWRvbS5zZXRTdHlsZShuLCAndGV4dEFsaWduJywgJycpOwoJCQkJCX0pOwoKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJZWFjaChkb20uc2VsZWN0KCcqJyksIGZ1bmN0aW9uKG4pIHsKCQkJCQl2YXIgdiA9IG4uYWxpZ247CgoJCQkJCWlmICh2KSB7CgkJCQkJCWlmICh2ID09ICdmdWxsJykKCQkJCQkJCXYgPSAnanVzdGlmeSc7CgoJCQkJCQlkb20uc2V0U3R5bGUobiwgJ3RleHRBbGlnbicsIHYpOwoJCQkJCQlkb20uc2V0QXR0cmliKG4sICdhbGlnbicsICcnKTsKCQkJCQl9CgkJCQl9KTsKCQkJfQoJCX0sCgoJCW1jZVNldENTU0NsYXNzIDogZnVuY3Rpb24odSwgdikgewoJCQl0aGlzLm1jZVNldFN0eWxlSW5mbygwLCB7Y29tbWFuZCA6ICdzZXRhdHRyaWInLCBuYW1lIDogJ2NsYXNzJywgdmFsdWUgOiB2fSk7CgkJfSwKCgkJZ2V0U2VsZWN0ZWRFbGVtZW50IDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpcywgZWQgPSB0LmVkaXRvciwgZG9tID0gZWQuZG9tLCBzZSA9IGVkLnNlbGVjdGlvbiwgciA9IHNlLmdldFJuZygpLCByMSwgcjIsIHNjLCBlYywgc28sIGVvLCBlLCBzcCwgZXAsIHJlOwoKCQkJaWYgKHNlLmlzQ29sbGFwc2VkKCkgfHwgci5pdGVtKQoJCQkJcmV0dXJuIHNlLmdldE5vZGUoKTsKCgkJCS8vIFNldHVwIHJlZ2V4cAoJCQlyZSA9IGVkLnNldHRpbmdzLm1lcmdlX3N0eWxlc19pbnZhbGlkX3BhcmVudHM7CgkJCWlmICh0aW55bWNlLmlzKHJlLCAnc3RyaW5nJykpCgkJCQlyZSA9IG5ldyBSZWdFeHAocmUsICdpJyk7CgoJCQlpZiAoaXNJRSkgewoJCQkJcjEgPSByLmR1cGxpY2F0ZSgpOwoJCQkJcjEuY29sbGFwc2UodHJ1ZSk7CgkJCQlzYyA9IHIxLnBhcmVudEVsZW1lbnQoKTsKCgkJCQlyMiA9IHIuZHVwbGljYXRlKCk7CgkJCQlyMi5jb2xsYXBzZShmYWxzZSk7CgkJCQllYyA9IHIyLnBhcmVudEVsZW1lbnQoKTsKCgkJCQlpZiAoc2MgIT0gZWMpIHsKCQkJCQlyMS5tb3ZlKCdjaGFyYWN0ZXInLCAxKTsKCQkJCQlzYyA9IHIxLnBhcmVudEVsZW1lbnQoKTsKCQkJCX0KCgkJCQlpZiAoc2MgPT0gZWMpIHsKCQkJCQlyMSA9IHIuZHVwbGljYXRlKCk7CgkJCQkJcjEubW92ZVRvRWxlbWVudFRleHQoc2MpOwoKCQkJCQlpZiAocjEuY29tcGFyZUVuZFBvaW50cygnU3RhcnRUb1N0YXJ0JywgcikgPT0gMCAmJiByMS5jb21wYXJlRW5kUG9pbnRzKCdFbmRUb0VuZCcsIHIpID09IDApCgkJCQkJCXJldHVybiByZSAmJiByZS50ZXN0KHNjLm5vZGVOYW1lKSA/IG51bGwgOiBzYzsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWZ1bmN0aW9uIGdldFBhcmVudChuKSB7CgkJCQkJcmV0dXJuIGRvbS5nZXRQYXJlbnQobiwgJyonKTsKCQkJCX07CgoJCQkJc2MgPSByLnN0YXJ0Q29udGFpbmVyOwoJCQkJZWMgPSByLmVuZENvbnRhaW5lcjsKCQkJCXNvID0gci5zdGFydE9mZnNldDsKCQkJCWVvID0gci5lbmRPZmZzZXQ7CgoJCQkJaWYgKCFyLmNvbGxhcHNlZCkgewoJCQkJCWlmIChzYyA9PSBlYykgewoJCQkJCQlpZiAoc28gLSBlbyA8IDIpIHsKCQkJCQkJCWlmIChzYy5oYXNDaGlsZE5vZGVzKCkpIHsKCQkJCQkJCQlzcCA9IHNjLmNoaWxkTm9kZXNbc29dOwoJCQkJCQkJCXJldHVybiByZSAmJiByZS50ZXN0KHNwLm5vZGVOYW1lKSA/IG51bGwgOiBzcDsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCX0KCgkJCQlpZiAoc2Mubm9kZVR5cGUgIT0gMyB8fCBlYy5ub2RlVHlwZSAhPSAzKQoJCQkJCXJldHVybiBudWxsOwoKCQkJCWlmIChzbyA9PSAwKSB7CgkJCQkJc3AgPSBnZXRQYXJlbnQoc2MpOwoKCQkJCQlpZiAoc3AgJiYgc3AuZmlyc3RDaGlsZCAhPSBzYykKCQkJCQkJc3AgPSBudWxsOwoJCQkJfQoKCQkJCWlmIChzbyA9PSBzYy5ub2RlVmFsdWUubGVuZ3RoKSB7CgkJCQkJZSA9IHNjLm5leHRTaWJsaW5nOwoKCQkJCQlpZiAoZSAmJiBlLm5vZGVUeXBlID09IDEpCgkJCQkJCXNwID0gc2MubmV4dFNpYmxpbmc7CgkJCQl9CgoJCQkJaWYgKGVvID09IDApIHsKCQkJCQllID0gZWMucHJldmlvdXNTaWJsaW5nOwoKCQkJCQlpZiAoZSAmJiBlLm5vZGVUeXBlID09IDEpCgkJCQkJCWVwID0gZTsKCQkJCX0KCgkJCQlpZiAoZW8gPT0gZWMubm9kZVZhbHVlLmxlbmd0aCkgewoJCQkJCWVwID0gZ2V0UGFyZW50KGVjKTsKCgkJCQkJaWYgKGVwICYmIGVwLmxhc3RDaGlsZCAhPSBlYykKCQkJCQkJZXAgPSBudWxsOwoJCQkJfQoKCQkJCS8vIFNhbWUgZWxlbWVudAoJCQkJaWYgKHNwID09IGVwKQoJCQkJCXJldHVybiByZSAmJiBzcCAmJiByZS50ZXN0KHNwLm5vZGVOYW1lKSA/IG51bGwgOiBzcDsKCQkJfQoKCQkJcmV0dXJuIG51bGw7CgkJfSwKCgkJbWNlU2V0U3R5bGVJbmZvIDogZnVuY3Rpb24odSwgdikgewoJCQl2YXIgdCA9IHRoaXMsIGVkID0gdC5lZGl0b3IsIGQgPSBlZC5nZXREb2MoKSwgZG9tID0gZWQuZG9tLCBlLCBiLCBzID0gZWQuc2VsZWN0aW9uLCBubiA9IHYud3JhcHBlciB8fCAnc3BhbicsIGIgPSBzLmdldEJvb2ttYXJrKCksIHJlOwoKCQkJZnVuY3Rpb24gc2V0KG4sIGUpIHsKCQkJCWlmIChuLm5vZGVUeXBlID09IDEpIHsKCQkJCQlzd2l0Y2ggKHYuY29tbWFuZCkgewoJCQkJCQljYXNlICdzZXRhdHRyaWInOgoJCQkJCQkJcmV0dXJuIGRvbS5zZXRBdHRyaWIobiwgdi5uYW1lLCB2LnZhbHVlKTsKCgkJCQkJCWNhc2UgJ3NldHN0eWxlJzoKCQkJCQkJCXJldHVybiBkb20uc2V0U3R5bGUobiwgdi5uYW1lLCB2LnZhbHVlKTsKCgkJCQkJCWNhc2UgJ3JlbW92ZWZvcm1hdCc6CgkJCQkJCQlyZXR1cm4gZG9tLnNldEF0dHJpYihuLCAnY2xhc3MnLCAnJyk7CgkJCQkJfQoJCQkJfQoJCQl9OwoKCQkJLy8gU2V0dXAgcmVnZXhwCgkJCXJlID0gZWQuc2V0dGluZ3MubWVyZ2Vfc3R5bGVzX2ludmFsaWRfcGFyZW50czsKCQkJaWYgKHRpbnltY2UuaXMocmUsICdzdHJpbmcnKSkKCQkJCXJlID0gbmV3IFJlZ0V4cChyZSwgJ2knKTsKCgkJCS8vIFNldCBzdHlsZSBpbmZvIG9uIHNlbGVjdGVkIGVsZW1lbnQKCQkJaWYgKChlID0gdC5nZXRTZWxlY3RlZEVsZW1lbnQoKSkgJiYgIWVkLnNldHRpbmdzLmZvcmNlX3NwYW5fd3JhcHBlcnMpCgkJCQlzZXQoZSwgMSk7CgkJCWVsc2UgewoJCQkJLy8gR2VuZXJhdGUgd3JhcHBlcnMgYW5kIHNldCBzdHlsZXMgb24gdGhlbQoJCQkJZC5leGVjQ29tbWFuZCgnRm9udE5hbWUnLCBmYWxzZSwgJ19fJyk7CgkJCQllYWNoKGRvbS5zZWxlY3QoJ3NwYW4sZm9udCcpLCBmdW5jdGlvbihuKSB7CgkJCQkJdmFyIHNwLCBlOwoKCQkJCQlpZiAoZG9tLmdldEF0dHJpYihuLCAnZmFjZScpID09ICdfXycgfHwgbi5zdHlsZS5mb250RmFtaWx5ID09PSAnX18nKSB7CgkJCQkJCXNwID0gZG9tLmNyZWF0ZShubiwge21jZV9uZXcgOiAnMSd9KTsKCgkJCQkJCXNldChzcCk7CgoJCQkJCQllYWNoIChuLmNoaWxkTm9kZXMsIGZ1bmN0aW9uKG4pIHsKCQkJCQkJCXNwLmFwcGVuZENoaWxkKG4uY2xvbmVOb2RlKHRydWUpKTsKCQkJCQkJfSk7CgoJCQkJCQlkb20ucmVwbGFjZShzcCwgbik7CgkJCQkJfQoJCQkJfSk7CgkJCX0KCgkJCS8vIFJlbW92ZSB3cmFwcGVycyBpbnNpZGUgbmV3IG9uZXMKCQkJZWFjaChkb20uc2VsZWN0KG5uKS5yZXZlcnNlKCksIGZ1bmN0aW9uKG4pIHsKCQkJCXZhciBwID0gbi5wYXJlbnROb2RlOwoKCQkJCS8vIENoZWNrIGlmIGl0J3MgYW4gb2xkIHNwYW4gaW4gYSBuZXcgd3JhcHBlcgoJCQkJaWYgKCFkb20uZ2V0QXR0cmliKG4sICdtY2VfbmV3JykpIHsKCQkJCQkvLyBGaW5kIG5ldyB3cmFwcGVyCgkJCQkJcCA9IGRvbS5nZXRQYXJlbnQobiwgJypbbWNlX25ld10nKTsKCgkJCQkJaWYgKHApCgkJCQkJCWRvbS5yZW1vdmUobiwgMSk7CgkJCQl9CgkJCX0pOwoKCQkJLy8gTWVyZ2Ugd3JhcHBlcnMgd2l0aCBwYXJlbnQgd3JhcHBlcnMKCQkJZWFjaChkb20uc2VsZWN0KG5uKS5yZXZlcnNlKCksIGZ1bmN0aW9uKG4pIHsKCQkJCXZhciBwID0gbi5wYXJlbnROb2RlOwoKCQkJCWlmICghcCB8fCAhZG9tLmdldEF0dHJpYihuLCAnbWNlX25ldycpKQoJCQkJCXJldHVybjsKCgkJCQlpZiAoZWQuc2V0dGluZ3MuZm9yY2Vfc3Bhbl93cmFwcGVycyAmJiBwLm5vZGVOYW1lICE9ICdTUEFOJykKCQkJCQlyZXR1cm47CgoJCQkJLy8gSGFzIHBhcmVudCBvZiB0aGUgc2FtZSB0eXBlIGFuZCBvbmx5IGNoaWxkCgkJCQlpZiAocC5ub2RlTmFtZSA9PSBubi50b1VwcGVyQ2FzZSgpICYmIHAuY2hpbGROb2Rlcy5sZW5ndGggPT0gMSkKCQkJCQlyZXR1cm4gZG9tLnJlbW92ZShwLCAxKTsKCgkJCQkvLyBIYXMgcGFyZW50IHRoYXQgaXMgbW9yZSBzdWl0YWJsZSB0byBoYXZlIHRoZSBjbGFzcyBhbmQgb25seSBjaGlsZAoJCQkJaWYgKG4ubm9kZVR5cGUgPT0gMSAmJiAoIXJlIHx8ICFyZS50ZXN0KHAubm9kZU5hbWUpKSAmJiBwLmNoaWxkTm9kZXMubGVuZ3RoID09IDEpIHsKCQkJCQlzZXQocCk7IC8vIFNldCBzdHlsZSBpbmZvIG9uIHBhcmVudCBpbnN0ZWFkCgkJCQkJZG9tLnNldEF0dHJpYihuLCAnY2xhc3MnLCAnJyk7CgkJCQl9CgkJCX0pOwoKCQkJLy8gUmVtb3ZlIGVtcHR5IHdyYXBwZXJzCgkJCWVhY2goZG9tLnNlbGVjdChubikucmV2ZXJzZSgpLCBmdW5jdGlvbihuKSB7CgkJCQlpZiAoZG9tLmdldEF0dHJpYihuLCAnbWNlX25ldycpIHx8IChkb20uZ2V0QXR0cmlicyhuKS5sZW5ndGggPD0gMSAmJiBuLmNsYXNzTmFtZSA9PT0gJycpKSB7CgkJCQkJaWYgKCFkb20uZ2V0QXR0cmliKG4sICdjbGFzcycpICYmICFkb20uZ2V0QXR0cmliKG4sICdzdHlsZScpKQoJCQkJCQlyZXR1cm4gZG9tLnJlbW92ZShuLCAxKTsKCgkJCQkJZG9tLnNldEF0dHJpYihuLCAnbWNlX25ldycsICcnKTsgLy8gUmVtb3ZlIG1jZV9uZXcgbWFya2VyCgkJCQl9CgkJCX0pOwoKCQkJcy5tb3ZlVG9Cb29rbWFyayhiKTsKCQl9LAoKCQlxdWVyeVN0YXRlSnVzdGlmeSA6IGZ1bmN0aW9uKGMsIHYpIHsKCQkJdmFyIGVkID0gdGhpcy5lZGl0b3IsIG4gPSBlZC5zZWxlY3Rpb24uZ2V0Tm9kZSgpLCBkb20gPSBlZC5kb207CgoJCQlpZiAobiAmJiBuLm5vZGVOYW1lID09ICdJTUcnKSB7CgkJCQlpZiAoZG9tLmdldFN0eWxlKG4sICdmbG9hdCcpID09IHYpCgkJCQkJcmV0dXJuIDE7CgoJCQkJcmV0dXJuIG4ucGFyZW50Tm9kZS5zdHlsZS50ZXh0QWxpZ24gPT0gdjsKCQkJfQoKCQkJbiA9IGRvbS5nZXRQYXJlbnQoZWQuc2VsZWN0aW9uLmdldFN0YXJ0KCksIGZ1bmN0aW9uKG4pIHsKCQkJCXJldHVybiBuLm5vZGVUeXBlID09IDEgJiYgbi5zdHlsZS50ZXh0QWxpZ247CgkJCX0pOwoKCQkJaWYgKHYgPT0gJ2Z1bGwnKQoJCQkJdiA9ICdqdXN0aWZ5JzsKCgkJCWlmIChlZC5zZXR0aW5ncy5pbmxpbmVfc3R5bGVzKQoJCQkJcmV0dXJuIChuICYmIG4uc3R5bGUudGV4dEFsaWduID09IHYpOwoKCQkJcmV0dXJuIHRoaXMuX3F1ZXJ5U3RhdGUoYyk7CgkJfSwKCgkJRm9yZUNvbG9yIDogZnVuY3Rpb24odWksIHYpIHsKCQkJdmFyIGVkID0gdGhpcy5lZGl0b3I7CgoJCQlpZiAoZWQuc2V0dGluZ3MuY29udmVydF9mb250c190b19zcGFucykgewoJCQkJdGhpcy5fYXBwbHlJbmxpbmVTdHlsZSgnc3BhbicsIHtzdHlsZSA6IHtjb2xvciA6IHZ9fSk7CgkJCQlyZXR1cm47CgkJCX0gZWxzZQoJCQkJZWQuZ2V0RG9jKCkuZXhlY0NvbW1hbmQoJ0ZvcmVDb2xvcicsIGZhbHNlLCB2KTsKCQl9LAoKCQlIaWxpdGVDb2xvciA6IGZ1bmN0aW9uKHVpLCB2YWwpIHsKCQkJdmFyIHQgPSB0aGlzLCBlZCA9IHQuZWRpdG9yLCBkID0gZWQuZ2V0RG9jKCk7CgoJCQlpZiAoZWQuc2V0dGluZ3MuY29udmVydF9mb250c190b19zcGFucykgewoJCQkJdGhpcy5fYXBwbHlJbmxpbmVTdHlsZSgnc3BhbicsIHtzdHlsZSA6IHtiYWNrZ3JvdW5kQ29sb3IgOiB2YWx9fSk7CgkJCQlyZXR1cm47CgkJCX0KCgkJCWZ1bmN0aW9uIHNldChzKSB7CgkJCQlpZiAoIWlzR2Vja28pCgkJCQkJcmV0dXJuOwoKCQkJCXRyeSB7CgkJCQkJLy8gVHJ5IG5ldyBHZWNrbyBtZXRob2QKCQkJCQlkLmV4ZWNDb21tYW5kKCJzdHlsZVdpdGhDU1MiLCAwLCBzKTsKCQkJCX0gY2F0Y2ggKGV4KSB7CgkJCQkJLy8gVXNlIG9sZAoJCQkJCWQuZXhlY0NvbW1hbmQoInVzZUNTUyIsIDAsICFzKTsKCQkJCX0KCQkJfTsKCgkJCWlmIChpc0dlY2tvIHx8IGlzT3BlcmEpIHsKCQkJCXNldCh0cnVlKTsKCQkJCWQuZXhlY0NvbW1hbmQoJ2hpbGl0ZWNvbG9yJywgZmFsc2UsIHZhbCk7CgkJCQlzZXQoZmFsc2UpOwoJCQl9IGVsc2UKCQkJCWQuZXhlY0NvbW1hbmQoJ0JhY2tDb2xvcicsIGZhbHNlLCB2YWwpOwoJCX0sCgoJCUZvcm1hdEJsb2NrIDogZnVuY3Rpb24odWksIHZhbCkgewogICAgICAgICAgICAvLyBBVExBU1NJQU4gLSBSdW4gb3VyIGN1c3RvbSBmb3JtYXR0ZXIgZm9yIGV2ZXJ5dGhpbmcgYnV0IGhlYWRpbmcgZm9ybWF0cy4KICAgICAgICAgICAgaWYoIS9IWzEtNl0vaS50ZXN0KHZhbCkpIHsKICAgICAgICAgICAgICAgIHRpbnltY2UuY29uZmx1ZW5jZS5mb3JtYXR0ZXIuZm9ybWF0QmxvY2sodmFsKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKCQkJdmFyIHQgPSB0aGlzLCBlZCA9IHQuZWRpdG9yLCBzID0gZWQuc2VsZWN0aW9uLCBkb20gPSBlZC5kb20sIGJsLCBuYiwgYjsKCgkJCWZ1bmN0aW9uIGlzQmxvY2sobikgewoJCQkJcmV0dXJuIC9eKFB8RElWfEhbMS02XXxBRERSRVNTfEJMT0NLUVVPVEV8UFJFKSQvLnRlc3Qobi5ub2RlTmFtZSk7CgkJCX07CgoJCQlibCA9IGRvbS5nZXRQYXJlbnQocy5nZXROb2RlKCksIGZ1bmN0aW9uKG4pIHsKCQkJCXJldHVybiBpc0Jsb2NrKG4pOwoJCQl9KTsKCgkJCS8vIElFIGhhcyBhbiBpc3N1ZSB3aGVyZSBpdCByZW1vdmVzIHRoZSBwYXJlbnQgZGl2IGlmIHlvdSBjaGFuZ2UgZm9ybWF0IG9uIHRoZSBwYXJhZ3JhaCBpbiA8ZGl2PjxwPkNvbnRlbnQ8L3A+PC9kaXY+CgkJCS8vIEZGIGFuZCBPcGVyYSBkb2Vzbid0IGNoYW5nZSBwYXJlbnQgRElWIGVsZW1lbnRzIGlmIHlvdSBzd2l0Y2ggZm9ybWF0CgkJCWlmIChibCkgewoJCQkJaWYgKChpc0lFICYmIGlzQmxvY2soYmwucGFyZW50Tm9kZSkpIHx8IGJsLm5vZGVOYW1lID09ICdESVYnKSB7CgkJCQkJLy8gUmVuYW1lIGJsb2NrIGVsZW1lbnQKCQkJCQluYiA9IGVkLmRvbS5jcmVhdGUodmFsKTsKCgkJCQkJZWFjaChkb20uZ2V0QXR0cmlicyhibCksIGZ1bmN0aW9uKHYpIHsKCQkJCQkJZG9tLnNldEF0dHJpYihuYiwgdi5ub2RlTmFtZSwgZG9tLmdldEF0dHJpYihibCwgdi5ub2RlTmFtZSkpOwoJCQkJCX0pOwoKCQkJCQliID0gcy5nZXRCb29rbWFyaygpOwoJCQkJCWRvbS5yZXBsYWNlKG5iLCBibCwgMSk7CgkJCQkJcy5tb3ZlVG9Cb29rbWFyayhiKTsKCQkJCQllZC5ub2RlQ2hhbmdlZCgpOwoJCQkJCXJldHVybjsKCQkJCX0KCQkJfQoKCQkJdmFsID0gZWQuc2V0dGluZ3MuZm9yY2VkX3Jvb3RfYmxvY2sgPyAodmFsIHx8ICc8cD4nKSA6IHZhbDsKCgkJCWlmICh2YWwuaW5kZXhPZignPCcpID09IC0xKQoJCQkJdmFsID0gJzwnICsgdmFsICsgJz4nOwoKCQkJaWYgKHRpbnltY2UuaXNHZWNrbykKCQkJCXZhbCA9IHZhbC5yZXBsYWNlKC88KGRpdnxibG9ja3F1b3RlfGNvZGV8ZHR8ZGR8ZGx8c2FtcCk+L2dpLCAnJDEnKTsKCgkJCWVkLmdldERvYygpLmV4ZWNDb21tYW5kKCdGb3JtYXRCbG9jaycsIGZhbHNlLCB2YWwpOwoJCX0sCgoJCW1jZUNsZWFudXAgOiBmdW5jdGlvbigpIHsKCQkJdmFyIGVkID0gdGhpcy5lZGl0b3IsIHMgPSBlZC5zZWxlY3Rpb24sIGIgPSBzLmdldEJvb2ttYXJrKCk7CgkJCWVkLnNldENvbnRlbnQoZWQuZ2V0Q29udGVudCgpKTsKCQkJcy5tb3ZlVG9Cb29rbWFyayhiKTsKCQl9LAoKCQltY2VSZW1vdmVOb2RlIDogZnVuY3Rpb24odWksIHZhbCkgewoJCQl2YXIgZWQgPSB0aGlzLmVkaXRvciwgcyA9IGVkLnNlbGVjdGlvbiwgYiwgbiA9IHZhbCB8fCBzLmdldE5vZGUoKTsKCgkJCS8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBib2R5IG5vZGUgaXNuJ3QgcmVtb3ZlZAoJCQlpZiAobiA9PSBlZC5nZXRCb2R5KCkpCgkJCQlyZXR1cm47CgoJCQliID0gcy5nZXRCb29rbWFyaygpOwoJCQllZC5kb20ucmVtb3ZlKG4sIDEpOwoJCQlzLm1vdmVUb0Jvb2ttYXJrKGIpOwoJCQllZC5ub2RlQ2hhbmdlZCgpOwoJCX0sCgoJCW1jZVNlbGVjdE5vZGVEZXB0aCA6IGZ1bmN0aW9uKHVpLCB2YWwpIHsKCQkJdmFyIGVkID0gdGhpcy5lZGl0b3IsIHMgPSBlZC5zZWxlY3Rpb24sIGMgPSAwOwoKCQkJZWQuZG9tLmdldFBhcmVudChzLmdldE5vZGUoKSwgZnVuY3Rpb24obikgewoJCQkJaWYgKG4ubm9kZVR5cGUgPT0gMSAmJiBjKysgPT0gdmFsKSB7CgkJCQkJcy5zZWxlY3Qobik7CgkJCQkJZWQubm9kZUNoYW5nZWQoKTsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgkJCX0sIGVkLmdldEJvZHkoKSk7CgkJfSwKCgkJbWNlU2VsZWN0Tm9kZSA6IGZ1bmN0aW9uKHUsIHYpIHsKCQkJdGhpcy5lZGl0b3Iuc2VsZWN0aW9uLnNlbGVjdCh2KTsKCQl9LAoKCQltY2VJbnNlcnRDb250ZW50IDogZnVuY3Rpb24odWksIHZhbCkgewoJCQl0aGlzLmVkaXRvci5zZWxlY3Rpb24uc2V0Q29udGVudCh2YWwpOwoJCX0sCgoJCW1jZUluc2VydFJhd0hUTUwgOiBmdW5jdGlvbih1aSwgdmFsKSB7CgkJCXZhciBlZCA9IHRoaXMuZWRpdG9yOwoKCQkJZWQuc2VsZWN0aW9uLnNldENvbnRlbnQoJ3RpbnlfbWNlX21hcmtlcicpOwoJCQllZC5zZXRDb250ZW50KGVkLmdldENvbnRlbnQoKS5yZXBsYWNlKC90aW55X21jZV9tYXJrZXIvZywgdmFsKSk7CgkJfSwKCgkJbWNlUmVwYWludCA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgcywgYiwgZSA9IHRoaXMuZWRpdG9yOwoKCQkJaWYgKHRpbnltY2UuaXNHZWNrbykgewoJCQkJdHJ5IHsKCQkJCQlzID0gZS5zZWxlY3Rpb247CgkJCQkJYiA9IHMuZ2V0Qm9va21hcmsodHJ1ZSk7CgoJCQkJCWlmIChzLmdldFNlbCgpKQoJCQkJCQlzLmdldFNlbCgpLnNlbGVjdEFsbENoaWxkcmVuKGUuZ2V0Qm9keSgpKTsKCgkJCQkJcy5jb2xsYXBzZSh0cnVlKTsKCQkJCQlzLm1vdmVUb0Jvb2ttYXJrKGIpOwoJCQkJfSBjYXRjaCAoZXgpIHsKCQkJCQkvLyBJZ25vcmUKCQkJCX0KCQkJfQoJCX0sCgoJCXF1ZXJ5U3RhdGVVbmRlcmxpbmUgOiBmdW5jdGlvbigpIHsKCQkJdmFyIGVkID0gdGhpcy5lZGl0b3IsIG4gPSBlZC5zZWxlY3Rpb24uZ2V0Tm9kZSgpOwoKCQkJaWYgKG4gJiYgbi5ub2RlTmFtZSA9PSAnQScpCgkJCQlyZXR1cm4gZmFsc2U7CgoJCQlyZXR1cm4gdGhpcy5fcXVlcnlTdGF0ZSgnVW5kZXJsaW5lJyk7CgkJfSwKCgkJcXVlcnlTdGF0ZU91dGRlbnQgOiBmdW5jdGlvbigpIHsKCQkJdmFyIGVkID0gdGhpcy5lZGl0b3IsIG47CgoJCQlpZiAoZWQuc2V0dGluZ3MuaW5saW5lX3N0eWxlcykgewoJCQkJaWYgKChuID0gZWQuZG9tLmdldFBhcmVudChlZC5zZWxlY3Rpb24uZ2V0U3RhcnQoKSwgZWQuZG9tLmlzQmxvY2spKSAmJiBwYXJzZUludChuLnN0eWxlLnBhZGRpbmdMZWZ0KSA+IDApCgkJCQkJcmV0dXJuIHRydWU7CgoJCQkJaWYgKChuID0gZWQuZG9tLmdldFBhcmVudChlZC5zZWxlY3Rpb24uZ2V0RW5kKCksIGVkLmRvbS5pc0Jsb2NrKSkgJiYgcGFyc2VJbnQobi5zdHlsZS5wYWRkaW5nTGVmdCkgPiAwKQoJCQkJCXJldHVybiB0cnVlOwoJCQl9CgoJCQlyZXR1cm4gdGhpcy5xdWVyeVN0YXRlSW5zZXJ0VW5vcmRlcmVkTGlzdCgpIHx8IHRoaXMucXVlcnlTdGF0ZUluc2VydE9yZGVyZWRMaXN0KCkgfHwgKCFlZC5zZXR0aW5ncy5pbmxpbmVfc3R5bGVzICYmICEhZWQuZG9tLmdldFBhcmVudChlZC5zZWxlY3Rpb24uZ2V0Tm9kZSgpLCAnQkxPQ0tRVU9URScpKTsKCQl9LAoKCQlxdWVyeVN0YXRlSW5zZXJ0VW5vcmRlcmVkTGlzdCA6IGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gdGhpcy5lZGl0b3IuZG9tLmdldFBhcmVudCh0aGlzLmVkaXRvci5zZWxlY3Rpb24uZ2V0Tm9kZSgpLCAnVUwnKTsKCQl9LAoKCQlxdWVyeVN0YXRlSW5zZXJ0T3JkZXJlZExpc3QgOiBmdW5jdGlvbigpIHsKCQkJcmV0dXJuIHRoaXMuZWRpdG9yLmRvbS5nZXRQYXJlbnQodGhpcy5lZGl0b3Iuc2VsZWN0aW9uLmdldE5vZGUoKSwgJ09MJyk7CgkJfSwKCgkJcXVlcnlTdGF0ZW1jZUJsb2NrUXVvdGUgOiBmdW5jdGlvbigpIHsKCQkJcmV0dXJuICEhdGhpcy5lZGl0b3IuZG9tLmdldFBhcmVudCh0aGlzLmVkaXRvci5zZWxlY3Rpb24uZ2V0U3RhcnQoKSwgZnVuY3Rpb24obikge3JldHVybiBuLm5vZGVOYW1lID09PSAnQkxPQ0tRVU9URSc7fSk7CgkJfSwKCgkJX2FwcGx5SW5saW5lU3R5bGUgOiBmdW5jdGlvbihuYSwgYXQsIG9wKSB7CgkJCXZhciB0ID0gdGhpcywgZWQgPSB0LmVkaXRvciwgZG9tID0gZWQuZG9tLCBibSwgbG8gPSB7fSwga2gsIGZvdW5kOwoKCQkJbmEgPSBuYS50b1VwcGVyQ2FzZSgpOwoKCQkJaWYgKG9wICYmIG9wLmNoZWNrX2NsYXNzZXMgJiYgYXRbJ2NsYXNzJ10pCgkJCQlvcC5jaGVja19jbGFzc2VzLnB1c2goYXRbJ2NsYXNzJ10pOwoKCQkJZnVuY3Rpb24gcmVtb3ZlRW1wdHkoKSB7CgkJCQllYWNoKGRvbS5zZWxlY3QobmEpLnJldmVyc2UoKSwgZnVuY3Rpb24obikgewoJCQkJCXZhciBjID0gMDsKCgkJCQkJLy8gQ2hlY2sgaWYgdGhlcmUgaXMgYW55IGF0dHJpYnV0ZXMKCQkJCQllYWNoKGRvbS5nZXRBdHRyaWJzKG4pLCBmdW5jdGlvbihhbikgewoJCQkJCQlpZiAoYW4ubm9kZU5hbWUuc3Vic3RyaW5nKDAsIDEpICE9ICdfJyAmJiBkb20uZ2V0QXR0cmliKG4sIGFuLm5vZGVOYW1lKSAhPSAnJykgewoJCQkJCQkJLy9jb25zb2xlLmxvZyhkb20uZ2V0T3V0ZXJIVE1MKG4pLCBkb20uZ2V0QXR0cmliKG4sIGFuLm5vZGVOYW1lKSk7CgkJCQkJCQljKys7CgkJCQkJCX0KCQkJCQl9KTsKCgkJCQkJLy8gTm8gYXR0cmlidXRlcyB0aGVuIHJlbW92ZSB0aGUgZWxlbWVudCBhbmQga2VlcCB0aGUgY2hpbGRyZW4KCQkJCQlpZiAoYyA9PSAwKQoJCQkJCQlkb20ucmVtb3ZlKG4sIDEpOwoJCQkJfSk7CgkJCX07CgoJCQlmdW5jdGlvbiByZXBsYWNlRm9udHMoKSB7CgkJCQl2YXIgYm07CgoJCQkJZWFjaChkb20uc2VsZWN0KCdzcGFuLGZvbnQnKSwgZnVuY3Rpb24obikgewoJCQkJCWlmIChuLnN0eWxlLmZvbnRGYW1pbHkgPT0gJ21jZWlubGluZScgfHwgbi5mYWNlID09ICdtY2VpbmxpbmUnKSB7CgkJCQkJCWlmICghYm0pCgkJCQkJCQlibSA9IGVkLnNlbGVjdGlvbi5nZXRCb29rbWFyaygpOwoKCQkJCQkJYXQuX21jZV9uZXcgPSAnMSc7CgkJCQkJCWRvbS5yZXBsYWNlKGRvbS5jcmVhdGUobmEsIGF0KSwgbiwgMSk7CgkJCQkJfQoJCQkJfSk7CgoJCQkJLy8gUmVtb3ZlIHJlZHVuZGFudCBlbGVtZW50cwoJCQkJZWFjaChkb20uc2VsZWN0KG5hICsgJ1tfbWNlX25ld10nKSwgZnVuY3Rpb24obikgewoJCQkJCWZ1bmN0aW9uIHJlbW92ZVN0eWxlKG4pIHsKCQkJCQkJaWYgKG4ubm9kZVR5cGUgPT0gMSkgewoJCQkJCQkJZWFjaChhdC5zdHlsZSwgZnVuY3Rpb24odiwgaykgewoJCQkJCQkJCWRvbS5zZXRTdHlsZShuLCBrLCAnJyk7CgkJCQkJCQl9KTsKCgkJCQkJCQkvLyBSZW1vdmUgc3BhbnMgd2l0aCB0aGUgc2FtZSBjbGFzcyBvciBtYXJrZWQgY2xhc3NlcwoJCQkJCQkJaWYgKGF0WydjbGFzcyddICYmIG4uY2xhc3NOYW1lICYmIG9wKSB7CgkJCQkJCQkJZWFjaChvcC5jaGVja19jbGFzc2VzLCBmdW5jdGlvbihjKSB7CgkJCQkJCQkJCWlmIChkb20uaGFzQ2xhc3MobiwgYykpCgkJCQkJCQkJCQlkb20ucmVtb3ZlQ2xhc3MobiwgYyk7CgkJCQkJCQkJfSk7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9OwoKCQkJCQkvLyBSZW1vdmUgc3BlY2lmaWVkIHN0eWxlIGluZm9ybWF0aW9uIGZyb20gY2hpbGQgZWxlbWVudHMKCQkJCQllYWNoKGRvbS5zZWxlY3QobmEsIG4pLCByZW1vdmVTdHlsZSk7CgoJCQkJCS8vIFJlbW92ZSB0aGUgc3BlY2lmaWVkIHN0eWxlIGluZm9ybWF0aW9uIG9uIHBhcmVudCBpZiBjdXJyZW50IG5vZGUgaXMgb25seSBjaGlsZCAoSUUpCgkJCQkJaWYgKG4ucGFyZW50Tm9kZSAmJiBuLnBhcmVudE5vZGUubm9kZVR5cGUgPT0gMSAmJiBuLnBhcmVudE5vZGUuY2hpbGROb2Rlcy5sZW5ndGggPT0gMSkKCQkJCQkJcmVtb3ZlU3R5bGUobi5wYXJlbnROb2RlKTsKCgkJCQkJLy8gUmVtb3ZlIHRoZSBjaGlsZCBlbGVtZW50cyBzdHlsZSBpbmZvIGlmIGEgcGFyZW50IGFscmVhZHkgaGFzIGl0CgkJCQkJZG9tLmdldFBhcmVudChuLnBhcmVudE5vZGUsIGZ1bmN0aW9uKHBuKSB7CgkJCQkJCWlmIChwbi5ub2RlVHlwZSA9PSAxKSB7CgkJCQkJCQlpZiAoYXQuc3R5bGUpIHsKCQkJCQkJCQllYWNoKGF0LnN0eWxlLCBmdW5jdGlvbih2LCBrKSB7CgkJCQkJCQkJCXZhciBzdjsKCgkJCQkJCQkJCWlmICghbG9ba10gJiYgKHN2ID0gZG9tLmdldFN0eWxlKHBuLCBrKSkpIHsKCQkJCQkJCQkJCWlmIChzdiA9PT0gdikKCQkJCQkJCQkJCQlkb20uc2V0U3R5bGUobiwgaywgJycpOwoKCQkJCQkJCQkJCWxvW2tdID0gMTsKCQkJCQkJCQkJfQoJCQkJCQkJCX0pOwoJCQkJCQkJfQoKCQkJCQkJCS8vIFJlbW92ZSBzcGFucyB3aXRoIHRoZSBzYW1lIGNsYXNzIG9yIG1hcmtlZCBjbGFzc2VzCgkJCQkJCQlpZiAoYXRbJ2NsYXNzJ10gJiYgcG4uY2xhc3NOYW1lICYmIG9wKSB7CgkJCQkJCQkJZWFjaChvcC5jaGVja19jbGFzc2VzLCBmdW5jdGlvbihjKSB7CgkJCQkJCQkJCWlmIChkb20uaGFzQ2xhc3MocG4sIGMpKQoJCQkJCQkJCQkJZG9tLnJlbW92ZUNsYXNzKG4sIGMpOwoJCQkJCQkJCX0pOwoJCQkJCQkJfQoJCQkJCQl9CgoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJfSk7CgoJCQkJCW4ucmVtb3ZlQXR0cmlidXRlKCdfbWNlX25ldycpOwoJCQkJfSk7CgoJCQkJcmVtb3ZlRW1wdHkoKTsKCQkJCWVkLnNlbGVjdGlvbi5tb3ZlVG9Cb29rbWFyayhibSk7CgoJCQkJcmV0dXJuICEhYm07CgkJCX07CgoJCQkvLyBDcmVhdGUgaW5saW5lIGVsZW1lbnRzCgkJCWVkLmZvY3VzKCk7CgkJCWVkLmdldERvYygpLmV4ZWNDb21tYW5kKCdGb250TmFtZScsIGZhbHNlLCAnbWNlaW5saW5lJyk7CgkJCXJlcGxhY2VGb250cygpOwoKCQkJaWYgKGtoID0gdC5fYXBwbHlJbmxpbmVTdHlsZS5rZXloYW5kbGVyKSB7CgkJCQllZC5vbktleVVwLnJlbW92ZShraCk7CgkJCQllZC5vbktleVByZXNzLnJlbW92ZShraCk7CgkJCQllZC5vbktleURvd24ucmVtb3ZlKGtoKTsKCQkJCWVkLm9uU2V0Q29udGVudC5yZW1vdmUodC5fYXBwbHlJbmxpbmVTdHlsZS5jaGFuZGxlcik7CgkJCX0KCgkJCWlmIChlZC5zZWxlY3Rpb24uaXNDb2xsYXBzZWQoKSkgewoJCQkJLy8gSUUgd2lsbCBmb3JtYXQgdGhlIGN1cnJlbnQgd29yZCBzbyB0aGlzIGNvZGUgY2FuJ3QgYmUgZXhlY3V0ZWQgb24gdGhhdCBicm93c2VyCgkJCQlpZiAoIWlzSUUpIHsKCQkJCQllYWNoKGRvbS5nZXRQYXJlbnRzKGVkLnNlbGVjdGlvbi5nZXROb2RlKCksICdzcGFuJyksIGZ1bmN0aW9uKG4pIHsKCQkJCQkJZWFjaChhdC5zdHlsZSwgZnVuY3Rpb24odiwgaykgewoJCQkJCQkJdmFyIGt2OwoKCQkJCQkJCWlmIChrdiA9IGRvbS5nZXRTdHlsZShuLCBrKSkgewoJCQkJCQkJCWlmIChrdiA9PSB2KSB7CgkJCQkJCQkJCWRvbS5zZXRTdHlsZShuLCBrLCAnJyk7CgkJCQkJCQkJCWZvdW5kID0gMjsKCQkJCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCQkJCX0KCgkJCQkJCQkJZm91bmQgPSAxOwoJCQkJCQkJCXJldHVybiBmYWxzZTsKCQkJCQkJCX0KCQkJCQkJfSk7CgoJCQkJCQlpZiAoZm91bmQpCgkJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJfSk7CgoJCQkJCWlmIChmb3VuZCA9PSAyKSB7CgkJCQkJCWJtID0gZWQuc2VsZWN0aW9uLmdldEJvb2ttYXJrKCk7CgoJCQkJCQlyZW1vdmVFbXB0eSgpOwoKCQkJCQkJZWQuc2VsZWN0aW9uLm1vdmVUb0Jvb2ttYXJrKGJtKTsKCgkJCQkJCS8vIE5vZGUgY2hhbmdlIG5lZWRzIHRvIGJlIGRldGFjaGVkIHNpbmNlIHRoZSBvbnNlbGVjdCBldmVudAoJCQkJCQkvLyBmb3IgdGhlIHNlbGVjdCBib3ggd2lsbCBydW4gdGhlIG9uY2xpY2sgaGFuZGxlciBhZnRlciBvbnNlbGVjdCBjYWxsLiBUb2RvOiBBZGQgYSBuaWNlciBmaXghCgkJCQkJCXdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewoJCQkJCQkJZWQubm9kZUNoYW5nZWQoKTsKCQkJCQkJfSwgMSk7CgoJCQkJCQlyZXR1cm47CgkJCQkJfQoJCQkJfQoKCQkJCS8vIFN0YXJ0IGNvbGxlY3Rpbmcgc3R5bGVzCgkJCQl0Ll9wZW5kaW5nU3R5bGVzID0gdGlueW1jZS5leHRlbmQodC5fcGVuZGluZ1N0eWxlcyB8fCB7fSwgYXQuc3R5bGUpOwoKCQkJCXQuX2FwcGx5SW5saW5lU3R5bGUuY2hhbmRsZXIgPSBlZC5vblNldENvbnRlbnQuYWRkKGZ1bmN0aW9uKCkgewoJCQkJCWRlbGV0ZSB0Ll9wZW5kaW5nU3R5bGVzOwoJCQkJfSk7CgoJCQkJdC5fYXBwbHlJbmxpbmVTdHlsZS5rZXloYW5kbGVyID0ga2ggPSBmdW5jdGlvbihlKSB7CgkJCQkJLy8gVXNlIHBlbmRpbmcgc3R5bGVzCgkJCQkJaWYgKHQuX3BlbmRpbmdTdHlsZXMpIHsKCQkJCQkJYXQuc3R5bGUgPSB0Ll9wZW5kaW5nU3R5bGVzOwoJCQkJCQlkZWxldGUgdC5fcGVuZGluZ1N0eWxlczsKCQkJCQl9CgoJCQkJCWlmIChyZXBsYWNlRm9udHMoKSkgewoJCQkJCQllZC5vbktleURvd24ucmVtb3ZlKHQuX2FwcGx5SW5saW5lU3R5bGUua2V5aGFuZGxlcik7CgkJCQkJCWVkLm9uS2V5UHJlc3MucmVtb3ZlKHQuX2FwcGx5SW5saW5lU3R5bGUua2V5aGFuZGxlcik7CgkJCQkJfQoKCQkJCQlpZiAoZS50eXBlID09ICdrZXl1cCcpCgkJCQkJCWVkLm9uS2V5VXAucmVtb3ZlKHQuX2FwcGx5SW5saW5lU3R5bGUua2V5aGFuZGxlcik7CgkJCQl9OwoKCQkJCWVkLm9uS2V5RG93bi5hZGQoa2gpOwoJCQkJZWQub25LZXlQcmVzcy5hZGQoa2gpOwoJCQkJZWQub25LZXlVcC5hZGQoa2gpOwoJCQl9IGVsc2UKCQkJCXQuX3BlbmRpbmdTdHlsZXMgPSAwOwoJCX0KCX0pOwp9KSh0aW55bWNlKTsoZnVuY3Rpb24odGlueW1jZSkgewoJdGlueW1jZS5jcmVhdGUoJ3RpbnltY2UuVW5kb01hbmFnZXInLCB7CgkJaW5kZXggOiAwLAoJCWRhdGEgOiBudWxsLAoJCXR5cGluZyA6IDAsCgoJCVVuZG9NYW5hZ2VyIDogZnVuY3Rpb24oZWQpIHsKCQkJdmFyIHQgPSB0aGlzLCBEaXNwYXRjaGVyID0gdGlueW1jZS51dGlsLkRpc3BhdGNoZXI7CgoJCQl0LmVkaXRvciA9IGVkOwoJCQl0LmRhdGEgPSBbXTsKCQkJdC5vbkFkZCA9IG5ldyBEaXNwYXRjaGVyKHRoaXMpOwoJCQl0Lm9uVW5kbyA9IG5ldyBEaXNwYXRjaGVyKHRoaXMpOwoJCQl0Lm9uUmVkbyA9IG5ldyBEaXNwYXRjaGVyKHRoaXMpOwoJCX0sCgoJCWFkZCA6IGZ1bmN0aW9uKGwpIHsKCQkJdmFyIHQgPSB0aGlzLCBpLCBlZCA9IHQuZWRpdG9yLCBiLCBzID0gZWQuc2V0dGluZ3MsIGxhOwoKCQkJbCA9IGwgfHwge307CgkJCWwuY29udGVudCA9IGwuY29udGVudCB8fCBlZC5nZXRDb250ZW50KHtmb3JtYXQgOiAncmF3Jywgbm9fZXZlbnRzIDogMX0pOwoKCQkJLy8gQWRkIHVuZG8gbGV2ZWwgaWYgbmVlZGVkCgkJCWwuY29udGVudCA9IGwuY29udGVudC5yZXBsYWNlKC9eXHMqfFxzKiQvZywgJycpOwoJCQlsYSA9IHQuZGF0YVt0LmluZGV4ID4gMCAmJiAodC5pbmRleCA9PSAwIHx8IHQuaW5kZXggPT0gdC5kYXRhLmxlbmd0aCkgPyB0LmluZGV4IC0gMSA6IHQuaW5kZXhdOwoJCQlpZiAoIWwuaW5pdGlhbCAmJiBsYSAmJiBsLmNvbnRlbnQgPT0gbGEuY29udGVudCkKCQkJCXJldHVybiBudWxsOwoKCQkJLy8gVGltZSB0byBjb21wcmVzcwoJCQlpZiAocy5jdXN0b21fdW5kb19yZWRvX2xldmVscykgewoJCQkJaWYgKHQuZGF0YS5sZW5ndGggPiBzLmN1c3RvbV91bmRvX3JlZG9fbGV2ZWxzKSB7CgkJCQkJZm9yIChpID0gMDsgaSA8IHQuZGF0YS5sZW5ndGggLSAxOyBpKyspCgkJCQkJCXQuZGF0YVtpXSA9IHQuZGF0YVtpICsgMV07CgoJCQkJCXQuZGF0YS5sZW5ndGgtLTsKCQkJCQl0LmluZGV4ID0gdC5kYXRhLmxlbmd0aDsKCQkJCX0KCQkJfQoKCQkJaWYgKHMuY3VzdG9tX3VuZG9fcmVkb19yZXN0b3JlX3NlbGVjdGlvbiAmJiAhbC5pbml0aWFsKQoJCQkJbC5ib29rbWFyayA9IGIgPSBsLmJvb2ttYXJrIHx8IGVkLnNlbGVjdGlvbi5nZXRCb29rbWFyaygpOwoKCQkJaWYgKHQuaW5kZXggPCB0LmRhdGEubGVuZ3RoKQoJCQkJdC5pbmRleCsrOwoKCQkJLy8gT25seSBpbml0aWFsIG1hcmtlZCB1bmRvIGxldmVscyBzaG91bGQgYmUgYWxsb3dlZCBhcyBmaXJzdCBpdGVtCgkJCS8vIFRoaXMgdG8gd29ya2Fyb3VuZCBhIGJ1ZyB3aXRoIEZpcmVmb3ggYW5kIHRoZSBibHVyIGV2ZW50CgkJCWlmICh0LmRhdGEubGVuZ3RoID09PSAwICYmICFsLmluaXRpYWwpCgkJCQlyZXR1cm4gbnVsbDsKCgkJCS8vIEFkZCBsZXZlbAoJCQl0LmRhdGEubGVuZ3RoID0gdC5pbmRleCArIDE7CgkJCXQuZGF0YVt0LmluZGV4KytdID0gbDsKCgkJCWlmIChsLmluaXRpYWwpCgkJCQl0LmluZGV4ID0gMDsKCgkJCS8vIFNldCBpbml0aWFsIGJvb2ttYXJrIHVzZSBmaXJzdCByZWFsIHVuZG8gbGV2ZWwKCQkJaWYgKHQuZGF0YS5sZW5ndGggPT0gMiAmJiB0LmRhdGFbMF0uaW5pdGlhbCkKCQkJCXQuZGF0YVswXS5ib29rbWFyayA9IGI7CgoJCQl0Lm9uQWRkLmRpc3BhdGNoKHQsIGwpOwoJCQllZC5pc05vdERpcnR5ID0gMDsKCgkJCS8vY29uc29sZS5kaXIodC5kYXRhKTsKCgkJCXJldHVybiBsOwoJCX0sCgoJCXVuZG8gOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCBlZCA9IHQuZWRpdG9yLCBsID0gbCwgaTsKCgkJCWlmICh0LnR5cGluZykgewoJCQkJdC5hZGQoKTsKCQkJCXQudHlwaW5nID0gMDsKCQkJfQoKCQkJaWYgKHQuaW5kZXggPiAwKSB7CgkJCQkvLyBJZiB1bmRvIG9uIGxhc3QgaW5kZXggdGhlbiB0YWtlIHNuYXBzaG90CgkJCQlpZiAodC5pbmRleCA9PSB0LmRhdGEubGVuZ3RoICYmIHQuaW5kZXggPiAxKSB7CgkJCQkJaSA9IHQuaW5kZXg7CgkJCQkJdC50eXBpbmcgPSAwOwoKCQkJCQlpZiAoIXQuYWRkKCkpCgkJCQkJCXQuaW5kZXggPSBpOwoKCQkJCQktLXQuaW5kZXg7CgkJCQl9CgoJCQkJbCA9IHQuZGF0YVstLXQuaW5kZXhdOwoJCQkJZWQuc2V0Q29udGVudChsLmNvbnRlbnQsIHtmb3JtYXQgOiAncmF3J30pOwoJCQkJZWQuc2VsZWN0aW9uLm1vdmVUb0Jvb2ttYXJrKGwuYm9va21hcmspOwoKCQkJCXQub25VbmRvLmRpc3BhdGNoKHQsIGwpOwoJCQl9CgoJCQlyZXR1cm4gbDsKCQl9LAoKCQlyZWRvIDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpcywgZWQgPSB0LmVkaXRvciwgbCA9IG51bGw7CgoJCQlpZiAodC5pbmRleCA8IHQuZGF0YS5sZW5ndGggLSAxKSB7CgkJCQlsID0gdC5kYXRhWysrdC5pbmRleF07CgkJCQllZC5zZXRDb250ZW50KGwuY29udGVudCwge2Zvcm1hdCA6ICdyYXcnfSk7CgkJCQllZC5zZWxlY3Rpb24ubW92ZVRvQm9va21hcmsobC5ib29rbWFyayk7CgoJCQkJdC5vblJlZG8uZGlzcGF0Y2godCwgbCk7CgkJCX0KCgkJCXJldHVybiBsOwoJCX0sCgoJCWNsZWFyIDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXQuZGF0YSA9IFtdOwoJCQl0LmluZGV4ID0gMDsKCQkJdC50eXBpbmcgPSAwOwoJCQl0LmFkZCh7aW5pdGlhbCA6IHRydWV9KTsKCQl9LAoKCQloYXNVbmRvIDogZnVuY3Rpb24oKSB7CgkJCXJldHVybiB0aGlzLmluZGV4ICE9IDAgfHwgdGhpcy50eXBpbmc7CgkJfSwKCgkJaGFzUmVkbyA6IGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gdGhpcy5pbmRleCA8IHRoaXMuZGF0YS5sZW5ndGggLSAxOwoJCX0KCgkJfSk7Cn0pKHRpbnltY2UpOwooZnVuY3Rpb24odGlueW1jZSkgewoJLy8gU2hvcnRlbiBuYW1lcwoJdmFyIEV2ZW50LCBpc0lFLCBpc0dlY2tvLCBpc09wZXJhLCBlYWNoLCBleHRlbmQ7CgoJRXZlbnQgPSB0aW55bWNlLmRvbS5FdmVudDsKCWlzSUUgPSB0aW55bWNlLmlzSUU7Cglpc0dlY2tvID0gdGlueW1jZS5pc0dlY2tvOwoJaXNPcGVyYSA9IHRpbnltY2UuaXNPcGVyYTsKCWVhY2ggPSB0aW55bWNlLmVhY2g7CglleHRlbmQgPSB0aW55bWNlLmV4dGVuZDsKCglmdW5jdGlvbiBpc0VtcHR5KG4pIHsKCQluID0gbi5pbm5lckhUTUw7CgoJCW4gPSBuLnJlcGxhY2UoLzwoaW1nfGhyfHRhYmxlfGlucHV0fHNlbGVjdHx0ZXh0YXJlYSlbIFw+XS9naSwgJy0nKTsgLy8gS2VlcCB0aGVzZSBjb252ZXJ0IHRoZW0gdG8gLSBjaGFycwoJCW4gPSBuLnJlcGxhY2UoLzxbXj5dKz4vZywgJycpOyAvLyBSZW1vdmUgYWxsIHRhZ3MKCgkJcmV0dXJuIG4ucmVwbGFjZSgvWyBcdFxyXG5dKy9nLCAnJykgPT0gJyc7Cgl9OwoKCXRpbnltY2UuY3JlYXRlKCd0aW55bWNlLkZvcmNlQmxvY2tzJywgewoJCUZvcmNlQmxvY2tzIDogZnVuY3Rpb24oZWQpIHsKCQkJdmFyIHQgPSB0aGlzLCBzID0gZWQuc2V0dGluZ3MsIGVsbTsKCgkJCXQuZWRpdG9yID0gZWQ7CgkJCXQuZG9tID0gZWQuZG9tOwoJCQllbG0gPSAocy5mb3JjZWRfcm9vdF9ibG9jayB8fCAncCcpLnRvTG93ZXJDYXNlKCk7CgkJCXMuZWxlbWVudCA9IGVsbS50b1VwcGVyQ2FzZSgpOwoKCQkJZWQub25QcmVJbml0LmFkZCh0LnNldHVwLCB0KTsKCgkJCXQucmVPcGVyYSA9IG5ldyBSZWdFeHAoJyhcXHUwMGEwfCYjMTYwO3wmbmJzcDspPFwvJyArIGVsbSArICc+JywgJ2dpJyk7CgkJCXQucmVQYWRkID0gbmV3IFJlZ0V4cCgnPHAoICkoW14+XSspPjxcXFwvcD58PHAoICkoW14+XSspXFxcLz58PHAoICkoW14+XSspPlxccys8XFxcL3A+fDxwPjxcXFwvcD58PHBcXFwvPnw8cD5cXHMrPFxcXC9wPicucmVwbGFjZSgvcC9nLCBlbG0pLCAnZ2knKTsKCQkJdC5yZU5ic3AyQlIxID0gbmV3IFJlZ0V4cCgnPHAoICkoW14+XSspPltcXHNcXHUwMGEwXSs8XFxcL3A+fDxwPltcXHNcXHUwMGEwXSs8XFxcL3A+Jy5yZXBsYWNlKC9wL2csIGVsbSksICdnaScpOwoJCQl0LnJlTmJzcDJCUjIgPSBuZXcgUmVnRXhwKCc8JXAoKShbXj5dKyk+KCZuYnNwO3wmIzE2MDspPFxcXC8lcD58PCVwPigmbmJzcDt8JiMxNjA7KTxcXFwvJXA+Jy5yZXBsYWNlKC8lcC9nLCBlbG0pLCAnZ2knKTsKCQkJdC5yZUJSMk5ic3AgPSBuZXcgUmVnRXhwKCc8cCggKShbXj5dKyk+XFxzKjxiciBcXFwvPlxccyo8XFxcL3A+fDxwPlxccyo8YnIgXFxcLz5cXHMqPFxcXC9wPicucmVwbGFjZSgvcC9nLCBlbG0pLCAnZ2knKTsKCgkJCWZ1bmN0aW9uIHBhZGQoZWQsIG8pIHsKCQkJCWlmIChpc09wZXJhKQoJCQkJCW8uY29udGVudCA9IG8uY29udGVudC5yZXBsYWNlKHQucmVPcGVyYSwgJzwvJyArIGVsbSArICc+Jyk7CgoJCQkJby5jb250ZW50ID0gby5jb250ZW50LnJlcGxhY2UodC5yZVBhZGQsICc8JyArIGVsbSArICckMSQyJDMkNCQ1JDY+XHUwMGEwPC8nICsgZWxtICsgJz4nKTsKCgkJCQlpZiAoIWlzSUUgJiYgIWlzT3BlcmEgJiYgby5zZXQpIHsKCQkJCQkvLyBVc2UgJm5ic3A7IGluc3RlYWQgb2YgQlIgaW4gcGFkZGVkIHBhcmFncmFwaHMKCQkJCQlvLmNvbnRlbnQgPSBvLmNvbnRlbnQucmVwbGFjZSh0LnJlTmJzcDJCUjEsICc8JyArIGVsbSArICckMSQyPjxiciAvPjwvJyArIGVsbSArICc+Jyk7CgkJCQkJby5jb250ZW50ID0gby5jb250ZW50LnJlcGxhY2UodC5yZU5ic3AyQlIyLCAnPCcgKyBlbG0gKyAnJDEkMj48YnIgLz48LycgKyBlbG0gKyAnPicpOwoJCQkJfSBlbHNlCgkJCQkJby5jb250ZW50ID0gby5jb250ZW50LnJlcGxhY2UodC5yZUJSMk5ic3AsICc8JyArIGVsbSArICckMSQyPlx1MDBhMDwvJyArIGVsbSArICc+Jyk7CgkJCX07CgoJCQllZC5vbkJlZm9yZVNldENvbnRlbnQuYWRkKHBhZGQpOwoJCQllZC5vblBvc3RQcm9jZXNzLmFkZChwYWRkKTsKCgkJCWlmIChzLmZvcmNlZF9yb290X2Jsb2NrKSB7CgkJCQllZC5vbkluaXQuYWRkKHQuZm9yY2VSb290cywgdCk7CgkJCQllZC5vblNldENvbnRlbnQuYWRkKHQuZm9yY2VSb290cywgdCk7CgkJCQllZC5vbkJlZm9yZUdldENvbnRlbnQuYWRkKHQuZm9yY2VSb290cywgdCk7CgkJCX0KCQl9LAoKCQlzZXR1cCA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgdCA9IHRoaXMsIGVkID0gdC5lZGl0b3IsIHMgPSBlZC5zZXR0aW5nczsKCgkJCS8vIEZvcmNlIHJvb3QgYmxvY2tzIHdoZW4gdHlwaW5nIGFuZCB3aGVuIGdldHRpbmcgb3V0cHV0CgkJCWlmIChzLmZvcmNlZF9yb290X2Jsb2NrKSB7CgkJCQllZC5vbktleVVwLmFkZCh0LmZvcmNlUm9vdHMsIHQpOwoJCQkJZWQub25QcmVQcm9jZXNzLmFkZCh0LmZvcmNlUm9vdHMsIHQpOwoJCQl9CgoJCQlpZiAocy5mb3JjZV9icl9uZXdsaW5lcykgewoJCQkJLy8gRm9yY2UgSUUgdG8gcHJvZHVjZSBCUnMgb24gZW50ZXIKCQkJCWlmIChpc0lFKSB7CgkJCQkJZWQub25LZXlQcmVzcy5hZGQoZnVuY3Rpb24oZWQsIGUpIHsKCQkJCQkJdmFyIG4sIHMgPSBlZC5zZWxlY3Rpb247CgoJCQkJCQlpZiAoZS5rZXlDb2RlID09IDEzICYmIHMuZ2V0Tm9kZSgpLm5vZGVOYW1lICE9ICdMSScpIHsKCQkJCQkJCXMuc2V0Q29udGVudCgnPGJyIGlkPSJfXyIgLz4gJywge2Zvcm1hdCA6ICdyYXcnfSk7CgkJCQkJCQluID0gZWQuZG9tLmdldCgnX18nKTsKCQkJCQkJCW4ucmVtb3ZlQXR0cmlidXRlKCdpZCcpOwoJCQkJCQkJcy5zZWxlY3Qobik7CgkJCQkJCQlzLmNvbGxhcHNlKCk7CgkJCQkJCQlyZXR1cm4gRXZlbnQuY2FuY2VsKGUpOwoJCQkJCQl9CgkJCQkJfSk7CgkJCQl9CgoJCQkJcmV0dXJuOwoJCQl9CgoJCQlpZiAoIWlzSUUgJiYgcy5mb3JjZV9wX25ld2xpbmVzKSB7Ci8qCQkJCWVkLm9uUHJlUHJvY2Vzcy5hZGQoZnVuY3Rpb24oZWQsIG8pIHsKCQkJCQllYWNoKGVkLmRvbS5zZWxlY3QoJ2JyJywgby5ub2RlKSwgZnVuY3Rpb24obikgewoJCQkJCQl2YXIgcCA9IG4ucGFyZW50Tm9kZTsKCgkJCQkJCS8vIFJlcGxhY2UgPHA+PGJyIC8+PC9wPiB3aXRoIDxwPiZuYnNwOzwvcD4KCQkJCQkJaWYgKHAgJiYgcC5ub2RlTmFtZSA9PSAncCcgJiYgKHAuY2hpbGROb2Rlcy5sZW5ndGggPT0gMSB8fCBwLmxhc3RDaGlsZCA9PSBuKSkgewoJCQkJCQkJcC5yZXBsYWNlQ2hpbGQoZWQuZ2V0RG9jKCkuY3JlYXRlVGV4dE5vZGUoJ1x1MDBhMCcpLCBuKTsKCQkJCQkJfQoJCQkJCX0pOwoJCQkJfSk7Ki8KCgkJCQllZC5vbktleVByZXNzLmFkZChmdW5jdGlvbihlZCwgZSkgewoJCQkJCWlmIChlLmtleUNvZGUgPT0gMTMgJiYgIWUuc2hpZnRLZXkpIHsKCQkJCQkJaWYgKCF0Lmluc2VydFBhcmEoZSkpCgkJCQkJCQlFdmVudC5jYW5jZWwoZSk7CgkJCQkJfQoJCQkJfSk7CgoJCQkJaWYgKGlzR2Vja28pIHsKCQkJCQllZC5vbktleURvd24uYWRkKGZ1bmN0aW9uKGVkLCBlKSB7CgkJCQkJCWlmICgoZS5rZXlDb2RlID09IDggfHwgZS5rZXlDb2RlID09IDQ2KSAmJiAhZS5zaGlmdEtleSkKCQkJCQkJCXQuYmFja3NwYWNlRGVsZXRlKGUsIGUua2V5Q29kZSA9PSA4KTsKCQkJCQl9KTsKCQkJCX0KCQkJfQoKCQkJZnVuY3Rpb24gcmVuKHJuLCBuYSkgewoJCQkJdmFyIG5lID0gZWQuZG9tLmNyZWF0ZShuYSk7CgoJCQkJZWFjaChybi5hdHRyaWJ1dGVzLCBmdW5jdGlvbihhKSB7CgkJCQkJaWYgKGEuc3BlY2lmaWVkICYmIGEubm9kZVZhbHVlKQoJCQkJCQluZS5zZXRBdHRyaWJ1dGUoYS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLCBhLm5vZGVWYWx1ZSk7CgkJCQl9KTsKCgkJCQllYWNoKHJuLmNoaWxkTm9kZXMsIGZ1bmN0aW9uKG4pIHsKCQkJCQluZS5hcHBlbmRDaGlsZChuLmNsb25lTm9kZSh0cnVlKSk7CgkJCQl9KTsKCgkJCQlybi5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChuZSwgcm4pOwoKCQkJCXJldHVybiBuZTsKCQkJfTsKCgkJCS8vIFBhZGQgZW1wdHkgaW5saW5lIGVsZW1lbnRzIHdpdGhpbiBibG9jayBlbGVtZW50cwoJCQkvLyBGb3IgZXhhbXBsZTogPHA+PHN0cm9uZz48ZW0+PC9lbT48L3N0cm9uZz48L3A+IGJlY29tZXMgPHA+PHN0cm9uZz48ZW0+Jm5ic3A7PC9lbT48L3N0cm9uZz48L3A+CgkJCWVkLm9uUHJlUHJvY2Vzcy5hZGQoZnVuY3Rpb24oZWQsIG8pIHsKCQkJCWVhY2goZWQuZG9tLnNlbGVjdCgncCxoMSxoMixoMyxoNCxoNSxoNixkaXYnLCBvLm5vZGUpLCBmdW5jdGlvbihwKSB7CgkJCQkJaWYgKGlzRW1wdHkocCkpIHsKCQkJCQkJZWFjaChlZC5kb20uc2VsZWN0KCdzcGFuLGVtLHN0cm9uZyxiLGknLCBvLm5vZGUpLCBmdW5jdGlvbihuKSB7CgkJCQkJCQlpZiAoIW4uaGFzQ2hpbGROb2RlcygpKSB7CgkJCQkJCQkJbi5hcHBlbmRDaGlsZChlZC5nZXREb2MoKS5jcmVhdGVUZXh0Tm9kZSgnXHUwMGEwJykpOwoJCQkJCQkJCXJldHVybiBmYWxzZTsgLy8gQnJlYWsgdGhlIGxvb3Agb25lIHBhZGRpbmcgaXMgZW5vdWdoCgkJCQkJCQl9CgkJCQkJCX0pOwoJCQkJCX0KCQkJCX0pOwoJCQl9KTsKCgkJCS8vIElFIHNwZWNpZmljIGZpeGVzCgkJCWlmIChpc0lFKSB7CgkJCQkvLyBSZXBsYWNlcyBJRTpzIGF1dG8gZ2VuZXJhdGVkIHBhcmFncmFwaHMgd2l0aCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgbmFtZQoJCQkJaWYgKHMuZWxlbWVudCAhPSAnUCcpIHsKCQkJCQllZC5vbktleVByZXNzLmFkZChmdW5jdGlvbihlZCwgZSkgewoJCQkJCQl0Lmxhc3RFbG0gPSBlZC5zZWxlY3Rpb24uZ2V0Tm9kZSgpLm5vZGVOYW1lOwoJCQkJCX0pOwoKCQkJCQllZC5vbktleVVwLmFkZChmdW5jdGlvbihlZCwgZSkgewoJCQkJCQl2YXIgYmwsIHNlbCA9IGVkLnNlbGVjdGlvbiwgbiA9IHNlbC5nZXROb2RlKCksIGIgPSBlZC5nZXRCb2R5KCk7CgoJCQkJCQlpZiAoYi5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMSAmJiBuLm5vZGVOYW1lID09ICdQJykgewoJCQkJCQkJbiA9IHJlbihuLCBzLmVsZW1lbnQpOwoJCQkJCQkJc2VsLnNlbGVjdChuKTsKCQkJCQkJCXNlbC5jb2xsYXBzZSgpOwoJCQkJCQkJZWQubm9kZUNoYW5nZWQoKTsKCQkJCQkJfSBlbHNlIGlmIChlLmtleUNvZGUgPT0gMTMgJiYgIWUuc2hpZnRLZXkgJiYgdC5sYXN0RWxtICE9ICdQJykgewoJCQkJCQkJYmwgPSBlZC5kb20uZ2V0UGFyZW50KG4sICdwJyk7CgoJCQkJCQkJaWYgKGJsKSB7CgkJCQkJCQkJcmVuKGJsLCBzLmVsZW1lbnQpOwoJCQkJCQkJCWVkLm5vZGVDaGFuZ2VkKCk7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9KTsKCQkJCX0KCQkJfQoJCX0sCgoJCWZpbmQgOiBmdW5jdGlvbihuLCB0LCBzKSB7CgkJCXZhciBlZCA9IHRoaXMuZWRpdG9yLCB3ID0gZWQuZ2V0RG9jKCkuY3JlYXRlVHJlZVdhbGtlcihuLCA0LCBudWxsLCBmYWxzZSksIGMgPSAtMTsKCgkJCXdoaWxlIChuID0gdy5uZXh0Tm9kZSgpKSB7CgkJCQljKys7CgoJCQkJLy8gSW5kZXggYnkgbm9kZQoJCQkJaWYgKHQgPT0gMCAmJiBuID09IHMpCgkJCQkJcmV0dXJuIGM7CgoJCQkJLy8gTm9kZSBieSBpbmRleAoJCQkJaWYgKHQgPT0gMSAmJiBjID09IHMpCgkJCQkJcmV0dXJuIG47CgkJCX0KCgkJCXJldHVybiAtMTsKCQl9LAoKCQlmb3JjZVJvb3RzIDogZnVuY3Rpb24oZWQsIGUpIHsKCQkJdmFyIHQgPSB0aGlzLCBlZCA9IHQuZWRpdG9yLCBiID0gZWQuZ2V0Qm9keSgpLCBkID0gZWQuZ2V0RG9jKCksIHNlID0gZWQuc2VsZWN0aW9uLCBzID0gc2UuZ2V0U2VsKCksIHIgPSBzZS5nZXRSbmcoKSwgc2kgPSAtMiwgZWksIHNvLCBlbywgdHIsIGMgPSAtMHhGRkZGRkY7CgkJCXZhciBueCwgYmwsIGJwLCBzcCwgbGUsIG5sID0gYi5jaGlsZE5vZGVzLCBpLCBuLCBlaWQ7CgoJCQkvLyBGaXggZm9yIGJ1ZyAjMTg2Mzg0NwoJCQkvL2lmIChlICYmIGUua2V5Q29kZSA9PSAxMykKCQkJLy8JcmV0dXJuIHRydWU7CgoJCQkvLyBXcmFwIG5vbiBibG9ja3MgaW50byBibG9ja3MKCQkJZm9yIChpID0gbmwubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHsKCQkJCW54ID0gbmxbaV07CgoJCQkJLy8gSXMgdGV4dCBvciBub24gYmxvY2sgZWxlbWVudAoJCQkJaWYgKG54Lm5vZGVUeXBlID09IDMgfHwgKCF0LmRvbS5pc0Jsb2NrKG54KSAmJiBueC5ub2RlVHlwZSAhPSA4KSkgewoJCQkJCWlmICghYmwpIHsKCQkJCQkJLy8gQ3JlYXRlIG5ldyBibG9jayBidXQgaWdub3JlIHdoaXRlc3BhY2UKCQkJCQkJaWYgKG54Lm5vZGVUeXBlICE9IDMgfHwgL1teXHNdL2cudGVzdChueC5ub2RlVmFsdWUpKSB7CgkJCQkJCQkvLyBTdG9yZSBzZWxlY3Rpb24KCQkJCQkJCWlmIChzaSA9PSAtMiAmJiByKSB7CgkJCQkJCQkJaWYgKCFpc0lFKSB7CgkJCQkJCQkJCS8vIElmIHNlbGVjdGlvbiBpcyBlbGVtZW50IHRoZW4gbWFyayBpdAoJCQkJCQkJCQlpZiAoci5zdGFydENvbnRhaW5lci5ub2RlVHlwZSA9PSAxICYmIChuID0gci5zdGFydENvbnRhaW5lci5jaGlsZE5vZGVzW3Iuc3RhcnRPZmZzZXRdKSAmJiBuLm5vZGVUeXBlID09IDEpIHsKCQkJCQkJCQkJCS8vIFNhdmUgdGhlIGlkIG9mIHRoZSBzZWxlY3RlZCBlbGVtZW50CgkJCQkJCQkJCQllaWQgPSBuLmdldEF0dHJpYnV0ZSgiaWQiKTsKCQkJCQkJCQkJCW4uc2V0QXR0cmlidXRlKCJpZCIsICJfX21jZSIpOwoJCQkJCQkJCQl9IGVsc2UgewoJCQkJCQkJCQkJLy8gSWYgZWxlbWVudCBpcyBpbnNpZGUgYm9keSwgbWlnaHQgbm90IGJlIHRoZSBjYXNlIGluIGNvbnRlbnRFZGlhYmxlIG1vZGUKCQkJCQkJCQkJCWlmIChlZC5kb20uZ2V0UGFyZW50KHIuc3RhcnRDb250YWluZXIsIGZ1bmN0aW9uKGUpIHtyZXR1cm4gZSA9PT0gYjt9KSkgewoJCQkJCQkJCQkJCXNvID0gci5zdGFydE9mZnNldDsKCQkJCQkJCQkJCQllbyA9IHIuZW5kT2Zmc2V0OwoJCQkJCQkJCQkJCXNpID0gdC5maW5kKGIsIDAsIHIuc3RhcnRDb250YWluZXIpOwoJCQkJCQkJCQkJCWVpID0gdC5maW5kKGIsIDAsIHIuZW5kQ29udGFpbmVyKTsKCQkJCQkJCQkJCX0KCQkJCQkJCQkJfQoJCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkJCXRyID0gZC5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpOwoJCQkJCQkJCQl0ci5tb3ZlVG9FbGVtZW50VGV4dChiKTsKCQkJCQkJCQkJdHIuY29sbGFwc2UoMSk7CgkJCQkJCQkJCWJwID0gdHIubW92ZSgnY2hhcmFjdGVyJywgYykgKiAtMTsKCgkJCQkJCQkJCXRyID0gci5kdXBsaWNhdGUoKTsKCQkJCQkJCQkJdHIuY29sbGFwc2UoMSk7CgkJCQkJCQkJCXNwID0gdHIubW92ZSgnY2hhcmFjdGVyJywgYykgKiAtMTsKCgkJCQkJCQkJCXRyID0gci5kdXBsaWNhdGUoKTsKCQkJCQkJCQkJdHIuY29sbGFwc2UoMCk7CgkJCQkJCQkJCWxlID0gKHRyLm1vdmUoJ2NoYXJhY3RlcicsIGMpICogLTEpIC0gc3A7CgoJCQkJCQkJCQlzaSA9IHNwIC0gYnA7CgkJCQkJCQkJCWVpID0gbGU7CgkJCQkJCQkJfQoJCQkJCQkJfQoKCQkJCQkJCWJsID0gZWQuZG9tLmNyZWF0ZShlZC5zZXR0aW5ncy5mb3JjZWRfcm9vdF9ibG9jayk7CgkJCQkJCQlibC5hcHBlbmRDaGlsZChueC5jbG9uZU5vZGUoMSkpOwoJCQkJCQkJbngucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoYmwsIG54KTsKCQkJCQkJfQoJCQkJCX0gZWxzZSB7CgkJCQkJCWlmIChibC5oYXNDaGlsZE5vZGVzKCkpCgkJCQkJCQlibC5pbnNlcnRCZWZvcmUobngsIGJsLmZpcnN0Q2hpbGQpOwoJCQkJCQllbHNlCgkJCQkJCQlibC5hcHBlbmRDaGlsZChueCk7CgkJCQkJfQoJCQkJfSBlbHNlCgkJCQkJYmwgPSBudWxsOyAvLyBUaW1lIHRvIGNyZWF0ZSBuZXcgYmxvY2sKCQkJfQoKCQkJLy8gUmVzdG9yZSBzZWxlY3Rpb24KCQkJaWYgKHNpICE9IC0yKSB7CgkJCQlpZiAoIWlzSUUpIHsKCQkJCQlibCA9IGIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoZWQuc2V0dGluZ3MuZWxlbWVudClbMF07CgkJCQkJciA9IGQuY3JlYXRlUmFuZ2UoKTsKCgkJCQkJLy8gU2VsZWN0IGxhc3QgbG9jYXRpb24gb3IgZ2VuZXJhdGVkIGJsb2NrCgkJCQkJaWYgKHNpICE9IC0xKQoJCQkJCQlyLnNldFN0YXJ0KHQuZmluZChiLCAxLCBzaSksIHNvKTsKCQkJCQllbHNlCgkJCQkJCXIuc2V0U3RhcnQoYmwsIDApOwoKCQkJCQkvLyBTZWxlY3QgbGFzdCBsb2NhdGlvbiBvciBnZW5lcmF0ZWQgYmxvY2sKCQkJCQlpZiAoZWkgIT0gLTEpCgkJCQkJCXIuc2V0RW5kKHQuZmluZChiLCAxLCBlaSksIGVvKTsKCQkJCQllbHNlCgkJCQkJCXIuc2V0RW5kKGJsLCAwKTsKCgkJCQkJaWYgKHMpIHsKCQkJCQkJcy5yZW1vdmVBbGxSYW5nZXMoKTsKCQkJCQkJcy5hZGRSYW5nZShyKTsKCQkJCQl9CgkJCQl9IGVsc2UgewoJCQkJCXRyeSB7CgkJCQkJCXIgPSBzLmNyZWF0ZVJhbmdlKCk7CgkJCQkJCXIubW92ZVRvRWxlbWVudFRleHQoYik7CgkJCQkJCXIuY29sbGFwc2UoMSk7CgkJCQkJCXIubW92ZVN0YXJ0KCdjaGFyYWN0ZXInLCBzaSk7CgkJCQkJCXIubW92ZUVuZCgnY2hhcmFjdGVyJywgZWkpOwoJCQkJCQlyLnNlbGVjdCgpOwoJCQkJCX0gY2F0Y2ggKGV4KSB7CgkJCQkJCS8vIElnbm9yZQoJCQkJCX0KCQkJCX0KCQkJfSBlbHNlIGlmICghaXNJRSAmJiAobiA9IGVkLmRvbS5nZXQoJ19fbWNlJykpKSB7CgkJCQkvLyBSZXN0b3JlIHRoZSBpZCBvZiB0aGUgc2VsZWN0ZWQgZWxlbWVudAoJCQkJaWYgKGVpZCkKCQkJCQluLnNldEF0dHJpYnV0ZSgnaWQnLCBlaWQpOwoJCQkJZWxzZQoJCQkJCW4ucmVtb3ZlQXR0cmlidXRlKCdpZCcpOwoKCQkJCS8vIE1vdmUgY2FyZXQgYmVmb3JlIHNlbGVjdGVkIGVsZW1lbnQKCQkJCXIgPSBkLmNyZWF0ZVJhbmdlKCk7CgkJCQlyLnNldFN0YXJ0QmVmb3JlKG4pOwoJCQkJci5zZXRFbmRCZWZvcmUobik7CgkJCQlzZS5zZXRSbmcocik7CgkJCX0KCQl9LAoKCQlnZXRQYXJlbnRCbG9jayA6IGZ1bmN0aW9uKG4pIHsKCQkJdmFyIGQgPSB0aGlzLmRvbTsKCgkJCXJldHVybiBkLmdldFBhcmVudChuLCBkLmlzQmxvY2spOwoJCX0sCgoJCWluc2VydFBhcmEgOiBmdW5jdGlvbihlKSB7CgkJCXZhciB0ID0gdGhpcywgZWQgPSB0LmVkaXRvciwgZG9tID0gZWQuZG9tLCBkID0gZWQuZ2V0RG9jKCksIHNlID0gZWQuc2V0dGluZ3MsIHMgPSBlZC5zZWxlY3Rpb24uZ2V0U2VsKCksIHIgPSBzLmdldFJhbmdlQXQoMCksIGIgPSBkLmJvZHk7CgkJCXZhciByYiwgcmEsIGRpciwgc24sIHNvLCBlbiwgZW8sIHNiLCBlYiwgYm4sIGJlZiwgYWZ0LCBzYywgZWMsIG4sIHZwID0gZG9tLmdldFZpZXdQb3J0KGVkLmdldFdpbigpKSwgeSwgY2gsIGNhcjsKCgkJCS8vIElmIHJvb3QgYmxvY2tzIGFyZSBmb3JjZWQgdGhlbiB1c2UgT3BlcmFzIGRlZmF1bHQgYmVoYXZpb3Igc2luY2UgaXQncyByZWFsbHkgZ29vZAovLyBSZW1vdmVkIGR1ZSB0byBidWc6ICMxODUzODE2Ci8vCQkJaWYgKHNlLmZvcmNlZF9yb290X2Jsb2NrICYmIGlzT3BlcmEpCi8vCQkJCXJldHVybiB0cnVlOwoKCQkJLy8gU2V0dXAgYmVmb3JlIHJhbmdlCgkJCXJiID0gZC5jcmVhdGVSYW5nZSgpOwoKCQkJLy8gSWYgaXMgYmVmb3JlIHRoZSBmaXJzdCBibG9jayBlbGVtZW50IGFuZCBpbiBib2R5LCB0aGVuIG1vdmUgaXQgaW50byBmaXJzdCBibG9jayBlbGVtZW50CgkJCXJiLnNldFN0YXJ0KHMuYW5jaG9yTm9kZSwgcy5hbmNob3JPZmZzZXQpOwoJCQlyYi5jb2xsYXBzZSh0cnVlKTsKCgkJCS8vIFNldHVwIGFmdGVyIHJhbmdlCgkJCXJhID0gZC5jcmVhdGVSYW5nZSgpOwoKCQkJLy8gSWYgaXMgYmVmb3JlIHRoZSBmaXJzdCBibG9jayBlbGVtZW50IGFuZCBpbiBib2R5LCB0aGVuIG1vdmUgaXQgaW50byBmaXJzdCBibG9jayBlbGVtZW50CgkJCXJhLnNldFN0YXJ0KHMuZm9jdXNOb2RlLCBzLmZvY3VzT2Zmc2V0KTsKCQkJcmEuY29sbGFwc2UodHJ1ZSk7CgoJCQkvLyBTZXR1cCBzdGFydC9lbmQgcG9pbnRzCgkJCWRpciA9IHJiLmNvbXBhcmVCb3VuZGFyeVBvaW50cyhyYi5TVEFSVF9UT19FTkQsIHJhKSA8IDA7CgkJCXNuID0gZGlyID8gcy5hbmNob3JOb2RlIDogcy5mb2N1c05vZGU7CgkJCXNvID0gZGlyID8gcy5hbmNob3JPZmZzZXQgOiBzLmZvY3VzT2Zmc2V0OwoJCQllbiA9IGRpciA/IHMuZm9jdXNOb2RlIDogcy5hbmNob3JOb2RlOwoJCQllbyA9IGRpciA/IHMuZm9jdXNPZmZzZXQgOiBzLmFuY2hvck9mZnNldDsKCiAgICAgICAgICAgIC8vIEFUTEFTU0lBTiAtIFNraXAgcGFyYWdyYXBocyBmb3IgdGFibGUgY2VsbHMKICAgICAgICAgICAgaWYgKC9eKFREfFRIKSQvLnRlc3Qoc24ubm9kZU5hbWUpIHx8IChzbi5ub2RlVHlwZT09MyAmJiAvXihURHxUSCkkLy50ZXN0KHNuLnBhcmVudE5vZGUubm9kZU5hbWUpKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCgkJCS8vIElmIHNlbGVjdGlvbiBpcyBpbiBlbXB0eSB0YWJsZSBjZWxsCgkJCWlmIChzbiA9PT0gZW4gJiYgL14oVER8VEgpJC8udGVzdChzbi5ub2RlTmFtZSkpIHsKCQkJCWlmIChzbi5maXJzdENoaWxkLm5vZGVOYW1lID09ICdCUicpCgkJCQkJZG9tLnJlbW92ZShzbi5maXJzdENoaWxkKTsgLy8gUmVtb3ZlIEJSCgoJCQkJLy8gQ3JlYXRlIHR3byBuZXcgYmxvY2sgZWxlbWVudHMKCQkJCWlmIChzbi5jaGlsZE5vZGVzLmxlbmd0aCA9PSAwKSB7CgkJCQkJZWQuZG9tLmFkZChzbiwgc2UuZWxlbWVudCwgbnVsbCwgJzxiciAvPicpOwoJCQkJCWFmdCA9IGVkLmRvbS5hZGQoc24sIHNlLmVsZW1lbnQsIG51bGwsICc8YnIgLz4nKTsKCQkJCX0gZWxzZSB7CgkJCQkJbiA9IHNuLmlubmVySFRNTDsKCQkJCQlzbi5pbm5lckhUTUwgPSAnJzsKCQkJCQllZC5kb20uYWRkKHNuLCBzZS5lbGVtZW50LCBudWxsLCBuKTsKCQkJCQlhZnQgPSBlZC5kb20uYWRkKHNuLCBzZS5lbGVtZW50LCBudWxsLCAnPGJyIC8+Jyk7CgkJCQl9CgoJCQkJLy8gTW92ZSBjYXJldCBpbnRvIHRoZSBsYXN0IG9uZQoJCQkJciA9IGQuY3JlYXRlUmFuZ2UoKTsKCQkJCXIuc2VsZWN0Tm9kZUNvbnRlbnRzKGFmdCk7CgkJCQlyLmNvbGxhcHNlKDEpOwoJCQkJZWQuc2VsZWN0aW9uLnNldFJuZyhyKTsKCgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCgkJCS8vIElmIHRoZSBjYXJldCBpcyBpbiBhbiBpbnZhbGlkIGxvY2F0aW9uIGluIEZGIHdlIG5lZWQgdG8gbW92ZSBpdCBpbnRvIHRoZSBmaXJzdCBibG9jawoJCQlpZiAoc24gPT0gYiAmJiBlbiA9PSBiICYmIGIuZmlyc3RDaGlsZCAmJiBlZC5kb20uaXNCbG9jayhiLmZpcnN0Q2hpbGQpKSB7CgkJCQlzbiA9IGVuID0gc24uZmlyc3RDaGlsZDsKCQkJCXNvID0gZW8gPSAwOwoJCQkJcmIgPSBkLmNyZWF0ZVJhbmdlKCk7CgkJCQlyYi5zZXRTdGFydChzbiwgMCk7CgkJCQlyYSA9IGQuY3JlYXRlUmFuZ2UoKTsKCQkJCXJhLnNldFN0YXJ0KGVuLCAwKTsKCQkJfQoKCQkJLy8gTmV2ZXIgdXNlIGJvZHkgYXMgc3RhcnQgb3IgZW5kIG5vZGUKCQkJc24gPSBzbi5ub2RlTmFtZSA9PSAiSFRNTCIgPyBkLmJvZHkgOiBzbjsgLy8gRml4IGZvciBPcGVyYSBidWc6IGh0dHBzOi8vYnVncy5vcGVyYS5jb20vc2hvd19idWcuY2dpP2lkPTI3MzIyNCZjb21tZW50cz15ZXMKCQkJc24gPSBzbi5ub2RlTmFtZSA9PSAiQk9EWSIgPyBzbi5maXJzdENoaWxkIDogc247CgkJCWVuID0gZW4ubm9kZU5hbWUgPT0gIkhUTUwiID8gZC5ib2R5IDogZW47IC8vIEZpeCBmb3IgT3BlcmEgYnVnOiBodHRwczovL2J1Z3Mub3BlcmEuY29tL3Nob3dfYnVnLmNnaT9pZD0yNzMyMjQmY29tbWVudHM9eWVzCgkJCWVuID0gZW4ubm9kZU5hbWUgPT0gIkJPRFkiID8gZW4uZmlyc3RDaGlsZCA6IGVuOwoKCQkJLy8gR2V0IHN0YXJ0IGFuZCBlbmQgYmxvY2tzCgkJCXNiID0gdC5nZXRQYXJlbnRCbG9jayhzbik7CgkJCWViID0gdC5nZXRQYXJlbnRCbG9jayhlbik7CgkJCWJuID0gc2IgPyBzYi5ub2RlTmFtZSA6IHNlLmVsZW1lbnQ7IC8vIEdldCBibG9jayBuYW1lIHRvIGNyZWF0ZQoKCQkJLy8gUmV0dXJuIGluc2lkZSBsaXN0IHVzZSBkZWZhdWx0IGJyb3dzZXIgYmVoYXZpb3IKCQkJaWYgKHQuZG9tLmdldFBhcmVudChzYiwgJ29sLHVsLHByZScpKQoJCQkJcmV0dXJuIHRydWU7CgoJCQkvLyBJZiBjYXB0aW9uIG9yIGFic29sdXRlIGxheWVycyB0aGVuIGFsd2F5cyBnZW5lcmF0ZSBuZXcgYmxvY2tzIHdpdGhpbgoJCQlpZiAoc2IgJiYgKHNiLm5vZGVOYW1lID09ICdDQVBUSU9OJyB8fCAvYWJzb2x1dGV8cmVsYXRpdmV8Zml4ZWQvZ2kudGVzdChkb20uZ2V0U3R5bGUoc2IsICdwb3NpdGlvbicsIDEpKSkpIHsKCQkJCWJuID0gc2UuZWxlbWVudDsKCQkJCXNiID0gbnVsbDsKCQkJfQoKCQkJLy8gSWYgY2FwdGlvbiBvciBhYnNvbHV0ZSBsYXllcnMgdGhlbiBhbHdheXMgZ2VuZXJhdGUgbmV3IGJsb2NrcyB3aXRoaW4KCQkJaWYgKGViICYmIChlYi5ub2RlTmFtZSA9PSAnQ0FQVElPTicgfHwgL2Fic29sdXRlfHJlbGF0aXZlfGZpeGVkL2dpLnRlc3QoZG9tLmdldFN0eWxlKHNiLCAncG9zaXRpb24nLCAxKSkpKSB7CgkJCQlibiA9IHNlLmVsZW1lbnQ7CgkJCQllYiA9IG51bGw7CgkJCX0KCgkJCS8vIFVzZSBQIGluc3RlYWQKCQkJaWYgKC8oVER8VEFCTEV8VEh8Q0FQVElPTikvLnRlc3QoYm4pIHx8IChzYiAmJiBibiA9PSAiRElWIiAmJiAvbGVmdHxyaWdodC9naS50ZXN0KGRvbS5nZXRTdHlsZShzYiwgJ2Zsb2F0JywgMSkpKSkgewoJCQkJYm4gPSBzZS5lbGVtZW50OwoJCQkJc2IgPSBlYiA9IG51bGw7CgkJCX0KCgkJCS8vIFNldHVwIG5ldyBiZWZvcmUgYW5kIGFmdGVyIGJsb2NrcwoJCQliZWYgPSAoc2IgJiYgc2Iubm9kZU5hbWUgPT0gYm4pID8gc2IuY2xvbmVOb2RlKDApIDogZWQuZG9tLmNyZWF0ZShibik7CgkJCWFmdCA9IChlYiAmJiBlYi5ub2RlTmFtZSA9PSBibikgPyBlYi5jbG9uZU5vZGUoMCkgOiBlZC5kb20uY3JlYXRlKGJuKTsKCgkJCS8vIFJlbW92ZSBpZCBmcm9tIGFmdGVyIGNsb25lCgkJCWFmdC5yZW1vdmVBdHRyaWJ1dGUoJ2lkJyk7CgoJCQkvLyBJcyBoZWFkZXIgYW5kIGN1cnNvciBpcyBhdCB0aGUgZW5kLCB0aGVuIGZvcmNlIHBhcmFncmFwaCB1bmRlcgoJCQlpZiAoL14oSFsxLTZdKSQvLnRlc3QoYm4pICYmIHNuLm5vZGVWYWx1ZSAmJiBzbyA9PSBzbi5ub2RlVmFsdWUubGVuZ3RoKQoJCQkJYWZ0ID0gZWQuZG9tLmNyZWF0ZShzZS5lbGVtZW50KTsKCgkJCS8vIEZpbmQgc3RhcnQgY2hvcCBub2RlCgkJCW4gPSBzYyA9IHNuOwoJCQlkbyB7CgkJCQlpZiAobiA9PSBiIHx8IG4ubm9kZVR5cGUgPT0gOSB8fCB0LmRvbS5pc0Jsb2NrKG4pIHx8IC8oVER8VEFCTEV8VEh8Q0FQVElPTikvLnRlc3Qobi5ub2RlTmFtZSkpCgkJCQkJYnJlYWs7CgoJCQkJc2MgPSBuOwoJCQl9IHdoaWxlICgobiA9IG4ucHJldmlvdXNTaWJsaW5nID8gbi5wcmV2aW91c1NpYmxpbmcgOiBuLnBhcmVudE5vZGUpKTsKCgkJCS8vIEZpbmQgZW5kIGNob3Agbm9kZQoJCQluID0gZWMgPSBlbjsKCQkJZG8gewoJCQkJaWYgKG4gPT0gYiB8fCBuLm5vZGVUeXBlID09IDkgfHwgdC5kb20uaXNCbG9jayhuKSB8fCAvKFREfFRBQkxFfFRIfENBUFRJT04pLy50ZXN0KG4ubm9kZU5hbWUpKQoJCQkJCWJyZWFrOwoKCQkJCWVjID0gbjsKCQkJfSB3aGlsZSAoKG4gPSBuLm5leHRTaWJsaW5nID8gbi5uZXh0U2libGluZyA6IG4ucGFyZW50Tm9kZSkpOwoKCQkJLy8gUGxhY2UgZmlyc3QgY2hvcCBwYXJ0IGludG8gYmVmb3JlIGJsb2NrIGVsZW1lbnQKCQkJaWYgKHNjLm5vZGVOYW1lID09IGJuKQoJCQkJcmIuc2V0U3RhcnQoc2MsIDApOwoJCQllbHNlCgkJCQlyYi5zZXRTdGFydEJlZm9yZShzYyk7CgoJCQlyYi5zZXRFbmQoc24sIHNvKTsKCQkJYmVmLmFwcGVuZENoaWxkKHJiLmNsb25lQ29udGVudHMoKSB8fCBkLmNyZWF0ZVRleHROb2RlKCcnKSk7IC8vIEVtcHR5IHRleHQgbm9kZSBuZWVkZWQgZm9yIFNhZmFyaQoKCQkJLy8gUGxhY2Ugc2VjbmQgY2hvcCBwYXJ0IHdpdGhpbiBuZXcgYmxvY2sgZWxlbWVudAoJCQl0cnkgewoJCQkJcmEuc2V0RW5kQWZ0ZXIoZWMpOwoJCQl9IGNhdGNoKGV4KSB7CgkJCQkvL2NvbnNvbGUuZGVidWcocy5mb2N1c05vZGUsIHMuZm9jdXNPZmZzZXQpOwoJCQl9CgoJCQlyYS5zZXRTdGFydChlbiwgZW8pOwoJCQlhZnQuYXBwZW5kQ2hpbGQocmEuY2xvbmVDb250ZW50cygpIHx8IGQuY3JlYXRlVGV4dE5vZGUoJycpKTsgLy8gRW1wdHkgdGV4dCBub2RlIG5lZWRlZCBmb3IgU2FmYXJpCgoJCQkvLyBDcmVhdGUgcmFuZ2UgYXJvdW5kIGV2ZXJ5dGhpbmcKCQkJciA9IGQuY3JlYXRlUmFuZ2UoKTsKCQkJaWYgKCFzYy5wcmV2aW91c1NpYmxpbmcgJiYgc2MucGFyZW50Tm9kZS5ub2RlTmFtZSA9PSBibikgewoJCQkJci5zZXRTdGFydEJlZm9yZShzYy5wYXJlbnROb2RlKTsKCQkJfSBlbHNlIHsKCQkJCWlmIChyYi5zdGFydENvbnRhaW5lci5ub2RlTmFtZSA9PSBibiAmJiByYi5zdGFydE9mZnNldCA9PSAwKQoJCQkJCXIuc2V0U3RhcnRCZWZvcmUocmIuc3RhcnRDb250YWluZXIpOwoJCQkJZWxzZQoJCQkJCXIuc2V0U3RhcnQocmIuc3RhcnRDb250YWluZXIsIHJiLnN0YXJ0T2Zmc2V0KTsKCQkJfQoKCQkJaWYgKCFlYy5uZXh0U2libGluZyAmJiBlYy5wYXJlbnROb2RlLm5vZGVOYW1lID09IGJuKQoJCQkJci5zZXRFbmRBZnRlcihlYy5wYXJlbnROb2RlKTsKCQkJZWxzZQoJCQkJci5zZXRFbmQocmEuZW5kQ29udGFpbmVyLCByYS5lbmRPZmZzZXQpOwoKCQkJLy8gRGVsZXRlIGFuZCByZXBsYWNlIGl0IHdpdGggbmV3IGJsb2NrIGVsZW1lbnRzCgkJCXIuZGVsZXRlQ29udGVudHMoKTsKCgkJCWlmIChpc09wZXJhKQoJCQkJZWQuZ2V0V2luKCkuc2Nyb2xsVG8oMCwgdnAueSk7CgoJCQkvLyBOZXZlciB3cmFwIGJsb2NrcyBpbiBibG9ja3MKCQkJaWYgKGJlZi5maXJzdENoaWxkICYmIGJlZi5maXJzdENoaWxkLm5vZGVOYW1lID09IGJuKQoJCQkJYmVmLmlubmVySFRNTCA9IGJlZi5maXJzdENoaWxkLmlubmVySFRNTDsKCgkJCWlmIChhZnQuZmlyc3RDaGlsZCAmJiBhZnQuZmlyc3RDaGlsZC5ub2RlTmFtZSA9PSBibikKCQkJCWFmdC5pbm5lckhUTUwgPSBhZnQuZmlyc3RDaGlsZC5pbm5lckhUTUw7CgoJCQkvLyBQYWRkIGVtcHR5IGJsb2NrcwoJCQlpZiAoaXNFbXB0eShiZWYpKQoJCQkJYmVmLmlubmVySFRNTCA9ICc8YnIgLz4nOwoKCQkJZnVuY3Rpb24gYXBwZW5kU3R5bGVzKGUsIGVuKSB7CgkJCQl2YXIgbmwgPSBbXSwgbm4sIG4sIGk7CgoJCQkJZS5pbm5lckhUTUwgPSAnJzsKCgkJCQkvLyBNYWtlIGNsb25lcyBvZiBzdHlsZSBlbGVtZW50cwoJCQkJaWYgKHNlLmtlZXBfc3R5bGVzKSB7CgkJCQkJbiA9IGVuOwoJCQkJCWRvIHsKCQkJCQkJLy8gV2Ugb25seSB3YW50IHN0eWxlIHNwZWNpZmljIGVsZW1lbnRzCgkJCQkJCWlmICgvXihTUEFOfFNUUk9OR3xCfEVNfEl8Rk9OVHxTVFJJS0V8VSkkLy50ZXN0KG4ubm9kZU5hbWUpKSB7CgkJCQkJCQlubiA9IG4uY2xvbmVOb2RlKGZhbHNlKTsKCQkJCQkJCWRvbS5zZXRBdHRyaWIobm4sICdpZCcsICcnKTsgLy8gUmVtb3ZlIElEIHNpbmNlIGl0IG5lZWRzIHRvIGJlIHVuaXF1ZQoJCQkJCQkJbmwucHVzaChubik7CgkJCQkJCX0KCQkJCQl9IHdoaWxlIChuID0gbi5wYXJlbnROb2RlKTsKCQkJCX0KCgkJCQkvLyBBcHBlbmQgc3R5bGUgZWxlbWVudHMgdG8gYWZ0CgkJCQlpZiAobmwubGVuZ3RoID4gMCkgewoJCQkJCWZvciAoaSA9IG5sLmxlbmd0aCAtIDEsIG5uID0gZTsgaSA+PSAwOyBpLS0pCgkJCQkJCW5uID0gbm4uYXBwZW5kQ2hpbGQobmxbaV0pOwoKCQkJCQkvLyBQYWRkIG1vc3QgaW5uZXIgc3R5bGUgZWxlbWVudAoJCQkJCW5sWzBdLmlubmVySFRNTCA9IGlzT3BlcmEgPyAnJm5ic3A7JyA6ICc8YnIgLz4nOyAvLyBFeHRyYSBzcGFjZSBmb3IgT3BlcmEgc28gdGhhdCB0aGUgY2FyZXQgY2FuIG1vdmUgdGhlcmUKCQkJCQlyZXR1cm4gbmxbMF07IC8vIE1vdmUgY2FyZXQgdG8gbW9zdCBpbm5lciBlbGVtZW50CgkJCQl9IGVsc2UKCQkJCQllLmlubmVySFRNTCA9IGlzT3BlcmEgPyAnJm5ic3A7JyA6ICc8YnIgLz4nOyAvLyBFeHRyYSBzcGFjZSBmb3IgT3BlcmEgc28gdGhhdCB0aGUgY2FyZXQgY2FuIG1vdmUgdGhlcmUKCQkJfTsKCgkJCS8vIEZpbGwgZW1wdHkgYWZ0ZXJibG9vayB3aXRoIGN1cnJlbnQgc3R5bGUKCQkJaWYgKGlzRW1wdHkoYWZ0KSkKCQkJCWNhciA9IGFwcGVuZFN0eWxlcyhhZnQsIGVuKTsKCgkJCS8vIE9wZXJhIG5lZWRzIHRoaXMgb25lIGJhY2t3YXJkcyBmb3Igb2xkZXIgdmVyc2lvbnMKCQkJaWYgKGlzT3BlcmEgJiYgcGFyc2VGbG9hdChvcGVyYS52ZXJzaW9uKCkpIDwgOS41KSB7CgkJCQlyLmluc2VydE5vZGUoYmVmKTsKCQkJCXIuaW5zZXJ0Tm9kZShhZnQpOwoJCQl9IGVsc2UgewoJCQkJci5pbnNlcnROb2RlKGFmdCk7CgkJCQlyLmluc2VydE5vZGUoYmVmKTsKCQkJfQoKCQkJLy8gTm9ybWFsaXplCgkJCWFmdC5ub3JtYWxpemUoKTsKCQkJYmVmLm5vcm1hbGl6ZSgpOwoKCQkJZnVuY3Rpb24gZmlyc3QobikgewoJCQkJcmV0dXJuIGQuY3JlYXRlVHJlZVdhbGtlcihuLCBOb2RlRmlsdGVyLlNIT1dfVEVYVCwgbnVsbCwgZmFsc2UpLm5leHROb2RlKCkgfHwgbjsKCQkJfTsKCgkJCS8vIE1vdmUgY3Vyc29yIGFuZCBzY3JvbGwgaW50byB2aWV3CgkJCXIgPSBkLmNyZWF0ZVJhbmdlKCk7CgkJCXIuc2VsZWN0Tm9kZUNvbnRlbnRzKGlzR2Vja28gPyBmaXJzdChjYXIgfHwgYWZ0KSA6IGNhciB8fCBhZnQpOwoJCQlyLmNvbGxhcHNlKDEpOwoJCQlzLnJlbW92ZUFsbFJhbmdlcygpOwoJCQlzLmFkZFJhbmdlKHIpOwoKCQkJLy8gc2Nyb2xsSW50b1ZpZXcgc2VlbXMgdG8gc2Nyb2xsIHRoZSBwYXJlbnQgd2luZG93IGluIG1vc3QgYnJvd3NlcnMgbm93IGluY2x1ZGluZyBGRiAzLjBiNCBzbyBpdCdzIHRpbWUgdG8gc3RvcCB1c2luZyBpdCBhbmQgZG8gaXQgb3VyIHNlbGZzCgkJCXkgPSBlZC5kb20uZ2V0UG9zKGFmdCkueTsKCQkJY2ggPSBhZnQuY2xpZW50SGVpZ2h0OwoKCQkJLy8gSXMgZWxlbWVudCB3aXRoaW4gdmlld3BvcnQKCQkJaWYgKHkgPCB2cC55IHx8IHkgKyBjaCA+IHZwLnkgKyB2cC5oKSB7CgkJCQllZC5nZXRXaW4oKS5zY3JvbGxUbygwLCB5IDwgdnAueSA/IHkgOiB5IC0gdnAuaCArIDI1KTsgLy8gTmVlZHMgdG8gYmUgaGFyZGNvZGVkIHRvIHJvdWdobHkgb25lIGxpbmUgb2YgdGV4dCBpZiBhIGh1Z2UgdGV4dCBibG9jayBpcyBicm9rZW4gaW50byB0d28gYmxvY2tzCgkJCQkvL2NvbnNvbGUubG9nKCdTQ1JPTEwhJywgJ3ZwLnk6ICcgKyB2cC55LCAneScgKyB5LCAndnAuaCcgKyB2cC5oLCAnY2xpZW50SGVpZ2h0JyArIGFmdC5jbGllbnRIZWlnaHQsICd5eXk6ICcgKyAoeSA8IHZwLnkgPyB5IDogeSAtIHZwLmggKyBhZnQuY2xpZW50SGVpZ2h0KSk7CgkJCX0KCgkJCXJldHVybiBmYWxzZTsKCQl9LAoKCQliYWNrc3BhY2VEZWxldGUgOiBmdW5jdGlvbihlLCBicykgewoJCQl2YXIgdCA9IHRoaXMsIGVkID0gdC5lZGl0b3IsIGIgPSBlZC5nZXRCb2R5KCksIG4sIHNlID0gZWQuc2VsZWN0aW9uLCByID0gc2UuZ2V0Um5nKCksIHNjID0gci5zdGFydENvbnRhaW5lciwgbiwgdywgdG47CgoJCQkvLyBUaGUgY2FyZXQgc29tZXRpbWVzIGdldHMgc3R1Y2sgaW4gR2Vja28gaWYgeW91IGRlbGV0ZSBlbXB0eSBwYXJhZ3JhcGhzCgkJCS8vIFRoaXMgd29ya2Fyb3VuZCByZW1vdmVzIHRoZSBlbGVtZW50IGJ5IGhhbmQgYW5kIG1vdmVzIHRoZSBjYXJldCB0byB0aGUgcHJldmlvdXMgZWxlbWVudAoJCQlpZiAoc2MgJiYgZWQuZG9tLmlzQmxvY2soc2MpICYmICEvXihURHxUSCkkLy50ZXN0KHNjLm5vZGVOYW1lKSAmJiBicykgewoJCQkJaWYgKHNjLmNoaWxkTm9kZXMubGVuZ3RoID09IDAgfHwgKHNjLmNoaWxkTm9kZXMubGVuZ3RoID09IDEgJiYgc2MuZmlyc3RDaGlsZC5ub2RlTmFtZSA9PSAnQlInKSkgewoJCQkJCS8vIEZpbmQgcHJldmlvdXMgYmxvY2sgZWxlbWVudAoJCQkJCW4gPSBzYzsKCQkJCQl3aGlsZSAoKG4gPSBuLnByZXZpb3VzU2libGluZykgJiYgIWVkLmRvbS5pc0Jsb2NrKG4pKSA7CgoJCQkJCWlmIChuKSB7CgkJCQkJCWlmIChzYyAhPSBiLmZpcnN0Q2hpbGQpIHsKCQkJCQkJCS8vIEZpbmQgbGFzdCB0ZXh0IG5vZGUKCQkJCQkJCXcgPSBlZC5kb20uZG9jLmNyZWF0ZVRyZWVXYWxrZXIobiwgTm9kZUZpbHRlci5TSE9XX1RFWFQsIG51bGwsIGZhbHNlKTsKCQkJCQkJCXdoaWxlICh0biA9IHcubmV4dE5vZGUoKSkKCQkJCQkJCQluID0gdG47CgoJCQkJCQkJLy8gUGxhY2UgY2FyZXQgYXQgdGhlIGVuZCBvZiBsYXN0IHRleHQgbm9kZQoJCQkJCQkJciA9IGVkLmdldERvYygpLmNyZWF0ZVJhbmdlKCk7CgkJCQkJCQlyLnNldFN0YXJ0KG4sIG4ubm9kZVZhbHVlID8gbi5ub2RlVmFsdWUubGVuZ3RoIDogMCk7CgkJCQkJCQlyLnNldEVuZChuLCBuLm5vZGVWYWx1ZSA/IG4ubm9kZVZhbHVlLmxlbmd0aCA6IDApOwoJCQkJCQkJc2Uuc2V0Um5nKHIpOwoKCQkJCQkJCS8vIFJlbW92ZSB0aGUgdGFyZ2V0IGNvbnRhaW5lcgoJCQkJCQkJZWQuZG9tLnJlbW92ZShzYyk7CgkJCQkJCX0KCgkJCQkJCXJldHVybiBFdmVudC5jYW5jZWwoZSk7CgkJCQkJfQoJCQkJfQoJCQl9CgoJCQkvLyBHZWNrbyBnZW5lcmF0ZXMgQlIgZWxlbWVudHMgaGVyZSBhbmQgdGhlcmUsIHdlIGRvbid0IGxpa2UgdGhvc2Ugc28gbGV0cyByZW1vdmUgdGhlbQoJCQlmdW5jdGlvbiBoYW5kbGVyKGUpIHsKCQkJCXZhciBwcjsKCgkJCQllID0gZS50YXJnZXQ7CgoJCQkJLy8gQSBuZXcgQlIgd2FzIGNyZWF0ZWQgaW4gYSBibG9jayBlbGVtZW50LCByZW1vdmUgaXQKCQkJCWlmIChlICYmIGUucGFyZW50Tm9kZSAmJiBlLm5vZGVOYW1lID09ICdCUicgJiYgKG4gPSB0LmdldFBhcmVudEJsb2NrKGUpKSkgewoJCQkJCXByID0gZS5wcmV2aW91c1NpYmxpbmc7CgoJCQkJCUV2ZW50LnJlbW92ZShiLCAnRE9NTm9kZUluc2VydGVkJywgaGFuZGxlcik7CgoJCQkJCS8vIElzIHRoZXJlIHdoaXRlc3BhY2UgYXQgdGhlIGVuZCBvZiB0aGUgbm9kZSBiZWZvcmUgdGhlbiB3ZSBtaWdodCBuZWVkIHRoZSBwZXNreSBCUgoJCQkJCS8vIHRvIHBsYWNlIHRoZSBjYXJldCBhdCBhIGNvcnJlY3QgbG9jYXRpb24gc2VlIGJ1ZzogIzIwMTM5NDMKCQkJCQlpZiAocHIgJiYgcHIubm9kZVR5cGUgPT0gMyAmJiAvXHMrJC8udGVzdChwci5ub2RlVmFsdWUpKQoJCQkJCQlyZXR1cm47CgoJCQkJCS8vIE9ubHkgcmVtb3ZlIEJSIGVsZW1lbnRzIHRoYXQgZ290IGluc2VydGVkIGluIHRoZSBtaWRkbGUgb2YgdGhlIHRleHQKCQkJCQlpZiAoZS5wcmV2aW91c1NpYmxpbmcgfHwgZS5uZXh0U2libGluZykKCQkJCQkJZWQuZG9tLnJlbW92ZShlKTsKCQkJCX0KCQkJfTsKCgkJCS8vIExpc3RlbiBmb3IgbmV3IG5vZGVzCgkJCUV2ZW50Ll9hZGQoYiwgJ0RPTU5vZGVJbnNlcnRlZCcsIGhhbmRsZXIpOwoKCQkJLy8gUmVtb3ZlIGxpc3RlbmVyCgkJCXdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewoJCQkJRXZlbnQuX3JlbW92ZShiLCAnRE9NTm9kZUluc2VydGVkJywgaGFuZGxlcik7CgkJCX0sIDEpOwoJCX0KCX0pOwp9KSh0aW55bWNlKTsKKGZ1bmN0aW9uKHRpbnltY2UpIHsKCS8vIFNob3J0ZW4gbmFtZXMKCXZhciBET00gPSB0aW55bWNlLkRPTSwgRXZlbnQgPSB0aW55bWNlLmRvbS5FdmVudCwgZWFjaCA9IHRpbnltY2UuZWFjaCwgZXh0ZW5kID0gdGlueW1jZS5leHRlbmQ7CgoJdGlueW1jZS5jcmVhdGUoJ3RpbnltY2UuQ29udHJvbE1hbmFnZXInLCB7CgkJQ29udHJvbE1hbmFnZXIgOiBmdW5jdGlvbihlZCwgcykgewoJCQl2YXIgdCA9IHRoaXMsIGk7CgoJCQlzID0gcyB8fCB7fTsKCQkJdC5lZGl0b3IgPSBlZDsKCQkJdC5jb250cm9scyA9IHt9OwoJCQl0Lm9uQWRkID0gbmV3IHRpbnltY2UudXRpbC5EaXNwYXRjaGVyKHQpOwoJCQl0Lm9uUG9zdFJlbmRlciA9IG5ldyB0aW55bWNlLnV0aWwuRGlzcGF0Y2hlcih0KTsKCQkJdC5wcmVmaXggPSBzLnByZWZpeCB8fCBlZC5pZCArICdfJzsKCQkJdC5fY2xzID0ge307CgoJCQl0Lm9uUG9zdFJlbmRlci5hZGQoZnVuY3Rpb24oKSB7CgkJCQllYWNoKHQuY29udHJvbHMsIGZ1bmN0aW9uKGMpIHsKCQkJCQljLnBvc3RSZW5kZXIoKTsKCQkJCX0pOwoJCQl9KTsKCQl9LAoKCQlnZXQgOiBmdW5jdGlvbihpZCkgewoJCQlyZXR1cm4gdGhpcy5jb250cm9sc1t0aGlzLnByZWZpeCArIGlkXSB8fCB0aGlzLmNvbnRyb2xzW2lkXTsKCQl9LAoKCQlzZXRBY3RpdmUgOiBmdW5jdGlvbihpZCwgcykgewoJCQl2YXIgYyA9IG51bGw7CgoJCQlpZiAoYyA9IHRoaXMuZ2V0KGlkKSkKCQkJCWMuc2V0QWN0aXZlKHMpOwoKCQkJcmV0dXJuIGM7CgkJfSwKCgkJc2V0RGlzYWJsZWQgOiBmdW5jdGlvbihpZCwgcykgewoJCQl2YXIgYyA9IG51bGw7CgoJCQlpZiAoYyA9IHRoaXMuZ2V0KGlkKSkKCQkJCWMuc2V0RGlzYWJsZWQocyk7CgoJCQlyZXR1cm4gYzsKCQl9LAoKCQlhZGQgOiBmdW5jdGlvbihjKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCWlmIChjKSB7CgkJCQl0LmNvbnRyb2xzW2MuaWRdID0gYzsKCQkJCXQub25BZGQuZGlzcGF0Y2goYywgdCk7CgkJCX0KCgkJCXJldHVybiBjOwoJCX0sCgoJCWNyZWF0ZUNvbnRyb2wgOiBmdW5jdGlvbihuKSB7CgkJCXZhciBjLCB0ID0gdGhpcywgZWQgPSB0LmVkaXRvcjsKCgkJCWVhY2goZWQucGx1Z2lucywgZnVuY3Rpb24ocCkgewoJCQkJaWYgKHAuY3JlYXRlQ29udHJvbCkgewoJCQkJCWMgPSBwLmNyZWF0ZUNvbnRyb2wobiwgdCk7CgoJCQkJCWlmIChjKQoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgkJCX0pOwoKCQkJc3dpdGNoIChuKSB7CgkJCQljYXNlICJ8IjoKCQkJCWNhc2UgInNlcGFyYXRvciI6CgkJCQkJcmV0dXJuIHQuY3JlYXRlU2VwYXJhdG9yKCk7CgkJCX0KCgkJCWlmICghYyAmJiBlZC5idXR0b25zICYmIChjID0gZWQuYnV0dG9uc1tuXSkpCgkJCQlyZXR1cm4gdC5jcmVhdGVCdXR0b24obiwgYyk7CgoJCQlyZXR1cm4gdC5hZGQoYyk7CgkJfSwKCgkJY3JlYXRlRHJvcE1lbnUgOiBmdW5jdGlvbihpZCwgcywgY2MpIHsKCQkJdmFyIHQgPSB0aGlzLCBlZCA9IHQuZWRpdG9yLCBjLCBibSwgdiwgY2xzOwoKCQkJcyA9IGV4dGVuZCh7CgkJCQknY2xhc3MnIDogJ21jZURyb3BEb3duJywKCQkJCWNvbnN0cmFpbiA6IGVkLnNldHRpbmdzLmNvbnN0cmFpbl9tZW51cwoJCQl9LCBzKTsKCgkJCXNbJ2NsYXNzJ10gPSBzWydjbGFzcyddICsgJyAnICsgZWQuZ2V0UGFyYW0oJ3NraW4nKSArICdTa2luJzsKCQkJaWYgKHYgPSBlZC5nZXRQYXJhbSgnc2tpbl92YXJpYW50JykpCgkJCQlzWydjbGFzcyddICs9ICcgJyArIGVkLmdldFBhcmFtKCdza2luJykgKyAnU2tpbicgKyB2LnN1YnN0cmluZygwLCAxKS50b1VwcGVyQ2FzZSgpICsgdi5zdWJzdHJpbmcoMSk7CgoJCQlpZCA9IHQucHJlZml4ICsgaWQ7CgkJCWNscyA9IGNjIHx8IHQuX2Nscy5kcm9wbWVudSB8fCB0aW55bWNlLnVpLkRyb3BNZW51OwoJCQljID0gdC5jb250cm9sc1tpZF0gPSBuZXcgY2xzKGlkLCBzKTsKCQkJYy5vbkFkZEl0ZW0uYWRkKGZ1bmN0aW9uKGMsIG8pIHsKCQkJCXZhciBzID0gby5zZXR0aW5nczsKCgkJCQlzLnRpdGxlID0gZWQuZ2V0TGFuZyhzLnRpdGxlLCBzLnRpdGxlKTsKCgkJCQlpZiAoIXMub25jbGljaykgewoJCQkJCXMub25jbGljayA9IGZ1bmN0aW9uKHYpIHsKCQkJCQkJZWQuZXhlY0NvbW1hbmQocy5jbWQsIHMudWkgfHwgZmFsc2UsIHMudmFsdWUpOwoJCQkJCX07CgkJCQl9CgkJCX0pOwoKCQkJZWQub25SZW1vdmUuYWRkKGZ1bmN0aW9uKCkgewoJCQkJYy5kZXN0cm95KCk7CgkJCX0pOwoKCQkJLy8gRml4IGZvciBidWcgIzE4OTc3ODUsICMxODk4MDA3CgkJCWlmICh0aW55bWNlLmlzSUUpIHsKCQkJCWMub25TaG93TWVudS5hZGQoZnVuY3Rpb24oKSB7CgkJCQkJLy8gSUUgOCBuZWVkcyBmb2N1cyBpbiBvcmRlciB0byBzdG9yZSBhd2F5IGEgcmFuZ2Ugd2l0aCB0aGUgY3VycmVudCBjb2xsYXBzZWQgY2FyZXQgbG9jYXRpb24KCQkJCQllZC5mb2N1cygpOwoKCQkJCQlibSA9IGVkLnNlbGVjdGlvbi5nZXRCb29rbWFyaygxKTsKCQkJCX0pOwoKCQkJCWMub25IaWRlTWVudS5hZGQoZnVuY3Rpb24oKSB7CgkJCQkJaWYgKGJtKSB7CgkJCQkJCWVkLnNlbGVjdGlvbi5tb3ZlVG9Cb29rbWFyayhibSk7CgkJCQkJCWJtID0gMDsKCQkJCQl9CgkJCQl9KTsKCQkJfQoKCQkJcmV0dXJuIHQuYWRkKGMpOwoJCX0sCgoJCWNyZWF0ZUxpc3RCb3ggOiBmdW5jdGlvbihpZCwgcywgY2MpIHsKCQkJdmFyIHQgPSB0aGlzLCBlZCA9IHQuZWRpdG9yLCBjbWQsIGMsIGNsczsKCgkJCWlmICh0LmdldChpZCkpCgkJCQlyZXR1cm4gbnVsbDsKCgkJCXMudGl0bGUgPSBlZC50cmFuc2xhdGUocy50aXRsZSk7CgkJCXMuc2NvcGUgPSBzLnNjb3BlIHx8IGVkOwoKCQkJaWYgKCFzLm9uc2VsZWN0KSB7CgkJCQlzLm9uc2VsZWN0ID0gZnVuY3Rpb24odikgewoJCQkJCWVkLmV4ZWNDb21tYW5kKHMuY21kLCBzLnVpIHx8IGZhbHNlLCB2IHx8IHMudmFsdWUpOwoJCQkJfTsKCQkJfQoKCQkJcyA9IGV4dGVuZCh7CgkJCQl0aXRsZSA6IHMudGl0bGUsCgkJCQknY2xhc3MnIDogJ21jZV8nICsgaWQsCgkJCQlzY29wZSA6IHMuc2NvcGUsCgkJCQljb250cm9sX21hbmFnZXIgOiB0CgkJCX0sIHMpOwoKCQkJaWQgPSB0LnByZWZpeCArIGlkOwoKCQkJaWYgKGVkLnNldHRpbmdzLnVzZV9uYXRpdmVfc2VsZWN0cykKCQkJCWMgPSBuZXcgdGlueW1jZS51aS5OYXRpdmVMaXN0Qm94KGlkLCBzKTsKCQkJZWxzZSB7CgkJCQljbHMgPSBjYyB8fCB0Ll9jbHMubGlzdGJveCB8fCB0aW55bWNlLnVpLkxpc3RCb3g7CgkJCQljID0gbmV3IGNscyhpZCwgcyk7CgkJCX0KCgkJCXQuY29udHJvbHNbaWRdID0gYzsKCgkJCS8vIEZpeCBmb2N1cyBwcm9ibGVtIGluIFNhZmFyaQoJCQlpZiAodGlueW1jZS5pc1dlYktpdCkgewoJCQkJYy5vblBvc3RSZW5kZXIuYWRkKGZ1bmN0aW9uKGMsIG4pIHsKCQkJCQkvLyBTdG9yZSBib29rbWFyayBvbiBtb3VzZWRvd24KCQkJCQlFdmVudC5hZGQobiwgJ21vdXNlZG93bicsIGZ1bmN0aW9uKCkgewoJCQkJCQllZC5ib29rbWFyayA9IGVkLnNlbGVjdGlvbi5nZXRCb29rbWFyaygxKTsKCQkJCQl9KTsKCgkJCQkJLy8gUmVzdG9yZSBvbiBmb2N1cywgc2luY2UgaXQgbWlnaHQgYmUgbG9zdAoJCQkJCUV2ZW50LmFkZChuLCAnZm9jdXMnLCBmdW5jdGlvbigpIHsKCQkJCQkJZWQuc2VsZWN0aW9uLm1vdmVUb0Jvb2ttYXJrKGVkLmJvb2ttYXJrKTsKCQkJCQkJZWQuYm9va21hcmsgPSBudWxsOwoJCQkJCX0pOwoJCQkJfSk7CgkJCX0KCgkJCWlmIChjLmhpZGVNZW51KQoJCQkJZWQub25Nb3VzZURvd24uYWRkKGMuaGlkZU1lbnUsIGMpOwoKCQkJcmV0dXJuIHQuYWRkKGMpOwoJCX0sCgoJCWNyZWF0ZUJ1dHRvbiA6IGZ1bmN0aW9uKGlkLCBzLCBjYykgewoJCQl2YXIgdCA9IHRoaXMsIGVkID0gdC5lZGl0b3IsIG8sIGMsIGNsczsKCgkJCWlmICh0LmdldChpZCkpCgkJCQlyZXR1cm4gbnVsbDsKCgkJCXMudGl0bGUgPSBlZC50cmFuc2xhdGUocy50aXRsZSk7CgkJCXMubGFiZWwgPSBlZC50cmFuc2xhdGUocy5sYWJlbCk7CgkJCXMuc2NvcGUgPSBzLnNjb3BlIHx8IGVkOwoKCQkJaWYgKCFzLm9uY2xpY2sgJiYgIXMubWVudV9idXR0b24pIHsKCQkJCXMub25jbGljayA9IGZ1bmN0aW9uKCkgewoJCQkJCWVkLmV4ZWNDb21tYW5kKHMuY21kLCBzLnVpIHx8IGZhbHNlLCBzLnZhbHVlKTsKCQkJCX07CgkJCX0KCgkJCXMgPSBleHRlbmQoewoJCQkJdGl0bGUgOiBzLnRpdGxlLAoJCQkJJ2NsYXNzJyA6ICdtY2VfJyArIGlkLAoJCQkJdW5hdmFpbGFibGVfcHJlZml4IDogZWQuZ2V0TGFuZygndW5hdmFpbGFibGUnLCAnJyksCgkJCQlzY29wZSA6IHMuc2NvcGUsCgkJCQljb250cm9sX21hbmFnZXIgOiB0CgkJCX0sIHMpOwoKCQkJaWQgPSB0LnByZWZpeCArIGlkOwoKCQkJaWYgKHMubWVudV9idXR0b24pIHsKCQkJCWNscyA9IGNjIHx8IHQuX2Nscy5tZW51YnV0dG9uIHx8IHRpbnltY2UudWkuTWVudUJ1dHRvbjsKCQkJCWMgPSBuZXcgY2xzKGlkLCBzKTsKCQkJCWVkLm9uTW91c2VEb3duLmFkZChjLmhpZGVNZW51LCBjKTsKCQkJfSBlbHNlIHsKCQkJCWNscyA9IHQuX2Nscy5idXR0b24gfHwgdGlueW1jZS51aS5CdXR0b247CgkJCQljID0gbmV3IGNscyhpZCwgcyk7CgkJCX0KCgkJCXJldHVybiB0LmFkZChjKTsKCQl9LAoKCQljcmVhdGVNZW51QnV0dG9uIDogZnVuY3Rpb24oaWQsIHMsIGNjKSB7CgkJCXMgPSBzIHx8IHt9OwoJCQlzLm1lbnVfYnV0dG9uID0gMTsKCgkJCXJldHVybiB0aGlzLmNyZWF0ZUJ1dHRvbihpZCwgcywgY2MpOwoJCX0sCgoJCWNyZWF0ZVNwbGl0QnV0dG9uIDogZnVuY3Rpb24oaWQsIHMsIGNjKSB7CgkJCXZhciB0ID0gdGhpcywgZWQgPSB0LmVkaXRvciwgY21kLCBjLCBjbHM7CgoJCQlpZiAodC5nZXQoaWQpKQoJCQkJcmV0dXJuIG51bGw7CgoJCQlzLnRpdGxlID0gZWQudHJhbnNsYXRlKHMudGl0bGUpOwoJCQlzLnNjb3BlID0gcy5zY29wZSB8fCBlZDsKCgkJCWlmICghcy5vbmNsaWNrKSB7CgkJCQlzLm9uY2xpY2sgPSBmdW5jdGlvbih2KSB7CgkJCQkJaWYgKHRpbnltY2UuaXNJRSkKCQkJCQkJYm0gPSBlZC5zZWxlY3Rpb24uZ2V0Qm9va21hcmsoMSk7CgoJCQkJCWVkLmV4ZWNDb21tYW5kKHMuY21kLCBzLnVpIHx8IGZhbHNlLCB2IHx8IHMudmFsdWUpOwoJCQkJfTsKCQkJfQoKCQkJaWYgKCFzLm9uc2VsZWN0KSB7CgkJCQlzLm9uc2VsZWN0ID0gZnVuY3Rpb24odikgewoJCQkJCWVkLmV4ZWNDb21tYW5kKHMuY21kLCBzLnVpIHx8IGZhbHNlLCB2IHx8IHMudmFsdWUpOwoJCQkJfTsKCQkJfQoKCQkJcyA9IGV4dGVuZCh7CgkJCQl0aXRsZSA6IHMudGl0bGUsCgkJCQknY2xhc3MnIDogJ21jZV8nICsgaWQsCgkJCQlzY29wZSA6IHMuc2NvcGUsCgkJCQljb250cm9sX21hbmFnZXIgOiB0CgkJCX0sIHMpOwoKCQkJaWQgPSB0LnByZWZpeCArIGlkOwoJCQljbHMgPSBjYyB8fCB0Ll9jbHMuc3BsaXRidXR0b24gfHwgdGlueW1jZS51aS5TcGxpdEJ1dHRvbjsKCQkJYyA9IHQuYWRkKG5ldyBjbHMoaWQsIHMpKTsKCQkJZWQub25Nb3VzZURvd24uYWRkKGMuaGlkZU1lbnUsIGMpOwoKCQkJcmV0dXJuIGM7CgkJfSwKCgkJY3JlYXRlQ29sb3JTcGxpdEJ1dHRvbiA6IGZ1bmN0aW9uKGlkLCBzLCBjYykgewoJCQl2YXIgdCA9IHRoaXMsIGVkID0gdC5lZGl0b3IsIGNtZCwgYywgY2xzLCBibTsKCgkJCWlmICh0LmdldChpZCkpCgkJCQlyZXR1cm4gbnVsbDsKCgkJCXMudGl0bGUgPSBlZC50cmFuc2xhdGUocy50aXRsZSk7CgkJCXMuc2NvcGUgPSBzLnNjb3BlIHx8IGVkOwoKCQkJaWYgKCFzLm9uY2xpY2spIHsKCQkJCXMub25jbGljayA9IGZ1bmN0aW9uKHYpIHsKCQkJCQllZC5leGVjQ29tbWFuZChzLmNtZCwgcy51aSB8fCBmYWxzZSwgdiB8fCBzLnZhbHVlKTsKCQkJCX07CgkJCX0KCgkJCWlmICghcy5vbnNlbGVjdCkgewoJCQkJcy5vbnNlbGVjdCA9IGZ1bmN0aW9uKHYpIHsKCQkJCQllZC5leGVjQ29tbWFuZChzLmNtZCwgcy51aSB8fCBmYWxzZSwgdiB8fCBzLnZhbHVlKTsKCQkJCX07CgkJCX0KCgkJCXMgPSBleHRlbmQoewoJCQkJdGl0bGUgOiBzLnRpdGxlLAoJCQkJJ2NsYXNzJyA6ICdtY2VfJyArIGlkLAoJCQkJJ21lbnVfY2xhc3MnIDogZWQuZ2V0UGFyYW0oJ3NraW4nKSArICdTa2luJywKCQkJCXNjb3BlIDogcy5zY29wZSwKCQkJCW1vcmVfY29sb3JzX3RpdGxlIDogZWQuZ2V0TGFuZygnY29sb3JwaWNrZXIubW9yZV9jb2xvcnMnKQoJCQl9LCBzKTsKCgkJCWlkID0gdC5wcmVmaXggKyBpZDsKCQkJY2xzID0gY2MgfHwgdC5fY2xzLmNvbG9yc3BsaXRidXR0b24gfHwgdGlueW1jZS51aS5Db2xvclNwbGl0QnV0dG9uOwoJCQljID0gbmV3IGNscyhpZCwgcyk7CgkJCWVkLm9uTW91c2VEb3duLmFkZChjLmhpZGVNZW51LCBjKTsKCgkJCS8vIFJlbW92ZSB0aGUgbWVudSBlbGVtZW50IHdoZW4gdGhlIGVkaXRvciBpcyByZW1vdmVkCgkJCWVkLm9uUmVtb3ZlLmFkZChmdW5jdGlvbigpIHsKCQkJCWMuZGVzdHJveSgpOwoJCQl9KTsKCgkJCS8vIEZpeCBmb3IgYnVnICMxODk3Nzg1LCAjMTg5ODAwNwoJCQlpZiAodGlueW1jZS5pc0lFKSB7CgkJCQljLm9uU2hvd01lbnUuYWRkKGZ1bmN0aW9uKCkgewoJCQkJCS8vIElFIDggbmVlZHMgZm9jdXMgaW4gb3JkZXIgdG8gc3RvcmUgYXdheSBhIHJhbmdlIHdpdGggdGhlIGN1cnJlbnQgY29sbGFwc2VkIGNhcmV0IGxvY2F0aW9uCgkJCQkJZWQuZm9jdXMoKTsKCQkJCQlibSA9IGVkLnNlbGVjdGlvbi5nZXRCb29rbWFyaygxKTsKCQkJCX0pOwoKCQkJCWMub25IaWRlTWVudS5hZGQoZnVuY3Rpb24oKSB7CgkJCQkJaWYgKGJtKSB7CgkJCQkJCWVkLnNlbGVjdGlvbi5tb3ZlVG9Cb29rbWFyayhibSk7CgkJCQkJCWJtID0gMDsKCQkJCQl9CgkJCQl9KTsKCQkJfQoKCQkJcmV0dXJuIHQuYWRkKGMpOwoJCX0sCgoJCWNyZWF0ZVRvb2xiYXIgOiBmdW5jdGlvbihpZCwgcywgY2MpIHsKCQkJdmFyIGMsIHQgPSB0aGlzLCBjbHM7CgoJCQlpZCA9IHQucHJlZml4ICsgaWQ7CgkJCWNscyA9IGNjIHx8IHQuX2Nscy50b29sYmFyIHx8IHRpbnltY2UudWkuVG9vbGJhcjsKCQkJYyA9IG5ldyBjbHMoaWQsIHMpOwoKCQkJaWYgKHQuZ2V0KGlkKSkKCQkJCXJldHVybiBudWxsOwoKCQkJcmV0dXJuIHQuYWRkKGMpOwoJCX0sCgoJCWNyZWF0ZVNlcGFyYXRvciA6IGZ1bmN0aW9uKGNjKSB7CgkJCXZhciBjbHMgPSBjYyB8fCB0aGlzLl9jbHMuc2VwYXJhdG9yIHx8IHRpbnltY2UudWkuU2VwYXJhdG9yOwoKCQkJcmV0dXJuIG5ldyBjbHMoKTsKCQl9LAoKCQlzZXRDb250cm9sVHlwZSA6IGZ1bmN0aW9uKG4sIGMpIHsKCQkJcmV0dXJuIHRoaXMuX2Nsc1tuLnRvTG93ZXJDYXNlKCldID0gYzsKCQl9LAoKCQlkZXN0cm95IDogZnVuY3Rpb24oKSB7CgkJCWVhY2godGhpcy5jb250cm9scywgZnVuY3Rpb24oYykgewoJCQkJYy5kZXN0cm95KCk7CgkJCX0pOwoKCQkJdGhpcy5jb250cm9scyA9IG51bGw7CgkJfQoKCQl9KTsKfSkodGlueW1jZSk7CihmdW5jdGlvbih0aW55bWNlKSB7Cgl2YXIgRGlzcGF0Y2hlciA9IHRpbnltY2UudXRpbC5EaXNwYXRjaGVyLCBlYWNoID0gdGlueW1jZS5lYWNoLCBpc0lFID0gdGlueW1jZS5pc0lFLCBpc09wZXJhID0gdGlueW1jZS5pc09wZXJhOwoKCXRpbnltY2UuY3JlYXRlKCd0aW55bWNlLldpbmRvd01hbmFnZXInLCB7CgkJV2luZG93TWFuYWdlciA6IGZ1bmN0aW9uKGVkKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXQuZWRpdG9yID0gZWQ7CgkJCXQub25PcGVuID0gbmV3IERpc3BhdGNoZXIodCk7CgkJCXQub25DbG9zZSA9IG5ldyBEaXNwYXRjaGVyKHQpOwoJCQl0LnBhcmFtcyA9IHt9OwoJCQl0LmZlYXR1cmVzID0ge307CgkJfSwKCgkJb3BlbiA6IGZ1bmN0aW9uKHMsIHApIHsKCQkJdmFyIHQgPSB0aGlzLCBmID0gJycsIHgsIHksIG1vID0gdC5lZGl0b3Iuc2V0dGluZ3MuZGlhbG9nX3R5cGUgPT0gJ21vZGFsJywgdywgc3csIHNoLCB2cCA9IHRpbnltY2UuRE9NLmdldFZpZXdQb3J0KCksIHU7CgoJCQkvLyBEZWZhdWx0IHNvbWUgb3B0aW9ucwoJCQlzID0gcyB8fCB7fTsKCQkJcCA9IHAgfHwge307CgkJCXN3ID0gaXNPcGVyYSA/IHZwLncgOiBzY3JlZW4ud2lkdGg7IC8vIE9wZXJhIHVzZXMgd2luZG93cyBpbnNpZGUgdGhlIE9wZXJhIHdpbmRvdwoJCQlzaCA9IGlzT3BlcmEgPyB2cC5oIDogc2NyZWVuLmhlaWdodDsKCQkJcy5uYW1lID0gcy5uYW1lIHx8ICdtY18nICsgbmV3IERhdGUoKS5nZXRUaW1lKCk7CgkJCXMud2lkdGggPSBwYXJzZUludChzLndpZHRoIHx8IDMyMCk7CgkJCXMuaGVpZ2h0ID0gcGFyc2VJbnQocy5oZWlnaHQgfHwgMjQwKTsKCQkJcy5yZXNpemFibGUgPSB0cnVlOwoJCQlzLmxlZnQgPSBzLmxlZnQgfHwgcGFyc2VJbnQoc3cgLyAyLjApIC0gKHMud2lkdGggLyAyLjApOwoJCQlzLnRvcCA9IHMudG9wIHx8IHBhcnNlSW50KHNoIC8gMi4wKSAtIChzLmhlaWdodCAvIDIuMCk7CgkJCXAuaW5saW5lID0gZmFsc2U7CgkJCXAubWNlX3dpZHRoID0gcy53aWR0aDsKCQkJcC5tY2VfaGVpZ2h0ID0gcy5oZWlnaHQ7CgkJCXAubWNlX2F1dG9fZm9jdXMgPSBzLmF1dG9fZm9jdXM7CgogICAgICAgICAgICBBSlMubG9nKCJXaW5kb3dNYW5hZ2VyOm9wZW4gcG9wdXAgbmFtZT0iICsgcy5uYW1lKTsKCgkJCWlmIChtbykgewoJCQkJaWYgKGlzSUUpIHsKCQkJCQlzLmNlbnRlciA9IHRydWU7CgkJCQkJcy5oZWxwID0gZmFsc2U7CgkJCQkJcy5kaWFsb2dXaWR0aCA9IHMud2lkdGggKyAncHgnOwoJCQkJCXMuZGlhbG9nSGVpZ2h0ID0gcy5oZWlnaHQgKyAncHgnOwoJCQkJCXMuc2Nyb2xsID0gcy5zY3JvbGxiYXJzIHx8IGZhbHNlOwoJCQkJfQoJCQl9CgoJCQkvLyBCdWlsZCBmZWF0dXJlcyBzdHJpbmcKCQkJZWFjaChzLCBmdW5jdGlvbih2LCBrKSB7CgkJCQlpZiAodGlueW1jZS5pcyh2LCAnYm9vbGVhbicpKQoJCQkJCXYgPSB2ID8gJ3llcycgOiAnbm8nOwoKCQkJCWlmICghL14obmFtZXx1cmwpJC8udGVzdChrKSkgewoJCQkJCWlmIChpc0lFICYmIG1vKQoJCQkJCQlmICs9IChmID8gJzsnIDogJycpICsgayArICc6JyArIHY7CgkJCQkJZWxzZQoJCQkJCQlmICs9IChmID8gJywnIDogJycpICsgayArICc9JyArIHY7CgkJCQl9CgkJCX0pOwoKCQkJdC5mZWF0dXJlcyA9IHM7CgkJCXQucGFyYW1zID0gcDsKCQkJdC5vbk9wZW4uZGlzcGF0Y2godCwgcywgcCk7CgoJCQl1ID0gcy51cmwgfHwgcy5maWxlOwoJCQl1ID0gdGlueW1jZS5fYWRkVmVyKHUpOwoKCQkJdHJ5IHsKCQkJCWlmIChpc0lFICYmIG1vKSB7CgkJCQkJdyA9IDE7CgkJCQkJd2luZG93LnNob3dNb2RhbERpYWxvZyh1LCB3aW5kb3csIGYpOwoJCQkJfSBlbHNlCgkJCQkJdyA9IHdpbmRvdy5vcGVuKHUsIHMubmFtZSwgZik7CgkJCX0gY2F0Y2ggKGV4KSB7CgkJCQkvLyBJZ25vcmUKCQkJfQoKCQkJaWYgKCF3KQoJCQkJYWxlcnQodC5lZGl0b3IuZ2V0TGFuZygncG9wdXBfYmxvY2tlZCcpKTsKCQl9LAoKCQljbG9zZSA6IGZ1bmN0aW9uKHcpIHsKCQkJdy5jbG9zZSgpOwoJCQl0aGlzLm9uQ2xvc2UuZGlzcGF0Y2godGhpcyk7CgkJfSwKCgkJY3JlYXRlSW5zdGFuY2UgOiBmdW5jdGlvbihjbCwgYSwgYiwgYywgZCwgZSkgewoJCQl2YXIgZiA9IHRpbnltY2UucmVzb2x2ZShjbCk7CgoJCQlyZXR1cm4gbmV3IGYoYSwgYiwgYywgZCwgZSk7CgkJfSwKCgkJY29uZmlybSA6IGZ1bmN0aW9uKHQsIGNiLCBzLCB3KSB7CgkJCXcgPSB3IHx8IHdpbmRvdzsKCgkJCWNiLmNhbGwocyB8fCB0aGlzLCB3LmNvbmZpcm0odGhpcy5fZGVjb2RlKHRoaXMuZWRpdG9yLmdldExhbmcodCwgdCkpKSk7CgkJfSwKCgkJYWxlcnQgOiBmdW5jdGlvbih0eCwgY2IsIHMsIHcpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJdyA9IHcgfHwgd2luZG93OwoJCQl3LmFsZXJ0KHQuX2RlY29kZSh0LmVkaXRvci5nZXRMYW5nKHR4LCB0eCkpKTsKCgkJCWlmIChjYikKCQkJCWNiLmNhbGwocyB8fCB0KTsKCQl9LAoKCQkvLyBJbnRlcm5hbCBmdW5jdGlvbnMKCgkJX2RlY29kZSA6IGZ1bmN0aW9uKHMpIHsKCQkJcmV0dXJuIHRpbnltY2UuRE9NLmRlY29kZShzKS5yZXBsYWNlKC9cXG4vZywgJ1xuJyk7CgkJfQoKCQl9KTsKfSh0aW55bWNlKSk7KGZ1bmN0aW9uKHRpbnltY2UpIHsKCXRpbnltY2UuQ29tbWFuZE1hbmFnZXIgPSBmdW5jdGlvbigpIHsKCQl2YXIgZXhlY0NvbW1hbmRzID0ge30sIHF1ZXJ5U3RhdGVDb21tYW5kcyA9IHt9LCBxdWVyeVZhbHVlQ29tbWFuZHMgPSB7fTsKCgkJZnVuY3Rpb24gYWRkKGNvbGxlY3Rpb24sIGNtZCwgZnVuYywgc2NvcGUpIHsKCQkJaWYgKHR5cGVvZihjbWQpID09ICdzdHJpbmcnKQoJCQkJY21kID0gW2NtZF07CgoJCQl0aW55bWNlLmVhY2goY21kLCBmdW5jdGlvbihjbWQpIHsKCQkJCWNvbGxlY3Rpb25bY21kLnRvTG93ZXJDYXNlKCldID0ge2Z1bmMgOiBmdW5jLCBzY29wZSA6IHNjb3BlfTsKCQkJfSk7CgkJfTsKCgkJdGlueW1jZS5leHRlbmQodGhpcywgewoJCQlhZGQgOiBmdW5jdGlvbihjbWQsIGZ1bmMsIHNjb3BlKSB7CgkJCQlhZGQoZXhlY0NvbW1hbmRzLCBjbWQsIGZ1bmMsIHNjb3BlKTsKCQkJfSwKCgkJCWFkZFF1ZXJ5U3RhdGVIYW5kbGVyIDogZnVuY3Rpb24oY21kLCBmdW5jLCBzY29wZSkgewoJCQkJYWRkKHF1ZXJ5U3RhdGVDb21tYW5kcywgY21kLCBmdW5jLCBzY29wZSk7CgkJCX0sCgoJCQlhZGRRdWVyeVZhbHVlSGFuZGxlciA6IGZ1bmN0aW9uKGNtZCwgZnVuYywgc2NvcGUpIHsKCQkJCWFkZChxdWVyeVZhbHVlQ29tbWFuZHMsIGNtZCwgZnVuYywgc2NvcGUpOwoJCQl9LAoKCQkJZXhlY0NvbW1hbmQgOiBmdW5jdGlvbihzY29wZSwgY21kLCB1aSwgdmFsdWUsIGFyZ3MpIHsKCQkJCWlmIChjbWQgPSBleGVjQ29tbWFuZHNbY21kLnRvTG93ZXJDYXNlKCldKSB7CgkJCQkJaWYgKGNtZC5mdW5jLmNhbGwoc2NvcGUgfHwgY21kLnNjb3BlLCB1aSwgdmFsdWUsIGFyZ3MpICE9PSBmYWxzZSkKCQkJCQkJcmV0dXJuIHRydWU7CgkJCQl9CgkJCX0sCgoJCQlxdWVyeUNvbW1hbmRWYWx1ZSA6IGZ1bmN0aW9uKCkgewoJCQkJaWYgKGNtZCA9IHF1ZXJ5VmFsdWVDb21tYW5kc1tjbWQudG9Mb3dlckNhc2UoKV0pCgkJCQkJcmV0dXJuIGNtZC5mdW5jLmNhbGwoc2NvcGUgfHwgY21kLnNjb3BlLCB1aSwgdmFsdWUsIGFyZ3MpOwoJCQl9LAoKCQkJcXVlcnlDb21tYW5kU3RhdGUgOiBmdW5jdGlvbigpIHsKCQkJCWlmIChjbWQgPSBxdWVyeVN0YXRlQ29tbWFuZHNbY21kLnRvTG93ZXJDYXNlKCldKQoJCQkJCXJldHVybiBjbWQuZnVuYy5jYWxsKHNjb3BlIHx8IGNtZC5zY29wZSwgdWksIHZhbHVlLCBhcmdzKTsKCQkJfQoJCX0pOwoJfTsKCgl0aW55bWNlLkdsb2JhbENvbW1hbmRzID0gbmV3IHRpbnltY2UuQ29tbWFuZE1hbmFnZXIoKTsKfSkodGlueW1jZSk7KGZ1bmN0aW9uKHRpbnltY2UpIHsKCWZ1bmN0aW9uIHByb2Nlc3NSYW5nZShkb20sIHN0YXJ0LCBlbmQsIGNhbGxiYWNrKSB7CgkJdmFyIGFuY2VzdG9yLCBuLCBzdGFydFBvaW50LCBlbmRQb2ludCwgc2liOwoKCQlmdW5jdGlvbiBmaW5kRW5kUG9pbnQobiwgYykgewoJCQlkbyB7CgkJCQlpZiAobi5wYXJlbnROb2RlID09IGMpCgkJCQkJcmV0dXJuIG47CgoJCQkJbiA9IG4ucGFyZW50Tm9kZTsKCQkJfSB3aGlsZShuKTsKCQl9OwoKCQlmdW5jdGlvbiBwcm9jZXNzKG4pIHsKCQkJY2FsbGJhY2sobik7CgkJCXRpbnltY2Uud2FsayhuLCBjYWxsYmFjaywgJ2NoaWxkTm9kZXMnKTsKCQl9OwoKCQkvLyBGaW5kIGNvbW1vbiBhbmNlc3RvciBhbmQgZW5kIHBvaW50cwoJCWFuY2VzdG9yID0gZG9tLmZpbmRDb21tb25BbmNlc3RvcihzdGFydCwgZW5kKTsKCQlzdGFydFBvaW50ID0gZmluZEVuZFBvaW50KHN0YXJ0LCBhbmNlc3RvcikgfHwgc3RhcnQ7CgkJZW5kUG9pbnQgPSBmaW5kRW5kUG9pbnQoZW5kLCBhbmNlc3RvcikgfHwgZW5kOwoKCQkvLyBQcm9jZXNzIGxlZnQgbGVhZgoJCWZvciAobiA9IHN0YXJ0OyBuICYmIG4gIT0gc3RhcnRQb2ludDsgbiA9IG4ucGFyZW50Tm9kZSkgewoJCQlmb3IgKHNpYiA9IG4ubmV4dFNpYmxpbmc7IHNpYjsgc2liID0gc2liLm5leHRTaWJsaW5nKQoJCQkJcHJvY2VzcyhzaWIpOwoJCX0KCgkJLy8gUHJvY2VzcyBtaWRkbGUgZnJvbSBzdGFydCB0byBlbmQgcG9pbnQKCQlpZiAoc3RhcnRQb2ludCAhPSBlbmRQb2ludCkgewoJCQlmb3IgKG4gPSBzdGFydFBvaW50Lm5leHRTaWJsaW5nOyBuICYmIG4gIT0gZW5kUG9pbnQ7IG4gPSBuLm5leHRTaWJsaW5nKQoJCQkJcHJvY2VzcyhuKTsKCQl9IGVsc2UKCQkJcHJvY2VzcyhzdGFydFBvaW50KTsKCgkJLy8gUHJvY2VzcyByaWdodCBsZWFmCgkJZm9yIChuID0gZW5kOyBuICYmIG4gIT0gZW5kUG9pbnQ7IG4gPSBuLnBhcmVudE5vZGUpIHsKCQkJZm9yIChzaWIgPSBuLnByZXZpb3VzU2libGluZzsgc2liOyBzaWIgPSBzaWIucHJldmlvdXNTaWJsaW5nKQoJCQkJcHJvY2VzcyhzaWIpOwoJCX0KCX07CgoJdGlueW1jZS5HbG9iYWxDb21tYW5kcy5hZGQoJ1JlbW92ZUZvcm1hdCcsIGZ1bmN0aW9uKCkgewoJCXZhciBlZCA9IHRoaXMsIGRvbSA9IGVkLmRvbSwgcyA9IGVkLnNlbGVjdGlvbiwgciA9IHMuZ2V0Um5nKDEpLCBub2RlcyA9IFtdLCBibSwgc3RhcnQsIGVuZCwgc2MsIHNvLCBlYywgZW8sIG47CgoJCWZ1bmN0aW9uIGZpbmRGb3JtYXRSb290KG4pIHsKCQkJdmFyIHNwOwoKCQkJZG9tLmdldFBhcmVudChuLCBmdW5jdGlvbihuKSB7CgkJCQlpZiAoZG9tLmlzKG4sIGVkLmdldFBhcmFtKCdyZW1vdmVmb3JtYXRfc2VsZWN0b3InKSkpCgkJCQkJc3AgPSBuOwoKCQkJCXJldHVybiBkb20uaXNCbG9jayhuKTsKCQkJfSwgZWQuZ2V0Qm9keSgpKTsKCgkJCXJldHVybiBzcDsKCQl9OwoKCQlmdW5jdGlvbiBjb2xsZWN0KG4pIHsKCQkJaWYgKGRvbS5pcyhuLCBlZC5nZXRQYXJhbSgncmVtb3ZlZm9ybWF0X3NlbGVjdG9yJykpKQoJCQkJbm9kZXMucHVzaChuKTsKCQl9OwoKCQlmdW5jdGlvbiB3YWxrKG4pIHsKCQkJY29sbGVjdChuKTsKCQkJdGlueW1jZS53YWxrKG4sIGNvbGxlY3QsICdjaGlsZE5vZGVzJyk7CgkJfTsKCgkJYm0gPSBzLmdldEJvb2ttYXJrKCk7CgkJc2MgPSByLnN0YXJ0Q29udGFpbmVyOwoJCWVjID0gci5lbmRDb250YWluZXI7CgkJc28gPSByLnN0YXJ0T2Zmc2V0OwoJCWVvID0gci5lbmRPZmZzZXQ7CgkJc2MgPSBzYy5ub2RlVHlwZSA9PSAxID8gc2MuY2hpbGROb2Rlc1tNYXRoLm1pbihzbywgc2MuY2hpbGROb2Rlcy5sZW5ndGggLSAxKV0gOiBzYzsKCQllYyA9IGVjLm5vZGVUeXBlID09IDEgPyBlYy5jaGlsZE5vZGVzW01hdGgubWluKHNvID09IGVvID8gZW8gOiBlbyAtIDEsIGVjLmNoaWxkTm9kZXMubGVuZ3RoIC0gMSldIDogZWM7CgoJCS8vIFNhbWUgY29udGFpbmVyCgkJaWYgKHNjID09IGVjKSB7IC8vIFRFWFRfTk9ERQoJCQlzdGFydCA9IGZpbmRGb3JtYXRSb290KHNjKTsKCgkJCS8vIEhhbmRsZSBzaW5nbGUgdGV4dCBub2RlCgkJCWlmIChzYy5ub2RlVHlwZSA9PSAzKSB7CgkJCQlpZiAoc3RhcnQgJiYgc3RhcnQubm9kZVR5cGUgPT0gMSkgeyAvLyBFTEVNRU5UCgkJCQkJbiA9IHNjLnNwbGl0VGV4dChzbyk7CgkJCQkJbi5zcGxpdFRleHQoZW8gLSBzbyk7CgkJCQkJZG9tLnNwbGl0KHN0YXJ0LCBuKTsKCgkJCQkJcy5tb3ZlVG9Cb29rbWFyayhibSk7CgkJCQl9CgoJCQkJcmV0dXJuOwoJCQl9CgoJCQkvLyBIYW5kbGUgc2luZ2xlIGVsZW1lbnQKCQkJd2Fsayhkb20uc3BsaXQoc3RhcnQsIHNjKSB8fCBzYyk7CgkJfSBlbHNlIHsKCQkJLy8gRmluZCBzdGFydC9lbmQgZm9ybWF0IHJvb3QKCQkJc3RhcnQgPSBmaW5kRm9ybWF0Um9vdChzYyk7CgkJCWVuZCA9IGZpbmRGb3JtYXRSb290KGVjKTsKCgkJCS8vIFNwbGl0IHN0YXJ0IHRleHQgbm9kZQoJCQlpZiAoc3RhcnQpIHsKCQkJCWlmIChzYy5ub2RlVHlwZSA9PSAzKSB7IC8vIFRFWFQKCQkJCQkvLyBTaW5jZSBJRSBkb2Vzbid0IHN1cHBvcnQgd2hpdGUgc3BhY2Ugbm9kZXMgaW4gdGhlIERPTSB3ZSBuZWVkIHRvCgkJCQkJLy8gYWRkIHRoaXMgaW52aXNpYmxlIGNoYXJhY3RlciBzbyB0aGF0IHRoZSBzcGxpdFRleHQgZnVuY3Rpb24gY2FuIHNwbGl0IHRoZSBjb250ZW50cwoJCQkJCWlmIChzbyA9PSBzYy5ub2RlVmFsdWUubGVuZ3RoKQoJCQkJCQlzYy5ub2RlVmFsdWUgKz0gJ1x1RkVGRic7IC8vIFlldCBhbm90aGVyIHBlc2t5IElFIGZpeAoKCQkJCQlzYyA9IHNjLnNwbGl0VGV4dChzbyk7CgkJCQl9CgkJCX0KCgkJCS8vIFNwbGl0IGVuZCB0ZXh0IG5vZGUKCQkJaWYgKGVuZCkgewoJCQkJaWYgKGVjLm5vZGVUeXBlID09IDMpIC8vIFRFWFQKCQkJCQllYy5zcGxpdFRleHQoZW8pOwoJCQl9CgoJCQkvLyBJZiB0aGUgc3RhcnQgYW5kIGVuZCBmb3JtYXQgcm9vdCBpcyB0aGUgc2FtZSB0aGVuIHdlIG5lZWQgdG8gd3JhcAoJCQkvLyB0aGUgZW5kIG5vZGUgaW4gYSBzcGFuIHNpbmNlIHRoZSBzcGxpdCBjYWxscyBtaWdodCBjaGFuZ2UgdGhlIHJlZmVyZW5jZQoJCQkvLyBFeGFtcGxlOiA8cD48Yj48ZW0+eFt5ejxzcGFuPi0tLTwvc3Bhbj4xMl0zPC9lbT48L2I+PC9wPgoJCQlpZiAoc3RhcnQgJiYgc3RhcnQgPT0gZW5kKQoJCQkJZG9tLnJlcGxhY2UoZG9tLmNyZWF0ZSgnc3BhbicsIHtpZCA6ICdfX2VuZCd9LCBlYy5jbG9uZU5vZGUodHJ1ZSkpLCBlYyk7CgoJCQkvLyBTcGxpdCBhbGwgc3RhcnQgY29udGFpbmVycyBkb3duIHRvIHRoZSBmb3JtYXQgcm9vdAoJCQlpZiAoc3RhcnQpCgkJCQlzdGFydCA9IGRvbS5zcGxpdChzdGFydCwgc2MpOwoJCQllbHNlCgkJCQlzdGFydCA9IHNjOwoKCQkJLy8gSWYgdGhlcmUgaXMgYSBzcGFuIHdyYXBwZXIgdXNlIHRoYXQgb25lIGluc3RlYWQKCQkJaWYgKG4gPSBkb20uZ2V0KCdfX2VuZCcpKSB7CgkJCQllYyA9IG47CgkJCQllbmQgPSBmaW5kRm9ybWF0Um9vdChlYyk7CgkJCX0KCgkJCS8vIFNwbGl0IGFsbCBlbmQgY29udGFpbmVycyBkb3duIHRvIHRoZSBmb3JtYXQgcm9vdAoJCQlpZiAoZW5kKQoJCQkJZW5kID0gZG9tLnNwbGl0KGVuZCwgZWMpOwoJCQllbHNlCgkJCQllbmQgPSBlYzsKCgkJCS8vIENvbGxlY3Qgbm9kZXMgaW4gYmV0d2VlbgoJCQlwcm9jZXNzUmFuZ2UoZG9tLCBzdGFydCwgZW5kLCBjb2xsZWN0KTsKCgkJCS8vIFJlbW92ZSBpbnZpc2libGUgY2hhcmFjdGVyIGZvciBJRSB3b3JrYXJvdW5kIGlmIHdlIGZpbmQgaXQKCQkJaWYgKHNjLm5vZGVWYWx1ZSA9PSAnXHVGRUZGJykKCQkJCXNjLm5vZGVWYWx1ZSA9ICcnOwoKCQkJLy8gUHJvY2VzcyBzdGFydC9lbmQgY29udGFpbmVyIGVsZW1lbnRzCgkJCXdhbGsoZWMpOwoJCQl3YWxrKHNjKTsKCQl9CgoJCS8vIFJlbW92ZSBhbGwgY29sbGVjdGVkIG5vZGVzCgkJdGlueW1jZS5lYWNoKG5vZGVzLCBmdW5jdGlvbihuKSB7CgkJCWRvbS5yZW1vdmUobiwgMSk7CgkJfSk7CgoJCS8vIFJlbW92ZSBsZWZ0b3ZlciB3cmFwcGVyCgkJZG9tLnJlbW92ZSgnX19lbmQnLCAxKTsKCgkJcy5tb3ZlVG9Cb29rbWFyayhibSk7Cgl9KTsKfSkodGlueW1jZSk7CihmdW5jdGlvbih0aW55bWNlKSB7Cgl0aW55bWNlLkdsb2JhbENvbW1hbmRzLmFkZCgnbWNlQmxvY2tRdW90ZScsIGZ1bmN0aW9uKCkgewoJCXZhciBlZCA9IHRoaXMsIHMgPSBlZC5zZWxlY3Rpb24sIGRvbSA9IGVkLmRvbSwgc2IsIGViLCBuLCBibSwgYnEsIHIsIGJxMiwgaSwgbmw7CgoJCWZ1bmN0aW9uIGdldEJRKGUpIHsKCQkJcmV0dXJuIGRvbS5nZXRQYXJlbnQoZSwgZnVuY3Rpb24obikge3JldHVybiBuLm5vZGVOYW1lID09PSAnQkxPQ0tRVU9URSc7fSk7CgkJfTsKCgkJLy8gR2V0IHN0YXJ0L2VuZCBibG9jawoJCXNiID0gZG9tLmdldFBhcmVudChzLmdldFN0YXJ0KCksIGRvbS5pc0Jsb2NrKTsKCQllYiA9IGRvbS5nZXRQYXJlbnQocy5nZXRFbmQoKSwgZG9tLmlzQmxvY2spOwoKCQkvLyBSZW1vdmUgYmxvY2txdW90ZShzKQoJCWlmIChicSA9IGdldEJRKHNiKSkgewoJCQlpZiAoc2IgIT0gZWIgfHwgc2IuY2hpbGROb2Rlcy5sZW5ndGggPiAxIHx8IChzYi5jaGlsZE5vZGVzLmxlbmd0aCA9PSAxICYmIHNiLmZpcnN0Q2hpbGQubm9kZU5hbWUgIT0gJ0JSJykpCgkJCQlibSA9IHMuZ2V0Qm9va21hcmsoKTsKCgkJCS8vIE1vdmUgYWxsIGVsZW1lbnRzIGFmdGVyIHRoZSBlbmQgYmxvY2sgaW50byBuZXcgYnEKCQkJaWYgKGdldEJRKGViKSkgewoJCQkJYnEyID0gYnEuY2xvbmVOb2RlKGZhbHNlKTsKCgkJCQl3aGlsZSAobiA9IGViLm5leHRTaWJsaW5nKQoJCQkJCWJxMi5hcHBlbmRDaGlsZChuLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobikpOwoJCQl9CgoJCQkvLyBBZGQgbmV3IGJxIGFmdGVyCgkJCWlmIChicTIpCgkJCQlkb20uaW5zZXJ0QWZ0ZXIoYnEyLCBicSk7CgoJCQkvLyBNb3ZlIGFsbCBzZWxlY3RlZCBibG9ja3MgYWZ0ZXIgdGhlIGN1cnJlbnQgYnEKCQkJbmwgPSBzLmdldFNlbGVjdGVkQmxvY2tzKHNiLCBlYik7CgkJCWZvciAoaSA9IG5sLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7CgkJCQlkb20uaW5zZXJ0QWZ0ZXIobmxbaV0sIGJxKTsKCQkJfQoKCQkJLy8gRW1wdHkgYnEsIHRoZW4gcmVtb3ZlIGl0CgkJCWlmICgvXlxzKiQvLnRlc3QoYnEuaW5uZXJIVE1MKSkKCQkJCWRvbS5yZW1vdmUoYnEsIDEpOyAvLyBLZWVwIGNoaWxkcmVuIHNvIGJvb21hcmsgcmVzdG9yYXRpb24gd29ya3MgY29ycmVjdGx5CgoJCQkvLyBFbXB0eSBicSwgdGhlbiByZW1vdGUgaXQKCQkJaWYgKGJxMiAmJiAvXlxzKiQvLnRlc3QoYnEyLmlubmVySFRNTCkpCgkJCQlkb20ucmVtb3ZlKGJxMiwgMSk7IC8vIEtlZXAgY2hpbGRyZW4gc28gYm9vbWFyayByZXN0b3JhdGlvbiB3b3JrcyBjb3JyZWN0bHkKCgkJCWlmICghYm0pIHsKCQkJCS8vIE1vdmUgY2FyZXQgaW5zaWRlIGVtcHR5IGJsb2NrIGVsZW1lbnQKCQkJCWlmICghdGlueW1jZS5pc0lFKSB7CgkJCQkJciA9IGVkLmdldERvYygpLmNyZWF0ZVJhbmdlKCk7CgkJCQkJci5zZXRTdGFydChzYiwgMCk7CgkJCQkJci5zZXRFbmQoc2IsIDApOwoJCQkJCXMuc2V0Um5nKHIpOwoJCQkJfSBlbHNlIHsKCQkJCQlzLnNlbGVjdChzYik7CgkJCQkJcy5jb2xsYXBzZSgwKTsKCgkJCQkJLy8gSUUgbWlzc2VzIHRoZSBlbXB0eSBibG9jayBzb21lIHRpbWVzIGVsZW1lbnQgc28gd2UgbXVzdCBtb3ZlIGJhY2sgdGhlIGNhcmV0CgkJCQkJaWYgKGRvbS5nZXRQYXJlbnQocy5nZXRTdGFydCgpLCBkb20uaXNCbG9jaykgIT0gc2IpIHsKCQkJCQkJciA9IHMuZ2V0Um5nKCk7CgkJCQkJCXIubW92ZSgnY2hhcmFjdGVyJywgLTEpOwoJCQkJCQlyLnNlbGVjdCgpOwoJCQkJCX0KCQkJCX0KCQkJfSBlbHNlCgkJCQllZC5zZWxlY3Rpb24ubW92ZVRvQm9va21hcmsoYm0pOwoKCQkJcmV0dXJuOwoJCX0KCgkJLy8gU2luY2UgSUUgY2FuIHN0YXJ0IHdpdGggYSB0b3RhbGx5IGVtcHR5IGRvY3VtZW50IHdlIG5lZWQgdG8gYWRkIHRoZSBmaXJzdCBicSBhbmQgcGFyYWdyYXBoCgkJaWYgKHRpbnltY2UuaXNJRSAmJiAhc2IgJiYgIWViKSB7CgkJCWVkLmdldERvYygpLmV4ZWNDb21tYW5kKCdJbmRlbnQnKTsKCQkJbiA9IGdldEJRKHMuZ2V0Tm9kZSgpKTsKCQkJbi5zdHlsZS5tYXJnaW4gPSBuLmRpciA9ICcnOyAvLyBJRSBhZGRzIG1hcmdpbiBhbmQgZGlyIHRvIGJxCgkJCXJldHVybjsKCQl9CgoJCWlmICghc2IgfHwgIWViKQoJCQlyZXR1cm47CgoJCS8vIElmIGVtcHR5IHBhcmFncmFwaCBub2RlIHRoZW4gZG8gbm90IHVzZSBib29rbWFyawoJCWlmIChzYiAhPSBlYiB8fCBzYi5jaGlsZE5vZGVzLmxlbmd0aCA+IDEgfHwgKHNiLmNoaWxkTm9kZXMubGVuZ3RoID09IDEgJiYgc2IuZmlyc3RDaGlsZC5ub2RlTmFtZSAhPSAnQlInKSkKCQkJYm0gPSBzLmdldEJvb2ttYXJrKCk7CgoJCS8vIE1vdmUgc2VsZWN0ZWQgYmxvY2sgZWxlbWVudHMgaW50byBhIGJxCgkJdGlueW1jZS5lYWNoKHMuZ2V0U2VsZWN0ZWRCbG9ja3MoZ2V0QlEocy5nZXRTdGFydCgpKSwgZ2V0QlEocy5nZXRFbmQoKSkpLCBmdW5jdGlvbihlKSB7CgkJCS8vIEZvdW5kIGV4aXN0aW5nIEJRIGFkZCB0byB0aGlzIG9uZQoJCQlpZiAoZS5ub2RlTmFtZSA9PSAnQkxPQ0tRVU9URScgJiYgIWJxKSB7CgkJCQlicSA9IGU7CgkJCQlyZXR1cm47CgkJCX0KCgkJCS8vIE5vIEJRIGZvdW5kLCBjcmVhdGUgb25lCgkJCWlmICghYnEpIHsKCQkJCWJxID0gZG9tLmNyZWF0ZSgnYmxvY2txdW90ZScpOwoJCQkJZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShicSwgZSk7CgkJCX0KCgkJCS8vIEFkZCBjaGlsZHJlbiBmcm9tIGV4aXN0aW5nIEJRCgkJCWlmIChlLm5vZGVOYW1lID09ICdCTE9DS1FVT1RFJyAmJiBicSkgewoJCQkJbiA9IGUuZmlyc3RDaGlsZDsKCgkJCQl3aGlsZSAobikgewoJCQkJCWJxLmFwcGVuZENoaWxkKG4uY2xvbmVOb2RlKHRydWUpKTsKCQkJCQluID0gbi5uZXh0U2libGluZzsKCQkJCX0KCgkJCQlkb20ucmVtb3ZlKGUpOwoJCQkJcmV0dXJuOwoJCQl9CgoJCQkvLyBBZGQgbm9uIEJRIGVsZW1lbnQgdG8gQlEKCQkJYnEuYXBwZW5kQ2hpbGQoZG9tLnJlbW92ZShlKSk7CgkJfSk7CgoJCWlmICghYm0pIHsKCQkJLy8gTW92ZSBjYXJldCBpbnNpZGUgZW1wdHkgYmxvY2sgZWxlbWVudAoJCQlpZiAoIXRpbnltY2UuaXNJRSkgewoJCQkJciA9IGVkLmdldERvYygpLmNyZWF0ZVJhbmdlKCk7CgkJCQlyLnNldFN0YXJ0KHNiLCAwKTsKCQkJCXIuc2V0RW5kKHNiLCAwKTsKCQkJCXMuc2V0Um5nKHIpOwoJCQl9IGVsc2UgewoJCQkJcy5zZWxlY3Qoc2IpOwoJCQkJcy5jb2xsYXBzZSgxKTsKCQkJfQoJCX0gZWxzZQoJCQlzLm1vdmVUb0Jvb2ttYXJrKGJtKTsKCX0pOwp9KSh0aW55bWNlKTsKKGZ1bmN0aW9uKHRpbnltY2UpIHsKCXRpbnltY2UuZWFjaChbJ0N1dCcsICdDb3B5JywgJ1Bhc3RlJ10sIGZ1bmN0aW9uKGNtZCkgewoJCXRpbnltY2UuR2xvYmFsQ29tbWFuZHMuYWRkKGNtZCwgZnVuY3Rpb24oKSB7CgkJCXZhciBlZCA9IHRoaXMsIGRvYyA9IGVkLmdldERvYygpOwoKCQkJdHJ5IHsKCQkJCWRvYy5leGVjQ29tbWFuZChjbWQsIGZhbHNlLCBudWxsKTsKCgkJCQkvLyBPbiBXZWJLaXQgdGhlIGNvbW1hbmQgd2lsbCBqdXN0IGJlIGlnbm9yZWQgaWYgaXQncyBub3QgZW5hYmxlZAoJCQkJaWYgKCFkb2MucXVlcnlDb21tYW5kU3VwcG9ydGVkKGNtZCkpCgkJCQkJdGhyb3cgJ0Vycm9yJzsKCQkJfSBjYXRjaCAoZXgpIHsKCQkJCWVkLndpbmRvd01hbmFnZXIuYWxlcnQoZWQuZ2V0TGFuZygnY2xpcGJvYXJkX25vX3N1cHBvcnQnKSk7CgkJCX0KCQl9KTsKCX0pOwp9KSh0aW55bWNlKTsKKGZ1bmN0aW9uKHRpbnltY2UpIHsKCXRpbnltY2UuR2xvYmFsQ29tbWFuZHMuYWRkKCdJbnNlcnRIb3Jpem9udGFsUnVsZScsIGZ1bmN0aW9uKCkgewoJCWlmICh0aW55bWNlLmlzT3BlcmEpCgkJCXJldHVybiB0aGlzLmdldERvYygpLmV4ZWNDb21tYW5kKCdJbnNlcnRIb3Jpem9udGFsUnVsZScsIGZhbHNlLCAnJyk7CgoJCXRoaXMuc2VsZWN0aW9uLnNldENvbnRlbnQoJzxociAvPicpOwoJfSk7Cn0pKHRpbnltY2UpOwooZnVuY3Rpb24oKSB7Cgl2YXIgY21kcyA9IHRpbnltY2UuR2xvYmFsQ29tbWFuZHM7CgoJY21kcy5hZGQoWydtY2VFbmRVbmRvTGV2ZWwnLCAnbWNlQWRkVW5kb0xldmVsJ10sIGZ1bmN0aW9uKCkgewoJCXRoaXMudW5kb01hbmFnZXIuYWRkKCk7Cgl9KTsKCgljbWRzLmFkZCgnVW5kbycsIGZ1bmN0aW9uKCkgewoJCXZhciBlZCA9IHRoaXM7CgoJCWlmIChlZC5zZXR0aW5ncy5jdXN0b21fdW5kb19yZWRvKSB7CgkJCWVkLnVuZG9NYW5hZ2VyLnVuZG8oKTsKCQkJZWQubm9kZUNoYW5nZWQoKTsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQlyZXR1cm4gZmFsc2U7IC8vIFJ1biBicm93c2VyIGNvbW1hbmQKCX0pOwoKCWNtZHMuYWRkKCdSZWRvJywgZnVuY3Rpb24oKSB7CgkJdmFyIGVkID0gdGhpczsKCgkJaWYgKGVkLnNldHRpbmdzLmN1c3RvbV91bmRvX3JlZG8pIHsKCQkJZWQudW5kb01hbmFnZXIucmVkbygpOwoJCQllZC5ub2RlQ2hhbmdlZCgpOwoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCXJldHVybiBmYWxzZTsgLy8gUnVuIGJyb3dzZXIgY29tbWFuZAoJfSk7Cn0pKCk7CgovKioKICogJElkOiBlZGl0b3JfdGVtcGxhdGVfc3JjLmpzIDEwNDUgMjAwOS0wMy0wNCAyMDowMzoxOFogc3BvY2tlICQKICoKICogQGF1dGhvciBNb3hpZWNvZGUKICogQGNvcHlyaWdodCBDb3B5cmlnaHQgqSAyMDA0LTIwMDgsIE1veGllY29kZSBTeXN0ZW1zIEFCLCBBbGwgcmlnaHRzIHJlc2VydmVkLgogKi8KCihmdW5jdGlvbih0aW55bWNlKSB7Cgl2YXIgRE9NID0gdGlueW1jZS5ET00sIEV2ZW50ID0gdGlueW1jZS5kb20uRXZlbnQsIGV4dGVuZCA9IHRpbnltY2UuZXh0ZW5kLCBlYWNoID0gdGlueW1jZS5lYWNoLCBDb29raWUgPSB0aW55bWNlLnV0aWwuQ29va2llLCBsYXN0RXh0SUQsIGV4cGxvZGUgPSB0aW55bWNlLmV4cGxvZGU7CgoJLy8gVGVsbCBpdCB0byBsb2FkIHRoZW1lIHNwZWNpZmljIGxhbmd1YWdlIHBhY2socykKCXRpbnltY2UuVGhlbWVNYW5hZ2VyLnJlcXVpcmVMYW5nUGFjaygnYWR2YW5jZWQnKTsKCgl0aW55bWNlLmNyZWF0ZSgndGlueW1jZS50aGVtZXMuQWR2YW5jZWRUaGVtZScsIHsKCQlzaXplcyA6IFs4LCAxMCwgMTIsIDE0LCAxOCwgMjQsIDM2XSwKCgkJLy8gQ29udHJvbCBuYW1lIGxvb2t1cCwgZm9ybWF0OiB0aXRsZSwgY29tbWFuZAoJCWNvbnRyb2xzIDogewoJCQlib2xkIDogWydib2xkX2Rlc2MnLCAnQm9sZCddLAoJCQlpdGFsaWMgOiBbJ2l0YWxpY19kZXNjJywgJ0l0YWxpYyddLAoJCQl1bmRlcmxpbmUgOiBbJ3VuZGVybGluZV9kZXNjJywgJ1VuZGVybGluZSddLAoJCQlzdHJpa2V0aHJvdWdoIDogWydzdHJpa2V0cm91Z2hfZGVzYycsICdTdHJpa2V0aHJvdWdoJ10sCgkJCWp1c3RpZnlsZWZ0IDogWydqdXN0aWZ5bGVmdF9kZXNjJywgJ0p1c3RpZnlMZWZ0J10sCgkJCWp1c3RpZnljZW50ZXIgOiBbJ2p1c3RpZnljZW50ZXJfZGVzYycsICdKdXN0aWZ5Q2VudGVyJ10sCgkJCWp1c3RpZnlyaWdodCA6IFsnanVzdGlmeXJpZ2h0X2Rlc2MnLCAnSnVzdGlmeVJpZ2h0J10sCgkJCWp1c3RpZnlmdWxsIDogWydqdXN0aWZ5ZnVsbF9kZXNjJywgJ0p1c3RpZnlGdWxsJ10sCgkJCWJ1bGxpc3QgOiBbJ2J1bGxpc3RfZGVzYycsICdJbnNlcnRVbm9yZGVyZWRMaXN0J10sCgkJCW51bWxpc3QgOiBbJ251bWxpc3RfZGVzYycsICdJbnNlcnRPcmRlcmVkTGlzdCddLAoJCQlvdXRkZW50IDogWydvdXRkZW50X2Rlc2MnLCAnT3V0ZGVudCddLAoJCQlpbmRlbnQgOiBbJ2luZGVudF9kZXNjJywgJ0luZGVudCddLAoJCQljdXQgOiBbJ2N1dF9kZXNjJywgJ0N1dCddLAoJCQljb3B5IDogWydjb3B5X2Rlc2MnLCAnQ29weSddLAoJCQlwYXN0ZSA6IFsncGFzdGVfZGVzYycsICdQYXN0ZSddLAoJCQl1bmRvIDogWyd1bmRvX2Rlc2MnLCAnVW5kbyddLAoJCQlyZWRvIDogWydyZWRvX2Rlc2MnLCAnUmVkbyddLAoJCQlsaW5rIDogWydsaW5rX2Rlc2MnLCAnbWNlTGluayddLAoJCQl1bmxpbmsgOiBbJ3VubGlua19kZXNjJywgJ3VubGluayddLAoJCQlpbWFnZSA6IFsnaW1hZ2VfZGVzYycsICdtY2VJbWFnZSddLAoJCQljbGVhbnVwIDogWydjbGVhbnVwX2Rlc2MnLCAnbWNlQ2xlYW51cCddLAoJCQloZWxwIDogWydoZWxwX2Rlc2MnLCAnbWNlSGVscCddLAoJCQljb2RlIDogWydjb2RlX2Rlc2MnLCAnbWNlQ29kZUVkaXRvciddLAoJCQlociA6IFsnaHJfZGVzYycsICdJbnNlcnRIb3Jpem9udGFsUnVsZSddLAoJCQlyZW1vdmVmb3JtYXQgOiBbJ3JlbW92ZWZvcm1hdF9kZXNjJywgJ1JlbW92ZUZvcm1hdCddLAoJCQlzdWIgOiBbJ3N1Yl9kZXNjJywgJ3N1YnNjcmlwdCddLAoJCQlzdXAgOiBbJ3N1cF9kZXNjJywgJ3N1cGVyc2NyaXB0J10sCgkJCWZvcmVjb2xvciA6IFsnZm9yZWNvbG9yX2Rlc2MnLCAnRm9yZUNvbG9yJ10sCgkJCWZvcmVjb2xvcnBpY2tlciA6IFsnZm9yZWNvbG9yX2Rlc2MnLCAnbWNlRm9yZUNvbG9yJ10sCgkJCWJhY2tjb2xvciA6IFsnYmFja2NvbG9yX2Rlc2MnLCAnSGlsaXRlQ29sb3InXSwKCQkJYmFja2NvbG9ycGlja2VyIDogWydiYWNrY29sb3JfZGVzYycsICdtY2VCYWNrQ29sb3InXSwKCQkJY2hhcm1hcCA6IFsnY2hhcm1hcF9kZXNjJywgJ21jZUNoYXJNYXAnXSwKCQkJdmlzdWFsYWlkIDogWyd2aXN1YWxhaWRfZGVzYycsICdtY2VUb2dnbGVWaXN1YWxBaWQnXSwKCQkJYW5jaG9yIDogWydhbmNob3JfZGVzYycsICdtY2VJbnNlcnRBbmNob3InXSwKCQkJbmV3ZG9jdW1lbnQgOiBbJ25ld2RvY3VtZW50X2Rlc2MnLCAnbWNlTmV3RG9jdW1lbnQnXSwKCQkJYmxvY2txdW90ZSA6IFsnYmxvY2txdW90ZV9kZXNjJywgJ21jZUJsb2NrUXVvdGUnXQoJCX0sCgoJCXN0YXRlQ29udHJvbHMgOiBbJ2JvbGQnLCAnaXRhbGljJywgJ3VuZGVybGluZScsICdzdHJpa2V0aHJvdWdoJywgJ2J1bGxpc3QnLCAnbnVtbGlzdCcsICdqdXN0aWZ5bGVmdCcsICdqdXN0aWZ5Y2VudGVyJywgJ2p1c3RpZnlyaWdodCcsICdqdXN0aWZ5ZnVsbCcsICdzdWInLCAnc3VwJywgJ2Jsb2NrcXVvdGUnXSwKCgkJaW5pdCA6IGZ1bmN0aW9uKGVkLCB1cmwpIHsKCQkJdmFyIHQgPSB0aGlzLCBzLCB2LCBvOwoJCgkJCXQuZWRpdG9yID0gZWQ7CgkJCXQudXJsID0gdXJsOwoJCQl0Lm9uUmVzb2x2ZU5hbWUgPSBuZXcgdGlueW1jZS51dGlsLkRpc3BhdGNoZXIodGhpcyk7CgoJCQkvLyBEZWZhdWx0IHNldHRpbmdzCgkJCXQuc2V0dGluZ3MgPSBzID0gZXh0ZW5kKHsKCQkJCXRoZW1lX2FkdmFuY2VkX3BhdGggOiB0cnVlLAoJCQkJdGhlbWVfYWR2YW5jZWRfdG9vbGJhcl9sb2NhdGlvbiA6ICdib3R0b20nLAoJCQkJdGhlbWVfYWR2YW5jZWRfYnV0dG9uczEgOiAiYm9sZCxpdGFsaWMsdW5kZXJsaW5lLHN0cmlrZXRocm91Z2gsfCxqdXN0aWZ5bGVmdCxqdXN0aWZ5Y2VudGVyLGp1c3RpZnlyaWdodCxqdXN0aWZ5ZnVsbCx8LHN0eWxlc2VsZWN0LGZvcm1hdHNlbGVjdCIsCgkJCQl0aGVtZV9hZHZhbmNlZF9idXR0b25zMiA6ICJidWxsaXN0LG51bWxpc3QsfCxvdXRkZW50LGluZGVudCx8LHVuZG8scmVkbyx8LGxpbmssdW5saW5rLGFuY2hvcixpbWFnZSxjbGVhbnVwLGhlbHAsY29kZSIsCgkJCQl0aGVtZV9hZHZhbmNlZF9idXR0b25zMyA6ICJocixyZW1vdmVmb3JtYXQsdmlzdWFsYWlkLHwsc3ViLHN1cCx8LGNoYXJtYXAiLAoJCQkJdGhlbWVfYWR2YW5jZWRfYmxvY2tmb3JtYXRzIDogInAsYWRkcmVzcyxwcmUsaDEsaDIsaDMsaDQsaDUsaDYiLAoJCQkJdGhlbWVfYWR2YW5jZWRfdG9vbGJhcl9hbGlnbiA6ICJjZW50ZXIiLAoJCQkJdGhlbWVfYWR2YW5jZWRfZm9udHMgOiAiQW5kYWxlIE1vbm89YW5kYWxlIG1vbm8sdGltZXM7QXJpYWw9YXJpYWwsaGVsdmV0aWNhLHNhbnMtc2VyaWY7QXJpYWwgQmxhY2s9YXJpYWwgYmxhY2ssYXZhbnQgZ2FyZGU7Qm9vayBBbnRpcXVhPWJvb2sgYW50aXF1YSxwYWxhdGlubztDb21pYyBTYW5zIE1TPWNvbWljIHNhbnMgbXMsc2Fucy1zZXJpZjtDb3VyaWVyIE5ldz1jb3VyaWVyIG5ldyxjb3VyaWVyO0dlb3JnaWE9Z2VvcmdpYSxwYWxhdGlubztIZWx2ZXRpY2E9aGVsdmV0aWNhO0ltcGFjdD1pbXBhY3QsY2hpY2FnbztTeW1ib2w9c3ltYm9sO1RhaG9tYT10YWhvbWEsYXJpYWwsaGVsdmV0aWNhLHNhbnMtc2VyaWY7VGVybWluYWw9dGVybWluYWwsbW9uYWNvO1RpbWVzIE5ldyBSb21hbj10aW1lcyBuZXcgcm9tYW4sdGltZXM7VHJlYnVjaGV0IE1TPXRyZWJ1Y2hldCBtcyxnZW5ldmE7VmVyZGFuYT12ZXJkYW5hLGdlbmV2YTtXZWJkaW5ncz13ZWJkaW5ncztXaW5nZGluZ3M9d2luZ2RpbmdzLHphcGYgZGluZ2JhdHMiLAoJCQkJdGhlbWVfYWR2YW5jZWRfbW9yZV9jb2xvcnMgOiAxLAoJCQkJdGhlbWVfYWR2YW5jZWRfcm93X2hlaWdodCA6IDIzLAoJCQkJdGhlbWVfYWR2YW5jZWRfcmVzaXplX2hvcml6b250YWwgOiAxLAoJCQkJdGhlbWVfYWR2YW5jZWRfcmVzaXppbmdfdXNlX2Nvb2tpZSA6IDEsCgkJCQl0aGVtZV9hZHZhbmNlZF9mb250X3NpemVzIDogIjEsMiwzLDQsNSw2LDciLAoJCQkJcmVhZG9ubHkgOiBlZC5zZXR0aW5ncy5yZWFkb25seQoJCQl9LCBlZC5zZXR0aW5ncyk7CgoJCQkvLyBTZXR1cCBkZWZhdWx0IGZvbnRfc2l6ZV9zdHlsZV92YWx1ZXMKCQkJaWYgKCFzLmZvbnRfc2l6ZV9zdHlsZV92YWx1ZXMpCgkJCQlzLmZvbnRfc2l6ZV9zdHlsZV92YWx1ZXMgPSAiOHB0LDEwcHQsMTJwdCwxNHB0LDE4cHQsMjRwdCwzNnB0IjsKCgkJCWlmICh0aW55bWNlLmlzKHMudGhlbWVfYWR2YW5jZWRfZm9udF9zaXplcywgJ3N0cmluZycpKSB7CgkJCQlzLmZvbnRfc2l6ZV9zdHlsZV92YWx1ZXMgPSB0aW55bWNlLmV4cGxvZGUocy5mb250X3NpemVfc3R5bGVfdmFsdWVzKTsKCQkJCXMuZm9udF9zaXplX2NsYXNzZXMgPSB0aW55bWNlLmV4cGxvZGUocy5mb250X3NpemVfY2xhc3NlcyB8fCAnJyk7CgoJCQkJLy8gUGFyc2Ugc3RyaW5nIHZhbHVlCgkJCQlvID0ge307CgkJCQllZC5zZXR0aW5ncy50aGVtZV9hZHZhbmNlZF9mb250X3NpemVzID0gcy50aGVtZV9hZHZhbmNlZF9mb250X3NpemVzOwoJCQkJZWFjaChlZC5nZXRQYXJhbSgndGhlbWVfYWR2YW5jZWRfZm9udF9zaXplcycsICcnLCAnaGFzaCcpLCBmdW5jdGlvbih2LCBrKSB7CgkJCQkJdmFyIGNsOwoKCQkJCQlpZiAoayA9PSB2ICYmIHYgPj0gMSAmJiB2IDw9IDcpIHsKCQkJCQkJayA9IHYgKyAnICgnICsgdC5zaXplc1t2IC0gMV0gKyAncHQpJzsKCgkJCQkJCWlmIChlZC5zZXR0aW5ncy5jb252ZXJ0X2ZvbnRzX3RvX3NwYW5zKSB7CgkJCQkJCQljbCA9IHMuZm9udF9zaXplX2NsYXNzZXNbdiAtIDFdOwoJCQkJCQkJdiA9IHMuZm9udF9zaXplX3N0eWxlX3ZhbHVlc1t2IC0gMV0gfHwgKHQuc2l6ZXNbdiAtIDFdICsgJ3B0Jyk7CgkJCQkJCX0KCQkJCQl9CgoJCQkJCWlmICgvXlxzKlwuLy50ZXN0KHYpKQoJCQkJCQljbCA9IHYucmVwbGFjZSgvXC4vZywgJycpOwoKCQkJCQlvW2tdID0gY2wgPyB7J2NsYXNzJyA6IGNsfSA6IHtmb250U2l6ZSA6IHZ9OwoJCQkJfSk7CgoJCQkJcy50aGVtZV9hZHZhbmNlZF9mb250X3NpemVzID0gbzsKCQkJfQoKCQkJaWYgKCh2ID0gcy50aGVtZV9hZHZhbmNlZF9wYXRoX2xvY2F0aW9uKSAmJiB2ICE9ICdub25lJykKCQkJCXMudGhlbWVfYWR2YW5jZWRfc3RhdHVzYmFyX2xvY2F0aW9uID0gcy50aGVtZV9hZHZhbmNlZF9wYXRoX2xvY2F0aW9uOwoKCQkJaWYgKHMudGhlbWVfYWR2YW5jZWRfc3RhdHVzYmFyX2xvY2F0aW9uID09ICdub25lJykKCQkJCXMudGhlbWVfYWR2YW5jZWRfc3RhdHVzYmFyX2xvY2F0aW9uID0gMDsKCgkJCS8vIEluaXQgZWRpdG9yCgkJCWVkLm9uSW5pdC5hZGQoZnVuY3Rpb24oKSB7CgkJCQllZC5vbk5vZGVDaGFuZ2UuYWRkKHQuX25vZGVDaGFuZ2VkLCB0KTsKCiAgICAgICAgICAgICAgICAvLyBBVExBU1NJQU4gLSBkb24ndCBpbmNsdWRlIHRoZSBkZWZhdWx0IGFkdmFuY2VkIHRoZW1lJ3MgY3NzCiAgICAgICAgICAgICAgICAvL2lmIChlZC5zZXR0aW5ncy5jb250ZW50X2NzcyAhPT0gZmFsc2UpCgkJCQkvLwllZC5kb20ubG9hZENTUyhlZC5iYXNlVVJJLnRvQWJzb2x1dGUoInRoZW1lcy9hZHZhbmNlZC9za2lucy8iICsgZWQuc2V0dGluZ3Muc2tpbiArICIvY29udGVudC5jc3MiKSk7CgkJCX0pOwoKCQkJZWQub25TZXRQcm9ncmVzc1N0YXRlLmFkZChmdW5jdGlvbihlZCwgYiwgdGkpIHsKCQkJCXZhciBjbywgaWQgPSBlZC5pZCwgdGI7CgoJCQkJaWYgKGIpIHsKCQkJCQl0LnByb2dyZXNzVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewoJCQkJCQljbyA9IGVkLmdldENvbnRhaW5lcigpOwoJCQkJCQljbyA9IGNvLmluc2VydEJlZm9yZShET00uY3JlYXRlKCdESVYnLCB7c3R5bGUgOiAncG9zaXRpb246cmVsYXRpdmUnfSksIGNvLmZpcnN0Q2hpbGQpOwoJCQkJCQl0YiA9IERPTS5nZXQoZWQuaWQgKyAnX3RibCcpOwoKCQkJCQkJRE9NLmFkZChjbywgJ2RpdicsIHtpZCA6IGlkICsgJ19ibG9ja2VyJywgJ2NsYXNzJyA6ICdtY2VCbG9ja2VyJywgc3R5bGUgOiB7d2lkdGggOiB0Yi5jbGllbnRXaWR0aCArIDIsIGhlaWdodCA6IHRiLmNsaWVudEhlaWdodCArIDJ9fSk7CgkJCQkJCURPTS5hZGQoY28sICdkaXYnLCB7aWQgOiBpZCArICdfcHJvZ3Jlc3MnLCAnY2xhc3MnIDogJ21jZVByb2dyZXNzJywgc3R5bGUgOiB7bGVmdCA6IHRiLmNsaWVudFdpZHRoIC8gMiwgdG9wIDogdGIuY2xpZW50SGVpZ2h0IC8gMn19KTsKCQkJCQl9LCB0aSB8fCAwKTsKCQkJCX0gZWxzZSB7CgkJCQkJRE9NLnJlbW92ZShpZCArICdfYmxvY2tlcicpOwoJCQkJCURPTS5yZW1vdmUoaWQgKyAnX3Byb2dyZXNzJyk7CgkJCQkJY2xlYXJUaW1lb3V0KHQucHJvZ3Jlc3NUaW1lcik7CgkJCQl9CgkJCX0pOwoKCQkJRE9NLmxvYWRDU1Mocy5lZGl0b3JfY3NzID8gZWQuZG9jdW1lbnRCYXNlVVJJLnRvQWJzb2x1dGUocy5lZGl0b3JfY3NzKSA6IHVybCArICIvc2tpbnMvIiArIGVkLnNldHRpbmdzLnNraW4gKyAiL3VpLmNzcyIpOwoKCQkJaWYgKHMuc2tpbl92YXJpYW50KQoJCQkJRE9NLmxvYWRDU1ModXJsICsgIi9za2lucy8iICsgZWQuc2V0dGluZ3Muc2tpbiArICIvdWlfIiArIHMuc2tpbl92YXJpYW50ICsgIi5jc3MiKTsKCQl9LAoKCQljcmVhdGVDb250cm9sIDogZnVuY3Rpb24obiwgY2YpIHsKCQkJdmFyIGNkLCBjOwoKCQkJaWYgKGMgPSBjZi5jcmVhdGVDb250cm9sKG4pKQoJCQkJcmV0dXJuIGM7CgoJCQlzd2l0Y2ggKG4pIHsKCQkJCWNhc2UgInN0eWxlc2VsZWN0IjoKCQkJCQlyZXR1cm4gdGhpcy5fY3JlYXRlU3R5bGVTZWxlY3QoKTsKCgkJCQljYXNlICJmb3JtYXRzZWxlY3QiOgoJCQkJCXJldHVybiB0aGlzLl9jcmVhdGVCbG9ja0Zvcm1hdHMoKTsKCgkJCQljYXNlICJmb250c2VsZWN0IjoKCQkJCQlyZXR1cm4gdGhpcy5fY3JlYXRlRm9udFNlbGVjdCgpOwoKCQkJCWNhc2UgImZvbnRzaXplc2VsZWN0IjoKCQkJCQlyZXR1cm4gdGhpcy5fY3JlYXRlRm9udFNpemVTZWxlY3QoKTsKCgkJCQljYXNlICJmb3JlY29sb3IiOgoJCQkJCXJldHVybiB0aGlzLl9jcmVhdGVGb3JlQ29sb3JNZW51KCk7CgoJCQkJY2FzZSAiYmFja2NvbG9yIjoKCQkJCQlyZXR1cm4gdGhpcy5fY3JlYXRlQmFja0NvbG9yTWVudSgpOwoJCQl9CgoJCQlpZiAoKGNkID0gdGhpcy5jb250cm9sc1tuXSkpCgkJCQlyZXR1cm4gY2YuY3JlYXRlQnV0dG9uKG4sIHt0aXRsZSA6ICJhZHZhbmNlZC4iICsgY2RbMF0sIGNtZCA6IGNkWzFdLCB1aSA6IGNkWzJdLCB2YWx1ZSA6IGNkWzNdfSk7CgkJfSwKCgkJZXhlY0NvbW1hbmQgOiBmdW5jdGlvbihjbWQsIHVpLCB2YWwpIHsKCQkJdmFyIGYgPSB0aGlzWydfJyArIGNtZF07CgoJCQlpZiAoZikgewoJCQkJZi5jYWxsKHRoaXMsIHVpLCB2YWwpOwoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCgkJCXJldHVybiBmYWxzZTsKCQl9LAoKCQlfaW1wb3J0Q2xhc3NlcyA6IGZ1bmN0aW9uKGUpIHsKCQkJdmFyIGVkID0gdGhpcy5lZGl0b3IsIGMgPSBlZC5jb250cm9sTWFuYWdlci5nZXQoJ3N0eWxlc2VsZWN0Jyk7CgoJCQlpZiAoYy5nZXRMZW5ndGgoKSA9PSAwKSB7CgkJCQllYWNoKGVkLmRvbS5nZXRDbGFzc2VzKCksIGZ1bmN0aW9uKG8pIHsKCQkJCQljLmFkZChvWydjbGFzcyddLCBvWydjbGFzcyddKTsKCQkJCX0pOwoJCQl9CgkJfSwKCgkJX2NyZWF0ZVN0eWxlU2VsZWN0IDogZnVuY3Rpb24obikgewoJCQl2YXIgdCA9IHRoaXMsIGVkID0gdC5lZGl0b3IsIGNmID0gZWQuY29udHJvbE1hbmFnZXIsIGMgPSBjZi5jcmVhdGVMaXN0Qm94KCdzdHlsZXNlbGVjdCcsIHsKCQkJCXRpdGxlIDogJ2FkdmFuY2VkLnN0eWxlX3NlbGVjdCcsCgkJCQlvbnNlbGVjdCA6IGZ1bmN0aW9uKHYpIHsKCQkJCQlpZiAoYy5zZWxlY3RlZFZhbHVlID09PSB2KSB7CgkJCQkJCWVkLmV4ZWNDb21tYW5kKCdtY2VTZXRTdHlsZUluZm8nLCAwLCB7Y29tbWFuZCA6ICdyZW1vdmVmb3JtYXQnfSk7CgkJCQkJCWMuc2VsZWN0KCk7CgkJCQkJCXJldHVybiBmYWxzZTsKCQkJCQl9IGVsc2UKCQkJCQkJZWQuZXhlY0NvbW1hbmQoJ21jZVNldENTU0NsYXNzJywgMCwgdik7CgkJCQl9CgkJCX0pOwoKCQkJaWYgKGMpIHsKCQkJCWVhY2goZWQuZ2V0UGFyYW0oJ3RoZW1lX2FkdmFuY2VkX3N0eWxlcycsICcnLCAnaGFzaCcpLCBmdW5jdGlvbih2LCBrKSB7CgkJCQkJaWYgKHYpCgkJCQkJCWMuYWRkKHQuZWRpdG9yLnRyYW5zbGF0ZShrKSwgdik7CgkJCQl9KTsKCgkJCQljLm9uUG9zdFJlbmRlci5hZGQoZnVuY3Rpb24oZWQsIG4pIHsKCQkJCQlpZiAoIWMuTmF0aXZlTGlzdEJveCkgewoJCQkJCQlFdmVudC5hZGQobi5pZCArICdfdGV4dCcsICdmb2N1cycsIHQuX2ltcG9ydENsYXNzZXMsIHQpOwoJCQkJCQlFdmVudC5hZGQobi5pZCArICdfdGV4dCcsICdtb3VzZWRvd24nLCB0Ll9pbXBvcnRDbGFzc2VzLCB0KTsKCQkJCQkJRXZlbnQuYWRkKG4uaWQgKyAnX29wZW4nLCAnZm9jdXMnLCB0Ll9pbXBvcnRDbGFzc2VzLCB0KTsKCQkJCQkJRXZlbnQuYWRkKG4uaWQgKyAnX29wZW4nLCAnbW91c2Vkb3duJywgdC5faW1wb3J0Q2xhc3NlcywgdCk7CgkJCQkJfSBlbHNlCgkJCQkJCUV2ZW50LmFkZChuLmlkLCAnZm9jdXMnLCB0Ll9pbXBvcnRDbGFzc2VzLCB0KTsKCQkJCX0pOwoJCQl9CgoJCQlyZXR1cm4gYzsKCQl9LAoKCQlfY3JlYXRlRm9udFNlbGVjdCA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgYywgdCA9IHRoaXMsIGVkID0gdC5lZGl0b3I7CgoJCQljID0gZWQuY29udHJvbE1hbmFnZXIuY3JlYXRlTGlzdEJveCgnZm9udHNlbGVjdCcsIHt0aXRsZSA6ICdhZHZhbmNlZC5mb250ZGVmYXVsdCcsIGNtZCA6ICdGb250TmFtZSd9KTsKCQkJaWYgKGMpIHsKCQkJCWVhY2goZWQuZ2V0UGFyYW0oJ3RoZW1lX2FkdmFuY2VkX2ZvbnRzJywgdC5zZXR0aW5ncy50aGVtZV9hZHZhbmNlZF9mb250cywgJ2hhc2gnKSwgZnVuY3Rpb24odiwgaykgewoJCQkJCWMuYWRkKGVkLnRyYW5zbGF0ZShrKSwgdiwge3N0eWxlIDogdi5pbmRleE9mKCdkaW5ncycpID09IC0xID8gJ2ZvbnQtZmFtaWx5OicgKyB2IDogJyd9KTsKCQkJCX0pOwoJCQl9CgoJCQlyZXR1cm4gYzsKCQl9LAoKCQlfY3JlYXRlRm9udFNpemVTZWxlY3QgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzLCBlZCA9IHQuZWRpdG9yLCBjLCBpID0gMCwgY2wgPSBbXTsKCgkJCWMgPSBlZC5jb250cm9sTWFuYWdlci5jcmVhdGVMaXN0Qm94KCdmb250c2l6ZXNlbGVjdCcsIHt0aXRsZSA6ICdhZHZhbmNlZC5mb250X3NpemUnLCBvbnNlbGVjdCA6IGZ1bmN0aW9uKHYpIHsKCQkJCWlmICh2LmZvbnRTaXplKQoJCQkJCWVkLmV4ZWNDb21tYW5kKCdGb250U2l6ZScsIGZhbHNlLCB2LmZvbnRTaXplKTsKCQkJCWVsc2UgewoJCQkJCWVhY2godC5zZXR0aW5ncy50aGVtZV9hZHZhbmNlZF9mb250X3NpemVzLCBmdW5jdGlvbih2LCBrKSB7CgkJCQkJCWlmICh2WydjbGFzcyddKQoJCQkJCQkJY2wucHVzaCh2WydjbGFzcyddKTsKCQkJCQl9KTsKCgkJCQkJZWQuZWRpdG9yQ29tbWFuZHMuX2FwcGx5SW5saW5lU3R5bGUoJ3NwYW4nLCB7J2NsYXNzJyA6IHZbJ2NsYXNzJ119LCB7Y2hlY2tfY2xhc3NlcyA6IGNsfSk7CgkJCQl9CgkJCX19KTsKCgkJCWlmIChjKSB7CgkJCQllYWNoKHQuc2V0dGluZ3MudGhlbWVfYWR2YW5jZWRfZm9udF9zaXplcywgZnVuY3Rpb24odiwgaykgewoJCQkJCXZhciBmeiA9IHYuZm9udFNpemU7CgoJCQkJCWlmIChmeiA+PSAxICYmIGZ6IDw9IDcpCgkJCQkJCWZ6ID0gdC5zaXplc1twYXJzZUludChmeikgLSAxXSArICdwdCc7CgoJCQkJCWMuYWRkKGssIHYsIHsnc3R5bGUnIDogJ2ZvbnQtc2l6ZTonICsgZnosICdjbGFzcycgOiAnbWNlRm9udFNpemUnICsgKGkrKykgKyAoJyAnICsgKHZbJ2NsYXNzJ10gfHwgJycpKX0pOwoJCQkJfSk7CgkJCX0KCgkJCXJldHVybiBjOwoJCX0sCgoJCV9jcmVhdGVCbG9ja0Zvcm1hdHMgOiBmdW5jdGlvbigpIHsKCQkJdmFyIGMsIGZtdHMgPSB7CgkJCQkvL3AgOiAnYWR2YW5jZWQucGFyYWdyYXBoJywKCQkJCWFkZHJlc3MgOiAnYWR2YW5jZWQuYWRkcmVzcycsCgkJCQlwcmUgOiAnaHR0cDovLzEwLjIwLjE2MC4xOTgvd2lraS9zL2VuLzIxNjYvMzQvMy41LjkvXy9kb3dubG9hZC9iYXRjaC9jb20uYXRsYXNzaWFuLmNvbmZsdWVuY2UudGlueW1jZXBsdWdpbjplZGl0b3ItcmVzb3VyY2VzL2FkdmFuY2VkLnByZScsCgkJCQloMSA6ICdodHRwOi8vMTAuMjAuMTYwLjE5OC93aWtpL3MvZW4vMjE2Ni8zNC8zLjUuOS9fL2Rvd25sb2FkL2JhdGNoL2NvbS5hdGxhc3NpYW4uY29uZmx1ZW5jZS50aW55bWNlcGx1Z2luOmVkaXRvci1yZXNvdXJjZXMvYWR2YW5jZWQuaDEnLAoJCQkJaDIgOiAnaHR0cDovLzEwLjIwLjE2MC4xOTgvd2lraS9zL2VuLzIxNjYvMzQvMy41LjkvXy9kb3dubG9hZC9iYXRjaC9jb20uYXRsYXNzaWFuLmNvbmZsdWVuY2UudGlueW1jZXBsdWdpbjplZGl0b3ItcmVzb3VyY2VzL2FkdmFuY2VkLmgyJywKCQkJCWgzIDogJ2h0dHA6Ly8xMC4yMC4xNjAuMTk4L3dpa2kvcy9lbi8yMTY2LzM0LzMuNS45L18vZG93bmxvYWQvYmF0Y2gvY29tLmF0bGFzc2lhbi5jb25mbHVlbmNlLnRpbnltY2VwbHVnaW46ZWRpdG9yLXJlc291cmNlcy9hZHZhbmNlZC5oMycsCgkJCQloNCA6ICdodHRwOi8vMTAuMjAuMTYwLjE5OC93aWtpL3MvZW4vMjE2Ni8zNC8zLjUuOS9fL2Rvd25sb2FkL2JhdGNoL2NvbS5hdGxhc3NpYW4uY29uZmx1ZW5jZS50aW55bWNlcGx1Z2luOmVkaXRvci1yZXNvdXJjZXMvYWR2YW5jZWQuaDQnLAoJCQkJaDUgOiAnaHR0cDovLzEwLjIwLjE2MC4xOTgvd2lraS9zL2VuLzIxNjYvMzQvMy41LjkvXy9kb3dubG9hZC9iYXRjaC9jb20uYXRsYXNzaWFuLmNvbmZsdWVuY2UudGlueW1jZXBsdWdpbjplZGl0b3ItcmVzb3VyY2VzL2FkdmFuY2VkLmg1JywKCQkJCWg2IDogJ2h0dHA6Ly8xMC4yMC4xNjAuMTk4L3dpa2kvcy9lbi8yMTY2LzM0LzMuNS45L18vZG93bmxvYWQvYmF0Y2gvY29tLmF0bGFzc2lhbi5jb25mbHVlbmNlLnRpbnltY2VwbHVnaW46ZWRpdG9yLXJlc291cmNlcy9hZHZhbmNlZC5oNicsCiAgICAgICAgICAgICAgICBtYWNyb19xdW90ZSA6ICdhZHZhbmNlZC5tYWNyb19xdW90ZScsCiAgICAgICAgICAgICAgICBtYWNyb19ub2Zvcm1hdCA6ICdhZHZhbmNlZC5tYWNyb19ub2Zvcm1hdCcsCiAgICAgICAgICAgICAgICBtYWNyb19wYW5lbCA6ICdhZHZhbmNlZC5tYWNyb19wYW5lbCcsCiAgICAgICAgICAgICAgICBtYWNyb19jb2RlIDogJ2FkdmFuY2VkLm1hY3JvX2NvZGUnLAogICAgICAgICAgICAgICAgZGl2IDogJ2h0dHA6Ly8xMC4yMC4xNjAuMTk4L3dpa2kvcy9lbi8yMTY2LzM0LzMuNS45L18vZG93bmxvYWQvYmF0Y2gvY29tLmF0bGFzc2lhbi5jb25mbHVlbmNlLnRpbnltY2VwbHVnaW46ZWRpdG9yLXJlc291cmNlcy9hZHZhbmNlZC5kaXYnLAoJCQkJYmxvY2txdW90ZSA6ICdhZHZhbmNlZC5ibG9ja3F1b3RlJywKCQkJCWNvZGUgOiAnaHR0cDovLzEwLjIwLjE2MC4xOTgvd2lraS9zL2VuLzIxNjYvMzQvMy41LjkvXy9kb3dubG9hZC9iYXRjaC9jb20uYXRsYXNzaWFuLmNvbmZsdWVuY2UudGlueW1jZXBsdWdpbjplZGl0b3ItcmVzb3VyY2VzL2FkdmFuY2VkLmNvZGUnLAoJCQkJZHQgOiAnaHR0cDovLzEwLjIwLjE2MC4xOTgvd2lraS9zL2VuLzIxNjYvMzQvMy41LjkvXy9kb3dubG9hZC9iYXRjaC9jb20uYXRsYXNzaWFuLmNvbmZsdWVuY2UudGlueW1jZXBsdWdpbjplZGl0b3ItcmVzb3VyY2VzL2FkdmFuY2VkLmR0JywKCQkJCWRkIDogJ2h0dHA6Ly8xMC4yMC4xNjAuMTk4L3dpa2kvcy9lbi8yMTY2LzM0LzMuNS45L18vZG93bmxvYWQvYmF0Y2gvY29tLmF0bGFzc2lhbi5jb25mbHVlbmNlLnRpbnltY2VwbHVnaW46ZWRpdG9yLXJlc291cmNlcy9hZHZhbmNlZC5kZCcsCgkJCQlzYW1wIDogJ2h0dHA6Ly8xMC4yMC4xNjAuMTk4L3dpa2kvcy9lbi8yMTY2LzM0LzMuNS45L18vZG93bmxvYWQvYmF0Y2gvY29tLmF0bGFzc2lhbi5jb25mbHVlbmNlLnRpbnltY2VwbHVnaW46ZWRpdG9yLXJlc291cmNlcy9hZHZhbmNlZC5zYW1wJwoJCQl9LCB0ID0gdGhpczsKCiAgICAgICAgICAgIC8vIEFUTEFTU0lBTiAtIG1ha2UgdGhlIGRlZmF1bHQgZm9ybWF0IHN0eWxlIGJlIHBhcmFncmFwaHMKICAgICAgICAgICAgYyA9IHQuZWRpdG9yLmNvbnRyb2xNYW5hZ2VyLmNyZWF0ZUxpc3RCb3goJ2Zvcm1hdHNlbGVjdCcsIHt0aXRsZSA6ICdhZHZhbmNlZC5wYXJhZ3JhcGgnLCBjbWQgOiAnRm9ybWF0QmxvY2snfSk7CgkJCWlmIChjKSB7CgkJCQllYWNoKHQuZWRpdG9yLmdldFBhcmFtKCd0aGVtZV9hZHZhbmNlZF9ibG9ja2Zvcm1hdHMnLCB0LnNldHRpbmdzLnRoZW1lX2FkdmFuY2VkX2Jsb2NrZm9ybWF0cywgJ2hhc2gnKSwgZnVuY3Rpb24odiwgaykgewoJCQkJCWMuYWRkKHQuZWRpdG9yLnRyYW5zbGF0ZShrICE9IHYgPyBrIDogZm10c1t2XSksIHYsIHsnY2xhc3MnIDogJ21jZV9mb3JtYXRQcmV2aWV3IG1jZV8nICsgdn0pOwoJCQkJfSk7CgkJCX0KCgkJCXJldHVybiBjOwoJCX0sCgoJCV9jcmVhdGVGb3JlQ29sb3JNZW51IDogZnVuY3Rpb24oKSB7CgkJCXZhciBjLCB0ID0gdGhpcywgcyA9IHQuc2V0dGluZ3MsIG8gPSB7fSwgdjsKCgkJCWlmIChzLnRoZW1lX2FkdmFuY2VkX21vcmVfY29sb3JzKSB7CgkJCQlvLm1vcmVfY29sb3JzX2Z1bmMgPSBmdW5jdGlvbigpIHsKCQkJCQl0Ll9tY2VDb2xvclBpY2tlcigwLCB7CgkJCQkJCWNvbG9yIDogYy52YWx1ZSwKCQkJCQkJZnVuYyA6IGZ1bmN0aW9uKGNvKSB7CgkJCQkJCQljLnNldENvbG9yKGNvKTsKCQkJCQkJfQoJCQkJCX0pOwoJCQkJfTsKCQkJfQoKCQkJaWYgKHYgPSBzLnRoZW1lX2FkdmFuY2VkX3RleHRfY29sb3JzKQoJCQkJby5jb2xvcnMgPSB2OwoKCQkJaWYgKHMudGhlbWVfYWR2YW5jZWRfZGVmYXVsdF9mb3JlZ3JvdW5kX2NvbG9yKQoJCQkJby5kZWZhdWx0X2NvbG9yID0gcy50aGVtZV9hZHZhbmNlZF9kZWZhdWx0X2ZvcmVncm91bmRfY29sb3I7CgoJCQlvLnRpdGxlID0gJ2FkdmFuY2VkLmZvcmVjb2xvcl9kZXNjJzsKCQkJby5jbWQgPSAnRm9yZUNvbG9yJzsKCQkJby5zY29wZSA9IHRoaXM7CgoJCQljID0gdC5lZGl0b3IuY29udHJvbE1hbmFnZXIuY3JlYXRlQ29sb3JTcGxpdEJ1dHRvbignZm9yZWNvbG9yJywgbyk7CgoJCQlyZXR1cm4gYzsKCQl9LAoKCQlfY3JlYXRlQmFja0NvbG9yTWVudSA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgYywgdCA9IHRoaXMsIHMgPSB0LnNldHRpbmdzLCBvID0ge30sIHY7CgoJCQlpZiAocy50aGVtZV9hZHZhbmNlZF9tb3JlX2NvbG9ycykgewoJCQkJby5tb3JlX2NvbG9yc19mdW5jID0gZnVuY3Rpb24oKSB7CgkJCQkJdC5fbWNlQ29sb3JQaWNrZXIoMCwgewoJCQkJCQljb2xvciA6IGMudmFsdWUsCgkJCQkJCWZ1bmMgOiBmdW5jdGlvbihjbykgewoJCQkJCQkJYy5zZXRDb2xvcihjbyk7CgkJCQkJCX0KCQkJCQl9KTsKCQkJCX07CgkJCX0KCgkJCWlmICh2ID0gcy50aGVtZV9hZHZhbmNlZF9iYWNrZ3JvdW5kX2NvbG9ycykKCQkJCW8uY29sb3JzID0gdjsKCgkJCWlmIChzLnRoZW1lX2FkdmFuY2VkX2RlZmF1bHRfYmFja2dyb3VuZF9jb2xvcikKCQkJCW8uZGVmYXVsdF9jb2xvciA9IHMudGhlbWVfYWR2YW5jZWRfZGVmYXVsdF9iYWNrZ3JvdW5kX2NvbG9yOwoKCQkJby50aXRsZSA9ICdhZHZhbmNlZC5iYWNrY29sb3JfZGVzYyc7CgkJCW8uY21kID0gJ0hpbGl0ZUNvbG9yJzsKCQkJby5zY29wZSA9IHRoaXM7CgoJCQljID0gdC5lZGl0b3IuY29udHJvbE1hbmFnZXIuY3JlYXRlQ29sb3JTcGxpdEJ1dHRvbignYmFja2NvbG9yJywgbyk7CgoJCQlyZXR1cm4gYzsKCQl9LAoKCQlyZW5kZXJVSSA6IGZ1bmN0aW9uKG8pIHsKCQkJdmFyIG4sIGljLCB0YiwgdCA9IHRoaXMsIGVkID0gdC5lZGl0b3IsIHMgPSB0LnNldHRpbmdzLCBzYywgcCwgbmw7CgoJCQluID0gcCA9IERPTS5jcmVhdGUoJ3NwYW4nLCB7aWQgOiBlZC5pZCArICdfcGFyZW50JywgJ2NsYXNzJyA6ICdtY2VFZGl0b3IgJyArIGVkLnNldHRpbmdzLnNraW4gKyAnU2tpbicgKyAocy5za2luX3ZhcmlhbnQgPyAnICcgKyBlZC5zZXR0aW5ncy5za2luICsgJ1NraW4nICsgdC5fdWZpcnN0KHMuc2tpbl92YXJpYW50KSA6ICcnKX0pOwoKCQkJaWYgKCFET00uYm94TW9kZWwpCgkJCQluID0gRE9NLmFkZChuLCAnZGl2JywgeydjbGFzcycgOiAnbWNlT2xkQm94TW9kZWwnfSk7CgoJCQluID0gc2MgPSBET00uYWRkKG4sICd0YWJsZScsIHtpZCA6IGVkLmlkICsgJ190YmwnLCAnY2xhc3MnIDogJ21jZUxheW91dCcsIGNlbGxTcGFjaW5nIDogMCwgY2VsbFBhZGRpbmcgOiAwfSk7CgkJCW4gPSB0YiA9IERPTS5hZGQobiwgJ3Rib2R5Jyk7CgoJCQlzd2l0Y2ggKChzLnRoZW1lX2FkdmFuY2VkX2xheW91dF9tYW5hZ2VyIHx8ICcnKS50b0xvd2VyQ2FzZSgpKSB7CgkJCQljYXNlICJyb3dsYXlvdXQiOgoJCQkJCWljID0gdC5fcm93TGF5b3V0KHMsIHRiLCBvKTsKCQkJCQlicmVhazsKCgkJCQljYXNlICJjdXN0b21sYXlvdXQiOgoJCQkJCWljID0gZWQuZXhlY0NhbGxiYWNrKCJ0aGVtZV9hZHZhbmNlZF9jdXN0b21fbGF5b3V0IiwgcywgdGIsIG8sIHApOwoJCQkJCWJyZWFrOwoKCQkJCWRlZmF1bHQ6CgkJCQkJaWMgPSB0Ll9zaW1wbGVMYXlvdXQocywgdGIsIG8sIHApOwoJCQl9CgoJCQluID0gby50YXJnZXROb2RlOwoKCQkJLy8gQWRkIGNsYXNzZXMgdG8gZmlyc3QgYW5kIGxhc3QgVFJzCgkJCW5sID0gRE9NLnN0ZE1vZGUgPyBzYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgndHInKSA6IHNjLnJvd3M7IC8vIFF1aWNrIGZpeCBmb3IgSUUgOAoJCQlET00uYWRkQ2xhc3MobmxbMF0sICdtY2VGaXJzdCcpOwoJCQlET00uYWRkQ2xhc3MobmxbbmwubGVuZ3RoIC0gMV0sICdtY2VMYXN0Jyk7CgoJCQkvLyBBZGQgY2xhc3NlcyB0byBmaXJzdCBhbmQgbGFzdCBURHMKCQkJZWFjaChET00uc2VsZWN0KCd0cicsIHRiKSwgZnVuY3Rpb24obikgewoJCQkJRE9NLmFkZENsYXNzKG4uZmlyc3RDaGlsZCwgJ21jZUZpcnN0Jyk7CgkJCQlET00uYWRkQ2xhc3Mobi5jaGlsZE5vZGVzW24uY2hpbGROb2Rlcy5sZW5ndGggLSAxXSwgJ21jZUxhc3QnKTsKCQkJfSk7CgoJCQlpZiAoRE9NLmdldChzLnRoZW1lX2FkdmFuY2VkX3Rvb2xiYXJfY29udGFpbmVyKSkKCQkJCURPTS5nZXQocy50aGVtZV9hZHZhbmNlZF90b29sYmFyX2NvbnRhaW5lcikuYXBwZW5kQ2hpbGQocCk7CgkJCWVsc2UKCQkJCURPTS5pbnNlcnRBZnRlcihwLCBuKTsKCgkJCUV2ZW50LmFkZChlZC5pZCArICdfcGF0aF9yb3cnLCAnY2xpY2snLCBmdW5jdGlvbihlKSB7CgkJCQllID0gZS50YXJnZXQ7CgoJCQkJaWYgKGUubm9kZU5hbWUgPT0gJ0EnKSB7CgkJCQkJdC5fc2VsKGUuY2xhc3NOYW1lLnJlcGxhY2UoL14uKm1jZVBhdGhfKFswLTldKykuKiQvLCAnJDEnKSk7CgoJCQkJCXJldHVybiBFdmVudC5jYW5jZWwoZSk7CgkJCQl9CgkJCX0pOwovKgoJCQlpZiAoRE9NLmdldChlZC5pZCArICdfcGF0aF9yb3cnKSkgewoJCQkJRXZlbnQuYWRkKGVkLmlkICsgJ190YmwnLCAnbW91c2VvdmVyJywgZnVuY3Rpb24oZSkgewoJCQkJCXZhciByZTsKCQoJCQkJCWUgPSBlLnRhcmdldDsKCgkJCQkJaWYgKGUubm9kZU5hbWUgPT0gJ1NQQU4nICYmIERPTS5oYXNDbGFzcyhlLnBhcmVudE5vZGUsICdtY2VCdXR0b24nKSkgewoJCQkJCQlyZSA9IERPTS5nZXQoZWQuaWQgKyAnX3BhdGhfcm93Jyk7CgkJCQkJCXQubGFzdFBhdGggPSByZS5pbm5lckhUTUw7CgkJCQkJCURPTS5zZXRIVE1MKHJlLCBlLnBhcmVudE5vZGUudGl0bGUpOwoJCQkJCX0KCQkJCX0pOwoKCQkJCUV2ZW50LmFkZChlZC5pZCArICdfdGJsJywgJ21vdXNlb3V0JywgZnVuY3Rpb24oZSkgewoJCQkJCWlmICh0Lmxhc3RQYXRoKSB7CgkJCQkJCURPTS5zZXRIVE1MKGVkLmlkICsgJ19wYXRoX3JvdycsIHQubGFzdFBhdGgpOwoJCQkJCQl0Lmxhc3RQYXRoID0gMDsKCQkJCQl9CgkJCQl9KTsKCQkJfQoqLwoKCQkJaWYgKCFlZC5nZXRQYXJhbSgnYWNjZXNzaWJpbGl0eV9mb2N1cycpKQoJCQkJRXZlbnQuYWRkKERPTS5hZGQocCwgJ2EnLCB7aHJlZiA6ICcjJ30sICc8IS0tIElFIC0tPicpLCAnZm9jdXMnLCBmdW5jdGlvbigpIHt0aW55TUNFLmdldChlZC5pZCkuZm9jdXMoKTt9KTsKCgkJCWlmIChzLnRoZW1lX2FkdmFuY2VkX3Rvb2xiYXJfbG9jYXRpb24gPT0gJ2V4dGVybmFsJykKCQkJCW8uZGVsdGFIZWlnaHQgPSAwOwoKCQkJdC5kZWx0YUhlaWdodCA9IG8uZGVsdGFIZWlnaHQ7CgkJCW8udGFyZ2V0Tm9kZSA9IG51bGw7CgoJCQlyZXR1cm4gewoJCQkJaWZyYW1lQ29udGFpbmVyIDogaWMsCgkJCQllZGl0b3JDb250YWluZXIgOiBlZC5pZCArICdfcGFyZW50JywKCQkJCXNpemVDb250YWluZXIgOiBzYywKCQkJCWRlbHRhSGVpZ2h0IDogby5kZWx0YUhlaWdodAoJCQl9OwoJCX0sCgoJCWdldEluZm8gOiBmdW5jdGlvbigpIHsKCQkJcmV0dXJuIHsKCQkJCWxvbmduYW1lIDogJ0FkdmFuY2VkIHRoZW1lJywKCQkJCWF1dGhvciA6ICdNb3hpZWNvZGUgU3lzdGVtcyBBQicsCgkJCQlhdXRob3J1cmwgOiAnaHR0cDovL3RpbnltY2UubW94aWVjb2RlLmNvbS8nLAoJCQkJdmVyc2lvbiA6IHRpbnltY2UubWFqb3JWZXJzaW9uICsgIi4iICsgdGlueW1jZS5taW5vclZlcnNpb24KCQkJfQoJCX0sCgoJCXJlc2l6ZUJ5IDogZnVuY3Rpb24oZHcsIGRoKSB7CgkJCXZhciBlID0gRE9NLmdldCh0aGlzLmVkaXRvci5pZCArICdfdGJsJyk7CgoJCQl0aGlzLnJlc2l6ZVRvKGUuY2xpZW50V2lkdGggKyBkdywgZS5jbGllbnRIZWlnaHQgKyBkaCk7CgkJfSwKCgkJcmVzaXplVG8gOiBmdW5jdGlvbih3LCBoKSB7CgkJCXZhciBlZCA9IHRoaXMuZWRpdG9yLCBzID0gZWQuc2V0dGluZ3MsIGUgPSBET00uZ2V0KGVkLmlkICsgJ190YmwnKSwgaWZyID0gRE9NLmdldChlZC5pZCArICdfaWZyJyksIGRoOwoKCQkJLy8gQm91bmRlcnkgZml4IGJveAoJCQl3ID0gTWF0aC5tYXgocy50aGVtZV9hZHZhbmNlZF9yZXNpemluZ19taW5fd2lkdGggfHwgMTAwLCB3KTsKCQkJaCA9IE1hdGgubWF4KHMudGhlbWVfYWR2YW5jZWRfcmVzaXppbmdfbWluX2hlaWdodCB8fCAxMDAsIGgpOwoJCQl3ID0gTWF0aC5taW4ocy50aGVtZV9hZHZhbmNlZF9yZXNpemluZ19tYXhfd2lkdGggfHwgMHhGRkZGLCB3KTsKCQkJaCA9IE1hdGgubWluKHMudGhlbWVfYWR2YW5jZWRfcmVzaXppbmdfbWF4X2hlaWdodCB8fCAweEZGRkYsIGgpOwoKCQkJLy8gQ2FsYyBkaWZmZXJlbmNlIGJldHdlZW4gaWZyYW1lIGFuZCBjb250YWluZXIKCQkJZGggPSBlLmNsaWVudEhlaWdodCAtIGlmci5jbGllbnRIZWlnaHQ7CgoJCQkvLyBSZXNpemUgaWZyYW1lIGFuZCBjb250YWluZXIKCQkJRE9NLnNldFN0eWxlKGlmciwgJ2hlaWdodCcsIGggLSBkaCk7CgkJCURPTS5zZXRTdHlsZXMoZSwge3dpZHRoIDogdywgaGVpZ2h0IDogaH0pOwoJCX0sCgoJCWRlc3Ryb3kgOiBmdW5jdGlvbigpIHsKCQkJdmFyIGlkID0gdGhpcy5lZGl0b3IuaWQ7CgoJCQlFdmVudC5jbGVhcihpZCArICdfcmVzaXplJyk7CgkJCUV2ZW50LmNsZWFyKGlkICsgJ19wYXRoX3JvdycpOwoJCQlFdmVudC5jbGVhcihpZCArICdfZXh0ZXJuYWxfY2xvc2UnKTsKCQl9LAoKCQkvLyBJbnRlcm5hbCBmdW5jdGlvbnMKCgkJX3NpbXBsZUxheW91dCA6IGZ1bmN0aW9uKHMsIHRiLCBvLCBwKSB7CgkJCXZhciB0ID0gdGhpcywgZWQgPSB0LmVkaXRvciwgbG8gPSBzLnRoZW1lX2FkdmFuY2VkX3Rvb2xiYXJfbG9jYXRpb24sIHNsID0gcy50aGVtZV9hZHZhbmNlZF9zdGF0dXNiYXJfbG9jYXRpb24sIG4sIGljLCBldGIsIGM7CgoJCQlpZiAocy5yZWFkb25seSkgewoJCQkJbiA9IERPTS5hZGQodGIsICd0cicpOwoJCQkJbiA9IGljID0gRE9NLmFkZChuLCAndGQnLCB7J2NsYXNzJyA6ICdtY2VJZnJhbWVDb250YWluZXInfSk7CgkJCQlyZXR1cm4gaWM7CgkJCX0KCgkJCS8vIENyZWF0ZSB0b29sYmFyIGNvbnRhaW5lciBhdCB0b3AKCQkJaWYgKGxvID09ICd0b3AnKQoJCQkJdC5fYWRkVG9vbGJhcnModGIsIG8pOwoKCQkJLy8gQ3JlYXRlIGV4dGVybmFsIHRvb2xiYXIKCQkJaWYgKGxvID09ICdleHRlcm5hbCcpIHsKCQkJCW4gPSBjID0gRE9NLmNyZWF0ZSgnZGl2Jywge3N0eWxlIDogJ3Bvc2l0aW9uOnJlbGF0aXZlJ30pOwoJCQkJbiA9IERPTS5hZGQobiwgJ2RpdicsIHtpZCA6IGVkLmlkICsgJ19leHRlcm5hbCcsICdjbGFzcycgOiAnbWNlRXh0ZXJuYWxUb29sYmFyJ30pOwoJCQkJRE9NLmFkZChuLCAnYScsIHtpZCA6IGVkLmlkICsgJ19leHRlcm5hbF9jbG9zZScsIGhyZWYgOiAnamF2YXNjcmlwdDo7JywgJ2NsYXNzJyA6ICdtY2VFeHRlcm5hbENsb3NlJ30pOwoJCQkJbiA9IERPTS5hZGQobiwgJ3RhYmxlJywge2lkIDogZWQuaWQgKyAnX3RibGV4dCcsIGNlbGxTcGFjaW5nIDogMCwgY2VsbFBhZGRpbmcgOiAwfSk7CgkJCQlldGIgPSBET00uYWRkKG4sICd0Ym9keScpOwoKCQkJCWlmIChwLmZpcnN0Q2hpbGQuY2xhc3NOYW1lID09ICdtY2VPbGRCb3hNb2RlbCcpCgkJCQkJcC5maXJzdENoaWxkLmFwcGVuZENoaWxkKGMpOwoJCQkJZWxzZQoJCQkJCXAuaW5zZXJ0QmVmb3JlKGMsIHAuZmlyc3RDaGlsZCk7CgoJCQkJdC5fYWRkVG9vbGJhcnMoZXRiLCBvKTsKCgkJCQllZC5vbk1vdXNlVXAuYWRkKGZ1bmN0aW9uKCkgewoJCQkJCXZhciBlID0gRE9NLmdldChlZC5pZCArICdfZXh0ZXJuYWwnKTsKCQkJCQlET00uc2hvdyhlKTsKCgkJCQkJRE9NLmhpZGUobGFzdEV4dElEKTsKCgkJCQkJdmFyIGYgPSBFdmVudC5hZGQoZWQuaWQgKyAnX2V4dGVybmFsX2Nsb3NlJywgJ2NsaWNrJywgZnVuY3Rpb24oKSB7CgkJCQkJCURPTS5oaWRlKGVkLmlkICsgJ19leHRlcm5hbCcpOwoJCQkJCQlFdmVudC5yZW1vdmUoZWQuaWQgKyAnX2V4dGVybmFsX2Nsb3NlJywgJ2NsaWNrJywgZik7CgkJCQkJfSk7CgoJCQkJCURPTS5zaG93KGUpOwoJCQkJCURPTS5zZXRTdHlsZShlLCAndG9wJywgMCAtIERPTS5nZXRSZWN0KGVkLmlkICsgJ190YmxleHQnKS5oIC0gMSk7CgoJCQkJCS8vIEZpeGVzIElFIHJlbmRlcmluZyBidWcKCQkJCQlET00uaGlkZShlKTsKCQkJCQlET00uc2hvdyhlKTsKCQkJCQllLnN0eWxlLmZpbHRlciA9ICcnOwoKCQkJCQlsYXN0RXh0SUQgPSBlZC5pZCArICdfZXh0ZXJuYWwnOwoKCQkJCQllID0gbnVsbDsKCQkJCX0pOwoJCQl9CgoJCQlpZiAoc2wgPT0gJ3RvcCcpCgkJCQl0Ll9hZGRTdGF0dXNCYXIodGIsIG8pOwoKCQkJLy8gQ3JlYXRlIGlmcmFtZSBjb250YWluZXIKCQkJaWYgKCFzLnRoZW1lX2FkdmFuY2VkX3Rvb2xiYXJfY29udGFpbmVyKSB7CgkJCQluID0gRE9NLmFkZCh0YiwgJ3RyJyk7CgkJCQluID0gaWMgPSBET00uYWRkKG4sICd0ZCcsIHsnY2xhc3MnIDogJ21jZUlmcmFtZUNvbnRhaW5lcid9KTsKCQkJfQoKCQkJLy8gQ3JlYXRlIHRvb2xiYXIgY29udGFpbmVyIGF0IGJvdHRvbQoJCQlpZiAobG8gPT0gJ2JvdHRvbScpCgkJCQl0Ll9hZGRUb29sYmFycyh0Yiwgbyk7CgoJCQlpZiAoc2wgPT0gJ2JvdHRvbScpCgkJCQl0Ll9hZGRTdGF0dXNCYXIodGIsIG8pOwoKCQkJcmV0dXJuIGljOwoJCX0sCgoJCV9yb3dMYXlvdXQgOiBmdW5jdGlvbihzLCB0YiwgbykgewoJCQl2YXIgdCA9IHRoaXMsIGVkID0gdC5lZGl0b3IsIGRjLCBkYSwgY2YgPSBlZC5jb250cm9sTWFuYWdlciwgbiwgaWMsIHRvLCBhOwoKCQkJZGMgPSBzLnRoZW1lX2FkdmFuY2VkX2NvbnRhaW5lcnNfZGVmYXVsdF9jbGFzcyB8fCAnJzsKCQkJZGEgPSBzLnRoZW1lX2FkdmFuY2VkX2NvbnRhaW5lcnNfZGVmYXVsdF9hbGlnbiB8fCAnY2VudGVyJzsKCgkJCWVhY2goZXhwbG9kZShzLnRoZW1lX2FkdmFuY2VkX2NvbnRhaW5lcnMgfHwgJycpLCBmdW5jdGlvbihjLCBpKSB7CgkJCQl2YXIgdiA9IHNbJ3RoZW1lX2FkdmFuY2VkX2NvbnRhaW5lcl8nICsgY10gfHwgJyc7CgoJCQkJc3dpdGNoICh2LnRvTG93ZXJDYXNlKCkpIHsKCQkJCQljYXNlICdtY2VlZGl0b3InOgoJCQkJCQluID0gRE9NLmFkZCh0YiwgJ3RyJyk7CgkJCQkJCW4gPSBpYyA9IERPTS5hZGQobiwgJ3RkJywgeydjbGFzcycgOiAnbWNlSWZyYW1lQ29udGFpbmVyJ30pOwoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAnbWNlZWxlbWVudHBhdGgnOgoJCQkJCQl0Ll9hZGRTdGF0dXNCYXIodGIsIG8pOwoJCQkJCQlicmVhazsKCgkJCQkJZGVmYXVsdDoKCQkJCQkJYSA9IChzWyd0aGVtZV9hZHZhbmNlZF9jb250YWluZXJfJyArIGMgKyAnX2FsaWduJ10gfHwgZGEpLnRvTG93ZXJDYXNlKCk7CgkJCQkJCWEgPSAnbWNlJyArIHQuX3VmaXJzdChhKTsKCgkJCQkJCW4gPSBET00uYWRkKERPTS5hZGQodGIsICd0cicpLCAndGQnLCB7CgkJCQkJCQknY2xhc3MnIDogJ21jZVRvb2xiYXIgJyArIChzWyd0aGVtZV9hZHZhbmNlZF9jb250YWluZXJfJyArIGMgKyAnX2NsYXNzJ10gfHwgZGMpICsgJyAnICsgYSB8fCBkYQoJCQkJCQl9KTsKCgkJCQkJCXRvID0gY2YuY3JlYXRlVG9vbGJhcigidG9vbGJhciIgKyBpKTsKCQkJCQkJdC5fYWRkQ29udHJvbHModiwgdG8pOwoJCQkJCQlET00uc2V0SFRNTChuLCB0by5yZW5kZXJIVE1MKCkpOwoJCQkJCQlvLmRlbHRhSGVpZ2h0IC09IHMudGhlbWVfYWR2YW5jZWRfcm93X2hlaWdodDsKCQkJCX0KCQkJfSk7CgoJCQlyZXR1cm4gaWM7CgkJfSwKCgkJX2FkZENvbnRyb2xzIDogZnVuY3Rpb24odiwgdGIpIHsKCQkJdmFyIHQgPSB0aGlzLCBzID0gdC5zZXR0aW5ncywgZGksIGNmID0gdC5lZGl0b3IuY29udHJvbE1hbmFnZXI7CgoJCQlpZiAocy50aGVtZV9hZHZhbmNlZF9kaXNhYmxlICYmICF0Ll9kaXNhYmxlZCkgewoJCQkJZGkgPSB7fTsKCgkJCQllYWNoKGV4cGxvZGUocy50aGVtZV9hZHZhbmNlZF9kaXNhYmxlKSwgZnVuY3Rpb24odikgewoJCQkJCWRpW3ZdID0gMTsKCQkJCX0pOwoKCQkJCXQuX2Rpc2FibGVkID0gZGk7CgkJCX0gZWxzZQoJCQkJZGkgPSB0Ll9kaXNhYmxlZDsKCgkJCWVhY2goZXhwbG9kZSh2KSwgZnVuY3Rpb24obikgewoJCQkJdmFyIGM7CgoJCQkJaWYgKGRpICYmIGRpW25dKQoJCQkJCXJldHVybjsKCgkJCQkvLyBDb21wYXRpYmxpdHkgd2l0aCAyLngKCQkJCWlmIChuID09ICd0YWJsZWNvbnRyb2xzJykgewoJCQkJCWVhY2goWyJ0YWJsZSIsInwiLCJyb3dfcHJvcHMiLCJjZWxsX3Byb3BzIiwifCIsInJvd19iZWZvcmUiLCJyb3dfYWZ0ZXIiLCJkZWxldGVfcm93IiwifCIsImNvbF9iZWZvcmUiLCJjb2xfYWZ0ZXIiLCJkZWxldGVfY29sIiwifCIsInNwbGl0X2NlbGxzIiwibWVyZ2VfY2VsbHMiXSwgZnVuY3Rpb24obikgewoJCQkJCQluID0gdC5jcmVhdGVDb250cm9sKG4sIGNmKTsKCgkJCQkJCWlmIChuKQoJCQkJCQkJdGIuYWRkKG4pOwoJCQkJCX0pOwoKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJYyA9IHQuY3JlYXRlQ29udHJvbChuLCBjZik7CgoJCQkJaWYgKGMpCgkJCQkJdGIuYWRkKGMpOwoJCQl9KTsKCQl9LAoKCQlfYWRkVG9vbGJhcnMgOiBmdW5jdGlvbihjLCBvKSB7CgkJCXZhciB0ID0gdGhpcywgaSwgdGIsIGVkID0gdC5lZGl0b3IsIHMgPSB0LnNldHRpbmdzLCB2LCBjZiA9IGVkLmNvbnRyb2xNYW5hZ2VyLCBkaSwgbiwgaCA9IFtdLCBhOwoKCQkJYSA9IHMudGhlbWVfYWR2YW5jZWRfdG9vbGJhcl9hbGlnbi50b0xvd2VyQ2FzZSgpOwoJCQlhID0gJ21jZScgKyB0Ll91Zmlyc3QoYSk7CgoJCQluID0gRE9NLmFkZChET00uYWRkKGMsICd0cicpLCAndGQnLCB7J2NsYXNzJyA6ICdtY2VUb29sYmFyICcgKyBhfSk7CgoJCQlpZiAoIWVkLmdldFBhcmFtKCdhY2Nlc3NpYmlsaXR5X2ZvY3VzJykpCgkJCQloLnB1c2goRE9NLmNyZWF0ZUhUTUwoJ2EnLCB7aHJlZiA6ICcjJywgb25mb2N1cyA6ICd0aW55TUNFLmdldChcJycgKyBlZC5pZCArICdcJykuZm9jdXMoKTsnfSwgJzwhLS0gSUUgLS0+JykpOwoKCQkJaC5wdXNoKERPTS5jcmVhdGVIVE1MKCdhJywge2hyZWYgOiAnIycsIGFjY2Vzc2tleSA6ICdxJywgdGl0bGUgOiBlZC5nZXRMYW5nKCJhZHZhbmNlZC50b29sYmFyX2ZvY3VzIil9LCAnPCEtLSBJRSAtLT4nKSk7CgoJCQkvLyBDcmVhdGUgdG9vbGJhciBhbmQgYWRkIHRoZSBjb250cm9scwoJCQlmb3IgKGk9MTsgKHYgPSBzWyd0aGVtZV9hZHZhbmNlZF9idXR0b25zJyArIGldKTsgaSsrKSB7CgkJCQl0YiA9IGNmLmNyZWF0ZVRvb2xiYXIoInRvb2xiYXIiICsgaSwgeydjbGFzcycgOiAnbWNlVG9vbGJhclJvdycgKyBpfSk7CgoJCQkJaWYgKHNbJ3RoZW1lX2FkdmFuY2VkX2J1dHRvbnMnICsgaSArICdfYWRkJ10pCgkJCQkJdiArPSAnLCcgKyBzWyd0aGVtZV9hZHZhbmNlZF9idXR0b25zJyArIGkgKyAnX2FkZCddOwoKCQkJCWlmIChzWyd0aGVtZV9hZHZhbmNlZF9idXR0b25zJyArIGkgKyAnX2FkZF9iZWZvcmUnXSkKCQkJCQl2ID0gc1sndGhlbWVfYWR2YW5jZWRfYnV0dG9ucycgKyBpICsgJ19hZGRfYmVmb3JlJ10gKyAnLCcgKyB2OwoKCQkJCXQuX2FkZENvbnRyb2xzKHYsIHRiKTsKCgkJCQkvL24uYXBwZW5kQ2hpbGQobiA9IHRiLnJlbmRlcigpKTsKCQkJCWgucHVzaCh0Yi5yZW5kZXJIVE1MKCkpOwoKCQkJCW8uZGVsdGFIZWlnaHQgLT0gcy50aGVtZV9hZHZhbmNlZF9yb3dfaGVpZ2h0OwoJCQl9CgoJCQloLnB1c2goRE9NLmNyZWF0ZUhUTUwoJ2EnLCB7aHJlZiA6ICcjJywgYWNjZXNza2V5IDogJ3onLCB0aXRsZSA6IGVkLmdldExhbmcoImFkdmFuY2VkLnRvb2xiYXJfZm9jdXMiKSwgb25mb2N1cyA6ICd0aW55TUNFLmdldEluc3RhbmNlQnlJZChcJycgKyBlZC5pZCArICdcJykuZm9jdXMoKTsnfSwgJzwhLS0gSUUgLS0+JykpOwoJCQlET00uc2V0SFRNTChuLCBoLmpvaW4oJycpKTsKCQl9LAoKCQlfYWRkU3RhdHVzQmFyIDogZnVuY3Rpb24odGIsIG8pIHsKCQkJdmFyIG4sIHQgPSB0aGlzLCBlZCA9IHQuZWRpdG9yLCBzID0gdC5zZXR0aW5ncywgciwgbWYsIG1lLCB0ZDsKCgkJCW4gPSBET00uYWRkKHRiLCAndHInKTsKCQkJbiA9IHRkID0gRE9NLmFkZChuLCAndGQnLCB7J2NsYXNzJyA6ICdtY2VTdGF0dXNiYXInfSk7CgkJCW4gPSBET00uYWRkKG4sICdkaXYnLCB7aWQgOiBlZC5pZCArICdfcGF0aF9yb3cnfSwgcy50aGVtZV9hZHZhbmNlZF9wYXRoID8gZWQudHJhbnNsYXRlKCdodHRwOi8vMTAuMjAuMTYwLjE5OC93aWtpL3MvZW4vMjE2Ni8zNC8zLjUuOS9fL2Rvd25sb2FkL2JhdGNoL2NvbS5hdGxhc3NpYW4uY29uZmx1ZW5jZS50aW55bWNlcGx1Z2luOmVkaXRvci1yZXNvdXJjZXMvYWR2YW5jZWQucGF0aCcpICsgJzogJyA6ICcmIzE2MDsnKTsKCQkJRE9NLmFkZChuLCAnYScsIHtocmVmIDogJyMnLCBhY2Nlc3NrZXkgOiAneCd9KTsKCgkJCWlmIChzLnRoZW1lX2FkdmFuY2VkX3Jlc2l6aW5nKSB7CgkJCQlET00uYWRkKHRkLCAnYScsIHtpZCA6IGVkLmlkICsgJ19yZXNpemUnLCBocmVmIDogJ2phdmFzY3JpcHQ6OycsIG9uY2xpY2sgOiAicmV0dXJuIGZhbHNlOyIsICdjbGFzcycgOiAnbWNlUmVzaXplJ30pOwoKCQkJCWlmIChzLnRoZW1lX2FkdmFuY2VkX3Jlc2l6aW5nX3VzZV9jb29raWUpIHsKCQkJCQllZC5vblBvc3RSZW5kZXIuYWRkKGZ1bmN0aW9uKCkgewoJCQkJCQl2YXIgbyA9IENvb2tpZS5nZXRIYXNoKCJUaW55TUNFXyIgKyBlZC5pZCArICJfc2l6ZSIpLCBjID0gRE9NLmdldChlZC5pZCArICdfdGJsJyk7CgoJCQkJCQlpZiAoIW8pCgkJCQkJCQlyZXR1cm47CgoJCQkJCQlpZiAocy50aGVtZV9hZHZhbmNlZF9yZXNpemVfaG9yaXpvbnRhbCkKCQkJCQkJCWMuc3R5bGUud2lkdGggPSBNYXRoLm1heCgxMCwgby5jdykgKyAncHgnOwoKCQkJCQkJYy5zdHlsZS5oZWlnaHQgPSBNYXRoLm1heCgxMCwgby5jaCkgKyAncHgnOwoJCQkJCQlET00uZ2V0KGVkLmlkICsgJ19pZnInKS5zdHlsZS5oZWlnaHQgPSBNYXRoLm1heCgxMCwgcGFyc2VJbnQoby5jaCkgKyB0LmRlbHRhSGVpZ2h0KSArICdweCc7CgkJCQkJfSk7CgkJCQl9CgoJCQkJZWQub25Qb3N0UmVuZGVyLmFkZChmdW5jdGlvbigpIHsKCQkJCQlFdmVudC5hZGQoZWQuaWQgKyAnX3Jlc2l6ZScsICdtb3VzZWRvd24nLCBmdW5jdGlvbihlKSB7CgkJCQkJCXZhciBjLCBwLCB3LCBoLCBuLCBwYTsKCgkJCQkJCS8vIE1lYXN1cmUgY29udGFpbmVyCgkJCQkJCWMgPSBET00uZ2V0KGVkLmlkICsgJ190YmwnKTsKCQkJCQkJdyA9IGMuY2xpZW50V2lkdGg7CgkJCQkJCWggPSBjLmNsaWVudEhlaWdodDsKCgkJCQkJCW1pdyA9IHMudGhlbWVfYWR2YW5jZWRfcmVzaXppbmdfbWluX3dpZHRoIHx8IDEwMDsKCQkJCQkJbWloID0gcy50aGVtZV9hZHZhbmNlZF9yZXNpemluZ19taW5faGVpZ2h0IHx8IDEwMDsKCQkJCQkJbWF3ID0gcy50aGVtZV9hZHZhbmNlZF9yZXNpemluZ19tYXhfd2lkdGggfHwgMHhGRkZGOwoJCQkJCQltYWggPSBzLnRoZW1lX2FkdmFuY2VkX3Jlc2l6aW5nX21heF9oZWlnaHQgfHwgMHhGRkZGOwoKCQkJCQkJLy8gU2V0dXAgcGxhY2Vob2xkZXIKCQkJCQkJcCA9IERPTS5hZGQoRE9NLmdldChlZC5pZCArICdfcGFyZW50JyksICdkaXYnLCB7J2NsYXNzJyA6ICdtY2VQbGFjZUhvbGRlcid9KTsKCQkJCQkJRE9NLnNldFN0eWxlcyhwLCB7d2lkdGggOiB3LCBoZWlnaHQgOiBofSk7CgoJCQkJCQkvLyBSZXBsYWNlIHdpdGggcGxhY2Vob2xkZXIKCQkJCQkJRE9NLmhpZGUoYyk7CgkJCQkJCURPTS5zaG93KHApOwoKCQkJCQkJLy8gQ3JlYXRlIGludGVybmFsIHJlc2l6ZSBvYmoKCQkJCQkJciA9IHsKCQkJCQkJCXggOiBlLnNjcmVlblgsCgkJCQkJCQl5IDogZS5zY3JlZW5ZLAoJCQkJCQkJdyA6IHcsCgkJCQkJCQloIDogaCwKCQkJCQkJCWR4IDogbnVsbCwKCQkJCQkJCWR5IDogbnVsbAoJCQkJCQl9OwoKCQkJCQkJLy8gU3RhcnQgbGlzdGVuaW5nCgkJCQkJCW1mID0gRXZlbnQuYWRkKERPTS5kb2MsICdtb3VzZW1vdmUnLCBmdW5jdGlvbihlKSB7CgkJCQkJCQl2YXIgdywgaDsKCgkJCQkJCQkvLyBDYWxjIGRlbHRhIHZhbHVlcwoJCQkJCQkJci5keCA9IGUuc2NyZWVuWCAtIHIueDsKCQkJCQkJCXIuZHkgPSBlLnNjcmVlblkgLSByLnk7CgoJCQkJCQkJLy8gQm91bmRlcnkgZml4IGJveAoJCQkJCQkJdyA9IE1hdGgubWF4KG1pdywgci53ICsgci5keCk7CgkJCQkJCQloID0gTWF0aC5tYXgobWloLCByLmggKyByLmR5KTsKCQkJCQkJCXcgPSBNYXRoLm1pbihtYXcsIHcpOwoJCQkJCQkJaCA9IE1hdGgubWluKG1haCwgaCk7CgoJCQkJCQkJLy8gUmVzaXplIHBsYWNlaG9sZGVyCgkJCQkJCQlpZiAocy50aGVtZV9hZHZhbmNlZF9yZXNpemVfaG9yaXpvbnRhbCkKCQkJCQkJCQlwLnN0eWxlLndpZHRoID0gdyArICdweCc7CgoJCQkJCQkJcC5zdHlsZS5oZWlnaHQgPSBoICsgJ3B4JzsKCgkJCQkJCQlyZXR1cm4gRXZlbnQuY2FuY2VsKGUpOwoJCQkJCQl9KTsKCgkJCQkJCW1lID0gRXZlbnQuYWRkKERPTS5kb2MsICdtb3VzZXVwJywgZnVuY3Rpb24oZSkgewoJCQkJCQkJdmFyIGlmcjsKCgkJCQkJCQkvLyBTdG9wIGxpc3RlbmluZwoJCQkJCQkJRXZlbnQucmVtb3ZlKERPTS5kb2MsICdtb3VzZW1vdmUnLCBtZik7CgkJCQkJCQlFdmVudC5yZW1vdmUoRE9NLmRvYywgJ21vdXNldXAnLCBtZSk7CgoJCQkJCQkJYy5zdHlsZS5kaXNwbGF5ID0gJyc7CgkJCQkJCQlET00ucmVtb3ZlKHApOwoKCQkJCQkJCWlmIChyLmR4ID09PSBudWxsKQoJCQkJCQkJCXJldHVybjsKCgkJCQkJCQlpZnIgPSBET00uZ2V0KGVkLmlkICsgJ19pZnInKTsKCgkJCQkJCQlpZiAocy50aGVtZV9hZHZhbmNlZF9yZXNpemVfaG9yaXpvbnRhbCkKCQkJCQkJCQljLnN0eWxlLndpZHRoID0gTWF0aC5tYXgoMTAsIHIudyArIHIuZHgpICsgJ3B4JzsKCgkJCQkJCQljLnN0eWxlLmhlaWdodCA9IE1hdGgubWF4KDEwLCByLmggKyByLmR5KSArICdweCc7CgkJCQkJCQlpZnIuc3R5bGUuaGVpZ2h0ID0gTWF0aC5tYXgoMTAsIGlmci5jbGllbnRIZWlnaHQgKyByLmR5KSArICdweCc7CgoJCQkJCQkJaWYgKHMudGhlbWVfYWR2YW5jZWRfcmVzaXppbmdfdXNlX2Nvb2tpZSkgewoJCQkJCQkJCUNvb2tpZS5zZXRIYXNoKCJUaW55TUNFXyIgKyBlZC5pZCArICJfc2l6ZSIsIHsKCQkJCQkJCQkJY3cgOiByLncgKyByLmR4LAoJCQkJCQkJCQljaCA6IHIuaCArIHIuZHkKCQkJCQkJCQl9KTsKCQkJCQkJCX0KCQkJCQkJfSk7CgoJCQkJCQlyZXR1cm4gRXZlbnQuY2FuY2VsKGUpOwoJCQkJCX0pOwoJCQkJfSk7CgkJCX0KCgkJCW8uZGVsdGFIZWlnaHQgLT0gMjE7CgkJCW4gPSB0YiA9IG51bGw7CgkJfSwKCgkJX25vZGVDaGFuZ2VkIDogZnVuY3Rpb24oZWQsIGNtLCBuLCBjbykgewoJCQl2YXIgdCA9IHRoaXMsIHAsIGRlID0gMCwgdiwgYywgcyA9IHQuc2V0dGluZ3MsIGNsLCBmeiwgZm47CgoJCQlpZiAocy5yZWFkb25seSkKCQkJCXJldHVybjsKCgkJCXRpbnltY2UuZWFjaCh0LnN0YXRlQ29udHJvbHMsIGZ1bmN0aW9uKGMpIHsKCQkJCWNtLnNldEFjdGl2ZShjLCBlZC5xdWVyeUNvbW1hbmRTdGF0ZSh0LmNvbnRyb2xzW2NdWzFdKSk7CgkJCX0pOwoKCQkJY20uc2V0QWN0aXZlKCd2aXN1YWxhaWQnLCBlZC5oYXNWaXN1YWwpOwoJCQljbS5zZXREaXNhYmxlZCgndW5kbycsICFlZC51bmRvTWFuYWdlci5oYXNVbmRvKCkgJiYgIWVkLnR5cGluZyk7CgkJCWNtLnNldERpc2FibGVkKCdyZWRvJywgIWVkLnVuZG9NYW5hZ2VyLmhhc1JlZG8oKSk7CgkJCWNtLnNldERpc2FibGVkKCdvdXRkZW50JywgIWVkLnF1ZXJ5Q29tbWFuZFN0YXRlKCdPdXRkZW50JykpOwogICAgICAgICAgICAvLyBBVExBU1NJQU4gLSBvbmx5IHN1cHBvcnQgaW5kZW50YXRpb24gaW4gbGlzdHMKICAgICAgICAgICAgY20uc2V0RGlzYWJsZWQoJ2luZGVudCcsICEoZWQucXVlcnlDb21tYW5kU3RhdGUoJ0luc2VydFVub3JkZXJlZExpc3QnKSB8fCBlZC5xdWVyeUNvbW1hbmRTdGF0ZSgnSW5zZXJ0T3JkZXJlZExpc3QnKSkpOwoKCQkJcCA9IERPTS5nZXRQYXJlbnQobiwgJ0EnKTsKCQkJaWYgKGMgPSBjbS5nZXQoJ2xpbmsnKSkgewoJCQkJaWYgKCFwIHx8ICFwLm5hbWUpIHsKCQkJCQljLnNldERpc2FibGVkKCFwICYmIGNvKTsKCQkJCQljLnNldEFjdGl2ZSghIXApOwoJCQkJfQoJCQl9CgoJCQlpZiAoYyA9IGNtLmdldCgndW5saW5rJykpIHsKCQkJCWMuc2V0RGlzYWJsZWQoIXAgJiYgY28pOwoJCQkJYy5zZXRBY3RpdmUoISFwICYmICFwLm5hbWUpOwoJCQl9CgoJCQlpZiAoYyA9IGNtLmdldCgnYW5jaG9yJykpIHsKCQkJCWMuc2V0QWN0aXZlKCEhcCAmJiBwLm5hbWUpOwoKCQkJCWlmICh0aW55bWNlLmlzV2ViS2l0KSB7CgkJCQkJcCA9IERPTS5nZXRQYXJlbnQobiwgJ0lNRycpOwoJCQkJCWMuc2V0QWN0aXZlKCEhcCAmJiBET00uZ2V0QXR0cmliKHAsICdtY2VfbmFtZScpID09ICdhJyk7CgkJCQl9CgkJCX0KCgkJCXAgPSBET00uZ2V0UGFyZW50KG4sICdJTUcnKTsKCQkJaWYgKGMgPSBjbS5nZXQoJ2ltYWdlJykpCgkJCQljLnNldEFjdGl2ZSghIXAgJiYgbi5jbGFzc05hbWUuaW5kZXhPZignbWNlSXRlbScpID09IC0xKTsKCgkJCWlmIChjID0gY20uZ2V0KCdzdHlsZXNlbGVjdCcpKSB7CgkJCQlpZiAobi5jbGFzc05hbWUpIHsKCQkJCQl0Ll9pbXBvcnRDbGFzc2VzKCk7CgkJCQkJYy5zZWxlY3Qobi5jbGFzc05hbWUpOwoJCQkJfSBlbHNlCgkJCQkJYy5zZWxlY3QoKTsKCQkJfQoKCQkJaWYgKGMgPSBjbS5nZXQoJ2Zvcm1hdHNlbGVjdCcpKSB7CgkJCQlwID0gRE9NLmdldFBhcmVudChuLCBET00uaXNCbG9jayk7CgoJCQkJaWYgKHApCgkJCQkJYy5zZWxlY3QocC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKTsKCQkJfQoKCQkJaWYgKGVkLnNldHRpbmdzLmNvbnZlcnRfZm9udHNfdG9fc3BhbnMpIHsKCQkJCWVkLmRvbS5nZXRQYXJlbnQobiwgZnVuY3Rpb24obikgewoJCQkJCWlmIChuLm5vZGVOYW1lID09PSAnU1BBTicpIHsKCQkJCQkJaWYgKCFjbCAmJiBuLmNsYXNzTmFtZSkKCQkJCQkJCWNsID0gbi5jbGFzc05hbWU7CgoJCQkJCQlpZiAoIWZ6ICYmIG4uc3R5bGUuZm9udFNpemUpCgkJCQkJCQlmeiA9IG4uc3R5bGUuZm9udFNpemU7CgoJCQkJCQlpZiAoIWZuICYmIG4uc3R5bGUuZm9udEZhbWlseSkKCQkJCQkJCWZuID0gbi5zdHlsZS5mb250RmFtaWx5LnJlcGxhY2UoL1tcIlwnXSsvZywgJycpLnJlcGxhY2UoL14oW14sXSspLiovLCAnJDEnKS50b0xvd2VyQ2FzZSgpOwoJCQkJCX0KCgkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfSk7CgoJCQkJaWYgKGMgPSBjbS5nZXQoJ2ZvbnRzZWxlY3QnKSkgewoJCQkJCWMuc2VsZWN0KGZ1bmN0aW9uKHYpIHsKCQkJCQkJcmV0dXJuIHYucmVwbGFjZSgvXihbXixdKykuKi8sICckMScpLnRvTG93ZXJDYXNlKCkgPT0gZm47CgkJCQkJfSk7CgkJCQl9CgoJCQkJaWYgKGMgPSBjbS5nZXQoJ2ZvbnRzaXplc2VsZWN0JykpIHsKCQkJCQljLnNlbGVjdChmdW5jdGlvbih2KSB7CgkJCQkJCWlmICh2LmZvbnRTaXplICYmIHYuZm9udFNpemUgPT09IGZ6KQoJCQkJCQkJcmV0dXJuIHRydWU7CgoJCQkJCQlpZiAodlsnY2xhc3MnXSAmJiB2WydjbGFzcyddID09PSBjbCkKCQkJCQkJCXJldHVybiB0cnVlOwoJCQkJCX0pOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJaWYgKGMgPSBjbS5nZXQoJ2ZvbnRzZWxlY3QnKSkKCQkJCQljLnNlbGVjdChlZC5xdWVyeUNvbW1hbmRWYWx1ZSgnRm9udE5hbWUnKSk7CgoJCQkJaWYgKGMgPSBjbS5nZXQoJ2ZvbnRzaXplc2VsZWN0JykpIHsKCQkJCQl2ID0gZWQucXVlcnlDb21tYW5kVmFsdWUoJ0ZvbnRTaXplJyk7CgkJCQkJYy5zZWxlY3QoZnVuY3Rpb24oaXYpIHsKCQkJCQkJcmV0dXJuIGl2LmZvbnRTaXplID09IHY7CgkJCQkJfSk7CgkJCQl9CgkJCX0KCgkJCWlmIChzLnRoZW1lX2FkdmFuY2VkX3BhdGggJiYgcy50aGVtZV9hZHZhbmNlZF9zdGF0dXNiYXJfbG9jYXRpb24pIHsKCQkJCXAgPSBET00uZ2V0KGVkLmlkICsgJ19wYXRoJykgfHwgRE9NLmFkZChlZC5pZCArICdfcGF0aF9yb3cnLCAnc3BhbicsIHtpZCA6IGVkLmlkICsgJ19wYXRoJ30pOwoJCQkJRE9NLnNldEhUTUwocCwgJycpOwoKCQkJCWVkLmRvbS5nZXRQYXJlbnQobiwgZnVuY3Rpb24obikgewoJCQkJCXZhciBuYSA9IG4ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSwgdSwgcGksIHRpID0gJyc7CgoJCQkJCS8vIElnbm9yZSBub24gZWxlbWVudCBhbmQgaGlkZGVuIGVsZW1lbnRzCgkJCQkJaWYgKG4ubm9kZVR5cGUgIT0gMSB8fCBuLm5vZGVOYW1lID09PSAnQlInIHx8IChET00uaGFzQ2xhc3MobiwgJ21jZUl0ZW1IaWRkZW4nKSB8fCBET00uaGFzQ2xhc3MobiwgJ21jZUl0ZW1SZW1vdmVkJykpKQoJCQkJCQlyZXR1cm47CgoJCQkJCS8vIEZha2UgbmFtZQoJCQkJCWlmICh2ID0gRE9NLmdldEF0dHJpYihuLCAnbWNlX25hbWUnKSkKCQkJCQkJbmEgPSB2OwoKCQkJCQkvLyBIYW5kbGUgcHJlZml4CgkJCQkJaWYgKHRpbnltY2UuaXNJRSAmJiBuLnNjb3BlTmFtZSAhPT0gJ0hUTUwnKQoJCQkJCQluYSA9IG4uc2NvcGVOYW1lICsgJzonICsgbmE7CgoJCQkJCS8vIFJlbW92ZSBpbnRlcm5hbCBwcmVmaXgKCQkJCQluYSA9IG5hLnJlcGxhY2UoL21jZVw6L2csICcnKTsKCgkJCQkJLy8gSGFuZGxlIG5vZGUgbmFtZQoJCQkJCXN3aXRjaCAobmEpIHsKCQkJCQkJY2FzZSAnYic6CgkJCQkJCQluYSA9ICdzdHJvbmcnOwoJCQkJCQkJYnJlYWs7CgoJCQkJCQljYXNlICdpJzoKCQkJCQkJCW5hID0gJ2VtJzsKCQkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSAnaW1nJzoKCQkJCQkJCWlmICh2ID0gRE9NLmdldEF0dHJpYihuLCAnc3JjJykpCgkJCQkJCQkJdGkgKz0gJ3NyYzogJyArIHYgKyAnICc7CgoJCQkJCQkJYnJlYWs7CgoJCQkJCQljYXNlICdhJzoKCQkJCQkJCWlmICh2ID0gRE9NLmdldEF0dHJpYihuLCAnbmFtZScpKSB7CgkJCQkJCQkJdGkgKz0gJ25hbWU6ICcgKyB2ICsgJyAnOwoJCQkJCQkJCW5hICs9ICcjJyArIHY7CgkJCQkJCQl9CgoJCQkJCQkJaWYgKHYgPSBET00uZ2V0QXR0cmliKG4sICdocmVmJykpCgkJCQkJCQkJdGkgKz0gJ2hyZWY6ICcgKyB2ICsgJyAnOwoKCQkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSAnZm9udCc6CgkJCQkJCQlpZiAocy5jb252ZXJ0X2ZvbnRzX3RvX3NwYW5zKQoJCQkJCQkJCW5hID0gJ3NwYW4nOwoKCQkJCQkJCWlmICh2ID0gRE9NLmdldEF0dHJpYihuLCAnZmFjZScpKQoJCQkJCQkJCXRpICs9ICdmb250OiAnICsgdiArICcgJzsKCgkJCQkJCQlpZiAodiA9IERPTS5nZXRBdHRyaWIobiwgJ3NpemUnKSkKCQkJCQkJCQl0aSArPSAnc2l6ZTogJyArIHYgKyAnICc7CgoJCQkJCQkJaWYgKHYgPSBET00uZ2V0QXR0cmliKG4sICdjb2xvcicpKQoJCQkJCQkJCXRpICs9ICdjb2xvcjogJyArIHYgKyAnICc7CgoJCQkJCQkJYnJlYWs7CgoJCQkJCQljYXNlICdzcGFuJzoKCQkJCQkJCWlmICh2ID0gRE9NLmdldEF0dHJpYihuLCAnc3R5bGUnKSkKCQkJCQkJCQl0aSArPSAnc3R5bGU6ICcgKyB2ICsgJyAnOwoKCQkJCQkJCWJyZWFrOwoJCQkJCX0KCgkJCQkJaWYgKHYgPSBET00uZ2V0QXR0cmliKG4sICdpZCcpKQoJCQkJCQl0aSArPSAnaWQ6ICcgKyB2ICsgJyAnOwoKCQkJCQlpZiAodiA9IG4uY2xhc3NOYW1lKSB7CgkJCQkJCXYgPSB2LnJlcGxhY2UoLyh3ZWJraXQtW1x3XC1dK3xBcHBsZS1bXHdcLV0rfG1jZUl0ZW1cdyt8bWNlVmlzdWFsQWlkKS9nLCAnJyk7CgoJCQkJCQlpZiAodiAmJiB2LmluZGV4T2YoJ21jZUl0ZW0nKSA9PSAtMSkgewoJCQkJCQkJdGkgKz0gJ2NsYXNzOiAnICsgdiArICcgJzsKCgkJCQkJCQlpZiAoRE9NLmlzQmxvY2sobikgfHwgbmEgPT0gJ2ltZycgfHwgbmEgPT0gJ3NwYW4nKQoJCQkJCQkJCW5hICs9ICcuJyArIHY7CgkJCQkJCX0KCQkJCQl9CgoJCQkJCW5hID0gbmEucmVwbGFjZSgvKGh0bWw6KS9nLCAnJyk7CgkJCQkJbmEgPSB7bmFtZSA6IG5hLCBub2RlIDogbiwgdGl0bGUgOiB0aX07CgkJCQkJdC5vblJlc29sdmVOYW1lLmRpc3BhdGNoKHQsIG5hKTsKCQkJCQl0aSA9IG5hLnRpdGxlOwoJCQkJCW5hID0gbmEubmFtZTsKCgkJCQkJLy91ID0gImphdmFzY3JpcHQ6dGlueW1jZS5FZGl0b3JNYW5hZ2VyLmdldCgnIiArIGVkLmlkICsgIicpLnRoZW1lLl9zZWwoJyIgKyAoZGUrKykgKyAiJyk7IjsKCQkJCQlwaSA9IERPTS5jcmVhdGUoJ2EnLCB7J2hyZWYnIDogImphdmFzY3JpcHQ6OyIsIG9ubW91c2Vkb3duIDogInJldHVybiBmYWxzZTsiLCB0aXRsZSA6IHRpLCAnY2xhc3MnIDogJ21jZVBhdGhfJyArIChkZSsrKX0sIG5hKTsKCgkJCQkJaWYgKHAuaGFzQ2hpbGROb2RlcygpKSB7CgkJCQkJCXAuaW5zZXJ0QmVmb3JlKERPTS5kb2MuY3JlYXRlVGV4dE5vZGUoJyBcdTAwYmIgJyksIHAuZmlyc3RDaGlsZCk7CgkJCQkJCXAuaW5zZXJ0QmVmb3JlKHBpLCBwLmZpcnN0Q2hpbGQpOwoJCQkJCX0gZWxzZQoJCQkJCQlwLmFwcGVuZENoaWxkKHBpKTsKCQkJCX0sIGVkLmdldEJvZHkoKSk7CgkJCX0KCQl9LAoKCQkvLyBDb21tYW5kcyBnZXRzIGNhbGxlZCBieSBleGVjQ29tbWFuZAoKCQlfc2VsIDogZnVuY3Rpb24odikgewoJCQl0aGlzLmVkaXRvci5leGVjQ29tbWFuZCgnbWNlU2VsZWN0Tm9kZURlcHRoJywgZmFsc2UsIHYpOwoJCX0sCgoJCV9tY2VJbnNlcnRBbmNob3IgOiBmdW5jdGlvbih1aSwgdikgewoJCQl2YXIgZWQgPSB0aGlzLmVkaXRvcjsKCgkJCWVkLndpbmRvd01hbmFnZXIub3Blbih7CgkJCQl1cmwgOiB0aW55bWNlLmJhc2VVUkwgKyAnL3RoZW1lcy9hZHZhbmNlZC9hbmNob3IuaHRtJywKCQkJCXdpZHRoIDogMzIwICsgcGFyc2VJbnQoZWQuZ2V0TGFuZygnYWR2YW5jZWQuYW5jaG9yX2RlbHRhX3dpZHRoJywgMCkpLAoJCQkJaGVpZ2h0IDogOTAgKyBwYXJzZUludChlZC5nZXRMYW5nKCdhZHZhbmNlZC5hbmNob3JfZGVsdGFfaGVpZ2h0JywgMCkpLAoJCQkJaW5saW5lIDogdHJ1ZQoJCQl9LCB7CgkJCQl0aGVtZV91cmwgOiB0aGlzLnVybAoJCQl9KTsKCQl9LAoKCQlfbWNlQ2hhck1hcCA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgZWQgPSB0aGlzLmVkaXRvcjsKCgkJCWVkLndpbmRvd01hbmFnZXIub3Blbih7CgkJCQl1cmwgOiB0aW55TUNFLnNldHRpbmdzLnBsdWdpbl9hY3Rpb25fYmFzZV9wYXRoICsgJy9jaGFybWFwLmFjdGlvbicsCgkJCQl3aWR0aCA6IDY1MCArIHBhcnNlSW50KGVkLmdldExhbmcoJ2FkdmFuY2VkLmNoYXJtYXBfZGVsdGFfd2lkdGgnLCAwKSksCgkJCQloZWlnaHQgOiAzNTAgKyBwYXJzZUludChlZC5nZXRMYW5nKCdhZHZhbmNlZC5jaGFybWFwX2RlbHRhX2hlaWdodCcsIDApKSwKCQkJCWlubGluZSA6IHRydWUsCiAgICAgICAgICAgICAgICBuYW1lOiAiY2hhcm1hcF9pbnNlcnRlciIKICAgICAgICAgICAgfSwgewoJCQkJdGhlbWVfdXJsIDogdGhpcy51cmwKCQkJfSk7CgkJfSwKCgkJX21jZUhlbHAgOiBmdW5jdGlvbigpIHsKCQkJdmFyIGVkID0gdGhpcy5lZGl0b3I7CgoJCQllZC53aW5kb3dNYW5hZ2VyLm9wZW4oewoJCQkJdXJsIDogdGlueW1jZS5iYXNlVVJMICsgJy90aGVtZXMvYWR2YW5jZWQvYWJvdXQuaHRtJywKCQkJCXdpZHRoIDogNDgwLAoJCQkJaGVpZ2h0IDogMzgwLAoJCQkJaW5saW5lIDogdHJ1ZQoJCQl9LCB7CgkJCQl0aGVtZV91cmwgOiB0aGlzLnVybAoJCQl9KTsKCQl9LAoKCQlfbWNlQ29sb3JQaWNrZXIgOiBmdW5jdGlvbih1LCB2KSB7CgkJCXZhciBlZCA9IHRoaXMuZWRpdG9yOwoKCQkJdiA9IHYgfHwge307CgoJCQllZC53aW5kb3dNYW5hZ2VyLm9wZW4oewogICAgICAgICAgICAgICAgbmFtZTogImNvbG9yX3BpY2tlciIsCiAgICAgICAgICAgICAgICB1cmwgOiB0aW55TUNFLnNldHRpbmdzLnBsdWdpbl9hY3Rpb25fYmFzZV9wYXRoICsgJy9jb2xvcl9waWNrZXIuYWN0aW9uJywKCQkJCXdpZHRoIDogMzc1ICsgcGFyc2VJbnQoZWQuZ2V0TGFuZygnYWR2YW5jZWQuY29sb3JwaWNrZXJfZGVsdGFfd2lkdGgnLCAwKSksCgkJCQloZWlnaHQgOiAyODAgKyBwYXJzZUludChlZC5nZXRMYW5nKCdhZHZhbmNlZC5jb2xvcnBpY2tlcl9kZWx0YV9oZWlnaHQnLCAwKSksCgkJCQljbG9zZV9wcmV2aW91cyA6IGZhbHNlLAoJCQkJaW5saW5lIDogdHJ1ZQoJCQl9LCB7CgkJCQlpbnB1dF9jb2xvciA6IHYuY29sb3IsCgkJCQlmdW5jIDogdi5mdW5jLAoJCQkJdGhlbWVfdXJsIDogdGhpcy51cmwKCQkJfSk7CgkJfSwKCgkJX21jZUNvZGVFZGl0b3IgOiBmdW5jdGlvbih1aSwgdmFsKSB7CgkJCXZhciBlZCA9IHRoaXMuZWRpdG9yOwoKCQkJZWQud2luZG93TWFuYWdlci5vcGVuKHsKCQkJCXVybCA6IHRpbnltY2UuYmFzZVVSTCArICcvdGhlbWVzL2FkdmFuY2VkL3NvdXJjZV9lZGl0b3IuaHRtJywKCQkJCXdpZHRoIDogcGFyc2VJbnQoZWQuZ2V0UGFyYW0oInRoZW1lX2FkdmFuY2VkX3NvdXJjZV9lZGl0b3Jfd2lkdGgiLCA3MjApKSwKCQkJCWhlaWdodCA6IHBhcnNlSW50KGVkLmdldFBhcmFtKCJ0aGVtZV9hZHZhbmNlZF9zb3VyY2VfZWRpdG9yX2hlaWdodCIsIDU4MCkpLAoJCQkJaW5saW5lIDogdHJ1ZSwKCQkJCXJlc2l6YWJsZSA6IHRydWUsCgkJCQltYXhpbWl6YWJsZSA6IHRydWUKCQkJfSwgewoJCQkJdGhlbWVfdXJsIDogdGhpcy51cmwKCQkJfSk7CgkJfSwKCgkJX21jZUltYWdlIDogZnVuY3Rpb24odWksIHZhbCkgewoJCQl2YXIgZWQgPSB0aGlzLmVkaXRvcjsKCgkJCS8vIEludGVybmFsIGltYWdlIG9iamVjdCBsaWtlIGEgZmxhc2ggcGxhY2Vob2xkZXIKCQkJaWYgKGVkLmRvbS5nZXRBdHRyaWIoZWQuc2VsZWN0aW9uLmdldE5vZGUoKSwgJ2NsYXNzJykuaW5kZXhPZignbWNlSXRlbScpICE9IC0xKQoJCQkJcmV0dXJuOwoKCQkJZWQud2luZG93TWFuYWdlci5vcGVuKHsKCQkJCXVybCA6IHRpbnltY2UuYmFzZVVSTCArICcvdGhlbWVzL2FkdmFuY2VkL2ltYWdlLmh0bScsCgkJCQl3aWR0aCA6IDM1NSArIHBhcnNlSW50KGVkLmdldExhbmcoJ2FkdmFuY2VkLmltYWdlX2RlbHRhX3dpZHRoJywgMCkpLAoJCQkJaGVpZ2h0IDogMjc1ICsgcGFyc2VJbnQoZWQuZ2V0TGFuZygnYWR2YW5jZWQuaW1hZ2VfZGVsdGFfaGVpZ2h0JywgMCkpLAoJCQkJaW5saW5lIDogdHJ1ZQoJCQl9LCB7CgkJCQl0aGVtZV91cmwgOiB0aGlzLnVybAoJCQl9KTsKCQl9LAoKCQlfbWNlTGluayA6IGZ1bmN0aW9uKHVpLCB2YWwpIHsKCQkJdmFyIGVkID0gdGhpcy5lZGl0b3I7CgoJCQllZC53aW5kb3dNYW5hZ2VyLm9wZW4oewoJCQkJdXJsIDogdGlueW1jZS5iYXNlVVJMICsgJy90aGVtZXMvYWR2YW5jZWQvbGluay5odG0nLAoJCQkJd2lkdGggOiAzMTAgKyBwYXJzZUludChlZC5nZXRMYW5nKCdhZHZhbmNlZC5saW5rX2RlbHRhX3dpZHRoJywgMCkpLAoJCQkJaGVpZ2h0IDogMjAwICsgcGFyc2VJbnQoZWQuZ2V0TGFuZygnYWR2YW5jZWQubGlua19kZWx0YV9oZWlnaHQnLCAwKSksCgkJCQlpbmxpbmUgOiB0cnVlCgkJCX0sIHsKCQkJCXRoZW1lX3VybCA6IHRoaXMudXJsCgkJCX0pOwoJCX0sCgoJCV9tY2VOZXdEb2N1bWVudCA6IGZ1bmN0aW9uKCkgewoJCQl2YXIgZWQgPSB0aGlzLmVkaXRvcjsKCgkJCWVkLndpbmRvd01hbmFnZXIuY29uZmlybSgnYWR2YW5jZWQubmV3ZG9jdW1lbnQnLCBmdW5jdGlvbihzKSB7CgkJCQlpZiAocykKCQkJCQllZC5leGVjQ29tbWFuZCgnbWNlU2V0Q29udGVudCcsIGZhbHNlLCAnJyk7CgkJCX0pOwoJCX0sCgoJCV9tY2VGb3JlQ29sb3IgOiBmdW5jdGlvbigpIHsKCQkJdmFyIHQgPSB0aGlzOwoKCQkJdGhpcy5fbWNlQ29sb3JQaWNrZXIoMCwgewoJCQkJY29sb3I6IHQuZmdDb2xvciwKCQkJCWZ1bmMgOiBmdW5jdGlvbihjbykgewoJCQkJCXQuZmdDb2xvciA9IGNvOwoJCQkJCXQuZWRpdG9yLmV4ZWNDb21tYW5kKCdGb3JlQ29sb3InLCBmYWxzZSwgY28pOwoJCQkJfQoJCQl9KTsKCQl9LAoKCQlfbWNlQmFja0NvbG9yIDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpczsKCgkJCXRoaXMuX21jZUNvbG9yUGlja2VyKDAsIHsKCQkJCWNvbG9yOiB0LmJnQ29sb3IsCgkJCQlmdW5jIDogZnVuY3Rpb24oY28pIHsKCQkJCQl0LmJnQ29sb3IgPSBjbzsKCQkJCQl0LmVkaXRvci5leGVjQ29tbWFuZCgnSGlsaXRlQ29sb3InLCBmYWxzZSwgY28pOwoJCQkJfQoJCQl9KTsKCQl9LAoKCQlfdWZpcnN0IDogZnVuY3Rpb24ocykgewoJCQlyZXR1cm4gcy5zdWJzdHJpbmcoMCwgMSkudG9VcHBlckNhc2UoKSArIHMuc3Vic3RyaW5nKDEpOwoJCX0KCX0pOwoKCXRpbnltY2UuVGhlbWVNYW5hZ2VyLmFkZCgnYWR2YW5jZWQnLCB0aW55bWNlLnRoZW1lcy5BZHZhbmNlZFRoZW1lKTsKfSh0aW55bWNlKSk7Ci8qKgogKiAkSWQ6IGVkaXRvcl9wbHVnaW5fc3JjLmpzIDk1MyAyMDA4LTExLTA0IDEwOjE2OjUwWiBzcG9ja2UgJAogKgogKiBAYXV0aG9yIE1veGllY29kZQogKiBAY29weXJpZ2h0IENvcHlyaWdodCCpIDIwMDQtMjAwOCwgTW94aWVjb2RlIFN5c3RlbXMgQUIsIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqLwoKKGZ1bmN0aW9uKCkgewoJdmFyIGVhY2ggPSB0aW55bWNlLmVhY2g7CgoJdGlueW1jZS5jcmVhdGUoJ3RpbnltY2UucGx1Z2lucy5UYWJsZVBsdWdpbicsIHsKCQlpbml0IDogZnVuY3Rpb24oZWQsIHVybCkgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQl0LmVkaXRvciA9IGVkOwoJCQl0LnVybCA9IHVybDsKCgkJCS8vIFJlZ2lzdGVyIGJ1dHRvbnMKCQkJZWFjaChbCgkJCQlbJ3RhYmxlJywgJ2h0dHA6Ly8xMC4yMC4xNjAuMTk4L3dpa2kvcy9lbi8yMTY2LzM0LzMuNS45L18vZG93bmxvYWQvYmF0Y2gvY29tLmF0bGFzc2lhbi5jb25mbHVlbmNlLnRpbnltY2VwbHVnaW46ZWRpdG9yLXJlc291cmNlcy90YWJsZS5kZXNjJywgJ21jZUluc2VydFRhYmxlJywgdHJ1ZV0sCgkJCQlbJ2RlbGV0ZV90YWJsZScsICdodHRwOi8vMTAuMjAuMTYwLjE5OC93aWtpL3MvZW4vMjE2Ni8zNC8zLjUuOS9fL2Rvd25sb2FkL2JhdGNoL2NvbS5hdGxhc3NpYW4uY29uZmx1ZW5jZS50aW55bWNlcGx1Z2luOmVkaXRvci1yZXNvdXJjZXMvdGFibGUuZGVsJywgJ21jZVRhYmxlRGVsZXRlJ10sCgkJCQlbJ2RlbGV0ZV9jb2wnLCAndGFibGUuZGVsZXRlX2NvbF9kZXNjJywgJ21jZVRhYmxlRGVsZXRlQ29sJ10sCgkJCQlbJ2RlbGV0ZV9yb3cnLCAndGFibGUuZGVsZXRlX3Jvd19kZXNjJywgJ21jZVRhYmxlRGVsZXRlUm93J10sCgkJCQlbJ2NvbF9hZnRlcicsICd0YWJsZS5jb2xfYWZ0ZXJfZGVzYycsICdtY2VUYWJsZUluc2VydENvbEFmdGVyJ10sCgkJCQlbJ2NvbF9iZWZvcmUnLCAndGFibGUuY29sX2JlZm9yZV9kZXNjJywgJ21jZVRhYmxlSW5zZXJ0Q29sQmVmb3JlJ10sCgkJCQlbJ3Jvd19hZnRlcicsICd0YWJsZS5yb3dfYWZ0ZXJfZGVzYycsICdtY2VUYWJsZUluc2VydFJvd0FmdGVyJ10sCgkJCQlbJ3Jvd19iZWZvcmUnLCAndGFibGUucm93X2JlZm9yZV9kZXNjJywgJ21jZVRhYmxlSW5zZXJ0Um93QmVmb3JlJ10sCgkJCQlbJ3Jvd19wcm9wcycsICd0YWJsZS5yb3dfZGVzYycsICdtY2VUYWJsZVJvd1Byb3BzJywgdHJ1ZV0sCgkJCQlbJ2NlbGxfcHJvcHMnLCAndGFibGUuY2VsbF9kZXNjJywgJ21jZVRhYmxlQ2VsbFByb3BzJywgdHJ1ZV0sCgkJCQlbJ3NwbGl0X2NlbGxzJywgJ3RhYmxlLnNwbGl0X2NlbGxzX2Rlc2MnLCAnbWNlVGFibGVTcGxpdENlbGxzJywgdHJ1ZV0sCgkJCQlbJ21lcmdlX2NlbGxzJywgJ3RhYmxlLm1lcmdlX2NlbGxzX2Rlc2MnLCAnbWNlVGFibGVNZXJnZUNlbGxzJywgdHJ1ZV0KCQkJXSwgZnVuY3Rpb24oYykgewoJCQkJZWQuYWRkQnV0dG9uKGNbMF0sIHt0aXRsZSA6IGNbMV0sIGNtZCA6IGNbMl0sIHVpIDogY1szXX0pOwoJCQl9KTsKCgkJCWlmIChlZC5nZXRQYXJhbSgnaW5saW5lX3N0eWxlcycpKSB7CgkJCQkvLyBGb3JjZSBtb3ZlIG9mIGF0dHJpYnMgdG8gc3R5bGVzIGluIHN0cmljdCBtb2RlCgkJCQllZC5vblByZVByb2Nlc3MuYWRkKGZ1bmN0aW9uKGVkLCBvKSB7CgkJCQkJdmFyIGRvbSA9IGVkLmRvbTsKCgkJCQkJZWFjaChkb20uc2VsZWN0KCd0YWJsZScsIG8ubm9kZSksIGZ1bmN0aW9uKG4pIHsKCQkJCQkJdmFyIHY7CgoJCQkJCQlpZiAodiA9IGRvbS5nZXRBdHRyaWIobiwgJ3dpZHRoJykpIHsKCQkJCQkJCWRvbS5zZXRTdHlsZShuLCAnd2lkdGgnLCB2KTsKCQkJCQkJCWRvbS5zZXRBdHRyaWIobiwgJ3dpZHRoJyk7CgkJCQkJCX0KCgkJCQkJCWlmICh2ID0gZG9tLmdldEF0dHJpYihuLCAnaGVpZ2h0JykpIHsKCQkJCQkJCWRvbS5zZXRTdHlsZShuLCAnaGVpZ2h0Jywgdik7CgkJCQkJCQlkb20uc2V0QXR0cmliKG4sICdoZWlnaHQnKTsKCQkJCQkJfQoJCQkJCX0pOwoJCQkJfSk7CgkJCX0KCgkJCWVkLm9uSW5pdC5hZGQoZnVuY3Rpb24oKSB7CgkJCQlpZiAoZWQgJiYgZWQucGx1Z2lucy5jb250ZXh0bWVudSkgewoJCQkJCWVkLnBsdWdpbnMuY29udGV4dG1lbnUub25Db250ZXh0TWVudS5hZGQoZnVuY3Rpb24odGgsIG0sIGUpIHsKCQkJCQkJdmFyIHNtLCBzZSA9IGVkLnNlbGVjdGlvbiwgZWwgPSBzZS5nZXROb2RlKCkgfHwgZWQuZ2V0Qm9keSgpOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVkLmRvbS5nZXRQYXJlbnQoZSwgJ3RkJykgfHwgZWQuZG9tLmdldFBhcmVudChlLCAndGgnKSB8fCBlZC5kb20uZ2V0UGFyZW50KGUsICd0YWJsZScpKSB7CgkJCQkJCQkvL0FUTEFTU0lBTiAtIHdlIHdhbnQgaW5zZXJ0IGxpbmssIGltYWdlIG1lbnVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL20ucmVtb3ZlQWxsKCk7CgoJCQkJCQkJbS5hZGQoe3RpdGxlIDogJ2h0dHA6Ly8xMC4yMC4xNjAuMTk4L3dpa2kvcy9lbi8yMTY2LzM0LzMuNS45L18vZG93bmxvYWQvYmF0Y2gvY29tLmF0bGFzc2lhbi5jb25mbHVlbmNlLnRpbnltY2VwbHVnaW46ZWRpdG9yLXJlc291cmNlcy90YWJsZS5kZWwnLCBpY29uIDogJ2RlbGV0ZV90YWJsZScsIGNtZCA6ICdtY2VUYWJsZURlbGV0ZScsIHVpIDogdHJ1ZX0pOwoJCQkJCQkJbS5hZGRTZXBhcmF0b3IoKTsKCgkJCQkJCQkvLyBSb3cgbWVudQoJCQkJCQkJc20gPSBtLmFkZE1lbnUoe3RpdGxlIDogJ2h0dHA6Ly8xMC4yMC4xNjAuMTk4L3dpa2kvcy9lbi8yMTY2LzM0LzMuNS45L18vZG93bmxvYWQvYmF0Y2gvY29tLmF0bGFzc2lhbi5jb25mbHVlbmNlLnRpbnltY2VwbHVnaW46ZWRpdG9yLXJlc291cmNlcy90YWJsZS5yb3cnfSk7CgkJCQkJCQlzbS5hZGQoe3RpdGxlIDogJ3RhYmxlLnJvd19iZWZvcmVfZGVzYycsIGljb24gOiAncm93X2JlZm9yZScsIGNtZCA6ICdtY2VUYWJsZUluc2VydFJvd0JlZm9yZSd9KTsKCQkJCQkJCXNtLmFkZCh7dGl0bGUgOiAndGFibGUucm93X2FmdGVyX2Rlc2MnLCBpY29uIDogJ3Jvd19hZnRlcicsIGNtZCA6ICdtY2VUYWJsZUluc2VydFJvd0FmdGVyJ30pOwoJCQkJCQkJc20uYWRkKHt0aXRsZSA6ICd0YWJsZS5kZWxldGVfcm93X2Rlc2MnLCBpY29uIDogJ2RlbGV0ZV9yb3cnLCBjbWQgOiAnbWNlVGFibGVEZWxldGVSb3cnfSk7CgkJCQkJCQlzbS5hZGQoe3RpdGxlIDogJ3RhYmxlLmhlYWRpbmdfcm93JywgaWNvbiA6ICdyb3dfcHJvcHMnLCBjbWQgOiAnbWNlVGFibGVIZWFkaW5nUm93J30pOwoJCQkJCQkJc20uYWRkU2VwYXJhdG9yKCk7CgkJCQkJCQlzbS5hZGQoe3RpdGxlIDogJ3RhYmxlLmN1dF9yb3dfZGVzYycsIGljb24gOiAnY3V0JywgY21kIDogJ21jZVRhYmxlQ3V0Um93J30pOwoJCQkJCQkJc20uYWRkKHt0aXRsZSA6ICd0YWJsZS5jb3B5X3Jvd19kZXNjJywgaWNvbiA6ICdjb3B5JywgY21kIDogJ21jZVRhYmxlQ29weVJvdyd9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGVkLnRhYmxlUm93Q2xpcGJvYXJkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc20uYWRkKHt0aXRsZSA6ICd0YWJsZS5wYXN0ZV9yb3dfYmVmb3JlX2Rlc2MnLCBpY29uIDogJ3Bhc3RlJywgY21kIDogJ21jZVRhYmxlUGFzdGVSb3dCZWZvcmUnfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc20uYWRkKHt0aXRsZSA6ICd0YWJsZS5wYXN0ZV9yb3dfYWZ0ZXJfZGVzYycsIGljb24gOiAncGFzdGUnLCBjbWQgOiAnbWNlVGFibGVQYXN0ZVJvd0FmdGVyJ30pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoJCQkJCQkJLy8gQ29sdW1uIG1lbnUKCQkJCQkJCXNtID0gbS5hZGRNZW51KHt0aXRsZSA6ICdodHRwOi8vMTAuMjAuMTYwLjE5OC93aWtpL3MvZW4vMjE2Ni8zNC8zLjUuOS9fL2Rvd25sb2FkL2JhdGNoL2NvbS5hdGxhc3NpYW4uY29uZmx1ZW5jZS50aW55bWNlcGx1Z2luOmVkaXRvci1yZXNvdXJjZXMvdGFibGUuY29sJ30pOwoJCQkJCQkJc20uYWRkKHt0aXRsZSA6ICd0YWJsZS5jb2xfYmVmb3JlX2Rlc2MnLCBpY29uIDogJ2NvbF9iZWZvcmUnLCBjbWQgOiAnbWNlVGFibGVJbnNlcnRDb2xCZWZvcmUnfSk7CgkJCQkJCQlzbS5hZGQoe3RpdGxlIDogJ3RhYmxlLmNvbF9hZnRlcl9kZXNjJywgaWNvbiA6ICdjb2xfYWZ0ZXInLCBjbWQgOiAnbWNlVGFibGVJbnNlcnRDb2xBZnRlcid9KTsKCQkJCQkJCXNtLmFkZCh7dGl0bGUgOiAndGFibGUuZGVsZXRlX2NvbF9kZXNjJywgaWNvbiA6ICdkZWxldGVfY29sJywgY21kIDogJ21jZVRhYmxlRGVsZXRlQ29sJ30pOwoJCQkJCQl9IGVsc2UgewoJCQkJCQkJbS5hZGQoe3RpdGxlIDogJ2h0dHA6Ly8xMC4yMC4xNjAuMTk4L3dpa2kvcy9lbi8yMTY2LzM0LzMuNS45L18vZG93bmxvYWQvYmF0Y2gvY29tLmF0bGFzc2lhbi5jb25mbHVlbmNlLnRpbnltY2VwbHVnaW46ZWRpdG9yLXJlc291cmNlcy90YWJsZS5kZXNjJywgaWNvbiA6ICd0YWJsZScsIGNtZCA6ICdtY2VJbnNlcnRUYWJsZScsIHVpIDogdHJ1ZX0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIG0uYWRkU2VwYXJhdG9yKCk7CiAgICAgICAgICAgICAgICAgICAgfSk7CgkJCQl9CgkJCX0pOwoKICAgICAgICAgICAgLy8gQVRMQVNTSUFOIC0gdGFiIGhhbmRsaW5nIGRvbmUgaW4gdGlueU1jZUFkYXB0ZXIuanMKCQkJLy8gQWRkIHVuZG8gbGV2ZWwgd2hlbiBuZXcgcm93cyBhcmUgY3JlYXRlZCB1c2luZyB0aGUgdGFiIGtleQovLwkJCWVkLm9uS2V5RG93bi5hZGQoZnVuY3Rpb24oZWQsIGUpIHsKLy8JCQkJaWYgKGUua2V5Q29kZSA9PSA5ICYmIGVkLmRvbS5nZXRQYXJlbnQoZWQuc2VsZWN0aW9uLmdldE5vZGUoKSwgJ1RBQkxFJykpIHsKLy8JCQkJCWlmICghdGlueW1jZS5pc0dlY2tvICYmICF0aW55bWNlLmlzT3BlcmEpIHsKLy8JCQkJCQl0aW55TUNFLmV4ZWNJbnN0YW5jZUNvbW1hbmQoZWQuZWRpdG9ySWQsICJtY2VUYWJsZU1vdmVUb05leHRSb3ciLCB0cnVlKTsKLy8JCQkJCQlyZXR1cm4gdGlueW1jZS5kb20uRXZlbnQuY2FuY2VsKGUpOwovLwkJCQkJfQovLwovLwkJCQkJZWQudW5kb01hbmFnZXIuYWRkKCk7Ci8vCQkJCX0KLy8JCQl9KTsKCgkJCS8vIFNlbGVjdCB3aG9sZSB0YWJsZSBpcyBhIHRhYmxlIGJvcmRlciBpcyBjbGlja2VkCgkJCWlmICghdGlueW1jZS5pc0lFKSB7CgkJCQlpZiAoZWQuZ2V0UGFyYW0oJ3RhYmxlX3NlbGVjdGlvbicsIHRydWUpKSB7CgkJCQkJZWQub25DbGljay5hZGQoZnVuY3Rpb24oZWQsIGUpIHsKCQkJCQkJZSA9IGUudGFyZ2V0OwoKCQkJCQkJaWYgKGUubm9kZU5hbWUgPT09ICdUQUJMRScpCgkJCQkJCQllZC5zZWxlY3Rpb24uc2VsZWN0KGUpOwoJCQkJCX0pOwoJCQkJfQoJCQl9CgoJCQllZC5vbk5vZGVDaGFuZ2UuYWRkKGZ1bmN0aW9uKGVkLCBjbSwgbikgewoJCQkJdmFyIHAgPSBlZC5kb20uZ2V0UGFyZW50KG4sICd0ZCx0aCxjYXB0aW9uJyk7CgogICAgICAgICAgICAgICAgLy8gQVRMQVNTSUFOIC0gd2UgY2FuJ3QgYWRkIHRhYmxlcyBpbnNpZGUgdGFibGVzLCBzbyBkaXNhYmxlCiAgICAgICAgICAgICAgICBjbS5zZXREaXNhYmxlZCgndGFibGUnLCBuLm5vZGVOYW1lID09PSAnVEFCTEUnIHx8ICEhcCk7CgkJCQlpZiAocCAmJiBwLm5vZGVOYW1lID09PSAnQ0FQVElPTicpCgkJCQkJcCA9IG51bGw7CgoJCQkJY20uc2V0RGlzYWJsZWQoJ2RlbGV0ZV90YWJsZScsICFwKTsKCQkJCWNtLnNldERpc2FibGVkKCdkZWxldGVfY29sJywgIXApOwoJCQkJY20uc2V0RGlzYWJsZWQoJ2RlbGV0ZV90YWJsZScsICFwKTsKCQkJCWNtLnNldERpc2FibGVkKCdkZWxldGVfcm93JywgIXApOwoJCQkJY20uc2V0RGlzYWJsZWQoJ2NvbF9hZnRlcicsICFwKTsKCQkJCWNtLnNldERpc2FibGVkKCdjb2xfYmVmb3JlJywgIXApOwoJCQkJY20uc2V0RGlzYWJsZWQoJ3Jvd19hZnRlcicsICFwKTsKCQkJCWNtLnNldERpc2FibGVkKCdyb3dfYmVmb3JlJywgIXApOwoJCQkJY20uc2V0RGlzYWJsZWQoJ3Jvd19wcm9wcycsICFwKTsKCQkJCWNtLnNldERpc2FibGVkKCdjZWxsX3Byb3BzJywgIXApOwoJCQkJY20uc2V0RGlzYWJsZWQoJ3NwbGl0X2NlbGxzJywgIXAgfHwgKHBhcnNlSW50KGVkLmRvbS5nZXRBdHRyaWIocCwgJ2NvbHNwYW4nLCAnMScpKSA8IDIgJiYgcGFyc2VJbnQoZWQuZG9tLmdldEF0dHJpYihwLCAncm93c3BhbicsICcxJykpIDwgMikpOwoJCQkJY20uc2V0RGlzYWJsZWQoJ21lcmdlX2NlbGxzJywgIXApOwoJCQl9KTsKCgkJCS8vIFBhZGQgZW1wdHkgdGFibGUgY2VsbHMKCQkJaWYgKCF0aW55bWNlLmlzSUUpIHsKCQkJCWVkLm9uQmVmb3JlU2V0Q29udGVudC5hZGQoZnVuY3Rpb24oZWQsIG8pIHsKCQkJCQlpZiAoby5pbml0aWFsKQoJCQkJCQlvLmNvbnRlbnQgPSBvLmNvbnRlbnQucmVwbGFjZSgvPCh0ZHx0aCkoW14+XSt8KT5ccyo8XC8odGR8dGgpPi9nLCB0aW55bWNlLmlzT3BlcmEgPyAnPCQxJDI+Jm5ic3A7PC8kMT4nIDogJzwkMSQyPjxiciBtY2VfYm9ndXM9IjEiIC8+PC8kMT4nKTsKCQkJCX0pOwoJCQl9CgkJfSwKCgkJZXhlY0NvbW1hbmQgOiBmdW5jdGlvbihjbWQsIHVpLCB2YWwpIHsKCQkJdmFyIGVkID0gdGhpcy5lZGl0b3IsIGI7CgoJCQkvLyBJcyB0YWJsZSBjb21tYW5kCgkJCXN3aXRjaCAoY21kKSB7CiAgICAgICAgICAgICAgICBjYXNlICJtY2VUYWJsZU1vdmVUb1ByZXZSb3ciOgoJCQkJY2FzZSAibWNlVGFibGVNb3ZlVG9OZXh0Um93IjoKCQkJCWNhc2UgIm1jZUluc2VydFRhYmxlIjoKCQkJCWNhc2UgIm1jZVRhYmxlUm93UHJvcHMiOgoJCQkJY2FzZSAibWNlVGFibGVDZWxsUHJvcHMiOgoJCQkJY2FzZSAibWNlVGFibGVTcGxpdENlbGxzIjoKCQkJCWNhc2UgIm1jZVRhYmxlTWVyZ2VDZWxscyI6CgkJCQljYXNlICJtY2VUYWJsZUluc2VydFJvd0JlZm9yZSI6CgkJCQljYXNlICJtY2VUYWJsZUluc2VydFJvd0FmdGVyIjoKCQkJCWNhc2UgIm1jZVRhYmxlRGVsZXRlUm93IjoKCQkJCWNhc2UgIm1jZVRhYmxlSGVhZGluZ1JvdyI6CgkJCQljYXNlICJtY2VUYWJsZUluc2VydENvbEJlZm9yZSI6CgkJCQljYXNlICJtY2VUYWJsZUluc2VydENvbEFmdGVyIjoKCQkJCWNhc2UgIm1jZVRhYmxlRGVsZXRlQ29sIjoKCQkJCWNhc2UgIm1jZVRhYmxlQ3V0Um93IjoKCQkJCWNhc2UgIm1jZVRhYmxlQ29weVJvdyI6CgkJCQljYXNlICJtY2VUYWJsZVBhc3RlUm93QmVmb3JlIjoKCQkJCWNhc2UgIm1jZVRhYmxlUGFzdGVSb3dBZnRlciI6CgkJCQljYXNlICJtY2VUYWJsZURlbGV0ZSI6CgkJCQkJZWQuZXhlY0NvbW1hbmQoJ21jZUJlZ2luVW5kb0xldmVsJyk7CgkJCQkJdGhpcy5fZG9FeGVjQ29tbWFuZChjbWQsIHVpLCB2YWwpOwoJCQkJCWVkLmV4ZWNDb21tYW5kKCdtY2VFbmRVbmRvTGV2ZWwnKTsKCgkJCQkJcmV0dXJuIHRydWU7CgkJCX0KCgkJCS8vIFBhc3MgdG8gbmV4dCBoYW5kbGVyIGluIGNoYWluCgkJCXJldHVybiBmYWxzZTsKCQl9LAoKCQlnZXRJbmZvIDogZnVuY3Rpb24oKSB7CgkJCXJldHVybiB7CgkJCQlsb25nbmFtZSA6ICdUYWJsZXMnLAoJCQkJYXV0aG9yIDogJ01veGllY29kZSBTeXN0ZW1zIEFCJywKCQkJCWF1dGhvcnVybCA6ICdodHRwOi8vdGlueW1jZS5tb3hpZWNvZGUuY29tLycsCgkJCQlpbmZvdXJsIDogJ2h0dHA6Ly93aWtpLm1veGllY29kZS5jb20vaW5kZXgucGhwL1RpbnlNQ0U6UGx1Z2lucy90YWJsZScsCgkJCQl2ZXJzaW9uIDogdGlueW1jZS5tYWpvclZlcnNpb24gKyAiLiIgKyB0aW55bWNlLm1pbm9yVmVyc2lvbgoJCQl9OwoJCX0sCgoJCS8vIFByaXZhdGUgcGx1Z2luIGludGVybmFsIG1ldGhvZHMKCgkJLyoqCgkJICogRXhlY3V0ZXMgdGhlIHRhYmxlIGNvbW1hbmRzLgoJCSAqLwoJCV9kb0V4ZWNDb21tYW5kIDogZnVuY3Rpb24oY29tbWFuZCwgdXNlcl9pbnRlcmZhY2UsIHZhbHVlKSB7CgkJCXZhciBpbnN0ID0gdGhpcy5lZGl0b3IsIGVkID0gaW5zdCwgdXJsID0gdGhpcy51cmw7CgkJCXZhciBmb2N1c0VsbSA9IGluc3Quc2VsZWN0aW9uLmdldE5vZGUoKTsKCQkJdmFyIHRyRWxtID0gaW5zdC5kb20uZ2V0UGFyZW50KGZvY3VzRWxtLCAidHIiKTsKCQkJdmFyIHRkRWxtID0gaW5zdC5kb20uZ2V0UGFyZW50KGZvY3VzRWxtLCAidGQsdGgiKTsKCQkJdmFyIHRhYmxlRWxtID0gaW5zdC5kb20uZ2V0UGFyZW50KGZvY3VzRWxtLCAidGFibGUiKTsKCQkJdmFyIGRvYyA9IGluc3QuY29udGVudFdpbmRvdy5kb2N1bWVudDsKCQkJdmFyIHRhYmxlQm9yZGVyID0gdGFibGVFbG0gPyB0YWJsZUVsbS5nZXRBdHRyaWJ1dGUoImJvcmRlciIpIDogIiI7CiAgICAgICAgICAgIHZhciBhY3Rpb25CYXNlVXJsID0gdGlueU1DRS5zZXR0aW5ncy5wbHVnaW5fYWN0aW9uX2Jhc2VfcGF0aDsKICAgICAgICAgICAgdmFyIGNlbGxTdHlsZSA9IHRpbnlNQ0Uuc2V0dGluZ3MuY29uZmx1ZW5jZV90YWJsZV9jZWxsX3N0eWxlOwoKICAgICAgICAgICAgLy8gR2V0IGZpcnN0IFREIGlmIG5vIFREIGZvdW5kCgkJCWlmICh0ckVsbSAmJiB0ZEVsbSA9PSBudWxsKQoJCQkJdGRFbG0gPSB0ckVsbS5jZWxsc1swXTsKCgkJCWZ1bmN0aW9uIGluQXJyYXkoYXIsIHYpIHsKCQkJCWZvciAodmFyIGk9MDsgaTxhci5sZW5ndGg7IGkrKykgewoJCQkJCS8vIElzIGFycmF5CgkJCQkJaWYgKGFyW2ldICYmIGFyW2ldLmxlbmd0aCA+IDAgJiYgaW5BcnJheShhcltpXSwgdikpCgkJCQkJCXJldHVybiB0cnVlOwoKCQkJCQkvLyBGb3VuZCB2YWx1ZQoJCQkJCWlmIChhcltpXSA9PSB2KQoJCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCX0KCgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCgkJCWZ1bmN0aW9uIHNlbGVjdChkeCwgZHkpIHsKCQkJCXZhciB0ZDsKCgkJCQlncmlkID0gZ2V0VGFibGVHcmlkKHRhYmxlRWxtKTsKCQkJCWR4ID0gZHggfHwgMDsKCQkJCWR5ID0gZHkgfHwgMDsKCQkJCWR4ID0gTWF0aC5tYXgoY3Bvcy5jZWxsaW5kZXggKyBkeCwgMCk7CgkJCQlkeSA9IE1hdGgubWF4KGNwb3Mucm93aW5kZXggKyBkeSwgMCk7CgoJCQkJLy8gUmVjYWxjdWxhdGUgZ3JpZCBhbmQgc2VsZWN0CgkJCQlpbnN0LmV4ZWNDb21tYW5kKCdtY2VSZXBhaW50Jyk7CgkJCQl0ZCA9IGdldENlbGwoZ3JpZCwgZHksIGR4KTsKCgkJCQlpZiAodGQpIHsKCQkJCQlpbnN0LnNlbGVjdGlvbi5zZWxlY3QodGQuZmlyc3RDaGlsZCB8fCB0ZCk7CgkJCQkJaW5zdC5zZWxlY3Rpb24uY29sbGFwc2UoMSk7CgkJCQl9CgkJCX07CgoJCQlmdW5jdGlvbiBtYWtlVEQoKSB7CgkJCQl2YXIgbmV3VEQgPSBkb2MuY3JlYXRlRWxlbWVudCgidGQiKTsKCgkJCQlpZiAoIXRpbnltY2UuaXNJRSkKCQkJCQluZXdURC5pbm5lckhUTUwgPSAnPGJyIG1jZV9ib2d1cz0iMSIvPic7CgkJCX0KCgkJCWZ1bmN0aW9uIGdldENvbFJvd1NwYW4odGQpIHsKCQkJCXZhciBjb2xzcGFuID0gaW5zdC5kb20uZ2V0QXR0cmliKHRkLCAiY29sc3BhbiIpOwoJCQkJdmFyIHJvd3NwYW4gPSBpbnN0LmRvbS5nZXRBdHRyaWIodGQsICJyb3dzcGFuIik7CgoJCQkJY29sc3BhbiA9IGNvbHNwYW4gPT0gIiIgPyAxIDogcGFyc2VJbnQoY29sc3Bhbik7CgkJCQlyb3dzcGFuID0gcm93c3BhbiA9PSAiIiA/IDEgOiBwYXJzZUludChyb3dzcGFuKTsKCgkJCQlyZXR1cm4ge2NvbHNwYW4gOiBjb2xzcGFuLCByb3dzcGFuIDogcm93c3Bhbn07CgkJCX0KCgkJCWZ1bmN0aW9uIGdldENlbGxQb3MoZ3JpZCwgdGQpIHsKCQkJCXZhciB4LCB5OwoKCQkJCWZvciAoeT0wOyB5PGdyaWQubGVuZ3RoOyB5KyspIHsKCQkJCQlmb3IgKHg9MDsgeDxncmlkW3ldLmxlbmd0aDsgeCsrKSB7CgkJCQkJCWlmIChncmlkW3ldW3hdID09IHRkKQoJCQkJCQkJcmV0dXJuIHtjZWxsaW5kZXggOiB4LCByb3dpbmRleCA6IHl9OwoJCQkJCX0KCQkJCX0KCgkJCQlyZXR1cm4gbnVsbDsKCQkJfQoKCQkJZnVuY3Rpb24gZ2V0Q2VsbChncmlkLCByb3csIGNvbCkgewoJCQkJaWYgKGdyaWRbcm93XSAmJiBncmlkW3Jvd11bY29sXSkKCQkJCQlyZXR1cm4gZ3JpZFtyb3ddW2NvbF07CgoJCQkJcmV0dXJuIG51bGw7CgkJCX0KCiAgICAgICAgICAgIC8vQVRMQVNTSUFOIC0gdXNlZCBieSB0aGUgbWNlVGFibGVNb3ZlVG9QcmV2Um93IGNvbW1hbmQKICAgICAgICAgICAgZnVuY3Rpb24gZ2V0UHJldkNlbGwodGFibGUsIGNlbGwpIHsKICAgICAgICAgICAgICAgIHZhciBpLCBqOwoKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0YWJsZS5yb3dzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IHRhYmxlLnJvd3NbaV0uY2VsbHMubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRhYmxlLnJvd3NbaV0uY2VsbHNbal0gPT0gY2VsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGogPT0gMCA/IHVuZGVmaW5lZCA6IHRhYmxlLnJvd3NbaV0uY2VsbHNbaiAtIDFdOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgoJCQlmdW5jdGlvbiBnZXROZXh0Q2VsbCh0YWJsZSwgY2VsbCkgewoJCQkJdmFyIGNlbGxzID0gW10sIHggPSAwLCBpLCBqLCBjZWxsLCBuZXh0Q2VsbDsKCgkJCQlmb3IgKGkgPSAwOyBpIDwgdGFibGUucm93cy5sZW5ndGg7IGkrKykKCQkJCQlmb3IgKGogPSAwOyBqIDwgdGFibGUucm93c1tpXS5jZWxscy5sZW5ndGg7IGorKywgeCsrKQoJCQkJCQljZWxsc1t4XSA9IHRhYmxlLnJvd3NbaV0uY2VsbHNbal07CgoJCQkJZm9yIChpID0gMDsgaSA8IGNlbGxzLmxlbmd0aDsgaSsrKQoJCQkJCWlmIChjZWxsc1tpXSA9PSBjZWxsKQoJCQkJCQlpZiAobmV4dENlbGwgPSBjZWxsc1tpKzFdKQoJCQkJCQkJcmV0dXJuIG5leHRDZWxsOwoJCQl9CgoJCQlmdW5jdGlvbiBnZXRUYWJsZUdyaWQodGFibGUpIHsKCQkJCXZhciBncmlkID0gW10sIHJvd3MgPSB0YWJsZS5yb3dzLCB4LCB5LCB0ZCwgc2QsIHhzdGFydCwgeDIsIHkyOwoKCQkJCWZvciAoeT0wOyB5PHJvd3MubGVuZ3RoOyB5KyspIHsKCQkJCQlmb3IgKHg9MDsgeDxyb3dzW3ldLmNlbGxzLmxlbmd0aDsgeCsrKSB7CgkJCQkJCXRkID0gcm93c1t5XS5jZWxsc1t4XTsKCQkJCQkJc2QgPSBnZXRDb2xSb3dTcGFuKHRkKTsKCgkJCQkJCS8vIEFsbCByZWFkeSBmaWxsZWQKCQkJCQkJZm9yICh4c3RhcnQgPSB4OyBncmlkW3ldICYmIGdyaWRbeV1beHN0YXJ0XTsgeHN0YXJ0KyspIDsKCgkJCQkJCS8vIEZpbGwgYm94CgkJCQkJCWZvciAoeTI9eTsgeTI8eStzZFsncm93c3BhbiddOyB5MisrKSB7CgkJCQkJCQlpZiAoIWdyaWRbeTJdKQoJCQkJCQkJCWdyaWRbeTJdID0gW107CgoJCQkJCQkJZm9yICh4Mj14c3RhcnQ7IHgyPHhzdGFydCtzZFsnY29sc3BhbiddOyB4MisrKQoJCQkJCQkJCWdyaWRbeTJdW3gyXSA9IHRkOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoKCQkJCXJldHVybiBncmlkOwoJCQl9CgoJCQlmdW5jdGlvbiB0cmltUm93KHRhYmxlLCB0ciwgdGQsIG5ld190cikgewoJCQkJdmFyIGdyaWQgPSBnZXRUYWJsZUdyaWQodGFibGUpLCBjcG9zID0gZ2V0Q2VsbFBvcyhncmlkLCB0ZCk7CgkJCQl2YXIgY2VsbHMsIGxhc3RFbG07CgoJCQkJLy8gVGltZSB0byBjcm9wIGF3YXkgc29tZQoJCQkJaWYgKG5ld190ci5jZWxscy5sZW5ndGggIT0gdHIuY2hpbGROb2Rlcy5sZW5ndGgpIHsKCQkJCQljZWxscyA9IHRyLmNoaWxkTm9kZXM7CgkJCQkJbGFzdEVsbSA9IG51bGw7CgoJCQkJCWZvciAodmFyIHg9MDsgdGQgPSBnZXRDZWxsKGdyaWQsIGNwb3Mucm93aW5kZXgsIHgpOyB4KyspIHsKCQkJCQkJdmFyIHJlbW92ZSA9IHRydWU7CgkJCQkJCXZhciBzZCA9IGdldENvbFJvd1NwYW4odGQpOwoKCQkJCQkJLy8gUmVtb3ZlIGR1ZSB0byByb3dzcGFuCgkJCQkJCWlmIChpbkFycmF5KGNlbGxzLCB0ZCkpIHsKCQkJCQkJCW5ld190ci5jaGlsZE5vZGVzW3hdLl9kZWxldGUgPSB0cnVlOwoJCQkJCQl9IGVsc2UgaWYgKChsYXN0RWxtID09IG51bGwgfHwgdGQgIT0gbGFzdEVsbSkgJiYgc2QuY29sc3BhbiA+IDEpIHsgLy8gUmVtb3ZlIGR1ZSB0byBjb2xzcGFuCgkJCQkJCQlmb3IgKHZhciBpPXg7IGk8eCt0ZC5jb2xTcGFuOyBpKyspCgkJCQkJCQkJbmV3X3RyLmNoaWxkTm9kZXNbaV0uX2RlbGV0ZSA9IHRydWU7CgkJCQkJCX0KCgkJCQkJCWlmICgobGFzdEVsbSA9PSBudWxsIHx8IHRkICE9IGxhc3RFbG0pICYmIHNkLnJvd3NwYW4gPiAxKQoJCQkJCQkJdGQucm93U3BhbiA9IHNkLnJvd3NwYW4gKyAxOwoKCQkJCQkJbGFzdEVsbSA9IHRkOwoJCQkJCX0KCgkJCQkJZGVsZXRlTWFya2VkKHRhYmxlRWxtKTsKCQkJCX0KCQkJfQoKCQkJZnVuY3Rpb24gcHJldkVsbShub2RlLCBuYW1lKSB7CgkJCQl3aGlsZSAoKG5vZGUgPSBub2RlLnByZXZpb3VzU2libGluZykgIT0gbnVsbCkgewoJCQkJCWlmIChub2RlLm5vZGVOYW1lID09IG5hbWUpCgkJCQkJCXJldHVybiBub2RlOwoJCQkJfQoKCQkJCXJldHVybiBudWxsOwoJCQl9CgoJCQlmdW5jdGlvbiBuZXh0RWxtKG5vZGUsIG5hbWVzKSB7CgkJCQl2YXIgbmFtZXNBciA9IG5hbWVzLnNwbGl0KCcsJyk7CgoJCQkJd2hpbGUgKChub2RlID0gbm9kZS5uZXh0U2libGluZykgIT0gbnVsbCkgewoJCQkJCWZvciAodmFyIGk9MDsgaTxuYW1lc0FyLmxlbmd0aDsgaSsrKSB7CgkJCQkJCWlmIChub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT0gbmFtZXNBcltpXS50b0xvd2VyQ2FzZSgpICkKCQkJCQkJCXJldHVybiBub2RlOwoJCQkJCX0KCQkJCX0KCgkJCQlyZXR1cm4gbnVsbDsKCQkJfQoKCQkJZnVuY3Rpb24gZGVsZXRlTWFya2VkKHRibCkgewoJCQkJaWYgKHRibC5yb3dzID09IDApCgkJCQkJcmV0dXJuOwoKCQkJCXZhciB0ciA9IHRibC5yb3dzWzBdOwoJCQkJZG8gewoJCQkJCXZhciBuZXh0ID0gbmV4dEVsbSh0ciwgIlRSIik7CgoJCQkJCS8vIERlbGV0ZSByb3cKCQkJCQlpZiAodHIuX2RlbGV0ZSkgewoJCQkJCQl0ci5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRyKTsKCQkJCQkJY29udGludWU7CgkJCQkJfQoKCQkJCQkvLyBEZWxldGUgY2VsbHMKCQkJCQl2YXIgdGQgPSB0ci5jZWxsc1swXTsKCQkJCQlpZiAodGQuY2VsbHMgPiAxKSB7CgkJCQkJCWRvIHsKCQkJCQkJCXZhciBuZXh0dGQgPSBuZXh0RWxtKHRkLCAiVEQsVEgiKTsKCgkJCQkJCQlpZiAodGQuX2RlbGV0ZSkKCQkJCQkJCQl0ZC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRkKTsKCQkJCQkJfSB3aGlsZSAoKHRkID0gbmV4dHRkKSAhPSBudWxsKTsKCQkJCQl9CgkJCQl9IHdoaWxlICgodHIgPSBuZXh0KSAhPSBudWxsKTsKCQkJfQoKCQkJZnVuY3Rpb24gYWRkUm93cyh0ZF9lbG0sIHRyX2VsbSwgcm93c3BhbikgewoJCQkJLy8gQWRkIHJvd3MKCQkJCXRkX2VsbS5yb3dTcGFuID0gMTsKCQkJCXZhciB0ck5leHQgPSBuZXh0RWxtKHRyX2VsbSwgIlRSIik7CgkJCQlmb3IgKHZhciBpPTE7IGk8cm93c3BhbiAmJiB0ck5leHQ7IGkrKykgewoJCQkJCXZhciBuZXdURCA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0ZCIpOwoKCQkJCQlpZiAoIXRpbnltY2UuaXNJRSkKCQkJCQkJbmV3VEQuaW5uZXJIVE1MID0gJzxiciBtY2VfYm9ndXM9IjEiLz4nOwoKCQkJCQlpZiAodGlueW1jZS5pc0lFKQoJCQkJCQl0ck5leHQuaW5zZXJ0QmVmb3JlKG5ld1RELCB0ck5leHQuY2VsbHModGRfZWxtLmNlbGxJbmRleCkpOwoJCQkJCWVsc2UKCQkJCQkJdHJOZXh0Lmluc2VydEJlZm9yZShuZXdURCwgdHJOZXh0LmNlbGxzW3RkX2VsbS5jZWxsSW5kZXhdKTsKCgkJCQkJdHJOZXh0ID0gbmV4dEVsbSh0ck5leHQsICJUUiIpOwoJCQkJfQoJCQl9CgoJCQlmdW5jdGlvbiBjb3B5Um93KGRvYywgdGFibGUsIHRyKSB7CgkJCQl2YXIgZ3JpZCA9IGdldFRhYmxlR3JpZCh0YWJsZSk7CgkJCQl2YXIgbmV3VFIgPSB0ci5jbG9uZU5vZGUoZmFsc2UpOwoJCQkJdmFyIGNwb3MgPSBnZXRDZWxsUG9zKGdyaWQsIHRyLmNlbGxzWzBdKTsKCQkJCXZhciBsYXN0Q2VsbCA9IG51bGw7CgkJCQl2YXIgdGFibGVCb3JkZXIgPSBpbnN0LmRvbS5nZXRBdHRyaWIodGFibGUsICJib3JkZXIiKTsKCQkJCXZhciB0ZEVsbSA9IG51bGw7CgoJCQkJZm9yICh2YXIgeD0wOyB0ZEVsbSA9IGdldENlbGwoZ3JpZCwgY3Bvcy5yb3dpbmRleCwgeCk7IHgrKykgewoJCQkJCXZhciBuZXdURCA9IG51bGw7CgoJCQkJCWlmIChsYXN0Q2VsbCAhPSB0ZEVsbSkgewoJCQkJCQlmb3IgKHZhciBpPTA7IGk8dHIuY2VsbHMubGVuZ3RoOyBpKyspIHsKCQkJCQkJCWlmICh0ZEVsbSA9PSB0ci5jZWxsc1tpXSkgewoJCQkJCQkJCW5ld1REID0gdGRFbG0uY2xvbmVOb2RlKHRydWUpOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoKCQkJCQlpZiAobmV3VEQgPT0gbnVsbCkgewoJCQkJCQluZXdURCA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0ZCIpOwoKCQkJCQkJaWYgKCF0aW55bWNlLmlzSUUpCgkJCQkJCQluZXdURC5pbm5lckhUTUwgPSAnPGJyIG1jZV9ib2d1cz0iMSIvPic7CgkJCQkJfQoKCQkJCQkvLyBSZXNldCBjb2wvcm93IHNwYW4KCQkJCQluZXdURC5jb2xTcGFuID0gMTsKCQkJCQluZXdURC5yb3dTcGFuID0gMTsKCgkJCQkJbmV3VFIuYXBwZW5kQ2hpbGQobmV3VEQpOwoKCQkJCQlsYXN0Q2VsbCA9IHRkRWxtOwoJCQkJfQoKCQkJCXJldHVybiBuZXdUUjsKCQkJfQoKCQkJLy8gLS0tLSBDb21tYW5kcyAtLS0tLQoKCQkJLy8gSGFuZGxlIGNvbW1hbmRzCgkJCXN3aXRjaCAoY29tbWFuZCkgewogICAgICAgICAgICAgICAgLy8gQVRMQVNTSUFOIC0gYWRkIGFiaWxpdHkgdG8gbW92ZSB0byBwcmV2aW91cyBjZWxsL3JvdwogICAgICAgICAgICAgICAgY2FzZSAibWNlVGFibGVNb3ZlVG9QcmV2Um93IjoKICAgICAgICAgICAgICAgICAgICB2YXIgcHJldkNlbGwgPSBnZXRQcmV2Q2VsbCh0YWJsZUVsbSwgdGRFbG0pOwoKICAgICAgICAgICAgICAgICAgICBpZiAoIXByZXZDZWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGluc3QuZXhlY0NvbW1hbmQoIm1jZVRhYmxlSW5zZXJ0Um93QmVmb3JlIiwgdGRFbG0pOwogICAgICAgICAgICAgICAgICAgICAgICBwcmV2Q2VsbCA9IGdldFByZXZDZWxsKHRhYmxlRWxtLCB0ZEVsbSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAodGlueW1jZS5pc0dlY2tvICYmIHByZXZDZWxsLmZpcnN0Q2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcHJldkNlbGwgPSBwcmV2Q2VsbC5maXJzdENoaWxkOwogICAgICAgICAgICAgICAgICAgIH0KCQkJCQlpbnN0LnNlbGVjdGlvbi5zZWxlY3QocHJldkNlbGwpOwoJCQkJCWluc3Quc2VsZWN0aW9uLmNvbGxhcHNlKHRydWUpOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCgkJCQljYXNlICJtY2VUYWJsZU1vdmVUb05leHRSb3ciOgoJCQkJCXZhciBuZXh0Q2VsbCA9IGdldE5leHRDZWxsKHRhYmxlRWxtLCB0ZEVsbSk7CgoJCQkJCWlmICghbmV4dENlbGwpIHsKCQkJCQkJaW5zdC5leGVjQ29tbWFuZCgibWNlVGFibGVJbnNlcnRSb3dBZnRlciIsIHRkRWxtKTsKCQkJCQkJbmV4dENlbGwgPSBnZXROZXh0Q2VsbCh0YWJsZUVsbSwgdGRFbG0pOwoJCQkJCX0KCiAgICAgICAgICAgICAgICAgICAgLy8gQVRMQVNTSUFOIC0gbmVlZCB0byBzZWxlY3QgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIGNlbGwgZm9yIEZGCiAgICAgICAgICAgICAgICAgICAgaWYgKHRpbnltY2UuaXNHZWNrbyAmJiBuZXh0Q2VsbC5maXJzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRDZWxsID0gbmV4dENlbGwuZmlyc3RDaGlsZDsKICAgICAgICAgICAgICAgICAgICB9CgkJCQkJaW5zdC5zZWxlY3Rpb24uc2VsZWN0KG5leHRDZWxsKTsKCQkJCQlpbnN0LnNlbGVjdGlvbi5jb2xsYXBzZSh0cnVlKTsKCgkJCQkJcmV0dXJuIHRydWU7CgoJCQkJY2FzZSAibWNlVGFibGVSb3dQcm9wcyI6CgkJCQkJaWYgKHRyRWxtID09IG51bGwpCgkJCQkJCXJldHVybiB0cnVlOwoKCQkJCQlpZiAodXNlcl9pbnRlcmZhY2UpIHsKCQkJCQkJaW5zdC53aW5kb3dNYW5hZ2VyLm9wZW4oewoJCQkJCQkJdXJsIDogYWN0aW9uQmFzZVVybCArICcvcm93LmFjdGlvbicsCgkJCQkJCQl3aWR0aCA6IDQwMCArIHBhcnNlSW50KGluc3QuZ2V0TGFuZygndGFibGUucm93cHJvcHNfZGVsdGFfd2lkdGgnLCAwKSksCgkJCQkJCQloZWlnaHQgOiAyOTUgKyBwYXJzZUludChpbnN0LmdldExhbmcoJ3RhYmxlLnJvd3Byb3BzX2RlbHRhX2hlaWdodCcsIDApKSwKCQkJCQkJCWlubGluZSA6IDEKCQkJCQkJfSwgewoJCQkJCQkJcGx1Z2luX3VybCA6IHVybAoJCQkJCQl9KTsKCQkJCQl9CgoJCQkJCXJldHVybiB0cnVlOwoKCQkJCWNhc2UgIm1jZVRhYmxlQ2VsbFByb3BzIjoKCQkJCQlpZiAodGRFbG0gPT0gbnVsbCkKCQkJCQkJcmV0dXJuIHRydWU7CgoJCQkJCWlmICh1c2VyX2ludGVyZmFjZSkgewoJCQkJCQlpbnN0LndpbmRvd01hbmFnZXIub3Blbih7CgkJCQkJCQl1cmwgOiBhY3Rpb25CYXNlVXJsICsgJy9jZWxsLmFjdGlvbicsCgkJCQkJCQl3aWR0aCA6IDQwMCArIHBhcnNlSW50KGluc3QuZ2V0TGFuZygndGFibGUuY2VsbHByb3BzX2RlbHRhX3dpZHRoJywgMCkpLAoJCQkJCQkJaGVpZ2h0IDogMjk1ICsgcGFyc2VJbnQoaW5zdC5nZXRMYW5nKCd0YWJsZS5jZWxscHJvcHNfZGVsdGFfaGVpZ2h0JywgMCkpLAoJCQkJCQkJaW5saW5lIDogMQoJCQkJCQl9LCB7CgkJCQkJCQlwbHVnaW5fdXJsIDogdXJsCgkJCQkJCX0pOwoJCQkJCX0KCgkJCQkJcmV0dXJuIHRydWU7CgoJCQkJY2FzZSAibWNlSW5zZXJ0VGFibGUiOgoJCQkJCWlmICh1c2VyX2ludGVyZmFjZSkgewoJCQkJCQlpbnN0LndpbmRvd01hbmFnZXIub3Blbih7CgkJCQkJCQl1cmwgOiBhY3Rpb25CYXNlVXJsICsgJy93eXNpd3lnLXRhYmxlLmFjdGlvbicsCgkJCQkJCQl3aWR0aCA6IDQwMCArIHBhcnNlSW50KGluc3QuZ2V0TGFuZygndGFibGUudGFibGVfZGVsdGFfd2lkdGgnLCAwKSksCgkJCQkJCQloZWlnaHQgOiAzMjAgKyBwYXJzZUludChpbnN0LmdldExhbmcoJ3RhYmxlLnRhYmxlX2RlbHRhX2hlaWdodCcsIDApKSwKCQkJCQkJCWlubGluZSA6IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAidGFibGVfaW5zZXJ0ZXIiCgogICAgICAgICAgICAgICAgICAgICAgICB9LCB7CgkJCQkJCQlwbHVnaW5fdXJsIDogdXJsLAoJCQkJCQkJYWN0aW9uIDogdmFsdWUgPyB2YWx1ZS5hY3Rpb24gOiAwCgkJCQkJCX0pOwoJCQkJCX0KCgkJCQkJcmV0dXJuIHRydWU7CgoJCQkJY2FzZSAibWNlVGFibGVEZWxldGUiOgoJCQkJCXZhciB0YWJsZSA9IGluc3QuZG9tLmdldFBhcmVudChpbnN0LnNlbGVjdGlvbi5nZXROb2RlKCksICJ0YWJsZSIpOwoJCQkJCWlmICh0YWJsZSkgewoJCQkJCQl0YWJsZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRhYmxlKTsKCQkJCQkJaW5zdC5leGVjQ29tbWFuZCgnbWNlUmVwYWludCcpOwoJCQkJCX0KCQkJCQlyZXR1cm4gdHJ1ZTsKCgkJCQljYXNlICJtY2VUYWJsZVNwbGl0Q2VsbHMiOgoJCQkJY2FzZSAibWNlVGFibGVNZXJnZUNlbGxzIjoKCQkJCWNhc2UgIm1jZVRhYmxlSW5zZXJ0Um93QmVmb3JlIjoKCQkJCWNhc2UgIm1jZVRhYmxlSW5zZXJ0Um93QWZ0ZXIiOgoJCQkJY2FzZSAibWNlVGFibGVEZWxldGVSb3ciOgoJCQkJY2FzZSAibWNlVGFibGVIZWFkaW5nUm93IjoKCQkJCWNhc2UgIm1jZVRhYmxlSW5zZXJ0Q29sQmVmb3JlIjoKCQkJCWNhc2UgIm1jZVRhYmxlSW5zZXJ0Q29sQWZ0ZXIiOgoJCQkJY2FzZSAibWNlVGFibGVEZWxldGVDb2wiOgoJCQkJY2FzZSAibWNlVGFibGVDdXRSb3ciOgoJCQkJY2FzZSAibWNlVGFibGVDb3B5Um93IjoKCQkJCWNhc2UgIm1jZVRhYmxlUGFzdGVSb3dCZWZvcmUiOgoJCQkJY2FzZSAibWNlVGFibGVQYXN0ZVJvd0FmdGVyIjoKCQkJCQkvLyBObyB0YWJsZSBqdXN0IHJldHVybiAoaW52YWxpZCBjb21tYW5kKQoJCQkJCWlmICghdGFibGVFbG0pCgkJCQkJCXJldHVybiB0cnVlOwoKCQkJCQkvLyBUYWJsZSBoYXMgYSB0Ym9keSB1c2UgdGhhdCByZWZlcmVuY2UKCQkJCQkvLyBDaGFuZ2VkIGxvZ2ljIGJ5IEFwVGVzdCAyMDA1LjA3LjEyICh3d3cuYXB0ZXN0LmNvbSkKCQkJCQkvLyBOb3cgbG9va2sgYXQgdGhlIGZvY3VzZWQgZWxlbWVudCBhbmQgdGFrZSBpdHMgcGFyZW50Tm9kZS4gIFRoYXQgd2lsbCBiZSBhIHRib2R5IG9yIGEgdGFibGUuCgkJCQkJaWYgKHRyRWxtICYmIHRhYmxlRWxtICE9IHRyRWxtLnBhcmVudE5vZGUpCgkJCQkJCXRhYmxlRWxtID0gdHJFbG0ucGFyZW50Tm9kZTsKCgkJCQkJaWYgKHRhYmxlRWxtICYmIHRyRWxtKSB7CgkJCQkJCXN3aXRjaCAoY29tbWFuZCkgewoJCQkJCQkJY2FzZSAibWNlVGFibGVDdXRSb3ciOgoJCQkJCQkJCWlmICghdHJFbG0gfHwgIXRkRWxtKQoJCQkJCQkJCQlyZXR1cm4gdHJ1ZTsKCgkJCQkJCQkJaW5zdC50YWJsZVJvd0NsaXBib2FyZCA9IGNvcHlSb3coZG9jLCB0YWJsZUVsbSwgdHJFbG0pOwoJCQkJCQkJCWluc3QuZXhlY0NvbW1hbmQoIm1jZVRhYmxlRGVsZXRlUm93Iik7CgkJCQkJCQkJYnJlYWs7CgoJCQkJCQkJY2FzZSAibWNlVGFibGVDb3B5Um93IjoKCQkJCQkJCQlpZiAoIXRyRWxtIHx8ICF0ZEVsbSkKCQkJCQkJCQkJcmV0dXJuIHRydWU7CgoJCQkJCQkJCWluc3QudGFibGVSb3dDbGlwYm9hcmQgPSBjb3B5Um93KGRvYywgdGFibGVFbG0sIHRyRWxtKTsKCQkJCQkJCQlicmVhazsKCgkJCQkJCQljYXNlICJtY2VUYWJsZVBhc3RlUm93QmVmb3JlIjoKCQkJCQkJCQlpZiAoIXRyRWxtIHx8ICF0ZEVsbSkKCQkJCQkJCQkJcmV0dXJuIHRydWU7CgoJCQkJCQkJCXZhciBuZXdUUiA9IGluc3QudGFibGVSb3dDbGlwYm9hcmQuY2xvbmVOb2RlKHRydWUpOwoKCQkJCQkJCQl2YXIgcHJldlRSID0gcHJldkVsbSh0ckVsbSwgIlRSIik7CgkJCQkJCQkJaWYgKHByZXZUUiAhPSBudWxsKQoJCQkJCQkJCQl0cmltUm93KHRhYmxlRWxtLCBwcmV2VFIsIHByZXZUUi5jZWxsc1swXSwgbmV3VFIpOwoKCQkJCQkJCQl0ckVsbS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShuZXdUUiwgdHJFbG0pOwoJCQkJCQkJCWJyZWFrOwoKCQkJCQkJCWNhc2UgIm1jZVRhYmxlUGFzdGVSb3dBZnRlciI6CgkJCQkJCQkJaWYgKCF0ckVsbSB8fCAhdGRFbG0pCgkJCQkJCQkJCXJldHVybiB0cnVlOwoJCQkJCQkJCQoJCQkJCQkJCXZhciBuZXh0VFIgPSBuZXh0RWxtKHRyRWxtLCAiVFIiKTsKCQkJCQkJCQl2YXIgbmV3VFIgPSBpbnN0LnRhYmxlUm93Q2xpcGJvYXJkLmNsb25lTm9kZSh0cnVlKTsKCgkJCQkJCQkJdHJpbVJvdyh0YWJsZUVsbSwgdHJFbG0sIHRkRWxtLCBuZXdUUik7CgoJCQkJCQkJCWlmIChuZXh0VFIgPT0gbnVsbCkKCQkJCQkJCQkJdHJFbG0ucGFyZW50Tm9kZS5hcHBlbmRDaGlsZChuZXdUUik7CgkJCQkJCQkJZWxzZQoJCQkJCQkJCQluZXh0VFIucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobmV3VFIsIG5leHRUUik7CgoJCQkJCQkJCWJyZWFrOwoKCQkJCQkJCWNhc2UgIm1jZVRhYmxlSW5zZXJ0Um93QmVmb3JlIjoKCQkJCQkJCQlpZiAoIXRyRWxtIHx8ICF0ZEVsbSkKCQkJCQkJCQkJcmV0dXJuIHRydWU7CgoJCQkJCQkJCXZhciBncmlkID0gZ2V0VGFibGVHcmlkKHRhYmxlRWxtKTsKCQkJCQkJCQl2YXIgY3BvcyA9IGdldENlbGxQb3MoZ3JpZCwgdGRFbG0pOwoJCQkJCQkJCXZhciBuZXdUUiA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0ciIpOwoJCQkJCQkJCXZhciBsYXN0VERFbG0gPSBudWxsOwoKCQkJCQkJCQljcG9zLnJvd2luZGV4LS07CgkJCQkJCQkJaWYgKGNwb3Mucm93aW5kZXggPCAwKQoJCQkJCQkJCQljcG9zLnJvd2luZGV4ID0gMDsKCgkJCQkJCQkJLy8gQ3JlYXRlIGNlbGxzCgkJCQkJCQkJZm9yICh2YXIgeD0wOyB0ZEVsbSA9IGdldENlbGwoZ3JpZCwgY3Bvcy5yb3dpbmRleCwgeCk7IHgrKykgewoJCQkJCQkJCQlpZiAodGRFbG0gIT0gbGFzdFRERWxtKSB7CgkJCQkJCQkJCQl2YXIgc2QgPSBnZXRDb2xSb3dTcGFuKHRkRWxtKTsKCgkJCQkJCQkJCQlpZiAoc2RbJ3Jvd3NwYW4nXSA9PSAxKSB7CgkJCQkJCQkJCQkJdmFyIG5ld1REID0gZG9jLmNyZWF0ZUVsZW1lbnQoInRkIik7CgoJCQkJCQkJCQkJCWlmICghdGlueW1jZS5pc0lFKQoJCQkJCQkJCQkJCQluZXdURC5pbm5lckhUTUwgPSAnPGJyIG1jZV9ib2d1cz0iMSIvPic7CgoJCQkJCQkJCQkJCW5ld1RELmNvbFNwYW4gPSB0ZEVsbS5jb2xTcGFuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzZXMgdGhlIGNlbGwgc3R5bGUgZnJvbSBjb25mbHVlbmNlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdURC5jbGFzc05hbWUgPSBjZWxsU3R5bGU7CgkJCQkJCQkJCQkJbmV3VFIuYXBwZW5kQ2hpbGQobmV3VEQpOwoJCQkJCQkJCQkJfSBlbHNlCgkJCQkJCQkJCQkJdGRFbG0ucm93U3BhbiA9IHNkWydyb3dzcGFuJ10gKyAxOwoKCQkJCQkJCQkJCWxhc3RUREVsbSA9IHRkRWxtOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoKCQkJCQkJCQl0ckVsbS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShuZXdUUiwgdHJFbG0pOwoJCQkJCQkJCXNlbGVjdCgwLCAxKTsKCQkJCQkJCWJyZWFrOwoKCQkJCQkJCWNhc2UgIm1jZVRhYmxlSW5zZXJ0Um93QWZ0ZXIiOgoJCQkJCQkJCWlmICghdHJFbG0gfHwgIXRkRWxtKQoJCQkJCQkJCQlyZXR1cm4gdHJ1ZTsKCgkJCQkJCQkJdmFyIGdyaWQgPSBnZXRUYWJsZUdyaWQodGFibGVFbG0pOwoJCQkJCQkJCXZhciBjcG9zID0gZ2V0Q2VsbFBvcyhncmlkLCB0ZEVsbSk7CgkJCQkJCQkJdmFyIG5ld1RSID0gZG9jLmNyZWF0ZUVsZW1lbnQoInRyIik7CgkJCQkJCQkJdmFyIGxhc3RUREVsbSA9IG51bGw7CgoJCQkJCQkJCS8vIENyZWF0ZSBjZWxscwoJCQkJCQkJCWZvciAodmFyIHg9MDsgdGRFbG0gPSBnZXRDZWxsKGdyaWQsIGNwb3Mucm93aW5kZXgsIHgpOyB4KyspIHsKCQkJCQkJCQkJaWYgKHRkRWxtICE9IGxhc3RUREVsbSkgewoJCQkJCQkJCQkJdmFyIHNkID0gZ2V0Q29sUm93U3Bhbih0ZEVsbSk7CgoJCQkJCQkJCQkJaWYgKHNkWydyb3dzcGFuJ10gPT0gMSkgewoJCQkJCQkJCQkJCXZhciBuZXdURCA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0ZCIpOwoKCQkJCQkJCQkJCQlpZiAoIXRpbnltY2UuaXNJRSkKCQkJCQkJCQkJCQkJbmV3VEQuaW5uZXJIVE1MID0gJzxiciBtY2VfYm9ndXM9IjEiLz4nOwoKCQkJCQkJCQkJCQluZXdURC5jb2xTcGFuID0gdGRFbG0uY29sU3BhbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2VzIHRoZSBjZWxsIHN0eWxlIGZyb20gY29uZmx1ZW5jZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1RELmNsYXNzTmFtZSA9IGNlbGxTdHlsZTsKCQkJCQkJCQkJCQluZXdUUi5hcHBlbmRDaGlsZChuZXdURCk7CgkJCQkJCQkJCQl9IGVsc2UKCQkJCQkJCQkJCQl0ZEVsbS5yb3dTcGFuID0gc2RbJ3Jvd3NwYW4nXSArIDE7CgoJCQkJCQkJCQkJbGFzdFRERWxtID0gdGRFbG07CgkJCQkJCQkJCX0KCQkJCQkJCQl9CgoJCQkJCQkJCWlmIChuZXdUUi5oYXNDaGlsZE5vZGVzKCkpIHsKCQkJCQkJCQkJdmFyIG5leHRUUiA9IG5leHRFbG0odHJFbG0sICJUUiIpOwoJCQkJCQkJCQlpZiAobmV4dFRSKQoJCQkJCQkJCQkJbmV4dFRSLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5ld1RSLCBuZXh0VFIpOwoJCQkJCQkJCQllbHNlCgkJCQkJCQkJCQl0YWJsZUVsbS5hcHBlbmRDaGlsZChuZXdUUik7CgkJCQkJCQkJfQoKCQkJCQkJCQlzZWxlY3QoMCwgMSk7CgkJCQkJCQlicmVhazsKCgkJCQkJCQljYXNlICJtY2VUYWJsZURlbGV0ZVJvdyI6CgkJCQkJCQkJaWYgKCF0ckVsbSB8fCAhdGRFbG0pCgkJCQkJCQkJCXJldHVybiB0cnVlOwoKCQkJCQkJCQl2YXIgZ3JpZCA9IGdldFRhYmxlR3JpZCh0YWJsZUVsbSk7CgkJCQkJCQkJdmFyIGNwb3MgPSBnZXRDZWxsUG9zKGdyaWQsIHRkRWxtKTsKCgkJCQkJCQkJLy8gT25seSBvbmUgcm93LCByZW1vdmUgd2hvbGUgdGFibGUKCQkJCQkJCQlpZiAoZ3JpZC5sZW5ndGggPT0gMSAmJiB0YWJsZUVsbS5ub2RlTmFtZSA9PSAnVEJPRFknKSB7CgkJCQkJCQkJCWluc3QuZG9tLnJlbW92ZShpbnN0LmRvbS5nZXRQYXJlbnQodGFibGVFbG0sICJ0YWJsZSIpKTsKCQkJCQkJCQkJcmV0dXJuIHRydWU7CgkJCQkJCQkJfQoKCQkJCQkJCQkvLyBNb3ZlIGRvd24gcm93IHNwYW5uZWQgY2VsbHMKCQkJCQkJCQl2YXIgY2VsbHMgPSB0ckVsbS5jZWxsczsKCQkJCQkJCQl2YXIgbmV4dFRSID0gbmV4dEVsbSh0ckVsbSwgIlRSIik7CgkJCQkJCQkJZm9yICh2YXIgeD0wOyB4PGNlbGxzLmxlbmd0aDsgeCsrKSB7CgkJCQkJCQkJCWlmIChjZWxsc1t4XS5yb3dTcGFuID4gMSkgewoJCQkJCQkJCQkJdmFyIG5ld1REID0gY2VsbHNbeF0uY2xvbmVOb2RlKHRydWUpOwoJCQkJCQkJCQkJdmFyIHNkID0gZ2V0Q29sUm93U3BhbihjZWxsc1t4XSk7CgoJCQkJCQkJCQkJbmV3VEQucm93U3BhbiA9IHNkLnJvd3NwYW4gLSAxOwoKCQkJCQkJCQkJCXZhciBuZXh0VEQgPSBuZXh0VFIuY2VsbHNbeF07CgoJCQkJCQkJCQkJaWYgKG5leHRURCA9PSBudWxsKQoJCQkJCQkJCQkJCW5leHRUUi5hcHBlbmRDaGlsZChuZXdURCk7CgkJCQkJCQkJCQllbHNlCgkJCQkJCQkJCQkJbmV4dFRSLmluc2VydEJlZm9yZShuZXdURCwgbmV4dFREKTsKCQkJCQkJCQkJfQoJCQkJCQkJCX0KCgkJCQkJCQkJLy8gRGVsZXRlIGNlbGxzCgkJCQkJCQkJdmFyIGxhc3RUREVsbSA9IG51bGw7CgkJCQkJCQkJZm9yICh2YXIgeD0wOyB0ZEVsbSA9IGdldENlbGwoZ3JpZCwgY3Bvcy5yb3dpbmRleCwgeCk7IHgrKykgewoJCQkJCQkJCQlpZiAodGRFbG0gIT0gbGFzdFRERWxtKSB7CgkJCQkJCQkJCQl2YXIgc2QgPSBnZXRDb2xSb3dTcGFuKHRkRWxtKTsKCgkJCQkJCQkJCQlpZiAoc2Qucm93c3BhbiA+IDEpIHsKCQkJCQkJCQkJCQl0ZEVsbS5yb3dTcGFuID0gc2Qucm93c3BhbiAtIDE7CgkJCQkJCQkJCQl9IGVsc2UgewoJCQkJCQkJCQkJCXRyRWxtID0gdGRFbG0ucGFyZW50Tm9kZTsKCgkJCQkJCQkJCQkJaWYgKHRyRWxtLnBhcmVudE5vZGUpCgkJCQkJCQkJCQkJCXRyRWxtLl9kZWxldGUgPSB0cnVlOwoJCQkJCQkJCQkJfQoKCQkJCQkJCQkJCWxhc3RUREVsbSA9IHRkRWxtOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoKCQkJCQkJCQlkZWxldGVNYXJrZWQodGFibGVFbG0pOwoKCQkJCQkJCQlzZWxlY3QoMCwgLTEpOwoJCQkJCQkJYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQVRMQVNTSUFOIC0gYWRkIHN1cHBvcnQgdG8gdG9nZ2xlIHJvdyBhcyBoZWFkaW5ncwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAibWNlVGFibGVIZWFkaW5nUm93IjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZighdHJFbG0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGxzID0gdHJFbG0uY2VsbHM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaT0wOyBpPGNlbGxzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gY2VsbHNbaV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdDZWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2VsbC5ub2RlTmFtZSA9PSAiVEQiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdDZWxsID0gZG9jLmNyZWF0ZUVsZW1lbnQoInRoIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdDZWxsLmNsYXNzTmFtZSA9IHRpbnlNQ0Uuc2V0dGluZ3MuY29uZmx1ZW5jZV90YWJsZV9oZWFkZXJfc3R5bGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY2VsbC5ub2RlTmFtZSA9PSAiVEgiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdDZWxsID0gZG9jLmNyZWF0ZUVsZW1lbnQoInRkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdDZWxsLmNsYXNzTmFtZSA9IHRpbnlNQ0Uuc2V0dGluZ3MuY29uZmx1ZW5jZV90YWJsZV9jZWxsX3N0eWxlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW55bWNlLkRPTS5yZXBsYWNlKG5ld0NlbGwsIGNlbGwsIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIm1jZVRhYmxlSW5zZXJ0Q29sQmVmb3JlIjoKCQkJCQkJCQlpZiAoIXRyRWxtIHx8ICF0ZEVsbSkKCQkJCQkJCQkJcmV0dXJuIHRydWU7CgoJCQkJCQkJCXZhciBncmlkID0gZ2V0VGFibGVHcmlkKGluc3QuZG9tLmdldFBhcmVudCh0YWJsZUVsbSwgInRhYmxlIikpOwoJCQkJCQkJCXZhciBjcG9zID0gZ2V0Q2VsbFBvcyhncmlkLCB0ZEVsbSk7CgkJCQkJCQkJdmFyIGxhc3RUREVsbSA9IG51bGw7CgoJCQkJCQkJCWZvciAodmFyIHk9MDsgdGRFbG0gPSBnZXRDZWxsKGdyaWQsIHksIGNwb3MuY2VsbGluZGV4KTsgeSsrKSB7CgkJCQkJCQkJCWlmICh0ZEVsbSAhPSBsYXN0VERFbG0pIHsKCQkJCQkJCQkJCXZhciBzZCA9IGdldENvbFJvd1NwYW4odGRFbG0pOwoKCQkJCQkJCQkJCWlmIChzZFsnY29sc3BhbiddID09IDEpIHsKCQkJCQkJCQkJCQl2YXIgbmV3VEQgPSBkb2MuY3JlYXRlRWxlbWVudCh0ZEVsbS5ub2RlTmFtZSk7CgoJCQkJCQkJCQkJCWlmICghdGlueW1jZS5pc0lFKQoJCQkJCQkJCQkJCQluZXdURC5pbm5lckhUTUwgPSAnPGJyIG1jZV9ib2d1cz0iMSIvPic7CgoJCQkJCQkJCQkJCW5ld1RELnJvd1NwYW4gPSB0ZEVsbS5yb3dTcGFuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvcHkgd2hhdGV2ZXIgc3R5bGUgdGhlIGN1cnJlbnQgY29sdW1uIGhhcy4gIENvcGllcyBoZWFkZXIgcm93cy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdURC5jbGFzc05hbWUgPSB0ZEVsbS5jbGFzc05hbWU7CgkJCQkJCQkJCQkJdGRFbG0ucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobmV3VEQsIHRkRWxtKTsKCQkJCQkJCQkJCX0gZWxzZQoJCQkJCQkJCQkJCXRkRWxtLmNvbFNwYW4rKzsKCgkJCQkJCQkJCQlsYXN0VERFbG0gPSB0ZEVsbTsKCQkJCQkJCQkJfQoJCQkJCQkJCX0KCgkJCQkJCQkJc2VsZWN0KCk7CgkJCQkJCQlicmVhazsKCgkJCQkJCQljYXNlICJtY2VUYWJsZUluc2VydENvbEFmdGVyIjoKCQkJCQkJCQlpZiAoIXRyRWxtIHx8ICF0ZEVsbSkKCQkJCQkJCQkJcmV0dXJuIHRydWU7CgoJCQkJCQkJCXZhciBncmlkID0gZ2V0VGFibGVHcmlkKGluc3QuZG9tLmdldFBhcmVudCh0YWJsZUVsbSwgInRhYmxlIikpOwoJCQkJCQkJCXZhciBjcG9zID0gZ2V0Q2VsbFBvcyhncmlkLCB0ZEVsbSk7CgkJCQkJCQkJdmFyIGxhc3RUREVsbSA9IG51bGw7CgoJCQkJCQkJCWZvciAodmFyIHk9MDsgdGRFbG0gPSBnZXRDZWxsKGdyaWQsIHksIGNwb3MuY2VsbGluZGV4KTsgeSsrKSB7CgkJCQkJCQkJCWlmICh0ZEVsbSAhPSBsYXN0VERFbG0pIHsKCQkJCQkJCQkJCXZhciBzZCA9IGdldENvbFJvd1NwYW4odGRFbG0pOwoKCQkJCQkJCQkJCWlmIChzZFsnY29sc3BhbiddID09IDEpIHsKCQkJCQkJCQkJCQl2YXIgbmV3VEQgPSBkb2MuY3JlYXRlRWxlbWVudCh0ZEVsbS5ub2RlTmFtZSk7CgoJCQkJCQkJCQkJCWlmICghdGlueW1jZS5pc0lFKQoJCQkJCQkJCQkJCQluZXdURC5pbm5lckhUTUwgPSAnPGJyIG1jZV9ib2d1cz0iMSIvPic7CgoJCQkJCQkJCQkJCW5ld1RELnJvd1NwYW4gPSB0ZEVsbS5yb3dTcGFuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvcHkgd2hhdGV2ZXIgc3R5bGUgdGhlIGN1cnJlbnQgY29sdW1uIGhhcy4gIENvcGllcyBoZWFkZXIgcm93cy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdURC5jbGFzc05hbWUgPSB0ZEVsbS5jbGFzc05hbWU7CgoJCQkJCQkJCQkJCXZhciBuZXh0VEQgPSBuZXh0RWxtKHRkRWxtLCAiVEQsVEgiKTsKCQkJCQkJCQkJCQlpZiAobmV4dFREID09IG51bGwpCgkJCQkJCQkJCQkJCXRkRWxtLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQobmV3VEQpOwoJCQkJCQkJCQkJCWVsc2UKCQkJCQkJCQkJCQkJbmV4dFRELnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5ld1RELCBuZXh0VEQpOwoJCQkJCQkJCQkJfSBlbHNlCgkJCQkJCQkJCQkJdGRFbG0uY29sU3BhbisrOwoKCQkJCQkJCQkJCWxhc3RUREVsbSA9IHRkRWxtOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoKCQkJCQkJCQlzZWxlY3QoMSk7CgkJCQkJCQlicmVhazsKCgkJCQkJCQljYXNlICJtY2VUYWJsZURlbGV0ZUNvbCI6CgkJCQkJCQkJaWYgKCF0ckVsbSB8fCAhdGRFbG0pCgkJCQkJCQkJCXJldHVybiB0cnVlOwoKCQkJCQkJCQl2YXIgZ3JpZCA9IGdldFRhYmxlR3JpZCh0YWJsZUVsbSk7CgkJCQkJCQkJdmFyIGNwb3MgPSBnZXRDZWxsUG9zKGdyaWQsIHRkRWxtKTsKCQkJCQkJCQl2YXIgbGFzdFRERWxtID0gbnVsbDsKCgkJCQkJCQkJLy8gT25seSBvbmUgY29sLCByZW1vdmUgd2hvbGUgdGFibGUKCQkJCQkJCQlpZiAoKGdyaWQubGVuZ3RoID4gMSAmJiBncmlkWzBdLmxlbmd0aCA8PSAxKSAmJiB0YWJsZUVsbS5ub2RlTmFtZSA9PSAnVEJPRFknKSB7CgkJCQkJCQkJCWluc3QuZG9tLnJlbW92ZShpbnN0LmRvbS5nZXRQYXJlbnQodGFibGVFbG0sICJ0YWJsZSIpKTsKCQkJCQkJCQkJcmV0dXJuIHRydWU7CgkJCQkJCQkJfQoKCQkJCQkJCQkvLyBEZWxldGUgY2VsbHMKCQkJCQkJCQlmb3IgKHZhciB5PTA7IHRkRWxtID0gZ2V0Q2VsbChncmlkLCB5LCBjcG9zLmNlbGxpbmRleCk7IHkrKykgewoJCQkJCQkJCQlpZiAodGRFbG0gIT0gbGFzdFRERWxtKSB7CgkJCQkJCQkJCQl2YXIgc2QgPSBnZXRDb2xSb3dTcGFuKHRkRWxtKTsKCgkJCQkJCQkJCQlpZiAoc2RbJ2NvbHNwYW4nXSA+IDEpCgkJCQkJCQkJCQkJdGRFbG0uY29sU3BhbiA9IHNkWydjb2xzcGFuJ10gLSAxOwoJCQkJCQkJCQkJZWxzZSB7CgkJCQkJCQkJCQkJaWYgKHRkRWxtLnBhcmVudE5vZGUpCgkJCQkJCQkJCQkJCXRkRWxtLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGRFbG0pOwoJCQkJCQkJCQkJfQoKCQkJCQkJCQkJCWxhc3RUREVsbSA9IHRkRWxtOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoKCQkJCQkJCQlzZWxlY3QoLTEpOwoJCQkJCQkJYnJlYWs7CgoJCQkJCQljYXNlICJtY2VUYWJsZVNwbGl0Q2VsbHMiOgoJCQkJCQkJaWYgKCF0ckVsbSB8fCAhdGRFbG0pCgkJCQkJCQkJcmV0dXJuIHRydWU7CgoJCQkJCQkJdmFyIHNwYW5kYXRhID0gZ2V0Q29sUm93U3Bhbih0ZEVsbSk7CgoJCQkJCQkJdmFyIGNvbHNwYW4gPSBzcGFuZGF0YVsiY29sc3BhbiJdOwoJCQkJCQkJdmFyIHJvd3NwYW4gPSBzcGFuZGF0YVsicm93c3BhbiJdOwoKCQkJCQkJCS8vIE5lZWRzIHNwbGl0dGluZwoJCQkJCQkJaWYgKGNvbHNwYW4gPiAxIHx8IHJvd3NwYW4gPiAxKSB7CgkJCQkJCQkJLy8gR2VuZXJhdGUgY29scwoJCQkJCQkJCXRkRWxtLmNvbFNwYW4gPSAxOwoJCQkJCQkJCWZvciAodmFyIGk9MTsgaTxjb2xzcGFuOyBpKyspIHsKCQkJCQkJCQkJdmFyIG5ld1REID0gZG9jLmNyZWF0ZUVsZW1lbnQoInRkIik7CgoJCQkJCQkJCQlpZiAoIXRpbnltY2UuaXNJRSkKCQkJCQkJCQkJCW5ld1RELmlubmVySFRNTCA9ICc8YnIgbWNlX2JvZ3VzPSIxIi8+JzsKCgkJCQkJCQkJCXRyRWxtLmluc2VydEJlZm9yZShuZXdURCwgbmV4dEVsbSh0ZEVsbSwgIlRELFRIIikpOwoKCQkJCQkJCQkJaWYgKHJvd3NwYW4gPiAxKQoJCQkJCQkJCQkJYWRkUm93cyhuZXdURCwgdHJFbG0sIHJvd3NwYW4pOwoJCQkJCQkJCX0KCgkJCQkJCQkJYWRkUm93cyh0ZEVsbSwgdHJFbG0sIHJvd3NwYW4pOwoJCQkJCQkJfQoKCQkJCQkJCS8vIEFwcGx5IHZpc3VhbCBhaWRzCgkJCQkJCQl0YWJsZUVsbSA9IGluc3QuZG9tLmdldFBhcmVudChpbnN0LnNlbGVjdGlvbi5nZXROb2RlKCksICJ0YWJsZSIpOwoJCQkJCQkJYnJlYWs7CgoJCQkJCQljYXNlICJtY2VUYWJsZU1lcmdlQ2VsbHMiOgoJCQkJCQkJdmFyIHJvd3MgPSBbXTsKCQkJCQkJCXZhciBzZWwgPSBpbnN0LnNlbGVjdGlvbi5nZXRTZWwoKTsKCQkJCQkJCXZhciBncmlkID0gZ2V0VGFibGVHcmlkKHRhYmxlRWxtKTsKCgkJCQkJCQlpZiAodGlueW1jZS5pc0lFIHx8IHNlbC5yYW5nZUNvdW50ID09IDEpIHsKCQkJCQkJCQlpZiAodXNlcl9pbnRlcmZhY2UpIHsKCQkJCQkJCQkJLy8gU2V0dXAgdGVtcGxhdGUKCQkJCQkJCQkJdmFyIHNwID0gZ2V0Q29sUm93U3Bhbih0ZEVsbSk7CgoJCQkJCQkJCQlpbnN0LndpbmRvd01hbmFnZXIub3Blbih7CgkJCQkJCQkJCQl1cmwgOiB1cmwgKyAnL21lcmdlX2NlbGxzLmh0bScsCgkJCQkJCQkJCQl3aWR0aCA6IDI0MCArIHBhcnNlSW50KGluc3QuZ2V0TGFuZygndGFibGUubWVyZ2VfY2VsbHNfZGVsdGFfd2lkdGgnLCAwKSksCgkJCQkJCQkJCQloZWlnaHQgOiAxMTAgKyBwYXJzZUludChpbnN0LmdldExhbmcoJ3RhYmxlLm1lcmdlX2NlbGxzX2RlbHRhX2hlaWdodCcsIDApKSwKCQkJCQkJCQkJCWlubGluZSA6IDEKCQkJCQkJCQkJfSwgewoJCQkJCQkJCQkJYWN0aW9uIDogInVwZGF0ZSIsCgkJCQkJCQkJCQludW1jb2xzIDogc3AuY29sc3BhbiwKCQkJCQkJCQkJCW51bXJvd3MgOiBzcC5yb3dzcGFuLAoJCQkJCQkJCQkJcGx1Z2luX3VybCA6IHVybAoJCQkJCQkJCQl9KTsKCgkJCQkJCQkJCXJldHVybiB0cnVlOwoJCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkJCXZhciBudW1Sb3dzID0gcGFyc2VJbnQodmFsdWVbJ251bXJvd3MnXSk7CgkJCQkJCQkJCXZhciBudW1Db2xzID0gcGFyc2VJbnQodmFsdWVbJ251bWNvbHMnXSk7CgkJCQkJCQkJCXZhciBjcG9zID0gZ2V0Q2VsbFBvcyhncmlkLCB0ZEVsbSk7CgoJCQkJCQkJCQlpZiAoKCIiICsgbnVtUm93cykgPT0gIk5hTiIpCgkJCQkJCQkJCQludW1Sb3dzID0gMTsKCgkJCQkJCQkJCWlmICgoIiIgKyBudW1Db2xzKSA9PSAiTmFOIikKCQkJCQkJCQkJCW51bUNvbHMgPSAxOwoKCQkJCQkJCQkJLy8gR2V0IHJvd3MgYW5kIGNlbGxzCgkJCQkJCQkJCXZhciB0Um93cyA9IHRhYmxlRWxtLnJvd3M7CgkJCQkJCQkJCWZvciAodmFyIHk9Y3Bvcy5yb3dpbmRleDsgeTxncmlkLmxlbmd0aDsgeSsrKSB7CgkJCQkJCQkJCQl2YXIgcm93Q2VsbHMgPSBbXTsKCgkJCQkJCQkJCQlmb3IgKHZhciB4PWNwb3MuY2VsbGluZGV4OyB4PGdyaWRbeV0ubGVuZ3RoOyB4KyspIHsKCQkJCQkJCQkJCQl2YXIgdGQgPSBnZXRDZWxsKGdyaWQsIHksIHgpOwoKCQkJCQkJCQkJCQlpZiAodGQgJiYgIWluQXJyYXkocm93cywgdGQpICYmICFpbkFycmF5KHJvd0NlbGxzLCB0ZCkpIHsKCQkJCQkJCQkJCQkJdmFyIGNwID0gZ2V0Q2VsbFBvcyhncmlkLCB0ZCk7CgoJCQkJCQkJCQkJCQkvLyBXaXRoaW4gcmFuZ2UKCQkJCQkJCQkJCQkJaWYgKGNwLmNlbGxpbmRleCA8IGNwb3MuY2VsbGluZGV4K251bUNvbHMgJiYgY3Aucm93aW5kZXggPCBjcG9zLnJvd2luZGV4K251bVJvd3MpCgkJCQkJCQkJCQkJCQlyb3dDZWxsc1tyb3dDZWxscy5sZW5ndGhdID0gdGQ7CgkJCQkJCQkJCQkJfQoJCQkJCQkJCQkJfQoKCQkJCQkJCQkJCWlmIChyb3dDZWxscy5sZW5ndGggPiAwKQoJCQkJCQkJCQkJCXJvd3Nbcm93cy5sZW5ndGhdID0gcm93Q2VsbHM7CgoJCQkJCQkJCQkJdmFyIHRkID0gZ2V0Q2VsbChncmlkLCBjcG9zLnJvd2luZGV4LCBjcG9zLmNlbGxpbmRleCk7CgkJCQkJCQkJCQllYWNoKGVkLmRvbS5zZWxlY3QoJ2JyJywgdGQpLCBmdW5jdGlvbihlLCBpKSB7CgkJCQkJCQkJCQkJaWYgKGkgPiAwICYmIGVkLmRvbS5nZXRBdHRyaWIoJ21jZV9ib2d1cycpKQoJCQkJCQkJCQkJCQllZC5kb20ucmVtb3ZlKGUpOwoJCQkJCQkJCQkJfSk7CgkJCQkJCQkJCX0KCgkJCQkJCQkJCS8vcmV0dXJuIHRydWU7CgkJCQkJCQkJfQoJCQkJCQkJfSBlbHNlIHsKCQkJCQkJCQl2YXIgY2VsbHMgPSBbXTsKCQkJCQkJCQl2YXIgc2VsID0gaW5zdC5zZWxlY3Rpb24uZ2V0U2VsKCk7CgkJCQkJCQkJdmFyIGxhc3RUUiA9IG51bGw7CgkJCQkJCQkJdmFyIGN1clJvdyA9IG51bGw7CgkJCQkJCQkJdmFyIHgxID0gLTEsIHkxID0gLTEsIHgyLCB5MjsKCgkJCQkJCQkJLy8gT25seSBvbmUgY2VsbCBzZWxlY3RlZCwgd2hhdHMgdGhlIHBvaW50PwoJCQkJCQkJCWlmIChzZWwucmFuZ2VDb3VudCA8IDIpCgkJCQkJCQkJCXJldHVybiB0cnVlOwoKCQkJCQkJCQkvLyBHZXQgYWxsIHNlbGVjdGVkIGNlbGxzCgkJCQkJCQkJZm9yICh2YXIgaT0wOyBpPHNlbC5yYW5nZUNvdW50OyBpKyspIHsKCQkJCQkJCQkJdmFyIHJuZyA9IHNlbC5nZXRSYW5nZUF0KGkpOwoJCQkJCQkJCQl2YXIgdGRFbG0gPSBybmcuc3RhcnRDb250YWluZXIuY2hpbGROb2Rlc1tybmcuc3RhcnRPZmZzZXRdOwoKCQkJCQkJCQkJaWYgKCF0ZEVsbSkKCQkJCQkJCQkJCWJyZWFrOwoKCQkJCQkJCQkJaWYgKHRkRWxtLm5vZGVOYW1lID09ICJURCIgfHwgdGRFbG0ubm9kZU5hbWUgPT0gIlRIIikKCQkJCQkJCQkJCWNlbGxzW2NlbGxzLmxlbmd0aF0gPSB0ZEVsbTsKCQkJCQkJCQl9CgoJCQkJCQkJCS8vIEdldCByb3dzIGFuZCBjZWxscwoJCQkJCQkJCXZhciB0Um93cyA9IHRhYmxlRWxtLnJvd3M7CgkJCQkJCQkJZm9yICh2YXIgeT0wOyB5PHRSb3dzLmxlbmd0aDsgeSsrKSB7CgkJCQkJCQkJCXZhciByb3dDZWxscyA9IFtdOwoKCQkJCQkJCQkJZm9yICh2YXIgeD0wOyB4PHRSb3dzW3ldLmNlbGxzLmxlbmd0aDsgeCsrKSB7CgkJCQkJCQkJCQl2YXIgdGQgPSB0Um93c1t5XS5jZWxsc1t4XTsKCgkJCQkJCQkJCQlmb3IgKHZhciBpPTA7IGk8Y2VsbHMubGVuZ3RoOyBpKyspIHsKCQkJCQkJCQkJCQlpZiAodGQgPT0gY2VsbHNbaV0pIHsKCQkJCQkJCQkJCQkJcm93Q2VsbHNbcm93Q2VsbHMubGVuZ3RoXSA9IHRkOwoJCQkJCQkJCQkJCX0KCQkJCQkJCQkJCX0KCQkJCQkJCQkJfQoKCQkJCQkJCQkJaWYgKHJvd0NlbGxzLmxlbmd0aCA+IDApCgkJCQkJCQkJCQlyb3dzW3Jvd3MubGVuZ3RoXSA9IHJvd0NlbGxzOwoJCQkJCQkJCX0KCgkJCQkJCQkJLy8gRmluZCBzZWxlY3RlZCBjZWxscyBpbiBncmlkIGFuZCBib3gKCQkJCQkJCQl2YXIgY3VyUm93ID0gW107CgkJCQkJCQkJdmFyIGxhc3RUUiA9IG51bGw7CgkJCQkJCQkJZm9yICh2YXIgeT0wOyB5PGdyaWQubGVuZ3RoOyB5KyspIHsKCQkJCQkJCQkJZm9yICh2YXIgeD0wOyB4PGdyaWRbeV0ubGVuZ3RoOyB4KyspIHsKCQkJCQkJCQkJCWdyaWRbeV1beF0uX3NlbGVjdGVkID0gZmFsc2U7CgoJCQkJCQkJCQkJZm9yICh2YXIgaT0wOyBpPGNlbGxzLmxlbmd0aDsgaSsrKSB7CgkJCQkJCQkJCQkJaWYgKGdyaWRbeV1beF0gPT0gY2VsbHNbaV0pIHsKCQkJCQkJCQkJCQkJLy8gR2V0IHN0YXJ0IHBvcwoJCQkJCQkJCQkJCQlpZiAoeDEgPT0gLTEpIHsKCQkJCQkJCQkJCQkJCXgxID0geDsKCQkJCQkJCQkJCQkJCXkxID0geTsKCQkJCQkJCQkJCQkJfQoKCQkJCQkJCQkJCQkJLy8gR2V0IGVuZCBwb3MKCQkJCQkJCQkJCQkJeDIgPSB4OwoJCQkJCQkJCQkJCQl5MiA9IHk7CgoJCQkJCQkJCQkJCQlncmlkW3ldW3hdLl9zZWxlY3RlZCA9IHRydWU7CgkJCQkJCQkJCQkJfQoJCQkJCQkJCQkJfQoJCQkJCQkJCQl9CgkJCQkJCQkJfQoKCQkJCQkJCQkvLyBJcyB0aGVyZSBnYXBzLCBpZiBzbyBkZW55CgkJCQkJCQkJZm9yICh2YXIgeT15MTsgeTw9eTI7IHkrKykgewoJCQkJCQkJCQlmb3IgKHZhciB4PXgxOyB4PD14MjsgeCsrKSB7CgkJCQkJCQkJCQlpZiAoIWdyaWRbeV1beF0uX3NlbGVjdGVkKSB7CgkJCQkJCQkJCQkJYWxlcnQoIkludmFsaWQgc2VsZWN0aW9uIGZvciBtZXJnZS4iKTsKCQkJCQkJCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCQkJCQkJCX0KCQkJCQkJCQkJfQoJCQkJCQkJCX0KCQkJCQkJCX0KCgkJCQkJCQkvLyBWYWxpZGF0ZSBzZWxlY3Rpb24gYW5kIGdldCB0b3RhbCByb3dzcGFuIGFuZCBjb2xzcGFuCgkJCQkJCQl2YXIgcm93U3BhbiA9IDEsIGNvbFNwYW4gPSAxOwoKCQkJCQkJCS8vIFZhbGlkYXRlIGhvcml6b250YWwgYW5kIGdldCB0b3RhbCBjb2xzcGFuCgkJCQkJCQl2YXIgbGFzdFJvd1NwYW4gPSAtMTsKCQkJCQkJCWZvciAodmFyIHk9MDsgeTxyb3dzLmxlbmd0aDsgeSsrKSB7CgkJCQkJCQkJdmFyIHJvd0NvbFNwYW4gPSAwOwoKCQkJCQkJCQlmb3IgKHZhciB4PTA7IHg8cm93c1t5XS5sZW5ndGg7IHgrKykgewoJCQkJCQkJCQl2YXIgc2QgPSBnZXRDb2xSb3dTcGFuKHJvd3NbeV1beF0pOwoKCQkJCQkJCQkJcm93Q29sU3BhbiArPSBzZFsnY29sc3BhbiddOwoKCQkJCQkJCQkJaWYgKGxhc3RSb3dTcGFuICE9IC0xICYmIHNkWydyb3dzcGFuJ10gIT0gbGFzdFJvd1NwYW4pIHsKCQkJCQkJCQkJCWFsZXJ0KCJJbnZhbGlkIHNlbGVjdGlvbiBmb3IgbWVyZ2UuIik7CgkJCQkJCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCQkJCQkJfQoKCQkJCQkJCQkJbGFzdFJvd1NwYW4gPSBzZFsncm93c3BhbiddOwoJCQkJCQkJCX0KCgkJCQkJCQkJaWYgKHJvd0NvbFNwYW4gPiBjb2xTcGFuKQoJCQkJCQkJCQljb2xTcGFuID0gcm93Q29sU3BhbjsKCgkJCQkJCQkJbGFzdFJvd1NwYW4gPSAtMTsKCQkJCQkJCX0KCgkJCQkJCQkvLyBWYWxpZGF0ZSB2ZXJ0aWNhbCBhbmQgZ2V0IHRvdGFsIHJvd3NwYW4KCQkJCQkJCXZhciBsYXN0Q29sU3BhbiA9IC0xOwoJCQkJCQkJZm9yICh2YXIgeD0wOyB4PHJvd3NbMF0ubGVuZ3RoOyB4KyspIHsKCQkJCQkJCQl2YXIgY29sUm93U3BhbiA9IDA7CgoJCQkJCQkJCWZvciAodmFyIHk9MDsgeTxyb3dzLmxlbmd0aDsgeSsrKSB7CgkJCQkJCQkJCXZhciBzZCA9IGdldENvbFJvd1NwYW4ocm93c1t5XVt4XSk7CgoJCQkJCQkJCQljb2xSb3dTcGFuICs9IHNkWydyb3dzcGFuJ107CgoJCQkJCQkJCQlpZiAobGFzdENvbFNwYW4gIT0gLTEgJiYgc2RbJ2NvbHNwYW4nXSAhPSBsYXN0Q29sU3BhbikgewoJCQkJCQkJCQkJYWxlcnQoIkludmFsaWQgc2VsZWN0aW9uIGZvciBtZXJnZS4iKTsKCQkJCQkJCQkJCXJldHVybiB0cnVlOwoJCQkJCQkJCQl9CgoJCQkJCQkJCQlsYXN0Q29sU3BhbiA9IHNkWydjb2xzcGFuJ107CgkJCQkJCQkJfQoKCQkJCQkJCQlpZiAoY29sUm93U3BhbiA+IHJvd1NwYW4pCgkJCQkJCQkJCXJvd1NwYW4gPSBjb2xSb3dTcGFuOwoKCQkJCQkJCQlsYXN0Q29sU3BhbiA9IC0xOwoJCQkJCQkJfQoKCQkJCQkJCS8vIFNldHVwIHRkCgkJCQkJCQl0ZEVsbSA9IHJvd3NbMF1bMF07CgkJCQkJCQl0ZEVsbS5yb3dTcGFuID0gcm93U3BhbjsKCQkJCQkJCXRkRWxtLmNvbFNwYW4gPSBjb2xTcGFuOwoKCQkJCQkJCS8vIE1lcmdlIGNlbGxzCgkJCQkJCQlmb3IgKHZhciB5PTA7IHk8cm93cy5sZW5ndGg7IHkrKykgewoJCQkJCQkJCWZvciAodmFyIHg9MDsgeDxyb3dzW3ldLmxlbmd0aDsgeCsrKSB7CgkJCQkJCQkJCXZhciBodG1sID0gcm93c1t5XVt4XS5pbm5lckhUTUw7CgkJCQkJCQkJCXZhciBjaGsgPSBodG1sLnJlcGxhY2UoL1sgXHRcclxuXS9nLCAiIik7CgoJCQkJCQkJCQlpZiAoY2hrICE9ICI8YnIvPiIgJiYgY2hrICE9ICI8YnI+IiAmJiBjaGsgIT0gJzxiciBtY2VfYm9ndXM9IjEiLz4nICYmICh4K3kgPiAwKSkKCQkJCQkJCQkJCXRkRWxtLmlubmVySFRNTCArPSBodG1sOwoKCQkJCQkJCQkJLy8gTm90IGN1cnJlbnQgY2VsbAoJCQkJCQkJCQlpZiAocm93c1t5XVt4XSAhPSB0ZEVsbSAmJiAhcm93c1t5XVt4XS5fZGVsZXRlZCkgewoJCQkJCQkJCQkJdmFyIGNwb3MgPSBnZXRDZWxsUG9zKGdyaWQsIHJvd3NbeV1beF0pOwoJCQkJCQkJCQkJdmFyIHRyID0gcm93c1t5XVt4XS5wYXJlbnROb2RlOwoKCQkJCQkJCQkJCXRyLnJlbW92ZUNoaWxkKHJvd3NbeV1beF0pOwoJCQkJCQkJCQkJcm93c1t5XVt4XS5fZGVsZXRlZCA9IHRydWU7CgoJCQkJCQkJCQkJLy8gRW1wdHkgVFIsIHJlbW92ZSBpdAoJCQkJCQkJCQkJaWYgKCF0ci5oYXNDaGlsZE5vZGVzKCkpIHsKCQkJCQkJCQkJCQl0ci5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRyKTsKCgkJCQkJCQkJCQkJdmFyIGxhc3RDZWxsID0gbnVsbDsKCQkJCQkJCQkJCQlmb3IgKHZhciB4PTA7IGNlbGxFbG0gPSBnZXRDZWxsKGdyaWQsIGNwb3Mucm93aW5kZXgsIHgpOyB4KyspIHsKCQkJCQkJCQkJCQkJaWYgKGNlbGxFbG0gIT0gbGFzdENlbGwgJiYgY2VsbEVsbS5yb3dTcGFuID4gMSkKCQkJCQkJCQkJCQkJCWNlbGxFbG0ucm93U3Bhbi0tOwoKCQkJCQkJCQkJCQkJbGFzdENlbGwgPSBjZWxsRWxtOwoJCQkJCQkJCQkJCX0KCgkJCQkJCQkJCQkJaWYgKHRkRWxtLnJvd1NwYW4gPiAxKQoJCQkJCQkJCQkJCQl0ZEVsbS5yb3dTcGFuLS07CgkJCQkJCQkJCQl9CgkJCQkJCQkJCX0KCQkJCQkJCQl9CgkJCQkJCQl9CgoJCQkJCQkJLy8gUmVtb3ZlIGFsbCBidXQgb25lIGJvZ3VzIGJyCgkJCQkJCQllYWNoKGVkLmRvbS5zZWxlY3QoJ2JyJywgdGRFbG0pLCBmdW5jdGlvbihlLCBpKSB7CgkJCQkJCQkJaWYgKGkgPiAwICYmIGVkLmRvbS5nZXRBdHRyaWIoZSwgJ21jZV9ib2d1cycpKQoJCQkJCQkJCQllZC5kb20ucmVtb3ZlKGUpOwoJCQkJCQkJfSk7CgoJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCgkJCQkJCXRhYmxlRWxtID0gaW5zdC5kb20uZ2V0UGFyZW50KGluc3Quc2VsZWN0aW9uLmdldE5vZGUoKSwgInRhYmxlIik7CgkJCQkJCWluc3QuYWRkVmlzdWFsKHRhYmxlRWxtKTsKCQkJCQkJaW5zdC5ub2RlQ2hhbmdlZCgpOwoJCQkJCX0KCgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoKCQkJLy8gUGFzcyB0byBuZXh0IGhhbmRsZXIgaW4gY2hhaW4KCQkJcmV0dXJuIGZhbHNlOwoJCX0KCX0pOwoKCS8vIFJlZ2lzdGVyIHBsdWdpbgoJdGlueW1jZS5QbHVnaW5NYW5hZ2VyLmFkZCgndGFibGUnLCB0aW55bWNlLnBsdWdpbnMuVGFibGVQbHVnaW4pOwp9KSgpOwoKLyoqCiAqICRJZDogZWRpdG9yX3BsdWdpbl9zcmMuanMgMTE0MyAyMDA5LTA1LTI3IDEwOjA1OjMxWiBzcG9ja2UgJAogKgogKiBAYXV0aG9yIE1veGllY29kZQogKiBAY29weXJpZ2h0IENvcHlyaWdodCCpIDIwMDQtMjAwOCwgTW94aWVjb2RlIFN5c3RlbXMgQUIsIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqLwoKKGZ1bmN0aW9uKCkgewoJdmFyIGVhY2ggPSB0aW55bWNlLmVhY2g7CgoJdGlueW1jZS5jcmVhdGUoJ3RpbnltY2UucGx1Z2lucy5QYXN0ZVBsdWdpbicsIHsKCQlpbml0IDogZnVuY3Rpb24oZWQsIHVybCkgewoJCQl2YXIgdCA9IHRoaXMsIGNiOwoKCQkJdC5lZGl0b3IgPSBlZDsKCQkJdC51cmwgPSB1cmw7CgoJCQkvLyBTZXR1cCBwbHVnaW4gZXZlbnRzCgkJCXQub25QcmVQcm9jZXNzID0gbmV3IHRpbnltY2UudXRpbC5EaXNwYXRjaGVyKHQpOwoJCQl0Lm9uUG9zdFByb2Nlc3MgPSBuZXcgdGlueW1jZS51dGlsLkRpc3BhdGNoZXIodCk7CgoJCQkvLyBSZWdpc3RlciBkZWZhdWx0IGhhbmRsZXJzCgkJCXQub25QcmVQcm9jZXNzLmFkZCh0Ll9wcmVQcm9jZXNzKTsKCQkJdC5vblBvc3RQcm9jZXNzLmFkZCh0Ll9wb3N0UHJvY2Vzcyk7CgoJCQkvLyBSZWdpc3RlciBvcHRpb25hbCBwcmVwcm9jZXNzIGhhbmRsZXIKCQkJdC5vblByZVByb2Nlc3MuYWRkKGZ1bmN0aW9uKHBsLCBvKSB7CgkJCQllZC5leGVjQ2FsbGJhY2soJ3Bhc3RlX3ByZXByb2Nlc3MnLCBwbCwgbyk7CgkJCX0pOwoKCQkJLy8gUmVnaXN0ZXIgb3B0aW9uYWwgcG9zdHByb2Nlc3MKCQkJdC5vblBvc3RQcm9jZXNzLmFkZChmdW5jdGlvbihwbCwgbykgewoJCQkJZWQuZXhlY0NhbGxiYWNrKCdwYXN0ZV9wb3N0cHJvY2VzcycsIHBsLCBvKTsKCQkJfSk7CgoJCQkvLyBUaGlzIGZ1bmN0aW9uIGV4ZWN1dGVzIHRoZSBwcm9jZXNzIGhhbmRsZXJzIGFuZCBpbnNlcnRzIHRoZSBjb250ZW50cwoJCQlmdW5jdGlvbiBwcm9jZXNzKG8pIHsKCQkJCXZhciBkb20gPSBlZC5kb207CgoJCQkJLy8gRXhlY3V0ZSBwcmUgcHJvY2VzcyBoYW5kbGVycwoJCQkJdC5vblByZVByb2Nlc3MuZGlzcGF0Y2godCwgbyk7CgoJCQkJLy8gQ3JlYXRlIERPTSBzdHJ1Y3R1cmUKCQkJCW8ubm9kZSA9IGRvbS5jcmVhdGUoJ2RpdicsIDAsIG8uY29udGVudCk7CgoJCQkJLy8gRXhlY3V0ZSBwb3N0IHByb2Nlc3MgaGFuZGxlcnMKCQkJCXQub25Qb3N0UHJvY2Vzcy5kaXNwYXRjaCh0LCBvKTsKCgkJCQkvLyBTZXJpYWxpemUgY29udGVudAoJCQkJby5jb250ZW50ID0gZWQuc2VyaWFsaXplci5zZXJpYWxpemUoby5ub2RlLCB7Z2V0SW5uZXIgOiAxfSk7CgoJCQkJLy8gIEluc2VydCBjbGVhbmVkIGNvbnRlbnQuIFdlIG5lZWQgdG8gaGFuZGxlIGluc2VydGlvbiBvZiBjb250ZW50cyBjb250YWluaW5nIGJsb2NrIGVsZW1lbnRzIHNlcGFyYXRlbHkKCQkJCWlmICgvPChwfGhbMS02XXx1bHxvbCkvLnRlc3Qoby5jb250ZW50KSkKCQkJCQl0Ll9pbnNlcnRCbG9ja0NvbnRlbnQoZWQsIGRvbSwgby5jb250ZW50KTsKCQkJCWVsc2UKCQkJCQl0Ll9pbnNlcnQoby5jb250ZW50KTsKCQkJfTsKCgkJCS8vIEFkZCBjb21tYW5kIGZvciBleHRlcm5hbCB1c2FnZQoJCQllZC5hZGRDb21tYW5kKCdtY2VJbnNlcnRDbGlwYm9hcmRDb250ZW50JywgZnVuY3Rpb24odSwgbykgewoJCQkJcHJvY2VzcyhvKTsKCQkJfSk7CgoJCQkvLyBUaGlzIGZ1bmN0aW9uIGdyYWJzIHRoZSBjb250ZW50cyBmcm9tIHRoZSBjbGlwYm9hcmQgYnkgYWRkaW5nIGEKCQkJLy8gaGlkZGVuIGRpdiBhbmQgcGxhY2luZyB0aGUgY2FyZXQgaW5zaWRlIGl0IGFuZCBhZnRlciB0aGUgYnJvd3NlciBwYXN0ZQoJCQkvLyBpcyBkb25lIGl0IGdyYWJzIHRoYXQgY29udGVudHMgYW5kIHByb2Nlc3NlcyB0aGF0CgkJCWZ1bmN0aW9uIGdyYWJDb250ZW50KGUpIHsKCQkJCXZhciBuLCBvciwgcm5nLCBzZWwgPSBlZC5zZWxlY3Rpb24sIGRvbSA9IGVkLmRvbSwgYm9keSA9IGVkLmdldEJvZHkoKSwgcG9zWTsKCgkJCQlpZiAoZG9tLmdldCgnX21jZVBhc3RlJykpCgkJCQkJcmV0dXJuOwoKCQkJCS8vIENyZWF0ZSBjb250YWluZXIgdG8gcGFzdGUgaW50bwoJCQkJbiA9IGRvbS5hZGQoYm9keSwgJ2RpdicsIHtpZCA6ICdfbWNlUGFzdGUnfSwgJyZuYnNwOycpOwoKCQkJCS8vIElmIGNvbnRlbnRFZGl0YWJsZSBtb2RlIHdlIG5lZWQgdG8gZmluZCBvdXQgdGhlIHBvc2l0aW9uIG9mIHRoZSBjbG9zZXN0IGVsZW1lbnQKCQkJCWlmIChib2R5ICE9IGVkLmdldERvYygpLmJvZHkpCgkJCQkJcG9zWSA9IGRvbS5nZXRQb3MoZWQuc2VsZWN0aW9uLmdldFN0YXJ0KCksIGJvZHkpLnk7CgkJCQllbHNlCgkJCQkJcG9zWSA9IGJvZHkuc2Nyb2xsVG9wOwoKCQkJCS8vIFN0eWxlcyBuZWVkcyB0byBiZSBhcHBsaWVkIGFmdGVyIHRoZSBlbGVtZW50IGlzIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBzaW5jZSBXZWJLaXQgd2lsbCBvdGhlcndpc2UgcmVtb3ZlIGFsbCBzdHlsZXMKCQkJCWRvbS5zZXRTdHlsZXMobiwgewoJCQkJCXBvc2l0aW9uIDogJ2Fic29sdXRlJywKCQkJCQlsZWZ0IDogLTEwMDAwLAoJCQkJCXRvcCA6IHBvc1ksCgkJCQkJd2lkdGggOiAxLAoJCQkJCWhlaWdodCA6IDEsCgkJCQkJb3ZlcmZsb3cgOiAnaGlkZGVuJwoJCQkJfSk7CgoJCQkJaWYgKHRpbnltY2UuaXNJRSkgewoJCQkJCS8vIFNlbGVjdCB0aGUgY29udGFpbmVyCgkJCQkJcm5nID0gZG9tLmRvYy5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpOwoJCQkJCXJuZy5tb3ZlVG9FbGVtZW50VGV4dChuKTsKCQkJCQlybmcuZXhlY0NvbW1hbmQoJ1Bhc3RlJyk7CgoJCQkJCS8vIFJlbW92ZSBjb250YWluZXIKCQkJCQlkb20ucmVtb3ZlKG4pOwoKCQkJCQkvLyBQcm9jZXNzIGNvbnRlbnRzCgkJCQkJcHJvY2Vzcyh7Y29udGVudCA6IG4uaW5uZXJIVE1MfSk7CgoJCQkJCXJldHVybiB0aW55bWNlLmRvbS5FdmVudC5jYW5jZWwoZSk7CgkJCQl9IGVsc2UgewoJCQkJCW9yID0gZWQuc2VsZWN0aW9uLmdldFJuZygpOwoKCQkJCQkvLyBNb3ZlIGNhcmV0IGludG8gaGlkZGVuIGRpdgoJCQkJCW4gPSBuLmZpcnN0Q2hpbGQ7CgkJCQkJcm5nID0gZWQuZ2V0RG9jKCkuY3JlYXRlUmFuZ2UoKTsKCQkJCQlybmcuc2V0U3RhcnQobiwgMCk7CgkJCQkJcm5nLnNldEVuZChuLCAxKTsKCQkJCQlzZWwuc2V0Um5nKHJuZyk7CgoJCQkJCS8vIFdhaXQgYSB3aGlsZSBhbmQgZ3JhYiB0aGUgcGFzdGVkIGNvbnRlbnRzCgkJCQkJd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7CgkJCQkJCXZhciBuID0gZG9tLmdldCgnX21jZVBhc3RlJyksIGg7CgoJCQkJCQkvLyBXZWJraXQgY2xvbmVzIHRoZSBfbWNlUGFzdGUgZGl2IGZvciBzb21lIG9kZCByZWFzb24gc28gdGhpcyB3aWxsIGVuc3VyZSB0aGF0IHdlIGdldCB0aGUgcmVhbCBuZXcgZGl2IG5vdCB0aGUgb2xkIGVtcHR5IG9uZQoJCQkJCQluLmlkID0gJ19tY2VSZW1vdmVkJzsKCQkJCQkJZG9tLnJlbW92ZShuKTsKCQkJCQkJbiA9IGRvbS5nZXQoJ19tY2VQYXN0ZScpIHx8IG47CgoJCQkJCQkvLyBHcmFiIHRoZSBIVE1MIGNvbnRlbnRzCgkJCQkJCS8vIFdlIG5lZWQgdG8gbG9vayBmb3IgYSBhcHBsZSBzdHlsZSB3cmFwcGVyIG9uIHdlYmtpdCBpdCBhbHNvIGFkZHMgYSBkaXYgd3JhcHBlciBpZiB5b3UgY29weS9wYXN0ZSB0aGUgYm9keSBvZiB0aGUgZWRpdG9yCgkJCQkJCS8vIEl0J3MgYW1hemluZyBob3cgc3RyYW5nZSB0aGUgY29udGVudEVkaXRhYmxlIG1vZGUgd29ya3MgaW4gV2ViS2l0CgkJCQkJCWggPSAoZG9tLnNlbGVjdCgnPiBzcGFuLkFwcGxlLXN0eWxlLXNwYW4gZGl2JywgbilbMF0gfHwgZG9tLnNlbGVjdCgnPiBzcGFuLkFwcGxlLXN0eWxlLXNwYW4nLCBuKVswXSB8fCBuKS5pbm5lckhUTUw7CgoJCQkJCQkvLyBSZW1vdmUgaGlkZGVuIGRpdiBhbmQgcmVzdG9yZSBzZWxlY3Rpb24KCQkJCQkJZG9tLnJlbW92ZShuKTsKCgkJCQkJCS8vIFJlc3RvcmUgdGhlIG9sZCBzZWxlY3Rpb24KCQkJCQkJaWYgKG9yKQoJCQkJCQkJc2VsLnNldFJuZyhvcik7CgoJCQkJCQlwcm9jZXNzKHtjb250ZW50IDogaH0pOwoJCQkJCX0sIDApOwoJCQkJfQoJCQl9OwoKCQkJLy8gQ2hlY2sgaWYgd2Ugc2hvdWxkIHVzZSB0aGUgbmV3IGF1dG8gcHJvY2VzcyBtZXRob2QJCQkKCQkJaWYgKGVkLmdldFBhcmFtKCdwYXN0ZV9hdXRvX2NsZWFudXBfb25fcGFzdGUnLCB0cnVlKSkgewoJCQkJLy8gSXMgaXQncyBPcGVyYSBvciBvbGRlciBGRiB1c2Uga2V5IGhhbmRsZXIKCQkJCWlmICh0aW55bWNlLmlzT3BlcmEgfHwgL0ZpcmVmb3hcLzIvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHsKCQkJCQllZC5vbktleURvd24uYWRkKGZ1bmN0aW9uKGVkLCBlKSB7CgkJCQkJCWlmICgoKHRpbnltY2UuaXNNYWMgPyBlLm1ldGFLZXkgOiBlLmN0cmxLZXkpICYmIGUua2V5Q29kZSA9PSA4NikgfHwgKGUuc2hpZnRLZXkgJiYgZS5rZXlDb2RlID09IDQ1KSkKCQkJCQkJCWdyYWJDb250ZW50KGUpOwoJCQkJCX0pOwoJCQkJfSBlbHNlIHsKCQkJCQkvLyBHcmFiIGNvbnRlbnRzIG9uIHBhc3RlIGV2ZW50IG9uIEdlY2tvIGFuZCBXZWJLaXQKCQkJCQllZC5vblBhc3RlLmFkZFRvVG9wKGZ1bmN0aW9uKGVkLCBlKSB7CgkJCQkJCXJldHVybiBncmFiQ29udGVudChlKTsKCQkJCQl9KTsKCQkJCX0KCQkJfQoKCQkJLy8gQmxvY2sgYWxsIGRyYWcvZHJvcCBldmVudHMKCQkJaWYgKGVkLmdldFBhcmFtKCdwYXN0ZV9ibG9ja19kcm9wJykpIHsKCQkJCWVkLm9uSW5pdC5hZGQoZnVuY3Rpb24oKSB7CgkJCQkJZWQuZG9tLmJpbmQoZWQuZ2V0Qm9keSgpLCBbJ2RyYWdlbmQnLCAnZHJhZ292ZXInLCAnZHJhZ2dlc3R1cmUnLCAnZHJhZ2Ryb3AnLCAnZHJvcCcsICdkcmFnJ10sIGZ1bmN0aW9uKGUpIHsKCQkJCQkJZS5wcmV2ZW50RGVmYXVsdCgpOwoJCQkJCQllLnN0b3BQcm9wYWdhdGlvbigpOwoKCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCX0pOwoJCQkJfSk7CgkJCX0KCgkJCS8vIEFkZCBsZWdhY3kgc3VwcG9ydAoJCQl0Ll9sZWdhY3lTdXBwb3J0KCk7CgkJfSwKCgkJZ2V0SW5mbyA6IGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gewoJCQkJbG9uZ25hbWUgOiAnUGFzdGUgdGV4dC93b3JkJywKCQkJCWF1dGhvciA6ICdNb3hpZWNvZGUgU3lzdGVtcyBBQicsCgkJCQlhdXRob3J1cmwgOiAnaHR0cDovL3RpbnltY2UubW94aWVjb2RlLmNvbS8nLAoJCQkJaW5mb3VybCA6ICdodHRwOi8vd2lraS5tb3hpZWNvZGUuY29tL2luZGV4LnBocC9UaW55TUNFOlBsdWdpbnMvcGFzdGUnLAoJCQkJdmVyc2lvbiA6IHRpbnltY2UubWFqb3JWZXJzaW9uICsgIi4iICsgdGlueW1jZS5taW5vclZlcnNpb24KCQkJfTsKCQl9LAoKCQlfcHJlUHJvY2VzcyA6IGZ1bmN0aW9uKHBsLCBvKSB7CgkJCXZhciBlZCA9IHRoaXMuZWRpdG9yLCBoID0gby5jb250ZW50LCBwcm9jZXNzLCBzdHJpcENsYXNzOwoKCQkJLy9jb25zb2xlLmxvZygnQmVmb3JlIHByZXByb2Nlc3M6JyArIG8uY29udGVudCk7CgoJCQlmdW5jdGlvbiBwcm9jZXNzKGl0ZW1zKSB7CgkJCQllYWNoKGl0ZW1zLCBmdW5jdGlvbih2KSB7CgkJCQkJLy8gUmVtb3ZlIG9yIHJlcGxhY2UKCQkJCQlpZiAodi5jb25zdHJ1Y3RvciA9PSBSZWdFeHApCgkJCQkJCWggPSBoLnJlcGxhY2UodiwgJycpOwoJCQkJCWVsc2UKCQkJCQkJaCA9IGgucmVwbGFjZSh2WzBdLCB2WzFdKTsKCQkJCX0pOwoJCQl9OwoKCQkJLy8gUHJvY2VzcyBhd2F5IHNvbWUgYmFzaWMgY29udGVudAoJCQlwcm9jZXNzKFsKCQkJCS9eXHMqKCZuYnNwOykrL2csCQkJCQkJCQkJCQkvLyBuYnNwIGVudGl0aWVzIGF0IHRoZSBzdGFydCBvZiBjb250ZW50cwoJCQkJLygmbmJzcDt8PGJyW14+XSo+KStccyokL2cJCQkJCQkJCQkvLyBuYnNwIGVudGl0aWVzIGF0IHRoZSBlbmQgb2YgY29udGVudHMKCQkJXSk7CgoJCQkvLyBEZXRlY3QgV29yZCBjb250ZW50IGFuZCBwcm9jZXNzIGl0IG1vcmUgYWdncmVzc2l2ZQoJCQlpZiAoLyhjbGFzcz1cIj9Nc298c3R5bGU9XCJbXlwiXSpcYm1zb1wtfHc6V29yZERvY3VtZW50KS8udGVzdChoKSB8fCBvLndvcmRDb250ZW50KSB7CgkJCQlvLndvcmRDb250ZW50ID0gdHJ1ZTsgLy8gTWFyayB0aGUgcGFzdGVkIGNvbnRlbnRzIGFzIHdvcmQgc3BlY2lmaWMgY29udGVudAoJCQkJLy9jb25zb2xlLmxvZygnV29yZCBjb250ZW50cyBkZXRlY3RlZC4nKTsKCgkJCQlpZiAoZWQuZ2V0UGFyYW0oJ3Bhc3RlX2NvbnZlcnRfbWlkZG90X2xpc3RzJywgdHJ1ZSkpIHsKCQkJCQlwcm9jZXNzKFsKCQkJCQkJWy88IS0tXFtpZiAhc3VwcG9ydExpc3RzXF0tLT4vZ2ksICckJl9fTUNFX0lURU1fXyddLAkJCS8vIENvbnZlcnQgc3VwcG9ydExpc3RzIHRvIGEgbGlzdCBpdGVtIG1hcmtlcgoJCQkJCQlbLyg8c3BhbltePl0rOlxzKnN5bWJvbFtePl0rPikvZ2ksICckMV9fTUNFX0lURU1fXyddLAkJCQkvLyBDb252ZXJ0IHN5bWJvbCBzcGFucyB0byBsaXN0IGl0ZW1zCgkJCQkJCVsvKDxzcGFuW14+XSttc28tbGlzdDpbXj5dKz4pL2dpLCAnJDFfX01DRV9JVEVNX18nXQkJCQkvLyBDb252ZXJ0IG1zby1saXN0IHRvIGl0ZW0gbWFya2VyCgkJCQkJXSk7CgkJCQl9CgoJCQkJcHJvY2VzcyhbCgkJCQkJLzwhLS1bXHNcU10rPy0tPi9naSwJCQkJCQkJCQkJCQkvLyBXb3JkIGNvbW1lbnRzCgkJCQkJLzxcLz8oaW1nfGZvbnR8bWV0YXxsaW5rfHN0eWxlfGRpdnx2Olx3KylbXj5dKj4vZ2ksCQkJCQkvLyBSZW1vdmUgc29tZSB0YWdzIGluY2x1ZGluZyBWTUwgY29udGVudAoJCQkJCS88XFw/XD94bWxbXj5dKj4vZ2ksCQkJCQkJCQkJCQkJLy8gWE1MIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMKCQkJCQkvPFwvP286W14+XSo+L2dpLAkJCQkJCQkJCQkJCQkvLyBNUyBuYW1lc3BhY2VkIGVsZW1lbnRzIDxvOnRhZz4KCQkJCQkvIChpZHxuYW1lfGxhbmd1YWdlfHR5cGV8b25cdyt8djpcdyspPVwiKFteXCJdKilcIi9naSwJCQkJLy8gb24uLiwgY2xhc3MsIHN0eWxlIGFuZCBsYW5ndWFnZSBhdHRyaWJ1dGVzIHdpdGggcXVvdGVzCgkJCQkJLyAoaWR8bmFtZXxsYW5ndWFnZXx0eXBlfG9uXHcrfHY6XHcrKT0oXHcrKS9naSwJCQkJCQkvLyBvbi4uLCBjbGFzcywgc3R5bGUgYW5kIGxhbmd1YWdlIGF0dHJpYnV0ZXMgd2l0aG91dCBxdW90ZXMgKElFKQoJCQkJCVsvPChcLz8pcz4vZ2ksICc8JDFzdHJpa2U+J10sCQkJCQkJCQkJCS8vIENvbnZlcnQgPHM+IGludG8gPHN0cmlrZT4gZm9yIGxpbmUtdGhvdWdoCgkJCQkJLzxzY3JpcHRbXj5dKz5bXHNcU10qPzxcL3NjcmlwdD4vZ2ksCQkJCQkJCQkvLyBBbGwgc2NyaXB0cyBlbGVtZW50cyBmb3IgbXNvU2hvd0NvbW1lbnQgZm9yIGV4YW1wbGUKCQkJCQlbLyZuYnNwOy9nLCAnXHUwMGEwJ10JCQkJCQkJCQkJCQkvLyBSZXBsYWNlIG5zYnAgZW50aXRlcyB0byBjaGFyIHNpbmNlIGl0J3MgZWFzaWVyIHRvIGhhbmRsZQoJCQkJXSk7CgoJCQkJLy8gUmVtb3ZlIGFsbCBzcGFucyBpZiBubyBzdHlsZXMgaXMgdG8gYmUgcmV0YWluZWQKCQkJCWlmICghZWQuZ2V0UGFyYW0oJ3Bhc3RlX3JldGFpbl9zdHlsZV9wcm9wZXJ0aWVzJykpIHsKCQkJCQlwcm9jZXNzKFsKCQkJCQkJLzxcLz8oc3BhbilbXj5dKj4vZ2kKCQkJCQldKTsKCQkJCX0KCQkJfQoKCQkJLy8gQWxsb3cgZm9yIGNsYXNzIG5hbWVzIHRvIGJlIHJldGFpbmVkIGlmIGRlc2lyZWQ7IGVpdGhlciBhbGwsIG9yIGp1c3QgdGhlIG9uZXMgZnJvbSBXb3JkCgkJCS8vIE5vdGUgdGhhdCB0aGUgcGFzdGVfc3RyaXBfY2xhc3NfYXR0cmlidXRlczogJ25vbmUsIHZlcmlmeV9jc3NfY2xhc3NlczogdHJ1ZSBpcyBhbHNvIGEgZ29vZCB2YXJpYXRpb24uCgkJCXN0cmlwQ2xhc3MgPSBlZC5nZXRQYXJhbSgncGFzdGVfc3RyaXBfY2xhc3NfYXR0cmlidXRlcycsICdhbGwnKTsKCQkJaWYgKHN0cmlwQ2xhc3MgIT0gJ25vbmUnKSB7CgkJCQlpZiAoc3RyaXBDbGFzcyA9PSAnYWxsJykgewoJCQkJCXByb2Nlc3MoWwoJCQkJCQkvIGNsYXNzPVwiKFteXCJdKilcIi9naSwJLy8gY2xhc3MgYXR0cmlidXRlcyB3aXRoIHF1b3RlcwoJCQkJCQkvIGNsYXNzPShcdyspL2dpCQkJLy8gY2xhc3MgYXR0cmlidXRlcyB3aXRob3V0IHF1b3RlcyAoSUUpCgkJCQkJXSk7CgkJCQl9IGVsc2UgeyAvLyBPbmx5IHN0cmlwIHRoZSAnbXNvKicgY2xhc3NlcwoJCQkJCXByb2Nlc3MoWwoJCQkJCQkvIGNsYXNzPVwiKG1zb1teXCJdKilcIi9naSwJLy8gY2xhc3MgYXR0cmlidXRlcyB3aXRoIHF1b3RlcwoJCQkJCQkvIGNsYXNzPShtc29cdyspL2dpCQkJLy8gY2xhc3MgYXR0cmlidXRlcyB3aXRob3V0IHF1b3RlcyAoSUUpCgkJCQkJXSk7CgkJCQl9CgkJCX0KCgkJCS8vIFJlbW92ZSBzcGFucyBvcHRpb24KCQkJaWYgKGVkLmdldFBhcmFtKCdwYXN0ZV9yZW1vdmVfc3BhbnMnKSkgewoJCQkJcHJvY2VzcyhbCgkJCQkJLzxcLz8oc3BhbilbXj5dKj4vZ2kKCQkJCV0pOwoJCQl9CgoJCQkvL2NvbnNvbGUubG9nKCdBZnRlciBwcmVwcm9jZXNzOicgKyBoKTsKCgkJCW8uY29udGVudCA9IGg7CgkJfSwKCgkJLyoqCgkJICogVmFyaW91cyBwb3N0IHByb2Nlc3MgaXRlbXMuCgkJICovCgkJX3Bvc3RQcm9jZXNzIDogZnVuY3Rpb24ocGwsIG8pIHsKCQkJdmFyIHQgPSB0aGlzLCBlZCA9IHQuZWRpdG9yLCBkb20gPSBlZC5kb20sIHN0eWxlUHJvcHM7CgoJCQlpZiAoby53b3JkQ29udGVudCkgewoJCQkJLy8gUmVtb3ZlIG5hbWVkIGFuY2hvcnMgb3IgVE9DIGxpbmtzCgkJCQllYWNoKGRvbS5zZWxlY3QoJ2EnLCBvLm5vZGUpLCBmdW5jdGlvbihhKSB7CgkJCQkJaWYgKCFhLmhyZWYgfHwgYS5ocmVmLmluZGV4T2YoJyNfVG9jJykgIT0gLTEpCgkJCQkJCWRvbS5yZW1vdmUoYSwgMSk7CgkJCQl9KTsKCgkJCQlpZiAodC5lZGl0b3IuZ2V0UGFyYW0oJ3Bhc3RlX2NvbnZlcnRfbWlkZG90X2xpc3RzJywgdHJ1ZSkpCgkJCQkJdC5fY29udmVydExpc3RzKHBsLCBvKTsKCgkJCQkvLyBQcm9jZXNzIHN0eWxlcwoJCQkJc3R5bGVQcm9wcyA9IGVkLmdldFBhcmFtKCdwYXN0ZV9yZXRhaW5fc3R5bGVfcHJvcGVydGllcycpOyAvLyByZXRhaW5lZCBwcm9wZXJ0aWVzCgoJCQkJLy8gSWYgc3RyaW5nIHByb3BlcnR5IHRoZW4gc3BsaXQgaXQKCQkJCWlmICh0aW55bWNlLmlzKHN0eWxlUHJvcHMsICdzdHJpbmcnKSkKCQkJCQlzdHlsZVByb3BzID0gdGlueW1jZS5leHBsb2RlKHN0eWxlUHJvcHMpOwoKCQkJCS8vIFJldGFpbnMgc29tZSBzdHlsZSBwcm9wZXJ0aWVzCgkJCQllYWNoKGRvbS5zZWxlY3QoJyonLCBvLm5vZGUpLCBmdW5jdGlvbihlbCkgewoJCQkJCXZhciBuZXdTdHlsZSA9IHt9LCBucGMgPSAwLCBpLCBzcCwgc3Y7CgoJCQkJCS8vIFN0b3JlIGEgc3Vic2V0IG9mIHRoZSBleGlzdGluZyBzdHlsZXMKCQkJCQlpZiAoc3R5bGVQcm9wcykgewoJCQkJCQlmb3IgKGkgPSAwOyBpIDwgc3R5bGVQcm9wcy5sZW5ndGg7IGkrKykgewoJCQkJCQkJc3AgPSBzdHlsZVByb3BzW2ldOwoJCQkJCQkJc3YgPSBkb20uZ2V0U3R5bGUoZWwsIHNwKTsKCgkJCQkJCQlpZiAoc3YpIHsKCQkJCQkJCQluZXdTdHlsZVtzcF0gPSBzdjsKCQkJCQkJCQlucGMrKzsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCgkJCQkJLy8gUmVtb3ZlIGFsbCBvZiB0aGUgZXhpc3Rpbmcgc3R5bGVzCgkJCQkJZG9tLnNldEF0dHJpYihlbCwgJ3N0eWxlJywgJycpOwoKCQkJCQlpZiAoc3R5bGVQcm9wcyAmJiBucGMgPiAwKQoJCQkJCQlkb20uc2V0U3R5bGVzKGVsLCBuZXdTdHlsZSk7IC8vIEFkZCBiYWNrIHRoZSBzdG9yZWQgc3Vic2V0IG9mIHN0eWxlcwoJCQkJCWVsc2UgLy8gUmVtb3ZlIGVtcHR5IHNwYW4gdGFncyB0aGF0IGRvIG5vdCBoYXZlIGNsYXNzIGF0dHJpYnV0ZXMKCQkJCQkJaWYgKGVsLm5vZGVOYW1lID09ICdTUEFOJyAmJiAhZWwuY2xhc3NOYW1lKQoJCQkJCQkJZG9tLnJlbW92ZShlbCwgdHJ1ZSk7CgkJCQl9KTsKCQkJfQoKCQkJLy8gUmVtb3ZlIGFsbCBzdHlsZSBpbmZvcm1hdGlvbiBvciBvbmx5IHNwZWNpZmljYWxseSBvbiBXZWJLaXQgdG8gYXZvaWQgdGhlIHN0eWxlIGJ1ZyBvbiB0aGF0IGJyb3dzZXIKCQkJaWYgKGVkLmdldFBhcmFtKCJwYXN0ZV9yZW1vdmVfc3R5bGVzIikgfHwgKGVkLmdldFBhcmFtKCJwYXN0ZV9yZW1vdmVfc3R5bGVzX2lmX3dlYmtpdCIpICYmIHRpbnltY2UuaXNXZWJLaXQpKSB7CgkJCQllYWNoKGRvbS5zZWxlY3QoJypbc3R5bGVdJywgby5ub2RlKSwgZnVuY3Rpb24oZWwpIHsKCQkJCQllbC5yZW1vdmVBdHRyaWJ1dGUoJ3N0eWxlJyk7CgkJCQkJZWwucmVtb3ZlQXR0cmlidXRlKCdtY2Vfc3R5bGUnKTsKCQkJCX0pOwoJCQl9IGVsc2UgewoJCQkJaWYgKHRpbnltY2UuaXNXZWJLaXQpIHsKCQkJCQkvLyBXZSBuZWVkIHRvIGNvbXByZXNzIHRoZSBzdHlsZXMgb24gV2ViS2l0IHNpbmNlIGlmIHlvdSBwYXN0ZSA8aW1nIGJvcmRlcj0iMCIgLz4gaXQgd2lsbCBiZWNvbWUgPGltZyBib3JkZXI9IjAiIHN0eWxlPSIuLi4gbG90cyBvZiBqdW5rIC4uLiIgLz4KCQkJCQkvLyBSZW1vdmluZyB0aGUgbWNlX3N0eWxlIHRoYXQgY29udGFpbnMgdGhlIHJlYWwgdmFsdWUgd2lsbCBmb3JjZSB0aGUgU2VyaWFsaXplciBlbmdpbmUgdG8gY29tcHJlc3MgdGhlIHN0eWxlcwoJCQkJCWVhY2goZG9tLnNlbGVjdCgnKicsIG8ubm9kZSksIGZ1bmN0aW9uKGVsKSB7CgkJCQkJCWVsLnJlbW92ZUF0dHJpYnV0ZSgnbWNlX3N0eWxlJyk7CgkJCQkJfSk7CgkJCQl9CgkJCX0KCQl9LAoKCQkvKioKCQkgKiBDb252ZXJ0cyB0aGUgbW9zdCBjb21tb24gYnVsbGV0IGFuZCBudW1iZXIgZm9ybWF0cyBpbiBPZmZpY2UgaW50byBhIHJlYWwgc2VtYW50aWMgVUwvTEkgbGlzdC4KCQkgKi8KCQlfY29udmVydExpc3RzIDogZnVuY3Rpb24ocGwsIG8pIHsKCQkJdmFyIGRvbSA9IHBsLmVkaXRvci5kb20sIGxpc3RFbG0sIGxpLCBsYXN0TWFyZ2luID0gLTEsIG1hcmdpbiwgbGV2ZWxzID0gW10sIGxhc3RUeXBlLCBodG1sOwoKCQkJLy8gQ29udmVydCBtaWRkb3QgbGlzdHMgaW50byByZWFsIHNlbWFudGljIGxpc3RzCgkJCWVhY2goZG9tLnNlbGVjdCgncCcsIG8ubm9kZSksIGZ1bmN0aW9uKHApIHsKCQkJCXZhciBzaWIsIHZhbCA9ICcnLCB0eXBlLCBodG1sLCBpZHgsIHBhcmVudHM7CgoJCQkJLy8gR2V0IHRleHQgbm9kZSB2YWx1ZSBhdCBiZWdpbm5pbmcgb2YgcGFyYWdyYXBoCgkJCQlmb3IgKHNpYiA9IHAuZmlyc3RDaGlsZDsgc2liICYmIHNpYi5ub2RlVHlwZSA9PSAzOyBzaWIgPSBzaWIubmV4dFNpYmxpbmcpCgkJCQkJdmFsICs9IHNpYi5ub2RlVmFsdWU7CgoJCQkJdmFsID0gcC5pbm5lckhUTUwucmVwbGFjZSgvPFwvP1x3K1tePl0qPi9naSwgJycpLnJlcGxhY2UoLyZuYnNwOy9nLCAnXHUwMGEwJyk7CgoJCQkJLy8gRGV0ZWN0IHVub3JkZXJlZCBsaXN0cyBsb29rIGZvciBidWxsZXRzCgkJCQlpZiAoL14oX19NQ0VfSVRFTV9fKStbXHUyMDIyXHUwMGI3XHUwMGE3XHUwMGQ4b11ccypcdTAwYTAqLy50ZXN0KHZhbCkpCgkJCQkJdHlwZSA9ICd1bCc7CgoJCQkJLy8gRGV0ZWN0IG9yZGVyZWQgbGlzdHMgMS4sIGEuIG9yIGl4di4KCQkJCWlmICgvXl9fTUNFX0lURU1fX1xzKlx3K1wuXHMqXHUwMGEwezIsfS8udGVzdCh2YWwpKQoJCQkJCXR5cGUgPSAnb2wnOwoKCQkJCS8vIENoZWNrIGlmIG5vZGUgdmFsdWUgbWF0Y2hlcyB0aGUgbGlzdCBwYXR0ZXJuOiBvJm5ic3A7Jm5ic3A7CgkJCQlpZiAodHlwZSkgewoJCQkJCW1hcmdpbiA9IHBhcnNlRmxvYXQocC5zdHlsZS5tYXJnaW5MZWZ0IHx8IDApOwoKCQkJCQlpZiAobWFyZ2luID4gbGFzdE1hcmdpbikKCQkJCQkJbGV2ZWxzLnB1c2gobWFyZ2luKTsKCgkJCQkJaWYgKCFsaXN0RWxtIHx8IHR5cGUgIT0gbGFzdFR5cGUpIHsKCQkJCQkJbGlzdEVsbSA9IGRvbS5jcmVhdGUodHlwZSk7CgkJCQkJCWRvbS5pbnNlcnRBZnRlcihsaXN0RWxtLCBwKTsKCQkJCQl9IGVsc2UgewoJCQkJCQkvLyBOZXN0ZWQgbGlzdCBlbGVtZW50CgkJCQkJCWlmIChtYXJnaW4gPiBsYXN0TWFyZ2luKSB7CgkJCQkJCQlsaXN0RWxtID0gbGkuYXBwZW5kQ2hpbGQoZG9tLmNyZWF0ZSh0eXBlKSk7CgkJCQkJCX0gZWxzZSBpZiAobWFyZ2luIDwgbGFzdE1hcmdpbikgewoJCQkJCQkJLy8gRmluZCBwYXJlbnQgbGV2ZWwgYmFzZWQgb24gbWFyZ2luIHZhbHVlCgkJCQkJCQlpZHggPSB0aW55bWNlLmluQXJyYXkobGV2ZWxzLCBtYXJnaW4pOwoJCQkJCQkJcGFyZW50cyA9IGRvbS5nZXRQYXJlbnRzKGxpc3RFbG0ucGFyZW50Tm9kZSwgdHlwZSk7CgkJCQkJCQlsaXN0RWxtID0gcGFyZW50c1twYXJlbnRzLmxlbmd0aCAtIDEgLSBpZHhdIHx8IGxpc3RFbG07CgkJCQkJCX0KCQkJCQl9CgoJCQkJCS8vIFJlbW92ZSBtaWRkb3Qgb3IgbnVtYmVyIHNwYW5zIGlmIHRoZXkgZXhpc3RzCgkJCQkJZWFjaChkb20uc2VsZWN0KCdzcGFuJywgcCksIGZ1bmN0aW9uKHNwYW4pIHsKCQkJCQkJdmFyIGh0bWwgPSBzcGFuLmlubmVySFRNTC5yZXBsYWNlKC88XC8/XHcrW14+XSo+L2dpLCAnJyk7CgoJCQkJCQkvLyBSZW1vdmUgc3BhbiB3aXRoIHRoZSBtaWRkb3Qgb3IgdGhlIG51bWJlcgoJCQkJCQlpZiAodHlwZSA9PSAndWwnICYmIC9eW1x1MjAyMlx1MDBiN1x1MDBhN1x1MDBkOG9dLy50ZXN0KGh0bWwpKQoJCQkJCQkJZG9tLnJlbW92ZShzcGFuKTsKCQkJCQkJZWxzZSBpZiAoL15bXHNcU10qXHcrXC4oJm5ic3A7fFx1MDBhMCkqXHMqLy50ZXN0KGh0bWwpKQoJCQkJCQkJZG9tLnJlbW92ZShzcGFuKTsKCQkJCQl9KTsKCgkJCQkJaHRtbCA9IHAuaW5uZXJIVE1MOwoKCQkJCQkvLyBSZW1vdmUgbWlkZG90L2xpc3QgaXRlbXMKCQkJCQlpZiAodHlwZSA9PSAndWwnKQoJCQkJCQlodG1sID0gcC5pbm5lckhUTUwucmVwbGFjZSgvX19NQ0VfSVRFTV9fL2csICcnKS5yZXBsYWNlKC9eW1x1MjAyMlx1MDBiN1x1MDBhN1x1MDBkOG9dXHMqKCZuYnNwO3xcdTAwYTApK1xzKi8sICcnKTsKCQkJCQllbHNlCgkJCQkJCWh0bWwgPSBwLmlubmVySFRNTC5yZXBsYWNlKC9fX01DRV9JVEVNX18vZywgJycpLnJlcGxhY2UoL15ccypcdytcLigmbmJzcDt8XHUwMGEwKStccyovLCAnJyk7CgoJCQkJCS8vIENyZWF0ZSBsaSBhbmQgYWRkIHBhcmFncmFwaCBkYXRhIGludG8gdGhlIG5ldyBsaQoJCQkJCWxpID0gbGlzdEVsbS5hcHBlbmRDaGlsZChkb20uY3JlYXRlKCdsaScsIDAsIGh0bWwpKTsKCQkJCQlkb20ucmVtb3ZlKHApOwoKCQkJCQlsYXN0TWFyZ2luID0gbWFyZ2luOwoJCQkJCWxhc3RUeXBlID0gdHlwZTsKCQkJCX0gZWxzZQoJCQkJCWxpc3RFbG0gPSBsYXN0TWFyZ2luID0gMDsgLy8gRW5kIGxpc3QgZWxlbWVudAoJCQl9KTsKCgkJCS8vIFJlbW92ZSBhbnkgbGVmdCBvdmVyIG1ha2VycwoJCQlodG1sID0gby5ub2RlLmlubmVySFRNTDsKCQkJaWYgKGh0bWwuaW5kZXhPZignX19NQ0VfSVRFTV9fJykgIT0gLTEpCgkJCQlvLm5vZGUuaW5uZXJIVE1MID0gaHRtbC5yZXBsYWNlKC9fX01DRV9JVEVNX18vZywgJycpOwoJCX0sCgoJCS8qKgoJCSAqIFRoaXMgbWV0aG9kIHdpbGwgc3BsaXQgdGhlIGN1cnJlbnQgYmxvY2sgcGFyZW50IGFuZCBpbnNlcnQgdGhlIGNvbnRlbnRzIGluc2lkZSB0aGUgc3BsaXQgcG9zaXRpb24uCgkJICogVGhpcyBsb2dpYyBjYW4gYmUgaW1wcm92ZWQgc28gdGV4dCBub2RlcyBhdCB0aGUgc3RhcnQvZW5kIHJlbWFpbiBpbiB0aGUgc3RhcnQvZW5kIGJsb2NrIGVsZW1lbnRzCgkJICovCgkJX2luc2VydEJsb2NrQ29udGVudCA6IGZ1bmN0aW9uKGVkLCBkb20sIGNvbnRlbnQpIHsKCQkJdmFyIHBhcmVudEJsb2NrLCBtYXJrZXIsIHNlbCA9IGVkLnNlbGVjdGlvbiwgbGFzdCwgZWxtLCB2cCwgeSwgZWxtSGVpZ2h0OwoKCQkJZnVuY3Rpb24gc2VsZWN0KG4pIHsKCQkJCXZhciByOwoKCQkJCWlmICh0aW55bWNlLmlzSUUpIHsKCQkJCQlyID0gZWQuZ2V0RG9jKCkuYm9keS5jcmVhdGVUZXh0UmFuZ2UoKTsKCQkJCQlyLm1vdmVUb0VsZW1lbnRUZXh0KG4pOwoJCQkJCXIuY29sbGFwc2UoZmFsc2UpOwoJCQkJCXIuc2VsZWN0KCk7CgkJCQl9IGVsc2UgewoJCQkJCXNlbC5zZWxlY3QobiwgMSk7CgkJCQkJc2VsLmNvbGxhcHNlKGZhbHNlKTsKCQkJCX0KCQkJfTsKCgkJCS8vIEluc2VydCBhIG1hcmtlciBmb3IgdGhlIGNhcmV0IHBvc2l0aW9uCgkJCXRoaXMuX2luc2VydCgnPHNwYW4gaWQ9Il9tYXJrZXIiPiZuYnNwOzwvc3Bhbj4nLCAxKTsKCQkJbWFya2VyID0gZG9tLmdldCgnX21hcmtlcicpOwoJCQlwYXJlbnRCbG9jayA9IGRvbS5nZXRQYXJlbnQobWFya2VyLCAncCxoMSxoMixoMyxoNCxoNSxoNix1bCxvbCcpOwoKCQkJaWYgKHBhcmVudEJsb2NrKSB7CgkJCQkvLyBTcGxpdCBwYXJlbnQgYmxvY2sKCQkJCW1hcmtlciA9IGRvbS5zcGxpdChwYXJlbnRCbG9jaywgbWFya2VyKTsKCgkJCQkvLyBJbnNlcnQgbm9kZXMgYmVmb3JlIHRoZSBtYXJrZXIKCQkJCWVhY2goZG9tLmNyZWF0ZSgnZGl2JywgMCwgY29udGVudCkuY2hpbGROb2RlcywgZnVuY3Rpb24obikgewoJCQkJCWxhc3QgPSBtYXJrZXIucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobi5jbG9uZU5vZGUodHJ1ZSksIG1hcmtlcik7CgkJCQl9KTsKCgkJCQkvLyBNb3ZlIGNhcmV0IGFmdGVyIG1hcmtlcgoJCQkJc2VsZWN0KGxhc3QpOwoJCQl9IGVsc2UgewoJCQkJZG9tLnNldE91dGVySFRNTChtYXJrZXIsIGNvbnRlbnQpOwoJCQkJc2VsLnNlbGVjdChlZC5nZXRCb2R5KCksIDEpOwoJCQkJc2VsLmNvbGxhcHNlKDApOwoJCQl9CgoJCQlkb20ucmVtb3ZlKCdfbWFya2VyJyk7IC8vIFJlbW92ZSBtYXJrZXIgaWYgaXQncyBsZWZ0CgoJCQkvLyBHZXQgZWxlbWVudCwgcG9zaXRpb24gYW5kIGhlaWdodAoJCQllbG0gPSBzZWwuZ2V0U3RhcnQoKTsKCQkJdnAgPSBkb20uZ2V0Vmlld1BvcnQoZWQuZ2V0V2luKCkpOwoJCQl5ID0gZWQuZG9tLmdldFBvcyhlbG0pLnk7CgkJCWVsbUhlaWdodCA9IGVsbS5jbGllbnRIZWlnaHQ7CgoJCQkvLyBJcyBlbGVtZW50IHdpdGhpbiB2aWV3cG9ydCBpZiBub3QgdGhlbiBzY3JvbGwgaXQgaW50byB2aWV3CgkJCWlmICh5IDwgdnAueSB8fCB5ICsgZWxtSGVpZ2h0ID4gdnAueSArIHZwLmgpCgkJCQllZC5nZXREb2MoKS5ib2R5LnNjcm9sbFRvcCA9IHkgPCB2cC55ID8geSA6IHkgLSB2cC5oICsgMjU7CgkJfSwKCgkJLyoqCgkJICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGNvbnRlbnRzIGF0IHRoZSBjYXJldCBwb3NpdGlvbi4KCQkgKi8KCQlfaW5zZXJ0IDogZnVuY3Rpb24oaCwgc2tpcF91bmRvKSB7CgkJCXZhciBlZCA9IHRoaXMuZWRpdG9yOwoKCQkJLy8gRmlyc3QgZGVsZXRlIHRoZSBjb250ZW50cyBzZWVtcyB0byB3b3JrIGJldHRlciBvbiBXZWJLaXQKCQkJaWYgKCFlZC5zZWxlY3Rpb24uaXNDb2xsYXBzZWQoKSkKCQkJCWVkLmdldERvYygpLmV4ZWNDb21tYW5kKCdEZWxldGUnLCBmYWxzZSwgbnVsbCk7CgoJCQkvLyBJdCdzIGJldHRlciB0byB1c2UgdGhlIGluc2VydEhUTUwgbWV0aG9kIG9uIEdlY2tvIHNpbmNlIGl0IHdpbGwgY29tYmluZSBwYXJhZ3JhcGhzIGNvcnJlY3RseSBiZWZvcmUgaW5zZXJ0aW5nIHRoZSBjb250ZW50cwoJCQllZC5leGVjQ29tbWFuZCh0aW55bWNlLmlzR2Vja28gPyAnaW5zZXJ0SFRNTCcgOiAnbWNlSW5zZXJ0Q29udGVudCcsIGZhbHNlLCBoLCB7c2tpcF91bmRvIDogc2tpcF91bmRvfSk7CgkJfSwKCgkJLyoqCgkJICogVGhpcyBtZXRob2Qgd2lsbCBvcGVuIHRoZSBvbGQgc3R5bGUgcGFzdGUgZGlhbG9ncy4gU29tZSB1c2VycyBtaWdodCB3YW50IHRoZSBvbGQgYmVoYXZpb3IgYnV0IHN0aWxsIHVzZSB0aGUgbmV3IGNsZWFudXAgZW5naW5lLgoJCSAqLwoJCV9sZWdhY3lTdXBwb3J0IDogZnVuY3Rpb24oKSB7CgkJCXZhciB0ID0gdGhpcywgZWQgPSB0LmVkaXRvcjsKCgkJCS8vIFJlZ2lzdGVyIGNvbW1hbmRzIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eQoJCQllYWNoKFsnbWNlUGFzdGVUZXh0JywgJ21jZVBhc3RlV29yZCddLCBmdW5jdGlvbihjbWQpIHsKCQkJCWVkLmFkZENvbW1hbmQoY21kLCBmdW5jdGlvbigpIHsKCQkJCQllZC53aW5kb3dNYW5hZ2VyLm9wZW4oewoJCQkJCQlmaWxlIDogdC51cmwgKyAoY21kID09ICdtY2VQYXN0ZVRleHQnID8gJ2h0dHA6Ly8xMC4yMC4xNjAuMTk4L3Bhc3RldGV4dC5odG0nIDogJ2h0dHA6Ly8xMC4yMC4xNjAuMTk4L3Bhc3Rld29yZC5odG0nKSwKCQkJCQkJd2lkdGggOiBwYXJzZUludChlZC5nZXRQYXJhbSgicGFzdGVfZGlhbG9nX3dpZHRoIiwgIjQ1MCIpKSwKCQkJCQkJaGVpZ2h0IDogcGFyc2VJbnQoZWQuZ2V0UGFyYW0oInBhc3RlX2RpYWxvZ19oZWlnaHQiLCAiNDAwIikpLAoJCQkJCQlpbmxpbmUgOiAxCgkJCQkJfSk7CgkJCQl9KTsKCQkJfSk7CgoJCQkvLyBSZWdpc3RlciBidXR0b25zIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eQoJCQllZC5hZGRCdXR0b24oJ3Bhc3RldGV4dCcsIHt0aXRsZSA6ICdwYXN0ZS5wYXN0ZV90ZXh0X2Rlc2MnLCBjbWQgOiAnbWNlUGFzdGVUZXh0J30pOwoJCQllZC5hZGRCdXR0b24oJ3Bhc3Rld29yZCcsIHt0aXRsZSA6ICdwYXN0ZS5wYXN0ZV93b3JkX2Rlc2MnLCBjbWQgOiAnbWNlUGFzdGVXb3JkJ30pOwoJCQllZC5hZGRCdXR0b24oJ3NlbGVjdGFsbCcsIHt0aXRsZSA6ICdwYXN0ZS5zZWxlY3RhbGxfZGVzYycsIGNtZCA6ICdzZWxlY3RhbGwnfSk7CgkJfQoJfSk7CgoJLy8gUmVnaXN0ZXIgcGx1Z2luCgl0aW55bWNlLlBsdWdpbk1hbmFnZXIuYWRkKCdwYXN0ZScsIHRpbnltY2UucGx1Z2lucy5QYXN0ZVBsdWdpbik7Cn0pKCk7CgovKioKICogJElkOiBlZGl0b3JfcGx1Z2luX3NyYy5qcyA1MjAgMjAwOC0wMS0wNyAxNjozMDozMlogc3BvY2tlICQKICoKICogQGF1dGhvciBNb3hpZWNvZGUKICogQGNvcHlyaWdodCBDb3B5cmlnaHQgqSAyMDA0LTIwMDgsIE1veGllY29kZSBTeXN0ZW1zIEFCLCBBbGwgcmlnaHRzIHJlc2VydmVkLgogKi8KCihmdW5jdGlvbigpIHsKCXRpbnltY2UuY3JlYXRlKCd0aW55bWNlLnBsdWdpbnMuRW1vdGlvbnNQbHVnaW4nLCB7CgkJaW5pdCA6IGZ1bmN0aW9uKGVkLCB1cmwpIHsKCQkJLy8gUmVnaXN0ZXIgY29tbWFuZHMKCQkJZWQuYWRkQ29tbWFuZCgnbWNlRW1vdGlvbicsIGZ1bmN0aW9uKCkgewoJCQkJZWQud2luZG93TWFuYWdlci5vcGVuKHsKCQkJCQlmaWxlIDogdGlueU1DRS5zZXR0aW5ncy5wbHVnaW5fYWN0aW9uX2Jhc2VfcGF0aCArICcvZW1vdGlvbnMuYWN0aW9uJywKCQkJCQl3aWR0aCA6IDI1MCArIHBhcnNlSW50KGVkLmdldExhbmcoJ2Vtb3Rpb25zLmRlbHRhX3dpZHRoJywgMCkpLAoJCQkJCWhlaWdodCA6IDIxMCArIHBhcnNlSW50KGVkLmdldExhbmcoJ2Vtb3Rpb25zLmRlbHRhX2hlaWdodCcsIDApKSwKCQkJCQlpbmxpbmUgOiAxLAogICAgICAgICAgICAgICAgICAgIG5hbWUgOiAiZW1vdGljb25faW5zZXJ0ZXIiCgkJCQl9LCB7CgkJCQkJcGx1Z2luX3VybCA6IHVybAoJCQkJfSk7CgkJCX0pOwoKCQkJLy8gUmVnaXN0ZXIgYnV0dG9ucwoJCQllZC5hZGRCdXR0b24oJ2Vtb3Rpb25zJywge3RpdGxlIDogJ2Vtb3Rpb25zLmVtb3Rpb25zX2Rlc2MnLCBjbWQgOiAnbWNlRW1vdGlvbid9KTsKCQl9LAoKCQlnZXRJbmZvIDogZnVuY3Rpb24oKSB7CgkJCXJldHVybiB7CgkJCQlsb25nbmFtZSA6ICdFbW90aW9ucycsCgkJCQlhdXRob3IgOiAnTW94aWVjb2RlIFN5c3RlbXMgQUInLAoJCQkJYXV0aG9ydXJsIDogJ2h0dHA6Ly90aW55bWNlLm1veGllY29kZS5jb20vJywKCQkJCWluZm91cmwgOiAnaHR0cDovL3dpa2kubW94aWVjb2RlLmNvbS9pbmRleC5waHAvVGlueU1DRTpQbHVnaW5zL2Vtb3Rpb25zJywKCQkJCXZlcnNpb24gOiB0aW55bWNlLm1ham9yVmVyc2lvbiArICIuIiArIHRpbnltY2UubWlub3JWZXJzaW9uCgkJCX07CgkJfQoJfSk7CgoJLy8gUmVnaXN0ZXIgcGx1Z2luCgl0aW55bWNlLlBsdWdpbk1hbmFnZXIuYWRkKCdlbW90aW9ucycsIHRpbnltY2UucGx1Z2lucy5FbW90aW9uc1BsdWdpbik7Cn0pKCk7Ci8qKgogKiAkSWQ6IGVkaXRvcl9wbHVnaW5fc3JjLmpzIDkyMyAyMDA4LTA5LTA5IDE2OjQ1OjI5WiBzcG9ja2UgJAogKgogKiBAYXV0aG9yIE1veGllY29kZQogKiBAY29weXJpZ2h0IENvcHlyaWdodCCpIDIwMDQtMjAwOCwgTW94aWVjb2RlIFN5c3RlbXMgQUIsIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqLwoKKGZ1bmN0aW9uKCkgewoJdmFyIERPTSA9IHRpbnltY2UuRE9NOwoKCXRpbnltY2UuY3JlYXRlKCd0aW55bWNlLnBsdWdpbnMuRnVsbFNjcmVlblBsdWdpbicsIHsKCQlpbml0IDogZnVuY3Rpb24oZWQsIHVybCkgewoJCQl2YXIgdCA9IHRoaXMsIHMgPSB7fSwgdnA7CgoJCQl0LmVkaXRvciA9IGVkOwoKCQkJLy8gUmVnaXN0ZXIgY29tbWFuZHMKCQkJZWQuYWRkQ29tbWFuZCgnbWNlRnVsbFNjcmVlbicsIGZ1bmN0aW9uKCkgewoJCQkJdmFyIHdpbiwgZGUgPSBET00uZG9jLmRvY3VtZW50RWxlbWVudDsKCgkJCQlpZiAoZWQuZ2V0UGFyYW0oJ2Z1bGxzY3JlZW5faXNfZW5hYmxlZCcpKSB7CgkJCQkJaWYgKGVkLmdldFBhcmFtKCdmdWxsc2NyZWVuX25ld193aW5kb3cnKSkKCQkJCQkJY2xvc2VGdWxsc2NyZWVuKCk7IC8vIENhbGwgdG8gY2xvc2UgaW4gbmV3IHdpbmRvdwoJCQkJCWVsc2UgewoJCQkJCQlET00ud2luLnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7CgkJCQkJCQl0aW55bWNlLmRvbS5FdmVudC5yZW1vdmUoRE9NLndpbiwgJ3Jlc2l6ZScsIHQucmVzaXplRnVuYyk7CgkJCQkJCQl0aW55TUNFLmdldChlZC5nZXRQYXJhbSgnZnVsbHNjcmVlbl9lZGl0b3JfaWQnKSkuc2V0Q29udGVudChlZC5nZXRDb250ZW50KHtmb3JtYXQgOiAncmF3J30pLCB7Zm9ybWF0IDogJ3Jhdyd9KTsKCQkJCQkJCXRpbnlNQ0UucmVtb3ZlKGVkKTsKCQkJCQkJCURPTS5yZW1vdmUoJ21jZV9mdWxsc2NyZWVuX2NvbnRhaW5lcicpOwoJCQkJCQkJZGUuc3R5bGUub3ZlcmZsb3cgPSBlZC5nZXRQYXJhbSgnZnVsbHNjcmVlbl9odG1sX292ZXJmbG93Jyk7CgkJCQkJCQlET00uc2V0U3R5bGUoRE9NLmRvYy5ib2R5LCAnb3ZlcmZsb3cnLCBlZC5nZXRQYXJhbSgnZnVsbHNjcmVlbl9vdmVyZmxvdycpKTsKCQkJCQkJCURPTS53aW4uc2Nyb2xsVG8oZWQuZ2V0UGFyYW0oJ2Z1bGxzY3JlZW5fc2Nyb2xseCcpLCBlZC5nZXRQYXJhbSgnZnVsbHNjcmVlbl9zY3JvbGx5JykpOwoJCQkJCQkJdGlueU1DRS5zZXR0aW5ncyA9IHRpbnlNQ0Uub2xkU2V0dGluZ3M7IC8vIFJlc3RvcmUgb2xkIHNldHRpbmdzCgkJCQkJCX0sIDEwKTsKCQkJCQl9CgoJCQkJCXJldHVybjsKCQkJCX0KCgkJCQlpZiAoZWQuZ2V0UGFyYW0oJ2Z1bGxzY3JlZW5fbmV3X3dpbmRvdycpKSB7CgkJCQkJd2luID0gRE9NLndpbi5vcGVuKHVybCArICIvZnVsbHNjcmVlbi5odG0iLCAibWNlRnVsbFNjcmVlblBvcHVwIiwgImZ1bGxzY3JlZW49eWVzLG1lbnViYXI9bm8sdG9vbGJhcj1ubyxzY3JvbGxiYXJzPW5vLHJlc2l6YWJsZT15ZXMsbGVmdD0wLHRvcD0wLHdpZHRoPSIgKyBzY3JlZW4uYXZhaWxXaWR0aCArICIsaGVpZ2h0PSIgKyBzY3JlZW4uYXZhaWxIZWlnaHQpOwoJCQkJCXRyeSB7CgkJCQkJCXdpbi5yZXNpemVUbyhzY3JlZW4uYXZhaWxXaWR0aCwgc2NyZWVuLmF2YWlsSGVpZ2h0KTsKCQkJCQl9IGNhdGNoIChlKSB7CgkJCQkJCS8vIElnbm9yZQoJCQkJCX0KCQkJCX0gZWxzZSB7CgkJCQkJdGlueU1DRS5vbGRTZXR0aW5ncyA9IHRpbnlNQ0Uuc2V0dGluZ3M7IC8vIFN0b3JlIG9sZCBzZXR0aW5ncwoJCQkJCXMuZnVsbHNjcmVlbl9vdmVyZmxvdyA9IERPTS5nZXRTdHlsZShET00uZG9jLmJvZHksICdvdmVyZmxvdycsIDEpIHx8ICdhdXRvJzsKCQkJCQlzLmZ1bGxzY3JlZW5faHRtbF9vdmVyZmxvdyA9IERPTS5nZXRTdHlsZShkZSwgJ292ZXJmbG93JywgMSk7CgkJCQkJdnAgPSBET00uZ2V0Vmlld1BvcnQoKTsKCQkJCQlzLmZ1bGxzY3JlZW5fc2Nyb2xseCA9IHZwLng7CgkJCQkJcy5mdWxsc2NyZWVuX3Njcm9sbHkgPSB2cC55OwoKCQkJCQkvLyBGaXhlcyBhbiBPcGVyYSBidWcgd2hlcmUgdGhlIHNjcm9sbGJhcnMgZG9lc24ndCByZWFwcGVhcgoJCQkJCWlmICh0aW55bWNlLmlzT3BlcmEgJiYgcy5mdWxsc2NyZWVuX292ZXJmbG93ID09ICd2aXNpYmxlJykKCQkJCQkJcy5mdWxsc2NyZWVuX292ZXJmbG93ID0gJ2F1dG8nOwoKCQkJCQkvLyBGaXhlcyBhbiBJRSBidWcgd2hlcmUgaG9yaXpvbnRhbCBzY3JvbGxiYXJzIHdvdWxkIGFwcGVhcgoJCQkJCWlmICh0aW55bWNlLmlzSUUgJiYgcy5mdWxsc2NyZWVuX292ZXJmbG93ID09ICdzY3JvbGwnKQoJCQkJCQlzLmZ1bGxzY3JlZW5fb3ZlcmZsb3cgPSAnYXV0byc7CgoJCQkJCS8vIEZpeGVzIGFuIElFIGJ1ZyB3aGVyZSB0aGUgc2Nyb2xsYmFycyBkb2Vzbid0IHJlYXBwZWFyCgkJCQkJaWYgKHRpbnltY2UuaXNJRSAmJiAocy5mdWxsc2NyZWVuX2h0bWxfb3ZlcmZsb3cgPT0gJ3Zpc2libGUnIHx8IHMuZnVsbHNjcmVlbl9odG1sX292ZXJmbG93ID09ICdzY3JvbGwnKSkKCQkJCQkJcy5mdWxsc2NyZWVuX2h0bWxfb3ZlcmZsb3cgPSAnYXV0byc7IAoKCQkJCQlpZiAocy5mdWxsc2NyZWVuX292ZXJmbG93ID09ICcwcHgnKQoJCQkJCQlzLmZ1bGxzY3JlZW5fb3ZlcmZsb3cgPSAnJzsKCgkJCQkJRE9NLnNldFN0eWxlKERPTS5kb2MuYm9keSwgJ292ZXJmbG93JywgJ2hpZGRlbicpOwoJCQkJCWRlLnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbic7IC8vRml4IGZvciBJRTYvNwoJCQkJCXZwID0gRE9NLmdldFZpZXdQb3J0KCk7CgkJCQkJRE9NLndpbi5zY3JvbGxUbygwLCAwKTsKCgkJCQkJaWYgKHRpbnltY2UuaXNJRSkKCQkJCQkJdnAuaCAtPSAxOwoKCQkJCQluID0gRE9NLmFkZChET00uZG9jLmJvZHksICdkaXYnLCB7aWQgOiAnbWNlX2Z1bGxzY3JlZW5fY29udGFpbmVyJywgc3R5bGUgOiAncG9zaXRpb246JyArICh0aW55bWNlLmlzSUU2IHx8ICh0aW55bWNlLmlzSUUgJiYgIURPTS5ib3hNb2RlbCkgPyAnYWJzb2x1dGUnIDogJ2ZpeGVkJykgKyAnO3RvcDowO2xlZnQ6MDt3aWR0aDonICsgdnAudyArICdweDtoZWlnaHQ6JyArIHZwLmggKyAncHg7ei1pbmRleDo1MDA7J30pOwoJCQkJCURPTS5hZGQobiwgJ2RpdicsIHtpZCA6ICdtY2VfZnVsbHNjcmVlbid9KTsKCgkJCQkJdGlueW1jZS5lYWNoKGVkLnNldHRpbmdzLCBmdW5jdGlvbih2LCBuKSB7CgkJCQkJCXNbbl0gPSB2OwoJCQkJCX0pOwoKCQkJCQlzLmlkID0gJ21jZV9mdWxsc2NyZWVuJzsKCQkJCQlzLndpZHRoID0gbi5jbGllbnRXaWR0aDsKCQkJCQlzLmhlaWdodCA9IG4uY2xpZW50SGVpZ2h0IC0gMTU7CgkJCQkJcy5mdWxsc2NyZWVuX2lzX2VuYWJsZWQgPSB0cnVlOwoJCQkJCXMuZnVsbHNjcmVlbl9lZGl0b3JfaWQgPSBlZC5pZDsKCQkJCQlzLnRoZW1lX2FkdmFuY2VkX3Jlc2l6aW5nID0gZmFsc2U7CgkJCQkJcy5zYXZlX29uc2F2ZWNhbGxiYWNrID0gZnVuY3Rpb24oKSB7CgkJCQkJCWVkLnNldENvbnRlbnQodGlueU1DRS5nZXQocy5pZCkuZ2V0Q29udGVudCh7Zm9ybWF0IDogJ3Jhdyd9KSwge2Zvcm1hdCA6ICdyYXcnfSk7CgkJCQkJfTsKCgkJCQkJdGlueW1jZS5lYWNoKGVkLmdldFBhcmFtKCdmdWxsc2NyZWVuX3NldHRpbmdzJyksIGZ1bmN0aW9uKHYsIGspIHsKCQkJCQkJc1trXSA9IHY7CgkJCQkJfSk7CgoJCQkJCWlmIChzLnRoZW1lX2FkdmFuY2VkX3Rvb2xiYXJfbG9jYXRpb24gPT09ICdleHRlcm5hbCcpCgkJCQkJCXMudGhlbWVfYWR2YW5jZWRfdG9vbGJhcl9sb2NhdGlvbiA9ICd0b3AnOwoKCQkJCQl0LmZ1bGxzY3JlZW5FZGl0b3IgPSBuZXcgdGlueW1jZS5FZGl0b3IoQUpTLkVkaXRvci5BZGFwdGVyLnNldHRpbmdzLmZ1bGxfc2NyZWVuX2VkaXRvcl9pZCwgcyk7CgkJCQkJdC5mdWxsc2NyZWVuRWRpdG9yLm9uSW5pdC5hZGQoZnVuY3Rpb24oKSB7CgkJCQkJCXQuZnVsbHNjcmVlbkVkaXRvci5zZXRDb250ZW50KGVkLmdldENvbnRlbnQoKSk7CgkJCQkJCXQuZnVsbHNjcmVlbkVkaXRvci5mb2N1cygpOwoJCQkJCX0pOwoKICAgICAgICAgICAgICAgICAgICB2YXIgaW5pdENhbGxiYWNrcyA9IEFKUy5FZGl0b3IuQWRhcHRlci5mdWxsc2NyZWVuRWRpdG9yT25Jbml0Q2FsbGJhY2tzOwogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGluaXRDYWxsYmFja3MubGVuZ3RoOyBpIDwgaWk7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZiA9IGluaXRDYWxsYmFja3NbaV07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChBSlMuJC5pc0Z1bmN0aW9uKGYpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LmZ1bGxzY3JlZW5FZGl0b3Iub25Jbml0LmFkZChmKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCgkJCQkJdC5mdWxsc2NyZWVuRWRpdG9yLnJlbmRlcigpOwoJCQkJCXRpbnlNQ0UuYWRkKHQuZnVsbHNjcmVlbkVkaXRvcik7CgoJCQkJCXQuZnVsbHNjcmVlbkVsZW1lbnQgPSBuZXcgdGlueW1jZS5kb20uRWxlbWVudCgnbWNlX2Z1bGxzY3JlZW5fY29udGFpbmVyJyk7CgkJCQkJdC5mdWxsc2NyZWVuRWxlbWVudC51cGRhdGUoKTsKCQkJCQkvL2RvY3VtZW50LmJvZHkub3ZlcmZsb3cgPSAnaGlkZGVuJzsKCgkJCQkJdC5yZXNpemVGdW5jID0gdGlueW1jZS5kb20uRXZlbnQuYWRkKERPTS53aW4sICdyZXNpemUnLCBmdW5jdGlvbigpIHsKCQkJCQkJdmFyIHZwID0gdGlueW1jZS5ET00uZ2V0Vmlld1BvcnQoKTsKCgkJCQkJCXQuZnVsbHNjcmVlbkVkaXRvci50aGVtZS5yZXNpemVUbyh2cC53LCB2cC5oKTsKCQkJCQl9KTsKCQkJCX0KCQkJfSk7CgoJCQkvLyBSZWdpc3RlciBidXR0b25zCgkJCWVkLmFkZEJ1dHRvbignZnVsbHNjcmVlbicsIHt0aXRsZSA6ICdodHRwOi8vMTAuMjAuMTYwLjE5OC93aWtpL3MvZW4vMjE2Ni8zNC8zLjUuOS9fL2Rvd25sb2FkL2JhdGNoL2NvbS5hdGxhc3NpYW4uY29uZmx1ZW5jZS50aW55bWNlcGx1Z2luOmVkaXRvci1yZXNvdXJjZXMvZnVsbHNjcmVlbi5kZXNjJywgY21kIDogJ21jZUZ1bGxTY3JlZW4nfSk7CgoJCQllZC5vbk5vZGVDaGFuZ2UuYWRkKGZ1bmN0aW9uKGVkLCBjbSkgewoJCQkJY20uc2V0QWN0aXZlKCdmdWxsc2NyZWVuJywgZWQuZ2V0UGFyYW0oJ2Z1bGxzY3JlZW5faXNfZW5hYmxlZCcpKTsKCQkJfSk7CgkJfSwKCgkJZ2V0SW5mbyA6IGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gewoJCQkJbG9uZ25hbWUgOiAnRnVsbHNjcmVlbicsCgkJCQlhdXRob3IgOiAnTW94aWVjb2RlIFN5c3RlbXMgQUInLAoJCQkJYXV0aG9ydXJsIDogJ2h0dHA6Ly90aW55bWNlLm1veGllY29kZS5jb20vJywKCQkJCWluZm91cmwgOiAnaHR0cDovL3dpa2kubW94aWVjb2RlLmNvbS9pbmRleC5waHAvVGlueU1DRTpQbHVnaW5zL2Z1bGxzY3JlZW4nLAoJCQkJdmVyc2lvbiA6IHRpbnltY2UubWFqb3JWZXJzaW9uICsgIi4iICsgdGlueW1jZS5taW5vclZlcnNpb24KCQkJfTsKCQl9Cgl9KTsKCgkvLyBSZWdpc3RlciBwbHVnaW4KCXRpbnltY2UuUGx1Z2luTWFuYWdlci5hZGQoJ2Z1bGxzY3JlZW4nLCB0aW55bWNlLnBsdWdpbnMuRnVsbFNjcmVlblBsdWdpbik7Cn0pKCk7CgovKioKICogJElkOiBlZGl0b3JfcGx1Z2luX3NyYy5qcyA4NDggMjAwOC0wNS0xNSAxMTo1NDo0MFogc3BvY2tlICQKICoKICogQGF1dGhvciBNb3hpZWNvZGUKICogQGNvcHlyaWdodCBDb3B5cmlnaHQgqSAyMDA0LTIwMDgsIE1veGllY29kZSBTeXN0ZW1zIEFCLCBBbGwgcmlnaHRzIHJlc2VydmVkLgogKi8KCihmdW5jdGlvbigpIHsKCXZhciBFdmVudCA9IHRpbnltY2UuZG9tLkV2ZW50LCBlYWNoID0gdGlueW1jZS5lYWNoLCBET00gPSB0aW55bWNlLkRPTTsKCgl0aW55bWNlLmNyZWF0ZSgndGlueW1jZS5wbHVnaW5zLkNvbnRleHRNZW51JywgewoJCWluaXQgOiBmdW5jdGlvbihlZCkgewoJCQl2YXIgdCA9IHRoaXM7CgoJCQl0LmVkaXRvciA9IGVkOwoJCQl0Lm9uQ29udGV4dE1lbnUgPSBuZXcgdGlueW1jZS51dGlsLkRpc3BhdGNoZXIodGhpcyk7CgogICAgICAgICAgICBmdW5jdGlvbiBidXR0b24oKSB7IHJldHVybiBBSlMuJCgiLm1jZVRvb2xiYXIgYS5tY2VfY29udGV4dG1lbnUiKTsgfTsKCiAgICAgICAgICAgIC8vIEFUTEFTU0lBTiAtIHN1cHBvcnQgY29udGV4dCBtZW51IHVzZXIgcHJlZmVyZW5jZQogICAgICAgICAgICBlZC5vblBvc3RSZW5kZXIuYWRkKGZ1bmN0aW9uKGVkKSB7CiAgICAgICAgICAgICAgICAvLyBkb20gbWlnaHQgbm90IG5lY2Vzc2FyaWx5IGJlIHJlYWR5IG9uIGVkaXRvciBwb3N0IHJlbmRlcgogICAgICAgICAgICAgICAgQUpTLiQoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGIgPSBidXR0b24oKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYi5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEFKUy5wYXJhbXMucmVtb3RlVXNlcikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQUpTLiQuZ2V0SlNPTih0aW55TUNFLnNldHRpbmdzLnBsdWdpbl9hY3Rpb25fYmFzZV9wYXRoICsgIi9nZXQtd3lzaXd5Zy1jb250ZXh0bWVudS5hY3Rpb24iLCB7fSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKG9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb24gJiYgYi5hZGRDbGFzcygib24iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBhbm9ueW1vdXMgdXNlcnM6IGlmIGdvaW5nIHRvIGZ1bGxzY3JlZW4gbW9kZSwgY29weSBidXR0b24gc3RhdGUgZnJvbSBub3JtYWwgbW9kZQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlZC5pZC5pbmRleE9mKCJmdWxsc2NyZWVuIikgJiYgQUpTLiQoIiN3eXNpd3lnIC5tY2VUb29sYmFyIGEubWNlX2NvbnRleHRtZW51IikuaGFzQ2xhc3MoIm9uIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGIuYWRkQ2xhc3MoIm9uIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSk7CgkJCWVkLm9uQ29udGV4dE1lbnUuYWRkKGZ1bmN0aW9uKGVkLCBlKSB7CgkJCQlpZiAoIWUuY3RybEtleSAmJiBidXR0b24oKS5oYXNDbGFzcygib24iKSkgewoJCQkJCXQuX2dldE1lbnUoZWQpLnNob3dNZW51KGUuY2xpZW50WCwgZS5jbGllbnRZKTsKCQkJCQlFdmVudC5jYW5jZWwoZSk7CgkJCQl9CgkJCX0pOwoKCQkJZnVuY3Rpb24gaGlkZSgpIHsKCQkJCWlmICh0Ll9tZW51KSB7CgkJCQkJdC5fbWVudS5yZW1vdmVBbGwoKTsKCQkJCQl0Ll9tZW51LmRlc3Ryb3koKTsKCQkJCX0KCQkJfTsKCgkJCWVkLm9uTW91c2VEb3duLmFkZChoaWRlKTsKCQkJZWQub25LZXlEb3duLmFkZChoaWRlKTsKCiAgICAgICAgICAgIC8vIEFUTEFTU0lBTiAtIGFkZCBidXR0b24gdG8gdG9nZ2xlIHRoZSBjb250ZXh0IG1lbnUgb24vb2ZmCiAgICAgICAgICAgIGVkLmFkZENvbW1hbmQoJ21jZUNvbnRleHRNZW51JywgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICBoaWRlKCk7CiAgICAgICAgICAgICAgICB2YXIgYiA9IGJ1dHRvbigpOwogICAgICAgICAgICAgICAgdmFyIHNldEJ1dHRvbiA9IGZ1bmN0aW9uKG9uKSB7CiAgICAgICAgICAgICAgICAgICAgb24gPyBiLmFkZENsYXNzKCJvbiIpIDogYi5yZW1vdmVDbGFzcygib24iKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICBpZiAoQUpTLnBhcmFtcy5yZW1vdGVVc2VyKSB7CiAgICAgICAgICAgICAgICAgICAgQUpTLiQuZ2V0SlNPTih0aW55TUNFLnNldHRpbmdzLnBsdWdpbl9hY3Rpb25fYmFzZV9wYXRoICsgIi9zZXQtd3lzaXd5Zy1jb250ZXh0bWVudS5hY3Rpb24iLAogICAgICAgICAgICAgICAgICAgIHsgY29udGV4dE1lbnVQcmVmOiAhYi5oYXNDbGFzcygib24iKSB9LCBzZXRCdXR0b24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc2V0QnV0dG9uKCFiLmhhc0NsYXNzKCJvbiIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGVkLmFkZEJ1dHRvbignY29udGV4dG1lbnUnLCB7dGl0bGUgOiAnaHR0cDovLzEwLjIwLjE2MC4xOTgvd2lraS9zL2VuLzIxNjYvMzQvMy41LjkvXy9kb3dubG9hZC9iYXRjaC9jb20uYXRsYXNzaWFuLmNvbmZsdWVuY2UudGlueW1jZXBsdWdpbjplZGl0b3ItcmVzb3VyY2VzL2NvbnRleHRtZW51LmRlc2MnLCBjbWQgOiAnbWNlQ29udGV4dE1lbnUnfSk7CiAgICAgICAgfSwKCgkJZ2V0SW5mbyA6IGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gewoJCQkJbG9uZ25hbWUgOiAnQ29udGV4dG1lbnUnLAoJCQkJYXV0aG9yIDogJ01veGllY29kZSBTeXN0ZW1zIEFCJywKCQkJCWF1dGhvcnVybCA6ICdodHRwOi8vdGlueW1jZS5tb3hpZWNvZGUuY29tLycsCgkJCQlpbmZvdXJsIDogJ2h0dHA6Ly93aWtpLm1veGllY29kZS5jb20vaW5kZXgucGhwL1RpbnlNQ0U6UGx1Z2lucy9jb250ZXh0bWVudScsCgkJCQl2ZXJzaW9uIDogdGlueW1jZS5tYWpvclZlcnNpb24gKyAiLiIgKyB0aW55bWNlLm1pbm9yVmVyc2lvbgoJCQl9OwoJCX0sCgoJCV9nZXRNZW51IDogZnVuY3Rpb24oZWQpIHsKCQkJdmFyIHQgPSB0aGlzLCBtID0gdC5fbWVudSwgc2UgPSBlZC5zZWxlY3Rpb24sIGNvbCA9IHNlLmlzQ29sbGFwc2VkKCksIGVsID0gc2UuZ2V0Tm9kZSgpIHx8IGVkLmdldEJvZHkoKSwgYW0sIHAxLCBwMjsKCgkJCWlmIChtKSB7CgkJCQltLnJlbW92ZUFsbCgpOwoJCQkJbS5kZXN0cm95KCk7CgkJCX0KCgkJCXAxID0gRE9NLmdldFBvcyhlZC5nZXRDb250ZW50QXJlYUNvbnRhaW5lcigpKTsKCQkJcDIgPSBET00uZ2V0UG9zKGVkLmdldENvbnRhaW5lcigpKTsKCgkJCW0gPSBlZC5jb250cm9sTWFuYWdlci5jcmVhdGVEcm9wTWVudSgnY29udGV4dG1lbnUnLCB7CgkJCQlvZmZzZXRfeCA6IHAxLnggKyBlZC5nZXRQYXJhbSgnY29udGV4dG1lbnVfb2Zmc2V0X3gnLCAwKSwKCQkJCW9mZnNldF95IDogcDEueSArIGVkLmdldFBhcmFtKCdjb250ZXh0bWVudV9vZmZzZXRfeScsIDApLAoJCQkJY29uc3RyYWluIDogMQoJCQl9KTsKCgkJCXQuX21lbnUgPSBtOwoKICAgICAgICAgICAgLy8gQVRMQVNTSUFOIC0gdXNlbGVzcyBpbiBmaXJlZm94IGFuZCBzYWZhcmkKLy8JCQltLmFkZCh7dGl0bGUgOiAnYWR2YW5jZWQuY3V0X2Rlc2MnLCBpY29uIDogJ2N1dCcsIGNtZCA6ICdDdXQnfSkuc2V0RGlzYWJsZWQoY29sKTsKLy8JCQltLmFkZCh7dGl0bGUgOiAnYWR2YW5jZWQuY29weV9kZXNjJywgaWNvbiA6ICdjb3B5JywgY21kIDogJ0NvcHknfSkuc2V0RGlzYWJsZWQoY29sKTsKLy8JCQltLmFkZCh7dGl0bGUgOiAnYWR2YW5jZWQucGFzdGVfZGVzYycsIGljb24gOiAncGFzdGUnLCBjbWQgOiAnUGFzdGUnfSk7CgogICAgICAgICAgICAvLyBBVExBU1NJQU4gLSBDb25mbHVlbmNlIFBsdWdpbiBjb250ZXh0IG1lbnUgaXRlbXMKICAgICAgICAgICAgbS5hZGQoe3RpdGxlIDogJ2NvbmZsdWVuY2UuY29uZmxpbmtfZGVzYycsIGljb24gOiAnY29uZmxpbmsnLCBjbWQgOiAnbWNlQ29uZmxpbmsnfSk7CiAgICAgICAgICAgIGlmIChlbC5ub2RlTmFtZSA9PSAnQScpIHsKICAgICAgICAgICAgICAgIG0uYWRkKHt0aXRsZSA6ICdhZHZhbmNlZC51bmxpbmtfZGVzYycsIGljb24gOiAndW5saW5rJywgY21kIDogJ21jZUNvbmZVbmxpbmsnfSk7CiAgICAgICAgICAgIH0KCQkJbS5hZGQoe3RpdGxlIDogJ2NvbmZsdWVuY2UuY29uZmltYWdlX2Rlc2MnLCBpY29uIDogJ2NvbmZpbWFnZScsIGNtZCA6ICdtY2VDb25maW1hZ2UnLCB1aSA6IHRydWV9KTsKCQkJbS5hZGQoe3RpdGxlIDogJ2NvbmZsdWVuY2UuY29uZl9tYWNyb19icm93c2VyX2Rlc2MnLCBpY29uIDogJ2NvbmZfbWFjcm9fYnJvd3NlcicsIGNtZCA6ICdtY2VDb25mTWFjcm9Ccm93c2VyJ30pOwogICAgICAgICAgICBtLmFkZFNlcGFyYXRvcigpOwoKICAgICAgICAgICAgdC5vbkNvbnRleHRNZW51LmRpc3BhdGNoKHQsIG0sIGVsLCBjb2wpOwoKICAgICAgICAgICAgLy8gQVRMQVNTSUFOIC0gYWRkIHRoZSBkaXNhYmxlIGNvbnRleHQgbWVudSBsYXN0CiAgICAgICAgICAgIG0uYWRkKHt0aXRsZSA6ICdjb250ZXh0bWVudS5kaXNhYmxlX2Rlc2MnLCBpY29uIDogJ2NvbnRleHRtZW51JywgY21kIDogJ21jZUNvbnRleHRNZW51JywgdWkgOiB0cnVlfSk7CgoJCQlyZXR1cm4gbTsKCQl9Cgl9KTsKCgkvLyBSZWdpc3RlciBwbHVnaW4KCXRpbnltY2UuUGx1Z2luTWFuYWdlci5hZGQoJ2NvbnRleHRtZW51JywgdGlueW1jZS5wbHVnaW5zLkNvbnRleHRNZW51KTsKfSkoKTsKCi8qKgogKiAkSWQ6IGVkaXRvcl9wbHVnaW5fc3JjLmpzIDY4NiAyMDA4LTAzLTA5IDE4OjEzOjQ5WiBzcG9ja2UgJAogKgogKiBAYXV0aG9yIE1veGllY29kZQogKiBAY29weXJpZ2h0IENvcHlyaWdodCCpIDIwMDQtMjAwOCwgTW94aWVjb2RlIFN5c3RlbXMgQUIsIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqLwoKKGZ1bmN0aW9uKCkgewoJdGlueW1jZS5jcmVhdGUoJ3RpbnltY2UucGx1Z2lucy5TZWFyY2hSZXBsYWNlUGx1Z2luJywgewoJCWluaXQgOiBmdW5jdGlvbihlZCwgdXJsKSB7CgkJCWZ1bmN0aW9uIG9wZW4obSkgewoJCQkJZWQud2luZG93TWFuYWdlci5vcGVuKHsKCQkJCQlmaWxlIDogdGlueU1DRS5zZXR0aW5ncy5wbHVnaW5fYWN0aW9uX2Jhc2VfcGF0aCArICAnL3NlYXJjaHJlcGxhY2UuYWN0aW9uJywKCQkJCQl3aWR0aCA6IDQwMCArIHBhcnNlSW50KGVkLmdldExhbmcoJ3NlYXJjaHJlcGxhY2UuZGVsdGFfd2lkdGgnLCAwKSksCgkJCQkJaGVpZ2h0IDogMjI1ICsgcGFyc2VJbnQoZWQuZ2V0TGFuZygnc2VhcmNocmVwbGFjZS5kZWx0YV9oZWlnaHQnLCAwKSksCgkJCQkJaW5saW5lIDogMSwKCQkJCQlhdXRvX2ZvY3VzIDogMAoJCQkJfSwgewoJCQkJCW1vZGUgOiBtLAoJCQkJCXNlYXJjaF9zdHJpbmcgOiBlZC5zZWxlY3Rpb24uZ2V0Q29udGVudCh7Zm9ybWF0IDogJ3RleHQnfSksCgkJCQkJcGx1Z2luX3VybCA6IHVybAoJCQkJfSk7CgkJCX07CgoJCQkvLyBSZWdpc3RlciBjb21tYW5kcwoJCQllZC5hZGRDb21tYW5kKCdtY2VTZWFyY2gnLCBmdW5jdGlvbigpIHsKCQkJCW9wZW4oJ3NlYXJjaCcpOwoJCQl9KTsKCgkJCWVkLmFkZENvbW1hbmQoJ21jZVJlcGxhY2UnLCBmdW5jdGlvbigpIHsKCQkJCW9wZW4oJ3JlcGxhY2UnKTsKCQkJfSk7CgoJCQkvLyBSZWdpc3RlciBidXR0b25zCgkJCWVkLmFkZEJ1dHRvbignc2VhcmNoJywge3RpdGxlIDogJ3NlYXJjaHJlcGxhY2Uuc2VhcmNoX2Rlc2MnLCBjbWQgOiAnbWNlU2VhcmNoJ30pOwoJCQllZC5hZGRCdXR0b24oJ3JlcGxhY2UnLCB7dGl0bGUgOiAnc2VhcmNocmVwbGFjZS5yZXBsYWNlX2Rlc2MnLCBjbWQgOiAnbWNlUmVwbGFjZSd9KTsKCgkJCWVkLmFkZFNob3J0Y3V0KCdjdHJsK2YnLCAnc2VhcmNocmVwbGFjZS5zZWFyY2hfZGVzYycsICdtY2VTZWFyY2gnKTsKCQl9LAoKCQlnZXRJbmZvIDogZnVuY3Rpb24oKSB7CgkJCXJldHVybiB7CgkJCQlsb25nbmFtZSA6ICdTZWFyY2gvUmVwbGFjZScsCgkJCQlhdXRob3IgOiAnTW94aWVjb2RlIFN5c3RlbXMgQUInLAoJCQkJYXV0aG9ydXJsIDogJ2h0dHA6Ly90aW55bWNlLm1veGllY29kZS5jb20vJywKCQkJCWluZm91cmwgOiAnaHR0cDovL3dpa2kubW94aWVjb2RlLmNvbS9pbmRleC5waHAvVGlueU1DRTpQbHVnaW5zL3NlYXJjaHJlcGxhY2UnLAoJCQkJdmVyc2lvbiA6IHRpbnltY2UubWFqb3JWZXJzaW9uICsgIi4iICsgdGlueW1jZS5taW5vclZlcnNpb24KCQkJfTsKCQl9Cgl9KTsKCgkvLyBSZWdpc3RlciBwbHVnaW4KCXRpbnltY2UuUGx1Z2luTWFuYWdlci5hZGQoJ3NlYXJjaHJlcGxhY2UnLCB0aW55bWNlLnBsdWdpbnMuU2VhcmNoUmVwbGFjZVBsdWdpbik7Cn0pKCk7CnRpbnltY2UuY29uZmx1ZW5jZSA9IHRpbnltY2UuY29uZmx1ZW5jZSB8fCB7fTsKCnRpbnltY2UuY29uZmx1ZW5jZS5mb3JtYXR0ZXIgPSBuZXcgKGZ1bmN0aW9uICgkKSB7CiAgICAvKioKICAgICAqIFRoaXMgc3RydWN0dXJlIGRlc2NyaWJlcyBob3cgdG8gY3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIGEgYmxvY2sgZm9ybWF0LgogICAgICogcmF3VGV4dDogaWYgdHJ1ZSwgZXh0cmFjdCB0aGUgcmF3IHRleHQgZnJvbSB0aGUgbWFjcm8gYm9keSBhbmQgdGhyb3cgYW55IGZvcm1hdHRpbmcgYXdheS4KICAgICAqLwogICAgdmFyIGZvcm1hdERlc2NyaXB0b3JzID0gewogICAgICAgIHA6IHsKICAgICAgICAgICAgcmF3VGV4dDogZmFsc2V9LAogICAgICAgIG1hY3JvX3F1b3RlOiB7CiAgICAgICAgICAgIG1hY3JvTmFtZTogInF1b3RlIiwKICAgICAgICAgICAgcmF3VGV4dDogZmFsc2UgfSwKICAgICAgICBtYWNyb19wYW5lbDogewogICAgICAgICAgICBtYWNyb05hbWU6ICJwYW5lbCIsCiAgICAgICAgICAgIHJhd1RleHQ6IGZhbHNlIH0sCiAgICAgICAgbWFjcm9fbm9mb3JtYXQ6IHsKICAgICAgICAgICAgbWFjcm9OYW1lOiAibm9mb3JtYXQiLAogICAgICAgICAgICByYXdUZXh0OiB0cnVlIH0sCiAgICAgICAgbWFjcm9fY29kZTogewogICAgICAgICAgICBtYWNyb05hbWU6ICJjb2RlIiwKICAgICAgICAgICAgcmF3VGV4dDogdHJ1ZSB9CiAgICB9OwoKICAgIC8vIFB1YmxpYyAocHJpdmlsZWdlZCkgbWV0aG9kcyBoZXJlIC0gY2FsbGVkIGZyb20gdGlueV9tY2Vfc3JjLmpzCiAgICB0aGlzLmZvcm1hdEJsb2NrID0gZnVuY3Rpb24oZm9ybWF0KSB7CiAgICAgICAgdmFyIGVkID0gdGlueU1DRS5hY3RpdmVFZGl0b3IsCiAgICAgICAgICAgIHNlbGVjdGlvbiA9IGVkLnNlbGVjdGlvbiwKICAgICAgICAgICAgb3V0ZXJCbG9jayA9IGdldEVuY2xvc2luZ0Jsb2NrKHNlbGVjdGlvbi5nZXROb2RlKCkpLAogICAgICAgICAgICBib29rbWFyayA9IHNlbGVjdGlvbi5nZXRCb29rbWFyaygpOyAvLyBnZXQgdGhlIGJvb2ttYXJrIGJlZm9yZSB3ZSBkbyBhbnkgZm9ybWF0dGluZwoKICAgICAgICBpZiAoIWZvcm1hdCB8fCBmb3JtYXQgPT0gJ3AnKSB7CiAgICAgICAgICAgIHJlbW92ZUZvcm1hdChvdXRlckJsb2NrLCBlZC5kb20pOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICghb3V0ZXJCbG9jaykgeyAKICAgICAgICAgICAgZm9ybWF0UmFuZ2UoZWQsIGZvcm1hdCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBmb3JtYXRFbGVtZW50KGVkLCBmb3JtYXQsIG91dGVyQmxvY2spOwogICAgICAgIH0KCiAgICAgICAgLy8gY2xlYW4gdXAgY29kZQogICAgICAgIHNlbGVjdGlvbi5tb3ZlVG9Cb29rbWFyayhib29rbWFyayk7CiAgICAgICAgZWQubm9kZUNoYW5nZWQoKTsKCiAgICAgICAgLy8gb25seSBleGVjdXRlIHRoZSBGb3JtYXRCbG9jayBjb21tYW5kIGZvciBrbm93biBmb3JtYXR0aW5nCiAgICAgICAgaWYoL14oUCkkL2kudGVzdChmb3JtYXQpKSB7CiAgICAgICAgICAgIGVkLmdldERvYygpLmV4ZWNDb21tYW5kKCdGb3JtYXRCbG9jaycsIGZhbHNlLCBmb3JtYXQpOwogICAgICAgIH0KICAgIH07CgogICAgLy8gUHJpdmF0ZSBtZW1iZXJzIC0gdmFyaWFibGVzIGFuZCBmdW5jdGlvbnMuCiAgICBmdW5jdGlvbiBmb3JtYXRFbGVtZW50KGVkaXRvciwgZm9ybWF0LCBvdXRlckJsb2NrKSB7CiAgICAgICAgQUpTLmxvZygiZm9ybWF0RWxlbWVudCIpOwoKICAgICAgICB2YXIgJGJsb2NrVG9Gb3JtYXQgPSAkKG91dGVyQmxvY2spLAogICAgICAgICAgICBtYWNyb0JvZHkgPSAkYmxvY2tUb0Zvcm1hdC5odG1sKCksCiAgICAgICAgICAgIGZvcm1hdERlc2NyaXB0b3IgPSBmb3JtYXREZXNjcmlwdG9yc1tmb3JtYXRdOwoKICAgICAgICBpZiAoZm9ybWF0RGVzY3JpcHRvci5yYXdUZXh0KSB7CiAgICAgICAgICAgIG1hY3JvQm9keSA9ICRibG9ja1RvRm9ybWF0LnRleHQoKTsKICAgICAgICB9CgogICAgICAgIC8vIGlmIHdlIGFyZSBhbHJlYWR5IGluIGEgZm9ybWF0dGluZyBtYWNybywgd2UgbmVlZCB0bwogICAgICAgIC8vIHJlbW92ZSB0aGUgZm9ybWF0dGluZyBiZWZvcmUgYXBwbHlpbmcgdGhlIG5ldyBvbmUKICAgICAgICB2YXIgbWFjcm8gPSBnZXRFbmNsb3NpbmdNYWNybygkYmxvY2tUb0Zvcm1hdCk7CiAgICAgICAgaWYgKG1hY3JvLmxlbmd0aCAmJiBnZXRGb3JtYXREZXNjcmlwdG9yKG1hY3JvKSkgewogICAgICAgICAgICB2YXIgcyA9IGVkaXRvci5zZWxlY3Rpb24sIGIgPSBzLmdldEJvb2ttYXJrKCk7CiAgICAgICAgICAgIHJlbW92ZUZvcm1hdChtYWNyb1swXSwgZWRpdG9yLmRvbSwgbWFjcm8pOwogICAgICAgICAgICBzLm1vdmVUb0Jvb2ttYXJrKGIpOwogICAgICAgICAgICBpbnNlcnRNYWNybyhmb3JtYXREZXNjcmlwdG9yLCBtYWNyb0JvZHksIHMuZ2V0Tm9kZSgpKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGluc2VydE1hY3JvKGZvcm1hdERlc2NyaXB0b3IsIG1hY3JvQm9keSwgJGJsb2NrVG9Gb3JtYXRbMF0pOwogICAgICAgIH0KICAgIH07CgogICAgZnVuY3Rpb24gZm9ybWF0UmFuZ2UoZWRpdG9yLCBmb3JtYXQpIHsKICAgICAgICBBSlMubG9nKCJmb3JtYXRSYW5nZSIpOwogICAgICAgIHZhciByYW5nZSA9IGVkaXRvci5zZWxlY3Rpb24uZ2V0Um5nKCksIGZvcm1hdERlc2NyaXB0b3IgPSBmb3JtYXREZXNjcmlwdG9yc1tmb3JtYXRdOwogICAgICAgIHZhciBtYWNyb0JvZHk7CiAgICAgICAgaWYgKGZvcm1hdERlc2NyaXB0b3IucmF3VGV4dCkgewogICAgICAgICAgICBtYWNyb0JvZHkgPSByYW5nZS50ZXh0IHx8IGVkaXRvci5zZWxlY3Rpb24uZ2V0Q29udGVudCh7Zm9ybWF0IDogJ3RleHQnfSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBtYWNyb0JvZHkgPSByYW5nZS5odG1sVGV4dCB8fCBlZGl0b3Iuc2VsZWN0aW9uLmdldENvbnRlbnQoKTsKICAgICAgICB9CiAgICAgICAgaW5zZXJ0TWFjcm8oZm9ybWF0RGVzY3JpcHRvciwgbWFjcm9Cb2R5KTsKICAgIH07CgogICAgZnVuY3Rpb24gZ2V0Qm9keVNlbGVjdG9yKGZvcm1hdERlc2NyaXB0b3IpIHsKICAgICAgICByZXR1cm4gZm9ybWF0RGVzY3JpcHRvci5yYXdUZXh0ID8gInByZSIgOiAicCI7CiAgICB9OwoKICAgIGZ1bmN0aW9uIGluc2VydE1hY3JvKGZvcm1hdERlc2NyaXB0b3IsIG1hY3JvQm9keSwgbm9kZSkgewogICAgICAgIG1hY3JvQm9keSA9IG1hY3JvQm9keSB8fCAiICI7CiAgICAgICAgdmFyIG1hY3JvTmFtZSA9IGZvcm1hdERlc2NyaXB0b3IubWFjcm9OYW1lLAogICAgICAgICAgICBtYXJrdXAgPSAiXG57IiArIG1hY3JvTmFtZSArICJ9XG50ZXh0XG57IiArIG1hY3JvTmFtZSArICJ9XG4iOyAvLyBuZXdsaW5lcyBhbmQgJ3RleHQnIGlzIHJlcXVpcmVkCgogICAgICAgIHZhciBkYXRhID0gewogICAgICAgIAkJcGFnZUlkOiBBSlMuRWRpdG9yLmdldENvbnRlbnRJZCgpLCBzcGFjZUtleTogQUpTLnBhcmFtcy5zcGFjZUtleSwgd2lraU1hcmt1cDogbWFya3VwCiAgICAgICAgfTsKICAgICAgICB2YXIgY2FsbGJhY2sgPSBmdW5jdGlvbihtYWNyb0h0bWwpIHsKICAgICAgICAgICAgdmFyIGVkaXRvciA9IHRpbnlNQ0UuYWN0aXZlRWRpdG9yLCBzID0gZWRpdG9yLnNlbGVjdGlvbjsKICAgICAgICAgICAgaWYgKG5vZGUpIHsKICAgICAgICAgICAgICAgIHMuc2VsZWN0KG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciAkbWFjcm8gPSAkKCI8ZGl2PiIgKyBtYWNyb0h0bWwgKyAiPC9kaXY+IiksCiAgICAgICAgICAgICAgICB0b0luc2VydCA9ICRtYWNyby5maW5kKCJkaXYud3lzaXd5Zy1tYWNybyAiICsgZ2V0Qm9keVNlbGVjdG9yKGZvcm1hdERlc2NyaXB0b3IpKTsKICAgICAgICAgICAgaWYgKHRvSW5zZXJ0Lmxlbmd0aCA9PSAxKSB7CiAgICAgICAgICAgICAgICBpZiAoZm9ybWF0RGVzY3JpcHRvci5yYXdUZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgLy8gUmF3IHRleHQgZm9ybWF0cyBzaG91bGRuJ3QgaGF2ZSBhbnkgSFRNTCB0YWdzIHJlbmRlcmVkLCBzbyAiZXNjYXBlIiB0aGVtIGJ5IGluc2VydGluZyBhcyB0ZXh0LgogICAgICAgICAgICAgICAgICAgIHRvSW5zZXJ0LnRleHQobWFjcm9Cb2R5KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdG9JbnNlcnQuaHRtbChtYWNyb0JvZHkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgQUpTLmxvZygiRXJyb3I6IGNhbm5vdCBmaW5kIG1hY3JvIGJvZHkiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGlueW1jZS5jb25mbHVlbmNlLm1hY3JvYnJvd3Nlci5wcm9jZXNzTWFjcm9zKCRtYWNybyk7CiAgICAgICAgICAgIHMuc2V0Q29udGVudCgkbWFjcm8uaHRtbCgpKTsKICAgICAgICB9OwogICAgICAgIAogICAgICAgIEFKUy5zYWZlLnBvc3QoQUpTLnBhcmFtcy5jb250ZXh0UGF0aCArICIvanNvbi9jb252ZXJ0d2lraW1hcmt1cHRveGh0bWx3aXRob3V0cGFnZXdpdGhzcGFjZWtleS5hY3Rpb24iLCBkYXRhLCBjYWxsYmFjaywgImpzb24iKTsKICAgIH07CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgaHRtbCBlbGVtZW50IHRoYXQgaXMgYW4gJ2VuY2xvc2luZyBibG9jaycgb2YgdGhlIGdpdmVuIG5vZGUuIEFuIGVuY2xvc2luZyBibG9jayBpbiB0aGlzIGNvbnRleHQKICAgICAqIHJlZmVycyB0byBhIGZvcm1hdCBibG9jayBkZXNjcmliZWQgaW4gZm9ybWF0RGVzY3JpcHRvcnMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGdldEVuY2xvc2luZ0Jsb2NrIChub2RlKSB7CgogICAgICAgIGlmICgvXihQfERJVnxIWzEtNl18UFJFKSQvaS50ZXN0KG5vZGUubm9kZU5hbWUpKSB7CiAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgIH0KICAgICAgICAvLyBvdGhlcndpc2Ugd2UgdHJ5IGFuZCBmaW5kIHRoZSBmaXJzdCBhbmNlc3RvciB0aGF0IGlzIGEgYmxvY2sgZWxlbWVudAogICAgICAgIHZhciBlbmNsb3NpbmdFbGVtID0gbnVsbDsKICAgICAgICAkKG5vZGUpLnBhcmVudHMoKS5lYWNoKGZ1bmN0aW9uKGksIHBhcmVudCkgewogICAgICAgICAgICBpZiAoL14oUHxESVZ8SFsxLTZdfFBSRSkkL2kudGVzdChwYXJlbnQubm9kZU5hbWUpKSB7CiAgICAgICAgICAgICAgICBlbmNsb3NpbmdFbGVtID0gcGFyZW50OwogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIGVuY2xvc2luZ0VsZW07CiAgICB9OwoKICAgIGZ1bmN0aW9uIGdldEVuY2xvc2luZ01hY3JvKCRub2RlKSB7CiAgICAgICAgcmV0dXJuICRub2RlLmhhc0NsYXNzKCJ3eXNpd3lnLW1hY3JvIikgPyAkbm9kZSA6ICRub2RlLnBhcmVudHMoImRpdi53eXNpd3lnLW1hY3JvOmZpcnN0Iik7CiAgICB9OwoKICAgIGZ1bmN0aW9uIGdldEZvcm1hdERlc2NyaXB0b3IoJG5vZGUpIHsKICAgICAgICB2YXIgbWFjcm9OYW1lID0gJG5vZGUuYXR0cigibWFjcm9uYW1lIik7CiAgICAgICAgcmV0dXJuIGZvcm1hdERlc2NyaXB0b3JzWyJtYWNyb18iICsgbWFjcm9OYW1lXTsKICAgIH07CgogICAgZnVuY3Rpb24gcmVtb3ZlRm9ybWF0KGVuY2xvc2luZ0Jsb2NrLCBkb21VdGlscywgZW5jbG9zaW5nTWFjcm8pIHsKICAgICAgICBBSlMubG9nKCJyZW1vdmVGb3JtYXQiKTsKICAgICAgICAvLyBDYW4ndCByZW1vdmUgZm9ybWF0IGZyb20gcmFuZ2UgLSBkb2Vzbid0IG1ha2Ugc2Vuc2UuCiAgICAgICAgaWYgKCFlbmNsb3NpbmdCbG9jaykgewogICAgICAgICAgICBBSlMubG9nKCJyZW1vdmVGb3JtYXQ6IGVuY2xvc2luZ0Jsb2NrIG51bGwsIHJldHVybmluZyIpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIHZhciBjb250ZW50LCAkZW5jbG9zaW5nQmxvY2sgPSAkKGVuY2xvc2luZ0Jsb2NrKTsKICAgICAgICAvLyBsb29rIGZvciBhbiBlbmNsb3NpbmcgbWFjcm8gZmlyc3QKICAgICAgICBlbmNsb3NpbmdNYWNybyA9IGVuY2xvc2luZ01hY3JvIHx8IGdldEVuY2xvc2luZ01hY3JvKCRlbmNsb3NpbmdCbG9jayk7CiAgICAgICAgaWYgKGVuY2xvc2luZ01hY3JvLmxlbmd0aCkgewogICAgICAgICAgICB2YXIgZGVzY3JpcHRvciA9IGdldEZvcm1hdERlc2NyaXB0b3IoZW5jbG9zaW5nTWFjcm8pOwogICAgICAgICAgICBpZiAoZGVzY3JpcHRvcikgewogICAgICAgICAgICAgICAgQUpTLmxvZygiUmVtb3ZlIG1hY3JvIGZvcm1hdDogIiArIGRlc2NyaXB0b3IubWFjcm9OYW1lKTsKICAgICAgICAgICAgICAgICRlbmNsb3NpbmdCbG9jayA9IGVuY2xvc2luZ01hY3JvOwogICAgICAgICAgICAgICAgY29udGVudCA9IGVuY2xvc2luZ01hY3JvLmZpbmQoZ2V0Qm9keVNlbGVjdG9yKGRlc2NyaXB0b3IpKTsKICAgICAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yLnJhd1RleHQpIHsKICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gY29udGVudC50ZXh0KCk7ICAgLy8gcmVtb3ZlcyBmb3JtYXR0aW5nIHRhZ3MgKGUuZy4gY29kZS1xdW90ZXMpIGJ1dCB1bmVzY2FwZXMgc2NyaXB0IHRhZ3MKICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gQUpTKCJpIikudGV4dChjb250ZW50KS5odG1sKCk7IC8vIGVzY2FwZXMgc2NyaXB0IHRhZ3MgYWdhaW4KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IGNvbnRlbnQuaHRtbCgpOyAgIC8vIHJlbW92ZXMgd3JhcHBlciBlbGVtZW50IGZyb20gYXJvdW5kIGNvbnRlbnQKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIWNvbnRlbnQpIHsKICAgICAgICAgICAgY29udGVudCA9IGVuY2xvc2luZ0Jsb2NrLmNoaWxkTm9kZXM7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGVuY2xvc2luZ0Jsb2NrLnBhcmVudCgiYm9keSIpLmxlbmd0aCkgewogICAgICAgICAgICAvLyBUZXh0IGluIHRoZSBlZGl0b3Igc2hvdWxkIG5ldmVyIGJlIGRpcmVjdGx5IGluc2lkZSB0aGUgYm9keSAtIHNob3VsZCBhdCBsZWFzdAogICAgICAgICAgICAvLyBiZSBpbiBhIHAuIFRoaXMgaXMgaG93IHRoZSB3aWtpLXJlbmRlcmVyIGRvZXMgaXQgdG9vLgogICAgICAgICAgICB2YXIgcCA9ICBkb21VdGlscy5jcmVhdGUoInAiKTsKICAgICAgICAgICAgJChwKS5hcHBlbmQoY29udGVudCk7CiAgICAgICAgICAgICRlbmNsb3NpbmdCbG9jay5yZXBsYWNlV2l0aChwKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRlbmNsb3NpbmdCbG9jay5yZXBsYWNlV2l0aChjb250ZW50KTsKICAgICAgICB9CiAgICB9Owp9KShBSlMuJCk7Cgp0aW55bWNlLmNvbmZsdWVuY2UubWFjcm9icm93c2VyID0gKGZ1bmN0aW9uKCQpIHsgcmV0dXJuIHsKICAgIC8qKgogICAgICogVGhlIGN1cnJlbnQgc2VsZWN0aW9uIHJhbmdlIGluIHRoZSBlZGl0b3IKICAgICAqLwogICAgc3RvcmVkUmFuZ2UgOiBudWxsLAogICAgLyoqCiAgICAgKiBUaGUgY3VycmVudCBib29rbWFyayBsb2NhdGlvbiBpbiB0aGUgZWRpdG9yCiAgICAgKi8KICAgIGJvb2ttYXJrIDogbnVsbCwKCiAgICBnZXRDdXJyZW50Tm9kZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gJCh0aW55TUNFLmFjdGl2ZUVkaXRvci5zZWxlY3Rpb24uZ2V0Tm9kZSgpKTsKICAgIH0sCiAgICBpc01hY3JvRGl2IDogZnVuY3Rpb24obm9kZSkgewogICAgICAgIHJldHVybiAkKG5vZGUpLmhhc0NsYXNzKCJ3eXNpd3lnLW1hY3JvIik7CiAgICB9LAogICAgaXNNYWNyb1RhZyA6IGZ1bmN0aW9uKG5vZGUpIHsKICAgICAgICByZXR1cm4gJChub2RlKS5oYXNDbGFzcygid3lzaXd5Zy1tYWNyby10YWciKTsKICAgIH0sCiAgICBpc01hY3JvU3RhcnRUYWcgOiBmdW5jdGlvbihub2RlKSB7CiAgICAgICAgcmV0dXJuICQobm9kZSkuaGFzQ2xhc3MoInd5c2l3eWctbWFjcm8tc3RhcnR0YWciKTsKICAgIH0sCiAgICBpc01hY3JvRW5kVGFnIDogZnVuY3Rpb24obm9kZSkgewogICAgICAgIHJldHVybiAkKG5vZGUpLmhhc0NsYXNzKCJ3eXNpd3lnLW1hY3JvLWVuZHRhZyIpOwogICAgfSwKICAgIGlzTWFjcm9Cb2R5IDogZnVuY3Rpb24obm9kZSkgewogICAgICAgIHJldHVybiAkKG5vZGUpLmhhc0NsYXNzKCJ3eXNpd3lnLW1hY3JvLWJvZHkiKTsKICAgIH0sCiAgICBoYXNNYWNyb0JvZHkgOiBmdW5jdGlvbihub2RlKSB7CiAgICAgICAgcmV0dXJuICQobm9kZSkuYXR0cigibWFjcm9oYXNib2R5IikgPT0gInRydWUiOwogICAgfSwKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBtYWNybyBuYW1lcyBmb3IgbWFjcm8gZGl2cyBlbmNsb3NpbmcgdGhlIGN1cnJlbnQgbm9kZS4KICAgICAqLwogICAgZ2V0TmVzdGluZ01hY3JvcyA6IGZ1bmN0aW9uKG5vZGUpIHsKICAgICAgICB2YXIgJG5vZGUgPSAkKG5vZGUgfHwgdGhpcy5nZXRDdXJyZW50Tm9kZSgpKTsKICAgICAgICB2YXIgbmVzdGluZ01hY3JvcyA9IFtdOwogICAgICAgICRub2RlLnBhcmVudHMoIi53eXNpd3lnLW1hY3JvIikuZWFjaChmdW5jdGlvbigpIHsKICAgICAgICAgICAgbmVzdGluZ01hY3Jvcy5wdXNoKCQodGhpcykuYXR0cigibWFjcm9uYW1lIikpOwogICAgICAgIH0pOwogICAgICAgIHJldHVybiBuZXN0aW5nTWFjcm9zOwogICAgfSwKICAgIHByb2Nlc3NNYWNyb3MgOiBmdW5jdGlvbihub2RlLCBlZGl0b3IpIHsKICAgICAgICAvLyB0aGUgZWRpdG9yIHdlJ3JlIHdvcmtpbmcgd2l0aCBpcyBub3QgYWx3YXlzIHRoZSBhY3RpdmUgb25lIGkuZSBmdWxsc2NyZWVuIC0+IG5vcm1hbAogICAgICAgIGVkaXRvciA9IGVkaXRvciB8fCB0aW55TUNFLmFjdGl2ZUVkaXRvcjsKICAgICAgICB2YXIgZG9tVXRpbHMgPSBlZGl0b3IuZG9tOwoKICAgICAgICAvLyB3cmFwIG1hY3JvIGJvZHkgZWxtZW50cyBpbiBhIHAgaWYgbm9uZSBleGlzdHMKICAgICAgICAkKCIud3lzaXd5Zy1tYWNyby1ib2R5Iiwgbm9kZSkuZWFjaChmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIG1hY3JvQm9keSA9IHRoaXM7CiAgICAgICAgICAgIGlmICghbWFjcm9Cb2R5LmZpcnN0Q2hpbGQpIHsKICAgICAgICAgICAgICAgIGRvbVV0aWxzLmFkZChtYWNyb0JvZHksICJwIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZighKCQobWFjcm9Cb2R5LmZpcnN0Q2hpbGQpLmlzKCJwLCBwcmUsIC53eXNpd3lnLW1hY3JvIikpKSB7CiAgICAgICAgICAgICAgICB2YXIgcCA9IGRvbVV0aWxzLmNyZWF0ZSgicCIpOwogICAgICAgICAgICAgICAgd2hpbGUgKG1hY3JvQm9keS5maXJzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgcC5hcHBlbmRDaGlsZChtYWNyb0JvZHkuZmlyc3RDaGlsZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkb21VdGlscy5hZGQobWFjcm9Cb2R5LCBwKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIEFKUy5FZGl0b3IuQWRhcHRlci5vblNldENvbnRlbnQobm9kZSk7CiAgICB9LAogICAgZmx1c2hSZWR1bmRhbnRQYWRkaW5nIDogZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBkb21VdGlscyA9IHRpbnlNQ0UuYWN0aXZlRWRpdG9yLmRvbTsKICAgICAgICAvLyByZW1vdmUgdW5uZWNlc3NhcnkgcCdzIGFkZGVkIGJ5IENvbmZsdWVuY2UncyByZW5kZXJlcgogICAgICAgICQoInAuYXRsX2NvbmZfcGFkIiwgdGlueU1DRS5hY3RpdmVFZGl0b3IuZ2V0RG9jKCkpLmVhY2goZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICgkKHRoaXMpLm5leHQoKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIEFKUy5sb2coIm9uU2V0Q29udGVudDogcmVtb3ZpbmcgcC5hdGxfY29uZl9wYWQiKTsKICAgICAgICAgICAgICAgIGRvbVV0aWxzLnJlbW92ZSh0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfSwKCiAgICBoYW5kbGVLZXlQcmVzc0luTWFjcm9UYWcgOiBmdW5jdGlvbiAoaXNSZXR1cm4sIGNvZGUsIHNlbGVjdGlvbk5vZGUpIHsKICAgICAgICB2YXIgdCA9IHRpbnltY2UuY29uZmx1ZW5jZS5tYWNyb2Jyb3dzZXIsIGRvbVV0aWxzID0gdGlueU1DRS5hY3RpdmVFZGl0b3IuZG9tOwogICAgICAgIHZhciBzID0gdGlueU1DRS5hY3RpdmVFZGl0b3Iuc2VsZWN0aW9uOwoKICAgICAgICB2YXIgcENvbnRlbnQgPSBpc1JldHVybiA/ICImbmJzcDsiIDogU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKTsKICAgICAgICB2YXIgbWFjcm9EaXYgPSBzZWxlY3Rpb25Ob2RlLnBhcmVudE5vZGU7CiAgICAgICAgdmFyIGhhc01hY3JvQm9keSA9IHQuaGFzTWFjcm9Cb2R5KG1hY3JvRGl2KTsKICAgICAgICB2YXIgYm9keURpdiA9IGhhc01hY3JvQm9keSA/ICQoIi53eXNpd3lnLW1hY3JvLWJvZHk6Zmlyc3QiLCBtYWNyb0RpdilbMF0gOiBudWxsOwoKICAgICAgICB2YXIgcm5nOwogICAgICAgIGlmIChBSlMuRWRpdG9yLkFkYXB0ZXIuSUVSYW5nZSkgewogICAgICAgICAgICBybmcgPSBBSlMuRWRpdG9yLkFkYXB0ZXIuSUVSYW5nZS5nZXRTZWxlY3Rpb24oKS5nZXRSYW5nZUF0KDApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJuZyA9IHMuZ2V0Um5nKCk7CiAgICAgICAgfQoKICAgICAgICB2YXIgY3Vyc29yTG9jYXRpb24gPSBybmcuc3RhcnRPZmZzZXQ7CiAgICAgICAgdmFyIGF0U3RhcnRPZk1hY3JvVGFnID0gY3Vyc29yTG9jYXRpb24gPT0gMDsKICAgICAgICB2YXIgZXh0cmFOb2RlOwogICAgICAgIHZhciBuZXdOb2RlTmFtZTsKICAgICAgICBpZiAoYXRTdGFydE9mTWFjcm9UYWcpIHsKICAgICAgICAgICAgLy8gQ3Vyc29yIGlzIGF0IHN0YXJ0IG9mIGVpdGhlciB0aGUgc3RhcnQgb3IgZW5kIHRhZyAoaWYgcHJlc2VudCkKICAgICAgICAgICAgaWYgKHQuaXNNYWNyb1N0YXJ0VGFnKHNlbGVjdGlvbk5vZGUpKSB7CiAgICAgICAgICAgICAgICBleHRyYU5vZGUgPSBkb21VdGlscy5jcmVhdGUoInAiLCB7fSwgcENvbnRlbnQpOwogICAgICAgICAgICAgICAgLy8gdHlwaW5nIGF0IHN0YXJ0IG9mIHN0YXJ0aW5nIHRhZyAtIGluc2VydCBwYXJhIGJlZm9yZSBtYWNybyBkaXYuCiAgICAgICAgICAgICAgICB2YXIgcGFyZW50ID0gbWFjcm9EaXYucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoZXh0cmFOb2RlLCBtYWNyb0Rpdik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBhdCBzdGFydCBvZiBlbmQgdGFnLCBhZGQgdGV4dCB0byBib2R5IGluIG5vZGUgd2l0aCBzYW1lIHR5cGUgYXMgYm9keSBub2RlcwogICAgICAgICAgICAgICAgbmV3Tm9kZU5hbWUgPSAkKCI6Zmlyc3QiLCBib2R5RGl2KVswXS5ub2RlTmFtZSB8fCAicCI7CiAgICAgICAgICAgICAgICBleHRyYU5vZGUgPSBkb21VdGlscy5jcmVhdGUobmV3Tm9kZU5hbWUsIHt9LCBwQ29udGVudCk7CiAgICAgICAgICAgICAgICBib2R5RGl2LmFwcGVuZENoaWxkKGV4dHJhTm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBBSlMubG9nKCJOb3QgYXRTdGFydE9mTWFjcm9UYWciKTsKICAgICAgICAgICAgLy8gQ3Vyc29yIGlzIGVpdGhlciBpbnNpZGUgdGhlIHRhZyBvciBhdCB0aGUgZW5kLgogICAgICAgICAgICB2YXIgbmVlZHNQID0gaXNSZXR1cm4gfHwgdC5pc01hY3JvRW5kVGFnKHNlbGVjdGlvbk5vZGUpOwogICAgICAgICAgICBpZiAoIW5lZWRzUCkgewogICAgICAgICAgICAgICAgdmFyIG1hY3JvVGFnVGV4dCA9ICQoc2VsZWN0aW9uTm9kZSkudGV4dCgpOwogICAgICAgICAgICAgICAgLy8gQXNzdW1lcyB0aGF0IGRpdiB0ZXh0IGlzIGEgc2luZ2xlIG5vZGUgYW5kIHRoZSBjdXJzb3IgaXMgYXQgdGhlIGVuZCBvZiB0aGUgdGV4dCAoYWZ0ZXIgdGhlICd9JykKICAgICAgICAgICAgICAgIG5lZWRzUCA9IGN1cnNvckxvY2F0aW9uID09IG1hY3JvVGFnVGV4dC5sZW5ndGg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFuZWVkc1ApIHsKICAgICAgICAgICAgICAgIC8vIFR5cGluZyBpbnNpZGUgdGhlIHN0YXJ0IHRhZyAtIGFsbG93LgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChoYXNNYWNyb0JvZHkgJiYgdC5pc01hY3JvU3RhcnRUYWcoc2VsZWN0aW9uTm9kZSkpIHsKICAgICAgICAgICAgICAgIC8vIGluc2VydCBhcHByb3ByaWF0ZSBuZXcgbm9kZSBhdCBzdGFydCBvZiBib2R5LCBpbnNpZGUgYm9keSBkaXYKICAgICAgICAgICAgICAgIG5ld05vZGVOYW1lID0gJCgiOmZpcnN0IiwgYm9keURpdilbMF0ubm9kZU5hbWUgfHwgInAiOwogICAgICAgICAgICAgICAgZXh0cmFOb2RlID0gZG9tVXRpbHMuY3JlYXRlKG5ld05vZGVOYW1lLCB7fSwgcENvbnRlbnQpOwogICAgICAgICAgICAgICAgYm9keURpdi5pbnNlcnRCZWZvcmUoZXh0cmFOb2RlLCBib2R5RGl2LmZpcnN0Q2hpbGQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gcHV0IGFmdGVyIHRoZSBlbnRpcmUgbWFjcm8KICAgICAgICAgICAgICAgIGV4dHJhTm9kZSA9IGRvbVV0aWxzLmNyZWF0ZSgicCIsIHt9LCBwQ29udGVudCk7CiAgICAgICAgICAgICAgICBkb21VdGlscy5pbnNlcnRBZnRlcihleHRyYU5vZGUsIG1hY3JvRGl2KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzLnNlbGVjdChleHRyYU5vZGUsIHRydWUpOyAgLy8gc2VsZWN0IHRoZSB0ZXh0bm9kZSBpbiB0aGUgcCByYXRoZXIgdGhhbiB0aGUgcCBpdHNlbGYKICAgICAgICBzLmNvbGxhcHNlKGlzUmV0dXJuKTsgLy8gY29sbGFwc2UgdG8gZW5kIChhZnRlciB0aGUgbmV3IGNoYXJhY3Rlcikgb3Igc3RhcnQgKGJlZm9yZSBuYnNwKQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9LAoKICAgIG9uVGlueU1jZUluaXRpYWxpc2VkIDogZnVuY3Rpb24oZWRpdG9yKSB7CiAgICAgICAgdmFyIHQgPSB0aW55bWNlLmNvbmZsdWVuY2UubWFjcm9icm93c2VyOwoKICAgICAgICBlZGl0b3Iub25TZXRDb250ZW50LmFkZChmdW5jdGlvbihlZGl0b3IpIHsKICAgICAgICAgICAgQUpTLmxvZygib25TZXRDb250ZW50OiBwcm9jZXNzIG1hY3JvcyBhbmQgcmVtb3ZlIHVuY2Vzc2FyeSBwJ3MiKTsKICAgICAgICAgICAgdC5wcm9jZXNzTWFjcm9zKGVkaXRvci5nZXREb2MoKSwgZWRpdG9yKTsKICAgICAgICAgICAgdC5mbHVzaFJlZHVuZGFudFBhZGRpbmcoKTsKICAgICAgICB9KTsKCiAgICAgICAgLy8gb3ZlcnJpZGUgZW50ZXIga2V5IHByZXNzIG9uIG1hY3JvIHRhZ3Mgc28gaXQgYWRkcyBhICdwJyBpbnN0ZWFkIG9mIGEgJ2RpdicKICAgICAgICBlZGl0b3Iub25LZXlQcmVzcy5hZGRUb1RvcChmdW5jdGlvbihlZGl0b3IsIGUpIHsKCiAgICAgICAgICAgIC8vIElnbm9yZSBrZXkgY29tYmluYXRpb25zLgogICAgICAgICAgICBpZiAoZS5jdHJsS2V5IHx8IGUubWV0YUtleSB8fCBlLmFsdEtleSkgcmV0dXJuIHRydWU7CgogICAgICAgICAgICAvLyBJZ25vcmUgYXJyb3dzLCB0YWJzLCBldGMuIFRPRE8gLSBmaW5kIGRpc3BsYXlhYmxlIGNoYXJzIGJldHRlci4KICAgICAgICAgICAgdmFyIGNvZGUgPSBlLmNoYXJDb2RlIHx8IGUua2V5Q29kZTsKICAgICAgICAgICAgdmFyIGlzUHJpbnRhYmxlQ2hhciA9IGZhbHNlOyAgLy8gKGNvZGUgPj0gMzIgJiYgY29kZSA8PSAxMjYpOwogICAgICAgICAgICB2YXIgaXNSZXR1cm4gPSAoY29kZSA9PSAxMyAmJiAhZS5zaGlmdEtleSk7CiAgICAgICAgICAgIGlmICghaXNSZXR1cm4gJiYgIWlzUHJpbnRhYmxlQ2hhcikgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIElnbm9yZSBhbnl0aGluZyBvdXRzaWRlIGEgbWFjcm8gdGFnLgogICAgICAgICAgICB2YXIgcyA9IGVkaXRvci5zZWxlY3Rpb24sIHNlbGVjdGlvbk5vZGUgPSBzLmdldE5vZGUoKTsKICAgICAgICAgICAgaWYgKCF0LmlzTWFjcm9UYWcoc2VsZWN0aW9uTm9kZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgcmV0dXJuVmFsID0gdC5oYW5kbGVLZXlQcmVzc0luTWFjcm9UYWcoaXNSZXR1cm4sIGNvZGUsIHNlbGVjdGlvbk5vZGUpOwogICAgICAgICAgICBpZiAoIXJldHVyblZhbCkKICAgICAgICAgICAgICAgIHRpbnltY2UuZG9tLkV2ZW50LmNhbmNlbChlKTsKCiAgICAgICAgICAgIHJldHVybiByZXR1cm5WYWw7CiAgICAgICAgfSk7CiAgICB9LAoKICAgIGxvZ01DRVNlbGVjdGlvbiA6IGZ1bmN0aW9uICh0aXRsZSkgewogICAgICAgIHZhciBzID0gdGlueU1DRS5hY3RpdmVFZGl0b3Iuc2VsZWN0aW9uOwogICAgICAgIEFKUy5sb2coIioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiIpOwogICAgICAgIEFKUy5sb2coIkxvZ2dpbmcgVGlueU1DRSBzZWxlY3Rpb24gdGl0bGU6ICAgICIgKyB0aXRsZSk7CiAgICAgICAgQUpTLmxvZygiQm9va21hcms6Iik7CiAgICAgICAgQUpTLmxvZyhzLmdldEJvb2ttYXJrKCkpOwogICAgICAgIHZhciByYW5nZU5vZGVUZXh0ID0gJChzLmdldFJuZygpLnN0YXJ0Q29udGFpbmVyKS50ZXh0KCkgfHwgJChzLmdldFJuZygpLnN0YXJ0Q29udGFpbmVyLnBhcmVudE5vZGUpLnRleHQoKTsKICAgICAgICBBSlMubG9nKCJSYW5nZTogIiArIHJhbmdlTm9kZVRleHQpOwogICAgICAgIEFKUy5sb2cocy5nZXRSbmcoKSk7CiAgICB9LAoKICAgIGdldFNlbGVjdGVkTWFjcm8gOiBmdW5jdGlvbihlZGl0b3IpIHsKICAgICAgICB2YXIgdCA9IHRpbnltY2UuY29uZmx1ZW5jZS5tYWNyb2Jyb3dzZXIsCiAgICAgICAgICAgICRzZWxlY3Rpb25Ob2RlID0gdC5nZXRDdXJyZW50Tm9kZSgpOwogICAgICAgIEFKUy5sb2coImdldFNlbGVjdGVkTWFjcm86ICRzZWxlY3Rpb25Ob2RlPSIgKyAkc2VsZWN0aW9uTm9kZVswXSk7CiAgICAgICAgLy8gd2hlbiB3ZSB1cGdyYWRlIHRvIGpxdWVyeSAxLjMgdXNlIGNsb3Nlc3QoKSBpbnN0ZWFkIG9mIHBhcmVudHMoKQogICAgICAgIHJldHVybiB0LmlzTWFjcm9EaXYoJHNlbGVjdGlvbk5vZGUpID8gJHNlbGVjdGlvbk5vZGUgOiAkc2VsZWN0aW9uTm9kZS5wYXJlbnRzKCIud3lzaXd5Zy1tYWNybzpmaXJzdCIpOwogICAgfSwKCiAgICBvcGVuTWFjcm8gOiBmdW5jdGlvbihtYWNybykgewogICAgICAgIEFKUy5NYWNyb0Jyb3dzZXIub3Blbih7CiAgICAgICAgICAgIHNlbGVjdGVkTWFjcm8gOiBtYWNybywKICAgICAgICAgICAgb25Db21wbGV0ZSA6IHRpbnltY2UuY29uZmx1ZW5jZS5tYWNyb2Jyb3dzZXIubWFjcm9Ccm93c2VyQ29tcGxldGUsCiAgICAgICAgICAgIG9uQ2FuY2VsIDogdGlueW1jZS5jb25mbHVlbmNlLm1hY3JvYnJvd3Nlci5tYWNyb0Jyb3dzZXJDYW5jZWwKICAgICAgICB9KTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBDYWxsZWQgdG8gaW5zZXJ0IGEgbmV3IG1hY3JvLgogICAgICogSWYgdXNlciBoYXMgbm90IHNlbGVjdGVkIHRleHQsIGp1c3Qgb3BlbiB0aGUgTWFjcm8gQnJvd3Nlci4KICAgICAqIElmIHVzZXIgaGFzIHNlbGVjdGVkIHRleHQsIGl0IHdpbGwgY29udmVydCBpdCB0byB3aWtpIG1hcmt1cCBmb3IgdGhlIGJvZHkgb2YgdGhlIG1hY3JvCiAgICAgKi8KICAgIG1hY3JvQnJvd3NlclRvb2xiYXJCdXR0b25DbGlja2VkIDogZnVuY3Rpb24ob3B0aW9ucykgewoKICAgICAgICB2YXIgdCA9IHRpbnltY2UuY29uZmx1ZW5jZS5tYWNyb2Jyb3dzZXIsCiAgICAgICAgICAgIGVkaXRvciA9IHRpbnlNQ0UuYWN0aXZlRWRpdG9yLAogICAgICAgICAgICBub2RlID0gdC5nZXRDdXJyZW50Tm9kZSgpOwoKICAgICAgICBBSlMuRWRpdG9yLkFkYXB0ZXIuc3RvcmVDdXJyZW50U2VsZWN0aW9uU3RhdGUoKTsKCiAgICAgICAgLy8gRWRpdGluZyBhbiBleGlzdGluZyBtYWNybwogICAgICAgIGlmICghb3B0aW9ucy5pZ25vcmVFZGl0b3JTZWxlY3Rpb24gJiYgdC5pc01hY3JvVGFnKG5vZGUpKSB7CiAgICAgICAgICAgIHZhciBtYWNyb0RpdiA9IG5vZGUucGFyZW50KClbMF07CiAgICAgICAgICAgIGVkaXRvci5zZWxlY3Rpb24uc2VsZWN0KG1hY3JvRGl2KTsgICAgICAvLyBzZWxlY3QgdGhlIGVudGlyZSBtYWNybyBmb3IgdGhlIHVzZXIgdG8gc2VlCiAgICAgICAgICAgIHQuZWRpdGVkTWFjcm9EaXYgPSBtYWNyb0RpdjsKICAgICAgICAgICAgdmFyIG1hY3JvSHRtbCA9IHRpbnltY2UuRE9NLmdldE91dGVySFRNTChtYWNyb0Rpdik7CiAgICAgICAgICAgIAogICAgICAgICAgICBBSlMuc2FmZS5wb3N0KEFKUy5wYXJhbXMuY29udGV4dFBhdGggKyAiL2pzb24vY29udmVydHhodG1sdG93aWtpbWFya3Vwd2l0aG91dHBhZ2UuYWN0aW9uIiwge3BhZ2VJZDogQUpTLkVkaXRvci5nZXRDb250ZW50SWQoKSwgeGh0bWw6IG1hY3JvSHRtbH0sIGZ1bmN0aW9uKG1hcmt1cCkgewogICAgICAgICAgICAgICAgdC5lZGl0ZWRNYWNybyA9IEFKUy5NYWNyb0Jyb3dzZXIucGFyc2VNYWNybyhtYXJrdXApOwogICAgICAgICAgICAgICAgdC5vcGVuTWFjcm8odC5lZGl0ZWRNYWNybyk7CiAgICAgICAgICAgIH0sICJqc29uIik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgLy8gSW5zZXJ0aW5nIG5ldyBtYWNybwogICAgICAgIHZhciBzZXR0aW5ncyA9ICQuZXh0ZW5kKHsKICAgICAgICAgICAgbmVzdGluZ01hY3JvcyA6IHQuZ2V0TmVzdGluZ01hY3Jvcyhub2RlKSwKICAgICAgICAgICAgb25Db21wbGV0ZSA6IHQubWFjcm9Ccm93c2VyQ29tcGxldGUsCiAgICAgICAgICAgIG9uQ2FuY2VsIDogdC5tYWNyb0Jyb3dzZXJDYW5jZWwsCiAgICAgICAgICAgIG1vZGUgOiAiaW5zZXJ0IgogICAgICAgIH0sIG9wdGlvbnMpOwoKICAgICAgICB2YXIgc2VsZWN0ZWRIdG1sID0gIW9wdGlvbnMuaWdub3JlRWRpdG9yU2VsZWN0aW9uICYmIGVkaXRvci5zZWxlY3Rpb24uZ2V0Q29udGVudCgpOwogICAgICAgIGlmICghc2VsZWN0ZWRIdG1sKSB7IC8vIG5vIHNlbGVjdGVkIHRleHQKICAgICAgICAgICAgQUpTLk1hY3JvQnJvd3Nlci5vcGVuKHNldHRpbmdzKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gc2VsZWN0ZWQgdGV4dCBmb3IgdGhlIG1hY3JvIGJvZHkKICAgICAgICBBSlMuc2FmZS5wb3N0KEFKUy5wYXJhbXMuY29udGV4dFBhdGggKyAiL2pzb24vY29udmVydHhodG1sdG93aWtpbWFya3Vwd2l0aG91dHBhZ2UuYWN0aW9uIiwge3BhZ2VJZDogQUpTLkVkaXRvci5nZXRDb250ZW50SWQoKSwgeGh0bWw6IHNlbGVjdGVkSHRtbH0sIGZ1bmN0aW9uKG1hcmt1cCkgewogICAgICAgICAgICBzZXR0aW5ncy5zZWxlY3RlZE1hcmt1cCA9IG1hcmt1cDsKICAgICAgICAgICAgc2V0dGluZ3Muc2VsZWN0ZWRIdG1sID0gc2VsZWN0ZWRIdG1sOwogICAgICAgICAgICBBSlMuTWFjcm9Ccm93c2VyLm9wZW4oc2V0dGluZ3MpOwogICAgICAgIH0sICJqc29uIik7CiAgICB9LAogICAgLyoqCiAgICAgKiBUYWtlcyBtYWNybyBtYXJrdXAgKHVzdWFsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBNYWNybyBCcm93c2VyKSBhbmQgaW5zZXJ0cy91cGRhdGVzIHRoZSByZWxldmFudCBNYWNybyBtYWNyb0hlYWRlcgogICAgICogaW4gdGhlIFJURS4KICAgICAqIEBwYXJhbSBtYWNybyBtYWNybyBvYmplY3QgZGVzY3JpYmluZyBpbnNlcnRlZC9lZGl0ZWQgbWFjcm8KICAgICAqLwogICAgbWFjcm9Ccm93c2VyQ29tcGxldGUgOiBmdW5jdGlvbihtYWNybykgewogICAgICAgIHZhciB0ID0gdGlueW1jZS5jb25mbHVlbmNlLm1hY3JvYnJvd3NlcjsKCiAgICAgICAgLy8gUHV0IGFueSBzdGFydGluZyBhbmQgZW5kaW5nIHRleHQgZnJvbSBhbiBlZGl0ZWQgbWFjcm8gYXJvdW5kIHRoZSBtYWNybyB0YWdzLgogICAgICAgIGlmICh0LmVkaXRlZE1hY3JvKSB7CiAgICAgICAgICAgIGlmICh0LmVkaXRlZE1hY3JvLmJlZm9yZVRhZykgewogICAgICAgICAgICAgICAgbWFjcm8ubWFya3VwID0gdC5lZGl0ZWRNYWNyby5iZWZvcmVUYWcgKyBtYWNyby5tYXJrdXA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHQuZWRpdGVkTWFjcm8uYWZ0ZXJUYWcpIHsKICAgICAgICAgICAgICAgIG1hY3JvLm1hcmt1cCArPSB0LmVkaXRlZE1hY3JvLmFmdGVyVGFnOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHQuaW5zZXJ0TWFjcm9BdFNlbGVjdGlvbkZyb21NYXJrdXAobWFjcm8ubWFya3VwKTsKICAgIH0sCgogICAgaW5zZXJ0TWFjcm9BdFNlbGVjdGlvbkZyb21NYXJrdXA6IGZ1bmN0aW9uIChtYXJrdXAsIGNhbGxiYWNrKSB7CiAgICAgICAgdmFyIHQgPSB0aW55bWNlLmNvbmZsdWVuY2UubWFjcm9icm93c2VyLAogICAgICAgICAgICBjb250ZW50SWQgPSBBSlMucGFyYW1zLmNvbnRlbnRJZCB8fCAiMCI7CiAgICAgICAgQUpTLnNhZmUucG9zdChBSlMucGFyYW1zLmNvbnRleHRQYXRoICsgIi9qc29uL2NvbnZlcnR3aWtpbWFya3VwdG94aHRtbHdpdGhvdXRwYWdld2l0aHNwYWNla2V5LmFjdGlvbiIsIAogICAgICAgICAgICB7cGFnZUlkOiBjb250ZW50SWQsIHNwYWNlS2V5OiBBSlMucGFyYW1zLnNwYWNlS2V5LCB3aWtpTWFya3VwOiBtYXJrdXB9LAogICAgICAgICAgICBmdW5jdGlvbiAobWFjcm9IdG1sKSB7CiAgICAgICAgICAgICAgICB2YXIgZWQgPSB0aW55TUNFLmFjdGl2ZUVkaXRvciwKICAgICAgICAgICAgICAgICAgICBtYWNybyA9IGVkLmRvbS5jcmVhdGUoImRpdiIsIHt9LCBtYWNyb0h0bWwpOwogICAgICAgICAgICAgICAgdC5wcm9jZXNzTWFjcm9zKG1hY3JvKTsKCiAgICAgICAgICAgICAgICAvLyBUaGUgY29udmVydGVyIGNhbGwgYWJvdmUgZG9lc24ndCBrbm93IGlmIGl0IHNob3VsZCBoYXZlIGxpbmVzIGJlZm9yZS9hZnRlciBzbyBhZGQgYm90aCBiZWNhdXNlIGl0J3MKICAgICAgICAgICAgICAgIC8vIGJldHRlciB0aGFuIGxvc2luZyBib3RoLgogICAgICAgICAgICAgICAgJCgiLnd5c2l3eWctbWFjcm8iLCBtYWNybykuYXR0cigid2lraWhhc3ByZWNlZGluZ25ld2xpbmUiLCAidHJ1ZSIpLmF0dHIoIndpa2loYXN0cmFpbGluZ25ld2xpbmUiLCAidHJ1ZSIpOwoKICAgICAgICAgICAgICAgIEFKUy5FZGl0b3IuQWRhcHRlci5yZXN0b3JlU2VsZWN0aW9uU3RhdGUoKTsgIC8vIHJlc3RvcmVzIHRvIG9yaWdpbmFsIGNhcmV0IG9yIHJhbmdlIHVzZXIgd2FzIGF0CiAgICAgICAgICAgICAgICBBSlMuRWRpdG9yLkFkYXB0ZXIuc2V0Tm9kZUF0Q3Vyc29yKG1hY3JvLCB0LmVkaXRlZE1hY3JvRGl2KTsKICAgICAgICAgICAgICAgIHQuZWRpdGVkTWFjcm9EaXYgJiYgKHQuZWRpdGVkTWFjcm9EaXYgPSBudWxsKTsKCiAgICAgICAgICAgICAgICB0LmZsdXNoUmVkdW5kYW50UGFkZGluZygpOwoKICAgICAgICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJqc29uIgogICAgICAgICk7CiAgICB9LAogICAgLy8gQ2FsbGVkIHdoZW4gdGhlIG1hY3JvIGJyb3dzZXIgaXMgY2xvc2VkIHRvIGNsZWFuIHVwIGFuZCByZXNldCBkYXRhLgogICAgbWFjcm9Ccm93c2VyQ2FuY2VsIDogZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIHQgPSB0aW55bWNlLmNvbmZsdWVuY2UubWFjcm9icm93c2VyOwogICAgICAgIEFKUy5FZGl0b3IuQWRhcHRlci5yZXN0b3JlU2VsZWN0aW9uU3RhdGUoKTsKICAgICAgICB0LmVkaXRlZE1hY3JvRGl2ID0gbnVsbDsKICAgICAgICB0LmVkaXRlZE1hY3JvID0gbnVsbDsKICAgIH0KfTt9KShBSlMuJCk7CgooZnVuY3Rpb24oJCkgewogICAgLyoqCiAgICAgKiBLZXlzIG9mIHByb3BlcnRpZXMgdGhhdCBzaG91bGQgYmUgc3RvcmVkIGluIHRoZSB3aWtpIG1hcmt1cCBvZiB0aGUgaW1hZ2UuCiAgICAgKi8KICAgIHZhciBpbWFnZXRleHRLZXlzID0gWyJhbGlnbiIsICJ0aHVtYm5haWwiLCAiYm9yZGVyIiwgIndpZHRoIiwgImhlaWdodCJdLAoKICAgICAgICAvKioKICAgICAgICAgKiAgS2V5cyBvZiBwcm9wZXJ0aWVzIHRoYXQgc2hvdWxkIGJlIHN0b3JlZCBhcyBhdHRyaWJ1dGVzIG9mIHRoZSBpbWFnZSBlbGVtZW50LgogICAgICAgICAqLwogICAgICAgIGltYWdlRWxlbWVudEF0dHJpYnV0ZUtleXMgPSAgWyJpbWFnZXRleHQiLCAic3JjIiwgImFsaWduIiwgImJvcmRlciIsICJ3aWR0aCIsICJoZWlnaHQiXSwKCiAgICAgICAgLyoqCiAgICAgICAgICogRXh0cmFjdHMgdGhlIGZpbGVuYW1lIGZyb20gdGhlIHdpa2ktbWFya3VwIGRlc3RpbmF0aW9uLgogICAgICAgICAqCiAgICAgICAgICogRS5nLiBleHRyYWN0cyAic3RhcnJ5TmlnaHQucG5nIi8qdHBhPWh0dHA6Ly8xMC4yMC4xNjAuMTk4L3dpa2kvcy9lbi8yMTY2LzM0LzMuNS45L18vZG93bmxvYWQvYmF0Y2gvY29tLmF0bGFzc2lhbi5jb25mbHVlbmNlLnRpbnltY2VwbHVnaW46ZWRpdG9yLXJlc291cmNlcy9zdGFycnlOaWdodC5wbmcqLyBmcm9tIFRTVDpUZXN0IFBhZ2Vec3RhcnJ5TmlnaHQucG5nIgogICAgICAgICAqLwogICAgICAgIGdldEltYWdlRmlsZU5hbWVGcm9tRGVzdGluYXRpb24gPSBmdW5jdGlvbiAoZGVzdGluYXRpb24pIHsKICAgICAgICAgICAgdmFyIGNhcmV0SW5kZXggPSBkZXN0aW5hdGlvbi5pbmRleE9mKCJeIik7CiAgICAgICAgICAgIHJldHVybiBkZXN0aW5hdGlvbi5zdWJzdHJpbmcoY2FyZXRJbmRleCArIDEpOwogICAgICAgIH0sCgoKICAgICAgICBjcmVhdGVGcm9tTWFya3VwID0gZnVuY3Rpb24gKG1hcmt1cCkgewogICAgICAgICAgICB2YXIgbWFya3VwUGFydHMgPSBtYXJrdXAuc3BsaXQoInwiKSwKICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSAobWFya3VwUGFydHNbMV0gJiYgbWFya3VwUGFydHNbMV0uc3BsaXQoIiwiKSkgfHwgW107CgogICAgICAgICAgICB2YXIgaW1hZ2VQcm9wZXJ0aWVzID0gewogICAgICAgICAgICAgICAgZGVzdGluYXRpb246IG1hcmt1cFBhcnRzWzBdCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBpZiAodGlueW1jZS5jb25mbHVlbmNlLkltYWdlVXRpbHMuaXNSZW1vdGVJbWcoaW1hZ2VQcm9wZXJ0aWVzLmRlc3RpbmF0aW9uKSkgewogICAgICAgICAgICAgICAgaW1hZ2VQcm9wZXJ0aWVzLnVybCA9IGltYWdlUHJvcGVydGllcy5kZXN0aW5hdGlvbjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGltYWdlUHJvcGVydGllcy5pbWFnZUZpbGVOYW1lID0gZ2V0SW1hZ2VGaWxlTmFtZUZyb21EZXN0aW5hdGlvbihpbWFnZVByb3BlcnRpZXMuZGVzdGluYXRpb24pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBhdHRyaWJ1dGVzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBwYXJ0cyA9IGF0dHJpYnV0ZXNbaV0uc3BsaXQoIj0iKTsKICAgICAgICAgICAgICAgIGltYWdlUHJvcGVydGllc1twYXJ0c1swXV0gPSBwYXJ0c1sxXSB8fCB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gaW1hZ2VQcm9wZXJ0aWVzOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBwYWdlSWQgZm9yIHRoZSBjb250ZW50IG93bmluZyB0aGUgaW1hZ2UgYXR0YWNobWVudCBpcyBub3QKICAgICAgICAgKiBzdG9yZWQgYWdhaW5zdCB0aGUgaW1hZ2UgZWxlbWVudCBkaXJlY3RseSwgc28gd2UgZXh0cmFjdCBpdCBmcm9tIHRoZQogICAgICAgICAqIGltYWdlIGVsZW1lbnQncyBzcmMgYXR0cmlidXRlLgogICAgICAgICAqCiAgICAgICAgICogZS5nLiAvY29uZmx1ZW5jZS9kb3dubG9hZC9hdHRhY2htZW50cy8yMTI5OTM1L2NhNS5naWYgZXh0cmFjdHMgIjIxMjk5MzUiCiAgICAgICAgICogICAgICAvY29uZmx1ZW5jZS9kb3dubG9hZC90aHVtYm5haWxzLzIxMjk5MzUvY2E1LmdpZiBBTFNPIGV4dHJhY3RzICIyMTI5OTM1IgogICAgICAgICAqLwogICAgICAgIGdldFBhZ2VJZEZyb21JbWFnZUVsZW1lbnQgPSBmdW5jdGlvbiAoaW1nRWwpIHsKICAgICAgICAgICAgdmFyIHNyYyA9ICQoaW1nRWwpLmF0dHIoInNyYyIpLAogICAgICAgICAgICAgICAgbWF0Y2hlcyA9IHNyYy5tYXRjaCgvXC9kb3dubG9hZFwvKHRodW1ibmFpbHN8YXR0YWNobWVudHMpXC8oWzAtOV0rKVwvLyk7CiAgICAgICAgICAgIGlmIChtYXRjaGVzLmxlbmd0aCA9PSAzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlc1syXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBBSlMubG9nKCJFUlJPUjogY291bGQgbm90IHBhcnNlIHBhZ2UgaWQgZnJvbSBpbWFnZSB1cmwgIiArIHNyYyk7CiAgICAgICAgICAgIHJldHVybiAiMCI7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlcyB0aGUgc3RyaW5nIHRvIHN0b3JlIGluIHRoZSBzcmMgYXR0cmlidXRlIG9mIHRoZSBpbWcgZWxlbWVudC4KICAgICAgICAgKgogICAgICAgICAqIGUuZy4gL2NvbmZsdWVuY2UvZG93bmxvYWQvYXR0YWNobWVudHMvODg0NzM4L2hlZGdlaG9nLmpwZwogICAgICAgICAqLwogICAgICAgIGdldFNyYyA9IGZ1bmN0aW9uIChpbWdQcm9wcykgewogICAgICAgICAgICB2YXIgZGVzdGluYXRpb24gPSBpbWdQcm9wcy5kZXN0aW5hdGlvbjsKICAgICAgICAgICAgaWYgKHRpbnltY2UuY29uZmx1ZW5jZS5JbWFnZVV0aWxzLmlzUmVtb3RlSW1nKGRlc3RpbmF0aW9uKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGRlc3RpbmF0aW9uOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbG9jYXRpb24gPSBpbWdQcm9wcy50aHVtYm5haWwgPyAndGh1bWJuYWlscycgOiAnYXR0YWNobWVudHMnOwogICAgICAgICAgICByZXR1cm4gQUpTLnBhcmFtcy5jb250ZXh0UGF0aCArICcvZG93bmxvYWQvJyArIGxvY2F0aW9uICsgJy8nICsKICAgICAgICAgICAgICAgICAgaW1nUHJvcHMucGFnZUlkICsgJy8nICsgaW1nUHJvcHMuaW1hZ2VGaWxlTmFtZTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRoZSB3aWtpIG1hcmt1cCBzdHJpbmcgdGhhdCB0aGVzZSBwcm9wZXJ0aWVzIGRlZmluZS4KICAgICAgICAgKgogICAgICAgICAqIGUuZy4gc3BhY2VLZXk6cGFnZVRpdGxlXmltYWdlLmdpZnx0aHVtYm5haWwsYWxpZ249cmlnaHQsYm9yZGVyCiAgICAgICAgICovCiAgICAgICAgZ2V0TWFya3VwID0gZnVuY3Rpb24gKGltZ1Byb3BzKSB7CgogICAgICAgICAgICB2YXIgaW1hZ2V0ZXh0ID0gaW1nUHJvcHMuZGVzdGluYXRpb24gfHwgaW1nUHJvcHMuaW1hZ2VGaWxlTmFtZSwKICAgICAgICAgICAgICAgIHByb3BzID0gW107CgogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBpbWFnZXRleHRLZXlzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBrZXkgPSBpbWFnZXRleHRLZXlzW2ldLCB2YWwgPSBpbWdQcm9wc1trZXldOwogICAgICAgICAgICAgICAgaWYgKCF2YWwpIGNvbnRpbnVlOwoKICAgICAgICAgICAgICAgIHZhciBwcm9wID0ga2V5OwogICAgICAgICAgICAgICAgaWYgKHZhbCAhPT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgIC8vIG5vdCBhIGJvb2xlYW4gcHJvcGVydHkgbGlrZSAidGh1bWJuYWlsIiAtIGFkZCB0aGUgdmFsdWUKICAgICAgICAgICAgICAgICAgICBwcm9wICs9ICI9IiArIHZhbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHByb3BzLnB1c2gocHJvcCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHByb3BzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgaW1hZ2V0ZXh0ICs9ICJ8IiArIHByb3BzLmpvaW4oIiwiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gaW1hZ2V0ZXh0OwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEZvciB3aWR0aCBhbmQgaGVpZ2h0IGF0dHJpYnV0ZXMsIGRvbid0IHVzZSAkZWwuYXR0cigid2lkdGgiKSBvciBlbC5nZXRBdHRyaWJ1dGUoIndpZHRoIikgYWxvbmUgYXMgaXQKICAgICAgICAgKiByZXR1cm5zIHRoZSBjYWxjdWxhdGVkIHZhbHVlIGV2ZW4gaWYgdGhlIGF0dHJpYnV0ZSBpc24ndCBwcmVzZW50LgogICAgICAgICAqCiAgICAgICAgICogU2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI0lELTg2MjUyOTI3MyBmb3IgbW9yZSBkZXRhaWwuCiAgICAgICAgICovCiAgICAgICAgZ2V0U3BlY2lmaWVkQXR0cmlidXRlVmFsdWUgPSBmdW5jdGlvbiAoZWwsIG5hbWUpIHsKICAgICAgICAgICAgdmFyIGF0dHIgPSBlbC5nZXRBdHRyaWJ1dGVOb2RlKG5hbWUpOwogICAgICAgICAgICByZXR1cm4gYXR0ciAmJiBhdHRyLnNwZWNpZmllZCAmJiBhdHRyLm5vZGVWYWx1ZTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWZmIHRoaXMgaXMgYSBDb25mbHVlbmNlIGltYWdlIHRhZyB3aXRoIGEgd2lraS1tYXJrdXAgImltYWdldGV4dCIgYXR0cmlidXRlLgogICAgICAgICAqLwogICAgICAgIGlzT3VySW1hZ2UgPSBmdW5jdGlvbihpbWdFbCkgewogICAgICAgICAgICByZXR1cm4gaW1nRWwgJiYgaW1nRWwudGFnTmFtZSAmJiAoaW1nRWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09ICJpbWciKSAmJiBpbWdFbC5nZXRBdHRyaWJ1dGUoImltYWdldGV4dCIpOwogICAgICAgIH0sCgogICAgICAgIG5ld0ltYWdlQ291bnRlciA9IDA7CgogICAgLyoqCiAgICAgKiBJbWFnZVByb3BlcnRpZXMgY2xhc3MgcmVwcmVzZW50cyBhbGwgb2YgdGhlIGF0dHJpYnV0ZXMgb2YgYW4gaW1hZ2UgaW4gdGhlCiAgICAgKiBSVEU6CiAgICAgKiAgICAgIGltYWdlRmlsZU5hbWUKICAgICAqICAgICAgYWxpZ24KICAgICAqICAgICAgdGh1bWJuYWlsCiAgICAgKiAgICAgIGJvcmRlcgogICAgICogICAgICB3aWR0aAogICAgICogICAgICBoZWlnaHQKICAgICAqICAgICAgdXJsIChvcHRpb25hbCkgdGhlIGZ1bGwgdXJsIG9mIHRoZSBpbWFnZSBmb3IgYW4gZXh0ZXJuYWwgaW1hZ2UKICAgICAqICAgICAgcGFnZUlkIChvcHRpb25hbCBpZiB1cmwgZXhpc3RzKSB0aGUgaWQgb2YgdGhlIHBhZ2Ugb3duaW5nIHRoZSBpbWFnZSBhdHRhY2htZW50CiAgICAgKiAgICAgIGRlc3RpbmF0aW9uIChvcHRpb25hbCkgdGhlIGZ1bGwgIndpa2kiIHBhdGggdG8gdGhlIGltYWdlLCBlZyAiVFNUOkZvb15iYXIuanBnIgogICAgICoKICAgICAqICBJdCBjYW4gcmV0dXJuIGNhbGN1bGF0ZWQgdmFsdWVzLCBzdWNoIGFzOgogICAgICogICAgICBzcmMKICAgICAqICAgICAgaW1hZ2V0ZXh0CiAgICAgKi8KICAgIHRpbnltY2UuY29uZmx1ZW5jZS5JbWFnZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAocHJvcHMpIHsKICAgICAgICBpZiAoaXNPdXJJbWFnZShwcm9wcykpIHsKICAgICAgICAgICAgLy8gcHJvcHMgaXMgYW4gaW1nIGVsZW1lbnQKICAgICAgICAgICAgdmFyICRlbCA9ICQocHJvcHMpLAogICAgICAgICAgICAgICAgZWwgPSAkZWxbMF0sCiAgICAgICAgICAgICAgICBtYXJrdXAgPSAkZWwuYXR0cigiaW1hZ2V0ZXh0Iik7CgogICAgICAgICAgICBwcm9wcyA9IGNyZWF0ZUZyb21NYXJrdXAobWFya3VwKTsKICAgICAgICAgICAgcHJvcHMud2lkdGggPSBnZXRTcGVjaWZpZWRBdHRyaWJ1dGVWYWx1ZShlbCwgIndpZHRoIikgfHwgcHJvcHMud2lkdGg7CiAgICAgICAgICAgIHByb3BzLmhlaWdodCA9IGdldFNwZWNpZmllZEF0dHJpYnV0ZVZhbHVlKGVsLCAiaGVpZ2h0IikgfHwgcHJvcHMuaGVpZ2h0OwoKICAgICAgICAgICAgaWYgKCF0aW55bWNlLmNvbmZsdWVuY2UuSW1hZ2VVdGlscy5pc1JlbW90ZUltZyhwcm9wcy5kZXN0aW5hdGlvbikpCiAgICAgICAgICAgICAgICBwcm9wcy5wYWdlSWQgPSBnZXRQYWdlSWRGcm9tSW1hZ2VFbGVtZW50KCRlbCk7CgogICAgICAgICAgICByZXR1cm4gJC5leHRlbmQoe30sIHByb3BzKTsKCiAgICAgICAgfSBlbHNlIGlmIChwcm9wcy5kZXN0aW5hdGlvbikgewogICAgICAgICAgICAvLyBwcm9wcyBpcyBhIG1hcCBvZiBJbWFnZVByb3BlcnRpZXMgdmFsdWVzCiAgICAgICAgICAgIHByb3BzLmltYWdlRmlsZU5hbWUgPSBwcm9wcy5pbWFnZUZpbGVOYW1lIHx8IGdldEltYWdlRmlsZU5hbWVGcm9tRGVzdGluYXRpb24ocHJvcHMuZGVzdGluYXRpb24pOwogICAgICAgICAgICBwcm9wcy5hbGlnbiA9IHByb3BzLmFsaWduIHx8ICIiOwoKICAgICAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LCBwcm9wcyk7CiAgICAgICAgfQogICAgICAgIC8vIG5vdCBhbiBpbWFnZSBlbGVtZW50IGFuZCBub3QgYSB2YWxpZCBwcm9wZXJ0aWVzIG9iamVjdCAtIHJldHVybiBub3RoaW5nCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9OwoKICAgIHRpbnltY2UuY29uZmx1ZW5jZS5JbWFnZVV0aWxzID0gewoKICAgICAgICAvKioKICAgICAgICAgKiBMb2FkcyB0aGUgaW1hZ2UgcHJvcGVydGllcyBpbnRvIHRoZSBwYXNzZWQgaW1nIGVsZW1lbnQuCiAgICAgICAgICogQHBhcmFtIGltZyBhbiBIdG1sSW1hZ2VFbGVtZW50IG9yIGEgalF1ZXJ5IHdyYXBwaW5nIG9uZS4KICAgICAgICAgKiBAcGFyYW0gaW1nUHJvcHMgdGhlIGltYWdlIHByb3BlcnRpZXMgdG8gdXBkYXRlIHRoZSBlbGVtZW50IHdpdGguCiAgICAgICAgICovCiAgICAgICAgdXBkYXRlSW1hZ2VFbGVtZW50OiBmdW5jdGlvbiAoaW1nLCBpbWdQcm9wcykgewoKICAgICAgICAgICAgdmFyICRpbWcgPSAkKGltZyk7CgogICAgICAgICAgICBpbWdQcm9wcy5pbWFnZXRleHQgPSBnZXRNYXJrdXAoaW1nUHJvcHMpOwogICAgICAgICAgICBpbWdQcm9wcy5zcmMgPSBnZXRTcmMoaW1nUHJvcHMpOwoKICAgICAgICAgICAgLy8gUmVuZGVyZXIgJiBUaW55TUNFIGJvdGggYWRkIHN0eWxlIHRhZ3MgdG8gc2hvdyBib3JkZXJzIC0gdGhlc2UgYm90aCBuZWVkIHVwZGF0aW5nLCBpZiBwcmVzZW50LCBvciB0aGV5J2xsCiAgICAgICAgICAgIC8vIG92ZXJyaWRlIGFueSBib3JkZXIgYXR0cmlidXRlIHNldC4KICAgICAgICAgICAgdmFyIG5ld0JvcmRlclN0eWxlID0gIjFweCBzb2xpZCAiICsgKGltZ1Byb3BzLmJvcmRlciA/ICJibGFjayIgOiAidHJhbnNwYXJlbnQiKTsKICAgICAgICAgICAgJGltZy5jc3MoImJvcmRlciIsIG5ld0JvcmRlclN0eWxlKTsKICAgICAgICAgICAgJGltZy5hdHRyKCJtY2Vfc3R5bGUiLCAkaW1nLmF0dHIoInN0eWxlIikpOwoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gaW1hZ2VFbGVtZW50QXR0cmlidXRlS2V5cy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7CiAgICAgICAgICAgICAgICB2YXIga2V5ID0gaW1hZ2VFbGVtZW50QXR0cmlidXRlS2V5c1tpXSwgdmFsID0gaW1nUHJvcHNba2V5XTsKICAgICAgICAgICAgICAgIGlmICh2YWwgIT09IGZhbHNlICYmIHZhbCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgJGltZy5hdHRyKGtleSwgdmFsKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGltZy5yZW1vdmVBdHRyKGtleSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgaW1hZ2UgZWxlbWVudCdzIHBhcmVudCdzIGFsaWdubWVudCBpZiBuZWNlc3NhcnkuCiAgICAgICAgICAgIHZhciBwYXJlbnQgPSBpbWcucGFyZW50Tm9kZTsKICAgICAgICAgICAgdmFyIGlzQ2VudHJlZCA9IHBhcmVudCAmJiAocGFyZW50LnRhZ05hbWUgJiYgcGFyZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PSAiZGl2IikgJiYgcGFyZW50LmdldEF0dHJpYnV0ZSgiYWxpZ24iKSA9PSAiY2VudGVyIjsKICAgICAgICAgICAgdmFyIHNob3VsZEJlQ2VudHJlZCA9IChpbWdQcm9wcy5hbGlnbiA9PSAiY2VudGVyIik7CgogICAgICAgICAgICBpZiAoIWlzQ2VudHJlZCAmJiBzaG91bGRCZUNlbnRyZWQpIHsKICAgICAgICAgICAgICAgIC8vIElmIHRoZSBpbWFnZSBpcyBub3QgY2VudGVyZWQgYWxyZWFkeS4uLgogICAgICAgICAgICAgICAgLy8gU2V0IHRoZSBhbGlnbm1lbnQgaW4gdGhlIHBhcmVudCBub2RlCiAgICAgICAgICAgICAgICBwYXJlbnQuc2V0QXR0cmlidXRlKCJhbGlnbiIsICJjZW50ZXIiKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChpc0NlbnRyZWQgJiYgIXNob3VsZEJlQ2VudHJlZCkgewogICAgICAgICAgICAgICAgLy8gSWYgdGhlIGltYWdlIGlzIGN1cnJlbnRseSBjZW50ZXJlZCwgYnV0IHNob3VsZCBub3QgYmUuLi4KICAgICAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgYWxpZ24gYXR0cmlidXRlCiAgICAgICAgICAgICAgICBwYXJlbnQucmVtb3ZlQXR0cmlidXRlKCJhbGlnbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgIAogICAgICAgIC8qKgogICAgICAgICAqIEluc2VydHMgYSBuZXcgSU1HIGVsZW1lbnQgYXQgdGhlIGN1cnJlbnQgc2VsZWN0aW9uIGluIHRoZSBSVEUuCiAgICAgICAgICogQHJldHVybiBhIHJlZmVyZW5jZSB0byB0aGUgaW5zZXJ0ZWQgSU1HIGVsZW1lbnQuCiAgICAgICAgICovCiAgICAgICAgaW5zZXJ0SW1hZ2VFbGVtZW50IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgLy8gUmVnYXJkbGVzcyBvZiBob3cgdGhlIGltYWdlIGlzIGJlaW5nIGFsaWduZWQsIHdyYXAgaXQgaW4gYSBkaXYsIHNvIHRoZSBpbWFnZSBoYXMgYSBwYXJlbnQgbm9kZQogICAgICAgICAgICB2YXIgZWQgPSB0aW55TUNFLmFjdGl2ZUVkaXRvciwKICAgICAgICAgICAgICAgIGRvYyA9IGVkLmdldERvYygpLAogICAgICAgICAgICAgICAgZGl2ID0gZWQuZG9tLmNyZWF0ZSgiRElWIiksCiAgICAgICAgICAgICAgICBvSW1nID0gZWQuZG9tLmNyZWF0ZSgiSU1HIiksCiAgICAgICAgICAgICAgICB0aGlzSW1hZ2VJZCA9ICJuZXctcnRlLWltYWdlLSIgKyBuZXdJbWFnZUNvdW50ZXIrKzsKCiAgICAgICAgICAgIG9JbWcuc2V0QXR0cmlidXRlKCJpZCIsIHRoaXNJbWFnZUlkKTsgIC8vIGZvciByZXRyaWV2aW5nIElNRyBlbGVtZW50IGFmdGVyIERPTSBpbnNlcnRpb24gdmlhIG5vZGUgb3IgSFRNTCBwYXN0ZQogICAgICAgICAgICBkaXYuYXBwZW5kQ2hpbGQob0ltZyk7CgogICAgICAgICAgICBBSlMuRWRpdG9yLkFkYXB0ZXIuc2V0Tm9kZUF0Q3Vyc29yKGRpdik7CgogICAgICAgICAgICB2YXIgZm91bmRFbCA9ICQoIiMiICsgdGhpc0ltYWdlSWQsIGRvYyk7CiAgICAgICAgICAgIGZvdW5kRWwuYXR0cigiaWQiLCAiIik7IC8vIFRPRE8gLSBkZWxldGUgc29tZSBuaWNlIHdheQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIGZvdW5kRWxbMF07CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogR2l2ZW4gYSBtYXAgb2YgSW1hZ2VQcm9wZXJ0aWVzIHByb3BlcnRpZXMsIGluc2VydCBhIG5ldyBJbWFnZSBlbGVtZW50CiAgICAgICAgICogYXQgdGhlIGN1cnJlbnQgc2VsZWN0aW9uIGluIHRoZSBSVEUgYW5kIHBvcHVsYXRlIGl0LgogICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eU1hcAogICAgICAgICAqLwogICAgICAgIGluc2VydEZyb21Qcm9wZXJ0aWVzOiBmdW5jdGlvbiAocHJvcGVydHlNYXApIHsKICAgICAgICAgICAgdmFyIGltYWdlUHJvcGVydGllcyA9IHRpbnltY2UuY29uZmx1ZW5jZS5JbWFnZVByb3BlcnRpZXMocHJvcGVydHlNYXApLAogICAgICAgICAgICAgICAgaW1nRWwgPSB0aGlzLmluc2VydEltYWdlRWxlbWVudCgpOwogICAgICAgICAgICB0aGlzLnVwZGF0ZUltYWdlRWxlbWVudChpbWdFbCwgaW1hZ2VQcm9wZXJ0aWVzKTsKICAgICAgICAgICAgcmV0dXJuIGltZ0VsOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZXMgSW1hZ2VQcm9wZXJ0aWVzIGZyb20gdGhlIHBhc3NlZCBtYXAgYW5kIGVpdGhlciB1cGRhdGVzIHRoZQogICAgICAgICAqIHBhc3NlZCBpbWcgZWxlbWVudCBpZiBwYXNzZWQsIG9yIGluc2VydHMgYSBuZXcgaW1nIGVsZW1lbnQuCiAgICAgICAgICogQHBhcmFtIHByb3BlcnR5TWFwCiAgICAgICAgICogQHBhcmFtIGltZ0VsCiAgICAgICAgICovCiAgICAgICAgdXBkYXRlT3JJbnNlcnRJbWFnZUVsZW1lbnQ6IGZ1bmN0aW9uIChwcm9wZXJ0eU1hcCwgaW1nRWwpIHsKCiAgICAgICAgICAgIHZhciBpbWFnZVByb3BlcnRpZXMgPSB0aW55bWNlLmNvbmZsdWVuY2UuSW1hZ2VQcm9wZXJ0aWVzKHByb3BlcnR5TWFwKTsKCiAgICAgICAgICAgIGlmICghaXNPdXJJbWFnZShpbWdFbCkpIHsKICAgICAgICAgICAgICAgIGltZ0VsID0gdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnVwZGF0ZUltYWdlRWxlbWVudChpbWdFbCwgaW1hZ2VQcm9wZXJ0aWVzKTsKICAgICAgICAgICAgcmV0dXJuIGltZ0VsOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrcyBpZiBhbiBpbWFnZSBoYXMgYSB1cmwgYXMgaXRzIGRlc3RpbmF0aW9uIGluc3RlYWQgb2YgYSB3aWtpIGxpbmsuCiAgICAgICAgICogQHJldHVybiB0cnVlIGlmIGltYWdlIHRleHQgc3RhcnRzIHdpdGggaHR0cCBvciBodHRwcyBwcm90b2NvbAogICAgICAgICAqLwogICAgICAgIGlzUmVtb3RlSW1nOiBmdW5jdGlvbiAoZGVzdGluYXRpb24pIHsKICAgICAgICAgICAgcmV0dXJuIGRlc3RpbmF0aW9uLmluZGV4T2YoImh0dHA6Ly8iKSA9PSAwIHx8IGRlc3RpbmF0aW9uLmluZGV4T2YoImh0dHBzOi8vIikgPT0gMDsKICAgICAgICB9CiAgICB9Owp9KShBSlMuJCk7CgpmdW5jdGlvbiBQYWdlSXRlbSgpIHt9CgovLyB0aGlzIG1ldGhvZCBpcyBwYXNzZWQgdGhlIGV2ZW50ClBhZ2VJdGVtLnByb3RvdHlwZS5PbkNsaWNrID0gZnVuY3Rpb24gKGUpIHsKICAgIHZhciB0YXJnZXQ7CgogICAgLy9hbGVydChEV1JVdGlsLnRvRGVzY3JpcHRpdmVTdHJpbmcoZSwyLDEpKTsKICAgIGlmICghZS50YXJnZXQpIHsKICAgICAgICAvLyBJRSBldmVudCBtb2RlbAogICAgICAgIHRhcmdldCA9IGUuc3JjRWxlbWVudDsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHRhcmdldCA9IGUudGFyZ2V0OwogICAgfQogICAgdGhpcy5zZWxlY3ROb2RlKHRhcmdldCk7Cn07CgoKLy8gdGhpcyBtZXRob2QgaXMgcGFzc2VkIHRoZSB0YWcgd2hpY2ggaGFzIGJlZW4gY2xpY2tlZCBvbgpQYWdlSXRlbS5wcm90b3R5cGUuT25Eb3VibGVDbGljayA9IGZ1bmN0aW9uIChlKSB7CiAgICB0aGlzLnNlbGVjdE5vZGUoZSk7Cn07CgpQYWdlSXRlbS5wcm90b3R5cGUuZmluZFRhcmdldCA9IGZ1bmN0aW9uICh0KSB7CiAgICBpZiAodCA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICBpZiAodGhpcy5pc091ck5vZGUodCkpIHsKICAgICAgICByZXR1cm4gdDsKICAgIH0KICAgIHJldHVybiB0aGlzLmZpbmRUYXJnZXQodC5wYXJlbnROb2RlKTsKfTsKClBhZ2VJdGVtLnByb3RvdHlwZS5zZWxlY3ROb2RlID0gZnVuY3Rpb24gKHRhcmdldCkgewogICAgdmFyIGEgPSB0aGlzLmZpbmRUYXJnZXQodGFyZ2V0KTsKICAgIGlmIChhKSB7CiAgICAgICAgdGhpcy5TZWxlY3RlZE5vZGUgPSBhOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgdGhpcy5TZWxlY3RlZE5vZGUgPSB1bmRlZmluZWQ7CiAgICB9CiAgICByZXR1cm4gdGhpcy5TZWxlY3RlZE5vZGU7Cn07CgpDb25mTGluay5wcm90b3R5cGUgPSBuZXcgUGFnZUl0ZW0oKTsKCmZ1bmN0aW9uIENvbmZMaW5rKCkgeyB9CgovLyBBZGQgYSBuZXcgZWxlbWVudCBhdCB0aGUgYWN0dWFsIHNlbGVjdGlvbi4KQ29uZkxpbmsucHJvdG90eXBlLkFkZCA9IGZ1bmN0aW9uIChsaW5rLCBzaG93LCBkZXN0aW5hdGlvbiwgYWxpYXMsIHRvb2x0aXAsIHBhZ2VJZCwgc3BhY2VLZXkgKSB7CgogICAgdmFyIG9TcGFuID0gdGlueU1DRS5hY3RpdmVFZGl0b3IuZG9tLmNyZWF0ZSgnQScpOwogICAgQ29uZkxpbmsucmFuZ2UgPSB0aW55TUNFLmFjdGl2ZUVkaXRvci5zZWxlY3Rpb24uZ2V0Um5nKCk7CiAgICB0aGlzLlNldHVwU3BhbihvU3BhbiwgbGluaywgc2hvdywgZGVzdGluYXRpb24sIGFsaWFzLCB0b29sdGlwLCBwYWdlSWQsIHNwYWNlS2V5KTsKCiAgICAvLyBTaW5jZSB3ZSBjYW4ndCBpbnNlcnQgYSBub2RlIGludG8gdGhlIERPTSwKICAgIC8vIGluc2VydCB0aGUgaHRtbCBzeW5jaHJvbm91c2x5IGZvciBJRS4KICAgIC8vIFNlZSAnQ29uZkxpbmsucHJvdG90eXBlLnJlcGx5X3NldHVwc3BhbicKICAgIGlmICghdGlueW1jZS5pc0lFKSB7CiAgICAgICAgQ29uZkxpbmsucmFuZ2UuaW5zZXJ0Tm9kZShyZXBseVNwYW4pOwogICAgfQp9OwoKdmFyIHJlcGx5U3BhbjsKCkNvbmZMaW5rLnByb3RvdHlwZS5yZXBseV9zZXR1cHNwYW4gPSBmdW5jdGlvbiAoaHRtbCkgewogICAgaWYgKGh0bWwuaW5kZXhPZignPHA+JykgPT0gMCkgewogICAgICAgIGh0bWwgPSBodG1sLnN1YnN0cmluZygzKTsKICAgIH0KICAgIGlmIChodG1sLmxhc3RJbmRleE9mKCc8L3A+JykgPT0gaHRtbC5sZW5ndGggLSA0KSB7CiAgICAgICAgaHRtbCA9IGh0bWwuc3Vic3RyaW5nKDAsaHRtbC5sZW5ndGggLSA0KTsKICAgIH0KICAgIC8vIFNvIHRoYXQgd2UgZG8gbm90IG5lZWQgdG8gYWx3YXlzIHBhZCBsaW5rcyB3aXRoIGEgdGhpbnNwIG9yIHNvbWV0aGluZywKICAgIC8vIHBhZCBpdCBoZXJlIHdpdGggYSByZWd1bGFyIHNwYWNlLiAgTm90IGlkZWFsIGF0IGFsbC4KICAgIGh0bWwgKz0gJyAnOwoKICAgIC8vIHNldE91dGVySFRNTAogICAgaWYgKHRpbnltY2UuaXNJRSkgeyAgICAgICAgCiAgICAgICAgQ29uZkxpbmsucmFuZ2UucGFzdGVIVE1MKGh0bWwpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgdGlueU1DRS5hY3RpdmVFZGl0b3IuZm9jdXMoKTsKCiAgICAgICAgLy9hbGVydChEV1JVdGlsLnRvRGVzY3JpcHRpdmVTdHJpbmcocmVwbHlTcGFuKSk7CiAgICAgICAgdmFyIHIgPSByZXBseVNwYW4ub3duZXJEb2N1bWVudC5jcmVhdGVSYW5nZSgpOwogICAgICAgIHIuc2V0U3RhcnRCZWZvcmUocmVwbHlTcGFuKTsKICAgICAgICB2YXIgZGYgPSByLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChodG1sKTsKICAgICAgICB2YXIgcGFyZW50Tm9kZSA9IHJlcGx5U3Bhbi5wYXJlbnROb2RlOwogICAgICAgIHZhciBjdXJzb3JJbmRleCA9IEFKUy5FZGl0b3IuQWRhcHRlci5nZXRDaGlsZEluZGV4KHBhcmVudE5vZGUsIHJlcGx5U3BhbikgKyAyOyAgLy8gKzEgZm9yIGVuZCBvZiA8YT4sICsxIGZvciBhZnRlciB0cmFpbGluZyBzcGFjZQogICAgICAgIHBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGRmLCByZXBseVNwYW4pOwoKICAgICAgICAvLyBQdXQgY3Vyc29yIGF0IGVuZCBvZiBsaW5rCiAgICAgICAgdmFyIHJhbmdlID0gQUpTLkVkaXRvci5BZGFwdGVyLmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgcmFuZ2Uuc2V0U3RhcnQocGFyZW50Tm9kZSwgY3Vyc29ySW5kZXgpOwogICAgICAgIHJhbmdlLnNldEVuZChwYXJlbnROb2RlLCBjdXJzb3JJbmRleCk7CiAgICAgICAgdGlueU1DRS5hY3RpdmVFZGl0b3Iuc2VsZWN0aW9uLnNldFJuZyhyYW5nZSk7CiAgICB9Cn07CgovLyBkZWNvZGUgSFRNTCBlbmNvZGVkIHRleHQKQ29uZkxpbmsucHJvdG90eXBlLkRlY29kZVVSSSA9IGZ1bmN0aW9uIChlbmNvZGVkKSB7CiAgICByZXR1cm4gZW5jb2RlZDsKfTsKCi8vIGRlY29kZSBIVE1MIGVuY29kZWQgdGV4dApDb25mTGluay5wcm90b3R5cGUuRW5jb2RlVVJJID0gZnVuY3Rpb24gKHVuZW5jb2RlZCkgewogICAgcmV0dXJuIHVuZW5jb2RlZDsKfTsKCkNvbmZMaW5rLnByb3RvdHlwZS5TZXR1cFNwYW4gPSBmdW5jdGlvbiAoc3BhbiwgbGluaywgc2hvdywgZGVzdGluYXRpb24sIGFsaWFzLCB0b29sdGlwLCBwYWdlSWQsIHNwYWNlS2V5KSB7CiAgICByZXBseVNwYW4gPSBzcGFuOwogICAgcmVwbHlTcGFuLmlubmVySFRNTCA9IHNob3c7CiAgICBzcGFuLnNldEF0dHJpYnV0ZSgnaHJlZicsJyMnKTsKICAgIHNwYW4uc2V0QXR0cmlidXRlKCdsaW5rdHlwZScsJ3JhdycpOwogICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ3dpa2lkZXN0aW5hdGlvbicsIGRlc3RpbmF0aW9uKTsKICAgIGlmIChhbGlhcy5sZW5ndGggPiAwKSB7CiAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2FsaWFzc3BlY2lmaWVkJywgJ3RydWUnKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHNwYW4uc2V0QXR0cmlidXRlKCdvcmlnaW5hbGFsaWFzJywgZGVzdGluYXRpb24pOwogICAgfQogICAgaWYgKHRvb2x0aXAubGVuZ3RoID4gMCkgewogICAgICAgIHNwYW4uc2V0QXR0cmlidXRlKCd0aXRsZScsIHRvb2x0aXApOwogICAgICAgIHNwYW4uc2V0QXR0cmlidXRlKCd3aWtpdGl0bGUnLCB0b29sdGlwKTsKICAgIH0KICAgIGlmIChwYWdlSWQpIHsKICAgICAgICBkd3JJblByb2dyZXNzID0gdHJ1ZTsKICAgICAgICBBSlMuc2FmZS5wb3N0KEFKUy5wYXJhbXMuY29udGV4dFBhdGggKyAiL2pzb24vY29udmVydHdpa2ltYXJrdXB0b3hodG1sd2l0aG91dHBhZ2V3aXRoc3BhY2VrZXkuYWN0aW9uIiwgCiAgICAgICAgICAgIHtwYWdlSWQ6IHBhZ2VJZCwgc3BhY2VLZXk6IHNwYWNlS2V5LCB3aWtpTWFya3VwOiAnWycgKyBsaW5rICsgJ10nfSwgCiAgICAgICAgICAgIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAJdGhpcy5yZXBseV9zZXR1cHNwYW4oKTsKICAgICAgICAgICAgICAgIGR3ckluUHJvZ3Jlc3MgPSBmYWxzZTsKICAgICAgICAgICAgfSwgImpzb24iKTsKICAgIH0KfTsKCkNvbmZMaW5rLnByb3RvdHlwZS5EV1JDb21wbGV0ZSA9IGZ1bmN0aW9uKCkgewogICAgZHdySW5Qcm9ncmVzcyA9IGZhbHNlOwp9OwoKQ29uZkxpbmsucHJvdG90eXBlLmlzT3VyTm9kZSA9IGZ1bmN0aW9uKHQpIHsKICAgIHJldHVybiB0LnRhZ05hbWUgPT0gJ0EnICYmIHQuZ2V0QXR0cmlidXRlKCdsaW5rdHlwZScpID09ICJyYXciOwp9OwoKdmFyIHRleHRGaWVsZDsKCmZ1bmN0aW9uIHJlcGx5X2xvYWRzZWxlY3RlZChtYXJrdXApIHsKICAgIHRleHRGaWVsZC52YWx1ZSA9IG1hcmt1cDsKfQoKQ29uZkxpbmsucHJvdG90eXBlLkxvYWRNYXJrdXAgPSBmdW5jdGlvbih4aHRtbCwgZmllbGQsIHBhZ2VJZCkgewogICAgdGV4dEZpZWxkID0gZmllbGQ7CiAgICBpZiAocGFnZUlkKSB7CiAgICAJQUpTLnNhZmUucG9zdChBSlMucGFyYW1zLmNvbnRleHRQYXRoICsgIi9qc29uL2NvbnZlcnR4aHRtbHRvd2lraW1hcmt1cHdpdGhvdXRwYWdlLmFjdGlvbiIsIHtwYWdlSWQ6IHBhZ2VJZCwgeGh0bWw6IHhodG1sfSwgcmVwbHlfbG9hZHNlbGVjdGVkLCAianNvbiIpOwogICAgfQp9OwoKQ29uZkxpbmsucHJvdG90eXBlLk9rID0gZnVuY3Rpb24oZGVzdGluYXRpb25TdHIsIGFsaWFzU3RyLCB0b29sdGlwU3RyLCBsaW5rVGV4dFdpa2lNYXJrdXAsIHNlbGVjdGlvbiwgcGFnZUlkLCBzcGFjZUtleSkgewogICAgdmFyIGVkID0gdGlueU1DRS5hY3RpdmVFZGl0b3I7CiAgICBpZiAoIGRlc3RpbmF0aW9uU3RyLmxlbmd0aCA9PSAwICkgewogICAgICAgIGFsZXJ0KGVkLmdldExhbmcoImNvbmZsdWVuY2UuY29uZmxpbmtfZXJyb3Jfbm9fbmFtZSIpKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLy8gaHR0cDovL2ppcmEuYXRsYXNzaWFuLmNvbS9icm93c2UvQ09ORi0xMzM0MgogICAgaWYgKHRvb2x0aXBTdHIubGVuZ3RoID4gMCAmJiBhbGlhc1N0ci5sZW5ndGggPT0gMCkgewogICAgICAgIGFsaWFzU3RyID0gZGVzdGluYXRpb25TdHI7CiAgICB9CiAgICB2YXIgc2hvd3RleHQgPSAoYWxpYXNTdHIubGVuZ3RoID4gMCA/IGFsaWFzU3RyIDogZGVzdGluYXRpb25TdHIpOwoKICAgIHZhciBlU2VsZWN0ZWQgPSBzZWxlY3Rpb24uZ2V0Tm9kZSgpOwogICAgaWYgKGVTZWxlY3RlZCAmJiAhdGhpcy5pc091ck5vZGUoZVNlbGVjdGVkKSkgewogICAgICAgIC8vIHdlIGhhZCBhIHNlbGVjdGlvbiwgYnV0IGl0IHdhc24ndCBhbiBleGlzdGluZyBsaW5rCiAgICAgICAgLy8gc28gZGVsZXRlIHRoZSBleGlzdGluZyBjb250ZW50cyB0aGVuIGFkZAogICAgICAgIHZhciBybmcgPSBlZC5zZWxlY3Rpb24uZ2V0Um5nKCk7CiAgICAgICAgaWYgKHJuZy5kZWxldGVDb250ZW50cykgcm5nLmRlbGV0ZUNvbnRlbnRzKCk7CiAgICAgICAgZVNlbGVjdGVkID0gbnVsbDsKICAgIH0KCiAgICBpZiAoZVNlbGVjdGVkKSB7CiAgICAgICAgdGhpcy5TZXR1cFNwYW4oZVNlbGVjdGVkLCB0aGlzLkVuY29kZVVSSShsaW5rVGV4dFdpa2lNYXJrdXApLCBzaG93dGV4dCwgZGVzdGluYXRpb25TdHIsIGFsaWFzU3RyLCB0b29sdGlwU3RyLCBwYWdlSWQsIHNwYWNlS2V5KTsKICAgIH0gZWxzZSB7CiAgICAgICAgdGhpcy5BZGQodGhpcy5FbmNvZGVVUkkobGlua1RleHRXaWtpTWFya3VwKSwgc2hvd3RleHQsIGRlc3RpbmF0aW9uU3RyLCBhbGlhc1N0ciwgdG9vbHRpcFN0ciwgcGFnZUlkLCBzcGFjZUtleSk7CiAgICB9Cn07CgpDb25mSW1hZ2UucHJvdG90eXBlID0gbmV3IFBhZ2VJdGVtKCk7CgpmdW5jdGlvbiBDb25mSW1hZ2UoKSB7CiAgICB3aW5kb3cuQ29uZkltYWdlID0gdGhpczsKfQoKQ29uZkltYWdlLnByb3RvdHlwZS5pc091ck5vZGUgPSBmdW5jdGlvbiAodCkgewogICAgcmV0dXJuIHQudGFnTmFtZSA9PSAiSU1HIiAmJiB0LmdldEF0dHJpYnV0ZSgiaW1hZ2V0ZXh0Iik7Cn07CgovLyBJbnNlcnRzIG9yIHVwZGF0ZXMgYW4gaW1hZ2UgaW4gdGhlIFJURSBhbmQgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgaW5zZXJ0ZWQgY29udGVudC4KLy8gQGRlcHJlY2F0ZWQgVXNlIHRpbnltY2UuY29uZmx1ZW5jZS5JbWFnZVV0aWxzLnVwZGF0ZU9ySW5zZXJ0SW1hZ2VFbGVtZW50CkNvbmZJbWFnZS5wcm90b3R5cGUuT2sgPSBmdW5jdGlvbiAoaW1hZ2VGaWxlTmFtZSwgdGh1bWJuYWlsLCBib3JkZXIsIGFsaWduLCBpbWdFbCwgcGFnZUlkKSB7CgogICAgdmFyIHByb3BlcnR5TWFwID0gewogICAgICAgIGltYWdlRmlsZU5hbWU6IGltYWdlRmlsZU5hbWUsCiAgICAgICAgdGh1bWJuYWlsOiB0aHVtYm5haWwsCiAgICAgICAgYm9yZGVyOiBib3JkZXIsCiAgICAgICAgYWxpZ246IGFsaWduLAogICAgICAgIHBhZ2VJZDogcGFnZUlkLAogICAgICAgIHdpZHRoOiBpbWdFbCAmJiBpbWdFbC5nZXRBdHRyaWJ1dGUoIndpZHRoIiksCiAgICAgICAgaGVpZ2h0OiBpbWdFbCAmJiBpbWdFbC5nZXRBdHRyaWJ1dGUoImhlaWdodCIpCiAgICB9OwogICAgcmV0dXJuIHRpbnltY2UuY29uZmx1ZW5jZS5JbWFnZVV0aWxzLnVwZGF0ZU9ySW5zZXJ0SW1hZ2VFbGVtZW50KHByb3BlcnR5TWFwLCBpbWdFbCk7Cn07CgpDb25mSW1hZ2UucHJvdG90eXBlLm9wZW5EaWFsb2cgPSBmdW5jdGlvbiAoKSB7CiAgICBBSlMuRWRpdG9yLkFkYXB0ZXIuc3RvcmVDdXJyZW50U2VsZWN0aW9uU3RhdGUoKTsKICAgIHZhciBpbWcgPSB0aW55TUNFLmFjdGl2ZUVkaXRvci5zZWxlY3Rpb24uZ2V0Tm9kZSgpOwogICAgdmFyIGltYWdlUHJvcGVydGllcyA9IHRpbnltY2UuY29uZmx1ZW5jZS5JbWFnZVByb3BlcnRpZXMoaW1nKTsKICAgIEFKUy5FZGl0b3Iub3BlbkltYWdlRGlhbG9nKHsKICAgICAgICBzdWJtaXRDYWxsYmFjazogZnVuY3Rpb24gKGZpbGVOYW1lLCBwYXJhbXMsIGNvbnRlbnRJZCkgewogICAgICAgICAgICBBSlMuRWRpdG9yLkFkYXB0ZXIucmVzdG9yZVNlbGVjdGlvblN0YXRlKCk7CgogICAgICAgICAgICB2YXIgcHJvcGVydHlNYXAgPSBBSlMuJC5leHRlbmQoewogICAgICAgICAgICAgICAgZGVzdGluYXRpb246IGZpbGVOYW1lLAogICAgICAgICAgICAgICAgcGFnZUlkOiBjb250ZW50SWQKICAgICAgICAgICAgfSwgcGFyYW1zKTsKICAgICAgICAgICAgdmFyIGltZ0VsID0gdGlueU1DRS5jb25mSW1hZ2Uuc2VsZWN0Tm9kZSh0aW55TUNFLmFjdGl2ZUVkaXRvci5zZWxlY3Rpb24uZ2V0Tm9kZSgpKTsKCiAgICAgICAgICAgIHRpbnltY2UuY29uZmx1ZW5jZS5JbWFnZVV0aWxzLnVwZGF0ZU9ySW5zZXJ0SW1hZ2VFbGVtZW50KHByb3BlcnR5TWFwLCBpbWdFbCk7CiAgICAgICAgfSwKICAgICAgICBjYW5jZWxDYWxsYmFjazogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBBSlMuRWRpdG9yLkFkYXB0ZXIucmVzdG9yZVNlbGVjdGlvblN0YXRlKCk7CiAgICAgICAgfSwKICAgICAgICBpbWFnZVByb3BlcnRpZXM6IGltYWdlUHJvcGVydGllcwogICAgfSk7Cn07CgpTdHJpbmcucHJvdG90eXBlLnRyaW0gPSBmdW5jdGlvbiAoKSB7CiAgICByZXR1cm4gdGhpcy5yZXBsYWNlKC9eXHMrfFxzKyQvZywgIiIpOwp9OwoKdGlueU1DRS5jb25mTGluayA9IG5ldyBDb25mTGluaygpOwp0aW55TUNFLmNvbmZJbWFnZSA9IG5ldyBDb25mSW1hZ2UoKTsKCihmdW5jdGlvbigkKSB7CgogICAgLy8gUmVnaXN0ZXIgY29tbWFuZHMgYW5kIG9uY2xpY2tzCiAgICB0aW55bWNlLmNyZWF0ZSgndGlueW1jZS5wbHVnaW5zLkNvbmZsdWVuY2VQbHVnaW4nLCB7CiAgICAgICAgaW5pdCA6IGZ1bmN0aW9uKGVkLCB1cmwpIHsKCiAgICAgICAgICAgIGVkLmFkZENvbW1hbmQoIm1jZUNvbmZpbWFnZSIsIHRpbnlNQ0UuY29uZkltYWdlLm9wZW5EaWFsb2cpOwogICAgICAgICAgICBlZC5hZGRDb21tYW5kKCJtY2VDb25mTWFjcm9Ccm93c2VyIiwgdGlueW1jZS5jb25mbHVlbmNlLm1hY3JvYnJvd3Nlci5tYWNyb0Jyb3dzZXJUb29sYmFyQnV0dG9uQ2xpY2tlZCk7CgogICAgICAgICAgICBlZC5hZGRDb21tYW5kKCJtY2VDb25mVW5saW5rIiwgZnVuY3Rpb24gKHVpLCB2YWwpIHsKICAgICAgICAgICAgICAgIHZhciBlZCA9IEFKUy5FZGl0b3IuQWRhcHRlci5nZXRFZGl0b3IoKSwKICAgICAgICAgICAgICAgICAgICBzID0gZWQuc2VsZWN0aW9uLAogICAgICAgICAgICAgICAgICAgIG4gPSB2YWwgfHwgcy5nZXROb2RlKCksCiAgICAgICAgICAgICAgICAgICAgJG4gPSAkKG4pOwoKICAgICAgICAgICAgICAgIGlmIChuLm5vZGVOYW1lICE9ICdBJykgewogICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnQgPSAkbi5jbG9zZXN0KCJhW2hyZWZdIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFwYXJlbnQubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbiA9IHBhcmVudFswXTsKICAgICAgICAgICAgICAgICAgICAkbiA9IHBhcmVudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIHVubGlua2luZyBleHRlcm5hbCBsaW5rcyByZXF1aXJlcyB3cmFwcGluZyBpbiB0aGUgbm9saW5rIG1hY3JvCiAgICAgICAgICAgICAgICB2YXIgaXNFeHRlcm5hbCA9ICRuLmhhc0NsYXNzKCJleHRlcm5hbC1saW5rIikgfHwKICAgICAgICAgICAgICAgICAgICAoISRuLmF0dHIoIndpa2lkZXN0aW5hdGlvbiIpICYmIEFKUy5FZGl0b3IuQWRhcHRlci5pc0V4dGVybmFsTGluaygkbi5hdHRyKCJocmVmIikpKTsgLy9tYW51YWxseSBwYXN0ZWQgbGlua3MKICAgICAgICAgICAgICAgIGlmIChpc0V4dGVybmFsICYmICRuLmF0dHIoImFsaWFzc3BlY2lmaWVkIikgIT0gInRydWUiKSB7CiAgICAgICAgICAgICAgICAgICAgQUpTLnNhZmUucG9zdChBSlMucGFyYW1zLmNvbnRleHRQYXRoICsgIi9qc29uL2NvbnZlcnR3aWtpbWFya3VwdG94aHRtbHdpdGhvdXRwYWdld2l0aHNwYWNla2V5LmFjdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VJZDogQUpTLkVkaXRvci5nZXRDb250ZW50SWQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYWNlS2V5OiBBSlMucGFyYW1zLnNwYWNlS2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lraU1hcmt1cDogIntub2xpbms6IiArICRuLnRleHQoKSArICJ9IgogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAobWFjcm9IdG1sKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGlueW1jZS5pc1dlYktpdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBoYXMgYW4gaW50ZXJlc3RpbmcgcHJvYmxlbSB3aGVyZSBzZWxlY3RpbmcgdGhlIGxpbmsgbm9kZSBvbmx5IHNlbGVjdHMgdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGV4dCAtIHdlIG5lZWQgdG8gcmVwbGFjZSB0aGUgbGluayB3aXRoIGR1bW15IHRleHQgYW5kIHRoZW4gc2V0IHRoZSBuZXcgY29udGVudC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50ID0gbi5wYXJlbnROb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVQb3NpdGlvbiA9IEFKUy5FZGl0b3IuQWRhcHRlci5nZXRDaGlsZEluZGV4KHBhcmVudCwgbiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUZyb21FbmQgPSBwYXJlbnQuY2hpbGROb2Rlcy5sZW5ndGggLSBub2RlUG9zaXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm5nID0gQUpTLkVkaXRvci5BZGFwdGVyLnJlcGxhY2VXaXRoVGV4dEFuZEdldFJhbmdlKCRuLCAiJm5ic3A7Iik7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuc2V0Q29udGVudChtYWNyb0h0bWwpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSB0aGVuIGhhdmUgdG8gcmVzZXQgdGhlIGN1cnNvciBhZnRlciBTYWZhcmkgbG9zZXMgaXQsIGFuZCByZWZvY3VzIGluIHRoZSBFZGl0b3IuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIG5ldyBjb250ZW50IG1pZ2h0IG5vdCBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiBub2RlcyBhcyB0aGUgcmVtb3ZlZCBjb250ZW50LCBzbwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgY3Vyc29yIHBvc2l0aW9uIGZyb20gdGhlICplbmQqIG9mIHRoZSBwYXJlbnQgbm9kZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlUG9zaXRpb24gPSBwYXJlbnQuY2hpbGROb2Rlcy5sZW5ndGggLSBub2RlRnJvbUVuZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBybmcuc2V0U3RhcnQocGFyZW50LCBub2RlUG9zaXRpb24pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJuZy5zZXRFbmQocGFyZW50LCBub2RlUG9zaXRpb24pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuc2V0Um5nKHJuZyk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVkLmZvY3VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuc2VsZWN0KG4pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVkLmRvbS5yZW1vdmUobik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcy5zZXRDb250ZW50KG1hY3JvSHRtbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgImpzb24iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIHMuc2VsZWN0KG4pOwogICAgICAgICAgICAgICAgICAgIGVkLmV4ZWNDb21tYW5kKCJVbkxpbmsiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAvLyBSZWdpc3RlciBidXR0b25zCiAgICAgICAgICAgIGVkLmFkZEJ1dHRvbigiY29uZmltYWdlIiwge3RpdGxlIDogImNvbmZsdWVuY2UuY29uZmltYWdlX2Rlc2MiLCBjbWQgOiAibWNlQ29uZmltYWdlIn0pOwogICAgICAgICAgICBlZC5hZGRCdXR0b24oImNvbmZfbWFjcm9fYnJvd3NlciIsIHt0aXRsZSA6ICJjb25mbHVlbmNlLmNvbmZfbWFjcm9fYnJvd3Nlcl9kZXNjIiwgY21kIDogIm1jZUNvbmZNYWNyb0Jyb3dzZXIifSk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0SW5mbyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgIGxvbmduYW1lIDogIkNvbmZsdWVuY2UgVGlueU1DRSBQbHVnaW4iLAogICAgICAgICAgICAgICAgYXV0aG9yIDogIkF0bGFzc2lhbiIsCiAgICAgICAgICAgICAgICBhdXRob3J1cmwgOiAiaHR0cDovL3d3dy5hdGxhc3NpYW4uY29tLyIsCiAgICAgICAgICAgICAgICB2ZXJzaW9uIDogdGlueW1jZS5tYWpvclZlcnNpb24gKyAiLiIgKyB0aW55bWNlLm1pbm9yVmVyc2lvbgogICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIC8qKiBDcmVhdGUgdGhlIEluc2VydCBNZW51ICovCiAgICAgICAgY3JlYXRlQ29udHJvbDogZnVuY3Rpb24obiwgY20pIHsKCiAgICAgICAgICAgIHN3aXRjaCAobikgewoKICAgICAgICAgICAgICAgIGNhc2UgJ2NvbmZpbnNlcnQnOgogICAgICAgICAgICAgICAgICAgIHZhciBjID0gY20uY3JlYXRlTWVudUJ1dHRvbigncnRlLWluc2VydC1tZW51LWJ1dHRvbicsIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgOiAnY29uZmx1ZW5jZS5jb25mX2luc2VydF9tZW51JywKICAgICAgICAgICAgICAgICAgICAgICAgImNsYXNzIiA6ICdydGUtaW5zZXJ0LW1lbnUnCiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgIGMub25SZW5kZXJNZW51LmFkZChmdW5jdGlvbihjLCBtKSB7CgogICAgICAgICAgICAgICAgICAgICAgICBtLmFkZCh7dGl0bGUgOiAnY29uZmx1ZW5jZS5jb25mX2ltYWdlJywgY21kIDogIm1jZUNvbmZpbWFnZSIsICJjbGFzcyIgOiAibWNlX21lbnVfY29uZmltYWdlIn0pOwogICAgICAgICAgICAgICAgICAgICAgICBtLmFkZCh7dGl0bGUgOiAnY29uZmx1ZW5jZS5jb25mX2xpbmsnLCBjbWQgOiAibWNlQ29uZmxpbmsiLCAiY2xhc3MiIDogIm1jZV9tZW51X2NvbmZsaW5rIn0pOwogICAgICAgICAgICAgICAgICAgICAgICBtLmFkZCh7dGl0bGUgOiAnY29uZmx1ZW5jZS5jb25mX2F0dGFjaG1lbnQnLCBjbWQ6ICJtY2VDb25mQXR0YWNobWVudHMiLCAiY2xhc3MiIDogIm1jZV9tZW51X2NvbmZhdHRhY2htZW50In0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgbS5hZGRTZXBhcmF0b3IoKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIG0uYWRkKHt0aXRsZSA6ICdjb25mbHVlbmNlLmNvbmZfZW1vdGljb24nLCBjbWQgOiAibWNlRW1vdGlvbiIsICJjbGFzcyIgOiAibWNlX21lbnVfY29uZl9lbW90aWNvbiJ9KTsKICAgICAgICAgICAgICAgICAgICAgICAgbS5hZGQoe3RpdGxlIDogJ2NvbmZsdWVuY2UuY29uZl9zeW1ib2wnLCBjbWQgOiAibWNlQ2hhck1hcCIsICJjbGFzcyIgOiAibWNlX21lbnVfY29uZl9zeW1ib2wifSk7CiAgICAgICAgICAgICAgICAgICAgICAgIG0uYWRkKHt0aXRsZSA6ICdjb25mbHVlbmNlLmNvbmZfaHInLCBjbWQgOiAiSW5zZXJ0SG9yaXpvbnRhbFJ1bGUiLCAiY2xhc3MiIDogIm1jZV9tZW51X2NvbmZfaHIifSk7CgogICAgICAgICAgICAgICAgICAgICAgICBtLmFkZFNlcGFyYXRvcigpOwoKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1iQ2xpY2tGbiA9IHRpbnltY2UuY29uZmx1ZW5jZS5tYWNyb2Jyb3dzZXIubWFjcm9Ccm93c2VyVG9vbGJhckJ1dHRvbkNsaWNrZWQ7CgogICAgICAgICAgICAgICAgICAgICAgICAkKCIjcnRlLWZlYXR1cmVkLW1hY3JvcyBkaXYiKS5lYWNoKGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGl0ZW0gPSAkKHRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1hY3JvTmFtZSA9IGl0ZW0udGV4dCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzTmFtZSA9ICJtY2VfbWVudV9jb25mX21hY3JvXyIgKyBtYWNyb05hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtLmFkZCh7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgOiB0aGlzLnRpdGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjbGFzcyIgOiBjbGFzc05hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25jbGljayA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYkNsaWNrRm4oeyBwcmVzZXRNYWNyb05hbWU6IG1hY3JvTmFtZSB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgIG0uYWRkKHt0aXRsZSA6ICdjb25mbHVlbmNlLmNvbmZfb3RoZXJfbWFjcm9zX2Rlc2MnLCBjbWQgOiAibWNlQ29uZk1hY3JvQnJvd3NlciIsICJjbGFzcyIgOiAibWNlX2NvbmZfbWFjcm9fYnJvd3NlciJ9KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAgICAgICAgICAgKiBDbG9zZSB0aGUgbWVudSBvbiBFc2NhcGUga2V5IHdoZW4gZm9jdXMgaXMgaW4gb3Igb3V0IG9mIFJURS4KICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjbG9zZU1lbnVPbkVzYyA9IGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZS5rZXlDb2RlID09IDI3KSAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uY29sbGFwc2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQUpTLnN0b3BFdmVudChlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNsb3NlTWVudU9uRXNjSW5SVEUgPSBmdW5jdGlvbiAoZWQsIGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlTWVudU9uRXNjKGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICBtLm9uU2hvd01lbnUuYWRkKGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJCh0b3AuZG9jdW1lbnQpLmJpbmQoImtleXVwIiwgY2xvc2VNZW51T25Fc2MpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgQUpTLkVkaXRvci5BZGFwdGVyLmdldEVkaXRvcigpLm9uS2V5VXAuYWRkKGNsb3NlTWVudU9uRXNjSW5SVEUpOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgbS5vbkhpZGVNZW51LmFkZChmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFKUy5FZGl0b3IuQWRhcHRlci5nZXRFZGl0b3IoKS5vbktleVVwLnJlbW92ZShjbG9zZU1lbnVPbkVzY0luUlRFKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQodG9wLmRvY3VtZW50KS51bmJpbmQoImtleXVwIiwgY2xvc2VNZW51T25Fc2MpOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgLy8gUmV0dXJuIHRoZSBuZXcgbWVudSBidXR0b24gaW5zdGFuY2UKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfSk7CgogICAgLy8gUmVnaXN0ZXIgcGx1Z2luCiAgICB0aW55bWNlLlBsdWdpbk1hbmFnZXIuYWRkKCJjb25mbHVlbmNlIiwgdGlueW1jZS5wbHVnaW5zLkNvbmZsdWVuY2VQbHVnaW4pOwp9KShBSlMuJCk7CgovKioKICogSW1wbGVtZW50IHRoZSBtZXRob2RzIHJlcXVpcmVkIGJ5IHRoZSBjb20uYXRsYXNzaWFuLmNvbmZsdWVuY2UucGx1Z2luLmVkaXRvci5FZGl0b3IgaW50ZXJmYWNlLCBhZGFwdGluZyB0byBhCiAqIFRpbnlNQ0UgZWRpdG9yIGltcGxlbWVudGF0aW9uLgogKgogKiBOb3RlIHRoYXQgdGlueU1DRSBzaG91bGQgbm90IGJlIHVzZWQgYXMgaXQgZ2V0cyBjb25mdXNlZCB3aXRoIHRoZSB0aW55bWNlIG9iamVjdC4gVXNlIHRpbnltY2UuRWRpdG9yTWFuYWdlciBpZiB0aGF0J3MKICogd2hhdCB5b3UgbmVlZC4KICovCkFKUy5FZGl0b3IuQWRhcHRlciA9IChmdW5jdGlvbigkKSB7IHJldHVybiB7CgogICAgLyoqCiAgICAgKiBQdWJsaWMgaW50ZXJmYWNlIG1ldGhvZHMgb24gRWRpdG9yLmphdmEKICAgICAqLwoKICAgIC8vIGNhbGxlZCBqdXN0IGFmdGVyIHRoZSBESVYgY29udGFpbmluZyB0aGUgZWRpdG9yIGlzIG1hZGUgdmlzaWJsZQogICAgb25TaG93RWRpdG9yIDogZnVuY3Rpb24gKCkge30sCgogICAgLy8gY2FsbGVkIGp1c3QgYmVmb3JlIHRoZSBESVYgY29udGFpbmluZyB0aGUgZWRpdG9yIGlzIGhpZGRlbgogICAgb25IaWRlRWRpdG9yIDogZnVuY3Rpb24gKCkge30sCgogICAgLyoqCiAgICAgKiBTdG9yZXMgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCByYW5nZSBhbmQgc2Nyb2xsIHBvc2l0aW9uIG9mIHRoZSBlZGl0b3Igc28gd2UgY2FuIGdldCBiYWNrIHRvIHRvIGl0IGxhdGVyCiAgICAgKi8KICAgIHN0b3JlQ3VycmVudFNlbGVjdGlvblN0YXRlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIHNlbGVjdGlvbiA9IHRpbnlNQ0UuYWN0aXZlRWRpdG9yLnNlbGVjdGlvbiwKICAgICAgICAgICAgdnAgPSB0aW55TUNFLmFjdGl2ZUVkaXRvci5kb20uZ2V0Vmlld1BvcnQodGlueU1DRS5hY3RpdmVFZGl0b3IuZ2V0V2luKCkpLAogICAgICAgICAgICBybmcgPSBzZWxlY3Rpb24uZ2V0Um5nKCksCiAgICAgICAgICAgIHJuZ0NvcHk7CiAgICAgICAgaWYgKHJuZy5jbG9uZVJhbmdlICYmIHR5cGVvZiBybmcuY2xvbmVSYW5nZSA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICAgIHJuZ0NvcHkgPSBybmcuY2xvbmVSYW5nZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIElmIGFuIElFIFRleHRSYW5nZSBtYWtlIGEgY29weSwgZWxzZSBpdCB3aWxsIGJlIGFuIElFIElIVE1MQ29udHJvbFJhbmdlIHNvIHN0b3JlIGl0IGRpcmVjdGx5IGFzIGl0IGNhbid0CiAgICAgICAgICAgIC8vICBiZSBjb3BpZWQuCiAgICAgICAgICAgIHJuZ0NvcHkgPSBybmcuZHVwbGljYXRlICYmIHJuZy5kdXBsaWNhdGUoKSB8fCBybmc7CiAgICAgICAgfQoKICAgICAgICBBSlMuRWRpdG9yLkFkYXB0ZXIuYm9va21hcmsgPSB7CiAgICAgICAgICAgIHNjcm9sbFggOiB2cC54LAogICAgICAgICAgICBzY3JvbGxZIDogdnAueSwKICAgICAgICAgICAgcmFuZ2UgOiBybmdDb3B5CiAgICAgICAgfTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBNb3ZlcyB0aGUgc2Nyb2xsIHBvc2l0aW9uIGFuZCBzZWxlY3RlZCByYW5nZSBpbiB0aGUgZWRpdG9yIGJhY2sgdG8gd2hlcmUgaXQgdXNlZCB0byBiZS4KICAgICAqLwogICAgcmVzdG9yZVNlbGVjdGlvblN0YXRlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIHNlbGVjdGlvbiA9IHRpbnlNQ0UuYWN0aXZlRWRpdG9yLnNlbGVjdGlvbiwKICAgICAgICAgICAgd2luID0gdGlueU1DRS5hY3RpdmVFZGl0b3IuZ2V0V2luKCksCiAgICAgICAgICAgIGJvb2ttYXJrID0gQUpTLkVkaXRvci5BZGFwdGVyLmJvb2ttYXJrOwoKICAgICAgICB3aW4uc2Nyb2xsVG8oYm9va21hcmsuc2Nyb2xsWCwgYm9va21hcmsuc2Nyb2xsWSk7CiAgICAgICAgd2luLmZvY3VzKCk7CiAgICAgICAgc2VsZWN0aW9uLnNldFJuZyhib29rbWFyay5yYW5nZSk7CiAgICB9LAoKICAgIC8vIHB1dCB0aGUgdGV4dCBpbiBuZXdWYWx1ZSBpbnRvIHRoZSBlZGl0b3IuIFRoaXMgaXMgY2FsbGVkIHdoZW4gdGhlIGVkaXRvciBuZWVkcyBuZXcKICAgIC8vIGNvbnRlbnQgLS0gaXQgaXMgKm5vdCogY2FsbGVkIHRvIHNldCB0aGUgaW5pdGlhbCBjb250ZW50LiBUaGF0IHNob3VsZCBiZSBkb25lIGVpdGhlciBieSBwcm92aWRpbmcgdGhlCiAgICAvLyBlZGl0b3Igd2l0aCB0aGUgY29udGVudCBhcyBwYXJ0IG9mIHRoZSBpbml0aWFsIEhUTUwsIG9yIGJ5IGNhbGxpbmcgamF2YXNjcmlwdCBmcm9tIGVkaXRvck9uTG9hZCgpCiAgICBzZXRFZGl0b3JWYWx1ZSA6IGZ1bmN0aW9uIChuZXdWYWx1ZSkgewogICAgICAgIEFKUy5sb2coIkFKUy5FZGl0b3IuQWRhcHRlci5zZXRFZGl0b3JWYWx1ZSBjYWxsZWQgd2l0aCA6IiArIG5ld1ZhbHVlKTsKICAgICAgICBpZiAobmV3VmFsdWUpIHsKICAgICAgICAgICAgdGhpcy5nZXRFZGl0b3IoKS5zZXRDb250ZW50KG5ld1ZhbHVlKTsKICAgICAgICB9CiAgICB9LAoKICAgIC8qCiAgICAgKiAgSWYgVGlueU1DRSBoYXMgbm90IGZpbmlzaGVkIGxvYWRpbmcgdGhlIHBhZ2UgY29udGVudCwgYW5kIHRoZSB1c2VyIHN3aXRjaGVzIHRhYnMgKGZyb20gcmljaCB0ZXh0IHRvIG1hcmt1cCksCiAgICAgKiAgYmxvY2sgdGhlIHN3aXRjaCwgb3RoZXJ3aXNlIHRoZWlyIGNvbnRlbnQgd2lsbCBiZSBsb3N0LiAoQ09ORi00ODI0KQogICAgICovCiAgICAvLyByZXR1cm4gdHJ1ZSBpZiB0aGUgZWRpdG9yIGlzIGluIGEgc3RhdGUgd2hlcmUgY2hhbmdlcyBmcm9tIHJpY2ggdGV4dCB0byBtYXJrdXAgYW5kIHZpY2UgdmVyc2EgYXJlIGFsbG93ZWQKICAgIGFsbG93TW9kZUNoYW5nZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gdGhpcy5fdGlueU1jZUhhc0luaXQ7CiAgICB9LAogICAgLy8gY2FsbGVkIHdoZW4gZWRpdG9yIG1vZGUgaXMgY2hhbmdlZCBmcm9tIHd5c2l3eWcgdG8gYW5vdGhlciBlLmcuIG1hcmt1cAogICAgb25DaGFuZ2VNb2RlIDogZnVuY3Rpb24oKSB7fSwKCiAgICAvLyByZXR1cm4gdGhlIGN1cnJlbnQgSFRNTCBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBUaGlzICptdXN0KiByZXR1cm4gYSBKYXZhU2NyaXB0IHN0cmluZywKICAgIC8vIG5vdCBhIEphdmFPYmplY3Qgd3JhcHBpbmcgYSBqYXZhLmxhbmcuU3RyaW5nCiAgICBnZXRFZGl0b3JIVE1MIDogZnVuY3Rpb24gKCkgewogICAgICAgIHZhciB0aW55TUNFQ29udGVudCA9ICIiICsgdGhpcy5nZXRFZGl0b3IoKS5nZXRDb250ZW50KCk7CiAgICAgICAgLy8gU29tZSBjbGVhbnVwIGlzIGRvbmUgaGVyZSBiZWNhdXNlIHdlIGhhdmUgdGlueU1DRSdzIGNsZWFudXAgdHVybmVkIG9mZgogICAgICAgIHJldHVybiB0aW55TUNFQ29udGVudC5yZXBsYWNlKCc8YnIgbWNlX2JvZ3VzPSIxIj4nLCAnJyk7CiAgICB9LAoKICAgIC8vIGNhbGxlZCBpbiB0aGUgcGFnZSdzIG9uTG9hZCBoYW5kbGVyLCBwbGFjZSBhbnkgaW5pdGlhbGl6YXRpb24gbmVlZGVkIGF0IHRoaXMgcG9pbnQgaGVyZQogICAgZWRpdG9yT25Mb2FkIDogZnVuY3Rpb24gKCkgewogICAgICAgIHRoaXMuX3BhZ2VFZGl0b3JIYXNJbml0ID0gdHJ1ZTsKICAgIH0sCgogICAgLy8gcmV0dXJuIHRydWUgaWYgdGhlIGNvbnRlbnRzIG9mIHRoZSBlZGl0b3IgaGFzIGJlZW4gbW9kaWZpZWQgYnkgdGhlIHVzZXIgc2luY2UKICAgIC8vIHRoZSBsYXN0IHRpbWUgZWRpdG9yUmVzZXRDb250ZW50Q2hhbmdlZCgpCiAgICBlZGl0b3JIYXNDb250ZW50Q2hhbmdlZCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gdGhpcy5nZXRFZGl0b3IoKS5pc0RpcnR5KCk7CiAgICB9LAoKICAgIC8vIGNhbGxlZCB0byByZXNldCB0aGUgY29udGVudHMgY2hhbmdlIGluZGljYXRvcgogICAgZWRpdG9yUmVzZXRDb250ZW50Q2hhbmdlZCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLmdldEVkaXRvcigpLnNldERpcnR5KGZhbHNlKTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBBZGRzIGEgY2FsbGJhY2sgdGhhdCB3aWxsIGJlIGV4ZWN1dGVkIGFmdGVyIHRoaXMgZWRpdG9yIGluc3RhbmNlIGhhcyBiZWVuIGluaXRpYWxpc2VkLgogICAgICogQHBhcmFtIGNhbGxiYWNrCiAgICAgKi8KICAgIGFkZE9uSW5pdENhbGxiYWNrOiBmdW5jdGlvbihjYWxsYmFjaykgewogICAgICAgIGlmICgkLmlzRnVuY3Rpb24oY2FsbGJhY2spKSB7CiAgICAgICAgICAgIGlmICh0aGlzLl90aW55TWNlSGFzSW5pdCkgewogICAgICAgICAgICAgICAgY2FsbGJhY2soKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIEFKUy5iaW5kKCJ0aW55bWNlLm9uaW5pdCIsIGNhbGxiYWNrKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQXR0ZW1wdCBtYWRlIHRvIHJlZ2lzdGVyIGFuIG9uaW5pdCBjYWxsYmFjayB0aGF0IGlzIG5vdCBhIGZ1bmN0aW9uLiBSZWNlaXZlZDogJyArIGNhbGxiYWNrKTsKICAgICAgICB9CiAgICB9LAoKICAgIC8qKgogICAgICogQmluZHMgYSBuYW1lc3BhY2VkIGNhbGxiYWNrIHRvIHRoZSBSVEUgd2luZG93IHNjcm9sbCBldmVudC4KICAgICAqIEBwYXJhbSBuYW1lc3BhY2UgdXNlZCBmb3IgdW5iaW5kaW5nIGUuZy4gcHJvcGVydHktcGFuZWwKICAgICAqIEBwYXJhbSBjYWxsYmFjayB0aGUgZnVuY3Rpb24gdG8gcnVuIHdoZW4gdGhlIGV2ZW50IG9jY3VycwogICAgICovCiAgICBiaW5kU2Nyb2xsOiBmdW5jdGlvbihuYW1lc3BhY2UsIGNhbGxiYWNrKSB7CiAgICAgICAgdmFyIGVkID0gdGhpcy5nZXRFZGl0b3IoKTsKICAgICAgICBBSlMubG9nKCJiaW5kIHNjcm9sbCBmb3IgZWQiKTsKICAgICAgICBBSlMubG9nKGVkKTsKICAgICAgICBBSlMuJChlZC5nZXREb2MoKSkuYWRkKGVkLmdldFdpbigpKS5iaW5kKCJzY3JvbGwuIiArIG5hbWVzcGFjZSwgY2FsbGJhY2spOwogICAgfSwKCiAgICAvKioKICAgICAqIFVuYmluZHMgYSBuYW1lc3BhY2UgYm91bmQgdG8gdGhlIFJURSB3aW5kb3cgc2Nyb2xsIGV2ZW50CiAgICAgKiBAcGFyYW0gbmFtZXNwYWNlCiAgICAgKi8KICAgIHVuYmluZFNjcm9sbDogZnVuY3Rpb24obmFtZXNwYWNlKSB7CiAgICAgICAgdmFyIGVkID0gdGhpcy5nZXRFZGl0b3IoKTsKICAgICAgICBBSlMuJChlZC5nZXREb2MoKSkuYWRkKGVkLmdldFdpbigpKS51bmJpbmQoInNjcm9sbC4iICsgbmFtZXNwYWNlKTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBOb24gaW50ZXJmYWNlIG1ldGhvZHMgJiB2YXJpYWJsZXMKICAgICAqLwogICAgX3BhZ2VFZGl0b3JIYXNJbml0OiBmYWxzZSwKICAgIF90aW55TWNlSGFzSW5pdCA6IGZhbHNlLAogICAgX3RpbnltY2VQbHVnaW5Jbml0cyA6IFtdLAoKICAgIF90aW55bWNlT25Jbml0Q2FsbGJhY2tzQ29tcGxldGUgOiBmYWxzZSwKCiAgICAvKioKICAgICAqIFByb3ZpZGVzIGEgcGx1Z2luIHBvaW50IHRvIGFsbG93IHBsdWdpbnMgdG8gaG9vayBpbnRvIHRoZSBwb2ludCBhdCB3aGljaCB0aGUgZnVsbCBzY3JlZW4gZWRpdG9yIGlzIGluaXRpYWxpc2VkLgogICAgICovCiAgICBmdWxsc2NyZWVuRWRpdG9yT25Jbml0Q2FsbGJhY2tzIDogW10sCgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBtYWluIGVkaXRvciBpbnN0YW5jZS4KICAgICAqLwogICAgZ2V0TWFpbkVkaXRvcjogZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBlID0gdGlueW1jZS5FZGl0b3JNYW5hZ2VyLmVkaXRvcnNbQUpTLkVkaXRvci5BZGFwdGVyLnNldHRpbmdzLmVkaXRvcl9pZF07CiAgICAgICAgaWYgKCFlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiTWFpbiBlZGl0b3IgaGFzIG5vdCBiZWVuIGluaXRpYWxpc2VkIHlldCBhbmQgaXMgdGhlcmVmb3JlIG5vdCBhY2Nlc3NpYmxlIHZpYSB0aW55bWNlLkVkaXRvck1hbmFnZXIuZWRpdG9ycyIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBmdWxsIHNjcmVlbiBlZGl0b3IgaW5zdGFuY2UuCiAgICAgKi8KICAgIGdldEZ1bGxTY3JlZW5FZGl0b3I6IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgZSA9IHRpbnltY2UuRWRpdG9yTWFuYWdlci5lZGl0b3JzW0FKUy5FZGl0b3IuQWRhcHRlci5zZXR0aW5ncy5mdWxsX3NjcmVlbl9lZGl0b3JfaWRdOwogICAgICAgIGlmICghZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkZ1bGwgc2NyZWVuIGVkaXRvciBoYXMgbm90IGJlZW4gaW5pdGlhbGlzZWQgeWV0IGFuZCBpcyB0aGVyZWZvcmUgbm90IGFjY2Vzc2libGUgdmlhIHRpbnltY2UuRWRpdG9yTWFuYWdlci5lZGl0b3JzIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBlOwogICAgfSwKCiAgICBnZXRUaW55TWNlSGFzSW5pdDogZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiB0aGlzLl90aW55TWNlSGFzSW5pdCAmJiB0aGlzLl90aW55bWNlT25Jbml0Q2FsbGJhY2tzQ29tcGxldGU7CiAgICB9LAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGFjdGl2ZSBlZGl0b3IKICAgICAqLwogICAgZ2V0RWRpdG9yIDogZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiB0aW55TUNFLmFjdGl2ZUVkaXRvcjsKICAgIH0sCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGlmcmFtZSBjb250YWluaW5nIHRoZSBjdXJyZW50IGFjdGl2ZSBlZGl0b3IKICAgICAqLwogICAgZ2V0RWRpdG9yRnJhbWU6IGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiAkKCIjIiArIHRoaXMuZ2V0RWRpdG9yKCkuaWQgKyAiX2lmciIpWzBdOwogICAgfSwKCiAgICBfZWRpdG9ySGludEtleXM6IFsKICAgICAgICAiaGludHMuaW5zZXJ0X2xpbmsiLAogICAgICAgICJoaW50cy5pbnNlcnRfaW1hZ2UiLAogICAgICAgICJoaW50cy5pbnNlcnRfbWFjcm8iLAogICAgICAgICJoaW50cy5pbnNlcnRfYnVsbGV0X2xpc3QiLAogICAgICAgICJoaW50cy5pbnNlcnRfbnVtYmVyZWRfbGlzdCIsCiAgICAgICAgImhpbnRzLmluc2VydF9oZWFkaW5nIiwKICAgICAgICAiaGludHMuaW5zZXJ0X3RhYmxlIiwKICAgICAgICAiaGludHMudGFibGVfcm93c19jb3B5IiwKICAgICAgICAiaGludHMudGFibGVfcm93c19jdXQiLAoKICAgICAgICAvL2F1dG9jb21wbGV0ZSBoaW50cwogICAgICAgICJoaW50cy5pbnNlcnRfbGlua19yZWNlbnRseV92aWV3ZWQiLAogICAgICAgICJoaW50cy5pbnNlcnRfbGlua19zZWFyY2giLAogICAgICAgICJoaW50cy5pbnNlcnRfbGlua19lbmQiLAogICAgICAgICJoaW50cy5pbnNlcnRfaW1hZ2Vfb25fcGFnZSIsCiAgICAgICAgImhpbnRzLmluc2VydF9pbWFnZV9zZWFyY2giLAogICAgICAgICJoaW50cy5pbnNlcnRfaW1hZ2VfZW5kIgogICAgXSwKCiAgICBzZXRTdGF0dXNiYXJUZXh0OiBmdW5jdGlvbih0ZXh0KSB7CiAgICAgICAgdmFyIHNwYW4gPSAkKCJodHRwOi8vMTAuMjAuMTYwLjE5OC93aWtpL3MvZW4vMjE2Ni8zNC8zLjUuOS9fL2Rvd25sb2FkL2JhdGNoL2NvbS5hdGxhc3NpYW4uY29uZmx1ZW5jZS50aW55bWNlcGx1Z2luOmVkaXRvci1yZXNvdXJjZXMvdGQubWNlU3RhdHVzYmFyIHNwYW4uaGludCIpOwogICAgICAgIGlmICghc3Bhbi5sZW5ndGgpIHsKICAgICAgICAgICAgc3BhbiA9ICQoIjxzcGFuIGNsYXNzPSdoaW50Jz48L3NwYW4+Iik7CiAgICAgICAgICAgICQoInRkLm1jZVN0YXR1c2JhciIpLmFwcGVuZChzcGFuKTsKICAgICAgICB9CiAgICAgICAgc3Bhbi5odG1sKHRleHQpOwogICAgfSwKCiAgICB0aW55TWNlT25Jbml0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgQUpTLmxvZygiQWRhcHRlcjp0aW55TWNlT25Jbml0IG9uaW5pdCBjYWxsYmFjayIpOwogICAgICAgIHRoaXMuX3RpbnlNY2VIYXNJbml0ID0gdHJ1ZTsKCiAgICAgICAgLy8gZGlzcGxheSBhIHJhbmRvbSBoaW50IGluIHRoZSBzdGF0dXMgYmFyCiAgICAgICAgdmFyIHJhbmRvbSA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSp0aGlzLl9lZGl0b3JIaW50S2V5cy5sZW5ndGgpOwogICAgICAgIHZhciBoaW50ID0gdGhpcy5fZWRpdG9ySGludEtleXNbcmFuZG9tXTsKICAgICAgICB2YXIgZWQgPSB0aGlzLmdldEVkaXRvcigpOwogICAgICAgIHZhciBpZTdkZXRlY3RlZCA9ICQuYnJvd3Nlci5tc2llICYmIChwYXJzZUludCgkLmJyb3dzZXIudmVyc2lvbikgPT0gNyk7CiAgICAgICAgdmFyIGVkaXRpbmdDb21tZW50ID0gQUpTLnBhcmFtcy5jb250ZW50VHlwZSA9PSAiY29tbWVudCIgJiYgQUpTLnBhcmFtcy5lZGl0b3JNb2RlID09ICJyaWNodGV4dCI7CiAgICAgICAgdGhpcy5zZXRTdGF0dXNiYXJUZXh0KGVkLmdldExhbmcoaGludCkpOwoKICAgICAgICBBSlMuYmluZCgidGlueW1jZS5vbmluaXQiLCBmdW5jdGlvbigpewogICAgICAgICAgICBBSlMuRWRpdG9yLkFkYXB0ZXIuX3RpbnltY2VPbkluaXRDYWxsYmFja3NDb21wbGV0ZSA9IHRydWU7CiAgICAgICAgfSk7CgogICAgICAgIC8vIHBhZ2UgZWRpdG9yIGphdmFzY3JpcHQgcnVucyBvbiBkb20gcmVhZHkgYW5kIGl0IG1pZ2h0IG5vdCBoYXZlIGZpbmlzaGVkIGF0IHRoaXMgcG9pbnQKICAgICAgICAvLyBhcyB0aW55bWNlIGlzIGluaXRpYWxpc2VkIGltbWVkaWF0ZWx5LCBvbiBzY3JpcHQgbG9hZAogICAgICAgIHZhciBjb3VudGVyID0gMDsKICAgICAgICAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICBpZiAoQUpTLkVkaXRvci5BZGFwdGVyLl9wYWdlRWRpdG9ySGFzSW5pdCkgewogICAgICAgICAgICAgICAgQUpTLnRyaWdnZXIoInRpbnltY2Uub25pbml0Iix7ZWRpdG9yOiBBSlMuRWRpdG9yLkFkYXB0ZXIuZ2V0RWRpdG9yKCl9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChjb3VudGVyKysgPCAxMDApIHsKICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGFyZ3VtZW50cy5jYWxsZWUsIDUwMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBBSlMubG9nKCJFUlJPUjogVGltZWQgb3V0IGZvciBleGVjdXRpbmcgdGlueW1jZSBvbmluaXQgY2FsbGJhY2sgZnVuY3Rpb25zIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9KSgpOwoKICAgICAgICAvLyBJbml0aWFsIElFIHJhbmdlIC0+IFczQyBET00gUmFuZ2UgaGFuZGxlcgogICAgICAgIHRoaXMuSUVSYW5nZSAmJiB0aGlzLklFUmFuZ2Uuc2V0dXBTZWxlY3Rpb24oZWQuZ2V0RG9jKCkpOwoKICAgICAgICAvLyBGb3Igc29tZSByZWFzb24gd2UgbmVlZCB0byBzZXQgdGhlIGZvY3VzIGFmdGVyIHRoZSByZXN0IG9mIHRoZSBzdGFjayBoYXMgZXhlY3V0ZWQsIG9yIHRoZSBjdXJzb3IKICAgICAgICAvLyB3aWxsIG5vdCBiZSByZW5kZXJlZCBpbiBGaXJlZm94LiBOb3RlOiBXZSB0cmllZCBzZXR0aW5nIHRoZSBmb2N1cyB0byB0aGUgdGl0bGUgZm9yIGNyZWF0ZSBwYWdlLAogICAgICAgIC8vIGhvd2V2ZXIgdGhpcyBjYXVzZWQgcHJvYmxlbXMgaW4gU2FmYXJpLCBzZWUgQ09ORkRFVi04NjguCiAgICAgICAgaWYgKCEoaWU3ZGV0ZWN0ZWQgJiYgZWRpdGluZ0NvbW1lbnQpKSB7CiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgIGVkLmZvY3VzKCk7CiAgICAgICAgICAgIH0sIDApOwogICAgICAgIH0KICAgIH0sCgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0ZXh0IGN1cnJlbnRseSBzZWxlY3RlZCBpbiB0aGUgUlRFCiAgICAgKi8KICAgIGdldFNlbGVjdGVkVGV4dCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgdmFyIHNlbGVjdGlvbiA9IHRpbnlNQ0UuYWN0aXZlRWRpdG9yLnNlbGVjdGlvbjsKICAgICAgICB2YXIgc2VsZWN0ZWRFbGVtZW50ID0gc2VsZWN0aW9uLmdldE5vZGUoKTsKICAgICAgICByZXR1cm4gc2VsZWN0aW9uLmdldFJuZygpLnRleHQgfHwgKHNlbGVjdGlvbi5nZXRTZWwoKSAmJiBzZWxlY3Rpb24uZ2V0U2VsKCkudG9TdHJpbmcgJiYgc2VsZWN0aW9uLmdldFNlbCgpLnRvU3RyaW5nKCkpIHx8ICIiOwogICAgfSwKCiAgICAvKioKICAgICAqIENhbGxlZCBhZnRlciBUaW55TUNFIHNldHMgdGhlIGNvbnRlbnQgb2YgdGhlIFJURS4gQW55IGN1c3RvbWl6YXRpb24gb2YgdGhlIEhUTUwgY2FuIG9jY3VyIGhlcmUuCiAgICAgKi8KICAgIG9uU2V0Q29udGVudCA6IGZ1bmN0aW9uKG5vZGUpIHsKICAgIH0sCgogICAgLyoqCiAgICAgKiBDYWxsZWQgYmVmb3JlIFRpbnlNQ0UgZ2V0cyB0aGUgY29udGVudCBvZiB0aGUgUlRFLiBBbnkgdW4tY3VzdG9taXphdGlvbiBvZiB0aGUgSFRNTCBjYW4gb2NjdXIgaGVyZS4KICAgICAqLwogICAgb25CZWZvcmVHZXRDb250ZW50IDogZnVuY3Rpb24obm9kZSkgewogICAgfSwKCiAgICBvZmZzZXQ6IGZ1bmN0aW9uIChlbGVtZW50KSB7CgogICAgICAgIC8vIHBhdGNoIGZvciBqUXVlcnkgb2Zmc2V0IHByb2JsZW0gd2l0aCBpZnJhbWVzCiAgICAgICAgaWYgKCJnZXRCb3VuZGluZ0NsaWVudFJlY3QiIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkgewogICAgICAgICAgICB2YXIgb2Zmc3QgPSBmdW5jdGlvbiAoZWxlbSkgewogICAgICAgICAgICAgICAgdmFyIGJveCAgICAgICAgPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLAogICAgICAgICAgICAgICAgICAgIGRvYyAgICAgICAgPSBlbGVtLm93bmVyRG9jdW1lbnQsCiAgICAgICAgICAgICAgICAgICAgYm9keSAgICAgICA9IGRvYy5ib2R5LAogICAgICAgICAgICAgICAgICAgIGRvY0VsZW0gICAgPSBkb2MuZG9jdW1lbnRFbGVtZW50LAogICAgICAgICAgICAgICAgICAgIGNsaWVudFRvcCAgPSBkb2NFbGVtLmNsaWVudFRvcCB8fCBib2R5LmNsaWVudFRvcCB8fCAwLAogICAgICAgICAgICAgICAgICAgIGNsaWVudExlZnQgPSBkb2NFbGVtLmNsaWVudExlZnQgfHwgYm9keS5jbGllbnRMZWZ0IHx8IDAsCiAgICAgICAgICAgICAgICAgICAgdG9wICAgICAgICA9IGJveC50b3AgICsgKGpRdWVyeS5zdXBwb3J0LmJveE1vZGVsICYmIGRvY0VsZW0uc2Nyb2xsVG9wICB8fCBib2R5LnNjcm9sbFRvcCkgLSBjbGllbnRUb3AsCiAgICAgICAgICAgICAgICAgICAgbGVmdCAgICAgICA9IGJveC5sZWZ0ICsgKGpRdWVyeS5zdXBwb3J0LmJveE1vZGVsICYmIGRvY0VsZW0uc2Nyb2xsTGVmdCB8fCBib2R5LnNjcm9sbExlZnQpIC0gY2xpZW50TGVmdDsKICAgICAgICAgICAgICAgIHJldHVybiB7IHRvcDogdG9wLCBsZWZ0OiBsZWZ0IH07CiAgICAgICAgICAgIH07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb2Zmc3QgPSBmdW5jdGlvbiAoZWxlbSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGpRdWVyeShlbGVtKS5vZmZzZXQoKTsKICAgICAgICAgICAgfTsKICAgICAgICB9CgoKICAgICAgICB2YXIgJG5vZGUgPSBBSlMuJChlbGVtZW50KSwKICAgICAgICAgICAgb2Zmc2V0ID0gb2Zmc3QoJG5vZGVbMF0pLAogICAgICAgICAgICBmcmFtZSA9ICQodGhpcy5nZXRFZGl0b3JGcmFtZSgpKSwKICAgICAgICAgICAgZnJhbWVPZmZzZXQgPSBmcmFtZS5vZmZzZXQoKSwKICAgICAgICAgICAgZnJhbWVEb2MgPSBmcmFtZVswXS5jb250ZW50V2luZG93LmRvY3VtZW50LAogICAgICAgICAgICBmcmFtZVNjcm9sbCA9IChqUXVlcnkuc3VwcG9ydC5ib3hNb2RlbCAmJiBmcmFtZURvYy5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wICB8fCBmcmFtZURvYy5ib2R5LnNjcm9sbFRvcCk7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgdG9wOiBmcmFtZU9mZnNldC50b3AgKyBvZmZzZXQudG9wIC0gZnJhbWVTY3JvbGwsCiAgICAgICAgICAgIGxlZnQ6IGZyYW1lT2Zmc2V0LmxlZnQgKyBvZmZzZXQubGVmdAogICAgICAgIH07CiAgICB9LAoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY3VycmVudCByYW5nZSBpbiBET00tc3R5bGUgZm9yIGFueSBicm93c2VyLgogICAgICovCiAgICBnZXRSYW5nZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAodGhpcy5JRVJhbmdlKQogICAgICAgICAgICByZXR1cm4gdGhpcy5JRVJhbmdlLmdldFNlbGVjdGlvbigpLmdldFJhbmdlQXQoMCk7CgogICAgICAgIHJldHVybiB0aW55TUNFLmFjdGl2ZUVkaXRvci5zZWxlY3Rpb24uZ2V0Um5nKCk7CiAgICB9LAoKICAgIC8qKgogICAgICogUmV0dXJucyBhIG5ldyBET00tc3R5bGUgcmFuZ2UgZm9yIGFueSBicm93c2VyLgogICAgICovCiAgICBjcmVhdGVSYW5nZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgZG9jID0gdGlueU1DRS5hY3RpdmVFZGl0b3IuZ2V0RG9jKCk7CgogICAgICAgIGlmICh0aGlzLklFUmFuZ2UgJiYgdGhpcy5JRVJhbmdlLmNyZWF0ZVJhbmdlKQogICAgICAgICAgICByZXR1cm4gdGhpcy5JRVJhbmdlLmNyZWF0ZVJhbmdlKGRvYyk7CgogICAgICAgIHJldHVybiBkb2MuY3JlYXRlUmFuZ2UoKTsKICAgIH0sCgogICAgLy8gVXNlZCB0byBlbnN1cmUgdGhhdCBhIFRleHROb2RlIGV4aXN0cyB1bmRlciB0aGUgc2VhcmNoLXRleHQgc3BhbiB3aGVuIHRoZSByYW5nZXMgYXJlIHNldC4KICAgIEhJRERFTl9DSEFSOiAiXHVmZWZmIiwKCiAgICAvKioKICAgICAqIFJlcGxhY2VzIHRoZSBlbGVtZW50IHdpdGggdGhlIGdpdmVuIHRleHQsIHdoaWNoIG1heSBiZSBlbXB0eS4KICAgICAqIElmIHRoZSBjb2xsYXBzZSBwYXJhbWV0ZXIgaXMgdHJ1ZSwgdGhlIHJhbmdlIHdpbGwgYmUgY29sbGFwc2VkIGF0IHRoZSBlbmQgb2YgdGhlIHRleHQuCiAgICAgKiBJZiB0aGUgZ2l2ZW4gdGV4dCBJUyBlbXB0eSwgaXQgd2lsbCBhbHdheXMgYmUgY29sbGFwc2VkLgogICAgICogQHBhcmFtIGVsZW1lbnQgIGpRdWVyeS13cmFwcGVkIGVsZW1lbnQgdG8gcmVwbGFjZQogICAgICogQHBhcmFtIHRleHQgIHN0cmluZyB0byByZXBsYWNlIGF1dG9jb21wbGV0ZSB3aXRoLCBpZiB1bmRlZmluZWQgYSBibGFuayBzdHJpbmcgaXMgdXNlZAogICAgICogQHBhcmFtIGNvbGxhcHNlVG9FbmQgaWYgdHJ1ZSwgY29sbGFwc2UgcmFuZ2UgdG8gZW5kIG9mIHRleHQsIGVsc2Ugc2VsZWN0IHRleHQKICAgICAqLwogICAgcmVwbGFjZVdpdGhUZXh0QW5kR2V0UmFuZ2U6IGZ1bmN0aW9uKGVsZW1lbnQsIHRleHQsIGNvbGxhcHNlVG9FbmQpIHsKICAgICAgICB0ZXh0ID0gdGV4dCB8fCAiIjsKICAgICAgICBjb2xsYXBzZVRvRW5kID0gY29sbGFwc2VUb0VuZCB8fCAhdGV4dDsKCiAgICAgICAgdmFyIGVkID0gdGhpcy5nZXRFZGl0b3IoKSwgcm5nOwogICAgICAgIGlmICh0aW55bWNlLmlzSUUpIHsKICAgICAgICAgICAgZWxlbWVudC5iZWZvcmUodGV4dCk7CgogICAgICAgICAgICBybmcgPSBlZC5nZXREb2MoKS5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpOwogICAgICAgICAgICBybmcubW92ZVRvRWxlbWVudFRleHQoZWxlbWVudFswXSk7CiAgICAgICAgICAgIGlmIChjb2xsYXBzZVRvRW5kKSB7CiAgICAgICAgICAgICAgICBybmcuY29sbGFwc2UoZmFsc2UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICFjb2xsYXBzZVRvRW5kICYmIHJuZy5tb3ZlU3RhcnQoImNoYXJhY3RlciIsIC10ZXh0Lmxlbmd0aCkgJiYgcm5nLm1vdmVFbmQoImNoYXJhY3RlciIsIC10ZXh0Lmxlbmd0aCAtIDEpOwogICAgICAgICAgICBybmcuc2VsZWN0KCk7CiAgICAgICAgICAgIGVsZW1lbnQucmVtb3ZlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdmFyIHBhcmVudCA9IGVsZW1lbnRbMF0ucGFyZW50Tm9kZSwKICAgICAgICAgICAgICAgIGN1cnNvclBvc2l0aW9uID0gdGhpcy5nZXRDaGlsZEluZGV4KHBhcmVudCwgZWxlbWVudFswXSksCiAgICAgICAgICAgICAgICBvZmZzZXQgPSBjb2xsYXBzZVRvRW5kID8gMSA6IDA7IC8vICshIWNvbGxhcHNlCgogICAgICAgICAgICBybmcgPSB0aGlzLmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgICAgIHJuZy5zZXRTdGFydChwYXJlbnQsIGN1cnNvclBvc2l0aW9uICsgb2Zmc2V0KTsKICAgICAgICAgICAgcm5nLnNldEVuZChwYXJlbnQsIGN1cnNvclBvc2l0aW9uICsgMSk7CgogICAgICAgICAgICBlbGVtZW50LmJlZm9yZSh0ZXh0IHx8IHRoaXMuSElEREVOX0NIQVIpLnJlbW92ZSgpOwogICAgICAgICAgICBlZC5zZWxlY3Rpb24uc2V0Um5nKHJuZyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcm5nOwogICAgfSwKCiAgICB0aW55TWNlRXZlbnRIYW5kbGVyIDogZnVuY3Rpb24oZSkgewogICAgICAgIC8vIGhhbmRsZSB0YWJiaW5nIGluIHRhYmxlcyBhbmQgbGlzdHMKICAgICAgICBpZiAoZS5rZXlDb2RlID09IDkpIHsKICAgICAgICAgICAgdmFyIGVkID0gdGhpcy5nZXRFZGl0b3IoKTsKICAgICAgICAgICAgdmFyIHNlbGVjdGlvbk5vZGUgPSBlZC5zZWxlY3Rpb24uZ2V0Tm9kZSgpOwogICAgICAgICAgICB2YXIgaW5UYWJsZSA9IGVkLmRvbS5nZXRQYXJlbnQoc2VsZWN0aW9uTm9kZSwgJ1RBQkxFJyk7CiAgICAgICAgICAgIHZhciBpbkxpc3QgPSBlZC5kb20uZ2V0UGFyZW50KHNlbGVjdGlvbk5vZGUsICdVTCcpIHx8IGVkLmRvbS5nZXRQYXJlbnQoc2VsZWN0aW9uTm9kZSwgJ09MJyk7CgogICAgICAgICAgICBpZiAoaW5MaXN0IHx8IGluVGFibGUpIHsKICAgICAgICAgICAgICAgIC8vIHN0b3AgZmlyZWZveCdzIGRlZmF1bHQgdGFiIGJlaGF2aW91cgogICAgICAgICAgICAgICAgaWYgKHRpbnltY2UuaXNHZWNrbyAmJiBlLnR5cGUgPT0gImtleXByZXNzIikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBBSlMuc3RvcEV2ZW50KGUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGxpc3RzIGhhdmUgcHJlY2VkZW5jZSBvdmVyIHRhYmxlcwogICAgICAgICAgICAgICAgaWYgKGUudHlwZSA9PSAia2V5ZG93biIpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY29tbWFuZDsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5MaXN0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSBlLnNoaWZ0S2V5ID8gIk91dGRlbnQiIDogIkluZGVudCI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgeyAgICAvLyBpblRhYmxlCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSBlLnNoaWZ0S2V5ID8gIm1jZVRhYmxlTW92ZVRvUHJldlJvdyIgOiAibWNlVGFibGVNb3ZlVG9OZXh0Um93IjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWQuZXhlY0NvbW1hbmQoY29tbWFuZCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gb3RoZXJ3aXNlIGNvbnRpbnVlIHdpdGggZGVmYXVsdCBoYW5kbGluZwogICAgfSwKCiAgICBhZGRUaW55TWNlUGx1Z2luSW5pdDogZnVuY3Rpb24oZnVuYykgewogICAgICAgIHRoaXMuX3RpbnltY2VQbHVnaW5Jbml0cy5wdXNoKGZ1bmMpOwogICAgfSwKCiAgICB3ZWJSZXNvdXJjZVBhdGggOiAiL2Rvd25sb2FkL3Jlc291cmNlcy9jb20uYXRsYXNzaWFuLmNvbmZsdWVuY2UudGlueW1jZXBsdWdpbiUzQXRpbnltY2VlZGl0b3IvIiwKCiAgICAvLyBnZXRzIHRoZSBiYXNlIHVybCBmcm9tIHRoZSBjdXJyZW50IGxvY2F0aW9uLAogICAgZ2V0Q3VycmVudEJhc2VVcmwgOiBmdW5jdGlvbigpIHsKICAgICAgICBpZiAoIXRoaXMuY3VycmVudEJhc2VVcmwpIHsKICAgICAgICAgICAgdmFyIGwgPSBkb2N1bWVudC5sb2NhdGlvbjsKICAgICAgICAgICAgdGhpcy5jdXJyZW50QmFzZVVybCA9IGwucHJvdG9jb2wgKyAiLy8iICsgbC5ob3N0bmFtZSArIChsLnBvcnQgPyAiOiIgKyBsLnBvcnQgOiAiIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRCYXNlVXJsOwogICAgfSwKCiAgICAvLyBnZXRzIHRoZSBzdGF0aWMgcmVzb3VyY2UgdXJsIHByZWZpeCwgd2hpY2ggd2lsbCBpbmNsdWRlIHRoZSBjYWNoaW5nIGhlYWRlcnMKICAgIGdldFJlc291cmNlVXJsUHJlZml4IDogZnVuY3Rpb24oKSB7CiAgICAgICAgaWYgKCF0aGlzLnJlc291cmNlVXJsUHJlZml4KSB7CiAgICAgICAgICAgIHRoaXMucmVzb3VyY2VVcmxQcmVmaXggPSB0aGlzLmdldEN1cnJlbnRCYXNlVXJsKCkgKyB0aGlzLmdldEVsZW1lbnRWYWx1ZSgiZWRpdG9yUGx1Z2luUmVzb3VyY2VQcmVmaXgiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXMucmVzb3VyY2VVcmxQcmVmaXg7CiAgICB9LAoKICAgIC8vIGdldHMgdGhlIGFic29sdXRlIHVybCBwYXRoIHRvIHRoZSB0aW55bWNlIHdlYiByZXNvdXJjZXMsIHdoaWNoIHdpbGwgaW5jbHVkZSB0aGUgY2FjaGluZyBoZWFkZXJzCiAgICBnZXRUaW55TWNlQmFzZVVybCA6IGZ1bmN0aW9uKCkgewogICAgICAgIGlmICghdGhpcy5hYnNvbHV0ZVVybCkgewogICAgICAgICAgICB0aGlzLmFic29sdXRlVXJsID0gIHRoaXMuZ2V0UmVzb3VyY2VVcmxQcmVmaXgoKSArIHRoaXMud2ViUmVzb3VyY2VQYXRoICsgInRpbnltY2Vzb3VyY2UvIjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXMuYWJzb2x1dGVVcmw7CiAgICB9LAoKICAgIC8vIEZvciBTZWxlbml1bSB0ZXN0cy4KICAgIHB1dEN1cnNvckF0UG9zdGlvbkluRWxlbWVudCA6IGZ1bmN0aW9uIChzZWxlY3RvciwgcG9zaXRpb24sIG5vZGUpIHsKICAgICAgICB2YXIgZWQgPSB0aW55TUNFLmFjdGl2ZUVkaXRvciwgZG9jID0gZWQuZ2V0RG9jKCk7CgogICAgICAgIC8vIG5lZWQgdGhlICN0ZXh0IG5vZGUgaW5zaWRlIHRoZSBzZWxlY3RlZCBlbGVtZW50LCBzbyBmaWx0ZXIgdGhlIGNoaWxkIG5vZGVzIG9mIHRoZSBzZWxlY3RvcgogICAgICAgIHZhciBlbCA9ICQoc2VsZWN0b3IsIG5vZGUgfHwgZG9jKTsKICAgICAgICBlbCA9IGVsLmNvbnRlbnRzKCkuZmlsdGVyKGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzLm5vZGVUeXBlID09IDM7IH0pWzBdOwogICAgICAgIHZhciByYW5nZSA9IHRoaXMuY3JlYXRlUmFuZ2UoKTsKICAgICAgICByYW5nZS5zZXRTdGFydChlbCwgcG9zaXRpb24pOwogICAgICAgIHJhbmdlLnNldEVuZChlbCwgcG9zaXRpb24pOwogICAgICAgIGVkLnNlbGVjdGlvbi5zZXRSbmcocmFuZ2UpOwogICAgfSwKCiAgICAvLyBEb2Vzbid0IHJlbHkgb24gQUpTLnBhcmFtcyBvbiBQVVJQT1NFIGFzIGl0IHJlcXVpcmVzIERPTSByZWFkeSAtIHVzZWQgZm9yIHF1aWNrbHkgZ2VuZXJhdGluZyBzZXR0aW5ncyBiZWxvdwogICAgZ2V0RWxlbWVudFZhbHVlOiBmdW5jdGlvbiAoaWQpIHsKICAgICAgICB2YXIgZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTsKICAgICAgICBpZiAoZSkgcmV0dXJuIGUudmFsdWU7CiAgICAgICAgcmV0dXJuICIiOwogICAgfSwKCiAgICAvKioKICAgICAqIEZpbmRzIHRoZSBpbmRleCBvZiB0aGUgc3VwcGxpZWQgY2hpbGROb2RlIGluIHRoZSBwYXJlbnROb2RlCiAgICAgKi8KICAgIGdldENoaWxkSW5kZXg6IGZ1bmN0aW9uKHBhcmVudE5vZGUsIGNoaWxkTm9kZSkgewogICAgICAgIHZhciBjaGlsZHJlbiA9IHBhcmVudE5vZGUuY2hpbGROb2RlczsKICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHsKICAgICAgICAgICAgaWYgKGNoaWxkcmVuW2ldID09IGNoaWxkTm9kZSkKICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gLTE7CiAgICB9LAoKICAgIC8qKgogICAgICogSW5zZXJ0cyBhIGxpbmsgYXQgdGhlIHBvc2l0aW9uIG9mIHRoZSBjdXJyZW50IHJhbmdlLgogICAgICogQHBhcmFtIGxpbmtEZXRhaWxzLCBjb250YWluaW5nCiAgICAgKiAgLSBocmVmIDogdGhlIHJlbGF0aXZlIFVSTAogICAgICogIC0gZGVzdGluYXRpb24gOiB0aGUgcGFydCB0byB0aGUgcmlnaHQgb2YgdGhlIHwKICAgICAqICAtIGFsaWFzIDogdGhlIHBhcnQgdG8gdGhlIGxlZnQgb2YgdGhlIHwsIG1heSBiZSBibGFuawogICAgICogIC0gdG9vbHRpcCA6IHRoZSB0b29sdGlwIChvcHRpb25hbCkKICAgICAqICAtIGFsaWFzc3BlY2lmaWVkIDogVGhpcyBzaG91bGQgYmUgdHJ1ZSBpZiB0aGUgc3VwcGxpZWQgYWxpYXMgd2FzIHNldCBieSB0aGUgdXNlciwgZmFsc2UgaWYgaXQncyB0aGUgZGVmYXVsdCBvbmUgZm9yIHRoZSB3aWtpIGxpbmsuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdGhpcyBtZXRob2QgcmVuZGVycyB0aGUgbGluayB3aXRob3V0IGdvaW5nIHRocm91Z2ggdGhlIHdpa2kgcmVuZGVyZXIgb24gdGhlIHNlcnZlci4KICAgICAqICAgICAgICAgICAgICAgICAgICAgSXQncyBpbXBvc3NpYmxlIHRvIGtub3cgdGhlIHJlbmRlcmVkIHRleHQgb2Ygc29tZSB3aWtpIGxpbmtzIHdpdGhvdXQgbWFraW5nIGEgc2VydmVyIGNhbGwuCiAgICAgKiBAcGFyYW0gbm9kZVRvUmVwbGFjZSAob3B0aW9uYWwpIHRoZSBub2RlIHRvIHJlcGxhY2Ugd2l0aCB0aGUgbmV3IGxpbmsKICAgICAqLwogICAgaW5zZXJ0TGluazogZnVuY3Rpb24gKGxpbmtEZXRhaWxzLCBub2RlVG9SZXBsYWNlKSB7CiAgICAgICAgdmFyIHQgPSBBSlMuRWRpdG9yLkFkYXB0ZXIsCiAgICAgICAgICAgIGxpbmsgPSB0Lm1ha2VMaW5rKGxpbmtEZXRhaWxzKTsKCiAgICAgICAgcmV0dXJuIHQuc2V0Tm9kZUF0Q3Vyc29yKGxpbmtbMF0sIG5vZGVUb1JlcGxhY2UpOwogICAgfSwKCiAgICAvKioKICAgICAqIFNldHMgdGhlIG5vZGUgYXQgdGhlIGN1cnNvciB0byBiZSB0aGUgbmV3IGVsZW1lbnQgYW5kIHBsYWNlcyB0aGUgY3Vyc29yCiAgICAgKiBhZnRlciB0aGUgZWxlbWVudC4gSWYgYSBub2RlVG9SZXBsYWNlIGlzIHBhc3NlZCwgdGhlIGN1cnNvciBpcyBhc3N1bWVkIHRvCiAgICAgKiBiZSBhdCB0aGUgZWxlbWVudCBhbmQgaXQgaXMgcmVwbGFjZWQuCiAgICAgKiBAcGFyYW0gbmV3RWxlbWVudCBlbGVtZW50IHRvIHB1dCBpbnRvIHRoZSBlZGl0b3IKICAgICAqIEBwYXJhbSBub2RlVG9SZXBsYWNlIChvcHRpb25hbCkgZWxlbWVudCB0byByZXBsYWNlIHdpdGggdGhlIG5ldyBvbmUKICAgICAqLwogICAgc2V0Tm9kZUF0Q3Vyc29yOiBmdW5jdGlvbiAobmV3RWxlbWVudCwgbm9kZVRvUmVwbGFjZSkgewogICAgICAgIHZhciBlZCA9IEFKUy5FZGl0b3IuQWRhcHRlci5nZXRFZGl0b3IoKTsKCiAgICAgICAgaWYgKG5vZGVUb1JlcGxhY2UpIHsKICAgICAgICAgICAgZWQuc2VsZWN0aW9uLnNlbGVjdChub2RlVG9SZXBsYWNlKTsKICAgICAgICAgICAgZWQuZG9tLnJlcGxhY2UobmV3RWxlbWVudCwgbm9kZVRvUmVwbGFjZSwgZmFsc2UpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZhciByYW5nZSA9IHRpbnlNQ0UuYWN0aXZlRWRpdG9yLnNlbGVjdGlvbi5nZXRSbmcoKTsKCiAgICAgICAgICAgIGlmICh0aW55bWNlLmlzSUUpIHsKICAgICAgICAgICAgICAgIHJhbmdlLnBhc3RlSFRNTChuZXdFbGVtZW50Lm91dGVySFRNTCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByYW5nZS5kZWxldGVDb250ZW50cygpOwogICAgICAgICAgICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZShuZXdFbGVtZW50KTsKICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobmV3RWxlbWVudCk7CiAgICAgICAgICAgICAgICByYW5nZS5zZXRFbmRBZnRlcihuZXdFbGVtZW50KTsKICAgICAgICAgICAgICAgIGVkLnNlbGVjdGlvbi5zZWxlY3QobmV3RWxlbWVudCwgZmFsc2UpOwogICAgICAgICAgICAgICAgZWQuc2VsZWN0aW9uLmNvbGxhcHNlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnQ7CiAgICB9LAoKICAgIG1ha2VMaW5rOiBmdW5jdGlvbiAobGlua0RldGFpbHMpIHsKICAgICAgICB2YXIgbGluayA9ICQoQUpTLkVkaXRvci5BZGFwdGVyLmdldEVkaXRvcigpLmdldERvYygpLmNyZWF0ZUVsZW1lbnQoImEiKSkuYXR0cih7CiAgICAgICAgICAgICAgICBocmVmOiBsaW5rRGV0YWlscy5ocmVmLAogICAgICAgICAgICAgICAgbGlua3R5cGU6ICJyYXciLAogICAgICAgICAgICAgICAgd2lraWRlc3RpbmF0aW9uOiBsaW5rRGV0YWlscy5kZXN0aW5hdGlvbgoKICAgICAgICAgICAgfSk7CiAgICAgICAgaWYgKCFsaW5rRGV0YWlscy5hbGlhcykgewogICAgICAgICAgICBsaW5rRGV0YWlscy5hbGlhcyA9IGxpbmtEZXRhaWxzLmRlc3RpbmF0aW9uOwogICAgICAgIH0KICAgICAgICBpZiAobGlua0RldGFpbHMuYWxpYXNzcGVjaWZpZWQpewogICAgICAgICAgICBsaW5rLmF0dHIoewogICAgICAgICAgICAgICAgYWxpYXNzcGVjaWZpZWQ6ICJ0cnVlIgogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgaWYgKEFKUy5FZGl0b3IuQWRhcHRlci5pc0V4dGVybmFsTGluayhsaW5rRGV0YWlscy5kZXN0aW5hdGlvbikpIHsKICAgICAgICAgICAgbGluay5hZGRDbGFzcygiZXh0ZXJuYWwtbGluayIpOwogICAgICAgIH0KICAgICAgICAvLyBvcmlnaW5hbGFsaWFzIG5lZWRzIHRvIGJlIHNwZWNpZmllZCBvciB0aGUgUlRFLT53aWtpIGNvbnZlcnRlciBwdXRzIGFuIGFsaWFzIGluLgogICAgICAgIGxpbmsuYXR0cih7CiAgICAgICAgICAgIG9yaWdpbmFsYWxpYXM6IGxpbmtEZXRhaWxzLmFsaWFzCiAgICAgICAgfSk7CgogICAgICAgIGxpbmsudGV4dChsaW5rRGV0YWlscy5hbGlhcyB8fCBsaW5rRGV0YWlscy5kZXN0aW5hdGlvbik7CiAgICAgICAgbGlua0RldGFpbHMudG9vbHRpcCAmJiBsaW5rLmF0dHIoewogICAgICAgICAgICB0aXRsZTogbGlua0RldGFpbHMudG9vbHRpcCwKICAgICAgICAgICAgd2lraXRpdGxlOiBsaW5rRGV0YWlscy50b29sdGlwCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIGxpbms7CiAgICB9LAoKICAgIGlzRXh0ZXJuYWxMaW5rOiBmdW5jdGlvbihkZXN0aW5hdGlvbikgeyAvL1NhbWUgY2hlY2sgYXMgQ29uZmx1ZW5jZUxpbmtSZXNvbHZlcgogICAgICAgIHJldHVybiBkZXN0aW5hdGlvbi5tYXRjaCgvXihcL1wvfG1haWx0bzp8ZmlsZTp8aHR0cDp8aHR0cHM6KS8pIHx8IGRlc3RpbmF0aW9uLmluZGV4T2YoIlxcIikgPT0gMDsKCiAgICB9LAogICAgLy8gSW5pdGlhbGlzZXMgdGhlIFRpbnlNQ0UgZWRpdG9yLiBUaGlzIGNhbiBiZSBydW4gd2l0aG91dCB3YWl0aW5nIGZvciBET00gcmVhZHkgaWYgdGhlIGxhbmd1YWdlIHBhY2sgdmFyaWFibGUKICAgIC8vIFRpbnlNQ0VMYW5nIGlzIGF2YWlsYWJsZSBiZWZvcmUgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLgogICAgaW5pdFRpbnlNY2U6IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciB0ID0gQUpTLkVkaXRvci5BZGFwdGVyOwogICAgICAgIHQuc2V0dGluZ3MgPSB7CgogICAgICAgICAgICAvLyBnZW5lcmFsCiAgICAgICAgICAgIHdpZHRoOiAiMTAwJSIsCiAgICAgICAgICAgIGhlaWdodDogdC5nZXRFbGVtZW50VmFsdWUoInBhcmFtc0hlaWdodCIpLAogICAgICAgICAgICBkb2N1bWVudF9iYXNlX3VybDogdC5nZXRUaW55TWNlQmFzZVVybCgpLAogICAgICAgICAgICBsYW5ndWFnZTogdC5nZXRFbGVtZW50VmFsdWUoImFjdGlvbkxvY2FsZSIpLAogICAgICAgICAgICBidXR0b25fdGlsZV9tYXA6IHRydWUsCiAgICAgICAgICAgIGF1dG9fcmVzZXRfZGVzaWdubW9kZTogdHJ1ZSwgLy8gcmVjb21tZW5kZWQgZm9yIHRhYnMgYW5kIGhpZGRpbmcgZWRpdG9ycwogICAgICAgICAgICBwbHVnaW5zOiAidGFibGUscGFzdGUsZW1vdGlvbnMsZnVsbHNjcmVlbixjb25mbHVlbmNlLGNvbnRleHRtZW51LGF1dG9jb21wbGV0ZSxzYWZhcmkscHJvcGVydHlwYW5lbCxrZXlib2FyZHNob3J0Y3V0cyIsCiAgICAgICAgICAgIGdlY2tvX3NwZWxsY2hlY2sgOiB0cnVlLAoKICAgICAgICAgICAgLy8gYWR2YW5jZWQgdGhlbWUgcGFyYW1zCiAgICAgICAgICAgIHRoZW1lOiAiYWR2YW5jZWQiLAogICAgICAgICAgICB0aGVtZV9hZHZhbmNlZF9idXR0b25zMTogImZvcm1hdHNlbGVjdCxib2xkLGl0YWxpYyx1bmRlcmxpbmUsc3RyaWtldGhyb3VnaCxmb3JlY29sb3Isc2VwYXJhdG9yLCIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhYmxlLHJvd19iZWZvcmUscm93X2FmdGVyLGRlbGV0ZV9yb3csY29sX2JlZm9yZSxjb2xfYWZ0ZXIsZGVsZXRlX2NvbCxkZWxldGVfdGFibGUsc2VwYXJhdG9yLCIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJ1bGxpc3QsbnVtbGlzdCxvdXRkZW50LGluZGVudCxzZXBhcmF0b3IsIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5kbyxyZWRvLHNlcGFyYXRvciwiICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb25maW5zZXJ0LGNvbmZsaW5rLGNvbmZpbWFnZSxjb25mX21hY3JvX2Jyb3dzZXIsc2VwYXJhdG9yLCIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNlYXJjaCxmdWxsc2NyZWVuLGNvbnRleHRtZW51LGNvbmZzaG9ydGN1dGRpYWxvZyIsCiAgICAgICAgICAgIHRoZW1lX2FkdmFuY2VkX2J1dHRvbnMyOiAiIiwKICAgICAgICAgICAgdGhlbWVfYWR2YW5jZWRfYnV0dG9uczM6ICIiLAogICAgICAgICAgICB0aGVtZV9hZHZhbmNlZF90b29sYmFyX2xvY2F0aW9uOiAidG9wIiwKICAgICAgICAgICAgdGhlbWVfYWR2YW5jZWRfdG9vbGJhcl9hbGlnbjogImxlZnQiLAogICAgICAgICAgICB0aGVtZV9hZHZhbmNlZF9yZXNpemluZzogdHJ1ZSwKICAgICAgICAgICAgdGhlbWVfYWR2YW5jZWRfcmVzaXplX2hvcml6b250YWw6IGZhbHNlLAogICAgICAgICAgICB0aGVtZV9hZHZhbmNlZF9zdGF0dXNiYXJfbG9jYXRpb246ICJib3R0b20iLAogICAgICAgICAgICB0aGVtZV9hZHZhbmNlZF9wYXRoOiBmYWxzZSwKICAgICAgICAgICAgdGhlbWVfYWR2YW5jZWRfYmxvY2tmb3JtYXRzOiAiaDEsaDIsaDMsaDQsaDUsaDYsbWFjcm9fcXVvdGUsbWFjcm9fcGFuZWwsbWFjcm9fY29kZSxtYWNyb19ub2Zvcm1hdCIsCgogICAgICAgICAgICAvLyBzZWxlY3RvcnMgZm9yIHRpbnltY2UgZWRpdG9ycwogICAgICAgICAgICBtb2RlOiAidGV4dGFyZWFzIiwKICAgICAgICAgICAgZWRpdG9yX3NlbGVjdG9yOiAidGlueW1jZS1lZGl0b3IiLAoKICAgICAgICAgICAgLy8gY2FsbGJhY2tzCiAgICAgICAgICAgIG9uaW5pdDogIkFKUy5FZGl0b3IuQWRhcHRlci50aW55TWNlT25Jbml0IiwKICAgICAgICAgICAgaGFuZGxlX2V2ZW50X2NhbGxiYWNrOiAiQUpTLkVkaXRvci5BZGFwdGVyLnRpbnlNY2VFdmVudEhhbmRsZXIiLAoKICAgICAgICAgICAgLy8gdGFibGUgc2V0dGluZ3MKICAgICAgICAgICAgdmlzdWFsOiBmYWxzZSwKICAgICAgICAgICAgY29uZmx1ZW5jZV90YWJsZV9zdHlsZTogImNvbmZsdWVuY2VUYWJsZSIsCiAgICAgICAgICAgIGNvbmZsdWVuY2VfdGFibGVfY2VsbF9zdHlsZTogImNvbmZsdWVuY2VUZCIsCiAgICAgICAgICAgIGNvbmZsdWVuY2VfdGFibGVfaGVhZGVyX3N0eWxlOiAiY29uZmx1ZW5jZVRoIiwKICAgICAgICAgICAgY29uZmx1ZW5jZV90YWJsZV9kZWZhdWx0X3Jvd3M6IDQsCiAgICAgICAgICAgIGNvbmZsdWVuY2VfdGFibGVfZGVmYXVsdF9jb2xzOiAzLAogICAgICAgICAgICBjb25mbHVlbmNlX3RhYmxlX2RlZmF1bHRfaGVhZGluZzogdHJ1ZSwKCiAgICAgICAgICAgIC8vIG91dHB1dCBzZXR0aW5ncwogICAgICAgICAgICBjbGVhbnVwOiBmYWxzZSwgLy8gZG9uJ3QgY2xlYW4gdXAgY2F1c2Ugd2UgaGF2ZSBzcGVjaWFsIG1hY3JvIGF0dHJpYnV0ZXMgd2hpY2ggbmVlZCB0byBiZSBhZGRlZCB0byAidmFsaWRfZWxlbWVudHMiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZWRpdG9yLnNlbGVjdGlvbi5nZXRDb250ZW50IHN0aWxsIGNhbGxzIGNsZWFudXAgc28gd2Ugc3RpbGwgc2hvdWxkIHNldCB2YWxpZF9lbGVtZW50cyBhcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlbGwgYXMgcG9zc2libGUuCiAgICAgICAgICAgIHZhbGlkX2VsZW1lbnRzIDogLy8gVGhlb3JldGljYWxseSwgbW9zdCBlbGVtZW50cyBhcmUgYWxsb3dlZCB0byBoYXZlIGEgd3lzaXd5ZyBwYXJhbWV0ZXIgc2V0LiAgU2VlIEV4dGVybmFsbHlEZWZpbmVkQ29udmVydGVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0BbaWR8Y2xhc3N8c3R5bGV8dGl0bGV8d3lzaXd5Z3xkaXI8bHRyP3J0bHxsYW5nfHhtbDo6bGFuZ3xvbmNsaWNrfG9uZGJsY2xpY2t8b25tb3VzZWRvd258b25tb3VzZXVwfG9ubW91c2VvdmVyfG9ubW91c2Vtb3ZlfG9ubW91c2VvdXR8b25rZXlwcmVzc3xvbmtleWRvd258b25rZXl1cF0sJyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgYWRkIGV4dHJhIGxpbmsgYXR0cmlidXRlcyB0byBoZWxwIGNvbnZlcnNpb24gdG8gd2lraSBtYXJrdXAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYVtsaW5rdHlwZXx3aWtpdGl0bGV8YWxpYXNzcGVjaWZpZWR8b3JpZ2luYWxhbGlhc3x3aWtpZGVzdGluYXRpb258cmVsfHJldnxjaGFyc2V0fGhyZWZsYW5nfHRhYmluZGV4fGFjY2Vzc2tleXx0eXBlfG5hbWV8aHJlZnx0YXJnZXR8dGl0bGV8Y2xhc3N8b25mb2N1c3xvbmJsdXJdLCcgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJvbmcvYixlbS9pLHN0cmlrZSx1LCcgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVzZXIgcGFyYWdyYXBocyBpbmRpY2F0ZSBhIGJsYW5rIGxpbmUuICBTZWUgRGVmYXVsdFd5c2l3eWdDb252ZXJ0ZXIuaXNVc2VyTmV3bGluZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICcjcFthbGlnbnx1c2VyXSwnICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLW9sW3R5cGV8Y29tcGFjdF0sLXVsW3R5cGV8Y29tcGFjdF0sLWxpLGJyLCcgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBJbWFnZUNvbnZlcnRlciB1c2VzIGFuIGltYWdldGV4dCBhdHRyaWJ1dGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaW1nW2ltYWdldGV4dHxsb25nZGVzY3x1c2VtYXB8c3JjfGJvcmRlcnxhbHQ9fHRpdGxlfGhzcGFjZXx2c3BhY2V8d2lkdGh8aGVpZ2h0fGFsaWduXSwnICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLXN1Yiwtc3VwLCcrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIG1hcmt1cCB0YWcgaXMgdXNlZCB0byBkaXN0aW5ndWlzaCBicS4gbWFya3VwIGZyb20ge3F1b3RlfXMuICBTZWUgQmxvY2tRdW90ZUNvbnZlcnRlci5qYXZhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJy1ibG9ja3F1b3RlW2NpdGV8bWFya3VwXSwnICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLXRhYmxlW2JvcmRlcj0wfGNlbGxzcGFjaW5nfGNlbGxwYWRkaW5nfHdpZHRofGZyYW1lfHJ1bGVzfGhlaWdodHxhbGlnbnxzdW1tYXJ5fGJnY29sb3J8YmFja2dyb3VuZHxib3JkZXJjb2xvcl0sJyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJy10cltyb3dzcGFufHdpZHRofGhlaWdodHxhbGlnbnx2YWxpZ258Ymdjb2xvcnxiYWNrZ3JvdW5kfGJvcmRlcmNvbG9yXSx0Ym9keSx0aGVhZCx0Zm9vdCwnICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnI3RkW2NvbHNwYW58cm93c3Bhbnx3aWR0aHxoZWlnaHR8YWxpZ258dmFsaWdufGJnY29sb3J8YmFja2dyb3VuZHxib3JkZXJjb2xvcnxzY29wZV0sJyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyN0aFtjb2xzcGFufHJvd3NwYW58d2lkdGh8aGVpZ2h0fGFsaWdufHZhbGlnbnxzY29wZV0sY2FwdGlvbiwnICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBFeHRyYSBEaXYgZWxlbWVudHMgYXJlIGFkZGVkIHRvIG1hY3JvIGRpdnMgdG8gaGVscCBjb252ZXJzaW9uIHRvIHdpa2kgbWFya3VwCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJy1kaXZbbWFjcm9uYW1lfG1hY3Jvc3RhcnR0YWd8bWFjcm9oYXNib2R5fHdpa2loYXNuZXdsaW5lYmVmb3JlYm9keXx3aWtpaGFzbmV3bGluZWFmdGVyYm9keXx3aWtpaGFzcHJlY2VkaW5nbmV3bGluZXx3aWtpaGFzdHJhaWxpbmduZXdsaW5lXSwnICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLXNwYW4sLWNvZGUsLXByZSxhZGRyZXNzLC1oMSwtaDIsLWgzLC1oNCwtaDUsLWg2LGhyW3NpemV8bm9zaGFkZV0sJyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJy1mb250W2ZhY2V8c2l6ZXxjb2xvcl0sZGQsZGwsZHQsY2l0ZSxhYmJyLGFjcm9ueW0sZGVsW2RhdGV0aW1lfGNpdGVdLGluc1tkYXRldGltZXxjaXRlXSxvYmplY3RbY2xhc3NpZHx3aWR0aHxoZWlnaHR8Y29kZWJhc2V8Kl0scGFyYW1bbmFtZXx2YWx1ZV0sJyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2VtYmVkW3R5cGV8d2lkdGh8aGVpZ2h0fHNyY3wqXSxzY3JpcHRbc3JjfHR5cGVdLG1hcFtuYW1lXSxhcmVhW3NoYXBlfGNvb3Jkc3xocmVmfGFsdHx0YXJnZXRdLGJkbyxidXR0b24sY29sW2FsaWdufGNoYXJ8Y2hhcm9mZnxzcGFufHZhbGlnbnx3aWR0aF0sJyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbGdyb3VwW2FsaWdufGNoYXJ8Y2hhcm9mZnxzcGFufHZhbGlnbnx3aWR0aF0sZGZuLGZpZWxkc2V0LGZvcm1bYWN0aW9ufGFjY2VwdHxhY2NlcHQtY2hhcnNldHxlbmN0eXBlfG1ldGhvZF0sJyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2lucHV0W2FjY2VwdHxhbHR8Y2hlY2tlZHxkaXNhYmxlZHxtYXhsZW5ndGh8bmFtZXxyZWFkb25seXxzaXplfHNyY3x0eXBlfHZhbHVlXSxrYmQsbGFiZWxbZm9yXSxsZWdlbmQsbm9zY3JpcHQsJyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ29wdGdyb3VwW2xhYmVsfGRpc2FibGVkXSxvcHRpb25bZGlzYWJsZWR8bGFiZWx8c2VsZWN0ZWR8dmFsdWVdLHFbY2l0ZV0sc2FtcCxzZWxlY3RbZGlzYWJsZWR8bXVsdGlwbGV8bmFtZXxzaXplXSxzbWFsbCwnICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dGFyZWFbY29sc3xyb3dzfGRpc2FibGVkfG5hbWV8cmVhZG9ubHldLHR0LHZhcixiaWcnLAogICAgICAgICAgICBmb3JjZV9wX25ld2xpbmVzOiB0cnVlLCAvLyBkZWZhdWx0CiAgICAgICAgICAgIGZvcmNlX2JyX25ld2xpbmVzOiBmYWxzZSwgLy8gZGVmYXVsdAoKICAgICAgICAgICAgLy8gbGF5b3V0IHNldHRpbmdzCiAgICAgICAgICAgIGJvZHlfY2xhc3M6ICJ3aWtpLWNvbnRlbnQiLAogICAgICAgICAgICBjb250ZW50X2NzczogdC5nZXRSZXNvdXJjZVVybFByZWZpeCgpICsgIi9zdHlsZXMvY29tYmluZWQuY3NzP2Zvcld5c2l3eWc9dHJ1ZSZzcGFjZUtleT0iICsgZW5jb2RlVVJJKHQuZ2V0RWxlbWVudFZhbHVlKCJzcGFjZUtleSIpKSwKICAgICAgICAgICAgcG9wdXBfY3NzOiB0LmdldFJlc291cmNlVXJsUHJlZml4KCkgKyAiL3N0eWxlcy9jb21iaW5lZC5jc3M/c3BhY2VLZXk9IiArIGVuY29kZVVSSSh0LmdldEVsZW1lbnRWYWx1ZSgic3BhY2VLZXkiKSksCgogICAgICAgICAgICByZXNvdXJjZV9wcmVmaXg6IHQuZ2V0UmVzb3VyY2VVcmxQcmVmaXgoKSwKCiAgICAgICAgICAgIC8vIGNvbmZsdWVuY2Utc3BlY2lmaWMgc2V0dGluZ3MKICAgICAgICAgICAgY29udGV4dF9wYXRoOiB0LmdldEVsZW1lbnRWYWx1ZSgiY29udGV4dFBhdGgiKSwKICAgICAgICAgICAgcGx1Z2luX2FjdGlvbl9iYXNlX3BhdGg6IHQuZ2V0RWxlbWVudFZhbHVlKCJjb250ZXh0UGF0aCIpICsgIi9wbHVnaW5zL3RpbnltY2UiLAogICAgICAgICAgICBwYWdlX2lkOiB0LmdldEVsZW1lbnRWYWx1ZSgicGFnZUlkIiksCiAgICAgICAgICAgIGRyYWZ0X3R5cGU6IG51bGwsCiAgICAgICAgICAgIGZvcm1fbmFtZTogdC5nZXRFbGVtZW50VmFsdWUoImZvcm1OYW1lIiksCiAgICAgICAgICAgIHNwYWNlX2tleTogZW5jb2RlVVJJKHQuZ2V0RWxlbWVudFZhbHVlKCJzcGFjZUtleSIpKSwKICAgICAgICAgICAgY29uZmx1ZW5jZV9wb3B1cF93aWR0aDogNjIwLAogICAgICAgICAgICBjb25mbHVlbmNlX3BvcHVwX2hlaWdodDogNTUwLAogICAgICAgICAgICBlbGVtZW50czogInd5c2l3eWdUZXh0YXJlYSIsCiAgICAgICAgICAgIGVkaXRvcl9pZDogInd5c2l3eWdUZXh0YXJlYSIsCiAgICAgICAgICAgIGZ1bGxfc2NyZWVuX2VkaXRvcl9pZDogIm1jZV9mdWxsc2NyZWVuIgogICAgICAgIH07CgogICAgICAgIC8vIGFsdGVyIHNldHRpbmdzIGZvciBkcmFmdHMKICAgICAgICBpZiAodC5zZXR0aW5ncy5wYWdlX2lkID09IDApIHsKICAgICAgICAgICAgdC5zZXR0aW5ncy5wYWdlX2lkID0gbnVsbDsKICAgICAgICAgICAgdC5zZXR0aW5ncy5kcmFmdF90eXBlID0gdC5nZXRFbGVtZW50VmFsdWUoImRyYWZ0VHlwZSIpOwogICAgICAgIH0KCiAgICAgICAgLy8gbG9hZCB0aGUgaTE4biBrZXlzIGZvciB0aW55bWNlCiAgICAgICAgaWYgKHR5cGVvZiBUaW55TUNFTGFuZyAhPSAidW5kZWZpbmVkIikgewogICAgICAgICAgICB2YXIgY3RybFRyYW5zID0gVGlueU1DRUxhbmdbdC5zZXR0aW5ncy5sYW5ndWFnZV0uY3RybF9rZXkgKyAiXFwrIjsKICAgICAgICAgICAgdmFyIHNoaWZ0VHJhbnMgPSBUaW55TUNFTGFuZ1t0LnNldHRpbmdzLmxhbmd1YWdlXS5zaGlmdF9rZXkgKyAiXFwrIjsKICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIFRpbnlNQ0VMYW5nKSB7CiAgICAgICAgICAgICAgICAvLyBtYWtlIHRvb2wtdGlwcyBtYWMgZnJpZW5kbHkKICAgICAgICAgICAgICAgIHZhciBsYW5nR3JvdXAgPSBUaW55TUNFTGFuZ1trZXldOwogICAgICAgICAgICAgICAgZm9yICh2YXIgc3RyS2V5ICBpbiBsYW5nR3JvdXApIHsKICAgICAgICAgICAgICAgICAgICBpZih0aW55bWNlLmlzTWFjKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxhbmdHcm91cFtzdHJLZXldID0gbGFuZ0dyb3VwW3N0cktleV0ucmVwbGFjZShSZWdFeHAoY3RybFRyYW5zLCAnZycpLCAiXHUyMzE4Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIGxhbmdHcm91cFtzdHJLZXldID0gbGFuZ0dyb3VwW3N0cktleV0ucmVwbGFjZShSZWdFeHAoc2hpZnRUcmFucywgJ2cnKSwgIlx1MjFFNyIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aW55bWNlLkVkaXRvck1hbmFnZXIuYWRkSTE4bihrZXksIFRpbnlNQ0VMYW5nW2tleV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBBSlMubG9nKCJFUlJPUjogY291bGQgbm90IGZpbmQgdGhlIFRpbnlNQ0UgbGFuZ3VhZ2UgcGFjayIpOwogICAgICAgIH0KCiAgICAgICAgLy8gcGx1Z2luIHBvaW50IGZvciB0aW55bWNlIHBsdWdpbnMgdG8gY29uZmlndXJlIHNldHRpbmdzCiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gdC5fdGlueW1jZVBsdWdpbkluaXRzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHsKICAgICAgICAgICAgaWYgKHR5cGVvZiB0Ll90aW55bWNlUGx1Z2luSW5pdHNbaV0gPT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICAgICAgdC5fdGlueW1jZVBsdWdpbkluaXRzW2ldKHQuc2V0dGluZ3MpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB0aW55TUNFLmluaXQodC5zZXR0aW5ncyk7CgogICAgICAgIEFKUy5sb2coIkFkYXB0ZXI6YWZ0ZXIgZWRpdG9yIG1hbmFnZXIgaW5pdCIpOwogICAgICAgIHRpbnlNQ0Uub25CZWZvcmVVbmxvYWQuYWRkVG9Ub3AoQUpTLkVkaXRvci5oYW5kbGVVbmxvYWQpOwogICAgICAgIHRpbnltY2UuY29uZmx1ZW5jZS5tYWNyb2Jyb3dzZXIub25UaW55TWNlSW5pdGlhbGlzZWQodC5nZXRFZGl0b3IoKSk7CiAgICAgICAgdC5lZGl0b3JSZXNldENvbnRlbnRDaGFuZ2VkKCk7IC8vIHNvIHdlIGRvbid0IHRyaWdnZXIgZHJhZnRzIGR1ZSB0byBtYWNybyBtYW5pcHVsYXRpb24KICAgIH0KCgp9O30pKEFKUy4kKTsKCi8vIGlmIHRoZXJlIGlzIGEgYm9keSwgd2UgY2FuIGFzc3VtZSB0aGF0IHRoZSBzY3JpcHRzIGFyZSBhdCB0aGUgYm90dG9tCi8vIGFuZCBpbml0IFRpbnlNQ0Ugd2l0aG91dCB3YWl0aW5nIGZvciBET00gcmVhZHkKaWYgKGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJib2R5IikubGVuZ3RoKSB7CiAgICBBSlMuRWRpdG9yLkFkYXB0ZXIuaW5pdFRpbnlNY2UoKTsKfQplbHNlIHsKICAgIEFKUy50b0luaXQoQUpTLkVkaXRvci5BZGFwdGVyLmluaXRUaW55TWNlKTsKfQoKCi8qKgogKiBDb25mbHVlbmNlIHByb3BlcnR5IHBhbmVscyBmb3IgaW1hZ2VzIGFuZCBsaW5rcy4KICovCihmdW5jdGlvbigkKSB7CiAgICB2YXIgaGFuZGxlcnMgPSBuZXcgQXJyYXkoKTsKICAgIEFKUy5iaW5kKCJhZGQtaGFuZGxlci5wcm9wZXJ0eS1wYW5lbCIsIGZ1bmN0aW9uIChlLCBkYXRhKSB7CiAgICAgICAgaGFuZGxlcnMucHVzaChkYXRhKTsKICAgIH0pOwoKCiAgICB0aW55bWNlLmNyZWF0ZSgndGlueW1jZS5wbHVnaW5zLlByb3BlcnR5UGFuZWwnLCB7CiAgICAgICAgaW5pdCA6IGZ1bmN0aW9uKGVkKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgQSBzaW5nbGUgc2VsZWN0aW9uIGV2ZW50IG1pZ2h0IGhhdmUgc2V2ZXJhbCBjb250ZXh0czoKICAgICAgICAgICAgICAtIE5vIGN1cnJlbnQgcHJvcGVydHkgcGFuZWwKICAgICAgICAgICAgICAtLSBTZWxlY3RlZCBlbGVtZW50IHRoYXQgRE9FU04nVCBmaXJlIGEgcGFuZWwKICAgICAgICAgICAgICAtLSBTZWxlY3RlZCBlbGVtZW50IHRoYXQgRE9FUyBmaXJlIGEgcGFuZWwKICAgICAgICAgICAgICAtIEN1cnJlbnQgcHJvcGVydHkgcGFuZWwKICAgICAgICAgICAgICAtLSBTZWxlY3RlZCBlbGVtZW50IHRoYXQgRE9FU04nVCBmaXJlIGEgcGFuZWwKICAgICAgICAgICAgICAtLSBTZWxlY3RlZCBlbGVtZW50IHRoYXQgRE9FUyBmaXJlIGEgcGFuZWwKICAgICAgICAgICAgICAtLS0gU2VsZWN0ZWQgdGhlIGFuY2hvciBvZiB0aGUgQ1VSUkVOVCBwcm9wZXJ0eSBwYW5lbAogICAgICAgICAgICAgIC0tLSBTZWxlY3RlZCBhIGRpZmZlcmVudCBlbGVtZW50IHRoYXQgRE9FUyBmaXJlIGEgcGFuZWwKICAgICAgICAgICAgICAtLS0tIFNlbGVjdGVkIGEgZGlmZmVyZW50IGVsZW1lbnQgdGhhdCBET0VTIGZpcmUgYSBwYW5lbCBvZiB0aGUgU0FNRSB0eXBlCiAgICAgICAgICAgICAgLS0tLSBTZWxlY3RlZCBhIGRpZmZlcmVudCBlbGVtZW50IHRoYXQgRE9FUyBmaXJlIGEgcGFuZWwgb2YgYSBESUZGRVJFTlQgdHlwZQoKICAgICAgICAgICAgICBUbyBiZWdpbiB3aXRoIGl0IHdpbGwgYmUgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSBlbGVtZW50LXNwZWNpZmljIGNvZGUgKGltZy9hL2V0YykgdG8gZGV0ZXJtaW5lIHRoZSBjb250ZXh0OwogICAgICAgICAgICAgIGlmIGVub3VnaCBvdmVybGFwIGJldHdlZW4gSU1HIGFuZCBBIGlzIGZvdW5kIGl0IGNhbiBiZSBjZW50cmFsaXplZCBoZXJlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgQUpTLmxvZygiaW5pdCBwcm9wZXJ0eSBwYW5lbCBwbHVnaW4iKTsKICAgICAgICAgICAgdmFyIGJvdW5kRWxlbWVudCwKICAgICAgICAgICAgaXNSaWdodENsaWNrID0gZnVuY3Rpb24gKGUpIHsKICAgICAgICAgICAgICAgIGlmIChlLnR5cGUgIT0gImNsaWNrIikgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgaWYgKGUud2hpY2gpICByZXR1cm4gKGUud2hpY2ggPT0gMyk7CiAgICAgICAgICAgICAgICBpZiAoZS5idXR0b24pIHJldHVybiAoZS5idXR0b24gPT0gMik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGdldENsb3Nlc3RBbmNob3IgPSBmdW5jdGlvbigkZWxlbWVudCkgewogICAgICAgICAgICAgICAgaWYgKCRlbGVtZW50LmlzKCJpbWciKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkZWxlbWVudFswXTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgY2xvc2VzdCA9ICRlbGVtZW50LmNsb3Nlc3QoImEsdGFibGUiKTsKICAgICAgICAgICAgICAgIGlmIChjbG9zZXN0Lmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBjbG9zZXN0WzBdOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgaGFuZGxlciA9IGZ1bmN0aW9uIChlZCwgZSwgZm9jdXNlZEVsKSB7CiAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9jdXNlZEVsOiBmb2N1c2VkRWwsCiAgICAgICAgICAgICAgICAgICAgICAgIGZvY3VzZWROb2RlTmFtZTogZm9jdXNlZEVsLm5vZGVOYW1lICYmIGZvY3VzZWRFbC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLAogICAgICAgICAgICAgICAgICAgICAgICBlZDogZWQsCiAgICAgICAgICAgICAgICAgICAgICAgIGU6IGUKICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgdmFyIGNvbnRhaW5lckVsID0gZ2V0Q2xvc2VzdEFuY2hvcigkKGZvY3VzZWRFbCkpOwogICAgICAgICAgICAgICAgZGF0YS5jb250YWluZXJFbCA9IGNvbnRhaW5lckVsOwoKICAgICAgICAgICAgICAgIEFKUy50cmlnZ2VyKCJ1c2VyLWJsdXJyZWQtcnRlLWVsZW1lbnQiLCBkYXRhKTsKICAgICAgICAgICAgICAgIGlmIChjb250YWluZXJFbCAmJiAhaXNSaWdodENsaWNrKGUpICYmICFpc1BhbmVsU2hvd2luZygpKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGhhbmRsZXJzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyc1tpXS5jYW5IYW5kbGVFbGVtZW50KCQoY29udGFpbmVyRWwpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQUpTLmxvZygiUHJvcGVydHlQYW5lbC5jcmVhdGU6IENyZWF0aW5nIGEgcGFuZWwgZm9yOiAiICsgaGFuZGxlcnNbaV0ubmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlcnNbaV0uaGFuZGxlKGRhdGEpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICBpc1BhbmVsU2hvd2luZyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiAhIUFKUy5Db25mbHVlbmNlLlByb3BlcnR5UGFuZWwuY3VycmVudDsKICAgICAgICAgICAgfTsKICAgICAgICAgICAgLy90aGlzIGdldHMgYXJvdW5kIGFuIGllIGJ1ZywgaWUgZG9lcyBub3Qgc2VlbSB0byBmaXJlIHRoZSBvbmNsaWNrIGV2ZW50IGlmIGEgc2VsZWN0aW9uIGhhcyBiZWVuIGFkZGVkIHRvIGFuIGVsZW1lbnQuCiAgICAgICAgICAgIGlmKHRpbnltY2UuaXNJRSkgewogICAgICAgICAgICAgICAgZWQub25Nb3VzZURvd24uYWRkKGZ1bmN0aW9uKGVkLCBlKSB7CiAgICAgICAgICAgICAgICAvL2F2b2lkIG1lbW9yeSBsZWFrcyBraWxsIGFueSBwcmV2aW91cyBib3VuZCBldmVudHMKICAgICAgICAgICAgICAgIC8vdXNpbmcganF1ZXJ5IHRvIGhvcGVmdWxseSBhdm9pZCBpbnRlcmFjdGluZyB3aXRoIGFueSBlZGl0b3IgZXZlCiAgICAgICAgICAgICAgICBBSlMuJChib3VuZEVsZW1lbnQpLnVuYmluZCgnbW91c2V1cCcpOwogICAgICAgICAgICAgICAgICAgIGJvdW5kRWxlbWVudCA9IGUudGFyZ2V0OwogICAgICAgICAgICAgICAgICAgIGlmKGJvdW5kRWxlbWVudC5ub2RlTmFtZSA9PSAiSU1HIikgewogICAgICAgICAgICAgICAgICAgICAgICBBSlMuJChib3VuZEVsZW1lbnQpLmJpbmQoJ21vdXNldXAnLGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcihlZCwgZSwgZS50YXJnZXQpOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZWQub25DbGljay5hZGQoZnVuY3Rpb24oZWQsIGUpIHsKICAgICAgICAgICAgICAgIGhhbmRsZXIoZWQsIGUsIGUudGFyZ2V0KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGVkLm9uS2V5VXAuYWRkVG9Ub3AoZnVuY3Rpb24gKGVkLGUsbykgewogICAgICAgICAgICAgICAgaWYgKGUua2V5Q29kZSA9PT0gMjcpIHJldHVybjsgLy8gaWdub3JlIGVzYywgaXQncyBoYW5kbGVkIGJ5IGtleWRvd24gbGlzdGVuZXIKICAgICAgICAgICAgICAgIGhhbmRsZXIoZWQsIGUsIGVkLnNlbGVjdGlvbi5nZXROb2RlKCkpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIEFKUy5iaW5kKCJ1c2VyLWJsdXJyZWQtcnRlLWVsZW1lbnQiLCBmdW5jdGlvbiAoZSwgZGF0YSkgewogICAgICAgICAgICAgICAgaWYgKGlzUGFuZWxTaG93aW5nKCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIUFKUy5Db25mbHVlbmNlLlByb3BlcnR5UGFuZWwuY3VycmVudC5oYXNBbmNob3JDaGFuZ2VkKGRhdGEuY29udGFpbmVyRWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEFKUy5Db25mbHVlbmNlLlByb3BlcnR5UGFuZWwuZGVzdHJveSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIEFKUy5iaW5kKCJjcmVhdGVkLnByb3BlcnR5LXBhbmVsIiwgZnVuY3Rpb24gKGUsIGRhdGEpIHsKICAgICAgICAgICAgICAgIEFKUy5FZGl0b3IuQWRhcHRlci5iaW5kU2Nyb2xsKCJwcm9wZXJ0eS1wYW5lbCIsIGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgICAgICAgICAgQUpTLkNvbmZsdWVuY2UuUHJvcGVydHlQYW5lbC5kZXN0cm95KCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIEFKUy4kKGVkLmdldERvYygpKS5iaW5kKCJrZXlkb3duLnByb3BlcnR5LXBhbmVsLmVzY2FwZSIsIGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGUua2V5Q29kZSA9PT0gMjcgJiYgaXNQYW5lbFNob3dpbmcoKSkgeyAvLyBlc2Mga2V5CiAgICAgICAgICAgICAgICAgICAgICAgIEFKUy5Db25mbHVlbmNlLlByb3BlcnR5UGFuZWwuZGVzdHJveSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgQUpTLmJpbmQoImRlc3Ryb3llZC5wcm9wZXJ0eS1wYW5lbCIsIGZ1bmN0aW9uIChlLCBkYXRhKSB7CiAgICAgICAgICAgICAgICBBSlMuRWRpdG9yLkFkYXB0ZXIudW5iaW5kU2Nyb2xsKCJwcm9wZXJ0eS1wYW5lbCIpOwogICAgICAgICAgICAgICAgQUpTLiQoZWQuZ2V0RG9jKCkpLnVuYmluZCgia2V5ZG93bi5wcm9wZXJ0eS1wYW5lbC5lc2NhcGUiKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0SW5mbyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgbG9uZ25hbWUgOiAnSW1hZ2UgYW5kIExpbmsgUHJvcGVydHkgUGFuZWxzJywKICAgICAgICAgICAgICAgIGF1dGhvciA6ICdBdGxhc3NpYW4nLAogICAgICAgICAgICAgICAgYXV0aG9ydXJsIDogJ2h0dHA6Ly93d3cuYXRsYXNzaWFuLmNvbS8nLAogICAgICAgICAgICAgICAgdmVyc2lvbiA6IHRpbnltY2UubWFqb3JWZXJzaW9uICsgIi4iICsgdGlueW1jZS5taW5vclZlcnNpb24KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9KTsKCiAgICAvLyBSZWdpc3RlciBwbHVnaW4KICAgIHRpbnltY2UuUGx1Z2luTWFuYWdlci5hZGQoJ3Byb3BlcnR5cGFuZWwnLCB0aW55bWNlLnBsdWdpbnMuUHJvcGVydHlQYW5lbCk7Cn0pKEFKUy4kKTsKCihmdW5jdGlvbigkKSB7CiAgICAvLyBLZWVwIGEgY291bnQgb2YgdGhlIG51bWJlciBvZiBwYW5lbHMgb3BlbmVkLCBzbyB0aGUgIkdvdG8gbG9jYXRpb24iIGJ1dHRvbiBhbHdheXMgb3BlbnMgdGhlIGxpbmsgbG9jYXRpb24gaW4gYQogICAgLy8gbmV3IG5hbWVkIHdpbmRvdwogICAgdmFyIGxpbmtQYW5lbENvdW50ZXIgPSAwOwoKICAgIEFKUy5Db25mbHVlbmNlLlByb3BlcnR5UGFuZWwuTGluayA9IHsKICAgICAgICBuYW1lIDogImxpbmsiLAoKICAgICAgICBjYW5IYW5kbGVFbGVtZW50IDogZnVuY3Rpb24gKCRlbGVtZW50KSB7CiAgICAgICAgICAgIHJldHVybiAkZWxlbWVudC5pcygiYSIpOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZSA6IGZ1bmN0aW9uKGRhdGEpIHsKICAgICAgICAgICAgdmFyIGxpbmsgPSBkYXRhLmNvbnRhaW5lckVsOwoKICAgICAgICAgICAgdmFyIGVkID0gZGF0YS5lZCwKICAgICAgICAgICAgICAgIGdldExhbmcgPSBmdW5jdGlvbihrZXkpIHsgcmV0dXJuIEFKUy5FZGl0b3IuQWRhcHRlci5nZXRFZGl0b3IoKS5nZXRMYW5nKGtleSk7IH0sCiAgICAgICAgICAgICAgICBidXR0b25zID0gW3sKICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICJsaW5rLXByb3BlcnR5LXBhbmVsLWdvdG8tYnV0dG9uIiwKICAgICAgICAgICAgICAgICAgICB0ZXh0OiBnZXRMYW5nKCJwcm9wZXJ0eXBhbmVsLmxpbmtzX2dvdG8iKSwKICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiBsaW5rLmhyZWYsCiAgICAgICAgICAgICAgICAgICAgaHJlZjogbGluay5ocmVmLAogICAgICAgICAgICAgICAgICAgIGNsaWNrOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEFKUy5Db25mbHVlbmNlLlByb3BlcnR5UGFuZWwuZGVzdHJveSgpOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2l2ZSB0aGUgd2luZG93IGEgbmFtZSB0byBoZWxwIHRlc3RpbmcsIGJ1dCBtYWtlIHN1cmUgdGhlIG5hbWUgaXMgdW5pcXVlLgogICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RlOiBJRSBkb2Vzbid0IGFsbG93IG5hbWVkIHdpbmRvd3M7IGp1c3Qgb3BlbiBhbiB1bm5hbWVkIG9uZS4KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHdpbmRvd05hbWUgPSB0aW55bWNlLmlzSUUgPyAiX2JsYW5rIiA6ICJjb25mbHVlbmNlLWdvdG8tbGluay0iICsgQUpTLnBhcmFtcy5wYWdlSWQgKyAiLSIgKyBsaW5rUGFuZWxDb3VudGVyOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWFpbHRvIGxpbmtzIGluIElFIGNhbiByZXR1cm4gbnVsbCBzb21ldGltZXMgZm9yIHdpbmRvdy5vcGVuCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlZSBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM1MzY2NTEoVlMuODUpLmFzcHgKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHdpbiA9IHdpbmRvdy5vcGVuKGxpbmsuaHJlZiwgd2luZG93TmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3aW4pIHdpbi5mb2N1cygpOwoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LCB7CiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAibGluay1wcm9wZXJ0eS1wYW5lbC1lZGl0LWJ1dHRvbiIsCiAgICAgICAgICAgICAgICAgICAgdGV4dDogZ2V0TGFuZygicHJvcGVydHlwYW5lbC5saW5rc19lZGl0IiksCiAgICAgICAgICAgICAgICAgICAgdG9vbHRpcDogZ2V0TGFuZygicHJvcGVydHlwYW5lbC5saW5rc19lZGl0X3Rvb2x0aXAiKSwKICAgICAgICAgICAgICAgICAgICBjbGljazogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICBBSlMuQ29uZmx1ZW5jZS5Qcm9wZXJ0eVBhbmVsLmRlc3Ryb3koKTsKICAgICAgICAgICAgICAgICAgICAgICAgZWQuc2VsZWN0aW9uLnNlbGVjdChsaW5rKTsKICAgICAgICAgICAgICAgICAgICAgICAgQUpTLkVkaXRvci5MaW5rQnJvd3Nlci5vcGVuKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwgewogICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogImxpbmstcHJvcGVydHktcGFuZWwtdW5saW5rLWJ1dHRvbiIsCiAgICAgICAgICAgICAgICAgICAgdGV4dDogZ2V0TGFuZygicHJvcGVydHlwYW5lbC5saW5rc191bmxpbmsiKSwKICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiBnZXRMYW5nKCJwcm9wZXJ0eXBhbmVsLmxpbmtzX3VubGlua190b29sdGlwIiksCiAgICAgICAgICAgICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgQUpTLkNvbmZsdWVuY2UuUHJvcGVydHlQYW5lbC5kZXN0cm95KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGVkLmV4ZWNDb21tYW5kKCJtY2VDb25mVW5saW5rIiwgZmFsc2UsIGxpbmspOwogICAgICAgICAgICAgICAgICAgICAgICBlZC5mb2N1cygpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH1dOwoKICAgICAgICAgICAgQUpTLkNvbmZsdWVuY2UuUHJvcGVydHlQYW5lbC5jcmVhdGVGcm9tQnV0dG9uTW9kZWwodGhpcy5uYW1lLCBsaW5rLCBidXR0b25zKTsKCiAgICAgICAgICAgIGxpbmtQYW5lbENvdW50ZXIrKzsKCiAgICAgICAgICAgIC8vIERvbid0IGZvbGxvdyB0aGUgbGluawogICAgICAgICAgICBkYXRhLmUucHJldmVudERlZmF1bHQoKTsKICAgICAgICB9CiAgICB9OwogICAgQUpTLnRyaWdnZXIoImFkZC1oYW5kbGVyLnByb3BlcnR5LXBhbmVsIiwgQUpTLkNvbmZsdWVuY2UuUHJvcGVydHlQYW5lbC5MaW5rKTsKfSkoQUpTLiQpOwoKKGZ1bmN0aW9uKCQpIHsKCiAgICAvKioKICAgICAqIFVwZGF0ZSB0aGUgaW1hZ2UgZWxlbWVudCB0byBtYXRjaCB0aGUgSW1hZ2VQcm9wZXJ0aWVzIHBhc3NlZCBpbiwgcmVsb2NhdGUgdGhlIHByb3BlcnR5IHBhbmVsIHRvIG1hdGNoIHRoZQogICAgICogcmVzaXplZCBpbWFnZSwgYW5kIGNsZWFudXAgYW55IGltYWdlLXNlbGVjdGlvbiBoYW5kbGVzLgogICAgICovCiAgICB2YXIgdXBkYXRlSW1hZ2VFbGVtZW50ID0gZnVuY3Rpb24gKGltYWdlUHJvcHMpIHsKICAgICAgICB2YXIgcHBhbmVsID0gQUpTLkNvbmZsdWVuY2UuUHJvcGVydHlQYW5lbC5jdXJyZW50LAogICAgICAgICAgICAkaW1nID0gJChwcGFuZWwuYW5jaG9yKSwKICAgICAgICAgICAgb2xkU3JjID0gJGltZy5hdHRyKCJzcmMiKSwKICAgICAgICAgICAgb2xkSGVpZ2h0ID0gJGltZy5oZWlnaHQoKTsKCiAgICAgICAgLy8gVHVybiBvZmYgc2Nyb2xsIGJpbmRpbmcsIGluIGNhc2UgYW4gaW1nIHJlc2l6ZSBjYXVzZXMgYSBzY3JvbGwgZXZlbnQsIGFuZCByZWJpbmQgYWZ0ZXIgdGhlIHJlc2l6ZS4KICAgICAgICBwcGFuZWwudXBkYXRpbmcgPSB0cnVlOwogICAgICAgIHZhciByZWJpbmRBbmRTbmFwID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICBwcGFuZWwudXBkYXRpbmcgPSBmYWxzZTsKICAgICAgICAgICAgcHBhbmVsLnNuYXBUb0VsZW1lbnQoewogICAgICAgICAgICAgICAgYW5pbWF0ZTogdHJ1ZSwKICAgICAgICAgICAgICAgIGFuaW1hdGVEdXJhdGlvbjogMTAwCiAgICAgICAgICAgIH0pOwogICAgICAgIH07CgogICAgICAgIHRpbnltY2UuY29uZmx1ZW5jZS5JbWFnZVV0aWxzLnVwZGF0ZUltYWdlRWxlbWVudCgkaW1nLCBpbWFnZVByb3BzKTsKICAgICAgICBpZiAodGlueW1jZS5pc0dlY2tvKSB7CiAgICAgICAgICAgIC8vIFJlcGFpbnQgdG8gY2xlYXIgdGhlIGltYWdlIGhhbmRsZXMgZnJvbSB0aGVpciBvbGQgcG9zaXRpb25zLgogICAgICAgICAgICBBSlMuRWRpdG9yLkFkYXB0ZXIuZ2V0RWRpdG9yKCkuZXhlY0NvbW1hbmQoJ21jZVJlcGFpbnQnLCBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaW1hZ2VQcm9wcy5zcmMgIT0gb2xkU3JjKSB7CiAgICAgICAgICAgIC8vIEltYWdlIHNvdXJjZSBjaGFuZ2VkIC0gbWF5IGhhdmUgdG8gd2FpdCBmb3IgaGVpZ2h0IHRvIGNoYW5nZSB0byBzbmFwVG9FbGVtZW50CiAgICAgICAgICAgIHZhciBzbmFwSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHZhciBuZXdIZWlnaHQgPSAkaW1nLmhlaWdodCgpOwogICAgICAgICAgICAgICAgaWYgKG5ld0hlaWdodCAhPSBvbGRIZWlnaHQpIHsKICAgICAgICAgICAgICAgICAgICBBSlMubG9nKCJ1cGRhdGVJbWFnZUVsZW1lbnQgOiBoZWlnaHQgY2hhbmdlZCBhZnRlciBpbWFnZSBzcmMgY2hhbmdlIC0gIiArIG9sZEhlaWdodCArICIgdG8gIiArIG5ld0hlaWdodCk7CiAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHNuYXBJbnRlcnZhbCk7CiAgICAgICAgICAgICAgICAgICAgc25hcEludGVydmFsID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICByZWJpbmRBbmRTbmFwKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIDEwKTsKICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIGlmIChzbmFwSW50ZXJ2YWwpIHsKICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoc25hcEludGVydmFsKTsKICAgICAgICAgICAgICAgICAgICBzbmFwSW50ZXJ2YWwgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIHJlYmluZEFuZFNuYXAoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgMTAwMCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmViaW5kQW5kU25hcCgpOwogICAgICAgIH0KICAgIH0sCgogICAgLyoqCiAgICAgKiBVbnNlbGVjdHMgb3RoZXIgc2l6ZS1yZWxhdGVkIGJ1dHRvbnMgYW5kIHVuZmxhZ3MgdGh1bWJuYWlsIGlmIGFueXRoaW5nIGJ1dCB0aGUgdGh1bWJuYWlsIGJ1dHRvbiB3YXMgcHJlc3NlZC4KICAgICAqLwogICAgY2xlYXJPdGhlckltYWdlU2l6ZUJ1dHRvbnMgPSBmdW5jdGlvbiAoc2VsZWN0ZWRCdXR0b24pIHsKICAgICAgICBzZWxlY3RlZEJ1dHRvbiA9ICQoc2VsZWN0ZWRCdXR0b24pOwogICAgICAgIHZhciBidXR0b25zID0gc2VsZWN0ZWRCdXR0b24ucGFyZW50KCkuZmluZCgiLmltYWdlLXNpemUtc21hbGwsIC5pbWFnZS1zaXplLW1lZGl1bSwgLmltYWdlLXNpemUtbGFyZ2UsIC5pbWFnZS1zaXplLW9yaWdpbmFsIik7CiAgICAgICAgYnV0dG9ucy5yZW1vdmVDbGFzcygic2VsZWN0ZWQiKTsKICAgICAgICBzZWxlY3RlZEJ1dHRvbi5hZGRDbGFzcygic2VsZWN0ZWQiKTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBQaXhlbCBzaXplcyBmb3IgaW1hZ2UgcmVzaXplIGJ1dHRvbnMuCiAgICAgKi8KICAgIHNpemVzID0gewogICAgICAgIHNtYWxsIDogMTAwLAogICAgICAgIG1lZGl1bSA6IDIwMCwKICAgICAgICBsYXJnZSA6IDMwMAogICAgfTsKCiAgICBBSlMuQ29uZmx1ZW5jZS5Qcm9wZXJ0eVBhbmVsLkltYWdlID0gewogICAgICAgIG5hbWUgOiAiaW1hZ2UiLAoKICAgICAgICBjYW5IYW5kbGVFbGVtZW50IDogZnVuY3Rpb24gKCRlbGVtZW50KSB7CiAgICAgICAgICAgcmV0dXJuICgkZWxlbWVudC5pcygiaW1nIikgJiYgISRlbGVtZW50Lmhhc0NsYXNzKCJlZGl0b3ItYm9keWxlc3MtbWFjcm8iKSk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlIDogZnVuY3Rpb24gKGRhdGEpIHsKICAgICAgICAgICAgdmFyIGltZyA9IGRhdGEuY29udGFpbmVyRWwsCiAgICAgICAgICAgICAgICAkaW1nID0gJChpbWcpLAogICAgICAgICAgICAgICAgaW1hZ2VQcm9wcyA9IHRpbnltY2UuY29uZmx1ZW5jZS5JbWFnZVByb3BlcnRpZXMoaW1nKTsKICAgICAgICAgICAgaWYgKCFpbWFnZVByb3BzKSB7CiAgICAgICAgICAgICAgICByZXR1cm47ICAgICAgICAgLy8gbm90IGEgInByb3BlciIgaW1hZ2UsIGUuZy4gYW4gZW1vdGljb24KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGdldExhbmcgPSBmdW5jdGlvbihrZXkpIHsgcmV0dXJuIEFKUy5FZGl0b3IuQWRhcHRlci5nZXRFZGl0b3IoKS5nZXRMYW5nKGtleSk7IH0sCiAgICAgICAgICAgICAgICBpc1RodW1ibmFpbGFibGUgPSAhdGlueW1jZS5jb25mbHVlbmNlLkltYWdlVXRpbHMuaXNSZW1vdGVJbWcoaW1hZ2VQcm9wcy5kZXN0aW5hdGlvbiksCiAgICAgICAgICAgICAgICBtYXhEaW1lbnNpb24gPSAoJGltZy53aWR0aCgpID49ICRpbWcuaGVpZ2h0KCkpID8gIndpZHRoIiA6ICJoZWlnaHQiLAogICAgICAgICAgICAgICAgbWluRGltZW5zaW9uID0gKG1heERpbWVuc2lvbiA9PSAiaGVpZ2h0IikgPyAid2lkdGgiIDogImhlaWdodCIsCiAgICAgICAgICAgICAgICBpbWFnZVNpemVCdXR0b24gPSBmdW5jdGlvbiAoc2l6ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogImltYWdlLXNpemUtIiArIHNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IGdldExhbmcoInByb3BlcnR5cGFuZWwuaW1hZ2VzXyIgKyBzaXplKSwKICAgICAgICAgICAgICAgICAgICAgICAgdG9vbHRpcDogZ2V0TGFuZygicHJvcGVydHlwYW5lbC5pbWFnZXNfIiArIHNpemUgKyAiX3Rvb2x0aXAiKSwKICAgICAgICAgICAgICAgICAgICAgICAgY2xpY2sgOiBmdW5jdGlvbiAoYSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGltYWdlUHJvcHNbbWluRGltZW5zaW9uXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlUHJvcHNbbWF4RGltZW5zaW9uXSA9IHNpemVzW3NpemVdOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlUHJvcHMudGh1bWJuYWlsID0gKHNpemUgIT0gImxhcmdlIikgPyBpc1RodW1ibmFpbGFibGUgOiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyT3RoZXJJbWFnZVNpemVCdXR0b25zKGEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlSW1hZ2VFbGVtZW50KGltYWdlUHJvcHMpOwogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDogaW1hZ2VQcm9wc1ttYXhEaW1lbnNpb25dID09IHNpemVzW3NpemVdCiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBidXR0b25zID0gWwogICAgICAgICAgICAgICAgICAgIGltYWdlU2l6ZUJ1dHRvbigic21hbGwiKSwKICAgICAgICAgICAgICAgICAgICBpbWFnZVNpemVCdXR0b24oIm1lZGl1bSIpLAogICAgICAgICAgICAgICAgICAgIGltYWdlU2l6ZUJ1dHRvbigibGFyZ2UiKSwKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogImltYWdlLXNpemUtb3JpZ2luYWwiLAogICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OiBnZXRMYW5nKCJwcm9wZXJ0eXBhbmVsLmltYWdlc19vcmlnaW5hbCIpLAogICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiBnZXRMYW5nKCJwcm9wZXJ0eXBhbmVsLmltYWdlc19vcmlnaW5hbF90b29sdGlwIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGNsaWNrOiBmdW5jdGlvbiAoYSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGltYWdlUHJvcHMud2lkdGg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgaW1hZ2VQcm9wcy5oZWlnaHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZVByb3BzLnRodW1ibmFpbCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJPdGhlckltYWdlU2l6ZUJ1dHRvbnMoYSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVJbWFnZUVsZW1lbnQoaW1hZ2VQcm9wcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiAhaW1hZ2VQcm9wcy53aWR0aCAmJiAhaW1hZ2VQcm9wcy5oZWlnaHQgJiYgIWltYWdlUHJvcHMudGh1bWJuYWlsCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBudWxsLCAgIC8vIHNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAiaW1hZ2UtYm9yZGVyLXRvZ2dsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IGdldExhbmcoInByb3BlcnR5cGFuZWwuaW1hZ2VzX2JvcmRlciIpLAogICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiBnZXRMYW5nKCJwcm9wZXJ0eXBhbmVsLmltYWdlc19ib3JkZXJfdG9vbHRpcCIpLAogICAgICAgICAgICAgICAgICAgICAgICBjbGljazogZnVuY3Rpb24gKGEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlUHJvcHMuYm9yZGVyID0gKyFpbWFnZVByb3BzLmJvcmRlciB8fCBmYWxzZTsgICAvLyBlaXRoZXIgMSBvciBmYWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJChhKS50b2dnbGVDbGFzcygic2VsZWN0ZWQiLCBpbWFnZVByb3BzLmJvcmRlcik7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlSW1hZ2VFbGVtZW50KGltYWdlUHJvcHMpOwogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDogKGltYWdlUHJvcHMuYm9yZGVyIHx8IGltYWdlUHJvcHMuYm9yZGVyID09IDApCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgXTsKICAgICAgICAgICAgQUpTLkNvbmZsdWVuY2UuUHJvcGVydHlQYW5lbC5jcmVhdGVGcm9tQnV0dG9uTW9kZWwodGhpcy5uYW1lLCBpbWcsIGJ1dHRvbnMsIHsgYW5jaG9ySWZyYW1lOiBBSlMuRWRpdG9yLkFkYXB0ZXIuZ2V0RWRpdG9yRnJhbWUoKSB9KTsKCiAgICAgICAgICAgIC8vIFN0b3JlIHRoZSBzdGF0ZSBvZiB0aGUgaW1hZ2Ugc28gaXQgY2FuIGJlIHVwZGF0ZWQgbGF0ZXIKICAgICAgICAgICAgQUpTLkNvbmZsdWVuY2UuUHJvcGVydHlQYW5lbC5jdXJyZW50LmltYWdlUHJvcHMgPSBpbWFnZVByb3BzOwogICAgICAgIH0KICAgIH07CiAgICBBSlMudHJpZ2dlcigiYWRkLWhhbmRsZXIucHJvcGVydHktcGFuZWwiLCBBSlMuQ29uZmx1ZW5jZS5Qcm9wZXJ0eVBhbmVsLkltYWdlKTsKfSkoQUpTLiQpOwovKgogKiBDb25mbHVlbmNlIEtleWJvYXJkIHNob3J0Y3V0cyBmb3IgdGhlIGVkaXRvcgogKi8KdGlueW1jZS5jb25mbHVlbmNlLmtleWJvYXJkc2hvcnRjdXRzID0gKGZ1bmN0aW9uKCQpIHsgcmV0dXJuIHsKICAgIHNhdmVQYWdlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgdGhpcy5zZXR0aW5ncy5zYXZlX29uc2F2ZWNhbGxiYWNrICYmIHRoaXMuc2V0dGluZ3Muc2F2ZV9vbnNhdmVjYWxsYmFjaygpOyAvL0NPTkYtMjExMjgKICAgICAgICAkKCIuc3VibWl0LWJ1dHRvbnMgaW5wdXRbbmFtZT0nY29uZmlybSddIikuZXEoMCkuY2xpY2soKTsKICAgIH0sCgogICAgb3BlblNob3J0Y3V0RGlhbG9nOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgJCgiI2tleWJvYXJkLXNob3J0Y3V0cy1saW5rIikuY2xpY2soKTsKICAgIH0KfTt9KShBSlMuJCk7CgooZnVuY3Rpb24oJCkgewoJdGlueW1jZS5jcmVhdGUoJ3RpbnltY2UucGx1Z2lucy5LZXlib2FyZFNob3J0Y3V0c1BsdWdpbicsIHsKICAgICAgICBpbml0IDogZnVuY3Rpb24oZWQpIHsKICAgICAgICAgICAgQUpTLmxvZygiSW5pdCBLZXlib2FyZCBzaG9ydGN1dHMgcGx1Z2luIik7CiAgICAgICAgICAgIGVkLmFkZENvbW1hbmQoIm1jZUNvbmZTYXZlUGFnZSIsIHRpbnltY2UuY29uZmx1ZW5jZS5rZXlib2FyZHNob3J0Y3V0cy5zYXZlUGFnZSk7CiAgICAgICAgICAgIGVkLmFkZENvbW1hbmQoIm1jZUNvbmZTaG9ydGN1dERpYWxvZyIsIHRpbnltY2UuY29uZmx1ZW5jZS5rZXlib2FyZHNob3J0Y3V0cy5vcGVuU2hvcnRjdXREaWFsb2cpOwoKICAgICAgICAgICAgZWQuYWRkQnV0dG9uKCJjb25mc2hvcnRjdXRkaWFsb2ciLCB7dGl0bGUgOiAiY29uZmx1ZW5jZS5jb25mX3Nob3J0Y3V0c19oZWxwX2Rlc2MiLCBjbWQgOiAibWNlQ29uZlNob3J0Y3V0RGlhbG9nIiwgImNsYXNzIiA6ICJtY2VfY29uZl9rZXlib2FyZF9zaG9ydGN1dCJ9KTsKCiAgICAgICAgICAgIC8vIFNob3J0Y3V0IGtleXMKICAgICAgICAgICAgZWQuYWRkU2hvcnRjdXQoImN0cmwrbSIsIGVkLmdldExhbmcoImNvbmZsdWVuY2UuY29uZmltYWdlX2Rlc2MiKSwgIm1jZUNvbmZpbWFnZSIpOwogICAgICAgICAgICBlZC5hZGRTaG9ydGN1dCgiY3RybCtzaGlmdCthIiwgZWQuZ2V0TGFuZygiY29uZmx1ZW5jZS5jb25mX21hY3JvX2Jyb3dzZXJfZGVzYyIpLCAibWNlQ29uZk1hY3JvQnJvd3NlciIpOwogICAgICAgICAgICBlZC5hZGRTaG9ydGN1dCgiY3RybCtzaGlmdCtpIiwgZWQuZ2V0TGFuZygiaHR0cDovLzEwLjIwLjE2MC4xOTgvd2lraS9zL2VuLzIxNjYvMzQvMy41LjkvXy9kb3dubG9hZC9iYXRjaC9jb20uYXRsYXNzaWFuLmNvbmZsdWVuY2UudGlueW1jZXBsdWdpbjplZGl0b3ItcmVzb3VyY2VzL3RhYmxlLmRlc2MiKSwgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZWQuZXhlY0NvbW1hbmQoIm1jZUluc2VydFRhYmxlIiwgdHJ1ZSk7IC8vIG5lZWQgdG8gcGFzcyBpbiB0cnVlIHRvIG9wZW4gdGhlIHBvcHVwCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgZWQuYWRkU2hvcnRjdXQoImN0cmwrc2hpZnQrZiIsIGVkLmdldExhbmcoImh0dHA6Ly8xMC4yMC4xNjAuMTk4L3dpa2kvcy9lbi8yMTY2LzM0LzMuNS45L18vZG93bmxvYWQvYmF0Y2gvY29tLmF0bGFzc2lhbi5jb25mbHVlbmNlLnRpbnltY2VwbHVnaW46ZWRpdG9yLXJlc291cmNlcy9mdWxsc2NyZWVuLmRlc2MiKSwgIm1jZUZ1bGxTY3JlZW4iKTsKICAgICAgICAgICAgZWQuYWRkU2hvcnRjdXQoImN0cmwrc2hpZnQrYiIsIGVkLmdldExhbmcoImFkdmFuY2VkLmJ1bGxpc3RfZGVzYyIpLCAiSW5zZXJ0VW5vcmRlcmVkTGlzdCIpOwogICAgICAgICAgICBlZC5hZGRTaG9ydGN1dCgiY3RybCtzaGlmdCtuIiwgZWQuZ2V0TGFuZygiYWR2YW5jZWQubnVtbGlzdF9kZXNjIiksICJJbnNlcnRPcmRlcmVkTGlzdCIpOwogICAgICAgICAgICBlZC5hZGRTaG9ydGN1dCgiY3RybCtzaGlmdCtzIiwgZWQuZ2V0TGFuZygiYWR2YW5jZWQuc3RyaWtldHJvdWdoX2Rlc2MiKSwgIlN0cmlrZXRocm91Z2giKTsKCiAgICAgICAgICAgIGVkLmFkZFNob3J0Y3V0KCJjdHJsK3NoaWZ0K2MiLCBlZC5nZXRMYW5nKCJ0YWJsZS5jb3B5X3Jvd19kZXNjIiksICJtY2VUYWJsZUNvcHlSb3ciKTsKICAgICAgICAgICAgZWQuYWRkU2hvcnRjdXQoImN0cmwrc2hpZnQreCIsIGVkLmdldExhbmcoInRhYmxlLmN1dF9yb3dfZGVzYyIpLCAibWNlVGFibGVDdXRSb3ciKTsKICAgICAgICAgICAgZWQuYWRkU2hvcnRjdXQoImN0cmwrc2hpZnQrdiIsIGVkLmdldExhbmcoInRhYmxlLnBhc3RlX3Jvd19iZWZvcmVfZGVzYyIpLCAibWNlVGFibGVQYXN0ZVJvd0JlZm9yZSIpOwogICAgICAgICAgICBlZC5hZGRTaG9ydGN1dCgnY3RybCtzJywgJycsICdtY2VDb25mU2F2ZVBhZ2UnKTsKICAgICAgICAgICAgZWQuYWRkU2hvcnRjdXQoJ2N0cmwrYWx0K3EnLCAnJywgWydGb3JtYXRCbG9jaycsIGZhbHNlLCAnbWFjcm9fcXVvdGUnXSk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0SW5mbyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgIGxvbmduYW1lIDogIkNvbmZsdWVuY2UgS2V5Ym9hcmQgU2hvcnRjdXRzIFBsdWdpbiIsCiAgICAgICAgICAgICAgICBhdXRob3IgOiAiQXRsYXNzaWFuIiwKICAgICAgICAgICAgICAgIGF1dGhvcnVybCA6ICJodHRwOi8vd3d3LmF0bGFzc2lhbi5jb20vIiwKICAgICAgICAgICAgICAgIHZlcnNpb24gOiB0aW55bWNlLm1ham9yVmVyc2lvbiArICIuIiArIHRpbnltY2UubWlub3JWZXJzaW9uCiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfSk7CgogICAgLy8gUmVnaXN0ZXIgcGx1Z2luCiAgICB0aW55bWNlLlBsdWdpbk1hbmFnZXIuYWRkKCJrZXlib2FyZHNob3J0Y3V0cyIsIHRpbnltY2UucGx1Z2lucy5LZXlib2FyZFNob3J0Y3V0c1BsdWdpbik7Cn0pKCk7CgovKgogIERPTSBSYW5nZXMgZm9yIEludGVybmV0IEV4cGxvcmVyIChtMikKCiAgQ29weXJpZ2h0IChjKSAyMDA5IFRpbSBDYW1lcm9uIFJ5YW4KICBSZWxlYXNlZCB1bmRlciB0aGUgTUlUL1ggTGljZW5zZQogKi8KCi8qCiAgUmFuZ2UgcmVmZXJlbmNlOgogICAgaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItVHJhdmVyc2FsLVJhbmdlL3Jhbmdlcy5odG1sCiAgICBodHRwOi8vbXhyLm1vemlsbGEub3JnL21vemlsbGEtY2VudHJhbC9zb3VyY2UvY29udGVudC9iYXNlL3NyYy9uc1JhbmdlLmNwcAogICAgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvRW4vRE9NOlJhbmdlCiAgU2VsZWN0aW9uIHJlZmVyZW5jZToKICAgIGh0dHA6Ly90cmFjLndlYmtpdC5vcmcvYnJvd3Nlci90cnVuay9XZWJDb3JlL3BhZ2UvRE9NU2VsZWN0aW9uLmNwcAogIFRleHRSYW5nZSByZWZlcmVuY2U6CiAgICBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM1MzU4NzIuYXNweAogIE90aGVyIGxpbmtzOgogICAgaHR0cDovL2pvcmdlbmhvcnN0aW5rLm5sL3Rlc3QvamF2YXNjcmlwdC9yYW5nZS9yYW5nZS5qcwogICAgaHR0cDovL2pvcmdlbmhvcnN0aW5rLm5sLzIwMDYvMDcvMDUvZG9tLXJhbmdlLWltcGxlbWVudGF0aW9uLWluLWVjbWFzY3JpcHQtY29tcGxldGVkLwogICAgaHR0cDovL2R5bGFuc2NoaWVtYW5uLmNvbS9hcnRpY2xlcy9kb20yUmFuZ2UvZG9tMlJhbmdlRXhhbXBsZXMuaHRtbAoqLwoKLy9bVE9ET10gYmV0dGVyIGV4Y2VwdGlvbiBzdXBwb3J0CgooZnVuY3Rpb24gKCkgewkvLyBzYW5kYm94CgovKgogIERPTSBmdW5jdGlvbnMKICovCgp2YXIgRE9NVXRpbHMgPSB7CglmaW5kQ2hpbGRQb3NpdGlvbjogZnVuY3Rpb24gKG5vZGUpIHsKCQlmb3IgKHZhciBpID0gMDsgbm9kZSA9IG5vZGUucHJldmlvdXNTaWJsaW5nOyBpKyspCgkJCWNvbnRpbnVlOwoJCXJldHVybiBpOwoJfSwKCWlzRGF0YU5vZGU6IGZ1bmN0aW9uIChub2RlKSB7CgkJcmV0dXJuIG5vZGUgJiYgbm9kZS5ub2RlVmFsdWUgIT09IG51bGwgJiYgbm9kZS5kYXRhICE9PSBudWxsOwoJfSwKCWlzQW5jZXN0b3JPZjogZnVuY3Rpb24gKHBhcmVudCwgbm9kZSkgewoJCXJldHVybiAhRE9NVXRpbHMuaXNEYXRhTm9kZShwYXJlbnQpICYmCgkJICAgIChwYXJlbnQuY29udGFpbnMoRE9NVXRpbHMuaXNEYXRhTm9kZShub2RlKSA/IG5vZGUucGFyZW50Tm9kZSA6IG5vZGUpIHx8CgkJICAgIG5vZGUucGFyZW50Tm9kZSA9PSBwYXJlbnQpOwoJfSwKCWlzQW5jZXN0b3JPclNlbGY6IGZ1bmN0aW9uIChyb290LCBub2RlKSB7CgkJcmV0dXJuIERPTVV0aWxzLmlzQW5jZXN0b3JPZihyb290LCBub2RlKSB8fCByb290ID09IG5vZGU7Cgl9LAoJZmluZENsb3Nlc3RBbmNlc3RvcjogZnVuY3Rpb24gKHJvb3QsIG5vZGUpIHsKCQlpZiAoRE9NVXRpbHMuaXNBbmNlc3Rvck9mKHJvb3QsIG5vZGUpKQoJCQl3aGlsZSAobm9kZSAmJiBub2RlLnBhcmVudE5vZGUgIT0gcm9vdCkKCQkJCW5vZGUgPSBub2RlLnBhcmVudE5vZGU7CgkJcmV0dXJuIG5vZGU7Cgl9LAoJZ2V0Tm9kZUxlbmd0aDogZnVuY3Rpb24gKG5vZGUpIHsKCQlyZXR1cm4gRE9NVXRpbHMuaXNEYXRhTm9kZShub2RlKSA/IG5vZGUubGVuZ3RoIDogbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDsKCX0sCglzcGxpdERhdGFOb2RlOiBmdW5jdGlvbiAobm9kZSwgb2Zmc2V0KSB7CgkJaWYgKCFET01VdGlscy5pc0RhdGFOb2RlKG5vZGUpKQoJCQlyZXR1cm4gZmFsc2U7CgkJdmFyIG5ld05vZGUgPSBub2RlLmNsb25lTm9kZShmYWxzZSk7CgkJbm9kZS5kZWxldGVEYXRhKG9mZnNldCwgbm9kZS5sZW5ndGgpOwoJCW5ld05vZGUuZGVsZXRlRGF0YSgwLCBvZmZzZXQpOwoJCW5vZGUucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobmV3Tm9kZSwgbm9kZS5uZXh0U2libGluZyk7Cgl9Cn07CgovKgogIFRleHQgUmFuZ2UgdXRpbGl0aWVzCiAgZnVuY3Rpb25zIHRvIHNpbXBsaWZ5IHRleHQgcmFuZ2UgbWFuaXB1bGF0aW9uIGluIGllCiAqLwoKdmFyIFRleHRSYW5nZVV0aWxzID0gewoJY29udmVydFRvRE9NUmFuZ2U6IGZ1bmN0aW9uICh0ZXh0UmFuZ2UsIGRvY3VtZW50KSB7CgkJZnVuY3Rpb24gYWRvcHRCb3VuZGFyeShkb21SYW5nZSwgdGV4dFJhbmdlLCBiU3RhcnQpIHsKCQkJLy8gaXRlcmF0ZSBiYWNrd2FyZHMgdGhyb3VnaCBwYXJlbnQgZWxlbWVudCB0byBmaW5kIGFuY2hvciBsb2NhdGlvbgoJCQl2YXIgY3Vyc29yTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKSwgY3Vyc29yID0gdGV4dFJhbmdlLmR1cGxpY2F0ZSgpOwoJCQljdXJzb3IuY29sbGFwc2UoYlN0YXJ0KTsKCQkJdmFyIHBhcmVudCA9IGN1cnNvci5wYXJlbnRFbGVtZW50KCk7CgkJCWRvIHsKCQkJCXBhcmVudC5pbnNlcnRCZWZvcmUoY3Vyc29yTm9kZSwgY3Vyc29yTm9kZS5wcmV2aW91c1NpYmxpbmcpOwoJCQkJY3Vyc29yLm1vdmVUb0VsZW1lbnRUZXh0KGN1cnNvck5vZGUpOwoJCQl9IHdoaWxlIChjdXJzb3IuY29tcGFyZUVuZFBvaW50cyhiU3RhcnQgPyAnU3RhcnRUb1N0YXJ0JyA6ICdTdGFydFRvRW5kJywgdGV4dFJhbmdlKSA+IDAgJiYgY3Vyc29yTm9kZS5wcmV2aW91c1NpYmxpbmcpOwoKCQkJLy8gd2hlbiB3ZSBleGNlZWQgb3IgbWVldCB0aGUgY3Vyc29yLCB3ZSd2ZSBmb3VuZCB0aGUgbm9kZQoJCQlpZiAoY3Vyc29yLmNvbXBhcmVFbmRQb2ludHMoYlN0YXJ0ID8gJ1N0YXJ0VG9TdGFydCcgOiAnU3RhcnRUb0VuZCcsIHRleHRSYW5nZSkgPT0gLTEgJiYgY3Vyc29yTm9kZS5uZXh0U2libGluZykgewoJCQkJLy8gZGF0YSBub2RlCgkJCQljdXJzb3Iuc2V0RW5kUG9pbnQoYlN0YXJ0ID8gJ0VuZFRvU3RhcnQnIDogJ0VuZFRvRW5kJywgdGV4dFJhbmdlKTsKCQkJCWRvbVJhbmdlW2JTdGFydCA/ICdzZXRTdGFydCcgOiAnc2V0RW5kJ10oY3Vyc29yTm9kZS5uZXh0U2libGluZywgY3Vyc29yLnRleHQubGVuZ3RoKTsKCQkJfSBlbHNlIHsKCQkJCS8vIGVsZW1lbnQKCQkJCWRvbVJhbmdlW2JTdGFydCA/ICdzZXRTdGFydEJlZm9yZScgOiAnc2V0RW5kQmVmb3JlJ10oY3Vyc29yTm9kZSk7CgkJCX0KCQkJY3Vyc29yTm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGN1cnNvck5vZGUpOwoJCX0KCQkvLyByZXR1cm4gYSBET00gcmFuZ2UKCQl2YXIgZG9tUmFuZ2UgPSBuZXcgRE9NUmFuZ2UoZG9jdW1lbnQpOwoJCWFkb3B0Qm91bmRhcnkoZG9tUmFuZ2UsIHRleHRSYW5nZSwgdHJ1ZSk7CgkJYWRvcHRCb3VuZGFyeShkb21SYW5nZSwgdGV4dFJhbmdlLCBmYWxzZSk7CgkJcmV0dXJuIGRvbVJhbmdlOwoJfSwKCgljb252ZXJ0RnJvbURPTVJhbmdlOiBmdW5jdGlvbiAoZG9tUmFuZ2UpIHsKCQlmdW5jdGlvbiBhZG9wdEVuZFBvaW50KHRleHRSYW5nZSwgZG9tUmFuZ2UsIGJTdGFydCkgewoJCQkvLyBmaW5kIGFuY2hvciBub2RlIGFuZCBvZmZzZXQKCQkJdmFyIGNvbnRhaW5lciA9IGRvbVJhbmdlW2JTdGFydCA/ICdzdGFydENvbnRhaW5lcicgOiAnZW5kQ29udGFpbmVyJ107CgkJCXZhciBvZmZzZXQgPSBkb21SYW5nZVtiU3RhcnQgPyAnc3RhcnRPZmZzZXQnIDogJ2VuZE9mZnNldCddLCB0ZXh0T2Zmc2V0ID0gMDsKCQkJdmFyIGFuY2hvck5vZGUgPSBET01VdGlscy5pc0RhdGFOb2RlKGNvbnRhaW5lcikgPyBjb250YWluZXIgOiBjb250YWluZXIuY2hpbGROb2Rlc1tvZmZzZXRdOwoJCQl2YXIgYW5jaG9yUGFyZW50ID0gRE9NVXRpbHMuaXNEYXRhTm9kZShjb250YWluZXIpID8gY29udGFpbmVyLnBhcmVudE5vZGUgOiBjb250YWluZXI7CgkJCS8vIHZpc2libGUgZGF0YSBub2RlcyBuZWVkIGEgdGV4dCBvZmZzZXQKCQkJaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PSAzIHx8IGNvbnRhaW5lci5ub2RlVHlwZSA9PSA0KQoJCQkJdGV4dE9mZnNldCA9IG9mZnNldDsKCgkJCS8vIGNyZWF0ZSBhIGN1cnNvciBlbGVtZW50IG5vZGUgdG8gcG9zaXRpb24gcmFuZ2UgKHNpbmNlIHdlIGNhbid0IHNlbGVjdCB0ZXh0IG5vZGVzKQoJCQl2YXIgY3Vyc29yTm9kZSA9IGRvbVJhbmdlLl9kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7CgkJCWFuY2hvclBhcmVudC5pbnNlcnRCZWZvcmUoY3Vyc29yTm9kZSwgYW5jaG9yTm9kZSk7CgkJCXZhciBjdXJzb3IgPSBkb21SYW5nZS5fZG9jdW1lbnQuYm9keS5jcmVhdGVUZXh0UmFuZ2UoKTsKCQkJY3Vyc29yLm1vdmVUb0VsZW1lbnRUZXh0KGN1cnNvck5vZGUpOwoJCQljdXJzb3JOb2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY3Vyc29yTm9kZSk7CgkJCS8vIG1vdmUgcmFuZ2UKCQkJdGV4dFJhbmdlLnNldEVuZFBvaW50KGJTdGFydCA/ICdTdGFydFRvU3RhcnQnIDogJ0VuZFRvU3RhcnQnLCBjdXJzb3IpOwoJCQl0ZXh0UmFuZ2VbYlN0YXJ0ID8gJ21vdmVTdGFydCcgOiAnbW92ZUVuZCddKCdjaGFyYWN0ZXInLCB0ZXh0T2Zmc2V0KTsKCQl9CgoJCS8vIHJldHVybiBhbiBJRSB0ZXh0IHJhbmdlCgkJdmFyIHRleHRSYW5nZSA9IGRvbVJhbmdlLl9kb2N1bWVudC5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpOwoJCWFkb3B0RW5kUG9pbnQodGV4dFJhbmdlLCBkb21SYW5nZSwgdHJ1ZSk7CgkJYWRvcHRFbmRQb2ludCh0ZXh0UmFuZ2UsIGRvbVJhbmdlLCBmYWxzZSk7CgkJcmV0dXJuIHRleHRSYW5nZTsKCX0KfTsKCi8qCiAgRE9NIFJhbmdlCiAqLwoKZnVuY3Rpb24gRE9NUmFuZ2UoZG9jdW1lbnQpIHsKCS8vIHNhdmUgZG9jdW1lbnQgcGFyYW1ldGVyCgl0aGlzLl9kb2N1bWVudCA9IGRvY3VtZW50OwoKCS8vIGluaXRpYWxpemUgcmFuZ2UKLy9bVE9ET10gdGhpcyBzaG91bGQgYmUgbG9jYXRlZCBhdCBkb2N1bWVudFswXSwgZG9jdW1lbnRbMF0KCXRoaXMuc3RhcnRDb250YWluZXIgPSB0aGlzLmVuZENvbnRhaW5lciA9IGRvY3VtZW50LmJvZHk7Cgl0aGlzLmVuZE9mZnNldCA9IERPTVV0aWxzLmdldE5vZGVMZW5ndGgoZG9jdW1lbnQuYm9keSk7Cn0KRE9NUmFuZ2UuU1RBUlRfVE9fU1RBUlQgPSAwOwpET01SYW5nZS5TVEFSVF9UT19FTkQgPSAxOwpET01SYW5nZS5FTkRfVE9fRU5EID0gMjsKRE9NUmFuZ2UuRU5EX1RPX1NUQVJUID0gMzsKCkRPTVJhbmdlLnByb3RvdHlwZSA9IHsKCS8vIHB1YmxpYyBwcm9wZXJ0aWVzCglzdGFydENvbnRhaW5lcjogbnVsbCwKCXN0YXJ0T2Zmc2V0OiAwLAoJZW5kQ29udGFpbmVyOiBudWxsLAoJZW5kT2Zmc2V0OiAwLAoJY29tbW9uQW5jZXN0b3JDb250YWluZXI6IG51bGwsCgljb2xsYXBzZWQ6IGZhbHNlLAoJLy8gcHJpdmF0ZSBwcm9wZXJ0aWVzCglfZG9jdW1lbnQ6IG51bGwsCgoJLy8gcHJpdmF0ZSBtZXRob2RzCglfcmVmcmVzaFByb3BlcnRpZXM6IGZ1bmN0aW9uICgpIHsKCQkvLyBjb2xsYXBzZWQgYXR0cmlidXRlCgkJdGhpcy5jb2xsYXBzZWQgPSAodGhpcy5zdGFydENvbnRhaW5lciA9PSB0aGlzLmVuZENvbnRhaW5lciAmJiB0aGlzLnN0YXJ0T2Zmc2V0ID09IHRoaXMuZW5kT2Zmc2V0KTsKCQkvLyBmaW5kIGNvbW1vbiBhbmNlc3RvcgoJCXZhciBub2RlID0gdGhpcy5zdGFydENvbnRhaW5lcjsKCQl3aGlsZSAobm9kZSAmJiBub2RlICE9IHRoaXMuZW5kQ29udGFpbmVyICYmICFET01VdGlscy5pc0FuY2VzdG9yT2Yobm9kZSwgdGhpcy5lbmRDb250YWluZXIpKQoJCQlub2RlID0gbm9kZS5wYXJlbnROb2RlOwoJCXRoaXMuY29tbW9uQW5jZXN0b3JDb250YWluZXIgPSBub2RlOwoJfSwKCgkvLyByYW5nZSBtZXRob2RzCi8vW1RPRE9dIGNvbGxhcHNlIGlmIHN0YXJ0IGlzIGFmdGVyIGVuZCwgZW5kIGlzIGJlZm9yZSBzdGFydAoJc2V0U3RhcnQ6IGZ1bmN0aW9uKGNvbnRhaW5lciwgb2Zmc2V0KSB7CgkJdGhpcy5zdGFydENvbnRhaW5lciA9IGNvbnRhaW5lcjsKCQl0aGlzLnN0YXJ0T2Zmc2V0ID0gb2Zmc2V0OwoJCXRoaXMuX3JlZnJlc2hQcm9wZXJ0aWVzKCk7Cgl9LAoJc2V0RW5kOiBmdW5jdGlvbihjb250YWluZXIsIG9mZnNldCkgewoJCXRoaXMuZW5kQ29udGFpbmVyID0gY29udGFpbmVyOwoJCXRoaXMuZW5kT2Zmc2V0ID0gb2Zmc2V0OwoJCXRoaXMuX3JlZnJlc2hQcm9wZXJ0aWVzKCk7Cgl9LAoJc2V0U3RhcnRCZWZvcmU6IGZ1bmN0aW9uIChyZWZOb2RlKSB7CgkJLy8gc2V0IHN0YXJ0IHRvIGJlb3JlIHRoaXMgbm9kZQoJCXRoaXMuc2V0U3RhcnQocmVmTm9kZS5wYXJlbnROb2RlLCBET01VdGlscy5maW5kQ2hpbGRQb3NpdGlvbihyZWZOb2RlKSk7Cgl9LAoJc2V0U3RhcnRBZnRlcjogZnVuY3Rpb24gKHJlZk5vZGUpIHsKCQkvLyBzZWxlY3QgbmV4dCBzaWJsaW5nCgkJdGhpcy5zZXRTdGFydChyZWZOb2RlLnBhcmVudE5vZGUsIERPTVV0aWxzLmZpbmRDaGlsZFBvc2l0aW9uKHJlZk5vZGUpICsgMSk7Cgl9LAoJc2V0RW5kQmVmb3JlOiBmdW5jdGlvbiAocmVmTm9kZSkgewoJCS8vIHNldCBlbmQgdG8gYmVvcmUgdGhpcyBub2RlCgkJdGhpcy5zZXRFbmQocmVmTm9kZS5wYXJlbnROb2RlLCBET01VdGlscy5maW5kQ2hpbGRQb3NpdGlvbihyZWZOb2RlKSk7Cgl9LAoJc2V0RW5kQWZ0ZXI6IGZ1bmN0aW9uIChyZWZOb2RlKSB7CgkJLy8gc2VsZWN0IG5leHQgc2libGluZwoJCXRoaXMuc2V0RW5kKHJlZk5vZGUucGFyZW50Tm9kZSwgRE9NVXRpbHMuZmluZENoaWxkUG9zaXRpb24ocmVmTm9kZSkgKyAxKTsKCX0sCglzZWxlY3ROb2RlOiBmdW5jdGlvbiAocmVmTm9kZSkgewoJCXRoaXMuc2V0U3RhcnRCZWZvcmUocmVmTm9kZSk7CgkJdGhpcy5zZXRFbmRBZnRlcihyZWZOb2RlKTsKCX0sCglzZWxlY3ROb2RlQ29udGVudHM6IGZ1bmN0aW9uIChyZWZOb2RlKSB7CgkJdGhpcy5zZXRTdGFydChyZWZOb2RlLCAwKTsKCQl0aGlzLnNldEVuZChyZWZOb2RlLCBET01VdGlscy5nZXROb2RlTGVuZ3RoKHJlZk5vZGUpKTsKCX0sCgljb2xsYXBzZTogZnVuY3Rpb24gKHRvU3RhcnQpIHsKCQlpZiAodG9TdGFydCkKCQkJdGhpcy5zZXRFbmQodGhpcy5zdGFydENvbnRhaW5lciwgdGhpcy5zdGFydE9mZnNldCk7CgkJZWxzZQoJCQl0aGlzLnNldFN0YXJ0KHRoaXMuZW5kQ29udGFpbmVyLCB0aGlzLmVuZE9mZnNldCk7Cgl9LAoKCS8vIGVkaXRpbmcgbWV0aG9kcwoJY2xvbmVDb250ZW50czogZnVuY3Rpb24gKCkgewoJCS8vIGNsb25lIHN1YnRyZWUKCQlyZXR1cm4gKGZ1bmN0aW9uIGNsb25lU3VidHJlZShpdGVyYXRvcikgewoJCQlmb3IgKHZhciBub2RlLCBmcmFnID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOyBub2RlID0gaXRlcmF0b3IubmV4dCgpOyApIHsKCQkJCW5vZGUgPSBub2RlLmNsb25lTm9kZSghaXRlcmF0b3IuaGFzUGFydGlhbFN1YnRyZWUoKSk7CgkJCQlpZiAoaXRlcmF0b3IuaGFzUGFydGlhbFN1YnRyZWUoKSkKCQkJCQlub2RlLmFwcGVuZENoaWxkKGNsb25lU3VidHJlZShpdGVyYXRvci5nZXRTdWJ0cmVlSXRlcmF0b3IoKSkpOwoJCQkJZnJhZy5hcHBlbmRDaGlsZChub2RlKTsKCQkJfQoJCQlyZXR1cm4gZnJhZzsKCQl9KShuZXcgUmFuZ2VJdGVyYXRvcih0aGlzKSk7Cgl9LAoJZXh0cmFjdENvbnRlbnRzOiBmdW5jdGlvbiAoKSB7CgkJLy8gY2FjaGUgcmFuZ2UgYW5kIG1vdmUgYW5jaG9yIHBvaW50cwoJCXZhciByYW5nZSA9IHRoaXMuY2xvbmVSYW5nZSgpOwoJCWlmICh0aGlzLnN0YXJ0Q29udGFpbmVyICE9IHRoaXMuY29tbW9uQW5jZXN0b3JDb250YWluZXIpCgkJCXRoaXMuc2V0U3RhcnRBZnRlcihET01VdGlscy5maW5kQ2xvc2VzdEFuY2VzdG9yKHRoaXMuY29tbW9uQW5jZXN0b3JDb250YWluZXIsIHRoaXMuc3RhcnRDb250YWluZXIpKTsKCQl0aGlzLmNvbGxhcHNlKHRydWUpOwoJCS8vIGV4dHJhY3QgcmFuZ2UKCQlyZXR1cm4gKGZ1bmN0aW9uIGV4dHJhY3RTdWJ0cmVlKGl0ZXJhdG9yKSB7CgkJCWZvciAodmFyIG5vZGUsIGZyYWcgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7IG5vZGUgPSBpdGVyYXRvci5uZXh0KCk7ICkgewoJCQkJaXRlcmF0b3IuaGFzUGFydGlhbFN1YnRyZWUoKSA/IG5vZGUgPSBub2RlLmNsb25lTm9kZShmYWxzZSkgOiBpdGVyYXRvci5yZW1vdmUoKTsKCQkJCWlmIChpdGVyYXRvci5oYXNQYXJ0aWFsU3VidHJlZSgpKQoJCQkJCW5vZGUuYXBwZW5kQ2hpbGQoZXh0cmFjdFN1YnRyZWUoaXRlcmF0b3IuZ2V0U3VidHJlZUl0ZXJhdG9yKCkpKTsKCQkJCWZyYWcuYXBwZW5kQ2hpbGQobm9kZSk7CgkJCX0KCQkJcmV0dXJuIGZyYWc7CgkJfSkobmV3IFJhbmdlSXRlcmF0b3IocmFuZ2UpKTsKCX0sCglkZWxldGVDb250ZW50czogZnVuY3Rpb24gKCkgewoJCS8vIGNhY2hlIHJhbmdlIGFuZCBtb3ZlIGFuY2hvciBwb2ludHMKCQl2YXIgcmFuZ2UgPSB0aGlzLmNsb25lUmFuZ2UoKTsKCQlpZiAodGhpcy5zdGFydENvbnRhaW5lciAhPSB0aGlzLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyKQoJCQl0aGlzLnNldFN0YXJ0QWZ0ZXIoRE9NVXRpbHMuZmluZENsb3Nlc3RBbmNlc3Rvcih0aGlzLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyLCB0aGlzLnN0YXJ0Q29udGFpbmVyKSk7CgkJdGhpcy5jb2xsYXBzZSh0cnVlKTsKCQkvLyBkZWxldGUgcmFuZ2UKCQkoZnVuY3Rpb24gZGVsZXRlU3VidHJlZShpdGVyYXRvcikgewoJCQl3aGlsZSAoaXRlcmF0b3IubmV4dCgpKQoJCQkJaXRlcmF0b3IuaGFzUGFydGlhbFN1YnRyZWUoKSA/IGRlbGV0ZVN1YnRyZWUoaXRlcmF0b3IuZ2V0U3VidHJlZUl0ZXJhdG9yKCkpIDogaXRlcmF0b3IucmVtb3ZlKCk7CgkJfSkobmV3IFJhbmdlSXRlcmF0b3IocmFuZ2UpKTsKCX0sCglpbnNlcnROb2RlOiBmdW5jdGlvbiAobmV3Tm9kZSkgewoJCS8vIHNldCBvcmlnaW5hbCBhbmNob3IgYW5kIGluc2VydCBub2RlCgkJaWYgKERPTVV0aWxzLmlzRGF0YU5vZGUodGhpcy5zdGFydENvbnRhaW5lcikpIHsKCQkJRE9NVXRpbHMuc3BsaXREYXRhTm9kZSh0aGlzLnN0YXJ0Q29udGFpbmVyLCB0aGlzLnN0YXJ0T2Zmc2V0KTsKCQkJdGhpcy5zdGFydENvbnRhaW5lci5wYXJlbnROb2RlLmluc2VydEJlZm9yZShuZXdOb2RlLCB0aGlzLnN0YXJ0Q29udGFpbmVyLm5leHRTaWJsaW5nKTsKCQl9IGVsc2UgewoJCQl0aGlzLnN0YXJ0Q29udGFpbmVyLmluc2VydEJlZm9yZShuZXdOb2RlLCB0aGlzLnN0YXJ0Q29udGFpbmVyLmNoaWxkTm9kZXNbdGhpcy5zdGFydE9mZnNldF0pOwoJCX0KCQkvLyByZXN5bmMgc3RhcnQgYW5jaG9yCgkJdGhpcy5zZXRTdGFydCh0aGlzLnN0YXJ0Q29udGFpbmVyLCB0aGlzLnN0YXJ0T2Zmc2V0KTsKCX0sCglzdXJyb3VuZENvbnRlbnRzOiBmdW5jdGlvbiAobmV3Tm9kZSkgewoJCS8vIGV4dHJhY3QgYW5kIHN1cnJvdW5kIGNvbnRlbnRzCgkJdmFyIGNvbnRlbnQgPSB0aGlzLmV4dHJhY3RDb250ZW50cygpOwoJCXRoaXMuaW5zZXJ0Tm9kZShuZXdOb2RlKTsKCQluZXdOb2RlLmFwcGVuZENoaWxkKGNvbnRlbnQpOwoJCXRoaXMuc2VsZWN0Tm9kZShuZXdOb2RlKTsKCX0sCgoJLy8gb3RoZXIgbWV0aG9kcwoJY29tcGFyZUJvdW5kYXJ5UG9pbnRzOiBmdW5jdGlvbiAoaG93LCBzb3VyY2VSYW5nZSkgewoJCS8vIGdldCBhbmNob3JzCgkJdmFyIGNvbnRhaW5lckEsIG9mZnNldEEsIGNvbnRhaW5lckIsIG9mZnNldEI7CgkJc3dpdGNoIChob3cpIHsKCQkgICAgY2FzZSBET01SYW5nZS5TVEFSVF9UT19TVEFSVDoKCQkgICAgY2FzZSBET01SYW5nZS5TVEFSVF9UT19FTkQ6CgkJCWNvbnRhaW5lckEgPSB0aGlzLnN0YXJ0Q29udGFpbmVyOwoJCQlvZmZzZXRBID0gdGhpcy5zdGFydE9mZnNldDsKCQkJYnJlYWs7CgkJICAgIGNhc2UgRE9NUmFuZ2UuRU5EX1RPX0VORDoKCQkgICAgY2FzZSBET01SYW5nZS5FTkRfVE9fU1RBUlQ6CgkJCWNvbnRhaW5lckEgPSB0aGlzLmVuZENvbnRhaW5lcjsKCQkJb2Zmc2V0QSA9IHRoaXMuZW5kT2Zmc2V0OwoJCQlicmVhazsKCQl9CgkJc3dpdGNoIChob3cpIHsKCQkgICAgY2FzZSBET01SYW5nZS5TVEFSVF9UT19TVEFSVDoKCQkgICAgY2FzZSBET01SYW5nZS5FTkRfVE9fU1RBUlQ6CgkJCWNvbnRhaW5lckIgPSBzb3VyY2VSYW5nZS5zdGFydENvbnRhaW5lcjsKCQkJb2Zmc2V0QiA9IHNvdXJjZVJhbmdlLnN0YXJ0T2Zmc2V0OwoJCQlicmVhazsKCQkgICAgY2FzZSBET01SYW5nZS5TVEFSVF9UT19FTkQ6CgkJICAgIGNhc2UgRE9NUmFuZ2UuRU5EX1RPX0VORDoKCQkJY29udGFpbmVyQiA9IHNvdXJjZVJhbmdlLmVuZENvbnRhaW5lcjsKCQkJb2Zmc2V0QiA9IHNvdXJjZVJhbmdlLmVuZE9mZnNldDsKCQkJYnJlYWs7CgkJfQoKCQkvLyBjb21wYXJlCgkJcmV0dXJuIGNvbnRhaW5lckEuc291cmNlSW5kZXggPCBjb250YWluZXJCLnNvdXJjZUluZGV4ID8gLTEgOgoJCSAgICBjb250YWluZXJBLnNvdXJjZUluZGV4ID09IGNvbnRhaW5lckIuc291cmNlSW5kZXggPwoJCSAgICAgICAgb2Zmc2V0QSA8IG9mZnNldEIgPyAtMSA6IG9mZnNldEEgPT0gb2Zmc2V0QiA/IDAgOiAxCgkJICAgICAgICA6IDE7Cgl9LAoJY2xvbmVSYW5nZTogZnVuY3Rpb24gKCkgewoJCS8vIHJldHVybiBjbG9uZWQgcmFuZ2UKCQl2YXIgcmFuZ2UgPSBuZXcgRE9NUmFuZ2UodGhpcy5fZG9jdW1lbnQpOwoJCXJhbmdlLnNldFN0YXJ0KHRoaXMuc3RhcnRDb250YWluZXIsIHRoaXMuc3RhcnRPZmZzZXQpOwoJCXJhbmdlLnNldEVuZCh0aGlzLmVuZENvbnRhaW5lciwgdGhpcy5lbmRPZmZzZXQpOwoJCXJldHVybiByYW5nZTsKCX0sCglkZXRhY2g6IGZ1bmN0aW9uICgpIHsKLy9bVE9ET10gUmVsZWFzZXMgUmFuZ2UgZnJvbSB1c2UgdG8gaW1wcm92ZSBwZXJmb3JtYW5jZS4KCX0sCgl0b1N0cmluZzogZnVuY3Rpb24gKCkgewovLyAgICAgICAgcmV0dXJuICJIYXZlIGEgc3RyaW5nLCBtdWdnbGVzISI7CgkJcmV0dXJuIFRleHRSYW5nZVV0aWxzLmNvbnZlcnRGcm9tRE9NUmFuZ2UodGhpcykudGV4dDsKCX0sCgljcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQ6IGZ1bmN0aW9uICh0YWdTdHJpbmcpIHsKCQkvLyBwYXJzZSB0aGUgdGFnIHN0cmluZyBpbiBhIGNvbnRleHQgbm9kZQoJCXZhciBjb250ZW50ID0gKERPTVV0aWxzLmlzRGF0YU5vZGUodGhpcy5zdGFydENvbnRhaW5lcikgPyB0aGlzLnN0YXJ0Q29udGFpbmVyLnBhcmVudE5vZGUgOiB0aGlzLnN0YXJ0Q29udGFpbmVyKS5jbG9uZU5vZGUoZmFsc2UpOwoJCWNvbnRlbnQuaW5uZXJIVE1MID0gdGFnU3RyaW5nOwoJCS8vIHJldHVybiBhIGRvY3VtZW50IGZyYWdtZW50IGZyb20gdGhlIGNyZWF0ZWQgbm9kZQoJCWZvciAodmFyIGZyYWdtZW50ID0gdGhpcy5fZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOyBjb250ZW50LmZpcnN0Q2hpbGQ7ICkKCQkJZnJhZ21lbnQuYXBwZW5kQ2hpbGQoY29udGVudC5maXJzdENoaWxkKTsKCQlyZXR1cm4gZnJhZ21lbnQ7Cgl9Cn07CgovKgogIFJhbmdlIGl0ZXJhdG9yCiAqLwoKZnVuY3Rpb24gUmFuZ2VJdGVyYXRvcihyYW5nZSkgewoJdGhpcy5yYW5nZSA9IHJhbmdlOwoJaWYgKHJhbmdlLmNvbGxhcHNlZCkKCQlyZXR1cm47CgovL1tUT0RPXSBlbnN1cmUgdGhpcyB3b3JrcwoJLy8gZ2V0IGFuY2hvcnMKCXZhciByb290ID0gcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXI7Cgl0aGlzLl9uZXh0ID0gcmFuZ2Uuc3RhcnRDb250YWluZXIgPT0gcm9vdCAmJiAhRE9NVXRpbHMuaXNEYXRhTm9kZShyYW5nZS5zdGFydENvbnRhaW5lcikgPwoJICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyLmNoaWxkTm9kZXNbcmFuZ2Uuc3RhcnRPZmZzZXRdIDoKCSAgICBET01VdGlscy5maW5kQ2xvc2VzdEFuY2VzdG9yKHJvb3QsIHJhbmdlLnN0YXJ0Q29udGFpbmVyKTsKCXRoaXMuX2VuZCA9IHJhbmdlLmVuZENvbnRhaW5lciA9PSByb290ICYmICFET01VdGlscy5pc0RhdGFOb2RlKHJhbmdlLmVuZENvbnRhaW5lcikgPwoJICAgIHJhbmdlLmVuZENvbnRhaW5lci5jaGlsZE5vZGVzW3JhbmdlLmVuZE9mZnNldF0gOgoJICAgIERPTVV0aWxzLmZpbmRDbG9zZXN0QW5jZXN0b3Iocm9vdCwgcmFuZ2UuZW5kQ29udGFpbmVyKS5uZXh0U2libGluZzsKfQoKUmFuZ2VJdGVyYXRvci5wcm90b3R5cGUgPSB7CgkvLyBwdWJsaWMgcHJvcGVydGllcwoJcmFuZ2U6IG51bGwsCgkvLyBwcml2YXRlIHByb3BlcnRpZXMKCV9jdXJyZW50OiBudWxsLAoJX25leHQ6IG51bGwsCglfZW5kOiBudWxsLAoKCS8vIHB1YmxpYyBtZXRob2RzCgloYXNOZXh0OiBmdW5jdGlvbiAoKSB7CgkJcmV0dXJuICEhdGhpcy5fbmV4dDsKCX0sCgluZXh0OiBmdW5jdGlvbiAoKSB7CgkJLy8gbW92ZSB0byBuZXh0IG5vZGUKCQl2YXIgY3VycmVudCA9IHRoaXMuX2N1cnJlbnQgPSB0aGlzLl9uZXh0OwoJCXRoaXMuX25leHQgPSB0aGlzLl9jdXJyZW50ICYmIHRoaXMuX2N1cnJlbnQubmV4dFNpYmxpbmcgIT0gdGhpcy5fZW5kID8KCQkgICAgdGhpcy5fY3VycmVudC5uZXh0U2libGluZyA6IG51bGw7CgoJCS8vIGNoZWNrIGZvciBwYXJ0aWFsIHRleHQgbm9kZXMKCQlpZiAoRE9NVXRpbHMuaXNEYXRhTm9kZSh0aGlzLl9jdXJyZW50KSkgewoJCQlpZiAodGhpcy5yYW5nZS5lbmRDb250YWluZXIgPT0gdGhpcy5fY3VycmVudCkKCQkJCShjdXJyZW50ID0gY3VycmVudC5jbG9uZU5vZGUodHJ1ZSkpLmRlbGV0ZURhdGEodGhpcy5yYW5nZS5lbmRPZmZzZXQsIGN1cnJlbnQubGVuZ3RoIC0gdGhpcy5yYW5nZS5lbmRPZmZzZXQpOwoJCQlpZiAodGhpcy5yYW5nZS5zdGFydENvbnRhaW5lciA9PSB0aGlzLl9jdXJyZW50KQoJCQkJKGN1cnJlbnQgPSBjdXJyZW50LmNsb25lTm9kZSh0cnVlKSkuZGVsZXRlRGF0YSgwLCB0aGlzLnJhbmdlLnN0YXJ0T2Zmc2V0KTsKCQl9CgkJcmV0dXJuIGN1cnJlbnQ7Cgl9LAoJcmVtb3ZlOiBmdW5jdGlvbiAoKSB7CgkJLy8gY2hlY2sgZm9yIHBhcnRpYWwgdGV4dCBub2RlcwoJCWlmIChET01VdGlscy5pc0RhdGFOb2RlKHRoaXMuX2N1cnJlbnQpICYmCgkJICAgICh0aGlzLnJhbmdlLnN0YXJ0Q29udGFpbmVyID09IHRoaXMuX2N1cnJlbnQgfHwgdGhpcy5yYW5nZS5lbmRDb250YWluZXIgPT0gdGhpcy5fY3VycmVudCkpIHsKCQkJdmFyIHN0YXJ0ID0gdGhpcy5yYW5nZS5zdGFydENvbnRhaW5lciA9PSB0aGlzLl9jdXJyZW50ID8gdGhpcy5yYW5nZS5zdGFydE9mZnNldCA6IDA7CgkJCXZhciBlbmQgPSB0aGlzLnJhbmdlLmVuZENvbnRhaW5lciA9PSB0aGlzLl9jdXJyZW50ID8gdGhpcy5yYW5nZS5lbmRPZmZzZXQgOiB0aGlzLl9jdXJyZW50Lmxlbmd0aDsKCQkJdGhpcy5fY3VycmVudC5kZWxldGVEYXRhKHN0YXJ0LCBlbmQgLSBzdGFydCk7CgkJfSBlbHNlCgkJCXRoaXMuX2N1cnJlbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLl9jdXJyZW50KTsKCX0sCgloYXNQYXJ0aWFsU3VidHJlZTogZnVuY3Rpb24gKCkgewoJCS8vIGNoZWNrIGlmIHRoaXMgbm9kZSBiZSBwYXJ0aWFsbHkgc2VsZWN0ZWQKCQlyZXR1cm4gIURPTVV0aWxzLmlzRGF0YU5vZGUodGhpcy5fY3VycmVudCkgJiYKCQkgICAgKERPTVV0aWxzLmlzQW5jZXN0b3JPclNlbGYodGhpcy5fY3VycmVudCwgdGhpcy5yYW5nZS5zdGFydENvbnRhaW5lcikgfHwKCQkgICAgICAgIERPTVV0aWxzLmlzQW5jZXN0b3JPclNlbGYodGhpcy5fY3VycmVudCwgdGhpcy5yYW5nZS5lbmRDb250YWluZXIpKTsKCX0sCglnZXRTdWJ0cmVlSXRlcmF0b3I6IGZ1bmN0aW9uICgpIHsKCQkvLyBjcmVhdGUgYSBuZXcgcmFuZ2UKCQl2YXIgc3ViUmFuZ2UgPSBuZXcgRE9NUmFuZ2UodGhpcy5yYW5nZS5fZG9jdW1lbnQpOwoJCXN1YlJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyh0aGlzLl9jdXJyZW50KTsKCQkvLyBoYW5kbGUgYW5jaG9yIHBvaW50cwoJCWlmIChET01VdGlscy5pc0FuY2VzdG9yT3JTZWxmKHRoaXMuX2N1cnJlbnQsIHRoaXMucmFuZ2Uuc3RhcnRDb250YWluZXIpKQoJCQlzdWJSYW5nZS5zZXRTdGFydCh0aGlzLnJhbmdlLnN0YXJ0Q29udGFpbmVyLCB0aGlzLnJhbmdlLnN0YXJ0T2Zmc2V0KTsKCQlpZiAoRE9NVXRpbHMuaXNBbmNlc3Rvck9yU2VsZih0aGlzLl9jdXJyZW50LCB0aGlzLnJhbmdlLmVuZENvbnRhaW5lcikpCgkJCXN1YlJhbmdlLnNldEVuZCh0aGlzLnJhbmdlLmVuZENvbnRhaW5lciwgdGhpcy5yYW5nZS5lbmRPZmZzZXQpOwoJCS8vIHJldHVybiBpdGVyYXRvcgoJCXJldHVybiBuZXcgUmFuZ2VJdGVyYXRvcihzdWJSYW5nZSk7Cgl9Cn07CgovKgogIERPTSBTZWxlY3Rpb24KICovCgovL1tOT1RFXSBUaGlzIGlzIGEgdmVyeSBzaGFsbG93IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWxlY3Rpb24gb2JqZWN0LCBiYXNlZCBvbiBXZWJraXQncwovLyBpbXBsZW1lbnRhdGlvbiBhbmQgd2l0aG91dCByZWR1bmRhbnQgZmVhdHVyZXMuIENvbXBsZXRlIHNlbGVjdGlvbiBtYW5pcHVsYXRpb24gaXMgc3RpbGwKLy8gcG9zc2libGUgd2l0aCBqdXN0IHJlbW92ZUFsbFJhbmdlcy9hZGRSYW5nZS9nZXRSYW5nZUF0LgoKZnVuY3Rpb24gRE9NU2VsZWN0aW9uKGRvY3VtZW50KSB7CgkvLyBzYXZlIGRvY3VtZW50IHBhcmFtZXRlcgoJdGhpcy5fZG9jdW1lbnQgPSBkb2N1bWVudDsKCgkvLyBhZGQgRE9NIHNlbGVjdGlvbiBoYW5kbGVyCgl2YXIgc2VsZWN0aW9uID0gdGhpczsKCWRvY3VtZW50LmF0dGFjaEV2ZW50KCdvbnNlbGVjdGlvbmNoYW5nZScsIGZ1bmN0aW9uICgpIHsgc2VsZWN0aW9uLl9zZWxlY3Rpb25DaGFuZ2VIYW5kbGVyKCk7IH0pOwp9CgpET01TZWxlY3Rpb24ucHJvdG90eXBlID0gewoJLy8gcHVibGljIHByb3BlcnRpZXMKCXJhbmdlQ291bnQ6IDAsCgkvLyBwcml2YXRlIHByb3BlcnRpZXMKCV9kb2N1bWVudDogbnVsbCwKCgkvLyBwcml2YXRlIG1ldGhvZHMKCV9zZWxlY3Rpb25DaGFuZ2VIYW5kbGVyOiBmdW5jdGlvbiAoKSB7CgkJLy8gY2hlY2sgaWYgdGhlcmUgZXhpc3RzIGEgcmFuZ2UKCQoJCXRoaXMucmFuZ2VDb3VudCA9IHRoaXMuX3NlbGVjdGlvbkV4aXN0cyh0aGlzLl9kb2N1bWVudC5zZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKSkgPyAxIDogMDsKCX0sCglfc2VsZWN0aW9uRXhpc3RzOiBmdW5jdGlvbiAodGV4dFJhbmdlKSB7CiAgICAgICAgLy9BVExBU1NJQU46IGlzc3VlIHdpdGggc2VsZWN0aW9uYSByb3VuZCBpbWFnZXMsIHhodG1sIGJyYW5jaCBoYXMgcmVtb3ZlZCByZWZlcmVuY2VzIHRvIHRoaXMuCiAgICAJLy9sb29rZWQgb3ZlciBpdCwgZG9lcyBub3Qgc2VlbSB0byBiZSBmdWxseSB0ZXN0ZWQgeWV0LgogICAgCS8vc28gaG9wZWZ1bGx5IHdlIGNhbiBqdXN0IGJlIGRvbmUgd2l0aCB0aGlzIGZpbGUgc29vbgoJICAgIGlmKCF0ZXh0UmFuZ2UuY29tcGFyZUVuZFBvaW50cykgICAgewoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJCS8vIGNoZWNrcyBpZiBhIGNyZWF0ZWQgdGV4dCByYW5nZSBleGlzdHMgb3IgaXMgYW4gZWRpdGFibGUgY3Vyc29yCgkJcmV0dXJuIHRleHRSYW5nZS5jb21wYXJlRW5kUG9pbnRzKCdTdGFydFRvRW5kJywgdGV4dFJhbmdlKSAhPSAwIHx8CgkJICAgIHRleHRSYW5nZS5wYXJlbnRFbGVtZW50KCkuaXNDb250ZW50RWRpdGFibGU7Cgl9LAoKCS8vIHB1YmxpYyBtZXRob2RzCglhZGRSYW5nZTogZnVuY3Rpb24gKHJhbmdlKSB7CgkJLy8gYWRkIHJhbmdlIG9yIGNvbWJpbmUgd2l0aCBleGlzdGluZyByYW5nZQoJCXZhciBzZWxlY3Rpb24gPSB0aGlzLl9kb2N1bWVudC5zZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKSwgdGV4dFJhbmdlID0gVGV4dFJhbmdlVXRpbHMuY29udmVydEZyb21ET01SYW5nZShyYW5nZSk7CgkJaWYgKCF0aGlzLl9zZWxlY3Rpb25FeGlzdHMoc2VsZWN0aW9uKSkKCQl7CgkJCS8vIHNlbGVjdCByYW5nZQoJCQl0ZXh0UmFuZ2Uuc2VsZWN0KCk7CgkJfQoJCWVsc2UKCQl7CgkJCS8vIG9ubHkgbW9kaWZ5IHJhbmdlIGlmIGl0IGludGVyc2VjdHMgd2l0aCBjdXJyZW50IHJhbmdlCgkJCWlmICh0ZXh0UmFuZ2UuY29tcGFyZUVuZFBvaW50cygnU3RhcnRUb1N0YXJ0Jywgc2VsZWN0aW9uKSA9PSAtMSkKCQkJCWlmICh0ZXh0UmFuZ2UuY29tcGFyZUVuZFBvaW50cygnU3RhcnRUb0VuZCcsIHNlbGVjdGlvbikgPiAtMSAmJgoJCQkJICAgIHRleHRSYW5nZS5jb21wYXJlRW5kUG9pbnRzKCdFbmRUb0VuZCcsIHNlbGVjdGlvbikgPT0gLTEpCgkJCQkJc2VsZWN0aW9uLnNldEVuZFBvaW50KCdTdGFydFRvU3RhcnQnLCB0ZXh0UmFuZ2UpOwoJCQllbHNlCgkJCQlpZiAodGV4dFJhbmdlLmNvbXBhcmVFbmRQb2ludHMoJ0VuZFRvU3RhcnQnLCBzZWxlY3Rpb24pIDwgMSAmJgoJCQkJICAgIHRleHRSYW5nZS5jb21wYXJlRW5kUG9pbnRzKCdFbmRUb0VuZCcsIHNlbGVjdGlvbikgPiAtMSkKCQkJCQlzZWxlY3Rpb24uc2V0RW5kUG9pbnQoJ0VuZFRvRW5kJywgdGV4dFJhbmdlKTsKCQkJc2VsZWN0aW9uLnNlbGVjdCgpOwoJCX0KCX0sCglyZW1vdmVBbGxSYW5nZXM6IGZ1bmN0aW9uICgpIHsKCQkvLyByZW1vdmUgYWxsIHJhbmdlcwoJCXRoaXMuX2RvY3VtZW50LnNlbGVjdGlvbi5lbXB0eSgpOwoJfSwKCWdldFJhbmdlQXQ6IGZ1bmN0aW9uIChpbmRleCkgewoJCS8vIHJldHVybiBhbnkgZXhpc3Rpbmcgc2VsZWN0aW9uLCBvciBhIGN1cnNvciBwb3NpdGlvbiBpbiBjb250ZW50IGVkaXRhYmxlIG1vZGUKCQl2YXIgdGV4dFJhbmdlID0gdGhpcy5fZG9jdW1lbnQuc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCk7CgkJaWYgKHRoaXMuX3NlbGVjdGlvbkV4aXN0cyh0ZXh0UmFuZ2UpKSB7CgkJCXJldHVybiBUZXh0UmFuZ2VVdGlscy5jb252ZXJ0VG9ET01SYW5nZSh0ZXh0UmFuZ2UsIHRoaXMuX2RvY3VtZW50KTsKICAgICAgICB9CgkJcmV0dXJuIG51bGw7Cgl9LAoJdG9TdHJpbmc6IGZ1bmN0aW9uICgpIHsKCQkvLyBnZXQgc2VsZWN0aW9uIHRleHQKCQlyZXR1cm4gdGhpcy5fZG9jdW1lbnQuc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCkudGV4dDsKCX0KfTsKCi8qCiAgU2NyaXB0aW5nIGhvb2tzIC0gY2hhbmdlZCBmcm9tIHdpbmRvdy1sZXZlbCBmdW5jdGlvbnMgZm9yIENvbmZsdWVuY2Ugc2FmZXR5LgoKICBjcmVhdGVSYW5nZSwgc2V0dXBTZWxlY3Rpb24gYW5kIGdldFNlbGVjdGlvbiByZXBsYWNlIHRoZSBleGlzdGluZyBJRVJhbmdlIGhvb2tzLCB3aGlsZSB0ZXh0UmFuZ2VVdGlscyBleHBvc2VzIHRoaXMKICBsaWJyYXJ5J3MgaGVscGVyIGZvciBjb252ZXJ0aW5nIGJldHdlZW4gRE9NIGFuZCBUZXh0IFJhbmdlcy4KICovCmlmICghd2luZG93LmdldFNlbGVjdGlvbikgewogICAgQUpTLmxvZygiQWRkaW5nIElFUmFuZ2UgdG8gQUpTLkVkaXRvci5BZGFwdGVyIik7CgogICAgQUpTLkVkaXRvci5BZGFwdGVyLklFUmFuZ2UgPSB7CiAgICAgICAgY3JlYXRlUmFuZ2UgOiBmdW5jdGlvbiAoZG9jdW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBET01SYW5nZShkb2N1bWVudCk7CiAgICAgICAgfSwKICAgICAgICBzZXR1cFNlbGVjdGlvbiA6IGZ1bmN0aW9uKGRvY3VtZW50KSB7CiAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uID0gbmV3IERPTVNlbGVjdGlvbihkb2N1bWVudCk7CiAgICAgICAgfSwKICAgICAgICBnZXRTZWxlY3Rpb24gOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnNlbGVjdGlvbjsKICAgICAgICB9LAogICAgICAgIHRleHRSYW5nZVV0aWxzIDogVGV4dFJhbmdlVXRpbHMKICAgIH07Cn0KLy9bVE9ET10gZXhwb3NlIERPTVJhbmdlL0RPTVNlbGVjdGlvbiB0byB3aW5kb3cuPwoKfSkoKTsKCg==