{ "id": "ssc-testnet-hive", "json": { "contractName":"contract", "contractAction":"update", "contractPayload":{"name":"comments","params":"","code":"LyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCAqLwovKiBlc2xpbnQgbm8tdW5kZXJzY29yZS1kYW5nbGU6IFsiZXJyb3IiLCB7ICJhbGxvdyI6IFsiX2lkIl0gfV0gKi8KLyogZ2xvYmFsIGFjdGlvbnMsIGFwaSAqLwoKY29uc3QgU01UX1BSRUNJU0lPTiA9IDEwOwpjb25zdCBNQVhfVk9USU5HX1BPV0VSID0gMTAwMDA7CmNvbnN0IE1BWF9XRUlHSFQgPSAxMDAwMDsKY29uc3QgUE9TVF9RVUVSWV9MSU1JVCA9IDEwMDA7CgphY3Rpb25zLmNyZWF0ZVNTQyA9IGFzeW5jICgpID0+IHsKICBjb25zdCB0YWJsZUV4aXN0cyA9IGF3YWl0IGFwaS5kYi50YWJsZUV4aXN0cygncmV3YXJkUG9vbHMnKTsKICBpZiAodGFibGVFeGlzdHMgPT09IGZhbHNlKSB7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ3BhcmFtcycpOwogICAgYXdhaXQgYXBpLmRiLmNyZWF0ZVRhYmxlKCdyZXdhcmRQb29scycsIFsnY29uZmlnLnRhZ3MnLCAnbGFzdENsYWltRGVjYXlUaW1lc3RhbXAnXSk7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ3Bvc3RzJywgWwogICAgICAnYXV0aG9ycGVybScsCiAgICAgIHsgbmFtZTogJ2J5Q2FzaG91dFRpbWUnLCBpbmRleDogeyByZXdhcmRQb29sSWQ6IDEsIGNhc2hvdXRUaW1lOiAxIH0gfSwKICAgIF0sIHsgcHJpbWFyeUtleTogWydhdXRob3JwZXJtJywgJ3Jld2FyZFBvb2xJZCddIH0pOwogICAgYXdhaXQgYXBpLmRiLmNyZWF0ZVRhYmxlKCdwb3N0TWV0YWRhdGEnLCBbXSwgeyBwcmltYXJ5S2V5OiBbJ2F1dGhvcnBlcm0nXSB9KTsKICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgndm90ZXMnLCBbeyBuYW1lOiAnYnlUaW1lc3RhbXAnLCBpbmRleDogeyByZXdhcmRQb29sSWQ6IDEsIGF1dGhvcnBlcm06IDEsIHRpbWVzdGFtcDogMSB9IH1dLCB7IHByaW1hcnlLZXk6IFsncmV3YXJkUG9vbElkJywgJ2F1dGhvcnBlcm0nLCAndm90ZXInXSB9KTsKICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgndm90aW5nUG93ZXInLCBbXSwgeyBwcmltYXJ5S2V5OiBbJ3Jld2FyZFBvb2xJZCcsICdhY2NvdW50J10gfSk7CgogICAgY29uc3QgcGFyYW1zID0gewogICAgICBzZXR1cEZlZTogJzEwMDAnLAogICAgICB1cGRhdGVGZWU6ICcyMCcsCiAgICAgIG1heFBvb2xzUGVyUG9zdDogMjAsCiAgICAgIG1heFRhZ3NQZXJQb29sOiA1LAogICAgICBtYWludGVuYW5jZVRva2Vuc1BlckJsb2NrOiAyLAogICAgICBsYXN0TWFpbnRlbmFuY2VCbG9jazogYXBpLmJsb2NrTnVtYmVyLAogICAgICBtYXhQb3N0c1Byb2Nlc3NlZFBlclJvdW5kOiAyMCwKICAgICAgdm90ZVF1ZXJ5TGltaXQ6IDEwMCwKICAgICAgbWF4Vm90ZXNQcm9jZXNzZWRQZXJSb3VuZDogMTAwLAogICAgICBsYXN0UHJvY2Vzc2VkUG9vbElkOiAwLAogICAgfTsKICAgIGF3YWl0IGFwaS5kYi5pbnNlcnQoJ3BhcmFtcycsIHBhcmFtcyk7CiAgfQp9OwoKYWN0aW9ucy51cGRhdGVQYXJhbXMgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGlmIChhcGkuc2VuZGVyICE9PSBhcGkub3duZXIpIHJldHVybjsKCiAgY29uc3QgewogICAgc2V0dXBGZWUsCiAgICB1cGRhdGVGZWUsCiAgICBtYWludGVuYW5jZVRva2Vuc1BlckJsb2NrLAogICAgbWF4UG9zdHNQcm9jZXNzZWRQZXJSb3VuZCwKICAgIG1heFZvdGVzUHJvY2Vzc2VkUGVyUm91bmQsCiAgICB2b3RlUXVlcnlMaW1pdCwKICB9ID0gcGF5bG9hZDsKCiAgY29uc3QgcGFyYW1zID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BhcmFtcycsIHt9KTsKCiAgaWYgKHNldHVwRmVlKSB7CiAgICBpZiAoIWFwaS5hc3NlcnQodHlwZW9mIHNldHVwRmVlID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihzZXR1cEZlZSkuaXNOYU4oKSAmJiBhcGkuQmlnTnVtYmVyKHNldHVwRmVlKS5ndGUoMCksICdpbnZhbGlkIHNldHVwRmVlJykpIHJldHVybjsKICAgIHBhcmFtcy5zZXR1cEZlZSA9IHNldHVwRmVlOwogIH0KICBpZiAodXBkYXRlRmVlKSB7CiAgICBpZiAoIWFwaS5hc3NlcnQodHlwZW9mIHVwZGF0ZUZlZSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIodXBkYXRlRmVlKS5pc05hTigpICYmIGFwaS5CaWdOdW1iZXIodXBkYXRlRmVlKS5ndGUoMCksICdpbnZhbGlkIHVwZGF0ZUZlZScpKSByZXR1cm47CiAgICBwYXJhbXMudXBkYXRlRmVlID0gdXBkYXRlRmVlOwogIH0KICBpZiAobWFpbnRlbmFuY2VUb2tlbnNQZXJCbG9jaykgewogICAgaWYgKCFhcGkuYXNzZXJ0KE51bWJlci5pc0ludGVnZXIobWFpbnRlbmFuY2VUb2tlbnNQZXJCbG9jaykgJiYgbWFpbnRlbmFuY2VUb2tlbnNQZXJCbG9jayA+PSAxLCAnaW52YWxpZCBtYWludGVuYW5jZVRva2Vuc1BlckJsb2NrJykpIHJldHVybjsKICAgIHBhcmFtcy5tYWludGVuYW5jZVRva2Vuc1BlckJsb2NrID0gbWFpbnRlbmFuY2VUb2tlbnNQZXJCbG9jazsKICB9CiAgaWYgKG1heFBvc3RzUHJvY2Vzc2VkUGVyUm91bmQpIHsKICAgIGlmICghYXBpLmFzc2VydChOdW1iZXIuaXNJbnRlZ2VyKG1heFBvc3RzUHJvY2Vzc2VkUGVyUm91bmQpICYmIG1heFBvc3RzUHJvY2Vzc2VkUGVyUm91bmQgPj0gMSwgJ2ludmFsaWQgbWF4UG9zdHNQcm9jZXNzZWRQZXJSb3VuZCcpKSByZXR1cm47CiAgICBwYXJhbXMubWF4UG9zdHNQcm9jZXNzZWRQZXJSb3VuZCA9IG1heFBvc3RzUHJvY2Vzc2VkUGVyUm91bmQ7CiAgfQogIGlmIChtYXhWb3Rlc1Byb2Nlc3NlZFBlclJvdW5kKSB7CiAgICBpZiAoIWFwaS5hc3NlcnQoTnVtYmVyLmlzSW50ZWdlcihtYXhWb3Rlc1Byb2Nlc3NlZFBlclJvdW5kKSAmJiBtYXhWb3Rlc1Byb2Nlc3NlZFBlclJvdW5kID49IDEsICdpbnZhbGlkIG1heFZvdGVzUHJvY2Vzc2VkUGVyUm91bmQnKSkgcmV0dXJuOwogICAgcGFyYW1zLm1heFZvdGVzUHJvY2Vzc2VkUGVyUm91bmQgPSBtYXhWb3Rlc1Byb2Nlc3NlZFBlclJvdW5kOwogIH0KICBpZiAodm90ZVF1ZXJ5TGltaXQpIHsKICAgIGlmICghYXBpLmFzc2VydChOdW1iZXIuaXNJbnRlZ2VyKHZvdGVRdWVyeUxpbWl0KSAmJiB2b3RlUXVlcnlMaW1pdCA+PSAxLCAnaW52YWxpZCB2b3RlUXVlcnlMaW1pdCcpKSByZXR1cm47CiAgICBwYXJhbXMudm90ZVF1ZXJ5TGltaXQgPSB2b3RlUXVlcnlMaW1pdDsKICB9CgogIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3BhcmFtcycsIHBhcmFtcyk7Cn07CgpmdW5jdGlvbiBjYWxjdWxhdGVXZWlnaHRSc2hhcmVzKHJld2FyZFBvb2wsIHZvdGVSc2hhcmVTdW0pIHsKICBpZiAoYXBpLkJpZ051bWJlcih2b3RlUnNoYXJlU3VtKS5sdGUoMCkpIHJldHVybiBhcGkuQmlnTnVtYmVyKDApOwogIGlmIChyZXdhcmRQb29sLmNvbmZpZy5wb3N0UmV3YXJkQ3VydmUgPT09ICdwb3dlcicpIHsKICAgIGNvbnN0IHBvc3RSZXdhcmRFeHBvbmVudCA9IGFwaS5CaWdOdW1iZXIocmV3YXJkUG9vbC5jb25maWcucG9zdFJld2FyZEN1cnZlUGFyYW1ldGVyKTsKICAgIGlmIChwb3N0UmV3YXJkRXhwb25lbnQuZXEoJzEnKSB8fCBwb3N0UmV3YXJkRXhwb25lbnQuZXEoJzInKSkgewogICAgICByZXR1cm4gYXBpLkJpZ051bWJlcih2b3RlUnNoYXJlU3VtKS5wb3cocmV3YXJkUG9vbC5jb25maWcucG9zdFJld2FyZEN1cnZlUGFyYW1ldGVyKQogICAgICAgIC50b0ZpeGVkKFNNVF9QUkVDSVNJT04sIGFwaS5CaWdOdW1iZXIuUk9VTkRfRE9XTik7CiAgICB9CiAgICByZXR1cm4gYXBpLkJpZ051bWJlcihwYXJzZUZsb2F0KHZvdGVSc2hhcmVTdW0pCiAgICAgICAgKiogcGFyc2VGbG9hdChyZXdhcmRQb29sLmNvbmZpZy5wb3N0UmV3YXJkQ3VydmVQYXJhbWV0ZXIpKQogICAgICAudG9GaXhlZChTTVRfUFJFQ0lTSU9OLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOwogIH0KICByZXR1cm4gYXBpLkJpZ051bWJlcih2b3RlUnNoYXJlU3VtKTsKfQoKZnVuY3Rpb24gY2FsY3VsYXRlQ3VyYXRpb25XZWlnaHRSc2hhcmVzKHJld2FyZFBvb2wsIHZvdGVSc2hhcmVTdW0pIHsKICBpZiAoYXBpLkJpZ051bWJlcih2b3RlUnNoYXJlU3VtKS5sdGUoMCkpIHJldHVybiBhcGkuQmlnTnVtYmVyKDApOwogIGlmIChyZXdhcmRQb29sLmNvbmZpZy5jdXJhdGlvblJld2FyZEN1cnZlID09PSAncG93ZXInKSB7CiAgICBjb25zdCBjdXJhdGlvblJld2FyZEV4cG9uZW50ID0gYXBpLkJpZ051bWJlcihyZXdhcmRQb29sLmNvbmZpZy5jdXJhdGlvblJld2FyZEN1cnZlUGFyYW1ldGVyKTsKICAgIGlmIChjdXJhdGlvblJld2FyZEV4cG9uZW50LmVxKCcwLjUnKSkgewogICAgICByZXR1cm4gYXBpLkJpZ051bWJlcih2b3RlUnNoYXJlU3VtKS5zcXJ0KCkKICAgICAgICAudG9GaXhlZChTTVRfUFJFQ0lTSU9OLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOwogICAgfSBpZiAoY3VyYXRpb25SZXdhcmRFeHBvbmVudC5lcSgnMScpKSB7CiAgICAgIHJldHVybiBhcGkuQmlnTnVtYmVyKHZvdGVSc2hhcmVTdW0pLnRvRml4ZWQoU01UX1BSRUNJU0lPTiwgYXBpLkJpZ051bWJlci5ST1VORF9ET1dOKTsKICAgIH0KICAgIHJldHVybiBhcGkuQmlnTnVtYmVyKHBhcnNlRmxvYXQodm90ZVJzaGFyZVN1bSkKICAgICAgICAqKiBwYXJzZUZsb2F0KHJld2FyZFBvb2wuY29uZmlnLmN1cmF0aW9uUmV3YXJkQ3VydmVQYXJhbWV0ZXIpKQogICAgICAudG9GaXhlZChTTVRfUFJFQ0lTSU9OLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOwogIH0KICByZXR1cm4gYXBpLkJpZ051bWJlcih2b3RlUnNoYXJlU3VtKTsKfQoKYXN5bmMgZnVuY3Rpb24gcGF5VXNlcihzeW1ib2wsIHF1YW50aXR5LCB1c2VyLCBzdGFrZWRSZXdhcmRQZXJjZW50YWdlLCBtdXRlKSB7CiAgaWYgKG11dGUpIHJldHVybjsKICBjb25zdCBxdWFudGl0eUJpZ251bSA9IGFwaS5CaWdOdW1iZXIocXVhbnRpdHkpOwogIGNvbnN0IHN0YWtlZFF1YW50aXR5ID0gcXVhbnRpdHlCaWdudW0ubXVsdGlwbGllZEJ5KHN0YWtlZFJld2FyZFBlcmNlbnRhZ2UpLmRpdmlkZWRCeSgxMDApCiAgICAudG9GaXhlZChxdWFudGl0eUJpZ251bS5kcCgpLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOwogIGNvbnN0IGxpcXVpZFF1YW50aXR5ID0gcXVhbnRpdHlCaWdudW0ubWludXMoc3Rha2VkUXVhbnRpdHkpCiAgICAudG9GaXhlZChxdWFudGl0eUJpZ251bS5kcCgpLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOwogIGxldCByZXM7CiAgaWYgKGFwaS5CaWdOdW1iZXIobGlxdWlkUXVhbnRpdHkpLmd0KDApKSB7CiAgICByZXMgPSBhd2FpdCBhcGkudHJhbnNmZXJUb2tlbnModXNlciwgc3ltYm9sLCBsaXF1aWRRdWFudGl0eSwgJ3VzZXInKTsKICAgIGlmIChyZXMuZXJyb3JzKSB7CiAgICAgIGFwaS5kZWJ1ZyhgRXJyb3IgcGF5aW5nIG91dCBsaXF1aWQgJHtsaXF1aWRRdWFudGl0eX0gJHtzeW1ib2x9IHRvICR7dXNlcn0gKFRYSUQgJHthcGkudHJhbnNhY3Rpb25JZH0pOiBcbiR7cmVzLmVycm9yc31gKTsKICAgIH0KICB9CiAgaWYgKGFwaS5CaWdOdW1iZXIoc3Rha2VkUXVhbnRpdHkpLmd0KDApKSB7CiAgICByZXMgPSBhd2FpdCBhcGkuZXhlY3V0ZVNtYXJ0Q29udHJhY3QoJ3Rva2VucycsICdzdGFrZUZyb21Db250cmFjdCcsIHsgdG86IHVzZXIsIHN5bWJvbCwgcXVhbnRpdHk6IHN0YWtlZFF1YW50aXR5IH0pOwogICAgaWYgKHJlcy5lcnJvcnMpIHsKICAgICAgYXBpLmRlYnVnKGBFcnJvciBwYXlpbmcgb3V0IHN0YWtlZCAke3N0YWtlZFF1YW50aXR5fSAke3N5bWJvbH0gdG8gJHt1c2VyfSAoVFhJRCAke2FwaS50cmFuc2FjdGlvbklkfSk6IFxuJHtyZXMuZXJyb3JzfWApOwogICAgfQogIH0KfQoKYXN5bmMgZnVuY3Rpb24gZ2V0TXV0ZShyZXdhcmRQb29sSWQsIGFjY291bnQpIHsKICBjb25zdCB2b3RpbmdQb3dlciA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd2b3RpbmdQb3dlcicsIHsgcmV3YXJkUG9vbElkLCBhY2NvdW50IH0pOwogIHJldHVybiB2b3RpbmdQb3dlciA/IHZvdGluZ1Bvd2VyLm11dGUgOiBmYWxzZTsKfQoKYXN5bmMgZnVuY3Rpb24gcGF5T3V0QmVuZWZpY2lhcmllcyhyZXdhcmRQb29sLCB0b2tlbiwgcG9zdCwgYXV0aG9yQmVuZVBvcnRpb24pIHsKICBjb25zdCB7CiAgICBhdXRob3JwZXJtLAogICAgc3ltYm9sLAogICAgcmV3YXJkUG9vbElkLAogICAgYmVuZWZpY2lhcmllcywKICB9ID0gcG9zdDsKICBpZiAoIWJlbmVmaWNpYXJpZXMgfHwgYmVuZWZpY2lhcmllcy5sZW5ndGggPT09IDApIHsKICAgIHJldHVybiBhcGkuQmlnTnVtYmVyKDApOwogIH0KICBsZXQgdG90YWxCZW5lUGF5ID0gYXBpLkJpZ051bWJlcigwKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IGJlbmVmaWNpYXJpZXMubGVuZ3RoOyBpICs9IDEpIHsKICAgIGNvbnN0IGJlbmVmaWNpYXJ5ID0gYmVuZWZpY2lhcmllc1tpXTsKICAgIGNvbnN0IGJlbmVQYXkgPSBhcGkuQmlnTnVtYmVyKGF1dGhvckJlbmVQb3J0aW9uKS5tdWx0aXBsaWVkQnkoYmVuZWZpY2lhcnkud2VpZ2h0KQogICAgICAuZGl2aWRlZEJ5KDEwMDAwKQogICAgICAudG9GaXhlZCh0b2tlbi5wcmVjaXNpb24sIGFwaS5CaWdOdW1iZXIuUk9VTkRfRE9XTik7CiAgICBjb25zdCBtdXRlID0gYXdhaXQgZ2V0TXV0ZShyZXdhcmRQb29sSWQsIGJlbmVmaWNpYXJ5LmFjY291bnQpOwogICAgY29uc3QgcmV3YXJkTG9nID0gewogICAgICByZXdhcmRQb29sSWQsIGF1dGhvcnBlcm0sIHN5bWJvbCwgYWNjb3VudDogYmVuZWZpY2lhcnkuYWNjb3VudCwgcXVhbnRpdHk6IGJlbmVQYXksCiAgICB9OwogICAgaWYgKG11dGUpIHsKICAgICAgcmV3YXJkTG9nLm11dGUgPSB0cnVlOwogICAgfQogICAgYXBpLmVtaXQoJ2JlbmVmaWNpYXJ5UmV3YXJkJywgcmV3YXJkTG9nKTsKICAgIGF3YWl0IHBheVVzZXIoc3ltYm9sLCBiZW5lUGF5LCBiZW5lZmljaWFyeS5hY2NvdW50LCByZXdhcmRQb29sLmNvbmZpZy5zdGFrZWRSZXdhcmRQZXJjZW50YWdlLAogICAgICBtdXRlKTsKICAgIHRvdGFsQmVuZVBheSA9IGFwaS5CaWdOdW1iZXIodG90YWxCZW5lUGF5KS5wbHVzKGJlbmVQYXkpOwogIH0KICByZXR1cm4gdG90YWxCZW5lUGF5Owp9Cgphc3luYyBmdW5jdGlvbiBwYXlPdXRDdXJhdG9ycyhyZXdhcmRQb29sLCB0b2tlbiwgcG9zdCwgY3VyYXRvclBvcnRpb24sIHBhcmFtcykgewogIGNvbnN0IHsKICAgIGF1dGhvcnBlcm0sCiAgICBzeW1ib2wsCiAgICByZXdhcmRQb29sSWQsCiAgfSA9IHBvc3Q7CiAgY29uc3QgewogICAgdm90ZVF1ZXJ5TGltaXQsCiAgfSA9IHBhcmFtczsKICBjb25zdCByZXNwb25zZSA9IHsKICAgIGRvbmU6IGZhbHNlLAogICAgdm90ZXNQcm9jZXNzZWQ6IDAsCiAgfTsKICBjb25zdCB2b3Rlc1RvUGF5b3V0ID0gYXdhaXQgYXBpLmRiLmZpbmQoJ3ZvdGVzJywgeyByZXdhcmRQb29sSWQsIGF1dGhvcnBlcm0gfSwgdm90ZVF1ZXJ5TGltaXQsIDAsIFt7IGluZGV4OiAnYnlUaW1lc3RhbXAnLCBkZXNjZW5kaW5nOiBmYWxzZSB9XSk7CiAgaWYgKHZvdGVzVG9QYXlvdXQubGVuZ3RoID09PSAwKSB7CiAgICByZXNwb25zZS5kb25lID0gdHJ1ZTsKICB9IGVsc2UgewogICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2b3Rlc1RvUGF5b3V0Lmxlbmd0aDsgaSArPSAxKSB7CiAgICAgIGNvbnN0IHZvdGUgPSB2b3Rlc1RvUGF5b3V0W2ldOwogICAgICBpZiAoYXBpLkJpZ051bWJlcih2b3RlLmN1cmF0aW9uV2VpZ2h0KSA+IDApIHsKICAgICAgICBjb25zdCB0b3RhbEN1cmF0aW9uV2VpZ2h0ID0gY2FsY3VsYXRlQ3VyYXRpb25XZWlnaHRSc2hhcmVzKAogICAgICAgICAgcmV3YXJkUG9vbCwgcG9zdC52b3RlUG9zaXRpdmVSc2hhcmVTdW0sCiAgICAgICAgKTsKICAgICAgICBjb25zdCB2b3RlUGF5ID0gYXBpLkJpZ051bWJlcihjdXJhdG9yUG9ydGlvbikubXVsdGlwbGllZEJ5KHZvdGUuY3VyYXRpb25XZWlnaHQpCiAgICAgICAgICAuZGl2aWRlZEJ5KHRvdGFsQ3VyYXRpb25XZWlnaHQpCiAgICAgICAgICAudG9GaXhlZCh0b2tlbi5wcmVjaXNpb24sIGFwaS5CaWdOdW1iZXIuUk9VTkRfRE9XTik7CiAgICAgICAgY29uc3QgbXV0ZSA9IGF3YWl0IGdldE11dGUocmV3YXJkUG9vbElkLCB2b3RlLnZvdGVyKTsKICAgICAgICBjb25zdCByZXdhcmRMb2cgPSB7CiAgICAgICAgICByZXdhcmRQb29sSWQsIGF1dGhvcnBlcm0sIHN5bWJvbCwgYWNjb3VudDogdm90ZS52b3RlciwgcXVhbnRpdHk6IHZvdGVQYXksCiAgICAgICAgfTsKICAgICAgICBpZiAobXV0ZSkgewogICAgICAgICAgcmV3YXJkTG9nLm11dGUgPSB0cnVlOwogICAgICAgIH0KICAgICAgICBhcGkuZW1pdCgnY3VyYXRpb25SZXdhcmQnLCByZXdhcmRMb2cpOwogICAgICAgIGF3YWl0IHBheVVzZXIoc3ltYm9sLCB2b3RlUGF5LCB2b3RlLnZvdGVyLCByZXdhcmRQb29sLmNvbmZpZy5zdGFrZWRSZXdhcmRQZXJjZW50YWdlLCBtdXRlKTsKICAgICAgfQogICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKCd2b3RlcycsIHZvdGUpOwogICAgfQogICAgcmVzcG9uc2Uudm90ZXNQcm9jZXNzZWQgKz0gdm90ZXNUb1BheW91dC5sZW5ndGg7CiAgICBpZiAodm90ZXNUb1BheW91dC5sZW5ndGggPCB2b3RlUXVlcnlMaW1pdCkgewogICAgICByZXNwb25zZS5kb25lID0gdHJ1ZTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3BvbnNlOwp9Cgphc3luYyBmdW5jdGlvbiBwYXlPdXRQb3N0KHJld2FyZFBvb2wsIHRva2VuLCBwb3N0LCBwYXJhbXMpIHsKICBjb25zdCByZXNwb25zZSA9IHsKICAgIHRvdGFsUGF5b3V0VmFsdWU6IDAsCiAgICB2b3Rlc1Byb2Nlc3NlZDogMCwKICAgIGRvbmU6IGZhbHNlLAogIH07CiAgaWYgKHBvc3QuZGVjbGluZVBheW91dCkgewogICAgYXBpLmVtaXQoJ2F1dGhvclJld2FyZCcsIHsKICAgICAgcmV3YXJkUG9vbElkOiBwb3N0LnJld2FyZFBvb2xJZCwKICAgICAgYXV0aG9ycGVybTogcG9zdC5hdXRob3JwZXJtLAogICAgICBzeW1ib2w6IHBvc3Quc3ltYm9sLAogICAgICBhY2NvdW50OiBwb3N0LmF1dGhvciwKICAgICAgcXVhbnRpdHk6ICcwJywKICAgIH0pOwogICAgcmVzcG9uc2UuZG9uZSA9IHRydWU7CiAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKCdwb3N0cycsIHBvc3QpOwogICAgcmV0dXJuIHJlc3BvbnNlOwogIH0KICBjb25zdCBwb3N0Q2xhaW1zID0gY2FsY3VsYXRlV2VpZ2h0UnNoYXJlcyhyZXdhcmRQb29sLCBwb3N0LnZvdGVSc2hhcmVTdW0pOwogIGNvbnN0IHBvc3RQZW5kaW5nVG9rZW4gPSBhcGkuQmlnTnVtYmVyKHJld2FyZFBvb2wuaW50ZXJ2YWxQZW5kaW5nQ2xhaW1zKS5ndCgwKQogICAgPyBhcGkuQmlnTnVtYmVyKHJld2FyZFBvb2wuaW50ZXJ2YWxSZXdhcmRQb29sKS5tdWx0aXBsaWVkQnkocG9zdENsYWltcykKICAgICAgLmRpdmlkZWRCeShyZXdhcmRQb29sLmludGVydmFsUGVuZGluZ0NsYWltcykKICAgICAgLnRvRml4ZWQodG9rZW4ucHJlY2lzaW9uLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pCiAgICA6ICcwJzsKICByZXNwb25zZS50b3RhbFBheW91dFZhbHVlID0gcG9zdFBlbmRpbmdUb2tlbjsKCiAgY29uc3QgY3VyYXRvclBvcnRpb24gPSBhcGkuQmlnTnVtYmVyKHBvc3RQZW5kaW5nVG9rZW4pCiAgICAubXVsdGlwbGllZEJ5KHJld2FyZFBvb2wuY29uZmlnLmN1cmF0aW9uUmV3YXJkUGVyY2VudGFnZSkKICAgIC5kaXZpZGVkQnkoMTAwKQogICAgLnRvRml4ZWQodG9rZW4ucHJlY2lzaW9uLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOwogIGNvbnN0IGF1dGhvckJlbmVQb3J0aW9uID0gYXBpLkJpZ051bWJlcihwb3N0UGVuZGluZ1Rva2VuKS5taW51cyhjdXJhdG9yUG9ydGlvbikKICAgIC50b0ZpeGVkKHRva2VuLnByZWNpc2lvbiwgYXBpLkJpZ051bWJlci5ST1VORF9ET1dOKTsKCiAgY29uc3QgYmVuZWZpY2lhcmllc1BheW91dFZhbHVlID0gYXdhaXQgcGF5T3V0QmVuZWZpY2lhcmllcygKICAgIHJld2FyZFBvb2wsIHRva2VuLCBwb3N0LCBhdXRob3JCZW5lUG9ydGlvbiwKICApOwogIGNvbnN0IGF1dGhvclBvcnRpb24gPSBhcGkuQmlnTnVtYmVyKGF1dGhvckJlbmVQb3J0aW9uKS5taW51cyhiZW5lZmljaWFyaWVzUGF5b3V0VmFsdWUpCiAgICAudG9GaXhlZCh0b2tlbi5wcmVjaXNpb24sIGFwaS5CaWdOdW1iZXIuUk9VTkRfRE9XTik7CgogIGNvbnN0IGN1cmF0b3JQYXlTdGF0dXMgPSBhd2FpdCBwYXlPdXRDdXJhdG9ycyhyZXdhcmRQb29sLCB0b2tlbiwgcG9zdCwgY3VyYXRvclBvcnRpb24sIHBhcmFtcyk7CiAgcmVzcG9uc2Uudm90ZXNQcm9jZXNzZWQgKz0gY3VyYXRvclBheVN0YXR1cy52b3Rlc1Byb2Nlc3NlZDsKICByZXNwb25zZS5kb25lID0gY3VyYXRvclBheVN0YXR1cy5kb25lOwogIGlmIChjdXJhdG9yUGF5U3RhdHVzLmRvbmUpIHsKICAgIGNvbnN0IG11dGUgPSBhd2FpdCBnZXRNdXRlKHBvc3QucmV3YXJkUG9vbElkLCBwb3N0LmF1dGhvcik7CiAgICBjb25zdCByZXdhcmRMb2cgPSB7CiAgICAgIHJld2FyZFBvb2xJZDogcG9zdC5yZXdhcmRQb29sSWQsCiAgICAgIGF1dGhvcnBlcm06IHBvc3QuYXV0aG9ycGVybSwKICAgICAgc3ltYm9sOiBwb3N0LnN5bWJvbCwKICAgICAgYWNjb3VudDogcG9zdC5hdXRob3IsCiAgICAgIHF1YW50aXR5OiBhdXRob3JQb3J0aW9uLAogICAgfTsKICAgIGlmIChtdXRlKSB7CiAgICAgIHJld2FyZExvZy5tdXRlID0gdHJ1ZTsKICAgIH0KICAgIGFwaS5lbWl0KCdhdXRob3JSZXdhcmQnLCByZXdhcmRMb2cpOwogICAgYXdhaXQgcGF5VXNlcihwb3N0LnN5bWJvbCwgYXV0aG9yUG9ydGlvbiwgcG9zdC5hdXRob3IsCiAgICAgIHJld2FyZFBvb2wuY29uZmlnLnN0YWtlZFJld2FyZFBlcmNlbnRhZ2UsIG11dGUpOwogICAgYXdhaXQgYXBpLmRiLnJlbW92ZSgncG9zdHMnLCBwb3N0KTsKICB9CiAgcmV0dXJuIHJlc3BvbnNlOwp9Cgphc3luYyBmdW5jdGlvbiBjb21wdXRlUG9zdFJld2FyZHMocGFyYW1zLCByZXdhcmRQb29sLCB0b2tlbiwgZW5kVGltZXN0YW1wKSB7CiAgY29uc3QgewogICAgbGFzdENsYWltRGVjYXlUaW1lc3RhbXAsCiAgfSA9IHJld2FyZFBvb2w7CiAgY29uc3QgewogICAgbWF4UG9zdHNQcm9jZXNzZWRQZXJSb3VuZCwKICAgIG1heFZvdGVzUHJvY2Vzc2VkUGVyUm91bmQsCiAgfSA9IHBhcmFtczsKCiAgY29uc3QgcG9zdHNUb1BheW91dCA9IGF3YWl0IGFwaS5kYi5maW5kKCdwb3N0cycsCiAgICB7CiAgICAgIHJld2FyZFBvb2xJZDogcmV3YXJkUG9vbC5faWQsCiAgICAgIGNhc2hvdXRUaW1lOiB7ICRndGU6IGxhc3RDbGFpbURlY2F5VGltZXN0YW1wLCAkbHRlOiBlbmRUaW1lc3RhbXAgfSwKICAgIH0sCiAgICBtYXhQb3N0c1Byb2Nlc3NlZFBlclJvdW5kLAogICAgMCwKICAgIFt7IGluZGV4OiAnYnlDYXNob3V0VGltZScsIGRlc2NlbmRpbmc6IGZhbHNlIH0sIHsgaW5kZXg6ICdfaWQnLCBkZXNjZW5kaW5nOiBmYWxzZSB9XSk7CiAgbGV0IGRvbmUgPSBmYWxzZTsKICBsZXQgZGVkdWN0RnJvbVJld2FyZFBvb2wgPSBhcGkuQmlnTnVtYmVyKDApOwogIGxldCB2b3Rlc1Byb2Nlc3NlZCA9IDA7CiAgaWYgKHBvc3RzVG9QYXlvdXQgJiYgcG9zdHNUb1BheW91dC5sZW5ndGggPiAwKSB7CiAgICBsZXQgbGltaXRSZWFjaGVkID0gZmFsc2U7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBvc3RzVG9QYXlvdXQubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgY29uc3QgcG9zdCA9IHBvc3RzVG9QYXlvdXRbaV07CiAgICAgIGNvbnN0IHBvc3RQYXlvdXRSZXNwb25zZSA9IGF3YWl0IHBheU91dFBvc3QocmV3YXJkUG9vbCwgdG9rZW4sIHBvc3QsIHBhcmFtcyk7CiAgICAgIGNvbnN0IHsgdG90YWxQYXlvdXRWYWx1ZSB9ID0gcG9zdFBheW91dFJlc3BvbnNlOwogICAgICB2b3Rlc1Byb2Nlc3NlZCArPSBwb3N0UGF5b3V0UmVzcG9uc2Uudm90ZXNQcm9jZXNzZWQ7CiAgICAgIGlmIChwb3N0UGF5b3V0UmVzcG9uc2UuZG9uZSkgewogICAgICAgIGRlZHVjdEZyb21SZXdhcmRQb29sID0gZGVkdWN0RnJvbVJld2FyZFBvb2wucGx1cyh0b3RhbFBheW91dFZhbHVlKTsKICAgICAgfQogICAgICBpZiAoIXBvc3RQYXlvdXRSZXNwb25zZS5kb25lIHx8IHZvdGVzUHJvY2Vzc2VkID49IG1heFZvdGVzUHJvY2Vzc2VkUGVyUm91bmQpIHsKICAgICAgICBsaW1pdFJlYWNoZWQgPSB0cnVlOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgICBpZiAoIWxpbWl0UmVhY2hlZCAmJiBwb3N0c1RvUGF5b3V0Lmxlbmd0aCA8IG1heFBvc3RzUHJvY2Vzc2VkUGVyUm91bmQpIHsKICAgICAgZG9uZSA9IHRydWU7CiAgICB9CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ24KICAgIHJld2FyZFBvb2wucmV3YXJkUG9vbCA9IGFwaS5CaWdOdW1iZXIocmV3YXJkUG9vbC5yZXdhcmRQb29sKQogICAgICAubWludXMoZGVkdWN0RnJvbVJld2FyZFBvb2wpCiAgICAgIC50b0ZpeGVkKHRva2VuLnByZWNpc2lvbiwgYXBpLkJpZ051bWJlci5ST1VORF9ET1dOKTsKICB9IGVsc2UgewogICAgZG9uZSA9IHRydWU7CiAgfQogIGlmIChkb25lKSB7CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ24KICAgIHJld2FyZFBvb2wubGFzdENsYWltRGVjYXlUaW1lc3RhbXAgPSBlbmRUaW1lc3RhbXA7CiAgfQp9Cgphc3luYyBmdW5jdGlvbiBwb3N0Q2xhaW1zSW5JbnRlcnZhbChwYXJhbXMsIHJld2FyZFBvb2wsIHN0YXJ0LCBlbmQpIHsKICBsZXQgcG9zdE9mZnNldCA9IDA7CiAgbGV0IG5ld1BlbmRpbmdDbGFpbXMgPSBhcGkuQmlnTnVtYmVyKDApOwogIGxldCBwb3N0c1RvUGF5b3V0ID0gYXdhaXQgYXBpLmRiLmZpbmQoJ3Bvc3RzJywKICAgIHsKICAgICAgcmV3YXJkUG9vbElkOiByZXdhcmRQb29sLl9pZCwKICAgICAgY2FzaG91dFRpbWU6IHsgJGd0ZTogc3RhcnQsICRsdGU6IGVuZCB9LAogICAgfSwKICAgIFBPU1RfUVVFUllfTElNSVQsCiAgICBwb3N0T2Zmc2V0LAogICAgW3sgaW5kZXg6ICdieUNhc2hvdXRUaW1lJywgZGVzY2VuZGluZzogZmFsc2UgfSwgeyBpbmRleDogJ19pZCcsIGRlc2NlbmRpbmc6IGZhbHNlIH1dKTsKICB3aGlsZSAocG9zdHNUb1BheW91dCAmJiBwb3N0c1RvUGF5b3V0Lmxlbmd0aCA+IDApIHsKICAgIG5ld1BlbmRpbmdDbGFpbXMgPSBuZXdQZW5kaW5nQ2xhaW1zLnBsdXMoCiAgICAgIHBvc3RzVG9QYXlvdXQucmVkdWNlKCh4LCB5KSA9PiB4LnBsdXMoY2FsY3VsYXRlV2VpZ2h0UnNoYXJlcyhyZXdhcmRQb29sLCB5LnZvdGVSc2hhcmVTdW0pKSwKICAgICAgICBhcGkuQmlnTnVtYmVyKDApKSwKICAgICkKICAgICAgLmRwKFNNVF9QUkVDSVNJT04sIGFwaS5CaWdOdW1iZXIuUk9VTkRfRE9XTik7CiAgICBpZiAocG9zdHNUb1BheW91dC5sZW5ndGggPCBQT1NUX1FVRVJZX0xJTUlUKSB7CiAgICAgIGJyZWFrOwogICAgfQogICAgcG9zdE9mZnNldCArPSBQT1NUX1FVRVJZX0xJTUlUOwogICAgcG9zdHNUb1BheW91dCA9IGF3YWl0IGFwaS5kYi5maW5kKCdwb3N0cycsCiAgICAgIHsKICAgICAgICByZXdhcmRQb29sSWQ6IHJld2FyZFBvb2wuX2lkLAogICAgICAgIGNhc2hvdXRUaW1lOiB7ICRndGU6IHN0YXJ0LCAkbHRlOiBlbmQgfSwKICAgICAgfSwKICAgICAgUE9TVF9RVUVSWV9MSU1JVCwKICAgICAgcG9zdE9mZnNldCwKICAgICAgW3sgaW5kZXg6ICdieUNhc2hvdXRUaW1lJywgZGVzY2VuZGluZzogZmFsc2UgfSwgeyBpbmRleDogJ19pZCcsIGRlc2NlbmRpbmc6IGZhbHNlIH1dKTsKICB9CiAgcmV0dXJuIG5ld1BlbmRpbmdDbGFpbXM7Cn0KCmFzeW5jIGZ1bmN0aW9uIHRva2VuTWFpbnRlbmFuY2UoKSB7CiAgY29uc3QgYmxvY2tEYXRlID0gbmV3IERhdGUoYCR7YXBpLmhpdmVCbG9ja1RpbWVzdGFtcH0uMDAwWmApOwogIGNvbnN0IHRpbWVzdGFtcCA9IGJsb2NrRGF0ZS5nZXRUaW1lKCk7CiAgY29uc3QgcGFyYW1zID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BhcmFtcycsIHt9KTsKICBjb25zdCB7IGxhc3RNYWludGVuYW5jZUJsb2NrLCBsYXN0UHJvY2Vzc2VkUG9vbElkLCBtYWludGVuYW5jZVRva2Vuc1BlckJsb2NrIH0gPSBwYXJhbXM7CiAgaWYgKGxhc3RNYWludGVuYW5jZUJsb2NrID49IGFwaS5ibG9ja051bWJlcikgewogICAgcmV0dXJuOwogIH0KICBwYXJhbXMubGFzdE1haW50ZW5hbmNlQmxvY2sgPSBhcGkuYmxvY2tOdW1iZXI7CgogIC8vIENoZWNrcyBpZiByZWFkeSB0byBwcm9jZXNzIG5leHQgcmV3YXJkIGludGVydmFsCiAgY29uc3QgcmV3YXJkUG9vbFByb2Nlc3NpbmdFeHByZXNzaW9uID0gewogICAgJGx0ZTogWwogICAgICAnJGxhc3RDbGFpbURlY2F5VGltZXN0YW1wJywKICAgICAgewogICAgICAgICRzdWJ0cmFjdDogWwogICAgICAgICAgdGltZXN0YW1wLAogICAgICAgICAgewogICAgICAgICAgICAkbXVsdGlwbHk6IFsKICAgICAgICAgICAgICAnJGNvbmZpZy5yZXdhcmRJbnRlcnZhbFNlY29uZHMnLAogICAgICAgICAgICAgIDEwMDAsCiAgICAgICAgICAgIF0sCiAgICAgICAgICB9LAogICAgICAgIF0sCiAgICAgIH0sCiAgICBdLAogIH07CiAgbGV0IHJld2FyZFBvb2xzID0gYXdhaXQgYXBpLmRiLmZpbmQoJ3Jld2FyZFBvb2xzJywgewogICAgYWN0aXZlOiB0cnVlLAogICAgJGV4cHI6IHJld2FyZFBvb2xQcm9jZXNzaW5nRXhwcmVzc2lvbiwKICAgIF9pZDogeyAkZ3Q6IGxhc3RQcm9jZXNzZWRQb29sSWQgfSwKICB9LCBtYWludGVuYW5jZVRva2Vuc1BlckJsb2NrLCAwLCBbeyBpbmRleDogJ19pZCcsIGRlc2NlbmRpbmc6IGZhbHNlIH1dKTsKICBpZiAoIXJld2FyZFBvb2xzIHx8IHJld2FyZFBvb2xzLmxlbmd0aCA8IG1haW50ZW5hbmNlVG9rZW5zUGVyQmxvY2spIHsKICAgIGlmICghcmV3YXJkUG9vbHMpIHsKICAgICAgcmV3YXJkUG9vbHMgPSBbXTsKICAgIH0KICAgIC8vIGF1Z21lbnQgZnJvbSBiZWdpbm5pbmcKICAgIGNvbnN0IG1vcmVSZXdhcmRQb29scyA9IGF3YWl0IGFwaS5kYi5maW5kKCdyZXdhcmRQb29scycsIHsKICAgICAgYWN0aXZlOiB0cnVlLAogICAgICAkZXhwcjogcmV3YXJkUG9vbFByb2Nlc3NpbmdFeHByZXNzaW9uLAogICAgfSwgbWFpbnRlbmFuY2VUb2tlbnNQZXJCbG9jayAtIHJld2FyZFBvb2xzLmxlbmd0aCwgMCwgW3sgaW5kZXg6ICdfaWQnLCBkZXNjZW5kaW5nOiBmYWxzZSB9XSk7CiAgICBjb25zdCBleGlzdGluZ0lkcyA9IG5ldyBTZXQocmV3YXJkUG9vbHMubWFwKHAgPT4gcC5faWQpKTsKICAgIG1vcmVSZXdhcmRQb29scy5mb3JFYWNoKChtcnApID0+IHsKICAgICAgaWYgKCFleGlzdGluZ0lkcy5oYXMobXJwLl9pZCkpIHsKICAgICAgICByZXdhcmRQb29scy5wdXNoKG1ycCk7CiAgICAgIH0KICAgIH0pOwogIH0KICBpZiAocmV3YXJkUG9vbHMpIHsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmV3YXJkUG9vbHMubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgY29uc3QgcmV3YXJkUG9vbCA9IHJld2FyZFBvb2xzW2ldOwogICAgICBwYXJhbXMubGFzdFByb2Nlc3NlZFBvb2xJZCA9IHJld2FyZFBvb2wuX2lkOwogICAgICBjb25zdCB7CiAgICAgICAgc3ltYm9sLAogICAgICAgIGxhc3RDbGFpbURlY2F5VGltZXN0YW1wLAogICAgICAgIGxhc3RSZXdhcmRUaW1lc3RhbXAsCiAgICAgICAgY29uZmlnLAogICAgICB9ID0gcmV3YXJkUG9vbDsKICAgICAgY29uc3QgewogICAgICAgIHJld2FyZEludGVydmFsU2Vjb25kcywKICAgICAgICByZXdhcmRQZXJJbnRlcnZhbCwKICAgICAgICBjYXNob3V0V2luZG93RGF5cywKICAgICAgfSA9IGNvbmZpZzsKICAgICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ3Rva2VucycsICd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKICAgICAgY29uc3QgcmV3YXJkSW50ZXJ2YWxEdXJhdGlvbk1pbGxpcyA9IHJld2FyZEludGVydmFsU2Vjb25kcyAqIDEwMDA7CiAgICAgIGNvbnN0IG5leHRSZXdhcmRUaW1lc3RhbXAgPSBsYXN0UmV3YXJkVGltZXN0YW1wICsgcmV3YXJkSW50ZXJ2YWxEdXJhdGlvbk1pbGxpczsKICAgICAgY29uc3QgbmV4dENsYWltRGVjYXlUaW1lc3RhbXAgPSBsYXN0Q2xhaW1EZWNheVRpbWVzdGFtcCArIHJld2FyZEludGVydmFsRHVyYXRpb25NaWxsaXM7CiAgICAgIGlmIChuZXh0Q2xhaW1EZWNheVRpbWVzdGFtcCA+PSBuZXh0UmV3YXJkVGltZXN0YW1wKSB7CiAgICAgICAgY29uc3QgcmV3YXJkVG9BZGQgPSBhcGkuQmlnTnVtYmVyKHJld2FyZFBlckludGVydmFsKTsKICAgICAgICBpZiAoYXBpLkJpZ051bWJlcihyZXdhcmRUb0FkZCkuZ3QoMCkpIHsKICAgICAgICAgIGF3YWl0IGFwaS5leGVjdXRlU21hcnRDb250cmFjdCgndG9rZW5zJywgJ2lzc3VlVG9Db250cmFjdCcsCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICBzeW1ib2w6IHJld2FyZFBvb2wuc3ltYm9sLCBxdWFudGl0eTogcmV3YXJkVG9BZGQsIHRvOiAnY29tbWVudHMnLCBpc1NpZ25lZFdpdGhBY3RpdmVLZXk6IHRydWUsCiAgICAgICAgICAgIH0pOwogICAgICAgICAgcmV3YXJkUG9vbC5yZXdhcmRQb29sID0gYXBpLkJpZ051bWJlcihyZXdhcmRQb29sLnJld2FyZFBvb2wpLnBsdXMocmV3YXJkVG9BZGQpCiAgICAgICAgICAgIC50b0ZpeGVkKHRva2VuLnByZWNpc2lvbiwgYXBpLkJpZ051bWJlci5ST1VORF9ET1dOKTsKICAgICAgICB9CiAgICAgICAgLy8gY2xhaW0gYWRqdXN0bWVudHMgKGRlY2F5ICsgcG9zdHMgdG8gcGF5IG91dCBpbiBuZXh0IGludGVydmFsKQogICAgICAgIGNvbnN0IGNsYWltc0RlY2F5UGVyaW9kRGF5cyA9IGNhc2hvdXRXaW5kb3dEYXlzICogMiArIDE7CiAgICAgICAgY29uc3QgYWRqdXN0TnVtZXIgPSBuZXh0UmV3YXJkVGltZXN0YW1wIC0gbGFzdFJld2FyZFRpbWVzdGFtcDsKICAgICAgICBjb25zdCBhZGp1c3REZW5vbSA9IGNsYWltc0RlY2F5UGVyaW9kRGF5cyAqIDI0ICogMzYwMCAqIDEwMDA7CiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduCiAgICAgICAgcmV3YXJkUG9vbC5wZW5kaW5nQ2xhaW1zID0gYXBpLkJpZ051bWJlcihyZXdhcmRQb29sLnBlbmRpbmdDbGFpbXMpCiAgICAgICAgICAubWludXMoYXBpLkJpZ051bWJlcihyZXdhcmRQb29sLnBlbmRpbmdDbGFpbXMpCiAgICAgICAgICAgIC5tdWx0aXBsaWVkQnkoYWRqdXN0TnVtZXIpCiAgICAgICAgICAgIC5kaXZpZGVkQnkoYWRqdXN0RGVub20pKQogICAgICAgICAgLnRvRml4ZWQoU01UX1BSRUNJU0lPTiwgYXBpLkJpZ051bWJlci5ST1VORF9ET1dOKTsKICAgICAgICAvLyBBZGQgcG9zdHMgY2xhaW1zLCBjb21wdXRlIHN1YnNlcXVlbnQgcmV3YXJkcyBiYXNlZCBvbiBpbmNsdXNpb24gaW50byBjbGFpbXMgdG8KICAgICAgICAvLyBlbnN1cmUgaXQgY2Fubm90IHRha2UgbW9yZSBvZiB0aGUgY3VycmVudCBwb29sCiAgICAgICAgcmV3YXJkUG9vbC5wZW5kaW5nQ2xhaW1zID0gYXBpLkJpZ051bWJlcihyZXdhcmRQb29sLnBlbmRpbmdDbGFpbXMpCiAgICAgICAgICAucGx1cygKICAgICAgICAgICAgYXdhaXQgcG9zdENsYWltc0luSW50ZXJ2YWwoCiAgICAgICAgICAgICAgcGFyYW1zLCByZXdhcmRQb29sLCBsYXN0UmV3YXJkVGltZXN0YW1wLCBuZXh0UmV3YXJkVGltZXN0YW1wLAogICAgICAgICAgICApLAogICAgICAgICAgKQogICAgICAgICAgLnRvRml4ZWQoU01UX1BSRUNJU0lPTiwgYXBpLkJpZ051bWJlci5ST1VORF9ET1dOKTsKCiAgICAgICAgcmV3YXJkUG9vbC5sYXN0UmV3YXJkVGltZXN0YW1wID0gbmV4dFJld2FyZFRpbWVzdGFtcDsKICAgICAgICAvLyBjb3B5IGNsYWltcyBhbmQgcmV3YXJkcyBmb3IgY3VycmVudCByZXdhcmQgaW50ZXJ2YWwKICAgICAgICByZXdhcmRQb29sLmludGVydmFsUGVuZGluZ0NsYWltcyA9IHJld2FyZFBvb2wucGVuZGluZ0NsYWltczsKICAgICAgICByZXdhcmRQb29sLmludGVydmFsUmV3YXJkUG9vbCA9IHJld2FyZFBvb2wucmV3YXJkUG9vbDsKICAgICAgfQogICAgICAvLyBDb21wdXRlIHBvc3QgcmV3YXJkcwogICAgICBhd2FpdCBjb21wdXRlUG9zdFJld2FyZHMocGFyYW1zLCByZXdhcmRQb29sLCB0b2tlbiwgbmV4dENsYWltRGVjYXlUaW1lc3RhbXApOwogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdyZXdhcmRQb29scycsIHJld2FyZFBvb2wpOwogICAgfQogIH0KICBhd2FpdCBhcGkuZGIudXBkYXRlKCdwYXJhbXMnLCBwYXJhbXMpOwp9CgphY3Rpb25zLmNyZWF0ZVJld2FyZFBvb2wgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHN5bWJvbCwKICAgIGNvbmZpZywKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKICBpZiAoIWFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAnb3BlcmF0aW9uIG11c3QgYmUgc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykpIHsKICAgIHJldHVybjsKICB9CgogIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CiAgY29uc3QgeyBzZXR1cEZlZSwgbWF4VGFnc1BlclBvb2wgfSA9IHBhcmFtczsKCiAgLy8gZ2V0IGFwaS5zZW5kZXIncyBVVElMSVRZX1RPS0VOX1NZTUJPTCBiYWxhbmNlCiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRlbXBsYXRlLWN1cmx5LWluLXN0cmluZwogIGNvbnN0IHV0aWxpdHlUb2tlbkJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ3Rva2VucycsICdiYWxhbmNlcycsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgc3ltYm9sOiAiQkVFIiB9KTsKCiAgY29uc3QgYXV0aG9yaXplZENyZWF0aW9uID0gYXBpLkJpZ051bWJlcihzZXR1cEZlZSkubHRlKDApIHx8IGFwaS5zZW5kZXIgPT09IGFwaS5vd25lcgogICAgPyB0cnVlCiAgICA6IHV0aWxpdHlUb2tlbkJhbGFuY2UgJiYgYXBpLkJpZ051bWJlcih1dGlsaXR5VG9rZW5CYWxhbmNlLmJhbGFuY2UpLmd0ZShzZXR1cEZlZSk7CgogIGlmICghYXBpLmFzc2VydChhdXRob3JpemVkQ3JlYXRpb24sICd5b3UgbXVzdCBoYXZlIGVub3VnaCB0b2tlbnMgdG8gY292ZXIgdGhlIGNyZWF0aW9uIGZlZScpKSByZXR1cm47CgoKICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lSW5UYWJsZSgndG9rZW5zJywgJ3Rva2VucycsIHsgc3ltYm9sIH0pOwogIGlmICghYXBpLmFzc2VydCh0b2tlbiwgJ3Rva2VuIG5vdCBmb3VuZCcpKSByZXR1cm47CiAgaWYgKCFhcGkuYXNzZXJ0KGNvbmZpZyAmJiB0eXBlb2YgY29uZmlnID09PSAnb2JqZWN0JywgJ2NvbmZpZyBpbnZhbGlkJykpIHJldHVybjsKCiAgY29uc3QgewogICAgcG9zdFJld2FyZEN1cnZlLAogICAgcG9zdFJld2FyZEN1cnZlUGFyYW1ldGVyLAogICAgY3VyYXRpb25SZXdhcmRDdXJ2ZSwKICAgIGN1cmF0aW9uUmV3YXJkQ3VydmVQYXJhbWV0ZXIsCiAgICBjdXJhdGlvblJld2FyZFBlcmNlbnRhZ2UsCiAgICBjYXNob3V0V2luZG93RGF5cywKICAgIHJld2FyZFBlckludGVydmFsLAogICAgcmV3YXJkSW50ZXJ2YWxTZWNvbmRzLAogICAgdm90ZVJlZ2VuZXJhdGlvbkRheXMsCiAgICBkb3dudm90ZVJlZ2VuZXJhdGlvbkRheXMsCiAgICBzdGFrZWRSZXdhcmRQZXJjZW50YWdlLAogICAgdm90ZVBvd2VyQ29uc3VtcHRpb24sCiAgICBkb3dudm90ZVBvd2VyQ29uc3VtcHRpb24sCiAgICB0YWdzLAogIH0gPSBjb25maWc7CgogIGlmICghYXBpLmFzc2VydChwb3N0UmV3YXJkQ3VydmUgJiYgcG9zdFJld2FyZEN1cnZlID09PSAncG93ZXInLCAncG9zdFJld2FyZEN1cnZlIHNob3VsZCBiZSBvbmUgb2Y6IFtwb3dlcl0nKSkgcmV0dXJuOwogIGNvbnN0IHBvc3RFeHBvbmVudCA9IGFwaS5CaWdOdW1iZXIocG9zdFJld2FyZEN1cnZlUGFyYW1ldGVyKTsKICBpZiAoIWFwaS5hc3NlcnQodHlwZW9mIHBvc3RSZXdhcmRDdXJ2ZVBhcmFtZXRlciA9PT0gJ3N0cmluZycgJiYgcG9zdEV4cG9uZW50LmlzRmluaXRlKCkgJiYgcG9zdEV4cG9uZW50Lmd0ZSgnMScpICYmIHBvc3RFeHBvbmVudC5sdGUoJzInKSAmJiBwb3N0RXhwb25lbnQuZHAoKSA8PSAyLCAncG9zdFJld2FyZEN1cnZlUGFyYW1ldGVyIHNob3VsZCBiZSBiZXR3ZWVuICIxIiBhbmQgIjIiIHdpdGggcHJlY2lzaW9uIGF0IG1vc3QgMicpKSByZXR1cm47CgogIGlmICghYXBpLmFzc2VydChjdXJhdGlvblJld2FyZEN1cnZlICYmIGN1cmF0aW9uUmV3YXJkQ3VydmUgPT09ICdwb3dlcicsICdjdXJhdGlvblJld2FyZEN1cnZlIHNob3VsZCBiZSBvbmUgb2Y6IFtwb3dlcl0nKSkgcmV0dXJuOwogIGNvbnN0IGN1cmF0aW9uRXhwb25lbnQgPSBhcGkuQmlnTnVtYmVyKGN1cmF0aW9uUmV3YXJkQ3VydmVQYXJhbWV0ZXIpOwogIGlmICghYXBpLmFzc2VydCh0eXBlb2YgY3VyYXRpb25SZXdhcmRDdXJ2ZVBhcmFtZXRlciA9PT0gJ3N0cmluZycgJiYgY3VyYXRpb25FeHBvbmVudC5pc0Zpbml0ZSgpICYmIGN1cmF0aW9uRXhwb25lbnQuZ3RlKCcwLjUnKSAmJiBjdXJhdGlvbkV4cG9uZW50Lmx0ZSgnMScpICYmIGN1cmF0aW9uRXhwb25lbnQuZHAoKSA8PSAyLCAnY3VyYXRpb25SZXdhcmRDdXJ2ZVBhcmFtZXRlciBjYW4gb25seSBiZSBiZXR3ZWVuICIwLjUiIGFuZCAiMSIgd2l0aCBwcmVjaXNpb24gYXQgbW9zdCAyJykpIHJldHVybjsKCiAgaWYgKCFhcGkuYXNzZXJ0KE51bWJlci5pc0ludGVnZXIoY3VyYXRpb25SZXdhcmRQZXJjZW50YWdlKSAmJiBjdXJhdGlvblJld2FyZFBlcmNlbnRhZ2UgPj0gMCAmJiBjdXJhdGlvblJld2FyZFBlcmNlbnRhZ2UgPD0gMTAwLCAnY3VyYXRpb25SZXdhcmRQZXJjZW50YWdlIHNob3VsZCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gMCBhbmQgMTAwJykpIHJldHVybjsKCiAgaWYgKCFhcGkuYXNzZXJ0KGNhc2hvdXRXaW5kb3dEYXlzICYmIE51bWJlci5pc0ludGVnZXIoY2FzaG91dFdpbmRvd0RheXMpICYmIGNhc2hvdXRXaW5kb3dEYXlzID49IDEgJiYgY2FzaG91dFdpbmRvd0RheXMgPD0gMzAsICdjYXNob3V0V2luZG93RGF5cyBzaG91bGQgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDMwJykpIHJldHVybjsKCiAgY29uc3QgcGFyc2VkUmV3YXJkUGVySW50ZXJ2YWwgPSBhcGkuQmlnTnVtYmVyKHJld2FyZFBlckludGVydmFsKTsKICBpZiAoIWFwaS5hc3NlcnQodHlwZW9mIHJld2FyZFBlckludGVydmFsID09PSAnc3RyaW5nJyAmJiBwYXJzZWRSZXdhcmRQZXJJbnRlcnZhbC5pc0Zpbml0ZSgpICYmIHBhcnNlZFJld2FyZFBlckludGVydmFsLmd0KDApLCAncmV3YXJkUGVySW50ZXJ2YWwgaW52YWxpZCcpCiAgICAgICAgfHwgIWFwaS5hc3NlcnQocGFyc2VkUmV3YXJkUGVySW50ZXJ2YWwuZHAoKSA8PSB0b2tlbi5wcmVjaXNpb24sICd0b2tlbiBwcmVjaXNpb24gbWlzbWF0Y2ggZm9yIHJld2FyZFBlckludGVydmFsJykpIHJldHVybjsKCiAgaWYgKCFhcGkuYXNzZXJ0KHJld2FyZEludGVydmFsU2Vjb25kcyAmJiBOdW1iZXIuaXNJbnRlZ2VyKHJld2FyZEludGVydmFsU2Vjb25kcykgJiYgcmV3YXJkSW50ZXJ2YWxTZWNvbmRzID49IDMgJiYgcmV3YXJkSW50ZXJ2YWxTZWNvbmRzIDw9IDg2NDAwICYmIHJld2FyZEludGVydmFsU2Vjb25kcyAlIDMgPT09IDAsICdyZXdhcmRJbnRlcnZhbFNlY29uZHMgc2hvdWxkIGJlIGFuIGludGVnZXIgYmV0d2VlbiAzIGFuZCA4NjQwMCwgYW5kIGRpdmlzaWJsZSBieSAzJykpIHJldHVybjsKCiAgaWYgKCFhcGkuYXNzZXJ0KHZvdGVSZWdlbmVyYXRpb25EYXlzICYmIE51bWJlci5pc0ludGVnZXIodm90ZVJlZ2VuZXJhdGlvbkRheXMpICYmIHZvdGVSZWdlbmVyYXRpb25EYXlzID49IDEgJiYgdm90ZVJlZ2VuZXJhdGlvbkRheXMgPD0gMzAsICd2b3RlUmVnZW5lcmF0aW9uRGF5cyBzaG91bGQgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDMwJykpIHJldHVybjsKICBpZiAoIWFwaS5hc3NlcnQoZG93bnZvdGVSZWdlbmVyYXRpb25EYXlzICYmIE51bWJlci5pc0ludGVnZXIoZG93bnZvdGVSZWdlbmVyYXRpb25EYXlzKSAmJiBkb3dudm90ZVJlZ2VuZXJhdGlvbkRheXMgPj0gMSAmJiBkb3dudm90ZVJlZ2VuZXJhdGlvbkRheXMgPD0gMzAsICdkb3dudm90ZVJlZ2VuZXJhdGlvbkRheXMgc2hvdWxkIGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAzMCcpKSByZXR1cm47CiAgaWYgKCFhcGkuYXNzZXJ0KE51bWJlci5pc0ludGVnZXIoc3Rha2VkUmV3YXJkUGVyY2VudGFnZSkgJiYgc3Rha2VkUmV3YXJkUGVyY2VudGFnZSA+PSAwICYmIHN0YWtlZFJld2FyZFBlcmNlbnRhZ2UgPD0gMTAwLCAnc3Rha2VkUmV3YXJkUGVyY2VudGFnZSBzaG91bGQgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDAgYW5kIDEwMCcpKSByZXR1cm47CiAgaWYgKCFhcGkuYXNzZXJ0KHZvdGVQb3dlckNvbnN1bXB0aW9uICYmIE51bWJlci5pc0ludGVnZXIodm90ZVBvd2VyQ29uc3VtcHRpb24pICYmIHZvdGVQb3dlckNvbnN1bXB0aW9uID49IDEgJiYgdm90ZVBvd2VyQ29uc3VtcHRpb24gPD0gMTAwMDAsICd2b3RlUG93ZXJDb25zdW1wdGlvbiBzaG91bGQgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDEwMDAwJykpIHJldHVybjsKICBpZiAoIWFwaS5hc3NlcnQoZG93bnZvdGVQb3dlckNvbnN1bXB0aW9uICYmIE51bWJlci5pc0ludGVnZXIoZG93bnZvdGVQb3dlckNvbnN1bXB0aW9uKSAmJiBkb3dudm90ZVBvd2VyQ29uc3VtcHRpb24gPj0gMSAmJiBkb3dudm90ZVBvd2VyQ29uc3VtcHRpb24gPD0gMTAwMDAsICdkb3dudm90ZVBvd2VyQ29uc3VtcHRpb24gc2hvdWxkIGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAxMDAwMCcpKSByZXR1cm47CgogIGlmICghYXBpLmFzc2VydChBcnJheS5pc0FycmF5KHRhZ3MpICYmIHRhZ3MubGVuZ3RoID49IDEgJiYgdGFncy5sZW5ndGggPD0gbWF4VGFnc1BlclBvb2wgJiYgdGFncy5ldmVyeSh0ID0+IHR5cGVvZiB0ID09PSAnc3RyaW5nJyksIGB0YWdzIHNob3VsZCBiZSBhIG5vbi1lbXB0eSBhcnJheSBvZiBzdHJpbmdzIG9mIGxlbmd0aCBhdCBtb3N0ICR7bWF4VGFnc1BlclBvb2x9YCkpIHJldHVybjsKCiAgLy8gZm9yIG5vdywgcmVzdHJpY3QgdG8gMSBwb29sIHBlciBzeW1ib2wsIGFuZCBjcmVhdG9yIG11c3QgYmUgaXNzdWVyLgogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10ZW1wbGF0ZS1jdXJseS1pbi1zdHJpbmcKICBpZiAoIWFwaS5hc3NlcnQoYXBpLnNlbmRlciA9PT0gdG9rZW4uaXNzdWVyIHx8IChhcGkuc2VuZGVyID09PSBhcGkub3duZXIgJiYgdG9rZW4uc3ltYm9sID09PSAiQkVFIiksICdtdXN0IGJlIGlzc3VlciBvZiB0b2tlbicpKSByZXR1cm47CiAgaWYgKCFhcGkuYXNzZXJ0KHRva2VuLnN0YWtpbmdFbmFibGVkLCAndG9rZW4gbXVzdCBoYXZlIHN0YWtpbmcgZW5hYmxlZCcpKSByZXR1cm47CgogIGNvbnN0IGV4aXN0aW5nUmV3YXJkUG9vbCA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdyZXdhcmRQb29scycsIHsgc3ltYm9sIH0pOwogIGlmICghYXBpLmFzc2VydCghZXhpc3RpbmdSZXdhcmRQb29sLCAnY2Fubm90IGNyZWF0ZSBtdWx0aXBsZSByZXdhcmQgcG9vbHMgcGVyIHRva2VuJykpIHJldHVybjsKCiAgY29uc3QgYmxvY2tEYXRlID0gbmV3IERhdGUoYCR7YXBpLmhpdmVCbG9ja1RpbWVzdGFtcH0uMDAwWmApOwogIGNvbnN0IHRpbWVzdGFtcCA9IGJsb2NrRGF0ZS5nZXRUaW1lKCk7CgogIGNvbnN0IHJld2FyZFBvb2wgPSB7CiAgICBzeW1ib2wsCiAgICByZXdhcmRQb29sOiAnMCcsCiAgICBsYXN0UmV3YXJkVGltZXN0YW1wOiB0aW1lc3RhbXAsCiAgICBsYXN0Q2xhaW1EZWNheVRpbWVzdGFtcDogdGltZXN0YW1wLAogICAgY3JlYXRlZFRpbWVzdGFtcDogdGltZXN0YW1wLAogICAgY29uZmlnOiB7CiAgICAgIHBvc3RSZXdhcmRDdXJ2ZSwKICAgICAgcG9zdFJld2FyZEN1cnZlUGFyYW1ldGVyLAogICAgICBjdXJhdGlvblJld2FyZEN1cnZlLAogICAgICBjdXJhdGlvblJld2FyZEN1cnZlUGFyYW1ldGVyLAogICAgICBjdXJhdGlvblJld2FyZFBlcmNlbnRhZ2UsCiAgICAgIGNhc2hvdXRXaW5kb3dEYXlzLAogICAgICByZXdhcmRQZXJJbnRlcnZhbCwKICAgICAgcmV3YXJkSW50ZXJ2YWxTZWNvbmRzLAogICAgICB2b3RlUmVnZW5lcmF0aW9uRGF5cywKICAgICAgZG93bnZvdGVSZWdlbmVyYXRpb25EYXlzLAogICAgICBzdGFrZWRSZXdhcmRQZXJjZW50YWdlLAogICAgICB2b3RlUG93ZXJDb25zdW1wdGlvbiwKICAgICAgZG93bnZvdGVQb3dlckNvbnN1bXB0aW9uLAogICAgICB0YWdzLAogICAgfSwKICAgIHBlbmRpbmdDbGFpbXM6ICcwJywKICAgIGFjdGl2ZTogdHJ1ZSwKICB9OwogIGNvbnN0IGluc2VydGVkUmV3YXJkUG9vbCA9IGF3YWl0IGFwaS5kYi5pbnNlcnQoJ3Jld2FyZFBvb2xzJywgcmV3YXJkUG9vbCk7CiAgLy8gYnVybiB0aGUgdG9rZW4gY3JlYXRpb24gZmVlcwogIGlmIChhcGkuc2VuZGVyICE9PSBhcGkub3duZXIgJiYgYXBpLkJpZ051bWJlcihzZXR1cEZlZSkuZ3QoMCkpIHsKICAgIGF3YWl0IGFwaS5leGVjdXRlU21hcnRDb250cmFjdCgndG9rZW5zJywgJ3RyYW5zZmVyJywgewogICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdGVtcGxhdGUtY3VybHktaW4tc3RyaW5nCiAgICAgIHRvOiAnbnVsbCcsIHN5bWJvbDogIkJFRSIsIHF1YW50aXR5OiBzZXR1cEZlZSwgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogICAgfSk7CiAgfQogIGFwaS5lbWl0KCdjcmVhdGVSZXdhcmRQb29sJywgeyBfaWQ6IGluc2VydGVkUmV3YXJkUG9vbC5faWQgfSk7Cn07CgphY3Rpb25zLnVwZGF0ZVJld2FyZFBvb2wgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHJld2FyZFBvb2xJZCwKICAgIGNvbmZpZywKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKICBpZiAoIWFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAnb3BlcmF0aW9uIG11c3QgYmUgc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykpIHsKICAgIHJldHVybjsKICB9CiAgLy8gZ2V0IGNvbnRyYWN0IHBhcmFtcwogIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CiAgY29uc3QgeyB1cGRhdGVGZWUsIG1heFRhZ3NQZXJQb29sIH0gPSBwYXJhbXM7CiAgLy8gZ2V0IGFwaS5zZW5kZXIncyBVVElMSVRZX1RPS0VOX1NZTUJPTCBiYWxhbmNlCiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRlbXBsYXRlLWN1cmx5LWluLXN0cmluZwogIGNvbnN0IHV0aWxpdHlUb2tlbkJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ3Rva2VucycsICdiYWxhbmNlcycsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgc3ltYm9sOiAiQkVFIiB9KTsKCiAgY29uc3QgYXV0aG9yaXplZCA9IGFwaS5CaWdOdW1iZXIodXBkYXRlRmVlKS5sdGUoMCkgfHwgYXBpLnNlbmRlciA9PT0gYXBpLm93bmVyCiAgICA/IHRydWUKICAgIDogdXRpbGl0eVRva2VuQmFsYW5jZSAmJiBhcGkuQmlnTnVtYmVyKHV0aWxpdHlUb2tlbkJhbGFuY2UuYmFsYW5jZSkuZ3RlKHVwZGF0ZUZlZSk7CgogIGlmICghYXBpLmFzc2VydChhdXRob3JpemVkLCAneW91IG11c3QgaGF2ZSBlbm91Z2ggdG9rZW5zIHRvIGNvdmVyIHRoZSB1cGRhdGUgZmVlJykpIHJldHVybjsKCiAgaWYgKCFhcGkuYXNzZXJ0KGNvbmZpZyAmJiB0eXBlb2YgY29uZmlnID09PSAnb2JqZWN0JywgJ2NvbmZpZyBpbnZhbGlkJykpIHJldHVybjsKCiAgY29uc3QgewogICAgcG9zdFJld2FyZEN1cnZlLAogICAgcG9zdFJld2FyZEN1cnZlUGFyYW1ldGVyLAogICAgY3VyYXRpb25SZXdhcmRDdXJ2ZSwKICAgIGN1cmF0aW9uUmV3YXJkQ3VydmVQYXJhbWV0ZXIsCiAgICBjdXJhdGlvblJld2FyZFBlcmNlbnRhZ2UsCiAgICBjYXNob3V0V2luZG93RGF5cywKICAgIHJld2FyZFBlckludGVydmFsLAogICAgcmV3YXJkSW50ZXJ2YWxTZWNvbmRzLAogICAgdm90ZVJlZ2VuZXJhdGlvbkRheXMsCiAgICBkb3dudm90ZVJlZ2VuZXJhdGlvbkRheXMsCiAgICBzdGFrZWRSZXdhcmRQZXJjZW50YWdlLAogICAgdm90ZVBvd2VyQ29uc3VtcHRpb24sCiAgICBkb3dudm90ZVBvd2VyQ29uc3VtcHRpb24sCiAgICB0YWdzLAogIH0gPSBjb25maWc7CgogIGNvbnN0IGV4aXN0aW5nUmV3YXJkUG9vbCA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdyZXdhcmRQb29scycsIHsgX2lkOiByZXdhcmRQb29sSWQgfSk7CiAgaWYgKCFhcGkuYXNzZXJ0KGV4aXN0aW5nUmV3YXJkUG9vbCwgJ3Jld2FyZCBwb29sIG5vdCBmb3VuZCcpKSByZXR1cm47CgogIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAndG9rZW5zJywgeyBzeW1ib2w6IGV4aXN0aW5nUmV3YXJkUG9vbC5zeW1ib2wgfSk7CgogIGlmICghYXBpLmFzc2VydChwb3N0UmV3YXJkQ3VydmUgJiYgcG9zdFJld2FyZEN1cnZlID09PSAncG93ZXInLCAncG9zdFJld2FyZEN1cnZlIHNob3VsZCBiZSBvbmUgb2Y6IFtwb3dlcl0nKSkgcmV0dXJuOwogIGV4aXN0aW5nUmV3YXJkUG9vbC5jb25maWcucG9zdFJld2FyZEN1cnZlID0gcG9zdFJld2FyZEN1cnZlOwoKICBjb25zdCBwb3N0RXhwb25lbnQgPSBhcGkuQmlnTnVtYmVyKHBvc3RSZXdhcmRDdXJ2ZVBhcmFtZXRlcik7CiAgaWYgKCFhcGkuYXNzZXJ0KHR5cGVvZiBwb3N0UmV3YXJkQ3VydmVQYXJhbWV0ZXIgPT09ICdzdHJpbmcnICYmIHBvc3RFeHBvbmVudC5pc0Zpbml0ZSgpICYmIHBvc3RFeHBvbmVudC5ndGUoJzEnKSAmJiBwb3N0RXhwb25lbnQubHRlKCcyJykgJiYgcG9zdEV4cG9uZW50LmRwKCkgPD0gMiwgJ3Bvc3RSZXdhcmRDdXJ2ZVBhcmFtZXRlciBzaG91bGQgYmUgYmV0d2VlbiAiMSIgYW5kICIyIiB3aXRoIHByZWNpc2lvbiBhdCBtb3N0IDInKSkgcmV0dXJuOwogIGV4aXN0aW5nUmV3YXJkUG9vbC5jb25maWcucG9zdFJld2FyZEN1cnZlUGFyYW1ldGVyID0gcG9zdFJld2FyZEN1cnZlUGFyYW1ldGVyOwoKICBpZiAoIWFwaS5hc3NlcnQoY3VyYXRpb25SZXdhcmRDdXJ2ZSAmJiBjdXJhdGlvblJld2FyZEN1cnZlID09PSAncG93ZXInLCAnY3VyYXRpb25SZXdhcmRDdXJ2ZSBzaG91bGQgYmUgb25lIG9mOiBbcG93ZXJdJykpIHJldHVybjsKICBjb25zdCBjdXJhdGlvbkV4cG9uZW50ID0gYXBpLkJpZ051bWJlcihjdXJhdGlvblJld2FyZEN1cnZlUGFyYW1ldGVyKTsKICBpZiAoIWFwaS5hc3NlcnQodHlwZW9mIGN1cmF0aW9uUmV3YXJkQ3VydmVQYXJhbWV0ZXIgPT09ICdzdHJpbmcnICYmIGN1cmF0aW9uRXhwb25lbnQuaXNGaW5pdGUoKSAmJiBjdXJhdGlvbkV4cG9uZW50Lmd0ZSgnMC41JykgJiYgY3VyYXRpb25FeHBvbmVudC5sdGUoJzEnKSAmJiBjdXJhdGlvbkV4cG9uZW50LmRwKCkgPD0gMiwgJ2N1cmF0aW9uUmV3YXJkQ3VydmVQYXJhbWV0ZXIgY2FuIG9ubHkgYmUgYmV0d2VlbiAiMC41IiBhbmQgIjEiIHdpdGggcHJlY2lzaW9uIGF0IG1vc3QgMicpKSByZXR1cm47CiAgZXhpc3RpbmdSZXdhcmRQb29sLmNvbmZpZy5jdXJhdGlvblJld2FyZEN1cnZlUGFyYW1ldGVyID0gY3VyYXRpb25SZXdhcmRDdXJ2ZVBhcmFtZXRlcjsKCiAgaWYgKCFhcGkuYXNzZXJ0KE51bWJlci5pc0ludGVnZXIoY3VyYXRpb25SZXdhcmRQZXJjZW50YWdlKSAmJiBjdXJhdGlvblJld2FyZFBlcmNlbnRhZ2UgPj0gMCAmJiBjdXJhdGlvblJld2FyZFBlcmNlbnRhZ2UgPD0gMTAwLCAnY3VyYXRpb25SZXdhcmRQZXJjZW50YWdlIHNob3VsZCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gMCBhbmQgMTAwJykpIHJldHVybjsKICBleGlzdGluZ1Jld2FyZFBvb2wuY29uZmlnLmN1cmF0aW9uUmV3YXJkUGVyY2VudGFnZSA9IGN1cmF0aW9uUmV3YXJkUGVyY2VudGFnZTsKCiAgaWYgKCFhcGkuYXNzZXJ0KGNhc2hvdXRXaW5kb3dEYXlzICYmIE51bWJlci5pc0ludGVnZXIoY2FzaG91dFdpbmRvd0RheXMpICYmIGNhc2hvdXRXaW5kb3dEYXlzID49IDEgJiYgY2FzaG91dFdpbmRvd0RheXMgPD0gMzAsICdjYXNob3V0V2luZG93RGF5cyBzaG91bGQgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDMwJykpIHJldHVybjsKICBleGlzdGluZ1Jld2FyZFBvb2wuY29uZmlnLmNhc2hvdXRXaW5kb3dEYXlzID0gY2FzaG91dFdpbmRvd0RheXM7CgogIGNvbnN0IHBhcnNlZFJld2FyZFBlckludGVydmFsID0gYXBpLkJpZ051bWJlcihyZXdhcmRQZXJJbnRlcnZhbCk7CiAgaWYgKCFhcGkuYXNzZXJ0KHR5cGVvZiByZXdhcmRQZXJJbnRlcnZhbCA9PT0gJ3N0cmluZycgJiYgcGFyc2VkUmV3YXJkUGVySW50ZXJ2YWwuaXNGaW5pdGUoKSAmJiBwYXJzZWRSZXdhcmRQZXJJbnRlcnZhbC5ndCgwKSwgJ3Jld2FyZFBlckludGVydmFsIGludmFsaWQnKQogICAgICAgIHx8ICFhcGkuYXNzZXJ0KHBhcnNlZFJld2FyZFBlckludGVydmFsLmRwKCkgPD0gdG9rZW4ucHJlY2lzaW9uLCAndG9rZW4gcHJlY2lzaW9uIG1pc21hdGNoIGZvciByZXdhcmRQZXJJbnRlcnZhbCcpKSByZXR1cm47CiAgZXhpc3RpbmdSZXdhcmRQb29sLmNvbmZpZy5yZXdhcmRQZXJJbnRlcnZhbCA9IHJld2FyZFBlckludGVydmFsOwoKICBpZiAoIWFwaS5hc3NlcnQocmV3YXJkSW50ZXJ2YWxTZWNvbmRzICYmIE51bWJlci5pc0ludGVnZXIocmV3YXJkSW50ZXJ2YWxTZWNvbmRzKSAmJiByZXdhcmRJbnRlcnZhbFNlY29uZHMgPj0gMyAmJiByZXdhcmRJbnRlcnZhbFNlY29uZHMgPD0gODY0MDAgJiYgcmV3YXJkSW50ZXJ2YWxTZWNvbmRzICUgMyA9PT0gMCwgJ3Jld2FyZEludGVydmFsU2Vjb25kcyBzaG91bGQgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDMgYW5kIDg2NDAwLCBhbmQgZGl2aXNpYmxlIGJ5IDMnKSkgcmV0dXJuOwogIGV4aXN0aW5nUmV3YXJkUG9vbC5jb25maWcucmV3YXJkSW50ZXJ2YWxTZWNvbmRzID0gcmV3YXJkSW50ZXJ2YWxTZWNvbmRzOwoKICBpZiAoIWFwaS5hc3NlcnQodm90ZVJlZ2VuZXJhdGlvbkRheXMgJiYgTnVtYmVyLmlzSW50ZWdlcih2b3RlUmVnZW5lcmF0aW9uRGF5cykgJiYgdm90ZVJlZ2VuZXJhdGlvbkRheXMgPj0gMSAmJiB2b3RlUmVnZW5lcmF0aW9uRGF5cyA8PSAzMCwgJ3ZvdGVSZWdlbmVyYXRpb25EYXlzIHNob3VsZCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gMSBhbmQgMzAnKSkgcmV0dXJuOwogIGV4aXN0aW5nUmV3YXJkUG9vbC5jb25maWcudm90ZVJlZ2VuZXJhdGlvbkRheXMgPSB2b3RlUmVnZW5lcmF0aW9uRGF5czsKCiAgaWYgKCFhcGkuYXNzZXJ0KGRvd252b3RlUmVnZW5lcmF0aW9uRGF5cyAmJiBOdW1iZXIuaXNJbnRlZ2VyKGRvd252b3RlUmVnZW5lcmF0aW9uRGF5cykgJiYgZG93bnZvdGVSZWdlbmVyYXRpb25EYXlzID49IDEgJiYgZG93bnZvdGVSZWdlbmVyYXRpb25EYXlzIDw9IDMwLCAnZG93bnZvdGVSZWdlbmVyYXRpb25EYXlzIHNob3VsZCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gMSBhbmQgMzAnKSkgcmV0dXJuOwogIGV4aXN0aW5nUmV3YXJkUG9vbC5jb25maWcuZG93bnZvdGVSZWdlbmVyYXRpb25EYXlzID0gZG93bnZvdGVSZWdlbmVyYXRpb25EYXlzOwoKICBpZiAoIWFwaS5hc3NlcnQoTnVtYmVyLmlzSW50ZWdlcihzdGFrZWRSZXdhcmRQZXJjZW50YWdlKSAmJiBzdGFrZWRSZXdhcmRQZXJjZW50YWdlID49IDAgJiYgc3Rha2VkUmV3YXJkUGVyY2VudGFnZSA8PSAxMDAsICdzdGFrZWRSZXdhcmRQZXJjZW50YWdlIHNob3VsZCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gMCBhbmQgMTAwJykpIHJldHVybjsKICBleGlzdGluZ1Jld2FyZFBvb2wuY29uZmlnLnN0YWtlZFJld2FyZFBlcmNlbnRhZ2UgPSBzdGFrZWRSZXdhcmRQZXJjZW50YWdlOwoKICBpZiAoIWFwaS5hc3NlcnQodm90ZVBvd2VyQ29uc3VtcHRpb24gJiYgTnVtYmVyLmlzSW50ZWdlcih2b3RlUG93ZXJDb25zdW1wdGlvbikgJiYgdm90ZVBvd2VyQ29uc3VtcHRpb24gPj0gMSAmJiB2b3RlUG93ZXJDb25zdW1wdGlvbiA8PSAxMDAwMCwgJ3ZvdGVQb3dlckNvbnN1bXB0aW9uIHNob3VsZCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gMSBhbmQgMTAwMDAnKSkgcmV0dXJuOwogIGV4aXN0aW5nUmV3YXJkUG9vbC5jb25maWcudm90ZVBvd2VyQ29uc3VtcHRpb24gPSB2b3RlUG93ZXJDb25zdW1wdGlvbjsKCiAgaWYgKCFhcGkuYXNzZXJ0KGRvd252b3RlUG93ZXJDb25zdW1wdGlvbiAmJiBOdW1iZXIuaXNJbnRlZ2VyKGRvd252b3RlUG93ZXJDb25zdW1wdGlvbikgJiYgZG93bnZvdGVQb3dlckNvbnN1bXB0aW9uID49IDEgJiYgZG93bnZvdGVQb3dlckNvbnN1bXB0aW9uIDw9IDEwMDAwLCAnZG93bnZvdGVQb3dlckNvbnN1bXB0aW9uIHNob3VsZCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gMSBhbmQgMTAwMDAnKSkgcmV0dXJuOwogIGV4aXN0aW5nUmV3YXJkUG9vbC5jb25maWcuZG93bnZvdGVQb3dlckNvbnN1bXB0aW9uID0gZG93bnZvdGVQb3dlckNvbnN1bXB0aW9uOwoKICBpZiAoIWFwaS5hc3NlcnQoQXJyYXkuaXNBcnJheSh0YWdzKSAmJiB0YWdzLmxlbmd0aCA+PSAxICYmIHRhZ3MubGVuZ3RoIDw9IG1heFRhZ3NQZXJQb29sICYmIHRhZ3MuZXZlcnkodCA9PiB0eXBlb2YgdCA9PT0gJ3N0cmluZycpLCBgdGFncyBzaG91bGQgYmUgYSBub24tZW1wdHkgYXJyYXkgb2Ygc3RyaW5ncyBvZiBsZW5ndGggYXQgbW9zdCAke21heFRhZ3NQZXJQb29sfWApKSByZXR1cm47CiAgZXhpc3RpbmdSZXdhcmRQb29sLmNvbmZpZy50YWdzID0gdGFnczsKCiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRlbXBsYXRlLWN1cmx5LWluLXN0cmluZwogIGlmICghYXBpLmFzc2VydChhcGkuc2VuZGVyID09PSB0b2tlbi5pc3N1ZXIgfHwgKGFwaS5zZW5kZXIgPT09IGFwaS5vd25lciAmJiB0b2tlbi5zeW1ib2wgPT09ICJCRUUiKSwgJ211c3QgYmUgaXNzdWVyIG9mIHRva2VuJykpIHJldHVybjsKCiAgLy8gYnVybiB0aGUgZmVlcwogIGlmIChhcGkuc2VuZGVyICE9PSBhcGkub3duZXIgJiYgYXBpLkJpZ051bWJlcih1cGRhdGVGZWUpLmd0KDApKSB7CiAgICBhd2FpdCBhcGkuZXhlY3V0ZVNtYXJ0Q29udHJhY3QoJ3Rva2VucycsICd0cmFuc2ZlcicsIHsKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRlbXBsYXRlLWN1cmx5LWluLXN0cmluZwogICAgICB0bzogJ251bGwnLCBzeW1ib2w6ICJCRUUiLCBxdWFudGl0eTogdXBkYXRlRmVlLCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgICB9KTsKICB9CgogIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Jld2FyZFBvb2xzJywgZXhpc3RpbmdSZXdhcmRQb29sKTsKfTsKCmFjdGlvbnMuc2V0QWN0aXZlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICByZXdhcmRQb29sSWQsCiAgICBhY3RpdmUsCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CiAgaWYgKCFhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ29wZXJhdGlvbiBtdXN0IGJlIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpKSB7CiAgICByZXR1cm47CiAgfQoKICBjb25zdCBleGlzdGluZ1Jld2FyZFBvb2wgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgncmV3YXJkUG9vbHMnLCB7IF9pZDogcmV3YXJkUG9vbElkIH0pOwogIGlmICghYXBpLmFzc2VydChleGlzdGluZ1Jld2FyZFBvb2wsICdyZXdhcmQgcG9vbCBub3QgZm91bmQnKSkgcmV0dXJuOwogIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAndG9rZW5zJywgeyBzeW1ib2w6IGV4aXN0aW5nUmV3YXJkUG9vbC5zeW1ib2wgfSk7CiAgaWYgKCFhcGkuYXNzZXJ0KGFwaS5zZW5kZXIgPT09IHRva2VuLmlzc3VlciB8fCBhcGkuc2VuZGVyID09PSBhcGkub3duZXIsICdtdXN0IGJlIGlzc3VlciBvZiB0b2tlbicpKSByZXR1cm47CgogIGV4aXN0aW5nUmV3YXJkUG9vbC5hY3RpdmUgPSBhY3RpdmU7CiAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncmV3YXJkUG9vbHMnLCBleGlzdGluZ1Jld2FyZFBvb2wpOwp9OwoKYWN0aW9ucy5zZXRNdXRlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICByZXdhcmRQb29sSWQsCiAgICBhY2NvdW50LAogICAgbXV0ZSwKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKCFhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ29wZXJhdGlvbiBtdXN0IGJlIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpKSB7CiAgICByZXR1cm47CiAgfQogIGNvbnN0IGV4aXN0aW5nUmV3YXJkUG9vbCA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdyZXdhcmRQb29scycsIHsgX2lkOiByZXdhcmRQb29sSWQgfSk7CiAgaWYgKCFhcGkuYXNzZXJ0KGV4aXN0aW5nUmV3YXJkUG9vbCwgJ3Jld2FyZCBwb29sIG5vdCBmb3VuZCcpKSByZXR1cm47CiAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ3Rva2VucycsICd0b2tlbnMnLCB7IHN5bWJvbDogZXhpc3RpbmdSZXdhcmRQb29sLnN5bWJvbCB9KTsKICBpZiAoIWFwaS5hc3NlcnQoYXBpLnNlbmRlciA9PT0gdG9rZW4uaXNzdWVyIHx8IGFwaS5zZW5kZXIgPT09IGFwaS5vd25lciwgJ211c3QgYmUgaXNzdWVyIG9mIHRva2VuJykpIHJldHVybjsKICBpZiAoIWFwaS5hc3NlcnQoYXBpLmlzVmFsaWRBY2NvdW50TmFtZShhY2NvdW50KSwgJ2ludmFsaWQgYWNjb3VudCcpKSByZXR1cm47CiAgaWYgKCFhcGkuYXNzZXJ0KHR5cGVvZiBtdXRlID09PSAnYm9vbGVhbicsICdtdXRlIG11c3QgYmUgYSBib29sZWFuJykpIHJldHVybjsKCiAgY29uc3Qgdm90aW5nUG93ZXIgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndm90aW5nUG93ZXInLCB7IHJld2FyZFBvb2xJZCwgYWNjb3VudCB9KTsKICBpZiAoIXZvdGluZ1Bvd2VyKSB7CiAgICBjb25zdCBibG9ja0RhdGUgPSBuZXcgRGF0ZShgJHthcGkuaGl2ZUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgICBjb25zdCB0aW1lc3RhbXAgPSBibG9ja0RhdGUuZ2V0VGltZSgpOwogICAgY29uc3QgbmV3Vm90aW5nUG93ZXIgPSB7CiAgICAgIHJld2FyZFBvb2xJZCwKICAgICAgYWNjb3VudCwKICAgICAgbGFzdFZvdGVUaW1lc3RhbXA6IHRpbWVzdGFtcCwKICAgICAgdm90aW5nUG93ZXI6IE1BWF9WT1RJTkdfUE9XRVIsCiAgICAgIGRvd252b3RpbmdQb3dlcjogTUFYX1ZPVElOR19QT1dFUiwKICAgICAgbXV0ZSwKICAgIH07CiAgICBhd2FpdCBhcGkuZGIuaW5zZXJ0KCd2b3RpbmdQb3dlcicsIG5ld1ZvdGluZ1Bvd2VyKTsKICB9IGVsc2UgewogICAgdm90aW5nUG93ZXIubXV0ZSA9IG11dGU7CiAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd2b3RpbmdQb3dlcicsIHZvdGluZ1Bvd2VyKTsKICB9Cn07Cgphc3luYyBmdW5jdGlvbiBnZXRSZXdhcmRQb29sSWRzKHBheWxvYWQpIHsKICBjb25zdCB7CiAgICByZXdhcmRQb29scywKICAgIGpzb25NZXRhZGF0YSwKICAgIHBhcmVudEF1dGhvciwKICAgIHBhcmVudFBlcm1saW5rLAogIH0gPSBwYXlsb2FkOwoKICBjb25zdCBwYXJhbXMgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgncGFyYW1zJywge30pOwoKICAvLyBDaGVjayBpZiBpdCBpcyBhIHJlcGx5LCBhbmQgaW5oZXJpdCB0aGUgc2V0dGluZ3MKICAvLyBmcm9tIHRoZSBwYXJlbnQuCiAgaWYgKHBhcmVudEF1dGhvciAmJiBwYXJlbnRQZXJtbGluaykgewogICAgY29uc3QgcGFyZW50QXV0aG9ycGVybSA9IGBAJHtwYXJlbnRBdXRob3J9LyR7cGFyZW50UGVybWxpbmt9YDsKICAgIGNvbnN0IHBhcmVudFBvc3RNZXRhZGF0YSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwb3N0TWV0YWRhdGEnLCB7IGF1dGhvcnBlcm06IHBhcmVudEF1dGhvcnBlcm0gfSk7CiAgICBpZiAocGFyZW50UG9zdE1ldGFkYXRhKSB7CiAgICAgIHJldHVybiBwYXJlbnRQb3N0TWV0YWRhdGEucmV3YXJkUG9vbElkczsKICAgIH0KICAgIC8vIFRoaXMgZmFsbGJhY2sgaXMgbmVlZGVkIHdoaWxlIHdlIHBvcHVsYXRlIG1ldGFkYXRhLCBjYW4gYmUgcmVtb3ZlZCBhZnRlcgogICAgLy8gYWxsIG91c3RhbmRpbmcgcG9zdHMgYXJlIGFsc28gaW4gbWV0YWRhdGEuCiAgICAvLyBDYW4gb25seSByZXR1cm4gcGFyYW1zLm1heFBvb2xzUGVyUG9zdCAoPDEwMDApIHBvc3RzCiAgICBjb25zdCBwYXJlbnRQb3N0cyA9IGF3YWl0IGFwaS5kYi5maW5kKCdwb3N0cycsIHsgYXV0aG9ycGVybTogcGFyZW50QXV0aG9ycGVybSB9KTsKICAgIGlmIChwYXJlbnRQb3N0cyAmJiBwYXJlbnRQb3N0cy5sZW5ndGggPiAwKSB7CiAgICAgIHJldHVybiBwYXJlbnRQb3N0cy5tYXAocCA9PiBwLnJld2FyZFBvb2xJZCk7CiAgICB9CiAgICByZXR1cm4gW107CiAgfQogIC8vIENoZWNrIG1ldGFkYXRhIGZvciB0YWdzIC8gcGFyZW50IHBlcm1saW5rCiAgLy8gZm9yIGNvbW11bml0eS4KICBpZiAoanNvbk1ldGFkYXRhICYmIGpzb25NZXRhZGF0YS50YWdzICYmIEFycmF5LmlzQXJyYXkoanNvbk1ldGFkYXRhLnRhZ3MpCiAgICAgICYmIGpzb25NZXRhZGF0YS50YWdzLmV2ZXJ5KHQgPT4gdHlwZW9mIHQgPT09ICdzdHJpbmcnKSkgewogICAgY29uc3Qgc2VhcmNoVGFncyA9IHBhcmVudFBlcm1saW5rID8ganNvbk1ldGFkYXRhLnRhZ3MuY29uY2F0KFtwYXJlbnRQZXJtbGlua10pCiAgICAgIDoganNvbk1ldGFkYXRhLnRhZ3M7CiAgICBjb25zdCB0YWdSZXdhcmRQb29scyA9IGF3YWl0IGFwaS5kYi5maW5kKCdyZXdhcmRQb29scycsCiAgICAgIHsgJ2NvbmZpZy50YWdzJzogeyAkaW46IHNlYXJjaFRhZ3MgfSB9LAogICAgICBwYXJhbXMubWF4UG9vbHNQZXJQb3N0LCAwLCBbeyBpbmRleDogJ19pZCcsIGRlc2NlbmRpbmc6IGZhbHNlIH1dKTsKICAgIGlmICh0YWdSZXdhcmRQb29scyAmJiB0YWdSZXdhcmRQb29scy5sZW5ndGggPiAwKSB7CiAgICAgIHJldHVybiB0YWdSZXdhcmRQb29scy5tYXAociA9PiByLl9pZCk7CiAgICB9CiAgfQogIGlmIChyZXdhcmRQb29scyAmJiBBcnJheS5pc0FycmF5KHJld2FyZFBvb2xzKSAmJiByZXdhcmRQb29scy5sZW5ndGggPiAwKSB7CiAgICByZXR1cm4gcmV3YXJkUG9vbHMuc2xpY2UoMCwgcGFyYW1zLm1heFBvb2xzUGVyUG9zdCk7CiAgfQogIHJldHVybiBbXTsKfQoKYWN0aW9ucy5jb21tZW50ID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBhdXRob3IsCiAgICBwZXJtbGluaywKICAgIHJld2FyZFBvb2xzLAogIH0gPSBwYXlsb2FkOwoKICAvLyBOb2RlIGVuZm9yY2VzIGF1dGhvciAvIHBlcm1saW5rcyBmcm9tIEhpdmUuIENoZWNrIHRoYXQgc2VuZGVyIGlzIG51bGwuCiAgaWYgKCFhcGkuYXNzZXJ0KGFwaS5zZW5kZXIgPT09ICdudWxsJywgJ2FjdGlvbiBtdXN0IHVzZSBjb21tZW50IG9wZXJhdGlvbicpKSByZXR1cm47CiAgYXdhaXQgdG9rZW5NYWludGVuYW5jZSgpOwoKICBpZiAoIWFwaS5hc3NlcnQoIXJld2FyZFBvb2xzIHx8IChBcnJheS5pc0FycmF5KHJld2FyZFBvb2xzKSAmJiByZXdhcmRQb29scy5ldmVyeShycCA9PiBOdW1iZXIuaXNJbnRlZ2VyKHJwKSkpLCAncmV3YXJkUG9vbHMgbXVzdCBiZSBhbiBhcnJheSBvZiBpbnRlZ2VycycpKSByZXR1cm47CgogIGNvbnN0IHJld2FyZFBvb2xJZHMgPSBhd2FpdCBnZXRSZXdhcmRQb29sSWRzKHBheWxvYWQpOwogIGNvbnN0IGF1dGhvcnBlcm0gPSBgQCR7YXV0aG9yfS8ke3Blcm1saW5rfWA7CgogIC8vIFZhbGlkYXRlIHRoYXQgY29tbWVudCBpcyBub3QgYW4gZWRpdCAoY2Fubm90IGFkZCBtdWx0aXBsZSBwb29scykKICBjb25zdCBleGlzdGluZ1Bvc3RNZXRhZGF0YSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwb3N0TWV0YWRhdGEnLCB7IGF1dGhvcnBlcm0gfSk7CiAgaWYgKGV4aXN0aW5nUG9zdE1ldGFkYXRhKSB7CiAgICByZXR1cm47CiAgfQogIC8vIE5lZWRlZCBmb3IgcG9zdHMgYmVmb3JlIG1ldGFkYXRhIHVwZGF0ZWQuIENhbiBiZSByZW1vdmVkIG9uY2UgYWxsIHBvc3RzIGhhdmUgbWV0YWRhdGEuCiAgY29uc3QgZXhpc3RpbmdQb3N0ID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Bvc3RzJywgeyBhdXRob3JwZXJtIH0pOwogIGlmIChleGlzdGluZ1Bvc3QpIHsKICAgIHJldHVybjsKICB9CgogIGF3YWl0IGFwaS5kYi5pbnNlcnQoJ3Bvc3RNZXRhZGF0YScsIHsgYXV0aG9ycGVybSwgcmV3YXJkUG9vbElkcyB9KTsKCiAgY29uc3QgYmxvY2tEYXRlID0gbmV3IERhdGUoYCR7YXBpLmhpdmVCbG9ja1RpbWVzdGFtcH0uMDAwWmApOwogIGNvbnN0IHRpbWVzdGFtcCA9IGJsb2NrRGF0ZS5nZXRUaW1lKCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXdhcmRQb29sSWRzLmxlbmd0aDsgaSArPSAxKSB7CiAgICBjb25zdCByZXdhcmRQb29sSWQgPSByZXdhcmRQb29sSWRzW2ldOwogICAgY29uc3QgcmV3YXJkUG9vbCA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdyZXdhcmRQb29scycsIHsgX2lkOiByZXdhcmRQb29sSWQgfSk7CiAgICBpZiAocmV3YXJkUG9vbCAmJiByZXdhcmRQb29sLmFjdGl2ZSkgewogICAgICBjb25zdCBjYXNob3V0VGltZSA9IHRpbWVzdGFtcCArIHJld2FyZFBvb2wuY29uZmlnLmNhc2hvdXRXaW5kb3dEYXlzICogMjQgKiAzNjAwICogMTAwMDsKCiAgICAgIGNvbnN0IHBvc3QgPSB7CiAgICAgICAgcmV3YXJkUG9vbElkLAogICAgICAgIHN5bWJvbDogcmV3YXJkUG9vbC5zeW1ib2wsCiAgICAgICAgYXV0aG9ycGVybSwKICAgICAgICBhdXRob3IsCiAgICAgICAgY3JlYXRlZDogdGltZXN0YW1wLAogICAgICAgIGNhc2hvdXRUaW1lLAogICAgICAgIHZvdGVQb3NpdGl2ZVJzaGFyZVN1bTogJzAnLAogICAgICAgIHZvdGVSc2hhcmVTdW06ICcwJywKICAgICAgfTsKICAgICAgYXdhaXQgYXBpLmRiLmluc2VydCgncG9zdHMnLCBwb3N0KTsKICAgICAgYXBpLmVtaXQoJ25ld0NvbW1lbnQnLCB7IHJld2FyZFBvb2xJZCwgc3ltYm9sOiByZXdhcmRQb29sLnN5bWJvbCB9KTsKICAgIH0KICB9Cn07CgphY3Rpb25zLmNvbW1lbnRPcHRpb25zID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBhdXRob3IsCiAgICBwZXJtbGluaywKICAgIG1heEFjY2VwdGVkUGF5b3V0LAogICAgYmVuZWZpY2lhcmllcywKICB9ID0gcGF5bG9hZDsKCiAgLy8gTm9kZSBlbmZvcmNlcyBhdXRob3IgLyBwZXJtbGlua3MgZnJvbSBIaXZlLiBDaGVjayB0aGF0IHNlbmRlciBpcyBudWxsLgogIGlmICghYXBpLmFzc2VydChhcGkuc2VuZGVyID09PSAnbnVsbCcsICdhY3Rpb24gbXVzdCB1c2UgY29tbWVudE9wdGlvbnMgb3BlcmF0aW9uJykpIHJldHVybjsKICBjb25zdCBhdXRob3JwZXJtID0gYEAke2F1dGhvcn0vJHtwZXJtbGlua31gOwoKICBjb25zdCBleGlzdGluZ1Bvc3RzID0gYXdhaXQgYXBpLmRiLmZpbmQoJ3Bvc3RzJywgeyBhdXRob3JwZXJtIH0pOwogIGlmICghZXhpc3RpbmdQb3N0cykgewogICAgcmV0dXJuOwogIH0KCiAgY29uc3QgZGVjbGluZVBheW91dCA9IG1heEFjY2VwdGVkUGF5b3V0LnN0YXJ0c1dpdGgoJzAuMDAwJyk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBleGlzdGluZ1Bvc3RzLmxlbmd0aDsgaSArPSAxKSB7CiAgICBjb25zdCBwb3N0ID0gZXhpc3RpbmdQb3N0c1tpXTsKICAgIHBvc3QuZGVjbGluZVBheW91dCA9IGRlY2xpbmVQYXlvdXQ7CiAgICBwb3N0LmJlbmVmaWNpYXJpZXMgPSBiZW5lZmljaWFyaWVzOwogICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncG9zdHMnLCBwb3N0KTsKICB9Cn07Cgphc3luYyBmdW5jdGlvbiBwcm9jZXNzVm90ZShwb3N0LCB2b3Rlciwgd2VpZ2h0LCB0aW1lc3RhbXApIHsKICBjb25zdCB7CiAgICByZXdhcmRQb29sSWQsCiAgICBzeW1ib2wsCiAgICBhdXRob3JwZXJtLAogICAgY2FzaG91dFRpbWUsCiAgfSA9IHBvc3Q7CgogIGlmIChjYXNob3V0VGltZSA8IHRpbWVzdGFtcCkgewogICAgcmV0dXJuOwogIH0KCiAgLy8gY2hlY2sgdm90aW5nIHBvd2VyLCBzdGFrZSwgYW5kIGN1cnJlbnQgdm90ZSByc2hhcmVzLgogIGNvbnN0IHJld2FyZFBvb2wgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgncmV3YXJkUG9vbHMnLCB7IF9pZDogcmV3YXJkUG9vbElkIH0pOwogIGlmICghcmV3YXJkUG9vbCB8fCAhcmV3YXJkUG9vbC5hY3RpdmUpIHsKICAgIHJldHVybjsKICB9CgogIGxldCB2b3RpbmdQb3dlciA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd2b3RpbmdQb3dlcicsIHsgcmV3YXJkUG9vbElkLCBhY2NvdW50OiB2b3RlciB9KTsKICBpZiAoIXZvdGluZ1Bvd2VyKSB7CiAgICB2b3RpbmdQb3dlciA9IHsKICAgICAgcmV3YXJkUG9vbElkLAogICAgICBhY2NvdW50OiB2b3RlciwKICAgICAgbGFzdFZvdGVUaW1lc3RhbXA6IHRpbWVzdGFtcCwKICAgICAgdm90aW5nUG93ZXI6IE1BWF9WT1RJTkdfUE9XRVIsCiAgICAgIGRvd252b3RpbmdQb3dlcjogTUFYX1ZPVElOR19QT1dFUiwKICAgIH07CiAgICB2b3RpbmdQb3dlciA9IGF3YWl0IGFwaS5kYi5pbnNlcnQoJ3ZvdGluZ1Bvd2VyJywgdm90aW5nUG93ZXIpOwogIH0gZWxzZSB7CiAgICAvLyByZWdlbmVyYXRlIHZvdGluZyBwb3dlcgogICAgdm90aW5nUG93ZXIudm90aW5nUG93ZXIgKz0gKHRpbWVzdGFtcCAtIHZvdGluZ1Bvd2VyLmxhc3RWb3RlVGltZXN0YW1wKSAqIE1BWF9WT1RJTkdfUE9XRVIKICAgICAgICAgIC8gKHJld2FyZFBvb2wuY29uZmlnLnZvdGVSZWdlbmVyYXRpb25EYXlzICogMjQgKiAzNjAwICogMTAwMCk7CiAgICB2b3RpbmdQb3dlci52b3RpbmdQb3dlciA9IE1hdGguZmxvb3Iodm90aW5nUG93ZXIudm90aW5nUG93ZXIpOwogICAgdm90aW5nUG93ZXIudm90aW5nUG93ZXIgPSBNYXRoLm1pbih2b3RpbmdQb3dlci52b3RpbmdQb3dlciwgTUFYX1ZPVElOR19QT1dFUik7CiAgICB2b3RpbmdQb3dlci5kb3dudm90aW5nUG93ZXIgKz0gKHRpbWVzdGFtcCAtIHZvdGluZ1Bvd2VyLmxhc3RWb3RlVGltZXN0YW1wKSAqIE1BWF9WT1RJTkdfUE9XRVIKICAgICAgICAgIC8gKHJld2FyZFBvb2wuY29uZmlnLmRvd252b3RlUmVnZW5lcmF0aW9uRGF5cyAqIDI0ICogMzYwMCAqIDEwMDApOwogICAgdm90aW5nUG93ZXIuZG93bnZvdGluZ1Bvd2VyID0gTWF0aC5mbG9vcih2b3RpbmdQb3dlci5kb3dudm90aW5nUG93ZXIpOwogICAgdm90aW5nUG93ZXIuZG93bnZvdGluZ1Bvd2VyID0gTWF0aC5taW4odm90aW5nUG93ZXIuZG93bnZvdGluZ1Bvd2VyLCBNQVhfVk9USU5HX1BPV0VSKTsKICAgIHZvdGluZ1Bvd2VyLmxhc3RWb3RlVGltZXN0YW1wID0gdGltZXN0YW1wOwogIH0KCiAgY29uc3Qgdm90ZXJUb2tlbkJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ3Rva2VucycsICdiYWxhbmNlcycsIHsgc3ltYm9sLCBhY2NvdW50OiB2b3RlciB9KTsKICBsZXQgc3Rha2UgPSB2b3RlclRva2VuQmFsYW5jZSA/IHZvdGVyVG9rZW5CYWxhbmNlLnN0YWtlIDogJzAnOwogIGlmICh2b3RlclRva2VuQmFsYW5jZSAmJiB2b3RlclRva2VuQmFsYW5jZS5kZWxlZ2F0aW9uc0luCiAgICAgICYmIGFwaS5CaWdOdW1iZXIodm90ZXJUb2tlbkJhbGFuY2UuZGVsZWdhdGlvbnNJbikuaXNGaW5pdGUoKSkgewogICAgc3Rha2UgPSBhcGkuQmlnTnVtYmVyKHN0YWtlKS5wbHVzKHZvdGVyVG9rZW5CYWxhbmNlLmRlbGVnYXRpb25zSW4pOwogIH0KCiAgbGV0IHZvdGVSc2hhcmVzID0gJzAnOwogIGxldCB1cGRhdGVkUG9zdFJzaGFyZXMgPSAnMCc7CiAgbGV0IHVzZWRQb3dlciA9IDA7CiAgbGV0IHVzZWREb3dudm90ZVBvd2VyID0gMDsKICBsZXQgY3VyYXRpb25XZWlnaHQgPSAnMCc7CiAgaWYgKHdlaWdodCA+IDApIHsKICAgIHZvdGVSc2hhcmVzID0gYXBpLkJpZ051bWJlcihzdGFrZSkubXVsdGlwbGllZEJ5KHdlaWdodCkubXVsdGlwbGllZEJ5KHZvdGluZ1Bvd2VyLnZvdGluZ1Bvd2VyKQogICAgICAuZGl2aWRlZEJ5KE1BWF9WT1RJTkdfUE9XRVIpCiAgICAgIC5kaXZpZGVkQnkoTUFYX1dFSUdIVCkKICAgICAgLnRvRml4ZWQoU01UX1BSRUNJU0lPTiwgYXBpLkJpZ051bWJlci5ST1VORF9ET1dOKTsKICAgIHVzZWRQb3dlciA9IE1hdGguZmxvb3Iodm90aW5nUG93ZXIudm90aW5nUG93ZXIgKiBNYXRoLmFicyh3ZWlnaHQpICogNjAgKiA2MCAqIDI0IC8gTUFYX1dFSUdIVCk7CiAgICBjb25zdCB1c2VkUG93ZXJEZW5vbSA9IE1hdGguZmxvb3IoTUFYX1ZPVElOR19QT1dFUiAqIDYwICogNjAgKiAyNAogICAgICAgIC8gcmV3YXJkUG9vbC5jb25maWcudm90ZVBvd2VyQ29uc3VtcHRpb24pOwogICAgdXNlZFBvd2VyID0gTWF0aC5mbG9vcigodXNlZFBvd2VyICsgdXNlZFBvd2VyRGVub20gLSAxKSAvIHVzZWRQb3dlckRlbm9tKTsKICAgIHZvdGluZ1Bvd2VyLnZvdGluZ1Bvd2VyID0gTWF0aC5tYXgoMCwgTWF0aC5mbG9vcih2b3RpbmdQb3dlci52b3RpbmdQb3dlciAtIHVzZWRQb3dlcikpOwogICAgY3VyYXRpb25XZWlnaHQgPSBhcGkuQmlnTnVtYmVyKGNhbGN1bGF0ZUN1cmF0aW9uV2VpZ2h0UnNoYXJlcygKICAgICAgcmV3YXJkUG9vbCwgYXBpLkJpZ051bWJlcih2b3RlUnNoYXJlcykucGx1cyhwb3N0LnZvdGVQb3NpdGl2ZVJzaGFyZVN1bSksCiAgICApKQogICAgICAubWludXMoY2FsY3VsYXRlQ3VyYXRpb25XZWlnaHRSc2hhcmVzKHJld2FyZFBvb2wsIHBvc3Qudm90ZVBvc2l0aXZlUnNoYXJlU3VtKSkKICAgICAgLnRvRml4ZWQoU01UX1BSRUNJU0lPTiwgYXBpLkJpZ051bWJlci5ST1VORF9ET1dOKTsKICB9IGVsc2UgaWYgKHdlaWdodCA8IDApIHsKICAgIHZvdGVSc2hhcmVzID0gYXBpLkJpZ051bWJlcihzdGFrZSkubXVsdGlwbGllZEJ5KHdlaWdodCkKICAgICAgLm11bHRpcGxpZWRCeSh2b3RpbmdQb3dlci5kb3dudm90aW5nUG93ZXIpCiAgICAgIC5kaXZpZGVkQnkoTUFYX1ZPVElOR19QT1dFUikKICAgICAgLmRpdmlkZWRCeShNQVhfV0VJR0hUKQogICAgICAudG9GaXhlZChTTVRfUFJFQ0lTSU9OLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOwogICAgdXNlZERvd252b3RlUG93ZXIgPSBNYXRoLmZsb29yKHZvdGluZ1Bvd2VyLmRvd252b3RpbmdQb3dlciAqIE1hdGguYWJzKHdlaWdodCkgKiA2MCAqIDYwICogMjQKICAgICAgICAvIE1BWF9XRUlHSFQpOwogICAgY29uc3QgdXNlZERvd252b3RlUG93ZXJEZW5vbSA9IE1hdGguZmxvb3IoTUFYX1ZPVElOR19QT1dFUiAqIDYwICogNjAgKiAyNAogICAgICAgIC8gcmV3YXJkUG9vbC5jb25maWcuZG93bnZvdGVQb3dlckNvbnN1bXB0aW9uKTsKICAgIHVzZWREb3dudm90ZVBvd2VyID0gTWF0aC5mbG9vcigodXNlZERvd252b3RlUG93ZXIgKyB1c2VkRG93bnZvdGVQb3dlckRlbm9tIC0gMSkKICAgICAgICAvIHVzZWREb3dudm90ZVBvd2VyRGVub20pOwogICAgdm90aW5nUG93ZXIuZG93bnZvdGluZ1Bvd2VyID0gTWF0aC5tYXgoCiAgICAgIDAsIE1hdGguZmxvb3Iodm90aW5nUG93ZXIuZG93bnZvdGluZ1Bvd2VyIC0gdXNlZERvd252b3RlUG93ZXIpLAogICAgKTsKICB9CgogIGlmICh2b3RpbmdQb3dlci5tdXRlKSB7CiAgICB2b3RlUnNoYXJlcyA9ICcwJzsKICAgIGN1cmF0aW9uV2VpZ2h0ID0gJzAnOwogIH0KCiAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndm90aW5nUG93ZXInLCB2b3RpbmdQb3dlcik7CgogIGxldCB2b3RlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3ZvdGVzJywgeyByZXdhcmRQb29sSWQsIGF1dGhvcnBlcm0sIHZvdGVyIH0pOwogIGlmICh2b3RlKSB7CiAgICAvLyBBIHJlLXZvdGUgbmVnYXRlcyBjdXJhdGlvbiByZXdhcmRzLCBzaW1pbGFyIHRvIEhpdmUuCiAgICB2b3RlLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDsKICAgIHZvdGUud2VpZ2h0ID0gd2VpZ2h0OwogICAgdm90ZS5jdXJhdGlvbldlaWdodCA9ICcwJzsKICAgIGNvbnN0IG9sZFZvdGVSc2hhcmVzID0gdm90ZS5yc2hhcmVzOwogICAgdm90ZS5yc2hhcmVzID0gdm90ZVJzaGFyZXM7CiAgICB1cGRhdGVkUG9zdFJzaGFyZXMgPSBhcGkuQmlnTnVtYmVyKHZvdGVSc2hhcmVzKS5taW51cyhvbGRWb3RlUnNoYXJlcykKICAgICAgLnRvRml4ZWQoU01UX1BSRUNJU0lPTiwgYXBpLkJpZ051bWJlci5ST1VORF9ET1dOKTsKICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3ZvdGVzJywgdm90ZSk7CiAgICBjb25zdCB2b3RlTG9nID0geyByZXdhcmRQb29sSWQsIHN5bWJvbDogcmV3YXJkUG9vbC5zeW1ib2wsIHJzaGFyZXM6IHZvdGVSc2hhcmVzIH07CiAgICBpZiAodm90aW5nUG93ZXIubXV0ZSkgewogICAgICB2b3RlTG9nLm11dGUgPSB0cnVlOwogICAgfQogICAgYXBpLmVtaXQoJ3VwZGF0ZVZvdGUnLCB2b3RlTG9nKTsKICB9IGVsc2UgewogICAgdm90ZSA9IHsKICAgICAgcmV3YXJkUG9vbElkLAogICAgICBzeW1ib2wsCiAgICAgIGF1dGhvcnBlcm0sCiAgICAgIHdlaWdodCwKICAgICAgcnNoYXJlczogdm90ZVJzaGFyZXMsCiAgICAgIGN1cmF0aW9uV2VpZ2h0LAogICAgICB0aW1lc3RhbXAsCiAgICAgIHZvdGVyLAogICAgfTsKICAgIHVwZGF0ZWRQb3N0UnNoYXJlcyA9IHZvdGVSc2hhcmVzOwogICAgYXdhaXQgYXBpLmRiLmluc2VydCgndm90ZXMnLCB2b3RlKTsKICAgIGNvbnN0IHZvdGVMb2cgPSB7IHJld2FyZFBvb2xJZCwgc3ltYm9sOiByZXdhcmRQb29sLnN5bWJvbCwgcnNoYXJlczogdm90ZVJzaGFyZXMgfTsKICAgIGlmICh2b3RpbmdQb3dlci5tdXRlKSB7CiAgICAgIHZvdGVMb2cubXV0ZSA9IHRydWU7CiAgICB9CiAgICBhcGkuZW1pdCgnbmV3Vm90ZScsIHZvdGVMb2cpOwogIH0KCiAgY29uc3Qgb2xkUG9zdENsYWltcyA9IGNhbGN1bGF0ZVdlaWdodFJzaGFyZXMocmV3YXJkUG9vbCwgcG9zdC52b3RlUnNoYXJlU3VtKTsKICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ24KICBwb3N0LnZvdGVSc2hhcmVTdW0gPSBhcGkuQmlnTnVtYmVyKHBvc3Qudm90ZVJzaGFyZVN1bSkucGx1cyh1cGRhdGVkUG9zdFJzaGFyZXMpCiAgICAudG9GaXhlZChTTVRfUFJFQ0lTSU9OLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOwoKICBpZiAoYXBpLkJpZ051bWJlcih1cGRhdGVkUG9zdFJzaGFyZXMpLmd0KDApKSB7CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ24KICAgIHBvc3Qudm90ZVBvc2l0aXZlUnNoYXJlU3VtID0gYXBpLkJpZ051bWJlcihwb3N0LnZvdGVQb3NpdGl2ZVJzaGFyZVN1bSkucGx1cyh1cGRhdGVkUG9zdFJzaGFyZXMpCiAgICAgIC50b0ZpeGVkKFNNVF9QUkVDSVNJT04sIGFwaS5CaWdOdW1iZXIuUk9VTkRfRE9XTik7CiAgICBpZiAodGltZXN0YW1wIDwgcmV3YXJkUG9vbC5jcmVhdGVkVGltZXN0YW1wCiAgICAgICAgKyAoMiAqIHJld2FyZFBvb2wuY29uZmlnLmNhc2hvdXRXaW5kb3dEYXlzICsgMSkgKiAyNCAqIDM2MDAgKiAxMDAwKSB7CiAgICAgIGNvbnN0IG5ld1Bvc3RDbGFpbXMgPSBjYWxjdWxhdGVXZWlnaHRSc2hhcmVzKHJld2FyZFBvb2wsIHBvc3Qudm90ZVJzaGFyZVN1bSk7CiAgICAgIHJld2FyZFBvb2wucGVuZGluZ0NsYWltcyA9IGFwaS5CaWdOdW1iZXIocmV3YXJkUG9vbC5wZW5kaW5nQ2xhaW1zKQogICAgICAgIC5wbHVzKG5ld1Bvc3RDbGFpbXMpCiAgICAgICAgLm1pbnVzKG9sZFBvc3RDbGFpbXMpCiAgICAgICAgLnRvRml4ZWQoU01UX1BSRUNJU0lPTiwgYXBpLkJpZ051bWJlci5ST1VORF9ET1dOKTsKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncmV3YXJkUG9vbHMnLCByZXdhcmRQb29sKTsKICAgIH0KICB9CiAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncG9zdHMnLCBwb3N0KTsKfQoKYWN0aW9ucy52b3RlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICB2b3RlciwKICAgIGF1dGhvciwKICAgIHBlcm1saW5rLAogICAgd2VpZ2h0LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoIWFwaS5hc3NlcnQoYXBpLnNlbmRlciA9PT0gJ251bGwnLCAnY2FuIG9ubHkgdm90ZSB3aXRoIHZvdGluZyBvcCcpKSByZXR1cm47CiAgYXdhaXQgdG9rZW5NYWludGVuYW5jZSgpOwoKICBpZiAoIWFwaS5hc3NlcnQoTnVtYmVyLmlzSW50ZWdlcih3ZWlnaHQpICYmIHdlaWdodCA+PSAtMTAwMDAgJiYgd2VpZ2h0IDw9IDEwMDAwLAogICAgJ3dlaWdodCBtdXN0IGJlIGFuIGludGVnZXIgZnJvbSAtMTAwMDAgdG8gMTAwMDAnKSkgcmV0dXJuOwoKICBjb25zdCBibG9ja0RhdGUgPSBuZXcgRGF0ZShgJHthcGkuaGl2ZUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgY29uc3QgdGltZXN0YW1wID0gYmxvY2tEYXRlLmdldFRpbWUoKTsKICBjb25zdCBhdXRob3JwZXJtID0gYEAke2F1dGhvcn0vJHtwZXJtbGlua31gOwogIC8vIENhbiBvbmx5IHJldHVybiBwYXJhbXMubWF4UG9vbHNQZXJQb3N0ICg8MTAwMCkgcG9zdHMKICBjb25zdCBwb3N0cyA9IGF3YWl0IGFwaS5kYi5maW5kKCdwb3N0cycsIHsgYXV0aG9ycGVybSB9KTsKCiAgaWYgKCFwb3N0cykgcmV0dXJuOwogIGZvciAobGV0IGkgPSAwOyBpIDwgcG9zdHMubGVuZ3RoOyBpICs9IDEpIHsKICAgIGNvbnN0IHBvc3QgPSBwb3N0c1tpXTsKICAgIGF3YWl0IHByb2Nlc3NWb3RlKHBvc3QsIHZvdGVyLCB3ZWlnaHQsIHRpbWVzdGFtcCk7CiAgfQp9Owo="}}}
RE: testnet