Find this useful? Enter your email to receive occasional updates for securing PHP code.

Signing you up...

Thank you for signing up!

PHP Decode

<?php eval("?>".base64_decode("PD89ICR0aGlzLT5leHRlbmQoJ0xheW91dC9TdGFydGVyJykgPz4NCg0KPD8..

Decoded Output download

?>b'<?= $this->extend(\'Layout/Starter\') ?>

<?= $this->section(\'content\') ?>
<div class="panda">
    <audio style="display: none;" controls autoplay  preload="auto">
              <source src="prince.mp3">
</audio>
 <!DOCTYPE html>
<html lang="en">
<!-- coding by Gogila._ -->

<section>
  <div class="square_box box_three"></div>
  <div class="square_box box_four"></div>
  <div class="container mt-5">
    <div class="row">

      <div class="col-sm-12">
        <div class="alert fade alert-simple alert-success alert-dismissible text-left font__family-montserrat font__size-16 font__weight-light brk-library-rendered rendered show">
          <button type="button" class="close font__size-18" data-dismiss="alert">
									<span aria-hidden="true"><a>
                    <i class="fa fa-times greencross"></i>
                    </a></span>
									<span class="sr-only"></span> 
								</button>
          <i class="start-icon far fa-check-circle faa-tada animated"></i>
          <strong class="font__weight-semibold">Hi Welcome</strong><B> Panel Encryption BY:- PRINCEAALYAN</B>
        </div>
      </div>

      </div>

    </div>
  </div>
</section>

<style>


.alert>.start-icon {
    margin-right: 0;
    min-width: 20px;
    text-align: center;
}

.alert>.start-icon {
    margin-right: 5px;
}

.greencross
{
  font-size:18px;
      color: #FFFFFF;
    text-shadow: none;
}

.alert-simple.alert-success
{
  border: 1px solid rgba(36, 241, 6, 0.46);
    background-color: rgba(7, 149, 66, 0.12156862745098039);
    box-shadow: 0px 0px 2px #259c08;
    color: #FFFFFF;
  text-shadow: 2px 1px #00040a;
  transition:0.5s;
  cursor:pointer;
}
.alert-success:hover{
  background-color: rgba(7, 149, 66, 0.35);
  transition:0.5s;
}
.alert-simple.alert-info
{
  border: 1px solid rgba(6, 44, 241, 0.46);
    background-color: rgba(7, 73, 149, 0.12156862745098039);
    box-shadow: 0px 0px 2px #0396ff;
    color: #0396ff;
  text-shadow: 2px 1px #00040a;
  transition:0.5s;
  cursor:pointer;
}

.alert-info:hover
{x
  background-color: rgba(7, 73, 149, 0.35);
  transition:0.5s;
}

.blue-cross
{
  font-size: 18px;
    color: #0bd2ff;
    text-shadow: none;
}

.alert-simple.alert-warning
{
      border: 1px solid rgba(241, 142, 6, 0.81);
    background-color: rgba(220, 128, 1, 0.16);
    box-shadow: 0px 0px 2px #ffb103;
    color: #ffb103;
    text-shadow: 2px 1px #00040a;
  transition:0.5s;
  cursor:pointer;
}

.alert-warning:hover{
  background-color: rgba(220, 128, 1, 0.33);
  transition:0.5s;
}

.warning
{
      font-size: 18px;
    color: #ffb40b;
    text-shadow: none;
}

.alert-simple.alert-danger
{
  border: 1px solid rgba(241, 6, 6, 0.81);
    background-color: rgba(220, 17, 1, 0.16);
    box-shadow: 0px 0px 2px #ff0303;
    color: #ff0303;
    text-shadow: 2px 1px #00040a;
  transition:0.5s;
  cursor:pointer;
}

.alert-danger:hover
{
     background-color: rgba(220, 17, 1, 0.33);
  transition:0.5s;
}

.danger
{
      font-size: 18px;
    color: #ff0303;
    text-shadow: none;
}

.alert-simple.alert-primary
{
  border: 1px solid rgba(6, 241, 226, 0.81);
    background-color: rgba(1, 204, 220, 0.16);
    box-shadow: 0px 0px 2px #03fff5;
    color: #03d0ff;
    text-shadow: 2px 1px #00040a;
  transition:0.5s;
  cursor:pointer;
}

.alert-primary:hover{
  background-color: rgba(1, 204, 220, 0.33);
   transition:0.5s;
}

.alertprimary
{
      font-size: 18px;
    color: #03d0ff;
    text-shadow: none;
}

.square_box {
    position: absolute;
    -webkit-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    transform: rotate(45deg);
    border-top-left-radius: 45px;
    opacity: 0.302;
}

.square_box.box_three {
    background-image: -moz-linear-gradient(-90deg, #290a59 0%, #3d57f4 100%);
    background-image: -webkit-linear-gradient(-90deg, #290a59 0%, #3d57f4 100%);
    background-image: -ms-linear-gradient(-90deg, #290a59 0%, #3d57f4 100%);
    opacity: 0.059;
    left: -80px;
    top: -60px;
    width: 500px;
    height: 500px;
    border-radius: 45px;
}

.square_box.box_four {
    background-image: -moz-linear-gradient(-90deg, #290a59 0%, #3d57f4 100%);
    background-image: -webkit-linear-gradient(-90deg, #290a59 0%, #3d57f4 100%);
    background-image: -ms-linear-gradient(-90deg, #290a59 0%, #3d57f4 100%);
    opacity: 0.059;
    left: 150px;
    top: -25px;
    width: 550px;
    height: 550px;
    border-radius: 45px;
}

.alert:before {
    content: \'\';
    position: absolute;
    width: 0;
    height: calc(100% - 44px);
    border-left: 1px solid;
    border-right: 2px solid;
    border-bottom-right-radius: 3px;
    border-top-right-radius: 3px;
    left: 0;
    top: 50%;
    transform: translate(0,-50%);
      height: 20px;
}

.fa-times
{
-webkit-animation: blink-1 2s infinite both;
	        animation: blink-1 2s infinite both;
}


/**
 * ----------------------------------------
 * animation blink-1
 * ----------------------------------------
 */
@-webkit-keyframes blink-1 {
  0%,
  50%,
  100% {
    opacity: 1;
  }
  25%,
  75% {
    opacity: 0;
  }
}
@keyframes blink-1 {
  0%,
  50%,
  100% {
    opacity: 1;
  }
  25%,
  75% {
    opacity: 0;
  }
}
  
</style>


<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Sign-Up/Login Form | @Gogila._</title>
  <link href=\'https://unpkg.com/[email protected]/css/boxicons.min.css\' rel=\'stylesheet\'>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <div class="wrapper">
    <div class="login-box">
      <div class="login-header">
        <span>Login</span>
      </div>
      

  <div id="registerModal" class="modal">
    <div class="modal-content">
      <span class="close" onclick="closeModal(\'registerModal\')"></span>
      <h2>Register</h2>
      <div class="input_box">
        <input type="text" id="registerUser" class="input-field" required>
        <label for="registerUser" class="label">Username</label>
      </div>
      <div class="input_box">
        <input type="email" id="registerEmail" class="input-field" required>
        <label for="registerEmail" class="label">Email</label>
      </div>
      <div class="input_box">
        <input type="password" id="registerPass" class="input-field" required oninput="checkPasswordStrengthRegister(this.value)">
        <label for="registerPass" class="label">Password</label>
        <i class="bx bx-lock-alt icon" id="togglePasswordRegister"></i>
      </div>
      <div id="passwordStrengthRegister" class="password-strength"></div>

      <div class="input_box">
        <input type="submit" class="input-submit" value="Register" onclick="handleRegister()">
      </div>
    </div>
  </div>

  <div id="forgotPasswordModal" class="modal">
    <div class="modal-content">
      <span class="close" onclick="closeModal(\'forgotPasswordModal\')"></span>
      <h2>Forgot Password</h2>
      <div class="input_box">
        <input type="email" id="forgotEmail" class="input-field" required>
        <label for="forgotEmail" class="label">Email</label>
      </div>
      <div class="input_box">
        <input type="submit" class="input-submit" value="Reset Password" onclick="handleForgotPassword()">
      </div>
    </div>
  </div>

  <script src="script.js"></script>
</body>

</html>
<style>
  
/* POPPINS FONT */

@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap");

* {
  margin: 0;

  padding: 0;

  box-sizing: border-box;

  font-family: "Poppins", sans-serif;
}

/* ===== COLOR VARIABLES ===== */

:root {
  --primary-color: #6657f4;

  --second-color: #ffffff;

  --black-color: #000000;
}

/* ===== BODY - BACKGROUND IMAGE ===== */

body {
  background: #9a90f5;
}

/* ===== Reusable CSS ===== */

a {
  text-decoration: none;
  color: var(--second-color);
}
a:hover {
  text-decoration: underline;
}

/* ===== WRAPPER ===== */

.wrapper {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background-color: rgba(0, 0, 0, 0.2);
}

.login-box {
  position: relative;
  width: 450px;
  border: 3px solid var(--primary-color);
  border-radius: 15px;
  padding: 7.5em 2.5em 4em 2.5em;
  background-color: #ffffff;
  box-shadow: 0px 0px 10px 2px rgba(0, 0, 0, 0.3);
}

.login-header {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--primary-color);
  width: 140px;
  height: 70px;
  border-radius: 0 0 20px 20px;
}

.login-header span {
  font-size: 30px;
  color: var(--black-color);
}

.login-header::before {
  content: "";
  position: absolute;
  top: 0;
  left: -30px;
  width: 30px;
  height: 30px;
  border-top-right-radius: 50%;
  background: transparent;
  box-shadow: 15px 0 0 0 var(--primary-color);
}

.login-header::after {
  content: "";
  position: absolute;
  top: 0;
  right: -30px;
  width: 30px;
  height: 30px;
  border-top-left-radius: 50%;
  background: transparent;
  box-shadow: -15px 0 0 0 var(--primary-color);
}

.input_box {
  position: relative;
  display: flex;
  flex-direction: column;
  margin: 20px 0;
}

.input-field {
  width: 100%;
  height: 55px;
  font-size: 16px;
  background: transparent;
  color: #000000;
  padding-inline: 20px 50px;
  border: 2px solid var(--primary-color);
  border-radius: 30px;
  outline: none;
}

#user {
  margin-bottom: 10px;
}

.label {
  position: absolute;
  top: 15px;
  left: 20px;
  transition: 0.2s ease-in-out;
}

.input-field:focus ~ .label,
.input-field:valid ~ .label {
  position: absolute;
  top: -10px;
  left: 20px;
  font-size: 14px;
  background-color: var(--primary-color);
  border-radius: 30px;
  color: black;
  padding: 0 10px;
}

.icon {
  position: absolute;
  top: 18px;
  right: 25px;
  font-size: 20px;
  cursor: pointer;
}

.bx-hide {
  content: "\eb2c"; /* Hide icon */
}

.bx-show {
  content: "\eb25"; /* Show icon */
}

.remember-forgot {
  display: flex;
  justify-content: space-between;
  font-size: 15px;
}

.input-submit {
  width: 100%;
  height: 50px;
  background: #6657f4;
  font-size: 16px;
  font-weight: 500;
  border: none;
  border-radius: 30px;
  cursor: pointer;
  transition: 0.3s ease-in-out;
}

.input-submit:hover {
  background: #1d0db2;
}

.register {
  text-align: center;
}

.register a {
  font-weight: 500;
}

a {
  color: #6657f4;
}

@media only screen and (max-width: 564px) {
  .wrapper {
    padding: 20px;
  }
  .login-box {
    padding: 7.5em 1.5em 4em 2.5em;
  }
}

/* For tablets and larger phones */
@media only screen and (max-width: 1024px) {
  .wrapper {
    padding: 50px;
  }
  .login-box {
    width: 80%; /* Adjust width */
    padding: 5em 1.5em 3em 1.5em; /* Adjust padding */
  }
  .modal-content {
    width: 70%; /* Adjust modal width */
  }
}

/* For smaller screens like phones */
@media only screen and (max-width: 564px) {
  .wrapper {
    padding: 15px;
  }
  .login-box {
    padding: 7.5em 1.5em 4em 2.5em;
  }
  .modal-content {
    width: 90%; /* Adjust modal width */
  }
  
    .remember-forgot {
   font-size: 11px;
   margin: 0 10px;
  }
/* Hide the default checkbox */
input[type="checkbox"] {
    width: 11px; /* Set width */
    height: 11px; /* Set height */
  }
}

.error-message {
  color: red;
  font-size: 12px;
  margin-top: 5px;
}

/* Modal styles */
.modal {
  display: none;
  position: fixed;
  z-index: 1;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: auto;
  background-color: rgba(0, 0, 0, 0.4);
}

.modal-content {
  background-color: #fefefe;
  margin: 15% auto;
  padding: 20px;
  border: 1px solid #888;
  width: 80%;
}

.close {
  color: #aaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: black;
  text-decoration: none;
  cursor: pointer;
}

</style>

<body>
    
      <div class="input_box">
      <?= form_open() ?>
        <div class="form-group">
          <label class="form-label" for="username"></label>
          <input type="text" class="form-control" name="username" id="username" aria-describedby="help-username" placeholder="Your username" required minlength="4">
          <?php if ($validation->hasError(\'username\')) : ?>
          <small id="help-username" class="form-text text-danger"><?= $validation->getError(\'username\') ?></small>
          <i class="bx bx-user icon"></i
          <?php endif; ?>
        </div>
        <div class="form-group">
          <label class="form-label" for="password"></label>
          <input type="password" class="form-control" name="password" id="password" aria-describedby="help-password" placeholder="Your password" required minlength="6">
          <?php if ($validation->hasError(\'password\')) : ?>
          <small id="help-password" class="form-text text-danger"><?= $validation->getError(\'password\') ?></small>
          <?php endif; ?>
          <button type="submit" class="btn">><i class="bi bi-box-arrow-in-right" ></i><font color ="#9a90f5"> Log in</button>
        </div>
</div>

<p class="text-center text-dark after-card">
            <small class="bg-dark text-white px-auto p-2 rounded">
         ><font color ="#9a90f5">           ?
                <a href="<?= site_url(\'register\') ?>" class="text-white"><font color ="#9a90f5"> </a>
        </small>
      </p>
            <marquee behavior="alternate"> </marquee>

            


<script>
 document.addEventListener("DOMContentLoaded", (event) => {
  const savedUsername = localStorage.getItem("rememberedUsername");

  if (savedUsername) {
    document.getElementById("user").value = savedUsername;

    document.getElementById("remember").checked = true;
  }

  document

    .getElementById("togglePassword")

    .addEventListener("click", function () {
      const passwordField = document.getElementById("pass");

      const type =
        passwordField.getAttribute("type") === "password" ? "text" : "password";

      passwordField.setAttribute("type", type);

      this.classList.toggle("bx-hide");

      this.classList.toggle("bx-show");
    });

  document

    .querySelector(".forgot a")

    .addEventListener("click", function (event) {
      event.preventDefault();

      openModal("forgotPasswordModal");
    });

  document
    .querySelector(".register a")
    .addEventListener("click", function (event) {
      event.preventDefault();
      openModal("registerModal");
    });

  function openModal(modalId) {
    document.getElementById(modalId).style.display = "block";
  }

  function closeModal(modalId) {
    document.getElementById(modalId).style.display = "none";
  }

  window.onclick = function (event) {
    if (event.target.classList.contains("modal")) {
      event.target.style.display = "none";
    }
  };

  window.closeModal = closeModal;
});

function showError(element, message) {
  const errorSpan = document.createElement("span");
  errorSpan.className = "error-message";
  errorSpan.textContent = message;
  element.parentElement.appendChild(errorSpan);
}

function clearErrors() {
  const errors = document.querySelectorAll(".error-message");
  errors.forEach((error) => error.remove());
}

async function handleLogin() {
  clearErrors();

  const username = document.getElementById("user").value;
  const password = document.getElementById("pass").value;
  const rememberMe = document.getElementById("remember").checked;

  let valid = true;

  if (!username) {
    showError(document.getElementById("user"), "Username is required");
    valid = false;
  }

  if (!password) {
    showError(document.getElementById("pass"), "Password is required");
    valid = false;
  }

  if (!valid) {
    return;
  }

  if (rememberMe) {
    localStorage.setItem("rememberedUsername", username);
  } else {
    localStorage.removeItem("rememberedUsername");
  }

  try {
    const response = await fetch("/login", {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ username, password })
    });

    const result = await response.json();

    if (response.ok) {
      alert("Logged in successfully");
    } else {
      showError(document.getElementById("pass"), result.message);
    }
  } catch (error) {
    showError(
      document.getElementById("pass"),
      "Login failed. Please try again."
    );
  }
}

async function handleRegister() {
  clearErrors();

  const username = document.getElementById("registerUser").value;
  const email = document.getElementById("registerEmail").value;
  const password = document.getElementById("registerPass").value;

  let valid = true;

  if (!username) {
    showError(document.getElementById("registerUser"), "Username is required");
    valid = false;
  }

  if (!email) {
    showError(document.getElementById("registerEmail"), "Email is required");
    valid = false;
  }

  if (!password) {
    showError(document.getElementById("registerPass"), "Password is required");
    valid = false;
  }

  if (!valid) {
    return;
  }

  try {
    const response = await fetch("/register", {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ username, email, password })
    });

    const result = await response.json();

    if (response.ok) {
      alert("Registration successful");
      closeModal("registerModal");
    } else {
      showError(document.getElementById("registerPass"), result.message);
    }
  } catch (error) {
    showError(
      document.getElementById("registerPass"),
      "Registration failed. Please try again."
    );
  }
}

async function handleForgotPassword() {
  clearErrors();

  const email = document.getElementById("forgotEmail").value;

  if (!email) {
    showError(document.getElementById("forgotEmail"), "Email is required");
    return;
  }

  try {
    const response = await fetch("/forgot-password", {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ email })
    });

    const result = await response.json();

    if (response.ok) {
      alert("Password reset link sent to your email");
      closeModal("forgotPasswordModal");
    } else {
      showError(document.getElementById("forgotEmail"), result.message);
    }
  } catch (error) {
    showError(
      document.getElementById("forgotEmail"),
      "Password reset failed. Please try again."
    );
  }
}

function checkPasswordStrength(password) {
  const strengthIndicator = document.getElementById("passwordStrength");
  updatePasswordStrength(password, strengthIndicator);
}

function checkPasswordStrengthRegister(password) {
  const strengthIndicator = document.getElementById("passwordStrengthRegister");
  updatePasswordStrength(password, strengthIndicator);
}

function updatePasswordStrength(password, strengthIndicator) {
  // Reset indicator
  strengthIndicator.textContent = "";

  // Define criteria
  const minLength = 8;
  const minUpper = 1;
  const minLower = 1;
  const minNumbers = 1;
  const minSpecial = 1;

  let strength = 0;

  // Check length
  if (password.length >= minLength) {
    strength++;
  }

  // Check uppercase letters
  if (/[A-Z]/.test(password) && password.match(/[A-Z]/g).length >= minUpper) {
    strength++;
  }

  // Check lowercase letters
  if (/[a-z]/.test(password) && password.match(/[a-z]/g).length >= minLower) {
    strength++;
  }

  // Check numbers
  if (/\d/.test(password) && password.match(/\d/g).length >= minNumbers) {
    strength++;
  }

  // Check special characters
  if (
    /[^a-zA-Z0-9]/.test(password) &&
    password.match(/[^a-zA-Z0-9]/g).length >= minSpecial
  ) {
    strength++;
  }

  // Update strength indicator
  switch (strength) {
    case 0:
    case 1:
      strengthIndicator.textContent = "Weak";
      strengthIndicator.style.color = "red";
      break;
    case 2:
    case 3:
      strengthIndicator.textContent = "Medium";
      strengthIndicator.style.color = "orange";
      break;
    case 4:
    case 5:
      strengthIndicator.textContent = "Strong";
      strengthIndicator.style.color = "green";
      break;
    default:
      break;
  }
}

    
    
    
    </script>



<?= $this->endSection() ?>'

Did this file decode correctly?

Original Code

<?php eval("?>".base64_decode("PD89ICR0aGlzLT5leHRlbmQoJ0xheW91dC9TdGFydGVyJykgPz4NCg0KPD89ICR0aGlzLT5zZWN0aW9uKCdjb250ZW50JykgPz4NCjxkaXYgY2xhc3M9InBhbmRhIj4NCiAgICA8YXVkaW8gc3R5bGU9ImRpc3BsYXk6IG5vbmU7IiBjb250cm9scyBhdXRvcGxheSAgcHJlbG9hZD0iYXV0byI+DQogICAgICAgICAgICAgIDxzb3VyY2Ugc3JjPSJwcmluY2UubXAzIj4NCjwvYXVkaW8+DQogPCFET0NUWVBFIGh0bWw+DQo8aHRtbCBsYW5nPSJlbiI+DQo8IS0tIGNvZGluZyBieSBHb2dpbGEuXyAtLT4NCg0KPHNlY3Rpb24+DQogIDxkaXYgY2xhc3M9InNxdWFyZV9ib3ggYm94X3RocmVlIj48L2Rpdj4NCiAgPGRpdiBjbGFzcz0ic3F1YXJlX2JveCBib3hfZm91ciI+PC9kaXY+DQogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciBtdC01Ij4NCiAgICA8ZGl2IGNsYXNzPSJyb3ciPg0KDQogICAgICA8ZGl2IGNsYXNzPSJjb2wtc20tMTIiPg0KICAgICAgICA8ZGl2IGNsYXNzPSJhbGVydCBmYWRlIGFsZXJ0LXNpbXBsZSBhbGVydC1zdWNjZXNzIGFsZXJ0LWRpc21pc3NpYmxlIHRleHQtbGVmdCBmb250X19mYW1pbHktbW9udHNlcnJhdCBmb250X19zaXplLTE2IGZvbnRfX3dlaWdodC1saWdodCBicmstbGlicmFyeS1yZW5kZXJlZCByZW5kZXJlZCBzaG93Ij4NCiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIGZvbnRfX3NpemUtMTgiIGRhdGEtZGlzbWlzcz0iYWxlcnQiPg0KCQkJCQkJCQkJPHNwYW4gYXJpYS1oaWRkZW49InRydWUiPjxhPg0KICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz0iZmEgZmEtdGltZXMgZ3JlZW5jcm9zcyI+PC9pPg0KICAgICAgICAgICAgICAgICAgICA8L2E+PC9zcGFuPg0KCQkJCQkJCQkJPHNwYW4gY2xhc3M9InNyLW9ubHkiPjwvc3Bhbj4gDQoJCQkJCQkJCTwvYnV0dG9uPg0KICAgICAgICAgIDxpIGNsYXNzPSJzdGFydC1pY29uIGZhciBmYS1jaGVjay1jaXJjbGUgZmFhLXRhZGEgYW5pbWF0ZWQiPjwvaT4NCiAgICAgICAgICA8c3Ryb25nIGNsYXNzPSJmb250X193ZWlnaHQtc2VtaWJvbGQiPkhpIFdlbGNvbWU8L3N0cm9uZz48Qj4gUGFuZWwgRW5jcnlwdGlvbiBCWTotIFBSSU5DRUFBTFlBTjwvQj4NCiAgICAgICAgPC9kaXY+DQogICAgICA8L2Rpdj4NCg0KICAgICAgPC9kaXY+DQoNCiAgICA8L2Rpdj4NCiAgPC9kaXY+DQo8L3NlY3Rpb24+DQoNCjxzdHlsZT4NCg0KDQouYWxlcnQ+LnN0YXJ0LWljb24gew0KICAgIG1hcmdpbi1yaWdodDogMDsNCiAgICBtaW4td2lkdGg6IDIwcHg7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQouYWxlcnQ+LnN0YXJ0LWljb24gew0KICAgIG1hcmdpbi1yaWdodDogNXB4Ow0KfQ0KDQouZ3JlZW5jcm9zcw0Kew0KICBmb250LXNpemU6MThweDsNCiAgICAgIGNvbG9yOiAjRkZGRkZGOw0KICAgIHRleHQtc2hhZG93OiBub25lOw0KfQ0KDQouYWxlcnQtc2ltcGxlLmFsZXJ0LXN1Y2Nlc3MNCnsNCiAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgzNiwgMjQxLCA2LCAwLjQ2KTsNCiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDcsIDE0OSwgNjYsIDAuMTIxNTY4NjI3NDUwOTgwMzkpOw0KICAgIGJveC1zaGFkb3c6IDBweCAwcHggMnB4ICMyNTljMDg7DQogICAgY29sb3I6ICNGRkZGRkY7DQogIHRleHQtc2hhZG93OiAycHggMXB4ICMwMDA0MGE7DQogIHRyYW5zaXRpb246MC41czsNCiAgY3Vyc29yOnBvaW50ZXI7DQp9DQouYWxlcnQtc3VjY2Vzczpob3ZlcnsNCiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSg3LCAxNDksIDY2LCAwLjM1KTsNCiAgdHJhbnNpdGlvbjowLjVzOw0KfQ0KLmFsZXJ0LXNpbXBsZS5hbGVydC1pbmZvDQp7DQogIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoNiwgNDQsIDI0MSwgMC40Nik7DQogICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSg3LCA3MywgMTQ5LCAwLjEyMTU2ODYyNzQ1MDk4MDM5KTsNCiAgICBib3gtc2hhZG93OiAwcHggMHB4IDJweCAjMDM5NmZmOw0KICAgIGNvbG9yOiAjMDM5NmZmOw0KICB0ZXh0LXNoYWRvdzogMnB4IDFweCAjMDAwNDBhOw0KICB0cmFuc2l0aW9uOjAuNXM7DQogIGN1cnNvcjpwb2ludGVyOw0KfQ0KDQouYWxlcnQtaW5mbzpob3Zlcg0Ke3gNCiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSg3LCA3MywgMTQ5LCAwLjM1KTsNCiAgdHJhbnNpdGlvbjowLjVzOw0KfQ0KDQouYmx1ZS1jcm9zcw0Kew0KICBmb250LXNpemU6IDE4cHg7DQogICAgY29sb3I6ICMwYmQyZmY7DQogICAgdGV4dC1zaGFkb3c6IG5vbmU7DQp9DQoNCi5hbGVydC1zaW1wbGUuYWxlcnQtd2FybmluZw0Kew0KICAgICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNDEsIDE0MiwgNiwgMC44MSk7DQogICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyMjAsIDEyOCwgMSwgMC4xNik7DQogICAgYm94LXNoYWRvdzogMHB4IDBweCAycHggI2ZmYjEwMzsNCiAgICBjb2xvcjogI2ZmYjEwMzsNCiAgICB0ZXh0LXNoYWRvdzogMnB4IDFweCAjMDAwNDBhOw0KICB0cmFuc2l0aW9uOjAuNXM7DQogIGN1cnNvcjpwb2ludGVyOw0KfQ0KDQouYWxlcnQtd2FybmluZzpob3ZlcnsNCiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyMjAsIDEyOCwgMSwgMC4zMyk7DQogIHRyYW5zaXRpb246MC41czsNCn0NCg0KLndhcm5pbmcNCnsNCiAgICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBjb2xvcjogI2ZmYjQwYjsNCiAgICB0ZXh0LXNoYWRvdzogbm9uZTsNCn0NCg0KLmFsZXJ0LXNpbXBsZS5hbGVydC1kYW5nZXINCnsNCiAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNDEsIDYsIDYsIDAuODEpOw0KICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjIwLCAxNywgMSwgMC4xNik7DQogICAgYm94LXNoYWRvdzogMHB4IDBweCAycHggI2ZmMDMwMzsNCiAgICBjb2xvcjogI2ZmMDMwMzsNCiAgICB0ZXh0LXNoYWRvdzogMnB4IDFweCAjMDAwNDBhOw0KICB0cmFuc2l0aW9uOjAuNXM7DQogIGN1cnNvcjpwb2ludGVyOw0KfQ0KDQouYWxlcnQtZGFuZ2VyOmhvdmVyDQp7DQogICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjIwLCAxNywgMSwgMC4zMyk7DQogIHRyYW5zaXRpb246MC41czsNCn0NCg0KLmRhbmdlcg0Kew0KICAgICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGNvbG9yOiAjZmYwMzAzOw0KICAgIHRleHQtc2hhZG93OiBub25lOw0KfQ0KDQouYWxlcnQtc2ltcGxlLmFsZXJ0LXByaW1hcnkNCnsNCiAgYm9yZGVyOiAxcHggc29saWQgcmdiYSg2LCAyNDEsIDIyNiwgMC44MSk7DQogICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgxLCAyMDQsIDIyMCwgMC4xNik7DQogICAgYm94LXNoYWRvdzogMHB4IDBweCAycHggIzAzZmZmNTsNCiAgICBjb2xvcjogIzAzZDBmZjsNCiAgICB0ZXh0LXNoYWRvdzogMnB4IDFweCAjMDAwNDBhOw0KICB0cmFuc2l0aW9uOjAuNXM7DQogIGN1cnNvcjpwb2ludGVyOw0KfQ0KDQouYWxlcnQtcHJpbWFyeTpob3ZlcnsNCiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgxLCAyMDQsIDIyMCwgMC4zMyk7DQogICB0cmFuc2l0aW9uOjAuNXM7DQp9DQoNCi5hbGVydHByaW1hcnkNCnsNCiAgICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBjb2xvcjogIzAzZDBmZjsNCiAgICB0ZXh0LXNoYWRvdzogbm9uZTsNCn0NCg0KLnNxdWFyZV9ib3ggew0KICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTsNCiAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDQ1ZGVnKTsNCiAgICAtbXMtdHJhbnNmb3JtOiByb3RhdGUoNDVkZWcpOw0KICAgIHRyYW5zZm9ybTogcm90YXRlKDQ1ZGVnKTsNCiAgICBib3JkZXItdG9wLWxlZnQtcmFkaXVzOiA0NXB4Ow0KICAgIG9wYWNpdHk6IDAuMzAyOw0KfQ0KDQouc3F1YXJlX2JveC5ib3hfdGhyZWUgew0KICAgIGJhY2tncm91bmQtaW1hZ2U6IC1tb3otbGluZWFyLWdyYWRpZW50KC05MGRlZywgIzI5MGE1OSAwJSwgIzNkNTdmNCAxMDAlKTsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOiAtd2Via2l0LWxpbmVhci1ncmFkaWVudCgtOTBkZWcsICMyOTBhNTkgMCUsICMzZDU3ZjQgMTAwJSk7DQogICAgYmFja2dyb3VuZC1pbWFnZTogLW1zLWxpbmVhci1ncmFkaWVudCgtOTBkZWcsICMyOTBhNTkgMCUsICMzZDU3ZjQgMTAwJSk7DQogICAgb3BhY2l0eTogMC4wNTk7DQogICAgbGVmdDogLTgwcHg7DQogICAgdG9wOiAtNjBweDsNCiAgICB3aWR0aDogNTAwcHg7DQogICAgaGVpZ2h0OiA1MDBweDsNCiAgICBib3JkZXItcmFkaXVzOiA0NXB4Ow0KfQ0KDQouc3F1YXJlX2JveC5ib3hfZm91ciB7DQogICAgYmFja2dyb3VuZC1pbWFnZTogLW1vei1saW5lYXItZ3JhZGllbnQoLTkwZGVnLCAjMjkwYTU5IDAlLCAjM2Q1N2Y0IDEwMCUpOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6IC13ZWJraXQtbGluZWFyLWdyYWRpZW50KC05MGRlZywgIzI5MGE1OSAwJSwgIzNkNTdmNCAxMDAlKTsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOiAtbXMtbGluZWFyLWdyYWRpZW50KC05MGRlZywgIzI5MGE1OSAwJSwgIzNkNTdmNCAxMDAlKTsNCiAgICBvcGFjaXR5OiAwLjA1OTsNCiAgICBsZWZ0OiAxNTBweDsNCiAgICB0b3A6IC0yNXB4Ow0KICAgIHdpZHRoOiA1NTBweDsNCiAgICBoZWlnaHQ6IDU1MHB4Ow0KICAgIGJvcmRlci1yYWRpdXM6IDQ1cHg7DQp9DQoNCi5hbGVydDpiZWZvcmUgew0KICAgIGNvbnRlbnQ6ICcnOw0KICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTsNCiAgICB3aWR0aDogMDsNCiAgICBoZWlnaHQ6IGNhbGMoMTAwJSAtIDQ0cHgpOw0KICAgIGJvcmRlci1sZWZ0OiAxcHggc29saWQ7DQogICAgYm9yZGVyLXJpZ2h0OiAycHggc29saWQ7DQogICAgYm9yZGVyLWJvdHRvbS1yaWdodC1yYWRpdXM6IDNweDsNCiAgICBib3JkZXItdG9wLXJpZ2h0LXJhZGl1czogM3B4Ow0KICAgIGxlZnQ6IDA7DQogICAgdG9wOiA1MCU7DQogICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMCwtNTAlKTsNCiAgICAgIGhlaWdodDogMjBweDsNCn0NCg0KLmZhLXRpbWVzDQp7DQotd2Via2l0LWFuaW1hdGlvbjogYmxpbmstMSAycyBpbmZpbml0ZSBib3RoOw0KCSAgICAgICAgYW5pbWF0aW9uOiBibGluay0xIDJzIGluZmluaXRlIGJvdGg7DQp9DQoNCg0KLyoqDQogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQogKiBhbmltYXRpb24gYmxpbmstMQ0KICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KICovDQpALXdlYmtpdC1rZXlmcmFtZXMgYmxpbmstMSB7DQogIDAlLA0KICA1MCUsDQogIDEwMCUgew0KICAgIG9wYWNpdHk6IDE7DQogIH0NCiAgMjUlLA0KICA3NSUgew0KICAgIG9wYWNpdHk6IDA7DQogIH0NCn0NCkBrZXlmcmFtZXMgYmxpbmstMSB7DQogIDAlLA0KICA1MCUsDQogIDEwMCUgew0KICAgIG9wYWNpdHk6IDE7DQogIH0NCiAgMjUlLA0KICA3NSUgew0KICAgIG9wYWNpdHk6IDA7DQogIH0NCn0NCiAgDQo8L3N0eWxlPg0KDQoNCjxoZWFkPg0KICA8bWV0YSBjaGFyc2V0PSJVVEYtOCI+DQogIDxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MS4wIj4NCiAgPHRpdGxlPlNpZ24tVXAvTG9naW4gRm9ybSB8IEBHb2dpbGEuXzwvdGl0bGU+DQogIDxsaW5rIGhyZWY9J2h0dHBzOi8vdW5wa2cuY29tL2JveGljb25zQDIuMS40L2Nzcy9ib3hpY29ucy5taW4uY3NzJyByZWw9J3N0eWxlc2hlZXQnPg0KICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9InN0eWxlLmNzcyI+DQo8L2hlYWQ+DQoNCjxib2R5Pg0KICA8ZGl2IGNsYXNzPSJ3cmFwcGVyIj4NCiAgICA8ZGl2IGNsYXNzPSJsb2dpbi1ib3giPg0KICAgICAgPGRpdiBjbGFzcz0ibG9naW4taGVhZGVyIj4NCiAgICAgICAgPHNwYW4+TG9naW48L3NwYW4+DQogICAgICA8L2Rpdj4NCiAgICAgIA0KDQogIDxkaXYgaWQ9InJlZ2lzdGVyTW9kYWwiIGNsYXNzPSJtb2RhbCI+DQogICAgPGRpdiBjbGFzcz0ibW9kYWwtY29udGVudCI+DQogICAgICA8c3BhbiBjbGFzcz0iY2xvc2UiIG9uY2xpY2s9ImNsb3NlTW9kYWwoJ3JlZ2lzdGVyTW9kYWwnKSI+w5c8L3NwYW4+DQogICAgICA8aDI+UmVnaXN0ZXI8L2gyPg0KICAgICAgPGRpdiBjbGFzcz0iaW5wdXRfYm94Ij4NCiAgICAgICAgPGlucHV0IHR5cGU9InRleHQiIGlkPSJyZWdpc3RlclVzZXIiIGNsYXNzPSJpbnB1dC1maWVsZCIgcmVxdWlyZWQ+DQogICAgICAgIDxsYWJlbCBmb3I9InJlZ2lzdGVyVXNlciIgY2xhc3M9ImxhYmVsIj5Vc2VybmFtZTwvbGFiZWw+DQogICAgICA8L2Rpdj4NCiAgICAgIDxkaXYgY2xhc3M9ImlucHV0X2JveCI+DQogICAgICAgIDxpbnB1dCB0eXBlPSJlbWFpbCIgaWQ9InJlZ2lzdGVyRW1haWwiIGNsYXNzPSJpbnB1dC1maWVsZCIgcmVxdWlyZWQ+DQogICAgICAgIDxsYWJlbCBmb3I9InJlZ2lzdGVyRW1haWwiIGNsYXNzPSJsYWJlbCI+RW1haWw8L2xhYmVsPg0KICAgICAgPC9kaXY+DQogICAgICA8ZGl2IGNsYXNzPSJpbnB1dF9ib3giPg0KICAgICAgICA8aW5wdXQgdHlwZT0icGFzc3dvcmQiIGlkPSJyZWdpc3RlclBhc3MiIGNsYXNzPSJpbnB1dC1maWVsZCIgcmVxdWlyZWQgb25pbnB1dD0iY2hlY2tQYXNzd29yZFN0cmVuZ3RoUmVnaXN0ZXIodGhpcy52YWx1ZSkiPg0KICAgICAgICA8bGFiZWwgZm9yPSJyZWdpc3RlclBhc3MiIGNsYXNzPSJsYWJlbCI+UGFzc3dvcmQ8L2xhYmVsPg0KICAgICAgICA8aSBjbGFzcz0iYnggYngtbG9jay1hbHQgaWNvbiIgaWQ9InRvZ2dsZVBhc3N3b3JkUmVnaXN0ZXIiPjwvaT4NCiAgICAgIDwvZGl2Pg0KICAgICAgPGRpdiBpZD0icGFzc3dvcmRTdHJlbmd0aFJlZ2lzdGVyIiBjbGFzcz0icGFzc3dvcmQtc3RyZW5ndGgiPjwvZGl2Pg0KDQogICAgICA8ZGl2IGNsYXNzPSJpbnB1dF9ib3giPg0KICAgICAgICA8aW5wdXQgdHlwZT0ic3VibWl0IiBjbGFzcz0iaW5wdXQtc3VibWl0IiB2YWx1ZT0iUmVnaXN0ZXIiIG9uY2xpY2s9ImhhbmRsZVJlZ2lzdGVyKCkiPg0KICAgICAgPC9kaXY+DQogICAgPC9kaXY+DQogIDwvZGl2Pg0KDQogIDxkaXYgaWQ9ImZvcmdvdFBhc3N3b3JkTW9kYWwiIGNsYXNzPSJtb2RhbCI+DQogICAgPGRpdiBjbGFzcz0ibW9kYWwtY29udGVudCI+DQogICAgICA8c3BhbiBjbGFzcz0iY2xvc2UiIG9uY2xpY2s9ImNsb3NlTW9kYWwoJ2ZvcmdvdFBhc3N3b3JkTW9kYWwnKSI+w5c8L3NwYW4+DQogICAgICA8aDI+Rm9yZ290IFBhc3N3b3JkPC9oMj4NCiAgICAgIDxkaXYgY2xhc3M9ImlucHV0X2JveCI+DQogICAgICAgIDxpbnB1dCB0eXBlPSJlbWFpbCIgaWQ9ImZvcmdvdEVtYWlsIiBjbGFzcz0iaW5wdXQtZmllbGQiIHJlcXVpcmVkPg0KICAgICAgICA8bGFiZWwgZm9yPSJmb3Jnb3RFbWFpbCIgY2xhc3M9ImxhYmVsIj5FbWFpbDwvbGFiZWw+DQogICAgICA8L2Rpdj4NCiAgICAgIDxkaXYgY2xhc3M9ImlucHV0X2JveCI+DQogICAgICAgIDxpbnB1dCB0eXBlPSJzdWJtaXQiIGNsYXNzPSJpbnB1dC1zdWJtaXQiIHZhbHVlPSJSZXNldCBQYXNzd29yZCIgb25jbGljaz0iaGFuZGxlRm9yZ290UGFzc3dvcmQoKSI+DQogICAgICA8L2Rpdj4NCiAgICA8L2Rpdj4NCiAgPC9kaXY+DQoNCiAgPHNjcmlwdCBzcmM9InNjcmlwdC5qcyI+PC9zY3JpcHQ+DQo8L2JvZHk+DQoNCjwvaHRtbD4NCjxzdHlsZT4NCiAgDQovKiBQT1BQSU5TIEZPTlQgKi8NCg0KQGltcG9ydCB1cmwoImh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzMj9mYW1pbHk9UG9wcGluczp3Z2h0QDQwMDs1MDA7NjAwOzcwMCZkaXNwbGF5PXN3YXAiKTsNCg0KKiB7DQogIG1hcmdpbjogMDsNCg0KICBwYWRkaW5nOiAwOw0KDQogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7DQoNCiAgZm9udC1mYW1pbHk6ICJQb3BwaW5zIiwgc2Fucy1zZXJpZjsNCn0NCg0KLyogPT09PT0gQ09MT1IgVkFSSUFCTEVTID09PT09ICovDQoNCjpyb290IHsNCiAgLS1wcmltYXJ5LWNvbG9yOiAjNjY1N2Y0Ow0KDQogIC0tc2Vjb25kLWNvbG9yOiAjZmZmZmZmOw0KDQogIC0tYmxhY2stY29sb3I6ICMwMDAwMDA7DQp9DQoNCi8qID09PT09IEJPRFkgLSBCQUNLR1JPVU5EIElNQUdFID09PT09ICovDQoNCmJvZHkgew0KICBiYWNrZ3JvdW5kOiAjOWE5MGY1Ow0KfQ0KDQovKiA9PT09PSBSZXVzYWJsZSBDU1MgPT09PT0gKi8NCg0KYSB7DQogIHRleHQtZGVjb3JhdGlvbjogbm9uZTsNCiAgY29sb3I6IHZhcigtLXNlY29uZC1jb2xvcik7DQp9DQphOmhvdmVyIHsNCiAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7DQp9DQoNCi8qID09PT09IFdSQVBQRVIgPT09PT0gKi8NCg0KLndyYXBwZXIgew0KICB3aWR0aDogMTAwJTsNCiAgZGlzcGxheTogZmxleDsNCiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7DQogIGFsaWduLWl0ZW1zOiBjZW50ZXI7DQogIG1pbi1oZWlnaHQ6IDEwMHZoOw0KICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuMik7DQp9DQoNCi5sb2dpbi1ib3ggew0KICBwb3NpdGlvbjogcmVsYXRpdmU7DQogIHdpZHRoOiA0NTBweDsNCiAgYm9yZGVyOiAzcHggc29saWQgdmFyKC0tcHJpbWFyeS1jb2xvcik7DQogIGJvcmRlci1yYWRpdXM6IDE1cHg7DQogIHBhZGRpbmc6IDcuNWVtIDIuNWVtIDRlbSAyLjVlbTsNCiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZmZmZjsNCiAgYm94LXNoYWRvdzogMHB4IDBweCAxMHB4IDJweCByZ2JhKDAsIDAsIDAsIDAuMyk7DQp9DQoNCi5sb2dpbi1oZWFkZXIgew0KICBwb3NpdGlvbjogYWJzb2x1dGU7DQogIHRvcDogMDsNCiAgbGVmdDogNTAlOw0KICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTUwJSk7DQogIGRpc3BsYXk6IGZsZXg7DQogIGFsaWduLWl0ZW1zOiBjZW50ZXI7DQogIGp1c3RpZnktY29udGVudDogY2VudGVyOw0KICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1wcmltYXJ5LWNvbG9yKTsNCiAgd2lkdGg6IDE0MHB4Ow0KICBoZWlnaHQ6IDcwcHg7DQogIGJvcmRlci1yYWRpdXM6IDAgMCAyMHB4IDIwcHg7DQp9DQoNCi5sb2dpbi1oZWFkZXIgc3BhbiB7DQogIGZvbnQtc2l6ZTogMzBweDsNCiAgY29sb3I6IHZhcigtLWJsYWNrLWNvbG9yKTsNCn0NCg0KLmxvZ2luLWhlYWRlcjo6YmVmb3JlIHsNCiAgY29udGVudDogIiI7DQogIHBvc2l0aW9uOiBhYnNvbHV0ZTsNCiAgdG9wOiAwOw0KICBsZWZ0OiAtMzBweDsNCiAgd2lkdGg6IDMwcHg7DQogIGhlaWdodDogMzBweDsNCiAgYm9yZGVyLXRvcC1yaWdodC1yYWRpdXM6IDUwJTsNCiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7DQogIGJveC1zaGFkb3c6IDE1cHggMCAwIDAgdmFyKC0tcHJpbWFyeS1jb2xvcik7DQp9DQoNCi5sb2dpbi1oZWFkZXI6OmFmdGVyIHsNCiAgY29udGVudDogIiI7DQogIHBvc2l0aW9uOiBhYnNvbHV0ZTsNCiAgdG9wOiAwOw0KICByaWdodDogLTMwcHg7DQogIHdpZHRoOiAzMHB4Ow0KICBoZWlnaHQ6IDMwcHg7DQogIGJvcmRlci10b3AtbGVmdC1yYWRpdXM6IDUwJTsNCiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7DQogIGJveC1zaGFkb3c6IC0xNXB4IDAgMCAwIHZhcigtLXByaW1hcnktY29sb3IpOw0KfQ0KDQouaW5wdXRfYm94IHsNCiAgcG9zaXRpb246IHJlbGF0aXZlOw0KICBkaXNwbGF5OiBmbGV4Ow0KICBmbGV4LWRpcmVjdGlvbjogY29sdW1uOw0KICBtYXJnaW46IDIwcHggMDsNCn0NCg0KLmlucHV0LWZpZWxkIHsNCiAgd2lkdGg6IDEwMCU7DQogIGhlaWdodDogNTVweDsNCiAgZm9udC1zaXplOiAxNnB4Ow0KICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsNCiAgY29sb3I6ICMwMDAwMDA7DQogIHBhZGRpbmctaW5saW5lOiAyMHB4IDUwcHg7DQogIGJvcmRlcjogMnB4IHNvbGlkIHZhcigtLXByaW1hcnktY29sb3IpOw0KICBib3JkZXItcmFkaXVzOiAzMHB4Ow0KICBvdXRsaW5lOiBub25lOw0KfQ0KDQojdXNlciB7DQogIG1hcmdpbi1ib3R0b206IDEwcHg7DQp9DQoNCi5sYWJlbCB7DQogIHBvc2l0aW9uOiBhYnNvbHV0ZTsNCiAgdG9wOiAxNXB4Ow0KICBsZWZ0OiAyMHB4Ow0KICB0cmFuc2l0aW9uOiAwLjJzIGVhc2UtaW4tb3V0Ow0KfQ0KDQouaW5wdXQtZmllbGQ6Zm9jdXMgfiAubGFiZWwsDQouaW5wdXQtZmllbGQ6dmFsaWQgfiAubGFiZWwgew0KICBwb3NpdGlvbjogYWJzb2x1dGU7DQogIHRvcDogLTEwcHg7DQogIGxlZnQ6IDIwcHg7DQogIGZvbnQtc2l6ZTogMTRweDsNCiAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tcHJpbWFyeS1jb2xvcik7DQogIGJvcmRlci1yYWRpdXM6IDMwcHg7DQogIGNvbG9yOiBibGFjazsNCiAgcGFkZGluZzogMCAxMHB4Ow0KfQ0KDQouaWNvbiB7DQogIHBvc2l0aW9uOiBhYnNvbHV0ZTsNCiAgdG9wOiAxOHB4Ow0KICByaWdodDogMjVweDsNCiAgZm9udC1zaXplOiAyMHB4Ow0KICBjdXJzb3I6IHBvaW50ZXI7DQp9DQoNCi5ieC1oaWRlIHsNCiAgY29udGVudDogIlxlYjJjIjsgLyogSGlkZSBpY29uICovDQp9DQoNCi5ieC1zaG93IHsNCiAgY29udGVudDogIlxlYjI1IjsgLyogU2hvdyBpY29uICovDQp9DQoNCi5yZW1lbWJlci1mb3Jnb3Qgew0KICBkaXNwbGF5OiBmbGV4Ow0KICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47DQogIGZvbnQtc2l6ZTogMTVweDsNCn0NCg0KLmlucHV0LXN1Ym1pdCB7DQogIHdpZHRoOiAxMDAlOw0KICBoZWlnaHQ6IDUwcHg7DQogIGJhY2tncm91bmQ6ICM2NjU3ZjQ7DQogIGZvbnQtc2l6ZTogMTZweDsNCiAgZm9udC13ZWlnaHQ6IDUwMDsNCiAgYm9yZGVyOiBub25lOw0KICBib3JkZXItcmFkaXVzOiAzMHB4Ow0KICBjdXJzb3I6IHBvaW50ZXI7DQogIHRyYW5zaXRpb246IDAuM3MgZWFzZS1pbi1vdXQ7DQp9DQoNCi5pbnB1dC1zdWJtaXQ6aG92ZXIgew0KICBiYWNrZ3JvdW5kOiAjMWQwZGIyOw0KfQ0KDQoucmVnaXN0ZXIgew0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCi5yZWdpc3RlciBhIHsNCiAgZm9udC13ZWlnaHQ6IDUwMDsNCn0NCg0KYSB7DQogIGNvbG9yOiAjNjY1N2Y0Ow0KfQ0KDQpAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDU2NHB4KSB7DQogIC53cmFwcGVyIHsNCiAgICBwYWRkaW5nOiAyMHB4Ow0KICB9DQogIC5sb2dpbi1ib3ggew0KICAgIHBhZGRpbmc6IDcuNWVtIDEuNWVtIDRlbSAyLjVlbTsNCiAgfQ0KfQ0KDQovKiBGb3IgdGFibGV0cyBhbmQgbGFyZ2VyIHBob25lcyAqLw0KQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAxMDI0cHgpIHsNCiAgLndyYXBwZXIgew0KICAgIHBhZGRpbmc6IDUwcHg7DQogIH0NCiAgLmxvZ2luLWJveCB7DQogICAgd2lkdGg6IDgwJTsgLyogQWRqdXN0IHdpZHRoICovDQogICAgcGFkZGluZzogNWVtIDEuNWVtIDNlbSAxLjVlbTsgLyogQWRqdXN0IHBhZGRpbmcgKi8NCiAgfQ0KICAubW9kYWwtY29udGVudCB7DQogICAgd2lkdGg6IDcwJTsgLyogQWRqdXN0IG1vZGFsIHdpZHRoICovDQogIH0NCn0NCg0KLyogRm9yIHNtYWxsZXIgc2NyZWVucyBsaWtlIHBob25lcyAqLw0KQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA1NjRweCkgew0KICAud3JhcHBlciB7DQogICAgcGFkZGluZzogMTVweDsNCiAgfQ0KICAubG9naW4tYm94IHsNCiAgICBwYWRkaW5nOiA3LjVlbSAxLjVlbSA0ZW0gMi41ZW07DQogIH0NCiAgLm1vZGFsLWNvbnRlbnQgew0KICAgIHdpZHRoOiA5MCU7IC8qIEFkanVzdCBtb2RhbCB3aWR0aCAqLw0KICB9DQogIA0KICAgIC5yZW1lbWJlci1mb3Jnb3Qgew0KICAgZm9udC1zaXplOiAxMXB4Ow0KICAgbWFyZ2luOiAwIDEwcHg7DQogIH0NCi8qIEhpZGUgdGhlIGRlZmF1bHQgY2hlY2tib3ggKi8NCmlucHV0W3R5cGU9ImNoZWNrYm94Il0gew0KICAgIHdpZHRoOiAxMXB4OyAvKiBTZXQgd2lkdGggKi8NCiAgICBoZWlnaHQ6IDExcHg7IC8qIFNldCBoZWlnaHQgKi8NCiAgfQ0KfQ0KDQouZXJyb3ItbWVzc2FnZSB7DQogIGNvbG9yOiByZWQ7DQogIGZvbnQtc2l6ZTogMTJweDsNCiAgbWFyZ2luLXRvcDogNXB4Ow0KfQ0KDQovKiBNb2RhbCBzdHlsZXMgKi8NCi5tb2RhbCB7DQogIGRpc3BsYXk6IG5vbmU7DQogIHBvc2l0aW9uOiBmaXhlZDsNCiAgei1pbmRleDogMTsNCiAgbGVmdDogMDsNCiAgdG9wOiAwOw0KICB3aWR0aDogMTAwJTsNCiAgaGVpZ2h0OiAxMDAlOw0KICBvdmVyZmxvdzogYXV0bzsNCiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjQpOw0KfQ0KDQoubW9kYWwtY29udGVudCB7DQogIGJhY2tncm91bmQtY29sb3I6ICNmZWZlZmU7DQogIG1hcmdpbjogMTUlIGF1dG87DQogIHBhZGRpbmc6IDIwcHg7DQogIGJvcmRlcjogMXB4IHNvbGlkICM4ODg7DQogIHdpZHRoOiA4MCU7DQp9DQoNCi5jbG9zZSB7DQogIGNvbG9yOiAjYWFhOw0KICBmbG9hdDogcmlnaHQ7DQogIGZvbnQtc2l6ZTogMjhweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQp9DQoNCi5jbG9zZTpob3ZlciwNCi5jbG9zZTpmb2N1cyB7DQogIGNvbG9yOiBibGFjazsNCiAgdGV4dC1kZWNvcmF0aW9uOiBub25lOw0KICBjdXJzb3I6IHBvaW50ZXI7DQp9DQoNCjwvc3R5bGU+DQoNCjxib2R5Pg0KICAgIA0KICAgICAgPGRpdiBjbGFzcz0iaW5wdXRfYm94Ij4NCiAgICAgIDw/PSBmb3JtX29wZW4oKSA/Pg0KICAgICAgICA8ZGl2IGNsYXNzPSJmb3JtLWdyb3VwIj4NCiAgICAgICAgICA8bGFiZWwgY2xhc3M9ImZvcm0tbGFiZWwiIGZvcj0idXNlcm5hbWUiPjwvbGFiZWw+DQogICAgICAgICAgPGlucHV0IHR5cGU9InRleHQiIGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InVzZXJuYW1lIiBpZD0idXNlcm5hbWUiIGFyaWEtZGVzY3JpYmVkYnk9ImhlbHAtdXNlcm5hbWUiIHBsYWNlaG9sZGVyPSJZb3VyIHVzZXJuYW1lIiByZXF1aXJlZCBtaW5sZW5ndGg9IjQiPg0KICAgICAgICAgIDw/cGhwIGlmICgkdmFsaWRhdGlvbi0+aGFzRXJyb3IoJ3VzZXJuYW1lJykpIDogPz4NCiAgICAgICAgICA8c21hbGwgaWQ9ImhlbHAtdXNlcm5hbWUiIGNsYXNzPSJmb3JtLXRleHQgdGV4dC1kYW5nZXIiPjw/PSAkdmFsaWRhdGlvbi0+Z2V0RXJyb3IoJ3VzZXJuYW1lJykgPz48L3NtYWxsPg0KICAgICAgICAgIDxpIGNsYXNzPSJieCBieC11c2VyIGljb24iPjwvaQ0KICAgICAgICAgIDw/cGhwIGVuZGlmOyA/Pg0KICAgICAgICA8L2Rpdj4NCiAgICAgICAgPGRpdiBjbGFzcz0iZm9ybS1ncm91cCI+DQogICAgICAgICAgPGxhYmVsIGNsYXNzPSJmb3JtLWxhYmVsIiBmb3I9InBhc3N3b3JkIj48L2xhYmVsPg0KICAgICAgICAgIDxpbnB1dCB0eXBlPSJwYXNzd29yZCIgY2xhc3M9ImZvcm0tY29udHJvbCIgbmFtZT0icGFzc3dvcmQiIGlkPSJwYXNzd29yZCIgYXJpYS1kZXNjcmliZWRieT0iaGVscC1wYXNzd29yZCIgcGxhY2Vob2xkZXI9IllvdXIgcGFzc3dvcmQiIHJlcXVpcmVkIG1pbmxlbmd0aD0iNiI+DQogICAgICAgICAgPD9waHAgaWYgKCR2YWxpZGF0aW9uLT5oYXNFcnJvcigncGFzc3dvcmQnKSkgOiA/Pg0KICAgICAgICAgIDxzbWFsbCBpZD0iaGVscC1wYXNzd29yZCIgY2xhc3M9ImZvcm0tdGV4dCB0ZXh0LWRhbmdlciI+PD89ICR2YWxpZGF0aW9uLT5nZXRFcnJvcigncGFzc3dvcmQnKSA/Pjwvc21hbGw+DQogICAgICAgICAgPD9waHAgZW5kaWY7ID8+DQogICAgICAgICAgPGJ1dHRvbiB0eXBlPSJzdWJtaXQiIGNsYXNzPSJidG4iPj48aSBjbGFzcz0iYmkgYmktYm94LWFycm93LWluLXJpZ2h0IiA+PC9pPjxmb250IGNvbG9yID0iIzlhOTBmNSI+IExvZyBpbjwvYnV0dG9uPg0KICAgICAgICA8L2Rpdj4NCjwvZGl2Pg0KDQo8cCBjbGFzcz0idGV4dC1jZW50ZXIgdGV4dC1kYXJrIGFmdGVyLWNhcmQiPg0KICAgICAgICAgICAgPHNtYWxsIGNsYXNzPSJiZy1kYXJrIHRleHQtd2hpdGUgcHgtYXV0byBwLTIgcm91bmRlZCI+DQogICAgICAgICA+PGZvbnQgY29sb3IgPSIjOWE5MGY1Ij4gICAgICDwnZC38J2RnCDwnZGb8J2RnPCdkaEg4oSO8J2RjvCdkaPwnZGSIPCdkY7wnZGbIPCdkLTwnZGQ8J2RkPCdkZzwnZGi8J2Rm/CdkaEg8J2RjPCdkZLwnZGhPw0KICAgICAgICAgICAgICAgIDxhIGhyZWY9Ijw/PSBzaXRlX3VybCgncmVnaXN0ZXInKSA/PiIgY2xhc3M9InRleHQtd2hpdGUiPjxmb250IGNvbG9yID0iIzlhOTBmNSI+8J2RufCdkobwnZKI8J2SivCdkpTwnZKV8J2ShvCdkpMg8J2Rr/CdkobwnZKT8J2ShjwvYT4NCiAgICAgICAgPC9zbWFsbD4NCiAgICAgIDwvcD4NCiAgICAgICAgICAgIDxtYXJxdWVlIGJlaGF2aW9yPSJhbHRlcm5hdGUiPvCdkI/wnZCR8J2QiPCdkI3wnZCC8J2QhCDwnZCP8J2QgPCdkI3wnZCE8J2QizwvbWFycXVlZT4NCg0KICAgICAgICAgICAgDQoNCg0KPHNjcmlwdD4NCiBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIiwgKGV2ZW50KSA9PiB7DQogIGNvbnN0IHNhdmVkVXNlcm5hbWUgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgicmVtZW1iZXJlZFVzZXJuYW1lIik7DQoNCiAgaWYgKHNhdmVkVXNlcm5hbWUpIHsNCiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgidXNlciIpLnZhbHVlID0gc2F2ZWRVc2VybmFtZTsNCg0KICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJyZW1lbWJlciIpLmNoZWNrZWQgPSB0cnVlOw0KICB9DQoNCiAgZG9jdW1lbnQNCg0KICAgIC5nZXRFbGVtZW50QnlJZCgidG9nZ2xlUGFzc3dvcmQiKQ0KDQogICAgLmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgZnVuY3Rpb24gKCkgew0KICAgICAgY29uc3QgcGFzc3dvcmRGaWVsZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJwYXNzIik7DQoNCiAgICAgIGNvbnN0IHR5cGUgPQ0KICAgICAgICBwYXNzd29yZEZpZWxkLmdldEF0dHJpYnV0ZSgidHlwZSIpID09PSAicGFzc3dvcmQiID8gInRleHQiIDogInBhc3N3b3JkIjsNCg0KICAgICAgcGFzc3dvcmRGaWVsZC5zZXRBdHRyaWJ1dGUoInR5cGUiLCB0eXBlKTsNCg0KICAgICAgdGhpcy5jbGFzc0xpc3QudG9nZ2xlKCJieC1oaWRlIik7DQoNCiAgICAgIHRoaXMuY2xhc3NMaXN0LnRvZ2dsZSgiYngtc2hvdyIpOw0KICAgIH0pOw0KDQogIGRvY3VtZW50DQoNCiAgICAucXVlcnlTZWxlY3RvcigiLmZvcmdvdCBhIikNCg0KICAgIC5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsIGZ1bmN0aW9uIChldmVudCkgew0KICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsNCg0KICAgICAgb3Blbk1vZGFsKCJmb3Jnb3RQYXNzd29yZE1vZGFsIik7DQogICAgfSk7DQoNCiAgZG9jdW1lbnQNCiAgICAucXVlcnlTZWxlY3RvcigiLnJlZ2lzdGVyIGEiKQ0KICAgIC5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsIGZ1bmN0aW9uIChldmVudCkgew0KICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsNCiAgICAgIG9wZW5Nb2RhbCgicmVnaXN0ZXJNb2RhbCIpOw0KICAgIH0pOw0KDQogIGZ1bmN0aW9uIG9wZW5Nb2RhbChtb2RhbElkKSB7DQogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQobW9kYWxJZCkuc3R5bGUuZGlzcGxheSA9ICJibG9jayI7DQogIH0NCg0KICBmdW5jdGlvbiBjbG9zZU1vZGFsKG1vZGFsSWQpIHsNCiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChtb2RhbElkKS5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOw0KICB9DQoNCiAgd2luZG93Lm9uY2xpY2sgPSBmdW5jdGlvbiAoZXZlbnQpIHsNCiAgICBpZiAoZXZlbnQudGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucygibW9kYWwiKSkgew0KICAgICAgZXZlbnQudGFyZ2V0LnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7DQogICAgfQ0KICB9Ow0KDQogIHdpbmRvdy5jbG9zZU1vZGFsID0gY2xvc2VNb2RhbDsNCn0pOw0KDQpmdW5jdGlvbiBzaG93RXJyb3IoZWxlbWVudCwgbWVzc2FnZSkgew0KICBjb25zdCBlcnJvclNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzcGFuIik7DQogIGVycm9yU3Bhbi5jbGFzc05hbWUgPSAiZXJyb3ItbWVzc2FnZSI7DQogIGVycm9yU3Bhbi50ZXh0Q29udGVudCA9IG1lc3NhZ2U7DQogIGVsZW1lbnQucGFyZW50RWxlbWVudC5hcHBlbmRDaGlsZChlcnJvclNwYW4pOw0KfQ0KDQpmdW5jdGlvbiBjbGVhckVycm9ycygpIHsNCiAgY29uc3QgZXJyb3JzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgiLmVycm9yLW1lc3NhZ2UiKTsNCiAgZXJyb3JzLmZvckVhY2goKGVycm9yKSA9PiBlcnJvci5yZW1vdmUoKSk7DQp9DQoNCmFzeW5jIGZ1bmN0aW9uIGhhbmRsZUxvZ2luKCkgew0KICBjbGVhckVycm9ycygpOw0KDQogIGNvbnN0IHVzZXJuYW1lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInVzZXIiKS52YWx1ZTsNCiAgY29uc3QgcGFzc3dvcmQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicGFzcyIpLnZhbHVlOw0KICBjb25zdCByZW1lbWJlck1lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInJlbWVtYmVyIikuY2hlY2tlZDsNCg0KICBsZXQgdmFsaWQgPSB0cnVlOw0KDQogIGlmICghdXNlcm5hbWUpIHsNCiAgICBzaG93RXJyb3IoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInVzZXIiKSwgIlVzZXJuYW1lIGlzIHJlcXVpcmVkIik7DQogICAgdmFsaWQgPSBmYWxzZTsNCiAgfQ0KDQogIGlmICghcGFzc3dvcmQpIHsNCiAgICBzaG93RXJyb3IoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInBhc3MiKSwgIlBhc3N3b3JkIGlzIHJlcXVpcmVkIik7DQogICAgdmFsaWQgPSBmYWxzZTsNCiAgfQ0KDQogIGlmICghdmFsaWQpIHsNCiAgICByZXR1cm47DQogIH0NCg0KICBpZiAocmVtZW1iZXJNZSkgew0KICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCJyZW1lbWJlcmVkVXNlcm5hbWUiLCB1c2VybmFtZSk7DQogIH0gZWxzZSB7DQogICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oInJlbWVtYmVyZWRVc2VybmFtZSIpOw0KICB9DQoNCiAgdHJ5IHsNCiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCIvbG9naW4iLCB7DQogICAgICBtZXRob2Q6ICJQT1NUIiwNCiAgICAgIGhlYWRlcnM6IHsNCiAgICAgICAgIkNvbnRlbnQtVHlwZSI6ICJhcHBsaWNhdGlvbi9qc29uIg0KICAgICAgfSwNCiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgdXNlcm5hbWUsIHBhc3N3b3JkIH0pDQogICAgfSk7DQoNCiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7DQoNCiAgICBpZiAocmVzcG9uc2Uub2spIHsNCiAgICAgIGFsZXJ0KCJMb2dnZWQgaW4gc3VjY2Vzc2Z1bGx5Iik7DQogICAgfSBlbHNlIHsNCiAgICAgIHNob3dFcnJvcihkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicGFzcyIpLCByZXN1bHQubWVzc2FnZSk7DQogICAgfQ0KICB9IGNhdGNoIChlcnJvcikgew0KICAgIHNob3dFcnJvcigNCiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJwYXNzIiksDQogICAgICAiTG9naW4gZmFpbGVkLiBQbGVhc2UgdHJ5IGFnYWluLiINCiAgICApOw0KICB9DQp9DQoNCmFzeW5jIGZ1bmN0aW9uIGhhbmRsZVJlZ2lzdGVyKCkgew0KICBjbGVhckVycm9ycygpOw0KDQogIGNvbnN0IHVzZXJuYW1lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInJlZ2lzdGVyVXNlciIpLnZhbHVlOw0KICBjb25zdCBlbWFpbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJyZWdpc3RlckVtYWlsIikudmFsdWU7DQogIGNvbnN0IHBhc3N3b3JkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInJlZ2lzdGVyUGFzcyIpLnZhbHVlOw0KDQogIGxldCB2YWxpZCA9IHRydWU7DQoNCiAgaWYgKCF1c2VybmFtZSkgew0KICAgIHNob3dFcnJvcihkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicmVnaXN0ZXJVc2VyIiksICJVc2VybmFtZSBpcyByZXF1aXJlZCIpOw0KICAgIHZhbGlkID0gZmFsc2U7DQogIH0NCg0KICBpZiAoIWVtYWlsKSB7DQogICAgc2hvd0Vycm9yKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJyZWdpc3RlckVtYWlsIiksICJFbWFpbCBpcyByZXF1aXJlZCIpOw0KICAgIHZhbGlkID0gZmFsc2U7DQogIH0NCg0KICBpZiAoIXBhc3N3b3JkKSB7DQogICAgc2hvd0Vycm9yKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJyZWdpc3RlclBhc3MiKSwgIlBhc3N3b3JkIGlzIHJlcXVpcmVkIik7DQogICAgdmFsaWQgPSBmYWxzZTsNCiAgfQ0KDQogIGlmICghdmFsaWQpIHsNCiAgICByZXR1cm47DQogIH0NCg0KICB0cnkgew0KICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goIi9yZWdpc3RlciIsIHsNCiAgICAgIG1ldGhvZDogIlBPU1QiLA0KICAgICAgaGVhZGVyczogew0KICAgICAgICAiQ29udGVudC1UeXBlIjogImFwcGxpY2F0aW9uL2pzb24iDQogICAgICB9LA0KICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyB1c2VybmFtZSwgZW1haWwsIHBhc3N3b3JkIH0pDQogICAgfSk7DQoNCiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7DQoNCiAgICBpZiAocmVzcG9uc2Uub2spIHsNCiAgICAgIGFsZXJ0KCJSZWdpc3RyYXRpb24gc3VjY2Vzc2Z1bCIpOw0KICAgICAgY2xvc2VNb2RhbCgicmVnaXN0ZXJNb2RhbCIpOw0KICAgIH0gZWxzZSB7DQogICAgICBzaG93RXJyb3IoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInJlZ2lzdGVyUGFzcyIpLCByZXN1bHQubWVzc2FnZSk7DQogICAgfQ0KICB9IGNhdGNoIChlcnJvcikgew0KICAgIHNob3dFcnJvcigNCiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJyZWdpc3RlclBhc3MiKSwNCiAgICAgICJSZWdpc3RyYXRpb24gZmFpbGVkLiBQbGVhc2UgdHJ5IGFnYWluLiINCiAgICApOw0KICB9DQp9DQoNCmFzeW5jIGZ1bmN0aW9uIGhhbmRsZUZvcmdvdFBhc3N3b3JkKCkgew0KICBjbGVhckVycm9ycygpOw0KDQogIGNvbnN0IGVtYWlsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImZvcmdvdEVtYWlsIikudmFsdWU7DQoNCiAgaWYgKCFlbWFpbCkgew0KICAgIHNob3dFcnJvcihkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZm9yZ290RW1haWwiKSwgIkVtYWlsIGlzIHJlcXVpcmVkIik7DQogICAgcmV0dXJuOw0KICB9DQoNCiAgdHJ5IHsNCiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCIvZm9yZ290LXBhc3N3b3JkIiwgew0KICAgICAgbWV0aG9kOiAiUE9TVCIsDQogICAgICBoZWFkZXJzOiB7DQogICAgICAgICJDb250ZW50LVR5cGUiOiAiYXBwbGljYXRpb24vanNvbiINCiAgICAgIH0sDQogICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IGVtYWlsIH0pDQogICAgfSk7DQoNCiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7DQoNCiAgICBpZiAocmVzcG9uc2Uub2spIHsNCiAgICAgIGFsZXJ0KCJQYXNzd29yZCByZXNldCBsaW5rIHNlbnQgdG8geW91ciBlbWFpbCIpOw0KICAgICAgY2xvc2VNb2RhbCgiZm9yZ290UGFzc3dvcmRNb2RhbCIpOw0KICAgIH0gZWxzZSB7DQogICAgICBzaG93RXJyb3IoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImZvcmdvdEVtYWlsIiksIHJlc3VsdC5tZXNzYWdlKTsNCiAgICB9DQogIH0gY2F0Y2ggKGVycm9yKSB7DQogICAgc2hvd0Vycm9yKA0KICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImZvcmdvdEVtYWlsIiksDQogICAgICAiUGFzc3dvcmQgcmVzZXQgZmFpbGVkLiBQbGVhc2UgdHJ5IGFnYWluLiINCiAgICApOw0KICB9DQp9DQoNCmZ1bmN0aW9uIGNoZWNrUGFzc3dvcmRTdHJlbmd0aChwYXNzd29yZCkgew0KICBjb25zdCBzdHJlbmd0aEluZGljYXRvciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJwYXNzd29yZFN0cmVuZ3RoIik7DQogIHVwZGF0ZVBhc3N3b3JkU3RyZW5ndGgocGFzc3dvcmQsIHN0cmVuZ3RoSW5kaWNhdG9yKTsNCn0NCg0KZnVuY3Rpb24gY2hlY2tQYXNzd29yZFN0cmVuZ3RoUmVnaXN0ZXIocGFzc3dvcmQpIHsNCiAgY29uc3Qgc3RyZW5ndGhJbmRpY2F0b3IgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicGFzc3dvcmRTdHJlbmd0aFJlZ2lzdGVyIik7DQogIHVwZGF0ZVBhc3N3b3JkU3RyZW5ndGgocGFzc3dvcmQsIHN0cmVuZ3RoSW5kaWNhdG9yKTsNCn0NCg0KZnVuY3Rpb24gdXBkYXRlUGFzc3dvcmRTdHJlbmd0aChwYXNzd29yZCwgc3RyZW5ndGhJbmRpY2F0b3IpIHsNCiAgLy8gUmVzZXQgaW5kaWNhdG9yDQogIHN0cmVuZ3RoSW5kaWNhdG9yLnRleHRDb250ZW50ID0gIiI7DQoNCiAgLy8gRGVmaW5lIGNyaXRlcmlhDQogIGNvbnN0IG1pbkxlbmd0aCA9IDg7DQogIGNvbnN0IG1pblVwcGVyID0gMTsNCiAgY29uc3QgbWluTG93ZXIgPSAxOw0KICBjb25zdCBtaW5OdW1iZXJzID0gMTsNCiAgY29uc3QgbWluU3BlY2lhbCA9IDE7DQoNCiAgbGV0IHN0cmVuZ3RoID0gMDsNCg0KICAvLyBDaGVjayBsZW5ndGgNCiAgaWYgKHBhc3N3b3JkLmxlbmd0aCA+PSBtaW5MZW5ndGgpIHsNCiAgICBzdHJlbmd0aCsrOw0KICB9DQoNCiAgLy8gQ2hlY2sgdXBwZXJjYXNlIGxldHRlcnMNCiAgaWYgKC9bQS1aXS8udGVzdChwYXNzd29yZCkgJiYgcGFzc3dvcmQubWF0Y2goL1tBLVpdL2cpLmxlbmd0aCA+PSBtaW5VcHBlcikgew0KICAgIHN0cmVuZ3RoKys7DQogIH0NCg0KICAvLyBDaGVjayBsb3dlcmNhc2UgbGV0dGVycw0KICBpZiAoL1thLXpdLy50ZXN0KHBhc3N3b3JkKSAmJiBwYXNzd29yZC5tYXRjaCgvW2Etel0vZykubGVuZ3RoID49IG1pbkxvd2VyKSB7DQogICAgc3RyZW5ndGgrKzsNCiAgfQ0KDQogIC8vIENoZWNrIG51bWJlcnMNCiAgaWYgKC9cZC8udGVzdChwYXNzd29yZCkgJiYgcGFzc3dvcmQubWF0Y2goL1xkL2cpLmxlbmd0aCA+PSBtaW5OdW1iZXJzKSB7DQogICAgc3RyZW5ndGgrKzsNCiAgfQ0KDQogIC8vIENoZWNrIHNwZWNpYWwgY2hhcmFjdGVycw0KICBpZiAoDQogICAgL1teYS16QS1aMC05XS8udGVzdChwYXNzd29yZCkgJiYNCiAgICBwYXNzd29yZC5tYXRjaCgvW15hLXpBLVowLTldL2cpLmxlbmd0aCA+PSBtaW5TcGVjaWFsDQogICkgew0KICAgIHN0cmVuZ3RoKys7DQogIH0NCg0KICAvLyBVcGRhdGUgc3RyZW5ndGggaW5kaWNhdG9yDQogIHN3aXRjaCAoc3RyZW5ndGgpIHsNCiAgICBjYXNlIDA6DQogICAgY2FzZSAxOg0KICAgICAgc3RyZW5ndGhJbmRpY2F0b3IudGV4dENvbnRlbnQgPSAiV2VhayI7DQogICAgICBzdHJlbmd0aEluZGljYXRvci5zdHlsZS5jb2xvciA9ICJyZWQiOw0KICAgICAgYnJlYWs7DQogICAgY2FzZSAyOg0KICAgIGNhc2UgMzoNCiAgICAgIHN0cmVuZ3RoSW5kaWNhdG9yLnRleHRDb250ZW50ID0gIk1lZGl1bSI7DQogICAgICBzdHJlbmd0aEluZGljYXRvci5zdHlsZS5jb2xvciA9ICJvcmFuZ2UiOw0KICAgICAgYnJlYWs7DQogICAgY2FzZSA0Og0KICAgIGNhc2UgNToNCiAgICAgIHN0cmVuZ3RoSW5kaWNhdG9yLnRleHRDb250ZW50ID0gIlN0cm9uZyI7DQogICAgICBzdHJlbmd0aEluZGljYXRvci5zdHlsZS5jb2xvciA9ICJncmVlbiI7DQogICAgICBicmVhazsNCiAgICBkZWZhdWx0Og0KICAgICAgYnJlYWs7DQogIH0NCn0NCg0KICAgIA0KICAgIA0KICAgIA0KICAgIDwvc2NyaXB0Pg0KDQoNCg0KPD89ICR0aGlzLT5lbmRTZWN0aW9uKCkgPz4=")); ?>

Function Calls

base64_decode 1

Variables

None

Stats

MD5 7dd134ca944988d89f8b580019f0aa82
Eval Count 1
Decode Time 130 ms