NFT Market Smart Contract

in #steem-engine5 years ago

{
"id": "ssc-mainnet1",
"json": {
"contractName": "contract",
"contractAction": "deploy",
"contractPayload": {
"name": "nftmarket",
"params": "",
"code": "LyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCAqLwovKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovCi8qIGVzbGludC1kaXNhYmxlIHByZWZlci10ZW1wbGF0ZSAqLwovKiBlc2xpbnQtZGlzYWJsZSBuby11bmRlcnNjb3JlLWRhbmdsZSAqLwovKiBnbG9iYWwgYWN0aW9ucywgYXBpICovCgpjb25zdCBDT05UUkFDVF9OQU1FID0gJ25mdG1hcmtldCc7CgovLyBjYW5ub3QgYnV5IG9yIHNlbGwgbW9yZSB0aGFuIHRoaXMgbnVtYmVyIG9mIE5GVCBpbnN0YW5jZXMgaW4gb25lIGFjdGlvbgpjb25zdCBNQVhfTlVNX1VOSVRTX09QRVJBQkxFID0gNTA7CgphY3Rpb25zLmNyZWF0ZVNTQyA9IGFzeW5jICgpID0+IHsKICAvLyBub3RoaW5nIHRvIGRvIGhlcmUKfTsKCi8vIGNoZWNrIHRoYXQgdG9rZW4gdHJhbnNmZXJzIHN1Y2NlZWRlZApjb25zdCBpc1Rva2VuVHJhbnNmZXJWZXJpZmllZCA9IChyZXN1bHQsIGZyb20sIHRvLCBzeW1ib2wsIHF1YW50aXR5LCBldmVudFN0cikgPT4gewogIGlmIChyZXN1bHQuZXJyb3JzID09PSB1bmRlZmluZWQKICAgICYmIHJlc3VsdC5ldmVudHMgJiYgcmVzdWx0LmV2ZW50cy5maW5kKGVsID0+IGVsLmNvbnRyYWN0ID09PSAndG9rZW5zJyAmJiBlbC5ldmVudCA9PT0gZXZlbnRTdHIKICAgICYmIGVsLmRhdGEuZnJvbSA9PT0gZnJvbSAmJiBlbC5kYXRhLnRvID09PSB0byAmJiBlbC5kYXRhLnF1YW50aXR5ID09PSBxdWFudGl0eSAmJiBlbC5kYXRhLnN5bWJvbCA9PT0gc3ltYm9sKSAhPT0gdW5kZWZpbmVkKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgcmV0dXJuIGZhbHNlOwp9OwoKY29uc3QgY291bnREZWNpbWFscyA9IHZhbHVlID0+IGFwaS5CaWdOdW1iZXIodmFsdWUpLmRwKCk7CgovLyBhIHZhbGlkIFN0ZWVtIGFjY291bnQgaXMgYmV0d2VlbiAzIGFuZCAxNiBjaGFyYWN0ZXJzIGluIGxlbmd0aApjb25zdCBpc1ZhbGlkU3RlZW1BY2NvdW50TGVuZ3RoID0gYWNjb3VudCA9PiBhY2NvdW50Lmxlbmd0aCA+PSAzICYmIGFjY291bnQubGVuZ3RoIDw9IDE2OwoKLy8gaGVscGVyIGZvciBidXkgYWN0aW9uCmNvbnN0IG1ha2VNYXBLZXkgPSAoYWNjb3VudCwgdHlwZSkgPT4gYWNjb3VudCArICctJyArIHR5cGU7CgovLyBoZWxwZXIgZm9yIHVwZGF0aW5nIG9wZW4gaW50ZXJlc3QKY29uc3QgbWFrZUdyb3VwaW5nS2V5ID0gKGdyb3VwaW5nLCBncm91cEJ5KSA9PiB7CiAgbGV0IGtleSA9ICcnOwogIGdyb3VwQnkuZm9yRWFjaCgobmFtZSkgPT4gewogICAga2V5ID0ga2V5ICsgJzonICsgbmFtZSArICc6JyArIGdyb3VwaW5nW25hbWVdOwogIH0pOwogIHJldHVybiBrZXk7Cn07Cgpjb25zdCBpc1ZhbGlkSWRBcnJheSA9IChhcnIpID0+IHsKICB0cnkgewogICAgaWYgKCFhcGkuYXNzZXJ0KGFyciAmJiB0eXBlb2YgYXJyID09PSAnb2JqZWN0JyAmJiBBcnJheS5pc0FycmF5KGFyciksICdpbnZhbGlkIGlkIGxpc3QnKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgaWYgKCFhcGkuYXNzZXJ0KGFyci5sZW5ndGggPD0gTUFYX05VTV9VTklUU19PUEVSQUJMRSwgYGNhbm5vdCBhY3Qgb24gbW9yZSB0aGFuICR7TUFYX05VTV9VTklUU19PUEVSQUJMRX0gSURzIGF0IG9uY2VgKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgY29uc3QgaWQgPSBhcnJbaV07CiAgICAgIGlmICghYXBpLmFzc2VydChpZCAmJiB0eXBlb2YgaWQgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKGlkKS5pc05hTigpICYmIGFwaS5CaWdOdW1iZXIoaWQpLmd0KDApLCAnaW52YWxpZCBpZCBsaXN0JykpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgIH0KICB9IGNhdGNoIChlKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIHJldHVybiB0cnVlOwp9OwoKYWN0aW9ucy5lbmFibGVNYXJrZXQgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHN5bWJvbCwKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgLy8gbWFrZSBzdXJlIE5GVCBleGlzdHMgYW5kIHZlcmlmeSBvd25lcnNoaXAKICAgIGNvbnN0IG5mdCA9IGF3YWl0IGFwaS5kYi5maW5kT25lSW5UYWJsZSgnbmZ0JywgJ25mdHMnLCB7IHN5bWJvbCB9KTsKICAgIGlmIChhcGkuYXNzZXJ0KG5mdCAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICYmIGFwaS5hc3NlcnQobmZ0Lmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ211c3QgYmUgdGhlIGlzc3VlcicpKSB7CiAgICAgIC8vIGNyZWF0ZSBhIG5ldyB0YWJsZSB0byBob2xkIG1hcmtldCBvcmRlcnMgZm9yIHRoaXMgTkZUCiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItdGVtcGxhdGUKICAgICAgY29uc3QgbWFya2V0VGFibGVOYW1lID0gc3ltYm9sICsgJ3NlbGxCb29rJzsKICAgICAgY29uc3QgbWV0cmljc1RhYmxlTmFtZSA9IHN5bWJvbCArICdvcGVuSW50ZXJlc3QnOwogICAgICBjb25zdCBoaXN0b3J5VGFibGVOYW1lID0gc3ltYm9sICsgJ3RyYWRlc0hpc3RvcnknOwogICAgICBjb25zdCB0YWJsZUV4aXN0cyA9IGF3YWl0IGFwaS5kYi50YWJsZUV4aXN0cyhtYXJrZXRUYWJsZU5hbWUpOwogICAgICBpZiAoYXBpLmFzc2VydCh0YWJsZUV4aXN0cyA9PT0gZmFsc2UsICdtYXJrZXQgYWxyZWFkeSBlbmFibGVkJykpIHsKICAgICAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUobWFya2V0VGFibGVOYW1lLCBbJ293bmVkQnknLCAnYWNjb3VudCcsICduZnRJZCcsICdncm91cGluZycsICdwcmljZVN5bWJvbCddKTsKICAgICAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUobWV0cmljc1RhYmxlTmFtZSwgWydzaWRlJywgJ3ByaWNlU3ltYm9sJywgJ2dyb3VwaW5nJ10pOwogICAgICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZShoaXN0b3J5VGFibGVOYW1lLCBbJ3ByaWNlU3ltYm9sJywgJ3RpbWVzdGFtcCddKTsKCiAgICAgICAgYXBpLmVtaXQoJ2VuYWJsZU1hcmtldCcsIHsgc3ltYm9sIH0pOwogICAgICB9CiAgICB9CiAgfQp9OwoKY29uc3QgdXBkYXRlT3BlbkludGVyZXN0ID0gYXN5bmMgKHNpZGUsIHN5bWJvbCwgcHJpY2VTeW1ib2wsIGdyb3VwcywgZ3JvdXBCeSkgPT4gewogIGNvbnN0IG1ldHJpY3NUYWJsZU5hbWUgPSBzeW1ib2wgKyAnb3BlbkludGVyZXN0JzsKCiAgLy8gY29sbGVjdCBhbGwgdGhlIGdyb3VwaW5ncyB0byBmZXRjaAogIGNvbnN0IGdyb3VwS2V5cyA9IFtdOwogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheAogIGZvciAoY29uc3QgaW5mbyBvZiBPYmplY3QudmFsdWVzKGdyb3VwcykpIHsKICAgIGdyb3VwS2V5cy5wdXNoKGluZm8uZ3JvdXBpbmcpOwogIH0KCiAgaWYgKGdyb3VwS2V5cy5sZW5ndGggPD0gMCkgewogICAgcmV0dXJuOwogIH0KCiAgY29uc3Qgb3BlbkludGVyZXN0ID0gYXdhaXQgYXBpLmRiLmZpbmQoCiAgICBtZXRyaWNzVGFibGVOYW1lLAogICAgewogICAgICBzaWRlLAogICAgICBwcmljZVN5bWJvbCwKICAgICAgZ3JvdXBpbmc6IHsKICAgICAgICAkaW46IGdyb3VwS2V5cywKICAgICAgfSwKICAgIH0sCiAgICBNQVhfTlVNX1VOSVRTX09QRVJBQkxFLAogICAgMCwKICAgIFt7IGluZGV4OiAnc2lkZScsIGRlc2NlbmRpbmc6IGZhbHNlIH0sIHsgaW5kZXg6ICdwcmljZVN5bWJvbCcsIGRlc2NlbmRpbmc6IGZhbHNlIH0sIHsgaW5kZXg6ICdncm91cGluZycsIGRlc2NlbmRpbmc6IGZhbHNlIH1dLAogICk7CgogIC8vIHVwZGF0ZSBleGlzdGluZyByZWNvcmRzLi4uCiAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcGVuSW50ZXJlc3QubGVuZ3RoOyBpICs9IDEpIHsKICAgIGNvbnN0IG1ldHJpYyA9IG9wZW5JbnRlcmVzdFtpXTsKICAgIGNvbnN0IGtleSA9IG1ha2VHcm91cGluZ0tleShtZXRyaWMuZ3JvdXBpbmcsIGdyb3VwQnkpOwogICAgaWYgKGtleSBpbiBncm91cHMpIHsKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduCiAgICAgIGdyb3Vwc1trZXldLmlzSW5Db2xsZWN0aW9uID0gdHJ1ZTsKICAgICAgbWV0cmljLmNvdW50ICs9IGdyb3Vwc1trZXldLmNvdW50OwogICAgICBpZiAobWV0cmljLmNvdW50IDwgMCkgewogICAgICAgIG1ldHJpYy5jb3VudCA9IDA7IC8vIHNob3VsZG4ndCBoYXBwZW4sIGJ1dCBuZWVkIHRvIHNhZmVndWFyZAogICAgICB9CgogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKG1ldHJpY3NUYWJsZU5hbWUsIG1ldHJpYyk7CiAgICB9CiAgfQoKICAvLyAuLi5hbmQgYWRkIG5ldyBvbmVzCiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4CiAgZm9yIChjb25zdCBpbmZvIG9mIE9iamVjdC52YWx1ZXMoZ3JvdXBzKSkgewogICAgaWYgKCFpbmZvLmlzSW5Db2xsZWN0aW9uKSB7CiAgICAgIGNvbnN0IGZpbmFsQ291bnQgPSBpbmZvLmNvdW50ID4gMCA/IGluZm8uY291bnQgOiAwOwogICAgICBjb25zdCBuZXdNZXRyaWMgPSB7CiAgICAgICAgc2lkZSwKICAgICAgICBwcmljZVN5bWJvbCwKICAgICAgICBncm91cGluZzogaW5mby5ncm91cGluZywKICAgICAgICBjb3VudDogZmluYWxDb3VudCwKICAgICAgfTsKCiAgICAgIGF3YWl0IGFwaS5kYi5pbnNlcnQobWV0cmljc1RhYmxlTmFtZSwgbmV3TWV0cmljKTsKICAgIH0KICB9Cn07Cgpjb25zdCB1cGRhdGVUcmFkZXNIaXN0b3J5ID0gYXN5bmMgKHR5cGUsIGFjY291bnQsIG93bmVkQnksIGNvdW50ZXJwYXJ0aWVzLCBzeW1ib2wsIHByaWNlU3ltYm9sLCBwcmljZSwgbWFya2V0QWNjb3VudCwgZmVlLCB2b2x1bWUpID0+IHsKICBjb25zdCBibG9ja0RhdGUgPSBuZXcgRGF0ZShgJHthcGkuc3RlZW1CbG9ja1RpbWVzdGFtcH0uMDAwWmApOwogIGNvbnN0IHRpbWVzdGFtcFNlYyA9IGJsb2NrRGF0ZS5nZXRUaW1lKCkgLyAxMDAwOwogIGNvbnN0IHRpbWVzdGFtcE1pbnVzMjRocnMgPSBibG9ja0RhdGUuc2V0RGF0ZShibG9ja0RhdGUuZ2V0RGF0ZSgpIC0gMSkgLyAxMDAwOwogIGNvbnN0IGhpc3RvcnlUYWJsZU5hbWUgPSBzeW1ib2wgKyAndHJhZGVzSGlzdG9yeSc7CgogIC8vIGNsZWFuIGhpc3RvcnkKICBsZXQgdHJhZGVzVG9EZWxldGUgPSBhd2FpdCBhcGkuZGIuZmluZCgKICAgIGhpc3RvcnlUYWJsZU5hbWUsCiAgICB7CiAgICAgIHByaWNlU3ltYm9sLAogICAgICB0aW1lc3RhbXA6IHsKICAgICAgICAkbHQ6IHRpbWVzdGFtcE1pbnVzMjRocnMsCiAgICAgIH0sCiAgICB9LAogICk7CiAgbGV0IG5iVHJhZGVzVG9EZWxldGUgPSB0cmFkZXNUb0RlbGV0ZS5sZW5ndGg7CgogIHdoaWxlIChuYlRyYWRlc1RvRGVsZXRlID4gMCkgewogICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IG5iVHJhZGVzVG9EZWxldGU7IGluZGV4ICs9IDEpIHsKICAgICAgY29uc3QgdHJhZGUgPSB0cmFkZXNUb0RlbGV0ZVtpbmRleF07CiAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoaGlzdG9yeVRhYmxlTmFtZSwgdHJhZGUpOwogICAgfQogICAgdHJhZGVzVG9EZWxldGUgPSBhd2FpdCBhcGkuZGIuZmluZCgKICAgICAgaGlzdG9yeVRhYmxlTmFtZSwKICAgICAgewogICAgICAgIHByaWNlU3ltYm9sLAogICAgICAgIHRpbWVzdGFtcDogewogICAgICAgICAgJGx0OiB0aW1lc3RhbXBNaW51czI0aHJzLAogICAgICAgIH0sCiAgICAgIH0sCiAgICApOwogICAgbmJUcmFkZXNUb0RlbGV0ZSA9IHRyYWRlc1RvRGVsZXRlLmxlbmd0aDsKICB9CiAgLy8gYWRkIG9yZGVyIHRvIHRoZSBoaXN0b3J5CiAgY29uc3QgbmV3VHJhZGUgPSB7fTsKICBuZXdUcmFkZS50eXBlID0gdHlwZTsKICBuZXdUcmFkZS5hY2NvdW50ID0gYWNjb3VudDsKICBuZXdUcmFkZS5vd25lZEJ5ID0gb3duZWRCeTsKICBuZXdUcmFkZS5jb3VudGVycGFydGllcyA9IGNvdW50ZXJwYXJ0aWVzOwogIG5ld1RyYWRlLnByaWNlU3ltYm9sID0gcHJpY2VTeW1ib2w7CiAgbmV3VHJhZGUucHJpY2UgPSBwcmljZTsKICBuZXdUcmFkZS5tYXJrZXRBY2NvdW50ID0gbWFya2V0QWNjb3VudDsKICBuZXdUcmFkZS5mZWUgPSBmZWU7CiAgbmV3VHJhZGUudGltZXN0YW1wID0gdGltZXN0YW1wU2VjOwogIG5ld1RyYWRlLnZvbHVtZSA9IHZvbHVtZTsKICBhd2FpdCBhcGkuZGIuaW5zZXJ0KGhpc3RvcnlUYWJsZU5hbWUsIG5ld1RyYWRlKTsKfTsKCmFjdGlvbnMuY2hhbmdlUHJpY2UgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHN5bWJvbCwKICAgIG5mdHMsCiAgICBwcmljZSwKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKCFhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJywgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIHJldHVybjsKICB9CgogIGNvbnN0IG1hcmtldFRhYmxlTmFtZSA9IHN5bWJvbCArICdzZWxsQm9vayc7CiAgY29uc3QgdGFibGVFeGlzdHMgPSBhd2FpdCBhcGkuZGIudGFibGVFeGlzdHMobWFya2V0VGFibGVOYW1lKTsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGlzVmFsaWRJZEFycmF5KG5mdHMpCiAgICAmJiBhcGkuYXNzZXJ0KHByaWNlICYmIHR5cGVvZiBwcmljZSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocHJpY2UpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpCiAgICAmJiBhcGkuYXNzZXJ0KHRhYmxlRXhpc3RzLCAnbWFya2V0IG5vdCBlbmFibGVkIGZvciBzeW1ib2wnKSkgewogICAgLy8gbG9vayB1cCBvcmRlciBpbmZvCiAgICBjb25zdCBvcmRlcnMgPSBhd2FpdCBhcGkuZGIuZmluZCgKICAgICAgbWFya2V0VGFibGVOYW1lLAogICAgICB7CiAgICAgICAgbmZ0SWQ6IHsKICAgICAgICAgICRpbjogbmZ0cywKICAgICAgICB9LAogICAgICB9LAogICAgICBNQVhfTlVNX1VOSVRTX09QRVJBQkxFLAogICAgICAwLAogICAgICBbeyBpbmRleDogJ25mdElkJywgZGVzY2VuZGluZzogZmFsc2UgfV0sCiAgICApOwoKICAgIGlmIChvcmRlcnMubGVuZ3RoID4gMCkgewogICAgICAvLyBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGNhbGxlciBpcyBhY3R1YWxseSB0aGUgb3duZXIgb2YgZWFjaCBvcmRlcgogICAgICAvLyBhbmQgYWxsIG9yZGVycyBoYXZlIHRoZSBzYW1lIHByaWNlIHN5bWJvbAogICAgICBsZXQgcHJpY2VTeW1ib2wgPSAnJzsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcmRlcnMubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgICBjb25zdCBvcmRlciA9IG9yZGVyc1tpXTsKICAgICAgICBpZiAocHJpY2VTeW1ib2wgPT09ICcnKSB7CiAgICAgICAgICAoeyBwcmljZVN5bWJvbCB9ID0gb3JkZXIpOwogICAgICAgIH0KICAgICAgICBpZiAoIWFwaS5hc3NlcnQob3JkZXIuYWNjb3VudCA9PT0gYXBpLnNlbmRlcgogICAgICAgICAgJiYgb3JkZXIub3duZWRCeSA9PT0gJ3UnLCAnYWxsIG9yZGVycyBtdXN0IGJlIHlvdXIgb3duJykKICAgICAgICAgIHx8ICFhcGkuYXNzZXJ0KHByaWNlU3ltYm9sID09PSBvcmRlci5wcmljZVN5bWJvbCwgJ2FsbCBvcmRlcnMgbXVzdCBoYXZlIHRoZSBzYW1lIHByaWNlIHN5bWJvbCcpKSB7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICB9CiAgICAgIC8vIGdldCB0aGUgcHJpY2UgdG9rZW4gcGFyYW1zCiAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAndG9rZW5zJywgeyBzeW1ib2w6IHByaWNlU3ltYm9sIH0pOwogICAgICBpZiAoYXBpLmFzc2VydCh0b2tlbgogICAgICAgICYmIGFwaS5CaWdOdW1iZXIocHJpY2UpLmd0KDApCiAgICAgICAgJiYgY291bnREZWNpbWFscyhwcmljZSkgPD0gdG9rZW4ucHJlY2lzaW9uLCAnaW52YWxpZCBwcmljZScpKSB7CiAgICAgICAgY29uc3QgZmluYWxQcmljZSA9IGFwaS5CaWdOdW1iZXIocHJpY2UpLnRvRml4ZWQodG9rZW4ucHJlY2lzaW9uKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9yZGVycy5sZW5ndGg7IGkgKz0gMSkgewogICAgICAgICAgY29uc3Qgb3JkZXIgPSBvcmRlcnNbaV07CiAgICAgICAgICBjb25zdCBvbGRQcmljZSA9IG9yZGVyLnByaWNlOwogICAgICAgICAgb3JkZXIucHJpY2UgPSBmaW5hbFByaWNlOwogICAgICAgICAgb3JkZXIucHJpY2VEZWMgPSB7ICRudW1iZXJEZWNpbWFsOiBmaW5hbFByaWNlIH07CgogICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZShtYXJrZXRUYWJsZU5hbWUsIG9yZGVyKTsKCiAgICAgICAgICBhcGkuZW1pdCgnY2hhbmdlUHJpY2UnLCB7CiAgICAgICAgICAgIHN5bWJvbCwKICAgICAgICAgICAgbmZ0SWQ6IG9yZGVyLm5mdElkLAogICAgICAgICAgICBvbGRQcmljZSwKICAgICAgICAgICAgbmV3UHJpY2U6IG9yZGVyLnByaWNlLAogICAgICAgICAgICBwcmljZVN5bWJvbDogb3JkZXIucHJpY2VTeW1ib2wsCiAgICAgICAgICAgIG9yZGVySWQ6IG9yZGVyLl9pZCwKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfTsKCmFjdGlvbnMuY2FuY2VsID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICBuZnRzLAogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoIWFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgcmV0dXJuOwogIH0KCiAgY29uc3QgbWFya2V0VGFibGVOYW1lID0gc3ltYm9sICsgJ3NlbGxCb29rJzsKICBjb25zdCB0YWJsZUV4aXN0cyA9IGF3YWl0IGFwaS5kYi50YWJsZUV4aXN0cyhtYXJrZXRUYWJsZU5hbWUpOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgaXNWYWxpZElkQXJyYXkobmZ0cykKICAgICYmIGFwaS5hc3NlcnQodGFibGVFeGlzdHMsICdtYXJrZXQgbm90IGVuYWJsZWQgZm9yIHN5bWJvbCcpKSB7CiAgICBjb25zdCBuZnQgPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ25mdCcsICduZnRzJywgeyBzeW1ib2wgfSk7CiAgICBpZiAoIWFwaS5hc3NlcnQobmZ0ICYmIG5mdC5ncm91cEJ5ICYmIG5mdC5ncm91cEJ5Lmxlbmd0aCA+IDAsICdtYXJrZXQgZ3JvdXBpbmcgbm90IHNldCcpKSB7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBsb29rIHVwIG9yZGVyIGluZm8KICAgIGNvbnN0IG9yZGVycyA9IGF3YWl0IGFwaS5kYi5maW5kKAogICAgICBtYXJrZXRUYWJsZU5hbWUsCiAgICAgIHsKICAgICAgICBuZnRJZDogewogICAgICAgICAgJGluOiBuZnRzLAogICAgICAgIH0sCiAgICAgIH0sCiAgICAgIE1BWF9OVU1fVU5JVFNfT1BFUkFCTEUsCiAgICAgIDAsCiAgICAgIFt7IGluZGV4OiAnbmZ0SWQnLCBkZXNjZW5kaW5nOiBmYWxzZSB9XSwKICAgICk7CgogICAgaWYgKG9yZGVycy5sZW5ndGggPiAwKSB7CiAgICAgIC8vIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgY2FsbGVyIGlzIGFjdHVhbGx5IHRoZSBvd25lciBvZiBlYWNoIG9yZGVyCiAgICAgIGNvbnN0IGlkcyA9IFtdOwogICAgICBjb25zdCBpZE1hcCA9IHt9OwogICAgICBsZXQgcHJpY2VTeW1ib2wgPSAnJzsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcmRlcnMubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgICBjb25zdCBvcmRlciA9IG9yZGVyc1tpXTsKICAgICAgICBpZiAocHJpY2VTeW1ib2wgPT09ICcnKSB7CiAgICAgICAgICAoeyBwcmljZVN5bWJvbCB9ID0gb3JkZXIpOwogICAgICAgIH0KICAgICAgICBpZiAoIWFwaS5hc3NlcnQob3JkZXIuYWNjb3VudCA9PT0gYXBpLnNlbmRlciAmJiBvcmRlci5vd25lZEJ5ID09PSAndScsICdhbGwgb3JkZXJzIG11c3QgYmUgeW91ciBvd24nKQogICAgICAgICAgfHwgIWFwaS5hc3NlcnQocHJpY2VTeW1ib2wgPT09IG9yZGVyLnByaWNlU3ltYm9sLCAnYWxsIG9yZGVycyBtdXN0IGhhdmUgdGhlIHNhbWUgcHJpY2Ugc3ltYm9sJykpIHsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWRzLnB1c2gob3JkZXIubmZ0SWQpOwogICAgICAgIGlkTWFwW29yZGVyLm5mdElkXSA9IG9yZGVyOwogICAgICB9CgogICAgICAvLyBtb3ZlIHRoZSBsb2NrZWQgTkZUcyBiYWNrIHRvIHRoZWlyIG93bmVyCiAgICAgIGNvbnN0IG5mdEFycmF5ID0gW107CiAgICAgIGNvbnN0IHdyYXBwZWROZnRzID0gewogICAgICAgIHN5bWJvbCwKICAgICAgICBpZHMsCiAgICAgIH07CiAgICAgIG5mdEFycmF5LnB1c2god3JhcHBlZE5mdHMpOwogICAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkuZXhlY3V0ZVNtYXJ0Q29udHJhY3QoJ25mdCcsICd0cmFuc2ZlcicsIHsKICAgICAgICBmcm9tVHlwZTogJ2NvbnRyYWN0JywKICAgICAgICB0bzogYXBpLnNlbmRlciwKICAgICAgICB0b1R5cGU6ICd1c2VyJywKICAgICAgICBuZnRzOiBuZnRBcnJheSwKICAgICAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgICAgIH0pOwoKICAgICAgLy8gaXQncyBwb3NzaWJsZSAoYnV0IHVubGlrZWx5KSB0aGF0IHNvbWUgdHJhbnNmZXJzIGNvdWxkIGhhdmUgZmFpbGVkCiAgICAgIC8vIGR1ZSB0byB2YWxpZGF0aW9uIGVycm9ycyAmIHdoYXRub3QsIHNvIHdlIG5lZWQgdG8gbG9vcCBvdmVyIHRoZQogICAgICAvLyB0cmFuc2ZlciByZXN1bHRzIGFuZCBvbmx5IGNhbmNlbCBvcmRlcnMgZm9yIHRoZSB0cmFuc2ZlcnMgdGhhdCBzdWNjZWVkZWQKICAgICAgaWYgKHJlcy5ldmVudHMpIHsKICAgICAgICBjb25zdCBncm91cGluZ01hcCA9IHt9OwogICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgcmVzLmV2ZW50cy5sZW5ndGg7IGogKz0gMSkgewogICAgICAgICAgY29uc3QgZXYgPSByZXMuZXZlbnRzW2pdOwogICAgICAgICAgaWYgKGV2LmNvbnRyYWN0ICYmIGV2LmV2ZW50ICYmIGV2LmRhdGEKICAgICAgICAgICAgJiYgZXYuY29udHJhY3QgPT09ICduZnQnCiAgICAgICAgICAgICYmIGV2LmV2ZW50ID09PSAndHJhbnNmZXInCiAgICAgICAgICAgICYmIGV2LmRhdGEuZnJvbSA9PT0gQ09OVFJBQ1RfTkFNRQogICAgICAgICAgICAmJiBldi5kYXRhLmZyb21UeXBlID09PSAnYycKICAgICAgICAgICAgJiYgZXYuZGF0YS50byA9PT0gYXBpLnNlbmRlcgogICAgICAgICAgICAmJiBldi5kYXRhLnRvVHlwZSA9PT0gJ3UnCiAgICAgICAgICAgICYmIGV2LmRhdGEuc3ltYm9sID09PSBzeW1ib2wpIHsKICAgICAgICAgICAgLy8gdHJhbnNmZXIgaXMgdmVyaWZpZWQsIG5vdyB3ZSBjYW4gY2FuY2VsIHRoZSBvcmRlcgogICAgICAgICAgICBjb25zdCBpbnN0YW5jZUlkID0gZXYuZGF0YS5pZDsKICAgICAgICAgICAgaWYgKGluc3RhbmNlSWQgaW4gaWRNYXApIHsKICAgICAgICAgICAgICBjb25zdCBvcmRlciA9IGlkTWFwW2luc3RhbmNlSWRdOwoKICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKG1hcmtldFRhYmxlTmFtZSwgb3JkZXIpOwoKICAgICAgICAgICAgICBhcGkuZW1pdCgnY2FuY2VsT3JkZXInLCB7CiAgICAgICAgICAgICAgICBhY2NvdW50OiBvcmRlci5hY2NvdW50LAogICAgICAgICAgICAgICAgb3duZWRCeTogb3JkZXIub3duZWRCeSwKICAgICAgICAgICAgICAgIHN5bWJvbCwKICAgICAgICAgICAgICAgIG5mdElkOiBvcmRlci5uZnRJZCwKICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogb3JkZXIudGltZXN0YW1wLAogICAgICAgICAgICAgICAgcHJpY2U6IG9yZGVyLnByaWNlLAogICAgICAgICAgICAgICAgcHJpY2VTeW1ib2w6IG9yZGVyLnByaWNlU3ltYm9sLAogICAgICAgICAgICAgICAgZmVlOiBvcmRlci5mZWUsCiAgICAgICAgICAgICAgICBvcmRlcklkOiBvcmRlci5faWQsCiAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgIGNvbnN0IGtleSA9IG1ha2VHcm91cGluZ0tleShvcmRlci5ncm91cGluZywgbmZ0Lmdyb3VwQnkpOwogICAgICAgICAgICAgIGNvbnN0IGdyb3VwSW5mbyA9IGtleSBpbiBncm91cGluZ01hcAogICAgICAgICAgICAgICAgPyBncm91cGluZ01hcFtrZXldCiAgICAgICAgICAgICAgICA6IHsKICAgICAgICAgICAgICAgICAgZ3JvdXBpbmc6IG9yZGVyLmdyb3VwaW5nLAogICAgICAgICAgICAgICAgICBpc0luQ29sbGVjdGlvbjogZmFsc2UsCiAgICAgICAgICAgICAgICAgIGNvdW50OiAwLAogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICBncm91cEluZm8uY291bnQgLT0gMTsKICAgICAgICAgICAgICBncm91cGluZ01hcFtrZXldID0gZ3JvdXBJbmZvOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyB1cGRhdGUgb3BlbiBpbnRlcmVzdCBtZXRyaWNzCiAgICAgICAgYXdhaXQgdXBkYXRlT3BlbkludGVyZXN0KCdzZWxsJywgc3ltYm9sLCBwcmljZVN5bWJvbCwgZ3JvdXBpbmdNYXAsIG5mdC5ncm91cEJ5KTsKICAgICAgfQogICAgfQogIH0KfTsKCmFjdGlvbnMuYnV5ID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICBuZnRzLAogICAgbWFya2V0QWNjb3VudCwKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKCFhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgJiYgbWFya2V0QWNjb3VudCAmJiB0eXBlb2YgbWFya2V0QWNjb3VudCA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICByZXR1cm47CiAgfQoKICBjb25zdCBtYXJrZXRUYWJsZU5hbWUgPSBzeW1ib2wgKyAnc2VsbEJvb2snOwogIGNvbnN0IHRhYmxlRXhpc3RzID0gYXdhaXQgYXBpLmRiLnRhYmxlRXhpc3RzKG1hcmtldFRhYmxlTmFtZSk7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBpc1ZhbGlkSWRBcnJheShuZnRzKQogICAgJiYgYXBpLmFzc2VydCh0YWJsZUV4aXN0cywgJ21hcmtldCBub3QgZW5hYmxlZCBmb3Igc3ltYm9sJykpIHsKICAgIGNvbnN0IGZpbmFsTWFya2V0QWNjb3VudCA9IG1hcmtldEFjY291bnQudHJpbSgpLnRvTG93ZXJDYXNlKCk7CiAgICBpZiAoYXBpLmFzc2VydChpc1ZhbGlkU3RlZW1BY2NvdW50TGVuZ3RoKGZpbmFsTWFya2V0QWNjb3VudCksICdpbnZhbGlkIG1hcmtldCBhY2NvdW50JykpIHsKICAgICAgY29uc3QgbmZ0ID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCduZnQnLCAnbmZ0cycsIHsgc3ltYm9sIH0pOwogICAgICBpZiAoIWFwaS5hc3NlcnQobmZ0ICYmIG5mdC5ncm91cEJ5ICYmIG5mdC5ncm91cEJ5Lmxlbmd0aCA+IDAsICdtYXJrZXQgZ3JvdXBpbmcgbm90IHNldCcpKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICAvLyBsb29rIHVwIG9yZGVyIGluZm8KICAgICAgY29uc3Qgb3JkZXJzID0gYXdhaXQgYXBpLmRiLmZpbmQoCiAgICAgICAgbWFya2V0VGFibGVOYW1lLAogICAgICAgIHsKICAgICAgICAgIG5mdElkOiB7CiAgICAgICAgICAgICRpbjogbmZ0cywKICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgICAgICBNQVhfTlVNX1VOSVRTX09QRVJBQkxFLAogICAgICAgIDAsCiAgICAgICAgW3sgaW5kZXg6ICduZnRJZCcsIGRlc2NlbmRpbmc6IGZhbHNlIH1dLAogICAgICApOwoKICAgICAgaWYgKG9yZGVycy5sZW5ndGggPiAwKSB7CiAgICAgICAgLy8gZG8gYSBjb3VwbGUgbW9yZSBzYW5pdHkgY2hlY2tzCiAgICAgICAgbGV0IHByaWNlU3ltYm9sID0gJyc7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcmRlcnMubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgICAgIGNvbnN0IG9yZGVyID0gb3JkZXJzW2ldOwogICAgICAgICAgaWYgKHByaWNlU3ltYm9sID09PSAnJykgewogICAgICAgICAgICAoeyBwcmljZVN5bWJvbCB9ID0gb3JkZXIpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKCFhcGkuYXNzZXJ0KCEob3JkZXIub3duZWRCeSA9PT0gJ3UnICYmIG9yZGVyLmFjY291bnQgPT09IGFwaS5zZW5kZXIpLCAnY2Fubm90IGZpbGwgeW91ciBvd24gb3JkZXJzJykKICAgICAgICAgICAgfHwgIWFwaS5hc3NlcnQocHJpY2VTeW1ib2wgPT09IG9yZGVyLnByaWNlU3ltYm9sLCAnYWxsIG9yZGVycyBtdXN0IGhhdmUgdGhlIHNhbWUgcHJpY2Ugc3ltYm9sJykpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBnZXQgdGhlIHByaWNlIHRva2VuIHBhcmFtcwogICAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAndG9rZW5zJywgeyBzeW1ib2w6IHByaWNlU3ltYm9sIH0pOwogICAgICAgIGlmICghdG9rZW4pIHsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIGNyZWF0ZSBvcmRlciBtYXBzCiAgICAgICAgbGV0IGZlZVRvdGFsID0gYXBpLkJpZ051bWJlcigwKTsKICAgICAgICBsZXQgcGF5bWVudFRvdGFsID0gYXBpLkJpZ051bWJlcigwKTsKICAgICAgICBsZXQgc29sZE5mdHMgPSBbXTsKICAgICAgICBjb25zdCBzZWxsZXJzID0gW107CiAgICAgICAgY29uc3Qgc2VsbGVyTWFwID0ge307CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcmRlcnMubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgICAgIGNvbnN0IG9yZGVyID0gb3JkZXJzW2ldOwogICAgICAgICAgY29uc3QgZmluYWxQcmljZSA9IGFwaS5CaWdOdW1iZXIob3JkZXIucHJpY2UpOwogICAgICAgICAgY29uc3QgZmVlUGVyY2VudCA9IG9yZGVyLmZlZSAvIDEwMDAwOwogICAgICAgICAgbGV0IGZpbmFsRmVlID0gZmluYWxQcmljZS5tdWx0aXBsaWVkQnkoZmVlUGVyY2VudCkuZGVjaW1hbFBsYWNlcyh0b2tlbi5wcmVjaXNpb24pOwogICAgICAgICAgaWYgKGZpbmFsRmVlLmd0KGZpbmFsUHJpY2UpKSB7CiAgICAgICAgICAgIGZpbmFsRmVlID0gZmluYWxQcmljZTsgLy8gdW5saWtlbHkgYnV0IG5lZWQgdG8gYmUgc3VyZQogICAgICAgICAgfQogICAgICAgICAgbGV0IGZpbmFsUGF5bWVudCA9IGZpbmFsUHJpY2UubWludXMoZmluYWxGZWUpLmRlY2ltYWxQbGFjZXModG9rZW4ucHJlY2lzaW9uKTsKICAgICAgICAgIGlmIChmaW5hbFBheW1lbnQubHQoMCkpIHsKICAgICAgICAgICAgZmluYWxQYXltZW50ID0gYXBpLkJpZ051bWJlcigwKTsgLy8gdW5saWtlbHkgYnV0IG5lZWQgdG8gYmUgc3VyZQogICAgICAgICAgfQogICAgICAgICAgcGF5bWVudFRvdGFsID0gcGF5bWVudFRvdGFsLnBsdXMoZmluYWxQYXltZW50KTsKICAgICAgICAgIGZlZVRvdGFsID0gZmVlVG90YWwucGx1cyhmaW5hbEZlZSk7CgogICAgICAgICAgY29uc3Qga2V5ID0gbWFrZU1hcEtleShvcmRlci5hY2NvdW50LCBvcmRlci5vd25lZEJ5KTsKICAgICAgICAgIGNvbnN0IHNlbGxlckluZm8gPSBrZXkgaW4gc2VsbGVyTWFwCiAgICAgICAgICAgID8gc2VsbGVyTWFwW2tleV0KICAgICAgICAgICAgOiB7CiAgICAgICAgICAgICAgYWNjb3VudDogb3JkZXIuYWNjb3VudCwKICAgICAgICAgICAgICBvd25lZEJ5OiBvcmRlci5vd25lZEJ5LAogICAgICAgICAgICAgIG5mdElkczogW10sCiAgICAgICAgICAgICAgcGF5bWVudFRvdGFsOiBhcGkuQmlnTnVtYmVyKDApLAogICAgICAgICAgICB9OwoKICAgICAgICAgIHNlbGxlckluZm8ucGF5bWVudFRvdGFsID0gc2VsbGVySW5mby5wYXltZW50VG90YWwucGx1cyhmaW5hbFBheW1lbnQpOwogICAgICAgICAgc2VsbGVySW5mby5uZnRJZHMucHVzaChvcmRlci5uZnRJZCk7CiAgICAgICAgICBzZWxsZXJNYXBba2V5XSA9IHNlbGxlckluZm87CiAgICAgICAgfQoKICAgICAgICAvLyB2ZXJpZnkgYnV5ZXIgaGFzIGVub3VnaCBmdW5kcyBmb3IgcGF5bWVudAogICAgICAgIGNvbnN0IHJlcXVpcmVkQmFsYW5jZSA9IHBheW1lbnRUb3RhbC5wbHVzKGZlZVRvdGFsKS50b0ZpeGVkKHRva2VuLnByZWNpc2lvbik7CiAgICAgICAgY29uc3QgYnV5ZXJCYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAnYmFsYW5jZXMnLCB7IGFjY291bnQ6IGFwaS5zZW5kZXIsIHN5bWJvbDogcHJpY2VTeW1ib2wgfSk7CiAgICAgICAgaWYgKCFhcGkuYXNzZXJ0KGJ1eWVyQmFsYW5jZQogICAgICAgICAgJiYgYXBpLkJpZ051bWJlcihidXllckJhbGFuY2UuYmFsYW5jZSkuZ3RlKHJlcXVpcmVkQmFsYW5jZSksICd5b3UgbXVzdCBoYXZlIGVub3VnaCB0b2tlbnMgZm9yIHBheW1lbnQnKSkgewogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBwYXltZW50VG90YWwgPSBwYXltZW50VG90YWwudG9GaXhlZCh0b2tlbi5wcmVjaXNpb24pOwoKICAgICAgICAvLyBzZW5kIGZlZXMgdG8gbWFya2V0IGFjY291bnQKICAgICAgICBpZiAoZmVlVG90YWwuZ3QoMCkpIHsKICAgICAgICAgIGZlZVRvdGFsID0gZmVlVG90YWwudG9GaXhlZCh0b2tlbi5wcmVjaXNpb24pOwogICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgYXBpLmV4ZWN1dGVTbWFydENvbnRyYWN0KCd0b2tlbnMnLCAndHJhbnNmZXInLCB7CiAgICAgICAgICAgIHRvOiBmaW5hbE1hcmtldEFjY291bnQsIHN5bWJvbDogcHJpY2VTeW1ib2wsIHF1YW50aXR5OiBmZWVUb3RhbCwgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogICAgICAgICAgfSk7CiAgICAgICAgICBpZiAoIWFwaS5hc3NlcnQoaXNUb2tlblRyYW5zZmVyVmVyaWZpZWQocmVzLCBhcGkuc2VuZGVyLCBmaW5hbE1hcmtldEFjY291bnQsIHByaWNlU3ltYm9sLCBmZWVUb3RhbCwgJ3RyYW5zZmVyJyksICd1bmFibGUgdG8gdHJhbnNmZXIgbWFya2V0IGZlZXMnKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBzZW5kIHBheW1lbnRzIHRvIHNlbGxlcnMKICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgKICAgICAgICBmb3IgKGNvbnN0IGluZm8gb2YgT2JqZWN0LnZhbHVlcyhzZWxsZXJNYXApKSB7CiAgICAgICAgICBpZiAoaW5mby5wYXltZW50VG90YWwuZ3QoMCkpIHsKICAgICAgICAgICAgY29uc3QgY29udHJhY3RBY3Rpb24gPSBpbmZvLm93bmVkQnkgPT09ICd1JyA/ICd0cmFuc2ZlcicgOiAndHJhbnNmZXJUb0NvbnRyYWN0JzsKICAgICAgICAgICAgaW5mby5wYXltZW50VG90YWwgPSBpbmZvLnBheW1lbnRUb3RhbC50b0ZpeGVkKHRva2VuLnByZWNpc2lvbik7CiAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaS5leGVjdXRlU21hcnRDb250cmFjdCgndG9rZW5zJywgY29udHJhY3RBY3Rpb24sIHsKICAgICAgICAgICAgICB0bzogaW5mby5hY2NvdW50LCBzeW1ib2w6IHByaWNlU3ltYm9sLCBxdWFudGl0eTogaW5mby5wYXltZW50VG90YWwsIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlmIChhcGkuYXNzZXJ0KGlzVG9rZW5UcmFuc2ZlclZlcmlmaWVkKHJlcywgYXBpLnNlbmRlciwgaW5mby5hY2NvdW50LCBwcmljZVN5bWJvbCwgaW5mby5wYXltZW50VG90YWwsIGNvbnRyYWN0QWN0aW9uKSwgYHVuYWJsZSB0byB0cmFuc2ZlciBwYXltZW50IHRvICR7aW5mby5hY2NvdW50fWApKSB7CiAgICAgICAgICAgICAgc29sZE5mdHMgPSBzb2xkTmZ0cy5jb25jYXQoaW5mby5uZnRJZHMpOwogICAgICAgICAgICAgIHNlbGxlcnMucHVzaChpbmZvKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc29sZE5mdHMgPSBzb2xkTmZ0cy5jb25jYXQoaW5mby5uZnRJZHMpOwogICAgICAgICAgICBzZWxsZXJzLnB1c2goaW5mbyk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyB0cmFuc2ZlciBzb2xkIE5GVCBpbnN0YW5jZXMgdG8gbmV3IG93bmVyCiAgICAgICAgY29uc3QgbmZ0QXJyYXkgPSBbXTsKICAgICAgICBjb25zdCB3cmFwcGVkTmZ0cyA9IHsKICAgICAgICAgIHN5bWJvbCwKICAgICAgICAgIGlkczogc29sZE5mdHMsCiAgICAgICAgfTsKICAgICAgICBuZnRBcnJheS5wdXNoKHdyYXBwZWROZnRzKTsKICAgICAgICBhd2FpdCBhcGkuZXhlY3V0ZVNtYXJ0Q29udHJhY3QoJ25mdCcsICd0cmFuc2ZlcicsIHsKICAgICAgICAgIGZyb21UeXBlOiAnY29udHJhY3QnLAogICAgICAgICAgdG86IGFwaS5zZW5kZXIsCiAgICAgICAgICB0b1R5cGU6ICd1c2VyJywKICAgICAgICAgIG5mdHM6IG5mdEFycmF5LAogICAgICAgICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogICAgICAgIH0pOwoKICAgICAgICAvLyBkZWxldGUgc29sZCBtYXJrZXQgb3JkZXJzCiAgICAgICAgY29uc3QgZ3JvdXBpbmdNYXAgPSB7fTsKICAgICAgICBjb25zdCBzb2xkU2V0ID0gbmV3IFNldChzb2xkTmZ0cyk7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcmRlcnMubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgICAgIGNvbnN0IG9yZGVyID0gb3JkZXJzW2ldOwogICAgICAgICAgaWYgKHNvbGRTZXQuaGFzKG9yZGVyLm5mdElkKSkgewogICAgICAgICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKG1hcmtldFRhYmxlTmFtZSwgb3JkZXIpOwoKICAgICAgICAgICAgY29uc3Qga2V5ID0gbWFrZUdyb3VwaW5nS2V5KG9yZGVyLmdyb3VwaW5nLCBuZnQuZ3JvdXBCeSk7CiAgICAgICAgICAgIGNvbnN0IGdyb3VwSW5mbyA9IGtleSBpbiBncm91cGluZ01hcAogICAgICAgICAgICAgID8gZ3JvdXBpbmdNYXBba2V5XQogICAgICAgICAgICAgIDogewogICAgICAgICAgICAgICAgZ3JvdXBpbmc6IG9yZGVyLmdyb3VwaW5nLAogICAgICAgICAgICAgICAgaXNJbkNvbGxlY3Rpb246IGZhbHNlLAogICAgICAgICAgICAgICAgY291bnQ6IDAsCiAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgZ3JvdXBJbmZvLmNvdW50IC09IDE7CiAgICAgICAgICAgIGdyb3VwaW5nTWFwW2tleV0gPSBncm91cEluZm87CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBhZGQgdGhlIHRyYWRlIHRvIHRoZSBoaXN0b3J5CiAgICAgICAgYXdhaXQgdXBkYXRlVHJhZGVzSGlzdG9yeSgnYnV5JywgYXBpLnNlbmRlciwgJ3UnLCBzZWxsZXJzLCBzeW1ib2wsIHByaWNlU3ltYm9sLCByZXF1aXJlZEJhbGFuY2UsIGZpbmFsTWFya2V0QWNjb3VudCwgZmVlVG90YWwsIHNvbGROZnRzLmxlbmd0aCk7CgogICAgICAgIGFwaS5lbWl0KCdoaXRTZWxsT3JkZXInLCB7CiAgICAgICAgICBzeW1ib2wsCiAgICAgICAgICBwcmljZVN5bWJvbCwKICAgICAgICAgIGFjY291bnQ6IGFwaS5zZW5kZXIsCiAgICAgICAgICBvd25lZEJ5OiAndScsCiAgICAgICAgICBzZWxsZXJzLAogICAgICAgICAgcGF5bWVudFRvdGFsLAogICAgICAgICAgZmVlVG90YWwsCiAgICAgICAgfSk7CgogICAgICAgIC8vIHVwZGF0ZSBvcGVuIGludGVyZXN0IG1ldHJpY3MKICAgICAgICBhd2FpdCB1cGRhdGVPcGVuSW50ZXJlc3QoJ3NlbGwnLCBzeW1ib2wsIHByaWNlU3ltYm9sLCBncm91cGluZ01hcCwgbmZ0Lmdyb3VwQnkpOwogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy5zZWxsID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICBuZnRzLAogICAgcHJpY2UsCiAgICBwcmljZVN5bWJvbCwKICAgIGZlZSwKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKCFhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJywgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIHJldHVybjsKICB9CgogIGNvbnN0IG1hcmtldFRhYmxlTmFtZSA9IHN5bWJvbCArICdzZWxsQm9vayc7CiAgY29uc3QgaW5zdGFuY2VUYWJsZU5hbWUgPSBzeW1ib2wgKyAnaW5zdGFuY2VzJzsKICBjb25zdCB0YWJsZUV4aXN0cyA9IGF3YWl0IGFwaS5kYi50YWJsZUV4aXN0cyhtYXJrZXRUYWJsZU5hbWUpOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChuZnRzICYmIHR5cGVvZiBuZnRzID09PSAnb2JqZWN0JyAmJiBBcnJheS5pc0FycmF5KG5mdHMpCiAgICAmJiBwcmljZVN5bWJvbCAmJiB0eXBlb2YgcHJpY2VTeW1ib2wgPT09ICdzdHJpbmcnCiAgICAmJiBwcmljZSAmJiB0eXBlb2YgcHJpY2UgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHByaWNlKS5pc05hTigpCiAgICAmJiBmZWUgJiYgdHlwZW9mIGZlZSA9PT0gJ251bWJlcicgJiYgZmVlID49IDAgJiYgZmVlIDw9IDEwMDAwICYmIE51bWJlci5pc0ludGVnZXIoZmVlKSwgJ2ludmFsaWQgcGFyYW1zJykKICAgICYmIGFwaS5hc3NlcnQobmZ0cy5sZW5ndGggPD0gTUFYX05VTV9VTklUU19PUEVSQUJMRSwgYGNhbm5vdCBzZWxsIG1vcmUgdGhhbiAke01BWF9OVU1fVU5JVFNfT1BFUkFCTEV9IE5GVCBpbnN0YW5jZXMgYXQgb25jZWApCiAgICAmJiBhcGkuYXNzZXJ0KHRhYmxlRXhpc3RzLCAnbWFya2V0IG5vdCBlbmFibGVkIGZvciBzeW1ib2wnKSkgewogICAgY29uc3QgbmZ0ID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCduZnQnLCAnbmZ0cycsIHsgc3ltYm9sIH0pOwogICAgaWYgKCFhcGkuYXNzZXJ0KG5mdCAmJiBuZnQuZ3JvdXBCeSAmJiBuZnQuZ3JvdXBCeS5sZW5ndGggPiAwLCAnbWFya2V0IGdyb3VwaW5nIG5vdCBzZXQnKSkgewogICAgICByZXR1cm47CiAgICB9CgogICAgLy8gZ2V0IHRoZSBwcmljZSB0b2tlbiBwYXJhbXMKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAndG9rZW5zJywgeyBzeW1ib2w6IHByaWNlU3ltYm9sIH0pOwogICAgaWYgKGFwaS5hc3NlcnQodG9rZW4KICAgICAgJiYgYXBpLkJpZ051bWJlcihwcmljZSkuZ3QoMCkKICAgICAgJiYgY291bnREZWNpbWFscyhwcmljZSkgPD0gdG9rZW4ucHJlY2lzaW9uLCAnaW52YWxpZCBwcmljZScpKSB7CiAgICAgIC8vIGxvY2sgdGhlIE5GVHMgdG8gc2VsbCBieSBtb3ZpbmcgdGhlbSB0byB0aGlzIGNvbnRyYWN0IGZvciBzYWZla2VlcGluZwogICAgICBjb25zdCBuZnRBcnJheSA9IFtdOwogICAgICBjb25zdCB3cmFwcGVkTmZ0cyA9IHsKICAgICAgICBzeW1ib2wsCiAgICAgICAgaWRzOiBuZnRzLAogICAgICB9OwogICAgICBuZnRBcnJheS5wdXNoKHdyYXBwZWROZnRzKTsKICAgICAgY29uc3QgcmVzID0gYXdhaXQgYXBpLmV4ZWN1dGVTbWFydENvbnRyYWN0KCduZnQnLCAndHJhbnNmZXInLCB7CiAgICAgICAgZnJvbVR5cGU6ICd1c2VyJywKICAgICAgICB0bzogQ09OVFJBQ1RfTkFNRSwKICAgICAgICB0b1R5cGU6ICdjb250cmFjdCcsCiAgICAgICAgbmZ0czogbmZ0QXJyYXksCiAgICAgICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogICAgICB9KTsKCiAgICAgIC8vIGl0J3MgcG9zc2libGUgdGhhdCBzb21lIHRyYW5zZmVycyBjb3VsZCBoYXZlIGZhaWxlZCBkdWUgdG8gdmFsaWRhdGlvbgogICAgICAvLyBlcnJvcnMgJiB3aGF0bm90LCBzbyB3ZSBuZWVkIHRvIGxvb3Agb3ZlciB0aGUgdHJhbnNmZXIgcmVzdWx0cyBhbmQKICAgICAgLy8gb25seSBjcmVhdGUgbWFya2V0IG9yZGVycyBmb3IgdGhlIHRyYW5zZmVycyB0aGF0IHN1Y2NlZWRlZAogICAgICBpZiAocmVzLmV2ZW50cykgewogICAgICAgIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5zdGVlbUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgICAgICAgY29uc3QgdGltZXN0YW1wID0gYmxvY2tEYXRlLmdldFRpbWUoKTsKICAgICAgICBjb25zdCBmaW5hbFByaWNlID0gYXBpLkJpZ051bWJlcihwcmljZSkudG9GaXhlZCh0b2tlbi5wcmVjaXNpb24pOwogICAgICAgIGNvbnN0IG5mdEludGVnZXJJZExpc3QgPSBbXTsKICAgICAgICBjb25zdCBvcmRlckRhdGFNYXAgPSB7fTsKCiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXMuZXZlbnRzLmxlbmd0aDsgaSArPSAxKSB7CiAgICAgICAgICBjb25zdCBldiA9IHJlcy5ldmVudHNbaV07CiAgICAgICAgICBpZiAoZXYuY29udHJhY3QgJiYgZXYuZXZlbnQgJiYgZXYuZGF0YQogICAgICAgICAgICAmJiBldi5jb250cmFjdCA9PT0gJ25mdCcKICAgICAgICAgICAgJiYgZXYuZXZlbnQgPT09ICd0cmFuc2ZlcicKICAgICAgICAgICAgJiYgZXYuZGF0YS5mcm9tID09PSBhcGkuc2VuZGVyCiAgICAgICAgICAgICYmIGV2LmRhdGEuZnJvbVR5cGUgPT09ICd1JwogICAgICAgICAgICAmJiBldi5kYXRhLnRvID09PSBDT05UUkFDVF9OQU1FCiAgICAgICAgICAgICYmIGV2LmRhdGEudG9UeXBlID09PSAnYycKICAgICAgICAgICAgJiYgZXYuZGF0YS5zeW1ib2wgPT09IHN5bWJvbCkgewogICAgICAgICAgICAvLyB0cmFuc2ZlciBpcyB2ZXJpZmllZCwgbm93IHdlIGNhbiBhZGQgYSBtYXJrZXQgb3JkZXIKICAgICAgICAgICAgY29uc3QgaW5zdGFuY2VJZCA9IGV2LmRhdGEuaWQ7CgogICAgICAgICAgICBjb25zdCBvcmRlckRhdGEgPSB7CiAgICAgICAgICAgICAgbmZ0SWQ6IGluc3RhbmNlSWQsCiAgICAgICAgICAgICAgZ3JvdXBpbmc6IHt9LAogICAgICAgICAgICAgIGdyb3VwaW5nS2V5OiAnJywKICAgICAgICAgICAgfTsKICAgICAgICAgICAgY29uc3QgaW50ZWdlcklkID0gYXBpLkJpZ051bWJlcihpbnN0YW5jZUlkKS50b051bWJlcigpOwogICAgICAgICAgICBuZnRJbnRlZ2VySWRMaXN0LnB1c2goaW50ZWdlcklkKTsKICAgICAgICAgICAgb3JkZXJEYXRhTWFwW2ludGVnZXJJZF0gPSBvcmRlckRhdGE7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBxdWVyeSBORlQgaW5zdGFuY2VzIHRvIGNvbnN0cnVjdCB0aGUgZ3JvdXBpbmcKICAgICAgICBjb25zdCBpbnN0YW5jZXMgPSBhd2FpdCBhcGkuZGIuZmluZEluVGFibGUoCiAgICAgICAgICAnbmZ0JywKICAgICAgICAgIGluc3RhbmNlVGFibGVOYW1lLAogICAgICAgICAgewogICAgICAgICAgICBfaWQ6IHsKICAgICAgICAgICAgICAkaW46IG5mdEludGVnZXJJZExpc3QsCiAgICAgICAgICAgIH0sCiAgICAgICAgICB9LAogICAgICAgICAgTUFYX05VTV9VTklUU19PUEVSQUJMRSwKICAgICAgICAgIDAsCiAgICAgICAgICBbeyBpbmRleDogJ19pZCcsIGRlc2NlbmRpbmc6IGZhbHNlIH1dLAogICAgICAgICk7CgogICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5zdGFuY2VzLmxlbmd0aDsgaiArPSAxKSB7CiAgICAgICAgICBjb25zdCBpbnN0YW5jZSA9IGluc3RhbmNlc1tqXTsKICAgICAgICAgIGNvbnN0IGdyb3VwaW5nID0ge307CiAgICAgICAgICBsZXQgZ3JvdXBpbmdLZXkgPSAnJzsKICAgICAgICAgIG5mdC5ncm91cEJ5LmZvckVhY2goKG5hbWUpID0+IHsKICAgICAgICAgICAgaWYgKGluc3RhbmNlLnByb3BlcnRpZXNbbmFtZV0gIT09IHVuZGVmaW5lZCAmJiBpbnN0YW5jZS5wcm9wZXJ0aWVzW25hbWVdICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgZ3JvdXBpbmdbbmFtZV0gPSBpbnN0YW5jZS5wcm9wZXJ0aWVzW25hbWVdLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZ3JvdXBpbmdbbmFtZV0gPSAnJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBncm91cGluZ0tleSA9IGdyb3VwaW5nS2V5ICsgJzonICsgbmFtZSArICc6JyArIGdyb3VwaW5nW25hbWVdOwogICAgICAgICAgfSk7CiAgICAgICAgICBvcmRlckRhdGFNYXBbaW5zdGFuY2UuX2lkXS5ncm91cGluZyA9IGdyb3VwaW5nOwogICAgICAgICAgb3JkZXJEYXRhTWFwW2luc3RhbmNlLl9pZF0uZ3JvdXBpbmdLZXkgPSBncm91cGluZ0tleTsKICAgICAgICB9CgogICAgICAgIC8vIGNyZWF0ZSB0aGUgb3JkZXJzCiAgICAgICAgY29uc3QgZ3JvdXBpbmdNYXAgPSB7fTsKICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG5mdEludGVnZXJJZExpc3QubGVuZ3RoOyBrICs9IDEpIHsKICAgICAgICAgIGNvbnN0IGludElkID0gbmZ0SW50ZWdlcklkTGlzdFtrXTsKICAgICAgICAgIGNvbnN0IG9yZGVySW5mbyA9IG9yZGVyRGF0YU1hcFtpbnRJZF07CiAgICAgICAgICBjb25zdCBvcmRlciA9IHsKICAgICAgICAgICAgYWNjb3VudDogYXBpLnNlbmRlciwKICAgICAgICAgICAgb3duZWRCeTogJ3UnLAogICAgICAgICAgICBuZnRJZDogb3JkZXJJbmZvLm5mdElkLAogICAgICAgICAgICBncm91cGluZzogb3JkZXJJbmZvLmdyb3VwaW5nLAogICAgICAgICAgICB0aW1lc3RhbXAsCiAgICAgICAgICAgIHByaWNlOiBmaW5hbFByaWNlLAogICAgICAgICAgICBwcmljZURlYzogeyAkbnVtYmVyRGVjaW1hbDogZmluYWxQcmljZSB9LAogICAgICAgICAgICBwcmljZVN5bWJvbCwKICAgICAgICAgICAgZmVlLAogICAgICAgICAgfTsKCiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcGkuZGIuaW5zZXJ0KG1hcmtldFRhYmxlTmFtZSwgb3JkZXIpOwoKICAgICAgICAgIGFwaS5lbWl0KCdzZWxsT3JkZXInLCB7CiAgICAgICAgICAgIGFjY291bnQ6IG9yZGVyLmFjY291bnQsCiAgICAgICAgICAgIG93bmVkQnk6IG9yZGVyLm93bmVkQnksCiAgICAgICAgICAgIHN5bWJvbCwKICAgICAgICAgICAgbmZ0SWQ6IG9yZGVyLm5mdElkLAogICAgICAgICAgICB0aW1lc3RhbXAsCiAgICAgICAgICAgIHByaWNlOiBvcmRlci5wcmljZSwKICAgICAgICAgICAgcHJpY2VTeW1ib2w6IG9yZGVyLnByaWNlU3ltYm9sLAogICAgICAgICAgICBmZWUsCiAgICAgICAgICAgIG9yZGVySWQ6IHJlc3VsdC5faWQsCiAgICAgICAgICB9KTsKCiAgICAgICAgICBjb25zdCBncm91cEluZm8gPSBvcmRlckluZm8uZ3JvdXBpbmdLZXkgaW4gZ3JvdXBpbmdNYXAKICAgICAgICAgICAgPyBncm91cGluZ01hcFtvcmRlckluZm8uZ3JvdXBpbmdLZXldCiAgICAgICAgICAgIDogewogICAgICAgICAgICAgIGdyb3VwaW5nOiBvcmRlckluZm8uZ3JvdXBpbmcsCiAgICAgICAgICAgICAgaXNJbkNvbGxlY3Rpb246IGZhbHNlLAogICAgICAgICAgICAgIGNvdW50OiAwLAogICAgICAgICAgICB9OwogICAgICAgICAgZ3JvdXBJbmZvLmNvdW50ICs9IDE7CiAgICAgICAgICBncm91cGluZ01hcFtvcmRlckluZm8uZ3JvdXBpbmdLZXldID0gZ3JvdXBJbmZvOwogICAgICAgIH0KCiAgICAgICAgLy8gdXBkYXRlIG9wZW4gaW50ZXJlc3QgbWV0cmljcwogICAgICAgIGF3YWl0IHVwZGF0ZU9wZW5JbnRlcmVzdCgnc2VsbCcsIHN5bWJvbCwgcHJpY2VTeW1ib2wsIGdyb3VwaW5nTWFwLCBuZnQuZ3JvdXBCeSk7CiAgICAgIH0KICAgIH0KICB9Cn07Cg=="
}
}
}

Coin Marketplace

STEEM 0.20
TRX 0.20
JST 0.034
BTC 89955.66
ETH 3105.10
USDT 1.00
SBD 2.98