{"created_by":"Tampermonkey","version":"1","scripts":[{"name":"Simple YouTube Age Restriction Bypass","options":{"check_for_updates":true,"comment":null,"compatopts_for_requires":true,"compat_wrappedjsobject":false,"compat_metadata":false,"compat_foreach":false,"compat_powerful_this":null,"sandbox":null,"noframes":null,"unwrap":null,"run_at":null,"tab_types":null,"override":{"use_includes":[],"orig_includes":[],"merge_includes":true,"use_matches":[],"orig_matches":["https://www.youtube.com/*","https://www.youtube-nocookie.com/*","https://m.youtube.com/*","https://music.youtube.com/*"],"merge_matches":true,"use_excludes":[],"orig_excludes":[],"merge_excludes":true,"use_connects":[],"orig_connects":[],"merge_connects":true,"use_blockers":[],"orig_run_at":"document-start","orig_noframes":null},"user_modified":null},"storage":{"ts":1690579539894,"data":{}},"enabled":true,"position":1,"file_url":"https://github.com/zerodytrash/Simple-YouTube-Age-Restriction-Bypass/raw/main/dist/Simple-YouTube-Age-Restriction-Bypass.user.js","uuid":"163ac3a9-2569-42c4-ba78-9b0b4bab3293","source":"Ly8gPT1Vc2VyU2NyaXB0PT0KLy8gQG5hbWUgICAgICAgICAgICBTaW1wbGUgWW91VHViZSBBZ2UgUmVzdHJpY3Rpb24gQnlwYXNzCi8vIEBkZXNjcmlwdGlvbiAgICAgV2F0Y2ggYWdlIHJlc3RyaWN0ZWQgdmlkZW9zIG9uIFlvdVR1YmUgd2l0aG91dCBsb2dpbiBhbmQgd2l0aG91dCBhZ2UgdmVyaWZpY2F0aW9uIPCfmI4KLy8gQGRlc2NyaXB0aW9uOmRlICBTY2hhdWUgWW91VHViZSBWaWRlb3MgbWl0IEFsdGVyc2Jlc2NocsOkbmt1bmdlbiBvaG5lIEFubWVsZHVuZyB1bmQgb2huZSBkZWluIEFsdGVyIHp1IGJlc3TDpHRpZ2VuIPCfmI4KLy8gQGRlc2NyaXB0aW9uOmZyICBSZWdhcmRleiBkZXMgdmlkw6lvcyBZb3VUdWJlIGF2ZWMgZGVzIHJlc3RyaWN0aW9ucyBkJ8OiZ2Ugc2FucyB2b3VzIGluc2NyaXJlIGV0IHNhbnMgY29uZmlybWVyIHZvdHJlIMOiZ2Ug8J+YjgovLyBAZGVzY3JpcHRpb246aXQgIEd1YXJkYSBpIHZpZGVvIGNvbiByZXN0cml6aW9uaSBkaSBldMOgIHN1IFlvdVR1YmUgc2VuemEgbG9naW4gZSBzZW56YSB2ZXJpZmljYSBkZWxsJ2V0w6Ag8J+YjgovLyBAaWNvbiAgICAgICAgICAgIGh0dHBzOi8vZ2l0aHViLmNvbS96ZXJvZHl0cmFzaC9TaW1wbGUtWW91VHViZS1BZ2UtUmVzdHJpY3Rpb24tQnlwYXNzL3Jhdy92Mi41LjQvc3JjL2V4dGVuc2lvbi9pY29uL2ljb25fNjQucG5nCi8vIEB2ZXJzaW9uICAgICAgICAgMi41LjkKLy8gQGF1dGhvciAgICAgICAgICBaZXJvZHkgKGh0dHBzOi8vZ2l0aHViLmNvbS96ZXJvZHl0cmFzaCkKLy8gQG5hbWVzcGFjZSAgICAgICBodHRwczovL2dpdGh1Yi5jb20vemVyb2R5dHJhc2gvU2ltcGxlLVlvdVR1YmUtQWdlLVJlc3RyaWN0aW9uLUJ5cGFzcy8KLy8gQHN1cHBvcnRVUkwgICAgICBodHRwczovL2dpdGh1Yi5jb20vemVyb2R5dHJhc2gvU2ltcGxlLVlvdVR1YmUtQWdlLVJlc3RyaWN0aW9uLUJ5cGFzcy9pc3N1ZXMKLy8gQHVwZGF0ZVVSTCAgICAgICBodHRwczovL2dpdGh1Yi5jb20vemVyb2R5dHJhc2gvU2ltcGxlLVlvdVR1YmUtQWdlLVJlc3RyaWN0aW9uLUJ5cGFzcy9yYXcvbWFpbi9kaXN0L1NpbXBsZS1Zb3VUdWJlLUFnZS1SZXN0cmljdGlvbi1CeXBhc3MudXNlci5qcwovLyBAbGljZW5zZSAgICAgICAgIE1JVAovLyBAbWF0Y2ggICAgICAgICAgIGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tLyoKLy8gQG1hdGNoICAgICAgICAgICBodHRwczovL3d3dy55b3V0dWJlLW5vY29va2llLmNvbS8qCi8vIEBtYXRjaCAgICAgICAgICAgaHR0cHM6Ly9tLnlvdXR1YmUuY29tLyoKLy8gQG1hdGNoICAgICAgICAgICBodHRwczovL211c2ljLnlvdXR1YmUuY29tLyoKLy8gQGdyYW50ICAgICAgICAgICBub25lCi8vIEBydW4tYXQgICAgICAgICAgZG9jdW1lbnQtc3RhcnQKLy8gQGNvbXBhdGlibGUgICAgICBjaHJvbWUKLy8gQGNvbXBhdGlibGUgICAgICBmaXJlZm94Ci8vIEBjb21wYXRpYmxlICAgICAgb3BlcmEKLy8gQGNvbXBhdGlibGUgICAgICBlZGdlCi8vIEBjb21wYXRpYmxlICAgICAgc2FmYXJpCi8vID09L1VzZXJTY3JpcHQ9PQoKLyoKICAgIFRoaXMgaXMgYSB0cmFuc3BpbGVkIHZlcnNpb24gdG8gYWNoaWV2ZSBhIGNsZWFuIGNvZGUgYmFzZSBhbmQgYmV0dGVyIGJyb3dzZXIgY29tcGF0aWJpbGl0eS4KICAgIFlvdSBjYW4gZmluZCB0aGUgbmljZWx5IHJlYWRhYmxlIHNvdXJjZSBjb2RlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS96ZXJvZHl0cmFzaC9TaW1wbGUtWW91VHViZS1BZ2UtUmVzdHJpY3Rpb24tQnlwYXNzCiovCgooZnVuY3Rpb24gaWlmZShyYW5PbmNlKSB7CiAgICAvLyBUcmljayB0byBnZXQgYXJvdW5kIHRoZSBzYW5kYm94IHJlc3RyaWN0aW9ucyBpbiBHcmVhc2Vtb25rZXkgKEZpcmVmb3gpCiAgICAvLyBJbmplY3QgY29kZSBpbnRvIHRoZSBtYWluIHdpbmRvdyBpZiBjcml0ZXJpYSBtYXRjaAogICAgaWYgKHRoaXMgIT09IHdpbmRvdyAmJiAhcmFuT25jZSkgewogICAgICAgIHdpbmRvdy5ldmFsKCcoJyArIGlpZmUudG9TdHJpbmcoKSArICcpKHRydWUpOycpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBTY3JpcHQgY29uZmlndXJhdGlvbiB2YXJpYWJsZXMKICAgIGNvbnN0IFVOTE9DS0FCTEVfUExBWUFCSUxJVFlfU1RBVFVTRVMgPSBbJ0FHRV9WRVJJRklDQVRJT05fUkVRVUlSRUQnLCAnQUdFX0NIRUNLX1JFUVVJUkVEJywgJ0NPTlRFTlRfQ0hFQ0tfUkVRVUlSRUQnLCAnTE9HSU5fUkVRVUlSRUQnXTsKICAgIGNvbnN0IFZBTElEX1BMQVlBQklMSVRZX1NUQVRVU0VTID0gWydPSycsICdMSVZFX1NUUkVBTV9PRkZMSU5FJ107CgogICAgLy8gVGhlc2UgYXJlIHRoZSBwcm94eSBzZXJ2ZXJzIHRoYXQgYXJlIHNvbWV0aW1lcyByZXF1aXJlZCB0byB1bmxvY2sgdmlkZW9zIHdpdGggYWdlIHJlc3RyaWN0aW9ucy4KICAgIC8vIFlvdSBjYW4gaG9zdCB5b3VyIG93biBhY2NvdW50IHByb3h5IGluc3RhbmNlLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3plcm9keXRyYXNoL1NpbXBsZS1Zb3VUdWJlLUFnZS1SZXN0cmljdGlvbi1CeXBhc3MvdHJlZS9tYWluL2FjY291bnQtcHJveHkKICAgIC8vIFRvIGxlYXJuIHdoYXQgaW5mb3JtYXRpb24gaXMgdHJhbnNmZXJyZWQsIHBsZWFzZSByZWFkOiBodHRwczovL2dpdGh1Yi5jb20vemVyb2R5dHJhc2gvU2ltcGxlLVlvdVR1YmUtQWdlLVJlc3RyaWN0aW9uLUJ5cGFzcyNwcml2YWN5CiAgICBjb25zdCBBQ0NPVU5UX1BST1hZX1NFUlZFUl9IT1NUID0gJ2h0dHBzOi8veW91dHViZS1wcm94eS56ZXJvZHkub25lJzsKICAgIGNvbnN0IFZJREVPX1BST1hZX1NFUlZFUl9IT1NUID0gJ2h0dHBzOi8vbnkuNGV2ZXJwcm94eS5jb20nOwoKICAgIC8vIFVzZXIgbmVlZHMgdG8gY29uZmlybSB0aGUgdW5sb2NrIHByb2Nlc3Mgb24gZW1iZWRkZWQgcGxheWVyPwogICAgbGV0IEVOQUJMRV9VTkxPQ0tfQ09ORklSTUFUSU9OX0VNQkVEID0gdHJ1ZTsKCiAgICAvLyBTaG93IG5vdGlmaWNhdGlvbj8KICAgIGxldCBFTkFCTEVfVU5MT0NLX05PVElGSUNBVElPTiA9IHRydWU7CgogICAgLy8gRGlzYWJsZSBjb250ZW50IHdhcm5pbmdzPwogICAgbGV0IFNLSVBfQ09OVEVOVF9XQVJOSU5HUyA9IHRydWU7CgogICAgLy8gU29tZSBJbm5lcnR1YmUgYnlwYXNzIG1ldGhvZHMgcmVxdWlyZSB0aGUgZm9sbG93aW5nIGF1dGhlbnRpY2F0aW9uIGhlYWRlcnMgb2YgdGhlIGN1cnJlbnRseSBsb2dnZWQgaW4gdXNlci4KICAgIGNvbnN0IEdPT0dMRV9BVVRIX0hFQURFUl9OQU1FUyA9IFsnQXV0aG9yaXphdGlvbicsICdYLUdvb2ctQXV0aFVzZXInLCAnWC1PcmlnaW4nXTsKCiAgICAvKioKICAgICAqIFRoZSBTUVAgcGFyYW1ldGVyIGxlbmd0aCBpcyBkaWZmZXJlbnQgZm9yIGJsdXJyZWQgdGh1bWJuYWlscy4KICAgICAqIFRoZXkgY29udGFpbiBtdWNoIGxlc3MgaW5mb3JtYXRpb24sIHRoYW4gbm9ybWFsIHRodW1ibmFpbHMuCiAgICAgKiBUaGUgdGh1bWJuYWlsIFNRUHMgdGVuZCB0byBoYXZlIGEgbG9uZyBhbmQgYSBzaG9ydCB2ZXJzaW9uLgogICAgICovCiAgICBjb25zdCBCTFVSUkVEX1RIVU1CTkFJTF9TUVBfTEVOR1RIUyA9IFsKICAgICAgICAzMiwgLy8gTW9iaWxlIChTSE9SVCkKICAgICAgICA0OCwgLy8gRGVza3RvcCBQbGF5bGlzdCAoU0hPUlQpCiAgICAgICAgNTYsIC8vIERlc2t0b3AgKFNIT1JUKQogICAgICAgIDY4LCAvLyBNb2JpbGUgKExPTkcpCiAgICAgICAgNzIsIC8vIE1vYmlsZSBTaG9ydHMKICAgICAgICA4NCwgLy8gRGVza3RvcCBQbGF5bGlzdCAoTE9ORykKICAgICAgICA4OCwgLy8gRGVza3RvcCAoTE9ORykKICAgIF07CgogICAgLy8gc21hbGwgaGFjayB0byBwcmV2ZW50IHRyZWUgc2hha2luZyBvbiB0aGVzZSBleHBvcnRzCiAgICB2YXIgQ29uZmlnID0gd2luZG93W1N5bWJvbCgpXSA9IHsKICAgICAgICBVTkxPQ0tBQkxFX1BMQVlBQklMSVRZX1NUQVRVU0VTLAogICAgICAgIFZBTElEX1BMQVlBQklMSVRZX1NUQVRVU0VTLAogICAgICAgIEFDQ09VTlRfUFJPWFlfU0VSVkVSX0hPU1QsCiAgICAgICAgVklERU9fUFJPWFlfU0VSVkVSX0hPU1QsCiAgICAgICAgRU5BQkxFX1VOTE9DS19DT05GSVJNQVRJT05fRU1CRUQsCiAgICAgICAgRU5BQkxFX1VOTE9DS19OT1RJRklDQVRJT04sCiAgICAgICAgU0tJUF9DT05URU5UX1dBUk5JTkdTLAogICAgICAgIEdPT0dMRV9BVVRIX0hFQURFUl9OQU1FUywKICAgICAgICBCTFVSUkVEX1RIVU1CTkFJTF9TUVBfTEVOR1RIUywKICAgIH07CgogICAgZnVuY3Rpb24gaXNHb29nbGVWaWRlb1VybCh1cmwpIHsKICAgICAgICByZXR1cm4gdXJsLmhvc3QuaW5jbHVkZXMoJy5nb29nbGV2aWRlby5jb20nKTsKICAgIH0KCiAgICBmdW5jdGlvbiBpc0dvb2dsZVZpZGVvVW5sb2NrUmVxdWlyZWQoZ29vZ2xlVmlkZW9VcmwsIGxhc3RQcm94aWVkR29vZ2xlVmlkZW9JZCkgewogICAgICAgIGNvbnN0IHVybFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoZ29vZ2xlVmlkZW9Vcmwuc2VhcmNoKTsKICAgICAgICBjb25zdCBoYXNHY3JGbGFnID0gdXJsUGFyYW1zLmdldCgnZ2NyJyk7CiAgICAgICAgY29uc3Qgd2FzVW5sb2NrZWRCeUFjY291bnRQcm94eSA9IHVybFBhcmFtcy5nZXQoJ2lkJykgPT09IGxhc3RQcm94aWVkR29vZ2xlVmlkZW9JZDsKCiAgICAgICAgcmV0dXJuIGhhc0djckZsYWcgJiYgd2FzVW5sb2NrZWRCeUFjY291bnRQcm94eTsKICAgIH0KCiAgICBjb25zdCBuYXRpdmVKU09OUGFyc2UgPSB3aW5kb3cuSlNPTi5wYXJzZTsKICAgIGNvbnN0IG5hdGl2ZVhNTEh0dHBSZXF1ZXN0T3BlbiA9IHdpbmRvdy5YTUxIdHRwUmVxdWVzdC5wcm90b3R5cGUub3BlbjsKCiAgICBjb25zdCBpc0Rlc2t0b3AgPSB3aW5kb3cubG9jYXRpb24uaG9zdCAhPT0gJ20ueW91dHViZS5jb20nOwogICAgY29uc3QgaXNNdXNpYyA9IHdpbmRvdy5sb2NhdGlvbi5ob3N0ID09PSAnbXVzaWMueW91dHViZS5jb20nOwogICAgY29uc3QgaXNFbWJlZCA9IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZS5pbmRleE9mKCcvZW1iZWQvJykgPT09IDA7CiAgICBjb25zdCBpc0NvbmZpcm1lZCA9IHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guaW5jbHVkZXMoJ3VubG9ja19jb25maXJtZWQnKTsKCiAgICBjbGFzcyBEZWZlcnJlZCB7CiAgICAgICAgY29uc3RydWN0b3IoKSB7CiAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKAogICAgICAgICAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gewogICAgICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZSA9IHJlc29sdmU7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWplY3QgPSByZWplY3Q7CiAgICAgICAgICAgICAgICB9KSwKICAgICAgICAgICAgICAgIHRoaXMsCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQodGFnTmFtZSwgb3B0aW9ucykgewogICAgICAgIGNvbnN0IG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZ05hbWUpOwogICAgICAgIG9wdGlvbnMgJiYgT2JqZWN0LmFzc2lnbihub2RlLCBvcHRpb25zKTsKICAgICAgICByZXR1cm4gbm9kZTsKICAgIH0KCiAgICBmdW5jdGlvbiBpc09iamVjdChvYmopIHsKICAgICAgICByZXR1cm4gb2JqICE9PSBudWxsICYmIHR5cGVvZiBvYmogPT09ICdvYmplY3QnOwogICAgfQoKICAgIGZ1bmN0aW9uIGZpbmROZXN0ZWRPYmplY3RzQnlBdHRyaWJ1dGVOYW1lcyhvYmplY3QsIGF0dHJpYnV0ZU5hbWVzKSB7CiAgICAgICAgdmFyIHJlc3VsdHMgPSBbXTsKCiAgICAgICAgLy8gRG9lcyB0aGUgY3VycmVudCBvYmplY3QgbWF0Y2ggdGhlIGF0dHJpYnV0ZSBjb25kaXRpb25zPwogICAgICAgIGlmIChhdHRyaWJ1dGVOYW1lcy5ldmVyeSgoa2V5KSA9PiB0eXBlb2Ygb2JqZWN0W2tleV0gIT09ICd1bmRlZmluZWQnKSkgewogICAgICAgICAgICByZXN1bHRzLnB1c2gob2JqZWN0KTsKICAgICAgICB9CgogICAgICAgIC8vIERpZ2dpbicgZGVlcGVyIGZvciBlYWNoIG5lc3RlZCBvYmplY3QgKHJlY3Vyc2l2ZSkKICAgICAgICBPYmplY3Qua2V5cyhvYmplY3QpLmZvckVhY2goKGtleSkgPT4gewogICAgICAgICAgICBpZiAob2JqZWN0W2tleV0gJiYgdHlwZW9mIG9iamVjdFtrZXldID09PSAnb2JqZWN0JykgewogICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKC4uLmZpbmROZXN0ZWRPYmplY3RzQnlBdHRyaWJ1dGVOYW1lcyhvYmplY3Rba2V5XSwgYXR0cmlidXRlTmFtZXMpKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gcmVzdWx0czsKICAgIH0KCiAgICBmdW5jdGlvbiBwYWdlTG9hZGVkKCkgewogICAgICAgIGlmIChkb2N1bWVudC5yZWFkeVN0YXRlID09PSAnY29tcGxldGUnKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7CgogICAgICAgIGNvbnN0IGRlZmVycmVkID0gbmV3IERlZmVycmVkKCk7CgogICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgZGVmZXJyZWQucmVzb2x2ZSwgeyBvbmNlOiB0cnVlIH0pOwoKICAgICAgICByZXR1cm4gZGVmZXJyZWQ7CiAgICB9CgogICAgZnVuY3Rpb24gY3JlYXRlRGVlcENvcHkob2JqKSB7CiAgICAgICAgcmV0dXJuIG5hdGl2ZUpTT05QYXJzZShKU09OLnN0cmluZ2lmeShvYmopKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRZdGNmZ1ZhbHVlKG5hbWUpIHsKICAgICAgICB2YXIgX3dpbmRvdyR5dGNmZzsKICAgICAgICByZXR1cm4gKF93aW5kb3ckeXRjZmcgPSB3aW5kb3cueXRjZmcpID09PSBudWxsIHx8IF93aW5kb3ckeXRjZmcgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF93aW5kb3ckeXRjZmcuZ2V0KG5hbWUpOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldFNpZ25hdHVyZVRpbWVzdGFtcCgpIHsKICAgICAgICByZXR1cm4gKAogICAgICAgICAgICBnZXRZdGNmZ1ZhbHVlKCdTVFMnKQogICAgICAgICAgICB8fCAoKCkgPT4gewogICAgICAgICAgICAgICAgdmFyIF9kb2N1bWVudCRxdWVyeVNlbGVjdDsKICAgICAgICAgICAgICAgIC8vIFNUUyBpcyBtaXNzaW5nIG9uIGVtYmVkZGVkIHBsYXllci4gUmV0cmlldmUgZnJvbSBwbGF5ZXIgYmFzZSBzY3JpcHQgYXMgZmFsbGJhY2suLi4KICAgICAgICAgICAgICAgIGNvbnN0IHBsYXllckJhc2VKc1BhdGggPSAoX2RvY3VtZW50JHF1ZXJ5U2VsZWN0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcignc2NyaXB0W3NyYyo9Ii9iYXNlLmpzIl0nKSkgPT09IG51bGwgfHwgX2RvY3VtZW50JHF1ZXJ5U2VsZWN0ID09PSB2b2lkIDAKICAgICAgICAgICAgICAgICAgICA/IHZvaWQgMAogICAgICAgICAgICAgICAgICAgIDogX2RvY3VtZW50JHF1ZXJ5U2VsZWN0LnNyYzsKCiAgICAgICAgICAgICAgICBpZiAoIXBsYXllckJhc2VKc1BhdGgpIHJldHVybjsKCiAgICAgICAgICAgICAgICBjb25zdCB4bWxodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7CiAgICAgICAgICAgICAgICB4bWxodHRwLm9wZW4oJ0dFVCcsIHBsYXllckJhc2VKc1BhdGgsIGZhbHNlKTsKICAgICAgICAgICAgICAgIHhtbGh0dHAuc2VuZChudWxsKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQoeG1saHR0cC5yZXNwb25zZVRleHQubWF0Y2goL3NpZ25hdHVyZVRpbWVzdGFtcDooWzAtOV0qKS8pWzFdKTsKICAgICAgICAgICAgfSkoKQogICAgICAgICk7CiAgICB9CgogICAgZnVuY3Rpb24gaXNVc2VyTG9nZ2VkSW4oKSB7CiAgICAgICAgLy8gTE9HR0VEX0lOIGRvZXNuJ3QgZXhpc3Qgb24gZW1iZWRkZWQgcGFnZSwgdXNlIERFTEVHQVRFRF9TRVNTSU9OX0lEIG9yIFNFU1NJT05fSU5ERVggYXMgZmFsbGJhY2sKICAgICAgICBpZiAodHlwZW9mIGdldFl0Y2ZnVmFsdWUoJ0xPR0dFRF9JTicpID09PSAnYm9vbGVhbicpIHJldHVybiBnZXRZdGNmZ1ZhbHVlKCdMT0dHRURfSU4nKTsKICAgICAgICBpZiAodHlwZW9mIGdldFl0Y2ZnVmFsdWUoJ0RFTEVHQVRFRF9TRVNTSU9OX0lEJykgPT09ICdzdHJpbmcnKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAocGFyc2VJbnQoZ2V0WXRjZmdWYWx1ZSgnU0VTU0lPTl9JTkRFWCcpKSA+PSAwKSByZXR1cm4gdHJ1ZTsKCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldEN1cnJlbnRWaWRlb1N0YXJ0VGltZShjdXJyZW50VmlkZW9JZCkgewogICAgICAgIC8vIENoZWNrIGlmIHRoZSBVUkwgY29ycmVzcG9uZHMgdG8gdGhlIHJlcXVlc3RlZCB2aWRlbwogICAgICAgIC8vIFRoaXMgaXMgbm90IHRoZSBjYXNlIHdoZW4gdGhlIHBsYXllciBnZXRzIHByZWxvYWRlZCBmb3IgdGhlIG5leHQgdmlkZW8gaW4gYSBwbGF5bGlzdC4KICAgICAgICBpZiAod2luZG93LmxvY2F0aW9uLmhyZWYuaW5jbHVkZXMoY3VycmVudFZpZGVvSWQpKSB7CiAgICAgICAgICAgIHZhciBfcmVmOwogICAgICAgICAgICAvLyAidCItcGFyYW0gb24geW91dHUuYmUgdXJscwogICAgICAgICAgICAvLyAic3RhcnQiLXBhcmFtIG9uIGVtYmVkIHBsYXllcgogICAgICAgICAgICAvLyAidGltZV9jb250aW51ZSIgd2hlbiBjbGlja2luZyAid2F0Y2ggb24geW91dHViZSIgb24gZW1iZWRkZWQgcGxheWVyCiAgICAgICAgICAgIGNvbnN0IHVybFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaCk7CiAgICAgICAgICAgIGNvbnN0IHN0YXJ0VGltZVN0cmluZyA9IChfcmVmID0gdXJsUGFyYW1zLmdldCgndCcpIHx8IHVybFBhcmFtcy5nZXQoJ3N0YXJ0JykgfHwgdXJsUGFyYW1zLmdldCgndGltZV9jb250aW51ZScpKSA9PT0gbnVsbCB8fCBfcmVmID09PSB2b2lkIDAKICAgICAgICAgICAgICAgID8gdm9pZCAwCiAgICAgICAgICAgICAgICA6IF9yZWYucmVwbGFjZSgncycsICcnKTsKCiAgICAgICAgICAgIGlmIChzdGFydFRpbWVTdHJpbmcgJiYgIWlzTmFOKHN0YXJ0VGltZVN0cmluZykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludChzdGFydFRpbWVTdHJpbmcpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBmdW5jdGlvbiBzZXRVcmxQYXJhbXMocGFyYW1zKSB7CiAgICAgICAgY29uc3QgdXJsUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKTsKICAgICAgICBmb3IgKGNvbnN0IHBhcmFtTmFtZSBpbiBwYXJhbXMpIHsKICAgICAgICAgICAgdXJsUGFyYW1zLnNldChwYXJhbU5hbWUsIHBhcmFtc1twYXJhbU5hbWVdKTsKICAgICAgICB9CiAgICAgICAgd2luZG93LmxvY2F0aW9uLnNlYXJjaCA9IHVybFBhcmFtczsKICAgIH0KCiAgICBmdW5jdGlvbiB3YWl0Rm9yRWxlbWVudChlbGVtZW50U2VsZWN0b3IsIHRpbWVvdXQpIHsKICAgICAgICBjb25zdCBkZWZlcnJlZCA9IG5ldyBEZWZlcnJlZCgpOwoKICAgICAgICBjb25zdCBjaGVja0RvbUludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4gewogICAgICAgICAgICBjb25zdCBlbGVtID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50U2VsZWN0b3IpOwogICAgICAgICAgICBpZiAoZWxlbSkgewogICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChjaGVja0RvbUludGVydmFsKTsKICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUoZWxlbSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LCAxMDApOwoKICAgICAgICBpZiAodGltZW91dCkgewogICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsKICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoY2hlY2tEb21JbnRlcnZhbCk7CiAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QoKTsKICAgICAgICAgICAgfSwgdGltZW91dCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZGVmZXJyZWQ7CiAgICB9CgogICAgZnVuY3Rpb24gcGFyc2VSZWxhdGl2ZVVybCh1cmwpIHsKICAgICAgICBpZiAodHlwZW9mIHVybCAhPT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZiAodXJsLmluZGV4T2YoJy8nKSA9PT0gMCkgewogICAgICAgICAgICB1cmwgPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luICsgdXJsOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIHVybC5pbmRleE9mKCdodHRwczovLycpID09PSAwID8gbmV3IHdpbmRvdy5VUkwodXJsKSA6IG51bGw7CiAgICAgICAgfSBjYXRjaCB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBpc1dhdGNoTmV4dE9iamVjdChwYXJzZWREYXRhKSB7CiAgICAgICAgdmFyIF9wYXJzZWREYXRhJGN1cnJlbnRWaTsKICAgICAgICBpZiAoCiAgICAgICAgICAgICEocGFyc2VkRGF0YSAhPT0gbnVsbCAmJiBwYXJzZWREYXRhICE9PSB2b2lkIDAgJiYgcGFyc2VkRGF0YS5jb250ZW50cykKICAgICAgICAgICAgfHwgIShwYXJzZWREYXRhICE9PSBudWxsICYmIHBhcnNlZERhdGEgIT09IHZvaWQgMCAmJiAoX3BhcnNlZERhdGEkY3VycmVudFZpID0gcGFyc2VkRGF0YS5jdXJyZW50VmlkZW9FbmRwb2ludCkgIT09IG51bGwgJiYgX3BhcnNlZERhdGEkY3VycmVudFZpICE9PSB2b2lkIDAKICAgICAgICAgICAgICAgICYmIChfcGFyc2VkRGF0YSRjdXJyZW50VmkgPSBfcGFyc2VkRGF0YSRjdXJyZW50Vmkud2F0Y2hFbmRwb2ludCkgIT09IG51bGwgJiYgX3BhcnNlZERhdGEkY3VycmVudFZpICE9PSB2b2lkIDAgJiYgX3BhcnNlZERhdGEkY3VycmVudFZpLnZpZGVvSWQpCiAgICAgICAgKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuICEhcGFyc2VkRGF0YS5jb250ZW50cy50d29Db2x1bW5XYXRjaE5leHRSZXN1bHRzIHx8ICEhcGFyc2VkRGF0YS5jb250ZW50cy5zaW5nbGVDb2x1bW5XYXRjaE5leHRSZXN1bHRzOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzV2F0Y2hOZXh0U2lkZWJhckVtcHR5KHBhcnNlZERhdGEpIHsKICAgICAgICB2YXIgX3BhcnNlZERhdGEkY29udGVudHMyLCBfY29udGVudCRmaW5kOwogICAgICAgIGlmIChpc0Rlc2t0b3ApIHsKICAgICAgICAgICAgdmFyIF9wYXJzZWREYXRhJGNvbnRlbnRzOwogICAgICAgICAgICAvLyBXRUIgcmVzcG9uc2UgbGF5b3V0CiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IChfcGFyc2VkRGF0YSRjb250ZW50cyA9IHBhcnNlZERhdGEuY29udGVudHMpID09PSBudWxsIHx8IF9wYXJzZWREYXRhJGNvbnRlbnRzID09PSB2b2lkIDAKICAgICAgICAgICAgICAgICAgICB8fCAoX3BhcnNlZERhdGEkY29udGVudHMgPSBfcGFyc2VkRGF0YSRjb250ZW50cy50d29Db2x1bW5XYXRjaE5leHRSZXN1bHRzKSA9PT0gbnVsbCB8fCBfcGFyc2VkRGF0YSRjb250ZW50cyA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICAgICAgfHwgKF9wYXJzZWREYXRhJGNvbnRlbnRzID0gX3BhcnNlZERhdGEkY29udGVudHMuc2Vjb25kYXJ5UmVzdWx0cykgPT09IG51bGwgfHwgX3BhcnNlZERhdGEkY29udGVudHMgPT09IHZvaWQgMAogICAgICAgICAgICAgICAgICAgIHx8IChfcGFyc2VkRGF0YSRjb250ZW50cyA9IF9wYXJzZWREYXRhJGNvbnRlbnRzLnNlY29uZGFyeVJlc3VsdHMpID09PSBudWxsIHx8IF9wYXJzZWREYXRhJGNvbnRlbnRzID09PSB2b2lkIDAKICAgICAgICAgICAgICAgID8gdm9pZCAwCiAgICAgICAgICAgICAgICA6IF9wYXJzZWREYXRhJGNvbnRlbnRzLnJlc3VsdHM7CiAgICAgICAgICAgIHJldHVybiAhcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgLy8gTVdFQiByZXNwb25zZSBsYXlvdXQKICAgICAgICBjb25zdCBjb250ZW50ID0gKF9wYXJzZWREYXRhJGNvbnRlbnRzMiA9IHBhcnNlZERhdGEuY29udGVudHMpID09PSBudWxsIHx8IF9wYXJzZWREYXRhJGNvbnRlbnRzMiA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICB8fCAoX3BhcnNlZERhdGEkY29udGVudHMyID0gX3BhcnNlZERhdGEkY29udGVudHMyLnNpbmdsZUNvbHVtbldhdGNoTmV4dFJlc3VsdHMpID09PSBudWxsIHx8IF9wYXJzZWREYXRhJGNvbnRlbnRzMiA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICB8fCAoX3BhcnNlZERhdGEkY29udGVudHMyID0gX3BhcnNlZERhdGEkY29udGVudHMyLnJlc3VsdHMpID09PSBudWxsIHx8IF9wYXJzZWREYXRhJGNvbnRlbnRzMiA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICB8fCAoX3BhcnNlZERhdGEkY29udGVudHMyID0gX3BhcnNlZERhdGEkY29udGVudHMyLnJlc3VsdHMpID09PSBudWxsIHx8IF9wYXJzZWREYXRhJGNvbnRlbnRzMiA9PT0gdm9pZCAwCiAgICAgICAgICAgID8gdm9pZCAwCiAgICAgICAgICAgIDogX3BhcnNlZERhdGEkY29udGVudHMyLmNvbnRlbnRzOwogICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnRlbnQgPT09IG51bGwgfHwgY29udGVudCA9PT0gdm9pZCAwIHx8IChfY29udGVudCRmaW5kID0gY29udGVudC5maW5kKChlKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgdmFyIF9lJGl0ZW1TZWN0aW9uUmVuZGVyZTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChfZSRpdGVtU2VjdGlvblJlbmRlcmUgPSBlLml0ZW1TZWN0aW9uUmVuZGVyZXIpID09PSBudWxsIHx8IF9lJGl0ZW1TZWN0aW9uUmVuZGVyZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2UkaXRlbVNlY3Rpb25SZW5kZXJlLnRhcmdldElkKQogICAgICAgICAgICAgICAgICAgICAgICA9PT0gJ3dhdGNoLW5leHQtZmVlZCc7CiAgICAgICAgICAgICAgICB9KSkgPT09IG51bGwKICAgICAgICAgICAgICAgIHx8IF9jb250ZW50JGZpbmQgPT09IHZvaWQgMAogICAgICAgICAgICA/IHZvaWQgMAogICAgICAgICAgICA6IF9jb250ZW50JGZpbmQuaXRlbVNlY3Rpb25SZW5kZXJlcjsKICAgICAgICByZXR1cm4gdHlwZW9mIHJlc3VsdCAhPT0gJ29iamVjdCc7CiAgICB9CgogICAgZnVuY3Rpb24gaXNQbGF5ZXJPYmplY3QocGFyc2VkRGF0YSkgewogICAgICAgIHJldHVybiAocGFyc2VkRGF0YSA9PT0gbnVsbCB8fCBwYXJzZWREYXRhID09PSB2b2lkIDAgPyB2b2lkIDAgOiBwYXJzZWREYXRhLnZpZGVvRGV0YWlscykKICAgICAgICAgICAgJiYgKHBhcnNlZERhdGEgPT09IG51bGwgfHwgcGFyc2VkRGF0YSA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFyc2VkRGF0YS5wbGF5YWJpbGl0eVN0YXR1cyk7CiAgICB9CgogICAgZnVuY3Rpb24gaXNFbWJlZGRlZFBsYXllck9iamVjdChwYXJzZWREYXRhKSB7CiAgICAgICAgcmV0dXJuIHR5cGVvZiAocGFyc2VkRGF0YSA9PT0gbnVsbCB8fCBwYXJzZWREYXRhID09PSB2b2lkIDAgPyB2b2lkIDAgOiBwYXJzZWREYXRhLnByZXZpZXdQbGF5YWJpbGl0eVN0YXR1cykgPT09ICdvYmplY3QnOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzQWdlUmVzdHJpY3RlZChwbGF5YWJpbGl0eVN0YXR1cykgewogICAgICAgIHZhciBfcGxheWFiaWxpdHlTdGF0dXMkZXI7CiAgICAgICAgaWYgKCEocGxheWFiaWxpdHlTdGF0dXMgIT09IG51bGwgJiYgcGxheWFiaWxpdHlTdGF0dXMgIT09IHZvaWQgMCAmJiBwbGF5YWJpbGl0eVN0YXR1cy5zdGF0dXMpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKHBsYXlhYmlsaXR5U3RhdHVzLmRlc2t0b3BMZWdhY3lBZ2VHYXRlUmVhc29uKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoQ29uZmlnLlVOTE9DS0FCTEVfUExBWUFCSUxJVFlfU1RBVFVTRVMuaW5jbHVkZXMocGxheWFiaWxpdHlTdGF0dXMuc3RhdHVzKSkgcmV0dXJuIHRydWU7CgogICAgICAgIC8vIEZpeCB0byBkZXRlY3QgYWdlIHJlc3RyaWN0aW9ucyBvbiBlbWJlZCBwbGF5ZXIKICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3plcm9keXRyYXNoL1NpbXBsZS1Zb3VUdWJlLUFnZS1SZXN0cmljdGlvbi1CeXBhc3MvaXNzdWVzLzg1I2lzc3VlY29tbWVudC05NDY4NTM1NTMKICAgICAgICByZXR1cm4gKAogICAgICAgICAgICBpc0VtYmVkCiAgICAgICAgICAgICYmICgoX3BsYXlhYmlsaXR5U3RhdHVzJGVyID0gcGxheWFiaWxpdHlTdGF0dXMuZXJyb3JTY3JlZW4pID09PSBudWxsIHx8IF9wbGF5YWJpbGl0eVN0YXR1cyRlciA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICAgICAgfHwgKF9wbGF5YWJpbGl0eVN0YXR1cyRlciA9IF9wbGF5YWJpbGl0eVN0YXR1cyRlci5wbGF5ZXJFcnJvck1lc3NhZ2VSZW5kZXJlcikgPT09IG51bGwgfHwgX3BsYXlhYmlsaXR5U3RhdHVzJGVyID09PSB2b2lkIDAKICAgICAgICAgICAgICAgICAgICB8fCAoX3BsYXlhYmlsaXR5U3RhdHVzJGVyID0gX3BsYXlhYmlsaXR5U3RhdHVzJGVyLnJlYXNvbikgPT09IG51bGwgfHwgX3BsYXlhYmlsaXR5U3RhdHVzJGVyID09PSB2b2lkIDAKICAgICAgICAgICAgICAgICAgICB8fCAoX3BsYXlhYmlsaXR5U3RhdHVzJGVyID0gX3BsYXlhYmlsaXR5U3RhdHVzJGVyLnJ1bnMpID09PSBudWxsIHx8IF9wbGF5YWJpbGl0eVN0YXR1cyRlciA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICAgICAgfHwgKF9wbGF5YWJpbGl0eVN0YXR1cyRlciA9IF9wbGF5YWJpbGl0eVN0YXR1cyRlci5maW5kKCh4KSA9PiB4Lm5hdmlnYXRpb25FbmRwb2ludCkpID09PSBudWxsIHx8IF9wbGF5YWJpbGl0eVN0YXR1cyRlciA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICAgICAgfHwgKF9wbGF5YWJpbGl0eVN0YXR1cyRlciA9IF9wbGF5YWJpbGl0eVN0YXR1cyRlci5uYXZpZ2F0aW9uRW5kcG9pbnQpID09PSBudWxsIHx8IF9wbGF5YWJpbGl0eVN0YXR1cyRlciA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICAgICAgfHwgKF9wbGF5YWJpbGl0eVN0YXR1cyRlciA9IF9wbGF5YWJpbGl0eVN0YXR1cyRlci51cmxFbmRwb2ludCkgPT09IG51bGwgfHwgX3BsYXlhYmlsaXR5U3RhdHVzJGVyID09PSB2b2lkIDAKICAgICAgICAgICAgICAgICAgICB8fCAoX3BsYXlhYmlsaXR5U3RhdHVzJGVyID0gX3BsYXlhYmlsaXR5U3RhdHVzJGVyLnVybCkgPT09IG51bGwgfHwgX3BsYXlhYmlsaXR5U3RhdHVzJGVyID09PSB2b2lkIDAKICAgICAgICAgICAgICAgID8gdm9pZCAwCiAgICAgICAgICAgICAgICA6IF9wbGF5YWJpbGl0eVN0YXR1cyRlci5pbmNsdWRlcygnLzI4MDIxNjcnKSkKICAgICAgICApOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzU2VhcmNoUmVzdWx0KHBhcnNlZERhdGEpIHsKICAgICAgICB2YXIgX3BhcnNlZERhdGEkY29udGVudHMzLCBfcGFyc2VkRGF0YSRjb250ZW50czQsIF9wYXJzZWREYXRhJG9uUmVzcG9uczsKICAgICAgICByZXR1cm4gKAogICAgICAgICAgICB0eXBlb2YgKHBhcnNlZERhdGEgPT09IG51bGwgfHwgcGFyc2VkRGF0YSA9PT0gdm9pZCAwIHx8IChfcGFyc2VkRGF0YSRjb250ZW50czMgPSBwYXJzZWREYXRhLmNvbnRlbnRzKSA9PT0gbnVsbCB8fCBfcGFyc2VkRGF0YSRjb250ZW50czMgPT09IHZvaWQgMAogICAgICAgICAgICAgICAgICAgID8gdm9pZCAwCiAgICAgICAgICAgICAgICAgICAgOiBfcGFyc2VkRGF0YSRjb250ZW50czMudHdvQ29sdW1uU2VhcmNoUmVzdWx0c1JlbmRlcmVyKSA9PT0gJ29iamVjdCcgLy8gRGVza3RvcCBpbml0aWFsIHJlc3VsdHMKICAgICAgICAgICAgfHwgKHBhcnNlZERhdGEgPT09IG51bGwgfHwgcGFyc2VkRGF0YSA9PT0gdm9pZCAwIHx8IChfcGFyc2VkRGF0YSRjb250ZW50czQgPSBwYXJzZWREYXRhLmNvbnRlbnRzKSA9PT0gbnVsbCB8fCBfcGFyc2VkRGF0YSRjb250ZW50czQgPT09IHZvaWQgMAogICAgICAgICAgICAgICAgICAgICAgICB8fCAoX3BhcnNlZERhdGEkY29udGVudHM0ID0gX3BhcnNlZERhdGEkY29udGVudHM0LnNlY3Rpb25MaXN0UmVuZGVyZXIpID09PSBudWxsIHx8IF9wYXJzZWREYXRhJGNvbnRlbnRzNCA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICAgICAgPyB2b2lkIDAKICAgICAgICAgICAgICAgICAgICA6IF9wYXJzZWREYXRhJGNvbnRlbnRzNC50YXJnZXRJZCkgPT09ICdzZWFyY2gtZmVlZCcgLy8gTW9iaWxlIGluaXRpYWwgcmVzdWx0cwogICAgICAgICAgICB8fCAocGFyc2VkRGF0YSA9PT0gbnVsbCB8fCBwYXJzZWREYXRhID09PSB2b2lkIDAgfHwgKF9wYXJzZWREYXRhJG9uUmVzcG9ucyA9IHBhcnNlZERhdGEub25SZXNwb25zZVJlY2VpdmVkQ29tbWFuZHMpID09PSBudWxsIHx8IF9wYXJzZWREYXRhJG9uUmVzcG9ucyA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICAgICAgICAgIHx8IChfcGFyc2VkRGF0YSRvblJlc3BvbnMgPSBfcGFyc2VkRGF0YSRvblJlc3BvbnMuZmluZCgoeCkgPT4geC5hcHBlbmRDb250aW51YXRpb25JdGVtc0FjdGlvbikpID09PSBudWxsIHx8IF9wYXJzZWREYXRhJG9uUmVzcG9ucyA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICAgICAgICAgIHx8IChfcGFyc2VkRGF0YSRvblJlc3BvbnMgPSBfcGFyc2VkRGF0YSRvblJlc3BvbnMuYXBwZW5kQ29udGludWF0aW9uSXRlbXNBY3Rpb24pID09PSBudWxsIHx8IF9wYXJzZWREYXRhJG9uUmVzcG9ucyA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICAgICAgPyB2b2lkIDAKICAgICAgICAgICAgICAgICAgICA6IF9wYXJzZWREYXRhJG9uUmVzcG9ucy50YXJnZXRJZCkgPT09ICdzZWFyY2gtZmVlZCcgLy8gRGVza3RvcCAmIE1vYmlsZSBzY3JvbGwgY29udGludWF0aW9uCiAgICAgICAgKTsKICAgIH0KCiAgICBmdW5jdGlvbiBhdHRhY2gkNChvYmosIHByb3AsIG9uQ2FsbCkgewogICAgICAgIGlmICghb2JqIHx8IHR5cGVvZiBvYmpbcHJvcF0gIT09ICdmdW5jdGlvbicpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgbGV0IG9yaWdpbmFsID0gb2JqW3Byb3BdOwoKICAgICAgICBvYmpbcHJvcF0gPSBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIG9uQ2FsbChhcmd1bWVudHMpOwogICAgICAgICAgICB9IGNhdGNoIHt9CiAgICAgICAgICAgIG9yaWdpbmFsLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfTsKICAgIH0KCiAgICBjb25zdCBsb2dQcmVmaXggPSAnJWNTaW1wbGUtWW91VHViZS1BZ2UtUmVzdHJpY3Rpb24tQnlwYXNzOic7CiAgICBjb25zdCBsb2dQcmVmaXhTdHlsZSA9ICdiYWNrZ3JvdW5kLWNvbG9yOiAjMWU1Yzg1OyBjb2xvcjogI2ZmZjsgZm9udC1zaXplOiAxLjJlbTsnOwogICAgY29uc3QgbG9nU3VmZml4ID0gJ1x1RDgzRFx1REMxRSBZb3UgY2FuIHJlcG9ydCBidWdzIGF0OiBodHRwczovL2dpdGh1Yi5jb20vemVyb2R5dHJhc2gvU2ltcGxlLVlvdVR1YmUtQWdlLVJlc3RyaWN0aW9uLUJ5cGFzcy9pc3N1ZXMnOwoKICAgIGZ1bmN0aW9uIGVycm9yKGVyciwgbXNnKSB7CiAgICAgICAgY29uc29sZS5lcnJvcihsb2dQcmVmaXgsIGxvZ1ByZWZpeFN0eWxlLCBtc2csIGVyciwgZ2V0WXRjZmdEZWJ1Z1N0cmluZygpLCAnXG5cbicsIGxvZ1N1ZmZpeCk7CiAgICAgICAgaWYgKHdpbmRvdy5TWUFSQl9DT05GSUcpIHsKICAgICAgICAgICAgd2luZG93LmRpc3BhdGNoRXZlbnQoCiAgICAgICAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoJ1NZQVJCX0xPR19FUlJPUicsIHsKICAgICAgICAgICAgICAgICAgICBkZXRhaWw6IHsKICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogKG1zZyA/IG1zZyArICc7ICcgOiAnJykgKyAoZXJyICYmIGVyci5tZXNzYWdlID8gZXJyLm1lc3NhZ2UgOiAnJyksCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YWNrOiBlcnIgJiYgZXJyLnN0YWNrID8gZXJyLnN0YWNrIDogbnVsbCwKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgfSksCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGluZm8obXNnKSB7CiAgICAgICAgY29uc29sZS5pbmZvKGxvZ1ByZWZpeCwgbG9nUHJlZml4U3R5bGUsIG1zZyk7CiAgICAgICAgaWYgKHdpbmRvdy5TWUFSQl9DT05GSUcpIHsKICAgICAgICAgICAgd2luZG93LmRpc3BhdGNoRXZlbnQoCiAgICAgICAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoJ1NZQVJCX0xPR19JTkZPJywgewogICAgICAgICAgICAgICAgICAgIGRldGFpbDogewogICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBtc2csCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIH0pLAogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBnZXRZdGNmZ0RlYnVnU3RyaW5nKCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiAoCiAgICAgICAgICAgICAgICBgSW5uZXJ0dWJlQ29uZmlnOiBgCiAgICAgICAgICAgICAgICArIGBpbm5lcnR1YmVBcGlLZXk6ICR7Z2V0WXRjZmdWYWx1ZSgnSU5ORVJUVUJFX0FQSV9LRVknKX0gYAogICAgICAgICAgICAgICAgKyBgaW5uZXJ0dWJlQ2xpZW50TmFtZTogJHtnZXRZdGNmZ1ZhbHVlKCdJTk5FUlRVQkVfQ0xJRU5UX05BTUUnKX0gYAogICAgICAgICAgICAgICAgKyBgaW5uZXJ0dWJlQ2xpZW50VmVyc2lvbjogJHtnZXRZdGNmZ1ZhbHVlKCdJTk5FUlRVQkVfQ0xJRU5UX1ZFUlNJT04nKX0gYAogICAgICAgICAgICAgICAgKyBgbG9nZ2VkSW46ICR7Z2V0WXRjZmdWYWx1ZSgnTE9HR0VEX0lOJyl9IGAKICAgICAgICAgICAgKTsKICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgICAgcmV0dXJuIGBGYWlsZWQgdG8gYWNjZXNzIGNvbmZpZzogJHtlcnJ9YDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBbmQgaGVyZSB3ZSBkZWFsIHdpdGggWW91VHViZSdzIGNyYXBweSBpbml0aWFsIGRhdGEgKHByZXNlbnQgaW4gcGFnZSBzb3VyY2UpIGFuZCB0aGUgcHJvYmxlbXMgdGhhdCBvY2N1ciB3aGVuIGludGVyY2VwdGluZyB0aGF0IGRhdGEuCiAgICAgKiBZb3VUdWJlIGhhcyBzb21lIHByb3RlY3Rpb25zIGluIHBsYWNlIHRoYXQgbWFrZSBpdCBkaWZmaWN1bHQgdG8gaW50ZXJjZXB0IGFuZCBtb2RpZnkgdGhlIGdsb2JhbCB5dEluaXRpYWxQbGF5ZXJSZXNwb25zZSB2YXJpYWJsZS4KICAgICAqIFRoZSBlYXNpZXN0IHdheSB3b3VsZCBiZSB0byBzZXQgYSBkZXNjcmlwdG9yIG9uIHRoYXQgdmFyaWFibGUgdG8gY2hhbmdlIHRoZSB2YWx1ZSBkaXJlY3RseSBvbiBkZWNsYXJhdGlvbi4KICAgICAqIEJ1dCBzb21lIGFkYmxvY2tlcnMgZGVmaW5lIHRoZWlyIG93biBkZXNjcmlwdG9ycyBvbiB0aGUgeXRJbml0aWFsUGxheWVyUmVzcG9uc2UgdmFyaWFibGUsIHdoaWNoIG1ha2VzIGl0IGhhcmQgdG8gcmVnaXN0ZXIgYW5vdGhlciBkZXNjcmlwdG9yIG9uIGl0LgogICAgICogQXMgYSB3b3JrYXJvdW5kIG9ubHkgdGhlIHJlbGV2YW50IHBsYXllclJlc3BvbnNlIHByb3BlcnR5IG9mIHRoZSB5dEluaXRpYWxQbGF5ZXJSZXNwb25zZSB2YXJpYWJsZSB3aWxsIGJlIGludGVyY2VwdGVkLgogICAgICogVGhpcyBpcyBhY2hpZXZlZCBieSBkZWZpbmluZyBhIGRlc2NyaXB0b3Igb24gdGhlIG9iamVjdCBwcm90b3R5cGUgZm9yIHRoYXQgcHJvcGVydHksIHdoaWNoIGFmZmVjdHMgYW55IG9iamVjdCB3aXRoIGEgYHBsYXllclJlc3BvbnNlYCBwcm9wZXJ0eS4KICAgICAqLwogICAgZnVuY3Rpb24gYXR0YWNoJDMob25Jbml0aWFsRGF0YSkgewogICAgICAgIGludGVyY2VwdE9iamVjdFByb3BlcnR5KCdwbGF5ZXJSZXNwb25zZScsIChvYmosIHBsYXllclJlc3BvbnNlKSA9PiB7CiAgICAgICAgICAgIGluZm8oYHBsYXllclJlc3BvbnNlIHByb3BlcnR5IHNldCwgY29udGFpbnMgc2lkZWJhcjogJHshIW9iai5yZXNwb25zZX1gKTsKCiAgICAgICAgICAgIC8vIFRoZSBzYW1lIG9iamVjdCBhbHNvIGNvbnRhaW5zIHRoZSBzaWRlYmFyIGRhdGEgYW5kIHZpZGVvIGRlc2NyaXB0aW9uCiAgICAgICAgICAgIGlmIChpc09iamVjdChvYmoucmVzcG9uc2UpKSBvbkluaXRpYWxEYXRhKG9iai5yZXNwb25zZSk7CgogICAgICAgICAgICAvLyBJZiB0aGUgc2NyaXB0IGlzIGV4ZWN1dGVkIHRvbyBsYXRlIGFuZCB0aGUgYm9vdHN0cmFwIGRhdGEgaGFzIGFscmVhZHkgYmVlbiBwcm9jZXNzZWQsCiAgICAgICAgICAgIC8vIGEgcmVsb2FkIG9mIHRoZSBwbGF5ZXIgY2FuIGJlIGZvcmNlZCBieSBjcmVhdGluZyBhIGRlZXAgY29weSBvZiB0aGUgb2JqZWN0LgogICAgICAgICAgICAvLyBUaGlzIGlzIGVzcGVjaWFsbHkgcmVsZXZhbnQgaWYgdGhlIHVzZXJzY3JpcHQgbWFuYWdlciBkb2VzIG5vdCBoYW5kbGUgdGhlIGBAcnVuLWF0IGRvY3VtZW50LXN0YXJ0YCBjb3JyZWN0bHkuCiAgICAgICAgICAgIHBsYXllclJlc3BvbnNlLnVubG9ja2VkID0gZmFsc2U7CiAgICAgICAgICAgIG9uSW5pdGlhbERhdGEocGxheWVyUmVzcG9uc2UpOwogICAgICAgICAgICByZXR1cm4gcGxheWVyUmVzcG9uc2UudW5sb2NrZWQgPyBjcmVhdGVEZWVwQ29weShwbGF5ZXJSZXNwb25zZSkgOiBwbGF5ZXJSZXNwb25zZTsKICAgICAgICB9KTsKCiAgICAgICAgLy8gVGhlIGdsb2JhbCBgeXRJbml0aWFsRGF0YWAgdmFyaWFibGUgY2FuIGJlIG1vZGlmaWVkIG9uIHRoZSBmbHkuCiAgICAgICAgLy8gSXQgY29udGFpbnMgc2VhcmNoIHJlc3VsdHMsIHNpZGViYXIgZGF0YSBhbmQgbWV0YSBpbmZvcm1hdGlvbgogICAgICAgIC8vIE5vdCByZWFsbHkgaW1wb3J0YW50IGJ1dCBmaXhlcyBodHRwczovL2dpdGh1Yi5jb20vemVyb2R5dHJhc2gvU2ltcGxlLVlvdVR1YmUtQWdlLVJlc3RyaWN0aW9uLUJ5cGFzcy9pc3N1ZXMvMTI3CiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCAoKSA9PiB7CiAgICAgICAgICAgIGlmIChpc09iamVjdCh3aW5kb3cueXRJbml0aWFsRGF0YSkpIHsKICAgICAgICAgICAgICAgIG9uSW5pdGlhbERhdGEod2luZG93Lnl0SW5pdGlhbERhdGEpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9CgogICAgZnVuY3Rpb24gaW50ZXJjZXB0T2JqZWN0UHJvcGVydHkocHJvcCwgb25TZXQpIHsKICAgICAgICB2YXIgX09iamVjdCRnZXRPd25Qcm9wZXJ0OwogICAgICAgIC8vIEFsbG93IG90aGVyIHVzZXJzY3JpcHRzIHRvIGRlY29yYXRlIHRoaXMgZGVzY3JpcHRvciwgaWYgdGhleSBkbyBzb21ldGhpbmcgc2ltaWxhcgogICAgICAgIGNvbnN0IGRhdGFLZXkgPSAnX19TWUFSQl8nICsgcHJvcDsKICAgICAgICBjb25zdCB7IGdldDogZ2V0dGVyLCBzZXQ6IHNldHRlciB9ID0gKF9PYmplY3QkZ2V0T3duUHJvcGVydCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoT2JqZWN0LnByb3RvdHlwZSwgcHJvcCkpICE9PSBudWxsICYmIF9PYmplY3QkZ2V0T3duUHJvcGVydCAhPT0gdm9pZCAwCiAgICAgICAgICAgID8gX09iamVjdCRnZXRPd25Qcm9wZXJ0CiAgICAgICAgICAgIDogewogICAgICAgICAgICAgICAgc2V0KHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpc1tkYXRhS2V5XSA9IHZhbHVlOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGdldCgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpc1tkYXRhS2V5XTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIH07CgogICAgICAgIC8vIEludGVyY2VwdCB0aGUgZ2l2ZW4gcHJvcGVydHkgb24gYW55IG9iamVjdAogICAgICAgIC8vIFRoZSBhc3NpZ25lZCBhdHRyaWJ1dGUgdmFsdWUgYW5kIHRoZSBjb250ZXh0IChlbmNsb3Npbmcgb2JqZWN0KSBhcmUgcGFzc2VkIHRvIHRoZSBvblNldCBmdW5jdGlvbi4KICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoT2JqZWN0LnByb3RvdHlwZSwgcHJvcCwgewogICAgICAgICAgICBzZXQodmFsdWUpIHsKICAgICAgICAgICAgICAgIHNldHRlci5jYWxsKHRoaXMsIGlzT2JqZWN0KHZhbHVlKSA/IG9uU2V0KHRoaXMsIHZhbHVlKSA6IHZhbHVlKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZ2V0KCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGdldHRlci5jYWxsKHRoaXMpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsCiAgICAgICAgfSk7CiAgICB9CgogICAgLy8gSW50ZXJjZXB0LCBpbnNwZWN0IGFuZCBtb2RpZnkgSlNPTi1iYXNlZCBjb21tdW5pY2F0aW9uIHRvIHVubG9jayBwbGF5ZXIgcmVzcG9uc2VzIGJ5IGhpamFja2luZyB0aGUgSlNPTi5wYXJzZSBmdW5jdGlvbgogICAgZnVuY3Rpb24gYXR0YWNoJDIob25Kc29uRGF0YVJlY2VpdmVkKSB7CiAgICAgICAgd2luZG93LkpTT04ucGFyc2UgPSBmdW5jdGlvbigpIHsKICAgICAgICAgICAgY29uc3QgZGF0YSA9IG5hdGl2ZUpTT05QYXJzZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICByZXR1cm4gaXNPYmplY3QoZGF0YSkgPyBvbkpzb25EYXRhUmVjZWl2ZWQoZGF0YSkgOiBkYXRhOwogICAgICAgIH07CiAgICB9CgogICAgZnVuY3Rpb24gYXR0YWNoJDEob25SZXF1ZXN0Q3JlYXRlKSB7CiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cuUmVxdWVzdCAhPT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICB3aW5kb3cuUmVxdWVzdCA9IG5ldyBQcm94eSh3aW5kb3cuUmVxdWVzdCwgewogICAgICAgICAgICBjb25zdHJ1Y3QodGFyZ2V0LCBhcmdzKSB7CiAgICAgICAgICAgICAgICBjb25zdCBbdXJsLCBvcHRpb25zXSA9IGFyZ3M7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZFVybCA9IHBhcnNlUmVsYXRpdmVVcmwodXJsKTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBtb2RpZmllZFVybCA9IG9uUmVxdWVzdENyZWF0ZShwYXJzZWRVcmwsIG9wdGlvbnMpOwoKICAgICAgICAgICAgICAgICAgICBpZiAobW9kaWZpZWRVcmwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1swXSA9IG1vZGlmaWVkVXJsLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IoZXJyLCBgRmFpbGVkIHRvIGludGVyY2VwdCBSZXF1ZXN0KClgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gUmVmbGVjdC5jb25zdHJ1Y3QoLi4uYXJndW1lbnRzKTsKICAgICAgICAgICAgfSwKICAgICAgICB9KTsKICAgIH0KCiAgICBmdW5jdGlvbiBhdHRhY2gob25YaHJPcGVuQ2FsbGVkKSB7CiAgICAgICAgWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbihtZXRob2QsIHVybCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgbGV0IHBhcnNlZFVybCA9IHBhcnNlUmVsYXRpdmVVcmwodXJsKTsKCiAgICAgICAgICAgICAgICBpZiAocGFyc2VkVXJsKSB7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgbW9kaWZpZWRVcmwgPSBvblhock9wZW5DYWxsZWQobWV0aG9kLCBwYXJzZWRVcmwsIHRoaXMpOwoKICAgICAgICAgICAgICAgICAgICBpZiAobW9kaWZpZWRVcmwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzWzFdID0gbW9kaWZpZWRVcmwudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICAgICAgZXJyb3IoZXJyLCBgRmFpbGVkIHRvIGludGVyY2VwdCBYTUxIdHRwUmVxdWVzdC5vcGVuKClgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbmF0aXZlWE1MSHR0cFJlcXVlc3RPcGVuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfTsKICAgIH0KCiAgICBjb25zdCBsb2NhbFN0b3JhZ2VQcmVmaXggPSAnU1lBUkJfJzsKCiAgICBmdW5jdGlvbiBzZXQoa2V5LCB2YWx1ZSkgewogICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGxvY2FsU3RvcmFnZVByZWZpeCArIGtleSwgSlNPTi5zdHJpbmdpZnkodmFsdWUpKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXQoa2V5KSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0obG9jYWxTdG9yYWdlUHJlZml4ICsga2V5KSk7CiAgICAgICAgfSBjYXRjaCB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBnZXRQbGF5ZXIkMShwYXlsb2FkLCB1c2VBdXRoKSB7CiAgICAgICAgcmV0dXJuIHNlbmRJbm5lcnR1YmVSZXF1ZXN0KCd2MS9wbGF5ZXInLCBwYXlsb2FkLCB1c2VBdXRoKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXROZXh0JDEocGF5bG9hZCwgdXNlQXV0aCkgewogICAgICAgIHJldHVybiBzZW5kSW5uZXJ0dWJlUmVxdWVzdCgndjEvbmV4dCcsIHBheWxvYWQsIHVzZUF1dGgpOwogICAgfQoKICAgIGZ1bmN0aW9uIHNlbmRJbm5lcnR1YmVSZXF1ZXN0KGVuZHBvaW50LCBwYXlsb2FkLCB1c2VBdXRoKSB7CiAgICAgICAgY29uc3QgeG1saHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOwogICAgICAgIHhtbGh0dHAub3BlbignUE9TVCcsIGAveW91dHViZWkvJHtlbmRwb2ludH0/a2V5PSR7Z2V0WXRjZmdWYWx1ZSgnSU5ORVJUVUJFX0FQSV9LRVknKX0mcHJldHR5UHJpbnQ9ZmFsc2VgLCBmYWxzZSk7CgogICAgICAgIGlmICh1c2VBdXRoICYmIGlzVXNlckxvZ2dlZEluKCkpIHsKICAgICAgICAgICAgeG1saHR0cC53aXRoQ3JlZGVudGlhbHMgPSB0cnVlOwogICAgICAgICAgICBDb25maWcuR09PR0xFX0FVVEhfSEVBREVSX05BTUVTLmZvckVhY2goKGhlYWRlck5hbWUpID0+IHsKICAgICAgICAgICAgICAgIHhtbGh0dHAuc2V0UmVxdWVzdEhlYWRlcihoZWFkZXJOYW1lLCBnZXQoaGVhZGVyTmFtZSkpOwogICAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIHhtbGh0dHAuc2VuZChKU09OLnN0cmluZ2lmeShwYXlsb2FkKSk7CiAgICAgICAgcmV0dXJuIG5hdGl2ZUpTT05QYXJzZSh4bWxodHRwLnJlc3BvbnNlVGV4dCk7CiAgICB9CgogICAgdmFyIGlubmVydHViZSA9IHsKICAgICAgICBnZXRQbGF5ZXI6IGdldFBsYXllciQxLAogICAgICAgIGdldE5leHQ6IGdldE5leHQkMSwKICAgIH07CgogICAgbGV0IG5leHRSZXNwb25zZUNhY2hlID0ge307CgogICAgZnVuY3Rpb24gZ2V0R29vZ2xlVmlkZW9Vcmwob3JpZ2luYWxVcmwpIHsKICAgICAgICByZXR1cm4gQ29uZmlnLlZJREVPX1BST1hZX1NFUlZFUl9IT1NUICsgJy9kaXJlY3QvJyArIGJ0b2Eob3JpZ2luYWxVcmwudG9TdHJpbmcoKSk7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0UGxheWVyKHBheWxvYWQpIHsKICAgICAgICAvLyBBbHNvIHJlcXVlc3QgdGhlIC9uZXh0IHJlc3BvbnNlIGlmIGEgbGF0ZXIgL25leHQgcmVxdWVzdCBpcyBsaWtlbHkuCiAgICAgICAgaWYgKCFuZXh0UmVzcG9uc2VDYWNoZVtwYXlsb2FkLnZpZGVvSWRdICYmICFpc011c2ljICYmICFpc0VtYmVkKSB7CiAgICAgICAgICAgIHBheWxvYWQuaW5jbHVkZU5leHQgPSAxOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KCdnZXRQbGF5ZXInLCBwYXlsb2FkKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXROZXh0KHBheWxvYWQpIHsKICAgICAgICAvLyBOZXh0IHJlc3BvbnNlIGFscmVhZHkgY2FjaGVkPyA9PiBSZXR1cm4gY2FjaGVkIGNvbnRlbnQKICAgICAgICBpZiAobmV4dFJlc3BvbnNlQ2FjaGVbcGF5bG9hZC52aWRlb0lkXSkgewogICAgICAgICAgICByZXR1cm4gbmV4dFJlc3BvbnNlQ2FjaGVbcGF5bG9hZC52aWRlb0lkXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBzZW5kUmVxdWVzdCgnZ2V0TmV4dCcsIHBheWxvYWQpOwogICAgfQoKICAgIGZ1bmN0aW9uIHNlbmRSZXF1ZXN0KGVuZHBvaW50LCBwYXlsb2FkKSB7CiAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHBheWxvYWQpOwogICAgICAgIGNvbnN0IHByb3h5VXJsID0gYCR7Q29uZmlnLkFDQ09VTlRfUFJPWFlfU0VSVkVSX0hPU1R9LyR7ZW5kcG9pbnR9PyR7cXVlcnlQYXJhbXN9JmNsaWVudD1qc2A7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGNvbnN0IHhtbGh0dHAgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTsKICAgICAgICAgICAgeG1saHR0cC5vcGVuKCdHRVQnLCBwcm94eVVybCwgZmFsc2UpOwogICAgICAgICAgICB4bWxodHRwLnNlbmQobnVsbCk7CgogICAgICAgICAgICBjb25zdCBwcm94eVJlc3BvbnNlID0gbmF0aXZlSlNPTlBhcnNlKHhtbGh0dHAucmVzcG9uc2VUZXh0KTsKCiAgICAgICAgICAgIC8vIE1hcmsgcmVxdWVzdCBhcyAncHJveGllZCcKICAgICAgICAgICAgcHJveHlSZXNwb25zZS5wcm94aWVkID0gdHJ1ZTsKCiAgICAgICAgICAgIC8vIFB1dCBpbmNsdWRlZCAvbmV4dCByZXNwb25zZSBpbiB0aGUgY2FjaGUKICAgICAgICAgICAgaWYgKHByb3h5UmVzcG9uc2UubmV4dFJlc3BvbnNlKSB7CiAgICAgICAgICAgICAgICBuZXh0UmVzcG9uc2VDYWNoZVtwYXlsb2FkLnZpZGVvSWRdID0gcHJveHlSZXNwb25zZS5uZXh0UmVzcG9uc2U7CiAgICAgICAgICAgICAgICBkZWxldGUgcHJveHlSZXNwb25zZS5uZXh0UmVzcG9uc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBwcm94eVJlc3BvbnNlOwogICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICBlcnJvcihlcnIsICdQcm94eSBBUEkgRXJyb3InKTsKICAgICAgICAgICAgcmV0dXJuIHsgZXJyb3JNZXNzYWdlOiAnUHJveHkgQ29ubmVjdGlvbiBmYWlsZWQnIH07CiAgICAgICAgfQogICAgfQoKICAgIHZhciBwcm94eSA9IHsKICAgICAgICBnZXRQbGF5ZXIsCiAgICAgICAgZ2V0TmV4dCwKICAgICAgICBnZXRHb29nbGVWaWRlb1VybCwKICAgIH07CgogICAgZnVuY3Rpb24gZ2V0VW5sb2NrU3RyYXRlZ2llcyQxKHZpZGVvSWQsIGxhc3RQbGF5ZXJVbmxvY2tSZWFzb24pIHsKICAgICAgICB2YXIgX2dldFl0Y2ZnVmFsdWUkY2xpZW50OwogICAgICAgIGNvbnN0IGNsaWVudE5hbWUgPSBnZXRZdGNmZ1ZhbHVlKCdJTk5FUlRVQkVfQ0xJRU5UX05BTUUnKSB8fCAnV0VCJzsKICAgICAgICBjb25zdCBjbGllbnRWZXJzaW9uID0gZ2V0WXRjZmdWYWx1ZSgnSU5ORVJUVUJFX0NMSUVOVF9WRVJTSU9OJykgfHwgJzIuMjAyMjAyMDMuMDQuMDAnOwogICAgICAgIGNvbnN0IGhsID0gZ2V0WXRjZmdWYWx1ZSgnSEwnKTsKICAgICAgICBjb25zdCB1c2VySW50ZXJmYWNlVGhlbWUgPSAoX2dldFl0Y2ZnVmFsdWUkY2xpZW50ID0gZ2V0WXRjZmdWYWx1ZSgnSU5ORVJUVUJFX0NPTlRFWFQnKS5jbGllbnQudXNlckludGVyZmFjZVRoZW1lKSAhPT0gbnVsbCAmJiBfZ2V0WXRjZmdWYWx1ZSRjbGllbnQgIT09IHZvaWQgMAogICAgICAgICAgICA/IF9nZXRZdGNmZ1ZhbHVlJGNsaWVudAogICAgICAgICAgICA6IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5oYXNBdHRyaWJ1dGUoJ2RhcmsnKQogICAgICAgICAgICA/ICdVU0VSX0lOVEVSRkFDRV9USEVNRV9EQVJLJwogICAgICAgICAgICA6ICdVU0VSX0lOVEVSRkFDRV9USEVNRV9MSUdIVCc7CgogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBSZXRyaWV2ZSB0aGUgc2lkZWJhciBhbmQgdmlkZW8gZGVzY3JpcHRpb24gYnkganVzdCBhZGRpbmcgYHJhY3lDaGVja09rYCBhbmQgYGNvbnRlbnRDaGVja09rYCBwYXJhbXMKICAgICAgICAgICAgICogVGhpcyBzdHJhdGVneSBjYW4gYmUgdXNlZCB0byBieXBhc3MgY29udGVudCB3YXJuaW5ncwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbmFtZTogJ0NvbnRlbnQgV2FybmluZyBCeXBhc3MnLAogICAgICAgICAgICAgICAgc2tpcDogIWxhc3RQbGF5ZXJVbmxvY2tSZWFzb24gfHwgIWxhc3RQbGF5ZXJVbmxvY2tSZWFzb24uaW5jbHVkZXMoJ0NIRUNLX1JFUVVJUkVEJyksCiAgICAgICAgICAgICAgICBvcHRpb25hbEF1dGg6IHRydWUsCiAgICAgICAgICAgICAgICBwYXlsb2FkOiB7CiAgICAgICAgICAgICAgICAgICAgY29udGV4dDogewogICAgICAgICAgICAgICAgICAgICAgICBjbGllbnQ6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudE5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRWZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VySW50ZXJmYWNlVGhlbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICB2aWRlb0lkLAogICAgICAgICAgICAgICAgICAgIHJhY3lDaGVja09rOiB0cnVlLAogICAgICAgICAgICAgICAgICAgIGNvbnRlbnRDaGVja09rOiB0cnVlLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGVuZHBvaW50OiBpbm5lcnR1YmUsCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBSZXRyaWV2ZSB0aGUgc2lkZWJhciBhbmQgdmlkZW8gZGVzY3JpcHRpb24gZnJvbSBhbiBhY2NvdW50IHByb3h5IHNlcnZlci4KICAgICAgICAgICAgICogU2Vzc2lvbiBjb29raWVzIG9mIGFuIGFnZS12ZXJpZmllZCBHb29nbGUgYWNjb3VudCBhcmUgc3RvcmVkIG9uIHNlcnZlciBzaWRlLgogICAgICAgICAgICAgKiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3plcm9keXRyYXNoL1NpbXBsZS1Zb3VUdWJlLUFnZS1SZXN0cmljdGlvbi1CeXBhc3MvdHJlZS9tYWluL2FjY291bnQtcHJveHkKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG5hbWU6ICdBY2NvdW50IFByb3h5JywKICAgICAgICAgICAgICAgIHBheWxvYWQ6IHsKICAgICAgICAgICAgICAgICAgICB2aWRlb0lkLAogICAgICAgICAgICAgICAgICAgIGNsaWVudE5hbWUsCiAgICAgICAgICAgICAgICAgICAgY2xpZW50VmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICBobCwKICAgICAgICAgICAgICAgICAgICB1c2VySW50ZXJmYWNlVGhlbWUsCiAgICAgICAgICAgICAgICAgICAgaXNFbWJlZDogK2lzRW1iZWQsCiAgICAgICAgICAgICAgICAgICAgaXNDb25maXJtZWQ6ICtpc0NvbmZpcm1lZCwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBlbmRwb2ludDogcHJveHksCiAgICAgICAgICAgIH0sCiAgICAgICAgXTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRVbmxvY2tTdHJhdGVnaWVzKHZpZGVvSWQsIHJlYXNvbikgewogICAgICAgIGNvbnN0IGNsaWVudE5hbWUgPSBnZXRZdGNmZ1ZhbHVlKCdJTk5FUlRVQkVfQ0xJRU5UX05BTUUnKSB8fCAnV0VCJzsKICAgICAgICBjb25zdCBjbGllbnRWZXJzaW9uID0gZ2V0WXRjZmdWYWx1ZSgnSU5ORVJUVUJFX0NMSUVOVF9WRVJTSU9OJykgfHwgJzIuMjAyMjAyMDMuMDQuMDAnOwogICAgICAgIGNvbnN0IHNpZ25hdHVyZVRpbWVzdGFtcCA9IGdldFNpZ25hdHVyZVRpbWVzdGFtcCgpOwogICAgICAgIGNvbnN0IHN0YXJ0VGltZVNlY3MgPSBnZXRDdXJyZW50VmlkZW9TdGFydFRpbWUodmlkZW9JZCk7CiAgICAgICAgY29uc3QgaGwgPSBnZXRZdGNmZ1ZhbHVlKCdITCcpOwoKICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogUmV0cmlldmUgdGhlIHZpZGVvIGluZm8gYnkganVzdCBhZGRpbmcgYHJhY3lDaGVja09rYCBhbmQgYGNvbnRlbnRDaGVja09rYCBwYXJhbXMKICAgICAgICAgICAgICogVGhpcyBzdHJhdGVneSBjYW4gYmUgdXNlZCB0byBieXBhc3MgY29udGVudCB3YXJuaW5ncwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbmFtZTogJ0NvbnRlbnQgV2FybmluZyBCeXBhc3MnLAogICAgICAgICAgICAgICAgc2tpcDogIXJlYXNvbiB8fCAhcmVhc29uLmluY2x1ZGVzKCdDSEVDS19SRVFVSVJFRCcpLAogICAgICAgICAgICAgICAgb3B0aW9uYWxBdXRoOiB0cnVlLAogICAgICAgICAgICAgICAgcGF5bG9hZDogewogICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6IHsKICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50OiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnROYW1lOiBjbGllbnROYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50VmVyc2lvbjogY2xpZW50VmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhsLAogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgcGxheWJhY2tDb250ZXh0OiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRQbGF5YmFja0NvbnRleHQ6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25hdHVyZVRpbWVzdGFtcCwKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHZpZGVvSWQsCiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lU2VjcywKICAgICAgICAgICAgICAgICAgICByYWN5Q2hlY2tPazogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBjb250ZW50Q2hlY2tPazogdHJ1ZSwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBlbmRwb2ludDogaW5uZXJ0dWJlLAogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogUmV0cmlldmUgdGhlIHZpZGVvIGluZm8gYnkgdXNpbmcgdGhlIFRWSFRNTDUgRW1iZWRkZWQgY2xpZW50CiAgICAgICAgICAgICAqIFRoaXMgY2xpZW50IGhhcyBubyBhZ2UgcmVzdHJpY3Rpb25zIGluIHBsYWNlICgyMDIyLTAzLTI4KQogICAgICAgICAgICAgKiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3plcm9keXRyYXNoL1lvdVR1YmUtSW50ZXJuYWwtQ2xpZW50cwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbmFtZTogJ1RWIEVtYmVkZGVkIFBsYXllcicsCiAgICAgICAgICAgICAgICByZXF1aXJlc0F1dGg6IGZhbHNlLAogICAgICAgICAgICAgICAgcGF5bG9hZDogewogICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6IHsKICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50OiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnROYW1lOiAnVFZIVE1MNV9TSU1QTFlfRU1CRURERURfUExBWUVSJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudFZlcnNpb246ICcyLjAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50U2NyZWVuOiAnV0FUQ0gnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGwsCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXJkUGFydHk6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkVXJsOiAnaHR0cHM6Ly93d3cueW91dHViZS5jb20vJywKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHBsYXliYWNrQ29udGV4dDogewogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50UGxheWJhY2tDb250ZXh0OiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduYXR1cmVUaW1lc3RhbXAsCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICB2aWRlb0lkLAogICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZVNlY3MsCiAgICAgICAgICAgICAgICAgICAgcmFjeUNoZWNrT2s6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgY29udGVudENoZWNrT2s6IHRydWUsCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZW5kcG9pbnQ6IGlubmVydHViZSwKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFJldHJpZXZlIHRoZSB2aWRlbyBpbmZvIGJ5IHVzaW5nIHRoZSBXRUJfQ1JFQVRPUiBjbGllbnQgaW4gY29tYmluYXRpb24gd2l0aCB1c2VyIGF1dGhlbnRpY2F0aW9uCiAgICAgICAgICAgICAqIFJlcXVpcmVzIHRoYXQgdGhlIHVzZXIgaXMgbG9nZ2VkIGluLiBDYW4gYnlwYXNzIHRoZSB0aWdodGVuZWQgYWdlIHZlcmlmaWNhdGlvbiBpbiB0aGUgRVUuCiAgICAgICAgICAgICAqIFNlZSBodHRwczovL2dpdGh1Yi5jb20veXQtZGxwL3l0LWRscC9wdWxsLzYwMAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbmFtZTogJ0NyZWF0b3IgKyBBdXRoJywKICAgICAgICAgICAgICAgIHJlcXVpcmVzQXV0aDogdHJ1ZSwKICAgICAgICAgICAgICAgIHBheWxvYWQ6IHsKICAgICAgICAgICAgICAgICAgICBjb250ZXh0OiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudDogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50TmFtZTogJ1dFQl9DUkVBVE9SJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudFZlcnNpb246ICcxLjIwMjEwOTA5LjA3LjAwJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhsLAogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgcGxheWJhY2tDb250ZXh0OiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRQbGF5YmFja0NvbnRleHQ6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25hdHVyZVRpbWVzdGFtcCwKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHZpZGVvSWQsCiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lU2VjcywKICAgICAgICAgICAgICAgICAgICByYWN5Q2hlY2tPazogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBjb250ZW50Q2hlY2tPazogdHJ1ZSwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBlbmRwb2ludDogaW5uZXJ0dWJlLAogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogUmV0cmlldmUgdGhlIHZpZGVvIGluZm8gZnJvbSBhbiBhY2NvdW50IHByb3h5IHNlcnZlci4KICAgICAgICAgICAgICogU2Vzc2lvbiBjb29raWVzIG9mIGFuIGFnZS12ZXJpZmllZCBHb29nbGUgYWNjb3VudCBhcmUgc3RvcmVkIG9uIHNlcnZlciBzaWRlLgogICAgICAgICAgICAgKiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3plcm9keXRyYXNoL1NpbXBsZS1Zb3VUdWJlLUFnZS1SZXN0cmljdGlvbi1CeXBhc3MvdHJlZS9tYWluL2FjY291bnQtcHJveHkKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG5hbWU6ICdBY2NvdW50IFByb3h5JywKICAgICAgICAgICAgICAgIHBheWxvYWQ6IHsKICAgICAgICAgICAgICAgICAgICB2aWRlb0lkLAogICAgICAgICAgICAgICAgICAgIHJlYXNvbiwKICAgICAgICAgICAgICAgICAgICBjbGllbnROYW1lLAogICAgICAgICAgICAgICAgICAgIGNsaWVudFZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgc2lnbmF0dXJlVGltZXN0YW1wLAogICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZVNlY3MsCiAgICAgICAgICAgICAgICAgICAgaGwsCiAgICAgICAgICAgICAgICAgICAgaXNFbWJlZDogK2lzRW1iZWQsCiAgICAgICAgICAgICAgICAgICAgaXNDb25maXJtZWQ6ICtpc0NvbmZpcm1lZCwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBlbmRwb2ludDogcHJveHksCiAgICAgICAgICAgIH0sCiAgICAgICAgXTsKICAgIH0KCiAgICB2YXIgYnV0dG9uVGVtcGxhdGUgPQogICAgICAgICc8ZGl2IHN0eWxlPSJtYXJnaW4tdG9wOiAxNXB4ICFpbXBvcnRhbnQ7IHBhZGRpbmc6IDNweCAxMHB4IDNweCAxMHB4OyBtYXJnaW46IDBweCBhdXRvOyBiYWNrZ3JvdW5kLWNvbG9yOiAjNGQ0ZDRkOyB3aWR0aDogZml0LWNvbnRlbnQ7IGZvbnQtc2l6ZTogMS4yZW07IHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7IGJvcmRlci1yYWRpdXM6IDNweDsgY3Vyc29yOiBwb2ludGVyOyI+XG4gICAgPGRpdiBjbGFzcz0iYnV0dG9uLXRleHQiPjwvZGl2PlxuPC9kaXY+JzsKCiAgICBsZXQgYnV0dG9ucyA9IHt9OwoKICAgIGFzeW5jIGZ1bmN0aW9uIGFkZEJ1dHRvbihpZCwgdGV4dCwgYmFja2dyb3VuZENvbG9yLCBvbkNsaWNrKSB7CiAgICAgICAgY29uc3QgZXJyb3JTY3JlZW5FbGVtZW50ID0gYXdhaXQgd2FpdEZvckVsZW1lbnQoJy55dHAtZXJyb3InLCAyMDAwKTsKICAgICAgICBjb25zdCBidXR0b25FbGVtZW50ID0gY3JlYXRlRWxlbWVudCgnZGl2JywgeyBjbGFzczogJ2J1dHRvbi1jb250YWluZXInLCBpbm5lckhUTUw6IGJ1dHRvblRlbXBsYXRlIH0pOwogICAgICAgIGJ1dHRvbkVsZW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnYnV0dG9uLXRleHQnKVswXS5pbm5lclRleHQgPSB0ZXh0OwoKICAgICAgICBpZiAoYmFja2dyb3VuZENvbG9yKSB7CiAgICAgICAgICAgIGJ1dHRvbkVsZW1lbnQucXVlcnlTZWxlY3RvcignOnNjb3BlID4gZGl2Jykuc3R5bGVbJ2JhY2tncm91bmQtY29sb3InXSA9IGJhY2tncm91bmRDb2xvcjsKICAgICAgICB9CgogICAgICAgIGlmICh0eXBlb2Ygb25DbGljayA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICBidXR0b25FbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgb25DbGljayk7CiAgICAgICAgfQoKICAgICAgICAvLyBCdXR0b24gYWxyZWFkeSBhdHRhY2hlZD8KICAgICAgICBpZiAoYnV0dG9uc1tpZF0gJiYgYnV0dG9uc1tpZF0uaXNDb25uZWN0ZWQpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgYnV0dG9uc1tpZF0gPSBidXR0b25FbGVtZW50OwogICAgICAgIGVycm9yU2NyZWVuRWxlbWVudC5hcHBlbmQoYnV0dG9uRWxlbWVudCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlQnV0dG9uKGlkKSB7CiAgICAgICAgaWYgKGJ1dHRvbnNbaWRdICYmIGJ1dHRvbnNbaWRdLmlzQ29ubmVjdGVkKSB7CiAgICAgICAgICAgIGJ1dHRvbnNbaWRdLnJlbW92ZSgpOwogICAgICAgIH0KICAgIH0KCiAgICBjb25zdCBjb25maXJtYXRpb25CdXR0b25JZCA9ICdjb25maXJtQnV0dG9uJzsKICAgIGNvbnN0IGNvbmZpcm1hdGlvbkJ1dHRvblRleHQgPSAnQ2xpY2sgdG8gdW5sb2NrJzsKCiAgICBmdW5jdGlvbiBpc0NvbmZpcm1hdGlvblJlcXVpcmVkKCkgewogICAgICAgIHJldHVybiAhaXNDb25maXJtZWQgJiYgaXNFbWJlZCAmJiBDb25maWcuRU5BQkxFX1VOTE9DS19DT05GSVJNQVRJT05fRU1CRUQ7CiAgICB9CgogICAgZnVuY3Rpb24gcmVxdWVzdENvbmZpcm1hdGlvbigpIHsKICAgICAgICBhZGRCdXR0b24oY29uZmlybWF0aW9uQnV0dG9uSWQsIGNvbmZpcm1hdGlvbkJ1dHRvblRleHQsIG51bGwsICgpID0+IHsKICAgICAgICAgICAgcmVtb3ZlQnV0dG9uKGNvbmZpcm1hdGlvbkJ1dHRvbklkKTsKICAgICAgICAgICAgY29uZmlybSgpOwogICAgICAgIH0pOwogICAgfQoKICAgIGZ1bmN0aW9uIGNvbmZpcm0oKSB7CiAgICAgICAgc2V0VXJsUGFyYW1zKHsKICAgICAgICAgICAgdW5sb2NrX2NvbmZpcm1lZDogMSwKICAgICAgICAgICAgYXV0b3BsYXk6IDEsCiAgICAgICAgfSk7CiAgICB9CgogICAgdmFyIHREZXNrdG9wID0gJzx0cC15dC1wYXBlci10b2FzdD48L3RwLXl0LXBhcGVyLXRvYXN0PlxuJzsKCiAgICB2YXIgdE1vYmlsZSA9CiAgICAgICAgJzxjMy10b2FzdD5cbiAgICA8eXRtLW5vdGlmaWNhdGlvbi1hY3Rpb24tcmVuZGVyZXI+XG4gICAgICAgIDxkaXYgY2xhc3M9Im5vdGlmaWNhdGlvbi1hY3Rpb24tcmVzcG9uc2UtdGV4dCI+PC9kaXY+XG4gICAgPC95dG0tbm90aWZpY2F0aW9uLWFjdGlvbi1yZW5kZXJlcj5cbjwvYzMtdG9hc3Q+XG4nOwoKICAgIGNvbnN0IHRlbXBsYXRlID0gaXNEZXNrdG9wID8gdERlc2t0b3AgOiB0TW9iaWxlOwoKICAgIGNvbnN0IG5Ub2FzdENvbnRhaW5lciA9IGNyZWF0ZUVsZW1lbnQoJ2RpdicsIHsgaWQ6ICd0b2FzdC1jb250YWluZXInLCBpbm5lckhUTUw6IHRlbXBsYXRlIH0pOwogICAgY29uc3QgblRvYXN0ID0gblRvYXN0Q29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJzpzY29wZSA+IConKTsKCiAgICAvLyBPbiBZVCBNdXNpYyBzaG93IHRoZSB0b2FzdCBhYm92ZSB0aGUgcGxheWVyIGNvbnRyb2xzCiAgICBpZiAoaXNNdXNpYykgewogICAgICAgIG5Ub2FzdC5zdHlsZVsnbWFyZ2luLWJvdHRvbSddID0gJzg1cHgnOwogICAgfQoKICAgIGlmICghaXNEZXNrdG9wKSB7CiAgICAgICAgblRvYXN0Lm5NZXNzYWdlID0gblRvYXN0LnF1ZXJ5U2VsZWN0b3IoJy5ub3RpZmljYXRpb24tYWN0aW9uLXJlc3BvbnNlLXRleHQnKTsKICAgICAgICBuVG9hc3Quc2hvdyA9IChtZXNzYWdlKSA9PiB7CiAgICAgICAgICAgIG5Ub2FzdC5uTWVzc2FnZS5pbm5lclRleHQgPSBtZXNzYWdlOwogICAgICAgICAgICBuVG9hc3Quc2V0QXR0cmlidXRlKCdkaXInLCAnaW4nKTsKICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7CiAgICAgICAgICAgICAgICBuVG9hc3Quc2V0QXR0cmlidXRlKCdkaXInLCAnb3V0Jyk7CiAgICAgICAgICAgIH0sIG5Ub2FzdC5kdXJhdGlvbiArIDIyNSk7CiAgICAgICAgfTsKICAgIH0KCiAgICBhc3luYyBmdW5jdGlvbiBzaG93KG1lc3NhZ2UsIGR1cmF0aW9uID0gNSkgewogICAgICAgIGlmICghQ29uZmlnLkVOQUJMRV9VTkxPQ0tfTk9USUZJQ0FUSU9OKSByZXR1cm47CiAgICAgICAgaWYgKGlzRW1iZWQpIHJldHVybjsKCiAgICAgICAgYXdhaXQgcGFnZUxvYWRlZCgpOwoKICAgICAgICAvLyBEbyBub3Qgc2hvdyBub3RpZmljYXRpb24gd2hlbiB0YWIgaXMgaW4gYmFja2dyb3VuZAogICAgICAgIGlmIChkb2N1bWVudC52aXNpYmlsaXR5U3RhdGUgPT09ICdoaWRkZW4nKSByZXR1cm47CgogICAgICAgIC8vIEFwcGVuZCB0b2FzdCBjb250YWluZXIgdG8gRE9NLCBpZiBub3QgYWxyZWFkeSBkb25lCiAgICAgICAgaWYgKCFuVG9hc3RDb250YWluZXIuaXNDb25uZWN0ZWQpIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5hcHBlbmQoblRvYXN0Q29udGFpbmVyKTsKCiAgICAgICAgblRvYXN0LmR1cmF0aW9uID0gZHVyYXRpb24gKiAxMDAwOwogICAgICAgIG5Ub2FzdC5zaG93KG1lc3NhZ2UpOwogICAgfQoKICAgIHZhciBUb2FzdCA9IHsgc2hvdyB9OwoKICAgIGNvbnN0IG1lc3NhZ2VzTWFwID0gewogICAgICAgIHN1Y2Nlc3M6ICdBZ2UtcmVzdHJpY3RlZCB2aWRlbyBzdWNjZXNzZnVsbHkgdW5sb2NrZWQhJywKICAgICAgICBmYWlsOiAnVW5hYmxlIHRvIHVubG9jayB0aGlzIHZpZGVvIPCfmYEgLSBNb3JlIGluZm9ybWF0aW9uIGluIHRoZSBkZXZlbG9wZXIgY29uc29sZScsCiAgICB9OwoKICAgIGxldCBsYXN0UGxheWVyVW5sb2NrVmlkZW9JZCA9IG51bGw7CiAgICBsZXQgbGFzdFBsYXllclVubG9ja1JlYXNvbiA9IG51bGw7CgogICAgbGV0IGxhc3RQcm94aWVkR29vZ2xlVmlkZW9VcmxQYXJhbXM7CiAgICBsZXQgY2FjaGVkUGxheWVyUmVzcG9uc2UgPSB7fTsKCiAgICBmdW5jdGlvbiBnZXRMYXN0UHJveGllZEdvb2dsZVZpZGVvSWQoKSB7CiAgICAgICAgdmFyIF9sYXN0UHJveGllZEdvb2dsZVZpZDsKICAgICAgICByZXR1cm4gKF9sYXN0UHJveGllZEdvb2dsZVZpZCA9IGxhc3RQcm94aWVkR29vZ2xlVmlkZW9VcmxQYXJhbXMpID09PSBudWxsIHx8IF9sYXN0UHJveGllZEdvb2dsZVZpZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2xhc3RQcm94aWVkR29vZ2xlVmlkLmdldCgnaWQnKTsKICAgIH0KCiAgICBmdW5jdGlvbiB1bmxvY2tSZXNwb25zZSQxKHBsYXllclJlc3BvbnNlKSB7CiAgICAgICAgdmFyIF9wbGF5ZXJSZXNwb25zZSR2aWRlbywgX3BsYXllclJlc3BvbnNlJHBsYXlhLCBfcGxheWVyUmVzcG9uc2UkcHJldmksIF91bmxvY2tlZFBsYXllclJlc3BvbiwgX3VubG9ja2VkUGxheWVyUmVzcG9uMzsKICAgICAgICAvLyBDaGVjayBpZiB0aGUgdXNlciBoYXMgdG8gY29uZmlybSB0aGUgdW5sb2NrIGZpcnN0CiAgICAgICAgaWYgKGlzQ29uZmlybWF0aW9uUmVxdWlyZWQoKSkgewogICAgICAgICAgICBpbmZvKCdVbmxvY2sgY29uZmlybWF0aW9uIHJlcXVpcmVkLicpOwogICAgICAgICAgICByZXF1ZXN0Q29uZmlybWF0aW9uKCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGNvbnN0IHZpZGVvSWQgPSAoKF9wbGF5ZXJSZXNwb25zZSR2aWRlbyA9IHBsYXllclJlc3BvbnNlLnZpZGVvRGV0YWlscykgPT09IG51bGwgfHwgX3BsYXllclJlc3BvbnNlJHZpZGVvID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfcGxheWVyUmVzcG9uc2UkdmlkZW8udmlkZW9JZCkKICAgICAgICAgICAgfHwgZ2V0WXRjZmdWYWx1ZSgnUExBWUVSX1ZBUlMnKS52aWRlb19pZDsKICAgICAgICBjb25zdCByZWFzb24gPSAoKF9wbGF5ZXJSZXNwb25zZSRwbGF5YSA9IHBsYXllclJlc3BvbnNlLnBsYXlhYmlsaXR5U3RhdHVzKSA9PT0gbnVsbCB8fCBfcGxheWVyUmVzcG9uc2UkcGxheWEgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9wbGF5ZXJSZXNwb25zZSRwbGF5YS5zdGF0dXMpCiAgICAgICAgICAgIHx8ICgoX3BsYXllclJlc3BvbnNlJHByZXZpID0gcGxheWVyUmVzcG9uc2UucHJldmlld1BsYXlhYmlsaXR5U3RhdHVzKSA9PT0gbnVsbCB8fCBfcGxheWVyUmVzcG9uc2UkcHJldmkgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9wbGF5ZXJSZXNwb25zZSRwcmV2aS5zdGF0dXMpOwoKICAgICAgICBpZiAoIUNvbmZpZy5TS0lQX0NPTlRFTlRfV0FSTklOR1MgJiYgcmVhc29uLmluY2x1ZGVzKCdDSEVDS19SRVFVSVJFRCcpKSB7CiAgICAgICAgICAgIGluZm8oYFNLSVBfQ09OVEVOVF9XQVJOSU5HUyBkaXNhYmxlZCBhbmQgJHtyZWFzb259IHN0YXR1cyBkZXRlY3RlZC5gKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgbGFzdFBsYXllclVubG9ja1ZpZGVvSWQgPSB2aWRlb0lkOwogICAgICAgIGxhc3RQbGF5ZXJVbmxvY2tSZWFzb24gPSByZWFzb247CgogICAgICAgIGNvbnN0IHVubG9ja2VkUGxheWVyUmVzcG9uc2UgPSBnZXRVbmxvY2tlZFBsYXllclJlc3BvbnNlKHZpZGVvSWQsIHJlYXNvbik7CgogICAgICAgIC8vIGFjY291bnQgcHJveHkgZXJyb3I/CiAgICAgICAgaWYgKHVubG9ja2VkUGxheWVyUmVzcG9uc2UuZXJyb3JNZXNzYWdlKSB7CiAgICAgICAgICAgIFRvYXN0LnNob3coYCR7bWVzc2FnZXNNYXAuZmFpbH0gKFByb3h5RXJyb3IpYCwgMTApOwogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFBsYXllciBVbmxvY2sgRmFpbGVkLCBQcm94eSBFcnJvciBNZXNzYWdlOiAke3VubG9ja2VkUGxheWVyUmVzcG9uc2UuZXJyb3JNZXNzYWdlfWApOwogICAgICAgIH0KCiAgICAgICAgLy8gY2hlY2sgaWYgdGhlIHVubG9ja2VkIHJlc3BvbnNlIGlzbid0IHBsYXlhYmxlCiAgICAgICAgaWYgKAogICAgICAgICAgICAhQ29uZmlnLlZBTElEX1BMQVlBQklMSVRZX1NUQVRVU0VTLmluY2x1ZGVzKAogICAgICAgICAgICAgICAgKF91bmxvY2tlZFBsYXllclJlc3BvbiA9IHVubG9ja2VkUGxheWVyUmVzcG9uc2UucGxheWFiaWxpdHlTdGF0dXMpID09PSBudWxsIHx8IF91bmxvY2tlZFBsYXllclJlc3BvbiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX3VubG9ja2VkUGxheWVyUmVzcG9uLnN0YXR1cywKICAgICAgICAgICAgKQogICAgICAgICkgewogICAgICAgICAgICB2YXIgX3VubG9ja2VkUGxheWVyUmVzcG9uMjsKICAgICAgICAgICAgVG9hc3Quc2hvdyhgJHttZXNzYWdlc01hcC5mYWlsfSAoUGxheWFiaWxpdHlFcnJvcilgLCAxMCk7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigKICAgICAgICAgICAgICAgIGBQbGF5ZXIgVW5sb2NrIEZhaWxlZCwgcGxheWFiaWxpdHlTdGF0dXM6ICR7CiAgICAgICAgICAgICAgICAgICAgKF91bmxvY2tlZFBsYXllclJlc3BvbjIgPSB1bmxvY2tlZFBsYXllclJlc3BvbnNlLnBsYXlhYmlsaXR5U3RhdHVzKSA9PT0gbnVsbCB8fCBfdW5sb2NrZWRQbGF5ZXJSZXNwb24yID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfdW5sb2NrZWRQbGF5ZXJSZXNwb24yLnN0YXR1cwogICAgICAgICAgICAgICAgfWAsCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAvLyBpZiB0aGUgdmlkZW8gaW5mbyB3YXMgcmV0cmlldmVkIHZpYSBwcm94eSwgc3RvcmUgdGhlIFVSTCBwYXJhbXMgZnJvbSB0aGUgdXJsLWF0dHJpYnV0ZSB0byBkZXRlY3QgbGF0ZXIgaWYgdGhlIHJlcXVlc3RlZCB2aWRlbyBmaWxlIChnb29nbGV2aWRlby5jb20pIG5lZWQgYSBwcm94eS4KICAgICAgICBpZiAoCiAgICAgICAgICAgIHVubG9ja2VkUGxheWVyUmVzcG9uc2UucHJveGllZCAmJiAoX3VubG9ja2VkUGxheWVyUmVzcG9uMyA9IHVubG9ja2VkUGxheWVyUmVzcG9uc2Uuc3RyZWFtaW5nRGF0YSkgIT09IG51bGwgJiYgX3VubG9ja2VkUGxheWVyUmVzcG9uMyAhPT0gdm9pZCAwCiAgICAgICAgICAgICYmIF91bmxvY2tlZFBsYXllclJlc3BvbjMuYWRhcHRpdmVGb3JtYXRzCiAgICAgICAgKSB7CiAgICAgICAgICAgIHZhciBfdW5sb2NrZWRQbGF5ZXJSZXNwb240LCBfdW5sb2NrZWRQbGF5ZXJSZXNwb241OwogICAgICAgICAgICBjb25zdCBjaXBoZXJUZXh0ID0gKF91bmxvY2tlZFBsYXllclJlc3BvbjQgPSB1bmxvY2tlZFBsYXllclJlc3BvbnNlLnN0cmVhbWluZ0RhdGEuYWRhcHRpdmVGb3JtYXRzLmZpbmQoKHgpID0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4LnNpZ25hdHVyZUNpcGhlcgogICAgICAgICAgICAgICAgICAgICAgICApKSA9PT0gbnVsbCB8fCBfdW5sb2NrZWRQbGF5ZXJSZXNwb240ID09PSB2b2lkIDAKICAgICAgICAgICAgICAgID8gdm9pZCAwCiAgICAgICAgICAgICAgICA6IF91bmxvY2tlZFBsYXllclJlc3BvbjQuc2lnbmF0dXJlQ2lwaGVyOwogICAgICAgICAgICBjb25zdCB2aWRlb1VybCA9IGNpcGhlclRleHQKICAgICAgICAgICAgICAgID8gbmV3IFVSTFNlYXJjaFBhcmFtcyhjaXBoZXJUZXh0KS5nZXQoJ3VybCcpCiAgICAgICAgICAgICAgICA6IChfdW5sb2NrZWRQbGF5ZXJSZXNwb241ID0gdW5sb2NrZWRQbGF5ZXJSZXNwb25zZS5zdHJlYW1pbmdEYXRhLmFkYXB0aXZlRm9ybWF0cy5maW5kKCh4KSA9PiB4LnVybCkpID09PSBudWxsIHx8IF91bmxvY2tlZFBsYXllclJlc3BvbjUgPT09IHZvaWQgMAogICAgICAgICAgICAgICAgPyB2b2lkIDAKICAgICAgICAgICAgICAgIDogX3VubG9ja2VkUGxheWVyUmVzcG9uNS51cmw7CgogICAgICAgICAgICBsYXN0UHJveGllZEdvb2dsZVZpZGVvVXJsUGFyYW1zID0gdmlkZW9VcmwgPyBuZXcgVVJMU2VhcmNoUGFyYW1zKG5ldyB3aW5kb3cuVVJMKHZpZGVvVXJsKS5zZWFyY2gpIDogbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vIE92ZXJ3cml0ZSB0aGUgZW1iZWRkZWQgKHByZXZpZXcpIHBsYXlhYmlsaXR5U3RhdHVzIHdpdGggdGhlIHVubG9ja2VkIG9uZQogICAgICAgIGlmIChwbGF5ZXJSZXNwb25zZS5wcmV2aWV3UGxheWFiaWxpdHlTdGF0dXMpIHsKICAgICAgICAgICAgcGxheWVyUmVzcG9uc2UucHJldmlld1BsYXlhYmlsaXR5U3RhdHVzID0gdW5sb2NrZWRQbGF5ZXJSZXNwb25zZS5wbGF5YWJpbGl0eVN0YXR1czsKICAgICAgICB9CgogICAgICAgIC8vIFRyYW5zZmVyIGFsbCB1bmxvY2tlZCBwcm9wZXJ0aWVzIHRvIHRoZSBvcmlnaW5hbCBwbGF5ZXIgcmVzcG9uc2UKICAgICAgICBPYmplY3QuYXNzaWduKHBsYXllclJlc3BvbnNlLCB1bmxvY2tlZFBsYXllclJlc3BvbnNlKTsKCiAgICAgICAgcGxheWVyUmVzcG9uc2UudW5sb2NrZWQgPSB0cnVlOwoKICAgICAgICBUb2FzdC5zaG93KG1lc3NhZ2VzTWFwLnN1Y2Nlc3MpOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldFVubG9ja2VkUGxheWVyUmVzcG9uc2UodmlkZW9JZCwgcmVhc29uKSB7CiAgICAgICAgLy8gQ2hlY2sgaWYgcmVzcG9uc2UgaXMgY2FjaGVkCiAgICAgICAgaWYgKGNhY2hlZFBsYXllclJlc3BvbnNlLnZpZGVvSWQgPT09IHZpZGVvSWQpIHJldHVybiBjcmVhdGVEZWVwQ29weShjYWNoZWRQbGF5ZXJSZXNwb25zZSk7CgogICAgICAgIGNvbnN0IHVubG9ja1N0cmF0ZWdpZXMgPSBnZXRVbmxvY2tTdHJhdGVnaWVzKHZpZGVvSWQsIHJlYXNvbik7CgogICAgICAgIGxldCB1bmxvY2tlZFBsYXllclJlc3BvbnNlID0ge307CgogICAgICAgIC8vIFRyeSBldmVyeSBzdHJhdGVneSB1bnRpbCBvbmUgb2YgdGhlbSB3b3JrcwogICAgICAgIHVubG9ja1N0cmF0ZWdpZXMuZXZlcnkoKHN0cmF0ZWd5LCBpbmRleCkgPT4gewogICAgICAgICAgICB2YXIgX3VubG9ja2VkUGxheWVyUmVzcG9uNjsKICAgICAgICAgICAgLy8gU2tpcCBzdHJhdGVneSBpZiBhdXRoZW50aWNhdGlvbiBpcyByZXF1aXJlZCBhbmQgdGhlIHVzZXIgaXMgbm90IGxvZ2dlZCBpbgogICAgICAgICAgICBpZiAoc3RyYXRlZ3kuc2tpcCB8fCBzdHJhdGVneS5yZXF1aXJlc0F1dGggJiYgIWlzVXNlckxvZ2dlZEluKCkpIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgaW5mbyhgVHJ5aW5nIFBsYXllciBVbmxvY2sgTWV0aG9kICMke2luZGV4ICsgMX0gKCR7c3RyYXRlZ3kubmFtZX0pYCk7CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdW5sb2NrZWRQbGF5ZXJSZXNwb25zZSA9IHN0cmF0ZWd5LmVuZHBvaW50LmdldFBsYXllcihzdHJhdGVneS5wYXlsb2FkLCBzdHJhdGVneS5yZXF1aXJlc0F1dGggfHwgc3RyYXRlZ3kub3B0aW9uYWxBdXRoKTsKICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICBlcnJvcihlcnIsIGBQbGF5ZXIgVW5sb2NrIE1ldGhvZCAke2luZGV4ICsgMX0gZmFpbGVkIHdpdGggZXhjZXB0aW9uYCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnN0IGlzU3RhdHVzVmFsaWQgPSBDb25maWcuVkFMSURfUExBWUFCSUxJVFlfU1RBVFVTRVMuaW5jbHVkZXMoCiAgICAgICAgICAgICAgICAoX3VubG9ja2VkUGxheWVyUmVzcG9uNiA9IHVubG9ja2VkUGxheWVyUmVzcG9uc2UpID09PSBudWxsIHx8IF91bmxvY2tlZFBsYXllclJlc3BvbjYgPT09IHZvaWQgMAogICAgICAgICAgICAgICAgICAgIHx8IChfdW5sb2NrZWRQbGF5ZXJSZXNwb242ID0gX3VubG9ja2VkUGxheWVyUmVzcG9uNi5wbGF5YWJpbGl0eVN0YXR1cykgPT09IG51bGwgfHwgX3VubG9ja2VkUGxheWVyUmVzcG9uNiA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICAgICAgPyB2b2lkIDAKICAgICAgICAgICAgICAgICAgICA6IF91bmxvY2tlZFBsYXllclJlc3BvbjYuc3RhdHVzLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgaWYgKGlzU3RhdHVzVmFsaWQpIHsKICAgICAgICAgICAgICAgIHZhciBfdW5sb2NrZWRQbGF5ZXJSZXNwb243OwogICAgICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAgICAgKiBXb3JrYXJvdW5kOiBodHRwczovL2dpdGh1Yi5jb20vemVyb2R5dHJhc2gvU2ltcGxlLVlvdVR1YmUtQWdlLVJlc3RyaWN0aW9uLUJ5cGFzcy9pc3N1ZXMvMTkxCiAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICogWW91VHViZSBjaGVja3MgaWYgdGhlIGB0cmFja2luZ1BhcmFtc2AgaW4gdGhlIHJlc3BvbnNlIG1hdGNoZXMgdGhlIGRlY29kZWQgYHRyYWNraW5nUGFyYW1gIGluIGByZXNwb25zZUNvbnRleHQubWFpbkFwcFdlYlJlc3BvbnNlQ29udGV4dGAuCiAgICAgICAgICAgICAgICAgKiBIb3dldmVyLCBzb21ldGltZXMgdGhlIHJlc3BvbnNlIGRvZXMgbm90IGluY2x1ZGUgdGhlIGB0cmFja2luZ1BhcmFtYCBpbiB0aGUgYHJlc3BvbnNlQ29udGV4dGAsIGNhdXNpbmcgdGhlIGNoZWNrIHRvIGZhaWwuCiAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICogVGhpcyB3b3JrYXJvdW5kIGFkZHJlc3NlcyB0aGUgaXNzdWUgYnkgaGFyZGNvZGluZyB0aGUgYHRyYWNraW5nUGFyYW1zYCBpbiB0aGUgcmVzcG9uc2UgY29udGV4dC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICF1bmxvY2tlZFBsYXllclJlc3BvbnNlLnRyYWNraW5nUGFyYW1zCiAgICAgICAgICAgICAgICAgICAgfHwgISgoX3VubG9ja2VkUGxheWVyUmVzcG9uNyA9IHVubG9ja2VkUGxheWVyUmVzcG9uc2UucmVzcG9uc2VDb250ZXh0KSAhPT0gbnVsbCAmJiBfdW5sb2NrZWRQbGF5ZXJSZXNwb243ICE9PSB2b2lkIDAKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKF91bmxvY2tlZFBsYXllclJlc3BvbjcgPSBfdW5sb2NrZWRQbGF5ZXJSZXNwb243Lm1haW5BcHBXZWJSZXNwb25zZUNvbnRleHQpICE9PSBudWxsICYmIF91bmxvY2tlZFBsYXllclJlc3BvbjcgIT09IHZvaWQgMAogICAgICAgICAgICAgICAgICAgICAgICAmJiBfdW5sb2NrZWRQbGF5ZXJSZXNwb243LnRyYWNraW5nUGFyYW0pCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICB1bmxvY2tlZFBsYXllclJlc3BvbnNlLnRyYWNraW5nUGFyYW1zID0gJ0NBQVF1MmtpRXdqb3I4dUh5T0xfQWhXT3ZkNEtIYXZYQ0t3PSc7CiAgICAgICAgICAgICAgICAgICAgdW5sb2NrZWRQbGF5ZXJSZXNwb25zZS5yZXNwb25zZUNvbnRleHQgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1haW5BcHBXZWJSZXNwb25zZUNvbnRleHQ6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNraW5nUGFyYW06ICdreF9mbVB4aG9QWlJ6Z0w4a3pPd0FOVWRRaDhad0hUUkVrdzJVcW1CQXdwQllyelJna3VNc05MQndPY0NFNTlURHRzbExLUFEtU1MnLAogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAgICAgKiBXb3JrYXJvdW5kOiBBY2NvdW50IHByb3h5IHJlc3BvbnNlIGN1cnJlbnRseSBkb2VzIG5vdCBpbmNsdWRlIGBwbGF5ZXJDb25maWdgCiAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICogU3RheXMgaGVyZSB1bnRpbCB3ZSByZXdyaXRlIHRoZSBhY2NvdW50IHByb3h5IHRvIG9ubHkgaW5jbHVkZSB0aGUgbmVjZXNzYXJ5IGFuZCBiYXJlIG1pbmltdW0gcmVzcG9uc2UKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKHN0cmF0ZWd5LnBheWxvYWQuc3RhcnRUaW1lU2VjcyAmJiBzdHJhdGVneS5uYW1lID09PSAnQWNjb3VudCBQcm94eScpIHsKICAgICAgICAgICAgICAgICAgICB1bmxvY2tlZFBsYXllclJlc3BvbnNlLnBsYXllckNvbmZpZyA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgcGxheWJhY2tTdGFydENvbmZpZzogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRTZWNvbmRzOiBzdHJhdGVneS5wYXlsb2FkLnN0YXJ0VGltZVNlY3MsCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICFpc1N0YXR1c1ZhbGlkOwogICAgICAgIH0pOwoKICAgICAgICAvLyBDYWNoZSByZXNwb25zZSB0byBwcmV2ZW50IGEgZmxvb2Qgb2YgcmVxdWVzdHMgaW4gY2FzZSB5b3V0dWJlIHByb2Nlc3NlcyBhIGJsb2NrZWQgcmVzcG9uc2UgbXV0aXBsZSB0aW1lcy4KICAgICAgICBjYWNoZWRQbGF5ZXJSZXNwb25zZSA9IHsgdmlkZW9JZCwgLi4uY3JlYXRlRGVlcENvcHkodW5sb2NrZWRQbGF5ZXJSZXNwb25zZSkgfTsKCiAgICAgICAgcmV0dXJuIHVubG9ja2VkUGxheWVyUmVzcG9uc2U7CiAgICB9CgogICAgbGV0IGNhY2hlZE5leHRSZXNwb25zZSA9IHt9OwoKICAgIGZ1bmN0aW9uIHVubG9ja1Jlc3BvbnNlKG9yaWdpbmFsTmV4dFJlc3BvbnNlKSB7CiAgICAgICAgY29uc3QgdmlkZW9JZCA9IG9yaWdpbmFsTmV4dFJlc3BvbnNlLmN1cnJlbnRWaWRlb0VuZHBvaW50LndhdGNoRW5kcG9pbnQudmlkZW9JZDsKCiAgICAgICAgaWYgKCF2aWRlb0lkKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyB2aWRlb0lkIGluIG5leHRSZXNwb25zZWApOwogICAgICAgIH0KCiAgICAgICAgLy8gT25seSB1bmxvY2sgdGhlIC9uZXh0IHJlc3BvbnNlIHdoZW4gdGhlIHBsYXllciBoYXMgYmVlbiB1bmxvY2tlZCBhcyB3ZWxsCiAgICAgICAgaWYgKHZpZGVvSWQgIT09IGxhc3RQbGF5ZXJVbmxvY2tWaWRlb0lkKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGNvbnN0IHVubG9ja2VkTmV4dFJlc3BvbnNlID0gZ2V0VW5sb2NrZWROZXh0UmVzcG9uc2UodmlkZW9JZCk7CgogICAgICAgIC8vIGNoZWNrIGlmIHRoZSBzaWRlYmFyIG9mIHRoZSB1bmxvY2tlZCByZXNwb25zZSBpcyBzdGlsbCBlbXB0eQogICAgICAgIGlmIChpc1dhdGNoTmV4dFNpZGViYXJFbXB0eSh1bmxvY2tlZE5leHRSZXNwb25zZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTaWRlYmFyIFVubG9jayBGYWlsZWRgKTsKICAgICAgICB9CgogICAgICAgIC8vIFRyYW5zZmVyIHNvbWUgcGFydHMgb2YgdGhlIHVubG9ja2VkIHJlc3BvbnNlIHRvIHRoZSBvcmlnaW5hbCByZXNwb25zZQogICAgICAgIG1lcmdlTmV4dFJlc3BvbnNlKG9yaWdpbmFsTmV4dFJlc3BvbnNlLCB1bmxvY2tlZE5leHRSZXNwb25zZSk7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0VW5sb2NrZWROZXh0UmVzcG9uc2UodmlkZW9JZCkgewogICAgICAgIC8vIENoZWNrIGlmIHJlc3BvbnNlIGlzIGNhY2hlZAogICAgICAgIGlmIChjYWNoZWROZXh0UmVzcG9uc2UudmlkZW9JZCA9PT0gdmlkZW9JZCkgcmV0dXJuIGNyZWF0ZURlZXBDb3B5KGNhY2hlZE5leHRSZXNwb25zZSk7CgogICAgICAgIGNvbnN0IHVubG9ja1N0cmF0ZWdpZXMgPSBnZXRVbmxvY2tTdHJhdGVnaWVzJDEodmlkZW9JZCwgbGFzdFBsYXllclVubG9ja1JlYXNvbik7CgogICAgICAgIGxldCB1bmxvY2tlZE5leHRSZXNwb25zZSA9IHt9OwoKICAgICAgICAvLyBUcnkgZXZlcnkgc3RyYXRlZ3kgdW50aWwgb25lIG9mIHRoZW0gd29ya3MKICAgICAgICB1bmxvY2tTdHJhdGVnaWVzLmV2ZXJ5KChzdHJhdGVneSwgaW5kZXgpID0+IHsKICAgICAgICAgICAgaWYgKHN0cmF0ZWd5LnNraXApIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgaW5mbyhgVHJ5aW5nIE5leHQgVW5sb2NrIE1ldGhvZCAjJHtpbmRleCArIDF9ICgke3N0cmF0ZWd5Lm5hbWV9KWApOwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHVubG9ja2VkTmV4dFJlc3BvbnNlID0gc3RyYXRlZ3kuZW5kcG9pbnQuZ2V0TmV4dChzdHJhdGVneS5wYXlsb2FkLCBzdHJhdGVneS5vcHRpb25hbEF1dGgpOwogICAgICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgICAgICAgIGVycm9yKGVyciwgYE5leHQgVW5sb2NrIE1ldGhvZCAke2luZGV4ICsgMX0gZmFpbGVkIHdpdGggZXhjZXB0aW9uYCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBpc1dhdGNoTmV4dFNpZGViYXJFbXB0eSh1bmxvY2tlZE5leHRSZXNwb25zZSk7CiAgICAgICAgfSk7CgogICAgICAgIC8vIENhY2hlIHJlc3BvbnNlIHRvIHByZXZlbnQgYSBmbG9vZCBvZiByZXF1ZXN0cyBpbiBjYXNlIHlvdXR1YmUgcHJvY2Vzc2VzIGEgYmxvY2tlZCByZXNwb25zZSBtdXRpcGxlIHRpbWVzLgogICAgICAgIGNhY2hlZE5leHRSZXNwb25zZSA9IHsgdmlkZW9JZCwgLi4uY3JlYXRlRGVlcENvcHkodW5sb2NrZWROZXh0UmVzcG9uc2UpIH07CgogICAgICAgIHJldHVybiB1bmxvY2tlZE5leHRSZXNwb25zZTsKICAgIH0KCiAgICBmdW5jdGlvbiBtZXJnZU5leHRSZXNwb25zZShvcmlnaW5hbE5leHRSZXNwb25zZSwgdW5sb2NrZWROZXh0UmVzcG9uc2UpIHsKICAgICAgICB2YXIgX3VubG9ja2VkTmV4dFJlc3BvbnNlOwogICAgICAgIGlmIChpc0Rlc2t0b3ApIHsKICAgICAgICAgICAgLy8gVHJhbnNmZXIgV2F0Y2hOZXh0UmVzdWx0cyB0byBvcmlnaW5hbCByZXNwb25zZQogICAgICAgICAgICBvcmlnaW5hbE5leHRSZXNwb25zZS5jb250ZW50cy50d29Db2x1bW5XYXRjaE5leHRSZXN1bHRzLnNlY29uZGFyeVJlc3VsdHMgPSB1bmxvY2tlZE5leHRSZXNwb25zZS5jb250ZW50cy50d29Db2x1bW5XYXRjaE5leHRSZXN1bHRzLnNlY29uZGFyeVJlc3VsdHM7CgogICAgICAgICAgICAvLyBUcmFuc2ZlciB2aWRlbyBkZXNjcmlwdGlvbiB0byBvcmlnaW5hbCByZXNwb25zZQogICAgICAgICAgICBjb25zdCBvcmlnaW5hbFZpZGVvU2Vjb25kYXJ5SW5mb1JlbmRlcmVyID0gb3JpZ2luYWxOZXh0UmVzcG9uc2UuY29udGVudHMudHdvQ29sdW1uV2F0Y2hOZXh0UmVzdWx0cy5yZXN1bHRzLnJlc3VsdHMuY29udGVudHMuZmluZCgKICAgICAgICAgICAgICAgICh4KSA9PiB4LnZpZGVvU2Vjb25kYXJ5SW5mb1JlbmRlcmVyLAogICAgICAgICAgICApLnZpZGVvU2Vjb25kYXJ5SW5mb1JlbmRlcmVyOwogICAgICAgICAgICBjb25zdCB1bmxvY2tlZFZpZGVvU2Vjb25kYXJ5SW5mb1JlbmRlcmVyID0gdW5sb2NrZWROZXh0UmVzcG9uc2UuY29udGVudHMudHdvQ29sdW1uV2F0Y2hOZXh0UmVzdWx0cy5yZXN1bHRzLnJlc3VsdHMuY29udGVudHMuZmluZCgKICAgICAgICAgICAgICAgICh4KSA9PiB4LnZpZGVvU2Vjb25kYXJ5SW5mb1JlbmRlcmVyLAogICAgICAgICAgICApLnZpZGVvU2Vjb25kYXJ5SW5mb1JlbmRlcmVyOwoKICAgICAgICAgICAgLy8gVE9ETzogVGhyb3cgaWYgZGVzY3JpcHRpb24gbm90IGZvdW5kPwogICAgICAgICAgICBpZiAodW5sb2NrZWRWaWRlb1NlY29uZGFyeUluZm9SZW5kZXJlci5kZXNjcmlwdGlvbikgewogICAgICAgICAgICAgICAgb3JpZ2luYWxWaWRlb1NlY29uZGFyeUluZm9SZW5kZXJlci5kZXNjcmlwdGlvbiA9IHVubG9ja2VkVmlkZW9TZWNvbmRhcnlJbmZvUmVuZGVyZXIuZGVzY3JpcHRpb247CiAgICAgICAgICAgIH0gZWxzZSBpZiAodW5sb2NrZWRWaWRlb1NlY29uZGFyeUluZm9SZW5kZXJlci5hdHRyaWJ1dGVkRGVzY3JpcHRpb24pIHsKICAgICAgICAgICAgICAgIG9yaWdpbmFsVmlkZW9TZWNvbmRhcnlJbmZvUmVuZGVyZXIuYXR0cmlidXRlZERlc2NyaXB0aW9uID0gdW5sb2NrZWRWaWRlb1NlY29uZGFyeUluZm9SZW5kZXJlci5hdHRyaWJ1dGVkRGVzY3JpcHRpb247CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIFRyYW5zZmVyIFdhdGNoTmV4dFJlc3VsdHMgdG8gb3JpZ2luYWwgcmVzcG9uc2UKICAgICAgICBjb25zdCB1bmxvY2tlZFdhdGNoTmV4dEZlZWQgPSAoX3VubG9ja2VkTmV4dFJlc3BvbnNlID0gdW5sb2NrZWROZXh0UmVzcG9uc2UuY29udGVudHMpID09PSBudWxsIHx8IF91bmxvY2tlZE5leHRSZXNwb25zZSA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICB8fCAoX3VubG9ja2VkTmV4dFJlc3BvbnNlID0gX3VubG9ja2VkTmV4dFJlc3BvbnNlLnNpbmdsZUNvbHVtbldhdGNoTmV4dFJlc3VsdHMpID09PSBudWxsIHx8IF91bmxvY2tlZE5leHRSZXNwb25zZSA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICB8fCAoX3VubG9ja2VkTmV4dFJlc3BvbnNlID0gX3VubG9ja2VkTmV4dFJlc3BvbnNlLnJlc3VsdHMpID09PSBudWxsIHx8IF91bmxvY2tlZE5leHRSZXNwb25zZSA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICB8fCAoX3VubG9ja2VkTmV4dFJlc3BvbnNlID0gX3VubG9ja2VkTmV4dFJlc3BvbnNlLnJlc3VsdHMpID09PSBudWxsIHx8IF91bmxvY2tlZE5leHRSZXNwb25zZSA9PT0gdm9pZCAwCiAgICAgICAgICAgICAgICB8fCAoX3VubG9ja2VkTmV4dFJlc3BvbnNlID0gX3VubG9ja2VkTmV4dFJlc3BvbnNlLmNvbnRlbnRzKSA9PT0gbnVsbCB8fCBfdW5sb2NrZWROZXh0UmVzcG9uc2UgPT09IHZvaWQgMAogICAgICAgICAgICA/IHZvaWQgMAogICAgICAgICAgICA6IF91bmxvY2tlZE5leHRSZXNwb25zZS5maW5kKAogICAgICAgICAgICAgICAgKHgpID0+IHsKICAgICAgICAgICAgICAgICAgICB2YXIgX3gkaXRlbVNlY3Rpb25SZW5kZXJlOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAoKF94JGl0ZW1TZWN0aW9uUmVuZGVyZSA9IHguaXRlbVNlY3Rpb25SZW5kZXJlcikgPT09IG51bGwgfHwgX3gkaXRlbVNlY3Rpb25SZW5kZXJlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfeCRpdGVtU2VjdGlvblJlbmRlcmUudGFyZ2V0SWQpCiAgICAgICAgICAgICAgICAgICAgICAgID09PSAnd2F0Y2gtbmV4dC1mZWVkJzsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICk7CgogICAgICAgIGlmICh1bmxvY2tlZFdhdGNoTmV4dEZlZWQpIG9yaWdpbmFsTmV4dFJlc3BvbnNlLmNvbnRlbnRzLnNpbmdsZUNvbHVtbldhdGNoTmV4dFJlc3VsdHMucmVzdWx0cy5yZXN1bHRzLmNvbnRlbnRzLnB1c2godW5sb2NrZWRXYXRjaE5leHRGZWVkKTsKCiAgICAgICAgLy8gVHJhbnNmZXIgdmlkZW8gZGVzY3JpcHRpb24gdG8gb3JpZ2luYWwgcmVzcG9uc2UKICAgICAgICBjb25zdCBvcmlnaW5hbFN0cnVjdHVyZWREZXNjcmlwdGlvbkNvbnRlbnRSZW5kZXJlciA9IG9yaWdpbmFsTmV4dFJlc3BvbnNlLmVuZ2FnZW1lbnRQYW5lbHMKICAgICAgICAgICAgLmZpbmQoKHgpID0+IHguZW5nYWdlbWVudFBhbmVsU2VjdGlvbkxpc3RSZW5kZXJlcikKICAgICAgICAgICAgLmVuZ2FnZW1lbnRQYW5lbFNlY3Rpb25MaXN0UmVuZGVyZXIuY29udGVudC5zdHJ1Y3R1cmVkRGVzY3JpcHRpb25Db250ZW50UmVuZGVyZXIuaXRlbXMuZmluZCgoeCkgPT4geC5leHBhbmRhYmxlVmlkZW9EZXNjcmlwdGlvbkJvZHlSZW5kZXJlcik7CiAgICAgICAgY29uc3QgdW5sb2NrZWRTdHJ1Y3R1cmVkRGVzY3JpcHRpb25Db250ZW50UmVuZGVyZXIgPSB1bmxvY2tlZE5leHRSZXNwb25zZS5lbmdhZ2VtZW50UGFuZWxzCiAgICAgICAgICAgIC5maW5kKCh4KSA9PiB4LmVuZ2FnZW1lbnRQYW5lbFNlY3Rpb25MaXN0UmVuZGVyZXIpCiAgICAgICAgICAgIC5lbmdhZ2VtZW50UGFuZWxTZWN0aW9uTGlzdFJlbmRlcmVyLmNvbnRlbnQuc3RydWN0dXJlZERlc2NyaXB0aW9uQ29udGVudFJlbmRlcmVyLml0ZW1zLmZpbmQoKHgpID0+IHguZXhwYW5kYWJsZVZpZGVvRGVzY3JpcHRpb25Cb2R5UmVuZGVyZXIpOwoKICAgICAgICBpZiAodW5sb2NrZWRTdHJ1Y3R1cmVkRGVzY3JpcHRpb25Db250ZW50UmVuZGVyZXIuZXhwYW5kYWJsZVZpZGVvRGVzY3JpcHRpb25Cb2R5UmVuZGVyZXIpIHsKICAgICAgICAgICAgb3JpZ2luYWxTdHJ1Y3R1cmVkRGVzY3JpcHRpb25Db250ZW50UmVuZGVyZXIuZXhwYW5kYWJsZVZpZGVvRGVzY3JpcHRpb25Cb2R5UmVuZGVyZXIgPQogICAgICAgICAgICAgICAgdW5sb2NrZWRTdHJ1Y3R1cmVkRGVzY3JpcHRpb25Db250ZW50UmVuZGVyZXIuZXhwYW5kYWJsZVZpZGVvRGVzY3JpcHRpb25Cb2R5UmVuZGVyZXI7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogIEhhbmRsZXMgWE1MSHR0cFJlcXVlc3RzIGFuZAogICAgICogLSBSZXdyaXRlIEdvb2dsZXZpZGVvIFVSTHMgdG8gUHJveHkgVVJMcyAoaWYgbmVjZXNzYXJ5KQogICAgICogLSBTdG9yZSBhdXRoIGhlYWRlcnMgZm9yIHRoZSBhdXRoZW50aWNhdGlvbiBvZiBmdXJ0aGVyIHVubG9jayByZXF1ZXN0cy4KICAgICAqIC0gQWRkICJjb250ZW50IGNoZWNrIG9rIiBmbGFncyB0byByZXF1ZXN0IGJvZHlzCiAgICAgKi8KICAgIGZ1bmN0aW9uIGhhbmRsZVhock9wZW4obWV0aG9kLCB1cmwsIHhocikgewogICAgICAgIGxldCBwcm94eVVybCA9IHVubG9ja0dvb2dsZVZpZGVvKHVybCk7CiAgICAgICAgaWYgKHByb3h5VXJsKSB7CiAgICAgICAgICAgIC8vIEV4Y2x1ZGUgY3JlZGVudGlhbHMgZnJvbSBYTUxIdHRwUmVxdWVzdAogICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoeGhyLCAnd2l0aENyZWRlbnRpYWxzJywgewogICAgICAgICAgICAgICAgc2V0OiAoKSA9PiB7fSwKICAgICAgICAgICAgICAgIGdldDogKCkgPT4gZmFsc2UsCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICByZXR1cm4gcHJveHlVcmw7CiAgICAgICAgfQoKICAgICAgICBpZiAodXJsLnBhdGhuYW1lLmluZGV4T2YoJy95b3V0dWJlaS8nKSA9PT0gMCkgewogICAgICAgICAgICAvLyBTdG9yZSBhdXRoIGhlYWRlcnMgaW4gc3RvcmFnZSBmb3IgZnVydGhlciB1c2FnZS4KICAgICAgICAgICAgYXR0YWNoJDQoeGhyLCAnc2V0UmVxdWVzdEhlYWRlcicsIChbaGVhZGVyTmFtZSwgaGVhZGVyVmFsdWVdKSA9PiB7CiAgICAgICAgICAgICAgICBpZiAoQ29uZmlnLkdPT0dMRV9BVVRIX0hFQURFUl9OQU1FUy5pbmNsdWRlcyhoZWFkZXJOYW1lKSkgewogICAgICAgICAgICAgICAgICAgIHNldChoZWFkZXJOYW1lLCBoZWFkZXJWYWx1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgaWYgKENvbmZpZy5TS0lQX0NPTlRFTlRfV0FSTklOR1MgJiYgbWV0aG9kID09PSAnUE9TVCcgJiYgWycveW91dHViZWkvdjEvcGxheWVyJywgJy95b3V0dWJlaS92MS9uZXh0J10uaW5jbHVkZXModXJsLnBhdGhuYW1lKSkgewogICAgICAgICAgICAvLyBBZGQgY29udGVudCBjaGVjayBmbGFncyB0byBwbGF5ZXIgYW5kIG5leHQgcmVxdWVzdCAodGhpcyB3aWxsIHNraXAgY29udGVudCB3YXJuaW5ncykKICAgICAgICAgICAgYXR0YWNoJDQoeGhyLCAnc2VuZCcsIChhcmdzKSA9PiB7CiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFyZ3NbMF0gPT09ICdzdHJpbmcnKSB7CiAgICAgICAgICAgICAgICAgICAgYXJnc1swXSA9IHNldENvbnRlbnRDaGVja09rKGFyZ3NbMF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiAgSGFuZGxlcyBGZXRjaCByZXF1ZXN0cyBhbmQKICAgICAqIC0gUmV3cml0ZSBHb29nbGV2aWRlbyBVUkxzIHRvIFByb3h5IFVSTHMgKGlmIG5lY2Vzc2FyeSkKICAgICAqIC0gU3RvcmUgYXV0aCBoZWFkZXJzIGZvciB0aGUgYXV0aGVudGljYXRpb24gb2YgZnVydGhlciB1bmxvY2sgcmVxdWVzdHMuCiAgICAgKiAtIEFkZCAiY29udGVudCBjaGVjayBvayIgZmxhZ3MgdG8gcmVxdWVzdCBib2R5cwogICAgICovCiAgICBmdW5jdGlvbiBoYW5kbGVGZXRjaFJlcXVlc3QodXJsLCByZXF1ZXN0T3B0aW9ucykgewogICAgICAgIGxldCBuZXdHb29nbGVWaWRlb1VybCA9IHVubG9ja0dvb2dsZVZpZGVvKHVybCk7CiAgICAgICAgaWYgKG5ld0dvb2dsZVZpZGVvVXJsKSB7CiAgICAgICAgICAgIC8vIEV4Y2x1ZGUgY3JlZGVudGlhbHMgZnJvbSBGZXRjaCBSZXF1ZXN0CiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5jcmVkZW50aWFscykgewogICAgICAgICAgICAgICAgcmVxdWVzdE9wdGlvbnMuY3JlZGVudGlhbHMgPSAnb21pdCc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ld0dvb2dsZVZpZGVvVXJsOwogICAgICAgIH0KCiAgICAgICAgaWYgKHVybC5wYXRobmFtZS5pbmRleE9mKCcveW91dHViZWkvJykgPT09IDAgJiYgaXNPYmplY3QocmVxdWVzdE9wdGlvbnMuaGVhZGVycykpIHsKICAgICAgICAgICAgLy8gU3RvcmUgYXV0aCBoZWFkZXJzIGluIGF1dGhTdG9yYWdlIGZvciBmdXJ0aGVyIHVzYWdlLgogICAgICAgICAgICBmb3IgKGxldCBoZWFkZXJOYW1lIGluIHJlcXVlc3RPcHRpb25zLmhlYWRlcnMpIHsKICAgICAgICAgICAgICAgIGlmIChDb25maWcuR09PR0xFX0FVVEhfSEVBREVSX05BTUVTLmluY2x1ZGVzKGhlYWRlck5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgc2V0KGhlYWRlck5hbWUsIHJlcXVlc3RPcHRpb25zLmhlYWRlcnNbaGVhZGVyTmFtZV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoQ29uZmlnLlNLSVBfQ09OVEVOVF9XQVJOSU5HUyAmJiBbJy95b3V0dWJlaS92MS9wbGF5ZXInLCAnL3lvdXR1YmVpL3YxL25leHQnXS5pbmNsdWRlcyh1cmwucGF0aG5hbWUpKSB7CiAgICAgICAgICAgIC8vIEFkZCBjb250ZW50IGNoZWNrIGZsYWdzIHRvIHBsYXllciBhbmQgbmV4dCByZXF1ZXN0ICh0aGlzIHdpbGwgc2tpcCBjb250ZW50IHdhcm5pbmdzKQogICAgICAgICAgICByZXF1ZXN0T3B0aW9ucy5ib2R5ID0gc2V0Q29udGVudENoZWNrT2socmVxdWVzdE9wdGlvbnMuYm9keSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSWYgdGhlIGFjY291bnQgcHJveHkgd2FzIHVzZWQgdG8gcmV0cmlldmUgdGhlIHZpZGVvIGluZm8sIHRoZSBmb2xsb3dpbmcgYXBwbGllczoKICAgICAqIHNvbWUgdmlkZW8gZmlsZXMgKG1vc3RseSBtdXNpYyB2aWRlb3MpIGNhbiBvbmx5IGJlIGFjY2Vzc2VkIGZyb20gSVBzIGluIHRoZSBzYW1lIGNvdW50cnkgYXMgdGhlIGlubmVydHViZSBhcGkgcmVxdWVzdCAoL3lvdXR1YmVpL3YxL3BsYXllcikgd2FzIG1hZGUuCiAgICAgKiB0byBnZXQgYXJvdW5kIHRoaXMsIHRoZSBnb29nbGV2aWRlbyBVUkwgd2lsbCBiZSByZXBsYWNlZCB3aXRoIGEgd2ViLXByb3h5IFVSTCBpbiB0aGUgc2FtZSBjb3VudHJ5IChVUykuCiAgICAgKiB0aGlzIGlzIG9ubHkgcmVxdWlyZWQgaWYgdGhlICJnY3I9W2NvdW50cnljb2RlXSIgZmxhZyBpcyBzZXQgaW4gdGhlIGdvb2dsZXZpZGVvLXVybC4uLgogICAgICogQHJldHVybnMgVGhlIHJld2l0dGVuIHVybCAoaWYgYSBwcm94eSBpcyByZXF1aXJlZCkKICAgICAqLwogICAgZnVuY3Rpb24gdW5sb2NrR29vZ2xlVmlkZW8odXJsKSB7CiAgICAgICAgaWYgKENvbmZpZy5WSURFT19QUk9YWV9TRVJWRVJfSE9TVCAmJiBpc0dvb2dsZVZpZGVvVXJsKHVybCkpIHsKICAgICAgICAgICAgaWYgKGlzR29vZ2xlVmlkZW9VbmxvY2tSZXF1aXJlZCh1cmwsIGdldExhc3RQcm94aWVkR29vZ2xlVmlkZW9JZCgpKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHByb3h5LmdldEdvb2dsZVZpZGVvVXJsKHVybCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGBjb250ZW50Q2hlY2tPa2AgYW5kIGByYWN5Q2hlY2tPa2AgdG8gdGhlIGdpdmVuIGpzb24gZGF0YSAoaWYgdGhlIGRhdGEgY29udGFpbnMgYSB2aWRlbyBpZCkKICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBtb2RpZmllZCBqc29uCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNldENvbnRlbnRDaGVja09rKGJvZHlKc29uKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgbGV0IHBhcnNlZEJvZHkgPSBKU09OLnBhcnNlKGJvZHlKc29uKTsKICAgICAgICAgICAgaWYgKHBhcnNlZEJvZHkudmlkZW9JZCkgewogICAgICAgICAgICAgICAgcGFyc2VkQm9keS5jb250ZW50Q2hlY2tPayA9IHRydWU7CiAgICAgICAgICAgICAgICBwYXJzZWRCb2R5LnJhY3lDaGVja09rID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShwYXJzZWRCb2R5KTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2gge30KICAgICAgICByZXR1cm4gYm9keUpzb247CiAgICB9CgogICAgZnVuY3Rpb24gcHJvY2Vzc1RodW1ibmFpbHMocmVzcG9uc2VPYmplY3QpIHsKICAgICAgICBjb25zdCB0aHVtYm5haWxzID0gZmluZE5lc3RlZE9iamVjdHNCeUF0dHJpYnV0ZU5hbWVzKHJlc3BvbnNlT2JqZWN0LCBbJ3VybCcsICdoZWlnaHQnXSk7CgogICAgICAgIGxldCBibHVycmVkVGh1bWJuYWlsQ291bnQgPSAwOwoKICAgICAgICBmb3IgKGNvbnN0IHRodW1ibmFpbCBvZiB0aHVtYm5haWxzKSB7CiAgICAgICAgICAgIGlmIChpc1RodW1ibmFpbEJsdXJyZWQodGh1bWJuYWlsKSkgewogICAgICAgICAgICAgICAgYmx1cnJlZFRodW1ibmFpbENvdW50Kys7CiAgICAgICAgICAgICAgICB0aHVtYm5haWwudXJsID0gdGh1bWJuYWlsLnVybC5zcGxpdCgnPycpWzBdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpbmZvKGJsdXJyZWRUaHVtYm5haWxDb3VudCArICcvJyArIHRodW1ibmFpbHMubGVuZ3RoICsgJyB0aHVtYm5haWxzIGRldGVjdGVkIGFzIGJsdXJyZWQuJyk7CiAgICB9CgogICAgZnVuY3Rpb24gaXNUaHVtYm5haWxCbHVycmVkKHRodW1ibmFpbCkgewogICAgICAgIGNvbnN0IGhhc1NRUFBhcmFtID0gdGh1bWJuYWlsLnVybC5pbmRleE9mKCc/c3FwPScpICE9PSAtMTsKCiAgICAgICAgaWYgKCFoYXNTUVBQYXJhbSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBjb25zdCBTUVBMZW5ndGggPSBuZXcgVVJMKHRodW1ibmFpbC51cmwpLnNlYXJjaFBhcmFtcy5nZXQoJ3NxcCcpLmxlbmd0aDsKICAgICAgICBjb25zdCBpc0JsdXJyZWQgPSBDb25maWcuQkxVUlJFRF9USFVNQk5BSUxfU1FQX0xFTkdUSFMuaW5jbHVkZXMoU1FQTGVuZ3RoKTsKCiAgICAgICAgcmV0dXJuIGlzQmx1cnJlZDsKICAgIH0KCiAgICB0cnkgewogICAgICAgIGF0dGFjaCQzKHByb2Nlc3NZdERhdGEpOwogICAgICAgIGF0dGFjaCQyKHByb2Nlc3NZdERhdGEpOwogICAgICAgIGF0dGFjaChoYW5kbGVYaHJPcGVuKTsKICAgICAgICBhdHRhY2gkMShoYW5kbGVGZXRjaFJlcXVlc3QpOwogICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgZXJyb3IoZXJyLCAnRXJyb3Igd2hpbGUgYXR0YWNoaW5nIGRhdGEgaW50ZXJjZXB0b3JzJyk7CiAgICB9CgogICAgZnVuY3Rpb24gcHJvY2Vzc1l0RGF0YSh5dERhdGEpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICAvLyBQbGF5ZXIgVW5sb2NrICMxOiBJbml0aWFsIHBhZ2UgZGF0YSBzdHJ1Y3R1cmUgYW5kIHJlc3BvbnNlIGZyb20gYC95b3V0dWJlaS92MS9wbGF5ZXJgIFhIUiByZXF1ZXN0CiAgICAgICAgICAgIGlmIChpc1BsYXllck9iamVjdCh5dERhdGEpICYmIGlzQWdlUmVzdHJpY3RlZCh5dERhdGEucGxheWFiaWxpdHlTdGF0dXMpKSB7CiAgICAgICAgICAgICAgICB1bmxvY2tSZXNwb25zZSQxKHl0RGF0YSk7CiAgICAgICAgICAgIH0gLy8gUGxheWVyIFVubG9jayAjMjogRW1iZWRkZWQgUGxheWVyIGluaXRhbCBkYXRhIHN0cnVjdHVyZQogICAgICAgICAgICBlbHNlIGlmIChpc0VtYmVkZGVkUGxheWVyT2JqZWN0KHl0RGF0YSkgJiYgaXNBZ2VSZXN0cmljdGVkKHl0RGF0YS5wcmV2aWV3UGxheWFiaWxpdHlTdGF0dXMpKSB7CiAgICAgICAgICAgICAgICB1bmxvY2tSZXNwb25zZSQxKHl0RGF0YSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgICAgZXJyb3IoZXJyLCAnVmlkZW8gdW5sb2NrIGZhaWxlZCcpOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8gVW5sb2NrIHNpZGViYXIgd2F0Y2ggbmV4dCBmZWVkIChzaWRlYmFyKSBhbmQgdmlkZW8gZGVzY3JpcHRpb24KICAgICAgICAgICAgaWYgKGlzV2F0Y2hOZXh0T2JqZWN0KHl0RGF0YSkgJiYgaXNXYXRjaE5leHRTaWRlYmFyRW1wdHkoeXREYXRhKSkgewogICAgICAgICAgICAgICAgdW5sb2NrUmVzcG9uc2UoeXREYXRhKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gTW9iaWxlIHZlcnNpb24KICAgICAgICAgICAgaWYgKGlzV2F0Y2hOZXh0T2JqZWN0KHl0RGF0YS5yZXNwb25zZSkgJiYgaXNXYXRjaE5leHRTaWRlYmFyRW1wdHkoeXREYXRhLnJlc3BvbnNlKSkgewogICAgICAgICAgICAgICAgdW5sb2NrUmVzcG9uc2UoeXREYXRhLnJlc3BvbnNlKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICBlcnJvcihlcnIsICdTaWRlYmFyIHVubG9jayBmYWlsZWQnKTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIC8vIFVubG9jayBibHVycnkgdmlkZW8gdGh1bWJuYWlscyBpbiBzZWFyY2ggcmVzdWx0cwogICAgICAgICAgICBpZiAoaXNTZWFyY2hSZXN1bHQoeXREYXRhKSkgewogICAgICAgICAgICAgICAgcHJvY2Vzc1RodW1ibmFpbHMoeXREYXRhKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICBlcnJvcihlcnIsICdUaHVtYm5haWwgdW5sb2NrIGZhaWxlZCcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHl0RGF0YTsKICAgIH0KfSkoKTsK"}]}