LyoKICBTb3J0VGFibGUKICB2ZXJzaW9uIDIKICA3dGggQXByaWwgMjAwNwogIFN0dWFydCBMYW5ncmlkZ2UsIGh0dHA6Ly93d3cua3J5b2dlbml4Lm9yZy9jb2RlL2Jyb3dzZXIvc29ydHRhYmxlLwoKICBJbnN0cnVjdGlvbnM6CiAgRG93bmxvYWQgdGhpcyBmaWxlCiAgQWRkIDxzY3JpcHQgc3JjPSJzb3J0dGFibGUuanMiPjwvc2NyaXB0PiB0byB5b3VyIEhUTUwKICBBZGQgY2xhc3M9InNvcnRhYmxlIiB0byBhbnkgdGFibGUgeW91J2QgbGlrZSB0byBtYWtlIHNvcnRhYmxlCiAgQ2xpY2sgb24gdGhlIGhlYWRlcnMgdG8gc29ydAoKICBUaGFua3MgdG8gbWFueSwgbWFueSBwZW9wbGUgZm9yIGNvbnRyaWJ1dGlvbnMgYW5kIHN1Z2dlc3Rpb25zLgogIExpY2VuY2VkIGFzIFgxMTogaHR0cDovL3d3dy5rcnlvZ2VuaXgub3JnL2NvZGUvYnJvd3Nlci9saWNlbmNlLmh0bWwKICBUaGlzIGJhc2ljYWxseSBtZWFuczogZG8gd2hhdCB5b3Ugd2FudCB3aXRoIGl0LgoqLwoKCnZhciBzdElzSUUgPSAvKkBjY19vbiFAKi9mYWxzZTsKCnNvcnR0YWJsZSA9IHsKICBpbml0OiBmdW5jdGlvbigpIHsKICAgIC8vIHF1aXQgaWYgdGhpcyBmdW5jdGlvbiBoYXMgYWxyZWFkeSBiZWVuIGNhbGxlZAogICAgaWYgKGFyZ3VtZW50cy5jYWxsZWUuZG9uZSkgcmV0dXJuOwogICAgLy8gZmxhZyB0aGlzIGZ1bmN0aW9uIHNvIHdlIGRvbid0IGRvIHRoZSBzYW1lIHRoaW5nIHR3aWNlCiAgICBhcmd1bWVudHMuY2FsbGVlLmRvbmUgPSB0cnVlOwogICAgLy8ga2lsbCB0aGUgdGltZXIKICAgIGlmIChfdGltZXIpIGNsZWFySW50ZXJ2YWwoX3RpbWVyKTsKCiAgICBpZiAoIWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgfHwgIWRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKSByZXR1cm47CgogICAgc29ydHRhYmxlLkRBVEVfUkUgPSAvXihcZFxkPylbXC9cLi1dKFxkXGQ/KVtcL1wuLV0oKFxkXGQpP1xkXGQpJC87CgogICAgZm9yRWFjaChkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgndGFibGUnKSwgZnVuY3Rpb24odGFibGUpIHsKICAgICAgaWYgKHRhYmxlLmNsYXNzTmFtZS5zZWFyY2goL1xic29ydGFibGVcYi8pICE9IC0xKSB7CiAgICAgICAgc29ydHRhYmxlLm1ha2VTb3J0YWJsZSh0YWJsZSk7CiAgICAgIH0KICAgIH0pOwoKICB9LAoKICBtYWtlU29ydGFibGU6IGZ1bmN0aW9uKHRhYmxlKSB7CiAgICBpZiAodGFibGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3RoZWFkJykubGVuZ3RoID09IDApIHsKICAgICAgLy8gdGFibGUgZG9lc24ndCBoYXZlIGEgdEhlYWQuIFNpbmNlIGl0IHNob3VsZCBoYXZlLCBjcmVhdGUgb25lIGFuZAogICAgICAvLyBwdXQgdGhlIGZpcnN0IHRhYmxlIHJvdyBpbiBpdC4KICAgICAgdGhlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGhlYWQnKTsKICAgICAgdGhlLmFwcGVuZENoaWxkKHRhYmxlLnJvd3NbMF0pOwogICAgICB0YWJsZS5pbnNlcnRCZWZvcmUodGhlLHRhYmxlLmZpcnN0Q2hpbGQpOwogICAgfQogICAgLy8gU2FmYXJpIGRvZXNuJ3Qgc3VwcG9ydCB0YWJsZS50SGVhZCwgc2lnaAogICAgaWYgKHRhYmxlLnRIZWFkID09IG51bGwpIHRhYmxlLnRIZWFkID0gdGFibGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3RoZWFkJylbMF07CgogICAgaWYgKHRhYmxlLnRIZWFkLnJvd3MubGVuZ3RoICE9IDEpIHJldHVybjsgLy8gY2FuJ3QgY29wZSB3aXRoIHR3byBoZWFkZXIgcm93cwoKICAgIC8vIFNvcnR0YWJsZSB2MSBwdXQgcm93cyB3aXRoIGEgY2xhc3Mgb2YgInNvcnRib3R0b20iIGF0IHRoZSBib3R0b20gKGFzCiAgICAvLyAidG90YWwiIHJvd3MsIGZvciBleGFtcGxlKS4gVGhpcyBpcyBCJlIsIHNpbmNlIHdoYXQgeW91J3JlIHN1cHBvc2VkCiAgICAvLyB0byBkbyBpcyBwdXQgdGhlbSBpbiBhIHRmb290LiBTbywgaWYgdGhlcmUgYXJlIHNvcnRib3R0b20gcm93cywKICAgIC8vIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSwgbW92ZSB0aGVtIHRvIHRmb290IChjcmVhdGluZyBpdCBpZiBuZWVkZWQpLgogICAgc29ydGJvdHRvbXJvd3MgPSBbXTsKICAgIGZvciAodmFyIGk9MDsgaTx0YWJsZS5yb3dzLmxlbmd0aDsgaSsrKSB7CiAgICAgIGlmICh0YWJsZS5yb3dzW2ldLmNsYXNzTmFtZS5zZWFyY2goL1xic29ydGJvdHRvbVxiLykgIT0gLTEpIHsKICAgICAgICBzb3J0Ym90dG9tcm93c1tzb3J0Ym90dG9tcm93cy5sZW5ndGhdID0gdGFibGUucm93c1tpXTsKICAgICAgfQogICAgfQogICAgaWYgKHNvcnRib3R0b21yb3dzKSB7CiAgICAgIGlmICh0YWJsZS50Rm9vdCA9PSBudWxsKSB7CiAgICAgICAgLy8gdGFibGUgZG9lc24ndCBoYXZlIGEgdGZvb3QuIENyZWF0ZSBvbmUuCiAgICAgICAgdGZvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGZvb3QnKTsKICAgICAgICB0YWJsZS5hcHBlbmRDaGlsZCh0Zm8pOwogICAgICB9CiAgICAgIGZvciAodmFyIGk9MDsgaTxzb3J0Ym90dG9tcm93cy5sZW5ndGg7IGkrKykgewogICAgICAgIHRmby5hcHBlbmRDaGlsZChzb3J0Ym90dG9tcm93c1tpXSk7CiAgICAgIH0KICAgICAgZGVsZXRlIHNvcnRib3R0b21yb3dzOwogICAgfQoKICAgIC8vIHdvcmsgdGhyb3VnaCBlYWNoIGNvbHVtbiBhbmQgY2FsY3VsYXRlIGl0cyB0eXBlCiAgICBoZWFkcm93ID0gdGFibGUudEhlYWQucm93c1swXS5jZWxsczsKICAgIGZvciAodmFyIGk9MDsgaTxoZWFkcm93Lmxlbmd0aDsgaSsrKSB7CiAgICAgIC8vIG1hbnVhbGx5IG92ZXJyaWRlIHRoZSB0eXBlIHdpdGggYSBzb3J0dGFibGVfdHlwZSBhdHRyaWJ1dGUKICAgICAgaWYgKCFoZWFkcm93W2ldLmNsYXNzTmFtZS5tYXRjaCgvXGJzb3J0dGFibGVfbm9zb3J0XGIvKSkgeyAvLyBza2lwIHRoaXMgY29sCiAgICAgICAgbXRjaCA9IGhlYWRyb3dbaV0uY2xhc3NOYW1lLm1hdGNoKC9cYnNvcnR0YWJsZV8oW2EtejAtOV0rKVxiLyk7CiAgICAgICAgaWYgKG10Y2gpIHsgb3ZlcnJpZGUgPSBtdGNoWzFdOyB9CgkgICAgICBpZiAobXRjaCAmJiB0eXBlb2Ygc29ydHRhYmxlWyJzb3J0XyIrb3ZlcnJpZGVdID09ICdmdW5jdGlvbicpIHsKCSAgICAgICAgaGVhZHJvd1tpXS5zb3J0dGFibGVfc29ydGZ1bmN0aW9uID0gc29ydHRhYmxlWyJzb3J0XyIrb3ZlcnJpZGVdOwoJICAgICAgfSBlbHNlIHsKCSAgICAgICAgaGVhZHJvd1tpXS5zb3J0dGFibGVfc29ydGZ1bmN0aW9uID0gc29ydHRhYmxlLmd1ZXNzVHlwZSh0YWJsZSxpKTsKCSAgICAgIH0KCSAgICAgIC8vIG1ha2UgaXQgY2xpY2thYmxlIHRvIHNvcnQKCSAgICAgIGhlYWRyb3dbaV0uc29ydHRhYmxlX2NvbHVtbmluZGV4ID0gaTsKCSAgICAgIGhlYWRyb3dbaV0uc29ydHRhYmxlX3Rib2R5ID0gdGFibGUudEJvZGllc1swXTsKCSAgICAgIGRlYW5fYWRkRXZlbnQoaGVhZHJvd1tpXSwiY2xpY2siLCBmdW5jdGlvbihlKSB7CgogICAgICAgICAgaWYgKHRoaXMuY2xhc3NOYW1lLnNlYXJjaCgvXGJzb3J0dGFibGVfc29ydGVkXGIvKSAhPSAtMSkgewogICAgICAgICAgICAvLyBpZiB3ZSdyZSBhbHJlYWR5IHNvcnRlZCBieSB0aGlzIGNvbHVtbiwganVzdAogICAgICAgICAgICAvLyByZXZlcnNlIHRoZSB0YWJsZSwgd2hpY2ggaXMgcXVpY2tlcgogICAgICAgICAgICBzb3J0dGFibGUucmV2ZXJzZSh0aGlzLnNvcnR0YWJsZV90Ym9keSk7CiAgICAgICAgICAgIHRoaXMuY2xhc3NOYW1lID0gdGhpcy5jbGFzc05hbWUucmVwbGFjZSgnc29ydHRhYmxlX3NvcnRlZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc29ydHRhYmxlX3NvcnRlZF9yZXZlcnNlJyk7CiAgICAgICAgICAgIHRoaXMucmVtb3ZlQ2hpbGQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NvcnR0YWJsZV9zb3J0ZndkaW5kJykpOwogICAgICAgICAgICBzb3J0cmV2aW5kID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpOwogICAgICAgICAgICBzb3J0cmV2aW5kLmlkID0gInNvcnR0YWJsZV9zb3J0cmV2aW5kIjsKICAgICAgICAgICAgc29ydHJldmluZC5pbm5lckhUTUwgPSBzdElzSUUgPyAnJm5ic3A8Zm9udCBmYWNlPSJ3ZWJkaW5ncyI+NTwvZm9udD4nIDogJyZuYnNwOyYjeDI1QjQ7JzsKICAgICAgICAgICAgdGhpcy5hcHBlbmRDaGlsZChzb3J0cmV2aW5kKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHRoaXMuY2xhc3NOYW1lLnNlYXJjaCgvXGJzb3J0dGFibGVfc29ydGVkX3JldmVyc2VcYi8pICE9IC0xKSB7CiAgICAgICAgICAgIC8vIGlmIHdlJ3JlIGFscmVhZHkgc29ydGVkIGJ5IHRoaXMgY29sdW1uIGluIHJldmVyc2UsIGp1c3QKICAgICAgICAgICAgLy8gcmUtcmV2ZXJzZSB0aGUgdGFibGUsIHdoaWNoIGlzIHF1aWNrZXIKICAgICAgICAgICAgc29ydHRhYmxlLnJldmVyc2UodGhpcy5zb3J0dGFibGVfdGJvZHkpOwogICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSA9IHRoaXMuY2xhc3NOYW1lLnJlcGxhY2UoJ3NvcnR0YWJsZV9zb3J0ZWRfcmV2ZXJzZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc29ydHRhYmxlX3NvcnRlZCcpOwogICAgICAgICAgICB0aGlzLnJlbW92ZUNoaWxkKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzb3J0dGFibGVfc29ydHJldmluZCcpKTsKICAgICAgICAgICAgc29ydGZ3ZGluZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTsKICAgICAgICAgICAgc29ydGZ3ZGluZC5pZCA9ICJzb3J0dGFibGVfc29ydGZ3ZGluZCI7CiAgICAgICAgICAgIHNvcnRmd2RpbmQuaW5uZXJIVE1MID0gc3RJc0lFID8gJyZuYnNwPGZvbnQgZmFjZT0id2ViZGluZ3MiPjY8L2ZvbnQ+JyA6ICcmbmJzcDsmI3gyNUJFOyc7CiAgICAgICAgICAgIHRoaXMuYXBwZW5kQ2hpbGQoc29ydGZ3ZGluZCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyByZW1vdmUgc29ydHRhYmxlX3NvcnRlZCBjbGFzc2VzCiAgICAgICAgICB0aGVhZHJvdyA9IHRoaXMucGFyZW50Tm9kZTsKICAgICAgICAgIGZvckVhY2godGhlYWRyb3cuY2hpbGROb2RlcywgZnVuY3Rpb24oY2VsbCkgewogICAgICAgICAgICBpZiAoY2VsbC5ub2RlVHlwZSA9PSAxKSB7IC8vIGFuIGVsZW1lbnQKICAgICAgICAgICAgICBjZWxsLmNsYXNzTmFtZSA9IGNlbGwuY2xhc3NOYW1lLnJlcGxhY2UoJ3NvcnR0YWJsZV9zb3J0ZWRfcmV2ZXJzZScsJycpOwogICAgICAgICAgICAgIGNlbGwuY2xhc3NOYW1lID0gY2VsbC5jbGFzc05hbWUucmVwbGFjZSgnc29ydHRhYmxlX3NvcnRlZCcsJycpOwogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKICAgICAgICAgIHNvcnRmd2RpbmQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc29ydHRhYmxlX3NvcnRmd2RpbmQnKTsKICAgICAgICAgIGlmIChzb3J0ZndkaW5kKSB7IHNvcnRmd2RpbmQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzb3J0ZndkaW5kKTsgfQogICAgICAgICAgc29ydHJldmluZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzb3J0dGFibGVfc29ydHJldmluZCcpOwogICAgICAgICAgaWYgKHNvcnRyZXZpbmQpIHsgc29ydHJldmluZC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHNvcnRyZXZpbmQpOyB9CgogICAgICAgICAgdGhpcy5jbGFzc05hbWUgKz0gJyBzb3J0dGFibGVfc29ydGVkJzsKICAgICAgICAgIHNvcnRmd2RpbmQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7CiAgICAgICAgICBzb3J0ZndkaW5kLmlkID0gInNvcnR0YWJsZV9zb3J0ZndkaW5kIjsKICAgICAgICAgIHNvcnRmd2RpbmQuaW5uZXJIVE1MID0gc3RJc0lFID8gJyZuYnNwPGZvbnQgZmFjZT0id2ViZGluZ3MiPjY8L2ZvbnQ+JyA6ICcmbmJzcDsmI3gyNUJFOyc7CiAgICAgICAgICB0aGlzLmFwcGVuZENoaWxkKHNvcnRmd2RpbmQpOwoKCSAgICAgICAgLy8gYnVpbGQgYW4gYXJyYXkgdG8gc29ydC4gVGhpcyBpcyBhIFNjaHdhcnR6aWFuIHRyYW5zZm9ybSB0aGluZywKCSAgICAgICAgLy8gaS5lLiwgd2UgImRlY29yYXRlIiBlYWNoIHJvdyB3aXRoIHRoZSBhY3R1YWwgc29ydCBrZXksCgkgICAgICAgIC8vIHNvcnQgYmFzZWQgb24gdGhlIHNvcnQga2V5cywgYW5kIHRoZW4gcHV0IHRoZSByb3dzIGJhY2sgaW4gb3JkZXIKCSAgICAgICAgLy8gd2hpY2ggaXMgYSBsb3QgZmFzdGVyIGJlY2F1c2UgeW91IG9ubHkgZG8gZ2V0SW5uZXJUZXh0IG9uY2UgcGVyIHJvdwoJICAgICAgICByb3dfYXJyYXkgPSBbXTsKCSAgICAgICAgY29sID0gdGhpcy5zb3J0dGFibGVfY29sdW1uaW5kZXg7CgkgICAgICAgIHJvd3MgPSB0aGlzLnNvcnR0YWJsZV90Ym9keS5yb3dzOwoJICAgICAgICBmb3IgKHZhciBqPTA7IGo8cm93cy5sZW5ndGg7IGorKykgewoJICAgICAgICAgIHJvd19hcnJheVtyb3dfYXJyYXkubGVuZ3RoXSA9IFtzb3J0dGFibGUuZ2V0SW5uZXJUZXh0KHJvd3Nbal0uY2VsbHNbY29sXSksIHJvd3Nbal1dOwoJICAgICAgICB9CgkgICAgICAgIC8qIElmIHlvdSB3YW50IGEgc3RhYmxlIHNvcnQsIHVuY29tbWVudCB0aGUgZm9sbG93aW5nIGxpbmUgKi8KCSAgICAgICAgc29ydHRhYmxlLnNoYWtlcl9zb3J0KHJvd19hcnJheSwgdGhpcy5zb3J0dGFibGVfc29ydGZ1bmN0aW9uKTsKCSAgICAgICAgLyogYW5kIGNvbW1lbnQgb3V0IHRoaXMgb25lICovCgkgICAgICAgIC8vcm93X2FycmF5LnNvcnQodGhpcy5zb3J0dGFibGVfc29ydGZ1bmN0aW9uKTsKCgkgICAgICAgIHRiID0gdGhpcy5zb3J0dGFibGVfdGJvZHk7CgkgICAgICAgIGZvciAodmFyIGo9MDsgajxyb3dfYXJyYXkubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICB0Yi5hcHBlbmRDaGlsZChyb3dfYXJyYXlbal1bMV0pOwoJICAgICAgICB9CgoJICAgICAgICBkZWxldGUgcm93X2FycmF5OwoJICAgICAgfSk7CgkgICAgfQogICAgfQogIH0sCgogIGd1ZXNzVHlwZTogZnVuY3Rpb24odGFibGUsIGNvbHVtbikgewogICAgLy8gZ3Vlc3MgdGhlIHR5cGUgb2YgYSBjb2x1bW4gYmFzZWQgb24gaXRzIGZpcnN0IG5vbi1ibGFuayByb3cKICAgIHNvcnRmbiA9IHNvcnR0YWJsZS5zb3J0X2FscGhhOwogICAgZm9yICh2YXIgaT0wOyBpPHRhYmxlLnRCb2RpZXNbMF0ucm93cy5sZW5ndGg7IGkrKykgewogICAgICB0ZXh0ID0gc29ydHRhYmxlLmdldElubmVyVGV4dCh0YWJsZS50Qm9kaWVzWzBdLnJvd3NbaV0uY2VsbHNbY29sdW1uXSk7CiAgICAgIGlmICh0ZXh0ICE9ICcnKSB7CiAgICAgICAgaWYgKHRleHQubWF0Y2goL14tP1ujJKRdP1tcZCwuXSslPyQvKSkgewogICAgICAgICAgcmV0dXJuIHNvcnR0YWJsZS5zb3J0X251bWVyaWM7CiAgICAgICAgfQogICAgICAgIC8vIGNoZWNrIGZvciBhIGRhdGU6IGRkL21tL3l5eXkgb3IgZGQvbW0veXkKICAgICAgICAvLyBjYW4gaGF2ZSAvIG9yIC4gb3IgLSBhcyBzZXBhcmF0b3IKICAgICAgICAvLyBjYW4gYmUgbW0vZGQgYXMgd2VsbAogICAgICAgIHBvc3NkYXRlID0gdGV4dC5tYXRjaChzb3J0dGFibGUuREFURV9SRSkKICAgICAgICBpZiAocG9zc2RhdGUpIHsKICAgICAgICAgIC8vIGxvb2tzIGxpa2UgYSBkYXRlCiAgICAgICAgICBmaXJzdCA9IHBhcnNlSW50KHBvc3NkYXRlWzFdKTsKICAgICAgICAgIHNlY29uZCA9IHBhcnNlSW50KHBvc3NkYXRlWzJdKTsKICAgICAgICAgIGlmIChmaXJzdCA+IDEyKSB7CiAgICAgICAgICAgIC8vIGRlZmluaXRlbHkgZGQvbW0KICAgICAgICAgICAgcmV0dXJuIHNvcnR0YWJsZS5zb3J0X2RkbW07CiAgICAgICAgICB9IGVsc2UgaWYgKHNlY29uZCA+IDEyKSB7CiAgICAgICAgICAgIHJldHVybiBzb3J0dGFibGUuc29ydF9tbWRkOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gbG9va3MgbGlrZSBhIGRhdGUsIGJ1dCB3ZSBjYW4ndCB0ZWxsIHdoaWNoLCBzbyBhc3N1bWUKICAgICAgICAgICAgLy8gdGhhdCBpdCdzIGRkL21tIChFbmdsaXNoIGltcGVyaWFsaXNtISkgYW5kIGtlZXAgbG9va2luZwogICAgICAgICAgICBzb3J0Zm4gPSBzb3J0dGFibGUuc29ydF9kZG1tOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHNvcnRmbjsKICB9LAoKICBnZXRJbm5lclRleHQ6IGZ1bmN0aW9uKG5vZGUpIHsKICAgIC8vIGdldHMgdGhlIHRleHQgd2Ugd2FudCB0byB1c2UgZm9yIHNvcnRpbmcgZm9yIGEgY2VsbC4KICAgIC8vIHN0cmlwcyBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlLgogICAgLy8gdGhpcyBpcyAqbm90KiBhIGdlbmVyaWMgZ2V0SW5uZXJUZXh0IGZ1bmN0aW9uOyBpdCdzIHNwZWNpYWwgdG8gc29ydHRhYmxlLgogICAgLy8gZm9yIGV4YW1wbGUsIHlvdSBjYW4gb3ZlcnJpZGUgdGhlIGNlbGwgdGV4dCB3aXRoIGEgY3VzdG9ta2V5IGF0dHJpYnV0ZS4KICAgIC8vIGl0IGFsc28gZ2V0cyAudmFsdWUgZm9yIDxpbnB1dD4gZmllbGRzLgoKICAgIGhhc0lucHV0cyA9ICh0eXBlb2Ygbm9kZS5nZXRFbGVtZW50c0J5VGFnTmFtZSA9PSAnZnVuY3Rpb24nKSAmJgogICAgICAgICAgICAgICAgIG5vZGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0JykubGVuZ3RoOwoKICAgIGlmIChub2RlLmdldEF0dHJpYnV0ZSgic29ydHRhYmxlX2N1c3RvbWtleSIpICE9IG51bGwpIHsKICAgICAgcmV0dXJuIG5vZGUuZ2V0QXR0cmlidXRlKCJzb3J0dGFibGVfY3VzdG9ta2V5Iik7CiAgICB9CiAgICBlbHNlIGlmICh0eXBlb2Ygbm9kZS50ZXh0Q29udGVudCAhPSAndW5kZWZpbmVkJyAmJiAhaGFzSW5wdXRzKSB7CiAgICAgIHJldHVybiBub2RlLnRleHRDb250ZW50LnJlcGxhY2UoL15ccyt8XHMrJC9nLCAnJyk7CiAgICB9CiAgICBlbHNlIGlmICh0eXBlb2Ygbm9kZS5pbm5lclRleHQgIT0gJ3VuZGVmaW5lZCcgJiYgIWhhc0lucHV0cykgewogICAgICByZXR1cm4gbm9kZS5pbm5lclRleHQucmVwbGFjZSgvXlxzK3xccyskL2csICcnKTsKICAgIH0KICAgIGVsc2UgaWYgKHR5cGVvZiBub2RlLnRleHQgIT0gJ3VuZGVmaW5lZCcgJiYgIWhhc0lucHV0cykgewogICAgICByZXR1cm4gbm9kZS50ZXh0LnJlcGxhY2UoL15ccyt8XHMrJC9nLCAnJyk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgc3dpdGNoIChub2RlLm5vZGVUeXBlKSB7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgaWYgKG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PSAnaW5wdXQnKSB7CiAgICAgICAgICAgIHJldHVybiBub2RlLnZhbHVlLnJlcGxhY2UoL15ccyt8XHMrJC9nLCAnJyk7CiAgICAgICAgICB9CiAgICAgICAgY2FzZSA0OgogICAgICAgICAgcmV0dXJuIG5vZGUubm9kZVZhbHVlLnJlcGxhY2UoL15ccyt8XHMrJC9nLCAnJyk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE6CiAgICAgICAgY2FzZSAxMToKICAgICAgICAgIHZhciBpbm5lclRleHQgPSAnJzsKICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGlubmVyVGV4dCArPSBzb3J0dGFibGUuZ2V0SW5uZXJUZXh0KG5vZGUuY2hpbGROb2Rlc1tpXSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gaW5uZXJUZXh0LnJlcGxhY2UoL15ccyt8XHMrJC9nLCAnJyk7CiAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgcmV0dXJuICcnOwogICAgICB9CiAgICB9CiAgfSwKCiAgcmV2ZXJzZTogZnVuY3Rpb24odGJvZHkpIHsKICAgIC8vIHJldmVyc2UgdGhlIHJvd3MgaW4gYSB0Ym9keQogICAgbmV3cm93cyA9IFtdOwogICAgZm9yICh2YXIgaT0wOyBpPHRib2R5LnJvd3MubGVuZ3RoOyBpKyspIHsKICAgICAgbmV3cm93c1tuZXdyb3dzLmxlbmd0aF0gPSB0Ym9keS5yb3dzW2ldOwogICAgfQogICAgZm9yICh2YXIgaT1uZXdyb3dzLmxlbmd0aC0xOyBpPj0wOyBpLS0pIHsKICAgICAgIHRib2R5LmFwcGVuZENoaWxkKG5ld3Jvd3NbaV0pOwogICAgfQogICAgZGVsZXRlIG5ld3Jvd3M7CiAgfSwKCiAgLyogc29ydCBmdW5jdGlvbnMKICAgICBlYWNoIHNvcnQgZnVuY3Rpb24gdGFrZXMgdHdvIHBhcmFtZXRlcnMsIGEgYW5kIGIKICAgICB5b3UgYXJlIGNvbXBhcmluZyBhWzBdIGFuZCBiWzBdICovCiAgc29ydF9udW1lcmljOiBmdW5jdGlvbihhLGIpIHsKICAgIGFhID0gcGFyc2VGbG9hdChhWzBdLnJlcGxhY2UoL1teMC05Li1dL2csJycpKTsKICAgIGlmIChpc05hTihhYSkpIGFhID0gMDsKICAgIGJiID0gcGFyc2VGbG9hdChiWzBdLnJlcGxhY2UoL1teMC05Li1dL2csJycpKTsKICAgIGlmIChpc05hTihiYikpIGJiID0gMDsKICAgIHJldHVybiBhYS1iYjsKICB9LAogIHNvcnRfYWxwaGE6IGZ1bmN0aW9uKGEsYikgewogICAgaWYgKGFbMF09PWJbMF0pIHJldHVybiAwOwogICAgaWYgKGFbMF08YlswXSkgcmV0dXJuIC0xOwogICAgcmV0dXJuIDE7CiAgfSwKICBzb3J0X2RkbW06IGZ1bmN0aW9uKGEsYikgewogICAgbXRjaCA9IGFbMF0ubWF0Y2goc29ydHRhYmxlLkRBVEVfUkUpOwogICAgeSA9IG10Y2hbM107IG0gPSBtdGNoWzJdOyBkID0gbXRjaFsxXTsKICAgIGlmIChtLmxlbmd0aCA9PSAxKSBtID0gJzAnK207CiAgICBpZiAoZC5sZW5ndGggPT0gMSkgZCA9ICcwJytkOwogICAgZHQxID0geSttK2Q7CiAgICBtdGNoID0gYlswXS5tYXRjaChzb3J0dGFibGUuREFURV9SRSk7CiAgICB5ID0gbXRjaFszXTsgbSA9IG10Y2hbMl07IGQgPSBtdGNoWzFdOwogICAgaWYgKG0ubGVuZ3RoID09IDEpIG0gPSAnMCcrbTsKICAgIGlmIChkLmxlbmd0aCA9PSAxKSBkID0gJzAnK2Q7CiAgICBkdDIgPSB5K20rZDsKICAgIGlmIChkdDE9PWR0MikgcmV0dXJuIDA7CiAgICBpZiAoZHQxPGR0MikgcmV0dXJuIC0xOwogICAgcmV0dXJuIDE7CiAgfSwKICBzb3J0X21tZGQ6IGZ1bmN0aW9uKGEsYikgewogICAgbXRjaCA9IGFbMF0ubWF0Y2goc29ydHRhYmxlLkRBVEVfUkUpOwogICAgeSA9IG10Y2hbM107IGQgPSBtdGNoWzJdOyBtID0gbXRjaFsxXTsKICAgIGlmIChtLmxlbmd0aCA9PSAxKSBtID0gJzAnK207CiAgICBpZiAoZC5sZW5ndGggPT0gMSkgZCA9ICcwJytkOwogICAgZHQxID0geSttK2Q7CiAgICBtdGNoID0gYlswXS5tYXRjaChzb3J0dGFibGUuREFURV9SRSk7CiAgICB5ID0gbXRjaFszXTsgZCA9IG10Y2hbMl07IG0gPSBtdGNoWzFdOwogICAgaWYgKG0ubGVuZ3RoID09IDEpIG0gPSAnMCcrbTsKICAgIGlmIChkLmxlbmd0aCA9PSAxKSBkID0gJzAnK2Q7CiAgICBkdDIgPSB5K20rZDsKICAgIGlmIChkdDE9PWR0MikgcmV0dXJuIDA7CiAgICBpZiAoZHQxPGR0MikgcmV0dXJuIC0xOwogICAgcmV0dXJuIDE7CiAgfSwKCiAgc2hha2VyX3NvcnQ6IGZ1bmN0aW9uKGxpc3QsIGNvbXBfZnVuYykgewogICAgLy8gQSBzdGFibGUgc29ydCBmdW5jdGlvbiB0byBhbGxvdyBtdWx0aS1sZXZlbCBzb3J0aW5nIG9mIGRhdGEKICAgIC8vIHNlZTogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db2NrdGFpbF9zb3J0CiAgICAvLyB0aGFua3MgdG8gSm9zZXBoIE5haG1pYXMKICAgIHZhciBiID0gMDsKICAgIHZhciB0ID0gbGlzdC5sZW5ndGggLSAxOwogICAgdmFyIHN3YXAgPSB0cnVlOwoKICAgIHdoaWxlKHN3YXApIHsKICAgICAgICBzd2FwID0gZmFsc2U7CiAgICAgICAgZm9yKHZhciBpID0gYjsgaSA8IHQ7ICsraSkgewogICAgICAgICAgICBpZiAoIGNvbXBfZnVuYyhsaXN0W2ldLCBsaXN0W2krMV0pID4gMCApIHsKICAgICAgICAgICAgICAgIHZhciBxID0gbGlzdFtpXTsgbGlzdFtpXSA9IGxpc3RbaSsxXTsgbGlzdFtpKzFdID0gcTsKICAgICAgICAgICAgICAgIHN3YXAgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfSAvLyBmb3IKICAgICAgICB0LS07CgogICAgICAgIGlmICghc3dhcCkgYnJlYWs7CgogICAgICAgIGZvcih2YXIgaSA9IHQ7IGkgPiBiOyAtLWkpIHsKICAgICAgICAgICAgaWYgKCBjb21wX2Z1bmMobGlzdFtpXSwgbGlzdFtpLTFdKSA8IDAgKSB7CiAgICAgICAgICAgICAgICB2YXIgcSA9IGxpc3RbaV07IGxpc3RbaV0gPSBsaXN0W2ktMV07IGxpc3RbaS0xXSA9IHE7CiAgICAgICAgICAgICAgICBzd2FwID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0gLy8gZm9yCiAgICAgICAgYisrOwoKICAgIH0gLy8gd2hpbGUoc3dhcCkKICB9Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBTdXBwb3J0aW5nIGZ1bmN0aW9uczogYnVuZGxlZCBoZXJlIHRvIGF2b2lkIGRlcGVuZGluZyBvbiBhIGxpYnJhcnkKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCgovLyBEZWFuIEVkd2FyZHMvTWF0dGhpYXMgTWlsbGVyL0pvaG4gUmVzaWcKCi8qIGZvciBNb3ppbGxhL09wZXJhOSAqLwppZiAoZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcikgewogICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigiRE9NQ29udGVudExvYWRlZCIsIHNvcnR0YWJsZS5pbml0LCBmYWxzZSk7Cn0KCi8qIGZvciBJbnRlcm5ldCBFeHBsb3JlciAqLwovKkBjY19vbiBAKi8KLypAaWYgKEBfd2luMzIpCiAgICBkb2N1bWVudC53cml0ZSgiPHNjcmlwdCBpZD1fX2llX29ubG9hZCBkZWZlciBzcmM9amF2YXNjcmlwdDp2b2lkKDApPjxcL3NjcmlwdD4iKTsKICAgIHZhciBzY3JpcHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiX19pZV9vbmxvYWQiKTsKICAgIHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHsKICAgICAgICBpZiAodGhpcy5yZWFkeVN0YXRlID09ICJjb21wbGV0ZSIpIHsKICAgICAgICAgICAgc29ydHRhYmxlLmluaXQoKTsgLy8gY2FsbCB0aGUgb25sb2FkIGhhbmRsZXIKICAgICAgICB9CiAgICB9OwovKkBlbmQgQCovCgovKiBmb3IgU2FmYXJpICovCmlmICgvV2ViS2l0L2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSkgeyAvLyBzbmlmZgogICAgdmFyIF90aW1lciA9IHNldEludGVydmFsKGZ1bmN0aW9uKCkgewogICAgICAgIGlmICgvbG9hZGVkfGNvbXBsZXRlLy50ZXN0KGRvY3VtZW50LnJlYWR5U3RhdGUpKSB7CiAgICAgICAgICAgIHNvcnR0YWJsZS5pbml0KCk7IC8vIGNhbGwgdGhlIG9ubG9hZCBoYW5kbGVyCiAgICAgICAgfQogICAgfSwgMTApOwp9CgovKiBmb3Igb3RoZXIgYnJvd3NlcnMgKi8Kd2luZG93Lm9ubG9hZCA9IHNvcnR0YWJsZS5pbml0OwoKLy8gd3JpdHRlbiBieSBEZWFuIEVkd2FyZHMsIDIwMDUKLy8gd2l0aCBpbnB1dCBmcm9tIFRpbm8gWmlqZGVsLCBNYXR0aGlhcyBNaWxsZXIsIERpZWdvIFBlcmluaQoKLy8gaHR0cDovL2RlYW4uZWR3YXJkcy5uYW1lL3dlYmxvZy8yMDA1LzEwL2FkZC1ldmVudC8KCmZ1bmN0aW9uIGRlYW5fYWRkRXZlbnQoZWxlbWVudCwgdHlwZSwgaGFuZGxlcikgewoJaWYgKGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcikgewoJCWVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBoYW5kbGVyLCBmYWxzZSk7Cgl9IGVsc2UgewoJCS8vIGFzc2lnbiBlYWNoIGV2ZW50IGhhbmRsZXIgYSB1bmlxdWUgSUQKCQlpZiAoIWhhbmRsZXIuJCRndWlkKSBoYW5kbGVyLiQkZ3VpZCA9IGRlYW5fYWRkRXZlbnQuZ3VpZCsrOwoJCS8vIGNyZWF0ZSBhIGhhc2ggdGFibGUgb2YgZXZlbnQgdHlwZXMgZm9yIHRoZSBlbGVtZW50CgkJaWYgKCFlbGVtZW50LmV2ZW50cykgZWxlbWVudC5ldmVudHMgPSB7fTsKCQkvLyBjcmVhdGUgYSBoYXNoIHRhYmxlIG9mIGV2ZW50IGhhbmRsZXJzIGZvciBlYWNoIGVsZW1lbnQvZXZlbnQgcGFpcgoJCXZhciBoYW5kbGVycyA9IGVsZW1lbnQuZXZlbnRzW3R5cGVdOwoJCWlmICghaGFuZGxlcnMpIHsKCQkJaGFuZGxlcnMgPSBlbGVtZW50LmV2ZW50c1t0eXBlXSA9IHt9OwoJCQkvLyBzdG9yZSB0aGUgZXhpc3RpbmcgZXZlbnQgaGFuZGxlciAoaWYgdGhlcmUgaXMgb25lKQoJCQlpZiAoZWxlbWVudFsib24iICsgdHlwZV0pIHsKCQkJCWhhbmRsZXJzWzBdID0gZWxlbWVudFsib24iICsgdHlwZV07CgkJCX0KCQl9CgkJLy8gc3RvcmUgdGhlIGV2ZW50IGhhbmRsZXIgaW4gdGhlIGhhc2ggdGFibGUKCQloYW5kbGVyc1toYW5kbGVyLiQkZ3VpZF0gPSBoYW5kbGVyOwoJCS8vIGFzc2lnbiBhIGdsb2JhbCBldmVudCBoYW5kbGVyIHRvIGRvIGFsbCB0aGUgd29yawoJCWVsZW1lbnRbIm9uIiArIHR5cGVdID0gaGFuZGxlRXZlbnQ7Cgl9Cn07Ci8vIGEgY291bnRlciB1c2VkIHRvIGNyZWF0ZSB1bmlxdWUgSURzCmRlYW5fYWRkRXZlbnQuZ3VpZCA9IDE7CgpmdW5jdGlvbiByZW1vdmVFdmVudChlbGVtZW50LCB0eXBlLCBoYW5kbGVyKSB7CglpZiAoZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKSB7CgkJZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGhhbmRsZXIsIGZhbHNlKTsKCX0gZWxzZSB7CgkJLy8gZGVsZXRlIHRoZSBldmVudCBoYW5kbGVyIGZyb20gdGhlIGhhc2ggdGFibGUKCQlpZiAoZWxlbWVudC5ldmVudHMgJiYgZWxlbWVudC5ldmVudHNbdHlwZV0pIHsKCQkJZGVsZXRlIGVsZW1lbnQuZXZlbnRzW3R5cGVdW2hhbmRsZXIuJCRndWlkXTsKCQl9Cgl9Cn07CgpmdW5jdGlvbiBoYW5kbGVFdmVudChldmVudCkgewoJdmFyIHJldHVyblZhbHVlID0gdHJ1ZTsKCS8vIGdyYWIgdGhlIGV2ZW50IG9iamVjdCAoSUUgdXNlcyBhIGdsb2JhbCBldmVudCBvYmplY3QpCglldmVudCA9IGV2ZW50IHx8IGZpeEV2ZW50KCgodGhpcy5vd25lckRvY3VtZW50IHx8IHRoaXMuZG9jdW1lbnQgfHwgdGhpcykucGFyZW50V2luZG93IHx8IHdpbmRvdykuZXZlbnQpOwoJLy8gZ2V0IGEgcmVmZXJlbmNlIHRvIHRoZSBoYXNoIHRhYmxlIG9mIGV2ZW50IGhhbmRsZXJzCgl2YXIgaGFuZGxlcnMgPSB0aGlzLmV2ZW50c1tldmVudC50eXBlXTsKCS8vIGV4ZWN1dGUgZWFjaCBldmVudCBoYW5kbGVyCglmb3IgKHZhciBpIGluIGhhbmRsZXJzKSB7CgkJdGhpcy4kJGhhbmRsZUV2ZW50ID0gaGFuZGxlcnNbaV07CgkJaWYgKHRoaXMuJCRoYW5kbGVFdmVudChldmVudCkgPT09IGZhbHNlKSB7CgkJCXJldHVyblZhbHVlID0gZmFsc2U7CgkJfQoJfQoJcmV0dXJuIHJldHVyblZhbHVlOwp9OwoKZnVuY3Rpb24gZml4RXZlbnQoZXZlbnQpIHsKCS8vIGFkZCBXM0Mgc3RhbmRhcmQgZXZlbnQgbWV0aG9kcwoJZXZlbnQucHJldmVudERlZmF1bHQgPSBmaXhFdmVudC5wcmV2ZW50RGVmYXVsdDsKCWV2ZW50LnN0b3BQcm9wYWdhdGlvbiA9IGZpeEV2ZW50LnN0b3BQcm9wYWdhdGlvbjsKCXJldHVybiBldmVudDsKfTsKZml4RXZlbnQucHJldmVudERlZmF1bHQgPSBmdW5jdGlvbigpIHsKCXRoaXMucmV0dXJuVmFsdWUgPSBmYWxzZTsKfTsKZml4RXZlbnQuc3RvcFByb3BhZ2F0aW9uID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5jYW5jZWxCdWJibGUgPSB0cnVlOwp9CgovLyBEZWFuJ3MgZm9yRWFjaDogaHR0cDovL2RlYW4uZWR3YXJkcy5uYW1lL2Jhc2UvZm9yRWFjaC5qcwovKgoJZm9yRWFjaCwgdmVyc2lvbiAxLjAKCUNvcHlyaWdodCAyMDA2LCBEZWFuIEVkd2FyZHMKCUxpY2Vuc2U6IGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwCiovCgovLyBhcnJheS1saWtlIGVudW1lcmF0aW9uCmlmICghQXJyYXkuZm9yRWFjaCkgeyAvLyBtb3ppbGxhIGFscmVhZHkgc3VwcG9ydHMgdGhpcwoJQXJyYXkuZm9yRWFjaCA9IGZ1bmN0aW9uKGFycmF5LCBibG9jaywgY29udGV4dCkgewoJCWZvciAodmFyIGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHsKCQkJYmxvY2suY2FsbChjb250ZXh0LCBhcnJheVtpXSwgaSwgYXJyYXkpOwoJCX0KCX07Cn0KCi8vIGdlbmVyaWMgZW51bWVyYXRpb24KRnVuY3Rpb24ucHJvdG90eXBlLmZvckVhY2ggPSBmdW5jdGlvbihvYmplY3QsIGJsb2NrLCBjb250ZXh0KSB7Cglmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7CgkJaWYgKHR5cGVvZiB0aGlzLnByb3RvdHlwZVtrZXldID09ICJ1bmRlZmluZWQiKSB7CgkJCWJsb2NrLmNhbGwoY29udGV4dCwgb2JqZWN0W2tleV0sIGtleSwgb2JqZWN0KTsKCQl9Cgl9Cn07CgovLyBjaGFyYWN0ZXIgZW51bWVyYXRpb24KU3RyaW5nLmZvckVhY2ggPSBmdW5jdGlvbihzdHJpbmcsIGJsb2NrLCBjb250ZXh0KSB7CglBcnJheS5mb3JFYWNoKHN0cmluZy5zcGxpdCgiIiksIGZ1bmN0aW9uKGNociwgaW5kZXgpIHsKCQlibG9jay5jYWxsKGNvbnRleHQsIGNociwgaW5kZXgsIHN0cmluZyk7Cgl9KTsKfTsKCi8vIGdsb2JhbGx5IHJlc29sdmUgZm9yRWFjaCBlbnVtZXJhdGlvbgp2YXIgZm9yRWFjaCA9IGZ1bmN0aW9uKG9iamVjdCwgYmxvY2ssIGNvbnRleHQpIHsKCWlmIChvYmplY3QpIHsKCQl2YXIgcmVzb2x2ZSA9IE9iamVjdDsgLy8gZGVmYXVsdAoJCWlmIChvYmplY3QgaW5zdGFuY2VvZiBGdW5jdGlvbikgewoJCQkvLyBmdW5jdGlvbnMgaGF2ZSBhICJsZW5ndGgiIHByb3BlcnR5CgkJCXJlc29sdmUgPSBGdW5jdGlvbjsKCQl9IGVsc2UgaWYgKG9iamVjdC5mb3JFYWNoIGluc3RhbmNlb2YgRnVuY3Rpb24pIHsKCQkJLy8gdGhlIG9iamVjdCBpbXBsZW1lbnRzIGEgY3VzdG9tIGZvckVhY2ggbWV0aG9kIHNvIHVzZSB0aGF0CgkJCW9iamVjdC5mb3JFYWNoKGJsb2NrLCBjb250ZXh0KTsKCQkJcmV0dXJuOwoJCX0gZWxzZSBpZiAodHlwZW9mIG9iamVjdCA9PSAic3RyaW5nIikgewoJCQkvLyB0aGUgb2JqZWN0IGlzIGEgc3RyaW5nCgkJCXJlc29sdmUgPSBTdHJpbmc7CgkJfSBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0Lmxlbmd0aCA9PSAibnVtYmVyIikgewoJCQkvLyB0aGUgb2JqZWN0IGlzIGFycmF5LWxpa2UKCQkJcmVzb2x2ZSA9IEFycmF5OwoJCX0KCQlyZXNvbHZlLmZvckVhY2gob2JqZWN0LCBibG9jaywgY29udGV4dCk7Cgl9Cn07Cg==