GoogleドライブやOneDriveへ簡単にバックアップ出来る「EasyRclone」

先日作成した、クラウドサービスとのデータコピーを行えるrcloneのGUI版「EasyRclone」。自分の使い方では動作に問題はなさそうなので本格的に運用していきたいと思います。それに伴い、デザインを変更してみました。動作自体は全く変わっていないので、前のデザインのほうがよければ前のバージョンでも。

履歴画面は次のような感じです。

使用方法などは前と全く変わらないので、そちらを参照してください。

LXDコンテナにインストール

#!/bin/bash
set -e

INSTALL_DIR="/opt/easyrclone"
unset PORT
APP_PORT="${EASYRCLONE_PORT:-3348}"

echo "========================================="
echo "  EasyRclone Installer v7"
echo "========================================="
echo ""

if [ "$(id -u)" -ne 0 ]; then
  echo "エラー: root で実行してください"
  echo " sudo bash $0"
  exit 1
fi

echo "[1/6] タイムゾーン設定 (JST)..."
if command -v timedatectl &>/dev/null; then
  timedatectl set-timezone Asia/Tokyo 2>/dev/null || true
elif [ -f /usr/share/zoneinfo/Asia/Tokyo ]; then
  ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
  echo "Asia/Tokyo" > /etc/timezone
fi
echo "  $(date)"
echo ""

if [ -f /etc/os-release ]; then . /etc/os-release; OS=$ID; else OS=$(uname -s | tr '[:upper:]' '[:lower:]'); fi
echo "OS: $OS"
echo ""

echo "[Tailscale] IP / MagicDNS 検出..."
TS_IP=""
TS_HOSTNAME=""
if command -v tailscale &>/dev/null; then
  TS_JSON=$(tailscale status --json 2>/dev/null || true)
  if [ -n "$TS_JSON" ]; then
    TS_IP=$(echo "$TS_JSON" | python3 -c "import json,sys
try:
    d=json.load(sys.stdin)
    print(d.get('Self',{}).get('TailscaleIPs',[''])[0])
except Exception:
    print('')" 2>/dev/null)
    TS_HOSTNAME=$(echo "$TS_JSON" | python3 -c "import json,sys
try:
    d=json.load(sys.stdin)
    print(d.get('Self',{}).get('DNSName','').rstrip('.'))
except Exception:
    print('')" 2>/dev/null)
  fi
fi
if [ -n "$TS_IP" ]; then
  echo "  Tailscale IP: $TS_IP"
else
  echo "  Tailscale 未検出(ローカルURLのみ表示します)"
fi
echo ""

echo "[2/6] Node.js インストール..."
if command -v node &>/dev/null && [ "$(node -v | sed 's/v//' | cut -d. -f1)" -ge 18 ]; then
  echo "  Node.js $(node -v) は既にインストール済み"
else
  case "$OS" in
    ubuntu|debian) curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && apt-get install -y nodejs ;;
    centos|rhel|rocky|alma|fedora) curl -fsSL https://rpm.nodesource.com/setup_22.x | bash - && yum install -y nodejs ;;
    *) curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && apt-get install -y nodejs 2>/dev/null || yum install -y nodejs ;;
  esac
fi
echo "  Node.js $(node -v)"
echo ""

echo "[3/6] rclone インストール..."
if ! command -v rclone &>/dev/null; then
  curl -fsSL https://rclone.org/install.sh | bash
fi
echo "  rclone $(rclone version | head -1)"
echo ""

echo "[4/6] プロジェクト作成..."
mkdir -p "$INSTALL_DIR"/{public/css,public/js,config,sync-jobs}

B64_SERVER='Y29uc3QgZXhwcmVzcyA9IHJlcXVpcmUoJ2V4cHJlc3MnKTsKY29uc3QgeyBleGVjU3luYywgc3Bhd24gfSA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKTsKY29uc3QgZnMgPSByZXF1aXJlKCdmcycpOwpjb25zdCBwYXRoID0gcmVxdWlyZSgncGF0aCcpOwoKY29uc3QgYXBwID0gZXhwcmVzcygpOwpjb25zdCBQT1JUID0gcHJvY2Vzcy5lbnYuUE9SVCB8fCAzMzQ4Owpjb25zdCBSQ0xPTkVfQ09ORklHX0RJUiA9IHBhdGguam9pbihfX2Rpcm5hbWUsICdjb25maWcnKTsKY29uc3QgU1lOQ19KT0JTX0RJUiA9IHBhdGguam9pbihfX2Rpcm5hbWUsICdzeW5jLWpvYnMnKTsKY29uc3QgQ09ORklHX1BBVEggPSBwYXRoLmpvaW4oUkNMT05FX0NPTkZJR19ESVIsICdyY2xvbmUuY29uZicpOwoKaWYgKCFmcy5leGlzdHNTeW5jKFJDTE9ORV9DT05GSUdfRElSKSkgZnMubWtkaXJTeW5jKFJDTE9ORV9DT05GSUdfRElSLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTsKaWYgKCFmcy5leGlzdHNTeW5jKFNZTkNfSk9CU19ESVIpKSBmcy5ta2RpclN5bmMoU1lOQ19KT0JTX0RJUiwgeyByZWN1cnNpdmU6IHRydWUgfSk7Cgpwcm9jZXNzLmVudi5SQ0xPTkVfQ09ORklHID0gQ09ORklHX1BBVEg7CgphcHAudXNlKGV4cHJlc3MuanNvbigpKTsKYXBwLnVzZShleHByZXNzLnN0YXRpYyhwYXRoLmpvaW4oX19kaXJuYW1lLCAncHVibGljJykpKTsKCmZ1bmN0aW9uIHJlYWRDb25maWcoKSB7CiAgaWYgKCFmcy5leGlzdHNTeW5jKENPTkZJR19QQVRIKSkgcmV0dXJuICcnOwogIHJldHVybiBmcy5yZWFkRmlsZVN5bmMoQ09ORklHX1BBVEgsICd1dGYtOCcpOwp9CgpmdW5jdGlvbiB3cml0ZUNvbmZpZyhjb250ZW50KSB7CiAgZnMud3JpdGVGaWxlU3luYyhDT05GSUdfUEFUSCwgY29udGVudC50cmltKCkgKyAnXG4nKTsKfQoKZnVuY3Rpb24gcGFyc2VSZW1vdGVzKCkgewogIGNvbnN0IGNvbnRlbnQgPSByZWFkQ29uZmlnKCk7CiAgaWYgKCFjb250ZW50LnRyaW0oKSkgcmV0dXJuIFtdOwogIGNvbnN0IHJlbW90ZXMgPSBbXTsKICBsZXQgY3VycmVudCA9IG51bGw7CiAgZm9yIChjb25zdCBsaW5lIG9mIGNvbnRlbnQuc3BsaXQoJ1xuJykpIHsKICAgIGNvbnN0IG0gPSBsaW5lLm1hdGNoKC9eXFsoLispXF0kLyk7CiAgICBpZiAobSkgewogICAgICBpZiAoY3VycmVudCkgcmVtb3Rlcy5wdXNoKGN1cnJlbnQpOwogICAgICBjdXJyZW50ID0geyBuYW1lOiBtWzFdLCB0eXBlOiAnJywgcGFyYW1zOiB7fSB9OwogICAgfSBlbHNlIGlmIChjdXJyZW50ICYmIGxpbmUuaW5jbHVkZXMoJz0nKSkgewogICAgICBjb25zdCBlcSA9IGxpbmUuaW5kZXhPZignPScpOwogICAgICBjb25zdCBrZXkgPSBsaW5lLnN1YnN0cmluZygwLCBlcSkudHJpbSgpOwogICAgICBjb25zdCB2YWwgPSBsaW5lLnN1YnN0cmluZyhlcSArIDEpLnRyaW0oKTsKICAgICAgY3VycmVudC5wYXJhbXNba2V5XSA9IHZhbDsKICAgICAgaWYgKGtleSA9PT0gJ3R5cGUnKSBjdXJyZW50LnR5cGUgPSB2YWw7CiAgICB9CiAgfQogIGlmIChjdXJyZW50KSByZW1vdGVzLnB1c2goY3VycmVudCk7CiAgcmV0dXJuIHJlbW90ZXM7Cn0KCmZ1bmN0aW9uIHJjbG9uZShhcmdzKSB7CiAgdHJ5IHsKICAgIGNvbnN0IG91dCA9IGV4ZWNTeW5jKGByY2xvbmUgJHthcmdzLmpvaW4oJyAnKX1gLCB7CiAgICAgIHRpbWVvdXQ6IDMwMDAwLAogICAgICBlbmNvZGluZzogJ3V0Zi04JywKICAgICAgZW52OiB7IC4uLnByb2Nlc3MuZW52LCBSQ0xPTkVfQ09ORklHOiBDT05GSUdfUEFUSCB9CiAgICB9KTsKICAgIHJldHVybiB7IG9rOiB0cnVlLCBkYXRhOiBvdXQudHJpbSgpIH07CiAgfSBjYXRjaCAoZSkgewogICAgcmV0dXJuIHsgb2s6IGZhbHNlLCBlcnJvcjogKGUuc3RkZXJyIHx8IGUubWVzc2FnZSkudHJpbSgpIH07CiAgfQp9CgovLyA9PT0gQ29uZmlnIEFQSSA9PT0KYXBwLmdldCgnL2FwaS9yZW1vdGVzJywgKHJlcSwgcmVzKSA9PiB7CiAgcmVzLmpzb24oeyByZW1vdGVzOiBwYXJzZVJlbW90ZXMoKSB9KTsKfSk7CgphcHAucG9zdCgnL2FwaS9yZW1vdGVzJywgKHJlcSwgcmVzKSA9PiB7CiAgY29uc3QgeyBuYW1lLCB0eXBlLCBwYXJhbXMgfSA9IHJlcS5ib2R5OwogIGlmICghbmFtZSB8fCAhdHlwZSkgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5qc29uKHsgZXJyb3I6ICflkI3liY3jgajjgr/jgqTjg5fjga/lv4XpoIjjgafjgZknIH0pOwogIGlmICghL15bYS16QS1aMC05Xy1dKyQvLnRlc3QobmFtZSkpIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7IGVycm9yOiAn5ZCN5YmN44Gv6Iux5pWw5a2X44CB44OP44Kk44OV44Oz44CB44Ki44Oz44OA44O844K544Kz44Ki44Gu44G/JyB9KTsKCiAgY29uc3QgcmVtb3RlcyA9IHBhcnNlUmVtb3RlcygpOwogIGlmIChyZW1vdGVzLmZpbmQociA9PiByLm5hbWUgPT09IG5hbWUpKSByZXR1cm4gcmVzLnN0YXR1cyg0MDkpLmpzb24oeyBlcnJvcjogYOOAjCR7bmFtZX3jgI3jga/ml6LjgavlrZjlnKjjgZfjgb7jgZlgIH0pOwoKICBsZXQgc2VjdGlvbiA9IGBbJHtuYW1lfV1cbnR5cGUgPSAke3R5cGV9YDsKICBmb3IgKGNvbnN0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyhwYXJhbXMgfHwge30pKSB7CiAgICBpZiAodiAhPT0gJycgJiYgdiAhPSBudWxsKSBzZWN0aW9uICs9IGBcbiR7a30gPSAke3Z9YDsKICB9CiAgY29uc3Qgc2VwID0gcmVhZENvbmZpZygpLnRyaW0oKSA/ICdcbicgOiAnJzsKICBmcy5hcHBlbmRGaWxlU3luYyhDT05GSUdfUEFUSCwgc2VwICsgc2VjdGlvbiArICdcbicpOwogIHJlcy5qc29uKHsgb2s6IHRydWUgfSk7Cn0pOwoKYXBwLmRlbGV0ZSgnL2FwaS9yZW1vdGVzLzpuYW1lJywgKHJlcSwgcmVzKSA9PiB7CiAgY29uc3QgeyBuYW1lIH0gPSByZXEucGFyYW1zOwogIGxldCBjb250ZW50ID0gcmVhZENvbmZpZygpOwogIGNvbnN0IHJlID0gbmV3IFJlZ0V4cChgXFxuP1xcWyR7bmFtZS5yZXBsYWNlKC9bLiorP14ke30oKXxbXF1cXF0vZywgJ1xcJCYnKX1cXF1bXlxcW10qYCwgJ2cnKTsKICBpZiAoIXJlLnRlc3QoY29udGVudCkpIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7IGVycm9yOiBg44CMJHtuYW1lfeOAjeOBjOimi+OBpOOBi+OCiuOBvuOBm+OCk2AgfSk7CiAgY29udGVudCA9IGNvbnRlbnQucmVwbGFjZShyZSwgJycpLnJlcGxhY2UoL1xuezMsfS9nLCAnXG5cbicpLnRyaW0oKTsKICB3cml0ZUNvbmZpZyhjb250ZW50KTsKICByZXMuanNvbih7IG9rOiB0cnVlIH0pOwp9KTsKCmFwcC5wb3N0KCcvYXBpL3JlbW90ZXMvOm5hbWUvdGVzdCcsIChyZXEsIHJlcykgPT4gewogIGNvbnN0IHsgbmFtZSB9ID0gcmVxLnBhcmFtczsKICBjb25zdCByZXN1bHQgPSByY2xvbmUoWydsc2QnLCBgJHtuYW1lfTpgLCAnLS1tYXgtZGVwdGgnLCAnMSddKTsKICBpZiAocmVzdWx0Lm9rKSB7CiAgICByZXMuanNvbih7IG9rOiB0cnVlLCBmb2xkZXJzOiByZXN1bHQuZGF0YSA/IHJlc3VsdC5kYXRhLnNwbGl0KCdcbicpLmZpbHRlcihCb29sZWFuKS5tYXAobCA9PiBsLnNwbGl0KC9ccysvKS5wb3AoKSkgOiBbXSB9KTsKICB9IGVsc2UgewogICAgcmVzLmpzb24oeyBvazogZmFsc2UsIGVycm9yOiByZXN1bHQuZXJyb3IgfSk7CiAgfQp9KTsKCi8vID09PSBTeW5jIFNldHRpbmdzID09PQpjb25zdCBTWU5DX1NFVFRJTkdTX1BBVEggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnY29uZmlnJywgJ3N5bmMtc2V0dGluZ3MuanNvbicpOwoKYXBwLmdldCgnL2FwaS9zeW5jLXNldHRpbmdzJywgKHJlcSwgcmVzKSA9PiB7CiAgdHJ5IHsKICAgIGlmIChmcy5leGlzdHNTeW5jKFNZTkNfU0VUVElOR1NfUEFUSCkpIHsKICAgICAgY29uc3QgZGF0YSA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKFNZTkNfU0VUVElOR1NfUEFUSCwgJ3V0Zi04JykpOwogICAgICByZXMuanNvbih7IG9rOiB0cnVlLCBzZXR0aW5nczogZGF0YSB9KTsKICAgIH0gZWxzZSB7CiAgICAgIHJlcy5qc29uKHsgb2s6IHRydWUsIHNldHRpbmdzOiB7IHBhaXJzOiBbXSwgc2NoZWR1bGU6IFtdIH0gfSk7CiAgICB9CiAgfSBjYXRjaCAoZSkgewogICAgcmVzLmpzb24oeyBvazogdHJ1ZSwgc2V0dGluZ3M6IHsgcGFpcnM6IFtdLCBzY2hlZHVsZTogW10gfSB9KTsKICB9Cn0pOwoKY29uc3QgQ1JPTl9NQVJLRVIgPSAnIyBlYXN5cmNsb25lLXNjaGVkdWxlJzsKY29uc3QgQ1JPTl9TQ1JJUFQgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnY3Jvbi1zeW5jLnNoJyk7CgpmdW5jdGlvbiB3cml0ZUNyb25TY3JpcHQocGFpcnMpIHsKICBsZXQgc2NyaXB0ID0gYCMhL2Jpbi9iYXNoCmV4cG9ydCBSQ0xPTkVfQ09ORklHPSIke0NPTkZJR19QQVRIfSIKSk9CU19ESVI9IiR7U1lOQ19KT0JTX0RJUn0iCgpydW5fcGFpcigpIHsKICBsb2NhbCBzcmM9IiQxIiBkZXN0PSIkMiIgZGVsPSIkMyIgbmFtZT0iJDQiCiAgbG9jYWwgamlkPSJqb2JfJChkYXRlICslcyVOIHwgY3V0IC1jMS0xMylfJChzaHVmIC1pIDEwMDAtOTk5OSAtbjEpIgogIGxvY2FsIGpmaWxlPSIkSk9CU19ESVIvJGppZC5qc29uIgogIGxvY2FsIGp0bXA9IiRKT0JTX0RJUi8kamlkLnRtcCIKICBsb2NhbCBhcmdzPSIiCiAgaWYgWyAiJGRlbCIgPSAidHJ1ZSIgXTsgdGhlbiBhcmdzPSJzeW5jIjsgZWxzZSBhcmdzPSJjb3B5IjsgZmkKICBhcmdzPSIkYXJncyAtLXN0YXRzIDJzIC0tc3RhdHMtb25lLWxpbmUgLXYiCiAgcmNsb25lICRhcmdzICIkc3JjIiAiJGRlc3QiID4gIiRqdG1wIiAyPiYxCiAgbG9jYWwgY29kZT0kPwogIGxvY2FsIHN0YXR1cz0iY29tcGxldGVkIgogIGlmIFsgJGNvZGUgLW5lIDAgXTsgdGhlbiBzdGF0dXM9ImZhaWxlZCI7IGZpCiAgbG9jYWwgbG9nY29udGVudD0iIgogIGlmIFsgLWYgIiRqdG1wIiBdOyB0aGVuIGxvZ2NvbnRlbnQ9JChjYXQgIiRqdG1wIiB8IHRyICJcXG4iICIgIiB8IGhlYWQgLWMgNTAwMCk7IGZpCiAgbG9jYWwgdHM9JChkYXRlIC1Jc2Vjb25kcykKICBwcmludGYgJ3tcXG4gICJpZCI6ICIlcyIsXFxuICAibmFtZSI6ICIlcyIsXFxuICAic291cmNlIjogIiVzIixcXG4gICJkZXN0IjogIiVzIixcXG4gICJtb2RlIjogImNvcHkiLFxcbiAgImRlbGV0ZUV4dHJhIjogJXMsXFxuICAic3RhdHVzIjogIiVzIixcXG4gICJsb2ciOiAiJXMiLFxcbiAgImNyZWF0ZWRBdCI6ICIlcyIsXFxuICAiY29tcGxldGVkQXQiOiAiJXMiXFxufScgXFwKICAgICIkamlkIiAiJG5hbWUiICIkc3JjIiAiJGRlc3QiICIkZGVsIiAiJHN0YXR1cyIgIiRsb2djb250ZW50IiAiJHRzIiAiJHRzIiA+ICIkamZpbGUiCiAgcm0gLWYgIiRqdG1wIgp9CgpgOwogIGZvciAobGV0IGkgPSAwOyBpIDwgcGFpcnMubGVuZ3RoOyBpKyspIHsKICAgIGNvbnN0IHAgPSBwYWlyc1tpXTsKICAgIHNjcmlwdCArPSBgIyBQYWlyICR7aSArIDF9OiAke3Auc291cmNlfSAtPiAke3AuZGVzdH1cbmA7CiAgICBzY3JpcHQgKz0gYHJ1bl9wYWlyICIke3Auc291cmNlfSIgIiR7cC5kZXN0fSIgIiR7cC5kZWxldGVFeHRyYSB8fCBmYWxzZX0iICIke3Auc291cmNlfSAtPiAke3AuZGVzdH0iXG5cbmA7CiAgfQogIGZzLndyaXRlRmlsZVN5bmMoQ1JPTl9TQ1JJUFQsIHNjcmlwdCk7CiAgZnMuY2htb2RTeW5jKENST05fU0NSSVBULCAnNzU1Jyk7Cn0KCmZ1bmN0aW9uIGJ1aWxkQ3JvbkxpbmUoc2NoZWR1bGUpIHsKICBpZiAoIXNjaGVkdWxlLmxlbmd0aCkgcmV0dXJuICcnOwogIGNvbnN0IHNvcnRlZCA9IFsuLi5zY2hlZHVsZV0uc29ydCgpOwogIGNvbnN0IGdyb3VwcyA9IHt9OwogIHNvcnRlZC5mb3JFYWNoKHQgPT4gewogICAgY29uc3QgW2gsIG1dID0gdC5zcGxpdCgnOicpOwogICAgY29uc3QgbWluID0gcGFyc2VJbnQobSk7CiAgICBpZiAoIWdyb3Vwc1ttaW5dKSBncm91cHNbbWluXSA9IFtdOwogICAgZ3JvdXBzW21pbl0ucHVzaChwYXJzZUludChoKSk7CiAgfSk7CiAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGdyb3VwcykubWFwKChbbWluLCBob3Vyc10pID0+IHsKICAgIHJldHVybiBgJHttaW59ICR7aG91cnMuam9pbignLCcpfSAqICogKiAke0NST05fU0NSSVBUfSA+PiAke1NZTkNfSk9CU19ESVJ9L2Nyb24ubG9nIDI+JjFgOwogIH0pLmpvaW4oJ1xuJyk7Cn0KCmFwcC5wb3N0KCcvYXBpL3N5bmMtc2V0dGluZ3MnLCAocmVxLCByZXMpID0+IHsKICB0cnkgewogICAgY29uc3Qgc2V0dGluZ3MgPSByZXEuYm9keTsKICAgIGZzLndyaXRlRmlsZVN5bmMoU1lOQ19TRVRUSU5HU19QQVRILCBKU09OLnN0cmluZ2lmeShzZXR0aW5ncywgbnVsbCwgMikpOwoKICAgIC8vIFdyaXRlIHN5bmMgc2NyaXB0CiAgICB3cml0ZUNyb25TY3JpcHQoc2V0dGluZ3MucGFpcnMgfHwgW10pOwoKICAgIC8vIFVwZGF0ZSBjcm9uIC0gcmVtb3ZlIEFMTCBvbGQgZWFzeXJjbG9uZSBlbnRyaWVzCiAgICBsZXQgY3JvbkxpbmVzID0gW107CiAgICB0cnkgewogICAgICBjb25zdCBleGlzdGluZyA9IGV4ZWNTeW5jKCdjcm9udGFiIC1sIDI+L2Rldi9udWxsJywgeyBlbmNvZGluZzogJ3V0Zi04JywgdGltZW91dDogNTAwMCB9KTsKICAgICAgY3JvbkxpbmVzID0gZXhpc3Rpbmcuc3BsaXQoJ1xuJykuZmlsdGVyKGwgPT4gIWwuaW5jbHVkZXMoJ2Nyb24tc3luYy5zaCcpICYmICFsLmluY2x1ZGVzKENST05fTUFSS0VSKSAmJiBsLnRyaW0oKSk7CiAgICB9IGNhdGNoIHt9CgogICAgY29uc3QgY3JvbkxpbmUgPSBidWlsZENyb25MaW5lKHNldHRpbmdzLnNjaGVkdWxlIHx8IFtdKTsKICAgIGlmIChjcm9uTGluZSkgewogICAgICBjcm9uTGluZXMucHVzaCgnJyk7CiAgICAgIGNyb25MaW5lcy5wdXNoKENST05fTUFSS0VSKTsKICAgICAgY3JvbkxpbmVzLnB1c2goY3JvbkxpbmUpOwogICAgfQoKICAgIGNvbnN0IG5ld0Nyb24gPSBjcm9uTGluZXMuam9pbignXG4nKSArICdcbic7CiAgICBjb25zdCB0bXBGaWxlID0gJy90bXAvZWFzeXJjbG9uZV9jcm9uX3RtcCc7CiAgICBmcy53cml0ZUZpbGVTeW5jKHRtcEZpbGUsIG5ld0Nyb24pOwogICAgZXhlY1N5bmMoYGNyb250YWIgJHt0bXBGaWxlfWAsIHsgdGltZW91dDogNTAwMCB9KTsKICAgIGZzLnVubGlua1N5bmModG1wRmlsZSk7CgogICAgcmVzLmpzb24oeyBvazogdHJ1ZSB9KTsKICB9IGNhdGNoIChlKSB7CiAgICByZXMuanNvbih7IG9rOiBmYWxzZSwgZXJyb3I6IGUubWVzc2FnZSB9KTsKICB9Cn0pOwoKYXBwLmdldCgnL2FwaS9jcm9uLWluZm8nLCAocmVxLCByZXMpID0+IHsKICB0cnkgewogICAgbGV0IG91dHB1dCA9ICcnOwoKICAgIC8vIENoZWNrIHVzZXIgY3JvbnRhYiBmaXJzdCAobW9zdCByZWxldmFudCkKICAgIG91dHB1dCArPSAnPT09IHJvb3Qg44GuIGNyb250YWIgPT09XG4nOwogICAgdHJ5IHsKICAgICAgY29uc3QgdXNlckNyb24gPSBleGVjU3luYygnY3JvbnRhYiAtbCAyPi9kZXYvbnVsbCB8fCBlY2hvICIoY3JvbnRhYuOBquOBlykiJywgeyBlbmNvZGluZzogJ3V0Zi04JywgdGltZW91dDogNTAwMCB9KTsKICAgICAgb3V0cHV0ICs9IHVzZXJDcm9uOwogICAgfSBjYXRjaCB7IG91dHB1dCArPSAnKGNyb250YWLjgarjgZcpXG4nOyB9CgogICAgLy8gQ2hlY2sgcmNsb25lIHJlbGF0ZWQgKGZyb20gYWxsIHNvdXJjZXMpCiAgICBvdXRwdXQgKz0gJ1xuPT09IHJjbG9uZSDplqLpgKPjga4gY3JvbiDjgqjjg7Pjg4jjg6ogPT09XG4nOwogICAgdHJ5IHsKICAgICAgY29uc3QgcmNsb25lQ3JvbiA9IGV4ZWNTeW5jKCdjcm9udGFiIC1sIDI+L2Rldi9udWxsIHwgZ3JlcCAtaSByY2xvbmUgfHwgZWNobyAiKHJjbG9uZemWoumAo+OBrmNyb27jgqjjg7Pjg4jjg6rjgarjgZcpIicsIHsgZW5jb2Rpbmc6ICd1dGYtOCcsIHRpbWVvdXQ6IDUwMDAgfSk7CiAgICAgIG91dHB1dCArPSByY2xvbmVDcm9uOwogICAgfSBjYXRjaCB7IG91dHB1dCArPSAnKHJjbG9uZemWoumAo+OBrmNyb27jgqjjg7Pjg4jjg6rjgarjgZcpXG4nOyB9CgogICAgLy8gQ2hlY2sgc2NoZWR1bGVkIHN5bmMgc2V0dGluZ3MKICAgIG91dHB1dCArPSAnXG49PT0gRWFzeVJjbG9uZSDjgrnjgrHjgrjjg6Xjg7zjg6voqK3lrpogPT09XG4nOwogICAgdHJ5IHsKICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoU1lOQ19TRVRUSU5HU19QQVRIKSkgewogICAgICAgIGNvbnN0IHNldHRpbmdzID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMoU1lOQ19TRVRUSU5HU19QQVRILCAndXRmLTgnKSk7CiAgICAgICAgb3V0cHV0ICs9IGDlkIzmnJ/jg5rjgqLmlbA6ICR7KHNldHRpbmdzLnBhaXJzIHx8IFtdKS5sZW5ndGh9XG5gOwogICAgICAgIG91dHB1dCArPSBg44K544Kx44K444Ol44O844OrOiAkeyhzZXR0aW5ncy5zY2hlZHVsZSB8fCBbXSkuam9pbignLCAnKSB8fCAn5pyq6Kit5a6aJ31cbmA7CiAgICAgICAgKHNldHRpbmdzLnBhaXJzIHx8IFtdKS5mb3JFYWNoKChwLCBpKSA9PiB7CiAgICAgICAgICBvdXRwdXQgKz0gYCAgWyR7aSArIDF9XSAke3Auc291cmNlfSDihpIgJHtwLmRlc3R9JHtwLmRlbGV0ZUV4dHJhID8gJyAo5YmK6Zmk44GC44KKKScgOiAnJ31cbmA7CiAgICAgICAgfSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgb3V0cHV0ICs9ICco6Kit5a6a44OV44Kh44Kk44Or44Gq44GXKVxuJzsKICAgICAgfQogICAgfSBjYXRjaCB7IG91dHB1dCArPSAnKOioreWumuiqreOBv+WPluOCiuOCqOODqeODvClcbic7IH0KCiAgICAvLyBTeXN0ZW0gY3JvbnRhYiAoYnJpZWYpCiAgICBvdXRwdXQgKz0gJ1xuPT09IOOCt+OCueODhuODoCBjcm9udGFiICjmipznsospID09PVxuJzsKICAgIHRyeSB7CiAgICAgIGNvbnN0IHN5c0Nyb24gPSBleGVjU3luYygnY2F0IC9ldGMvY3JvbnRhYiAyPi9kZXYvbnVsbCB8IGdyZXAgLXYgIl4jIiB8IGdyZXAgLXYgIl4kIiB8fCBlY2hvICIo44OV44Kh44Kk44Or44Gq44GXKSInLCB7IGVuY29kaW5nOiAndXRmLTgnLCB0aW1lb3V0OiA1MDAwIH0pOwogICAgICBvdXRwdXQgKz0gc3lzQ3JvbjsKICAgIH0gY2F0Y2ggeyBvdXRwdXQgKz0gJyjoqq3jgb/lj5bjgorkuI3lj68pXG4nOyB9CgogICAgLy8gQ2hlY2sgc3lzdGVtZCB0aW1lcnMgKHJjbG9uZSByZWxhdGVkKQogICAgb3V0cHV0ICs9ICdcbj09PSBzeXN0ZW1kIOOCv+OCpOODnuODvCAocmNsb25l6Zai6YCjKSA9PT1cbic7CiAgICB0cnkgewogICAgICBjb25zdCB0aW1lcnMgPSBleGVjU3luYygnc3lzdGVtY3RsIGxpc3QtdGltZXJzIC0tYWxsIC0tbm8tcGFnZXIgMj4vZGV2L251bGwgfCBncmVwIC1pIHJjbG9uZSB8fCBlY2hvICIocmNsb25l6Zai6YCj44Gu44K/44Kk44Oe44O844Gq44GXKSInLCB7IGVuY29kaW5nOiAndXRmLTgnLCB0aW1lb3V0OiA1MDAwIH0pOwogICAgICBvdXRwdXQgKz0gdGltZXJzOwogICAgfSBjYXRjaCB7IG91dHB1dCArPSAnKHJjbG9uZemWoumAo+OBruOCv+OCpOODnuODvOOBquOBlylcbic7IH0KCiAgICByZXMuanNvbih7IG9rOiB0cnVlLCBvdXRwdXQgfSk7CiAgfSBjYXRjaCAoZSkgewogICAgcmVzLmpzb24oeyBvazogZmFsc2UsIGVycm9yOiBlLm1lc3NhZ2UgfSk7CiAgfQp9KTsKCi8vID09PSBUZW1wIFNTSCBzZXR1cCA9PT0KYXBwLnBvc3QoJy9hcGkvc3NoL3NldHVwJywgKHJlcSwgcmVzKSA9PiB7CiAgdHJ5IHsKICAgIGNvbnN0IHBhc3N3b3JkID0gJ3JjbG9uZSc7CiAgICBleGVjU3luYyhgZWNobyAicm9vdDoke3Bhc3N3b3JkfSIgfCBjaHBhc3N3ZGAsIHsgdGltZW91dDogNTAwMCB9KTsKICAgIGV4ZWNTeW5jKGBzZWQgLWkgJ3MvXlBhc3N3b3JkQXV0aGVudGljYXRpb24gbm8vUGFzc3dvcmRBdXRoZW50aWNhdGlvbiB5ZXMvJyAvZXRjL3NzaC9zc2hkX2NvbmZpZy5kLzYwLWNsb3VkaW1nLXNldHRpbmdzLmNvbmYgMj4vZGV2L251bGwgfHwgc2VkIC1pICdzL14jKlBhc3N3b3JkQXV0aGVudGljYXRpb24uKi9QYXNzd29yZEF1dGhlbnRpY2F0aW9uIHllcy8nIC9ldGMvc3NoL3NzaGRfY29uZmlnIDI+L2Rldi9udWxsIHx8IHRydWVgLCB7IHRpbWVvdXQ6IDMwMDAgfSk7CiAgICBleGVjU3luYyhgZ3JlcCAtcSAiS2JkSW50ZXJhY3RpdmVBdXRoZW50aWNhdGlvbiB5ZXMiIC9ldGMvc3NoL3NzaGRfY29uZmlnLmQvNjAtY2xvdWRpbWctc2V0dGluZ3MuY29uZiAyPi9kZXYvbnVsbCB8fCBlY2hvICJLYmRJbnRlcmFjdGl2ZUF1dGhlbnRpY2F0aW9uIHllcyIgPj4gL2V0Yy9zc2gvc3NoZF9jb25maWcuZC82MC1jbG91ZGltZy1zZXR0aW5ncy5jb25mIDI+L2Rldi9udWxsIHx8IHRydWVgLCB7IHRpbWVvdXQ6IDMwMDAgfSk7CiAgICBleGVjU3luYyhgZ3JlcCAtcSAiUGVybWl0Um9vdExvZ2luIHllcyIgL2V0Yy9zc2gvc3NoZF9jb25maWcuZC82MC1jbG91ZGltZy1zZXR0aW5ncy5jb25mIDI+L2Rldi9udWxsIHx8IGVjaG8gIlBlcm1pdFJvb3RMb2dpbiB5ZXMiID4+IC9ldGMvc3NoL3NzaGRfY29uZmlnLmQvNjAtY2xvdWRpbWctc2V0dGluZ3MuY29uZiAyPi9kZXYvbnVsbCB8fCB0cnVlYCwgeyB0aW1lb3V0OiAzMDAwIH0pOwogICAgZXhlY1N5bmMoYHN5c3RlbWN0bCByZXN0YXJ0IHNzaGRgLCB7IHRpbWVvdXQ6IDUwMDAgfSk7CiAgICBjb25zdCBob3N0bmFtZSA9IGV4ZWNTeW5jKCdob3N0bmFtZSAtSSB8IGF3ayBcJ3twcmludCAkMX1cJycsIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSkudHJpbSgpOwogICAgcmVzLmpzb24oeyBvazogdHJ1ZSwgcGFzc3dvcmQsIGhvc3RuYW1lIH0pOwogIH0gY2F0Y2ggKGUpIHsKICAgIHJlcy5qc29uKHsgb2s6IGZhbHNlLCBlcnJvcjogZS5tZXNzYWdlIH0pOwogIH0KfSk7CgphcHAucG9zdCgnL2FwaS9zc2gvdGVhcmRvd24nLCAocmVxLCByZXMpID0+IHsKICB0cnkgewogICAgZXhlY1N5bmMoYHBhc3N3ZCAtZCByb290IDI+L2Rldi9udWxsOyB0cnVlYCwgeyB0aW1lb3V0OiA1MDAwIH0pOwogICAgZXhlY1N5bmMoYHNlZCAtaSAncy9eUGFzc3dvcmRBdXRoZW50aWNhdGlvbiB5ZXMvUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBuby8nIC9ldGMvc3NoL3NzaGRfY29uZmlnLmQvNjAtY2xvdWRpbWctc2V0dGluZ3MuY29uZmAsIHsgdGltZW91dDogMzAwMCB9KTsKICAgIGV4ZWNTeW5jKGBzZWQgLWkgJy9eS2JkSW50ZXJhY3RpdmVBdXRoZW50aWNhdGlvbiB5ZXMkL2QnIC9ldGMvc3NoL3NzaGRfY29uZmlnLmQvNjAtY2xvdWRpbWctc2V0dGluZ3MuY29uZmAsIHsgdGltZW91dDogMzAwMCB9KTsKICAgIGV4ZWNTeW5jKGBzeXN0ZW1jdGwgcmVzdGFydCBzc2hkYCwgeyB0aW1lb3V0OiA1MDAwIH0pOwogICAgcmVzLmpzb24oeyBvazogdHJ1ZSB9KTsKICB9IGNhdGNoIChlKSB7CiAgICByZXMuanNvbih7IG9rOiBmYWxzZSwgZXJyb3I6IGUubWVzc2FnZSB9KTsKICB9Cn0pOwoKYXBwLnBvc3QoJy9hcGkvc3NoL3N0YXR1cycsIChyZXEsIHJlcykgPT4gewogIHRyeSB7CiAgICBjb25zdCBvdXQgPSBleGVjU3luYygnc3NoZCAtVCAyPi9kZXYvbnVsbCB8IGdyZXAgcGFzc3dvcmRhdXRoZW50aWNhdGlvbicsIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSk7CiAgICBjb25zdCBlbmFibGVkID0gb3V0LmluY2x1ZGVzKCd5ZXMnKTsKICAgIHJlcy5qc29uKHsgb2s6IHRydWUsIGVuYWJsZWQgfSk7CiAgfSBjYXRjaCAoZSkgewogICAgcmVzLmpzb24oeyBvazogZmFsc2UsIGVycm9yOiBlLm1lc3NhZ2UgfSk7CiAgfQp9KTsKCi8vID09PSBBdXRoOiBydW4gcmNsb25lIGF1dGhvcml6ZSB0byBnZXQgdG9rZW4gPT09CmNvbnN0IGF1dGhTZXNzaW9ucyA9IG5ldyBNYXAoKTsKCmFwcC5wb3N0KCcvYXBpL2F1dGgvc3RhcnQnLCAocmVxLCByZXMpID0+IHsKICBjb25zdCB7IHR5cGUsIHJlbW90ZU5hbWUgfSA9IHJlcS5ib2R5OwogIGlmICghWydkcml2ZScsICdvbmVkcml2ZSddLmluY2x1ZGVzKHR5cGUpKSByZXR1cm4gcmVzLnN0YXR1cyg0MDApLmpzb24oeyBlcnJvcjogJ+OCteODneODvOODiOOBleOCjOOBpuOBhOOBquOBhOOCv+OCpOODl+OBp+OBmScgfSk7CgogIC8vIEtpbGwgYW55IGxpbmdlcmluZyByY2xvbmUgYXV0aG9yaXplIHByb2Nlc3NlcwogIHRyeSB7IGV4ZWNTeW5jKCdwa2lsbCAtOSAtZiAicmNsb25lIGF1dGhvcml6ZSInLCB7IHRpbWVvdXQ6IDMwMDAgfSk7IH0gY2F0Y2gge30KCiAgY29uc3Qgc2Vzc2lvbklkID0gYGF1dGhfJHtEYXRlLm5vdygpfWA7CiAgY29uc3QgYXJncyA9IFsnYXV0aG9yaXplJywgdHlwZSwgJy0tYXV0aC1uby1vcGVuLWJyb3dzZXInXTsKCiAgY29uc3QgcHJvYyA9IHNwYXduKCdyY2xvbmUnLCBhcmdzLCB7CiAgICBlbnY6IHsgLi4ucHJvY2Vzcy5lbnYsIFJDTE9ORV9DT05GSUc6IENPTkZJR19QQVRIIH0sCiAgICBzdGRpbzogWydwaXBlJywgJ3BpcGUnLCAncGlwZSddCiAgfSk7CgogIGxldCBhdXRoVXJsID0gJyc7CiAgbGV0IHN0ZG91dEJ1ZiA9ICcnOwoKICBwcm9jLnN0ZGVyci5vbignZGF0YScsIGQgPT4gewogICAgY29uc3QgdGV4dCA9IGQudG9TdHJpbmcoKTsKICAgIGNvbnN0IG1hdGNoID0gdGV4dC5tYXRjaCgvKGh0dHBzPzpcL1wvW15ccyInXStcL2F1dGhcP3N0YXRlPVteXHMiJ10rKS8pOwogICAgaWYgKG1hdGNoICYmICFhdXRoVXJsKSB7CiAgICAgIGF1dGhVcmwgPSBtYXRjaFsxXS5yZXBsYWNlKC9bIiddJC8sICcnKTsKICAgIH0KICB9KTsKCiAgY29uc3Qgc2Vzc2lvbiA9IHsgcHJvYywgdHlwZSwgcmVtb3RlTmFtZSwgdG9rZW46IG51bGwsIGRvbmU6IGZhbHNlLCBhdXRoVXJsOiAnJyB9OwogIGF1dGhTZXNzaW9ucy5zZXQoc2Vzc2lvbklkLCBzZXNzaW9uKTsKCiAgcHJvYy5zdGRvdXQub24oJ2RhdGEnLCBkID0+IHsKICAgIHN0ZG91dEJ1ZiArPSBkLnRvU3RyaW5nKCk7CiAgfSk7CgogIHByb2Mub24oJ2Nsb3NlJywgKGNvZGUpID0+IHsKICAgIGNvbnN0IHJhdyA9IHN0ZG91dEJ1Zi50cmltKCk7CiAgICBjb25zb2xlLmxvZyhgW0F1dGggJHtzZXNzaW9uSWR9XSByY2xvbmUgY2xvc2VkIGNvZGU9JHtjb2RlfSBzdGRvdXQ9JHtyYXcuc3Vic3RyaW5nKDAsIDMwMCl9YCk7CiAgICAvLyByY2xvbmUgYXV0aG9yaXplIHdyYXBzIEpTT04gaW4gIlBhc3RlIHRoZSBmb2xsb3dpbmcuLi4iIHRleHQKICAgIGNvbnN0IGpzb25NYXRjaCA9IHJhdy5tYXRjaCgvKFx7W1xzXFNdKlx9KS8pOwogICAgaWYgKGpzb25NYXRjaCkgewogICAgICB0cnkgewogICAgICAgIHNlc3Npb24udG9rZW4gPSBKU09OLnBhcnNlKGpzb25NYXRjaFsxXSk7CiAgICAgICAgY29uc29sZS5sb2coYFtBdXRoICR7c2Vzc2lvbklkfV0gdG9rZW4gcGFyc2VkIE9LYCk7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICBjb25zb2xlLmxvZyhgW0F1dGggJHtzZXNzaW9uSWR9XSB0b2tlbiBwYXJzZSBGQUlMRUQ6ICR7ZS5tZXNzYWdlfWApOwogICAgICB9CiAgICB9CiAgICBzZXNzaW9uLmRvbmUgPSB0cnVlOwogIH0pOwoKICBjb25zdCBjaGVjayA9IHNldEludGVydmFsKCgpID0+IHsKICAgIGlmIChhdXRoVXJsICYmICFzZXNzaW9uLmF1dGhVcmwpIHNlc3Npb24uYXV0aFVybCA9IGF1dGhVcmw7CiAgICBpZiAoc2Vzc2lvbi5kb25lICYmIHNlc3Npb24udG9rZW4pIHsKICAgICAgY29uc29sZS5sb2coYFtBdXRoICR7c2Vzc2lvbklkfV0gd3JpdGluZyB0b2tlbiB0byBjb25maWdgKTsKICAgICAgY2xlYXJJbnRlcnZhbChjaGVjayk7CiAgICAgIHdyaXRlVG9rZW5Ub0NvbmZpZyhzZXNzaW9uLnJlbW90ZU5hbWUgfHwgYHJlbW90ZV8ke0RhdGUubm93KCl9YCwgc2Vzc2lvbi50eXBlLCBzZXNzaW9uLnRva2VuKTsKICAgICAgYXV0aFNlc3Npb25zLmRlbGV0ZShzZXNzaW9uSWQpOwogICAgfSBlbHNlIGlmIChzZXNzaW9uLmRvbmUgJiYgIXNlc3Npb24udG9rZW4pIHsKICAgICAgY29uc29sZS5sb2coYFtBdXRoICR7c2Vzc2lvbklkfV0gZG9uZSBidXQgbm8gdG9rZW4sIHN0ZG91dCB3YXM6ICR7c3Rkb3V0QnVmLnN1YnN0cmluZygwLCAyMDApfWApOwogICAgfQogIH0sIDUwMCk7CgogIHNldFRpbWVvdXQoKCkgPT4gewogICAgY2xlYXJJbnRlcnZhbChjaGVjayk7CiAgICBpZiAoYXV0aFNlc3Npb25zLmhhcyhzZXNzaW9uSWQpKSB7CiAgICAgIHNlc3Npb24ucHJvYy5raWxsKCk7CiAgICAgIGF1dGhTZXNzaW9ucy5kZWxldGUoc2Vzc2lvbklkKTsKICAgIH0KICB9LCAzMDAwMDApOwoKICByZXMuanNvbih7IG9rOiB0cnVlLCBzZXNzaW9uSWQsIGF1dGhVcmw6IG51bGwgfSk7Cn0pOwoKYXBwLmdldCgnL2FwaS9hdXRoL3BvbGwvOnNlc3Npb25JZCcsIChyZXEsIHJlcykgPT4gewogIGNvbnN0IHNlc3Npb24gPSBhdXRoU2Vzc2lvbnMuZ2V0KHJlcS5wYXJhbXMuc2Vzc2lvbklkKTsKICBpZiAoIXNlc3Npb24pIHJldHVybiByZXMuanNvbih7IGRvbmU6IHRydWUsIHN1Y2Nlc3M6IGZhbHNlLCBlcnJvcjogJ+OCu+ODg+OCt+ODp+ODs+OBjOimi+OBpOOBi+OCiuOBvuOBm+OCkycgfSk7CiAgaWYgKHNlc3Npb24uZG9uZSAmJiBzZXNzaW9uLnRva2VuKSB7CiAgICByZXR1cm4gcmVzLmpzb24oeyBkb25lOiB0cnVlLCBzdWNjZXNzOiB0cnVlIH0pOwogIH0KICBpZiAoc2Vzc2lvbi5kb25lICYmICFzZXNzaW9uLnRva2VuKSB7CiAgICByZXR1cm4gcmVzLmpzb24oeyBkb25lOiB0cnVlLCBzdWNjZXNzOiBmYWxzZSwgZXJyb3I6ICfjg4jjg7zjgq/jg7Plj5blvpfjgavlpLHmlZfjgZfjgb7jgZfjgZ8nIH0pOwogIH0KICByZXMuanNvbih7IGRvbmU6IGZhbHNlLCBhdXRoVXJsOiBzZXNzaW9uLmF1dGhVcmwgfHwgbnVsbCB9KTsKfSk7CgpmdW5jdGlvbiB3cml0ZVRva2VuVG9Db25maWcocmVtb3RlTmFtZSwgdHlwZSwgdG9rZW4pIHsKICBjb25zdCB0b2tlblN0ciA9IHR5cGVvZiB0b2tlbiA9PT0gJ3N0cmluZycgPyB0b2tlbiA6IEpTT04uc3RyaW5naWZ5KHRva2VuKTsKICBsZXQgY29udGVudCA9IHJlYWRDb25maWcoKTsKCiAgY29uc3Qgc2VjdGlvblJlID0gbmV3IFJlZ0V4cChgXFxbJHtyZW1vdGVOYW1lLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXVxcXS9nLCAnXFwkJicpfVxcXVteXFxbXSpgLCAnZycpOwogIGlmIChzZWN0aW9uUmUudGVzdChjb250ZW50KSkgewogICAgY29udGVudCA9IGNvbnRlbnQucmVwbGFjZShzZWN0aW9uUmUsICcnKS5yZXBsYWNlKC9cbnszLH0vZywgJ1xuXG4nKS50cmltKCk7CiAgfQoKICBsZXQgc2VjdGlvbiA9IGBcblske3JlbW90ZU5hbWV9XVxudHlwZSA9ICR7dHlwZX1gOwogIGlmICh0eXBlID09PSAnZHJpdmUnKSB7CiAgICBzZWN0aW9uICs9IGBcbnNjb3BlID0gZHJpdmVgOwogIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29uZWRyaXZlJykgewogICAgc2VjdGlvbiArPSBgXG5kcml2ZV90eXBlID0gcGVyc29uYWxgOwogICAgLy8gR2V0IGRyaXZlX2lkIGZyb20gTWljcm9zb2Z0IEdyYXBoIEFQSQogICAgdHJ5IHsKICAgICAgY29uc3QgdG9rZW5PYmogPSB0eXBlb2YgdG9rZW4gPT09ICdzdHJpbmcnID8gSlNPTi5wYXJzZSh0b2tlbikgOiB0b2tlbjsKICAgICAgY29uc3QgYWNjZXNzVG9rZW4gPSB0b2tlbk9iai5hY2Nlc3NfdG9rZW47CiAgICAgIGlmIChhY2Nlc3NUb2tlbikgewogICAgICAgIGNvbnN0IHJlc3VsdCA9IGV4ZWNTeW5jKGBjdXJsIC1zIC1IICJBdXRob3JpemF0aW9uOiBCZWFyZXIgJHthY2Nlc3NUb2tlbn0iICJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20vdjEuMC9tZS9kcml2ZSJgLCB7CiAgICAgICAgICBlbmNvZGluZzogJ3V0Zi04JywgdGltZW91dDogMTAwMDAKICAgICAgICB9KTsKICAgICAgICBjb25zdCBkcml2ZUluZm8gPSBKU09OLnBhcnNlKHJlc3VsdCk7CiAgICAgICAgaWYgKGRyaXZlSW5mby5pZCkgewogICAgICAgICAgc2VjdGlvbiArPSBgXG5kcml2ZV9pZCA9ICR7ZHJpdmVJbmZvLmlkfWA7CiAgICAgICAgfQogICAgICB9CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIGNvbnNvbGUubG9nKGBbQ29uZmlnXSBGYWlsZWQgdG8gZ2V0IGRyaXZlX2lkIGZvciAke3JlbW90ZU5hbWV9OiAke2UubWVzc2FnZX1gKTsKICAgIH0KICB9CiAgc2VjdGlvbiArPSBgXG50b2tlbiA9ICR7dG9rZW5TdHJ9YDsKCiAgY29uc3Qgc2VwID0gY29udGVudC50cmltKCkgPyAnXG4nIDogJyc7CiAgZnMud3JpdGVGaWxlU3luYyhDT05GSUdfUEFUSCwgKGNvbnRlbnQudHJpbSgpICsgc2VwICsgc2VjdGlvbiArICdcbicpLnRyaW0oKSArICdcbicpOwp9CgovLyA9PT0gRmlsZSBCcm93c2VyID09PQphcHAuZ2V0KCcvYXBpL2Jyb3dzZS86cmVtb3RlLyonLCAocmVxLCByZXMpID0+IHsKICBjb25zdCByZW1vdGUgPSByZXEucGFyYW1zLnJlbW90ZTsKICBjb25zdCBzdWJQYXRoID0gcmVxLnBhcmFtc1swXSB8fCAnJzsKICBjb25zdCB0YXJnZXQgPSBzdWJQYXRoID8gYCR7cmVtb3RlfTovJHtzdWJQYXRofWAgOiBgJHtyZW1vdGV9OmA7CiAgY29uc3QgcmVzdWx0ID0gcmNsb25lKFsnbHNmJywgYCIke3RhcmdldH0iYCwgJy0tZm9ybWF0JywgJ3RwJywgJy0tZGlycy1vbmx5J10pOwogIGlmICghcmVzdWx0Lm9rICYmICFyZXN1bHQuZGF0YSkgcmV0dXJuIHJlcy5qc29uKHsgaXRlbXM6IFtdLCBlcnJvcjogcmVzdWx0LmVycm9yIH0pOwoKICBjb25zdCBsaW5lcyA9IChyZXN1bHQuZGF0YSB8fCAnJykuc3BsaXQoJ1xuJykuZmlsdGVyKEJvb2xlYW4pOwogIGNvbnN0IGl0ZW1zID0gbGluZXMubWFwKGwgPT4gewogICAgY29uc3QgaXNEaXIgPSBsLmVuZHNXaXRoKCcvJyk7CiAgICByZXR1cm4geyBuYW1lOiBpc0RpciA/IGwuc2xpY2UoMCwgLTEpIDogbCwgaXNEaXIgfTsKICB9KS5zb3J0KChhLCBiKSA9PiBiLmlzRGlyIC0gYS5pc0RpciB8fCBhLm5hbWUubG9jYWxlQ29tcGFyZShiLm5hbWUpKTsKCiAgcmVzLmpzb24oeyBpdGVtcywgcGF0aDogc3ViUGF0aCB9KTsKfSk7CgphcHAuZ2V0KCcvYXBpL2Jyb3dzZS1maWxlcy86cmVtb3RlLyonLCAocmVxLCByZXMpID0+IHsKICBjb25zdCByZW1vdGUgPSByZXEucGFyYW1zLnJlbW90ZTsKICBjb25zdCBzdWJQYXRoID0gcmVxLnBhcmFtc1swXSB8fCAnJzsKICBjb25zdCB0YXJnZXQgPSBzdWJQYXRoID8gYCR7cmVtb3RlfTovJHtzdWJQYXRofWAgOiBgJHtyZW1vdGV9OmA7CiAgY29uc3QgcmVzdWx0ID0gcmNsb25lKFsnbHNmJywgYCIke3RhcmdldH0iYCwgJy0tZm9ybWF0JywgJ3RwJ10pOwogIGlmICghcmVzdWx0Lm9rICYmICFyZXN1bHQuZGF0YSkgcmV0dXJuIHJlcy5qc29uKHsgaXRlbXM6IFtdLCBlcnJvcjogcmVzdWx0LmVycm9yIH0pOwoKICBjb25zdCBsaW5lcyA9IChyZXN1bHQuZGF0YSB8fCAnJykuc3BsaXQoJ1xuJykuZmlsdGVyKEJvb2xlYW4pOwogIGNvbnN0IGl0ZW1zID0gbGluZXMubWFwKGwgPT4gewogICAgY29uc3QgaXNEaXIgPSBsLmVuZHNXaXRoKCcvJyk7CiAgICByZXR1cm4geyBuYW1lOiBpc0RpciA/IGwuc2xpY2UoMCwgLTEpIDogbCwgaXNEaXIgfTsKICB9KS5zb3J0KChhLCBiKSA9PiBiLmlzRGlyIC0gYS5pc0RpciB8fCBhLm5hbWUubG9jYWxlQ29tcGFyZShiLm5hbWUpKTsKCiAgcmVzLmpzb24oeyBpdGVtcywgcGF0aDogc3ViUGF0aCB9KTsKfSk7CgovLyA9PT0gU3luYyBKb2JzID09PQpjb25zdCBKT0JfUkVURU5USU9OX0RBWVMgPSAzMDsKCmZ1bmN0aW9uIGNsZWFudXBPbGRKb2JzKCkgewogIHRyeSB7CiAgICBjb25zdCBmaWxlcyA9IGZzLnJlYWRkaXJTeW5jKFNZTkNfSk9CU19ESVIpLmZpbHRlcihmID0+IGYuZW5kc1dpdGgoJy5qc29uJykpOwogICAgY29uc3QgY3V0b2ZmID0gRGF0ZS5ub3coKSAtIEpPQl9SRVRFTlRJT05fREFZUyAqIDI0ICogNjAgKiA2MCAqIDEwMDA7CiAgICBmb3IgKGNvbnN0IGYgb2YgZmlsZXMpIHsKICAgICAgdHJ5IHsKICAgICAgICBjb25zdCBqb2IgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhwYXRoLmpvaW4oU1lOQ19KT0JTX0RJUiwgZiksICd1dGYtOCcpKTsKICAgICAgICBjb25zdCBjcmVhdGVkID0gbmV3IERhdGUoam9iLmNyZWF0ZWRBdCB8fCAwKS5nZXRUaW1lKCk7CiAgICAgICAgaWYgKGNyZWF0ZWQgPCBjdXRvZmYpIGZzLnVubGlua1N5bmMocGF0aC5qb2luKFNZTkNfSk9CU19ESVIsIGYpKTsKICAgICAgfSBjYXRjaCB7fQogICAgfQogIH0gY2F0Y2gge30KfQoKYXBwLmdldCgnL2FwaS9qb2JzJywgKHJlcSwgcmVzKSA9PiB7CiAgdHJ5IHsKICAgIGNsZWFudXBPbGRKb2JzKCk7CiAgICBjb25zdCBmaWxlcyA9IGZzLnJlYWRkaXJTeW5jKFNZTkNfSk9CU19ESVIpLmZpbHRlcihmID0+IGYuZW5kc1dpdGgoJy5qc29uJykpOwogICAgY29uc3Qgam9icyA9IGZpbGVzLm1hcChmID0+IHsKICAgICAgdHJ5IHsgcmV0dXJuIEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKHBhdGguam9pbihTWU5DX0pPQlNfRElSLCBmKSwgJ3V0Zi04JykpOyB9CiAgICAgIGNhdGNoIHsgcmV0dXJuIG51bGw7IH0KICAgIH0pLmZpbHRlcihCb29sZWFuKTsKICAgIGpvYnMuc29ydCgoYSwgYikgPT4gbmV3IERhdGUoYi5jcmVhdGVkQXQgfHwgMCkgLSBuZXcgRGF0ZShhLmNyZWF0ZWRBdCB8fCAwKSk7CiAgICByZXMuanNvbih7IGpvYnMgfSk7CiAgfSBjYXRjaCAoZSkgewogICAgcmVzLmpzb24oeyBqb2JzOiBbXSB9KTsKICB9Cn0pOwoKYXBwLnBvc3QoJy9hcGkvam9icycsIChyZXEsIHJlcykgPT4gewogIGNvbnN0IHsgc291cmNlLCBkZXN0LCBtb2RlLCBleGNsdWRlLCBkcnlSdW4sIHZlcmJvc2UsIG5hbWUsIGRlbGV0ZUV4dHJhIH0gPSByZXEuYm9keTsKICBpZiAoIXNvdXJjZSB8fCAhZGVzdCkgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5qc29uKHsgZXJyb3I6ICfjgrPjg5Tjg7zlhYPjgajjgrPjg5Tjg7zlhYjjga/lv4XpoIjjgafjgZknIH0pOwoKICBjb25zdCBqb2JJZCA9IGBqb2JfJHtEYXRlLm5vdygpfWA7CiAgY29uc3Qgam9iID0gewogICAgaWQ6IGpvYklkLAogICAgbmFtZTogbmFtZSB8fCBgJHtzb3VyY2Uuc3BsaXQoJzonKVswXX0g4oaSICR7ZGVzdC5zcGxpdCgnOicpWzBdfWAsCiAgICBzb3VyY2UsIGRlc3QsCiAgICBtb2RlOiBtb2RlIHx8ICdjb3B5JywKICAgIGV4Y2x1ZGU6IGV4Y2x1ZGUgfHwgJycsCiAgICBkcnlSdW46ICEhZHJ5UnVuLAogICAgdmVyYm9zZTogISF2ZXJib3NlLAogICAgZGVsZXRlRXh0cmE6ICEhZGVsZXRlRXh0cmEsCiAgICBzdGF0dXM6ICdydW5uaW5nJywKICAgIGxvZzogJycsCiAgICBjcmVhdGVkQXQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKQogIH07CiAgZnMud3JpdGVGaWxlU3luYyhwYXRoLmpvaW4oU1lOQ19KT0JTX0RJUiwgYCR7am9iSWR9Lmpzb25gKSwgSlNPTi5zdHJpbmdpZnkoam9iLCBudWxsLCAyKSk7CgogIGNvbnN0IGFyZ3MgPSBbZGVsZXRlRXh0cmEgPyAnc3luYycgOiAnY29weSddOwogIGFyZ3MucHVzaCgnLS1zdGF0cycsICcycycsICctLXN0YXRzLW9uZS1saW5lJywgJy12Jyk7CiAgaWYgKGRyeVJ1bikgYXJncy5wdXNoKCctLWRyeS1ydW4nKTsKICBpZiAoZXhjbHVkZSkgYXJncy5wdXNoKCctLWV4Y2x1ZGUnLCBleGNsdWRlKTsKICBhcmdzLnB1c2goc291cmNlLCBkZXN0KTsKCiAgY29uc3Qgam9iRmlsZSA9IHBhdGguam9pbihTWU5DX0pPQlNfRElSLCBgJHtqb2JJZH0uanNvbmApOwogIGNvbnN0IHByb2MgPSBzcGF3bigncmNsb25lJywgYXJncywgewogICAgZW52OiB7IC4uLnByb2Nlc3MuZW52LCBSQ0xPTkVfQ09ORklHOiBDT05GSUdfUEFUSCB9LAogICAgc3RkaW86IFsncGlwZScsICdwaXBlJywgJ3BpcGUnXQogIH0pOwogIGxldCBsb2dCdWYgPSAnJzsKICBwcm9jLnN0ZG91dC5vbignZGF0YScsIGQgPT4geyBsb2dCdWYgKz0gZC50b1N0cmluZygpOyB9KTsKICBwcm9jLnN0ZGVyci5vbignZGF0YScsIGQgPT4geyBsb2dCdWYgKz0gZC50b1N0cmluZygpOyB9KTsKICBjb25zdCBzYXZlTG9nID0gc2V0SW50ZXJ2YWwoKCkgPT4gewogICAgaWYgKGxvZ0J1ZikgewogICAgICBqb2IubG9nID0gbG9nQnVmOwogICAgICB0cnkgeyBmcy53cml0ZUZpbGVTeW5jKGpvYkZpbGUsIEpTT04uc3RyaW5naWZ5KGpvYiwgbnVsbCwgMikpOyB9IGNhdGNoIHt9CiAgICB9CiAgfSwgNTAwKTsKICBwcm9jLm9uKCdjbG9zZScsIChjb2RlKSA9PiB7CiAgICBjbGVhckludGVydmFsKHNhdmVMb2cpOwogICAgam9iLnN0YXR1cyA9IGNvZGUgPT09IDAgPyAnY29tcGxldGVkJyA6ICdmYWlsZWQnOwogICAgam9iLmNvbXBsZXRlZEF0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpOwogICAgam9iLmxvZyA9IGxvZ0J1ZiB8fCAnKG5vIG91dHB1dCknOwogICAgam9iLmV4aXRDb2RlID0gY29kZTsKICAgIHRyeSB7IGZzLndyaXRlRmlsZVN5bmMoam9iRmlsZSwgSlNPTi5zdHJpbmdpZnkoam9iLCBudWxsLCAyKSk7IH0gY2F0Y2gge30KICB9KTsKCiAgcmVzLmpzb24oeyBqb2JJZCwgc3RhdHVzOiAncnVubmluZycgfSk7Cn0pOwoKYXBwLmRlbGV0ZSgnL2FwaS9qb2JzLzppZCcsIChyZXEsIHJlcykgPT4gewogIGNvbnN0IGYgPSBwYXRoLmpvaW4oU1lOQ19KT0JTX0RJUiwgYCR7cmVxLnBhcmFtcy5pZH0uanNvbmApOwogIGlmIChmcy5leGlzdHNTeW5jKGYpKSB7IGZzLnVubGlua1N5bmMoZik7IHJlcy5qc29uKHsgb2s6IHRydWUgfSk7IH0KICBlbHNlIHJlcy5zdGF0dXMoNDA0KS5qc29uKHsgZXJyb3I6ICfjgrjjg6fjg5bjgYzopovjgaTjgYvjgorjgb7jgZvjgpMnIH0pOwp9KTsKCmFwcC5wb3N0KCcvYXBpL2pvYnMvOmlkL3N0b3AnLCAocmVxLCByZXMpID0+IHsKICBjb25zdCBmID0gcGF0aC5qb2luKFNZTkNfSk9CU19ESVIsIGAke3JlcS5wYXJhbXMuaWR9Lmpzb25gKTsKICBpZiAoIWZzLmV4aXN0c1N5bmMoZikpIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7IGVycm9yOiAn44K444On44OW44GM6KaL44Gk44GL44KK44G+44Gb44KTJyB9KTsKICBjb25zdCBqb2IgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhmLCAndXRmLTgnKSk7CiAgam9iLnN0YXR1cyA9ICdzdG9wcGVkJzsKICBqb2IuY29tcGxldGVkQXQgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7CiAgZnMud3JpdGVGaWxlU3luYyhmLCBKU09OLnN0cmluZ2lmeShqb2IsIG51bGwsIDIpKTsKICB0cnkgeyBleGVjU3luYyhga2lsbCAkKHBncmVwIC1mICJyY2xvbmUuKiR7cmVxLnBhcmFtcy5pZH0iIHwgaGVhZCAtMSkgMj4vZGV2L251bGxgKTsgfSBjYXRjaCB7fQogIHJlcy5qc29uKHsgb2s6IHRydWUgfSk7Cn0pOwoKLy8gPT09IFNpemUgPT09CmFwcC5nZXQoJy9hcGkvc2l6ZS86cmVtb3RlLyonLCAocmVxLCByZXMpID0+IHsKICBjb25zdCB0YXJnZXQgPSByZXEucGFyYW1zWzBdID8gYCR7cmVxLnBhcmFtcy5yZW1vdGV9Oi8ke3JlcS5wYXJhbXNbMF19YCA6IGAke3JlcS5wYXJhbXMucmVtb3RlfTpgOwogIGNvbnN0IHJlc3VsdCA9IHJjbG9uZShbJ3NpemUnLCBgIiR7dGFyZ2V0fSJgLCAnLS1qc29uJ10pOwogIGlmIChyZXN1bHQub2spIHsgdHJ5IHsgcmV0dXJuIHJlcy5qc29uKEpTT04ucGFyc2UocmVzdWx0LmRhdGEpKTsgfSBjYXRjaCB7fSB9CiAgcmVzLmpzb24oeyBlcnJvcjogcmVzdWx0LmVycm9yIHx8ICfjgrXjgqTjgrrlj5blvpfjgavlpLHmlZcnIH0pOwp9KTsKCmFwcC5nZXQoJyonLCAocmVxLCByZXMpID0+IHsKICByZXMuc2VuZEZpbGUocGF0aC5qb2luKF9fZGlybmFtZSwgJ3B1YmxpYycsICdpbmRleC5odG1sJykpOwp9KTsKCmNvbnN0IHNlcnZlciA9IGFwcC5saXN0ZW4oUE9SVCwgJzAuMC4wLjAnLCAoKSA9PiB7CiAgY29uc29sZS5sb2coYFxuICDwn5qAIEVhc3lSY2xvbmUgR1VJIOi1t+WLlWApOwogIGNvbnNvbGUubG9nKGAgIPCfk6EgaHR0cDovL2xvY2FsaG9zdDoke1BPUlR9XG5gKTsKfSk7Cg=='
B64_HTML='PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImphIj4KPGhlYWQ+CiAgPG1ldGEgY2hhcnNldD0iVVRGLTgiPgogIDxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MS4wIj4KICA8dGl0bGU+RWFzeVJjbG9uZTwvdGl0bGU+CiAgPGxpbmsgcmVsPSJpY29uIiBocmVmPSJkYXRhOmltYWdlL3N2Zyt4bWwsPHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAzMiAzMic+PHJlY3Qgcng9JzgnIHdpZHRoPSczMicgaGVpZ2h0PSczMicgZmlsbD0nJTIzNjM2NmYxJy8+PHRleHQgeD0nMTYnIHk9JzIyJyBmb250LXNpemU9JzE4JyB0ZXh0LWFuY2hvcj0nbWlkZGxlJyBmaWxsPSd3aGl0ZScgZm9udC1mYW1pbHk9J3N5c3RlbS11aScgZm9udC13ZWlnaHQ9J2JvbGQnPlI8L3RleHQ+PC9zdmc+Ij4KICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Ii9jc3Mvc3R5bGUuY3NzIj4KPC9oZWFkPgo8Ym9keT4KICA8aGVhZGVyIGNsYXNzPSJhcHAtaGVhZGVyIj4KICAgIDxkaXYgY2xhc3M9ImhlYWRlci1sZWZ0Ij4KICAgICAgPGRpdiBjbGFzcz0ibG9nby1pY29uIj4KICAgICAgICA8c3ZnIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTQgMTQuODk5QTcgNyAwIDEgMSAxNS43MSA4aDEuNzlhNC41IDQuNSAwIDAgMSAyLjUgOC4yNDIiLz48cGF0aCBkPSJNMTIgMTJ2OSIvPjxwYXRoIGQ9Im04IDE3IDQgNCA0LTQiLz48L3N2Zz4KICAgICAgPC9kaXY+CiAgICAgIDxoMT5FYXN5UmNsb25lPC9oMT4KICAgIDwvZGl2PgogICAgPGRpdiBjbGFzcz0iaGVhZGVyLXJpZ2h0Ij4KICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuLWljb24taGVhZGVyIGFjY2VudCIgb25jbGljaz0ib3BlbkFkZE1vZGFsKCdkcml2ZScpIj4KICAgICAgICA8c3ZnIHdpZHRoPSIxNSIgaGVpZ2h0PSIxNSIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xMiA1djE0Ii8+PHBhdGggZD0iTTUgMTJoMTQiLz48L3N2Zz4KICAgICAgICA8c3BhbiBjbGFzcz0iYnRuLWxhYmVsIj5Hb29nbGXjg4njg6njgqTjg5Y8L3NwYW4+CiAgICAgIDwvYnV0dG9uPgogICAgICA8YnV0dG9uIGNsYXNzPSJidG4taWNvbi1oZWFkZXIgYWNjZW50IiBvbmNsaWNrPSJvcGVuQWRkTW9kYWwoJ29uZWRyaXZlJykiPgogICAgICAgIDxzdmcgd2lkdGg9IjE1IiBoZWlnaHQ9IjE1IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTEyIDV2MTQiLz48cGF0aCBkPSJNNSAxMmgxNCIvPjwvc3ZnPgogICAgICAgIDxzcGFuIGNsYXNzPSJidG4tbGFiZWwiPk9uZURyaXZlPC9zcGFuPgogICAgICA8L2J1dHRvbj4KICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuLWljb24taGVhZGVyIiBvbmNsaWNrPSJleHBvcnRTZXR0aW5ncygpIj4KICAgICAgICA8c3ZnIHdpZHRoPSIxNSIgaGVpZ2h0PSIxNSIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMSAxNXY0YTIgMiAwIDAgMS0yIDJINWEyIDIgMCAwIDEtMi0ydi00Ii8+PHBvbHlsaW5lIHBvaW50cz0iNyAxMCAxMiAxNSAxNyAxMCIvPjxsaW5lIHgxPSIxMiIgeTE9IjE1IiB4Mj0iMTIiIHkyPSIzIi8+PC9zdmc+CiAgICAgICAgPHNwYW4gY2xhc3M9ImJ0bi1sYWJlbCI+44Ko44Kv44K544Od44O844OIPC9zcGFuPgogICAgICA8L2J1dHRvbj4KICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuLWljb24taGVhZGVyIiBvbmNsaWNrPSJpbXBvcnRTZXR0aW5ncygpIj4KICAgICAgICA8c3ZnIHdpZHRoPSIxNSIgaGVpZ2h0PSIxNSIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMSAxNXY0YTIgMiAwIDAgMS0yIDJINWEyIDIgMCAwIDEtMi0ydi00Ii8+PHBvbHlsaW5lIHBvaW50cz0iMTcgOCAxMiAzIDcgOCIvPjxsaW5lIHgxPSIxMiIgeTE9IjMiIHgyPSIxMiIgeTI9IjE1Ii8+PC9zdmc+CiAgICAgICAgPHNwYW4gY2xhc3M9ImJ0bi1sYWJlbCI+44Kk44Oz44Od44O844OIPC9zcGFuPgogICAgICA8L2J1dHRvbj4KICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuLWljb24taGVhZGVyIG5hdi1idG4iIGRhdGEtcGFnZT0iam9icyIgb25jbGljaz0ic2hvd1BhZ2UoJ2pvYnMnKSI+CiAgICAgICAgPHN2ZyB3aWR0aD0iMTUiIGhlaWdodD0iMTUiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMTQgMkg2YTIgMiAwIDAgMC0yIDJ2MTZhMiAyIDAgMCAwIDIgMmgxMmEyIDIgMCAwIDAgMi0yVjhaIi8+PHBhdGggZD0iTTE0IDJ2Nmg2Ii8+PHBhdGggZD0iTTE2IDEzSDgiLz48cGF0aCBkPSJNMTYgMTdIOCIvPjxwYXRoIGQ9Ik0xMCA5SDgiLz48L3N2Zz4KICAgICAgICA8c3BhbiBjbGFzcz0iYnRuLWxhYmVsIj7lsaXmrbQ8L3NwYW4+CiAgICAgIDwvYnV0dG9uPgogICAgPC9kaXY+CiAgPC9oZWFkZXI+CgogIDxtYWluIGNsYXNzPSJjb250ZW50Ij4KICAgIDxkaXYgaWQ9InBhZ2UtbWFpbiIgY2xhc3M9InBhZ2UgYWN0aXZlIj4KICAgICAgPGRpdiBpZD0icmVtb3RlLWNhcmRzIj48L2Rpdj4KCiAgICAgIDxkaXYgY2xhc3M9InNjaGVkdWxlLXNlY3Rpb24iIGlkPSJzY2hlZHVsZS1zZWN0aW9uIiBzdHlsZT0iZGlzcGxheTpub25lIj4KICAgICAgICA8ZGl2IGNsYXNzPSJjYXJkIj4KICAgICAgICAgIDxoMz4KICAgICAgICAgICAgPHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PGNpcmNsZSBjeD0iMTIiIGN5PSIxMiIgcj0iMTAiLz48cG9seWxpbmUgcG9pbnRzPSIxMiA2IDEyIDEyIDE2IDE0Ii8+PC9zdmc+CiAgICAgICAgICAgIOOCueOCseOCuOODpeODvOODq+ioreWumgogICAgICAgICAgPC9oMz4KICAgICAgICAgIDxkaXYgY2xhc3M9InNjaGVkdWxlLXRpbWUtcm93Ij4KICAgICAgICAgICAgPHNlbGVjdCBpZD0ic2NoZWR1bGUtdGltZS1zZWxlY3QiPgogICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IiI+5pmCPC9vcHRpb24+CiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMCI+MDwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjEiPjE8L29wdGlvbj48b3B0aW9uIHZhbHVlPSIyIj4yPC9vcHRpb24+CiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMyI+Mzwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjQiPjQ8L29wdGlvbj48b3B0aW9uIHZhbHVlPSI1Ij41PC9vcHRpb24+CiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iNiI+Njwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjciPjc8L29wdGlvbj48b3B0aW9uIHZhbHVlPSI4Ij44PC9vcHRpb24+CiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iOSI+OTwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjEwIj4xMDwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjExIj4xMTwvb3B0aW9uPgogICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjEyIj4xMjwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjEzIj4xMzwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjE0Ij4xNDwvb3B0aW9uPgogICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjE1Ij4xNTwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjE2Ij4xNjwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjE3Ij4xNzwvb3B0aW9uPgogICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjE4Ij4xODwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjE5Ij4xOTwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjIwIj4yMDwvb3B0aW9uPgogICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjIxIj4yMTwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjIyIj4yMjwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjIzIj4yMzwvb3B0aW9uPgogICAgICAgICAgICA8L3NlbGVjdD4KICAgICAgICAgICAgPHNlbGVjdCBpZD0ic2NoZWR1bGUtbWluLXNlbGVjdCI+CiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMDAiPjowMDwvb3B0aW9uPjxvcHRpb24gdmFsdWU9IjE1Ij46MTU8L29wdGlvbj48b3B0aW9uIHZhbHVlPSIzMCI+OjMwPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT0iNDUiPjo0NTwvb3B0aW9uPgogICAgICAgICAgICA8L3NlbGVjdD4KICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1vdXRsaW5lIGJ0bi1zbSIgb25jbGljaz0iYWRkU3luY1NjaGVkdWxlKCkiPui/veWKoDwvYnV0dG9uPgogICAgICAgICAgPC9kaXY+CiAgICAgICAgICA8ZGl2IGlkPSJzeW5jLXNjaGVkdWxlLWxpc3QiPjwvZGl2PgogICAgICAgICAgPGRpdiBjbGFzcz0iYnRuLXJvdyI+CiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tcGFzdGVsIGJ0bi1zbSIgb25jbGljaz0ic2F2ZVNjaGVkdWxlKCkiPuOCueOCseOCuOODpeODvOODq+S/neWtmDwvYnV0dG9uPgogICAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLW91dGxpbmUgYnRuLXNtIiBvbmNsaWNrPSJzaG93Q3JvbkluZm8oKSI+Y3JvbuioreWumueiuuiqjTwvYnV0dG9uPgogICAgICAgICAgPC9kaXY+CiAgICAgICAgICA8ZGl2IGlkPSJjcm9uLWluZm8tYXJlYSIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+CiAgICAgICAgICAgIDxkaXYgaWQ9ImNyb24taW5mby1jb250ZW50IiBjbGFzcz0iY3Jvbi1pbmZvLWJveCI+PC9kaXY+CiAgICAgICAgICA8L2Rpdj4KICAgICAgICA8L2Rpdj4KICAgICAgPC9kaXY+CiAgICA8L2Rpdj4KCiAgICA8ZGl2IGlkPSJwYWdlLWpvYnMiIGNsYXNzPSJwYWdlIj4KICAgICAgPGRpdiBjbGFzcz0icGFnZS1oZWFkZXIiPgogICAgICAgIDxoMj7jgrjjg6fjg5blsaXmrbQ8L2gyPgogICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tb3V0bGluZSBidG4tc20iIG9uY2xpY2s9InNob3dQYWdlKCdtYWluJykiPgogICAgICAgICAgPHN2ZyB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJtMTIgMTktNy03IDctNyIvPjxwYXRoIGQ9Ik0xOSAxMkg1Ii8+PC9zdmc+CiAgICAgICAgICDmiLvjgosKICAgICAgICA8L2J1dHRvbj4KICAgICAgPC9kaXY+CiAgICAgIDxkaXYgaWQ9ImpvYi1saXN0Ij48L2Rpdj4KICAgIDwvZGl2PgogIDwvbWFpbj4KCiAgPCEtLSBBZGQgUmVtb3RlIE1vZGFsIC0tPgogIDxkaXYgaWQ9Im1vZGFsLWFkZCIgY2xhc3M9Im1vZGFsLW92ZXJsYXkiIG9uY2xpY2s9ImNsb3NlTW9kYWxCZyhldmVudCkiPgogICAgPGRpdiBjbGFzcz0ibW9kYWwiIG9uY2xpY2s9ImV2ZW50LnN0b3BQcm9wYWdhdGlvbigpIj4KICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtaGVhZGVyIj4KICAgICAgICA8aDMgaWQ9Im1vZGFsLXRpdGxlIj48L2gzPgogICAgICAgIDxidXR0b24gY2xhc3M9Im1vZGFsLWNsb3NlIiBvbmNsaWNrPSJjbG9zZU1vZGFsKCkiPgogICAgICAgICAgPHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTE4IDYgNiAxOCIvPjxwYXRoIGQ9Im02IDYgMTIgMTIiLz48L3N2Zz4KICAgICAgICA8L2J1dHRvbj4KICAgICAgPC9kaXY+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWJvZHkiIGlkPSJtb2RhbC1ib2R5Ij48L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2PgoKICA8IS0tIEF1dGggRmxvdyBNb2RhbCAtLT4KICA8ZGl2IGlkPSJtb2RhbC1hdXRoIiBjbGFzcz0ibW9kYWwtb3ZlcmxheSIgb25jbGljaz0iY2xvc2VNb2RhbEJnKGV2ZW50KSI+CiAgICA8ZGl2IGNsYXNzPSJtb2RhbCBtb2RhbC1hdXRoIiBvbmNsaWNrPSJldmVudC5zdG9wUHJvcGFnYXRpb24oKSI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgPGgzPgogICAgICAgICAgPHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMTUgM2g0YTIgMiAwIDAgMSAyIDJ2MTRhMiAyIDAgMCAxLTIgMmgtNCIvPjxwb2x5bGluZSBwb2ludHM9IjEwIDE3IDE1IDEyIDEwIDciLz48bGluZSB4MT0iMTUiIHkxPSIxMiIgeDI9IjMiIHkyPSIxMiIvPjwvc3ZnPgogICAgICAgICAg44Ki44Kr44Km44Oz44OI6KqN6Ki8CiAgICAgICAgPC9oMz4KICAgICAgICA8YnV0dG9uIGNsYXNzPSJtb2RhbC1jbG9zZSIgb25jbGljaz0iY2xvc2VNb2RhbCgpIj4KICAgICAgICAgIDxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xOCA2IDYgMTgiLz48cGF0aCBkPSJtNiA2IDEyIDEyIi8+PC9zdmc+CiAgICAgICAgPC9idXR0b24+CiAgICAgIDwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICA8cCBpZD0iYXV0aC1zdGF0dXMiIHN0eWxlPSJtYXJnaW46MCAwIDEycHg7Zm9udC1zaXplOjAuOXJlbTtjb2xvcjp2YXIoLS10ZXh0Mik7Zm9udC13ZWlnaHQ6NTAwIj48L3A+CiAgICAgICAgPGRpdiBpZD0iYXV0aC11cmwtYXJlYSIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJzc2gtdHVubmVsLWJveCI+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9InNzaC10dW5uZWwtbGFiZWwiPgogICAgICAgICAgICAgIDxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxyZWN0IHdpZHRoPSIyMCIgaGVpZ2h0PSIxNiIgeD0iMiIgeT0iNCIgcng9IjIiLz48cGF0aCBkPSJtMjIgNy04Ljk3IDUuN2ExLjk0IDEuOTQgMCAwIDEtMi4wNiAwTDIgNyIvPjwvc3ZnPgogICAgICAgICAgICAgIDEuIFNTSOODiOODs+ODjeODq+OCkuaOpee2mjoKICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9InNzaC10dW5uZWwtY21kIj4KICAgICAgICAgICAgICA8Y29kZSBpZD0ic3NoLWNtZCI+PC9jb2RlPgogICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tb3V0bGluZSBidG4tc20iIG9uY2xpY2s9ImNvcHlTc2hDbWQoKSI+CiAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxyZWN0IHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgeD0iOCIgeT0iOCIgcng9IjIiIHJ5PSIyIi8+PHBhdGggZD0iTTQgMTZjLTEuMSAwLTItLjktMi0yVjRjMC0xLjEuOS0yIDItMmgxMGMxLjEgMCAyIC45IDIgMiIvPjwvc3ZnPgogICAgICAgICAgICAgIDwvYnV0dG9uPgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgIDwvZGl2PgogICAgICAgICAgPGRpdiBjbGFzcz0iYXV0aC11cmwtYm94IiBzdHlsZT0ibWFyZ2luLXRvcDo4cHgiPgogICAgICAgICAgICA8bGFiZWw+Mi4g44OW44Op44Km44K244Gn44Ot44Kw44Kk44OzOjwvbGFiZWw+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9ImF1dGgtdXJsLWlucHV0LXJvdyI+CiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InRleHQiIGlkPSJhdXRoLXVybC1pbnB1dCIgcmVhZG9ubHkgY2xhc3M9ImF1dGgtdXJsLWlucHV0Ij4KICAgICAgICAgICAgICA8YSBpZD0iYXV0aC11cmwtbGluayIgaHJlZj0iIyIgdGFyZ2V0PSJfYmxhbmsiIGNsYXNzPSJidG4gYnRuLXByaW1hcnkgYnRuLXNtIj7plovjgY88L2E+CiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1vdXRsaW5lIGJ0bi1zbSIgb25jbGljaz0iY29weUF1dGhVcmwoKSI+CiAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxyZWN0IHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgeD0iOCIgeT0iOCIgcng9IjIiIHJ5PSIyIi8+PHBhdGggZD0iTTQgMTZjLTEuMSAwLTItLjktMi0yVjRjMC0xLjEuOS0yIDItMmgxMGMxLjEgMCAyIC45IDIgMiIvPjwvc3ZnPgogICAgICAgICAgICAgIDwvYnV0dG9uPgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvZGl2PgogICAgICAgIDxkaXYgaWQ9ImF1dGgtZG9uZS1hcmVhIiBzdHlsZT0iZGlzcGxheTpub25lO3RleHQtYWxpZ246Y2VudGVyO3BhZGRpbmc6MjRweCAwIj4KICAgICAgICAgIDxkaXYgc3R5bGU9IndpZHRoOjQ4cHg7aGVpZ2h0OjQ4cHg7Ym9yZGVyLXJhZGl1czoxMnB4O2JhY2tncm91bmQ6dmFyKC0tc3VjY2Vzcy1iZyk7ZGlzcGxheTpmbGV4O2FsaWduLWl0ZW1zOmNlbnRlcjtqdXN0aWZ5LWNvbnRlbnQ6Y2VudGVyO21hcmdpbjowIGF1dG8gMTJweCI+CiAgICAgICAgICAgIDxzdmcgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0idmFyKC0tc3VjY2VzcykiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMjAgNiA5IDE3bC01LTUiLz48L3N2Zz4KICAgICAgICAgIDwvZGl2PgogICAgICAgICAgPHAgc3R5bGU9ImNvbG9yOnZhcigtLXN1Y2Nlc3MpO2ZvbnQtd2VpZ2h0OjYwMDtmb250LXNpemU6MXJlbSI+6KqN6Ki85a6M5LqGPC9wPgogICAgICAgIDwvZGl2PgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2PgoKICA8IS0tIFN5bmMgUGFpciBBZGQgTW9kYWwgLS0+CiAgPGRpdiBpZD0ibW9kYWwtc3luYy1wYWlyIiBjbGFzcz0ibW9kYWwtb3ZlcmxheSIgb25jbGljaz0iY2xvc2VNb2RhbEJnKGV2ZW50KSI+CiAgICA8ZGl2IGNsYXNzPSJtb2RhbCIgc3R5bGU9Im1heC13aWR0aDo1NjBweCIgb25jbGljaz0iZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCkiPgogICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1oZWFkZXIiPgogICAgICAgIDxoMz4KICAgICAgICAgIDxzdmcgd2lkdGg9IjE4IiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTEyIDV2MTQiLz48cGF0aCBkPSJNNSAxMmgxNCIvPjwvc3ZnPgogICAgICAgICAg5ZCM5pyf44Oa44Ki44KS6L+95YqgCiAgICAgICAgPC9oMz4KICAgICAgICA8YnV0dG9uIGNsYXNzPSJtb2RhbC1jbG9zZSIgb25jbGljaz0iY2xvc2VNb2RhbCgpIj4KICAgICAgICAgIDxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xOCA2IDYgMTgiLz48cGF0aCBkPSJtNiA2IDEyIDEyIi8+PC9zdmc+CiAgICAgICAgPC9idXR0b24+CiAgICAgIDwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICA8ZGl2IGNsYXNzPSJmb3JtLWdyb3VwIj4KICAgICAgICAgIDxsYWJlbD7jgrPjg5Tjg7zlhYPvvIjjgrXjg7zjg5Djg7zlgbTvvIk8L2xhYmVsPgogICAgICAgICAgPGlucHV0IHR5cGU9InRleHQiIGlkPSJwYWlyLXNvdXJjZSIgcGxhY2Vob2xkZXI9Ii9vcHQvbHhkLWRhdGEvZmlsZSI+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0iZm9ybS1ncm91cCI+CiAgICAgICAgICA8bGFiZWw+44Kz44OU44O85YWI77yI44Kv44Op44Km44OJ5YG077yJPC9sYWJlbD4KICAgICAgICAgIDxkaXYgc3R5bGU9ImRpc3BsYXk6ZmxleDtnYXA6MCI+CiAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJzeW5jLXBhaXItcHJlZml4IiBpZD0icGFpci1wcmVmaXgiPmdkcml2ZTo8L3NwYW4+CiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBpZD0icGFpci1kZXN0IiBjbGFzcz0ic3luYy1wYWlyLWRlc3QtaW5wdXQiIHBsYWNlaG9sZGVyPSIvYmFja3VwIj4KICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvZGl2PgogICAgICAgIDxsYWJlbCBjbGFzcz0iY2hlY2tib3giIHN0eWxlPSJtYXJnaW46MTBweCAwIj4KICAgICAgICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9InBhaXItZGVsZXRlIj4KICAgICAgICAgIDxzcGFuPuOCs+ODlOODvOWFg+OBq+OBquOBhOODleOCoeOCpOODq+OCkuOCs+ODlOODvOWFiOOBp+WJiumZpDwvc3Bhbj4KICAgICAgICA8L2xhYmVsPgogICAgICA8L2Rpdj4KICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLW91dGxpbmUiIG9uY2xpY2s9ImNsb3NlTW9kYWwoKSI+44Kt44Oj44Oz44K744OrPC9idXR0b24+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1wYXN0ZWwiIG9uY2xpY2s9InNhdmVTeW5jUGFpcigpIj7ov73liqA8L2J1dHRvbj4KICAgICAgPC9kaXY+CiAgICA8L2Rpdj4KICA8L2Rpdj4KCiAgPGRpdiBpZD0idG9hc3QiIGNsYXNzPSJ0b2FzdCI+PC9kaXY+CiAgPHNjcmlwdCBzcmM9Ii9qcy9hcHAuanM/dj03Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+Cg=='
B64_JS='bGV0IGFsbFJlbW90ZXMgPSBbXTsKbGV0IHN5bmNQYWlycyA9IFtdOwpsZXQgc3luY1NjaGVkdWxlID0gW107CmxldCBqb2JIaXN0b3J5ID0gW107CmxldCBhdXRoVHlwZSA9ICcnOwpsZXQgYXV0aFJlbW90ZU5hbWUgPSAnJzsKbGV0IGF1dGhTZXNzaW9uSWQgPSAnJzsKbGV0IGF1dGhQb2xsVGltZXIgPSBudWxsOwpsZXQgYWRkaW5nUGFpckZvciA9ICcnOwpsZXQgZGlzbWlzc2VkRXJyb3JzID0gbmV3IFNldChKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdlYXN5cmNsb25lX2Rpc21pc3NlZCcpIHx8ICdbXScpKTsKCmNvbnN0IElDT05TID0gewogIHBsdXM6ICc8c3ZnIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xMiA1djE0Ii8+PHBhdGggZD0iTTUgMTJoMTQiLz48L3N2Zz4nLAogIGtleTogJzxzdmcgd2lkdGg9IjE0IiBoZWlnaHQ9IjE0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0ibTIxIDItMiAybS03LjYxIDcuNjFhNS41IDUuNSAwIDEgMS03Ljc3OCA3Ljc3OCA1LjUgNS41IDAgMCAxIDcuNzc3LTcuNzc3em0wIDBMMTUuNSA3LjVtMCAwIDMgM0wyMiA3bC0zLTNtLTMuNSAzLjVMMTkgNCIvPjwvc3ZnPicsCiAgbGluazogJzxzdmcgd2lkdGg9IjE0IiBoZWlnaHQ9IjE0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTEwIDEzYTUgNSAwIDAgMCA3LjU0LjU0bDMtM2E1IDUgMCAwIDAtNy4wNy03LjA3bC0xLjcyIDEuNzEiLz48cGF0aCBkPSJNMTQgMTFhNSA1IDAgMCAwLTcuNTQtLjU0bC0zIDNhNSA1IDAgMCAwIDcuMDcgNy4wN2wxLjcxLTEuNzEiLz48L3N2Zz4nLAogIHRyYXNoOiAnPHN2ZyB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMyA2aDE4Ii8+PHBhdGggZD0iTTE5IDZ2MTRjMCAxLTEgMi0yIDJIN2MtMSAwLTItMS0yLTJWNiIvPjxwYXRoIGQ9Ik04IDZWNGMwLTEgMS0yIDItMmg0YzEgMCAyIDEgMiAydjIiLz48L3N2Zz4nLAogIHNldHRpbmdzOiAnPHN2ZyB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMTIuMjIgMmgtLjQ0YTIgMiAwIDAgMC0yIDJ2LjE4YTIgMiAwIDAgMS0xIDEuNzNsLS40My4yNWEyIDIgMCAwIDEtMiAwbC0uMTUtLjA4YTIgMiAwIDAgMC0yLjczLjczbC0uMjIuMzhhMiAyIDAgMCAwIC43MyAyLjczbC4xNS4xYTIgMiAwIDAgMSAxIDEuNzJ2LjUxYTIgMiAwIDAgMS0xIDEuNzRsLS4xNS4wOWEyIDIgMCAwIDAtLjczIDIuNzNsLjIyLjM4YTIgMiAwIDAgMCAyLjczLjczbC4xNS0uMDhhMiAyIDAgMCAxIDIgMGwuNDMuMjVhMiAyIDAgMCAxIDEgMS43M1YyMGEyIDIgMCAwIDAgMiAyaC40NGEyIDIgMCAwIDAgMi0ydi0uMThhMiAyIDAgMCAxIDEtMS43M2wuNDMtLjI1YTIgMiAwIDAgMSAyIDBsLjE1LjA4YTIgMiAwIDAgMCAyLjczLS43M2wuMjItLjM5YTIgMiAwIDAgMC0uNzMtMi43M2wtLjE1LS4wOGEyIDIgMCAwIDEtMS0xLjc0di0uNWEyIDIgMCAwIDEgMS0xLjc0bC4xNS0uMDlhMiAyIDAgMCAwIC43My0yLjczbC0uMjItLjM4YTIgMiAwIDAgMC0yLjczLS43M2wtLjE1LjA4YTIgMiAwIDAgMS0yIDBsLS40My0uMjVhMiAyIDAgMCAxLTEtMS43M1Y0YTIgMiAwIDAgMC0yLTJ6Ii8+PGNpcmNsZSBjeD0iMTIiIGN5PSIxMiIgcj0iMyIvPjwvc3ZnPicsCiAgc3luYzogJzxzdmcgd2lkdGg9IjE0IiBoZWlnaHQ9IjE0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTIxIDEyYTkgOSAwIDAgMC05LTkgOS43NSA5Ljc1IDAgMCAwLTYuNzQgMi43NEwzIDgiLz48cGF0aCBkPSJNMyAzdjVoNSIvPjxwYXRoIGQ9Ik0zIDEyYTkgOSAwIDAgMCA5IDkgOS43NSA5Ljc1IDAgMCAwIDYuNzQtMi43NEwyMSAxNiIvPjxwYXRoIGQ9Ik0xNiAxNmg1djUiLz48L3N2Zz4nLAogIGVkaXQ6ICc8c3ZnIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xNyAzYTIuODUgMi44MyAwIDEgMSA0IDRMNy41IDIwLjUgMiAyMmwxLjUtNS41WiIvPjwvc3ZnPicsCiAgY2xvdWQ6ICc8c3ZnIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTE3LjUgMTlIOWE3IDcgMCAxIDEgNi43MS05aDEuNzlhNC41IDQuNSAwIDEgMSAwIDlaIi8+PC9zdmc+JywKICBjaGVjazogJzxzdmcgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTIwIDYgOSAxN2wtNS01Ii8+PC9zdmc+JywKICB4OiAnPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMTggNiA2IDE4Ii8+PHBhdGggZD0ibTYgNiAxMiAxMiIvPjwvc3ZnPicsCiAgY2xvY2s6ICc8c3ZnIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxjaXJjbGUgY3g9IjEyIiBjeT0iMTIiIHI9IjEwIi8+PHBvbHlsaW5lIHBvaW50cz0iMTIgNiAxMiAxMiAxNiAxNCIvPjwvc3ZnPicsCiAgY29weTogJzxzdmcgd2lkdGg9IjE0IiBoZWlnaHQ9IjE0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHJlY3Qgd2lkdGg9IjE0IiBoZWlnaHQ9IjE0IiB4PSI4IiB5PSI4IiByeD0iMiIgcnk9IjIiLz48cGF0aCBkPSJNNCAxNmMtMS4xIDAtMi0uOS0yLTJWNGMwLTEuMS45LTIgMi0yaDEwYzEuMSAwIDIgLjkgMiAyIi8+PC9zdmc+JywKICBhcnJvd1JpZ2h0OiAnPHN2ZyB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNNSAxMmgxNCIvPjxwYXRoIGQ9Im0xMiA1IDcgNy03IDciLz48L3N2Zz4nLAogIGFycm93TGVmdDogJzxzdmcgd2lkdGg9IjE0IiBoZWlnaHQ9IjE0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0ibTEyIDE5LTctNyA3LTciLz48cGF0aCBkPSJNMTkgMTJINSIvPjwvc3ZnPicsCiAgdGVybWluYWw6ICc8c3ZnIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwb2x5bGluZSBwb2ludHM9IjQgMTcgMTAgMTEgNCA1Ii8+PGxpbmUgeDE9IjEyIiB5MT0iMTkiIHgyPSIyMCIgeTI9IjE5Ii8+PC9zdmc+JywKICBoaXN0b3J5OiAnPHN2ZyB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMyAxMmE5IDkgMCAxIDAgOS05IDkuNzUgOS43NSAwIDAgMC02Ljc0IDIuNzRMMyA4Ii8+PHBhdGggZD0iTTMgM3Y1aDUiLz48cGF0aCBkPSJNMTIgN3Y1bDQgMiIvPjwvc3ZnPicsCiAgZm9sZGVyT3BlbjogJzxzdmcgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJtNiAxNCAxLjUtMi45QTIgMiAwIDAgMSA5LjI0IDEwSDIwYTIgMiAwIDAgMSAxLjk0IDIuNWwtMS41NCA2YTIgMiAwIDAgMS0xLjk1IDEuNUg0YTIgMiAwIDAgMS0yLTJWNWEyIDIgMCAwIDEgMi0yaDMuOWEyIDIgMCAwIDEgMS42OS45bC44MSAxLjJhMiAyIDAgMCAwIDEuNjcuOUgxOGEyIDIgMCAwIDEgMiAydjIiLz48L3N2Zz4nLAogIGZpbGVUZXh0OiAnPHN2ZyB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMTUgMkg2YTIgMiAwIDAgMC0yIDJ2MTZhMiAyIDAgMCAwIDIgMmgxMmEyIDIgMCAwIDAgMi0yVjdaIi8+PHBhdGggZD0iTTE0IDJ2NGEyIDIgMCAwIDAgMiAyaDQiLz48cGF0aCBkPSJNMTAgOUg4Ii8+PHBhdGggZD0iTTE2IDEzSDgiLz48cGF0aCBkPSJNMTYgMTdIOCIvPjwvc3ZnPicsCiAgc3RvcDogJzxzdmcgd2lkdGg9IjE0IiBoZWlnaHQ9IjE0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHJlY3Qgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIiB4PSIyIiB5PSIyIiByeD0iNCIvPjwvc3ZnPicsCn07CgpmdW5jdGlvbiBpY29uKG5hbWUsIHNpemUpIHsKICBjb25zdCBzdmcgPSBJQ09OU1tuYW1lXSB8fCAnJzsKICBpZiAoc2l6ZSAmJiBzdmcpIHJldHVybiBzdmcucmVwbGFjZSgvd2lkdGg9IlxkKyIvLCBgd2lkdGg9IiR7c2l6ZX0iYCkucmVwbGFjZSgvaGVpZ2h0PSJcZCsiLywgYGhlaWdodD0iJHtzaXplfSJgKTsKICByZXR1cm4gc3ZnOwp9Cgphc3luYyBmdW5jdGlvbiBhcGkodXJsLCBvcHRzID0ge30pIHsKICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCh1cmwsIHsKICAgIG1ldGhvZDogb3B0cy5tZXRob2QgfHwgJ0dFVCcsCiAgICBoZWFkZXJzOiBvcHRzLmJvZHkgPyB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSA6IHVuZGVmaW5lZCwKICAgIGJvZHk6IG9wdHMuYm9keSA/IEpTT04uc3RyaW5naWZ5KG9wdHMuYm9keSkgOiB1bmRlZmluZWQKICB9KTsKICByZXR1cm4gcmVzLmpzb24oKTsKfQoKYXN5bmMgZnVuY3Rpb24gbG9hZEFsbCgpIHsKICBjb25zdCBkYXRhID0gYXdhaXQgYXBpKCcvYXBpL3JlbW90ZXMnKTsKICBhbGxSZW1vdGVzID0gZGF0YS5yZW1vdGVzIHx8IFtdOwogIGNvbnN0IHNldHRpbmdzID0gYXdhaXQgYXBpKCcvYXBpL3N5bmMtc2V0dGluZ3MnKTsKICBzeW5jUGFpcnMgPSBzZXR0aW5ncy5zZXR0aW5ncz8ucGFpcnMgfHwgW107CiAgc3luY1NjaGVkdWxlID0gc2V0dGluZ3Muc2V0dGluZ3M/LnNjaGVkdWxlIHx8IFtdOwogIGNvbnN0IGpvYnMgPSBhd2FpdCBhcGkoJy9hcGkvam9icycpOwogIGpvYkhpc3RvcnkgPSBqb2JzLmpvYnMgfHwgW107CiAgcmVuZGVyQWxsKCk7Cn0KCmZ1bmN0aW9uIHNob3dUb2FzdChtc2csIHR5cGUgPSAnaW5mbycpIHsKICBjb25zdCB0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RvYXN0Jyk7CiAgY29uc3QgaWNvbkh0bWwgPSB0eXBlID09PSAnc3VjY2VzcycgPyBpY29uKCdjaGVjaycpIDogdHlwZSA9PT0gJ2Vycm9yJyA/IGljb24oJ3gnKSA6IGljb24oJ2Nsb2NrJyk7CiAgdC5pbm5lckhUTUwgPSBpY29uSHRtbCArIG1zZzsKICB0LmNsYXNzTmFtZSA9IGB0b2FzdCAke3R5cGV9IHNob3dgOwogIGNsZWFyVGltZW91dCh0Ll90aW1lcik7CiAgdC5fdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHQuY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpLCA0MDAwKTsKfQoKZnVuY3Rpb24gc2hvd1BhZ2UobmFtZSkgewogIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5wYWdlJykuZm9yRWFjaChwID0+IHAuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJykpOwogIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYWdlLScgKyBuYW1lKS5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTsKICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcubmF2LWJ0bicpLmZvckVhY2goYiA9PiBiLmNsYXNzTGlzdC50b2dnbGUoJ2FjdGl2ZScsIGIuZGF0YXNldC5wYWdlID09PSBuYW1lKSk7CiAgaWYgKG5hbWUgPT09ICdtYWluJykgbG9hZEFsbCgpOwogIGlmIChuYW1lID09PSAnam9icycpIGxvYWRKb2JzKCk7Cn0KCmZ1bmN0aW9uIGNsb3NlTW9kYWwoKSB7CiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLm1vZGFsLW92ZXJsYXknKS5mb3JFYWNoKG0gPT4gbS5jbGFzc0xpc3QucmVtb3ZlKCdvcGVuJykpOwp9CmZ1bmN0aW9uIGNsb3NlTW9kYWxCZyhlKSB7IGlmIChlLnRhcmdldCA9PT0gZS5jdXJyZW50VGFyZ2V0KSBjbG9zZU1vZGFsKCk7IH0KCmZ1bmN0aW9uIGVzYyhzKSB7IHJldHVybiBTdHJpbmcocykucmVwbGFjZSgvJy9nLCAiXFwnIikucmVwbGFjZSgvIi9nLCAnJnF1b3Q7Jyk7IH0KCmZ1bmN0aW9uIGRpc21pc3NFcnJvcihzb3VyY2UsIGRlc3QpIHsKICBkaXNtaXNzZWRFcnJvcnMuYWRkKGAke3NvdXJjZX3ihpIke2Rlc3R9YCk7CiAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2Vhc3lyY2xvbmVfZGlzbWlzc2VkJywgSlNPTi5zdHJpbmdpZnkoWy4uLmRpc21pc3NlZEVycm9yc10pKTsKICBzaG93UGFnZSgnam9icycpOwp9CgpmdW5jdGlvbiByZW5kZXJBbGwoKSB7CiAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlbW90ZS1jYXJkcycpOwogIGNvbnN0IHNjaGVkU2VjdGlvbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzY2hlZHVsZS1zZWN0aW9uJyk7CgogIGlmICghYWxsUmVtb3Rlcy5sZW5ndGgpIHsKICAgIGNvbnRhaW5lci5pbm5lckhUTUwgPSBgCiAgICAgIDxkaXYgY2xhc3M9ImVtcHR5LXN0YXRlIj4KICAgICAgICA8ZGl2IGNsYXNzPSJlbXB0eS1pY29uIj4ke2ljb24oJ2Nsb3VkJyl9PC9kaXY+CiAgICAgICAgPGgzPuOCouOCq+OCpuODs+ODiOOBjOacqueZu+mMsuOBp+OBmTwvaDM+CiAgICAgICAgPHA+5Y+z5LiK44Gu44Oc44K/44Oz44GL44KJ44Kv44Op44Km44OJ44Ki44Kr44Km44Oz44OI44KS6L+95Yqg44GX44Gm44GP44Gg44GV44GEPC9wPgogICAgICA8L2Rpdj5gOwogICAgc2NoZWRTZWN0aW9uLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICByZXR1cm47CiAgfQoKICBsZXQgaHRtbCA9ICcnOwogIGZvciAoY29uc3QgciBvZiBhbGxSZW1vdGVzKSB7CiAgICBjb25zdCBwYWlycyA9IHN5bmNQYWlycy5maWx0ZXIocCA9PiBwLnJlbW90ZU5hbWUgPT09IHIubmFtZSk7CiAgICBjb25zdCB0eXBlTGFiZWwgPSByLnR5cGUgPT09ICdkcml2ZScgPyAnR29vZ2xlIOODieODqeOCpOODlicgOiAnT25lRHJpdmUnOwogICAgY29uc3QgdHlwZUljb24gPSByLnR5cGUgPT09ICdkcml2ZScKICAgICAgPyAnPHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0id2hpdGUiPjxwYXRoIGQ9Ik03LjcxIDMuNSAxLjE1IDE1bDMuNDMgNmgxMy4xNGwzLjQzLTZMMTUuMjkgMy41SDcuNzF6Ii8+PC9zdmc+JwogICAgICA6ICc8c3ZnIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJ3aGl0ZSI+PHBhdGggZD0iTTEwLjUgMTguNWgtNmEzLjUgMy41IDAgMCAxLS43Mi02LjkzQTUgNSAwIDAgMSAxNC41NiA4SDE4YTMuNSAzLjUgMCAwIDEgLjUgNi45NCIvPjxwYXRoIGQ9Ik0xOCA4VjYuNWEzLjUgMy41IDAgMCAwLTcgMFY4Ii8+PC9zdmc+JzsKCiAgICBodG1sICs9IGAKICAgIDxkaXYgY2xhc3M9ImNhcmQgcmVtb3RlLWNhcmQiPgogICAgICA8ZGl2IGNsYXNzPSJyZW1vdGUtY2FyZC1oZWFkZXIiPgogICAgICAgIDxkaXYgY2xhc3M9InJlbW90ZS1jYXJkLWxlZnQiPgogICAgICAgICAgPGRpdiBjbGFzcz0icmVtb3RlLWljb24gJHtyLnR5cGV9Ij4ke3R5cGVJY29ufTwvZGl2PgogICAgICAgICAgPGRpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icmVtb3RlLWNhcmQtbmFtZSI+JHtlc2Moci5uYW1lKX08L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icmVtb3RlLWNhcmQtdHlwZSI+JHt0eXBlTGFiZWx9PC9kaXY+CiAgICAgICAgICA8L2Rpdj4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJyZW1vdGUtY2FyZC1hY3Rpb25zIj4KICAgICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tb3V0bGluZSBidG4tc20iIG9uY2xpY2s9InNldHVwU3NoKCkiPiR7aWNvbigndGVybWluYWwnKX0g5LiA5pmCU1NIPC9idXR0b24+CiAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLXBhc3RlbCBidG4tc20iIG9uY2xpY2s9InN0YXJ0QXV0aEZsb3coJyR7ZXNjKHIubmFtZSl9JywnJHtyLnR5cGV9JykiPiR7aWNvbigna2V5Jyl9IOiqjeiovDwvYnV0dG9uPgogICAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1vdXRsaW5lIGJ0bi1zbSIgb25jbGljaz0idGVzdFJlbW90ZSgnJHtlc2Moci5uYW1lKX0nKSI+JHtpY29uKCdsaW5rJyl9IOODhuOCueODiDwvYnV0dG9uPgogICAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1vdXRsaW5lIGJ0bi1zbSIgb25jbGljaz0idGVhcmRvd25Tc2goKSI+JHtpY29uKCd0cmFzaCcpfSBTU0jliYrpmaQ8L2J1dHRvbj4KICAgICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tcGFzdGVsLWdyZWVuIGJ0bi1zbSIgb25jbGljaz0ib3BlbkFkZFBhaXIoJyR7ZXNjKHIubmFtZSl9JywnJHtyLnR5cGV9JykiPiR7aWNvbigncGx1cycpfSDlkIzmnJ/jg5rjgqLov73liqA8L2J1dHRvbj4KICAgICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tZGFuZ2VyIGJ0bi1zbSIgb25jbGljaz0iZGVsZXRlUmVtb3RlKCcke2VzYyhyLm5hbWUpfScpIj4ke2ljb24oJ3RyYXNoJyl9IOWJiumZpDwvYnV0dG9uPgogICAgICAgIDwvZGl2PgogICAgICA8L2Rpdj5gOwoKICAgIGlmIChwYWlycy5sZW5ndGgpIHsKICAgICAgaHRtbCArPSAnPGRpdiBjbGFzcz0ic3luYy1wYWlycy1hcmVhIj4nOwogICAgICBodG1sICs9ICc8ZGl2IGNsYXNzPSJzeW5jLXBhaXJzLWFyZWEtdGl0bGUiPuWQjOacn+ODmuOCojwvZGl2Pic7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFpcnMubGVuZ3RoOyBpKyspIHsKICAgICAgICBjb25zdCBwaSA9IHN5bmNQYWlycy5pbmRleE9mKHBhaXJzW2ldKTsKICAgICAgICBjb25zdCBwID0gcGFpcnNbaV07CiAgICAgICAgY29uc3QgcGFpckpvYnMgPSBqb2JIaXN0b3J5LmZpbHRlcihqID0+IGouc291cmNlID09PSBwLnNvdXJjZSAmJiBqLmRlc3QgPT09IHAuZGVzdCk7CiAgICAgICAgY29uc3QgZXJyb3JLZXkgPSBgJHtwLnNvdXJjZX3ihpIke3AuZGVzdH1gOwogICAgICAgIGNvbnN0IGhhc0Vycm9yID0gcGFpckpvYnMuc29tZShqID0+IGouc3RhdHVzID09PSAnZmFpbGVkJykgJiYgIWRpc21pc3NlZEVycm9ycy5oYXMoZXJyb3JLZXkpOwogICAgICAgIGNvbnN0IGVycm9yTGluayA9IGhhc0Vycm9yID8gYDxzcGFuIGNsYXNzPSJzeW5jLWVycm9yLWxpbmsiIG9uY2xpY2s9ImRpc21pc3NFcnJvcignJHtlc2MocC5zb3VyY2UpfScsJyR7ZXNjKHAuZGVzdCl9JykiPuWQjOacn+OCqOODqeODvOOBguOCijwvc3Bhbj5gIDogJyc7CiAgICAgICAgaHRtbCArPSBgCiAgICAgICAgPGRpdiBjbGFzcz0ic3luYy1wYWlyLXJvdyI+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJzeW5jLXBhaXItbGVmdCI+CiAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJzeW5jLXBhaXItcGF0aCI+JHtlc2MocC5zb3VyY2UpfTwvc3Bhbj4KICAgICAgICAgICAgPHNwYW4gY2xhc3M9InN5bmMtYXJyb3ciPiR7aWNvbignYXJyb3dSaWdodCcpfTwvc3Bhbj4KICAgICAgICAgICAgPHNwYW4gY2xhc3M9InN5bmMtcGFpci1wYXRoIj4ke2VzYyhwLmRlc3QpfTwvc3Bhbj4KICAgICAgICAgICAgJHtwLmRlbGV0ZUV4dHJhID8gJzxzcGFuIGNsYXNzPSJ0YWcgdGFnLXJlZCI+5YmK6Zmk44GC44KKPC9zcGFuPicgOiAnJ30KICAgICAgICAgIDwvZGl2PgogICAgICAgICAgPGRpdiBjbGFzcz0ic3luYy1wYWlyLXJpZ2h0Ij4KICAgICAgICAgICAgJHtlcnJvckxpbmt9CiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tcGFzdGVsIGJ0bi1zbSIgb25jbGljaz0ic3luY1BhaXJOb3coJHtwaX0pIj4ke2ljb24oJ3N5bmMnKX0g5ZCM5pyfPC9idXR0b24+CiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tb3V0bGluZSBidG4tc20iIG9uY2xpY2s9ImVkaXRQYWlyKCR7cGl9KSI+JHtpY29uKCdlZGl0Jyl9IOe3qOmbhjwvYnV0dG9uPgogICAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLWRhbmdlciBidG4tc20iIG9uY2xpY2s9ImRlbGV0ZVBhaXIoJHtwaX0pIj4ke2ljb24oJ3RyYXNoJyl9PC9idXR0b24+CiAgICAgICAgICA8L2Rpdj4KICAgICAgICA8L2Rpdj5gOwogICAgICB9CiAgICAgIGh0bWwgKz0gJzwvZGl2Pic7CiAgICB9CiAgICBodG1sICs9ICc8L2Rpdj4nOwogIH0KICBjb250YWluZXIuaW5uZXJIVE1MID0gaHRtbDsKCiAgaWYgKHN5bmNQYWlycy5sZW5ndGgpIHsKICAgIHNjaGVkU2VjdGlvbi5zdHlsZS5kaXNwbGF5ID0gJyc7CiAgICByZW5kZXJTeW5jU2NoZWR1bGUoKTsKICB9IGVsc2UgewogICAgc2NoZWRTZWN0aW9uLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgfQp9CgovLyA9PT0gUmVtb3RlIEFjdGlvbnMgPT09CmFzeW5jIGZ1bmN0aW9uIHRlc3RSZW1vdGUobikgewogIHNob3dUb2FzdCgn44OG44K544OI5LitLi4uJywgJ2luZm8nKTsKICB0cnkgewogICAgY29uc3QgZCA9IGF3YWl0IGFwaShgL2FwaS9yZW1vdGVzLyR7bn0vdGVzdGAsIHsgbWV0aG9kOiAnUE9TVCcgfSk7CiAgICBzaG93VG9hc3QoZC5vayA/IGAke259IOaOpee2muaIkOWKn2AgOiBg5aSx5pWXOiAkeyhkLmVycm9yIHx8ICcnKS5zdWJzdHJpbmcoMCwgODApfWAsIGQub2sgPyAnc3VjY2VzcycgOiAnZXJyb3InKTsKICB9IGNhdGNoIChlKSB7CiAgICBzaG93VG9hc3QoJ+ODhuOCueODiOWkseaVlzogJyArIGUubWVzc2FnZSwgJ2Vycm9yJyk7CiAgfQp9Cgphc3luYyBmdW5jdGlvbiBkZWxldGVSZW1vdGUobikgewogIGlmICghY29uZmlybShg44CMJHtufeOAjeOCkuWJiumZpOOBl+OBvuOBmeOBi++8n2ApKSByZXR1cm47CiAgdHJ5IHsKICAgIGNvbnN0IGQgPSBhd2FpdCBhcGkoYC9hcGkvcmVtb3Rlcy8ke259YCwgeyBtZXRob2Q6ICdERUxFVEUnIH0pOwogICAgaWYgKGQub2spIHsgc2hvd1RvYXN0KCfliYrpmaTjgZfjgb7jgZfjgZ8nLCAnc3VjY2VzcycpOyBsb2FkQWxsKCk7IH0KICAgIGVsc2Ugc2hvd1RvYXN0KGQuZXJyb3IgfHwgJ+WkseaVlycsICdlcnJvcicpOwogIH0gY2F0Y2ggKGUpIHsgc2hvd1RvYXN0KCflpLHmlZc6ICcgKyBlLm1lc3NhZ2UsICdlcnJvcicpOyB9Cn0KCi8vID09PSBTU0ggPT09CmFzeW5jIGZ1bmN0aW9uIHNldHVwU3NoKCkgewogIHNob3dUb2FzdCgnU1NI6Kit5a6a5LitLi4uJywgJ2luZm8nKTsKICB0cnkgewogICAgY29uc3QgZCA9IGF3YWl0IGFwaSgnL2FwaS9zc2gvc2V0dXAnLCB7IG1ldGhvZDogJ1BPU1QnIH0pOwogICAgaWYgKGQub2spIHsKICAgICAgYWxlcnQoYFNTSOS4gOaZguioreWumuWujOS6hlxuXG7jg5vjgrnjg4g6ICR7ZC5ob3N0bmFtZX1cbuODpuODvOOCtuODvDogcm9vdFxu44OR44K544Ov44O844OJOiAke2QucGFzc3dvcmR9XG5cbuaOpee2mjpcbnNzaCAtTCA1MzY4MjoxMjcuMC4wLjE6NTM2ODIgcm9vdEAke2QuaG9zdG5hbWV9YCk7CiAgICAgIHNob3dUb2FzdCgnU1NI5pyJ5Yq5JywgJ3N1Y2Nlc3MnKTsKICAgIH0gZWxzZSBzaG93VG9hc3QoJ+WkseaVlzogJyArIChkLmVycm9yIHx8ICcnKSwgJ2Vycm9yJyk7CiAgfSBjYXRjaCAoZSkgeyBzaG93VG9hc3QoJ+WkseaVlzogJyArIGUubWVzc2FnZSwgJ2Vycm9yJyk7IH0KfQoKYXN5bmMgZnVuY3Rpb24gdGVhcmRvd25Tc2goKSB7CiAgaWYgKCFjb25maXJtKCfkuIDmmYJTU0joqK3lrprjgpLliYrpmaTjgZfjgb7jgZnjgYvvvJ8nKSkgcmV0dXJuOwogIHRyeSB7CiAgICBjb25zdCBkID0gYXdhaXQgYXBpKCcvYXBpL3NzaC90ZWFyZG93bicsIHsgbWV0aG9kOiAnUE9TVCcgfSk7CiAgICBzaG93VG9hc3QoZC5vayA/ICfliYrpmaTjgZfjgb7jgZfjgZ8nIDogJ+WkseaVlycsIGQub2sgPyAnc3VjY2VzcycgOiAnZXJyb3InKTsKICB9IGNhdGNoIChlKSB7IHNob3dUb2FzdCgn5aSx5pWXOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTsgfQp9CgovLyA9PT0gQWRkIFJlbW90ZSA9PT0KZnVuY3Rpb24gb3BlbkFkZE1vZGFsKHR5cGUpIHsKICBhdXRoVHlwZSA9IHR5cGU7CiAgY29uc3QgdGl0bGUgPSB0eXBlID09PSAnZHJpdmUnID8gJ0dvb2dsZSDjg4njg6njgqTjg5bjgpLov73liqAnIDogJ09uZURyaXZlIOOCkui/veWKoCc7CiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vZGFsLXRpdGxlJykudGV4dENvbnRlbnQgPSB0aXRsZTsKICBjb25zdCBkZWZhdWx0TmFtZSA9IHR5cGUgPT09ICdkcml2ZScgPyAnZ2RyaXZlJyA6ICdvbmVkcml2ZSc7CiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vZGFsLWJvZHknKS5pbm5lckhUTUwgPSBgCiAgICA8ZGl2IGNsYXNzPSJmb3JtLWdyb3VwIj4KICAgICAgPGxhYmVsPuODquODouODvOODiOWQjTwvbGFiZWw+CiAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBpZD0iYWRkLW5hbWUiIHZhbHVlPSIke2RlZmF1bHROYW1lfSI+CiAgICA8L2Rpdj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWZvb3RlciIgc3R5bGU9InBhZGRpbmc6MDttYXJnaW4tdG9wOjE2cHgiPgogICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLW91dGxpbmUiIG9uY2xpY2s9ImNsb3NlTW9kYWwoKSI+44Kt44Oj44Oz44K744OrPC9idXR0b24+CiAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tcGFzdGVsIiBvbmNsaWNrPSJhZGRSZW1vdGVPbmx5KCkiPui/veWKoOOBmeOCizwvYnV0dG9uPgogICAgPC9kaXY+YDsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9kYWwtYWRkJykuY2xhc3NMaXN0LmFkZCgnb3BlbicpOwp9Cgphc3luYyBmdW5jdGlvbiBhZGRSZW1vdGVPbmx5KCkgewogIGNvbnN0IG5hbWUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYWRkLW5hbWUnKS52YWx1ZS50cmltKCk7CiAgaWYgKCFuYW1lKSB7IHNob3dUb2FzdCgn5ZCN5YmN44KS5YWl5YqbJywgJ2Vycm9yJyk7IHJldHVybjsgfQogIHRyeSB7CiAgICBjb25zdCBkID0gYXdhaXQgYXBpKCcvYXBpL3JlbW90ZXMnLCB7IG1ldGhvZDogJ1BPU1QnLCBib2R5OiB7IG5hbWUsIHR5cGU6IGF1dGhUeXBlLCBwYXJhbXM6IHt9IH0gfSk7CiAgICBpZiAoIWQub2spIHsgc2hvd1RvYXN0KGQuZXJyb3IgfHwgJ+WkseaVlycsICdlcnJvcicpOyByZXR1cm47IH0KICAgIHNob3dUb2FzdChg44CMJHtuYW1lfeOAjeOCkui/veWKoOOBl+OBvuOBl+OBn2AsICdzdWNjZXNzJyk7CiAgICBjbG9zZU1vZGFsKCk7CiAgICBsb2FkQWxsKCk7CiAgfSBjYXRjaCAoZSkgeyBzaG93VG9hc3QoJ+WkseaVlzogJyArIGUubWVzc2FnZSwgJ2Vycm9yJyk7IH0KfQoKLy8gPT09IEF1dGggPT09CmZ1bmN0aW9uIHN0YXJ0QXV0aEZsb3cobmFtZSwgdHlwZSkgewogIGF1dGhSZW1vdGVOYW1lID0gbmFtZTsKICBhdXRoVHlwZSA9IHR5cGU7CiAgaWYgKGF1dGhQb2xsVGltZXIpIHsgY2xlYXJJbnRlcnZhbChhdXRoUG9sbFRpbWVyKTsgYXV0aFBvbGxUaW1lciA9IG51bGw7IH0KICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXV0aC1zdGF0dXMnKS50ZXh0Q29udGVudCA9ICfoqo3oqLzjgrXjg7zjg5Djg7zotbfli5XkuK0uLi4nOwogIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdXRoLXVybC1hcmVhJykuc3R5bGUuZGlzcGxheSA9ICdub25lJzsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXV0aC1kb25lLWFyZWEnKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnOwogIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2RhbC1hdXRoJykuY2xhc3NMaXN0LmFkZCgnb3BlbicpOwoKICBmZXRjaCgnL2FwaS9hdXRoL3N0YXJ0JywgewogICAgbWV0aG9kOiAnUE9TVCcsCiAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSwKICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgdHlwZSwgcmVtb3RlTmFtZTogbmFtZSB9KQogIH0pLnRoZW4ociA9PiByLmpzb24oKSkudGhlbihkYXRhID0+IHsKICAgIGlmICghZGF0YS5vaykgeyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXV0aC1zdGF0dXMnKS50ZXh0Q29udGVudCA9ICfjgqjjg6njg7w6ICcgKyAoZGF0YS5lcnJvciB8fCAnJyk7IHJldHVybjsgfQogICAgYXV0aFNlc3Npb25JZCA9IGRhdGEuc2Vzc2lvbklkOwogICAgaWYgKGRhdGEuYXV0aFVybCkgc2hvd1VybChkYXRhLmF1dGhVcmwpOwogICAgYXV0aFBvbGxUaW1lciA9IHNldEludGVydmFsKHBvbGxBdXRoLCAxNTAwKTsKICAgIHBvbGxBdXRoKCk7CiAgfSkuY2F0Y2goZSA9PiB7IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdXRoLXN0YXR1cycpLnRleHRDb250ZW50ID0gJ+OCqOODqeODvDogJyArIGUubWVzc2FnZTsgfSk7Cn0KCmZ1bmN0aW9uIHBvbGxBdXRoKCkgewogIGlmICghYXV0aFNlc3Npb25JZCkgcmV0dXJuOwogIGZldGNoKGAvYXBpL2F1dGgvcG9sbC8ke2F1dGhTZXNzaW9uSWR9YCkudGhlbihyID0+IHIuanNvbigpKS50aGVuKGRhdGEgPT4gewogICAgaWYgKGRhdGEuYXV0aFVybCkgc2hvd1VybChkYXRhLmF1dGhVcmwpOwogICAgaWYgKGRhdGEuZG9uZSkgewogICAgICBjbGVhckludGVydmFsKGF1dGhQb2xsVGltZXIpOyBhdXRoUG9sbFRpbWVyID0gbnVsbDsKICAgICAgaWYgKGRhdGEuc3VjY2VzcykgewogICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdXRoLWRvbmUtYXJlYScpLnN0eWxlLmRpc3BsYXkgPSAnJzsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXV0aC1zdGF0dXMnKS50ZXh0Q29udGVudCA9ICcnOwogICAgICAgIHNldFRpbWVvdXQoKCkgPT4geyBjbG9zZU1vZGFsKCk7IHNob3dUb2FzdChg44CMJHthdXRoUmVtb3RlTmFtZX3jgI3oqo3oqLzlrozkuoZgLCAnc3VjY2VzcycpOyBsb2FkQWxsKCk7IH0sIDIwMDApOwogICAgICB9IGVsc2UgewogICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdXRoLXN0YXR1cycpLnRleHRDb250ZW50ID0gJ+WkseaVlzogJyArIChkYXRhLmVycm9yIHx8ICcnKTsKICAgICAgfQogICAgfQogIH0pLmNhdGNoKCgpID0+IHt9KTsKfQoKZnVuY3Rpb24gc2hvd1VybCh1cmwpIHsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXV0aC11cmwtYXJlYScpLnN0eWxlLmRpc3BsYXkgPSAnJzsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXV0aC11cmwtaW5wdXQnKS52YWx1ZSA9IHVybDsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXV0aC11cmwtbGluaycpLmhyZWYgPSB1cmw7CiAgY29uc3QgbSA9IHVybC5tYXRjaCgvaHR0cDpcL1wvW1xkLl0rOihcZCspLyk7CiAgY29uc3QgcG9ydCA9IG0gPyBtWzFdIDogJzUzNjgyJzsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXV0aC1zdGF0dXMnKS50ZXh0Q29udGVudCA9ICdTU0jjg4jjg7Pjg43jg6vmjqXntprlvozjgIHkuIvjga5VUkzjgpLplovjgYTjgabjgY/jgaDjgZXjgYQnOwogIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzc2gtY21kJykudGV4dENvbnRlbnQgPSBgc3NoIC1MICR7cG9ydH06MTI3LjAuMC4xOiR7cG9ydH0gcm9vdEAke2xvY2F0aW9uLmhvc3RuYW1lfWA7Cn0KCmZ1bmN0aW9uIGNvcHlBdXRoVXJsKCkgewogIGNvbnN0IGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXV0aC11cmwtaW5wdXQnKTsKICBlLnNlbGVjdCgpOyBlLnNldFNlbGVjdGlvblJhbmdlKDAsIDk5OTk5KTsKICB0cnkgeyBkb2N1bWVudC5leGVjQ29tbWFuZCgnY29weScpOyBzaG93VG9hc3QoJ+OCs+ODlOODvOOBl+OBvuOBl+OBnycsICdzdWNjZXNzJyk7IH0gY2F0Y2ggeyBzaG93VG9hc3QoJ+WkseaVlycsICdlcnJvcicpOyB9Cn0KCmZ1bmN0aW9uIGNvcHlTc2hDbWQoKSB7CiAgY29uc3QgZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzc2gtY21kJyk7CiAgY29uc3QgdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7CiAgdC52YWx1ZSA9IGUudGV4dENvbnRlbnQ7IGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodCk7IHQuc2VsZWN0KCk7CiAgdHJ5IHsgZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ2NvcHknKTsgc2hvd1RvYXN0KCfjgrPjg5Tjg7zjgZfjgb7jgZfjgZ8nLCAnc3VjY2VzcycpOyB9IGNhdGNoIHsgc2hvd1RvYXN0KCflpLHmlZcnLCAnZXJyb3InKTsgfQogIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodCk7Cn0KCi8vID09PSBTeW5jIFBhaXJzID09PQpmdW5jdGlvbiBvcGVuQWRkUGFpcihyZW1vdGVOYW1lLCByZW1vdGVUeXBlKSB7CiAgYWRkaW5nUGFpckZvciA9IHJlbW90ZU5hbWU7CiAgY29uc3QgcHJlZml4ID0gYCR7cmVtb3RlTmFtZX06YDsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGFpci1wcmVmaXgnKS50ZXh0Q29udGVudCA9IHByZWZpeDsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGFpci1zb3VyY2UnKS52YWx1ZSA9ICcnOwogIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYWlyLWRlc3QnKS52YWx1ZSA9ICcnOwogIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYWlyLWRlbGV0ZScpLmNoZWNrZWQgPSBmYWxzZTsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9kYWwtc3luYy1wYWlyJykuY2xhc3NMaXN0LmFkZCgnb3BlbicpOwp9Cgphc3luYyBmdW5jdGlvbiBzYXZlU3luY1BhaXIoKSB7CiAgY29uc3Qgc291cmNlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BhaXItc291cmNlJykudmFsdWUudHJpbSgpOwogIGNvbnN0IHBhdGhPbmx5ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BhaXItZGVzdCcpLnZhbHVlLnRyaW0oKTsKICBjb25zdCBwcmVmaXggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGFpci1wcmVmaXgnKS50ZXh0Q29udGVudDsKICBjb25zdCBkZWxldGVFeHRyYSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYWlyLWRlbGV0ZScpLmNoZWNrZWQ7CiAgaWYgKCFzb3VyY2UpIHsgc2hvd1RvYXN0KCfjgrPjg5Tjg7zlhYPjgpLlhaXlipsnLCAnZXJyb3InKTsgcmV0dXJuOyB9CiAgaWYgKCFwYXRoT25seSkgeyBzaG93VG9hc3QoJ+OCs+ODlOODvOWFiOOCkuWFpeWKmycsICdlcnJvcicpOyByZXR1cm47IH0KCiAgaWYgKGVkaXRpbmdQYWlySWR4ID49IDApIHsKICAgIHN5bmNQYWlyc1tlZGl0aW5nUGFpcklkeF0gPSB7IHNvdXJjZSwgZGVzdDogcHJlZml4ICsgcGF0aE9ubHksIGRlbGV0ZUV4dHJhLCByZW1vdGVOYW1lOiBhZGRpbmdQYWlyRm9yIH07CiAgICBzaG93VG9hc3QoJ+WQjOacn+ODmuOCouOCkuabtOaWsOOBl+OBvuOBl+OBnycsICdzdWNjZXNzJyk7CiAgfSBlbHNlIHsKICAgIHN5bmNQYWlycy5wdXNoKHsgc291cmNlLCBkZXN0OiBwcmVmaXggKyBwYXRoT25seSwgZGVsZXRlRXh0cmEsIHJlbW90ZU5hbWU6IGFkZGluZ1BhaXJGb3IgfSk7CiAgICBzaG93VG9hc3QoJ+WQjOacn+ODmuOCouOCkui/veWKoOOBl+OBvuOBl+OBnycsICdzdWNjZXNzJyk7CiAgfQogIGVkaXRpbmdQYWlySWR4ID0gLTE7CiAgYXdhaXQgc2F2ZVNldHRpbmdzKCk7CiAgY2xvc2VNb2RhbCgpOwogIGxvYWRBbGwoKTsKfQoKYXN5bmMgZnVuY3Rpb24gZGVsZXRlUGFpcihpZHgpIHsKICBpZiAoIWNvbmZpcm0oJ+OBk+OBruWQjOacn+ODmuOCouOCkuWJiumZpOOBl+OBvuOBmeOBi++8nycpKSByZXR1cm47CiAgc3luY1BhaXJzLnNwbGljZShpZHgsIDEpOwogIHRyeSB7CiAgICBhd2FpdCBzYXZlU2V0dGluZ3MoKTsKICAgIHNob3dUb2FzdCgn5YmK6Zmk44GX44G+44GX44GfJywgJ3N1Y2Nlc3MnKTsKICAgIGxvYWRBbGwoKTsKICB9IGNhdGNoIChlKSB7IHNob3dUb2FzdCgn5aSx5pWXOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTsgfQp9Cgphc3luYyBmdW5jdGlvbiBzeW5jUGFpck5vdyhpZHgpIHsKICBjb25zdCBwID0gc3luY1BhaXJzW2lkeF07CiAgaWYgKCFwKSByZXR1cm47CiAgc2hvd1RvYXN0KCflkIzmnJ/plovlp4suLi4nLCAnaW5mbycpOwogIHRyeSB7CiAgICBjb25zdCBkID0gYXdhaXQgYXBpKCcvYXBpL2pvYnMnLCB7CiAgICAgIG1ldGhvZDogJ1BPU1QnLAogICAgICBib2R5OiB7IHNvdXJjZTogcC5zb3VyY2UsIGRlc3Q6IHAuZGVzdCwgbW9kZTogJ2NvcHknLCBuYW1lOiBgJHtwLnNvdXJjZX0g4oaSICR7cC5kZXN0fWAsIGRlbGV0ZUV4dHJhOiBwLmRlbGV0ZUV4dHJhIH0KICAgIH0pOwogICAgaWYgKGQuam9iSWQpIHsgc2hvd1RvYXN0KGDjgrjjg6fjg5YgJHtkLmpvYklkfSDplovlp4tgLCAnc3VjY2VzcycpOyBzaG93UGFnZSgnam9icycpOyB9CiAgICBlbHNlIHNob3dUb2FzdChkLmVycm9yIHx8ICflpLHmlZcnLCAnZXJyb3InKTsKICB9IGNhdGNoIChlKSB7IHNob3dUb2FzdCgn5aSx5pWXOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTsgfQp9CgpsZXQgZWRpdGluZ1BhaXJJZHggPSAtMTsKCmZ1bmN0aW9uIGVkaXRQYWlyKGlkeCkgewogIGVkaXRpbmdQYWlySWR4ID0gaWR4OwogIGNvbnN0IHAgPSBzeW5jUGFpcnNbaWR4XTsKICBjb25zdCByZW1vdGVOYW1lID0gcC5yZW1vdGVOYW1lIHx8IGFsbFJlbW90ZXNbMF0/Lm5hbWUgfHwgJ2dkcml2ZSc7CiAgYWRkaW5nUGFpckZvciA9IHJlbW90ZU5hbWU7CiAgY29uc3QgcHJlZml4ID0gYCR7cmVtb3RlTmFtZX06YDsKICBsZXQgcGF0aE9ubHkgPSBwLmRlc3QgfHwgJyc7CiAgaWYgKHBhdGhPbmx5LnN0YXJ0c1dpdGgocHJlZml4KSkgcGF0aE9ubHkgPSBwYXRoT25seS5zdWJzdHJpbmcocHJlZml4Lmxlbmd0aCk7CgogIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYWlyLXNvdXJjZScpLnZhbHVlID0gcC5zb3VyY2UgfHwgJyc7CiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BhaXItZGVzdCcpLnZhbHVlID0gcGF0aE9ubHk7CiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BhaXItZGVsZXRlJykuY2hlY2tlZCA9IHAuZGVsZXRlRXh0cmEgfHwgZmFsc2U7CiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BhaXItcHJlZml4JykudGV4dENvbnRlbnQgPSBwcmVmaXg7CiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vZGFsLXN5bmMtcGFpcicpLmNsYXNzTGlzdC5hZGQoJ29wZW4nKTsKfQoKYXN5bmMgZnVuY3Rpb24gc2F2ZVNldHRpbmdzKCkgewogIGF3YWl0IGFwaSgnL2FwaS9zeW5jLXNldHRpbmdzJywgeyBtZXRob2Q6ICdQT1NUJywgYm9keTogeyBwYWlyczogc3luY1BhaXJzLCBzY2hlZHVsZTogc3luY1NjaGVkdWxlIH0gfSk7Cn0KCi8vID09PSBTY2hlZHVsZSA9PT0KZnVuY3Rpb24gcmVuZGVyU3luY1NjaGVkdWxlKCkgewogIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N5bmMtc2NoZWR1bGUtbGlzdCcpOwogIGlmICghc3luY1NjaGVkdWxlLmxlbmd0aCkgewogICAgZWwuaW5uZXJIVE1MID0gJzxkaXYgc3R5bGU9InBhZGRpbmc6OHB4IDA7Y29sb3I6dmFyKC0tdGV4dDMpO2ZvbnQtc2l6ZTowLjg1cmVtIj7mnKroqK3lrpo8L2Rpdj4nOwogICAgcmV0dXJuOwogIH0KICBlbC5pbm5lckhUTUwgPSBzeW5jU2NoZWR1bGUubWFwKCh0LCBpKSA9PiBgCiAgICA8ZGl2IGNsYXNzPSJzeW5jLXNjaGVkdWxlLWl0ZW0iPgogICAgICA8c3BhbiBjbGFzcz0ic3luYy1zY2hlZHVsZS10aW1lIj4ke2ljb24oJ2Nsb2NrJyl9ICR7dH08L3NwYW4+CiAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tZGFuZ2VyIGJ0bi1zbSIgb25jbGljaz0ic3luY1NjaGVkdWxlLnNwbGljZSgke2l9LDEpO3JlbmRlclN5bmNTY2hlZHVsZSgpIj4ke2ljb24oJ3RyYXNoJyl9PC9idXR0b24+CiAgICA8L2Rpdj4KICBgKS5qb2luKCcnKTsKfQoKZnVuY3Rpb24gYWRkU3luY1NjaGVkdWxlKCkgewogIGNvbnN0IGhvdXJTZWxlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2NoZWR1bGUtdGltZS1zZWxlY3QnKTsKICBjb25zdCBtaW5TZWxlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2NoZWR1bGUtbWluLXNlbGVjdCcpOwogIGNvbnN0IGhvdXIgPSBob3VyU2VsZWN0LnZhbHVlOwogIGNvbnN0IG1pbiA9IG1pblNlbGVjdC52YWx1ZTsKICBpZiAoIWhvdXIgJiYgaG91ciAhPT0gJzAnKSB7IHNob3dUb2FzdCgn5pmC6ZaT44KS6YG45oqe44GX44Gm44GP44Gg44GV44GEJywgJ2Vycm9yJyk7IHJldHVybjsgfQogIGNvbnN0IGggPSBob3VyLnBhZFN0YXJ0KDIsICcwJyk7CiAgY29uc3QgdGltZSA9IGAke2h9OiR7bWlufWA7CiAgaWYgKHN5bmNTY2hlZHVsZS5pbmNsdWRlcyh0aW1lKSkgeyBzaG93VG9hc3QoJ+mHjeikh+OBl+OBpuOBhOOBvuOBmScsICdlcnJvcicpOyByZXR1cm47IH0KICBzeW5jU2NoZWR1bGUucHVzaCh0aW1lKTsKICBzeW5jU2NoZWR1bGUuc29ydCgpOwogIHJlbmRlclN5bmNTY2hlZHVsZSgpOwogIGhvdXJTZWxlY3QudmFsdWUgPSAnJzsKICBtaW5TZWxlY3QudmFsdWUgPSAnMDAnOwp9Cgphc3luYyBmdW5jdGlvbiBzYXZlU2NoZWR1bGUoKSB7CiAgYXdhaXQgYXBpKCcvYXBpL3N5bmMtc2V0dGluZ3MnLCB7IG1ldGhvZDogJ1BPU1QnLCBib2R5OiB7IHBhaXJzOiBzeW5jUGFpcnMsIHNjaGVkdWxlOiBzeW5jU2NoZWR1bGUgfSB9KTsKICBzaG93VG9hc3QoJ+OCueOCseOCuOODpeODvOODq+OCkuS/neWtmOOBl+OBvuOBl+OBnycsICdzdWNjZXNzJyk7Cn0KCmZ1bmN0aW9uIGV4cG9ydFNldHRpbmdzKCkgewogIGNvbnN0IGRhdGEgPSB7IHBhaXJzOiBzeW5jUGFpcnMsIHNjaGVkdWxlOiBzeW5jU2NoZWR1bGUsIGV4cG9ydGVkQXQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSB9OwogIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbSlNPTi5zdHJpbmdpZnkoZGF0YSwgbnVsbCwgMildLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyB9KTsKICBjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpOwogIGNvbnN0IGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7CiAgYS5ocmVmID0gdXJsOwogIGEuZG93bmxvYWQgPSBgZWFzeXJjbG9uZS1zZXR0aW5ncy0ke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKS5zbGljZSgwLDEwKX0uanNvbmA7CiAgYS5jbGljaygpOwogIFVSTC5yZXZva2VPYmplY3RVUkwodXJsKTsKICBzaG93VG9hc3QoJ+ioreWumuOCkuOCqOOCr+OCueODneODvOODiOOBl+OBvuOBl+OBnycsICdzdWNjZXNzJyk7Cn0KCmZ1bmN0aW9uIGltcG9ydFNldHRpbmdzKCkgewogIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTsKICBpbnB1dC50eXBlID0gJ2ZpbGUnOwogIGlucHV0LmFjY2VwdCA9ICcuanNvbic7CiAgaW5wdXQub25jaGFuZ2UgPSBhc3luYyAoZSkgPT4gewogICAgY29uc3QgZmlsZSA9IGUudGFyZ2V0LmZpbGVzWzBdOwogICAgaWYgKCFmaWxlKSByZXR1cm47CiAgICB0cnkgewogICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgZmlsZS50ZXh0KCk7CiAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKHRleHQpOwogICAgICBpZiAoZGF0YS5wYWlycyAmJiBkYXRhLnNjaGVkdWxlKSB7CiAgICAgICAgc3luY1BhaXJzID0gZGF0YS5wYWlyczsKICAgICAgICBzeW5jU2NoZWR1bGUgPSBkYXRhLnNjaGVkdWxlOwogICAgICAgIGF3YWl0IHNhdmVTZXR0aW5ncygpOwogICAgICAgIHNob3dUb2FzdCgn6Kit5a6a44KS44Kk44Oz44Od44O844OI44GX44G+44GX44GfJywgJ3N1Y2Nlc3MnKTsKICAgICAgICBsb2FkQWxsKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc2hvd1RvYXN0KCfnhKHlirnjgaroqK3lrprjg5XjgqHjgqTjg6vjgafjgZknLCAnZXJyb3InKTsKICAgICAgfQogICAgfSBjYXRjaCAoZSkgewogICAgICBzaG93VG9hc3QoJ+iqreOBv+i+vOOBv+OCqOODqeODvDogJyArIGUubWVzc2FnZSwgJ2Vycm9yJyk7CiAgICB9CiAgfTsKICBpbnB1dC5jbGljaygpOwp9Cgphc3luYyBmdW5jdGlvbiBzaG93Q3JvbkluZm8oKSB7CiAgY29uc3QgYXJlYSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjcm9uLWluZm8tYXJlYScpOwogIGNvbnN0IGNvbnRlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY3Jvbi1pbmZvLWNvbnRlbnQnKTsKICBpZiAoYXJlYS5zdHlsZS5kaXNwbGF5ICE9PSAnbm9uZScpIHsgYXJlYS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnOyByZXR1cm47IH0KICBhcmVhLnN0eWxlLmRpc3BsYXkgPSAnJzsKICBjb250ZW50LnRleHRDb250ZW50ID0gJ+iqreOBv+i+vOOBv+S4rS4uLic7CiAgY29uc3QgZCA9IGF3YWl0IGFwaSgnL2FwaS9jcm9uLWluZm8nKTsKICBjb250ZW50LnRleHRDb250ZW50ID0gZC5vayA/IGQub3V0cHV0IDogJ+OCqOODqeODvDogJyArIChkLmVycm9yIHx8ICcnKTsKfQoKLy8gPT09IEpvYnMgPT09CmFzeW5jIGZ1bmN0aW9uIGxvYWRKb2JzKCkgewogIGNvbnN0IGRhdGEgPSBhd2FpdCBhcGkoJy9hcGkvam9icycpOwogIGNvbnN0IGxpc3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnam9iLWxpc3QnKTsKICBpZiAoIWRhdGEuam9icz8ubGVuZ3RoKSB7CiAgICBsaXN0LmlubmVySFRNTCA9IGAKICAgICAgPGRpdiBjbGFzcz0iZW1wdHktc3RhdGUiPgogICAgICAgIDxkaXYgY2xhc3M9ImVtcHR5LWljb24iPiR7aWNvbignZmlsZVRleHQnKX08L2Rpdj4KICAgICAgICA8aDM+44K444On44OW44GM44GC44KK44G+44Gb44KTPC9oMz4KICAgICAgPC9kaXY+YDsKICAgIHJldHVybjsKICB9CiAgbGlzdC5pbm5lckhUTUwgPSBkYXRhLmpvYnMubWFwKGogPT4gewogICAgY29uc3Qgc2wgPSB7IHJ1bm5pbmc6ICflrp/ooYzkuK0nLCBjb21wbGV0ZWQ6ICflrozkuoYnLCBmYWlsZWQ6ICflpLHmlZcnLCBzdG9wcGVkOiAn5YGc5q2iJyB9W2ouc3RhdHVzXSB8fCBqLnN0YXR1czsKICAgIGNvbnN0IGxvZ0xpbmVzID0gKGoubG9nIHx8ICcnKS5zcGxpdCgnXG4nKS5maWx0ZXIoQm9vbGVhbik7CiAgICBjb25zdCBsYXN0TGluZXMgPSBsb2dMaW5lcy5zbGljZSgtMjApLmpvaW4oJ1xuJyk7CiAgICByZXR1cm4gYAogICAgPGRpdiBjbGFzcz0iam9iLWNhcmQiPgogICAgICA8ZGl2IGNsYXNzPSJqb2ItY2FyZC10b3AiPgogICAgICAgIDxzcGFuIGNsYXNzPSJqb2ItY2FyZC1uYW1lIj4ke2VzYyhqLm5hbWUgfHwgai5pZCl9PC9zcGFuPgogICAgICAgIDxzcGFuIGNsYXNzPSJqb2Itc3RhdHVzICR7ai5zdGF0dXN9Ij4ke3NsfTwvc3Bhbj4KICAgICAgPC9kaXY+CiAgICAgIDxkaXYgY2xhc3M9ImpvYi1jYXJkLXBhdGhzIj48c3Bhbj4ke2VzYyhqLnNvdXJjZSl9PC9zcGFuPjxzcGFuIGNsYXNzPSJzeW5jLWFycm93Ij4ke2ljb24oJ2Fycm93UmlnaHQnKX08L3NwYW4+PHNwYW4+JHtlc2Moai5kZXN0KX08L3NwYW4+PC9kaXY+CiAgICAgIDxkaXYgY2xhc3M9ImpvYi1jYXJkLW1ldGEiPgogICAgICAgIDxkaXY+JHtuZXcgRGF0ZShqLmNyZWF0ZWRBdCkudG9Mb2NhbGVTdHJpbmcoJ2phLUpQJyl9JHtqLmNvbXBsZXRlZEF0ID8gJyDihpIgJyArIG5ldyBEYXRlKGouY29tcGxldGVkQXQpLnRvTG9jYWxlU3RyaW5nKCdqYS1KUCcpIDogJyd9PC9kaXY+CiAgICAgIDwvZGl2PgogICAgICAke2xhc3RMaW5lcyA/IGA8ZGl2IGNsYXNzPSJqb2ItbG9nIj48cHJlPiR7ZXNjKGxhc3RMaW5lcyl9PC9wcmU+PC9kaXY+YCA6ICcnfQogICAgPC9kaXY+YDsKICB9KS5qb2luKCcnKTsKCiAgaWYgKGRhdGEuam9icy5zb21lKGogPT4gai5zdGF0dXMgPT09ICdydW5uaW5nJykpIHNldFRpbWVvdXQobG9hZEpvYnMsIDIwMDApOwp9Cgpkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdET01Db250ZW50TG9hZGVkJywgKCkgPT4gbG9hZEFsbCgpKTsK'
B64_CSS='OnJvb3QgewogIC0tcHJpbWFyeTogIzYzNjZmMTsKICAtLXByaW1hcnktaG92ZXI6ICM0ZjQ2ZTU7CiAgLS1wcmltYXJ5LWxpZ2h0OiAjZWVmMmZmOwogIC0tcHJpbWFyeS01MDogcmdiYSg5OSwxMDIsMjQxLDAuMDgpOwogIC0tYmc6ICNmOGZhZmM7CiAgLS1jYXJkOiAjZmZmZmZmOwogIC0tdGV4dDogIzBmMTcyYTsKICAtLXRleHQyOiAjMzM0MTU1OwogIC0tdGV4dDM6ICM5NGEzYjg7CiAgLS1ib3JkZXI6ICNlMmU4ZjA7CiAgLS1ib3JkZXIyOiAjY2JkNWUxOwogIC0tc3VjY2VzczogIzEwYjk4MTsKICAtLXN1Y2Nlc3MtYmc6ICNlY2ZkZjU7CiAgLS1kYW5nZXI6ICNlZjQ0NDQ7CiAgLS1kYW5nZXItYmc6ICNmZWYyZjI7CiAgLS13YXJuaW5nOiAjZjU5ZTBiOwogIC0td2FybmluZy1iZzogI2ZmZmJlYjsKICAtLWRyaXZlOiAjMzRhODUzOwogIC0tb25lZHJpdmU6ICMwMDc4ZDQ7CiAgLS1yYWRpdXM6IDEycHg7CiAgLS1yYWRpdXMtc206IDhweDsKICAtLXJhZGl1cy14czogNnB4OwogIC0tc2hhZG93OiAwIDFweCAycHggcmdiYSgwLDAsMCwwLjA0KTsKICAtLXNoYWRvdy1zbTogMCAxcHggM3B4IHJnYmEoMCwwLDAsMC4wNiksIDAgMXB4IDJweCByZ2JhKDAsMCwwLDAuMDQpOwogIC0tc2hhZG93LW1kOiAwIDRweCA2cHggLTFweCByZ2JhKDAsMCwwLDAuMDcpLCAwIDJweCA0cHggLTJweCByZ2JhKDAsMCwwLDAuMDUpOwogIC0tdHJhbnNpdGlvbjogMC4xNXMgZWFzZTsKfQoKKiB7IG1hcmdpbjogMDsgcGFkZGluZzogMDsgYm94LXNpemluZzogYm9yZGVyLWJveDsgfQpib2R5IHsKICBmb250LWZhbWlseTogJ0ludGVyJywgLWFwcGxlLXN5c3RlbSwgQmxpbmtNYWNTeXN0ZW1Gb250LCAnU2Vnb2UgVUknLCAnSGlyYWdpbm8gU2FucycsICdZdSBHb3RoaWMnLCBzYW5zLXNlcmlmOwogIGJhY2tncm91bmQ6IHZhcigtLWJnKTsgY29sb3I6IHZhcigtLXRleHQpOyBtaW4taGVpZ2h0OiAxMDB2aDsKICAtd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhbnRpYWxpYXNlZDsKfQoKLyogSGVhZGVyICovCi5hcHAtaGVhZGVyIHsKICBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkKTsKICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsKICBjb2xvcjogdmFyKC0tdGV4dCk7IHBhZGRpbmc6IDAgMjhweDsgaGVpZ2h0OiA2MHB4OwogIGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsKICBwb3NpdGlvbjogc3RpY2t5OyB0b3A6IDA7IHotaW5kZXg6IDEwMDsKfQouaGVhZGVyLWxlZnQgeyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDEycHg7IH0KLmhlYWRlci1sZWZ0IC5sb2dvLWljb24gewogIHdpZHRoOiAzMnB4OyBoZWlnaHQ6IDMycHg7IGJvcmRlci1yYWRpdXM6IDhweDsKICBiYWNrZ3JvdW5kOiB2YXIoLS1wcmltYXJ5KTsgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsganVzdGlmeS1jb250ZW50OiBjZW50ZXI7Cn0KLmhlYWRlci1sZWZ0IGgxIHsgZm9udC1zaXplOiAxLjA1cmVtOyBmb250LXdlaWdodDogNzAwOyBjb2xvcjogdmFyKC0tdGV4dCk7IGxldHRlci1zcGFjaW5nOiAtMC4wMWVtOyB9Ci5oZWFkZXItcmlnaHQgeyBkaXNwbGF5OiBmbGV4OyBnYXA6IDZweDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgfQoKLyogSWNvbiBCdXR0b25zIChoZWFkZXIpICovCi5idG4taWNvbi1oZWFkZXIgewogIGRpc3BsYXk6IGlubGluZS1mbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDZweDsKICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsKICBjb2xvcjogdmFyKC0tdGV4dDIpOyBwYWRkaW5nOiA3cHggMTRweDsgYm9yZGVyLXJhZGl1czogdmFyKC0tcmFkaXVzLXNtKTsKICBjdXJzb3I6IHBvaW50ZXI7IGZvbnQtc2l6ZTogMC44MnJlbTsgZm9udC13ZWlnaHQ6IDUwMDsKICB0cmFuc2l0aW9uOiBhbGwgdmFyKC0tdHJhbnNpdGlvbik7IHdoaXRlLXNwYWNlOiBub3dyYXA7Cn0KLmJ0bi1pY29uLWhlYWRlcjpob3ZlciB7IGJhY2tncm91bmQ6IHZhcigtLWJnKTsgYm9yZGVyLWNvbG9yOiB2YXIoLS1ib3JkZXIyKTsgY29sb3I6IHZhcigtLXRleHQpOyB9Ci5idG4taWNvbi1oZWFkZXIgc3ZnIHsgd2lkdGg6IDE1cHg7IGhlaWdodDogMTVweDsgZmxleC1zaHJpbms6IDA7IH0KLmJ0bi1pY29uLWhlYWRlci5hY3RpdmUgeyBiYWNrZ3JvdW5kOiB2YXIoLS1wcmltYXJ5LWxpZ2h0KTsgYm9yZGVyLWNvbG9yOiB2YXIoLS1wcmltYXJ5KTsgY29sb3I6IHZhcigtLXByaW1hcnkpOyB9Ci5idG4taWNvbi1oZWFkZXIuYWNjZW50IHsKICBiYWNrZ3JvdW5kOiB2YXIoLS1wcmltYXJ5KTsgYm9yZGVyLWNvbG9yOiB2YXIoLS1wcmltYXJ5KTsgY29sb3I6IHdoaXRlOwp9Ci5idG4taWNvbi1oZWFkZXIuYWNjZW50OmhvdmVyIHsgYmFja2dyb3VuZDogdmFyKC0tcHJpbWFyeS1ob3Zlcik7IGJvcmRlci1jb2xvcjogdmFyKC0tcHJpbWFyeS1ob3Zlcik7IH0KCi8qIExheW91dCAqLwouY29udGVudCB7IG1heC13aWR0aDogMTA4MHB4OyBtYXJnaW46IDAgYXV0bzsgcGFkZGluZzogMjhweCAyMHB4OyB9Ci5wYWdlIHsgZGlzcGxheTogbm9uZTsgfQoucGFnZS5hY3RpdmUgeyBkaXNwbGF5OiBibG9jazsgfQoKLnBhZ2UtaGVhZGVyIHsgbWFyZ2luLWJvdHRvbTogMjRweDsgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOyB9Ci5wYWdlLWhlYWRlciBoMiB7IGZvbnQtc2l6ZTogMS4yNXJlbTsgZm9udC13ZWlnaHQ6IDcwMDsgbGV0dGVyLXNwYWNpbmc6IC0wLjAxZW07IH0KLnBhZ2UtaGVhZGVyIC5kZXNjIHsgY29sb3I6IHZhcigtLXRleHQzKTsgZm9udC1zaXplOiAwLjg4cmVtOyB9CgovKiBDYXJkcyAqLwouY2FyZCB7CiAgYmFja2dyb3VuZDogdmFyKC0tY2FyZCk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cyk7CiAgcGFkZGluZzogMjBweCAyNHB4OyBtYXJnaW4tYm90dG9tOiAxNnB4Owp9Ci5jYXJkIGgzIHsKICBmb250LXNpemU6IDAuOTVyZW07IGZvbnQtd2VpZ2h0OiA2MDA7IG1hcmdpbi1ib3R0b206IDE2cHg7CiAgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7IGNvbG9yOiB2YXIoLS10ZXh0KTsKfQouY2FyZCBoMyBzdmcgeyB3aWR0aDogMThweDsgaGVpZ2h0OiAxOHB4OyBjb2xvcjogdmFyKC0tdGV4dDMpOyB9CgovKiBSZW1vdGUgQ2FyZHMgKi8KLnJlbW90ZS1jYXJkcyB7IGRpc3BsYXk6IGdyaWQ7IGdhcDogMTZweDsgfQoucmVtb3RlLWNhcmQgeyBwYWRkaW5nOiAwOyBvdmVyZmxvdzogaGlkZGVuOyB9Ci5yZW1vdGUtY2FyZC1oZWFkZXIgewogIGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsKICBwYWRkaW5nOiAxOHB4IDI0cHg7IGZsZXgtd3JhcDogd3JhcDsgZ2FwOiAxMnB4Owp9Ci5yZW1vdGUtY2FyZC1sZWZ0IHsgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiAxNHB4OyB9Ci5yZW1vdGUtaWNvbiB7CiAgd2lkdGg6IDQwcHg7IGhlaWdodDogNDBweDsgYm9yZGVyLXJhZGl1czogMTBweDsKICBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsKICBjb2xvcjogd2hpdGU7Cn0KLnJlbW90ZS1pY29uIHN2ZyB7IHdpZHRoOiAyMHB4OyBoZWlnaHQ6IDIwcHg7IH0KLnJlbW90ZS1pY29uLmRyaXZlIHsgYmFja2dyb3VuZDogdmFyKC0tZHJpdmUpOyB9Ci5yZW1vdGUtaWNvbi5vbmVkcml2ZSB7IGJhY2tncm91bmQ6IHZhcigtLW9uZWRyaXZlKTsgfQoucmVtb3RlLWNhcmQtbmFtZSB7IGZvbnQtd2VpZ2h0OiA2MDA7IGZvbnQtc2l6ZTogMC45NXJlbTsgfQoucmVtb3RlLWNhcmQtdHlwZSB7IGZvbnQtc2l6ZTogMC43OHJlbTsgY29sb3I6IHZhcigtLXRleHQzKTsgbWFyZ2luLXRvcDogMXB4OyB9Ci5yZW1vdGUtY2FyZC1hY3Rpb25zIHsgZGlzcGxheTogZmxleDsgZ2FwOiA2cHg7IGZsZXgtd3JhcDogd3JhcDsgfQoKLyogU3luYyBQYWlycyBBcmVhICovCi5zeW5jLXBhaXJzLWFyZWEgeyBwYWRkaW5nOiAwIDI0cHggMThweDsgfQouc3luYy1wYWlycy1hcmVhLXRpdGxlIHsKICBmb250LXNpemU6IDAuNzhyZW07IGZvbnQtd2VpZ2h0OiA2MDA7IGNvbG9yOiB2YXIoLS10ZXh0Myk7CiAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTsgbGV0dGVyLXNwYWNpbmc6IDAuMDRlbTsKICBtYXJnaW4tYm90dG9tOiAxMHB4OyBwYWRkaW5nLXRvcDogMTRweDsgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7Cn0KLnN5bmMtcGFpci1yb3cgewogIGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogMTBweDsgcGFkZGluZzogMTBweCAxNHB4OwogIGJhY2tncm91bmQ6IHZhcigtLWJnKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsKICBib3JkZXItcmFkaXVzOiB2YXIoLS1yYWRpdXMtc20pOyBtYXJnaW4tYm90dG9tOiA4cHg7CiAgZm9udC1zaXplOiAwLjg1cmVtOyBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47Cn0KLnN5bmMtcGFpci1sZWZ0IHsgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7IGZsZXg6IDE7IG1pbi13aWR0aDogMDsgfQouc3luYy1wYWlyLXBhdGggeyBmb250LWZhbWlseTogJ1NGIE1vbm8nLCAnRmlyYSBDb2RlJywgbW9ub3NwYWNlOyBmb250LXNpemU6IDAuOHJlbTsgY29sb3I6IHZhcigtLXRleHQyKTsgd29yZC1icmVhazogYnJlYWstYWxsOyB9Ci5zeW5jLXBhaXItcmlnaHQgeyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDZweDsgZmxleC1zaHJpbms6IDA7IH0KLnN5bmMtYXJyb3cgeyBjb2xvcjogdmFyKC0tcHJpbWFyeSk7IGZvbnQtd2VpZ2h0OiA3MDA7IGZsZXgtc2hyaW5rOiAwOyBmb250LXNpemU6IDAuODVyZW07IH0KLnN5bmMtZXJyb3ItbGluayB7CiAgZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tZGFuZ2VyKTsgY3Vyc29yOiBwb2ludGVyOwogIHRleHQtZGVjb3JhdGlvbjogbm9uZTsgd2hpdGUtc3BhY2U6IG5vd3JhcDsgZm9udC13ZWlnaHQ6IDUwMDsKfQouc3luYy1lcnJvci1saW5rOmhvdmVyIHsgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7IH0KLnRhZyB7IGRpc3BsYXk6IGlubGluZS1mbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDRweDsgcGFkZGluZzogMnB4IDhweDsgYm9yZGVyLXJhZGl1czogNHB4OyBmb250LXNpemU6IDAuNzJyZW07IGZvbnQtd2VpZ2h0OiA2MDA7IH0KLnRhZy1yZWQgeyBiYWNrZ3JvdW5kOiB2YXIoLS1kYW5nZXItYmcpOyBjb2xvcjogI2I5MWMxYzsgfQoudGFnIHN2ZyB7IHdpZHRoOiAxMnB4OyBoZWlnaHQ6IDEycHg7IH0KCi8qIEJ1dHRvbnMgKi8KLmJ0biB7CiAgcGFkZGluZzogOHB4IDE0cHg7IGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy14cyk7IGZvbnQtc2l6ZTogMC44MnJlbTsKICBmb250LXdlaWdodDogNTAwOyBjdXJzb3I6IHBvaW50ZXI7IGJvcmRlcjogbm9uZTsgdHJhbnNpdGlvbjogYWxsIHZhcigtLXRyYW5zaXRpb24pOwogIGRpc3BsYXk6IGlubGluZS1mbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDVweDsgd2hpdGUtc3BhY2U6IG5vd3JhcDsKfQouYnRuIHN2ZyB7IHdpZHRoOiAxNHB4OyBoZWlnaHQ6IDE0cHg7IGZsZXgtc2hyaW5rOiAwOyB9Ci5idG4tcHJpbWFyeSB7IGJhY2tncm91bmQ6IHZhcigtLXByaW1hcnkpOyBjb2xvcjogd2hpdGU7IH0KLmJ0bi1wcmltYXJ5OmhvdmVyIHsgYmFja2dyb3VuZDogdmFyKC0tcHJpbWFyeS1ob3Zlcik7IH0KLmJ0bi1kYW5nZXIgeyBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tZGFuZ2VyKTsgY29sb3I6IHZhcigtLWRhbmdlcik7IH0KLmJ0bi1kYW5nZXI6aG92ZXIgeyBiYWNrZ3JvdW5kOiB2YXIoLS1kYW5nZXIpOyBjb2xvcjogd2hpdGU7IH0KLmJ0bi1zdWNjZXNzIHsgYmFja2dyb3VuZDogdmFyKC0tc3VjY2Vzcyk7IGNvbG9yOiB3aGl0ZTsgfQouYnRuLXN1Y2Nlc3M6aG92ZXIgeyBiYWNrZ3JvdW5kOiAjMDU5NjY5OyB9Ci5idG4tcGFzdGVsIHsgYmFja2dyb3VuZDogI2UwZTdmZjsgY29sb3I6ICM0MzM4Y2E7IGJvcmRlcjogbm9uZTsgfQouYnRuLXBhc3RlbDpob3ZlciB7IGJhY2tncm91bmQ6ICNjN2QyZmU7IH0KLmJ0bi1wYXN0ZWwtZ3JlZW4geyBiYWNrZ3JvdW5kOiAjZDFmYWU1OyBjb2xvcjogIzA0Nzg1NzsgYm9yZGVyOiBub25lOyB9Ci5idG4tcGFzdGVsLWdyZWVuOmhvdmVyIHsgYmFja2dyb3VuZDogI2E3ZjNkMDsgfQouYnRuLW91dGxpbmUgeyBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgY29sb3I6IHZhcigtLXRleHQyKTsgfQouYnRuLW91dGxpbmU6aG92ZXIgeyBiYWNrZ3JvdW5kOiB2YXIoLS1iZyk7IGJvcmRlci1jb2xvcjogdmFyKC0tYm9yZGVyMik7IH0KLmJ0bi1zbSB7IHBhZGRpbmc6IDVweCAxMHB4OyBmb250LXNpemU6IDAuNzhyZW07IH0KLmJ0bi1zbSBzdmcgeyB3aWR0aDogMTNweDsgaGVpZ2h0OiAxM3B4OyB9Ci5idG4tbGcgeyBwYWRkaW5nOiAxMnB4IDI4cHg7IGZvbnQtc2l6ZTogMC45NXJlbTsgfQouYnRuOmRpc2FibGVkIHsgb3BhY2l0eTogMC41OyBjdXJzb3I6IG5vdC1hbGxvd2VkOyB9CgovKiBFbXB0eSBTdGF0ZSAqLwouZW1wdHktc3RhdGUgeyB0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDQ4cHggMjRweDsgY29sb3I6IHZhcigtLXRleHQzKTsgfQouZW1wdHktaWNvbiB7CiAgd2lkdGg6IDU2cHg7IGhlaWdodDogNTZweDsgYm9yZGVyLXJhZGl1czogMTRweDsgbWFyZ2luOiAwIGF1dG8gMTZweDsKICBiYWNrZ3JvdW5kOiB2YXIoLS1iZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7CiAgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsganVzdGlmeS1jb250ZW50OiBjZW50ZXI7Cn0KLmVtcHR5LWljb24gc3ZnIHsgd2lkdGg6IDI0cHg7IGhlaWdodDogMjRweDsgY29sb3I6IHZhcigtLXRleHQzKTsgfQouZW1wdHktc3RhdGUgaDMgeyBmb250LXNpemU6IDFyZW07IGNvbG9yOiB2YXIoLS10ZXh0Mik7IG1hcmdpbi1ib3R0b206IDRweDsgZm9udC13ZWlnaHQ6IDYwMDsgfQouZW1wdHktc3RhdGUgcCB7IGZvbnQtc2l6ZTogMC44NXJlbTsgfQoKLyogU2NoZWR1bGUgU2VjdGlvbiAqLwouc2NoZWR1bGUtc2VjdGlvbiB7IG1hcmdpbi10b3A6IDI0cHg7IH0KLnNjaGVkdWxlLXRpbWUtcm93IHsgZGlzcGxheTogZmxleDsgZ2FwOiA4cHg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IG1hcmdpbi1ib3R0b206IDEycHg7IH0KLnNjaGVkdWxlLXRpbWUtcm93IHNlbGVjdCB7CiAgcGFkZGluZzogOHB4IDEycHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy14cyk7CiAgZm9udC1zaXplOiAwLjg1cmVtOyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkKTsgY29sb3I6IHZhcigtLXRleHQpOwp9Ci5zY2hlZHVsZS10aW1lLXJvdyBzZWxlY3Q6Zm9jdXMgeyBvdXRsaW5lOiBub25lOyBib3JkZXItY29sb3I6IHZhcigtLXByaW1hcnkpOyB9Cgouc3luYy1zY2hlZHVsZS1pdGVtIHsKICBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47CiAgcGFkZGluZzogOHB4IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWJnKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsKICBib3JkZXItcmFkaXVzOiB2YXIoLS1yYWRpdXMteHMpOyBtYXJnaW4tYm90dG9tOiA2cHg7IGZvbnQtc2l6ZTogMC44NXJlbTsKfQouc3luYy1zY2hlZHVsZS10aW1lIHsgZm9udC13ZWlnaHQ6IDUwMDsgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA2cHg7IH0KLnN5bmMtc2NoZWR1bGUtdGltZSBzdmcgeyB3aWR0aDogMTRweDsgaGVpZ2h0OiAxNHB4OyBjb2xvcjogdmFyKC0tdGV4dDMpOyB9CgovKiBCdXR0b25zIFJvdyAqLwouYnRuLXJvdyB7IGRpc3BsYXk6IGZsZXg7IGdhcDogOHB4OyBmbGV4LXdyYXA6IHdyYXA7IG1hcmdpbi10b3A6IDEycHg7IH0KCi8qIE9wdGlvbnMgKi8KLmZvcm0tZ3JvdXAgeyBtYXJnaW4tYm90dG9tOiAxNHB4OyB9Ci5mb3JtLWdyb3VwIGxhYmVsIHsKICBkaXNwbGF5OiBibG9jazsgZm9udC1zaXplOiAwLjhyZW07IGZvbnQtd2VpZ2h0OiA1MDA7IG1hcmdpbi1ib3R0b206IDZweDsgY29sb3I6IHZhcigtLXRleHQyKTsKfQouZm9ybS1ncm91cCBpbnB1dCwgLmZvcm0tZ3JvdXAgc2VsZWN0LCAuZm9ybS1ncm91cCB0ZXh0YXJlYSB7CiAgd2lkdGg6IDEwMCU7IHBhZGRpbmc6IDlweCAxMnB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOwogIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy14cyk7IGZvbnQtc2l6ZTogMC44NXJlbTsgdHJhbnNpdGlvbjogYm9yZGVyLWNvbG9yIHZhcigtLXRyYW5zaXRpb24pOwogIGJhY2tncm91bmQ6IHZhcigtLWNhcmQpOyBjb2xvcjogdmFyKC0tdGV4dCk7Cn0KLmZvcm0tZ3JvdXAgaW5wdXQ6Zm9jdXMsIC5mb3JtLWdyb3VwIHNlbGVjdDpmb2N1cyB7CiAgb3V0bGluZTogbm9uZTsgYm9yZGVyLWNvbG9yOiB2YXIoLS1wcmltYXJ5KTsgYm94LXNoYWRvdzogMCAwIDAgM3B4IHZhcigtLXByaW1hcnktNTApOwp9CgouY2hlY2tib3ggeyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDhweDsgZm9udC1zaXplOiAwLjg1cmVtOyBjdXJzb3I6IHBvaW50ZXI7IGNvbG9yOiB2YXIoLS10ZXh0Mik7IH0KLmNoZWNrYm94IGlucHV0IHsgd2lkdGg6IDE2cHg7IGhlaWdodDogMTZweDsgYWNjZW50LWNvbG9yOiB2YXIoLS1wcmltYXJ5KTsgfQoKLyogTW9kYWwgKi8KLm1vZGFsLW92ZXJsYXkgewogIGRpc3BsYXk6IG5vbmU7IHBvc2l0aW9uOiBmaXhlZDsgaW5zZXQ6IDA7IGJhY2tncm91bmQ6IHJnYmEoMTUsMjMsNDIsMC41KTsKICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoNHB4KTsgei1pbmRleDogMjAwOyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsKfQoubW9kYWwtb3ZlcmxheS5vcGVuIHsgZGlzcGxheTogZmxleDsgfQoubW9kYWwgewogIGJhY2tncm91bmQ6IHZhcigtLWNhcmQpOyBib3JkZXItcmFkaXVzOiB2YXIoLS1yYWRpdXMpOyB3aWR0aDogOTAlOyBtYXgtd2lkdGg6IDUwMHB4OwogIG1heC1oZWlnaHQ6IDg1dmg7IG92ZXJmbG93LXk6IGF1dG87IGJveC1zaGFkb3c6IDAgMjBweCA2MHB4IHJnYmEoMCwwLDAsMC4xNSk7CiAgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsKfQoubW9kYWwtaGVhZGVyIHsKICBkaXNwbGF5OiBmbGV4OyBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IGFsaWduLWl0ZW1zOiBjZW50ZXI7CiAgcGFkZGluZzogMThweCAyNHB4OyBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsKfQoubW9kYWwtaGVhZGVyIGgzIHsgZm9udC1zaXplOiAxcmVtOyBmb250LXdlaWdodDogNjAwOyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDhweDsgfQoubW9kYWwtY2xvc2UgewogIGJhY2tncm91bmQ6IG5vbmU7IGJvcmRlcjogbm9uZTsgY3Vyc29yOiBwb2ludGVyOyBjb2xvcjogdmFyKC0tdGV4dDMpOwogIHBhZGRpbmc6IDRweDsgYm9yZGVyLXJhZGl1czogNnB4OyB0cmFuc2l0aW9uOiBhbGwgdmFyKC0tdHJhbnNpdGlvbik7CiAgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsganVzdGlmeS1jb250ZW50OiBjZW50ZXI7Cn0KLm1vZGFsLWNsb3NlOmhvdmVyIHsgYmFja2dyb3VuZDogdmFyKC0tYmcpOyBjb2xvcjogdmFyKC0tdGV4dCk7IH0KLm1vZGFsLWNsb3NlIHN2ZyB7IHdpZHRoOiAxOHB4OyBoZWlnaHQ6IDE4cHg7IH0KLm1vZGFsLWJvZHkgeyBwYWRkaW5nOiAyNHB4OyB9Ci5tb2RhbC1mb290ZXIgeyBkaXNwbGF5OiBmbGV4OyBnYXA6IDhweDsganVzdGlmeS1jb250ZW50OiBmbGV4LWVuZDsgcGFkZGluZzogMCAyNHB4IDIwcHg7IH0KCi8qIEF1dGggRmxvdyAqLwoubW9kYWwtYXV0aCB7IG1heC13aWR0aDogNDYwcHg7IH0KLmF1dGgtZmxvdyB7IG1hcmdpbi1ib3R0b206IDE2cHg7IH0KLnN0ZXAgewogIHBhZGRpbmc6IDEwcHggMTRweDsgZm9udC1zaXplOiAwLjg1cmVtOyBjb2xvcjogdmFyKC0tdGV4dDIpOwogIGJvcmRlci1sZWZ0OiAzcHggc29saWQgdmFyKC0tcHJpbWFyeSk7IG1hcmdpbi1ib3R0b206IDhweDsKICBiYWNrZ3JvdW5kOiB2YXIoLS1wcmltYXJ5LWxpZ2h0KTsgYm9yZGVyLXJhZGl1czogMCB2YXIoLS1yYWRpdXMteHMpIHZhcigtLXJhZGl1cy14cykgMDsKfQouc3Bpbm5lciB7CiAgd2lkdGg6IDMycHg7IGhlaWdodDogMzJweDsgYm9yZGVyOiAzcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXRvcC1jb2xvcjogdmFyKC0tcHJpbWFyeSk7CiAgYm9yZGVyLXJhZGl1czogNTAlOyBhbmltYXRpb246IHNwaW4gMC44cyBsaW5lYXIgaW5maW5pdGU7IG1hcmdpbjogMjBweCBhdXRvOwp9CkBrZXlmcmFtZXMgc3BpbiB7IHRvIHsgdHJhbnNmb3JtOiByb3RhdGUoMzYwZGVnKTsgfSB9CgovKiBBdXRoIFVSTCAqLwouYXV0aC11cmwtYm94IHsKICBkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBnYXA6IDEwcHg7IHBhZGRpbmc6IDE0cHg7CiAgYmFja2dyb3VuZDogdmFyKC0tYmcpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiB2YXIoLS1yYWRpdXMtc20pOwp9Ci5hdXRoLXVybC1ib3ggbGFiZWwgeyBmb250LXNpemU6IDAuOHJlbTsgZm9udC13ZWlnaHQ6IDYwMDsgY29sb3I6IHZhcigtLXRleHQyKTsgfQouYXV0aC11cmwtaW5wdXQtcm93IHsgZGlzcGxheTogZmxleDsgZ2FwOiA4cHg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IH0KLmF1dGgtdXJsLWlucHV0IHsKICBmbGV4OiAxOyBwYWRkaW5nOiA4cHggMTBweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogdmFyKC0tcmFkaXVzLXhzKTsKICBmb250LWZhbWlseTogJ1NGIE1vbm8nLCAnRmlyYSBDb2RlJywgbW9ub3NwYWNlOyBmb250LXNpemU6IDAuOHJlbTsgYmFja2dyb3VuZDogdmFyKC0tY2FyZCk7CiAgY29sb3I6IHZhcigtLXRleHQpOyBtaW4td2lkdGg6IDA7Cn0KLmF1dGgtdXJsLWlucHV0OmZvY3VzIHsgb3V0bGluZTogbm9uZTsgYm9yZGVyLWNvbG9yOiB2YXIoLS1wcmltYXJ5KTsgfQoKLnNzaC10dW5uZWwtYm94IHsKICBwYWRkaW5nOiAxNHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS13YXJuaW5nLWJnKTsgYm9yZGVyOiAxcHggc29saWQgI2ZkZTY4YTsKICBib3JkZXItcmFkaXVzOiB2YXIoLS1yYWRpdXMtc20pOyBtYXJnaW4tYm90dG9tOiA4cHg7Cn0KLnNzaC10dW5uZWwtbGFiZWwgeyBmb250LXNpemU6IDAuOHJlbTsgZm9udC13ZWlnaHQ6IDYwMDsgY29sb3I6ICM5MjQwMGU7IG1hcmdpbi1ib3R0b206IDhweDsgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA2cHg7IH0KLnNzaC10dW5uZWwtbGFiZWwgc3ZnIHsgd2lkdGg6IDE0cHg7IGhlaWdodDogMTRweDsgfQouc3NoLXR1bm5lbC1jbWQgewogIGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkKTsKICBwYWRkaW5nOiA4cHggMTJweDsgYm9yZGVyLXJhZGl1czogdmFyKC0tcmFkaXVzLXhzKTsgYm9yZGVyOiAxcHggc29saWQgI2ZkZTY4YTsKfQouc3NoLXR1bm5lbC1jbWQgY29kZSB7CiAgZmxleDogMTsgZm9udC1mYW1pbHk6ICdTRiBNb25vJywgJ0ZpcmEgQ29kZScsIG1vbm9zcGFjZTsgZm9udC1zaXplOiAwLjhyZW07CiAgY29sb3I6IHZhcigtLXRleHQpOyB3b3JkLWJyZWFrOiBicmVhay1hbGw7IHVzZXItc2VsZWN0OiBhbGw7Cn0KCi8qIFN5bmMgUGFpciBNb2RhbCAqLwouc3luYy1wYWlyLXByZWZpeCB7CiAgcGFkZGluZzogOXB4IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWJnKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsKICBib3JkZXItcmlnaHQ6IG5vbmU7IGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy14cykgMCAwIHZhcigtLXJhZGl1cy14cyk7CiAgZm9udC1zaXplOiAwLjgycmVtOyBmb250LXdlaWdodDogNjAwOyBjb2xvcjogdmFyKC0tdGV4dDIpOwogIHdoaXRlLXNwYWNlOiBub3dyYXA7IGZvbnQtZmFtaWx5OiAnU0YgTW9ubycsICdGaXJhIENvZGUnLCBtb25vc3BhY2U7Cn0KLnN5bmMtcGFpci1kZXN0LWlucHV0IHsKICBmbGV4OiAxOyBwYWRkaW5nOiA5cHggMTJweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsKICBib3JkZXItcmFkaXVzOiAwIHZhcigtLXJhZGl1cy14cykgdmFyKC0tcmFkaXVzLXhzKSAwOwogIGZvbnQtc2l6ZTogMC44NXJlbTsgZm9udC1mYW1pbHk6ICdTRiBNb25vJywgJ0ZpcmEgQ29kZScsIG1vbm9zcGFjZTsKfQouc3luYy1wYWlyLWRlc3QtaW5wdXQ6Zm9jdXMgeyBvdXRsaW5lOiBub25lOyBib3JkZXItY29sb3I6IHZhcigtLXByaW1hcnkpOyBib3gtc2hhZG93OiAwIDAgMCAzcHggdmFyKC0tcHJpbWFyeS01MCk7IH0KCi8qIEpvYnMgKi8KLmpvYi1jYXJkIHsKICBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogdmFyKC0tcmFkaXVzKTsKICBwYWRkaW5nOiAxNnB4IDIwcHg7IG1hcmdpbi1ib3R0b206IDEwcHg7Cn0KLmpvYi1jYXJkLXRvcCB7IGRpc3BsYXk6IGZsZXg7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgYWxpZ24taXRlbXM6IGNlbnRlcjsgbWFyZ2luLWJvdHRvbTogOHB4OyB9Ci5qb2ItY2FyZC1uYW1lIHsgZm9udC13ZWlnaHQ6IDYwMDsgZm9udC1zaXplOiAwLjlyZW07IGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyB9Ci5qb2Itc3RhdHVzIHsKICBwYWRkaW5nOiAzcHggMTBweDsgYm9yZGVyLXJhZGl1czogNnB4OyBmb250LXNpemU6IDAuNzJyZW07IGZvbnQtd2VpZ2h0OiA2MDA7IHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7CiAgbGV0dGVyLXNwYWNpbmc6IDAuMDJlbTsKfQouam9iLXN0YXR1cy5ydW5uaW5nIHsgYmFja2dyb3VuZDogI2RiZWFmZTsgY29sb3I6ICMxZTQwYWY7IH0KLmpvYi1zdGF0dXMuY29tcGxldGVkIHsgYmFja2dyb3VuZDogI2RjZmNlNzsgY29sb3I6ICMxNjY1MzQ7IH0KLmpvYi1zdGF0dXMuZmFpbGVkIHsgYmFja2dyb3VuZDogI2ZlZTJlMjsgY29sb3I6ICM5OTFiMWI7IH0KLmpvYi1zdGF0dXMuc3RvcHBlZCB7IGJhY2tncm91bmQ6ICNmZWYzYzc7IGNvbG9yOiAjOTI0MDBlOyB9Ci5qb2ItY2FyZC1wYXRocyB7CiAgZm9udC1mYW1pbHk6ICdTRiBNb25vJywgJ0ZpcmEgQ29kZScsIG1vbm9zcGFjZTsgZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS10ZXh0Myk7CiAgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7IG1hcmdpbi1ib3R0b206IDZweDsKfQouam9iLWNhcmQtbWV0YSB7IGZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLXRleHQzKTsgfQouam9iLWxvZyB7CiAgbWFyZ2luLXRvcDogMTBweDsgYmFja2dyb3VuZDogIzBmMTcyYTsgY29sb3I6ICNhNWYzZmM7IGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy1zbSk7CiAgcGFkZGluZzogMTJweCAxNHB4OyBtYXgtaGVpZ2h0OiAyMDBweDsgb3ZlcmZsb3cteTogYXV0bzsKfQouam9iLWxvZyBwcmUgewogIG1hcmdpbjogMDsgZm9udC1mYW1pbHk6ICdTRiBNb25vJywgJ0ZpcmEgQ29kZScsIG1vbm9zcGFjZTsgZm9udC1zaXplOiAwLjc4cmVtOwogIHdoaXRlLXNwYWNlOiBwcmUtd3JhcDsgd29yZC1icmVhazogYnJlYWstYWxsOyBsaW5lLWhlaWdodDogMS41Owp9CgovKiBUb2FzdCAqLwoudG9hc3QgewogIHBvc2l0aW9uOiBmaXhlZDsgYm90dG9tOiAyNHB4OyByaWdodDogMjRweDsgcGFkZGluZzogMTJweCAyMHB4OwogIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy1zbSk7IGNvbG9yOiB3aGl0ZTsgZm9udC1zaXplOiAwLjg1cmVtOyBmb250LXdlaWdodDogNTAwOwogIHotaW5kZXg6IDEwMDA7IHRyYW5zZm9ybTogdHJhbnNsYXRlWSgxMDBweCk7IG9wYWNpdHk6IDA7IHRyYW5zaXRpb246IGFsbCAwLjI1cyBlYXNlOwogIGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4Owp9Ci50b2FzdCBzdmcgeyB3aWR0aDogMTZweDsgaGVpZ2h0OiAxNnB4OyBmbGV4LXNocmluazogMDsgfQoudG9hc3Quc2hvdyB7IHRyYW5zZm9ybTogdHJhbnNsYXRlWSgwKTsgb3BhY2l0eTogMTsgfQoudG9hc3Quc3VjY2VzcyB7IGJhY2tncm91bmQ6IHZhcigtLXN1Y2Nlc3MpOyB9Ci50b2FzdC5lcnJvciB7IGJhY2tncm91bmQ6IHZhcigtLWRhbmdlcik7IH0KLnRvYXN0LmluZm8geyBiYWNrZ3JvdW5kOiB2YXIoLS1wcmltYXJ5KTsgfQoKLyogQ3JvbiBJbmZvICovCi5jcm9uLWluZm8tYm94IHsKICBtYXJnaW4tdG9wOiAxMnB4OyBiYWNrZ3JvdW5kOiAjMGYxNzJhOyBjb2xvcjogI2E1ZjNmYzsKICBib3JkZXItcmFkaXVzOiB2YXIoLS1yYWRpdXMtc20pOyBwYWRkaW5nOiAxNHB4OwogIGZvbnQtc2l6ZTogMC44cmVtOyBvdmVyZmxvdy14OiBhdXRvOyB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7CiAgZm9udC1mYW1pbHk6ICdTRiBNb25vJywgJ0ZpcmEgQ29kZScsIG1vbm9zcGFjZTsKfQoKLyogUmVzcG9uc2l2ZSAqLwpAbWVkaWEgKG1heC13aWR0aDogNzY4cHgpIHsKICAuYXBwLWhlYWRlciB7IHBhZGRpbmc6IDAgMTZweDsgfQogIC5oZWFkZXItcmlnaHQgeyBnYXA6IDRweDsgfQogIC5idG4taWNvbi1oZWFkZXIgeyBwYWRkaW5nOiA2cHggMTBweDsgZm9udC1zaXplOiAwLjc4cmVtOyB9CiAgLmJ0bi1pY29uLWhlYWRlciAuYnRuLWxhYmVsIHsgZGlzcGxheTogbm9uZTsgfQogIC5jb250ZW50IHsgcGFkZGluZzogMjBweCAxMnB4OyB9CiAgLnJlbW90ZS1jYXJkLWhlYWRlciB7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0OyBwYWRkaW5nOiAxNnB4OyB9CiAgLnJlbW90ZS1jYXJkLWFjdGlvbnMgeyB3aWR0aDogMTAwJTsgfQogIC5zeW5jLXBhaXJzLWFyZWEgeyBwYWRkaW5nOiAwIDE2cHggMTRweDsgfQogIC5zeW5jLXBhaXItcm93IHsgZmxleC13cmFwOiB3cmFwOyB9CiAgLm1vZGFsIHsgbWF4LXdpZHRoOiA5NSU7IH0KfQo='
printf '%s' "$B64_SERVER" | base64 -d > "$INSTALL_DIR/server.js"
printf '%s' "$B64_HTML" | base64 -d > "$INSTALL_DIR/public/index.html"
printf '%s' "$B64_JS" | base64 -d > "$INSTALL_DIR/public/js/app.js"
printf '%s' "$B64_CSS" | base64 -d > "$INSTALL_DIR/public/css/style.css"
echo "  ファイルデコード完了"

cat > "$INSTALL_DIR/package.json" << 'PKGEND'
{
  "name": "easyrclone",
  "version": "10.0.0",
  "description": "EasyRclone - Cloud Sync Web GUI",
  "main": "server.js",
  "scripts": { "start": "node server.js" },
  "dependencies": {
    "express": "^4.18.2",
    "ws": "^8.16.0"
  }
}
PKGEND
echo "  package.json 作成完了"
echo ""

echo "[5/6] npm 依存関係インストール..."
cd "$INSTALL_DIR"
npm install --production 2>&1 | tail -3
echo ""

if ss -tlnp 2>/dev/null | grep -q ":${APP_PORT} " && ! pgrep -f "node server.js" >/dev/null 2>&1; then
  echo "エラー: ポート${APP_PORT}は既に使用されています"
  echo "  別のポートを指定してください:  EASYRCLONE_PORT=3349 bash $0"
  exit 1
fi

echo "[6/6] systemd サービス作成..."
cat > /etc/systemd/system/easyrclone.service << SVCEOF
[Unit]
Description=EasyRclone Web GUI
After=network.target

[Service]
Type=simple
WorkingDirectory=$INSTALL_DIR
ExecStart=$(which node) server.js
Restart=always
RestartSec=3
Environment=PORT=$APP_PORT
Environment=TZ=Asia/Tokyo

[Install]
WantedBy=multi-user.target
SVCEOF

systemctl daemon-reload
systemctl enable easyrclone
systemctl restart easyrclone
echo "  サービス起動完了"
echo ""

echo "========================================="
echo "  インストール完了!"
echo "========================================="
echo ""
echo ""
if [ -n "$TS_IP" ]; then
  echo "  Web UI : http://${TS_IP}:${APP_PORT}"
fi
if [ -n "$TS_HOSTNAME" ]; then
  echo "  Web UI : http://${TS_HOSTNAME%%.*}:${APP_PORT}  (MagicDNS)"
fi
echo "  Web UI (local) : http://localhost:$APP_PORT"
echo ""
echo "  サービス:  systemctl [start|stop|restart|status] easyrclone"
echo "  設定ファイル: $INSTALL_DIR/config/rclone.conf"
echo "  ログ:      journalctl -u easyrclone -f"
echo "  タイムゾーン: $(date)"
echo ""

アンインストール

一時SSHパスワード認証を「一時SSH設定」機能で有効にしたことがある場合は、先に忘れずにUIの「一時SSH削除」ボタンを押しておいてください(アンインストール後は/api/ssh/teardownが呼べなくなるため、sshd_configの変更が残ります)。
スクリプトの中身は systemd停止・無効化 → crontabの同期スケジュール削除 → /opt/easyrclone 削除、の3ステップです。rclone自体やNode.jsは他アプリと共用の可能性があるため削除していません。

#!/bin/bash
set -e

INSTALL_DIR="/opt/easyrclone"

echo "========================================="
echo "  EasyRclone アンインストーラー"
echo "========================================="
echo ""

if [ "$(id -u)" -ne 0 ]; then
  echo "エラー: root で実行してください"
  echo " sudo bash $0"
  exit 1
fi

echo "[1/3] systemd サービス停止・無効化..."
if systemctl list-unit-files | grep -q '^easyrclone.service'; then
  systemctl stop easyrclone 2>/dev/null || true
  systemctl disable easyrclone 2>/dev/null || true
  rm -f /etc/systemd/system/easyrclone.service
  systemctl daemon-reload
  echo "  停止・無効化・unitファイル削除完了"
else
  echo "  easyrclone.service は見つかりませんでした(スキップ)"
fi
echo ""

echo "[2/3] crontab のスケジュールエントリ削除..."
if crontab -l 2>/dev/null | grep -q -e 'cron-sync.sh' -e '# easyrclone-schedule'; then
  crontab -l 2>/dev/null | grep -v -e 'cron-sync.sh' -e '# easyrclone-schedule' > /tmp/easyrclone_crontab_tmp || true
  crontab /tmp/easyrclone_crontab_tmp
  rm -f /tmp/easyrclone_crontab_tmp
  echo "  crontab エントリ削除完了"
else
  echo "  crontab にエントリは見つかりませんでした(スキップ)"
fi
echo ""

echo "[3/3] ファイル削除..."
if [ -d "$INSTALL_DIR" ]; then
  rm -rf "$INSTALL_DIR"
  echo "  $INSTALL_DIR を削除しました"
else
  echo "  $INSTALL_DIR は見つかりませんでした(スキップ)"
fi
echo ""

echo "========================================="
echo "  アンインストール完了"
echo "========================================="
echo ""
echo "  ※ 一時SSH設定(パスワード認証有効化)を使ったことがある場合は、"
echo "    /etc/ssh/sshd_config.d/60-cloudimg-settings.conf を確認し、"
echo "    必要に応じて PasswordAuthentication / KbdInteractiveAuthentication を"
echo "    元に戻して 'systemctl restart sshd' を実行してください。"
echo ""
タイトルとURLをコピーしました