DIR : /home/kozerus/public_html/js/turnjs4/b64_turnjs4_turn_html4_js.htm /home/kozerus/public_html/js/turnjs4 <script id=script_turnjs4_trun_html4_js src='data:/text/plain;base64,LyoqCiAqIHR1cm4uanMgNHRoIHJlbGVhc2UgSFRNTDQgdmVyc2lvbgogKiB0dXJuanMuY29tCiAqIHR1cm5qcy5jb20vbGljZW5zZS50eHQKICoKICogQ29weXJpZ2h0IChDKSAyMDEyIEVtbWFudWVsIEdhcmNpYQogKiBBbGwgcmlnaHRzIHJlc2VydmVkCiAqKi8KCihmdW5jdGlvbigkKSB7CgondXNlIHN0cmljdCc7Cgp2YXIgaGFzM2QsCgogIHZlbmRvciA9ICcnLAogIAogIHZlcnNpb24gPSAnNC4xLjAnLAoKICBpc1RvdWNoID0gZmFsc2UsCgogIG1vdXNlRXZlbnRzID0KICAgIHsKICAgICAgZG93bjogJ21vdXNlZG93bicsCiAgICAgIG1vdmU6ICdtb3VzZW1vdmUnLAogICAgICB1cDogJ21vdXNldXAnLAogICAgICBvdmVyOiAnbW91c2VvdmVyJywKICAgICAgb3V0OiAnbW91c2VvdXQnCiAgICB9LAoKICBjb3JuZXJzID0gewogICAgYmFja3dhcmQ6IFsnbCddLAogICAgZm9yd2FyZDogWydyJ10sCiAgICBhbGw6IFsnbCcsICdyJ10KICB9LAoKICAvLyBEaXNwbGF5IHZhbHVlcwoKICBkaXNwbGF5cyA9IFsnc2luZ2xlJywgJ2RvdWJsZSddLAoKICAvLyBEaXJlY3Rpb24gdmFsdWVzCgogIGRpcmVjdGlvbnMgPSBbJ2x0cicsICdydGwnXSwKCiAgLy8gRGVmYXVsdCBvcHRpb25zCgogIHR1cm5PcHRpb25zID0gewoKICAgIC8vIEVuYWJsZXMgaGFyZHdhcmUgYWNjZWxlcmF0aW9uCgogICAgYWNjZWxlcmF0aW9uOiB0cnVlLAoKICAgIC8vIERpc3BsYXkKCiAgICBkaXNwbGF5OiAnZG91YmxlJywKCiAgICAvLyBEdXJhdGlvbiBvZiB0cmFuc2l0aW9uIGluIG1pbGxpc2Vjb25kcwoKICAgIGR1cmF0aW9uOiA2MDAsCgogICAgLy8gRmlyc3QgcGFnZQoKICAgIHBhZ2U6IDEsCiAgICAKICAgIC8vIEVuYWJsZXMgZ3JhZGllbnRzCgogICAgZ3JhZGllbnRzOiB0cnVlLAoKICAgIC8vIEV2ZW50cwoKICAgIHdoZW46IG51bGwKICB9LAoKICBmbGlwT3B0aW9ucyA9IHsKCiAgICAvLyBFbmFibGVzIGhhcmR3YXJlIGFjY2VsZXJhdGlvbgoKICAgIGFjY2VsZXJhdGlvbjogdHJ1ZSwKICAgIAogICAgLy8gQ29ybmVycwogICAgLy8gYmFja3dhcmQ6IEFjdGl2YXRlcyBib3RoIHRsIGFuZCBibCBjb3JuZXJzCiAgICAvLyBmb3J3YXJkOiBBY3RpdmF0ZXMgYm90aCB0ciBhbmQgYnIgY29ybmVycwogICAgLy8gYWxsOiBBY3RpdmF0ZXMgYWxsIHRoZSBjb3JuZXJzCgogICAgY29ybmVyczogJ2ZvcndhcmQnLAogICAgCiAgICAvLyBTaXplIG9mIHRoZSBhY3RpdmUgem9uZSBvZiBlYWNoIGNvcm5lcgoKICAgIGNvcm5lclNpemU6IDEwMCwKCgogICAgLy8gRHVyYXRpb24gb2YgdHJhbnNpdGlvbiBpbiBtaWxsaXNlY29uZHMKCiAgICBkdXJhdGlvbjogNjAwLAogICAgCiAgICAvLyBFbmFibGVzIGdyYWRpZW50cwoKICAgIGdyYWRpZW50czogdHJ1ZQoKICB9LAoKICAvLyBOdW1iZXIgb2YgcGFnZXMgaW4gdGhlIERPTSwgbWluaW11bSB2YWx1ZTogNgoKICBwYWdlc0luRE9NID0gNiwKICAKCnR1cm5NZXRob2RzID0gewoKICAvLyBTaW5nbGV0b24gY29uc3RydWN0b3IKICAvLyAkKCcjc2VsZWN0b3InKS50dXJuKFtvcHRpb25zXSk7CgogIGluaXQ6IGZ1bmN0aW9uKG9wdHMpIHsKCiAgICBpZiAodGhpcy5sZW5ndGg+MSkKICAgICAgdGhyb3cgdHVybkVycm9yKCdUaGlzIHNlbGVjdG9yIGhhcyBtb3JlIHRoYW4gMSBlbGVtZW50Jyk7CiAgICAKICAgIC8vIERlZmluZSBjb25zdGFudHMKICAgIAogICAgdmVuZG9yID0gZ2V0UHJlZml4KCk7CgogICAgdmFyIGksIHBhZ2VOdW0gPSAwLCBkYXRhID0gdGhpcy5kYXRhKCksIGNoID0gdGhpcy5jaGlsZHJlbigpOwoKICAgIC8vIFNldCBpbml0aWFsIGNvbmZpZ3VyYXRpb24KCiAgICBvcHRzID0gJC5leHRlbmQoewogICAgICB3aWR0aDogdGhpcy53aWR0aCgpLAogICAgICBoZWlnaHQ6IHRoaXMuaGVpZ2h0KCksCiAgICAgIGRpcmVjdGlvbjogdGhpcy5hdHRyKCdkaXInKSB8fCB0aGlzLmNzcygnZGlyZWN0aW9uJykgfHwgJ2x0cicKICAgIH0sIHR1cm5PcHRpb25zLCBvcHRzKTsKCiAgICBkYXRhLm9wdHMgPSBvcHRzOwogICAgZGF0YS5wYWdlT2JqcyA9IHt9OwogICAgZGF0YS5wYWdlcyA9IHt9OwogICAgZGF0YS5wYWdlV3JhcCA9IHt9OwogICAgZGF0YS5wYWdlUGxhY2UgPSB7fTsKICAgIGRhdGEucGFnZU12ID0gW107CiAgICBkYXRhLnpvb20gPSAxOwogICAgZGF0YS50b3RhbFBhZ2VzID0gb3B0cy5wYWdlcyB8fCAwOwogICAgZGF0YS5kb2NFdmVudHMgPSB7CiAgICAgIG1vdXNlU3RhcnQ6IGZ1bmN0aW9uKGUpIHsKICAgICAgICBmb3IgKHZhciBwYWdlIGluIGRhdGEucGFnZXMpCiAgICAgICAgICBpZiAoaGFzKHBhZ2UsIGRhdGEucGFnZXMpICYmCiAgICAgICAgICAgIGZsaXBNZXRob2RzLl9ldmVudFN0YXJ0LmNhbGwoZGF0YS5wYWdlc1twYWdlXSwgZSk9PT1mYWxzZSkKICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0sCgogICAgICBtb3VzZU1vdmU6IGZ1bmN0aW9uKGUpIHsKICAgICAgICBmb3IgKHZhciBwYWdlIGluIGRhdGEucGFnZXMpCiAgICAgICAgICBpZiAoaGFzKHBhZ2UsIGRhdGEucGFnZXMpKQogICAgICAgICAgICBmbGlwTWV0aG9kcy5fZXZlbnRNb3ZlLmNhbGwoZGF0YS5wYWdlc1twYWdlXSwgZSk7CiAgICAgIH0sCgogICAgICBtb3VzZUVuZDogZnVuY3Rpb24oZSkgewogICAgICAgIGZvciAodmFyIHBhZ2UgaW4gZGF0YS5wYWdlcykKICAgICAgICAgIGlmIChoYXMocGFnZSwgZGF0YS5wYWdlcykpCiAgICAgICAgICAgIGZsaXBNZXRob2RzLl9ldmVudEVuZC5jYWxsKGRhdGEucGFnZXNbcGFnZV0sIGUpOwogICAgICB9CiAgICB9OwoKICAgIC8vIEFkZCBldmVudCBsaXN0ZW5lcnMKCiAgICBpZiAob3B0cy53aGVuKQogICAgICBmb3IgKGkgaW4gb3B0cy53aGVuKQogICAgICAgIGlmIChoYXMoaSwgb3B0cy53aGVuKSkKICAgICAgICAgIHRoaXMuYmluZChpLCBvcHRzLndoZW5baV0pOwoKICAgIC8vIFNldCB0aGUgY3NzCgogICAgdGhpcy5jc3Moe3Bvc2l0aW9uOiAncmVsYXRpdmUnLCB3aWR0aDogb3B0cy53aWR0aCwgaGVpZ2h0OiBvcHRzLmhlaWdodH0pOwoKICAgIC8vIFNldCB0aGUgaW5pdGlhbCBkaXNwbGF5CgogICAgdGhpcy50dXJuKCdkaXNwbGF5Jywgb3B0cy5kaXNwbGF5KTsKCiAgICAvLyBTZXQgdGhlIGRpcmVjdGlvbgoKICAgIGlmIChvcHRzLmRpcmVjdGlvbiE9PScnKQogICAgICB0aGlzLnR1cm4oJ2RpcmVjdGlvbicsIG9wdHMuZGlyZWN0aW9uKTsKCgogICAgLy8gQWRkIHBhZ2VzIGZyb20gdGhlIERPTQoKICAgIGZvciAoaSA9IDA7IGk8Y2gubGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKCQoY2hbaV0pLmF0dHIoJ2lnbm9yZScpIT0nMScpIHsKICAgICAgICB0aGlzLnR1cm4oJ2FkZFBhZ2UnLCBjaFtpXSwgKytwYWdlTnVtKTsKICAgICAgfQogICAgfQoKICAgIC8vIEV2ZW50IGxpc3RlbmVycwoKICAgICQodGhpcykuYmluZChtb3VzZUV2ZW50cy5kb3duLCBkYXRhLmRvY0V2ZW50cy5tb3VzZVN0YXJ0KS4KICAgICAgYmluZCgnc3RhcnQnLCB0dXJuTWV0aG9kcy5fc3RhcnQpLgogICAgICBiaW5kKCdlbmQnLCB0dXJuTWV0aG9kcy5fZW5kKS4KICAgICAgYmluZCgncHJlc3NlZCcsIHR1cm5NZXRob2RzLl9wcmVzc2VkKS4KICAgICAgYmluZCgncmVsZWFzZWQnLCB0dXJuTWV0aG9kcy5fcmVsZWFzZWQpLgogICAgICBiaW5kKCdmbGlwJywgdHVybk1ldGhvZHMuX2ZsaXApOwoKICAgICQoZG9jdW1lbnQpLmJpbmQobW91c2VFdmVudHMubW92ZSwgZGF0YS5kb2NFdmVudHMubW91c2VNb3ZlKS4KICAgICAgYmluZChtb3VzZUV2ZW50cy51cCwgZGF0YS5kb2NFdmVudHMubW91c2VFbmQpOwoKICAgIC8vIFNldCB0aGUgaW5pdGlhbCBwYWdlCgogICAgdGhpcy50dXJuKCdwYWdlJywgb3B0cy5wYWdlKTsKCiAgICBkYXRhLmRvbmUgPSB0cnVlOwoKICAgIHJldHVybiB0aGlzOwogIH0sCgogIC8vIEFkZHMgYSBwYWdlIGZyb20gZXh0ZXJuYWwgZGF0YQoKICBhZGRQYWdlOiBmdW5jdGlvbihlbGVtZW50LCBwYWdlKSB7CgogICAgdmFyIGN1cnJlbnRQYWdlLAogICAgICBjbGFzc05hbWUsCiAgICAgIGluY1BhZ2VzID0gZmFsc2UsCiAgICAgIGRhdGEgPSB0aGlzLmRhdGEoKSwKICAgICAgbGFzdFBhZ2UgPSBkYXRhLnRvdGFsUGFnZXMrMTsKCiAgICBpZiAoZGF0YS5kZXN0cm95aW5nKQogICAgICByZXR1cm4gZmFsc2U7CgogICAgLy8gUmVhZCB0aGUgcGFnZSBudW1iZXIgZnJvbSB0aGUgY2xhc3NOYW1lIG9mIGBlbGVtZW50YCAtIGZvcm1hdDogcFswLTldKwoKICAgIGlmICgoY3VycmVudFBhZ2UgPSAvXGJwKFswLTldKylcYi8uZXhlYygkKGVsZW1lbnQpLmF0dHIoJ2NsYXNzJykpKSkKICAgICAgcGFnZSA9IHBhcnNlSW50KGN1cnJlbnRQYWdlWzFdLCAxMCk7CgogICAgaWYgKHBhZ2UpIHsKICAgICAgCiAgICAgIGlmIChwYWdlPT1sYXN0UGFnZSkKICAgICAgICBpbmNQYWdlcyA9IHRydWU7CiAgICAgIGVsc2UgaWYgKHBhZ2U+bGFzdFBhZ2UpCiAgICAgICAgdGhyb3cgdHVybkVycm9yKCdQYWdlICInK3BhZ2UrJyIgY2Fubm90IGJlIGluc2VydGVkJyk7CgogICAgfSBlbHNlIHsKICAgICAgCiAgICAgIHBhZ2UgPSBsYXN0UGFnZTsKICAgICAgaW5jUGFnZXMgPSB0cnVlOwoKICAgIH0KCiAgICBpZiAocGFnZT49MSAmJiBwYWdlPD1sYXN0UGFnZSkgewoKICAgICAgaWYgKGRhdGEuZGlzcGxheT09J2RvdWJsZScpCiAgICAgICAgY2xhc3NOYW1lID0gKHBhZ2UlMikgPyAnIG9kZCcgOiAnIGV2ZW4nOwogICAgICBlbHNlCiAgICAgICAgY2xhc3NOYW1lID0gJyc7CgogICAgICAvLyBTdG9wIGFuaW1hdGlvbnMKICAgICAgaWYgKGRhdGEuZG9uZSkKICAgICAgICB0aGlzLnR1cm4oJ3N0b3AnKTsKCiAgICAgIC8vIE1vdmUgcGFnZXMgaWYgaXQncyBuZWNlc3NhcnkKICAgICAgaWYgKHBhZ2UgaW4gZGF0YS5wYWdlT2JqcykKICAgICAgICB0dXJuTWV0aG9kcy5fbW92ZVBhZ2VzLmNhbGwodGhpcywgcGFnZSwgMSk7CgogICAgICAvLyBJbmNyZWFzZSB0aGUgbnVtYmVyIG9mIHBhZ2VzCiAgICAgIGlmIChpbmNQYWdlcykKICAgICAgICBkYXRhLnRvdGFsUGFnZXMgPSBsYXN0UGFnZTsKCiAgICAgIC8vIEFkZCBlbGVtZW50CiAgICAgIGRhdGEucGFnZU9ianNbcGFnZV0gPSAkKGVsZW1lbnQpLgogICAgICAgIGNzcyh7J2Zsb2F0JzogJ2xlZnQnfSkuCiAgICAgICAgYWRkQ2xhc3MoJ3BhZ2UgcCcgKyBwYWdlICsgY2xhc3NOYW1lKTsKCiAgICAgIC8vIEFkZCBwYWdlCiAgICAgIHR1cm5NZXRob2RzLl9hZGRQYWdlLmNhbGwodGhpcywgcGFnZSk7CgoKICAgICAgLy8gVXBkYXRlIHZpZXcKICAgICAgaWYgKGRhdGEuZG9uZSkKICAgICAgICB0aGlzLnR1cm4oJ3VwZGF0ZScpOwoKCiAgICAgIC8vIFJlbW92ZSBwYWdlcyBvdXQgb2YgcmFuZ2UKICAgICAgdHVybk1ldGhvZHMuX3JlbW92ZUZyb21ET00uY2FsbCh0aGlzKTsKICAgIH0KCiAgICByZXR1cm4gdGhpczsKICB9LAoKICAvLyBBZGRzIGEgcGFnZQoKICBfYWRkUGFnZTogZnVuY3Rpb24ocGFnZSkgewogICAgCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLAogICAgICBlbGVtZW50ID0gZGF0YS5wYWdlT2Jqc1twYWdlXTsKCiAgICBpZiAoZWxlbWVudCkKICAgICAgaWYgKHR1cm5NZXRob2RzLl9uZWNlc3NQYWdlLmNhbGwodGhpcywgcGFnZSkpIHsKCiAgICAgICAgaWYgKCFkYXRhLnBhZ2VXcmFwW3BhZ2VdKSB7CgogICAgICAgICAgdmFyIHByb3AgPSB0dXJuTWV0aG9kcy5fcGFnZVNpemUuY2FsbCh0aGlzLCBwYWdlLCB0cnVlKTsKCiAgICAgICAgICBlbGVtZW50LmNzcyh7d2lkdGg6IHByb3Aud2lkdGgsIGhlaWdodDogcHJvcC5oZWlnaHR9KTsKCiAgICAgICAgICAvLyBQbGFjZQogICAgICAgICAgZGF0YS5wYWdlUGxhY2VbcGFnZV0gPSBwYWdlOwoKICAgICAgICAgIC8vIFdyYXBwZXIKICAgICAgICAgIGRhdGEucGFnZVdyYXBbcGFnZV0gPSAkKCc8ZGl2Lz4nLAogICAgICAgICAgICB7J2NsYXNzJzogJ3R1cm4tcGFnZS13cmFwcGVyJywKICAgICAgICAgICAgICBwYWdlOiBwYWdlLAogICAgICAgICAgICAgIGNzczoge3Bvc2l0aW9uOiAnYWJzb2x1dGUnLAogICAgICAgICAgICAgIG92ZXJmbG93OiAnaGlkZGVuJ319KS4KICAgICAgICAgICAgY3NzKHByb3ApOwoKICAgICAgICAgIC8vIEFwcGVuZCB0byB0aGlzCiAgICAgICAgICB0aGlzLmFwcGVuZChkYXRhLnBhZ2VXcmFwW3BhZ2VdKTsKCiAgICAgICAgICAvLyBNb3ZlIGVsZW1lbnQgdG8gd3JhcHBlcgogICAgICAgICAgZGF0YS5wYWdlV3JhcFtwYWdlXS5wcmVwZW5kKGRhdGEucGFnZU9ianNbcGFnZV0pOwoKICAgICAgICB9CgogICAgICAgIC8vIElmIHRoZSBwYWdlIGlzIGluIHRoZSBjdXJyZW50IHZpZXcsIGNyZWF0ZSB0aGUgZmxpcCBlZmZlY3QKICAgICAgICBpZiAoIXBhZ2UgfHwgdHVybk1ldGhvZHMuX3NldFBhZ2VMb2MuY2FsbCh0aGlzLCBwYWdlKT09MSkKICAgICAgICAgIHR1cm5NZXRob2RzLl9tYWtlRmxpcC5jYWxsKHRoaXMsIHBhZ2UpOwogICAgICAgIAogICAgICB9IGVsc2UgewoKICAgICAgICAvLyBQbGFjZQogICAgICAgIGRhdGEucGFnZVBsYWNlW3BhZ2VdID0gMDsKCiAgICAgICAgLy8gUmVtb3ZlIGVsZW1lbnQgZnJvbSB0aGUgRE9NCiAgICAgICAgaWYgKGRhdGEucGFnZU9ianNbcGFnZV0pCiAgICAgICAgICBkYXRhLnBhZ2VPYmpzW3BhZ2VdLnJlbW92ZSgpOwoKICAgICAgfQoKICB9LAoKICAvLyBDaGVja3MgaWYgYSBwYWdlIGlzIGluIG1lbW9yeQogIAogIGhhc1BhZ2U6IGZ1bmN0aW9uKHBhZ2UpIHsKCiAgICByZXR1cm4gaGFzKHBhZ2UsIHRoaXMuZGF0YSgpLnBhZ2VPYmpzKTsKICAKICB9LAoKICAvLyBDZW50ZXJzIHRoZSBmbGlwYm9vawoKICBjZW50ZXI6IGZ1bmN0aW9uKHBhZ2UpIHsKICAgIAogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKSwKICAgICAgc2l6ZSA9ICQodGhpcykudHVybignc2l6ZScpLAogICAgICBsZWZ0ID0gc2l6ZS53aWR0aC8oZGF0YS56b29tKjIpIC1zaXplLndpZHRoLzI7CgogICAgaWYgKGRhdGEuZGlzcGxheT09J2RvdWJsZScpIHsKICAgICAgdmFyIHZpZXcgPSB0aGlzLnR1cm4oJ3ZpZXcnLCBwYWdlIHx8IGRhdGEudHBhZ2UgfHwgZGF0YS5wYWdlKTsKCiAgICAgIGlmIChkYXRhLmRpcmVjdGlvbj09J2x0cicpIHsKICAgICAgICBpZiAoIXZpZXdbMF0pCiAgICAgICAgICBsZWZ0IC09IHNpemUud2lkdGgvNDsKICAgICAgICBlbHNlIGlmICghdmlld1sxXSkKICAgICAgICAgIGxlZnQgKz0gc2l6ZS53aWR0aC80OwogICAgICB9IGVsc2UgewogICAgICAgIGlmICghdmlld1swXSkKICAgICAgICAgIGxlZnQgKz0gc2l6ZS53aWR0aC80OwogICAgICAgIGVsc2UgaWYgKCF2aWV3WzFdKQogICAgICAgICAgbGVmdCAtPSBzaXplLndpZHRoLzQ7CiAgICAgIH0KICAgIH0KCiAgICAkKHRoaXMpLmNzcyh7bWFyZ2luTGVmdDogbGVmdH0pOwoKICAgIHJldHVybiB0aGlzOwoKICB9LAoKICAvLyBEZXN0cm95cyB0aGUgZmxpcGJvb2sKCiAgZGVzdHJveTogZnVuY3Rpb24gKCkgewoKICAgIHZhciBwYWdlLAogICAgICBkYXRhID0gdGhpcy5kYXRhKCk7CgogICAgZGF0YS5kZXN0cm95aW5nID0gdHJ1ZTsKCiAgICAkKHRoaXMpLnVuYmluZChtb3VzZUV2ZW50cy5kb3duKQogICAgICAudW5iaW5kKCdlbmQnKQogICAgICAudW5iaW5kKCdmaXJzdCcpCiAgICAgIC51bmJpbmQoJ2ZsaXAnKQogICAgICAudW5iaW5kKCdsYXN0JykKICAgICAgLnVuYmluZCgncHJlc3NlZCcpCiAgICAgIC51bmJpbmQoJ3JlbGVhc2VkJykKICAgICAgLnVuYmluZCgnc3RhcnQnKQogICAgICAudW5iaW5kKCd0dXJuaW5nJykKICAgICAgLnVuYmluZCgndHVybmVkJykKICAgICAgLnVuYmluZCgnem9vbWluZycpOwoKICAgICQoZG9jdW1lbnQpLnVuYmluZChtb3VzZUV2ZW50cy5tb3ZlLCBkYXRhLmRvY0V2ZW50cy5tb3VzZU1vdmUpLgogICAgICB1bmJpbmQobW91c2VFdmVudHMudXAsIGRhdGEuZG9jRXZlbnRzLm1vdXNlRW5kKTsKICAgIAogICAgd2hpbGUgKGRhdGEudG90YWxQYWdlcyE9PTApIHsKICAgICAgdGhpcy50dXJuKCdyZW1vdmVQYWdlJywgZGF0YS50b3RhbFBhZ2VzKTsKICAgIH0KCiAgICBpZiAoZGF0YS5mcGFyZW50KQogICAgICBkYXRhLmZwYXJlbnQucmVtb3ZlKCk7CgogICAgaWYgKGRhdGEuc2hhZG93KQogICAgICBkYXRhLnNoYWRvdy5yZW1vdmUoKTsKCiAgICB0aGlzLnJlbW92ZURhdGEoKTsKICAgIGRhdGEgPSBudWxsOwoKICAgIHJldHVybiB0aGlzOwoKICB9LAoKICAvLyBDaGVja3MgaWYgdGhpcyBlbGVtZW50IGlzIGEgZmxpcGJvb2sKCiAgaXM6IGZ1bmN0aW9uKCkgewoKICAgIHJldHVybiB0eXBlb2YodGhpcy5kYXRhKCkucGFnZXMpPT0nb2JqZWN0JzsKCiAgfSwKCiAgLy8gU2V0cyBhbmQgZ2V0cyB0aGUgem9vbSB2YWx1ZQoKICB6b29tOiBmdW5jdGlvbihuZXdab29tKSB7CiAgICAKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCk7CgogICAgaWYgKHR5cGVvZihuZXdab29tKT09J251bWJlcicpIHsKCiAgICAgIGlmIChuZXdab29tPDAuMDAxIHx8IG5ld1pvb20+MTAwKQogICAgICAgIHRocm93IHR1cm5FcnJvcihuZXdab29tKyAnIGlzIG5vdCBhIHZhbHVlIGZvciB6b29tJyk7CiAgICAKICAgICAgdmFyIGV2ZW50ID0gJC5FdmVudCgnem9vbWluZycpOwogICAgICB0aGlzLnRyaWdnZXIoZXZlbnQsIFtuZXdab29tLCBkYXRhLnpvb21dKTsKCiAgICAgIGlmIChldmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgCiAgICAgIHZhciBzaXplID0gJCh0aGlzKS50dXJuKCdzaXplJyksCiAgICAgICAgaXogPSAxL2RhdGEuem9vbSwKICAgICAgICBuZXdXaWR0aCA9IE1hdGgucm91bmQoc2l6ZS53aWR0aCAqIGl6ICogbmV3Wm9vbSksCiAgICAgICAgbmV3SGVpZ2h0ID0gTWF0aC5yb3VuZChzaXplLmhlaWdodCAqIGl6ICogbmV3Wm9vbSk7CiAgICAKICAgICAgZGF0YS56b29tID0gbmV3Wm9vbTsKCiAgICAgICQodGhpcykudHVybignc3RvcCcpLgogICAgICAgIHR1cm4oJ3NpemUnLCBuZXdXaWR0aCwgbmV3SGVpZ2h0KS4KICAgICAgICBjc3Moe21hcmdpblRvcDogc2l6ZS5oZWlnaHQgKiBpeiAvIDIgLSBuZXdIZWlnaHQgLyAyfSk7CgogICAgICBpZiAoZGF0YS5vcHRzLmF1dG9DZW50ZXIpCiAgICAgICAgdGhpcy50dXJuKCdjZW50ZXInKTsKICAgICAgZWxzZQogICAgICAgICQodGhpcykuY3NzKHttYXJnaW5MZWZ0OiBzaXplLndpZHRoICogaXogLyAyIC0gbmV3V2lkdGggLyAyfSk7CiAgICAgIAogICAgICB0dXJuTWV0aG9kcy5fdXBkYXRlU2hhZG93LmNhbGwodGhpcyk7CiAgCiAgICAgIHJldHVybiB0aGlzOwoKICAgIH0gZWxzZQogICAgICByZXR1cm4gZGF0YS56b29tOwoKICB9LAoKICAvLyBHZXRzIHRoZSBzaXplIG9mIGEgcGFnZQoKICBfcGFnZVNpemU6IGZ1bmN0aW9uKHBhZ2UsIHBvc2l0aW9uKSB7CgogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKSwKICAgICAgcHJvcCA9IHt9OwoKICAgIGlmIChkYXRhLmRpc3BsYXk9PSdzaW5nbGUnKSB7CgogICAgICBwcm9wLndpZHRoID0gdGhpcy53aWR0aCgpOwogICAgICBwcm9wLmhlaWdodCA9IHRoaXMuaGVpZ2h0KCk7CgogICAgICBpZiAocG9zaXRpb24pIHsKICAgICAgICBwcm9wLnRvcCA9IDA7CiAgICAgICAgcHJvcC5sZWZ0ID0gMDsKICAgICAgICBwcm9wLnJpZ2h0ID0gJ2F1dG8nOwogICAgICB9CgogICAgfSBlbHNlIHsKCiAgICAgIHZhciBwYWdlV2lkdGggPSB0aGlzLndpZHRoKCkvMiwKICAgICAgICBwYWdlSGVpZ2h0ID0gdGhpcy5oZWlnaHQoKTsKCiAgICAgIGlmIChkYXRhLnBhZ2VPYmpzW3BhZ2VdLmhhc0NsYXNzKCdvd24tc2l6ZScpKSB7CiAgICAgICAgcHJvcC53aWR0aCA9IGRhdGEucGFnZU9ianNbcGFnZV0ud2lkdGgoKTsKICAgICAgICBwcm9wLmhlaWdodCA9IGRhdGEucGFnZU9ianNbcGFnZV0uaGVpZ2h0KCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcHJvcC53aWR0aCA9IHBhZ2VXaWR0aDsKICAgICAgICBwcm9wLmhlaWdodCA9IHBhZ2VIZWlnaHQ7CiAgICAgIH0KCiAgICAgIGlmIChwb3NpdGlvbikgewogICAgICAgIHZhciBvZGQgPSBwYWdlJTI7CiAgICAgICAgcHJvcC50b3AgPSAocGFnZUhlaWdodC1wcm9wLmhlaWdodCkvMjsKCiAgICAgICAgaWYgKGRhdGEuZGlyZWN0aW9uPT0nbHRyJykgewogICAgICAgICAgCiAgICAgICAgICBwcm9wWyhvZGQpID8gJ3JpZ2h0JyA6ICdsZWZ0J10gPSBwYWdlV2lkdGgtcHJvcC53aWR0aDsKICAgICAgICAgIHByb3BbKG9kZCkgPyAnbGVmdCcgOiAncmlnaHQnXSA9ICdhdXRvJzsKCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIAogICAgICAgICAgcHJvcFsob2RkKSA/ICdsZWZ0JyA6ICdyaWdodCddID0gcGFnZVdpZHRoLXByb3Aud2lkdGg7CiAgICAgICAgICBwcm9wWyhvZGQpID8gJ3JpZ2h0JyA6ICdsZWZ0J10gPSAnYXV0byc7CgogICAgICAgIH0KCiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcHJvcDsKCiAgfSwKCiAgLy8gUHJlcGFyZXMgdGhlIGZsaXAgZWZmZWN0IGZvciBhIHBhZ2UKCiAgX21ha2VGbGlwOiBmdW5jdGlvbihwYWdlKSB7CgogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKTsKCiAgICBpZiAoIWRhdGEucGFnZXNbcGFnZV0gJiYgZGF0YS5wYWdlUGxhY2VbcGFnZV09PXBhZ2UpIHsKICAgICAgdmFyIGNvcm5lciwKICAgICAgICBzaW5nbGUgPSBkYXRhLmRpc3BsYXk9PSdzaW5nbGUnLAogICAgICAgIG9kZCA9IHBhZ2UlMjsKCiAgICAgIGRhdGEucGFnZXNbcGFnZV0gPSBkYXRhLnBhZ2VPYmpzW3BhZ2VdLgogICAgICAgIGNzcyh0dXJuTWV0aG9kcy5fcGFnZVNpemUuY2FsbCh0aGlzLCBwYWdlKSkuCiAgICAgICAgZmxpcCh7cGFnZTogcGFnZSwKICAgICAgICAgIG5leHQ6IChvZGQgfHwgc2luZ2xlKSA/IHBhZ2UrMSA6IHBhZ2UtMSwKICAgICAgICAgIHR1cm46IHRoaXMsCiAgICAgICAgICBkdXJhdGlvbjogZGF0YS5vcHRzLmR1cmF0aW9uLAogICAgICAgICAgYWNjZWxlcmF0aW9uIDogZGF0YS5vcHRzLmFjY2VsZXJhdGlvbiwKICAgICAgICAgIGdyYWRpZW50czogZGF0YS5vcHRzLmdyYWRpZW50cwogICAgICAgICAgfSkuCiAgICAgICAgICBmbGlwKCdkaXNhYmxlJywgZGF0YS5kaXNhYmxlZCk7CiAgICB9CgogICAgcmV0dXJuIGRhdGEucGFnZXNbcGFnZV07CiAgfSwKCiAgLy8gTWFrZXMgcGFnZXMgd2l0aGluIGEgcmFuZ2UKCiAgX21ha2VSYW5nZTogZnVuY3Rpb24oKSB7CgogICAgdmFyIHBhZ2UsIHJhbmdlLAogICAgICBkYXRhID0gdGhpcy5kYXRhKCk7CgogICAgaWYgKGRhdGEudG90YWxQYWdlczwxKQogICAgICByZXR1cm47CgogICAgcmFuZ2UgPSB0aGlzLnR1cm4oJ3JhbmdlJyk7CgogICAgZm9yIChwYWdlID0gcmFuZ2VbMF07IHBhZ2U8PXJhbmdlWzFdOyBwYWdlKyspCiAgICAgIHR1cm5NZXRob2RzLl9hZGRQYWdlLmNhbGwodGhpcywgcGFnZSk7CgogIH0sCgogIC8vIFJldHVybnMgYSByYW5nZSBvZiBwYWdlcyB0aGF0IHNob3VsZCBiZSBpbiB0aGUgRE9NCiAgLy8gRXhhbXBsZToKICAvLyAtIHBhZ2UgaW4gdGhlIGN1cnJlbnQgdmlldywgcmV0dXJuIHRydWUKICAvLyAqIHBhZ2UgaXMgaW4gdGhlIHJhbmdlLCByZXR1cm4gdHJ1ZQogIC8vIE90aGVyd2lzZSwgcmV0dXJuIGZhbHNlCiAgLy8KICAvLyAxIDItMyA0LTUgNi03IDgtOSAxMC0xMSAxMi0xMwogIC8vICAgKiogICoqICAtLSAgICoqICAqKgoKICByYW5nZTogZnVuY3Rpb24ocGFnZSkgewoKICAgIHZhciByZW1haW5pbmdQYWdlcywgbGVmdCwgcmlnaHQsIHZpZXcsCiAgICAgIGRhdGEgPSB0aGlzLmRhdGEoKTsKCgogICAgICBwYWdlID0gcGFnZSB8fCBkYXRhLnRwYWdlIHx8IGRhdGEucGFnZSB8fCAxOwogICAgICB2aWV3ID0gdHVybk1ldGhvZHMuX3ZpZXcuY2FsbCh0aGlzLCBwYWdlKTsKCiAgICAgIGlmIChwYWdlPDEgfHwgcGFnZT5kYXRhLnRvdGFsUGFnZXMpCiAgICAgICAgdGhyb3cgdHVybkVycm9yKCciJytwYWdlKyciIGlzIG5vdCBhIHBhZ2UgZm9yIHJhbmdlJyk7CiAgICAKICAgICAgdmlld1sxXSA9IHZpZXdbMV0gfHwgdmlld1swXTsKICAgICAgCiAgICAgIGlmICh2aWV3WzBdPj0xICYmIHZpZXdbMV08PWRhdGEudG90YWxQYWdlcykgewoKICAgICAgICByZW1haW5pbmdQYWdlcyA9IE1hdGguZmxvb3IoKHBhZ2VzSW5ET00tMikvMik7CgogICAgICAgIGlmIChkYXRhLnRvdGFsUGFnZXMtdmlld1sxXSA+IHZpZXdbMF0pIHsKICAgICAgICAgIGxlZnQgPSBNYXRoLm1pbih2aWV3WzBdLTEsIHJlbWFpbmluZ1BhZ2VzKTsKICAgICAgICAgIHJpZ2h0ID0gMipyZW1haW5pbmdQYWdlcy1sZWZ0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByaWdodCA9IE1hdGgubWluKGRhdGEudG90YWxQYWdlcy12aWV3WzFdLCByZW1haW5pbmdQYWdlcyk7CiAgICAgICAgICBsZWZ0ID0gMipyZW1haW5pbmdQYWdlcy1yaWdodDsKICAgICAgICB9CgogICAgICB9IGVsc2UgewogICAgICAgIGxlZnQgPSBwYWdlc0luRE9NLTE7CiAgICAgICAgcmlnaHQgPSBwYWdlc0luRE9NLTE7CiAgICAgIH0KCiAgICAgIHJldHVybiBbTWF0aC5tYXgoMSwgdmlld1swXS1sZWZ0KSwKICAgICAgICAgIE1hdGgubWluKGRhdGEudG90YWxQYWdlcywgdmlld1sxXStyaWdodCldOwoKICB9LAoKICAvLyBEZXRlY3RzIGlmIGEgcGFnZSBpcyB3aXRoaW4gdGhlIHJhbmdlIG9mIGBwYWdlc0luRE9NYCBmcm9tIHRoZSBjdXJyZW50IHZpZXcKCiAgX25lY2Vzc1BhZ2U6IGZ1bmN0aW9uKHBhZ2UpIHsKICAgIAogICAgaWYgKHBhZ2U9PT0wKQogICAgICByZXR1cm4gdHJ1ZTsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLAogICAgICByYW5nZSA9IHRoaXMudHVybigncmFuZ2UnKTsKCiAgICByZXR1cm4gZGF0YS5wYWdlT2Jqc1twYWdlXS5oYXNDbGFzcygnZml4ZWQnKSB8fAogICAgICAocGFnZT49cmFuZ2VbMF0gJiYgcGFnZTw9cmFuZ2VbMV0pOwogICAgCiAgfSwKCiAgLy8gUmVsZWFzZXMgbWVtb3J5IGJ5IHJlbW92aW5nIHBhZ2VzIGZyb20gdGhlIERPTQoKICBfcmVtb3ZlRnJvbURPTTogZnVuY3Rpb24oKSB7CgogICAgdmFyIHBhZ2UsIGRhdGEgPSB0aGlzLmRhdGEoKTsKCiAgICBmb3IgKHBhZ2UgaW4gZGF0YS5wYWdlV3JhcCkKICAgICAgaWYgKGhhcyhwYWdlLCBkYXRhLnBhZ2VXcmFwKSAmJgogICAgICAgICF0dXJuTWV0aG9kcy5fbmVjZXNzUGFnZS5jYWxsKHRoaXMsIHBhZ2UpKQogICAgICB0dXJuTWV0aG9kcy5fcmVtb3ZlUGFnZUZyb21ET00uY2FsbCh0aGlzLCBwYWdlKTsKICAgIAogIH0sCgogIC8vIFJlbW92ZXMgYSBwYWdlIGZyb20gRE9NIGFuZCBpdHMgaW50ZXJuYWwgcmVmZXJlbmNlcwoKICBfcmVtb3ZlUGFnZUZyb21ET006IGZ1bmN0aW9uKHBhZ2UpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIGlmIChkYXRhLnBhZ2VzW3BhZ2VdKSB7CiAgICAgIHZhciBkZCA9IGRhdGEucGFnZXNbcGFnZV0uZGF0YSgpOwoKICAgICAgZmxpcE1ldGhvZHMuX21vdmVGb2xkaW5nUGFnZS5jYWxsKGRhdGEucGFnZXNbcGFnZV0sIGZhbHNlKTsKCiAgICAgIGlmIChkZC5mICYmIGRkLmYuZndyYXBwZXIpCiAgICAgICAgZGQuZi5md3JhcHBlci5yZW1vdmUoKTsKCiAgICAgIGRhdGEucGFnZXNbcGFnZV0ucmVtb3ZlRGF0YSgpOwogICAgICBkYXRhLnBhZ2VzW3BhZ2VdLnJlbW92ZSgpOwogICAgICBkZWxldGUgZGF0YS5wYWdlc1twYWdlXTsKICAgIH0KCiAgICBpZiAoZGF0YS5wYWdlT2Jqc1twYWdlXSkKICAgICAgZGF0YS5wYWdlT2Jqc1twYWdlXS5yZW1vdmUoKTsKCiAgICBpZiAoZGF0YS5wYWdlV3JhcFtwYWdlXSkgewogICAgICBkYXRhLnBhZ2VXcmFwW3BhZ2VdLnJlbW92ZSgpOwogICAgICBkZWxldGUgZGF0YS5wYWdlV3JhcFtwYWdlXTsKICAgIH0KCiAgICBkZWxldGUgZGF0YS5wYWdlUGxhY2VbcGFnZV07CgogIH0sCgogIC8vIFJlbW92ZXMgYSBwYWdlCgogIHJlbW92ZVBhZ2U6IGZ1bmN0aW9uKHBhZ2UpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIGlmIChwYWdlPDEgfHwgcGFnZT5kYXRhLnRvdGFsUGFnZXMpCiAgICAgIHRocm93IHR1cm5FcnJvcignVGhlIHBhZ2UgJysgcGFnZSArICcgZG9lc25cJ3QgZXhpc3QnKTsKICAgICAgCiAgICBpZiAoZGF0YS5wYWdlT2Jqc1twYWdlXSkgewoKICAgICAgLy8gU3RvcCBhbmltYXRpb25zCiAgICAgIHRoaXMudHVybignc3RvcCcpOwoKICAgICAgLy8gUmVtb3ZlIGBwYWdlYAogICAgICB0dXJuTWV0aG9kcy5fcmVtb3ZlUGFnZUZyb21ET00uY2FsbCh0aGlzLCBwYWdlKTsKICAgICAgZGVsZXRlIGRhdGEucGFnZU9ianNbcGFnZV07CgogICAgfQoKICAgIC8vIE1vdmUgdGhlIHBhZ2VzIGJlaGluZCBgcGFnZWAKICAgIHR1cm5NZXRob2RzLl9tb3ZlUGFnZXMuY2FsbCh0aGlzLCBwYWdlLCAtMSk7CgogICAgLy8gUmVzaXplIHRoZSBzaXplIG9mIHRoaXMgZmxpcGJvb2sKICAgIGRhdGEudG90YWxQYWdlcyA9IGRhdGEudG90YWxQYWdlcy0xOwoKICAgIC8vIENoZWNrIHRoZSBjdXJyZW50IHZpZXcKCiAgICBpZiAoZGF0YS5wYWdlPmRhdGEudG90YWxQYWdlcykKICAgICAgdGhpcy50dXJuKCdwYWdlJywgZGF0YS50b3RhbFBhZ2VzKTsKICAgIGVsc2UKICAgICAgdHVybk1ldGhvZHMuX21ha2VSYW5nZS5jYWxsKHRoaXMpOwoKICAgIHJldHVybiB0aGlzOwogIAogIH0sCgogIC8vIE1vdmVzIHBhZ2VzCgogIF9tb3ZlUGFnZXM6IGZ1bmN0aW9uKGZyb20sIGNoYW5nZSkgewoKICAgIHZhciBwYWdlLAogICAgICB0aGF0ID0gdGhpcywKICAgICAgZGF0YSA9IHRoaXMuZGF0YSgpLAogICAgICBzaW5nbGUgPSBkYXRhLmRpc3BsYXk9PSdzaW5nbGUnLAogICAgICBtb3ZlID0gZnVuY3Rpb24ocGFnZSkgewoKICAgICAgICB2YXIgbmV4dCA9IHBhZ2UgKyBjaGFuZ2UsCiAgICAgICAgICBvZGQgPSBuZXh0JTIsCiAgICAgICAgICBjbGFzc05hbWUgPSAob2RkKSA/ICcgb2RkICcgOiAnIGV2ZW4gJzsKCiAgICAgICAgaWYgKGRhdGEucGFnZU9ianNbcGFnZV0pCiAgICAgICAgICBkYXRhLnBhZ2VPYmpzW25leHRdID0gZGF0YS5wYWdlT2Jqc1twYWdlXQogICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ3AnICsgcGFnZSArICcgb2RkIGV2ZW4nKQogICAgICAgICAgICAuYWRkQ2xhc3MoJ3AnICsgbmV4dCArIGNsYXNzTmFtZSk7CgogICAgICAgIGlmIChkYXRhLnBhZ2VQbGFjZVtwYWdlXSAmJiBkYXRhLnBhZ2VXcmFwW3BhZ2VdKSB7CiAgICAgICAgICBkYXRhLnBhZ2VQbGFjZVtuZXh0XSA9IG5leHQ7CiAgICAgICAgCiAgICAgICAgaWYgKGRhdGEucGFnZU9ianNbbmV4dF0uaGFzQ2xhc3MoJ2ZpeGVkJykpCiAgICAgICAgICBkYXRhLnBhZ2VXcmFwW25leHRdID0gZGF0YS5wYWdlV3JhcFtwYWdlXQogICAgICAgICAgICAuYXR0cigncGFnZScsIG5leHQpOwogICAgICAgIGVsc2UKICAgICAgICAgIGRhdGEucGFnZVdyYXBbbmV4dF0gPSBkYXRhLnBhZ2VXcmFwW3BhZ2VdLgogICAgICAgICAgICBjc3ModHVybk1ldGhvZHMuX3BhZ2VTaXplLmNhbGwodGhhdCwgbmV4dCwgdHJ1ZSkpLgogICAgICAgICAgICBhdHRyKCdwYWdlJywgbmV4dCk7CiAgICAKICAgICAgICAgIGlmIChkYXRhLnBhZ2VzW3BhZ2VdKQogICAgICAgICAgICBkYXRhLnBhZ2VzW25leHRdID0gZGF0YS5wYWdlc1twYWdlXQogICAgICAgICAgICAgIC5mbGlwKCdvcHRpb25zJywgewogICAgICAgICAgICAgICAgcGFnZTogbmV4dCwKICAgICAgICAgICAgICAgIG5leHQ6IChzaW5nbGUgfHwgb2RkKSA/IG5leHQrMSA6IG5leHQtMSwKICAgICAgICAgICAgICAgIGNvcm5lcnM6IChzaW5nbGUpID8gJ2FsbCcgOgogICAgICAgICAgICAgICAgICAoKG9kZCkgPyAnZm9yd2FyZCcgOiAnYmFja3dhcmQnKQogICAgICAgICAgICAgIH0pOwoKICAgICAgICAgIGlmIChjaGFuZ2UpIHsKICAgICAgICAgICAgZGVsZXRlIGRhdGEucGFnZXNbcGFnZV07CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhLnBhZ2VQbGFjZVtwYWdlXTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEucGFnZU9ianNbcGFnZV07CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhLnBhZ2VXcmFwW3BhZ2VdOwogICAgICAgICAgICBkZWxldGUgZGF0YS5wYWdlT2Jqc1twYWdlXTsKICAgICAgICAgIH0KICAgICAgfQogICAgfTsKCiAgICBpZiAoY2hhbmdlPjApCiAgICAgIGZvciAocGFnZT1kYXRhLnRvdGFsUGFnZXM7IHBhZ2U+PWZyb207IHBhZ2UtLSkKICAgICAgICBtb3ZlKHBhZ2UpOwogICAgZWxzZQogICAgICBmb3IgKHBhZ2U9ZnJvbTsgcGFnZTw9ZGF0YS50b3RhbFBhZ2VzOyBwYWdlKyspCiAgICAgICAgbW92ZShwYWdlKTsKCiAgfSwKCiAgLy8gU2V0cyBvciBHZXRzIHRoZSBkaXNwbGF5IG1vZGUKCiAgZGlzcGxheTogZnVuY3Rpb24oZGlzcGxheSkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCksCiAgICAgIGN1cnJlbnREaXNwbGF5ID0gZGF0YS5kaXNwbGF5OwoKICAgIGlmIChkaXNwbGF5KSB7CgogICAgICBpZiAoJC5pbkFycmF5KGRpc3BsYXksIGRpc3BsYXlzKT09LTEpCiAgICAgICAgdGhyb3cgdHVybkVycm9yKCciJytkaXNwbGF5ICsgJyIgaXMgbm90IGEgdmFsdWUgZm9yIGRpc3BsYXknKTsKICAgICAgCiAgICAgIGlmIChkaXNwbGF5PT0nc2luZ2xlJykgewogICAgICAgIGlmICghZGF0YS5wYWdlT2Jqc1swXSkgewoKICAgICAgICAgIHRoaXMudHVybignc3RvcCcpLgogICAgICAgICAgICBjc3MoeydvdmVyZmxvdyc6ICdoaWRkZW4nfSk7CgogICAgICAgICAgZGF0YS5wYWdlT2Jqc1swXSA9ICQoJzxkaXYgLz4nLAogICAgICAgICAgICAgIHsnY2xhc3MnOiAncGFnZSBwLXRlbXBvcmFsJ30pLgogICAgICAgICAgICBjc3Moe3dpZHRoOiB0aGlzLndpZHRoKCksIGhlaWdodDogdGhpcy5oZWlnaHQoKX0pLgogICAgICAgICAgICBhcHBlbmRUbyh0aGlzKTsKCiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGlmIChkYXRhLnBhZ2VPYmpzWzBdKSB7CiAgICAgICAgICB0aGlzLnR1cm4oJ3N0b3AnKS5jc3MoeydvdmVyZmxvdyc6ICcnfSk7CiAgICAgICAgICBkYXRhLnBhZ2VPYmpzWzBdLnJlbW92ZSgpOwogICAgICAgICAgZGVsZXRlIGRhdGEucGFnZU9ianNbMF07CiAgICAgICAgfQogICAgICB9CgogICAgICBkYXRhLmRpc3BsYXkgPSBkaXNwbGF5OwoKICAgICAgaWYgKGN1cnJlbnREaXNwbGF5KSB7CiAgICAgICAgdmFyIHNpemUgPSB0aGlzLnR1cm4oJ3NpemUnKTsKICAgICAgICB0dXJuTWV0aG9kcy5fbW92ZVBhZ2VzLmNhbGwodGhpcywgMSwgMCk7CiAgICAgICAgdGhpcy50dXJuKCdzaXplJywgc2l6ZS53aWR0aCwgc2l6ZS5oZWlnaHQpLgogICAgICAgICAgdHVybigndXBkYXRlJyk7CiAgICAgIH0KCiAgICAgIHJldHVybiB0aGlzOwoKICAgIH0gZWxzZQogICAgICByZXR1cm4gY3VycmVudERpc3BsYXk7CiAgCiAgfSwKCiAgLy8gR2V0cyBhbmQgc2V0cyB0aGUgZGlyZWN0aW9uIG9mIHRoZSBmbGlwYm9vawoKICBkaXJlY3Rpb246IGZ1bmN0aW9uKGRpcikgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCk7CgogICAgaWYgKHR5cGVvZihkaXIpPT0ndW5kZWZpbmVkJykgewoKICAgICAgcmV0dXJuIGRhdGEuZGlyZWN0aW9uOwoKICAgIH0gZWxzZSB7CgogICAgICBkaXIgPSBkaXIudG9Mb3dlckNhc2UoKTsKCiAgICAgIGlmICgkLmluQXJyYXkoZGlyLCBkaXJlY3Rpb25zKT09LTEpCiAgICAgICAgdGhyb3cgdHVybkVycm9yKCciJyArIGRpciArICciIGlzIG5vdCBhIHZhbHVlIGZvciBkaXJlY3Rpb24nKTsKCiAgICAgIGlmIChkaXI9PSdydGwnKSB7CiAgICAgICAgJCh0aGlzKS5hdHRyKCdkaXInLCAnbHRyJykuCiAgICAgICAgICBjc3Moe2RpcmVjdGlvbjogJ2x0cid9KTsKICAgICAgfQoKICAgICAgZGF0YS5kaXJlY3Rpb24gPSBkaXI7CgogICAgICBpZiAoZGF0YS5kb25lKQogICAgICAgIHRoaXMudHVybignc2l6ZScsICQodGhpcykud2lkdGgoKSwgJCh0aGlzKS5oZWlnaHQoKSk7CgogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgfSwKCiAgLy8gRGV0ZWN0cyBpZiB0aGUgcGFnZXMgYXJlIGJlaW5nIGFuaW1hdGVkCgogIGFuaW1hdGluZzogZnVuY3Rpb24oKSB7CgogICAgcmV0dXJuIHRoaXMuZGF0YSgpLnBhZ2VNdi5sZW5ndGg+MDsKCiAgfSwKCiAgLy8gRGlzYWJsZXMgYW5kIGVuYWJsZXMgdGhlIGVmZmVjdAoKICBkaXNhYmxlOiBmdW5jdGlvbihib29sKSB7CgogICAgdmFyIHBhZ2UsCiAgICAgIGRhdGEgPSB0aGlzLmRhdGEoKSwKICAgICAgdmlldyA9IHRoaXMudHVybigndmlldycpOwoKICAgICAgZGF0YS5kaXNhYmxlZCA9IGJvb2w9PT11bmRlZmluZWQgfHwgYm9vbD09PXRydWU7CgogICAgZm9yIChwYWdlIGluIGRhdGEucGFnZXMpCiAgICAgIGlmIChoYXMocGFnZSwgZGF0YS5wYWdlcykpCiAgICAgICAgZGF0YS5wYWdlc1twYWdlXS5mbGlwKCdkaXNhYmxlJywgKGJvb2wpID8gJC5pbkFycmF5KHBhZ2UsIHZpZXcpIDogZmFsc2UpOwoKICAgIHJldHVybiB0aGlzOwoKICB9LAoKICAvLyBEaXNhYmxlcyBhbmQgZW5hYmxlcyB0aGUgZWZmZWN0CgogIGRpc2FibGVkOiBmdW5jdGlvbihkaXNhYmxlKSB7CgogICAgaWYgKGRpc2FibGU9PT11bmRlZmluZWQpIHsKICAgICAgcmV0dXJuIHRoaXMuZGF0YSgpLmRpc2FibGVkPT09dHJ1ZTsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiB0aGlzLnR1cm4oJ2Rpc2FibGUnLCBkaXNhYmxlKTsKICAgIH0KCiAgfSwKCiAgLy8gR2V0cyBhbmQgc2V0cyB0aGUgc2l6ZQoKICBzaXplOiBmdW5jdGlvbih3aWR0aCwgaGVpZ2h0KSB7CgogICAgaWYgKHdpZHRoICYmIGhlaWdodCkgewoKICAgICAgdmFyIHBhZ2UsIHByb3AsCiAgICAgICAgZGF0YSA9IHRoaXMuZGF0YSgpLAogICAgICAgIHBhZ2VXaWR0aCA9IChkYXRhLmRpc3BsYXk9PSdkb3VibGUnKSA/IHdpZHRoLzIgOiB3aWR0aDsKCiAgICAgIHRoaXMuY3NzKHt3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0fSk7CgogICAgICBpZiAoZGF0YS5wYWdlT2Jqc1swXSkKICAgICAgICBkYXRhLnBhZ2VPYmpzWzBdLmNzcyh7d2lkdGg6IHBhZ2VXaWR0aCwgaGVpZ2h0OiBoZWlnaHR9KTsKICAgICAgCiAgICAgIGZvciAocGFnZSBpbiBkYXRhLnBhZ2VXcmFwKSB7CiAgICAgICAgaWYgKCFoYXMocGFnZSwgZGF0YS5wYWdlV3JhcCkpIGNvbnRpbnVlOwoKICAgICAgICBwcm9wID0gdHVybk1ldGhvZHMuX3BhZ2VTaXplLmNhbGwodGhpcywgcGFnZSwgdHJ1ZSk7CgogICAgICAgIGRhdGEucGFnZU9ianNbcGFnZV0uY3NzKHt3aWR0aDogcHJvcC53aWR0aCwgaGVpZ2h0OiBwcm9wLmhlaWdodH0pOwogICAgICAgIGRhdGEucGFnZVdyYXBbcGFnZV0uY3NzKHByb3ApOwoKICAgICAgICBpZiAoZGF0YS5wYWdlc1twYWdlXSkKICAgICAgICAgIGRhdGEucGFnZXNbcGFnZV0uY3NzKHt3aWR0aDogcHJvcC53aWR0aCwgaGVpZ2h0OiBwcm9wLmhlaWdodH0pOwogICAgICB9CgogICAgICB0aGlzLnR1cm4oJ3Jlc2l6ZScpOwoKICAgICAgcmV0dXJuIHRoaXM7CgogICAgfSBlbHNlIHsKICAgICAgCiAgICAgIHJldHVybiB7d2lkdGg6IHRoaXMud2lkdGgoKSwgaGVpZ2h0OiB0aGlzLmhlaWdodCgpfTsKCiAgICB9CiAgfSwKCiAgLy8gUmVzaXplcyBlYWNoIHBhZ2UKCiAgcmVzaXplOiBmdW5jdGlvbigpIHsKCiAgICB2YXIgcGFnZSwgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIGlmIChkYXRhLnBhZ2VzWzBdKSB7CiAgICAgIGRhdGEucGFnZVdyYXBbMF0uY3NzKHtsZWZ0OiAtdGhpcy53aWR0aCgpfSk7CiAgICAgIGRhdGEucGFnZXNbMF0uZmxpcCgncmVzaXplJywgdHJ1ZSk7CiAgICB9CgogICAgZm9yIChwYWdlID0gMTsgcGFnZSA8PSBkYXRhLnRvdGFsUGFnZXM7IHBhZ2UrKykKICAgICAgaWYgKGRhdGEucGFnZXNbcGFnZV0pCiAgICAgICAgZGF0YS5wYWdlc1twYWdlXS5mbGlwKCdyZXNpemUnLCB0cnVlKTsKCgogIH0sCgogIC8vIFJlbW92ZXMgYW4gYW5pbWF0aW9uIGZyb20gdGhlIGNhY2hlCgogIF9yZW1vdmVNdjogZnVuY3Rpb24ocGFnZSkgewoKICAgIHZhciBpLCBkYXRhID0gdGhpcy5kYXRhKCk7CiAgICAgIAogICAgZm9yIChpPTA7IGk8ZGF0YS5wYWdlTXYubGVuZ3RoOyBpKyspCiAgICAgIGlmIChkYXRhLnBhZ2VNdltpXT09cGFnZSkgewogICAgICAgIGRhdGEucGFnZU12LnNwbGljZShpLCAxKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgIHJldHVybiBmYWxzZTsKCiAgfSwKCiAgLy8gQWRkcyBhbiBhbmltYXRpb24gdG8gdGhlIGNhY2hlCiAgCiAgX2FkZE12OiBmdW5jdGlvbihwYWdlKSB7CgogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKTsKCiAgICB0dXJuTWV0aG9kcy5fcmVtb3ZlTXYuY2FsbCh0aGlzLCBwYWdlKTsKICAgIGRhdGEucGFnZU12LnB1c2gocGFnZSk7CgogIH0sCgogIC8vIEdldHMgaW5kZXhlcyBmb3IgYSB2aWV3CgogIF92aWV3OiBmdW5jdGlvbihwYWdlKSB7CiAgCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpOwogICAgCiAgICBwYWdlID0gcGFnZSB8fCBkYXRhLnBhZ2U7CgogICAgaWYgKGRhdGEuZGlzcGxheT09J2RvdWJsZScpCiAgICAgIHJldHVybiAocGFnZSUyKSA/IFtwYWdlLTEsIHBhZ2VdIDogW3BhZ2UsIHBhZ2UrMV07CiAgICBlbHNlCiAgICAgIHJldHVybiBbcGFnZV07CgogIH0sCgogIC8vIEdldHMgYSB2aWV3CgogIHZpZXc6IGZ1bmN0aW9uKHBhZ2UpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLAogICAgICB2aWV3ID0gdHVybk1ldGhvZHMuX3ZpZXcuY2FsbCh0aGlzLCBwYWdlKTsKCiAgICBpZiAoZGF0YS5kaXNwbGF5PT0nZG91YmxlJykKICAgICAgcmV0dXJuIFsodmlld1swXT4wKSA/IHZpZXdbMF0gOiAwLAogICAgICAgICh2aWV3WzFdPD1kYXRhLnRvdGFsUGFnZXMpID8gdmlld1sxXSA6IDBdOwogICAgZWxzZQogICAgICByZXR1cm4gWyh2aWV3WzBdPjAgJiYgdmlld1swXTw9ZGF0YS50b3RhbFBhZ2VzKSA/IHZpZXdbMF0gOiAwXTsKCiAgfSwKCiAgLy8gU3RvcHMgYW5pbWF0aW9ucwoKICBzdG9wOiBmdW5jdGlvbihpZ25vcmUsIGFuaW1hdGUpIHsKCiAgICBpZiAodGhpcy50dXJuKCdhbmltYXRpbmcnKSkgewogICAgICB2YXIgaSwgb3B0cywgcGFnZSwKICAgICAgICBkYXRhID0gdGhpcy5kYXRhKCksCiAgICAgICAgcGFnZXMgPSBkYXRhLnBhZ2VNdjsKCiAgICAgIGRhdGEucGFnZU12ID0gW107CgogICAgICBpZiAoZGF0YS50cGFnZSkgewogICAgICAgIGRhdGEucGFnZSA9IGRhdGEudHBhZ2U7CiAgICAgICAgZGVsZXRlIGRhdGFbJ3RwYWdlJ107CiAgICAgIH0KCiAgICAgIGZvciAoaSA9IDA7IGk8cGFnZXMubGVuZ3RoOyBpKyspIHsKCiAgICAgICAgcGFnZSA9IGRhdGEucGFnZXNbcGFnZXNbaV1dOwogICAgICAgIG9wdHMgPSBwYWdlLmRhdGEoKS5mLm9wdHM7CgogICAgICAgIHBhZ2UuZmxpcCgnaGlkZUZvbGRlZFBhZ2UnLCBmYWxzZSk7CgogICAgICAgIGZsaXBNZXRob2RzLl9tb3ZlRm9sZGluZ1BhZ2UuY2FsbChwYWdlLCBmYWxzZSk7CgogICAgICAgIGRhdGEucGFnZVBsYWNlW29wdHMubmV4dF0gPSBvcHRzLm5leHQ7CgogICAgICAgIGlmIChvcHRzLmZvcmNlKSB7CiAgICAgICAgICBvcHRzLm5leHQgPSAob3B0cy5wYWdlJTI9PT0wKSA/IG9wdHMucGFnZS0xIDogb3B0cy5wYWdlKzE7CiAgICAgICAgICBkZWxldGUgb3B0c1snZm9yY2UnXTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICB0aGlzLnR1cm4oJ3VwZGF0ZScpOwoKICAgIHJldHVybiB0aGlzOwogIAogIH0sCgogIC8vIEdldHMgYW5kIHNldHMgdGhlIG51bWJlciBvZiBwYWdlcwoKICBwYWdlczogZnVuY3Rpb24ocGFnZXMpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIGlmIChwYWdlcykgewogICAgICBpZiAocGFnZXM8ZGF0YS50b3RhbFBhZ2VzKSB7CgogICAgICAgIGZvciAodmFyIHBhZ2UgPSBwYWdlcysxOyBwYWdlPD1kYXRhLnRvdGFsUGFnZXM7IHBhZ2UrKykKICAgICAgICAgIHRoaXMudHVybigncmVtb3ZlUGFnZScsIHBhZ2UpOwoKICAgICAgICBpZiAodGhpcy50dXJuKCdwYWdlJyk+cGFnZXMpCiAgICAgICAgICB0aGlzLnR1cm4oJ3BhZ2UnLCBwYWdlcyk7CiAgICAgIH0KCiAgICAgIGRhdGEudG90YWxQYWdlcyA9IHBhZ2VzOwoKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9IGVsc2UKICAgICAgcmV0dXJuIGRhdGEudG90YWxQYWdlczsKCiAgfSwKCiAgLy8gQ2hlY2tzIG1pc3NpbmcgcGFnZXMKCiAgX21pc3NpbmcgOiBmdW5jdGlvbihwYWdlKSB7CiAgICAKICAgIHZhciBwLAogICAgICBkYXRhID0gdGhpcy5kYXRhKCksCiAgICAgIHJhbmdlID0gdGhpcy50dXJuKCdyYW5nZScsIHBhZ2UpLAogICAgICBtaXNzaW5nID0gW107CgogICAgZm9yIChwID0gcmFuZ2VbMF07IHA8PXJhbmdlWzFdOyBwKyspIHsKICAgICAgaWYgKCFkYXRhLnBhZ2VPYmpzW3BdKQogICAgICAgIG1pc3NpbmcucHVzaChwKTsKICAgIH0KCiAgICBpZiAobWlzc2luZy5sZW5ndGg+MCkKICAgICAgdGhpcy50cmlnZ2VyKCdtaXNzaW5nJywgW21pc3NpbmddKTsKICAgIAogIH0sCgogIC8vIFNldHMgYSBwYWdlIHdpdGhvdXQgZWZmZWN0CgogIF9maXRQYWdlOiBmdW5jdGlvbihwYWdlKSB7CgogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKSwKICAgICAgbmV3VmlldyA9IHRoaXMudHVybigndmlldycsIHBhZ2UpOwogICAgCiAgICB0dXJuTWV0aG9kcy5fbWlzc2luZy5jYWxsKHRoaXMsIHBhZ2UpOwoKICAgIGlmICghZGF0YS5wYWdlT2Jqc1twYWdlXSkKICAgICAgcmV0dXJuOwoKICAgIGRhdGEucGFnZSA9IHBhZ2U7CgogICAgdGhpcy50dXJuKCdzdG9wJyk7CiAgICB0dXJuTWV0aG9kcy5fcmVtb3ZlRnJvbURPTS5jYWxsKHRoaXMpOwogICAgdHVybk1ldGhvZHMuX21ha2VSYW5nZS5jYWxsKHRoaXMpOwogICAgdHVybk1ldGhvZHMuX3VwZGF0ZVNoYWRvdy5jYWxsKHRoaXMpOwogICAgdGhpcy50cmlnZ2VyKCd0dXJuZWQnLCBbcGFnZSwgbmV3Vmlld10pOwoKICAgIGlmIChkYXRhLm9wdHMuYXV0b0NlbnRlcikKICAgICAgdGhpcy50dXJuKCdjZW50ZXInKTsKCiAgfSwKICAKICAvLyBUdXJucyB0byBhIHBhZ2UKCiAgX3R1cm5QYWdlOiBmdW5jdGlvbihwYWdlLCBmcm9tTW91c2VBY3Rpb24pIHsKCiAgICB2YXIgY3VycmVudCwgbmV4dCwKICAgICAgZGF0YSA9IHRoaXMuZGF0YSgpLAogICAgICBwbGFjZSA9IGRhdGEucGFnZVBsYWNlW3BhZ2VdLAogICAgICB2aWV3ID0gdGhpcy50dXJuKCd2aWV3JyksCiAgICAgIG5ld1ZpZXcgPSB0aGlzLnR1cm4oJ3ZpZXcnLCBwYWdlKTsKICAKICAgIGlmIChkYXRhLnBhZ2UhPXBhZ2UpIHsKCiAgICAgIHZhciBldmVudCA9ICQuRXZlbnQoJ3R1cm5pbmcnKTsKICAgICAgdGhpcy50cmlnZ2VyKGV2ZW50LCBbcGFnZSwgbmV3Vmlld10pOwoKICAgICAgaWYgKGV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpKQogICAgICAgIHJldHVybjsKCiAgICAgIGlmICgkLmluQXJyYXkoMSwgbmV3VmlldykhPS0xKQogICAgICAgIHRoaXMudHJpZ2dlcignZmlyc3QnKTsKICAgICAgaWYgKCQuaW5BcnJheShkYXRhLnRvdGFsUGFnZXMsIG5ld1ZpZXcpIT0tMSkKICAgICAgICB0aGlzLnRyaWdnZXIoJ2xhc3QnKTsKCiAgICB9CgoKCiAgICBpZiAoZnJvbU1vdXNlQWN0aW9uKSB7CgogICAgICB0aGlzLnR1cm4oJ3N0b3AnLCBwbGFjZSk7CgogICAgfSBlbHNlIHsKCiAgICAgIHR1cm5NZXRob2RzLl9taXNzaW5nLmNhbGwodGhpcywgcGFnZSk7CiAgICAgIAogICAgICBpZiAoIWRhdGEucGFnZU9ianNbcGFnZV0pCiAgICAgICAgcmV0dXJuOwoKICAgICAgdGhpcy50dXJuKCdzdG9wJyk7CiAgICAgIGRhdGEucGFnZSA9IHBhZ2U7CiAgICB9CiAgICAKCiAgICB0dXJuTWV0aG9kcy5fbWFrZVJhbmdlLmNhbGwodGhpcyk7CgogICAgaWYgKGRhdGEuZGlzcGxheT09J3NpbmdsZScpIHsKICAgICAgY3VycmVudCA9IHZpZXdbMF07CiAgICAgIG5leHQgPSBuZXdWaWV3WzBdOwogICAgfSBlbHNlIGlmICh2aWV3WzFdICYmIHBhZ2U+dmlld1sxXSkgewogICAgICBjdXJyZW50ID0gdmlld1sxXTsKICAgICAgbmV4dCA9IG5ld1ZpZXdbMF07CiAgICB9IGVsc2UgaWYgKHZpZXdbMF0gJiYgcGFnZTx2aWV3WzBdKSB7CiAgICAgIGN1cnJlbnQgPSB2aWV3WzBdOwogICAgICBuZXh0ID0gbmV3Vmlld1sxXTsKICAgIH0KCiAgICBpZiAoZGF0YS5wYWdlc1tjdXJyZW50XSkgewoKICAgICAgdmFyIG9wdHMgPSBkYXRhLnBhZ2VzW2N1cnJlbnRdLmRhdGEoKS5mLm9wdHM7CiAgICAgIGRhdGEudHBhZ2UgPSBuZXh0OwogICAgICAKICAgICAgaWYgKG9wdHMubmV4dCE9bmV4dCkgewogICAgICAgIG9wdHMubmV4dCA9IG5leHQ7CiAgICAgICAgZGF0YS5wYWdlUGxhY2VbbmV4dF0gPSBvcHRzLnBhZ2U7CiAgICAgICAgb3B0cy5mb3JjZSA9IHRydWU7CiAgICAgIH0KCiAgICAgIGlmIChkYXRhLmRpc3BsYXk9PSdzaW5nbGUnKSB7CgogICAgICAgIGlmIChkYXRhLmRpcmVjdGlvbj09J2x0cicpIHsKICAgICAgICAgIGRhdGEucGFnZXNbY3VycmVudF0uZmxpcCgndHVyblBhZ2UnLAogICAgICAgICAgICAobmV3Vmlld1swXSA+IHZpZXdbMF0pID8gJ3InIDogJ2wnKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZGF0YS5wYWdlc1tjdXJyZW50XS5mbGlwKCd0dXJuUGFnZScsCiAgICAgICAgICAgIChuZXdWaWV3WzBdID4gdmlld1swXSkgPyAnbCcgOiAncicpOwogICAgICAgIH0KCiAgICAgIH0gZWxzZSB7CiAgICAgICAgCiAgICAgICAgZGF0YS5wYWdlc1tjdXJyZW50XS5mbGlwKCd0dXJuUGFnZScpOwoKICAgICAgfQogICAgfQoKICB9LAoKICAvLyBHZXRzIGFuZCBzZXRzIGEgcGFnZQoKICBwYWdlOiBmdW5jdGlvbihwYWdlKSB7CgogICAgcGFnZSA9IHBhcnNlSW50KHBhZ2UsIDEwKTsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIGlmIChwYWdlPjAgJiYgcGFnZTw9ZGF0YS50b3RhbFBhZ2VzKSB7CiAgICAgIGlmICghZGF0YS5kb25lIHx8ICQuaW5BcnJheShwYWdlLCB0aGlzLnR1cm4oJ3ZpZXcnKSkhPS0xKQogICAgICAgIHR1cm5NZXRob2RzLl9maXRQYWdlLmNhbGwodGhpcywgcGFnZSk7CiAgICAgIGVsc2UKICAgICAgICB0dXJuTWV0aG9kcy5fdHVyblBhZ2UuY2FsbCh0aGlzLCBwYWdlKTsKICAgIAogICAgICByZXR1cm4gdGhpczsKCiAgICB9IGVsc2UKICAgICAgcmV0dXJuIGRhdGEucGFnZTsKICAKICB9LAoKICAvLyBUdXJucyB0byB0aGUgbmV4dCB2aWV3CgogIG5leHQ6IGZ1bmN0aW9uKCkgewoKICAgIHJldHVybiB0aGlzLnR1cm4oJ3BhZ2UnLAogICAgICB0dXJuTWV0aG9kcy5fdmlldy5jYWxsKHRoaXMsIHRoaXMuZGF0YSgpLnBhZ2UpLnBvcCgpICsgMSk7CiAgCiAgfSwKCiAgLy8gVHVybnMgdG8gdGhlIHByZXZpb3VzIHZpZXcKCiAgcHJldmlvdXM6IGZ1bmN0aW9uKCkgewogICAgCiAgICByZXR1cm4gdGhpcy50dXJuKCdwYWdlJywKICAgICAgdHVybk1ldGhvZHMuX3ZpZXcuY2FsbCh0aGlzLCB0aGlzLmRhdGEoKS5wYWdlKS5zaGlmdCgpIC0gMSk7CgogIH0sCgogIHBlZWw6IGZ1bmN0aW9uKGNvcm5lciwgYW5pbWF0ZSkgewogICAgCiAgICByZXR1cm4gdGhpczsKCiAgfSwKCiAgLy8gQWRkcyBhIG1vdGlvbiB0byB0aGUgaW50ZXJuYWwgbGlzdAogIC8vIFRoaXMgZXZlbnQgaXMgY2FsbGVkIGluIGNvbnRleHQgb2YgZmxpcAoKICBfYWRkTW90aW9uUGFnZTogZnVuY3Rpb24oKSB7CgogICAgdmFyIG9wdHMgPSAkKHRoaXMpLmRhdGEoKS5mLm9wdHMsCiAgICAgIHR1cm4gPSBvcHRzLnR1cm4sCiAgICAgIGRkID0gdHVybi5kYXRhKCk7CgogICAgdHVybk1ldGhvZHMuX2FkZE12LmNhbGwodHVybiwgb3B0cy5wYWdlKTsKICAgIGRkLnBhZ2VQbGFjZVtvcHRzLm5leHRdID0gb3B0cy5wYWdlOwogICAgdHVybi50dXJuKCd1cGRhdGUnKTsKCiAgfSwKCiAgLy8gVGhpcyBldmVudCBpcyBjYWxsZWQgaW4gY29udGV4dCBvZiBmbGlwCgogIF9zdGFydDogZnVuY3Rpb24oZSwgb3B0cywgY29ybmVyKSB7CgogICAgdmFyIGRhdGEgPSBvcHRzLnR1cm4uZGF0YSgpOwoKICAgIGlmIChlLmlzRGVmYXVsdFByZXZlbnRlZCgpKSB7CiAgICAgIHR1cm5NZXRob2RzLl91cGRhdGVTaGFkb3cuY2FsbChvcHRzLnR1cm4pOwogICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGRhdGEuZGlzcGxheT09J3NpbmdsZScgJiYgY29ybmVyKSB7CgogICAgICBpZiAoKGNvcm5lcj09J2wnICYmIGRhdGEuZGlyZWN0aW9uPT0nbHRyJykKICAgICAgICB8fAogICAgICAgIChjb3JuZXI9PSdyJyAmJiBkYXRhLmRpcmVjdGlvbj09J3J0bCcpKQogICAgICB7CiAgICAgICAgCiAgICAgICAgb3B0cy5uZXh0ID0gKG9wdHMubmV4dDxvcHRzLnBhZ2UpID8gb3B0cy5uZXh0IDogb3B0cy5wYWdlLTE7CiAgICAgICAgb3B0cy5mb3JjZSA9IHRydWU7CgogICAgICB9IGVsc2UgewoKICAgICAgICBvcHRzLm5leHQgPSAob3B0cy5uZXh0Pm9wdHMucGFnZSkgPyBvcHRzLm5leHQgOiBvcHRzLnBhZ2UrMTsKCiAgICAgIH0KCiAgICB9CgogICAgdHVybk1ldGhvZHMuX2FkZE1vdGlvblBhZ2UuY2FsbChlLnRhcmdldCk7CiAgICB0dXJuTWV0aG9kcy5fdXBkYXRlU2hhZG93LmNhbGwob3B0cy50dXJuKTsKICB9LAoKICAvLyBUaGlzIGV2ZW50IGlzIGNhbGxlZCBpbiBjb250ZXh0IG9mIGZsaXAKCiAgX2VuZDogZnVuY3Rpb24oZSwgb3B0cywgdHVybmVkKSB7CgogICAgdmFyIHRoYXQgPSAkKGUudGFyZ2V0KSwKICAgICAgZGF0YSA9IHRoYXQuZGF0YSgpLmYsCiAgICAgIHR1cm4gPSBvcHRzLnR1cm4sCiAgICAgIGRkID0gdHVybi5kYXRhKCk7CgogICAgaWYgKHR1cm5lZCB8fCBkZC50cGFnZSkgewoKICAgICAgaWYgKGRkLnRwYWdlPT1vcHRzLm5leHQgfHwgZGQudHBhZ2U9PW9wdHMucGFnZSkgewogICAgICAgIGRlbGV0ZSBkZFsndHBhZ2UnXTsKICAgICAgICB0dXJuTWV0aG9kcy5fZml0UGFnZS5jYWxsKHR1cm4sIGRkLnRwYWdlIHx8IG9wdHMubmV4dCwgdHJ1ZSk7CiAgICAgIH0KCiAgICB9IGVsc2UgewoKICAgICAgdHVybk1ldGhvZHMuX3JlbW92ZU12LmNhbGwodHVybiwgb3B0cy5wYWdlKTsKICAgICAgdHVybk1ldGhvZHMuX3VwZGF0ZVNoYWRvdy5jYWxsKHR1cm4pOwogICAgICB0dXJuLnR1cm4oJ3VwZGF0ZScpOwoKICAgIH0KICAgIAogIH0sCiAgCiAgLy8gVGhpcyBldmVudCBpcyBjYWxsZWQgaW4gY29udGV4dCBvZiBmbGlwCgogIF9wcmVzc2VkOiBmdW5jdGlvbihlKSB7CgogICAgZS5zdG9wUHJvcGFnYXRpb24oKTsKCiAgICB2YXIgcGFnZSwKICAgICAgZGF0YSA9ICQoZS50YXJnZXQpLmRhdGEoKS5mLAogICAgICBwYWdlcyA9IGRhdGEub3B0cy50dXJuLmRhdGEoKS5wYWdlczsKCiAgICBmb3IgKHBhZ2UgaW4gcGFnZXMpCiAgICAgIGlmIChwYWdlIT1kYXRhLm9wdHMucGFnZSkKICAgICAgICBwYWdlc1twYWdlXS5mbGlwKCdkaXNhYmxlJywgdHJ1ZSk7CgogICAgcmV0dXJuIGRhdGEudGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpOwoKICB9LAoKICAvLyBUaGlzIGV2ZW50IGlzIGNhbGxlZCBpbiBjb250ZXh0IG9mIGZsaXAKCiAgX3JlbGVhc2VkOiBmdW5jdGlvbihlLCBwb2ludCkgewoKICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7CgogICAgdmFyIG91dEFyZWEsCiAgICAgIHBhZ2UgPSAkKGUudGFyZ2V0KSwKICAgICAgZGF0YSA9IHBhZ2UuZGF0YSgpLmYsCiAgICAgIHR1cm4gPSBkYXRhLm9wdHMudHVybiwKICAgICAgdHVybkRhdGEgPSB0dXJuLmRhdGEoKTsKICAgIAogICAgaWYgKHR1cm5EYXRhLmRpc3BsYXk9PSdzaW5nbGUnKSB7CiAgICAgIG91dEFyZWEgPSAocG9pbnQuY29ybmVyPT0ncicpID8KICAgICAgICBwb2ludC54PHBhZ2Uud2lkdGgoKS8yOgogICAgICAgIHBvaW50Lng+cGFnZS53aWR0aCgpLzI7CiAgICB9IGVsc2UgewogICAgICBvdXRBcmVhID0gcG9pbnQueDwwIHx8IHBvaW50Lng+cGFnZS53aWR0aCgpOwogICAgfQoKICAgIGlmICgobmV3IERhdGUoKSkuZ2V0VGltZSgpLWRhdGEudGltZTwyMDAgfHwgb3V0QXJlYSkgewoKICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOwoKICAgICAgdHVybk1ldGhvZHMuX3R1cm5QYWdlLmNhbGwoCiAgICAgICAgdHVybiwKICAgICAgICBkYXRhLm9wdHMubmV4dCwKICAgICAgICBmbGlwTWV0aG9kcy5fY29ybmVyQWN0aXZhdGVkLmNhbGwocGFnZSwgcG9pbnQsIDEpID09PSBmYWxzZQogICAgICApOwoKICAgIH0KCiAgICB0dXJuRGF0YS5tb3VzZUFjdGlvbiA9IGZhbHNlOwoKICB9LAoKICAvLyBUaGlzIGV2ZW50IGlzIGNhbGxlZCBpbiBjb250ZXh0IG9mIGZsaXAKICAKICBfZmxpcDogZnVuY3Rpb24oZSkgewoKICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7CgogICAgdmFyIG9wdHMgPSAkKGUudGFyZ2V0KS5kYXRhKCkuZi5vcHRzOwoKICAgIG9wdHMudHVybi50cmlnZ2VyKCd0dXJuJywgW29wdHMubmV4dF0pOwoKICAgIGlmIChvcHRzLnR1cm4uZGF0YSgpLm9wdHMuYXV0b0NlbnRlcikKICAgICAgb3B0cy50dXJuLnR1cm4oJ2NlbnRlcicsIG9wdHMubmV4dCk7CgogIH0sCgogIC8vIENhbGN1bGF0ZSB0aGUgei1pbmRleCB2YWx1ZSBmb3IgcGFnZXMgZHVyaW5nIHRoZSBhbmltYXRpb24KCiAgY2FsY3VsYXRlWjogZnVuY3Rpb24obXYpIHsKCiAgICB2YXIgaSwgcGFnZSwgbmV4dFBhZ2UsIHBsYWNlUGFnZSwgZHBhZ2UsCiAgICAgIHRoYXQgPSB0aGlzLAogICAgICBkYXRhID0gdGhpcy5kYXRhKCksCiAgICAgIHZpZXcgPSB0aGlzLnR1cm4oJ3ZpZXcnKSwKICAgICAgY3VycmVudFBhZ2UgPSB2aWV3WzBdIHx8IHZpZXdbMV0sCiAgICAgIHIgPSB7cGFnZVo6IHt9LCBwYXJ0Wjoge30sIHBhZ2VWOiB7fX0sCgogICAgICBhZGRWaWV3ID0gZnVuY3Rpb24ocGFnZSkgewogICAgICAgIHZhciB2aWV3ID0gdGhhdC50dXJuKCd2aWV3JywgcGFnZSk7CiAgICAgICAgaWYgKHZpZXdbMF0pIHIucGFnZVZbdmlld1swXV0gPSB0cnVlOwogICAgICAgIGlmICh2aWV3WzFdKSByLnBhZ2VWW3ZpZXdbMV1dID0gdHJ1ZTsKICAgICAgfTsKICAgIAogICAgZm9yIChpID0gMDsgaTxtdi5sZW5ndGg7IGkrKykgewogICAgICBwYWdlID0gbXZbaV07CiAgICAgIG5leHRQYWdlID0gZGF0YS5wYWdlc1twYWdlXS5kYXRhKCkuZi5vcHRzLm5leHQ7CiAgICAgIHBsYWNlUGFnZSA9IGRhdGEucGFnZVBsYWNlW3BhZ2VdOwogICAgICBhZGRWaWV3KHBhZ2UpOwogICAgICBhZGRWaWV3KG5leHRQYWdlKTsKICAgICAgZHBhZ2UgPSAoZGF0YS5wYWdlUGxhY2VbbmV4dFBhZ2VdPT1uZXh0UGFnZSkgPyBuZXh0UGFnZSA6IHBhZ2U7CiAgICAgIHIucGFnZVpbZHBhZ2VdID0gZGF0YS50b3RhbFBhZ2VzIC0gTWF0aC5hYnMoY3VycmVudFBhZ2UtZHBhZ2UpOwogICAgICByLnBhcnRaW3BsYWNlUGFnZV0gPSBkYXRhLnRvdGFsUGFnZXMqMiArIE1hdGguYWJzKGN1cnJlbnRQYWdlLWRwYWdlKTsKICAgIH0KCiAgICByZXR1cm4gcjsKICB9LAoKICAvLyBVcGRhdGVzIHRoZSB6LWluZGV4IGFuZCBkaXNwbGF5IHByb3BlcnR5IG9mIGV2ZXJ5IHBhZ2UKCiAgdXBkYXRlOiBmdW5jdGlvbigpIHsKCiAgICB2YXIgcGFnZSwKICAgICAgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIGlmIChkYXRhLnBhZ2VNdi5sZW5ndGggJiYgZGF0YS5wYWdlTXZbMF0hPT0wKSB7CgogICAgICAvLyBVcGRhdGUgbW90aW9uCgogICAgICB2YXIgcCwKICAgICAgICBmaXhlZCwKICAgICAgICBwb3MgPSB0aGlzLnR1cm4oJ2NhbGN1bGF0ZVonLCBkYXRhLnBhZ2VNdiksCiAgICAgICAgdmlldyA9IHRoaXMudHVybigndmlldycsIGRhdGEudHBhZ2UpOwogICAgCiAgICAgIGZvciAocGFnZSBpbiBkYXRhLnBhZ2VXcmFwKSB7CgogICAgICAgIGlmICghaGFzKHBhZ2UsIGRhdGEucGFnZVdyYXApKQogICAgICAgICAgY29udGludWU7CgogICAgICAgIGZpeGVkID0gZGF0YS5wYWdlT2Jqc1twYWdlXS5oYXNDbGFzcygnZml4ZWQnKTsKCiAgICAgICAgZGF0YS5wYWdlV3JhcFtwYWdlXS5jc3MoewogICAgICAgICAgZGlzcGxheTogKHBvcy5wYWdlVltwYWdlXSB8fCBmaXhlZCkgPyAnJyA6ICdub25lJywKICAgICAgICAgICd6LWluZGV4JzogcG9zLnBhZ2VaW3BhZ2VdIHx8ICgoZml4ZWQpID8gLTEgOiAwKQogICAgICAgIH0pOwoKICAgICAgICBpZiAoKHAgPSBkYXRhLnBhZ2VzW3BhZ2VdKSkgewogICAgICAgICAgcC5mbGlwKCd6JywgcG9zLnBhcnRaW3BhZ2VdIHx8IG51bGwpOwoKICAgICAgICAgIGlmIChwb3MucGFnZVZbcGFnZV0pCiAgICAgICAgICAgIHAuZmxpcCgncmVzaXplJyk7CgogICAgICAgICAgaWYgKGRhdGEudHBhZ2UpCiAgICAgICAgICAgIHAuZmxpcCgnZGlzYWJsZScsIHRydWUpOyAvLyBkYXRhLmRpc2FibGVkIHx8IHBhZ2UhPWFwYWdlCiAgICAgICAgfQogICAgICB9CiAgCiAgICB9IGVsc2UgewoKICAgICAgLy8gVXBkYXRlIHN0YXRpYyBwYWdlcwoKICAgICAgZm9yIChwYWdlIGluIGRhdGEucGFnZVdyYXApIHsKCiAgICAgICAgaWYgKCFoYXMocGFnZSwgZGF0YS5wYWdlV3JhcCkpCiAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgdmFyIHBhZ2VMb2NhdGlvbiA9IHR1cm5NZXRob2RzLl9zZXRQYWdlTG9jLmNhbGwodGhpcywgcGFnZSk7CgogICAgICAgIGlmIChkYXRhLnBhZ2VzW3BhZ2VdKQogICAgICAgICAgZGF0YS5wYWdlc1twYWdlXS5mbGlwKCdkaXNhYmxlJywKICAgICAgICAgICAgZGF0YS5kaXNhYmxlZCB8fCBwYWdlTG9jYXRpb24hPTEpLmZsaXAoJ3onLCBudWxsKTsKCiAgICAgIH0KICAgIH0KICB9LAoKICAvLyBVcGRhdGVzIHRoZSBwb3NpdGlvbiBhbmQgc2l6ZSBvZiB0aGUgZmxpcGJvb2sncyBzaGFkb3cKCiAgX3VwZGF0ZVNoYWRvdzogZnVuY3Rpb24oKSB7CiAgICAKICAgIHZhciB2aWV3LCB2aWV3Miwgc2hhZG93LAogICAgICBkYXRhID0gdGhpcy5kYXRhKCksCiAgICAgIHdpZHRoID0gdGhpcy53aWR0aCgpLAogICAgICBoZWlnaHQgPSB0aGlzLmhlaWdodCgpLAogICAgICBwYWdlV2lkdGggPSAoZGF0YS5kaXNwbGF5PT0nc2luZ2xlJykgPyB3aWR0aCA6IHdpZHRoLzI7CgogICAgdmlldyA9IHRoaXMudHVybigndmlldycpOwoKICAgIGlmICghZGF0YS5zaGFkb3cpIHsKICAgICAgZGF0YS5zaGFkb3cgPSAkKCc8ZGl2IC8+JywKICAgICAgewogICAgICAgICdjbGFzcyc6ICdzaGFkb3cnLAogICAgICAgICdjc3MnOiBkaXZBdHQoMCwgMCwgMCkuY3NzCiAgICAgIH0pLgogICAgICBhcHBlbmRUbyh0aGlzKTsKICAgIH0KCiAgICBmb3IgKHZhciBpID0gMDsgaTxkYXRhLnBhZ2VNdi5sZW5ndGg7IGkrKykgewogICAgICBpZiAoIXZpZXdbMF0gfHwgIXZpZXdbMV0pCiAgICAgICAgYnJlYWs7CiAgICAKICAgICAgdmlldyA9IHRoaXMudHVybigndmlldycsIGRhdGEucGFnZXNbZGF0YS5wYWdlTXZbaV1dLmRhdGEoKS5mLm9wdHMubmV4dCk7CiAgICAgIHZpZXcyID0gdGhpcy50dXJuKCd2aWV3JywgZGF0YS5wYWdlTXZbaV0pOwoKICAgICAgdmlld1swXSA9IHZpZXdbMF0gJiYgdmlldzJbMF07CiAgICAgIHZpZXdbMV0gPSB2aWV3WzFdICYmIHZpZXcyWzFdOwogICAgfQoKICAgIGlmICghdmlld1swXSkgc2hhZG93ID0gKGRhdGEuZGlyZWN0aW9uPT0nbHRyJykgPyAxIDogMjsKICAgIGVsc2UgaWYgKCF2aWV3WzFdKSBzaGFkb3cgPSAoZGF0YS5kaXJlY3Rpb249PSdsdHInKSA/IDIgOiAxOwogICAgZWxzZSBzaGFkb3cgPSAzOwoKICAgIHN3aXRjaCAoc2hhZG93KSB7CiAgICAgIGNhc2UgMToKICAgICAgICBkYXRhLnNoYWRvdy5jc3MoewogICAgICAgICAgd2lkdGg6IHBhZ2VXaWR0aCwKICAgICAgICAgIGhlaWdodDogaGVpZ2h0LAogICAgICAgICAgdG9wOiAwLAogICAgICAgICAgbGVmdDogcGFnZVdpZHRoCiAgICAgICAgfSk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMjoKICAgICAgICBkYXRhLnNoYWRvdy5jc3MoewogICAgICAgICAgd2lkdGg6IHBhZ2VXaWR0aCwKICAgICAgICAgIGhlaWdodDogaGVpZ2h0LAogICAgICAgICAgdG9wOiAwLAogICAgICAgICAgbGVmdDogMAogICAgICAgIH0pOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDM6CiAgICAgICAgZGF0YS5zaGFkb3cuY3NzKHsKICAgICAgICAgIHdpZHRoOiB3aWR0aCwKICAgICAgICAgIGhlaWdodDogaGVpZ2h0LAogICAgICAgICAgdG9wOiAwLAogICAgICAgICAgbGVmdDogMAogICAgICAgIH0pOwogICAgICAgIGJyZWFrOwogICAgfQoKICB9LAoKICAvLyBTZXRzIHRoZSB6LWluZGV4IGFuZCBkaXNwbGF5IHByb3BlcnR5IG9mIGEgcGFnZQogIC8vIEl0IGRlcGVuZHMgb24gdGhlIGN1cnJlbnQgdmlldwoKICBfc2V0UGFnZUxvYzogZnVuY3Rpb24ocGFnZSkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCksCiAgICAgIHZpZXcgPSB0aGlzLnR1cm4oJ3ZpZXcnKTsKCiAgICBpZiAocGFnZT09dmlld1swXSB8fCBwYWdlPT12aWV3WzFdKSB7CiAgICAgIAogICAgICBkYXRhLnBhZ2VXcmFwW3BhZ2VdLmNzcyh7ekluZGV4OiBkYXRhLnRvdGFsUGFnZXMsIGRpc3BsYXk6ICcnfSk7CiAgICAgIHJldHVybiAxOwoKICAgIH0gZWxzZSBpZiAoKGRhdGEuZGlzcGxheT09J3NpbmdsZScgJiYgcGFnZT09dmlld1swXSsxKSB8fAogICAgICAoZGF0YS5kaXNwbGF5PT0nZG91YmxlJyAmJiBwYWdlPT12aWV3WzBdLTIgfHwKICAgICAgcGFnZT09dmlld1sxXSsyKSkgewogICAgICAKICAgICAgZGF0YS5wYWdlV3JhcFtwYWdlXS5jc3Moe3pJbmRleDogZGF0YS50b3RhbFBhZ2VzLTEsIGRpc3BsYXk6ICcnfSk7CiAgICAgIHJldHVybiAyOwoKICAgIH0gZWxzZSB7CiAgICAgIAogICAgICBkYXRhLnBhZ2VXcmFwW3BhZ2VdLmNzcyh7ekluZGV4OiAwLAogICAgICAgIGRpc3BsYXk6IChkYXRhLnBhZ2VPYmpzW3BhZ2VdLmhhc0NsYXNzKCdmaXhlZCcpKSA/ICcnIDogJ25vbmUnfQogICAgICApOwoKICAgICAgcmV0dXJuIDA7CiAgICB9CiAgfSwKCiAgLy8gR2V0cyBhbmQgc2V0cyB0aGUgb3B0aW9ucwoKICBvcHRpb25zOiBmdW5jdGlvbihvcHRpb25zKSB7CiAgICAKICAgIGlmIChvcHRpb25zPT09dW5kZWZpbmVkKSB7CiAgICAgIAogICAgICByZXR1cm4gdGhpcy5kYXRhKCkub3B0czsKCiAgICB9IGVsc2UgewoKICAgICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKTsKCiAgICAgIC8vIFNldCBuZXcgdmFsdWVzCgogICAgICAkLmV4dGVuZChkYXRhLm9wdHMsIG9wdGlvbnMpOwogICAgICAKICAgICAgLy8gU2V0IHBhZ2VzCgogICAgICBpZiAob3B0aW9ucy5wYWdlcykKICAgICAgICB0aGlzLnR1cm4oJ3BhZ2VzJywgb3B0aW9ucy5wYWdlcyk7CgogICAgICAvLyBTZXQgcGFnZQoKICAgICAgaWYgKG9wdGlvbnMucGFnZSkKICAgICAgICB0aGlzLnR1cm4oJ3BhZ2UnLCBvcHRpb25zLnBhZ2UpOwoKICAgICAgLy8gU2V0IGRpc3BsYXkKCiAgICAgIGlmIChvcHRpb25zLmRpc3BsYXkpCiAgICAgICAgdGhpcy50dXJuKCdkaXNwbGF5Jywgb3B0aW9ucy5kaXNwbGF5KTsKICAgICAgCiAgICAgIC8vIFNldCBkaXJlY3Rpb24KCiAgICAgIGlmIChvcHRpb25zLmRpcmVjdGlvbikKICAgICAgICB0aGlzLnR1cm4oJ2RpcmVjdGlvbicsIG9wdGlvbnMuZGlyZWN0aW9uKTsKCiAgICAgIC8vIFNldCBzaXplCgogICAgICBpZiAob3B0aW9ucy53aWR0aCAmJiBvcHRpb25zLmhlaWdodCkKICAgICAgICB0aGlzLnR1cm4oJ3NpemUnLCBvcHRpb25zLndpZHRoLCBvcHRpb25zLmhlaWdodCk7CiAgICAgIAogICAgICAvLyBBZGQgZXZlbnQgbGlzdGVuZXJzCgogICAgICBpZiAob3B0aW9ucy53aGVuKQogICAgICAgIGZvciAodmFyIGV2ZW50TmFtZSBpbiBvcHRpb25zLndoZW4pCiAgICAgICAgICBpZiAoaGFzKGV2ZW50TmFtZSwgb3B0aW9ucy53aGVuKSkgewogICAgICAgICAgICB0aGlzLnVuYmluZChldmVudE5hbWUpLgogICAgICAgICAgICAgIGJpbmQoZXZlbnROYW1lLCBvcHRpb25zLndoZW5bZXZlbnROYW1lXSk7CiAgICAgICAgICB9CgogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgfSwKCiAgLy8gR2V0cyB0aGUgY3VycmVudCB2ZXJzaW9uCgogIHZlcnNpb246IGZ1bmN0aW9uKCkgewoKICAgIHJldHVybiB2ZXJzaW9uOwoKICB9Cn0sCgovLyBNZXRob2RzIGFuZCBwcm9wZXJ0aWVzIGZvciB0aGUgZmxpcCBwYWdlIGVmZmVjdAoKZmxpcE1ldGhvZHMgPSB7CgogIC8vIENvbnN0cnVjdG9yCgogIGluaXQ6IGZ1bmN0aW9uKG9wdHMpIHsKCiAgICB0aGlzLmRhdGEoe2Y6CiAgICAgIHtlZmZlY3Q6IChvcHRzLmNvcm5lcnM9PSdyJyB8fCBvcHRzLmNvcm5lcnM9PSdsJykgPyAnaGFyZCcgOiAnc2hlZXQnfX0KICAgICk7CgogICAgdGhpcy5mbGlwKCdvcHRpb25zJywgb3B0cyk7CgogICAgZmxpcE1ldGhvZHMuX2FkZFBhZ2VXcmFwcGVyLmNhbGwodGhpcyk7CgogICAgcmV0dXJuIHRoaXM7CiAgfSwKCiAgc2V0RGF0YTogZnVuY3Rpb24oZCkgewogICAgCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIGRhdGEuZiA9ICQuZXh0ZW5kKGRhdGEuZiwgZCk7CgogICAgcmV0dXJuIHRoaXM7CiAgfSwKCiAgb3B0aW9uczogZnVuY3Rpb24ob3B0cykgewogICAgCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmY7CgogICAgaWYgKG9wdHMpIHsKICAgICAgZmxpcE1ldGhvZHMuc2V0RGF0YS5jYWxsKHRoaXMsCiAgICAgICAge29wdHM6ICQuZXh0ZW5kKHt9LCBkYXRhLm9wdHMgfHwgZmxpcE9wdGlvbnMsIG9wdHMpfSk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfSBlbHNlCiAgICAgIHJldHVybiBkYXRhLm9wdHM7CgogIH0sCgogIHo6IGZ1bmN0aW9uKHopIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmY7CgogICAgaWYgKGRhdGEuZndyYXBwZXIpIHsKICAgICAgZGF0YS5vcHRzWyd6LWluZGV4J10gPSB6OwogICAgICBkYXRhLmZ3cmFwcGVyLmNzcygKICAgICAgICB7J3otaW5kZXgnOiB6IHx8IHBhcnNlSW50KGRhdGEucGFyZW50LmNzcygnei1pbmRleCcpLCAxMCkgfHwgMH0KICAgICAgKTsKICAgIH0KCiAgICByZXR1cm4gdGhpczsKICB9LAoKICBfY0FsbG93ZWQ6IGZ1bmN0aW9uKCkgewogICAgCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmYsCiAgICB0dXJuRGF0YSA9IGRhdGEub3B0cy50dXJuLmRhdGEoKSwKICAgIHBhZ2UgPSBkYXRhLm9wdHMucGFnZSwKICAgIG9kZCA9IHBhZ2UlMjsKCiAgICBpZiAodHVybkRhdGEuZGlzcGxheT09J3NpbmdsZScpIHsKICAgICAgaWYgKHBhZ2U9PTEpCiAgICAgICAgcmV0dXJuICh0dXJuRGF0YS5kaXJlY3Rpb249PSdsdHInKSA/CiAgICAgICAgICBjb3JuZXJzWydmb3J3YXJkJ10gOiBjb3JuZXJzWydiYWNrd2FyZCddOwogICAgICBlbHNlIGlmIChwYWdlPT10dXJuRGF0YS50b3RhbFBhZ2VzKQogICAgICAgIHJldHVybiAodHVybkRhdGEuZGlyZWN0aW9uPT0nbHRyJykgPwogICAgICAgICAgY29ybmVyc1snYmFja3dhcmQnXSA6IGNvcm5lcnNbJ2ZvcndhcmQnXTsKICAgICAgZWxzZQogICAgICAgIHJldHVybiBjb3JuZXJzWydhbGwnXTsKICAgIH0gZWxzZSB7CgogICAgICByZXR1cm4gKHR1cm5EYXRhLmRpcmVjdGlvbj09J2x0cicpID8KICAgICAgICBjb3JuZXJzWyhvZGQpID8gJ2ZvcndhcmQnIDogJ2JhY2t3YXJkJ10KICAgICAgICA6CiAgICAgICAgY29ybmVyc1sob2RkKSA/ICdiYWNrd2FyZCcgOiAnZm9yd2FyZCddOwoKICAgIH0KCiAgfSwKCiAgX2Nvcm5lckFjdGl2YXRlZDogZnVuY3Rpb24oZSkgewogIAogIAogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKS5mLAogICAgICBwb3MgPSBkYXRhLnBhcmVudC5vZmZzZXQoKSwKICAgICAgd2lkdGggPSB0aGlzLndpZHRoKCksCiAgICAgIGhlaWdodCA9IHRoaXMuaGVpZ2h0KCksCiAgICAgIGMgPSB7eDogTWF0aC5tYXgoMCwgZS5wYWdlWC1wb3MubGVmdCksIHk6IE1hdGgubWF4KDAsIGUucGFnZVktcG9zLnRvcCl9LAogICAgICBjc3ogPSBkYXRhLm9wdHMuY29ybmVyU2l6ZTsKCiAgICBpZiAoYy54PD0wIHx8IGMueTw9MCB8fCBjLng+PXdpZHRoIHx8IGMueT49aGVpZ2h0KQogICAgICByZXR1cm4gZmFsc2U7CgogICAgdmFyIGFsbG93ZWRDb3JuZXJzID0gZmxpcE1ldGhvZHMuX2NBbGxvd2VkLmNhbGwodGhpcyk7CgogICAgaWYgKGMueD53aWR0aC1jc3opCiAgICAgIGMuY29ybmVyID0gJ3InOwogICAgZWxzZSBpZiAoYy54PGNzeikKICAgICAgYy5jb3JuZXIgPSAnbCc7CiAgICBlbHNlCiAgICAgIHJldHVybiBmYWxzZTsKCgogICAgcmV0dXJuICgkLmluQXJyYXkoYy5jb3JuZXIsIGFsbG93ZWRDb3JuZXJzKT09LTEpID8gZmFsc2UgOiBjOwoKICB9LAoKICBfYzogZnVuY3Rpb24oY29ybmVyLCBvcHRzKSB7CgogICAgb3B0cyA9IG9wdHMgfHwgMDsKCiAgICBzd2l0Y2ggKGNvcm5lcikgewogICAgICBjYXNlICdsJzoKICAgICAgICByZXR1cm4gcG9pbnQyRChvcHRzLCAwKTsKICAgICAgY2FzZSAncic6CiAgICAgICAgcmV0dXJuIHBvaW50MkQodGhpcy53aWR0aCgpLW9wdHMsIDApOwogICAgfQoKICB9LAoKICBfYzI6IGZ1bmN0aW9uKGNvcm5lcikgewoKICAgIHN3aXRjaCAoY29ybmVyKSB7CiAgICAgIGNhc2UgJ2wnOgogICAgICAgIHJldHVybiBwb2ludDJEKHRoaXMud2lkdGgoKSoyLCAwKTsKICAgICAgY2FzZSAncic6CiAgICAgICAgcmV0dXJuIHBvaW50MkQoLXRoaXMud2lkdGgoKSwgMCk7CiAgICB9CgogIH0sCgogIF9mb2xkaW5nUGFnZTogZnVuY3Rpb24oY29ybmVyKSB7CgogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKS5mLAogICAgICBvcHRzID0gZGF0YS5vcHRzOwoKICAgIGlmIChkYXRhLmZvbGRpbmcpIHJldHVybiBkYXRhLmZvbGRpbmc7CiAgICBlbHNlIGlmKG9wdHMudHVybikgewoKICAgICAgZGF0YSA9IG9wdHMudHVybi5kYXRhKCk7CiAgICAgIGlmIChkYXRhLmRpc3BsYXkgPT0gJ3NpbmdsZScpCiAgICAgICAgcmV0dXJuIChkYXRhLnBhZ2VPYmpzW29wdHMubmV4dF0pID8gZGF0YS5wYWdlT2Jqc1swXSA6IG51bGw7CiAgICAgIGVsc2UKICAgICAgICByZXR1cm4gZGF0YS5wYWdlT2Jqc1tvcHRzLm5leHRdOwogICAgfQoKICB9LAoKICBfYmFja0dyYWRpZW50OiBmdW5jdGlvbigpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmYsCiAgICAgIHR1cm4gPSBkYXRhLm9wdHMudHVybiwKICAgICAgZ3JhZGllbnQgPSBkYXRhLm9wdHMuZ3JhZGllbnRzICYmCiAgICAgICAgKCF0dXJuIHx8CiAgICAgICAgdHVybi5kYXRhKCkuZGlzcGxheT09J3NpbmdsZScgfHwKICAgICAgICAoZGF0YS5vcHRzLnBhZ2UhPTIgJiYgZGF0YS5vcHRzLnBhZ2UhPXR1cm4uZGF0YSgpLnRvdGFsUGFnZXMtMSkpOwoKCiAgICByZXR1cm4gZ3JhZGllbnQ7CgogIH0sCgogIHJlc2l6ZTogZnVuY3Rpb24oZnVsbCkgewogICAgCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmYsCiAgICAgIHdpZHRoID0gdGhpcy53aWR0aCgpLAogICAgICBoZWlnaHQgPSB0aGlzLmhlaWdodCgpOwoKCiAgICBpZiAoZnVsbCkgewogICAgICBkYXRhLndyYXBwZXIuY3NzKHt3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0fSk7CiAgICAgIGRhdGEuZnBhZ2UuY3NzKHt3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0fSk7CiAgICB9CgogIH0sCgogIC8vIFByZXBhcmVzIHRoZSBwYWdlIGJ5IGFkZGluZyBhIGdlbmVyYWwgd3JhcHBlciBhbmQgYW5vdGhlciBvYmplY3RzCgogIF9hZGRQYWdlV3JhcHBlcjogZnVuY3Rpb24oKSB7CgogICAgdmFyIGF0dCwKICAgICAgZGF0YSA9IHRoaXMuZGF0YSgpLmYsCiAgICAgIHBhcmVudCA9IHRoaXMucGFyZW50KCk7CgogICAgZGF0YS5wYXJlbnQgPSBwYXJlbnQ7CgogICAgaWYgKCFkYXRhLndyYXBwZXIpIHsKICAgICAgICAKICAgICAgdmFyIGNzc1Byb3BlcnRpZXMgPSB7fTsKCiAgICAgIGRhdGEud3JhcHBlciA9ICQoJzxkaXYvPicsIGRpdkF0dCgwLCAwLCAyKSkuCiAgICAgICAgY3NzKGNzc1Byb3BlcnRpZXMpLgogICAgICAgIGFwcGVuZFRvKHBhcmVudCkuCiAgICAgICAgcHJlcGVuZCh0aGlzKTsKCiAgICAgIGRhdGEuZnBhZ2UgPSAkKCc8ZGl2Lz4nLCBkaXZBdHQoMCwgMCwgMSkpLgogICAgICAgIGNzcyhjc3NQcm9wZXJ0aWVzKS4KICAgICAgICBhcHBlbmRUbyhwYXJlbnQpOwoKICAgIH0KCiAgICAvLyBTZXQgc2l6ZQogICAgZmxpcE1ldGhvZHMucmVzaXplLmNhbGwodGhpcywgdHJ1ZSk7CgogIH0sCgogIC8vIFRha2VzIGEgMlAgcG9pbnQgZnJvbSB0aGUgc2NyZWVuIGFuZCBhcHBsaWVzIHRoZSB0cmFuc2Zvcm1hdGlvbgoKICBfZm9sZDogZnVuY3Rpb24ocG9pbnQpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmYsCiAgICAgIG8gPSBmbGlwTWV0aG9kcy5fYy5jYWxsKHRoaXMsIHBvaW50LmNvcm5lciksCiAgICAgIHJlbFggPSAoby54KSA/IG8ueCAtIHBvaW50LnggOiAgcG9pbnQueCwKICAgICAgd2lkdGggPSB0aGlzLndpZHRoKCksCiAgICAgIGhlaWdodCA9IHRoaXMuaGVpZ2h0KCk7CgogICAgICByZWxYID0gTWF0aC5taW4od2lkdGgqMiwgTWF0aC5tYXgoMCwgcmVsWCkpOwoKCiAgICAgIHN3aXRjaChwb2ludC5jb3JuZXIpIHsKICAgICAgICBjYXNlICdyJyA6CiAgICAgICAgICBkYXRhLndyYXBwZXIuY3NzKHsKICAgICAgICAgICAgd2lkdGg6IE1hdGgubWF4KDAsIHdpZHRoLXJlbFgpCiAgICAgICAgICB9KTsKICAgICAgICAgIHRoaXMuY3NzKHsKICAgICAgICAgICAgcG9zaXRpb246ICdyZWxhdGl2ZScsCiAgICAgICAgICAgIGxlZnQ6IC1yZWxYCiAgICAgICAgICB9KTsKCiAgICAgICAgICBkYXRhLmZwYWdlLmNzcyh7CiAgICAgICAgICAgIGxlZnQ6IC1yZWxYICsgd2lkdGgsCiAgICAgICAgICAgIHdpZHRoOiBNYXRoLm1heCgwLCByZWxYLXdpZHRoKQogICAgICAgICAgfSk7CiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnbCcgOgoKICAgICAgICAgIGRhdGEud3JhcHBlci5jc3MoewogICAgICAgICAgICB3aWR0aDogd2lkdGgKICAgICAgICAgIH0pOwogICAgICAgICAgdGhpcy5jc3MoewogICAgICAgICAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJywKICAgICAgICAgICAgbGVmdDogcmVsWAogICAgICAgICAgfSk7CgogICAgICAgICAgZGF0YS5mcGFnZS5jc3MoewogICAgICAgICAgICBsZWZ0OiB3aWR0aCwKICAgICAgICAgICAgd2lkdGg6IE1hdGgubWF4KDAsIHJlbFgtd2lkdGgpCiAgICAgICAgICB9KTsKCiAgICAgICAgICBpZiAoZGF0YS5mb2xkaW5nKQogICAgICAgICAgICBkYXRhLmZvbGRpbmcuY3NzKHsKICAgICAgICAgICAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJywKICAgICAgICAgICAgICBsZWZ0OiAtd2lkdGgqMiArIHJlbFgKICAgICAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgYnJlYWs7CiAgICAgIH0KCiAgICAgIGRhdGEucGFyZW50LmNzcyh7J292ZXJmbG93JzogJ3Zpc2libGUnfSk7CgogICAgZGF0YS5wb2ludCA9IHBvaW50OwogIAogIH0sCgogIF9tb3ZlRm9sZGluZ1BhZ2U6IGZ1bmN0aW9uKGJvb2wpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmY7CiAgICAgIAogICAgaWYgKGJvb2wpIHsKICAgICAgCiAgICAgIHZhciBmb2xkaW5nID0gZmxpcE1ldGhvZHMuX2ZvbGRpbmdQYWdlLmNhbGwodGhpcyksCiAgICAgICAgdHVybiA9IGRhdGEub3B0cy50dXJuOwogICAgICAKICAgICAgaWYgKGZvbGRpbmcpIHsKCiAgICAgICAgaWYgKGRhdGEuZm9sZGluZykgewogICAgICAgICAgaWYgKGRhdGEuZm9sZGluZz09PWZvbGRpbmcpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIGZsaXBNZXRob2RzLl9tb3ZlRm9sZGluZ1BhZ2UuY2FsbCh0aGlzLCBmYWxzZSk7CiAgICAgICAgfQogICAgICAKICAgICAgICBmbGlwTWV0aG9kcy5zZXREYXRhLmNhbGwodGhpcywKICAgICAgICAgIHtiYWNrUGFyZW50OiBmb2xkaW5nLnBhcmVudCgpLAogICAgICAgICAgZm9sZGluZzogZm9sZGluZ30pOwoKICAgICAgICBkYXRhLmZwYWdlLnByZXBlbmQoZm9sZGluZyk7CgogICAgICB9CgogICAgICB0dXJuLnR1cm4oJ3VwZGF0ZScpOwoKICAgIH0gZWxzZSB7CiAgICAgIGlmIChkYXRhLmJhY2tQYXJlbnQpIHsKICAgICAgICBkYXRhLmJhY2tQYXJlbnQucHJlcGVuZChkYXRhLmZvbGRpbmcpOwogICAgICAgIGRlbGV0ZSBkYXRhLmJhY2tQYXJlbnQ7CiAgICAgICAgZGVsZXRlIGRhdGEuZm9sZGluZzsKICAgICAgfQogICAgfQogIH0sCgogIF9zaG93Rm9sZGVkUGFnZTogZnVuY3Rpb24oYywgYW5pbWF0ZSkgewoKICAgIHZhciBmb2xkaW5nID0gZmxpcE1ldGhvZHMuX2ZvbGRpbmdQYWdlLmNhbGwodGhpcyksCiAgICAgIGRkID0gdGhpcy5kYXRhKCksCiAgICAgIGRhdGEgPSBkZC5mLAogICAgICB2aXNpYmxlID0gZGF0YS52aXNpYmxlOwoKICAgIGlmICghdmlzaWJsZSB8fCAhZGF0YS5wb2ludCB8fCBkYXRhLnBvaW50LmNvcm5lciE9Yy5jb3JuZXIpIHsKICAgICAgCiAgICAgIHZhciBtQWN0aW9uID0gZGF0YS5vcHRzLnR1cm4uZGF0YSgpLm1vdXNlQWN0aW9uOwoKICAgICAgdmFyIGV2ZW50ID0gJC5FdmVudCgnc3RhcnQnKTsKICAgICAgdGhpcy50cmlnZ2VyKGV2ZW50LCBbZGF0YS5vcHRzLCBjLmNvcm5lcl0pOwogICAgICB2aXNpYmxlID0gZmFsc2U7CgogICAgICBpZiAoZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIH0KCiAgICBpZiAoZm9sZGluZykgewoKICAgICAgaWYgKGFuaW1hdGUpIHsKICAgICAgICAKICAgICAgICB2YXIgdGhhdCA9IHRoaXMsCiAgICAgICAgICBwb2ludCA9IChkYXRhLnBvaW50ICYmIGRhdGEucG9pbnQuY29ybmVyPT1jLmNvcm5lcikgPwogICAgICAgICAgZGF0YS5wb2ludCA6IGZsaXBNZXRob2RzLl9jLmNhbGwodGhpcywgYy5jb3JuZXIsIDEpOwogICAgICAKICAgICAgICB0aGlzLmFuaW1hdGVmKHtmcm9tOiBbcG9pbnQueCwgcG9pbnQueV0sCiAgICAgICAgICB0bzogW2MueCwgYy55XSwKICAgICAgICAgIGR1cmF0aW9uOiA1MDAsCiAgICAgICAgICBmcmFtZTogZnVuY3Rpb24odikgewogICAgICAgICAgICBjLnggPSBNYXRoLnJvdW5kKHZbMF0pOwogICAgICAgICAgICBjLnkgPSBNYXRoLnJvdW5kKHZbMV0pOwogICAgICAgICAgICBmbGlwTWV0aG9kcy5fZm9sZC5jYWxsKHRoYXQsIGMpOwogICAgICAgICAgfX0pOwoKICAgICAgfSBlbHNlICB7CgogICAgICAgIGZsaXBNZXRob2RzLl9mb2xkLmNhbGwodGhpcywgYyk7CiAgICAgICAgaWYgKGRkLmVmZmVjdCAmJiAhZGQuZWZmZWN0LnR1cm5pbmcpCiAgICAgICAgICB0aGlzLmFuaW1hdGVmKGZhbHNlKTsKCiAgICAgIH0KCiAgICAgIGlmICghdmlzaWJsZSkgewoKICAgICAgICBkYXRhLnZpc2libGUgPSB0cnVlOwogICAgICAgIGZsaXBNZXRob2RzLl9tb3ZlRm9sZGluZ1BhZ2UuY2FsbCh0aGlzLCB0cnVlKTsKICAgICAgICBkYXRhLmZwYWdlLnNob3coKTsKICAgICAgfQoKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcmV0dXJuIGZhbHNlOwogIH0sCgogIGhpZGU6IGZ1bmN0aW9uKCkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCkuZiwKICAgICAgZm9sZGluZyA9IGZsaXBNZXRob2RzLl9mb2xkaW5nUGFnZS5jYWxsKHRoaXMpOwoKICAgIHRoaXMuY3NzKHsKICAgICAgcG9zaXRpb246ICcnLAogICAgICBsZWZ0OiAnYXV0bycKICAgIH0pOwoKICAgIGRhdGEud3JhcHBlci5jc3MoewogICAgICB3aWR0aDogdGhpcy53aWR0aCgpCiAgICB9KTsKCiAgICBkYXRhLmZwYWdlLmNzcyh7CiAgICAgIHdpZHRoOiB0aGlzLndpZHRoKCkKICAgIH0pOwoKICAgIGlmIChkYXRhLmZvbGRpbmcpCiAgICAgIGRhdGEuZm9sZGluZy5jc3MoewogICAgICAgIHBvc2l0aW9uOiAnJywKICAgICAgICBsZWZ0OiAnYXV0bycKICAgICAgfSk7CgogICAgZGF0YS5mcGFnZS5oaWRlKCk7CgogICAgZGF0YS52aXNpYmxlID0gZmFsc2U7CgogICAgcmV0dXJuIHRoaXM7CiAgfSwKCiAgaGlkZUZvbGRlZFBhZ2U6IGZ1bmN0aW9uKGFuaW1hdGUpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmY7CgogICAgaWYgKCFkYXRhLnBvaW50KSByZXR1cm47CgogICAgdmFyIHRoYXQgPSB0aGlzLAogICAgICBwMSA9IGRhdGEucG9pbnQsCiAgICAgIGhpZGUgPSBmdW5jdGlvbigpIHsKICAgICAgICBkYXRhLnBvaW50ID0gbnVsbDsKICAgICAgICB0aGF0LmZsaXAoJ2hpZGUnKTsKICAgICAgICB0aGF0LnRyaWdnZXIoJ2VuZCcsIFtkYXRhLm9wdHMsIGZhbHNlXSk7CiAgICAgIH07CgogICAgaWYgKGFuaW1hdGUpIHsKICAgICAgdmFyIHA0ID0gZmxpcE1ldGhvZHMuX2MuY2FsbCh0aGlzLCBwMS5jb3JuZXIpLAogICAgICAgIHRvcCA9IChwMS5jb3JuZXIuc3Vic3RyKDAsMSk9PSd0JyksCiAgICAgICAgZGVsdGEgPSAodG9wKSA/IE1hdGgubWluKDAsIHAxLnktcDQueSkvMiA6IE1hdGgubWF4KDAsIHAxLnktcDQueSkvMiwKICAgICAgICBwMiA9IHBvaW50MkQocDEueCwgcDEueStkZWx0YSksCiAgICAgICAgcDMgPSBwb2ludDJEKHA0LngsIHA0LnktZGVsdGEpOwogICAgCiAgICAgIHRoaXMuYW5pbWF0ZWYoewogICAgICAgIGZyb206IDAsCiAgICAgICAgdG86IDEsCiAgICAgICAgZnJhbWU6IGZ1bmN0aW9uKHYpIHsKICAgICAgICAgIHZhciBucCA9IGJlemllcihwMSwgcDIsIHAzLCBwNCwgdik7CiAgICAgICAgICBwMS54ID0gbnAueDsKICAgICAgICAgIHAxLnkgPSBucC55OwogICAgICAgICAgZmxpcE1ldGhvZHMuX2ZvbGQuY2FsbCh0aGF0LCBwMSk7CiAgICAgICAgfSwKICAgICAgICBjb21wbGV0ZTogaGlkZSwKICAgICAgICBkdXJhdGlvbjogODAwLAogICAgICAgIGhpZGluZzogdHJ1ZQogICAgICAgIH0pOwoKICAgIH0gZWxzZSB7CiAgICAgIHRoaXMuYW5pbWF0ZWYoZmFsc2UpOwogICAgICBoaWRlKCk7CiAgICB9CiAgfSwKCiAgdHVyblBhZ2U6IGZ1bmN0aW9uKGNvcm5lcikgewoKICAgIHZhciB0aGF0ID0gdGhpcywKICAgICAgZGF0YSA9IHRoaXMuZGF0YSgpLmY7CgogICAgY29ybmVyID0ge2Nvcm5lcjogKGRhdGEuY29ybmVyKSA/CiAgICAgIGRhdGEuY29ybmVyLmNvcm5lciA6CiAgICAgIGNvcm5lciB8fCBmbGlwTWV0aG9kcy5fY0FsbG93ZWQuY2FsbCh0aGlzKVswXX07CgogICAgdmFyIHAxID0gZGF0YS5wb2ludCB8fAogICAgICBmbGlwTWV0aG9kcy5fYy5jYWxsKHRoaXMsCiAgICAgICAgY29ybmVyLmNvcm5lciwKICAgICAgICAoZGF0YS5vcHRzLnR1cm4pID8gZGF0YS5vcHRzLnR1cm4uZGF0YSgpLm9wdHMuZWxldmF0aW9uIDogMCksCiAgICAgIHA0ID0gZmxpcE1ldGhvZHMuX2MyLmNhbGwodGhpcywgY29ybmVyLmNvcm5lcik7CgogICAgICB0aGlzLnRyaWdnZXIoJ2ZsaXAnKS4KICAgICAgICBhbmltYXRlZih7CiAgICAgICAgICBmcm9tOiAwLAogICAgICAgICAgdG86IDEsCiAgICAgICAgICBmcmFtZTogZnVuY3Rpb24odikgewogICAgICAgICAgICB2YXIgbnAgPSBiZXppZXIocDEsIHAxLCBwNCwgcDQsIHYpOwogICAgICAgICAgICBjb3JuZXIueCA9IG5wLng7CiAgICAgICAgICAgIGNvcm5lci55ID0gbnAueTsKCiAgICAgICAgICAgIGZsaXBNZXRob2RzLl9zaG93Rm9sZGVkUGFnZS5jYWxsKHRoYXQsIGNvcm5lcik7CiAgICAgICAgICB9LAogICAgICAgICAgCiAgICAgICAgICBjb21wbGV0ZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHRoYXQudHJpZ2dlcignZW5kJywgW2RhdGEub3B0cywgdHJ1ZV0pOwogICAgICAgICAgfSwKICAgICAgICAgIGR1cmF0aW9uOiBkYXRhLm9wdHMuZHVyYXRpb24sCiAgICAgICAgICB0dXJuaW5nOiB0cnVlCiAgICAgICAgfSk7CgogICAgICBkYXRhLmNvcm5lciA9IG51bGw7CiAgfSwKCiAgbW92aW5nOiBmdW5jdGlvbigpIHsKCiAgICByZXR1cm4gJ2VmZmVjdCcgaW4gdGhpcy5kYXRhKCk7CiAgCiAgfSwKCiAgaXNUdXJuaW5nOiBmdW5jdGlvbigpIHsKCiAgICByZXR1cm4gdGhpcy5mbGlwKCdtb3ZpbmcnKSAmJiB0aGlzLmRhdGEoKS5lZmZlY3QudHVybmluZzsKICAKICB9LAoKICBfZXZlbnRTdGFydDogZnVuY3Rpb24oZSkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCkuZjsKCiAgICBpZiAoIWRhdGEuZGlzYWJsZWQgJiYgIXRoaXMuZmxpcCgnaXNUdXJuaW5nJykpIHsKCiAgICAgIGRhdGEuY29ybmVyID0gZmxpcE1ldGhvZHMuX2Nvcm5lckFjdGl2YXRlZC5jYWxsKHRoaXMsIGUpOwogICAgCiAgICAgIGlmIChkYXRhLmNvcm5lciAmJiBmbGlwTWV0aG9kcy5fZm9sZGluZ1BhZ2UuY2FsbCh0aGlzLCBkYXRhLmNvcm5lcikpIHsKICAgICAgCiAgICAgICAgaWYgKGZsaXBNZXRob2RzLl9zaG93Rm9sZGVkUGFnZS5jYWxsKHRoaXMsIGRhdGEuY29ybmVyKSkKICAgICAgICAgIHRoaXMudHJpZ2dlcigncHJlc3NlZCcsIFtkYXRhLnBvaW50XSk7CgogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgIH0gZWxzZQogICAgICAgIGRhdGEuY29ybmVyID0gbnVsbDsKCiAgICB9CgogIH0sCgogIF9ldmVudE1vdmU6IGZ1bmN0aW9uKGUpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmY7CgogICAgaWYgKCFkYXRhLmRpc2FibGVkKSB7CgogICAgICBlID0gKGlzVG91Y2gpID8gZS5vcmlnaW5hbEV2ZW50LnRvdWNoZXMgOiBbZV07CiAgICAKICAgICAgaWYgKGRhdGEuY29ybmVyKSB7CgogICAgICAgIHZhciBwb3MgPSBkYXRhLnBhcmVudC5vZmZzZXQoKTsKICAgICAgICBkYXRhLmNvcm5lci54ID0gZVswXS5wYWdlWC1wb3MubGVmdDsKICAgICAgICBkYXRhLmNvcm5lci55ID0gZVswXS5wYWdlWS1wb3MudG9wOwogICAgICAgIGZsaXBNZXRob2RzLl9zaG93Rm9sZGVkUGFnZS5jYWxsKHRoaXMsIGRhdGEuY29ybmVyKTsKCiAgICAgIH0gZWxzZSBpZiAoIXRoaXMuZGF0YSgpLmVmZmVjdCAmJiB0aGlzLmlzKCc6dmlzaWJsZScpKSB7CiAgICAKCiAgICAgICAgdmFyIGNvcm5lciA9IGZsaXBNZXRob2RzLl9jb3JuZXJBY3RpdmF0ZWQuY2FsbCh0aGlzLCBlWzBdKTsKCiAgICAgICAgaWYgKGNvcm5lcikgewogICAgICAgICAgdmFyIG9yaWdpbiA9IGZsaXBNZXRob2RzLl9jLmNhbGwodGhpcywgY29ybmVyLmNvcm5lciwgZGF0YS5vcHRzLmNvcm5lclNpemUvMik7CiAgICAgICAgICBjb3JuZXIueCA9IG9yaWdpbi54OwogICAgICAgICAgY29ybmVyLnkgPSBvcmlnaW4ueTsKICAgICAgICAgIGZsaXBNZXRob2RzLl9zaG93Rm9sZGVkUGFnZS5jYWxsKHRoaXMsIGNvcm5lciwgdHJ1ZSk7CiAgICAgICAgfSBlbHNlCiAgICAgICAgICBmbGlwTWV0aG9kcy5oaWRlRm9sZGVkUGFnZS5jYWxsKHRoaXMsIHRydWUpOwogICAgICAgICAgICAgICAKCiAgICAgIH0KICAgIH0KICB9LAoKICBfZXZlbnRFbmQ6IGZ1bmN0aW9uKCkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCkuZjsKCiAgICBpZiAoIWRhdGEuZGlzYWJsZWQgJiYgZGF0YS5wb2ludCkgewogICAgICB2YXIgZXZlbnQgPSAkLkV2ZW50KCdyZWxlYXNlZCcpOwogICAgICB0aGlzLnRyaWdnZXIoZXZlbnQsIFtkYXRhLnBvaW50XSk7CiAgICAgIGlmICghZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkpCiAgICAgICAgZmxpcE1ldGhvZHMuaGlkZUZvbGRlZFBhZ2UuY2FsbCh0aGlzLCB0cnVlKTsKICAgIH0KCiAgICBkYXRhLmNvcm5lciA9IG51bGw7CgogIH0sCgogIGRpc2FibGU6IGZ1bmN0aW9uKGRpc2FibGUpIHsKCiAgICBmbGlwTWV0aG9kcy5zZXREYXRhLmNhbGwodGhpcywgeydkaXNhYmxlZCc6IGRpc2FibGV9KTsKICAgIHJldHVybiB0aGlzOwoKICB9Cn07CgoKCi8vIFByb2Nlc3NlcyBjbGFzc2VzCgpmdW5jdGlvbiBkZWNvcmF0b3IodGhhdCwgbWV0aG9kcywgYXJncykgewoKICBpZiAoIWFyZ3NbMF0gfHwgdHlwZW9mKGFyZ3NbMF0pPT0nb2JqZWN0JykKICAgIHJldHVybiBtZXRob2RzLmluaXQuYXBwbHkodGhhdCwgYXJncyk7CgogIGVsc2UgaWYgKG1ldGhvZHNbYXJnc1swXV0pCiAgICByZXR1cm4gbWV0aG9kc1thcmdzWzBdXS5hcHBseSh0aGF0LCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmdzLCAxKSk7CgogIGVsc2UKICAgIHRocm93IHR1cm5FcnJvcihhcmdzWzBdICsgJyBpcyBhbiBpbnZhbGlkIHZhbHVlJyk7Cn0KCgovLyBBdHRyaWJ1dGVzIGZvciBhIGxheWVyCgpmdW5jdGlvbiBkaXZBdHQodG9wLCBsZWZ0LCB6SW5kZXgsIG92ZXJmKSB7CiAgICAKICByZXR1cm4geydjc3MnOiB7CiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsCiAgICAgICAgdG9wOiB0b3AsCiAgICAgICAgbGVmdDogbGVmdCwKICAgICAgICAnb3ZlcmZsb3cnOiBvdmVyZiB8fCAnaGlkZGVuJywKICAgICAgICAnei1pbmRleCc6IHpJbmRleCB8fCAnYXV0bycKICAgICAgICB9CiAgICB9OwogICAgICAKfQoKLy8gR2V0cyBhIDJEIHBvaW50IGZyb20gYSBiZXppZXIgY3VydmUgb2YgZm91ciBwb2ludHMKCmZ1bmN0aW9uIGJlemllcihwMSwgcDIsIHAzLCBwNCwgdCkgewoKICB2YXIgYSA9IDEgLSB0LAogICAgYiA9IGEgKiBhICogYSwKICAgIGMgPSB0ICogdCAqIHQ7CiAgICAKICByZXR1cm4gcG9pbnQyRChNYXRoLnJvdW5kKGIqcDEueCArIDMqdCphKmEqcDIueCArIDMqdCp0KmEqcDMueCArIGMqcDQueCksCiAgICBNYXRoLnJvdW5kKGIqcDEueSArIDMqdCphKmEqcDIueSArIDMqdCp0KmEqcDMueSArIGMqcDQueSkpOwoKfQoKLy8gR2V0cyBhIDJEIHBvaW50CgpmdW5jdGlvbiBwb2ludDJEKHgsIHkpIHsKICAKICByZXR1cm4ge3g6IHgsIHk6IHl9OwoKfQoKLy8gQ2hlY2tzIGlmIGEgcHJvcGVydHkgYmVsb25ncyB0byBhbiBvYmplY3QKCmZ1bmN0aW9uIGhhcyhwcm9wZXJ0eSwgb2JqZWN0KSB7CiAgCiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsKCn0KCi8vIEdldHMgdGhlIENTUzMgdmVuZG9yIHByZWZpeAoKZnVuY3Rpb24gZ2V0UHJlZml4KCkgewoKICB2YXIgdmVuZG9yUHJlZml4ZXMgPSBbJ01veicsJ1dlYmtpdCcsJ0todG1sJywnTycsJ21zJ10sCiAgbGVuID0gdmVuZG9yUHJlZml4ZXMubGVuZ3RoLAogIHZlbmRvciA9ICcnOwoKICB3aGlsZSAobGVuLS0pCiAgICBpZiAoKHZlbmRvclByZWZpeGVzW2xlbl0gKyAnVHJhbnNmb3JtJykgaW4gZG9jdW1lbnQuYm9keS5zdHlsZSkKICAgICAgdmVuZG9yPSctJyt2ZW5kb3JQcmVmaXhlc1tsZW5dLnRvTG93ZXJDYXNlKCkrJy0nOwoKICByZXR1cm4gdmVuZG9yOwoKfQoKLy8gSlMgRXJyb3JzCgpmdW5jdGlvbiB0dXJuRXJyb3IobWVzc2FnZSkgewoKICBmdW5jdGlvbiBUdXJuSnNFcnJvcihtZXNzYWdlKSB7CiAgICB0aGlzLm5hbWUgPSAiVHVybkpzRXJyb3IiOwogICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTsKICB9CgogIFR1cm5Kc0Vycm9yLnByb3RvdHlwZSA9IG5ldyBFcnJvcigpOwogIFR1cm5Kc0Vycm9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFR1cm5Kc0Vycm9yOwoKICByZXR1cm4gbmV3IFR1cm5Kc0Vycm9yKG1lc3NhZ2UpOwp9CgovLyBGaW5kIHRoZSBvZmZzZXQgb2YgYW4gZWxlbWVudCBkaXNjYXJkaW5nIGl0cyB0cmFuc2Zvcm1hdGlvbgoKZnVuY3Rpb24gZmluZFBvcyhvYmopIHsKICB2YXIgb2Zmc2V0ID0ge3RvcDogMCwgbGVmdDogMH07CgogIGRvewogICAgb2Zmc2V0LmxlZnQgKz0gb2JqLm9mZnNldExlZnQ7CiAgICBvZmZzZXQudG9wICs9IG9iai5vZmZzZXRUb3A7CiAgfSB3aGlsZSAoKG9iaiA9IG9iai5vZmZzZXRQYXJlbnQpKTsKCiAgcmV0dXJuIG9mZnNldDsKfQoKCi8vIFJlcXVlc3QgYW4gYW5pbWF0aW9uCgp3aW5kb3cucmVxdWVzdEFuaW0gPSBmdW5jdGlvbihjYWxsYmFjaykgewogIHdpbmRvdy5zZXRUaW1lb3V0KGNhbGxiYWNrLCAxMDAwIC8gNjApOwp9CgoKZnVuY3Rpb24gZW1wdHlGdW5jdGlvbigpIHsKICByZXR1cm4gJyc7Cn0KCgovLyBFeHRlbmQgJC5mbgoKJC5leHRlbmQoJC5mbiwgewoKICBmbGlwOiBmdW5jdGlvbihyZXEsIG9wdHMpIHsKICAgIHJldHVybiBkZWNvcmF0b3IodGhpcywgZmxpcE1ldGhvZHMsIGFyZ3VtZW50cyk7CiAgfSwKCiAgdHVybjogZnVuY3Rpb24ocmVxKSB7CiAgICByZXR1cm4gZGVjb3JhdG9yKHRoaXMsIHR1cm5NZXRob2RzLCBhcmd1bWVudHMpOwogIH0sCgogIHRyYW5zZm9ybTogZnVuY3Rpb24odHJhbnNmb3JtLCBvcmlnaW4pIHsKCiAgICB2YXIgcHJvcGVydGllcyA9IHt9OwogICAgCiAgICBpZiAob3JpZ2luKQogICAgICBwcm9wZXJ0aWVzW3ZlbmRvcisndHJhbnNmb3JtLW9yaWdpbiddID0gb3JpZ2luOwogICAgCiAgICBwcm9wZXJ0aWVzW3ZlbmRvcisndHJhbnNmb3JtJ10gPSB0cmFuc2Zvcm07CiAgCiAgICByZXR1cm4gdGhpcy5jc3MocHJvcGVydGllcyk7CgogIH0sCgogIGFuaW1hdGVmOiBmdW5jdGlvbihwb2ludCkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCk7CgogICAgaWYgKGRhdGEuZWZmZWN0KQogICAgICBkYXRhLmVmZmVjdC5zdG9wKCk7CgogICAgaWYgKHBvaW50KSB7CgogICAgICBpZiAoIXBvaW50LnRvLmxlbmd0aCkgcG9pbnQudG8gPSBbcG9pbnQudG9dOwogICAgICBpZiAoIXBvaW50LmZyb20ubGVuZ3RoKSBwb2ludC5mcm9tID0gW3BvaW50LmZyb21dOwoKICAgICAgdmFyIGRpZmYgPSBbXSwKICAgICAgICBsZW4gPSBwb2ludC50by5sZW5ndGgsCiAgICAgICAgYW5pbWF0aW5nID0gdHJ1ZSwKICAgICAgICB0aGF0ID0gdGhpcywKICAgICAgICB0aW1lID0gKG5ldyBEYXRlKCkpLmdldFRpbWUoKSwKICAgICAgICBmcmFtZSA9IGZ1bmN0aW9uKCkgewoKICAgICAgICAgIGlmICghZGF0YS5lZmZlY3QgfHwgIWFuaW1hdGluZykKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgIHZhciB2ID0gW10sCiAgICAgICAgICAgIHRpbWVEaWZmID0gTWF0aC5taW4ocG9pbnQuZHVyYXRpb24sIChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkgLSB0aW1lKTsKCiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKQogICAgICAgICAgICB2LnB1c2goZGF0YS5lZmZlY3QuZWFzaW5nKDEsIHRpbWVEaWZmLCBwb2ludC5mcm9tW2ldLCBkaWZmW2ldLCBwb2ludC5kdXJhdGlvbikpOwoKICAgICAgICAgIHBvaW50LmZyYW1lKChsZW49PTEpID8gdlswXSA6IHYpOwoKICAgICAgICAgIGlmICh0aW1lRGlmZj09cG9pbnQuZHVyYXRpb24pIHsKICAgICAgICAgICAgZGVsZXRlIGRhdGFbJ2VmZmVjdCddOwogICAgICAgICAgICB0aGF0LmRhdGEoZGF0YSk7CiAgICAgICAgICAgIGlmIChwb2ludC5jb21wbGV0ZSkKICAgICAgICAgICAgICBwb2ludC5jb21wbGV0ZSgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltKGZyYW1lKTsKICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykKICAgICAgICBkaWZmLnB1c2gocG9pbnQudG9baV0gLSBwb2ludC5mcm9tW2ldKTsKCiAgICAgIGRhdGEuZWZmZWN0ID0gJC5leHRlbmQoewogICAgICAgIHN0b3A6IGZ1bmN0aW9uKCkgewogICAgICAgICAgYW5pbWF0aW5nID0gZmFsc2U7CiAgICAgICAgfSwKICAgICAgICBlYXNpbmc6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkYXRhKSB7CiAgICAgICAgICByZXR1cm4gYyAqIE1hdGguc3FydCgxIC0gKHQ9dC9kYXRhLTEpKnQpICsgYjsKICAgICAgICB9CiAgICAgIH0sIHBvaW50KTsKCiAgICAgIHRoaXMuZGF0YShkYXRhKTsKCiAgICAgIGZyYW1lKCk7CgogICAgfSBlbHNlIHsKICAgICAgCiAgICAgIGRlbGV0ZSBkYXRhWydlZmZlY3QnXTsKCiAgICB9CiAgfQp9KTsKCi8vIEV4cG9ydCBzb21lIGdsb2JhbHMKCiQuaXNUb3VjaCA9IGlzVG91Y2g7CiQubW91c2VFdmVudHMgPSBtb3VzZUV2ZW50czsKJC5jc3NQcmVmaXggPSBlbXB0eUZ1bmN0aW9uOwokLmNzc1RyYW5zaXRpb25FbmQgPSBlbXB0eUZ1bmN0aW9uOwokLmZpbmRQb3MgPSBmaW5kUG9zOwoKfSkoalF1ZXJ5KTs= '></script id=script_turnjs4_turn_html4_js_end>//