PageSourceSearch

https://osalto.gal/js/app-80d97eff7c3642fd1c658f9ad51186ba.js?vsn=d

js osalto.gal collected 2026-09-24 22:53:37 UTC 1,717,455 bytes, 1 lines download raw bytes

1(()=>{var __webpack_modules__={17:(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__)=>{"use strict";eval('\n;// CONCATENATED MODULE: ./js/basicos.js\nfunction medidas() {\n  var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n  var h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;\n  h > w ? document.body.classList.add("portrait") : document.body.classList.remove("portrait");\n  h < w ? document.body.classList.add("landscape") : document.body.classList.remove("landscape");\n}\n;\nvar body = document.body,\n  html = document.documentElement;\nvar height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);\nfunction basicos_visible(el) {\n  if (el) {\n    const antelacion = 250;\n    const elem = el.getBoundingClientRect();\n    var altura = document.documentElement.clientHeight;\n    var isVisible = elem.top >= 0 && elem.top <= altura || elem.bottom >= 0 && elem.top <= altura || elem.top < altura + antelacion && elem.bottom > 0;\n    return isVisible;\n  } else {\n    return false;\n  }\n}\nfunction basicos_mostrar(clases) {\n  var mostrar = document.querySelectorAll(clases);\n  for (var i = 0; i < mostrar.length; i++) {\n    mostrar[i].style.opacity = 1;\n    mostrar[i].style.visibility = "visible";\n    mostrar[i].style.display = "block";\n  }\n}\nfunction basicos_ocultar(clases) {\n  var ocultar = document.querySelectorAll(clases);\n  for (var i = 0; i < ocultar.length; i++) {\n    ocultar[i].style.opacity = 0;\n    ocultar[i].style.visibility = "hidden";\n    ocultar[i].style.visibility = "none";\n  }\n}\n// EXTERNAL MODULE: ../deps/phoenix_html/priv/static/phoenix_html.js\nvar phoenix_html = __webpack_require__(458);\n// EXTERNAL MODULE: ./vendor/jquery.slugger.js\nvar jquery_slugger = __webpack_require__(70);\n;// CONCATENATED MODULE: ./js/publi.js\njQuery("document").ready(function ($) {\n  cambio_apanhos();\n  apanhos_swip();\n});\nfunction apanhos_swip() {\n  if ($(\'.swiper-socias\').length) {\n    var width = $(window).width();\n    if (width > 767) {\n      $(\'.swiper-socias .swiper-wrapper\').css("height", width / 2.1);\n    }\n  }\n}\n$(function () {\n  var $window = $(window);\n  var width = $window.width();\n  var height = $window.height();\n  setInterval(function () {\n    if (width != $window.width() || height != $window.height()) {\n      width = $window.width();\n      height = $window.height();\n      cambio_apanhos();\n    }\n  }, 300);\n});\nfunction cambio_apanhos() {\n  $(\'.videos .carousel-inner\').height($(\'.videos .carousel-item.active\').outerHeight());\n  var width = $(window).width();\n  if ($(window).width() > 769) {\n    $(".contenido .contenido .real .todo-el-ancho").each(function () {\n      console.log("cambio_apanhos");\n      var prop = $(this).attr("data-proporcion");\n      var width = $(this).width();\n      $(this).css("padding-bottom", function () {\n        return prop * width / 100;\n      });\n    });\n    var fijo_compartir = $(".fijo .compartir");\n    if (false) { var left; }\n    var left = (width - $("#menu-arriba .container").width()) / 2;\n    var video_texto = $(".video-texto");\n    if (video_texto) {\n      video_texto.css("padding-left", left);\n    }\n    $(".destacada1 .elem1.noencalada .resumen:first-of-type .responsively-lazy").css("overflow", "hidden").css("padding-bottom", "40%");\n    $(".destacada1 .elem1.noencalada .resumen:first-of-type .responsively-lazy img").css("top", "-20%").css("height", "140%");\n  } else {\n    $(".contenido .contenido img").css("width", "100%");\n  }\n\n  //var fotos = html.match(/{{([A-z.jpg]*)}}/);\n  //$(\'video,audio\').not(\'.no-mep,.fullscreen-bg__video\').mediaelementplayer({\n  //var player = new MediaElement("video-principal", {\n  //  var mediaE = document.getElementById("video-principal");\n  //  console.log("xxx")\n  //  console.log(mediaE);\n  //  var player = new MediaElement(mediaE, {\n  //    iconSprite: \'/js/mediaelement/mejs-controls.svg\',\n  //    stretching: \'responsive\' ,\n  //  });\n\n  var iframes = document.querySelectorAll(\'.articulo-contenido iframe\');
1\n  if (iframes && iframes.legth) {\n    for (var i = 0; i < iframes.length; i++) {\n      var medidas = iframes[i].Element.getBoundingClientRect();\n      var iframe_w = medidas.width;\n      var h = iframes[i].getAttribute("height");\n      var w = iframes[i].getAttribute("width");\n      var altura = iframe_w / w * h;\n      iframes[i].style.height = altura;\n    }\n  }\n}\n;\n$(\'.modal\').on(\'shown.bs.modal\', function (e) {\n  var modal_box = $(this).find(\'.modal\');\n  modal_box.css("display", "flex !important ");\n  var modal = $(this).find(\'.modal-dialog\');\n  var modalc = $(this).find(\'.modal-content\');\n  var modalo = $(this).find(\'.mejs__container iframe\');\n  var rw = modal.width();\n  var h = $(this).find(\'.mejs__container iframe\').attr("height");\n  var w = $(this).find(\'.mejs__container iframe\').attr("width");\n  var altura = rw / w * h;\n  $(this).find(\'.mejs__layer\').css("height", altura).css("width", rw);\n  $(this).find(\'.mejs__container\').css("height", altura).css("width", rw);\n  modalo.css("width", rw).css("height", altura);\n  //modalmodal.css(\'margin-top\', (($(window).height() - (parseInt(modalc.height() )))/2));\n});\n$(\'iframe-off\').each(function () {\n  function injectCSS() {\n    $iframe.contents().find(\'head\').append($("<style type=\'text/css\'>" + ".player .vp-cards, .player .vp-controls { display: none !important; } " + "</style>"));\n  }\n  var $iframe = $(this);\n  $iframe.on(\'load\', injectCSS);\n  injectCSS();\n});\nfunction eliminarID(elementId) {\n  var element = document.getElementById(elementId);\n  element.parentNode.removeChild(element);\n}\nif (document.getElementById("close-faldon")) {\n  document.getElementById("close-faldon").addEventListener("click", function () {\n    eliminarID("faldon-container");\n  });\n}\n// EXTERNAL MODULE: ./js/formularios.js\nvar formularios = __webpack_require__(587);\n// EXTERNAL MODULE: ./vendor/postscribe.min.js\nvar postscribe_min = __webpack_require__(782);\nvar postscribe_min_default = /*#__PURE__*/__webpack_require__.n(postscribe_min);\n;// CONCATENATED MODULE: ../deps/phoenix/priv/static/phoenix.mjs\n// js/phoenix/utils.js\nvar closure = (value) => {\n  if (typeof value === "function") {\n    return value;\n  } else {\n    let closure2 = function() {\n      return value;\n    };\n    return closure2;\n  }\n};\n\n// js/phoenix/constants.js\nvar globalSelf = typeof self !== "undefined" ? self : null;\nvar phxWindow = typeof window !== "undefined" ? window : null;\nvar global = globalSelf || phxWindow || globalThis;\nvar DEFAULT_VSN = "2.0.0";\nvar SOCKET_STATES = { connecting: 0, open: 1, closing: 2, closed: 3 };\nvar MAX_LONGPOLL_BATCH_SIZE = 100;\nvar DEFAULT_TIMEOUT = 1e4;\nvar WS_CLOSE_NORMAL = 1e3;\nvar CHANNEL_STATES = {\n  closed: "closed",\n  errored: "errored",\n  joined: "joined",\n  joining: "joining",\n  leav
1ing: "leaving"\n};\nvar CHANNEL_EVENTS = {\n  close: "phx_close",\n  error: "phx_error",\n  join: "phx_join",\n  reply: "phx_reply",\n  leave: "phx_leave"\n};\nvar TRANSPORTS = {\n  longpoll: "longpoll",\n  websocket: "websocket"\n};\nvar XHR_STATES = {\n  complete: 4\n};\nvar AUTH_TOKEN_PREFIX = "base64url.bearer.phx.";\n\n// js/phoenix/push.js\nvar Push = class {\n  constructor(channel, event, payload, timeout) {\n    this.channel = channel;\n    this.event = event;\n    this.payload = payload || function() {\n      return {};\n    };\n    this.receivedResp = null;\n    this.timeout = timeout;\n    this.timeoutTimer = null;\n    this.recHooks = [];\n    this.sent = false;\n  }\n  /**\n   *\n   * @param {number} timeout\n   */\n  resend(timeout) {\n    this.timeout = timeout;\n    this.reset();\n    this.send();\n  }\n  /**\n   *\n   */\n  send() {\n    if (this.hasReceived("timeout")) {\n      return;\n    }\n    this.startTimeout();\n    this.sent = true;\n    this.channel.socket.push({\n      topic: this.channel.topic,\n      event: this.event,\n      payload: this.payload(),\n      ref: this.ref,\n      join_ref: this.channel.joinRef()\n    });\n  }\n  /**\n   *\n   * @param {*} status\n   * @param {*} callback\n   */\n  receive(status, callback) {\n    if (this.hasReceived(status)) {\n      callback(this.receivedResp.response);\n    }\n    this.recHooks.push({ status, callback });\n    return this;\n  }\n  /**\n   * @private\n   */\n  reset() {\n    this.cancelRefEvent();\n    this.ref = null;\n    this.refEvent = null;\n    this.receivedResp = null;\n    this.sent = false;\n  }\n  /**\n   * @private\n   */\n  matchReceive({ status, response, _ref }) {\n    this.recHooks.filter((h) => h.status === status).forEach((h) => h.callback(response));\n  }\n  /**\n   * @private\n   */\n  cancelRefEvent() {\n    if (!this.refEvent) {\n      return;\n    }\n    this.channel.off(this.refEvent);\n  }\n  /**\n   * @private\n   */\n  cancelTimeout() {\n    clearTimeout(this.timeoutTimer);\n    this.timeoutTimer = null;\n  }\n  /**\n   * @private\n   */\n  startTimeout() {\n    if (this.timeoutTimer) {\n      this.cancelTimeout();\n    }\n    this.ref = this.channel.socket.makeRef();\n    this.refEvent = this.channel.replyEventName(this.ref);\n    this.channel.on(this.refEvent, (payload) => {\n      this.cancelRefEvent();\n      this.cancelTimeout();\n      this.receivedResp = payload;\n      this.matchReceive(payload);\n    });\n    this.timeoutTimer = setTimeout(() => {\n      this.trigger("timeout", {});\n    }, this.timeout);\n  }\n  /**\n   * @private\n   */\n  hasReceived(status) {\n    return this.receivedResp && this.receivedResp.status === status;\n  }\n  /**\n   * @private\n   */\n  trigger(status, response) {\n    this.channel.trigger(this.refEvent, { status, response });\n  }\n};\n\n// js/phoenix/timer.js\nvar Timer = class {\n  constructor(callback, timerCalc) {\n    this.callback = callback;\n    this.timerCalc = timerCalc;\n    this.timer = null;\n    this.tries = 0;\n  }\n  reset() {\n    this.tries = 0;\n    clearTimeout(this.timer);\n  }\n  /**\n   * Cancels any previous scheduleTimeout and schedules callback\n   */\n  scheduleTimeout() {\n    clearTimeout(this.timer);\n    this.timer = setTimeout(() => {\n      this.tries = this.tries + 1;\n      this.callback();\n    }, this.timerCalc(this.tries + 1));\n  }\n};\n\n// js/phoenix/channel.js\nvar Channel = class {\n  constructor(topic, params, socket) {\n    this.state = CHANNEL_STATES.closed;\n    this.topic = topic;\n    this.params = closure(params || {});\n    this.socket = socket;\n    this.bindings = [];\n    this.bindingRef = 0;\n    this.timeout = this.socket.timeout;\n    this.joinedOnce = false;\n    this.joinPush = new Push(this, CHANNEL_EVENTS.join, this.params, this.timeout);\n    this.pushBuffer = [];\n    this.stateChangeRefs = [];\n    this.rejoinTimer = new Timer(() => {\n      if (this.socket.isConnected()) {\n        this.rejoin();\n      }\n    }, this.socket.rejoinAfterMs);\n    this.stateChangeRefs.push(this.socket.onError(() => this.rejoinTimer.reset()));\n    this.stateChangeRefs.push(\n      this.socket.onOpen(() =>
1 {\n        this.rejoinTimer.reset();\n        if (this.isErrored()) {\n          this.rejoin();\n        }\n      })\n    );\n    this.joinPush.receive("ok", () => {\n      this.state = CHANNEL_STATES.joined;\n      this.rejoinTimer.reset();\n      this.pushBuffer.forEach((pushEvent) => pushEvent.send());\n      this.pushBuffer = [];\n    });\n    this.joinPush.receive("error", () => {\n      this.state = CHANNEL_STATES.errored;\n      if (this.socket.isConnected()) {\n        this.rejoinTimer.scheduleTimeout();\n      }\n    });\n    this.onClose(() => {\n      this.rejoinTimer.reset();\n      if (this.socket.hasLogger()) this.socket.log("channel", `close ${this.topic} ${this.joinRef()}`);\n      this.state = CHANNEL_STATES.closed;\n      this.socket.remove(this);\n    });\n    this.onError((reason) => {\n      if (this.socket.hasLogger()) this.socket.log("channel", `error ${this.topic}`, reason);\n      if (this.isJoining()) {\n        this.joinPush.reset();\n      }\n      this.state = CHANNEL_STATES.errored;\n      if (this.socket.isConnected()) {\n        this.rejoinTimer.scheduleTimeout();\n      }\n    });\n    this.joinPush.receive("timeout", () => {\n      if (this.socket.hasLogger()) this.socket.log("channel", `timeout ${this.topic} (${this.joinRef()})`, this.joinPush.timeout);\n      let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), this.timeout);\n      leavePush.send();\n      this.state = CHANNEL_STATES.errored;\n      this.joinPush.reset();\n      if (this.socket.isConnected()) {\n        this.rejoinTimer.scheduleTimeout();\n      }\n    });\n    this.on(CHANNEL_EVENTS.reply, (payload, ref) => {\n      this.trigger(this.replyEventName(ref), payload);\n    });\n  }\n  /**\n   * Join the channel\n   * @param {integer} timeout\n   * @returns {Push}\n   */\n  join(timeout = this.timeout) {\n    if (this.joinedOnce) {\n      throw new Error("tried to join multiple times. \'join\' can only be called a single time per channel instance");\n    } else {\n      this.timeout = timeout;\n      this.joinedOnce = true;\n      this.rejoin();\n      return this.joinPush;\n    }\n  }\n  /**\n   * Hook into channel close\n   * @param {Function} callback\n   */\n  onClose(callback) {\n    this.on(CHANNEL_EVENTS.close, callback);\n  }\n  /**\n   * Hook into channel errors\n   * @param {Function} callback\n   */\n  onError(callback) {\n    return this.on(CHANNEL_EVENTS.error, (reason) => callback(reason));\n  }\n  /**\n   * Subscribes on channel events\n   *\n   * Subscription returns a ref counter, which can be used later to\n   * unsubscribe the exact event listener\n   *\n   * @example\n   * const ref1 = channel.on("event", do_stuff)\n   * const ref2 = channel.on("event", do_other_stuff)\n   * channel.off("event", ref1)\n   * // Since unsubscription, do_stuff won\'t fire,\n   * // while do_other_stuff will keep firing on the "event"\n   *\n   * @param {string} event\n   * @param {Function} callback\n   * @returns {integer} ref\n   */\n  on(event, callback) {\n    let ref = this.bindingRef++;\n    this.bindings.push({ event, ref, callback });\n    return ref;\n  }\n  /**\n   * Unsubscribes off of channel events\n   *\n   * Use the ref returned from a channel.on() to unsubscribe one\n   * handler, or pass nothing for the ref to unsubscribe all\n   * handlers for the given event.\n   *\n   * @example\n   * // Unsubscribe the do_stuff handler\n   * const ref1 = channel.on("event", do_stuff)\n   * channel.off("event", ref1)\n   *\n   * // Unsubscribe all handlers from event\n   * channel.off("event")\n   *\n   * @param {string} event\n   * @param {integer} ref\n   */\n  off(event, ref) {\n    this.bindings = this.bindings.filter((bind) => {\n      return !(bind.event === event && (typeof ref === "undefined" || ref === bind.ref));\n    });\n  }\n  /**\n   * @private\n   */\n  canPush() {\n    return this.socket.isConnected() && this.isJoined();\n  }\n  /**\n   * Sends a message `event` to phoenix with the payload `payload`.\n   * Phoenix receives this in the `handle_in(event, payload, socket)`\n   * function. if phoenix replies or it times out (default 10000ms),\n   * then optionally the reply can be received.\n   *\n   * @example\n   * channel.push("event")\n   *   .receive("ok", payload => console.log("phoenix replied:", payload))\n   *   .receive("error", err => console.log("phoenix errored", err))\n   *   .receive("timeout", () => console.log("timed out pushing"))\n   * @param {string} event\n   * @param {Object} payload\n   * @param {number} [timeout]\n   * @returns {Push}\n   */\n  push(event, payload, timeout = this.timeout) {\n    payload = payload || {};\n    if (!this.joinedOnce) {\n      throw new Error(`tried to push \'${event}\' to \'${this.topic}\' before joining. Use channel.join() before pushing events`);\n    }
1\n    let pushEvent = new Push(this, event, function() {\n      return payload;\n    }, timeout);\n    if (this.canPush()) {\n      pushEvent.send();\n    } else {\n      pushEvent.startTimeout();\n      this.pushBuffer.push(pushEvent);\n    }\n    return pushEvent;\n  }\n  /** Leaves the channel\n   *\n   * Unsubscribes from server events, and\n   * instructs channel to terminate on server\n   *\n   * Triggers onClose() hooks\n   *\n   * To receive leave acknowledgements, use the `receive`\n   * hook to bind to the server ack, ie:\n   *\n   * @example\n   * channel.leave().receive("ok", () => alert("left!") )\n   *\n   * @param {integer} timeout\n   * @returns {Push}\n   */\n  leave(timeout = this.timeout) {\n    this.rejoinTimer.reset();\n    this.joinPush.cancelTimeout();\n    this.state = CHANNEL_STATES.leaving;\n    let onClose = () => {\n      if (this.socket.hasLogger()) this.socket.log("channel", `leave ${this.topic}`);\n      this.trigger(CHANNEL_EVENTS.close, "leave");\n    };\n    let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), timeout);\n    leavePush.receive("ok", () => onClose()).receive("timeout", () => onClose());\n    leavePush.send();\n    if (!this.canPush()) {\n      leavePush.trigger("ok", {});\n    }\n    return leavePush;\n  }\n  /**\n   * Overridable message hook\n   *\n   * Receives all events for specialized message handling\n   * before dispatching to the channel callbacks.\n   *\n   * Must return the payload, modified or unmodified\n   * @param {string} event\n   * @param {Object} payload\n   * @param {integer} ref\n   * @returns {Object}\n   */\n  onMessage(_event, payload, _ref) {\n    return payload;\n  }\n  /**\n   * @private\n   */\n  isMember(topic, event, payload, joinRef) {\n    if (this.topic !== topic) {\n      return false;\n    }\n    if (joinRef && joinRef !== this.joinRef()) {\n      if (this.socket.hasLogger()) this.socket.log("channel", "dropping outdated message", { topic, event, payload, joinRef });\n      return false;\n    } else {\n      return true;\n    }\n  }\n  /**\n   * @private\n   */\n  joinRef() {\n    return this.joinPush.ref;\n  }\n  /**\n   * @private\n   */\n  rejoin(timeout = this.timeout) {\n    if (this.isLeaving()) {\n      return;\n    }\n    this.socket.leaveOpenTopic(this.topic);\n    this.state = CHANNEL_STATES.joining;\n    this.joinPush.resend(timeout);\n  }\n  /**\n   * @private\n   */\n  trigger(event, payload, ref, joinRef) {\n    let handledPayload = this.onMessage(event, payload, ref, joinRef);\n    if (payload && !handledPayload) {\n      throw new Error("channel onMessage callbacks must return the payload, modified or unmodified");\n    }\n    let eventBindings = this.bindings.filter((bind) => bind.event === event);\n    for (let i = 0; i < eventBindings.length; i++) {\n      let bind = eventBindings[i];\n      bind.callback(handledPayload, ref, joinRef || this.joinRef());\n    }\n  }\n  /**\n   * @private\n   */\n  replyEventName(ref) {\n    return `chan_reply_${ref}`;\n  }\n  /**\n   * @private\n   */\n  isClosed() {\n    return this.state === CHANNEL_STATES.closed;\n  }\n  /**\n   * @private\n   */\n  isErrored() {\n    return this.state === CHANNEL_STATES.errored;\n  }\n  /**\n   * @private\n   */\n  isJoined() {\n    return this.state === CHANNEL_STATES.joined;\n  }\n  /**\n   * @private\n   */\n  isJoining() {\n    return this.state === CHANNEL_STATES.joining;\n  }\n  /**\n   * @private\n   */\n  isLeaving() {\n    return this.state === CHANNEL_STATES.leaving;\n  }\n};\n\n// js/phoenix/ajax.js\nvar Ajax = class {\n  static request(method, endPoint, headers, body, timeout, ontimeout, callback) {\n    if (global.XDomainRequest) {\n      let req = new global.XDomainRequest();\n      return this.xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback);\n    } else if (global.XMLHttpRequest) {\n      let req = new global.XMLHttpRequest();\n      return this.xhrRequest(req, method, endPoint, headers, body, timeout, ontimeout, callback);\n    } else if (global.fetch && global.AbortController) {\n      return this.fetchRequest(method, endPoint, headers, body, timeout, ontimeout, callback);\n    } else {\n      throw new Error("No suitable XMLHttpRequest implementation found");\n    }\n  }\n  static fetchRequest(method, endPoint, headers, body, timeout, ontimeout, callback) {\n    let options = {\n      method,\n      headers,\n      body\n    };
1\n    let controller = null;\n    if (timeout) {\n      controller = new AbortController();\n      const _timeoutId = setTimeout(() => controller.abort(), timeout);\n      options.signal = controller.signal;\n    }\n    global.fetch(endPoint, options).then((response) => response.text()).then((data) => this.parseJSON(data)).then((data) => callback && callback(data)).catch((err) => {\n      if (err.name === "AbortError" && ontimeout) {\n        ontimeout();\n      } else {\n        callback && callback(null);\n      }\n    });\n    return controller;\n  }\n  static xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback) {\n    req.timeout = timeout;\n    req.open(method, endPoint);\n    req.onload = () => {\n      let response = this.parseJSON(req.responseText);\n      callback && callback(response);\n    };\n    if (ontimeout) {\n      req.ontimeout = ontimeout;\n    }\n    req.onprogress = () => {\n    };\n    req.send(body);\n    return req;\n  }\n  static xhrRequest(req, method, endPoint, headers, body, timeout, ontimeout, callback) {\n    req.open(method, endPoint, true);\n    req.timeout = timeout;\n    for (let [key, value] of Object.entries(headers)) {\n      req.setRequestHeader(key, value);\n    }\n    req.onerror = () => callback && callback(null);\n    req.onreadystatechange = () => {\n      if (req.readyState === XHR_STATES.complete && callback) {\n        let response = this.parseJSON(req.responseText);\n        callback(response);\n      }\n    };\n    if (ontimeout) {\n      req.ontimeout = ontimeout;\n    }\n    req.send(body);\n    return req;\n  }\n  static parseJSON(resp) {\n    if (!resp || resp === "") {\n      return null;\n    }\n    try {\n      return JSON.parse(resp);\n    } catch {\n      console && console.log("failed to parse JSON response", resp);\n      return null;\n    }\n  }\n  static serialize(obj, parentKey) {\n    let queryStr = [];\n    for (var key in obj) {\n      if (!Object.prototype.hasOwnProperty.call(obj, key)) {\n        continue;\n      }\n      let paramKey = parentKey ? `${parentKey}[${key}]` : key;\n      let paramVal = obj[key];\n      if (typeof paramVal === "object") {\n        queryStr.push(this.serialize(paramVal, paramKey));\n      } else {\n        queryStr.push(encodeURIComponent(paramKey) + "=" + encodeURIComponent(paramVal));\n      }\n    }\n    return queryStr.join("&");\n  }\n  static appendParams(url, params) {\n    if (Object.keys(params).length === 0) {\n      return url;\n    }\n    let prefix = url.match(/\\?/) ? "&" : "?";\n    return `${url}${prefix}${this.serialize(params)}`;\n  }\n};\n\n// js/phoenix/longpoll.js\nvar arrayBufferToBase64 = (buffer) => {\n  let binary = "";\n  let bytes = new Uint8Array(buffer);\n  let len = bytes.byteLength;\n  for (let i = 0; i < len; i++) {\n    binary += String.fromCharCode(bytes[i]);\n  }\n  return btoa(binary);\n};\nvar LongPoll = class {\n  constructor(endPoint, protocols) {\n    if (protocols && protocols.length === 2 && protocols[1].startsWith(AUTH_TOKEN_PREFIX)) {\n      this.authToken = atob(protocols[1].slice(AUTH_TOKEN_PREFIX.length));\n    }\n    this.endPoint = null;\n    this.token = null;\n    this.skipHeartbeat = true;\n    this.reqs = /* @__PURE__ */ new Set();\n    this.awaitingBatchAck = false;\n    this.currentBatch = null;\n    this.currentBatchTimer = null;\n    this.batchBuffer = [];\n    this.onopen = function() {\n    };\n    this.onerror = function() {\n    };\n    this.onmessage = function() {\n    };\n    this.onclose = function() {\n    };\n    this.pollEndpoint = this.normalizeEndpoint(endPoint);\n    this.readyState = SOCKET_STATES.connecting;\n    setTimeout(() => this.poll(), 0);\n  }\n  normalizeEndpoint(endPoint) {\n    return endPoint.replace("ws://", "http://").replace("wss://", "https://").replace(new RegExp("(.*)/" + TRANSPORTS.websocket), "$1/" + TRANSPORTS.longpoll);\n  }\n  endpointURL() {\n    return Ajax.appendParams(this.pollEndpoint, { token: this.token });\n  }\n  closeAndRetry(code, reason, wasClean) {\n    this.close(code, reason, wasClean);\n    this.readyState = SOCKET_STATES.connecting;\n  }
1\n  ontimeout() {\n    this.onerror("timeout");\n    this.closeAndRetry(1005, "timeout", false);\n  }\n  isActive() {\n    return this.readyState === SOCKET_STATES.open || this.readyState === SOCKET_STATES.connecting;\n  }\n  poll() {\n    const headers = { "Accept": "application/json" };\n    if (this.authToken) {\n      headers["X-Phoenix-AuthToken"] = this.authToken;\n    }\n    this.ajax("GET", headers, null, () => this.ontimeout(), (resp) => {\n      if (resp) {\n        var { status, token, messages } = resp;\n        if (status === 410 && this.token !== null) {\n          this.onerror(410);\n          this.closeAndRetry(3410, "session_gone", false);\n          return;\n        }\n        this.token = token;\n      } else {\n        status = 0;\n      }\n      switch (status) {\n        case 200:\n          messages.forEach((msg) => {\n            setTimeout(() => this.onmessage({ data: msg }), 0);\n          });\n          this.poll();\n          break;\n        case 204:\n          this.poll();\n          break;\n        case 410:\n          this.readyState = SOCKET_STATES.open;\n          this.onopen({});\n          this.poll();\n          break;\n        case 403:\n          this.onerror(403);\n          this.close(1008, "forbidden", false);\n          break;\n        case 0:\n        case 500:\n          this.onerror(500);\n          this.closeAndRetry(1011, "internal server error", 500);\n          break;\n        default:\n          throw new Error(`unhandled poll status ${status}`);\n      }\n    });\n  }\n  // we collect all pushes within the current event loop by\n  // setTimeout 0, which optimizes back-to-back procedural\n  // pushes against an empty buffer\n  send(body) {\n    if (typeof body !== "string") {\n      body = arrayBufferToBase64(body);\n    }\n    if (this.currentBatch) {\n      this.currentBatch.push(body);\n    } else if (this.awaitingBatchAck) {\n      this.batchBuffer.push(body);\n    } else {\n      this.currentBatch = [body];\n      this.currentBatchTimer = setTimeout(() => {\n        this.batchSend(this.currentBatch);\n        this.currentBatch = null;\n      }, 0);\n    }\n  }\n  batchSend(messages, offset = 0) {\n    this.awaitingBatchAck = true;\n    const next = offset + MAX_LONGPOLL_BATCH_SIZE;\n    const batch = messages.slice(offset, next);\n    this.ajax("POST", { "Content-Type": "application/x-ndjson" }, batch.join("\\n"), () => this.onerror("timeout"), (resp) => {\n      if (!resp || resp.status !== 200) {\n        this.awaitingBatchAck = false;\n        this.onerror(resp && resp.status);\n        this.closeAndRetry(1011, "internal server error", false);\n      } else if (next < messages.length) {\n        this.batchSend(messages, next);\n      } else if (this.batchBuffer.length > 0) {\n        this.batchSend(this.batchBuffer);\n        this.batchBuffer = [];\n      } else {\n        this.awaitingBatchAck = false;\n      }\n    });\n  }\n  close(code, reason, wasClean) {\n    for (let req of this.reqs) {\n      req.abort();\n    }\n    this.readyState = SOCKET_STATES.closed;\n    let opts = Object.assign({ code: 1e3, reason: void 0, wasClean: true }, { code, reason, wasClean });\n    this.batchBuffer = [];\n    clearTimeout(this.currentBatchTimer);\n    this.currentBatchTimer = null;\n    if (typeof CloseEvent !== "undefined") {\n      this.onclose(new CloseEvent("close", opts));\n    } else {\n      this.onclose(opts);\n    }\n  }\n  ajax(method, headers, body, onCallerTimeout, callback) {\n    let req;\n    let ontimeout = () => {\n      this.reqs.delete(req);\n      onCallerTimeout();\n    };\n    req = Ajax.request(method, this.endpointURL(), headers, body, this.timeout, ontimeout, (resp) => {\n      this.reqs.delete(req);\n      if (this.isActive()) {\n        callback(resp);\n      }\n    });\n    this.reqs.add(req);\n  }\n};\n\n// js/phoenix/presence.js\nvar Presence = class _Presence {\n  constructor(channel, opts = {}) {\n    let events = opts.events || { state: "presence_state", diff: "presence_diff" };\n    this.state = /* @__PURE__ */ Object.create(null);\n    this.pendingDiffs = [];\n    this.channel = channel;\n    this.joinRef = null;
1\n    this.caller = {\n      onJoin: function() {\n      },\n      onLeave: function() {\n      },\n      onSync: function() {\n      }\n    };\n    this.channel.on(events.state, (newState) => {\n      let { onJoin, onLeave, onSync } = this.caller;\n      this.joinRef = this.channel.joinRef();\n      this.state = _Presence.syncState(this.state, newState, onJoin, onLeave);\n      this.pendingDiffs.forEach((diff) => {\n        this.state = _Presence.syncDiff(this.state, diff, onJoin, onLeave);\n      });\n      this.pendingDiffs = [];\n      onSync();\n    });\n    this.channel.on(events.diff, (diff) => {\n      let { onJoin, onLeave, onSync } = this.caller;\n      if (this.inPendingSyncState()) {\n        this.pendingDiffs.push(diff);\n      } else {\n        this.state = _Presence.syncDiff(this.state, diff, onJoin, onLeave);\n        onSync();\n      }\n    });\n  }\n  onJoin(callback) {\n    this.caller.onJoin = callback;\n  }\n  onLeave(callback) {\n    this.caller.onLeave = callback;\n  }\n  onSync(callback) {\n    this.caller.onSync = callback;\n  }\n  list(by) {\n    return _Presence.list(this.state, by);\n  }\n  inPendingSyncState() {\n    return !this.joinRef || this.joinRef !== this.channel.joinRef();\n  }\n  // lower-level public static API\n  /**\n   * Used to sync the list of presences on the server\n   * with the client\'s state. An optional `onJoin` and `onLeave` callback can\n   * be provided to react to changes in the client\'s local presences across\n   * disconnects and reconnects with the server.\n   *\n   * @returns {Presence}\n   */\n  static syncState(currentState, newState, onJoin, onLeave) {\n    let state = this.toNullProtoObj(this.clone(currentState));\n    newState = this.toNullProtoObj(newState);\n    let joins = /* @__PURE__ */ Object.create(null);\n    let leaves = /* @__PURE__ */ Object.create(null);\n    this.map(state, (key, presence) => {\n      if (!newState[key]) {\n        leaves[key] = presence;\n      }\n    });\n    this.map(newState, (key, newPresence) => {\n      let currentPresence = state[key];\n      if (currentPresence) {\n        let newRefs = newPresence.metas.map((m) => m.phx_ref);\n        let curRefs = currentPresence.metas.map((m) => m.phx_ref);\n        let joinedMetas = newPresence.metas.filter((m) => curRefs.indexOf(m.phx_ref) < 0);\n        let leftMetas = currentPresence.metas.filter((m) => newRefs.indexOf(m.phx_ref) < 0);\n        if (joinedMetas.length > 0) {\n          joins[key] = newPresence;\n          joins[key].metas = joinedMetas;\n        }\n        if (leftMetas.length > 0) {\n          leaves[key] = this.clone(currentPresence);\n          leaves[key].metas = leftMetas;\n        }\n      } else {\n        joins[key] = newPresence;\n      }\n    });\n    return this.syncDiff(state, { joins, leaves }, onJoin, onLeave);\n  }\n  /**\n   *\n   * Used to sync a diff of presence join and leave\n   * events from the server, as they happen. Like `syncState`, `syncDiff`\n   * accepts optional `onJoin` and `onLeave` callbacks to react to a user\n   * joining or leaving from a device.\n   *\n   * @returns {Presence}\n   */\n  static syncDiff(state, diff, onJoin, onLeave) {\n    state = this.toNullProtoObj(state);\n    let { joins, leaves } = this.clone(diff);\n    if (!onJoin) {\n      onJoin = function() {\n      };\n    }\n    if (!onLeave) {\n      onLeave = function() {\n      };\n    }\n    this.map(joins, (key, newPresence) => {\n      let currentPresence = state[key];\n      state[key] = this.clone(newPresence);\n      if (currentPresence) {\n        let joinedRefs = state[key].metas.map((m) => m.phx_ref);\n        let curMetas = currentPresence.metas.filter((m) => joinedRefs.indexOf(m.phx_ref) < 0);\n        state[key].metas.unshift(...curMetas);\n      }\n      onJoin(key, currentPresence, newPresence);\n    });\n    this.map(leaves, (key, leftPresence) => {\n      let currentPresence = state[key];\n      if (!currentPresence) {\n        return;\n      }\n      let refsToRemove = leftPresence.metas.map((m) => m.phx_ref);\n      currentPresence.metas = currentPresence.metas.filter((p) => {\n        return refsToRemove.indexOf(p.phx_ref) < 0;\n      });\n      onLeave(key, currentPresence, leftPresence);\n      if (currentPresence.metas.length === 0) {\n        delete state[key];\n      }\n    });\n    return state;\n  }\n  /**\n   * Returns the array of presences, with selected metadata.\n   *\n   * @param {Object} presences\n   * @param {Function} chooser\n   *\n   * @returns {Presence}
1\n   */\n  static list(presences, chooser) {\n    if (!chooser) {\n      chooser = function(key, pres) {\n        return pres;\n      };\n    }\n    return this.map(presences, (key, presence) => {\n      return chooser(key, presence);\n    });\n  }\n  // private\n  static map(obj, func) {\n    return Object.getOwnPropertyNames(obj).map((key) => func(key, obj[key]));\n  }\n  // Presence keys are chosen on the server and may collide with\n  // Object.prototype properties ("__proto__", "constructor", ...), so any\n  // object indexed by presence key must not have a prototype chain\n  //\n  // TODO: replace the null-prototype objects with Maps in Phoenix 2.0\n  // (breaking change for the lower-level static API)\n  static toNullProtoObj(obj) {\n    if (Object.getPrototypeOf(obj) === null) {\n      return obj;\n    }\n    let cleaned = /* @__PURE__ */ Object.create(null);\n    Object.getOwnPropertyNames(obj).forEach((key) => {\n      cleaned[key] = obj[key];\n    });\n    return cleaned;\n  }\n  static clone(obj) {\n    return JSON.parse(JSON.stringify(obj));\n  }\n};\n\n// js/phoenix/serializer.js\nvar serializer_default = {\n  HEADER_LENGTH: 1,\n  META_LENGTH: 4,\n  KINDS: { push: 0, reply: 1, broadcast: 2 },\n  encode(msg, callback) {\n    if (msg.payload.constructor === ArrayBuffer) {\n      return callback(this.binaryEncode(msg));\n    } else {\n      let payload = [msg.join_ref, msg.ref, msg.topic, msg.event, msg.payload];\n      return callback(JSON.stringify(payload));\n    }\n  },\n  decode(rawPayload, callback) {\n    if (rawPayload.constructor === ArrayBuffer) {\n      return callback(this.binaryDecode(rawPayload));\n    } else {\n      let [join_ref, ref, topic, event, payload] = JSON.parse(rawPayload);\n      return callback({ join_ref, ref, topic, event, payload });\n    }\n  },\n  // private\n  binaryEncode(message) {\n    let { join_ref, ref, event, topic, payload } = message;\n    let encoder = new TextEncoder();\n    let joinRefBytes = encoder.encode(join_ref);\n    let refBytes = encoder.encode(ref);\n    let topicBytes = encoder.encode(topic);\n    let eventBytes = encoder.encode(event);\n    this.assertFieldSize(joinRefBytes.byteLength, "join_ref");\n    this.assertFieldSize(refBytes.byteLength, "ref");\n    this.assertFieldSize(topicBytes.byteLength, "topic");\n    this.assertFieldSize(eventBytes.byteLength, "event");\n    let metaLength = this.META_LENGTH + joinRefBytes.byteLength + refBytes.byteLength + topicBytes.byteLength + eventBytes.byteLength;\n    let header = new ArrayBuffer(this.HEADER_LENGTH + metaLength);\n    let headerBytes = new Uint8Array(header);\n    let view = new DataView(header);\n    let offset = 0;\n    view.setUint8(offset++, this.KINDS.push);\n    view.setUint8(offset++, joinRefBytes.byteLength);\n    view.setUint8(offset++, refBytes.byteLength);\n    view.setUint8(offset++, topicBytes.byteLength);\n    view.setUint8(offset++, eventBytes.byteLength);\n    headerBytes.set(joinRefBytes, offset);\n    offset += joinRefBytes.byteLength;\n    headerBytes.set(refBytes, offset);\n    offset += refBytes.byteLength;\n    headerBytes.set(topicBytes, offset);\n    offset += topicBytes.byteLength;\n    headerBytes.set(eventBytes, offset);\n    offset += eventBytes.byteLength;\n    var combined = new Uint8Array(header.byteLength + payload.byteLength);\n    combined.set(headerBytes, 0);\n    combined.set(new Uint8Array(payload), header.byteLength);\n    return combined.buffer;\n  },\n  assertFieldSize(size, name) {\n    if (size > 255) {\n      throw new Error(`unable to convert ${name} to binary: must be less than or equal to 255 bytes, but is ${size} bytes`);\n    }\n  },\n  binaryDecode(buffer) {\n    let view = new DataView(buffer);\n    let kind = view.getUint8(0);\n    let decoder = new TextDecoder();\n    switch (kind) {\n      case this.KINDS.push:\n        return this.decodePush(buffer, view, decoder);\n      case this.KINDS.reply:\n        return this.decodeReply(buffer, view, decoder);\n      case this.KINDS.broadcast:\n        return this.decodeBroadcast(buffer, view, decoder);\n    }\n  },\n  decodePush(buffer, view, decoder) {\n    let joinRefSize = view.getUint8(1);\n    let topicSize = view.getUint8(2);\n    let eventSize = view.getUint8(3);\n    let offset = this.HEADER_LENGTH + this.META_LENGTH - 1;\n    let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize));\n    offset = offset + joinRefSize;\n    let topic = decoder.decode(buffer.slice(offset, offset + topicSize));\n    offset = offset + topicSize;\n    let event = decoder.decode(buffer.slice(offset, offset + eventSize));\n    offset = offset + eventSize;\n    let data = buffer.slice(offset, buffer.byteLength);\n    return { join_ref: joinRef, ref: null, topic, event, payload: data };\n  },\n  decodeReply(buffer, view, decoder) {\n    let joinRefSize = view.getUint8(1);\n    let refSize = view.getUint8(2);\n    let topicSize = view.getUint8(3);\n    let eventSize = view.getUint8(4);\n    let offset = this.HEADER_LENGTH + this.META_LENGTH;\n    let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize));\n    offset = offset + joinRefSize;\n    let ref = decoder.decode(buffer.slice(offset, offset + refSize));\n    offset = offset + refSize;\n    let topic = decoder.decode(buffer.slice(offset, offset + topicSize));\n    offset = offset + topicSize;\n    let event = decoder.decode(buffer.slice(offset, offset + eventSize));\n    offset = offset + eventSize;\n    let data = buffer.slice(offset, buffer.byteLength);\n    let payload = { status: event, response: data };\n    return { join_ref: joinRef, ref, topic, event: CHANNEL_EVENTS.reply, payload };\n  },\n  decodeBroadcast(buffer, view, decoder) {\n    let topicSize = view.getUint8(1);\n    let eventSize = view.getUint8(2);\n    let offset = this.HEADER_LENGTH + 2;\n    let topic = decoder.decode(buffer.slice(offset, offset + topicSize));\n    offset = offset + topicSize;\n    let event = decoder.decode(buffer.slice(offset, offset + eventSize));\n    offset = offset + eventSize;\n    let data = buffer.slice(offset, buffer.byteLength);\n    return { join_ref: null, ref: null, topic, event, payload: data };\n  }\n};\n\n// js/phoenix/socket.js\nvar Socket = class {\n  constructor(endPoint, opts = {}) {\n    this.stateChangeCallbacks = { open: [], close: [], error: [], message: [] };\n    this.channels = [];\n    this.sendBuffer = [];\n    this.ref = 0;\n    this.fallbackRef = null;\n    this.timeout = opts.timeout || DEFAULT_TIMEOUT;\n    this.transport = opts.transport || global.WebSocket || LongPoll;\n    this.primaryPassedHealthCheck = false;\n    this.longPollFallbackMs = opts.longPollFallbackMs;\n    this.fallbackTimer = null;\n    this.sessionStore = opts.sessionStorage || global && global.sessionStorage;\n    this.establishedConnections = 0;\n    this.defaultEncoder = serializer_default.encode.bind(serializer_default);\n    this.defaultDecoder = serializer_default.decode.bind(serializer_default);\n    this.closeWasClean = true;\n    this.disconnecting = false;\n    this.binaryType = opts.binaryType || "arraybuffer";\n    this.connectClock = 1;\n    this.pageHidden = false;\n    if (this.transport !== LongPoll) {\n      this.encode = opts.encode || this.defaultEncoder;\n      this.decode = opts.decode || this.defaultDecoder;\n    } else {\n      this.encode = this.defaultEncoder;\n      this.decode = this.defaultDecoder;\n    }\n    let awaitingConnectionOnPageShow = null;\n    if (phxWindow && phxWindow.addEventListener) {\n      phxWindow.addEventListener("pagehide", (_e) => {\n        if (this.conn) {\n          this.disconnect();\n          awaitingConnectionOnPageShow = this.connectClock;\n        }\n      });\n      phxWindow.addEventListener("pageshow", (_e) => {\n        if (awaitingConnectionOnPageShow === this.connectClock) {\n          awaitingConnectionOnPageShow = null;\n          this.connect();\n        }\n      });\n      phxWindow.addEventListener("visibilitychange", () => {\n        if (document.visibilityState === "hidden") {\n          this.pageHidden = true;\n        } else {\n          this.pageHidden = false;\n          if (!this.isConnected() && !this.closeWasClean) {\n            this.teardown(() => this.connect());\n          }\n        }\n      });\n    }\n    this.heartbeatIntervalMs = opts.heartbeatIntervalMs || 3e4;
1\n    this.rejoinAfterMs = (tries) => {\n      if (opts.rejoinAfterMs) {\n        return opts.rejoinAfterMs(tries);\n      } else {\n        return [1e3, 2e3, 5e3][tries - 1] || 1e4;\n      }\n    };\n    this.reconnectAfterMs = (tries) => {\n      if (opts.reconnectAfterMs) {\n        return opts.reconnectAfterMs(tries);\n      } else {\n        return [10, 50, 100, 150, 200, 250, 500, 1e3, 2e3][tries - 1] || 5e3;\n      }\n    };\n    this.logger = opts.logger || null;\n    if (!this.logger && opts.debug) {\n      this.logger = (kind, msg, data) => {\n        console.log(`${kind}: ${msg}`, data);\n      };\n    }\n    this.longpollerTimeout = opts.longpollerTimeout || 2e4;\n    this.params = closure(opts.params || {});\n    this.endPoint = `${endPoint}/${TRANSPORTS.websocket}`;\n    this.vsn = opts.vsn || DEFAULT_VSN;\n    this.heartbeatTimeoutTimer = null;\n    this.heartbeatTimer = null;\n    this.pendingHeartbeatRef = null;\n    this.reconnectTimer = new Timer(() => {\n      if (this.pageHidden) {\n        this.log("Not reconnecting as page is hidden!");\n        this.teardown();\n        return;\n      }\n      this.teardown(() => this.connect());\n    }, this.reconnectAfterMs);\n    this.authToken = opts.authToken && closure(opts.authToken);\n  }\n  /**\n   * Returns the LongPoll transport reference\n   */\n  getLongPollTransport() {\n    return LongPoll;\n  }\n  /**\n   * Disconnects and replaces the active transport\n   *\n   * @param {Function} newTransport - The new transport class to instantiate\n   *\n   */\n  replaceTransport(newTransport) {\n    this.connectClock++;\n    this.closeWasClean = true;\n    clearTimeout(this.fallbackTimer);\n    this.reconnectTimer.reset();\n    if (this.conn) {\n      this.conn.close();\n      this.conn = null;\n    }\n    this.transport = newTransport;\n  }\n  /**\n   * Returns the socket protocol\n   *\n   * @returns {string}\n   */\n  protocol() {\n    return location.protocol.match(/^https/) ? "wss" : "ws";\n  }\n  /**\n   * The fully qualified socket url\n   *\n   * @returns {string}\n   */\n  endPointURL() {\n    let uri = Ajax.appendParams(\n      Ajax.appendParams(this.endPoint, this.params()),\n      { vsn: this.vsn }\n    );\n    if (uri.charAt(0) !== "/") {\n      return uri;\n    }\n    if (uri.charAt(1) === "/") {\n      return `${this.protocol()}:${uri}`;\n    }\n    return `${this.protocol()}://${location.host}${uri}`;\n  }\n  /**\n   * Disconnects the socket\n   *\n   * See https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes for valid status codes.\n   *\n   * @param {Function} callback - Optional callback which is called after socket is disconnected.\n   * @param {integer} code - A status code for disconnection (Optional).\n   * @param {string} reason - A textual description of the reason to disconnect. (Optional)\n   */\n  disconnect(callback, code, reason) {\n    this.connectClock++;\n    this.disconnecting = true;\n    this.closeWasClean = true;\n    clearTimeout(this.fallbackTimer);\n    this.reconnectTimer.reset();\n    this.teardown(() => {\n      this.disconnecting = false;\n      callback && callback();\n    }, code, reason);\n  }\n  /**\n   *\n   * @param {Object} params - The params to send when connecting, for example `{user_id: userToken}`\n   *\n   * Passing params to connect is deprecated; pass them in the Socket constructor instead:\n   * `new Socket("/socket", {params: {user_id: userToken}})`.\n   */\n  connect(params) {\n    if (params) {\n      console && console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor");\n      this.params = closure(params);\n    }\n    if (this.conn && !this.disconnecting) {\n      return;\n    }\n    if (this.longPollFallbackMs && this.transport !== LongPoll) {\n      this.connectWithF
1allback(LongPoll, this.longPollFallbackMs);\n    } else {\n      this.transportConnect();\n    }\n  }\n  /**\n   * Logs the message. Override `this.logger` for specialized logging. noops by default\n   * @param {string} kind\n   * @param {string} msg\n   * @param {Object} data\n   */\n  log(kind, msg, data) {\n    this.logger && this.logger(kind, msg, data);\n  }\n  /**\n   * Returns true if a logger has been set on this socket.\n   */\n  hasLogger() {\n    return this.logger !== null;\n  }\n  /**\n   * Registers callbacks for connection open events\n   *\n   * @example socket.onOpen(function(){ console.info("the socket was opened") })\n   *\n   * @param {Function} callback\n   */\n  onOpen(callback) {\n    let ref = this.makeRef();\n    this.stateChangeCallbacks.open.push([ref, callback]);\n    return ref;\n  }\n  /**\n   * Registers callbacks for connection close events\n   * @param {Function} callback\n   */\n  onClose(callback) {\n    let ref = this.makeRef();\n    this.stateChangeCallbacks.close.push([ref, callback]);\n    return ref;\n  }\n  /**\n   * Registers callbacks for connection error events\n   *\n   * @example socket.onError(function(error){ alert("An error occurred") })\n   *\n   * @param {Function} callback\n   */\n  onError(callback) {\n    let ref = this.makeRef();\n    this.stateChangeCallbacks.error.push([ref, callback]);\n    return ref;\n  }\n  /**\n   * Registers callbacks for connection message events\n   * @param {Function} callback\n   */\n  onMessage(callback) {\n    let ref = this.makeRef();\n    this.stateChangeCallbacks.message.push([ref, callback]);\n    return ref;\n  }\n  /**\n   * Pings the server and invokes the callback with the RTT in milliseconds\n   * @param {Function} callback\n   *\n   * Returns true if the ping was pushed or false if unable to be pushed.\n   */\n  ping(callback) {\n    if (!this.isConnected()) {\n      return false;\n    }\n    let ref = this.makeRef();\n    let startTime = Date.now();\n    this.push({ topic: "phoenix", event: "heartbeat", payload: {}, ref });\n    let onMsgRef = this.onMessage((msg) => {\n      if (msg.ref === ref) {\n        this.off([onMsgRef]);\n        callback(Date.now() - startTime);\n      }\n    });\n    return true;\n  }\n  /**\n   * @private\n   *\n   * @param {Function}\n   */\n  transportName(transport) {\n    switch (transport) {\n      case LongPoll:\n        return "LongPoll";\n      default:\n        return transport.name;\n    }\n  }\n  /**\n   * @private\n   */\n  transportConnect() {\n    this.connectClock++;\n    this.closeWasClean = false;\n    let protocols = void 0;\n    if (this.authToken) {\n      protocols = ["phoenix", `${AUTH_TOKEN_PREFIX}${btoa(this.authToken()).replace(/=/g, "")}`];\n    }\n    this.conn = new this.transport(this.endPointURL(), protocols);\n    this.conn.binaryType = this.binaryType;\n    this.conn.timeout = this.longpollerTimeout;\n    this.conn.onopen = () => this.onConnOpen();\n    this.conn.onerror = (error) => this.onConnError(error);\n    this.conn.onmessage = (event) => this.onConnMessage(event);\n    this.conn.onclose = (event) => this.onConnClose(event);\n  }\n  getSession(key) {\n    return this.sessionStore && this.sessionStore.getItem(key);\n  }\n  storeSession(key, val) {\n    this.sessionStore && this.sessionStore.setItem(key, val);\n  }
1\n  connectWithFallback(fallbackTransport, fallbackThreshold = 2500) {\n    clearTimeout(this.fallbackTimer);\n    let established = false;\n    let primaryTransport = true;\n    let openRef, errorRef;\n    let fallbackTransportName = this.transportName(fallbackTransport);\n    let fallback = (reason) => {\n      this.log("transport", `falling back to ${fallbackTransportName}...`, reason);\n      this.off([openRef, errorRef]);\n      primaryTransport = false;\n      this.replaceTransport(fallbackTransport);\n      this.transportConnect();\n    };\n    if (this.getSession(`phx:fallback:${fallbackTransportName}`)) {\n      return fallback("memorized");\n    }\n    this.fallbackTimer = setTimeout(fallback, fallbackThreshold);\n    errorRef = this.onError((reason) => {\n      this.log("transport", "error", reason);\n      if (primaryTransport && !established) {\n        clearTimeout(this.fallbackTimer);\n        fallback(reason);\n      }\n    });\n    if (this.fallbackRef) {\n      this.off([this.fallbackRef]);\n    }\n    this.fallbackRef = this.onOpen(() => {\n      established = true;\n      if (!primaryTransport) {\n        let fallbackTransportName2 = this.transportName(fallbackTransport);\n        if (!this.primaryPassedHealthCheck) {\n          this.storeSession(`phx:fallback:${fallbackTransportName2}`, "true");\n        }\n        return this.log("transport", `established ${fallbackTransportName2} fallback`);\n      }\n      clearTimeout(this.fallbackTimer);\n      this.fallbackTimer = setTimeout(fallback, fallbackThreshold);\n      this.ping((rtt) => {\n        this.log("transport", "connected to primary after", rtt);\n        this.primaryPassedHealthCheck = true;\n        clearTimeout(this.fallbackTimer);\n      });\n    });\n    this.transportConnect();\n  }\n  clearHeartbeats() {\n    clearTimeout(this.heartbeatTimer);\n    clearTimeout(this.heartbeatTimeoutTimer);\n  }\n  onConnOpen() {\n    if (this.hasLogger()) this.log("transport", `${this.transportName(this.transport)} connected to ${this.endPointURL()}`);\n    this.closeWasClean = false;\n    this.disconnecting = false;\n    this.establishedConnections++;\n    this.flushSendBuffer();\n    this.reconnectTimer.reset();\n    this.resetHeartbeat();\n    this.stateChangeCallbacks.open.forEach(([, callback]) => callback());\n  }\n  /**\n   * @private\n   */\n  heartbeatTimeout() {\n    if (this.pendingHeartbeatRef) {\n      this.pendingHeartbeatRef = null;\n      if (this.hasLogger()) {\n        this.log("transport", "heartbeat timeout. Attempting to re-establish connection");\n      }\n      this.triggerChanError();\n      this.closeWasClean = false;\n      this.teardown(() => this.reconnectTimer.scheduleTimeout(), WS_CLOSE_NORMAL, "heartbeat timeout");\n    }\n  }\n  resetHeartbeat() {\n    if (this.conn && this.conn.skipHeartbeat) {\n      return;\n    }\n    this.pendingHeartbeatRef = null;\n    this.clearHeartbeats();\n    this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs);\n  }\n  teardown(callback, code, reason) {\n    if (!this.conn) {\n      return callback && callback();\n    }\n    const connToClose = this.conn;\n    this.waitForBufferDone(connToClose, () => {\n      if (code) {\n        connToClose.close(code, reason || "");\n      } else {\n        connToClose.close();\n      }\n      this.waitForSocketClosed(connToClose, () => {\n        if (this.conn === connToClose) {\n          this.conn.onopen = function() {\n          };\n          this.conn.onerror = function() {\n          };\n          this.conn.onmessage = function() {\n          };\n          this.conn.onclose = function() {\n          };\n          this.conn = null;\n        }\n        callback && callback();\n      });\n    });\n  }\n  waitForBufferDone(conn, callback, tries = 1) {\n    if (tries === 5 || !conn.bufferedAmount) {\n      callback();\n      return;\n    }\n    setTimeout(() => {\n      this.waitForBufferDone(conn, callback, tries + 1);\n    }, 150 * tries);\n  }\n  waitForSocketClosed(conn, callback, tries = 1) {\n    if (tries === 5 || conn.readyState === SOCKET_STATES.closed) {\n      callback();\n      return;\n    }\n    setTimeout(() =>
1 {\n      this.waitForSocketClosed(conn, callback, tries + 1);\n    }, 150 * tries);\n  }\n  onConnClose(event) {\n    if (this.conn) this.conn.onclose = () => {\n    };\n    let closeCode = event && event.code;\n    if (this.hasLogger()) this.log("transport", "close", event);\n    this.triggerChanError();\n    this.clearHeartbeats();\n    if (!this.closeWasClean && closeCode !== 1e3) {\n      this.reconnectTimer.scheduleTimeout();\n    }\n    this.stateChangeCallbacks.close.forEach(([, callback]) => callback(event));\n  }\n  /**\n   * @private\n   */\n  onConnError(error) {\n    if (this.hasLogger()) this.log("transport", "error", error);\n    let transportBefore = this.transport;\n    let establishedBefore = this.establishedConnections;\n    this.stateChangeCallbacks.error.forEach(([, callback]) => {\n      callback(error, transportBefore, establishedBefore);\n    });\n    if (transportBefore === this.transport || establishedBefore > 0) {\n      this.triggerChanError();\n    }\n  }\n  /**\n   * @private\n   */\n  triggerChanError() {\n    this.channels.forEach((channel) => {\n      if (!(channel.isErrored() || channel.isLeaving() || channel.isClosed())) {\n        channel.trigger(CHANNEL_EVENTS.error);\n      }\n    });\n  }\n  /**\n   * @returns {string}\n   */\n  connectionState() {\n    switch (this.conn && this.conn.readyState) {\n      case SOCKET_STATES.connecting:\n        return "connecting";\n      case SOCKET_STATES.open:\n        return "open";\n      case SOCKET_STATES.closing:\n        return "closing";\n      default:\n        return "closed";\n    }\n  }\n  /**\n   * @returns {boolean}\n   */\n  isConnected() {\n    return this.connectionState() === "open";\n  }\n  /**\n   * @private\n   *\n   * @param {Channel}\n   */\n  remove(channel) {\n    this.off(channel.stateChangeRefs);\n    this.channels = this.channels.filter((c) => c !== channel);\n  }\n  /**\n   * Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations.\n   *\n   * @param {refs} - list of refs returned by calls to\n   *                 `onOpen`, `onClose`, `onError,` and `onMessage`\n   */\n  off(refs) {\n    for (let key in this.stateChangeCallbacks) {\n      this.stateChangeCallbacks[key] = this.stateChangeCallbacks[key].filter(([ref]) => {\n        return refs.indexOf(ref) === -1;\n      });\n    }\n  }\n  /**\n   * Initiates a new channel for the given topic\n   *\n   * @param {string} topic\n   * @param {Object} chanParams - Parameters for the channel\n   * @returns {Channel}\n   */\n  channel(topic, chanParams = {}) {\n    let chan = new Channel(topic, chanParams, this);\n    this.channels.push(chan);\n    return chan;\n  }\n  /**\n   * @param {Object} data\n   */\n  push(data) {\n    if (this.hasLogger()) {\n      let { topic, event, payload, ref, join_ref } = data;\n      this.log("push", `${topic} ${event} (${join_ref}, ${ref})`, payload);\n    }\n    if (this.isConnected()) {\n      this.encode(data, (result) => this.conn.send(result));\n    } else {\n      this.sendBuffer.push(() => this.encode(data, (result) => this.conn.send(result)));\n    }\n  }\n  /**\n   * Return the next message ref, accounting for overflows\n   * @returns {string}\n   */\n  makeRef() {\n    let newRef = this.ref + 1;\n    if (newRef === this.ref) {\n      this.ref = 0;\n    } else {\n      this.ref = newRef;\n    }\n    return this.ref.toString();\n  }\n  sendHeartbeat() {\n    if (this.pendingHeartbeatRef && !this.isConnected()) {\n      return;\n    }\n    this.pendingHeartbeatRef = this.makeRef();\n    this.push({ topic: "phoenix", event: "heartbeat", payload: {}, ref: this.pendingHeartbeatRef });\n    this.heartbeatTimeoutTimer = setTimeout(() => this.heartbeatTimeout(), this.heartbeatIntervalMs);\n  }\n  flushSendBuffer() {\n    if (this.isConnected() && this.sendBuffer.length > 0) {\n      this.sendBuffer.forEach((callback) => callback());\n      this.sendBuffer = [];\n    }\n  }\n  onConnMessage(rawMessage) {\n    this.decode(rawMessage.data, (msg) => {\n      let { topic, event, payload, ref, join_ref } = msg;\n      if (ref && ref === this.pendingHeartbeatRef) {\n        this.clearHeartbeats();\n        this.pendingHeartbeatRef = null;\n        this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs);\n      }\n      if (this.hasLogger()) this.log("receive", `${payload.status || ""} ${topic} ${event} ${ref && "(" + ref + ")" || ""}`, payload);\n      for (let i = 0; i < this.channels.length;
1 i++) {\n        const channel = this.channels[i];\n        if (!channel.isMember(topic, event, payload, join_ref)) {\n          continue;\n        }\n        channel.trigger(event, payload, ref, join_ref);\n      }\n      for (let i = 0; i < this.stateChangeCallbacks.message.length; i++) {\n        let [, callback] = this.stateChangeCallbacks.message[i];\n        callback(msg);\n      }\n    });\n  }\n  leaveOpenTopic(topic) {\n    let dupChannel = this.channels.find((c) => c.topic === topic && (c.isJoined() || c.isJoining()));\n    if (dupChannel) {\n      if (this.hasLogger()) this.log("transport", `leaving duplicate topic "${topic}"`);\n      dupChannel.leave();\n    }\n  }\n};\n\n//# sourceMappingURL=phoenix.mjs.map\n\n// EXTERNAL MODULE: ./node_modules/nprogress/nprogress.js\nvar nprogress = __webpack_require__(865);\nvar nprogress_default = /*#__PURE__*/__webpack_require__.n(nprogress);\n;// CONCATENATED MODULE: ./node_modules/phoenix_live_view/priv/static/phoenix_live_view.esm.js\n// js/phoenix_live_view/constants.ts\nvar CONSECUTIVE_RELOADS = "consecutive-reloads";\nvar MAX_RELOADS = 10;\nvar RELOAD_JITTER_MIN = 5e3;\nvar RELOAD_JITTER_MAX = 1e4;\nvar FAILSAFE_JITTER = 3e4;\nvar PHX_EVENT_CLASSES = [\n  "phx-click-loading",\n  "phx-change-loading",\n  "phx-submit-loading",\n  "phx-keydown-loading",\n  "phx-keyup-loading",\n  "phx-blur-loading",\n  "phx-focus-loading",\n  "phx-hook-loading"\n];\nvar PHX_DROP_TARGET_ACTIVE_CLASS = "phx-drop-target-active";\nvar PHX_COMPONENT = "data-phx-component";\nvar PHX_VIEW_REF = "data-phx-view";\nvar PHX_LIVE_LINK = "data-phx-link";\nvar PHX_TRACK_STATIC = "track-static";\nvar PHX_LINK_STATE = "data-phx-link-state";\nvar PHX_REF_LOADING = "data-phx-ref-loading";\nvar PHX_REF_SRC = "data-phx-ref-src";\nvar PHX_REF_LOCK = "data-phx-ref-lock";\nvar PHX_PENDING_REFS = "phx-pending-refs";\nvar PHX_TRACK_UPLOADS = "track-uploads";\nvar PHX_UPLOAD_REF = "data-phx-upload-ref";\nvar PHX_PREFLIGHTED_REFS = "data-phx-preflighted-refs";\nvar PHX_DONE_REFS = "data-phx-done-refs";\nvar PHX_DROP_TARGET = "drop-target";\nvar PHX_ACTIVE_ENTRY_REFS = "data-phx-active-refs";\nvar PHX_LIVE_FILE_UPDATED = "phx:live-file:updated";\nvar PHX_SKIP = "data-phx-skip";\nvar PHX_MAGIC_ID = "data-phx-id";\nvar PHX_PRUNE = "data-phx-prune";\nvar PHX_CONNECTED_CLASS = "phx-connected";\nvar PHX_LOADING_CLASS = "phx-loading";\nvar PHX_ERROR_CLASS = "phx-error";\nvar PHX_CLIENT_ERROR_CLASS = "phx-client-error";\nvar PHX_SERVER_ERROR_CLASS = "phx-server-error";\nvar PHX_PARENT_ID = "data-phx-parent-id";\nvar PHX_MAIN = "data-phx-main";\nvar PHX_ROOT_ID = "data-phx-root-id";\nvar PHX_VIEWPORT_TOP = "viewport-top";\nvar PHX_VIEWPORT_BOTTOM = "viewport-bottom";\nvar PHX_VIEWPORT_OVERRUN_TARGET = "viewport-overrun-target";\nvar PHX_TRIGGER_ACTION = "trigger-action";\nvar PHX_HAS_FOCUSED = "phx-has-focused";\nvar FOCUSABLE_INPUTS = [\n  "text",\n  "textarea",\n  "number",\n  "email",\n  "password",\n  "search",\n  "tel",\n  "url",\n  "date",\n  "time",\n  "datetime-local",\n  "color",\n  "range"\n];\nvar CHECKABLE_INPUTS = ["checkbox", "radio"];\nvar PHX_HAS_SUBMITTED = "phx-has-submitted";\nvar PHX_SESSION = "data-phx-session";\nvar PHX_VIEW_SELECTOR = `[${PHX_SESSION}]`;\nvar PHX_STICKY = "data-phx-sticky";\nvar PHX_STATIC = "data-phx-static";\nvar PHX_READONLY = "data-phx-readonly";\nvar PHX_DISABLED = "data-phx-disabled";\nvar PHX_DISABLE_WITH = "disable-with";\nvar PHX_DISABLE_WITH_RESTORE = "data-phx-disable-with-restore";\nvar PHX_HOOK = "hook";\nvar PHX_DEBOUNCE = "debounce";\nvar PHX_THROTTLE = "throttle";\nvar PHX_UPDATE = "update";\nvar PHX_STREAM = "stream";\nvar PHX_STREAM_REF = "data-phx-stream";\nvar PHX_PORTAL = "data-phx-portal";\nvar PHX_TELEPORTED_REF = "data-phx-teleported";\nvar PHX_TELEPORTED_SRC = "data-phx-teleported-src";\nvar PHX_RUNTIME_HOOK = "data-phx-runtime-hook";\nvar PHX_LV_PID = "data-phx-pid";\nvar PHX_KEY = "key";\nvar PHX_PRIVATE = "phxPrivate";\nvar PHX_AUTO_RECOVER = "auto-recover";\nvar PHX_NO_UNUSED_FIELD = "no-unused-field";\nvar PHX_LV_DEBUG = "phx:live-socket:debug";\nvar PHX_LV_PROFILE = "phx:live-socket:profiling";
1\nvar PHX_LV_LATENCY_SIM = "phx:live-socket:latency-sim";\nvar PHX_LV_HISTORY_POSITION = "phx:nav-history-position";\nvar PHX_PROGRESS = "progress";\nvar PHX_MOUNTED = "mounted";\nvar PHX_RELOAD_STATUS = "__phoenix_reload_status__";\nvar LOADER_TIMEOUT = 1;\nvar MAX_CHILD_JOIN_ATTEMPTS = 3;\nvar BEFORE_UNLOAD_LOADER_TIMEOUT = 200;\nvar DISCONNECTED_TIMEOUT = 500;\nvar BINDING_PREFIX = "phx-";\nvar PUSH_TIMEOUT = 3e4;\nvar DEBOUNCE_TRIGGER = "debounce-trigger";\nvar THROTTLED = "throttled";\nvar DEBOUNCE_PREV_KEY = "debounce-prev-key";\nvar DEFAULTS = {\n  debounce: 300,\n  throttle: 300\n};\nvar PHX_PENDING_ATTRS = [PHX_REF_LOADING, PHX_REF_SRC, PHX_REF_LOCK];\nvar STATIC = "s";\nvar ROOT = "r";\nvar COMPONENTS = "c";\nvar KEYED = "k";\nvar KEYED_COUNT = "kc";\nvar EVENTS = "e";\nvar REPLY = "r";\nvar TITLE = "t";\nvar TEMPLATES = "p";\nvar STREAM = "stream";\n\n// js/phoenix_live_view/entry_uploader.js\nvar EntryUploader = class {\n  constructor(entry, config, liveSocket) {\n    const { chunk_size, chunk_timeout } = config;\n    this.liveSocket = liveSocket;\n    this.entry = entry;\n    this.offset = 0;\n    this.chunkSize = chunk_size;\n    this.chunkTimeout = chunk_timeout;\n    this.chunkTimer = null;\n    this.errored = false;\n    this.uploadChannel = liveSocket.channel(`lvu:${entry.ref}`, {\n      token: entry.metadata()\n    });\n  }\n  error(reason) {\n    if (this.errored) {\n      return;\n    }\n    this.uploadChannel.leave();\n    this.errored = true;\n    this.chunkTimer != null && clearTimeout(this.chunkTimer);\n    this.entry.error(reason);\n  }\n  upload() {\n    this.uploadChannel.onError((reason) => this.error(reason));\n    this.uploadChannel.join().receive("ok", (_data) => this.readNextChunk()).receive("error", ({ reason }) => this.error(reason));\n  }\n  isDone() {\n    return this.offset >= this.entry.file.size;\n  }\n  readNextChunk() {\n    const reader = new window.FileReader();\n    const blob = this.entry.file.slice(\n      this.offset,\n      this.chunkSize + this.offset\n    );\n    reader.onload = (e) => {\n      if (e.target?.error === null) {\n        this.offset += /** @type {ArrayBuffer} */\n        e.target.result.byteLength;\n        this.pushChunk(\n          /** @type {ArrayBuffer} */\n          e.target.result\n        );\n      } else {\n        return logError("Read error: " + e.target?.error);\n      }\n    };\n    reader.readAsArrayBuffer(blob);\n  }\n  pushChunk(chunk) {\n    if (!this.uploadChannel.isJoined()) {\n      return;\n    }\n    this.uploadChannel.push("chunk", chunk, this.chunkTimeout).receive("ok", () => {\n      this.entry.progress(this.offset / this.entry.file.size * 100);\n      if (!this.isDone()) {\n        this.chunkTimer = setTimeout(\n          () => this.readNextChunk(),\n          this.liveSocket.getLatencySim() || 0\n        );\n      }\n    }).receive("error", ({ reason }) => this.error(reason));\n  }\n};\n\n// js/phoenix_live_view/utils.ts\nvar logError = (msg, obj) => console.error && console.error(msg, obj);\nvar ensureSameOrigin = (href, kind) => {\n  let url;\n  try {\n    url = new URL(href, window.location.href);\n  } catch {\n    throw new Error(\n      `expected ${kind} destination to be a valid URL, got: ${href}`\n    );\n  }\n  if (url.origin !== window.location.origin) {\n    throw new Error(\n      `cannot ${kind} to "${href}" because its origin does not match the current origin "${window.location.origin}". Use window.location directly for cross-origin navigation.`\n    );\n  }\n};\nvar isCid = (cid) => {\n  const type = typeof cid;\n  return type === "number" || type === "string" && /^(0|[1-9]\\d*)$/.test(cid);\n};\nfunction detectDuplicateIds() {\n  const ids = /* @__PURE__ */ new Set();\n  const elems = document.querySelectorAll("*[id]");\n  for (let i = 0, len = elems.length; i < len; i++) {\n    if (ids.has(elems[i].id)) {\n      console.error(\n        `Multiple IDs detected: ${elems[i].id}. Ensure unique element ids.`\n      );\n    } else {\n      ids.add(elems[i].id);\n    }\n  }\n}\nfunction detectInvalidStreamInserts(inserts) {\n  const errors = /* @__PURE__ */ new Set();
1\n  Object.keys(inserts).forEach((id) => {\n    const streamEl = document.getElementById(id);\n    if (streamEl && streamEl.parentElement && streamEl.parentElement.getAttribute("phx-update") !== "stream") {\n      errors.add(\n        `The stream container with id "${streamEl.parentElement.id}" is missing the phx-update="stream" attribute. Ensure it is set for streams to work properly.`\n      );\n    }\n  });\n  errors.forEach((error) => console.error(error));\n}\nvar debug = (view, kind, msg, obj) => {\n  if (view.liveSocket.isDebugEnabled()) {\n    console.log(`${view.id} ${kind}: ${msg} - `, obj);\n  }\n};\nvar phoenix_live_view_esm_closure = (val) => typeof val === "function" ? val : function() {\n  return val;\n};\nvar clone = (obj) => {\n  return JSON.parse(JSON.stringify(obj));\n};\nvar closestPhxBinding = (startEl, binding, borderEl) => {\n  let el = startEl;\n  do {\n    if (el.matches(`[${binding}]`) && !("disabled" in el && el.disabled)) {\n      return el;\n    }\n    el = el.parentElement;\n  } while (el !== null && el.nodeType === 1 && !(borderEl && borderEl.isSameNode(el) || el.matches(PHX_VIEW_SELECTOR)));\n  return null;\n};\nvar isObject = (obj) => {\n  return obj !== null && typeof obj === "object" && !(obj instanceof Array);\n};\nvar isEqualObj = (obj1, obj2) => JSON.stringify(obj1) === JSON.stringify(obj2);\nvar isEmpty = (obj) => {\n  for (const x in obj) {\n    return false;\n  }\n  return true;\n};\nvar maybe = (el, callback) => el && callback(el);\nvar channelUploader = function(entries, onError, resp, liveSocket) {\n  entries.forEach((entry) => {\n    const entryUploader = new EntryUploader(entry, resp.config, liveSocket);\n    entryUploader.upload();\n  });\n};\nvar eventContainsFiles = (e) => {\n  if (e.dataTransfer.types) {\n    for (let i = 0; i < e.dataTransfer.types.length; i++) {\n      if (e.dataTransfer.types[i] === "Files") {\n        return true;\n      }\n    }\n  }\n  return false;\n};\n\n// js/phoenix_live_view/browser.ts\nvar Browser = {\n  canPushState() {\n    return typeof history.pushState !== "undefined";\n  },\n  dropLocal(localStorage, namespace, subkey) {\n    return localStorage.removeItem(this.localKey(namespace, subkey));\n  },\n  updateLocal(localStorage, namespace, subkey, initial, func) {\n    const current = this.getLocal(localStorage, namespace, subkey);\n    const key = this.localKey(namespace, subkey);\n    const newVal = current === null ? initial : func(current);\n    localStorage.setItem(key, JSON.stringify(newVal));\n    return newVal;\n  },\n  getLocal(localStorage, namespace, subkey) {\n    return JSON.parse(localStorage.getItem(this.localKey(namespace, subkey)));\n  },\n  updateCurrentState(callback) {\n    if (!this.canPushState()) {\n      return;\n    }\n    history.replaceState(\n      callback(history.state || {}),\n      "",\n      window.location.href\n    );\n  },\n  pushState(kind, meta, to) {\n    if (this.canPushState()) {\n      if (to !== window.location.href) {\n        if (meta.type == "redirect" && meta.scroll) {\n          const currentState = history.state || {};\n          currentState.scroll = meta.scroll;\n          history.replaceState(currentState, "", window.location.href);\n        }\n        delete meta.scroll;\n        history[kind + "State"](meta, "", to || null);\n        window.requestAnimationFrame(() => {\n          const hashEl = this.getHashTargetEl(window.location.hash);\n          if (hashEl) {\n            hashEl.scrollIntoView();\n          } else if (meta.type === "redirect") {\n            window.scroll(0, 0);\n          }\n        });\n      }\n    } else if (to) {\n      this.redirect(to);\n    }\n  },\n  setCookie(name, value, maxAgeSeconds) {\n    const expires = typeof maxAgeSeconds === "number" ? ` max-age=${maxAgeSeconds};` : "";\n    document.cookie = `${name}=${value};${expires} path=/`;\n  },\n  getCookie(name) {\n    return document.cookie.replace(\n      new RegExp(`(?:(?:^|.*;s*)${name}s*=s*([^;]*).*$)|^.*$`),\n      "$1"\n    );\n  },\n  deleteCookie(name) {\n    document.cookie = `${name}=; max-age=-1; path=/`;\n  },\n  redirect(toURL, flash = null, navigate = (url) => {\n    window.location.href = url;\n  }) {\n    if (flash) {\n      this.setCookie("__phoenix_flash__", flash, 60);\n    }\n    navigate(toURL);\n  },\n  localKey(namespace, subkey) {\n    return `${namespace}-${subkey}`;\n  },\n  getHashTargetEl(maybeHash) {\n    const hash = maybeHash.toString().substring(1);\n    if (hash === "") {\n      return;\n    }\n    return document.getElementById(hash) || document.querySelector(`a[name="${hash}"]`);\n  }\n};\nvar browser_default = Browser;\n\n// js/phoenix_live_view/dom.ts\nvar DOM = {\n  byId(id) {\n    return document.getElementById(id) || logError(`no id found for ${id}`);\n  },\n  elementFromTarget(target) {\n    if (!(target instanceof Node)) {\n      return null;\n    }\n    if (target.nodeType === Node.ELEMENT_NODE) {\n      return target;\n    } else {\n      return target.parentElement;\n    }\n  },\n  removeClass(el, className) {\n    el.classList.remove(className);\n    if (el.classList.length === 0) {\n      el.removeAttribute("class");\n    }\n  },\n  all(node, query, callback) {\n    if (!node) {\n      return [];\n    }\n    const array = Array.from(node.querySelectorAll(query));\n    if (callback) {\n      array.forEach(callback);\n    }\n    return array;\n  },\n  childNodeLength(html) {\n    const template = document.createElement("template");\n    template.innerHTML = html;\n    return template.content.childElementCount;\n  },\n  isUploadInput(el) {\n    return el.type === "file" && el.getAttribute(PHX_UPLOAD_REF) !== null;\n  },\n  isAutoUpload(inputEl) {\n    return inputEl.hasAttribute("data-phx-auto-upload");\n  }
1,\n  findUploadInputs(node) {\n    const formId = node.id;\n    const inputsOutsideForm = this.all(\n      document,\n      `input[type="file"][${PHX_UPLOAD_REF}][form="${formId}"]`\n    );\n    return this.all(node, `input[type="file"][${PHX_UPLOAD_REF}]`).concat(\n      inputsOutsideForm\n    );\n  },\n  findComponent(viewId, cid, doc2 = document) {\n    return doc2.querySelector(\n      `[${PHX_VIEW_REF}="${viewId}"][${PHX_COMPONENT}="${cid}"]`\n    );\n  },\n  getComponent(viewId, cid, doc2 = document) {\n    const el = this.findComponent(viewId, cid, doc2);\n    if (!el) {\n      throw new Error(\n        `no component found matching viewId ${viewId} and cid ${cid}`\n      );\n    }\n    return el;\n  },\n  isPhxDestroyed(node) {\n    return node.id && DOM.private(node, "destroyed") ? true : false;\n  },\n  wantsNewTab(e) {\n    const wantsNewTab = e.ctrlKey || e.shiftKey || e.metaKey || e.button && e.button === 1;\n    const isDownload = e.target instanceof HTMLAnchorElement && e.target.hasAttribute("download");\n    const isTargetBlank = e.target.hasAttribute("target") && e.target.getAttribute("target").toLowerCase() === "_blank";\n    const isTargetNamedTab = e.target.hasAttribute("target") && !e.target.getAttribute("target").startsWith("_");\n    return wantsNewTab || isTargetBlank || isDownload || isTargetNamedTab;\n  },\n  isUnloadableFormSubmit(e) {\n    const isDialogSubmit = e.target && e.target.getAttribute("method") === "dialog" || e.submitter && e.submitter.getAttribute("formmethod") === "dialog";\n    if (isDialogSubmit) {\n      return false;\n    } else {\n      return !e.defaultPrevented && !this.wantsNewTab(e);\n    }\n  },\n  isNewPageClick(e, currentLocation) {\n    const href = e.target instanceof HTMLAnchorElement ? e.target.getAttribute("href") : null;\n    let url;\n    if (e.defaultPrevented || href === null || this.wantsNewTab(e)) {\n      return false;\n    }\n    if (href.startsWith("mailto:") || href.startsWith("tel:")) {\n      return false;\n    }\n    if (e.target.isContentEditable) {\n      return false;\n    }\n    try {\n      url = new URL(href);\n    } catch {\n      try {\n        url = new URL(href, currentLocation);\n      } catch {\n        return true;\n      }\n    }\n    if (url.host === currentLocation.host && url.protocol === currentLocation.protocol) {\n      if (url.pathname === currentLocation.pathname && url.search === currentLocation.search) {\n        return url.hash === "" && !url.href.endsWith("#");\n      }\n    }\n    return url.protocol.startsWith("http");\n  },\n  markPhxChildDestroyed(el) {\n    if (this.isPhxChild(el)) {\n      el.setAttribute(PHX_SESSION, "");\n    }\n    this.putPrivate(el, "destroyed", true);\n  },\n  findPhxChildrenInFragment(html, parentId) {\n    const template = document.createElement("template");\n    template.innerHTML = html;\n    return this.findPhxChildren(template.content, parentId);\n  },\n  isIgnored(el, phxUpdate) {\n    return (el.getAttribute(phxUpdate) || el.getAttribute("data-phx-update")) === "ignore";\n  },\n  isPhxUpdate(el, phxUpdate, updateTypes) {\n    return el.getAttribute && updateTypes.indexOf(el.getAttribute(phxUpdate)) >= 0;\n  },\n  findPhxSticky(el) {\n    return this.all(el, `[${PHX_STICKY}]`);\n  },\n  findPhxChildren(el, parentId) {\n    return this.all(el, `${PHX_VIEW_SELECTOR}[${PHX_PARENT_ID}="${parentId}"]`);\n  },\n  findExistingParentCIDs(viewId, cids) {\n    const parentCids = /* @__PURE__ */ new Set();\n    const childrenCids = /* @__PURE__ */ new Set();\n    cids.forEach((cid) => {\n      this.all(\n        document,\n        `[${PHX_VIEW_REF}="${viewId}"][${PHX_COMPONENT}="${cid}"]`\n      ).forEach((parent) => {\n        parentCids.add(cid);\n        this.all(parent, `[${PHX_VIEW_REF}="${viewId}"][${PHX_COMPONENT}]`).map((el) => parseInt(el.getAttribute(PHX_COMPONENT))).forEach((childCID) => childrenCids.add(childCID));\n      });\n    });\n    childrenCids.forEach((childCid) => parentCids.delete(childCid));\n    return parentCids;\n  },\n  private(el, key) {\n    return el[PHX_PRIVATE] && el[PHX_PRIVATE][key];\n  },\n  deletePrivate(el, key) {\n    el[PHX_PRIVATE] && delete el[PHX_PRIVATE][key];\n  },\n  putPrivate(el, key, value) {\n    if (!el[PHX_PRIVATE]) {\n      el[PHX_PRIVATE] = {};\n    }\n    el[PHX_PRIVATE][key] = value;\n  },\n  updatePrivate(el, key, defaultVal, updateFunc) {\n    const existing = this.private(el, key);\n    if (existing === void 0) {\n      this.putPrivate(el, key, updateFunc(defaultVal));\n    } else {\n      this.putPrivate(el, key, updateFunc(existing));\n    }\n  },\n  syncPendingAttrs(fromEl, toEl) {\n    if (!fromEl.hasAttribute(PHX_REF_SRC)) {\n      return;\n    }\n    PHX_EVENT_CLASSES.forEach((className) => {\n      fromEl.classList.contains(className) && toEl.classList.add(className);\n    });\n    PHX_PENDING_ATTRS.filter((attr) =>
1 fromEl.hasAttribute(attr)).forEach(\n      (attr) => {\n        toEl.setAttribute(attr, fromEl.getAttribute(attr));\n      }\n    );\n  },\n  copyPrivates(target, source) {\n    if (source[PHX_PRIVATE]) {\n      target[PHX_PRIVATE] = source[PHX_PRIVATE];\n    }\n  },\n  putTitle(str) {\n    const titleEl = document.querySelector("title");\n    if (titleEl) {\n      const { prefix, suffix, default: defaultTitle } = titleEl.dataset;\n      const isEmpty2 = typeof str !== "string" || str.trim() === "";\n      if (isEmpty2 && typeof defaultTitle !== "string") {\n        return;\n      }\n      const inner = isEmpty2 ? defaultTitle : str;\n      document.title = `${prefix || ""}${inner || ""}${suffix || ""}`;\n    } else {\n      document.title = str;\n    }\n  },\n  debounce(el, event, phxDebounce, defaultDebounce, phxThrottle, defaultThrottle, asyncFilter, callback) {\n    let debounce = el.getAttribute(phxDebounce);\n    let throttle = el.getAttribute(phxThrottle);\n    if (debounce === "") {\n      debounce = defaultDebounce;\n    }\n    if (throttle === "") {\n      throttle = defaultThrottle;\n    }\n    const value = debounce || throttle;\n    switch (value) {\n      case null:\n        return callback();\n      case "blur":\n        this.incCycle(el, "debounce-blur-cycle", () => {\n          if (asyncFilter()) {\n            callback();\n          }\n        });\n        if (this.once(el, "debounce-blur")) {\n          el.addEventListener(\n            "blur",\n            () => this.triggerCycle(el, "debounce-blur-cycle")\n          );\n        }\n        return;\n      default:\n        const timeout = parseInt(value);\n        const trigger = () => throttle ? this.deletePrivate(el, THROTTLED) : callback();\n        const currentCycle = this.incCycle(el, DEBOUNCE_TRIGGER, trigger);\n        if (isNaN(timeout)) {\n          return logError(`invalid throttle/debounce value: ${value}`);\n        }\n        if (throttle) {\n          let newKeyDown = false;\n          if (event.type === "keydown") {\n            const prevKey = this.private(el, DEBOUNCE_PREV_KEY);\n            this.putPrivate(el, DEBOUNCE_PREV_KEY, event.key);\n            newKeyDown = prevKey !== event.key;\n          }\n          if (!newKeyDown && this.private(el, THROTTLED)) {\n            return false;\n          } else {\n            callback();\n            const t = setTimeout(() => {\n              if (asyncFilter()) {\n                this.triggerCycle(el, DEBOUNCE_TRIGGER);\n              }\n            }, timeout);\n            this.putPrivate(el, THROTTLED, t);\n          }\n        } else {\n          setTimeout(() => {\n            if (asyncFilter()) {\n              this.triggerCycle(el, DEBOUNCE_TRIGGER, currentCycle);\n            }\n          }, timeout);\n        }\n        const form = el.form;\n        if (form && this.once(form, "bind-debounce")) {\n          form.addEventListener("submit", () => {\n            Array.from(new FormData(form).entries(), ([name]) => {\n              const namedItem = form.elements.namedItem(name);\n              const input = namedItem instanceof RadioNodeList ? namedItem[0] : namedItem;\n              if (input) {\n                this.incCycle(input, DEBOUNCE_TRIGGER);\n                this.deletePrivate(input, THROTTLED);\n              }\n            });\n          });\n        }\n        if (this.once(el, "bind-debounce")) {\n          el.addEventListener("blur", () => {\n            clearTimeout(this.private(el, THROTTLED));\n            if (asyncFilter()) {\n              this.triggerCycle(el, DEBOUNCE_TRIGGER);\n            }\n          });\n        }\n    }\n  },\n  triggerCycle(el, key, currentCycle) {\n    const [cycle, trigger] = this.private(el, key);\n    if (!currentCycle) {\n      currentCycle = cycle;\n    }\n    if (currentCycle === cycle) {\n      this.incCycle(el, key);\n      trigger();\n    }\n  },\n  once(el, key) {\n    if (this.private(el, key) === true) {\n      return false;\n    }\n    this.putPrivate(el, key, true);\n    return true;\n  }
1,\n  incCycle(el, key, trigger = function() {\n  }) {\n    let [currentCycle] = this.private(el, key) || [0, trigger];\n    currentCycle++;\n    this.putPrivate(el, key, [currentCycle, trigger]);\n    return currentCycle;\n  },\n  // maintains or adds privately used hook information\n  // fromEl and toEl can be the same element in the case of a newly added node\n  // fromEl and toEl can be any HTML node type, so we need to check if it\'s an element node\n  maintainPrivateHooks(fromEl, toEl, phxViewportTop, phxViewportBottom) {\n    if (fromEl.hasAttribute && fromEl.hasAttribute("data-phx-hook") && !toEl.hasAttribute("data-phx-hook")) {\n      toEl.setAttribute("data-phx-hook", fromEl.getAttribute("data-phx-hook"));\n    }\n    if (toEl.hasAttribute && (toEl.hasAttribute(phxViewportTop) || toEl.hasAttribute(phxViewportBottom))) {\n      toEl.setAttribute("data-phx-hook", "Phoenix.InfiniteScroll");\n    }\n  },\n  putCustomElHook(el, hook) {\n    if (el.isConnected) {\n      el.setAttribute("data-phx-hook", "");\n    } else {\n      console.error(`\n        hook attached to non-connected DOM element\n        ensure you are calling createHook within your connectedCallback. ${el.outerHTML}\n      `);\n    }\n    this.putPrivate(el, "custom-el-hook", hook);\n  },\n  getCustomElHook(el) {\n    return this.private(el, "custom-el-hook");\n  },\n  isUsedInput(el) {\n    return el.nodeType === Node.ELEMENT_NODE && (this.private(el, PHX_HAS_FOCUSED) || this.private(el, PHX_HAS_SUBMITTED));\n  },\n  resetForm(form) {\n    Array.from(form.elements).forEach((input) => {\n      this.deletePrivate(input, PHX_HAS_FOCUSED);\n      this.deletePrivate(input, PHX_HAS_SUBMITTED);\n    });\n  },\n  isPhxChild(node) {\n    return node.getAttribute && node.getAttribute(PHX_PARENT_ID);\n  },\n  isPhxSticky(node) {\n    return node.getAttribute && node.getAttribute(PHX_STICKY) !== null;\n  },\n  isChildOfAny(el, parents) {\n    return !!parents.find((parent) => parent.contains(el));\n  },\n  firstPhxChild(el) {\n    return this.isPhxChild(el) ? el : this.all(el, `[${PHX_PARENT_ID}]`)[0];\n  },\n  isPortalTemplate(el) {\n    return el.tagName === "TEMPLATE" && el.hasAttribute(PHX_PORTAL);\n  },\n  closestViewEl(el) {\n    const portalOrViewEl = el.closest(\n      `[${PHX_TELEPORTED_REF}],${PHX_VIEW_SELECTOR}`\n    );\n    if (!portalOrViewEl) {\n      return null;\n    }\n    if (portalOrViewEl.hasAttribute(PHX_TELEPORTED_REF)) {\n      return this.byId(portalOrViewEl.getAttribute(PHX_TELEPORTED_REF));\n    } else if (portalOrViewEl.hasAttribute(PHX_SESSION)) {\n      return portalOrViewEl;\n    }\n    return null;\n  },\n  dispatchEvent(target, name, opts = {}) {\n    let defaultBubble = true;\n    const isUploadTarget = target.nodeName === "INPUT" && target.type === "file";\n    if (isUploadTarget && name === "click") {\n      defaultBubble = false;\n    }\n    const bubbles = opts.bubbles === void 0 ? defaultBubble : !!opts.bubbles;\n    const eventOpts = {\n      bubbles,\n      cancelable: true,\n      detail: opts.detail || {}\n    };\n    const event = name === "click" ? new MouseEvent("click", eventOpts) : new CustomEvent(name, eventOpts);\n    target.dispatchEvent(event);\n  },\n  cloneNode(node, html) {\n    if (typeof html === "undefined") {\n      return node.cloneNode(true);\n    } else {\n      const cloned = node.cloneNode(false);\n      cloned.innerHTML = html;\n      return cloned;\n    }\n  },\n  // merge attributes from source to target\n  // if an element is ignored, we only merge data attributes\n  // including removing data attributes that are no longer in the source\n  mergeAttrs(target, source, opts = {}) {\n    const exclude = new Set(opts.exclude || []);\n    const isIgnored = opts.isIgnored;\n    const sourceAttrs = source.attributes;\n    for (let i = sourceAttrs.length - 1; i >= 0; i--) {\n      const name = sourceAttrs[i].name;\n      if (!exclude.has(name)) {\n        const sourceValue = source.getAttribute(name);\n        if (target.getAttribute(name) !== sourceValue && (!isIgnored || isIgnored && name.startsWith("data-"))) {\n          target.setAttribute(name, sourceValue);\n        }\n      } else {\n        if (name === "value") {\n          const sourceValue = source.value ?? source.getAttribute(name);\n          if (target.value === sourceValue) {\n            target.setAttribute("value", source.getAttribute(name));\n          }\n        }\n      }\n    }\n    const targetAttrs = target.attributes;\n    for (let i = targetAttrs.length - 1; i >= 0; i--) {\n      const name = targetAttrs[i].name;\n      if (isIgnored) {\n        if (name.startsWith("data-") && !source.hasAttribute(name) && !PHX_PENDING_ATTRS.includes(name)) {\
1n          target.removeAttribute(name);\n        }\n      } else {\n        if (!source.hasAttribute(name)) {\n          target.removeAttribute(name);\n        }\n      }\n    }\n  },\n  mergeFocusedInput(target, source) {\n    if (!(target instanceof HTMLSelectElement)) {\n      DOM.mergeAttrs(target, source, { exclude: ["value"] });\n    }\n    if (source.readOnly) {\n      target.setAttribute("readonly", true);\n    } else {\n      target.removeAttribute("readonly");\n    }\n  },\n  hasSelectionRange(el) {\n    return el.setSelectionRange && (el.type === "text" || el.type === "textarea");\n  },\n  restoreFocus(focused, selectionStart, selectionEnd) {\n    if (focused instanceof HTMLSelectElement) {\n      focused.focus();\n    }\n    if (!DOM.isTextualInput(focused)) {\n      return;\n    }\n    const wasFocused = focused.matches(":focus");\n    if (!wasFocused) {\n      focused.focus();\n    }\n    if (this.hasSelectionRange(focused)) {\n      focused.setSelectionRange(selectionStart, selectionEnd);\n    }\n  },\n  /**\n   * Returns true if the element is an input that can be focused and edited by the user,\n   * so we can skip patching it if it has focus.\n   */\n  isEditableInput(el) {\n    return this.isFormAssociated(el) && !(el instanceof HTMLButtonElement) && !(el instanceof HTMLInputElement && el.type === "button");\n  },\n  isFormAssociated(el) {\n    if (!(el instanceof HTMLElement))\n      return false;\n    if (el.localName) {\n      const customEl = customElements.get(el.localName);\n      if (customEl) {\n        return customEl.formAssociated === true;\n      }\n    }\n    return el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement || el instanceof HTMLButtonElement;\n  },\n  syncAttrsToProps(el) {\n    if (el instanceof HTMLInputElement && CHECKABLE_INPUTS.indexOf(el.type.toLocaleLowerCase()) >= 0) {\n      el.checked = el.getAttribute("checked") !== null;\n    }\n  },\n  isTextualInput(el) {\n    return FOCUSABLE_INPUTS.indexOf(el.type) >= 0;\n  },\n  isNowTriggerFormExternal(el, phxTriggerExternal) {\n    return el.getAttribute && el.getAttribute(phxTriggerExternal) !== null && document.body.contains(el);\n  },\n  cleanChildNodes(container, phxUpdate) {\n    if (DOM.isPhxUpdate(container, phxUpdate, ["append", "prepend", PHX_STREAM])) {\n      const toRemove = [];\n      container.childNodes.forEach((childNode) => {\n        if (!("id" in childNode) || !childNode.id) {\n          const isEmptyTextNode = childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue && childNode.nodeValue.trim() === "";\n          if (!isEmptyTextNode && childNode.nodeType !== Node.COMMENT_NODE) {\n            logError(\n              `only HTML element tags with an id are allowed inside containers with phx-update.\n\nremoving illegal node: "${("outerHTML" in childNode && childNode.outerHTML || childNode.nodeValue || "").trim()}"\n\n`\n            );\n          }\n          toRemove.push(childNode);\n        }\n      });\n      toRemove.forEach((childNode) => childNode.remove());\n    }\n  },\n  replaceRootContainer(container, tagName, attrs) {\n    const retainedAttrs = /* @__PURE__ */ new Set([\n      "id",\n      PHX_SESSION,\n      PHX_STATIC,\n      PHX_MAIN,\n      PHX_ROOT_ID\n    ]);\n    if (container.tagName.toLowerCase() === tagName.toLowerCase()) {\n      Array.from(container.attributes).filter((attr) => !retainedAttrs.has(attr.name.toLowerCase())).forEach((attr) => container.removeAttribute(attr.name));\n      Object.keys(attrs).filter((name) => !retainedAttrs.has(name.toLowerCase())).forEach((attr) => container.setAttribute(attr, attrs[attr]));\n      return container;\n    } else {\n      const newContainer = document.createElement(tagName);\n      Object.keys(attrs).forEach(\n        (attr) => newContainer.setAttribute(attr, attrs[attr])\n      );\n      retainedAttrs.forEach((attr) => {\n        const value = container.getAttribute(attr);\n        if (value !== null) {\n          newContainer.setAttribute(attr, value);\n        }\n      });\n      newContainer.innerHTML = container.innerHTML;\n      container.replaceWith(newContainer);\n      return newContainer;\n    }\n  },\n  getSticky(el, name, defaultVal) {\n    const op = (DOM.private(el, "sticky") || []).find(\n      ([existingName]) => name === existingName\n    );\n    if (op) {\n      const [_name, _op, stashedResult] = op;\n      return stashedResult;\n    } else {\n      return typeof defaultVal === "function" ? defaultVal() : defaultVal;\n    }\n  },\n  deleteSticky(el, name) {\n    this.updatePrivate(el, "sticky", [], (ops) =>
1 {\n      return ops.filter(([existingName, _]) => existingName !== name);\n    });\n  },\n  putSticky(el, name, op) {\n    const stashedResult = op(el);\n    this.updatePrivate(el, "sticky", [], (ops) => {\n      const existingIndex = ops.findIndex(\n        ([existingName]) => name === existingName\n      );\n      if (existingIndex >= 0) {\n        ops[existingIndex] = [name, op, stashedResult];\n      } else {\n        ops.push([name, op, stashedResult]);\n      }\n      return ops;\n    });\n  },\n  applyStickyOperations(el) {\n    const ops = DOM.private(el, "sticky");\n    if (!ops) {\n      return;\n    }\n    ops.forEach(([name, op, _stashed]) => this.putSticky(el, name, op));\n  },\n  isLocked(el) {\n    return el.hasAttribute && el.hasAttribute(PHX_REF_LOCK);\n  },\n  attributeIgnored(attribute, ignoredAttributes) {\n    return ignoredAttributes.some(\n      (toIgnore) => attribute.name == toIgnore || toIgnore === "*" || toIgnore.includes("*") && attribute.name.match(toIgnore) != null\n    );\n  }\n};\nvar dom_default = DOM;\n\n// js/phoenix_live_view/upload_entry.js\nvar UploadEntry = class {\n  static isActive(fileEl, file) {\n    const isNew = file._phxRef === void 0;\n    const activeRefs = fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");\n    const isActive = activeRefs.indexOf(LiveUploader.genFileRef(file)) >= 0;\n    return file.size > 0 && (isNew || isActive);\n  }\n  static isPreflighted(fileEl, file) {\n    const preflightedRefs = fileEl.getAttribute(PHX_PREFLIGHTED_REFS).split(",");\n    const isPreflighted = preflightedRefs.indexOf(LiveUploader.genFileRef(file)) >= 0;\n    return isPreflighted && this.isActive(fileEl, file);\n  }\n  static isPreflightInProgress(file) {\n    return file._preflightInProgress === true;\n  }\n  static markPreflightInProgress(file) {\n    file._preflightInProgress = true;\n  }\n  constructor(fileEl, file, view, autoUpload) {\n    this.ref = LiveUploader.genFileRef(file);\n    this.fileEl = fileEl;\n    this.file = file;\n    this.view = view;\n    this.meta = null;\n    this._isCancelled = false;\n    this._isDone = false;\n    this._progress = 0;\n    this._lastProgressSent = -1;\n    this._onDone = function() {\n    };\n    this._onElUpdated = this.onElUpdated.bind(this);\n    this.fileEl.addEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);\n    this.autoUpload = autoUpload;\n  }\n  metadata() {\n    return this.meta;\n  }\n  progress(progress) {\n    this._progress = Math.floor(progress);\n    if (this._progress > this._lastProgressSent) {\n      if (this._progress >= 100) {\n        this._progress = 100;\n        this._lastProgressSent = 100;\n        this._isDone = true;\n        this.view.pushFileProgress(this.fileEl, this.ref, 100, () => {\n          LiveUploader.untrackFile(this.fileEl, this.file);\n          this._onDone();\n        });\n      } else {\n        this._lastProgressSent = this._progress;\n        this.view.pushFileProgress(this.fileEl, this.ref, this._progress);\n      }\n    }\n  }\n  isCancelled() {\n    return this._isCancelled;\n  }\n  cancel() {\n    this.file._preflightInProgress = false;\n    this._isCancelled = true;\n    this._isDone = true;\n    this._onDone();\n  }\n  isDone() {\n    return this._isDone;\n  }\n  error(reason = "failed") {\n    this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);\n    this.view.pushFileProgress(this.fileEl, this.ref, { error: reason });\n    if (!this.isAutoUpload()) {\n      LiveUploader.clearFiles(this.fileEl);\n    }\n  }\n  isAutoUpload() {\n    return this.autoUpload;\n  }\n  //private\n  onDone(callback) {\n    this._onDone = () => {\n      this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);\n      callback();\n    };\n  }\n  onElUpdated() {\n    const activeRefs = this.fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");\n    if (activeRefs.indexOf(this.ref) === -1) {\n      LiveUploader.untrackFile(this.fileEl, this.file);\n      this.cancel();\n    }\n  }\n  toPreflightPayload() {\n    return {\n      last_modified: this.file.lastModified,\n      name: this.file.name,\n      relative_path: this.file.webkitRelativePath,\n      size: this.file.size,\n      type: this.file.type,\n      ref: this.ref,\n      meta: typeof this.file.meta === "function" ? this.file.meta() : void 0\n    };\n  }\n  uploader(uploaders) {\n    if (this.meta.uploader) {\n      const callback = uploaders[this.meta.uploader] || logError(`no uploader configured for ${this.meta.uploader}`);\n      return { name: this.meta.uploader, callback };\n    } else {\n      return { name: "channel", callback: channelUploader };\n    }\n  }\n  zipPostFlight(resp) {\n    this.meta = resp.entries[this.ref];\n    if (!this.meta) {\n      logError(`no preflight upload response returned with ref ${this.ref}`, {\n        input: this.fileEl,\n        response: resp\n      });\n    }\n  }\n};\n\n// js/phoenix_live_view/live_uploader.js\nvar liveUploaderFileRef = 0;\nvar LiveUploader = class _LiveUploader {\n  static genFileRef(file) {\n    const ref = file._phxRef;\n    if (ref !== void 0) {\n      return ref;\n    } else {\n      file._phxRef = (liveUploaderFileRef++).toString();\n      return file._phxRef;\n    }\n  }\n  static getEntryDataURL(inputEl, ref) {\n    const file = this.activeFiles(inputEl).find(\n      (file2) => this.genFileRef(file2) === ref\n    );\n    if (!file)\n      return null;\n    return URL.createObjectURL(file);\n  }\n  static hasUploadsInProgress(formEl) {\n    let active = 0;
1\n    dom_default.findUploadInputs(formEl).forEach((input) => {\n      if (input.getAttribute(PHX_PREFLIGHTED_REFS) !== input.getAttribute(PHX_DONE_REFS)) {\n        active++;\n      }\n    });\n    return active > 0;\n  }\n  static serializeUploads(inputEl) {\n    const files = this.activeFiles(inputEl);\n    const fileData = {};\n    files.forEach((file) => {\n      const entry = { path: inputEl.name };\n      const uploadRef = inputEl.getAttribute(PHX_UPLOAD_REF);\n      fileData[uploadRef] = fileData[uploadRef] || [];\n      entry.ref = this.genFileRef(file);\n      entry.last_modified = file.lastModified;\n      entry.name = file.name || entry.ref;\n      entry.relative_path = file.webkitRelativePath;\n      entry.type = file.type;\n      entry.size = file.size;\n      if (typeof file.meta === "function") {\n        entry.meta = file.meta();\n      }\n      fileData[uploadRef].push(entry);\n    });\n    return fileData;\n  }\n  static clearFiles(inputEl) {\n    inputEl.value = null;\n    inputEl.removeAttribute(PHX_UPLOAD_REF);\n    dom_default.putPrivate(inputEl, "files", []);\n  }\n  static untrackFile(inputEl, file) {\n    dom_default.putPrivate(\n      inputEl,\n      "files",\n      dom_default.private(inputEl, "files").filter((f) => !Object.is(f, file))\n    );\n  }\n  /**\n   * @param {HTMLInputElement} inputEl\n   * @param {Array<File|Blob>} files\n   * @param {DataTransfer} [dataTransfer]\n   */\n  static trackFiles(inputEl, files, dataTransfer) {\n    if (inputEl.getAttribute("multiple") !== null) {\n      const newFiles = files.filter(\n        (file) => !this.activeFiles(inputEl).find((f) => Object.is(f, file))\n      );\n      dom_default.updatePrivate(\n        inputEl,\n        "files",\n        [],\n        (existing) => existing.concat(newFiles)\n      );\n      inputEl.value = "";\n    } else {\n      if (dataTransfer && dataTransfer.files.length > 0) {\n        inputEl.files = dataTransfer.files;\n      }\n      dom_default.putPrivate(inputEl, "files", files);\n    }\n  }\n  static activeFileInputs(formEl) {\n    const fileInputs = dom_default.findUploadInputs(formEl);\n    return Array.from(fileInputs).filter(\n      (el) => el.files && this.activeFiles(el).length > 0\n    );\n  }\n  static activeFiles(input) {\n    return (dom_default.private(input, "files") || []).filter(\n      (f) => UploadEntry.isActive(input, f)\n    );\n  }\n  static inputsAwaitingPreflight(formEl) {\n    const fileInputs = dom_default.findUploadInputs(formEl);\n    return Array.from(fileInputs).filter(\n      (input) => this.filesAwaitingPreflight(input).length > 0\n    );\n  }\n  static filesAwaitingPreflight(input) {\n    return this.activeFiles(input).filter(\n      (f) => !UploadEntry.isPreflighted(input, f) && !UploadEntry.isPreflightInProgress(f)\n    );\n  }\n  static markPreflightInProgress(entries) {\n    entries.forEach((entry) => UploadEntry.markPreflightInProgress(entry.file));\n  }\n  constructor(inputEl, view, onComplete) {\n    this.autoUpload = dom_default.isAutoUpload(inputEl);\n    this.view = view;\n    this.onComplete = onComplete;\n    this._entries = Array.from(\n      _LiveUploader.filesAwaitingPreflight(inputEl) || []\n    ).map((file) => new UploadEntry(inputEl, file, view, this.autoUpload));\n    _LiveUploader.markPreflightInProgress(this._entries);\n    this.numEntriesInProgress = this._entries.length;\n  }\n  isAutoUpload() {\n    return this.autoUpload;\n  }\n  entries() {\n    return this._entries;\n  }\n  initAdapterUpload(resp, onError, liveSocket) {\n    this._entries = this._entries.map((entry) => {\n      if (entry.isCancelled()) {\n        this.numEntriesInProgress--;\n        if (this.numEntriesInProgress === 0) {\n          this.onComplete();\n        }\n      } else {\n        entry.zipPostFlight(resp);\n        entry.onDone(() => {\n          this.numEntriesInProgress--;\n          if (this.numEntriesInProgress === 0) {\n            this.onComplete();\n          }\n        });\n      }\n      return entry;\n    });\n    const groupedEntries = this._entries.reduce((acc, entry) => {\n      if (!entry.meta) {\n        return acc;\n      }\n      const { name, callback } = entry.uploader(liveSocket.uploaders);\n      acc[name] = acc[name] || { callback, entries: [] };\n      acc[name].entries.push(entry);\n      return acc;\n    }, {});\n    for (const name in groupedEntries) {\n      const { callback, entries } = groupedEntries[name];\n      callback(entries, onError, resp, liveSocket);\n    }\n  }\n};\n\n// js/phoenix_live_view/aria.ts\nvar ARIA = {\n  anyOf(instance, classes) {\n    return classes.some((name) => instance instanceof name);\n  },\n  isFocusable(el, interactiveOnly = false) {\n    return el instanceof HTMLAnchorElement && el.rel !== "ignore" || el instanceof HTMLAreaElement && el.href !== void 0 || !("disabled" in el && el.disabled) && this.anyOf(el, [\n      HTMLInputElement,\n      HTMLSelectElement,\n      HTMLTextAreaElement,\n      HTMLButtonElement\n    ]) || el instanceof HTMLIFrameElement || el instanceof HTMLElement && el.tabIndex >= 0 && el.getAttribute("aria-hidden") !== "true" || !interactiveOnly && el.getAttribute("tabindex") !== null && el.getAttribute("aria-hidden") !== "true";\n  },\n  attemptFocus(el, interactiveOnly = false) {\n    if (this.isFocusable(el, interactiveOnly)) {\n      tr
1y {\n        el.focus();\n      } catch {\n      }\n    }\n    return !!document.activeElement && document.activeElement.isSameNode(el);\n  },\n  focusFirstInteractive(el) {\n    let child = el.firstElementChild;\n    while (child) {\n      if (this.attemptFocus(child, true) || this.focusFirstInteractive(child)) {\n        return true;\n      }\n      child = child.nextElementSibling;\n    }\n    return false;\n  },\n  focusFirst(el) {\n    let child = el.firstElementChild;\n    while (child) {\n      if (this.attemptFocus(child) || this.focusFirst(child)) {\n        return true;\n      }\n      child = child.nextElementSibling;\n    }\n    return false;\n  },\n  focusLast(el) {\n    let child = el.lastElementChild;\n    while (child) {\n      if (this.attemptFocus(child) || this.focusLast(child)) {\n        return true;\n      }\n      child = child.previousElementSibling;\n    }\n    return false;\n  }\n};\nvar aria_default = ARIA;\n\n// js/phoenix_live_view/hooks.ts\nvar findScrollContainer = (el) => {\n  if (["HTML", "BODY"].indexOf(el.nodeName.toUpperCase()) >= 0)\n    return null;\n  if (["scroll", "auto"].indexOf(getComputedStyle(el).overflowY) >= 0)\n    return el;\n  return findScrollContainer(el.parentElement);\n};\nvar scrollTop = (scrollContainer) => {\n  if (scrollContainer) {\n    return scrollContainer.scrollTop;\n  } else {\n    return document.documentElement.scrollTop || document.body.scrollTop;\n  }\n};\nvar bottom = (scrollContainer) => {\n  if (scrollContainer) {\n    return scrollContainer.getBoundingClientRect().bottom;\n  } else {\n    return window.innerHeight || document.documentElement.clientHeight;\n  }\n};\nvar phoenix_live_view_esm_top = (scrollContainer) => {\n  if (scrollContainer) {\n    return scrollContainer.getBoundingClientRect().top;\n  } else {\n    return 0;\n  }\n};\nvar isAtViewportTop = (el, scrollContainer) => {\n  const rect = el.getBoundingClientRect();\n  return Math.ceil(rect.top) >= phoenix_live_view_esm_top(scrollContainer) && Math.floor(rect.top) <= bottom(scrollContainer);\n};\nvar isAtViewportBottom = (el, scrollContainer) => {\n  const rect = el.getBoundingClientRect();\n  return Math.ceil(rect.bottom) >= phoenix_live_view_esm_top(scrollContainer) && Math.floor(rect.bottom) <= bottom(scrollContainer);\n};\nvar isWithinViewport = (el, scrollContainer) => {\n  const rect = el.getBoundingClientRect();\n  return Math.ceil(rect.top) >= phoenix_live_view_esm_top(scrollContainer) && Math.floor(rect.top) <= bottom(scrollContainer);\n};\nvar InfiniteScroll = {\n  mounted() {\n    this.scrollContainer = findScrollContainer(this.el);\n    let scrollBefore = scrollTop(this.scrollContainer);\n    let topOverran = false;\n    const throttleInterval = 500;\n    let pendingOp = null;\n    const onTopOverrun = this.throttle(\n      throttleInterval,\n      (topEvent, firstChild) => {\n        pendingOp = () => true;\n        this.liveSocket.js().push(this.el, topEvent, {\n          value: { id: firstChild.id, _overran: true },\n          callback: () => {\n            pendingOp = null;\n          }\n        });\n      }\n    );\n    const onFirstChildAtTop = this.throttle(\n      throttleInterval,\n      (topEvent, firstChild) => {\n        pendingOp = () => firstChild.scrollIntoView({ block: "start" });\n        this.liveSocket.js().push(this.el, topEvent, {\n          value: { id: firstChild.id },\n          callback: () => {\n            pendingOp = null;\n            window.requestAnimationFrame(() => {\n              if (!isWithinViewport(firstChild, this.scrollContainer)) {\n                firstChild.scrollIntoView({ block: "start" });\n              }\n            });\n          }\n        });\n      }\n    );\n    const onLastChildAtBottom = this.throttle(\n      throttleInterval,\n      (bottomEvent, lastChild) => {\n        pendingOp = () => lastChild.scrollIntoView({ block: "end" });\n        this.liveSocket.js().push(this.el, bottomEvent, {\n          value: { id: lastChild.id },\n          callback: () => {\n            pendingOp = null;\n            window.requestAnimationFrame(() =>
1 {\n              if (!isWithinViewport(lastChild, this.scrollContainer)) {\n                lastChild.scrollIntoView({ block: "end" });\n              }\n            });\n          }\n        });\n      }\n    );\n    this.onScroll = (_e) => {\n      const scrollNow = scrollTop(this.scrollContainer);\n      if (pendingOp) {\n        scrollBefore = scrollNow;\n        return pendingOp();\n      }\n      const rect = this.findOverrunTarget();\n      const topEvent = this.el.getAttribute(\n        this.liveSocket.binding("viewport-top")\n      );\n      const bottomEvent = this.el.getAttribute(\n        this.liveSocket.binding("viewport-bottom")\n      );\n      const lastChild = this.el.lastElementChild;\n      const firstChild = this.el.firstElementChild;\n      const isScrollingUp = scrollNow < scrollBefore;\n      const isScrollingDown = scrollNow > scrollBefore;\n      if (isScrollingUp && topEvent && !topOverran && rect.top >= 0) {\n        topOverran = true;\n        onTopOverrun(topEvent, firstChild);\n      } else if (isScrollingDown && topOverran && rect.top <= 0) {\n        topOverran = false;\n      }\n      if (topEvent && isScrollingUp && firstChild && isAtViewportTop(firstChild, this.scrollContainer)) {\n        onFirstChildAtTop(topEvent, firstChild);\n      } else if (bottomEvent && isScrollingDown && lastChild && isAtViewportBottom(lastChild, this.scrollContainer)) {\n        onLastChildAtBottom(bottomEvent, lastChild);\n      }\n      scrollBefore = scrollNow;\n    };\n    if (this.scrollContainer) {\n      this.scrollContainer.addEventListener("scroll", this.onScroll);\n    } else {\n      window.addEventListener("scroll", this.onScroll);\n    }\n  },\n  updated() {\n    if (this.scrollContainer && !this.scrollContainer.isConnected) {\n      this.destroyed();\n      this.mounted();\n    }\n  },\n  destroyed() {\n    if (this.scrollContainer) {\n      this.scrollContainer.removeEventListener("scroll", this.onScroll);\n    } else {\n      window.removeEventListener("scroll", this.onScroll);\n    }\n  },\n  throttle(interval, callback) {\n    let lastCallAt = 0;\n    let timer;\n    return (...args) => {\n      const now = Date.now();\n      const remainingTime = interval - (now - lastCallAt);\n      if (remainingTime <= 0 || remainingTime > interval) {\n        if (timer) {\n          clearTimeout(timer);\n          timer = null;\n        }\n        lastCallAt = now;\n        callback(...args);\n      } else if (!timer) {\n        timer = setTimeout(() => {\n          lastCallAt = Date.now();\n          timer = null;\n          callback(...args);\n        }, remainingTime);\n      }\n    };\n  },\n  findOverrunTarget() {\n    let rect;\n    const overrunTarget = this.el.getAttribute(\n      this.liveSocket.binding(PHX_VIEWPORT_OVERRUN_TARGET)\n    );\n    if (overrunTarget) {\n      const overrunEl = document.getElementById(overrunTarget);\n      if (overrunEl) {\n        rect = overrunEl.getBoundingClientRect();\n      } else {\n        throw new Error("did not find element with id " + overrunTarget);\n      }\n    } else {\n      rect = this.el.getBoundingClientRect();\n    }\n    return rect;\n  }\n};\nvar LiveFileUpload = {\n  activeRefs() {\n    return this.el.getAttribute(PHX_ACTIVE_ENTRY_REFS);\n  },\n  preflightedRefs() {\n    return this.el.getAttribute(PHX_PREFLIGHTED_REFS);\n  },\n  mounted() {\n    this.js().ignoreAttributes(this.el, ["value"]);\n    this.preflightedWas = this.preflightedRefs();\n  },\n  updated() {\n    const newPreflights = this.preflightedRefs();\n    if (this.preflightedWas !== newPreflights) {\n      this.preflightedWas = newPreflights;\n      if (newPreflights === "") {\n        this.__view().cancelSubmit(this.el.form);\n      }\n    }\n    if (this.activeRefs() === "") {\n      this.el.value = "";\n    }\n    this.el.dispatchEvent(new CustomEvent(PHX_LIVE_FILE_UPDATED));\n  }\n};\nvar LiveImgPreview = {\n  mounted() {\n    this.ref = this.el.getAttribute("data-phx-entry-ref");\n    this.inputEl = document.getElementById(\n      this.el.getAttribute(PHX_UPLOAD_REF)\n    );\n    this.url = LiveUploader.getEntryDataURL(this.inputEl, this.ref);\n    this.el.src = this.url;\n  },\n  destroyed() {\n    URL.revokeObjectURL(this.url);\n  }\n};\nvar Hooks = {\n  LiveFileUpload,\n  LiveImgPreview,\n  FocusWrap: {\n    mounted() {\n      this.focusStart = this.el.firstElementChild;\n      this.focusEnd = this.el.lastElementChild;\n      this.focusStart.addEventListener("focus", (e) => {\n        if (!e.relatedTarget || !this.el.contains(e.relatedTarget)) {\n          const nextFocus = e.target.nextElementSibling;\n          aria_default.attemptFocus(nextFocus) || aria_default.focu
1sFirst(nextFocus);\n        } else {\n          aria_default.focusLast(this.el);\n        }\n      });\n      this.focusEnd.addEventListener("focus", (e) => {\n        if (!e.relatedTarget || !this.el.contains(e.relatedTarget)) {\n          const nextFocus = e.target.previousElementSibling;\n          aria_default.attemptFocus(nextFocus) || aria_default.focusLast(nextFocus);\n        } else {\n          aria_default.focusFirst(this.el);\n        }\n      });\n      if (!this.el.contains(document.activeElement)) {\n        this.el.addEventListener("phx:show-end", () => this.el.focus());\n        if (window.getComputedStyle(this.el).display !== "none") {\n          aria_default.focusFirst(this.el);\n        }\n      }\n    }\n  },\n  InfiniteScroll\n};\nvar hooks_default = Hooks;\n\n// js/phoenix_live_view/element_ref.ts\nvar ElementRef = class {\n  static onUnlock(el, callback) {\n    if (!dom_default.isLocked(el) && !el.closest(`[${PHX_REF_LOCK}]`)) {\n      return callback();\n    }\n    const closestLock = el.closest(`[${PHX_REF_LOCK}]`);\n    const ref = closestLock.closest(`[${PHX_REF_LOCK}]`).getAttribute(PHX_REF_LOCK);\n    closestLock.addEventListener(\n      `phx:undo-lock:${ref}`,\n      () => {\n        callback();\n      },\n      { once: true }\n    );\n  }\n  constructor(el) {\n    this.el = el;\n    this.loadingRef = el.hasAttribute(PHX_REF_LOADING) ? parseInt(el.getAttribute(PHX_REF_LOADING), 10) : null;\n    this.lockRef = el.hasAttribute(PHX_REF_LOCK) ? parseInt(el.getAttribute(PHX_REF_LOCK), 10) : null;\n  }\n  // public\n  maybeUndo(ref, phxEvent, eachCloneCallback) {\n    if (!this.isWithin(ref)) {\n      dom_default.updatePrivate(this.el, PHX_PENDING_REFS, [], (pendingRefs) => {\n        pendingRefs.push(ref);\n        return pendingRefs;\n      });\n      return;\n    }\n    this.undoLocks(ref, phxEvent, eachCloneCallback);\n    this.undoLoading(ref, phxEvent);\n    dom_default.updatePrivate(this.el, PHX_PENDING_REFS, [], (pendingRefs) => {\n      return pendingRefs.filter((pendingRef) => {\n        let opts = {\n          detail: { ref: pendingRef, event: phxEvent },\n          bubbles: true,\n          cancelable: false\n        };\n        if (this.loadingRef && this.loadingRef > pendingRef) {\n          this.el.dispatchEvent(\n            new CustomEvent(`phx:undo-loading:${pendingRef}`, opts)\n          );\n        }\n        if (this.lockRef && this.lockRef > pendingRef) {\n          this.el.dispatchEvent(\n            new CustomEvent(`phx:undo-lock:${pendingRef}`, opts)\n          );\n        }\n        return pendingRef > ref;\n      });\n    });\n    if (this.isFullyResolvedBy(ref)) {\n      this.el.removeAttribute(PHX_REF_SRC);\n    }\n  }\n  // private\n  isWithin(ref) {\n    return !(this.loadingRef !== null && this.loadingRef > ref && this.lockRef !== null && this.lockRef > ref);\n  }\n  // Check for cloned PHX_REF_LOCK element that has been morphed behind\n  // the scenes while this element was locked in the DOM.\n  // When we apply the cloned tree to the active DOM element, we must\n  //\n  //   1. execute pending mounted hooks for nodes now in the DOM\n  //   2. undo any ref inside the cloned tree that has since been ack\'d\n  undoLocks(ref, phxEvent, eachCloneCallback) {\n    if (!this.isLockUndoneBy(ref)) {\n      return;\n    }\n    const clonedTree = dom_default.private(this.el, PHX_REF_LOCK);\n    if (clonedTree) {\n      eachCloneCallback(clonedTree);\n      dom_default.deletePrivate(this.el, PHX_REF_LOCK);\n    }\n    this.el.removeAttribute(PHX_REF_LOCK);\n    const opts = {\n      detail: { ref, event: phxEvent },\n      bubbles: true,\n      cancelable: false\n    };\n    this.el.dispatchEvent(\n      new CustomEvent(`phx:undo-lock:${this.lockRef}`, opts)\n    );\n  }\n  undoLoading(ref, phxEvent) {\n    if (!this.isLoadingUndoneBy(ref)) {\n      if (this.canUndoLoading(ref) && this.el.classList.contains("phx-submit-loading")) {\n        this.el.classList.remove("phx-change-loading");\n      }\n      return;\n    }\n    if (this.canUndoLoading(ref)) {\n      this.el.removeAttribute(PHX_REF_LOADING);\n      const disabledVal = this.el.getAttribute(PHX_DISABLED);\n      const readOnlyVal = this.el.getAttribute(PHX_READONLY);\n      if (readOnlyVal !== null && "readOnly" in this.el) {\n        this.el.readOnly = readOnlyVal === "true" ? true : false;\n        this.el.removeAttribute(PHX_READONLY);\n      }\n      if (disabledVal !== null && "disabled" in this.el) {\n        this.el.disabled = disabledVal === "true" ? true : false;\n        this.el.removeAttribute(PHX_DISABLED);\n      }\n      const disableRestore = this.el.getAttribute(PHX_DISABLE_WITH_RESTORE);\n      if (disableRestore !== null) {\n        this.el.textContent = disableRestore;\n        this.el.removeAttribute(PHX_DISABLE_WITH_RESTORE);\n      }\n      const opts = {\n        detail: { ref, event: phxEvent },\n        bubbles: true,\n        cancelable: false\n      };\n      this.el.dispatchEvent(\n        new CustomEvent(`phx:undo-loading:${this.loadingRef}`, opts)\n      );\n    }\n    PHX_EVENT_CLASSES.forEach((name) => {\n      if (name !== "phx-submit-loading" || this.canUndoLoading(ref)) {\n        dom_default.removeClass(this.el, name);\n      }\n    });\n  }\n  isLoadingUndoneBy(ref) {\n    return this.loadingRef === null ? false : this.loadingRef <= ref;\n  }\n  /** @internal */\n  isLockUndoneBy(ref) {\n    return this.lockRef === null ? false : this.lockRef <= ref;\n  }\n  isFullyResolvedBy(ref) {\n    return (this.loadingRef === null || this.loadingRef <= ref) && (this.lockRef === null || this.lockRef <= ref);\n  }\n  // only remove the phx-submit-loading class if we are not locked\n  canUndoLoading(ref) {\n    return this.lockRef === null || this.lockRef <= ref;\n  }\n};\n\n// js/phoenix_live_view/dom_post_morph_restorer.ts\nvar DOMPostMorphRestorer = class {\n  constructor(containerBefore, containerAfter, updateType) {\n    const idsBefore = /* @__PURE__ */ new Set();\n    const idsAfter = new Set(\n      [...containerAfter.children].map((child) => child.id)\n    );\n    const elementsToModify = [];
1\n    Array.from(containerBefore.children).forEach((child) => {\n      if (child.id) {\n        idsBefore.add(child.id);\n        if (idsAfter.has(child.id)) {\n          const previousElementId = child.previousElementSibling && child.previousElementSibling.id;\n          elementsToModify.push({\n            elementId: child.id,\n            previousElementId\n          });\n        }\n      }\n    });\n    this.containerId = containerAfter.id;\n    this.updateType = updateType;\n    this.elementsToModify = elementsToModify;\n    this.elementIdsToAdd = [...idsAfter].filter((id) => !idsBefore.has(id));\n  }\n  // We do the following to optimize append/prepend operations:\n  //   1) Track ids of modified elements & of new elements\n  //   2) All the modified elements are put back in the correct position in the DOM tree\n  //      by storing the id of their previous sibling\n  //   3) New elements are going to be put in the right place by morphdom during append.\n  //      For prepend, we move them to the first position in the container\n  perform() {\n    const container = dom_default.byId(this.containerId);\n    if (!container) {\n      return;\n    }\n    this.elementsToModify.forEach((elementToModify) => {\n      if (elementToModify.previousElementId) {\n        maybe(\n          document.getElementById(elementToModify.previousElementId),\n          (previousElem) => {\n            maybe(\n              document.getElementById(elementToModify.elementId),\n              (elem) => {\n                const isInRightPlace = elem.previousElementSibling && elem.previousElementSibling.id == previousElem.id;\n                if (!isInRightPlace) {\n                  previousElem.insertAdjacentElement("afterend", elem);\n                }\n              }\n            );\n          }\n        );\n      } else {\n        maybe(document.getElementById(elementToModify.elementId), (elem) => {\n          const isInRightPlace = elem.previousElementSibling == null;\n          if (!isInRightPlace) {\n            container.insertAdjacentElement("afterbegin", elem);\n          }\n        });\n      }\n    });\n    if (this.updateType == "prepend") {\n      this.elementIdsToAdd.reverse().forEach((elemId) => {\n        maybe(\n          document.getElementById(elemId),\n          (elem) => container.insertAdjacentElement("afterbegin", elem)\n        );\n      });\n    }\n  }\n};\n\n// ../node_modules/morphdom/dist/morphdom-esm.js\nvar DOCUMENT_FRAGMENT_NODE = 11;\nfunction morphAttrs(fromNode, toNode) {\n  var toNodeAttrs = toNode.attributes;\n  var attr;\n  var attrName;\n  var attrNamespaceURI;\n  var attrValue;\n  var fromValue;\n  if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE || fromNode.nodeType === DOCUMENT_FRAGMENT_NODE) {\n    return;\n  }\n  for (var i = toNodeAttrs.length - 1; i >= 0; i--) {\n    attr = toNodeAttrs[i];\n    attrName = attr.name;\n    attrNamespaceURI = attr.namespaceURI;\n    attrValue = attr.value;\n    if (attrNamespaceURI) {\n      attrName = attr.localName || attrName;\n      fromValue = fromNode.getAttributeNS(attrNamespaceURI, attrName);\n      if (fromValue !== attrValue) {\n        if (attr.prefix === "xmlns") {\n          attrName = attr.name;\n        }\n        fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue);\n      }\n    } else {\n      fromValue = fromNode.getAttribute(attrName);\n      if (fromValue !== attrValue) {\n        fromNode.setAttribute(attrName, attrValue);\n      }\n    }\n  }\n  var fromNodeAttrs = fromNode.attributes;\n  for (var d = fromNodeAttrs.length - 1; d >= 0; d--) {\n    attr = fromNodeAttrs[d];\n    attrName = attr.name;\n    attrNamespaceURI = attr.namespaceURI;\n    if (attrNamespaceURI) {\n      attrName = attr.localName || attrName;\n      if (!toNode.hasAttributeNS(attrNamespaceURI, attrName)) {\n        fromNode.removeAttributeNS(attrNamespaceURI, attrName);\n      }\n    } else {\n      if (!toNode.hasAttribute(attrName)) {\n        fromNode.removeAttribute(attrName);\n      }\n    }\n  }\n}\nvar range;\nvar NS_XHTML = "http://www.w3.org/1999/xhtml";\nvar doc = typeof document === "undefined" ? void 0 : document;
1\nvar HAS_TEMPLATE_SUPPORT = !!doc && "content" in doc.createElement("template");\nvar HAS_RANGE_SUPPORT = !!doc && doc.createRange && "createContextualFragment" in doc.createRange();\nfunction createFragmentFromTemplate(str) {\n  var template = doc.createElement("template");\n  template.innerHTML = str;\n  return template.content.childNodes[0];\n}\nfunction createFragmentFromRange(str) {\n  if (!range) {\n    range = doc.createRange();\n    range.selectNode(doc.body);\n  }\n  var fragment = range.createContextualFragment(str);\n  return fragment.childNodes[0];\n}\nfunction createFragmentFromWrap(str) {\n  var fragment = doc.createElement("body");\n  fragment.innerHTML = str;\n  return fragment.childNodes[0];\n}\nfunction toElement(str) {\n  str = str.trim();\n  if (HAS_TEMPLATE_SUPPORT) {\n    return createFragmentFromTemplate(str);\n  } else if (HAS_RANGE_SUPPORT) {\n    return createFragmentFromRange(str);\n  }\n  return createFragmentFromWrap(str);\n}\nfunction compareNodeNames(fromEl, toEl) {\n  var fromNodeName = fromEl.nodeName;\n  var toNodeName = toEl.nodeName;\n  var fromCodeStart, toCodeStart;\n  if (fromNodeName === toNodeName) {\n    return true;\n  }\n  fromCodeStart = fromNodeName.charCodeAt(0);\n  toCodeStart = toNodeName.charCodeAt(0);\n  if (fromCodeStart <= 90 && toCodeStart >= 97) {\n    return fromNodeName === toNodeName.toUpperCase();\n  } else if (toCodeStart <= 90 && fromCodeStart >= 97) {\n    return toNodeName === fromNodeName.toUpperCase();\n  } else {\n    return false;\n  }\n}\nfunction createElementNS(name, namespaceURI) {\n  return !namespaceURI || namespaceURI === NS_XHTML ? doc.createElement(name) : doc.createElementNS(namespaceURI, name);\n}\nfunction moveChildren(fromEl, toEl) {\n  var curChild = fromEl.firstChild;\n  while (curChild) {\n    var nextChild = curChild.nextSibling;\n    toEl.appendChild(curChild);\n    curChild = nextChild;\n  }\n  return toEl;\n}\nfunction syncBooleanAttrProp(fromEl, toEl, name) {\n  if (fromEl[name] !== toEl[name]) {\n    fromEl[name] = toEl[name];\n    if (fromEl[name]) {\n      fromEl.setAttribute(name, "");\n    } else {\n      fromEl.removeAttribute(name);\n    }\n  }\n}\nvar specialElHandlers = {\n  OPTION: function(fromEl, toEl) {\n    var parentNode = fromEl.parentNode;\n    if (parentNode) {\n      var parentName = parentNode.nodeName.toUpperCase();\n      if (parentName === "OPTGROUP") {\n        parentNode = parentNode.parentNode;\n        parentName = parentNode && parentNode.nodeName.toUpperCase();\n      }\n      if (parentName === "SELECT" && !parentNode.hasAttribute("multiple")) {\n        if (fromEl.hasAttribute("selected") && !toEl.selected) {\n          fromEl.setAttribute("selected", "selected");\n          fromEl.removeAttribute("selected");\n        }\n        parentNode.selectedIndex = -1;\n      }\n    }\n    syncBooleanAttrProp(fromEl, toEl, "selected");\n  },\n  /**\n   * The "value" attribute is special for the <input> element since it sets\n   * the initial value. Changing the "value" attribute without changing the\n   * "value" property will have no effect since it is only used to the set the\n   * initial value.  Similar for the "checked" attribute, and "disabled".\n   */\n  INPUT: function(fromEl, toEl) {\n    syncBooleanAttrProp(fromEl, toEl, "checked");\n    syncBooleanAttrProp(fromEl, toEl, "disabled");\n    if (fromEl.value !== toEl.value) {\n      fromEl.value = toEl.value;\n    }\n    if (!toEl.hasAttribute("value")) {\n      fromEl.removeAttribute("value");\n    }\n  },\n  TEXTAREA: function(fromEl, toEl) {\n    var newValue = toEl.value;\n    if (fromEl.value !== newValue) {\n      fromEl.value = newValue;\n    }\n    var firstChild = fromEl.firstChild;\n    if (firstChild) {\n      var oldValue = firstChild.nodeValue;\n      if (oldValue == newValue || !newValue && oldValue == fromEl.placeholder) {\n        return;\n      }\n      firstChild.nodeValue = newValue;\n    }\n  },\n  SELECT: function(fromEl, toEl) {\n    if (!toEl.hasAttribute("multiple")) {\n      var selectedIndex = -1;\n      var i = 0;\n      var curChild = fromEl.firstChild;\n      var optgroup;\n      var nodeName;\n      while (curChild) {\n        nodeName = curChild.nodeName && curChild.nodeName.toUpperCase();\n        if (nodeName === "OPTGROUP") {\n          optgroup = curChild;\n          curChild = optgroup.firstChild;\n          if (!curChild) {\n            curChild = optgroup.nextSibling;\n            optgroup = null;\n          }\n        } else {\n          if (nodeName === "OPTION") {\n            if (curChild.hasAttribute("selected")) {\n              selectedIndex = i;\n              break;\n            }\n            i++;\n          }\n          curChild = curChild.nextSibling;\n          if (!curChild && optgroup) {\n            curChild = optgroup.nextSibling;\n            optgroup = null;\n          }\n        }\n      }\n      fromEl.selectedIndex = selectedIndex;\n    }\n  }\n};\nvar ELEMENT_NODE = 1;\nvar DOCUMENT_FRAGMENT_NODE$1 = 11;\nvar TEXT_NODE = 3;\nvar COMMENT_NODE = 8;\nfunction noop() {\n}\nfunction defaultGetNodeKey(node) {\n  if (node) {\n    return node.getAttribute && node.getAttribute("id") || node.id;\n  }\n}\nfunction morphdomFactory(morphAttrs2) {\n  return function morphdom2(fromNode, toNode, options) {\n    if (!options) {\n      options = {};\n    }\n    if (typeof toNode === "string") {\n      if (fromNode.nodeName === "#document" || fromNode.nodeName === "HTML") {\n        var toNodeHtml = toNode;\n        toNode = doc.createElement("html");\n        toNode.innerHTML = toNodeHtml;\n      } else if (fromNode.nodeName === "BODY") {\n        var toNodeBody = toNode;\n        toNode = doc.createElement("html");\n        toNode.innerHTML = toNodeBody;\n        var bodyElement = toNode.querySelector("body");\n        if (bodyElement) {\n          toNode = bodyElement;\n        }\n      } else {\n        toNode = toElement(toNode);\n      }\n    } else if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE$1) {\n      toNode = toNode.firstElementChild;\n    }\n    var getNodeKey = options.getNodeKey || defaultGetNodeKey;\n    var onBeforeNodeAdded = options.onBeforeNodeAdded || noop;\n    var onNodeAdded = options.onNodeAdded || noop;\n    var onBeforeElUpdated = options.onBeforeElUpdated || noop;\n    var onElUpdated = options.onElUpdated || noop;\n    var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop;\n    var onNodeDiscarded = options.onNodeDiscarded || noop;\n    var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop;\n    var skipFromChildren = options.skipFromChildren || noop;\n    var addChild = options.addChild || function(parent, child) {\n      return parent.appendChild(child);\n    };\n    var childrenOnly = options.childrenOnly === true;\n    var fromNodesLookup = /* @__PURE__ */ Object.create(null);\n    var keyedRemovalList = [];\n    function addKeyedRemoval(key) {\n      keyedRemovalList.push(key);\n    }\n    function walkDiscardedChildNodes(node, skipKeyedNodes) {\n      if (node.nodeType === ELEMENT_NODE) {\n        var curChild = node.firstChild;\n        while (curChild) {\n          var key = void 0;\n          if (skipKeyedNodes && (key = getNodeKey(curChild))) {\n            addKeyedRemoval(key);\n          } else {\n            onNodeDiscarded(curChild);\n            if (curChild.firstChild) {\n              walkDiscardedChildNodes(curChild, skipKeyedNodes);\n            }\n          }\n          curChild = curChild.nextSibling;\n        }\n      }\n    }\n    function removeNode(node, parentNode, skipKeyedNodes) {\n      if (onBeforeNodeDiscarded(node) === false) {\n        return;\n      }\n      if (parentNode) {\n        parentNode.removeChild(node);\n      }\n      onNodeDiscarded(node);\n      walkDiscardedChildNodes(node, skipKeyedNodes);\n    }\n    function indexTree(node) {\n      if (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE$1) {\n        var curChild = node.firstChild;\n        while (curChild) {\n          var key = getNodeKey(curChild);\n          if (key) {\n            fromNodesLookup[key] = curChild;\n          }\n          indexTree(curChild);\n          curChild = curChild.nextSibling;\n        }\n      }\n    }\n    indexTree(fromNode);\n    function handleNodeAdded(el) {\n      onNodeAdded(el);\n      var curChild = el.firstChild;\n      while (curChild) {\n        var nextSibling = curChild.nextSibling;\n        var key = getNodeKey(curChild);\n        if (key) {\n          var unmatchedFromEl = fromNodesLookup[key];\n          if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) {\n            curChild.parentNode.replaceChild(unmatchedFromEl, curChild);\n            morphEl(unmatchedFromEl, curChild);\n          } else {\n            handleNodeAdded(curChild);\n          }\n        } else {\n          handleNodeAdded(curChild);\n        }\n        curChild = nextSibling;\n      }\n    }\n    function cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey) {\n      while (curFromNodeChild) {\n        var fromNextSibling = curFromNodeChild.nextSibling;\n        if (curFromNodeKey = getNodeKey(curFromNodeChild)) {\n          addKeyedRemoval(curFromNodeKey);\n        } else {\n          removeNode(\n            curFromNodeChild,\n            fromEl,\n            true\n            /* skip keyed nodes */\n          );\n        }\n        curFromNodeChild = fromNextSibling;\n      }\n    }\n    function morphEl(fromEl, toEl, childrenOnly2) {\n      var toElKey = getNodeKey(toEl);\n      if (toElKey) {\n        delete fromNodesLookup[toElKey];\n      }\n      if (!childrenOnly2) {\n        var beforeUpdateResult = onBeforeElUpdated(fromEl, toEl);\n        if (beforeUpdateResult === false) {\n          return;\n        } else if (beforeUpdateResult instanceof HTMLElement) {\n          fromEl = beforeUpdateResult;\n          indexTree(fromEl);\n        }\n        morphAttrs2(fromEl, toEl);\n        onElUpdated(fromEl);\n        if (onBeforeElChildrenUpdated(fromEl, toEl) === false) {\n          return;\n        }\n      }\n      if (fromEl.nodeName !== "TEXTAREA") {\n        morphChildren(fromEl, toEl);\n      } else {\n        specialElHandlers.TEXTAREA(fromEl, toEl);\n      }\n    }\n    function morphChildren(fromEl, toEl) {\n      var skipFrom = ski
1pFromChildren(fromEl, toEl);\n      var curToNodeChild = toEl.firstChild;\n      var curFromNodeChild = fromEl.firstChild;\n      var curToNodeKey;\n      var curFromNodeKey;\n      var fromNextSibling;\n      var toNextSibling;\n      var matchingFromEl;\n      outer:\n        while (curToNodeChild) {\n          toNextSibling = curToNodeChild.nextSibling;\n          curToNodeKey = getNodeKey(curToNodeChild);\n          while (!skipFrom && curFromNodeChild) {\n            fromNextSibling = curFromNodeChild.nextSibling;\n            if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) {\n              curToNodeChild = toNextSibling;\n              curFromNodeChild = fromNextSibling;\n              continue outer;\n            }\n            curFromNodeKey = getNodeKey(curFromNodeChild);\n            var curFromNodeType = curFromNodeChild.nodeType;\n            var isCompatible = void 0;\n            if (curFromNodeType === curToNodeChild.nodeType) {\n              if (curFromNodeType === ELEMENT_NODE) {\n                if (curToNodeKey) {\n                  if (curToNodeKey !== curFromNodeKey) {\n                    if (matchingFromEl = fromNodesLookup[curToNodeKey]) {\n                      if (fromNextSibling === matchingFromEl) {\n                        isCompatible = false;\n                      } else {\n                        fromEl.insertBefore(matchingFromEl, curFromNodeChild);\n                        if (curFromNodeKey) {\n                          addKeyedRemoval(curFromNodeKey);\n                        } else {\n                          removeNode(\n                            curFromNodeChild,\n                            fromEl,\n                            true\n                            /* skip keyed nodes */\n                          );\n                        }\n                        curFromNodeChild = matchingFromEl;\n                        curFromNodeKey = getNodeKey(curFromNodeChild);\n                      }\n                    } else {\n                      isCompatible = false;\n                    }\n                  }\n                } else if (curFromNodeKey) {\n                  isCompatible = false;\n                }\n                isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild);\n                if (isCompatible) {\n                  morphEl(curFromNodeChild, curToNodeChild);\n                }\n              } else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) {\n                isCompatible = true;\n                if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) {\n                  curFromNodeChild.nodeValue = curToNodeChild.nodeValue;\n                }\n              }\n            }\n            if (isCompatible) {\n              curToNodeChild = toNextSibling;\n              curFromNodeChild = fromNextSibling;\n              continue outer;\n            }\n            if (curFromNodeKey) {\n              addKeyedRemoval(curFromNodeKey);\n            } else {\n              removeNode(\n                curFromNodeChild,\n                fromEl,\n                true\n                /* skip keyed nodes */\n              );\n            }\n            curFromNodeChild = fromNextSibling;\n          }\n          if (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) {\n            if (!skipFrom) {\n              addChild(fromEl, matchingFromEl);\n            }\n            morphEl(matchingFromEl, curToNodeChild);\n          } else {\n            var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild);\n            if (onBeforeNodeAddedResult !== false) {\n              if (onBeforeNodeAddedResult) {\n                curToNodeChild = onBeforeNodeAddedResult;\n              }\n              if (curToNodeChild.actualize) {\n                curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc);\n              }\n              addChild(fromEl, curToNodeChild);\n              handleNodeAdded(curToNodeChild);\n            }\n          }\n          curToNodeChild = toNextSibling;\n          curFromNodeChild = fromNextSibling;\n        }\n      cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey);\n      var specialElHandler = specialElHandlers[fromEl.nodeName];\n      if (specialElHandler) {\n        specialElHandler(fromEl, toEl);\n      }\n    }\n    var morphedNode = fromNode;\n    var morphedNodeType = morphedNode.nodeType;\n    var toNodeType = toNode.nodeType;\n    if (!childrenOnly) {\n      if (morphedNodeType === ELEMENT_NODE) {\n        if (toNodeType === ELEMENT_NODE) {\n          if (!compareNodeNames(fromNode, toNode)) {\n            onNodeDiscarded(fromNode);\n            morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI));\n          }\n        } else {\n          morphedNode = toNode;\n        }\n      } else if (morphedNodeType === TEXT_NODE || morphedNodeType === COMMENT_NODE) {\n        if (toNodeType === morphedNodeType) {\n          if (morphedNode.nodeValue !== toNode.nodeValue) {\n            morphedNode.nodeValue = toNode.nodeValue;\n          }\n          return morphedNode;\n        } else {\n          morphedNode = toNode;\n        }\n      }\n    }\n    if (morphedNode === toNode) {\n      onNodeDiscarded(fromNode);\n    } else {\n      if (toNode.isSameNode && toNode.isSameNode(morphedNode)) {\n        return;\n      }\n      morphEl(morphedNode, toNode, childrenOnly);\n      if (keyedRemovalList) {\n        for (var i = 0, len = keyedRemovalList.length; i < len;
1 i++) {\n          var elToRemove = fromNodesLookup[keyedRemovalList[i]];\n          if (elToRemove) {\n            removeNode(elToRemove, elToRemove.parentNode, false);\n          }\n        }\n      }\n    }\n    if (!childrenOnly && morphedNode !== fromNode && fromNode.parentNode) {\n      if (morphedNode.actualize) {\n        morphedNode = morphedNode.actualize(fromNode.ownerDocument || doc);\n      }\n      fromNode.parentNode.replaceChild(morphedNode, fromNode);\n    }\n    return morphedNode;\n  };\n}\nvar morphdom = morphdomFactory(morphAttrs);\nvar morphdom_esm_default = morphdom;\n\n// js/phoenix_live_view/dom_patch.ts\nvar DOMPatch = class {\n  constructor(view, container, html, streams, targetCID, opts = {}) {\n    this.view = view;\n    this.liveSocket = view.liveSocket;\n    this.container = container;\n    this.rootID = view.root.id;\n    this.html = html;\n    this.streams = streams;\n    this.streamInserts = {};\n    this.streamComponentRestore = {};\n    this.targetCID = targetCID;\n    this.pendingRemoves = [];\n    this.phxRemove = this.liveSocket.binding("remove");\n    this.targetContainer = targetCID ? dom_default.getComponent(this.view.id, targetCID) : container;\n    this.beforeUpdatedCallbacks = [];\n    this.afterAddedCallbacks = [];\n    this.afterUpdatedCallbacks = [];\n    this.afterPhxChildAddedCallbacks = [];\n    this.afterDiscardedCallbacks = [];\n    this.afterTransitionsDiscardedCallbacks = [];\n    this.withChildren = opts.withChildren || opts.undoRef !== void 0 || false;\n    this.undoRef = opts.undoRef ?? null;\n  }\n  beforeUpdated(callback) {\n    this.beforeUpdatedCallbacks.push(callback);\n  }\n  afterAdded(callback) {\n    this.afterAddedCallbacks.push(callback);\n  }\n  afterUpdated(callback) {\n    this.afterUpdatedCallbacks.push(callback);\n  }\n  afterPhxChildAdded(callback) {\n    this.afterPhxChildAddedCallbacks.push(callback);\n  }\n  afterDiscarded(callback) {\n    this.afterDiscardedCallbacks.push(callback);\n  }\n  afterTransitionsDiscarded(callback) {\n    this.afterTransitionsDiscardedCallbacks.push(callback);\n  }\n  markPrunableContentForRemoval() {\n    const phxUpdate = this.liveSocket.binding(PHX_UPDATE);\n    dom_default.all(\n      this.container,\n      `[${phxUpdate}=append] > *, [${phxUpdate}=prepend] > *`,\n      (el) => {\n        el.setAttribute(PHX_PRUNE, "");\n      }\n    );\n  }\n  perform(isJoinPatch) {\n    const { view, liveSocket, html, container } = this;\n    let targetContainer = this.targetContainer;\n    if (this.targetCID) {\n      const closestLock = targetContainer.closest(`[${PHX_REF_LOCK}]`);\n      if (closestLock && !closestLock.isSameNode(targetContainer)) {\n        const clonedTree = dom_default.private(closestLock, PHX_REF_LOCK);\n        if (clonedTree) {\n          targetContainer = clonedTree.querySelector(\n            `[data-phx-component="${this.targetCID}"]`\n          );\n          if (!targetContainer)\n            return;\n        }\n      }\n    }\n    const focused = liveSocket.getActiveElement();\n    const { selectionStart, selectionEnd } = focused && dom_default.hasSelectionRange(focused) ? focused : {};\n    const phxUpdate = liveSocket.binding(PHX_UPDATE);\n    const phxViewportTop = liveSocket.binding(PHX_VIEWPORT_TOP);\n    const phxViewportBottom = liveSocket.binding(PHX_VIEWPORT_BOTTOM);\n    const phxTriggerExternal = liveSocket.binding(PHX_TRIGGER_ACTION);\n    const added = [];\n    const updates = [];\n    const appendPrependUpdates = [];\n    let portalCallbacks = [];\n    let externalFormTriggered = null;\n    const morph = (targetContainer2, source, withChildren = this.withChildren) => {\n      const morphCallbacks = {\n        // normally, we are running with childrenOnly, as the patch HTML for a LV\n        // does not include the LV attrs (data-phx-session, etc.)\n        // when we are patching a live component, we do want to patch the root element as well;\n        // another case is the recursive patch of a stream item that was kept on reset (-> onBeforeNodeAdded)\n        childrenOnly: targetContainer2.getAttribute(PHX_COMPONENT) === null && !withChildren,\n        getNodeKey: (node) => {\n          if (!(node instanceof Element))\n            return null;\n          if (dom_default.isPhxDestroyed(node)) {\n            return null;\n          }\n          if (isJoinPatch) {\n            return node.id;\n          }\n          if (dom_default.private(node, "clientsideIdAttribute")) {\n            return node.getAttribute(PHX_MAGIC_ID);\n          }\n          return node.id || node.getAttribute(PHX_MAGIC_ID);\n        },\n        // skip indexing from children when container is stream\n        skipFromChildren: (from) => {\n          return from.getAttribute(phxUpdate) === PHX_STREAM;\n        },\n        // tell morphdom how to add a child\n        addChild: (parent, child) =>
1 {\n          const { ref, streamAt } = this.getStreamInsert(child);\n          if (ref === void 0) {\n            return parent.appendChild(child);\n          }\n          this.setStreamRef(child, ref);\n          if (streamAt === 0) {\n            parent.insertAdjacentElement("afterbegin", child);\n          } else if (streamAt === -1) {\n            const lastChild = parent.lastElementChild;\n            if (lastChild && !lastChild.hasAttribute(PHX_STREAM_REF)) {\n              const nonStreamChild = Array.from(parent.children).find(\n                (c) => !c.hasAttribute(PHX_STREAM_REF)\n              );\n              parent.insertBefore(child, nonStreamChild ?? null);\n            } else {\n              parent.appendChild(child);\n            }\n          } else if (streamAt > 0) {\n            const sibling = Array.from(parent.children)[streamAt];\n            parent.insertBefore(child, sibling);\n          }\n        },\n        onBeforeNodeAdded: (el) => {\n          if (!(el instanceof Element)) {\n            return el;\n          }\n          if (this.getStreamInsert(el)?.updateOnly && !this.streamComponentRestore[el.id]) {\n            return false;\n          }\n          dom_default.maintainPrivateHooks(el, el, phxViewportTop, phxViewportBottom);\n          let morphedEl = el;\n          if (this.streamComponentRestore[el.id]) {\n            morphedEl = this.streamComponentRestore[el.id];\n            delete this.streamComponentRestore[el.id];\n            morph(morphedEl, el, true);\n          }\n          return morphedEl;\n        },\n        onNodeAdded: (el) => {\n          if (!(el instanceof Element)) {\n            added.push(el);\n            return;\n          }\n          this.maybeReOrderStream(el, true);\n          if (dom_default.isPortalTemplate(el)) {\n            portalCallbacks.push(() => this.teleport(el, morph));\n          }\n          if (el instanceof HTMLImageElement && el.srcset) {\n            el.srcset = el.srcset;\n          } else if (el instanceof HTMLVideoElement && el.autoplay) {\n            el.play();\n          }\n          if (dom_default.isNowTriggerFormExternal(el, phxTriggerExternal)) {\n            externalFormTriggered = el;\n          }\n          if (dom_default.isPhxChild(el) && view.ownsElement(el) || dom_default.isPhxSticky(el) && view.ownsElement(el.parentNode)) {\n            this.trackAfterPhxChildAdded(el);\n          }\n          if (el.nodeName === "SCRIPT" && el.hasAttribute(PHX_RUNTIME_HOOK)) {\n            this.handleRuntimeHook(el, source);\n          }\n          added.push(el);\n        },\n        onNodeDiscarded: (el) => this.onNodeDiscarded(el),\n        onBeforeNodeDiscarded: (el) => {\n          if (!(el instanceof Element)) {\n            return true;\n          }\n          if (el.getAttribute(PHX_PRUNE) !== null) {\n            return true;\n          }\n          if (el.parentElement !== null && el.id && dom_default.isPhxUpdate(el.parentElement, phxUpdate, [\n            PHX_STREAM,\n            "append",\n            "prepend"\n          ])) {\n            return false;\n          }\n          if (el.getAttribute(PHX_TELEPORTED_REF)) {\n            return false;\n          }\n          if (this.maybePendingRemove(el)) {\n            return false;\n          }\n          if (this.skipCIDSibling(el)) {\n            return false;\n          }\n          if (dom_default.isPortalTemplate(el)) {\n            const teleportedEl = document.getElementById(\n              el.content.firstElementChild?.id || ""\n            );\n            if (teleportedEl) {\n              teleportedEl.remove();\n              morphCallbacks.onNodeDiscarded(teleportedEl);\n              this.view.dropPortalElementId(teleportedEl.id);\n            }\n          }\n          return true;\n        },\n        onElUpdated: (el) => {\n          if (dom_default.isNowTriggerFormExternal(el, phxTriggerExternal)) {\n            externalFormTriggered = el;\n          }\n          updates.push(el);\n          this.maybeReOrderStream(el, false);\n        },\n        onBeforeElUpdated: (fromEl, toEl) => {\n          if (fromEl.id && fromEl.isSameNode(targetContainer2) && fromEl.id !== toEl.id) {\n            morphCallbacks.onNodeDiscarded(fromEl);\n            fromEl.replaceWith(toEl);\n            return morphCallbacks.onNodeAdded(toEl);\n          }\n          dom_default.syncPendingAttrs(fromEl, toEl);\n          dom_default.maintainPrivateHooks(\n            fromEl,\n            toEl,\n            phxViewportTop,\n            phxViewportBottom\n          );\n          dom_default.cleanChildNodes(toEl, phxUpdate);\n          const isFocusedFormEl = focused && fromEl.isSameNode(focused) && dom_default.isEditableInput(fromEl);\n          const focusedSelectChanged = isFocusedFormEl && this.isChangedSelect(fromEl, toEl);\n          if (this.skipCIDSibling(toEl)) {\n            this.maybeCloneLockedElement(fromEl, isFocusedFormEl);\n            this.copyNestedPrivateLock(fromEl, toEl);\n            this.maybeReOrderStream(fromEl);\n            return false;\n          }\n          if (dom_default.isPhxSticky(fromEl)) {\n            [PHX_SESSION, PHX_STATIC, PHX_ROOT_ID].map((attr) => [\n              attr,\n              fromEl.getAttribute(attr),\n              toEl.getAttribute(attr)\n            ]).forEac
1h(([attr, fromVal, toVal]) => {\n              if (toVal && fromVal !== toVal) {\n                fromEl.setAttribute(attr, toVal);\n              }\n            });\n            return false;\n          }\n          if (dom_default.isIgnored(fromEl, phxUpdate) || fromEl.form && fromEl.form.isSameNode(externalFormTriggered)) {\n            this.trackBeforeUpdated(fromEl, toEl);\n            dom_default.mergeAttrs(fromEl, toEl, {\n              isIgnored: dom_default.isIgnored(fromEl, phxUpdate)\n            });\n            updates.push(fromEl);\n            dom_default.applyStickyOperations(fromEl);\n            return false;\n          }\n          if (fromEl.type === "number" && fromEl.validity && fromEl.validity.badInput) {\n            return false;\n          }\n          fromEl = this.maybeCloneLockedElement(fromEl, isFocusedFormEl);\n          if (dom_default.isPhxChild(toEl)) {\n            const prevSession = fromEl.getAttribute(PHX_SESSION);\n            dom_default.mergeAttrs(fromEl, toEl, { exclude: [PHX_STATIC] });\n            if (prevSession !== "") {\n              fromEl.setAttribute(PHX_SESSION, prevSession);\n            }\n            fromEl.setAttribute(PHX_ROOT_ID, this.rootID);\n            dom_default.applyStickyOperations(fromEl);\n            return false;\n          }\n          this.copyNestedPrivateLock(fromEl, toEl);\n          dom_default.copyPrivates(toEl, fromEl);\n          if (dom_default.isPortalTemplate(toEl)) {\n            portalCallbacks.push(() => this.teleport(toEl, morph));\n            fromEl.content.replaceChildren(toEl.content.cloneNode(true));\n            return false;\n          }\n          if (isFocusedFormEl && fromEl.type !== "hidden" && !focusedSelectChanged) {\n            this.trackBeforeUpdated(fromEl, toEl);\n            dom_default.mergeFocusedInput(fromEl, toEl);\n            dom_default.syncAttrsToProps(fromEl);\n            updates.push(fromEl);\n            dom_default.applyStickyOperations(fromEl);\n            return false;\n          } else {\n            if (focusedSelectChanged) {\n              fromEl.blur();\n            }\n            if (dom_default.isPhxUpdate(toEl, phxUpdate, ["append", "prepend"])) {\n              appendPrependUpdates.push(\n                new DOMPostMorphRestorer(\n                  fromEl,\n                  toEl,\n                  toEl.getAttribute(phxUpdate)\n                )\n              );\n            }\n            dom_default.syncAttrsToProps(toEl);\n            dom_default.applyStickyOperations(toEl);\n            this.trackBeforeUpdated(fromEl, toEl);\n            return fromEl;\n          }\n        }\n      };\n      morphdom_esm_default(targetContainer2, source, morphCallbacks);\n    };\n    this.trackBeforeUpdated(container, container);\n    liveSocket.time("morphdom", () => {\n      this.streams.forEach(([ref, inserts, deleteIds, reset]) => {\n        inserts.forEach(([key, streamAt, limit, updateOnly]) => {\n          this.streamInserts[key] = { ref, streamAt, limit, reset, updateOnly };\n        });\n        if (reset !== void 0) {\n          dom_default.all(document, `[${PHX_STREAM_REF}="${ref}"]`, (child) =>
1 {\n            this.removeStreamChildElement(child);\n          });\n        }\n        deleteIds.forEach((id) => {\n          const child = document.getElementById(id);\n          if (child) {\n            this.removeStreamChildElement(child);\n          }\n        });\n      });\n      if (isJoinPatch) {\n        dom_default.all(this.container, `[${phxUpdate}=${PHX_STREAM}]`).filter((el) => this.view.ownsElement(el)).forEach((el) => {\n          Array.from(el.children).forEach((child) => {\n            this.removeStreamChildElement(child, true);\n          });\n        });\n      }\n      morph(targetContainer, html);\n      let teleportCount = 0;\n      while (portalCallbacks.length > 0 && teleportCount < 5) {\n        const copy = portalCallbacks.slice();\n        portalCallbacks = [];\n        copy.forEach((callback) => callback());\n        teleportCount++;\n      }\n      this.view.portalElementIds.forEach((id) => {\n        const el = document.getElementById(id);\n        if (el) {\n          const srcId = el.getAttribute(PHX_TELEPORTED_SRC);\n          if (srcId) {\n            const source = document.getElementById(srcId);\n            if (!source) {\n              el.remove();\n              this.onNodeDiscarded(el);\n              this.view.dropPortalElementId(id);\n            }\n          }\n        }\n      });\n    });\n    if (liveSocket.isDebugEnabled()) {\n      detectDuplicateIds();\n      detectInvalidStreamInserts(this.streamInserts);\n      Array.from(document.querySelectorAll("input[name=id]")).forEach(\n        (node) => {\n          if (node instanceof HTMLInputElement && node.form) {\n            console.error(\n              \'Detected an input with name="id" inside a form! This will cause problems when patching the DOM.\\n\',\n              node\n            );\n          }\n        }\n      );\n    }\n    if (appendPrependUpdates.length > 0) {\n      liveSocket.time("post-morph append/prepend restoration", () => {\n        appendPrependUpdates.forEach((update) => update.perform());\n      });\n    }\n    liveSocket.silenceEvents(\n      () => dom_default.restoreFocus(focused, selectionStart, selectionEnd)\n    );\n    dom_default.dispatchEvent(document, "phx:update");\n    added.forEach((el) => this.trackAfterAdded(el));\n    updates.forEach((el) => this.trackAfterUpdated(el));\n    this.transitionPendingRemoves();\n    if (externalFormTriggered) {\n      liveSocket.unload();\n      const submitter = dom_default.private(externalFormTriggered, "submitter");\n      if (submitter && submitter.name && targetContainer.contains(submitter)) {\n        const input = document.createElement("input");\n        input.type = "hidden";\n        const formId = submitter.getAttribute("form");\n        if (formId) {\n          input.setAttribute("form", formId);\n        }\n        input.name = submitter.name;\n        input.value = submitter.value;\n        submitter.parentElement.insertBefore(input, submitter);\n      }\n      Object.getPrototypeOf(externalFormTriggered).submit.call(\n        externalFormTriggered\n      );\n    }\n    return true;\n  }\n  trackBeforeUpdated(fromEl, toEl) {\n    this.beforeUpdatedCallbacks.forEach((cb) => cb(fromEl, toEl));\n  }\n  trackAfterAdded(el) {\n    this.afterAddedCallbacks.forEach((cb) => cb(el));\n  }\n  trackAfterUpdated(el) {\n    this.afterUpdatedCallbacks.forEach((cb) => cb(el));\n  }\n  trackAfterPhxChildAdded(el) {\n    this.afterPhxChildAddedCallbacks.forEach((cb) => cb(el));\n  }\n  trackAfterDiscarded(el) {\n    this.afterDiscardedCallbacks.forEach((cb) => cb(el));\n  }\n  trackAfterTransitionsDiscarded(els) {\n    this.afterTransitionsDiscardedCallbacks.forEach((cb) => cb(els));\n  }\n  onNodeDiscarded(el) {\n    if (dom_default.isPhxChild(el) || dom_default.isPhxSticky(el)) {\n      this.liveSocket.destroyViewByEl(el);\n    }\n    this.trackAfterDiscarded(el);\n  }\n  maybePendingRemove(node) {\n    if (node.getAttribute && node.getAttribute(this.phxRemove) !== null) {\n      this.pendingRemoves.push(node);\n      return true;\n    } else {\n      return false;\n    }\n  }\n  removeStreamChildElement(child, force = false) {\n    if (!force && !this.view.ownsElement(child)) {\n      return;\n    }\n    if (this.streamInserts[child.id]) {\n      this.streamComponentRestore[child.id] = child;\n      child.remove();\n    } else {\n      if (!this.maybePendingRemove(child)) {\n        child.remove();\n        this.onNodeDiscarded(child);\n      }\n    }\n  }
1\n  getStreamInsert(el) {\n    const insert = el.id ? this.streamInserts[el.id] : {};\n    return insert || {};\n  }\n  setStreamRef(el, ref) {\n    dom_default.putSticky(\n      el,\n      PHX_STREAM_REF,\n      (el2) => el2.setAttribute(PHX_STREAM_REF, ref)\n    );\n  }\n  maybeReOrderStream(el, isNew = false) {\n    const { ref, streamAt, reset } = this.getStreamInsert(el);\n    if (streamAt === void 0) {\n      return;\n    }\n    this.setStreamRef(el, ref);\n    if (!reset && !isNew) {\n      return;\n    }\n    if (!el.parentElement) {\n      return;\n    }\n    if (streamAt === 0) {\n      this.moveOrInsertBefore(\n        el.parentElement,\n        el,\n        el.parentElement.firstElementChild\n      );\n    } else if (streamAt > 0) {\n      const children = Array.from(el.parentElement.children);\n      const oldIndex = children.indexOf(el);\n      if (streamAt >= children.length - 1) {\n        this.moveOrInsertBefore(el.parentElement, el, null);\n      } else {\n        const sibling = children[streamAt];\n        if (oldIndex > streamAt) {\n          this.moveOrInsertBefore(el.parentElement, el, sibling);\n        } else {\n          this.moveOrInsertBefore(\n            el.parentElement,\n            el,\n            sibling.nextElementSibling\n          );\n        }\n      }\n    }\n    this.maybeLimitStream(el);\n  }\n  // Reorder a child within its parent. When supported, use the atomic\n  // moveBefore (https://developer.mozilla.org/en-US/docs/Web/API/Node/moveBefore)\n  // so connected custom elements (and other state-bearing nodes like iframes)\n  // are not disconnected and reconnected by the move. Falls back to\n  // insertBefore otherwise. Passing `ref === null` moves to the end.\n  // See also https://github.com/phoenixframework/phoenix_live_view/issues/4212.\n  moveOrInsertBefore(parent, child, ref) {\n    if (typeof parent.moveBefore === "function") {\n      try {\n        parent.moveBefore(child, ref);\n        return;\n      } catch {\n      }\n    }\n    parent.insertBefore(child, ref);\n  }\n  maybeLimitStream(el) {\n    const { limit } = this.getStreamInsert(el);\n    if (limit !== null) {\n      const children = Array.from(el.parentElement.children);\n      if (limit < 0 && children.length > limit * -1) {\n        children.slice(0, children.length + limit).forEach((child) => this.removeStreamChildElement(child));\n      } else if (limit >= 0 && children.length > limit) {\n        children.slice(limit).forEach((child) => this.removeStreamChildElement(child));\n      }\n    }\n  }\n  transitionPendingRemoves() {\n    const { pendingRemoves, liveSocket } = this;\n    if (pendingRemoves.length > 0) {\n      liveSocket.transitionRemoves(pendingRemoves, this.view, () => {\n        pendingRemoves.forEach((el) => {\n          const child = dom_default.firstPhxChild(el);\n          if (child) {\n            liveSocket.destroyViewByEl(child);\n          }\n          el.remove();\n        });\n        this.trackAfterTransitionsDiscarded(pendingRemoves);\n      });\n    }\n  }\n  isChangedSelect(fromEl, toEl) {\n    if (!(fromEl instanceof HTMLSelectElement) || fromEl.multiple) {\n      return false;\n    }\n    if (fromEl.options.length !== toEl.options.length) {\n      return true;\n    }\n    toEl.value = fromEl.value;\n    return !fromEl.isEqualNode(toEl);\n  }\n  skipCIDSibling(el) {\n    return el.nodeType === Node.ELEMENT_NODE && el.hasAttribute(PHX_SKIP);\n  }\n  maybeCloneLockedElement(fromEl, isFocusedFormEl) {\n    if (!fromEl.hasAttribute(PHX_REF_SRC))\n      return fromEl;\n    const ref = new ElementRef(fromEl);\n    if (!fromEl.hasAttribute(PHX_REF_LOCK) || this.undoRef !== null && ref.isLockUndoneBy(this.undoRef)) {\n      return fromEl;\n    }\n    dom_default.applyStickyOperations(fromEl);\n    const clone2 = fromEl.hasAttribute(PHX_REF_LOCK) ? dom_default.private(fromEl, PHX_REF_LOCK) || fromEl.cloneNode(true) : null;\n    if (!clone2)\n      return fromEl;\n    dom_default.putPrivate(fromEl, PHX_REF_LOCK, clone2);\n    return isFocusedFormEl ? fromEl : clone2;\n  }\n  copyNestedPrivateLock(fromEl, toEl) {\n    if (this.undoRef === null || !dom_default.private(toEl, PHX_REF_LO
1CK))\n      return;\n    dom_default.putPrivate(fromEl, PHX_REF_LOCK, dom_default.private(toEl, PHX_REF_LOCK));\n  }\n  indexOf(parent, child) {\n    return Array.from(parent.children).indexOf(child);\n  }\n  teleport(el, morph) {\n    const targetSelector = el.getAttribute(PHX_PORTAL);\n    const portalContainer = document.querySelector(targetSelector);\n    if (!portalContainer) {\n      throw new Error(\n        "portal target with selector " + targetSelector + " not found"\n      );\n    }\n    const toTeleport = el.content.firstElementChild;\n    if (this.skipCIDSibling(toTeleport)) {\n      return;\n    }\n    if (!toTeleport?.id) {\n      throw new Error(\n        "phx-portal template must have a single root element with ID!"\n      );\n    }\n    const existing = document.getElementById(toTeleport.id);\n    let portalTarget;\n    if (existing) {\n      if (!portalContainer.contains(existing)) {\n        portalContainer.appendChild(existing);\n      }\n      portalTarget = existing;\n    } else {\n      portalTarget = document.createElement(toTeleport.tagName);\n      portalContainer.appendChild(portalTarget);\n    }\n    toTeleport.setAttribute(PHX_TELEPORTED_REF, this.view.id);\n    toTeleport.setAttribute(PHX_TELEPORTED_SRC, el.id);\n    morph(portalTarget, toTeleport, true);\n    toTeleport.removeAttribute(PHX_TELEPORTED_REF);\n    toTeleport.removeAttribute(PHX_TELEPORTED_SRC);\n    this.view.pushPortalElementId(toTeleport.id);\n  }\n  handleRuntimeHook(el, source) {\n    const name = el.getAttribute(PHX_RUNTIME_HOOK);\n    let nonce = el.hasAttribute("nonce") ? el.getAttribute("nonce") : null;\n    if (el.hasAttribute("nonce")) {\n      const template = document.createElement("template");\n      template.innerHTML = source;\n      nonce = template.content.querySelector(`script[${PHX_RUNTIME_HOOK}="${CSS.escape(name)}"]`)?.getAttribute("nonce") ?? null;\n    }\n    const script = document.createElement("script");\n    script.textContent = el.textContent;\n    dom_default.mergeAttrs(script, el, { isIgnored: false });\n    if (nonce) {\n      script.nonce = nonce;\n    }\n    el.replaceWith(script);\n    el = script;\n  }\n};\n\n// js/phoenix_live_view/rendered.js\nvar VOID_TAGS = /* @__PURE__ */ new Set([\n  "area",\n  "base",\n  "br",\n  "col",\n  "command",\n  "embed",\n  "hr",\n  "img",\n  "input",\n  "keygen",\n  "link",\n  "meta",\n  "param",\n  "source",\n  "track",\n  "wbr"\n]);\nvar quoteChars = /* @__PURE__ */ new Set(["\'", \'"\']);\nvar modifyRoot = (html, attrs, clearInnerHTML) => {\n  let i = 0;\n  let insideComment = false;\n  let beforeTag, afterTag, tag, tagNameEndsAt, id, newHTML;\n  const lookahead = html.match(/^(\\s*(?:\x3c!--.*?--\x3e\\s*)*)<([^\\s\\/>]+)/);\n  if (lookahead === null) {\n    throw new Error(`malformed html ${html}`);\n  }\n  i = lookahead[0].length;\n  beforeTag = lookahead[1];\n  tag = lookahead[2];\n  tagNameEndsAt = i;\n  for (i; i < html.length; i++) {\n    if (html.charAt(i) === ">") {\n      break;\n    }\n    if (html.charAt(i) === "=") {\n      const isId = html.slice(i - 3, i) === " id";\n      i++;\n      const char = html.charAt(i);\n      if (quoteChars.has(char)) {\n        const attrStartsAt = i;\n        i++;\n        for (i; i < html.length; i++) {\n          if (html.charAt(i) === char) {\n            break;\n          }\n        }\n        if (isId) {\n          id = html.slice(attrStartsAt + 1, i);\n          break;\n        }\n      }\n    }\n  }\n  let closeAt = html.length - 1;\n  insideComment = false;\n  while (closeAt >= beforeTag.length + tag.length) {\n    const char = html.charAt(closeAt);\n    if (insideComment) {\n      if (char === "-" && html.slice(closeAt - 3, closeAt) === "<!-") {\n        insideComment = false;\n        closeAt -= 4;\n      } else {\n        closeAt -= 1;\n      }\n    } else if (char === ">" && html.slice(closeAt - 2, closeAt) === "--") {\n      insideComment = true;\n      closeAt -= 3;\n    } else if (char === ">") {\n      break;\n    } else {\n      closeAt -= 1;\n    }\n  }\n  afterTag = html.slice(closeAt + 1, html.length);\n  const attrsStr = Object.keys(attrs).map((attr) => attrs[attr] === true ? attr : `${attr}="${attrs[attr]}"`).join(" ");\n  if (clearInnerHTML) {\n    const idAttrStr = id ? ` id="${id}"` : "";\n    if (VOID_TAGS.has(tag)) {\n      newHTML = `<${tag}${idAttrStr}${attrsStr === "" ? "" : " "}${attrsStr}/>`;\n    } else {\n      newHTML = `<${tag}${idAttrStr}${attrsStr === "" ? "" : " "}${attrsStr}></${tag}>`;\n    }\n  } else {\n    const rest = html.slice(tagNameEndsAt, closeAt + 1);\n    newHTML = `<${tag}${attrsStr === "" ? "" : " "}${attrsStr}${rest}`;\n  }\n  return [newHTML, beforeTag, afterTag];\n};\nvar Rendered = class {\n  static extract(diff) {\n    const { [REPLY]: reply, [EVENTS]: events, [TITLE]: title } = diff;\n    delete diff[REPLY];\n    delete diff[EVENTS];\n    delete diff[TITLE];\n    return { diff, title, reply: reply || null, events: events || [] };\n  }\n  constructor(viewId, rendered) {\n    this.viewId = viewId;\n    this.rendered = {};\n    this.magicId = 0;\n    this.mergeDiff(rendered);\n  }\n  parentViewId() {\n    return this.viewId;\n  }\n  toString(onlyCids) {\n    const { buffer: str, streams } = this.recursiveToString(\n      this.rendered,\n      this.rendered[COMPONENTS],\n      onlyCids,\n      true,\n      {}\n    );\n    return { buffer: str, streams };\n  }\n  recursiveToString(rendered, components = rendered[COMPONENTS], onlyCids, changeTracking, rootAttrs) {\n    onlyCids = onlyCids ? new Set(onlyCids) : null;\n    const output = {\n      buffer: "",\n      components,\n      onlyCids,\n      streams: /* @__PURE__ */ new Set()\n    };\n    this.toOutputBuffer(rendered, null, output, changeTracking, rootAttrs);\n    return { buffer: output.buffer, streams: output.streams };\n  }\n  componentCIDs(diff) {\n    return Object.keys(diff[COMPONENTS] || {}).map((i) => parseInt(i));\n  }\n  isComponentOnlyDiff(diff) {\n    if (!diff[COMPONENTS]) {\n      return false;\n    }\n    return Object.keys(diff).length === 1;\n  }\n  getComponent(diff, cid) {\n    return diff[COMPONENTS][cid];\n  }\n  resetRender(cid) {\n    if (this.rendered[COMPONENTS][cid]) {\n      this.rendered[COMPONENTS][cid].reset = true;\n    }\n  }\n  mergeDiff(diff) {\n    const newc = diff[COMPONENTS];\n    const cache = {};\n    delete diff[COMPONENTS];\n    this.rendered = this.mutableMerge(this.rendered, diff);\n    this.rendered[COMPONENTS] = this.rendered[COMPONENTS] || {};\n    if (newc) {\n      const oldc = this.rendered[COMPONENTS];\n      for (const cid in newc) {\n        newc[cid] = this.cachedFindComponent(cid, newc[cid], oldc, newc, cache);\n      }\n      for (const cid in newc) {\n        oldc[cid] = newc[cid];\n      }\n      diff[COMPONENTS] = newc;\n    }\n  }\n  cachedFindComponent(cid, cdiff, oldc, newc, cache) {\n    if (cache[cid]) {\n      return cache[cid];\n    } else {\n      let ndiff, stat, scid = cdiff[STATIC];\n      if (isCid(scid)) {\n        let tdiff;\n        if (scid > 0) {\n          tdiff = this.cachedFindComponent(scid, newc[scid], oldc, newc, cache);\n        } else {\n          tdiff = oldc[-scid];\n        }\n        stat = tdiff[STATIC];\n        ndiff = this.cloneMerge(tdiff, cdiff, true);\n        ndiff[STATIC] = stat;\n      } else {\n        ndiff = cdiff[STATIC] !== void 0 || oldc[cid] === void 0 ? cdiff : this.cloneMerge(oldc[cid], cdiff, false);\n      }\n      cache[cid] = ndiff;\n      return ndiff;\n    }\n  }\n  mutableMerge(target, source) {\n    if (source[STATIC] !== void 0) {\n      return source;\n    } else {\n      this.doMutableMerge(target, source);\n      return target;\n    }\n  }\n  doMutableMerge(target, source) {\n    if (source[KEYED]) {\n      this.mergeKe
1yed(target, source);\n    } else {\n      for (const key in source) {\n        const val = source[key];\n        const targetVal = target[key];\n        const isObjVal = isObject(val);\n        if (isObjVal && val[STATIC] === void 0 && isObject(targetVal)) {\n          this.doMutableMerge(targetVal, val);\n        } else {\n          target[key] = val;\n        }\n      }\n    }\n    if (target[ROOT]) {\n      target.newRender = true;\n    }\n  }\n  clone(diff) {\n    if ("structuredClone" in window) {\n      return structuredClone(diff);\n    } else {\n      return JSON.parse(JSON.stringify(diff));\n    }\n  }\n  // keyed comprehensions\n  mergeKeyed(target, source) {\n    const clonedTarget = this.clone(target);\n    Object.entries(source[KEYED]).forEach(([i, entry]) => {\n      if (i === KEYED_COUNT) {\n        return;\n      }\n      if (Array.isArray(entry)) {\n        const [old_idx, diff] = entry;\n        target[KEYED][i] = clonedTarget[KEYED][old_idx];\n        this.doMutableMerge(target[KEYED][i], diff);\n      } else if (typeof entry === "number") {\n        const old_idx = entry;\n        target[KEYED][i] = clonedTarget[KEYED][old_idx];\n      } else if (typeof entry === "object") {\n        if (!target[KEYED][i]) {\n          target[KEYED][i] = {};\n        }\n        this.doMutableMerge(target[KEYED][i], entry);\n      }\n    });\n    if (source[KEYED][KEYED_COUNT] < target[KEYED][KEYED_COUNT]) {\n      for (let i = source[KEYED][KEYED_COUNT]; i < target[KEYED][KEYED_COUNT]; i++) {\n        delete target[KEYED][i];\n      }\n    }\n    target[KEYED][KEYED_COUNT] = source[KEYED][KEYED_COUNT];\n    if (source[STREAM]) {\n      target[STREAM] = source[STREAM];\n    }\n    if (source[TEMPLATES]) {\n      target[TEMPLATES] = source[TEMPLATES];\n    }\n  }\n  // Merges cid trees together, copying statics from source tree.\n  //\n  // The `pruneMagicId` is passed to control pruning the magicId of the\n  // target. We must always prune the magicId when we are sharing statics\n  // from another component. If not pruning, we replicate the logic from\n  // mutableMerge, where we set newRender to true if there is a root\n  // (effectively forcing the new version to be rendered instead of skipped)\n  //\n  cloneMerge(target, source, pruneMagicId) {\n    let merged;\n    if (source[KEYED]) {\n      merged = this.clone(target);\n      this.mergeKeyed(merged, source);\n    } else {\n      merged = { ...target, ...source };\n      for (const key in merged) {\n        const val = source[key];\n        const targetVal = target[key];\n        if (isObject(val) && val[STATIC] === void 0 && isObject(targetVal)) {\n          merged[key] = this.cloneMerge(targetVal, val, pruneMagicId);\n        } else if (val === void 0 && isObject(targetVal)) {\n          merged[key] = this.cloneMerge(targetVal, {}, pruneMagicId);\n        }\n      }\n    }\n    if (pruneMagicId) {\n      delete merged.magicId;\n      delete merged.newRender;\n    } else if (target[ROOT]) {\n      merged.newRender = true;\n    }\n    return merged;\n  }\n  componentToString(cid) {\n    const { buffer: str, streams } = this.recursiveCIDToString(\n      this.rendered[COMPONENTS],\n      cid,\n      null\n    );\n    const [strippedHTML, _before, _after] = modifyRoot(str, {});\n    return { buffer: strippedHTML, streams };\n  }\n  pruneCIDs(cids) {\n    cids.forEach((cid) => delete this.rendered[COMPONENTS][cid]);\n  }\n  // private\n  get() {\n    return this.rendered;\n  }\n  isNewFingerprint(diff = {}) {\n    return !!diff[STATIC];\n  }\n  templateStatic(part, templates) {\n    if (typeof part === "number") {\n      return templates[part];\n    } else {\n      return part;\n    }\n  }\n  nextMagicID() {\n    this.magicId++;\n    return `m${this.magicId}-${this.parentViewId()}`;\n  }\n  // Converts rendered tree to output buffer.\n  //\n  // changeTracking controls if we can apply the PHX_SKIP optimization.\n  toOutputBuffer(rendered, templates, output, changeTracking, rootAttrs = {}) {\n    if (rendered[KEYED]) {\n      return this.comprehensionToBuffer(\n        rendered,\n        templates,\n        output,\n        changeTracking\n      );\n    }\n    if (rendered[TEMPLATES]) {\n      templates = rendered[TEMPLATES];\n      delete rendered[TEMPLATES];\n    }\n    let { [STATIC]: statics } = rendered;\n    statics = this.templateStatic(statics, templates);\n    rendered[STATIC] = statics;\n    const isRoot = rendered[ROOT];\n    const prevBuffer = output.buffer;\n    if (isRoot) {\n      output.buffer = "";\n    }\n    if (changeTracking && isRoot && !rendered.magicId) {\n      rendered.newRender = true;\n      rendered.magicId = this.nextMagicID();\n    }\n    output.buffer += statics[0];\n    for (let i = 1; i < statics.length;
1 i++) {\n      this.dynamicToBuffer(rendered[i - 1], templates, output, changeTracking);\n      output.buffer += statics[i];\n    }\n    if (isRoot) {\n      let skip = false;\n      let attrs;\n      if (changeTracking || rendered.magicId) {\n        skip = changeTracking && !rendered.newRender;\n        attrs = { [PHX_MAGIC_ID]: rendered.magicId, ...rootAttrs };\n      } else {\n        attrs = rootAttrs;\n      }\n      if (skip) {\n        attrs[PHX_SKIP] = true;\n      }\n      const [newRoot, commentBefore, commentAfter] = modifyRoot(\n        output.buffer,\n        attrs,\n        skip\n      );\n      rendered.newRender = false;\n      output.buffer = prevBuffer + commentBefore + newRoot + commentAfter;\n    }\n  }\n  comprehensionToBuffer(rendered, templates, output, changeTracking) {\n    const keyedTemplates = templates || rendered[TEMPLATES];\n    const statics = this.templateStatic(rendered[STATIC], templates);\n    rendered[STATIC] = statics;\n    delete rendered[TEMPLATES];\n    for (let i = 0; i < rendered[KEYED][KEYED_COUNT]; i++) {\n      output.buffer += statics[0];\n      for (let j = 1; j < statics.length; j++) {\n        this.dynamicToBuffer(\n          rendered[KEYED][i][j - 1],\n          keyedTemplates,\n          output,\n          changeTracking\n        );\n        output.buffer += statics[j];\n      }\n    }\n    if (rendered[STREAM]) {\n      const stream = rendered[STREAM];\n      const [_ref, _inserts, deleteIds, reset] = stream || [null, {}, [], null];\n      if (stream !== void 0 && (rendered[KEYED][KEYED_COUNT] > 0 || deleteIds.length > 0 || reset)) {\n        delete rendered[STREAM];\n        rendered[KEYED] = {\n          [KEYED_COUNT]: 0\n        };\n        output.streams.add(stream);\n      }\n    }\n  }\n  dynamicToBuffer(rendered, templates, output, changeTracking) {\n    if (typeof rendered === "number") {\n      const { buffer: str, streams } = this.recursiveCIDToString(\n        output.components,\n        rendered,\n        output.onlyCids\n      );\n      output.buffer += str;\n      output.streams = /* @__PURE__ */ new Set([...output.streams, ...streams]);\n    } else if (isObject(rendered)) {\n      this.toOutputBuffer(rendered, templates, output, changeTracking, {});\n    } else {\n      output.buffer += rendered;\n    }\n  }\n  recursiveCIDToString(components, cid, onlyCids) {\n    const component = components[cid] || logError(`no component for CID ${cid}`, components);\n    const attrs = { [PHX_COMPONENT]: cid, [PHX_VIEW_REF]: this.viewId };\n    const skip = onlyCids && !onlyCids.has(cid);\n    component.newRender = !skip;\n    component.magicId = `c${cid}-${this.parentViewId()}`;\n    const changeTracking = !component.reset;\n    const { buffer: html, streams } = this.recursiveToString(\n      component,\n      components,\n      onlyCids,\n      changeTracking,\n      attrs\n    );\n    delete component.reset;\n    return { buffer: html, streams };\n  }\n};\n\n// js/phoenix_live_view/js.js\nvar focusStack = [];\nvar default_transition_time = 200;\nvar JS = {\n  // private\n  exec(e, eventType, phxEvent, view, sourceEl, defaults) {\n    const [defaultKind, defaultArgs] = defaults || [\n      null,\n      { callback: defaults && defaults.callback }\n    ];\n    const commands = Array.isArray(phxEvent) ? phxEvent : typeof phxEvent === "string" && phxEvent.startsWith("[") ? JSON.parse(phxEvent) : [[defaultKind, defaultArgs]];\n    commands.forEach(([kind, args]) => {\n      if (kind === defaultKind) {\n        args = { ...defaultArgs, ...args };\n        args.callback = args.callback || defaultArgs.callback;\n      }\n      this.filterToEls(view.liveSocket, sourceEl, args).forEach((el) => {\n        this[`exec_${kind}`](e, eventType, phxEvent, view, sourceEl, el, args);\n      });\n    });\n  },\n  isVisible(el) {\n    return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length > 0);\n  },\n  // returns true if any part of the element is inside the viewport\n  isInViewport(el) {\n    const rect = el.getBoundingClientRect();\n    const windowHeight = window.innerHeight || document.documentElement.clientHeight;\n    const windowWidth = window.innerWidth || document.documentElement.clientWidth;\n    return rect.right > 0 && rect.bottom > 0 && rect.left < windowWidth && rect.top < windowHeight;\n  },\n  // private\n  // commands\n  exec_exec(e, eventType, phxEvent, view, sourceEl, el, { attr, to }) {\n    const encodedJS = el.getAttribute(attr);\n    if (!encodedJS) {\n      throw new Error(`expected ${attr} to contain JS command on "${to}"`);\n    }\n    view.liveSocket.execJS(el, encodedJS, eventType);\n  },\n  exec_dispatch(e, eventType, phxEvent, view, sourceEl, el, { event, detail, bubbles, blocking }) {\n    detail = detail || {};\n    detail.dispatcher = sourceEl;\n    if (blocking) {\n      const promise = new Promise((resolve, _reject) => {\n        detail.done = resolve;\n      });\n      view.liveSocket.asyncTransition(promise);\n    }\n    dom_default.dispatchEvent(el, event, { detail, bubbles });\n  }
1,\n  exec_push(e, eventType, phxEvent, view, sourceEl, el, args) {\n    const {\n      event,\n      data,\n      target,\n      page_loading,\n      loading,\n      value,\n      dispatcher,\n      callback\n    } = args;\n    const pushOpts = {\n      loading,\n      value,\n      target,\n      page_loading: !!page_loading,\n      originalEvent: e\n    };\n    const targetSrc = eventType === "change" && dispatcher ? dispatcher : sourceEl;\n    const phxTarget = target || targetSrc.getAttribute(view.binding("target")) || targetSrc;\n    const handler = (targetView, targetCtx) => {\n      if (!targetView.isConnected()) {\n        return;\n      }\n      if (eventType === "change") {\n        let { newCid, _target } = args;\n        _target = _target || (dom_default.isFormAssociated(sourceEl) ? sourceEl.name : void 0);\n        if (_target) {\n          pushOpts._target = _target;\n        }\n        targetView.pushInput(\n          sourceEl,\n          targetCtx,\n          newCid,\n          event || phxEvent,\n          pushOpts,\n          callback\n        );\n      } else if (eventType === "submit") {\n        const { submitter } = args;\n        targetView.submitForm(\n          sourceEl,\n          targetCtx,\n          event || phxEvent,\n          submitter,\n          pushOpts,\n          callback\n        );\n      } else {\n        targetView.pushEvent(\n          eventType,\n          sourceEl,\n          targetCtx,\n          event || phxEvent,\n          data,\n          pushOpts,\n          callback\n        );\n      }\n    };\n    if (args.targetView && args.targetCtx) {\n      handler(args.targetView, args.targetCtx);\n    } else {\n      view.withinTargets(phxTarget, handler);\n    }\n  },\n  exec_navigate(e, eventType, phxEvent, view, sourceEl, el, { href, replace }) {\n    view.liveSocket.historyRedirect(\n      e,\n      href,\n      replace ? "replace" : "push",\n      null,\n      sourceEl\n    );\n  },\n  exec_patch(e, eventType, phxEvent, view, sourceEl, el, { href, replace }) {\n    view.liveSocket.pushHistoryPatch(\n      e,\n      href,\n      replace ? "replace" : "push",\n      sourceEl\n    );\n  },\n  exec_focus(e, eventType, phxEvent, view, sourceEl, el) {\n    aria_default.attemptFocus(el);\n    window.requestAnimationFrame(() => {\n      window.requestAnimationFrame(() => aria_default.attemptFocus(el));\n    });\n  },\n  exec_focus_first(e, eventType, phxEvent, view, sourceEl, el) {\n    aria_default.focusFirstInteractive(el) || aria_default.focusFirst(el);\n    window.requestAnimationFrame(() => {\n      window.requestAnimationFrame(\n        () => aria_default.focusFirstInteractive(el) || aria_default.focusFirst(el)\n      );\n    });\n  },\n  exec_push_focus(e, eventType, phxEvent, view, sourceEl, el) {\n    focusStack.push(el || sourceEl);\n  },\n  exec_pop_focus(_e, _eventType, _phxEvent, _view, _sourceEl, _el) {\n    const el = focusStack.pop();\n    if (el) {\n      el.focus();\n      window.requestAnimationFrame(() => {\n        window.requestAnimationFrame(() => el.focus());\n      });\n    }\n  },\n  exec_add_class(e, eventType, phxEvent, view, sourceEl, el, { names, transition, time, blocking }) {\n    this.addOrRemoveClasses(el, names, [], transition, time, view, blocking);\n  },\n  exec_remove_class(e, eventType, phxEvent, view, sourceEl, el, { names, transition, time, blocking }) {\n    this.addOrRemoveClasses(el, [], names, transition, time, view, blocking);\n  },\n  exec_toggle_class(e, eventType, phxEvent, view, sourceEl, el, { names, transition, time, blocking }) {\n    this.toggleClasses(el, names, transition, time, view, blocking);\n  },\n  exec_toggle_attr(e, eventType, phxEvent, view, sourceEl, el, { attr: [attr, val1, val2] }) {\n    this.toggleAttr(el, attr, val1, val2);\n  },\n  exec_ignore_attrs(e, eventType, phxEvent, view, sourceEl, el, { attrs }) {\n    this.ignoreAttrs(el, attrs);\n  },\n  exec_transition(e, eventType, phxEvent, view, sourceEl, el, { time, transition, blocking }) {\n    this.addOrRemoveClasses(el, [], [], transition, time, view, blocking);\n  },\n  exec_toggle(e, eventType, phxEvent, view, sourceEl, el, { display, ins, outs, time, blocking }) {\n    this.toggle(eventType, view, el, display, ins, outs, time, blocking);\n  },\n  exec_show(e, eventType, phxEvent, view, sourceEl, el, { display, transition, time, blocking }) {\n    this.show(eventType, view, el, display, transition, time, blocking);\n  },\n  exec_hide(e, eventType, phxEvent, view, sourceEl, el, { display, transition, time, blocking }) {\n    this.hide(eventType, view, el, display, transition, time, blocking);\n  },\n  exec_set_attr(e, eventType, phxEvent, view, sourceEl, el, { attr: [attr, val] }) {\n    this.setOrRemoveAttrs(el, [[attr, val]], []);\n  },\n  exec_remove_attr(e, eventType, phxEvent, view, sourceEl, el, { attr }) {\n    this.setOrRemoveAttrs(el, [], [attr]);\n  },\n  ignoreAttrs(el, attrs) {\n    dom_default.putPrivate(el, "JS:ignore_attrs", {\n      apply: (fromEl, toEl) => {\n        let fromAttributes = Array.from(fromEl.attributes);\n        let fromAttributeNames = fromAttributes.map((attr) => attr.name);\n        Array.from(toEl.attributes).filter((attr) => {\n          return !fromAttributeNames.includes(attr.name);\n        }
1).forEach((attr) => {\n          if (dom_default.attributeIgnored(attr, attrs)) {\n            toEl.removeAttribute(attr.name);\n          }\n        });\n        fromAttributes.forEach((attr) => {\n          if (dom_default.attributeIgnored(attr, attrs)) {\n            toEl.setAttribute(attr.name, attr.value);\n          }\n        });\n      }\n    });\n  },\n  onBeforeElUpdated(fromEl, toEl) {\n    const ignoreAttrs = dom_default.private(fromEl, "JS:ignore_attrs");\n    if (ignoreAttrs) {\n      ignoreAttrs.apply(fromEl, toEl);\n    }\n  },\n  // utils for commands\n  show(eventType, view, el, display, transition, time, blocking) {\n    if (!this.isVisible(el)) {\n      this.toggle(\n        eventType,\n        view,\n        el,\n        display,\n        transition,\n        null,\n        time,\n        blocking\n      );\n    }\n  },\n  hide(eventType, view, el, display, transition, time, blocking) {\n    if (this.isVisible(el)) {\n      this.toggle(\n        eventType,\n        view,\n        el,\n        display,\n        null,\n        transition,\n        time,\n        blocking\n      );\n    }\n  },\n  toggle(eventType, view, el, display, ins, outs, time, blocking) {\n    time = time || default_transition_time;\n    const [inClasses, inStartClasses, inEndClasses] = ins || [[], [], []];\n    const [outClasses, outStartClasses, outEndClasses] = outs || [[], [], []];\n    if (inClasses.length > 0 || outClasses.length >
1 0) {\n      if (this.isVisible(el)) {\n        const onStart = () => {\n          this.addOrRemoveClasses(\n            el,\n            outStartClasses,\n            inClasses.concat(inStartClasses).concat(inEndClasses)\n          );\n          window.requestAnimationFrame(() => {\n            this.addOrRemoveClasses(el, outClasses, []);\n            window.requestAnimationFrame(\n              () => this.addOrRemoveClasses(el, outEndClasses, outStartClasses)\n            );\n          });\n        };\n        const onEnd = () => {\n          this.addOrRemoveClasses(el, [], outClasses.concat(outEndClasses));\n          dom_default.putSticky(\n            el,\n            "toggle",\n            (currentEl) => currentEl.style.display = "none"\n          );\n          el.dispatchEvent(new Event("phx:hide-end"));\n        };\n        el.dispatchEvent(new Event("phx:hide-start"));\n        if (blocking === false) {\n          onStart();\n          setTimeout(onEnd, time);\n        } else {\n          view.transition(time, onStart, onEnd);\n        }\n      } else {\n        if (eventType === "remove") {\n          return;\n        }\n        const onStart = () => {\n          this.addOrRemoveClasses(\n            el,\n            inStartClasses,\n            outClasses.concat(outStartClasses).concat(outEndClasses)\n          );\n          const stickyDisplay = display || this.defaultDisplay(el);\n          window.requestAnimationFrame(() => {\n            this.addOrRemoveClasses(el, inClasses, []);\n            window.requestAnimationFrame(() => {\n              dom_default.putSticky(\n                el,\n                "toggle",\n                (currentEl) => currentEl.style.display = stickyDisplay\n              );\n              this.addOrRemoveClasses(el, inEndClasses, inStartClasses);\n            });\n          });\n        };\n        const onEnd = () => {\n          this.addOrRemoveClasses(el, [], inClasses.concat(inEndClasses));\n          el.dispatchEvent(new Event("phx:show-end"));\n        };\n        el.dispatchEvent(new Event("phx:show-start"));\n        if (blocking === false) {\n          onStart();\n          setTimeout(onEnd, time);\n        } else {\n          view.transition(time, onStart, onEnd);\n        }\n      }\n    }
1 else {\n      if (this.isVisible(el)) {\n        window.requestAnimationFrame(() => {\n          el.dispatchEvent(new Event("phx:hide-start"));\n          dom_default.putSticky(\n            el,\n            "toggle",\n            (currentEl) => currentEl.style.display = "none"\n          );\n          el.dispatchEvent(new Event("phx:hide-end"));\n        });\n      } else {\n        window.requestAnimationFrame(() => {\n          el.dispatchEvent(new Event("phx:show-start"));\n          const stickyDisplay = display || this.defaultDisplay(el);\n          dom_default.putSticky(\n            el,\n            "toggle",\n            (currentEl) => currentEl.style.display = stickyDisplay\n          );\n          el.dispatchEvent(new Event("phx:show-end"));\n        });\n      }\n    }\n  },\n  toggleClasses(el, classes, transition, time, view, blocking) {\n    window.requestAnimationFrame(() => {\n      const [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]);\n      const newAdds = classes.filter(\n        (name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name)\n      );\n      const newRemoves = classes.filter(\n        (name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name)\n      );\n      this.addOrRemoveClasses(\n        el,\n        newAdds,\n        newRemoves,\n        transition,\n        time,\n        view,\n        blocking\n      );\n    });\n  },\n  toggleAttr(el, attr, val1, val2) {\n    if (el.hasAttribute(attr)) {\n      if (val2 !== void 0) {\n        if (el.getAttribute(attr) === val1) {\n          this.setOrRemoveAttrs(el, [[attr, val2]], []);\n        } else {\n          this.setOrRemoveAttrs(el, [[attr, val1]], []);\n        }\n      } else {\n        this.setOrRemoveAttrs(el, [], [attr]);\n      }\n    } else {\n      this.setOrRemoveAttrs(el, [[attr, val1]], []);\n    }\n  },\n  addOrRemoveClasses(el, adds, removes, transition, time, view, blocking) {\n    time = time || default_transition_time;\n    const [transitionRun, transitionStart, transitionEnd] = transition || [\n      [],\n      [],\n      []\n    ];\n    if (transitionRun.length > 0) {\n      const onStart = () => {\n        this.addOrRemoveClasses(\n          el,\n          transitionStart,\n          [].concat(transitionRun).concat(transitionEnd)\n        );\n        window.requestAnimationFrame(() => {\n          this.addOrRemoveClasses(el, transitionRun, []);\n          window.requestAnimationFrame(\n            () => this.addOrRemoveClasses(el, transitionEnd, transitionStart)\n          );\n        });\n      };\n      const onDone = () => this.addOrRemoveClasses(\n        el,\n        adds.concat(transitionEnd),\n        removes.concat(transitionRun).concat(transitionStart)\n      );\n      if (blocking === false) {\n        onStart();\n        setTimeout(onDone, time);\n      } else {\n        view.transition(time, onStart, onDone);\n      }\n      return;\n    }\n    window.requestAnimationFrame(() => {\n      const [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]);\n      const keepAdds = adds.filter(\n        (name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name)\n      );\n      const keepRemoves = removes.filter(\n        (name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name)\n      );\n      const newAdds = prevAdds.filter((name) => removes.indexOf(name) < 0).concat(keepAdds);\n      const newRemoves = prevRemoves.filter((name) => adds.indexOf(name) < 0).concat(keepRemoves);\n      dom_default.putSticky(el, "classes", (currentEl) => {\n        currentEl.classList.remove(...newRemoves);\n        currentEl.classList.add(...newAdds);\n        return [newAdds, newRemoves];\n      });\n    });\n  },\n  setOrRemoveAttrs(el, sets, removes) {\n    const [prevSets, prevRemoves] = dom_default.getSticky(el, "attrs", [[], []]);\n    const alteredAttrs = sets.map(([attr, _val]) => attr).concat(removes);\n    const newSets = prevSets.filter(([attr, _val]) => !alteredAttrs.includes(attr)).concat(sets);\n    const newRemoves = prevRemoves.filter((attr) => !alteredAttrs.includes(attr)).concat(removes);\n    if (sets.some(([attr, _val]) => attr === "id")) {\n      dom_default.putPrivate(el, "clientsideIdAttribute", true);\n    }\n    dom_default.putSticky(el, "attrs", (currentEl) =>
1 {\n      newRemoves.forEach((attr) => currentEl.removeAttribute(attr));\n      newSets.forEach(([attr, val]) => currentEl.setAttribute(attr, val));\n      return [newSets, newRemoves];\n    });\n  },\n  hasAllClasses(el, classes) {\n    return classes.every((name) => el.classList.contains(name));\n  },\n  isToggledOut(el, outClasses) {\n    return !this.isVisible(el) || this.hasAllClasses(el, outClasses);\n  },\n  filterToEls(liveSocket, sourceEl, { to }) {\n    const defaultQuery = () => {\n      if (typeof to === "string") {\n        return document.querySelectorAll(to);\n      } else if (to.closest) {\n        const toEl = sourceEl.closest(to.closest);\n        return toEl ? [toEl] : [];\n      } else if (to.inner) {\n        return sourceEl.querySelectorAll(to.inner);\n      }\n    };\n    return to ? liveSocket.jsQuerySelectorAll(sourceEl, to, defaultQuery) : [sourceEl];\n  },\n  defaultDisplay(el) {\n    return { tr: "table-row", td: "table-cell" }[el.tagName.toLowerCase()] || "block";\n  },\n  transitionClasses(val) {\n    if (!val) {\n      return null;\n    }\n    let [trans, tStart, tEnd] = Array.isArray(val) ? val : [val.split(" "), [], []];\n    trans = Array.isArray(trans) ? trans : trans.split(" ");\n    tStart = Array.isArray(tStart) ? tStart : tStart.split(" ");\n    tEnd = Array.isArray(tEnd) ? tEnd : tEnd.split(" ");\n    return [trans, tStart, tEnd];\n  }\n};\nvar js_default = JS;\n\n// js/phoenix_live_view/js_commands.ts\nvar js_commands_default = (liveSocket, eventType) => {\n  return {\n    exec(el, encodedJS) {\n      liveSocket.execJS(el, encodedJS, eventType);\n    },\n    show(el, opts = {}) {\n      const owner = liveSocket.owner(el);\n      js_default.show(\n        eventType,\n        owner,\n        el,\n        opts.display,\n        js_default.transitionClasses(opts.transition),\n        opts.time,\n        opts.blocking\n      );\n    },\n    hide(el, opts = {}) {\n      const owner = liveSocket.owner(el);\n      js_default.hide(\n        eventType,\n        owner,\n        el,\n        null,\n        js_default.transitionClasses(opts.transition),\n        opts.time,\n        opts.blocking\n      );\n    },\n    toggle(el, opts = {}) {\n      const owner = liveSocket.owner(el);\n      const inTransition = js_default.transitionClasses(opts.in);\n      const outTransition = js_default.transitionClasses(opts.out);\n      js_default.toggle(\n        eventType,\n        owner,\n        el,\n        opts.display,\n        inTransition,\n        outTransition,\n        opts.time,\n        opts.blocking\n      );\n    },\n    addClass(el, names, opts = {}) {\n      const classNames = Array.isArray(names) ? names : names.split(" ");\n      const owner = liveSocket.owner(el);\n      js_default.addOrRemoveClasses(\n        el,\n        classNames,\n        [],\n        js_default.transitionClasses(opts.transition),\n        opts.time,\n        owner,\n        opts.blocking\n      );\n    },\n    removeClass(el, names, opts = {}) {\n      const classNames = Array.isArray(names) ? names : names.split(" ");\n      const owner = liveSocket.owner(el);\n      js_default.addOrRemoveClasses(\n        el,\n        [],\n        classNames,\n        js_default.transitionClasses(opts.transition),\n        opts.time,\n        owner,\n        opts.blocking\n      );\n    },\n    toggleClass(el, names, opts = {}) {\n      const classNames = Array.isArray(names) ? names : names.split(" ");\n      const owner = liveSocket.owner(el);\n      js_default.toggleClasses(\n        el,\n        classNames,\n        js_default.transitionClasses(opts.transition),\n        opts.time,\n        owner,\n        opts.blocking\n      );\n    },\n    transition(el, transition, opts = {}) {\n      const owner = liveSocket.owner(el);\n      js_default.addOrRemoveClasses(\n        el,\n        [],\n        [],\n        js_default.transitionClasses(transition),\n        opts.time,\n        owner,\n        opts.blocking\n      );\n    },\n    setAttribute(el, attr, val) {\n      js_default.setOrRemoveAttrs(el, [[attr, val]], []);\n    },\n    removeAttribute(el, attr) {\n      js_default.setOrRemoveAttrs(el, [], [attr]);\n    },\n    toggleAttribute(el, attr, val1, val2) {\n      js_default.toggleAttr(el, attr, val1, val2);\n    },\n    push(el, type, opts = {}) {\n      liveSocket.withinOwners(el, (view) => {\n        const data = opts.value || {};\n        delete opts.value;\n        let e = new CustomEvent("phx:exec", { detail: { sourceElement: el } });\n        js_default.exec(e, eventType, type, view, el, ["push", { data, ...opts }]);\n      });\n    },\n    navigate(href, opts = {}
1) {\n      ensureSameOrigin(href, "navigate");\n      const customEvent = new CustomEvent("phx:exec");\n      liveSocket.historyRedirect(\n        customEvent,\n        href,\n        opts.replace ? "replace" : "push",\n        null,\n        null\n      );\n    },\n    patch(href, opts = {}) {\n      ensureSameOrigin(href, "patch");\n      const customEvent = new CustomEvent("phx:exec");\n      liveSocket.pushHistoryPatch(\n        customEvent,\n        href,\n        opts.replace ? "replace" : "push",\n        null\n      );\n    },\n    ignoreAttributes(el, attrs) {\n      js_default.ignoreAttrs(el, Array.isArray(attrs) ? attrs : [attrs]);\n    }\n  };\n};\n\n// js/phoenix_live_view/view_hook.ts\nvar HOOK_ID = "hookId";\nvar DEAD_HOOK = "deadHook";\nvar viewHookID = 1;\nvar ViewHook = class _ViewHook {\n  get liveSocket() {\n    return this.__liveSocket();\n  }\n  /** @internal */\n  static makeID() {\n    return viewHookID++;\n  }\n  /** @internal */\n  static elementID(el) {\n    return dom_default.private(el, HOOK_ID);\n  }\n  /** @internal */\n  static deadHook(el) {\n    return dom_default.private(el, DEAD_HOOK) === true;\n  }\n  /** @internal */\n  constructor(view, el, callbacks) {\n    this.el = el;\n    this.__attachView(view);\n    this.__listeners = /* @__PURE__ */ new Set();\n    this.__isDisconnected = false;\n    dom_default.putPrivate(this.el, HOOK_ID, _ViewHook.makeID());\n    if (view && view.isDead) {\n      dom_default.putPrivate(this.el, DEAD_HOOK, true);\n    }\n    if (callbacks) {\n      const protectedProps = /* @__PURE__ */ new Set([\n        "el",\n        "liveSocket",\n        "__view",\n        "__listeners",\n        "__isDisconnected",\n        "constructor",\n        // Standard object properties\n        // Core ViewHook API methods\n        "js",\n        "pushEvent",\n        "pushEventTo",\n        "handleEvent",\n        "removeHandleEvent",\n        "upload",\n        "uploadTo",\n        // Internal lifecycle callers\n        "__mounted",\n        "__updated",\n        "__beforeUpdate",\n        "__destroyed",\n        "__reconnected",\n        "__disconnected",\n        "__cleanup__"\n      ]);\n      for (const key in callbacks) {\n        if (Object.prototype.hasOwnProperty.call(callbacks, key)) {\n          this[key] = callbacks[key];\n          if (protectedProps.has(key)) {\n            console.warn(\n              `Hook object for element #${el.id} overwrites core property \'${key}\'!`\n            );\n          }\n        }\n      }\n      const lifecycleMethods = [\n        "mounted",\n        "beforeUpdate",\n        "updated",\n        "destroyed",\n        "disconnected",\n        "reconnected"\n      ];\n      lifecycleMethods.forEach((methodName) => {\n        if (callbacks[methodName] && typeof callbacks[methodName] === "function") {\n          this[methodName] = callbacks[methodName];\n        }\n      });\n    }\n  }\n  /** @internal */\n  __attachView(view) {\n    if (view) {\n      this.__view = () => view;\n      this.__liveSocket = () => view.liveSocket;\n    } else {\n      this.__view = () => {\n        throw new Error(\n          `hook not yet attached to a live view: ${this.el.outerHTML}`\n        );\n      };\n      this.__liveSocket = () => {\n        throw new Error(\n          `hook not yet attached to a live view: ${this.el.outerHTML}`\n        );\n      };\n    }\n  }\n  // Default lifecycle methods\n  mounted() {\n  }\n  beforeUpdate() {\n  }\n  updated() {\n  }\n  destroyed() {\n  }\n  disconnected() {\n  }\n  reconnected() {\n  }\n  // Internal lifecycle callers - called by the View\n  /** @internal */\n  __mounted() {\n    this.mounted();\n  }\n  /** @internal */\n  __updated() {\n    this.updated();\n  }\n  /** @internal */\n  __beforeUpdate() {\n    this.beforeUpdate();\n  }\n  /** @internal */\n  __destroyed() {\n    this.destroyed();\n    dom_default.deletePrivate(this.el, HOOK_ID);\n  }\n  /** @internal */\n  __reconnected() {\n    if (this.__isDisconnected) {\n      this.__isDisconnected = false;\n      this.reconnected();\n    }\n  }\n  /** @internal */\n  __disconnected() {\n    this.__isDisconnected = true;\n    this.disconnected();\n  }\n  js() {\n    return {\n      ...js_commands_default(this.__view().liveSocket, "hook"),\n      exec: (encodedJS) => {\n        this.__view().liveSocket.execJS(this.el, encodedJS, "hook");\n      }\n    };\n  }\n  pushEvent(event, payload, onReply) {\n    const promise = this.__view().pushHookEvent(\n      this.el,\n      null,\n      event,\n      payload || {}\n    );\n    if (onReply === void 0) {\n      return promise.then(({ reply }) => reply);\n    }\n    promise.then(\n      ({ reply, ref }) => onReply(reply, ref)\n    ).catch(() =>
1 {\n    });\n  }\n  pushEventTo(selectorOrTarget, event, payload, onReply) {\n    if (onReply === void 0) {\n      const targetPair = [];\n      this.__view().withinTargets(\n        selectorOrTarget,\n        (view, targetCtx) => {\n          targetPair.push({ view, targetCtx });\n        }\n      );\n      const promises = targetPair.map(({ view, targetCtx }) => {\n        return view.pushHookEvent(\n          this.el,\n          targetCtx,\n          event,\n          payload || {}\n        );\n      });\n      return Promise.allSettled(promises);\n    }\n    this.__view().withinTargets(\n      selectorOrTarget,\n      (view, targetCtx) => {\n        view.pushHookEvent(this.el, targetCtx, event, payload || {}).then(\n          ({ reply, ref }) => onReply(reply, ref)\n        ).catch(() => {\n        });\n      }\n    );\n  }\n  handleEvent(event, callback) {\n    const callbackRef = {\n      event,\n      callback: (customEvent) => callback(customEvent.detail)\n    };\n    window.addEventListener(\n      `phx:${event}`,\n      callbackRef.callback\n    );\n    this.__listeners.add(callbackRef);\n    return callbackRef;\n  }\n  removeHandleEvent(ref) {\n    window.removeEventListener(\n      `phx:${ref.event}`,\n      ref.callback\n    );\n    this.__listeners.delete(ref);\n  }\n  upload(name, files) {\n    return this.__view().dispatchUploads(null, name, files);\n  }\n  uploadTo(selectorOrTarget, name, files) {\n    return this.__view().withinTargets(\n      selectorOrTarget,\n      (view, targetCtx) => {\n        view.dispatchUploads(targetCtx, name, files);\n      }\n    );\n  }\n  /** @internal */\n  __cleanup__() {\n    this.__listeners.forEach(\n      (callbackRef) => this.removeHandleEvent(callbackRef)\n    );\n  }\n};\n\n// js/phoenix_live_view/view.ts\nvar prependFormDataKey = (key, prefix) => {\n  const isArray = key.endsWith("[]");\n  let baseKey = isArray ? key.slice(0, -2) : key;\n  baseKey = baseKey.replace(/([^\\[\\]]+)(\\]?$)/, `${prefix}$1$2`);\n  if (isArray) {\n    baseKey += "[]";\n  }\n  return baseKey;\n};\nvar View = class _View {\n  static closestView(el) {\n    const liveViewEl = el.closest(PHX_VIEW_SELECTOR);\n    return liveViewEl ? dom_default.private(liveViewEl, "view") : null;\n  }\n  constructor(el, liveSocket, parentView, flash = null, liveReferer = null) {\n    this.rendered = null;\n    this.isDead = false;\n    this.liveSocket = liveSocket;\n    this.flash = flash;\n    this.parent = parentView;\n    this.root = parentView ? parentView.root : this;\n    this.el = el;\n    const boundView = dom_default.private(this.el, "view");\n    if (boundView !== void 0 && boundView.isDead !== true) {\n      logError(\n        `The DOM element for this view has already been bound to a view.\n\n        An element can only ever be associated with a single view!\n        Please ensure that you are not trying to initialize multiple LiveSockets on the same page.\n        This could happen if you\'re accidentally trying to render your root layout more than once.\n        Ensure that the template set on the LiveView is different than the root layout.\n      `,\n        { view: boundView }\n      );\n      throw new Error("Cannot bind multiple views to the same DOM element.");\n    }\n    dom_default.putPrivate(this.el, "view", this);\n    this.id = this.el.id;\n    this.el.setAttribute(PHX_ROOT_ID, this.root.id);\n    this.ref = 0;\n    this.lastAckRef = null;\n    this.childJoins = 0;\n    this.loaderTimer = null;\n    this.disconnectedTimer = null;\n    this.pendingDiffs = [];\n    this.pendingForms = /* @__PURE__ */ new Set();\n    this.redirect = false;\n    this.href = null;\n    this.joinCount = this.parent ? this.parent.joinCount - 1 : 0;\n    this.joinAttempts = 0;\n    this.joinPending = true;\n    this.destroyed = false;\n    this.joinCallback = function(onDone) {\n      onDone && onDone();\n    };\n    this.stopCallback = function() {\n    };\n    this.pendingJoinOps = [];\n    this.viewHooks = {};\n    this.formSubmits = [];\n    this.children = this.parent ? null : {};\n    this.root.children[this.id] = {};\n    this.formsForRecovery = {};\n    this.channel = this.liveSocket.channel(`lv:${this.id}`, () => {\n      const url = this.href && this.expandURL(this.href);\n      return {\n        redirect: this.redirect ? url : void 0,\n        url: this.redirect ? void 0 : url || void 0,\n        params: this.connectParam
1s(liveReferer),\n        session: this.getSession(),\n        static: this.getStatic(),\n        flash: this.flash ?? void 0,\n        sticky: this.el.hasAttribute(PHX_STICKY)\n      };\n    });\n    this.portalElementIds = /* @__PURE__ */ new Set();\n  }\n  setHref(href) {\n    this.href = href;\n  }\n  setRedirect(href) {\n    this.redirect = true;\n    this.href = href;\n  }\n  isMain() {\n    return this.el.hasAttribute(PHX_MAIN);\n  }\n  connectParams(liveReferer) {\n    const params = this.liveSocket.params(this.el);\n    const manifest = dom_default.all(document, `[${this.binding(PHX_TRACK_STATIC)}]`).map(\n      (node) => "src" in node && node.src || "href" in node && node.href\n    ).filter((url) => typeof url === "string");\n    if (manifest.length > 0) {\n      params["_track_static"] = manifest;\n    }\n    params["_mounts"] = this.joinCount;\n    params["_mount_attempts"] = this.joinAttempts;\n    params["_live_referer"] = liveReferer ?? void 0;\n    this.joinAttempts++;\n    return params;\n  }\n  isConnected() {\n    return this.channel.canPush();\n  }\n  getSession() {\n    return this.el.getAttribute(PHX_SESSION);\n  }\n  getStatic() {\n    const val = this.el.getAttribute(PHX_STATIC);\n    return val === "" ? null : val;\n  }\n  destroy(callback = function() {\n  }) {\n    this.destroyAllChildren();\n    this.destroyPortalElements();\n    this.destroyed = true;\n    dom_default.deletePrivate(this.el, "view");\n    delete this.root.children[this.id];\n    if (this.parent) {\n      delete this.root.children[this.parent.id][this.id];\n    }\n    this.loaderTimer != null && clearTimeout(this.loaderTimer);\n    const onFinished = () => {\n      callback();\n      for (const id in this.viewHooks) {\n        this.destroyHook(this.viewHooks[id]);\n      }\n    };\n    dom_default.markPhxChildDestroyed(this.el);\n    this.log("destroyed", () => ["the child has been removed from the parent"]);\n    this.channel.leave().receive("ok", onFinished).receive("error", onFinished).receive("timeout", onFinished);\n  }\n  setContainerClasses(...classes) {\n    this.el.classList.remove(\n      PHX_CONNECTED_CLASS,\n      PHX_LOADING_CLASS,\n      PHX_ERROR_CLASS,\n      PHX_CLIENT_ERROR_CLASS,\n      PHX_SERVER_ERROR_CLASS\n    );\n    this.el.classList.add(...classes);\n  }\n  showLoader(timeout) {\n    this.loaderTimer != null && clearTimeout(this.loaderTimer);\n    if (timeout) {\n      this.loaderTimer = setTimeout(() => this.showLoader(), timeout);\n    } else {\n      for (const id in this.viewHooks) {\n        this.viewHooks[id].__disconnected();\n      }\n      this.setContainerClasses(PHX_LOADING_CLASS);\n    }\n  }\n  execAll(binding) {\n    dom_default.all(\n      this.el,\n      `[${binding}]`,\n      (el) => this.liveSocket.execJS(el, el.getAttribute(binding))\n    );\n  }\n  hideLoader() {\n    this.loaderTimer != null && clearTimeout(this.loaderTimer);\n    this.disconnectedTimer != null && clearTimeout(this.disconnectedTimer);\n    this.setContainerClasses(PHX_CONNECTED_CLASS);\n    this.execAll(this.binding("connected"));\n  }\n  triggerReconnected() {\n    for (const id in this.viewHooks) {\n      this.viewHooks[id].__reconnected();\n    }\n  }\n  log(kind, msgCallback) {\n    this.liveSocket.log(this, kind, msgCallback);\n  }\n  transition(time, onStart, onDone = function() {\n  }) {\n    this.liveSocket.transition(time, onStart, onDone);\n  }\n  // calls the callback with the view and target element for the given phxTarget\n  // targets can be:\n  //  * an element itself, then it is simply passed to liveSocket.owner;\n  //  * a CID (Component ID), then we first search the component\'s element in the DOM\n  //  * a selector, then we search the selector in the DOM and call the callback\n  //    for each element found with the corresponding owner view\n  withinTargets(phxTarget, callback, dom = document) {\n    if (phxTarget instanceof HTMLElement || phxTarget instanceof SVGElement) {\n      return this.liveSocket.owner(\n        phxTarget,\n        (view) => callback(view, phxTarget)\n      );\n    }\n    if (isCid(phxTarget)) {\n      const target = dom_default.findComponent(this.id, phxTarget, dom);\n      if (!target) {\n        logError(`no component found matching phx-target of ${phxTarget}`);\n      } else {\n        callback(\n          this,\n          typeof phxTarget === "number" ? phxTarget : parseInt(phxTarget)\n        );\n      }\n    } else {\n      const targets = Array.from(dom.querySelectorAll(phxTarget));\n      if (targets.length === 0) {\n        logError(\n          `nothing found matching the phx-target selector "${phxTarget}"`\n        );\n      }
1\n      targets.forEach(\n        (target) => this.liveSocket.owner(target, (view) => callback(view, target))\n      );\n    }\n  }\n  applyDiff(type, rawDiff, callback) {\n    this.log(type, () => ["", clone(rawDiff)]);\n    const { diff, reply, events, title } = Rendered.extract(rawDiff);\n    const ev = events.reduce(\n      (acc, args) => {\n        if (args.length === 3 && args[2] == true) {\n          acc.pre.push(args.slice(0, -1));\n        } else {\n          acc.post.push(args);\n        }\n        return acc;\n      },\n      { pre: [], post: [] }\n    );\n    this.liveSocket.dispatchEvents(ev.pre);\n    const update = () => {\n      callback({ diff, reply, events: ev.post });\n      if (typeof title === "string" || type == "mount" && this.isMain()) {\n        window.requestAnimationFrame(() => dom_default.putTitle(title));\n      }\n    };\n    if ("onDocumentPatch" in this.liveSocket.domCallbacks) {\n      this.liveSocket.triggerDOM("onDocumentPatch", [update]);\n    } else {\n      update();\n    }\n  }\n  onJoin(resp) {\n    const { rendered, container, liveview_version, pid } = resp;\n    if (container) {\n      const [tag, attrs] = container;\n      this.el = dom_default.replaceRootContainer(this.el, tag, attrs);\n      dom_default.putPrivate(this.el, "view", this);\n    }\n    this.childJoins = 0;\n    this.joinPending = true;\n    this.flash = null;\n    if (this.root === this) {\n      this.formsForRecovery = this.getFormsForRecovery();\n    }\n    if (this.isMain() && window.history.state === null) {\n      browser_default.pushState("replace", {\n        type: "patch",\n        id: this.id,\n        position: this.liveSocket.currentHistoryPosition\n      });\n    }\n    if (liveview_version !== this.liveSocket.version()) {\n      console.warn(\n        `LiveView asset version mismatch. JavaScript version ${this.liveSocket.version()} vs. server ${liveview_version}. To avoid issues, please ensure that your assets use the same version as the server.`\n      );\n    }\n    if (pid) {\n      this.el.setAttribute(PHX_LV_PID, pid);\n    }\n    browser_default.dropLocal(\n      this.liveSocket.localStorage,\n      window.location.pathname,\n      CONSECUTIVE_RELOADS\n    );\n    this.applyDiff("mount", rendered, ({ diff, events }) => {\n      this.rendered = new Rendered(this.id, diff);\n      const [html, streams] = this.renderContainer(null, "join");\n      this.dropPendingRefs();\n      this.joinCount++;\n      this.joinAttempts = 0;\n      this.maybeRecoverForms(html, () => {\n        this.onJoinComplete(resp, html, streams, events);\n      });\n    });\n  }\n  dropPendingRefs() {\n    dom_default.all(document, `[${PHX_REF_SRC}="${this.refSrc()}"]`, (el) => {\n      el.removeAttribute(PHX_REF_LOADING);\n      el.removeAttribute(PHX_REF_SRC);\n      el.removeAttribute(PHX_REF_LOCK);\n    });\n  }\n  onJoinComplete({ live_patch }, html, streams, events) {\n    if (this.joinCount > 1 || this.parent && !this.parent.isJoinPending()) {\n      return this.applyJoinPatch(live_patch, html, streams, events);\n    }\n    const newChildren = dom_default.findPhxChildrenInFragment(html, this.id).filter(\n      (toEl) => {\n        const fromEl = toEl.id && this.el.querySelector(`[id="${toEl.id}"]`);\n        const phxStatic = fromEl && fromEl.getAttribute(PHX_STATIC);\n        if (phxStatic) {\n          toEl.setAttribute(PHX_STATIC, phxStatic);\n        }\n        if (fromEl) {\n          fromEl.setAttribute(PHX_ROOT_ID, this.root.id);\n        }\n        return this.joinChild(toEl);\n      }\n    );\n    if (newChildren.length === 0) {\n      if (this.parent) {\n        this.root.pendingJoinOps.push([\n          this,\n          () => this.applyJoinPatch(live_patch, html, streams, events)\n        ]);\n        this.parent.ackJoin(this);\n      } else {\n        this.onAllChildJoinsComplete();\n        this.applyJoinPatch(live_patch, html, streams, events);\n      }\n    } else {\n      this.root.pendingJoinOps.push([\n        this,\n        () => this.applyJoinPatch(live_patch, html, streams, events)\n      ]);\n    }\n  }\n  attachTrueDocEl() {\n    const el = dom_default.byId(this.id);\n    if (!el) {\n      throw new Error("unable to find root element for view");\n    }\n    this.el = el;\n    dom_default.putPrivate(this.el, "view", this);\n    this.el.setAttribute(PHX_ROOT_ID, this.root.id);\n  }\n  // this is invoked for dead and live views, so we must filter by\n  // by owner to ensure we aren\'t duplicating hooks across disconnect\n  // and connected states. This also handles cases where hooks exist\n  // in a root layout with a 
1LV in the body\n  execNewMounted(parent = document) {\n    let phxViewportTop = this.binding(PHX_VIEWPORT_TOP);\n    let phxViewportBottom = this.binding(PHX_VIEWPORT_BOTTOM);\n    this.all(\n      parent,\n      `[${phxViewportTop}], [${phxViewportBottom}]`,\n      (hookEl) => {\n        dom_default.maintainPrivateHooks(\n          hookEl,\n          hookEl,\n          phxViewportTop,\n          phxViewportBottom\n        );\n        this.maybeAddNewHook(hookEl);\n      }\n    );\n    this.all(\n      parent,\n      `[${this.binding(PHX_HOOK)}], [data-phx-${PHX_HOOK}]`,\n      (hookEl) => {\n        this.maybeAddNewHook(hookEl);\n      }\n    );\n    this.all(parent, `[${this.binding(PHX_MOUNTED)}]`, (el) => {\n      this.maybeMounted(el);\n    });\n  }\n  all(parent, selector, callback) {\n    dom_default.all(parent, selector, (el) => {\n      if (this.ownsElement(el)) {\n        callback(el);\n      }\n    });\n  }\n  applyJoinPatch(live_patch, html, streams, events) {\n    if (this.joinCount > 1) {\n      if (this.pendingJoinOps.length) {\n        this.pendingJoinOps.forEach((cb) => typeof cb === "function" && cb());\n        this.pendingJoinOps = [];\n      }\n    }\n    this.attachTrueDocEl();\n    const patch = new DOMPatch(this, this.el, html, streams, null);\n    patch.markPrunableContentForRemoval();
1\n    this.performPatch(patch, false, true);\n    this.joinNewChildren();\n    this.execNewMounted();\n    this.joinPending = false;\n    this.liveSocket.dispatchEvents(events);\n    this.applyPendingUpdates();\n    if (live_patch) {\n      const { kind, to } = live_patch;\n      this.liveSocket.historyPatch(to, kind);\n    }\n    this.hideLoader();\n    if (this.joinCount > 1) {\n      this.triggerReconnected();\n    }\n    this.stopCallback();\n  }\n  triggerBeforeUpdateHook(fromEl, toEl) {\n    this.liveSocket.triggerDOM("onBeforeElUpdated", [fromEl, toEl]);\n    const hook = this.getHook(fromEl);\n    const isIgnored = hook && dom_default.isIgnored(fromEl, this.binding(PHX_UPDATE));\n    if (hook && !fromEl.isEqualNode(toEl) && !(isIgnored && isEqualObj(fromEl.dataset, toEl.dataset))) {\n      hook.__beforeUpdate();\n      return hook;\n    }\n  }\n  maybeMounted(el) {\n    const phxMounted = el.getAttribute(this.binding(PHX_MOUNTED));\n    const hasBeenInvoked = phxMounted && dom_default.private(el, "mounted");\n    if (phxMounted && !hasBeenInvoked) {\n      this.liveSocket.execJS(el, phxMounted);\n      dom_default.putPrivate(el, "mounted", true);\n    }\n  }\n  maybeAddNewHook(el) {\n    const newHook = this.addHook(el);\n    if (newHook) {\n      newHook.__mounted();\n    }\n  }
1\n  performPatch(patch, pruneCids, isJoinPatch = false) {\n    const removedEls = [];\n    let phxChildrenAdded = false;\n    const updatedHookIds = /* @__PURE__ */ new Set();\n    this.liveSocket.triggerDOM("onPatchStart", [patch.targetContainer]);\n    patch.afterAdded((el) => {\n      this.liveSocket.triggerDOM("onNodeAdded", [el]);\n      const phxViewportTop = this.binding(PHX_VIEWPORT_TOP);\n      const phxViewportBottom = this.binding(PHX_VIEWPORT_BOTTOM);\n      dom_default.maintainPrivateHooks(el, el, phxViewportTop, phxViewportBottom);\n      this.maybeAddNewHook(el);\n      if (el.getAttribute) {\n        this.maybeMounted(el);\n      }\n    });\n    patch.afterPhxChildAdded((el) => {\n      if (dom_default.isPhxSticky(el)) {\n        this.liveSocket.joinRootViews();\n      } else {\n        phxChildrenAdded = true;\n      }\n    });\n    patch.beforeUpdated((fromEl, toEl) => {\n      const hook = this.triggerBeforeUpdateHook(fromEl, toEl);\n      if (hook) {\n        updatedHookIds.add(fromEl.id);\n      }\n      js_default.onBeforeElUpdated(fromEl, toEl);\n    });\n    patch.afterUpdated((el) => {\n      if (updatedHookIds.has(el.id)) {\n        const hook = this.getHook(el);\n        hook && hook.__updated();\n      }\n    });\n    patch.afterDiscarded((el) => {\n      if (el.nodeType === Node.ELEMENT_NODE) {\n        removedEls.push(el);\n      }\n    });\n    patch.afterTransitionsDiscarded(\n      (els) => this.afterElementsRemoved(els, pruneCids)\n    );\n    patch.perform(isJoinPatch);\n    this.afterElementsRemoved(removedEls, pruneCids);\n    this.liveSocket.triggerDOM("onPatchEnd", [patch.targetContainer]);\n    return phxChildrenAdded;\n  }
1\n  afterElementsRemoved(elements, pruneCids) {\n    const destroyedCIDs = [];\n    elements.forEach((parent) => {\n      const components = dom_default.all(\n        parent,\n        `[${PHX_VIEW_REF}="${this.id}"][${PHX_COMPONENT}]`\n      );\n      const hooks = dom_default.all(\n        parent,\n        `[${this.binding(PHX_HOOK)}], [data-phx-hook]`\n      );\n      components.concat(parent).forEach((el) => {\n        const cid = this.componentID(el);\n        if (isCid(cid) && destroyedCIDs.indexOf(cid) === -1 && el.getAttribute(PHX_VIEW_REF) === this.id) {\n          destroyedCIDs.push(cid);\n        }\n      });\n      hooks.concat(parent).forEach((hookEl) => {\n        const hook = this.getHook(hookEl);\n        hook && this.destroyHook(hook);\n      });\n    });\n    if (pruneCids) {\n      this.maybePushComponentsDestroyed(destroyedCIDs);\n    }\n  }\n  joinNewChildren() {\n    dom_default.findPhxChildren(document, this.id).forEach((el) => this.joinChild(el));\n  }\n  maybeRecoverForms(html, callback) {\n    const phxChange = this.binding("change");\n    const oldForms = this.root.formsForRecovery;\n    const template = document.createElement("template");\n    template.innerHTML = html;\n    if (!template.content.firstElementChild) {\n      return;\n    }\n    dom_default.all(template.content, `[${PHX_PORTAL}]`).forEach((portalTemplate) => {\n      if (!(portalTemplate instanceof HTMLTemplateElement)) {\n        return;\n      }\n      template.content.firstElementChild?.appendChild(\n        portalTemplate.content.firstElementChild\n      );\n    });\n    const rootEl = template.content.firstElementChild;\n    rootEl.id = this.id;\n    rootEl.setAttribute(PHX_ROOT_ID, this.root.id);
1\n    rootEl.setAttribute(PHX_SESSION, this.getSession());\n    rootEl.setAttribute(PHX_STATIC, this.getStatic() ?? "");\n    this.parent && rootEl.setAttribute(PHX_PARENT_ID, this.parent.id);\n    dom_default.putPrivate(rootEl, "view", this);\n    const formsToRecover = (\n      // we go over all forms in the new DOM; because this is only the HTML for the current\n      // view, we can be sure that all forms are owned by this view:\n      dom_default.all(template.content, "form").filter((newForm) => newForm.id && oldForms[newForm.id]).filter((newForm) => !this.pendingForms.has(newForm.id)).filter(\n        (newForm) => oldForms[newForm.id].getAttribute(phxChange) === newForm.getAttribute(phxChange)\n      ).map((newForm) => {\n        return [oldForms[newForm.id], newForm];\n      })\n    );\n    if (formsToRecover.length === 0) {\n      return callback();\n    }\n    formsToRecover.forEach(([oldForm, newForm], i) => {\n      this.pendingForms.add(newForm.id);\n      this.pushFormRecovery(\n        oldForm,\n        newForm,\n        template.content.firstElementChild,\n        () => {\n          this.pendingForms.delete(newForm.id);\n          if (i === formsToRecover.length - 1) {\n            callback();\n          }\n        }\n      );\n    });\n  }\n  getChildById(id) {\n    return this.root.children[this.id][id];\n  }\n  getDescendentByEl(el) {\n    if (el.id === this.id) {\n      return this;\n    } else {\n      return this.children && this.children[el.getAttribute(PHX_PARENT_ID)]?.[el.id];\n    }\n  }\n  destroyDescendent(id) {\n    for (const parentId in this.root.children) {\n      for (const childId in this.root.children[parentId]) {\n        if (childId === id) {\n          return this.root.children[parentId][childId].destroy();\n        }\n      }\n    }\n  }\n  joinChild(el) {\n    const child = this.getChildById(el.id);\n    if (!child) {\n      const view = new _View(el, this.liveSocket, this);\n      this.root.children[this.id][view.id] = view;\n      view.join();\n      this.childJoins++;\n      return true;\n    }\n  }\n  isJoinPending() {\n    return this.joinPending;\n  }\n  ackJoin(_child) {\n    this.childJoins--;\n    if (this.childJoins === 0) {\n      if (this.parent) {\n        this.parent.ackJoin(this);\n      } else {\n        this.onAllChildJoinsComplete();\n      }\n    }\n  }\n  onAllChildJoinsComplete() {\n    this.pendingForms.clear();\n    this.formsForRecovery = {};\n    this.joinCallback(() => {\n      this.pendingJoinOps.forEach(([view, op]) => {\n        if (!view.isDestroyed()) {\n          op();\n        }\n      });\n      this.pendingJoinOps = [];\n    });\n  }\n  update(diff, events, isPending = false) {\n    if (this.isJoinPending() || this.liveSocket.hasPendingLink() && this.root.isMain()) {\n      if (!isPending) {\n        this.pendingDiffs.push({ diff, events });\n      }\n      return false;\n    }\n    this.rendered.mergeDiff(diff);\n    let phxChildrenAdded = false;\n    if (this.rendered.isComponentOnlyDiff(diff)) {\n      this.liveSocket.time("component patch complete", () => {\n        const parentCids = dom_default.findExistingParentCIDs(\n          this.id,\n          this.rendered.componentCIDs(diff)\n        );\n        parentCids.forEach((parentCID) => {\n          if (this.componentPatch(\n            this.rendered.getComponent(diff, parentCID),\n            parentCID\n          )) {\n            phxChildrenAdded = true;\n          }\n        });\n      });\n    } else if (!isEmpty(diff)) {\n      this.liveSocket.time("full patch complete", () => {\n        const [html, streams] = this.renderContainer(diff, "update");\n        const patch = new DOMPatch(this, this.el, html, streams, null);
1\n        phxChildrenAdded = this.performPatch(patch, true);\n      });\n    }\n    this.liveSocket.dispatchEvents(events);\n    if (phxChildrenAdded) {\n      this.joinNewChildren();\n    }\n    return true;\n  }\n  renderContainer(diff, kind) {\n    return this.liveSocket.time(`toString diff (${kind})`, () => {\n      const tag = this.el.tagName;\n      const cids = diff ? this.rendered.componentCIDs(diff) : null;\n      const { buffer: html, streams } = this.rendered.toString(cids);\n      return [`<${tag}>${html}</${tag}>`, streams];\n    });\n  }\n  componentPatch(diff, cid) {\n    if (isEmpty(diff))\n      return false;\n    const { buffer: html, streams } = this.rendered.componentToString(cid);\n    const patch = new DOMPatch(this, this.el, html, streams, cid);\n    const childrenAdded = this.performPatch(patch, true);\n    return childrenAdded;\n  }\n  getHook(el) {\n    return this.viewHooks[ViewHook.elementID(el)];\n  }\n  addHook(el) {\n    const hookElId = ViewHook.elementID(el);\n    if (el.getAttribute && !this.ownsElement(el)) {\n      return;\n    }\n    if (hookElId && !this.viewHooks[hookElId]) {\n      if (ViewHook.deadHook(el)) {\n        return;\n      }\n      const hook = dom_default.getCustomElHook(el) || logError(`no hook found for custom element: ${el.id}`);\n      this.viewHooks[hookElId] = hook;\n      hook.__attachView(this);\n      return hook;\n    } else if (hookElId || !el.getAttribute) {\n      return;\n    } else {\n      const hookName = el.getAttribute(`data-phx-${PHX_HOOK}`) || el.getAttribute(this.binding(PHX_HOOK));\n      if (!hookName) {\n        return;\n      }\n      const hookDefinition = this.liveSocket.getHookDefinition(hookName);\n      if (hookDefinition) {\n        if (!el.id) {\n          logError(\n            `no DOM ID for hook "${hookName}". Hooks require a unique ID on each element.`,\n            el\n          );\n          return;\n        }\n        let hookInstance;\n        try {\n          if (typeof hookDefinition === "function" && hookDefinition.prototype instanceof ViewHook) {\n            hookInstance = new hookDefinition(this, el);\n          } else if (typeof hookDefinition === "object" && hookDefinition !== null) {\n            hookInstance = new ViewHook(this, el, hookDefinition);\n          } else {\n            logError(\n              `Invalid hook definition for "${hookName}". Expected a class extending ViewHook or an object definition.`,\n              el\n            );\n            return;\n          }\n        } catch (e) {\n          const errorMessage = e instanceof Error ? e.message : String(e);\n          logError(`Failed to create hook "${hookName}": ${errorMessage}`, el);\n          return;\n        }\n        this.viewHooks[ViewHook.elementID(hookInstance.el)] = hookInstance;\n        return hookInstance;\n      } else if (hookName !== null) {\n        logError(`unknown hook foun
1d for "${hookName}"`, el);\n      }\n    }\n  }\n  destroyHook(hook) {\n    const hookId = ViewHook.elementID(hook.el);\n    hook.__destroyed();\n    hook.__cleanup__();\n    delete this.viewHooks[hookId];\n  }\n  applyPendingUpdates() {\n    this.pendingDiffs = this.pendingDiffs.filter(\n      ({ diff, events }) => !this.update(diff, events, true)\n    );\n    this.eachChild((child) => child.applyPendingUpdates());\n  }\n  eachChild(callback) {\n    const children = this.root.children[this.id] || {};\n    for (const id in children) {\n      callback(this.getChildById(id));\n    }\n  }\n  onChannel(event, cb) {\n    this.liveSocket.onChannel(this.channel, event, (resp) => {\n      if (this.isJoinPending()) {\n        if (this.joinCount > 1) {\n          this.pendingJoinOps.push(() => cb(resp));\n        } else {\n          this.root.pendingJoinOps.push([this, () => cb(resp)]);\n        }\n      } else {\n        this.liveSocket.requestDOMUpdate(() => cb(resp));\n      }\n    });\n  }\n  bindChannel() {\n    this.liveSocket.onChannel(this.channel, "diff", (rawDiff) => {\n      this.liveSocket.requestDOMUpdate(() => {\n        this.applyDiff(\n          "update",\n          rawDiff,\n          ({ diff, events }) => this.update(diff, events)\n        );\n      });\n    });\n    this.onChannel(\n      "redirect",\n      ({ to, flash }) => this.onRedirect({ to, flash })\n    );\n    this.onChannel("live_patch", (redir) => this.onLivePatch(redir));\n    this.onChannel("live_redirect", (redir) => this.onLiveRedirect(redir));\n    this.channel.onError((reason) => this.onError(reason));\n    this.channel.onClose((reason) => this.onClose(reason));\n  }\n  destroyAllChildren() {\n    this.eachChild((child) => child.destroy());\n  }\n  onLiveRedirect(redir) {\n    const { to, kind, flash } = redir;\n    const url = this.expandURL(to);\n    const e = new CustomEvent("phx:server-navigate", {\n      detail: { to, kind, flash }\n    });\n    this.liveSocket.historyRedirect(e, url, kind, flash);\n  }\n  onLivePatch(redir) {\n    const { to, kind } = redir;\n    this.href = this.expandURL(to);\n    this.liveSocket.historyPatch(to, kind);\n  }\n  expandURL(to) {\n    return to.startsWith("/") ? `${window.location.protocol}//${window.location.host}${to}` : to;\n  }\n  onRedirect({\n    to,\n    flash,\n    reloadToken\n  }) {\n    this.liveSocket.redirect(to, flash ?? null, reloadToken ?? null);\n  }\n  isDestroyed() {\n    return this.destroyed;\n  }\n  joinDead() {\n    this.isDead = true;\n  }\n  join(callback) {\n    this.showLoader(this.liveSocket.loaderTimeout);\n    this.bindChannel();\n    if (this.isMain()) {\n      this.stopCallback = this.liveSocket.withPageLoading({\n        to: this.href,\n        kind: "initial"\n      });\n    }\n    this.joinCallback = (onDone) => {\n      onDone = onDone || function() {\n      };\n      callback ? callback(this.joinCount, onDone) : onDone();\n    };\n    this.wrapPush(() => this.channel.join(), {\n      ok: (resp) => this.liveSocket.requestDOMUpdate(() => this.onJoin(resp)),\n      error: (error) => this.onJoinError(error),\n      timeout: () => this.onJoinError({ reason: "timeout" })\n    });\n  }\n  onJoinError(resp) {\n    if (resp.events) {\n      this.liveSocket.dispatchEvents(resp.events);\n    }\n    if (resp.reason === "reload") {\n      this.log("error", () => [\n        `failed mount with ${resp.status}. Falling back to page reload`,\n        resp\n      ]);\n      this.onRedirect({\n        to: this.liveSocket.main.href,\n        reloadToken: resp.token\n      });\n      return;\n    } else if (resp.reason === "unauthorized" || resp.reason === "stale") {\n      this.log("error", () => [\n        "unauthorized live_redirect. Falling back to page request",\n        resp\n      ]);\n      this.onRedirect({ to: this.liveSocket.main.href, flash: this.flash });\n      return;\n    }\n    if (resp.redirect || resp.live_redirect) {\n      this.joinPending = false;\n      this.channel.leave();\n    }\n    if (resp.redirect) {\n      return this.onRedirect(resp.redirect);\n    }\n    if (resp.live_redirect) {\n      return this.onLiveRedirect(resp.live_redirect);\n    }\n    this.log("error", () => ["unable to join", resp]);\n    if (this.isMain()) {\n      this.displayError(\n        [PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS],\n        { unstructuredError: resp, errorKind: "server" }\n      );\n      if (this.liveSocket.isConnected()) {\n        this.liveSocket.reloadWithJitter(this);\n      }\n    } else {\n      if (this.joinAttempts >= MAX_CHILD_JOIN_ATTEMPTS) {\n        this.root.displayError(\n          [PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS],\n          { unstructuredError: resp, errorKind: "server" }\n        );\n        this.log("error", () => [\n          `giving up trying to mount after ${MAX_CHILD_JOIN_ATTEMPTS} tries`,\n          resp\n        ]);\n        this.destroy();\n      }
1\n      const trueChildEl = dom_default.byId(this.el.id);\n      if (trueChildEl) {\n        dom_default.mergeAttrs(trueChildEl, this.el);\n        this.displayError(\n          [PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS],\n          { unstructuredError: resp, errorKind: "server" }\n        );\n        this.el = trueChildEl;\n      } else {\n        this.destroy();\n      }\n    }\n  }\n  onClose(reason) {\n    if (this.isDestroyed()) {\n      return;\n    }\n    if (this.isMain() && this.liveSocket.hasPendingLink() && reason !== "leave") {\n      return this.liveSocket.reloadWithJitter(this);\n    }\n    this.destroyAllChildren();\n    this.liveSocket.dropActiveElement(this);\n    if (this.liveSocket.isUnloaded()) {\n      this.showLoader(BEFORE_UNLOAD_LOADER_TIMEOUT);\n    }\n  }\n  onError(reason) {\n    this.onClose(reason);\n    if (this.liveSocket.isConnected()) {\n      this.log("error", () => ["view crashed", reason]);\n    }\n    if (!this.liveSocket.isUnloaded()) {\n      if (this.liveSocket.isConnected()) {\n        this.displayError(\n          [PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS],\n          { unstructuredError: reason, errorKind: "server" }\n        );\n      } else {\n        this.displayError(\n          [PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_CLIENT_ERROR_CLASS],\n          { unstructuredError: reason, errorKind: "client" }\n        );\n      }\n    }\n  }\n  displayError(classes, details = {}) {\n    if (this.isMain()) {\n      dom_default.dispatchEvent(window, "phx:page-loading-start", {\n        detail: { to: this.href, kind: "error", ...details }\n      });\n    }\n    this.showLoader();\n    this.setContainerClasses(...classes);\n    this.delayedDisconnected();\n  }\n  delayedDisconnected() {\n    this.disconnectedTimer = setTimeout(() => {\n      this.execAll(this.binding("disconnected"));\n    }, this.liveSocket.disconnectedTimeout);\n  }\n  wrapPush(callerPush, receives) {\n    const latency = this.liveSocket.getLatencySim();\n    const withLatency = latency ? (cb) => setTimeout(() => !this.isDestroyed() && cb(), latency) : (cb) => !this.isDestroyed() && cb();\n    withLatency(() => {\n      callerPush().receive(\n        "ok",\n        (resp) => withLatency(() => receives.ok && receives.ok(resp))\n      ).receive(\n        "error",\n        (reason) => withLatency(() => receives.error && receives.error(reason))\n      ).receive(\n        "timeout",\n        () => withLatency(() => receives.timeout && receives.timeout())\n      );\n    });\n  }\n  pushWithReply(refGenerator, event, payload) {\n    if (!this.isConnected()) {\n      return Promise.reject(new Error("no connection"));\n    }\n    const [ref, [el], opts] = refGenerator ? refGenerator({ payload }) : [null, [], {}];\n    const oldJoinCount = this.joinCount;\n    let onLoadingDone = function() {\n    };\n    if (opts.page_loading) {\n      onLoadingDone = this.liveSocket.withPageLoading({\n        kind: "element",\n        target: el\n      });\n    }\n    if (typeof payload.cid !== "number") {\n      delete payload.cid;\n    }\n    return new Promise((resolve, reject) => {\n      this.wrapPush(() => this.channel.push(event, payload, PUSH_TIMEOUT), {\n        ok: (resp) => {\n          if (ref !== null) {\n            this.lastAckRef = ref;\n          }\n          const finish = (hookReply) => {\n            if (resp.redirect) {\n              this.onRedirect(resp.redirect);\n            }\n            if (resp.live_patch) {\n              this.onLivePatch(resp.live_patch);\n            }\n            if (resp.live_redirect) {\n              this.onLiveRedirect(resp.live_redirect);\n            }\n            onLoadingDone();\n            resolve({ resp, reply: hookReply, ref });\n          };\n          if (resp.diff) {\n            this.liveSocket.requestDOMUpdate(() => {\n              this.applyDiff("update", resp.diff, ({ diff, reply, events }) => {\n                if (ref !== null) {\n                  this.undoRefs(ref, payload.event);\n                }\n                this.update(diff, events);\n                finish(reply);\n              });\n            });\n          } else {\n            if (ref !== null) {\n              this.undoRefs(ref, payload.event);\n            }\n            finish(null);\n          }\n        },\n        error: (reason) => reject(new Error(`failed with reason: ${JSON.stringify(reason)}`)),\n        timeout: () => {\n          reject(new Error("timeout"));\n          if (this.joinCount === oldJoinCount) {\n            this.liveSocket.reloadWithJitter(this, () => {\n              this.log("timeout", () => [\n                "received timeout while communicating with server. Falling back to hard refresh for recovery"\n              ]);\n            });\n          }\n        }\n      });\n    });\n  }\n  undoRefs(ref, phxEvent, onlyEls) {\n    if (!this.isConnected()) {\n      return;\n    }\n    const selector = `[${PHX_REF_SRC}="${this.refSrc()}"]`;\n    if (onlyEls) {\n      onlyEls = new Set(onlyEls);\n      dom_default.all(document, selector, (parent) => {\n        if (onlyEls && !onlyEls.has(parent)) {\n          return;\n        }\n        dom_default.all(\n          parent,\n          selector,\n          (child) => this.undoElRef(child, ref, phxEvent)\n        );\n        this.undoElRef(parent, ref, phxEvent);\n      });\n    } else {\n      dom_default.all(document, selector, (el) => this.undoElRef(el, ref, phxEvent));\n    }\n  }\n  undoElRef(el, ref, phxEvent) {\n    const elRef = new ElementRef(el);\n    elRef.maybeUndo(ref, phxEvent, (clonedTree) => {\n      const patch = new DOMPatch(this, el, clonedTree, /* @__P
1URE__ */ new Set(), null, {\n        undoRef: ref\n      });\n      const phxChildrenAdded = this.performPatch(patch, true);\n      dom_default.all(\n        el,\n        `[${PHX_REF_SRC}="${this.refSrc()}"]`,\n        (child) => this.undoElRef(child, ref, phxEvent)\n      );\n      if (phxChildrenAdded) {\n        this.joinNewChildren();\n      }\n    });\n  }\n  refSrc() {\n    return this.el.id;\n  }\n  putRef(elements, phxEvent, eventType, opts = {}) {\n    const newRef = this.ref++;\n    const disableWith = this.binding(PHX_DISABLE_WITH);\n    if (opts.loading) {\n      const loadingEls = dom_default.all(document, opts.loading).map((el) => {\n        return { el, lock: true, loading: true };\n      });\n      elements = elements.concat(loadingEls);\n    }\n    for (const { el, lock, loading } of elements) {\n      if (!lock && !loading) {\n        throw new Error("putRef requires lock or loading");\n      }\n      el.setAttribute(PHX_REF_SRC, this.refSrc());\n      if (loading) {\n        el.setAttribute(PHX_REF_LOADING, newRef.toString());\n      }\n      if (lock) {\n        el.setAttribute(PHX_REF_LOCK, newRef.toString());\n      }\n      if (!loading || opts.submitter && !(el === opts.submitter || el === opts.form)) {\n        continue;\n      }\n      const lockCompletePromise = new Promise((resolve) => {\n        el.addEventListener(`phx:undo-lock:${newRef}`, () => resolve(detail), {\n          once: true\n        });\n      });\n      const loadingCompletePromise = new Promise((resolve) => {\n        el.addEventListener(\n          `phx:undo-loading:${newRef}`,\n          () => resolve(detail),\n          { once: true }\n        );\n      });\n      el.classList.add(`phx-${eventType}-loading`);\n      const disableText = el.getAttribute(disableWith);\n      if (disableText !== null) {\n        if (!el.getAttribute(PHX_DISABLE_WITH_RESTORE)) {\n          el.setAttribute(PHX_DISABLE_WITH_RESTORE, el.textContent || "");\n        }\n        if (disableText !== "") {\n          el.textContent = disableText;\n        }\n        el.setAttribute(\n          PHX_DISABLED,\n          el.getAttribute(PHX_DISABLED) || ("disabled" in el ? String(el.disabled) : "")\n        );\n        el.setAttribute("disabled", "");\n      }\n      const detail = {\n        event: phxEvent,\n        eventType,\n        ref: newRef,\n        isLoading: loading,\n        isLocked: lock,\n        lockElements: elements.filter(({ lock: lock2 }) => lock2).map(({ el: el2 }) => el2),\n        loadingElements: elements.filter(({ loading: loading2 }) => loading2).map(({ el: el2 }) => el2),\n        unlock: (els) => {\n          els = Array.isArray(els) ? els : [els];\n          this.undoRefs(newRef, phxEvent, els);\n        },\n        lockComplete: lockCompletePromise,\n        loadingComplete: loadingCompletePromise,\n        lock: (lockEl) => {\n          return new Promise((resolve) => {\n            if (this.isAcked(newRef)) {\n              return resolve(detail);\n            }\n            lockEl.setAttribute(PHX_REF_LOCK, newRef);\n            lockEl.setAttribute(PHX_REF_SRC, this.refSrc());\n            lockEl.addEventListener(\n              `phx:lock-stop:${newRef}`,\n              () => resolve(detail),\n              { once: true }\n            );\n          });\n        }\n      };\n      if (opts.payload) {\n        detail["payload"] = opts.payload;\n      }\n      if (opts.target) {\n        detail["target"] = opts.target;\n      }\n      if (opts.originalEvent) {\n        detail["originalEvent"] = opts.originalEvent;\n      }\n      el.dispatchEvent(\n        new CustomEvent("phx:push", {\n          detail,\n          bubbles: true,\n          cancelable: false\n        })\n      );\n      if (phxEvent) {\n        el.dispatchEvent(\n          new CustomEvent(`phx:push:${phxEvent}`, {\n            detail,\n            bubbles: true,\n            cancelable: false\n          })\n        );\n      }\n    }\n    return [newRef, elements.map(({ el }) => el), opts];\n  }\n  isAcked(ref) {\n    return this.lastAckRef !== null && this.lastAckRef >= ref;\n  }\n  componentID(el) {\n    const cid = el.getAttribute && el.getAttribute(PHX_COMPONENT);\n    return cid ? parseInt(cid) : null;\n  }\n  targetComponentID(target, targetCtx, opts = {}) {\n    if (isCid(targetCtx)) {\n      return targetCtx;\n    }\n    const cidOrSelector = opts.target || target.getAttribute(this.binding("target"));
1\n    if (isCid(cidOrSelector)) {\n      return typeof cidOrSelector === "number" ? cidOrSelector : parseInt(cidOrSelector);\n    } else if (targetCtx && (cidOrSelector !== null || opts.target)) {\n      return this.closestComponentID(targetCtx);\n    } else {\n      return null;\n    }\n  }\n  closestComponentID(targetCtx) {\n    if (isCid(targetCtx)) {\n      return targetCtx;\n    } else if (targetCtx) {\n      return maybe(\n        // We either use the closest data-phx-component binding, or -\n        // in case of portals - continue with the portal source.\n        // This is necessary if teleporting an element outside of its LiveComponent.\n        targetCtx.closest(`[${PHX_COMPONENT}],[${PHX_TELEPORTED_SRC}]`),\n        (el) => {\n          if (el.hasAttribute(PHX_COMPONENT)) {\n            return this.ownsElement(el) && this.componentID(el);\n          }\n          if (el.hasAttribute(PHX_TELEPORTED_SRC)) {\n            const portalParent = dom_default.byId(el.getAttribute(PHX_TELEPORTED_SRC));\n            return this.closestComponentID(portalParent);\n          }\n        }\n      );\n    } else {\n      return null;\n    }\n  }\n  pushHookEvent(el, targetCtx, event, payload) {\n    if (!this.isConnected()) {\n      this.log("hook", () => [\n        "unable to push hook event. LiveView not connected",\n        event,\n        payload\n      ]);\n      return Promise.reject(\n        new Error("unable to push hook event. LiveView not connected")\n      );\n    }\n    const refGenerator = () => this.putRef([{ el, loading: true, lock: true }], event, "hook", {\n      payload,\n      target: targetCtx\n    });\n    return this.pushWithReply(refGenerator, "event", {\n      type: "hook",\n      event,\n      value: payload,\n      cid: this.closestComponentID(targetCtx)\n    }).then(\n      ({ resp: _resp, reply, ref }) => ({ reply, ref })\n    );\n  }\n  extractMeta(el, meta, value) {\n    const prefix = this.binding("value-");\n    for (let i = 0; i < el.attributes.length; i++) {\n      if (!meta) {\n        meta = {};\n      }\n      const name = el.attributes[i].name;\n      if (name.startsWith(prefix)) {\n        meta[name.replace(prefix, "")] = el.getAttribute(name);\n      }\n    }\n    if (el.value !== void 0 && !(el instanceof HTMLFormElement)) {\n      if (!meta) {\n        meta = {};\n      }\n      meta.value = el.value;\n      if (el.tagName === "INPUT" && CHECKABLE_INPUTS.indexOf(el.type) >= 0 && !el.checked) {\n        delete meta.value;\n      }\n    }\n    if (value) {\n      if (!meta) {\n        meta = {};\n      }\n      for (const key in value) {\n        meta[key] = value[key];\n      }\n    }\n    return meta;\n  }\n  serializeForm(form, opts = {}, onlyNames = []) {\n    const { submitter } = opts;\n    let injectedElement;\n    if (submitter && submitter.name) {\n      const input = document.createElement("input");\n      input.type = "hidden";\n      const formId = submitter.getAttribute("form");\n      if (formId) {\n        input.setAttribute("form", formId);\n      }\n      input.name = submitter.name;\n      input.value = submitter.value;\n      submitter.parentElement.insertBefore(input, submitter);\n      injectedElement = input;\n    }\n    const formData = new FormData(form);\n    const toRemove = [];\n    formData.forEach((val, key, _index) => {\n      if (val instanceof File) {\n        toRemove.push(key);\n      }\n    });\n    toRemove.forEach((key) => formData.delete(key));\n    const params = new URLSearchParams();\n    const { inputsUnused, onlyHiddenInputs } = Array.from(form.elements).reduce(\n      (acc, input) => {\n        if (!dom_default.isFormAssociated(input)) {\n          return acc;\n        }\n        const { inputsUnused: inputsUnused2, onlyHiddenInputs: onlyHiddenInputs2 } = acc;\n        const key = input.name;\n        if (!key) {\n          return acc;\n        }\n        if (inputsUnused2[key] === void 0) {\n          inputsUnused2[key] = true;\n        }\n        if (onlyHiddenInputs2[key] === void 0) {\n          onlyHiddenInputs2[key] = true;\n        }\n        const inputSkipUnusedField = input.hasAttribute(\n          this.binding(PHX_NO_UNUSED_FIELD)\n        );\n        const isUsed = dom_default.private(input, PHX_HAS_FOCUSED) || dom_default.private(input, PHX_HAS_SUBMITTED) || inputSkipUnusedField;\n        const isHidden = input.type === "hidden";
1\n        inputsUnused2[key] = inputsUnused2[key] && !isUsed;\n        onlyHiddenInputs2[key] = onlyHiddenInputs2[key] && isHidden;\n        return acc;\n      },\n      { inputsUnused: {}, onlyHiddenInputs: {} }\n    );\n    const formSkipUnusedFields = form.hasAttribute(\n      this.binding(PHX_NO_UNUSED_FIELD)\n    );\n    for (const [key, val] of formData.entries()) {\n      if (onlyNames.length === 0 || onlyNames.indexOf(key) >= 0) {\n        const isUnused = inputsUnused[key];\n        const hidden = onlyHiddenInputs[key];\n        const skipUnusedCheck = formSkipUnusedFields;\n        if (!skipUnusedCheck && isUnused && !(submitter && submitter.name == key) && !hidden) {\n          params.append(prependFormDataKey(key, "_unused_"), "");\n        }\n        if (typeof val === "string") {\n          params.append(key, val);\n        }\n      }\n    }\n    if (submitter && injectedElement) {\n      submitter.parentElement.removeChild(injectedElement);\n    }\n    return params.toString();\n  }\n  pushEvent(type, el, targetCtx, phxEvent, meta, opts = {}, onReply) {\n    this.pushWithReply(\n      (maybePayload) => this.putRef([{ el, loading: true, lock: true }], phxEvent, type, {\n        ...opts,\n        payload: maybePayload?.payload\n      }),\n      "event",\n      {\n        type,\n        event: phxEvent,\n        value: this.extractMeta(el, meta, opts.value),\n        cid: this.targetComponentID(el, targetCtx, opts)\n      }\n    ).then(({ reply }) => onReply && onReply(reply)).catch((error) => logError("Failed to push event", error));\n  }\n  pushFileProgress(fileEl, entryRef, progress, onReply = function() {\n  }) {\n    this.liveSocket.withinOwners(fileEl.form, (view, targetCtx) => {\n      view.pushWithReply(null, "progress", {\n        event: fileEl.getAttribute(view.binding(PHX_PROGRESS)),\n        ref: fileEl.getAttribute(PHX_UPLOAD_REF),\n        entry_ref: entryRef,\n        progress,\n        cid: view.targetComponentID(fileEl.form, targetCtx)\n      }).then(() => onReply()).catch((error) => logError("Failed to push file progress", error));\n    });\n  }\n  pushInput(inputEl, targetCtx, forceCid, phxEvent, opts, callback) {\n    if (!inputEl.form) {\n      throw new Error("form events require the input to be inside a form");\n    }\n    let uploads;\n    const cid = isCid(forceCid) ? forceCid : this.targetComponentID(inputEl.form, targetCtx, opts);\n    const refGenerator = (maybePayload) => {\n      return this.putRef(\n        [\n          { el: inputEl, loading: true, lock: true },\n          { el: inputEl.form, loading: true, lock: true }\n        ],\n        phxEvent,\n        "change",\n        { ...opts, payload: maybePayload?.payload }\n      );\n    };\n    let formData;\n    const meta = this.extractMeta(inputEl.form, {}, opts.value);\n    const serializeOpts = {};\n    if (inputEl instanceof HTMLButtonElement) {\n      serializeOpts.submitter = inputEl;\n    }\n    if (inputEl.getAttribute(this.binding("change"))) {\n      formData = this.serializeForm(inputEl.form, serializeOpts, [\n        inputEl.name\n      ]);\n    } else {\n      formData = this.serializeForm(inputEl.form, serializeOpts);\n    }\n    if (dom_default.isUploadInput(inputEl) && inputEl.files && inputEl.files.length > 0) {\n      LiveUploader.trackFiles(inputEl, Array.from(inputEl.files));\n    }\n    uploads = LiveUploader.serializeUploads(inputEl);\n    const event = {\n      type: "form",\n      event: phxEvent,\n      value: formData,\n      meta: {\n        // no target was implicitly sent as "undefined" in LV <= 1.0.5, therefore\n        // we have to keep it. In 1.0.6 we switched from passing meta as URL encoded data\n        // to passing it directly in the event, but the JSON encode would drop keys with\n        // undefined values.\n        _target: opts._target || "undefined",\n        ...meta\n      },\n      uploads,\n      cid\n    };\n    this.pushWithReply(refGenerator, "event", event).then(({ resp }) => {\n      if (dom_default.isUploadInput(inputEl) && dom_default.isAutoUpload(inputEl)) {\n        ElementRef.onUnlock(inputEl, () => {\n          if (LiveUploader.filesAwaitingPreflight(inputEl).length > 0) {\n            const [ref, _els] = refGenerator();\n            this.undoRefs(ref, phxEvent, [inputEl.form]);\n            this.uploadFiles(\n              inputEl.form,\n              phxEvent,\n              targetCtx,\n              ref,\n              cid,\n              (_uploads) =>
1 {\n                callback && callback(resp);\n                this.triggerAwaitingSubmit(inputEl.form, phxEvent);\n                this.undoRefs(ref, phxEvent);\n              }\n            );\n          }\n        });\n      } else {\n        callback && callback(resp);\n      }\n    }).catch((error) => logError("Failed to push input event", error));\n  }\n  triggerAwaitingSubmit(formEl, phxEvent) {\n    const awaitingSubmit = this.getScheduledSubmit(formEl);\n    if (awaitingSubmit) {\n      const [_el, _ref, _opts, callback] = awaitingSubmit;\n      this.cancelSubmit(formEl, phxEvent);\n      callback();\n    }\n  }\n  getScheduledSubmit(formEl) {\n    return this.formSubmits.find(\n      ([el, _ref, _opts, _callback]) => el.isSameNode(formEl)\n    );\n  }\n  scheduleSubmit(formEl, ref, opts, callback) {\n    if (this.getScheduledSubmit(formEl)) {\n      return true;\n    }\n    this.formSubmits.push([formEl, ref, opts, callback]);\n  }\n  cancelSubmit(formEl, phxEvent) {\n    this.formSubmits = this.formSubmits.filter(\n      ([el, ref, _opts, _callback]) => {\n        if (el.isSameNode(formEl)) {\n          this.undoRefs(ref, phxEvent);\n          return false;\n        } else {\n          return true;\n        }\n      }\n    );\n  }\n  disableForm(formEl, phxEvent, opts = {}) {\n    const filterIgnored = (el) => {\n      const userIgnored = closestPhxBinding(\n        el,\n        `${this.binding(PHX_UPDATE)}=ignore`,\n        el.form\n      );\n      return !(userIgnored || closestPhxBinding(el, "data-phx-update=ignore", el.form));\n    };\n    const filterDisables = (el) => {\n      return el.hasAttribute(this.binding(PHX_DISABLE_WITH));\n    };\n    const filterButton = (el) => el.tagName == "BUTTON";\n    const filterInput = (el) => ["INPUT", "TEXTAREA"].includes(el.tagName);\n    const formElements = Array.from(formEl.elements);\n    const disables = formElements.filter(filterDisables);\n    const buttons = formElements.filter(filterButton).filter(filterIgnored);\n    const inputs = formElements.filter(filterInput).filter(filterIgnored);\n    buttons.forEach((button) => {\n      button.setAttribute(PHX_DISABLED, button.disabled.toString());\n      button.disabled = true;\n    });\n    inputs.forEach((input) => {\n      input.setAttribute(PHX_READONLY, input.readOnly.toString());\n      input.readOnly = true;\n      if (input instanceof HTMLInputElement && input.files) {\n        input.setAttribute(PHX_DISABLED, input.disabled.toString());\n        input.disabled = true;\n      }\n    });\n    const formEls = disables.concat(buttons).concat(inputs).map((el) => {\n      return { el, loading: true, lock: true };\n    });\n    const els = [\n      { el: formEl, loading: true, lock: false },\n      ...formEls\n    ].reverse();\n    return this.putRef(els, phxEvent, "submit", opts);\n  }\n  pushFormSubmit(formEl, targetCtx, phxEvent, submitter, opts, onReply) {\n    const refGenerator = (maybePayload) => this.disableForm(formEl, phxEvent, {\n      ...opts,\n      form: formEl,\n      payload: maybePayload?.payload,\n      submitter\n    });\n    dom_default.putPrivate(formEl, "submitter", submitter);\n    const cid = this.targetComponentID(formEl, targetCtx);\n    if (LiveUploader.hasUploadsInProgress(formEl)) {\n      const [ref, _els] = refGenerator();\n      const push = () => this.pushFormSubmit(\n        formEl,\n        targetCtx,\n        phxEvent,\n        submitter,\n        opts,\n        onReply\n      );\n      return this.scheduleSubmit(formEl, ref, opts, push);\n    } else if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {\n      const [ref, els] = refGenerator();\n      const proxyRefGen = () => [ref, els, opts];\n      this.uploadFiles(formEl, phxEvent, targetCtx, ref, cid, (_uploads) => {\n        if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {\n          return this.undoRefs(ref, phxEvent);\n        }\n        const meta = this.extractMeta(formEl, {}, opts.value);\n        const formData = this.serializeForm(formEl, { submitter });\n        this.pushWithReply(proxyRefGen, "event", {\n          type: "form",\n          event: phxEvent,\n          value: formData,\n          meta,\n          cid\n        }).then(({ resp }) => onReply(resp)).catch((error) => logError("Failed to push form submit", error));\n      });\n    } else if (!(formEl.hasAttribute(PHX_REF_SRC) && formEl.classList.contains("phx-submit-loading"))) {\n      const meta = this.extractMeta(formEl, {}, opts.value);\n      const formData = this.serializeForm(formEl, { submitter });\n      this.pushWithReply(refGenerator, "event", {\n        type: "form",\n        event: phxEvent,\n        value: formData,\n        meta,\n        cid\n      }).then(({ resp }) => onReply(resp)).catch((error) => logError("Failed to push form submit", error));\n    }\n  }\n  uploadFiles(formEl, phxEvent, targetCtx, ref, cid, onComplete) {\n    const joinCountAtUpload = this.joinCount;\n    const inputEls = LiveUploader.activeFileInputs(formEl);\n    let numFileInputsInProgress = inputEls.length;
1\n    inputEls.forEach((inputEl) => {\n      const uploader = new LiveUploader(inputEl, this, () => {\n        numFileInputsInProgress--;\n        if (numFileInputsInProgress === 0) {\n          onComplete();\n        }\n      });\n      const entries = uploader.entries().map((entry) => entry.toPreflightPayload());\n      if (entries.length === 0) {\n        numFileInputsInProgress--;\n        return;\n      }\n      const payload = {\n        ref: inputEl.getAttribute(PHX_UPLOAD_REF),\n        entries,\n        cid: this.targetComponentID(inputEl.form, targetCtx)\n      };\n      this.log("upload", () => ["sending preflight request", payload]);\n      this.pushWithReply(null, "allow_upload", payload).then(({ resp }) => {\n        this.log("upload", () => ["got preflight response", resp]);\n        uploader.entries().forEach((entry) => {\n          if (resp.entries && !resp.entries[entry.ref]) {\n            this.handleFailedEntryPreflight(\n              entry.ref,\n              "failed preflight",\n              uploader\n            );\n          }\n        });\n        if (resp.error || Object.keys(resp.entries).length === 0) {\n          this.undoRefs(ref, phxEvent);\n          const errors = resp.error || [];\n          errors.map(([entry_ref, reason]) => {\n            this.handleFailedEntryPreflight(entry_ref, reason, uploader);\n          });\n        } else {\n          const onError = (callback) => {\n            this.channel.onError(() => {\n              if (this.joinCount === joinCountAtUpload) {\n                callback();\n              }\n            });\n          };\n          uploader.initAdapterUpload(resp, onError, this.liveSocket);\n        }\n      }).catch((error) => logError("Failed to push upload", error));\n    });\n  }\n  handleFailedEntryPreflight(uploadRef, reason, uploader) {\n    if (uploader.isAutoUpload()) {\n      const entry = uploader.entries().find((entry2) => entry2.ref === uploadRef.toString());\n      if (entry) {\n        entry.cancel();\n      }\n    } else {\n      uploader.entries().map((entry) => entry.cancel());\n    }\n    this.log("upload", () => [`error for entry ${uploadRef}`, reason]);\n  }\n  dispatchUploads(targetCtx, name, filesOrBlobs) {\n    const targetElement = this.targetCtxElement(targetCtx) || this.el;\n    const inputs = dom_default.findUploadInputs(targetElement).filter(\n      (el) => el.name === name\n    );\n    if (inputs.length === 0) {\n      logError(`no live file inputs found matching the name "${name}"`);\n    } else if (inputs.length > 1) {\n      logError(`duplicate live file inputs found matching the name "${name}"`);\n    } else {\n      dom_default.dispatchEvent(inputs[0], PHX_TRACK_UPLOADS, {\n        detail: { files: filesOrBlobs }\n      });\n    }\n  }\n  targetCtxElement(targetCtx) {\n    if (isCid(targetCtx)) {\n      const target = dom_default.findComponent(this.id, targetCtx);\n      return target;\n    } else if (targetCtx) {\n      return targetCtx;\n    } else {\n      return null;\n    }\n  }\n  pushFormRecovery(oldForm, newForm, templateDom, callback) {\n    const phxChange = this.binding("change");\n    const phxTarget = newForm.getAttribute(this.binding("target")) || newForm;\n    const phxEvent = newForm.getAttribute(this.binding(PHX_AUTO_RECOVER)) || newForm.getAttribute(this.binding("change"));\n    const inputs = Array.from(oldForm.elements).filter(\n      (el) => dom_default.isFormAssociated(el) && el.name && !el.hasAttribute(phxChange)\n    );\n    if (inputs.length === 0) {\n      callback();\n      return;\n    }\n    inputs.forEach(\n      (input2) => input2.hasAttribute(PHX_UPLOAD_REF) && LiveUploader.clearFiles(input2)\n    );\n    const input = inputs.find((el) => el.type !== "hidden") || inputs[0];\n    let pending = 0;\n    this.withinTargets(\n      phxTarget,\n      (targetView, targetCtx) => {\n        const cid = this.targetComponentID(newForm, targetCtx);\n        pending++;\n        let e = new CustomEvent("phx:form-recovery", {\n          detail: { sourceElement: oldForm }\n        });\n        js_default.exec(e, "change", phxEvent, this, input, [\n          "push",\n          {\n            _target: input.name,\n            targetView,\n            targetCtx,\n            newCid: cid,\n            callback: () => {\n              pending--;\n              if (pending === 0) {\n                callback();\n              }\n            }\n          }\n        ]);\n      },\n      templateDom\n    );\n  }\n  pushLinkPatch(e, href, targetEl, callback) {\n    const linkRef = this.liveSocket.setPendingLink(href);\n    const loading = e.isTrusted && e.type !== "popstate";\n    const refGen = targetEl ? () => this.putRef(\n      [{ el: targetEl, loading, lock: true }],\n      null,\n      "click"\n    ) : null;\n    const fallback = () => this.liveSocket.redirect(window.location.href, null, null);\n    const url = href.startsWith("/") ? `${location.protocol}//${location.host}${href}` : href;\n    this.pushWithReply(refGen, "live_patch", { url }).then(\n      ({ resp }) =>
1 {\n        this.liveSocket.requestDOMUpdate(() => {\n          if (resp.link_redirect) {\n            this.liveSocket.replaceMain(href, null, callback, linkRef);\n          } else if (resp.redirect) {\n            return;\n          } else {\n            if (this.liveSocket.commitPendingLink(linkRef)) {\n              this.href = href;\n            }\n            this.applyPendingUpdates();\n            callback && callback(linkRef);\n          }\n        });\n      },\n      ({ error: _error, timeout: _timeout }) => fallback()\n    );\n  }\n  getFormsForRecovery() {\n    if (this.joinCount === 0) {\n      return {};\n    }\n    const phxChange = this.binding("change");\n    return dom_default.all(\n      document,\n      `#${CSS.escape(this.id)} form[${phxChange}], [${PHX_TELEPORTED_REF}="${CSS.escape(this.id)}"] form[${phxChange}]`\n    ).filter((form) => form instanceof HTMLFormElement).filter((form) => form.id).filter((form) => form.elements.length > 0).filter(\n      (form) => form.getAttribute(this.binding(PHX_AUTO_RECOVER)) !== "ignore"\n    ).map((form) => {\n      const clonedForm = form.cloneNode(true);\n      morphdom_esm_default(clonedForm, form, {\n        onBeforeElUpdated: (fromEl, toEl) => {\n          dom_default.copyPrivates(fromEl, toEl);\n          if (fromEl.getAttribute("form") === form.id && fromEl.parentNode) {\n            fromEl.parentNode.removeChild(fromEl);\n            return false;\n          }\n          return true;\n        }\n      });\n      const externalElements = document.querySelectorAll(\n        `[form="${CSS.escape(form.id)}"]`\n      );\n      Array.from(externalElements).forEach((el) => {\n        const clonedEl = el.cloneNode(true);\n        morphdom_esm_default(clonedEl, el);\n        dom_default.copyPrivates(clonedEl, el);\n        clonedEl.removeAttribute("form");\n        clonedForm.appendChild(clonedEl);\n      });\n      return clonedForm;\n    }).reduce((acc, form) => {\n      acc[form.id] = form;\n      return acc;\n    }, {});\n  }\n  maybePushComponentsDestroyed(destroyedCIDs) {\n    let willDestroyCIDs = destroyedCIDs.filter((cid) => {\n      return dom_default.findComponent(this.id, cid) === null;\n    });\n    const onError = (error) => {\n      if (!this.isDestroyed()) {\n        logError("Failed to push components destroyed", error);\n      }\n    };\n    if (willDestroyCIDs.length > 0) {\n      willDestroyCIDs.forEach((cid) => this.rendered.resetRender(cid));\n      this.pushWithReply(null, "cids_will_destroy", { cids: willDestroyCIDs }).then(() => {\n        this.liveSocket.requestDOMUpdate(() => {\n          let completelyDestroyCIDs = willDestroyCIDs.filter((cid) => {\n            return dom_default.findComponent(this.id, cid) === null;\n          });\n          if (completelyDestroyCIDs.length > 0) {\n            this.pushWithReply(null, "cids_destroyed", {\n              cids: completelyDestroyCIDs\n            }).then(({ resp }) => {\n              this.rendered.pruneCIDs(resp.cids);\n            }).catch(onError);\n          }\n        });\n      }).catch(onError);\n    }\n  }\n  ownsElement(el) {\n    let parentViewEl = dom_default.closestViewEl(el);\n    return el.getAttribute(PHX_PARENT_ID) === this.id || parentViewEl && parentViewEl.id === this.id || !parentViewEl && this.isDead;\n  }\n  submitForm(form, targetCtx, phxEvent, submitter, opts = {}) {\n    dom_default.putPrivate(form, PHX_HAS_SUBMITTED, true);\n    const inputs = Array.from(form.elements);\n    inputs.forEach((input) => dom_default.putPrivate(input, PHX_HAS_SUBMITTED, true));\n    this.liveSocket.blurActiveElement();\n    this.pushFormSubmit(form, targetCtx, phxEvent, submitter, opts, () => {\n      this.liveSocket.restorePreviouslyActiveFocus();\n    });\n  }\n  binding(kind) {\n    return this.liveSocket.binding(kind);\n  }\n  // phx-portal\n  pushPortalElementId(id) {\n    this.portalElementIds.add(id);\n  }\n  dropPortalElementId(id) {\n    this.portalElementIds.delete(id);\n  }\n  destroyPortalElements() {\n    if (!this.liveSocket.unloaded) {\n      this.portalElementIds.forEach((id) => {\n        const el = document.getElementById(id);\n        if (el) {\n          el.remove();\n        }\n      });\n    }\n  }\n};\n\n// js/phoenix_live_view/live_socket.ts\nvar isUsedInput = (el) => dom_default.isUsedInput(el);\nvar LiveSocket = class {\n  /**\n   * Creates a new LiveSocket instance.\n   */\n  constructor(url, phxSocket, opts = {}) {\n    /** @internal */\n    this.unloaded = false;\n    if (!phxSocket || phxSocket.constructor.name === "Object") {\n      throw new Error(`\n      a phoenix Socket must be provided as the second argument to the LiveSocket constructor. For example:\n\n          import {Socket} from "phoenix"\n          import {LiveSocket} from "phoenix_live_view"\n          let liveSocket = new LiveSocket("/live", Socket, {...})\n      `);\n    }\n    this.socket = new phxSocket(url, opts);\n    this.bindingPrefix = opts.bindingPrefix || BINDING_PREFIX;\n    this.params = phoenix_live_view_esm_closure(opts.params || {});\n    this.viewLogger = opts.viewLogger;\n    this.metadataCallbacks = opts.metadata || {};\n    this.defaults = Object.assign(clone(DEFAULTS), opts.defaults || {});\n    this.prevActive = null;\n    this.silenced = false;\n    this.main = null;\n    this.outgoingMainEl = null;\n    this.clickStartedAtTarget = null;\n    this.linkRef = 1;\n    this.roots = {};\n    this.href = window.location.href;\n    this.pendingLink = null;\n    this.currentLocation = clone(window.location);\n    this.hooks = opts.hooks || {};\n    this.uploaders = opts.uploaders || {};\n    this.loaderTimeout = opts.loaderTimeout || LOADER_TIMEOUT;\n    this.disconnectedTimeout = opts.disconnectedTimeout || DISCONNECTED_TIMEOUT;\n    this.reloadWithJitterTimer = null;\n    this.maxReloads = opts.maxReloads || MAX_RELOADS;\n    this.reloadJitterMin = opts.reloadJitterMin || RELOAD_JITTER_MIN;\n    this.reloadJitterMax = opts.reloadJitterMax || RELOAD_JITTER_MAX;\n    this.failsafeJitter = opts.failsafeJitter || FAILSAFE_JITTER;\n    this.localStorage = opts.localStorage || window.localStorage;\n    this.sessionStorage = opts.sessionStorage || window.sessionStorage;\n    this.boundTopLevelEvents = false;\n    this.boundEventNames = /* @__PURE__ */ new Set();\n    this.blockPhxChangeWhileComposing = opts.blockPhxChangeWhileComposing || false;\n    this.serverCloseRef = null;\n    this.domCallbacks = Object.assign(\n      {\n        jsQuerySelectorAll: null,\n        onPatchStart: phoenix_live_view_esm_closure(),\n        onPatchEnd: phoenix_live_view_esm_closure(),\n        onNodeAdded: phoenix_live_view_esm_closure(),\n        onBeforeElUpdated: phoenix_live_view_esm_closure()\n      },\n      opts.dom || {}\n    );\n    this.transitions = new TransitionSet();\n    this.currentHistoryPosition = parseInt(this.sessionStorage.getItem(PHX_LV_HISTORY_POSITION) || "0") || 0;\n    window.addEventListener("pagehide", (_e) => {\n      this.unloaded = true;\n    });\n    this.socket.onOpen(() =>
1 {\n      if (this.isUnloaded()) {\n        window.location.reload();\n      }\n    });\n  }\n  // public\n  /**\n   * Returns the version of the LiveView client.\n   */\n  version() {\n    return "1.2.6";\n  }\n  /**\n   * Returns true if profiling is enabled. See {@link enableProfiling} and {@link disableProfiling}.\n   */\n  isProfileEnabled() {\n    return this.sessionStorage.getItem(PHX_LV_PROFILE) === "true";\n  }\n  /**\n   * Returns true if debugging is enabled. See {@link enableDebug} and {@link disableDebug}.\n   */\n  isDebugEnabled() {\n    return this.sessionStorage.getItem(PHX_LV_DEBUG) === "true";\n  }\n  /**\n   * Returns true if debugging is disabled. See {@link enableDebug} and {@link disableDebug}.\n   */\n  isDebugDisabled() {\n    return this.sessionStorage.getItem(PHX_LV_DEBUG) === "false";\n  }\n  /**\n   * Enables debugging.\n   *\n   * When debugging is enabled, the LiveView client will log debug information to the console.\n   * See [Debugging client events](https://phoenix-live-view.hexdocs.pm/js-interop.html#debugging-client-events) for more information.\n   */\n  enableDebug() {\n    this.sessionStorage.setItem(PHX_LV_DEBUG, "true");\n  }\n  /**\n   * Enables profiling.\n   *\n   * When profiling is enabled, the LiveView client will log profiling information to the console.\n   */\n  enableProfiling() {\n    this.sessionStorage.setItem(PHX_LV_PROFILE, "true");\n  }\n  /**\n   * Disables debugging.\n   */\n  disableDebug() {\n    this.sessionStorage.setItem(PHX_LV_DEBUG, "false");\n  }\n  /**\n   * Disables profiling.\n   */\n  disableProfiling() {\n    this.sessionStorage.removeItem(PHX_LV_PROFILE);\n  }\n  /**\n   * Enables latency simulation.\n   *\n   * When latency simulation is enabled, the LiveView client will add a delay to requests and responses from the server.\n   * See [Simulating Latency](https://phoenix-live-view.hexdocs.pm/js-interop.html#simulating-latency) for more information.\n   */\n  enableLatencySim(upperBoundMs) {\n    this.enableDebug();\n    console.log(\n      "latency simulator enabled for the duration of this browser session. Call disableLatencySim() to disable"\n    );\n    this.sessionStorage.setItem(PHX_LV_LATENCY_SIM, upperBoundMs.toString());\n  }\n  /**\n   * Disables latency simulation.\n   */\n  disableLatencySim() {\n    this.sessionStorage.removeItem(PHX_LV_LATENCY_SIM);\n  }\n  /**\n   * Returns the current latency simulation upper bound.\n   */\n  getLatencySim() {\n    const str = this.sessionStorage.getItem(PHX_LV_LATENCY_SIM);\n    return str ? parseInt(str) : null;\n  }\n  /**\n   * Returns the Phoenix Socket instance.\n   */\n  getSocket() {\n    return this.socket;\n  }\n  /**\n   * Connects to the LiveView server.\n   */\n  connect() {\n    if (window.location.hostname === "localhost" && !this.isDebugDisabled()) {\n      this.enableDebug();\n    }\n    const doConnect = () => {\n      this.resetReloadStatus();\n      if (this.joinRootViews()) {\n        this.bindTopLevelEvents();\n        this.socket.connect();\n      } else if (this.main) {\n        this.socket.connect();\n      } else {\n        this.bindTopLevelEvents({ dead: true });\n      }\n      this.joinDeadView();\n    };\n    if (["complete", "loaded", "interactive"].indexOf(document.readyState) >= 0) {\n      doConnect();\n    } else {\n      document.addEventListener("DOMContentLoaded", () => doConnect());\n    }\n  }\n  /**\n   * Disconnects from the LiveView server.\n   */\n  disconnect(callback) {\n    this.reloadWithJitterTimer != null && clearTimeout(this.reloadWithJitterTimer);\n    if (this.serverCloseRef) {\n      this.socket.off([this.serverCloseRef]);\n      this.serverCloseRef = null;\n    }\n    this.socket.disconnect(callback);\n  }\n  /**\n   * Can be used to replace the transport used by the underlying Phoenix Socket.\n   */\n  replaceTransport(transport) {\n    this.reloadWithJitterTimer != null && clearTimeout(this.reloadWithJitterTimer);\n    this.socket.replaceTransport(transport);\n    this.connect();\n  }\n  /**\n   * Executes an encoded JS command, targeting the given element.\n   *\n   * See [`Phoenix.LiveView.JS`](https://phoenix-live-view.hexdocs.pm/Phoenix.LiveView.JS.html) for more information.\n   */\n  execJS(el, encodedJS, eventType = null) {\n    const e = new CustomEvent("phx:exec", { detail: { sourceElement: el } });\n    this.owner(el, (view) => js_default.exec(e, eventType, encodedJS, view, el));\n  }\n  /**\n   * Returns an object with methods to manipulate the DOM and execute JavaScript.\n   * The applied changes integrate with server DOM patching.\n   *\n   * See [JavaScript interoperability](https://phoenix-live-view.hexdocs.pm/js-interop.html) for more information.\n   */\n  js() {\n    return js_commands_default(this, "js");\n  }\n  // private\n  /** @internal */\n  unload() {\n    if (this.unloaded) {\n      return;\n    }\n    if (this.main && this.isConnected()) {\n      this.log(this.main, "socket", () => ["disconnect for page nav"]);\n    }\n    this.unloaded = true;\n    this.destroyAllViews();\n    this.disconnect();\n  }\n  /** @internal */\n  triggerDOM(kind, args) {\n    this.domCallbacks[kind](...args);\n  }\n  /** @internal */\n  time(name, func) {\n    if (!this.isProfileEnabled() || !console.time) {\n      return func();\n    }\n    console.time(name);\n    const result = func();\n    console.timeEnd(name);\n    return result;\n  }\n  /** @internal */\n  log(view, kind, msgCallback) {\n    if (this.viewLogger) {\n      const [msg, obj] = msgCallback();\n      this.viewLogger(view, kind, msg, obj);\n    } else if (this.isDebugEnabled()) {\n      const [msg, obj] = msgCallback();\n      debug(view, kind, msg, obj);\n    }\n  }\n  /** @internal */\n  requestDOMUpdate(callback) {\n    this.transitions.after(callback);\n  }\n  /** @internal */\n  asyncTransition(promise) {\n    this.transitions.addAsyncTransition(promise);\n  }\n  /** @internal */\n  transition(time, onStart, onDone = function() {\
1n  }) {\n    this.transitions.addTransition(time, onStart, onDone);\n  }\n  /** @internal */\n  onChannel(channel, event, cb) {\n    channel.on(event, (data) => {\n      const latency = this.getLatencySim();\n      if (!latency) {\n        cb(data);\n      } else {\n        setTimeout(() => cb(data), latency);\n      }\n    });\n  }\n  /** @internal */\n  reloadWithJitter(view, log) {\n    this.reloadWithJitterTimer != null && clearTimeout(this.reloadWithJitterTimer);\n    this.disconnect();\n    const minMs = this.reloadJitterMin;\n    const maxMs = this.reloadJitterMax;\n    let afterMs = Math.floor(Math.random() * (maxMs - minMs + 1)) + minMs;\n    const tries = browser_default.updateLocal(\n      this.localStorage,\n      window.location.pathname,\n      CONSECUTIVE_RELOADS,\n      0,\n      (count) => count + 1\n    );\n    if (tries >= this.maxReloads) {\n      afterMs = this.failsafeJitter;\n    }\n    this.reloadWithJitterTimer = setTimeout(() => {\n      if (view.isDestroyed() || view.isConnected()) {\n        return;\n      }\n      view.destroy();\n      log ? log() : this.log(view, "join", () => [\n        `encountered ${tries} consecutive reloads`\n      ]);\n      if (tries >= this.maxReloads) {\n        this.log(view, "join", () => [\n          `exceeded ${this.maxReloads} consecutive reloads. Entering failsafe mode`\n        ]);\n      }\n      if (this.pendingLink !== null) {\n        window.location.href = this.pendingLink;\n      } else {\n        window.location.reload();\n      }\n    }, afterMs);\n  }\n  /** @internal */\n  getHookDefinition(name) {\n    if (!name) {\n      return;\n    }\n    return this.maybeInternalHook(name) || this.hooks[name] || this.maybeRuntimeHook(name);\n  }\n  /** @internal */\n  maybeInternalHook(name) {\n    return name && name.startsWith("Phoenix.") && hooks_default[name.split(".")[1]];\n  }\n  /** @internal */\n  maybeRuntimeHook(name) {\n    const runtimeHook = document.querySelector(\n      `script[${PHX_RUNTIME_HOOK}="${CSS.escape(name)}"]`\n    );\n    if (!runtimeHook) {\n      return;\n    }\n    let callbacks = window[`phx_hook_${name}`];\n    if (!callbacks || typeof callbacks !== "function") {\n      logError("a runtime hook must be a function", runtimeHook);\n      return;\n    }\n    const hookDefiniton = callbacks();\n    if (hookDefiniton && (typeof hookDefiniton === "object" || typeof hookDefiniton === "function")) {\n      return hookDefiniton;\n    }\n    logError(\n      "runtime hook must return an object with hook callbacks or an instance of ViewHook",\n      runtimeHook\n    );\n  }\n  /** @internal */\n  isUnloaded() {\n    return this.unloaded;\n  }\n  /** @internal */\n  isConnected() {\n    return this.socket.isConnected();\n  }\n  /** @internal */\n  getBindingPrefix() {\n    return this.bindingPrefix;\n  }\n  /** @internal */\n  binding(kind) {\n    return `${this.getBindingPrefix()}${kind}`;\n  }\n  /** @internal */\n  channel(topic, params) {\n    return this.socket.channel(topic, params);\n  }\n  /** @internal */\n  joinDeadView() {\n    const body = document.body;\n    if (body && !this.isPhxView(body) && !this.isPhxView(document.firstElementChild)) {\n      const view = this.newRootView(body);\n      view.setHref(this.getHref());\n      view.joinDead();\n      if (!this.main) {\n        this.main = view;\n      }\n      window.requestAnimationFrame(() => {\n        view.execNewMounted();\n        this.maybeScroll(history.state?.scroll);\n      });\n    }\n  }\n  /** @internal */\n  joinRootViews() {\n    let rootsFound = false;\n    dom_default.all(\n      document,\n      `${PHX_VIEW_SELECTOR}:not([${PHX_PARENT_ID}])`,\n      (rootEl) => {\n        if (!this.getRootById(rootEl.id)) {\n          const view = this.newRootView(rootEl);\n          if (!dom_default.isPhxSticky(rootEl)) {\n            view.setHref(this.getHref());\n          }\n          view.join();\n          if (rootEl.hasAttribute(PHX_MAIN)) {\n            this.main = view;\n          }\n        }\n        rootsFound = true;\n      }\n    );\n    return rootsFound;\n  }\n  /** @internal */\n  redirect(to, flash, reloadToken) {\n    if (reloadToken) {\n      browser_default.setCookie(PHX_RELOAD_STATUS, reloadToken, 60);\n    }\n    this.unload();\n    browser_default.redirect(to, flash);\n  }\n  /** @internal */\n  replaceMain(href, flash, callback = null, linkRef = this.setPendingLink(href)) {\n    if (!this.main) {\n      return;\n    }\n    const liveReferer = this.currentLocation.href;\n    this.outgoingMainEl = this.outgoingMainEl || this.main.el;\n    const stickies = dom_default.findPhxSticky(document) || [];\n    const removeEls = dom_default.all(\n      this.outgoingMainEl,\n      `[${this.binding("remove")}]`\n    ).filter((el) => !dom_default.isChildOfAny(el, stickies));\n    const newMainEl = dom_default.cloneNode(this.outgoingMainEl, "");\n    const oldMainView = this.main;\n    oldMainView.showLoader(this.loaderTimeout);\n    oldMainView.destroy();\n    this.main = this.newRootView(newMainEl, flash, liveReferer);\n    this.main.setRedirect(href);\n    this.transitionRemoves(removeEls, oldMainView);\n    this.main.join((joinCount, onDone) => {\n      if (joinCount === 1 && this.commitPendingLink(linkRef)) {\n        this.requestDOMUpdate(() =>
1 {\n          removeEls.forEach((el) => el.remove());\n          stickies.forEach((el) => newMainEl.appendChild(el));\n          this.outgoingMainEl.replaceWith(newMainEl);\n          this.outgoingMainEl = null;\n          callback && callback(linkRef);\n          onDone();\n        });\n      }\n    });\n  }\n  /** @internal */\n  transitionRemoves(elements, view, callback) {\n    const removeAttr = this.binding("remove");\n    const silenceEvents = (e) => {\n      e.preventDefault();\n      e.stopImmediatePropagation();\n    };\n    elements.forEach((el) => {\n      for (const event of this.boundEventNames) {\n        el.addEventListener(event, silenceEvents, true);\n      }\n      const e = new CustomEvent("phx:exec", { detail: { sourceElement: el } });\n      js_default.exec(e, "remove", el.getAttribute(removeAttr), view, el);\n    });\n    this.requestDOMUpdate(() => {\n      elements.forEach((el) => {\n        for (const event of this.boundEventNames) {\n          el.removeEventListener(event, silenceEvents, true);\n        }\n      });\n      callback && callback();\n    });\n  }\n  /** @internal */\n  isPhxView(el) {\n    return el.getAttribute && el.getAttribute(PHX_SESSION) !== null;\n  }\n  /** @internal */\n  newRootView(el, flash, liveReferer) {\n    const view = new View(el, this, null, flash, liveReferer);\n    this.roots[view.id] = view;\n    return view;\n  }\n  /** @internal */\n  owner(childEl, callback) {\n    let view;\n    const viewEl = dom_default.closestViewEl(childEl);\n    if (viewEl) {\n      view = dom_default.private(viewEl, "view");\n    } else {\n      if (!childEl.isConnected) {\n        return null;\n      }\n      view = this.main;\n    }\n    return view && callback ? callback(view) : view;\n  }\n  /** @internal */\n  withinOwners(childEl, callback) {\n    this.owner(childEl, (view) => callback(view, childEl));\n  }\n  /** @internal */\n  getViewByEl(el) {\n    const rootId = el.getAttribute(PHX_ROOT_ID);\n    return maybe(\n      this.getRootById(rootId),\n      (root) => root.getDescendentByEl(el)\n    );\n  }\n  /** @internal */\n  getRootById(id) {\n    return this.roots[id];\n  }\n  /** @internal */\n  destroyAllViews() {\n    for (const id in this.roots) {\n      this.roots[id].destroy();\n      delete this.roots[id];\n    }\n    this.main = null;\n  }\n  /** @internal */\n  destroyViewByEl(el) {\n    const root = this.getRootById(el.getAttribute(PHX_ROOT_ID));\n    if (root && root.id === el.id) {\n      root.destroy();\n      delete this.roots[root.id];\n    } else if (root) {\n      root.destroyDescendent(el.id);\n    }\n  }\n  /** @internal */\n  getActiveElement() {\n    return document.activeElement;\n  }\n  /** @internal */\n  dropActiveElement(view) {\n    if (this.prevActive && view.ownsElement(this.prevActive)) {\n      this.prevActive = null;\n    }\n  }\n  /** @internal */\n  restorePreviouslyActiveFocus() {\n    if (this.prevActive && this.prevActive !== document.body && this.prevActive instanceof HTMLElement) {\n      this.prevActive.focus();\n    }\n  }\n  /** @internal */\n  blurActiveElement() {\n    this.prevActive = this.getActiveElement();\n    if (this.prevActive !== document.body && this.prevActive instanceof HTMLElement) {\n      this.prevActive.blur();\n    }\n  }\n  /** @internal */\n  bindTopLevelEvents({ dead } = {}) {\n    if (this.boundTopLevelEvents) {\n      return;\n    }\n    this.boundTopLevelEvents = true;\n    this.serverCloseRef = this.socket.onClose((event) => {\n      if (event && event.code === 1e3 && this.main) {\n        return this.reloadWithJitter(this.main);\n      }\n    });\n    document.body.addEventListener("click", function() {\n    });\n    window.addEventListener(\n      "pageshow",\n      (e) =>
1 {\n        if (e.persisted) {\n          this.getSocket().disconnect();\n          this.withPageLoading({ to: window.location.href, kind: "redirect" });\n          window.location.reload();\n        }\n      },\n      true\n    );\n    if (!dead) {\n      this.bindNav();\n    }\n    this.bindClicks();\n    if (!dead) {\n      this.bindForms();\n    }\n    this.bind(\n      { keyup: "keyup", keydown: "keydown" },\n      (e, type, view, targetEl, phxEvent, _phxTarget) => {\n        const matchKey = targetEl.getAttribute(this.binding(PHX_KEY));\n        const pressedKey = e.key && e.key.toLowerCase();\n        if (matchKey && matchKey.toLowerCase() !== pressedKey) {\n          return;\n        }\n        const data = { key: e.key, ...this.eventMeta(type, e, targetEl) };\n        js_default.exec(e, type, phxEvent, view, targetEl, ["push", { data }]);\n      }\n    );\n    this.bind(\n      { blur: "focusout", focus: "focusin" },\n      (e, type, view, targetEl, phxEvent, phxTarget) => {\n        if (!phxTarget) {\n          const data = { ...this.eventMeta(type, e, targetEl) };\n          js_default.exec(e, type, phxEvent, view, targetEl, ["push", { data }]);\n        }\n      }\n    );\n    this.bind(\n      { blur: "blur", focus: "focus" },\n      (e, type, view, targetEl, phxEvent, phxTarget) => {\n        if (phxTarget === "window") {\n          const data = this.eventMeta(type, e, targetEl);\n          js_default.exec(e, type, phxEvent, view, targetEl, ["push", { data }]);\n        }\n      }\n    );\n    this.on("dragover", (e) => e.preventDefault());\n    this.on("dragenter", (e) => {\n      let target = e.target && dom_default.elementFromTarget(e.target);\n      if (!target) {\n        return;\n      }\n      const dropzone = closestPhxBinding(target, this.binding(PHX_DROP_TARGET));\n      if (!dropzone || !(dropzone instanceof HTMLElement)) {\n        return;\n      }\n      if (eventContainsFiles(e)) {\n        this.js().addClass(dropzone, PHX_DROP_TARGET_ACTIVE_CLASS);\n      }\n    });\n    this.on("dragleave", (e) => {\n      let target = e.target && dom_default.elementFromTarget(e.target);\n      if (!target) {\n        return;\n      }\n      const dropzone = closestPhxBinding(target, this.binding(PHX_DROP_TARGET));\n      if (!dropzone || !(dropzone instanceof HTMLElement)) {\n        return;\n      }\n      const rect = dropzone.getBoundingClientRect();\n      if (e.clientX <= rect.left || e.clientX >= rect.right || e.clientY <= rect.top || e.clientY >= rect.bottom) {\n        this.js().removeClass(dropzone, PHX_DROP_TARGET_ACTIVE_CLASS);\n      }\n    });\n    this.on("drop", (e) => {\n      let target = e.target && dom_default.elementFromTarget(e.target);\n      if (!target) {\n        return;\n      }\n      e.preventDefault();\n      const dropzone = closestPhxBinding(target, this.binding(PHX_DROP_TARGET));\n      if (!dropzone || !(dropzone instanceof HTMLElement)) {\n        return;\n      }\n      this.js().removeClass(dropzone, PHX_DROP_TARGET_ACTIVE_CLASS);\n      if (!e.dataTransfer) {\n        return;\n      }\n      const dropTargetId = dropzone.getAttribute(this.binding(PHX_DROP_TARGET));\n      const dropTarget = dropTargetId && document.getElementById(dropTargetId);\n      const files = Array.from(e.dataTransfer.files || []);\n      if (!dropTarget || !(dropTarget instanceof HTMLInputElement) || dropTarget.disabled || files.length === 0 || !(dropTarget.files instanceof FileList)) {\n        return;\n      }\n      LiveUploader.trackFiles(dropTarget, files, e.dataTransfer);\n      dropTarget.dispatchEvent(new Event("input", { bubbles: true }));\n    });\n    this.on(PHX_TRACK_UPLOADS, (e) => {\n      const uploadTarget = e.target && dom_default.elementFromTarget(e.target);\n      if (!dom_default.isUploadInput(uploadTarget)) {\n        return;\n      }\n      const files = Array.from(e.detail.files || []).filter(\n        (f) => f instanceof File || f instanceof Blob\n      );\n      LiveUploader.trackFiles(uploadTarget, files);\n      uploadTarget.dispatchEvent(new Event("input", { bubbles: true }));\n    });\n  }\n  /** @internal */\n  eventMeta(eventName, e, targetEl) {\n    const callback = this.metadataCallbacks[eventName];\n    return callback ? callback(e, targetEl) : {};\n  }\n  /** @internal */\n  setPendingLink(href) {\n    this.linkRef++;\n    this.pendingLink = href;\n    this.resetReloadStatus();\n    return this.linkRef;\n  }\n  /**\n   * @internal\n   * anytime we are navigating or connecting, drop reload cookie in case\n   * we issue the cookie but the next request was interrupted and the server never dropped it\n   */\n  resetReloadStatus() {\n    browser_default.deleteCookie(PHX_RELOAD_STATUS);\n  }\n  /** @internal */\n  commitPendingLink(linkRef) {\n    if (this.linkRef !== linkRef) {\n      return false;\n    }\n    if (this.pendingLink !== null) {\n      this.href = this.pendingLink;\n      this.pendingLink = null;\n    }\n    return true;\n  }\n  /** @internal */\n  getHref() {\n    return this.href;\n  }
1\n  /** @internal */\n  hasPendingLink() {\n    return !!this.pendingLink;\n  }\n  /** @internal */\n  bind(events, callback) {\n    for (const event in events) {\n      const browserEventName = events[event];\n      this.on(browserEventName, (e) => {\n        const binding = this.binding(event);\n        const windowBinding = this.binding(`window-${event}`);\n        const targetPhxEvent = e.target instanceof Element && e.target.getAttribute(binding);\n        if (!(e.target instanceof Element)) {\n          return;\n        }\n        if (targetPhxEvent) {\n          this.debounce(e.target, e, browserEventName, () => {\n            this.withinOwners(e.target, (view) => {\n              callback(\n                e,\n                event,\n                view,\n                e.target,\n                targetPhxEvent,\n                null\n              );\n            });\n          });\n        } else {\n          dom_default.all(document, `[${windowBinding}]`, (el) => {\n            const phxEvent = el.getAttribute(windowBinding);\n            this.debounce(el, e, browserEventName, () => {\n              this.withinOwners(el, (view) => {\n                callback(\n                  e,\n                  event,\n                  view,\n                  el,\n                  phxEvent,\n                  "window"\n                );\n              });\n            });\n          });\n        }\n      });\n    }\n  }\n  /** @internal */\n  bindClicks() {\n    this.on("mousedown", (e) => this.clickStartedAtTarget = e.target);\n    this.bindClick();\n  }\n  /** @internal */\n  bindClick() {\n    const click = this.binding("click");\n    window.addEventListener(\n      "click",\n      (e) => {\n        let target = e.target && dom_default.elementFromTarget(e.target);\n        if (!target) {\n          return;\n        }\n        if (e.detail === 0)\n          this.clickStartedAtTarget = target;\n        const clickStartedAtTarget = this.clickStartedAtTarget || target;\n        target = closestPhxBinding(target, click);\n        this.dispatchClickAway(e, clickStartedAtTarget);\n        this.clickStartedAtTarget = null;\n        if (!target) {\n          return;\n        }\n        const phxEvent = target.getAttribute(click);\n        if (!phxEvent) {\n          if (dom_default.isNewPageClick(e, window.location)) {\n            this.unload();\n          }\n          return;\n        }\n        if (target.getAttribute("href") === "#") {\n          e.preventDefault();\n        }\n        if (target.hasAttribute(PHX_REF_SRC)) {\n          return;\n        }\n        this.debounce(target, e, "click", () => {\n          this.withinOwners(target, (view) => {\n            js_default.exec(e, "click", phxEvent, view, target, [\n              "push",\n              { data: this.eventMeta("click", e, target) }\n            ]);\n          });\n        });\n      },\n      false\n    );\n  }\n  /** @internal */\n  dispatchClickAway(e, clickStartedAt) {\n    const phxClickAway = this.binding("click-away");\n    const portal = clickStartedAt.closest(`[${PHX_TELEPORTED_SRC}]`);\n    const portalStartedAt = portal && dom_default.byId(portal.getAttribute(PHX_TELEPORTED_SRC));\n    dom_default.all(document, `[${phxClickAway}]`, (el) => {\n      let startedAt = clickStartedAt;\n      if (portal && !portal.contains(el)) {\n        startedAt = portalStartedAt;\n      }\n      if (!(el.isSameNode(startedAt) || el.contains(startedAt) || // When clicking a link with custom method,\n      // phoenix_html triggers a click on a submit button\n      // of a hidden form appended to the body. For such cases\n      // where the clicked target is hidden, we skip click-away.\n      //\n      // Also, when we have a portal, we don\'t want to check the visibility\n      // of the portal source, as it\'s a <template> that is always not visible.\n      // Instead, check the visibility of the original click target.\n      !js_default.isVisible(clickStartedAt))) {\n        this.withinOwners(el, (view) => {\n          const phxEvent = el.getAttribute(phxClickAway);\n          if (js_default.isVisible(el) && js_default.isInViewport(el)) {\
1n            js_default.exec(e, "click", phxEvent, view, el, [\n              "push",\n              { data: this.eventMeta("click", e, e.target) }\n            ]);\n          }\n        });\n      }\n    });\n  }\n  /** @internal */\n  bindNav() {\n    if (!browser_default.canPushState()) {\n      return;\n    }\n    if (history.scrollRestoration) {\n      history.scrollRestoration = "manual";\n    }\n    let scrollTimer = null;\n    window.addEventListener("scroll", (_e) => {\n      scrollTimer != null && clearTimeout(scrollTimer);\n      scrollTimer = setTimeout(() => {\n        browser_default.updateCurrentState(\n          (state) => Object.assign(state, { scroll: window.scrollY })\n        );\n      }, 100);\n    });\n    window.addEventListener(\n      "popstate",\n      (event) => {\n        if (!this.registerNewLocation(window.location)) {\n          return;\n        }\n        const { type, backType, id, scroll, position } = event.state || {};\n        const href = window.location.href;\n        const isForward = position > this.currentHistoryPosition;\n        const navType = isForward ? type : backType || type;\n        this.currentHistoryPosition = position || 0;\n        this.sessionStorage.setItem(\n          PHX_LV_HISTORY_POSITION,\n          this.currentHistoryPosition.toString()\n        );\n        dom_default.dispatchEvent(window, "phx:navigate", {\n          detail: {\n            href,\n            patch: navType === "patch",\n            pop: true,\n            direction: isForward ? "forward" : "backward"\n          }\n        });\n        this.requestDOMUpdate(() => {\n          const callback = () => {\n            this.maybeScroll(scroll);\n          };\n          if (this.main && this.main.isConnected() && navType === "patch" && id === this.main.id) {\n            this.main.pushLinkPatch(event, href, null, callback);\n          } else {\n            this.replaceMain(href, null, callback);\n          }\n        });\n      },\n      false\n    );\n    window.addEventListener(\n      "click",\n      (e) => {\n        let el = e.target && dom_default.elementFromTarget(e.target);\n        if (!el) {\n          return;\n        }\n        const target = closestPhxBinding(\n          el,\n          PHX_LIVE_LINK\n        );\n        const type = target && target.getAttribute(PHX_LIVE_LINK);\n        if (!type || !this.isConnected() || !this.main || dom_default.wantsNewTab(e)) {\n          return;\n        }\n        const href = target.href instanceof SVGAnimatedString ? target.href.baseVal : target.href;\n        const linkState = target.getAttribute(PHX_LINK_STATE);\n        if (linkState !== "replace" && linkState !== "push") {\n          throw new Error(\n            `expected ${PHX_LINK_STATE} to be "replace" or "push", got: ${linkState}`\n          );\n        }\n        e.preventDefault();\n        e.stopImmediatePropagation();\n        if (this.pendingLink === href) {\n          return;\n        }\n        this.requestDOMUpdate(() => {\n          if (type === "patch") {\n            this.pushHistoryPatch(e, href, linkState, target);\n          } else if (type === "redirect") {\n            this.historyRedirect(e, href, linkState, null, target);\n          } else {\n            throw new Error(\n              `expected ${PHX_LIVE_LINK} to be "patch" or "redirect", got: ${type}`\n            );\n          }\n          const phxClick = target.getAttribute(this.binding("click"));\n          if (phxClick) {\n            this.requestDOMUpdate(() => this.execJS(target, phxClick, "click"));\n          }\n        });\n      },\n      false\n    );\n  }\n  /** @internal */\n  maybeScroll(scroll) {\n    if (typeof scroll === "number") {\n      requestAnimationFrame(() => {\n        window.scrollTo(0, scroll);\n      });\n    }\n  }\n  /** @internal */\n  dispatchEvent(event, payload = {}) {\n    dom_default.dispatchEvent(window, `phx:${event}`, { detail: payload });\n  }\n  /** @internal */\n  dispatchEvents(events) {\n    events.forEach(([event, payload]) => this.dispatchEvent(event, payload));\n  }\n  /** @internal */\n  withPageLoading(info, callback) {\n    dom_default.dispatchEvent(window, "phx:page-loading-start", { detail: info });\n    const done = () => dom_default.dispatchEvent(window, "phx:page-loading-stop", { detail: info });\n    return callback ? callback(done) : done;\n  }\n  /** @internal */\n  pushHistoryPatch(e, href, linkState, targetEl) {\n    if (!this.isConnected() || !(this.main && this.main.isMain())) {\n      return browser_default.redirect(href);\n    }\n    this.withPageLoading({ to: href, kind: "patch" }, (done) => {\n      this.main.pushLinkPatch(e, href, targetEl, (linkRef) => {\n        this.historyPatch(href, linkState, linkRef);\n        done();\n      });\n    });\n  }\n  /** @internal */\n  historyPatch(href, linkState, linkRef = this.setPendingLink(href)) {\n    if (!this.commitPendingLink(linkRef)) {\n      return;\n    }\n    this.currentHistoryPosition++;\n    this.sessionStorage.setItem(\n      PHX_LV_HISTORY_POSITION,\n      this.currentHistoryPosition.toString()\n    );\n    browser_default.updateCurrentState((state) => ({ ...state, backType: "patch" }));\n    browser_default.pushState(\n      linkState,\n      {\n        type: "patch",\n        id: this.main.id,\n        position: this.currentHistoryPosition\n      },\n      href\n    );\n    dom_default.dispatchEvent(window, "phx:navigate", {\n      detail: { patch: true, href, pop: false, direction: "forward" }\n    });\n    this.registerNewLocation(window.location);\n  }\n  /** @internal */\n  historyRedirect(e, href, linkState, flash, targetEl) {\n    const clickLoading = targetEl && e.isTrusted && e.type !== "popstate";\n    if (clickLoading) {\n      targetEl.classList.add("phx-click-loading");\n    }\n    if (!this.isConnected() || !(this.main && this.main.isMain())) {\n      return browser_default.redirect(href, flash);\n    }\n    if (/^\\/$|^\\/[^\\/]+.*$/.test(href)) {\n      const { protocol, host } = window.location;\n      href = `${protocol}//${host}${href}`;\n    }\n    const scroll = window.scrollY;\n    this.withPageLoading({ to: href, kind: "redirect" }, (done) => {\n      this.replaceMain(href, flash, (linkRef) => {\n        if (linkRef === this.linkRef) {\n          this.currentHistoryPosition++;\n          this.sessionStorage.setItem(\n            PHX_LV_HISTORY_POSITION,\n            this.currentHistoryPosition.toString()\n          );\n          browser_default.updateCurrentState((state) => ({\n            ...state,\n            backType: "redirect"\n          }));\n          browser_default.pushState(\n            linkState,\n            {\n              type: "redirect",\n              id: this.main.id,\n              scroll,\n              position: this.currentHistoryPosition\n            },\n            href\n          );\n          dom_default.dispatchEvent(window, "phx:navigate", {\n            detail: { href, patch: false, pop: false, direction: "forward" }\n          });\n          this.registerNewLocation(window.location);\n        }\n        if (clickLoading) {\n          targetEl.classList.remove("phx-click-loading");\n        }\n        done();\n      });\n    });\n  }\n  /** @internal */\n  registerNewLocation(newLocation) {\n    const { pathname, search } = this.currentLocation;\n    if (pathname + search === newLocation.pathname + newLocation.search) {\n      return false;\n    } else {\n      this.currentLocation = clone(newLocation);\n      return true;\n    }\n  }\n  /** @internal */\n  bindForms() {\n    let iterations = 0;\n    let externalFormSubmitted = false;\n    this.on("submit", (e) => {\n      if (!(e.target instanceof HTMLFormElement))\n        return;\n      const phxSubmit = e.target.getAttribute(this.binding("submit"));\n      const phxChange = e.target.getAttribute(this.binding("change"));\n      if (!externalFormSubmitted && phxChange && !phxSubmit) {\n        externalFormSubmitted = true;\n        e.preventDefault();\n        this.withinOwners(e.target, (view) => {\n          view.disableForm(e.target);\n          window.requestAnimationFrame(() =>
1 {\n            if (dom_default.isUnloadableFormSubmit(e)) {\n              this.unload();\n            }\n            e.target.submit();\n          });\n        });\n      }\n    });\n    this.on("submit", (e) => {\n      if (!(e.target instanceof HTMLFormElement))\n        return;\n      const phxEvent = e.target.getAttribute(this.binding("submit"));\n      if (!phxEvent) {\n        if (dom_default.isUnloadableFormSubmit(e)) {\n          this.unload();\n        }\n        return;\n      }\n      e.preventDefault();\n      e.target.disabled = true;\n      this.withinOwners(e.target, (view) => {\n        js_default.exec(e, "submit", phxEvent, view, e.target, [\n          "push",\n          { submitter: e.submitter }\n        ]);\n      });\n    });\n    for (const type of ["change", "input"]) {\n      this.on(type, (e) => {\n        if (!dom_default.isFormAssociated(e.target)) {\n          return;\n        }\n        if (e instanceof CustomEvent && e.target.form === void 0) {\n          if (e.detail && e.detail.dispatcher) {\n            throw new Error(\n              `dispatching a custom ${type} event is only supported on input elements inside a form`\n            );\n          }\n          return;\n        }\n        const input = e.target;\n        const phxChange = this.binding("change");\n        if (this.blockPhxChangeWhileComposing && e instanceof InputEvent && e.isComposing) {\n          const key = `composition-listener-${type}`;\n          if (!dom_default.private(input, key)) {\n            dom_default.putPrivate(input, key, true);\n            input.addEventListener(\n              "compositionend",\n              () => {\n                input.dispatchEvent(new Event(type, { bubbles: true }));\n                dom_default.deletePrivate(input, key);\n              },\n              { once: true }\n            );\n          }\n          return;\n        }\n        const inputEvent = input.getAttribute(phxChange);\n        const formEvent = input.form && input.form.getAttribute(phxChange);\n        const phxEvent = inputEvent || formEvent;\n        if (!phxEvent) {\n          return;\n        }\n        if (input.type === "number" && input.validity && input.validity.badInput) {\n          return;\n        }\n        const dispatcher = inputEvent ? input : input.form;\n        const currentIterations = iterations;\n        iterations++;\n        const { at, type: lastType } = dom_default.private(input, "prev-iteration") || {};\n        if (at === currentIterations - 1 && type === "change" && lastType === "input") {\n          return;\n        }\n        dom_default.putPrivate(input, "prev-iteration", {\n          at: currentIterations,\n          type\n        });\n        this.debounce(input, e, type, () => {\n          this.withinOwners(dispatcher, (view) => {\n            dom_default.putPrivate(input, PHX_HAS_FOCUSED, true);\n            js_default.exec(e, "change", phxEvent, view, input, [\n              "push",\n              { _target: input.name, dispatcher }\n            ]);\n          });\n        });\n      });\n    }\n    this.on("reset", (e) => {\n      const form = e.target;\n      dom_default.resetForm(form);\n      const input = Array.from(form.elements).find(\n        (el) => "type" in el && el.type === "reset"\n      );\n      if (input) {\n        window.requestAnimationFrame(() => {\n          input.dispatchEvent(\n            new Event("input", { bubbles: true, cancelable: false })\n          );\n        });\n      }\n    });\n  }\n  /** @internal */\n  debounce(el, event, eventType, callback) {\n    if (eventType === "blur" || eventType === "focusout") {\n      return callback();\n    }\n    const phxDebounce = this.binding(PHX_DEBOUNCE);\n    const phxThrottle = this.binding(PHX_THROTTLE);\n    const defaultDebounce = this.defaults.debounce.toString();\n    const defaultThrottle = this.defaults.throttle.toString();\n    this.withinOwners(el, (view) => {\n      const asyncFilter = () => !view.isDestroyed() && document.body.contains(el);\n      dom_default.debounce(\n        el,\n        event,\n        phxDebounce,\n        defaultDebounce,\n        phxThrottle,\n        defaultThrottle,\n        asyncFilter,\n        () => {\n          callback();\n        }\n      );\n    });\n  }\n  /** @internal */\n  silenceEvents(callback) {\n    this.silenced = true;\n    callback();\n    this.silenced = false;\n  }\n  /** @internal */\n  on(event, callback) {\n    this.boundEventNames.add(event);\n    window.addEventListener(event, (e) => {\n      if (!this.silenced) {\n        callback(e);\n      }\n    });\n  }\n  /** @internal */\n  jsQuerySelectorAll(sourceEl, query, defaultQuery) {\n    const all = this.domCallbacks.jsQuerySelectorAll;\n    return all ? all(sourceEl, query, defaultQuery) : defaultQuery();\n  }\n};\nvar TransitionSet = class {\n  constructor() {\n    this.transitions = /* @__PURE__ */ new Set();\n    this.promises = /* @__PURE__ */ new Set();\n    this.pendingOps = [];\n  }\n  reset() {\n    this.transitions.forEach((timer) => {\n      clearTimeout(timer);\n      this.transitions.delete(timer);\n    });\n    this.promises.clear();\n    this.flushPendingOps();\n  }\n  after(callback) {\n    if (this.size() === 0) {\n      callback();\n    } else {\n      this.pushPendingOp(callback);\n    }\n  }\n  addTransition(time, onStart, onDone) {\n    onStart();\n    const timer = setTimeout(() =>
1 {\n      this.transitions.delete(timer);\n      onDone();\n      this.flushPendingOps();\n    }, time);\n    this.transitions.add(timer);\n  }\n  addAsyncTransition(promise) {\n    this.promises.add(promise);\n    promise.then(() => {\n      this.promises.delete(promise);\n      this.flushPendingOps();\n    });\n  }\n  pushPendingOp(op) {\n    this.pendingOps.push(op);\n  }\n  size() {\n    return this.transitions.size + this.promises.size;\n  }\n  flushPendingOps() {\n    if (this.size() > 0) {\n      return;\n    }\n    const op = this.pendingOps.shift();\n    if (op) {\n      op();\n      this.flushPendingOps();\n    }\n  }\n};\n\n// js/phoenix_live_view/index.ts\nfunction createHook(el, callbacks) {\n  let existingHook = dom_default.getCustomElHook(el);\n  if (existingHook) {\n    return existingHook;\n  }\n  if (!el.hasAttribute("id")) {\n    logError(\n      "Elements passed to createHook need to have a unique id attribute",\n      el\n    );\n  }\n  let hook = new ViewHook(View.closestView(el), el, callbacks);\n  dom_default.putCustomElHook(el, hook);\n  return hook;\n}\nfunction getFileURLForUpload(input, uploadRef) {\n  return LiveUploader.getEntryDataURL(input, uploadRef);\n}\n\n//# sourceMappingURL=phoenix_live_view.esm.js.map\n\n;// CONCATENATED MODULE: ../deps/live_select/priv/static/live_select.min.js\nfunction o(e, t) {\n  let i;\n  return (...s) => {\n    clearTimeout(i), i = setTimeout(() => {\n      e.apply(this, s);\n    }, t);\n  };\n}\n/* harmony default export */ const live_select_min = ({\n  LiveSelect: {\n    textInput() {\n      return this.el.querySelector("input[type=text]");\n    },\n    debounceMsec() {\n      return parseInt(this.el.dataset.debounce);\n    },\n    updateMinLen() {\n      return parseInt(this.el.dataset.updateMinLen);\n    },\n    maybeStyleClearButtons() {\n      const e = this.el.querySelector("button.ls-clear-button");\n      e && (this.textInput().parentElement.style.position = "relative", this.textInput().parentElement.style.display = "flex", this.textInput().parentElement.style.alignItems = "center", e.style.minHeight = "20px", e.style.minWidth = "20px", e.style.position = "absolute", e.style.right = "5px", e.style.display = "block"), this.el.querySelectorAll("button.ls-clear-tag-button").forEach(t => {\n        t.style.minHeight = "20px", t.style.minWidth = "20px";\n      });\n    },\n    pushEventToParent(e, t) {\n      const i = this.el.dataset.phxTarget;\n      i ? this.pushEventTo(i, e, t) : this.pushEvent(e, t);\n    },\n    attachDomEventHandlers() {\n      this.textInput().onkeydown = t => {\n        t.code === "Enter" && t.preventDefault(), this.pushEventTo(this.el, "keydown", {\n          key: t.code\n        });\n      }, this.changeEvents = o((t, i, s) => {\n        this.pushEventTo(this.el, "change", {\n          text: s\n        }), this.pushEventToParent("live_select_change", {\n          id: this.el.id,\n          field: i,\n          text: s\n        });\n      }, this.debounceMsec()), this.textInput().oninput = t => {\n        const i = t.target.value.trim(),\n          s = this.el.dataset.field;\n        i.length >
1= this.updateMinLen() ? this.changeEvents(this.el.id, s, i) : this.pushEventTo(this.el, "options_clear", {});\n      };\n      const e = this.el.querySelector("ul");\n      e && (e.onmousedown = t => {\n        const i = t.target.closest("div[data-idx]");\n        i && (this.pushEventTo(this.el, "option_click", {\n          idx: i.dataset.idx\n        }), t.preventDefault());\n      }), this.el.querySelectorAll("button[data-idx]").forEach(t => {\n        t.onclick = i => {\n          this.pushEventTo(this.el, "option_remove", {\n            idx: t.dataset.idx\n          });\n        };\n      });\n    },\n    setInputValue(e) {\n      this.textInput().value = e;\n    },\n    inputEvent(e, t) {\n      const i = t === "single" ? "input.single-mode" : e.length === 0 ? "input[data-live-select-empty]" : "input[type=hidden]";\n      this.el.querySelector(i).dispatchEvent(new Event("input", {\n        bubbles: !0\n      }));\n    },\n    mounted() {\n      this.maybeStyleClearButtons(), this.handleEvent("select", ({\n        id: e,\n        selection: t,\n        mode: i,\n        current_text: s,\n        input_event: l,\n        parent_event: n\n      }) => {\n        this.el.id === e && (this.selection = t, s != null && this.setInputValue(s), l && this.inputEvent(t, i), n && this.pushEventToParent(n, {\n          id: e\n        }));\n      }), this.handleEvent("scroll_to_option", ({\n        id: e,\n        idx: t\n      }) => {\n        if (this.el.id === e) {\n          const i = this.el.querySelector(`div[data-idx="${t}"]`);\n          i && i.scrollIntoView({\n            block: "nearest",\n            behavior: "instant",\n            container: "nearest"\n          });\n        }\n      }), this.attachDomEventHandlers();\n    },\n    updated() {\n      this.maybeStyleClearButtons(), this.attachDomEventHandlers();\n    },\n    reconnected() {\n      this.selection && this.selection.length > 0 && this.pushEventTo(this.el, "selection_recovery", this.selection);\n    }\n  }\n});\n;// CONCATENATED MODULE: ./node_modules/alpinejs/dist/module.esm.js\n// packages/alpinejs/src/scheduler.js\nvar flushPending = false;\nvar flushing = false;\nvar queue = [];\nvar lastFlushedIndex = -1;\nfunction scheduler(callback) {\n  queueJob(callback);\n}\nfunction queueJob(job) {\n  if (!queue.includes(job))\n    queue.push(job);\n  queueFlush();\n}\nfunction dequeueJob(job) {\n  let index = queue.indexOf(job);\n  if (index !== -1 && index > lastFlushedIndex)\n    queue.splice(index, 1);\n}\nfunction queueFlush() {\n  if (!flushing && !flushPending) {\n    flushPending = true;\n    queueMicrotask(flushJobs);\n  }\n}\nfunction flushJobs() {\n  flushPending = false;\n  flushing = true;\n  for (let i = 0; i < queue.length; i++) {\n    queue[i]();\n    lastFlushedIndex = i;\n  }\n  queue.length = 0;\n  lastFlushedIndex = -1;\n  flushing = false;\n}\n\n// packages/alpinejs/src/reactivity.js\nvar reactive;\nvar effect;\nvar release;\nvar raw;\nvar shouldSchedule = true;\nfunction disableEffectScheduling(callback) {\n  shouldSchedule = false;\n  callback();\n  shouldSchedule = true;\n}\nfunction setReactivityEngine(engine) {\n  reactive = engine.reactive;\n  release = engine.release;\n  effect = (callback) => engine.effect(callback, {scheduler: (task) => {\n    if (shouldSchedule) {\n      scheduler(task);\n    } else {\n      task();\n    }\n  }});\n  raw = engine.raw;\n}\nfunction overrideEffect(override) {\n  effect = override;\n}\nfunction elementBoundEffect(el) {\n  let cleanup2 = () => {\n  };\n  let wrappedEffect = (callback) => {\n    let effectReference = effect(callback);\n    if (!el._x_effects) {\n      el._x_effects = new Set();\n      el._x_runEffects = () => {\n        el._x_effects.forEach((i) => i());\n      };\n    }\n    el._x_effects.add(effectReference);\n    cleanup2 = () => {\n      if (effectReference === void 0)\n        return;\n      el._x_effects.delete(effectReference);\n      release(effectReference);\n    };\n    return effectReference;\n  };\n  return [wrappedEffect, () => {\n    cleanup2();\n  }];\n}\n\n// packages/alpinejs/src/mutation.js\nvar onAttributeAddeds = [];\nvar onElRemoveds = [];\nvar onElAddeds = [];\nfunction onElAdded(callback) {\n  onElAddeds.push(callback);\n}\nfunction onElRemoved(el, callback) {\n  if (typeof callback === "function") {\n    if (!el._x_cleanups)\n      el._x_cleanups = [];\n    el._x_cleanups.push(callback);\n  } else {\n    callback = el;\n    onElRemoveds.push(callback);\n  }\n}\nfunction onAttributesAdded(callback) {\n  onAttributeAddeds.push(callback);\n}\nfunction onAttributeRemoved(el, name, callback) {\n  if (!el._x_attributeCleanups)\n    el._x_attributeCleanups = {};\n  if (!el._x_attributeCleanups[name])\n    el._x_attributeCleanups[name] = [];\n  el._x_attributeCleanups[name].push(callback);\n}\nfunction cleanupAttributes(el, names) {\n  if (!el._x_attributeCleanups)\n    return;
1\n  Object.entries(el._x_attributeCleanups).forEach(([name, value]) => {\n    if (names === void 0 || names.includes(name)) {\n      value.forEach((i) => i());\n      delete el._x_attributeCleanups[name];\n    }\n  });\n}\nvar observer = new MutationObserver(onMutate);\nvar currentlyObserving = false;\nfunction startObservingMutations() {\n  observer.observe(document, {subtree: true, childList: true, attributes: true, attributeOldValue: true});\n  currentlyObserving = true;\n}\nfunction stopObservingMutations() {\n  flushObserver();\n  observer.disconnect();\n  currentlyObserving = false;\n}\nvar recordQueue = [];\nvar willProcessRecordQueue = false;\nfunction flushObserver() {\n  recordQueue = recordQueue.concat(observer.takeRecords());\n  if (recordQueue.length && !willProcessRecordQueue) {\n    willProcessRecordQueue = true;\n    queueMicrotask(() => {\n      processRecordQueue();\n      willProcessRecordQueue = false;\n    });\n  }\n}\nfunction processRecordQueue() {\n  onMutate(recordQueue);\n  recordQueue.length = 0;\n}\nfunction mutateDom(callback) {\n  if (!currentlyObserving)\n    return callback();\n  stopObservingMutations();\n  let result = callback();\n  startObservingMutations();\n  return result;\n}\nvar isCollecting = false;\nvar deferredMutations = [];\nfunction deferMutations() {\n  isCollecting = true;\n}\nfunction flushAndStopDeferringMutations() {\n  isCollecting = false;\n  onMutate(deferredMutations);\n  deferredMutations = [];\n}\nfunction onMutate(mutations) {\n  if (isCollecting) {\n    deferredMutations = deferredMutations.concat(mutations);\n    return;\n  }\n  let addedNodes = [];\n  let removedNodes = [];\n  let addedAttributes = new Map();\n  let removedAttributes = new Map();\n  for (let i = 0; i < mutations.length; i++) {\n    if (mutations[i].target._x_ignoreMutationObserver)\n      continue;\n    if (mutations[i].type === "childList") {\n      mutations[i].addedNodes.forEach((node) => node.nodeType === 1 && addedNodes.push(node));\n      mutations[i].removedNodes.forEach((node) => node.nodeType === 1 && removedNodes.push(node));\n    }\n    if (mutations[i].type === "attributes") {\n      let el = mutations[i].target;\n      let name = mutations[i].attributeName;\n      let oldValue = mutations[i].oldValue;\n      let add2 = () => {\n        if (!addedAttributes.has(el))\n          addedAttributes.set(el, []);\n        addedAttributes.get(el).push({name, value: el.getAttribute(name)});\n      };\n      let remove = () => {\n        if (!removedAttributes.has(el))\n          removedAttributes.set(el, []);\n        removedAttributes.get(el).push(name);\n      };\n      if (el.hasAttribute(name) && oldValue === null) {\n        add2();\n      }
1 else if (el.hasAttribute(name)) {\n        remove();\n        add2();\n      } else {\n        remove();\n      }\n    }\n  }\n  removedAttributes.forEach((attrs, el) => {\n    cleanupAttributes(el, attrs);\n  });\n  addedAttributes.forEach((attrs, el) => {\n    onAttributeAddeds.forEach((i) => i(el, attrs));\n  });\n  for (let node of removedNodes) {\n    if (addedNodes.includes(node))\n      continue;\n    onElRemoveds.forEach((i) => i(node));\n    if (node._x_cleanups) {\n      while (node._x_cleanups.length)\n        node._x_cleanups.pop()();\n    }\n  }\n  addedNodes.forEach((node) => {\n    node._x_ignoreSelf = true;\n    node._x_ignore = true;\n  });\n  for (let node of addedNodes) {\n    if (removedNodes.includes(node))\n      continue;\n    if (!node.isConnected)\n      continue;\n    delete node._x_ignoreSelf;\n    delete node._x_ignore;\n    onElAddeds.forEach((i) => i(node));\n    node._x_ignore = true;\n    node._x_ignoreSelf = true;\n  }\n  addedNodes.forEach((node) => {\n    delete node._x_ignoreSelf;\n    delete node._x_ignore;\n  });\n  addedNodes = null;\n  removedNodes = null;\n  addedAttributes = null;\n  removedAttributes = null;\n}\n\n// packages/alpinejs/src/scope.js\nfunction scope(node) {\n  return mergeProxies(closestDataStack(node));\n}\nfunction addScopeToNode(node, data2, referenceNode) {\n  node._x_dataStack = [data2, ...closestDataStack(referenceNode || node)];\n  return () => {\n    node._x_dataStack = node._x_dataStack.filter((i) => i !== data2);\n  };\n}\nfunction closestDataStack(node) {\n  if (node._x_dataStack)\n    return node._x_dataStack;\n  if (typeof ShadowRoot === "function" && node instanceof ShadowRoot) {\n    return closestDataStack(node.host);\n  }\n  if (!node.parentNode) {\n    return [];\n  }\n  return closestDataStack(node.parentNode);\n}\nfunction mergeProxies(objects) {\n  let thisProxy = new Proxy({}, {\n    ownKeys: () => {\n      return Array.from(new Set(objects.flatMap((i) => Object.keys(i))));\n    },\n    has: (target, name) => {\n      return objects.some((obj) => obj.hasOwnProperty(name));\n    },\n    get: (target, name) => {\n      return (objects.find((obj) => {\n        if (obj.hasOwnProperty(name)) {\n          let descriptor = Object.getOwnPropertyDescriptor(obj, name);\n          if (descriptor.get && descriptor.get._x_alreadyBound || descriptor.set && descriptor.set._x_alreadyBound) {\n            return true;\n          }\n          if ((descriptor.get || descriptor.set) && descriptor.enumerable) {\n            let getter = descriptor.get;\n            let setter = descriptor.set;\n            let property = descriptor;\n            getter = getter && getter.bind(thisProxy);\n            setter = setter && setter.bind(thisProxy);\n            if (getter)\n              getter._x_alreadyBound = true;\n            if (setter)\n              setter._x_alreadyBound = true;\n            Object.defineProperty(obj, name, {\n              ...property,\n              get: getter,\n              set: setter\n            });\n          }\n          return true;\n        }\n        return false;\n      }) || {})[name];\n    },\n    set: (target, name, value) => {\n      let closestObjectWithKey = objects.find((obj) => obj.hasOwnProperty(name));\n      if (closestObjectWithKey) {\n        closestObjectWithKey[name] = value;\n      } else {\n        objects[objects.length - 1][name] = value;\n      }\n      return true;\n    }\n  });\n  return thisProxy;\n}\n\n// packages/alpinejs/src/interceptor.js\nfunction initInterceptors(data2) {\n  let isObject2 = (val) => typeof val === "object" && !Array.isArray(val) && val !== null;\n  let recurse = (obj, basePath = "") => {\n    Object.entries(Object.getOwnPropertyDescriptors(obj)).forEach(([key, {value, enumerable}]) => {\n      if (enumerable === false || value === void 0)\n        return;\n      let path = basePath === "" ? key : `${basePath}.${key}`;\n      if (typeof value === "object" && value !== null && value._x_interceptor) {\n        obj[key] = value.initialize(data2, path, key);\n      } else {\n        if (isObject2(value) && value !== obj && !(value instanceof Element)) {\n          recurse(value, path);\n        }\n      }\n    });\n  };
1\n  return recurse(data2);\n}\nfunction interceptor(callback, mutateObj = () => {\n}) {\n  let obj = {\n    initialValue: void 0,\n    _x_interceptor: true,\n    initialize(data2, path, key) {\n      return callback(this.initialValue, () => get(data2, path), (value) => set(data2, path, value), path, key);\n    }\n  };\n  mutateObj(obj);\n  return (initialValue) => {\n    if (typeof initialValue === "object" && initialValue !== null && initialValue._x_interceptor) {\n      let initialize = obj.initialize.bind(obj);\n      obj.initialize = (data2, path, key) => {\n        let innerValue = initialValue.initialize(data2, path, key);\n        obj.initialValue = innerValue;\n        return initialize(data2, path, key);\n      };\n    } else {\n      obj.initialValue = initialValue;\n    }\n    return obj;\n  };\n}\nfunction get(obj, path) {\n  return path.split(".").reduce((carry, segment) => carry[segment], obj);\n}\nfunction set(obj, path, value) {\n  if (typeof path === "string")\n    path = path.split(".");\n  if (path.length === 1)\n    obj[path[0]] = value;\n  else if (path.length === 0)\n    throw error;\n  else {\n    if (obj[path[0]])\n      return set(obj[path[0]], path.slice(1), value);\n    else {\n      obj[path[0]] = {};\n      return set(obj[path[0]], path.slice(1), value);\n    }\n  }\n}\n\n// packages/alpinejs/src/magics.js\nvar magics = {};\nfunction magic(name, callback) {\n  magics[name] = callback;\n}\nfunction injectMagics(obj, el) {\n  Object.entries(magics).forEach(([name, callback]) => {\n    let memoizedUtilities = null;\n    function getUtilities() {\n      if (memoizedUtilities) {\n        return memoizedUtilities;\n      } else {\n        let [utilities, cleanup2] = getElementBoundUtilities(el);\n        memoizedUtilities = {interceptor, ...utilities};\n        onElRemoved(el, cleanup2);\n        return memoizedUtilities;\n      }\n    }\n    Object.defineProperty(obj, `$${name}`, {\n      get() {\n        return callback(el, getUtilities());\n      },\n      enumerable: false\n    });\n  });\n  return obj;\n}\n\n// packages/alpinejs/src/utils/error.js\nfunction tryCatch(el, expression, callback, ...args) {\n  try {\n    return callback(...args);\n  } catch (e) {\n    handleError(e, el, expression);\n  }\n}\nfunction handleError(error2, el, expression = void 0) {\n  Object.assign(error2, {el, expression});\n  console.warn(`Alpine Expression Error: ${error2.message}\n\n${expression ? \'Expression: "\' + expression + \'"\\n\\n\' : ""}`, el);\n  setTimeout(() => {\n    throw error2;\n  }, 0);\n}\n\n// packages/alpinejs/src/evaluator.js\nvar shouldAutoEvaluateFunctions = true;\nfunction dontAutoEvaluateFunctions(callback) {\n  let cache = shouldAutoEvaluateFunctions;\n  shouldAutoEvaluateFunctions = false;\n  let result = callback();\n  shouldAutoEvaluateFunctions = cache;\n  return result;\n}\nfunction evaluate(el, expression, extras = {}) {\n  let result;\n  evaluateLater(el, expression)((value) => result = value, extras);\n  return result;\n}\nfunction evaluateLater(...args) {\n  return theEvaluatorFunction(...args);\n}\nvar theEvaluatorFunction = normalEvaluator;\nfunction setEvaluator(newEvaluator) {\n  theEvaluatorFunction = newEvaluator;\n}\nfunction normalEvaluator(el, expression) {\n  let overriddenMagics = {};\n  injectMagics(overriddenMagics, el);\n  let dataStack = [overriddenMagics, ...closestDataStack(el)];\n  let evaluator = typeof expression === "function" ? generateEvaluatorFromFunction(dataStack, expression) : generateEvaluatorFromString(dataStack, expression, el);\n  return tryCatch.bind(null, el, expression, evaluator);\n}\nfunction generateEvaluatorFromFunction(dataStack, func) {\n  return (receiver = () => {\n  }, {scope: scope2 = {}, params = []} = {}) => {\n    let result = func.apply(mergeProxies([scope2, ...dataStack]), params);\n    runIfTypeOfFunction(receiver, result);\n  };\n}\nvar evaluatorMemo = {};\nfunction generateFunctionFromString(expression, el) {\n  if (evaluatorMemo[expression]) {\n    return evaluatorMemo[expression];\n  }\n  let AsyncFunction = Object.getPrototypeOf(async function() {\
1n  }).constructor;\n  let rightSideSafeExpression = /^[\\n\\s]*if.*\\(.*\\)/.test(expression) || /^(let|const)\\s/.test(expression) ? `(async()=>{ ${expression} })()` : expression;\n  const safeAsyncFunction = () => {\n    try {\n      return new AsyncFunction(["__self", "scope"], `with (scope) { __self.result = ${rightSideSafeExpression} }; __self.finished = true; return __self.result;`);\n    } catch (error2) {\n      handleError(error2, el, expression);\n      return Promise.resolve();\n    }\n  };\n  let func = safeAsyncFunction();\n  evaluatorMemo[expression] = func;\n  return func;\n}\nfunction generateEvaluatorFromString(dataStack, expression, el) {\n  let func = generateFunctionFromString(expression, el);\n  return (receiver = () => {\n  }, {scope: scope2 = {}, params = []} = {}) => {\n    func.result = void 0;\n    func.finished = false;\n    let completeScope = mergeProxies([scope2, ...dataStack]);\n    if (typeof func === "function") {\n      let promise = func(func, completeScope).catch((error2) => handleError(error2, el, expression));\n      if (func.finished) {\n        runIfTypeOfFunction(receiver, func.result, completeScope, params, el);\n        func.result = void 0;\n      } else {\n        promise.then((result) => {\n          runIfTypeOfFunction(receiver, result, completeScope, params, el);\n        }).catch((error2) => handleError(error2, el, expression)).finally(() => func.result = void 0);\n      }\n    }\n  };\n}\nfunction runIfTypeOfFunction(receiver, value, scope2, params, el) {\n  if (shouldAutoEvaluateFunctions && typeof value === "function") {\n    let result = value.apply(scope2, params);\n    if (result instanceof Promise) {\n      result.then((i) => runIfTypeOfFunction(receiver, i, scope2, params)).catch((error2) => handleError(error2, el, value));\n    } else {\n      receiver(result);\n    }\n  } else if (typeof value === "object" && value instanceof Promise) {\n    value.then((i) => receiver(i));\n  } else {\n    receiver(value);\n  }\n}\n\n// packages/alpinejs/src/directives.js\nvar prefixAsString = "x-";\nfunction prefix(subject = "") {\n  return prefixAsString + subject;\n}\nfunction setPrefix(newPrefix) {\n  prefixAsString = newPrefix;\n}\nvar directiveHandlers = {};\nfunction directive(name, callback) {\n  directiveHandlers[name] = callback;\n  return {\n    before(directive2) {\n      if (!directiveHandlers[directive2]) {\n        console.warn("Cannot find directive `${directive}`. `${name}` will use the default order of execution");\n        return;\n      }\n      const pos = directiveOrder.indexOf(directive2);\n      directiveOrder.splice(pos >= 0 ? pos : directiveOrder.indexOf("DEFAULT"), 0, name);\n    }\n  };\n}\nfunction directives(el, attributes, originalAttributeOverride) {\n  attributes = Array.from(attributes);\n  if (el._x_virtualDirectives) {\n    let vAttributes = Object.entries(el._x_virtualDirectives).map(([name, value]) => ({name, value}));\n    let staticAttributes = attributesOnly(vAttributes);\n    vAttributes = vAttributes.map((attribute) => {\n      if (staticAttributes.find((attr) => attr.name === attribute.name)) {\n        return {\n          name: `x-bind:${attribute.name}`,\n          value: `"${attribute.value}"`\n        };\n      }\n      return attribute;\n    });\n    attributes = attributes.concat(vAttributes);\n  }\n  let transformedAttributeMap = {};\n  let directives2 = attributes.map(toTransformedAttributes((newName, oldName) => transformedAttributeMap[newName] = oldName)).filter(outNonAlpineAttributes).map(toParsedDirectives(transformedAttributeMap, originalAttributeOverride)).sort(byPriority);\n  return directives2.map((directive2) => {\n    return getDirectiveHandler(el, directive2);\n  });\n}\nfunction attributesOnly(attributes) {\n  return Array.from(attributes).map(toTransformedAttributes()).filter((attr) => !outNonAlpineAttributes(attr));\n}\nvar isDeferringHandlers = false;\nvar directiveHandlerStacks = new Map();\nvar currentHandlerStackKey = Symbol();\nfunction deferHandlingDirectives(callback) {\n  isDeferringHandlers = true;\n  let key = Symbol();\n  currentHandlerStackKey = key;\n  directiveHandlerStacks.set(key, []);\n  let flushHandlers = () => {\n    while (directiveHandlerStacks.get(key).length)\n      directiveHandlerStacks.get(key).shift()();\n    directiveHandlerStacks.delete(key);\n  };\n  let stopDeferring = () => {\n    isDeferringHandlers = false;\n    flushHandlers();\n  };\n  callback(flushHandlers);\n  stopDeferring();\n}\nfunction getElementBoundUtilities(el) {\n  let cleanups = [];\n  let cleanup2 = (callback) => cleanups.push(callback);\n  let [effect3, cleanupEffect] = elementBoundEffect(el);\n  cleanups.push(cleanupEffect);\n  let utilities = {\n    Alpine: alpine_default,\n    effect: effect3,\n    cleanup: cleanup2,\n    evaluateLater: evaluateLater.bind(evaluateLater, el),\n    evaluate: evaluate.bind(evaluate, el)\n  };\n  let doCleanup = () => cleanups.forEach((i) => i());\n  return [utilities, doCleanup];\n}\nfunction getDirectiveHandler(el, directive2) {\n  let noop = () => {\n  };\n  let handler4 = directiveHandlers[directive2.type] || noop;\n  let [utilities, cleanup2] = getElementBoundUtilities(el);\n  onAttributeRemoved(el, directive2.original, cleanup2);\n  let fullHandler = () => {\n    if (el._x_ignore || el._x_ignoreSelf)\n      return;\n    handler4.inline && handler4.inline(el, directive2, utilities);\n    handler4 = handler4.bind(handler4, el, directive2, utilities);\n    isDeferringHandlers ? directiveHandlerStacks.get(currentHandlerStackKey).push(handler4) : handler4();\n  };\n  fullHandler.runCleanups = cleanup2;\n  return fullHandler;\n}\nvar startingWith = (subject, replacement) => ({name, value}) =>
1 {\n  if (name.startsWith(subject))\n    name = name.replace(subject, replacement);\n  return {name, value};\n};\nvar into = (i) => i;\nfunction toTransformedAttributes(callback = () => {\n}) {\n  return ({name, value}) => {\n    let {name: newName, value: newValue} = attributeTransformers.reduce((carry, transform) => {\n      return transform(carry);\n    }, {name, value});\n    if (newName !== name)\n      callback(newName, name);\n    return {name: newName, value: newValue};\n  };\n}\nvar attributeTransformers = [];\nfunction mapAttributes(callback) {\n  attributeTransformers.push(callback);\n}\nfunction outNonAlpineAttributes({name}) {\n  return alpineAttributeRegex().test(name);\n}\nvar alpineAttributeRegex = () => new RegExp(`^${prefixAsString}([^:^.]+)\\\\b`);\nfunction toParsedDirectives(transformedAttributeMap, originalAttributeOverride) {\n  return ({name, value}) => {\n    let typeMatch = name.match(alpineAttributeRegex());\n    let valueMatch = name.match(/:([a-zA-Z0-9\\-:]+)/);\n    let modifiers = name.match(/\\.[^.\\]]+(?=[^\\]]*$)/g) || [];\n    let original = originalAttributeOverride || transformedAttributeMap[name] || name;\n    return {\n      type: typeMatch ? typeMatch[1] : null,\n      value: valueMatch ? valueMatch[1] : null,\n      modifiers: modifiers.map((i) => i.replace(".", "")),\n      expression: value,\n      original\n    };\n  };\n}\nvar DEFAULT = "DEFAULT";\nvar directiveOrder = [\n  "ignore",\n  "ref",\n  "data",\n  "id",\n  "bind",\n  "init",\n  "for",\n  "model",\n  "modelable",\n  "transition",\n  "show",\n  "if",\n  DEFAULT,\n  "teleport"\n];\nfunction byPriority(a, b) {\n  let typeA = directiveOrder.indexOf(a.type) === -1 ? DEFAULT : a.type;\n  let typeB = directiveOrder.indexOf(b.type) === -1 ? DEFAULT : b.type;\n  return directiveOrder.indexOf(typeA) - directiveOrder.indexOf(typeB);\n}\n\n// packages/alpinejs/src/utils/dispatch.js\nfunction dispatch(el, name, detail = {}) {\n  el.dispatchEvent(new CustomEvent(name, {\n    detail,\n    bubbles: true,\n    composed: true,\n    cancelable: true\n  }));\n}\n\n// packages/alpinejs/src/utils/walk.js\nfunction walk(el, callback) {\n  if (typeof ShadowRoot === "function" && el instanceof ShadowRoot) {\n    Array.from(el.children).forEach((el2) => walk(el2, callback));\n    return;\n  }\n  let skip = false;\n  callback(el, () => skip = true);\n  if (skip)\n    return;\n  let node = el.firstElementChild;\n  while (node) {\n    walk(node, callback, false);\n    node = node.nextElementSibling;\n  }\n}\n\n// packages/alpinejs/src/utils/warn.js\nfunction warn(message, ...args) {\n  console.warn(`Alpine Warning: ${message}`, ...args);\n}\n\n// packages/alpinejs/src/lifecycle.js\nvar started = false;\nfunction start() {\n  if (started)\n    warn("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems.");\n  started = true;\n  if (!document.body)\n    warn("Unable to initialize. Trying to load Alpine before `<body>` is available. Did you forget to add `defer` in Alpine\'s `<script>` tag?");\n  dispatch(document, "alpine:init");\n  dispatch(document, "alpine:initializing");\n  startObservingMutations();\n  onElAdded((el) => initTree(el, walk));\n  onElRemoved((el) => destroyTree(el));\n  onAttributesAdded((el, attrs) => {\n    directives(el, attrs).forEach((handle) => handle());\n  });\n  let outNestedComponents = (el) => !closestRoot(el.parentElement, true);\n  Array.from(document.querySelectorAll(allSelectors())).filter(outNestedComponents).forEach((el) => {\n    initTree(el);\n  });\n  dispatch(document, "alpine:initialized");\n}\nvar rootSelectorCallbacks = [];\nvar initSelectorCallbacks = [];\nfunction rootSelectors() {\n  return rootSelectorCallbacks.map((fn) => fn());\n}\nfunction allSelectors() {\n  return rootSelectorCallbacks.concat(initSelectorCallbacks).map((fn) => fn());\n}\nfunction addRootSelector(selectorCallback) {\n  rootSelectorCallbacks.push(selectorCallback);\n}\nfunction addInitSelector(selectorCallback) {\n  initSelectorCallbacks.push(selectorCallback);\n}\nfunction closestRoot(el, includeInitSelectors = false) {\n  return findClosest(el, (element) => {\n    const selectors = includeInitSelectors ? allSelectors() : rootSelectors();\n    if (selectors.some((selector) => element.matches(selector)))\n      return true;\n  });\n}\nfunction findClosest(el, callback) {\n  if (!el)\n    return;\n  if (callback(el))\n    return el;\n  if (el._x_teleportBack)\n    el = el._x_teleportBack;\n  if (!el.parentElement)\n    return;\n  return findClosest(el.parentElement, callback);\n}\nfunction isRoot(el) {\n  return rootSelectors().some((selector) => el.matches(selector));\n}\nvar initInterceptors2 = [];\nfunction interceptInit(callback) {\n  initInterceptors2.push(callback);\n}\nfunction initTree(el, walker = walk, intercept = () => {\n}) {\n  deferHandlingDirectives(() =>
1 {\n    walker(el, (el2, skip) => {\n      intercept(el2, skip);\n      initInterceptors2.forEach((i) => i(el2, skip));\n      directives(el2, el2.attributes).forEach((handle) => handle());\n      el2._x_ignore && skip();\n    });\n  });\n}\nfunction destroyTree(root) {\n  walk(root, (el) => cleanupAttributes(el));\n}\n\n// packages/alpinejs/src/nextTick.js\nvar tickStack = [];\nvar isHolding = false;\nfunction nextTick(callback = () => {\n}) {\n  queueMicrotask(() => {\n    isHolding || setTimeout(() => {\n      releaseNextTicks();\n    });\n  });\n  return new Promise((res) => {\n    tickStack.push(() => {\n      callback();\n      res();\n    });\n  });\n}\nfunction releaseNextTicks() {\n  isHolding = false;\n  while (tickStack.length)\n    tickStack.shift()();\n}\nfunction holdNextTicks() {\n  isHolding = true;\n}\n\n// packages/alpinejs/src/utils/classes.js\nfunction setClasses(el, value) {\n  if (Array.isArray(value)) {\n    return setClassesFromString(el, value.join(" "));\n  } else if (typeof value === "object" && value !== null) {\n    return setClassesFromObject(el, value);\n  } else if (typeof value === "function") {\n    return setClasses(el, value());\n  }\n  return setClassesFromString(el, value);\n}\nfunction setClassesFromString(el, classString) {\n  let split = (classString2) => classString2.split(" ").filter(Boolean);\n  let missingClasses = (classString2) => classString2.split(" ").filter((i) => !el.classList.contains(i)).filter(Boolean);\n  let addClassesAndReturnUndo = (classes) => {\n    el.classList.add(...classes);\n    return () => {\n      el.classList.remove(...classes);\n    };\n  };\n  classString = classString === true ? classString = "" : classString || "";\n  return addClassesAndReturnUndo(missingClasses(classString));\n}\nfunction setClassesFromObject(el, classObject) {\n  let split = (classString) => classString.split(" ").filter(Boolean);\n  let forAdd = Object.entries(classObject).flatMap(([classString, bool]) =>
1 bool ? split(classString) : false).filter(Boolean);\n  let forRemove = Object.entries(classObject).flatMap(([classString, bool]) => !bool ? split(classString) : false).filter(Boolean);\n  let added = [];\n  let removed = [];\n  forRemove.forEach((i) => {\n    if (el.classList.contains(i)) {\n      el.classList.remove(i);\n      removed.push(i);\n    }\n  });\n  forAdd.forEach((i) => {\n    if (!el.classList.contains(i)) {\n      el.classList.add(i);\n      added.push(i);\n    }\n  });\n  return () => {\n    removed.forEach((i) => el.classList.add(i));\n    added.forEach((i) => el.classList.remove(i));\n  };\n}\n\n// packages/alpinejs/src/utils/styles.js\nfunction setStyles(el, value) {\n  if (typeof value === "object" && value !== null) {\n    return setStylesFromObject(el, value);\n  }\n  return setStylesFromString(el, value);\n}\nfunction setStylesFromObject(el, value) {\n  let previousStyles = {};\n  Object.entries(value).forEach(([key, value2]) => {\n    previousStyles[key] = el.style[key];\n    if (!key.startsWith("--")) {\n      key = kebabCase(key);\n    }\n    el.style.setProperty(key, value2);\n  });\n  setTimeout(() => {\n    if (el.style.length === 0) {\n      el.removeAttribute("style");\n    }\n  });\n  return () => {\n    setStyles(el, previousStyles);\n  };\n}\nfunction setStylesFromString(el, value) {\n  let cache = el.getAttribute("style", value);\n  el.setAttribute("style", value);\n  return () => {\n    el.setAttribute("style", cache || "");\n  };\n}\nfunction kebabCase(subject) {\n  return subject.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();\n}\n\n// packages/alpinejs/src/utils/once.js\nfunction once(callback, fallback = () => {\n}) {\n  let called = false;\n  return function() {\n    if (!called) {\n      called = true;\n      callback.apply(this, arguments);\n    } else {\n      fallback.apply(this, arguments);\n    }\n  };\n}\n\n// packages/alpinejs/src/directives/x-transition.js\ndirective("transition", (el, {value, modifiers, expression}, {evaluate: evaluate2}) => {\n  if (typeof expression === "function")\n    expression = evaluate2(expression);\n  if (expression === false)\n    return;\n  if (!expression || typeof expression === "boolean") {\n    registerTransitionsFromHelper(el, modifiers, value);\n  } else {\n    registerTransitionsFromClassString(el, expression, value);\n  }\n});\nfunction registerTransitionsFromClassString(el, classString, stage) {\n  registerTransitionObject(el, setClasses, "");\n  let directiveStorageMap = {\n    enter: (classes) => {\n      el._x_transition.enter.during = classes;\n    },\n    "enter-start": (classes) => {\n      el._x_transition.enter.start = classes;\n    },\n    "enter-end": (classes) => {\n      el._x_transition.enter.end = classes;\n    },\n    leave: (classes) => {\n      el._x_transition.leave.during = classes;\n    },\n    "leave-start": (classes) => {\n      el._x_transition.leave.start = classes;\n    },\n    "leave-end": (classes) => {\n      el._x_transition.leave.end = classes;\n    }\n  };\n  directiveStorageMap[stage](classString);\n}\nfunction registerTransitionsFromHelper(el, modifiers, stage) {\n  registerTransitionObject(el, setStyles);\n  let doesntSpecify = !modifiers.includes("in") && !modifiers.includes("out") && !stage;\n  let transitioningIn = doesntSpecify || modifiers.includes("in") || ["enter"].includes(stage);\n  let transitioningOut = doesntSpecify || modifiers.includes("out") || ["leave"].includes(stage);\n  if (modifiers.includes("in") && !doesntSpecify) {\n    modifiers = modifiers.filter((i, index) => index < modifiers.indexOf("out"));\n  }\n  if (modifiers.includes("out") && !doesntSpecify) {\n    modifiers = modifiers.filter((i, index) => index > modifiers.indexOf("out"));\n  }\n  let wantsAll = !modifiers.includes("opacity") && !modifiers.includes("scale");\n  let wantsOpacity = wantsAll || modifiers.includes("opacity");\n  let wantsScale = wantsAll || modifiers.includes("scale");\n  let opacityValue = wantsOpacity ? 0 : 1;\n  let scaleValue = wantsScale ? modifierValue(modifiers, "scale", 95) / 100 : 1;\n  let delay = modifierValue(modifiers, "delay", 0) / 1e3;\n  let origin = modifierValue(modifiers, "origin", "center");\n  let property = "opacity, transform";\n  let durationIn = modifierValue(modifiers, "duration", 150) / 1e3;\n  let durationOut = modifierValue(modifiers, "duration", 75) / 1e3;\n  let easing = `cubic-bezier(0.4, 0.0, 0.2, 1)`;\n  if (transitioningIn) {\n    el._x_transition.enter.during = {\n      transformOrigin: origin,\n      transitionDelay: `${delay}s`,\n      transitionProperty: property,\n      transitionDuration: `${durationIn}s`,\n      transitionTimingFunction: easing\n    };
1\n    el._x_transition.enter.start = {\n      opacity: opacityValue,\n      transform: `scale(${scaleValue})`\n    };\n    el._x_transition.enter.end = {\n      opacity: 1,\n      transform: `scale(1)`\n    };\n  }\n  if (transitioningOut) {\n    el._x_transition.leave.during = {\n      transformOrigin: origin,\n      transitionDelay: `${delay}s`,\n      transitionProperty: property,\n      transitionDuration: `${durationOut}s`,\n      transitionTimingFunction: easing\n    };\n    el._x_transition.leave.start = {\n      opacity: 1,\n      transform: `scale(1)`\n    };\n    el._x_transition.leave.end = {\n      opacity: opacityValue,\n      transform: `scale(${scaleValue})`\n    };\n  }\n}\nfunction registerTransitionObject(el, setFunction, defaultValue = {}) {\n  if (!el._x_transition)\n    el._x_transition = {\n      enter: {during: defaultValue, start: defaultValue, end: defaultValue},\n      leave: {during: defaultValue, start: defaultValue, end: defaultValue},\n      in(before = () => {\n      }, after = () => {\n      }) {\n        transition(el, setFunction, {\n          during: this.enter.during,\n          start: this.enter.start,\n          end: this.enter.end\n        }, before, after);\n      },\n      out(before = () => {\n      }, after = () => {\n      }) {\n        transition(el, setFunction, {\n          during: this.leave.during,\n          start: this.leave.start,\n          end: this.leave.end\n        }, before, after);\n      }\n    };\n}\nwindow.Element.prototype._x_toggleAndCascadeWithTransitions = function(el, value, show, hide) {\n  const nextTick2 = document.visibilityState === "visible" ? requestAnimationFrame : setTimeout;\n  let clickAwayCompatibleShow = () => nextTick2(show);\n  if (value) {\n    if (el._x_transition && (el._x_transition.enter || el._x_transition.leave)) {\n      el._x_transition.enter && (Object.entries(el._x_transition.enter.during).length || Object.entries(el._x_transition.enter.start).length || Object.entries(el._x_transition.enter.end).length) ? el._x_transition.in(show) : clickAwayCompatibleShow();\n    } else {\n      el._x_transition ? el._x_transition.in(show) : clickAwayCompatibleShow();\n    }\n    return;\n  }\n  el._x_hidePromise = el._x_transition ? new Promise((resolve, reject) => {\n    el._x_transition.out(() => {\n    }, () => resolve(hide));\n    el._x_transitioning.beforeCancel(() => reject({isFromCancelledTransition: true}));\n  }) : Promise.resolve(hide);\n  queueMicrotask(() => {\n    let closest = closestHide(el);\n    if (closest) {\n      if (!closest._x_hideChildren)\n        closest._x_hideChildren = [];\n      closest._x_hideChildren.push(el);\n    } else {\n      nextTick2(() =>
1 {\n        let hideAfterChildren = (el2) => {\n          let carry = Promise.all([\n            el2._x_hidePromise,\n            ...(el2._x_hideChildren || []).map(hideAfterChildren)\n          ]).then(([i]) => i());\n          delete el2._x_hidePromise;\n          delete el2._x_hideChildren;\n          return carry;\n        };\n        hideAfterChildren(el).catch((e) => {\n          if (!e.isFromCancelledTransition)\n            throw e;\n        });\n      });\n    }\n  });\n};\nfunction closestHide(el) {\n  let parent = el.parentNode;\n  if (!parent)\n    return;\n  return parent._x_hidePromise ? parent : closestHide(parent);\n}\nfunction transition(el, setFunction, {during, start: start2, end} = {}, before = () => {\n}, after = () => {\n}) {\n  if (el._x_transitioning)\n    el._x_transitioning.cancel();\n  if (Object.keys(during).length === 0 && Object.keys(start2).length === 0 && Object.keys(end).length === 0) {\n    before();\n    after();\n    return;\n  }\n  let undoStart, undoDuring, undoEnd;\n  performTransition(el, {\n    start() {\n      undoStart = setFunction(el, start2);\n    },\n    during() {\n      undoDuring = setFunction(el, during);\n    },\n    before,\n    end() {\n      undoStart();\n      undoEnd = setFunction(el, end);\n    },\n    after,\n    cleanup() {\n      undoDuring();\n      undoEnd();\n    }\n  });\n}\nfunction performTransition(el, stages) {\n  let interrupted, reachedBefore, reachedEnd;\n  let finish = once(() => {\n    mutateDom(() => {\n      interrupted = true;\n      if (!reachedBefore)\n        stages.before();\n      if (!reachedEnd) {\n        stages.end();\n        releaseNextTicks();\n      }\n      stages.after();\n      if (el.isConnected)\n        stages.cleanup();\n      delete el._x_transitioning;\n    });\n  });\n  el._x_transitioning = {\n    beforeCancels: [],\n    beforeCancel(callback) {\n      this.beforeCancels.push(callback);\n    },\n    cancel: once(function() {\n      while (this.beforeCancels.length) {\n        this.beforeCancels.shift()();\n      }\n      ;\n      finish();\n    }),\n    finish\n  };\n  mutateDom(() => {\n    stages.start();\n    stages.during();\n  });\n  holdNextTicks();\n  requestAnimationFrame(() => {\n    if (interrupted)\n      return;\n    let duration = Number(getComputedStyle(el).transitionDuration.replace(/,.*/, "").replace("s", "")) * 1e3;\n    let delay = Number(getComputedStyle(el).transitionDelay.replace(/,.*/, "").replace("s", "")) * 1e3;\n    if (duration === 0)\n      duration = Number(getComputedStyle(el).animationDuration.replace("s", "")) * 1e3;\n    mutateDom(() => {\n      stages.before();\n    });\n    reachedBefore = true;\n    requestAnimationFrame(() => {\n      if (interrupted)\n        return;\n      mutateDom(() => {\n        stages.end();\n      });\n      releaseNextTicks();\n      setTimeout(el._x_transitioning.finish, duration + delay);\n      reachedEnd = true;\n    });\n  });\n}\nfunction modifierValue(modifiers, key, fallback) {\n  if (modifiers.indexOf(key) === -1)\n    return fallback;\n  const rawValue = modifiers[modifiers.indexOf(key) + 1];\n  if (!rawValue)\n    return fallback;\n  if (key === "scale") {\n    if (isNaN(rawValue))\n      return fallback;\n  }\n  if (key === "duration" || key === "delay") {\n    let match = rawValue.match(/([0-9]+)ms/);\n    if (match)\n      return match[1];\n  }\n  if (key === "origin") {\n    if (["top", "right", "left", "center", "bottom"].includes(modifiers[modifiers.indexOf(key) + 2])) {\n      return [rawValue, modifiers[modifiers.indexOf(key) + 2]].join(" ");\n    }\n  }\n  return rawValue;\n}\n\n// packages/alpinejs/src/clone.js\nvar isCloning = false;\nfunction skipDuringClone(callback, fallback = () => {\n}) {\n  return (...args) => isCloning ? fallback(...args) : callback(...args);\n}\nfunction onlyDuringClone(callback) {\n  return (...args) => isCloning && callback(...args);\n}\nfunction module_esm_clone(oldEl, newEl) {\n  if (!newEl._x_dataStack)\n    newEl._x_dataStack = oldEl._x_dataStack;\n  isCloning = true;\n  dontRegisterReactiveSideEffects(() =>
1 {\n    cloneTree(newEl);\n  });\n  isCloning = false;\n}\nfunction cloneTree(el) {\n  let hasRunThroughFirstEl = false;\n  let shallowWalker = (el2, callback) => {\n    walk(el2, (el3, skip) => {\n      if (hasRunThroughFirstEl && isRoot(el3))\n        return skip();\n      hasRunThroughFirstEl = true;\n      callback(el3, skip);\n    });\n  };\n  initTree(el, shallowWalker);\n}\nfunction dontRegisterReactiveSideEffects(callback) {\n  let cache = effect;\n  overrideEffect((callback2, el) => {\n    let storedEffect = cache(callback2);\n    release(storedEffect);\n    return () => {\n    };\n  });\n  callback();\n  overrideEffect(cache);\n}\n\n// packages/alpinejs/src/utils/bind.js\nfunction bind(el, name, value, modifiers = []) {\n  if (!el._x_bindings)\n    el._x_bindings = reactive({});\n  el._x_bindings[name] = value;\n  name = modifiers.includes("camel") ? camelCase(name) : name;\n  switch (name) {\n    case "value":\n      bindInputValue(el, value);\n      break;\n    case "style":\n      bindStyles(el, value);\n      break;\n    case "class":\n      bindClasses(el, value);\n      break;\n    case "selected":\n    case "checked":\n      bindAttributeAndProperty(el, name, value);\n      break;\n    default:\n      bindAttribute(el, name, value);\n      break;\n  }\n}\nfunction bindInputValue(el, value) {\n  if (el.type === "radio") {\n    if (el.attributes.value === void 0) {\n      el.value = value;\n    }\n    if (window.fromModel) {\n      el.checked = checkedAttrLooseCompare(el.value, value);\n    }\n  } else if (el.type === "checkbox") {\n    if (Number.isInteger(value)) {\n      el.value = value;\n    } else if (!Number.isInteger(value) && !Array.isArray(value) && typeof value !== "boolean" && ![null, void 0].includes(value)) {\n      el.value = 
1String(value);\n    } else {\n      if (Array.isArray(value)) {\n        el.checked = value.some((val) => checkedAttrLooseCompare(val, el.value));\n      } else {\n        el.checked = !!value;\n      }\n    }\n  } else if (el.tagName === "SELECT") {\n    updateSelect(el, value);\n  } else {\n    if (el.value === value)\n      return;\n    el.value = value;\n  }\n}\nfunction bindClasses(el, value) {\n  if (el._x_undoAddedClasses)\n    el._x_undoAddedClasses();\n  el._x_undoAddedClasses = setClasses(el, value);\n}\nfunction bindStyles(el, value) {\n  if (el._x_undoAddedStyles)\n    el._x_undoAddedStyles();\n  el._x_undoAddedStyles = setStyles(el, value);\n}\nfunction bindAttributeAndProperty(el, name, value) {\n  bindAttribute(el, name, value);\n  setPropertyIfChanged(el, name, value);\n}\nfunction bindAttribute(el, name, value) {\n  if ([null, void 0, false].includes(value) && attributeShouldntBePreservedIfFalsy(name)) {\n    el.removeAttribute(name);\n  } else {\n    if (isBooleanAttr(name))\n      value = name;\n    setIfChanged(el, name, value);\n  }\n}\nfunction setIfChanged(el, attrName, value) {\n  if (el.getAttribute(attrName) != value) {\n    el.setAttribute(attrName, value);\n  }\n}\nfunction setPropertyIfChanged(el, propName, value) {\n  if (el[propName] !== value) {\n    el[propName] = value;\n  }\n}\nfunction updateSelect(el, value) {\n  const arrayWrappedValue = [].concat(value).map((value2) => {\n    return value2 + "";\n  });\n  Array.from(el.options).forEach((option) => {\n    option.selected = arrayWrappedValue.includes(option.value);\n  });\n}\nfunction camelCase(subject) {\n  return subject.toLowerCase().replace(/-(\\w)/g, (match, char) => char.toUpperCase());\n}\nfunction checkedAttrLooseCompare(valueA, valueB) {\n  return valueA == valueB;\n}\nfunction isBooleanAttr(attrName) {\n  const booleanAttributes = [\n    "disabled",\n    "checked",\n    "required",\n    "readonly",\n    "hidden",\n    "open",\n    "selected",\n    "autofocus",\n    "itemscope",\n    "multiple",\n    "novalidate",\n    "allowfullscreen",\n    "allowpaymentrequest",\n    "formnovalidate",\n    "autoplay",\n    "controls",\n    "loop",\n    "muted",\n    "playsinline",\n    "default",\n    "ismap",\n    "reversed",\n    "async",\n    "defer",\n    "nomodule"\n  ];\n  return booleanAttributes.includes(attrName);\n}\nfunction attributeShouldntBePreservedIfFalsy(name) {\n  return !["aria-pressed", "aria-checked", "aria-expanded", "aria-selected"].includes(name);\n}\nfunction getBinding(el, name, fallback) {\n  if (el._x_bindings && el._x_bindings[name] !== void 0)\n    return el._x_bindings[name];\n  return getAttributeBinding(el, name, fallback);\n}\nfunction extractProp(el, name, fallback, extract = true) {\n  if (el._x_bindings && el._x_bindings[name] !== void 0)\n    return el._x_bindings[name];\n  if (el._x_inlineBindings && el._x_inlineBindings[name] !== void 0) {\n    let binding = el._x_inlineBindings[name];\n    binding.extract = extract;\n    return dontAutoEvaluateFunctions(() => {\n      return evaluate(el, binding.expression);\n    });\n  }\n  return getAttributeBinding(el, name, fallback);\n}\nfunction getAttributeBinding(el, name, fallback) {\n  let attr = el.getAttribute(name);\n  if (attr === null)\n    return typeof fallback === "function" ? fallback() : fallback;\n  if (attr === "")\n    return true;\n  if (isBooleanAttr(name)) {\n    return !![name, "true"].includes(attr);\n  }\n  return attr;\n}\n\n// packages/alpinejs/src/utils/debounce.js\nfunction debounce(func, wait) {\n  var timeout;\n  return function() {\n    var context = this, args = arguments;\n    var later = function() {\n      timeout = null;\n      func.apply(context, args);\n    };\n    clearTimeout(timeout);\n    timeout = setTimeout(later, wait);\n  };\n}\n\n// packages/alpinejs/src/utils/throttle.js\nfunction throttle(func, limit) {\n  let inThrottle;\n  return function() {\n    let context = this, args = arguments;\n    if (!inThrottle) {\n      func.apply(context, args);\n      inThrottle = true;\n      setTimeout(() => inThrottle = false, limit);\n    }\n  };\n}\n\n// packages/alpinejs/src/plugin.js\nfunction module_esm_plugin(callback) {\n  let callbacks = Array.isArray(callback) ? callback : [callback];\n  callbacks.forEach((i) => i(alpine_default));\n}\n\n// packages/alpinejs/src/store.js\nvar stores = {};\nvar isReactive = false;\nfunction store(name, value) {\n  if (!isReactive) {\n    stores = reactive(stores);\n    isReactive = true;\n  }\n  if (value === void 0) {\n    return stores[name];\n  }\n  stores[name] = value;\n  if (typeof value === "object" && value !== null && value.hasOwnProperty("init") && typeof value.init === "function") {\n    stores[name].init();\n  }\n  initInterceptors(stores[name]);\n}\nfunction getStores() {\n  return stores;\n}\n\n// packages/alpinejs/src/binds.js\nvar binds = {};\nfunction bind2(name, bindings) {\n  let getBindings = typeof bindings !== "function" ? () => bindings : bindings;\n  if (name instanceof Element) {\n    applyBindingsObject(name, getBindings());\n  } else {\n    binds[name] = getBindings;\n  }\n}\nfunction injectBindingProviders(obj) {\n  Object.entries(binds).forEac
1h(([name, callback]) => {\n    Object.defineProperty(obj, name, {\n      get() {\n        return (...args) => {\n          return callback(...args);\n        };\n      }\n    });\n  });\n  return obj;\n}\nfunction applyBindingsObject(el, obj, original) {\n  let cleanupRunners = [];\n  while (cleanupRunners.length)\n    cleanupRunners.pop()();\n  let attributes = Object.entries(obj).map(([name, value]) => ({name, value}));\n  let staticAttributes = attributesOnly(attributes);\n  attributes = attributes.map((attribute) => {\n    if (staticAttributes.find((attr) => attr.name === attribute.name)) {\n      return {\n        name: `x-bind:${attribute.name}`,\n        value: `"${attribute.value}"`\n      };\n    }\n    return attribute;\n  });\n  directives(el, attributes, original).map((handle) => {\n    cleanupRunners.push(handle.runCleanups);\n    handle();\n  });\n}\n\n// packages/alpinejs/src/datas.js\nvar datas = {};\nfunction data(name, callback) {\n  datas[name] = callback;\n}\nfunction injectDataProviders(obj, context) {\n  Object.entries(datas).forEach(([name, callback]) => {\n    Object.defineProperty(obj, name, {\n      get() {\n        return (...args) => {\n          return callback.bind(context)(...args);\n        };\n      },\n      enumerable: false\n    });\n  });\n  return obj;\n}\n\n// packages/alpinejs/src/alpine.js\nvar Alpine = {\n  get reactive() {\n    return reactive;\n  },\n  get release() {\n    return release;\n  },\n  get effect() {\n    return effect;\n  },\n  get raw() {\n    return raw;\n  },\n  version: "3.12.3",\n  flushAndStopDeferringMutations,\n  dontAutoEvaluateFunctions,\n  disableEffectScheduling,\n  startObservingMutations,\n  stopObservingMutations,\n  setReactivityEngine,\n  closestDataStack,\n  skipDuringClone,\n  onlyDuringClone,\n  addRootSelector,\n  addInitSelector,\n  addScopeToNode,\n  deferMutations,\n  mapAttributes,\n  evaluateLater,\n  interceptInit,\n  setEvaluator,\n  mergeProxies,\n  extractProp,\n  findClosest,\n  closestRoot,\n  destroyTree,\n  interceptor,\n  transition,\n  setStyles,\n  mutateDom,\n  directive,\n  throttle,\n  debounce,\n  evaluate,\n  initTree,\n  nextTick,\n  prefixed: prefix,\n  prefix: setPrefix,\n  plugin: module_esm_plugin,\n  magic,\n  store,\n  start,\n  clone: module_esm_clone,\n  bound: getBinding,\n  $data: scope,\n  walk,\n  data,\n  bind: bind2\n};\nvar alpine_default = Alpine;\n\n// node_modules/@vue/shared/dist/shared.esm-bundler.js\nfunction makeMap(str, expectsLowerCase) {\n  const map = Object.create(null);\n  const list = str.split(",");\n  for (let i = 0; i < list.length; i++) {\n    map[list[i]] = true;\n  }\n  return expectsLowerCase ? (val) => !!map[val.toLowerCase()] : (val) => !!map[val];\n}\nvar PatchFlagNames = {\n  [1]: `TEXT`,\n  [2]: `CLASS`,\n  [4]: `STYLE`,\n  [8]: `PROPS`,\n  [16]: `FULL_PROPS`,\n  [32]: `HYDRATE_EVENTS`,\n  [64]: `STABLE_FRAGMENT`,\n  [128]: `KEYED_FRAGMENT`,\n  [256]: `UNKEYED_FRAGMENT`,\n  [512]: `NEED_PATCH`,\n  [1024]: `DYNAMIC_SLOTS`,\n  [2048]: `DEV_ROOT_FRAGMENT`,\n  [-1]: `HOISTED`,\n  [-2]: `BAIL`\n};\nvar slotFlagsText = {\n  [1]: "STABLE",\n  [2]: "DYNAMIC",\n  [3]: "FORWARDED"\n};\nvar specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;\nvar isBooleanAttr2 = /* @__PURE__ */ makeMap(specialBooleanAttrs + `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected`);\nvar EMPTY_OBJ =  true ? Object.freeze({}) : 0;\nvar EMPTY_ARR =  true ? Object.freeze([]) : 0;\nvar extend = Object.assign;\nvar module_esm_hasOwnProperty = Object.prototype.hasOwnProperty;\nvar hasOwn = (val, key) => module_esm_hasOwnProperty.call(val, key);\nvar isArray = Array.isArray;\nvar isMap = (val) => toTypeString(val) === "[object Map]";\nvar isString = (val) => typeof val === "string";\nvar isSymbol = (val) => typeof val === "symbol";\nvar module_esm_isObject = (val) => val !== null && typeof val === "object";\nvar objectToString = Object.prototype.toString;\nvar toTypeString = (value) => objectToString.call(value);\nvar toRawType = (value) => {\n  return toTypeString(value).slice(8, -1);\n};\nvar isIntegerKey = (key) =>
1 isString(key) && key !== "NaN" && key[0] !== "-" && "" + parseInt(key, 10) === key;\nvar cacheStringFunction = (fn) => {\n  const cache = Object.create(null);\n  return (str) => {\n    const hit = cache[str];\n    return hit || (cache[str] = fn(str));\n  };\n};\nvar camelizeRE = /-(\\w)/g;\nvar camelize = cacheStringFunction((str) => {\n  return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : "");\n});\nvar hyphenateRE = /\\B([A-Z])/g;\nvar hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, "-$1").toLowerCase());\nvar capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1));\nvar toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``);\nvar hasChanged = (value, oldValue) => value !== oldValue && (value === value || oldValue === oldValue);\n\n// node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js\nvar targetMap = new WeakMap();\nvar effectStack = [];\nvar activeEffect;\nvar ITERATE_KEY = Symbol( true ? "iterate" : 0);\nvar MAP_KEY_ITERATE_KEY = Symbol( true ? "Map key iterate" : 0);\nfunction isEffect(fn) {\n  return fn && fn._isEffect === true;\n}\nfunction effect2(fn, options = EMPTY_OBJ) {\n  if (isEffect(fn)) {\n    fn = fn.raw;\n  }\n  const effect3 = createReactiveEffect(fn, options);\n  if (!options.lazy) {\n    effect3();\n  }\n  return effect3;\n}\nfunction stop(effect3) {\n  if (effect3.active) {\n    cleanup(effect3);\n    if (effect3.options.onStop) {\n      effect3.options.onStop();\n    }\n    effect3.active = false;\n  }\n}\nvar uid = 0;\nfunction createReactiveEffect(fn, options) {\n  const effect3 = function reactiveEffect() {\n    if (!effect3.active) {\n      return fn();\n    }\n    if (!effectStack.includes(effect3)) {\n      cleanup(effect3);\n      try {\n        enableTracking();\n        effectStack.push(effect3);\n        activeEffect = effect3;\n        return fn();\n      } finally {\n        effectStack.pop();\n        resetTracking();\n        activeEffect = effectStack[effectStack.length - 1];\n      }\n    }\n  };\n  effect3.id = uid++;\n  effect3.allowRecurse = !!options.allowRecurse;\n  effect3._isEffect = true;\n  effect3.active = true;\n  effect3.raw = fn;\n  effect3.deps = [];\n  effect3.options = options;\n  return effect3;\n}\nfunction cleanup(effect3) {\n  const {deps} = effect3;\n  if (deps.length) {\n    for (let i = 0; i < deps.length; i++) {\n      deps[i].delete(effect3);\n    }\n    deps.length = 0;\n  }\n}\nvar shouldTrack = true;\nvar trackStack = [];\nfunction pauseTracking() {\n  trackStack.push(shouldTrack);\n  shouldTrack = false;\n}\nfunction enableTracking() {\n  trackStack.push(shouldTrack);\n  shouldTrack = true;\n}\nfunction resetTracking() {\n  const last = trackStack.pop();\n  shouldTrack = last === void 0 ? true : last;\n}\nfunction track(target, type, key) {\n  if (!shouldTrack || activeEffect === void 0) {\n    return;\n  }\n  let depsMap = targetMap.get(target);\n  if (!depsMap) {\n    targetMap.set(target, depsMap = new Map());\n  }\n  let dep = depsMap.get(key);\n  if (!dep) {\n    depsMap.set(key, dep = new Set());\n  }
1\n  if (!dep.has(activeEffect)) {\n    dep.add(activeEffect);\n    activeEffect.deps.push(dep);\n    if (activeEffect.options.onTrack) {\n      activeEffect.options.onTrack({\n        effect: activeEffect,\n        target,\n        type,\n        key\n      });\n    }\n  }\n}\nfunction trigger(target, type, key, newValue, oldValue, oldTarget) {\n  const depsMap = targetMap.get(target);\n  if (!depsMap) {\n    return;\n  }\n  const effects = new Set();\n  const add2 = (effectsToAdd) => {\n    if (effectsToAdd) {\n      effectsToAdd.forEach((effect3) => {\n        if (effect3 !== activeEffect || effect3.allowRecurse) {\n          effects.add(effect3);\n        }\n      });\n    }\n  };\n  if (type === "clear") {\n    depsMap.forEach(add2);\n  } else if (key === "length" && isArray(target)) {\n    depsMap.forEach((dep, key2) => {\n      if (key2 === "length" || key2 >= newValue) {\n        add2(dep);\n      }\n    });\n  } else {\n    if (key !== void 0) {\n      add2(depsMap.get(key));\n    }\n    switch (type) {\n      case "add":\n        if (!isArray(target)) {\n          add2(depsMap.get(ITERATE_KEY));\n          if (isMap(target)) {\n            add2(depsMap.get(MAP_KEY_ITERATE_KEY));\n          }\n        } else if (isIntegerKey(key)) {\n          add2(depsMap.get("length"));\n        }\n        break;\n      case "delete":\n        if (!isArray(target)) {\n          add2(depsMap.get(ITERATE_KEY));\n          if (isMap(target)) {\n            add2(depsMap.get(MAP_KEY_ITERATE_KEY));\n          }\n        }\n        break;\n      case "set":\n        if (isMap(target)) {\n          add2(depsMap.get(ITERATE_KEY));\n        }\n        break;\n    }\n  }\n  const run = (effect3) => {\n    if (effect3.options.onTrigger) {\n      effect3.options.onTrigger({\n        effect: effect3,\n        target,\n        key,\n        type,\n        newValue,\n        oldValue,\n        oldTarget\n      });\n    }\n    if (effect3.options.scheduler) {\n      effect3.options.scheduler(effect3);\n    } else {\n      effect3();\n    }\n  };\n  effects.forEach(run);\n}\nvar isNonTrackableKeys = /* @__PURE__ */ makeMap(`__proto__,__v_isRef,__isVue`);\nvar builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol).map((key) => Symbol[key]).filter(isSymbol));\nvar get2 = /* @__PURE__ */ createGetter();\nvar shallowGet = /* @__PURE__ */ createGetter(false, true);\nvar readonlyGet = /* @__PURE__ */ createGetter(true);\nvar shallowReadonlyGet = /* @__PURE__ */ createGetter(true, true);\nvar arrayInstrumentations = {};\n["includes", "indexOf", "lastIndexOf"].forEach((key) => {\n  const method = Array.prototype[key];\n  arrayInstrumentations[key] = function(...args) {\n    const arr = toRaw(this);\n    for (let i = 0, l = this.length; i < l; i++) {\n      track(arr, "get", i + "");\n    }\n    const res = method.apply(arr, args);\n    if (res === -1 || res === false) {\n      return method.apply(arr, args.map(toRaw));\n    } else {\n      return res;\n    }\n  };\n});\n["push", "pop", "shift", "unshift", "splice"].forEach((key) => {\n  const method = Array.prototype[key];\n  arrayInstrumentations[key] = function(...args) {\n    pauseTracking();\n    const res = method.apply(this, args);\n    resetTracking();\n    return res;\n  };\n});\nfunction createGetter(isReadonly = false, shallow = false) {\n  return function get3(target, key, receiver) {\n    if (key === "__v_isReactive") {\n      return !isReadonly;\n    } else if (key === "__v_isReadonly") {\n      return isReadonly;\n    } else if (key === "__v_raw" && receiver === (isReadonly ? shallow ? shallowReadonlyMap : readonlyMap : shallow ? shallowReactiveMap : reactiveMap).get(target)) {\n      return target;\n    }\n    const targetIsArray = isArray(target);\n    if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {\n      return Reflect.get(arrayInstrumentations, key, receiver);\n    }\n    const res = Reflect.get(target, key, receiver);\n    if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {\n      return res;\n    }\n    if (!isReadonly) {\n      track(target, "get", key);\n    }\n    if (shallow) {\n      return res;\n    }\n    if (isRef(res)) {\n      const shouldUnwrap = !targetIsArray || !isIntegerKey(key);\n      return shouldUnwrap ? res.value : res;\n    }
1\n    if (module_esm_isObject(res)) {\n      return isReadonly ? readonly(res) : reactive2(res);\n    }\n    return res;\n  };\n}\nvar set2 = /* @__PURE__ */ createSetter();\nvar shallowSet = /* @__PURE__ */ createSetter(true);\nfunction createSetter(shallow = false) {\n  return function set3(target, key, value, receiver) {\n    let oldValue = target[key];\n    if (!shallow) {\n      value = toRaw(value);\n      oldValue = toRaw(oldValue);\n      if (!isArray(target) && isRef(oldValue) && !isRef(value)) {\n        oldValue.value = value;\n        return true;\n      }\n    }\n    const hadKey = isArray(target) && isIntegerKey(key) ? Number(key) < target.length : hasOwn(target, key);\n    const result = Reflect.set(target, key, value, receiver);\n    if (target === toRaw(receiver)) {\n      if (!hadKey) {\n        trigger(target, "add", key, value);\n      } else if (hasChanged(value, oldValue)) {\n        trigger(target, "set", key, value, oldValue);\n      }\n    }\n    return result;\n  };\n}\nfunction deleteProperty(target, key) {\n  const hadKey = hasOwn(target, key);\n  const oldValue = target[key];\n  const result = Reflect.deleteProperty(target, key);\n  if (result && hadKey) {\n    trigger(target, "delete", key, void 0, oldValue);\n  }\n  return result;\n}\nfunction has(target, key) {\n  const result = Reflect.has(target, key);\n  if (!isSymbol(key) || !builtInSymbols.has(key)) {\n    track(target, "has", key);\n  }\n  return result;\n}\nfunction ownKeys(target) {\n  track(target, "iterate", isArray(target) ? "length" : ITERATE_KEY);\n  return Reflect.ownKeys(target);\n}\nvar mutableHandlers = {\n  get: get2,\n  set: set2,\n  deleteProperty,\n  has,\n  ownKeys\n};\nvar readonlyHandlers = {\n  get: readonlyGet,\n  set(target, key) {\n    if (true) {\n      console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);\n    }\n    return true;\n  },\n  deleteProperty(target, key) {\n    if (true) {\n      console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);\n    }\n    return true;\n  }\n};\nvar shallowReactiveHandlers = extend({}, mutableHandlers, {\n  get: shallowGet,\n  set: shallowSet\n});\nvar shallowReadonlyHandlers = extend({}, readonlyHandlers, {\n  get: shallowReadonlyGet\n});\nvar toReactive = (value) => module_esm_isObject(value) ? reactive2(value) : value;\nvar toReadonly = (value) => module_esm_isObject(value) ? readonly(value) : value;\nvar toShallow = (value) => value;\nvar getProto = (v) => Reflect.getPrototypeOf(v);\nfunction get$1(target, key, isReadonly = false, isShallow = false) {\n  target = target["__v_raw"];\n  const rawTarget = toRaw(target);\n  const rawKey = toRaw(key);\n  if (key !== rawKey) {\n    !isReadonly && track(rawTarget, "get", key);\n  }\n  !isReadonly && track(rawTarget, "get", rawKey);\n  const {has: has2} = getProto(rawTarget);\n  const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;\n  if (has2.call(rawTarget, key)) {\n    return wrap(target.get(key));\n  } else if (has2.call(rawTarget, rawKey)) {\n    return wrap(target.get(rawKey));\n  } else if (target !== rawTarget) {\n    target.get(key);\n  }\n}\nfunction has$1(key, isReadonly = false) {\n  const target = this["__v_raw"];\n  const rawTarget = toRaw(target);\n  const rawKey = toRaw(key);\n  if (key !== rawKey) {\n    !isReadonly && track(rawTarget, "has", key);\n  }\n  !isReadonly && track(rawTarget, "has", rawKey);\n  return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey);\n}\nfunction size(target, isReadonly = false) {\n  target = target["__v_raw"];\n  !isReadonly && track(toRaw(target), "iterate", ITERATE_KEY);\n  return Reflect.get(target, "size", target);\n}\nfunction add(value) {\n  value = toRaw(value);\n  const target = toRaw(this);\n  const proto = getProto(target);\n  const hadKey = proto.has.call(target, value);\n  if (!hadKey) {\n    target.add(value);\n    trigger(target, "add", value, value);\n  }\n  return this;\n}\nfunction set$1(key, value) {\n  value = toRaw(value);\n  const target = toRaw(this);\n  const {has: has2, get: get3} = getProto(target);\n  let hadKey = has2.call(target, key);\n  if (!hadKey) {\n    key = toRaw(key);\n    hadKey = has2.call(target, key);\n  } else if (true) {\n    checkIdentityKeys(target, has2, key);\n  }\n  const oldValue = get3.call(target, key);\n  target.set(key, value);\n  if (!hadKey) {\n    trigger(target, "add", key, value);\n  } else if (hasChanged(value, oldValue)) {\n    trigger(target, "set", key, value, oldValue);\n  }\n  return this;\n}\nfunction deleteEntry(key) {\n  const target = toRaw(this);\n  const {has: has2, get: get3} = getProto(target);\n  let hadKey = has2.call(target, key);\n  if (!hadKey) {\n    key = toRaw(key);\n    hadKey = has2.call(target, key);\n  } else if (true) {\n    checkIdentityKeys(target, has2, key);\n  }\n  const oldValue = get3 ? get3.call(target, key) : void 0;\n  const result = target.delete(key);\n  if (hadKey) {\n    trigger(target, "delete", key, void 0, oldValue);\n  }\n  return result;\n}\nfunction clear() {\n  const target = toRaw(this);\n  const hadItems = target.size !== 0;\n  const oldTarget =  true ? isMap(target) ? new Map(target) : new Set(target) : 0;\n  const result = target.clear();\n  if (hadItems) {\n    trigger(target, "clear", void 0, void 0, oldTarget);\n  }\n  return result;\n}\nfunction createForEach(isReadonly, isShallow) {\n  return function forEach(callback, thisArg) {\n    const observed = this;\n    const target = observed["__v_raw"];\n    const rawTarget = toRaw(target);\n    const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;\n    !isReadonly && track(rawTarget, "iterate", ITERATE_KEY);\n    return target.forEach((value, key) => {\n      return callback.call(thisArg, wrap(value), wrap(key), observed);\n    });\n  };\n}\nfunction createIterableMethod(method, isReadonly, isShallow) {\n  return function(...args) {\n    const target = this["__v_raw"];\n    const rawTarget = toRaw(target);\n    const targetIsMap = isMap(rawTarget);\n    const isPair = method === "entries" || method === Symbol.iterator && targetIsMap;\n    const isKeyOnly = method === "keys" && targetIsMap;\n    const innerIterator = target[method](...args);\n    const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;\n    !isReadonly && track(rawTarget, "iterate", isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);\n    return {\n      next() {\n        const {value, done} = innerIterator.next();\n        return done ? {value, done} : {\n          value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),\n          done\n        };\n      },\n      [Symbol.iterator]() {\n        return this;\n      }\n    };\n  };\n}\nfunction createReadonlyMethod(type) {\n  return function(...args) {\n    if (true) {\n      const 
1key = args[0] ? `on key "${args[0]}" ` : ``;\n      console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));\n    }\n    return type === "delete" ? false : this;\n  };\n}\nvar mutableInstrumentations = {\n  get(key) {\n    return get$1(this, key);\n  },\n  get size() {\n    return size(this);\n  },\n  has: has$1,\n  add,\n  set: set$1,\n  delete: deleteEntry,\n  clear,\n  forEach: createForEach(false, false)\n};\nvar shallowInstrumentations = {\n  get(key) {\n    return get$1(this, key, false, true);\n  },\n  get size() {\n    return size(this);\n  },\n  has: has$1,\n  add,\n  set: set$1,\n  delete: deleteEntry,\n  clear,\n  forEach: createForEach(false, true)\n};\nvar readonlyInstrumentations = {\n  get(key) {\n    return get$1(this, key, true);\n  },\n  get size() {\n    return size(this, true);\n  },\n  has(key) {\n    return has$1.call(this, key, true);\n  },\n  add: createReadonlyMethod("add"),\n  set: createReadonlyMethod("set"),\n  delete: createReadonlyMethod("delete"),\n  clear: createReadonlyMethod("clear"),\n  forEach: createForEach(true, false)\n};\nvar shallowReadonlyInstrumentations = {\n  get(key) {\n    return get$1(this, key, true, true);\n  },\n  get size() {\n    return size(this, true);\n  },\n  has(key) {\n    return has$1.call(this, key, true);\n  },\n  add: createReadonlyMethod("add"),\n  set: createReadonlyMethod("set"),\n  delete: createReadonlyMethod("delete"),\n  clear: createReadonlyMethod("clear"),\n  forEach: createForEach(true, true)\n};\nvar iteratorMethods = ["keys", "values", "entries", Symbol.iterator];\niteratorMethods.forEach((method) => {\n  mutableInstrumentations[method] = createIterableMethod(method, false, false);\n  readonlyInstrumentations[method] = createIterableMethod(method, true, false);\n  shallowInstrumentations[method] = createIterableMethod(method, false, true);\n  shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);\n});\nfunction createInstrumentationGetter(isReadonly, shallow) {\n  const instrumentations = shallow ? isReadonly ? shallowReadonlyInstrumentations : shallowInstrumentations : isReadonly ? readonlyInstrumentations : mutableInstrumentations;\n  return (target, key, receiver) => {\n    if (key === "__v_isReactive") {\n      return !isReadonly;\n    } else if (key === "__v_isReadonly") {\n      return isReadonly;\n    } else if (key === "__v_raw") {\n      return target;\n    }\n    return Reflect.get(hasOwn(instrumentations, key) && key in target ? instrumentations : target, key, receiver);\n  };\n}\nvar mutableCollectionHandlers = {\n  get: createInstrumentationGetter(false, false)\n};\nvar shallowCollectionHandlers = {\n  get: createInstrumentationGetter(false, true)\n};\nvar readonlyCollectionHandlers = {\n  get: createInstrumentationGetter(true, false)\n};\nvar shallowReadonlyCollectionHandlers = {\n  get: createInstrumentationGetter(true, true)\n};\nfunction checkIdentityKeys(target, has2, key) {\n  const rawKey = toRaw(key);\n  if (rawKey !== key && has2.call(target, rawKey)) {\n    const type = toRawType(target);\n    console.warn(`Reactive ${type} contains both the raw and reactive versions of the same object${type === `Map` ? ` as keys` : ``}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`);\n  }\n}\nvar reactiveMap = new WeakMap();\nvar shallowReactiveMap = new WeakMap();\nvar readonlyMap = new WeakMap();\nvar shallowReadonlyMap = new WeakMap();\nfunction targetTypeMap(rawType) {\n  switch (rawType) {\n    case "Object":\n    case "Array":\n      return 1;\n    case "Map":\n    case "Set":\n    case "WeakMap":\n    case "WeakSet":\n      return 2;\n    default:\n      return 0;\n  }\n}\nfunction getTargetType(value) {\n  return value["__v_skip"] || !Object.isExtensible(value) ? 0 : targetTypeMap(toRawType(value));\n}\nfunction reactive2(target) {\n  if (target && target["__v_isReadonly"]) {\n    return target;\n  }\n  return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);\n}\nfunction readonly(target) {\n  return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);\n}\nfunction createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {\n  if (!module_esm_isObject(target)) {\n    if (true) {\n      console.warn(`value cannot be made reactive: ${String(target)}`);\n    }\n    return target;\n  }\n  if (target["__v_raw"] && !(isReadonly && target["__v_isReactive"])) {\n    return target;\n  }\n  const existingProxy = proxyMap.get(target);\n  if (existingProxy) {\n    return existingProxy;\n  }\n  const targetType = getTargetType(target);\n  if (targetType === 0) {\n    return target;\n  }\n  const proxy = new Proxy(target, targetType === 2 ? collectionHandlers : baseHandlers);\n  proxyMap.set(target, proxy);\n  return proxy;\n}\nfunction toRaw(observed) {\n  return observed && toRaw(observed["__v_raw"]) || observed;\n}\nfunction isRef(r) {\n  return Boolean(r && r.__v_isRef === true);\n}\n\n// packages/alpinejs/src/magics/$nextTick.js\nmagic("nextTick", () => nextTick);\n\n// packages/alpinejs/src/magics/$dispatch.js\nmagic("dispatch", (el) => dispatch.bind(dispatch, el));\n\n// packages/alpinejs/src/magics/$watch.js\nmagic("watch", (el, {evaluateLater: evaluateLater2, effect: effect3}) => (key, callback) =>
1 {\n  let evaluate2 = evaluateLater2(key);\n  let firstTime = true;\n  let oldValue;\n  let effectReference = effect3(() => evaluate2((value) => {\n    JSON.stringify(value);\n    if (!firstTime) {\n      queueMicrotask(() => {\n        callback(value, oldValue);\n        oldValue = value;\n      });\n    } else {\n      oldValue = value;\n    }\n    firstTime = false;\n  }));\n  el._x_effects.delete(effectReference);\n});\n\n// packages/alpinejs/src/magics/$store.js\nmagic("store", getStores);\n\n// packages/alpinejs/src/magics/$data.js\nmagic("data", (el) => scope(el));\n\n// packages/alpinejs/src/magics/$root.js\nmagic("root", (el) => closestRoot(el));\n\n// packages/alpinejs/src/magics/$refs.js\nmagic("refs", (el) => {\n  if (el._x_refs_proxy)\n    return el._x_refs_proxy;\n  el._x_refs_proxy = mergeProxies(getArrayOfRefObject(el));\n  return el._x_refs_proxy;\n});\nfunction getArrayOfRefObject(el) {\n  let refObjects = [];\n  let currentEl = el;\n  while (currentEl) {\n    if (currentEl._x_refs)\n      refObjects.push(currentEl._x_refs);\n    currentEl = currentEl.parentNode;\n  }\n  return refObjects;\n}\n\n// packages/alpinejs/src/ids.js\nvar globalIdMemo = {};\nfunction findAndIncrementId(name) {\n  if (!globalIdMemo[name])\n    globalIdMemo[name] = 0;\n  return ++globalIdMemo[name];\n}\nfunction closestIdRoot(el, name) {\n  return findClosest(el, (element) => {\n    if (element._x_ids && element._x_ids[name])\n      return true;\n  });\n}\nfunction setIdRoot(el, name) {\n  if (!el._x_ids)\n    el._x_ids = {};\n  if (!el._x_ids[name])\n    el._x_ids[name] = findAndIncrementId(name);\n}\n\n// packages/alpinejs/src/magics/$id.js\nmagic("id", (el) => (name, key = null) => {\n  let root = closestIdRoot(el, name);\n  let id = root ? root._x_ids[name] : findAndIncrementId(name);\n  return key ? `${name}-${id}-${key}` : `${name}-${id}`;\n});\n\n// packages/alpinejs/src/magics/$el.js\nmagic("el", (el) => el);\n\n// packages/alpinejs/src/magics/index.js\nwarnMissingPluginMagic("Focus", "focus", "focus");\nwarnMissingPluginMagic("Persist", "persist", "persist");\nfunction warnMissingPluginMagic(name, magicName, slug) {\n  magic(magicName, (el) => warn(`You can\'t use [$${directiveName}] without first installing the "${name}" plugin here: https://alpinejs.dev/plugins/${slug}`, el));\n}\n\n// packages/alpinejs/src/entangle.js\nfunction entangle({get: outerGet, set: outerSet}, {get: innerGet, set: innerSet}) {\n  let firstRun = true;\n  let outerHash, innerHash, outerHashLatest, innerHashLatest;\n  let reference = effect(() => {\n    let outer, inner;\n    if (firstRun) {\n      outer = outerGet();\n      innerSet(outer);\n      inner = innerGet();\n      firstRun = false;\n    } else {\n      outer = outerGet();\n      inner = innerGet();\n      outerHashLatest = JSON.stringify(outer);\n      innerHashLatest = JSON.stringify(inner);\n      if (outerHashLatest !== outerHash) {\n        inner = innerGet();\n        innerSet(outer);\n        inner = outer;\n      } else {\n        outerSet(inner);\n        outer = inner;\n      }\n    }\n    outerHash = JSON.stringify(outer);\n    innerHash = JSON.stringify(inner);\n  });\n  return () => {\n    release(reference);\n  };\n}\n\n// packages/alpinejs/src/directives/x-modelable.js\ndirective("modelable", (el, {expression}, {effect: effect3, evaluateLater: evaluateLater2, cleanup: cleanup2}) => {\n  let func = evaluateLater2(expression);\n  let innerGet = () => {\n    let result;\n    func((i) => result = i);\n    return result;\n  };\n  let evaluateInnerSet = evaluateLater2(`${expression} = __placeholder`);\n  let innerSet = (val) => evaluateInnerSet(() => {\n  }, {scope: {__placeholder: val}});\n  let initialValue = innerGet();\n  innerSet(initialValue);\n  queueMicrotask(() => {\n    if (!el._x_model)\n      return;\n    el._x_removeModelListeners["default"]();\n    let outerGet = el._x_model.get;\n    let outerSet = el._x_model.set;\n    let releaseEntanglement = entangle({\n      get() {\n        return outerGet();\n      },\n      set(value) {\n        outerSet(value);\n      }\n    }, {\n      get() {\n        return innerGet();\n      },\n      set(value) {\n        innerSet(value);\n      }\n    });\n    cleanup2(releaseEntanglement);\n  });\n});\n\n// packages/alpinejs/src/directives/x-teleport.js\nvar teleportContainerDuringClone = document.createElement("div");\ndirective("teleport", (el, {modifiers, expression}, {cleanup: cleanup2}) =>
1 {\n  if (el.tagName.toLowerCase() !== "template")\n    warn("x-teleport can only be used on a <template> tag", el);\n  let target = skipDuringClone(() => {\n    return document.querySelector(expression);\n  }, () => {\n    return teleportContainerDuringClone;\n  })();\n  if (!target)\n    warn(`Cannot find x-teleport element for selector: "${expression}"`);\n  let clone2 = el.content.cloneNode(true).firstElementChild;\n  el._x_teleport = clone2;\n  clone2._x_teleportBack = el;\n  if (el._x_forwardEvents) {\n    el._x_forwardEvents.forEach((eventName) => {\n      clone2.addEventListener(eventName, (e) => {\n        e.stopPropagation();\n        el.dispatchEvent(new e.constructor(e.type, e));\n      });\n    });\n  }\n  addScopeToNode(clone2, {}, el);\n  mutateDom(() => {\n    if (modifiers.includes("prepend")) {\n      target.parentNode.insertBefore(clone2, target);\n    } else if (modifiers.includes("append")) {\n      target.parentNode.insertBefore(clone2, target.nextSibling);\n    } else {\n      target.appendChild(clone2);\n    }\n    initTree(clone2);\n    clone2._x_ignore = true;\n  });\n  cleanup2(() => clone2.remove());\n});\n\n// packages/alpinejs/src/directives/x-ignore.js\nvar handler = () => {\n};\nhandler.inline = (el, {modifiers}, {cleanup: cleanup2}) => {\n  modifiers.includes("self") ? el._x_ignoreSelf = true : el._x_ignore = true;\n  cleanup2(() =>
1 {\n    modifiers.includes("self") ? delete el._x_ignoreSelf : delete el._x_ignore;\n  });\n};\ndirective("ignore", handler);\n\n// packages/alpinejs/src/directives/x-effect.js\ndirective("effect", (el, {expression}, {effect: effect3}) => effect3(evaluateLater(el, expression)));\n\n// packages/alpinejs/src/utils/on.js\nfunction on(el, event, modifiers, callback) {\n  let listenerTarget = el;\n  let handler4 = (e) => callback(e);\n  let options = {};\n  let wrapHandler = (callback2, wrapper) => (e) => wrapper(callback2, e);\n  if (modifiers.includes("dot"))\n    event = dotSyntax(event);\n  if (modifiers.includes("camel"))\n    event = camelCase2(event);\n  if (modifiers.includes("passive"))\n    options.passive = true;\n  if (modifiers.includes("capture"))\n    options.capture = true;\n  if (modifiers.includes("window"))\n    listenerTarget = window;\n  if (modifiers.includes("document"))\n    listenerTarget = document;\n  if (modifiers.includes("debounce")) {\n    let nextModifier = modifiers[modifiers.indexOf("debounce") + 1] || "invalid-wait";\n    let wait = isNumeric(nextModifier.split("ms")[0]) ? Number(nextModifier.split("ms")[0]) : 250;\n    handler4 = debounce(handler4, wait);\n  }\n  if (modifiers.includes("throttle")) {\n    let nextModifier = modifiers[modifiers.indexOf("throttle") + 1] || "invalid-wait";\n    let wait = isNumeric(nextModifier.split("ms")[0]) ? Number(nextModifier.split("ms")[0]) : 250;\n    handler4 = throttle(handler4, wait);\n  }\n  if (modifiers.includes("prevent"))\n    handler4 = wrapHandler(handler4, (next, e) => {\n      e.preventDefault();\n      next(e);\n    });\n  if (modifiers.includes("stop"))\n    handler4 = wrapHandler(handler4, (next, e) => {\n      e.stopPropagation();\n      next(e);\n    });\n  if (modifiers.includes("self"))\n    handler4 = wrapHandler(handler4, (next, e) => {\n      e.target === el && next(e);\n    });\n  if (modifiers.includes("away") || modifiers.includes("outside")) {\n    listenerTarget = document;\n    handler4 = wrapHandler(handler4, (next, e) => {\n      if (el.contains(e.target))\n        return;\n      if (e.target.isConnected === false)\n        return;\n      if (el.offsetWidth < 1 && el.offsetHeight < 1)\n        return;\n      if (el._x_isShown === false)\n        return;\n      next(e);\n    });\n  }\n  if (modifiers.includes("once")) {\n    handler4 = wrapHandler(handler4, (next, e) => {\n      next(e);\n      listenerTarget.removeEventListener(event, handler4, options);\n    });\n  }\n  handler4 = wrapHandler(handler4, (next, e) => {\n    if (isKeyEvent(event)) {\n      if (isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers)) {\n        return;\n      }\n    }\n    next(e);\n  });\n  listenerTarget.addEventListener(event, handler4, options);\n  return () => {\n    listenerTarget.removeEventListener(event, handler4, options);\n  };\n}\nfunction dotSyntax(subject) {\n  return subject.replace(/-/g, ".");\n}\nfunction camelCase2(subject) {\n  return subject.toLowerCase().replace(/-(\\w)/g, (match, char) => char.toUpperCase());\n}\nfunction isNumeric(subject) {\n  return !Array.isArray(subject) && !isNaN(subject);\n}\nfunction kebabCase2(subject) {\n  if ([" ", "_"].includes(subject))\n    return subject;\n  return subject.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[_\\s]/, "-").toLowerCase();\n}\nfunction isKeyEvent(event) {\n  return ["keydown", "keyup"].includes(event);\n}\nfunction isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers) {\n  let keyModifiers = modifiers.filter((i) => {\n    return !["window", "document", "prevent", "stop", "once", "capture"].includes(i);\n  });\n  if (keyModifiers.includes("debounce")) {\n    let debounceIndex = keyModifiers.indexOf("debounce");\n    keyModifiers.splice(debounceIndex, isNumeric((keyModifiers[debounceIndex + 1] || "invalid-wait").split("ms")[0]) ? 2 : 1);\n  }\n  if (keyModifiers.includes("throttle")) {\n    let debounceIndex = keyModifiers.indexOf("throttle");\n    keyModifiers.splice(debounceIndex, isNumeric((keyModifiers[debounceIndex + 1] || "invalid-wait").split("ms")[0]) ? 2 : 1);\n  }\n  if (keyModifiers.length === 0)\n    return false;\n  if (keyModifiers.length === 1 && keyToModifiers(e.key).includes(keyModifiers[0]))\n    return false;\n  const systemKeyModifiers = ["ctrl", "shift", "alt", "meta", "cmd", "super"];\n  const selectedSystemKeyModifiers = systemKeyModifiers.filter((modifier) => keyModifiers.includes(modifier));\n  keyModifiers = keyModifiers.filter((i) => !selectedSystemKeyModifiers.includes(i));\n  if (selectedSystemKeyModifiers.length > 0) {\n    const activelyPressedKeyModifiers = selectedSystemKeyModifiers.filter((modifier) => {\n      if (modifier === "cmd" || modifier === "super")\n        modifier = "meta";\n      return e[`${modifier}Key`];\n    });\n    if (activelyPressedKeyModifiers.length === selectedSystemKeyModifiers.length) {\n      if (keyToModifiers(e.key).includes(keyModifiers[0]))\n        return false;\n    }\n  }\n  return true;\n}\nfunction keyToModifiers(key) {\n  if (!key)\n    return [];\n  key = kebabCase2(key);\n  let modifierToKeyMap = {\n    ctrl: "control",\n    slash: "/",\n    space: " ",\n    spacebar: " ",\n    cmd: "meta",\n    esc: "escape",\n    up: "arrow-up",\n    down: "arrow-down",\n    left: "arrow-left",\n    right: "arrow-right",\n    period: ".",\n    equal: "=",\n    minus: "-",\n    underscore: "_"\n  };\n  modifierToKeyMap[key] = key;\n  return Object.keys(modifierToKeyMap).map((modifier) => {\n    if (modifierToKeyMap[modifier] === key)\n      return modifier;\n  }).filter((modifier) => modifier);\n}\n\n// packages/alpinejs/src/directives/x-model.js\ndirective("model", (el, {modifiers, expression}, {effect: effect3, cleanup: cleanup2}) =>
1 {\n  let scopeTarget = el;\n  if (modifiers.includes("parent")) {\n    scopeTarget = el.parentNode;\n  }\n  let evaluateGet = evaluateLater(scopeTarget, expression);\n  let evaluateSet;\n  if (typeof expression === "string") {\n    evaluateSet = evaluateLater(scopeTarget, `${expression} = __placeholder`);\n  } else if (typeof expression === "function" && typeof expression() === "string") {\n    evaluateSet = evaluateLater(scopeTarget, `${expression()} = __placeholder`);\n  } else {\n    evaluateSet = () => {\n    };\n  }\n  let getValue = () => {\n    let result;\n    evaluateGet((value) => result = value);\n    return isGetterSetter(result) ? result.get() : result;\n  };\n  let setValue = (value) => {\n    let result;\n    evaluateGet((value2) => result = value2);\n    if (isGetterSetter(result)) {\n      result.set(value);\n    } else {\n      evaluateSet(() => {\n      }, {\n        scope: {__placeholder: value}\n      });\n    }\n  };\n  if (typeof expression === "string" && el.type === "radio") {\n    mutateDom(() => {\n      if (!el.hasAttribute("name"))\n        el.setAttribute("name", expression);\n    });\n  }\n  var event = el.tagName.toLowerCase() === "select" || ["checkbox", "radio"].includes(el.type) || modifiers.includes("lazy") ? "change" : "input";\n  let removeListener = isCloning ? () => {\n  } : on(el, event, modifiers, (e) => {\n    setValue(getInputValue(el, modifiers, e, getValue()));\n  });\n  if (modifiers.includes("fill") && [null, ""].includes(getValue())) {\n    el.dispatchEvent(new Event(event, {}));\n  }\n  if (!el._x_removeModelListeners)\n    el._x_removeModelListeners = {};\n  el._x_removeModelListeners["default"] = removeListener;\n  cleanup2(() => el._x_removeModelListeners["default"]());\n  if (el.form) {\n    let removeResetListener = on(el.form, "reset", [], (e) => {\n      nextTick(() => el._x_model && el._x_model.set(el.value));\n    });\n    cleanup2(() => removeResetListener());\n  }\n  el._x_model = {\n    get() {\n      return getValue();\n    },\n    set(value) {\n      setValue(value);\n    }\n  };\n  el._x_forceModelUpdate = (value) => {\n    value = value === void 0 ? getValue() : value;\n    if (value === void 0 && typeof expression === "string" && expression.match(/\\./))\n      value = "";\n    window.fromModel = true;\n    mutateDom(() => bind(el, "value", value));\n    delete window.fromModel;\n  };\n  effect3(() => {\n    let value = getValue();\n    if (modifiers.includes("unintrusive") && document.activeElement.isSameNode(el))\n      return;\n    el._x_forceModelUpdate(value);\n  });\n});\nfunction getInputValue(el, modifiers, event, currentValue) {\n  return mutateDom(() => {\n    if (event instanceof CustomEvent && event.detail !== void 0)\n      return event.detail ?? event.target.value;\n    else if (el.type === "checkbox") {\n      if (Array.isArray(currentValue)) {\n        let newValue = modifiers.includes("number") ? safeParseNumber(event.target.value) : event.target.value;\n        return event.target.checked ? currentValue.concat([newValue]) : currentValue.filter((el2) => !checkedAttrLooseCompare2(el2, newValue));\n      } else {\n        return event.target.checked;\n      }\n    } else if (el.tagName.toLowerCase() === "select" && el.multiple) {\n      return modifiers.includes("number") ? Array.from(event.target.selectedOptions).map((option) => {\n        let rawValue = option.value || option.text;\n        return safeParseNumber(rawValue);\n      }) : Array.from(event.target.selectedOptions).map((option) => {\n        return option.value || option.text;\n      });\n    } else {\n      let rawValue = event.target.value;\n      return modifiers.includes("number") ? safeParseNumber(rawValue) : modifiers.includes("trim") ? rawValue.trim() : rawValue;\n    }\n  });\n}\nfunction safeParseNumber(rawValue) {\n  let number = rawValue ? parseFloat(rawValue) : null;\n  return isNumeric2(number) ? number : rawValue;\n}\nfunction checkedAttrLooseCompare2(valueA, valueB) {\n  return valueA == valueB;\n}\nfunction isNumeric2(subject) {\n  return !Array.isArray(subject) && !isNaN(subject);\n}\nfunction isGetterSetter(value) {\n  return value !== null && typeof value === "object" && typeof value.get === "function" && typeof value.set === "function";\n}\n\n// packages/alpinejs/src/directives/x-cloak.js\ndirective("cloak", (el) => queueMicrotask(() => mutateDom(() => el.removeAttribute(prefix("cloak")))));\n\n// packages/alpinejs/src/directives/x-init.js\naddInitSelector(() => `[${prefix("init")}]`);\ndirective("init", skipDuringClone((el, {expression}, {evaluate: evaluate2}) =>
1 {\n  if (typeof expression === "string") {\n    return !!expression.trim() && evaluate2(expression, {}, false);\n  }\n  return evaluate2(expression, {}, false);\n}));\n\n// packages/alpinejs/src/directives/x-text.js\ndirective("text", (el, {expression}, {effect: effect3, evaluateLater: evaluateLater2}) => {\n  let evaluate2 = evaluateLater2(expression);\n  effect3(() => {\n    evaluate2((value) => {\n      mutateDom(() => {\n        el.textContent = value;\n      });\n    });\n  });\n});\n\n// packages/alpinejs/src/directives/x-html.js\ndirective("html", (el, {expression}, {effect: effect3, evaluateLater: evaluateLater2}) => {\n  let evaluate2 = evaluateLater2(expression);\n  effect3(() => {\n    evaluate2((value) => {\n      mutateDom(() => {\n        el.innerHTML = value;\n        el._x_ignoreSelf = true;\n        initTree(el);\n        delete el._x_ignoreSelf;\n      });\n    });\n  });\n});\n\n// packages/alpinejs/src/directives/x-bind.js\nmapAttributes(startingWith(":", into(prefix("bind:"))));\nvar handler2 = (el, {value, modifiers, expression, original}, {effect: effect3}) => {\n  if (!value) {\n    let bindingProviders = {};\n    injectBindingProviders(bindingProviders);\n    let getBindings = evaluateLater(el, expression);\n    getBindings((bindings) => {\n      applyBindingsObject(el, bindings, original);\n    }, {scope: bindingProviders});\n    return;\n  }\n  if (value === "key")\n    return storeKeyForXFor(el, expression);\n  if (el._x_inlineBindings && el._x_inlineBindings[value] && el._x_inlineBindings[value].extract) {\n    return;\n  }\n  let evaluate2 = evaluateLater(el, expression);\n  effect3(() => evaluate2((result) => {\n    if (result === void 0 && typeof expression === "string" && expression.match(/\\./)) {\n      result = "";\n    }\n    mutateDom(() => bind(el, value, result, modifiers));\n  }));\n};\nhandler2.inline = (el, {value, modifiers, expression}) => {\n  if (!value)\n    return;\n  if (!el._x_inlineBindings)\n    el._x_inlineBindings = {};\n  el._x_inlineBindings[value] = {expression, extract: false};\n};\ndirective("bind", handler2);\nfunction storeKeyForXFor(el, expression) {\n  el._x_keyExpression = expression;\n}\n\n// packages/alpinejs/src/directives/x-data.js\naddRootSelector(() => `[${prefix("data")}]`);\ndirective("data", skipDuringClone((el, {expression}, {cleanup: cleanup2}) => {\n  expression = expression === "" ? "{}" : expression;\n  let magicContext = {};\n  injectMagics(magicContext, el);\n  let dataProviderContext = {};\n  injectDataProviders(dataProviderContext, magicContext);\n  let data2 = evaluate(el, expression, {scope: dataProviderContext});\n  if (data2 === void 0 || data2 === true)\n    data2 = {};\n  injectMagics(data2, el);\n  let reactiveData = reactive(data2);\n  initInterceptors(reactiveData);\n  let undo = addScopeToNode(el, reactiveData);\n  reactiveData["init"] && evaluate(el, reactiveData["init"]);\n  cleanup2(() =>
1 {\n    reactiveData["destroy"] && evaluate(el, reactiveData["destroy"]);\n    undo();\n  });\n}));\n\n// packages/alpinejs/src/directives/x-show.js\ndirective("show", (el, {modifiers, expression}, {effect: effect3}) => {\n  let evaluate2 = evaluateLater(el, expression);\n  if (!el._x_doHide)\n    el._x_doHide = () => {\n      mutateDom(() => {\n        el.style.setProperty("display", "none", modifiers.includes("important") ? "important" : void 0);\n      });\n    };\n  if (!el._x_doShow)\n    el._x_doShow = () => {\n      mutateDom(() => {\n        if (el.style.length === 1 && el.style.display === "none") {\n          el.removeAttribute("style");\n        } else {\n          el.style.removeProperty("display");\n        }\n      });\n    };\n  let hide = () => {\n    el._x_doHide();\n    el._x_isShown = false;\n  };\n  let show = () => {\n    el._x_doShow();\n    el._x_isShown = true;\n  };\n  let clickAwayCompatibleShow = () => setTimeout(show);\n  let toggle = once((value) => value ? show() : hide(), (value) => {\n    if (typeof el._x_toggleAndCascadeWithTransitions === "function") {\n      el._x_toggleAndCascadeWithTransitions(el, value, show, hide);\n    } else {\n      value ? clickAwayCompatibleShow() : hide();\n    }\n  });\n  let oldValue;\n  let firstTime = true;\n  effect3(() => evaluate2((value) => {\n    if (!firstTime && value === oldValue)\n      return;\n    if (modifiers.includes("immediate"))\n      value ? clickAwayCompatibleShow() : hide();\n    toggle(value);\n    oldValue = value;\n    firstTime = false;\n  }));\n});\n\n// packages/alpinejs/src/directives/x-for.js\ndirective("for", (el, {expression}, {effect: effect3, cleanup: cleanup2}) => {\n  let iteratorNames = parseForExpression(expression);\n  let evaluateItems = evaluateLater(el, iteratorNames.items);\n  let evaluateKey = evaluateLater(el, el._x_keyExpression || "index");\n  el._x_prevKeys = [];\n  el._x_lookup = {};\n  effect3(() => loop(el, iteratorNames, evaluateItems, evaluateKey));\n  cleanup2(() =>
1 {\n    Object.values(el._x_lookup).forEach((el2) => el2.remove());\n    delete el._x_prevKeys;\n    delete el._x_lookup;\n  });\n});\nfunction loop(el, iteratorNames, evaluateItems, evaluateKey) {\n  let isObject2 = (i) => typeof i === "object" && !Array.isArray(i);\n  let templateEl = el;\n  evaluateItems((items) => {\n    if (isNumeric3(items) && items >= 0) {\n      items = Array.from(Array(items).keys(), (i) => i + 1);\n    }\n    if (items === void 0)\n      items = [];\n    let lookup = el._x_lookup;\n    let prevKeys = el._x_prevKeys;\n    let scopes = [];\n    let keys = [];\n    if (isObject2(items)) {\n      items = Object.entries(items).map(([key, value]) => {\n        let scope2 = getIterationScopeVariables(iteratorNames, value, key, items);\n        evaluateKey((value2) => keys.push(value2), {scope: {index: key, ...scope2}});\n        scopes.push(scope2);\n      });\n    } else {\n      for (let i = 0; i < items.length; i++) {\n        let scope2 = getIterationScopeVariables(iteratorNames, items[i], i, items);\n        evaluateKey((value) => keys.push(value), {scope: {index: i, ...scope2}});\n        scopes.push(scope2);\n      }\n    }\n    let adds = [];\n    let moves = [];\n    let removes = [];\n    let sames = [];\n    for (let i = 0; i < prevKeys.length; i++) {\n      let key = prevKeys[i];\n      if (keys.indexOf(key) === -1)\n        removes.push(key);\n    }\n    prevKeys = prevKeys.filter((key) => !removes.includes(key));\n    let lastKey = "template";\n    for (let i = 0; i < keys.length; i++) {\n      let key = keys[i];\n      let prevIndex = prevKeys.indexOf(key);\n      if (prevIndex === -1) {\n        prevKeys.splice(i, 0, key);\n        adds.push([lastKey, i]);\n      } else if (prevIndex !== i) {\n        let keyInSpot = prevKeys.splice(i, 1)[0];\n        let keyForSpot = prevKeys.splice(prevIndex - 1, 1)[0];\n        prevKeys.splice(i, 0, keyForSpot);\n        prevKeys.splice(prevIndex, 0, keyInSpot);\n        moves.push([keyInSpot, keyForSpot]);\n      } else {\n        sames.push(key);\n      }\n      lastKey = key;\n    }\n    for (let i = 0; i < removes.length; i++) {\n      let key = removes[i];\n      if (!!lookup[key]._x_effects) {\n        lookup[key]._x_effects.forEach(dequeueJob);\n      }\n      lookup[key].remove();\n      lookup[key] = null;\n      delete lookup[key];\n    }\n    for (let i = 0; i < moves.length; i++) {\n      let [keyInSpot, keyForSpot] = moves[i];\n      let elInSpot = lookup[keyInSpot];\n      let elForSpot = lookup[keyForSpot];\n      let marker = document.createElement("div");\n      mutateDom(() => {\n        if (!elForSpot)\n          warn(`x-for ":key" is undefined or invalid`, templateEl);\n        elForSpot.after(marker);\n        elInSpot.after(elForSpot);\n        elForSpot._x_currentIfEl && elForSpot.after(elForSpot._x_currentIfEl);\n        marker.before(elInSpot);\n        elInSpot._x_currentIfEl && elInSpot.after(elInSpot._x_currentIfEl);\n        marker.remove();\n      });\n      elForSpot._x_refreshXForScope(scopes[keys.indexOf(keyForSpot)]);\n    }\n    for (let i = 0; i < adds.length; i++) {\n      let [lastKey2, index] = adds[i];\n      let lastEl = lastKey2 === "template" ? templateEl : lookup[lastKey2];\n      if (lastEl._x_currentIfEl)\n        lastEl = lastEl._x_currentIfEl;\n      let scope2 = scopes[index];\n      let key = keys[index];\n      let clone2 = document.importNode(templateEl.content, true).firstElementChild;\n      let reactiveScope = reactive(scope2);\n      addScopeToNode(clone2, reactiveScope, templateEl);\n      clone2._x_refreshXForScope = (newScope) => {\n        Object.entries(newScope).forEach(([key2, value]) => {\n          reactiveScope[key2] = value;\n        });\n      };\n      mutateDom(() => {\n        lastEl.after(clone2);\n        initTree(clone2);\n      });\n      if (typeof key === "object") {\n        warn("x-for key cannot be an object, it must be a string or an integer", templateEl);\n      }\n      lookup[key] = clone2;\n    }\n    for (let i = 0; i < sames.length; i++) {\n      lookup[sames[i]]._x_refreshXForScope(scopes[keys.indexOf(sames[i])]);\n    }\n    templateEl._x_prevKeys = keys;\n  });\n}\nfunction parseForExpression(expression) {\n  let forIteratorRE = /,([^,\\}
1\\]]*)(?:,([^,\\}\\]]*))?$/;\n  let stripParensRE = /^\\s*\\(|\\)\\s*$/g;\n  let forAliasRE = /([\\s\\S]*?)\\s+(?:in|of)\\s+([\\s\\S]*)/;\n  let inMatch = expression.match(forAliasRE);\n  if (!inMatch)\n    return;\n  let res = {};\n  res.items = inMatch[2].trim();\n  let item = inMatch[1].replace(stripParensRE, "").trim();\n  let iteratorMatch = item.match(forIteratorRE);\n  if (iteratorMatch) {\n    res.item = item.replace(forIteratorRE, "").trim();\n    res.index = iteratorMatch[1].trim();\n    if (iteratorMatch[2]) {\n      res.collection = iteratorMatch[2].trim();\n    }\n  } else {\n    res.item = item;\n  }\n  return res;\n}\nfunction getIterationScopeVariables(iteratorNames, item, index, items) {\n  let scopeVariables = {};\n  if (/^\\[.*\\]$/.test(iteratorNames.item) && Array.isArray(item)) {\n    let names = iteratorNames.item.replace("[", "").replace("]", "").split(",").map((i) => i.trim());\n    names.forEach((name, i) => {\n      scopeVariables[name] = item[i];\n    });\n  } else if (/^\\{.*\\}$/.test(iteratorNames.item) && !Array.isArray(item) && typeof item === "object") {\n    let names = iteratorNames.item.replace("{", "").replace("}", "").split(",").map((i) => i.trim());\n    names.forEach((name) => {\n      scopeVariables[name] = item[name];\n    });\n  } else {\n    scopeVariables[iteratorNames.item] = item;\n  }\n  if (iteratorNames.index)\n    scopeVariables[iteratorNames.index] = index;\n  if (iteratorNames.collection)\n    scopeVariables[iteratorNames.collection] = items;\n  return scopeVariables;\n}\nfunction isNumeric3(subject) {\n  return !Array.isArray(subject) && !isNaN(subject);\n}\n\n// packages/alpinejs/src/directives/x-ref.js\nfunction handler3() {\n}\nhandler3.inline = (el, {expression}, {cleanup: cleanup2}) => {\n  let root = closestRoot(el);\n  if (!root._x_refs)\n    root._x_refs = {};\n  root._x_refs[expression] = el;\n  cleanup2(() => delete root._x_refs[expression]);\n};\ndirective("ref", handler3);\n\n// packages/alpinejs/src/directives/x-if.js\ndirective("if", (el, {expression}, {effect: effect3, cleanup: cleanup2}) => {\n  let evaluate2 = evaluateLater(el, expression);\n  let show = () => {\n    if (el._x_currentIfEl)\n      return el._x_currentIfEl;\n    let clone2 = el.content.cloneNode(true).firstElementChild;\n    addScopeToNode(clone2, {}, el);\n    mutateDom(() => {\n      el.after(clone2);\n      initTree(clone2);\n    });\n    el._x_currentIfEl = clone2;\n    el._x_undoIf = () => {\n      walk(clone2, (node) => {\n        if (!!node._x_effects) {\n          node._x_effects.forEach(dequeueJob);\n        }\n      });\n      clone2.remove();\n      delete el._x_currentIfEl;\n    };\n    return clone2;\n  };\n  let hide = () => {\n    if (!el._x_undoIf)\n      return;\n    el._x_undoIf();\n    delete el._x_undoIf;\n  };\n  effect3(() => evaluate2((value) => {\n    value ? show() : hide();\n  }));\n  cleanup2(() => el._x_undoIf && el._x_undoIf());\n});\n\n// packages/alpinejs/src/directives/x-id.js\ndirective("id", (el, {expression}, {evaluate: evaluate2}) => {\n  let names = evaluate2(expression);\n  names.forEach((name) => setIdRoot(el, name));\n});\n\n// packages/alpinejs/src/directives/x-on.js\nmapAttributes(startingWith("@", into(prefix("on:"))));\ndirective("on", skipDuringClone((el, {value, modifiers, expression}, {cleanup: cleanup2}) => {\n  let evaluate2 = expression ? evaluateLater(el, expression) : () => {\n  };\n  if (el.tagName.toLowerCase() === "template") {\n    if (!el._x_forwardEvents)\n      el._x_forwardEvents = [];\n    if (!el._x_forwardEvents.includes(value))\n      el._x_forwardEvents.push(value);\n  }\n  let removeListener = on(el, value, modifiers, (e) => {\n    evaluate2(() => {\n    }, {scope: {$event: e}, params: [e]});\n  });\n  cleanup2(() => removeListener());\n}));\n\n// packages/alpinejs/src/directives/index.js\nwarnMissingPluginDirective("Collapse", "collapse", "collapse");\nwarnMissingPluginDirective("Intersect", "intersect", "intersect");\nwarnMissingPluginDirective("Focus", "trap", "focus");\nwarnMissingPluginDirective("Mask", "mask", "mask");\nfunction warnMissingPluginDirective(name, directiveName2, slug) {\n  directive(directiveName2, (el) => warn(`You can\'t use [x-${directiveName2}] without first installing the "${name}" plugin here: https://alpinejs.dev/plugins/${slug}`, el));\n}\n\n// packages/alpinejs/src/index.js\nalpine_default.setEvaluator(normalEvaluator);\nalpine_default.setReactivityEngine({reactive: reactive2, effect: effect2, release: stop, raw: toRaw});\nvar src_default = alpine_default;\n\n// packages/alpinejs/builds/module.js\nvar module_default = src_default;\n\n\n;// CONCATENATED MODULE: ./js/app.js\n// Import dependencies\n//\n// If you no longer want to use a dependency, remember\n// to also remove its path from "config.paths.watched".\n\n\n\n\n\n\n\n//import postscribe from \'postscribe\'\n\n//import postcribe from \'../vendor/postscribe\'\n//import socket from "./socket"\n\n\n\n\nconst userAgent = navigator.userAgent.toLowerCase();\nconst human = userAgent.includes("bot") ? false : true;
1\n\n//import \'alpinejs\';\n\nwindow.Alpine = module_default;\nmodule_default.start();\nlet csrfToken = document.querySelector("meta[name=\'csrf-token\']").getAttribute("content");\n\n// NOTIFICACIONES //\n\nconst applicationServerPublicKey = "BG2FvaWurlCXXeyEN6R0muQuhrBgimi7QvNjcFIOoCN9wyeQJNxSkFlunAv62WsW72JpeDgbLlFyV8P6ZogvEAU";\nlet pushButton = null;\nlet canalesDiv = null;\nlet isSubscribed = false;\nlet swRegistration = null;\nfunction urlB64ToUint8Array(base64String) {\n  const padding = \'=\'.repeat((4 - base64String.length % 4) % 4);\n  const base64 = (base64String + padding).replace(/\\-/g, \'+\').replace(/_/g, \'/\');\n  const rawData = window.atob(base64);\n  const outputArray = new Uint8Array(rawData.length);\n  for (let i = 0; i < rawData.length; ++i) {\n    outputArray[i] = rawData.charCodeAt(i);\n  }\n  return outputArray;\n}\nfunction updateBtn() {\n  if (Notification.permission === \'denied\') {\n    pushButton.textContent = \'Notificaciones Push Bloqueadas.\';\n    pushButton.disabled = true;\n    updateSubscriptionOnServer(null);\n    return;\n  }\n  if (isSubscribed) {\n    pushButton.textContent = \'Desactivar Notificaciones Push\';\n  } else {\n    pushButton.textContent = \'Activar Notificaciones Push\';\n  }\n  pushButton.disabled = false;\n}\nfunction updateSubscriptionOnServer(subscription, inicial) {\n  var canales = radioCanales();\n  if (inicial) {\n    canales = ["peticion_inicial"];\n  }\n  if (subscription) {\n    sendSubscriptionToBackEnd(subscription, canales);\n  }\n  const subscriptionJson = document.querySelector(\'.js-subscription-json\');\n  const subscriptionDetails = document.querySelector(\'.js-subscription-details\');\n  if (subscription) {\n    subscriptionJson.textContent = JSON.stringify(subscription);\n    subscriptionDetails.classList.remove(\'is-invisible\');\n  } else {\n    subscriptionDetails.classList.add(\'is-invisible\');\n  }\n}\nfunction subscribeUser() {\n  const applicationServerKey = urlB64ToUint8Array(applicationServerublicKey);\n  swRegistration.pushManager.subscribe({\n    userVisibleOnly: true,\n    applicationServerKey: applicationServerKey\n  }).then(function (subscription) {\n    updateSubscriptionOnServer(subscription);\n    isSubscribed = true;\n    updateBtn();\n  }).catch(function (err) {\n    updateBtn();\n  });\n}\nfunction unsubscribeUser() {\n  swRegistration.pushManager.getSubscription().then(function (subscription) {\n    if (subscription) {\n      deleteSubscriptionBackEnd(subscription);\n      return subscription.unsubscribe();\n    }\n  }).catch(function (error) {\n    console.log(\'Error unsubscribing\', error);\n  }).then(function (subscription) {\n    updateSubscriptionOnServer(null);\n    console.log(\'User is unsubscribed.\');\n    isSubscribed = false;\n    updateBtn();\n    //updateCanales([]);\n  });\n}\nfunction initializeNotificationsUI(hook) {\n  pushButton.addEventListener(\'click\', function () {\n    pushButton.disabled = true;\n    if (isSubscribed) {\n      hook.pushEvent("suscrito", {\n        "suscrito": "suscrito"\n      });\n      unsubscribeUser();\n    } else {\n      hook.pushEvent("suscrito", {\n        "suscrito": "no_suscrito"\n      });\n      subscribeUser();\n    }\n  });\n\n  // Set the initial subscription value\n  swRegistration.pushManager.getSubscription().then(function (subscription) {\n    isSubscribed = !(subscription === null);\n    updateSubscriptionOnServer(subscription, "inicial");\n    updateBtn();\n  });\n}\nfunction sendSubscriptionToBackEnd(subscription, canales) {\n  subscription = {\n    "suscripcion_push": subscription,\n    "canales": canales\n  };\n  return fetch(\'/api/suscripcionespush/\', {\n    method: \'POST\',\n    headers: {\n      \'Content-Type\': \'application/json\'\n    },\n    body: JSON.stringify(subscription)\n  }).then(function (response) {\n    if (!response.ok) {\n      throw new Error(\'Bad status code from server.\');\n    }\n    return response.json();\n  }).then(function (responseData) {\n    if (!(responseData.data && responseData.data.success)) {\n      throw new Error(\'Bad response from server.\');\n    } else {\n      console.log(responseData.data);\n      updateCanales(responseData.data["canales"], responseData.data["suscripciones"]);\n    }\n  });\n}\nfunction deleteSubscriptionBackEnd(subscription) {\n  const endpoint = encodeURIComponent(subscription.endpoint);\n  return fetch(\'/api/suscripcionespush/\' + endpoint, {\n    method: \'DELETE\',\n    headers: {\n      \'Content-Type\': \'application/json\'\n    }\n  }).then(function (response) {\n    if (!response.ok) {\n      throw new Error(\'Bad status code from server.\');\n    }\n    return response.json();\n  }).then(function (responseData) {\n    if (!(responseData.data && responseData.data.success)) {\n      throw new Error(\'Bad response from server.\');\n    } else {\n      updateCanales([]);\n    }\n  });\n}\nfunction updateCanales(canales, canales_activos) {\n  canalesDiv.innerHTML = "";\n  for (const canal of canales) {\n    createCanal(canal, canales_activos);\n  }\n}\nfunction createCanal(canal, canales_activos) {\n  var activo = false;\n  for (const canal_activo of canales_activos) {\n    if (canal_activo == canal.id) {\n      var activo = true;\n    }\n  }\n  var checked = "";\n  if (activo) {\n    checked = "checked";\n  }\n  var div = document.createElement("div");\n  var label_l = document.createElement(\'label\');\n  label_l.htmlFor = canal.id;\n  label_l.innerHTML = canal.nombre;\n  div.appendChild(label_l);\n  var span = document.createElement("span");\n  span.classList.add(\'ckbx-style-1\');\n  var button = document.createElement("input");\n  button.type = "checkbox";\n  button.value = canal.id;\n  button.id = canal.id;\n  button.checked = checked;\n  span.appendChild(button);\n  var label_c = document.createElement(\'label\');\n  label_c.htmlFor = canal.id;\n  span.appendChild(label_c);\n  div.appendChild(span);\n  canalesDiv.appendChild(div);\n  button.addEventListener(\'change\', event => {\n    subscribeUser();\n  });\n}\nfunction radioCanales() {\n  let activados = [];\n  let checkboxes = document.querySelectorAll(\'input:checked\');
1\n  checkboxes.forEach(checkbox => {\n    activados.push(checkbox.value);\n  });\n  return activados;\n}\nfunction handleConnection() {\n  if (navigator.onLine) {\n    isReachable(getServerUrl()).then(function (online) {\n      if (online) {\n        console.log(\'online\');\n      } else {\n        console.log(\'no connectivity\');\n      }\n    });\n  } else {\n    console.log(\'offline\');\n  }\n}\nfunction isReachable(url) {\n  return fetch(url, {\n    method: \'HEAD\',\n    mode: \'no-cors\'\n  }).then(function (resp) {\n    return resp && (resp.ok || resp.type === \'opaque\');\n  }).catch(function (err) {\n    console.warn(\'[conn test failure]:\', err);\n  });\n}\nfunction getServerUrl() {\n  return window.location.origin;\n}\n\n// FIN NOTIFICACIONES\n\nconst summerNoteMin = {\n  styleWithSpan: false,\n  lang: \'es-ES\',\n  height: 400,\n  dialogsFade: true,\n  toolbar: [[\'style\', [\'italic\', \'underline\', \'clear\']], [\'insert\', [\'link\', \'unlink\']]],\n  cleaner: {\n    notTime: 500,\n    // Time to display Notifications.\n    action: \'both\',\n    // both|button|paste \'button\' only cleans via toolbar button, \'paste\' only clean when pasting content, both does both options.\n    newline: \'<br>\',\n    // Summernote\'s default is to use \'<p><br></p>\'\n    notStyle: \'position:absolute;top:0;left:0;right:0\',\n    // Position of Notification\n    icon: \'<i class="note-icon">[x]</i>\',\n    keepHtml: true,\n    // Remove all Html formats\n    keepClasses: false,\n    // Remove Classes\n    keepOnlyTags: [\'<br>\', \'<a>\', \'<p>\'],\n    // If keepHtml is true, remove all tags except these\n    badTags: [\'style\', \'script\', \'applet\', \'embed\', \'noframes\', \'noscript\', \'html\'],\n    // Remove full tags with contents\n    keepTagContents: [\'span\', \'font\', \'strong\'],\n    // Remove full tags with contents\n    badAttributes: [\'dir\', \'id\', \'style\', \'start\', \'name\', \'class\', \'align\', \'ontouchstart\', \'size\', \'face\', \'lang\'] // Remove attributes from remaining tags\n  }\n};\nconst summerNoteConf = {\n  styleWithSpan: false,\n  lang: \'es-ES\',\n  height: 400,\n  dialogsFade: true,\n  toolbar: [[\'style\', [\'bold\', \'italic\', \'underline\', \'clear\']], [\'font\', [\'strikethrough\', \'superscript\', \'subscript\']], [\'para\', [\'ul\', \'ol\', \'paragraph\']], [\'link\', [\'style\']], [\'insert\', [\'link\', \'unlink\']], [\'salto\', [\'articulo\', \'foto\', \'codigo\', \'documento\', \'borrar\']], [\'view\', [\'codeview\']], [\'insert\', [\'template\']]],\n  popover: {\n    image: [[\'custom\', [\'imageAttributes\', \'captionIt\']], [\'imagesize\', [\'imageSize100\', \'imageSize50\', \'imageSize25\']], [\'float\', [\'floatLeft\', \'floatRight\', \'floatNone\']], [\'remove\', [\'removeMedia\']]]\n  },\n  imageAttributes: {\n    imageDialogLayout: \'default\',\n    // default|horizontal\n    icon: \'<i class="note-icon-pencil"/>\',\n    removeEmpty: false // true = remove attributes | false = leave empty if present\n  },\n  displayFields: {\n    imageBasic: true,\n    // show/hide Title, Source, Alt fields\n    imageExtra: true,\n    // show/hide Alt, Class, Style, Role fields\n    linkBasic: true,\n    // show/hide URL and Target fields for link\n    linkExtra: false // show/hide Class, Rel, Role fields for link\n  },\n  captionIt: {\n    icon: \'<i class="note-icon-pencil"}/>\',\n    // Leave empty or don\'t set for default Icon.\n    figureClass: \'figure-interna\',\n    figcaptionClass: \'pie\'\n  },\n  cleaner: {\n    notTime: 500,\n    // Time to display Notifications.\n    action: \'both\',\n    // both|button|paste \'button\' only cleans via toolbar button, \'paste\' only clean when pasting content, both does both options.\n    newline: \'<br>\',\n    // Summernote\'s default is to use \'<p><br></p>\'\n    notStyle: \'position:absolute;top:0;left:0;right:0\',\n    // Position of Notification\n    icon: \'<i class="note-icon">[x]</i>\',\n    keepHtml: true,\n    // Remove all Html formats\n    keepClasses: false,\n    // Remove Classes\n    keepOnlyTags: [\'<br>\', \'<a>\', \'<p>\'],\n    // If keepHtml is true, remove all tags except these\n    badTags: [\'style\', \'script\', \'applet\', \'embed\', \'noframes\', \'noscript\', \'html\'],\n    // Remove full tags with contents\n    keepTagContents: [\'span\', \'font\', \'strong\'],\n    // Remove full tags with contents\n    badAttributes: [\'dir\', \'id\', \'style\', \'start\', \'name\', \'class\', \'align\', \'ontouchstart\', \'size\', \'face\', \'lang\'] // Remove attributes from remaining tags\n  },\n  template: {\n    path: \'/js/summernote/tpls\',\n    list: {\n      \'recuadro_generico\': \'Recuadro genérico\',\n      \'recuadro_dcha\': \'Recuadro derecho\',\n      \'recuadro_izq\': \'Recuadro izquierdo\',\n      \'recuadro\': \'Recuadro "antiguo"\'\n    }\n  }\n};\nwindow.addEventListener("phx:quitar-body-overflows", e => {\n  document.querySelector("body").classList.remove("overflow");\n});\nwindow.addEventListener("articulista:limpiar_url", e => {\n  history.replaceState(\'\', document.title, window.location.href.split(\'#\')[0]);\n});\nwindow.addEventListener("articulista:menu", e => {\n  var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n  if (w > 768 && document.querySelector(\'#menu-bur-contenedor\')) {\n    var menu_admin = 0;\n    if (document.querySelector(\'#menu-admin\')) {\n      menu_admin = document.querySelector(\'#menu-admin\').offsetHeight;\n    }\n    var publi = 0;\n    if (basicos_visible(document.querySelector(\'#publi-cabecera\'))) {\n      var {\n        bottom\n      } = document.querySelector(\'#publi-cabecera\').getBoundingClientRect();\n      if (bottom > 1) {\n        publi = bottom;\n      }\n    }\n    var menu_arriba = document.querySelector(\'#menu-arriba\').offsetHeight - 1;\n    var abajo = menu_arriba + menu_admin + publi;
1\n    const menu_1 = document.querySelector(\'#menu-bur-contenedor\');\n    menu_1.style.top = `${menu_arriba}px`;\n    menu_1.style.height = `calc(100vh - ${abajo}px)`;\n    const menu_secciones = document.querySelector(\'.menu-secciones\');\n    const menu_secciones_container = document.getElementById("menu-secciones-escritorio");\n    menu_secciones_container.appendChild(menu_secciones);\n    const menu_secciones_h = menu_secciones.offsetHeight / 2;\n    var {\n      top\n    } = document.querySelector(\'.secciones\').getBoundingClientRect();\n    menu_secciones_container.style.top = `${top - menu_secciones_h}px`;\n    if (document.querySelector(\'#menu-personal-contenedor\')) {\n      const menu_2 = document.querySelector(\'#menu-personal-contenedor\');\n      menu_2.style.top = `${menu_arriba}px`;\n      menu_2.style.height = `calc(100vh - ${abajo}px)`;\n    }\n  }\n  if (w < 768 && document.querySelector(\'#menu-bur-contenedor\')) {\n    const menu_secciones = document.querySelector(\'.menu-secciones\');\n    document.getElementById("menu-secciones-movil").appendChild(menu_secciones);\n  }\n});\n\n// Base AUDIOS \n\nwindow.addEventListener("phx:cambiar-seleccion", e => {\n  if (audio.paused) {\n    liveSocket.hooks.AudioPlayer.datos_audio();\n  }\n  ;\n});\nwindow.addEventListener("phx:play-seleccion", e => {\n  if (document.getElementById("seleccionar")) {\n    liveSocket.hooks.AudioSeleccionar.mounted();\n  }\n  audio_origen = "recomendacion";\n  liveSocket.hooks.AudioPlayer.audio_reproducir();\n});\nfunction segundos_a_string(s) {\n  if (s === "undefined" || s == 0 || isNaN(s)) return "00:00";\n  const h = Math.floor(s / 3600);\n  const m = Math.floor(s % 3600 / 60);\n  s = s % 60;\n  s = parseInt(s);\n  return [h, m > 9 ? m : h ? \'0\' + m : m || \'0\', s > 9 ? s : \'0\' + s].filter(a => a).join(\':\');\n}\nvar radiobot_api = "wss://radio.radiobot.org/api/live/nowplaying/websocket";\nvar socket_radio_bot = false;\nlet audio = false;\nlet audio_origen = "recomendacion";\nvar audio_progreso = document.querySelector(\'#progreso-audio\');\nvar audio_momento = 0;\nvar audio_position = document.querySelector("#audio-position");\nconst hooks = {\n  TrackEvent: {\n    mounted() {\n      document.addEventListener("click", e => {\n        if (this.liveSocket.isConnected()) {\n          console.log(e.target);\n          const el = e.target.closest("[id]");\n          console.log(el);\n          this.pushEvent("track_event", {\n            tag: e.target.tagName,\n            id: el.id,\n            path: location.pathname\n          }).catch(() => {});\n        }\n      });\n    },\n    destroyed() {\n      document.removeEventListener("click", this.clickHandler);\n    }\n  },\n  ScrollToInicio: {\n    updated() {\n      const el = document.getElementById("lista-inicio");\n      if (el) {\n        //el.scrollIntoView({ behavior: "smooth" })\n        const y = el.getBoundingClientRect().top + window.scrollY - 100;\n        window.scrollTo({\n          top: y,\n          behavior: "smooth"\n        });\n      }\n    }\n  },\n  MantenerScroll: {\n    mounted() {\n      this.scrollX = window.scrollX;\n      this.scrollY = window.scrollY;\n    },\n    updated() {\n      if (this.scrollX !== undefined) {\n        requestAnimationFrame(() => {\n          window.scrollTo(this.scrollX, this.scrollY);\n        });\n      }\n      this.scrollX = window.scrollX;\n      this.scrollY = window.scrollY;\n    }\n  },\n  EleccionesChart: {\n    mounted() {\n      this.cargarD3();\n    },\n    cargarD3() {\n      if (typeof d3 !== \'undefined\') {\n        this.inicializar();\n        return;\n      }\n      const script = document.createElement(\'script\');\n      script.src = \'https://cdnjs.cloudflare.com/ajax/libs/d3/6.0.0/d3.min.js\';\n      script.integrity = \'sha512-9uJB6ZmL2UhBkQH2X1B+lbEFIDtlauO0fPUp0Rdo6Tz21a1awgSD+FfSykvd+gD3c8WQrwWeaEgMkPsDep3P8w==\';\n      script.crossOrigin = \'anonymous\';\n      script.referrerPolicy = \'no-referrer\';\n      script.onload = () => {\n        // Fallback: asegurar que D3 esté disponible\n        setTimeout(() => this.inicializar(), 50);\n      };\n\n      // Fallback si onload no funciona\n      script.onerror = () => {\n        setTimeout(() => this.inicializar(), 500);\n      };\n      document.head.appendChild(script);\n    },\n    inicializar() {\n      this.state = {\n        data: JSON.parse(this.el.dataset.datos || \'{}\'),\n        anho: this.el.dataset.anho,\n        territorio: this.el.dataset.territorio,\n        datosConsulta: JSON.parse(this.el.dataset.datosConsulta || \'{}\')\n      };\n      this.draw_all();\n    },\n    updated() {\n      this.state.anho = this.el.dataset.anho;\n      this.state.territorio = this.el.dataset.territorio;\n      this.draw_all();\n    },\n    getSize(id) {\n      const el = document.getElementById(id);\n      if (!el || !el.clientWidth) return null;\n      return {\n        width: el.clientWidth,\n        height: el.clientWidth / 950 * 250\n      };\n    },\n    responsivefy(svg) {\n      const c = d3.select(svg.node().parentNode);\n      const w = parseInt(svg.style("width"));\n      const h = parseInt(svg.style("height"));\n      svg.attr("viewBox", `0 0 ${w} ${h}`).attr("preserveAspectRatio", "xMinYMid meet");\n      window.addEventListener("resize", () => {\n        const nw = parseInt(c.style("width"));\n        svg.attr("width", nw).attr("height", Math.round(nw * h / w));\n      });\n    },\n    createSvg(id, w, h) {\n      const c = d3.select(\'#\' + id);\n      c.selectAll(\'*\').remove();\n      return c.append(\'svg\').attr(\'width\', w).attr(\'height\', h).call(this.responsivefy).append(\'g\');\n    },\n    createDatosSvg(width, height) {\n      var size = 16;\n      if (width < 600) {\n        size = 13;\n      }\n      if (width < 550) {\n        size = 12;\n      }\n      if (width < 500) {\n        size = 12;\n      }\n      if (width < 450) {\n        size = 11;\n      }\n      if (width < 400) {\n        size = 10;\n      }\n      const c = d3.select(\'#datos\');\n      c.selectAll(\'*\').remove();\n      return c.append(\'svg\').attr(\'width\', width).attr(\'height\', height).call(this.responsivefy).append(\'g\').attr(\'font-family\', \'sans-serif\').attr(\'font-size\', size).attr(\'text-anchor\', \'middle\');\n    },\n    createScales(data, w, h) {\n      return {\n        x: d3.scaleBand().domain(data.map(d => d.siglas)).range([0, w]).padding(0.05),\n        y: d3.scaleLinear().domain([0, d3.max(data, d => d.percent / 100)]).nice().range([h, 0])\n      };\n    },\n    createYScaleGlobal(data, height) {\n      return d3.scaleLinear().domain([0, d3.max(data, d => d.percent / 100)]).range([height, 0]).nice();\n    },\n    drawBars(svg, data, size, frac, yScaleGlobal, id) {\n      let d = data;\n      if (frac === 1) d = data.slice(0, 5);\n      if (frac === 2) d = data.slice(5);\n      const s = this.createScales(d, size.width, size.height);\n      const anho_actual = this.state.datosConsulta.anho_actual || \'2026\';\n      const anho_anterior = this.state.datosConsulta.anho_anterior || \'2022\';\n      if (id !== \'grafica_2\') {\n        svg.append(\'text\').attr(\'x\', size.width - 10).attr(\'y\', 40).attr(\'text-anchor\', \'end\').attr(\'font-size\', 32).attr(\'font-weight\', \'bold\').text(this.state.anho === \'elecciones_actuales\' ? anho_actual : anho_anterior);\n      }\n      const g = svg.selectAll(\'.bar\').data(d).enter().append(\'g\');\n      g.append(\'rect\').attr(\'class\', \'bar\').attr(\'x\', x => s.x(x.siglas)).attr(\'y\', yScaleGlobal(0)).attr(\'width\', s.x.bandwidth()).attr(\'height\', size.height - yScaleGlobal(0)).attr(\'fill\', x => this.color(this.sigla(x.siglas))).on(\'mouseover\', this.showTooltip).on(\'mouseout\', this.hideTooltip).transition().duration(800).attr(\'y\', x => yScaleGlobal(x.percent / 100)).attr(\'height\', x => size.height - yScaleGlobal(x.percent / 100));\n      g.append(\'text\').attr(\'x\', x => s.x(x.siglas) + s.x.bandwidth() / 2).attr(\'y\', x => yScaleGlobal(4)).attr(\'text-anchor\', \'middle\').attr(\'font-weight\', \'bold\').attr(\'font-size\', 26).attr(\'fill\', d => d.percent > 650 ? "#fff" : "#000").text(x => x.escanhos);\n    }
1,\n    drawPie(id, data, frac) {\n      const size = this.getSize(id);\n      if (!size) return;\n      let d = data;\n      const totalVotes = d3.sum(d, x => x.votos);\n      if (frac === 1) d = data.slice(0, 5);\n      if (frac === 2) d = data.slice(5);\n      const svg = this.createSvg(id, size.width, 100);\n      const s = this.createScales(d, size.width, 100);\n      const g = svg.selectAll(\'g.partido\').data(d).enter().append(\'g\').attr(\'class\', \'partido\').attr(\'transform\', x => `translate(${s.x(x.siglas) + s.x.bandwidth() / 2},0)`);\n      g.append(\'text\').attr(\'y\', 20).attr(\'font-size\', 14).attr(\'text-anchor\', \'middle\').attr(\'font-weight\', \'bold\').text(x => this.sigla(x.siglas));\n      g.append(\'text\').attr(\'y\', 40).attr(\'font-size\', 13).attr(\'font-weight\', \'bold\').attr(\'text-anchor\', \'middle\').text(x => (x.votos / totalVotes * 100).toFixed(1) + \'%\');\n      g.append(\'text\').attr(\'y\', 58).attr(\'font-size\', 11).attr(\'fill\', \'#555\').attr(\'text-anchor\', \'middle\').text(x => x.votos.toLocaleString(\'es-ES\'));\n    },\n    draw_datos() {\n      if (!this.state.data?.[this.state.anho]?.[this.state.territorio] || !this.state.data?.elecciones_anteriores?.[this.state.territorio]) return;\n      const size = this.getSize(\'datos\');\n      if (!size) return;\n      const svg = this.createDatosSvg(size.width, 120);\n      const d26 = this.state.data.elecciones_actuales[this.state.territorio].general;\n      const d23 = this.state.data.elecciones_anteriores[this.state.territorio].general;\n      const cols = 6;\n      const colW = size.width / cols;\n      const x = i => colW * i + colW / 2;\n      const y1 = 30,\n        y2 = 65,\n        y3 = 95;\n      const anho_actual = this.state.datosConsulta.anho_actual;\n      const anho_anterior = this.state.datosConsulta.anho_anterior;\n      svg.append(\'rect\').attr(\'x\', 0).attr(\'y\', y2 - 18).attr(\'width\', size.width).attr(\'height\', 28).attr(\'fill\', \'#eee\');\n      svg.append(\'rect\').attr(\'x\', 0).attr(\'y\', y3 - 18).attr(\'width\', size.width).attr(\'height\', 28).attr(\'fill\', \'#eee\');\n      svg.append(\'text\').attr(\'x\', x(0)).attr(\'y\', y1).attr(\'font-weight\', \'bold\').text(\'\');\n      svg.append(\'text\').attr(\'x\', x(1)).attr(\'y\', y1).text(\'Escrutado\');\n      svg.append(\'text\').attr(\'x\', x(2)).attr(\'y\', y1).text(\'Abstención\');\n      svg.append(\'text\').attr(\'x\', x(3)).attr(\'y\', y1).text(\'Blanco\');\n      svg.append(\'text\').attr(\'x\', x(4)).attr(\'y\', y1).text(\'Nulos\');\n      svg.append(\'text\').attr(\'x\', x(5)).attr(\'y\', y1).text(\'Escaños\');\n      svg.append(\'text\').attr(\'x\', x(0)).attr(\'y\', y2).attr(\'font-weight\', \'bold\').text(anho_actual);\n      svg.append(\'text\').attr(\'x\', x(1)).attr(\'y\', y2).text(d26.percent_escrutado.toFixed(2) + \' %\');\n      svg.append(\'text\').attr(\'x\', x(2)).attr(\'y\', y2).text(d26.percent_abstencion.toFixed(2) + \' %\');\n      svg.append(\'text\').attr(\'x\', x(3)).attr(\'y\', y2).text(d26.percent_blanco.toFixed(2) + \' %\');\n      svg.append(\'text\').attr(\'x\', x(4)).attr(\'y\', y2).text(d26.percent_nulos.toFixed(2) + \' %\');\n      svg.append(\'text\').attr(\'x\', x(5)).attr(\'y\', y2).text(d26.escanhos);\n      svg.append(\'text\').attr(\'x\', x(0)).attr(\'y\', y3).attr(\'font-weight\', \'bold\').text(anho_anterior);\n      svg.append(\'text\').attr(\'x\', x(1)).attr(\'y\', y3).text(\'100.00 %\');\n      svg.append(\'text\').attr(\'x\', x(2)).attr(\'y\', y3).text(d23.percent_abstencion.toFixed(2) + \' %\');\n      svg.append(\'text\').attr(\'x\', x(3)).attr(\'y\', y3).text(d23.percent_blanco.toFixed(2) + \' %\');\n      svg.append(\'text\').attr(\'x\', x(4)).attr(\'y\', y3).text(d23.percent_nulos.toFixed(2) + \' %\');\n      svg.append(\'text\').attr(\'x\', x(5)).attr(\'y\', y3).text(d23.escanhos);\n    },\n    showTooltip(e, d) {\n      const t = document.getElementById(\'tooltip\');\n      const r = e.target.getBoundingClientRect();\n      t.textContent = d.siglas;\n      t.style.left = r.left + r.width / 2 + \'px\';\n      t.style.top = r.top - 30 + \'px\';\n      t.classList.add(\'show\');\n    },\n    hideTooltip() {\n      document.getElementById(\'tooltip\').classList.remove(\'show\');\n    },\n    draw_all() {\n      const data = this.state.data?.[this.state.anho]?.[this.state.territorio]?.recuento_partidos;\n      this.draw_datos();\n      if (!data || !data.length || data[0].codigo == "0000") {\n        const anho_actual = this.state.datosConsulta.anho_actual || \'2026\';\n        const anho_anterior = this.state.datosConsulta.anho_anterior || \'2022\';\n        const anho = this.state.anho === \'elecciones_actuales\' ? anho_actual : anho_anterior;\n        [\'grafica\', \'grafica_1\', \'grafica_2\'].forEach(id =>
1 {\n          const s = this.getSize(id);\n          if (!s) return;\n          const svg = this.createSvg(id, s.width, s.height);\n          svg.append(\'text\').attr(\'x\', s.width / 2).attr(\'y\', s.height / 2).attr(\'text-anchor\', \'middle\').attr(\'font-size\', 24).attr(\'font-weight\', \'bold\').attr(\'fill\', \'#666\').text(`SIN DATOS ${anho}`);\n        });\n        [\'pie\', \'pie_1\', \'pie_2\'].forEach(id => {\n          const s = this.getSize(id);\n          if (!s) return;\n          const svg = this.createSvg(id, s.width, 100);\n        });\n        return;\n      }\n      [\'grafica\', \'grafica_1\', \'grafica_2\'].forEach((id, i) => {\n        const s = this.getSize(id);\n        if (!s) return;\n        const yScaleGlobal = this.createYScaleGlobal(data, s.height);\n        this.drawBars(this.createSvg(id, s.width, s.height), data, s, i, yScaleGlobal, id);\n      });\n      this.drawPie(\'pie\', data, 0);\n      this.drawPie(\'pie_1\', data, 1);\n      this.drawPie(\'pie_2\', data, 2);\n    },\
1n    color(partido) {\n      const colores = {\n        "PSOE": "#dc0612",\n        "PSOE-A": "#dc0612",\n        "PP": "#01549f",\n        "VOX": "#53d403",\n        "AHORA REPÚBLICAS": "#f7b93f",\n        "AHORA REPÚBLICAS (ERC-EH BILDU-BNG-ARA MÉS)": "#f7b93f",\n        "JUNTS": "#00B4C4",\n        "JUNTS-UE": "#00B4C4",\n        "CEUS": "#297f41",\n        "PODEMOS": "#72156e",\n        "PODEMOS-IU": "#72156e",\n        "PODEMOS ALIAZA VERDE": "#72156e",\n        "PODEMOS -AV": "#72156e",\n        "P-IU-AV": "#72156e",\n        "SUMAR": "#BB2649",\n        "Cs": "#ff6419",\n        "S.A.L.F": "#9FA2B2",\n        "SALF": "#9FA2B2",\n        "PACMA": "#00d084",\n        "PorA": "#f8c565",\n        "ADELANTE ANDALUCÍA": "#009076",\n        "AA": "#009076"\n      };\n      return colores[partido] || \'#\' + Math.floor(Math.random() * Math.pow(2, 32) ^ 0xffffff).toString(16).substr(-6);\n    },\n    sigla(partido) {\n      const siglas = {\n        "P.S.O.E.": "PSOE",\n        "PARTIDO AUTÓNOMOS": "PA",\n        "RECORTES CERO": "RC",\n        "ADELANTE ANDALUCÍA-ANDALUCISTAS": "AA-A",\n        "ADELANTE ANDALUCÍA-ANDALUCISTAS": "AA-A",\n        "ANDALUCISTAS-PA": "A-PA",\n        "ANDALUCISTAS - PA": "A-PA",\n        "ADELANTE ANDALUCÍA": "AA",\n        "AHORA REPÚBLICAS": "A.R.",\n        "AGRUPACIÓN DE ELECTORES SE ACABÓ LA FIESTA": "A.E.S.A.F",\n        "AHORA REPÚBLICAS (ERC-EH BILDU-BNG-ARA MÉS)": "A.R.",\n        "PODEMOS ALIANZA VERDE": "P-AV",\n        "PODEMOS -AV": "P-AV",\n        "PODEMOS-IU-AV": "P-IU-AV",\n        "COALICIÓN ARAGONESA": "CA",\n        "IU- MOVIMIENTO SUMAR": "IU-MS",\n        "ESCAÑOS EN BLANCO": "EB",\n        "MUNDO+JUSTO": "M+J",\n        "ESPAÑA VACIADA": "E.V.",\n        "CS-TÚ ARAGÓN": "CS-TU",\n        "FE de las JONS": "FE Jons",\n        "PCAS-TC-Recortes Cero": "PCAS-TC-RC"\n      };\n      return siglas[partido] || partido;\n    }\n  },\n  FlowCurrent: {\n    mounted() {\n      this.el.style.transition = "transform 1.2s ease-in-out, fill 0.8s";\n    },\n    updated() {\n      let x = parseFloat(this.el.dataset.x);\n      let y = parseFloat(this.el.dataset.y);\n\n      // efecto Bezier-like: ligera curva en movimiento\n      let cx = x + (Math.random() - 0.5) * 20;\n      let cy = y + (Math.random() - 0.5) * 10;\n      this.el.setAttribute("x", cx);\n      this.el.setAttribute("y", cy);\n    }\n  },\n  HorizontalScroll: {\n    mounted() {\n      if (window.innerWidth > 768) return; // ❌ No hacer nada en escritorio\n      const id = `#${this.el.dataset.id}`;\n      const el = this.el;\n      let atEnd = false;\n      el.addEventListener("scroll", () => {\n        const scrollLeft = el.scrollLeft;\n        const scrollWidth = el.scrollWidth;\n        const clientWidth = el.clientWidth;\n        if (scrollLeft + clientWidth >= scrollWidth - 0) {\n          if (!atEnd) {\n            this.pushEventTo(id, "scroll_end");\n            atEnd = true;\n          }\n        } else {\n          atEnd = false;\n        }\n      });\n    }\n  },\n  CarruselTrack: {\n    mounted() {\n      this.page = parseInt(this.el.dataset.page);\n    },\n    updated() {\n      const page = parseInt(this.el.dataset.page);\n      const perPage = parseInt(this.el.dataset.perPage);\n      const elemento = document.getElementById(\'track-socias-opinion\') || document.getElementById(\'track-relacionadas-live\').parentNode;\n      const ancho_total_visible = elemento.offsetWidth;\n\n      //const offset = -page * perPage * itemWidth\n      const offset = -page * ancho_total_visible;\n      const track = this.el.querySelector(".items-track");\n      this.page = page;\n      if (track) {\n        if (window.innerWidth <= 768) return; // ❌ No hacer nada en movil  \n        track.style.transform = `translateX(${offset}px)`;\n      }\n    }\n  },\n  LazyLoadAd: {\n    mounted() {\n      var modulo_publi = this.el.dataset.name;\n      let alreadyTriggered = false;\n      const handleVisible = () => {\n        //if (alreadyTriggered) return\n        alreadyTriggered = true;\n\n        // Verificar locks y estado de actualización de contenido\n        if (publi_lock || contenidoupdating) {\n          if (!publi_pendientes.includes(modulo_publi)) {\n            publi_pendientes.push(modulo_publi);\n          }\n          return;\n        }\n        var slug1 = "";\n        var slug2 = "";\n        var loc = location.pathname.split(\'/\').slice(1);\n        if (loc[0]) {\n          slug1 = loc[0];\n        }\n        if (loc[1]) {\n          slug2 = loc[1];\n        }\n        if (loc[0] == "sin-publicar") {\n          slug1 = loc[1];\n          slug2 = loc[2];\n        }\n        var nodo = document.getElementById("nodo-contenido");\n        if (nodo) {\n          nodo = nodo.getAttribute(\'data-nodo\');\n        }\n        this.pushEventTo(this.el, "ad_visible", {\n          modulo: modulo_publi,\n          slug1: slug1,\n          slug2: slug2,\n          mobil: window.innerWidth > 767 ? false : true,\n          nodo: nodo,\n          ip: document.body.getAttribute(\'data-ip\')\n        });\n        observer.disconnect();\n      };\n      const observer = new IntersectionObserver(([entry]) => {\n        if (entry.isIntersecting || entry.intersectionRatio > 0) {\n          handleVisible();\n        }\n      }, {\n        rootMargin: "200px"\n      });\n      observer.observe(this.el);\n\n      // comprobación inicial\n      const rect = this.el.getBoundingClientRect();\n      const inView = rect.top < window.innerHeight && rect.bottom > 0;\n      if (inView) {\n        handleVisible();\n      }\n      this.handleEvent(`update_ad_${modulo_publi}`, anuncio =>
1 {\n        if (this.el.dataset.name == anuncio.modulo) {\n          var mobil = window.innerWidth > 767 ? false : true;\n          let modulo = this.el;\n          if (!modulo) return;\n\n          // 1. Añadir clase según el tipo de anuncio\n          if (anuncio.maquetacion && anuncio.maquetacion.no_publicidad === "no_publicidad") {\n            modulo.classList.add(\'bloque-activo\');\n          } else {\n            modulo.classList.add(\'anuncio-activo\');\n          }\n\n          // 2. Vaciar el contenido del módulo\n          modulo.innerHTML = "";\n\n          // 3. Atributo "phx-update"\n          modulo.setAttribute(\'phx-update\', \'ignore\');\n\n          // 4. Si hay script, usar postscribe (si está disponible)\n          if (anuncio.script && anuncio.script.length > 10) {\n            if (typeof (postscribe_min_default()) !== "undefined") {\n              try {\n                postscribe_min_default()(modulo, anuncio.script, {\n                  error: function (e) {\n                    console.warn(\'Ad failed to load:\', e);\n                  }\n                });\n              } catch (err) {\n                console.log("Error al insertar script");\n              }\n            } else {\n              console.warn("postscribe no está definido");\n            }\n          } else {\n            // 5. Si hay HTML personalizado\n            if (anuncio.html && anuncio.html.length > 1) {\n              const div = document.createElement(\'div\');\n              div.classList.add(\'html-anun\');\n              div.innerHTML = anuncio.html;\n              modulo.appendChild(div);\n            } else {\n              // 6. Si no hay HTML ni script, construir enlace de anuncio\n              const redireccion = anuncio.url_redireccion || "false";\n              const a = document.createElement(\'a\');\n              a.dataset.anun = anuncio.id;\n              a.dataset.click = redireccion;\n              a.href = `/ir_anuncio/${anuncio.id}/${mobil}`;\n              a.target = "_blank";\n              a.setAttribute(\'aria-label\', \'publicidad\');\n              a.classList.add(\'anuncio-link\');\n              modulo.appendChild(a);\n\n              // 7. Imagen o video\n              if (anuncio.imagen) {\n                const ext = anuncio.imagen.split(\'.\').pop().split(\'?\').shift();\n                if (ext === "mp4") {\n                  const video = document.createElement(\'video\');\n                  video.classList.add(\'no-mep\');\n                  video.autoplay = true;\n                  video.muted = true;\n                  video.loop = true;\n                  video.src = anuncio.imagen;\n                  video.alt = a.titulo;\n                  a.appendChild(video);\n                } else {\n                  const img = document.createElement(\'img\');\n                  img.src = anuncio.imagen;\n                  img.alt = anuncio.titulo;\n                  a.appendChild(img);\n                }\n              }\n\n              // 8. Píxel de impresión\n              if (anuncio.url_impresion) {\n                const pixel = document.createElement(\'img\');\n                pixel.classList.add(\'transparent\');\n                pixel.src = anuncio.url_impresion.replace("[timestamp]", +new Date());\n                pixel.alt = "Advertisment";\n                pixel.border = "0";\n                pixel.height = 1;\n                pixel.width = 1;\n                a.appendChild(pixel);\n              }\n            }\n          }\n          //this.el.innerHTML = data.content;\n        }\n        popup();\n      });\n    }\n  },\n  MapLibreFormMap: {\n    mounted() {\n      if (!window.maplibregl) {\n        Promise.all([this.loadCSS("https://unpkg.com/[email protected]/dist/maplibre-gl.css"), this.loadJS("https://unpkg.com/[email protected]/dist/maplibre-gl.js")]).then(() => this.initMap()).catch(err => console.error("Error loading MapLibre:", err));\n      } else {\n        this.initMap();\n      }\n    },\n    updated() {\n      this.initMap();\n    },\n    loadCSS(url) {\n      return new Promise((resolve, reject) => {\n        if (document.querySelector(`link[href="${url}"]`)) return resolve();\n        const link = document.createElement("link");\n        link.rel = "stylesheet";\n        link.href = url;\n        link.onload = resolve;\n        link.onerror = reject;\n        document.head.appendChild(link);\n      });\n    },\n    loadJS(url) {\n      return new Promise((resolve, reject) => {\n        if (document.querySelector(`script[src="${url}"]`)) return resolve();\n        const script = document.createElement("script");\n        script.src = url;\n        script.id = "ID_map_script";\n        script.async = true;\n        script.onload = resolve;\n        script.onerror = reject;\n        document.body.appendChild(script);\n      });\n    },\n    initMap() {\n      const lat = parseFloat(this.el.dataset.lat) || 0;\n      const lng = parseFloat(this.el.dataset.lng) || 0;\n      const zoom = parseFloat(this.el.dataset.zoom) || 2;\n      this.map = new maplibregl.Map({\n        container: this.el,\n        style: "https://demotiles.maplibre.org/style.json",\n        style: "https://demotiles.maplibre.org/styles/osm-bright-gl-style/tyle.json",\n        style: "https://tiles.stadiamaps.com/styles/osm_bright.json",\n        center: [lng, lat],\n        zoom: zoom\n      });\n      this.map.addControl(new maplibregl.NavigationControl());\n\n      // 🧷 Crear marcador inicial\n      this.marker = new maplibregl.Marker({\n        draggable: true\n      }).setLngLat([lng, lat]).addTo(this.map);\n\n      // 🛰️ Actualizar marcador y enviar evento cuando se mueve o hace zoom\n      this.map.on("moveend", () => this.handleMapMove());\n      this.map.on("zoomend", () => this.handleMapMove());\n      this.map.on("click", e => {\n        const {\n          lng,\n          lat\n        } = e.lngLat;\n        this.marker.setLngLat([lng, lat]);\n\n        // Emitir evento a LiveView si lo deseas\n        this.pushEvent("map_moved", {\n          lat,\n          lng,\n          zoom: Math.round(this.map.getZoom())\n        });\n      });\n    },\n    handleMapMove() {\n      const center = this.map.getCenter();\n      const zoom = this.map.getZoom();\n\n      // Mover el marcador al nuevo centro\n      this.marker.setLngLat(center);\n\n      // Emitir evento a LiveView\n      this.pushEvent("map_moved", {\n        lat: center.lat,\n        lng: center.lng,\n        zoom: Math.round(zoom)\n      });\n    }\n  },\n  TabHighlight: {\n    mounted() {\n      this.startBlinking();\n    },\n    updated() {\n      this.startBlinking();\n    },\n    destroyed() {\n      // Limpieza de seguridad\n      if (this.blinkInterval) {\n        clearInterval(this.blinkInterval);\n      }\n    },\n    startBlinking() {\n      if (document.hasFocus()) {\n        return;\n      }\n      let originalTitle = document.title;\n      let newTitle = this.el.dataset.title || "Nueva actualización";\n\n      // Limpia cualquier intervalo anterior\n      if (this.blinkInterval) {\n        clearInterval(this.blinkInterval);\n      }\n      const blink = () => {\n        document.title = document.title === originalTitle ? newTitle : originalTitle;\n      };\n      this.blinkInterval = setInterval(blink, 1000);\n\n      // Detener cuando se vuelve a enfocar la pestaña\n      window.addEventListener("focus", () => {\n        clearInterval(this.blinkInterval);\n        document.title = originalTitle;\n      }, {\n        once: true\n      });\n    }\n  },\n  CoordinaContenido: {\n    mounted() {\n      window.addEventListener(\'contenido-actualizando\', () => {\n        contenidoupdating = true;\n      });\n      window.addEventListener(\'contenido-estabilizado\', () => {\n        contenidoupdating = false;\n        // Reanudar procesamiento de publicidad después de breve delay\n        setTimeout(() =>
1 {\n          if (!publi_lock) {\n            reubicar_publis(true);\n          }\n        }, 200);\n      });\n    }\n  },\n  LazyRelacionadas: {\n    mounted() {\n      const observer = new IntersectionObserver((entries, observer) => {\n        entries.forEach(entry => {\n          if (entry.isIntersecting || entry.intersectionRatio > 0) {\n            //console.log("RELACIONADAS");\n            // Notificar inicio de actualización de contenido\n            window.dispatchEvent(new CustomEvent(\'contenido-actualizando\'));\n            this.pushEvent("cargar-relacionadas");\n            this.pushEvent("cargar-portadilla");\n\n            // Notificar fin de actualización después de procesamiento\n            setTimeout(() => {\n              window.dispatchEvent(new CustomEvent(\'contenido-estabilizado\'));\n            }, 300);\n            observer.unobserve(entry.target); // Solo una vez\n          }\n        });\n      }, {\n        root: null,\n        rootMargin: "150px",\n        // 100px antes de entrar en vista\n        threshold: 0.01\n      });\n      observer.observe(this.el);\n    },\n    updated() {\n      apanhos_publi_bloque_tema();\n    }\n  },\n  LazyPortadilla: {\n    mounted() {\n      const observer = new IntersectionObserver((entries, observer) => {\n        entries.forEach(entry => {\n          if (entry.isIntersecting || entry.intersectionRatio > 0) {\n            //console.log("PORTADILLA");\n            observer.unobserve(entry.target); // Solo una vez\n          }\n        });\n      }, {\n        root: null,\n        rootMargin: "150px",\n        // 100px antes de entrar en vista\n        threshold: 0.01\n      });\n      observer.observe(this.el);\n    }\n  },\n  MenuPosicion: {\n    mounted() {\n      ajuste_menu_movil();\n    },\n    updated() {\n      ajuste_menu_movil();\n    }\n  },\n  AutoClearFlash: {\n    mounted() {\n      let ignoredIDs = ["client-error", "server-error"];\n      if (ignoredIDs.includes(this.el.id)) return;\n      let hideElementAfter = 3000; // ms\n      let clearFlashAfter = hideElementAfter + 500; // ms\n\n      // first hide the element\n      setTimeout(() => {\n        this.el.style.opacity = 0;\n      }, hideElementAfter);\n\n      // then clear the flash\n      setTimeout(() => {\n        this.pushEvent("lv:clear-flash");\n      }, clearFlashAfter);\n    }\n  },\n  ApanhoCrop: {\n    mounted() {\n      apanho_crop();\n      console.log("CROP");\n    },\n    updated() {\n      apanho_crop();\n      console.log("CROP");\n    },\n    beforeUpdate() {},\n    destroyed() {},\n    disconnected() {},\n    reconnected() {}\n  },\n  ApanhosArticulo: {\n    mounted() {\n      ejecutados_embebidos = false;\n      reubicar_resumenes_articulo();\n      lanzar_codigos_embebidos();\n      apanhos_imagenes_articulos();\n      //reubicar_publis();\n      esperarHastaQueExistaAlturaLimitados(() => {\n        ejecutados_limitados = false;\n        limitados();\n      });\n      copiar_acortados();\n      lanzar_scripts();\n      scroll_into_id();\n      document.addEventListener("scroll", processScroll);\n    },\n    updated() {\n      //console.log("Articulo UPDATED")\n      ejecutados_embebidos = false;\n      apanhos_imagenes_articulos();\n      //lanzar_codigos_embebidos();\n      reubicar_resumenes_articulo();\n      //reubicar_publis(true);\n      lanzar_scripts();\n      ejecutados_embebidos = true;\n      document.addEventListener("scroll", processScroll);\n      esperarHastaQueExistaAlturaLimitados(() => {\n        ejecutados_limitados = false;\n        limitados();\n      });\n      apanhos_publi_bloque_tema();\n    }\n  },\n  ApanhosComentarios: {\n    mounted() {},\n    updated() {\n      recortar_comentarios();\n      scroll_into_id(true);\n    }\n  },\n  SwiperGalerias: {\n    updated() {\n      swiper_galeria();\n      swiper_galeria_modal();\n    },\n    mounted() {\n      swiper_galeria();\n      swiper_galeria_modal();\n    }\n  },\n  BorrarTooltips: {\n    updated() {\n      setTimeout(() => {\n        document.querySelector(\'.temptooltip\').style.display = \'none\';\n      }, 1500);\n    },\n    mounted() {\n      setTimeout(() =>
1 {\n        document.querySelector(\'.temptooltip\').style.display = \'none\';\n      }, 1500);\n    }\n  },\n  EditorSocias: {\n    updated() {\n      $(\'.summernote\').summernote(\'destroy\');\n      $(\'.summernote\').summernote(summerNoteMin);\n    },\n    mounted() {\n      $(\'.summernote\').summernote(\'destroy\');\n      $(\'.summernote\').summernote(summerNoteMin);\n    }\n  },\n  Editor: {\n    updated() {\n      $(\'.summernote\').summernote(\'destroy\');\n      $(\'.summernote\').summernote(summerNoteConf);\n    },\n    mounted() {\n      $(\'.summernote\').summernote(\'destroy\');\n      $(\'.summernote\').summernote(summerNoteConf);\n    }\n  },\n  EditorMinimo: {\n    mounted() {\n      this.initSummerNote();\n    },\n    updated() {\n      this.initSummerNote();\n    },\n    destroyed() {\n      this.destroySummerNote();\n    },\n    initSummerNote() {\n      const element = this.el.querySelector(\'.summernote\');\n      if (element) {\n        let contenido = \'\';\n        if ($(element).data(\'summernote\')) {\n          contenido = $(element).summernote(\'code\');\n        }\n        $(element).summernote(\'destroy\');\n        $(element).summernote(summerNoteMin);\n        if (contenido) {\n          $(element).summernote(\'code\', contenido);\n        }\n      }\n    },\n    destroySummerNote() {\n      const element = this.el.querySelector(\'.summernote\');\n      if (element && $(element).data(\'summernote\')) {\n        $(element).summernote(\'destroy\');\n      }\n    }\n  },\n  Notificaciones: {\n    mounted() {\n      const hook = this;\n      pushButton = document.querySelector(\'.js-push-btn\');\n      canalesDiv = document.querySelector(\'.canales\');\n      if (\'serviceWorker\' in navigator && \'PushManager\' in window) {\n        navigator.serviceWorker.register(\'/sw.js\').then(function (swReg) {\n          console.log(\'Service Worker registrado\');\n          swRegistration = swReg;\n          initializeNotificationsUI(hook);\n          swRegistration.pushManager.getSubscription().then(function (subscription) {\n            hook.pushEvent("suscrito", subscription);\n          });\n        }).catch(function (error) {\n          //console.error(\'Service Worker Error\', error);\n          console.error(\'Service Worker Error\');\n          console.log(error.message);\n          console.log(error.name);\n          console.log(error.stack);\n        });\n      } else {\n        console.log("NO soportado");\n      }\n      window.addEventListener(\'online\', handleConnection);\n      window.addEventListener(\'offline\', handleConnection);\n      /*\n        console.log(Notification);\n        if(Notification.permission === "default") {\n        console.log("permiso???");\n           Notification.requestPermission();\n         //swRegistration.pushManager.getSubscription()\n        } else {\n        console.log("permiso si.....???");\n         }\n      */\n    }\n  },\n  CookieHook: {\n    mounted() {\n      this.handleEvent(\'cookie_portada\', async params => {\n        try {\n          await fetch(\'api/cookie_portada\', {\n            method: \'post\',\n            body: JSON.stringify(params),\n            headers: {\n              \'Content-Type\': \'application/json\'\n            }\n          });\n        } catch (err) {\n          alert(err.message ?? "An error occurred");\n        }\n      });\n    }\n  },\n  AudioRadioSeleccionar: {\n    destroyed() {},\n    mounted() {\n      //document.querySelector(\'#reproductor_radio\').classList.remove("activo")\n      audio_origen = "directo";\n      if (audio.paused) {\n        liveSocket.hooks.AudioPlayer.datos_audio();\n      }\n      ;\n      this.anhadir_eventos();\n    },\n    anhadir_eventos() {\n      var viewportWidth = window.innerWidth || document.documentElement.clientWidth;\n      if (viewportWidth < 769) {\n        var hoy = new Date().getDay();\n        this.toggleDay(hoy);\n      }\n    },\n    toggleDay(day) {\n      var days = document.getElementById("days");\n      var grid = document.getElementById("grid");\n      var labels = document.getElementsByClassName("day");\n      switch (day) {\n        case 1:\n          grid.style.setProperty("grid-template-columns", "3em 10px calc(100% - 3em - 10px) repeat(6, 0)");\n          days.style.setProperty("grid-template-columns", "3em 10px calc(100% - 3em - 10px) repeat(6, 0)");\n          break;\n        case 2:\n          days.style.setProperty("grid-template-columns", "3em 10px 0 calc(100% - 3em - 10px) 0 0 0 0 0");\n          grid.style.setProperty("grid-template-columns", "3em 10px 0 calc(100% - 3em - 10px) 0 0 0 0 0");\n          break;\n        case 3:\n          days.style.setProperty("grid-template-columns", "3em 10px 0 0 calc(100% - 3em - 10px) 0 0 0 0");\n          grid.style.setProperty("grid-template-columns", "3em 10px 0 0 calc(100% - 3em - 10px) 0 0 0 0");\n          break;\n        case 4:\n          days.style.setProperty("grid-template-columns", "3em 10px 0 0 0 calc(100% - 3em - 10px) 0 0 0");\n          grid.style.setProperty("grid-template-columns", "3em 10px 0 0 0 calc(100% - 3em - 10px) 0 0 0");\n          break;\n        case 5:\n          days.style.setProperty("grid-template-columns", "3em 10px 0 0 0 0 calc(100% - 3em - 10px) 0 0");\n          grid.style.setProperty("grid-template-columns", "3em 10px 0 0 0 0 calc(100% - 3em - 10px) 0 0");\n          break;\n        case 6:\n          days.style.setProperty("grid-template-columns", "3em 10px 0 0 0 0 0 calc(100% - 3em - 10px) 0");\n          grid.style.setProperty("grid-template-columns", "3em 10px 0 0 0 0 0 calc(100% - 3em - 10px) 0");\n          break;\n        default:\n          days.style.setProperty("grid-template-columns", "3em 10px  repeat(6, 0) calc(100% - 3em - 10px)");\n          grid.style.setProperty("grid-template-columns", "3em 10px  repeat(6, 0) calc(100% - 3em - 10px)");\n          break;\n      }\n      for (let i = 0; i < labels.length;
1 i++) {\n        labels[i].style.setProperty("height", "0px");\n        labels[i].style.setProperty("visibility", "hidden");\n      }\n      labels[day - 1].style.setProperty("height", "auto");\n      labels[day - 1].style.setProperty("visibility", "visible");\n    }\n  },\n  ListadoRadio: {\n    mounted() {\n      var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n      if (w > 768) {\n        document.querySelector(\'#reproductor_radio\').classList.add("activo");\n        document.querySelector(\'body\').classList.add("radio");\n        document.querySelector(\'body\').classList.add("overflow_m");\n      }\n    }\n  },\n  AudioSeleccionar: {\n    disconnected() {\n      document.querySelector(\'#reproductor_radio\').classList.remove("activo");\n      document.querySelector(\'body\').classList.remove("radio");\n      document.querySelector(\'body\').classList.remove("overflow_m");\n      document.querySelector(\'.play-podcast\').style.display = \'none \';\n      document.querySelector(\'body\').classList.remove("overflow");\n      if (audio.paused) {\n        audio_origen = "recomendacion";\n        liveSocket.hooks.AudioPlayer.datos_audio();\n      }\n    },\n    destroyed() {\n      document.querySelector(\'#reproductor_radio\').classList.remove("activo");\n      document.querySelector(\'body\').classList.remove("radio");\n      document.querySelector(\'body\').classList.remove("overflow_m");\n      document.querySelector(\'.play-podcast\').style.display = \'none \';\n      document.querySelector(\'body\').classList.remove("overflow");\n      if (audio.paused) {\n        audio_origen = "recomendacion";\n        liveSocket.hooks.AudioPlayer.datos_audio();\n      }\n    },\n    updated() {},\n    mounted() {\n      const ua = navigator.userAgent.toLowerCase();\n      const isTelegram = ua.includes(\'telegram\');\n      const isMovileSafari = ua.includes(\'mobile safari\');\n      audio_origen = "podcast";\n      document.querySelector(\'.podcast-titulo\').innerText = document.getElementById(\'audio-titulo\').innerText;\n      document.querySelector(\'.play-podcast\').style.display = \'block\';\n      document.querySelector(\'.play-podcast\').addEventListener(\'click\', event => {\n        this.seleccionar();\n      });\n      document.getElementById("podcast-radio-bot").src = document.getElementById("seleccionar").src;\n      document.querySelector(\'#reproductor_radio\').classList.add("activo");\n      document.querySelector(\'body\').classList.add("radio");\n      document.querySelector(\'body\').classList.add("overflow_m");\n      document.querySelector(\'body\').classList.remove("overflow");\n      if (audio.paused) {\n        liveSocket.hooks.AudioPlayer.datos_audio();\n      }\n      document.querySelector(\'#reproductor_radio\').classList.add("activo");\n    },\n    seleccionar() {\n      audio_origen = "podcast";\n      liveSocket.hooks.AudioPlayer.audio_reproducir();\n    }\n  },\n  AudioPlayer: {\n    mounted() {\n      //para que no se cuelque el Telegram...\n      document.addEventListener("visibilitychange", () => {\n        if (document.hidden) {\n          window.audioPlayingOnHide = audio && !audio.paused;\n        } else if (window.audioPlayingOnHide && audio && audio.paused) {\n          audio.play().catch(() => {});\n        }\n      });\n      document.querySelector(\'.play-button.play\').addEventListener(\'click\', event => {\n        if (this.isRestrictedEnv()) {\n          this.mostrarAvisoSalida();\n          return;\n        }\n        if (audio_origen == "podcast" || audio_origen == "recomendacion") {\n          this.audio_reproducir();\n        } else {\n          this.play_directo();\n        }\n      });\n      document.querySelector(\'.play-directo\').addEventListener(\'click\', event => {\n        this.play_directo();\n      });\n      document.querySelector(\'.play-button.pause\').addEventListener(\'click\', event => {\n        this.pausar();\n      });\n      document.querySelector(\'.mute-button.mute\').addEventListener(\'click\', event => {\n        this.mutear();\n      });\n      document.querySelector(\'.mute-button.unmute\').addEventListener(\'click\', event => {\n        this.unmutear();\n      });\n      document.querySelector(\'.hacia-atras\').addEventListener(\'click\', event => {\n        this.posicion(-10);\n      });\n      document.querySelector(\'.hacia-delante\').addEventListener(\'click\', event => {\n        this.posicion(10);\n      });\n      audio_position.addEventListener("change", event => {\n        audio.currentTime = audio_position.value;\n        document.querySelector(\'.momento\').innerText = segundos_a_string(audio.currentTime);\n      });\n      this.datos_audio();\n    },\n    isTelegram() {\n      const ua = navigator.userAgent || "";\n      return /Telegram/i.test(ua);\n    },\n    isWebView() {\n      const ua = navigator.userAgent || "";\n\n      // Android WebView típico\n      const isAndroidWebView = /wv|WebView/i.test(ua);\n\n      // iOS WebView (no Safari)\n      const isIOSWebView = /iPhone|iPad/.test(ua) && !/Safari/i.test(ua);\n      return isAndroidWebView || isIOSWebView;\n    },\n    isRestrictedEnv() {\n      //return true;\n      return this.isTelegram() || this.isWebView();\n    },\n    mostrarAvisoSalida() {\n      const modal = document.getElementById("aviso-telegram");\n      const link = document.getElementById("abrir-navegador");\n\n      // URL actual\n      link.href = window.location.href;\n      modal.classList.remove("hidden");\n      document.getElementById("seguir-aqui").onclick = () => {\n        modal.classList.add("hidden");\n        if (audio_origen == "podcast" || audio_origen == "recomendacion") {\n          this.audio_reproducir();\n        } else {\n          this.play_directo();\n        }\n      };\n    },\n    audio_reproducir() {\n      // estado actual antes de cualquier cambio\n      let isResume = audio && audio.src && audio.paused && audio.currentTime > 0;\n      audio.pause();\n      if (audio_origen == "podcast" || audio_origen == "recomendacion") {\n        this.cerrar_datos_directo();\n      }\n\n      // Solo llamar a datos_audio() para nuevas selecciones\n      if (!isResume) {\n        this.datos_audio();\n      }\n\n      // asegurarnos que la duración esté disponible\n      if (audio.duration) {\n        document.querySelector(\'.tiempo\').innerText = segundos_a_string(audio.duration);\n        audio_position.setAttribute("max", audio.duration);\n      }\n      audio.play();\n      document.querySelector(\'.con_sonido\').style.display = \'block\';\n      document.querySelector(\'.play-button.play\').style.display = \'none\';\n      document.querySelector(\'.play-button.pause\').style.display = \'inline-block\';\n    }
1,\n    play_directo() {\n      audio_origen = "directo";\n      this.audio_reproducir();\n    },\n    pausar() {\n      audio.pause();\n      document.querySelector(\'.play-button.play\').style.display = \'inline-block\';\n      document.querySelector(\'.play-button.pause\').style.display = \'none\';\n      document.querySelector(\'.con_sonido\').style.display = \'none\';\n    },\n    mutear() {\n      audio.volume = 0;\n      document.querySelector(\'.mute-button.unmute\').style.display = \'inline-block\';\n      document.querySelector(\'.mute-button.mute\').style.display = \'none\';\n      document.querySelector(\'.con_sonido\').style.display = \'none\';\n    },\n    unmutear() {\n      //audio.volume = this.range.value/100;\n      audio.volume = 50 / 100;\n      document.querySelector(\'.mute-button.mute\').style.display = \'inline-block\';\n      document.querySelector(\'.mute-button.unmute\').style.display = \'none\';\n      document.querySelector(\'.con_sonido\').style.display = \'block\';\n    },\n    datos_audio() {\n      document.querySelector(\'#reproductor_radio\').classList.add(audio_origen);\n      switch (audio_origen) {\n        case "recomendacion":\n          audio = document.getElementById("seleccion-radio");\n          document.querySelector(\'.modo\').innerText = "Recomendación";\n          document.querySelector(\'.sonando1\').innerText = document.querySelector(\'.seleccion-titulo\').innerText;\n          document.querySelector(\'.sonando2\').innerText = document.querySelector(\'.seleccion-tema\').innerText;\n          this.control_tiempo();\n          break;\n        case "podcast":\n          audio = document.getElementById("podcast-radio-bot");\n          document.querySelector(\'.modo\').innerText = "Podcast";\n          document.querySelector(\'.sonando1\').innerText = document.getElementById(\'audio-titulo\').innerText;\n          document.querySelector(\'.sonando2\').innerText = document.querySelector(\'#audio-tema\').innerText;\n          document.querySelector(\'#RadioBot .imagen\').innerHTML = "";\n          document.querySelector(\'#RadioBot .imagen\').appendChild(document.querySelector(\'#articulo-contenido .cabecera .responsively-lazy\').cloneNode(true));\n          this.control_tiempo();\n          document.querySelector(\'.podcast-titulo\').innerText = document.getElementById(\'audio-titulo\').innerText;\n          document.querySelector(\'.play-podcast\').style.display = \'block\';\n          document.querySelector(\'.play-podcast\').addEventListener(\'click\', event => {\n            this.seleccionar();\n          });\n          document.getElementById("podcast-radio-bot").src = document.getElementById("seleccionar").src;\n          document.querySelector(\'#reproductor_radio\').classList.add("activo");\n          document.querySelector(\'body\').classList.add("radio");\n          document.querySelector(\'body\').classList.add("overflow_m");\n          document.querySelector(\'body\').classList.remove("overflow");\n          document.querySelector(\'#reproductor_radio\').classList.add("activo");\n          break;\n        default:\n          //audio = document.getElementById("directo-radio-bot");\n          //document.querySelector(\'.modo\').innerText = "Radio 24h";\n          //document.querySelector(\'.sonando1\').innerText = "";\n          //document.querySelector(\'.sonando2\').innerText = "";\n          //\n          audio = document.getElementById("seleccion-radio");\n          document.querySelector(\'.modo\').innerText = "Recomendación";\n          document.querySelector(\'.sonando1\').innerText = document.querySelector(\'.seleccion-titulo\').innerText;\n          document.querySelector(\'.sonando2\').innerText = document.querySelector(\'.seleccion-tema\').innerText;\n          this.control_tiempo();\n      }\n    },\n    datos_directo() {\n      socket_radio_bot = new WebSocket(radiobot_api);\n      socket_radio_bot.onopen = function (e) {\n        socket_radio_bot.send(JSON.stringify({\n          "subs": {\n            "station:salto": {}\n          }\n        }));\n      };\n      socket_radio_bot.onmessage = function (event) {\n        const data = JSON.parse(event.data);\n        const np = data?.pub?.data?.np || null;\n        if (np) {\n          audio_momento = np.now_playing.elapsed / np.now_playing.duration * 100 + "%";\n          document.querySelector(\'.sonando1\').innerText = np.now_playing.playlist.split(" - ")[1] || "Continuidad";\n          document.querySelector(\'.sonando2\').innerText = np.now_playing.song.text + " | ";\n          audio_progreso.style.setProperty("--progreso", audio_momento);\n          audio_position.value = np.now_playing.elapsed;\n          audio_position.setAttribute("max", np.now_playing.duration);\n          document.querySelector(\'.tiempo\').innerText = segundos_a_string(np.now_playing.duration);\n          document.querySelector(\'.momento\').innerText = segundos_a_string(np.now_playing.elapsed);\n        }\n      };\n    }
1,\n    cerrar_datos_directo() {\n      if (socket_radio_bot.readyState == WebSocket.OPEN) socket_radio_bot.close();\n    },\n    control_tiempo() {\n      /*\n      audio.onloadedmetadata = function(e) {\n        document.querySelector(\'.tiempo\').innerText =\n          segundos_a_string(audio.duration);\n        audio_position.setAttribute("max", audio.duration)\n      };\n      audio_momento = 0;\n      audio.addEventListener(\'timeupdate\', () => {\n        // actualizar progreso UI\n        audio_position.value = audio.currentTime;\n        audio_momento = audio.currentTime / audio.duration * 100 + "%";\n        audio_progreso.style.setProperty("--progreso", audio_momento);\n      });\n      */\n      if (audio.duration) {\n        document.querySelector(\'.tiempo\').innerText = segundos_a_string(audio.duration);\n        audio_position.setAttribute("max", audio.duration);\n      }\n      setInterval(() => {\n        if (!audio.paused && audio.duration) {\n          document.querySelector(\'.momento\').innerText = segundos_a_string(audio.currentTime);\n          audio_momento = audio.currentTime / audio.duration * 100 + "%";\n        } else {\n          //document.querySelector(\'.momento\').innerText = "00:00"\n          //audio_momento = 0\n        }\n        audio_position.value = audio.currentTime;\n        audio_progreso.style.setProperty("--progreso", audio_momento);\n      }, 1000);\n    },\n    posicion(t) {\n      audio.currentTime = audio.currentTime + t;\n    }\n  },\n  VidstackHook: {\n    mounted() {\n      let currentEl = this.el;\n      //console.log("VidstackHook mounted");\n      var player = document.querySelector(\'media-player\');\n      //console.log(player);              \n    },\n    beforeUpdate() {},\n    updated() {\n      //console.log("VidstackHook updated");\n    },\n    destroyed() {},\n    disconnected() {},\n    reconnected() {}\n  },\n  ...live_select_min\n};\nlet liveSocket = new LiveSocket(\'/live\', Socket, {\n  hooks,\n  dom: {\n    // make LiveView work nicely with alpinejs\n    onBeforeElUpdated(from, to) {\n      //if (from.__x) {\n      if (from._x_dataStack) {\n        //window.Alpine.clone(from.__x, to);\n        window.Alpine.clone(from, to);\n      }\n    }\n  },\n  params: {\n    _csrf_token: csrfToken\n  }\n});\nfunction esperarHastaQueExistaAlturaLimitados(callback) {\n  const check = () => {\n    const elems = document.querySelectorAll(".limitado");\n    if (!elems.length) {\n      return requestAnimationFrame(check);\n    }\n\n    // Esperar a que scrollHeight y clientHeight sean > 0\n    const listo = [...elems].every(el => el.scrollHeight > 0 && el.clientHeight > 0);\n    if (listo) {\n      callback();\n    } else {\n      requestAnimationFrame(check);\n    }\n  };\n  check();\n}\nwindow.addEventListener("phx:page-loading-start", function (info) {\n  nprogress_default().start();\n  document.querySelector("body").classList.remove("overflow");\n  if (document.querySelector("#menu-bur-contenedor")) {\n    document.querySelector("#menu-bur-contenedor").classList.remove("activo");\n    document.querySelector("#menu-bur-contenedor").classList.remove("scroll-off");\n  }\n  if (document.querySelector("#menu-personal-contenedor")) {\n    document.querySelector("#menu-personal-contenedor").classList.remove("activo");\n  }\n  if (document.querySelector("#menu-admin")) {\n    document.querySelector("#menu-admin").classList.remove("activo");\n  }\n});\nwindow.addEventListener("phx:page-loading-stop", function (info) {\n  //document.querySelector("body").classList.remove("overflow_m");\n  //document.querySelector("body").classList.remove("radio");\n\n  modulos_publi = modulos_publi_iniciales;\n  cambio();\n  cambio_apanhos();\n  apanhos_imagenes_articulos();\n  apanho_crop();\n  reubicar_publis(true);\n  nprogress_default().done();\n  responsivelyLazy.run();\n  ubicacion_banda_inferior();\n  scrollHandler();\n  if ($(\'.twitter-tweet\').length) {\n    //$.getScript(\'//platform.twitter.com/widgets.js\',function(){});\n  }\n  ;\n  scroll_into = true;\n  //scroll_into_id()\n});\nvar scroll_into = true;\nfunction scroll_into_id(parar = false) {\n  if (parar) {\n    if (true) {\n      var id = window.location.hash.substring(1);\n      if (document.getElementById(id)) {\n        if (id.includes("comentario")) {\n          document.querySelector(\'body\').classList.add("overflow");\n          document.querySelector(\'#comentarios\').classList.add("activo");\n        }\n        document.getElementById(id).scrollIntoView({\n          behavior: \'smooth\'\n        });\n      }\n      document.querySelector(\'body\').classList.remove("overflow-hidden");\n      //history.replaceState(null, null, \' \');\n      //history.replaceState(\'\', document.title, window.location.href.split(\'#\')[0]); \n      scroll_into = false;\n    }\n  }\n}
1\n// connect if there are any LiveViews on the page\nliveSocket.connect();\n\n// expose liveSocket on window for web console debug logs and latency simulation:\n// >> liveSocket.enableDebug()\n//liveSocket.enableDebug()\n// >> liveSocket.enableLatencySim(1000)  // enabled for duration of browser session\n// >> liveSocket.disableLatencySim()\nwindow.liveSocket = liveSocket;\n//console.log(liveSocket)\n\ndocument.addEventListener(\'DOMContentLoaded\', function () {\n  //apanhos_imagenes_articulos();\n  //reubicar_publis(); //evitamos pedir laterales al principio\n  cambio_apanhos();\n  //social();\n  apanhos_menus();\n  //triggers_menus_mob();\n  scrollHandler();\n  //lecturas_cuenteo();\n  //setInterval(function() {responsivelyLazy.run(); apanhos_imagenes_articulos()}, 300);\n  setInterval(function () {\n    responsivelyLazy.run();\n  }, 300);\n  setInterval(function () {\n    scrollHandler();\n  }, 500);\n  var sw = true;\n  window.addEventListener("scroll", function () {\n    if (sw) {\n      sw = false;\n      setTimeout(function () {\n        scrollHandler();\n        sw = true;\n      }, 300);\n    }\n  });\n  if (typeof $(\'.linkpdf\').fancybox === "function") {\n    $(".linkpdf").fancybox({\n      type: "iframe"\n    });\n  }\n  if ($(\'.articulo.show .twitter-tweet\').length || $(\'.articulo.search .twitter-tweet\').length) {\n    //$.getScript(\'//platform.twitter.com/widgets.js\',function(){});\n  }\n}, false);\nconst onScrollStop = callback => {\n  let isScrolling;\n  window.addEventListener(\'scroll\', e => {\n    clearTimeout(isScrolling);\n    isScrolling = setTimeout(() => {\n      callback();\n    }, 750);\n  }, false);\n};\nonScrollStop(() => {\n  if (document.querySelector(".banda-portada")) {\n    document.querySelector(".banda-portada").style.display = "block";\n  }\n});\nfunction scrollHandler() {\n  subir_o_bajar();\n  //social();\n  header_en_sticky();\n  ver_barra_progreso();\n  apanhos_menus();\n  if (document.querySelector("body:not(.formulario):not(.edit)")) {\n    comprobar_publi_visible();\n  }\n}\nfunction ajuste_menu_movil() {\n  var posicion = document.querySelector("#MenuPosicion");\n  posicion = ".menu_zona_socias_mobil .m_" + posicion.dataset.posicion;\n  var m = document.querySelector(posicion);\n  if (m && !m.classList.contains("activo")) {\n    m.classList.add("activo");\n    m.scrollLeft = 20;\n    var x = m.getBoundingClientRect().x;\n    if (x > 1) {\n      document.querySelector(".menu_zona_socias_mobil .menu_container").scrollLeft = x;\n    }\n  }\n}\n\n// PUBLI\nvar extra_1 = document.querySelector(\'#articulo-contenido .col-extra .publicidades\');\nvar extra_2 = document.querySelector(\'.portada-portadilla .col-extra\');\nvar lateral_1 = document.querySelector(\'#lateral-1-container\');\nvar lateral_2 = document.querySelector(\'#lateral-2-container\');\nvar lateral_3 = document.querySelector(\'#lateral-3-container\');\nvar lateral_4 = document.querySelector(\'#lateral-4-container\');\nvar lateral_5 = document.querySelector(\'#lateral-5-container\');\nfunction actualizar_bloques_anuncios() {\n  extra_1 = document.querySelector(\'#articulo-contenido .col-extra .publicidades\');\n  extra_2 = document.querySelector(\'.portada-portadilla .col-extra\');\n  lateral_1 = document.querySelector(\'#lateral-1-container\');\n  lateral_2 = document.querySelector(\'#lateral-2-container\');\n  lateral_3 = document.querySelector(\'#lateral-3-container\');\n  lateral_4 = document.querySelector(\'#lateral-4-container\');\n  lateral_5 = document.querySelector(\'#lateral-5-container\');\n  lateral_5 = document.querySelector(\'#lateral-5-container\');\n}\nvar anuncios_reubicar = ["lateral-1", "lateral-2", "central-grande", "opinion-1", "opinion-2", "opinion-3", "lateral-3", "lateral-4", "central-grande-2", "bajo-1", "bajo-2", "bajo-3", "lateral-5"];\nfunction reubicar_publis_escritorio() {\n  var lateral_1_p = document.getElementById("lateral-1");\n  var lateral_2_p = document.getElementById("lateral-2");\n  var lateral_3_p = document.getElementById("lateral-3");\n  var lateral_4_p = document.getElementById("lateral-4");\n  var lateral_5_p = document.getElementById("lateral-5");\n  lateral_1 != null && lateral_1_p != null ? lateral_1.appendChild(lateral_1_p) : false;\n  lateral_2 != null && lateral_2_p != null ? lateral_2.appendChild(lateral_2_p) : false;\n  lateral_3 != null && lateral_3_p != null ? lateral_3.appendChild(lateral_3_p) : false;\n  lateral_4 != null && lateral_4_p != null ? lateral_4.appendChild(lateral_4_p) : false;\n  lateral_5 != null && lateral_5_p != null ? lateral_5.appendChild(lateral_5_p) : false;\n  if (document.getElementById("anuncios-opinion")) {\n    document.getElementById("anuncios-opinion").appendChild(document.getElementById("opinion-1"));\n    document.getElementById("anuncios-opinion").appendChild(document.getElementById("opinion-2"));\n    document.getElementById("anuncios-opinion").appendChild(document.getElementById("opinion-3"));\n  }\n  if (document.getElementById("anuncios-footer")) {\n    document.getElementById("anuncios-footer").appendChild(document.getElementById("bajo-1"));\n    document.getElementById("anuncios-footer").appendChild(document.getElementById("bajo-2"));\n    document.getElementById("anuncios-footer").appendChild(document.getElementById("bajo-3"));\n  }\n  if (document.getElementById("central-grande-container")) {\n    document.getElementById("central-grande-container").appendChild(document.getElementById("central-grande"));\n  }\n  if (document.getElementById("central-grande-2-container")) {\n    document.getElementById("central-grande-2-container").appendChild(document.getElementById("central-grande-2"));\n  }\n}\nfunction reubicar_publis_mobil() {\n  var bloques = false;\n  var contenido = document.querySelector("#articulo-contenido .col
1-contenido .articulo-texto-contenido");\n  var cobertura = document.querySelectorAll(".cobertura");\n  //var portada = document.querySelector("main .portada:not(.portada-portadilla)");\n  var portada = document.querySelector("main .portada");\n  if (contenido && portada) {\n    if (cobertura.length > 0) {\n      bloques = [...contenido.querySelectorAll(".cobertura")].concat([...portada.querySelectorAll(".resumen")]);\n    } else {\n      bloques = [...contenido.querySelectorAll("div:not(.resumen):not(blockquote) p")].concat([...portada.querySelectorAll(".resumen")]);\n    }\n  }\n  if (!bloques && portada) {\n    //bloques = portada.querySelectorAll(".grid .columna");\n    if (!bloques) {\n      bloques = portada.querySelectorAll(".resumen");\n    }\n  }\n  if (bloques) {\n    //console.log(bloques)\n    anuncios_reubicar.forEach(function (elem, indice, array) {\n      if (bloques && bloques[1 + 2 * indice] && document.getElementById(elem)) {\n        //console.log(indice)\n        //console.log(bloques[indice])\n        //console.log(elem)\n        bloques[1 + 2 * indice].insertAdjacentElement("afterend", document.getElementById(elem));\n      } else {\n        //console.log("DND???????????????????????\'\'\'\'")\n        //console.log(elem)\n      }\n    });\n  }\n}\n// Variables de coordinación entre publicidad y contenido\nvar publi_lock = false; // Evita manipulación simultánea\nvar publi_pendientes = []; // Anuncios pendientes de procesar\nvar contenidoupdating = false; // Indica actualización de contenido LiveView\n\nvar reubicar_las_publis = true;\nfunction reubicar_publis(forzar = false) {\n  reubicar_las_publis = forzar ? true : reubicar_las_publis;\n\n  // Si hay contenido actualizándose y no es forzado, pausar ejecución\n  if (contenidoupdating && !forzar) return;\n  if (reubicar_las_publis === true) {\n    // Establecer lock para evitar conflicto con LazyLoadAd\n    if (!publi_lock) {\n      publi_lock = true;\n    }\n    actualizar_bloques_anuncios();\n    if (document.querySelector(".articulo-contenido")) {\n      var anuncio_grande = document.getElementById("central-grande");\n      var contenido = document.querySelector("#articulo-contenido .col-contenido .articulo-texto-contenido");\n      var cobertura = document.querySelectorAll(".cobertura");\n      var bloques = [];\n      if (contenido) {\n        if (cobertura.length > 0) {\n          bloques = contenido.querySelectorAll(".cobertura");\n        } else {\n          bloques = contenido.querySelectorAll("div:not(.resumen):not(blockquote):not(.twitter-tweet) p");\n        }\n        var bloque = Math.ceil(bloques.length / 2);\n        if (bloques.length > 1 && bloque > 3 && anuncio_grande) {\n          bloques[bloque].insertAdjacentElement("afterend", anuncio_grande);\n        }\n      }\n    }\n    if ($(window).width() < 767) {\n      reubicar_publis_mobil();\n    } else {\n      reubicar_publis_escritorio();\n    }\n    if ($(window).width() > 1024 && !document.querySelector(".galeria_todo_ancho")) {\n      if (document.getElementById(\'articulo-contenido\')) {\n        var articulo_textos = document.querySelector(\'#articulo-textos .contenido\');\n        var altura_articulo = 0;\n        if (articulo_textos) {\n          altura_articulo = articulo_textos.scrollHeight;\n        }\n        var altura_info = 0;\n        if (document.querySelector(\'.info-blog\')) {\n          altura_info = document.querySelector(\'.info-blog\').scrollHeight;\n        }\n        if (document.querySelector(\'.info-tema\')) {\n          altura_info = altura_info + document.querySelector(\'.info-tema\').scrollHeight;\n        }\n        var altura = altura_articulo - altura_info;\n        //var style = "height: "+altura+"px; max-height: "+altura+"px; min-height: "+altura+"px"\n        //var style = "";\n\n        if (extra_1) {\n          //extra_1.setAttribute("style", style);\n          extra_1.setAttribute("phx-update", "ignore");\n          if (extra_2) {\n            extra_2.setAttribute("phx-update", "ignore");\n          }\n          ;\n          if (altura <= 300) {\n            //console.log("lat-0");\n            // 0 en articulo / 0 + 2\n            //extra_1.remove();\n            //extra_1.innerHTML = "";\n            //if(lateral_4){ lateral_4.replaceWith(lateral_1)}\n            //if(lateral_5){ lateral_5.replaceWith(lateral_2)}\n            if (lateral_4 && lateral_1) {\n              lateral_4.appendChild(lateral_1.children[0].cloneNode(true));\n            }\n            if (lateral_5 && lateral_2) {\n              lateral_5.appendChild(lateral_2.children[0].cloneNode(true));\n            }\n            if (lateral_1) {\n              lateral_1.classList.add("hidden");\n              lateral_2.classList.add("hidden");\n              lateral_3.classList.add("hidden");\n              lateral_4.classList.add("h50");\n              lateral_5.classList.add("h50");\n            }\n          } else if (altura >
1 300 && altura < 1000) {\n            // console.log("lat-1");\n            // 1 en articulo / 1 + 2\n            //extra_2.replaceChild(lateral_2,lateral_4)\n            //extra_2.replaceChild(lateral_3,lateral_5)\n            if (lateral_4 && lateral_2) {\n              lateral_4.appendChild(lateral_2.children[0].cloneNode(true));\n            }\n            if (lateral_5 && lateral_3) {\n              lateral_5.appendChild(lateral_3.children[0].cloneNode(true));\n            }\n            if (lateral_1) {\n              lateral_1.classList.add("h100");\n              lateral_2.classList.add("hidden");\n              lateral_3.classList.add("hidden");\n              if (lateral_4) {\n                lateral_4.classList.add("h50");\n              }\n              ;\n              if (lateral_5) {\n                lateral_5.classList.add("h50");\n              }\n              ;\n            }\n          } else if (altura >= 1000 && altura < 2500) {\n            //console.log("lat-2");\n            // 2 en articulo / 2 + 2\n            //if(lateral_4 && lateral_3){ lateral_4.replaceWith(lateral_3)}\n            if (lateral_5 && lateral_4) {\n              lateral_5.appendChild(lateral_4.children[0].cloneNode(true));\n            }\n            if (lateral_4 && lateral_3) {\n              lateral_4.appendChild(lateral_3.children[0].cloneNode(true));\n            }\n            //if(lateral_5){lateral_5.remove()}\n            lateral_1.classList.add("h50");\n            lateral_2.classList.add("h50");\n            if (lateral_3) {\n              lateral_3.classList.add("hidden");\n            }\n            ;\n            if (lateral_4 && lateral_5) {\n              lateral_4.classList.add("h50");\n            }\n            ;\n            if (lateral_5) {\n              lateral_5.classList.add("h50");\n            }\n            ;\n          } else if (altura >= 2500) {\n            //console.log("lat-3");\n            // 3 en articulo todo / 3 + 2\n            lateral_1.classList.add("h33");\n            lateral_2.classList.add("h33");\n            lateral_3.classList.add("h33");\n            if (lateral_4) {\n              lateral_4.classList.add("h50");\n            }\n            ;\n            if (lateral_5) {\n              lateral_5.classList.add("h50");\n            }\n            ;\n          }\n        }\n      }\n    } else {\n      if (document.getElementById(\'articulo-contenido\')) {\n        //var style = ""\n        if (extra_1) {\n          //extra_1.setAttribute("style", style);\n          //extra_1.setAttribute("phx-update", "ignore");\n          //extra_2.setAttribute("phx-update", "ignore");\n          if (lateral_1) {\n            lateral_1.classList.remove("h33");\n            lateral_1.classList.remove("h50");\n            lateral_1.classList.remove("h100");\n            lateral_5.classList.remove("hidden");\n          }\n          if (lateral_2) {\n            lateral_2.classList.remove("h33");\n            lateral_2.classList.remove("h50");\n            lateral_5.classList.remove("hidden");\n          }\n          if (lateral_3) {\n            lateral_3.classList.remove("h33");\n            lateral_3.classList.remove("h50");\n            lateral_5.classList.remove("hidden");\n          }\n          if (lateral_4) {\n            lateral_4.classList.remove("h50");\n            lateral_5.classList.remove("hidden");\n          }\n          if (lateral_5) {\n            lateral_5.classList.remove("h50");\n            lateral_5.classList.remove("hidden");\n          }\n        }\n      }\n    }\n    //console.log("Reubicadas publis")\n    reubicar_las_publis = false;\n\n    // Liberar lock y procesar anuncios pendientes\n    setTimeout(() => {\n      publi_lock = false;\n      procesar_publi_pendientes();\n    }, 100);\n  }\n}\nfunction apanhos_publi_bloque_tema() {\n  if ($(window).width() > 767 && document.querySelector(".info-tema")) {\n    let h = document.querySelector(".info-tema").offsetHeight;\n    let h2 = document.querySelector(".relacionadas").offsetHeight;\n    document.querySelectorAll(".h100").forEach(el =>
1 {\n      el.style.height = `calc(100% - ${h}px + ${h2}px)`;\n      el.style.minHeight = `calc(100% - ${h}px + ${h2}px)`;\n      el.style.maxHeight = `calc(100% - ${h}px + ${h2}px)`;\n    });\n  }\n}\n\n// Función para procesar anuncios pendientes después de liberar locks\nfunction procesar_publi_pendientes() {\n  if (publi_pendientes.length === 0) return;\n\n  //console.log("Procesando publicidad pendiente:", publi_pendientes);\n\n  while (publi_pendientes.length > 0) {\n    const modulo = publi_pendientes.shift();\n    const elemento = document.querySelector(`[data-name="${modulo}"]`);\n    if (elemento && !elemento.classList.contains(\'anuncio-activo\')) {\n      // Simular evento de intersección para procesar el anuncio\n      const event = new Event(\'intersect\');\n      Object.defineProperty(event, \'isIntersecting\', {\n        get: () => true\n      });\n      Object.defineProperty(event, \'intersectionRatio\', {\n        get: () => 1\n      });\n\n      // Disparar manualmente el procesamiento\n      const observer = new IntersectionObserver(([entry]) => {\n        if (entry.isIntersecting) {\n          elemento.dispatchEvent(new CustomEvent(\'ad-visible-trigger\', {\n            detail: {\n              modulo: modulo\n            }\n          }));\n        }\n      });\n      observer.observe(elemento);\n      observer.disconnect();\n    }\n  }\n}\nvar modulos_publi_iniciales = ["popup", "faldon"];\nvar modulos_publi = modulos_publi_iniciales;\nfunction comprobar_publi_visible() {\n  var publis = [];\n  var modulos = modulos_publi.slice(0);\n  for (var i = 0; i < modulos_publi.length; i++) {\n    if (document.getElementById(modulos_publi[i]) && basicos_visible(document.getElementById(modulos_publi[i]))) {\n      //console.log("VISIBLE: "+ modulos_publi[i]);\n      publis.push(modulos_publi[i]);\n      modulos = modulos.filter(item => item !== modulos_publi[i]);\n    }\n  }\n  if (publis.length > 0) {\n    pedir_anuncios(publis);\n    modulos_publi = modulos;\n  }\n}\nfunction social() {\n  if (document.getElementById(\'compartirPrincipal\')) {\n    if (visible(document.getElementById(\'compartirPrincipal\')) || visible(document.querySelector(".banner-blogs"))) {\n      ocultar(\'.fijo .compartir\');\n    } else {\n      mostrar(\'.fijo .compartir\');\n    }\n    if (!visible(document.getElementById(\'articulo-contenido\'))) {\n      ocultar(\'.fijo .compartir\');\n    }\n  }\n}\nfunction ver_barra_progreso() {\n  if (document.getElementById(\'articulo-contenido\')) {\n    if (basicos_visible(document.getElementById(\'header\'))) {\n      document.querySelector(\'.header\').classList.remove(\'header-out\');\n    } else {\n      document.querySelector(\'.header\').classList.add(\'header-out\');\n    }\n  }\n}\nvar rem = function (count) {\n  var unit = $(\'html\').css(\'font-size\');\n  if (typeof count !== \'undefined\' && count > 0) {\n    return parseInt(unit) * count;\n  } else {\n    return parseInt(unit);\n  }\n};\nvar scrollPos = 0;\nvar parar = 0;\nfunction subir_o_bajar() {\n  var actual = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;\n  var sticky_activo = document.querySelector(".sticky-header") ? document.querySelector(".sticky-header").offsetHeight : 0;
1\n  var h = sticky_activo + rem(1.25);\n  //console.log(actual +" "+ scrollPos + " " + (actual - scrollPos))\n  var dif = actual - scrollPos;\n  //console.log(dif)\n  if (dif < -40) {\n    //if (dif < -40 && sticky_activo) {\n    //console.log("UP")\n    document.querySelector(\'body\').classList.add(\'up\');\n    document.querySelector(\'body\').classList.remove(\'down\');\n    parar = 0;\n  } else if (dif > 40) {\n    //} else if (dif > 40 || sticky_activo == 0){\n    //console.log("DOWN")\n    document.querySelector(\'body\').classList.add(\'down\');\n    document.querySelector(\'body\').classList.remove(\'up\');\n    parar = 0;\n  } else {\n    if (parar == 2) {\n      //document.querySelector(\'body\').classList.add(\'up\')\n      //document.querySelector(\'body\').classList.remove(\'down\')\n    }\n    parar = parar + 1;\n    //console.log("PARA")\n  }\n  var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n  if (document.querySelector(".up-down") && dif < -40 && sticky_activo) {\n    document.querySelector(".up-down").style.display = "block";\n  } else if (document.querySelector(".up-down") && (dif > 40 || sticky_activo == 0)) {\n    document.querySelector(".up-down").style.display = "none";\n  }\n  if (document.querySelector(".banda-portada")) {\n    if (sticky_activo == 0) {\n      document.querySelector(".banda-portada").style.display = "block";\n    }\n    if (dif > 50) {\n      document.querySelector(".banda-portada").style.display = "none";\n    } else if (dif < -40 && sticky_activo) {\n      document.querySelector(".banda-portada").style.display = "block";\n    }\n  }\n  if (document.querySelector("#menu-arriba .cabeceradoble")) {\n    var cabecera_1 = document.querySelector(".cabecera_portada .cabeceradoble");\n    var cabecera_2 = document.querySelector("#menu-arriba .cabeceradoble");\n    var escondida = cabecera_1.getBoundingClientRect().bottom < -100;\n    if (cabecera_1 && escondida) {\n      cabecera_2.classList.add("visible-logo");\n    } else {\n      cabecera_2.classList.remove("visible-logo");\n    }\n  }\n  if (w < 769) {\n    if (document.querySelector(".up-down-articulo")) {\n      if (basicos_visible(document.getElementById(\'articulo-textos\')) && !basicos_visible(document.querySelector("#compartirPrincipal .compartir"))) {\n        document.querySelector(".header").classList.add("up-down-activo");\n      } else {\n        document.querySelector(".header").classList.remove("up-down-activo");\n      }\n    }\n  }\n  if (document.querySelector(".publi-lateral")) {\n    document.querySelectorAll(".publi-lateral").forEach(lateral => {\n      lateral.style.top = h + "px";\n    });\n  }\n  scrollPos = actual <= 0 ? 0 : actual;\n}\n;\nfunction ubicacion_banda_inferior() {\n  var width = $(window).width();\n  const portada_bi = document.querySelector(\'.portada_bi\');\n  if (portada_bi && width < 768) {\n    var loc = location.pathname.split(\'/\');\n    loc = loc.join("/");\n    const boletines_bi = document.querySelector(\'.boletines_bi\');\n    const misalto_bi = document.querySelector(\'.misalto_bi\');\n    const guardados_bi = document.querySelector(\'.guardados_bi\');\n    switch (loc) {\n      case "/":\n        portada_bi.classList.add(\'activa\');\n        boletines_bi && boletines_bi.classList.remove(\'activa\');\n        misalto_bi && misalto_bi.classList.remove(\'activa\');\n        guardados_bi && guardados_bi.classList.remove(\'activa\');\n        break;\n      case "/zona-socias/boletines":\n        portada_bi.classList.remove(\'activa\');\n        boletines_bi && boletines_bi.classList.add(\'activa\');\n        misalto_bi && misalto_bi.classList.remove(\'activa\');\n        guardados_bi && guardados_bi.classList.remove(\'activa\');\n        break;\n      case "/mi-salto":\n        portada_bi.classList.remove(\'activa\');\n        boletines_bi && boletines_bi.classList.remove(\'activa\');\n        misalto_bi && misalto_bi.classList.add(\'activa\');\n        guardados_bi && guardados_bi.classList.remove(\'activa\');\n        break;\n      case "/zona-socias/articulos-guardados":\n        portada_bi.classList.remove(\'activa\');\n        boletines_bi && boletines_bi.classList.remove(\'activa\');\n        misalto_bi && misalto_bi.classList.remove(\'activa\');\n        guardados_bi && guardados_bi.classList.add(\'activa\');\n        break;\n      default:\n        portada_bi.classList.remove(\'activa\');\n        boletines_bi && boletines_bi.classList.remove(\'activa\');\n        misalto_bi && misalto_bi.classList.remove(\'activa\');\n        guardados_bi && guardados_bi.classList.remove(\'activa\');\n        break;\n    }\n  }\n}\n;\nfunction pedir_anuncios(modulos) {\n  //console.log("pedir anuncios")\n  var width = $(window).width();\n  if (width > 767) {\n    var mobil = false;\n  } else {\n    var mobil = true;\n  }\n  var loc = location.pathname.split(\'/\').slice(1);\n  const ubicaciones_sin_publi = ["info", "mi-salto", "zona-socias", "suscribirse", "formulario", "cuenta", "area-personal", "admin"];\n  if (ubicaciones_sin_publi.includes(loc[0]) && document.querySelector("#css_zona_s
1ocias") == null) {\n    var style = document.createElement(\'style\');\n    style.setAttribute("id", "css_zona_socias");\n    style.textContent = `\n      #publi-cabecera,\n      .anuncio {\n        display: none !important;\n      }\n    `;\n    document.head.appendChild(style);\n    return true;\n  } else {\n    if (!ubicaciones_sin_publi.includes(loc[0]) && document.querySelector("#css_zona_socias")) {\n      var css = document.querySelector("#css_zona_socias");\n      css.remove();\n    }\n  }\n  var slug = "";\n  if (loc[0]) {\n    slug = loc[0] + \'/\';\n  }\n  if (loc[1]) {\n    slug = slug + loc[1] + \'/\';\n  } else {\n    slug;\n  }\n  ;\n  if (loc[0] == "sin-publicar") {\n    slug = loc[1] + \'/\' + loc[2];\n  }\n  var nodo = $(\'body\').attr(\'id\');\n  if (!ubicaciones_sin_publi.includes(loc[0])) {\n    $(\'body\').addClass(\'wait\');\n    $.ajax({\n      url: \'/api/\' + slug + \'anuncio/\' + modulos + \'/\' + nodo + \'/\' + mobil,\n      type: \'GET\',\n      dataType: \'json\',\n      success: function (data) {\
1n        $(\'body\').removeClass(\'wait\');\n        modulos = data.data;\n        $.each(modulos, function (row) {\n          var modulo_publi = modulos[row].modulo;\n          var modulo = $("#" + modulo_publi);\n          if (modulos[row].maquetacion && modulos[row].maquetacion.no_publicidad == "no_publicidad") {\n            modulo.addClass(\'bloque-activo\');\n          } else {\n            modulo.addClass(\'anuncio-activo\');\n          }\n          modulo.empty();\n          modulo.attr(\'phx-update\', "ignore");\n          if (modulos[row].script && modulos[row].script.length > 10) {\n            //$(modulos[row].script).appendTo(modulo);\n            //\n            $(function () {\n              //        console.log(modulos[row].script);\n              postscribe_min_default()(modulo, modulos[row].script);\n              try {\n                postscribe_min_default()(modulo, modulos[row].script);\n              } catch (err) {\n                console.log("Error al insertar script");\n              }\n            });\n            //eval(modulos[row].script);\n          } else {\n            //modulo.addClass(\'anuncio-activo\');\n            if (modulos[row].html && modulos[row].html.length > 1) {\n              var div = $(\'<div/>\').addClass(\'html-anun\').appendTo(modulo);\n              div.append(modulos[row].html);\n            } else {\n              if (modulos[row].url_redireccion) {\n                var redireccion = modulos[row].url_redireccion;\n              } else {\n                var redireccion = "false";\n              }\n              var a = $(\'<a/>\').attr(\'data-anun\', modulos[row].id).attr(\'data-click\', redireccion).attr(\'href\', "/ir_anuncio/" + modulos[row].id + \'/\' + mobil).attr(\'target\', \'_blank\').attr(\'aria-label\', \'publicidad\').addClass(\'anuncio-link\').appendTo(modulo);\n              if (modulos[row].imagen) {\n                if (modulos[row].imagen.split(\'.\').pop().split(\'?\').shift() == "mp4") {\n                  var video = $(\'<video/>\').addClass(\'no-mep\').prop({\n                    autoplay: true,\n                    muted: true,\n                    loop: true\n                  }).attr(\'src\', modulos[row].imagen).attr(\'alt\', data.texto).appendTo(a);\n                } else {\n                  var img = $(\'<img/>\').addClass(\'\').attr(\'src\', modulos[row].imagen).attr(\'alt\', data.texto).attr(\'fetchpriority\', \'hight\').appendTo(a);\n                }\n              }\n              if (modulos[row].url_impresion) {\n                var pixel = $(\'<img/>\').addClass(\'transparent\').attr(\'src\', modulos[row].url_impresion.replace("[timestamp]", +new Date())).attr(\'alt\', "Advertisment").attr(\'border\', "0").attr(\'height\', "1").attr(\'width\', "1").appendTo(a);\n              }\n            }\n          }\n        });\n        popup();\n      },\n      error: function (request, error) {\n        $(\'body\').removeClass(\'wait\');\n      }\n    });\n  }\n  $(document).on(\'click\', \'.anuncio-link\', function () {\n    var url = $(this).attr("data-click");\n    if (url != "false") {\n      $.get(url);\n    }\n  });\n}\nfunction popup() {\n  const popup = document.getElementById("popup");\n  if (popup && popup.children.length !== 0) {\n    setTimeout(function () {\n      //const modal = document.getElementById("modal-popup");\n      //if (modal) {\n      // Mostrar el modal manualmente (sin Bootstrap)\n      //        modal.style.display = "block";     // o usa "flex" si tu CSS lo requiere\n      //       modal.classList.add("visible");    // opcional, por si tienes animaciones CSS\n      //     }\n      $(\'#modal-popup\').modal(\'show\');\n      const days = 1;\n      const date = new Date();\n      date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n      const expires = "; expires=" + date.toUTCString();\n      const name = "hab";\n      const value = "saltarines";\n      document.cookie = name + "=" + (value || "") + expires + "; path=/";\n    }, 10000);\n    popup.id = "popupOFF";\n  }\n}\nfunction pedir_articulos(nodo, tipo) {\n  $(\'body\').addClass(\'w
1ait\');\n  $.ajax({\n    url: \'/api/listar/\' + nodo + \'/\' + tipo,\n    type: \'GET\',\n    dataType: \'json\',\n    success: function (data) {\n      $(\'body\').removeClass(\'wait\');\n      fabricar_menu_secciones(data.data, tipo);\n    },\n    error: function (request, error) {\n      $(\'body\').removeClass(\'wait\');\n    }\n  });\n}\nfunction apanhos_menus() {\n  var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n  if (document.getElementById("menu-admin") && w > 768) {\n    let h = document.querySelector("#menu-admin .container").getBoundingClientRect().height;\n    if (document.getElementById("anuncio-cabecera")) {\n      document.getElementById("anuncio-cabecera").style.marginTop = h;\n    }\n    if (document.querySelector("publi-lateral")) {\n      h = document.getElementByClassName("seguimiento").getBoundingClientRect().height + h;\n      document.querySelectorAll(".publi-lateral").forEach(lateral => {\n        lateral.style.top = h;\n      });\n    }\n  }\n}\n$(document).on(\'click\', \'.compartir_link\', function () {});\n$(document).on(\'click\', \'.anuncio a off\', function () {\n  var d = $(this).attr("data-anun");\n  $.ajax({\n    url: \'/api/anuncio/redireccion/\' + d,\n    type: \'PUT\',\n    success: function (data) {}\n  });\n});\nvar swiper_seccion = "";\nvar width = $(window).width();\nfunction cambio() {\n  //social();\n  apanhos_menus();\n  //scrollHandler();\n  apanhos_imagenes_articulos();\n}\nfunction apanho_crop() {\n  var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n  if (w > 768 && (document.querySelector("table.table .crop") || document.querySelector("table.table .crop2"))) {\n    var table = document.querySelector("table.table");\n    var crop = document.querySelector("table.table .crop");\n    var crops = document.querySelectorAll("table.table .crop2");\n    var crop1 = crops[0];\n    var crop2 = crops[1];\n    var ancho_contenedor_0 = table.parentNode.offsetWidth;\n    if (crop) {\n      crop.style.maxWidth = "100%";\n      crop.style.width = "100%";\n    }\n    if (crop2) {\n      crop2.style.maxWidth = "100%";\n      crop2.style.width = "100%";\n    }\n    console.log(ancho_contenedor_0);\n    var ancho_contenedor = table.getBoundingClientRect().x;\n    console.log(ancho_contenedor);\n    var ancho_tabla = table.offsetWidth;\n    console.log(ancho_tabla);\n    var ancho_crop = 0;\n    if (crop) {\n      ancho_crop = crop.offsetWidth;\n    }\n    if (crop2) {\n      ancho_crop = crop2.offsetWidth + crop1.offsetWidth;\n    }\n    console.log(ancho_crop);\n    var nuevo_ancho_crop = ancho_contenedor - (ancho_tabla - ancho_crop);\n    console.log(nuevo_ancho_crop);\n    document.querySelectorAll("table.table .crop").forEach(crop => {\n      crop.style.maxWidth = `calc(${nuevo_ancho_crop}px)`;\n      crop.style.width = `calc(${nuevo_ancho_crop}px )`;\n    });\n    document.querySelectorAll("table.table .crop2").forEach(crop => {\n      crop.style.maxWidth = `calc(${nuevo_ancho_crop / 2}px)`;\n      crop.style.width = `calc(${nuevo_ancho_crop / 2}px )`;\n    });\n    table.style.maxWidth = `calc(${ancho_contenedor_0}px - 1.5rem)`;\n    table.style.width = `calc(${ancho_contenedor_0}px - 1.5rem)`;\n  }\n}\nfunction apanhos_imagenes_articulos() {\n  if (document.querySelector(".real .todo-el-ancho")) {\n    document.querySelectorAll(".real .todo-el-ancho").forEach(imagen => {\n      var prop = imagen.getAttribute("data-proporcion");\n      var width = imagen.offsetWidth;\n      imagen.style.paddingBottom = prop * width / 100 + "px";\n      imagen.setAttribute(\'phx-update\', \'ignore\');\n    });\n  }\n  var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n  if (w > 768) {\n    document.querySelectorAll(".vertical img").forEach(imagen => {\n      imagen.parentNode.style.cssText = "cssText", "width: 75% !important; margin-right: 2.5em !important; margin-left: -37% !important; float: left";\n      //imagen.nextElementSibling.style.marginLeft = "50%";\n    });\n    document.querySelectorAll(".real .vertical img").forEach(imagen =>
1 {\n      var paddingBottom = imagen.parentNode.style.paddingBottom * .63;\n      imagen.parentNode.style.cssText = `padding-bottom: ${paddingBottom}; margin: 0 !important;`;\n      imagen.parentNode.parentNode.style.cssText = "margin: 0 0 0 -37% !important; float: left; clear: both; padding: 2.5rem 2.5rem 0 0";\n      //imagen.parentNode.parentNode.querySelectorAll(".figure-caption").style.paddingLeft = "50%";\n      imagen.style.marginLeft = "0 !important";\n      var prop = imagen.parentNode.getAttribute("data-proporcion");\n      var width = imagen.parentNode.offsetWidth;\n      imagen.parentNode.style.paddingBottom = prop * width / 100 + "px";\n    });\n  } else {\n    document.querySelectorAll(".vertical img").forEach(imagen => {\n      imagen.parentNode.style.cssText = "cssText", "";\n    });\n    document.querySelectorAll(".real .vertical img").forEach(imagen => {\n      var width = imagen.parentNode.offsetWidth;\n      var prop = imagen.parentNode.getAttribute("data-proporcion");\n      var paddingBottom = width * prop;\n      imagen.parentNode.style.cssText = `padding-bottom: ${paddingBottom}; margin: 0 !important;`;\n      imagen.parentNode.parentNode.style.cssText = "";\n      imagen.style.marginLeft = "0 !important";\n      imagen.parentNode.style.paddingBottom = prop * width / 100 + "px";\n    });\n  }\n}\nvar galleryTop = {};\nvar galleryThumbs = {};\nvar galleryThumbsFake = {};\nfunction swiper_galeria() {\n  if ($(\'.gallery-top\').length) {\n    galleryTop = new Swiper(\'.gallery-top\', {\n      slidesPerView: 1,\n      slidesPerGroup: 1,\n      nextButton: \'.swiper-button-next\',\n      prevButton: \'.swiper-button-prev\',\n      onSlideChangeStart: function (swip) {\n        if (width > 768) {\n          var index = swip.activeIndex;\n          var activo = swip.slides[index];\n          galleryThumbs.slideTo(index);\n          galleryThumbsFake.slideTo(index);\n          var seccion = activo.getAttribute(\'data-seccion\');\n          if (seccion != swiper_seccion) {\n            swiper_seccion = seccion;\n            var id_link = \'#apartado\' + seccion;\n            var id_tab = \'#apartado\' + seccion + \'-tab\';\n            $(\'.tablink\').removeClass(\'active\');\n            $(\'.tab-pane\').removeClass(\'active\');\n            $(\'.tab-pane\').removeClass(\'show\');\n            $(id_link).addClass(\'active\');\n            $(id_tab).addClass(\'active\');\n            $(id_link).addClass(\'show\');\n            $(id_tab).addClass(\'show\');\n            $(id_tab).tab(\'show\');\n          }\n        }\n      }\n    });\n    if (width > 768) {\n      galleryThumbs = new Swiper(\'.gallery-thumbs\', {\n        centeredSlides: true,\n        slidesPerView: "auto",\n        slidesPerGroup: 1,\n        watchSlidesVisibility: true,\n        centeredSlides: true,\n        //touchRatio: 0.2,\n        slideToClickedSlide: true,\n        //pagination: ".swiper-pagination",\n        //nextButton: \'.swiper-button-next2\',\n        //prevButton: \'.swiper-button-prev2\',\n        //paginationClickable: true,\n        zoom: false,\n        grabCursor: true,\n        onSlideChangeStart: function (swip) {\n          var index = swip.activeIndex;\n          galleryTop.slideTo(index);\n        }\n      });\n      galleryThumbsFake = new Swiper(\'.gallery-thumbs-fake\', {\n        slidesPerView: 7,\n        slidesPerGroup: 7,\n        slideToClickedSlide: true,\n        pagination: ".swiper-pagination",\n        nextButton: \'.swiper-button-next2\',\n        prevButton: \'.swiper-button-prev2\',\n        paginationClickable: true,\n        onSlideChangeStart: function (swip) {\n          var index = swip.activeIndex;\n          galleryTop.slideTo(index);\n        }\n      });\n      galleryTop.params.control = galleryThumbs;\n      galleryThumbs.params.control = galleryTop;\n    }\n  }\n  var acceso = this;\n  $(document).on(\'click\', \'.pedir .articulo-resumen\', pedir_articulo);\n  $(document).on(\'dblclick\', \'.gallery-thumbs .swiper-slide-active\', pedir_articulo);\n  $(\'a[data-toggle="tab"]\').on(\'shown.bs.tab\', function (e) {\n    e.target; // newly activated tab;\n    var id = e.target.getAttribute(\'aria-controls\');\n    var id_art = $(\'#\' + id + \' .swiper-slide\').first().attr(\'data-articulo\');\n    e.relatedTarget; // previous active tab\n    var item = $(".gallery-top *[data-articulo=" + id_art + "]");\n    var index = $(".gallery-top .articulo-resumen").index(item);\n    if (index > -1) {\n      galleryTop.slideTo(index);\n    }\n    var id_link = \'#\' + id;\n    var id_tab = \'#\' + id + \'-tab\';\n    $(\'.tablink\').removeClass(\'active\');\n    $(\'.tab-pane\').removeClass(\'active\');\n    $(\'.tab-pane\').removeClass(\'show\');\n    $(id_link).addClass(\'active\');\n    $(id_tab).addClass(\'active\');\n    $(id_link).addClass(\'show\');\n    $(id_tab).addClass(\'show\');\n    $(id_tab).tab(\'show\');\n  });\n}\n$(document).ready(function () {\n  if ($(\'.swiper-socias\').length) {\n    var swiper = new Swiper(\'.swiper-socias\', {\n      nextButton: \'.swiper-button-next\',\n      prevButton: \'.swiper-button-prev\',\n      pagination: ".swiper-pagination",\n      spaceBetween: 0,\n      speed: 4000,\n      loop: true,\n      autoplay: {\n        delay: 6000\n      }\n    });\n  }\n});\nfunction swiper_galeria_modal() {\n  $(".modal").on(\'show.bs.modal\', function (e) {\n    setTimeout(function () {\n      if ($(\'.swiper-galeria\').length) {\n        var img = $(e.relatedTarget).attr("data-img");\n        var swiper = new Swiper(\'.swiper-galeria\', {\n          initialSlide: img,\n          slidesPerView: 1,\n          slidesPerGroup: 1,\n          nextButton: \'.swiper-buttom-next\',\n          prevButton: \'.swiper-buttom-prev\',\n          effect: \'fade\',\n          pagination: \'.pagination\',\n          paginationType: \'custom\',\n          paginationCustomRender: function (swiper, current, total) {\n            return current + \'/\' + total;\n          }\n        });\n      }\n    }, 500);\n  });\n  $(document).on(\'click\', \'.ocultar-info\', function () {\n    var cols = document.querySelectorAll(\'.swiper-galeria .info\');\n    for (var c = 0; c < cols.length; ++c) {\n      cols[c].classList.toggle(\'oculto\');\n    }\n  });\n}\n;
1\nfunction pedir_articulo() {\n  var id = $(this).attr("data-articulo");\n  $(\'body\').addClass(\'wait\');\n  $.ajax({\n    url: \'/api_secur/articulo/\' + id,\n    type: \'GET\',\n    dataType: \'json\',\n    success: function (data) {\n      $(\'body\').removeClass(\'wait\');\n      var articulo = $(\'.articulo-completo\');\n      articulo.html(\'\');\n      articulo.html(data.articulo);\n      cambio();\n      $(\'html, body\').stop().animate({\n        \'scrollTop\': articulo.offset().top - $(".seguimiento").height() - 25\n      }, 900, \'swing\');\n    },\n    error: function (request, error) {\n      $(\'body\').removeClass(\'wait\');\n    }\n  });\n  var id_tab = $("#TabContent *[data-articulo=" + id + "]").parent().parent().parent().parent().attr("id");\n  var id_link = \'#\' + id_tab;\n  id_tab = \'#\' + id_tab + \'-tab\';\n  $(\'.tablink\').removeClass(\'active\');\n  $(\'.tab-pane\').removeClass(\'active\');\n  $(\'.tab-pane\').removeClass(\'show\');\n  $(id_link).addClass(\'active\');\n  $(id_tab).addClass(\'active\');\n  $(id_link).addClass(\'show\');\n  $(id_tab).addClass(\'show\');\n  $(id_tab).tab(\'show\');\n  var item = $(".gallery-top *[data-articulo=" + id + "]");\n  var index = $(".gallery-top .articulo-resumen").index(item);\n  galleryTop.slideTo(index);\n  galleryThumbsFake.slideTo(index);\n}\n$(document).ready(function () {\n  if ($(\'.swiper-edicion-impresa\').length) {\n    var swiper = new Swiper(\'.swiper-edicion-impresa\', {\n      nextButton: \'.swiper-ed-next\',\n      prevButton: \'.swiper-ed-prev\',\n      spaceBetween: 0,\n      slidesPerView: 1,\n      slidesPerGroup: 1\n    });\n  }\n});\n$(document).ready(function () {\n  var width = $(window).width();\n  if (width < 768) {\n    if ($(\'.relacionadas-OFF .resumen\').length > 1) {\n      var swiper = new Swiper(\'.relacionadas .col-md-9\', {\n        slideClass: "resumen",\n        wrapperClass: "card-deck-portada",\n        nextButton: \'.swiper-numeros-next\',\n        prevButton: \'.swiper-numeros-prev\',\n        slidesPerView: 1,\n        slidesPerGroup: 1\n      });\n    }\n    if ($(\'.numero .resto\').length || $(\'.swiper-numeros\').length) {\n      var swiper = new Swiper(\'.swiper-numeros\', {\n        nextButton: \'.swiper-numeros-next\',\n        prevButton: \'.swiper-numeros-prev\',\n        slidesPerView: 1,\n        slidesPerGroup: 1\n      });\n    }\n  }\n  if ($(\'.swiper-libros\').length) {\n    var swiper = new Swiper(\'.swiper-libros\', {\n      nextButton: \'.swiper-libros-next\',\n      prevButton: \'.swiper-libros-prev\',\n      slidesPerView: 4,\n      slidesPerGroup: 4,\n      breakpoints: {\n        768: {\n          slidesPerView: 1,\n          slidesPerGroup: 1\n        }\n      }\n    });\n  }\n});\n\n/*\n$(document).ready(function(){\n  // to fade in on page load\n  // to fade out before redirect\n  $(\'a\').click(function(e){\n    redirect = $(this).attr(\'href\');\n    e.preventDefault();\n    $(\'body\').fadeOut(400, function(){\n      document.location.href = redirect\n    });\n  });\n})\n\n\n\nvar tooltips = document.querySelectorAll(\'.resumen\');\nfor(var i = 0; i < tooltips.length; i++) {\n  tooltips[i].addEventListener(\'mousemove\', function fn(e) {\n    if (e.target.classList.contains("entradilla_hover")) {\n    var tooltip = e.target.classList.contains("entradilla_hover") ?\n      e.target :\n      e.target.querySelector(\':scope .entradilla_hover\');\n    tooltip.style.left =\n      e.pageX + tooltip.clientWidth + 10 <\n      document.body.clientWidth ?\n      e.pageX + 10 + \'px\' :\n      document.body.clientWidth + 5 - tooltip.clientWidth + \'px\';\n    tooltip.style.top =\n      e.pageY + tooltip.clientHeight + 10 <\n      document.body.clientHeight ?\n      e.pageY + 10 + \'px\' : \n      document.body.clientHeight + 5 - tooltip.clientHeight + \'px\';\n    }\n  });\n}\n*/\n//document.addEventListener(\'DOMContentLoaded\', function() {\nfunction recortar_comentarios() {\n  var linkClick = function (e) {\n    var m = e.currentTarget;\n    if (m.classList.contains(\'less\')) {\n      m.classList.remove(\'less\');\n      m.innerHTML = moretext;\n    } else {\n      m.classList.add(\'less\');\n      m.innerHTML = lesstext;\n    }\n    m.parentNode.classList.toggle(\'visible\');\n    //m.parentNode.nextSlibing.classList.toggle(\'visible\')\n    return false;\n  };\n  var showChar = 300;\n  var ellipsestext = "...";\n  var moretext = "<svg class=\'icon\' title=\'\' viewBox=\'700 400  100 100\'><use xlink:href=\'#mas\'></use></svg>";\n  var lesstext = "<svg class=\'icon\' title=\'\' viewBox=\'400 700  100 100\'><use xlink:href=\'#menos\'></use> </svg>";\n  var mores = document.getElementsByClassName(\'cortar_texto\');\n  for (var i = 0; i < mores.length;
1 i++) {\n    var content = mores[i].innerHTML;\n    if (content.length > showChar) {\n      var c = content.substr(0, showChar);\n      var h = content.substr(showChar, content.length - showChar);\n      var html = \'\' + c + \'<span class="moreellipses">\' + ellipsestext + \'&nbsp;</span><span class="morecontent"><span>\' + h + \'</span><a class="morelink">\' + moretext + \'</a></span>\';\n      mores[i].innerHTML = html;\n    }\n  }\n  var morelinks = document.getElementsByClassName(\'morelink\');\n  for (var i = 0; i < morelinks.length; i++) {\n    morelinks[i].onclick = linkClick;\n  }\n}\nfunction copiar_acortados() {\n  var copiar_txt = function (e) {\n    var el = e.currentTarget;\n    var text = el.getAttribute("texto");\n    var textArea = document.createElement(\'textarea\');\n    textArea.setAttribute(\'style\', \'width:1px;border:0;opacity:0;\');\n    document.body.appendChild(textArea);\n    textArea.value = text;\n    textArea.select();\n    document.execCommand(\'copy\');\n    document.body.removeChild(textArea);\n  };\n  var copiar = document.getElementsByClassName("copiar");\n  for (var i = 0; i < copiar.length; i++) {\n    copiar[i].onclick = copiar_txt;\n  }\n  var copiar_acortado = document.getElementById("copiar_acortado");\n  if (copiar_acortado) {\n    copiar_acortado.onclick = function () {\n      var valor = document.getElementById(\'articulo_acortado\').value ? document.getElementById(\'articulo_acortado\').value : document.getElementById(\'articulo_id\').value;\n      var textArea = document.createElement(\'textarea\');\n      textArea.setAttribute(\'style\', \'width:1px;border:0;opacity:0;\');\n      document.body.appendChild(textArea);\n      textArea.value = "https://elsal.to/" + valor;\n      textArea.select();\n      document.execCommand(\'copy\');\n      document.body.removeChild(textArea);\n    };\n  }\n}\nvar segundos = 0;\nvar relacionadas = false;\nfunction pagina_activa() {\n  var repetir = true;\n  if (document.visibilityState == "visible") {\n    segundos++;\n  }\n  if (document.getElementsByClassName("relacionadas").length && visible(document.getElementsByClassName("relacionadas")[0])) {\n    relacionadas = true;\n  }\n  if (segundos > 15 && relacionadas) {\n    // anotar\n    //console.log("anotar")\n    //anotar_lectura();\n    repetir = false;\n  }\n  if (repetir) {\n    setTimeout(function () {\n      pagina_activa();\n    }, 1000);\n  }\n}\n//pagina_activa()\n\nfunction anotar_lectura() {\n  const csrf = document.querySelector(\'meta[name="csrf-token"]\').content;\n  const url = "/articulo/anotar/1223";\n  fetch(url, {\n    method: "PUT",\n    headers: {\n      \'x-csrf-token\': csrf\n    }\n  });\n}\nlet processScroll = () => {\n  if (document.getElementById("articulo-contenido")) {\n    let docElem = document.documentElement,\n      docBody = document.body,\n      scrollTop = docElem[\'scrollTop\'] || docBody[\'scrollTop\'],\n      header = document.getElementsByTagName("header")[0].offsetHeight,\n      halfWindowHeight = window.screen.height / 3,\n      scrollStop = document.getElementById(\'articulo-contenido\').offsetHeight,\n      scrollBottom_old = (docElem[\'scrollHeight\'] || docBody[\'scrollHeight\']) - scrollStop,\n      scrollBottom = scrollStop - halfWindowHeight,\n      scrollPercent = (scrollTop - header) / scrollBottom;\n    scrollPercent = scrollPercent < 0 ? 0 : scrollPercent;\n    scrollPercent = scrollPercent * 100 + \'%\';\n    if (document.getElementById("progress-bar") && scrollStop > 0) {\n      document.getElementById("progress-bar").style.setProperty("--scrollAmount", scrollPercent);\n    }\n  }\n};\nif (document.getElementById("articulo-contenido")) {\n  document.addEventListener("scroll", processScroll);\n}\nwindow.addEventListener("scroll_to", e => {\n  e.target.scrollIntoView();\n});\nfunction header_en_sticky() {\n  var sensor = document.querySelector(".sticky-sensor");\n  var header = document.querySelector("header");\n  var contenido = document.querySelector("#contenido-principal");\n  var tema = false;\n  if (document.querySelector(".nube-tema")) {\n    contenido = document.querySelector(".nube-tema");\n    tema = true;\n  }\n  if (document.querySelector(".articulo-contenido")) {\n    contenido = false;\n  }\n  if (header) {\n    var observer = new IntersectionObserver(([e]) =>
1 {\n      header.classList.toggle("sticky-header", e.intersectionRatio < 1);\n      var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n      if (w < 768 && contenido && e.intersectionRatio < 1) {\n        contenido.style.paddingTop = `${header.clientHeight}px`;\n      } else if (contenido && !tema) {\n        contenido.style.paddingTop = 0;\n      }\n    }, {\n      threshold: [1]\n    });\n    observer.observe(sensor);\n  }\n}\nvar reubicar_resumenes_articulos = false;\nfunction reubicar_resumenes_articulo() {\n  if (reubicar_resumenes_articulos === false) {\n    document.querySelectorAll(\'[data-articulo-resumen]\').forEach(resumen => {\n      var id = resumen.dataset.articuloResumen;\n      var ubicacion = document.getElementById(`ubicacion_articulo_${id}`);\n      var articulo = document.getElementById(`mover_ubicacion_${id}`);\n      ubicacion.replaceWith(articulo);\n      reubicar_resumenes_articulos = false;\n    });\n  }\n}\nwindow.addEventListener(\'orientationchange\', cambio_medidas);\nwindow.addEventListener(\'DOMContentLoaded\', cambio_medidas);\ndocument.addEventListener(\'DOMContentLoaded\', publi_version);\nwindow.addEventListener(\'resize\', cambio_medidas);\nfunction cambio_medidas() {\n  medidas();\n  publi_version_cambio();\n  apanhos_imagenes_articulos();\n}\nvar publi_version_actual = "";\nfunction publi_version() {\n  var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n  w <= 768 ? publi_version_actual = "mobil" : publi_version_actual = "escritorio";\n}\nfunction publi_version_cambio() {\n  var anterior = publi_version_actual;\n  publi_version();\n  publi_version_actual == anterior ? true : reubicar_publis(true);\n}\nfunction lanzar_scripts() {\n  lanzar_codigos_embebidos();\n  //console.log("LANZANDO SCRIPTSSSS")\n  var entradilla = document.querySelector("#entradilla2");\n  if (entradilla) {\n    var infografia = entradilla.innerHTML;\n    entradilla.innerHTML = "";\n    if (infografia) postscribe_min_default()("#entradilla2", infografia);\n  }\n  var flourish = document.querySelector(".flourish-embed");\n  if (document.querySelector(".flourish-embed iframe")) {\n    flourish = false;\n  } else {\n    flourish = flourish;\n  }\n  if (flourish) {\n    window.FlourishLoaded = null;\n    const script_flourish = "<script src=\'https://public.flourish.studio/resources/embed.js\'><\/script>";\n    postscribe_min_default()("#UbicacionScripts", script_flourish);\n    //console.log("!!!!!!!!!!!!!!!!!!!!")\n  }\n}\nvar ejecutados_embebidos = false;
1\nfunction lanzar_codigos_embebidos() {\n  if (ejecutados_embebidos === false) {\n    ejecutados_embebidos = true;\n    var embeds = document.querySelectorAll(".embed_data");\n    for (var i = 0; i < embeds.length; i++) {\n      var embed = embeds[i].getElementsByTagName("codigo")[0];\n      var id = embeds[i].getAttribute("move_to");\n      //console.log("aqui "+ id)\n      var to = document.getElementById(id);\n      //console.log(to)\n      //console.log(codigo)\n      var codigo = decodeURI(embed.getAttribute("codigo"));\n      if (to.innerHTML === "") {\n        to.innerHTML = "<span></span>";\n        postscribe_min_default()("#" + id, codigo);\n      }\n    }\n  }\n}\nvar ejecutados_limitados = false;\nfunction limitados() {\n  if (ejecutados_limitados === false) {\n    ejecutados_limitados = true;\n    var limitados = document.querySelectorAll(".limitado");\n    limitados = Array.from(limitados).filter(el => !el.closest(\'.socias_opinion\'));\n    var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n    if (w > 768) {\n      for (var i = 0; i < limitados.length; i++) {\n        var limitado = limitados[i];\n        limitado.parentNode.classList.add("limitar");\n        if (limitado.scrollHeight > limitado.clientHeight || limitado.scrollWidth > limitado.clientWidth) {\n          limitado.parentNode.classList.add("limitar");\n        } else {\n          limitado.parentNode.classList.remove("limitar");\n        }\n        if (limitado.scrollHeight >= 30) {\n          limitado.parentNode.classList.add("limitar");\n        }\n      }\n    }\n  }\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTcuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9iYXNpY29zLmpzPzM0MjAiLCJ3ZWJwYWNrOi8vLy4vanMvcHVibGkuanM/ZTA5NSIsIndlYnBhY2s6Ly8vLi4vZGVwcy9waG9lbml4L3ByaXYvc3RhdGljL3Bob2VuaXgubWpzPzRlMjAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3Bob2VuaXhfbGl2ZV92aWV3L3ByaXYvc3RhdGljL3Bob2VuaXhfbGl2ZV92aWV3LmVzbS5qcz8xMGRiIiwid2VicGFjazovLy8uLi9kZXBzL2xpdmVfc2VsZWN0L3ByaXYvc3RhdGljL2xpdmVfc2VsZWN0Lm1pbi5qcz81YTNiIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9hbHBpbmVqcy9kaXN0L21vZHVsZS5lc20uanM/ZGQ1MiIsIndlYnBhY2s6Ly8vLi9qcy9hcHAuanM/NzQ3MyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gbWVkaWRhcygpIHtcbiAgdmFyIHcgPSB3aW5kb3cuaW5uZXJXaWR0aFxuICAgIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aFxuICAgIHx8IGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGg7XG5cbiAgdmFyIGggPSB3aW5kb3cuaW5uZXJIZWlnaHRcbiAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0XG4gICAgfHwgZG9jdW1lbnQuYm9keS5jbGllbnRIZWlnaHQ7IFxuXG4gIGggPiB3ID8gZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKFwicG9ydHJhaXRcIikgOiBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoXCJwb3J0cmFpdFwiKTtcbiAgaCA8IHcgPyBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoXCJsYW5kc2NhcGVcIikgOiBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoXCJsYW5kc2NhcGVcIik7XG59O1xuXG52YXIgYm9keSA9IGRvY3VtZW50LmJvZHksXG4gICAgaHRtbCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblxudmFyIGhlaWdodCA9IE1hdGgubWF4KCBib2R5LnNjcm9sbEhlaWdodCwgYm9keS5vZmZzZXRIZWlnaHQsIFxuICAgICAgICAgICAgICAgICAgICAgICBodG1sLmNsaWVudEhlaWdodCwgaHRtbC5zY3JvbGxIZWlnaHQsIGh0bWwub2Zmc2V0SGVpZ2h0ICk7XG5cblxuZXhwb3J0IGZ1bmN0aW9uIHZpc2libGUoZWwpIHtcbiAgaWYgKGVsKSB7XG4gICAgY29uc3QgYW50ZWxhY2lvbiA9IDI1MDtcbiAgICBjb25zdCBlbGVtID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgdmFyIGFsdHVyYSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gICAgdmFyIGlzVmlzaWJsZSA9IChlbGVtLnRvcCA+PSAwICYmIGVsZW0udG9wPD0gYWx0dXJhKSBcbiAgICAgICAgICAgICAgICAgICAgfHwgKGVsZW0uYm90dG9tID49IDAgJiYgZWxlbS50b3A8PSBhbHR1cmEpXG4gICAgICAgICAgICAgICAgICAgIHx8IChlbGVtLnRvcCA8IGFsdHVyYSArIGFudGVsYWNpb24gJiYgZWxlbS5ib3R0b20gPiAwKTtcbiAgICByZXR1cm4gaXNWaXNpYmxlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbW9zdHJhcihjbGFzZXMpe1xuICB2YXIgbW9zdHJhciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoY2xhc2VzKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtb3N0cmFyLmxlbmd0aDsgaSsrKSB7XG4gICAgbW9zdHJhcltpXS5zdHlsZS5vcGFjaXR5ID0gMTtcbiAgICBtb3N0cmFyW2ldLnN0eWxlLnZpc2liaWxpdHkgPSBcInZpc2libGVcIjtcbiAgICBtb3N0cmFyW2ldLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG9jdWx0YXIoY2xhc2VzKXtcbiAgdmFyIG9jdWx0YXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKGNsYXNlcyk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgb2N1bHRhci5sZW5ndGg7IGkrKykge1xuICAgIG9jdWx0YXJbaV0uc3R5bGUub3BhY2l0eSA9IDA7XG4gICAgb2N1bHRhcltpXS5zdHlsZS52aXNpYmlsaXR5ID0gXCJoaWRkZW5cIjtcbiAgICBvY3VsdGFyW2ldLnN0eWxlLnZpc2liaWxpdHkgPSBcIm5vbmVcIjtcbiAgfVxufVxuXG4iLCJqUXVlcnkoXCJkb2N1bWVudFwiKS5yZWFkeShmdW5jdGlvbigkKXtcbiAgY2FtYmlvX2FwYW5ob3MoKTtcbiAgYXBhbmhvc19zd2lwKCk7XG59KTtcbmZ1bmN0aW9uIGFwYW5ob3Nfc3dpcCgpe1xuICBpZiAoJCgnLnN3aXBlci1zb2NpYXMnKS5sZW5ndGgpIHtcbiAgICB2YXIgd2lkdGggPSAkKHdpbmRvdykud2lkdGgoKTtcbiAgICBpZiAod2lkdGg+NzY3KXsgXG4gICAgICAkKCcuc3dpcGVyLXNvY2lhcyAuc3dpcGVyLXdyYXBwZXInKS5jc3MoXCJoZWlnaHRcIiwgd2lkdGgvMi4xKTtcbiAgICB9ICAgXG4gI
1H1cbn1cbiQoZnVuY3Rpb24oKSB7XG4gIHZhciAkd2luZG93ID0gJCh3aW5kb3cpO1xuICB2YXIgd2lkdGggPSAkd2luZG93LndpZHRoKCk7XG4gIHZhciBoZWlnaHQgPSAkd2luZG93LmhlaWdodCgpO1xuICBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCh3aWR0aCAhPSAkd2luZG93LndpZHRoKCkpIHx8IChoZWlnaHQgIT0gJHdpbmRvdy5oZWlnaHQoKSkpIHtcbiAgICAgIHdpZHRoID0gJHdpbmRvdy53aWR0aCgpO1xuICAgICAgaGVpZ2h0ID0gJHdpbmRvdy5oZWlnaHQoKTtcbiAgICAgIGNhbWJpb19hcGFuaG9zKCk7XG4gICAgfVxuICB9LCAzMDApO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gY2FtYmlvX2FwYW5ob3MoKXsgXG4gICAgJCgnLnZpZGVvcyAuY2Fyb3VzZWwtaW5uZXInKVxuICAgICAgLmhlaWdodCgkKCcudmlkZW9zIC5jYXJvdXNlbC1pdGVtLmFjdGl2ZScpLm91dGVySGVpZ2h0KCkpO1xuICB2YXIgd2lkdGggPSAkKHdpbmRvdykud2lkdGgoKTtcbiAgaWYgKCQod2luZG93KS53aWR0aCgpPjc2OSl7IFxuICAgICQoXCIuY29udGVuaWRvIC5jb250ZW5pZG8gLnJlYWwgLnRvZG8tZWwtYW5jaG9cIikuZWFjaChmdW5jdGlvbigpe1xuICAgICAgY29uc29sZS5sb2coXCJjYW1iaW9fYXBhbmhvc1wiKVxuICAgICAgdmFyIHByb3AgPSAkKHRoaXMpLmF0dHIoXCJkYXRhLXByb3BvcmNpb25cIik7XG4gICAgICB2YXIgd2lkdGggPSAkKHRoaXMpLndpZHRoKCk7XG4gICAgICAkKHRoaXMpLmNzcyhcInBhZGRpbmctYm90dG9tXCIsIGZ1bmN0aW9uKCl7XG4gICAgICAgIHJldHVybiBwcm9wKndpZHRoLzEwMH0pO1xuICAgIH0pO1xuXG4gICAgdmFyIGZpam9fY29tcGFydGlyID0gJChcIi5maWpvIC5jb21wYXJ0aXJcIik7XG4gICAgaWYgKGZhbHNlICYmIGZpam9fY29tcGFydGlyKSB7XG4gICAgICB2Y
1XIgbGVmdCA9ICgod2lkdGggLSAkKFwiLmFydGljdWxvLWNvbnRlbmlkbyAuY2FiZWNlcmEgLmNvbnRhaW5lclwiKS53aWR0aCgpKS8yKSAtIGZpam9fY29tcGFydGlyLndpZHRoKCk7XG4gICAgICBpZiAobGVmdCA8IDApeyBsZWZ0ID0gMDsgfVxuICAgICAgJChcIi5maWpvIC5jb21wYXJ0aXJcIikgLmNzcyhcImxlZnRcIixsZWZ0KTtcbiAgICB9XG4gICAgdmFyIGxlZnQgPSAoKHdpZHRoIC0gJChcIiNtZW51LWFycmliYSAuY29udGFpbmVyXCIpLndpZHRoKCkpLzIpO1xuICAgIHZhciB2aWRlb190ZXh0byA9ICQoXCIudmlkZW8tdGV4dG9cIik7XG4gICAgaWYgKHZpZGVvX3RleHRvKSB7XG4gICAgICB2aWRlb190ZXh0b1xuICAgICAgICAuY3NzKFwicGFkZGluZy1sZWZ0XCIsbGVmdCk7XG4gICAgfVxuICAgICQoXCIuZGVzdGFjYWRhMSAuZWxlbTEubm9lbmNhbGFkYSAucmVzdW1lbjpmaXJzdC1vZi10eXBlIC5yZXNwb25zaXZlbHktbGF6eVwiKVxuICAgICAgLmNzcyhcIm92ZXJmbG93XCIsXCJoaWRkZW5cIilcbiAgICAgIC5jc3MoXCJwYWRkaW5nLWJvdHRvbVwiLFwiNDAlXCIpO1xuICAgICQoXCIuZGVzdGFjYWRhMSAuZWxlbTEubm9lbmNhbGFkYSAucmVzdW1lbjpmaXJzdC1vZi10eXBlIC5yZXNwb25zaXZlbHktbGF6eSBpbWdcIilcbiAgICAgIC5jc3MoXCJ0b3BcIixcIi0yMCVcIilcbiAgICAgIC5jc3MoXCJoZWlnaHRcIixcIjE0MCVcIik7XG5cbiAgfSBlbHNlIHtcbiAgICAkKFwiLmNvbnRlbmlkbyAuY29udGVuaWRvIGltZ1wiKVxuICAgICAgLmNzcyhcIndpZHRoXCIsXCIxMDAl
1XCIpXG4gIH1cblxuICAvL3ZhciBmb3RvcyA9IGh0bWwubWF0Y2goL3t7KFtBLXouanBnXSopfX0vKTtcbiAgLy8kKCd2aWRlbyxhdWRpbycpLm5vdCgnLm5vLW1lcCwuZnVsbHNjcmVlbi1iZ19fdmlkZW8nKS5tZWRpYWVsZW1lbnRwbGF5ZXIoe1xuICAgIC8vdmFyIHBsYXllciA9IG5ldyBNZWRpYUVsZW1lbnQoXCJ2aWRlby1wcmluY2lwYWxcIiwge1xuLy8gIHZhciBtZWRpYUUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInZpZGVvLXByaW5jaXBhbFwiKTtcbi8vICBjb25zb2xlLmxvZyhcInh4eFwiKVxuLy8gIGNvbnNvbGUubG9nKG1lZGlhRSk7XG4vLyAgdmFyIHBsYXllciA9IG5ldyBNZWRpYUVsZW1lbnQobWVkaWFFLCB7XG4vLyAgICBpY29uU3ByaXRlOiAnL2pzL21lZGlhZWxlbWVudC9tZWpzLWNvbnRyb2xzLnN2ZycsXG4vLyAgICBzdHJldGNoaW5nOiAncmVzcG9uc2l2ZScgLFxuLy8gIH0pO1xuXG4gIHZhciBpZnJhbWVzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmFydGljdWxvLWNvbnRlbmlkbyBpZnJhbWUnKTtcbiAgaWYgKGlmcmFtZXMgJiYgaWZyYW1lcy5sZWd0aCl7IFxuICBmb3IgKHZhciBpID0gMDsgaSA8IGlmcmFtZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgbWVkaWRhcyA9IGlmcmFtZXNbaV0uRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB2YXIgaWZyYW1lX3cgPSBtZWRpZGFzLndpZHRoO1xuICAgIHZhciBoID0gaWZyYW1lc1tpXS5nZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIik7XG4gICAgdmFyIHcgPSBpZnJhbWVzW2ldLmdldEF0dHJpYnV0ZShcIndpZHRoXCIpO1xuICAgIHZhciBhbHR1cmEgPSBpZnJhbWVfdy93Kmg7XG4gICAgaWZyYW1lc1tpXS5zdHlsZS5oZWlnaHQgPSBhbHR1cmE7XG4gIH1cbiAgfVxufTtcblxuJCgnLm1vZGFsJykub24oJ3Nob3duLmJzLm1vZGFsJywgZnVuY3Rpb24gKGUpIHtcbiAgdmFyIG1vZGFsX2JveCA9ICQodGhpcykuZmluZCgnLm1vZGFsJyk7XG4gIG1vZGFsX2JveC5jc3MoXCJkaXNwbGF5XCIsIFwiZmxleCAhaW1wb3J0YW50IFwiKTtcbiAgdmFyIG1vZGFsID0gJCh0aGlzKS5maW5kKCcubW9kYWwtZGlhbG9nJyk7XG4gIHZhciBtb2RhbGMgPSAkKHRoaXMpLmZpbmQoJy5tb2RhbC1jb250ZW50Jyk7XG4gIHZhciBtb2RhbG8gPSAkKHRoaXMpLmZpbmQoJy5tZWpzX19jb250YWluZXIgaWZyYW1lJyk7XG4gIHZhciBydyA9IG1vZGFsLndpZHRoKCk7XG4gIHZhciBoID0gJCh0aGlzKS5maW5kKCcubWVqc19fY29udGFpbmVyIGlmcmFtZScpLmF0dHIoXCJoZWlnaHRcIik7XG4gIHZhciB3ID0gJCh0aGlzKS5maW5kKCcubWVqc19fY29udGFpbmVyIGlmcmFtZScpLmF0dHIoXCJ3aWR0aFwiKTtcbiAgdmFyIGFsdHVyYSA9IHJ3L3cqaDtcbiAgJCh0aGlzKS5maW5kKCcubWVqc19fbGF5ZXInKS5jc3MoXCJoZWlnaHRcIiwgYWx0dXJhKS5jc3MoXCJ3aWR0aFwiLCBydyk7XG4gICQodGhpcykuZmluZCgnLm1lanNfX2NvbnRhaW5lcicpLmNzcyhcImhlaWdodFwiLCBhbHR1cmEpLmNzcyhcIndpZHRoXCIsIHJ3KTtcbiAgbW9kYWxvLmNzcyhcIndpZHRoXCIsIHJ3KS5jc3MoXCJoZWlnaHRcIiwgYWx0dXJhKTtcbiAgLy9tb2RhbG1vZGFsLmNzcygnbWFyZ2luLXRvcCcsICgoJCh3aW5kb3cpLmhlaWdodCgpIC0gKHBhcnNlSW50KG1vZGFsYy5oZWlnaHQoKSApKSkvMikpO1xufSk7XG4kKCdpZnJhbWUtb2ZmJykuZWFjaChmdW5jdGlvbigpe1xuICBmdW5jdGlvbiBpbmplY3RDU1MoKXtcbiAgICAkaWZyYW1lLmNvbnRlbnRzKCkuZmluZCgnaGVhZCcpLmFwcGVuZChcbiAgICAgICQoXCI8c3R5bGUgdHlwZT0ndGV4dC9jc3MnPlwiK1xuICAgICAgICBcIi5wbGF5ZXIgLnZwLWNhcmRzLCAucGxheWVyIC52cC1jb250cm9scyB7IGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDsgfSBcIitcbiAgICAgICAgXCI8L3N0eWxlPlwiKVxuICAgICk7XG4gIH1cbiAgdmFyICRpZnJhbWUgPSAkKHRoaXMpO1xuICAkaWZyYW1lLm9uKCdsb2FkJywgaW5qZWN0Q1NTKTtcbiAgaW5qZWN0Q1NTKCk7XG59KTtcblxuZnVuY3Rpb24gZWxpbWluYXJJRChlbGVtZW50SWQpIHtcbiAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50SWQpO1xuICBlbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWxlbWVudCk7XG59XG5pZihkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNsb3NlLWZhbGRvblwiKSl7XG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiY2xvc2UtZmFsZG9uXCIpXG4gICAgLmFkZEV2ZW50TGlzdGVuZXIgKFwiY2xpY2tcIiwgZnVuY3Rpb24oKXtcbiAgICAgIGVsaW1pbmFySUQoXCJmYWxkb24tY29udGFpbmVyXCIpXG4gICAgfVxuICApO1xufVxuIiwiLy8ganMvcGhvZW5peC91dGlscy5qc1xudmFyIGNsb3N1cmUgPSAodmFsdWUpID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9IGVsc2Uge1xuICAgIGxldCBjbG9zdXJlMiA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gICAgcmV0dXJuIGNsb3N1cmUyO1xuICB9XG59O1xuXG4vLyBqcy9waG9lbml4L2NvbnN0YW50cy5qc1xudmFyIGdsb2JhbFNlbGYgPSB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiBudWxsO1xudmFyIHBoeFdpbmRvdyA9IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiBudWxsO1xudmFyIGdsb2JhbCA9IGdsb2JhbFNlbGYgfHwgcGh4V2luZG93IHx8IGdsb2JhbFRoaXM7XG52YXIgREVGQVVMVF9WU04gPSBcIjIuMC4wXCI7XG52YXIgU09DS0VUX1NUQVRFUyA9IHsgY29ubmVjdGluZzogMCwgb3BlbjogMSwgY2xvc2luZzogMiwgY2xvc2VkOiAzIH07XG52YXIgTUFYX0xPTkdQT0xMX0JBVENIX1NJWkUgPSAxMDA7XG52YXIgREVGQVVMVF9USU1FT1VUID0gMWU0O1xudmFyIFdTX0NMT1NFX05PUk1BTCA9IDFlMztcbnZhciBDSEFOTkVMX1NUQVRFUyA9IHtcbiAgY2xvc2VkOiBcImNsb3NlZFwiLFxuICBlcnJvcmVkOiBcImVycm9yZWRcIixcbiAgam9pbmVkOiBcImpvaW5lZFwiLFxuICBqb2luaW5nOiBcImpvaW5pbmdcIixcbiAgbGVhdmluZzogXCJsZWF2aW5nXCJcbn07XG52YXIgQ0hBTk5FTF9FVkVOVFMgPSB7XG4gIGNsb3NlOiBcInBoeF9jbG9zZVwiLFxuICBlcnJvcjogXCJwaHhfZXJyb3JcIixcbiAgam9pbjogXCJwaHhfam9pblwiLFxuICByZXBseTogXCJwaHhfcmVwbHlcIixcbiAgbGVhdmU6IFwicGh4X2xlYXZlXCJcbn07XG52YXIgVFJBTlNQT1JUUyA9IHtcbiAgbG9uZ3BvbGw6IFwibG9uZ3BvbGxcIixcbiAgd2Vic29ja2V0OiBcIndlYnNvY2tldFwiXG59O1xudmFyIFhIUl9TVEFURVMgPSB7XG4gIGNvbXBsZXRlOiA0XG59O1xudmFyIEFVVEhfVE9LRU5fUFJFRklYID0gXCJiYXNlNjR1cmwuYmVhcmVyLnBoeC5cIjtcblxuLy8ganMvcGhvZW5peC9w
1dXNoLmpzXG52YXIgUHVzaCA9IGNsYXNzIHtcbiAgY29uc3RydWN0b3IoY2hhbm5lbCwgZXZlbnQsIHBheWxvYWQsIHRpbWVvdXQpIHtcbiAgICB0aGlzLmNoYW5uZWwgPSBjaGFubmVsO1xuICAgIHRoaXMuZXZlbnQgPSBldmVudDtcbiAgICB0aGlzLnBheWxvYWQgPSBwYXlsb2FkIHx8IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH07XG4gICAgdGhpcy5yZWNlaXZlZFJlc3AgPSBudWxsO1xuICAgIHRoaXMudGltZW91dCA9IHRpbWVvdXQ7XG4gICAgdGhpcy50aW1lb3V0VGltZXIgPSBudWxsO1xuICAgIHRoaXMucmVjSG9va3MgPSBbXTtcbiAgICB0aGlzLnNlbnQgPSBmYWxzZTtcbiAgfVxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXRcbiAgICovXG4gIHJlc2VuZCh0aW1lb3V0KSB7XG4gICAgdGhpcy50aW1lb3V0ID0gdGltZW91dDtcbiAgICB0aGlzLnJlc2V0KCk7XG4gICAgdGhpcy5zZW5kKCk7XG4gIH1cbiAgLyoqXG4gICAqXG4gICAqL1xuICBzZW5kKCkge1xuICAgIGlmICh0aGlzLmhhc1JlY2VpdmVkKFwidGltZW91dFwiKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnN0YXJ0VGltZW91dCgpO1xuICAgIHRoaXMuc2VudCA9IHRydWU7XG4gICAgdGhpcy5jaGFubmVsLnNvY2tldC5wdXNoKHtcbiAgICAgIHRvcGljOiB0aGlzLmNoYW5uZWwudG9waWMsXG4gICAgICBldmVudDogdGhpcy5ldmVudCxcbiAgICAgIHBheWxvYWQ6IHRoaXMucGF5bG9hZCgpLFxuICAgICAgcmVmOiB0aGlzLnJlZixcbiAgICAgIGpvaW5fcmVmOiB0aGlzLmNoYW5uZWwuam9pblJlZigpXG4gICAgfSk7XG4gIH1cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gc3RhdHVzXG4gICAqIEBwYXJhbSB7Kn0gY2FsbGJhY2tcbiAgICovXG4gIHJlY2VpdmUoc3RhdHVzLCBjYWxsYmFjaykge1xuICAgIGlmICh0aGlzLmhhc1JlY2VpdmVkKHN0YXR1cykpIHtcbiAgICAgIGNhbGxiYWNrKHRoaXMucmVjZWl2ZWRSZXNwLnJlc3BvbnNlKTtcbiAgICB9XG4gICAgdGhpcy5yZWNIb29rcy5wdXNoKHsgc3RhdHVzLCBjYWxsYmFjayB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHJlc2V0KCkge1xuICAgIHRoaXMuY2FuY2VsUmVmRXZlbnQoKTtcbiAgICB0aGlzLnJlZiA9IG51bGw7XG4gICAgdGhpcy5yZWZFdmVudCA9IG51bGw7XG4gICAgdGhpcy5yZWNlaXZlZFJlc3AgPSBudWxsO1xuICAgIHRoaXMuc2VudCA9IGZhbHNlO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgbWF0Y2hSZWNlaXZlKHsgc3RhdHVzLCByZXNwb25zZSwgX3JlZiB9KSB7XG4gICAgdGhpcy5yZWNIb29rcy5maWx0ZXIoKGgpID0+IGguc3RhdHVzID09PSBzdGF0dXMpLmZvckVhY2goKGgpID0+IGguY2FsbGJhY2socmVzcG9uc2UpKTtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGNhbmNlbFJlZkV2ZW50KCkge1xuICAgIGlmICghdGhpcy5yZWZFdmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNoYW5uZWwub2ZmKHRoaXMucmVmRXZlbnQpO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY2FuY2VsVGltZW91dCgpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0VGltZXIpO1xuICAgIHRoaXMudGltZW91dFRpbWVyID0gbnVsbDtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHN0YXJ0VGltZW91dCgpIHtcbiAgICBpZiAodGhpcy50aW1lb3V0VGltZXIpIHtcbiAgICAgIHRoaXMuY2FuY2VsVGltZW91dCgpO1xuICAgIH1cbiAgICB0aGlzLnJlZiA9IHRoaXMuY2hhbm5lbC5zb2NrZXQubWFrZVJlZigpO1xuICAgIHRoaXMucmVmRXZlbnQgPSB0aGlzLmNoYW5uZWwucmVwbHlFdmVudE5hbWUodGhpcy5yZWYpO1xuICAgIHRoaXMuY2hhbm5lbC5vbih0aGlzLnJlZkV2ZW50LCAocGF5bG9hZCkgPT4ge1xuICAgICAgdGhpcy5jYW5jZWxSZWZFdmVudCgpO1xuICAgICAgdGhpcy5jYW5jZWxUaW1lb3V0KCk7XG4gICAgICB0aGlzLnJlY2VpdmVkUmVzcCA9IHBheWxvYWQ7XG4gICAgICB0aGlzLm1hdGNoUmVjZWl2ZShwYXlsb2FkKTtcbiAgICB9KTtcbiAgICB0aGlzLnRpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy50cmlnZ2VyKFwidGltZW91dFwiLCB7fSk7XG4gICAgfSwgdGhpcy50aW1lb3V0KTtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGhhc1JlY2VpdmVkKHN0YXR1cykge1xuICAgIHJldHVybiB0aGlzLnJlY2VpdmVkUmVzcCAmJiB0aGlzLnJlY2VpdmVkUmVzcC5zdGF0dXMgPT09IHN0YXR1cztcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHRyaWdnZXIoc3RhdHVzLCByZXNwb25zZSkge1xuICAgIHRoaXMuY2hhbm5lbC50cmlnZ2VyKHRoaXMucmVmRXZlbnQsIHsgc3RhdHVzLCByZXNwb25zZSB9KTtcbiAgfVxufTtcblxuLy8ganMvcGhvZW5peC90aW1lci5qc1xudmFyIFRpbWVyID0gY2xhc3Mge1xuICBjb25zdHJ1Y3RvcihjYWxsYmFjaywgdGltZXJDYWxjKSB7XG4gICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHRoaXMudGltZXJDYWxjID0gdGltZXJDYWxjO1xuICAgIHRoaXMudGltZXIgPSBudWxsO1xuICAgIHRoaXMudHJpZXMgPSAwO1xuICB9XG4gIHJlc2V0KCkge1xuICAgIHRoaXMudHJpZXMgPSAwO1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTtcbiAgfVxuICAvKipcbiAgICogQ2FuY2VscyBhbnkgcHJldmlvdXMgc2NoZWR1bGVUaW1lb3V0IGFuZCBzY2hlZHVsZXMgY2FsbGJhY2tcbiAgICovXG4gIHNjaGVkdWxlVGltZW91dCgpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lcik7XG4gICAgdGhpcy50aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy50cmllcyA9IHRoaXMudHJpZXMgKyAxO1xuICAgICAgdGhpcy5jYWxsYmFjaygpO1xuICAgIH0sIHRoaXMudGltZXJDYWxjKHRoaXMudHJpZXMgKyAxKSk7XG4gIH1cbn07XG5cbi8vIGpzL3Bob2VuaXgvY2hhbm5lbC5qc1xudmFyIENoYW5uZWwgPSBjbGFzcyB7XG4gIGNvbnN0cnVjdG9yKHRvcGljLCBwYXJhbXMsIHNvY2tldCkge1xuICAgIHRoaXMuc3RhdGUgPSBDSEFOTkVMX1NUQVRFUy5jbG9zZWQ7XG4gICAgdGhpcy50b3BpYyA9IHRvcGljO1xuICAgIHRoaXMucGFyYW1zID0gY2xvc3VyZShwYXJhbXMgfHwge30pO1xuICAgIHRoaXMuc29ja2V0ID0gc29ja2V0O1xuICAgIHRoaXMuYmluZGluZ3MgPSBbXTtcbiAgICB0aGlzLmJpbmRpbmdSZWYgPSAwO1xuICAgIHRoaXMudGltZW91dCA9IHRoaXMuc29ja2V0LnRpbWVvdXQ7XG4gICAgdGhpcy5qb2luZWRPbmNlID0gZmFsc2U7XG4gICAgdGhpcy5qb2luUHVzaCA9IG5ldyBQdXNoKHRoaXMsIENIQU5ORUxfRVZFTlRTLmpvaW4sIHRoaXMucGFyYW1zLCB0aGlzLnRpbWVvdXQpO1xuICAgIHRoaXMucHVzaEJ1ZmZlciA9IFtdO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VSZWZzID0gW107XG4gICAgdGhpcy5yZWpvaW5UaW1lciA9IG5ldyBUaW1lcigoKSA9PiB7XG4gICAgICBpZiAodGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKSkge1xuICAgICAgICB0aGlzLnJlam9pbigpO1xuICAgICAgfVxuICAgIH0sIHRoaXMuc29ja2V0LnJlam9pbkFmdGVyTXMpO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VSZWZzLnB1c2godGhpcy5zb2NrZXQub25FcnJvcigoKSA9PiB0aGlzLnJlam9pblRpbWVyLnJlc2V0KCkpKTtcbiAgICB0aGlzLnN0YXRlQ2hhbmdlUmVmcy5wdXNoKFxuICAgICAgdGhpcy5zb2NrZXQub25PcGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5yZWpvaW5UaW1lci5yZXNldCgpO1xuICAgICAgICBpZiAodGhpcy5pc0Vycm9yZWQoKSkge1xuICAgICAgICAgI
1HRoaXMucmVqb2luKCk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgICB0aGlzLmpvaW5QdXNoLnJlY2VpdmUoXCJva1wiLCAoKSA9PiB7XG4gICAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuam9pbmVkO1xuICAgICAgdGhpcy5yZWpvaW5UaW1lci5yZXNldCgpO1xuICAgICAgdGhpcy5wdXNoQnVmZmVyLmZvckVhY2goKHB1c2hFdmVudCkgPT4gcHVzaEV2ZW50LnNlbmQoKSk7XG4gICAgICB0aGlzLnB1c2hCdWZmZXIgPSBbXTtcbiAgICB9KTtcbiAgICB0aGlzLmpvaW5QdXNoLnJlY2VpdmUoXCJlcnJvclwiLCAoKSA9PiB7XG4gICAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuZXJyb3JlZDtcbiAgICAgIGlmICh0aGlzLnNvY2tldC5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICAgIHRoaXMucmVqb2luVGltZXIuc2NoZWR1bGVUaW1lb3V0KCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5vbkNsb3NlKCgpID0+IHtcbiAgICAgIHRoaXMucmVqb2luVGltZXIucmVzZXQoKTtcbiAgICAgIGlmICh0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBgY2xvc2UgJHt0aGlzLnRvcGljfSAke3RoaXMuam9pblJlZigpfWApO1xuICAgICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmNsb3NlZDtcbiAgICAgIHRoaXMuc29ja2V0LnJlbW92ZSh0aGlzKTtcbiAgICB9KTtcbiAgICB0aGlzLm9uRXJyb3IoKHJlYXNvbikgPT4ge1xuICAgICAgaWYgKHRoaXMuc29ja2V0Lmhhc0xvZ2dlcigpKSB0aGlzLnNvY2tldC5sb2coXCJjaGFubmVsXCIsIGBlcnJvciAke3RoaXMudG9waWN9YCwgcmVhc29uKTtcbiAgICAgIGlmICh0aGlzLmlzSm9pbmluZygpKSB7XG4gICAgICAgIHRoaXMuam9pblB1c2gucmVzZXQoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc3RhdGUgPSBDSEFOTkVMX1NUQVRFUy5lcnJvcmVkO1xuICAgICAgaWYgKHRoaXMuc29ja2V0LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgdGhpcy5yZWpvaW5UaW1lci5zY2hlZHVsZVRpbWVvdXQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLmpvaW5QdXNoLnJlY2VpdmUoXCJ0aW1lb3V0XCIsICgpID0+IHtcbiAgICAgIGlmICh0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBgdGltZW91dCAke3RoaXMudG9waWN9ICgke3RoaXMuam9pblJlZigpfSlgLCB0aGlzLmpvaW5QdXNoLnRpbWVvdXQpO1xuICAgICAgbGV0IGxlYXZlUHVzaCA9IG5ldyBQdXNoKHRoaXMsIENIQU5ORUxfRVZFTlRTLmxlYXZlLCBjbG9zdXJlKHt9KSwgdGhpcy50aW1lb3V0KTtcbiAgICAgIGxlYXZlUHVzaC5zZW5kKCk7XG4gICAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuZXJyb3JlZDtcbiAgICAgIHRoaXMuam9pblB1c2gucmVzZXQoKTtcbiAgICAgIGlmICh0aGlzLnNvY2tldC5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICAgIHRoaXMucmVqb2luVGltZXIuc2NoZWR1bGVUaW1lb3V0KCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5vbihDSEFOTkVMX0VWRU5UUy5yZXBseSwgKHBheWxvYWQsIHJlZikgPT4ge1xuICAgICAgdGhpcy50cmlnZ2VyKHRoaXMucmVwbHlFdmVudE5hbWUocmVmKSwgcGF5bG9hZCk7XG4gICAgfSk7XG4gIH1cbiAgLyoqXG4gICAqIEpvaW4gdGhlIGNoYW5uZWxcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSB0aW1lb3V0XG4gICAqIEByZXR1cm5zIHtQdXNofVxuICAgKi9cbiAgam9pbih0aW1lb3V0ID0gdGhpcy50aW1lb3V0KSB7XG4gICAgaWYgKHRoaXMuam9pbmVkT25jZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwidHJpZWQgdG8gam9pbiBtdWx0aXBsZSB0aW1lcy4gJ2pvaW4nIGNhbiBvbmx5IGJlIGNhbGxlZCBhIHNpbmdsZSB0aW1lIHBlciBjaGFubmVsIGluc3RhbmNlXCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRpbWVvdXQgPSB0aW1lb3V0O1xuICAgICAgdGhpcy5qb2luZWRPbmNlID0gdHJ1ZTtcbiAgICAgIHRoaXMucmVqb2luKCk7XG4gICAgICByZXR1cm4gdGhpcy5qb2luUHVzaDtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEhvb2sgaW50byBjaGFubmVsIGNsb3NlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBvbkNsb3NlKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5vbihDSEFOTkVMX0VWRU5UUy5jbG9zZSwgY2FsbGJhY2spO1xuICB9XG4gIC8qKlxuICAgKiBIb29rIGludG8gY2hhbm5lbCBlcnJvcnNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uRXJyb3IoY2FsbGJhY2spIHtcbiAgICByZXR1cm4gdGhpcy5vbihDSEFOTkVMX0VWRU5UUy5lcnJvciwgKHJlYXNvbikgPT4gY2FsbGJhY2socmVhc29uKSk7XG4gIH1cbiAgLyoqXG4gICAqIFN1YnNjcmliZXMgb24gY2hhbm5lbCBldmVudHNcbiAgICpcbiAgICogU3Vic2NyaXB0aW9uIHJldHVybnMgYSByZWYgY291bnRlciwgd2hpY2ggY2FuIGJlIHVzZWQgbGF0ZXIgdG9cbiAgICogdW5zdWJzY3JpYmUgdGhlIGV4YWN0IGV2ZW50IGxpc3RlbmVyXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNvbnN0IHJlZjEgPSBjaGFubmVsLm9uKFwiZXZlbnRcIiwgZG9fc3R1ZmYpXG4gICAqIGNvbnN0IHJlZjIgPSBjaGFubmVsLm9uKFwiZXZlbnRcIiwgZG9fb3RoZXJfc3R1ZmYpXG4gICAqIGNoYW5uZWwub2ZmKFwiZXZlbnRcIiwgcmVmMSlcbiAgICogLy8gU2luY2UgdW5zdWJzY3JpcHRpb24sIGRvX3N0dWZmIHdvbid0IGZpcmUsXG4gICAqIC8vIHdoaWxlIGRvX290aGVyX3N0dWZmIHdpbGwga2VlcCBmaXJpbmcgb24gdGhlIFwiZXZlbnRcIlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICogQHJldHVybnMge2ludGVnZXJ9IHJlZlxuICAgKi9cbiAgb24oZXZlbnQsIGNhbGxiYWNrKSB7XG4gICAgbGV0IHJlZiA9IHRoaXMuYmluZGluZ1JlZisrO1xuICAgIHRoaXMuYmluZGluZ3MucHVzaCh7IGV2ZW50LCByZWYsIGNhbGxiYWNrIH0pO1xuICAgIHJldHVybiByZWY7XG4gIH1cbiAgLyoqXG4gICAqIFVuc3Vic2NyaWJlcyBvZmYgb2YgY2hhbm5lbCBldmVudHNcbiAgICpcbiAgICogVXNlIHRoZSByZWYgcmV0dXJuZWQgZnJvbSBhIGNoYW5uZWwub24oKSB0byB1bnN1YnNjcmliZSBvbmVcbiAgICogaGFuZGxlciwgb3IgcGFzcyBub3RoaW5nIGZvciB0aGUgcmVmIHRvIHVuc3Vic2NyaWJlIGFsbFxuICAgKiBoYW5kbGVycyBmb3IgdGhlIGdpdmVuIGV2ZW50LlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBVbnN1YnNjcmliZSB0aGUgZG9fc3R1ZmYgaGFuZGxlclxuICAgKiBjb25zdCByZWYxID0gY2hhbm5lbC5vbihcImV2ZW50XCIsIGRvX3N0dWZmKVxuICAgKiBjaGFubmVsLm9mZihcImV2ZW50XCIsIHJlZjEpXG4gICAqXG4gICAqIC8vIFVuc3Vic2NyaWJlIGFsbCBoYW5kbGVycyBmcm9tIGV2ZW50XG4gICAqIGNoYW5uZWwub2ZmKFwiZXZlbnRcIilcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7aW50ZWdlcn0gcmVmXG4gICAqL1xuICBvZmYoZXZlbnQsIHJlZikge1xuICAgIHRoaXMuYmluZGluZ3MgPSB0aGlzLmJpbmRpbmdzLmZpbHRlcigoYmluZCkgPT4ge1xuICAgICAgcmV0dXJuICEoYmluZC5ldmVudCA9PT0gZXZlbnQgJiYgKHR5cGVvZiByZWYgPT09IFwidW5kZWZpbmVkXCIgfHwgcmVmID09PSBiaW5kLnJlZikpO1xuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY2FuUHVzaCgpIHtcbiAgICByZXR1cm4gdGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKSAmJiB0aGlzLmlzSm9pbmVkKCk7XG4gIH1cbiAgLyoqXG4gICAqIFNlbmRzIGEgbWVzc2FnZSBgZXZlbnRgIHRvIHBob2VuaXggd2l0aCB0aGUgcGF5bG9hZCBgcGF5bG9hZGAuXG4gICAqIFBob2VuaXggcmVjZWl2ZXMgdGhpcyBpbiB0aGUgYGhhbmRsZV9pbihldmVudCwgcGF5bG9hZCwgc29ja2V0KWBcbiAgICogZnVuY3Rpb24uIGlmIHBob2VuaXggcmVwbGllcyBvciBpdCB0aW1lcyBvdXQgKGRlZmF1bHQgMTAwMDBtcyksXG4gICAqIHRoZW4gb3B0aW9uYWxseSB0aGUgcmVwbHkgY2FuIGJlIHJlY2VpdmVkLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjaGFubmVsLnB1c2goXCJldmVudFwiKVxuICAgKiAgIC5yZWNlaXZlKFwib2tcIiwgcGF5bG9hZCA9PiBjb25zb2xlLmxvZyhcInBob2VuaXggcmVwbGllZDpcIiwgcGF5bG9hZCkpXG4gICAqICAg
1LnJlY2VpdmUoXCJlcnJvclwiLCBlcnIgPT4gY29uc29sZS5sb2coXCJwaG9lbml4IGVycm9yZWRcIiwgZXJyKSlcbiAgICogICAucmVjZWl2ZShcInRpbWVvdXRcIiwgKCkgPT4gY29uc29sZS5sb2coXCJ0aW1lZCBvdXQgcHVzaGluZ1wiKSlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXlsb2FkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbdGltZW91dF1cbiAgICogQHJldHVybnMge1B1c2h9XG4gICAqL1xuICBwdXNoKGV2ZW50LCBwYXlsb2FkLCB0aW1lb3V0ID0gdGhpcy50aW1lb3V0KSB7XG4gICAgcGF5bG9hZCA9IHBheWxvYWQgfHwge307XG4gICAgaWYgKCF0aGlzLmpvaW5lZE9uY2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdHJpZWQgdG8gcHVzaCAnJHtldmVudH0nIHRvICcke3RoaXMudG9waWN9JyBiZWZvcmUgam9pbmluZy4gVXNlIGNoYW5uZWwuam9pbigpIGJlZm9yZSBwdXNoaW5nIGV2ZW50c2ApO1xuICAgIH1cbiAgICBsZXQgcHVzaEV2ZW50ID0gbmV3IFB1c2godGhpcywgZXZlbnQsIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfSwgdGltZW91dCk7XG4gICAgaWYgKHRoaXMuY2FuUHVzaCgpKSB7XG4gICAgICBwdXNoRXZlbnQuc2VuZCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwdXNoRXZlbnQuc3RhcnRUaW1lb3V0KCk7XG4gICAgICB0aGlzLnB1c2hCdWZmZXIucHVzaChwdXNoRXZlbnQpO1xuICAgIH1cbiAgICByZXR1cm4gcHVzaEV2ZW50O1xuICB9XG4gIC8qKiBMZWF2ZXMgdGhlIGNoYW5uZWxcbiAgICpcbiAgICogVW5zdWJzY3JpYmVzIGZyb20gc2VydmVyIGV2ZW50cywgYW5kXG4gICAqIGluc3RydWN0cyBjaGFubmVsIHRvIHRlcm1pbmF0ZSBvbiBzZXJ2ZXJcbiAgICpcbiAgICogVHJpZ2dlcnMgb25DbG9zZSgpIGhvb2tzXG4gICAqXG4gICAqIFRvIHJlY2VpdmUgbGVhdmUgYWNrbm93bGVkZ2VtZW50cywgdXNlIHRoZSBgcmVjZWl2ZWBcbiAgICogaG9vayB0byBiaW5kIHRvIHRoZSBzZXJ2ZXIgYWNrLCBpZTpcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY2hhbm5lbC5sZWF2ZSgpLnJlY2VpdmUoXCJva1wiLCAoKSA9PiBhbGVydChcImxlZnQhXCIpIClcbiAgICpcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSB0aW1lb3V0XG4gICAqIEByZXR1cm5zIHtQdXNofVxuICAgKi9cbiAgbGVhdmUodGltZW91dCA9IHRoaXMudGltZW91dCkge1xuICAgIHRoaXMucmVqb2luVGltZXIucmVzZXQoKTtcbiAgICB0aGlzLmpvaW5QdXNoLmNhbmNlbFRpbWVvdXQoKTtcbiAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMubGVhdmluZztcbiAgICBsZXQgb25DbG9zZSA9ICgpID0+IHtcbiAgICAgIGlmICh0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBgbGVhdmUgJHt0aGlzLnRvcGljfWApO1xuICAgICAgdGhpcy50cmlnZ2VyKENIQU5ORUxfRVZFTlRTLmNsb3NlLCBcImxlYXZlXCIpO1xuICAgIH07XG4gICAgbGV0IGxlYXZlUHVzaCA9IG5ldyBQdXNoKHRoaXMsIENIQU5ORUxfRVZFTlRTLmxlYXZlLCBjbG9zdXJlKHt9KSwgdGltZW91dCk7XG4gICAgbGVhdmVQdXNoLnJlY2VpdmUoXCJva1wiLCAoKSA9PiBvbkNsb3NlKCkpLnJlY2VpdmUoXCJ0aW1lb3V0XCIsICgpID0+IG9uQ2xvc2UoKSk7XG4gICAgbGVhdmVQdXNoLnNlbmQoKTtcbiAgICBpZiAoIXRoaXMuY2FuUHVzaCgpKSB7XG4gICAgICBsZWF2ZVB1c2gudHJpZ2dlcihcIm9rXCIsIHt9KTtcbiAgICB9XG4gICAgcmV0dXJuIGxlYXZlUHVzaDtcbiAgfVxuICAvKipcbiAgICogT3ZlcnJpZGFibGUgbWVzc2FnZSBob29rXG4gICAqXG4gICAqIFJlY2VpdmVzIGFsbCBldmVudHMgZm9yIHNwZWNpYWxpemVkIG1lc3NhZ2UgaGFuZGxpbmdcbiAgICogYmVmb3JlIGRpc3BhdGNoaW5nIHRvIHRoZSBjaGFubmVsIGNhbGxiYWNrcy5cbiAgICpcbiAgICogTXVzdCByZXR1cm4gdGhlIHBheWxvYWQsIG1vZGlmaWVkIG9yIHVubW9kaWZpZWRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXlsb2FkXG4gICAqIEBwYXJhbSB7aW50ZWdlcn0gcmVmXG4gICAqIEByZXR1cm5zIHtPYmplY3R9XG4gICAqL1xuICBvbk1lc3NhZ2UoX2V2ZW50LCBwYXlsb2FkLCBfcmVmKSB7XG4gICAgcmV0dXJuIHBheWxvYWQ7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBpc01lbWJlcih0b3BpYywgZXZlbnQsIHBheWxvYWQsIGpvaW5SZWYpIHtcbiAgICBpZiAodGhpcy50b3BpYyAhPT0gdG9waWMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGpvaW5SZWYgJiYgam9pblJlZiAhPT0gdGhpcy5qb2luUmVmKCkpIHtcbiAgICAgIGlmICh0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBcImRyb3BwaW5nIG91dGRhdGVkIG1lc3NhZ2VcIiwgeyB0b3BpYywgZXZlbnQsIHBheWxvYWQsIGpvaW5SZWYgfSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGpvaW5SZWYoKSB7XG4gICAgcmV0dXJuIHRoaXMuam9pblB1c2gucmVmO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcmVqb2luKHRpbWVvdXQgPSB0aGlzLnRpbWVvdXQpIHtcbiAgICBpZiAodGhpcy5pc0xlYXZpbmcoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnNvY2tldC5sZWF2ZU9wZW5Ub3BpYyh0aGlzLnRvcGljKTtcbiAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuam9pbmluZztcbiAgICB0aGlzLmpvaW5QdXNoLnJlc2VuZCh0aW1lb3V0KTtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHRyaWdnZXIoZXZlbnQsIHBheWxvYWQsIHJlZiwgam9pblJlZikge1xuICAgIGxldCBoYW5kbGVkUGF5bG9hZCA9IHRoaXMub25NZXNzYWdlKGV2ZW50LCBwYXlsb2FkLCByZWYsIGpvaW5SZWYpO1xuICAgIGlmIChwYXlsb2FkICYmICFoYW5kbGVkUGF5bG9hZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2hhbm5lbCBvbk1lc3NhZ2UgY2FsbGJhY2tzIG11c3QgcmV0dXJuIHRoZSBwYXlsb2FkLCBtb2RpZmllZCBvciB1bm1vZGlmaWVkXCIpO1xuICAgIH1cbiAgICBsZXQgZXZlbnRCaW5kaW5ncyA9IHRoaXMuYmluZGluZ3MuZmlsdGVyKChiaW5kKSA9PiBiaW5kLmV2ZW50ID09PSBldmVudCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBldmVudEJpbmRpbmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgYmluZCA9IGV2ZW50QmluZGluZ3NbaV07XG4gICAgICBiaW5kLmNhbGxiYWNrKGhhbmRsZWRQYXlsb2FkLCByZWYsIGpvaW5SZWYgfHwgdGhpcy5qb2luUmVmKCkpO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHJlcGx5RXZlbnROYW1lKHJlZikge1xuICAgIHJldHVybi
1BgY2hhbl9yZXBseV8ke3JlZn1gO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaXNDbG9zZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmNsb3NlZDtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGlzRXJyb3JlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZSA9PT0gQ0hBTk5FTF9TVEFURVMuZXJyb3JlZDtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGlzSm9pbmVkKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlID09PSBDSEFOTkVMX1NUQVRFUy5qb2luZWQ7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBpc0pvaW5pbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmpvaW5pbmc7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBpc0xlYXZpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmxlYXZpbmc7XG4gIH1cbn07XG5cbi8vIGpzL3Bob2VuaXgvYWpheC5qc1xudmFyIEFqYXggPSBjbGFzcyB7XG4gIHN0YXRpYyByZXF1ZXN0KG1ldGhvZCwgZW5kUG9pbnQsIGhlYWRlcnMsIGJvZHksIHRpbWVvdXQsIG9udGltZW91dCwgY2FsbGJhY2spIHtcbiAgICBpZiAoZ2xvYmFsLlhEb21haW5SZXF1ZXN0KSB7XG4gICAgICBsZXQgcmVxID0gbmV3IGdsb2JhbC5YRG9tYWluUmVxdWVzdCgpO1xuICAgICAgcmV0dXJuIHRoaXMueGRvbWFpblJlcXVlc3QocmVxLCBtZXRob2QsIGVuZFBvaW50LCBib2R5LCB0aW1lb3V0LCBvbnRpbWVvdXQsIGNhbGxiYWNrKTtcbiAgICB9IGVsc2UgaWYgKGdsb2JhbC5YTUxIdHRwUmVxdWVzdCkge1xuICAgICAgbGV0IHJlcSA9IG5ldyBnbG9iYWwuWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgIHJldHVybiB0aGlzLnhoclJlcXVlc3QocmVxLCBtZXRob2QsIGVuZFBvaW50LCBoZWFkZXJzLCBib2R5LCB0aW1lb3V0LCBvbnRpbWVvdXQsIGNhbGxiYWNrKTtcbiAgICB9IGVsc2UgaWYgKGdsb2JhbC5mZXRjaCAmJiBnbG9iYWwuQWJvcnRDb250cm9sbGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5mZXRjaFJlcXVlc3QobWV0aG9kLCBlbmRQb2ludCwgaGVhZGVycywgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHN1aXRhYmxlIFhNTEh0dHBSZXF1
1ZXN0IGltcGxlbWVudGF0aW9uIGZvdW5kXCIpO1xuICAgIH1cbiAgfVxuICBzdGF0aWMgZmV0Y2hSZXF1ZXN0KG1ldGhvZCwgZW5kUG9pbnQsIGhlYWRlcnMsIGJvZHksIHRpbWVvdXQsIG9udGltZW91dCwgY2FsbGJhY2spIHtcbiAgICBsZXQgb3B0aW9ucyA9IHtcbiAgICAgIG1ldGhvZCxcbiAgICAgIGhlYWRlcnMsXG4gICAgICBib2R5XG4gICAgfTtcbiAgICBsZXQgY29udHJvbGxlciA9IG51bGw7XG4gICAgaWYgKHRpbWVvdXQpIHtcbiAgICAgIGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgICBjb25zdCBfdGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiBjb250cm9sbGVyLmFib3J0KCksIHRpbWVvdXQpO1xuICAgICAgb3B0aW9ucy5zaWduYWwgPSBjb250cm9sbGVyLnNpZ25hbDtcbiAgICB9XG4gICAgZ2xvYmFsLmZldGNoKGVuZFBvaW50LCBvcHRpb25zKS50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UudGV4dCgpKS50aGVuKChkYXRhKSA9PiB0aGlzLnBhcnNlSlNPTihkYXRhKSkudGhlbigoZGF0YSkgPT4gY2FsbGJhY2sgJiYgY2FsbGJhY2soZGF0YSkpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgIGlmIChlcnIubmFtZSA9PT0gXCJBYm9ydEVycm9yXCIgJiYgb250aW1lb3V0KSB7XG4gICAgICAgIG9udGltZW91dCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2sobnVsbCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGNvbnRyb2xsZXI7XG4gIH1cbiAgc3RhdGljIHhkb21haW5SZXF1ZXN0KHJlcSwgbWV0aG9kLCBlbmRQb2ludCwgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjaykge1xuICAgIHJlcS50aW1lb3V0ID0gdGltZW91dDtcbiAgICByZXEub3BlbihtZXRob2QsIGVuZFBvaW50KTtcbiAgICByZXEub25sb2FkID0gKCkgPT4ge1xuICAgICAgbGV0IHJlc3BvbnNlID0gdGhpcy5wYXJzZUpTT04ocmVxLnJlc3BvbnNlVGV4dCk7XG4gICAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhyZXNwb25zZSk7XG4gICAgfTtcbiAgICBpZiAob250aW1lb3V0KSB7XG4gICAgICByZXEub250aW1lb3V0ID0gb250aW1lb3V0O1xuICAgIH1cbiAgICByZXEub25wcm9ncmVzcyA9ICgpID0+IHtcbiAgICB9O1xuICAgIHJlcS5zZW5kKGJvZHkpO1xuICAgIHJldHVybiByZXE7XG4gIH1cbiAgc3RhdGljIHhoclJlcXVlc3QocmVxLCBtZXRob2QsIGVuZFBvaW50LCBoZWFkZXJzLCBib2R5LCB0aW1lb3V0LCBvbnRpbWVvdXQsIGNhbGxiYWNrKSB7XG4gICAgcmVxLm9wZW4obWV0aG9kLCBlbmRQb2ludCwgdHJ1ZSk7XG4gICAgcmVxLnRpbWVvdXQgPSB0aW1lb3V0O1xuICAgIGZvciAobGV0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhoZWFkZXJzKSkge1xuICAgICAgcmVxLnNldFJlcXVlc3RIZWFkZXIoa2V5LCB2YWx1ZSk7XG4gICAgfVxuICAgIHJlcS5vbmVycm9yID0gKCkgPT4gY2FsbGJhY2sgJiYgY2FsbGJhY2sobnVsbCk7XG4gICAgcmVxLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgIGlmIChyZXEucmVhZHlTdGF0ZSA9PT0gWEhSX1NUQVRFUy5jb21wbGV0ZSAmJiBjYWxsYmFjaykge1xuICAgICAgICBsZXQgcmVzcG9uc2UgPSB0aGlzLnBhcnNlSlNPTihyZXEucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgY2FsbGJhY2socmVzcG9uc2UpO1xuICAgICAgfVxuICAgIH07XG4gICAgaWYgKG9udGltZW91dCkge1xuICAgICAgcmVxLm9udGltZW91dCA9IG9udGltZW91dDtcbiAgICB9XG4gICAgcmVxLnNlbmQoYm9keSk7XG4gICAgcmV0dXJuIHJlcTtcbiAgfVxuICBzdGF0aWMgcGFyc2VKU09OKHJlc3ApIHtcbiAgICBpZiAoIXJlc3AgfHwgcmVzcCA9PT0gXCJcIikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gSlNPTi5wYXJzZShyZXNwKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIGNvbnNvbGUgJiYgY29uc29sZS5sb2coXCJmYWlsZWQgdG8gcGFyc2UgSlNPTiByZXNwb25zZVwiLCByZXNwKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuICBzdGF0aWMgc2VyaWFsaXplKG9iaiwgcGFyZW50S2V5KSB7XG4gICAgbGV0IHF1ZXJ5U3RyID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgbGV0IHBhcmFtS2V5ID0gcGFyZW50S2V5ID8gYCR7cGFyZW50S2V5fVske2tleX1dYCA6IGtleTtcbiAgICAgIGxldCBwYXJhbVZhbCA9IG9ialtrZXldO1xuICAgICAgaWYgKHR5cGVvZiBwYXJhbVZhbCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBxdWVyeVN0ci5wdXNoKHRoaXMuc2VyaWFsaXplKHBhcmFtVmFsLCBwYXJhbUtleSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcnlTdHIucHVzaChlbmNvZGVVUklDb21wb25lbnQocGFyYW1LZXkpICsgXCI9XCIgKyBlbmNvZGVVUklDb21wb25lbnQocGFyYW1WYWwpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHF1ZXJ5U3RyLmpvaW4oXCImXCIpO1xuICB9XG4gIHN0YXRpYyBhcHBlbmRQYXJhbXModXJsLCBwYXJhbXMpIHtcbiAgICBpZiAoT2JqZWN0LmtleXMocGFyYW1zKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB1cmw7XG4gICAgfVxuICAgIGxldCBwcmVmaXggPSB1cmwubWF0Y2goL1xcPy8pID8gXCImXCIgOiBcIj9cIjtcbiAgICByZXR1cm4gYCR7dXJsfSR7cHJlZml4fSR7dGhpcy5zZXJpYWxpemUocGFyYW1zKX1gO1xuICB9XG59O1xuXG4vLyBqcy9waG9lbml4L2xvbmdwb2xsLmpzXG52YXIgYXJyYXlCdWZmZXJUb0Jhc2U2NCA9IChidWZmZXIpID0+IHtcbiAgbGV0IGJpbmFyeSA9IFwiXCI7XG4gIGxldCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG4gIGxldCBsZW4gPSBieXRlcy5ieXRlTGVuZ3RoO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgYmluYXJ5ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0pO1xuICB9XG4gI
1HJldHVybiBidG9hKGJpbmFyeSk7XG59O1xudmFyIExvbmdQb2xsID0gY2xhc3Mge1xuICBjb25zdHJ1Y3RvcihlbmRQb2ludCwgcHJvdG9jb2xzKSB7XG4gICAgaWYgKHByb3RvY29scyAmJiBwcm90b2NvbHMubGVuZ3RoID09PSAyICYmIHByb3RvY29sc1sxXS5zdGFydHNXaXRoKEFVVEhfVE9LRU5fUFJFRklYKSkge1xuICAgICAgdGhpcy5hdXRoVG9rZW4gPSBhdG9iKHByb3RvY29sc1sxXS5zbGljZShBVVRIX1RPS0VOX1BSRUZJWC5sZW5ndGgpKTtcbiAgICB9XG4gICAgdGhpcy5lbmRQb2ludCA9IG51bGw7XG4gICAgdGhpcy50b2tlbiA9IG51bGw7XG4gICAgdGhpcy5za2lwSGVhcnRiZWF0ID0gdHJ1ZTtcbiAgICB0aGlzLnJlcXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICAgIHRoaXMuYXdhaXRpbmdCYXRjaEFjayA9IGZhbHNlO1xuICAgIHRoaXMuY3VycmVudEJhdGNoID0gbnVsbDtcbiAgICB0aGlzLmN1cnJlbnRCYXRjaFRpbWVyID0gbnVsbDtcbiAgICB0aGlzLmJhdGNoQnVmZmVyID0gW107XG4gICAgdGhpcy5vbm9wZW4gPSBmdW5jdGlvbigpIHtcbiAgICB9O1xuICAgIHRoaXMub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuICAgIH07XG4gICAgdGhpcy5vbm1lc3NhZ2UgPSBmdW5jdGlvbigpIHtcbiAgICB9O1xuICAgIHRoaXMub25jbG9zZSA9IGZ1bmN0aW9uKCkge1xuICAgIH07XG4gICAgdGhpcy5wb2xsRW5kcG9pbnQgPSB0aGlzLm5vcm1hbGl6ZUVuZHBvaW50KGVuZFBvaW50KTtcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTT0NLRVRfU1R
1BVEVTLmNvbm5lY3Rpbmc7XG4gICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnBvbGwoKSwgMCk7XG4gIH1cbiAgbm9ybWFsaXplRW5kcG9pbnQoZW5kUG9pbnQpIHtcbiAgICByZXR1cm4gZW5kUG9pbnQucmVwbGFjZShcIndzOi8vXCIsIFwiaHR0cDovL1wiKS5yZXBsYWNlKFwid3NzOi8vXCIsIFwiaHR0cHM6Ly9cIikucmVwbGFjZShuZXcgUmVnRXhwKFwiKC4qKS9cIiArIFRSQU5TUE9SVFMud2Vic29ja2V0KSwgXCIkMS9cIiArIFRSQU5TUE9SVFMubG9uZ3BvbGwpO1xuICB9XG4gIGVuZHBvaW50VVJMKCkge1xuICAgIHJldHVybiBBamF4LmFwcGVuZFBhcmFtcyh0aGlzLnBvbGxFbmRwb2ludCwgeyB0b2tlbjogdGhpcy50b2tlbiB9KTtcbiAgfVxuICBjbG9zZUFuZFJldHJ5KGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4pIHtcbiAgICB0aGlzLmNsb3NlKGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4pO1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNPQ0tFVF9TVEFURVMuY29ubmVjdGluZztcbiAgfVxuICBvbnRpbWVvdXQoKSB7XG4gICAgdGhpcy5vbmVycm9yKFwidGltZW91dFwiKTtcbiAgICB0aGlzLmNsb3NlQW5kUmV0cnkoMTAwNSwgXCJ0aW1lb3V0XCIsIGZhbHNlKTtcbiAgfVxuICBpc0FjdGl2ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5yZWFkeVN0YXRlID09PSBTT0NLRVRfU1RBVEVTLm9wZW4gfHwgdGhpcy5yZWFkeVN0YXRlID09PSBTT0NLRVRfU1RBVEVTLmNvbm5lY3Rpbmc7XG4gIH1cbiAgcG9sbCgpIHtcbiAgICBjb25zdCBoZWFkZXJzID0geyBcIkFjY2VwdFwiOiBcImFwcGxpY2F0aW9uL2pzb25cIiB9O1xuICAgIGlmICh0aGlzLmF1dGhUb2tlbikge1xuICAgICAgaGVhZGVyc1tcIlgtUGhvZW5peC1BdXRoVG9rZW5cIl0gPSB0aGlzLmF1dGhUb2tlbjtcbiAgICB9XG4gICAgdGhpcy5hamF4KFwiR0VUXCIsIGhlYWRlcnMsIG51bGwsICgpID0+IHRoaXMub250aW1lb3V0KCksIChyZXNwKSA9PiB7XG4gICAgICBpZiAocmVzcCkge1xuICAgICAgICB2Y
1XIgeyBzdGF0dXMsIHRva2VuLCBtZXNzYWdlcyB9ID0gcmVzcDtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gNDEwICYmIHRoaXMudG9rZW4gIT09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLm9uZXJyb3IoNDEwKTtcbiAgICAgICAgICB0aGlzLmNsb3NlQW5kUmV0cnkoMzQxMCwgXCJzZXNzaW9uX2dvbmVcIiwgZmFsc2UpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRva2VuID0gdG9rZW47XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0dXMgPSAwO1xuICAgICAgfVxuICAgICAgc3dpdGNoIChzdGF0dXMpIHtcbiAgICAgICAgY2FzZSAyMDA6XG4gICAgICAgICAgbWVzc2FnZXMuZm9yRWFjaCgobXNnKSA9PiB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMub25tZXNzYWdlKHsgZGF0YTogbXNnIH0pLCAwKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLnBvbGwoKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAyMDQ6XG4gICAgICAgICAgdGhpcy5wb2xsKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNDEwOlxuICAgICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNPQ0tFVF9TVEFURVMub3BlbjtcbiAgICAgICAgICB0aGlzLm9ub3Blbih7fSk7XG4gICAgICAgICAgdGhpcy5wb2xsKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNDAzOlxuICAgICAgICAgIHRoaXMub25lcnJvcig0MDMpO1xuICAgICAgICAgIHRoaXMuY2xvc2UoMTAwOCwgXCJmb3JiaWRkZW5cIiwgZmFsc2UpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgIGNhc2UgNTAwOlxuICAgICAgICAgIHRoaXMub25lcnJvcig1MDApO1xuICAgICAgICAgIHRoaXMuY2xvc2VBbmRSZXRyeSgxMDExLCBcImludGVybmFsIHNlcnZlciBlcnJvclwiLCA1MDApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5oYW5kbGVkIHBvbGwgc3RhdHVzICR7c3RhdHVzfWApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIC8vIHdlIGNvbGxlY3QgYWxsIHB1c2hlcyB3aXRoaW4gdGhlIGN1cnJlbnQgZXZlbnQgbG9vcCBieVxuICAvLyBzZXRUaW1lb3V0IDAsIHdoaWNoIG9wdGltaXplcyBiYWNrLXRvLWJhY2sgcHJvY2VkdXJhbFxuICAvLyBwdXNoZXMgYWdhaW5zdCBhbiBlbXB0eSBidWZmZXJcbiAgc2VuZChib2R5KSB7XG4gICAgaWYgKHR5cGVvZiBib2R5ICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICBib2R5ID0gYXJyYXlCdWZmZXJUb0Jhc2U2NChib2R5KTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY3VycmVudEJhdGNoKSB7XG4gICAgICB0aGlzLmN1cnJlbnRCYXRjaC5wdXNoKGJvZHkpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5hd2FpdGluZ0JhdGNoQWNrKSB7XG4gICAgICB0aGlzLmJhdGNoQnVmZmVyLnB1c2goYm9keSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3VycmVudEJhdGNoID0gW2JvZHldO1xuICAgICAgdGhpcy5jdXJyZW50QmF0Y2hUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmJhdGNoU2VuZCh0aGlzLmN1cnJlbnRCYXRjaCk7XG4gICAgICAgIHRoaXMuY3VycmVudEJhdGNoID0gbnVsbDtcbiAgICAgIH0sIDApO1xuICAgIH1cbiAgfVxuICBiYXRjaFNlbmQobWVzc2FnZXMsIG9mZnNldCA9IDApIHtcbiAgICB0aGlzLmF3YWl0aW5nQmF0Y2hBY2sgPSB0cnVlO1xuICAgIGNvbnN0IG5leHQgPSBvZmZzZXQgKyBNQVhfTE9OR1BPTExfQkFUQ0hfU0laRTtcbiAgICBjb25zdCBiYXRjaCA9IG1lc3NhZ2VzLnNsaWNlKG9mZnNldCwgbmV4dCk7XG4gICAgdGhpcy5hamF4KFwiUE9TVFwiLCB7IFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24veC1uZGpzb25cIiB9LCBiYXRjaC5qb2luKFwiXFxuXCIpLCAoKSA9PiB0aGlzLm9uZXJyb3IoXCJ0aW1lb3V0XCIpLCAocmVzcCkgPT4ge1xuICAgICAgaWYgKCFyZXNwIHx8IHJlc3Auc3RhdHVzICE9PSAyMDApIHtcbiAgICAgICAgdGhpcy5hd2FpdGluZ0JhdGNoQWNrID0gZmFsc2U7XG4gICAgICAgIHRoaXMub25lcnJvcihyZXNwICYmIHJlc3Auc3RhdHVzKTtcbiAgICAgICAgdGhpcy5jbG9zZUFuZFJldHJ5KDEwMTEsIFwiaW50ZXJuYWwgc2VydmVyIGVycm9yXCIsIGZhbHNlKTtcbiAgICAgIH0gZWxzZSBpZiAobmV4dCA8IG1lc3NhZ2VzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLmJhdGNoU2VuZChtZXNzYWdlcywgbmV4dCk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuYmF0Y2hCdWZmZXIubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmJhdGNoU2VuZCh0aGlzLmJhdGNoQnVmZmVyKTtcbiAgICAgICAgdGhpcy5iYXRjaEJ1ZmZlciA9IFtdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5hd2FpdGluZ0JhdGNoQWNrID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgY2xvc2UoY29kZSwgcmVhc29uLCB3YXNDbGVhbikge1xuICAgIGZvciAobGV0IHJlcSBvZiB0aGlzLnJlcXMpIHtcbiAgICAgIHJlcS5hYm9ydCgpO1xuICAgIH1cbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTT0NLRVRfU1R
1BVEVTLmNsb3NlZDtcbiAgICBsZXQgb3B0cyA9IE9iamVjdC5hc3NpZ24oeyBjb2RlOiAxZTMsIHJlYXNvbjogdm9pZCAwLCB3YXNDbGVhbjogdHJ1ZSB9LCB7IGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4gfSk7XG4gICAgdGhpcy5iYXRjaEJ1ZmZlciA9IFtdO1xuICAgIGNsZWFyVGltZW91dCh0aGlzLmN1cnJlbnRCYXRjaFRpbWVyKTtcbiAgICB0aGlzLmN1cnJlbnRCYXRjaFRpbWVyID0gbnVsbDtcbiAgICBpZiAodHlwZW9mIENsb3NlRXZlbnQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIHRoaXMub25jbG9zZShuZXcgQ2xvc2VFdmVudChcImNsb3NlXCIsIG9wdHMpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vbmNsb3NlKG9wdHMpO1xuICAgIH1cbiAgfVxuICBhamF4KG1ldGhvZCwgaGVhZGVycywgYm9keSwgb25DYWxsZXJUaW1lb3V0LCBjYWxsYmFjaykge1xuICAgIGxldCByZXE7XG4gICAgbGV0IG9udGltZW91dCA9ICgpID0+IHtcbiAgICAgIHRoaXMucmVxcy5kZWxldGUocmVxKTtcbiAgICAgIG9uQ2FsbGVyVGltZW91dCgpO1xuICAgIH07XG4gICAgcmVxID0gQWpheC5yZXF1ZXN0KG1ldGhvZCwgdGhpcy5lbmRwb2ludFVSTCgpLCBoZWFkZXJzLCBib2R5LCB0aGlzLnRpbWVvdXQsIG9udGltZW91dCwgKHJlc3ApID0+IHtcbiAgICAgIHRoaXMucmVxcy5kZWxldGUocmVxKTtcbiAgICAgIGlmICh0aGlzLmlzQWN0aXZlKCkpIHtcbiAgICAgICAgY2FsbGJhY2socmVzcCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5yZXFzLmFkZChyZXEpO1xuICB9XG59O1xuXG4vLyBqcy9waG9lbml4L3ByZXNlbmNlLmpzXG52YXIgUHJlc2VuY2UgPSBjbGFzcyBfUHJlc2VuY2Uge1xuICBjb25zdHJ1Y3RvcihjaGFubmVsLCBvcHRzID0ge30pIHtcbiAgICBsZXQgZXZlbnRzID0gb3B0cy5ldmVudHMgfHwgeyBzdGF0ZTogXCJwcmVzZW5jZV9zdGF0ZVwiLCBkaWZmOiBcInByZXNlbmNlX2RpZmZcIiB9O1xuICAgIHRoaXMuc3RhdGUgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB0aGlzLnBlbmRpbmdEaWZmcyA9IFtdO1xuICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWw7XG4gICAgdGhpcy5qb2luUmVmID0gbnVsbDtcbiAgICB0aGlzLmNhbGxlciA9IHtcbiAgICAgIG9uSm9pbjogZnVuY3Rpb24oKSB7XG4gICAgICB9LFxuICAgICAgb25MZWF2ZTogZnVuY3Rpb24oKSB7XG4gICAgICB9LFxuICAgICAgb25TeW5jOiBmdW5jdGlvbigpIHtcbiAgICAgIH1cbiAgICB9O1xuICAgIHRoaXMuY2hhbm5lbC5vbihldmVudHMuc3RhdGUsIChuZXdTdGF0ZSkgPT4ge1xuICAgICAgbGV0IHsgb25Kb2luLCBvbkxlYXZlLCBvblN5bmMgfSA9IHRoaXMuY2FsbGVyO1xuICAgICAgdGhpcy5qb2luUmVmID0gdGhpcy5jaGFubmVsLmpvaW5SZWYoKTtcbiAgICAgIHRoaXMuc3RhdGUgPSBfUHJlc2VuY2Uuc3luY1N0YXRlKHRoaXMuc3RhdGUsIG5ld1N0YXRlLCBvbkpvaW4sIG9uTGVhdmUpO1xuICAgICAgdGhpcy5wZW5kaW5nRGlmZnMuZm9yRWFjaCgoZGlmZikgPT4ge1xuICAgICAgICB0aGlzLnN0YXRlID0gX1ByZXNlbmNlLnN5bmNEaWZmKHRoaXMuc3RhdGUsIGRpZmYsIG9uSm9pbiwgb25MZWF2ZSk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMucGVuZGluZ0RpZmZzID0gW107XG4gICAgICBvblN5bmMoKTtcbiAgICB9KTtcbiAgICB0aGlzLmNoYW5uZWwub24oZXZlbnRzLmRpZmYsIChkaWZmKSA9PiB7XG4gICAgICBsZXQgeyBvbkpvaW4sIG9uTGVhdmUsIG9uU3luYyB9ID0gdGhpcy5jYWxsZXI7XG4gICAgICBpZiAodGhpcy5pblBlbmRpbmdTeW5jU3RhdGUoKSkge1xuICAgICAgICB0aGlzLnBlbmRpbmdEaWZmcy5wdXNoKGRpZmYpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IF9QcmVzZW5jZS5zeW5jRGlmZih0aGlzLnN0YXRlLCBkaWZmLCBvbkpvaW4sIG9uTGVhdmUpO1xuICAgICAgICBvblN5bmMoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICBvbkpvaW4oY2FsbGJhY2spIHtcbiAgICB0aGlzLmNhbGxlci5vbkpvaW4gPSBjYWxsYmFjaztcbiAgfVxuICBvbkxlYXZlKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5jYWxsZXIub25MZWF2ZSA9IGNhbGxiYWNrO1xuICB9XG4gIG9uU3luYyhjYWxsYmFjaykge1xuICAgIHRoaXMuY2FsbGVyLm9uU3luYyA9IGNhbGxiYWNrO1xuICB9XG4gIGxpc3QoYnkpIHtcbiAgICByZXR1cm4gX1ByZXNlbmNlLmxpc3QodGhpcy5zdGF0ZSwgYnkpO1xuICB9XG4gIGluUGVuZGluZ1N5bmNTdGF0ZSgpIHtcbiAgICByZXR1cm4gIXRoaXMuam9pblJlZiB8fCB0aGlzLmpvaW5SZWYgIT09IHRoaXMuY2hhbm5lbC5qb2luUmVmKCk7XG4gIH1cbiAgLy8gbG93ZXItbGV2ZWwgcHVibGljIHN0YXRpYyBBUElcbiAgLyoqXG4gICAqIFVzZWQgdG8gc3luYyB0aGUgbGlzdCBvZiBwcmVzZW5jZXMgb24gdGhlIHNlcnZlclxuICAgKiB3aXRoIHRoZSBjbGllbnQncyBzdGF0ZS4gQW4gb3B0aW9uYWwgYG9uSm9pbmAgYW5kIGBvbkxlYXZlYCBjYWxsYmFjayBjYW5cbiAgICogYmUgcHJvdmlkZWQgdG8gcmVhY3QgdG8gY2hhbmdlcyBpbiB0aGUgY2xpZW50J3MgbG9jYWwgcHJlc2VuY2VzIGFjcm9zc1xuICAgKiBkaXNjb25uZWN0cyBhbmQgcmVjb25uZWN0cyB3aXRoIHRoZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcmVzZW5jZX1cbiAgICovXG4gIHN0YXRpYyBzeW5jU3RhdGUoY3VycmVudFN0YXRlLCBuZXdTdGF0ZSwgb25Kb2luLCBvbkxlYXZlKSB7XG4gICAgbGV0IHN0YXRlID0gdGhpcy50b051bGxQcm90b09iaih0aGlzLmNsb25lKGN1cnJlbnRTdGF0ZSkpO1xuICAgIG5ld1N0YXRlID0gdGhpcy50b051bGxQcm90b09iaihuZXdTdGF0ZSk7XG4gICAgbGV0IGpvaW5zID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgbGV0IGxlYXZlcyA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMubWFwKHN0YXRlLCAoa2V5LCBwcmVzZW5jZSkgPT4ge1xuICAgICAgaWYgKCFuZXdTdGF0ZVtrZXldKSB7XG4gICAgICAgIGxlYXZlc1trZXldID0gcHJlc2VuY2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5tYXAobmV3U3RhdGUsIChrZXksIG5ld1ByZXNlbmNlKSA9PiB7XG4gICAgICBsZXQgY3VycmVudFByZXNlbmNlID0gc3RhdGVba2V5XTtcbiAgICAgIGlmIChjdXJyZW50UHJlc2VuY2UpIHtcbiAgICAgICAgbGV0IG5ld1JlZnMgPSBuZXdQcmVzZW5jZS5tZXRhcy5tYXAoKG0pID0+IG0ucGh4X3JlZik7XG4gICAgICAgIGxldCBjdXJSZWZzID0gY3VycmVudFByZXNlbmNlLm1ldGFzLm1hcCgobSkgPT4gbS5waHhfcmVmKTtcbiAgICAgICAgbGV0IGpvaW5lZE1ldGFzID0gbmV3UHJlc2VuY2UubWV0YXMuZmlsdGVyKChtKSA9PiBjdXJSZWZzLmluZGV4T2YobS5waHhfcmVmKSA8IDApO1xuICAgICAgICBsZXQgbGVmdE1ldGFzID0gY3VycmVudFByZXNlbmNlLm1ldGFzLmZpbHRlcigobSkgPT4gbmV3
1UmVmcy5pbmRleE9mKG0ucGh4X3JlZikgPCAwKTtcbiAgICAgICAgaWYgKGpvaW5lZE1ldGFzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBqb2luc1trZXldID0gbmV3UHJlc2VuY2U7XG4gICAgICAgICAgam9pbnNba2V5XS5tZXRhcyA9IGpvaW5lZE1ldGFzO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsZWZ0TWV0YXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGxlYXZlc1trZXldID0gdGhpcy5jbG9uZShjdXJyZW50UHJlc2VuY2UpO1xuICAgICAgICAgIGxlYXZlc1trZXldLm1ldGFzID0gbGVmdE1ldGFzO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBqb2luc1trZXldID0gbmV3UHJlc2VuY2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMuc3luY0RpZmYoc3RhdGUsIHsgam9pbnMsIGxlYXZlcyB9LCBvbkpvaW4sIG9uTGVhdmUpO1xuICB9XG4gIC8qKlxuICAgKlxuICAgKiBVc2VkIHRvIHN5bmMgYSBkaWZmIG9mIHByZXNlbmNlIGpvaW4gYW5kIGxlYXZlXG4gICAqIGV2ZW50cyBmcm9tIHRoZSBzZXJ2ZXIsIGFzIHRoZXkgaGFwcGVuLiBMaWtlIGBzeW5jU3RhdGVgLCBgc3luY0RpZmZgXG4gICAqIGFjY2VwdHMgb3B0aW9uYWwgYG9uSm9pbmAgYW5kIGBvbkxlYXZlYCBjYWxsYmFja3MgdG8gcmVhY3QgdG8gYSB1c2VyXG4gICAqIGpvaW5pbmcgb3IgbGVhdmluZyBmcm9tIGEgZGV2aWNlLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJlc2VuY2V9XG4gICAqL1xuICBzdGF0aWMgc3luY0RpZmYoc3RhdGUsIGRpZmYsIG9uSm9pbiwgb25MZWF2ZSkge1xuICAgIHN0YXRlID0gdGhpcy50b051bGxQcm90b09iaihzdGF0ZSk7XG4gICAgbGV0IHsgam9pbnMsIGxlYXZlcyB9ID0gdGhpcy5jbG9uZShkaWZmKTtcbiAgICBpZiAoIW9uSm9pbikge1xuICAgICAgb25Kb2luID0gZnVuY3Rpb24oKSB7XG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoIW9uTGVhdmUpIHtcbiAgICAgIG9uTGVhdmUgPSBmdW5jdGlvbigpIHtcbiAgICAgIH07XG4gICAgfVxuICAgIHRoaXMubWFwKGpvaW5zLCAoa2V5LCBuZXdQcmVzZW5jZSkgPT4ge1xuICAgICAgbGV0IGN1cnJlbnRQcmVzZW5jZSA9IHN0YXRlW2tleV07XG4gICAgICBzdGF0ZVtrZXldID0gdGhpcy5jbG9uZShuZXdQcmVzZW5jZSk7XG4gICAgICBpZiAoY3VycmVudFByZXNlbmNlKSB7XG4gICAgICAgIGxldCBqb2luZWRSZWZzID0gc3RhdGVba2V5XS5tZXRhcy5tYXAoKG0pID0+IG0ucGh4X3JlZik7XG4gICAgICAgIGxldCBjdXJNZXRhcyA9IGN1cnJlbnRQcmVzZW5jZS5tZXRhcy5maWx0ZXIoKG0pID0+IGpvaW5lZ
1FJlZnMuaW5kZXhPZihtLnBoeF9yZWYpIDwgMCk7XG4gICAgICAgIHN0YXRlW2tleV0ubWV0YXMudW5zaGlmdCguLi5jdXJNZXRhcyk7XG4gICAgICB9XG4gICAgICBvbkpvaW4oa2V5LCBjdXJyZW50UHJlc2VuY2UsIG5ld1ByZXNlbmNlKTtcbiAgICB9KTtcbiAgICB0aGlzLm1hcChsZWF2ZXMsIChrZXksIGxlZnRQcmVzZW5jZSkgPT4ge1xuICAgICAgbGV0IGN1cnJlbnRQcmVzZW5jZSA9IHN0YXRlW2tleV07XG4gICAgICBpZiAoIWN1cnJlbnRQcmVzZW5jZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsZXQgcmVmc1RvUmVtb3ZlID0gbGVmdFByZXNlbmNlLm1ldGFzLm1hcCgobSkgPT4gbS5waHhfcmVmKTtcbiAgICAgIGN1cnJlbnRQcmVzZW5jZS5tZXRhcyA9IGN1cnJlbnRQcmVzZW5jZS5tZXRhcy5maWx0ZXIoKHApID0+IHtcbiAgICAgICAgcmV0dXJuIHJlZnNUb1JlbW92ZS5pbmRleE9mKHAucGh4X3JlZikgPCAwO1xuICAgICAgfSk7XG4gICAgICBvbkxlYXZlKGtleSwgY3VycmVudFByZXNlbmNlLCBsZWZ0UHJlc2VuY2UpO1xuICAgICAgaWYgKGN1cnJlbnRQcmVzZW5jZS5tZXRhcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgZGVsZXRlIHN0YXRlW2tleV07XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcmVzZW5jZXMsIHdpdGggc2VsZWN0ZWQgbWV0YWRhdGEuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwcmVzZW5jZXNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2hvb3NlclxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJlc2VuY2V9XG4gICAqL1xuICBzdGF0aWMgbGlzdChwcmVzZW5jZXMsIGNob29zZXIpIHtcbiAgICBpZiAoIWNob29zZXIpIHtcbiAgICAgIGNob29zZXIgPSBmdW5jdGlvbihrZXksIHByZXMpIHtcbiAgICAgICAgcmV0dXJuIHByZXM7XG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5tYXAocHJlc2VuY2VzLCAoa2V5LCBwcmVzZW5jZSkgPT4ge1xuICAgICAgcmV0dXJuIGNob29zZXIoa2V5LCBwcmVzZW5jZSk7XG4gICAgfSk7XG4gIH1cbiAgLy8gcHJpdmF0ZVxuICBzdGF0aWMgbWFwKG9iaiwgZnVuYykge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLm1hcCgoa2V5KSA9PiBmdW5jKGtleSwgb2JqW2tleV0pKTtcbiAgfVxuICAvLyBQcmVzZW5jZSBrZXlzIGFyZSBjaG9zZW4gb24gdGhlIHNlcnZlciBhbmQgbWF5IGNvbGxpZGUgd2l0aFxuICAvLyBPYmplY3QucHJvdG90eXBlIHByb3BlcnRpZXMgKFwiX19wcm90b19fXCIsIFwiY29uc3RydWN0b3JcIiwgLi4uKSwgc28gYW55XG4gIC8vIG9iamVjdCBpbmRleGVkIGJ5IHByZXNlbmNlIGtleSBtdXN0IG5vdCBoYXZlIGEgcHJvdG90eXBlIGNoYWluXG4gIC8vXG4gIC8vIFRPRE86IHJlcGxhY2UgdGhlIG51bGwtcHJvdG90eXBlIG9iamVjdHMgd2l0aCBNYXBzIGluIFBob2VuaXggMi4wXG4gIC8vIChicmVha2luZyBjaGFuZ2UgZm9yIHRoZSBsb3dlci1sZXZlbCBzdGF0aWMgQVBJKVxuICBzdGF0aWMgdG9OdWxsUHJvdG9PYmoob2JqKSB7XG4gICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gb2JqO1xuICAgIH1cbiAgICBsZXQgY2xlYW5lZCA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9iaikuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICBjbGVhbmVkW2tleV0gPSBvYmpba2V5XTtcbiAgICB9KTtcbiAgICByZXR1cm4gY2xlYW5lZDtcbiAgfVxuICBzdGF0aWMgY2xvbmUob2JqKSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkob2JqKSk7XG4gIH1cbn07XG5cbi8vIGpzL3Bob2VuaXgvc2VyaWFsaXplci5qc1xudmFyIHNlcmlhbGl6ZXJfZGVmYXVsdCA9IHtcbiAgSEVBREVSX0xFTkdUSDogMSxcbiAgTUVUQV9MRU5HVEg6IDQsXG4gIEtJTkRTOiB7IHB1c2g6IDAsIHJlcGx5OiAxLCBicm9hZGNhc3Q6IDIgfSxcbiAgZW5jb2RlKG1zZywgY2FsbGJhY2spIHtcbiAgICBpZiAobXNnLnBheWxvYWQuY29uc3RydWN0b3IgPT09IEFycmF5QnVmZmVyKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2sodGhpcy5iaW5hcnlFbmNvZGUobXNnKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBwYXlsb2FkID0gW21zZy5qb2luX3JlZiwgbXNnLnJlZiwgbXNnLnRvcGljLCBtc2cuZXZlbnQsIG1zZy5wYXlsb2FkXTtcbiAgICAgIHJldHVybiBjYWxsYmFjayhKU09OLnN0cmluZ2lmeShwYXlsb2FkKSk7XG4gICAgfVxuICB9LFxuICBkZWNvZGUocmF3UGF5bG9hZCwgY2FsbGJhY2spIHtcbiAgICBpZiAocmF3UGF5bG9hZC5jb25zdHJ1Y3RvciA9PT0gQXJyYXlCdWZmZXIpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjayh0aGlzLmJpbmFyeURlY29kZShyYXdQYXlsb2FkKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBbam9pbl9yZWYsIHJlZiwgdG9waWMsIGV2ZW50LCBwYXlsb2FkXSA9IEpTT04ucGFyc2UocmF3UGF5bG9hZCk7XG4gICAgICByZXR1cm4gY2FsbGJhY2soeyBqb2luX3JlZiwgcmVmLCB0b3BpYywgZXZlbnQsIHBheWxvYWQgfSk7XG4gICAgfVxuICB9LFxuICAvLyBwcml2YXRlXG4gIGJpbmFyeUVuY29kZShtZXNzYWdlKSB7XG4gICAgbGV0IHsgam9pbl9yZWYsIHJlZiwgZXZlbnQsIHRvcGljLCBwYXlsb2FkIH0gPSBtZXNzYWdlO1xuICAgIGxldCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7XG4gICAgbGV0IGpvaW5SZWZCeXRlcyA9IGVuY29kZXIuZW5jb2RlKGpvaW5fcmVmKTtcbiAgICBsZXQgcmVmQnl0ZXMgPSBlbmNvZGVyLmVuY29kZShyZWYpO1xuICAgIGxldCB0b3BpY0J5dGVzID0gZW5jb2Rlci5lbmNvZGUodG9waWMpO1xuICAgIGxldCBldmVudEJ5dGVzID0gZW5jb2Rlci5lbmNvZGUoZXZlbnQpO1xuICAgIHRoaXMuYXNzZXJ0RmllbGRTaXplKGpvaW5SZWZCeXRlcy5ieXRlTGVuZ3RoLCBcImpvaW5fcmVmXCIpO1xuICAgIHRoaXMuYXNzZXJ0RmllbGRTaXplKHJlZkJ5dGVzLmJ5dGVMZW5ndGgsIFwicmVmXCIpO1xuICAgIHRoaXMuYXNzZXJ0RmllbGRTaXplKHRvcGljQnl0ZXMuYnl0ZUxlbmd0aCwgXCJ0b3BpY1wiKTtcbiAgICB0aGlzLmFzc2VydEZpZWxkU2l6ZShldmVudEJ5dGVzLmJ5dGVMZW5ndGgsIFwiZXZlbnRcIik7XG4gICAgbGV0IG1ldGFMZW5ndGggPSB0aGlzLk1FVEFfTEVOR1RIICsgam9pblJlZkJ5dGVzLmJ5dGVMZW5ndGggKyByZWZCeXRlcy5ieXRlTGVuZ3RoICsgdG9waWNCeXRlcy5ieXRlTGVuZ3RoICsgZXZlbnRCeXRlcy5ieXRlTGVuZ3RoO1xuICAgIGxldCBoZWFkZXIgPSBuZXcgQXJyYXlCdWZmZXIodGhpcy5IRUFERVJfTEVOR1RIICsgbWV0YUxlbmd0aCk7XG4gICAgbGV0IGhlYWRlckJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoaGVhZGVyKTtcbiAgICBsZXQgdmlldyA9IG5ldyBEYXRhVmlldyhoZWFkZXIpO1xuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIHZpZXcuc2V0VWludDgob2Zmc2V0KyssIHRoaXMuS0lORFMucHVzaCk7XG4gICAgdmlldy5zZXRVaW50OChvZmZzZXQrKywgam9pblJlZkJ5dGVzLmJ5dGVMZW5ndGgpO1xuICAgIHZpZXcuc2V0VWludDgob2Zmc2V0KyssIHJlZkJ5dGVzLmJ5dGVMZW5ndGgpO1xuICAgIHZpZXcuc2V0VWludDgob2Zmc2V0KyssIHRvcGljQnl0ZXMuYnl0ZUxlbmd0aCk7XG4gICAgdmlldy5zZXRVaW50OChvZmZzZXQrKywgZXZlbnRCeXRlcy5ieXRlTGVuZ3RoKTtcbiAgICBoZWFkZXJCeXRlcy5zZXQoam9pblJlZkJ5dGVzLCBvZmZzZXQpO1xuICAgIG9mZnNldCArPSBqb2luUmVmQnl0ZXMuYnl0ZUxlbmd0aDtcbiAgICBoZWFkZXJCeXRlcy5zZXQocmVmQnl0ZXMsIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IHJlZkJ5dGVzLmJ5dGVMZW5ndGg7XG4gICAgaGVhZGVyQnl0ZXMuc2V0KHRvcGljQnl0ZXMsIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IHRvcGljQnl0ZXMuYnl0ZUxlbmd0aDtcbiAgICBoZWFkZXJCeXRlcy5zZXQoZXZlbnRCeXRlcywgb2Zmc2V0KTtcbiAgICBvZmZzZXQgKz0gZXZlbnRCeXRlcy5ieXRlTGVuZ3RoO1xuICAgIHZhciBjb21iaW5lZCA9IG5ldyBVaW50OEFycmF5KGhlYWRlci5ieXRlTGVuZ3RoICsgcGF5bG9hZC5ieXRlTGVuZ3RoKTtcbiAgICBjb21iaW5lZC5zZXQoaGVhZG
1VyQnl0ZXMsIDApO1xuICAgIGNvbWJpbmVkLnNldChuZXcgVWludDhBcnJheShwYXlsb2FkKSwgaGVhZGVyLmJ5dGVMZW5ndGgpO1xuICAgIHJldHVybiBjb21iaW5lZC5idWZmZXI7XG4gIH0sXG4gIGFzc2VydEZpZWxkU2l6ZShzaXplLCBuYW1lKSB7XG4gICAgaWYgKHNpemUgPiAyNTUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdW5hYmxlIHRvIGNvbnZlcnQgJHtuYW1lfSB0byBiaW5hcnk6IG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDI1NSBieXRlcywgYnV0IGlzICR7c2l6ZX0gYnl0ZXNgKTtcbiAgICB9XG4gIH0sXG4gIGJpbmFyeURlY29kZShidWZmZXIpIHtcbiAgICBsZXQgdmlldyA9IG5ldyBEYXRhVmlldyhidWZmZXIpO1xuICAgIGxldCBraW5kID0gdmlldy5nZXRVaW50OCgwKTtcbiAgICBsZXQgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpO1xuICAgIHN3aXRjaCAoa2luZCkge1xuICAgICAgY2FzZSB0aGlzLktJTkRTLnB1c2g6XG4gICAgICAgIHJldHVybiB0aGlzLmRlY29kZVB1c2goYnVmZmVyLCB2aWV3LCBkZWNvZGVyKTtcbiAgICAgIGNhc2UgdGhpcy5LSU5EUy5yZXBseTpcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlUmVwbHkoYnVmZmVyLCB2aWV3LCBkZWNvZGVyKTtcbiAgICAgIGNhc2UgdGhpcy5LSU5EUy5icm9hZGNhc3Q6XG4gICAgICAgIHJldHVybiB0aGlzLmRlY29kZUJyb2FkY2FzdChidWZmZXIsIHZpZXcsIGRlY29kZXIpO1xuICAgIH1cbiAgfSxcbiAgZGVjb2RlUHVzaChidWZmZXIsIHZpZXcsIGRlY29kZXIpIHtcbiAgICBsZXQgam9pblJlZlNpemUgPSB2aWV3LmdldFVpbnQ4KDEpO1xuICAgIGxldCB0b3BpY1NpemUgPSB2aWV3LmdldFVpbnQ4KDIpO1xuICAgIGxldCBldmVudFNpemUgPSB2aWV3LmdldFVpbnQ4KDMpO1xuICAgIGxldCBvZmZzZXQgPSB0aGlzLkhFQURFUl9MRU5HVEggKyB0aGlzLk1FVEFfTEVOR1RIIC0gMTtcbiAgICBsZXQgam9pblJlZiA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIGpvaW5SZWZTaXplKSk7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgam9pblJlZlNpemU7XG4gICAgbGV0IHRvcGljID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgdG9waWNTaXplKSk7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgdG9waWNTaXplO1xuICAgIGxldCBldmVudCA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIGV2ZW50U2l6ZSkpO1xuICAgIG9mZnNldCA9IG9mZnNldCArIGV2ZW50U2l6ZTtcbiAgICBsZXQgZGF0YSA9IGJ1ZmZlci5zbGljZShvZmZzZXQsIGJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICByZXR1cm4geyBqb2luX3JlZjogam9pblJlZiwgcmVmOiBudWxsLCB0b3BpYywgZXZlbnQsIHBheWxvYWQ6IGRhdGEgfTtcbiAgfSxcbiAgZGVjb2RlUmVwbHkoYnVmZmVyLCB2aWV3LCBkZWNvZGVyKSB7XG4gICAgbGV0IGpvaW5SZWZTaXplID0gdmlldy5nZXRVaW50OCgxKTtcbiAgICBsZXQgcmVmU2l6ZSA9IHZpZXcuZ2V0VWludDgoMik7XG4gICAgbGV0IHRvcGljU2l6ZSA9IHZpZXcuZ2V0VWludDgoMyk7XG4gICAgbGV0IGV2ZW50U2l6ZSA9IHZpZXcuZ2V0VWludDgoNCk7XG4gICAgbGV0IG9mZnNldCA9IHRoaXMuSEVBREVSX0xFTkdUSCArIHRoaXMuTUVUQV9MRU5HVEg7XG4gICAgbGV0IGpvaW5SZWYgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBqb2luUmVmU2l6ZSkpO1xuICAgIG9mZnNldCA9IG9mZnNldCArIGpvaW5SZWZTaXplO1xuICAgIGxldCByZWYgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyByZWZTaXplKSk7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgcmVmU2l6ZTtcbiAgICBsZXQgdG9waWMgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyB0b3BpY1NpemUpKTtcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyB0b3BpY1NpemU7XG4gICAgbGV0IGV2ZW50ID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgZXZlbnRTaXplKSk7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgZXZlbnRTaXplO1xuICAgIGxldCBkYXRhID0gYnVmZmVyLnNsaWNlKG9mZnNldCwgYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgIGxldCBwYXlsb2FkID0geyBzdGF0dXM6IGV2ZW50LCByZXNwb25zZTogZGF0YSB9O1xuICAgIHJldHVybiB7IGpvaW5fcmVmOiBqb2luUmVmLCByZWYsIHRvcGljLCBldmVudDogQ0hBTk5FTF9FVkVOVFMucmVwbHksIHBheWxvYWQgfTtcbiAgfSxcbiAgZGVjb2RlQnJvYWRjYXN0KGJ1ZmZlciwgdmlldywgZGVjb2Rlcikge1xuICAgIGxldCB0b3BpY1NpemUgPSB2aWV3LmdldFVpbnQ4KDEpO1xuICAgIGxldCBldmVudFNpemUgPSB2aWV3LmdldFVpbnQ4KDIpO1xuICAgIGxldCBvZmZzZXQgPSB0aGlzLkhFQURFUl9MRU5HVEggKyAyO1xuICAgIGxldCB0b3BpYyA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIHRvcGljU2l6ZSkpO1xuICAgIG9mZnNldCA9IG9mZnNldCArIHRvcGljU2l6ZTtcbiAgICBsZXQgZXZlbnQgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBldmVudFNpemUpKTtcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyBldmVudFNpemU7XG4gICAgbGV0IGRhdGEgPSBidWZmZXIuc2xpY2Uob2Zmc2V0LCBidWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgcmV0dXJuIHsgam9pbl9yZWY6IG51bGwsIHJlZjogbnVsbCwgdG9waWMsIGV2ZW50LCBwYXlsb2FkOiBkYXRhIH07XG4gIH1cbn07XG5cbi8vIGpzL3Bob2VuaXgvc29ja2V0LmpzXG52YXIgU29ja2V0ID0gY2xhc3Mge1xuICBjb25zdHJ1Y3RvcihlbmRQb2ludCwgb3B0cyA9IHt9KSB7XG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcyA9IHsgb3BlbjogW10sIGNsb3NlOiBbXSwgZXJyb3I6IFtdLCBtZXNzYWdlOiBbXSB9O1xuICAgIHRoaXMuY2hhbm5lbHMgPSBbXTtcbiAgICB0aGlzLnNlbmRCdWZmZXIgPSBbXTtcbiAgICB0aGlzLnJlZiA9IDA7XG4gICAgdGhpcy5mYWxsYmFja1JlZiA9IG51bGw7XG4gICAgdGhpcy50aW1lb3V0ID0gb3B0cy50aW1lb3V0IHx8IERFRkFVTFRfVElNRU9VVDtcbiAgICB0aGlzLnRyYW5zcG9ydCA9IG9wdHMudHJhbnNwb3J0IHx8IGdsb2JhbC5XZWJTb2NrZXQgfHwgTG9uZ1BvbGw7XG4gICAgdGhpcy5wcmltYXJ5UGFzc2VkSGVhbHRoQ2hlY2sgPSBmYWxzZTtcbiAgICB0aGlzLmxvbmdQb2xsRmFsbGJhY2tNcyA9IG9wdHMubG9uZ1BvbGxGYWxsYmFja01zO1xuICAgIHRoaXMuZmFsbGJhY2tUaW1lciA9IG51bGw7XG4gICAgdGhpcy5zZXNzaW9uU3RvcmUgPSBvcHRzLnNlc3Npb25TdG9yYWdlIHx8IGdsb2JhbCAmJiBnbG9iYWwuc2Vzc2lvblN0b3JhZ2U7XG4gICAgdGhpcy5lc3RhYmxpc2hlZENvbm5lY3Rpb25zID0gMDtcbiAgICB0aGlzLmRlZmF1bHRFbmNvZGVyID0gc2VyaWFsaXplcl9kZWZhdWx0LmVuY29kZS5iaW5kKHNlcmlhbGl6ZXJfZGVmYXVsdCk7XG4gICAgdGhpcy5kZWZh
1dWx0RGVjb2RlciA9IHNlcmlhbGl6ZXJfZGVmYXVsdC5kZWNvZGUuYmluZChzZXJpYWxpemVyX2RlZmF1bHQpO1xuICAgIHRoaXMuY2xvc2VXYXNDbGVhbiA9IHRydWU7XG4gICAgdGhpcy5kaXNjb25uZWN0aW5nID0gZmFsc2U7XG4gICAgdGhpcy5iaW5hcnlUeXBlID0gb3B0cy5iaW5hcnlUeXBlIHx8IFwiYXJyYXlidWZmZXJcIjtcbiAgICB0aGlzLmNvbm5lY3RDbG9jayA9IDE7XG4gICAgdGhpcy5wYWdlSGlkZGVuID0gZmFsc2U7XG4gICAgaWYgKHRoaXMudHJhbnNwb3J0ICE9PSBMb25nUG9sbCkge1xuICAgICAgdGhpcy5lbmNvZGUgPSBvcHRzLmVuY29kZSB8fCB0aGlzLmRlZmF1bHRFbmNvZGVyO1xuICAgICAgdGhpcy5kZWNvZGUgPSBvcHRzLmRlY29kZSB8fCB0aGlzLmRlZmF1bHREZWNvZGVyO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVuY29kZSA9IHRoaXMuZGVmYXVsdEVuY29kZXI7XG4gICAgICB0aGlzLmRlY29kZSA9IHRoaXMuZGVmYXVsdERlY29kZXI7XG4gICAgfVxuICAgIGxldCBhd2FpdGluZ0Nvbm5lY3Rpb25PblBhZ2VTaG93ID0gbnVsbDtcbiAgICBpZiAocGh4V2luZG93ICYmIHBoeFdpbmRvdy5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICBwaHhXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBhZ2VoaWRlXCIsIChfZSkgPT4ge1xuICAgICAgICBpZiAodGhpcy5jb25uKSB7XG4gICAgICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgYXdhaXRpbmdDb25uZWN0aW9uT25QYWdlU2hvdyA9IHRoaXMuY29ubmVjdENsb2NrO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHBoeFdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGFnZXNob3dcIiwgKF9lKSA9PiB7XG4gICAgICAgIGlmIChhd2FpdGluZ0Nvbm5lY3Rpb25PblBhZ2VTaG93ID09PSB0aGlzLmNvbm5lY3RDbG9jaykge1xuICAgICAgICAgIGF3YWl0aW5nQ29ubmVjdGlvbk9uUGFnZVNob3cgPSBudWxsO1xuICAgICAgICAgIHRoaXMuY29ubmVjdCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHBoeFdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwidmlzaWJpbGl0eWNoYW5nZVwiLCAoKSA9PiB7XG4gICAgICAgIGlmIChkb2N1bWVudC52aXNpYmlsaXR5U3RhdGUgPT09IFwiaGlkZGVuXCIpIHtcbiAgICAgICAgICB0aGlzLnBhZ2VIaWRkZW4gPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucGFnZUhpZGRlbiA9IGZhbHNlO1xuICAgICAgICAgIGlmICghdGhpcy5pc0Nvbm5lY3RlZCgpICYmICF0aGlzLmNsb3NlV2FzQ2xlYW4pIHtcbiAgICAgICAgICAgIHRoaXMudGVhcmRvd24oKCkgPT4gdGhpcy5jb25uZWN0KCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWxNcyA9IG9wdHMuaGVhcnRiZWF0SW50ZXJ2YWxNcyB8fCAzZTQ7XG4gICAgdGhpcy5yZWpvaW5BZnRlck1zID0gKHRyaWVzKSA9PiB7XG4gICAgICBpZiAob3B0cy5yZWpvaW5BZnRlck1zKSB7XG4gICAgICAgIHJldHVybiBvcHRzLnJlam9pbkFmdGVyTXModHJpZXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFsxZTMsIDJlMywgNWUzXVt0cmllcyAtIDFdIHx8IDFlNDtcbiAgICAgIH1cbiAgICB9O1xuICAgIHRoaXMucmVjb25uZWN0QWZ0ZXJNcyA9ICh0cmllcykgPT4ge1xuICAgICAgaWYgKG9wdHMucmVjb25uZWN0QWZ0ZXJNcykge1xuICAgICAgICByZXR1cm4gb3B0cy5yZWNvbm5lY3RBZnRlck1zKHRyaWVzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbMTAsIDUwLCAxMDAsIDE1MCwgMjAwLCAyNTAsIDUwMCwgMWUzLCAyZTNdW3RyaWVzIC0gMV0gfHwgNWUzO1xuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5sb2dnZXIgPSBvcHRzLmxvZ2dlciB8fCBudWxsO1xuICAgIGlmICghdGhpcy5sb2dnZXIgJiYgb3B0cy5kZWJ1Zykge1xuICAgICAgdGhpcy5sb2dnZXIgPSAoa2luZCwgbXNnLCBkYXRhKSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKGAke2tpbmR9OiAke21zZ31gLCBkYXRhKTtcbiAgICAgIH07XG4gICAgfVxuICAgIHRoaXMubG9uZ3BvbGxlclRpbWVvdXQgPSBvcHRzLmxvbmdwb2xsZXJUaW1lb3V0IHx8IDJlNDtcbiAgICB0aGlzLnBhcmFtcyA9IGNsb3N1cmUob3B0cy5wYXJhbXMgfHwge30pO1xuICAgIHRoaXMuZW5kUG9pbnQgPSBgJHtlbmRQb2ludH0vJHtUUkFOU1BPUlRTLndlYnNvY2tldH1gO1xuICAgIHRoaXMudnNuID0gb3B0cy52c24gfHwgREVGQVVMVF9WU047XG4gICAgdGhpcy5oZWFydGJlYXRUaW1lb3V0VGltZXIgPSBudWxsO1xuICAgIHRoaXMuaGVhcnRiZWF0VGltZXIgPSBudWxsO1xuICAgIHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZiA9IG51bGw7XG4gICAgdGhpcy5yZWNvbm5lY3RUaW1lciA9IG5ldyBUaW1lcigoKSA9PiB7XG4gICAgICBpZiAodGhpcy5wYWdlSGlkZGVuKSB7XG4gICAgICAgIHRoaXMubG9nKFwiTm90IHJlY29ubmVjdGluZyBhcyBwYWdlIGlzIGhpZGRlbiFcIik7XG4gICAgICAgIHRoaXMudGVhcmRvd24oKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy50ZWFyZG93bigoKSA9PiB0aGlzLmNvbm5lY3QoKSk7XG4gICAgfSwgdGhpcy5yZWNvbm5lY3RBZnRlck1zKTtcbiAgICB0aGlzLmF1dGhUb2tlbiA9IG9wdHMuYXV0aFRva2VuICYmIGNsb3N1cmUob3B0cy5hdXRoVG9rZW4pO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBMb25nUG9sbCB0cmFuc3BvcnQgcmVmZXJlbmNlXG4gICAqL1xuICBnZXRMb25nUG9sbFRyYW5zcG9ydCgpIHtcbiAgICByZXR1cm4gTG9uZ1BvbGw7XG4gIH1cbiAgLyoqXG4gICAqIERpc2Nvbm5lY3RzIGFuZCByZXBsYWNlcyB0aGUgYWN0aXZlIHRyYW5zcG9ydFxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBuZXdUcmFuc3BvcnQgLSBUaGUgbmV3IHRyYW5zcG9ydCBjbGFzcyB0byBpbnN0YW50aWF0ZVxuICAgKlxuICAgKi9cbiAgcmVwbGFjZVRyYW5zcG9ydChuZXdUcmFuc3BvcnQpIHtcbiAgICB0aGlzLmNvbm5lY3RDbG9jaysrO1xuICAgIHRoaXMuY2xvc2VXYXNDbGVhbiA9IHRydWU7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuZmFsbGJhY2tUaW1lcik7XG4gICAgdGhpcy5yZWNvbm5lY3RUaW1lci5yZXNldCgpO1xuICAgIGlmICh0aGlzLmNvbm4pIHtcbiAgICAgIHRoaXMuY29ubi5jbG9zZSgpO1xuICAgICAgdGhpcy5jb25uID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy50cmFuc3BvcnQgPSBuZXdUcmFuc3BvcnQ7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHNvY2tldCBwcm90b2NvbFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgcHJvdG9jb2woKSB7XG4gICAgcmV0dXJuIGxvY2F0aW9uLnByb3RvY29sLm1hdGNoKC9eaHR0cHMvKSA/IFwid3NzXCIgOiBcIndzXCI7XG4gIH1cbiAgLyoqXG4gICAqIFRoZSBmdWxseSBxdWFsaWZpZWQgc29ja2V0IHVybFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgZW5kUG9pbnRVUkwoKSB7XG4gICAgbGV0IHVyaSA9IEFqYXguYXBwZW5kUGFyYW1zKFxuICAgICAgQWpheC5hcHBlbmRQYXJhbXModGhpcy5lbmRQb2ludCwgdGhpcy5wYXJhbXMoKSksXG4gICAgICB7IHZzbjogdGhpcy52c24gfV
1xuICAgICk7XG4gICAgaWYgKHVyaS5jaGFyQXQoMCkgIT09IFwiL1wiKSB7XG4gICAgICByZXR1cm4gdXJpO1xuICAgIH1cbiAgICBpZiAodXJpLmNoYXJBdCgxKSA9PT0gXCIvXCIpIHtcbiAgICAgIHJldHVybiBgJHt0aGlzLnByb3RvY29sKCl9OiR7dXJpfWA7XG4gICAgfVxuICAgIHJldHVybiBgJHt0aGlzLnByb3RvY29sKCl9Oi8vJHtsb2NhdGlvbi5ob3N0fSR7dXJpfWA7XG4gIH1cbiAgLyoqXG4gICAqIERpc2Nvbm5lY3RzIHRoZSBzb2NrZXRcbiAgICpcbiAgICogU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DbG9zZUV2ZW50I1N0YXR1c19jb2RlcyBmb3IgdmFsaWQgc3RhdHVzIGNvZGVzLlxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayAtIE9wdGlvbmFsIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCBhZnRlciBzb2NrZXQgaXMgZGlzY29ubmVjdGVkLlxuICAgKiBAcGFyYW0ge2ludGVnZXJ9IGNvZGUgLSBBIHN0YXR1cyBjb2RlIGZvciBkaXNjb25uZWN0aW9uIChPcHRpb25hbCkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb24gLSBBIHRleHR1YWwgZGVzY3JpcHRpb24gb2YgdGhlIHJlYXNvbiB0byBkaXNjb25uZWN0LiAoT3B0aW9uYWwpXG4gICAqL1xuICBkaXNjb25uZWN0KGNhbGxiYWNrLCBjb2RlLCByZWFzb24pIHtcbiAgICB0aGlzLmNvbm5lY3RDbG9jaysrO1xuICAgIHRoaXMuZGlzY29ubmVjdGluZyA9IHRydWU7XG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gdHJ1ZTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5mYWxsYmFja1RpbWVyKTtcbiAgICB0aGlzLnJlY29ubmVjdFRpbWVyLnJlc2V0KCk7XG4gICAgdGhpcy50ZWFyZG93bigoKSA9PiB7XG4gICAgICB0aGlzLmRpc2Nvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCk7XG4gICAgfSwgY29kZSwgcmVhc29uKTtcbiAgfVxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbXMgdG8gc2VuZCB3aGVuIGNvbm5lY3RpbmcsIGZvciBleGFtcGxlIGB7dXNlcl9pZDogdXNlclRva2VufWBcbiAgICpcbiAgICogUGFzc2luZyBwYXJhbXMgdG8gY29ubmVjdCBpcyBkZXByZWNhdGVkOyBwYXNzIHRoZW0gaW4gdGhlIFNvY2tldCBjb25zdHJ1Y3RvciBpbnN0ZWFkOlxuICAgKiBgbmV3IFNvY2tldChcIi9zb2NrZXRcIiwge3BhcmFtczoge3VzZXJfaWQ6IHVzZXJUb2tlbn19KWAuXG4gICAqL1xuICBjb25uZWN0KHBhcmFtcykge1xuICAgIGlmIChwYXJhbXMpIHtcbiAgICAgIGNvbnNvbGUgJiYgY29uc29sZS5sb2coXCJwYXNzaW5nIHBhcmFtcyB0byBjb25uZWN0IGlzIGRlcHJlY2F0ZWQuIEluc3RlYWQgcGFzcyA6cGFyYW1zIHRvIHRoZSBTb2NrZXQgY29uc3RydWN0b3JcIik7XG4gICAgICB0aGlzLnBhcmFtcyA9IGNsb3N1cmUocGFyYW1zKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY29ubiAmJiAhdGhpcy5kaXNjb25uZWN0aW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmxvbmdQb2xsRmFsbGJhY2tNcyAmJiB0aGlzLnRyYW5zcG9ydCAhPT0gTG9uZ1BvbGwpIHtcbiAgICAgIHRoaXMuY29ubmVjdFdpdGhGYWxsYmFjayhMb25nUG9sbCwgdGhpcy5sb25nUG9sbEZhbGxiYWNrTXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRyYW5zcG9ydENvbm5lY3QoKTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIExvZ3MgdGhlIG1lc3NhZ2UuIE92ZXJyaWRlIGB0aGlzLmxvZ2dlcmAgZm9yIHNwZWNpYWxpemVkIGxvZ2dpbmcuIG5vb3BzIGJ5IGRlZmF1bHRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtpbmRcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1zZ1xuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICAgKi9cbiAgbG9nKGtpbmQsIG1zZywgZGF0YSkge1xuICAgIHRoaXMubG9nZ2VyICYmIHRoaXMubG9nZ2VyKGtpbmQsIG1zZywgZGF0YSk7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiBhIGxvZ2dlciBoYXMgYmVlbiBzZXQgb24gdGhpcyBzb2NrZXQuXG4gICAqL1xuICBoYXNMb2dnZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMubG9nZ2VyICE9PSBudWxsO1xuICB9XG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgY2FsbGJhY2tzIGZvciBjb25uZWN0aW9uIG9wZW4gZXZlbnRzXG4gICAqXG4gICAqIEBleGFtcGxlIHNvY2tldC5vbk9wZW4oZnVuY3Rpb24oKXsgY29uc29sZS5pbmZvKFwidGhlIHNvY2tldCB3YXMgb3BlbmVkXCIpIH0pXG4gICAqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBvbk9wZW4oY2FsbGJhY2spIHtcbiAgICBsZXQgcmVmID0gdGhpcy5tYWtlUmVmKCk7XG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5vcGVuLnB1c2goW3JlZiwgY2FsbGJhY2tdKTtcbiAgICByZXR1cm4gcmVmO1xuICB9XG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgY2FsbGJhY2tzIGZvciBjb25uZWN0aW9uIGNsb3NlIGV2ZW50c1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgb25DbG9zZShjYWxsYmFjaykge1xuICAgIGxldCByZWYgPSB0aGlzLm1ha2VSZWYoKTtcbiAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLmNsb3NlLnB1c2goW3JlZiwgY2FsbGJhY2tdKTtcbiAgICByZXR1cm4gcmVmO1xuICB9XG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgY2FsbGJhY2tzIGZvciBjb25uZWN0aW9uIGVycm9yIGV2ZW50c1xuICAgKlxuICAgKiBAZXhhbXBsZSBzb2NrZXQub25FcnJvcihmdW5jdGlvbihlcnJvcil7IGFsZXJ0KFwiQW4gZXJyb3Igb2NjdXJyZWRcIikgfSlcbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uRXJyb3IoY2FsbGJhY2spIHtcbiAgICBsZXQgcmVmID0gdGhpcy5tYWtlUmVmKCk7XG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5lcnJvci5wdXNoKFtyZWYsIGNhbGxiYWNrXSk7XG4gICAgcmV0dXJuIHJlZjtcbiAgfVxuICAvKipcbiAgICogUmVnaXN0ZXJzIGNhbGxiYWNrcyBmb3IgY29ubmVjdGlvbiBtZXNzYWdlIGV2ZW50c1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgb25NZXNzYWdlKGNhbGxiYWNrKSB7XG4gICAgbGV0IHJlZiA9IHRoaXMubWFrZVJlZigpO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MubWVzc2FnZS5wdXNoKFtyZWYsIGNhbGxiYWNrXSk7XG4gICAgcmV0dXJuIHJlZjtcbiAgfVxuICAvKipcbiAgICogUGluZ3MgdGhlI
1HNlcnZlciBhbmQgaW52b2tlcyB0aGUgY2FsbGJhY2sgd2l0aCB0aGUgUlRUIGluIG1pbGxpc2Vjb25kc1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKlxuICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHBpbmcgd2FzIHB1c2hlZCBvciBmYWxzZSBpZiB1bmFibGUgdG8gYmUgcHVzaGVkLlxuICAgKi9cbiAgcGluZyhjYWxsYmFjaykge1xuICAgIGlmICghdGhpcy5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGxldCByZWYgPSB0aGlzLm1ha2VSZWYoKTtcbiAgICBsZXQgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICB0aGlzLnB1c2goeyB0b3BpYzogXCJwaG9lbml4XCIsIGV2ZW50OiBcImhlYXJ0YmVhdFwiLCBwYXlsb2FkOiB7fSwgcmVmIH0pO1xuICAgIGxldCBvbk1zZ1JlZiA9IHRoaXMub25NZXNzYWdlKChtc2cpID0+IHtcbiAgICAgIGlmIChtc2cucmVmID09PSByZWYpIHtcbiAgICAgICAgdGhpcy5vZmYoW29uTXNnUmVmXSk7XG4gICAgICAgIGNhbGxiYWNrKERhdGUubm93KCkgLSBzdGFydFRpbWUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufVxuICAgKi9cbiAgdHJhbnNwb3J0TmFtZSh0cmFuc3BvcnQpIHtcbiAgICBzd2l0Y2ggKHRyYW5zcG9ydCkge1xuICAgICAgY2FzZSBMb25nUG9sbDpcbiAgICAgICAgcmV0dXJuIFwiTG9uZ1BvbGxcIjtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB0cmFuc3BvcnQubmFtZTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0cmFuc3BvcnRDb25uZWN0KCkge1xuICAgIHRoaXMuY29ubmVjdENsb2NrKys7XG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gZmFsc2U7XG4gICAgbGV0IHByb3RvY29scyA9IHZvaWQgMDtcbiAgICBpZiAodGhpcy5hdXRoVG9rZW4pIHtcbiAgICAgIHByb3RvY29scyA9IFtcInBob2VuaXhcIiwgYCR7QVVUSF9UT0tFTl9QUkVGSVh9JHtidG9hKHRoaXMuYXV0aFRva2VuKCkpLnJlcGxhY2UoLz0vZywgXCJcIil9YF07XG4gICAgfVxuICAgIHRoaXMuY29ubiA9IG5ldyB0aGlzLnRyYW5zcG9ydCh0aGlzLmVuZFBvaW50VVJMKCksIHByb3RvY29scyk7XG4gICAgdGhpcy5jb25uLmJpbmFyeVR5cGUgPSB0aGlzLmJpbmFyeVR5cGU7XG4gICAgdGhpcy5jb25uLnRpbWVvdXQgPSB0aGlzLmxvbmdwb2xsZXJUaW1lb3V0O1xuICAgIHRoaXMuY29ubi5vbm9wZW4gPSAoKSA9PiB0aGlzLm9uQ29ubk9wZW4oKTtcbiAgICB0aGlzLmNvbm4ub25lcnJvciA9IChlcnJvcikgPT4gdGhpcy5vbkNvbm5FcnJvcihlcnJvcik7XG4gICAgdGhpcy5jb25uLm9ubWVzc2FnZSA9IChldmVudCkgPT4gdGhpcy5vbkNvbm5NZXNzYWdlKGV2ZW50KTtcbiAgICB0aGlzLmNvbm4ub25jbG9zZSA9IChldmVudCkgPT4gdGhpcy5vbkNvbm5DbG9zZShldmVudCk7XG4gIH1cbiAgZ2V0U2Vzc2lvbihrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uU3RvcmUgJiYgdGhpcy5zZXNzaW9uU3RvcmUuZ2V0SXRlbShrZXkpO1xuICB9XG4gIHN0b3JlU2Vzc2lvbihrZXksIHZhbCkge1xuICAgIHRoaXMuc2Vzc2lvblN0b3JlICYmIHRoaXMuc2Vzc2lvblN0b3JlLnNldEl0ZW0oa2V5LCB2YWwpO1xuICB9XG4gIGNvbm5lY3RXaXRoRmFsbGJhY2soZmFsbGJhY2tUcmFuc3BvcnQsIGZhbGxiYWNrVGhyZXNob2xkID0gMjUwMCkge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLmZhbGxiYWNrVGltZXIpO1xuICAgIGxldCBlc3RhYmxpc2hlZCA9IGZhbHNlO1xuICAgIGxldCBwcmltYXJ5VHJhbnNwb3J0ID0gdHJ1ZTtcbiAgICBsZXQgb3BlblJlZiwgZXJyb3JSZWY7XG4gICAgbGV0IGZhbGxiYWNrVHJhbnNwb3J0TmFtZSA9IHRoaXMudHJhbnNwb3J0TmFtZShmYWxsYmFja1RyYW5zcG9ydCk7XG4gICAgbGV0IGZhbGxiYWNrID0gKHJlYXNvbikgPT4ge1xuICAgICAgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgYGZhbGxpbmcgYmFjayB0byAke2ZhbGxiYWNrVHJhbnNwb3J0TmFtZX0uLi5gLCByZWFzb24pO1xuICAgICAgdGhpcy5vZmYoW29wZW5SZWYsIGVycm9yUmVmXSk7XG4gICAgICBwcmltYXJ5VHJhbnNwb3J0ID0gZmFsc2U7XG4gICAgICB0aGlzLnJlcGxhY2VUcmFuc3BvcnQoZmFsbGJhY2tUcmFuc3BvcnQpO1xuICAgICAgdGhpcy50cmFuc3BvcnRDb25uZWN0KCk7XG4gICAgfTtcbiAgICBpZiAodGhpcy5nZXRTZXNzaW9uKGBwaHg6ZmFsbGJhY2s6JHtmYWxsYmFja1RyYW5zcG9ydE5hbWV9YCkpIHtcbiAgICAgIHJldHVybiBmYWxsYmFjayhcIm1lbW9yaXplZFwiKTtcbiAgICB9XG4gICAgdGhpcy5mYWxsYmFja1RpbWVyID0gc2V0VGltZW91dChmYWxsYmFjaywgZmFsbGJhY2tUaHJlc2hvbGQpO1xuICAgIGVycm9yUmVmID0gdGhpcy5vbkVycm9yKChyZWFzb24pID0+IHtcbiAgICAgIHRoaXMubG9nKFwidHJhbnNwb3J0XCIsIFwiZXJyb3JcIiwgcmVhc29uKTtcbiAgICAgIGlmIChwcmltYXJ5VHJhbnNwb3J0ICYmICFlc3RhYmxpc2hlZCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5mYWxsYmFja1RpbWVyKTtcbiAgICAgICAgZmFsbGJhY2socmVhc29uKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAodGhpcy5mYWxsYmFja1JlZikge1xuICAgICAgdGhpcy5vZmYoW3RoaXMuZmFsbGJhY2tSZWZdKTtcbiAgICB9XG4gICAgdGhpcy5mYWxsYmFja1JlZiA9IHRoaXMub25PcGVuKCgpID0+IHtcbiAgICAgIGVzdGFibGlzaGVkID0gdHJ1ZTtcbiAgICAgIGlmICghcHJpbWFyeVRyYW5zcG9ydCkge1xuICAgICAgICBsZXQgZmFsbGJhY2tUcmFuc3BvcnROYW1lMiA9IHRoaXMudHJhbnNwb3J0TmFtZShmYWxsYmFja1RyYW5zcG9ydCk7XG4gICAgICAgIGlmICghdGhpcy5wcmltYXJ5UGFzc2VkSGVhbHRoQ2hlY2spIHtcbiAgICAgICAgICB0aGlzLnN0b3JlU2Vzc2lvbihgcGh4OmZhbGxiYWNrOiR7ZmFsbGJhY2tUcmFuc3BvcnROYW1lMn1gLCBcInRydWVcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMubG9nKFwidHJhbnNwb3J0XCIsIGBlc3RhYmxpc2hlZCAke2ZhbGxiYWNrVHJhbnNwb3J0TmFtZTJ9IGZhbGxiYWNrYCk7XG4gICAgICB9XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5mYWxsYmFja1RpbWVyKTtcbiAgICAgIHRoaXMuZmFsbGJhY2tUaW1lciA9IHNldFRpbWVvdXQoZmFsbGJhY2ssIGZhbGxiYWNrVGhyZXNob2xkKTtcbiAgICAgIHRoaXMucGluZygocnR0KSA9PiB7XG4gICAgICAgI
1HRoaXMubG9nKFwidHJhbnNwb3J0XCIsIFwiY29ubmVjdGVkIHRvIHByaW1hcnkgYWZ0ZXJcIiwgcnR0KTtcbiAgICAgICAgdGhpcy5wcmltYXJ5UGFzc2VkSGVhbHRoQ2hlY2sgPSB0cnVlO1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5mYWxsYmFja1RpbWVyKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHRoaXMudHJhbnNwb3J0Q29ubmVjdCgpO1xuICB9XG4gIGNsZWFySGVhcnRiZWF0cygpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5oZWFydGJlYXRUaW1lcik7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuaGVhcnRiZWF0VGltZW91dFRpbWVyKTtcbiAgfVxuICBvbkNvbm5PcGVuKCkge1xuICAgIGlmICh0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBgJHt0aGlzLnRyYW5zcG9ydE5hbWUodGhpcy50cmFuc3BvcnQpfSBjb25uZWN0ZWQgdG8gJHt0aGlzLmVuZFBvaW50VVJMKCl9YCk7XG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gZmFsc2U7XG4gICAgdGhpcy5kaXNjb25uZWN0aW5nID0gZmFsc2U7XG4gICAgdGhpcy5lc3RhYmxpc2hlZENvbm5lY3Rpb25zKys7XG4gICAgdGhpcy5mbHVzaFNlbmRCdWZmZXIoKTtcbiAgICB0aGlzLnJlY29ubmVjdFRpbWVyLnJlc2V0KCk7XG4gICAgdGhpcy5yZXNldEhlYXJ0YmVhdCgpO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3Mub3Blbi5mb3JFYWNoKChbLCBjYWxsYmFja10pID0+IGNhbGxiYWNrKCkpO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaGVhcnRiZWF0VGltZW91dCgpIHtcbiAgICBpZiAodGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmKSB7XG4gICAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSBudWxsO1xuICAgICAgaWYgKHRoaXMuaGFzTG9nZ2VyKCkpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgXCJoZWFydGJlYXQgdGltZW91dC4gQXR0ZW1wdGluZyB0byByZS1lc3RhYmxpc2ggY29ubmVjdGlvblwiKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudHJpZ2dlckNoYW5FcnJvcigpO1xuICAgICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gZmFsc2U7XG4gICAgICB0aGlzLnRlYXJkb3duKCgpID0+IHRoaXMucmVjb25uZWN0VGltZXIuc2NoZWR1bGVUaW1lb3V0KCksIFdTX0NMT1NFX05PUk1BTCwgXCJoZWFydGJlYXQgdGltZW91dFwiKTtcbiAgICB9XG4gIH1cbiAgcmVzZXRIZWFydGJlYXQoKSB7XG4gICAgaWYgKHRoaXMuY29ubiAmJiB0aGlzLmNvbm4uc2tpcEhlYXJ0YmVhdCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSBudWxsO1xuICAgIHRoaXMuY2xlYXJIZWFydGJlYXRzKCk7XG4gICAgdGhpcy5oZWFydGJlYXRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZW5kSGVhcnRiZWF0KCksIHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWxNcyk7XG4gIH1cbiAgdGVhcmRvd24oY2FsbGJhY2ssIGNvZGUsIHJlYXNvbikge1xuICAgIGlmICghdGhpcy5jb25uKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2sgJiYgY2FsbGJhY2soKTtcbiAgICB9XG4gICAgY29uc3QgY29ublRvQ2xvc2UgPSB0aGlzLmNvbm47XG4gICAgdGhpcy53YWl0Rm9yQnVmZmVyRG9uZShjb25uVG9DbG9zZSwgKCkgPT4ge1xuICAgICAgaWYgKGNvZGUpIHtcbiAgICAgICAgY29ublRvQ2xvc2UuY2xvc2UoY29kZSwgcmVhc29uIHx8IFwiXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29ublRvQ2xvc2UuY2xvc2UoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMud2FpdEZvclNvY2tldENsb3NlZChjb25uVG9DbG9zZSwgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5jb25uID09PSBjb25uVG9DbG9zZSkge1xuICAgICAgICAgIHRoaXMuY29ubi5vbm9wZW4gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICB9O1xuICAgICAgICAgIHRoaXMuY29ubi5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgfTtcbiAgICAgICAgICB0aGlzLmNvbm4ub25tZXNzYWdlID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgfTtcbiAgICAgICAgICB0aGlzLmNvbm4ub25jbG9zZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIH07XG4gICAgICAgICAgdGhpcy5jb25uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgd2FpdEZvckJ1ZmZlckRvbmUoY29ubiwgY2FsbGJhY2ssIHRyaWVzID0gMSkge1xuICAgIGlmICh0cmllcyA9PT0gNSB8fCAhY29ubi5idWZmZXJlZEFtb3VudCkge1xuICAgICAgY2FsbGJhY2soKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLndhaXRGb3JCdWZmZXJEb25lKGNvbm4sIGNhbGxiYWNrLCB0cmllcyArIDEpO1xuICAgIH0sIDE1MCAqIHRyaWVzKTtcbiAgfVxuICB3YWl0Rm9yU29ja2V0Q2xvc2VkKGNvbm4sIGNhbGxiYWNrLCB0cmllcyA9IDEpIHtcbiAgICBpZiAodHJpZXMgPT09IDUgfHwgY29ubi5yZWFkeVN0YXRlID09PSBTT0NLRVRfU1R
1BVEVTLmNsb3NlZCkge1xuICAgICAgY2FsbGJhY2soKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLndhaXRGb3JTb2NrZXRDbG9zZWQoY29ubiwgY2FsbGJhY2ssIHRyaWVzICsgMSk7XG4gICAgfSwgMTUwICogdHJpZXMpO1xuICB9XG4gIG9uQ29ubkNsb3NlKGV2ZW50KSB7XG4gICAgaWYgKHRoaXMuY29ubikgdGhpcy5jb25uLm9uY2xvc2UgPSAoKSA9PiB7XG4gICAgfTtcbiAgICBsZXQgY2xvc2VDb2RlID0gZXZlbnQgJiYgZXZlbnQuY29kZTtcbiAgICBpZiAodGhpcy5oYXNMb2dnZXIoKSkgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgXCJjbG9zZVwiLCBldmVudCk7XG4gICAgdGhpcy50cmlnZ2VyQ2hhbkVycm9yKCk7XG4gICAgdGhpcy5jbGVhckhlYXJ0YmVhdHMoKTtcbiAgICBpZiAoIXRoaXMuY2xvc2VXYXNDbGVhbiAmJiBjbG9zZUNvZGUgIT09IDFlMykge1xuICAgICAgdGhpcy5yZWNvbm5lY3RUaW1lci5zY2hlZHVsZVRpbWVvdXQoKTtcbiAgICB9XG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5jbG9zZS5mb3JFYWNoKChbLCBjYWxsYmFja10pID0+IGNhbGxiYWNrKGV2ZW50KSk7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBvbkNvbm5FcnJvcihlcnJvcikge1xuICAgIGlmICh0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBcImVycm9yXCIsIGVycm9yKTtcbiAgICBsZXQgdHJhbnNwb3J0QmVmb3JlID0gdGhpcy50cmFuc3BvcnQ7XG4gICAgbGV0IGVzdGFibGlzaGVkQmVmb3JlID0gdGhpcy5lc3RhYmxpc2hlZENvbm5lY3Rpb25zO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MuZXJyb3IuZm9yRWFjaCgoWywgY2FsbGJhY2tdKSA9PiB7XG4gICAgICBjYWxsYmFjayhlcnJvciwgdHJhbnNwb3J0QmVmb3JlLCBlc3RhYmxpc2hlZEJlZm9yZSk7XG4gICAgfSk7XG4gICAgaWYgKHRyYW5zcG9ydEJlZm9yZSA9PT0gdGhpcy50cmFuc3BvcnQgfHwgZXN0YWJsaXNoZWRCZWZvcmUgPiAwKSB7XG4gICAgICB0aGlzLnRyaWdnZXJDaGFuRXJyb3IoKTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0cmlnZ2VyQ2hhbkVycm9yKCkge1xuICAgIHRoaXMuY2hhbm5lbHMuZm9yRWFjaCgoY2hhbm5lbCkgPT4ge1xuICAgICAgaWYgKCEoY2hhbm5lbC5pc0Vycm9yZWQoKSB8fCBjaGFubmVsLmlzTGVhdmluZygpIHx8IGNoYW5uZWwuaXNDbG9zZWQoKSkpIHtcbiAgICAgICAgY2hhbm5lbC50cmlnZ2VyKENIQU5ORUxfRVZFTlRTLmVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogQHJldHVybnMge3N0cmluZ31cbiAgICovXG4gIGNvbm5lY3Rpb25TdGF0ZSgpIHtcbiAgICBzd2l0Y2ggKHRoaXMuY29ubiAmJiB0aGlzLmNvbm4ucmVhZHlTdGF0ZSkge1xuICAgICAgY2FzZSBTT0NLRVRfU1R
1BVEVTLmNvbm5lY3Rpbmc6XG4gICAgICAgIHJldHVybiBcImNvbm5lY3RpbmdcIjtcbiAgICAgIGNhc2UgU09DS0VUX1NUQVRFUy5vcGVuOlxuICAgICAgICByZXR1cm4gXCJvcGVuXCI7XG4gICAgICBjYXNlIFNPQ0tFVF9TVEFURVMuY2xvc2luZzpcbiAgICAgICAgcmV0dXJuIFwiY2xvc2luZ1wiO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIFwiY2xvc2VkXCI7XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIGlzQ29ubmVjdGVkKCkge1xuICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb25TdGF0ZSgpID09PSBcIm9wZW5cIjtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICpcbiAgICogQHBhcmFtIHtDaGFubmVsfVxuICAgKi9cbiAgcmVtb3ZlKGNoYW5uZWwpIHtcbiAgICB0aGlzLm9mZihjaGFubmVsLnN0YXRlQ2hhbmdlUmVmcyk7XG4gICAgdGhpcy5jaGFubmVscyA9IHRoaXMuY2hhbm5lbHMuZmlsdGVyKChjKSA9PiBjICE9PSBjaGFubmVsKTtcbiAgfVxuICAvKipcbiAgICogUmVtb3ZlcyBgb25PcGVuYCwgYG9uQ2xvc2VgLCBgb25FcnJvcixgIGFuZCBgb25NZXNzYWdlYCByZWdpc3RyYXRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0ge3JlZnN9IC0gbGlzdCBvZiByZWZzIHJldHVybmVkIGJ5IGNhbGxzIHRvXG4gICAqICAgICAgICAgICAgICAgICBgb25PcGVuYCwgYG9uQ2xvc2VgLCBgb25FcnJvcixgIGFuZCBgb25NZXNzYWdlYFxuICAgKi9cbiAgb2ZmKHJlZnMpIHtcbiAgICBmb3IgKGxldCBrZXkgaW4gdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcykge1xuICAgICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrc1trZXldID0gdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrc1trZXldLmZpbHRlcigoW3JlZl0pID0+IHtcbiAgICAgICAgcmV0dXJuIHJlZnMuaW5kZXhPZihyZWYpID09PSAtMTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogSW5pdGlhdGVzIGEgbmV3IGNoYW5uZWwgZm9yIHRoZSBnaXZlbiB0b3BpY1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9waWNcbiAgICogQHBhcmFtIHtPYmplY3R9IGNoYW5QYXJhbXMgLSBQYXJhbWV0ZXJzIGZvciB0aGUgY2hhbm5lbFxuICAgKiBAcmV0dXJucyB7Q2hhbm5lbH1cbiAgICovXG4gIGNoYW5uZWwodG9waWMsIGNoYW5QYXJhbXMgPSB7fSkge1xuICAgIGxldCBjaGFuID0gbmV3IENoYW5uZWwodG9waWMsIGNoYW5QYXJhbXMsIHRoaXMpO1xuICAgIHRoaXMuY2hhbm5lbHMucHVzaChjaGFuKTtcbiAgICByZXR1cm4gY2hhbjtcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFcbiAgICovXG4gIHB1c2goZGF0YSkge1xuICAgIGlmICh0aGlzLmhhc0xvZ2dlcigpKSB7XG4gICAgICBsZXQgeyB0b3BpYywgZXZlbnQsIHBheWxvYWQsIHJlZiwgam9pbl9yZWYgfSA9IGRhdGE7XG4gICAgICB0aGlzLmxvZyhcInB1c2hcIiwgYCR7dG9waWN9ICR7ZXZlbnR9ICgke2pvaW5fcmVmfSwgJHtyZWZ9KWAsIHBheWxvYWQpO1xuICAgIH1cbiAgICBpZiAodGhpcy5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICB0aGlzLmVuY29kZShkYXRhLCAocmVzdWx0KSA9PiB0aGlzLmNvbm4uc2VuZChyZXN1bHQpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZW5kQnVmZmVyLnB1c2goKCkgPT4gdGhpcy5lbmNvZGUoZGF0YSwgKHJlc3VsdCkgPT4gdGhpcy5jb25uLnNlbmQocmVzdWx0KSkpO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogUmV0dXJuIHRoZSBuZXh0IG1lc3NhZ2UgcmVmLCBhY2NvdW50aW5nIGZvciBvdmVyZmxvd3NcbiAgICogQHJldHVybnMge3N0cmluZ31cbiAgICovXG4gIG1ha2VSZWYoKSB7XG4gICAgbGV0IG5ld1JlZiA9IHRoaXMucmVmICsgMTtcbiAgICBpZiAobmV3UmVmID09PSB0aGlzLnJlZikge1xuICAgICAgdGhpcy5yZWYgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlZiA9IG5ld1JlZjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucmVmLnRvU3RyaW5nKCk7XG4gIH1cbiAgc2VuZEhlYXJ0YmVhdCgpIHtcbiAgICBpZiAodGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmICYmICF0aGlzLmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmID0gdGhpcy5tYWtlUmVmKCk7XG4gICAgdGhpcy5wdXNoKHsgdG9waWM6IFwicGhvZW5peFwiLCBldmVudDogXCJoZWFydGJlYXRcIiwgcGF5bG9hZDoge30sIHJlZjogdGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmIH0pO1xuICAgIHRoaXMuaGVhcnRiZWF0VGltZW91dFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLmhlYXJ0YmVhdFRpbWVvdXQoKSwgdGhpcy5oZWFydGJlYXRJbnRlcnZhbE1zKTtcbiAgfVxuICBmbHVzaFNlbmRCdWZmZXIoKSB7XG4gICAgaWYgKHRoaXMuaXNDb25uZWN0ZWQoKSAmJiB0aGlzLnNlbmRCdWZmZXIubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5zZW5kQnVmZmVyLmZvckVhY2goKGNhbGxiYWNrKSA9PiBjYWxsYmFjaygpKTtcbiAgICAgIHRoaXMuc2VuZEJ1ZmZlciA9IFtdO1xuICAgIH1cbiAgfVxuICBvbkNvbm5NZXNzYWdlKHJhd01lc3NhZ2UpIHtcbiAgICB0aGlzLmRlY29kZShyYXdNZXNzYWdlLmRhdGEsIChtc2cpID0+IHtcbiAgICAgIGxldCB7IHRvcGljLCBldmVudCwgcGF5bG9hZCwgcmVmLCBqb2luX3JlZiB9ID0gbXNnO1xuICAgICAgaWYgKHJlZiAmJiByZWYgPT09IHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZikge1xuICAgICAgICB0aGlzLmNsZWFySGVhcnRiZWF0cygpO1xuICAgICAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSBudWxsO1xuICAgICAgICB0aGlzLmhlYXJ0YmVhdFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLnNlbmRIZWFydGJlYXQoKSwgdGhpcy5oZWFydGJlYXRJbnRlcnZhbE1zKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInJlY2VpdmVcIiwgYCR7cGF5bG9hZC5zdGF0dXMgfHwgXCJcIn0gJHt0b3BpY30gJHtldmVudH0gJHtyZWYgJiYgXCIoXCIgKyByZWYgKyBcIilcIiB8fCBcIlwifWAsIHBheWxvYWQpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNoYW5uZWxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGNoYW5uZWwgPSB0aGlzLmNoYW5uZWxzW2ldO1xuICAgICAgICBpZiAoIWNoYW5uZWwuaXNNZW1iZXIodG9waWMsIGV2ZW50LCBwYXlsb2FkLCBqb2luX3JlZikpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjaGFubmVsLnRyaWdnZXIoZXZlbnQsIHBheWxvYWQsIHJlZiwgam9pbl9yZWYpO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLm1lc3NhZ2UubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IFssIGNhbGxiYWNrXSA9IHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MubWVzc2FnZVtpXTtcbiAgICAgICAgY2FsbGJhY2sobXNnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICBsZWF2ZU9wZW5Ub3BpYyh0b3BpYykge1xuICAgIGxldCBkdXBDaGFubmVsID0gdGhpcy5jaGFubmVscy5maW5kKChjKSA9PiBjLnRvcGljID09PSB0b3BpYyAmJiAoYy5pc0pvaW5lZCgpIHx8IGMuaXNKb2luaW5nKCkpKTtcbiAgICBpZiAoZHVwQ2hhbm5lbCkge1xuICAgICAgaWYgKHRoaXMuaGFzTG9nZ2VyKCkpIHRoaXMubG9nKFwidHJhbnNwb3J0XCIsIGBsZWF2aW5nIGR1cGxpY2F0ZSB0b3BpYyBcIiR7dG9waWN9XCJgKTtcbiAgICAgIGR1cENoYW5uZWwubGVhdmUoKTtcbiAgICB9XG4gI
1H1cbn07XG5leHBvcnQge1xuICBDaGFubmVsLFxuICBMb25nUG9sbCxcbiAgUHJlc2VuY2UsXG4gIHNlcmlhbGl6ZXJfZGVmYXVsdCBhcyBTZXJpYWxpemVyLFxuICBTb2NrZXRcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1waG9lbml4Lm1qcy5tYXBcbiIsIi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L2NvbnN0YW50cy50c1xudmFyIENPTlNFQ1VUSVZFX1JFTE9BRFMgPSBcImNvbnNlY3V0aXZlLXJlbG9hZHNcIjtcbnZhciBNQVhfUkVMT0FEUyA9IDEwO1xudmFyIFJFTE9BRF9KSVRURVJfTUlOID0gNWUzO1xudmFyIFJFTE9BRF9KSVRURVJfTUFYID0gMWU0O1xudmFyIEZBSUxTQUZFX0pJVFRFUiA9IDNlNDtcbnZhciBQSFhfRVZFTlRfQ0xBU1NFUyA9IFtcbiAgXCJwaHgtY2xpY2stbG9hZGluZ1wiLFxuICBcInBoeC1jaGFuZ2UtbG9hZGluZ1wiLFxuICBcInBoeC1zdWJtaXQtbG9hZGluZ1wiLFxuICBcInBoeC1rZXlkb3duLWxvYWRpbmdcIixcbiAgXCJwaHgta2V5dXAtbG9hZGluZ1wiLFxuICBcInBoeC1ibHVyLWxvYWRpbmdcIixcbiAgXCJwaHgtZm9jdXMtbG9hZGluZ1wiLFxuICBcInBoeC1ob29rLWxvYWRpbmdcIlxuXTtcbnZhciBQSFhfRFJPUF9UQVJHRVRfQUNUSVZFX0NMQVNTID0gXCJwaHgtZHJvcC10YXJnZXQtYWN0aXZlXCI7XG52YXIgUEhYX0NPTVBPTkVOVCA9IFwiZGF0YS1waHgtY29tcG9uZW50XCI7XG52YXIgUEhYX1ZJRVdfUkVGID0gXCJkYXRhLXBoeC12aWV3XCI7XG52YXIgUEhYX0xJVkVfTElOSyA9IFwiZGF0YS1waHgtbGlua1wiO1xudmFyIFBIWF9UUkFDS19TVEFUSUMgPSBcInRyYWNrLXN0YXRpY1wiO1xudmFyIFBIWF9MSU5LX1NUQVRFID0gXCJkYXRhLXBoeC1saW5rLXN0YXRlXCI7XG52YXIgUEhYX1JFRl9MT0FESU5HID0gXCJkYXRhLXBoeC1yZWYtbG9hZGluZ1wiO1xudmFyIFBIWF9SRUZfU1JDID0gXCJkYXRhLXBoeC1yZWYtc3JjXCI7XG52YXIgUEhYX1JFRl9MT0NLID0gXCJkYXRhLXBoeC1yZWYtbG9ja1wiO1xudmFyIFBIWF9QRU5ESU5HX1JFRlMgPSBcInBoeC1wZW5kaW5nLXJlZnNcIjtcbnZhciBQSFhfVFJBQ0tfVVBMT0FEUyA9IFwidHJhY2stdXBsb2Fkc1wiO1xudmFyIFBIWF9VUExPQURfUkVGID0gXCJkYXRhLXBoeC11cGxvYWQtcmVmXCI7XG52YXIgUEhYX1BSRUZMSUdIVEVEX1JFRlMgPSBcImRhdGEtcGh4LXByZWZsaWdodGVkLXJlZnNcIjtcbnZhciBQSFhfRE9ORV9SRUZTID0gXCJkYXRhLXBoeC1kb25lLXJlZnNcIjtcbnZhciBQSFhfRFJPUF9UQVJHRVQgPSBcImRyb3AtdGFyZ2V0XCI7XG52YXIgUEhYX0FDVElWRV9FTlRSWV9SRUZTID0gXCJkYXRhLXBoeC1hY3RpdmUtcmVmc1wiO1xudmFyIFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCA9IFwicGh4OmxpdmUtZmlsZTp1cGRhdGVkXCI7XG52YXIgUEhYX1NLSVAgPSBcImRhdGEtcGh4LXNraXBcIjtcbnZhciBQSFhfTUFHSUNfSUQgPSBcImRhdGEtcGh4LWlkXCI7XG52YXIgUEhYX1BSVU5FID0gXCJkYXRhLXBoeC1wcnVuZVwiO1xudmFyIFBIWF9DT05ORUNURURfQ0xBU1MgPSBcInBoeC1jb25uZWN0ZWRcIjtcbnZhciBQSFhfTE9BRElOR19DTEFTUyA9IFwicGh4LWxvYWRpbmdcIjtcbnZhciBQSFhfRVJST1JfQ0xBU1MgPSBcInBoeC1lcnJvclwiO1xudmFyIFBIWF9DTElFTlRfRVJST1JfQ0xBU1MgPSBcInBoeC1jbGllbnQtZXJyb3JcIjtcbnZhciBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTID0gXCJwaHgtc2VydmVyLWVycm9yXCI7XG52YXIgUEhYX1BBUkVOVF9JRCA9IFwiZGF0YS1waHgtcGFyZW50LWlkXCI7XG52YXIgUEhYX01BSU4gPSBcImRhdGEtcGh4LW1haW5cIjtcbnZhciBQSFhfUk9PVF9JRCA9IFwiZGF0YS1waHgtcm9vdC1pZFwiO1xudmFyIFBIWF9WSUVXUE9SVF9UT1AgPSBcInZpZXdwb3J0LXRvcFwiO1xudmFyIFBIWF9WSUVXUE9SVF9CT1RUT00gPSBcInZpZXdwb3J0LWJvdHRvbVwiO1xudmFyIFBIWF9WSUVXUE9SVF9PVkVSUlVOX1RBUkdFVCA9IFwidmlld3BvcnQtb3ZlcnJ1bi10YXJnZXRcIjtcbnZhciBQSFhfVFJJR0dFUl9BQ1RJT04gPSBcInRyaWdnZXItYWN0aW9uXCI7XG52YXIgUEhYX0hBU19GT0NVU0VEID0gXCJwaHgtaGFzLWZvY3VzZWRcIjtcbnZhciBGT0NVU0FCTEVfSU5QVVRTID0gW1xuICBcInRleHRcIixcbiAgXCJ0ZXh0YXJlYVwiLFxuICBcIm51bWJlclwiLFxuICBcImVtYWlsXCIsXG4gIFwicGFzc3dvcmRcIixcbiAgXCJzZWFyY2hcIixcbiAgXCJ0ZWxcIixcbiAgXCJ1cmxcIixcbiAgXCJkYXRlXCIsXG4gIFwidGltZVwiLFxuICBcImRhdGV0aW1lLWxvY2FsXCIsXG4gIFwiY29sb3JcIixcbiAgXCJyYW5nZVwiXG5dO1xudmFyIENIRUNLQUJMRV9JTlBVVFMgPSBbXCJjaGVja2JveFwiLCBcInJhZGlvXCJdO1xudmFyIFBIWF9IQVNfU1VCTUlUVEVEID0gXCJwaHgtaGFzLXN1Ym1pdHRlZFwiO1xudmFyIFBIWF9TRVNTSU9OID0gXCJkYXRhLXBoeC1zZXNzaW9uXCI7XG52YXIgUEhYX1ZJRVdfU0VMRUNUT1IgPSBgWyR7UEhYX1NFU1NJT059XWA7XG52YXIgUEhYX1NUSUNLWSA9IFwiZGF0YS1waHgtc3RpY2t5XCI7XG52YXIgUEhYX1NUQVRJQyA9IFwiZGF0YS1waHgtc3RhdGljXCI7XG52YXIgUEhYX1JFQURPTkxZID0gXCJkYXRhLXBoeC1yZWFkb25seVwiO1xudmFyIFBIWF9ESVNBQkxFRCA9IFwiZGF0YS1waHgtZGlzYWJsZWRcIjtcbnZhciBQSFhfRElTQUJMRV9XSVRIID0gXCJkaXNhYmxlLXdpdGhcIjtcbnZhciBQSFhfRElTQUJMRV9XSVRIX1JFU1RPUkUgPSBcImRhdGEtcGh4LWRpc2FibGUtd2l0aC1yZXN0b3JlXCI7XG52YXIgUEhYX0hPT0sgPSBcImhvb2tcIjtcbnZhciBQSFhfREVCT1VOQ0UgPSBcImRlYm91bmNlXCI7XG52YXIgUEhYX1RIUk9UVExFID0gXCJ0aHJvdHRsZVwiO1xudmFyIFBIWF9VUERBVEUgPSBcInVwZGF0ZVwiO1xudmFyIFBIWF9TVFJFQU0gPSBcInN0cmVhbVwiO1xudmFyIFBIWF9TVFJFQU1fUkVGID0gXCJkYXRhLXBoeC1zdHJlYW1cIjtcbnZhciBQSFhfUE9SVEFMID0gXCJkYXRhLXBoeC1wb3J0YWxcIjtcbnZhciBQSFhfVEVMRVBPUlRFRF9SRUYgPSBcImRhdGEtcGh4LXRlbGVwb3J0ZWRcIjtcbnZhciBQSFhfVEVMRVBPUlRFRF9TUkMgPSBcImRhdGEtcGh4LXRlbGVwb3J0ZWQtc3JjXCI7XG52YXIgUEhYX1JVTlRJTUVfSE9PSyA9IFwiZGF0YS1waHgtcnVudGltZS1ob29rXCI7XG52YXIgUEhYX0xWX1BJRCA9IFwiZGF0YS1waHgtcGlkXCI7XG52YXIgUEhYX0tFWSA9IFwia2V5XCI7XG52YXIgUEhYX1BSSVZBVEUgPSBcInBoeFByaXZhdGVcIjtcbnZhciBQSFhfQVVUT19SRUNPVkVSID0gXCJhdXRvLXJlY292ZXJcIjtcbnZhciBQSFhfTk9fVU5VU0VEX0ZJRUxEID0gXCJuby11bnVzZWQtZmllbGRcIjtcbnZhciBQSFhfTFZfREVCVUcgPSBcInBoeDpsaXZlLXNvY2tldDpkZWJ1Z1wiO1xudmFyIFBIWF9MVl9QUk9GSUxFID0gXCJwaHg6bGl2ZS1zb2NrZXQ6cHJvZmlsaW5nXCI7XG52YXIgUEhYX0xWX0xBVEVOQ1lfU0lNID0gXCJwaHg6bGl2ZS1zb2NrZXQ6bGF0ZW5jeS1zaW1cIjtcbnZhciBQSFhfTFZfSElTVE9SWV9QT1NJVElPTiA9IFwicGh4Om5hdi1oaXN0b3J5LXBvc2l0aW9uXCI7XG52YXIgUEhYX1BST0dSRVNTID0gXCJwcm9ncmVzc1wiO1xudmFyIFBIWF9NT1VOVEVEID0gXCJtb3VudGVkXCI7XG52YXIgUEhYX1JFTE9BRF9TVEFUVVMgPSBcIl9fcGhvZW5peF9yZWxvYWRfc3RhdHVzX19cIjtcbnZhciBMT0FERVJfVElNRU9VVCA9IDE7XG52YXIgTUFYX0NISUxEX0pPSU5fQVRURU1QVFMgPSAzO1xudmFyIEJFRk9S
1RV9VTkxPQURfTE9BREVSX1RJTUVPVVQgPSAyMDA7XG52YXIgRElTQ09OTkVDVEVEX1RJTUVPVVQgPSA1MDA7XG52YXIgQklORElOR19QUkVGSVggPSBcInBoeC1cIjtcbnZhciBQVVNIX1RJTUVPVVQgPSAzZTQ7XG52YXIgREVCT1VOQ0VfVFJJR0dFUiA9IFwiZGVib3VuY2UtdHJpZ2dlclwiO1xudmFyIFRIUk9UVExFRCA9IFwidGhyb3R0bGVkXCI7XG52YXIgREVCT1VOQ0VfUFJFVl9LRVkgPSBcImRlYm91bmNlLXByZXYta2V5XCI7XG52YXIgREVGQVVMVFMgPSB7XG4gIGRlYm91bmNlOiAzMDAsXG4gIHRocm90dGxlOiAzMDBcbn07XG52YXIgUEhYX1BFTkRJTkdfQVRUUlMgPSBbUEhYX1JFRl9MT0FESU5HLCBQSFhfUkVGX1NSQywgUEhYX1JFRl9MT0NLXTtcbnZhciBTVEFUSUMgPSBcInNcIjtcbnZhciBST09UID0gXCJyXCI7XG52YXIgQ09NUE9ORU5UUyA9IFwiY1wiO1xudmFyIEtFWUVEID0gXCJrXCI7XG52YXIgS0VZRURfQ09VTlQgPSBcImtjXCI7XG52YXIgRVZFTlRTID0gXCJlXCI7XG52YXIgUkVQTFkgPSBcInJcIjtcbnZhciBUSVRMRSA9IFwidFwiO1xudmFyIFRFTVBMQVRFUyA9IFwicFwiO1xudmFyIFNUUkVBTSA9IFwic3RyZWFtXCI7XG5cbi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L2VudHJ5X3VwbG9hZGVyLmpzXG52YXIgRW50cnlVcGxvYWRlciA9IGNsYXNzIHtcbiAgY29uc3RydWN0b3IoZW50cnksIGNvbmZpZywgbGl2ZVNvY2tldCkge1xuICAgIGNvbnN0IHsgY2h1bmtfc2l6ZSwgY2h1bmtfdGltZW91dCB9ID0gY29uZmlnO1xuICAgIHRoaXMubGl2ZVNvY2tldCA9IGxpdmVTb2NrZXQ7XG4gICAgdGhpcy5lbnRyeSA9IGVudHJ5O1xuICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgICB0aGlzLmNodW5rU2l6ZSA9IGNodW5rX3NpemU7XG4gICAgdGhpcy5jaHVua1RpbWVvdXQgPSBjaHVua190aW1lb3V0O1xuICAgIHRoaXMuY2h1bmtUaW1lciA9IG51bGw7XG4gICAgdGhpcy5lcnJvcmVkID0gZmFsc2U7XG4gICAgdGhpcy51cGxvYWRDaGFubmVsID0gbGl2ZVNvY2tldC5jaGFubmVsKGBsdnU6JHtlbnRyeS5yZWZ9YCwge1xuICAgICAgdG9rZW46IGVudHJ5Lm1ldGFkYXRhKClcbiAgICB9KTtcbiAgfVxuICBlcnJvcihyZWFzb24pIHtcbiAgICBpZiAodGhpcy5lcnJvcmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudXBsb2FkQ2hhbm5lbC5sZWF2ZSgpO1xuICAgIHRoaXMuZXJyb3JlZCA9IHRydWU7XG4gICAgdGhpcy5jaHVua1RpbWVyICE9IG51bGwgJiYgY2xlYXJUaW1lb3V0KHRoaXMuY2h1bmtUaW1lcik7XG4gICAgdGhpcy5lbnRyeS5lcnJvcihyZWFzb24pO1xuICB9XG4gIHVwbG9hZCgpIHtcbiAgICB0aGlzLnVwbG9hZENoYW5uZWwub25FcnJvcigocmVhc29uKSA9PiB0aGlzLmVycm9yKHJlYXNvbikpO1xuICAgIHRoaXMudXBsb2FkQ2hhbm5lbC5qb2luKCkucmVjZWl2ZShcIm9rXCIsIChfZGF0YSkgPT4gdGhpcy5yZWFkTmV4dENodW5rKCkpLnJlY2VpdmUoXCJlcnJvclwiLCAoeyByZWFzb24gfSkgPT4gdGhpcy5lcnJvcihyZWFzb24pKTtcbiAgfVxuICBpc0RvbmUoKSB7XG4gICAgcmV0dXJuIHRoaXMub2Zmc2V0ID49IHRoaXMuZW50cnkuZmlsZS5zaXplO1xuICB9XG4gIHJlYWROZXh0Q2h1bmsoKSB7XG4gICAgY29uc3QgcmVhZGVyID0gbmV3IHdpbmRvdy5GaWxlUmVhZGVyKCk7XG4gICAgY29uc3QgYmxvYiA9IHRoaXMuZW50cnkuZmlsZS5zbGljZShcbiAgICAgIHRoaXMub2Zmc2V0LFxuICAgICAgdGhpcy5jaHVua1NpemUgKyB0aGlzLm9mZnNldFxuICAgICk7XG4gICAgcmVhZGVyLm9ubG9hZCA9IChlKSA9PiB7XG4gICAgICBpZiAoZS50YXJnZXQ/LmVycm9yID09PSBudWxsKSB7XG4gICAgICAgIHRoaXMub2Zmc2V0ICs9IC8qKiBAdHlwZSB7QXJyYXlCdWZmZXJ9ICovXG4gICAgICAgIGUudGFyZ2V0LnJlc3VsdC5ieXRlTGVuZ3RoO1xuICAgICAgICB0aGlzLnB1c2hDaHVuayhcbiAgICAgICAgICAvKiogQHR5cGUge0FycmF5QnVmZmVyfSAqL1xuICAgICAgICAgIGUudGFyZ2V0LnJlc3VsdFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGxvZ0Vycm9yKFwiUmVhZCBlcnJvcjogXCIgKyBlLnRhcmdldD8uZXJyb3IpO1xuICAgICAgfVxuICAgIH07XG4gICAgcmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGJsb2IpO1xuICB9XG4gIHB1c2hDaHVuayhjaHVuaykge1xuICAgIGlmICghdGhpcy51cGxvYWRDaGFubmVsLmlzSm9pbmVkKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy51cGxvYWRDaGFubmVsLnB1c2goXCJjaHVua1wiLCBjaHVuaywgdGhpcy5jaHVua1RpbWVvdXQpLnJlY2VpdmUoXCJva1wiLCAoKSA9PiB7XG4gICAgICB0aGlzLmVudHJ5LnByb2dyZXNzKHRoaXMub2Zmc2V0IC8gdGhpcy5lbnRyeS5maWxlLnNpemUgKiAxMDApO1xuICAgICAgaWYgKCF0aGlzLmlzRG9uZSgpKSB7XG4gICAgICAgIHRoaXMuY2h1bmtUaW1lciA9IHNldFRpbWVvdXQoXG4gICAgICAgICAgKCkgPT4gdGhpcy5yZWFkTmV4dENodW5rKCksXG4gICAgICAgICAgdGhpcy5saXZlU29ja2V0LmdldExhdGVuY3lTaW0oKSB8fCAwXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSkucmVjZWl2ZShcImVycm9yXCIsICh7IHJlYXNvbiB9KSA9PiB0aGlzLmVycm9yKHJlYXNvbikpO1xuICB9XG59O1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy91dGlscy50c1xudmFyIGxvZ0Vycm9yID0gKG1zZywgb2JqKSA9PiBjb25zb2xlLmVycm9yICYmIGNvbnNvbGUuZXJyb3IobXNnLCBvYmopO1xudmFyIGVuc3VyZVNhbWVPcmlnaW4gPSAoaHJlZiwga2luZCkgPT4ge1xuICBsZXQgdXJsO1xuICB0cnkge1xuICAgIHVybCA9IG5ldyBVUkwoaHJlZiwgd2luZG93LmxvY2F0aW9uLmhyZWYpO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgZXhwZWN0ZWQgJHtraW5kfSBkZXN0aW5hdGlvbiB0byBiZSBhIHZhbGlkIFVSTCwgZ290OiAke2hyZWZ9YFxuICAgICk7XG4gIH1cbiAgaWYgKHVybC5vcmlnaW4gIT09IHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgY2Fubm90ICR7a2luZH0gdG8gXCIke2hyZWZ9XCIgYmVjYXVzZSBpdHMgb3JpZ2luIGRvZXMgbm90IG1hdGNoIHRoZSBjdXJyZW50IG9yaWdpbiBcIiR7d2luZG93LmxvY2F0aW9uLm9yaWdpbn1cIi4gVXNlIHdpbmRvdy5sb2NhdGlvbiBkaXJlY3RseSBmb3IgY3Jvc3Mtb3JpZ2luIG5hdmlnYXRpb24uYFxuICAgICk7XG4gIH1cbn07XG52YXIgaXNDaWQgPSAoY2lkKSA9PiB7XG4gIGNvbnN0IHR5cGUgPSB0eXBlb2YgY2lkO1xuICByZXR1cm4gdHlwZSA9PT0gXCJudW1iZXJcIiB8fCB0eXBlID09PSBcInN0cmluZ1wiICYmIC9eKDB8WzEtOV1cXGQqKSQvLnRlc3QoY2lkKTtcbn07XG5mdW5jdGlvbiBkZXRlY3REdXBsaWNhdGVJZHMoKSB7XG4gIGNvbnN0IGlkcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCk7XG4gIGNvbnN0IGVsZW1zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIipbaWRdXCIpO1xuICBmb3IgKGxldCBpID0gMCwgbGVuID0gZWxlbXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoaWRzLmhhcyhlbGVtc1tpXS5pZCkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgIGBNdWx0aXBsZSBJRHMgZGV0ZWN0ZWQ6ICR7ZWxlbXNbaV0uaWR9LiBFbnN1cmUgdW5pcXVlIGVsZW1lbnQgaWRzLmBcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGl
1kcy5hZGQoZWxlbXNbaV0uaWQpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gZGV0ZWN0SW52YWxpZFN0cmVhbUluc2VydHMoaW5zZXJ0cykge1xuICBjb25zdCBlcnJvcnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICBPYmplY3Qua2V5cyhpbnNlcnRzKS5mb3JFYWNoKChpZCkgPT4ge1xuICAgIGNvbnN0IHN0cmVhbUVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgIGlmIChzdHJlYW1FbCAmJiBzdHJlYW1FbC5wYXJlbnRFbGVtZW50ICYmIHN0cmVhbUVsLnBhcmVudEVsZW1lbnQuZ2V0QXR0cmlidXRlKFwicGh4LXVwZGF0ZVwiKSAhPT0gXCJzdHJlYW1cIikge1xuICAgICAgZXJyb3JzLmFkZChcbiAgICAgICAgYFRoZSBzdHJlYW0gY29udGFpbmVyIHdpdGggaWQgXCIke3N0cmVhbUVsLnBhcmVudEVsZW1lbnQuaWR9XCIgaXMgbWlzc2luZyB0aGUgcGh4LXVwZGF0ZT1cInN0cmVhbVwiIGF0dHJpYnV0ZS4gRW5zdXJlIGl0IGlzIHNldCBmb3Igc3RyZWFtcyB0byB3b3JrIHByb3Blcmx5LmBcbiAgICAgICk7XG4gICAgfVxuICB9KTtcbiAgZXJyb3JzLmZvckVhY2goKGVycm9yKSA9PiBjb25zb2xlLmVycm9yKGVycm9yKSk7XG59XG52YXIgZGVidWcgPSAodmlldywga2luZCwgbXNnLCBvYmopID0+IHtcbiAgaWYgKHZpZXcubGl2ZVNvY2tldC5pc0RlYnVnRW5hYmxlZCgpKSB7XG4gICAgY29uc29sZS5sb2coYCR7dmlldy5pZH0gJHtraW5kfTogJHttc2d9IC0gYCwgb2JqKTtcbiAgfVxufTtcbnZhciBjbG9zdXJlID0gKHZhbCkgPT4gdHlwZW9mIHZhbCA9PT0gXCJmdW5jdGlvblwiID8gdmFsIDogZnVuY3Rpb24oKSB7XG4gIHJldHVybiB2YWw7XG59O1xudmFyIGNsb25lID0gKG9iaikgPT4ge1xuICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShvYmopKTtcbn07XG52YXIgY2xvc2VzdFBoeEJpbmRpbmcgPSAoc3RhcnRFbCwgYmluZGluZywgYm9yZGVyRWwpID0+IHtcbiAgbGV0IGVsID0gc3RhcnRFbDtcbiAgZG8ge1xuICAgIGlmIChlbC5tYXRjaGVzKGBbJHtiaW5kaW5nfV1gKSAmJiAhKFwiZGlzYWJsZWRcIiBpbiBlbCAmJiBlbC5kaXNhYmxlZCkpIHtcbiAgICAgIHJldHVybiBlbDtcbiAgICB9XG4gICAgZWwgPSBlbC5wYXJlbnRFbGVtZW50O1xuICB9IHdoaWxlIChlbCAhPT0gbnVsbCAmJiBlbC5ub2RlVHlwZSA9PT0gMSAmJiAhKGJvcmRlckVsICYmIGJvcmRlckVsLmlzU2FtZU5vZGUoZWwpIHx8IGVsLm1hdGNoZXMoUEhYX1ZJRVdfU0VMRUNUT1IpKSk7XG4gIHJldHVybiBudWxsO1xufTtcbnZhciBpc09iamVjdCA9IChvYmopID0+IHtcbiAgcmV0dXJuIG9iaiAhPT0gbnVsbCAmJiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiICYmICEob2JqIGluc3RhbmNlb2YgQXJyYXkpO1xufTtcbnZhciBpc0VxdWFsT2JqID0gKG9iajEsIG9iajIpID0+IEpTT04uc3RyaW5naWZ5KG9iajEpID09PSBKU09OLnN0cmluZ2lmeShvYmoyKTtcbnZhciBpc0VtcHR5ID0gKG9iaikgPT4ge1xuICBmb3IgKGNvbnN0IHggaW4gb2JqKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufTtcbnZhciBtYXliZSA9IChlbCwgY2FsbGJhY2spID0+IGVsICYmIGNhbGxiYWNrKGVsKTtcbnZhciBjaGFubmVsVXBsb2FkZXIgPSBmdW5jdGlvbihlbnRyaWVzLCBvbkVycm9yLCByZXNwLCBsaXZlU29ja2V0KSB7XG4gIGVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICBjb25zdCBlbnRyeVVwbG9hZGVyID0gbmV3IEVudHJ5VXBsb2FkZXIoZW50cnksIHJlc3AuY29uZmlnLCBsaXZlU29ja2V0KTtcbiAgICBlbnRyeVVwbG9hZGVyLnVwbG9hZCgpO1xuICB9KTtcbn07XG52YXIgZXZlbnRDb250YWluc0ZpbGVzID0gKGUpID0+IHtcbiAgaWYgKGUuZGF0YVRyYW5zZmVyLnR5cGVzKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlLmRhdGFUcmFuc2Zlci50eXBlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGUuZGF0YVRyYW5zZmVyLnR5cGVzW2ldID09PSBcIkZpbGVzXCIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L2Jyb3dzZXIudHNcbnZhciBCcm93c2VyID0ge1xuICBjYW5QdXNoU3RhdGUoKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBoaXN0b3J5LnB1c2hTdGF0ZSAhPT0gXCJ1bmRlZmluZWRcIjtcbiAgfSxcbiAgZHJvcExvY2FsKGxvY2FsU3RvcmFnZSwgbmFtZXNwYWNlLCBzdWJrZXkpIHtcbiAgICByZXR1cm4gbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0odGhpcy5sb2NhbEtleShuYW1lc3BhY2UsIHN1YmtleSkpO1xuICB9LFxuICB1cGRhdGVMb2NhbChsb2NhbFN0b3JhZ2UsIG5hbWVzcGFjZSwgc3Via2V5LCBpbml0aWFsLCBmdW5jKSB7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuZ2V0TG9jYWwobG9jYWxTdG9yYWdlLCBuYW1lc3BhY2UsIHN1YmtleSk7XG4gICAgY29uc3Qga2V5ID0gdGhpcy5sb2NhbEtleShuYW1lc3BhY2UsIHN1YmtleSk7XG4gICAgY29uc3QgbmV3VmFsID0gY3VycmVudCA9PT0gbnVsbCA/IGluaXRpYWwgOiBmdW5jKGN1cnJlbnQpO1xuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGtleSwgSlNPTi5zdHJpbmdpZnkobmV3VmFsKSk7XG4gICAgcmV0dXJuIG5ld1ZhbDtcbiAgfSxcbiAgZ2V0TG9jYWwobG9jYWxTdG9yYWdlLCBuYW1lc3BhY2UsIHN1YmtleSkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMubG9jYWxLZXkobmFtZXNwYWNlLCBzdWJrZXkpKSk7XG4gIH0sXG4gIHVwZGF0ZUN1cnJlbnRTdGF0ZShjYWxsYmFjaykge1xuICAgIGlmICghdGhpcy5jYW5QdXNoU3RhdGUoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBoaXN0b3J5LnJlcGxhY2VTdGF0ZShcbiAgICAgIGNhbGxiYWNrKGhpc3Rvcnkuc3RhdGUgfHwge30pLFxuICAgICAgXCJcIixcbiAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmXG4gICAgKTtcbiAgfSxcbiAgcHVzaFN0YXRlKGtpbmQsIG1ldGEsIHRvKSB7XG4gICAgaWYgKHRoaXMuY2FuUHVzaFN0YXRlKCkpIHtcbiAgICAgIGlmICh0byAhPT0gd2luZG93LmxvY2F0aW9uLmhy
1ZWYpIHtcbiAgICAgICAgaWYgKG1ldGEudHlwZSA9PSBcInJlZGlyZWN0XCIgJiYgbWV0YS5zY3JvbGwpIHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50U3RhdGUgPSBoaXN0b3J5LnN0YXRlIHx8IHt9O1xuICAgICAgICAgIGN1cnJlbnRTdGF0ZS5zY3JvbGwgPSBtZXRhLnNjcm9sbDtcbiAgICAgICAgICBoaXN0b3J5LnJlcGxhY2VTdGF0ZShjdXJyZW50U3RhdGUsIFwiXCIsIHdpbmRvdy5sb2NhdGlvbi5ocmVmKTtcbiAgICAgICAgfVxuICAgICAgICBkZWxldGUgbWV0YS5zY3JvbGw7XG4gICAgICAgIGhpc3Rvcnlba2luZCArIFwiU3RhdGVcIl0obWV0YSwgXCJcIiwgdG8gfHwgbnVsbCk7XG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGhhc2hFbCA9IHRoaXMuZ2V0SGFzaFRhcmdldEVsKHdpbmRvdy5sb2NhdGlvbi5oYXNoKTtcbiAgICAgICAgICBpZiAoaGFzaEVsKSB7XG4gICAgICAgICAgICBoYXNoRWwuc2Nyb2xsSW50b1ZpZXcoKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG1ldGEudHlwZSA9PT0gXCJyZWRpcmVjdFwiKSB7XG4gICAgICAgICAgICB3aW5kb3cuc2Nyb2xsKDAsIDApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0bykge1xuICAgICAgdGhpcy5yZWRpcmVjdCh0byk7XG4gICAgfVxuICB9LFxuICBzZXRDb29raWUobmFtZSwgdmFsdWUsIG1heEFnZVNlY29uZHMpIHtcbiAgICBjb25zdCBleHBpcmVzID0gdHlwZW9mIG1heEFnZVNlY29uZHMgPT09IFwibnVtYmVyXCIgPyBgIG1heC1hZ2U9JHttYXhBZ2VTZWNvbmRzfTtgIDogXCJcIjtcbiAgICBkb2N1bWVudC5jb29raWUgPSBgJHtuYW1lfT0ke3ZhbHVlfTske2V4cGlyZXN9IHBhdGg9L2A7XG4gIH0sXG4gIGdldENvb2tpZShuYW1lKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNvb2tpZS5yZXBsYWNlKFxuICAgICAgbmV3IFJlZ0V4cChgKD86KD86XnwuKjtzKikke25hbWV9cyo9cyooW147XSopLiokKXxeLiokYCksXG4gICAgICBcIiQxXCJcbiAgICApO1xuICB9LFxuICBkZWxldGVDb29raWUobmFtZSkge1xuICAgIGRvY3VtZW50LmNvb2tpZSA9IGAke25hbWV9PTsgbWF4LWFnZT0tMTsgcGF0aD0vYDtcbiAgfSxcbiAgcmVkaXJlY3QodG9VUkwsIGZsYXNoID0gbnVsbCwgbmF2aWdhdGUgPSAodXJsKSA9PiB7XG4gICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSB1cmw7XG4gIH0pIHtcbiAgICBpZiAoZmxhc2gpIHtcbiAgICAgIHRoaXMuc2V0Q29va2llKFwiX19waG9lbml4X2ZsYXNoX19cIiwgZmxhc2gsIDYwKTtcbiAgICB9XG4gICAgbmF2aWdhdGUodG9VUkwpO1xuICB9LFxuICBsb2NhbEtleShuYW1lc3BhY2UsIHN1YmtleSkge1xuICAgIHJldHVybiBgJHtuYW1lc3BhY2V9LSR7c3Via2V5fWA7XG4gIH0sXG4gIGdldEhhc2hUYXJnZXRFbChtYXliZUhhc2gpIHtcbiAgICBjb25zdCBoYXNoID0gbWF5YmVIYXNoLnRvU3RyaW5nKCkuc3Vic3RyaW5nKDEpO1xuICAgIGlmIChoYXNoID09PSBcIlwiKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChoYXNoKSB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBhW25hbWU9XCIke2hhc2h9XCJdYCk7XG4gIH1cbn07XG52YXIgYnJvd3Nlcl9kZWZhdWx0ID0gQnJvd3NlcjtcblxuLy8ganMvcGhvZW5peF9saXZlX3ZpZXcvZG9tLnRzXG52YXIgRE9NID0ge1xuICBieUlkKGlkKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKSB8fCBsb2dFcnJvcihgbm8gaWQgZm91bmQgZm9yICR7aWR9YCk7XG4gIH0sXG4gIGVsZW1lbnRGcm9tVGFyZ2V0KHRhcmdldCkge1xuICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIE5vZGUpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHRhcmdldC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0YXJnZXQucGFyZW50RWxlbWVudDtcbiAgICB9XG4gIH0sXG4gIHJlbW92ZUNsYXNzKGVsLCBjbGFzc05hbWUpIHtcbiAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKGNsYXNzTmFtZSk7XG4gICAgaWYgKGVsLmNsYXNzTGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShcImNsYXNzXCIpO1xuICAgIH1cbiAgfSxcbiAgYWxsKG5vZGUsIHF1ZXJ5LCBjYWxsYmFjaykge1xuICAgIGlmICghbm9kZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBjb25zdCBhcnJheSA9IEFycmF5LmZyb20obm9kZS5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KSk7XG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICBhcnJheS5mb3JFYWNoKGNhbGxiYWNrKTtcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9LFxuICBjaGlsZE5vZGVMZW5ndGgoaHRtbCkge1xuICAgIGNvbnN0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWw7XG4gICAgcmV0dXJuIHRlbXBsYXRlLmNvbnRlbnQuY2hpbGRFbGVtZW50Q291bnQ7XG4gIH0sXG4gIGlzVXBsb2FkSW5wdXQoZWwpIHtcbiAgICByZXR1cm4gZWwudHlwZSA9PT0gXCJmaWxlXCIgJiYgZWwuZ2V0QXR0cmlidXRlKFBIWF9VUExPQURfUkVGKSAhPT0gbnVsbDtcbiAgfSxcbiAgaXNBdXRvVXBsb2FkKGlucHV0RWwpIHtcbiAgICByZXR1cm4gaW5wdXRFbC5oYXNBdHRyaWJ1dGUoXCJkYXRhLXBoeC1hdXRvLXVwbG9hZFwiKTtcbiAgfSxcbiAgZmluZFVwbG9hZElucHV0cyhub2RlKSB7XG4gICAgY29uc3QgZm9ybUlkID0gbm9kZS5pZDtcbiAgICBjb25zdCBpbnB1dHNPdXRzaWRlRm9ybSA9IHRoaXMuYWxsKFxuICAgICAgZG9jdW1lbnQsXG4gICAgICBgaW5wdXRbdHlwZT1cImZpbGVcIl1bJHtQSFhfVVBMT0FEX1JFRn1dW2Zvcm09XCIke2Zvcm1JZH1cIl1gXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hbGwobm9kZSwgYGlucHV0W3R5cGU9XCJmaWxlXCJdWyR7UEhYX1VQTE9BRF9SRUZ9XWApLmNvbmNhdChcbiAgICAgIGlucHV0c091dHNpZGVGb3JtXG4gICAgKTtcbiAgfSxcbiAgZmluZENvbXBvbmVudCh2aWV3SWQsIGNpZCwgZG9jMiA9IGRvY3VtZW50KSB7XG4gICAgcmV0dXJuIGRvYzIucXVlcnlTZWxlY3RvcihcbiAgICAgIGBbJHtQSFhfVklFV19SRUZ9PVwiJHt2aWV3SWR9XCJdWyR7UEhYX0NPTVBPTkVOVH09XCIke2NpZH1cIl1gXG4gICAgKTtcbiAgfSxcbiAgZ2V0Q29tcG9uZW50KHZpZXdJZCwgY2lkLCBkb2MyID0gZG9jdW1lbnQpIHtcbiAgICBjb25zdCBlbCA9IHRoaXMuZmluZENvbXBvbmVudCh2aWV3SWQsIGNpZCwgZG9jMik7XG4gICAgaWYgKCFlbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgbm8gY29tcG9uZW50IGZvdW5kIG1hdGNoaW5nIHZpZXdJZCAke3ZpZXdJZH0gYW5kIGNpZCAke2NpZH1gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gZWw7XG4gIH0sXG4gIGlzUGh4RGVzdHJveWVkKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5pZCAmJiBET00ucHJpdmF0ZShub2RlLCBcImRlc3Ryb3llZFwiKSA/IHRydWUgOiBmYWxzZTtcbiAgfSxcbiAgd2FudHNOZXdUYWIoZSkge1xuICAgIGNvbnN0IHdhbnRzTmV3VGFiID0gZS5jdHJsS2V5IHx8IGUuc2hpZnRLZXkgfHwgZS5tZXRhS2V5IHx8IGUuYnV0dG9uICYmIGUuYnV0dG9uID09PSAxO1xuICAgIGNvbnN0IGlzRG93bmxvYWQgPSBlLnRhcmdldCBpbnN0YW5jZW9mIEhUTUxBbmNob3JFbGVtZW50ICYmIGUudGFyZ2V0Lmhhc0F0dHJpYnV0ZShcImRvd25sb2FkXCIpO1xuICAgIGNvbnN0IGlzVGFyZ2V0QmxhbmsgPSBlLnRhcmdldC5oYXNBdHRyaWJ1dGUoXCJ0YXJnZXRcIikgJiYgZS50YXJnZXQuZ2V0QXR0cmlidXRlKFwidGFyZ2V0XCIpLnRvTG93ZXJDYXNlKCkgPT09IFwiX2JsYW5rXCI7XG4gICAgY29uc3QgaXNUYXJnZXROYW1lZFRhYiA9IGUudGFyZ2V0Lmhhc0F0dHJpYnV0ZShcInRhcmdldFwiKSAmJiAhZS
150YXJnZXQuZ2V0QXR0cmlidXRlKFwidGFyZ2V0XCIpLnN0YXJ0c1dpdGgoXCJfXCIpO1xuICAgIHJldHVybiB3YW50c05ld1RhYiB8fCBpc1RhcmdldEJsYW5rIHx8IGlzRG93bmxvYWQgfHwgaXNUYXJnZXROYW1lZFRhYjtcbiAgfSxcbiAgaXNVbmxvYWRhYmxlRm9ybVN1Ym1pdChlKSB7XG4gICAgY29uc3QgaXNEaWFsb2dTdWJtaXQgPSBlLnRhcmdldCAmJiBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoXCJtZXRob2RcIikgPT09IFwiZGlhbG9nXCIgfHwgZS5zdWJtaXR0ZXIgJiYgZS5zdWJtaXR0ZXIuZ2V0QXR0cmlidXRlKFwiZm9ybW1ldGhvZFwiKSA9PT0gXCJkaWFsb2dcIjtcbiAgICBpZiAoaXNEaWFsb2dTdWJtaXQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuICFlLmRlZmF1bHRQcmV2ZW50ZWQgJiYgIXRoaXMud2FudHNOZXdUYWIoZSk7XG4gICAgfVxuICB9LFxuICBpc05ld1BhZ2VDbGljayhlLCBjdXJyZW50TG9jYXRpb24pIHtcbiAgICBjb25zdCBocmVmID0gZS50YXJnZXQgaW5zdGFuY2VvZiBIVE1MQW5jaG9yRWxlbWVudCA/IGUudGFyZ2V0LmdldEF0dHJpYnV0ZShcImhyZWZcIikgOiBudWxsO1xuICAgIGxldCB1cmw7XG4gICAgaWYgKGUuZGVmYXVsdFByZXZlbnRlZCB8fCBocmVmID09PSBudWxsIHx8IHRoaXMud2FudHNOZXdUYWIoZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGhyZWYuc3RhcnRzV2l0aChcIm1haWx0bzpcIikgfHwgaHJlZi5zdGFydHNXaXRoKFwidGVsOlwiKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoZS50YXJnZXQuaXNDb250ZW50RWRpdGFibGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIHVybCA9IG5ldyBVUkwoaHJlZik7XG4gICAgfSBjYXRjaCB7XG4gICAgICB0cnkge1xuICAgICAgICB1cmwgPSBuZXcgVVJMKGhyZWYsIGN1cnJlbnRMb2NhdGlvbik7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh1cmwuaG9zdCA9PT0gY3VycmVudExvY2F0aW9uLmhvc3QgJiYgdXJsLnByb3RvY29sID09PSBjdXJyZW50TG9jYXRpb24ucHJvdG9jb2wpIHtcbiAgICAgIGlmICh1cmwucGF0aG5hbWUgPT09IGN1cnJlbnRMb2NhdGlvbi5wYXRobmFtZSAmJiB1cmwuc2VhcmNoID09PSBjdXJyZW50TG9jYXRpb24uc2VhcmNoKSB7XG4gICAgICAgIHJldHVybiB1cmwuaGFzaCA9PT0gXCJcIiAmJiAhdXJsLmhyZWYuZW5kc1dpdGgoXCIjXCIpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdXJsLnByb3RvY29sLnN0YXJ0c1dpdGgoXCJodHRwXCIpO1xuICB9LFxuICBtYXJrUGh4Q2hpbGREZXN0cm95ZWQoZWwpIHtcbiAgICBpZiAodGhpcy5pc1BoeENoaWxkKGVsKSkge1xuICAgICAgZWwuc2V0QXR0cmlidXRlKFBIWF9TRVNTSU9OLCBcIlwiKTtcbiAgICB9XG4gICAgdGhpcy5wdXRQcml2YXRlKGVsLCBcImRlc3Ryb3llZFwiLCB0cnVlKTtcbiAgfSxcbiAgZmluZFBoeENoaWxkcmVuSW5GcmFnbWVudChodG1sLCBwYXJlbnRJZCkge1xuICAgIGNvbnN0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWw7XG4gICAgcmV0dXJuIHRoaXMuZmluZFBoeENoaWxkcmVuKHRlbXBsYXRlLmNvbnRlbnQsIHBhcmVudElkKTtcbiAgfSxcbiAgaXNJZ25vcmVkKGVsLCBwaHhVcGRhdGUpIHtcbiAgICByZXR1cm4gKGVsLmdldEF0dHJpYnV0ZShwaHhVcGRhdGUpIHx8IGVsLmdldEF0dHJpYnV0ZShcImRhdGEtcGh4LXVwZGF0ZVwiKSkgPT09IFwiaWdub3JlXCI7XG4gIH0sXG4gIGlzUGh4VXBkYXRlKGVsLCBwaHhVcGRhdGUsIHVwZGF0ZVR5cGVzKSB7XG4gICAgcmV0dXJuIGVsLmdldEF0dHJpYnV0ZSAmJiB1cGRhdGVUeXBlcy5pbmRleE9mKGVsLmdldEF0dHJpYnV0ZShwaHhVcGRhdGUpKSA+PSAwO1xuICB9LFxuICBmaW5kUGh4U3RpY2t5KGVsKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKGVsLCBgWyR7UEhYX1NUSUNLWX1dYCk7XG4gIH0sXG4gIGZpbmRQaHhDaGlsZHJlbihlbCwgcGFyZW50SWQpIHtcbiAgICByZXR1cm4gdGhpcy5hbGwoZWwsIGAke1BIWF9WSUVXX1NFTEVDVE9SfVske1BIWF9QQVJFTlRfSUR9PVwiJHtwYXJlbnRJZH1cIl1gKTtcbiAgfSxcbiAgZmluZEV4aXN0aW5nUGFyZW50Q0lEcyh2aWV3SWQsIGNpZHMpIHtcbiAgICBjb25zdCBwYXJlbnRDaWRzID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgICBjb25zdCBjaGlsZHJlbkNpZHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICAgIGNpZHMuZm9yRWFjaCgoY2lkKSA9PiB7XG4gICAgICB0aGlzLmFsbChcbiAgICAgICAgZG9jdW1lbnQsXG4gICAgICAgIGBbJHtQSFhfVklFV19SRUZ9PVwiJHt2aWV3SWR9XCJdWyR7UEhYX0NPTVBPTkVOVH09XCIke2NpZH1cIl1gXG4gICAgICApLmZvckVhY2goKHBhcmVudCkgPT4ge1xuICAgICAgICBwYXJlbnRDaWRzLmFkZChjaWQpO1xuICAgICAgICB0aGlzLmFsbChwYXJlbnQsIGBbJHtQSFhfVklFV19SRUZ9PVwiJHt2aWV3SWR9XCJdWyR7UEhYX0NPTVBPTkVOVH1dYCkubWFwKChlbCkgPT4gcGFyc2VJbnQoZWwuZ2V0QXR0cmlidXRlKFBIWF9DT01QT05FTlQpKSkuZm9yRWFjaCgoY2hpbGRDSUQpID0+IGNoaWxkcmVuQ2lkcy5hZGQoY2hpbGRDSUQpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGNoaWxkcmVuQ2lkcy5mb3JFYWNoKChjaGlsZENpZCkgPT4gcGFyZW50Q2lkcy5kZWxldGUoY2hpbGRDaWQpKTtcbiAgICByZXR1cm4gcGFyZW50Q2lkcztcbiAgfSxcbiAgcHJpdmF0ZShlbCwga2V5KSB7XG4gICAgcmV0dXJuIGVsW1BIWF9QUklWQVRFXSAmJiBlbFtQSFhfUFJJVkFURV1ba2V5XTtcbiAgfSxcbiAgZGVsZXRlUHJpdmF0ZShlbCwga2V5KSB7XG4gICAgZWxbUEhYX1BSSVZBVEVdICYmIGRlbGV0ZSBlbFtQSFhfUFJJVkFURV1ba2V5XTtcbiAgfSxcbiAgcHV0UHJpdmF0ZShlbCwga2V5LCB2YWx1ZSkge1xuICAgIGlmICghZWxbUEhYX1BSSVZBVEVdKSB7XG4gICAgICBlbFtQSFhfUFJJVkFURV0gPSB7fTtcbiAgICB9XG4gICAgZWxbUEhYX1BSSVZBVEVdW2tleV0gPSB2YWx1ZTtcbiAgfSxcbiAgdXBkYXRlUHJpdmF0ZShlbCwga2V5LCBkZWZhdWx0VmFsLCB1cGRhdGVGdW5jKSB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLnByaXZhdGUoZWwsIGtleSk7XG4gICAgaWYgKGV4aXN0aW5nID09PSB2b2lkIDApIHtcbiAgICAgIHRoaXMucHV0UHJpdmF0ZShlbCwga2V5LCB1cGRhdGVGdW5jKGRlZmF1bHRWYWwpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wdXRQcml2YXRlKGVsLCBrZXksIHVwZGF0ZUZ1bmMoZXhpc3R
1pbmcpKTtcbiAgICB9XG4gIH0sXG4gIHN5bmNQZW5kaW5nQXR0cnMoZnJvbUVsLCB0b0VsKSB7XG4gICAgaWYgKCFmcm9tRWwuaGFzQXR0cmlidXRlKFBIWF9SRUZfU1JDKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBQSFhfRVZFTlRfQ0xBU1NFUy5mb3JFYWNoKChjbGFzc05hbWUpID0+IHtcbiAgICAgIGZyb21FbC5jbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKSAmJiB0b0VsLmNsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcbiAgICB9KTtcbiAgICBQSFhfUEVORElOR19BVFRSUy5maWx0ZXIoKGF0dHIpID0+IGZyb21FbC5oYXNBdHRyaWJ1dGUoYXR0cikpLmZvckVhY2goXG4gICAgICAoYXR0cikgPT4ge1xuICAgICAgICB0b0VsLnNldEF0dHJpYnV0ZShhdHRyLCBmcm9tRWwuZ2V0QXR0cmlidXRlKGF0dHIpKTtcbiAgICAgIH1cbiAgICApO1xuICB9LFxuICBjb3B5UHJpdmF0ZXModGFyZ2V0LCBzb3VyY2UpIHtcbiAgICBpZiAoc291cmNlW1BIWF9QUklWQVRFXSkge1xuICAgICAgdGFyZ2V0W1BIWF9QUklWQVRFXSA9IHNvdXJjZVtQSFhfUFJJVkFURV07XG4gICAgfVxuICB9LFxuICBwdXRUaXRsZShzdHIpIHtcbiAgICBjb25zdCB0aXRsZUVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcInRpdGxlXCIpO1xuICAgIGlmICh0aXRsZUVsKSB7XG4gICAgICBjb25zdCB7IHByZWZpeCwgc3VmZml4LCBkZWZhdWx0OiBkZWZhdWx0VGl0bGUgfSA9IHRpdGxlRWwuZGF0YXNldDtcbiAgICAgIGNvbnN0IGlzRW1wdHkyID0gdHlwZW9mIHN0ciAhPT0gXCJzdHJpbmdcIiB8fCBzdHIudHJpbSgpID09PSBcIlwiO1xuICAgICAgaWYgKGlzRW1wdHkyICYmIHR5cGVvZiBkZWZhdWx0VGl0bGUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgaW5uZXIgPSBpc0VtcHR5MiA/IGRlZmF1bHRUaXRsZSA6IHN0cjtcbiAgICAgIGRvY3VtZW50LnRpdGxlID0gYCR7cHJlZml4IHx8IFwiXCJ9JHtpbm5lciB8fCBcIlwifSR7c3VmZml4IHx8IFwiXCJ9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgZG9jdW1lbnQudGl0bGUgPSBzdHI7XG4gICAgfVxuICB9LFxuICBkZWJvdW5jZShlbCwgZXZlbnQsIHBoeERlYm91bmNlLCBkZWZhdWx0RGVib3VuY2UsIHBoeFRocm90dGxlLCBkZWZhdWx0VGhyb3R0bGUsIGFzeW5jRmlsdGVyLCBjYWxsYmFjaykge1xuICAgIGxldCBkZWJvdW5jZSA9IGVsLmdldEF0dHJpYnV0ZShwaHhEZWJvdW5jZSk7XG4gICAgbGV0IHRocm90dGxlID0gZWwuZ2V0QXR0cmlidXRlKHBoeFRocm90dGxlKTtcbiAgICBpZiAoZGVib3VuY2UgPT09IFwiXCIpIHtcbiAgICAgIGRlYm91bmNlID0gZGVmYXVsdERlYm91bmNlO1xuICAgIH1cbiAgICBpZiAodGhyb3R0bGUgPT09IFwiXCIpIHtcbiAgICAgIHRocm90dGxlID0gZGVmYXVsdFRocm90dGxlO1xuICAgIH1cbiAgICBjb25zdCB2YWx1ZSA9IGRlYm91bmNlIHx8IHRocm90dGxlO1xuICAgIHN3aXRjaCAodmFsdWUpIHtcbiAgICAgIGNhc2UgbnVsbDpcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgICBjYXNlIFwiYmx1clwiOlxuICAgICAgICB0aGlzLmluY0N5Y2xlKGVsLCBcImRlYm91bmNlLWJsdXItY3ljbGVcIiwgKCkgPT4ge1xuICAgICAgICAgIGlmIChhc3luY0ZpbHRlcigpKSB7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLm9uY2UoZWwsIFwiZGVib3VuY2UtYmx1clwiKSkge1xuICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICBcImJsdXJcIixcbiAgICAgICAgICAgICgpID0+IHRoaXMudHJpZ2dlckN5Y2xlKGVsLCBcImRlYm91bmNlLWJsdXItY3ljbGVcIilcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGNvbnN0IHRpbWVvdXQgPSBwYXJzZUludCh2YWx1ZSk7XG4gICAgICAgIGNvbnN0IHRyaWdnZXIgPSAoKSA9PiB0aHJvdHRsZSA/IHRoaXMuZGVsZXRlUHJpdmF0ZShlbCwgVEhST1RUTEVEKSA6IGNhbGxiYWNrKCk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRDeWNsZSA9IHRoaXMuaW5jQ3ljbGUoZWwsIERFQk9VTkNFX1RSSUdHRVIsIHRyaWdnZXIpO1xuICAgICAgICBpZiAoaXNOYU4odGltZW91dCkpIHtcbiAgICAgICAgICByZXR1cm4gbG9nRXJyb3IoYGludmFsaWQgdGhyb3R0bGUvZGVib3VuY2UgdmFsdWU6ICR7dmFsdWV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRocm90dGxlKSB7XG4gICAgICAgICAgbGV0IG5ld0tleURvd24gPSBmYWxzZTtcbiAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJrZXlkb3duXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZLZXkgPSB0aGlzLnByaXZhdGUoZWwsIERFQk9VTkNFX1BSRVZfS0VZKTtcbiAgICAgICAgICAgIHRoaXMucHV0UHJpdmF0ZShlbCwgREVCT1VOQ0VfUFJFVl9LRVksIGV2ZW50LmtleSk7XG4gICAgICAgICAgICBuZXdLZXlEb3duID0gcHJldktleSAhPT0gZXZlbnQua2V5O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5ld0tleURvd24gJiYgdGhpcy5wcml2YXRlKGVsLCBUSFJPVFRMRUQpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICBjb25zdCB0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChhc3luY0ZpbHRlcigpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyQ3ljbGUoZWwsIERFQk9VTkNFX1RSSUdHRVIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgICAgIHRoaXMucHV0UHJpdmF0ZShlbCwgVEhST1RUTEVELCB0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAoYXN5bmNGaWx0ZXIoKSkge1xuICAgICAgICAgICAgICB0aGlzLnRyaWdnZXJDeWNsZShlbCwgREVCT1VOQ0VfVFJJR0dFUiwgY3VycmVudEN5Y2xlKTtcbiAgICAgICAgICAgI
1H1cbiAgICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmb3JtID0gZWwuZm9ybTtcbiAgICAgICAgaWYgKGZvcm0gJiYgdGhpcy5vbmNlKGZvcm0sIFwiYmluZC1kZWJvdW5jZVwiKSkge1xuICAgICAgICAgIGZvcm0uYWRkRXZlbnRMaXN0ZW5lcihcInN1Ym1pdFwiLCAoKSA9PiB7XG4gICAgICAgICAgICBBcnJheS5mcm9tKG5ldyBGb3JtRGF0YShmb3JtKS5lbnRyaWVzKCksIChbbmFtZV0pID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgbmFtZWRJdGVtID0gZm9ybS5lbGVtZW50cy5uYW1lZEl0ZW0obmFtZSk7XG4gICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gbmFtZWRJdGVtIGluc3RhbmNlb2YgUmFkaW9Ob2RlTGlzdCA/IG5hbWVkSXRlbVswXSA6IG5hbWVkSXRlbTtcbiAgICAgICAgICAgICAgaWYgKGlucHV0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbmNDeWNsZShpbnB1dCwgREVCT1VOQ0VfVFJJR0dFUik7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxldGVQcml2YXRlKGlucHV0LCBUSFJPVFRMRUQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5vbmNlKGVsLCBcImJpbmQtZGVib3VuY2VcIikpIHtcbiAgICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKFwiYmx1clwiLCAoKSA9PiB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wcml2YXRlKGVsLCBUSFJPVFRMRUQpKTtcbiAgICAgICAgICAgIGlmIChhc3luY0ZpbHRlcigpKSB7XG4gICAgICAgICAgICAgIHRoaXMudHJpZ2dlckN5Y2xlKGVsLCBERUJPVU5DRV9UUklHR0VSKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgfSxcbiAgdHJpZ2dlckN5Y2xlKGVsLCBrZXksIGN1cnJlbnRDeWNsZSkge1xuICAgIGNvbnN0IFtjeWNsZSwgdHJpZ2dlcl0gPSB0aGlzLnByaXZhdGUoZWwsIGtleSk7XG4gICAgaWYgKCFjdXJyZW50Q3ljbGUpIHtcbiAgICAgIGN1cnJlbnRDeWNsZSA9IGN5Y2xlO1xuICAgIH1cbiAgICBpZiAoY3VycmVudEN5Y2xlID09PSBjeWNsZSkge1xuICAgICAgdGhpcy5pbmNDeWNsZShlbCwga2V5KTtcbiAgICAgIHRyaWdnZXIoKTtcbiAgICB9XG4gIH0sXG4gIG9uY2UoZWwsIGtleSkge1xuICAgIGlmICh0aGlzLnByaXZhdGUoZWwsIGtleSkgPT09IHRydWUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdGhpcy5wdXRQcml2YXRlKGVsLCBrZXksIHRydWUpO1xuICAgIHJldHVybiB0cnVlO1xuICB9LFxuICBpbmNDeWNsZShlbCwga2V5LCB0cmlnZ2VyID0gZnVuY3Rpb24oKSB7XG4gIH0pIHtcbiAgICBsZXQgW2N1cnJlbnRDeWNsZV0gPSB0aGlzLnByaXZhdGUoZWwsIGtleSkgfHwgWzAsIHRyaWdnZXJdO1xuICAgIGN1cnJlbnRDeWNsZSsrO1xuICAgIHRoaXMucHV0UHJpdmF0ZShlbCwga2V5LCBbY3VycmVudEN5Y2xlLCB0cmlnZ2VyXSk7XG4gICAgcmV0dXJuIGN1cnJlbnRDeWNsZTtcbiAgfSxcbiAgLy8gbWFpbnRhaW5zIG9yIGFkZHMgcHJpdmF0ZWx5IHVzZWQgaG9vayBpbmZvcm1hdGlvblxuICAvLyBmcm9tRWwgYW5kIHRvRWwgY2FuIGJlIHRoZSBzYW1lIGVsZW1lbnQgaW4gdGhlIGNhc2Ugb2YgYSBuZXdseSBhZGRlZCBub2RlXG4gIC8vIGZyb21FbCBhbmQgdG9FbCBjYW4gYmUgYW55IEhUTUwgbm9kZSB0eXBlLCBzbyB3ZSBuZWVkIHRvIGNoZWNrIGlmIGl0J3MgYW4gZWxlbWVudCBub2RlXG4gIG1haW50YWluUHJpdmF0ZUhvb2tzKGZyb21FbCwgdG9FbCwgcGh4Vmlld3BvcnRUb3AsIHBoeFZpZXdwb3J0Qm90dG9tKSB7XG4gICAgaWYgKGZyb21FbC5oYXNBdHRyaWJ1dGUgJiYgZnJvbUVsLmhhc0F0dHJpYnV0ZShcImRhdGEtcGh4LWhvb2tcIikgJiYgIXRvRWwuaGFzQXR0cmlidXRlKFwiZGF0YS1waHgtaG9va1wiKSkge1xuICAgICAgdG9FbC5zZXRBdHRyaWJ1dGUoXCJkYXRhLXBoeC1ob29rXCIsIGZyb21FbC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXBoeC1ob29rXCIpKTtcbiAgICB9XG4gICAgaWYgKHRvRWwuaGFzQXR0cmlidXRlICYmICh0b0VsLmhhc0F0dHJpYnV0ZShwaHhWaWV3cG9ydFRvcCkgfHwgdG9FbC5oYXNBdHRyaWJ1dGUocGh4Vmlld3BvcnRCb3R0b20pKSkge1xuICAgICAgdG9FbC5zZXRBdHRyaWJ1dGUoXCJkYXRhLXBoeC1ob29rXCIsIFwiUGhvZW5peC5JbmZpbml0ZVNjcm9sbFwiKTtcbiAgICB9XG4gIH0sXG4gIHB1dEN1c3RvbUVsSG9vayhlbCwgaG9vaykge1xuICAgIGlmIChlbC5pc0Nvbm5lY3RlZCkge1xuICAgICAgZWwuc2V0QXR0cmlidXRlKFwiZGF0YS1waHgtaG9va1wiLCBcIlwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcihgXG4gICAgICAgIGhvb2sgYXR0YWNoZWQgdG8gbm9uLWNvbm5lY3RlZCBET00gZWxlbWVudFxuICAgICAgICBlbnN1cmUgeW91IGFyZSBjYWxsaW5nIGNyZWF0ZUhvb2sgd2l0aGluIHlvdXIgY29ubmVjdGVkQ2FsbGJhY2suICR7ZWwub3V0ZXJIVE1MfVxuICAgICAgYCk7XG4gICAgfVxuICAgIHRoaXMucHV0UHJpdmF0ZShlbCwgXCJjdXN0b20tZWwtaG9va1wiLCBob29rKTtcbiAgfSxcbiAgZ2V0Q3VzdG9tRWxIb29rKGVsKSB7XG4gICAgcmV0dXJuIHRoaXMucHJpdmF0ZShlbCwgXCJjdXN0b20tZWwtaG9va1wiKTtcbiAgfSxcbiAgaXNVc2VkSW5wdXQoZWwpIHtcbiAgICByZXR1cm4gZWwubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmICh0aGlzLnByaXZhdGUoZWwsIFBIWF9IQVNfRk9DVVNFRCkgfHwgdGhpcy5wcml2YXRlKGVsLCBQSFhfSEFTX1NVQk1JVFRFRCkpO1xuICB9LFxuICByZXNldEZvcm0oZm9ybSkge1xuICAgIEFycmF5LmZyb20oZm9ybS5lbGVtZW50cykuZm9yRWFjaCgoaW5wdXQpID0+IHtcbiAgICAgIHRoaXMuZGVsZXRlUHJpdmF0ZShpbnB1dCwgUEhYX0hBU19GT0NVU0VEKTtcbiAgICAgIHRoaXMuZGVsZXRlUHJpdmF0ZShpbnB1dCwgUEhYX0hBU19TVUJNSVRURUQpO1xuICAgIH0pO1xuICB9LFxuICBpc1BoeENoaWxkKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5nZXRBdHRyaWJ1dGUgJiYgbm9kZS5nZXRBdHRyaWJ1dGUoUEhYX1BBUkVOVF9JRCk7XG4gIH0sXG4gIGlzUGh4U3RpY2t5KG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5nZXRBdHRyaWJ1dGUgJiYgbm9kZS5nZXRBdHRyaWJ1dGUoUEhYX1NUSUNLWSkgIT09IG51bGw7XG4gIH0sXG4gIGlzQ2hpbGRPZkFueShlbCwgcGFyZW50cykge1xuICAgIHJldHVybiAhIXBhcmVudHMuZmluZCgocGFyZW50KSA9PiBwYXJlbnQuY29udGFpbnMoZWwpKTtcbiAgfSxcbiAgZmlyc3RQaHhDaGlsZChlbCkge1xuICAgIHJldHVybi
1B0aGlzLmlzUGh4Q2hpbGQoZWwpID8gZWwgOiB0aGlzLmFsbChlbCwgYFske1BIWF9QQVJFTlRfSUR9XWApWzBdO1xuICB9LFxuICBpc1BvcnRhbFRlbXBsYXRlKGVsKSB7XG4gICAgcmV0dXJuIGVsLnRhZ05hbWUgPT09IFwiVEVNUExBVEVcIiAmJiBlbC5oYXNBdHRyaWJ1dGUoUEhYX1BPUlRBTCk7XG4gIH0sXG4gIGNsb3Nlc3RWaWV3RWwoZWwpIHtcbiAgICBjb25zdCBwb3J0YWxPclZpZXdFbCA9IGVsLmNsb3Nlc3QoXG4gICAgICBgWyR7UEhYX1RFTEVQT1JURURfUkVGfV0sJHtQSFhfVklFV19TRUxFQ1RPUn1gXG4gICAgKTtcbiAgICBpZiAoIXBvcnRhbE9yVmlld0VsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHBvcnRhbE9yVmlld0VsLmhhc0F0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9SRUYpKSB7XG4gICAgICByZXR1cm4gdGhpcy5ieUlkKHBvcnRhbE9yVmlld0VsLmdldEF0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9SRUYpKTtcbiAgICB9IGVsc2UgaWYgKHBvcnRhbE9yVmlld0VsLmhhc0F0dHJpYnV0ZShQSFhfU0VTU0lPTikpIHtcbiAgICAgIHJldHVybiBwb3J0YWxPclZpZXdFbDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH0sXG4gIGRpc3BhdGNoRXZlbnQodGFyZ2V0LCBuYW1lLCBvcHRzID0ge30pIHtcbiAgICBsZXQgZGVmYXVsdEJ1YmJsZSA9IHRydWU7XG4gICAgY29uc3QgaXNVcGxvYWRUYXJnZXQgPSB0YXJnZXQubm9kZU5hbWUgPT09IFwiSU5QVVRcIiAmJiB0YXJnZXQudHlwZSA9PT0gXCJmaWxlXCI7XG4gICAgaWYgKGlzVXBsb2FkVGFyZ2V0ICYmIG5hbWUgPT09IFwiY2xpY2tcIikge1xuICAgICAgZGVmYXVsdEJ1YmJsZSA9IGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCBidWJibGVzID0gb3B0cy5idWJibGVzID09PSB2b2lkIDAgPyBkZWZhdWx0QnViYmxlIDogISFvcHRzLmJ1YmJsZXM7XG4gICAgY29uc3QgZXZlbnRPcHRzID0ge1xuICAgICAgYnViYmxlcyxcbiAgICAgIGNhbmNlbGFibG
1U6IHRydWUsXG4gICAgICBkZXRhaWw6IG9wdHMuZGV0YWlsIHx8IHt9XG4gICAgfTtcbiAgICBjb25zdCBldmVudCA9IG5hbWUgPT09IFwiY2xpY2tcIiA/IG5ldyBNb3VzZUV2ZW50KFwiY2xpY2tcIiwgZXZlbnRPcHRzKSA6IG5ldyBDdXN0b21FdmVudChuYW1lLCBldmVudE9wdHMpO1xuICAgIHRhcmdldC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgfSxcbiAgY2xvbmVOb2RlKG5vZGUsIGh0bWwpIHtcbiAgICBpZiAodHlwZW9mIGh0bWwgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIHJldHVybiBub2RlLmNsb25lTm9kZSh0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgY2xvbmVkID0gbm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xuICAgICAgY2xvbmVkLmlubmVySFRNTCA9IGh0bWw7XG4gICAgICByZXR1cm4gY2xvbmVkO1xuICAgIH1cbiAgfSxcbiAgLy8gbWVyZ2UgYXR0cmlidXRlcyBmcm9tIHNvdXJjZSB0byB0YXJnZXRcbiAgLy8gaWYgYW4gZWxlbWVudCBpcyBpZ25vcmVkLCB3ZSBvbmx5IG1lcmdlIGRhdGEgYXR0cmlidXRlc1xuICAvLyBpbmNsdWRpbmcgcmVtb3ZpbmcgZGF0YSBhdHRyaWJ1dGVzIHRoYXQgYXJlIG5vIGxvbmdlciBpbiB0aGUgc291cmNlXG4gIG1lcmdlQXR0cnModGFyZ2V0LCBzb3VyY2UsIG9wdHMgPSB7fSkge1xuICAgIGNvbnN0IGV4Y2x1ZGUgPSBuZXcgU2V0KG9wdHMuZXhjbHVkZSB8fCBbXSk7XG4gICAgY29uc3QgaXNJZ25vcmVkID0gb3B0cy5pc0lnbm9yZWQ7XG4gICAgY29uc3Qgc291cmNlQXR0cnMgPSBzb3VyY2UuYXR0cmlidXRlcztcbiAgICBmb3IgKGxldCBpID0gc291cmNlQXR0cnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IG5hbWUgPSBzb3VyY2VBdHRyc1tpXS5uYW1lO1xuICAgICAgaWYgKCFleGNsdWRlLmhhcyhuYW1lKSkge1xuICAgICAgICBjb25zdCBzb3VyY2VWYWx1ZSA9IHNvdXJjZS5nZXRBdHRyaWJ1dGUobmFtZSk7XG4gICAgICAgIGlmICh0YXJnZXQuZ2V0QXR0cmlidXRlKG5hbWUpICE9PSBzb3VyY2VWYWx1ZSAmJiAoIWlzSWdub3JlZCB8fCBpc0lnbm9yZWQgJiYgbmFtZS5zdGFydHNXaXRoKFwiZGF0YS1cIikpKSB7XG4gICAgICAgICAgdGFyZ2V0LnNldEF0dHJpYnV0ZShuYW1lLCBzb3VyY2VWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChuYW1lID09PSBcInZhbHVlXCIpIHtcbiAgICAgICAgICBjb25zdCBzb3VyY2VWYWx1ZSA9IHNvdXJjZS52YWx1ZSA/PyBzb3VyY2UuZ2V0QXR0cmlidXRlKG5hbWUpO1xuICAgICAgICAgIGlmICh0YXJnZXQudmFsdWUgPT09IHNvdXJjZVZhbHVlKSB7XG4gICAgICAgICAgICB0YXJnZXQuc2V0QXR0cmlidXRlKFwidmFsdWVcIiwgc291cmNlLmdldEF0dHJpYnV0ZShuYW1lKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHRhcmdldEF0dHJzID0gdGFyZ2V0LmF0dHJpYnV0ZXM7XG4gICAgZm9yIChsZXQgaSA9IHRhcmdldEF0dHJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBjb25zdCBuYW1lID0gdGFyZ2V0QXR0cnNbaV0ubmFtZTtcbiAgICAgIGlmIChpc0lnbm9yZWQpIHtcbiAgICAgICAgaWYgKG5hbWUuc3RhcnRzV2l0aChcImRhdGEtXCIpICYmICFzb3VyY2UuaGFzQXR0cmlidXRlKG5hbWUpICYmICFQSFhfUEVORElOR19BVFRSUy5pbmNsdWRlcyhuYW1lKSkge1xuICAgICAgICAgIHRhcmdldC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghc291cmNlLmhhc0F0dHJpYnV0ZShuYW1lKSkge1xuICAgICAgICAgIHRhcmdldC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIG1lcmdlRm9jdXNlZElucHV0KHRhcmdldCwgc291cmNlKSB7XG4gICAgaWYgKCEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTFNlbGVjdEVsZW1lbnQpKSB7XG4gICAgICBET00ubWVyZ2VBdHRycyh0YXJnZXQsIHNvdXJjZSwgeyBleGNsdWRlOiBbXCJ2YWx1ZVwiXSB9KTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZS5yZWFkT25seSkge1xuICAgICAgdGFyZ2V0LnNldEF0dHJpYnV0ZShcInJlYWRvbmx5XCIsIHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0YXJnZXQucmVtb3ZlQXR0cmlidXRlKFwicmVhZG9ubHlcIik7XG4gICAgfVxuICB9LFxuICBoYXNTZWxlY3Rpb25SYW5nZShlbCkge1xuICAgIHJldHVybiBlbC5zZXRTZWxlY3Rpb25SYW5nZSAmJiAoZWwudHlwZSA9PT0gXCJ0ZXh0XCIgfHwgZWwudHlwZSA9PT0gXCJ0ZXh0YXJlYVwiKTtcbiAgfSxcbiAgcmVzdG9yZUZvY3VzKGZvY3VzZWQsIHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25FbmQpIHtcbiAgICBpZiAoZm9jdXNlZCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50KSB7XG4gICAgICBmb2N1c2VkLmZvY3VzKCk7XG4gICAgfVxuICAgIGlmICghRE9NLmlzVGV4dHVhbElucHV0KGZvY3VzZWQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHdhc0ZvY3VzZWQgPSBmb2N1c2VkLm1hdGNoZXMoXCI6Zm9jdXNcIik7XG4gICAgaWYgKCF3YXNGb2N1c2VkKSB7XG4gICAgICBmb2N1c2VkLmZvY3VzKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmhhc1NlbGVjdGlvblJhbmdlKGZvY3VzZWQpKSB7XG4gICAgICBmb2N1c2VkLnNldFNlbGVjdGlvblJhbmdlKHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25FbmQpO1xuICAgIH1cbiAgfSxcbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZWxlbWVudCBpcyBhbiBpbnB1dCB0aGF0IGNhbiBiZSBmb2N1c2VkIGFuZCBlZGl0ZWQgYnkgdGhlIHVzZXIsXG4gICAqIHNvIHdlIGNhbiBza2lwIHBhdGNoaW5nIGl0IGlmIGl0IGhhcyBmb2N1cy5cbiAgICovXG4gIGlzRWRpdGFibGVJbnB1dChlbCkge1xuICAgIHJldHVybiB0aGlzLmlzRm9ybUFzc29jaWF0ZWQoZWwpICYmICEoZWwgaW5zdGFuY2VvZiBIVE1MQnV0dG9uRWxlbWVudCkgJiYgIShlbCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQgJiYgZWwudHlwZSA9PT0gXCJidXR0b25cIik7XG4gIH0sXG4gIGlzRm9ybUFzc29jaWF0ZWQoZWwpIHtcbiAgICBpZiAoIShlbCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgIHJldHVybi
1BmYWxzZTtcbiAgICBpZiAoZWwubG9jYWxOYW1lKSB7XG4gICAgICBjb25zdCBjdXN0b21FbCA9IGN1c3RvbUVsZW1lbnRzLmdldChlbC5sb2NhbE5hbWUpO1xuICAgICAgaWYgKGN1c3RvbUVsKSB7XG4gICAgICAgIHJldHVybiBjdXN0b21FbC5mb3JtQXNzb2NpYXRlZCA9PT0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGVsIGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCB8fCBlbCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50IHx8IGVsIGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudCB8fCBlbCBpbnN0YW5jZW9mIEhUTUxCdXR0b25FbGVtZW50O1xuICB9LFxuICBzeW5jQXR0cnNUb1Byb3BzKGVsKSB7XG4gICAgaWYgKGVsIGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCAmJiBDSEVDS0FCTEVfSU5QVVRTLmluZGV4T2YoZWwudHlwZS50b0xvY2FsZUxvd2VyQ2FzZSgpKSA+PSAwKSB7XG4gICAgICBlbC5jaGVja2VkID0gZWwuZ2V0QXR0cmlidXRlKFwiY2hlY2tlZFwiKSAhPT0gbnVsbDtcbiAgICB9XG4gIH0sXG4gIGlzVGV4dHVhbElucHV0KGVsKSB7XG4gICAgcmV0dXJuIEZPQ1VTQUJMRV9JTlBVVFMuaW5kZXhPZihlbC50eXBlKSA+PSAwO1xuICB9LFxuICBpc05vd1RyaWdnZXJGb3JtRXh0ZXJuYWwoZWwsIHBoeFRyaWdnZXJFeHRlcm5hbCkge1xuICAgIHJldHVybiBlbC5nZXRBdHRyaWJ1dGUgJiYgZWwuZ2V0QXR0cmlidXRlKHBoeFRyaWdnZXJFeHRlcm5hbCkgIT09IG51bGwgJiYgZG9jdW1lbnQuYm9keS5jb250YWlucyhlbCk7XG4gIH0sXG4gIGNsZWFuQ2hpbGROb2Rlcyhjb250YWluZXIsIHBoeFVwZGF0ZSkge1xuICAgIGlmIChET00uaXNQaHhVcGRhdGUoY29udGFpbmVyLCBwaHhVcGRhdGUsIFtcImFwcGVuZFwiLCBcInByZXBlbmRcIiwgUEhYX1NUUkVBTV0pKSB7XG4gICAgICBjb25zdCB0b1JlbW92ZSA9IFtdO1xuICAgICAgY29udGFpbmVyLmNoaWxkTm9kZXMuZm9yRWFjaCgoY2hpbGROb2RlKSA9PiB7XG4gICAgICAgIGlmICghKFwiaWRcIiBpbiBjaGlsZE5vZGUpIHx8ICFjaGlsZE5vZGUuaWQpIHtcbiAgICAgICAgICBjb25zdCBpc0VtcHR5VGV4dE5vZGUgPSBjaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFICYmIGNoaWxkTm9kZS5ub2RlVmFsdWUgJiYgY2hpbGROb2RlLm5vZGVWYWx1ZS50cmltKCkgPT09IFwiXCI7XG4gICAgICAgICAgaWYgKCFpc0VtcHR5VGV4dE5vZGUgJiYgY2hpbGROb2RlLm5vZGVUeXBlICE9PSBOb2RlLkNPTU1FTlRfTk9ERSkge1xuICAgICAgICAgICAgbG9nRXJyb3IoXG4gICAgICAgICAgICAgIGBvbmx5IEhUTUwgZWxlbWVudCB0YWdzIHdpdGggYW4gaWQgYXJlIGFsbG93ZWQgaW5zaWRlIGNvbnRhaW5lcnMgd2l0aCBwaHgtdXBkYXRlLlxuXG5yZW1vdmluZyBpbGxlZ2FsIG5vZGU6IFwiJHsoXCJvdXRlckhUTUxcIiBpbiBjaGlsZE5vZGUgJiYgY2hpbGROb2RlLm91dGVySFRNTCB8fCBjaGlsZE5vZGUubm9kZVZhbHVlIHx8IFwiXCIpLnRyaW0oKX1cIlxuXG5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0b1JlbW92ZS5wdXNoKGNoaWxkTm9kZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdG9SZW1vdmUuZm9yRWFjaCgoY2hpbGROb2RlKSA9PiBjaGlsZE5vZGUucmVtb3ZlKCkpO1xuICAgIH1cbiAgfSxcbiAgcmVwbGFjZVJvb3RDb250YWluZXIoY29udGFpbmVyLCB0YWdOYW1lLCBhdHRycykge1xuICAgIGNvbnN0IHJldGFpbmVkQXR0cnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldChbXG4gICAgICBcImlkXCIsXG4gICAgICBQSFhfU0VTU0lPTixcbiAgICAgIFBIWF9TVEFUSUMsXG4gICAgICBQSFhfTUFJTixcbiAgICAgIFBIWF9ST09UX0lEXG4gICAgXSk7XG4gICAgaWYgKGNvbnRhaW5lci50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09IHRhZ05hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgQXJyYXkuZnJvbShjb250YWluZXIuYXR0cmlidXRlcykuZmlsdGVyKChhdHRyKSA9PiAhcmV0YWluZWRBdHRycy5oYXMoYXR0ci5uYW1lLnRvTG93ZXJDYXNlKCkpKS5mb3JFYWNoKChhdHRyKSA9PiBjb250YWluZXIucmVtb3ZlQXR0cmlidXRlKGF0dHIubmFtZSkpO1xuICAgICAgT2JqZWN0LmtleXMoYXR0cnMpLmZpbHRlcigobmFtZSkgPT4gIXJldGFpbmVkQXR0cnMuaGFzKG5hbWUudG9Mb3dlckNhc2UoKSkpLmZvckVhY2goKGF0dHIpID0+IGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoYXR0ciwgYXR0cnNbYXR0cl0pKTtcbiAgICAgIHJldHVybiBjb250YWluZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG5ld0NvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSk7XG4gICAgICBPYmplY3Qua2V5cyhhdHRycykuZm9yRWFjaChcbiAgICAgICAgKGF0dHIpID0+IG5ld0NvbnRhaW5lci5zZXRBdHRyaWJ1dGUoYXR0ciwgYXR0cnNbYXR0cl0pXG4gICAgICApO1xuICAgICAgcmV0YWluZWRBdHRycy5mb3JFYWNoKChhdHRyKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gY29udGFpbmVyLmdldEF0dHJpYnV0ZShhdHRyKTtcbiAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgICAgbmV3Q29udGFpbmVyLnNldEF0dHJpYnV0ZShhdHRyLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgbmV3Q29udGFpbmVyLmlubmVySFRNTCA9IGNvbnRhaW5lci5pbm5lckhUTUw7XG4gICAgICBjb250YWluZXIucmVwbGFjZVdpdGgobmV3Q29udGFpbmVyKTtcbiAgICAgIHJldHVybiBuZXdDb250YWluZXI7XG4gICAgfVxuICB9LFxuICBnZXRTdGlja3koZWwsIG5hbWUsIGRlZmF1bHRWYWwpIHtcbiAgICBjb25zdCBvcCA9IChET00ucHJpdmF0ZShlbCwgXCJzdGlja3lcIikgfHwgW10pLmZpbmQoXG4gICAgICAoW2V4aXN0aW5nTmFtZV0pID0+IG5hbWUgPT09IGV4aXN0aW5nTmFtZVxuICAgICk7XG4gICAgaWYgKG9wKSB7XG4gICAgICBjb25zdCBbX25hbWUsIF9vcCwgc3Rhc2hlZFJlc3VsdF0gPSBvcDtcbiAgICAgIHJldHVybiBzdGFzaGVkUmVzdWx0O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdHlwZW9mIGRlZmF1bHRWYWwgPT09IFwiZnVuY3Rpb25cIiA/IGRlZmF1bHRWYWwoKSA6IGRlZmF1bHRWYWw7XG4gICAgfVxuICB9LFxuICBkZWxldGVTdGlja3koZWwsIG5hbW
1UpIHtcbiAgICB0aGlzLnVwZGF0ZVByaXZhdGUoZWwsIFwic3RpY2t5XCIsIFtdLCAob3BzKSA9PiB7XG4gICAgICByZXR1cm4gb3BzLmZpbHRlcigoW2V4aXN0aW5nTmFtZSwgX10pID0+IGV4aXN0aW5nTmFtZSAhPT0gbmFtZSk7XG4gICAgfSk7XG4gIH0sXG4gIHB1dFN0aWNreShlbCwgbmFtZSwgb3ApIHtcbiAgICBjb25zdCBzdGFzaGVkUmVzdWx0ID0gb3AoZWwpO1xuICAgIHRoaXMudXBkYXRlUHJpdmF0ZShlbCwgXCJzdGlja3lcIiwgW10sIChvcHMpID0+IHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nSW5kZXggPSBvcHMuZmluZEluZGV4KFxuICAgICAgICAoW2V4aXN0aW5nTmFtZV0pID0+IG5hbWUgPT09IGV4aXN0aW5nTmFtZVxuICAgICAgKTtcbiAgICAgIGlmIChleGlzdGluZ0luZGV4ID49IDApIHtcbiAgICAgICAgb3BzW2V4aXN0aW5nSW5kZXhdID0gW25hbWUsIG9wLCBzdGFzaGVkUmVzdWx0XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9wcy5wdXNoKFtuYW1lLCBvcCwgc3Rhc2hlZFJlc3VsdF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9wcztcbiAgICB9KTtcbiAgfSxcbiAgYXBwbHlTdGlja3lPcGVyYXRpb25zKGVsKSB7XG4gICAgY29uc3Qgb3BzID0gRE9NLnByaXZhdGUoZWwsIFwic3RpY2t5XCIpO1xuICAgIGlmICghb3BzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG9wcy5mb3JFYWNoKChbbmFtZSwgb3AsIF9zdGFzaGVkXSkgPT4gdGhpcy5wdXRTdGlja3koZWwsIG5hbWUsIG9wKSk7XG4gIH0sXG4gIGlzTG9ja2VkKGVsKSB7XG4gICAgcmV0dXJuIGVsLmhhc0F0dHJpYnV0ZSAmJiBlbC5oYXNBdHRyaWJ1dGUoUEhYX1JFRl9MT0NLKTtcbiAgfSxcbiAgYXR0cmlidXRlSWdub3JlZChhdHRyaWJ1dGUsIGlnbm9yZWRBdHRyaWJ1dGVzKSB7XG4gICAgcmV0dXJuIGlnbm9yZWRBdHRyaWJ1dGVzLnNvbWUoXG4gICAgICAodG9JZ25vcmUpID0+IGF0dHJpYnV0ZS5uYW1lID09IHRvSWdub3JlIHx8IHRvSWdub3JlID09PSBcIipcIiB8fCB0b0lnbm9yZS5pbmNsdWRlcyhcIipcIikgJiYgYXR0cmlidXRlLm5hbWUubWF0Y2godG9JZ25vcmUpICE9IG51bGxcbiAgICApO1xuICB9XG59O1xudmFyIGRvbV9kZWZhdWx0ID0gRE9NO1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy91cGxvYWRfZW50cnkuanNcbnZhciBVcGxvYWRFbnRyeSA9IGNsYXNzIHtcbiAgc3RhdGljIGlzQWN0aXZlKGZpbGVFbCwgZmlsZSkge1xuICAgIGNvbnN0IGlzTmV3ID0gZmlsZS5fcGh4UmVmID09PSB2b2lkIDA7XG4gICAgY29uc3QgYWN0aXZlUmVmcyA9IGZpbGVFbC5nZXRBdHRyaWJ1dGUoUEhYX0FDVElWRV9FTlRSWV9SRUZTKS5zcGxpdChcIixcIik7XG4gICAgY29uc3QgaXNBY3RpdmUgPSBhY3RpdmVSZWZzLmluZGV4T2YoTGl2ZVVwbG9hZGVyLmdlbkZpbGVSZWYoZmlsZSkpID49IDA7XG4gICAgcmV0dXJuIGZpbGUuc2l6ZSA+IDAgJiYgKGlzTmV3IHx8IGlzQWN0aXZlKTtcbiAgfVxuICBzdGF0aWMgaXNQcmVmbGlnaHRlZChmaWxlRWwsIGZpbGUpIHtcbiAgICBjb25zdCBwcmVmbGlnaHRlZFJlZnMgPSBmaWxlRWwuZ2V0QXR0cmlidXRlKFBIWF9QUkVGTElHSFRFRF9SRUZTKS5zcGxpdChcIixcIik7XG4gICAgY29uc3QgaXNQcmVmbGlnaHRlZCA9IHByZWZsaWdodGVkUmVmcy5pbmRleE9mKExpdmVVcGxvYWRlci5nZW5GaWxlUmVmKGZpbGUpKSA+PSAwO1xuICAgIHJldHVybiBpc1ByZWZsaWdodGVkICYmIHRoaXMuaXNBY3RpdmUoZmlsZUVsLCBmaWxlKTtcbiAgfVxuICBzdGF0aWMgaXNQcmVmbGlnaHRJblByb2dyZXNzKGZpbGUpIHtcbiAgICByZXR1cm4gZmlsZS5fcHJlZmxpZ2h0SW5Qcm9ncmVzcyA9PT0gdHJ1ZTtcbiAgfVxuICBzdGF0aWMgbWFya1ByZWZsaWdodEluUHJvZ3Jlc3MoZmlsZSkge1xuICAgIGZpbGUuX3ByZWZsaWdodEluUHJvZ3Jlc3MgPSB0cnVlO1xuICB9XG4gIGNvbnN0cnVjdG9yKGZpbGVFbCwgZmlsZSwgdmlldywgYXV0b1VwbG9hZCkge1xuICAgIHRoaXMucmVmID0gTGl2ZVVwbG9hZGVyLmdlbkZpbGVSZWYoZmlsZSk7XG4gICAgdGhpcy5maWxlRWwgPSBmaWxlRWw7XG4gICAgdGhpcy5maWxlID0gZmlsZTtcbiAgICB0aGlzLnZpZXcgPSB2aWV3O1xuICAgIHRoaXMubWV0YSA9IG51bGw7XG4gICAgdGhpcy5faXNDYW5jZWxsZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9pc0RvbmUgPSBmYWxzZTtcbiAgICB0aGlzLl9wcm9ncmVzcyA9IDA7XG4gICAgdGhpcy5fbGFzdFByb2dyZXNzU2VudCA9IC0xO1xuICAgIHRoaXMuX29uRG9uZSA9IGZ1bmN0aW9uKCkge1xuICAgIH07XG4gICAgdGhpcy5fb25FbFVwZGF0ZWQgPSB0aGlzLm9uRWxVcGRhdGVkLmJpbmQodGhpcyk7XG4gICAgdGhpcy5maWxlRWwuYWRkRXZlbnRMaXN0ZW5lcihQSFhfTElWRV9GSUxFX1VQREFURUQsIHRoaXMuX29uRWxVcGRhdGVkKTtcbiAgICB0aGlzLmF1dG9VcGxvYWQgPSBhdXRvVXBsb2FkO1xuICB9XG4gIG1ldGFkYXRhKCkge1xuICAgIHJldHVybiB0aGlzLm1ldGE7XG4gIH1cbiAgcHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICB0aGlzLl9wcm9ncmVzcyA9IE1hdGguZmxvb3IocHJvZ3Jlc3MpO1xuICAgIGlmICh0aGlzLl9wcm9ncmVzcyA+IHRoaXMuX2xhc3RQcm9ncmVzc1NlbnQpIHtcbiAgICAgIGlmICh0aGlzLl9wcm9ncmVzcyA+PSAxMDApIHtcbiAgICAgICAgdGhpcy5fcHJvZ3Jlc3MgPSAxMDA7XG4gICAgICAgIHRoaXMuX2xhc3RQcm9ncmVzc1NlbnQgPSAxMDA7XG4gICAgICAgIHRoaXMuX2lzRG9uZSA9IHRydWU7XG4gICAgICAgIHRoaXMudmlldy5wdXNoRmlsZVByb2dyZXNzKHRoaXMuZmlsZUVsLCB0aGlzLnJlZiwgMTAwLCAoKSA9PiB7XG4gICAgICAgICAgTGl2ZVVwbG9hZGVyLnVudHJhY2tGaWxlKHRoaXMuZmlsZUVsLCB0aGlzLmZpbGUpO1xuICAgICAgICAgIHRoaXMuX29uRG9uZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2xhc3RQcm9ncmVzc1NlbnQgPSB0aGlzLl9wcm9ncmVzcztcbiAgICAgICAgdGhpcy52aWV3LnB1c2hGaWxlUHJvZ3Jlc3ModGhpcy5maWxlRWwsIHRoaXMucmVmLCB0aGlzLl9wcm9ncmVzcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlzQ2FuY2VsbGVkKCkge1xuICAgIHJldHVybi
1B0aGlzLl9pc0NhbmNlbGxlZDtcbiAgfVxuICBjYW5jZWwoKSB7XG4gICAgdGhpcy5maWxlLl9wcmVmbGlnaHRJblByb2dyZXNzID0gZmFsc2U7XG4gICAgdGhpcy5faXNDYW5jZWxsZWQgPSB0cnVlO1xuICAgIHRoaXMuX2lzRG9uZSA9IHRydWU7XG4gICAgdGhpcy5fb25Eb25lKCk7XG4gIH1cbiAgaXNEb25lKCkge1xuICAgIHJldHVybiB0aGlzLl9pc0RvbmU7XG4gIH1cbiAgZXJyb3IocmVhc29uID0gXCJmYWlsZWRcIikge1xuICAgIHRoaXMuZmlsZUVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoUEhYX0xJVkVfRklMRV9VUERBVEVELCB0aGlzLl9vbkVsVXBkYXRlZCk7XG4gICAgdGhpcy52aWV3LnB1c2hGaWxlUHJvZ3Jlc3ModGhpcy5maWxlRWwsIHRoaXMucmVmLCB7IGVycm9yOiByZWFzb24gfSk7XG4gICAgaWYgKCF0aGlzLmlzQXV0b1VwbG9hZCgpKSB7XG4gICAgICBMaXZlVXBsb2FkZXIuY2xlYXJGaWxlcyh0aGlzLmZpbGVFbCk7XG4gICAgfVxuICB9XG4gIGlzQXV0b1VwbG9hZCgpIHtcbiAgICByZXR1cm4gdGhpcy5hdXRvVXBsb2FkO1xuICB9XG4gIC8vcHJpdmF0ZVxuICBvbkRvbmUoY2FsbGJhY2spIHtcbiAgICB0aGlzLl9vbkRvbmUgPSAoKSA9PiB7XG4gICAgICB0aGlzLmZpbGVFbC5yZW1vdmVFdmVudExpc3RlbmVyKFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCwgdGhpcy5fb25FbFVwZGF0ZWQpO1xuICAgICAgY2FsbGJhY2soKTtcbiAgICB9O1xuICB9XG4gIG9uRWxVcGRhdGVkKCkge1xuICAgIGNvbnN0IGFjdGl2ZVJlZnMgPSB0aGlzLmZpbGVFbC5nZXRBdHRyaWJ1dGUoUEhYX0FDVElWRV9FTlRSWV9SRUZTKS5zcGxpdChcIixcIik7XG4gICAgaWYgKGFjdGl2ZVJlZnMuaW5kZXhPZih0aGlzLnJlZikgPT09IC0xKSB7XG4gICAgICBMaXZlVXBsb2FkZXIudW50cmFja0ZpbGUodGhpcy5maWxlRWwsIHRoaXMuZmlsZSk7XG4gICAgICB0aGlzLmNhbmNlbCgpO1xuICAgIH1cbiAgfVxuICB0b1ByZWZsaWdodFBheWxvYWQoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxhc3RfbW9kaWZpZWQ6IHRoaXMuZmlsZS5sYXN0TW9kaWZpZWQsXG4gICAgICBuYW1lOiB0aGlzLmZpbGUubmFtZSxcbiAgICAgIHJlbGF0aXZlX3BhdGg6IHRoaXMuZmlsZS53ZWJraXRSZWxhdGl2ZVBhdGgsXG4gICAgICBzaXplOiB0aGlzLmZpbGUuc2l6ZSxcbiAgICAgIHR5cGU6IHRoaXMuZmlsZS50eXBlLFxuICAgICAgcmVmOiB0aGlzLnJlZixcbiAgICAgIG1ldGE6IHR5cGVvZiB0aGlzLmZpbGUubWV0YSA9PT0gXCJmdW5jdGlvblwiID8gdGhpcy5maWxlLm1ldGEoKSA6IHZvaWQgMFxuICAgIH07XG4gIH1cbiAgdXBsb2FkZXIodXBsb2FkZXJzKSB7XG4gICAgaWYgKHRoaXMubWV0YS51cGxvYWRlcikge1xuICAgICAgY29uc3QgY2FsbGJhY2sgPSB1cGxvYWRlcnNbdGhpcy5tZXRhLnVwbG9hZGVyXSB8fCBsb2dFcnJvcihgbm8gdXBsb2FkZXIgY29uZmlndXJlZCBmb3IgJHt0aGlzLm1ldGEudXBsb2FkZXJ9YCk7XG4gICAgICByZXR1cm4geyBuYW1lOiB0aGlzLm1ldGEudXBsb2FkZXIsIGNhbGxiYWNrIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB7IG5hbWU6IFwiY2hhbm5lbFwiLCBjYWxsYmFjazogY2hhbm5lbFVwbG9hZGVyIH07XG4gICAgfVxuICB9XG4gIHppcFBvc3RGbGlnaHQocmVzcCkge1xuICAgIHRoaXMubWV0YSA9IHJlc3AuZW50cmllc1t0aGlzLnJlZl07XG4gICAgaWYgKCF0aGlzLm1ldGEpIHtcbiAgICAgIGxvZ0Vycm9yKGBubyBwcmVmbGlnaHQgdXBsb2FkIHJlc3BvbnNlIHJldHVybmVkIHdpdGggcmVmICR7dGhpcy5yZWZ9YCwge1xuICAgICAgICBpbnB1dDogdGhpcy5maWxlRWwsXG4gICAgICAgIHJlc3BvbnNlOiByZXNwXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn07XG5cbi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L2xpdmVfdXBsb2FkZXIuanNcbnZhciBsaXZlVXBsb2FkZXJGaWxlUmVmID0gMDtcbnZhciBMaXZlVXBsb2FkZXIgPSBjbGFzcyBfTGl2ZVVwbG9hZGVyIHtcbiAgc3RhdGljIGdlbkZpbGVSZWYoZmlsZSkge1xuICAgIGNvbnN0IHJlZiA9IGZpbGUuX3BoeFJlZjtcbiAgICBpZiAocmVmICE9PSB2b2lkIDApIHtcbiAgICAgIHJldHVybiByZWY7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZpbGUuX3BoeFJlZiA9IChsaXZlVXBsb2FkZXJGaWxlUmVmKyspLnRvU3RyaW5nKCk7XG4gICAgICByZXR1cm4gZmlsZS5fcGh4UmVmO1xuICAgIH1cbiAgfVxuICBzdGF0aWMgZ2V0RW50cnlEYXRhVVJMKGlucHV0RWwsIHJlZikge1xuICAgIGNvbnN0IGZpbGUgPSB0aGlzLmFjdGl2ZUZpbGVzKGlucHV0RWwpLmZpbmQoXG4gICAgICAoZmlsZTIpID0+IHRoaXMuZ2VuRmlsZVJlZihmaWxlMikgPT09IHJlZlxuICAgICk7XG4gICAgaWYgKCFmaWxlKVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIFVSTC5jcmVhdGVPYmplY3RVUkwoZmlsZSk7XG4gIH1cbiAgc3RhdGljIGhhc1VwbG9hZHNJblByb2dyZXNzKGZvcm1FbCkge1xuICAgIGxldCBhY3RpdmUgPSAwO1xuICAgIGRvbV9kZWZhdWx0LmZpbmRVcGxvYWRJbnB1dHMoZm9ybUVsKS5mb3JFYWNoKChpbnB1dCkgPT4ge1xuICAgICAgaWYgKGlucHV0LmdldEF0dHJpYnV0ZShQSFhfUFJFRkxJR0hURURfUkVGUykgIT09IGlucHV0LmdldEF0dHJpYnV0ZShQSFhfRE9ORV9SRUZTKSkge1xuICAgICAgICBhY3RpdmUrKztcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gYWN0aXZlID4gMDtcbiAgfVxuICBzdGF0aWMgc2VyaWFsaXplVXBsb2FkcyhpbnB1dEVsKSB7XG4gICAgY29uc3QgZmlsZXMgPSB0aGlzLmFjdGl2ZUZpbGVzKGlucHV0RWwpO1xuICAgIGNvbnN0IGZpbGVEYXRhID0ge307XG4gICAgZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xuICAgICAgY29uc3QgZW50cnkgPSB7IHBhdGg6IGlucHV0RWwubmFtZSB9O1xuICAgICAgY29uc3QgdXBsb2FkUmVmID0gaW5wdXRFbC5nZXRBdHRyaWJ1dGUoUEhYX1VQTE9BRF9SRUYpO1xuICAgICAgZmlsZURhdGFbdXBsb2FkUmVmXSA9IGZpbGVEYXRhW3VwbG9hZFJlZl0gfHwgW107XG4gICAgICBlbnRyeS5yZWYgPSB0aGlzLmdlbkZpbGVSZWYoZmlsZSk7XG4gICAgICBlbnRyeS5sYXN0X21vZGlmaWVkID0gZmlsZS5sYXN0TW9kaWZpZWQ7XG4gICAgICBlbnRyeS5uYW1lID0gZmlsZS5uYW1lIHx8IGVudHJ5LnJlZjtcbiAgICAgIGVudHJ5LnJlbGF0aXZlX3BhdGggPSBmaWxlLndlYmtpdFJlbGF0aXZlUGF0aDtcbiAgICAgIGVudHJ5LnR5cGUgPSBmaWxlLnR5cGU7XG4gICAgICBlbnRyeS5zaXplID0gZmlsZS5zaXplO1xuICAgICAgaWYgKHR5cGVvZiBmaWxlLm1ldGEgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBlbnRyeS5tZXRhID0gZmlsZS5tZXRhKCk7XG4gICAgICB9XG4gICAgICBmaWxlRGF0YVt1cGxvYWRSZWZdLnB1c2goZW50cnkpO1xuICAgIH0pO1xuICAgIHJldHVybi
1BmaWxlRGF0YTtcbiAgfVxuICBzdGF0aWMgY2xlYXJGaWxlcyhpbnB1dEVsKSB7XG4gICAgaW5wdXRFbC52YWx1ZSA9IG51bGw7XG4gICAgaW5wdXRFbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1VQTE9BRF9SRUYpO1xuICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUoaW5wdXRFbCwgXCJmaWxlc1wiLCBbXSk7XG4gIH1cbiAgc3RhdGljIHVudHJhY2tGaWxlKGlucHV0RWwsIGZpbGUpIHtcbiAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKFxuICAgICAgaW5wdXRFbCxcbiAgICAgIFwiZmlsZXNcIixcbiAgICAgIGRvbV9kZWZhdWx0LnByaXZhdGUoaW5wdXRFbCwgXCJmaWxlc1wiKS5maWx0ZXIoKGYpID0+ICFPYmplY3QuaXMoZiwgZmlsZSkpXG4gICAgKTtcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MSW5wdXRFbGVtZW50fSBpbnB1dEVsXG4gICAqIEBwYXJhbSB7QXJyYXk8RmlsZXxCbG9iPn0gZmlsZXNcbiAgICogQHBhcmFtIHtEYXRhVHJhbnNmZXJ9IFtkYXRhVHJhbnNmZXJdXG4gICAqL1xuICBzdGF0aWMgdHJhY2tGaWxlcyhpbnB1dEVsLCBmaWxlcywgZGF0YVRyYW5zZmVyKSB7XG4gICAgaWYgKGlucHV0RWwuZ2V0QXR0cmlidXRlKFwibXVsdGlwbGVcIikgIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IG5ld0ZpbGVzID0gZmlsZXMuZmlsdGVyKFxuICAgICAgICAoZmlsZSkgPT4gIXRoaXMuYWN0aXZlRmlsZXMoaW5wdXRFbCkuZmluZCgoZikgPT4gT2JqZWN0LmlzKGYsIGZpbGUpKVxuICAgICAgKTtcbiAgICAgIGRvbV9kZWZhdWx0LnVwZGF0ZVByaXZhdGUoXG4gICAgICAgIGlucHV0RWwsXG4gICAgICAgIFwiZmlsZXNcIixcbiAgICAgICAgW10sXG4gICAgICAgIChleGlzdGluZykgPT4gZXhpc3RpbmcuY29uY2F0KG5ld0ZpbGVzKVxuICAgICAgKTtcbiAgICAgIGlucHV0RWwudmFsdWUgPSBcIlwiO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoZGF0YVRyYW5zZmVyICYmIGRhdGFUcmFuc2Zlci5maWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGlucHV0RWwuZmlsZXMgPSBkYXRhVHJhbnNmZXIuZmlsZXM7XG4gICAgICB9XG4gICAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKGlucHV0RWwsIFwiZmlsZXNcIiwgZmlsZXMpO1xuICAgIH1cbiAgfVxuICBzdGF0aWMgYWN0aXZlRmlsZUlucHV0cyhmb3JtRWwpIHtcbiAgICBjb25zdCBmaWxlSW5wdXRzID0gZG9tX2RlZmF1bHQuZmluZFVwbG9hZElucHV0cyhmb3JtRWwpO1xuICAgIHJldHVybiBBcnJheS5mcm9tKGZpbGVJbnB1dHMpLmZpbHRlcihcbiAgICAgIChlbCkgPT4gZWwuZmlsZXMgJiYgdGhpcy5hY3RpdmVGaWxlcyhlbCkubGVuZ3RoID4gMFxuICAgICk7XG4gIH1cbiAgc3RhdGljIGFjdGl2ZUZpbGVzKGlucHV0KSB7XG4gICAgcmV0dXJuIChkb21fZGVmYXVsdC5wcml2YXRlKGlucHV0LCBcImZpbGVzXCIpIHx8IFtdKS5maWx0ZXIoXG4gICAgICAoZikgPT4gVXBsb2FkRW50cnkuaXNBY3RpdmUoaW5wdXQsIGYpXG4gICAgKTtcbiAgfVxuICBzdGF0aWMgaW5wdXRzQXdhaXRpbmdQcmVmbGlnaHQoZm9ybUVsKSB7XG4gICAgY29uc3QgZmlsZUlucHV0cyA9IGRvbV9kZWZhdWx0LmZpbmRVcGxvYWRJbnB1dHMoZm9ybUVsKTtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShmaWxlSW5wdXRzKS5maWx0ZXIoXG4gICAgICAoaW5wdXQpID0+IHRoaXMuZmlsZXNBd2FpdGluZ1ByZWZsaWdodChpbnB1dCkubGVuZ3RoID4gMFxuICAgICk7XG4gIH1cbiAgc3RhdGljIGZpbGVzQXdhaXRpbmdQcmVmbGlnaHQoaW5wdXQpIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmVGaWxlcyhpbnB1dCkuZmlsdGVyKFxuICAgICAgKGYpID0+ICFVcGxvYWRFbnRyeS5pc1ByZWZsaWdodGVkKGlucHV0LCBmKSAmJiAhVXBsb2FkRW50cnkuaXNQcmVmbGlnaHRJblByb2dyZXNzKGYpXG4gICAgKTtcbiAgfVxuICBzdGF0aWMgbWFya1ByZWZsaWdodEluUHJvZ3Jlc3MoZW50cmllcykge1xuICAgIGVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IFVwbG9hZEVudHJ5Lm1hcmtQcmVmbGlnaHRJblByb2dyZXNzKGVudHJ5LmZpbGUpKTtcbiAgfVxuICBjb25zdHJ1Y3RvcihpbnB1dEVsLCB2aWV3LCBvbkNvbXBsZXRlKSB7XG4gICAgdGhpcy5hdXRvVXBsb2FkID0gZG9tX2RlZmF1bHQuaXNBdXRvVXBsb2FkKGlucHV0RWwpO1xuICAgIHRoaXMudmlldyA9IHZpZXc7XG4gICAgdGhpcy5vbkNvbXBsZXRlID0gb25Db21wbGV0ZTtcbiAgICB0aGlzLl9lbnRyaWVzID0gQXJyYXkuZnJvbShcbiAgICAgIF9MaXZlVXBsb2FkZXIuZmlsZXNBd2FpdGluZ1ByZWZsaWdodChpbnB1dEVsKSB8fCBbXVxuICAgICkubWFwKChmaWxlKSA9PiBuZXcgVXBsb2FkRW50cnkoaW5wdXRFbCwgZmlsZSwgdmlldywgdGhpcy5hdXRvVXBsb2FkKSk7XG4gICAgX0xpdmVVcGxvYWRlci5tYXJrUHJlZmxpZ2h0SW5Qcm9ncmVzcyh0aGlzLl9lbnRyaWVzKTtcbiAgICB0aGlzLm51bUVudHJpZXNJblByb2dyZXNzID0gdGhpcy5fZW50cmllcy5sZW5ndGg7XG4gIH1cbiAgaXNBdXRvVXBsb2FkKCkge1xuICAgIHJldHVybiB0aGlzLmF1dG9VcGxvYWQ7XG4gIH1cbiAgZW50cmllcygpIHtcbiAgICByZXR1cm4gdGhpcy5fZW50cmllcztcbiAgfVxuICBpbml0QWRhcHRlclVwbG9hZChyZXNwLCBvbkVycm9yLCBsaXZlU29ja2V0KSB7XG4gICAgdGhpcy5fZW50cmllcyA9IHRoaXMuX2VudHJpZXMubWFwKChlbnRyeSkgPT4ge1xuICAgICAgaWYgKGVudHJ5LmlzQ2FuY2VsbGVkKCkpIHtcbiAgICAgICAgdGhpcy5udW1FbnRyaWVzSW5Qcm9ncmVzcy0tO1xuICAgICAgICBpZiAodGhpcy5udW1FbnRyaWVzSW5Qcm9ncmVzcyA9PT0gMCkge1xuICAgICAgICAgIHRoaXMub25Db21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbnRyeS56aXBQb3N0RmxpZ2h0KHJlc3ApO1xuICAgICAgICBlbnRyeS5vbkRvbmUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMubnVtRW50cmllc0luUHJvZ3Jlc3MtLTtcbiAgICAgICAgICBpZiAodGhpcy5udW1FbnRyaWVzSW5Qcm9ncmVzcyA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5vbkNvbXBsZXRlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybi
1BlbnRyeTtcbiAgICB9KTtcbiAgICBjb25zdCBncm91cGVkRW50cmllcyA9IHRoaXMuX2VudHJpZXMucmVkdWNlKChhY2MsIGVudHJ5KSA9PiB7XG4gICAgICBpZiAoIWVudHJ5Lm1ldGEpIHtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgbmFtZSwgY2FsbGJhY2sgfSA9IGVudHJ5LnVwbG9hZGVyKGxpdmVTb2NrZXQudXBsb2FkZXJzKTtcbiAgICAgIGFjY1tuYW1lXSA9IGFjY1tuYW1lXSB8fCB7IGNhbGxiYWNrLCBlbnRyaWVzOiBbXSB9O1xuICAgICAgYWNjW25hbWVdLmVudHJpZXMucHVzaChlbnRyeSk7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9KTtcbiAgICBmb3IgKGNvbnN0IG5hbWUgaW4gZ3JvdXBlZEVudHJpZXMpIHtcbiAgICAgIGNvbnN0IHsgY2FsbGJhY2ssIGVudHJpZXMgfSA9IGdyb3VwZWRFbnRyaWVzW25hbWVdO1xuICAgICAgY2FsbGJhY2soZW50cmllcywgb25FcnJvciwgcmVzcCwgbGl2ZVNvY2tldCk7XG4gICAgfVxuICB9XG59O1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy9hcmlhLnRzXG52YXIgQVJJQSA9IHtcbiAgYW55T2YoaW5zdGFuY2UsIGNsYXNzZXMpIHtcbiAgICByZXR1cm4gY2xhc3Nlcy5zb21lKChuYW1lKSA9PiBpbnN0YW5jZSBpbnN0YW5jZW9mIG5hbWUpO1xuICB9LFxuICBpc0ZvY3VzYWJsZShlbCwgaW50ZXJhY3RpdmVPbmx5ID0gZmFsc2UpIHtcbiAgICByZXR1cm4gZWwgaW5zdGFuY2VvZiBIVE1MQW5jaG9yRWxlbWVudCAmJiBlbC5yZWwgIT09IFwiaWdub3JlXCIgfHwgZWwgaW5zdGFuY2VvZiBIVE1MQXJlYUVsZW1lbnQgJiYgZWwuaHJlZiAhPT0gdm9pZCAwIHx8ICEoXCJkaXNhYmxlZFwiIGluIGVsICYmIGVsLmRpc2FibGVkKSAmJiB0aGlzLmFueU9mKGVsLCBbXG4gICAgICBIVE1MSW5wdXRFbGVtZW50LFxuICAgICAgSFRNTFNlbGVjdEVsZW1lbnQsXG4gICAgICBIVE1MVGV4dEFyZWFFbGVtZW50LFxuICAgICAgSFRNTEJ1dHRvbkVsZW1lbnRcbiAgICBdKSB8fCBlbCBpbnN0YW5jZW9mIEhUTUxJRnJhbWVFbGVtZW50IHx8IGVsIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgJiYgZWwudGFiSW5kZXggPj0gMCAmJiBlbC5nZXRBdHRyaWJ1dGUoXCJhcmlhLWhpZGRlblwiKSAhPT0gXCJ0cnVlXCIgfHwgIWludGVyYWN0aXZlT25seSAmJiBlbC5nZXRBdHRyaWJ1dGUoXCJ0YWJpbmRleFwiKSAhPT0gbnVsbCAmJiBlbC5nZXRBdHRyaWJ1dGUoXCJhcmlhLWhpZGRlblwiKSAhPT0gXCJ0cnVlXCI7XG4gIH0sXG4gIGF0dGVtcHRGb2N1cyhlbCwgaW50ZXJhY3RpdmVPbmx5ID0gZmFsc2UpIHtcbiAgICBpZiAodGhpcy5pc0ZvY3VzYWJsZShlbCwgaW50ZXJhY3RpdmVPbmx5KSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZWwuZm9jdXMoKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gISFkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQuaXNTYW1lTm9kZShlbCk7XG4gIH0sXG4gIGZvY3VzRmlyc3RJbnRlcmFjdGl2ZShlbCkge1xuICAgIGxldCBjaGlsZCA9IGVsLmZpcnN0RWxlbWVudENoaWxkO1xuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgaWYgKHRoaXMuYXR0ZW1wdEZvY3VzKGNoaWxkLCB0cnVlKSB8fCB0aGlzLmZvY3VzRmlyc3RJbnRlcmFjdGl2ZShjaGlsZCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBjaGlsZCA9IGNoaWxkLm5leHRFbGVtZW50U2libGluZztcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9LFxuICBmb2N1c0ZpcnN0KGVsKSB7XG4gICAgbGV0IGNoaWxkID0gZWwuZmlyc3RFbGVtZW50Q2hpbGQ7XG4gICAgd2hpbGUgKGNoaWxkKSB7XG4gICAgICBpZiAodGhpcy5hdHRlbXB0Rm9jdXMoY2hpbGQpIHx8IHRoaXMuZm9jdXNGaXJzdChjaGlsZCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBjaGlsZCA9IGNoaWxkLm5leHRFbGVtZW50U2libGluZztcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9LFxuICBmb2N1c0xhc3QoZWwpIHtcbiAgICBsZXQgY2hpbGQgPSBlbC5sYXN0RWxlbWVudENoaWxkO1xuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgaWYgKHRoaXMuYXR0ZW1wdEZvY3VzKGNoaWxkKSB8fCB0aGlzLmZvY3VzTGFzdChjaGlsZCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBjaGlsZCA9IGNoaWxkLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcbnZhciBhcmlhX2RlZmF1bHQgPSBBUklBO1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy9ob29rcy50c1xudmFyIGZpbmRTY3JvbGxDb250YWluZXIgPSAoZWwpID0+IHtcbiAgaWYgKFtcIkhUTUxcIiwgXCJCT0RZXCJdLmluZGV4T2YoZWwubm9kZU5hbWUudG9VcHBlckNhc2UoKSkgPj0gMClcbiAgICByZXR1cm4gbnVsbDtcbiAgaWYgKFtcInNjcm9sbFwiLCBcImF1dG9cIl0uaW5kZXhPZihnZXRDb21wdXRlZFN0eWxlKGVsKS5vdmVyZmxvd1kpID49IDApXG4gICAgcmV0dXJuIGVsO1xuICByZXR1cm4gZmluZFNjcm9sbENvbnRhaW5lcihlbC5wYXJlbnRFbGVtZW50KTtcbn07XG52YXIgc2Nyb2xsVG9wID0gKHNjcm9sbENvbnRhaW5lcikgPT4ge1xuICBpZiAoc2Nyb2xsQ29udGFpbmVyKSB7XG4gICAgcmV0dXJuIHNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3A7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxUb3A7XG4gIH1cbn07XG52YXIgYm90dG9tID0gKHNjcm9sbENvbnRhaW5lcikgPT4ge1xuICBpZiAoc2Nyb2xsQ29udGFpbmVyKSB7XG4gICAgcmV0dXJuIHNjcm9sbENvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5ib3R0b207XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHdpbmRvdy5pbm5lckhlaWdodCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0O1xuICB9XG59O1xudmFyIHRvcCA9IChzY3JvbGxDb250YWluZXIpID0+IHtcbiAgaWYgKHNjcm9sbENvbnRhaW5lcikge1xuICAgIHJldHVybi
1BzY3JvbGxDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAwO1xuICB9XG59O1xudmFyIGlzQXRWaWV3cG9ydFRvcCA9IChlbCwgc2Nyb2xsQ29udGFpbmVyKSA9PiB7XG4gIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgcmV0dXJuIE1hdGguY2VpbChyZWN0LnRvcCkgPj0gdG9wKHNjcm9sbENvbnRhaW5lcikgJiYgTWF0aC5mbG9vcihyZWN0LnRvcCkgPD0gYm90dG9tKHNjcm9sbENvbnRhaW5lcik7XG59O1xudmFyIGlzQXRWaWV3cG9ydEJvdHRvbSA9IChlbCwgc2Nyb2xsQ29udGFpbmVyKSA9PiB7XG4gIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgcmV0dXJuIE1hdGguY2VpbChyZWN0LmJvdHRvbSkgPj0gdG9wKHNjcm9sbENvbnRhaW5lcikgJiYgTWF0aC5mbG9vcihyZWN0LmJvdHRvbSkgPD0gYm90dG9tKHNjcm9sbENvbnRhaW5lcik7XG59O1xudmFyIGlzV2l0aGluVmlld3BvcnQgPSAoZWwsIHNjcm9sbENvbnRhaW5lcikgPT4ge1xuICBjb25zdCByZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIHJldHVybiBNYXRoLmNlaWwocmVjdC50b3ApID49IHRvcChzY3JvbGxDb250YWluZXIpICYmIE1hdGguZmxvb3IocmVjdC50b3ApIDw9IGJvdHRvbShzY3JvbGxDb250YWluZXIpO1xufTtcbnZhciBJbmZpbml0ZVNjcm9sbCA9IHtcbiAgbW91bnRlZCgpIHtcbiAgICB0aGlzLnNjcm9sbENvbnRhaW5lciA9IGZpbmRTY3JvbGxDb250YWluZXIodGhpcy5lbCk7XG4gICAgbGV0IHNjcm9sbEJlZm9yZSA9IHNjcm9sbFRvcCh0aGlzLnNjcm9sbENvbnRhaW5lcik7XG4gICAgbGV0IHRvcE92ZXJyYW4gPSBmYWxzZTtcbiAgICBjb25zdCB0aHJvdHRsZUludGVydmFsID0gNTAwO1xuICAgIGxldCBwZW5kaW5nT3AgPSBudWxsO1xuICAgIGNvbnN0IG9uVG9wT3ZlcnJ1biA9IHRoaXMudGhyb3R0bGUoXG4gICAgICB0aHJvdHRsZUludGVydmFsLFxuICAgICAgKHRvcEV2ZW50LCBmaXJzdENoaWxkKSA9PiB7XG4gICAgICAgIHBlbmRpbmdPcCA9ICgpID0+IHRydWU7XG4gICAgICAgIHRoaXMubGl2ZVNvY2tldC5qcygpLnB1c2godGhpcy5lbCwgdG9wRXZlbnQsIHtcbiAgICAgICAgICB2YWx1ZTogeyBpZDogZmlyc3RDaGlsZC5pZCwgX292ZXJyYW46IHRydWUgfSxcbiAgICAgICAgICBjYWxsYmFjazogKCkgPT4ge1xuICAgICAgICAgICAgcGVuZGluZ09wID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICk7XG4gICAgY29uc3Qgb25GaXJzdENoaWxkQXRUb3AgPSB0aGlzLnRocm90dGxlKFxuICAgICAgdGhyb3R0bGVJbnRlcnZhbCxcbiAgICAgICh0b3BFdmVudCwgZmlyc3RDaGlsZCkgPT4ge1xuICAgICAgICBwZW5kaW5nT3AgPSAoKSA9PiBmaXJzdENoaWxkLnNjcm9sbEludG9WaWV3KHsgYmxvY2s6IFwic3RhcnRcIiB9KTtcbiAgICAgICAgdGhpcy5saXZlU29ja2V0LmpzKCkucHVzaCh0aGlzLmVsLCB0b3BFdmVudCwge1xuICAgICAgICAgIHZhbHVlOiB7IGlkOiBmaXJzdENoaWxkLmlkIH0sXG4gICAgICAgICAgY2FsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgICAgIHBlbmRpbmdPcCA9IG51bGw7XG4gICAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFpc1dpdGhpblZpZXdwb3J0KGZpcnN0Q2hpbGQsIHRoaXMuc2Nyb2xsQ29udGFpbmVyKSkge1xuICAgICAgICAgICAgICAgIGZpcnN0Q2hpbGQuc2Nyb2xsSW50b1ZpZXcoeyBibG9jazogXCJzdGFydFwiIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICk7XG4gICAgY29uc3Qgb25MYXN0Q2hpbGRBdEJvdHRvbSA9IHRoaXMudGhyb3R0bGUoXG4gICAgICB0aHJvdHRsZUludGVydmFsLFxuICAgICAgKGJvdHRvbUV2ZW50LCBsYXN0Q2hpbGQpID0+IHtcbiAgICAgICAgcGVuZGluZ09wID0gKCkgPT4gbGFzdENoaWxkLnNjcm9sbEludG9WaWV3KHsgYmxvY2s6IFwiZW5kXCIgfSk7XG4gICAgICAgIHRoaXMubGl2ZVNvY2tldC5qcygpLnB1c2godGhpcy5lbCwgYm90dG9tRXZlbnQsIHtcbiAgICAgICAgICB2YWx1ZTogeyBpZDogbGFzdENoaWxkLmlkIH0sXG4gICAgICAgICAgY2FsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgICAgIHBlbmRpbmdPcCA9IG51bGw7XG4gICAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFpc1dpdGhpblZpZXdwb3J0KGxhc3RDaGlsZCwgdGhpcy5zY3JvbGxDb250YWluZXIpKSB7XG4gICAgICAgICAgICAgICAgbGFzdENoaWxkLnNjcm9sbEludG9WaWV3KHsgYmxvY2s6IFwiZW5kXCIgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLm9uU2Nyb2xsID0gKF9lKSA9PiB7XG4gICAgICBjb25zdCBzY3JvbGxOb3cgPSBzY3JvbGxUb3AodGhpcy5zY3JvbGxDb250YWluZXIpO1xuICAgICAgaWYgKHBlbmRpbmdPcCkge1xuICAgICAgICBzY3JvbGxCZWZvcmUgPSBzY3JvbGxOb3c7XG4gICAgICAgIHJldHVybiBwZW5kaW5nT3AoKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlY3QgPSB0aGlzLmZpbmRPdmVycnVuVGFyZ2V0KCk7XG4gICAgICBjb25zdCB0b3BFdmVudCA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKFxuICAgICAgICB0aGlzLmxpdmVTb2NrZXQuYmluZGluZyhcInZpZXdwb3J0LXRvcFwiKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGJvdHRvbUV2ZW50ID0gdGhpcy5lbC5nZXRBdHRyaWJ1dGUoXG4gICAgICAgIHRoaXMubGl2ZVNvY2tldC5iaW5kaW5nKFwidmlld3BvcnQtYm90dG9tXCIpXG4gICAgICApO1xuICAgICAgY29uc3QgbGFzdENoaWxkID0gdGhpcy5lbC5sYXN0RWxlbWVudENoaWxkO1xuICAgICAgY29uc3QgZmlyc3RDaGlsZCA9IHRoaXMuZWwuZmlyc3RFbGVtZW50Q2hpbGQ7XG4gICAgICBjb25zdCBpc1Njcm9sbGluZ1VwID0gc2Nyb2xsTm93IDwgc2Nyb2xsQmVmb3JlO1xuICAgICAgY29uc3QgaXNTY3JvbGxpbmdEb3duID0gc2Nyb2xsTm93ID4gc2Nyb2xsQmVmb3JlO1xuICAgICAgaWYgKGlzU2Nyb2xsaW5nVXAgJiYgdG9wRXZlbnQgJiYgIXRvcE92ZXJyYW4gJiYgcmVjdC50b3AgPj0gMCkge1xuICAgICAgICB0b3BPdmVycmFuID0gdHJ1ZTtcbiAgICAgICAgb25Ub3BPdmVycnVuKHRvcEV2ZW50LCBmaXJzdENoaWxkKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNTY3JvbGxpbmdEb3duICYmIHRvcE92ZXJyYW4gJiYgcmVjdC50b3AgPD0gMCkge1xuICAgICAgICB0b3BPdmVycmFuID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAodG9wRXZlbnQgJiYgaXNTY3JvbGxpbmdVcCAmJiBmaXJzdENoaWxkICYmIGlzQXRWaWV3cG9ydFRvcChmaXJzdENoaWxkLCB0aGlzLnNjcm9sbENvbnRhaW5lcikpIHtcbiAgICAgICAgb25GaXJzdENoaWxkQXRUb3AodG9wRXZlbnQsIGZpcnN0Q2hpbGQpO1xuICAgICAgfSBlbHNlIGlmIChib3R0b21FdmVudCAmJiBpc1Njcm9sbGluZ0Rvd24gJiYgbGFzdENoaWxkICYmIGlzQXRWaWV3cG9ydEJvdHRvbShsYXN0Q2hpbGQsIHRoaXMuc2Nyb2xsQ29udGFpbmVyKSkge1xuICAgICAgICBvbkxhc3RDaGlsZEF0Qm90dG9tKGJvdHRvbUV2ZW50LCBsYXN0Q2hpbGQpO1xuICAgICAgfVxuICAgICAgc2Nyb2xsQmVmb3JlID0gc2Nyb2xsTm93O1xuICAgIH07XG4gICAgaWYgKHRoaXMuc2Nyb2xsQ29udGFpbmVyKSB7XG4gICAgICB0aGlzLnNjcm9sbENvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHRoaXMub25TY3JvbGwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCB0aGlzLm9uU2Nyb2xsKTtcbiAgICB9XG4gI
1H0sXG4gIHVwZGF0ZWQoKSB7XG4gICAgaWYgKHRoaXMuc2Nyb2xsQ29udGFpbmVyICYmICF0aGlzLnNjcm9sbENvbnRhaW5lci5pc0Nvbm5lY3RlZCkge1xuICAgICAgdGhpcy5kZXN0cm95ZWQoKTtcbiAgICAgIHRoaXMubW91bnRlZCgpO1xuICAgIH1cbiAgfSxcbiAgZGVzdHJveWVkKCkge1xuICAgIGlmICh0aGlzLnNjcm9sbENvbnRhaW5lcikge1xuICAgICAgdGhpcy5zY3JvbGxDb250YWluZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCB0aGlzLm9uU2Nyb2xsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgdGhpcy5vblNjcm9sbCk7XG4gICAgfVxuICB9LFxuICB0aHJvdHRsZShpbnRlcnZhbCwgY2FsbGJhY2spIHtcbiAgICBsZXQgbGFzdENhbGxBdCA9IDA7XG4gICAgbGV0IHRpbWVyO1xuICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHJlbWFpbmluZ1RpbWUgPSBpbnRlcnZhbCAtIChub3cgLSBsYXN0Q2FsbEF0KTtcbiAgICAgIGlmIChyZW1haW5pbmdUaW1lIDw9IDAgfHwgcmVtYWluaW5nVGltZSA+IGludGVydmFsKSB7XG4gICAgICAgIGlmICh0aW1lcikge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgICAgdGltZXIgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RDYWxsQXQgPSBub3c7XG4gICAgICAgIGNhbGxiYWNrKC4uLmFyZ3MpO1xuICAgICAgfSBlbHNlIGlmICghdGltZXIpIHtcbiAgICAgICAgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBsYXN0Q2FsbEF0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICB0aW1lciA9IG51bGw7XG4gICAgICAgICAgY2FsbGJhY2soLi4uYXJncyk7XG4gICAgICAgIH0sIHJlbWFpbmluZ1RpbWUpO1xuICAgICAgfVxuICAgIH07XG4gIH0sXG4gIGZpbmRPdmVycnVuVGFyZ2V0KCkge1xuICAgIGxldCByZWN0O1xuICAgIGNvbnN0IG92ZXJydW5UYXJnZXQgPSB0aGlzLmVsLmdldEF0dHJpYnV0ZShcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5iaW5kaW5nKFBIWF9WSUVXUE9SVF9PVkVSUlVOX1RBUkdFVClcbiAgICApO1xuICAgIGlmIChvdmVycnVuVGFyZ2V0KSB7XG4gICAgICBjb25zdCBvdmVycnVuRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChvdmVycnVuVGFyZ2V0KTtcbiAgICAgIGlmIChvdmVycnVuRWwpIHtcbiAgICAgICAgcmVjdCA9IG92ZXJydW5FbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcImRpZCBub3QgZmluZCBlbGVtZW50IHdpdGggaWQgXCIgKyBvdmVycnVuVGFyZ2V0KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVjdCA9IHRoaXMuZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgfVxuICAgIHJldHVybiByZWN0O1xuICB9XG59O1xudmFyIExpdmVGaWxlVXBsb2FkID0ge1xuICBhY3RpdmVSZWZzKCkge1xuICAgIHJldHVybiB0aGlzLmVsLmdldEF0dHJpYnV0ZShQSFhfQUNUSVZFX0VOVFJZX1JFRlMpO1xuICB9LFxuICBwcmVmbGlnaHRlZFJlZnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZWwuZ2V0QXR0cmlidXRlKFBIWF9QUkVGTElHSFRFRF9SRUZTKTtcbiAgfSxcbiAgbW91bnRlZCgpIHtcbiAgICB0aGlzLmpzKCkuaWdub3JlQXR0cmlidXRlcyh0aGlzLmVsLCBbXCJ2YWx1ZVwiXSk7XG4gICAgdGhpcy5wcmVmbGlnaHRlZFdhcyA9IHRoaXMucHJlZmxpZ2h0ZWRSZWZzKCk7XG4gIH0sXG4gIHVwZGF0ZWQoKSB7XG4gICAgY29uc3QgbmV3UHJlZmxpZ2h0cyA9IHRoaXMucHJlZmxpZ2h0ZWRSZWZzKCk7XG4gICAgaWYgKHRoaXMucHJlZmxpZ2h0ZWRXYXMgIT09IG5ld1ByZWZsaWdodHMpIHtcbiAgICAgIHRoaXMucHJlZmxpZ2h0ZWRXYXMgPSBuZXdQcmVmbGlnaHRzO1xuICAgICAgaWYgKG5ld1ByZWZsaWdodHMgPT09IFwiXCIpIHtcbiAgICAgICAgdGhpcy5fX3ZpZXcoKS5jYW5jZWxTdWJtaXQodGhpcy5lbC5mb3JtKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRoaXMuYWN0aXZlUmVmcygpID09PSBcIlwiKSB7XG4gICAgICB0aGlzLmVsLnZhbHVlID0gXCJcIjtcbiAgICB9XG4gICAgdGhpcy5lbC5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudChQSFhfTElWRV9GSUxFX1VQREFURUQpKTtcbiAgfVxufTtcbnZhciBMaXZlSW1nUHJldmlldyA9IHtcbiAgbW91bnRlZCgpIHtcbiAgICB0aGlzLnJlZiA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKFwiZGF0YS1waHgtZW50cnktcmVmXCIpO1xuICAgIHRoaXMuaW5wdXRFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFxuICAgICAgdGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX1VQTE9BRF9SRUYpXG4gICAgKTtcbiAgICB0aGlzLnVybCA9IExpdmVVcGxvYWRlci5nZXRFbnRyeURhdGFVUkwodGhpcy5pbnB1dEVsLCB0aGlzLnJlZik7XG4gICAgdGhpcy5lbC5zcmMgPSB0aGlzLnVybDtcbiAgfSxcbiAgZGVzdHJveWVkKCkge1xuICAgIFVSTC5yZXZva2VPYmplY3RVUkwodGhpcy51cmwpO1xuICB9XG59O1xudmFyIEhvb2tzID0ge1xuICBMaXZlRmlsZVVwbG9hZCxcbiAgTGl2ZUltZ1ByZXZpZXcsXG4gIEZvY3VzV3JhcDoge1xuICAgIG1vdW50ZWQoKSB7XG4gICAgICB0aGlzLmZvY3VzU3RhcnQgPSB0aGlzLmVsLmZpcnN0RWxlbWVudENoaWxkO1xuICAgICAgdGhpcy5mb2N1c0VuZCA9IHRoaXMuZWwubGFzdEVsZW1lbnRDaGlsZDtcbiAgICAgIHRoaXMuZm9jdXNTdGFydC5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgKGUpID0+IHtcbiAgICAgICAgaWYgKCFlLnJlbGF0ZWRUYXJnZXQgfHwgIXRoaXMuZWwuY29udGFpbnMoZS5yZWxhdGVkVGFyZ2V0KSkge1xuICAgICAgICAgIGNvbnN0IG5leHRGb2N1cyA9IGUudGFyZ2V0Lm5leHRFbGVtZW50U2libGluZztcbiAgICAgICAgICBhcmlhX2RlZmF1bHQuYXR0ZW1wdEZvY3VzKG5leHRGb2N1cykgfHwgYXJpYV9kZWZhdWx0LmZvY3VzRmlyc3QobmV4dEZvY3VzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhcmlhX2RlZmF1bHQuZm9jdXNMYXN0KHRoaXMuZWwpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuZm9jdXNFbmQuYWRkRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsIChlKSA9PiB7XG4gICAgICAgIGlmICghZS5yZWxhdGVkVGFyZ2V0IHx8ICF0aGlzLmVsLmNvbnRhaW5zKGUucmVsYXRlZF
1RhcmdldCkpIHtcbiAgICAgICAgICBjb25zdCBuZXh0Rm9jdXMgPSBlLnRhcmdldC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nO1xuICAgICAgICAgIGFyaWFfZGVmYXVsdC5hdHRlbXB0Rm9jdXMobmV4dEZvY3VzKSB8fCBhcmlhX2RlZmF1bHQuZm9jdXNMYXN0KG5leHRGb2N1cyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXJpYV9kZWZhdWx0LmZvY3VzRmlyc3QodGhpcy5lbCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKCF0aGlzLmVsLmNvbnRhaW5zKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpKSB7XG4gICAgICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcihcInBoeDpzaG93LWVuZFwiLCAoKSA9PiB0aGlzLmVsLmZvY3VzKCkpO1xuICAgICAgICBpZiAod2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbCkuZGlzcGxheSAhPT0gXCJub25lXCIpIHtcbiAgICAgICAgICBhcmlhX2RlZmF1bHQuZm9jdXNGaXJzdCh0aGlzLmVsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgSW5maW5pdGVTY3JvbGxcbn07XG52YXIgaG9va3NfZGVmYXVsdCA9IEhvb2tzO1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy9lbGVtZW50X3JlZi50c1xudmFyIEVsZW1lbnRSZWYgPSBjbGFzcyB7XG4gIHN0YXRpYyBvblVubG9jayhlbCwgY2FsbGJhY2spIHtcbiAgICBpZiAoIWRvbV9kZWZhdWx0LmlzTG9ja2VkKGVsKSAmJiAhZWwuY2xvc2VzdChgWyR7UEhYX1JFRl9MT0NLfV1gKSkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfVxuICAgIGNvbnN0IGNsb3Nlc3RMb2NrID0gZWwuY2xvc2VzdChgWyR7UEhYX1JFRl9MT0NLfV1gKTtcbiAgICBjb25zdCByZWYgPSBjbG9zZXN0TG9jay5jbG9zZXN0KGBbJHtQSFhfUkVGX0xPQ0t9XWApLmdldEF0dHJpYnV0ZShQSFhfUkVGX0xPQ0spO1xuICAgIGNsb3Nlc3RMb2NrLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBgcGh4OnVuZG8tbG9jazoke3JlZn1gLFxuICAgICAgKCkgPT4ge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgfSxcbiAgICAgIHsgb25jZTogdHJ1ZSB9XG4gICAgKTtcbiAgfVxuICBjb25zdHJ1Y3RvcihlbCkge1xuICAgIHRoaXMuZWwgPSBlbDtcbiAgICB0aGlzLmxvYWRpbmdSZWYgPSBlbC5oYXNBdHRyaWJ1dGUoUEhYX1JFRl9MT0FESU5HKSA/IHBhcnNlSW50KGVsLmdldEF0dHJpYnV0ZShQSFhfUkVGX0xPQURJTkcpLCAxMCkgOiBudWxsO1xuICAgIHRoaXMubG9ja1JlZiA9IGVsLmhhc0F0dHJpYnV0ZShQSFhfUkVGX0xPQ0spID8gcGFyc2VJbnQoZWwuZ2V0QXR0cmlidXRlKFBIWF9SRUZfTE9DSyksIDEwKSA6IG51bGw7XG4gIH1cbiAgLy8gcHVibGljXG4gIG1heWJlVW5kbyhyZWYsIHBoeEV2ZW50LCBlYWNoQ2xvbmVDYWxsYmFjaykge1xuICAgIGlmICghdGhpcy5pc1dpdGhpbihyZWYpKSB7XG4gICAgICBkb21fZGVmYXVsdC51cGRhdGVQcml2YXRlKHRoaXMuZWwsIFBIWF9QRU5ESU5HX1JFRlMsIFtdLCAocGVuZGluZ1JlZnMpID0+IHtcbiAgICAgICAgcGVuZGluZ1JlZnMucHVzaChyZWYpO1xuICAgICAgICByZXR1cm4gcGVuZGluZ1JlZnM7XG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy51bmRvTG9ja3MocmVmLCBwaHhFdmVudCwgZWFjaENsb25lQ2FsbGJhY2spO1xuICAgIHRoaXMudW5kb0xvYWRpbmcocmVmLCBwaHhFdmVudCk7XG4gICAgZG9tX2RlZmF1bHQudXBkYXRlUHJpdmF0ZSh0aGlzLmVsLCBQSFhfUEVORElOR19SRUZTLCBbXSwgKHBlbmRpbmdSZWZzKSA9PiB7XG4gICAgICByZXR1cm4gcGVuZGluZ1JlZnMuZmlsdGVyKChwZW5kaW5nUmVmKSA9PiB7XG4gICAgICAgIGxldCBvcHRzID0ge1xuICAgICAgICAgIGRldGFpbDogeyByZWY6IHBlbmRpbmdSZWYsIGV2ZW50OiBwaHhFdmVudCB9LFxuICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHRoaXMubG9hZGluZ1JlZiAmJiB0aGlzLmxvYWRpbmdSZWYgPiBwZW5kaW5nUmVmKSB7XG4gICAgICAgICAgdGhpcy5lbC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KGBwaHg6dW5kby1sb2FkaW5nOiR7cGVuZGluZ1JlZn1gLCBvcHRzKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubG9ja1JlZiAmJiB0aGlzLmxvY2tSZWYgPiBwZW5kaW5nUmVmKSB7XG4gICAgICAgICAgdGhpcy5lbC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KGBwaHg6dW5kby1sb2NrOiR7cGVuZGluZ1JlZn1gLCBvcHRzKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBlbmRpbmdSZWYgPiByZWY7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpZiAodGhpcy5pc0Z1bGx5UmVzb2x2ZWRCeShyZWYpKSB7XG4gICAgICB0aGlzLmVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfUkVGX1NSQyk7XG4gICAgfVxuICB9XG4gIC8vIHByaXZhdGVcbiAgaXNXaXRoaW4ocmVmKSB7XG4gICAgcmV0dXJuICEodGhpcy5sb2FkaW5nUmVmICE9PSBudWxsICYmIHRoaXMubG9hZGluZ1JlZiA+IHJlZiAmJiB0aGlzLmxvY2tSZWYgIT09IG51bGwgJiYgdGhpcy5sb2NrUmVmID4gcmVmKTtcbiAgfVxuICAvLyBDaGVjayBmb3IgY2xvbmVkIFBIWF9SRUZfTE9DSyBlbGVtZW50IHRoYXQgaGFzIGJlZW4gbW9ycGhlZCBiZWhpbmRcbiAgLy8gdGhlIHNjZW5lcyB3aGlsZSB0aGlzIGVsZW1lbnQgd2FzIGxvY2tlZCBpbiB0aGUgRE9NLlxuICAvLyBXaGVuIHdlIGFwcGx5IHRoZSBjbG9uZWQgdHJlZSB0byB0aGUgYWN0aXZlIERPTSBlbGVtZW50LCB3ZSBtdXN0XG4gIC8vXG4gIC8vICAgMS4gZXhlY3V0ZSBwZW5kaW5nIG1vdW50ZWQgaG9va3MgZm9yIG5vZGVzIG5vdyBpbiB0aGUgRE9NXG4gIC8vICAgMi4gdW5kbyBhbnkgcmVmIGluc2lkZSB0aGUgY2xvbmVkIHRyZWUgdGhhdCBoYXMgc2luY2UgYmVlbiBhY2snZFxuICB1bmRvTG9ja3MocmVmLCBwaHhFdmVudCwgZWFjaENsb25lQ2FsbGJhY2spIHtcbiAgICBpZiAoIXRoaXMuaXNMb2NrVW5kb25lQnkocmVmKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjbG9uZWRUcmVlID0gZG9tX2RlZmF1bHQucHJpdmF0ZSh0aGlzLmVsLCBQSFhfUkVGX0xPQ0spO1xuICAgIGlmIChjbG9uZWRUcmVlKSB7XG4gICAgICBlYWNoQ2xvbmVDYWxsYmFjayhjbG9uZWRUcmVlKTtcbiAgICAgIGRvbV9kZWZhdWx0LmRlbGV0ZVByaXZhdGUodGhpcy5lbCwgUEhYX1JFRl9MT0NLKTtcbiAgICB9XG4gICAgdGhpcy5lbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRl9MT0NLKTtcbiAgICBjb25zdCBvcHRzID0ge1xuICAgICAgZGV0YWlsOiB7IHJlZiwgZXZlbnQ6IHBoeEV2ZW50IH0sXG4gICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgY2FuY2VsYWJsZTogZmFsc2VcbiAgICB9O1xuICAgIHRoaXMuZWwuZGlzcGF0Y2hFdmVudChcbiAgICAgIG5ldyBDdXN0b21FdmVudChgcGh4OnVuZG8tbG9jazoke3RoaXMubG9ja1JlZn1gLCBvcHRzKVxuICAgICk7XG4gIH1cbiAgdW5kb0xvYWRpbmcocmVmLCBwaHhFdmVudCkge1xuICAgIGlmICghdGhpcy5pc0xvYWRpbmdVbmRvbmVCeShyZWYpKSB7XG4gICAgICBpZiAodGhpcy5jYW5VbmRvTG9hZGluZyhyZWYpICYmIHRoaXMuZWwuY2xhc3NMaXN0LmNvbnRhaW5zKFwicGh4LXN1Ym1pdC1sb2FkaW5nXCIpKSB7XG4gICAgICAgI
1HRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcInBoeC1jaGFuZ2UtbG9hZGluZ1wiKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuY2FuVW5kb0xvYWRpbmcocmVmKSkge1xuICAgICAgdGhpcy5lbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRl9MT0FESU5HKTtcbiAgICAgIGNvbnN0IGRpc2FibGVkVmFsID0gdGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVEKTtcbiAgICAgIGNvbnN0IHJlYWRPbmx5VmFsID0gdGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX1JFQURPTkxZKTtcbiAgICAgIGlmIChyZWFkT25seVZhbCAhPT0gbnVsbCAmJiBcInJlYWRPbmx5XCIgaW4gdGhpcy5lbCkge1xuICAgICAgICB0aGlzLmVsLnJlYWRPbmx5ID0gcmVhZE9ubHlWYWwgPT09IFwidHJ1ZVwiID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICB0aGlzLmVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfUkVBRE9OTFkpO1xuICAgICAgfVxuICAgICAgaWYgKGRpc2FibGVkVmFsICE9PSBudWxsICYmIFwiZGlzYWJsZWRcIiBpbiB0aGlzLmVsKSB7XG4gICAgICAgIHRoaXMuZWwuZGlzYWJsZWQgPSBkaXNhYmxlZFZhbCA9PT0gXCJ0cnVlXCIgPyB0cnVlIDogZmFsc2U7XG4gICAgICAgIHRoaXMuZWwucmVtb3ZlQXR0cmlidXRlKFBIWF9ESVNBQkxFRCk7XG4gICAgICB9XG4gICAgICBjb25zdCBkaXNhYmxlUmVzdG9yZSA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKFBIWF9ESVNBQkxFX1dJVEhfUkVTVE9SRSk7XG4gICAgICBpZiAoZGlzYWJsZVJlc3RvcmUgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5lbC50ZXh0Q29udGVudCA9IGRpc2FibGVSZXN0b3JlO1xuICAgICAgICB0aGlzLmVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfRElTQUJMRV9XSVRIX1JFU1RPUkUpO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3B0cyA9IHtcbiAgICAgICAgZGV0YWlsOiB7IHJlZiwgZXZlbnQ6IHBoeEV2ZW50IH0sXG4gICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgIGNhbmNlbGFibG
1U6IGZhbHNlXG4gICAgICB9O1xuICAgICAgdGhpcy5lbC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoYHBoeDp1bmRvLWxvYWRpbmc6JHt0aGlzLmxvYWRpbmdSZWZ9YCwgb3B0cylcbiAgICAgICk7XG4gICAgfVxuICAgIFBIWF9FVkVOVF9DTEFTU0VTLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgIGlmIChuYW1lICE9PSBcInBoeC1zdWJtaXQtbG9hZGluZ1wiIHx8IHRoaXMuY2FuVW5kb0xvYWRpbmcocmVmKSkge1xuICAgICAgICBkb21fZGVmYXVsdC5yZW1vdmVDbGFzcyh0aGlzLmVsLCBuYW1lKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICBpc0xvYWRpbmdVbmRvbmVCeShyZWYpIHtcbiAgICByZXR1cm4gdGhpcy5sb2FkaW5nUmVmID09PSBudWxsID8gZmFsc2UgOiB0aGlzLmxvYWRpbmdSZWYgPD0gcmVmO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgaXNMb2NrVW5kb25lQnkocmVmKSB7XG4gICAgcmV0dXJuIHRoaXMubG9ja1JlZiA9PT0gbnVsbCA/IGZhbHNlIDogdGhpcy5sb2NrUmVmIDw9IHJlZjtcbiAgfVxuICBpc0Z1bGx5UmVzb2x2ZWRCeShyZWYpIHtcbiAgICByZXR1cm4gKHRoaXMubG9hZGluZ1JlZiA9PT0gbnVsbCB8fCB0aGlzLmxvYWRpbmdSZWYgPD0gcmVmKSAmJiAodGhpcy5sb2NrUmVmID09PSBudWxsIHx8IHRoaXMubG9ja1JlZiA8PSByZWYpO1xuICB9XG4gIC8vIG9ubHkgcmVtb3ZlIHRoZSBwaHgtc3VibWl0LWxvYWRpbmcgY2xhc3MgaWYgd2UgYXJlIG5vdCBsb2NrZWRcbiAgY2FuVW5kb0xvYWRpbmcocmVmKSB7XG4gICAgcmV0dXJuIHRoaXMubG9ja1JlZiA9PT0gbnVsbCB8fCB0aGlzLmxvY2tSZWYgPD0gcmVmO1xuICB9XG59O1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy9kb21fcG9zdF9tb3JwaF9yZXN0b3Jlci50c1xudmFyIERPTVBvc3RNb3JwaFJlc3RvcmVyID0gY2xhc3Mge1xuICBjb25zdHJ1Y3Rvcihjb250YWluZXJCZWZvcmUsIGNvbnRhaW5lckFmdGVyLCB1cGRhdGVUeXBlKSB7XG4gICAgY29uc3QgaWRzQmVmb3JlID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgICBjb25zdCBpZHNBZnRlciA9IG5ldyBTZXQoXG4gICAgICBbLi4uY29udGFpbmVyQWZ0ZXIuY2hpbGRyZW5dLm1hcCgoY2hpbGQpID0+IGNoaWxkLmlkKVxuICAgICk7XG4gICAgY29uc3QgZWxlbWVudHNUb01vZGlmeSA9IFtdO1xuICAgIEFycmF5LmZyb20oY29udGFpbmVyQmVmb3JlLmNoaWxkcmVuKS5mb3JFYWNoKChjaGlsZCkgPT4ge1xuICAgICAgaWYgKGNoaWxkLmlkKSB7XG4gICAgICAgIGlkc0JlZm9yZS5hZGQoY2hpbGQuaWQpO1xuICAgICAgICBpZiAoaWRzQWZ0ZXIuaGFzKGNoaWxkLmlkKSkge1xuICAgICAgICAgIGNvbnN0IHByZXZpb3VzRWxlbWVudElkID0gY2hpbGQucHJldmlvdXNFbGVtZW50U2libGluZyAmJiBjaGlsZC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nLmlkO1xuICAgICAgICAgIGVsZW1lbnRzVG9Nb2RpZnkucHVzaCh7XG4gICAgICAgICAgICBlbGVtZW50SWQ6IGNoaWxkLmlkLFxuICAgICAgICAgICAgcHJldmlvdXNFbGVtZW50SWRcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMuY29udGFpbmVySWQgPSBjb250YWluZXJBZnRlci5pZDtcbiAgICB0aGlzLnVwZGF0ZVR5cGUgPSB1cGRhdGVUeXBlO1xuICAgIHRoaXMuZWxlbWVudHNUb01vZGlmeSA9IGVsZW1lbnRzVG9Nb2RpZnk7XG4gICAgdGhpcy5lbGVtZW50SWRzVG9BZGQgPSBbLi4uaWRzQWZ0ZXJdLmZpbHRlcigoaWQpID0+ICFpZHNCZWZvcmUuaGFzKGlkKSk7XG4gIH1cbiAgLy8gV2UgZG8gdGhlIGZvbGxvd2luZyB0byBvcHRpbWl6ZSBhcHBlbmQvcHJlcGVuZCBvcGVyYXRpb25zOlxuICAvLyAgIDEpIFRyYWNrIGlkcyBvZiBtb2RpZmllZCBlbGVtZW50cyAmIG9mIG5ldyBlbGVtZW50c1xuICAvLyAgIDIpIEFsbCB0aGUgbW9kaWZpZWQgZWxlbWVudHMgYXJlIHB1dCBiYWNrIGluIHRoZSBjb3JyZWN0IHBvc2l0aW9uIGluIHRoZSBET00gdHJlZVxuICAvLyAgICAgIGJ5IHN0b3JpbmcgdGhlIGlkIG9mIHRoZWlyIHByZXZpb3VzIHNpYmxpbmdcbiAgLy8gICAzKSBOZXcgZWxlbWVudHMgYXJlIGdvaW5nIHRvIGJlIHB1dCBpbiB0aGUgcmlnaHQgcGxhY2UgYnkgbW9ycGhkb20gZHVyaW5nIGFwcGVuZC5cbiAgLy8gICAgICBGb3IgcHJlcGVuZCwgd2UgbW92ZSB0aGVtIHRvIHRoZSBmaXJzdCBwb3NpdGlvbiBpbiB0aGUgY29udGFpbmVyXG4gIHBlcmZvcm0oKSB7XG4gICAgY29uc3QgY29udGFpbmVyID0gZG9tX2RlZmF1bHQuYnlJZCh0aGlzLmNvbnRhaW5lcklkKTtcbiAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmVsZW1lbnRzVG9Nb2RpZnkuZm9yRWFjaCgoZWxlbWVudFRvTW9kaWZ5KSA9PiB7XG4gICAgICBpZiAoZWxlbWVudFRvTW9kaWZ5LnByZXZpb3VzRWxlbWVudElkKSB7XG4gICAgICAgIG1heWJlKFxuICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnRUb01vZGlmeS5wcmV2aW91c0VsZW1lbnRJZCksXG4gICAgICAgICAgKHByZXZpb3VzRWxlbSkgPT4ge1xuICAgICAgICAgICAgbWF5YmUoXG4gICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnRUb01vZGlmeS5lbGVtZW50SWQpLFxuICAgICAgICAgICAgICAoZWxlbSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlzSW5SaWdodFBsYWNlID0gZWxlbS5wcmV2aW91c0VsZW1lbnRTaWJsaW5nICYmIGVsZW0ucHJldmlvdXNFbGVtZW50U2libGluZy5pZCA9PSBwcmV2aW91c0VsZW0uaWQ7XG4gICAgICAgICAgICAgICAgaWYgKCFpc0luUmlnaHRQbGFjZSkge1xuICAgICAgICAgICAgICAgICAgcHJldmlvdXNFbGVtLmluc2VydEFkamFjZW50RWxlbWVudChcImFmdGVyZW5kXCIsIGVsZW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYXliZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50VG9Nb2RpZnkuZWxlbWVudElkKSwgKGVsZW0pID0+IHtcbiAgICAgICAgICBjb25zdCBpc0luUmlnaHRQbGFjZSA9IGVsZW0ucHJldmlvdXNFbGVtZW50U2libGluZyA9PSBudWxsO1xuICAgICAgICAgIGlmICghaXNJblJpZ2h0UGxhY2UpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5pbnNlcnRBZGphY2VudEVsZW1lbnQoXCJhZnRlcmJlZ2luXCIsIGVsZW0pO1xuICAgICAgICAgI
1H1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKHRoaXMudXBkYXRlVHlwZSA9PSBcInByZXBlbmRcIikge1xuICAgICAgdGhpcy5lbGVtZW50SWRzVG9BZGQucmV2ZXJzZSgpLmZvckVhY2goKGVsZW1JZCkgPT4ge1xuICAgICAgICBtYXliZShcbiAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtSWQpLFxuICAgICAgICAgIChlbGVtKSA9PiBjb250YWluZXIuaW5zZXJ0QWRqYWNlbnRFbGVtZW50KFwiYWZ0ZXJiZWdpblwiLCBlbGVtKVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59O1xuXG4vLyAuLi9ub2RlX21vZHVsZXMvbW9ycGhkb20vZGlzdC9tb3JwaGRvbS1lc20uanNcbnZhciBET0NVTUVOVF9GUkFHTUVOVF9OT0RFID0gMTE7XG5mdW5jdGlvbiBtb3JwaEF0dHJzKGZyb21Ob2RlLCB0b05vZGUpIHtcbiAgdmFyIHRvTm9kZUF0dHJzID0gdG9Ob2RlLmF0dHJpYnV0ZXM7XG4gIHZhciBhdHRyO1xuICB2YXIgYXR0ck5hbWU7XG4gIHZhciBhdHRyTmFtZXNwYWNlVVJJO1xuICB2YXIgYXR0clZhbHVlO1xuICB2YXIgZnJvbVZhbHVlO1xuICBpZiAodG9Ob2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFIHx8IGZyb21Ob2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGZvciAodmFyIGkgPSB0b05vZGVBdHRycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGF0dHIgPSB0b05vZGVBdHRyc1tpXTtcbiAgICBhdHRyTmFtZSA9IGF0dHIubmFtZTtcbiAgICBhdHRyTmFtZXNwYWNlVVJJID0gYXR0ci5uYW1lc3BhY2VVUkk7XG4gICAgYXR0clZhbHVlID0gYXR0ci52YWx1ZTtcbiAgICBpZiAoYXR0ck5hbWVzcGFjZVVSSSkge1xuICAgICAgYXR0ck5hbWUgPSBhdHRyLmxvY2FsTmFtZSB8fCBhdHRyTmFtZTtcbiAgICAgIGZyb21WYWx1ZSA9IGZyb21Ob2RlLmdldEF0dHJpYnV0ZU5TKGF0dHJOYW1lc3BhY2VVUkksIGF0dHJOYW1lKTtcbiAgICAgIGlmIChmcm9tVmFsdWUgIT09IGF0dHJWYWx1ZSkge1xuICAgICAgICBpZiAoYXR0ci5wcmVmaXggPT09IFwieG1sbnNcIikge1xuICAgICAgICAgIGF0dHJOYW1lID0gYXR0ci5uYW1lO1xuICAgICAgICB9XG4gICAgICAgIGZyb21Ob2RlLnNldEF0dHJpYnV0ZU5TKGF0dHJOYW1lc3BhY2VVUkksIGF0dHJOYW1lLCBhdHRyVmFsdWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmcm9tVmFsdWUgPSBmcm9tTm9kZS5nZXRBdHRyaWJ1dGUoYXR0ck5hbWUpO1xuICAgICAgaWYgKGZyb21WYWx1ZSAhPT0gYXR0clZhbHVlKSB7XG4gICAgICAgIGZyb21Ob2RlLnNldEF0dHJpYnV0ZShhdHRyTmFtZSwgYXR0clZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIGZyb21Ob2RlQXR0cnMgPSBmcm9tTm9kZS5hdHRyaWJ1dGVzO1xuICBmb3IgKHZhciBkID0gZnJvbU5vZGVBdHRycy5sZW5ndGggLSAxOyBkID49IDA7IGQtLSkge1xuICAgIGF0dHIgPSBmcm9tTm9kZUF0dHJzW2RdO1xuICAgIGF0dHJOYW1lID0gYXR0ci5uYW1lO1xuICAgIGF0dHJOYW1lc3BhY2VVUkkgPSBhdHRyLm5hbWVzcGFjZVVSSTtcbiAgICBpZiAoYXR0ck5hbWVzcGFjZVVSSSkge1xuICAgICAgYXR0ck5hbWUgPSBhdHRyLmxvY2FsTmFtZSB8fCBhdHRyTmFtZTtcbiAgICAgIGlmICghdG9Ob2RlLmhhc0F0dHJpYnV0ZU5TKGF0dHJOYW1lc3BhY2VVUkksIGF0dHJOYW1lKSkge1xuICAgICAgICBmcm9tTm9kZS5yZW1vdmVBdHRyaWJ1dGVOUyhhdHRyTmFtZXNwYWNlVVJJLCBhdHRyTmFtZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdG9Ob2RlLmhhc0F0dHJpYnV0ZShhdHRyTmFtZSkpIHtcbiAgICAgICAgZnJvbU5vZGUucmVtb3ZlQXR0cmlidXRlKGF0dHJOYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbnZhciByYW5nZTtcbnZhciBOU19YSFRNTCA9IFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiO1xudmFyIGRvYyA9IHR5cGVvZiBkb2N1bWVudCA9PT0gXCJ1bmRlZmluZWRcIiA/IHZvaWQgMCA6IGRvY3VtZW50O1xudmFyIEhBU19URU1QTEFURV9TVVBQT1JUID0gISFkb2MgJiYgXCJjb250ZW50XCIgaW4gZG9jLmNyZWF0ZUVsZW1lbnQoXCJ0ZW1wbGF0ZVwiKTtcbnZhciBIQVNfUkFOR0VfU1VQUE9SVCA9ICEhZG9jICYmIGRvYy5jcmVhdGVSYW5nZSAmJiBcImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudFwiIGluIGRvYy5jcmVhdGVSYW5nZSgpO1xuZnVuY3Rpb24gY3JlYXRlRnJhZ21lbnRGcm9tVGVtcGxhdGUoc3RyKSB7XG4gIHZhciB0ZW1wbGF0ZSA9IGRvYy5jcmVhdGVFbGVtZW50KFwidGVtcGxhdGVcIik7XG4gIHRlbXBsYXRlLmlubmVySFRNTCA9IHN0cjtcbiAgcmV0dXJuIHRlbXBsYXRlLmNvbnRlbnQuY2hpbGROb2Rlc1swXTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUZyYWdtZW50RnJvbVJhbmdlKHN0cikge1xuICBpZiAoIXJhbmdlKSB7XG4gICAgcmFuZ2UgPSBkb2MuY3JlYXRlUmFuZ2UoKTtcbiAgICByYW5nZS5zZWxlY3ROb2RlKGRvYy5ib2R5KTtcbiAgfVxuICB2YXIgZnJhZ21lbnQgPSByYW5nZS5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQoc3RyKTtcbiAgcmV0dXJuIGZyYWdtZW50LmNoaWxkTm9kZXNbMF07XG59XG5mdW5jdGlvbiBjcmVhdGVGcmFnbWVudEZyb21XcmFwKHN0cikge1xuICB2YXIgZnJhZ21lbnQgPSBkb2MuY3JlYXRlRWxlbWVudChcImJvZHlcIik7XG4gIGZyYWdtZW50LmlubmVySFRNTCA9IHN0cjtcbiAgcmV0dXJuIGZyYWdtZW50LmNoaWxkTm9kZXNbMF07XG59XG5mdW5jdGlvbiB0b0VsZW1lbnQoc3RyKSB7XG4gIHN0ciA9IHN0ci50cmltKCk7XG4gIGlmIChIQVNfVEVNUExBVEVfU1VQUE9SVCkge1xuICAgIHJldHVybiBjcmVhdGVGcmFnbWVudEZyb21UZW1wbGF0ZShzdHIpO1xuICB9IGVsc2UgaWYgKEhBU19SQU5HRV9TVVBQT1JUKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUZyYWdtZW50RnJvbVJhbmdlKHN0cik7XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUZyYWdtZW50RnJvbVdyYXAoc3RyKTtcbn1cbmZ1bmN0aW9uIGNvbXBhcmVOb2RlTmFtZXMoZnJvbUVsLCB0b0VsKSB7XG4gIHZhciBmcm9tTm9kZU5hbWUgPSBmcm9tRWwubm9kZU5hbWU7XG4gIHZhciB0b05vZGVOYW1lID0gdG9FbC5ub2RlTmFtZTtcbiAgdmFyIGZyb21
1Db2RlU3RhcnQsIHRvQ29kZVN0YXJ0O1xuICBpZiAoZnJvbU5vZGVOYW1lID09PSB0b05vZGVOYW1lKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgZnJvbUNvZGVTdGFydCA9IGZyb21Ob2RlTmFtZS5jaGFyQ29kZUF0KDApO1xuICB0b0NvZGVTdGFydCA9IHRvTm9kZU5hbWUuY2hhckNvZGVBdCgwKTtcbiAgaWYgKGZyb21Db2RlU3RhcnQgPD0gOTAgJiYgdG9Db2RlU3RhcnQgPj0gOTcpIHtcbiAgICByZXR1cm4gZnJvbU5vZGVOYW1lID09PSB0b05vZGVOYW1lLnRvVXBwZXJDYXNlKCk7XG4gIH0gZWxzZSBpZiAodG9Db2RlU3RhcnQgPD0gOTAgJiYgZnJvbUNvZGVTdGFydCA+PSA5Nykge1xuICAgIHJldHVybiB0b05vZGVOYW1lID09PSBmcm9tTm9kZU5hbWUudG9VcHBlckNhc2UoKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnROUyhuYW1lLCBuYW1lc3BhY2VVUkkpIHtcbiAgcmV0dXJuICFuYW1lc3BhY2VVUkkgfHwgbmFtZXNwYWNlVVJJID09PSBOU19YSFRNTCA/IGRvYy5jcmVhdGVFbGVtZW50KG5hbWUpIDogZG9jLmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkksIG5hbWUpO1xufVxuZnVuY3Rpb24gbW92ZUNoaWxkcmVuKGZyb21FbCwgdG9FbCkge1xuICB2YXIgY3VyQ2hpbGQgPSBmcm9tRWwuZmlyc3RDaGlsZDtcbiAgd2hpbGUgKGN1ckNoaWxkKSB7XG4gICAgdmFyIG5leHRDaGlsZCA9IGN1ckNoaWxkLm5leHRTaWJsaW5nO1xuICAgIHRvRWwuYXBwZW5kQ2hpbGQoY3VyQ2hpbGQpO1xuICAgIGN1ckNoaWxkID0gbmV4dENoaWxkO1xuICB9XG4gIHJldHVybiB0b0VsO1xufVxuZnVuY3Rpb24gc3luY0Jvb2xlYW5BdHRyUHJvcChmcm9tRWwsIHRvRWwsIG5hbWUpIHtcbiAgaWYgKGZyb21FbFtuYW1lXSAhPT0gdG9FbFtuYW1lXSkge1xuICAgIGZyb21FbFtuYW1lXSA9IHRvRWxbbmFtZV07XG4gICAgaWYgKGZyb21FbFtuYW1lXSkge1xuICAgICAgZnJvbUVsLnNldEF0dHJpYnV0ZShuYW1lLCBcIlwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZnJvbUVsLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICB9XG4gIH1cbn1cbnZhciBzcGVjaWFsRWxIYW5kbGVycyA9IHtcbiAgT1BUSU9OOiBmdW5jdGlvbihmcm9tRWwsIHRvRWwpIHtcbiAgICB2YXIgcGFyZW50Tm9kZSA9IGZyb21FbC5wYXJlbnROb2RlO1xuICAgIGlmIChwYXJlbnROb2RlKSB7XG4gICAgICB2Y
1XIgcGFyZW50TmFtZSA9IHBhcmVudE5vZGUubm9kZU5hbWUudG9VcHBlckNhc2UoKTtcbiAgICAgIGlmIChwYXJlbnROYW1lID09PSBcIk9QVEdST1VQXCIpIHtcbiAgICAgICAgcGFyZW50Tm9kZSA9IHBhcmVudE5vZGUucGFyZW50Tm9kZTtcbiAgICAgICAgcGFyZW50TmFtZSA9IHBhcmVudE5vZGUgJiYgcGFyZW50Tm9kZS5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgfVxuICAgICAgaWYgKHBhcmVudE5hbWUgPT09IFwiU0VMRUNUXCIgJiYgIXBhcmVudE5vZGUuaGFzQXR0cmlidXRlKFwibXVsdGlwbGVcIikpIHtcbiAgICAgICAgaWYgKGZyb21FbC5oYXNBdHRyaWJ1dGUoXCJzZWxlY3RlZFwiKSAmJiAhdG9FbC5zZWxlY3RlZCkge1xuICAgICAgICAgIGZyb21FbC5zZXRBdHRyaWJ1dGUoXCJzZWxlY3RlZFwiLCBcInNlbGVjdGVkXCIpO1xuICAgICAgICAgIGZyb21FbC5yZW1vdmVBdHRyaWJ1dGUoXCJzZWxlY3RlZFwiKTtcbiAgICAgICAgfVxuICAgICAgICBwYXJlbnROb2RlLnNlbGVjdGVkSW5kZXggPSAtMTtcbiAgICAgIH1cbiAgICB9XG4gICAgc3luY0Jvb2xlYW5BdHRyUHJvcChmcm9tRWwsIHRvRWwsIFwic2VsZWN0ZWRcIik7XG4gIH0sXG4gIC8qKlxuICAgKiBUaGUgXCJ2YWx1ZVwiIGF0dHJpYnV0ZSBpcyBzcGVjaWFsIGZvciB0aGUgPGlucHV0PiBlbGVtZW50IHNpbmNlIGl0IHNldHNcbiAgICogdGhlIGluaXRpYWwgdmFsdWUuIENoYW5naW5nIHRoZSBcInZhbHVlXCIgYXR0cmlidXRlIHdpdGhvdXQgY2hhbmdpbmcgdGhlXG4gICAqIFwidmFsdWVcIiBwcm9wZXJ0eSB3aWxsIGhhdmUgbm8gZWZmZWN0IHNpbmNlIGl0IGlzIG9ubHkgdXNlZCB0byB0aGUgc2V0IHRoZVxuICAgKiBpbml0aWFsIHZhbHVlLiAgU2ltaWxhciBmb3IgdGhlIFwiY2hlY2tlZFwiIGF0dHJpYnV0ZSwgYW5kIFwiZGlzYWJsZWRcIi5cbiAgICovXG4gIElOUFVUOiBmdW5jdGlvbihmcm9tRWwsIHRvRWwpIHtcbiAgICBzeW5jQm9vbGVhbkF0dHJQcm9wKGZyb21FbCwgdG9FbCwgXCJjaGVja2VkXCIpO1xuICAgIHN5bmNCb29sZWFuQXR0clByb3AoZnJvbUVsLCB0b0VsLCBcImRpc2FibGVkXCIpO1xuICAgIGlmIChmcm9tRWwudmFsdWUgIT09IHRvRWwudmFsdWUpIHtcbiAgICAgIGZyb21FbC52YWx1ZSA9IHRvRWwudmFsdWU7XG4gICAgfVxuICAgIGlmICghdG9FbC5oYXNBdHRyaWJ1dGUoXCJ2YWx1ZVwiKSkge1xuICAgICAgZnJvbUVsLnJlbW92ZUF0dHJpYnV0ZShcInZhbHVlXCIpO1xuICAgIH1cbiAgfSxcbiAgVEVYVEFSRUE6IGZ1bmN0aW9uKGZyb21FbCwgdG9FbCkge1xuICAgIHZhciBuZXdWYWx1ZSA9IHRvRWwudmFsdWU7XG4gICAgaWYgKGZyb21FbC52YWx1ZSAhPT0gbmV3VmFsdWUpIHtcbiAgICAgIGZyb21FbC52YWx1ZSA9IG5ld1ZhbHVlO1xuICAgIH1cbiAgICB2YXIgZmlyc3RDaGlsZCA9IGZyb21FbC5maXJzdENoaWxkO1xuICAgIGlmIChmaXJzdENoaWxkKSB7XG4gICAgICB2Y
1XIgb2xkVmFsdWUgPSBmaXJzdENoaWxkLm5vZGVWYWx1ZTtcbiAgICAgIGlmIChvbGRWYWx1ZSA9PSBuZXdWYWx1ZSB8fCAhbmV3VmFsdWUgJiYgb2xkVmFsdWUgPT0gZnJvbUVsLnBsYWNlaG9sZGVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGZpcnN0Q2hpbGQubm9kZVZhbHVlID0gbmV3VmFsdWU7XG4gICAgfVxuICB9LFxuICBTRUxFQ1Q6IGZ1bmN0aW9uKGZyb21FbCwgdG9FbCkge1xuICAgIGlmICghdG9FbC5oYXNBdHRyaWJ1dGUoXCJtdWx0aXBsZVwiKSkge1xuICAgICAgdmFyIHNlbGVjdGVkSW5kZXggPSAtMTtcbiAgICAgIHZhciBpID0gMDtcbiAgICAgIHZhciBjdXJDaGlsZCA9IGZyb21FbC5maXJzdENoaWxkO1xuICAgICAgdmFyIG9wdGdyb3VwO1xuICAgICAgdmFyIG5vZGVOYW1lO1xuICAgICAgd2hpbGUgKGN1ckNoaWxkKSB7XG4gICAgICAgIG5vZGVOYW1lID0gY3VyQ2hpbGQubm9kZU5hbWUgJiYgY3VyQ2hpbGQubm9kZU5hbWUudG9VcHBlckNhc2UoKTtcbiAgICAgICAgaWYgKG5vZGVOYW1lID09PSBcIk9QVEdST1VQXCIpIHtcbiAgICAgICAgICBvcHRncm91cCA9IGN1ckNoaWxkO1xuICAgICAgICAgIGN1ckNoaWxkID0gb3B0Z3JvdXAuZmlyc3RDaGlsZDtcbiAgICAgICAgICBpZiAoIWN1ckNoaWxkKSB7XG4gICAgICAgICAgICBjdXJDaGlsZCA9IG9wdGdyb3VwLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgb3B0Z3JvdXAgPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAobm9kZU5hbWUgPT09IFwiT1BUSU9OXCIpIHtcbiAgICAgICAgICAgIGlmIChjdXJDaGlsZC5oYXNBdHRyaWJ1dGUoXCJzZWxlY3RlZFwiKSkge1xuICAgICAgICAgICAgICBzZWxlY3RlZEluZGV4ID0gaTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpKys7XG4gICAgICAgICAgfVxuICAgICAgICAgIGN1ckNoaWxkID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgICAgaWYgKCFjdXJDaGlsZCAmJiBvcHRncm91cCkge1xuICAgICAgICAgICAgY3VyQ2hpbGQgPSBvcHRncm91cC5uZXh0U2libGluZztcbiAgICAgICAgICAgIG9wdGdyb3VwID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZyb21FbC5zZWxlY3RlZEluZGV4ID0gc2VsZWN0ZWRJbmRleDtcbiAgICB9XG4gIH1cbn07XG52YXIgRUxFTUVOVF9OT0RFID0gMTtcbnZhciBET0NVTUVOVF9GUkFHTUVOVF9OT0RFJDEgPSAxMTtcbnZhciBURVhUX05PREUgPSAzO1xudmFyIENPTU1FTlRfTk9ERSA9IDg7XG5mdW5jdGlvbiBub29wKCkge1xufVxuZnVuY3Rpb24gZGVmYXVsdEdldE5vZGVLZXkobm9kZSkge1xuICBpZiAobm9kZSkge1xuICAgIHJldHVybiBub2RlLmdldEF0dHJpYnV0ZSAmJiBub2RlLmdldEF0dHJpYnV0ZShcImlkXCIpIHx8IG5vZGUuaWQ7XG4gIH1cbn1cbmZ1bmN0aW9uIG1vcnBoZG9tRmFjdG9yeShtb3JwaEF0dHJzMikge1xuICByZXR1cm4gZnVuY3Rpb24gbW9ycGhkb20yKGZyb21Ob2RlLCB0b05vZGUsIG9wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB0b05vZGUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGlmIChmcm9tTm9kZS5ub2RlTmFtZSA9PT0gXCIjZG9jdW1lbnRcIiB8fCBmcm9tTm9kZS5ub2RlTmFtZSA9PT0gXCJIVE1MXCIpIHtcbiAgICAgICAgdmFyIHRvTm9kZUh0bWwgPSB0b05vZGU7XG4gICAgICAgIHRvTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KFwiaHRtbFwiKTtcbiAgICAgICAgdG9Ob2RlLmlubmVySFRNTCA9IHRvTm9kZUh0bWw7XG4gICAgICB9IGVsc2UgaWYgKGZyb21Ob2RlLm5vZGVOYW1lID09PSBcIkJPRFlcIikge1xuICAgICAgICB2Y
1XIgdG9Ob2RlQm9keSA9IHRvTm9kZTtcbiAgICAgICAgdG9Ob2RlID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJodG1sXCIpO1xuICAgICAgICB0b05vZGUuaW5uZXJIVE1MID0gdG9Ob2RlQm9keTtcbiAgICAgICAgdmFyIGJvZHlFbGVtZW50ID0gdG9Ob2RlLnF1ZXJ5U2VsZWN0b3IoXCJib2R5XCIpO1xuICAgICAgICBpZiAoYm9keUVsZW1lbnQpIHtcbiAgICAgICAgICB0b05vZGUgPSBib2R5RWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdG9Ob2RlID0gdG9FbGVtZW50KHRvTm9kZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0b05vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUkMSkge1xuICAgICAgdG9Ob2RlID0gdG9Ob2RlLmZpcnN0RWxlbWVudENoaWxkO1xuICAgIH1cbiAgICB2YXIgZ2V0Tm9kZUtleSA9IG9wdGlvbnMuZ2V0Tm9kZUtleSB8fCBkZWZhdWx0R2V0Tm9kZUtleTtcbiAgICB2YXIgb25CZWZvcmVOb2RlQWRkZWQgPSBvcHRpb25zLm9uQmVmb3JlTm9kZUFkZGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uTm9kZUFkZGVkID0gb3B0aW9ucy5vbk5vZGVBZGRlZCB8fCBub29wO1xuICAgIHZhciBvbkJlZm9yZUVsVXBkYXRlZCA9IG9wdGlvbnMub25CZWZvcmVFbFVwZGF0ZWQgfHwgbm9vcDtcbiAgICB2YXIgb25FbFVwZGF0ZWQgPSBvcHRpb25zLm9uRWxVcGRhdGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uQmVmb3JlTm9kZURpc2NhcmRlZCA9IG9wdGlvbnMub25CZWZvcmVOb2RlRGlzY2FyZGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uTm9kZURpc2NhcmRlZCA9IG9wdGlvbnMub25Ob2RlRGlzY2FyZGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uQmVmb3JlRWxDaGlsZHJlblVwZGF0ZWQgPSBvcHRpb25zLm9uQmVmb3JlRWxDaGlsZHJlblVwZGF0ZWQgfHwgbm9vcDtcbiAgICB2YXIgc2tpcEZyb21DaGlsZHJlbiA9IG9wdGlvbnMuc2tpcEZyb21DaGlsZHJlbiB8fCBub29wO1xuICAgIHZhciBhZGRDaGlsZCA9IG9wdGlvbnMuYWRkQ2hpbGQgfHwgZnVuY3Rpb24ocGFyZW50LCBjaGlsZCkge1xuICAgICAgcmV0dXJuIHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZCk7XG4gICAgfTtcbiAgICB2YXIgY2hpbGRyZW5Pbmx5ID0gb3B0aW9ucy5jaGlsZHJlbk9ubHkgPT09IHRydWU7XG4gICAgdmFyIGZyb21Ob2Rlc0xvb2t1cCA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHZhciBrZXllZFJlbW92YWxMaXN0ID0gW107XG4gICAgZnVuY3Rpb24gYWRkS2V5ZWRSZW1vdmFsKGtleSkge1xuICAgICAga2V5ZWRSZW1vdmFsTGlzdC5wdXNoKGtleSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHdhbGtEaXNjYXJkZWRDaGlsZE5vZGVzKG5vZGUsIHNraXBLZXllZE5vZGVzKSB7XG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgIHZhciBjdXJDaGlsZCA9IG5vZGUuZmlyc3RDaGlsZDtcbiAgICAgICAgd2hpbGUgKGN1ckNoaWxkKSB7XG4gICAgICAgICAgdmFyIGtleSA9IHZvaWQgMDtcbiAgICAgICAgICBpZiAoc2tpcEtleWVkTm9kZXMgJiYgKGtleSA9IGdldE5vZGVLZXkoY3VyQ2hpbGQpKSkge1xuICAgICAgICAgICAgYWRkS2V5ZWRSZW1vdmFsKGtleSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9uTm9kZURpc2NhcmRlZChjdXJDaGlsZCk7XG4gICAgICAgICAgICBpZiAoY3VyQ2hpbGQuZmlyc3RDaGlsZCkge1xuICAgICAgICAgICAgICB3YWxrRGlzY2FyZGVkQ2hpbGROb2RlcyhjdXJDaGlsZCwgc2tpcEtleWVkTm9kZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBjdXJDaGlsZCA9IGN1ckNoaWxkLm5leHRTaWJsaW5nO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIHJlbW92ZU5vZGUobm9kZSwgcGFyZW50Tm9kZSwgc2tpcEtleWVkTm9kZXMpIHtcbiAgICAgIGlmIChvbkJlZm9yZU5vZGVEaXNjYXJkZWQobm9kZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChwYXJlbnROb2RlKSB7XG4gICAgICAgIHBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7XG4gICAgICB9XG4gICAgICBvbk5vZGVEaXNjYXJkZWQobm9kZSk7XG4gICAgICB3YWxrRGlzY2FyZGVkQ2hpbGROb2Rlcyhub2RlLCBza2lwS2V5ZWROb2Rlcyk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGluZGV4VHJlZShub2RlKSB7XG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFIHx8IG5vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUkMSkge1xuICAgICAgICB2Y
1XIgY3VyQ2hpbGQgPSBub2RlLmZpcnN0Q2hpbGQ7XG4gICAgICAgIHdoaWxlIChjdXJDaGlsZCkge1xuICAgICAgICAgIHZhciBrZXkgPSBnZXROb2RlS2V5KGN1ckNoaWxkKTtcbiAgICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgICBmcm9tTm9kZXNMb29rdXBba2V5XSA9IGN1ckNoaWxkO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpbmRleFRyZWUoY3VyQ2hpbGQpO1xuICAgICAgICAgIGN1ckNoaWxkID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaW5kZXhUcmVlKGZyb21Ob2RlKTtcbiAgICBmdW5jdGlvbiBoYW5kbGVOb2RlQWRkZWQoZWwpIHtcbiAgICAgIG9uTm9kZUFkZGVkKGVsKTtcbiAgICAgIHZhciBjdXJDaGlsZCA9IGVsLmZpcnN0Q2hpbGQ7XG4gICAgICB3aGlsZSAoY3VyQ2hpbGQpIHtcbiAgICAgICAgdmFyIG5leHRTaWJsaW5nID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgIHZhciBrZXkgPSBnZXROb2RlS2V5KGN1ckNoaWxkKTtcbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgIHZhciB1bm1hdGNoZWRGcm9tRWwgPSBmcm9tTm9kZXNMb29rdXBba2V5XTtcbiAgICAgICAgICBpZiAodW5tYXRjaGVkRnJvbUVsICYmIGNvbXBhcmVOb2RlTmFtZXMoY3VyQ2hpbGQsIHVubWF0Y2hlZEZyb21FbCkpIHtcbiAgICAgICAgICAgIGN1ckNoaWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKHVubWF0Y2hlZEZyb21FbCwgY3VyQ2hpbGQpO1xuICAgICAgICAgICAgbW9ycGhFbCh1bm1hdGNoZWRGcm9tRWwsIGN1ckNoaWxkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaGFuZGxlTm9kZUFkZGVkKGN1ckNoaWxkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaGFuZGxlTm9kZUFkZGVkKGN1ckNoaWxkKTtcbiAgICAgICAgfVxuICAgICAgICBjdXJDaGlsZCA9IG5leHRTaWJsaW5nO1xuICAgICAgfVxuICAgIH1cbiAgICBmdW5jdGlvbiBjbGVhbnVwRnJvbUVsKGZyb21FbCwgY3VyRnJvbU5vZGVDaGlsZCwgY3VyRnJvbU5vZGVLZXkpIHtcbiAgICAgIHdoaWxlIChjdXJGcm9tTm9kZUNoaWxkKSB7XG4gICAgICAgIHZhciBmcm9tTmV4dFNpYmxpbmcgPSBjdXJGcm9tTm9kZUNoaWxkLm5leHRTaWJsaW5nO1xuICAgICAgICBpZiAoY3VyRnJvbU5vZGVLZXkgPSBnZXROb2RlS2V5KGN1ckZyb21Ob2RlQ2hpbGQpKSB7XG4gICAgICAgICAgYWRkS2V5ZWRSZW1vdmFsKGN1ckZyb21Ob2RlS2V5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZW1vdmVOb2RlKFxuICAgICAgICAgICAgY3VyRnJvbU5vZGVDaGlsZCxcbiAgICAgICAgICAgIGZyb21FbCxcbiAgICAgICAgICAgIHRydWVcbiAgICAgICAgICAgIC8qIHNraXAga2V5ZWQgbm9kZXMgKi9cbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGN1ckZyb21Ob2RlQ2hpbGQgPSBmcm9tTmV4dFNpYmxpbmc7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIG1vcnBoRWwoZnJvbUVsLCB0b0VsLCBjaGlsZHJlbk9ubHkyKSB7XG4gICAgICB2Y
1XIgdG9FbEtleSA9IGdldE5vZGVLZXkodG9FbCk7XG4gICAgICBpZiAodG9FbEtleSkge1xuICAgICAgICBkZWxldGUgZnJvbU5vZGVzTG9va3VwW3RvRWxLZXldO1xuICAgICAgfVxuICAgICAgaWYgKCFjaGlsZHJlbk9ubHkyKSB7XG4gICAgICAgIHZhciBiZWZvcmVVcGRhdGVSZXN1bHQgPSBvbkJlZm9yZUVsVXBkYXRlZChmcm9tRWwsIHRvRWwpO1xuICAgICAgICBpZiAoYmVmb3JlVXBkYXRlUmVzdWx0ID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChiZWZvcmVVcGRhdGVSZXN1bHQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgIGZyb21FbCA9IGJlZm9yZVVwZGF0ZVJlc3VsdDtcbiAgICAgICAgICBpbmRleFRyZWUoZnJvbUVsKTtcbiAgICAgICAgfVxuICAgICAgICBtb3JwaEF0dHJzMihmcm9tRWwsIHRvRWwpO1xuICAgICAgICBvbkVsVXBkYXRlZChmcm9tRWwpO1xuICAgICAgICBpZiAob25CZWZvcmVFbENoaWxkcmVuVXBkYXRlZChmcm9tRWwsIHRvRWwpID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZyb21FbC5ub2RlTmFtZSAhPT0gXCJURVhUQVJFQVwiKSB7XG4gICAgICAgIG1vcnBoQ2hpbGRyZW4oZnJvbUVsLCB0b0VsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNwZWNpYWxFbEhhbmRsZXJzLlRFWFRBUkVBKGZyb21FbCwgdG9FbCk7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIG1vcnBoQ2hpbGRyZW4oZnJvbUVsLCB0b0VsKSB7XG4gICAgICB2Y
1XIgc2tpcEZyb20gPSBza2lwRnJvbUNoaWxkcmVuKGZyb21FbCwgdG9FbCk7XG4gICAgICB2YXIgY3VyVG9Ob2RlQ2hpbGQgPSB0b0VsLmZpcnN0Q2hpbGQ7XG4gICAgICB2YXIgY3VyRnJvbU5vZGVDaGlsZCA9IGZyb21FbC5maXJzdENoaWxkO1xuICAgICAgdmFyIGN1clRvTm9kZUtleTtcbiAgICAgIHZhciBjdXJGcm9tTm9kZUtleTtcbiAgICAgIHZhciBmcm9tTmV4dFNpYmxpbmc7XG4gICAgICB2YXIgdG9OZXh0U2libGluZztcbiAgICAgIHZhciBtYXRjaGluZ0Zyb21FbDtcbiAgICAgIG91dGVyOlxuICAgICAgICB3aGlsZSAoY3VyVG9Ob2RlQ2hpbGQpIHtcbiAgICAgICAgICB0b05leHRTaWJsaW5nID0gY3VyVG9Ob2RlQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgICAgY3VyVG9Ob2RlS2V5ID0gZ2V0Tm9kZUtleShjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgd2hpbGUgKCFza2lwRnJvbSAmJiBjdXJGcm9tTm9kZUNoaWxkKSB7XG4gICAgICAgICAgICBmcm9tTmV4dFNpYmxpbmcgPSBjdXJGcm9tTm9kZUNoaWxkLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgaWYgKGN1clRvTm9kZUNoaWxkLmlzU2FtZU5vZGUgJiYgY3VyVG9Ob2RlQ2hpbGQuaXNTYW1lTm9kZShjdXJGcm9tTm9kZUNoaWxkKSkge1xuICAgICAgICAgICAgICBjdXJUb05vZGVDaGlsZCA9IHRvTmV4dFNpYmxpbmc7XG4gICAgICAgICAgICAgIGN1ckZyb21Ob2RlQ2hpbGQgPSBmcm9tTmV4dFNpYmxpbmc7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3VyRnJvbU5vZGVLZXkgPSBnZXROb2RlS2V5KGN1ckZyb21Ob2RlQ2hpbGQpO1xuICAgICAgICAgICAgdmFyIGN1ckZyb21Ob2RlVHlwZSA9IGN1ckZyb21Ob2RlQ2hpbGQubm9kZVR5cGU7XG4gICAgICAgICAgICB2Y
1XIgaXNDb21wYXRpYmxlID0gdm9pZCAwO1xuICAgICAgICAgICAgaWYgKGN1ckZyb21Ob2RlVHlwZSA9PT0gY3VyVG9Ob2RlQ2hpbGQubm9kZVR5cGUpIHtcbiAgICAgICAgICAgICAgaWYgKGN1ckZyb21Ob2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgICAgICAgaWYgKGN1clRvTm9kZUtleSkge1xuICAgICAgICAgICAgICAgICAgaWYgKGN1clRvTm9kZUtleSAhPT0gY3VyRnJvbU5vZGVLZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoaW5nRnJvbUVsID0gZnJvbU5vZGVzTG9va3VwW2N1clRvTm9kZUtleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoZnJvbU5leHRTaWJsaW5nID09PSBtYXRjaGluZ0Zyb21FbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNDb21wYXRpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZyb21FbC5pbnNlcnRCZWZvcmUobWF0Y2hpbmdGcm9tRWwsIGN1ckZyb21Ob2RlQ2hpbGQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1ckZyb21Ob2RlS2V5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGFkZEtleWVkUmVtb3ZhbChjdXJGcm9tTm9kZUtleSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVOb2RlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1ckZyb21Ob2RlQ2hpbGQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbUVsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBza2lwIGtleWVkIG5vZGVzICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gbWF0Y2hpbmdGcm9tRWw7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJGcm9tTm9kZUtleSA9IGdldE5vZGVLZXkoY3VyRnJvbU5vZGVDaGlsZCk7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIGlzQ29tcGF0aWJsZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJGcm9tTm9kZUtleSkge1xuICAgICAgICAgICAgICAgICAgaXNDb21wYXRpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlzQ29tcGF0aWJsZSA9IGlzQ29tcGF0aWJsZSAhPT0gZmFsc2UgJiYgY29tcGFyZU5vZGVOYW1lcyhjdXJGcm9tTm9kZUNoaWxkLCBjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgICAgICAgaWYgKGlzQ29tcGF0aWJsZSkge1xuICAgICAgICAgICAgICAgICAgbW9ycGhFbChjdXJGcm9tTm9kZUNoaWxkLCBjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGN1ckZyb21Ob2RlVHlwZSA9PT0gVEVYVF9OT0RFIHx8IGN1ckZyb21Ob2RlVHlwZSA9PSBDT01NRU5UX05PREUpIHtcbiAgICAgICAgICAgICAgICBpc0NvbXBhdGlibGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGlmIChjdXJGcm9tTm9kZUNoaWxkLm5vZGVWYWx1ZSAhPT0gY3VyVG9Ob2RlQ2hpbGQubm9kZVZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkLm5vZGVWYWx1ZSA9IGN1clRvTm9kZUNoaWxkLm5vZGVWYWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc0NvbXBhdGlibGUpIHtcbiAgICAgICAgICAgICAgY3VyVG9Ob2RlQ2hpbGQgPSB0b05leHRTaWJsaW5nO1xuICAgICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gZnJvbU5leHRTaWJsaW5nO1xuICAgICAgICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjdXJGcm9tTm9kZUtleSkge1xuICAgICAgICAgICAgICBhZGRLZXllZFJlbW92YWwoY3VyRnJvbU5vZGVLZXkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVtb3ZlTm9kZShcbiAgICAgICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkLFxuICAgICAgICAgICAgICAgIGZyb21FbCxcbiAgICAgICAgICAgICAgICB0cnVlXG4gICAgICAgICAgICAgICAgLyogc2tpcCBrZXllZCBub2RlcyAqL1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3VyRnJvbU5vZGVDaGlsZCA9IGZyb21OZXh0U2libGluZztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGN1clRvTm9kZUtleSAmJiAobWF0Y2hpbmdGcm9tRWwgPSBmcm9tTm9kZXNMb29rdXBbY3VyVG9Ob2RlS2V5XSkgJiYgY29tcGFyZU5vZGVOYW1lcyhtYXRjaGluZ0Zyb21FbCwgY3VyVG9Ob2RlQ2hpbGQpKSB7XG4gICAgICAgICAgICBpZiAoIXNraXBGcm9tKSB7XG4gICAgICAgICAgICAgIGFkZENoaWxkKGZyb21FbCwgbWF0Y2hpbmdGcm9tRWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbW9ycGhFbChtYXRjaGluZ0Zyb21FbCwgY3VyVG9Ob2RlQ2hpbGQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2Y
1XIgb25CZWZvcmVOb2RlQWRkZWRSZXN1bHQgPSBvbkJlZm9yZU5vZGVBZGRlZChjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgICBpZiAob25CZWZvcmVOb2RlQWRkZWRSZXN1bHQgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgIGlmIChvbkJlZm9yZU5vZGVBZGRlZFJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGN1clRvTm9kZUNoaWxkID0gb25CZWZvcmVOb2RlQWRkZWRSZXN1bHQ7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGN1clRvTm9kZUNoaWxkLmFjdHVhbGl6ZSkge1xuICAgICAgICAgICAgICAgIGN1clRvTm9kZUNoaWxkID0gY3VyVG9Ob2RlQ2hpbGQuYWN0dWFsaXplKGZyb21FbC5vd25lckRvY3VtZW50IHx8IGRvYyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYWRkQ2hpbGQoZnJvbUVsLCBjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgICAgIGhhbmRsZU5vZGVBZGRlZChjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGN1clRvTm9kZUNoaWxkID0gdG9OZXh0U2libGluZztcbiAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gZnJvbU5leHRTaWJsaW5nO1xuICAgICAgICB9XG4gICAgICBjbGVhbnVwRnJvbUVsKGZyb21FbCwgY3VyRnJvbU5vZGVDaGlsZCwgY3VyRnJvbU5vZGVLZXkpO1xuICAgICAgdmFyIHNwZWNpYWxFbEhhbmRsZXIgPSBzcGVjaWFsRWxIYW5kbGVyc1tmcm9tRWwubm9kZU5hbWVdO1xuICAgICAgaWYgKHNwZWNpYWxFbEhhbmRsZXIpIHtcbiAgICAgICAgc3BlY2lhbEVsSGFuZGxlcihmcm9tRWwsIHRvRWwpO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgbW9ycGhlZE5vZGUgPSBmcm9tTm9kZTtcbiAgICB2YXIgbW9ycGhlZE5vZGVUeXBlID0gbW9ycGhlZE5vZGUubm9kZVR5cGU7XG4gICAgdmFyIHRvTm9kZVR5cGUgPSB0b05vZGUubm9kZVR5cGU7XG4gICAgaWYgKCFjaGlsZHJlbk9ubHkpIHtcbiAgICAgIGlmIChtb3JwaGVkTm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSkge1xuICAgICAgICBpZiAodG9Ob2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgaWYgKCFjb21wYXJlTm9kZU5hbWVzKGZyb21Ob2RlLCB0b05vZGUpKSB7XG4gICAgICAgICAgICBvbk5vZGVEaXNjYXJkZWQoZnJvbU5vZGUpO1xuICAgICAgICAgICAgbW9ycGhlZE5vZGUgPSBtb3ZlQ2hpbGRyZW4oZnJvbU5vZGUsIGNyZWF0ZUVsZW1lbnROUyh0b05vZGUubm9kZU5hbWUsIHRvTm9kZS5uYW1lc3BhY2VVUkkpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbW9ycGhlZE5vZGUgPSB0b05vZGU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobW9ycGhlZE5vZGVUeXBlID09PSBURVhUX05PREUgfHwgbW9ycGhlZE5vZGVUeXBlID09PSBDT01NRU5UX05PREUpIHtcbiAgICAgICAgaWYgKHRvTm9kZVR5cGUgPT09IG1vcnBoZWROb2RlVHlwZSkge1xuICAgICAgICAgIGlmIChtb3JwaGVkTm9kZS5ub2RlVmFsdWUgIT09IHRvTm9kZS5ub2RlVmFsdWUpIHtcbiAgICAgICAgICAgIG1vcnBoZWROb2RlLm5vZGVWYWx1ZSA9IHRvTm9kZS5ub2RlVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBtb3JwaGVkTm9kZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtb3JwaGVkTm9kZSA9IHRvTm9kZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAobW9ycGhlZE5vZGUgPT09IHRvTm9kZSkge1xuICAgICAgb25Ob2RlRGlzY2FyZGVkKGZyb21Ob2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRvTm9kZS5pc1NhbWVOb2RlICYmIHRvTm9kZS5pc1NhbWVOb2RlKG1vcnBoZWROb2RlKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBtb3JwaEVsKG1vcnBoZWROb2RlLCB0b05vZGUsIGNoaWxkcmVuT25seSk7XG4gICAgICBpZiAoa2V5ZWRSZW1vdmFsTGlzdCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0ga2V5ZWRSZW1vdmFsTGlzdC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgIHZhciBlbFRvUmVtb3ZlID0gZnJvbU5vZGVzTG9va3VwW2tleWVkUmVtb3ZhbExpc3RbaV1dO1xuICAgICAgICAgIGlmIChlbFRvUmVtb3ZlKSB7XG4gICAgICAgICAgICByZW1vdmVOb2RlKGVsVG9SZW1vdmUsIGVsVG9SZW1vdmUucGFyZW50Tm9kZSwgZmFsc2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWNoaWxkcmVuT25seSAmJiBtb3JwaGVkTm9kZSAhPT0gZnJvbU5vZGUgJiYgZnJvbU5vZGUucGFyZW50Tm9kZSkge1xuICAgICAgaWYgKG1vcnBoZWROb2RlLmFjdHVhbGl6ZSkge1xuICAgICAgICBtb3JwaGVkTm9kZSA9IG1vcnBoZWROb2RlLmFjdHVhbGl6ZShmcm9tTm9kZS5vd25lckRvY3VtZW50IHx8IGRvYyk7XG4gICAgICB9XG4gICAgICBmcm9tTm9kZS5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChtb3JwaGVkTm9kZSwgZnJvbU5vZGUpO1xuICAgIH1cbiAgICByZXR1cm4gbW9ycGhlZE5vZGU7XG4gIH07XG59XG52YXIgbW9ycGhkb20gPSBtb3JwaGRvbUZhY3RvcnkobW9ycGhBdHRycyk7XG52YXIgbW9ycGhkb21fZXNtX2RlZmF1bHQgPSBtb3JwaGRvbTtcblxuLy8ganMvcGhvZW5peF9saXZlX3ZpZXcvZG9tX3BhdGNoLnRzXG52YXIgRE9NUGF0Y2ggPSBjbGFzcyB7XG4gIGNvbnN0cnVjdG9yKHZpZXcsIGNvbnRhaW5lciwgaHRtbCwgc3RyZWFtcywgdGFyZ2V0Q0lELCBvcHRzID0ge30pIHtcbiAgICB0aGlzLnZpZXcgPSB2aWV3O1xuICAgIHRoaXMubGl2ZVNvY2tldCA9IHZpZXcubGl2ZVNvY2tldDtcbiAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICB0aGlzLnJvb3RJRCA9IHZpZXcucm9vdC5pZDtcbiAgICB0aGlzLmh0bWwgPSBodG1sO1xuICAgIHRoaXMuc3RyZWFtcyA9IHN0cmVhbXM7XG4gICAgdGhpcy5zdHJlYW1JbnNlcnRzID0ge307XG4gICAgdGhpcy5zdHJlYW1Db21wb25lbnRSZXN0b3JlID0ge307XG4gICAgdGhpcy50YXJnZXRDSUQgPSB0YXJnZXRDSUQ7XG4gICAgdGhpcy5wZW5kaW5nUmVtb3ZlcyA9IFtdO1xuICAgIHRoaXMucGh4UmVtb3ZlID0gdGhpcy5saXZlU29ja2V0LmJpbmRpbmcoXCJyZW1vdmVcIik7XG4gICAgdGhpcy50YXJnZXRDb250YWluZXIgPSB0YXJnZXRDSUQgPyBkb21fZGVmYXVsdC5nZXRDb21wb25lbnQodGhpcy52aWV3LmlkLCB0YXJnZXRDSUQpIDogY29udGFpbmVyO1xuICAgIHRoaXMuYmVmb3JlVXBkYXRlZENhbGxiYWNrcyA9IFtdO1xuICAgIHRoaXMuYWZ0ZXJBZGRlZENhbGxiYWNrcyA9IFtdO1xuICAgIHRoaXMuYWZ0ZXJVcGRhdGVkQ2FsbGJhY2tzID0gW107XG4gICAgdGhpcy5hZnRlclBoeENoaWxkQWRkZWRDYWxsYmFja3MgPSBbXTtcbiAgICB0aGlzLmFmdGVyRGlzY2FyZGVkQ2FsbGJhY2tzID0gW107XG4gICAgdGhpcy5hZnRlclRyYW5zaXRpb25zRGlzY2FyZGVkQ2FsbGJhY2tzID0gW107XG4gICAgdGhpcy53aXRoQ2hpbGRyZW4gPSBvcHRzLndpdGhDaGlsZHJlbiB8fCBvcHRzLnVuZG9SZWYgIT09IHZvaWQgMCB8fCBmYWxzZTtcbiAgICB0aGlzLnVuZG9SZWYgPSBvcHRzLnVuZG9SZWYgPz8gbnVsbDtcbiAgfVxuICBiZWZvcmVVcGRhdGVkKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5iZWZvcmVVcGRhdGVkQ2FsbGJhY2tzLnB1c2goY2FsbGJhY2spO1xuICB9XG4gIGFmdGVyQWRkZWQoY2FsbGJhY2spIHtcbiAgICB0aGlzLmFmdGVyQWRkZWRDYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gIH1cbiAgYWZ0ZXJVcGRhdGVkKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5hZnRlclVwZGF0ZWRDYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gIH1cbiAgYWZ0ZXJQaHhDaGlsZEFkZGVkKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5hZnRlclBoeENoaWxkQWRkZWRDYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gIH1cbiAgYWZ0ZXJEaXNjYXJkZWQoY2FsbGJhY2spIHtcbiAgICB0aGlzLmFmdGVyRGlzY2FyZGVkQ2FsbGJhY2tzLnB1c2goY2FsbGJhY2spO1xuICB9XG4gIGFmdGVyVHJhbnNpdGlvbnNEaXNjYXJkZWQoY2FsbGJhY2spIHtcbiAgICB0aGlzLmFmdGVyVHJhbnNpdGlvbnNEaXNjYXJkZWRDYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gIH1cbiAgbWFya1BydW5hYmxlQ29udGVudEZvclJlbW92YWwoKSB7XG4gICAgY29uc3QgcGh4VXBkYXRlID0gdGhpcy5saXZlU29ja2V0LmJpbmRpbmcoUEhYX1VQREFURSk7XG4gICAgZG9tX2RlZmF1bHQuYWxsKFxuICAgICAgdGhpcy5jb250YWluZXIsXG4gICAgICBgWyR7cGh4VXBkYXRlfT1hcHBlbmRdID4gKiwgWyR7cGh4VXBkYXRlfT1wcmVwZW5kXSA+ICpgLFxuICAgICAgKGVsKSA9PiB7XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShQSFhfUFJVTkUsIFwiXCIpO1xuICAgICAgfVxuICAgICk7XG4gIH1cbiAgcGVyZm9ybShpc0pvaW5QYXRjaCkge1xuICAgIGNvbnN0IHsgdmlldywgbGl2ZVNvY2tldCwgaHRtbCwgY29udGFpbmVyIH0gPSB0aGlzO1xuICAgIGxldCB0YXJnZXRDb250YWluZXIgPSB0aGlzLnRhcmdldENvbnRhaW5lcjtcbiAgICBpZiAodGhpcy50YXJnZXRDSUQpIHtcbiAgICAgIGNvbnN0IGNsb3Nlc3RMb2NrID0gdGFyZ2V0Q29udGFpbmVyLmNsb3Nlc3QoYFske1BIWF9SRUZfTE9DS31dYCk7XG4gICAgICBpZiAoY2xvc2VzdExvY2sgJiYgIWNsb3Nlc3RMb2NrLmlzU2FtZU5vZGUodGFyZ2V0Q29udGFpbmVyKSkge1xuICAgICAgICBjb25zdCBjbG9uZWRUcmVlID0gZG9tX2RlZmF1bHQucHJpdmF0ZShjbG9zZXN0TG9jaywgUEhYX1JFRl9MT0NLKTtcbiAgICAgICAgaWYgKGNsb25lZFRyZWUpIHtcbiAgICAgICAgICB0YXJnZXRDb250YWluZXIgPSBjbG9uZWRUcmVlLnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgICBgW2RhdGEtcGh4LWNvbXBvbmVudD1cIiR7dGhpcy50YXJnZXRDSUR9XCJdYFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKCF0YXJnZXRDb250YWluZXIpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgI
1H1cbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgZm9jdXNlZCA9IGxpdmVTb2NrZXQuZ2V0QWN0aXZlRWxlbWVudCgpO1xuICAgIGNvbnN0IHsgc2VsZWN0aW9uU3RhcnQsIHNlbGVjdGlvbkVuZCB9ID0gZm9jdXNlZCAmJiBkb21fZGVmYXVsdC5oYXNTZWxlY3Rpb25SYW5nZShmb2N1c2VkKSA/IGZvY3VzZWQgOiB7fTtcbiAgICBjb25zdCBwaHhVcGRhdGUgPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX1VQREFURSk7XG4gICAgY29uc3QgcGh4Vmlld3BvcnRUb3AgPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX1ZJRVdQT1JUX1RPUCk7XG4gICAgY29uc3QgcGh4Vmlld3BvcnRCb3R0b20gPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX1ZJRVdQT1JUX0JPVFRPTSk7XG4gICAgY29uc3QgcGh4VHJpZ2dlckV4dGVybmFsID0gbGl2ZVNvY2tldC5iaW5kaW5nKFBIWF9UUklHR0VSX0FDVElPTik7XG4gICAgY29uc3QgYWRkZWQgPSBbXTtcbiAgICBjb25zdCB1cGRhdGVzID0gW107XG4gICAgY29uc3QgYXBwZW5kUHJlcGVuZFVwZGF0ZXMgPSBbXTtcbiAgICBsZXQgcG9ydGFsQ2FsbGJhY2tzID0gW107XG4gICAgbGV0IGV4dGVybmFsRm9ybVRyaWdnZXJlZCA9IG51bGw7XG4gICAgY29uc3QgbW9ycGggPSAodGFyZ2V0Q29udGFpbmVyMiwgc291cmNlLCB3aXRoQ2hpbGRyZW4gPSB0aGlzLndpdGhDaGlsZHJlbikgPT4ge1xuICAgICAgY29uc3QgbW9ycGhDYWxsYmFja3MgPSB7XG4gICAgICAgIC8vIG5vcm1hbGx5LCB3ZSBhcmUgcnVubmluZyB3aXRoIGNoaWxkcmVuT25seSwgYXMgdGhlIHBhdGNoIEhUTUwgZm9yIGEgTFZcbiAgICAgICAgLy8gZG9lcyBub3QgaW5jbHVkZSB0aGUgTFYgYXR0cnMgKGRhdGEtcGh4LXNlc3Npb24sIGV0Yy4pXG4gICAgICAgIC8vIHdoZW4gd2UgYXJlIHBhdGNoaW5nIGEgbGl2ZSBjb21wb25lbnQsIHdlIGRvIHdhbnQgdG8gcGF0Y2ggdGhlIHJvb3QgZWxlbWVudCBhcyB3ZWxsO1xuICAgICAgICAvLyBhbm90aGVyIGNhc2UgaXMgdGhlIHJlY3Vyc2l2ZSBwYXRjaCBvZiBhIHN0cmVhbSBpdGVtIHRoYXQgd2FzIGtlcHQgb24gcmVzZXQgKC0+IG9uQmVmb3JlTm9kZUFkZGVkKVxuICAgICAgICBjaGlsZHJlbk9ubHk6IHRhcmdldENvbnRhaW5lcjIuZ2V0QXR0cmlidXRlKFBIWF9DT01QT05FTlQpID09PSBudWxsICYmICF3aXRoQ2hpbGRyZW4sXG4gICAgICAgIGdldE5vZGVLZXk6IChub2RlKSA9PiB7XG4gICAgICAgICAgaWYgKCEobm9kZSBpbnN0YW5jZW9mIEVsZW1lbnQpKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgaWYgKGRvbV9kZWZhdWx0LmlzUGh4RGVzdHJveWVkKG5vZGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGlzSm9pblBhdGNoKSB7XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5pZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGRvbV9kZWZhdWx0LnByaXZhdGUobm9kZSwgXCJjbGllbnRzaWRlSWRBdHRyaWJ1dGVcIikpIHtcbiAgICAgICAgICAgIHJldHVybiBub2RlLmdldEF0dHJpYnV0ZShQSFhfTUFHSUNfSUQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbm9kZS5pZCB8fCBub2RlLmdldEF0dHJpYnV0ZShQSFhfTUFHSUNfSUQpO1xuICAgICAgICB9LFxuICAgICAgICAvLyBza2lwIGluZGV4aW5nIGZyb20gY2hpbGRyZW4gd2hlbiBjb250YWluZXIgaXMgc3RyZWFtXG4gICAgICAgIHNraXBGcm9tQ2hpbGRyZW46IChmcm9tKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGZyb20uZ2V0QXR0cmlidXRlKHBoeFVwZGF0ZSkgPT09IFBIWF9TVFJFQU07XG4gICAgICAgIH0sXG4gICAgICAgIC8vIHRlbGwgbW9ycGhkb20gaG93IHRvIGFkZCBhIGNoaWxkXG4gICAgICAgIGFkZENoaWxkOiAocGFyZW50LCBjaGlsZCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgcmVmLCBzdHJlYW1BdCB9ID0gdGhpcy5nZXRTdHJlYW1JbnNlcnQoY2hpbGQpO1xuICAgICAgICAgIGlmIChyZWYgPT09IHZvaWQgMCkge1xuICAgICAgICAgICAgcmV0dXJuIHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuc2V0U3RyZWFtUmVmKGNoaWxkLCByZWYpO1xuICAgICAgICAgIGlmIChzdHJlYW1BdCA9PT0gMCkge1xuICAgICAgICAgICAgcGFyZW50Lmluc2VydEFkamFjZW50RWxlbWVudChcImFmdGVyYmVnaW5cIiwgY2hpbGQpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoc3RyZWFtQXQgPT09IC0xKSB7XG4gICAgICAgICAgICBjb25zdCBsYXN0Q2hpbGQgPSBwYXJlbnQubGFzdEVsZW1lbnRDaGlsZDtcbiAgICAgICAgICAgIGlmIChsYXN0Q2hpbGQgJiYgIWxhc3RDaGlsZC5oYXNBdHRyaWJ1dGUoUEhYX1NUUkVBTV9SRUYpKSB7XG4gICAgICAgICAgICAgIGNvbnN0IG5vblN0cmVhbUNoaWxkID0gQXJyYXkuZnJvbShwYXJlbnQuY2hpbGRyZW4pLmZpbmQoXG4gICAgICAgICAgICAgICAgKGMpID0+ICFjLmhhc0F0dHJpYnV0ZShQSFhfU1RSRUFNX1JFRilcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgbm9uU3RyZWFtQ2hpbGQgPz8gbnVsbCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQoY2hpbGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoc3RyZWFtQXQgPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBzaWJsaW5nID0gQXJyYXkuZnJvbShwYXJlbnQuY2hpbGRyZW4pW3N0cmVhbUF0XTtcbiAgICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoY2hpbGQsIHNpYmxpbmcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgb25CZWZvcmVOb2RlQWRkZWQ6IChlbCkgPT4ge1xuICAgICAgICAgIGlmICghKGVsIGluc3RhbmNlb2YgRWxlbWVudCkpIHtcbiAgICAgICAgICAgIHJldHVybiBlbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHRoaXMuZ2V0U3RyZWFtSW5zZXJ0KGVsKT8udXBkYXRlT25seSAmJiAhdGhpcy5zdHJlYW1Db21wb25lbnRSZXN0b3JlW2VsLmlkXSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgI
1H1cbiAgICAgICAgICBkb21fZGVmYXVsdC5tYWludGFpblByaXZhdGVIb29rcyhlbCwgZWwsIHBoeFZpZXdwb3J0VG9wLCBwaHhWaWV3cG9ydEJvdHRvbSk7XG4gICAgICAgICAgbGV0IG1vcnBoZWRFbCA9IGVsO1xuICAgICAgICAgIGlmICh0aGlzLnN0cmVhbUNvbXBvbmVudFJlc3RvcmVbZWwuaWRdKSB7XG4gICAgICAgICAgICBtb3JwaGVkRWwgPSB0aGlzLnN0cmVhbUNvbXBvbmVudFJlc3RvcmVbZWwuaWRdO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtQ29tcG9uZW50UmVzdG9yZVtlbC5pZF07XG4gICAgICAgICAgICBtb3JwaChtb3JwaGVkRWwsIGVsLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG1vcnBoZWRFbDtcbiAgICAgICAgfSxcbiAgICAgICAgb25Ob2RlQWRkZWQ6IChlbCkgPT4ge1xuICAgICAgICAgIGlmICghKGVsIGluc3RhbmNlb2YgRWxlbWVudCkpIHtcbiAgICAgICAgICAgIGFkZGVkLnB1c2goZWwpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLm1heWJlUmVPcmRlclN0cmVhbShlbCwgdHJ1ZSk7XG4gICAgICAgICAgaWYgKGRvbV9kZWZhdWx0LmlzUG9ydGFsVGVtcGxhdGUoZWwpKSB7XG4gICAgICAgICAgICBwb3J0YWxDYWxsYmFja3MucHVzaCgoKSA9PiB0aGlzLnRlbGVwb3J0KGVsLCBtb3JwaCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZWwgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50ICYmIGVsLnNyY3NldCkge1xuICAgICAgICAgICAgZWwuc3Jjc2V0ID0gZWwuc3Jjc2V0O1xuICAgICAgICAgIH0gZWxzZSBpZiAoZWwgaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50ICYmIGVsLmF1dG9wbGF5KSB7XG4gICAgICAgICAgICBlbC5wbGF5KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChkb21fZGVmYXVsdC5pc05vd1RyaWdnZXJGb3JtRXh0ZXJuYWwoZWwsIHBoeFRyaWdnZXJFeHRlcm5hbCkpIHtcbiAgICAgICAgICAgIGV4dGVybmFsRm9ybVRyaWdnZXJlZCA9IGVsO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZG9tX2RlZmF1bHQuaXNQaHhDaGlsZChlbCkgJiYgdmlldy5vd25zRWxlbWVudChlbCkgfHwgZG9tX2RlZmF1bHQuaXNQaHhTdGlja3koZWwpICYmIHZpZXcub3duc0VsZW1lbnQoZWwucGFyZW50Tm9kZSkpIHtcbiAgICAgICAgICAgIHRoaXMudHJhY2tBZnRlclBoeENoaWxkQWRkZWQoZWwpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZWwubm9kZU5hbWUgPT09IFwiU0NSSVBUXCIgJiYgZWwuaGFzQXR0cmlidXRlKFBIWF9SVU5USU1FX0hPT0spKSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZVJ1bnRpbWVIb29rKGVsLCBzb3VyY2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBhZGRlZC5wdXNoKGVsKTtcbiAgICAgICAgfSxcbiAgICAgICAgb25Ob2RlRGlzY2FyZGVkOiAoZWwpID0+IHRoaXMub25Ob2RlRGlzY2FyZGVkKGVsKSxcbiAgICAgICAgb25CZWZvcmVOb2RlRGlzY2FyZGVkOiAoZWwpID0+IHtcbiAgICAgICAgICBpZiAoIShlbCBpbnN0YW5jZW9mIEVsZW1lbnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVsLmdldEF0dHJpYnV0ZShQSFhfUFJVTkUpICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVsLnBhcmVudEVsZW1lbnQgIT09IG51bGwgJiYgZWwuaWQgJiYgZG9tX2RlZmF1bHQuaXNQaHhVcGRhdGUoZWwucGFyZW50RWxlbWVudCwgcGh4VXBkYXRlLCBbXG4gICAgICAgICAgICBQSFhfU1RSRUFNLFxuICAgICAgICAgICAgXCJhcHBlbmRcIixcbiAgICAgICAgICAgIFwicHJlcGVuZFwiXG4gICAgICAgICAgXSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVsLmdldEF0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9SRUYpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0aGlzLm1heWJlUGVuZGluZ1JlbW92ZShlbCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHRoaXMuc2tpcENJRFNpYmxpbmcoZWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChkb21fZGVmYXVsdC5pc1BvcnRhbFRlbXBsYXRlKGVsKSkge1xuICAgICAgICAgICAgY29uc3QgdGVsZXBvcnRlZEVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXG4gICAgICAgICAgICAgIGVsLmNvbnRlbnQuZmlyc3RFbGVtZW50Q2hpbGQ/LmlkIHx8IFwiXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAodGVsZXBvcnRlZEVsKSB7XG4gICAgICAgICAgICAgIHRlbGVwb3J0ZWRFbC5yZW1vdmUoKTtcbiAgICAgICAgICAgICAgbW9ycGhDYWxsYmFja3Mub25Ob2RlRGlzY2FyZGVkKHRlbGVwb3J0ZWRFbCk7XG4gICAgICAgICAgICAgIHRoaXMudmlldy5kcm9wUG9ydGFsRWxlbWVudElkKHRlbGVwb3J0ZWRFbC5pZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9LFxuICAgICAgICBvbkVsVXBkYXRlZDogKGVsKSA9PiB7XG4gICAgICAgICAgaWYgKGRvbV9kZWZhdWx0LmlzTm93VHJpZ2dlckZvcm1FeHRlcm5hbChlbCwgcGh4VHJpZ2dlckV4dGVybmFsKSkge1xuICAgICAgICAgICAgZXh0ZXJuYWxGb3JtVHJpZ2dlcmVkID0gZWw7XG4gICAgICAgICAgfVxuICAgICAgICAgIHVwZGF0ZXMucHVzaChlbCk7XG4gICAgICAgICAgdGhpcy5tYXliZVJlT3JkZXJTdHJlYW0oZWwsIGZhbHNlKTtcbiAgICAgICAgfSxcbiAgICAgICAgb25CZWZvcmVFbFVwZGF0ZWQ6IChmcm9tRWwsIHRvRWwpID0+IHtcbiAgICAgICAgICBpZiAoZnJvbUVsLmlkICYmIGZyb21FbC5pc1NhbWVOb2RlKHRhcmdldENvbnRhaW5lcjIpICYmIGZyb21FbC5pZCAhPT0gdG9FbC5pZCkge1xuICAgICAgICAgICAgbW9ycGhDYWxsYmFja3Mub25Ob2RlRGlzY2FyZGVkKGZyb21FbCk7XG4gICAgICAgICAgICBmcm9tRWwucmVwbGFjZVdpdGgodG9FbCk7XG4gICAgICAgICAgICByZXR1cm4gbW9ycGhDYWxsYmFja3Mub25Ob2RlQWRkZWQodG9FbCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRvbV9kZWZhdWx0LnN5bmNQZW5kaW5nQXR0cnMoZnJvbUVsLCB0b0VsKTtcbiAgICAgICAgICBkb21fZGVmYXVsdC5tYWludGFpblByaXZhdGVIb29rcyhcbiAgICAgICAgICAgIGZyb21FbCxcbiAgICAgICAgICAgI
1HRvRWwsXG4gICAgICAgICAgICBwaHhWaWV3cG9ydFRvcCxcbiAgICAgICAgICAgIHBoeFZpZXdwb3J0Qm90dG9tXG4gICAgICAgICAgKTtcbiAgICAgICAgICBkb21fZGVmYXVsdC5jbGVhbkNoaWxkTm9kZXModG9FbCwgcGh4VXBkYXRlKTtcbiAgICAgICAgICBjb25zdCBpc0ZvY3VzZWRGb3JtRWwgPSBmb2N1c2VkICYmIGZyb21FbC5pc1NhbWVOb2RlKGZvY3VzZWQpICYmIGRvbV9kZWZhdWx0LmlzRWRpdGFibGVJbnB1dChmcm9tRWwpO1xuICAgICAgICAgIGNvbnN0IGZvY3VzZWRTZWxlY3RDaGFuZ2VkID0gaXNGb2N1c2VkRm9ybUVsICYmIHRoaXMuaXNDaGFuZ2VkU2VsZWN0KGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgaWYgKHRoaXMuc2tpcENJRFNpYmxpbmcodG9FbCkpIHtcbiAgICAgICAgICAgIHRoaXMubWF5YmVDbG9uZUxvY2tlZEVsZW1lbnQoZnJvbUVsLCBpc0ZvY3VzZWRGb3JtRWwpO1xuICAgICAgICAgICAgdGhpcy5jb3B5TmVzdGVkUHJpdmF0ZUxvY2soZnJvbUVsLCB0b0VsKTtcbiAgICAgICAgICAgIHRoaXMubWF5YmVSZU9yZGVyU3RyZWFtKGZyb21FbCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChkb21fZGVmYXVsdC5pc1BoeFN0aWNreShmcm9tRWwpKSB7XG4gICAgICAgICAgICBbUEhYX1NFU1NJT04sIFBIWF9TVEFUSUMsIFBIWF9ST09UX0lEXS5tYXAoKGF0dHIpID0+IFtcbiAgICAgICAgICAgICAgYXR0cixcbiAgICAgICAgICAgICAgZnJvbUVsLmdldEF0dHJpYnV0ZShhdHRyKSxcbiAgICAgICAgICAgICAgdG9FbC5nZXRBdHRyaWJ1dGUoYXR0cilcbiAgICAgICAgICAgIF0pLmZvckVhY2goKFthdHRyLCBmcm9tVmFsLCB0b1ZhbF0pID0+IHtcbiAgICAgICAgICAgICAgaWYgKHRvVmFsICYmIGZyb21WYWwgIT09IHRvVmFsKSB7XG4gICAgICAgICAgICAgICAgZnJvbUVsLnNldEF0dHJpYnV0ZShhdHRyLCB0b1ZhbCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZG9tX2RlZmF1bHQuaXNJZ25vcmVkKGZyb21FbCwgcGh4VXBkYXRlKSB8fCBmcm9tRWwuZm9ybSAmJiBmcm9tRWwuZm9ybS5pc1NhbWVOb2RlKGV4dGVybmFsRm9ybVRyaWdnZXJlZCkpIHtcbiAgICAgICAgICAgIHRoaXMudHJhY2tCZWZvcmVVcGRhdGVkKGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgICBkb21fZGVmYXVsdC5tZXJnZUF0dHJzKGZyb21FbCwgdG9FbCwge1xuICAgICAgICAgICAgICBpc0lnbm9yZWQ6IGRvbV9kZWZhdWx0LmlzSWdub3JlZChmcm9tRWwsIHBoeFVwZGF0ZSlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdXBkYXRlcy5wdXNoKGZyb21FbCk7XG4gICAgICAgICAgICBkb21fZGVmYXVsdC5hcHBseVN0aWNreU9wZXJhdGlvbnMoZnJvbUVsKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGZyb21FbC50eXBlID09PSBcIm51bWJlclwiICYmIGZyb21FbC52YWxpZGl0eSAmJiBmcm9tRWwudmFsaWRpdHkuYmFkSW5wdXQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZnJvbUVsID0gdGhpcy5tYXliZUNsb25lTG9ja2VkRWxlbWVudChmcm9tRWwsIGlzRm9jdXNlZEZvcm1FbCk7XG4gICAgICAgICAgaWYgKGRvbV9kZWZhdWx0LmlzUGh4Q2hpbGQodG9FbCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZTZXNzaW9uID0gZnJvbUVsLmdldEF0dHJpYnV0ZShQSFhfU0VTU0lPTik7XG4gICAgICAgICAgICBkb21fZGVmYXVsdC5tZXJnZUF0dHJzKGZyb21FbCwgdG9FbCwgeyBleGNsdWRlOiBbUEhYX1NUQVRJQ10gfSk7XG4gICAgICAgICAgICBpZiAocHJldlNlc3Npb24gIT09IFwiXCIpIHtcbiAgICAgICAgICAgICAgZnJvbUVsLnNldEF0dHJpYnV0ZShQSFhfU0VTU0lPTiwgcHJldlNlc3Npb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZnJvbUVsLnNldEF0dHJpYnV0ZShQSFhfUk9PVF9JRCwgdGhpcy5yb290SUQpO1xuICAgICAgICAgICAgZG9tX2RlZmF1bHQuYXBwbHlTdGlja3lPcGVyYXRpb25zKGZyb21FbCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuY29weU5lc3RlZFByaXZhdGVMb2NrKGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgZG9tX2RlZmF1bHQuY29weVByaXZhdGVzKHRvRWwsIGZyb21FbCk7XG4gICAgICAgICAgaWYgKGRvbV9kZWZhdWx0LmlzUG9ydGFsVGVtcGxhdGUodG9FbCkpIHtcbiAgICAgICAgICAgIHBvcnRhbENhbGxiYWNrcy5wdXNoKCgpID0+IHRoaXMudGVsZXBvcnQodG9FbCwgbW9ycGgpKTtcbiAgICAgICAgICAgIGZyb21FbC5jb250ZW50LnJlcGxhY2VDaGlsZHJlbih0b0VsLmNvbnRlbnQuY2xvbmVOb2RlKHRydWUpKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGlzRm9jdXNlZEZvcm1FbCAmJiBmcm9tRWwud
1HlwZSAhPT0gXCJoaWRkZW5cIiAmJiAhZm9jdXNlZFNlbGVjdENoYW5nZWQpIHtcbiAgICAgICAgICAgIHRoaXMudHJhY2tCZWZvcmVVcGRhdGVkKGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgICBkb21fZGVmYXVsdC5tZXJnZUZvY3VzZWRJbnB1dChmcm9tRWwsIHRvRWwpO1xuICAgICAgICAgICAgZG9tX2RlZmF1bHQuc3luY0F0dHJzVG9Qcm9wcyhmcm9tRWwpO1xuICAgICAgICAgICAgdXBkYXRlcy5wdXNoKGZyb21FbCk7XG4gICAgICAgICAgICBkb21fZGVmYXVsdC5hcHBseVN0aWNreU9wZXJhdGlvbnMoZnJvbUVsKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGZvY3VzZWRTZWxlY3RDaGFuZ2VkKSB7XG4gICAgICAgICAgICAgIGZyb21FbC5ibHVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZG9tX2RlZmF1bHQuaXNQaHhVcGRhdGUodG9FbCwgcGh4VXBkYXRlLCBbXCJhcHBlbmRcIiwgXCJwcmVwZW5kXCJdKSkge1xuICAgICAgICAgICAgICBhcHBlbmRQcmVwZW5kVXBkYXRlcy5wdXNoKFxuICAgICAgICAgICAgICAgIG5ldyBET01Qb3N0TW9ycGhSZXN0b3JlcihcbiAgICAgICAgICAgICAgICAgIGZyb21FbCxcbiAgICAgICAgICAgICAgICAgIHRvRWwsXG4gICAgICAgICAgICAgICAgICB0b0VsLmdldEF0dHJpYnV0ZShwaHhVcGRhdGUpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZG9tX2RlZmF1bHQuc3luY0F0dHJzVG9Qcm9wcyh0b0VsKTtcbiAgICAgICAgICAgIGRvbV9kZWZhdWx0LmFwcGx5U3RpY2t5T3BlcmF0aW9ucyh0b0VsKTtcbiAgICAgICAgICAgIHRoaXMudHJhY2tCZWZvcmVVcGRhdGVkKGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgICByZXR1cm4gZnJvbUVsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIG1vcnBoZG9tX2VzbV9kZWZhdWx0KHRhcmdldENvbnRhaW5lcjIsIHNvdXJjZSwgbW9ycGhDYWxsYmFja3MpO1xuICAgIH07XG4gICAgdGhpcy50cmFja0JlZm9yZVVwZGF0ZWQoY29udGFpbmVyLCBjb250YWluZXIpO1xuICAgIGxpdmVTb2NrZXQudGltZShcIm1vcnBoZG9tXCIsICgpID0+IHtcbiAgICAgIHRoaXMuc3RyZWFtcy5mb3JFYWNoKChbcmVmLCBpbnNlcnRzLCBkZWxldGVJZHMsIHJlc2V0XSkgPT4ge1xuICAgICAgICBpbnNlcnRzLmZvckVhY2goKFtrZXksIHN0cmVhbUF0LCBsaW1pdCwgdXBkYXRlT25seV0pID0+IHtcbiAgICAgICAgICB0aGlzLnN0cmVhbUluc2VydHNba2V5XSA9IHsgcmVmLCBzdHJlYW1BdCwgbGltaXQsIHJlc2V0LCB1cGRhdGVPbmx5IH07XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzZXQgIT09IHZvaWQgMCkge1xuICAgICAgICAgIGRvbV9kZWZhdWx0LmFsbChkb2N1bWVudCwgYFske1BIWF9TVFJFQU1fUkVGfT1cIiR7cmVmfVwiXWAsIChjaGlsZCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGRlbGV0ZUlkcy5mb3JFYWNoKChpZCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNoaWxkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgICAgICAgIGlmIChjaGlsZCkge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGlmIChpc0pvaW5QYXRjaCkge1xuICAgICAgICBkb21fZGVmYXVsdC5hbGwodGhpcy5jb250YWluZXIsIGBbJHtwaHhVcGRhdGV9PSR7UEhYX1NUUkVBTX1dYCkuZmlsdGVyKChlbCkgPT4gdGhpcy52aWV3Lm93bnNFbGVtZW50KGVsKSkuZm9yRWFjaCgoZWwpID0+IHtcbiAgICAgICAgICBBcnJheS5mcm9tKGVsLmNoaWxkcmVuKS5mb3JFYWNoKChjaGlsZCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQsIHRydWUpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIG1vcnBoKHRhcmdldENvbnRhaW5lciwgaHRtbCk7XG4gICAgICBsZXQgdGVsZXBvcnRDb3VudCA9IDA7XG4gICAgICB3aGlsZSAocG9ydGFsQ2FsbGJhY2tzLmxlbmd0aCA+IDAgJiYgdGVsZXBvcnRDb3VudCA8IDUpIHtcbiAgICAgICAgY29uc3QgY29weSA9IHBvcnRhbENhbGxiYWNrcy5zbGljZSgpO1xuICAgICAgICBwb3J0YWxDYWxsYmFja3MgPSBbXTtcbiAgICAgICAgY29weS5mb3JFYWNoKChjYWxsYmFjaykgPT4gY2FsbGJhY2soKSk7XG4gICAgICAgIHRlbGVwb3J0Q291bnQrKztcbiAgICAgIH1cbiAgICAgIHRoaXMudmlldy5wb3J0YWxFbGVtZW50SWRzLmZvckVhY2goKGlkKSA9PiB7XG4gICAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgICAgICBpZiAoZWwpIHtcbiAgICAgICAgICBjb25zdCBzcmNJZCA9IGVsLmdldEF0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9TUkMpO1xuICAgICAgICAgIGlmIChzcmNJZCkge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc3JjSWQpO1xuICAgICAgICAgICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgICAgICAgICAgZWwucmVtb3ZlKCk7XG4gICAgICAgICAgICAgIHRoaXMub25Ob2RlRGlzY2FyZGVkKGVsKTtcbiAgICAgICAgICAgICAgdGhpcy52aWV3LmRyb3BQb3J0YWxFbGVtZW50SWQoaWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaWYgKGxpdmVTb2NrZXQuaXNEZWJ1Z0VuYWJsZWQoKSkge1xuICAgICAgZGV0ZWN0RHVwbGljYXRlSWRzKCk7XG4gICAgICBkZXRlY3RJbnZhbGlkU3RyZWFtSW5zZXJ0cyh0aGlzLnN0cmVhbUluc2VydHMpO1xuICAgICAgQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiaW5wdXRbbmFtZT1pZF1cIikpLmZvckVhY2goXG4gICAgICAgIChub2RlKSA9PiB7XG4gICAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50ICYmIG5vZGUuZm9ybSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICAgICAgJ0RldGVjdGVkIGFuIGlucHV0IHdpdGggbmFtZT1cImlkXCIgaW5zaWRlIGEgZm9ybSEgVGhpcyB3aWxsIGNhdXNlIHByb2JsZW1zIHdoZW4gcGF0Y2hpbmcgdGhlIERPTS5cXG4nLFxuICAgICAgICAgICAgICBub2RlXG4gICAgICAgICAgICApO1xuICAgICAgICAgI
1H1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKGFwcGVuZFByZXBlbmRVcGRhdGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGxpdmVTb2NrZXQudGltZShcInBvc3QtbW9ycGggYXBwZW5kL3ByZXBlbmQgcmVzdG9yYXRpb25cIiwgKCkgPT4ge1xuICAgICAgICBhcHBlbmRQcmVwZW5kVXBkYXRlcy5mb3JFYWNoKCh1cGRhdGUpID0+IHVwZGF0ZS5wZXJmb3JtKCkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGxpdmVTb2NrZXQuc2lsZW5jZUV2ZW50cyhcbiAgICAgICgpID0+IGRvbV9kZWZhdWx0LnJlc3RvcmVGb2N1cyhmb2N1c2VkLCBzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kKVxuICAgICk7XG4gICAgZG9tX2RlZmF1bHQuZGlzcGF0Y2hFdmVudChkb2N1bWVudCwgXCJwaHg6dXBkYXRlXCIpO1xuICAgIGFkZGVkLmZvckVhY2goKGVsKSA9PiB0aGlzLnRyYWNrQWZ0ZXJBZGRlZChlbCkpO1xuICAgIHVwZGF0ZXMuZm9yRWFjaCgoZWwpID0+IHRoaXMudHJhY2tBZnRlclVwZGF0ZWQoZWwpKTtcbiAgICB0aGlzLnRyYW5zaXRpb25QZW5kaW5nUmVtb3ZlcygpO1xuICAgIGlmIChleHRlcm5hbEZvcm1UcmlnZ2VyZWQpIHtcbiAgICAgIGxpdmVTb2NrZXQudW5sb2FkKCk7XG4gICAgICBjb25zdCBzdWJtaXR0ZXIgPSBkb21fZGVmYXVsdC5wcml2YXRlKGV4dGVybmFsRm9ybVRyaWdnZXJlZCwgXCJzdWJtaXR0ZXJcIik7XG4gICAgICBpZiAoc3VibWl0dGVyICYmIHN1Ym1pdHRlci5uYW1lICYmIHRhcmdldENvbnRhaW5lci5jb250YWlucyhzdWJtaXR0ZXIpKSB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlucHV0XCIpO1xuICAgICAgICBpbnB1dC50eXBlID0gXCJoaWRkZW5cIjtcbiAgICAgICAgY29uc3QgZm9ybUlkID0gc3VibWl0dGVyLmdldEF0dHJpYnV0ZShcImZvcm1cIik7XG4gICAgICAgIGlmIChmb3JtSWQpIHtcbiAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoXCJmb3JtXCIsIGZvcm1JZCk7XG4gICAgICAgIH1cbiAgICAgICAgaW5wdXQubmFtZSA9IHN1Ym1pdHRlci5uYW1lO1xuICAgICAgICBpbnB1dC52YWx1ZSA9IHN1Ym1pdHRlci52YWx1ZTtcbiAgICAgICAgc3VibWl0dGVyLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKGlucHV0LCBzdWJtaXR0ZXIpO1xuICAgICAgfVxuICAgICAgT2JqZWN0LmdldFByb3RvdHlwZU9mKGV4dGVybmFsRm9ybVRyaWdnZXJlZCkuc3VibWl0LmNhbGwoXG4gICAgICAgIGV4dGVybmFsRm9ybVRyaWdnZXJlZFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgdHJhY2tCZWZvcmVVcGRhdGVkKGZyb21FbCwgdG9FbCkge1xuICAgIHRoaXMuYmVmb3JlVXBkYXRlZENhbGxiYWNrcy5mb3JFYWNoKChjYikgPT4gY2IoZnJvbUVsLCB0b0VsKSk7XG4gIH1cbiAgdHJhY2tBZnRlckFkZGVkKGVsKSB7XG4gICAgdGhpcy5hZnRlckFkZGVkQ2FsbGJhY2tzLmZvckVhY2goKGNiKSA9PiBjYihlbCkpO1xuICB9XG4gIHRyYWNrQWZ0ZXJVcGRhdGVkKGVsKSB7XG4gICAgdGhpcy5hZnRlclVwZGF0ZWRDYWxsYmFja3MuZm9yRWFjaCgoY2IpID0+IGNiKGVsKSk7XG4gIH1cbiAgdHJhY2tBZnRlclBoeENoaWxkQWRkZWQoZWwpIHtcbiAgICB0aGlzLmFmdGVyUGh4Q2hpbGRBZGRlZENhbGxiYWNrcy5mb3JFYWNoKChjYikgPT4gY2IoZWwpKTtcbiAgfVxuICB0cmFja0FmdGVyRGlzY2FyZGVkKGVsKSB7XG4gICAgdGhpcy5hZnRlckRpc2NhcmRlZENhbGxiYWNrcy5mb3JFYWNoKChjYikgPT4gY2IoZWwpKTtcbiAgfVxuICB0cmFja0FmdGVyVHJhbnNpdGlvbnNEaXNjYXJkZWQoZWxzKSB7XG4gICAgdGhpcy5hZnRlclRyYW5zaXRpb25zRGlzY2FyZGVkQ2FsbGJhY2tzLmZvckVhY2goKGNiKSA9PiBjYihlbHMpKTtcbiAgfVxuICBvbk5vZGVEaXNjYXJkZWQoZWwpIHtcbiAgICBpZiAoZG9tX2RlZmF1bHQuaXNQaHhDaGlsZChlbCkgfHwgZG9tX2RlZmF1bHQuaXNQaHhTdGlja3koZWwpKSB7XG4gICAgICB0aGlzLmxpdmVTb2NrZXQuZGVzdHJveVZpZXdCeUVsKGVsKTtcbiAgICB9XG4gICAgdGhpcy50cmFja0FmdGVyRGlzY2FyZGVkKGVsKTtcbiAgfVxuICBtYXliZVBlbmRpbmdSZW1vdmUobm9kZSkge1xuICAgIGlmIChub2RlLmdldEF0dHJpYnV0ZSAmJiBub2RlLmdldEF0dHJpYnV0ZSh0aGlzLnBoeFJlbW92ZSkgIT09IG51bGwpIHtcbiAgICAgIHRoaXMucGVuZGluZ1JlbW92ZXMucHVzaChub2RlKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJlbW92ZVN0cmVhbUNoaWxkRWxlbWVudChjaGlsZCwgZm9yY2UgPSBmYWxzZSkge1xuICAgIGlmICghZm9yY2UgJiYgIXRoaXMudmlldy5vd25zRWxlbWVudChjaGlsZCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuc3RyZWFtSW5zZXJ0c1tjaGlsZC5pZF0pIHtcbiAgICAgIHRoaXMuc3RyZWFtQ29tcG9uZW50UmVzdG9yZVtjaGlsZC5pZF0gPSBjaGlsZDtcbiAgICAgIGNoaWxkLnJlbW92ZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXRoaXMubWF5YmVQZW5kaW5nUmVtb3ZlKGNoaWxkKSkge1xuICAgICAgICBjaGlsZC5yZW1vdmUoKTtcbiAgICAgICAgdGhpcy5vbk5vZGVEaXNjYXJkZWQoY2hpbGQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBnZXRTdHJlYW1JbnNlcnQoZWwpIHtcbiAgICBjb25zdCBpbnNlcnQgPSBlbC5pZCA/IHRoaXMuc3RyZWFtSW5zZXJ0c1tlbC5pZF0gOiB7fTtcbiAgICByZXR1cm4gaW5zZXJ0IHx8IHt9O1xuICB9XG4gIHNldFN0cmVhbVJlZihlbCwgcmVmKSB7XG4gICAgZG9tX2RlZmF1bHQucHV0U3RpY2t5KFxuICAgICAgZWwsXG4gICAgICBQSFhfU1RSRUFNX1JFRixcbiAgICAgIChlbDIpID0+IGVsMi5zZXRBdHRyaWJ1dGUoUEhYX1NUUkVBTV9SRUYsIHJlZilcbiAgICApO1xuICB9XG4gIG1heWJlUmVPcmRlclN0cmVhbShlbCwgaXNOZXcgPSBmYWxzZSkge1xuICAgIGNvbnN0IHsgcmVmLCBzdHJlYW1BdCwgcmVzZXQgfSA9IHRoaXMuZ2V0U3RyZWFtSW5zZXJ0KGVsKTtcbiAgICBpZiAoc3RyZWFtQXQgPT09IHZvaWQgMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnNldFN0cmVhbVJlZihlbCwgcmVmKTtcbiAgICBpZiAoIXJlc2V0ICYmICFpc05ldykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIWVsLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHN0cmVhbUF0ID09PSAwKSB7XG4gICAgICB0aGlzLm1vdmVPckluc2VydEJlZm9yZShcbiAgICAgICAgZWwucGFyZW50RWxlbWVudCxcbiAgICAgICAgZWwsXG4gICAgICAgIGVsLnBhcmVudEVsZW1lbnQuZmlyc3RFbGVtZW50Q2hpbGRcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChzdHJlYW1B
1dCA+IDApIHtcbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gQXJyYXkuZnJvbShlbC5wYXJlbnRFbGVtZW50LmNoaWxkcmVuKTtcbiAgICAgIGNvbnN0IG9sZEluZGV4ID0gY2hpbGRyZW4uaW5kZXhPZihlbCk7XG4gICAgICBpZiAoc3RyZWFtQXQgPj0gY2hpbGRyZW4ubGVuZ3RoIC0gMSkge1xuICAgICAgICB0aGlzLm1vdmVPckluc2VydEJlZm9yZShlbC5wYXJlbnRFbGVtZW50LCBlbCwgbnVsbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBzaWJsaW5nID0gY2hpbGRyZW5bc3RyZWFtQXRdO1xuICAgICAgICBpZiAob2xkSW5kZXggPiBzdHJlYW1BdCkge1xuICAgICAgICAgIHRoaXMubW92ZU9ySW5zZXJ0QmVmb3JlKGVsLnBhcmVudEVsZW1lbnQsIGVsLCBzaWJsaW5nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLm1vdmVPckluc2VydEJlZm9yZShcbiAgICAgICAgICAgIGVsLnBhcmVudEVsZW1lbnQsXG4gICAgICAgICAgICBlbCxcbiAgICAgICAgICAgIHNpYmxpbmcubmV4dEVsZW1lbnRTaWJsaW5nXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLm1heWJlTGltaXRTdHJlYW0oZWwpO1xuICB9XG4gIC8vIFJlb3JkZXIgYSBjaGlsZCB3aXRoaW4gaXRzIHBhcmVudC4gV2hlbiBzdXBwb3J0ZWQsIHVzZSB0aGUgYXRvbWljXG4gIC8vIG1vdmVCZWZvcmUgKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Ob2RlL21vdmVCZWZvcmUpXG4gIC8vIHNvIGNvbm5lY3RlZCBjdXN0b20gZWxlbWVudHMgKGFuZCBvdGhlciBzdGF0ZS1iZWFyaW5nIG5vZGVzIGxpa2UgaWZyYW1lcylcbiAgLy8gYXJlIG5vdCBkaXNjb25uZWN0ZWQgYW5kIHJlY29ubmVjdGVkIGJ5IHRoZSBtb3ZlLiBGYWxscyBiYWNrIHRvXG4gIC8vIGluc2VydEJlZm9yZSBvdGhlcndpc2UuIFBhc3NpbmcgYHJlZiA9PT0gbnVsbGAgbW92ZXMgdG8gdGhlIGVuZC5cbiAgLy8gU2VlIGFsc28gaHR0cHM6Ly9naXRodWIuY29tL3Bob2VuaXhmcmFtZXdvcmsvcGhvZW5peF9saXZlX3ZpZXcvaXNzdWVzLzQyMTIuXG4gIG1vdmVPckluc2VydEJlZm9yZShwYXJlbnQsIGNoaWxkLCByZWYpIHtcbiAgICBpZiAodHlwZW9mIHBhcmVudC5tb3ZlQmVmb3JlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHBhcmVudC5tb3ZlQmVmb3JlKGNoaWxkLCByZWYpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIHtcbiAgICAgIH1cbiAgICB9XG4gICAgcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgcmVmKTtcbiAgfVxuICBtYXliZUxpbWl0U3RyZWFtKGVsKSB7XG4gICAgY29uc3QgeyBsaW1pdCB9ID0gdGhpcy5nZXRTdHJlYW1JbnNlcnQoZWwpO1xuICAgIGlmIChsaW1pdCAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgY2hpbGRyZW4gPSBBcnJheS5mcm9tKGVsLnBhcmVudEVsZW1lbnQuY2hpbGRyZW4pO1xuICAgICAgaWYgKGxpbWl0IDwgMCAmJiBjaGlsZHJlbi5sZW5ndGggPiBsaW1pdCAqIC0xKSB7XG4gICAgICAgIGNoaWxkcmVuLnNsaWNlKDAsIGNoaWxkcmVuLmxlbmd0aCArIGxpbWl0KS5mb3JFYWNoKChjaGlsZCkgPT4gdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQpKTtcbiAgICAgIH0gZWxzZSBpZiAobGltaXQgPj0gMCAmJiBjaGlsZHJlbi5sZW5ndGggPiBsaW1pdCkge1xuICAgICAgICBjaGlsZHJlbi5zbGljZShsaW1pdCkuZm9yRWFjaCgoY2hpbGQpID0+IHRoaXMucmVtb3ZlU3RyZWFtQ2hpbGRFbGVtZW50KGNoaWxkKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHRyYW5zaXRpb25QZW5kaW5nUmVtb3ZlcygpIHtcbiAgICBjb25zdCB7IHBlbmRpbmdSZW1vdmVzLCBsaXZlU29ja2V0IH0gPSB0aGlzO1xuICAgIGlmIChwZW5kaW5nUmVtb3Zlcy5sZW5ndGggPiAwKSB7XG4gICAgICBsaXZlU29ja2V0LnRyYW5zaXRpb25SZW1vdmVzKHBlbmRpbmdSZW1vdmVzLCB0aGlzLnZpZXcsICgpID0+IHtcbiAgICAgICAgcGVuZGluZ1JlbW92ZXMuZm9yRWFjaCgoZWwpID0+IHtcbiAgICAgICAgICBjb25zdCBjaGlsZCA9IGRvbV9kZWZhdWx0LmZpcnN0UGh4Q2hpbGQoZWwpO1xuICAgICAgICAgIGlmIChjaGlsZCkge1xuICAgICAgICAgICAgbGl2ZVNvY2tldC5kZXN0cm95Vmlld0J5RWwoY2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbC5yZW1vdmUoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudHJhY2tBZnRlclRyYW5zaXRpb25zRGlzY2FyZGVkKHBlbmRpbmdSZW1vdmVzKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICBpc0NoYW5nZWRTZWxlY3QoZnJvbUVsLCB0b0VsKSB7XG4gICAgaWYgKCEoZnJvbUVsIGluc3RhbmNlb2YgSFRNTFNlbGVjdEVsZW1lbnQpIHx8IGZyb21FbC5tdWx0aXBsZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoZnJvbUVsLm9wdGlvbnMubGVuZ3RoICE9PSB0b0VsLm9wdGlvbnMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgdG9FbC52YWx1ZSA9IGZyb21FbC52YWx1ZTtcbiAgICByZXR1cm4gIWZyb21FbC5pc0VxdWFsTm9kZSh0b0VsKTtcbiAgfVxuICBza2lwQ0lEU2libGluZyhlbCkge1xuICAgIHJldHVybiBlbC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUgJiYgZWwuaGFzQXR0cmlidXRlKFBIWF9TS0lQKTtcbiAgfVxuICBtYXliZUNsb25lTG9ja2VkRWxlbWVudChmcm9tRWwsIGlzRm9jdXNlZEZvcm1FbCkge1xuICAgIGlmICghZnJvbUVsLmhhc0F0dHJpYnV0ZShQSFhfUkVGX1NSQykpXG4gICAgICByZXR1cm4gZnJvbUVsO1xuICAgIGNvbnN0IHJlZiA9IG5ldyBFbGVtZW50UmVmKGZyb21FbCk7XG4gICAgaWYgKCFmcm9tRWwuaGFzQXR0cmlidXRlKFBIWF9SRUZfTE9DSykgfHwgdGhpcy51bmRvUmVmICE9PSBudWxsICYmIHJlZi5pc0xvY2tVbmRvbmVCeSh0aGlzLnVuZG9SZWYpKSB7XG4gICAgICByZXR1cm4gZnJvbUVsO1xuICAgIH1cbiAgICBkb21fZGVmYXVsdC5hcHBseVN0aWNreU9wZXJhdGlvbnMoZnJvbUVsKTtcbiAgICBjb25zdCBjbG9uZTIgPSBmcm9tRWwuaGFzQXR0cmlidXRlKFBIWF9SRUZfTE9DSykgPyBkb21fZGVmYXVsdC5wcml2YXRlKGZyb21FbCwgUEhYX1JFRl9MT0NLKSB8fCBmcm9tRWwuY2xvbmVOb2RlKHRydWUpIDogbnVsbDtcbiAgICBpZiAoIWNsb25lMilcbiAgICAgIHJldHVybi
1Bmcm9tRWw7XG4gICAgZG9tX2RlZmF1bHQucHV0UHJpdmF0ZShmcm9tRWwsIFBIWF9SRUZfTE9DSywgY2xvbmUyKTtcbiAgICByZXR1cm4gaXNGb2N1c2VkRm9ybUVsID8gZnJvbUVsIDogY2xvbmUyO1xuICB9XG4gIGNvcHlOZXN0ZWRQcml2YXRlTG9jayhmcm9tRWwsIHRvRWwpIHtcbiAgICBpZiAodGhpcy51bmRvUmVmID09PSBudWxsIHx8ICFkb21fZGVmYXVsdC5wcml2YXRlKHRvRWwsIFBIWF9SRUZfTE9DSykpXG4gICAgICByZXR1cm47XG4gICAgZG9tX2RlZmF1bHQucHV0UHJpdmF0ZShmcm9tRWwsIFBIWF9SRUZfTE9DSywgZG9tX2RlZmF1bHQucHJpdmF0ZSh0b0VsLCBQSFhfUkVGX0xPQ0spKTtcbiAgfVxuICBpbmRleE9mKHBhcmVudCwgY2hpbGQpIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShwYXJlbnQuY2hpbGRyZW4pLmluZGV4T2YoY2hpbGQpO1xuICB9XG4gIHRlbGVwb3J0KGVsLCBtb3JwaCkge1xuICAgIGNvbnN0IHRhcmdldFNlbGVjdG9yID0gZWwuZ2V0QXR0cmlidXRlKFBIWF9QT1JUQUwpO1xuICAgIGNvbnN0IHBvcnRhbENvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGFyZ2V0U2VsZWN0b3IpO1xuICAgIGlmICghcG9ydGFsQ29udGFpbmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwicG9ydGFsIHRhcmdldCB3aXRoIHNlbGVjdG9yIFwiICsgdGFyZ2V0U2VsZWN0b3IgKyBcIiBub3QgZm91bmRcIlxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgdG9UZWxlcG9ydCA9IGVsLmNvbnRlbnQuZmlyc3RFbGVtZW50Q2hpbGQ7XG4gICAgaWYgKHRoaXMuc2tpcENJRFNpYmxpbmcodG9UZWxlcG9ydCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCF0b1RlbGVwb3J0Py5pZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcInBoeC1wb3J0YWwgdGVtcGxhdGUgbXVzdCBoYXZlIGEgc2luZ2xlIHJvb3QgZWxlbWVudCB3aXRoIElEIVwiXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBleGlzdGluZyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRvVGVsZXBvcnQuaWQpO1xuICAgIGxldCBwb3J0YWxUYXJnZXQ7XG4gICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICBpZiAoIXBvcnRhbENvbnRhaW5lci5jb250YWlucyhleGlzdGluZykpIHtcbiAgICAgICAgcG9ydGFsQ29udGFpbmVyLmFwcGVuZENoaWxkKGV4aXN0aW5nKTtcbiAgICAgIH1cbiAgICAgIHBvcnRhbFRhcmdldCA9IGV4aXN0aW5nO1xuICAgIH0gZWxzZSB7XG4gICAgICBwb3J0YWxUYXJnZXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRvVGVsZXBvcnQudGFnTmFtZSk7XG4gICAgICBwb3J0YWxDb250YWluZXIuYXBwZW5kQ2hpbGQocG9ydGFsVGFyZ2V0KTtcbiAgICB9XG4gICAgdG9UZWxlcG9ydC5zZXRBdHRyaWJ1dGUoUEhYX1RFTEVQT1JURURfUkVGLCB0aGlzLnZpZXcuaWQpO1xuICAgIHRvVGVsZXBvcnQuc2V0QXR0cmlidXRlKFBIWF9URUxFUE9SVEVEX1NSQywgZWwuaWQpO1xuICAgIG1vcnBoKHBvcnRhbFRhcmdldCwgdG9UZWxlcG9ydCwgdHJ1ZSk7XG4gICAgdG9UZWxlcG9ydC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1RFTEVQT1JURURfUkVGKTtcbiAgICB0b1RlbGVwb3J0LnJlbW92ZUF0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9TUkMpO1xuICAgIHRoaXMudmlldy5wdXNoUG9ydGFsRWxlbWVudElkKHRvVGVsZXBvcnQuaWQpO1xuICB9XG4gIGhhbmRsZVJ1bnRpbWVIb29rKGVsLCBzb3VyY2UpIHtcbiAgICBjb25zdCBuYW1lID0gZWwuZ2V0QXR0cmlidXRlKFBIWF9SVU5USU1FX0hPT0spO1xuICAgIGxldCBub25jZSA9IGVsLmhhc0F0dHJpYnV0ZShcIm5vbmNlXCIpID8gZWwuZ2V0QXR0cmlidXRlKFwibm9uY2VcIikgOiBudWxsO1xuICAgIGlmIChlbC5oYXNBdHRyaWJ1dGUoXCJub25jZVwiKSkge1xuICAgICAgY29uc3QgdGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGVtcGxhdGVcIik7XG4gICAgICB0ZW1wbGF0ZS5pbm5lckhUTUwgPSBzb3VyY2U7XG4gICAgICBub25jZSA9IHRlbXBsYXRlLmNvbnRlbnQucXVlcnlTZWxlY3Rvcihgc2NyaXB0WyR7UEhYX1JVTlRJTUVfSE9PS309XCIke0NTUy5lc2NhcGUobmFtZSl9XCJdYCk/LmdldEF0dHJpYnV0ZShcIm5vbmNlXCIpID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIik7XG4gICAgc2NyaXB0LnRleHRDb250ZW50ID0gZWwudGV4dENvbnRlbnQ7XG4gICAgZG9tX2RlZmF1bHQubWVyZ2VBdHRycyhzY3JpcHQsIGVsLCB7IGlzSWdub3JlZDogZmFsc2UgfSk7XG4gICAgaWYgKG5vbmNlKSB7XG4gICAgICBzY3JpcHQubm9uY2UgPSBub25jZTtcbiAgICB9XG4gICAgZWwucmVwbGFjZVdpdGgoc2NyaXB0KTtcbiAgICBlbCA9IHNjcmlwdDtcbiAgfVxufTtcblxuLy8ganMvcGhvZW5peF9saXZlX3ZpZXcvcmVuZGVyZWQuanNcbnZhciBWT0lEX1RBR1MgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldChbXG4gIFwiYXJlYVwiLFxuICBcImJhc2VcIixcbiAgXCJiclwiLFxuICBcImNvbFwiLFxuICBcImNvbW1hbmRcIixcbiAgXCJlbWJlZFwiLFxuICBcImhyXCIsXG4gIFwiaW1nXCIsXG4gIFwiaW5wdXRcIixcbiAgXCJrZXlnZW5cIixcbiAgXCJsaW5rXCIsXG4gIFwibWV0YVwiLFxuICBcInBhcmFtXCIsXG4gIFwic291cmNlXCIsXG4gIFwidHJhY2tcIixcbiAgXCJ3YnJcIlxuXSk7XG52YXIgcXVvdGVDaGFycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KFtcIidcIiwgJ1wiJ10pO1xudmFyIG1vZGlmeVJvb3QgPSAoaHRtbCwgYXR0cnMsIGNsZWFySW5uZXJIVE1MKSA9PiB7XG4gIGxldCBpID0gMDtcbiAgbGV0IGluc2lkZUNvbW1lbnQgPSBmYWxzZTtcbiAgbGV0IGJlZm9yZVRhZywgYWZ0ZXJUYWcsIHRhZywgdGFnTmFtZUVuZHNBdCwgaWQsIG5ld0hUTUw7XG4gIGNvbnN0IGxvb2thaGVhZCA9IGh0bWwubWF0Y2goL14oXFxzKig/OjwhLS0uKj8tLT5cXHMqKSopPChbXlxcc1xcLz5dKykvKTtcbiAgaWYgKGxvb2thaGVhZCA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgbWFsZm9ybWVkIGh0bWwgJHtodG1sfWApO1xuICB9XG4gIGkgPSBsb29rYWhlYWRbMF0ubGVuZ3RoO1xuICBiZWZvcmVUYWcgPSBsb29rYWhlYWRbMV07XG4gIHRhZyA9IGxvb2thaGVhZFsyXTtcbiAgdGFnTmFtZUVuZHNBdCA9IGk7XG4gIGZvciAoaTsgaSA8IGh0bWwubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoaHRtbC5jaGFyQXQoaSkgPT09IFwiPlwiKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgaWYgKGh0bWwuY2hhckF0KGkpID09PSBcIj1cIikge1xuICAgICAgY29uc3QgaXNJZCA9IGh0bWwuc2xpY2UoaSAtIDMsIGkpID09PSBcIiBpZFwiO1xuICAgICAgaSsrO1xuICAgICAgY29uc3QgY2hhciA9IGh0bWwuY2hhckF0KGkpO1xuICAgICAgaWYgKHF1b3RlQ2hhcnMuaGFzKGNoYXIpKSB7XG4gICAgICAgIGNvbnN0IGF0dHJTdGFydHNBdCA9IGk7XG4gICAgICAgIGkrKztcbiAgICAgICAgZm9yIChpOyBpIDwgaHRtbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmIChodG1sLmNoYXJBdChpKSA9PT0gY2hhcikge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpc0lkKSB7XG4gICAgICAgICAgaWQgPSBodG1sLnNsaWNlKGF0dHJTdGFydHNBdCArIDEsIGkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGxldCBjbG9zZUF0ID0gaHRtbC5sZW5ndGggLSAxO1xuICBpbnNpZGVDb21tZW50ID0gZmFsc2U7XG4gIHdoaWxlIChjbG9zZUF0ID49IGJlZm9yZVRhZy5sZW5ndGggKyB0YWcubGVuZ3RoKSB7XG4gICAgY29uc3QgY2hhciA9IGh0bWwuY2hhckF0KGNsb3NlQXQpO1xuICAgIGlmIChpbnNpZGVDb21tZW50KSB7XG4gICAgICBpZiAoY2hhciA9PT0gXCItXCIgJiYgaHRtbC5zbGljZShjbG9zZUF0IC0gMywgY2xvc2VBdCkgPT09IFwiPCEtXCIpIHtcbiAgICAgICAgaW5zaWRlQ29tbWVudCA9IGZhbHNlO1xuICAgICAgICBjbG9zZUF0IC09IDQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjbG9zZUF0IC09IDE7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjaGFyID09PSBcIj5cIiAmJiBodG
11sLnNsaWNlKGNsb3NlQXQgLSAyLCBjbG9zZUF0KSA9PT0gXCItLVwiKSB7XG4gICAgICBpbnNpZGVDb21tZW50ID0gdHJ1ZTtcbiAgICAgIGNsb3NlQXQgLT0gMztcbiAgICB9IGVsc2UgaWYgKGNoYXIgPT09IFwiPlwiKSB7XG4gICAgICBicmVhaztcbiAgICB9IGVsc2Uge1xuICAgICAgY2xvc2VBdCAtPSAxO1xuICAgIH1cbiAgfVxuICBhZnRlclRhZyA9IGh0bWwuc2xpY2UoY2xvc2VBdCArIDEsIGh0bWwubGVuZ3RoKTtcbiAgY29uc3QgYXR0cnNTdHIgPSBPYmplY3Qua2V5cyhhdHRycykubWFwKChhdHRyKSA9PiBhdHRyc1thdHRyXSA9PT0gdHJ1ZSA/IGF0dHIgOiBgJHthdHRyfT1cIiR7YXR0cnNbYXR0cl19XCJgKS5qb2luKFwiIFwiKTtcbiAgaWYgKGNsZWFySW5uZXJIVE1MKSB7XG4gICAgY29uc3QgaWRBdHRyU3RyID0gaWQgPyBgIGlkPVwiJHtpZH1cImAgOiBcIlwiO1xuICAgIGlmIChWT0lEX1RBR1MuaGFzKHRhZykpIHtcbiAgICAgIG5ld0hUTUwgPSBgPCR7dGFnfSR7aWRBdHRyU3RyfSR7YXR0cnNTdHIgPT09IFwiXCIgPyBcIlwiIDogXCIgXCJ9JHthdHRyc1N0cn0vPmA7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld0hUTUwgPSBgPCR7dGFnfSR7aWRBdHRyU3RyfSR7YXR0cnNTdHIgPT09IFwiXCIgPyBcIlwiIDogXCIgXCJ9JHthdHRyc1N0cn0+PC8ke3RhZ30+YDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgcmVzdCA9IGh0bWwuc2xpY2UodGFnTmFtZUVuZHNBdCwgY2xvc2VBdCArIDEpO1xuICAgIG5ld0hUTUwgPSBgPCR7dGFnfSR7YXR0cnNTdHIgPT09IFwiXCIgPyBcIlwiIDogXCIgXCJ9JHthdHRyc1N0cn0ke3Jlc3R9YDtcbiAgfVxuICByZXR1cm4gW25ld0hUTUwsIGJlZm9yZVRhZywgYWZ0ZXJUYWddO1xufTtcbnZhciBSZW5kZXJlZCA9IGNsYXNzIHtcbiAgc3RhdGljIGV4dHJhY3QoZGlmZikge1xuICAgIGNvbnN0IHsgW1JFUExZXTogcmVwbHksIFtFVkVOVFNdOiBldmVudHMsIFtUSVRMRV06IHRpdGxlIH0gPSBkaWZmO1xuICAgIGRlbGV0ZSBkaWZmW1JFUExZXTtcbiAgICBkZWxldGUgZGlmZltFVkVOVFNdO1xuICAgIGRlbGV0ZSBkaWZmW1RJVExFXTtcbiAgICByZXR1cm4geyBkaWZmLCB0aXRsZSwgcmVwbHk6IHJlcGx5IHx8IG51bGwsIGV2ZW50czogZXZlbnRzIHx8IFtdIH07XG4gIH1cbiAgY29uc3RydWN0b3Iodmlld0lkLCByZW5kZXJlZCkge1xuICAgIHRoaXMudmlld0lkID0gdmlld0lkO1xuICAgIHRoaXMucmVuZGVyZWQgPSB7fTtcbiAgICB0aGlzLm1hZ2ljSWQgPSAwO1xuICAgIHRoaXMubWVyZ2VEaWZmKHJlbmRlcmVkKTtcbiAgfVxuICBwYXJlbnRWaWV3SWQoKSB7XG4gICAgcmV0dXJuIHRoaXMudmlld0lkO1xuICB9XG4gIHRvU3RyaW5nKG9ubHlDaWRzKSB7XG4gICAgY29uc3QgeyBidWZmZXI6IHN0ciwgc3RyZWFtcyB9ID0gdGhpcy5yZWN1cnNpdmVUb1N0cmluZyhcbiAgICAgIHRoaXMucmVuZGVyZWQsXG4gICAgICB0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdLFxuICAgICAgb25seUNpZHMsXG4gICAgICB0cnVlLFxuICAgICAge31cbiAgICApO1xuICAgIHJldHVybiB7IGJ1ZmZlcjogc3RyLCBzdHJlYW1zIH07XG4gIH1cbiAgcmVjdXJzaXZlVG9TdHJpbmcocmVuZGVyZWQsIGNvbXBvbmVudHMgPSByZW5kZXJlZFtDT01QT05FTlRTXSwgb25seUNpZHMsIGNoYW5nZVRyYWNraW5nLCByb290QXR0cnMpIHtcbiAgICBvbmx5Q2lkcyA9IG9ubHlDaWRzID8gbmV3IFNldChvbmx5Q2lkcykgOiBudWxsO1xuICAgIGNvbnN0IG91dHB1dCA9IHtcbiAgICAgIGJ1ZmZlcjogXCJcIixcbiAgICAgIGNvbXBvbmVudHMsXG4gICAgICBvbmx5Q2lkcyxcbiAgICAgIHN0cmVhbXM6IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KClcbiAgICB9O1xuICAgIHRoaXMudG9PdXRwdXRCdWZmZXIocmVuZGVyZWQsIG51bGwsIG91dHB1dCwgY2hhbmdlVHJhY2tpbmcsIHJvb3RBdHRycyk7XG4gICAgcmV0dXJuIHsgYnVmZmVyOiBvdXRwdXQuYnVmZmVyLCBzdHJlYW1zOiBvdXRwdXQuc3RyZWFtcyB9O1xuICB9XG4gIGNvbXBvbmVudENJRHMoZGlmZikge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhkaWZmW0NPTVBPTkVOVFNdIHx8IHt9KS5tYXAoKGkpID0+IHBhcnNlSW50KGkpKTtcbiAgfVxuICBpc0NvbXBvbmVudE9ubHlEaWZmKGRpZmYpIHtcbiAgICBpZiAoIWRpZmZbQ09NUE9ORU5UU10pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGRpZmYpLmxlbmd0aCA9PT0gMTtcbiAgfVxuICBnZXRDb21wb25lbnQoZGlmZiwgY2lkKSB7XG4gICAgcmV0dXJuIGRpZmZbQ09NUE9ORU5UU11bY2lkXTtcbiAgfVxuICByZXNldFJlbmRlcihjaWQpIHtcbiAgICBpZiAodGhpcy5yZW5kZXJlZFtDT01QT05FTlRTXVtjaWRdKSB7XG4gICAgICB0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdW2NpZF0ucmVzZXQgPSB0cnVlO1xuICAgIH1cbiAgfVxuICBtZXJnZURpZmYoZGlmZikge1xuICAgIGNvbnN0IG5ld2MgPSBkaWZmW0NPTVBPTkVOVFNdO1xuICAgIGNvbnN0IGNhY2hlID0ge307XG4gICAgZGVsZXRlIGRpZmZbQ09NUE9ORU5UU107XG4gICAgdGhpcy5yZW5kZXJlZCA9IHRoaXMubXV0YWJsZU1lcmdlKHRoaXMucmVuZGVyZWQsIGRpZmYpO1xuICAgIHRoaXMucmVuZGVyZWRbQ09NUE9ORU5UU10gPSB0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdIHx8IHt9O1xuICAgIGlmIChuZXdjKSB7XG4gICAgICBjb25zdCBvbGRjID0gdGhpcy5yZW5kZXJlZFtDT01QT05FTlRTXTtcbiAgICAgIGZvciAoY29uc3QgY2lkIGluIG5ld2MpIHtcbiAgICAgICAgbmV3Y1tjaWRdID0gdGhpcy5jYWNoZWRGaW5kQ29tcG9uZW50KGNpZCwgbmV3Y1tjaWRdLCBvbGRjLCBuZXdjLCBjYWNoZSk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGNpZCBpbiBuZXdjKSB7XG4gICAgICAgIG9sZGNbY2lkXSA9IG5ld2NbY2lkXTtcbiAgICAgIH1cbiAgICAgIGRpZmZbQ09NUE9ORU5UU10gPSBuZXdjO1xuICAgIH1cbiAgfVxuICBjYWNoZWRGaW5kQ29tcG9uZW50KGNpZCwgY2RpZmYsIG9sZGMsIG5ld2MsIGNhY2hlKSB7XG4gICAgaWYgKGNhY2hlW2NpZF0pIHtcbiAgICAgIHJldHVybi
1BjYWNoZVtjaWRdO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgbmRpZmYsIHN0YXQsIHNjaWQgPSBjZGlmZltTVEFUSUNdO1xuICAgICAgaWYgKGlzQ2lkKHNjaWQpKSB7XG4gICAgICAgIGxldCB0ZGlmZjtcbiAgICAgICAgaWYgKHNjaWQgPiAwKSB7XG4gICAgICAgICAgdGRpZmYgPSB0aGlzLmNhY2hlZEZpbmRDb21wb25lbnQoc2NpZCwgbmV3Y1tzY2lkXSwgb2xkYywgbmV3YywgY2FjaGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRkaWZmID0gb2xkY1stc2NpZF07XG4gICAgICAgIH1cbiAgICAgICAgc3RhdCA9IHRkaWZmW1NUQVRJQ107XG4gICAgICAgIG5kaWZmID0gdGhpcy5jbG9uZU1lcmdlKHRkaWZmLCBjZGlmZiwgdHJ1ZSk7XG4gICAgICAgIG5kaWZmW1NUQVRJQ10gPSBzdGF0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmRpZmYgPSBjZGlmZltTVEFUSUNdICE9PSB2b2lkIDAgfHwgb2xkY1tjaWRdID09PSB2b2lkIDAgPyBjZGlmZiA6IHRoaXMuY2xvbmVNZXJnZShvbGRjW2NpZF0sIGNkaWZmLCBmYWxzZSk7XG4gICAgICB9XG4gICAgICBjYWNoZVtjaWRdID0gbmRpZmY7XG4gICAgICByZXR1cm4gbmRpZmY7XG4gICAgfVxuICB9XG4gIG11dGFibGVNZXJnZSh0YXJnZXQsIHNvdXJjZSkge1xuICAgIGlmIChzb3VyY2VbU1RBVElDXSAhPT0gdm9pZCAwKSB7XG4gICAgICByZXR1cm4gc291cmNlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRvTXV0YWJsZU1lcmdlKHRhcmdldCwgc291cmNlKTtcbiAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuICB9XG4gIGRvTXV0YWJsZU1lcmdlKHRhcmdldCwgc291cmNlKSB7XG4gICAgaWYgKHNvdXJjZVtLRVlFRF0pIHtcbiAgICAgIHRoaXMubWVyZ2VLZXllZCh0YXJnZXQsIHNvdXJjZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIHNvdXJjZSkge1xuICAgICAgICBjb25zdCB2YWwgPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgY29uc3QgdGFyZ2V0VmFsID0gdGFyZ2V0W2tleV07XG4gICAgICAgIGNvbnN0IGlzT2JqVmFsID0gaXNPYmplY3QodmFsKTtcbiAgICAgICAgaWYgKGlzT2JqVmFsICYmIHZhbFtTVEFUSUNdID09PSB2b2lkIDAgJiYgaXNPYmplY3QodGFyZ2V0VmFsKSkge1xuICAgICAgICAgIHRoaXMuZG9NdXRhYmxlTWVyZ2UodGFyZ2V0VmFsLCB2YWwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRhcmdldFtrZXldID0gdmFsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0YXJnZXRbUk9PVF0pIHtcbiAgICAgIHRhcmdldC5uZXdSZW5kZXIgPSB0cnVlO1xuICAgIH1cbiAgfVxuICBjbG9uZShkaWZmKSB7XG4gICAgaWYgKFwic3RydWN0dXJlZENsb25lXCIgaW4gd2luZG93KSB7XG4gICAgICByZXR1cm4gc3RydWN0dXJlZENsb25lKGRpZmYpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkaWZmKSk7XG4gICAgfVxuICB9XG4gIC8vIGtleWVkIGNvbXByZWhlbnNpb25zXG4gIG1lcmdlS2V5ZWQodGFyZ2V0LCBzb3VyY2UpIHtcbiAgICBjb25zdCBjbG9uZWRUYXJnZXQgPSB0aGlzLmNsb25lKHRhcmdldCk7XG4gICAgT2JqZWN0LmVud
1HJpZXMoc291cmNlW0tFWUVEXSkuZm9yRWFjaCgoW2ksIGVudHJ5XSkgPT4ge1xuICAgICAgaWYgKGkgPT09IEtFWUVEX0NPVU5UKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGVudHJ5KSkge1xuICAgICAgICBjb25zdCBbb2xkX2lkeCwgZGlmZl0gPSBlbnRyeTtcbiAgICAgICAgdGFyZ2V0W0tFWUVEXVtpXSA9IGNsb25lZFRhcmdldFtLRVlFRF1bb2xkX2lkeF07XG4gICAgICAgIHRoaXMuZG9NdXRhYmxlTWVyZ2UodGFyZ2V0W0tFWUVEXVtpXSwgZGlmZik7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbnRyeSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICBjb25zdCBvbGRfaWR4ID0gZW50cnk7XG4gICAgICAgIHRhcmdldFtLRVlFRF1baV0gPSBjbG9uZWRUYXJnZXRbS0VZRURdW29sZF9pZHhdO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZW50cnkgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgaWYgKCF0YXJnZXRbS0VZRURdW2ldKSB7XG4gICAgICAgICAgdGFyZ2V0W0tFWUVEXVtpXSA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZG9NdXRhYmxlTWVyZ2UodGFyZ2V0W0tFWUVEXVtpXSwgZW50cnkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChzb3VyY2VbS0VZRURdW0tFWUVEX0NPVU5UXSA8IHRhcmdldFtLRVlFRF1bS0VZRURfQ09VTlRdKSB7XG4gICAgICBmb3IgKGxldCBpID0gc291cmNlW0tFWUVEXVtLRVlFRF9DT1VOVF07IGkgPCB0YXJnZXRbS0VZRURdW0tFWUVEX0NPVU5UXTsgaSsrKSB7XG4gICAgICAgIGRlbGV0ZSB0YXJnZXRbS0VZRURdW2ldO1xuICAgICAgfVxuICAgIH1cbiAgICB0YXJnZXRbS0VZRURdW0tFWUVEX0NPVU5UXSA9IHNvdXJjZVtLRVlFRF1bS0VZRURfQ09VTlRdO1xuICAgIGlmIChzb3VyY2VbU1RSRUFNXSkge1xuICAgICAgdGFyZ2V0W1NUUkVBTV0gPSBzb3VyY2VbU1RSRUFNXTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZVtURU1QTEFURVNdKSB7XG4gICAgICB0YXJnZXRbVEVNUExBVEVTXSA9IHNvdXJjZVtURU1QTEFURVNdO1xuICAgIH1cbiAgfVxuICAvLyBNZXJnZXMgY2lkIHRyZWVzIHRvZ2V0aGVyLCBjb3B5aW5nIHN0YXRpY3MgZnJvbSBzb3VyY2UgdHJlZS5cbiAgLy9cbiAgLy8gVGhlIGBwcnVuZU1hZ2ljSWRgIGlzIHBhc3NlZCB0byBjb250cm9sIHBydW5pbmcgdGhlIG1hZ2ljSWQgb2YgdGhlXG4gIC8vIHRhcmdldC4gV2UgbXVzdCBhbHdheXMgcHJ1bmUgdGhlIG1hZ2ljSWQgd2hlbiB3ZSBhcmUgc2hhcmluZyBzdGF0aWNzXG4gIC8vIGZyb20gYW5vdGhlciBjb21wb25lbnQuIElmIG5vdCBwcnVuaW5nLCB3ZSByZXBsaWNhdGUgdGhlIGxvZ2ljIGZyb21cbiAgLy8gbXV0YWJsZU1lcmdlLCB3aGVyZSB3ZSBzZXQgbmV3UmVuZGVyIHRvIHRydWUgaWYgdGhlcmUgaXMgYSByb290XG4gIC8vIChlZmZlY3RpdmVseSBmb3JjaW5nIHRoZSBuZXcgdmVyc2lvbiB0byBiZSByZW5kZXJlZCBpbnN0ZWFkIG9mIHNraXBwZWQpXG4gIC8vXG4gIGNsb25lTWVyZ2UodGFyZ2V0LCBzb3VyY2UsIHBydW5lTWFnaWNJZCkge1xuICAgIGxldCBtZXJnZWQ7XG4gICAgaWYgKHNvdXJjZVtLRVlFRF0pIHtcbiAgICAgIG1lcmdlZCA9IHRoaXMuY2xvbmUodGFyZ2V0KTtcbiAgICAgIHRoaXMubWVyZ2VLZXllZChtZXJnZWQsIHNvdXJjZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1lcmdlZCA9IHsgLi4udGFyZ2V0LCAuLi5zb3VyY2UgfTtcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIG1lcmdlZCkge1xuICAgICAgICBjb25zdCB2YWwgPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgY29uc3QgdGFyZ2V0VmFsID0gdGFyZ2V0W2tleV07XG4gICAgICAgIGlmIChpc09iamVjdCh2YWwpICYmIHZhbFtTVEFUSUNdID09PSB2b2lkIDAgJiYgaXNPYmplY3QodGFyZ2V0VmFsKSkge1xuICAgICAgICAgIG1lcmdlZFtrZXldID0gdGhpcy5jbG9uZU1lcmdlKHRhcmdldFZhbCwgdmFsLCBwcnVuZU1hZ2ljSWQpO1xuICAgICAgICB9IGVsc2UgaWYgKHZhbCA9PT0gdm9pZCAwICYmIGlzT2JqZWN0KHRhcmdldFZhbCkpIHtcbiAgICAgICAgICBtZXJnZWRba2V5XSA9IHRoaXMuY2xvbmVNZXJnZSh0YXJnZXRWYWwsIHt9LCBwcnVuZU1hZ2ljSWQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChwcnVuZU1hZ2ljSWQpIHtcbiAgICAgIGRlbGV0ZSBtZXJnZWQubWFnaWNJZDtcbiAgICAgIGRlbGV0ZSBtZXJnZWQubmV3UmVuZGVyO1xuICAgIH0gZWxzZSBpZiAodGFyZ2V0W1JPT1RdKSB7XG4gICAgICBtZXJnZWQubmV3UmVuZGVyID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIG1lcmdlZDtcbiAgfVxuICBjb21wb25lbnRUb1N0cmluZyhjaWQpIHtcbiAgICBjb25zdCB7IGJ1ZmZlcjogc3RyLCBzdHJlYW1zIH0gPSB0aGlzLnJlY3Vyc2l2ZUNJRFRvU3RyaW5nKFxuICAgICAgdGhpcy5yZW5kZXJlZFtDT01QT05FTlRTXSxcbiAgICAgIGNpZCxcbiAgICAgIG51bGxcbiAgICApO1xuICAgIGNvbnN0IFtzdHJpcHBlZEhUTUwsIF9iZWZvcmUsIF9hZnRlcl0gPSBtb2RpZnlSb290KHN0ciwge30pO1xuICAgIHJldHVybiB7IGJ1ZmZlcjogc3RyaXBwZWRIVE1MLCBzdHJlYW1zIH07XG4gIH1cbiAgcHJ1bmVDSURzKGNpZHMpIHtcbiAgICBjaWRzLmZvckVhY2goKGNpZCkgPT4gZGVsZXRlIHRoaXMucmVuZGVyZWRbQ09NUE9ORU5UU11bY2lkXSk7XG4gIH1cbiAgLy8gcHJpdmF0ZVxuICBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyZWQ7XG4gIH1cbiAgaXNOZXdGaW5nZXJwcmludChkaWZmID0ge30pIHtcbiAgICByZXR1cm4gISFkaWZmW1NUQVRJQ107XG4gIH1cbiAgdGVtcGxhdGVTdGF0aWMocGFydCwgdGVtcGxhdGVzKSB7XG4gICAgaWYgKHR5cGVvZiBwYXJ0ID09PSBcIm51bWJlclwiKSB7XG4gICAgICByZXR1cm4gdGVtcGxhdGVzW3BhcnRdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcGFydDtcbiAgICB9XG4gIH1cbiAgbmV4dE1hZ2ljSUQoKSB7XG4gICAgdGhpcy5tYWdpY0lkKys7XG4gICAgcmV0dXJuIGBtJHt0aGlzLm1hZ2ljSWR9LSR7dGhpcy5wYXJlbnRWaWV3SWQoKX1gO1xuICB9XG4gIC8vIENvbnZlcnRzIHJlbmRlcmVkIHRyZWUgdG8gb3V0cHV0IGJ1ZmZlci5cbiAgLy9cbiAgLy8gY2hhbmdlVHJhY2tpbmcgY29udHJvbHMgaWYgd2UgY2FuIGFwcGx5IHRoZSBQSFhfU0tJUCBvcHRpbWl6YXRpb24uXG4gIHRvT3V0cHV0QnVmZmVyKHJlbmRlcmVkLCB0ZW1wbGF0ZXMsIG91dHB1dCwgY2hhbmdlVHJhY2tpbmcsIHJvb3RBdHRycyA9IHt9KSB7XG4gICAgaWYgKHJlbmRlcmVkW0tFWUVEXSkge1xuICAgICAgcmV0dXJuIHRoaXMuY29tcHJlaGVuc2lvblRvQnVmZmVyKFxuICAgICAgICByZW5kZXJlZCxcbiAgICAgICAgdGVtcGxhdGVzLFxuICAgICAgICBvdXRwdXQsXG4gICAgICAgIGNoYW5nZVRyYWNraW5nXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAocmVuZGVyZWRbVEVNUExBVEVTXSkge1xuICAgICAgdGVtcGxhdGVzID0gcmVuZGVyZWRbVEVNUExBVEVTXTtcbiAgICAgIGRlbGV0ZSByZW5kZXJlZFtURU1QTEFURVNdO1xuICAgIH1cbiAgICBsZXQgeyBbU1RBVElDXTogc3RhdGljcyB9ID0gcmVuZGVyZWQ7XG4gICAgc3RhdGljcyA9IHRoaXMudGVtcGxhdGVTdGF0aWMoc3RhdGljcywgdGVtcGxhdGVzKTtcbiAgICByZW5kZXJlZFtTVEFUSUNd
1ID0gc3RhdGljcztcbiAgICBjb25zdCBpc1Jvb3QgPSByZW5kZXJlZFtST09UXTtcbiAgICBjb25zdCBwcmV2QnVmZmVyID0gb3V0cHV0LmJ1ZmZlcjtcbiAgICBpZiAoaXNSb290KSB7XG4gICAgICBvdXRwdXQuYnVmZmVyID0gXCJcIjtcbiAgICB9XG4gICAgaWYgKGNoYW5nZVRyYWNraW5nICYmIGlzUm9vdCAmJiAhcmVuZGVyZWQubWFnaWNJZCkge1xuICAgICAgcmVuZGVyZWQubmV3UmVuZGVyID0gdHJ1ZTtcbiAgICAgIHJlbmRlcmVkLm1hZ2ljSWQgPSB0aGlzLm5leHRNYWdpY0lEKCk7XG4gICAgfVxuICAgIG91dHB1dC5idWZmZXIgKz0gc3RhdGljc1swXTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHN0YXRpY3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuZHluYW1pY1RvQnVmZmVyKHJlbmRlcmVkW2kgLSAxXSwgdGVtcGxhdGVzLCBvdXRwdXQsIGNoYW5nZVRyYWNraW5nKTtcbiAgICAgIG91dHB1dC5idWZmZXIgKz0gc3RhdGljc1tpXTtcbiAgICB9XG4gICAgaWYgKGlzUm9vdCkge1xuICAgICAgbGV0IHNraXAgPSBmYWxzZTtcbiAgICAgIGxldCBhdHRycztcbiAgICAgIGlmIChjaGFuZ2VUcmFja2luZyB8fCByZW5kZXJlZC5tYWdpY0lkKSB7XG4gICAgICAgIHNraXAgPSBjaGFuZ2VUcmFja2luZyAmJiAhcmVuZGVyZWQubmV3UmVuZGVyO1xuICAgICAgICBhdHRycyA9IHsgW1BIWF9NQUdJQ19JRF06IHJlbmRlcmVkLm1hZ2ljSWQsIC4uLnJvb3RBdHRycyB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXR0cnMgPSByb290QXR0cnM7XG4gICAgICB9XG4gICAgICBpZiAoc2tpcCkge1xuICAgICAgICBhdHRyc1tQSFhfU0tJUF0gPSB0cnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgW25ld1Jvb3QsIGNvbW1lbnRCZWZvcmUsIGNvbW1lbnRBZnRlcl0gPSBtb2RpZnlSb290KFxuICAgICAgICBvdXRwdXQuYnVmZmVyLFxuICAgICAgICBhdHRycyxcbiAgICAgICAgc2tpcFxuICAgICAgKTtcbiAgICAgIHJlbmRlcmVkLm5ld1JlbmRlciA9IGZhbHNlO1xuICAgICAgb3V0cHV0LmJ1ZmZlciA9IHByZXZCdWZmZXIgKyBjb21tZW50QmVmb3JlICsgbmV3Um9vdCArIGNvbW1lbnRBZnRlcjtcbiAgICB9XG4gIH1cbiAgY29tcHJlaGVuc2lvblRvQnVmZmVyKHJlbmRlcmVkLCB0ZW1wbGF0ZXMsIG91dHB1dCwgY2hhbmdlVHJhY2tpbmcpIHtcbiAgICBjb25zdCBrZXllZFRlbXBsYXRlcyA9IHRlbXBsYXRlcyB8fCByZW5kZXJlZFtURU1QTEFURVNdO1xuICAgIGNvbnN0IHN0YXRpY3MgPSB0aGlzLnRlbXBsYXRlU3RhdGljKHJlbmRlcmVkW1NUQVRJQ10sIHRlbXBsYXRlcyk7XG4gICAgcmVuZGVyZWRbU1RBVElDXSA9IHN0YXRpY3M7XG4gICAgZGVsZXRlIHJlbmRlcmVkW1RFTVBMQVRFU107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZW5kZXJlZFtLRVlFRF1bS0VZRURfQ09VTlRdOyBpKyspIHtcbiAgICAgIG91dHB1dC5idWZmZXIgKz0gc3RhdGljc1swXTtcbiAgICAgIGZvciAobGV0IGogPSAxOyBqIDwgc3RhdGljcy5sZW5ndGg7IGorKykge1xuICAgICAgICB0aGlzLmR5bmFtaWNUb0J1ZmZlcihcbiAgICAgICAgICByZW5kZXJlZFtLRVlFRF1baV1baiAtIDFdLFxuICAgICAgICAgIGtleWVkVGVtcGxhdGVzLFxuICAgICAgICAgIG91dHB1dCxcbiAgICAgICAgICBjaGFuZ2VUcmFja2luZ1xuICAgICAgICApO1xuICAgICAgICBvdXRwdXQuYnVmZmVyICs9IHN0YXRpY3Nbal07XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChyZW5kZXJlZFtTVFJFQU1dKSB7XG4gICAgICBjb25zdCBzdHJlYW0gPSByZW5kZXJlZFtTVFJFQU1dO1xuICAgICAgY29uc3QgW19yZWYsIF9pbnNlcnRzLCBkZWxldGVJZHMsIHJlc2V0XSA9IHN0cmVhbSB8fCBbbnVsbCwge30sIFtdLCBudWxsXTtcbiAgICAgIGlmIChzdHJlYW0gIT09IHZvaWQgMCAmJiAocmVuZGVyZWRbS0VZRURdW0tFWUVEX0NPVU5UXSA+IDAgfHwgZGVsZXRlSWRzLmxlbmd0aCA+IDAgfHwgcmVzZXQpKSB7XG4gICAgICAgIGRlbGV0ZSByZW5kZXJlZFtTVFJFQU1dO1xuICAgICAgICByZW5kZXJlZFtLRVlFRF0gPSB7XG4gICAgICAgICAgW0tFWUVEX0NPVU5UXTogMFxuICAgICAgICB9O1xuICAgICAgICBvdXRwdXQuc3RyZWFtcy5hZGQoc3RyZWFtKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZHluYW1pY1RvQnVmZmVyKHJlbmRlcmVkLCB0ZW1wbGF0ZXMsIG91dHB1dCwgY2hhbmdlVHJhY2tpbmcpIHtcbiAgICBpZiAodHlwZW9mIHJlbmRlcmVkID09PSBcIm51bWJlclwiKSB7XG4gICAgICBjb25zdCB7IGJ1ZmZlcjogc3RyLCBzdHJlYW1zIH0gPSB0aGlzLnJlY3Vyc2l2ZUNJRFRvU3RyaW5nKFxuICAgICAgICBvdXRwdXQuY29tcG9uZW50cyxcbiAgICAgICAgcmVuZGVyZWQsXG4gICAgICAgIG91dHB1dC5vbmx5Q2lkc1xuICAgICAgKTtcbiAgICAgIG91dHB1dC5idWZmZXIgKz0gc3RyO1xuICAgICAgb3V0cHV0LnN0cmVhbXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldChbLi4ub3V0cHV0LnN0cmVhbXMsIC4uLnN0cmVhbXNdKTtcbiAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KHJlbmRlcmVkKSkge1xuICAgICAgdGhpcy50b091dHB1dEJ1ZmZlcihyZW5kZXJlZCwgdGVtcGxhdGVzLCBvdXRwdXQsIGNoYW5nZVRyYWNraW5nLCB7fSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5idWZmZXIgKz0gcmVuZGVyZWQ7XG4gICAgfVxuICB9XG4gIHJlY3Vyc2l2ZUNJRFRvU3RyaW5nKGNvbXBvbmVudHMsIGNpZCwgb25seUNpZHMpIHtcbiAgICBjb25zdCBjb21wb25lbnQgPSBjb21wb25lbnRzW2NpZF0gfHwgbG9nRXJyb3IoYG5vIGNvbXBvbmVudCBmb3IgQ0lEICR7Y2lkfWAsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGF0dHJzID0geyBbUEhYX0NPTVBPTkVOVF06IGNpZCwgW1BIWF9WSUVXX1JFRl06IHRoaXMudmlld0lkIH07XG4gICAgY29uc3Qgc2tpcCA9IG9ubHlDaWRzICYmICFvbmx5Q2lkcy5oYXMoY2lkKTtcbiAgICBjb21wb25lbnQubmV3UmVuZGVyID0gIXNraXA7XG4gICAgY29tcG9uZW50Lm1hZ2ljSWQgPSBgYyR7Y2lkfS0ke3RoaXMucGFyZW50Vmlld0lkKCl9YDtcbiAgICBjb25zdCBjaGFuZ2VUcmFja2luZyA9ICFjb21wb25lbnQucmVzZXQ7XG4gICAgY29uc3QgeyBidWZmZXI6IGh0bWwsIHN0cmVhbXMgfSA9IHRoaXMucmVjdXJzaXZlVG9TdHJpbmc
1oXG4gICAgICBjb21wb25lbnQsXG4gICAgICBjb21wb25lbnRzLFxuICAgICAgb25seUNpZHMsXG4gICAgICBjaGFuZ2VUcmFja2luZyxcbiAgICAgIGF0dHJzXG4gICAgKTtcbiAgICBkZWxldGUgY29tcG9uZW50LnJlc2V0O1xuICAgIHJldHVybiB7IGJ1ZmZlcjogaHRtbCwgc3RyZWFtcyB9O1xuICB9XG59O1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy9qcy5qc1xudmFyIGZvY3VzU3RhY2sgPSBbXTtcbnZhciBkZWZhdWx0X3RyYW5zaXRpb25fdGltZSA9IDIwMDtcbnZhciBKUyA9IHtcbiAgLy8gcHJpdmF0ZVxuICBleGVjKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBkZWZhdWx0cykge1xuICAgIGNvbnN0IFtkZWZhdWx0S2luZCwgZGVmYXVsdEFyZ3NdID0gZGVmYXVsdHMgfHwgW1xuICAgICAgbnVsbCxcbiAgICAgIHsgY2FsbGJhY2s6IGRlZmF1bHRzICYmIGRlZmF1bHRzLmNhbGxiYWNrIH1cbiAgICBdO1xuICAgIGNvbnN0IGNvbW1hbmRzID0gQXJyYXkuaXNBcnJheShwaHhFdmVudCkgPyBwaHhFdmVudCA6IHR5cGVvZiBwaHhFdmVudCA9PT0gXCJzdHJpbmdcIiAmJiBwaHhFdmVudC5zdGFydHNXaXRoKFwiW1wiKSA/IEpTT04ucGFyc2UocGh4RXZlbnQpIDogW1tkZWZhdWx0S2luZCwgZGVmYXVsdEFyZ3NdXTtcbiAgICBjb21tYW5kcy5mb3JFYWNoKChba2luZCwgYXJnc10pID0+IHtcbiAgICAgIGlmIChraW5kID09PSBkZWZhdWx0S2luZCkge1xuICAgICAgICBhcmdzID0geyAuLi5kZWZhdWx0QXJncywgLi4uYXJncyB9O1xuICAgICAgICBhcmdzLmNhbGxiYWNrID0gYXJncy5jYWxsYmFjayB8fCBkZWZhdWx0QXJncy5jYWxsYmFjaztcbiAgICAgIH1cbiAgICAgIHRoaXMuZmlsdGVyVG9FbHModmlldy5saXZlU29ja2V0LCBzb3VyY2VFbCwgYXJncykuZm9yRWFjaCgoZWwpID0+IHtcbiAgICAgICAgdGhpc1tgZXhlY18ke2tpbmR9YF0oZSwgZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCBhcmdzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBpc1Zpc2libGUoZWwpIHtcbiAgICByZXR1cm4gISEoZWwub2Zmc2V0V2lkdGggfHwgZWwub2Zmc2V0SGVpZ2h0IHx8IGVsLmdldENsaWVudFJlY3RzKCkubGVuZ3RoID4gMCk7XG4gIH0sXG4gIC8vIHJldHVybnMgdHJ1ZSBpZiBhbnkgcGFydCBvZiB0aGUgZWxlbWVudCBpcyBpbnNpZGUgdGhlIHZpZXdwb3J0XG4gIGlzSW5WaWV3cG9ydChlbCkge1xuICAgIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCB3aW5kb3dIZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodDtcbiAgICBjb25zdCB3aW5kb3dXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aDtcbiAgICByZXR1cm4gcmVjdC5yaWdodCA+IDAgJiYgcmVjdC5ib3R0b20gPiAwICYmIHJlY3QubGVmdCA8IHdpbmRvd1dpZHRoICYmIHJlY3QudG9wIDwgd2luZG93SGVpZ2h0O1xuICB9LFxuICAvLyBwcml2YXRlXG4gIC8vIGNvbW1hbmRzXG4gIGV4ZWNfZXhlYyhlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHsgYXR0ciwgdG8gfSkge1xuICAgIGNvbnN0IGVuY29kZWRKUyA9IGVsLmdldEF0dHJpYnV0ZShhdHRyKTtcbiAgICBpZiAoIWVuY29kZWRKUykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBleHBlY3RlZCAke2F0dHJ9IHRvIGNvbnRhaW4gSlMgY29tbWFuZCBvbiBcIiR7dG99XCJgKTtcbiAgICB9XG4gICAgdmlldy5saXZlU29ja2V0LmV4ZWNKUyhlbCwgZW5jb2RlZEpTLCBldmVudFR5cGUpO1xuICB9LFxuICBleGVjX2Rpc3BhdGNoKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBldmVudCwgZGV0YWlsLCBidWJibGVzLCBibG9ja2luZyB9KSB7XG4gICAgZGV0YWlsID0gZGV0YWlsIHx8IHt9O1xuICAgIGRldGFpbC5kaXNwYXRjaGVyID0gc291cmNlRWw7XG4gICAgaWYgKGJsb2NraW5nKSB7XG4gICAgICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICAgICAgZGV0YWlsLmRvbmUgPSByZXNvbHZlO1xuICAgICAgfSk7XG4gICAgICB2aWV3LmxpdmVTb2NrZXQuYXN5bmNUcmFuc2l0aW9uKHByb21pc2UpO1xuICAgIH1cbiAgICBkb21fZGVmYXVsdC5kaXNwYXRjaEV2ZW50KGVsLCBldmVudCwgeyBkZXRhaWwsIGJ1YmJsZXMgfSk7XG4gIH0sXG4gIGV4ZWNfcHVzaChlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIGFyZ3MpIHtcbiAgICBjb25zdCB7XG4gICAgICBldmVudCxcbiAgICAgIGRhdGEsXG4gICAgICB0YXJnZXQsXG4gICAgICBwYWdlX2xvYWRpbmcsXG4gICAgICBsb2FkaW5nLFxuICAgICAgdmFsdWUsXG4gICAgICBkaXNwYXRjaGVyLFxuICAgICAgY2FsbGJhY2tcbiAgICB9ID0gYXJncztcbiAgICBjb25zdCBwdXNoT3B0cyA9IHtcbiAgICAgIGxvYWRpbmcsXG4gICAgICB2YWx1ZSxcbiAgICAgIHRhcmdldCxcbiAgICAgIHBhZ2VfbG9hZGluZzogISFwYWdlX2xvYWRpbmcsXG4gICAgICBvcmlnaW5hbEV2ZW50OiBlXG4gICAgfTtcbiAgICBjb25zdCB0YXJnZXRTcmMgPSBldmVudFR5cGUgPT09IFwiY2hhbmdlXCIgJiYgZGlzcGF0Y2hlciA/IGRpc3BhdGNoZXIgOiBzb3VyY2VFbDtcbiAgICBjb25zdCBwaHhUYXJnZXQgPSB0YXJnZXQgfHwgdGFyZ2V0U3JjLmdldEF0dHJpYnV0ZSh2aWV3LmJpbmRpbmcoXCJ0YXJnZXRcIikpIHx8IHRhcmdldFNyYztcbiAgICBjb25zdCBoYW5kbGVyID0gKHRhcmdldFZpZXcsIHRhcmdldEN0eCkgPT4ge1xuICAgICAgaWYgKCF0YXJnZXRWaWV3LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50VHlwZSA9PT0gXCJjaGFuZ2VcIikge1xuICAgICAgICBsZXQgeyBuZXdDaWQsIF90YXJnZXQgfSA9IGFyZ3M7XG4gICAgICAgIF90YXJnZXQgPSBfdGFyZ2V0IHx8IChkb21fZGVmYXVsdC5pc0Zvcm1Bc3NvY2lhdG
1VkKHNvdXJjZUVsKSA/IHNvdXJjZUVsLm5hbWUgOiB2b2lkIDApO1xuICAgICAgICBpZiAoX3RhcmdldCkge1xuICAgICAgICAgIHB1c2hPcHRzLl90YXJnZXQgPSBfdGFyZ2V0O1xuICAgICAgICB9XG4gICAgICAgIHRhcmdldFZpZXcucHVzaElucHV0KFxuICAgICAgICAgIHNvdXJjZUVsLFxuICAgICAgICAgIHRhcmdldEN0eCxcbiAgICAgICAgICBuZXdDaWQsXG4gICAgICAgICAgZXZlbnQgfHwgcGh4RXZlbnQsXG4gICAgICAgICAgcHVzaE9wdHMsXG4gICAgICAgICAgY2FsbGJhY2tcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoZXZlbnRUeXBlID09PSBcInN1Ym1pdFwiKSB7XG4gICAgICAgIGNvbnN0IHsgc3VibWl0dGVyIH0gPSBhcmdzO1xuICAgICAgICB0YXJnZXRWaWV3LnN1Ym1pdEZvcm0oXG4gICAgICAgICAgc291cmNlRWwsXG4gICAgICAgICAgdGFyZ2V0Q3R4LFxuICAgICAgICAgIGV2ZW50IHx8IHBoeEV2ZW50LFxuICAgICAgICAgIHN1Ym1pdHRlcixcbiAgICAgICAgICBwdXNoT3B0cyxcbiAgICAgICAgICBjYWxsYmFja1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGFyZ2V0Vmlldy5wdXNoRXZlbnQoXG4gICAgICAgICAgZXZlbnRUeXBlLFxuICAgICAgICAgIHNvdXJjZUVsLFxuICAgICAgICAgIHRhcmdldEN0eCxcbiAgICAgICAgICBldmVudCB8fCBwaHhFdmVudCxcbiAgICAgICAgICBkYXRhLFxuICAgICAgICAgIHB1c2hPcHRzLFxuICAgICAgICAgIGNhbGxiYWNrXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfTtcbiAgICBpZiAoYXJncy50YXJnZXRWaWV3ICYmIGFyZ3MudGFyZ2V0Q3R4KSB7XG4gICAgICBoYW5kbGVyKGFyZ3MudGFyZ2V0VmlldywgYXJncy50YXJnZXRDdHgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2aWV3LndpdGhpblRhcmdldHMocGh4VGFyZ2V0LCBoYW5kbGVyKTtcbiAgICB9XG4gIH0sXG4gIGV4ZWNfbmF2aWdhdGUoZSwgZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7IGhyZWYsIHJlcGxhY2UgfSkge1xuICAgIHZpZXcubGl2ZVNvY2tldC5oaXN0b3J5UmVkaXJlY3QoXG4gICAgICBlLFxuICAgICAgaHJlZixcbiAgICAgIHJlcGxhY2UgPyBcInJlcGxhY2VcIiA6IFwicHVzaFwiLFxuICAgICAgbnVsbCxcbiAgICAgIHNvdXJjZUVsXG4gICAgKTtcbiAgfSxcbiAgZXhlY19wYXRjaChlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHsgaHJlZiwgcmVwbGFjZSB9KSB7XG4gICAgdmlldy5saXZlU29ja2V0LnB1c2hIaXN0b3J5UGF0Y2goXG4gICAgICBlLFxuICAgICAgaHJlZixcbiAgICAgIHJlcGxhY2UgPyBcInJlcGxhY2VcIiA6IFwicHVzaFwiLFxuICAgICAgc291cmNlRWxcbiAgICApO1xuICB9LFxuICBleGVjX2ZvY3VzKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCkge1xuICAgIGFyaWFfZGVmYXVsdC5hdHRlbXB0Rm9jdXMoZWwpO1xuICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiBhcmlhX2RlZmF1bHQuYXR0ZW1wdEZvY3VzKGVsKSk7XG4gICAgfSk7XG4gIH0sXG4gIGV4ZWNfZm9jdXNfZmlyc3QoZSwgZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsKSB7XG4gICAgYXJpYV9kZWZhdWx0LmZvY3VzRmlyc3RJbnRlcmFjdGl2ZShlbCkgfHwgYXJpYV9kZWZhdWx0LmZvY3VzRmlyc3QoZWwpO1xuICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZShcbiAgICAgICAgKCkgPT4gYXJpYV9kZWZhdWx0LmZvY3VzRmlyc3RJbnRlcmFjdGl2ZShlbCkgfHwgYXJpYV9kZWZhdWx0LmZvY3VzRmlyc3QoZWwpXG4gICAgICApO1xuICAgIH0pO1xuICB9LFxuICBleGVjX3B1c2hfZm9jdXMoZSwgZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsKSB7XG4gICAgZm9jdXNTdGFjay5wdXNoKGVsIHx8IHNvdXJjZUVsKTtcbiAgfSxcbiAgZXhlY19wb3BfZm9jdXMoX2UsIF9ldmVudFR5cGUsIF9waHhFdmVudCwgX3ZpZXcsIF9zb3VyY2VFbCwgX2VsKSB7XG4gICAgY29uc3QgZWwgPSBmb2N1c1N0YWNrLnBvcCgpO1xuICAgIGlmIChlbCkge1xuICAgICAgZWwuZm9jdXMoKTtcbiAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IGVsLmZvY3VzKCkpO1xuICAgICAgfSk7XG4gICAgfVxuICB9LFxuICBleGVjX2FkZF9jbGFzcyhlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHsgbmFtZXMsIHRyYW5zaXRpb24sIHRpbWUsIGJsb2NraW5nIH0pIHtcbiAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgbmFtZXMsIFtdLCB0cmFuc2l0aW9uLCB0aW1lLCB2aWV3LCBibG9ja2luZyk7XG4gIH0sXG4gIGV4ZWNfcmVtb3ZlX2NsYXNzKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBuYW1lcywgdHJhbnNpdGlvbiwgdGltZSwgYmxvY2tpbmcgfSkge1xuICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBbXSwgbmFtZXMsIHRyYW5zaXRpb24sIHRpbWUsIHZpZXcsIGJsb2NraW5nKTtcbiAgfSxcbiAgZXhlY190b2dnbGVfY2xhc3MoZSwgZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7IG5hbWVzLCB0cmFuc2l0aW9uLCB0aW1lLCBibG9ja2luZyB9KSB7XG4gICAgdGhpcy50b2dnbGVDbGFzc2VzKGVsLCBuYW1lcywgdHJhbnNpdGlvbiwgdGltZSwgdmlldywgYmxvY2tpbmcpO1xuICB9LFxuICBleGVjX3RvZ2dsZV9hdHRyKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBhdHRyOiBbYXR0ciwgdmFsMSwgdmFsMl0gfSkge1xuICAgIHRoaXMudG9nZ2xlQXR0cihlbCwgYXR0ciwgdmFsMSwgdmFsMik7XG4gIH0sXG4gIGV4ZWNfaWdub3JlX2F0dHJzKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBhdHRycyB9KSB7XG4gICAgdGhpcy5pZ25vcmVBdHRycyhlbCwgYX
1R0cnMpO1xuICB9LFxuICBleGVjX3RyYW5zaXRpb24oZSwgZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7IHRpbWUsIHRyYW5zaXRpb24sIGJsb2NraW5nIH0pIHtcbiAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgW10sIFtdLCB0cmFuc2l0aW9uLCB0aW1lLCB2aWV3LCBibG9ja2luZyk7XG4gIH0sXG4gIGV4ZWNfdG9nZ2xlKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBkaXNwbGF5LCBpbnMsIG91dHMsIHRpbWUsIGJsb2NraW5nIH0pIHtcbiAgICB0aGlzLnRvZ2dsZShldmVudFR5cGUsIHZpZXcsIGVsLCBkaXNwbGF5LCBpbnMsIG91dHMsIHRpbWUsIGJsb2NraW5nKTtcbiAgfSxcbiAgZXhlY19zaG93KGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBkaXNwbGF5LCB0cmFuc2l0aW9uLCB0aW1lLCBibG9ja2luZyB9KSB7XG4gICAgdGhpcy5zaG93KGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIHRyYW5zaXRpb24sIHRpbWUsIGJsb2NraW5nKTtcbiAgfSxcbiAgZXhlY19oaWRlKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBkaXNwbGF5LCB0cmFuc2l0aW9uLCB0aW1lLCBibG9ja2luZyB9KSB7XG4gICAgdGhpcy5oaWRlKGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIHRyYW5zaXRpb24sIHRpbWUsIGJsb2NraW5nKTtcbiAgfSxcbiAgZXhlY19zZXRfYXR0cihlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHsgYXR0cjogW2F0dHIsIHZhbF0gfSkge1xuICAgIHRoaXMuc2V0T3JSZW1vdmVBdHRycyhlbCwgW1thdHRyLCB2YWxdXSwgW10pO1xuICB9LFxuICBleGVjX3JlbW92ZV9hdHRyKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBhdHRyIH0pIHtcbiAgICB0aGlzLnNldE9yUmVtb3ZlQXR0cnMoZWwsIFtdLCBbYXR0cl0pO1xuICB9LFxuICBpZ25vcmVBdHRycyhlbCwgYXR0cnMpIHtcbiAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKGVsLCBcIkpTOmlnbm9yZV9hdHRyc1wiLCB7XG4gICAgICBhcHBseTogKGZyb21FbCwgdG9FbCkgPT4ge1xuICAgICAgICBsZXQgZnJvbUF0dHJpYnV0ZXMgPSBBcnJheS5mcm9tKGZyb21FbC5hdHRyaWJ1dGVzKTtcbiAgICAgICAgbGV0IGZyb21BdHRyaWJ1dGVOYW1lcyA9IGZyb21BdHRyaWJ1dGVzLm1hcCgoYXR0cikgPT4gYXR0ci5uYW1lKTtcbiAgICAgICAgQXJyYXkuZnJvbSh0b0VsLmF0dHJpYnV0ZXMpLmZpbHRlcigoYXR0cikgPT4ge1xuICAgICAgICAgIHJldHVybiAhZnJvbUF0dHJpYnV0ZU5hbWVzLmluY2x1ZGVzKGF0dHIubmFtZSk7XG4gICAgICAgIH0pLmZvckVhY2goKGF0dHIpID0+IHtcbiAgICAgICAgICBpZiAoZG9tX2RlZmF1bHQuYXR0cmlidXRlSWdub3JlZChhdHRyLCBhdHRycykpIHtcbiAgICAgICAgICAgIHRvRWwucmVtb3ZlQXR0cmlidXRlKGF0dHIubmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgZnJvbUF0dHJpYnV0ZXMuZm9yRWFjaCgoYXR0cikgPT4ge1xuICAgICAgICAgIGlmIChkb21fZGVmYXVsdC5hdHRyaWJ1dGVJZ25vcmVkKGF0dHIsIGF0dHJzKSkge1xuICAgICAgICAgICAgdG9FbC5zZXRBdHRyaWJ1dGUoYXR0ci5uYW1lLCBhdHRyLnZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9LFxuICBvbkJlZm9yZUVsVXBkYXRlZChmcm9tRWwsIHRvRWwpIHtcbiAgICBjb25zdCBpZ25vcmVBdHRycyA9IGRvbV9kZWZhdWx0LnByaXZhdGUoZnJvbUVsLCBcIkpTOmlnbm9yZV9hdHRyc1wiKTtcbiAgICBpZiAoaWdub3JlQXR0cnMpIHtcbiAgICAgIGlnbm9yZUF0dHJzLmFwcGx5KGZyb21FbCwgdG9FbCk7XG4gICAgfVxuICB9LFxuICAvLyB1dGlscyBmb3IgY29tbWFuZHNcbiAgc2hvdyhldmVudFR5cGUsIHZpZXcsIGVsLCBkaXNwbGF5LCB0cmFuc2l0aW9uLCB0aW1lLCBibG9ja2luZykge1xuICAgIGlmICghdGhpcy5pc1Zpc2libGUoZWwpKSB7XG4gICAgICB0aGlzLnRvZ2dsZShcbiAgICAgICAgZXZlbnRUeXBlLFxuICAgICAgICB2aWV3LFxuICAgICAgICBlbCxcbiAgICAgICAgZGlzcGxheSxcbiAgICAgICAgdHJhbnNpdGlvbixcbiAgICAgICAgbnVsbCxcbiAgICAgICAgdGltZSxcbiAgICAgICAgYmxvY2tpbmdcbiAgICAgICk7XG4gICAgfVxuICB9LFxuICBoaWRlKGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIHRyYW5zaXRpb24sIHRpbWUsIGJsb2NraW5nKSB7XG4gICAgaWYgKHRoaXMuaXNWaXNpYmxlKGVsKSkge1xuICAgICAgdGhpcy50b2dnbGUoXG4gICAgICAgIGV2ZW50VHlwZSxcbiAgICAgICAgdmlldyxcbiAgICAgICAgZWwsXG4gICAgICAgIGRpc3BsYXksXG4gICAgICAgIG51bGwsXG4gICAgICAgIHRyYW5zaXRpb24sXG4gICAgICAgIHRpbWUsXG4gICAgICAgIGJsb2NraW5nXG4gICAgICApO1xuICAgIH1cbiAgfSxcbiAgdG9nZ2xlKGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIGlucywgb3V0cywgdGltZSwgYmxvY2tpbmcpIHtcbiAgICB0aW1lID0gdGltZSB8fCBkZWZhdWx0X3RyYW5zaXRpb25fdGltZTtcbiAgICBjb25zdCBbaW5DbGFzc2VzLCBpblN0YXJ0Q2xhc3NlcywgaW5FbmRDbGFzc2VzXSA9IGlucyB8fCBbW10sIFtdLCBbXV07XG4gICAgY29uc3QgW291dENsYXNzZXMsIG91dFN0YXJ0Q2xhc3Nlcywgb3V0RW5kQ2xhc3Nlc10gPSBvdXRzIHx8IFtbXSwgW10sIFtdXTtcbiAgICBpZiAoaW5DbGFzc2VzLmxlbmd0aCA+IDAgfHwgb3V0Q2xhc3Nlcy5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAodGhpcy5pc1Zpc2libGUoZWwpKSB7XG4gICAgICAgIGNvbnN0IG9uU3RhcnQgPSAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoXG4gICAgICAgICAgICBlbCxcbiAgICAgICAgICAgIG91dFN0YXJ0Q2xhc3NlcyxcbiAgICAgICAgICAgIGluQ2xhc3Nlcy5jb25jYXQoaW5TdGFydENsYXNzZXMpLmNvbmNhdChpbkVuZENsYXNzZXMpXG4gICAgICAgICAgKTtcbiAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgI
1HRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBvdXRDbGFzc2VzLCBbXSk7XG4gICAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKFxuICAgICAgICAgICAgICAoKSA9PiB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgb3V0RW5kQ2xhc3Nlcywgb3V0U3RhcnRDbGFzc2VzKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgb25FbmQgPSAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIFtdLCBvdXRDbGFzc2VzLmNvbmNhdChvdXRFbmRDbGFzc2VzKSk7XG4gICAgICAgICAgZG9tX2RlZmF1bHQucHV0U3RpY2t5KFxuICAgICAgICAgICAgZWwsXG4gICAgICAgICAgICBcInRvZ2dsZVwiLFxuICAgICAgICAgICAgKGN1cnJlbnRFbCkgPT4gY3VycmVudEVsLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIlxuICAgICAgICAgICk7XG4gICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJwaHg6aGlkZS1lbmRcIikpO1xuICAgICAgICB9O1xuICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpoaWRlLXN0YXJ0XCIpKTtcbiAgICAgICAgaWYgKGJsb2NraW5nID09PSBmYWxzZSkge1xuICAgICAgICAgIG9uU3RhcnQoKTtcbiAgICAgICAgICBzZXRUaW1lb3V0KG9uRW5kLCB0aW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2aWV3LnRyYW5zaXRpb24odGltZSwgb25TdGFydCwgb25FbmQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZXZlbnRUeXBlID09PSBcInJlbW92ZVwiKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9uU3RhcnQgPSAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoXG4gICAgICAgICAgICBlbCxcbiAgICAgICAgICAgIGluU3RhcnRDbGFzc2VzLFxuICAgICAgICAgICAgb3V0Q2xhc3Nlcy5jb25jYXQob3V0U3RhcnRDbGFzc2VzKS5jb25jYXQob3V0RW5kQ2xhc3NlcylcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHN0aWNreURpc3BsYXkgPSBkaXNwbGF5IHx8IHRoaXMuZGVmYXVsdERpc3BsYXkoZWwpO1xuICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIGluQ2xhc3NlcywgW10pO1xuICAgICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICAgIGRvbV9kZWZhdWx0LnB1dFN0aWNreShcbiAgICAgICAgICAgICAgICBlbCxcbiAgICAgICAgICAgICAgICBcInRvZ2dsZVwiLFxuICAgICAgICAgICAgICAgIChjdXJyZW50RWwpID0+IGN1cnJlbnRFbC5zdHlsZS5kaXNwbGF5ID0gc3RpY2t5RGlzcGxheVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgaW5FbmRDbGFzc2VzLCBpblN0YXJ0Q2xhc3Nlcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgb25FbmQgPSAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIFtdLCBpbkNsYXNzZXMuY29uY2F0KGluRW5kQ2xhc3NlcykpO1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OnNob3ctZW5kXCIpKTtcbiAgICAgICAgfTtcbiAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJwaHg6c2hvdy1zdGFydFwiKSk7XG4gICAgICAgIGlmIChibG9ja2luZyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICBvblN0YXJ0KCk7XG4gICAgICAgICAgc2V0VGltZW91dChvbkVuZCwgdGltZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmlldy50cmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRW5kKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5pc1Zpc2libGUoZWwpKSB7XG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OmhpZGUtc3RhcnRcIikpO1xuICAgICAgICAgIGRvbV9kZWZhdWx0LnB1dFN0aWNreShcbiAgICAgICAgICAgIGVsLFxuICAgICAgICAgICAgXCJ0b2dnbGVcIixcbiAgICAgICAgICAgIChjdXJyZW50RWwpID0+IGN1cnJlbnRFbC5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCJcbiAgICAgICAgICApO1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OmhpZGUtZW5kXCIpKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpzaG93LXN0YXJ0XCIpKTtcbiAgICAgICAgICBjb25zdCBzdGlja3lEaXNwbGF5ID0gZGlzcGxheSB8fCB0aGlzLmRlZmF1bHREaXNwbGF5KGVsKTtcbiAgICAgICAgICBkb21fZGVmYXVsdC5wdXRTdGlja3koXG4gICAgICAgICAgICBlbCxcbiAgICAgICAgICAgIFwidG9nZ2xlXCIsXG4gICAgICAgICAgICAoY3VycmVudEVsKSA9PiBjdXJyZW50RWwuc3R5bGUuZGlzcGxheSA9IHN0aWNreURpc3BsYXlcbiAgICAgICAgICApO1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OnNob3ctZW5kXCIpKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICB0b2dnbGVDbGFzc2VzKGVsLCBjbGFzc2VzLCB0cmFuc2l0aW9uLCB0aW1lLCB2aWV3LCBibG9ja2luZykge1xuICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgY29uc3QgW3ByZXZBZGRzLCBwcmV2UmVtb3Zlc10gPSBkb21fZGVmYXVsdC5nZXRTdGlja3koZWwsIFwiY2xhc3Nlc1wiLCBbW10sIFtdXSk7XG4gICAgICBjb25zdCBuZXdBZGRzID0gY2xhc3Nlcy5maWx0ZXIoXG4gICAgICAgIChuYW1lKSA9PiBwcmV2QWRkcy5pbmRleE9mKG5hbW
1UpIDwgMCAmJiAhZWwuY2xhc3NMaXN0LmNvbnRhaW5zKG5hbWUpXG4gICAgICApO1xuICAgICAgY29uc3QgbmV3UmVtb3ZlcyA9IGNsYXNzZXMuZmlsdGVyKFxuICAgICAgICAobmFtZSkgPT4gcHJldlJlbW92ZXMuaW5kZXhPZihuYW1lKSA8IDAgJiYgZWwuY2xhc3NMaXN0LmNvbnRhaW5zKG5hbWUpXG4gICAgICApO1xuICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoXG4gICAgICAgIGVsLFxuICAgICAgICBuZXdBZGRzLFxuICAgICAgICBuZXdSZW1vdmVzLFxuICAgICAgICB0cmFuc2l0aW9uLFxuICAgICAgICB0aW1lLFxuICAgICAgICB2aWV3LFxuICAgICAgICBibG9ja2luZ1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSxcbiAgdG9nZ2xlQXR0cihlbCwgYXR0ciwgdmFsMSwgdmFsMikge1xuICAgIGlmIChlbC5oYXNBdHRyaWJ1dGUoYXR0cikpIHtcbiAgICAgIGlmICh2YWwyICE9PSB2b2lkIDApIHtcbiAgICAgICAgaWYgKGVsLmdldEF0dHJpYnV0ZShhdHRyKSA9PT0gdmFsMSkge1xuICAgICAgICAgIHRoaXMuc2V0T3JSZW1vdmVBdHRycyhlbCwgW1thdHRyLCB2YWwyXV0sIFtdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNldE9yUmVtb3ZlQXR0cnMoZWwsIFtbYXR0ciwgdmFsMV1dLCBbXSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0T3JSZW1vdmVBdHRycyhlbCwgW10sIFthdHRyXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0T3JSZW1vdmVBdHRycyhlbCwgW1thdHRyLCB2YWwxXV0sIFtdKTtcbiAgICB9XG4gIH0sXG4gIGFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgYWRkcywgcmVtb3ZlcywgdHJhbnNpdGlvbiwgdGltZSwgdmlldywgYmxvY2tpbmcpIHtcbiAgICB0aW1lID0gdGltZSB8fCBkZWZhdWx0X3RyYW5zaXRpb25fdGltZTtcbiAgICBjb25zdCBbdHJhbnNpdGlvblJ1biwgdHJhbnNpdGlvblN0YXJ0LCB0cmFuc2l0aW9uRW5kXSA9IHRyYW5zaXRpb24gfHwgW1xuICAgICAgW10sXG4gICAgICBbXSxcbiAgICAgIFtdXG4gICAgXTtcbiAgICBpZiAodHJhbnNpdGlvblJ1bi5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBvblN0YXJ0ID0gKCkgPT4ge1xuICAgICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhcbiAgICAgICAgICBlbCxcbiAgICAgICAgICB0cmFuc2l0aW9uU3RhcnQsXG4gICAgICAgICAgW10uY29uY2F0KHRyYW5zaXRpb25SdW4pLmNvbmNhdCh0cmFuc2l0aW9uRW5kKVxuICAgICAgICApO1xuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgdHJhbnNpdGlvblJ1biwgW10pO1xuICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoXG4gICAgICAgICAgICAoKSA9PiB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgdHJhbnNpdGlvbkVuZCwgdHJhbnNpdGlvblN0YXJ0KVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICAgIGNvbnN0IG9uRG9uZSA9ICgpID0+IHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKFxuICAgICAgICBlbCxcbiAgICAgICAgYWRkcy5jb25jYXQodHJhbnNpdGlvbkVuZCksXG4gICAgICAgIHJlbW92ZXMuY29uY2F0KHRyYW5zaXRpb25SdW4pLmNvbmNhdCh0cmFuc2l0aW9uU3RhcnQpXG4gICAgICApO1xuICAgICAgaWYgKGJsb2NraW5nID09PSBmYWxzZSkge1xuICAgICAgICBvblN0YXJ0KCk7XG4gICAgICAgIHNldFRpbWVvdXQob25Eb25lLCB0aW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZpZXcudHJhbnNpdGlvbih0aW1lLCBvblN0YXJ0LCBvbkRvbmUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgIGNvbnN0IFtwcmV2QWRkcywgcHJldlJlbW92ZXNdID0gZG9tX2RlZmF1bHQuZ2V0U3RpY2t5KGVsLCBcImNsYXNzZXNcIiwgW1tdLCBbXV0pO1xuICAgICAgY29uc3Qga2VlcEFkZHMgPSBhZGRzLmZpbHRlcihcbiAgICAgICAgKG5hbWUpID0+IHByZXZBZGRzLmluZGV4T2YobmFtZSkgPCAwICYmICFlbC5jbGFzc0xpc3QuY29udGFpbnMobmFtZSlcbiAgICAgICk7XG4gICAgICBjb25zdCBrZWVwUmVtb3ZlcyA9IHJlbW92ZXMuZmlsdGVyKFxuICAgICAgICAobmFtZSkgPT4gcHJldlJlbW92ZXMuaW5kZXhPZihuYW1lKSA8IDAgJiYgZWwuY2xhc3NMaXN0LmNvbnRhaW5zKG5hbWUpXG4gICAgICApO1xuICAgICAgY29uc3QgbmV3QWRkcyA9IHByZXZBZGRzLmZpbHRlcigobmFtZSkgPT4gcmVtb3Zlcy5pbmRleE9mKG5hbWUpIDwgMCkuY29uY2F0KGtlZXBBZGRzKTtcbiAgICAgIGNvbnN0IG5ld1JlbW92ZXMgPSBwcmV2UmVtb3Zlcy5maWx0ZXIoKG5hbWUpID0+IGFkZHMuaW5kZXhPZihuYW1lKSA8IDApLmNvbmNhdChrZWVwUmVtb3Zlcyk7XG4gICAgICBkb21fZGVmYXVsdC5wdXRTdGlja3koZWwsIFwiY2xhc3Nlc1wiLCAoY3VycmVudEVsKSA9PiB7XG4gICAgICAgIGN1cnJlbnRFbC5jbGFzc0xpc3QucmVtb3ZlKC4uLm5ld1JlbW92ZXMpO1xuICAgICAgICBjdXJyZW50RWwuY2xhc3NMaXN0LmFkZCguLi5uZXdBZGRzKTtcbiAgICAgICAgcmV0dXJuIFtuZXdBZGRzLCBuZXdSZW1vdmVzXTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBzZXRPclJlbW92ZUF0dHJzKGVsLCBzZXRzLCByZW1vdmVzKSB7XG4gICAgY29uc3QgW3ByZXZTZXRzLCBwcmV2UmVtb3Zlc10gPSBkb21fZGVmYXVsdC5nZXRTdGlja3koZWwsIFwiYXR0cnNcIiwgW1tdLCBbXV0pO1xuICAgIGNvbnN0IGFsdGVyZWRBdHRycyA9IHNldHMubWFwKChbYXR0ciwgX3ZhbF0pID0+IGF0dHIpLmNvbmNhdChyZW1vdmVzKTtcbiAgICBjb25zdCBuZXdTZXRzID0gcHJldlNldHMuZmlsdGVyKChbYXR0ciwgX3ZhbF0pID0+ICFhbHRlcmVkQXR0cnMuaW5jbHVkZXMoYXR0cikpLmNvbmNhdChzZXRzKTtcbiAgICBjb25zdCBuZXdSZW1vdmVzID0gcHJldlJlbW92ZXMuZmlsdGVyKChhdHRyKSA9PiAhYWx0ZXJlZEF0dHJzLmluY2x1ZGVzKGF0dHIpKS5jb25jYXQocmVtb3Zlcyk7XG4gICAgaWYgKHNldHMuc29tZSgoW2F0dHIsIF92YWxdKSA9PiBhdHRyID09PSBcImlkXCIpKSB7XG4gICAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKGVsLCBcImNsaWVudHNpZGVJZEF0dHJpYnV0ZVwiLCB0cnVlKTtcbiAgICB9XG4gICAgZG9tX2RlZmF1bHQucHV0U3RpY2t5KGVsLCBcImF0dHJzXCIsIChjdXJyZW50RWwpID0+IHtcbiAgICAgIG5ld1JlbW92ZXMuZm9yRWFjaCgoYXR0cikgPT4gY3VycmVudEVsLnJlbW92ZUF0dHJpYnV0ZShhdHRyKSk7XG4gICAgICBuZXdTZXRzLmZvckVhY2goKFthdHRyLCB2YWxdKSA9PiBjdXJyZW50RWwuc2V0QXR0cmlidXRlKGF0dHIsIHZhbCkpO1xuICAgICAgcmV0dXJuIFtuZXdTZXRzLCBuZXdSZW1vdmVzXTtcbiAgICB9KTtcbiAgfSxcbiAgaGFzQWxsQ2xhc3NlcyhlbCwgY2xhc3Nlcykge1xuICAgIHJldHVybi
1BjbGFzc2VzLmV2ZXJ5KChuYW1lKSA9PiBlbC5jbGFzc0xpc3QuY29udGFpbnMobmFtZSkpO1xuICB9LFxuICBpc1RvZ2dsZWRPdXQoZWwsIG91dENsYXNzZXMpIHtcbiAgICByZXR1cm4gIXRoaXMuaXNWaXNpYmxlKGVsKSB8fCB0aGlzLmhhc0FsbENsYXNzZXMoZWwsIG91dENsYXNzZXMpO1xuICB9LFxuICBmaWx0ZXJUb0VscyhsaXZlU29ja2V0LCBzb3VyY2VFbCwgeyB0byB9KSB7XG4gICAgY29uc3QgZGVmYXVsdFF1ZXJ5ID0gKCkgPT4ge1xuICAgICAgaWYgKHR5cGVvZiB0byA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCh0byk7XG4gICAgICB9IGVsc2UgaWYgKHRvLmNsb3Nlc3QpIHtcbiAgICAgICAgY29uc3QgdG9FbCA9IHNvdXJjZUVsLmNsb3Nlc3QodG8uY2xvc2VzdCk7XG4gICAgICAgIHJldHVybiB0b0VsID8gW3RvRWxdIDogW107XG4gICAgICB9IGVsc2UgaWYgKHRvLmlubmVyKSB7XG4gICAgICAgIHJldHVybiBzb3VyY2VFbC5xdWVyeVNlbGVjdG9yQWxsKHRvLmlubmVyKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiB0byA/IGxpdmVTb2NrZXQuanNRdWVyeVNlbGVjdG9yQWxsKHNvdXJjZUVsLCB0bywgZGVmYXVsdFF1ZXJ5KSA6IFtzb3VyY2VFbF07XG4gIH0sXG4gIGRlZmF1bHREaXNwbGF5KGVsKSB7XG4gICAgcmV0dXJuIHsgdHI6IFwidGFibGUtcm93XCIsIHRkOiBcInRhYmxlLWNlbGxcIiB9W2VsLnRhZ05hbWUudG9Mb3dlckNhc2UoKV0gfHwgXCJibG9ja1wiO1xuICB9LFxuICB0cmFuc2l0aW9uQ2xhc3Nlcyh2YWwpIHtcbiAgICBpZiAoIXZhbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGxldCBbdHJhbnMsIHRTdGFydCwgdEVuZF0gPSBBcnJheS5pc0FycmF5KHZhbCkgPyB2YWwgOiBbdmFsLnNwbGl0KFwiIFwiKSwgW10sIFtdXTtcbiAgICB0cmFucyA9IEFycmF5LmlzQXJyYXkodHJhbnMpID8gdHJhbnMgOiB0cmFucy5zcGxpdChcIiBcIik7XG4gICAgdFN0YXJ0ID0gQXJyYXkuaXNBcnJheSh0U3RhcnQpID8gdFN0YXJ0IDogdFN0YXJ0LnNwbGl0KFwiIFwiKTtcbiAgICB0RW5kID0gQXJyYXkuaXNBcnJheSh0RW5kKSA/IHRFbmQgOiB0RW5kLnNwbGl0KFwiIFwiKTtcbiAgICByZXR1cm4gW3RyYW5zLCB0U3RhcnQsIHRFbmRdO1xuICB9XG59O1xudmFyIGpzX2RlZmF1bHQgPSBKUztcblxuLy8ganMvcGhvZW5peF9saXZlX3ZpZXcvanNfY29tbWFuZHMudHNcbnZhciBqc19jb21tYW5kc19kZWZhdWx0ID0gKGxpdmVTb2NrZXQsIGV2ZW50VHlwZSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGV4ZWMoZWwsIGVuY29kZWRKUykge1xuICAgICAgbGl2ZVNvY2tldC5leGVjSlMoZWwsIGVuY29kZWRKUywgZXZlbnRUeXBlKTtcbiAgICB9LFxuICAgIHNob3coZWwsIG9wdHMgPSB7fSkge1xuICAgICAgY29uc3Qgb3duZXIgPSBsaXZlU29ja2V0Lm93bmVyKGVsKTtcbiAgICAgIGpzX2RlZmF1bHQuc2hvdyhcbiAgICAgICAgZXZlbnRUeXBlLFxuICAgICAgICBvd25lcixcbiAgICAgICAgZWwsXG4gICAgICAgIG9wdHMuZGlzcGxheSxcbiAgICAgICAganNfZGVmYXVsdC50cmFuc2l0aW9uQ2xhc3NlcyhvcHRzLnRyYW5zaXRpb24pLFxuICAgICAgICBvcHRzLnRpbWUsXG4gICAgICAgIG9wdHMuYmxvY2tpbmdcbiAgICAgICk7XG4gICAgfSxcbiAgICBoaWRlKGVsLCBvcHRzID0ge30pIHtcbiAgICAgIGNvbnN0IG93bmVyID0gbGl2ZVNvY2tldC5vd25lcihlbCk7XG4gICAgICBqc19kZWZhdWx0LmhpZGUoXG4gICAgICAgIGV2ZW50VHlwZSxcbiAgICAgICAgb3duZXIsXG4gICAgICAgIGVsLFxuICAgICAgICBudWxsLFxuICAgICAgICBqc19kZWZhdWx0LnRyYW5zaXRpb25DbGFzc2VzKG9wdHMudHJhbnNpdGlvbiksXG4gICAgICAgIG9wdHMudGltZSxcbiAgICAgICAgb3B0cy5ibG9ja2luZ1xuICAgICAgKTtcbiAgICB9LFxuICAgIHRvZ2dsZShlbCwgb3B0cyA9IHt9KSB7XG4gICAgICBjb25zdCBvd25lciA9IGxpdmVTb2NrZXQub3duZXIoZWwpO1xuICAgICAgY29uc3QgaW5UcmFuc2l0aW9uID0ganNfZGVmYXVsdC50cmFuc2l0aW9uQ2xhc3NlcyhvcHRzLmluKTtcbiAgICAgIGNvbnN0IG91dFRyYW5zaXRpb24gPSBqc19kZWZhdWx0LnRyYW5zaXRpb25DbGFzc2VzKG9wdHMub3V0KTtcbiAgICAgIGpzX2RlZmF1bHQudG9nZ2xlKFxuICAgICAgICBldmVudFR5cGUsXG4gICAgICAgIG93bmVyLFxuICAgICAgICBlbCxcbiAgICAgICAgb3B0cy5kaXNwbGF5LFxuICAgICAgICBpblRyYW5zaXRpb24sXG4gICAgICAgIG91dFRyYW5zaXRpb24sXG4gICAgICAgIG9wdHMudGltZSxcbiAgICAgICAgb3B0cy5ibG9ja2luZ1xuICAgICAgKTtcbiAgICB9LFxuICAgIGFkZENsYXNzKGVsLCBuYW1lcywgb3B0cyA9IHt9KSB7XG4gICAgICBjb25zdCBjbGFzc05hbWVzID0gQXJyYXkuaXNBcnJheShuYW1lcykgPyBuYW1lcyA6IG5hbWVzLnNwbGl0KFwiIFwiKTtcbiAgICAgIGNvbnN0IG93bmVyID0gbGl2ZVNvY2tldC5vd25lcihlbCk7XG4gICAgICBqc19kZWZhdWx0LmFkZE9yUmVtb3ZlQ2xhc3NlcyhcbiAgICAgICAgZWwsXG4gICAgICAgIGNsYXNzTmFtZXMsXG4gICAgICAgIFtdLFxuICAgICAgICBqc19kZWZhdWx0LnRyYW5zaXRpb25DbGFzc2VzKG9wdHMudHJhbnNpdGlvbiksXG4gICAgICAgIG9wdHMudGltZSxcbiAgICAgICAgb3duZXIsXG4gICAgICAgIG9wdHMuYmxvY2tpbmdcbiAgICAgICk7XG4gICAgfSxcbiAgICByZW1vdmVDbGFzcyhlbCwgbmFtZXMsIG9wdHMgPSB7fSkge1xuICAgICAgY29uc3QgY2xhc3NOYW1lcyA9IEFycmF5LmlzQXJyYXkobmFtZXMpID8gbmFtZXMgOiBuYW1lcy5zcGxpdChcIiBcIik7XG4gICAgICBjb25zdCBvd25lciA9IGxpdmVTb2NrZXQub3duZXIoZWwpO1xuICAgICAganNfZGVmYXVsdC5hZGRPclJlbW92ZUNsYXNzZXMoXG4gICAgICAgIGVsLFxuICAgICAgICBbXSxcbiAgICAgICAgY2xhc3NOYW1lcyxcbiAgICAgICAganNfZGVmYXVsdC50cmFuc2l0aW9uQ2xhc3NlcyhvcHRzLnRyYW5zaXRpb24pLFxuICAgICAgICBvcHRzLnRpbWUsXG4gICAgICAgIG93bmVyLFxuICAgICAgICBvcHRzLmJsb2NraW5nXG4gICAgICApO1xuICAgIH0sXG4gICAgdG9nZ2xlQ2xhc3MoZWwsIG5hbWVzLCBvcHRzID0ge30pIHtcbiAgICAgIGNvbnN0IGNsYXNzTmFtZXMgPSBBcnJheS5pc0FycmF
15KG5hbWVzKSA/IG5hbWVzIDogbmFtZXMuc3BsaXQoXCIgXCIpO1xuICAgICAgY29uc3Qgb3duZXIgPSBsaXZlU29ja2V0Lm93bmVyKGVsKTtcbiAgICAgIGpzX2RlZmF1bHQudG9nZ2xlQ2xhc3NlcyhcbiAgICAgICAgZWwsXG4gICAgICAgIGNsYXNzTmFtZXMsXG4gICAgICAgIGpzX2RlZmF1bHQudHJhbnNpdGlvbkNsYXNzZXMob3B0cy50cmFuc2l0aW9uKSxcbiAgICAgICAgb3B0cy50aW1lLFxuICAgICAgICBvd25lcixcbiAgICAgICAgb3B0cy5ibG9ja2luZ1xuICAgICAgKTtcbiAgICB9LFxuICAgIHRyYW5zaXRpb24oZWwsIHRyYW5zaXRpb24sIG9wdHMgPSB7fSkge1xuICAgICAgY29uc3Qgb3duZXIgPSBsaXZlU29ja2V0Lm93bmVyKGVsKTtcbiAgICAgIGpzX2RlZmF1bHQuYWRkT3JSZW1vdmVDbGFzc2VzKFxuICAgICAgICBlbCxcbiAgICAgICAgW10sXG4gICAgICAgIFtdLFxuICAgICAgICBqc19kZWZhdWx0LnRyYW5zaXRpb25DbGFzc2VzKHRyYW5zaXRpb24pLFxuICAgICAgICBvcHRzLnRpbWUsXG4gICAgICAgIG93bmVyLFxuICAgICAgICBvcHRzLmJsb2NraW5nXG4gICAgICApO1xuICAgIH0sXG4gICAgc2V0QXR0cmlidXRlKGVsLCBhdHRyLCB2YWwpIHtcbiAgICAgIGpzX2RlZmF1bHQuc2V0T3JSZW1vdmVBdHRycyhlbCwgW1thdHRyLCB2YWxdXSwgW10pO1xuICAgIH0sXG4gICAgcmVtb3ZlQXR0cmlidXRlKGVsLCBhdHRyKSB7XG4gICAgICBqc19kZWZhdWx0LnNldE9yUmVtb3ZlQXR0cnMoZWwsIFtdLCBbYXR0cl0pO1xuICAgIH0sXG4gICAgdG9nZ2xlQXR0cmlidXRlKGVsLCBhdHRyLCB2YWwxLCB2YWwyKSB7XG4gICAgICBqc19kZWZhdWx0LnRvZ2dsZUF0dHIoZWwsIGF0dHIsIHZhbDEsIHZhbDIpO1xuICAgIH0sXG4gICAgcHVzaChlbCwgdHlwZSwgb3B0cyA9IHt9KSB7XG4gICAgICBsaXZlU29ja2V0LndpdGhpbk93bmVycyhlbCwgKHZpZXcpID0+IHtcbiAgICAgICAgY29uc3QgZGF0YSA9IG9wdHMudmFsdWUgfHwge307XG4gICAgICAgIGRlbGV0ZSBvcHRzLnZhbHVlO1xuICAgICAgICBsZXQgZSA9IG5ldyBDdXN0b21FdmVudChcInBoeDpleGVjXCIsIHsgZGV0YWlsOiB7IHNvdXJjZUVsZW1lbnQ6IGVsIH0gfSk7XG4gICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCBldmVudFR5cGUsIHR5cGUsIHZpZXcsIGVsLCBbXCJwdXNoXCIsIHsgZGF0YSwgLi4ub3B0cyB9XSk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIG5hdmlnYXRlKGhyZWYsIG9wdHMgPSB7fSkge1xuICAgICAgZW5zdXJlU2FtZU9yaWdpbihocmVmLCBcIm5hdmlnYXRlXCIpO1xuICAgICAgY29uc3QgY3VzdG9tRXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQoXCJwaHg6ZXhlY1wiKTtcbiAgICAgIGxpdmVTb2NrZXQuaGlzdG9yeVJlZGlyZWN0KFxuICAgICAgICBjdXN0b21FdmVudCxcbiAgICAgICAgaHJlZixcbiAgICAgICAgb3B0cy5yZXBsYWNlID8gXCJyZXBsYWNlXCIgOiBcInB1c2hcIixcbiAgICAgICAgbnVsbCxcbiAgICAgICAgbnVsbFxuICAgICAgKTtcbiAgICB9LFxuICAgIHBhdGNoKGhyZWYsIG9wdHMgPSB7fSkge1xuICAgICAgZW5zdXJlU2FtZU9yaWdpbihocmVmLCBcInBhdGNoXCIpO1xuICAgICAgY29uc3QgY3VzdG9tRXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQoXCJwaHg6ZXhlY1wiKTtcbiAgICAgIGxpdmVTb2NrZXQucHVzaEhpc3RvcnlQYXRjaChcbiAgICAgICAgY3VzdG9tRXZlbnQsXG4gICAgICAgIGhyZWYsXG4gICAgICAgIG9wdHMucmVwbGFjZSA/IFwicmVwbGFjZVwiIDogXCJwdXNoXCIsXG4gICAgICAgIG51bGxcbiAgICAgICk7XG4gICAgfSxcbiAgICBpZ25vcmVBdHRyaWJ1dGVzKGVsLCBhdHRycykge1xuICAgICAganNfZGVmYXVsdC5pZ25vcmVBdHRycyhlbCwgQXJyYXkuaXNBcnJheShhdHRycykgPyBhdHRycyA6IFthdHRyc10pO1xuICAgIH1cbiAgfTtcbn07XG5cbi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L3ZpZXdfaG9vay50c1xudmFyIEhPT0tfSUQgPSBcImhvb2tJZFwiO1xudmFyIERFQURfSE9PSyA9IFwiZGVhZEhvb2tcIjtcbnZhciB2aWV3SG9va0lEID0gMTtcbnZhciBWaWV3SG9vayA9IGNsYXNzIF9WaWV3SG9vayB7XG4gIGdldCBsaXZlU29ja2V0KCkge1xuICAgIHJldHVybiB0aGlzLl9fbGl2ZVNvY2tldCgpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgc3RhdGljIG1ha2VJRCgpIHtcbiAgICByZXR1cm4gdmlld0hvb2tJRCsrO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgc3RhdGljIGVsZW1lbnRJRChlbCkge1xuICAgIHJldHVybiBkb21fZGVmYXVsdC5wcml2YXRlKGVsLCBIT09LX0lEKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIHN0YXRpYyBkZWFkSG9vayhlbCkge1xuICAgIHJldHVybiBkb21fZGVmYXVsdC5wcml2YXRlKGVsLCBERUFEX0hPT0spID09PSB0cnVlO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgY29uc3RydWN0b3IodmlldywgZWwsIGNhbGxiYWNrcykge1xuICAgIHRoaXMuZWwgPSBlbDtcbiAgICB0aGlzLl9fYXR0YWNoVmlldyh2aWV3KTtcbiAgICB0aGlzLl9fbGlzdGVuZXJzID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgICB0aGlzLl9faXNEaXNjb25uZWN0ZWQgPSBmYWxzZTtcbiAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKHRoaXMuZWwsIEhPT0tfSUQsIF9WaWV3SG9vay5tYWtlSUQoKSk7XG4gICAgaWYgKHZpZXcgJiYgdmlldy5pc0RlYWQpIHtcbiAgICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUodGhpcy5lbCwgREVBRF9IT09LLCB0cnVlKTtcbiAgICB9XG4gICAgaWYgKGNhbGxiYWNrcykge1xuICAgICAgY29uc3QgcHJvdGVjdGVkUHJvcHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldChbXG4gICAgICAgIFwiZWxcIixcbiAgICAgICAgXCJsaXZlU29ja2V0XCIsXG4gICAgICAgIFwiX192aWV3XCIsXG4gICAgICAgIFwiX19saXN0ZW5lcnNcIixcbiAgICAgICAgXCJfX2lzRGlzY29ubmVjdGVkXCIsXG4gICAgICAgIFwiY29uc3RydWN0b3JcIixcbiAgICAgICAgLy8gU3RhbmRhcmQgb2JqZWN0IHByb3BlcnRpZXNcbiAgICAgICAgLy8gQ29yZSBWaWV3SG9vayBBUEkgbWV0aG9kc1xuICAgICAgICBcImpzXCIsXG4gICAgICAgIFwicHVzaEV2ZW50XCIsXG4gICAgICAgIFwicHVzaEV2ZW50VG9cIixcbiAgICAgICAgXCJoYW5kbGVFdmVudFwiLFxuICAgICAgICBcInJlbW92ZUhhbmRsZUV2ZW50XCIsXG4gICAgICAgIFwidXBsb2FkXCIsXG4gICAgICAgIFwidXBsb2FkVG9cIixcbiAgICAgICAgLy8gSW50ZXJuYWwgbGlmZWN5Y2xlIGNhbGxlcnNcbiAgICAgICAgXCJfX21vdW50ZWRcIixcbiAgICAgICAgXCJfX3VwZGF0ZWRcIixcbiAgICAgICAgXCJfX2JlZm9yZVVwZGF0ZVwiLFxuICAgICAgICBcIl9fZGVzdHJveWVkXCIsXG4gICAgICAgIFwiX19yZWNvbm5lY3RlZFwiLFxuICAgICAgICBcIl9fZGlzY29ubmVjdGVkXCIsXG4gICAgICAgIFwiX19jbGVhbnVwX19cIlxuICAgICAgXSk7XG4gICAgICBmb3IgKGNvbnN0IGtleSBpbiBjYWxsYmFja3MpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChjYWxsYmFja3MsIGtleSkpIHtcbiAgICAgICAgICB0aGlzW2tleV0gPSBjYWxsYmFja3Nba2V5XTtcbiAgICAgICAgICBpZiAocHJvdGVjdGVkUHJvcHMuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgYEhvb2sgb2JqZWN0IGZvciBlbGVtZW50ICMke2VsLmlkfSBvdmVyd3JpdGVzIGNvcmUgcHJvcGVydHkgJyR7a2V5fSchYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgI
1H1cbiAgICAgIH1cbiAgICAgIGNvbnN0IGxpZmVjeWNsZU1ldGhvZHMgPSBbXG4gICAgICAgIFwibW91bnRlZFwiLFxuICAgICAgICBcImJlZm9yZVVwZGF0ZVwiLFxuICAgICAgICBcInVwZGF0ZWRcIixcbiAgICAgICAgXCJkZXN0cm95ZWRcIixcbiAgICAgICAgXCJkaXNjb25uZWN0ZWRcIixcbiAgICAgICAgXCJyZWNvbm5lY3RlZFwiXG4gICAgICBdO1xuICAgICAgbGlmZWN5Y2xlTWV0aG9kcy5mb3JFYWNoKChtZXRob2ROYW1lKSA9PiB7XG4gICAgICAgIGlmIChjYWxsYmFja3NbbWV0aG9kTmFtZV0gJiYgdHlwZW9mIGNhbGxiYWNrc1ttZXRob2ROYW1lXSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgdGhpc1ttZXRob2ROYW1lXSA9IGNhbGxiYWNrc1ttZXRob2ROYW1lXTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19hdHRhY2hWaWV3KHZpZXcpIHtcbiAgICBpZiAodmlldykge1xuICAgICAgdGhpcy5fX3ZpZXcgPSAoKSA9PiB2aWV3O1xuICAgICAgdGhpcy5fX2xpdmVTb2NrZXQgPSAoKSA9PiB2aWV3LmxpdmVTb2NrZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX192aWV3ID0gKCkgPT4ge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYGhvb2sgbm90IHlldCBhdHRhY2hlZCB0byBhIGxpdmUgdmlldzogJHt0aGlzLmVsLm91dGVySFRNTH1gXG4gICAgICAgICk7XG4gICAgICB9O1xuICAgICAgdGhpcy5fX2xpdmVTb2NrZXQgPSAoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgaG9vayBub3QgeWV0IGF0dGFjaGVkIHRvIGEgbGl2ZSB2aWV3OiAke3RoaXMuZWwub3V0ZXJIVE1MfWBcbiAgICAgICAgKTtcbiAgICAgIH07XG4gICAgfVxuICB9XG4gIC8vIERlZmF1bHQgbGlmZWN5Y2xlIG1ldGhvZHNcbiAgbW91bnRlZCgpIHtcbiAgfVxuICBiZWZvcmVVcGRhdGUoKSB7XG4gIH1cbiAgdXBkYXRlZCgpIHtcbiAgfVxuICBkZXN0cm95ZWQoKSB7XG4gIH1cbiAgZGlzY29ubmVjdGVkKCkge1xuICB9XG4gIHJlY29ubmVjdGVkKCkge1xuICB9XG4gIC8vIEludGVybmFsIGxpZmVjeWNsZSBjYWxsZXJzIC0gY2FsbGVkIGJ5IHRoZSBWaWV3XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19tb3VudGVkKCkge1xuICAgIHRoaXMubW91bnRlZCgpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX191cGRhdGVkKCkge1xuICAgIHRoaXMudXBkYXRlZCgpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19iZWZvcmVVcGRhdGUoKSB7XG4gICAgdGhpcy5iZWZvcmVVcGRhdGUoKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIF9fZGVzdHJveWVkKCkge1xuICAgIHRoaXMuZGVzdHJveWVkKCk7XG4gICAgZG9tX2RlZmF1bHQuZGVsZXRlUHJpdmF0ZSh0aGlzLmVsLCBIT09LX0lEKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIF9fcmVjb25uZWN0ZWQoKSB7XG4gICAgaWYgKHRoaXMuX19pc0Rpc2Nvbm5lY3RlZCkge1xuICAgICAgdGhpcy5fX2lzRGlzY29ubmVjdGVkID0gZmFsc2U7XG4gICAgICB0aGlzLnJlY29ubmVjdGVkKCk7XG4gICAgfVxuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19kaXNjb25uZWN0ZWQoKSB7XG4gICAgdGhpcy5fX2lzRGlzY29ubmVjdGVkID0gdHJ1ZTtcbiAgICB0aGlzLmRpc2Nvbm5lY3RlZCgpO1xuICB9XG4gIGpzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5qc19jb21tYW5kc19kZWZhdWx0KHRoaXMuX192aWV3KCkubGl2ZVNvY2tldCwgXCJob29rXCIpLFxuICAgICAgZXhlYzogKGVuY29kZWRKUykgPT4ge1xuICAgICAgICB0aGlzLl9fdmlldygpLmxpdmVTb2NrZXQuZXhlY0pTKHRoaXMuZWwsIGVuY29kZWRKUywgXCJob29rXCIpO1xuICAgICAgfVxuICAgIH07XG4gIH1cbiAgcHVzaEV2ZW50KGV2ZW50LCBwYXlsb2FkLCBvblJlcGx5KSB7XG4gICAgY29uc3QgcHJvbWlzZSA9IHRoaXMuX192aWV3KCkucHVzaEhvb2tFdmVudChcbiAgICAgIHRoaXMuZWwsXG4gICAgICBudWxsLFxuICAgICAgZXZlbnQsXG4gICAgICBwYXlsb2FkIHx8IHt9XG4gICAgKTtcbiAgICBpZiAob25SZXBseSA9PT0gdm9pZCAwKSB7XG4gICAgICByZXR1cm4gcHJvbWlzZS50aGVuKCh7IHJlcGx5IH0pID0+IHJlcGx5KTtcbiAgICB9XG4gICAgcHJvbWlzZS50aGVuKFxuICAgICAgKHsgcmVwbHksIHJlZiB9KSA9PiBvblJlcGx5KHJlcGx5LCByZWYpXG4gICAgKS5jYXRjaCgoKSA9PiB7XG4gICAgfSk7XG4gIH1cbiAgcHVzaEV2ZW50VG8oc2VsZWN0b3JPclRhcmdldCwgZXZlbnQsIHBheWxvYWQsIG9uUmVwbHkpIHtcbiAgICBpZiAob25SZXBseSA9PT0gdm9pZCAwKSB7XG4gICAgICBjb25zdCB0YXJnZXRQYWlyID0gW107XG4gICAgICB0aGlzLl9fdmlldygpLndpdGhpblRhcmdldHMoXG4gICAgICAgIHNlbGVjdG9yT3JUYXJnZXQsXG4gICAgICAgICh2aWV3LCB0YXJnZXRDdHgpID0+IHtcbiAgICAgICAgICB0YXJnZXRQYWlyLnB1c2goeyB2aWV3LCB0YXJnZXRDdHggfSk7XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgICBjb25zdCBwcm9taXNlcyA9IHRhcmdldFBhaXIubWFwKCh7IHZpZXcsIHRhcmdldEN0eCB9KSA9PiB7XG4gICAgICAgIHJldHVybiB2aWV3LnB1c2hIb29rRXZlbnQoXG4gICAgICAgICAgdGhpcy5lbCxcbiAgICAgICAgICB0YXJnZXRDdHgsXG4gICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgcGF5bG9hZCB8fCB7fVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGxTZXR0bGVkKHByb21pc2VzKTtcbiAgICB9XG4gICAgdGhpcy5fX3ZpZXcoKS53aXRoaW5UYXJnZXRzKFxuICAgICAgc2VsZWN0b3JPclRhcmdldCxcbiAgICAgICh2aWV3LCB0YXJnZXRDdHgpID0+IHtcbiAgICAgICAgdmlldy5wdXNoSG9va0V2ZW50KHRoaXMuZWwsIHRhcmdldEN0eCwgZXZlbnQsIHBheWxvYWQgfHwge30pLnRoZW4oXG4gICAgICAgICAgKHsgcmVwbHksIHJlZiB9KSA9PiBvblJlcGx5KHJlcGx5LCByZWYpXG4gICAgICAgICkuY2F0Y2goKCkgPT4ge1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICApO
11xuICB9XG4gIGhhbmRsZUV2ZW50KGV2ZW50LCBjYWxsYmFjaykge1xuICAgIGNvbnN0IGNhbGxiYWNrUmVmID0ge1xuICAgICAgZXZlbnQsXG4gICAgICBjYWxsYmFjazogKGN1c3RvbUV2ZW50KSA9PiBjYWxsYmFjayhjdXN0b21FdmVudC5kZXRhaWwpXG4gICAgfTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIGBwaHg6JHtldmVudH1gLFxuICAgICAgY2FsbGJhY2tSZWYuY2FsbGJhY2tcbiAgICApO1xuICAgIHRoaXMuX19saXN0ZW5lcnMuYWRkKGNhbGxiYWNrUmVmKTtcbiAgICByZXR1cm4gY2FsbGJhY2tSZWY7XG4gIH1cbiAgcmVtb3ZlSGFuZGxlRXZlbnQocmVmKSB7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBgcGh4OiR7cmVmLmV2ZW50fWAsXG4gICAgICByZWYuY2FsbGJhY2tcbiAgICApO1xuICAgIHRoaXMuX19saXN0ZW5lcnMuZGVsZXRlKHJlZik7XG4gIH1cbiAgdXBsb2FkKG5hbWUsIGZpbGVzKSB7XG4gICAgcmV0dXJuIHRoaXMuX192aWV3KCkuZGlzcGF0Y2hVcGxvYWRzKG51bGwsIG5hbWUsIGZpbGVzKTtcbiAgfVxuICB1cGxvYWRUbyhzZWxlY3Rvck9yVGFyZ2V0LCBuYW1lLCBmaWxlcykge1xuICAgIHJldHVybiB0aGlzLl9fdmlldygpLndpdGhpblRhcmdldHMoXG4gICAgICBzZWxlY3Rvck9yVGFyZ2V0LFxuICAgICAgKHZpZXcsIHRhcmdldEN0eCkgPT4ge1xuICAgICAgICB2aWV3LmRpc3BhdGNoVXBsb2Fkcyh0YXJnZXRDdHgsIG5hbWUsIGZpbGVzKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19jbGVhbnVwX18oKSB7XG4gICAgdGhpcy5fX2xpc3RlbmVycy5mb3JFYWNoKFxuICAgICAgKGNhbGxiYWNrUmVmKSA9PiB0aGlzLnJlbW92ZUhhbmRsZUV2ZW50KGNhbGxiYWNrUmVmKVxuICAgICk7XG4gIH1cbn07XG5cbi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L3ZpZXcudHNcbnZhciBwcmVwZW5kRm9ybURhdGFLZXkgPSAoa2V5LCBwcmVmaXgpID0+IHtcbiAgY29uc3QgaXNBcnJheSA9IGtleS5lbmRzV2l0aChcIltdXCIpO1xuICBsZXQgYmFzZUtleSA9IGlzQXJyYXkgPyBrZXkuc2xpY2UoMCwgLTIpIDoga2V5O1xuICBiYXNlS2V5ID0gYmFzZUtleS5yZXBsYWNlKC8oW15cXFtcXF1dKykoXFxdPyQpLywgYCR7cHJlZml4fSQxJDJgKTtcbiAgaWYgKGlzQXJyYXkpIHtcbiAgICBiYXNlS2V5ICs9IFwiW11cIjtcbiAgfVxuICByZXR1cm4gYmFzZUtleTtcbn07XG52YXIgVmlldyA9IGNsYXNzIF9WaWV3IHtcbiAgc3RhdGljIGNsb3Nlc3RWaWV3KGVsKSB7XG4gICAgY29uc3QgbGl2ZVZpZXdFbCA9IGVsLmNsb3Nlc3QoUEhYX1ZJRVdfU0VMRUNUT1IpO1xuICAgIHJldHVybiBsaXZlVmlld0VsID8gZG9tX2RlZmF1bHQucHJpdmF0ZShsaXZlVmlld0VsLCBcInZpZXdcIikgOiBudWxsO1xuICB9XG4gIGNvbnN0cnVjdG9yKGVsLCBsaXZlU29ja2V0LCBwYXJlbnRWaWV3LCBmbGFzaCA9IG51bGwsIGxpdmVSZWZlcmVyID0gbnVsbCkge1xuICAgIHRoaXMucmVuZGVyZWQgPSBudWxsO1xuICAgIHRoaXMuaXNEZWFkID0gZmFsc2U7XG4gICAgdGhpcy5saXZlU29ja2V0ID0gbGl2ZVNvY2tldDtcbiAgICB0aGlzLmZsYXNoID0gZmxhc2g7XG4gICAgdGhpcy5wYXJlbnQgPSBwYXJlbnRWaWV3O1xuICAgIHRoaXMucm9vdCA9IHBhcmVudFZpZXcgPyBwYXJlbnRWaWV3LnJvb3QgOiB0aGlzO1xuICAgIHRoaXMuZWwgPSBlbDtcbiAgICBjb25zdCBib3VuZFZpZXcgPSBkb21fZGVmYXVsdC5wcml2YXRlKHRoaXMuZWwsIFwidmlld1wiKTtcbiAgICBpZiAoYm91bmRWaWV3ICE9PSB2b2lkIDAgJiYgYm91bmRWaWV3LmlzRGVhZCAhPT0gdHJ1ZSkge1xuICAgICAgbG9nRXJyb3IoXG4gICAgICAgIGBUaGUgRE9NIGVsZW1lbnQgZm9yIHRoaXMgdmlldyBoYXMgYWxyZWFkeSBiZWVuIGJvdW5kIHRvIGEgdmlldy5cblxuICAgICAgICBBbiBlbGVtZW50IGNhbiBvbmx5IGV2ZXIgYmUgYXNzb2NpYXRlZCB3aXRoIGEgc2luZ2xlIHZpZXchXG4gICAgICAgIFBsZWFzZSBlbnN1cmUgdGhhdCB5b3UgYXJlIG5vdCB0cnlpbmcgdG8gaW5pdGlhbGl6ZSBtdWx0aXBsZSBMaXZlU29ja2V0cyBvbiB0aGUgc2FtZSBwYWdlLlxuICAgICAgICBUaGlzIGNvdWxkIGhhcHBlbiBpZiB5b3UncmUgYWNjaWRlbnRhbGx5IHRyeWluZyB0byByZW5kZXIgeW91ciByb290IGxheW91dCBtb3JlIHRoYW4gb25jZS5cbiAgICAgICAgRW5zdXJlIHRoYXQgdGhlIHRlbXBsYXRlIHNldCBvbiB0aGUgTGl2ZVZpZXcgaXMgZGlmZmVyZW50IHRoYW4gdGhlIHJvb3QgbGF5b3V0LlxuICAgICAgYCxcbiAgICAgICAgeyB2aWV3OiBib3VuZFZpZXcgfVxuICAgICAgKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBiaW5kIG11bHRpcGxlIHZpZXdzIHRvIHRoZSBzYW1lIERPTSBlbGVtZW50LlwiKTtcbiAgICB9XG4gICAgZG9tX2RlZmF1bHQucHV0UHJpdmF0ZSh0aGlzLmVsLCBcInZpZXdcIiwgdGhpcyk7XG4gICAgdGhpcy5pZCA9IHRoaXMuZWwuaWQ7XG4gICAgdGhpcy5lbC5zZXRBdHRyaWJ1dGUoUEhYX1JPT1RfSUQsIHRoaXMucm9vdC5pZCk7XG4gICAgdGhpcy5yZWYgPSAwO1xuICAgIHRoaXMubGFzdEFja1JlZiA9IG51bGw7XG4gICAgdGhpcy5jaGlsZEpvaW5zID0gMDtcbiAgICB0aGlzLmxvYWRlclRpbWVyID0gbnVsbDtcbiAgICB0aGlzLmRpc2Nvbm5lY3RlZFRpbWVyID0gbnVsbDtcbiAgICB0aGlzLnBlbmRpbmdEaWZmcyA9IFtdO1xuICAgIHRoaXMucGVuZGluZ0Zvcm1zID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgICB0aGlzLnJlZGlyZWN0ID0gZmFsc2U7XG4gICAgdGhpcy5ocmVmID0gbnVsbDtcbiAgICB0aGlzLmpvaW5Db3VudCA9IHRoaXMucGFyZW50ID8gdGhpcy5wYXJlbnQuam9pbkNvdW50IC0gMSA6IDA7XG4gICAgdGhpcy5qb2luQXR0ZW1wdHMgPSAwO1xuICAgIHRoaXMuam9pblBlbmRpbmcgPSB0cnVlO1xuICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5qb2luQ2FsbGJhY2sgPSBmdW5jdGlvbihvbkRvbmUpIHtcbiAgICAgIG9uRG9uZSAmJiBvbkRvbmUoKTtcbiAgICB9O1xuICAgIHRoaXMuc3RvcENhbGxiYWNrID0gZnVuY3Rpb24oKSB7XG4gICAgfTtcbiAgICB0aGlzLnBlbmRpbmdKb2luT3BzID0gW107XG4gICAgdGhpcy52aWV3SG9va3MgPSB7fTtcbiAgICB0aGlzLmZvcm1TdWJtaXRzID0gW107XG4gICAgdGhpcy5jaGlsZHJlbiA9IHRoaXMucGFyZW50ID8gbnVsbCA6IHt9O1xuICAgIHRoaXMucm9vdC5jaGlsZHJlblt0aGlzLmlkXSA9IHt9O1xuICAgIHRoaXMuZm9ybXNGb3JSZWNvdmVyeSA9IHt9O1xuICAgIHRoaXMuY2hhbm5lbCA9IHRoaXMubGl2ZVNvY2tldC5jaGFubmVsKGBsdjoke3RoaXMuaWR9YCwgKCkgPT4ge1xuICAgICAgY29uc3QgdXJsID0gdGh
1pcy5ocmVmICYmIHRoaXMuZXhwYW5kVVJMKHRoaXMuaHJlZik7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZWRpcmVjdDogdGhpcy5yZWRpcmVjdCA/IHVybCA6IHZvaWQgMCxcbiAgICAgICAgdXJsOiB0aGlzLnJlZGlyZWN0ID8gdm9pZCAwIDogdXJsIHx8IHZvaWQgMCxcbiAgICAgICAgcGFyYW1zOiB0aGlzLmNvbm5lY3RQYXJhbXMobGl2ZVJlZmVyZXIpLFxuICAgICAgICBzZXNzaW9uOiB0aGlzLmdldFNlc3Npb24oKSxcbiAgICAgICAgc3RhdGljOiB0aGlzLmdldFN0YXRpYygpLFxuICAgICAgICBmbGFzaDogdGhpcy5mbGFzaCA/PyB2b2lkIDAsXG4gICAgICAgIHN0aWNreTogdGhpcy5lbC5oYXNBdHRyaWJ1dGUoUEhYX1NUSUNLWSlcbiAgICAgIH07XG4gICAgfSk7XG4gICAgdGhpcy5wb3J0YWxFbGVtZW50SWRzID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgfVxuICBzZXRIcmVmKGhyZWYpIHtcbiAgICB0aGlzLmhyZWYgPSBocmVmO1xuICB9XG4gIHNldFJlZGlyZWN0KGhyZWYpIHtcbiAgICB0aGlzLnJlZGlyZWN0ID0gdHJ1ZTtcbiAgICB0aGlzLmhyZWYgPSBocmVmO1xuICB9XG4gIGlzTWFpbigpIHtcbiAgICByZXR1cm4gdGhpcy5lbC5oYXNBdHRyaWJ1dGUoUEhYX01BSU4pO1xuICB9XG4gIGNvbm5lY3RQYXJhbXMobGl2ZVJlZmVyZXIpIHtcbiAgICBjb25zdCBwYXJhbXMgPSB0aGlzLmxpdmVTb2NrZXQucGFyYW1zKHRoaXMuZWwpO1xuICAgIGNvbnN0IG1hbmlmZXN0ID0gZG9tX2RlZmF1bHQuYWxsKGRvY3VtZW50LCBgWyR7dGhpcy5iaW5kaW5nKFBIWF9UUkFDS19TVEFUSUMpfV1gKS5tYXAoXG4gICAgICAobm9kZSkgPT4gXCJzcmNcIiBpbiBub2RlICYmIG5vZGUuc3JjIHx8IFwiaHJlZlwiIGluIG5vZGUgJiYgbm9kZS5ocmVmXG4gICAgKS5maWx0ZXIoKHVybCkgPT4gdHlwZW9mIHVybCA9PT0gXCJzdHJpbmdcIik7XG4gICAgaWYgKG1hbmlmZXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgIHBhcmFtc1tcIl90cmFja19zdGF0aWNcIl0gPSBtYW5pZmVzdDtcbiAgICB9XG4gICAgcGFyYW1zW1wiX21vdW50c1wiXSA9IHRoaXMuam9pbkNvdW50O1xuICAgIHBhcmFtc1tcIl9tb3VudF9hdHRlbXB0c1wiXSA9IHRoaXMuam9pbkF0dGVtcHRzO1xuICAgIHBhcmFtc1tcIl9saXZlX3JlZmVyZXJcIl0gPSBsaXZlUmVmZXJlciA/PyB2b2lkIDA7XG4gICAgdGhpcy5qb2luQXR0ZW1wdHMrKztcbiAgICByZXR1cm4gcGFyYW1zO1xuICB9XG4gIGlzQ29ubmVjdGVkKCkge1xuICAgIHJldHVybiB0aGlzLmNoYW5uZWwuY2FuUHVzaCgpO1xuICB9XG4gIGdldFNlc3Npb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuZWwuZ2V0QXR0cmlidXRlKFBIWF9TRVNTSU9OKTtcbiAgfVxuICBnZXRTdGF0aWMoKSB7XG4gICAgY29uc3QgdmFsID0gdGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX1NUQVRJQyk7XG4gICAgcmV0dXJuIHZhbCA9PT0gXCJcIiA/IG51bGwgOiB2YWw7XG4gIH1cbiAgZGVzdHJveShjYWxsYmFjayA9IGZ1bmN0aW9uKCkge1xuICB9KSB7XG4gICAgdGhpcy5kZXN0cm95QWxsQ2hpbGRyZW4oKTtcbiAgICB0aGlzLmRlc3Ryb3lQb3J0YWxFbGVtZW50cygpO1xuICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZTtcbiAgICBkb21fZGVmYXVsdC5kZWxldGVQcml2YXRlKHRoaXMuZWwsIFwidmlld1wiKTtcbiAgICBkZWxldGUgdGhpcy5yb290LmNoaWxkcmVuW3RoaXMuaWRdO1xuICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgZGVsZXRlIHRoaXMucm9vdC5jaGlsZHJlblt0aGlzLnBhcmVudC5pZF1bdGhpcy5pZF07XG4gICAgfVxuICAgIHRoaXMubG9hZGVyVGltZXIgIT0gbnVsbCAmJiBjbGVhclRpbWVvdXQodGhpcy5sb2FkZXJUaW1lcik7XG4gICAgY29uc3Qgb25GaW5pc2hlZCA9ICgpID0+IHtcbiAgICAgIGNhbGxiYWNrKCk7XG4gICAgICBmb3IgKGNvbnN0IGlkIGluIHRoaXMudmlld0hvb2tzKSB7XG4gICAgICAgIHRoaXMuZGVzdHJveUhvb2sodGhpcy52aWV3SG9va3NbaWRdKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGRvbV9kZWZhdWx0Lm1hcmtQaHhDaGlsZERlc3Ryb3llZCh0aGlzLmVsKTtcbiAgICB0aGlzLmxvZyhcImRlc3Ryb3llZFwiLCAoKSA9PiBbXCJ0aGUgY2hpbGQgaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIHRoZSBwYXJlbnRcIl0pO1xuICAgIHRoaXMuY2hhbm5lbC5sZWF2ZSgpLnJlY2VpdmUoXCJva1wiLCBvbkZpbmlzaGVkKS5yZWNlaXZlKFwiZXJyb3JcIiwgb25GaW5pc2hlZCkucmVjZWl2ZShcInRpbWVvdXRcIiwgb25GaW5pc2hlZCk7XG4gIH1cbiAgc2V0Q29udGFpbmVyQ2xhc3NlcyguLi5jbGFzc2VzKSB7XG4gICAgdGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFxuICAgICAgUEhYX0NPTk5FQ1RFRF9DTEFTUyxcbiAgICAgIFBIWF9MT0FESU5HX0NMQVNTLFxuICAgICAgUEhYX0VSUk9SX0NMQVNTLFxuICAgICAgUEhYX0NMSUVOVF9FUlJPUl9DTEFTUyxcbiAgICAgIFBIWF9TRVJWRVJfRVJST1JfQ0xBU1NcbiAgICApO1xuICAgIHRoaXMuZWwuY2xhc3NMaXN0LmFkZCguLi5jbGFzc2VzKTtcbiAgfVxuICBzaG93TG9hZGVyKHRpbWVvdXQpIHtcbiAgICB0aGlzLmxvYWRlclRpbWVyICE9IG51bGwgJiYgY2xlYXJUaW1lb3V0KHRoaXMubG9hZGVyVGltZXIpO1xuICAgIGlmICh0aW1lb3V0KSB7XG4gICAgICB0aGlzLmxvYWRlclRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLnNob3dMb2FkZXIoKSwgdGltZW91dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy52aWV3SG9va3MpIHtcbiAgICAgICAgdGhpcy52aWV3SG9va3NbaWRdLl9fZGlzY29ubmVjdGVkKCk7XG4gICAgICB9XG4gICAgICB0aGlzLnNldENvbnRhaW5lckNsYXNzZXMoUEhYX0xPQURJTkdfQ0xBU1MpO1xuICAgIH1cbiAgfVxuICBleGVjQWxsKGJpbmRpbmcpIHtcbiAgICBkb21fZGVmYXVsdC5hbGwoXG4gICAgICB0aGlzLmVsLFxuICAgICAgYFske2JpbmRpbmd9XWAsXG4gICAgICAoZWwpID0+IHRoaXMubGl2ZVNvY2tldC5leGVjSlMoZWwsIGVsLmdldEF0dHJpYnV0ZShiaW5kaW5nKSlcbiAgICApO1xuICB9XG4gIGhpZGVMb2FkZXIoKSB7XG4gICAgdGhpcy5sb2FkZXJUaW1lciAhPSBudWxsICYmIGNsZWFyVGltZW91dCh0aGlzLmxvYWRlclRpbWVyKTtcbiAgICB0aGlzLmRpc2Nvbm5lY3RlZFRpbWVyICE9IG51bGwgJiYgY2xlYXJUaW1lb3V0KHRoaXMuZGlzY29ubmVjdGVkVGltZXIpO1xuICAgIHRoaXMuc2V0Q29udGFpbmVyQ2xhc3NlcyhQS
1FhfQ09OTkVDVEVEX0NMQVNTKTtcbiAgICB0aGlzLmV4ZWNBbGwodGhpcy5iaW5kaW5nKFwiY29ubmVjdGVkXCIpKTtcbiAgfVxuICB0cmlnZ2VyUmVjb25uZWN0ZWQoKSB7XG4gICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLnZpZXdIb29rcykge1xuICAgICAgdGhpcy52aWV3SG9va3NbaWRdLl9fcmVjb25uZWN0ZWQoKTtcbiAgICB9XG4gIH1cbiAgbG9nKGtpbmQsIG1zZ0NhbGxiYWNrKSB7XG4gICAgdGhpcy5saXZlU29ja2V0LmxvZyh0aGlzLCBraW5kLCBtc2dDYWxsYmFjayk7XG4gIH1cbiAgdHJhbnNpdGlvbih0aW1lLCBvblN0YXJ0LCBvbkRvbmUgPSBmdW5jdGlvbigpIHtcbiAgfSkge1xuICAgIHRoaXMubGl2ZVNvY2tldC50cmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSk7XG4gIH1cbiAgLy8gY2FsbHMgdGhlIGNhbGxiYWNrIHdpdGggdGhlIHZpZXcgYW5kIHRhcmdldCBlbGVtZW50IGZvciB0aGUgZ2l2ZW4gcGh4VGFyZ2V0XG4gIC8vIHRhcmdldHMgY2FuIGJlOlxuICAvLyAgKiBhbiBlbGVtZW50IGl0c2VsZiwgdGhlbiBpdCBpcyBzaW1wbHkgcGFzc2VkIHRvIGxpdmVTb2NrZXQub3duZXI7XG4gIC8vICAqIGEgQ0lEIChDb21wb25lbnQgSUQpLCB0aGVuIHdlIGZpcnN0IHNlYXJjaCB0aGUgY29tcG9uZW50J3MgZWxlbWVudCBpbiB0aGUgRE9NXG4gIC8vICAqIGEgc2VsZWN0b3IsIHRoZW4gd2Ugc2VhcmNoIHRoZSBzZWxlY3RvciBpbiB0aGUgRE9NIGFuZCBjYWxsIHRoZSBjYWxsYmFja1xuICAvLyAgICBmb3IgZWFjaCBlbGVtZW50IGZvdW5kIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgb3duZXIgdmlld1xuICB3aXRoaW5UYXJnZXRzKHBoeFRhcmdldCwgY2FsbGJhY2ssIGRvbSA9IGRvY3VtZW50KSB7XG4gICAgaWYgKHBoeFRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50IHx8IHBoeFRhcmdldCBpbnN0YW5jZW9mIFNWR0VsZW1lbnQpIHtcbiAgICAgIHJldHVybiB0aGlzLmxpdmVTb2NrZXQub3duZXIoXG4gICAgICAgIHBoeFRhcmdldCxcbiAgICAgICAgKHZpZXcpID0+IGNhbGxiYWNrKHZpZXcsIHBoeFRhcmdldClcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChpc0NpZChwaHhUYXJnZXQpKSB7XG4gICAgICBjb25zdCB0YXJnZXQgPSBkb21fZGVmYXVsdC5maW5kQ29tcG9uZW50KHRoaXMuaWQsIHBoeFRhcmdldCwgZG9tKTtcbiAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgIGxvZ0Vycm9yKGBubyBjb21wb25lbnQgZm91bmQgbWF0Y2hpbmcgcGh4LXRhcmdldCBvZiAke3BoeFRhcmdldH1gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhbGxiYWNrKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgdHlwZW9mIHBoeFRhcmdldCA9PT0gXCJudW1iZXJcIiA/IHBoeFRhcmdldCA6IHBhcnNlSW50KHBoeFRhcmdldClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdGFyZ2V0cyA9IEFycmF5LmZyb20oZG9tLnF1ZXJ5U2VsZWN0b3JBbGwocGh4VGFyZ2V0KSk7XG4gICAgICBpZiAodGFyZ2V0cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgbG9nRXJyb3IoXG4gICAgICAgICAgYG5vdGhpbmcgZm91bmQgbWF0Y2hpbmcgdGhlIHBoeC10YXJnZXQgc2VsZWN0b3IgXCIke3BoeFRhcmdldH1cImBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHRhcmdldHMuZm9yRWFjaChcbiAgICAgICAgKHRhcmdldCkgPT4gdGhpcy5saXZlU29ja2V0Lm93bmVyKHRhcmdldCwgKHZpZXcpID0+IGNhbGxiYWNrKHZpZXcsIHRhcmdldCkpXG4gICAgICApO1xuICAgIH1cbiAgfVxuICBhcHBseURpZmYodHlwZSwgcmF3RGlmZiwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmxvZyh0eXBlLCAoKSA9PiBbXCJcIiwgY2xvbmUocmF3RGlmZildKTtcbiAgICBjb25zdCB7IGRpZmYsIHJlcGx5LCBldmVudHMsIHRpdGxlIH0gPSBSZW5kZXJlZC5leHRyYWN0KHJhd0RpZmYpO1xuICAgIGNvbnN0IGV2ID0gZXZlbnRzLnJlZHVjZShcbiAgICAgIChhY2MsIGFyZ3MpID0+IHtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID09PSAzICYmIGFyZ3NbMl0gPT0gdHJ1ZSkge1xuICAgICAgICAgIGFjYy5wcmUucHVzaChhcmdzLnNsaWNlKDAsIC0xKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYWNjLnBvc3QucHVzaChhcmdzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIHsgcHJlOiBbXSwgcG9zdDogW10gfVxuICAgICk7XG4gICAgdGhpcy5saXZlU29ja2V0LmRpc3BhdGNoRXZlbnRzKGV2LnByZSk7XG4gICAgY29uc3QgdXBkYXRlID0gKCkgPT4ge1xuICAgICAgY2FsbGJhY2soeyBkaWZmLCByZXBseSwgZXZlbnRzOiBldi5wb3N0IH0pO1xuICAgICAgaWYgKHR5cGVvZiB0aXRsZSA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlID09IFwibW91bnRcIiAmJiB0aGlzLmlzTWFpbigpKSB7XG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gZG9tX2RlZmF1bHQucHV0VGl0bGUodGl0bGUpKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGlmIChcIm9uRG9jdW1lbnRQYXRjaFwiIGluIHRoaXMubGl2ZVNvY2tldC5kb21DYWxsYmFja3MpIHtcbiAgICAgIHRoaXMubGl2ZVNvY2tldC50cmlnZ2VyRE9NKFwib25Eb2N1bWVudFBhdGNoXCIsIFt1cGRhdGVdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXBkYXRlKCk7XG4gICAgfVxuICB9XG4gIG9uSm9pbihyZXNwKSB7XG4gICAgY29uc3QgeyByZW5kZXJlZCwgY29udGFpbmVyLCBsaXZldmlld192ZXJzaW9uLCBwaWQgfSA9IHJlc3A7XG4gICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgY29uc3QgW3RhZywgYXR0cnNdID0gY29udGFpbmVyO1xuICAgICAgdGhpcy5lbCA9IGRvbV9kZWZhdWx0LnJlcGxhY2VSb290Q29udGFpbmVyKHRoaXMuZWwsIHRhZywgYXR0cnMpO1xuICAgICAgZG9tX2RlZmF1bHQucHV0UHJpdmF0ZSh0aGlzLmVsLCBcInZpZXdcIiwgdGhpcyk7XG4gICAgfVxuICAgIHRoaXMuY2hpbGRKb2lucyA9IDA7XG4gICAgdGhpcy5qb2luUGVuZGluZyA9IHRydWU7XG4gICAgdGhpcy5mbGFzaCA9IG51bGw7XG4gICAgaWYgKHRoaXMucm9vdCA9PT0gdGhpcykge1xuICAgICAgdGhpcy5mb3Jtc0ZvclJlY292ZXJ5ID0gdGhpcy5nZXRGb3Jtc0ZvclJlY292ZXJ5KCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmlzTWFpbigpICYmIHdpbmRvdy5oaXN0b3J5LnN0YXRlID09PSBudWxsKSB7XG4gICAgICBicm93c2VyX2RlZmF1bHQucHVzaFN0YXRlKFwicmVwbGFjZVwiLCB7XG4gICAgICAgI
1HR5cGU6IFwicGF0Y2hcIixcbiAgICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgICAgIHBvc2l0aW9uOiB0aGlzLmxpdmVTb2NrZXQuY3VycmVudEhpc3RvcnlQb3NpdGlvblxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChsaXZldmlld192ZXJzaW9uICE9PSB0aGlzLmxpdmVTb2NrZXQudmVyc2lvbigpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBMaXZlVmlldyBhc3NldCB2ZXJzaW9uIG1pc21hdGNoLiBKYXZhU2NyaXB0IHZlcnNpb24gJHt0aGlzLmxpdmVTb2NrZXQudmVyc2lvbigpfSB2cy4gc2VydmVyICR7bGl2ZXZpZXdfdmVyc2lvbn0uIFRvIGF2b2lkIGlzc3VlcywgcGxlYXNlIGVuc3VyZSB0aGF0IHlvdXIgYXNzZXRzIHVzZSB0aGUgc2FtZSB2ZXJzaW9uIGFzIHRoZSBzZXJ2ZXIuYFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHBpZCkge1xuICAgICAgdGhpcy5lbC5zZXRBdHRyaWJ1dGUoUEhYX0xWX1BJRCwgcGlkKTtcbiAgICB9XG4gICAgYnJvd3Nlcl9kZWZhdWx0LmRyb3BMb2NhbChcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5sb2NhbFN0b3JhZ2UsXG4gICAgICB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsXG4gICAgICBDT05TRUNVVElWRV9SRUxPQURTXG4gICAgKTtcbiAgICB0aGlzLmFwcGx5RGlmZihcIm1vdW50XCIsIHJlbmRlcmVkLCAoeyBkaWZmLCBldmVudHMgfSkgPT4ge1xuICAgICAgdGhpcy5yZW5kZXJlZCA9IG5ldyBSZW5kZXJlZCh0aGlzLmlkLCBkaWZmKTtcbiAgICAgIGNvbnN0IFtodG1sLCBzdHJlYW1zXSA9IHRoaXMucmVuZGVyQ29udGFpbmVyKG51bGwsIFwiam9pblwiKTtcbiAgICAgIHRoaXMuZHJvcFBlbmRpbmdSZWZzKCk7XG4gICAgICB0aGlzLmpvaW5Db3VudCsrO1xuICAgICAgdGhpcy5qb2luQXR0ZW1wdHMgPSAwO1xuICAgICAgdGhpcy5tYXliZVJlY292ZXJGb3JtcyhodG1sLCAoKSA9PiB7XG4gICAgICAgIHRoaXMub25Kb2luQ29tcGxldGUocmVzcCwgaHRtbCwgc3RyZWFtcywgZXZlbnRzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIGRyb3BQZW5kaW5nUmVmcygpIHtcbiAgICBkb21fZGVmYXVsdC5hbGwoZG9jdW1lbnQsIGBbJHtQSFhfUkVGX1NSQ309XCIke3RoaXMucmVmU3JjKCl9XCJdYCwgKGVsKSA9PiB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRl9MT0FESU5HKTtcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfUkVGX1NSQyk7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRl9MT0NLKTtcbiAgICB9KTtcbiAgfVxuICBvbkpvaW5Db21wbGV0ZSh7IGxpdmVfcGF0Y2ggfSwgaHRtbCwgc3RyZWFtcywgZXZlbnRzKSB7XG4gICAgaWYgKHRoaXMuam9pbkNvdW50ID4gMSB8fCB0aGlzLnBhcmVudCAmJiAhdGhpcy5wYXJlbnQuaXNKb2luUGVuZGluZygpKSB7XG4gICAgICByZXR1cm4gdGhpcy5hcHBseUpvaW5QYXRjaChsaXZlX3BhdGNoLCBodG1sLCBzdHJlYW1zLCBldmVudHMpO1xuICAgIH1cbiAgICBjb25zdCBuZXdDaGlsZHJlbiA9IGRvbV9kZWZhdWx0LmZpbmRQaHhDaGlsZHJlbkluRnJhZ21lbnQoaHRtbCwgdGhpcy5pZCkuZmlsdGVyKFxuICAgICAgKHRvRWwpID0+IHtcbiAgICAgICAgY29uc3QgZnJvbUVsID0gdG9FbC5pZCAmJiB0aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoYFtpZD1cIiR7dG9FbC5pZH1cIl1gKTtcbiAgICAgICAgY29uc3QgcGh4U3RhdGljID0gZnJvbUVsICYmIGZyb21FbC5nZXRBdHRyaWJ1dGUoUEhYX1NUQVRJQyk7XG4gICAgICAgIGlmIChwaHhTdGF0aWMpIHtcbiAgICAgICAgICB0b0VsLnNldEF0dHJpYnV0ZShQSFhfU1RBVElDLCBwaHhTdGF0aWMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmcm9tRWwpIHtcbiAgICAgICAgICBmcm9tRWwuc2V0QXR0cmlidXRlKFBIWF9ST09UX0lELCB0aGlzLnJvb3QuaWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmpvaW5DaGlsZCh0b0VsKTtcbiAgICAgIH1cbiAgICApO1xuICAgIGlmIChuZXdDaGlsZHJlbi5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgICB0aGlzLnJvb3QucGVuZGluZ0pvaW5PcHMucHVzaChbXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICAoKSA9PiB0aGlzLmFwcGx5Sm9pblBhdGNoKGxpdmVfcGF0Y2gsIGh0bWwsIHN0cmVhbXMsIGV2ZW50cylcbiAgICAgICAgXSk7XG4gICAgICAgIHRoaXMucGFyZW50LmFja0pvaW4odGhpcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm9uQWxsQ2hpbGRKb2luc0NvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuYXBwbHlKb2luUGF0Y2gobGl2ZV9wYXRjaCwgaHRtbCwgc3RyZWFtcywgZXZlbnRzKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yb290LnBlbmRpbmdKb2luT3BzLnB1c2goW1xuICAgICAgICB0aGlzLFxuICAgICAgICAoKSA9PiB0aGlzLmFwcGx5Sm9pblBhdGNoKGxpdmVfcGF0Y2gsIGh0bWwsIHN0cmVhbXMsIGV2ZW50cylcbiAgICAgIF0pO1xuICAgIH1cbiAgfVxuICBhdHRhY2hUcnVlRG9jRWwoKSB7XG4gICAgY29uc3QgZWwgPSBkb21fZGVmYXVsdC5ieUlkKHRoaXMuaWQpO1xuICAgIGlmICghZWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcInVuYWJsZSB0byBmaW5kIHJvb3QgZWxlbWVudCBmb3Igdmlld1wiKTtcbiAgICB9XG4gICAgdGhpcy5lbCA9IGVsO1xuICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUodGhpcy5lbCwgXCJ2aWV3XCIsIHRoaXMpO1xuICAgIHRoaXMuZWwuc2V0QXR0cmlidXRlKFBIWF9ST09UX0lELCB0aGlzLnJvb3QuaWQpO1xuICB9XG4gIC8vIHRoaXMgaXMgaW52b2tlZCBmb3IgZGVhZCBhbmQgbGl2ZSB2aWV3cywgc28gd2UgbXVzdCBmaWx0ZXIgYnlcbiAgLy8gYnkgb3duZXIgdG8gZW5zdXJlIHdlIGFyZW4ndCBkdXBsaWNhdGluZyBob29rcyBhY3Jvc3MgZGlzY29ubmVjdFxuICAvLyBhbmQgY29ubmVjdGVkIHN0YXRlcy4gVGhpcyBhbHNvIGhhbmRsZXMgY2FzZXMgd2hlcmUgaG9va3MgZXhpc3RcbiAgLy8gaW4gYSByb290IGxheW91dCB3aXRoIGEgTFYgaW4gdGhlIGJvZHlcbiAgZXhlY05ld01vdW50ZWQocGFyZW50ID0gZG9jdW1lbnQpIHtcbiAgICBsZXQgcGh4Vmlld3BvcnRUb3AgPSB0aGlzLmJpbmRpbmcoUEhYX1ZJRVdQT1JUX1RPUCk7XG4gICAgbGV0IHBoeFZpZXdwb3J0Qm90dG9tID0gdGhpcy5iaW5kaW5nKFBIWF9WSUVXUE9SVF9CT1RUT00pO1xuICAgIHRoaXMuYWxsKFxuICAgICAgcGFyZW50LFxuICAgICAgYFske3BoeFZpZXdwb3J0VG9wfV0sIFske3BoeFZpZXdwb3J0Qm90dG9tfV1gLFxuICAgICAgKGhvb2tFbCkgPT4ge1xuICAgICAgICBkb21fZGVmYXVsdC5tYWludGFpblByaXZhdGVIb29rcyhcbiAgICAgICAgICBob29rRWwsXG4gICAgICAgICAgaG9va0VsLFxuICAgICAgICAgI
1HBoeFZpZXdwb3J0VG9wLFxuICAgICAgICAgIHBoeFZpZXdwb3J0Qm90dG9tXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMubWF5YmVBZGROZXdIb29rKGhvb2tFbCk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFsbChcbiAgICAgIHBhcmVudCxcbiAgICAgIGBbJHt0aGlzLmJpbmRpbmcoUEhYX0hPT0spfV0sIFtkYXRhLXBoeC0ke1BIWF9IT09LfV1gLFxuICAgICAgKGhvb2tFbCkgPT4ge1xuICAgICAgICB0aGlzLm1heWJlQWRkTmV3SG9vayhob29rRWwpO1xuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5hbGwocGFyZW50LCBgWyR7dGhpcy5iaW5kaW5nKFBIWF9NT1VOVEVEKX1dYCwgKGVsKSA9PiB7XG4gICAgICB0aGlzLm1heWJlTW91bnRlZChlbCk7XG4gICAgfSk7XG4gIH1cbiAgYWxsKHBhcmVudCwgc2VsZWN0b3IsIGNhbGxiYWNrKSB7XG4gICAgZG9tX2RlZmF1bHQuYWxsKHBhcmVudCwgc2VsZWN0b3IsIChlbCkgPT4ge1xuICAgICAgaWYgKHRoaXMub3duc0VsZW1lbnQoZWwpKSB7XG4gICAgICAgIGNhbGxiYWNrKGVsKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICBhcHBseUpvaW5QYXRjaChsaXZlX3BhdGNoLCBodG1sLCBzdHJlYW1zLCBldmVudHMpIHtcbiAgICBpZiAodGhpcy5qb2luQ291bnQgPiAxKSB7XG4gICAgICBpZiAodGhpcy5wZW5kaW5nSm9pbk9wcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nSm9pbk9wcy5mb3JFYWNoKChjYikgPT4gdHlwZW9mIGNiID09PSBcImZ1bmN0aW9uXCIgJiYgY2IoKSk7XG4gICAgICAgIHRoaXMucGVuZGluZ0pvaW5PcHMgPSBbXTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5hdHRhY2hUcnVlRG9jRWwoKTtcbiAgICBjb25zdCBwYXRjaCA9IG5ldyBET01QYXRjaCh0aGlzLCB0aGlzLmVsLCBodG1sLCBzdHJlYW1zLCBudWxsKTtcbiAgICBwYXRjaC5tYXJrUHJ1bmFibGVDb250ZW50Rm9yUmVtb3ZhbCgpO1xuICAgIHRoaXMucGVyZm9ybVBhdGNoKHBhdGNoLCBmYWxzZSwgdHJ1ZSk7XG4gICAgdGhpcy5qb2luTmV3Q2hpbGRyZW4oKTtcbiAgICB0aGlzLmV4ZWNOZXdNb3VudGVkKCk7XG4gICAgdGhpcy5qb2luUGVuZGluZyA9IGZhbHNlO1xuICAgIHRoaXMubGl2ZVNvY2tldC5kaXNwYXRjaEV2ZW50cyhldmVudHMpO1xuICAgIHRoaXMuYXBwbHlQZW5kaW5nVXBkYXRlcygpO1xuICAgIGlmIChsaXZlX3BhdGNoKSB7XG4gICAgICBjb25zdCB7IGtpbmQsIHRvIH0gPSBsaXZlX3BhdGNoO1xuICAgICAgdGhpcy5saXZlU29ja2V0Lmhpc3RvcnlQYXRjaCh0bywga2luZCk7XG4gICAgfVxuICAgIHRoaXMuaGlkZUxvYWRlcigpO1xuICAgIGlmICh0aGlzLmpvaW5Db3VudCA+IDEpIHtcbiAgICAgIHRoaXMudHJpZ2dlclJlY29ubmVjdGVkKCk7XG4gICAgfVxuICAgIHRoaXMuc3RvcENhbGxiYWNrKCk7XG4gIH1cbiAgdHJpZ2dlckJlZm9yZVVwZGF0ZUhvb2soZnJvbUVsLCB0b0VsKSB7XG4gICAgdGhpcy5saXZlU29ja2V0LnRyaWdnZXJET00oXCJvbkJlZm9yZUVsVXBkYXRlZFwiLCBbZnJvbUVsLCB0b0VsXSk7XG4gICAgY29uc3QgaG9vayA9IHRoaXMuZ2V0SG9vayhmcm9tRWwpO1xuICAgIGNvbnN0IGlzSWdub3JlZCA9IGhvb2sgJiYgZG9tX2RlZmF1bHQuaXNJZ25vcmVkKGZyb21FbCwgdGhpcy5iaW5kaW5nKFBIWF9VUERBVEUpKTtcbiAgICBpZiAoaG9vayAmJiAhZnJvbUVsLmlzRXF1YWxOb2RlKHRvRWwpICYmICEoaXNJZ25vcmVkICYmIGlzRXF1YWxPYmooZnJvbUVsLmRhdGFzZXQsIHRvRWwuZGF0YXNldCkpKSB7XG4gICAgICBob29rLl9fYmVmb3JlVXBkYXRlKCk7XG4gICAgICByZXR1cm4gaG9vaztcbiAgICB9XG4gIH1cbiAgbWF5YmVNb3VudGVkKGVsKSB7XG4gICAgY29uc3QgcGh4TW91bnRlZCA9IGVsLmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoUEhYX01PVU5URUQpKTtcbiAgICBjb25zdCBoYXNCZWVuSW52b2tlZCA9IHBoeE1vdW50ZWQgJiYgZG9tX2RlZmF1bHQucHJpdmF0ZShlbCwgXCJtb3VudGVkXCIpO1xuICAgIGlmIChwaHhNb3VudGVkICYmICFoYXNCZWVuSW52b2tlZCkge1xuICAgICAgdGhpcy5saXZlU29ja2V0LmV4ZWNKUyhlbCwgcGh4TW91bnRlZCk7XG4gICAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKGVsLCBcIm1vdW50ZWRcIiwgdHJ1ZSk7XG4gICAgfVxuICB9XG4gIG1heWJlQWRkTmV3SG9vayhlbCkge1xuICAgIGNvbnN0IG5ld0hvb2sgPSB0aGlzLmFkZEhvb2soZWwpO1xuICAgIGlmIChuZXdIb29rKSB7XG4gICAgICBuZXdIb29rLl9fbW91bnRlZCgpO1xuICAgIH1cbiAgfVxuICBwZXJmb3JtUGF0Y2gocGF0Y2gsIHBydW5lQ2lkcywgaXNKb2luUGF0Y2ggPSBmYWxzZSkge1xuICAgIGNvbnN0IHJlbW92ZWRFbHMgPSBbXTtcbiAgICBsZXQgcGh4Q2hpbGRyZW5BZGRlZCA9IGZhbHNlO1xuICAgIGNvbnN0IHVwZGF0ZWRIb29rSWRzID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgICB0aGlzLmxpdmVTb2NrZXQudHJpZ2dlckRPTShcIm9uUGF0Y2hTdGFydFwiLCBbcGF0Y2gudGFyZ2V0Q29udGFpbmVyXSk7XG4gICAgcGF0Y2guYWZ0ZXJBZGRlZCgoZWwpID0+IHtcbiAgICAgIHRoaXMubGl2ZVNvY2tldC50cmlnZ2VyRE9NKFwib25Ob2RlQWRkZWRcIiwgW2VsXSk7XG4gICAgICBjb25zdCBwaHhWaWV3cG9ydFRvcCA9IHRoaXMuYmluZGluZyhQSFhfVklFV1BPUlRfVE9QKTtcbiAgICAgIGNvbnN0IHBoeFZpZXdwb3J0Qm90dG9tID0gdGhpcy5iaW5kaW5nKFBIWF9WSUVXUE9SVF9CT1RUT00pO1xuICAgICAgZG9tX2RlZmF1bHQubWFpbnRhaW5Qcml2YXRlSG9va3MoZWwsIGVsLCBwaHhWaWV3cG9ydFRvcCwgcGh4Vmlld3BvcnRCb3R0b20pO1xuICAgICAgdGhpcy5tYXliZUFkZE5ld0hvb2soZWwpO1xuICAgICAgaWYgKGVsLmdldEF0dHJpYnV0ZSkge1xuICAgICAgICB0aGlzLm1heWJlTW91bnRlZChlbCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcGF0Y2guYWZ0ZXJQaHhDaGlsZEFkZGVkKChlbCkgPT4ge1xuICAgICAgaWYgKGRvbV9kZWZhdWx0LmlzUGh4U3RpY2t5KGVsKSkge1xuICAgICAgICB0aGlzLmxpdmVTb2NrZXQuam9pblJvb3RWaWV3cygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGh4Q2hpbGRyZW5BZGRlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcGF0Y2guYmVmb3JlVXBkYXRlZCgoZnJvbUVsLCB0b0VsKSA9PiB7XG4gICAgICBjb25zdCBob29rID0gdGhpcy50cmlnZ2VyQmVmb3JlVXBkYXRlSG9vayhmcm9tRWwsIHRvRWwpO1xuICAgICAgaWYgKGhvb2spIHtcbiAgICAgICAgdXBkYXRlZEhvb2tJZHMuYWRkKGZyb21FbC5pZCk7XG4gICAgICB9XG4gICAgICBqc19kZWZhdWx0Lm9uQmVmb3JlRWxVcGRhdGVkKGZyb21FbCwgdG9FbCk7XG4gICAgfSk7XG4gICAgcGF0Y2guYWZ0ZXJVcGRhdGVkKChlbCkgPT4ge1xuICAgICAgaWYgKHVwZGF0ZWRIb29rSWRzLmhhcyhlbC5pZCkpIHtcbiAgICAgICAgY29uc3QgaG9vayA9IHRoaXMuZ2V0SG9vayhlbCk7XG4gICAgICAgIGhvb2sgJiYgaG9vay5fX3VwZGF0ZWQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBwYXRjaC5hZnRlckRpc2NhcmRlZCgoZWwpID0+IHtcbiAgICAgIGlmIChlbC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgcmVtb3ZlZEVscy5wdXNoKGVsKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBwYXRjaC5hZnRlclRyYW5zaXRpb25zRGlzY2FyZGVkKFxuICAgICAgKGVscykgPT4gdGhpcy5hZnRlckVsZW1lbnRzUmVtb3ZlZChlbHMsIHBydW5lQ2lkcylcbiAgICApO
11xuICAgIHBhdGNoLnBlcmZvcm0oaXNKb2luUGF0Y2gpO1xuICAgIHRoaXMuYWZ0ZXJFbGVtZW50c1JlbW92ZWQocmVtb3ZlZEVscywgcHJ1bmVDaWRzKTtcbiAgICB0aGlzLmxpdmVTb2NrZXQudHJpZ2dlckRPTShcIm9uUGF0Y2hFbmRcIiwgW3BhdGNoLnRhcmdldENvbnRhaW5lcl0pO1xuICAgIHJldHVybiBwaHhDaGlsZHJlbkFkZGVkO1xuICB9XG4gIGFmdGVyRWxlbWVudHNSZW1vdmVkKGVsZW1lbnRzLCBwcnVuZUNpZHMpIHtcbiAgICBjb25zdCBkZXN0cm95ZWRDSURzID0gW107XG4gICAgZWxlbWVudHMuZm9yRWFjaCgocGFyZW50KSA9PiB7XG4gICAgICBjb25zdCBjb21wb25lbnRzID0gZG9tX2RlZmF1bHQuYWxsKFxuICAgICAgICBwYXJlbnQsXG4gICAgICAgIGBbJHtQSFhfVklFV19SRUZ9PVwiJHt0aGlzLmlkfVwiXVske1BIWF9DT01QT05FTlR9XWBcbiAgICAgICk7XG4gICAgICBjb25zdCBob29rcyA9IGRvbV9kZWZhdWx0LmFsbChcbiAgICAgICAgcGFyZW50LFxuICAgICAgICBgWyR7dGhpcy5iaW5kaW5nKFBIWF9IT09LKX1dLCBbZGF0YS1waHgtaG9va11gXG4gICAgICApO1xuICAgICAgY29tcG9uZW50cy5jb25jYXQocGFyZW50KS5mb3JFYWNoKChlbCkgPT4ge1xuICAgICAgICBjb25zdCBjaWQgPSB0aGlzLmNvbXBvbmVudElEKGVsKTtcbiAgICAgICAgaWYgKGlzQ2lkKGNpZCkgJiYgZGVzdHJveWVkQ0lEcy5pbmRleE9mKGNpZCkgPT09IC0xICYmIGVsLmdldEF0dHJpYnV0ZShQSFhfVklFV19SRUYpID09PSB0aGlzLmlkKSB7XG4gICAgICAgICAgZGVzdHJveWVkQ0lEcy5wdXNoKGNpZCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaG9va3MuY29uY2F0KHBhcmVudCkuZm9yRWFjaCgoaG9va0VsKSA9PiB7XG4gICAgICAgIGNvbnN0IGhvb2sgPSB0aGlzLmdldEhvb2soaG9va0VsKTtcbiAgICAgICAgaG9vayAmJiB0aGlzLmRlc3Ryb3lIb29rKGhvb2spO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaWYgKHBydW5lQ2lkcykge1xuICAgICAgdGhpcy5tYXliZVB1c2hDb21wb25lbnRzRGVzdHJveWVkKGRlc3Ryb3llZENJRHMpO1xuICAgIH1cbiAgfVxuICBqb2luTmV3Q2hpbGRyZW4oKSB7XG4gICAgZG9tX2RlZmF1bHQuZmluZFBoeENoaWxkcmVuKGRvY3VtZW50LCB0aGlzLmlkKS5mb3JFYWNoKChlbCkgPT4gdGhpcy5qb2luQ2hpbGQoZWwpKTtcbiAgfVxuICBtYXliZVJlY292ZXJGb3JtcyhodG1sLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHBoeENoYW5nZSA9IHRoaXMuYmluZGluZyhcImNoYW5nZVwiKTtcbiAgICBjb25zdCBvbGRGb3JtcyA9IHRoaXMucm9vdC5mb3Jtc0ZvclJlY292ZXJ5O1xuICAgIGNvbnN0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWw7XG4gICAgaWYgKCF0ZW1wbGF0ZS5jb250ZW50LmZpcnN0RWxlbWVudENoaWxkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRvbV9kZWZhdWx0LmFsbCh0ZW1wbGF0ZS5jb250ZW50LCBgWyR7UEhYX1BPUlRBTH1dYCkuZm9yRWFjaCgocG9ydGFsVGVtcGxhdGUpID0+IHtcbiAgICAgIGlmICghKHBvcnRhbFRlbXBsYXRlIGluc3RhbmNlb2YgSFRNTFRlbXBsYXRlRWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGVtcGxhdGUuY29udGVudC5maXJzdEVsZW1lbnRDaGlsZD8uYXBwZW5kQ2hpbGQoXG4gICAgICAgIHBvcnRhbFRlbXBsYXRlLmNvbnRlbnQuZmlyc3RFbGVtZW50Q2hpbGRcbiAgICAgICk7XG4gICAgfSk7XG4gICAgY29uc3Qgcm9vdEVsID0gdGVtcGxhdGUuY29udGVudC5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICByb290RWwuaWQgPSB0aGlzLmlkO1xuICAgIHJvb3RFbC5zZXRBdHRyaWJ1dGUoUEhYX1JPT1RfSUQsIHRoaXMucm9vdC5pZCk7XG4gICAgcm9vdEVsLnNldEF0dHJpYnV0ZShQSFhfU0VTU0lPTiwgdGhpcy5nZXRTZXNzaW9uKCkpO1xuICAgIHJvb3RFbC5zZXRBdHRyaWJ1dGUoUEhYX1NUQVRJQywgdGhpcy5nZXRTdGF0aWMoKSA/PyBcIlwiKTtcbiAgICB0aGlzLnBhcmVudCAmJiByb290RWwuc2V0QXR0cmlidXRlKFBIWF9QQVJFTlRfSUQsIHRoaXMucGFyZW50LmlkKTtcbiAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKHJvb3RFbCwgXCJ2aWV3XCIsIHRoaXMpO1xuICAgIGNvbnN0IGZvcm1zVG9SZWNvdmVyID0gKFxuICAgICAgLy8gd2UgZ28gb3ZlciBhbGwgZm9ybXMgaW4gdGhlIG5ldyBET007IGJlY2F1c2UgdGhpcyBpcyBvbmx5IHRoZSBIVE1MIGZvciB0aGUgY3VycmVudFxuICAgICAgLy8gdmlldywgd2UgY2FuIGJlIHN1cmUgdGhhdCBhbGwgZm9ybXMgYXJlIG93bmVkIGJ5IHRoaXMgdmlldzpcbiAgICAgIGRvbV9kZWZhdWx0LmFsbCh0ZW1wbGF0ZS5jb250ZW50LCBcImZvcm1cIikuZmlsdGVyKChuZXdGb3JtKSA9PiBuZXdGb3JtLmlkICYmIG9sZEZvcm1zW25ld0Zvcm0uaWRdKS5maWx0ZXIoKG5ld0Zvcm0pID0+ICF0aGlzLnBlbmRpbmdGb3Jtcy5oYXMobmV3Rm9ybS5pZCkpLmZpbHRlcihcbiAgICAgICAgKG5ld0Zvcm0pID0+IG9sZEZvcm1zW25ld0Zvcm0uaWRdLmdldEF0dHJpYnV0ZShwaHhDaGFuZ2UpID09PSBuZXdGb3JtLmdldEF0dHJpYnV0ZShwaHhDaGFuZ2UpXG4gICAgICApLm1hcCgobmV3Rm9ybSkgPT4ge1xuICAgICAgICByZXR1cm4gW29sZEZvcm1zW25ld0Zvcm0uaWRdLCBuZXdGb3JtXTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICBpZiAoZm9ybXNUb1JlY292ZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICB9XG4gICAgZm9ybXNUb1JlY292ZXIuZm9yRWFjaCgoW29sZEZvcm0sIG5ld0Zvcm1dLCBpKSA9PiB7XG4gICAgICB0aGlzLnBlbmRpbmdGb3Jtcy5hZGQobmV3Rm9ybS5pZCk7XG4gICAgICB0aGlzLnB1c2hGb3JtUmVjb3ZlcnkoXG4gICAgICAgIG9sZEZvcm0sXG4gICAgICAgIG5ld0Zvcm0sXG4gICAgICAgIHRlbXBsYXRlLmNvbnRlbnQuZmlyc3RFbGVtZW50Q2hpbGQsXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0aGlzLnBlbmRpbmdGb3Jtcy5kZWxldGUobmV3Rm9ybS5pZCk7XG4gICAgICAgICAgaWYgKGkgPT09IGZvcm1zVG9SZWNvdmVyLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG4gIGdldENoaWxkQnlJZChpZCkge1xuICAgIHJldHVybi
1B0aGlzLnJvb3QuY2hpbGRyZW5bdGhpcy5pZF1baWRdO1xuICB9XG4gIGdldERlc2NlbmRlbnRCeUVsKGVsKSB7XG4gICAgaWYgKGVsLmlkID09PSB0aGlzLmlkKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuY2hpbGRyZW4gJiYgdGhpcy5jaGlsZHJlbltlbC5nZXRBdHRyaWJ1dGUoUEhYX1BBUkVOVF9JRCldPy5bZWwuaWRdO1xuICAgIH1cbiAgfVxuICBkZXN0cm95RGVzY2VuZGVudChpZCkge1xuICAgIGZvciAoY29uc3QgcGFyZW50SWQgaW4gdGhpcy5yb290LmNoaWxkcmVuKSB7XG4gICAgICBmb3IgKGNvbnN0IGNoaWxkSWQgaW4gdGhpcy5yb290LmNoaWxkcmVuW3BhcmVudElkXSkge1xuICAgICAgICBpZiAoY2hpbGRJZCA9PT0gaWQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5yb290LmNoaWxkcmVuW3BhcmVudElkXVtjaGlsZElkXS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgam9pbkNoaWxkKGVsKSB7XG4gICAgY29uc3QgY2hpbGQgPSB0aGlzLmdldENoaWxkQnlJZChlbC5pZCk7XG4gICAgaWYgKCFjaGlsZCkge1xuICAgICAgY29uc3QgdmlldyA9IG5ldyBfVmlldyhlbCwgdGhpcy5saXZlU29ja2V0LCB0aGlzKTtcbiAgICAgIHRoaXMucm9vdC5jaGlsZHJlblt0aGlzLmlkXVt2aWV3LmlkXSA9IHZpZXc7XG4gICAgICB2aWV3LmpvaW4oKTtcbiAgICAgIHRoaXMuY2hpbGRKb2lucysrO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIGlzSm9pblBlbmRpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuam9pblBlbmRpbmc7XG4gIH1cbiAgYWNrSm9pbihfY2hpbGQpIHtcbiAgICB0aGlzLmNoaWxkSm9pbnMtLTtcbiAgICBpZiAodGhpcy5jaGlsZEpvaW5zID09PSAwKSB7XG4gICAgICBpZiAodGhpcy5wYXJlbnQpIHtcbiAgICAgICAgdGhpcy5wYXJlbnQuYWNrSm9pbih0aGlzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub25BbGxDaGlsZEpvaW5zQ29tcGxldGUoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgb25BbGxDaGlsZEpvaW5zQ29tcGxldGUoKSB7XG4gICAgdGhpcy5wZW5kaW5nRm9ybXMuY2xlYXIoKTtcbiAgICB0aGlzLmZvcm1zRm9yUmVjb3ZlcnkgPSB7fTtcbiAgICB0aGlzLmpvaW5DYWxsYmFjaygoKSA9PiB7XG4gICAgICB0aGlzLnBlbmRpbmdKb2luT3BzLmZvckVhY2goKFt2aWV3LCBvcF0pID0+IHtcbiAgICAgICAgaWYgKCF2aWV3LmlzRGVzdHJveWVkKCkpIHtcbiAgICAgICAgICBvcCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMucGVuZGluZ0pvaW5PcHMgPSBbXTtcbiAgICB9KTtcbiAgfVxuICB1cGRhdGUoZGlmZiwgZXZlbnRzLCBpc1BlbmRpbmcgPSBmYWxzZSkge1xuICAgIGlmICh0aGlzLmlzSm9pblBlbmRpbmcoKSB8fCB0aGlzLmxpdmVTb2NrZXQuaGFzUGVuZGluZ0xpbmsoKSAmJiB0aGlzLnJvb3QuaXNNYWluKCkpIHtcbiAgICAgIGlmICghaXNQZW5kaW5nKSB7XG4gICAgICAgIHRoaXMucGVuZGluZ0RpZmZzLnB1c2goeyBkaWZmLCBldmVudHMgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMucmVuZGVyZWQubWVyZ2VEaWZmKGRpZmYpO1xuICAgIGxldCBwaHhDaGlsZHJlbkFkZGVkID0gZmFsc2U7XG4gICAgaWYgKHRoaXMucmVuZGVyZWQuaXNDb21wb25lbnRPbmx5RGlmZihkaWZmKSkge1xuICAgICAgdGhpcy5saXZlU29ja2V0LnRpbWUoXCJjb21wb25lbnQgcGF0Y2ggY29tcGxldGVcIiwgKCkgPT4ge1xuICAgICAgICBjb25zdCBwYXJlbnRDaWRzID0gZG9tX2RlZmF1bHQuZmluZEV4aXN0aW5nUGFyZW50Q0lEcyhcbiAgICAgICAgICB0aGlzLmlkLFxuICAgICAgICAgIHRoaXMucmVuZGVyZWQuY29tcG9uZW50Q0lEcyhkaWZmKVxuICAgICAgICApO1xuICAgICAgICBwYXJlbnRDaWRzLmZvckVhY2goKHBhcmVudENJRCkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLmNvbXBvbmVudFBhdGNoKFxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlZC5nZXRDb21wb25lbnQoZGlmZiwgcGFyZW50Q0lEKSxcbiAgICAgICAgICAgIHBhcmVudENJRFxuICAgICAgICAgICkpIHtcbiAgICAgICAgICAgIHBoeENoaWxkcmVuQWRkZWQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKCFpc0VtcHR5KGRpZmYpKSB7XG4gICAgICB0aGlzLmxpdmVTb2NrZXQudGltZShcImZ1bGwgcGF0Y2ggY29tcGxldGVcIiwgKCkgPT4ge1xuICAgICAgICBjb25zdCBbaHRtbCwgc3RyZWFtc10gPSB0aGlzLnJlbmRlckNvbnRhaW5lcihkaWZmLCBcInVwZGF0ZVwiKTtcbiAgICAgICAgY29uc3QgcGF0Y2ggPSBuZXcgRE9NUGF0Y2godGhpcywgdGhpcy5lbCwgaHRtbCwgc3RyZWFtcywgbnVsbCk7XG4gICAgICAgIHBoeENoaWxkcmVuQWRkZWQgPSB0aGlzLnBlcmZvcm1QYXRjaChwYXRjaCwgdHJ1ZSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5saXZlU29ja2V0LmRpc3BhdGNoRXZlbnRzKGV2ZW50cyk7XG4gICAgaWYgKHBoeENoaWxkcmVuQWRkZWQpIHtcbiAgICAgIHRoaXMuam9pbk5ld0NoaWxkcmVuKCk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJlbmRlckNvbnRhaW5lcihkaWZmLCBraW5kKSB7XG4gICAgcmV0dXJuIHRoaXMubGl2ZVNvY2tldC50aW1lKGB0b1N0cmluZyBkaWZmICgke2tpbmR9KWAsICgpID0+IHtcbiAgICAgIGNvbnN0IHRhZyA9IHRoaXMuZWwudGFnTmFtZTtcbiAgICAgIGNvbnN0IGNpZHMgPSBkaWZmID8gdGhpcy5yZW5kZXJlZC5jb21wb25lbnRDSURzKGRpZmYpIDogbnVsbDtcbiAgICAgIGNvbnN0IHsgYnVmZmVyOiBodG1sLCBzdHJlYW1zIH0gPSB0aGlzLnJlbmRlcmVkLnRvU3RyaW5nKGNpZHMpO1xuICAgICAgcmV0dXJuIFtgPCR7dGFnfT4ke2h0bWx9PC8ke3RhZ30+YCwgc3RyZWFtc107XG4gICAgfSk7XG4gIH1cbiAgY29tcG9uZW50UGF0Y2goZGlmZiwgY2lkKSB7XG4gICAgaWYgKGlzRW1wdHkoZGlmZikpXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgeyBidWZmZXI6IGh0bWwsIHN0cmVhbXMgfSA9IHRoaXMucmVuZGVyZWQuY29tcG9uZW50VG9TdHJpbmc
1oY2lkKTtcbiAgICBjb25zdCBwYXRjaCA9IG5ldyBET01QYXRjaCh0aGlzLCB0aGlzLmVsLCBodG1sLCBzdHJlYW1zLCBjaWQpO1xuICAgIGNvbnN0IGNoaWxkcmVuQWRkZWQgPSB0aGlzLnBlcmZvcm1QYXRjaChwYXRjaCwgdHJ1ZSk7XG4gICAgcmV0dXJuIGNoaWxkcmVuQWRkZWQ7XG4gIH1cbiAgZ2V0SG9vayhlbCkge1xuICAgIHJldHVybiB0aGlzLnZpZXdIb29rc1tWaWV3SG9vay5lbGVtZW50SUQoZWwpXTtcbiAgfVxuICBhZGRIb29rKGVsKSB7XG4gICAgY29uc3QgaG9va0VsSWQgPSBWaWV3SG9vay5lbGVtZW50SUQoZWwpO1xuICAgIGlmIChlbC5nZXRBdHRyaWJ1dGUgJiYgIXRoaXMub3duc0VsZW1lbnQoZWwpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChob29rRWxJZCAmJiAhdGhpcy52aWV3SG9va3NbaG9va0VsSWRdKSB7XG4gICAgICBpZiAoVmlld0hvb2suZGVhZEhvb2soZWwpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGhvb2sgPSBkb21fZGVmYXVsdC5nZXRDdXN0b21FbEhvb2soZWwpIHx8IGxvZ0Vycm9yKGBubyBob29rIGZvdW5kIGZvciBjdXN0b20gZWxlbWVudDogJHtlbC5pZH1gKTtcbiAgICAgIHRoaXMudmlld0hvb2tzW2hvb2tFbElkXSA9IGhvb2s7XG4gICAgICBob29rLl9fYXR0YWNoVmlldyh0aGlzKTtcbiAgICAgIHJldHVybiBob29rO1xuICAgIH0gZWxzZSBpZiAoaG9va0VsSWQgfHwgIWVsLmdldEF0dHJpYnV0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBob29rTmFtZSA9IGVsLmdldEF0dHJpYnV0ZShgZGF0YS1waHgtJHtQSFhfSE9PS31gKSB8fCBlbC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9IT09LKSk7XG4gICAgICBpZiAoIWhvb2tOYW1lKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGhvb2tEZWZpbml0aW9uID0gdGhpcy5saXZlU29ja2V0LmdldEhvb2tEZWZpbml0aW9uKGhvb2tOYW1lKTtcbiAgICAgIGlmIChob29rRGVmaW5pdGlvbikge1xuICAgICAgICBpZiAoIWVsLmlkKSB7XG4gICAgICAgICAgbG9nRXJyb3IoXG4gICAgICAgICAgICBgbm8gRE9NIElEIGZvciBob29rIFwiJHtob29rTmFtZX1cIi4gSG9va3MgcmVxdWlyZSBhIHVuaXF1ZSBJRCBvbiBlYWNoIGVsZW1lbnQuYCxcbiAgICAgICAgICAgIGVsXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGhvb2tJbnN0YW5jZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAodHlwZW9mIGhvb2tEZWZpbml0aW9uID09PSBcImZ1bmN0aW9uXCIgJiYgaG9va0RlZmluaXRpb24ucHJvdG90eXBlIGluc3RhbmNlb2YgVmlld0hvb2spIHtcbiAgICAgICAgICAgIGhvb2tJbnN0YW5jZSA9IG5ldyBob29rRGVmaW5pdGlvbih0aGlzLCBlbCk7XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaG9va0RlZmluaXRpb24gPT09IFwib2JqZWN0XCIgJiYgaG9va0RlZmluaXRpb24gIT09IG51bGwpIHtcbiAgICAgICAgICAgIGhvb2tJbnN0YW5jZSA9IG5ldyBWaWV3SG9vayh0aGlzLCBlbCwgaG9va0RlZmluaXRpb24pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2dFcnJvcihcbiAgICAgICAgICAgICAgYEludmFsaWQgaG9vayBkZWZpbml0aW9uIGZvciBcIiR7aG9va05hbWV9XCIuIEV4cGVjdGVkIGEgY2xhc3MgZXh0ZW5kaW5nIFZpZXdIb29rIG9yIGFuIG9iamVjdCBkZWZpbml0aW9uLmAsXG4gICAgICAgICAgICAgIGVsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKTtcbiAgICAgICAgICBsb2dFcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBob29rIFwiJHtob29rTmFtZX1cIjogJHtlcnJvck1lc3NhZ2V9YCwgZWwpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZpZXdIb29rc1tWaWV3SG9vay5lbGVtZW50SUQoaG9va0luc3RhbmNlLmVsKV0gPSBob29rSW5zdGFuY2U7XG4gICAgICAgIHJldHVybiBob29rSW5zdGFuY2U7XG4gICAgICB9IGVsc2UgaWYgKGhvb2tOYW1lICE9PSBudWxsKSB7XG4gICAgICAgIGxvZ0Vycm9yKGB1bmtub3duIGhvb2sgZm91bmQgZm9yIFwiJHtob29rTmFtZX1cImAsIGVsKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZGVzdHJveUhvb2soaG9vaykge1xuICAgIGNvbnN0IGhvb2tJZCA9IFZpZXdIb29rLmVsZW1lbnRJRChob29rLmVsKTtcbiAgICBob29rLl9fZGVzdHJveWVkKCk7XG4gICAgaG9vay5fX2NsZWFudXBfXygpO1xuICAgIGRlbGV0ZSB0aGlzLnZpZXdIb29rc1tob29rSWRdO1xuICB9XG4gIGFwcGx5UGVuZGluZ1VwZGF0ZXMoKSB7XG4gICAgdGhpcy5wZW5kaW5nRGlmZnMgPSB0aGlzLnBlbmRpbmdEaWZmcy5maWx0ZXIoXG4gICAgICAoeyBkaWZmLCBldmVudHMgfSkgPT4gIXRoaXMudXBkYXRlKGRpZmYsIGV2ZW50cywgdHJ1ZSlcbiAgICApO1xuICAgIHRoaXMuZWFjaENoaWxkKChjaGlsZCkgPT4gY2hpbGQuYXBwbHlQZW5kaW5nVXBkYXRlcygpKTtcbiAgfVxuICBlYWNoQ2hpbGQoY2FsbGJhY2spIHtcbiAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMucm9vdC5jaGlsZHJlblt0aGlzLmlkXSB8fCB7fTtcbiAgICBmb3IgKGNvbnN0IGlkIGluIGNoaWxkcmVuKSB7XG4gICAgICBjYWxsYmFjayh0aGlzLmdldENoaWxkQnlJZChpZCkpO1xuICAgIH1cbiAgfVxuICBvbkNoYW5uZWwoZXZlbnQsIGNiKSB7XG4gICAgdGhpcy5saXZlU29ja2V0Lm9uQ2hhbm5lbCh0aGlzLmNoYW5uZWwsIGV2ZW50LCAocmVzcCkgPT4ge1xuICAgICAgaWYgKHRoaXMuaXNKb2luUGVuZGluZygpKSB7XG4gICAgICAgIGlmICh0aGlzLmpvaW5Db3VudCA+IDEpIHtcbiAgICAgICAgICB0aGlzLnBlbmRpbmdKb2luT3BzLnB1c2goKCkgPT4gY2IocmVzcCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucm9vdC5wZW5kaW5nSm9pbk9wcy5wdXNoKFt0aGlzLCAoKSA9PiBjYihyZXNwKV0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxpdmVTb2NrZXQucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiBjYihyZXNwKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgYmluZENoYW5uZWwoKSB7XG4gICAgdGhpcy5saXZlU29ja2V0Lm9uQ2hhbm5lbCh0aGlzLmNoYW5uZWwsIFwiZGlmZlwiLCAocmF3RGlmZikgPT4ge1xuICAgICAgdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICB0aGlzLmFwcGx5
1RGlmZihcbiAgICAgICAgICBcInVwZGF0ZVwiLFxuICAgICAgICAgIHJhd0RpZmYsXG4gICAgICAgICAgKHsgZGlmZiwgZXZlbnRzIH0pID0+IHRoaXMudXBkYXRlKGRpZmYsIGV2ZW50cylcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHRoaXMub25DaGFubmVsKFxuICAgICAgXCJyZWRpcmVjdFwiLFxuICAgICAgKHsgdG8sIGZsYXNoIH0pID0+IHRoaXMub25SZWRpcmVjdCh7IHRvLCBmbGFzaCB9KVxuICAgICk7XG4gICAgdGhpcy5vbkNoYW5uZWwoXCJsaXZlX3BhdGNoXCIsIChyZWRpcikgPT4gdGhpcy5vbkxpdmVQYXRjaChyZWRpcikpO1xuICAgIHRoaXMub25DaGFubmVsKFwibGl2ZV9yZWRpcmVjdFwiLCAocmVkaXIpID0+IHRoaXMub25MaXZlUmVkaXJlY3QocmVkaXIpKTtcbiAgICB0aGlzLmNoYW5uZWwub25FcnJvcigocmVhc29uKSA9PiB0aGlzLm9uRXJyb3IocmVhc29uKSk7XG4gICAgdGhpcy5jaGFubmVsLm9uQ2xvc2UoKHJlYXNvbikgPT4gdGhpcy5vbkNsb3NlKHJlYXNvbikpO1xuICB9XG4gIGRlc3Ryb3lBbGxDaGlsZHJlbigpIHtcbiAgICB0aGlzLmVhY2hDaGlsZCgoY2hpbGQpID0+IGNoaWxkLmRlc3Ryb3koKSk7XG4gIH1cbiAgb25MaXZlUmVkaXJlY3QocmVkaXIpIHtcbiAgICBjb25zdCB7IHRvLCBraW5kLCBmbGFzaCB9ID0gcmVkaXI7XG4gICAgY29uc3QgdXJsID0gdGhpcy5leHBhbmRVUkwodG8pO1xuICAgIGNvbnN0IGUgPSBuZXcgQ3VzdG9tRXZlbnQoXCJwaHg6c2VydmVyLW5hdmlnYXRlXCIsIHtcbiAgICAgIGRldGFpbDogeyB0bywga2luZCwgZmxhc2ggfVxuICAgIH0pO1xuICAgIHRoaXMubGl2ZVNvY2tldC5oaXN0b3J5UmVkaXJlY3QoZSwgdXJsLCBraW5kLCBmbGFzaCk7XG4gIH1cbiAgb25MaXZlUGF0Y2gocmVkaXIpIHtcbiAgICBjb25zdCB7IHRvLCBraW5kIH0gPSByZWRpcjtcbiAgICB0aGlzLmhyZWYgPSB0aGlzLmV4cGFuZFVSTCh0byk7XG4gICAgdGhpcy5saXZlU29ja2V0Lmhpc3RvcnlQYXRjaCh0bywga2luZCk7XG4gIH1cbiAgZXhwYW5kVVJMKHRvKSB7XG4gICAgcmV0dXJuIHRvLnN0YXJ0c1dpdGgoXCIvXCIpID8gYCR7d2luZG93LmxvY2F0aW9uLnByb3RvY29sfS8vJHt3aW5kb3cubG9jYXRpb24uaG9zdH0ke3RvfWAgOiB0bztcbiAgfVxuICBvblJlZGlyZWN0KHtcbiAgICB0byxcbiAgICBmbGFzaCxcbiAgICByZWxvYWRUb2tlblxuICB9KSB7XG4gICAgdGhpcy5saXZlU29ja2V0LnJlZGlyZWN0KHRvLCBmbGFzaCA/PyBudWxsLCByZWxvYWRUb2tlbiA/PyBudWxsKTtcbiAgfVxuICBpc0Rlc3Ryb3llZCgpIHtcbiAgICByZXR1cm4gdGhpcy5kZXN0cm95ZWQ7XG4gIH1cbiAgam9pbkRlYWQoKSB7XG4gICAgdGhpcy5pc0RlYWQgPSB0cnVlO1xuICB9XG4gIGpvaW4oY2FsbGJhY2spIHtcbiAgICB0aGlzLnNob3dMb2FkZXIodGhpcy5saXZlU29ja2V0LmxvYWRlclRpbWVvdXQpO1xuICAgIHRoaXMuYmluZENoYW5uZWwoKTtcbiAgICBpZiAodGhpcy5pc01haW4oKSkge1xuICAgICAgdGhpcy5zdG9wQ2FsbGJhY2sgPSB0aGlzLmxpdmVTb2NrZXQud2l0aFBhZ2VMb2FkaW5nKHtcbiAgICAgICAgdG86IHRoaXMuaHJlZixcbiAgICAgICAga2luZDogXCJpbml0aWFsXCJcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLmpvaW5DYWxsYmFjayA9IChvbkRvbmUpID0+IHtcbiAgICAgIG9uRG9uZSA9IG9uRG9uZSB8fCBmdW5jdGlvbigpIHtcbiAgICAgIH07XG4gICAgICBjYWxsYmFjayA/IGNhbGxiYWNrKHRoaXMuam9pbkNvdW50LCBvbkRvbmUpIDogb25Eb25lKCk7XG4gICAgfTtcbiAgICB0aGlzLndyYXBQdXNoKCgpID0+IHRoaXMuY2hhbm5lbC5qb2luKCksIHtcbiAgICAgIG9rOiAocmVzcCkgPT4gdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4gdGhpcy5vbkpvaW4ocmVzcCkpLFxuICAgICAgZXJyb3I6IChlcnJvcikgPT4gdGhpcy5vbkpvaW5FcnJvcihlcnJvciksXG4gICAgICB0aW1lb3V0OiAoKSA9PiB0aGlzLm9uSm9pbkVycm9yKHsgcmVhc29uOiBcInRpbWVvdXRcIiB9KVxuICAgIH0pO1xuICB9XG4gIG9uSm9pbkVycm9yKHJlc3ApIHtcbiAgICBpZiAocmVzcC5ldmVudHMpIHtcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5kaXNwYXRjaEV2ZW50cyhyZXNwLmV2ZW50cyk7XG4gICAgfVxuICAgIGlmIChyZXNwLnJlYXNvbiA9PT0gXCJyZWxvYWRcIikge1xuICAgICAgdGhpcy5sb2coXCJlcnJvclwiLCAoKSA9PiBbXG4gICAgICAgIGBmYWlsZWQgbW91bnQgd2l0aCAke3Jlc3Auc3RhdHVzfS4gRmFsbGluZyBiYWNrIHRvIHBhZ2UgcmVsb2FkYCxcbiAgICAgICAgcmVzcFxuICAgICAgXSk7XG4gICAgICB0aGlzLm9uUmVkaXJlY3Qoe1xuICAgICAgICB0bzogdGhpcy5saXZlU29ja2V0Lm1haW4uaHJlZixcbiAgICAgICAgcmVsb2FkVG9rZW46IHJlc3AudG9rZW5cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAocmVzcC5yZWFzb24gPT09IFwidW5hdXRob3JpemVkXCIgfHwgcmVzcC5yZWFzb24gPT09IFwic3RhbGVcIikge1xuICAgICAgdGhpcy5sb2coXCJlcnJvclwiLCAoKSA9PiBbXG4gICAgICAgIFwidW5hdXRob3JpemVkIGxpdmVfcmVkaXJlY3QuIEZhbGxpbmcgYmFjayB0byBwYWdlIHJlcXVlc3RcIixcbiAgICAgICAgcmVzcFxuICAgICAgXSk7XG4gICAgICB0aGlzLm9uUmVkaXJlY3QoeyB0bzogdGhpcy5saXZlU29ja2V0Lm1haW4uaHJlZiwgZmxhc2g6IHRoaXMuZmxhc2ggfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChyZXNwLnJlZGlyZWN0IHx8IHJlc3AubGl2ZV9yZWRpcmVjdCkge1xuICAgICAgdGhpcy5qb2luUGVuZGluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5jaGFubmVsLmxlYXZlKCk7XG4gICAgfVxuICAgIGlmIChyZXNwLnJlZGlyZWN0KSB7XG4gICAgICByZXR1cm4gdGhpcy5vblJlZGlyZWN0KHJlc3AucmVkaXJlY3QpO1xuICAgIH1cbiAgICBpZiAocmVzcC5saXZlX3JlZGlyZWN0KSB7XG4gICAgICByZXR1cm4gdGhpcy5vbkxpdmVSZWRpcmVjdChyZXNwLmxpdmVfcmVkaXJlY3QpO1xuICAgIH1cbiAgICB0aGlzLmxvZyhcImVycm9yXCIsICgpID0+IFtcInVuYWJsZSB0byBqb2luXCIsIHJlc3BdKTtcbiAgICBpZiAodGhpcy5pc01haW4oKSkge1xuICAgICAgdGhpcy5kaXNwbGF5RXJyb3IoXG4gICAgICAgIFtQSFhfTE9BRElOR19DTEFTUywgUEhYX0VSUk9SX0NMQVNTLCBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTXSxcbiAgICAgICAgeyB1bnN0cnVjdHVyZWRFcnJvcjogcmVzcCwgZXJyb3JLaW5kOiBcInNlcnZlclwiIH1cbiAgICAgICk7XG4gICAgICBpZiAodGhpcy5saXZlU29ja2V0LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgdGhpcy5saXZlU29ja2V0LnJlbG9hZFdpdGhKaXR0ZXIodGhpcyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLmpvaW5BdHRlbXB0cyA+PSBNQVhfQ0hJTERfSk9JTl9BVFRFTVBUUykge1xuICAgICAgICB0aGlzLnJvb3QuZGlzcGxheUVycm9yKFxuICAgICAgICAgIFtQSFhfTE9BRElOR19DTEFTUywgUEhYX0VSUk9SX0NMQVNTLCBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTXSxcbiAgICAgICAgICB7IHVuc3RydWN0dXJlZEVycm9yOiByZXNwLCBlcnJvcktpbmQ6IFwic2VydmVyXCIgfVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmxvZyhcImVycm9yXCIsICgpID0+IFtcbiAgICAgICAgICBgZ2l2aW5nIHVwIHRyeWluZyB0byBtb3VudCBhZnRlciAke01BWF9DSElMRF9KT0lOX0FUVEVNUFRTfSB0cmllc2AsXG4gICAgICAgICAgcmVzcFxuICAgICAgICBdKTtcbiAgICAgICAgdGhpcy5kZXN0cm95KCk7XG4gICAgICB9XG4gICAgICBjb25zdCB0cnVlQ2hpbGRFbCA9IGRvbV9kZWZhdWx0LmJ5SWQodGhpcy5lbC5pZCk7XG4gICAgICBpZiAodHJ1ZUNoaWxkRWwpIHtcbiAgICAgICAgZG9tX2RlZmF1bHQubWVyZ2VBdHRycyh0cnVlQ2hpbGRFbCwgdGhpcy5lbCk7XG4gICAgICAgI
1HRoaXMuZGlzcGxheUVycm9yKFxuICAgICAgICAgIFtQSFhfTE9BRElOR19DTEFTUywgUEhYX0VSUk9SX0NMQVNTLCBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTXSxcbiAgICAgICAgICB7IHVuc3RydWN0dXJlZEVycm9yOiByZXNwLCBlcnJvcktpbmQ6IFwic2VydmVyXCIgfVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmVsID0gdHJ1ZUNoaWxkRWw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRlc3Ryb3koKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgb25DbG9zZShyZWFzb24pIHtcbiAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmlzTWFpbigpICYmIHRoaXMubGl2ZVNvY2tldC5oYXNQZW5kaW5nTGluaygpICYmIHJlYXNvbiAhPT0gXCJsZWF2ZVwiKSB7XG4gICAgICByZXR1cm4gdGhpcy5saXZlU29ja2V0LnJlbG9hZFdpdGhKaXR0ZXIodGhpcyk7XG4gICAgfVxuICAgIHRoaXMuZGVzdHJveUFsbENoaWxkcmVuKCk7XG4gICAgdGhpcy5saXZlU29ja2V0LmRyb3BBY3RpdmVFbGVtZW50KHRoaXMpO1xuICAgIGlmICh0aGlzLmxpdmVTb2NrZXQuaXNVbmxvYWRlZCgpKSB7XG4gICAgICB0aGlzLnNob3dMb2FkZXIoQkVGT1JFX1VOTE9BRF9MT0FERVJfVElNRU9VVCk7XG4gICAgfVxuICB9XG4gIG9uRXJyb3IocmVhc29uKSB7XG4gICAgdGhpcy5vbkNsb3NlKHJlYXNvbik7XG4gICAgaWYgKHRoaXMubGl2ZVNvY2tldC5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICB0aGlzLmxvZyhcImVycm9yXCIsICgpID0+IFtcInZpZXcgY3Jhc2hlZFwiLCByZWFzb25dKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmxpdmVTb2NrZXQuaXNVbmxvYWRlZCgpKSB7XG4gICAgICBpZiAodGhpcy5saXZlU29ja2V0LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgdGhpcy5kaXNwbGF5RXJyb3IoXG4gICAgICAgICAgW1BIWF9MT0FESU5HX0NMQVNTLCBQSFhfRVJST1JfQ0xBU1MsIFBIWF9TRVJWRVJfRVJST1JfQ0xBU1NdLFxuICAgICAgICAgIHsgdW5zdHJ1Y3R1cmVkRXJyb3I6IHJlYXNvbiwgZXJyb3JLaW5kOiBcInNlcnZlclwiIH1cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZGlzcGxheUVycm9yKFxuICAgICAgICAgIFtQSFhfTE9BRElOR19DTEFTUywgUEhYX0VSUk9SX0NMQVNTLCBQSFhfQ0xJRU5UX0VSUk9SX0NMQVNTXSxcbiAgICAgICAgICB7IHVuc3RydWN0dXJlZEVycm9yOiByZWFzb24sIGVycm9yS2luZDogXCJjbGllbnRcIiB9XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGRpc3BsYXlFcnJvcihjbGFzc2VzLCBkZXRhaWxzID0ge30pIHtcbiAgICBpZiAodGhpcy5pc01haW4oKSkge1xuICAgICAgZG9tX2RlZmF1bHQuZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4OnBhZ2UtbG9hZGluZy1zdGFydFwiLCB7XG4gICAgICAgIGRldGFpbDogeyB0bzogdGhpcy5ocmVmLCBraW5kOiBcImVycm9yXCIsIC4uLmRldGFpbHMgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuc2hvd0xvYWRlcigpO1xuICAgIHRoaXMuc2V0Q29udGFpbmVyQ2xhc3NlcyguLi5jbGFzc2VzKTtcbiAgICB0aGlzLmRlbGF5ZWREaXNjb25uZWN0ZWQoKTtcbiAgfVxuICBkZWxheWVkRGlzY29ubmVjdGVkKCkge1xuICAgIHRoaXMuZGlzY29ubmVjdGVkVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuZXhlY0FsbCh0aGlzLmJpbmRpbmcoXCJkaXNjb25uZWN0ZWRcIikpO1xuICAgIH0sIHRoaXMubGl2ZVNvY2tldC5kaXNjb25uZWN0ZWRUaW1lb3V0KTtcbiAgfVxuICB3cmFwUHVzaChjYWxsZXJQdXNoLCByZWNlaXZlcykge1xuICAgIGNvbnN0IGxhdGVuY3kgPSB0aGlzLmxpdmVTb2NrZXQuZ2V0TGF0ZW5jeVNpbSgpO1xuICAgIGNvbnN0IHdpdGhMYXRlbmN5ID0gbGF0ZW5jeSA/IChjYikgPT4gc2V0VGltZW91dCgoKSA9PiAhdGhpcy5pc0Rlc3Ryb3llZCgpICYmIGNiKCksIGxhdGVuY3kpIDogKGNiKSA9PiAhdGhpcy5pc0Rlc3Ryb3llZCgpICYmIGNiKCk7XG4gICAgd2l0aExhdGVuY3koKCkgPT4ge1xuICAgICAgY2FsbGVyUHVzaCgpLnJlY2VpdmUoXG4gICAgICAgIFwib2tcIixcbiAgICAgICAgKHJlc3ApID0+IHdpdGhMYXRlbmN5KCgpID0+IHJlY2VpdmVzLm9rICYmIHJlY2VpdmVzLm9rKHJlc3ApKVxuICAgICAgKS5yZWNlaXZlKFxuICAgICAgICBcImVycm9yXCIsXG4gICAgICAgIChyZWFzb24pID0+IHdpdGhMYXRlbmN5KCgpID0+IHJlY2VpdmVzLmVycm9yICYmIHJlY2VpdmVzLmVycm9yKHJlYXNvbikpXG4gICAgICApLnJlY2VpdmUoXG4gICAgICAgIFwidGltZW91dFwiLFxuICAgICAgICAoKSA9PiB3aXRoTGF0ZW5jeSgoKSA9PiByZWNlaXZlcy50aW1lb3V0ICYmIHJlY2VpdmVzLnRpbWVvdXQoKSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cbiAgcHVzaFdpdGhSZXBseShyZWZHZW5lcmF0b3IsIGV2ZW50LCBwYXlsb2FkKSB7XG4gICAgaWYgKCF0aGlzLmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJubyBjb25uZWN0aW9uXCIpKTtcbiAgICB9XG4gICAgY29uc3QgW3JlZiwgW2VsXSwgb3B0c10gPSByZWZHZW5lcmF0b3IgPyByZWZHZW5lcmF0b3IoeyBwYXlsb2FkIH0pIDogW251bGwsIFtdLCB7fV07XG4gICAgY29uc3Qgb2xkSm9pbkNvdW50ID0gdGhpcy5qb2luQ291bnQ7XG4gICAgbGV0IG9uTG9hZGluZ0RvbmUgPSBmdW5jdGlvbigpIHtcbiAgICB9O1xuICAgIGlmIChvcHRzLnBhZ2VfbG9hZGluZykge1xuICAgICAgb25Mb2FkaW5nRG9uZSA9IHRoaXMubGl2ZVNvY2tldC53aXRoUGFnZUxvYWRpbmcoe1xuICAgICAgICBraW5kOiBcImVsZW1lbnRcIixcbiAgICAgICAgdGFyZ2V0OiBlbFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgcGF5bG9hZC5jaWQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgIGRlbGV0ZSBwYXlsb2FkLmNpZDtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMud3JhcFB1c2goKCkgPT4gdGhpcy5jaGFubmVsLnB1c2goZXZlbnQsIHBheWxvYWQsIFBVU0hfVElNRU9VVCksIHtcbiAgICAgICAgb2s6IChyZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlZiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5sYXN0QWNrUmVmID0gcmVmO1xuICAgICAgICAgI
1H1cbiAgICAgICAgICBjb25zdCBmaW5pc2ggPSAoaG9va1JlcGx5KSA9PiB7XG4gICAgICAgICAgICBpZiAocmVzcC5yZWRpcmVjdCkge1xuICAgICAgICAgICAgICB0aGlzLm9uUmVkaXJlY3QocmVzcC5yZWRpcmVjdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzcC5saXZlX3BhdGNoKSB7XG4gICAgICAgICAgICAgIHRoaXMub25MaXZlUGF0Y2gocmVzcC5saXZlX3BhdGNoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXNwLmxpdmVfcmVkaXJlY3QpIHtcbiAgICAgICAgICAgICAgdGhpcy5vbkxpdmVSZWRpcmVjdChyZXNwLmxpdmVfcmVkaXJlY3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb25Mb2FkaW5nRG9uZSgpO1xuICAgICAgICAgICAgcmVzb2x2ZSh7IHJlc3AsIHJlcGx5OiBob29rUmVwbHksIHJlZiB9KTtcbiAgICAgICAgICB9O1xuICAgICAgICAgIGlmIChyZXNwLmRpZmYpIHtcbiAgICAgICAgICAgIHRoaXMubGl2ZVNvY2tldC5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5hcHBseURpZmYoXCJ1cGRhdGVcIiwgcmVzcC5kaWZmLCAoeyBkaWZmLCByZXBseSwgZXZlbnRzIH0pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocmVmICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLnVuZG9SZWZzKHJlZiwgcGF5bG9hZC5ldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlKGRpZmYsIGV2ZW50cyk7XG4gICAgICAgICAgICAgICAgZmluaXNoKHJlcGx5KTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHJlZiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICB0aGlzLnVuZG9SZWZzKHJlZiwgcGF5bG9hZC5ldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaW5pc2gobnVsbCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKHJlYXNvbikgPT4gcmVqZWN0KG5ldyBFcnJvcihgZmFpbGVkIHdpdGggcmVhc29uOiAke0pTT04uc3RyaW5naWZ5KHJlYXNvbil9YCkpLFxuICAgICAgICB0aW1lb3V0OiAoKSA9PiB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcInRpbWVvdXRcIikpO1xuICAgICAgICAgIGlmICh0aGlzLmpvaW5Db3VudCA9PT0gb2xkSm9pbkNvdW50KSB7XG4gICAgICAgICAgICB0aGlzLmxpdmVTb2NrZXQucmVsb2FkV2l0aEppdHRlcih0aGlzLCAoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMubG9nKFwidGltZW91dFwiLCAoKSA9PiBbXG4gICAgICAgICAgICAgICAgXCJyZWNlaXZlZCB0aW1lb3V0IHdoaWxlIGNvbW11bmljYXRpbmcgd2l0aCBzZXJ2ZXIuIEZhbGxpbmcgYmFjayB0byBoYXJkIHJlZnJlc2ggZm9yIHJlY292ZXJ5XCJcbiAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIHVuZG9SZWZzKHJlZiwgcGh4RXZlbnQsIG9ubHlFbHMpIHtcbiAgICBpZiAoIXRoaXMuaXNDb25uZWN0ZWQoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzZWxlY3RvciA9IGBbJHtQSFhfUkVGX1NSQ309XCIke3RoaXMucmVmU3JjKCl9XCJdYDtcbiAgICBpZiAob25seUVscykge1xuICAgICAgb25seUVscyA9IG5ldyBTZXQob25seUVscyk7XG4gICAgICBkb21fZGVmYXVsdC5hbGwoZG9jdW1lbnQsIHNlbGVjdG9yLCAocGFyZW50KSA9PiB7XG4gICAgICAgIGlmIChvbmx5RWxzICYmICFvbmx5RWxzLmhhcyhwYXJlbnQpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGRvbV9kZWZhdWx0LmFsbChcbiAgICAgICAgICBwYXJlbnQsXG4gICAgICAgICAgc2VsZWN0b3IsXG4gICAgICAgICAgKGNoaWxkKSA9PiB0aGlzLnVuZG9FbFJlZihjaGlsZCwgcmVmLCBwaHhFdmVudClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy51bmRvRWxSZWYocGFyZW50LCByZWYsIHBoeEV2ZW50KTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBkb21fZGVmYXVsdC5hbGwoZG9jdW1lbnQsIHNlbGVjdG9yLCAoZWwpID0+IHRoaXMudW5kb0VsUmVmKGVsLCByZWYsIHBoeEV2ZW50KSk7XG4gICAgfVxuICB9XG4gIHVuZG9FbFJlZihlbCwgcmVmLCBwaHhFdmVudCkge1xuICAgIGNvbnN0IGVsUmVmID0gbmV3IEVsZW1lbnRSZWYoZWwpO1xuICAgIGVsUmVmLm1heWJlVW5kbyhyZWYsIHBoeEV2ZW50LCAoY2xvbmVkVHJlZSkgPT4ge1xuICAgICAgY29uc3QgcGF0Y2ggPSBuZXcgRE9NUGF0Y2godGhpcywgZWwsIGNsb25lZFRyZWUsIC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCksIG51bGwsIHtcbiAgICAgICAgdW5kb1JlZjogcmVmXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHBoeENoaWxkcmVuQWRkZWQgPSB0aGlzLnBlcmZvcm1QYXRjaChwYXRjaCwgdHJ1ZSk7XG4gICAgICBkb21fZGVmYXVsdC5hbGwoXG4gICAgICAgIGVsLFxuICAgICAgICBgWyR7UEhYX1JFRl9TUkN9PVwiJHt0aGlzLnJlZlNyYygpfVwiXWAsXG4gICAgICAgIChjaGlsZCkgPT4gdGhpcy51bmRvRWxSZWYoY2hpbGQsIHJlZiwgcGh4RXZlbnQpXG4gICAgICApO1xuICAgICAgaWYgKHBoeENoaWxkcmVuQWRkZWQpIHtcbiAgICAgICAgdGhpcy5qb2luTmV3Q2hpbGRyZW4oKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICByZWZTcmMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZWwuaWQ7XG4gIH1cbiAgcHV0UmVmKGVsZW1lbnRzLCBwaHhFdmVudCwgZXZlbnRUeXBlLCBvcHRzID0ge30pIHtcbiAgICBjb25zdCBuZXdSZWYgPSB0aGlzLnJlZisrO1xuICAgIGNvbnN0IGRpc2FibGVXaXRoID0gdGhpcy5iaW5kaW5nKFBIWF9ESVNBQkxFX1dJVEgpO1xuICAgIGlmIChvcHRzLmxvYWRpbmcpIHtcbiAgICAgIGNvbnN0IGxvYWRpbmdFbHMgPSBkb21fZGVmYXVsdC5hbGwoZG9jdW1lbnQsIG9wdHMubG9hZGluZykubWFwKChlbCkgPT4ge1xuICAgICAgICByZXR1cm4geyBlbCwgbG9jazogdHJ1ZSwgbG9hZGluZzogdHJ1ZSB9O1xuICAgICAgfSk7XG4gICAgICBlbGVtZW50cyA9IGVsZW1lbnRzLmNvbmNhdChsb2FkaW5nRWxzKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCB7IGVsLCBsb2NrLCBsb2FkaW5nIH0gb2YgZWxlbWVudHMpIHtcbiAgICAgIGlmICghbG9jayAmJiAhbG9hZGluZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwdXRSZWYgcmVxdWlyZXMgbG9jayBvciBsb2FkaW5nXCIpO1xuICAgICAgfVxuICAgICAgZWwuc2V0QXR0cmlidXRlKFBIWF9SRUZfU1JDLCB0aGlzLnJlZlNyYygpKTtcbiAgICAgIGlmIChsb2FkaW5nKSB7XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShQSFhfUkVGX0xPQURJTkcsIG5ld1JlZi50b1N0cmluZygpKTtcbiAgICAgIH1cbiAgICAgIGlmIChsb2NrKSB7XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShQSFhfUkVGX0xPQ0ssIG5ld1JlZi50b1N0cmluZygpKTtcbiAgICAgIH1cbiAgICAgIGlmICghbG9hZGluZyB8fCBvcHRzLnN1Ym1pdHRlciAmJiAhKGVsID09PSBvcHRzLnN1Ym1pdHRlciB8fCBlbCA9PT0gb3B0cy5mb3JtKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGxvY2tDb21wbGV0ZVByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKGBwaHg6dW5kby1sb2NrOiR7bmV3UmVmfWAsICgpID0+IHJlc29sdmUoZGV0YWlsKSwge1xuICAgICAgICAgIG9uY2U6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGxvYWRpbmdDb21wbGV0ZVByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgIGBwaHg6dW5kby1sb2FkaW5nOiR7bmV3UmVmfWAsXG4gICAgICAgICAgKCkgPT4gcmVzb2x2ZShkZXRhaWwpLFxuICAgICAgICAgI
1Hsgb25jZTogdHJ1ZSB9XG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICAgIGVsLmNsYXNzTGlzdC5hZGQoYHBoeC0ke2V2ZW50VHlwZX0tbG9hZGluZ2ApO1xuICAgICAgY29uc3QgZGlzYWJsZVRleHQgPSBlbC5nZXRBdHRyaWJ1dGUoZGlzYWJsZVdpdGgpO1xuICAgICAgaWYgKGRpc2FibGVUZXh0ICE9PSBudWxsKSB7XG4gICAgICAgIGlmICghZWwuZ2V0QXR0cmlidXRlKFBIWF9ESVNBQkxFX1dJVEhfUkVTVE9SRSkpIHtcbiAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVfV0lUSF9SRVNUT1JFLCBlbC50ZXh0Q29udGVudCB8fCBcIlwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGlzYWJsZVRleHQgIT09IFwiXCIpIHtcbiAgICAgICAgICBlbC50ZXh0Q29udGVudCA9IGRpc2FibGVUZXh0O1xuICAgICAgICB9XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBQSFhfRElTQUJMRUQsXG4gICAgICAgICAgZWwuZ2V0QXR0cmlidXRlKFBIWF9ESVNBQkxFRCkgfHwgKFwiZGlzYWJsZWRcIiBpbiBlbCA/IFN0cmluZyhlbC5kaXNhYmxlZCkgOiBcIlwiKVxuICAgICAgICApO1xuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiLCBcIlwiKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRldGFpbCA9IHtcbiAgICAgICAgZXZlbnQ6IHBoeEV2ZW50LFxuICAgICAgICBldmVudFR5cGUsXG4gICAgICAgIHJlZjogbmV3UmVmLFxuICAgICAgICBpc0xvYWRpbmc6IGxvYWRpbmcsXG4gICAgICAgIGlzTG9ja2VkOiBsb2NrLFxuICAgICAgICBsb2NrRWxlbWVudHM6IGVsZW1lbnRzLmZpbHRlcigoeyBsb2NrOiBsb2NrMiB9KSA9PiBsb2NrMikubWFwKCh7IGVsOiBlbDIgfSkgPT4gZWwyKSxcbiAgICAgICAgbG9hZGluZ0VsZW1lbnRzOiBlbGVtZW50cy5maWx0ZXIoKHsgbG9hZGluZzogbG9hZGluZzIgfSkgPT4gbG9hZGluZzIpLm1hcCgoeyBlbDogZWwyIH0pID0+IGVsMiksXG4gICAgICAgIHVubG9jazogKGVscykgPT4ge1xuICAgICAgICAgIGVscyA9IEFycmF5LmlzQXJyYXkoZWxzKSA/IGVscyA6IFtlbHNdO1xuICAgICAgICAgIHRoaXMudW5kb1JlZnMobmV3UmVmLCBwaHhFdmVudCwgZWxzKTtcbiAgICAgICAgfSxcbiAgICAgICAgbG9ja0NvbXBsZXRlOiBsb2NrQ29tcGxldGVQcm9taXNlLFxuICAgICAgICBsb2FkaW5nQ29tcGxldGU6IGxvYWRpbmdDb21wbGV0ZVByb21pc2UsXG4gICAgICAgIGxvY2s6IChsb2NrRWwpID0+IHtcbiAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzQWNrZWQobmV3UmVmKSkge1xuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShkZXRhaWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9ja0VsLnNldEF0dHJpYnV0ZShQSFhfUkVGX0xPQ0ssIG5ld1JlZik7XG4gICAgICAgICAgICBsb2NrRWwuc2V0QXR0cmlidXRlKFBIWF9SRUZfU1JDLCB0aGlzLnJlZlNyYygpKTtcbiAgICAgICAgICAgIGxvY2tFbC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICBgcGh4OmxvY2stc3RvcDoke25ld1JlZn1gLFxuICAgICAgICAgICAgICAoKSA9PiByZXNvbHZlKGRldGFpbCksXG4gICAgICAgICAgICAgIHsgb25jZTogdHJ1ZSB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgaWYgKG9wdHMucGF5bG9hZCkge1xuICAgICAgICBkZXRhaWxbXCJwYXlsb2FkXCJdID0gb3B0cy5wYXlsb2FkO1xuICAgICAgfVxuICAgICAgaWYgKG9wdHMudGFyZ2V0KSB7XG4gICAgICAgIGRldGFpbFtcInRhcmdldFwiXSA9IG9wdHMudGFyZ2V0O1xuICAgICAgfVxuICAgICAgaWYgKG9wdHMub3JpZ2luYWxFdmVudCkge1xuICAgICAgICBkZXRhaWxbXCJvcmlnaW5hbEV2ZW50XCJdID0gb3B0cy5vcmlnaW5hbEV2ZW50O1xuICAgICAgfVxuICAgICAgZWwuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwicGh4OnB1c2hcIiwge1xuICAgICAgICAgIGRldGFpbCxcbiAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgIGNhbmNlbGFibG
1U6IGZhbHNlXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgICAgaWYgKHBoeEV2ZW50KSB7XG4gICAgICAgIGVsLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KGBwaHg6cHVzaDoke3BoeEV2ZW50fWAsIHtcbiAgICAgICAgICAgIGRldGFpbCxcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZVxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBbbmV3UmVmLCBlbGVtZW50cy5tYXAoKHsgZWwgfSkgPT4gZWwpLCBvcHRzXTtcbiAgfVxuICBpc0Fja2VkKHJlZikge1xuICAgIHJldHVybiB0aGlzLmxhc3RBY2tSZWYgIT09IG51bGwgJiYgdGhpcy5sYXN0QWNrUmVmID49IHJlZjtcbiAgfVxuICBjb21wb25lbnRJRChlbCkge1xuICAgIGNvbnN0IGNpZCA9IGVsLmdldEF0dHJpYnV0ZSAmJiBlbC5nZXRBdHRyaWJ1dGUoUEhYX0NPTVBPTkVOVCk7XG4gICAgcmV0dXJuIGNpZCA/IHBhcnNlSW50KGNpZCkgOiBudWxsO1xuICB9XG4gIHRhcmdldENvbXBvbmVudElEKHRhcmdldCwgdGFyZ2V0Q3R4LCBvcHRzID0ge30pIHtcbiAgICBpZiAoaXNDaWQodGFyZ2V0Q3R4KSkge1xuICAgICAgcmV0dXJuIHRhcmdldEN0eDtcbiAgICB9XG4gICAgY29uc3QgY2lkT3JTZWxlY3RvciA9IG9wdHMudGFyZ2V0IHx8IHRhcmdldC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwidGFyZ2V0XCIpKTtcbiAgICBpZiAoaXNDaWQoY2lkT3JTZWxlY3RvcikpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgY2lkT3JTZWxlY3RvciA9PT0gXCJudW1iZXJcIiA/IGNpZE9yU2VsZWN0b3IgOiBwYXJzZUludChjaWRPclNlbGVjdG9yKTtcbiAgICB9IGVsc2UgaWYgKHRhcmdldEN0eCAmJiAoY2lkT3JTZWxlY3RvciAhPT0gbnVsbCB8fCBvcHRzLnRhcmdldCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmNsb3Nlc3RDb21wb25lbnRJRCh0YXJnZXRDdHgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cbiAgY2xvc2VzdENvbXBvbmVudElEKHRhcmdldEN0eCkge1xuICAgIGlmIChpc0NpZCh0YXJnZXRDdHgpKSB7XG4gICAgICByZXR1cm4gdGFyZ2V0Q3R4O1xuICAgIH0gZWxzZSBpZiAodGFyZ2V0Q3R4KSB7XG4gICAgICByZXR1cm4gbWF5YmUoXG4gICAgICAgIC8vIFdlIGVpdGhlciB1c2UgdGhlIGNsb3Nlc3QgZGF0YS1waHgtY29tcG9uZW50IGJpbmRpbmcsIG9yIC1cbiAgICAgICAgLy8gaW4gY2FzZSBvZiBwb3J0YWxzIC0gY29udGludWUgd2l0aCB0aGUgcG9ydGFsIHNvdXJjZS5cbiAgICAgICAgLy8gVGhpcyBpcyBuZWNlc3NhcnkgaWYgdGVsZXBvcnRpbmcgYW4gZWxlbWVudCBvdXRzaWRlIG9mIGl0cyBMaXZlQ29tcG9uZW50LlxuICAgICAgICB0YXJnZXRDdHguY2xvc2VzdChgWyR7UEhYX0NPTVBPTkVOVH1dLFske1BIWF9URUxFUE9SVEVEX1NSQ31dYCksXG4gICAgICAgIChlbCkgPT4ge1xuICAgICAgICAgIGlmIChlbC5oYXNBdHRyaWJ1dGUoUEhYX0NPTVBPTkVOVCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm93bnNFbGVtZW50KGVsKSAmJiB0aGlzLmNvbXBvbmVudElEKGVsKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVsLmhhc0F0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9TUkMpKSB7XG4gICAgICAgICAgICBjb25zdCBwb3J0YWxQYXJlbnQgPSBkb21fZGVmYXVsdC5ieUlkKGVsLmdldEF0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9TUkMpKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNsb3Nlc3RDb21wb25lbnRJRChwb3J0YWxQYXJlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG4gIHB1c2hIb29rRXZlbnQoZWwsIHRhcmdldEN0eCwgZXZlbnQsIHBheWxvYWQpIHtcbiAgICBpZiAoIXRoaXMuaXNDb25uZWN0ZWQoKSkge1xuICAgICAgdGhpcy5sb2coXCJob29rXCIsICgpID0+IFtcbiAgICAgICAgXCJ1bmFibGUgdG8gcHVzaCBob29rIGV2ZW50LiBMaXZlVmlldyBub3QgY29ubmVjdGVkXCIsXG4gICAgICAgIGV2ZW50LFxuICAgICAgICBwYXlsb2FkXG4gICAgICBdKTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgbmV3IEVycm9yKFwidW5hYmxlIHRvIHB1c2ggaG9vayBldmVudC4gTGl2ZVZpZXcgbm90IGNvbm5lY3RlZFwiKVxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcmVmR2VuZXJhdG9yID0gKCkgPT4gdGhpcy5wdXRSZWYoW3sgZWwsIGxvYWRpbmc6IHRydWUsIGxvY2s6IHRydWUgfV0sIGV2ZW50LCBcImhvb2tcIiwge1xuICAgICAgcGF5bG9hZCxcbiAgICAgIHRhcmdldDogdGFyZ2V0Q3R4XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucHVzaFdpdGhSZXBseShyZWZHZW5lcmF0b3IsIFwiZXZlbnRcIiwge1xuICAgICAgdHlwZTogXCJob29rXCIsXG4gICAgICBldmVudCxcbiAgICAgIHZhbHVlOiBwYXlsb2FkLFxuICAgICAgY2lkOiB0aGlzLmNsb3Nlc3RDb21wb25lbnRJRCh0YXJnZXRDdHgpXG4gICAgfSkudGhlbihcbiAgICAgICh7IHJlc3A6IF9yZXNwLCByZXBseSwgcmVmIH0pID0+ICh7IHJlcGx5LCByZWYgfSlcbiAgICApO1xuICB9XG4gIGV4dHJhY3RNZXRhKGVsLCBtZXRhLCB2YWx1ZSkge1xuICAgIGNvbnN0IHByZWZpeCA9IHRoaXMuYmluZGluZyhcInZhbHVlLVwiKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVsLmF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghbWV0YSkge1xuICAgICAgICBtZXRhID0ge307XG4gICAgICB9XG4gICAgICBjb25zdCBuYW1lID0gZWwuYXR0cmlidXRlc1tpXS5uYW1lO1xuICAgICAgaWYgKG5hbWUuc3RhcnRzV2l0aChwcmVmaXgpKSB7XG4gICAgICAgIG1ldGFbbmFtZS5yZXBsYWNlKHByZWZpeCwgXCJcIildID0gZWwuZ2V0QXR0cmlidXRlKG5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZWwudmFsdWUgIT09IHZvaWQgMCAmJiAhKGVsIGluc3RhbmNlb2YgSFRNTEZvcm1FbGVtZW50KSkge1xuICAgICAgaWYgKCFtZXRhKSB7XG4gICAgICAgIG1ldGEgPSB7fTtcbiAgICAgIH1cbiAgICAgIG1ldGEudmFsdWUgPSBlbC52YWx1ZTtcbiAgICAgIGlmIChlbC50YWdOYW1lID09PSBcIklOUFVUXCIgJiYgQ0hFQ0tBQkxFX0lOUFVUUy5pbmRleE9mKG
1VsLnR5cGUpID49IDAgJiYgIWVsLmNoZWNrZWQpIHtcbiAgICAgICAgZGVsZXRlIG1ldGEudmFsdWU7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh2YWx1ZSkge1xuICAgICAgaWYgKCFtZXRhKSB7XG4gICAgICAgIG1ldGEgPSB7fTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3Qga2V5IGluIHZhbHVlKSB7XG4gICAgICAgIG1ldGFba2V5XSA9IHZhbHVlW2tleV07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtZXRhO1xuICB9XG4gIHNlcmlhbGl6ZUZvcm0oZm9ybSwgb3B0cyA9IHt9LCBvbmx5TmFtZXMgPSBbXSkge1xuICAgIGNvbnN0IHsgc3VibWl0dGVyIH0gPSBvcHRzO1xuICAgIGxldCBpbmplY3RlZEVsZW1lbnQ7XG4gICAgaWYgKHN1Ym1pdHRlciAmJiBzdWJtaXR0ZXIubmFtZSkge1xuICAgICAgY29uc3QgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gICAgICBpbnB1dC50eXBlID0gXCJoaWRkZW5cIjtcbiAgICAgIGNvbnN0IGZvcm1JZCA9IHN1Ym1pdHRlci5nZXRBdHRyaWJ1dGUoXCJmb3JtXCIpO1xuICAgICAgaWYgKGZvcm1JZCkge1xuICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoXCJmb3JtXCIsIGZvcm1JZCk7XG4gICAgICB9XG4gICAgICBpbnB1dC5uYW1lID0gc3VibWl0dGVyLm5hbWU7XG4gICAgICBpbnB1dC52YWx1ZSA9IHN1Ym1pdHRlci52YWx1ZTtcbiAgICAgIHN1Ym1pdHRlci5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZShpbnB1dCwgc3VibWl0dGVyKTtcbiAgICAgIGluamVjdGVkRWxlbWVudCA9IGlucHV0O1xuICAgIH1cbiAgICBjb25zdCBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YShmb3JtKTtcbiAgICBjb25zdCB0b1JlbW92ZSA9IFtdO1xuICAgIGZvcm1EYXRhLmZvckVhY2goKHZhbCwga2V5LCBfaW5kZXgpID0+IHtcbiAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBGaWxlKSB7XG4gICAgICAgIHRvUmVtb3ZlLnB1c2goa2V5KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0b1JlbW92ZS5mb3JFYWNoKChrZXkpID0+IGZvcm1EYXRhLmRlbGV0ZShrZXkpKTtcbiAgICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG4gICAgY29uc3QgeyBpbnB1dHNVbnVzZWQsIG9ubHlIaWRkZW5JbnB1dHMgfSA9IEFycmF5LmZyb20oZm9ybS5lbGVtZW50cykucmVkdWNlKFxuICAgICAgKGFjYywgaW5wdXQpID0+IHtcbiAgICAgICAgaWYgKCFkb21fZGVmYXVsdC5pc0Zvcm1Bc3NvY2lhdGVkKGlucHV0KSkge1xuICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBpbnB1dHNVbnVzZWQ6IGlucHV0c1VudXNlZDIsIG9ubHlIaWRkZW5JbnB1dHM6IG9ubHlIaWRkZW5JbnB1dHMyIH0gPSBhY2M7XG4gICAgICAgIGNvbnN0IGtleSA9IGlucHV0Lm5hbWU7XG4gICAgICAgIGlmICgha2V5KSB7XG4gICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5wdXRzVW51c2VkMltrZXldID09PSB2b2lkIDApIHtcbiAgICAgICAgICBpbnB1dHNVbnVzZWQyW2tleV0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvbmx5SGlkZGVuSW5wdXRzMltrZXldID09PSB2b2lkIDApIHtcbiAgICAgICAgICBvbmx5SGlkZGVuSW5wdXRzMltrZXldID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbnB1dFNraXBVbnVzZWRGaWVsZCA9IGlucHV0Lmhhc0F0dHJpYnV0ZShcbiAgICAgICAgICB0aGlzLmJpbmRpbmcoUEhYX05PX1VOVVNFRF9GSUVMRClcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgaXNVc2VkID0gZG9tX2RlZmF1bHQucHJpdmF0ZShpbnB1dCwgUEhYX0hBU19GT0NVU0VEKSB8fCBkb21fZGVmYXVsdC5wcml2YXRlKGlucHV0LCBQSFhfSEFTX1NVQk1JVFRFRCkgfHwgaW5wdXRTa2lwVW51c2VkRmllbGQ7XG4gICAgICAgIGNvbnN0IGlzSGlkZGVuID0gaW5wdXQudHlwZSA9PT0gXCJoaWRkZW5cIjtcbiAgICAgICAgaW5wdXRzVW51c2VkMltrZXldID0gaW5wdXRzVW51c2VkMltrZXldICYmICFpc1VzZWQ7XG4gICAgICAgIG9ubHlIaWRkZW5JbnB1dHMyW2tleV0gPSBvbmx5SGlkZGVuSW5wdXRzMltrZXldICYmIGlzSGlkZGVuO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIHsgaW5wdXRzVW51c2VkOiB7fSwgb25seUhpZGRlbklucHV0czoge30gfVxuICAgICk7XG4gICAgY29uc3QgZm9ybVNraXBVbnVzZWRGaWVsZHMgPSBmb3JtLmhhc0F0dHJpYnV0ZShcbiAgICAgIHRoaXMuYmluZGluZyhQSFhfTk9fVU5VU0VEX0ZJRUxEKVxuICAgICk7XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWxdIG9mIGZvcm1EYXRhLmVudHJpZXMoKSkge1xuICAgICAgaWYgKG9ubHlOYW1lcy5sZW5ndGggPT09IDAgfHwgb25seU5hbWVzLmluZGV4T2Yoa2V5KSA+PSAwKSB7XG4gICAgICAgIGNvbnN0IGlzVW51c2VkID0gaW5wdXRzVW51c2VkW2tleV07XG4gICAgICAgIGNvbnN0IGhpZGRlbiA9IG9ubHlIaWRkZW5JbnB1dHNba2V5XTtcbiAgICAgICAgY29uc3Qgc2tpcFVudXNlZENoZWNrID0gZm9ybVNraXBVbnVzZWRGaWVsZHM7XG4gICAgICAgIGlmICghc2tpcFVudXNlZENoZWNrICYmIGlzVW51c2VkICYmICEoc3VibWl0dGVyICYmIHN1Ym1pdHRlci5uYW1lID09IGtleSkgJiYgIWhpZGRlbikge1xuICAgICAgICAgIHBhcmFtcy5hcHBlbmQocHJlcGVuZEZvcm1EYXRhS2V5KGtleSwgXCJfdW51c2VkX1wiKSwgXCJcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWwgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICBwYXJhbXMuYXBwZW5kKGtleSwgdmFsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc3VibWl0dGVyICYmIGluamVjdGVkRWxlbWVudCkge1xuICAgICAgc3VibWl0dGVyLnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoaW5qZWN0ZWRFbGVtZW50KTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcmFtcy50b1N0cmluZygpO1xuICB9XG4gIHB1c2hFdmVudCh0eXBlLCBlbCwgdGFyZ2V0Q3R4LCBwaHhFdmVudCwgbWV0YSwgb3B0cyA9IHt9LCBvblJlcGx5KSB7XG4gICAgdGhpcy5wdXNoV2l0aFJlcGx5KFxuICAgICAgKG1heWJlUGF5bG9hZCkgPT4gdGhpcy5wdXRSZWYoW3sgZWwsIGxvYWRpbmc6IHRydWUsIGxvY2s6IHRydWUgfV0sIHBoeEV2ZW50LCB0eX
1BlLCB7XG4gICAgICAgIC4uLm9wdHMsXG4gICAgICAgIHBheWxvYWQ6IG1heWJlUGF5bG9hZD8ucGF5bG9hZFxuICAgICAgfSksXG4gICAgICBcImV2ZW50XCIsXG4gICAgICB7XG4gICAgICAgIHR5cGUsXG4gICAgICAgIGV2ZW50OiBwaHhFdmVudCxcbiAgICAgICAgdmFsdWU6IHRoaXMuZXh0cmFjdE1ldGEoZWwsIG1ldGEsIG9wdHMudmFsdWUpLFxuICAgICAgICBjaWQ6IHRoaXMudGFyZ2V0Q29tcG9uZW50SUQoZWwsIHRhcmdldEN0eCwgb3B0cylcbiAgICAgIH1cbiAgICApLnRoZW4oKHsgcmVwbHkgfSkgPT4gb25SZXBseSAmJiBvblJlcGx5KHJlcGx5KSkuY2F0Y2goKGVycm9yKSA9PiBsb2dFcnJvcihcIkZhaWxlZCB0byBwdXNoIGV2ZW50XCIsIGVycm9yKSk7XG4gIH1cbiAgcHVzaEZpbGVQcm9ncmVzcyhmaWxlRWwsIGVudHJ5UmVmLCBwcm9ncmVzcywgb25SZXBseSA9IGZ1bmN0aW9uKCkge1xuICB9KSB7XG4gICAgdGhpcy5saXZlU29ja2V0LndpdGhpbk93bmVycyhmaWxlRWwuZm9ybSwgKHZpZXcsIHRhcmdldEN0eCkgPT4ge1xuICAgICAgdmlldy5wdXNoV2l0aFJlcGx5KG51bGwsIFwicHJvZ3Jlc3NcIiwge1xuICAgICAgICBldmVudDogZmlsZUVsLmdldEF0dHJpYnV0ZSh2aWV3LmJpbmRpbmcoUEhYX1BST0dSRVNTKSksXG4gICAgICAgIHJlZjogZmlsZUVsLmdldEF0dHJpYnV0ZShQSFhfVVBMT0FEX1JFRiksXG4gICAgICAgIGVudHJ5X3JlZjogZW50cnlSZWYsXG4gICAgICAgIHByb2dyZXNzLFxuICAgICAgICBjaWQ6IHZpZXcudGFyZ2V0Q29tcG9uZW50SUQoZmlsZUVsLmZvcm0sIHRhcmdldEN0eClcbiAgICAgIH0pLnRoZW4oKCkgPT4gb25SZXBseSgpKS5jYXRjaCgoZXJyb3IpID0+IGxvZ0Vycm9yKFwiRmFpbGVkIHRvIHB1c2ggZmlsZSBwcm9ncmVzc1wiLCBlcnJvcikpO1xuICAgIH0pO1xuICB9XG4gIHB1c2hJbnB1dChpbnB1dEVsLCB0YXJnZXRDdHgsIGZvcmNlQ2lkLCBwaHhFdmVudCwgb3B0cywgY2FsbGJhY2spIHtcbiAgICBpZiAoIWlucHV0RWwuZm9ybSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZm9ybSBldmVudHMgcmVxdWlyZSB0aGUgaW5wdXQgdG8gYmUgaW5zaWRlIGEgZm9ybVwiKTtcbiAgICB9XG4gICAgbGV0IHVwbG9hZHM7XG4gICAgY29uc3QgY2lkID0gaXNDaWQoZm9yY2VDaWQpID8gZm9yY2VDaWQgOiB0aGlzLnRhcmdldENvbXBvbmVudElEKGlucHV0RWwuZm9ybSwgdGFyZ2V0Q3R4LCBvcHRzKTtcbiAgICBjb25zdCByZWZHZW5lcmF0b3IgPSAobWF5YmVQYXlsb2FkKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5wdXRSZWYoXG4gICAgICAgIFtcbiAgICAgICAgICB7IGVsOiBpbnB1dEVsLCBsb2FkaW5nOiB0cnVlLCBsb2NrOiB0cnVlIH0sXG4gICAgICAgICAgeyBlbDogaW5wdXRFbC5mb3JtLCBsb2FkaW5nOiB0cnVlLCBsb2NrOiB0cnVlIH1cbiAgICAgICAgXSxcbiAgICAgICAgcGh4RXZlbnQsXG4gICAgICAgIFwiY2hhbmdlXCIsXG4gICAgICAgIHsgLi4ub3B0cywgcGF5bG9hZDogbWF5YmVQYXlsb2FkPy5wYXlsb2FkIH1cbiAgICAgICk7XG4gICAgfTtcbiAgICBsZXQgZm9ybURhdGE7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuZXh0cmFjdE1ldGEoaW5wdXRFbC5mb3JtLCB7fSwgb3B0cy52YWx1ZSk7XG4gICAgY29uc3Qgc2VyaWFsaXplT3B0cyA9IHt9O1xuICAgIGlmIChpbnB1dEVsIGluc3RhbmNlb2YgSFRNTEJ1dHRvbkVsZW1lbnQpIHtcbiAgICAgIHNlcmlhbGl6ZU9wdHMuc3VibWl0dGVyID0gaW5wdXRFbDtcbiAgICB9XG4gICAgaWYgKGlucHV0RWwuZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhcImNoYW5nZVwiKSkpIHtcbiAgICAgIGZvcm1EYXRhID0gdGhpcy5zZXJpYWxpemVGb3JtKGlucHV0RWwuZm9ybSwgc2VyaWFsaXplT3B0cywgW1xuICAgICAgICBpbnB1dEVsLm5hbWVcbiAgICAgIF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3JtRGF0YSA9IHRoaXMuc2VyaWFsaXplRm9ybShpbnB1dEVsLmZvcm0sIHNlcmlhbGl6ZU9wdHMpO1xuICAgIH1cbiAgICBpZiAoZG9tX2RlZmF1bHQuaXNVcGxvYWRJbnB1dChpbnB1dEVsKSAmJiBpbnB1dEVsLmZpbGVzICYmIGlucHV0RWwuZmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgTGl2ZVVwbG9hZGVyLnRyYWNrRmlsZXMoaW5wdXRFbCwgQXJyYXkuZnJvbShpbnB1dEVsLmZpbGVzKSk7XG4gICAgfVxuICAgIHVwbG9hZHMgPSBMaXZlVXBsb2FkZXIuc2VyaWFsaXplVXBsb2FkcyhpbnB1dEVsKTtcbiAgICBjb25zdCBldmVudCA9IHtcbiAgICAgIHR5cGU6IFwiZm9ybVwiLFxuICAgICAgZXZlbnQ6IHBoeEV2ZW50LFxuICAgICAgdmFsdWU6IGZvcm1EYXRhLFxuICAgICAgbWV0YToge1xuICAgICAgICAvLyBubyB0YXJnZXQgd2FzIGltcGxpY2l0bHkgc2VudCBhcyBcInVuZGVmaW5lZFwiIGluIExWIDw9IDEuMC41LCB0aGVyZWZvcmVcbiAgICAgICAgLy8gd2UgaGF2ZSB0byBrZWVwIGl0LiBJbiAxLjAuNiB3ZSBzd2l0Y2hlZCBmcm9tIHBhc3NpbmcgbWV0YSBhcyBVUkwgZW5jb2RlZCBkYXRhXG4gICAgICAgIC8vIHRvIHBhc3NpbmcgaXQgZGlyZWN0bHkgaW4gdGhlIGV2ZW50LCBidXQgdGhlIEpTT04gZW5jb2RlIHdvdWxkIGRyb3Aga2V5cyB3aXRoXG4gICAgICAgIC8vIHVuZGVmaW5lZCB2YWx1ZXMuXG4gICAgICAgIF90YXJnZXQ6IG9wdHMuX3RhcmdldCB8fCBcInVuZGVmaW5lZFwiLFxuICAgICAgICAuLi5tZXRhXG4gICAgICB9LFxuICAgICAgdXBsb2FkcyxcbiAgICAgIGNpZFxuICAgIH07XG4gICAgdGhpcy5wdXNoV2l0aFJlcGx5KHJlZkdlbmVyYXRvciwgXCJldmVudFwiLCBldmVudCkudGhlbigoeyByZXNwIH0pID0+IHtcbiAgICAgIGlmIChkb21fZGVmYXVsdC5pc1VwbG9hZElucHV0KGlucHV0RWwpICYmIGRvbV9kZWZhdWx0LmlzQXV0b1VwbG9hZChpbnB1dEVsKSkge1xuICAgICAgICBFbGVtZW50UmVmLm9uVW5sb2NrKGlucHV0RWwsICgpID0+IHtcbiAgICAgICAgICBpZiAoTGl2ZVVwbG9hZGVyLmZpbGVzQXdhaXRpbmdQcmVmbGlnaHQoaW5wdXRFbCkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgW3JlZiwgX2Vsc10gPSByZWZHZW5lcmF0b3IoKTtcbiAgICAgICAgICAgI
1HRoaXMudW5kb1JlZnMocmVmLCBwaHhFdmVudCwgW2lucHV0RWwuZm9ybV0pO1xuICAgICAgICAgICAgdGhpcy51cGxvYWRGaWxlcyhcbiAgICAgICAgICAgICAgaW5wdXRFbC5mb3JtLFxuICAgICAgICAgICAgICBwaHhFdmVudCxcbiAgICAgICAgICAgICAgdGFyZ2V0Q3R4LFxuICAgICAgICAgICAgICByZWYsXG4gICAgICAgICAgICAgIGNpZCxcbiAgICAgICAgICAgICAgKF91cGxvYWRzKSA9PiB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2socmVzcCk7XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyQXdhaXRpbmdTdWJtaXQoaW5wdXRFbC5mb3JtLCBwaHhFdmVudCk7XG4gICAgICAgICAgICAgICAgdGhpcy51bmRvUmVmcyhyZWYsIHBoeEV2ZW50KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2socmVzcCk7XG4gICAgICB9XG4gICAgfSkuY2F0Y2goKGVycm9yKSA9PiBsb2dFcnJvcihcIkZhaWxlZCB0byBwdXNoIGlucHV0IGV2ZW50XCIsIGVycm9yKSk7XG4gIH1cbiAgdHJpZ2dlckF3YWl0aW5nU3VibWl0KGZvcm1FbCwgcGh4RXZlbnQpIHtcbiAgICBjb25zdCBhd2FpdGluZ1N1Ym1pdCA9IHRoaXMuZ2V0U2NoZWR1bGVkU3VibWl0KGZvcm1FbCk7XG4gICAgaWYgKGF3YWl0aW5nU3VibWl0KSB7XG4gICAgICBjb25zdCBbX2VsLCBfcmVmLCBfb3B0cywgY2FsbGJhY2tdID0gYXdhaXRpbmdTdWJtaXQ7XG4gICAgICB0aGlzLmNhbmNlbFN1Ym1pdChmb3JtRWwsIHBoeEV2ZW50KTtcbiAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuICB9XG4gIGdldFNjaGVkdWxlZFN1Ym1pdChmb3JtRWwpIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtU3VibWl0cy5maW5kKFxuICAgICAgKFtlbCwgX3JlZiwgX29wdHMsIF9jYWxsYmFja10pID0+IGVsLmlzU2FtZU5vZGUoZm9ybUVsKVxuICAgICk7XG4gIH1cbiAgc2NoZWR1bGVTdWJtaXQoZm9ybUVsLCByZWYsIG9wdHMsIGNhbGxiYWNrKSB7XG4gICAgaWYgKHRoaXMuZ2V0U2NoZWR1bGVkU3VibWl0KGZvcm1FbCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICB0aGlzLmZvcm1TdWJtaXRzLnB1c2goW2Zvcm1FbCwgcmVmLCBvcHRzLCBjYWxsYmFja10pO1xuICB9XG4gIGNhbmNlbFN1Ym1pdChmb3JtRWwsIHBoeEV2ZW50KSB7XG4gICAgdGhpcy5mb3JtU3VibWl0cyA9IHRoaXMuZm9ybVN1Ym1pdHMuZmlsdGVyKFxuICAgICAgKFtlbCwgcmVmLCBfb3B0cywgX2NhbGxiYWNrXSkgPT4ge1xuICAgICAgICBpZiAoZWwuaXNTYW1lTm9kZShmb3JtRWwpKSB7XG4gICAgICAgICAgdGhpcy51bmRvUmVmcyhyZWYsIHBoeEV2ZW50KTtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuICB9XG4gIGRpc2FibGVGb3JtKGZvcm1FbCwgcGh4RXZlbnQsIG9wdHMgPSB7fSkge1xuICAgIGNvbnN0IGZpbHRlcklnbm9yZWQgPSAoZWwpID0+IHtcbiAgICAgIGNvbnN0IHVzZXJJZ25vcmVkID0gY2xvc2VzdFBoeEJpbmRpbmcoXG4gICAgICAgIGVsLFxuICAgICAgICBgJHt0aGlzLmJpbmRpbmcoUEhYX1VQREFURSl9PWlnbm9yZWAsXG4gICAgICAgIGVsLmZvcm1cbiAgICAgICk7XG4gICAgICByZXR1cm4gISh1c2VySWdub3JlZCB8fCBjbG9zZXN0UGh4QmluZGluZyhlbCwgXCJkYXRhLXBoeC11cGRhdGU9aWdub3JlXCIsIGVsLmZvcm0pKTtcbiAgICB9O1xuICAgIGNvbnN0IGZpbHRlckRpc2FibGVzID0gKGVsKSA9PiB7XG4gICAgICByZXR1cm4gZWwuaGFzQXR0cmlidXRlKHRoaXMuYmluZGluZyhQSFhfRElTQUJMRV9XSVRIKSk7XG4gICAgfTtcbiAgICBjb25zdCBmaWx0ZXJCdXR0b24gPSAoZWwpID0+IGVsLnRhZ05hbWUgPT0gXCJCVVRUT05cIjtcbiAgICBjb25zdCBmaWx0ZXJJbnB1dCA9IChlbCkgPT4gW1wiSU5QVVRcIiwgXCJURVhUQVJFQVwiXS5pbmNsdWRlcyhlbC50YWdOYW1lKTtcbiAgICBjb25zdCBmb3JtRWxlbWVudHMgPSBBcnJheS5mcm9tKGZvcm1FbC5lbGVtZW50cyk7XG4gICAgY29uc3QgZGlzYWJsZXMgPSBmb3JtRWxlbWVudHMuZmlsdGVyKGZpbHRlckRpc2FibGVzKTtcbiAgICBjb25zdCBidXR0b25zID0gZm9ybUVsZW1lbnRzLmZpbHRlcihmaWx0ZXJCdXR0b24pLmZpbHRlcihmaWx0ZXJJZ25vcmVkKTtcbiAgICBjb25zdCBpbnB1dHMgPSBmb3JtRWxlbWVudHMuZmlsdGVyKGZpbHRlcklucHV0KS5maWx0ZXIoZmlsdGVySWdub3JlZCk7XG4gICAgYnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IHtcbiAgICAgIGJ1dHRvbi5zZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVELCBidXR0b24uZGlzYWJsZWQudG9TdHJpbmcoKSk7XG4gICAgICBidXR0b24uZGlzYWJsZWQgPSB0cnVlO1xuICAgIH0pO1xuICAgIGlucHV0cy5mb3JFYWNoKChpbnB1dCkgPT4ge1xuICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKFBIWF9SRUFET05MWSwgaW5wdXQucmVhZE9ubHkudG9TdHJpbmcoKSk7XG4gICAgICBpbnB1dC5yZWFkT25seSA9IHRydWU7XG4gICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50ICYmIGlucHV0LmZpbGVzKSB7XG4gICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZShQSFhfRElTQUJMRUQsIGlucHV0LmRpc2FibGVkLnRvU3RyaW5nKCkpO1xuICAgICAgICBpbnB1dC5kaXNhYmxlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgZm9ybUVscyA9IGRpc2FibGVzLmNvbmNhdChidXR0b25zKS5jb25jYXQoaW5wdXRzKS5tYXAoKGVsKSA9PiB7XG4gICAgICByZXR1cm4geyBlbCwgbG9hZGluZzogdHJ1ZSwgbG9jazogdHJ1ZSB9O1xuICAgIH0pO1xuICAgIGNvbnN0IGVscyA9IFtcbiAgICAgIHsgZWw6IGZvcm1FbCwgbG9hZGluZzogdHJ1ZSwgbG9jazogZmFsc2UgfSxcbiAgICAgIC4uLmZvcm1FbHNcbiAgICBdLnJldmVyc2UoKTtcbiAgICByZXR1cm4gdGhpcy5wdXRSZWYoZWxzLCBwaHhFdmVudCwgXCJzdWJtaXRcIiwgb3B0cyk7XG4gIH1cbiAgcHVzaEZvcm1TdWJtaXQoZm9ybUVsLCB0YXJnZXRDdHgsIHBoeEV2ZW50LCBzdWJtaXR0ZXIsIG9wdHMsIG9uUmVwbHkpIHtcbiAgICBjb25zdCByZWZHZW5lcmF0b3IgPSAobWF5YmVQYXlsb2FkKSA9PiB0aGlzLmRpc2FibGVGb3JtKGZvcm1FbCwgcGh4RXZlbnQsIHtcbiAgICAgIC4uLm9wdHMsXG4gICAgICBmb3JtOiBmb3JtRWwsXG4gICAgICBwYXlsb2FkOiBtYXliZVBheWxvYWQ/LnBheWxvYWQsXG4gICAgICBzdWJtaXR0ZXJcbiAgICB9KTtcbiAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKGZvcm1FbCwgXCJzdWJtaXR0ZXJcIiwgc3VibWl0dGVyKTtcbiAgICBjb25zdCBjaWQgPSB0aGlzLnRhcmdldENvbXBvbmVudElEKGZvcm1FbCwgdGFyZ2V0Q3R4KTtcbiAgICBpZiAoTGl2ZVVwbG9hZGVyLmhhc1VwbG9hZHNJblByb2dyZXNzKGZvcm1FbCkpIHtcbiAgICAgIGNvbnN0IFtyZWYsIF9lbHNdID0gcmVmR2VuZXJhdG9yKCk7XG4gICAgICBjb25zdCBwdXNoID0gKCkgPT4gdGhpcy5wdXNoRm9ybVN1Ym1pdChcbiAgICAgICAgZm9ybUVsLFxuICAgICAgICB0YXJnZXRDdHgsXG4gICAgICAgI
1HBoeEV2ZW50LFxuICAgICAgICBzdWJtaXR0ZXIsXG4gICAgICAgIG9wdHMsXG4gICAgICAgIG9uUmVwbHlcbiAgICAgICk7XG4gICAgICByZXR1cm4gdGhpcy5zY2hlZHVsZVN1Ym1pdChmb3JtRWwsIHJlZiwgb3B0cywgcHVzaCk7XG4gICAgfSBlbHNlIGlmIChMaXZlVXBsb2FkZXIuaW5wdXRzQXdhaXRpbmdQcmVmbGlnaHQoZm9ybUVsKS5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBbcmVmLCBlbHNdID0gcmVmR2VuZXJhdG9yKCk7XG4gICAgICBjb25zdCBwcm94eVJlZkdlbiA9ICgpID0+IFtyZWYsIGVscywgb3B0c107XG4gICAgICB0aGlzLnVwbG9hZEZpbGVzKGZvcm1FbCwgcGh4RXZlbnQsIHRhcmdldEN0eCwgcmVmLCBjaWQsIChfdXBsb2FkcykgPT4ge1xuICAgICAgICBpZiAoTGl2ZVVwbG9hZGVyLmlucHV0c0F3YWl0aW5nUHJlZmxpZ2h0KGZvcm1FbCkubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnVuZG9SZWZzKHJlZiwgcGh4RXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLmV4dHJhY3RNZXRhKGZvcm1FbCwge30sIG9wdHMudmFsdWUpO1xuICAgICAgICBjb25zdCBmb3JtRGF0YSA9IHRoaXMuc2VyaWFsaXplRm9ybShmb3JtRWwsIHsgc3VibWl0dGVyIH0pO1xuICAgICAgICB0aGlzLnB1c2hXaXRoUmVwbHkocHJveHlSZWZHZW4sIFwiZXZlbnRcIiwge1xuICAgICAgICAgIHR5cGU6IFwiZm9ybVwiLFxuICAgICAgICAgIGV2ZW50OiBwaHhFdmVudCxcbiAgICAgICAgICB2YWx1ZTogZm9ybURhdGEsXG4gICAgICAgICAgbWV0YSxcbiAgICAgICAgICBjaWRcbiAgICAgICAgfSkudGhlbigoeyByZXNwIH0pID0+IG9uUmVwbHkocmVzcCkpLmNhdGNoKChlcnJvcikgPT4gbG9nRXJyb3IoXCJGYWlsZWQgdG8gcHVzaCBmb3JtIHN1Ym1pdFwiLCBlcnJvcikpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICghKGZvcm1FbC5oYXNBdHRyaWJ1dGUoUEhYX1JFRl9TUkMpICYmIGZvcm1FbC5jbGFzc0xpc3QuY29udGFpbnMoXCJwaHgtc3VibWl0LWxvYWRpbmdcIikpKSB7XG4gICAgICBjb25zdCBtZXRhID0gdGhpcy5leHRyYWN0TWV0YShmb3JtRWwsIHt9LCBvcHRzLnZhbHVlKTtcbiAgICAgIGNvbnN0IGZvcm1EYXRhID0gdGhpcy5zZXJpYWxpemVGb3JtKGZvcm1FbCwgeyBzdWJtaXR0ZXIgfSk7XG4gICAgICB0aGlzLnB1c2hXaXRoUmVwbHkocmVmR2VuZXJhdG9yLCBcImV2ZW50XCIsIHtcbiAgICAgICAgdHlwZTogXCJmb3JtXCIsXG4gICAgICAgIGV2ZW50OiBwaHhFdmVudCxcbiAgICAgICAgdmFsdWU6IGZvcm1EYXRhLFxuICAgICAgICBtZXRhLFxuICAgICAgICBjaWRcbiAgICAgIH0pLnRoZW4oKHsgcmVzcCB9KSA9PiBvblJlcGx5KHJlc3ApKS5jYXRjaCgoZXJyb3IpID0+IGxvZ0Vycm9yKFwiRmFpbGVkIHRvIHB1c2ggZm9ybSBzdWJtaXRcIiwgZXJyb3IpKTtcbiAgICB9XG4gIH1cbiAgdXBsb2FkRmlsZXMoZm9ybUVsLCBwaHhFdmVudCwgdGFyZ2V0Q3R4LCByZWYsIGNpZCwgb25Db21wbGV0ZSkge1xuICAgIGNvbnN0IGpvaW5Db3VudEF0VXBsb2FkID0gdGhpcy5qb2luQ291bnQ7XG4gICAgY29uc3QgaW5wdXRFbHMgPSBMaXZlVXBsb2FkZXIuYWN0aXZlRmlsZUlucHV0cyhmb3JtRWwpO1xuICAgIGxldCBudW1GaWxlSW5wdXRzSW5Qcm9ncmVzcyA9IGlucHV0RWxzLmxlbmd0aDtcbiAgICBpbnB1dEVscy5mb3JFYWNoKChpbnB1dEVsKSA9PiB7XG4gICAgICBjb25zdCB1cGxvYWRlciA9IG5ldyBMaXZlVXBsb2FkZXIoaW5wdXRFbCwgdGhpcywgKCkgPT4ge1xuICAgICAgICBudW1GaWxlSW5wdXRzSW5Qcm9ncmVzcy0tO1xuICAgICAgICBpZiAobnVtRmlsZUlucHV0c0luUHJvZ3Jlc3MgPT09IDApIHtcbiAgICAgICAgICBvbkNvbXBsZXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgY29uc3QgZW50cmllcyA9IHVwbG9hZGVyLmVudHJpZXMoKS5tYXAoKGVudHJ5KSA9PiBlbnRyeS50b1ByZWZsaWdodFBheWxvYWQoKSk7XG4gICAgICBpZiAoZW50cmllcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgbnVtRmlsZUlucHV0c0luUHJvZ3Jlc3MtLTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgcmVmOiBpbnB1dEVsLmdldEF0dHJpYnV0ZShQSFhfVVBMT0FEX1JFRiksXG4gICAgICAgIGVudHJpZXMsXG4gICAgICAgIGNpZDogdGhpcy50YXJnZXRDb21wb25lbnRJRChpbnB1dEVsLmZvcm0sIHRhcmdldEN0eClcbiAgICAgIH07XG4gICAgICB0aGlzLmxvZyhcInVwbG9hZFwiLCAoKSA9PiBbXCJzZW5kaW5nIHByZWZsaWdodCByZXF1ZXN0XCIsIH
1BheWxvYWRdKTtcbiAgICAgIHRoaXMucHVzaFdpdGhSZXBseShudWxsLCBcImFsbG93X3VwbG9hZFwiLCBwYXlsb2FkKS50aGVuKCh7IHJlc3AgfSkgPT4ge1xuICAgICAgICB0aGlzLmxvZyhcInVwbG9hZFwiLCAoKSA9PiBbXCJnb3QgcHJlZmxpZ2h0IHJlc3BvbnNlXCIsIHJlc3BdKTtcbiAgICAgICAgdXBsb2FkZXIuZW50cmllcygpLmZvckVhY2goKGVudHJ5KSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3AuZW50cmllcyAmJiAhcmVzcC5lbnRyaWVzW2VudHJ5LnJlZl0pIHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRmFpbGVkRW50cnlQcmVmbGlnaHQoXG4gICAgICAgICAgICAgIGVudHJ5LnJlZixcbiAgICAgICAgICAgICAgXCJmYWlsZWQgcHJlZmxpZ2h0XCIsXG4gICAgICAgICAgICAgIHVwbG9hZGVyXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXNwLmVycm9yIHx8IE9iamVjdC5rZXlzKHJlc3AuZW50cmllcykubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhpcy51bmRvUmVmcyhyZWYsIHBoeEV2ZW50KTtcbiAgICAgICAgICBjb25zdCBlcnJvcnMgPSByZXNwLmVycm9yIHx8IFtdO1xuICAgICAgICAgIGVycm9ycy5tYXAoKFtlbnRyeV9yZWYsIHJlYXNvbl0pID0+IHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRmFpbGVkRW50cnlQcmVmbGlnaHQoZW50cnlfcmVmLCByZWFzb24sIHVwbG9hZGVyKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBvbkVycm9yID0gKGNhbGxiYWNrKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNoYW5uZWwub25FcnJvcigoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLmpvaW5Db3VudCA9PT0gam9pbkNvdW50QXRVcGxvYWQpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9O1xuICAgICAgICAgIHVwbG9hZGVyLmluaXRBZGFwdGVyVXBsb2FkKHJlc3AsIG9uRXJyb3IsIHRoaXMubGl2ZVNvY2tldCk7XG4gICAgICAgIH1cbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4gbG9nRXJyb3IoXCJGYWlsZWQgdG8gcHVzaCB1cGxvYWRcIiwgZXJyb3IpKTtcbiAgICB9KTtcbiAgfVxuICBoYW5kbGVGYWlsZWRFbnRyeVByZWZsaWdodCh1cGxvYWRSZWYsIHJlYXNvbiwgdXBsb2FkZXIpIHtcbiAgICBpZiAodXBsb2FkZXIuaXNBdXRvVXBsb2FkKCkpIHtcbiAgICAgIGNvbnN0IGVudHJ5ID0gdXBsb2FkZXIuZW50cmllcygpLmZpbmQoKGVudHJ5MikgPT4gZW50cnkyLnJlZiA9PT0gdXBsb2FkUmVmLnRvU3RyaW5nKCkpO1xuICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgIGVudHJ5LmNhbmNlbCgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB1cGxvYWRlci5lbnRyaWVzKCkubWFwKChlbnRyeSkgPT4gZW50cnkuY2FuY2VsKCkpO1xuICAgIH1cbiAgICB0aGlzLmxvZyhcInVwbG9hZFwiLCAoKSA9PiBbYGVycm9yIGZvciBlbnRyeSAke3VwbG9hZFJlZn1gLCByZWFzb25dKTtcbiAgfVxuICBkaXNwYXRjaFVwbG9hZHModGFyZ2V0Q3R4LCBuYW1lLCBmaWxlc09yQmxvYnMpIHtcbiAgICBjb25zdCB0YXJnZXRFbGVtZW50ID0gdGhpcy50YXJnZXRDdHhFbGVtZW50KHRhcmdldEN0eCkgfHwgdGhpcy5lbDtcbiAgICBjb25zdCBpbnB1dHMgPSBkb21fZGVmYXVsdC5maW5kVXBsb2FkSW5wdXRzKHRhcmdldEVsZW1lbnQpLmZpbHRlcihcbiAgICAgIChlbCkgPT4gZWwubmFtZSA9PT0gbmFtZVxuICAgICk7XG4gICAgaWYgKGlucHV0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGxvZ0Vycm9yKGBubyBsaXZlIGZpbGUgaW5wdXRzIGZvdW5kIG1hdGNoaW5nIHRoZSBuYW1lIFwiJHtuYW1lfVwiYCk7XG4gICAgfSBlbHNlIGlmIChpbnB1dHMubGVuZ3RoID4gMSkge1xuICAgICAgbG9nRXJyb3IoYGR1cGxpY2F0ZSBsaXZlIGZpbGUgaW5wdXRzIGZvdW5kIG1hdGNoaW5nIHRoZSBuYW1lIFwiJHtuYW1lfVwiYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRvbV9kZWZhdWx0LmRpc3BhdGNoRXZlbnQoaW5wdXRzWzBdLCBQSFhfVFJBQ0tfVVBMT0FEUywge1xuICAgICAgICBkZXRhaWw6IHsgZmlsZXM6IGZpbGVzT3JCbG9icyB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgdGFyZ2V0Q3R4RWxlbWVudCh0YXJnZXRDdHgpIHtcbiAgICBpZiAoaXNDaWQodGFyZ2V0Q3R4KSkge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZG9tX2RlZmF1bHQuZmluZENvbXBvbmVudCh0aGlzLmlkLCB0YXJnZXRDdHgpO1xuICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9IGVsc2UgaWYgKHRhcmdldEN0eCkge1xuICAgICAgcmV0dXJuIHRhcmdldEN0eDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG4gIHB1c2hGb3JtUmVjb3Zlcnkob2xkRm9ybSwgbmV3Rm9ybSwgdGVtcGxhdGVEb20sIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgcGh4Q2hhbmdlID0gdGhpcy5iaW5kaW5nKFwiY2hhbmdlXCIpO1xuICAgIGNvbnN0IHBoeFRhcmdldCA9IG5ld0Zvcm0uZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhcInRhcmdldFwiKSkgfHwgbmV3Rm9ybTtcbiAgICBjb25zdCBwaHhFdmVudCA9IG5ld0Zvcm0uZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhQSFhfQVVUT19SRUNPVkVSKSkgfHwgbmV3Rm9ybS5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwiY2hhbmdlXCIpKTtcbiAgICBjb25zdCBpbnB1dHMgPSBBcnJheS5mcm9tKG9sZEZvcm0uZWxlbWVudHMpLmZpbHRlcihcbiAgICAgIChlbCkgPT4gZG9tX2RlZmF1bHQuaXNGb3JtQXNzb2NpYXRlZChlbCkgJiYgZWwubmFtZSAmJiAhZWwuaGFzQXR0cmlidXRlKHBoeENoYW5nZSlcbiAgICApO1xuICAgIGlmIChpbnB1dHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBjYWxsYmFjaygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpbnB1dHMuZm9yRWFjaChcbiAgICAgIChpbnB1dDIpID0+IGlucHV0Mi5oYXNBdHRyaWJ1dGUoUEhYX1VQTE9BRF9SRUYpICYmIExpdmVVcGxvYWRlci5jbGVhckZpbGVzKGlucHV0MilcbiAgICApO
11xuICAgIGNvbnN0IGlucHV0ID0gaW5wdXRzLmZpbmQoKGVsKSA9PiBlbC50eXBlICE9PSBcImhpZGRlblwiKSB8fCBpbnB1dHNbMF07XG4gICAgbGV0IHBlbmRpbmcgPSAwO1xuICAgIHRoaXMud2l0aGluVGFyZ2V0cyhcbiAgICAgIHBoeFRhcmdldCxcbiAgICAgICh0YXJnZXRWaWV3LCB0YXJnZXRDdHgpID0+IHtcbiAgICAgICAgY29uc3QgY2lkID0gdGhpcy50YXJnZXRDb21wb25lbnRJRChuZXdGb3JtLCB0YXJnZXRDdHgpO1xuICAgICAgICBwZW5kaW5nKys7XG4gICAgICAgIGxldCBlID0gbmV3IEN1c3RvbUV2ZW50KFwicGh4OmZvcm0tcmVjb3ZlcnlcIiwge1xuICAgICAgICAgIGRldGFpbDogeyBzb3VyY2VFbGVtZW50OiBvbGRGb3JtIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCBcImNoYW5nZVwiLCBwaHhFdmVudCwgdGhpcywgaW5wdXQsIFtcbiAgICAgICAgICBcInB1c2hcIixcbiAgICAgICAgICB7XG4gICAgICAgICAgICBfdGFyZ2V0OiBpbnB1dC5uYW1lLFxuICAgICAgICAgICAgdGFyZ2V0VmlldyxcbiAgICAgICAgICAgIHRhcmdldEN0eCxcbiAgICAgICAgICAgIG5ld0NpZDogY2lkLFxuICAgICAgICAgICAgY2FsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgICAgICAgcGVuZGluZy0tO1xuICAgICAgICAgICAgICBpZiAocGVuZGluZyA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIF0pO1xuICAgICAgfSxcbiAgICAgIHRlbXBsYXRlRG9tXG4gICAgKTtcbiAgfVxuICBwdXNoTGlua1BhdGNoKGUsIGhyZWYsIHRhcmdldEVsLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IGxpbmtSZWYgPSB0aGlzLmxpdmVTb2NrZXQuc2V0UGVuZGluZ0xpbmsoaHJlZik7XG4gICAgY29uc3QgbG9hZGluZyA9IGUuaXNUcnVzdGVkICYmIGUudHlwZSAhPT0gXCJwb3BzdGF0ZVwiO1xuICAgIGNvbnN0IHJlZkdlbiA9IHRhcmdldEVsID8gKCkgPT4gdGhpcy5wdXRSZWYoXG4gICAgICBbeyBlbDogdGFyZ2V0RWwsIGxvYWRpbmcsIGxvY2s6IHRydWUgfV0sXG4gICAgICBudWxsLFxuICAgICAgXCJjbGlja1wiXG4gICAgKSA6IG51bGw7XG4gICAgY29uc3QgZmFsbGJhY2sgPSAoKSA9PiB0aGlzLmxpdmVTb2NrZXQucmVkaXJlY3Qod2luZG93LmxvY2F0aW9uLmhyZWYsIG51bGwsIG51bGwpO1xuICAgIGNvbnN0IHVybCA9IGhyZWYuc3RhcnRzV2l0aChcIi9cIikgPyBgJHtsb2NhdGlvbi5wcm90b2NvbH0vLyR7bG9jYXRpb24uaG9zdH0ke2hyZWZ9YCA6IGhyZWY7XG4gICAgdGhpcy5wdXNoV2l0aFJlcGx5KHJlZkdlbiwgXCJsaXZlX3BhdGNoXCIsIHsgdXJsIH0pLnRoZW4oXG4gICAgICAoeyByZXNwIH0pID0+IHtcbiAgICAgICAgdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwLmxpbmtfcmVkaXJlY3QpIHtcbiAgICAgICAgICAgIHRoaXMubGl2ZVNvY2tldC5yZXBsYWNlTWFpbihocmVmLCBudWxsLCBjYWxsYmFjaywgbGlua1JlZik7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwLnJlZGlyZWN0KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxpdmVTb2NrZXQuY29tbWl0UGVuZGluZ0xpbmsobGlua1JlZikpIHtcbiAgICAgICAgICAgICAgdGhpcy5ocmVmID0gaHJlZjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuYXBwbHlQZW5kaW5nVXBkYXRlcygpO1xuICAgICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2sobGlua1JlZik7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICAoeyBlcnJvcjogX2Vycm9yLCB0aW1lb3V0OiBfdGltZW91dCB9KSA9PiBmYWxsYmFjaygpXG4gICAgKTtcbiAgfVxuICBnZXRGb3Jtc0ZvclJlY292ZXJ5KCkge1xuICAgIGlmICh0aGlzLmpvaW5Db3VudCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjb25zdCBwaHhDaGFuZ2UgPSB0aGlzLmJpbmRpbmcoXCJjaGFuZ2VcIik7XG4gICAgcmV0dXJuIGRvbV9kZWZhdWx0LmFsbChcbiAgICAgIGRvY3VtZW50LFxuICAgICAgYCMke0NTUy5lc2NhcGUodGhpcy5pZCl9IGZvcm1bJHtwaHhDaGFuZ2V9XSwgWyR7UEhYX1RFTEVQT1JURURfUkVGfT1cIiR7Q1NTLmVzY2FwZSh0aGlzLmlkKX1cIl0gZm9ybVske3BoeENoYW5nZX1dYFxuICAgICkuZmlsdGVyKChmb3JtKSA9PiBmb3JtIGluc3RhbmNlb2YgSFRNTEZvcm1FbGVtZW50KS5maWx0ZXIoKGZvcm0p
1ID0+IGZvcm0uaWQpLmZpbHRlcigoZm9ybSkgPT4gZm9ybS5lbGVtZW50cy5sZW5ndGggPiAwKS5maWx0ZXIoXG4gICAgICAoZm9ybSkgPT4gZm9ybS5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9BVVRPX1JFQ09WRVIpKSAhPT0gXCJpZ25vcmVcIlxuICAgICkubWFwKChmb3JtKSA9PiB7XG4gICAgICBjb25zdCBjbG9uZWRGb3JtID0gZm9ybS5jbG9uZU5vZGUodHJ1ZSk7XG4gICAgICBtb3JwaGRvbV9lc21fZGVmYXVsdChjbG9uZWRGb3JtLCBmb3JtLCB7XG4gICAgICAgIG9uQmVmb3JlRWxVcGRhdGVkOiAoZnJvbUVsLCB0b0VsKSA9PiB7XG4gICAgICAgICAgZG9tX2RlZmF1bHQuY29weVByaXZhdGVzKGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgaWYgKGZyb21FbC5nZXRBdHRyaWJ1dGUoXCJmb3JtXCIpID09PSBmb3JtLmlkICYmIGZyb21FbC5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgICBmcm9tRWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChmcm9tRWwpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBleHRlcm5hbEVsZW1lbnRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgYFtmb3JtPVwiJHtDU1MuZXNjYXBlKGZvcm0uaWQpfVwiXWBcbiAgICAgICk7XG4gICAgICBBcnJheS5mcm9tKGV4dGVybmFsRWxlbWVudHMpLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICAgIGNvbnN0IGNsb25lZEVsID0gZWwuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgICBtb3JwaGRvbV9lc21fZGVmYXVsdChjbG9uZWRFbCwgZWwpO1xuICAgICAgICBkb21fZGVmYXVsdC5jb3B5UHJpdmF0ZXMoY2xvbmVkRWwsIGVsKTtcbiAgICAgICAgY2xvbmVkRWwucmVtb3ZlQXR0cmlidXRlKFwiZm9ybVwiKTtcbiAgICAgICAgY2xvbmVkRm9ybS5hcHBlbmRDaGlsZChjbG9uZWRFbCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBjbG9uZWRGb3JtO1xuICAgIH0pLnJlZHVjZSgoYWNjLCBmb3JtKSA9PiB7XG4gICAgICBhY2NbZm9ybS5pZF0gPSBmb3JtO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG4gIH1cbiAgbWF5YmVQdXNoQ29tcG9uZW50c0Rlc3Ryb3llZChkZXN0cm95ZWRDSURzKSB7XG4gICAgbGV0IHdpbGxEZXN0cm95Q0lEcyA9IGRlc3Ryb3llZENJRHMuZmlsdGVyKChjaWQpID0+IHtcbiAgICAgIHJldHVybiBkb21fZGVmYXVsdC5maW5kQ29tcG9uZW50KHRoaXMuaWQsIGNpZCkgPT09IG51bGw7XG4gICAgfSk7XG4gICAgY29uc3Qgb25FcnJvciA9IChlcnJvcikgPT4ge1xuICAgICAgaWYgKCF0aGlzLmlzRGVzdHJveWVkKCkpIHtcbiAgICAgICAgbG9nRXJyb3IoXCJGYWlsZWQgdG8gcHVzaCBjb21wb25lbnRzIGRlc3Ryb3llZFwiLCBlcnJvcik7XG4gICAgICB9XG4gICAgfTtcbiAgICBpZiAod2lsbERlc3Ryb3lDSURzLmxlbmd0aCA+IDApIHtcbiAgICAgIHdpbGxEZXN0cm95Q0lEcy5mb3JFYWNoKChjaWQpID0+IHRoaXMucmVuZGVyZWQucmVzZXRSZW5kZXIoY2lkKSk7XG4gICAgICB0aGlzLnB1c2hXaXRoUmVwbHkobnVsbCwgXCJjaWRzX3dpbGxfZGVzdHJveVwiLCB7IGNpZHM6IHdpbGxEZXN0cm95Q0lEcyB9KS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICAgIGxldCBjb21wbGV0ZWx5RGVzdHJveUNJRHMgPSB3aWxsRGVzdHJveUNJRHMuZmlsdGVyKChjaWQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBkb21fZGVmYXVsdC5maW5kQ29tcG9uZW50KHRoaXMuaWQsIGNpZCkgPT09IG51bGw7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKGNvbXBsZXRlbHlEZXN0cm95Q0lEcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLnB1c2hXaXRoUmVwbHkobnVsbCwgXCJjaWRzX2Rlc3Ryb3llZFwiLCB7XG4gICAgICAgICAgICAgIGNpZHM6IGNvbXBsZXRlbHlEZXN0cm95Q0lEc1xuICAgICAgICAgICAgfSkudGhlbigoeyByZXNwIH0pID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlZC5wcnVuZUNJRHMocmVzcC5jaWRzKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKG9uRXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KS5jYXRjaChvbkVycm9yKTtcbiAgICB9XG4gIH1cbiAgb3duc0VsZW1lbnQoZWwpIHtcbiAgICBsZXQgcGFyZW50Vmlld0VsID0gZG9tX2RlZmF1bHQuY2xvc2VzdFZpZXdFbChlbCk7XG4gICAgcmV0dXJuIGVsLmdldEF0dHJpYnV0ZShQSFhfUEFSRU5UX0lEKSA9PT0gdGhpcy5pZCB8fCBwYXJlbnRWaWV3RWwgJiYgcGFyZW50Vmlld0VsLmlkID09PSB0aGlzLmlkIHx8ICFwYXJlbnRWaWV3RWwgJiYgdGhpcy5pc0RlYWQ7XG4gIH1cbiAgc3VibWl0Rm9ybShmb3JtLCB0YXJnZXRDdHgsIHBoeEV2ZW50LCBzdWJtaXR0ZXIsIG9wdHMgPSB7fSkge1xuICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUoZm9ybSwgUEhYX0hBU19TVUJNSVRURUQsIHRydWUpO1xuICAgIGNvbnN0IGlucHV0cyA9IEFycmF5LmZyb20oZm9ybS5lbGVtZW50cyk7XG4gICAgaW5wdXRzLmZvckVhY2goKGlucHV0KSA9PiBkb21fZGVmYXVsdC5wdXRQcml2YXRlKGlucHV0LCBQSFhfSEFTX1NVQk1JVFRFRCwgdHJ1ZSkpO1xuICAgIHRoaXMubGl2ZVNvY2tldC5ibHVyQWN0aXZlRWxlbWVudCgpO1xuICAgIHRoaXMucHVzaEZvcm1TdWJtaXQoZm9ybSwgdGFyZ2V0Q3R4LCBwaHhFdmVudCwgc3VibWl0dGVyLCBvcHRzLCAoKSA9PiB7XG4gICAgICB0aGlzLmxpdmVTb2NrZXQucmVzdG9yZVByZXZpb3VzbHlBY3RpdmVGb2N1cygpO1xuICAgIH0pO1xuICB9XG4gIGJpbmRpbmcoa2luZCkge1xuICAgIHJldHVybiB0aGlzLmxpdmVTb2NrZXQuYmluZGluZyhraW5kKTtcbiAgfVxuICAvLyBwaHgtcG9ydGFsXG4gIHB1c2hQb3J0YWxFbGVtZW50SWQoaWQpIHtcbiAgICB0aGlzLnBvcnRhbEVsZW1lbnRJZHMuYWRkKGlkKTtcbiAgfVxuICBkcm9wUG9ydGFsRWxlbWVudElkKGlkKSB7XG4gICAgdGhpcy5wb3J0YWxFbGVtZW50SWRzLmRlbGV0ZShpZCk7XG4gIH1cbiAgZGVzdHJveVBvcnRhbEVsZW1lbnRzKCkge1xuICAgIGlmICghdGhpcy5saXZlU29ja2V0LnVubG9hZGVkKSB7XG4gICAgICB0aGlzLnBvcnRhbEVsZW1lbnRJZHMuZm9yRWFjaCgoaWQpID0+IHtcbiAgICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG4gICAgICAgIGlmIChlbCkge1xuICAgICAgICAgIGVsLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gI
1H1cbn07XG5cbi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L2xpdmVfc29ja2V0LnRzXG52YXIgaXNVc2VkSW5wdXQgPSAoZWwpID0+IGRvbV9kZWZhdWx0LmlzVXNlZElucHV0KGVsKTtcbnZhciBMaXZlU29ja2V0ID0gY2xhc3Mge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBMaXZlU29ja2V0IGluc3RhbmNlLlxuICAgKi9cbiAgY29uc3RydWN0b3IodXJsLCBwaHhTb2NrZXQsIG9wdHMgPSB7fSkge1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICB0aGlzLnVubG9hZGVkID0gZmFsc2U7XG4gICAgaWYgKCFwaHhTb2NrZXQgfHwgcGh4U29ja2V0LmNvbnN0cnVjdG9yLm5hbWUgPT09IFwiT2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgXG4gICAgICBhIHBob2VuaXggU29ja2V0IG11c3QgYmUgcHJvdmlkZWQgYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byB0aGUgTGl2ZVNvY2tldCBjb25zdHJ1Y3Rvci4gRm9yIGV4YW1wbGU6XG5cbiAgICAgICAgICBpbXBvcnQge1NvY2tldH0gZnJvbSBcInBob2VuaXhcIlxuICAgICAgICAgIGltcG9ydCB7TGl2ZVNvY2tldH0gZnJvbSBcInBob2VuaXhfbGl2ZV92aWV3XCJcbiAgICAgICAgICBsZXQgbGl2ZVNvY2tldCA9IG5ldyBMaXZlU29ja2V0KFwiL2xpdmVcIiwgU29ja2V0LCB7Li4ufSlcbiAgICAgIGApO1xuICAgIH1cbiAgICB0aGlzLnNvY2tldCA9IG5ldyBwaHhTb2NrZXQodXJsLCBvcHRzKTtcbiAgICB0aGlzLmJpbmRpbmdQcmVmaXggPSBvcHRzLmJpbmRpbmdQcmVmaXggfHwgQklORElOR19QUkVGSVg7XG4gICAgdGhpcy5wYXJhbXMgPSBjbG9zdXJlKG9wdHMucGFyYW1zIHx8IHt9KTtcbiAgICB0aGlzLnZpZXdMb2dnZXIgPSBvcHRzLnZpZXdMb2dnZXI7XG4gICAgdGhpcy5tZXRhZGF0YUNhbGxiYWNrcyA9IG9wdHMubWV0YWRhdGEgfHwge307XG4gICAgdGhpcy5kZWZhdWx0cyA9IE9iamVjdC5hc3NpZ24oY2xvbmUoREVGQVVMVFMpLCBvcHRzLmRlZmF1bHRzIHx8IHt9KTtcbiAgICB0aGlzLnByZXZBY3RpdmUgPSBudWxsO1xuICAgIHRoaXMuc2lsZW5jZWQgPSBmYWxzZTtcbiAgICB0aGlzLm1haW4gPSBudWxsO1xuICAgIHRoaXMub3V0Z29pbmdNYWluRWwgPSBudWxsO1xuICAgIHRoaXMuY2xpY2tTdGFydGVkQXRUYXJnZXQgPSBudWxsO1xuICAgIHRoaXMubGlua1JlZiA9IDE7XG4gICAgdGhpcy5yb290cyA9IHt9O1xuICAgIHRoaXMuaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuICAgIHRoaXMucGVuZGluZ0xpbmsgPSBudWxsO1xuICAgIHRoaXMuY3VycmVudExvY2F0aW9uID0gY2xvbmUod2luZG93LmxvY2F0aW9uKTtcbiAgICB0aGlzLmhvb2tzID0gb3B0cy5ob29rcyB8fCB7fTtcbiAgICB0aGlzLnVwbG9hZGVycyA9IG9wdHMudXBsb2FkZXJzIHx8IHt9O1xuICAgIHRoaXMubG9hZGVyVGltZW91dCA9IG9wdHMubG9hZGVyVGltZW91dCB8fCBMT0FERVJfVElNRU9VVDtcbiAgICB0aGlzLmRpc2Nvbm5lY3RlZFRpbWVvdXQgPSBvcHRzLmRpc2Nvbm5lY3RlZFRpbWVvdXQgfHwgRElTQ09OTkVDVEVEX1RJTUVPVVQ7XG4gICAgdGhpcy5yZWxvYWRXaXRoSml0dGVyVGltZXIgPSBudWxsO1xuICAgIHRoaXMubWF4UmVsb2FkcyA9IG9wdHMubWF4UmVsb2FkcyB8fCBNQVhfUkVMT0FEUztcbiAgICB0aGlzLnJlbG9hZEppdHRlck1pbiA9IG9wdHMucmVsb2FkSml0dGVyTWluIHx8IFJFTE9BRF9KSVRURVJfTUlOO1xuICAgIHRoaXMucmVsb2FkSml0dGVyTWF4ID0gb3B0cy5yZWxvYWRKaXR0ZXJNYXggfHwgUkVMT0FEX0pJVFRFUl9NQVg7XG4gICAgdGhpcy5mYWlsc2FmZUppdHRlciA9IG9wdHMuZmFpbHNhZmVKaXR0ZXIgfHwgRkFJTFNBRkVfSklUVEVSO1xuICAgIHRoaXMubG9jYWxTdG9yYWdlID0gb3B0cy5sb2NhbFN0b3JhZ2UgfHwgd2luZG93LmxvY2FsU3RvcmFnZTtcbiAgICB0aGlzLnNlc3Npb25TdG9yYWdlID0gb3B0cy5zZXNzaW9uU3RvcmFnZSB8fCB3aW5kb3cuc2Vzc2lvblN0b3JhZ2U7XG4gICAgdGhpcy5ib3VuZFRvcExldmVsRXZlbnRzID0gZmFsc2U7XG4gICAgdGhpcy5ib3VuZEV2ZW50TmFtZXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICAgIHRoaXMuYmxvY2tQaHhDaGFuZ2VXaGlsZUNvbXBvc2luZyA9IG9wdHMuYmxvY2tQaHhDaGFuZ2VXaGlsZUNvbXBvc2luZyB8fCBmYWxzZTtcbiAgICB0aGlzLnNlcnZlckNsb3NlUmVmID0gbnVsbDtcbiAgICB0aGlzLmRvbUNhbGxiYWNrcyA9IE9iamVjdC5hc3NpZ24oXG4gICAgICB7XG4gICAgICAgIGpzUXVlcnlTZWxlY3RvckFsbDogbnVsbCxcbiAgICAgICAgb25QYXRjaFN0YXJ0OiBjbG9zdXJlKCksXG4gICAgICAgIG9uUGF0Y2hFbmQ6IGNsb3N1cmUoKSxcbiAgICAgICAgb25Ob2RlQWRkZWQ6IGNsb3N1cmUoKSxcbiAgICAgICAgb25CZWZvcmVFbFVwZGF0ZWQ6IGNsb3N1cmUoKVxuICAgICAgfSxcbiAgICAgIG9wdHMuZG9tIHx8IHt9XG4gICAgKTtcbiAgICB0aGlzLnRyYW5zaXRpb25zID0gbmV3IFRyYW5zaXRpb25TZXQoKTtcbiAgICB0aGlzLmN1cnJlbnRIaXN0b3J5UG9zaXRpb24gPSBwYXJzZUludCh0aGlzLnNlc3Npb25TdG9yYWdlLmdldEl0ZW0oUEhYX0xWX0hJU1RPUllfUE9TSVRJT04pIHx8IFwiMFwiKSB8fCAwO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGFnZWhpZGVcIiwgKF9lKSA9PiB7XG4gICAgICB0aGlzLnVubG9hZGVkID0gdHJ1ZTtcbiAgICB9KTtcbiAgICB0aGlzLnNvY2tldC5vbk9wZW4oKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuaXNVbmxvYWRlZCgpKSB7XG4gICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICAvLyBwdWJsaWNcbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHZlcnNpb24gb2YgdGhlIExpdmVWaWV3IGNsaWVudC5cbiAgICovXG4gIHZlcnNpb24oKSB7XG4gICAgcmV0dXJuIFwiMS4yLjZcIjtcbiAgfVxuICAvKipcbiAgICogUmV0dXJucyB0cnVlIGlmIHByb2ZpbGluZyBpcyBlbmFibGVkLiBTZWUge0BsaW5rIGVuYWJsZVByb2ZpbGluZ30gYW5kIHtAbGluayBkaXNhYmxlUHJvZmlsaW5nfS5cbiAgICovXG4gIGlzUHJvZmlsZUVuYWJsZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShQSFhfTFZfUFJPRklMRSkgPT09IFwidHJ1ZVwiO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRydWUgaWYgZGVidWdnaW5nIGlzIGVuYWJsZWQuIFNlZSB7QGxpbmsgZW5hYmxlRGVidWd9IGFuZCB7QGxpbmsgZGlzYWJsZURlYnVnfS5cbiAgICovXG4gIGlzRGVidWdFbmFibGVkKCkge1xuICAgIHJldHVybi
1B0aGlzLnNlc3Npb25TdG9yYWdlLmdldEl0ZW0oUEhYX0xWX0RFQlVHKSA9PT0gXCJ0cnVlXCI7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiBkZWJ1Z2dpbmcgaXMgZGlzYWJsZWQuIFNlZSB7QGxpbmsgZW5hYmxlRGVidWd9IGFuZCB7QGxpbmsgZGlzYWJsZURlYnVnfS5cbiAgICovXG4gIGlzRGVidWdEaXNhYmxlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uU3RvcmFnZS5nZXRJdGVtKFBIWF9MVl9ERUJVRykgPT09IFwiZmFsc2VcIjtcbiAgfVxuICAvKipcbiAgICogRW5hYmxlcyBkZWJ1Z2dpbmcuXG4gICAqXG4gICAqIFdoZW4gZGVidWdnaW5nIGlzIGVuYWJsZWQsIHRoZSBMaXZlVmlldyBjbGllbnQgd2lsbCBsb2cgZGVidWcgaW5mb3JtYXRpb24gdG8gdGhlIGNvbnNvbGUuXG4gICAqIFNlZSBbRGVidWdnaW5nIGNsaWVudCBldmVudHNdKGh0dHBzOi8vcGhvZW5peC1saXZlLXZpZXcuaGV4ZG9jcy5wbS9qcy1pbnRlcm9wLmh0bWwjZGVidWdnaW5nLWNsaWVudC1ldmVudHMpIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgZW5hYmxlRGVidWcoKSB7XG4gICAgdGhpcy5zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFBIWF9MVl9ERUJVRywgXCJ0cnVlXCIpO1xuICB9XG4gIC8qKlxuICAgKiBFbmFibGVzIHByb2ZpbGluZy5cbiAgICpcbiAgICogV2hlbiBwcm9maWxpbmcgaXMgZW5hYmxlZCwgdGhlIExpdmVWaWV3IGNsaWVudCB3aWxsIGxvZyBwcm9maWxpbmcgaW5mb3JtYXRpb24gdG8gdGhlIGNvbnNvbGUuXG4gICAqL1xuICBlbmFibGVQcm9maWxpbmcoKSB7XG4gICAgdGhpcy5zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFBIWF9MVl9QUk9GSUxFLCBcInRydWVcIik7XG4gIH1cbiAgLyoqXG4gICAqIERpc2FibGVzIGRlYnVnZ2luZy5cbiAgICovXG4gIGRpc2FibGVEZWJ1ZygpIHtcbiAgICB0aGlzLnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oUEhYX0xWX0RFQlVHLCBcImZhbHNlXCIpO1xuICB9XG4gIC8qKlxuICAgKiBEaXNhYmxlcyBwcm9maWxpbmcuXG4gICAqL1xuICBkaXNhYmxlUHJvZmlsaW5nKCkge1xuICAgIHRoaXMuc2Vzc2lvblN0b3JhZ2UucmVtb3ZlSXRlbShQSFhfTFZfUFJPRklMRSk7XG4gIH1cbiAgLyoqXG4gICAqIEVuYWJsZXMgbGF0ZW5jeSBzaW11bGF0aW9uLlxuICAgKlxuICAgKiBXaGVuIGxhdGVuY3kgc2ltdWxhdGlvbiBpcyBlbmFibGVkLCB0aGUgTGl2ZVZpZXcgY2xpZW50IHdpbGwgYWRkIGEgZGVsYXkgdG8gcmVxdWVzdHMgYW5kIHJlc3BvbnNlcyBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAqIFNlZSBbU2ltdWxhdGluZyBMYXRlbmN5XShodHRwczovL3Bob2VuaXgtbGl2ZS12aWV3LmhleGRvY3MucG0vanMtaW50ZXJvcC5odG1sI3NpbXVsYXRpbmctbGF0ZW5jeSkgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAqL1xuICBlbmFibGVMYXRlbmN5U2ltKHVwcGVyQm91bmRNcykge1xuICAgIHRoaXMuZW5hYmxlRGVidWcoKTtcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIFwibGF0ZW5jeSBzaW11bGF0b3IgZW5hYmxlZCBmb3IgdGhlIGR1cmF0aW9uIG9mIHRoaXMgYnJvd3NlciBzZXNzaW9uLiBDYWxsIGRpc2FibGVMYXRlbmN5U2ltKCkgdG8gZGlzYWJsZVwiXG4gICAgKTtcbiAgICB0aGlzLnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oUEhYX0xWX0xBVEVOQ1lfU0lNLCB1cHBlckJvdW5kTXMudG9TdHJpbmcoKSk7XG4gIH1cbiAgLyoqXG4gICAqIERpc2FibGVzIGxhdGVuY3kgc2ltdWxhdGlvbi5cbiAgICovXG4gIGRpc2FibGVMYXRlbmN5U2ltKCkge1xuICAgIHRoaXMuc2Vzc2lvblN0b3JhZ2UucmVtb3ZlSXRlbShQSFhfTFZfTEFURU5DWV9TSU0pO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGxhdGVuY3kgc2ltdWxhdGlvbiB1cHBlciBib3VuZC5cbiAgICovXG4gIGdldExhdGVuY3lTaW0oKSB7XG4gICAgY29uc3Qgc3RyID0gdGhpcy5zZXNzaW9uU3RvcmFnZS5nZXRJdGVtKFBIWF9MVl9MQVRFTkNZX1NJTSk7XG4gICAgcmV0dXJuIHN0ciA/IHBhcnNlSW50KHN0cikgOiBudWxsO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBQaG9lbml4IFNvY2tldCBpbnN0YW5jZS5cbiAgICovXG4gIGdldFNvY2tldCgpIHtcbiAgICByZXR1cm4gdGhpcy5zb2NrZXQ7XG4gIH1cbiAgLyoqXG4gICAqIENvbm5lY3RzIHRvIHRoZSBMaXZlVmlldyBzZXJ2ZXIuXG4gICAqL1xuICBjb25uZWN0KCkge1xuICAgIGlmICh3aW5kb3cubG9jYXRpb24uaG9zdG5hbWUgPT09IFwibG9jYWxob3N0XCIgJiYgIXRoaXMuaXNEZWJ1Z0Rpc2FibGVkKCkpIHtcbiAgICAgIHRoaXMuZW5hYmxlRGVidWcoKTtcbiAgICB9XG4gICAgY29uc3QgZG9Db25uZWN0ID0gKCkgPT4ge1xuICAgICAgdGhpcy5yZXNldFJlbG9hZFN0YXR1cygpO1xuICAgICAgaWYgKHRoaXMuam9pblJvb3RWaWV3cygpKSB7XG4gICAgICAgIHRoaXMuYmluZFRvcExldmVsRXZlbnRzKCk7XG4gICAgICAgIHRoaXMuc29ja2V0LmNvbm5lY3QoKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5tYWluKSB7XG4gICAgICAgIHRoaXMuc29ja2V0LmNvbm5lY3QoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYmluZFRvcExldmVsRXZlbnRzKHsgZGVhZDogdHJ1ZSB9KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuam9pbkRlYWRWaWV3KCk7XG4gICAgfTtcbiAgICBpZiAoW1wiY29tcGxldGVcIiwgXCJsb2FkZWRcIiwgXCJpbnRlcmFjdGl2ZVwiXS5pbmRleE9mKGRvY3VtZW50LnJlYWR5U3RhdGUpID49IDApIHtcbiAgICAgIGRvQ29ubmVjdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkb2
1N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCAoKSA9PiBkb0Nvbm5lY3QoKSk7XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBEaXNjb25uZWN0cyBmcm9tIHRoZSBMaXZlVmlldyBzZXJ2ZXIuXG4gICAqL1xuICBkaXNjb25uZWN0KGNhbGxiYWNrKSB7XG4gICAgdGhpcy5yZWxvYWRXaXRoSml0dGVyVGltZXIgIT0gbnVsbCAmJiBjbGVhclRpbWVvdXQodGhpcy5yZWxvYWRXaXRoSml0dGVyVGltZXIpO1xuICAgIGlmICh0aGlzLnNlcnZlckNsb3NlUmVmKSB7XG4gICAgICB0aGlzLnNvY2tldC5vZmYoW3RoaXMuc2VydmVyQ2xvc2VSZWZdKTtcbiAgICAgIHRoaXMuc2VydmVyQ2xvc2VSZWYgPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLnNvY2tldC5kaXNjb25uZWN0KGNhbGxiYWNrKTtcbiAgfVxuICAvKipcbiAgICogQ2FuIGJlIHVzZWQgdG8gcmVwbGFjZSB0aGUgdHJhbnNwb3J0IHVzZWQgYnkgdGhlIHVuZGVybHlpbmcgUGhvZW5peCBTb2NrZXQuXG4gICAqL1xuICByZXBsYWNlVHJhbnNwb3J0KHRyYW5zcG9ydCkge1xuICAgIHRoaXMucmVsb2FkV2l0aEppdHRlclRpbWVyICE9IG51bGwgJiYgY2xlYXJUaW1lb3V0KHRoaXMucmVsb2FkV2l0aEppdHRlclRpbWVyKTtcbiAgICB0aGlzLnNvY2tldC5yZXBsYWNlVHJhbnNwb3J0KHRyYW5zcG9ydCk7XG4gICAgdGhpcy5jb25uZWN0KCk7XG4gIH1cbiAgLyoqXG4gICAqIEV4ZWN1dGVzIGFuIGVuY29kZWQgSlMgY29tbWFuZCwgdGFyZ2V0aW5nIHRoZSBnaXZlbiBlbGVtZW50LlxuICAgKlxuICAgKiBTZWUgW2BQaG9lbml4LkxpdmVWaWV3LkpTYF0oaHR0cHM6Ly9waG9lbml4LWxpdmUtdmlldy5oZXhkb2NzLnBtL1Bob2VuaXguTGl2ZVZpZXcuSlMuaHRtbCkgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAqL1xuICBleGVjSlMoZWwsIGVuY29kZWRKUywgZXZlbnRUeXBlID0gbnVsbCkge1xuICAgIGNvbnN0IGUgPSBuZXcgQ3VzdG9tRXZlbnQoXCJwaHg6ZXhlY1wiLCB7IGRldGFpbDogeyBzb3VyY2VFbGVtZW50OiBlbCB9IH0pO1xuICAgIHRoaXMub3duZXIoZWwsICh2aWV3KSA9PiBqc19kZWZhdWx0LmV4ZWMoZSwgZXZlbnRUeXBlLCBlbmNvZGVkSlMsIHZpZXcsIGVsKSk7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gb2JqZWN0IHdpdGggbWV0aG9kcyB0byBtYW5pcHVsYXRlIHRoZSBET00gYW5kIGV4ZWN1dGUgSmF2YVNjcmlwdC5cbiAgICogVGhlIGFwcGxpZWQgY2hhbmdlcyBpbnRlZ3JhdGUgd2l0aCBzZXJ2ZXIgRE9NIHBhdGNoaW5nLlxuICAgKlxuICAgKiBTZWUgW0phdmFTY3JpcHQgaW50ZXJvcGVyYWJpbGl0eV0oaHR0cHM6Ly9waG9lbml4LWxpdmUtdmlldy5oZXhkb2NzLnBtL2pzLWludGVyb3AuaHRtbCkgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAqL1xuICBqcygpIHtcbiAgICByZXR1cm4ganNfY29tbWFuZHNfZGVmYXVsdCh0aGlzLCBcImpzXCIpO1xuICB9XG4gIC8vIHByaXZhdGVcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICB1bmxvYWQoKSB7XG4gICAgaWYgKHRoaXMudW5sb2FkZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMubWFpbiAmJiB0aGlzLmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgIHRoaXMubG9nKHRoaXMubWFpbiwgXCJzb2NrZXRcIiwgKCkgPT4gW1wiZGlzY29ubmVjdCBmb3IgcGFnZSBuYXZcIl0pO1xuICAgIH1cbiAgICB0aGlzLnVubG9hZGVkID0gdHJ1ZTtcbiAgICB0aGlzLmRlc3Ryb3lBbGxWaWV3cygpO1xuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgdHJpZ2dlckRPTShraW5kLCBhcmdzKSB7XG4gICAgdGhpcy5kb21DYWxsYmFja3Nba2luZF0oLi4uYXJncyk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICB0aW1lKG5hbWUsIGZ1bmMpIHtcbiAgICBpZiAoIXRoaXMuaXNQcm9maWxlRW5hYmxlZCgpIHx8ICFjb25zb2xlLnRpbWUpIHtcbiAgICAgIHJldHVybiBmdW5jKCk7XG4gICAgfVxuICAgIGNvbnNvbGUudGltZShuYW1lKTtcbiAgICBjb25zdCByZXN1bHQgPSBmdW5jKCk7XG4gICAgY29uc29sZS50aW1lRW5kKG5hbWUpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBsb2codmlldywga2luZCwgbXNnQ2FsbGJhY2spIHtcbiAgICBpZiAodGhpcy52aWV3TG9nZ2VyKSB7XG4gICAgICBjb25zdCBbbXNnLCBvYmpdID0gbXNnQ2FsbGJhY2soKTtcbiAgICAgIHRoaXMudmlld0xvZ2dlcih2aWV3LCBraW5kLCBtc2csIG9iaik7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzRGVidWdFbmFibGVkKCkpIHtcbiAgICAgIGNvbnN0IFttc2csIG9ial0gPSBtc2dDYWxsYmFjaygpO1xuICAgICAgZGVidWcodmlldywga2luZCwgbXNnLCBvYmopO1xuICAgIH1cbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIHJlcXVlc3RET01VcGRhdGUoY2FsbGJhY2spIHtcbiAgICB0aGlzLnRyYW5zaXRpb25zLmFmdGVyKGNhbGxiYWNrKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGFzeW5jVHJhbnNpdGlvbihwcm9taXNlKSB7XG4gICAgdGhpcy50cmFuc2l0aW9ucy5hZGRBc3luY1RyYW5zaXRpb24ocHJvbWlzZSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICB0cmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSA9IGZ1bmN0aW9uKCkge1xuICB9KSB7XG4gICAgdGhpcy50cmFuc2l0aW9ucy5hZGRUcmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBvbkNoYW5uZWwoY2hhbm5lbCwgZXZlbnQsIGNiKSB7XG4gICAgY2hhbm5lbC5vbihldmVudCwgKGRhdGEpID0+IHtcbiAgICAgIGNvbnN0IGxhdGVuY3kgPSB0aGlzLmdldExhdGVuY3lTaW0oKTtcbiAgICAgIGlmICghbGF0ZW5jeSkge1xuICAgICAgICBjYihkYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gY2IoZGF0YSksIGxhdGVuY3kpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcmVsb2FkV2l0aEppdHRlcih2aWV3LCBsb2cpIHtcbiAgICB0aGlzLnJlbG9hZFdpdGhKaXR0ZXJUaW1lciAhPSBudWxsICYmIGNsZWFyVGltZW91dCh0aGlzLnJlbG9hZFdpdGhKaXR0ZXJUaW1lcik7XG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgY29uc3QgbWluTXMgPSB0aGlzLnJlbG9hZEppdHRlck1pbjtcbiAgICBjb25zdCBtYXhNcyA9IHRoaXMucmVsb2FkSml0dGVyTWF4O1xuICAgIGxldCBhZnRlck1zID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogKG1heE1zIC0gbWluTXMgKyAxKSkgKyBtaW5NcztcbiAgICBjb25zdCB0cmllcyA9IGJyb3dzZXJfZGVmYXVsdC51cGRhdGVMb2NhbChcbiAgICAgIHRoaXMubG9jYWxTdG9yYWdlLFxuICAgICAgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLFxuICAgICAgQ09OU0VDVVRJVkVfUkVMT0FEUyxcbiAgICAgIDAsXG4gICAgICAoY291bnQpID0+IGNvdW50ICsgMVxuICAgICk7XG4gICAgaWYgKHRyaWVzID49IHRoaXMubWF4UmVsb2Fkcykge1xuICAgICAgYWZ0ZXJNcyA9IHRoaXMuZmFpbHNhZmVKaXR0ZXI7XG4gICAgfVxuICAgIHRoaXMucmVsb2FkV2l0aEppdHRlclRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAodmlldy5pc0Rlc3Ryb3llZCgpIHx8IHZpZXcuaXNDb25uZWN0ZWQoKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2aWV3LmRlc3Ryb3koKTtcbiAgICAgIGxvZyA/IGxvZygpIDogdGhpcy5sb2codmlldywgXCJqb2luXCIsICgpID0+IFtcbiAgICAgICAgYGVuY291bnRlcmVkICR7dHJpZXN9IGNvbnNlY3V0aXZlIHJlbG9hZHNgXG4gICAgICBdKTtcbiAgICAgIGlmICh0cmllcyA+PSB0aGlzLm1heFJlbG9hZHMpIHtcbiAgICAgICAgdGhpcy5sb2codmlldywgXCJqb2luXCIsICgpID0+IFtcbiAgICAgICAgICBgZXhjZWVkZWQgJHt0aGlzLm1heFJlbG9hZHN9IGNvbnNlY3V0aXZlIHJlbG9hZHMuIEVudGVyaW5nIGZhaWxzYWZlIG1vZGVgXG4gICAgICAgIF0pO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMucGVuZGluZ0xpbmsgIT09IG51bGwpIHtcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLmhy
1ZWYgPSB0aGlzLnBlbmRpbmdMaW5rO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpO1xuICAgICAgfVxuICAgIH0sIGFmdGVyTXMpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgZ2V0SG9va0RlZmluaXRpb24obmFtZSkge1xuICAgIGlmICghbmFtZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5tYXliZUludGVybmFsSG9vayhuYW1lKSB8fCB0aGlzLmhvb2tzW25hbWVdIHx8IHRoaXMubWF5YmVSdW50aW1lSG9vayhuYW1lKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIG1heWJlSW50ZXJuYWxIb29rKG5hbWUpIHtcbiAgICByZXR1cm4gbmFtZSAmJiBuYW1lLnN0YXJ0c1dpdGgoXCJQaG9lbml4LlwiKSAmJiBob29rc19kZWZhdWx0W25hbWUuc3BsaXQoXCIuXCIpWzFdXTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIG1heWJlUnVudGltZUhvb2sobmFtZSkge1xuICAgIGNvbnN0IHJ1bnRpbWVIb29rID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgIGBzY3JpcHRbJHtQSFhfUlVOVElNRV9IT09LfT1cIiR7Q1NTLmVzY2FwZShuYW1lKX1cIl1gXG4gICAgKTtcbiAgICBpZiAoIXJ1bnRpbWVIb29rKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBjYWxsYmFja3MgPSB3aW5kb3dbYHBoeF9ob29rXyR7bmFtZX1gXTtcbiAgICBpZiAoIWNhbGxiYWNrcyB8fCB0eXBlb2YgY2FsbGJhY2tzICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGxvZ0Vycm9yKFwiYSBydW50aW1lIGhvb2sgbXVzdCBiZSBhIGZ1bmN0aW9uXCIsIHJ1bnRpbWVIb29rKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaG9va0RlZmluaXRvbiA9IGNhbGxiYWNrcygpO1xuICAgIGlmIChob29rRGVmaW5pdG9uICYmICh0eXBlb2YgaG9va0RlZmluaXRvbiA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgaG9va0RlZmluaXRvbiA9PT0gXCJmdW5jdGlvblwiKSkge1xuICAgICAgcmV0dXJuIGhvb2tEZWZpbml0b247XG4gICAgfVxuICAgIGxvZ0Vycm9yKFxuICAgICAgXCJydW50aW1lIGhvb2sgbXVzdCByZXR1cm4gYW4gb2JqZWN0IHdpdGggaG9vayBjYWxsYmFja3Mgb3IgYW4gaW5zdGFuY2Ugb2YgVmlld0hvb2tcIixcbiAgICAgIHJ1bnRpbWVIb29rXG4gICAgKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGlzVW5sb2FkZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMudW5sb2FkZWQ7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBpc0Nvbm5lY3RlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGdldEJpbmRpbmdQcmVmaXgoKSB7XG4gICAgcmV0dXJuIHRoaXMuYmluZGluZ1ByZWZpeDtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGJpbmRpbmcoa2luZCkge1xuICAgIHJldHVybiBgJHt0aGlzLmdldEJpbmRpbmdQcmVmaXgoKX0ke2tpbmR9YDtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGNoYW5uZWwodG9waWMsIHBhcmFtcykge1xuICAgIHJldHVybiB0aGlzLnNvY2tldC5jaGFubmVsKHRvcGljLCBwYXJhbXMpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgam9pbkRlYWRWaWV3KCkge1xuICAgIGNvbnN0IGJvZHkgPSBkb2N1bWVudC5ib2R5O1xuICAgIGlmIChib2R5ICYmICF0aGlzLmlzUGh4Vmlldyhib2R5KSAmJiAhdGhpcy5pc1BoeFZpZXcoZG9jdW1lbnQuZmlyc3RFbGVtZW50Q2hpbGQpKSB7XG4gICAgICBjb25zdCB2aWV3ID0gdGhpcy5uZXdSb290Vmlldyhib2R5KTtcbiAgICAgIHZpZXcuc2V0SHJlZih0aGlzLmdldEhyZWYoKSk7XG4gICAgICB2aWV3LmpvaW5EZWFkKCk7XG4gICAgICBpZiAoIXRoaXMubWFpbikge1xuICAgICAgICB0aGlzLm1haW4gPSB2aWV3O1xuICAgICAgfVxuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIHZpZXcuZXhlY05ld01vdW50ZWQoKTtcbiAgICAgICAgdGhpcy5tYXliZVNjcm9sbChoaXN0b3J5LnN0YXRlPy5zY3JvbGwpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgam9pblJvb3RWaWV3cygpIHtcbiAgICBsZXQgcm9vdHNGb3VuZCA9IGZhbHNlO1xuICAgIGRvbV9kZWZhdWx0LmFsbChcbiAgICAgIGRvY3VtZW50LFxuICAgICAgYCR7UEhYX1ZJRVdfU0VMRUNUT1J9Om5vdChbJHtQSFhfUEFSRU5UX0lEfV0pYCxcbiAgICAgIChyb290RWwpID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLmdldFJvb3RCeUlkKHJvb3RFbC5pZCkpIHtcbiAgICAgICAgICBjb25zdCB2aWV3ID0gdGhpcy5uZXdSb290Vmlldyhyb290RWwpO1xuICAgICAgICAgIGlmICghZG9tX2RlZmF1bHQuaXNQaHhTdGlja3kocm9vdEVsKSkge1xuICAgICAgICAgICAgdmlldy5zZXRIcmVmKHRoaXMuZ2V0SHJlZigpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmlldy5qb2luKCk7XG4gICAgICAgICAgaWYgKHJvb3RFbC5oYXNBdHRyaWJ1dGUoUEhYX01BSU4pKSB7XG4gICAgICAgICAgICB0aGlzLm1haW4gPSB2aWV3O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByb290c0ZvdW5kID0gdHJ1ZTtcbiAgICAgIH1cbiAgICApO1xuICAgIHJldHVybiByb290c0ZvdW5kO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcmVkaXJlY3QodG8sIGZsYXNoLCByZWxvYWRUb2tlbikge1xuICAgIGlmIChyZWxvYWRUb2tlbikge1xuICAgICAgYnJvd3Nlcl9kZWZhdWx0LnNldENvb2tpZShQSFhfUkVMT0FEX1NUQVRVUywgcmVsb2FkVG9rZW4sIDYwKTtcbiAgICB9XG4gICAgdGhpcy51bmxvYWQoKTtcbiAgICBicm93c2VyX2RlZmF1bHQucmVkaXJlY3QodG8sIGZsYXNoKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIHJlcGxhY2VNYWluKGhyZWYsIGZsYXNoLCBjYWxsYmFjayA9IG51bGwsIGxpbmtSZWYgPSB0aGlzLnNldFBlbmRpbmdMaW5rKGhyZWYpKSB7XG4gICAgaWYgKCF0aGlzLm1haW4pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbGl2ZVJlZmVyZXIgPSB0aGlzLmN1cnJlbnRMb2NhdGlvbi5ocmVmO1xuICAgIHRoaXMub3V0Z29pbmdNYWluRWwgPSB0aGlzLm91dGdvaW5nTWFpbkVsIHx8IHRoaXMubWFpbi5lbDtcbiAgICBjb25zdCBzdGlja2llcyA9IGRvbV9kZWZhdWx0LmZpbmRQaHhTdGlja3koZG9jdW1lbnQpIHx8IFtdO1xuICAgIGNvbnN0IHJlbW92ZUVscyA9IGRvbV9kZWZhdWx0LmFsbChcbiAgICAgIHRoaXMub3V0Z29pbmdNYWluRWwsXG4gICAgICBgWyR7dGhpcy5iaW5kaW5nKFwicmVtb3ZlXCIpfV1gXG4gICAgKS5maWx0ZXIoKGVsKSA9PiAhZG9tX2RlZmF1bHQuaXNDaGlsZE9mQW55KGVsLCBzdGlja2llcykpO1xuICAgIGNvbnN0IG5ld01haW5FbCA9IGRvbV9kZWZhdWx0LmNsb25lTm9kZSh0aGlzLm91dGdvaW5nTWFpbkVsLCBcIlwiKTtcbiAgICBjb25zdCBvbGRNYWluVmlldyA9IHRoaXMubWFpbjtcbiAgICBvbGRNYWluVmlldy5zaG93TG9hZGVyKHRoaXMubG9hZGVyVGltZW91dCk7XG4gICAgb2xkTWFpblZpZXcuZGVzdHJveSgpO1xuICAgIHRoaXMubWFpbiA9IHRoaXMubmV3Um9vdFZpZXcobmV3TWFpbkVsLCBmbGFzaCwgbGl2ZVJlZmVyZXIpO1xuICAgIHRoaXMubWFpbi5zZXRSZWRpcmVjdChocmVmKTtcbiAgICB0aGlzLnRyYW5zaXRpb25SZW1vdmVzKHJlbW92ZUVscywgb2xkTWFpblZpZXcpO1xuICAgIHRoaXMubWFpbi5qb2luKChqb2luQ291bnQsIG9uRG9uZSkgPT4ge1xuICAgICAgaWYgKGpvaW5Db3VudCA9PT0gMSAmJi
1B0aGlzLmNvbW1pdFBlbmRpbmdMaW5rKGxpbmtSZWYpKSB7XG4gICAgICAgIHRoaXMucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiB7XG4gICAgICAgICAgcmVtb3ZlRWxzLmZvckVhY2goKGVsKSA9PiBlbC5yZW1vdmUoKSk7XG4gICAgICAgICAgc3RpY2tpZXMuZm9yRWFjaCgoZWwpID0+IG5ld01haW5FbC5hcHBlbmRDaGlsZChlbCkpO1xuICAgICAgICAgIHRoaXMub3V0Z29pbmdNYWluRWwucmVwbGFjZVdpdGgobmV3TWFpbkVsKTtcbiAgICAgICAgICB0aGlzLm91dGdvaW5nTWFpbkVsID0gbnVsbDtcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhsaW5rUmVmKTtcbiAgICAgICAgICBvbkRvbmUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICB0cmFuc2l0aW9uUmVtb3ZlcyhlbGVtZW50cywgdmlldywgY2FsbGJhY2spIHtcbiAgICBjb25zdCByZW1vdmVBdHRyID0gdGhpcy5iaW5kaW5nKFwicmVtb3ZlXCIpO1xuICAgIGNvbnN0IHNpbGVuY2VFdmVudHMgPSAoZSkgPT4ge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICB9O1xuICAgIGVsZW1lbnRzLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIHRoaXMuYm91bmRFdmVudE5hbWVzKSB7XG4gICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIHNpbGVuY2VFdmVudHMsIHRydWUpO1xuICAgICAgfVxuICAgICAgY29uc3QgZSA9IG5ldyBDdXN0b21FdmVudChcInBoeDpleGVjXCIsIHsgZGV0YWlsOiB7IHNvdXJjZUVsZW1lbnQ6IGVsIH0gfSk7XG4gICAgICBqc19kZWZhdWx0LmV4ZWMoZSwgXCJyZW1vdmVcIiwgZWwuZ2V0QXR0cmlidXRlKHJlbW92ZUF0dHIpLCB2aWV3LCBlbCk7XG4gICAgfSk7XG4gICAgdGhpcy5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHtcbiAgICAgIGVsZW1lbnRzLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgZXZlbnQgb2YgdGhpcy5ib3VuZEV2ZW50TmFtZXMpIHtcbiAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBzaWxlbmNlRXZlbnRzLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgIH0pO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgaXNQaHhWaWV3KGVsKSB7XG4gICAgcmV0dXJuIGVsLmdldEF0dHJpYnV0ZSAmJiBlbC5nZXRBdHRyaWJ1dGUoUEhYX1NFU1NJT04pICE9PSBudWxsO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgbmV3Um9vdFZpZXcoZWwsIGZsYXNoLCBsaXZlUmVmZXJlcikge1xuICAgIGNvbnN0IHZpZXcgPSBuZXcgVmlldyhlbCwgdGhpcywgbnVsbCwgZmxhc2gsIGxpdmVSZWZlcmVyKTtcbiAgICB0aGlzLnJvb3RzW3ZpZXcuaWRdID0gdmlldztcbiAgICByZXR1cm4gdmlldztcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIG93bmVyKGNoaWxkRWwsIGNhbGxiYWNrKSB7XG4gICAgbGV0IHZpZXc7XG4gICAgY29uc3Qgdmlld0VsID0gZG9tX2RlZmF1bHQuY2xvc2VzdFZpZXdFbChjaGlsZEVsKTtcbiAgICBpZiAodmlld0VsKSB7XG4gICAgICB2aWV3ID0gZG9tX2RlZmF1bHQucHJpdmF0ZSh2aWV3RWwsIFwidmlld1wiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFjaGlsZEVsLmlzQ29ubmVjdGVkKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgdmlldyA9IHRoaXMubWFpbjtcbiAgICB9XG4gICAgcmV0dXJuIHZpZXcgJiYgY2FsbGJhY2sgPyBjYWxsYmFjayh2aWV3KSA6IHZpZXc7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICB3aXRoaW5Pd25lcnMoY2hpbGRFbCwgY2FsbGJhY2spIHtcbiAgICB0aGlzLm93bmVyKGNoaWxkRWwsICh2aWV3KSA9PiBjYWxsYmFjayh2aWV3LCBjaGlsZEVsKSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBnZXRWaWV3QnlFbChlbCkge1xuICAgIGNvbnN0IHJvb3RJZCA9IGVsLmdldEF0dHJpYnV0ZShQSFhfUk9PVF9JRCk7XG4gICAgcmV0dXJuIG1heWJlKFxuICAgICAgdGhpcy5nZXRSb290QnlJZChyb290SWQpLFxuICAgICAgKHJvb3QpID0+IHJvb3QuZ2V0RGVzY2VuZGVudEJ5RWwoZWwpXG4gICAgKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGdldFJvb3RCeUlkKGlkKSB7XG4gICAgcmV0dXJuIHRoaXMucm9vdHNbaWRdO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgZGVzdHJveUFsbFZpZXdzKCkge1xuICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5yb290cykge1xuICAgICAgdGhpcy5yb290c1tpZF0uZGVzdHJveSgpO1xuICAgICAgZGVsZXRlIHRoaXMucm9vdHNbaWRdO1xuICAgIH1cbiAgICB0aGlzLm1haW4gPSBudWxsO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgZGVzdHJveVZpZXdCeUVsKGVsKSB7XG4gICAgY29uc3Qgcm9vdCA9IHRoaXMuZ2V0Um9vdEJ5SWQoZWwuZ2V0QXR0cmlidXRlKFBIWF9ST09UX0lEKSk7XG4gICAgaWYgKHJvb3QgJiYgcm9vdC5pZCA9PT0gZWwuaWQpIHtcbiAgICAgIHJvb3QuZGVzdHJveSgpO1xuICAgICAgZGVsZXRlIHRoaXMucm9vdHNbcm9vdC5pZF07XG4gICAgfSBlbHNlIGlmIChyb290KSB7XG4gICAgICByb290LmRlc3Ryb3lEZXNjZW5kZW50KGVsLmlkKTtcbiAgICB9XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBnZXRBY3RpdmVFbGVtZW50KCkge1xuICAgIHJldHVybiBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgZHJvcEFjdGl2ZUVsZW1lbnQodmlldykge1xuICAgIGlmICh0aGlzLnByZXZBY3RpdmUgJiYgdmlldy5vd25zRWxlbWVudCh0aGlzLnByZXZBY3RpdmUpKSB7XG4gICAgICB0aGlzLnByZXZBY3RpdmUgPSBudWxsO1xuICAgIH1cbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIHJlc3RvcmVQcmV2aW91c2x5QWN0aXZlRm9jdXMoKSB7XG4gICAgaWYgKHRoaXMucHJldkFjdGl2ZSAmJiB0aGlzLnByZXZBY3RpdmUgIT09IGRvY3VtZW50LmJvZHkgJiYgdGhpcy5wcmV2QWN0aXZlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgIHRoaXMucHJldkFjdGl2ZS5mb2N1cygpO1xuICAgIH1cbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGJsdXJBY3RpdmVFbGVtZW50KCkge1xuICAgIHRoaXMucHJldkFjdGl2ZSA9IHRoaXMuZ2V0QWN0aXZlRWxlbWVudCgpO1xuICAgIGlmICh0aGlzLnByZXZBY3RpdmUgIT09IGRvY3VtZW50LmJvZHkgJiYgdGhpcy5wcmV2QWN0aXZlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgIHRoaXMucHJldkFjdGl2ZS5ibHVyKCk7XG4gICAgfVxuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgYmluZFRvcExldmVsRXZlbnRzKHsgZGVhZCB9ID0ge30pIHtcbiAgICBpZiAodGhpcy5ib3VuZFRvcExldmVsRXZlbnRzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYm91bmRUb3BMZXZlbEV2ZW50cyA9IHRydWU7XG4gICAgdGhpcy5zZXJ2ZXJDbG9zZVJlZiA9IHRoaXMuc29ja2V0Lm9uQ2xvc2UoKGV2ZW50KSA9PiB7XG4gICAgICBpZiAoZXZlbnQgJiYgZXZlbnQuY29kZSA9PT0gMWUzICYmIHRoaXMubWFpbikge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWxvYWRXaXRoSml0dGVyKHRoaXMubWFpbik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgZnVuY3Rpb24oKSB7XG4gICAgfSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBcInBhZ2VzaG93XCIsXG4gICAgICAoZSkgPT4ge1xuICAgICAgICBpZiAoZS5wZXJzaXN0ZWQpIHtcbiAgICAgICAgICB0aGlzLmdldFNvY2tldCgpLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICB0aGlzLndpdGhQYWdlTG9hZGluZyh7IHRvOiB3aW5kb3cubG9jYXRpb24uaHJlZiwga2luZDogXCJyZWRpcmVjdFwiIH0pO1xuICAgICAgICAgI
1HdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHRydWVcbiAgICApO1xuICAgIGlmICghZGVhZCkge1xuICAgICAgdGhpcy5iaW5kTmF2KCk7XG4gICAgfVxuICAgIHRoaXMuYmluZENsaWNrcygpO1xuICAgIGlmICghZGVhZCkge1xuICAgICAgdGhpcy5iaW5kRm9ybXMoKTtcbiAgICB9XG4gICAgdGhpcy5iaW5kKFxuICAgICAgeyBrZXl1cDogXCJrZXl1cFwiLCBrZXlkb3duOiBcImtleWRvd25cIiB9LFxuICAgICAgKGUsIHR5cGUsIHZpZXcsIHRhcmdldEVsLCBwaHhFdmVudCwgX3BoeFRhcmdldCkgPT4ge1xuICAgICAgICBjb25zdCBtYXRjaEtleSA9IHRhcmdldEVsLmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoUEhYX0tFWSkpO1xuICAgICAgICBjb25zdCBwcmVzc2VkS2V5ID0gZS5rZXkgJiYgZS5rZXkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgaWYgKG1hdGNoS2V5ICYmIG1hdGNoS2V5LnRvTG93ZXJDYXNlKCkgIT09IHByZXNzZWRLZXkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGF0YSA9IHsga2V5OiBlLmtleSwgLi4udGhpcy5ldmVudE1ldGEodHlwZSwgZSwgdGFyZ2V0RWwpIH07XG4gICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCB0eXBlLCBwaHhFdmVudCwgdmlldywgdGFyZ2V0RWwsIFtcInB1c2hcIiwgeyBkYXRhIH1dKTtcbiAgICAgIH1cbiAgICApO1xuICAgIHRoaXMuYmluZChcbiAgICAgIHsgYmx1cjogXCJmb2N1c291dFwiLCBmb2N1czogXCJmb2N1c2luXCIgfSxcbiAgICAgIChlLCB0eXBlLCB2aWV3LCB0YXJnZXRFbCwgcGh4RXZlbnQsIHBoeFRhcmdldCkgPT4ge1xuICAgICAgICBpZiAoIXBoeFRhcmdldCkge1xuICAgICAgICAgIGNvbnN0IGRhdGEgPSB7IC4uLnRoaXMuZXZlbnRNZXRhKHR5cGUsIGUsIHRhcmdldEVsKSB9O1xuICAgICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCB0eXBlLCBwaHhFdmVudCwgdmlldywgdGFyZ2V0RWwsIFtcInB1c2hcIiwgeyBkYXRhIH1dKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5iaW5kKFxuICAgICAgeyBibHVyOiBcImJsdXJcIiwgZm9jdXM6IFwiZm9jdXNcIiB9LFxuICAgICAgKGUsIHR5cGUsIHZpZXcsIHRhcmdldEVsLCBwaHhFdmVudCwgcGh4VGFyZ2V0KSA9PiB7XG4gICAgICAgIGlmIChwaHhUYXJnZXQgPT09IFwid2luZG93XCIpIHtcbiAgICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5ldmVudE1ldGEodHlwZSwgZSwgdGFyZ2V0RWwpO1xuICAgICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCB0eXBlLCBwaHhFdmVudCwgdmlldywgdGFyZ2V0RWwsIFtcInB1c2hcIiwgeyBkYXRhIH1dKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5vbihcImRyYWdvdmVyXCIsIChlKSA9PiBlLnByZXZlbnREZWZhdWx0KCkpO1xuICAgIHRoaXMub24oXCJkcmFnZW50ZXJcIiwgKGUpID0+IHtcbiAgICAgIGxldCB0YXJnZXQgPSBlLnRhcmdldCAmJiBkb21fZGVmYXVsdC5lbGVtZW50RnJvbVRhcmdldChlLnRhcmdldCk7XG4gICAgICBpZiAoIXRhcmdldCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBkcm9wem9uZSA9IGNsb3Nlc3RQaHhCaW5kaW5nKHRhcmdldCwgdGhpcy5iaW5kaW5nKFBIWF9EUk9QX1RBUkdFVCkpO1xuICAgICAgaWYgKCFkcm9wem9uZSB8fCAhKGRyb3B6b25lIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChldmVudENvbnRhaW5zRmlsZXMoZSkpIHtcbiAgICAgICAgdGhpcy5qcygpLmFkZENsYXNzKGRyb3B6b25lLCBQSFhfRFJPUF9UQVJHRVRfQUNUSVZFX0NMQVNTKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLm9uKFwiZHJhZ2xlYXZlXCIsIChlKSA9PiB7XG4gICAgICBsZXQgdGFyZ2V0ID0gZS50YXJnZXQgJiYgZG9tX2RlZmF1bHQuZWxlbWVudEZyb21UYXJnZXQoZS50YXJnZXQpO1xuICAgICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgZHJvcHpvbmUgPSBjbG9zZXN0UGh4QmluZGluZyh0YXJnZXQsIHRoaXMuYmluZGluZyhQSFhfRFJPUF9UQVJHRVQpKTtcbiAgICAgIGlmICghZHJvcHpvbmUgfHwgIShkcm9wem9uZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCByZWN0ID0gZHJvcHpvbmUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBpZiAoZS5jbGllbnRYIDw9IHJlY3QubGVmdCB8fCBlLmNsaWVudFggPj0gcmVjdC5yaWdodCB8fCBlLmNsaWVudFkgPD0gcmVjdC50b3AgfHwgZS5jbGllbnRZID49IHJlY3QuYm90dG9tKSB7XG4gICAgICAgIHRoaXMuanMoKS5yZW1vdmVDbGFzcyhkcm9wem9uZSwgUEhYX0RST1BfVEFSR0VUX0FDVElWRV9DTEFTUyk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5vbihcImRyb3BcIiwgKGUpID0+IHtcbiAgICAgIGxldCB0YXJnZXQgPSBlLnRhcmdldCAmJiBkb21fZGVmYXVsdC5lbGVtZW50RnJvbVRhcmdldChlLnRhcmdldCk7XG4gICAgICBpZiAoIXRhcmdldCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBjb25zdCBkcm9wem9uZSA9IGNsb3Nlc3RQaHhCaW5kaW5nKHRhcmdldCwgdGhpcy5iaW5kaW5nKFBIWF9EUk9QX1RBUkdFVCkpO1xuICAgICAgaWYgKCFkcm9wem9uZSB8fCAhKGRyb3B6b25lIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuanMoKS5yZW1vdmVDbGFzcyhkcm9wem9uZSwgUEhYX0RST1BfVEFSR0VUX0FDVElWRV9DTEFTUyk7XG4gICAgICBpZiAoIWUuZGF0YVRyYW5zZmVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRyb3BUYXJnZXRJZCA9IGRyb3B6b25lLmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoUEhYX0RST1BfVEFSR0VUKSk7XG4gICAgICBjb25zdCBkcm9wVGFyZ2V0ID0gZHJvcFRhcmdldElkICYmIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGRyb3BUYXJnZXRJZCk7XG4gICAgICBjb25zdCBmaWxlcyA9IEFycmF5LmZyb20oZS5kYXRhV
1HJhbnNmZXIuZmlsZXMgfHwgW10pO1xuICAgICAgaWYgKCFkcm9wVGFyZ2V0IHx8ICEoZHJvcFRhcmdldCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQpIHx8IGRyb3BUYXJnZXQuZGlzYWJsZWQgfHwgZmlsZXMubGVuZ3RoID09PSAwIHx8ICEoZHJvcFRhcmdldC5maWxlcyBpbnN0YW5jZW9mIEZpbGVMaXN0KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBMaXZlVXBsb2FkZXIudHJhY2tGaWxlcyhkcm9wVGFyZ2V0LCBmaWxlcywgZS5kYXRhVHJhbnNmZXIpO1xuICAgICAgZHJvcFRhcmdldC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIsIHsgYnViYmxlczogdHJ1ZSB9KSk7XG4gICAgfSk7XG4gICAgdGhpcy5vbihQSFhfVFJBQ0tfVVBMT0FEUywgKGUpID0+IHtcbiAgICAgIGNvbnN0IHVwbG9hZFRhcmdldCA9IGUudGFyZ2V0ICYmIGRvbV9kZWZhdWx0LmVsZW1lbnRGcm9tVGFyZ2V0KGUudGFyZ2V0KTtcbiAgICAgIGlmICghZG9tX2RlZmF1bHQuaXNVcGxvYWRJbnB1dCh1cGxvYWRUYXJnZXQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpbGVzID0gQXJyYXkuZnJvbShlLmRldGFpbC5maWxlcyB8fCBbXSkuZmlsdGVyKFxuICAgICAgICAoZikgPT4gZiBpbnN0YW5jZW9mIEZpbGUgfHwgZiBpbnN0YW5jZW9mIEJsb2JcbiAgICAgICk7XG4gICAgICBMaXZlVXBsb2FkZXIudHJhY2tGaWxlcyh1cGxvYWRUYXJnZXQsIGZpbGVzKTtcbiAgICAgIHVwbG9hZFRhcmdldC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIsIHsgYnViYmxlczogdHJ1ZSB9KSk7XG4gICAgfSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBldmVudE1ldGEoZXZlbnROYW1lLCBlLCB0YXJnZXRFbCkge1xuICAgIGNvbnN0IGNhbGxiYWNrID0gdGhpcy5tZXRhZGF0YUNhbGxiYWNrc1tldmVudE5hbWVdO1xuICAgIHJldHVybiBjYWxsYmFjayA/IGNhbGxiYWNrKGUsIHRhcmdldEVsKSA6IHt9O1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgc2V0UGVuZGluZ0xpbmsoaHJlZikge1xuICAgIHRoaXMubGlua1JlZisrO1xuICAgIHRoaXMucGVuZGluZ0xpbmsgPSBocmVmO1xuICAgIHRoaXMucmVzZXRSZWxvYWRTdGF0dXMoKTtcbiAgICByZXR1cm4gdGhpcy5saW5rUmVmO1xuICB9XG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICogYW55dGltZSB3ZSBhcmUgbmF2aWdhdGluZyBvciBjb25uZWN0aW5nLCBkcm9wIHJlbG9hZCBjb29raWUgaW4gY2FzZVxuICAgKiB3ZSBpc3N1ZSB0aGUgY29va2llIGJ1dCB0aGUgbmV4dCByZXF1ZXN0IHdhcyBpbnRlcnJ1cHRlZCBhbmQgdGhlIHNlcnZlciBuZXZlciBkcm9wcGVkIGl0XG4gICAqL1xuICByZXNldFJlbG9hZFN0YXR1cygpIHtcbiAgICBicm93c2VyX2RlZmF1bHQuZGVsZXRlQ29va2llKFBIWF9SRUxPQURfU1RBVFVTKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGNvbW1pdFBlbmRpbmdMaW5rKGxpbmtSZWYpIHtcbiAgICBpZiAodGhpcy5saW5rUmVmICE9PSBsaW5rUmVmKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0aGlzLnBlbmRpbmdMaW5rICE9PSBudWxsKSB7XG4gICAgICB0aGlzLmhyZWYgPSB0aGlzLnBlbmRpbmdMaW5rO1xuICAgICAgdGhpcy5wZW5kaW5nTGluayA9IG51bGw7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgZ2V0SHJlZigpIHtcbiAgICByZXR1cm4gdGhpcy5ocmVmO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgaGFzUGVuZGluZ0xpbmsoKSB7XG4gICAgcmV0dXJuICEhdGhpcy5wZW5kaW5nTGluaztcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGJpbmQoZXZlbnRzLCBjYWxsYmFjaykge1xuICAgIGZvciAoY29uc3QgZXZlbnQgaW4gZXZlbnRzKSB7XG4gICAgICBjb25zdCBicm93c2VyRXZlbnROYW1lID0gZXZlbnRzW2V2ZW50XTtcbiAgICAgIHRoaXMub24oYnJvd3NlckV2ZW50TmFtZSwgKGUpID0+IHtcbiAgICAgICAgY29uc3QgYmluZGluZyA9IHRoaXMuYmluZGluZyhldmVudCk7XG4gICAgICAgIGNvbnN0IHdpbmRvd0JpbmRpbmcgPSB0aGlzLmJpbmRpbmcoYHdpbmRvdy0ke2V2ZW50fWApO1xuICAgICAgICBjb25zdCB0YXJnZXRQaHhFdmVudCA9IGUudGFyZ2V0IGluc3RhbmNlb2YgRWxlbWVudCAmJiBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoYmluZGluZyk7XG4gICAgICAgIGlmICghKGUudGFyZ2V0IGluc3RhbmNlb2YgRWxlbWVudCkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhcmdldFBoeEV2ZW50KSB7XG4gICAgICAgICAgdGhpcy5kZWJvdW5jZShlLnRhcmdldCwgZSwgYnJvd3NlckV2ZW50TmFtZSwgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy53aXRoaW5Pd25lcnMoZS50YXJnZXQsICh2aWV3KSA9PiB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKFxuICAgICAgICAgICAgICAgIGUsXG4gICAgICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICAgICAgdmlldyxcbiAgICAgICAgICAgICAgICBlLnRhcmdldCxcbiAgICAgICAgICAgICAgICB0YXJnZXRQaHhFdmVudCxcbiAgICAgICAgICAgICAgICBudWxsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkb21fZGVmYXVsdC5hbGwoZG9jdW1lbnQsIGBbJHt3aW5kb3dCaW5kaW5nfV1gLCAoZWwpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBoeEV2ZW50ID0gZWwuZ2V0QXR0cmlidXRlKHdpbmRvd0JpbmRpbmcpO1xuICAgICAgICAgICAgdGhpcy5kZWJvdW5jZShlbCwgZSwgYnJvd3NlckV2ZW50TmFtZSwgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLndpdGhpbk93bmVycyhlbCwgKHZpZXcpID0+IHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhcbiAgICAgICAgICAgICAgICAgIGUsXG4gICAgICAgICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgICAgICAgIHZpZXcsXG4gICAgICAgICAgICAgICAgICBlbCxcbiAgICAgICAgICAgICAgICAgIHBoeEV2ZW50LFxuICAgICAgICAgICAgICAgICAgXCJ3aW5kb3dcIlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgI
1H0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGJpbmRDbGlja3MoKSB7XG4gICAgdGhpcy5vbihcIm1vdXNlZG93blwiLCAoZSkgPT4gdGhpcy5jbGlja1N0YXJ0ZWRBdFRhcmdldCA9IGUudGFyZ2V0KTtcbiAgICB0aGlzLmJpbmRDbGljaygpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgYmluZENsaWNrKCkge1xuICAgIGNvbnN0IGNsaWNrID0gdGhpcy5iaW5kaW5nKFwiY2xpY2tcIik7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBcImNsaWNrXCIsXG4gICAgICAoZSkgPT4ge1xuICAgICAgICBsZXQgdGFyZ2V0ID0gZS50YXJnZXQgJiYgZG9tX2RlZmF1bHQuZWxlbWVudEZyb21UYXJnZXQoZS50YXJnZXQpO1xuICAgICAgICBpZiAoIXRhcmdldCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZS5kZXRhaWwgPT09IDApXG4gICAgICAgICAgdGhpcy5jbGlja1N0YXJ0ZWRBdFRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgY29uc3QgY2xpY2tTdGFydGVkQXRUYXJnZXQgPSB0aGlzLmNsaWNrU3RhcnRlZEF0VGFyZ2V0IHx8IHRhcmdldDtcbiAgICAgICAgdGFyZ2V0ID0gY2xvc2VzdFBoeEJpbmRpbmcodGFyZ2V0LCBjbGljayk7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hDbGlja0F3YXkoZSwgY2xpY2tTdGFydGVkQXRUYXJnZXQpO1xuICAgICAgICB0aGlzLmNsaWNrU3RhcnRlZEF0VGFyZ2V0ID0gbnVsbDtcbiAgICAgICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGh4RXZlbnQgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKGNsaWNrKTtcbiAgICAgICAgaWYgKCFwaHhFdmVudCkge1xuICAgICAgICAgIGlmIChkb21fZGVmYXVsdC5pc05ld1BhZ2VDbGljayhlLCB3aW5kb3cubG9jYXRpb24pKSB7XG4gICAgICAgICAgICB0aGlzLnVubG9hZCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhcmdldC5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpID09PSBcIiNcIikge1xuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGFyZ2V0Lmhhc0F0dHJpYnV0ZShQSFhfUkVGX1NSQykpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZWJvdW5jZSh0YXJnZXQsIGUsIFwiY2xpY2tcIiwgKCkgPT4ge1xuICAgICAgICAgIHRoaXMud2l0aGluT3duZXJzKHRhcmdldCwgKHZpZXcpID0+IHtcbiAgICAgICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCBcImNsaWNrXCIsIHBoeEV2ZW50LCB2aWV3LCB0YXJnZXQsIFtcbiAgICAgICAgICAgICAgXCJwdXNoXCIsXG4gICAgICAgICAgICAgIHsgZGF0YTogdGhpcy5ldmVudE1ldGEoXCJjbGlja1wiLCBlLCB0YXJnZXQpIH1cbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBmYWxzZVxuICAgICk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBkaXNwYXRjaENsaWNrQXdheShlLCBjbGlja1N0YXJ0ZWRBdCkge1xuICAgIGNvbnN0IHBoeENsaWNrQXdheSA9IHRoaXMuYmluZGluZyhcImNsaWNrLWF3YXlcIik7XG4gICAgY29uc3QgcG9ydGFsID0gY2xpY2tTdGFydGVkQXQuY2xvc2VzdChgWyR7UEhYX1RFTEVQT1JURURfU1JDfV1gKTtcbiAgICBjb25zdCBwb3J0YWxTdGFydGVkQXQgPSBwb3J0YWwgJiYgZG9tX2RlZmF1bHQuYnlJZChwb3J0YWwuZ2V0QXR0cmlidXRlKFBIWF9URUxFUE9SVEVEX1NSQykpO1xuICAgIGRvbV9kZWZhdWx0LmFsbChkb2N1bWVudCwgYFske3BoeENsaWNrQXdheX1dYCwgKGVsKSA9PiB7XG4gICAgICBsZXQgc3RhcnRlZEF0ID0gY2xpY2tTdGFydGVkQXQ7XG4gICAgICBpZiAocG9ydGFsICYmICFwb3J0YWwuY29udGFpbnMoZWwpKSB7XG4gICAgICAgIHN0YXJ0ZWRBdCA9IHBvcnRhbFN0YXJ0ZWRBdDtcbiAgICAgIH1cbiAgICAgIGlmICghKGVsLmlzU2FtZU5vZGUoc3RhcnRlZEF0KSB8fCBlbC5jb250YWlucyhzdGFydGVkQXQpIHx8IC8vIFdoZW4gY2xpY2tpbmcgYSBsaW5rIHdpdGggY3VzdG9tIG1ldGhvZCxcbiAgICAgIC8vIHBob2VuaXhfaHRtbCB0cmlnZ2VycyBhIGNsaWNrIG9uIGEgc3VibWl0IGJ1dHRvblxuICAgICAgLy8gb2YgYSBoaWRkZW4gZm9ybSBhcHBlbmRlZCB0byB0aGUgYm9keS4gRm9yIHN1Y2ggY2FzZXNcbiAgICAgIC8vIHdoZXJlIHRoZSBjbGlja2VkIHRhcmdldCBpcyBoaWRkZW4sIHdlIHNraXAgY2xpY2stYXdheS5cbiAgICAgIC8vXG4gICAgICAvLyBBbHNvLCB3aGVuIHdlIGhhdmUgYSBwb3J0YWwsIHdlIGRvbid0IHdhbnQgdG8gY2hlY2sgdGhlIHZpc2liaWxpdHlcbiAgICAgIC8vIG9mIHRoZSBwb3J0YWwgc291cmNlLCBhcyBpdCdzIGEgPHRlbXBsYXRlPiB0aGF0IGlzIGFsd2F5cyBub3QgdmlzaWJsZS5cbiAgICAgIC8vIEluc3RlYWQsIGNoZWNrIHRoZSB2aXNpYmlsaXR5IG9mIHRoZSBvcmlnaW5hbCBjbGljayB0YXJnZXQuXG4gICAgICAhanNfZGVmYXVsdC5pc1Zpc2libGUoY2xpY2tTdGFydGVkQXQpKSkge1xuICAgICAgICB0aGlzLndpdGhpbk93bmVycyhlbCwgKHZpZXcpID0+IHtcbiAgICAgICAgICBjb25zdCBwaHhFdmVudCA9IGVsLmdldEF0dHJpYnV0ZShwaHhDbGlja0F3YXkpO1xuICAgICAgICAgIGlmIChqc19kZWZhdWx0LmlzVmlzaWJsZShlbCkgJiYganNfZGVmYXVsdC5pc0luVmlld3BvcnQoZWwpKSB7XG4gICAgICAgICAgICBqc19kZWZhdWx0LmV4ZWMoZSwgXCJjbGlja1wiLCBwaHhFdmVudCwgdmlldywgZWwsIFtcbiAgICAgICAgICAgICAgXCJwdXNoXCIsXG4gICAgICAgICAgICAgIHsgZGF0YTogdGhpcy5ldmVudE1ldGEoXCJjbGlja1wiLCBlLCBlLnRhcmdldCkgfVxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGJpbmROYXYoKSB7XG4gICAgaWYgKCFicm93c2VyX2RlZmF1bHQuY2FuUHVzaFN0YXRlKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24pIHtcbiAgICAgIGhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24gPSBcIm1hbnVhbFwiO1xuICAgIH1cbiAgICBsZXQgc2Nyb2xsVGltZXIgPSBudWxsO1xuICAgIHdpbmRvdy5hZGR
1FdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIChfZSkgPT4ge1xuICAgICAgc2Nyb2xsVGltZXIgIT0gbnVsbCAmJiBjbGVhclRpbWVvdXQoc2Nyb2xsVGltZXIpO1xuICAgICAgc2Nyb2xsVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgYnJvd3Nlcl9kZWZhdWx0LnVwZGF0ZUN1cnJlbnRTdGF0ZShcbiAgICAgICAgICAoc3RhdGUpID0+IE9iamVjdC5hc3NpZ24oc3RhdGUsIHsgc2Nyb2xsOiB3aW5kb3cuc2Nyb2xsWSB9KVxuICAgICAgICApO1xuICAgICAgfSwgMTAwKTtcbiAgICB9KTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIFwicG9wc3RhdGVcIixcbiAgICAgIChldmVudCkgPT4ge1xuICAgICAgICBpZiAoIXRoaXMucmVnaXN0ZXJOZXdMb2NhdGlvbih3aW5kb3cubG9jYXRpb24pKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgdHlwZSwgYmFja1R5cGUsIGlkLCBzY3JvbGwsIHBvc2l0aW9uIH0gPSBldmVudC5zdGF0ZSB8fCB7fTtcbiAgICAgICAgY29uc3QgaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuICAgICAgICBjb25zdCBpc0ZvcndhcmQgPSBwb3NpdGlvbiA+IHRoaXMuY3VycmVudEhpc3RvcnlQb3NpdGlvbjtcbiAgICAgICAgY29uc3QgbmF2VHlwZSA9IGlzRm9yd2FyZCA/IHR5cGUgOiBiYWNrVHlwZSB8fCB0eXBlO1xuICAgICAgICB0aGlzLmN1cnJlbnRIaXN0b3J5UG9zaXRpb24gPSBwb3NpdGlvbiB8fCAwO1xuICAgICAgICB0aGlzLnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oXG4gICAgICAgICAgUEhYX0xWX0hJU1RPUllfUE9TSVRJT04sXG4gICAgICAgICAgdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uLnRvU3RyaW5nKClcbiAgICAgICAgKTtcbiAgICAgICAgZG9tX2RlZmF1bHQuZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4Om5hdmlnYXRlXCIsIHtcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIGhyZWYsXG4gICAgICAgICAgICBwYXRjaDogbmF2VHlwZSA9PT0gXCJwYXRjaFwiLFxuICAgICAgICAgICAgcG9wOiB0cnVlLFxuICAgICAgICAgICAgZGlyZWN0aW9uOiBpc0ZvcndhcmQgPyBcImZvcndhcmRcIiA6IFwiYmFja3dhcmRcIlxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiB7XG4gICAgICAgICAgY29uc3QgY2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm1heWJlU2Nyb2xsKHNjcm9sbCk7XG4gICAgICAgICAgfTtcbiAgICAgICAgICBpZiAodGhpcy5tYWluICYmIHRoaXMubWFpbi5pc0Nvbm5lY3RlZCgpICYmIG5hdlR5cGUgPT09IFwicGF0Y2hcIiAmJiBpZCA9PT0gdGhpcy5tYWluLmlkKSB7XG4gICAgICAgICAgICB0aGlzLm1haW4ucHVzaExpbmtQYXRjaChldmVudCwgaHJlZiwgbnVsbCwgY2FsbGJhY2spO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnJlcGxhY2VNYWluKGhyZWYsIG51bGwsIGNhbGxiYWNrKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIGZhbHNlXG4gICAgKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIFwiY2xpY2tcIixcbiAgICAgIChlKSA9PiB7XG4gICAgICAgIGxldCBlbCA9IGUudGFyZ2V0ICYmIGRvbV9kZWZhdWx0LmVsZW1lbnRGcm9tVGFyZ2V0KGUudGFyZ2V0KTtcbiAgICAgICAgaWYgKCFlbCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0YXJnZXQgPSBjbG9zZXN0UGh4QmluZGluZyhcbiAgICAgICAgICBlbCxcbiAgICAgICAgICBQSFhfTElWRV9MSU5LXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHR5cGUgPSB0YXJnZXQgJiYgdGFyZ2V0LmdldEF0dHJpYnV0ZShQSFhfTElWRV9MSU5LKTtcbiAgICAgICAgaWYgKCF0eXBlIHx8ICF0aGlzLmlzQ29ubmVjdGVkKCkgfHwgIXRoaXMubWFpbiB8fCBkb21fZGVmYXVsdC53YW50c05ld1RhYihlKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBocmVmID0gdGFyZ2V0LmhyZWYgaW5zdGFuY2VvZiBTVkdBbmltYXRlZFN0cmluZyA/IHRhcmdldC5ocmVmLmJhc2VWYWwgOiB0YXJnZXQuaHJlZjtcbiAgICAgICAgY29uc3QgbGlua1N0YXRlID0gdGFyZ2V0LmdldEF0dHJpYnV0ZShQSFhfTElOS19TVEFURSk7XG4gICAgICAgIGlmIChsaW5rU3RhdGUgIT09IFwicmVwbGFjZVwiICYmIGxpbmtTdGF0ZSAhPT0gXCJwdXNoXCIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgZXhwZWN0ZWQgJHtQSFhfTElOS19TVEFURX0gdG8gYmUgXCJyZXBsYWNlXCIgb3IgXCJwdXNoXCIsIGdvdDogJHtsaW5rU3RhdGV9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgICBpZiAodGhpcy5wZW5kaW5nTGluayA9PT0gaHJlZikge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICAgIGlmICh0eXBlID09PSBcInBhdGNoXCIpIHtcbiAgICAgICAgICAgIHRoaXMucHVzaEhpc3RvcnlQYXRjaChlLCBocmVmLCBsaW5rU3RhdGUsIHRhcmdldCk7XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBcInJlZGlyZWN0XCIpIHtcbiAgICAgICAgICAgIHRoaXMuaGlzdG9yeVJlZGlyZWN0KGUsIGhyZWYsIGxpbmtTdGF0ZSwgbnVsbCwgdGFyZ2V0KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICBgZXhwZWN0ZWQgJHtQSFhfTElWRV9MSU5LfSB0byBiZSBcInBhdGNoXCIgb3IgXCJyZWRpcmVjdFwiLCBnb3Q6ICR7dHlwZX1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBwaHhDbGljayA9IHRhcmdldC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwiY2xpY2tcIikpO1xuICAgICAgICAgIGlmIChwaHhDbGljaykge1xuICAgICAgICAgICAgdGhpcy5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHRoaXMuZXhlY0pTKHRhcmdldCwgcGh4Q2xpY2ssIFwiY2xpY2tcIikpO1xuICAgICAgICAgI
1H1cbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgZmFsc2VcbiAgICApO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgbWF5YmVTY3JvbGwoc2Nyb2xsKSB7XG4gICAgaWYgKHR5cGVvZiBzY3JvbGwgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIHdpbmRvdy5zY3JvbGxUbygwLCBzY3JvbGwpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgZGlzcGF0Y2hFdmVudChldmVudCwgcGF5bG9hZCA9IHt9KSB7XG4gICAgZG9tX2RlZmF1bHQuZGlzcGF0Y2hFdmVudCh3aW5kb3csIGBwaHg6JHtldmVudH1gLCB7IGRldGFpbDogcGF5bG9hZCB9KTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGRpc3BhdGNoRXZlbnRzKGV2ZW50cykge1xuICAgIGV2ZW50cy5mb3JFYWNoKChbZXZlbnQsIHBheWxvYWRdKSA9PiB0aGlzLmRpc3BhdGNoRXZlbnQoZXZlbnQsIHBheWxvYWQpKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIHdpdGhQYWdlTG9hZGluZyhpbmZvLCBjYWxsYmFjaykge1xuICAgIGRvbV9kZWZhdWx0LmRpc3BhdGNoRXZlbnQod2luZG93LCBcInBoeDpwYWdlLWxvYWRpbmctc3RhcnRcIiwgeyBkZXRhaWw6IGluZm8gfSk7XG4gICAgY29uc3QgZG9uZSA9ICgpID0+IGRvbV9kZWZhdWx0LmRpc3BhdGNoRXZlbnQod2luZG93LCBcInBoeDpwYWdlLWxvYWRpbmctc3RvcFwiLCB7IGRldGFpbDogaW5mbyB9KTtcbiAgICByZXR1cm4gY2FsbGJhY2sgPyBjYWxsYmFjayhkb25lKSA6IGRvbmU7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwdXNoSGlzdG9yeVBhdGNoKGUsIGhyZWYsIGxpbmtTdGF0ZSwgdGFyZ2V0RWwpIHtcbiAgICBpZiAoIXRoaXMuaXNDb25uZWN0ZWQoKSB8fCAhKHRoaXMubWFpbiAmJiB0aGlzLm1haW4uaXNNYWluKCkpKSB7XG4gICAgICByZXR1cm4gYnJvd3Nlcl9kZWZhdWx0LnJlZGlyZWN0KGhyZWYpO1xuICAgIH1cbiAgICB0aGlzLndpdGhQYWdlTG9hZGluZyh7IHRvOiBocmVmLCBraW5kOiBcInBhdGNoXCIgfSwgKGRvbmUpID0+IHtcbiAgICAgIHRoaXMubWFpbi5wdXNoTGlua1BhdGNoKGUsIGhyZWYsIHRhcmdldEVsLCAobGlua1JlZikgPT4ge1xuICAgICAgICB0aGlzLmhpc3RvcnlQYXRjaChocmVmLCBsaW5rU3RhdGUsIGxpbmtSZWYpO1xuICAgICAgICBkb25lKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGhpc3RvcnlQYXRjaChocmVmLCBsaW5rU3RhdGUsIGxpbmtSZWYgPSB0aGlzLnNldFBlbmRpbmdMaW5rKGhyZWYpKSB7XG4gICAgaWYgKCF0aGlzLmNvbW1pdFBlbmRpbmdMaW5rKGxpbmtSZWYpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY3VycmVudEhpc3RvcnlQb3NpdGlvbisrO1xuICAgIHRoaXMuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShcbiAgICAgIFBIWF9MVl9ISVNUT1JZX1BPU0lUSU9OLFxuICAgICAgdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uLnRvU3RyaW5nKClcbiAgICApO1xuICAgIGJyb3dzZXJfZGVmYXVsdC51cGRhdGVDdXJyZW50U3RhdGUoKHN0YXRlKSA9PiAoeyAuLi5zdGF0ZSwgYmFja1R5cGU6IFwicGF0Y2hcIiB9KSk7XG4gICAgYnJvd3Nlcl9kZWZhdWx0LnB1c2hTdGF0ZShcbiAgICAgIGxpbmtTdGF0ZSxcbiAgICAgIHtcbiAgICAgICAgdHlwZTogXCJwYXRjaFwiLFxuICAgICAgICBpZDogdGhpcy5tYWluLmlkLFxuICAgICAgICBwb3NpdGlvbjogdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uXG4gICAgICB9LFxuICAgICAgaHJlZlxuICAgICk7XG4gICAgZG9tX2RlZmF1bHQuZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4Om5hdmlnYXRlXCIsIHtcbiAgICAgIGRldGFpbDogeyBwYXRjaDogdHJ1ZSwgaHJlZiwgcG9wOiBmYWxzZSwgZGlyZWN0aW9uOiBcImZvcndhcmRcIiB9XG4gICAgfSk7XG4gICAgdGhpcy5yZWdpc3Rlck5ld0xvY2F0aW9uKHdpbmRvdy5sb2NhdGlvbik7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBoaXN0b3J5UmVkaXJlY3QoZSwgaHJlZiwgbGlua1N0YXRlLCBmbGFzaCwgdGFyZ2V0RWwpIHtcbiAgICBjb25zdCBjbGlja0xvYWRpbmcgPSB0YXJnZXRFbCAmJiBlLmlzVHJ1c3RlZCAmJiBlLnR5cGUgIT09IFwicG9wc3RhdGVcIjtcbiAgICBpZiAoY2xpY2tMb2FkaW5nKSB7XG4gICAgICB0YXJnZXRFbC5jbGFzc0xpc3QuYWRkKFwicGh4LWNsaWNrLWxvYWRpbmdcIik7XG4gICAgfVxuICAgIGlmICghdGhpcy5pc0Nvbm5lY3RlZCgpIHx8ICEodGhpcy5tYWluICYmIHRoaXMubWFpbi5pc01haW4oKSkpIHtcbiAgICAgIHJldHVybiBicm93c2VyX2RlZmF1bHQucmVkaXJlY3QoaHJlZiwgZmxhc2gpO1xuICAgIH1cbiAgICBpZiAoL15cXC8kfF5cXC9bXlxcL10rLiokLy50ZXN0KGhyZWYpKSB7XG4gICAgICBjb25zdCB7IHByb3RvY29sLCBob3N0IH0gPSB3aW5kb3cubG9jYXRpb247XG4gICAgICBocmVmID0gYCR7cHJvdG9jb2x9Ly8ke2hvc3R9JHtocmVmfWA7XG4gICAgfVxuICAgIGNvbnN0IHNjcm9sbCA9IHdpbmRvdy5zY3JvbGxZO1xuICAgIHRoaXMud2l0aFBhZ2VMb2FkaW5nKHsgdG86IGhyZWYsIGtpbmQ6IFwicmVkaXJlY3RcIiB9LCAoZG9uZSkgPT4ge1xuICAgICAgdGhpcy5yZXBsYWNlTWFpbihocmVmLCBmbGFzaCwgKGxpbmtSZWYpID0+IHtcbiAgICAgICAgaWYgKGxpbmtSZWYgPT09IHRoaXMubGlua1JlZikge1xuICAgICAgICAgIHRoaXMuY3VycmVudEhpc3RvcnlQb3NpdGlvbisrO1xuICAgICAgICAgIHRoaXMuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShcbiAgICAgICAgICAgIFBIWF9MVl9ISVNUT1JZX1BPU0lUSU9OLFxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uLnRvU3RyaW5nKClcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyb3dzZXJfZGVmYXVsdC51cGRhdGVDdXJyZW50U3RhdGUoKHN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICBiYWNrVHlwZTogXCJyZWRpcmVjdFwiXG4gICAgICAgICAgfSkpO1xuICAgICAgICAgIGJyb3dzZXJfZGVmYXVsdC5wdXNoU3RhdGUoXG4gICAgICAgICAgICBsaW5rU3RhdGUsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgI
1HR5cGU6IFwicmVkaXJlY3RcIixcbiAgICAgICAgICAgICAgaWQ6IHRoaXMubWFpbi5pZCxcbiAgICAgICAgICAgICAgc2Nyb2xsLFxuICAgICAgICAgICAgICBwb3NpdGlvbjogdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaHJlZlxuICAgICAgICAgICk7XG4gICAgICAgICAgZG9tX2RlZmF1bHQuZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4Om5hdmlnYXRlXCIsIHtcbiAgICAgICAgICAgIGRldGFpbDogeyBocmVmLCBwYXRjaDogZmFsc2UsIHBvcDogZmFsc2UsIGRpcmVjdGlvbjogXCJmb3J3YXJkXCIgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMucmVnaXN0ZXJOZXdMb2NhdGlvbih3aW5kb3cubG9jYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjbGlja0xvYWRpbmcpIHtcbiAgICAgICAgICB0YXJnZXRFbC5jbGFzc0xpc3QucmVtb3ZlKFwicGh4LWNsaWNrLWxvYWRpbmdcIik7XG4gICAgICAgIH1cbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICByZWdpc3Rlck5ld0xvY2F0aW9uKG5ld0xvY2F0aW9uKSB7XG4gICAgY29uc3QgeyBwYXRobmFtZSwgc2VhcmNoIH0gPSB0aGlzLmN1cnJlbnRMb2NhdGlvbjtcbiAgICBpZiAocGF0aG5hbWUgKyBzZWFyY2ggPT09IG5ld0xvY2F0aW9uLnBhdGhuYW1lICsgbmV3TG9jYXRpb24uc2VhcmNoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3VycmVudExvY2F0aW9uID0gY2xvbmUobmV3TG9jYXRpb24pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgYmluZEZvcm1zKCkge1xuICAgIGxldCBpdGVyYXRpb25zID0gMDtcbiAgICBsZXQgZXh0ZXJuYWxGb3JtU3VibWl0dGVkID0gZmFsc2U7XG4gICAgdGhpcy5vbihcInN1Ym1pdFwiLCAoZSkgPT4ge1xuICAgICAgaWYgKCEoZS50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRm9ybUVsZW1lbnQpKVxuICAgICAgICByZXR1cm47XG4gICAgICBjb25zdCBwaHhTdWJtaXQgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwic3VibWl0XCIpKTtcbiAgICAgIGNvbnN0IHBoeENoYW5nZSA9IGUudGFyZ2V0LmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoXCJjaGFuZ2VcIikpO1xuICAgICAgaWYgKCFleHRlcm5hbEZvcm1TdWJtaXR0ZWQgJiYgcGh4Q2hhbmdlICYmICFwaHhTdWJtaXQpIHtcbiAgICAgICAgZXh0ZXJuYWxGb3JtU3VibWl0dGVkID0gdHJ1ZTtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLndpdGhpbk93bmVycyhlLnRhcmdldCwgKHZpZXcpID0+IHtcbiAgICAgICAgICB2aWV3LmRpc2FibGVGb3JtKGUudGFyZ2V0KTtcbiAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgIGlmIChkb21fZGVmYXVsdC5pc1VubG9hZGFibGVGb3JtU3VibWl0KGUpKSB7XG4gICAgICAgICAgICAgIHRoaXMudW5sb2FkKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlLnRhcmdldC5zdWJtaXQoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5vbihcInN1Ym1pdFwiLCAoZSkgPT4ge1xuICAgICAgaWYgKCEoZS50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRm9ybUVsZW1lbnQpKVxuICAgICAgICByZXR1cm47XG4gICAgICBjb25zdCBwaHhFdmVudCA9IGUudGFyZ2V0LmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoXCJzdWJtaXRcIikpO1xuICAgICAgaWYgKCFwaHhFdmVudCkge1xuICAgICAgICBpZiAoZG9tX2RlZmF1bHQuaXNVbmxvYWRhYmxlRm9ybVN1Ym1pdChlKSkge1xuICAgICAgICAgIHRoaXMudW5sb2FkKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZS50YXJnZXQuZGlzYWJsZWQgPSB0cnVlO1xuICAgICAgdGhpcy53aXRoaW5Pd25lcnMoZS50YXJnZXQsICh2aWV3KSA9PiB7XG4gICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCBcInN1Ym1pdFwiLCBwaHhFdmVudCwgdmlldywgZS50YXJnZXQsIFtcbiAgICAgICAgICBcInB1c2hcIixcbiAgICAgICAgICB7IHN1Ym1pdHRlcjogZS5zdWJtaXR0ZXIgfVxuICAgICAgICBdKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGZvciAoY29uc3QgdHlwZSBvZiBbXCJjaGFuZ2VcIiwgXCJpbnB1dFwiXSkge1xuICAgICAgdGhpcy5vbih0eXBlLCAoZSkgPT4ge1xuICAgICAgICBpZiAoIWRvbV9kZWZhdWx0LmlzRm9ybUFzc29jaWF0ZWQoZS50YXJnZXQpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlIGluc3RhbmNlb2YgQ3VzdG9tRXZlbnQgJiYgZS50YXJnZXQuZm9ybSA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgaWYgKGUuZGV0YWlsICYmIGUuZGV0YWlsLmRpc3BhdGNoZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYGRpc3BhdGNoaW5nIGEgY3VzdG9tICR7dHlwZX0gZXZlbnQgaXMgb25seSBzdXBwb3J0ZWQgb24gaW5wdXQgZWxlbWVudHMgaW5zaWRlIGEgZm9ybWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbnB1dCA9IGUudGFyZ2V0O1xuICAgICAgICBjb25zdCBwaHhDaGFuZ2UgPSB0aGlzLmJpbmRpbmcoXCJjaGFuZ2VcIik7XG4gICAgICAgIGlmICh0aGlzLmJsb2NrUGh4Q2hhbmdlV2hpbGVDb21wb3NpbmcgJiYgZSBpbnN0YW5jZW9mIElucHV0RXZlbnQgJiYgZS5pc0NvbXBvc2luZykge1xuICAgICAgICAgIGNvbnN0IGtleSA9IGBjb21wb3NpdGlvbi1saXN0ZW5lci0ke3R5cGV9YDtcbiAgICAgICAgICBpZiAoIWRvbV9kZWZhdWx0LnByaXZhdGUoaW5wdXQsIGtleSkpIHtcbiAgICAgICAgICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUoaW5wdXQsIGtleSwgdHJ1ZSk7XG4gICAgICAgICAgICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICBcImNvbXBvc2l0aW9uZW5kXCIsXG4gICAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBpbnB1dC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCh0eXBlLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgICAgICAgICAgICAgIGRvbV9kZWZhdWx0LmRlbGV0ZVByaXZhdGUoaW5wdXQsIGtleSk7XG4gICAgICAgICAgICAgI
1H0sXG4gICAgICAgICAgICAgIHsgb25jZTogdHJ1ZSB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW5wdXRFdmVudCA9IGlucHV0LmdldEF0dHJpYnV0ZShwaHhDaGFuZ2UpO1xuICAgICAgICBjb25zdCBmb3JtRXZlbnQgPSBpbnB1dC5mb3JtICYmIGlucHV0LmZvcm0uZ2V0QXR0cmlidXRlKHBoeENoYW5nZSk7XG4gICAgICAgIGNvbnN0IHBoeEV2ZW50ID0gaW5wdXRFdmVudCB8fCBmb3JtRXZlbnQ7XG4gICAgICAgIGlmICghcGh4RXZlbnQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0LnR5cGUgPT09IFwibnVtYmVyXCIgJiYgaW5wdXQudmFsaWRpdHkgJiYgaW5wdXQudmFsaWRpdHkuYmFkSW5wdXQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGlzcGF0Y2hlciA9IGlucHV0RXZlbnQgPyBpbnB1dCA6IGlucHV0LmZvcm07XG4gICAgICAgIGNvbnN0IGN1cnJlbnRJdGVyYXRpb25zID0gaXRlcmF0aW9ucztcbiAgICAgICAgaXRlcmF0aW9ucysrO1xuICAgICAgICBjb25zdCB7IGF0LCB0eXBlOiBsYXN0VHlwZSB9ID0gZG9tX2RlZmF1bHQucHJpdmF0ZShpbnB1dCwgXCJwcmV2LWl0ZXJhdGlvblwiKSB8fCB7fTtcbiAgICAgICAgaWYgKGF0ID09PSBjdXJyZW50SXRlcmF0aW9ucyAtIDEgJiYgdHlwZSA9PT0gXCJjaGFuZ2VcIiAmJiBsYXN0VHlwZSA9PT0gXCJpbnB1dFwiKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUoaW5wdXQsIFwicHJldi1pdGVyYXRpb25cIiwge1xuICAgICAgICAgIGF0OiBjdXJyZW50SXRlcmF0aW9ucyxcbiAgICAgICAgICB0eXBlXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRlYm91bmNlKGlucHV0LCBlLCB0eXBlLCAoKSA9PiB7XG4gICAgICAgICAgdGhpcy53aXRoaW5Pd25lcnMoZGlzcGF0Y2hlciwgKHZpZXcpID0+IHtcbiAgICAgICAgICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUoaW5wdXQsIFBIWF9IQVNfRk9DVVNFRCwgdHJ1ZSk7XG4gICAgICAgICAgICBqc19kZWZhdWx0LmV4ZWMoZSwgXCJjaGFuZ2VcIiwgcGh4RXZlbnQsIHZpZXcsIGlucHV0LCBbXG4gICAgICAgICAgICAgIFwicHVzaFwiLFxuICAgICAgICAgICAgICB7IF90YXJnZXQ6IGlucHV0Lm5hbWUsIGRpc3BhdGNoZXIgfVxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMub24oXCJyZXNldFwiLCAoZSkgPT4ge1xuICAgICAgY29uc3QgZm9ybSA9IGUudGFyZ2V0O1xuICAgICAgZG9tX2RlZmF1bHQucmVzZXRGb3JtKGZvcm0pO1xuICAgICAgY29uc3QgaW5wdXQgPSBBcnJheS5mcm9tKGZvcm0uZWxlbWVudHMpLmZpbmQoXG4gICAgICAgIChlbCkgPT4gXCJ0eXBlXCIgaW4gZWwgJiYgZWwudHlwZSA9PT0gXCJyZXNldFwiXG4gICAgICApO1xuICAgICAgaWYgKGlucHV0KSB7XG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgIGlucHV0LmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgICBuZXcgRXZlbnQoXCJpbnB1dFwiLCB7IGJ1YmJsZXM6IHRydWUsIGNhbmNlbGFibG
1U6IGZhbHNlIH0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBkZWJvdW5jZShlbCwgZXZlbnQsIGV2ZW50VHlwZSwgY2FsbGJhY2spIHtcbiAgICBpZiAoZXZlbnRUeXBlID09PSBcImJsdXJcIiB8fCBldmVudFR5cGUgPT09IFwiZm9jdXNvdXRcIikge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfVxuICAgIGNvbnN0IHBoeERlYm91bmNlID0gdGhpcy5iaW5kaW5nKFBIWF9ERUJPVU5DRSk7XG4gICAgY29uc3QgcGh4VGhyb3R0bGUgPSB0aGlzLmJpbmRpbmcoUEhYX1RIUk9UVExFKTtcbiAgICBjb25zdCBkZWZhdWx0RGVib3VuY2UgPSB0aGlzLmRlZmF1bHRzLmRlYm91bmNlLnRvU3RyaW5nKCk7XG4gICAgY29uc3QgZGVmYXVsdFRocm90dGxlID0gdGhpcy5kZWZhdWx0cy50aHJvdHRsZS50b1N0cmluZygpO1xuICAgIHRoaXMud2l0aGluT3duZXJzKGVsLCAodmlldykgPT4ge1xuICAgICAgY29uc3QgYXN5bmNGaWx0ZXIgPSAoKSA9PiAhdmlldy5pc0Rlc3Ryb3llZCgpICYmIGRvY3VtZW50LmJvZHkuY29udGFpbnMoZWwpO1xuICAgICAgZG9tX2RlZmF1bHQuZGVib3VuY2UoXG4gICAgICAgIGVsLFxuICAgICAgICBldmVudCxcbiAgICAgICAgcGh4RGVib3VuY2UsXG4gICAgICAgIGRlZmF1bHREZWJvdW5jZSxcbiAgICAgICAgcGh4VGhyb3R0bGUsXG4gICAgICAgIGRlZmF1bHRUaHJvdHRsZSxcbiAgICAgICAgYXN5bmNGaWx0ZXIsXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgc2lsZW5jZUV2ZW50cyhjYWxsYmFjaykge1xuICAgIHRoaXMuc2lsZW5jZWQgPSB0cnVlO1xuICAgIGNhbGxiYWNrKCk7XG4gICAgdGhpcy5zaWxlbmNlZCA9IGZhbHNlO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgb24oZXZlbnQsIGNhbGxiYWNrKSB7XG4gICAgdGhpcy5ib3VuZEV2ZW50TmFtZXMuYWRkKGV2ZW50KTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgKGUpID0+IHtcbiAgICAgIGlmICghdGhpcy5zaWxlbmNlZCkge1xuICAgICAgICBjYWxsYmFjayhlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGpzUXVlcnlTZWxlY3RvckFsbChzb3VyY2VFbCwgcXVlcnksIGRlZmF1bHRRdWVyeSkge1xuICAgIGNvbnN0IGFsbCA9IHRoaXMuZG9tQ2FsbGJhY2tzLmpzUXVlcnlTZWxlY3RvckFsbDtcbiAgICByZXR1cm4gYWxsID8gYWxsKHNvdXJjZUVsLCBxdWVyeSwgZGVmYXVsdFF1ZXJ5KSA6IGRlZmF1bHRRdWVyeSgpO1xuICB9XG59O1xudmFyIFRyYW5zaXRpb25TZXQgPSBjbGFzcyB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMudHJhbnNpdGlvbnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICAgIHRoaXMucHJvbWlzZXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICAgIHRoaXMucGVuZGluZ09wcyA9IFtdO1xuICB9XG4gIHJlc2V0KCkge1xuICAgIHRoaXMudHJhbnNpdGlvbnMuZm9yRWFjaCgodGltZXIpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICB0aGlzLnRyYW5zaXRpb25zLmRlbGV0ZSh0aW1lcik7XG4gICAgfSk7XG4gICAgdGhpcy5wcm9taXNlcy5jbGVhcigpO1xuICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKCk7XG4gIH1cbiAgYWZ0ZXIoY2FsbGJhY2spIHtcbiAgICBpZiAodGhpcy5zaXplKCkgPT09IDApIHtcbiAgICAgIGNhbGxiYWNrKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHVzaFBlbmRpbmdPcChjYWxsYmFjayk7XG4gICAgfVxuICB9XG4gIGFkZFRyYW5zaXRpb24odGltZSwgb25TdGFydCwgb25Eb25lKSB7XG4gICAgb25TdGFydCgpO1xuICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnRyYW5zaXRpb25zLmRlbGV0ZSh0aW1lcik7XG4gICAgICBvbkRvbmUoKTtcbiAgICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKCk7XG4gICAgfSwgdGltZSk7XG4gICAgdGhpcy50cmFuc2l0aW9ucy5hZGQodGltZXIpO1xuICB9XG4gIGFkZEFzeW5jVHJhbnNpdGlvbihwcm9taXNlKSB7XG4gICAgdGhpcy5wcm9taXNlcy5hZGQocHJvbWlzZSk7XG4gICAgcHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMucHJvbWlzZXMuZGVsZXRlKHByb21pc2UpO1xuICAgICAgdGhpcy5mbHVzaFBlbmRpbmdPcHMoKTtcbiAgICB9KTtcbiAgfVxuICBwdXNoUGVuZGluZ09wKG9wKSB7XG4gICAgdGhpcy5wZW5kaW5nT3BzLnB1c2gob3ApO1xuICB9XG4gIHNpemUoKSB7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNpdGlvbnMuc2l6ZSArIHRoaXMucHJvbWlzZXMuc2l6ZTtcbiAgfVxuICBmbHVzaFBlbmRpbmdPcHMoKSB7XG4gICAgaWYgKHRoaXMuc2l6ZSgpID4gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBvcCA9IHRoaXMucGVuZGluZ09wcy5zaGlmdCgpO1xuICAgIGlmIChvcCkge1xuICAgICAgb3AoKTtcbiAgICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKCk7XG4gICAgfVxuICB9XG59O1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy9pbmRleC50c1xuZnVuY3Rpb24gY3JlYXRlSG9vayhlbCwgY2FsbGJhY2tzKSB7XG4gIGxldCBleGlzdGluZ0hvb2sgPSBkb21fZGVmYXVsdC5nZXRDdXN0b21FbEhvb2soZWwpO1xuICBpZiAoZXhpc3RpbmdIb29rKSB7XG4gICAgcmV0dXJuIGV4aXN0aW5nSG9vaztcbiAgfVxuICBpZiAoIWVsLmhhc0F0dHJpYnV0ZShcImlkXCIpKSB7XG4gICAgbG9nRXJyb3IoXG4gICAgICBcIkVsZW1lbnRzIHBhc3NlZCB0byBjcmVhdGVIb29rIG5lZWQgdG8gaGF2ZSBhIHVuaXF1ZSBpZCBhdHRyaWJ1dGVcIixcbiAgICAgIGVsXG4gICAgKTtcbiAgfVxuICBsZXQgaG9vayA9IG5ldyBWaWV3SG9vayhWaWV3LmNsb3Nlc3RWaWV3KGVsKSwgZWwsIGNhbGxiYWNrcyk7XG4gIGRvbV9kZWZhdWx0LnB1dEN1c3RvbUVsSG9vayhlbCwgaG9vayk7XG4gIHJldHVybiBob29rO1xufVxuZnVuY3Rpb24gZ2V0RmlsZVVSTEZvclVwbG9hZChpbnB1dCwgdXBsb2FkUmVmKSB7XG4gIHJldHVybi
1BMaXZlVXBsb2FkZXIuZ2V0RW50cnlEYXRhVVJMKGlucHV0LCB1cGxvYWRSZWYpO1xufVxuZXhwb3J0IHtcbiAgTGl2ZVNvY2tldCxcbiAgVmlld0hvb2ssXG4gIGNyZWF0ZUhvb2ssXG4gIGdldEZpbGVVUkxGb3JVcGxvYWQsXG4gIGlzVXNlZElucHV0XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGhvZW5peF9saXZlX3ZpZXcuZXNtLmpzLm1hcFxuIiwiZnVuY3Rpb24gbyhlLHQpe2xldCBpO3JldHVybiguLi5zKT0+e2NsZWFyVGltZW91dChpKSxpPXNldFRpbWVvdXQoKCk9PntlLmFwcGx5KHRoaXMscyl9LHQpfX1leHBvcnQgZGVmYXVsdHtMaXZlU2VsZWN0Ont0ZXh0SW5wdXQoKXtyZXR1cm4gdGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiaW5wdXRbdHlwZT10ZXh0XVwiKX0sZGVib3VuY2VNc2VjKCl7cmV0dXJuIHBhcnNlSW50KHRoaXMuZWwuZGF0YXNldC5kZWJvdW5jZSl9LHVwZGF0ZU1pbkxlbigpe3JldHVybiBwYXJzZUludCh0aGlzLmVsLmRhdGFzZXQudXBkYXRlTWluTGVuKX0sbWF5YmVTdHlsZUNsZWFyQnV0dG9ucygpe2NvbnN0IGU9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiYnV0dG9uLmxzLWNsZWFyLWJ1dHRvblwiKTtlJiYodGhpcy50ZXh0SW5wdXQoKS5wYXJlbnRFbGVtZW50LnN0eWxlLnBvc2l0aW9uPVwicmVsYXRpdmVcIix0aGlzLnRleHRJbnB1dCgpLnBhcmVudEVsZW1lbnQuc3R5bGUuZGlzcGxheT1cImZsZXhcIix0aGlzLnRleHRJbnB1dCgpLnBhcmVudEVsZW1lbnQuc3R5bGUuYWxpZ25JdGVtcz1cImNlbnRlclwiLGUuc3R5bGUubWluSGVpZ2h0PVwiMjBweFwiLGUuc3R5bGUubWluV2lkdGg9XCIyMHB4XCIsZS5zdHlsZS5wb3NpdGlvbj1cImFic29sdXRlXCIsZS5zdHlsZS5yaWdodD1cIjVweFwiLGUuc3R5bGUuZGlzcGxheT1cImJsb2NrXCIpLHRoaXMuZWwucXVlcnlTZWxlY3RvckFsbChcImJ1dHRvbi5scy1jbGVhci10YWctYnV0dG9uXCIpLmZvckVhY2godD0+e3Quc3R5bGUubWluSGVpZ2h0PVwiMjBweFwiLHQuc3R5bGUubWluV2lkdGg9XCIyMHB4XCJ9KX0scHVzaEV2ZW50VG9QYXJlbnQoZSx0KXtjb25zdCBpPXRoaXMuZWwuZGF0YXNldC5waHhUYXJnZXQ7aT90aGlzLnB1c2hFdmVudFRvKGksZSx0KTp0aGlzLnB1c2hFdmVudChlLHQpfSxhdHRhY2hEb21FdmVudEhhbmRsZXJzKCl7dGhpcy50ZXh0SW5wdXQoKS5vbmtleWRvd249dD0+e3QuY29kZT09PVwiRW50ZXJcIiYmdC5wcmV2ZW50RGVmYXVsdCgpLHRoaXMucHVzaEV2ZW50VG8odGhpcy5lbCxcImtleWRvd25cIix7a2V5OnQuY29kZX0pfSx0aGlzLmNoYW5nZUV2ZW50cz1vKCh0LGkscyk9Pnt0aGlzLnB1c2hFdmVudFRvKHRoaXMuZWwsXCJjaGFuZ2VcIix7dGV4dDpzfSksdGhpcy5wdXNoRXZlbnRUb1BhcmVudChcImxpdmVfc2VsZWN0X2NoYW5nZVwiLHtpZDp0aGlzLmVsLmlkLGZpZWxkOmksdGV4dDpzfSl9LHRoaXMuZGVib3VuY2VNc2VjKCkpLHRoaXMudGV4dElucHV0KCkub25pbnB1dD10PT57Y29uc3QgaT10LnRhcmdldC52YWx1ZS50cmltKCkscz10aGlzLmVsLmRhdGFzZXQuZmllbGQ7aS5sZW5ndGg+PXRoaXMudXBkYXRlTWluTGVuKCk/dGhpcy5jaGFuZ2VFdmVudHModGhpcy5lbC5pZCxzLGkpOnRoaXMucHVzaEV2ZW50VG8odGhpcy5lbCxcIm9wdGlvbnNfY2xlYXJcIix7fSl9O2NvbnN0IGU9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwidWxcIik7ZSYmKGUub25tb3VzZWRvd249dD0+e2NvbnN0IGk9dC50YXJnZXQuY2xvc2VzdChcImRpdltkYXRhLWlkeF1cIik7aSYmKHRoaXMucHVzaEV2ZW50VG8odGhpcy5lbCxcIm9wdGlvbl9jbGlja1wiLHtpZHg6aS5kYXRhc2V0LmlkeH0pLHQucHJldmVudERlZmF1bHQoKSl9KSx0aGlzLmVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCJidXR0b25bZGF0YS1pZHhdXCIpLmZvckVhY2godD0+e3Qub25jbGljaz1pPT57dGhpcy5wdXNoRXZlbnRUbyh0aGlzLmVsLFwib3B0aW9uX3JlbW92ZVwiLHtpZHg6dC5kYXRhc2V0LmlkeH0pfX0pfSxzZXRJbnB1dFZhbHVlKGUpe3RoaXMudGV4dElucHV0KCkudmFsdWU9ZX0saW5wdXRFdmVudChlLHQpe2NvbnN0IGk9dD09PVwic2luZ2xlXCI/XCJpbnB1dC5zaW5nbGUtbW9kZVwiOmUubGVuZ3RoPT09MD9cImlucHV0W2RhdGEtbGl2ZS1zZWxlY3QtZW1wdHldXCI6XCJpbnB1dFt0eXBlPWhpZGRlbl1cIjt0aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoaSkuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJpbnB1dFwiLHtidWJibGVzOiEwfSkpfSxtb3VudGVkKCl7dGhpcy5tYXliZVN0eWxlQ2xlYXJCdXR0b25zKCksdGhpcy5oYW5kbGVFdmVudChcInNlbGVjdFwiLCh7aWQ6ZSxzZWxlY3Rpb246dCxtb2RlOmksY3VycmVudF90ZXh0OnMsaW5wdXRfZXZlbnQ6bCxwYXJlbnRfZXZlbnQ6bn0pPT57dGhpcy5lbC5pZD09PWUmJih0aGlzLnNlbGVjdGlvbj10LHMhPW51bGwmJnRoaXMuc2V0SW5wdXRWYWx1ZShzKSxsJiZ0aGlzLmlucHV0RXZlbnQodCxpKSxuJiZ0aGlzLnB1c2hFdmVudFRvUGFyZW50KG4se2lkOmV9KSl9KSx0aGlzLmhhbmRsZUV2ZW50KFwic2Nyb2xsX3RvX29wdGlvblwiLCh7aWQ6ZSxpZHg6dH0pPT57aWYodGhpcy5lbC5pZD09PWUpe2NvbnN0IGk9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKGBkaXZbZGF0YS1pZHg9XCIke3R9XCJdYCk7aSYmaS5zY3JvbGxJbnRvVmlldyh7YmxvY2s6XCJuZWFyZXN0XCIsYmVoYXZpb3I6XCJpbnN0YW50XCIsY29udGFpbmVyOlwibmVhcmVzdFwifSl9fSksdGhpcy5hdHRhY2hEb21FdmVudEhhbmRsZXJzKCl9LHVwZGF0ZWQoKXt0aGlzLm1heWJlU3R5bGVDbGVhckJ1dHRvbnMoKSx0aGlzLmF0dGFjaERvbUV2ZW50SGFuZGxlcnMoKX0scmVjb25uZWN0ZWQoKXt0aGlzLnNlbGVjdGlvbiYmdGhpcy5zZWxlY3Rpb24ubGVuZ3RoPjAmJnRoaXMucHVzaEV2ZW50VG8odGhpcy5lbCxcInNlbGVjdGlvbl9yZWNvdmVyeVwiLHRoaXMuc2VsZWN0aW9uKX19fTtcbiIsIi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9zY2hlZHVsZXIuanNcbnZhciBmbHVzaFBlbmRpbmcgPSBmYWxzZTtcbnZhciBmbHVzaGluZyA9IGZhbHNlO1xudmFyIHF1ZXVlID0gW107XG52YXIgbGFzdEZsdXNoZWRJbmRleCA9IC0xO1xuZnVuY3Rpb24gc2NoZWR1bGVyKGNhbGxiYWNrKSB7XG4gIHF1ZXVlSm9iKGNhbGxiYWNrKTtcbn1cbmZ1bmN0aW9uIHF1ZXVlSm9iKGpvYikge1xuICBpZiAoIXF1ZXVlLmluY2x1ZGVzKGpvYikpXG4gICAgcXVldWUucHVzaChqb2IpO1xuICBxdWV1ZUZsdXNoKCk7XG59XG5mdW5jdGlvbiBkZXF1ZXVlSm9iKGpvYikge1xuICBsZXQgaW5kZXggPSBxdWV1ZS5pbmRleE9mKGpvYik7XG4gIGlmIChpbmRleCAhPT0gLTEgJiYgaW5kZXggPiBsYXN0Rmx1c2hlZEluZGV4KVxuICAgIHF1ZXVlLnNwbGljZShpbmRleCwgMSk7XG59XG5mdW5jdGlvbiBxdWV1ZUZsdXNoKCkge1xuICBpZiAoIWZsdXNoaW5nICYmICFmbHVzaFBlbmRpbmcpIHtcbiAgICBmbHVzaFBlbmRpbmcgPSB0cnVlO1xuICAgIHF1ZXVlTWljcm90YXNrKGZsdXNoSm9icyk7XG4gIH1cbn1cbmZ1bmN0aW9uIGZsdXNoSm9icygpIHtcbiAgZmx1c2hQZW5kaW5nID0gZmFsc2U7XG4gIGZsdXNoaW5nID0gdHJ1ZTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBxdWV1ZS5sZW5ndGg7IGkrKykge1xuICAgIHF1ZXVlW2ldKCk7XG4gICAgbGFzdEZsdXNoZWRJbmRleCA9IG
1k7XG4gIH1cbiAgcXVldWUubGVuZ3RoID0gMDtcbiAgbGFzdEZsdXNoZWRJbmRleCA9IC0xO1xuICBmbHVzaGluZyA9IGZhbHNlO1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvcmVhY3Rpdml0eS5qc1xudmFyIHJlYWN0aXZlO1xudmFyIGVmZmVjdDtcbnZhciByZWxlYXNlO1xudmFyIHJhdztcbnZhciBzaG91bGRTY2hlZHVsZSA9IHRydWU7XG5mdW5jdGlvbiBkaXNhYmxlRWZmZWN0U2NoZWR1bGluZyhjYWxsYmFjaykge1xuICBzaG91bGRTY2hlZHVsZSA9IGZhbHNlO1xuICBjYWxsYmFjaygpO1xuICBzaG91bGRTY2hlZHVsZSA9IHRydWU7XG59XG5mdW5jdGlvbiBzZXRSZWFjdGl2aXR5RW5naW5lKGVuZ2luZSkge1xuICByZWFjdGl2ZSA9IGVuZ2luZS5yZWFjdGl2ZTtcbiAgcmVsZWFzZSA9IGVuZ2luZS5yZWxlYXNlO1xuICBlZmZlY3QgPSAoY2FsbGJhY2spID0+IGVuZ2luZS5lZmZlY3QoY2FsbGJhY2ssIHtzY2hlZHVsZXI6ICh0YXNrKSA9PiB7XG4gICAgaWYgKHNob3VsZFNjaGVkdWxlKSB7XG4gICAgICBzY2hlZHVsZXIodGFzayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRhc2soKTtcbiAgICB9XG4gIH19KTtcbiAgcmF3ID0gZW5naW5lLnJhdztcbn1cbmZ1bmN0aW9uIG92ZXJyaWRlRWZmZWN0KG92ZXJyaWRlKSB7XG4gIGVmZmVjdCA9IG92ZXJyaWRlO1xufVxuZnVuY3Rpb24gZWxlbWVudEJvdW5kRWZmZWN0KGVsKSB7XG4gIGxldCBjbGVhbnVwMiA9ICgpID0+IHtcbiAgfTtcbiAgbGV0IHdyYXBwZWRFZmZlY3QgPSAoY2FsbGJhY2spID0+IHtcbiAgICBsZXQgZWZmZWN0UmVmZXJlbmNlID0gZWZmZWN0KGNhbGxiYWNrKTtcbiAgICBpZiAoIWVsLl94X2VmZmVjdHMpIHtcbiAgICAgIGVsLl94X2VmZmVjdHMgPSBuZXcgU2V0KCk7XG4gICAgICBlbC5feF9ydW5FZmZlY3RzID0gKCkgPT4ge1xuICAgICAgICBlbC5feF9lZmZlY3RzLmZvckVhY2goKGkpID0+IGkoKSk7XG4gICAgICB9O1xuICAgIH1cbiAgICBlbC5feF9lZmZlY3RzLmFkZChlZmZlY3RSZWZlcmVuY2UpO1xuICAgIGNsZWFudXAyID0gKCkgPT4ge1xuICAgICAgaWYgKGVmZmVjdFJlZmVyZW5jZSA9PT0gdm9pZCAwKVxuICAgICAgICByZXR1cm47XG4gICAgICBlbC5feF9lZmZlY3RzLmRlbGV0ZShlZmZlY3RSZWZlcmVuY2UpO1xuICAgICAgcmVsZWFzZShlZmZlY3RSZWZlcmVuY2UpO1xuICAgIH07XG4gICAgcmV0dXJuIGVmZmVjdFJlZmVyZW5jZTtcbiAgfTtcbiAgcmV0dXJuIFt3cmFwcGVkRWZmZWN0LCAoKSA9PiB7XG4gICAgY2xlYW51cDIoKTtcbiAgfV07XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tdXRhdGlvbi5qc1xudmFyIG9uQXR0cmlidXRlQWRkZWRzID0gW107XG52YXIgb25FbFJlbW92ZWRzID0gW107XG52YXIgb25FbEFkZGVkcyA9IFtdO1xuZnVuY3Rpb24gb25FbEFkZGVkKGNhbGxiYWNrKSB7XG4gIG9uRWxBZGRlZHMucHVzaChjYWxsYmFjayk7XG59XG5mdW5jdGlvbiBvbkVsUmVtb3ZlZChlbCwgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgaWYgKCFlbC5feF9jbGVhbnVwcylcbiAgICAgIGVsLl94X2NsZWFudXBzID0gW107XG4gICAgZWwuX3hfY2xlYW51cHMucHVzaChjYWxsYmFjayk7XG4gIH0gZWxzZSB7XG4gICAgY2FsbGJhY2sgPSBlbDtcbiAgICBvbkVsUmVtb3ZlZHMucHVzaChjYWxsYmFjayk7XG4gIH1cbn1cbmZ1bmN0aW9uIG9uQXR0cmlidXRlc0FkZGVkKGNhbGxiYWNrKSB7XG4gIG9uQXR0cmlidXRlQWRkZWRzLnB1c2goY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gb25BdHRyaWJ1dGVSZW1vdmVkKGVsLCBuYW1lLCBjYWxsYmFjaykge1xuICBpZiAoIWVsLl94X2F0dHJpYnV0ZUNsZWFudXBzKVxuICAgIGVsLl94X2F0dHJpYnV0ZUNsZWFudXBzID0ge307XG4gIGlmICghZWwuX3hfYXR0cmlidXRlQ2xlYW51cHNbbmFtZV0pXG4gICAgZWwuX3hfYXR0cmlidXRlQ2xlYW51cHNbbmFtZV0gPSBbXTtcbiAgZWwuX3hfYXR0cmlidXRlQ2xlYW51cHNbbmFtZV0ucHVzaChjYWxsYmFjayk7XG59XG5mdW5jdGlvbiBjbGVhbnVwQXR0cmlidXRlcyhlbCwgbmFtZXMpIHtcbiAgaWYgKCFlbC5feF9hdHRyaWJ1dGVDbGVhbnVwcylcbiAgICByZXR1cm47XG4gIE9iamVjdC5lbnRyaWVzKGVsLl94X2F0dHJpYnV0ZUNsZWFudXBzKS5mb3JFYWNoKChbbmFtZSwgdmFsdWVdKSA9PiB7XG4gICAgaWYgKG5hbWVzID09PSB2b2lkIDAgfHwgbmFtZXMuaW5jbHVkZXMobmFtZSkpIHtcbiAgICAgIHZhbHVlLmZvckVhY2goKGkpID0+IGkoKSk7XG4gICAgICBkZWxldGUgZWwuX3hfYXR0cmlidXRlQ2xlYW51cHNbbmFtZV07XG4gICAgfVxuICB9KTtcbn1cbnZhciBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKG9uTXV0YXRlKTtcbnZhciBjdXJyZW50bHlPYnNlcnZpbmcgPSBmYWxzZTtcbmZ1bmN0aW9uIHN0YXJ0T2JzZXJ2aW5nTXV0YXRpb25zKCkge1xuICBvYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LCB7c3VidHJlZTogdHJ1ZSwgY2hpbGRMaXN0OiB0cnVlLCBhdHRyaWJ1dGVzOiB0cnVlLCBhdHRyaWJ1dGVPbGRWYWx1ZTogdHJ1ZX0pO1xuICBjdXJyZW50bHlPYnNlcnZpbmcgPSB0cnVlO1xufVxuZnVuY3Rpb24gc3RvcE9ic2VydmluZ011dGF0aW9ucygpIHtcbiAgZmx1c2hPYnNlcnZlcigpO1xuICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gIGN1cnJlbnRseU9ic2VydmluZyA9IGZhbHNlO1xufVxudmFyIHJlY29yZFF1ZXVlID0gW107XG52YXIgd2lsbFByb2Nlc3NSZWNvcmRRdWV1ZSA9IGZhbHNlO1xuZnVuY3Rpb24gZmx1c2hPYnNlcnZlcigpIHtcbiAgcmVjb3JkUXVldWUgPSByZWNvcmRRdWV1ZS5jb25jYXQob2JzZXJ2ZXIudGFrZVJlY29yZHMoKSk7XG4gIGlmIChyZWNvcmRRdWV1ZS5sZW5ndGggJiYgIXdpbGxQcm9jZXNzUmVjb3JkUXVldWUpIHtcbiAgICB3aWxsUHJvY2Vzc1JlY29yZFF1ZXVlID0gdHJ1ZTtcbiAgICBxdWV1ZU1pY3JvdGFzaygoKSA9PiB7XG4gICAgICBwcm9jZXNzUmVjb3JkUXVldWUoKTtcbiAgICAgIHdpbGxQcm9jZXNzUmVjb3JkUXVldWUgPSBmYWxzZTtcbiAgICB9KTtcbiAgfVxufVxuZnVuY3Rpb24gcHJvY2Vzc1JlY29yZFF1ZXVlKCkge1xuICBvbk11dGF0ZShyZWNvcmRRdWV1ZSk7XG4gIHJlY29yZFF1ZXVlLmxlbmd0aCA9IDA7XG59XG5mdW5jdGlvbiBtdXRhdGVEb20oY2FsbGJhY2spIHtcbiAgaWYgKCFjdXJyZW50bHlPYnNlcnZpbmcpXG4gICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gIHN0b3BPYnNlcnZpbmdNdXRhdGlvbnMoKTtcbiAgbGV0IHJlc3VsdCA9IGNhbGxiYWNrKCk7XG4gIHN0YXJ0T2JzZXJ2aW5nTXV0YXRpb25zKCk7XG4gIHJldHVybi
1ByZXN1bHQ7XG59XG52YXIgaXNDb2xsZWN0aW5nID0gZmFsc2U7XG52YXIgZGVmZXJyZWRNdXRhdGlvbnMgPSBbXTtcbmZ1bmN0aW9uIGRlZmVyTXV0YXRpb25zKCkge1xuICBpc0NvbGxlY3RpbmcgPSB0cnVlO1xufVxuZnVuY3Rpb24gZmx1c2hBbmRTdG9wRGVmZXJyaW5nTXV0YXRpb25zKCkge1xuICBpc0NvbGxlY3RpbmcgPSBmYWxzZTtcbiAgb25NdXRhdGUoZGVmZXJyZWRNdXRhdGlvbnMpO1xuICBkZWZlcnJlZE11dGF0aW9ucyA9IFtdO1xufVxuZnVuY3Rpb24gb25NdXRhdGUobXV0YXRpb25zKSB7XG4gIGlmIChpc0NvbGxlY3RpbmcpIHtcbiAgICBkZWZlcnJlZE11dGF0aW9ucyA9IGRlZmVycmVkTXV0YXRpb25zLmNvbmNhdChtdXRhdGlvbnMpO1xuICAgIHJldHVybjtcbiAgfVxuICBsZXQgYWRkZWROb2RlcyA9IFtdO1xuICBsZXQgcmVtb3ZlZE5vZGVzID0gW107XG4gIGxldCBhZGRlZEF0dHJpYnV0ZXMgPSBuZXcgTWFwKCk7XG4gIGxldCByZW1vdmVkQXR0cmlidXRlcyA9IG5ldyBNYXAoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtdXRhdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAobXV0YXRpb25zW2ldLnRhcmdldC5feF9pZ25vcmVNdXRhdGlvbk9ic2VydmVyKVxuICAgICAgY29udGludWU7XG4gICAgaWYgKG11dGF0aW9uc1tpXS50eXBlID09PSBcImNoaWxkTGlzdFwiKSB7XG4gICAgICBtdXRhdGlvbnNbaV0uYWRkZWROb2Rlcy5mb3JFYWNoKChub2RlKSA9PiBub2RlLm5vZGVUeXBlID09PSAxICYmIGFkZGVkTm9kZXMucHVzaChub2RlKSk7XG4gICAgICBtdXRhdGlvbnNbaV0ucmVtb3ZlZE5vZGVzLmZvckVhY2goKG5vZGUpID0+IG5vZGUubm9kZVR5cGUgPT09IDEgJiYgcmVtb3ZlZE5vZGVzLnB1c2gobm9kZSkpO1xuICAgIH1cbiAgICBpZiAobXV0YXRpb25zW2ldLnR5cGUgPT09IFwiYXR0cmlidXRlc1wiKSB7XG4gICAgICBsZXQgZWwgPSBtdXRhdGlvbnNbaV0udGFyZ2V0O1xuICAgICAgbGV0IG5hbWUgPSBtdXRhdGlvbnNbaV0uYXR0cmlidXRlTmFtZTtcbiAgICAgIGxldCBvbGRWYWx1ZSA9IG11dGF0aW9uc1tpXS5vbGRWYWx1ZTtcbiAgICAgIGxldCBhZGQyID0gKCkgPT4ge1xuICAgICAgICBpZiAoIWFkZGVkQXR0cmlidXRlcy5oYXMoZWwpKVxuICAgICAgICAgIGFkZGVkQXR0cmlidXRlcy5zZXQoZWwsIFtdKTtcbiAgICAgICAgYWRkZWRBdHRyaWJ1dGVzLmdldChlbCkucHVzaCh7bmFtZSwgdmFsdWU6IGVsLmdldEF0dHJpYnV0ZShuYW1lKX0pO1xuICAgICAgfTtcbiAgICAgIGxldCByZW1vdmUgPSAoKSA9PiB7XG4gICAgICAgIGlmICghcmVtb3ZlZEF0dHJpYnV0ZXMuaGFzKGVsKSlcbiAgICAgICAgICByZW1vdmVkQXR0cmlidXRlcy5zZXQoZWwsIFtdKTtcbiAgICAgICAgcmVtb3ZlZEF0dHJpYnV0ZXMuZ2V0KGVsKS5wdXNoKG5hbWUpO1xuICAgICAgfTtcbiAgICAgIGlmIChlbC5oYXNBdHRyaWJ1dGUobmFtZSkgJiYgb2xkVmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgYWRkMigpO1xuICAgICAgfSBlbHNlIGlmIChlbC5oYXNBdHRyaWJ1dGUobmFtZSkpIHtcbiAgICAgICAgcmVtb3ZlKCk7XG4gICAgICAgIGFkZDIoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlbW92ZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZW1vdmVkQXR0cmlidXRlcy5mb3JFYWNoKChhdHRycywgZWwpID0+IHtcbiAgICBjbGVhbnVwQXR0cmlidXRlcyhlbCwgYXR0cnMpO1xuICB9KTtcbiAgYWRkZWRBdHRyaWJ1dGVzLmZvckVhY2goKGF0dHJzLCBlbCkgPT4ge1xuICAgIG9uQXR0cmlidXRlQWRkZWRzLmZvckVhY2goKGkpID0+IGkoZWwsIGF0dHJzKSk7XG4gIH0pO1xuICBmb3IgKGxldCBub2RlIG9mIHJlbW92ZWROb2Rlcykge1xuICAgIGlmIChhZGRlZE5vZGVzLmluY2x1ZGVzKG5vZGUpKVxuICAgICAgY29udGludWU7XG4gICAgb25FbFJlbW92ZWRzLmZvckVhY2goKGkpID0+IGkobm9kZSkpO1xuICAgIGlmIChub2RlLl94X2NsZWFudXBzKSB7XG4gICAgICB3aGlsZSAobm9kZS5feF9jbGVhbnVwcy5sZW5ndGgpXG4gICAgICAgIG5vZGUuX3hfY2xlYW51cHMucG9wKCkoKTtcbiAgICB9XG4gIH1cbiAgYWRkZWROb2Rlcy5mb3JFYWNoKChub2RlKSA9PiB7XG4gICAgbm9kZS5feF9pZ25vcmVTZWxmID0gdHJ1ZTtcbiAgICBub2RlLl94X2lnbm9yZSA9IHRydWU7XG4gIH0pO1xuICBmb3IgKGxldCBub2RlIG9mIGFkZGVkTm9kZXMpIHtcbiAgICBpZiAocmVtb3ZlZE5vZGVzLmluY2x1ZGVzKG5vZGUpKVxuICAgICAgY29udGludWU7XG4gICAgaWYgKCFub2RlLmlzQ29ubmVjdGVkKVxuICAgICAgY29udGludWU7XG4gICAgZGVsZXRlIG5vZGUuX3hfaWdub3JlU2VsZjtcbiAgICBkZWxldGUgbm9kZS5feF9pZ25vcmU7XG4gICAgb25FbEFkZGVkcy5mb3JFYWNoKChpKSA9PiBpKG5vZGUpKTtcbiAgICBub2RlLl94X2lnbm9yZSA9IHRydWU7XG4gICAgbm9kZS5feF9pZ25vcmVTZWxmID0gdHJ1ZTtcbiAgfVxuICBhZGRlZE5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICBkZWxldGUgbm9kZS5feF9pZ25vcmVTZWxmO1xuICAgIGRlbGV0ZSBub2RlLl94X2lnbm9yZTtcbiAgfSk7XG4gIGFkZGVkTm9kZXMgPSBudWxsO1xuICByZW1vdmVkTm9kZXMgPSBudWxsO1xuICBhZGRlZEF0dHJpYnV0ZXMgPSBudWxsO1xuICByZW1vdmVkQXR0cmlidXRlcyA9IG51bGw7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9zY29wZS5qc1xuZnVuY3Rpb24gc2NvcGUobm9kZSkge1xuICByZXR1cm4gbWVyZ2VQcm94aWVzKGNsb3Nlc3REYXRhU3RhY2sobm9kZSkpO1xufVxuZnVuY3Rpb24gYWRkU2NvcGVUb05vZGUobm9kZSwgZGF0YTIsIHJlZmVyZW5jZU5vZGUpIHtcbiAgbm9kZS5feF9kYXRhU3RhY2sgPSBbZGF0YTIsIC4uLmNsb3Nlc3REYXRhU3RhY2socmVmZXJlbmNlTm9kZSB8fCBub2RlKV07XG4gIHJldHVybiAoKSA9PiB7XG4gICAgbm9kZS5feF9kYXRhU3RhY2sgPSBub2RlLl94X2RhdGFTdGFjay5maWx0ZXIoKGkpID0+IGkgIT09IGRhdGEyKTtcbiAgfTtcbn1cbmZ1bmN0aW9uIGNsb3Nlc3REYXRhU3RhY2sobm9kZSkge1xuICBpZiAobm9kZS5feF9kYXRhU3RhY2spXG4gICAgcmV0dXJuIG5vZGUuX3hfZGF0YVN0YWNrO1xuICBpZiAodHlwZW9mIFNoYWRvd1Jvb3QgPT09IFwiZnVuY3Rpb25cIiAmJiBub2RlIGluc3RhbmNlb2YgU2hhZG93Um9vdCkge1xuICAgIHJldHVybi
1BjbG9zZXN0RGF0YVN0YWNrKG5vZGUuaG9zdCk7XG4gIH1cbiAgaWYgKCFub2RlLnBhcmVudE5vZGUpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgcmV0dXJuIGNsb3Nlc3REYXRhU3RhY2sobm9kZS5wYXJlbnROb2RlKTtcbn1cbmZ1bmN0aW9uIG1lcmdlUHJveGllcyhvYmplY3RzKSB7XG4gIGxldCB0aGlzUHJveHkgPSBuZXcgUHJveHkoe30sIHtcbiAgICBvd25LZXlzOiAoKSA9PiB7XG4gICAgICByZXR1cm4gQXJyYXkuZnJvbShuZXcgU2V0KG9iamVjdHMuZmxhdE1hcCgoaSkgPT4gT2JqZWN0LmtleXMoaSkpKSk7XG4gICAgfSxcbiAgICBoYXM6ICh0YXJnZXQsIG5hbWUpID0+IHtcbiAgICAgIHJldHVybiBvYmplY3RzLnNvbWUoKG9iaikgPT4gb2JqLmhhc093blByb3BlcnR5KG5hbWUpKTtcbiAgICB9LFxuICAgIGdldDogKHRhcmdldCwgbmFtZSkgPT4ge1xuICAgICAgcmV0dXJuIChvYmplY3RzLmZpbmQoKG9iaikgPT4ge1xuICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgICAgbGV0IGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgbmFtZSk7XG4gICAgICAgICAgaWYgKGRlc2NyaXB0b3IuZ2V0ICYmIGRlc2NyaXB0b3IuZ2V0Ll94X2FscmVhZHlCb3VuZCB8fCBkZXNjcmlwdG9yLnNldCAmJiBkZXNjcmlwdG9yLnNldC5feF9hbHJlYWR5Qm91bmQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoKGRlc2NyaXB0b3IuZ2V0IHx8IGRlc2NyaXB0b3Iuc2V0KSAmJiBkZXNjcmlwdG9yLmVudW1lcmFibGUpIHtcbiAgICAgICAgICAgIGxldCBnZXR0ZXIgPSBkZXNjcmlwdG9yLmdldDtcbiAgICAgICAgICAgIGxldCBzZXR0ZXIgPSBkZXNjcmlwdG9yLnNldDtcbiAgICAgICAgICAgIGxldCBwcm9wZXJ0eSA9IGRlc2NyaXB0b3I7XG4gICAgICAgICAgICBnZXR0ZXIgPSBnZXR0ZXIgJiYgZ2V0dGVyLmJpbmQodGhpc1Byb3h5KTtcbiAgICAgICAgICAgIHNldHRlciA9IHNldHRlciAmJiBzZXR0ZXIuYmluZCh0aGlzUHJveHkpO1xuICAgICAgICAgICAgaWYgKGdldHRlcilcbiAgICAgICAgICAgICAgZ2V0dGVyLl94X2FscmVhZHlCb3VuZCA9IHRydWU7XG4gICAgICAgICAgICBpZiAoc2V0dGVyKVxuICAgICAgICAgICAgICBzZXR0ZXIuX3hfYWxyZWFkeUJvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIG5hbWUsIHtcbiAgICAgICAgICAgICAgLi4ucHJvcGVydHksXG4gICAgICAgICAgICAgIGdldDogZ2V0dGVyLFxuICAgICAgICAgICAgICBzZXQ6IHNldHRlclxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pIHx8IHt9KVtuYW1lXTtcbiAgICB9LFxuICAgIHNldDogKHRhcmdldCwgbmFtZSwgdmFsdWUpID0+IHtcbiAgICAgIGxldCBjbG9zZXN0T2JqZWN0V2l0aEtleSA9IG9iamVjdHMuZmluZCgob2JqKSA9PiBvYmouaGFzT3duUHJvcGVydHkobmFtZSkpO1xuICAgICAgaWYgKGNsb3Nlc3RPYmplY3RXaXRoS2V5KSB7XG4gICAgICAgIGNsb3Nlc3RPYmplY3RXaXRoS2V5W25hbWVdID0gdmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvYmplY3RzW29iamVjdHMubGVuZ3RoIC0gMV1bbmFtZV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiB0aGlzUHJveHk7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9pbnRlcmNlcHRvci5qc1xuZnVuY3Rpb24gaW5pdEludGVyY2VwdG9ycyhkYXRhMikge1xuICBsZXQgaXNPYmplY3QyID0gKHZhbCkgPT4gdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheSh2YWwpICYmIHZhbCAhPT0gbnVsbDtcbiAgbGV0IHJlY3Vyc2UgPSAob2JqLCBiYXNlUGF0aCA9IFwiXCIpID0+IHtcbiAgICBPYmplY3QuZW50cmllcyhPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhvYmopKS5mb3JFYWNoKChba2V5LCB7dmFsdWUsIGVudW1lcmFibGV9XSkgPT4ge1xuICAgICAgaWYgKGVudW1lcmFibGUgPT09IGZhbHNlIHx8IHZhbHVlID09PSB2b2lkIDApXG4gICAgICAgIHJldHVybjtcbiAgICAgIGxldCBwYXRoID0gYmFzZVBhdGggPT09IFwiXCIgPyBrZXkgOiBgJHtiYXNlUGF0aH0uJHtrZXl9YDtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX3hfaW50ZXJjZXB0b3IpIHtcbiAgICAgICAgb2JqW2tleV0gPSB2YWx1ZS5pbml0aWFsaXplKGRhdGEyLCBwYXRoLCBrZXkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGlzT2JqZWN0Mih2YWx1ZSkgJiYgdmFsdWUgIT09IG9iaiAmJiAhKHZhbHVlIGluc3RhbmNlb2YgRWxlbWVudCkpIHtcbiAgICAgICAgICByZWN1cnNlKHZhbHVlLCBwYXRoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9O1xuICByZXR1cm4gcmVjdXJzZShkYXRhMik7XG59XG5mdW5jdGlvbiBpbnRlcmNlcHRvcihjYWxsYmFjaywgbXV0YXRlT2JqID0gKCkgPT4ge1xufSkge1xuICBsZXQgb2JqID0ge1xuICAgIGluaXRpYWxWYWx1ZTogdm9pZCAwLFxuICAgIF94X2ludGVyY2VwdG9yOiB0cnVlLFxuICAgIGluaXRpYWxpemUoZGF0YTIsIHBhdGgsIGtleSkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKHRoaXMuaW5pdGlhbFZhbHVlLCAoKSA9PiBnZXQoZGF0YTIsIHBhdGgpLCAodmFsdWUpID0+IHNldChkYXRhMiwgcGF0aCwgdmFsdWUpLCBwYXRoLCBrZXkpO1xuICAgIH1cbiAgfTtcbiAgbXV0YXRlT2JqKG9iaik7XG4gIHJldHVybiAoaW5pdGlhbFZhbHVlKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBpbml0aWFsVmFsdWUgPT09IFwib2JqZWN0XCIgJiYgaW5pdGlhbFZhbHVlICE9PSBudWxsICYmIGluaXRpYWxWYWx1ZS5feF9pbnRlcmNlcHRvcikge1xuICAgICAgbGV0IGluaXRpYWxpemUgPSBvYmouaW5pdGlhbGl6ZS5iaW5kKG9iaik7XG4gICAgICBvYmouaW5pdGlhbGl6ZSA9IChkYXRhMiwgcGF0aCwga2V5KSA9PiB7XG4gICAgICAgIGxldCBpbm5lclZhbHVlID0gaW5pdGlhbFZhbHVlLmluaXRpYWxpemUoZGF0YTIsIHBhdGgsIGtleSk7XG4gICAgICAgIG9iai5pbml0aWFsVmFsdWUgPSBpbm5lclZhbHVlO1xuICAgICAgICByZXR1cm4gaW5pdGlhbGl6ZShkYXRhMiwgcGF0aCwga2V5KTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIG9iai5pbml0aWFsVmFsdWUgPSBpbml0aWFsVmFsdWU7XG4gICAgfVxuICAgIHJldHVybi
1BvYmo7XG4gIH07XG59XG5mdW5jdGlvbiBnZXQob2JqLCBwYXRoKSB7XG4gIHJldHVybiBwYXRoLnNwbGl0KFwiLlwiKS5yZWR1Y2UoKGNhcnJ5LCBzZWdtZW50KSA9PiBjYXJyeVtzZWdtZW50XSwgb2JqKTtcbn1cbmZ1bmN0aW9uIHNldChvYmosIHBhdGgsIHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgcGF0aCA9PT0gXCJzdHJpbmdcIilcbiAgICBwYXRoID0gcGF0aC5zcGxpdChcIi5cIik7XG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMSlcbiAgICBvYmpbcGF0aFswXV0gPSB2YWx1ZTtcbiAgZWxzZSBpZiAocGF0aC5sZW5ndGggPT09IDApXG4gICAgdGhyb3cgZXJyb3I7XG4gIGVsc2Uge1xuICAgIGlmIChvYmpbcGF0aFswXV0pXG4gICAgICByZXR1cm4gc2V0KG9ialtwYXRoWzBdXSwgcGF0aC5zbGljZSgxKSwgdmFsdWUpO1xuICAgIGVsc2Uge1xuICAgICAgb2JqW3BhdGhbMF1dID0ge307XG4gICAgICByZXR1cm4gc2V0KG9ialtwYXRoWzBdXSwgcGF0aC5zbGljZSgxKSwgdmFsdWUpO1xuICAgIH1cbiAgfVxufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvbWFnaWNzLmpzXG52YXIgbWFnaWNzID0ge307XG5mdW5jdGlvbiBtYWdpYyhuYW1lLCBjYWxsYmFjaykge1xuICBtYWdpY3NbbmFtZV0gPSBjYWxsYmFjaztcbn1cbmZ1bmN0aW9uIGluamVjdE1hZ2ljcyhvYmosIGVsKSB7XG4gIE9iamVjdC5lbnRyaWVzKG1hZ2ljcykuZm9yRWFjaCgoW25hbWUsIGNhbGxiYWNrXSkgPT4ge1xuICAgIGxldCBtZW1vaXplZFV0aWxpdGllcyA9IG51bGw7XG4gICAgZnVuY3Rpb24gZ2V0VXRpbGl0aWVzKCkge1xuICAgICAgaWYgKG1lbW9pemVkVXRpbGl0aWVzKSB7XG4gICAgICAgIHJldHVybiBtZW1vaXplZFV0aWxpdGllcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBbdXRpbGl0aWVzLCBjbGVhbnVwMl0gPSBnZXRFbGVtZW50Qm91bmRVdGlsaXRpZXMoZWwpO1xuICAgICAgICBtZW1vaXplZFV0aWxpdGllcyA9IHtpbnRlcmNlcHRvciwgLi4udXRpbGl0aWVzfTtcbiAgICAgICAgb25FbFJlbW92ZWQoZWwsIGNsZWFudXAyKTtcbiAgICAgICAgcmV0dXJuIG1lbW9pemVkVXRpbGl0aWVzO1xuICAgICAgfVxuICAgIH1cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBgJCR7bmFtZX1gLCB7XG4gICAgICBnZXQoKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlbCwgZ2V0VXRpbGl0aWVzKCkpO1xuICAgICAgfSxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlXG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gb2JqO1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvdXRpbHMvZXJyb3IuanNcbmZ1bmN0aW9uIHRyeUNhdGNoKGVsLCBleHByZXNzaW9uLCBjYWxsYmFjaywgLi4uYXJncykge1xuICB0cnkge1xuICAgIHJldHVybiBjYWxsYmFjayguLi5hcmdzKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGhhbmRsZUVycm9yKGUsIGVsLCBleHByZXNzaW9uKTtcbiAgfVxufVxuZnVuY3Rpb24gaGFuZGxlRXJyb3IoZXJyb3IyLCBlbCwgZXhwcmVzc2lvbiA9IHZvaWQgMCkge1xuICBPYmplY3QuYXNzaWduKGVycm9yMiwge2VsLCBleHByZXNzaW9ufSk7XG4gIGNvbnNvbGUud2FybihgQWxwaW5lIEV4cHJlc3Npb24gRXJyb3I6ICR7ZXJyb3IyLm1lc3NhZ2V9XG5cbiR7ZXhwcmVzc2lvbiA/ICdFeHByZXNzaW9uOiBcIicgKyBleHByZXNzaW9uICsgJ1wiXFxuXFxuJyA6IFwiXCJ9YCwgZWwpO1xuICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICB0aHJvdyBlcnJvcjI7XG4gIH0sIDApO1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvZXZhbHVhdG9yLmpzXG52YXIgc2hvdWxkQXV0b0V2YWx1YXRlRnVuY3Rpb25zID0gdHJ1ZTtcbmZ1bmN0aW9uIGRvbnRBdXRvRXZhbHVhdGVGdW5jdGlvbnMoY2FsbGJhY2spIHtcbiAgbGV0IGNhY2hlID0gc2hvdWxkQXV0b0V2YWx1YXRlRnVuY3Rpb25zO1xuICBzaG91bGRBdXRvRXZhbHVhdGVGdW5jdGlvbnMgPSBmYWxzZTtcbiAgbGV0IHJlc3VsdCA9IGNhbGxiYWNrKCk7XG4gIHNob3VsZEF1dG9FdmFsdWF0ZUZ1bmN0aW9ucyA9IGNhY2hlO1xuICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gZXZhbHVhdGUoZWwsIGV4cHJlc3Npb24sIGV4dHJhcyA9IHt9KSB7XG4gIGxldCByZXN1bHQ7XG4gIGV2YWx1YXRlTGF0ZXIoZWwsIGV4cHJlc3Npb24pKCh2YWx1ZSkgPT4gcmVzdWx0ID0gdmFsdWUsIGV4dHJhcyk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBldmFsdWF0ZUxhdGVyKC4uLmFyZ3MpIHtcbiAgcmV0dXJuIHRoZUV2YWx1YXRvckZ1bmN0aW9uKC4uLmFyZ3MpO1xufVxudmFyIHRoZUV2YWx1YXRvckZ1bmN0aW9uID0gbm9ybWFsRXZhbHVhdG9yO1xuZnVuY3Rpb24gc2V0RXZhbHVhdG9yKG5ld0V2YWx1YXRvcikge1xuICB0aGVFdmFsdWF0b3JGdW5jdGlvbiA9IG5ld0V2YWx1YXRvcjtcbn1cbmZ1bmN0aW9uIG5vcm1hbEV2YWx1YXRvcihlbCwgZXhwcmVzc2lvbikge1xuICBsZXQgb3ZlcnJpZGRlbk1hZ2ljcyA9IHt9O1xuICBpbmplY3RNYWdpY3Mob3ZlcnJpZGRlbk1hZ2ljcywgZWwpO1xuICBsZXQgZGF0YVN0YWNrID0gW292ZXJyaWRkZW5NYWdpY3MsIC4uLmNsb3Nlc3REYXRhU3RhY2soZWwpXTtcbiAgbGV0IGV2YWx1YXRvciA9IHR5cGVvZiBleHByZXNzaW9uID09PSBcImZ1bmN0aW9uXCIgPyBnZW5lcmF0ZUV2YWx1YXRvckZyb21GdW5jdGlvbihkYXRhU3RhY2ssIGV4cHJlc3Npb24pIDogZ2VuZXJhdGVFdmFsdWF0b3JGcm9tU3RyaW5nKGRhdGFTdGFjaywgZXhwcmVzc2lvbiwgZWwpO1xuICByZXR1cm4gdHJ5Q2F0Y2guYmluZChudWxsLCBlbCwgZXhwcmVzc2lvbiwgZXZhbHVhdG9yKTtcbn1cbmZ1bmN0aW9uIGdlbmVyYXRlRXZhbHVhdG9yRnJvbUZ1bmN0aW9uKGRhdGFTdGFjaywgZnVuYykge1xuICByZXR1cm4gKHJlY2VpdmVyID0gKCkgPT4ge1xuICB9LCB7c2NvcGU6IHNjb3BlMiA9IHt9LCBwYXJhbXMgPSBbXX0gPSB7fSkgPT4ge1xuICAgIGxldCByZXN1bHQgPSBmdW5jLmFwcGx5KG1lcmdlUHJveGllcyhbc2NvcGUyLCAuLi5kYXRhU3RhY2tdKSwgcGFyYW1zKTtcbiAgICBydW5JZlR5cGVPZkZ1bmN0aW9uKHJlY2VpdmVyLCByZXN1bHQpO1xuICB9O1xufVxudmFyIGV2YWx1YXRvck1lbW8gPSB7fTtcbmZ1bmN0aW9uIGdlbmVyYXRlRnVuY3Rpb25Gcm9tU3RyaW5nKGV4cHJlc3Npb24sIGVsKSB7XG4gIGlmIChldmFsdWF0b3JNZW1vW2V4cHJlc3Npb25dKSB7XG4gICAgcmV0dXJuIGV2YWx1YXRvck1lbW9bZXhwcmVzc2lvbl07XG4gIH1cbiAgbGV0IEFzeW5jRnVuY3Rpb24gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoYXN5bmMgZnVuY3Rpb24oKSB7XG4gIH0pLmNvbnN0cnVjdG9yO1xuICBsZXQgcmlnaHRTaWRlU2FmZUV4cHJl
1c3Npb24gPSAvXltcXG5cXHNdKmlmLipcXCguKlxcKS8udGVzdChleHByZXNzaW9uKSB8fCAvXihsZXR8Y29uc3QpXFxzLy50ZXN0KGV4cHJlc3Npb24pID8gYChhc3luYygpPT57ICR7ZXhwcmVzc2lvbn0gfSkoKWAgOiBleHByZXNzaW9uO1xuICBjb25zdCBzYWZlQXN5bmNGdW5jdGlvbiA9ICgpID0+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIG5ldyBBc3luY0Z1bmN0aW9uKFtcIl9fc2VsZlwiLCBcInNjb3BlXCJdLCBgd2l0aCAoc2NvcGUpIHsgX19zZWxmLnJlc3VsdCA9ICR7cmlnaHRTaWRlU2FmZUV4cHJlc3Npb259IH07IF9fc2VsZi5maW5pc2hlZCA9IHRydWU7IHJldHVybiBfX3NlbGYucmVzdWx0O2ApO1xuICAgIH0gY2F0Y2ggKGVycm9yMikge1xuICAgICAgaGFuZGxlRXJyb3IoZXJyb3IyLCBlbCwgZXhwcmVzc2lvbik7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICB9O1xuICBsZXQgZnVuYyA9IHNhZmVBc3luY0Z1bmN0aW9uKCk7XG4gIGV2YWx1YXRvck1lbW9bZXhwcmVzc2lvbl0gPSBmdW5jO1xuICByZXR1cm4gZnVuYztcbn1cbmZ1bmN0aW9uIGdlbmVyYXRlRXZhbHVhdG9yRnJvbVN0cmluZyhkYXRhU3RhY2ssIGV4cHJlc3Npb24sIGVsKSB7XG4gIGxldCBmdW5jID0gZ2VuZXJhdGVGdW5jdGlvbkZyb21TdHJpbmcoZXhwcmVzc2lvbiwgZWwpO1xuICByZXR1cm4gKHJlY2VpdmVyID0gKCkgPT4ge1xuICB9LCB7c2NvcGU6IHNjb3BlMiA9IHt9LCBwYXJhbXMgPSBbXX0gPSB7fSkgPT4ge1xuICAgIGZ1bmMucmVzdWx0ID0gdm9pZCAwO1xuICAgIGZ1bmMuZmluaXNoZWQgPSBmYWxzZTtcbiAgICBsZXQgY29tcGxldGVTY29wZSA9IG1lcmdlUHJveGllcyhbc2NvcGUyLCAuLi5kYXRhU3RhY2tdKTtcbiAgICBpZiAodHlwZW9mIGZ1bmMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgbGV0IHByb21pc2UgPSBmdW5jKGZ1bmMsIGNvbXBsZXRlU2NvcGUpLmNhdGNoKChlcnJvcjIpID0+IGhhbmRsZUVycm9yKGVycm9yMiwgZWwsIGV4cHJlc3Npb24pKTtcbiAgICAgIGlmIChmdW5jLmZpbmlzaGVkKSB7XG4gICAgICAgIHJ1bklmVHlwZU9mRnVuY3Rpb24ocmVjZWl2ZXIsIGZ1bmMucmVzdWx0LCBjb21wbGV0ZVNjb3BlLCBwYXJhbXMsIGVsKTtcbiAgICAgICAgZnVuYy5yZXN1bHQgPSB2b2lkIDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwcm9taXNlLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICAgIHJ1bklmVHlwZU9mRnVuY3Rpb24ocmVjZWl2ZXIsIHJlc3VsdCwgY29tcGxldGVTY29wZSwgcGFyYW1zLCBlbCk7XG4gICAgICAgIH0pLmNhdGNoKChlcnJvcjIpID0+IGhhbmRsZUVycm9yKGVycm9yMiwgZWwsIGV4cHJlc3Npb24pKS5maW5hbGx5KCgpID0+IGZ1bmMucmVzdWx0ID0gdm9pZCAwKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG5mdW5jdGlvbiBydW5JZlR5cGVPZkZ1bmN0aW9uKHJlY2VpdmVyLCB2YWx1ZSwgc2NvcGUyLCBwYXJhbXMsIGVsKSB7XG4gIGlmIChzaG91bGRBdXRvRXZhbHVhdGVGdW5jdGlvbnMgJiYgdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICBsZXQgcmVzdWx0ID0gdmFsdWUuYXBwbHkoc2NvcGUyLCBwYXJhbXMpO1xuICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICByZXN1bHQudGhlbigoaSkgPT4gcnVuSWZUeXBlT2ZGdW5jdGlvbihyZWNlaXZlciwgaSwgc2NvcGUyLCBwYXJhbXMpKS5jYXRjaCgoZXJyb3IyKSA9PiBoYW5kbGVFcnJvcihlcnJvcjIsIGVsLCB2YWx1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZWNlaXZlcihyZXN1bHQpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgdmFsdWUudGhlbigoaSkgPT4gcmVjZWl2ZXIoaSkpO1xuICB9IGVsc2Uge1xuICAgIHJlY2VpdmVyKHZhbHVlKTtcbiAgfVxufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvZGlyZWN0aXZlcy5qc1xudmFyIHByZWZpeEFzU3RyaW5nID0gXCJ4LVwiO1xuZnVuY3Rpb24gcHJlZml4KHN1YmplY3QgPSBcIlwiKSB7XG4gIHJldHVybiBwcmVmaXhBc1N0cmluZyArIHN1YmplY3Q7XG59XG5mdW5jdGlvbiBzZXRQcmVmaXgobmV3UHJlZml4KSB7XG4gIHByZWZpeEFzU3RyaW5nID0gbmV3UHJlZml4O1xufVxudmFyIGRpcmVjdGl2ZUhhbmRsZXJzID0ge307XG5mdW5jdGlvbiBkaXJlY3RpdmUobmFtZSwgY2FsbGJhY2spIHtcbiAgZGlyZWN0aXZlSGFuZGxlcnNbbmFtZV0gPSBjYWxsYmFjaztcbiAgcmV0dXJuIHtcbiAgICBiZWZvcmUoZGlyZWN0aXZlMikge1xuICAgICAgaWYgKCFkaXJlY3RpdmVIYW5kbGVyc1tkaXJlY3RpdmUyXSkge1xuICAgICAgICBjb25zb2xlLndhcm4oXCJDYW5ub3QgZmluZCBkaXJlY3RpdmUgYCR7ZGlyZWN0aXZlfWAuIGAke25hbWV9YCB3aWxsIHVzZSB0aGUgZGVmYXVsdCBvcmRlciBvZiBleGVjdXRpb25cIik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBvcyA9IGRpcmVjdGl2ZU9yZGVyLmluZGV4T2YoZGlyZWN0aXZlMik7XG4gICAgICBkaXJlY3RpdmVPcmRlci5zcGxpY2UocG9zID49IDAgPyBwb3MgOiBkaXJlY3RpdmVPcmRlci5pbmRleE9mKFwiREVGQVVMVFwiKSwgMCwgbmFtZSk7XG4gICAgfVxuICB9O1xufVxuZnVuY3Rpb24gZGlyZWN0aXZlcyhlbCwgYXR0cmlidXRlcywgb3JpZ2luYWxBdHRyaWJ1dGVPdmVycmlkZSkge1xuICBhdHRyaWJ1dGVzID0gQXJyYXkuZnJvbShhdHRyaWJ1dGVzKTtcbiAgaWYgKGVsLl94X3ZpcnR1YWxEaXJlY3RpdmVzKSB7XG4gICAgbGV0IHZBdHRyaWJ1dGVzID0gT2JqZWN0LmVud
1HJpZXMoZWwuX3hfdmlydHVhbERpcmVjdGl2ZXMpLm1hcCgoW25hbWUsIHZhbHVlXSkgPT4gKHtuYW1lLCB2YWx1ZX0pKTtcbiAgICBsZXQgc3RhdGljQXR0cmlidXRlcyA9IGF0dHJpYnV0ZXNPbmx5KHZBdHRyaWJ1dGVzKTtcbiAgICB2QXR0cmlidXRlcyA9IHZBdHRyaWJ1dGVzLm1hcCgoYXR0cmlidXRlKSA9PiB7XG4gICAgICBpZiAoc3RhdGljQXR0cmlidXRlcy5maW5kKChhdHRyKSA9PiBhdHRyLm5hbWUgPT09IGF0dHJpYnV0ZS5uYW1lKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG5hbWU6IGB4LWJpbmQ6JHthdHRyaWJ1dGUubmFtZX1gLFxuICAgICAgICAgIHZhbHVlOiBgXCIke2F0dHJpYnV0ZS52YWx1ZX1cImBcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhdHRyaWJ1dGU7XG4gICAgfSk7XG4gICAgYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXMuY29uY2F0KHZBdHRyaWJ1dGVzKTtcbiAgfVxuICBsZXQgdHJhbnNmb3JtZWRBdHRyaWJ1dGVNYXAgPSB7fTtcbiAgbGV0IGRpcmVjdGl2ZXMyID0gYXR0cmlidXRlcy5tYXAodG9UcmFuc2Zvcm1lZEF0dHJpYnV0ZXMoKG5ld05hbWUsIG9sZE5hbWUpID0+IHRyYW5zZm9ybWVkQXR0cmlidXRlTWFwW25ld05hbWVdID0gb2xkTmFtZSkpLmZpbHRlcihvdXROb25BbHBpbmVBdHRyaWJ1dGVzKS5tYXAodG9QYXJzZWREaXJlY3RpdmVzKHRyYW5zZm9ybWVkQXR0cmlidXRlTWFwLCBvcmlnaW5hbEF0dHJpYnV0ZU92ZXJyaWRlKSkuc29ydChieVByaW9yaXR5KTtcbiAgcmV0dXJuIGRpcmVjdGl2ZXMyLm1hcCgoZGlyZWN0aXZlMikgPT4ge1xuICAgIHJldHVybiBnZXREaXJlY3RpdmVIYW5kbGVyKGVsLCBkaXJlY3RpdmUyKTtcbiAgfSk7XG59XG5mdW5jdGlvbiBhdHRyaWJ1dGVzT25seShhdHRyaWJ1dGVzKSB7XG4gIHJldHVybiBBcnJheS5mcm9tKGF0dHJpYnV0ZXMpLm1hcCh0b1RyYW5zZm9ybWVkQXR0cmlidXRlcygpKS5maWx0ZXIoKGF0dHIpID0+ICFvdXROb25BbHBpbmVBdHRyaWJ1dGVzKGF0dHIpKTtcbn1cbnZhciBpc0RlZmVycmluZ0hhbmRsZXJzID0gZmFsc2U7XG52YXIgZGlyZWN0aXZlSGFuZGxlclN0YWNrcyA9IG5ldyBNYXAoKTtcbnZhciBjdXJyZW50SGFuZGxlclN0YWNrS2V5ID0gU3ltYm9sKCk7XG5mdW5jdGlvbiBkZWZlckhhbmRsaW5nRGlyZWN0aXZlcyhjYWxsYmFjaykge1xuICBpc0RlZmVycmluZ0hhbmRsZXJzID0gdHJ1ZTtcbiAgbGV0IGtleSA9IFN5bWJvbCgpO1xuICBjdXJyZW50SGFuZGxlclN0YWNrS2V5ID0ga2V5O1xuICBkaXJlY3RpdmVIYW5kbGVyU3RhY2tzLnNldChrZXksIFtdKTtcbiAgbGV0IGZsdXNoSGFuZGxlcnMgPSAoKSA9PiB7XG4gICAgd2hpbGUgKGRpcmVjdGl2ZUhhbmRsZXJTdGFja3MuZ2V0KGtleSkubGVuZ3RoKVxuICAgICAgZGlyZWN0aXZlSGFuZGxlclN0YWNrcy5nZXQoa2V5KS5zaGlmdCgpKCk7XG4gICAgZGlyZWN0aXZlSGFuZGxlclN0YWNrcy5kZWxldGUoa2V5KTtcbiAgfTtcbiAgbGV0IHN0b3BEZWZlcnJpbmcgPSAoKSA9PiB7XG4gICAgaXNEZWZlcnJpbmdIYW5kbGVycyA9IGZhbHNlO1xuICAgIGZsdXNoSGFuZGxlcnMoKTtcbiAgfTtcbiAgY2FsbGJhY2soZmx1c2hIYW5kbGVycyk7XG4gIHN0b3BEZWZlcnJpbmcoKTtcbn1cbmZ1bmN0aW9uIGdldEVsZW1lbnRCb3VuZFV0aWxpdGllcyhlbCkge1xuICBsZXQgY2xlYW51cHMgPSBbXTtcbiAgbGV0IGNsZWFudXAyID0gKGNhbGxiYWNrKSA9PiBjbGVhbnVwcy5wdXNoKGNhbGxiYWNrKTtcbiAgbGV0IFtlZmZlY3QzLCBjbGVhbnVwRWZmZWN0XSA9IGVsZW1lbnRCb3VuZEVmZmVjdChlbCk7XG4gIGNsZWFudXBzLnB1c2goY2xlYW51cEVmZmVjdCk7XG4gIGxldCB1dGlsaXRpZXMgPSB7XG4gICAgQWxwaW5lOiBhbHBpbmVfZGVmYXVsdCxcbiAgICBlZmZlY3Q6IGVmZmVjdDMsXG4gICAgY2xlYW51cDogY2xlYW51cDIsXG4gICAgZXZhbHVhdGVMYXRlcjogZXZhbHVhdGVMYXRlci5iaW5kKGV2YWx1YXRlTGF0ZXIsIGVsKSxcbiAgICBldmFsdWF0ZTogZXZhbHVhdGUuYmluZChldmFsdWF0ZSwgZWwpXG4gIH07XG4gIGxldCBkb0NsZWFudXAgPSAoKSA9PiBjbGVhbnVwcy5mb3JFYWNoKChpKSA9PiBpKCkpO1xuICByZXR1cm4gW3V0aWxpdGllcywgZG9DbGVhbnVwXTtcbn1cbmZ1bmN0aW9uIGdldERpcmVjdGl2ZUhhbmRsZXIoZWwsIGRpcmVjdGl2ZTIpIHtcbiAgbGV0IG5vb3AgPSAoKSA9PiB7XG4gIH07XG4gIGxldCBoYW5kbGVyNCA9IGRpcmVjdGl2ZUhhbmRsZXJzW2RpcmVjdGl2ZTIudHlwZV0gfHwgbm9vcDtcbiAgbGV0IFt1dGlsaXRpZXMsIGNsZWFudXAyXSA9IGdldEVsZW1lbnRCb3VuZFV0aWxpdGllcyhlbCk7XG4gIG9uQXR0cmlidXRlUmVtb3ZlZChlbCwgZGlyZWN0aXZlMi5vcmlnaW5hbCwgY2xlYW51cDIpO1xuICBsZXQgZnVsbEhhbmRsZXIgPSAoKSA9PiB7XG4gICAgaWYgKGVsLl94X2lnbm9yZSB8fCBlbC5feF9pZ25vcmVTZWxmKVxuICAgICAgcmV0dXJuO1xuICAgIGhhbmRsZXI0LmlubGluZSAmJiBoYW5kbGVyNC5pbmxpbmUoZWwsIGRpcmVjdGl2ZTIsIHV0aWxpdGllcyk7XG4gICAgaGFuZGxlcjQgPSBoYW5kbGVyNC5iaW5kKGhhbmRsZXI0LCBlbCwgZGlyZWN0aXZlMiwgdXRpbGl0aWVzKTtcbiAgICBpc0RlZmVycmluZ0hhbmRsZXJzID8gZGlyZWN0aXZlSGFuZGxlclN0YWNrcy5nZXQoY3VycmVudEhhbmRsZXJTdGFja0tleSkucHVzaChoYW5kbGVyNCkgOiBoYW5kbGVyNCgpO1xuICB9O1xuICBmdWxsSGFuZGxlci5ydW5DbGVhbnVwcyA9IGNsZWFudXAyO1xuICByZXR1cm4gZnVsbEhhbmRsZXI7XG59XG52YXIgc3RhcnRpbmdXaXRoID0gKHN1YmplY3QsIHJlcGxhY2VtZW50KSA9PiAoe25hbWUsIHZhbHVlfSkgPT4ge1xuICBpZiAobmFtZS5zdGFydHNXaXRoKHN1YmplY3QpKVxuICAgIG5hbWUgPSBuYW1lLnJlcGxhY2Uoc3ViamVjdCwgcmVwbGFjZW1lbnQpO1xuICByZXR1cm4ge25hbWUsIHZhbHVlfTtcbn07XG52YXIgaW50byA9IChpKSA9PiBpO1xuZnVuY3Rpb24gdG9UcmFuc2Zvcm1lZEF0dHJpYnV0ZXMoY2FsbGJhY2sgPSAoKSA9PiB7XG59KSB7XG4gIHJldHVybiAoe25hbWUsIHZhbHVlfSkgPT4ge1xuICAgIGxldCB7bmFtZTogbmV3TmFtZSwgdmFsdWU6IG5ld1ZhbHVlfSA9IGF0dHJpYnV0ZVRyYW5zZm9ybWVycy5yZWR1Y2UoKGNhcnJ5LCB0cmFuc2Zvcm0pID0+IHtcbiAgICAgIHJldHVybi
1B0cmFuc2Zvcm0oY2FycnkpO1xuICAgIH0sIHtuYW1lLCB2YWx1ZX0pO1xuICAgIGlmIChuZXdOYW1lICE9PSBuYW1lKVxuICAgICAgY2FsbGJhY2sobmV3TmFtZSwgbmFtZSk7XG4gICAgcmV0dXJuIHtuYW1lOiBuZXdOYW1lLCB2YWx1ZTogbmV3VmFsdWV9O1xuICB9O1xufVxudmFyIGF0dHJpYnV0ZVRyYW5zZm9ybWVycyA9IFtdO1xuZnVuY3Rpb24gbWFwQXR0cmlidXRlcyhjYWxsYmFjaykge1xuICBhdHRyaWJ1dGVUcmFuc2Zvcm1lcnMucHVzaChjYWxsYmFjayk7XG59XG5mdW5jdGlvbiBvdXROb25BbHBpbmVBdHRyaWJ1dGVzKHtuYW1lfSkge1xuICByZXR1cm4gYWxwaW5lQXR0cmlidXRlUmVnZXgoKS50ZXN0KG5hbWUpO1xufVxudmFyIGFscGluZUF0dHJpYnV0ZVJlZ2V4ID0gKCkgPT4gbmV3IFJlZ0V4cChgXiR7cHJlZml4QXNTdHJpbmd9KFteOl4uXSspXFxcXGJgKTtcbmZ1bmN0aW9uIHRvUGFyc2VkRGlyZWN0aXZlcyh0cmFuc2Zvcm1lZEF0dHJpYnV0ZU1hcCwgb3JpZ2luYWxBdHRyaWJ1dGVPdmVycmlkZSkge1xuICByZXR1cm4gKHtuYW1lLCB2YWx1ZX0pID0+IHtcbiAgICBsZXQgdHlwZU1hdGNoID0gbmFtZS5tYXRjaChhbHBpbmVBdHRyaWJ1dGVSZWdleCgpKTtcbiAgICBsZXQgdmFsdWVNYXRjaCA9IG5hbWUubWF0Y2goLzooW2EtekEtWjAtOVxcLTpdKykvKTtcbiAgICBsZXQgbW9kaWZpZXJzID0gbmFtZS5tYXRjaCgvXFwuW14uXFxdXSsoPz1bXlxcXV0qJCkvZykgfHwgW107XG4gICAgbGV0IG9yaWdpbmFsID0gb3JpZ2luYWxBdHRyaWJ1dGVPdmVycmlkZSB8fCB0cmFuc2Zvcm1lZEF0dHJpYnV0ZU1hcFtuYW1lXSB8fCBuYW1lO1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiB0eXBlTWF0Y2ggPyB0eXBlTWF0Y2hbMV0gOiBudWxsLFxuICAgICAgdmFsdWU6IHZhbHVlTWF0Y2ggPyB2YWx1ZU1hdGNoWzFdIDogbnVsbCxcbiAgICAgIG1vZGlmaWVyczogbW9kaWZpZXJzLm1hcCgoaSkgPT4gaS5yZXBsYWNlKFwiLlwiLCBcIlwiKSksXG4gICAgICBleHByZXNzaW9uOiB2YWx1ZSxcbiAgICAgIG9yaWdpbmFsXG4gICAgfTtcbiAgfTtcbn1cbnZhciBERUZBVUxUID0gXCJERUZBVUxUXCI7XG52YXIgZGlyZWN0aXZlT3JkZXIgPSBbXG4gIFwiaWdub3JlXCIsXG4gIFwicmVmXCIsXG4gIFwiZGF0YVwiLFxuICBcImlkXCIsXG4gIFwiYmluZFwiLFxuICBcImluaXRcIixcbiAgXCJmb3JcIixcbiAgXCJtb2RlbFwiLFxuICBcIm1vZGVsYWJsZVwiLFxuICBcInRyYW5zaXRpb25cIixcbiAgXCJzaG93XCIsXG4gIFwiaWZcIixcbiAgREVGQVVMVCxcbiAgXCJ0ZWxlcG9ydFwiXG5dO1xuZnVuY3Rpb24gYnlQcmlvcml0eShhLCBiKSB7XG4gIGxldCB0eXBlQSA9IGRpcmVjdGl2ZU9yZGVyLmluZGV4T2YoYS50eXBlKSA9PT0gLTEgPyBERUZBVUxUIDogYS50eXBlO1xuICBsZXQgdHlwZUIgPSBkaXJlY3RpdmVPcmRlci5pbmRleE9mKGIudHlwZSkgPT09IC0xID8gREVGQVVMVCA6IGIudHlwZTtcbiAgcmV0dXJuIGRpcmVjdGl2ZU9yZGVyLmluZGV4T2YodHlwZUEpIC0gZGlyZWN0aXZlT3JkZXIuaW5kZXhPZih0eXBlQik7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy91dGlscy9kaXNwYXRjaC5qc1xuZnVuY3Rpb24gZGlzcGF0Y2goZWwsIG5hbWUsIGRldGFpbCA9IHt9KSB7XG4gIGVsLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KG5hbWUsIHtcbiAgICBkZXRhaWwsXG4gICAgYnViYmxlczogdHJ1ZSxcbiAgICBjb21wb3NlZDogdHJ1ZSxcbiAgICBjYW5jZWxhYmxlOiB0cnVlXG4gIH0pKTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL3V0aWxzL3dhbGsuanNcbmZ1bmN0aW9uIHdhbGsoZWwsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgU2hhZG93Um9vdCA9PT0gXCJmdW5jdGlvblwiICYmIGVsIGluc3RhbmNlb2YgU2hhZG93Um9vdCkge1xuICAgIEFycmF5LmZyb20oZWwuY2hpbGRyZW4pLmZvckVhY2goKGVsMikgPT4gd2FsayhlbDIsIGNhbGxiYWNrKSk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCBza2lwID0gZmFsc2U7XG4gIGNhbGxiYWNrKGVsLCAoKSA9PiBza2lwID0gdHJ1ZSk7XG4gIGlmIChza2lwKVxuICAgIHJldHVybjtcbiAgbGV0IG5vZGUgPSBlbC5maXJzdEVsZW1lbnRDaGlsZDtcbiAgd2hpbGUgKG5vZGUpIHtcbiAgICB3YWxrKG5vZGUsIGNhbGxiYWNrLCBmYWxzZSk7XG4gICAgbm9kZSA9IG5vZGUubmV4dEVsZW1lbnRTaWJsaW5nO1xuICB9XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy91dGlscy93YXJuLmpzXG5mdW5jdGlvbiB3YXJuKG1lc3NhZ2UsIC4uLmFyZ3MpIHtcbiAgY29uc29sZS53YXJuKGBBbHBpbmUgV2FybmluZzogJHttZXNzYWdlfWAsIC4uLmFyZ3MpO1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvbGlmZWN5Y2xlLmpzXG52YXIgc3RhcnRlZCA9IGZhbHNlO1xuZnVuY3Rpb24gc3RhcnQoKSB7XG4gIGlmIChzdGFydGVkKVxuICAgIHdhcm4oXCJBbHBpbmUgaGFzIGFscmVhZHkgYmVlbiBpbml0aWFsaXplZCBvbiB0aGlzIHBhZ2UuIENhbGxpbmcgQWxwaW5lLnN0YXJ0KCkgbW9yZSB0aGFuIG9uY2UgY2FuIGNhdXNlIHByb2JsZW1zLlwiKTtcbiAgc3RhcnRlZCA9IHRydWU7XG4gIGlmICghZG9jdW1lbnQuYm9keSlcbiAgICB3YXJuKFwiVW5hYmxlIHRvIGluaXRpYWxpemUuIFRyeWluZyB0byBsb2FkIEFscGluZSBiZWZvcmUgYDxib2R5PmAgaXMgYXZhaWxhYmxlLiBEaWQgeW91IGZvcmdldCB0byBhZGQgYGRlZmVyYCBpbiBBbHBpbmUncyBgPHNjcmlwdD5gIHRhZz9cIik7XG4gIGRpc3BhdGNoKGRvY3VtZW50LCBcImFscGluZTppbml0XCIpO1xuICBkaXNwYXRjaChkb2N1bWVudCwgXCJhbHBpbmU6aW5pdGlhbGl6aW5nXCIpO1xuICBzdGFydE9ic2VydmluZ011dGF0aW9ucygpO1xuICBvbkVsQWRkZWQoKGVsKSA9PiBpbml0VHJlZShlbCwgd2FsaykpO1xuICBvbkVsUmVtb3ZlZCgoZWwpID0+IGRlc3Ryb3lUcmVlKGVsKSk7XG4gIG9uQXR0cmlidXRlc0FkZGVkKChlbCwgYXR0cnMpID0+IHtcbiAgICBkaXJlY3RpdmVzKGVsLCBhdHRycykuZm9yRWFjaCgoaGFuZGxlKSA9PiBoYW5kbGUoKSk7XG4gIH0pO1xuICBsZXQgb3V0TmVzdGVkQ29tcG9uZW50cyA9IChlbCkgPT4gIWNsb3Nlc3RSb290KGVsLnBhcmVudEVsZW1lbnQsIHRydWUpO1xuICBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYWxsU2VsZWN0b3JzKCkpKS5maWx0ZXIob3V0TmVzdGVkQ29tcG9uZW50cykuZm9yRWFjaCgoZWwpID0+IHtcbiAgICBpbml0VHJlZShlbCk7XG4gIH0pO1xuICBkaXNwYXRjaChkb2N1bWVudCwgXCJhbHBpbmU6aW5pdGlhbGl6ZWRcIik7XG59XG52YXIgcm9vdFNlbGVjdG9yQ2FsbGJhY2tzID0gW107XG52YXIgaW5pdFNlbGVjdG9yQ2FsbGJhY2tzID0gW107XG5mdW5jdGlvbiByb290U2VsZWN0b3JzKCkge1xuICByZXR1cm4gcm9vdFNlbGVjdG9yQ2FsbGJhY2tzLm1hcCgoZm4pID0+IGZuKCkpO1xufVxuZnVuY3Rpb24gYWxsU2VsZWN0b3JzKCkge1xuICByZXR1cm4gcm9vdFNlbGVjdG9yQ2FsbGJhY2tzLmNvbmNhdChpbml0U2VsZWN0b3JDYWxsYmFja3MpLm1hcCgoZm4pID0+IGZuKCkpO1xufVxuZnVuY3Rpb24gYWRkUm9vdFNlbGVjdG9yKHNlbGVjdG9yQ2FsbGJhY2spIHtcbiAgcm9vdFNlbGVjdG9yQ2FsbGJhY2tzLnB1c2goc2VsZWN0b3JDYWxsYmFjayk7XG59XG5mdW5jdGlvbiBhZGRJbml0U2VsZWN0b3Ioc2VsZWN0b3JDYWxsYmFjaykge1xuICBpbml0U2VsZWN0b3JDYWxsYmFja3MucHVzaChzZWxlY3RvckNhbGxiYWNrKTtcbn1cbmZ1bmN0aW9uIGNsb3Nlc3RSb290KGVsLCBpbmNsdWRlSW5pdFNlbGVjdG9ycyA9IGZhbHNlKSB7XG4gIHJldHVybi
1BmaW5kQ2xvc2VzdChlbCwgKGVsZW1lbnQpID0+IHtcbiAgICBjb25zdCBzZWxlY3RvcnMgPSBpbmNsdWRlSW5pdFNlbGVjdG9ycyA/IGFsbFNlbGVjdG9ycygpIDogcm9vdFNlbGVjdG9ycygpO1xuICAgIGlmIChzZWxlY3RvcnMuc29tZSgoc2VsZWN0b3IpID0+IGVsZW1lbnQubWF0Y2hlcyhzZWxlY3RvcikpKVxuICAgICAgcmV0dXJuIHRydWU7XG4gIH0pO1xufVxuZnVuY3Rpb24gZmluZENsb3Nlc3QoZWwsIGNhbGxiYWNrKSB7XG4gIGlmICghZWwpXG4gICAgcmV0dXJuO1xuICBpZiAoY2FsbGJhY2soZWwpKVxuICAgIHJldHVybiBlbDtcbiAgaWYgKGVsLl94X3RlbGVwb3J0QmFjaylcbiAgICBlbCA9IGVsLl94X3RlbGVwb3J0QmFjaztcbiAgaWYgKCFlbC5wYXJlbnRFbGVtZW50KVxuICAgIHJldHVybjtcbiAgcmV0dXJuIGZpbmRDbG9zZXN0KGVsLnBhcmVudEVsZW1lbnQsIGNhbGxiYWNrKTtcbn1cbmZ1bmN0aW9uIGlzUm9vdChlbCkge1xuICByZXR1cm4gcm9vdFNlbGVjdG9ycygpLnNvbWUoKHNlbGVjdG9yKSA9PiBlbC5tYXRjaGVzKHNlbGVjdG9yKSk7XG59XG52YXIgaW5pdEludGVyY2VwdG9yczIgPSBbXTtcbmZ1bmN0aW9uIGludGVyY2VwdEluaXQoY2FsbGJhY2spIHtcbiAgaW5pdEludGVyY2VwdG9yczIucHVzaChjYWxsYmFjayk7XG59XG5mdW5jdGlvbiBpbml0VHJlZShlbCwgd2Fsa2VyID0gd2FsaywgaW50ZXJjZXB0ID0gKCkgPT4ge1xufSkge1xuICBkZWZlckhhbmRsaW5nRGlyZWN0aXZlcygoKSA9PiB7XG4gICAgd2Fsa2VyKGVsLCAoZWwyLCBza2lwKSA9PiB7XG4gICAgICBpbnRlcmNlcHQoZWwyLCBza2lwKTtcbiAgICAgIGluaXRJbnRlcmNlcHRvcnMyLmZvckVhY2goKGkpID0+IGkoZWwyLCBza2lwKSk7XG4gICAgICBkaXJlY3RpdmVzKGVsMiwgZWwyLmF0dHJpYnV0ZXMpLmZvckVhY2goKGhhbmRsZSkgPT4gaGFuZGxlKCkpO1xuICAgICAgZWwyLl94X2lnbm9yZSAmJiBza2lwKCk7XG4gICAgfSk7XG4gIH0pO1xufVxuZnVuY3Rpb24gZGVzdHJveVRyZWUocm9vdCkge1xuICB3YWxrKHJvb3QsIChlbCkgPT4gY2xlYW51cEF0dHJpYnV0ZXMoZWwpKTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL25leHRUaWNrLmpzXG52YXIgdGlja1N0YWNrID0gW107XG52YXIgaXNIb2xkaW5nID0gZmFsc2U7XG5mdW5jdGlvbiBuZXh0VGljayhjYWxsYmFjayA9ICgpID0+IHtcbn0pIHtcbiAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgIGlzSG9sZGluZyB8fCBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHJlbGVhc2VOZXh0VGlja3MoKTtcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzKSA9PiB7XG4gICAgdGlja1N0YWNrLnB1c2goKCkgPT4ge1xuICAgICAgY2FsbGJhY2soKTtcbiAgICAgIHJlcygpO1xuICAgIH0pO1xuICB9KTtcbn1cbmZ1bmN0aW9uIHJlbGVhc2VOZXh0VGlja3MoKSB7XG4gIGlzSG9sZGluZyA9IGZhbHNlO1xuICB3aGlsZSAodGlja1N0YWNrLmxlbmd0aClcbiAgICB0aWNrU3RhY2suc2hpZnQoKSgpO1xufVxuZnVuY3Rpb24gaG9sZE5leHRUaWNrcygpIHtcbiAgaXNIb2xkaW5nID0gdHJ1ZTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL3V0aWxzL2NsYXNzZXMuanNcbmZ1bmN0aW9uIHNldENsYXNzZXMoZWwsIHZhbHVlKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiBzZXRDbGFzc2VzRnJvbVN0cmluZyhlbCwgdmFsdWUuam9pbihcIiBcIikpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbCkge1xuICAgIHJldHVybiBzZXRDbGFzc2VzRnJvbU9iamVjdChlbCwgdmFsdWUpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgcmV0dXJuIHNldENsYXNzZXMoZWwsIHZhbHVlKCkpO1xuICB9XG4gIHJldHVybiBzZXRDbGFzc2VzRnJvbVN0cmluZyhlbCwgdmFsdWUpO1xufVxuZnVuY3Rpb24gc2V0Q2xhc3Nlc0Zyb21TdHJpbmcoZWwsIGNsYXNzU3RyaW5nKSB7XG4gIGxldCBzcGxpdCA9IChjbGFzc1N0cmluZzIpID0+IGNsYXNzU3RyaW5nMi5zcGxpdChcIiBcIikuZmlsdGVyKEJvb2xlYW4pO1xuICBsZXQgbWlzc2luZ0NsYXNzZXMgPSAoY2xhc3NTdHJpbmcyKSA9PiBjbGFzc1N0cmluZzIuc3BsaXQoXCIgXCIpLmZpbHRlcigoaSkgPT4gIWVsLmNsYXNzTGlzdC5jb250YWlucyhpKSkuZmlsdGVyKEJvb2xlYW4pO1xuICBsZXQgYWRkQ2xhc3Nlc0FuZFJldHVyblVuZG8gPSAoY2xhc3NlcykgPT4ge1xuICAgIGVsLmNsYXNzTGlzdC5hZGQoLi4uY2xhc3Nlcyk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoLi4uY2xhc3Nlcyk7XG4gICAgfTtcbiAgfTtcbiAgY2xhc3NTdHJpbmcgPSBjbGFzc1N0cmluZyA9PT0gdHJ1ZSA/IGNsYXNzU3RyaW5nID0gXCJcIiA6IGNsYXNzU3RyaW5nIHx8IFwiXCI7XG4gIHJldHVybiBhZGRDbGFzc2VzQW5kUmV0dXJuVW5kbyhtaXNzaW5nQ2xhc3NlcyhjbGFzc1N0cmluZykpO1xufVxuZnVuY3Rpb24gc2V0Q2xhc3Nlc0Zyb21PYmplY3QoZWwsIGNsYXNzT2JqZWN0KSB7XG4gIGxldCBzcGxpdCA9IChjbGFzc1N0cmluZykgPT4gY2xhc3NTdHJpbmcuc3BsaXQoXCIgXCIpLmZpbHRlcihCb29sZWFuKTtcbiAgbGV0IGZvckFkZCA9IE9iamVjdC5lbnRyaWVzKGNsYXNzT2JqZWN0KS5mbGF0TWFwKChbY2xhc3NTdHJpbmcsIGJvb2xdKSA9PiBib29sID8gc3BsaXQoY2xhc3NTdHJpbmcpIDogZmFsc2UpLmZpbHRlcihCb29sZWFuKTtcbiAgbGV0IGZvclJlbW92ZSA9IE9iamVjdC5lbnRyaWVzKGNsYXNzT2JqZWN0KS5mbGF0TWFwKChbY2xhc3NTdHJpbmcsIGJvb2xdKSA9PiAhYm9vbCA/IHNwbGl0KGNsYXNzU3RyaW5nKSA6IGZhbHNlKS5maWx0ZXIoQm9vbGVhbik7XG4gIGxldCBhZGRlZCA9IFtdO1xuICBsZXQgcmVtb3ZlZCA9IFtdO1xuICBmb3JSZW1vdmUuZm9yRWFjaCgoaSkgPT4ge1xuICAgIGlmIChlbC5jbGFzc0xpc3QuY29udGFpbnMoaSkpIHtcbiAgICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoaSk7XG4gICAgICByZW1vdmVkLnB1c2goaSk7XG4gICAgfVxuICB9KTtcbiAgZm9yQWRkLmZvckVhY2goKGkpID0+IHtcbiAgICBpZiAoIWVsLmNsYXNzTGlzdC5jb250YWlucyhpKSkge1xuICAgICAgZWwuY2xhc3NMaXN0LmFkZChpKTtcbiAgICAgIGFkZGVkLnB1c2goaSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuICgpID0+IHtcbiAgICByZW1vdmVkLmZvckVhY2goKGkpID0+IGVsLmNsYXNzTGlzdC5hZGQoaSkpO1xuICAgIGFkZGVkLmZvckVhY2goKGkpID0+IGVsLmNsYXNzTGlzdC5yZW1vdmUoaSkpO1xuICB9O1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvdXRpbHMvc3R5bGVzLmpzXG5mdW5jdGlvbiBzZXRTdHlsZXMoZWwsIHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwpIHtcbiAgICByZXR1cm4gc2V0U3R5bGVzRnJvbU9iamVjdChlbCwgdmFsdWUpO1xuICB9XG4gI
1HJldHVybiBzZXRTdHlsZXNGcm9tU3RyaW5nKGVsLCB2YWx1ZSk7XG59XG5mdW5jdGlvbiBzZXRTdHlsZXNGcm9tT2JqZWN0KGVsLCB2YWx1ZSkge1xuICBsZXQgcHJldmlvdXNTdHlsZXMgPSB7fTtcbiAgT2JqZWN0LmVudHJpZXModmFsdWUpLmZvckVhY2goKFtrZXksIHZhbHVlMl0pID0+IHtcbiAgICBwcmV2aW91c1N0eWxlc1trZXldID0gZWwuc3R5bGVba2V5XTtcbiAgICBpZiAoIWtleS5zdGFydHNXaXRoKFwiLS1cIikpIHtcbiAgICAgIGtleSA9IGtlYmFiQ2FzZShrZXkpO1xuICAgIH1cbiAgICBlbC5zdHlsZS5zZXRQcm9wZXJ0eShrZXksIHZhbHVlMik7XG4gIH0pO1xuICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICBpZiAoZWwuc3R5bGUubGVuZ3RoID09PSAwKSB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoXCJzdHlsZVwiKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gKCkgPT4ge1xuICAgIHNldFN0eWxlcyhlbCwgcHJldmlvdXNTdHlsZXMpO1xuICB9O1xufVxuZnVuY3Rpb24gc2V0U3R5bGVzRnJvbVN0cmluZyhlbCwgdmFsdWUpIHtcbiAgbGV0IGNhY2hlID0gZWwuZ2V0QXR0cmlidXRlKFwic3R5bGVcIiwgdmFsdWUpO1xuICBlbC5zZXRBdHRyaWJ1dGUoXCJzdHlsZVwiLCB2YWx1ZSk7XG4gIHJldHVybiAoKSA9PiB7XG4gICAgZWwuc2V0QXR0cmlidXRlKFwic3R5bGVcIiwgY2FjaGUgfHwgXCJcIik7XG4gIH07XG59XG5mdW5jdGlvbiBrZWJhYkNhc2Uoc3ViamVjdCkge1xuICByZXR1cm4gc3ViamVjdC5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCBcIiQxLSQyXCIpLnRvTG93ZXJDYXNlKCk7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy91dGlscy9vbmNlLmpzXG5mdW5jdGlvbiBvbmNlKGNhbGxiYWNrLCBmYWxsYmFjayA9ICgpID0+IHtcbn0pIHtcbiAgbGV0IGNhbGxlZCA9IGZhbHNlO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgaWYgKCFjYWxsZWQpIHtcbiAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC10cmFuc2l0aW9uLmpzXG5kaXJlY3RpdmUoXCJ0cmFuc2l0aW9uXCIsIChlbCwge3ZhbHVlLCBtb2RpZmllcnMsIGV4cHJlc3Npb259LCB7ZXZhbHVhdGU6IGV2YWx1YXRlMn0pID0+IHtcbiAgaWYgKHR5cGVvZiBleHByZXNzaW9uID09PSBcImZ1bmN0aW9uXCIpXG4gICAgZXhwcmVzc2lvbiA9IGV2YWx1YXRlMihleHByZXNzaW9uKTtcbiAgaWYgKGV4cHJlc3Npb24gPT09IGZhbHNlKVxuICAgIHJldHVybjtcbiAgaWYgKCFleHByZXNzaW9uIHx8IHR5cGVvZiBleHByZXNzaW9uID09PSBcImJvb2xlYW5cIikge1xuICAgIHJlZ2lzdGVyVHJhbnNpdGlvbnNGcm9tSGVscGVyKGVsLCBtb2RpZmllcnMsIHZhbHVlKTtcbiAgfSBlbHNlIHtcbiAgICByZWdpc3RlclRyYW5zaXRpb25zRnJvbUNsYXNzU3RyaW5nKGVsLCBleHByZXNzaW9uLCB2YWx1ZSk7XG4gIH1cbn0pO1xuZnVuY3Rpb24gcmVnaXN0ZXJUcmFuc2l0aW9uc0Zyb21DbGFzc1N0cmluZyhlbCwgY2xhc3NTdHJpbmcsIHN0YWdlKSB7XG4gIHJlZ2lzdGVyVHJhbnNpdGlvbk9iamVjdChlbCwgc2V0Q2xhc3NlcywgXCJcIik7XG4gIGxldCBkaXJlY3RpdmVTdG9yYWdlTWFwID0ge1xuICAgIGVudGVyOiAoY2xhc3NlcykgPT4ge1xuICAgICAgZWwuX3hfdHJhbnNpdGlvbi5lbnRlci5kdXJpbmcgPSBjbGFzc2VzO1xuICAgIH0sXG4gICAgXCJlbnRlci1zdGFydFwiOiAoY2xhc3NlcykgPT4ge1xuICAgICAgZWwuX3hfdHJhbnNpdGlvbi5lbnRlci5zdGFydCA9IGNsYXNzZXM7XG4gICAgfSxcbiAgICBcImVudGVyLWVuZFwiOiAoY2xhc3NlcykgPT4ge1xuICAgICAgZWwuX3hfdHJhbnNpdGlvbi5lbnRlci5lbmQgPSBjbGFzc2VzO1xuICAgIH0sXG4gICAgbGVhdmU6IChjbGFzc2VzKSA9PiB7XG4gICAgICBlbC5feF90cmFuc2l0aW9uLmxlYXZlLmR1cmluZyA9IGNsYXNzZXM7XG4gICAgfSxcbiAgICBcImxlYXZlLXN0YXJ0XCI6IChjbGFzc2VzKSA9PiB7XG4gICAgICBlbC5feF90cmFuc2l0aW9uLmxlYXZlLnN0YXJ0ID0gY2xhc3NlcztcbiAgICB9LFxuICAgIFwibGVhdmUtZW5kXCI6IChjbGFzc2VzKSA9PiB7XG4gICAgICBlbC5feF90cmFuc2l0aW9uLmxlYXZlLmVuZCA9IGNsYXNzZXM7XG4gICAgfVxuICB9O1xuICBkaXJlY3RpdmVTdG9yYWdlTWFwW3N0YWdlXShjbGFzc1N0cmluZyk7XG59XG5mdW5jdGlvbiByZWdpc3RlclRyYW5zaXRpb25zRnJvbUhlbHBlcihlbCwgbW9kaWZpZXJzLCBzdGFnZSkge1xuICByZWdpc3RlclRyYW5zaXRpb25PYmplY3QoZWwsIHNldFN0eWxlcyk7XG4gIGxldCBkb2VzbnRTcGVjaWZ5ID0gIW1vZGlmaWVycy5pbmNsdWRlcyhcImluXCIpICYmICFtb2RpZmllcnMuaW5jbHVkZXMoXCJvdXRcIikgJiYgIXN0YWdlO1xuICBsZXQgdHJhbnNpdGlvbmluZ0luID0gZG9lc250U3BlY2lmeSB8fCBtb2RpZmllcnMuaW5jbHVkZXMoXCJpblwiKSB8fCBbXCJlbnRlclwiXS5pbmNsdWRlcyhzdGFnZSk7XG4gIGxldCB0cmFuc2l0aW9uaW5nT3V0ID0gZG9lc250U3BlY2lmeSB8fCBtb2RpZmllcnMuaW5jbHVkZXMoXCJvdXRcIikgfHwgW1wibGVhdmVcIl0uaW5jbHVkZXMoc3RhZ2UpO1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwiaW5cIikgJiYgIWRvZXNudFNwZWNpZnkpIHtcbiAgICBtb2RpZmllcnMgPSBtb2RpZmllcnMuZmlsdGVyKChpLCBpbmRleCkgPT4gaW5kZXggPCBtb2RpZmllcnMuaW5kZXhPZihcIm91dFwiKSk7XG4gIH1cbiAgaWYgKG1vZGlmaWVycy5pbmNsdWRlcyhcIm91dFwiKSAmJiAhZG9lc250U3BlY2lmeSkge1xuICAgIG1vZGlmaWVycyA9IG1vZGlmaWVycy5maWx0ZXIoKGksIGluZGV4KSA9PiBpbmRleCA+IG1vZGlmaWVycy5pbmRleE9mKFwib3V0XCIpKTtcbiAgfVxuICBsZXQgd2FudHNBbGwgPSAhbW9kaWZpZXJzLmluY2x1ZGVzKFwib3BhY2l0eVwiKSAmJiAhbW9kaWZpZXJzLmluY2x1ZGVzKFwic2NhbGVcIik7XG4gIGxldCB3YW50c09wYWNpdHkgPSB3YW50c0FsbCB8fCBtb2RpZmllcnMuaW5jbHVkZXMoXCJvcGFjaXR5XCIpO1xuICBsZXQgd2FudHNTY2FsZSA9IHdhbnRzQWxsIHx8IG1vZGlmaWVycy5pbmNsdWRlcyhcInNjYWxlXCIpO1xuICBsZXQgb3BhY2l0eVZhbHVlID0gd2FudHNPcGFjaXR5ID8gMCA6IDE7XG4gIGxldCBzY2FsZVZhbHVlID0gd2FudHNTY2FsZSA/IG1vZGlmaWVyVmFsdWUobW9kaWZpZXJzLCBcInNjYWxlXCIsIDk1KSAvIDEwMCA6IDE7XG4gIGxldCBkZWxheSA9IG1vZGlmaWVyVmFsdWUobW9kaWZpZXJzLCBcImRlbGF5XCIsIDApIC8gMWUzO1xuICBsZXQgb3JpZ2luID0gbW9kaWZpZXJWYWx1ZShtb2RpZmllcnMsIFwib3JpZ2luXCIsIFwiY2VudGVyXCIpO1xuICBsZXQgcHJvcGVydHkgPSBcIm9wYWNpdHksIHRyYW5zZm9ybVwiO1xuICBsZXQgZHVyYXRpb25JbiA9IG1vZGlmaWVyVmFsdWUobW9kaWZpZXJzLCBcImR1cmF0aW9uXCIsIDE1MCkgLyAxZTM7XG4gIGxldCBkdXJhdGlvbk91dCA9IG1vZGlmaWVyVmFsdWUobW9kaWZpZXJzLCBcImR1cmF0aW9uXCIsIDc1KSAvIDFlMztcbiAgbGV0IGVhc2luZyA9IGBjdWJpYy1iZXppZXIoMC40LCAwLjAsIDAuMiwgMSlgO1xuICBpZiAodHJhbnNpdGlvbmluZ0luKSB7XG4gICAgZWwuX3hfdHJhbnNpdGlvbi5lbnRlci5kdXJpbmcgPSB7XG4gICAgICB0cmFuc2Zvcm1PcmlnaW46IG9yaWdpbixcbiAgICAgIHRyYW5zaXRpb25EZWxheTogYCR7ZGVsYXl9c2AsXG4gICAgICB0cmFuc2l0aW9uUHJvcGVydHk6IHByb3BlcnR5LFxuICAgICAgdHJhbnNpdGlvbkR1cmF0aW9uOiBgJHtkdXJhdGlvbklufXNgLFxuICAgICAgdHJhbnNpdGlvblRpbWluZ0Z1bmN0aW9uOiBlYXNpbmdcbiAgICB9O1xuICAgIGVsLl94X3RyYW5zaXRpb24uZW50ZXIuc3RhcnQgPSB7XG4gICAgICBvcGFjaXR5OiBvcGFjaXR5VmFsdWUsXG4gICAgICB0cmFuc2Zvcm06IGBzY2FsZSgke3NjYWxlVmFsdWV9KWBcbiAgICB9O1xuICAgIGVsLl94X3RyYW5zaXRpb24uZW50ZXIuZW5kID0ge1xuICAgICAgb3BhY2l0eTogMSxcbiAgICAgIHRyYW5zZm9ybTogYHNjYWxlKDEpYFxuICAgIH07XG4gIH1cbiAgaWYgKHRyYW5zaXRpb25pbmdPdXQpIHtcbiAgICBlbC5feF90cmFuc2l0aW9uLmxlYXZlLmR1cmluZyA9IHtcbiAgICAgIHRyYW5zZm9ybU9yaWdpbjogb3JpZ2luLFxuICAgICAgdHJhbnNpdGlvbkRlbGF5OiBgJHtkZWxheX1zYCxcbiAgICAgIHRyYW5zaXRpb25Qcm9wZXJ0eTogcHJvcGVydHksXG4gICAgICB0cmFuc2l0aW9uRHVyYXRpb246IGAke2R1cmF0aW9uT3V0fXNgLFxuICAgICAgdHJhbnNpdGlvblRpbWluZ0Z1bmN0aW9uOiBlYXNpbmdcbiAgICB9O1xuICAgIGVsLl94X3RyYW5zaXRpb24ubGVhdmUuc3RhcnQgPSB7XG4gICAgICBvcGFjaXR5OiAxLFxuICAgICAgdHJhbnNmb3JtOiBgc2NhbGUoMSlgXG4gICAgfTtcbiAgICBlbC5feF90cmFuc2l0aW9uLmxlYXZlLmVuZCA9IHtcbiAgICAgIG9wYWNpdHk6IG9wYWNpdHlWYWx1ZSxcbiAgICAgIHRyYW5zZm9ybTogYHNjYWxlKCR7c2NhbGVWYWx1ZX0pYFxuICAgIH07XG4gIH1cbn1cbmZ1bmN0aW9uIHJlZ2lzdGVyVHJhbnNpdGlvbk9iamVjdChlbCwgc2V0RnVuY3Rpb24sIGRlZmF1bHRWYWx1ZSA9IHt9KSB7XG4gIGlmICghZWwuX3hfdHJhbnNpdGlvbilcbiAgICBlbC5feF90cmFuc2l0aW9uID0ge1xuICAgICAgZW50ZXI6IHtkdXJpbmc6IGRlZmF1bHRWYWx1ZSwgc3RhcnQ6IGRlZmF1bHRWYWx1ZSwgZW5kOiBkZWZhdWx0VmFsdWV9LFxuICAgICAgbGVhdmU6IHtkdXJpbmc6IGRlZmF1bHRWYWx1ZSwgc3RhcnQ6IGRlZmF1bHRWYWx1ZSwgZW5kOiBkZWZhdWx0VmFsdWV9LFxuICAgICAgaW4oYmVmb3JlID0gKCkgPT4ge1xuICAgICAgfSwgYWZ0ZXIgPSAoKSA9PiB7XG4gICAgICB9KSB7XG4gICAgICAgI
1HRyYW5zaXRpb24oZWwsIHNldEZ1bmN0aW9uLCB7XG4gICAgICAgICAgZHVyaW5nOiB0aGlzLmVudGVyLmR1cmluZyxcbiAgICAgICAgICBzdGFydDogdGhpcy5lbnRlci5zdGFydCxcbiAgICAgICAgICBlbmQ6IHRoaXMuZW50ZXIuZW5kXG4gICAgICAgIH0sIGJlZm9yZSwgYWZ0ZXIpO1xuICAgICAgfSxcbiAgICAgIG91dChiZWZvcmUgPSAoKSA9PiB7XG4gICAgICB9LCBhZnRlciA9ICgpID0+IHtcbiAgICAgIH0pIHtcbiAgICAgICAgdHJhbnNpdGlvbihlbCwgc2V0RnVuY3Rpb24sIHtcbiAgICAgICAgICBkdXJpbmc6IHRoaXMubGVhdmUuZHVyaW5nLFxuICAgICAgICAgIHN0YXJ0OiB0aGlzLmxlYXZlLnN0YXJ0LFxuICAgICAgICAgIGVuZDogdGhpcy5sZWF2ZS5lbmRcbiAgICAgICAgfSwgYmVmb3JlLCBhZnRlcik7XG4gICAgICB9XG4gICAgfTtcbn1cbndpbmRvdy5FbGVtZW50LnByb3RvdHlwZS5feF90b2dnbGVBbmRDYXNjYWRlV2l0aFRyYW5zaXRpb25zID0gZnVuY3Rpb24oZWwsIHZhbHVlLCBzaG93LCBoaWRlKSB7XG4gIGNvbnN0IG5leHRUaWNrMiA9IGRvY3VtZW50LnZpc2liaWxpdHlTdGF0ZSA9PT0gXCJ2aXNpYmxlXCIgPyByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgOiBzZXRUaW1lb3V0O1xuICBsZXQgY2xpY2tBd2F5Q29tcGF0aWJsZVNob3cgPSAoKSA9PiBuZXh0VGljazIoc2hvdyk7XG4gIGlmICh2YWx1ZSkge1xuICAgIGlmIChlbC5feF90cmFuc2l0aW9uICYmIChlbC5feF90cmFuc2l0aW9uLmVudGVyIHx8IGVsLl94X3RyYW5zaXRpb24ubGVhdmUpKSB7XG4gICAgICBlbC5feF90cmFuc2l0aW9uLmVudGVyICYmIChPYmplY3QuZW50cmllcyhlbC5feF90cmFuc2l0aW9uLmVudGVyLmR1cmluZykubGVuZ3RoIHx8IE9iamVjdC5lbnRyaWVzKGVsLl94X3RyYW5zaXRpb24uZW50ZXIuc3RhcnQpLmxlbmd0aCB8fCBPYmplY3QuZW50cmllcyhlbC5feF90cmFuc2l0aW9uLmVudGVyLmVuZCkubGVuZ3RoKSA/IGVsLl94X3RyYW5zaXRpb24uaW4oc2hvdykgOiBjbGlja0F3YXlDb21wYXRpYmxlU2hvdygpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbC5feF90cmFuc2l0aW9uID8gZWwuX3hfdHJhbnNpdGlvbi5pbihzaG93KSA6IGNsaWNrQXdheUNvbXBhdGlibGVTaG93KCk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuICBlbC5feF9oaWRlUHJvbWlzZSA9IGVsLl94X3RyYW5zaXRpb24gPyBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgZWwuX3hfdHJhbnNpdGlvbi5vdXQoKCkgPT4ge1xuICAgIH0sICgpID0+IHJlc29sdmUoaGlkZSkpO1xuICAgIGVsLl94X3RyYW5zaXRpb25pbmcuYmVmb3JlQ2FuY2VsKCgpID0+IHJlamVjdCh7aXNGcm9tQ2FuY2VsbGVkVHJhbnNpdGlvbjogdHJ1ZX0pKTtcbiAgfSkgOiBQcm9taXNlLnJlc29sdmUoaGlkZSk7XG4gIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICBsZXQgY2xvc2VzdCA9IGNsb3Nlc3RIaWRlKGVsKTtcbiAgICBpZiAoY2xvc2VzdCkge1xuICAgICAgaWYgKCFjbG9zZXN0Ll94X2hpZGVDaGlsZHJlbilcbiAgICAgICAgY2xvc2VzdC5feF9oaWRlQ2hpbGRyZW4gPSBbXTtcbiAgICAgIGNsb3Nlc3QuX3hfaGlkZUNoaWxkcmVuLnB1c2goZWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0VGljazIoKCkgPT4ge1xuICAgICAgICBsZXQgaGlkZUFmdGVyQ2hpbGRyZW4gPSAoZWwyKSA9PiB7XG4gICAgICAgICAgbGV0IGNhcnJ5ID0gUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgZWwyLl94X2hpZGVQcm9taXNlLFxuICAgICAgICAgICAgLi4uKGVsMi5feF9oaWRlQ2hpbGRyZW4gfHwgW10pLm1hcChoaWRlQWZ0ZXJDaGlsZHJlbilcbiAgICAgICAgICBdKS50aGVuKChbaV0pID0+IGkoKSk7XG4gICAgICAgICAgZGVsZXRlIGVsMi5feF9oaWRlUHJvbWlzZTtcbiAgICAgICAgICBkZWxldGUgZWwyLl94X2hpZGVDaGlsZHJlbjtcbiAgICAgICAgICByZXR1cm4gY2Fycnk7XG4gICAgICAgIH07XG4gICAgICAgIGhpZGVBZnRlckNoaWxkcmVuKGVsKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgIGlmICghZS5pc0Zyb21DYW5jZWxsZWRUcmFuc2l0aW9uKVxuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xufTtcbmZ1bmN0aW9uIGNsb3Nlc3RIaWRlKGVsKSB7XG4gIGxldCBwYXJlbnQgPSBlbC5wYXJlbnROb2RlO1xuICBpZiAoIXBhcmVudClcbiAgICByZXR1cm47XG4gIHJldHVybiBwYXJlbnQuX3hfaGlkZVByb21pc2UgPyBwYXJlbnQgOiBjbG9zZXN0SGlkZShwYXJlbnQpO1xufVxuZnVuY3Rpb24gdHJhbnNpdGlvbihlbCwgc2V0RnVuY3Rpb24sIHtkdXJpbmcsIHN0YXJ0OiBzdGFydDIsIGVuZH0gPSB7fSwgYmVmb3JlID0gKCkgPT4ge1xufSwgYWZ0ZXIgPSAoKSA9PiB7XG59KSB7XG4gIGlmIChlbC5feF90cmFuc2l0aW9uaW5nKVxuICAgIGVsLl94X3RyYW5zaXRpb25pbmcuY2FuY2VsKCk7XG4gIGlmIChPYmplY3Qua2V5cyhkdXJpbmcpLmxlbmd0aCA9PT0gMCAmJiBPYmplY3Qua2V5cyhzdGFydDIpLmxlbmd0aCA9PT0gMCAmJiBPYmplY3Qua2V5cyhlbmQpLmxlbmd0aCA9PT0gMCkge1xuICAgIGJlZm9yZSgpO1xuICAgIGFmdGVyKCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCB1bmRvU3RhcnQsIHVuZG9EdXJpbmcsIHVuZG9FbmQ7XG4gIHBlcmZvcm1UcmFuc2l0aW9uKGVsLCB7XG4gICAgc3RhcnQoKSB7XG4gICAgICB1bmRvU3RhcnQgPSBzZXRGdW5jdGlvbihlbCwgc3RhcnQyKTtcbiAgICB9LFxuICAgIGR1cmluZygpIHtcbiAgICAgIHVuZG9EdXJpbmcgPSBzZXRGdW5jdGlvbihlbCwgZHVyaW5nKTtcbiAgICB9LFxuICAgIGJlZm9yZSxcbiAgICBlbmQoKSB7XG4gICAgICB1bmRvU3RhcnQoKTtcbiAgICAgIHVuZG9FbmQgPSBzZXRGdW5jdGlvbihlbCwgZW5kKTtcbiAgICB9LFxuICAgIGFmdGVyLFxuICAgIGNsZWFudXAoKSB7XG4gICAgICB1bmRvRHVyaW5nKCk7XG4gICAgICB1bmRvRW5kKCk7XG4gICAgfVxuICB9KTtcbn1cbmZ1bmN0aW9uIHBlcmZvcm1UcmFuc2l0aW9uKGVsLCBzdGFnZXMpIHtcbiAgbGV0IGludGVycnVwdGVkLCByZWFjaGVkQmVmb3JlLCByZWFjaGVkRW5kO1xuICBsZXQgZmluaXNoID0gb25jZSgoKSA9PiB7XG4gICAgbXV0YXRlRG9tKCgpID0+IHtcbiAgICAgIGludGVycnVwdGVkID0gdHJ1ZTtcbiAgICAgIGlmICghcmVhY2hlZEJlZm9yZSlcbiAgICAgICAgc3RhZ2VzLmJlZm9yZSgpO1xuICAgICAgaWYgKCFyZWFjaGVkRW5kKSB7XG4gICAgICAgI
1HN0YWdlcy5lbmQoKTtcbiAgICAgICAgcmVsZWFzZU5leHRUaWNrcygpO1xuICAgICAgfVxuICAgICAgc3RhZ2VzLmFmdGVyKCk7XG4gICAgICBpZiAoZWwuaXNDb25uZWN0ZWQpXG4gICAgICAgIHN0YWdlcy5jbGVhbnVwKCk7XG4gICAgICBkZWxldGUgZWwuX3hfdHJhbnNpdGlvbmluZztcbiAgICB9KTtcbiAgfSk7XG4gIGVsLl94X3RyYW5zaXRpb25pbmcgPSB7XG4gICAgYmVmb3JlQ2FuY2VsczogW10sXG4gICAgYmVmb3JlQ2FuY2VsKGNhbGxiYWNrKSB7XG4gICAgICB0aGlzLmJlZm9yZUNhbmNlbHMucHVzaChjYWxsYmFjayk7XG4gICAgfSxcbiAgICBjYW5jZWw6IG9uY2UoZnVuY3Rpb24oKSB7XG4gICAgICB3aGlsZSAodGhpcy5iZWZvcmVDYW5jZWxzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLmJlZm9yZUNhbmNlbHMuc2hpZnQoKSgpO1xuICAgICAgfVxuICAgICAgO1xuICAgICAgZmluaXNoKCk7XG4gICAgfSksXG4gICAgZmluaXNoXG4gIH07XG4gIG11dGF0ZURvbSgoKSA9PiB7XG4gICAgc3RhZ2VzLnN0YXJ0KCk7XG4gICAgc3RhZ2VzLmR1cmluZygpO1xuICB9KTtcbiAgaG9sZE5leHRUaWNrcygpO1xuICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgIGlmIChpbnRlcnJ1cHRlZClcbiAgICAgIHJldHVybjtcbiAgICBsZXQgZHVyYXRpb24gPSBOdW1iZXIoZ2V0Q29tcHV0ZWRTdHlsZShlbCkudHJhbnNpdGlvbkR1cmF0aW9uLnJlcGxhY2UoLywuKi8sIFwiXCIpLnJlcGxhY2UoXCJzXCIsIFwiXCIpKSAqIDFlMztcbiAgICBsZXQgZGVsYXkgPSBOdW1iZXIoZ2V0Q29tcHV0ZWRTdHlsZShlbCkudHJhbnNpdGlvbkRlbGF5LnJlcGxhY2UoLywuKi8sIFwiXCIpLnJlcGxhY2UoXCJzXCIsIFwiXCIpKSAqIDFlMztcbiAgICBpZiAoZHVyYXRpb24gPT09IDApXG4gICAgICBkdXJhdGlvbiA9IE51bWJlcihnZXRDb21wdXRlZFN0eWxlKGVsKS5hbmltYXRpb25EdXJhdGlvbi5yZXBsYWNlKFwic1wiLCBcIlwiKSkgKiAxZTM7XG4gICAgbXV0YXRlRG9tKCgpID0+IHtcbiAgICAgIHN0YWdlcy5iZWZvcmUoKTtcbiAgICB9KTtcbiAgICByZWFjaGVkQmVmb3JlID0gdHJ1ZTtcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgaWYgKGludGVycnVwdGVkKVxuICAgICAgICByZXR1cm47XG4gICAgICBtdXRhdGVEb20oKCkgPT4ge1xuICAgICAgICBzdGFnZXMuZW5kKCk7XG4gICAgICB9KTtcbiAgICAgIHJlbGVhc2VOZXh0VGlja3MoKTtcbiAgICAgIHNldFRpbWVvdXQoZWwuX3hfdHJhbnNpdGlvbmluZy5maW5pc2gsIGR1cmF0aW9uICsgZGVsYXkpO1xuICAgICAgcmVhY2hlZEVuZCA9IHRydWU7XG4gICAgfSk7XG4gIH0pO1xufVxuZnVuY3Rpb24gbW9kaWZpZXJWYWx1ZShtb2RpZmllcnMsIGtleSwgZmFsbGJhY2spIHtcbiAgaWYgKG1vZGlmaWVycy5pbmRleE9mKGtleSkgPT09IC0xKVxuICAgIHJldHVybiBmYWxsYmFjaztcbiAgY29uc3QgcmF3VmFsdWUgPSBtb2RpZmllcnNbbW9kaWZpZXJzLmluZGV4T2Yoa2V5KSArIDFdO1xuICBpZiAoIXJhd1ZhbHVlKVxuICAgIHJldHVybiBmYWxsYmFjaztcbiAgaWYgKGtleSA9PT0gXCJzY2FsZVwiKSB7XG4gICAgaWYgKGlzTmFOKHJhd1ZhbHVlKSlcbiAgICAgIHJldHVybiBmYWxsYmFjaztcbiAgfVxuICBpZiAoa2V5ID09PSBcImR1cmF0aW9uXCIgfHwga2V5ID09PSBcImRlbGF5XCIpIHtcbiAgICBsZXQgbWF0Y2ggPSByYXdWYWx1ZS5tYXRjaCgvKFswLTldKyltcy8pO1xuICAgIGlmIChtYXRjaClcbiAgICAgIHJldHVybiBtYXRjaFsxXTtcbiAgfVxuICBpZiAoa2V5ID09PSBcIm9yaWdpblwiKSB7XG4gICAgaWYgKFtcInRvcFwiLCBcInJpZ2h0XCIsIFwibGVmdFwiLCBcImNlbnRlclwiLCBcImJvdHRvbVwiXS5pbmNsdWRlcyhtb2RpZmllcnNbbW9kaWZpZXJzLmluZGV4T2Yoa2V5KSArIDJdKSkge1xuICAgICAgcmV0dXJuIFtyYXdWYWx1ZSwgbW9kaWZpZXJzW21vZGlmaWVycy5pbmRleE9mKGtleSkgKyAyXV0uam9pbihcIiBcIik7XG4gICAgfVxuICB9XG4gIHJldHVybiByYXdWYWx1ZTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2Nsb25lLmpzXG52YXIgaXNDbG9uaW5nID0gZmFsc2U7XG5mdW5jdGlvbiBza2lwRHVyaW5nQ2xvbmUoY2FsbGJhY2ssIGZhbGxiYWNrID0gKCkgPT4ge1xufSkge1xuICByZXR1cm4gKC4uLmFyZ3MpID0+IGlzQ2xvbmluZyA/IGZhbGxiYWNrKC4uLmFyZ3MpIDogY2FsbGJhY2soLi4uYXJncyk7XG59XG5mdW5jdGlvbiBvbmx5RHVyaW5nQ2xvbmUoY2FsbGJhY2spIHtcbiAgcmV0dXJuICguLi5hcmdzKSA9PiBpc0Nsb25pbmcgJiYgY2FsbGJhY2soLi4uYXJncyk7XG59XG5mdW5jdGlvbiBjbG9uZShvbGRFbCwgbmV3RWwpIHtcbiAgaWYgKCFuZXdFbC5feF9kYXRhU3RhY2spXG4gICAgbmV3RWwuX3hfZGF0YVN0YWNrID0gb2xkRWwuX3hfZGF0YVN0YWNrO1xuICBpc0Nsb25pbmcgPSB0cnVlO1xuICBkb250UmVnaXN0ZXJSZWFjdGl2ZVNpZGVFZmZlY3RzKCgpID0+IHtcbiAgICBjbG9uZVRyZWUobmV3RWwpO1xuICB9KTtcbiAgaXNDbG9uaW5nID0gZmFsc2U7XG59XG5mdW5jdGlvbiBjbG9uZVRyZWUoZWwpIHtcbiAgbGV0IGhhc1J1blRocm91Z2hGaXJzdEVsID0gZmFsc2U7XG4gIGxldCBzaGFsbG93V2Fsa2VyID0gKGVsMiwgY2FsbGJhY2spID0+IHtcbiAgICB3YWxrKGVsMiwgKGVsMywgc2tpcCkgPT4ge1xuICAgICAgaWYgKGhhc1J1blRocm91Z2hGaXJzdEVsICYmIGlzUm9vdChlbDMpKVxuICAgICAgICByZXR1cm4gc2tpcCgpO1xuICAgICAgaGFzUnVuVGhyb3VnaEZpcnN0RWwgPSB0cnVlO1xuICAgICAgY2FsbGJhY2soZWwzLCBza2lwKTtcbiAgICB9KTtcbiAgfTtcbiAgaW5pdFRyZWUoZWwsIHNoYWxsb3dXYWxrZXIpO1xufVxuZnVuY3Rpb24gZG9udFJlZ2lzdGVyUmVhY3RpdmVTaWRlRWZmZWN0cyhjYWxsYmFjaykge1xuICBsZXQgY2FjaGUgPSBlZmZlY3Q7XG4gIG92ZXJyaWRlRWZmZWN0KChjYWxsYmFjazIsIGVsKSA9PiB7XG4gICAgbGV0IHN0b3JlZEVmZmVjdCA9IGNhY2hlKGNhbGxiYWNrMik7XG4gICAgcmVsZWFzZShzdG9yZWRFZmZlY3QpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgfTtcbiAgfSk7XG4gIGNhbGxiYWNrKCk7XG4gIG92ZXJyaWRlRWZmZWN0KGNhY2hlKTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL3V0aWxzL2JpbmQuanNcbmZ1bmN0aW9uIGJpbmQoZWwsIG5hbW
1UsIHZhbHVlLCBtb2RpZmllcnMgPSBbXSkge1xuICBpZiAoIWVsLl94X2JpbmRpbmdzKVxuICAgIGVsLl94X2JpbmRpbmdzID0gcmVhY3RpdmUoe30pO1xuICBlbC5feF9iaW5kaW5nc1tuYW1lXSA9IHZhbHVlO1xuICBuYW1lID0gbW9kaWZpZXJzLmluY2x1ZGVzKFwiY2FtZWxcIikgPyBjYW1lbENhc2UobmFtZSkgOiBuYW1lO1xuICBzd2l0Y2ggKG5hbWUpIHtcbiAgICBjYXNlIFwidmFsdWVcIjpcbiAgICAgIGJpbmRJbnB1dFZhbHVlKGVsLCB2YWx1ZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIFwic3R5bGVcIjpcbiAgICAgIGJpbmRTdHlsZXMoZWwsIHZhbHVlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJjbGFzc1wiOlxuICAgICAgYmluZENsYXNzZXMoZWwsIHZhbHVlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJzZWxlY3RlZFwiOlxuICAgIGNhc2UgXCJjaGVja2VkXCI6XG4gICAgICBiaW5kQXR0cmlidXRlQW5kUHJvcGVydHkoZWwsIG5hbWUsIHZhbHVlKTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBiaW5kQXR0cmlidXRlKGVsLCBuYW1lLCB2YWx1ZSk7XG4gICAgICBicmVhaztcbiAgfVxufVxuZnVuY3Rpb24gYmluZElucHV0VmFsdWUoZWwsIHZhbHVlKSB7XG4gIGlmIChlbC50eXBlID09PSBcInJhZGlvXCIpIHtcbiAgICBpZiAoZWwuYXR0cmlidXRlcy52YWx1ZSA9PT0gdm9pZCAwKSB7XG4gICAgICBlbC52YWx1ZSA9IHZhbHVlO1xuICAgIH1cbiAgICBpZiAod2luZG93LmZyb21Nb2RlbCkge1xuICAgICAgZWwuY2hlY2tlZCA9IGNoZWNrZWRBdHRyTG9vc2VDb21wYXJlKGVsLnZhbHVlLCB2YWx1ZSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGVsLnR5cGUgPT09IFwiY2hlY2tib3hcIikge1xuICAgIGlmIChOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSkge1xuICAgICAgZWwudmFsdWUgPSB2YWx1ZTtcbiAgICB9IGVsc2UgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdHlwZW9mIHZhbHVlICE9PSBcImJvb2xlYW5cIiAmJiAhW251bGwsIHZvaWQgMF0uaW5jbHVkZXModmFsdWUpKSB7XG4gICAgICBlbC52YWx1ZSA9IFN0cmluZyh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICBlbC5jaGVja2VkID0gdmFsdWUuc29tZSgodmFsKSA9PiBjaGVja2VkQXR0ckxvb3NlQ29tcGFyZSh2YWwsIGVsLnZhbHVlKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbC5jaGVja2VkID0gISF2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAoZWwudGFnTmFtZSA9PT0gXCJTRUxFQ1RcIikge1xuICAgIHVwZGF0ZVNlbGVjdChlbCwgdmFsdWUpO1xuICB9IGVsc2Uge1xuICAgIGlmIChlbC52YWx1ZSA9PT0gdmFsdWUpXG4gICAgICByZXR1cm47XG4gICAgZWwudmFsdWUgPSB2YWx1ZTtcbiAgfVxufVxuZnVuY3Rpb24gYmluZENsYXNzZXMoZWwsIHZhbHVlKSB7XG4gIGlmIChlbC5feF91bmRvQWRkZWRDbGFzc2VzKVxuICAgIGVsLl94X3VuZG9BZGRlZENsYXNzZXMoKTtcbiAgZWwuX3hfdW5kb0FkZGVkQ2xhc3NlcyA9IHNldENsYXNzZXMoZWwsIHZhbHVlKTtcbn1cbmZ1bmN0aW9uIGJpbmRTdHlsZXMoZWwsIHZhbHVlKSB7XG4gIGlmIChlbC5feF91bmRvQWRkZWRTdHlsZXMpXG4gICAgZWwuX3hfdW5kb0FkZGVkU3R5bGVzKCk7XG4gIGVsLl94X3VuZG9BZGRlZFN0eWxlcyA9IHNldFN0eWxlcyhlbCwgdmFsdWUpO1xufVxuZnVuY3Rpb24gYmluZEF0dHJpYnV0ZUFuZFByb3BlcnR5KGVsLCBuYW1lLCB2YWx1ZSkge1xuICBiaW5kQXR0cmlidXRlKGVsLCBuYW1lLCB2YWx1ZSk7XG4gIHNldFByb3BlcnR5SWZDaGFuZ2VkKGVsLCBuYW1lLCB2YWx1ZSk7XG59XG5mdW5jdGlvbiBiaW5kQXR0cmlidXRlKGVsLCBuYW1lLCB2YWx1ZSkge1xuICBpZiAoW251bGwsIHZvaWQgMCwgZmFsc2VdLmluY2x1ZGVzKHZhbHVlKSAmJiBhdHRyaWJ1dGVTaG91bGRudEJlUHJlc2VydmVkSWZGYWxzeShuYW1lKSkge1xuICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoaXNCb29sZWFuQXR0cihuYW1lKSlcbiAgICAgIHZhbHVlID0gbmFtZTtcbiAgICBzZXRJZkNoYW5nZWQoZWwsIG5hbW
1UsIHZhbHVlKTtcbiAgfVxufVxuZnVuY3Rpb24gc2V0SWZDaGFuZ2VkKGVsLCBhdHRyTmFtZSwgdmFsdWUpIHtcbiAgaWYgKGVsLmdldEF0dHJpYnV0ZShhdHRyTmFtZSkgIT0gdmFsdWUpIHtcbiAgICBlbC5zZXRBdHRyaWJ1dGUoYXR0ck5hbWUsIHZhbHVlKTtcbiAgfVxufVxuZnVuY3Rpb24gc2V0UHJvcGVydHlJZkNoYW5nZWQoZWwsIHByb3BOYW1lLCB2YWx1ZSkge1xuICBpZiAoZWxbcHJvcE5hbWVdICE9PSB2YWx1ZSkge1xuICAgIGVsW3Byb3BOYW1lXSA9IHZhbHVlO1xuICB9XG59XG5mdW5jdGlvbiB1cGRhdGVTZWxlY3QoZWwsIHZhbHVlKSB7XG4gIGNvbnN0IGFycmF5V3JhcHBlZFZhbHVlID0gW10uY29uY2F0KHZhbHVlKS5tYXAoKHZhbHVlMikgPT4ge1xuICAgIHJldHVybiB2YWx1ZTIgKyBcIlwiO1xuICB9KTtcbiAgQXJyYXkuZnJvbShlbC5vcHRpb25zKS5mb3JFYWNoKChvcHRpb24pID0+IHtcbiAgICBvcHRpb24uc2VsZWN0ZWQgPSBhcnJheVdyYXBwZWRWYWx1ZS5pbmNsdWRlcyhvcHRpb24udmFsdWUpO1xuICB9KTtcbn1cbmZ1bmN0aW9uIGNhbWVsQ2FzZShzdWJqZWN0KSB7XG4gIHJldHVybiBzdWJqZWN0LnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvLShcXHcpL2csIChtYXRjaCwgY2hhcikgPT4gY2hhci50b1VwcGVyQ2FzZSgpKTtcbn1cbmZ1bmN0aW9uIGNoZWNrZWRBdHRyTG9vc2VDb21wYXJlKHZhbHVlQSwgdmFsdWVCKSB7XG4gIHJldHVybiB2YWx1ZUEgPT0gdmFsdWVCO1xufVxuZnVuY3Rpb24gaXNCb29sZWFuQXR0cihhdHRyTmFtZSkge1xuICBjb25zdCBib29sZWFuQXR0cmlidXRlcyA9IFtcbiAgICBcImRpc2FibGVkXCIsXG4gICAgXCJjaGVja2VkXCIsXG4gICAgXCJyZXF1aXJlZFwiLFxuICAgIFwicmVhZG9ubHlcIixcbiAgICBcImhpZGRlblwiLFxuICAgIFwib3BlblwiLFxuICAgIFwic2VsZWN0ZWRcIixcbiAgICBcImF1dG9mb2N1c1wiLFxuICAgIFwiaXRlbXNjb3BlXCIsXG4gICAgXCJtdWx0aXBsZVwiLFxuICAgIFwibm92YWxpZGF0ZVwiLFxuICAgIFwiYWxsb3dmdWxsc2NyZWVuXCIsXG4gICAgXCJhbGxvd3BheW1lbnRyZXF1ZXN0XCIsXG4gICAgXCJmb3Jtbm92YWxpZGF0ZVwiLFxuICAgIFwiYXV0b3BsYXlcIixcbiAgICBcImNvbnRyb2xzXCIsXG4gICAgXCJsb29wXCIsXG4gICAgXCJtdXRlZFwiLFxuICAgIFwicGxheXNpbmxpbmVcIixcbiAgICBcImRlZmF1bHRcIixcbiAgICBcImlzbWFwXCIsXG4gICAgXCJyZXZlcnNlZFwiLFxuICAgIFwiYXN5bmNcIixcbiAgICBcImRlZmVyXCIsXG4gICAgXCJub21vZHVsZVwiXG4gIF07XG4gIHJldHVybiBib29sZWFuQXR0cmlidXRlcy5pbmNsdWRlcyhhdHRyTmFtZSk7XG59XG5mdW5jdGlvbiBhdHRyaWJ1dGVTaG91bGRudEJlUHJlc2VydmVkSWZGYWxzeShuYW1lKSB7XG4gIHJldHVybiAhW1wiYXJpYS1wcmVzc2VkXCIsIFwiYXJpYS1jaGVja2VkXCIsIFwiYXJpYS1leHBhbmRlZFwiLCBcImFyaWEtc2VsZWN0ZWRcIl0uaW5jbHVkZXMobmFtZSk7XG59XG5mdW5jdGlvbiBnZXRCaW5kaW5nKGVsLCBuYW1lLCBmYWxsYmFjaykge1xuICBpZiAoZWwuX3hfYmluZGluZ3MgJiYgZWwuX3hfYmluZGluZ3NbbmFtZV0gIT09IHZvaWQgMClcbiAgICByZXR1cm4gZWwuX3hfYmluZGluZ3NbbmFtZV07XG4gIHJldHVybiBnZXRBdHRyaWJ1dGVCaW5kaW5nKGVsLCBuYW1lLCBmYWxsYmFjayk7XG59XG5mdW5jdGlvbiBleHRyYWN0UHJvcChlbCwgbmFtZSwgZmFsbGJhY2ssIGV4dHJhY3QgPSB0cnVlKSB7XG4gIGlmIChlbC5feF9iaW5kaW5ncyAmJiBlbC5feF9iaW5kaW5nc1tuYW1lXSAhPT0gdm9pZCAwKVxuICAgIHJldHVybiBlbC5feF9iaW5kaW5nc1tuYW1lXTtcbiAgaWYgKGVsLl94X2lubGluZUJpbmRpbmdzICYmIGVsLl94X2lubGluZUJpbmRpbmdzW25hbWVdICE9PSB2b2lkIDApIHtcbiAgICBsZXQgYmluZGluZyA9IGVsLl94X2lubGluZUJpbmRpbmdzW25hbWVdO1xuICAgIGJpbmRpbmcuZXh0cmFjdCA9IGV4dHJhY3Q7XG4gICAgcmV0dXJuIGRvbnRBdXRvRXZhbHVhdGVGdW5jdGlvbnMoKCkgPT4ge1xuICAgICAgcmV0dXJuIGV2YWx1YXRlKGVsLCBiaW5kaW5nLmV4cHJlc3Npb24pO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBnZXRBdHRyaWJ1dGVCaW5kaW5nKGVsLCBuYW1lLCBmYWxsYmFjayk7XG59XG5mdW5jdGlvbiBnZXRBdHRyaWJ1dGVCaW5kaW5nKGVsLCBuYW1lLCBmYWxsYmFjaykge1xuICBsZXQgYXR0ciA9IGVsLmdldEF0dHJpYnV0ZShuYW1lKTtcbiAgaWYgKGF0dHIgPT09IG51bGwpXG4gICAgcmV0dXJuIHR5cGVvZiBmYWxsYmFjayA9PT0gXCJmdW5jdGlvblwiID8gZmFsbGJhY2soKSA6IGZhbGxiYWNrO1xuICBpZiAoYXR0ciA9PT0gXCJcIilcbiAgICByZXR1cm4gdHJ1ZTtcbiAgaWYgKGlzQm9vbGVhbkF0dHIobmFtZSkpIHtcbiAgICByZXR1cm4gISFbbmFtZSwgXCJ0cnVlXCJdLmluY2x1ZGVzKGF0dHIpO1xuICB9XG4gIHJldHVybiBhdHRyO1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvdXRpbHMvZGVib3VuY2UuanNcbmZ1bmN0aW9uIGRlYm91bmNlKGZ1bmMsIHdhaXQpIHtcbiAgdmFyIHRpbWVvdXQ7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgY29udGV4dCA9IHRoaXMsIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgdmFyIGxhdGVyID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aW1lb3V0ID0gbnVsbDtcbiAgICAgIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgfTtcbiAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHdhaXQpO1xuICB9O1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvdXRpbHMvdGhyb3R0bGUuanNcbmZ1bmN0aW9uIHRocm90dGxlKGZ1bmMsIGxpbWl0KSB7XG4gIGxldCBpblRocm90dGxlO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgbGV0IGNvbnRleHQgPSB0aGlzLCBhcmdzID0gYXJndW1lbnRzO1xuICAgIGlmICghaW5UaHJvdHRsZSkge1xuICAgICAgZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgIGluVGhyb3R0bGUgPSB0cnVlO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiBpblRocm90dGxlID0gZmFsc2UsIGxpbWl0KTtcbiAgICB9XG4gI
1H07XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9wbHVnaW4uanNcbmZ1bmN0aW9uIHBsdWdpbihjYWxsYmFjaykge1xuICBsZXQgY2FsbGJhY2tzID0gQXJyYXkuaXNBcnJheShjYWxsYmFjaykgPyBjYWxsYmFjayA6IFtjYWxsYmFja107XG4gIGNhbGxiYWNrcy5mb3JFYWNoKChpKSA9PiBpKGFscGluZV9kZWZhdWx0KSk7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9zdG9yZS5qc1xudmFyIHN0b3JlcyA9IHt9O1xudmFyIGlzUmVhY3RpdmUgPSBmYWxzZTtcbmZ1bmN0aW9uIHN0b3JlKG5hbWUsIHZhbHVlKSB7XG4gIGlmICghaXNSZWFjdGl2ZSkge1xuICAgIHN0b3JlcyA9IHJlYWN0aXZlKHN0b3Jlcyk7XG4gICAgaXNSZWFjdGl2ZSA9IHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09PSB2b2lkIDApIHtcbiAgICByZXR1cm4gc3RvcmVzW25hbWVdO1xuICB9XG4gIHN0b3Jlc1tuYW1lXSA9IHZhbHVlO1xuICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlLmhhc093blByb3BlcnR5KFwiaW5pdFwiKSAmJiB0eXBlb2YgdmFsdWUuaW5pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgc3RvcmVzW25hbWVdLmluaXQoKTtcbiAgfVxuICBpbml0SW50ZXJjZXB0b3JzKHN0b3Jlc1tuYW1lXSk7XG59XG5mdW5jdGlvbiBnZXRTdG9yZXMoKSB7XG4gIHJldHVybiBzdG9yZXM7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9iaW5kcy5qc1xudmFyIGJpbmRzID0ge307XG5mdW5jdGlvbiBiaW5kMihuYW1lLCBiaW5kaW5ncykge1xuICBsZXQgZ2V0QmluZGluZ3MgPSB0eXBlb2YgYmluZGluZ3MgIT09IFwiZnVuY3Rpb25cIiA/ICgpID0+IGJpbmRpbmdzIDogYmluZGluZ3M7XG4gIGlmIChuYW1lIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgIGFwcGx5QmluZGluZ3NPYmplY3QobmFtZSwgZ2V0QmluZGluZ3MoKSk7XG4gIH0gZWxzZSB7XG4gICAgYmluZHNbbmFtZV0gPSBnZXRCaW5kaW5ncztcbiAgfVxufVxuZnVuY3Rpb24gaW5qZWN0QmluZGluZ1Byb3ZpZGVycyhvYmopIHtcbiAgT2JqZWN0LmVud
1HJpZXMoYmluZHMpLmZvckVhY2goKFtuYW1lLCBjYWxsYmFja10pID0+IHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBuYW1lLCB7XG4gICAgICBnZXQoKSB7XG4gICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgIHJldHVybiBjYWxsYmFjayguLi5hcmdzKTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBvYmo7XG59XG5mdW5jdGlvbiBhcHBseUJpbmRpbmdzT2JqZWN0KGVsLCBvYmosIG9yaWdpbmFsKSB7XG4gIGxldCBjbGVhbnVwUnVubmVycyA9IFtdO1xuICB3aGlsZSAoY2xlYW51cFJ1bm5lcnMubGVuZ3RoKVxuICAgIGNsZWFudXBSdW5uZXJzLnBvcCgpKCk7XG4gIGxldCBhdHRyaWJ1dGVzID0gT2JqZWN0LmVudHJpZXMob2JqKS5tYXAoKFtuYW1lLCB2YWx1ZV0pID0+ICh7bmFtZSwgdmFsdWV9KSk7XG4gIGxldCBzdGF0aWNBdHRyaWJ1dGVzID0gYXR0cmlidXRlc09ubHkoYXR0cmlidXRlcyk7XG4gIGF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzLm1hcCgoYXR0cmlidXRlKSA9PiB7XG4gICAgaWYgKHN0YXRpY0F0dHJpYnV0ZXMuZmluZCgoYXR0cikgPT4gYXR0ci5uYW1lID09PSBhdHRyaWJ1dGUubmFtZSkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5hbWU6IGB4LWJpbmQ6JHthdHRyaWJ1dGUubmFtZX1gLFxuICAgICAgICB2YWx1ZTogYFwiJHthdHRyaWJ1dGUudmFsdWV9XCJgXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gYXR0cmlidXRlO1xuICB9KTtcbiAgZGlyZWN0aXZlcyhlbCwgYXR0cmlidXRlcywgb3JpZ2luYWwpLm1hcCgoaGFuZGxlKSA9PiB7XG4gICAgY2xlYW51cFJ1bm5lcnMucHVzaChoYW5kbGUucnVuQ2xlYW51cHMpO1xuICAgIGhhbmRsZSgpO1xuICB9KTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RhdGFzLmpzXG52YXIgZGF0YXMgPSB7fTtcbmZ1bmN0aW9uIGRhdGEobmFtZSwgY2FsbGJhY2spIHtcbiAgZGF0YXNbbmFtZV0gPSBjYWxsYmFjaztcbn1cbmZ1bmN0aW9uIGluamVjdERhdGFQcm92aWRlcnMob2JqLCBjb250ZXh0KSB7XG4gIE9iamVjdC5lbnRyaWVzKGRhdGFzKS5mb3JFYWNoKChbbmFtZSwgY2FsbGJhY2tdKSA9PiB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgbmFtZSwge1xuICAgICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2suYmluZChjb250ZXh0KSguLi5hcmdzKTtcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZVxuICAgIH0pO1xuICB9KTtcbiAgcmV0dXJuIG9iajtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2FscGluZS5qc1xudmFyIEFscGluZSA9IHtcbiAgZ2V0IHJlYWN0aXZlKCkge1xuICAgIHJldHVybiByZWFjdGl2ZTtcbiAgfSxcbiAgZ2V0IHJlbGVhc2UoKSB7XG4gICAgcmV0dXJuIHJlbGVhc2U7XG4gIH0sXG4gIGdldCBlZmZlY3QoKSB7XG4gICAgcmV0dXJuIGVmZmVjdDtcbiAgfSxcbiAgZ2V0IHJhdygpIHtcbiAgICByZXR1cm4gcmF3O1xuICB9LFxuICB2ZXJzaW9uOiBcIjMuMTIuM1wiLFxuICBmbHVzaEFuZFN0b3BEZWZlcnJpbmdNdXRhdGlvbnMsXG4gIGRvbnRBdXRvRXZhbHVhdGVGdW5jdGlvbnMsXG4gIGRpc2FibGVFZmZlY3RTY2hlZHVsaW5nLFxuICBzdGFydE9ic2VydmluZ011dGF0aW9ucyxcbiAgc3RvcE9ic2VydmluZ011dGF0aW9ucyxcbiAgc2V0UmVhY3Rpdml0eUVuZ2luZSxcbiAgY2xvc2VzdERhdGFTdGFjayxcbiAgc2tpcER1cmluZ0Nsb25lLFxuICBvbmx5RHVyaW5nQ2xvbmUsXG4gIGFkZFJvb3RTZWxlY3RvcixcbiAgYWRkSW5pdFNlbGVjdG9yLFxuICBhZGRTY29wZVRvTm9kZSxcbiAgZGVmZXJNdXRhdGlvbnMsXG4gIG1hcEF0dHJpYnV0ZXMsXG4gIGV2YWx1YXRlTGF0ZXIsXG4gIGludGVyY2VwdEluaXQsXG4gIHNldEV2YWx1YXRvcixcbiAgbWVyZ2VQcm94aWVzLFxuICBleHRyYWN0UHJvcCxcbiAgZmluZENsb3Nlc3QsXG4gIGNsb3Nlc3RSb290LFxuICBkZXN0cm95VHJlZSxcbiAgaW50ZXJjZXB0b3IsXG4gIHRyYW5zaXRpb24sXG4gIHNldFN0eWxlcyxcbiAgbXV0YXRlRG9tLFxuICBkaXJlY3RpdmUsXG4gIHRocm90dGxlLFxuICBkZWJvdW5jZSxcbiAgZXZhbHVhdGUsXG4gIGluaXRUcmVlLFxuICBuZXh0VGljayxcbiAgcHJlZml4ZWQ6IHByZWZpeCxcbiAgcHJlZml4OiBzZXRQcmVmaXgsXG4gIHBsdWdpbixcbiAgbWFnaWMsXG4gIHN0b3JlLFxuICBzdGFydCxcbiAgY2xvbmUsXG4gIGJvdW5kOiBnZXRCaW5kaW5nLFxuICAkZGF0YTogc2NvcGUsXG4gIHdhbGssXG4gIGRhdGEsXG4gIGJpbmQ6IGJpbmQyXG59O1xudmFyIGFscGluZV9kZWZhdWx0ID0gQWxwaW5lO1xuXG4vLyBub2RlX21vZHVsZXMvQHZ1ZS9zaGFyZWQvZGlzdC9zaGFyZWQuZXNtLWJ1bmRsZXIuanNcbmZ1bmN0aW9uIG1ha2VNYXAoc3RyLCBleHBlY3RzTG93ZXJDYXNlKSB7XG4gIGNvbnN0IG1hcCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIGNvbnN0IGxpc3QgPSBzdHIuc3BsaXQoXCIsXCIpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICBtYXBbbGlzdFtpXV0gPSB0cnVlO1xuICB9XG4gIHJldHVybiBleHBlY3RzTG93ZXJDYXNlID8gKHZhbCkgPT4gISFtYXBbdmFsLnRvTG93ZXJDYXNlKCldIDogKHZhbCkgPT4gISFtYXBbdmFsXTtcbn1cbnZhciBQYXRjaEZsYWdOYW1lcyA9IHtcbiAgWzFdOiBgVEVYVGAsXG4gIFsyXTogYENMQVNTYCxcbiAgWzRdOiBgU1RZTEVgLFxuICBbOF06IGBQUk9QU2AsXG4gIFsxNl06IGBGVUxMX1BST1BTYCxcbiAgWzMyXTogYEhZRFJBVEVfRVZFTlRTYCxcbiAgWzY0XTogYFNUQUJMRV9GUkFHTUVOVGAsXG4gIFsxMjhdOiBgS0VZRURfRlJBR01FTlRgLFxuICBbMjU2XTogYFVOS0VZRURfRlJBR01FTlRgLFxuICBbNTEyXTogYE5FRURfUEFUQ0hgLFxuICBbMTAyNF06IGBEWU5BTUlDX1NMT1RTYCxcbiAgWzIwNDhdOiBgREVWX1JPT1RfRlJBR01FTlRgLFxuICBbLTFdOiBgSE9JU1RFRGAsXG4gIFstMl06IGBCQUlMYFxufTtcbnZhciBzbG90RmxhZ3NUZXh0ID0ge1xuICBbMV06IFwiU1RBQkxFXCIsXG4gIFsyXTogXCJEWU5BTUlDXCIsXG4gIFszXTogXCJGT1JXQVJERURcIlxufTtcbnZhciBzcGVjaWFsQm9vbGVhbkF0dHJzID0gYGl0ZW1zY29wZSxhbGxvd2Z1bGxzY3JlZW4sZm9ybW5vdmFsaWRhdGUsaXNtYXAsbm9tb2R1bGUsbm92YWxpZGF0ZSxyZWFkb25seWA7XG52YXIgaXNCb29sZWFuQXR0cjIgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChzcGVjaWFsQm9vbGVhbkF0dHJzICsgYCxhc3luYyxhdXRvZm9jdXMsYXV0b3BsYXksY29udHJvbHMsZGVmYXVsdCxkZWZlcixkaXNhYmxlZCxoaWRkZW4sbG9vcCxvcGVuLHJlcXVpcmVkLHJldmVyc2VkLHNjb3BlZCxzZWFtbGVzcyxjaGVja2VkLG11dGVkLG11bHRpcGxlLHNlbGVjdGVkYCk7XG52YXIgRU1QVFlfT0JKID0gdHJ1ZSA/IE9iamVjdC5mcmVlemUoe30pIDoge307XG52YXIgRU1QVFlfQVJSID0gdHJ1ZSA/IE9iamVjdC5mcmVlemUoW10pIDogW107XG52YXIgZXh0ZW5kID0gT2JqZWN0LmFzc2lnbjtcbnZhciBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgaGFzT3duID0gKHZhbCwga2V5KSA9PiBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbCwga2V5KTtcbnZhciBpc0FycmF
15ID0gQXJyYXkuaXNBcnJheTtcbnZhciBpc01hcCA9ICh2YWwpID0+IHRvVHlwZVN0cmluZyh2YWwpID09PSBcIltvYmplY3QgTWFwXVwiO1xudmFyIGlzU3RyaW5nID0gKHZhbCkgPT4gdHlwZW9mIHZhbCA9PT0gXCJzdHJpbmdcIjtcbnZhciBpc1N5bWJvbCA9ICh2YWwpID0+IHR5cGVvZiB2YWwgPT09IFwic3ltYm9sXCI7XG52YXIgaXNPYmplY3QgPSAodmFsKSA9PiB2YWwgIT09IG51bGwgJiYgdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIjtcbnZhciBvYmplY3RUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgdG9UeXBlU3RyaW5nID0gKHZhbHVlKSA9PiBvYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbnZhciB0b1Jhd1R5cGUgPSAodmFsdWUpID0+IHtcbiAgcmV0dXJuIHRvVHlwZVN0cmluZyh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xufTtcbnZhciBpc0ludGVnZXJLZXkgPSAoa2V5KSA9PiBpc1N0cmluZyhrZXkpICYmIGtleSAhPT0gXCJOYU5cIiAmJiBrZXlbMF0gIT09IFwiLVwiICYmIFwiXCIgKyBwYXJzZUludChrZXksIDEwKSA9PT0ga2V5O1xudmFyIGNhY2hlU3RyaW5nRnVuY3Rpb24gPSAoZm4pID0+IHtcbiAgY29uc3QgY2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICByZXR1cm4gKHN0cikgPT4ge1xuICAgIGNvbnN0IGhpdCA9IGNhY2hlW3N0cl07XG4gICAgcmV0dXJuIGhpdCB8fCAoY2FjaGVbc3RyXSA9IGZuKHN0cikpO1xuICB9O1xufTtcbnZhciBjYW1lbGl6ZVJFID0gLy0oXFx3KS9nO1xudmFyIGNhbWVsaXplID0gY2FjaGVTdHJpbmdGdW5jdGlvbigoc3RyKSA9PiB7XG4gIHJldHVybiBzdHIucmVwbGFjZShjYW1lbGl6ZVJFLCAoXywgYykgPT4gYyA/IGMudG9VcHBlckNhc2UoKSA6IFwiXCIpO1xufSk7XG52YXIgaHlwaGVuYXRlUkUgPSAvXFxCKFtBLVpdKS9nO1xudmFyIGh5cGhlbmF0ZSA9IGNhY2hlU3RyaW5nRnVuY3Rpb24oKHN0cikgPT4gc3RyLnJlcGxhY2UoaHlwaGVuYXRlUkUsIFwiLSQxXCIpLnRvTG93ZXJDYXNlKCkpO1xudmFyIGNhcGl0YWxpemUgPSBjYWNoZVN0cmluZ0Z1bmN0aW9uKChzdHIpID0+IHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKSk7XG52YXIgdG9IYW5kbGVyS2V5ID0gY2FjaGVTdHJpbmdGdW5jdGlvbigoc3RyKSA9PiBzdHIgPyBgb24ke2NhcGl0YWxpemUoc3RyKX1gIDogYGApO1xudmFyIGhhc0NoYW5nZWQgPSAodmFsdWUsIG9sZFZhbHVlKSA9PiB2YWx1ZSAhPT0gb2xkVmFsdWUgJiYgKHZhbHVlID09PSB2YWx1ZSB8fCBvbGRWYWx1ZSA9PT0gb2xkVmFsdWUpO1xuXG4vLyBub2RlX21vZHVsZXMvQHZ1ZS9yZWFjdGl2aXR5L2Rpc3QvcmVhY3Rpdml0eS5lc20tYnVuZGxlci5qc1xudmFyIHRhcmdldE1hcCA9IG5ldyBXZWFrTWFwKCk7XG52YXIgZWZmZWN0U3RhY2sgPSBbXTtcbnZhciBhY3RpdmVFZmZlY3Q7XG52YXIgSVRFUkFURV9LRVkgPSBTeW1ib2wodHJ1ZSA/IFwiaXRlcmF0ZVwiIDogXCJcIik7XG52YXIgTUFQX0tFWV9JVEVSQVRFX0tFWSA9IFN5bWJvbCh0cnVlID8gXCJNYXAga2V5IGl0ZXJhdGVcIiA6IFwiXCIpO1xuZnVuY3Rpb24gaXNFZmZlY3QoZm4pIHtcbiAgcmV0dXJuIGZuICYmIGZuLl9pc0VmZmVjdCA9PT0gdHJ1ZTtcbn1cbmZ1bmN0aW9uIGVmZmVjdDIoZm4sIG9wdGlvbnMgPSBFTVBUWV9PQkopIHtcbiAgaWYgKGlzRWZmZWN0KGZuKSkge1xuICAgIGZuID0gZm4ucmF3O1xuICB9XG4gIGNvbnN0IGVmZmVjdDMgPSBjcmVhdGVSZWFjdGl2ZUVmZmVjdChmbiwgb3B0aW9ucyk7XG4gIGlmICghb3B0aW9ucy5sYXp5KSB7XG4gICAgZWZmZWN0MygpO1xuICB9XG4gIHJldHVybiBlZmZlY3QzO1xufVxuZnVuY3Rpb24gc3RvcChlZmZlY3QzKSB7XG4gIGlmIChlZmZlY3QzLmFjdGl2ZSkge1xuICAgIGNsZWFudXAoZWZmZWN0Myk7XG4gICAgaWYgKGVmZmVjdDMub3B0aW9ucy5vblN0b3ApIHtcbiAgICAgIGVmZmVjdDMub3B0aW9ucy5vblN0b3AoKTtcbiAgICB9XG4gICAgZWZmZWN0My5hY3RpdmUgPSBmYWxzZTtcbiAgfVxufVxudmFyIHVpZCA9IDA7XG5mdW5jdGlvbiBjcmVhdGVSZWFjdGl2ZUVmZmVjdChmbiwgb3B0aW9ucykge1xuICBjb25zdCBlZmZlY3QzID0gZnVuY3Rpb24gcmVhY3RpdmVFZmZlY3QoKSB7XG4gICAgaWYgKCFlZmZlY3QzLmFjdGl2ZSkge1xuICAgICAgcmV0dXJuIGZuKCk7XG4gICAgfVxuICAgIGlmICghZWZmZWN0U3RhY2suaW5jbHVkZXMoZWZmZWN0MykpIHtcbiAgICAgIGNsZWFudXAoZWZmZWN0Myk7XG4gICAgICB0cnkge1xuICAgICAgICBlbmFibGVUcmFja2luZygpO1xuICAgICAgICBlZmZlY3RTdGFjay5wdXNoKGVmZmVjdDMpO1xuICAgICAgICBhY3RpdmVFZmZlY3QgPSBlZmZlY3QzO1xuICAgICAgICByZXR1cm4gZm4oKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGVmZmVjdFN0YWNrLnBvcCgpO1xuICAgICAgICByZXNldFRyYWNraW5nKCk7XG4gICAgICAgIGFjdGl2ZUVmZmVjdCA9IGVmZmVjdFN0YWNrW2VmZmVjdFN0YWNrLmxlbmd0aCAtIDFdO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgZWZmZWN0My5pZCA9IHVpZCsrO1xuICBlZmZlY3QzLmFsbG93UmVjdXJzZSA9ICEhb3B0aW9ucy5hbGxvd1JlY3Vyc2U7XG4gIGVmZmVjdDMuX2lzRWZmZWN0ID0gdHJ1ZTtcbiAgZWZmZWN0My5hY3RpdmUgPSB0cnVlO1xuICBlZmZlY3QzLnJhdyA9IGZuO1xuICBlZmZlY3QzLmRlcHMgPSBbXTtcbiAgZWZmZWN0My5vcHRpb25zID0gb3B0aW9ucztcbiAgcmV0dXJuIGVmZmVjdDM7XG59XG5mdW5jdGlvbiBjbGVhbnVwKGVmZmVjdDMpIHtcbiAgY29uc3Qge2RlcHN9ID0gZWZmZWN0MztcbiAgaWYgKGRlcHMubGVuZ3RoKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZXBzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBkZXBzW2ldLmRlbGV0ZShlZmZlY3QzKTtcbiAgICB9XG4gICAgZGVwcy5sZW5ndGggPSAwO1xuICB9XG59XG52YXIgc2hvdWxkVHJhY2sgPSB0cnVlO1xudmFyIHRyYWNrU3RhY2sgPSBbXTtcbmZ1bmN0aW9uIHBhdXNlVHJhY2tpbmcoKSB7XG4gIHRyYWNrU3RhY2sucHVzaChzaG91bGRUcmFjayk7XG4gIHNob3VsZFRyYWNrID0gZmFsc2U7XG59XG5mdW5jdGlvbiBlbmFibGVUcmFja2luZygpIHtcbiAgdHJhY2tTdGFjay5wdXNoKHNob3VsZFRyYWNrKTtcbiAgc2hvdWxkVHJhY2sgPSB0cnVlO1xufVxuZnVuY3Rpb24gcmVzZXRUcmFja2luZygpIHtcbiAgY29uc3QgbGFzdCA9IHRyYWNrU3RhY2sucG9wKCk7XG4gIHNob3VsZFRyYWNrID0gbGFzdCA9PT0gdm9pZCAwID8gdHJ1ZSA6IGxhc3Q7XG59XG5mdW5jdGlvbiB0cmFjayh0YXJnZXQsIHR5cGUsIGtleSkge1xuICBpZiAoIXNob3VsZFRyYWNrIHx8IGFjdGl2ZUVmZmVjdCA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCBkZXBzTWFwID0gdGFyZ2V0TWFwLmdldCh0YXJnZXQpO1xuICBpZiAoIWRlcHNNYXApIHtcbiAgICB0YXJnZXRNYXAuc2V0KHRhcmdldCwgZGVwc01hcCA9IG5ldyBNYXAoKSk7XG4gIH1cbiAgbGV0IGRlcCA9IGRlcHNNYXAuZ2V0KGtleSk7XG4gIGlmICghZGVwKSB7XG4gICAgZGVwc01hcC5zZXQoa2V5LCBkZXAgPSBuZXcgU2V0KCkpO1xuICB9XG4gIGlmICghZGVwLmhhcyhhY3RpdmVFZmZlY3QpKSB7XG4gICAgZGVwLmFkZChhY3RpdmVFZmZlY3QpO1xuICAgIGFjdGl2ZUVmZmVjdC5kZXBzLnB1c2goZGVwKTtcbiAgICBpZiAoYWN0aXZlRWZmZWN0Lm9wdGlvbnMub25UcmFjaykge1xuICAgICAgYWN0aXZlRWZmZWN0Lm9wdGlvbnMub25UcmFjayh7XG4gICAgICAgIGVmZmVjdDogYWN0aXZlRWZmZWN0LFxuICAgICAgICB0YXJnZXQsXG4gICAgICAgI
1HR5cGUsXG4gICAgICAgIGtleVxuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiB0cmlnZ2VyKHRhcmdldCwgdHlwZSwga2V5LCBuZXdWYWx1ZSwgb2xkVmFsdWUsIG9sZFRhcmdldCkge1xuICBjb25zdCBkZXBzTWFwID0gdGFyZ2V0TWFwLmdldCh0YXJnZXQpO1xuICBpZiAoIWRlcHNNYXApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgZWZmZWN0cyA9IG5ldyBTZXQoKTtcbiAgY29uc3QgYWRkMiA9IChlZmZlY3RzVG9BZGQpID0+IHtcbiAgICBpZiAoZWZmZWN0c1RvQWRkKSB7XG4gICAgICBlZmZlY3RzVG9BZGQuZm9yRWFjaCgoZWZmZWN0MykgPT4ge1xuICAgICAgICBpZiAoZWZmZWN0MyAhPT0gYWN0aXZlRWZmZWN0IHx8IGVmZmVjdDMuYWxsb3dSZWN1cnNlKSB7XG4gICAgICAgICAgZWZmZWN0cy5hZGQoZWZmZWN0Myk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcbiAgaWYgKHR5cGUgPT09IFwiY2xlYXJcIikge1xuICAgIGRlcHNNYXAuZm9yRWFjaChhZGQyKTtcbiAgfSBlbHNlIGlmIChrZXkgPT09IFwibGVuZ3RoXCIgJiYgaXNBcnJheSh0YXJnZXQpKSB7XG4gICAgZGVwc01hcC5mb3JFYWNoKChkZXAsIGtleTIpID0+IHtcbiAgICAgIGlmIChrZXkyID09PSBcImxlbmd0aFwiIHx8IGtleTIgPj0gbmV3VmFsdWUpIHtcbiAgICAgICAgYWRkMihkZXApO1xuICAgICAgfVxuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGlmIChrZXkgIT09IHZvaWQgMCkge1xuICAgICAgYWRkMihkZXBzTWFwLmdldChrZXkpKTtcbiAgICB9XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIFwiYWRkXCI6XG4gICAgICAgIGlmICghaXNBcnJheSh0YXJnZXQpKSB7XG4gICAgICAgICAgYWRkMihkZXBzTWFwLmdldChJVEVSQVRFX0tFWSkpO1xuICAgICAgICAgIGlmIChpc01hcCh0YXJnZXQpKSB7XG4gICAgICAgICAgICBhZGQyKGRlcHNNYXAuZ2V0KE1BUF9LRVlfSVRFUkFURV9LRVkpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoaXNJbnRlZ2VyS2V5KGtleSkpIHtcbiAgICAgICAgICBhZGQyKGRlcHNNYXAuZ2V0KFwibGVuZ3RoXCIpKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJkZWxldGVcIjpcbiAgICAgICAgaWYgKCFpc0FycmF5KHRhcmdldCkpIHtcbiAgICAgICAgICBhZGQyKGRlcHNNYXAuZ2V0KElURVJBVEVfS0VZKSk7XG4gICAgICAgICAgaWYgKGlzTWFwKHRhcmdldCkpIHtcbiAgICAgICAgICAgIGFkZDIoZGVwc01hcC5nZXQoTUFQX0tFWV9JVEVSQVRFX0tFWSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJzZXRcIjpcbiAgICAgICAgaWYgKGlzTWFwKHRhcmdldCkpIHtcbiAgICAgICAgICBhZGQyKGRlcHNNYXAuZ2V0KElURVJBVEVfS0VZKSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGNvbnN0IHJ1biA9IChlZmZlY3QzKSA9PiB7XG4gICAgaWYgKGVmZmVjdDMub3B0aW9ucy5vblRyaWdnZXIpIHtcbiAgICAgIGVmZmVjdDMub3B0aW9ucy5vblRyaWdnZXIoe1xuICAgICAgICBlZmZlY3Q6IGVmZmVjdDMsXG4gICAgICAgIHRhcmdldCxcbiAgICAgICAga2V5LFxuICAgICAgICB0eXBlLFxuICAgICAgICBuZXdWYWx1ZSxcbiAgICAgICAgb2xkVmFsdWUsXG4gICAgICAgIG9sZFRhcmdldFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChlZmZlY3QzLm9wdGlvbnMuc2NoZWR1bGVyKSB7XG4gICAgICBlZmZlY3QzLm9wdGlvbnMuc2NoZWR1bGVyKGVmZmVjdDMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlZmZlY3QzKCk7XG4gICAgfVxuICB9O1xuICBlZmZlY3RzLmZvckVhY2gocnVuKTtcbn1cbnZhciBpc05vblRyYWNrYWJsZUtleXMgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChgX19wcm90b19fLF9fdl9pc1JlZixfX2lzVnVlYCk7XG52YXIgYnVpbHRJblN5bWJvbHMgPSBuZXcgU2V0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKFN5bWJvbCkubWFwKChrZXkpID0+IFN5bWJvbFtrZXldKS5maWx0ZXIoaXNTeW1ib2wpKTtcbnZhciBnZXQyID0gLyogQF9fUFVSRV9fICovIGNyZWF0ZUdldHRlcigpO1xudmFyIHNoYWxsb3dHZXQgPSAvKiBAX19QVVJFX18gKi8gY3JlYXRlR2V0dGVyKGZhbHNlLCB0cnVlKTtcbnZhciByZWFkb25seUdldCA9IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVHZXR0ZXIodHJ1ZSk7XG52YXIgc2hhbGxvd1JlYWRvbmx5R2V0ID0gLyogQF9fUFVSRV9fICovIGNyZWF0ZUdldHRlcih0cnVlLCB0cnVlKTtcbnZhciBhcnJheUluc3RydW1lbnRhdGlvbnMgPSB7fTtcbltcImluY2x1ZGVzXCIsIFwiaW5kZXhPZlwiLCBcImxhc3RJbmRleE9mXCJdLmZvckVhY2goKGtleSkgPT4ge1xuICBjb25zdCBtZXRob2QgPSBBcnJheS5wcm90b3R5cGVba2V5XTtcbiAgYXJyYXlJbnN0cnVtZW50YXRpb25zW2tleV0gPSBmdW5jdGlvbiguLi5hcmdzKSB7XG4gICAgY29uc3QgYXJyID0gdG9SYXcodGhpcyk7XG4gICAgZm9yIChsZXQgaSA9IDAsIGwgPSB0aGlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdHJhY2soYXJyLCBcImdldFwiLCBpICsgXCJcIik7XG4gICAgfVxuICAgIGNvbnN0IHJlcyA9IG1ldGhvZC5hcHBseShhcnIsIGFyZ3MpO1xuICAgIGlmIChyZXMgPT09IC0xIHx8IHJlcyA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiBtZXRob2QuYXBwbHkoYXJyLCBhcmdzLm1hcCh0b1JhdykpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgfTtcbn0pO1xuW1wicHVzaFwiLCBcInBvcFwiLCBcInNoaWZ0XCIsIFwidW5zaGlmdFwiLCBcInNwbGljZVwiXS5mb3JFYWNoKChrZXkpID0+IHtcbiAgY29uc3QgbWV0aG9kID0gQXJyYXkucHJvdG90eXBlW2tleV07XG4gIGFycmF5SW5zdHJ1bWVudGF0aW9uc1trZXldID0gZnVuY3Rpb24oLi4uYXJncykge1xuICAgIHBhdXNlVHJhY2tpbmcoKTtcbiAgICBjb25zdCByZXMgPSBtZXRob2QuYXBwbHkodGhpcywgYXJncyk7XG4gICAgcmVzZXRUcmFja2luZygpO1xuICAgIHJldHVybiByZXM7XG4gIH07XG59KTtcbmZ1bmN0aW9uIGNyZWF0ZUdldHRlcihpc1JlYWRvbmx5ID0gZmFsc2UsIHNoYWxsb3cgPSBmYWxzZSkge1xuICByZXR1cm4gZnVuY3Rpb24gZ2V0Myh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpIHtcbiAgICBpZiAoa2V5ID09PSBcIl9fdl9pc1JlYWN0aXZlXCIpIHtcbiAgICAgIHJldHVybiAhaXNSZWFkb25seTtcbiAgICB9IGVsc2UgaWYgKGtleSA9PT0gXCJfX3ZfaXNSZWFkb25seVwiKSB7XG4gICAgICByZXR1cm4gaXNSZWFkb25seTtcbiAgICB9IGVsc2UgaWYgKGtleSA9PT0gXCJfX3ZfcmF3XCIgJiYgcmVjZWl2ZXIgPT09IChpc1JlYWRvbmx5ID8gc2hhbGxvdyA/IHNoYWxsb3dSZWFkb25seU1hcCA6IHJlYWRvbmx5TWFwIDogc2hhbGxvdyA/IHNoYWxsb3dSZWFjdGl2ZU1hcCA6IHJlYWN0aXZlTWFwKS5nZXQodGFyZ2V0KSkge1xuICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG4gICAgY29uc3QgdGFyZ2V0SXNBcnJheSA9IGlzQXJyYXkodGFyZ2V0KTtcbiAgICBpZiAoIWlzUmVhZG9ubHkgJiYgdGFyZ2V0SXNBcnJheSAmJiBoYXNPd24oYXJyYXlJbnN0cnVtZW50YXRpb25zLCBrZXkpKSB7XG4gICAgICByZXR1cm4gUmVmbGVjdC5nZXQoYXJyYXlJbnN0cnVtZW50YXRpb25zLCBrZXksIHJlY2VpdmVyKTtcbiAgICB9XG4gICAgY29uc3QgcmVzID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBrZXksIHJlY2VpdmVyKTtcbiAgICBpZiAoaXNTeW1ib2woa2V5KSA/IGJ1aWx0SW5TeW1ib2xzLmhhcyhrZXkpIDogaXNOb25UcmFja2FibGVLZXlzKGtleSkpIHtcbiAgICAgIHJldHVybi
1ByZXM7XG4gICAgfVxuICAgIGlmICghaXNSZWFkb25seSkge1xuICAgICAgdHJhY2sodGFyZ2V0LCBcImdldFwiLCBrZXkpO1xuICAgIH1cbiAgICBpZiAoc2hhbGxvdykge1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gICAgaWYgKGlzUmVmKHJlcykpIHtcbiAgICAgIGNvbnN0IHNob3VsZFVud3JhcCA9ICF0YXJnZXRJc0FycmF5IHx8ICFpc0ludGVnZXJLZXkoa2V5KTtcbiAgICAgIHJldHVybiBzaG91bGRVbndyYXAgPyByZXMudmFsdWUgOiByZXM7XG4gICAgfVxuICAgIGlmIChpc09iamVjdChyZXMpKSB7XG4gICAgICByZXR1cm4gaXNSZWFkb25seSA/IHJlYWRvbmx5KHJlcykgOiByZWFjdGl2ZTIocmVzKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcbn1cbnZhciBzZXQyID0gLyogQF9fUFVSRV9fICovIGNyZWF0ZVNldHRlcigpO1xudmFyIHNoYWxsb3dTZXQgPSAvKiBAX19QVVJFX18gKi8gY3JlYXRlU2V0dGVyKHRydWUpO1xuZnVuY3Rpb24gY3JlYXRlU2V0dGVyKHNoYWxsb3cgPSBmYWxzZSkge1xuICByZXR1cm4gZnVuY3Rpb24gc2V0Myh0YXJnZXQsIGtleSwgdmFsdWUsIHJlY2VpdmVyKSB7XG4gICAgbGV0IG9sZFZhbHVlID0gdGFyZ2V0W2tleV07XG4gICAgaWYgKCFzaGFsbG93KSB7XG4gICAgICB2YWx1ZSA9IHRvUmF3KHZhbHVlKTtcbiAgICAgIG9sZFZhbHVlID0gdG9SYXcob2xkVmFsdWUpO1xuICAgICAgaWYgKCFpc0FycmF5KHRhcmdldCkgJiYgaXNSZWYob2xkVmFsdWUpICYmICFpc1JlZih2YWx1ZSkpIHtcbiAgICAgICAgb2xkVmFsdWUudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGhhZEtleSA9IGlzQXJyYXkodGFyZ2V0KSAmJiBpc0ludGVnZXJLZXkoa2V5KSA/IE51bWJlcihrZXkpIDwgdGFyZ2V0Lmxlbmd0aCA6IGhhc093bih0YXJnZXQsIGtleSk7XG4gICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5zZXQodGFyZ2V0LCBrZXksIHZhbHVlLCByZWNlaXZlcik7XG4gICAgaWYgKHRhcmdldCA9PT0gdG9SYXcocmVjZWl2ZXIpKSB7XG4gICAgICBpZiAoIWhhZEtleSkge1xuICAgICAgICB0cmlnZ2VyKHRhcmdldCwgXCJhZGRcIiwga2V5LCB2YWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKGhhc0NoYW5nZWQodmFsdWUsIG9sZFZhbHVlKSkge1xuICAgICAgICB0cmlnZ2VyKHRhcmdldCwgXCJzZXRcIiwga2V5LCB2YWx1ZSwgb2xkVmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufVxuZnVuY3Rpb24gZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBrZXkpIHtcbiAgY29uc3QgaGFkS2V5ID0gaGFzT3duKHRhcmdldCwga2V5KTtcbiAgY29uc3Qgb2xkVmFsdWUgPSB0YXJnZXRba2V5XTtcbiAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5kZWxldGVQcm9wZXJ0eSh0YXJnZXQsIGtleSk7XG4gIGlmIChyZXN1bHQgJiYgaGFkS2V5KSB7XG4gICAgdHJpZ2dlcih0YXJnZXQsIFwiZGVsZXRlXCIsIGtleSwgdm9pZCAwLCBvbGRWYWx1ZSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGhhcyh0YXJnZXQsIGtleSkge1xuICBjb25zdCByZXN1bHQgPSBSZWZsZWN0Lmhhcyh0YXJnZXQsIGtleSk7XG4gIGlmICghaXNTeW1ib2woa2V5KSB8fCAhYnVpbHRJblN5bWJvbHMuaGFzKGtleSkpIHtcbiAgICB0cmFjayh0YXJnZXQsIFwiaGFzXCIsIGtleSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIG93bktleXModGFyZ2V0KSB7XG4gIHRyYWNrKHRhcmdldCwgXCJpdGVyYXRlXCIsIGlzQXJyYXkodGFyZ2V0KSA/IFwibGVuZ3RoXCIgOiBJVEVSQVRFX0tFWSk7XG4gIHJldHVybiBSZWZsZWN0Lm93bktleXModGFyZ2V0KTtcbn1cbnZhciBtdXRhYmxlSGFuZGxlcnMgPSB7XG4gIGdldDogZ2V0MixcbiAgc2V0OiBzZXQyLFxuICBkZWxldGVQcm9wZXJ0eSxcbiAgaGFzLFxuICBvd25LZXlzXG59O1xudmFyIHJlYWRvbmx5SGFuZGxlcnMgPSB7XG4gIGdldDogcmVhZG9ubHlHZXQsXG4gIHNldCh0YXJnZXQsIGtleSkge1xuICAgIGlmICh0cnVlKSB7XG4gICAgICBjb25zb2xlLndhcm4oYFNldCBvcGVyYXRpb24gb24ga2V5IFwiJHtTdHJpbmcoa2V5KX1cIiBmYWlsZWQ6IHRhcmdldCBpcyByZWFkb25seS5gLCB0YXJnZXQpO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSxcbiAgZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBrZXkpIHtcbiAgICBpZiAodHJ1ZSkge1xuICAgICAgY29uc29sZS53YXJuKGBEZWxldGUgb3BlcmF0aW9uIG9uIGtleSBcIiR7U3RyaW5nKGtleSl9XCIgZmFpbGVkOiB0YXJnZXQgaXMgcmVhZG9ubHkuYCwgdGFyZ2V0KTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn07XG52YXIgc2hhbGxvd1JlYWN0aXZlSGFuZGxlcnMgPSBleHRlbmQoe30sIG11dGFibGVIYW5kbGVycywge1xuICBnZXQ6IHNoYWxsb3dHZXQsXG4gIHNldDogc2hhbGxvd1NldFxufSk7XG52YXIgc2hhbGxvd1JlYWRvbmx5SGFuZGxlcnMgPSBleHRlbmQoe30sIHJlYWRvbmx5SGFuZGxlcnMsIHtcbiAgZ2V0OiBzaGFsbG93UmVhZG9ubHlHZXRcbn0pO1xudmFyIHRvUmVhY3RpdmUgPSAodmFsdWUpID0+IGlzT2JqZWN0KHZhbHVlKSA/IHJlYWN0aXZlMih2YWx1ZSkgOiB2YWx1ZTtcbnZhciB0b1JlYWRvbmx5ID0gKHZhbHVlKSA9PiBpc09iamVjdCh2YWx1ZSkgPyByZWFkb25seSh2YWx1ZSkgOiB2YWx1ZTtcbnZhciB0b1NoYWxsb3cgPSAodmFsdWUpID0+IHZhbHVlO1xudmFyIGdldFByb3RvID0gKHYpID0+IFJlZmxlY3QuZ2V0UHJvdG90eXBlT2Yodik7XG5mdW5jdGlvbiBnZXQkMSh0YXJnZXQsIGtleSwgaXNSZWFkb25seSA9IGZhbHNlLCBpc1NoYWxsb3cgPSBmYWxzZSkge1xuICB0YXJnZXQgPSB0YXJnZXRbXCJfX3ZfcmF3XCJdO1xuICBjb25zdCByYXdUYXJnZXQgPSB0b1Jhdyh0YXJnZXQpO1xuICBjb25zdCByYXdLZXkgPSB0b1JhdyhrZXkpO1xuICBpZiAoa2V5ICE9PSByYXdLZXkpIHtcbiAgICAhaXNSZWFkb25seSAmJiB0cmFjayhyYXdUYXJnZXQsIFwiZ2V0XCIsIGtleSk7XG4gIH1cbiAgIWlzUmVhZG9ubHkgJiYgdHJhY2socmF3VGFyZ2V0LCBcImdldFwiLCByYXdLZXkpO1xuICBjb25zdCB7aGFzOiBoYXMyfSA9IGdldFByb3RvKHJhd1RhcmdldCk7XG4gIGNvbnN0IHdyYXAgPSBpc1NoYWxsb3cgPyB0b1NoYWxsb3cgOiBpc1JlYWRvbmx5ID8gdG9SZWFkb25seSA6IHRvUmVhY3RpdmU7XG4gIGlmIChoYXMyLmNhbGwocmF3VGFyZ2V0LCBrZXkpKSB7XG4gICAgcmV0dXJuIHdyYXAodGFyZ2V0LmdldChrZXkpKTtcbiAgfSBlbHNlIGlmIChoYXMyLmNhbGwocmF3VGFyZ2V0LCByYXdLZXkpKSB7XG4gICAgcmV0dXJuIHdyYXAodGFyZ2V0LmdldChyYXdLZXkpKTtcbiAgfSBlbHNlIGlmICh0YXJnZXQgIT09IHJhd1RhcmdldCkge1xuICAgIHRhcmdldC5nZXQoa2V5KTtcbiAgfVxufVxuZnVuY3Rpb24gaGFzJDEoa2V5LCBpc1JlYWRvbmx5ID0gZmFsc2UpIHtcbiAgY29uc3QgdGFyZ2V0ID0gdGhpc1tcIl9fdl9yYXdcIl07XG4gIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7XG4gIGNvbnN0IHJhd0tleSA9IHRvUmF3KGtleSk7XG4gIGlmIChrZXkgIT09IHJhd0tleSkge1xuICAgICFpc1JlYWRvbmx5ICYmIHRyYWNrKHJhd1RhcmdldCwgXCJoYXNcIiwga2V5KTtcbiAgfVxuICAhaXNSZWFkb25seSAmJiB0cmFjayhyYXdUYXJnZXQsIFwiaGFzXCIsIHJhd0tleSk7XG4gIHJldHVybi
1BrZXkgPT09IHJhd0tleSA/IHRhcmdldC5oYXMoa2V5KSA6IHRhcmdldC5oYXMoa2V5KSB8fCB0YXJnZXQuaGFzKHJhd0tleSk7XG59XG5mdW5jdGlvbiBzaXplKHRhcmdldCwgaXNSZWFkb25seSA9IGZhbHNlKSB7XG4gIHRhcmdldCA9IHRhcmdldFtcIl9fdl9yYXdcIl07XG4gICFpc1JlYWRvbmx5ICYmIHRyYWNrKHRvUmF3KHRhcmdldCksIFwiaXRlcmF0ZVwiLCBJVEVSQVRFX0tFWSk7XG4gIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsIFwic2l6ZVwiLCB0YXJnZXQpO1xufVxuZnVuY3Rpb24gYWRkKHZhbHVlKSB7XG4gIHZhbHVlID0gdG9SYXcodmFsdWUpO1xuICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTtcbiAgY29uc3QgcHJvdG8gPSBnZXRQcm90byh0YXJnZXQpO1xuICBjb25zdCBoYWRLZXkgPSBwcm90by5oYXMuY2FsbCh0YXJnZXQsIHZhbHVlKTtcbiAgaWYgKCFoYWRLZXkpIHtcbiAgICB0YXJnZXQuYWRkKHZhbHVlKTtcbiAgICB0cmlnZ2VyKHRhcmdldCwgXCJhZGRcIiwgdmFsdWUsIHZhbHVlKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn1cbmZ1bmN0aW9uIHNldCQxKGtleSwgdmFsdWUpIHtcbiAgdmFsdWUgPSB0b1Jhdyh2YWx1ZSk7XG4gIGNvbnN0IHRhcmdldCA9IHRvUmF3KHRoaXMpO1xuICBjb25zdCB7aGFzOiBoYXMyLCBnZXQ6IGdldDN9ID0gZ2V0UHJvdG8odGFyZ2V0KTtcbiAgbGV0IGhhZEtleSA9IGhhczIuY2FsbCh0YXJnZXQsIGtleSk7XG4gIGlmICghaGFkS2V5KSB7XG4gICAga2V5ID0gdG9SYXcoa2V5KTtcbiAgICBoYWRLZXkgPSBoYXMyLmNhbGwodGFyZ2V0LCBrZXkpO1xuICB9IGVsc2UgaWYgKHRydWUpIHtcbiAgICBjaGVja0lkZW50aXR5S2V5cyh0YXJnZXQsIGhhczIsIGtleSk7XG4gIH1cbiAgY29uc3Qgb2xkVmFsdWUgPSBnZXQzLmNhbGwodGFyZ2V0LCBrZXkpO1xuICB0YXJnZXQuc2V0KGtleSwgdmFsdWUpO1xuICBpZiAoIWhhZEtleSkge1xuICAgIHRyaWdnZXIodGFyZ2V0LCBcImFkZFwiLCBrZXksIHZhbHVlKTtcbiAgfSBlbHNlIGlmIChoYXNDaGFuZ2VkKHZhbHVlLCBvbGRWYWx1ZSkpIHtcbiAgICB0cmlnZ2VyKHRhcmdldCwgXCJzZXRcIiwga2V5LCB2YWx1ZSwgb2xkVmFsdWUpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufVxuZnVuY3Rpb24gZGVsZXRlRW50cnkoa2V5KSB7XG4gIGNvbnN0IHRhcmdldCA9IHRvUmF3KHRoaXMpO1xuICBjb25zdCB7aGFzOiBoYXMyLCBnZXQ6IGdldDN9ID0gZ2V0UHJvdG8odGFyZ2V0KTtcbiAgbGV0IGhhZEtleSA9IGhhczIuY2FsbCh0YXJnZXQsIGtleSk7XG4gIGlmICghaGFkS2V5KSB7XG4gICAga2V5ID0gdG9SYXcoa2V5KTtcbiAgICBoYWRLZXkgPSBoYXMyLmNhbGwodGFyZ2V0LCBrZXkpO1xuICB9IGVsc2UgaWYgKHRydWUpIHtcbiAgICBjaGVja0lkZW50aXR5S2V5cyh0YXJnZXQsIGhhczIsIGtleSk7XG4gIH1cbiAgY29uc3Qgb2xkVmFsdWUgPSBnZXQzID8gZ2V0My5jYWxsKHRhcmdldCwga2V5KSA6IHZvaWQgMDtcbiAgY29uc3QgcmVzdWx0ID0gdGFyZ2V0LmRlbGV0ZShrZXkpO1xuICBpZiAoaGFkS2V5KSB7XG4gICAgdHJpZ2dlcih0YXJnZXQsIFwiZGVsZXRlXCIsIGtleSwgdm9pZCAwLCBvbGRWYWx1ZSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGNsZWFyKCkge1xuICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTtcbiAgY29uc3QgaGFkSXRlbXMgPSB0YXJnZXQuc2l6ZSAhPT0gMDtcbiAgY29uc3Qgb2xkVGFyZ2V0ID0gdHJ1ZSA/IGlzTWFwKHRhcmdldCkgPyBuZXcgTWFwKHRhcmdldCkgOiBuZXcgU2V0KHRhcmdldCkgOiB2b2lkIDA7XG4gIGNvbnN0IHJlc3VsdCA9IHRhcmdldC5jbGVhcigpO1xuICBpZiAoaGFkSXRlbXMpIHtcbiAgICB0cmlnZ2VyKHRhcmdldCwgXCJjbGVhclwiLCB2b2lkIDAsIHZvaWQgMCwgb2xkVGFyZ2V0KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gY3JlYXRlRm9yRWFjaChpc1JlYWRvbmx5LCBpc1NoYWxsb3cpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZvckVhY2goY2FsbGJhY2ssIHRoaXNBcmcpIHtcbiAgICBjb25zdCBvYnNlcnZlZCA9IHRoaXM7XG4gICAgY29uc3QgdGFyZ2V0ID0gb2JzZXJ2ZWRbXCJfX3ZfcmF3XCJdO1xuICAgIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7XG4gICAgY29uc3Qgd3JhcCA9IGlzU2hhbGxvdyA/IHRvU2hhbGxvdyA6IGlzUmVhZG9ubHkgPyB0b1JlYWRvbmx5IDogdG9SZWFjdGl2ZTtcbiAgICAhaXNSZWFkb25seSAmJiB0cmFjayhyYXdUYXJnZXQsIFwiaXRlcmF0ZVwiLCBJVEVSQVRFX0tFWSk7XG4gICAgcmV0dXJuIHRhcmdldC5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICByZXR1cm4gY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB3cmFwKHZhbHVlKSwgd3JhcChrZXkpLCBvYnNlcnZlZCk7XG4gICAgfSk7XG4gIH07XG59XG5mdW5jdGlvbiBjcmVhdGVJdGVyYWJsZU1ldGhvZChtZXRob2QsIGlzUmVhZG9ubHksIGlzU2hhbGxvdykge1xuICByZXR1cm4gZnVuY3Rpb24oLi4uYXJncykge1xuICAgIGNvbnN0IHRhcmdldCA9IHRoaXNbXCJfX3ZfcmF3XCJdO1xuICAgIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7XG4gICAgY29uc3QgdGFyZ2V0SXNNYXAgPSBpc01hcChyYXdUYXJnZXQpO1xuICAgIGNvbnN0IGlzUGFpciA9IG1ldGhvZCA9PT0gXCJlbnRyaWVzXCIgfHwgbWV0aG9kID09PSBTeW1ib2wuaXRlcmF0b3IgJiYgdGFyZ2V0SXNNYXA7XG4gICAgY29uc3QgaXNLZXlPbmx5ID0gbWV0aG9kID09PSBcImtleXNcIiAmJiB0YXJnZXRJc01hcDtcbiAgICBjb25zdCBpbm5lckl0ZXJhdG9yID0gdGFyZ2V0W21ldGhvZF0oLi4uYXJncyk7XG4gICAgY29uc3Qgd3JhcCA9IGlzU2hhbGxvdyA/IHRvU2hhbGxvdyA6IGlzUmVhZG9ubHkgPyB0b1JlYWRvbmx5IDogdG9SZWFjdGl2ZTtcbiAgICAhaXNSZWFkb25seSAmJiB0cmFjayhyYXdUYXJnZXQsIFwiaXRlcmF0ZVwiLCBpc0tleU9ubHkgPyBNQVBfS0VZX0lURVJBVEVfS0VZIDogSVRFUkFURV9LRVkpO1xuICAgIHJldHVybiB7XG4gICAgICBuZXh0KCkge1xuICAgICAgICBjb25zdCB7dmFsdWUsIGRvbmV9ID0gaW5uZXJJdGVyYXRvci5uZXh0KCk7XG4gICAgICAgI
1HJldHVybiBkb25lID8ge3ZhbHVlLCBkb25lfSA6IHtcbiAgICAgICAgICB2YWx1ZTogaXNQYWlyID8gW3dyYXAodmFsdWVbMF0pLCB3cmFwKHZhbHVlWzFdKV0gOiB3cmFwKHZhbHVlKSxcbiAgICAgICAgICBkb25lXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgW1N5bWJvbC5pdGVyYXRvcl0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH07XG4gIH07XG59XG5mdW5jdGlvbiBjcmVhdGVSZWFkb25seU1ldGhvZCh0eXBlKSB7XG4gIHJldHVybiBmdW5jdGlvbiguLi5hcmdzKSB7XG4gICAgaWYgKHRydWUpIHtcbiAgICAgIGNvbnN0IGtleSA9IGFyZ3NbMF0gPyBgb24ga2V5IFwiJHthcmdzWzBdfVwiIGAgOiBgYDtcbiAgICAgIGNvbnNvbGUud2FybihgJHtjYXBpdGFsaXplKHR5cGUpfSBvcGVyYXRpb24gJHtrZXl9ZmFpbGVkOiB0YXJnZXQgaXMgcmVhZG9ubHkuYCwgdG9SYXcodGhpcykpO1xuICAgIH1cbiAgICByZXR1cm4gdHlwZSA9PT0gXCJkZWxldGVcIiA/IGZhbHNlIDogdGhpcztcbiAgfTtcbn1cbnZhciBtdXRhYmxlSW5zdHJ1bWVudGF0aW9ucyA9IHtcbiAgZ2V0KGtleSkge1xuICAgIHJldHVybiBnZXQkMSh0aGlzLCBrZXkpO1xuICB9LFxuICBnZXQgc2l6ZSgpIHtcbiAgICByZXR1cm4gc2l6ZSh0aGlzKTtcbiAgfSxcbiAgaGFzOiBoYXMkMSxcbiAgYWRkLFxuICBzZXQ6IHNldCQxLFxuICBkZWxldGU6IGRlbGV0ZUVudHJ5LFxuICBjbGVhcixcbiAgZm9yRWFjaDogY3JlYXRlRm9yRWFjaChmYWxzZSwgZmFsc2UpXG59O1xudmFyIHNoYWxsb3dJbnN0cnVtZW50YXRpb25zID0ge1xuICBnZXQoa2V5KSB7XG4gICAgcmV0dXJuIGdldCQxKHRoaXMsIGtleSwgZmFsc2UsIHRydWUpO1xuICB9LFxuICBnZXQgc2l6ZSgpIHtcbiAgICByZXR1cm4gc2l6ZSh0aGlzKTtcbiAgfSxcbiAgaGFzOiBoYXMkMSxcbiAgYWRkLFxuICBzZXQ6IHNldCQxLFxuICBkZWxldGU6IGRlbGV0ZUVudHJ5LFxuICBjbGVhcixcbiAgZm9yRWFjaDogY3JlYXRlRm9yRWFjaChmYWxzZSwgdHJ1ZSlcbn07XG52YXIgcmVhZG9ubHlJbnN0cnVtZW50YXRpb25zID0ge1xuICBnZXQoa2V5KSB7XG4gICAgcmV0dXJuIGdldCQxKHRoaXMsIGtleSwgdHJ1ZSk7XG4gIH0sXG4gIGdldCBzaXplKCkge1xuICAgIHJldHVybiBzaXplKHRoaXMsIHRydWUpO1xuICB9LFxuICBoYXMoa2V5KSB7XG4gICAgcmV0dXJuIGhhcyQxLmNhbGwodGhpcywga2V5LCB0cnVlKTtcbiAgfSxcbiAgYWRkOiBjcmVhdGVSZWFkb25seU1ldGhvZChcImFkZFwiKSxcbiAgc2V0OiBjcmVhdGVSZWFkb25seU1ldGhvZChcInNldFwiKSxcbiAgZGVsZXRlOiBjcmVhdGVSZWFkb25seU1ldGhvZChcImRlbGV0ZVwiKSxcbiAgY2xlYXI6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKFwiY2xlYXJcIiksXG4gIGZvckVhY2g6IGNyZWF0ZUZvckVhY2godHJ1ZSwgZmFsc2UpXG59O1xudmFyIHNoYWxsb3dSZWFkb25seUluc3RydW1lbnRhdGlvbnMgPSB7XG4gIGdldChrZXkpIHtcbiAgICByZXR1cm4gZ2V0JDEodGhpcywga2V5LCB0cnVlLCB0cnVlKTtcbiAgfSxcbiAgZ2V0IHNpemUoKSB7XG4gICAgcmV0dXJuIHNpemUodGhpcywgdHJ1ZSk7XG4gIH0sXG4gIGhhcyhrZXkpIHtcbiAgICByZXR1cm4gaGFzJDEuY2FsbCh0aGlzLCBrZXksIHRydWUpO1xuICB9LFxuICBhZGQ6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKFwiYWRkXCIpLFxuICBzZXQ6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKFwic2V0XCIpLFxuICBkZWxldGU6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKFwiZGVsZXRlXCIpLFxuICBjbGVhcjogY3JlYXRlUmVhZG9ubHlNZXRob2QoXCJjbGVhclwiKSxcbiAgZm9yRWFjaDogY3JlYXRlRm9yRWFjaCh0cnVlLCB0cnVlKVxufTtcbnZhciBpdGVyYXRvck1ldGhvZHMgPSBbXCJrZXlzXCIsIFwidmFsdWVzXCIsIFwiZW50cmllc1wiLCBTeW1ib2wuaXRlcmF0b3JdO1xuaXRlcmF0b3JNZXRob2RzLmZvckVhY2goKG1ldGhvZCkgPT4ge1xuICBtdXRhYmxlSW5zdHJ1bWVudGF0aW9uc1ttZXRob2RdID0gY3JlYXRlSXRlcmFibGVNZXRob2QobWV0aG9kLCBmYWxzZSwgZmFsc2UpO1xuICByZWFkb25seUluc3RydW1lbnRhdGlvbnNbbWV0aG9kXSA9IGNyZWF0ZUl0ZXJhYmxlTWV0aG9kKG1ldGhvZCwgdHJ1ZSwgZmFsc2UpO1xuICBzaGFsbG93SW5zdHJ1bWVudGF0aW9uc1ttZXRob2RdID0gY3JlYXRlSXRlcmFibGVNZXRob2QobWV0aG9kLCBmYWxzZSwgdHJ1ZSk7XG4gIHNoYWxsb3dSZWFkb25seUluc3RydW1lbnRhdGlvbnNbbWV0aG9kXSA9IGNyZWF0ZUl0ZXJhYmxlTWV0aG9kKG1ldGhvZCwgdHJ1ZSwgdHJ1ZSk7XG59KTtcbmZ1bmN0aW9uIGNyZWF0ZUluc3RydW1lbnRhdGlvbkdldHRlcihpc1JlYWRvbmx5LCBzaGFsbG93KSB7XG4gIGNvbnN0IGluc3RydW1lbnRhdGlvbnMgPSBzaGFsbG93ID8gaXNSZWFkb25seSA/IHNoYWxsb3dSZWFkb25seUluc3RydW1lbnRhdGlvbnMgOiBzaGFsbG93SW5zdHJ1bWVudGF0aW9ucyA6IGlzUmVhZG9ubHkgPyByZWFkb25seUluc3RydW1lbnRhdGlvbnMgOiBtdXRhYmxlSW5zdHJ1bWVudGF0aW9ucztcbiAgcmV0dXJuICh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpID0+IHtcbiAgICBpZiAoa2V5ID09PSBcIl9fdl9pc1JlYWN0aXZlXCIpIHtcbiAgICAgIHJldHVybiAhaXNSZWFkb25seTtcbiAgICB9IGVsc2UgaWYgKGtleSA9PT0gXCJfX3ZfaXNSZWFkb25seVwiKSB7XG4gICAgICByZXR1cm4gaXNSZWFkb25seTtcbiAgICB9IGVsc2UgaWYgKGtleSA9PT0gXCJfX3ZfcmF3XCIpIHtcbiAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuICAgIHJldHVybiBSZWZsZWN0LmdldChoYXNPd24oaW5zdHJ1bWVudGF0aW9ucywga2V5KSAmJiBrZXkgaW4gdGFyZ2V0ID8gaW5zdHJ1bWVudGF0aW9ucyA6IHRhcmdldCwga2V5LCByZWNlaXZlcik7XG4gIH07XG59XG52YXIgbXV0YWJsZUNvbGxlY3Rpb25IYW5kbGVycyA9IHtcbiAgZ2V0OiBjcmVhdGVJbnN0cnVtZW50YXRpb25HZXR0ZXIoZmFsc2UsIGZhbHNlKVxufTtcbnZhciBzaGFsbG93Q29sbGVjdGlvbkhhbmRsZXJzID0ge1xuICBnZXQ6IGNyZWF0ZUluc3RydW1lbnRhdGlvbkdldHRlcihmYWxzZSwgdHJ1ZSlcbn07XG52YXIgcmVhZG9ubHlDb2xsZWN0aW9uSGFuZGxlcnMgPSB7XG4gIGdldDogY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKHRydWUsIGZhbHNlKVxufTtcbnZhciBzaGFsbG93UmVhZG9ubHlDb2xsZWN0aW9uSGFuZGxlcnMgPSB7XG4gIGdldDogY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKHRydWUsIHRydWUpXG59O1xuZnVuY3Rpb24gY2hlY2tJZGVudGl0eUtleXModGFyZ2V0LCBoYXMyLCBrZXkpIHtcbiAgY29uc3QgcmF3S2V5ID0gdG9SYXcoa2V5KTtcbiAgaWYgKHJhd0tleSAhPT0ga2V5ICYmIGhhczIuY2FsbCh0YXJnZXQsIHJhd0tleSkpIHtcbiAgICBjb25zdCB0eXBlID0gdG9SYXdUeXBlKHRhcmdldCk7XG4gICAgY29uc29sZS53YXJuKGBSZWFjdGl2ZSAke3R5cGV9IGNvbnRhaW5zIGJvdGggdGhlIHJhdyBhbmQgcmVhY3RpdmUgdmVyc2lvbnMgb2YgdGhlIHNhbWUgb2JqZWN0JHt0eXBlID09PSBgTWFwYCA/IGAgYXMga2V5c2AgOiBgYH0sIHdoaWNoIGNhbiBsZWFkIHRvIGluY29uc2lzdGVuY2llcy4gQXZvaWQgZGlmZmVyZW50aWF0aW5nIGJldHdlZW4gdGhlIHJhdyBhbmQgcmVhY3RpdmUgdmVyc2lvbnMgb2YgYW4gb2JqZWN0IGFuZCBvbmx5IHVzZSB0aGUgcmVhY3RpdmUgdmVyc2lvbiBpZiBwb3NzaWJsZS5gKTtcbiAgfVxufVxudmFyIHJlYWN0aXZlTWFwID0gbmV3IFdlYWtNYXAoKTtcbnZhciBzaGFsbG93UmVhY3RpdmVNYXAgPSBuZXcgV2Vha01hcCgpO1xudmFyIHJlYWRvbmx5TWFwID0gbmV3IFdlYWtNYXAoKTtcbnZhciBzaGFsbG93UmVhZG9ubHlNYXAgPSBuZXcgV2Vha01hcCgpO1xuZnVuY3Rpb24gdGFyZ2V0VHlwZU1hcChyYXdUeXBlKSB7XG4gIHN3aXRjaCAocmF3VHlwZSkge1xuICAgIGNhc2UgXCJPYmplY3RcIjpcbiAgICBjYXNlIFwiQXJyYXlcIjpcbiAgICAgIHJldHVybiAxO1xuICAgIGNhc2UgXCJNYXBcIjpcbiAgICBjYXNlIFwiU2V0XCI6XG4gICAgY2FzZSBcIldlYWtNYXBcIjpcbiAgICBjYXNlIFwiV2Vha1NldFwiOlxuICAgICAgcmV0dXJuIDI7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAwO1xuICB9XG59XG5mdW5jdGlvbiBnZXRUYXJnZXRUeXBlKHZhbHVlKSB7XG4gIHJldHVybi
1B2YWx1ZVtcIl9fdl9za2lwXCJdIHx8ICFPYmplY3QuaXNFeHRlbnNpYmxlKHZhbHVlKSA/IDAgOiB0YXJnZXRUeXBlTWFwKHRvUmF3VHlwZSh2YWx1ZSkpO1xufVxuZnVuY3Rpb24gcmVhY3RpdmUyKHRhcmdldCkge1xuICBpZiAodGFyZ2V0ICYmIHRhcmdldFtcIl9fdl9pc1JlYWRvbmx5XCJdKSB7XG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfVxuICByZXR1cm4gY3JlYXRlUmVhY3RpdmVPYmplY3QodGFyZ2V0LCBmYWxzZSwgbXV0YWJsZUhhbmRsZXJzLCBtdXRhYmxlQ29sbGVjdGlvbkhhbmRsZXJzLCByZWFjdGl2ZU1hcCk7XG59XG5mdW5jdGlvbiByZWFkb25seSh0YXJnZXQpIHtcbiAgcmV0dXJuIGNyZWF0ZVJlYWN0aXZlT2JqZWN0KHRhcmdldCwgdHJ1ZSwgcmVhZG9ubHlIYW5kbGVycywgcmVhZG9ubHlDb2xsZWN0aW9uSGFuZGxlcnMsIHJlYWRvbmx5TWFwKTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZVJlYWN0aXZlT2JqZWN0KHRhcmdldCwgaXNSZWFkb25seSwgYmFzZUhhbmRsZXJzLCBjb2xsZWN0aW9uSGFuZGxlcnMsIHByb3h5TWFwKSB7XG4gIGlmICghaXNPYmplY3QodGFyZ2V0KSkge1xuICAgIGlmICh0cnVlKSB7XG4gICAgICBjb25zb2xlLndhcm4oYHZhbHVlIGNhbm5vdCBiZSBtYWRlIHJlYWN0aXZlOiAke1N0cmluZyh0YXJnZXQpfWApO1xuICAgIH1cbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG4gIGlmICh0YXJnZXRbXCJfX3ZfcmF3XCJdICYmICEoaXNSZWFkb25seSAmJiB0YXJnZXRbXCJfX3ZfaXNSZWFjdGl2ZVwiXSkpIHtcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG4gIGNvbnN0IGV4aXN0aW5nUHJveHkgPSBwcm94eU1hcC5nZXQodGFyZ2V0KTtcbiAgaWYgKGV4aXN0aW5nUHJveHkpIHtcbiAgICByZXR1cm4gZXhpc3RpbmdQcm94eTtcbiAgfVxuICBjb25zdCB0YXJnZXRUeXBlID0gZ2V0VGFyZ2V0VHlwZSh0YXJnZXQpO1xuICBpZiAodGFyZ2V0VHlwZSA9PT0gMCkge1xuICAgIHJldHVybiB0YXJnZXQ7XG4gIH1cbiAgY29uc3QgcHJveHkgPSBuZXcgUHJveHkodGFyZ2V0LCB0YXJnZXRUeXBlID09PSAyID8gY29sbGVjdGlvbkhhbmRsZXJzIDogYmFzZUhhbmRsZXJzKTtcbiAgcHJveHlNYXAuc2V0KHRhcmdldCwgcHJveHkpO1xuICByZXR1cm4gcHJveHk7XG59XG5mdW5jdGlvbiB0b1JhdyhvYnNlcnZlZCkge1xuICByZXR1cm4gb2JzZXJ2ZWQgJiYgdG9SYXcob2JzZXJ2ZWRbXCJfX3ZfcmF3XCJdKSB8fCBvYnNlcnZlZDtcbn1cbmZ1bmN0aW9uIGlzUmVmKHIpIHtcbiAgcmV0dXJuIEJvb2xlYW4ociAmJiByLl9fdl9pc1JlZiA9PT0gdHJ1ZSk7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tYWdpY3MvJG5leHRUaWNrLmpzXG5tYWdpYyhcIm5leHRUaWNrXCIsICgpID0+IG5leHRUaWNrKTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL21hZ2ljcy8kZGlzcGF0Y2guanNcbm1hZ2ljKFwiZGlzcGF0Y2hcIiwgKGVsKSA9PiBkaXNwYXRjaC5iaW5kKGRpc3BhdGNoLCBlbCkpO1xuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvbWFnaWNzLyR3YXRjaC5qc1xubWFnaWMoXCJ3YXRjaFwiLCAoZWwsIHtldmFsdWF0ZUxhdGVyOiBldmFsdWF0ZUxhdGVyMiwgZWZmZWN0OiBlZmZlY3QzfSkgPT4gKGtleSwgY2FsbGJhY2spID0+IHtcbiAgbGV0IGV2YWx1YXRlMiA9IGV2YWx1YXRlTGF0ZXIyKGtleSk7XG4gIGxldCBmaXJzdFRpbWUgPSB0cnVlO1xuICBsZXQgb2xkVmFsdWU7XG4gIGxldCBlZmZlY3RSZWZlcmVuY2UgPSBlZmZlY3QzKCgpID0+IGV2YWx1YXRlMigodmFsdWUpID0+IHtcbiAgICBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgaWYgKCFmaXJzdFRpbWUpIHtcbiAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgICAgY2FsbGJhY2sodmFsdWUsIG9sZFZhbHVlKTtcbiAgICAgICAgb2xkVmFsdWUgPSB2YWx1ZTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBvbGRWYWx1ZSA9IHZhbHVlO1xuICAgIH1cbiAgICBmaXJzdFRpbWUgPSBmYWxzZTtcbiAgfSkpO1xuICBlbC5feF9lZmZlY3RzLmRlbGV0ZShlZmZlY3RSZWZlcmVuY2UpO1xufSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tYWdpY3MvJHN0b3JlLmpzXG5tYWdpYyhcInN0b3JlXCIsIGdldFN0b3Jlcyk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tYWdpY3MvJGRhdGEuanNcbm1hZ2ljKFwiZGF0YVwiLCAoZWwpID0+IHNjb3BlKGVsKSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tYWdpY3MvJHJvb3QuanNcbm1hZ2ljKFwicm9vdFwiLCAoZWwpID0+IGNsb3Nlc3RSb290KGVsKSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tYWdpY3MvJHJlZnMuanNcbm1hZ2ljKFwicmVmc1wiLCAoZWwpID0+IHtcbiAgaWYgKGVsLl94X3JlZnNfcHJveHkpXG4gICAgcmV0dXJuIGVsLl94X3JlZnNfcHJveHk7XG4gIGVsLl94X3JlZnNfcHJveHkgPSBtZXJnZVByb3hpZXMoZ2V0QXJyYXlPZlJlZk9iamVjdChlbCkpO1xuICByZXR1cm4gZWwuX3hfcmVmc19wcm94eTtcbn0pO1xuZnVuY3Rpb24gZ2V0QXJyYXlPZlJlZk9iamVjdChlbCkge1xuICBsZXQgcmVmT2JqZWN0cyA9IFtdO1xuICBsZXQgY3VycmVudEVsID0gZWw7XG4gIHdoaWxlIChjdXJyZW50RWwpIHtcbiAgICBpZiAoY3VycmVudEVsLl94X3JlZnMpXG4gICAgICByZWZPYmplY3RzLnB1c2goY3VycmVudEVsLl94X3JlZnMpO1xuICAgIGN1cnJlbnRFbCA9IGN1cnJlbnRFbC5wYXJlbnROb2RlO1xuICB9XG4gIHJldHVybiByZWZPYmplY3RzO1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvaWRzLmpzXG52YXIgZ2xvYmFsSWRNZW1vID0ge307XG5mdW5jdGlvbiBmaW5kQW5kSW5jcmVtZW50SWQobmFtZSkge1xuICBpZiAoIWdsb2JhbElkTWVtb1tuYW1lXSlcbiAgICBnbG9iYWxJZE1lbW9bbmFtZV0gPSAwO1xuICByZXR1cm4gKytnbG9iYWxJZE1lbW9bbmFtZV07XG59XG5mdW5jdGlvbiBjbG9zZXN0SWRSb290KGVsLCBuYW1lKSB7XG4gIHJldHVybiBmaW5kQ2xvc2VzdChlbCwgKGVsZW1lbnQpID0+IHtcbiAgICBpZiAoZWxlbWVudC5feF9pZHMgJiYgZWxlbWVudC5feF9pZHNbbmFtZV0pXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgfSk7XG59XG5mdW5jdGlvbiBzZXRJZFJvb3QoZWwsIG5hbW
1UpIHtcbiAgaWYgKCFlbC5feF9pZHMpXG4gICAgZWwuX3hfaWRzID0ge307XG4gIGlmICghZWwuX3hfaWRzW25hbWVdKVxuICAgIGVsLl94X2lkc1tuYW1lXSA9IGZpbmRBbmRJbmNyZW1lbnRJZChuYW1lKTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL21hZ2ljcy8kaWQuanNcbm1hZ2ljKFwiaWRcIiwgKGVsKSA9PiAobmFtZSwga2V5ID0gbnVsbCkgPT4ge1xuICBsZXQgcm9vdCA9IGNsb3Nlc3RJZFJvb3QoZWwsIG5hbWUpO1xuICBsZXQgaWQgPSByb290ID8gcm9vdC5feF9pZHNbbmFtZV0gOiBmaW5kQW5kSW5jcmVtZW50SWQobmFtZSk7XG4gIHJldHVybiBrZXkgPyBgJHtuYW1lfS0ke2lkfS0ke2tleX1gIDogYCR7bmFtZX0tJHtpZH1gO1xufSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tYWdpY3MvJGVsLmpzXG5tYWdpYyhcImVsXCIsIChlbCkgPT4gZWwpO1xuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvbWFnaWNzL2luZGV4LmpzXG53YXJuTWlzc2luZ1BsdWdpbk1hZ2ljKFwiRm9jdXNcIiwgXCJmb2N1c1wiLCBcImZvY3VzXCIpO1xud2Fybk1pc3NpbmdQbHVnaW5NYWdpYyhcIlBlcnNpc3RcIiwgXCJwZXJzaXN0XCIsIFwicGVyc2lzdFwiKTtcbmZ1bmN0aW9uIHdhcm5NaXNzaW5nUGx1Z2luTWFnaWMobmFtZSwgbWFnaWNOYW1lLCBzbHVnKSB7XG4gIG1hZ2ljKG1hZ2ljTmFtZSwgKGVsKSA9PiB3YXJuKGBZb3UgY2FuJ3QgdXNlIFskJHtkaXJlY3RpdmVOYW1lfV0gd2l0aG91dCBmaXJzdCBpbnN0YWxsaW5nIHRoZSBcIiR7bmFtZX1cIiBwbHVnaW4gaGVyZTogaHR0cHM6Ly9hbHBpbmVqcy5kZXYvcGx1Z2lucy8ke3NsdWd9YCwgZWwpKTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2VudGFuZ2xlLmpzXG5mdW5jdGlvbiBlbnRhbmdsZSh7Z2V0OiBvdXRlckdldCwgc2V0OiBvdXRlclNldH0sIHtnZXQ6IGlubmVyR2V0LCBzZXQ6IGlubmVyU2V0fSkge1xuICBsZXQgZmlyc3RSdW4gPSB0cnVlO1xuICBsZXQgb3V0ZXJIYXNoLCBpbm5lckhhc2gsIG91dGVySGFzaExhdGVzdCwgaW5uZXJIYXNoTGF0ZXN0O1xuICBsZXQgcmVmZXJlbmNlID0gZWZmZWN0KCgpID0+IHtcbiAgICBsZXQgb3V0ZXIsIGlubmVyO1xuICAgIGlmIChmaXJzdFJ1bikge1xuICAgICAgb3V0ZXIgPSBvdXRlckdldCgpO1xuICAgICAgaW5uZXJTZXQob3V0ZXIpO1xuICAgICAgaW5uZXIgPSBpbm5lckdldCgpO1xuICAgICAgZmlyc3RSdW4gPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0ZXIgPSBvdXRlckdldCgpO1xuICAgICAgaW5uZXIgPSBpbm5lckdldCgpO1xuICAgICAgb3V0ZXJIYXNoTGF0ZXN0ID0gSlNPTi5zdHJpbmdpZnkob3V0ZXIpO1xuICAgICAgaW5uZXJIYXNoTGF0ZXN0ID0gSlNPTi5zdHJpbmdpZnkoaW5uZXIpO1xuICAgICAgaWYgKG91dGVySGFzaExhdGVzdCAhPT0gb3V0ZXJIYXNoKSB7XG4gICAgICAgIGlubmVyID0gaW5uZXJHZXQoKTtcbiAgICAgICAgaW5uZXJTZXQob3V0ZXIpO1xuICAgICAgICBpbm5lciA9IG91dGVyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0ZXJTZXQoaW5uZXIpO1xuICAgICAgICBvdXRlciA9IGlubmVyO1xuICAgICAgfVxuICAgIH1cbiAgICBvdXRlckhhc2ggPSBKU09OLnN0cmluZ2lmeShvdXRlcik7XG4gICAgaW5uZXJIYXNoID0gSlNPTi5zdHJpbmdpZnkoaW5uZXIpO1xuICB9KTtcbiAgcmV0dXJuICgpID0+IHtcbiAgICByZWxlYXNlKHJlZmVyZW5jZSk7XG4gIH07XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtbW9kZWxhYmxlLmpzXG5kaXJlY3RpdmUoXCJtb2RlbGFibGVcIiwgKGVsLCB7ZXhwcmVzc2lvbn0sIHtlZmZlY3Q6IGVmZmVjdDMsIGV2YWx1YXRlTGF0ZXI6IGV2YWx1YXRlTGF0ZXIyLCBjbGVhbnVwOiBjbGVhbnVwMn0pID0+IHtcbiAgbGV0IGZ1bmMgPSBldmFsdWF0ZUxhdGVyMihleHByZXNzaW9uKTtcbiAgbGV0IGlubmVyR2V0ID0gKCkgPT4ge1xuICAgIGxldCByZXN1bHQ7XG4gICAgZnVuYygoaSkgPT4gcmVzdWx0ID0gaSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcbiAgbGV0IGV2YWx1YXRlSW5uZXJTZXQgPSBldmFsdWF0ZUxhdGVyMihgJHtleHByZXNzaW9ufSA9IF9fcGxhY2Vob2xkZXJgKTtcbiAgbGV0IGlubmVyU2V0ID0gKHZhbCkgPT4gZXZhbHVhdGVJbm5lclNldCgoKSA9PiB7XG4gIH0sIHtzY29wZToge19fcGxhY2Vob2xkZXI6IHZhbH19KTtcbiAgbGV0IGluaXRpYWxWYWx1ZSA9IGlubmVyR2V0KCk7XG4gIGlubmVyU2V0KGluaXRpYWxWYWx1ZSk7XG4gIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICBpZiAoIWVsLl94X21vZGVsKVxuICAgICAgcmV0dXJuO1xuICAgIGVsLl94X3JlbW92ZU1vZGVsTGlzdGVuZXJzW1wiZGVmYXVsdFwiXSgpO1xuICAgIGxldCBvdXRlckdldCA9IGVsLl94X21vZGVsLmdldDtcbiAgICBsZXQgb3V0ZXJTZXQgPSBlbC5feF9tb2RlbC5zZXQ7XG4gICAgbGV0IHJlbGVhc2VFbnRhbmdsZW1lbnQgPSBlbnRhbmdsZSh7XG4gICAgICBnZXQoKSB7XG4gICAgICAgIHJldHVybiBvdXRlckdldCgpO1xuICAgICAgfSxcbiAgICAgIHNldCh2YWx1ZSkge1xuICAgICAgICBvdXRlclNldCh2YWx1ZSk7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gaW5uZXJHZXQoKTtcbiAgICAgIH0sXG4gICAgICBzZXQodmFsdWUpIHtcbiAgICAgICAgaW5uZXJTZXQodmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGNsZWFudXAyKHJlbGVhc2VFbnRhbmdsZW1lbnQpO1xuICB9KTtcbn0pO1xuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvZGlyZWN0aXZlcy94LXRlbGVwb3J0LmpzXG52YXIgdGVsZXBvcnRDb250YWluZXJEdXJpbmdDbG9uZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5kaXJlY3RpdmUoXCJ0ZWxlcG9ydFwiLCAoZWwsIHttb2RpZmllcnMsIGV4cHJlc3Npb259LCB7Y2xlYW51cDogY2xlYW51cDJ9KSA9PiB7XG4gIGlmIChlbC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgIT09IFwidGVtcGxhdGVcIilcbiAgICB3YXJuKFwieC10ZWxlcG9ydCBjYW4gb25seSBiZSB1c2VkIG9uIGEgPHRlbXBsYXRlPiB0YWdcIiwgZWwpO1xuICBsZXQgdGFyZ2V0ID0gc2tpcER1cmluZ0Nsb25lKCgpID0+IHtcbiAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihleHByZXNzaW9uKTtcbiAgfSwgKCkgPT4ge1xuICAgIHJldHVybi
1B0ZWxlcG9ydENvbnRhaW5lckR1cmluZ0Nsb25lO1xuICB9KSgpO1xuICBpZiAoIXRhcmdldClcbiAgICB3YXJuKGBDYW5ub3QgZmluZCB4LXRlbGVwb3J0IGVsZW1lbnQgZm9yIHNlbGVjdG9yOiBcIiR7ZXhwcmVzc2lvbn1cImApO1xuICBsZXQgY2xvbmUyID0gZWwuY29udGVudC5jbG9uZU5vZGUodHJ1ZSkuZmlyc3RFbGVtZW50Q2hpbGQ7XG4gIGVsLl94X3RlbGVwb3J0ID0gY2xvbmUyO1xuICBjbG9uZTIuX3hfdGVsZXBvcnRCYWNrID0gZWw7XG4gIGlmIChlbC5feF9mb3J3YXJkRXZlbnRzKSB7XG4gICAgZWwuX3hfZm9yd2FyZEV2ZW50cy5mb3JFYWNoKChldmVudE5hbWUpID0+IHtcbiAgICAgIGNsb25lMi5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgKGUpID0+IHtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgZS5jb25zdHJ1Y3RvcihlLnR5cGUsIGUpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIGFkZFNjb3BlVG9Ob2RlKGNsb25lMiwge30sIGVsKTtcbiAgbXV0YXRlRG9tKCgpID0+IHtcbiAgICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwicHJlcGVuZFwiKSkge1xuICAgICAgdGFyZ2V0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGNsb25lMiwgdGFyZ2V0KTtcbiAgICB9IGVsc2UgaWYgKG1vZGlmaWVycy5pbmNsdWRlcyhcImFwcGVuZFwiKSkge1xuICAgICAgdGFyZ2V0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGNsb25lMiwgdGFyZ2V0Lm5leHRTaWJsaW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGFyZ2V0LmFwcGVuZENoaWxkKGNsb25lMik7XG4gICAgfVxuICAgIGluaXRUcmVlKGNsb25lMik7XG4gICAgY2xvbmUyLl94X2lnbm9yZSA9IHRydWU7XG4gIH0pO1xuICBjbGVhbnVwMigoKSA9PiBjbG9uZTIucmVtb3ZlKCkpO1xufSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtaWdub3JlLmpzXG52YXIgaGFuZGxlciA9ICgpID0+IHtcbn07XG5oYW5kbGVyLmlubGluZSA9IChlbCwge21vZGlmaWVyc30sIHtjbGVhbnVwOiBjbGVhbnVwMn0pID0+IHtcbiAgbW9kaWZpZXJzLmluY2x1ZGVzKFwic2VsZlwiKSA/IGVsLl94X2lnbm9yZVNlbGYgPSB0cnVlIDogZWwuX3hfaWdub3JlID0gdHJ1ZTtcbiAgY2xlYW51cDIoKCkgPT4ge1xuICAgIG1vZGlmaWVycy5pbmNsdWRlcyhcInNlbGZcIikgPyBkZWxldGUgZWwuX3hfaWdub3JlU2VsZiA6IGRlbGV0ZSBlbC5feF9pZ25vcmU7XG4gIH0pO1xufTtcbmRpcmVjdGl2ZShcImlnbm9yZVwiLCBoYW5kbGVyKTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC1lZmZlY3QuanNcbmRpcmVjdGl2ZShcImVmZmVjdFwiLCAoZWwsIHtleHByZXNzaW9ufSwge2VmZmVjdDogZWZmZWN0M30pID0+IGVmZmVjdDMoZXZhbHVhdGVMYXRlcihlbCwgZXhwcmVzc2lvbikpKTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL3V0aWxzL29uLmpzXG5mdW5jdGlvbiBvbihlbCwgZXZlbnQsIG1vZGlmaWVycywgY2FsbGJhY2spIHtcbiAgbGV0IGxpc3RlbmVyVGFyZ2V0ID0gZWw7XG4gIGxldCBoYW5kbGVyNCA9IChlKSA9PiBjYWxsYmFjayhlKTtcbiAgbGV0IG9wdGlvbnMgPSB7fTtcbiAgbGV0IHdyYXBIYW5kbGVyID0gKGNhbGxiYWNrMiwgd3JhcHBlcikgPT4gKGUpID0+IHdyYXBwZXIoY2FsbGJhY2syLCBlKTtcbiAgaWYgKG1vZGlmaWVycy5pbmNsdWRlcyhcImRvdFwiKSlcbiAgICBldmVudCA9IGRvdFN5bnRheChldmVudCk7XG4gIGlmIChtb2RpZmllcnMuaW5jbHVkZXMoXCJjYW1lbFwiKSlcbiAgICBldmVudCA9IGNhbWVsQ2FzZTIoZXZlbnQpO1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwicGFzc2l2ZVwiKSlcbiAgICBvcHRpb25zLnBhc3NpdmUgPSB0cnVlO1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwiY2FwdHVyZVwiKSlcbiAgICBvcHRpb25zLmNhcHR1cmUgPSB0cnVlO1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwid2luZG93XCIpKVxuICAgIGxpc3RlbmVyVGFyZ2V0ID0gd2luZG93O1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwiZG9jdW1lbnRcIikpXG4gICAgbGlzdGVuZXJUYXJnZXQgPSBkb2N1bWVudDtcbiAgaWYgKG1vZGlmaWVycy5pbmNsdWRlcyhcImRlYm91bmNlXCIpKSB7XG4gICAgbGV0IG5leHRNb2RpZmllciA9IG1vZGlmaWVyc1ttb2RpZmllcnMuaW5kZXhPZihcImRlYm91bmNlXCIpICsgMV0gfHwgXCJpbnZhbGlkLXdhaXRcIjtcbiAgICBsZXQgd2FpdCA9IGlzTnVtZXJpYyhuZXh0TW9kaWZpZXIuc3BsaXQoXCJtc1wiKVswXSkgPyBOdW1iZXIobmV4dE1vZGlmaWVyLnNwbGl0KFwibXNcIilbMF0pIDogMjUwO1xuICAgIGhhbmRsZXI0ID0gZGVib3VuY2UoaGFuZGxlcjQsIHdhaXQpO1xuICB9XG4gIGlmIChtb2RpZmllcnMuaW5jbHVkZXMoXCJ0aHJvdHRsZVwiKSkge1xuICAgIGxldCBuZXh0TW9kaWZpZXIgPSBtb2RpZmllcnNbbW9kaWZpZXJzLmluZGV4T2YoXCJ0aHJvdHRsZVwiKSArIDFdIHx8IFwiaW52YWxpZC13YWl0XCI7XG4gICAgbGV0IHdhaXQgPSBpc051bWVyaWMobmV4dE1vZGlmaWVyLnNwbGl0KFwibXNcIilbMF0pID8gTnVtYmVyKG5leHRNb2RpZmllci5zcGxpdChcIm1zXCIpWzBdKSA6IDI1MDtcbiAgICBoYW5kbGVyNCA9IHRocm90dGxlKGhhbmRsZXI0LCB3YWl0KTtcbiAgfVxuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwicHJldmVudFwiKSlcbiAgICBoYW5kbGVyNCA9IHdyYXBIYW5kbGVyKGhhbmRsZXI0LCAobmV4dCwgZSkgPT4ge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgbmV4dChlKTtcbiAgICB9KTtcbiAgaWYgKG1vZGlmaWVycy5pbmNsdWRlcyhcInN0b3BcIikpXG4gICAgaGFuZGxlcjQgPSB3cmFwSGFuZGxlcihoYW5kbGVyNCwgKG5leHQsIGUpID0+IHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBuZXh0KGUpO1xuICAgIH0pO1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwic2VsZlwiKSlcbiAgICBoYW5kbGVyNCA9IHdyYXBIYW5kbGVyKGhhbmRsZXI0LCAobmV4dCwgZSkgPT4ge1xuICAgICAgZS50YXJnZXQgPT09IGVsICYmIG5leHQoZSk7XG4gICAgfSk7XG4gIGlmIChtb2RpZmllcnMuaW5jbHVkZXMoXCJhd2F5XCIpIHx8IG1vZGlmaWVycy5pbmNsdWRlcyhcIm91dHNpZGVcIikpIHtcbiAgICBsaXN0ZW5lclRhcmdldCA9IGRvY3VtZW50O1xuICAgIGhhbmRsZXI0ID0gd3JhcEhhbmRsZXIoaGFuZGxlcjQsIChuZXh0LCBlKSA9PiB7XG4gICAgICBpZiAoZWwuY29udGFpbnMoZS50YXJnZXQpKVxuICAgICAgICByZXR1cm47XG4gICAgICBpZiAoZS50YXJnZXQuaXNDb25uZWN0ZWQgPT09IGZhbHNlKVxuICAgICAgICByZXR1cm47XG4gICAgICBpZiAoZWwub2Zmc2V0V2lkdGggPCAxICYmIGVsLm9mZnNldEhlaWdodCA8IDEpXG4gICAgICAgI
1HJldHVybjtcbiAgICAgIGlmIChlbC5feF9pc1Nob3duID09PSBmYWxzZSlcbiAgICAgICAgcmV0dXJuO1xuICAgICAgbmV4dChlKTtcbiAgICB9KTtcbiAgfVxuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwib25jZVwiKSkge1xuICAgIGhhbmRsZXI0ID0gd3JhcEhhbmRsZXIoaGFuZGxlcjQsIChuZXh0LCBlKSA9PiB7XG4gICAgICBuZXh0KGUpO1xuICAgICAgbGlzdGVuZXJUYXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgaGFuZGxlcjQsIG9wdGlvbnMpO1xuICAgIH0pO1xuICB9XG4gIGhhbmRsZXI0ID0gd3JhcEhhbmRsZXIoaGFuZGxlcjQsIChuZXh0LCBlKSA9PiB7XG4gICAgaWYgKGlzS2V5RXZlbnQoZXZlbnQpKSB7XG4gICAgICBpZiAoaXNMaXN0ZW5pbmdGb3JBU3BlY2lmaWNLZXlUaGF0SGFzbnRCZWVuUHJlc3NlZChlLCBtb2RpZmllcnMpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgbmV4dChlKTtcbiAgfSk7XG4gIGxpc3RlbmVyVGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIGhhbmRsZXI0LCBvcHRpb25zKTtcbiAgcmV0dXJuICgpID0+IHtcbiAgICBsaXN0ZW5lclRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBoYW5kbGVyNCwgb3B0aW9ucyk7XG4gIH07XG59XG5mdW5jdGlvbiBkb3RTeW50YXgoc3ViamVjdCkge1xuICByZXR1cm4gc3ViamVjdC5yZXBsYWNlKC8tL2csIFwiLlwiKTtcbn1cbmZ1bmN0aW9uIGNhbWVsQ2FzZTIoc3ViamVjdCkge1xuICByZXR1cm4gc3ViamVjdC50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoLy0oXFx3KS9nLCAobWF0Y2gsIGNoYXIpID0+IGNoYXIudG9VcHBlckNhc2UoKSk7XG59XG5mdW5jdGlvbiBpc051bWVyaWMoc3ViamVjdCkge1xuICByZXR1cm4gIUFycmF5LmlzQXJyYXkoc3ViamVjdCkgJiYgIWlzTmFOKHN1YmplY3QpO1xufVxuZnVuY3Rpb24ga2ViYWJDYXNlMihzdWJqZWN0KSB7XG4gIGlmIChbXCIgXCIsIFwiX1wiXS5pbmNsdWRlcyhzdWJqZWN0KSlcbiAgICByZXR1cm4gc3ViamVjdDtcbiAgcmV0dXJuIHN1YmplY3QucmVwbGFjZSgvKFthLXpdKShbQS1aXSkvZywgXCIkMS0kMlwiKS5yZXBsYWNlKC9bX1xcc10vLCBcIi1cIikudG9Mb3dlckNhc2UoKTtcbn1cbmZ1bmN0aW9uIGlzS2V5RXZlbnQoZXZlbnQpIHtcbiAgcmV0dXJuIFtcImtleWRvd25cIiwgXCJrZXl1cFwiXS5pbmNsdWRlcyhldmVudCk7XG59XG5mdW5jdGlvbiBpc0xpc3RlbmluZ0ZvckFTcGVjaWZpY0tleVRoYXRIYXNudEJlZW5QcmVzc2VkKGUsIG1vZGlmaWVycykge1xuICBsZXQga2V5TW9kaWZpZXJzID0gbW9kaWZpZXJzLmZpbHRlcigoaSkgPT4ge1xuICAgIHJldHVybiAhW1wid2luZG93XCIsIFwiZG9jdW1lbnRcIiwgXCJwcmV2ZW50XCIsIFwic3RvcFwiLCBcIm9uY2VcIiwgXCJjYXB0dXJlXCJdLmluY2x1ZGVzKGkpO1xuICB9KTtcbiAgaWYgKGtleU1vZGlmaWVycy5pbmNsdWRlcyhcImRlYm91bmNlXCIpKSB7XG4gICAgbGV0IGRlYm91bmNlSW5kZXggPSBrZXlNb2RpZmllcnMuaW5kZXhPZihcImRlYm91bmNlXCIpO1xuICAgIGtleU1vZGlmaWVycy5zcGxpY2UoZGVib3VuY2VJbmRleCwgaXNOdW1lcmljKChrZXlNb2RpZmllcnNbZGVib3VuY2VJbmRleCArIDFdIHx8IFwiaW52YWxpZC13YWl0XCIpLnNwbGl0KFwibXNcIilbMF0pID8gMiA6IDEpO1xuICB9XG4gIGlmIChrZXlNb2RpZmllcnMuaW5jbHVkZXMoXCJ0aHJvdHRsZVwiKSkge1xuICAgIGxldCBkZWJvdW5jZUluZGV4ID0ga2V5TW9kaWZpZXJzLmluZGV4T2YoXCJ0aHJvdHRsZVwiKTtcbiAgICBrZXlNb2RpZmllcnMuc3BsaWNlKGRlYm91bmNlSW5kZXgsIGlzTnVtZXJpYygoa2V5TW9kaWZpZXJzW2RlYm91bmNlSW5kZXggKyAxXSB8fCBcImludmFsaWQtd2FpdFwiKS5zcGxpdChcIm1zXCIpWzBdKSA/IDIgOiAxKTtcbiAgfVxuICBpZiAoa2V5TW9kaWZpZXJzLmxlbmd0aCA9PT0gMClcbiAgICByZXR1cm4gZmFsc2U7XG4gIGlmIChrZXlNb2RpZmllcnMubGVuZ3RoID09PSAxICYmIGtleVRvTW9kaWZpZXJzKGUua2V5KS5pbmNsdWRlcyhrZXlNb2RpZmllcnNbMF0pKVxuICAgIHJldHVybiBmYWxzZTtcbiAgY29uc3Qgc3lzdGVtS2V5TW9kaWZpZXJzID0gW1wiY3RybFwiLCBcInNoaWZ0XCIsIFwiYWx0XCIsIFwibWV0YVwiLCBcImNtZFwiLCBcInN1cGVyXCJdO1xuICBjb25zdCBzZWxlY3RlZFN5c3RlbUtleU1vZGlmaWVycyA9IHN5c3RlbUtleU1vZGlmaWVycy5maWx0ZXIoKG1vZGlmaWVyKSA9PiBrZXlNb2RpZmllcnMuaW5jbHVkZXMobW9kaWZpZXIpKTtcbiAga2V5TW9kaWZpZXJzID0ga2V5TW9kaWZpZXJzLmZpbHRlcigoaSkgPT4gIXNlbGVjdGVkU3lzdGVtS2V5TW9kaWZpZXJzLmluY2x1ZGVzKGkpKTtcbiAgaWYgKHNlbGVjdGVkU3lzdGVtS2V5TW9kaWZpZXJzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBhY3RpdmVseVByZXNzZWRLZXlNb2RpZmllcnMgPSBzZWxlY3RlZFN5c3RlbUtleU1vZGlmaWVycy5maWx0ZXIoKG1vZGlmaWVyKSA9PiB7XG4gICAgICBpZiAobW9kaWZpZXIgPT09IFwiY21kXCIgfHwgbW9kaWZpZXIgPT09IFwic3VwZXJcIilcbiAgICAgICAgbW9kaWZpZXIgPSBcIm1ldGFcIjtcbiAgICAgIHJldHVybiBlW2Ake21vZGlmaWVyfUtleWBdO1xuICAgIH0pO1xuICAgIGlmIChhY3RpdmVseVByZXNzZWRLZXlNb2RpZmllcnMubGVuZ3RoID09PSBzZWxlY3RlZFN5c3RlbUtleU1vZGlmaWVycy5sZW5ndGgpIHtcbiAgICAgIGlmIChrZXlUb01vZGlmaWVycyhlLmtleSkuaW5jbHVkZXMoa2V5TW9kaWZpZXJzWzBdKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIGtleVRvTW9kaWZpZXJzKGtleSkge1xuICBpZiAoIWtleSlcbiAgICByZXR1cm4gW107XG4gIGtleSA9IGtlYmFiQ2FzZTIoa2V5KTtcbiAgbGV0IG1vZGlmaWVyVG9LZXlNYXAgPSB7XG4gICAgY3RybDogXCJjb250cm9sXCIsXG4gICAgc2xhc2g6IFwiL1wiLFxuICAgIHNwYWNlOiBcIiBcIixcbiAgICBzcGFjZWJhcjogXCIgXCIsXG4gICAgY21kOiBcIm1ldGFcIixcbiAgICBlc2M6IFwiZXNjYXBlXCIsXG4gICAgdXA6IFwiYXJyb3ctdXBcIixcbiAgICBkb3duOiBcImFycm93LWRvd25cIixcbiAgICBsZWZ0OiBcImFycm93LWxlZnRcIixcbiAgICByaWdodDogXCJhcnJvdy1yaWdodFwiLFxuICAgIHBlcmlvZDogXCIuXCIsXG4gICAgZXF1YWw6IFwiPVwiLFxuICAgIG1pbnVzOiBcIi1cIixcbiAgICB1bmRlcnNjb3JlOiBcIl9cIlxuICB9O1xuICBtb2RpZmllclRvS2V5TWFwW2tleV0gPSBrZXk7XG4gIHJldHVybi
1BPYmplY3Qua2V5cyhtb2RpZmllclRvS2V5TWFwKS5tYXAoKG1vZGlmaWVyKSA9PiB7XG4gICAgaWYgKG1vZGlmaWVyVG9LZXlNYXBbbW9kaWZpZXJdID09PSBrZXkpXG4gICAgICByZXR1cm4gbW9kaWZpZXI7XG4gIH0pLmZpbHRlcigobW9kaWZpZXIpID0+IG1vZGlmaWVyKTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC1tb2RlbC5qc1xuZGlyZWN0aXZlKFwibW9kZWxcIiwgKGVsLCB7bW9kaWZpZXJzLCBleHByZXNzaW9ufSwge2VmZmVjdDogZWZmZWN0MywgY2xlYW51cDogY2xlYW51cDJ9KSA9PiB7XG4gIGxldCBzY29wZVRhcmdldCA9IGVsO1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwicGFyZW50XCIpKSB7XG4gICAgc2NvcGVUYXJnZXQgPSBlbC5wYXJlbnROb2RlO1xuICB9XG4gIGxldCBldmFsdWF0ZUdldCA9IGV2YWx1YXRlTGF0ZXIoc2NvcGVUYXJnZXQsIGV4cHJlc3Npb24pO1xuICBsZXQgZXZhbHVhdGVTZXQ7XG4gIGlmICh0eXBlb2YgZXhwcmVzc2lvbiA9PT0gXCJzdHJpbmdcIikge1xuICAgIGV2YWx1YXRlU2V0ID0gZXZhbHVhdGVMYXRlcihzY29wZVRhcmdldCwgYCR7ZXhwcmVzc2lvbn0gPSBfX3BsYWNlaG9sZGVyYCk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGV4cHJlc3Npb24gPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgZXhwcmVzc2lvbigpID09PSBcInN0cmluZ1wiKSB7XG4gICAgZXZhbHVhdGVTZXQgPSBldmFsdWF0ZUxhdGVyKHNjb3BlVGFyZ2V0LCBgJHtleHByZXNzaW9uKCl9ID0gX19wbGFjZWhvbGRlcmApO1xuICB9IGVsc2Uge1xuICAgIGV2YWx1YXRlU2V0ID0gKCkgPT4ge1xuICAgIH07XG4gIH1cbiAgbGV0IGdldFZhbHVlID0gKCkgPT4ge1xuICAgIGxldCByZXN1bHQ7XG4gICAgZXZhbHVhdGVHZXQoKHZhbHVlKSA9PiByZXN1bHQgPSB2YWx1ZSk7XG4gICAgcmV0dXJuIGlzR2V0dGVyU2V0dGVyKHJlc3VsdCkgPyByZXN1bHQuZ2V0KCkgOiByZXN1bHQ7XG4gIH07XG4gIGxldCBzZXRWYWx1ZSA9ICh2YWx1ZSkgPT4ge1xuICAgIGxldCByZXN1bHQ7XG4gICAgZXZhbHVhdGVHZXQoKHZhbHVlMikgPT4gcmVzdWx0ID0gdmFsdWUyKTtcbiAgICBpZiAoaXNHZXR0ZXJTZXR0ZXIocmVzdWx0KSkge1xuICAgICAgcmVzdWx0LnNldCh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV2YWx1YXRlU2V0KCgpID0+IHtcbiAgICAgIH0sIHtcbiAgICAgICAgc2NvcGU6IHtfX3BsYWNlaG9sZG
1VyOiB2YWx1ZX1cbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcbiAgaWYgKHR5cGVvZiBleHByZXNzaW9uID09PSBcInN0cmluZ1wiICYmIGVsLnR5cGUgPT09IFwicmFkaW9cIikge1xuICAgIG11dGF0ZURvbSgoKSA9PiB7XG4gICAgICBpZiAoIWVsLmhhc0F0dHJpYnV0ZShcIm5hbWVcIikpXG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShcIm5hbWVcIiwgZXhwcmVzc2lvbik7XG4gICAgfSk7XG4gIH1cbiAgdmFyIGV2ZW50ID0gZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcInNlbGVjdFwiIHx8IFtcImNoZWNrYm94XCIsIFwicmFkaW9cIl0uaW5jbHVkZXMoZWwudHlwZSkgfHwgbW9kaWZpZXJzLmluY2x1ZGVzKFwibGF6eVwiKSA/IFwiY2hhbmdlXCIgOiBcImlucHV0XCI7XG4gIGxldCByZW1vdmVMaXN0ZW5lciA9IGlzQ2xvbmluZyA/ICgpID0+IHtcbiAgfSA6IG9uKGVsLCBldmVudCwgbW9kaWZpZXJzLCAoZSkgPT4ge1xuICAgIHNldFZhbHVlKGdldElucHV0VmFsdWUoZWwsIG1vZGlmaWVycywgZSwgZ2V0VmFsdWUoKSkpO1xuICB9KTtcbiAgaWYgKG1vZGlmaWVycy5pbmNsdWRlcyhcImZpbGxcIikgJiYgW251bGwsIFwiXCJdLmluY2x1ZGVzKGdldFZhbHVlKCkpKSB7XG4gICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoZXZlbnQsIHt9KSk7XG4gIH1cbiAgaWYgKCFlbC5feF9yZW1vdmVNb2RlbExpc3RlbmVycylcbiAgICBlbC5feF9yZW1vdmVNb2RlbExpc3RlbmVycyA9IHt9O1xuICBlbC5feF9yZW1vdmVNb2RlbExpc3RlbmVyc1tcImRlZmF1bHRcIl0gPSByZW1vdmVMaXN0ZW5lcjtcbiAgY2xlYW51cDIoKCkgPT4gZWwuX3hfcmVtb3ZlTW9kZWxMaXN0ZW5lcnNbXCJkZWZhdWx0XCJdKCkpO1xuICBpZiAoZWwuZm9ybSkge1xuICAgIGxldCByZW1vdmVSZXNldExpc3RlbmVyID0gb24oZWwuZm9ybSwgXCJyZXNldFwiLCBbXSwgKGUpID0+IHtcbiAgICAgIG5leHRUaWNrKCgpID0+IGVsLl94X21vZGVsICYmIGVsLl94X21vZGVsLnNldChlbC52YWx1ZSkpO1xuICAgIH0pO1xuICAgIGNsZWFudXAyKCgpID0+IHJlbW92ZVJlc2V0TGlzdGVuZXIoKSk7XG4gIH1cbiAgZWwuX3hfbW9kZWwgPSB7XG4gICAgZ2V0KCkge1xuICAgICAgcmV0dXJuIGdldFZhbHVlKCk7XG4gICAgfSxcbiAgICBzZXQodmFsdWUpIHtcbiAgICAgIHNldFZhbHVlKHZhbHVlKTtcbiAgICB9XG4gIH07XG4gIGVsLl94X2ZvcmNlTW9kZWxVcGRhdGUgPSAodmFsdWUpID0+IHtcbiAgICB2YWx1ZSA9IHZhbHVlID09PSB2b2lkIDAgPyBnZXRWYWx1ZSgpIDogdmFsdWU7XG4gICAgaWYgKHZhbHVlID09PSB2b2lkIDAgJiYgdHlwZW9mIGV4cHJlc3Npb24gPT09IFwic3RyaW5nXCIgJiYgZXhwcmVzc2lvbi5tYXRjaCgvXFwuLykpXG4gICAgICB2YWx1ZSA9IFwiXCI7XG4gICAgd2luZG93LmZyb21Nb2RlbCA9IHRydWU7XG4gICAgbXV0YXRlRG9tKCgpID0+IGJpbmQoZWwsIFwidmFsdWVcIiwgdmFsdWUpKTtcbiAgICBkZWxldGUgd2luZG93LmZyb21Nb2RlbDtcbiAgfTtcbiAgZWZmZWN0MygoKSA9PiB7XG4gICAgbGV0IHZhbHVlID0gZ2V0VmFsdWUoKTtcbiAgICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwidW5pbnRydXNpdmVcIikgJiYgZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5pc1NhbWVOb2RlKGVsKSlcbiAgICAgIHJldHVybjtcbiAgICBlbC5feF9mb3JjZU1vZGVsVXBkYXRlKHZhbHVlKTtcbiAgfSk7XG59KTtcbmZ1bmN0aW9uIGdldElucHV0VmFsdWUoZWwsIG1vZGlmaWVycywgZXZlbnQsIGN1cnJlbnRWYWx1ZSkge1xuICByZXR1cm4gbXV0YXRlRG9tKCgpID0+IHtcbiAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBDdXN0b21FdmVudCAmJiBldmVudC5kZXRhaWwgIT09IHZvaWQgMClcbiAgICAgIHJldHVybiBldmVudC5kZXRhaWwgPz8gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIGVsc2UgaWYgKGVsLnR5cGUgPT09IFwiY2hlY2tib3hcIikge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY3VycmVudFZhbHVlKSkge1xuICAgICAgICBsZXQgbmV3VmFsdWUgPSBtb2RpZmllcnMuaW5jbHVkZXMoXCJudW1iZXJcIikgPyBzYWZlUGFyc2VOdW1iZXIoZXZlbnQudGFyZ2V0LnZhbHVlKSA6IGV2ZW50LnRhcmdldC52YWx1ZTtcbiAgICAgICAgcmV0dXJuIGV2ZW50LnRhcmdldC5jaGVja2VkID8gY3VycmVudFZhbHVlLmNvbmNhdChbbmV3VmFsdWVdKSA6IGN1cnJlbnRWYWx1ZS5maWx0ZXIoKGVsMikgPT4gIWNoZWNrZWRBdHRyTG9vc2VDb21wYXJlMihlbDIsIG5ld1ZhbHVlKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZXZlbnQudGFyZ2V0LmNoZWNrZWQ7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwic2VsZWN0XCIgJiYgZWwubXVsdGlwbGUpIHtcbiAgICAgIHJldHVybiBtb2RpZmllcnMuaW5jbHVkZXMoXCJudW1iZXJcIikgPyBBcnJheS5mcm9tKGV2ZW50LnRhcmdldC5zZWxlY3RlZE9wdGlvbnMpLm1hcCgob3B0aW9uKSA9PiB7XG4gICAgICAgIGxldCByYXdWYWx1ZSA9IG9wdGlvbi52YWx1ZSB8fCBvcHRpb24udGV4dDtcbiAgICAgICAgcmV0dXJuIHNhZmVQYXJzZU51bWJlcihyYXdWYWx1ZSk7XG4gICAgICB9KSA6IEFycmF5LmZyb20oZXZlbnQudGFyZ2V0LnNlbGVjdGVkT3B0aW9ucykubWFwKChvcHRpb24pID0+IHtcbiAgICAgICAgcmV0dXJuIG9wdGlvbi52YWx1ZSB8fCBvcHRpb24udGV4dDtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgcmF3VmFsdWUgPSBldmVudC50YXJnZXQudmFsdWU7XG4gICAgICByZXR1cm4gbW9kaWZpZXJzLmluY2x1ZGVzKFwibnVtYmVyXCIpID8gc2FmZVBhcnNlTnVtYmVyKHJhd1ZhbHVlKSA6IG1vZGlmaWVycy5pbmNsdWRlcyhcInRyaW1cIikgPyByYXdWYWx1ZS50cmltKCkgOiByYXdWYWx1ZTtcbiAgICB9XG4gIH0pO1xufVxuZnVuY3Rpb24gc2FmZVBhcnNlTnVtYmVyKHJhd1ZhbHVlKSB7XG4gIGxldCBudW1iZXIgPSByYXdWYWx1ZSA/IHBhcnNlRmxvYXQocmF3VmFsdWUpIDogbnVsbDtcbiAgcmV0dXJuIGlzTnVtZXJpYzIobnVtYmVyKSA/IG51bWJlciA6IHJhd1ZhbHVlO1xufVxuZnVuY3Rpb24gY2hlY2tlZEF0dHJMb29zZUNvbXBhcmUyKHZhbHVlQSwgdmFsdWVCKSB7XG4gIHJldHVybi
1B2YWx1ZUEgPT0gdmFsdWVCO1xufVxuZnVuY3Rpb24gaXNOdW1lcmljMihzdWJqZWN0KSB7XG4gIHJldHVybiAhQXJyYXkuaXNBcnJheShzdWJqZWN0KSAmJiAhaXNOYU4oc3ViamVjdCk7XG59XG5mdW5jdGlvbiBpc0dldHRlclNldHRlcih2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiB2YWx1ZS5nZXQgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgdmFsdWUuc2V0ID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtY2xvYWsuanNcbmRpcmVjdGl2ZShcImNsb2FrXCIsIChlbCkgPT4gcXVldWVNaWNyb3Rhc2soKCkgPT4gbXV0YXRlRG9tKCgpID0+IGVsLnJlbW92ZUF0dHJpYnV0ZShwcmVmaXgoXCJjbG9ha1wiKSkpKSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtaW5pdC5qc1xuYWRkSW5pdFNlbGVjdG9yKCgpID0+IGBbJHtwcmVmaXgoXCJpbml0XCIpfV1gKTtcbmRpcmVjdGl2ZShcImluaXRcIiwgc2tpcER1cmluZ0Nsb25lKChlbCwge2V4cHJlc3Npb259LCB7ZXZhbHVhdGU6IGV2YWx1YXRlMn0pID0+IHtcbiAgaWYgKHR5cGVvZiBleHByZXNzaW9uID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuICEhZXhwcmVzc2lvbi50cmltKCkgJiYgZXZhbHVhdGUyKGV4cHJlc3Npb24sIHt9LCBmYWxzZSk7XG4gIH1cbiAgcmV0dXJuIGV2YWx1YXRlMihleHByZXNzaW9uLCB7fSwgZmFsc2UpO1xufSkpO1xuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvZGlyZWN0aXZlcy94LXRleHQuanNcbmRpcmVjdGl2ZShcInRleHRcIiwgKGVsLCB7ZXhwcmVzc2lvbn0sIHtlZmZlY3Q6IGVmZmVjdDMsIGV2YWx1YXRlTGF0ZXI6IGV2YWx1YXRlTGF0ZXIyfSkgPT4ge1xuICBsZXQgZXZhbHVhdGUyID0gZXZhbHVhdGVMYXRlcjIoZXhwcmVzc2lvbik7XG4gIGVmZmVjdDMoKCkgPT4ge1xuICAgIGV2YWx1YXRlMigodmFsdWUpID0+IHtcbiAgICAgIG11dGF0ZURvbSgoKSA9PiB7XG4gICAgICAgIGVsLnRleHRDb250ZW50ID0gdmFsdWU7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC1odG1sLmpzXG5kaXJlY3RpdmUoXCJodG1sXCIsIChlbCwge2V4cHJlc3Npb259LCB7ZWZmZWN0OiBlZmZlY3QzLCBldmFsdWF0ZUxhdGVyOiBldmFsdWF0ZUxhdGVyMn0pID0+IHtcbiAgbGV0IGV2YWx1YXRlMiA9IGV2YWx1YXRlTGF0ZXIyKGV4cHJlc3Npb24pO1xuICBlZmZlY3QzKCgpID0+IHtcbiAgICBldmFsdWF0ZTIoKHZhbHVlKSA9PiB7XG4gICAgICBtdXRhdGVEb20oKCkgPT4ge1xuICAgICAgICBlbC5pbm5lckhUTUwgPSB2YWx1ZTtcbiAgICAgICAgZWwuX3hfaWdub3JlU2VsZiA9IHRydWU7XG4gICAgICAgIGluaXRUcmVlKGVsKTtcbiAgICAgICAgZGVsZXRlIGVsLl94X2lnbm9yZVNlbGY7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC1iaW5kLmpzXG5tYXBBdHRyaWJ1dGVzKHN0YXJ0aW5nV2l0aChcIjpcIiwgaW50byhwcmVmaXgoXCJiaW5kOlwiKSkpKTtcbnZhciBoYW5kbGVyMiA9IChlbCwge3ZhbHVlLCBtb2RpZmllcnMsIGV4cHJlc3Npb24sIG9yaWdpbmFsfSwge2VmZmVjdDogZWZmZWN0M30pID0+IHtcbiAgaWYgKCF2YWx1ZSkge1xuICAgIGxldCBiaW5kaW5nUHJvdmlkZXJzID0ge307XG4gICAgaW5qZWN0QmluZGluZ1Byb3ZpZGVycyhiaW5kaW5nUHJvdmlkZXJzKTtcbiAgICBsZXQgZ2V0QmluZGluZ3MgPSBldmFsdWF0ZUxhdGVyKGVsLCBleHByZXNzaW9uKTtcbiAgICBnZXRCaW5kaW5ncygoYmluZGluZ3MpID0+IHtcbiAgICAgIGFwcGx5QmluZGluZ3NPYmplY3QoZWwsIGJpbmRpbmdzLCBvcmlnaW5hbCk7XG4gICAgfSwge3Njb3BlOiBiaW5kaW5nUHJvdmlkZXJzfSk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmICh2YWx1ZSA9PT0gXCJrZXlcIilcbiAgICByZXR1cm4gc3RvcmVLZXlGb3JYRm9yKGVsLCBleHByZXNzaW9uKTtcbiAgaWYgKGVsLl94X2lubGluZUJpbmRpbmdzICYmIGVsLl94X2lubGluZUJpbmRpbmdzW3ZhbHVlXSAmJiBlbC5feF9pbmxpbmVCaW5kaW5nc1t2YWx1ZV0uZXh0cmFjdCkge1xuICAgIHJldHVybjtcbiAgfVxuICBsZXQgZXZhbHVhdGUyID0gZXZhbHVhdGVMYXRlcihlbCwgZXhwcmVzc2lvbik7XG4gIGVmZmVjdDMoKCkgPT4gZXZhbHVhdGUyKChyZXN1bHQpID0+IHtcbiAgICBpZiAocmVzdWx0ID09PSB2b2lkIDAgJiYgdHlwZW9mIGV4cHJlc3Npb24gPT09IFwic3RyaW5nXCIgJiYgZXhwcmVzc2lvbi5tYXRjaCgvXFwuLykpIHtcbiAgICAgIHJlc3VsdCA9IFwiXCI7XG4gICAgfVxuICAgIG11dGF0ZURvbSgoKSA9PiBiaW5kKGVsLCB2YWx1ZSwgcmVzdWx0LCBtb2RpZmllcnMpKTtcbiAgfSkpO1xufTtcbmhhbmRsZXIyLmlubGluZSA9IChlbCwge3ZhbHVlLCBtb2RpZmllcnMsIGV4cHJlc3Npb259KSA9PiB7XG4gIGlmICghdmFsdWUpXG4gICAgcmV0dXJuO1xuICBpZiAoIWVsLl94X2lubGluZUJpbmRpbmdzKVxuICAgIGVsLl94X2lubGluZUJpbmRpbmdzID0ge307XG4gIGVsLl94X2lubGluZUJpbmRpbmdzW3ZhbHVlXSA9IHtleHByZXNzaW9uLCBleHRyYWN0OiBmYWxzZX07XG59O1xuZGlyZWN0aXZlKFwiYmluZFwiLCBoYW5kbGVyMik7XG5mdW5jdGlvbiBzdG9yZUtleUZvclhGb3IoZWwsIGV4cHJlc3Npb24pIHtcbiAgZWwuX3hfa2V5RXhwcmVzc2lvbiA9IGV4cHJlc3Npb247XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtZGF0YS5qc1xuYWRkUm9vdFNlbGVjdG9yKCgpID0+IGBbJHtwcmVmaXgoXCJkYXRhXCIpfV1gKTtcbmRpcmVjdGl2ZShcImRhdGFcIiwgc2tpcER1cmluZ0Nsb25lKChlbCwge2V4cHJlc3Npb259LCB7Y2xlYW51cDogY2xlYW51cDJ9KSA9PiB7XG4gIGV4cHJlc3Npb24gPSBleHByZXNzaW9uID09PSBcIlwiID8gXCJ7fVwiIDogZXhwcmVzc2lvbjtcbiAgbGV0IG1hZ2ljQ29udGV4dCA9IHt9O1xuICBpbmplY3RNYWdpY3MobWFnaWNDb250ZXh0LCBlbCk7XG4gIGxldCBkYXRhUHJvdmlkZXJDb250ZXh0ID0ge307XG4gIGluamVjdERhdGFQcm92aWRlcnMoZGF0YVByb3ZpZGVyQ29udGV4dCwgbWFnaWNDb250ZXh0KTtcbiAgbGV0IGRhdGEyID0gZXZhbHVhdGUoZWwsIGV4cHJlc3Npb24sIHtzY29wZTogZGF0YVByb3ZpZGVyQ29udGV4dH0pO1xuICBpZiAoZGF0YTIgPT09IHZvaWQgMCB8fCBkYXRhMiA9PT0gdHJ1ZSlcbiAgICBkYXRhMiA9IHt9O1xuICBpbmplY3RNYWdpY3MoZGF0YTIsIGVsKTtcbiAgbGV0IHJlYWN0aXZlRGF0YSA9IHJlYWN0aXZlKGRhdGEyKTtcbiAgaW5pdEludGVyY2VwdG9ycyhyZWFjdGl2ZURhdGEpO1xuICBsZXQgdW5kbyA9IGFkZFNjb3BlVG9Ob2RlKGVsLCByZWFjdGl2ZURhdGEpO1xuICByZWFjdGl2ZURhdGFbXCJpbml0XCJdICYmIGV2YWx1YXRlKGVsLCByZWFjdGl2ZURhdGFbXCJpbml0XCJdKTtcbiAgY2xlYW51cDIoKCkgPT4ge1xuICAgIHJlYWN0aXZlRGF0YVtcImRlc3Ryb3lcIl0gJiYgZXZhbHVhdGUoZWwsIHJlYWN0aXZlRGF0YVtcImRlc3Ryb3lcIl0pO1xuICAgIHVuZG8oKTtcbiAgfSk7XG59KSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtc2hvdy5qc1xuZGlyZWN0aXZlKFwic2hvd1wiLCAoZWwsIHttb2RpZmllcnMsIGV4cHJlc3Npb259LCB7ZWZmZWN0OiBlZmZlY3QzfSkgPT4ge1xuICBsZXQgZXZhbHVhdGUyID0gZXZhbHVhdGVMYXRlcihlbCwgZXhwcmVzc2lvbik7XG4gIGlmICghZWwuX3hfZG9IaWRlKVxuICAgIGVsLl94X2RvSGlkZSA9ICgpID0+IHtcbiAgICAgIG11dGF0ZURvbSgoKSA9PiB7XG4gICAgICAgIGVsLnN0eWxlLnNldFByb3BlcnR5KFwiZGlzcGxheVwiLCBcIm5vbmVcIiwgbW9kaWZpZXJzLmluY2x1ZGVzKFwiaW1wb3J0YW50XCIpID8gXCJpbXBvcnRhbnRcIiA6IHZvaWQgMCk7XG4gICAgICB9KTtcbiAgICB9O1xuICBpZiAoIWVsLl94X2RvU2hvdylcbiAgICBlbC5feF9kb1Nob3cgPSAoKSA9PiB7XG4gICAgICBtdXRhdGVEb20oKCkgPT4ge1xuICAgICAgICBpZiAoZWwuc3R5bGUubGVuZ3RoID09PSAxICYmIGVsLnN0eWxlLmRpc3BsYXkgPT09IFwibm9uZVwiKSB7XG4gICAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKFwic3R5bGVcIik7XG4gICAgICAgI
1H0gZWxzZSB7XG4gICAgICAgICAgZWwuc3R5bGUucmVtb3ZlUHJvcGVydHkoXCJkaXNwbGF5XCIpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuICBsZXQgaGlkZSA9ICgpID0+IHtcbiAgICBlbC5feF9kb0hpZGUoKTtcbiAgICBlbC5feF9pc1Nob3duID0gZmFsc2U7XG4gIH07XG4gIGxldCBzaG93ID0gKCkgPT4ge1xuICAgIGVsLl94X2RvU2hvdygpO1xuICAgIGVsLl94X2lzU2hvd24gPSB0cnVlO1xuICB9O1xuICBsZXQgY2xpY2tBd2F5Q29tcGF0aWJsZVNob3cgPSAoKSA9PiBzZXRUaW1lb3V0KHNob3cpO1xuICBsZXQgdG9nZ2xlID0gb25jZSgodmFsdWUpID0+IHZhbHVlID8gc2hvdygpIDogaGlkZSgpLCAodmFsdWUpID0+IHtcbiAgICBpZiAodHlwZW9mIGVsLl94X3RvZ2dsZUFuZENhc2NhZGVXaXRoVHJhbnNpdGlvbnMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgZWwuX3hfdG9nZ2xlQW5kQ2FzY2FkZVdpdGhUcmFuc2l0aW9ucyhlbCwgdmFsdWUsIHNob3csIGhpZGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSA/IGNsaWNrQXdheUNvbXBhdGlibGVTaG93KCkgOiBoaWRlKCk7XG4gICAgfVxuICB9KTtcbiAgbGV0IG9sZFZhbHVlO1xuICBsZXQgZmlyc3RUaW1lID0gdHJ1ZTtcbiAgZWZmZWN0MygoKSA9PiBldmFsdWF0ZTIoKHZhbHVlKSA9PiB7XG4gICAgaWYgKCFmaXJzdFRpbWUgJiYgdmFsdWUgPT09IG9sZFZhbHVlKVxuICAgICAgcmV0dXJuO1xuICAgIGlmIChtb2RpZmllcnMuaW5jbHVkZXMoXCJpbW1lZGlhdGVcIikpXG4gICAgICB2YWx1ZSA/IGNsaWNrQXdheUNvbXBhdGlibGVTaG93KCkgOiBoaWRlKCk7XG4gICAgdG9nZ2xlKHZhbHVlKTtcbiAgICBvbGRWYWx1ZSA9IHZhbHVlO1xuICAgIGZpcnN0VGltZSA9IGZhbHNlO1xuICB9KSk7XG59KTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC1mb3IuanNcbmRpcmVjdGl2ZShcImZvclwiLCAoZWwsIHtleHByZXNzaW9ufSwge2VmZmVjdDogZWZmZWN0MywgY2xlYW51cDogY2xlYW51cDJ9KSA9PiB7XG4gIGxldCBpdGVyYXRvck5hbWVzID0gcGFyc2VGb3JFeHByZXNzaW9uKGV4cHJlc3Npb24pO1xuICBsZXQgZXZhbHVhdGVJdGVtcyA9IGV2YWx1YXRlTGF0ZXIoZWwsIGl0ZXJhdG9yTmFtZXMuaXRlbXMpO1xuICBsZXQgZXZhbHVhdGVLZXkgPSBldmFsdWF0ZUxhdGVyKGVsLCBlbC5feF9rZXlFeHByZXNzaW9uIHx8IFwiaW5kZXhcIik7XG4gIGVsLl94X3ByZXZLZXlzID0gW107XG4gIGVsLl94X2xvb2t1cCA9IHt9O1xuICBlZmZlY3QzKCgpID0+IGxvb3AoZWwsIGl0ZXJhdG9yTmFtZXMsIGV2YWx1YXRlSXRlbXMsIGV2YWx1YXRlS2V5KSk7XG4gIGNsZWFudXAyKCgpID0+IHtcbiAgICBPYmplY3QudmFsdWVzKGVsLl94X2xvb2t1cCkuZm9yRWFjaCgoZWwyKSA9PiBlbDIucmVtb3ZlKCkpO1xuICAgIGRlbGV0ZSBlbC5feF9wcmV2S2V5cztcbiAgICBkZWxldGUgZWwuX3hfbG9va3VwO1xuICB9KTtcbn0pO1xuZnVuY3Rpb24gbG9vcChlbCwgaXRlcmF0b3JOYW1lcywgZXZhbHVhdGVJdGVtcywgZXZhbHVhdGVLZXkpIHtcbiAgbGV0IGlzT2JqZWN0MiA9IChpKSA9PiB0eXBlb2YgaSA9PT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheShpKTtcbiAgbGV0IHRlbXBsYXRlRWwgPSBlbDtcbiAgZXZhbHVhdGVJdGVtcygoaXRlbXMpID0+IHtcbiAgICBpZiAoaXNOdW1lcmljMyhpdGVtcykgJiYgaXRlbXMgPj0gMCkge1xuICAgICAgaXRlbXMgPSBBcnJheS5mcm9tKEFycmF5KGl0ZW1zKS5rZXlzKCksIChpKSA9PiBpICsgMSk7XG4gICAgfVxuICAgIGlmIChpdGVtcyA9PT0gdm9pZCAwKVxuICAgICAgaXRlbXMgPSBbXTtcbiAgICBsZXQgbG9va3VwID0gZWwuX3hfbG9va3VwO1xuICAgIGxldCBwcmV2S2V5cyA9IGVsLl94X3ByZXZLZXlzO1xuICAgIGxldCBzY29wZXMgPSBbXTtcbiAgICBsZXQga2V5cyA9IFtdO1xuICAgIGlmIChpc09iamVjdDIoaXRlbXMpKSB7XG4gICAgICBpdGVtcyA9IE9iamVjdC5lbnRyaWVzKGl0ZW1zKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICBsZXQgc2NvcGUyID0gZ2V0SXRlcmF0aW9uU2NvcGVWYXJpYWJsZXMoaXRlcmF0b3JOYW1lcywgdmFsdWUsIGtleSwgaXRlbXMpO1xuICAgICAgICBldmFsdWF0ZUtleSgodmFsdWUyKSA9PiBrZXlzLnB1c2godmFsdWUyKSwge3Njb3BlOiB7aW5kZXg6IGtleSwgLi4uc2NvcGUyfX0pO1xuICAgICAgICBzY29wZXMucHVzaChzY29wZTIpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IHNjb3BlMiA9IGdldEl0ZXJhdGlvblNjb3BlVmFyaWFibGVzKGl0ZXJhdG9yTmFtZXMsIGl0ZW1zW2ldLCBpLCBpdGVtcyk7XG4gICAgICAgIGV2YWx1YXRlS2V5KCh2YWx1ZSkgPT4ga2V5cy5wdXNoKHZhbHVlKSwge3Njb3BlOiB7aW5kZXg6IGksIC4uLnNjb3BlMn19KTtcbiAgICAgICAgc2NvcGVzLnB1c2goc2NvcGUyKTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IGFkZHMgPSBbXTtcbiAgICBsZXQgbW92ZXMgPSBbXTtcbiAgICBsZXQgcmVtb3ZlcyA9IFtdO1xuICAgIGxldCBzYW1lcyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJldktleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBrZXkgPSBwcmV2S2V5c1tpXTtcbiAgICAgIGlmIChrZXlzLmluZGV4T2Yoa2V5KSA9PT0gLTEpXG4gICAgICAgIHJlbW92ZXMucHVzaChrZXkpO1xuICAgIH1cbiAgICBwcmV2S2V5cyA9IHByZXZLZXlzLmZpbHRlcigoa2V5KSA9PiAhcmVtb3Zlcy5pbmNsdWRlcyhrZXkpKTtcbiAgICBsZXQgbGFzdEtleSA9IFwidGVtcGxhdGVcIjtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBrZXkgPSBrZXlzW2ldO1xuICAgICAgbGV0IHByZXZJbmRleCA9IHByZXZLZXlzLmluZGV4T2Yoa2V5KTtcbiAgICAgIGlmIChwcmV2SW5kZXggPT09IC0xKSB7XG4gICAgICAgIHByZXZLZXlzLnNwbGljZShpLCAwLCBrZXkpO1xuICAgICAgICBhZGRzLnB1c2goW2xhc3RLZXksIGldKTtcbiAgICAgIH0gZWxzZSBpZiAocHJldkluZGV4ICE9PSBpKSB7XG4gICAgICAgIGxldCBrZXlJblNwb3QgPSBwcmV2S2V5cy5zcGxpY2UoaSwgMSlbMF07XG4gICAgICAgIGxldCBrZXlGb3JTcG90ID0gcHJldktleXMuc3BsaWNlKHByZXZJbmRleCAtIDEsIDEpWzBdO1xuICAgICAgICBwcmV2S2V5cy5zcGxpY2UoaSwgMCwga2V5Rm9yU3BvdCk7XG4gICAgICAgI
1HByZXZLZXlzLnNwbGljZShwcmV2SW5kZXgsIDAsIGtleUluU3BvdCk7XG4gICAgICAgIG1vdmVzLnB1c2goW2tleUluU3BvdCwga2V5Rm9yU3BvdF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2FtZXMucHVzaChrZXkpO1xuICAgICAgfVxuICAgICAgbGFzdEtleSA9IGtleTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZW1vdmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQga2V5ID0gcmVtb3Zlc1tpXTtcbiAgICAgIGlmICghIWxvb2t1cFtrZXldLl94X2VmZmVjdHMpIHtcbiAgICAgICAgbG9va3VwW2tleV0uX3hfZWZmZWN0cy5mb3JFYWNoKGRlcXVldWVKb2IpO1xuICAgICAgfVxuICAgICAgbG9va3VwW2tleV0ucmVtb3ZlKCk7XG4gICAgICBsb29rdXBba2V5XSA9IG51bGw7XG4gICAgICBkZWxldGUgbG9va3VwW2tleV07XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbW92ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBba2V5SW5TcG90LCBrZXlGb3JTcG90XSA9IG1vdmVzW2ldO1xuICAgICAgbGV0IGVsSW5TcG90ID0gbG9va3VwW2tleUluU3BvdF07XG4gICAgICBsZXQgZWxGb3JTcG90ID0gbG9va3VwW2tleUZvclNwb3RdO1xuICAgICAgbGV0IG1hcmtlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICBtdXRhdGVEb20oKCkgPT4ge1xuICAgICAgICBpZiAoIWVsRm9yU3BvdClcbiAgICAgICAgICB3YXJuKGB4LWZvciBcIjprZXlcIiBpcyB1bmRlZmluZWQgb3IgaW52YWxpZGAsIHRlbXBsYXRlRWwpO1xuICAgICAgICBlbEZvclNwb3QuYWZ0ZXIobWFya2VyKTtcbiAgICAgICAgZWxJblNwb3QuYWZ0ZXIoZWxGb3JTcG90KTtcbiAgICAgICAgZWxGb3JTcG90Ll94X2N1cnJlbnRJZkVsICYmIGVsRm9yU3BvdC5hZnRlcihlbEZvclNwb3QuX3hfY3VycmVudElmRWwpO1xuICAgICAgICBtYXJrZXIuYmVmb3JlKGVsSW5TcG90KTtcbiAgICAgICAgZWxJblNwb3QuX3hfY3VycmVudElmRWwgJiYgZWxJblNwb3QuYWZ0ZXIoZWxJblNwb3QuX3hfY3VycmVudElmRWwpO1xuICAgICAgICBtYXJrZXIucmVtb3ZlKCk7XG4gICAgICB9KTtcbiAgICAgIGVsRm9yU3BvdC5feF9yZWZyZXNoWEZvclNjb3BlKHNjb3Blc1trZXlzLmluZGV4T2Yoa2V5Rm9yU3BvdCldKTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhZGRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgW2xhc3RLZXkyLCBpbmRleF0gPSBhZGRzW2ldO1xuICAgICAgbGV0IGxhc3RFbCA9IGxhc3RLZXkyID09PSBcInRlbXBsYXRlXCIgPyB0ZW1wbGF0ZUVsIDogbG9va3VwW2xhc3RLZXkyXTtcbiAgICAgIGlmIChsYXN0RWwuX3hfY3VycmVudElmRWwpXG4gICAgICAgIGxhc3RFbCA9IGxhc3RFbC5feF9jdXJyZW50SWZFbDtcbiAgICAgIGxldCBzY29wZTIgPSBzY29wZXNbaW5kZXhdO1xuICAgICAgbGV0IGtleSA9IGtleXNbaW5kZXhdO1xuICAgICAgbGV0IGNsb25lMiA9IGRvY3VtZW50LmltcG9ydE5vZGUodGVtcGxhdGVFbC5jb250ZW50LCB0cnVlKS5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICAgIGxldCByZWFjdGl2ZVNjb3BlID0gcmVhY3RpdmUoc2NvcGUyKTtcbiAgICAgIGFkZFNjb3BlVG9Ob2RlKGNsb25lMiwgcmVhY3RpdmVTY29wZSwgdGVtcGxhdGVFbCk7XG4gICAgICBjbG9uZTIuX3hfcmVmcmVzaFhGb3JTY29wZSA9IChuZXdTY29wZSkgPT4ge1xuICAgICAgICBPYmplY3QuZW50cmllcyhuZXdTY29wZSkuZm9yRWFjaCgoW2tleTIsIHZhbHVlXSkgPT4ge1xuICAgICAgICAgIHJlYWN0aXZlU2NvcGVba2V5Ml0gPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgICAgbXV0YXRlRG9tKCgpID0+IHtcbiAgICAgICAgbGFzdEVsLmFmdGVyKGNsb25lMik7XG4gICAgICAgIGluaXRUcmVlKGNsb25lMik7XG4gICAgICB9KTtcbiAgICAgIGlmICh0eXBlb2Yga2V5ID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIHdhcm4oXCJ4LWZvciBrZXkgY2Fubm90IGJlIGFuIG9iamVjdCwgaXQgbXVzdCBiZSBhIHN0cmluZyBvciBhbiBpbnRlZ2VyXCIsIHRlbXBsYXRlRWwpO1xuICAgICAgfVxuICAgICAgbG9va3VwW2tleV0gPSBjbG9uZTI7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxvb2t1cFtzYW1lc1tpXV0uX3hfcmVmcmVzaFhGb3JTY29wZShzY29wZXNba2V5cy5pbmRleE9mKHNhbWVzW2ldKV0pO1xuICAgIH1cbiAgICB0ZW1wbGF0ZUVsLl94X3ByZXZLZXlzID0ga2V5cztcbiAgfSk7XG59XG5mdW5jdGlvbiBwYXJzZUZvckV4cHJlc3Npb24oZXhwcmVzc2lvbikge1xuICBsZXQgZm9ySXRlcmF0b3JSRSA9IC8sKFteLFxcfVxcXV0qKSg/OiwoW14sXFx9XFxdXSopKT8kLztcbiAgbGV0IHN0cmlwUGFyZW5zUkUgPSAvXlxccypcXCh8XFwpXFxzKiQvZztcbiAgbGV0IGZvckFsaWFzUkUgPSAvKFtcXHNcXFNdKj8pXFxzKyg/OmlufG9mKVxccysoW1xcc1xcU10qKS87XG4gIGxldCBpbk1hdGNoID0gZXhwcmVzc2lvbi5tYXRjaChmb3JBbGlhc1JFKTtcbiAgaWYgKCFpbk1hdGNoKVxuICAgIHJldHVybjtcbiAgbGV0IHJlcyA9IHt9O1xuICByZXMuaXRlbXMgPSBpbk1hdGNoWzJdLnRyaW0oKTtcbiAgbGV0IGl0ZW0gPSBpbk1hdGNoWzFdLnJlcGxhY2Uoc3RyaXBQYXJlbnNSRSwgXCJcIikudHJpbSgpO1xuICBsZXQgaXRlcmF0b3JNYXRjaCA9IGl0ZW0ubWF0Y2goZm9ySXRlcmF0b3JSRSk7XG4gIGlmIChpdGVyYXRvck1hdGNoKSB7XG4gICAgcmVzLml0ZW0gPSBpdGVtLnJlcGxhY2UoZm9ySXRlcmF0b3JSRSwgXCJcIikudHJpbSgpO1xuICAgIHJlcy5pbmRleCA9IGl0ZXJhdG9yTWF0Y2hbMV0udHJpbSgpO1xuICAgIGlmIChpdGVyYXRvck1hdGNoWzJdKSB7XG4gICAgICByZXMuY29sbGVjdGlvbiA9IGl0ZXJhdG9yTWF0Y2hbMl0udHJpbSgpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXMuaXRlbSA9IGl0ZW07XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmZ1bmN0aW9uIGdldEl0ZXJhdGlvblNjb3BlVmFyaWFibGVzKGl0ZXJhdG9yTmFtZXMsIGl0ZW0sIGluZGV4LCBpdGVtcykge1xuICBsZXQgc2NvcGVWYXJpYWJsZXMgPSB7fTtcbiAgaWYgKC9eXFxbLipcXF0kLy50ZXN0KGl0ZXJhdG9yTmFtZXMuaXRlbSkgJiYgQXJyYXkuaXNBcnJheShpdGVtKSkge1xuICAgIGxldCBuYW1lcyA9IGl0ZXJhdG9yTmFtZXMuaXRlbS5yZXBsYWNlKFwiW1wiLCBcIlwiKS5yZXBsYWNlKFwiXVwiLCBcIlwiKS5zcGxpdChcIixcIikubWFwKChpKSA9PiBpLnRyaW0oKSk7XG4gICAgbmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgc2NvcGVWYXJpYWJsZXNbbmFtZV0gPSBpdGVtW2ldO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKC9eXFx7LipcXH0kLy50ZXN0KGl0ZXJhdG9yTmFtZXMuaXRlbSkgJiYgIUFycmF5LmlzQXJyYXkoaXRlbSkgJiYgdHlwZW9mIGl0ZW0gPT09IFwib2JqZWN0XCIpIHtcbiAgICBsZXQgbmFtZXMgPSBpdGVyYXRvck5hbWVzLml0ZW0ucmVwbGFjZShcIntcIiwgXCJcIikucmVwbGFjZShcIn1cIiwgXCJcIikuc3BsaXQoXCIsXCIpLm1hcCgoaSkgPT4gaS50cmltKCkpO1xuICAgIG5hbWVzLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgIHNjb3BlVmFyaWFibGVzW25hbWVdID0gaXRlbVtuYW1lXTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBzY29wZVZhcmlhYmxlc1tpdGVyYXRvck5hbWVzLml0ZW1dID0gaXRlbTtcbiAgfVxuICBpZiAoaXRlcmF0b3JOYW1lcy5pbmRleClcbiAgICBzY29wZVZhcmlhYmxlc1tpdGVyYXRvck5hbWVzLmluZGV4XSA9IGluZGV4O1xuICBpZiAoaXRlcmF0b3JOYW1lcy5jb2xsZWN0aW9uKVxuICAgIHNjb3BlVmFyaWFibGVzW2l0ZXJhdG9yTmFtZXMuY29sbGVjdGlvbl0gPSBpdGVtcztcbiAgcmV0dXJuIHNjb3BlVmFyaWFibGVzO1xufVxuZnVuY3Rpb24gaXNOdW1lcmljMyhzdWJqZWN0KSB7XG4gIHJldHVybiAhQXJyYXkuaXNBcnJheShzdWJqZWN0KSAmJiAhaXNOYU4oc3ViamVjdCk7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtcmVmLmpzXG5mdW5jdGlvbiBoYW5kbGVyMygpIHtcbn1cbmhhbmRsZXIzLmlubGluZSA9IChlbCwge2V4cHJlc3Npb259LCB7Y2xlYW51cDogY2xlYW51cDJ9KSA9PiB7XG4gIGxldCByb290ID0gY2xvc2VzdFJvb3QoZWwpO1xuICBpZiAoIXJvb3QuX3hfcmVmcylcbiAgICByb290Ll94X3JlZnMgPSB7fTtcbiAgcm9vdC5feF9yZWZzW2V4cHJlc3Npb25dID0gZWw7XG4gIGNsZWFudXAyKCgpID0+IGRlbGV0ZSByb290Ll94X3JlZnNbZXhwcmVzc2lvbl0pO1xufTtcbmRpcmVjdGl2ZShcInJlZlwiLCBoYW5kbGVyMyk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtaWYuanNcbmRpcmVjdGl2ZShcImlmXCIsIChlbCwge2V4cHJlc3Npb259LCB7ZWZmZWN0OiBlZmZlY3QzLCBjbGVhbnVwOiBjbGVhbnVwMn0pID0+IHtcbiAgbGV0IGV2YWx1YXRlMiA9IGV2YWx1YXRlTGF0ZXIoZWwsIGV4cHJlc3Npb24pO1xuICBsZXQgc2hvdyA9ICgpID0+IHtcbiAgICBpZiAoZWwuX3hfY3VycmVudElmRWwpXG4gICAgICByZXR1cm4gZWwuX3hfY3VycmVudElmRWw7XG4gICAgbGV0IGNsb25lMiA9IGVsLmNvbnRlbnQuY2xvbmVOb2RlKHRydWUpLmZpcnN0RWxlbWVudENoaWxkO1xuICAgIGFkZFNjb3BlVG9Ob2RlKGNsb25lMiwge30sIGVsKTtcbiAgICBtdXRhdGVEb20oKCkgPT4ge1xuICAgICAgZWwuYWZ0ZXIoY2xvbmUyKTtcbiAgICAgIGluaXRUcmVlKGNsb25lMik7XG4gICAgfSk7XG4gICAgZWwuX3hfY3VycmVudElmRWwgPSBjbG9uZTI7XG4gICAgZWwuX3hfdW5kb0lmID0gKCkgPT4ge1xuICAgICAgd2FsayhjbG9uZTIsIChub2RlKSA9PiB7XG4gICAgICAgIGlmICghIW5vZGUuX3hfZWZmZWN0cykge1xuICAgICAgICAgIG5vZGUuX3hfZWZmZWN0cy5mb3JFYWNoKGRlcXVldWVKb2IpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGNsb25lMi5yZW1vdmUoKTtcbiAgICAgIGRlbGV0ZSBlbC5feF9jdXJyZW50SWZFbDtcbiAgICB9O1xuICAgIHJldHVybi
1BjbG9uZTI7XG4gIH07XG4gIGxldCBoaWRlID0gKCkgPT4ge1xuICAgIGlmICghZWwuX3hfdW5kb0lmKVxuICAgICAgcmV0dXJuO1xuICAgIGVsLl94X3VuZG9JZigpO1xuICAgIGRlbGV0ZSBlbC5feF91bmRvSWY7XG4gIH07XG4gIGVmZmVjdDMoKCkgPT4gZXZhbHVhdGUyKCh2YWx1ZSkgPT4ge1xuICAgIHZhbHVlID8gc2hvdygpIDogaGlkZSgpO1xuICB9KSk7XG4gIGNsZWFudXAyKCgpID0+IGVsLl94X3VuZG9JZiAmJiBlbC5feF91bmRvSWYoKSk7XG59KTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC1pZC5qc1xuZGlyZWN0aXZlKFwiaWRcIiwgKGVsLCB7ZXhwcmVzc2lvbn0sIHtldmFsdWF0ZTogZXZhbHVhdGUyfSkgPT4ge1xuICBsZXQgbmFtZXMgPSBldmFsdWF0ZTIoZXhwcmVzc2lvbik7XG4gIG5hbWVzLmZvckVhY2goKG5hbWUpID0+IHNldElkUm9vdChlbCwgbmFtZSkpO1xufSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtb24uanNcbm1hcEF0dHJpYnV0ZXMoc3RhcnRpbmdXaXRoKFwiQFwiLCBpbnRvKHByZWZpeChcIm9uOlwiKSkpKTtcbmRpcmVjdGl2ZShcIm9uXCIsIHNraXBEdXJpbmdDbG9uZSgoZWwsIHt2YWx1ZSwgbW9kaWZpZXJzLCBleHByZXNzaW9ufSwge2NsZWFudXA6IGNsZWFudXAyfSkgPT4ge1xuICBsZXQgZXZhbHVhdGUyID0gZXhwcmVzc2lvbiA/IGV2YWx1YXRlTGF0ZXIoZWwsIGV4cHJlc3Npb24pIDogKCkgPT4ge1xuICB9O1xuICBpZiAoZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcInRlbXBsYXRlXCIpIHtcbiAgICBpZiAoIWVsLl94X2ZvcndhcmRFdmVudHMpXG4gICAgICBlbC5feF9mb3J3YXJkRXZlbnRzID0gW107XG4gICAgaWYgKCFlbC5feF9mb3J3YXJkRXZlbnRzLmluY2x1ZGVzKHZhbHVlKSlcbiAgICAgIGVsLl94X2ZvcndhcmRFdmVudHMucHVzaCh2YWx1ZSk7XG4gIH1cbiAgbGV0IHJlbW92ZUxpc3RlbmVyID0gb24oZWwsIHZhbHVlLCBtb2RpZmllcnMsIChlKSA9PiB7XG4gICAgZXZhbHVhdGUyKCgpID0+IHtcbiAgICB9LCB7c2NvcGU6IHskZXZlbnQ6IGV9LCBwYXJhbXM6IFtlXX0pO1xuICB9KTtcbiAgY2xlYW51cDIoKCkgPT4gcmVtb3ZlTGlzdGVuZXIoKSk7XG59KSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL2luZGV4LmpzXG53YXJuTWlzc2luZ1BsdWdpbkRpcmVjdGl2ZShcIkNvbGxhcHNlXCIsIFwiY29sbGFwc2VcIiwgXCJjb2xsYXBzZVwiKTtcbndhcm5NaXNzaW5nUGx1Z2luRGlyZWN0aXZlKFwiSW50ZXJzZWN0XCIsIFwiaW50ZXJzZWN0XCIsIFwiaW50ZXJzZWN0XCIpO1xud2Fybk1pc3NpbmdQbHVnaW5EaXJlY3RpdmUoXCJGb2N1c1wiLCBcInRyYXBcIiwgXCJmb2N1c1wiKTtcbndhcm5NaXNzaW5nUGx1Z2luRGlyZWN0aXZlKFwiTWFza1wiLCBcIm1hc2tcIiwgXCJtYXNrXCIpO1xuZnVuY3Rpb24gd2Fybk1pc3NpbmdQbHVnaW5EaXJlY3RpdmUobmFtZSwgZGlyZWN0aXZlTmFtZTIsIHNsdWcpIHtcbiAgZGlyZWN0aXZlKGRpcmVjdGl2ZU5hbWUyLCAoZWwpID0+IHdhcm4oYFlvdSBjYW4ndCB1c2UgW3gtJHtkaXJlY3RpdmVOYW1lMn1dIHdpdGhvdXQgZmlyc3QgaW5zdGFsbGluZyB0aGUgXCIke25hbWV9XCIgcGx1Z2luIGhlcmU6IGh0dHBzOi8vYWxwaW5lanMuZGV2L3BsdWdpbnMvJHtzbHVnfWAsIGVsKSk7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9pbmRleC5qc1xuYWxwaW5lX2RlZmF1bHQuc2V0RXZhbHVhdG9yKG5vcm1hbEV2YWx1YXRvcik7XG5hbHBpbmVfZGVmYXVsdC5zZXRSZWFjdGl2aXR5RW5naW5lKHtyZWFjdGl2ZTogcmVhY3RpdmUyLCBlZmZlY3Q6IGVmZmVjdDIsIHJlbGVhc2U6IHN0b3AsIHJhdzogdG9SYXd9KTtcbnZhciBzcmNfZGVmYXVsdCA9IGFscGluZV9kZWZhdWx0O1xuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9idWlsZHMvbW9kdWxlLmpzXG52YXIgbW9kdWxlX2RlZmF1bHQgPSBzcmNfZGVmYXVsdDtcbmV4cG9ydCB7XG4gIG1vZHVsZV9kZWZhdWx0IGFzIGRlZmF1bHRcbn07XG4iLCIvLyBJbXBvcnQgZGVwZW5kZW5jaWVzXG4vL1xuLy8gSWYgeW91IG5vIGxvbmdlciB3YW50IHRvIHVzZSBhIGRlcGVuZGVuY3ksIHJlbWVtYmVyXG4vLyB0byBhbHNvIHJlbW92ZSBpdHMgcGF0aCBmcm9tIFwiY29uZmlnLnBhdGhzLndhdGNoZWRcIi5cbmltcG9ydCBjc3MgZnJvbSBcIi4uL2Nzcy9hcHAuc2Nzc1wiXG5cbmltcG9ydCB7dmlzaWJsZSwgbW9zdHJhciwgb2N1bHRhciwgbWVkaWRhc30gZnJvbSBcIi4vYmFzaWNvc1wiXG5pbXBvcnQgXCJwaG9lbml4X2h0bWxcIlxuaW1wb3J0IFwiLi4vdmVuZG9yL2pxdWVyeS5zbHVnZ2VyXCJcbmltcG9ydCBcIi4vcHVibGlcIlxuaW1wb3J0IHtjYW1iaW9fYXBhbmhvc30gZnJvbSBcIi4vcHVibGlcIlxuaW1wb3J0IFwiLi9mb3JtdWxhcmlvc1wiXG4vL2ltcG9ydCBwb3N0c2NyaWJlIGZyb20gJ3Bvc3RzY3JpYmUnXG5pbXBvcnQgcG9zdHNjcmliZSBmcm9tICcuLi92ZW5kb3IvcG9zdHNjcmliZS5taW4nXG4vL2ltcG9ydCBwb3N0Y3JpYmUgZnJvbSAnLi4vdmVuZG9yL3Bvc3RzY3JpYmUnXG4vL2ltcG9ydCBzb2NrZXQgZnJvbSBcIi4vc29ja2V0XCJcbmltcG9ydCB7U29ja2V0fSBmcm9tIFwicGhvZW5peFwiXG5pbXBvcnQgTlByb2dyZXNzIGZyb20gXCJucHJvZ3Jlc3NcIlxuaW1wb3J0IHtMaXZlU29ja2V0fSBmcm9tIFwicGhvZW5peF9saXZlX3ZpZXdcIlxuXG5pbXBvcnQgTGl2ZVNlbGVjdCBmcm9tIFwibGl2ZV9zZWxlY3RcIlxuXG5jb25zdCB1c2VyQWdlbnQgPSBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCk7XG5jb25zdCBodW1hbiA9IHVzZXJBZ2VudC5pbmNsdWRlcyhcImJvdFwiKSA/IGZhbHNlIDogdHJ1ZSBcblxuLy9pbXBvcnQgJ2FscGluZWpzJztcbmltcG9ydCBBbHBpbmUgZnJvbSAnYWxwaW5lanMnXG53aW5kb3cuQWxwaW5lID0gQWxwaW5lXG5BbHBpbmUuc3RhcnQoKVxuXG5sZXQgY3NyZlRva2VuID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIm1ldGFbbmFtZT0nY3NyZi10b2tlbiddXCIpLmdldEF0dHJpYnV0ZShcImNvbnRlbn
1RcIilcblxuLy8gTk9USUZJQ0FDSU9ORVMgLy9cblxuY29uc3QgYXBwbGljYXRpb25TZXJ2ZXJQdWJsaWNLZXkgPSBcIkJHMkZ2YVd1cmxDWFhleUVONlIwbXVRdWhyQmdpbWk3UXZOamNGSU9vQ045d3llUUpOeFNrRmx1bkF2NjJXc1c3MkpwZURnYkxsRnlWOFA2Wm9ndkVBVVwiXG5cbmxldCBwdXNoQnV0dG9uID0gbnVsbDtcbmxldCBjYW5hbGVzRGl2ID0gbnVsbDtcblxubGV0IGlzU3Vic2NyaWJlZCA9IGZhbHNlO1xubGV0IHN3UmVnaXN0cmF0aW9uID0gbnVsbDtcblxuZnVuY3Rpb24gdXJsQjY0VG9VaW50OEFycmF5KGJhc2U2NFN0cmluZykge1xuICBjb25zdCBwYWRkaW5nID0gJz0nLnJlcGVhdCgoNCAtIGJhc2U2NFN0cmluZy5sZW5ndGggJSA0KSAlIDQpO1xuICBjb25zdCBiYXNlNjQgPSAoYmFzZTY0U3RyaW5nICsgcGFkZGluZylcbiAgICAucmVwbGFjZSgvXFwtL2csICcrJylcbiAgICAucmVwbGFjZSgvXy9nLCAnLycpO1xuXG4gIGNvbnN0IHJhd0RhdGEgPSB3aW5kb3cuYXRvYihiYXNlNjQpO1xuICBjb25zdCBvdXRwdXRBcnJheSA9IG5ldyBVaW50OEFycmF5KHJhd0RhdGEubGVuZ3RoKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHJhd0RhdGEubGVuZ3RoOyArK2kpIHtcbiAgICBvdXRwdXRBcnJheVtpXSA9IHJhd0RhdGEuY2hhckNvZGVBdChpKTtcbiAgfVxuICByZXR1cm4gb3V0cHV0QXJyYXk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUJ0bigpIHtcbiAgaWYgKE5vdGlmaWNhdGlvbi5wZXJtaXNzaW9uID09PSAnZGVuaWVkJykge1xuICAgIHB1c2hCdXR0b24udGV4dENvbnRlbnQgPSAnTm90aWZpY2FjaW9uZXMgUHVzaCBCbG9xdWVhZGFzLic7XG4gICAgcHVzaEJ1dHRvbi5kaXNhYmxlZCA9IHRydWU7XG4gICAgdXBkYXRlU3Vic2NyaXB0aW9uT25TZXJ2ZXIobnVsbCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGlzU3Vic2NyaWJlZCkge1xuICAgIHB1c2hCdXR0b24udGV4dENvbnRlbnQgPSAnRGVzYWN0aXZhciBOb3RpZmljYWNpb25lcyBQdXNoJztcbiAgfSBlbHNlIHtcbiAgICBwdXNoQnV0dG9uLnRleHRDb250ZW50ID0gJ0FjdGl2YXIgTm90aWZpY2FjaW9uZXMgUHVzaCc7XG4gIH1cblxuICBwdXNoQnV0dG9uLmRpc2FibGVkID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN1YnNjcmlwdGlvbk9uU2VydmVyKHN1YnNjcmlwdGlvbiwgaW5pY2lhbCkge1xuICB2YXIgY2FuYWxlcyA9IHJhZGlvQ2FuYWxlcygpO1xuICAgIGlmIChpbmljaWFsKSAge1xuICAgIGNhbmFsZXMgPSBbXCJwZXRpY2lvbl9pbmljaWFsXCJdOyBcbiAgICB9XG4gIGlmIChzdWJzY3JpcHRpb24pIHtcbiAgICBzZW5kU3Vic2NyaXB0aW9uVG9CYWNrRW5kKHN1YnNjcmlwdGlvbiwgY2FuYWxlcylcbiAgfVxuICBcbiAgY29uc3Qgc3Vic2NyaXB0aW9uSnNvbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5qcy1zdWJzY3JpcHRpb24tanNvbicpO1xuICBjb25zdCBzdWJzY3JpcHRpb25EZXRhaWxzID1cbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtc3Vic2NyaXB0aW9uLWRldGFpbHMnKTtcblxuICBpZiAoc3Vic2NyaXB0aW9uKSB7XG4gICAgc3Vic2NyaXB0aW9uSnNvbi50ZXh0Q29udGVudCA9IEpTT04uc3RyaW5naWZ5KHN1YnNjcmlwdGlvbik7XG4gICAgc3Vic2NyaXB0aW9uRGV0YWlscy5jbGFzc0xpc3QucmVtb3ZlKCdpcy1pbnZpc2libGUnKTtcbiAgfSBlbHNlIHtcbiAgICBzdWJzY3JpcHRpb25EZXRhaWxzLmNsYXNzTGlzdC5hZGQoJ2lzLWludmlzaWJsZScpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN1YnNjcmliZVVzZXIoKSB7XG4gIGNvbnN0IGFwcGxpY2F0aW9uU2VydmVyS2V5ID0gdXJsQjY0VG9VaW50OEFycmF5KGFwcGxpY2F0aW9uU2VydmVydWJsaWNLZXkpO1xuICBzd1JlZ2lzdHJhdGlvbi5wdXNoTWFuYWdlci5zdWJzY3JpYmUoe1xuICAgIHVzZXJWaXNpYmxlT25seTogdHJ1ZSxcbiAgICBhcHBsaWNhdGlvblNlcnZlcktleTogYXBwbGljYXRpb25TZXJ2ZXJLZXlcbiAgfSlcbiAgLnRoZW4oZnVuY3Rpb24oc3Vic2NyaXB0aW9uKSB7XG4gICAgdXBkYXRlU3Vic2NyaXB0aW9uT25TZXJ2ZXIoc3Vic2NyaXB0aW9uKTtcbiAgICBpc1N1YnNjcmliZWQgPSB0cnVlO1xuICAgIHVwZGF0ZUJ0bigpO1xuICB9KVxuICAuY2F0Y2goZnVuY3Rpb24oZXJyKSB7XG4gICAgdXBkYXRlQnRuKCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiB1bnN1YnNjcmliZVVzZXIoKSB7XG4gIHN3UmVnaXN0cmF0aW9uLnB1c2hNYW5hZ2VyLmdldFN1YnNjcmlwdGlvbigpXG4gIC50aGVuKGZ1bmN0aW9uKHN1YnNjcmlwdGlvbikge1xuICAgIGlmIChzdWJzY3JpcHRpb24pIHtcbiAgICAgIGRlbGV0ZVN1YnNjcmlwdGlvbkJhY2tFbmQoc3Vic2NyaXB0aW9uKTtcbiAgICAgIHJldHVybiBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH0pXG4gIC5jYXRjaChmdW5jdGlvbihlcnJvcikge1xuICAgIGNvbnNvbGUubG9nKCdFcnJvciB1bnN1YnNjcmliaW5nJywgZXJyb3IpO1xuICB9KVxuICAudGhlbihmdW5jdGlvbihzdWJzY3JpcHRpb24pIHtcbiAgICB1cGRhdGVTdWJzY3JpcHRpb25PblNlcnZlcihudWxsKTtcblxuICAgIGNvbnNvbGUubG9nKCdVc2VyIGlzIHVuc3Vic2NyaWJlZC4nKTtcbiAgICBpc1N1YnNjcmliZWQgPSBmYWxzZTtcblxuICAgIHVwZGF0ZUJ0bigpO1xuICAgIC8vdXBkYXRlQ2FuYWxlcyhbXSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBpbml0aWFsaXplTm90aWZpY2F0aW9uc1VJKGhvb2spIHtcbiAgcHVzaEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgIHB1c2hCdXR0b24uZGlzYWJsZWQgPSB0cnVlO1xuICAgIGlmIChpc1N1YnNjcmliZWQpIHtcbiAgICAgIGhvb2sucHVzaEV2ZW50KFwic3VzY3JpdG9cIiwge1wic3VzY3JpdG9cIjogXCJzdXNjcml0b1wifSlcbiAgICAgIHVuc3Vic2NyaWJlVXNlcigpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIGhvb2sucHVzaEV2ZW50KFwic3VzY3JpdG9cIiwge1wic3VzY3JpdG9cIjogXCJub19zdXNjcml0b1wifSlcbiAgICAgIHN1YnNjcmliZVVzZXIoKTtcbiAgICB9XG4gI
1H0pO1xuXG4gIC8vIFNldCB0aGUgaW5pdGlhbCBzdWJzY3JpcHRpb24gdmFsdWVcbiAgc3dSZWdpc3RyYXRpb24ucHVzaE1hbmFnZXIuZ2V0U3Vic2NyaXB0aW9uKClcbiAgLnRoZW4oZnVuY3Rpb24oc3Vic2NyaXB0aW9uKSB7XG4gICAgaXNTdWJzY3JpYmVkID0gIShzdWJzY3JpcHRpb24gPT09IG51bGwpO1xuXG4gICAgdXBkYXRlU3Vic2NyaXB0aW9uT25TZXJ2ZXIoc3Vic2NyaXB0aW9uLCBcImluaWNpYWxcIik7XG5cbiAgICB1cGRhdGVCdG4oKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHNlbmRTdWJzY3JpcHRpb25Ub0JhY2tFbmQoc3Vic2NyaXB0aW9uLCBjYW5hbGVzKSB7XG4gIHN1YnNjcmlwdGlvbiA9IHtcInN1c2NyaXBjaW9uX3B1c2hcIjogc3Vic2NyaXB0aW9uLCBcImNhbmFsZXNcIjogY2FuYWxlc31cbiAgcmV0dXJuIGZldGNoKCcvYXBpL3N1c2NyaXBjaW9uZXNwdXNoLycsIHtcbiAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICBoZWFkZXJzOiB7XG4gICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgIH0sXG4gICAgYm9keTogSlNPTi5zdHJpbmdpZnkoc3Vic2NyaXB0aW9uKSxcbiAgfSlcbiAgICAudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdCYWQgc3RhdHVzIGNvZGUgZnJvbSBzZXJ2ZXIuJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xuICAgIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKHJlc3BvbnNlRGF0YSkge1xuICAgICAgaWYgKCEocmVzcG9uc2VEYXRhLmRhdGEgJiYgcmVzcG9uc2VEYXRhLmRhdGEuc3VjY2VzcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdCYWQgcmVzcG9uc2UgZnJvbSBzZXJ2ZXIuJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZURhdGEuZGF0YSk7XG4gICAgICB1cGRhdGVDYW5hbGVzKHJlc3BvbnNlRGF0YS5kYXRhW1wiY2FuYWxlc1wiXSwgcmVzcG9uc2VEYXRhLmRhdGFbXCJzdXNjcmlwY2lvbmVzXCJdKTtcbiAgICAgIH1cbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gZGVsZXRlU3Vic2NyaXB0aW9uQmFja0VuZChzdWJzY3JpcHRpb24pIHtcbiAgY29uc3QgZW5kcG9pbnQgPSBlbmNvZGVVUklDb21wb25lbnQoc3Vic2NyaXB0aW9uLmVuZHBvaW50KVxuICByZXR1cm4gZmV0Y2goJy9hcGkvc3VzY3JpcGNpb25lc3B1c2gvJyArIGVuZHBvaW50LCB7XG4gICAgbWV0aG9kOiAnREVMRVRFJyxcbiAgICBoZWFkZXJzOiB7XG4gICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgIH1cbiAgfSlcbiAgICAudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdCYWQgc3RhdHVzIGNvZGUgZnJvbSBzZXJ2ZXIuJyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgfSlcbiAgICAudGhlbihmdW5jdGlvbiAocmVzcG9uc2VEYXRhKSB7XG4gICAgICBpZiAoIShyZXNwb25zZURhdGEuZGF0YSAmJiByZXNwb25zZURhdGEuZGF0YS5zdWNjZXNzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JhZCByZXNwb25zZSBmcm9tIHNlcnZlci4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICB1cGRhdGVDYW5hbGVzKFtdKTtcbiAgICAgIH1cbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlQ2FuYWxlcyhjYW5hbGVzLCBjYW5hbGVzX2FjdGl2b3MpIHtcbiAgY2FuYWxlc0Rpdi5pbm5lckhUTUwgPSBcIlwiO1xuICBmb3IgKGNvbnN0IGNhbmFsIG9mIGNhbmFsZXMpIHtcbiAgICAgY3JlYXRlQ2FuYWwoY2FuYWwsIGNhbmFsZXNfYWN0aXZvcyk7XG4gIH1cbn0gXG5cbmZ1bmN0aW9uIGNyZWF0ZUNhbmFsKGNhbmFsLCBjYW5hbGVzX2FjdGl2b3MpIHtcbiAgdmFyIGFjdGl2byA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IGNhbmFsX2FjdGl2byBvZiBjYW5hbGVzX2FjdGl2b3MpIHsgXG4gICAgaWYgKGNhbmFsX2FjdGl2byA9PSBjYW5hbC5pZCkgeyBcbiAgICAgIHZhciBhY3Rpdm8gPSB0cnVlOyBcbiAgICB9XG4gIH1cblxuICB2YXIgY2hlY2tlZCA9IFwiXCI7XG4gIGlmIChhY3Rpdm8pIHsgY2hlY2tlZCA9IFwiY2hlY2tlZFwiOyB9XG5cbiAgdmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgdmFyIGxhYmVsX2wgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsYWJlbCcpO1xuICBsYWJlbF9sLmh0bWxGb3IgPSBjYW5hbC5pZDtcbiAgbGFiZWxfbC5pbm5lckhUTUwgPSBjYW5hbC5ub21icmU7ICAgIFxuICBkaXYuYXBwZW5kQ2hpbGQobGFiZWxfbCk7XG5cbiAgdmFyIHNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcbiAgc3Bhbi5jbGFzc0xpc3QuYWRkKCdja2J4LXN0eWxlLTEnKVxuXG4gIHZhciBidXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gIGJ1dHRvbi50eXBlID0gXCJjaGVja2JveFwiO1xuICBidXR0b24udmFsdWUgPSBjYW5hbC5pZDtcbiAgYnV0dG9uLmlkID0gY2FuYWwuaWQ7XG4gIGJ1dHRvbi5jaGVja2VkID0gY2hlY2tlZDtcbiAgc3Bhbi5hcHBlbmRDaGlsZChidXR0b24pO1xuXG4gIHZhciBsYWJlbF9jID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgbGFiZWxfYy5odG1sRm9yID0gY2FuYWwuaWQ7XG4gIHNwYW4uYXBwZW5kQ2hpbGQobGFiZWxfYyk7XG4gIGRpdi5hcHBlbmRDaGlsZChzcGFuKTtcblxuICBjYW5hbGVzRGl2LmFwcGVuZENoaWxkKGRpdik7XG5cbiAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIChldmVudCkgPT4ge1xuICBzdWJzY3JpYmVVc2VyKClcbiAgfSlcbn1cblxuZnVuY3Rpb24gcmFkaW9DYW5hbGVzKCkge1xuICBsZXQgYWN0aXZhZG9zID0gW107XG4gIGxldCBjaGVja2JveGVzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnaW5wdXQ6Y2hlY2tlZCcpO1xuICBjaGVja2JveGVzLmZvckVhY2goKGNoZWNrYm94KSA9PiB7XG4gICAgYWN0aXZhZG9zLnB1c2goY2hlY2tib3gudmFsdWUpO1xuICB9KTtcbiAgcmV0dXJuIGFjdGl2YWRvcztcbn1cblxuZnVuY3Rpb24gaGFuZGxlQ29ubmVjdGlvbigpIHtcbiAgaWYgKG5hdmlnYXRvci5vbkxpbmUpIHtcbiAgICBpc1JlYWNoYWJsZShnZXRTZXJ2ZXJVcmwoKSkudGhlbihmdW5jdGlvbihvbmxpbmUpIHtcbiAgICAgIGlmIChvbmxpbmUpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ29ubGluZScpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coJ25vIGNvbm5lY3Rpdml0eScpO1xuICAgICAgfVxuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUubG9nKCdvZmZsaW5lJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNSZWFjaGFibGUodXJsKSB7XG4gIHJldHVybi
1BmZXRjaCh1cmwsIHsgbWV0aG9kOiAnSEVBRCcsIG1vZGU6ICduby1jb3JzJyB9KVxuICAgIC50aGVuKGZ1bmN0aW9uKHJlc3ApIHtcbiAgICAgIHJldHVybiByZXNwICYmIChyZXNwLm9rIHx8IHJlc3AudHlwZSA9PT0gJ29wYXF1ZScpO1xuICAgIH0pXG4gICAgLmNhdGNoKGZ1bmN0aW9uKGVycikge1xuICAgICAgY29uc29sZS53YXJuKCdbY29ubiB0ZXN0IGZhaWx1cmVdOicsIGVycik7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldFNlcnZlclVybCgpIHtcbiAgcmV0dXJuICB3aW5kb3cubG9jYXRpb24ub3JpZ2luO1xufVxuXG4vLyBGSU4gTk9USUZJQ0FDSU9ORVNcblxuY29uc3Qgc3VtbWVyTm90ZU1pbiA9IHtcbiAgc3R5bGVXaXRoU3BhbjogZmFsc2UsXG4gIGxhbmc6ICdlcy1FUycsXG4gIGhlaWdodDogNDAwLFxuICBkaWFsb2dzRmFkZTogdHJ1ZSAgLFxuICB0b29sYmFyOiBbXG4gICAgWydzdHlsZScsIFsnaXRhbGljJywgJ3VuZGVybGluZScsICdjbGVhciddXSxcbiAgICBbJ2luc2VydCcsIFsnbGluaycsICd1bmxpbmsnXV0sXG4gIF0sXG4gIGNsZWFuZXI6e1xuICAgIG5vdFRpbWU6IDUwMCwgLy8gVGltZSB0byBkaXNwbGF5IE5vdGlmaWNhdGlvbnMuXG4gICAgYWN0aW9uOiAnYm90aCcsIC8vIGJvdGh8YnV0dG9ufHBhc3RlICdidXR0b24nIG9ubHkgY2xlYW5zIHZpYSB0b29sYmFyIGJ1dHRvbiwgJ3Bhc3RlJyBvbmx5IGNsZWFuIHdoZW4gcGFzdGluZyBjb250ZW50LCBib3RoIGRvZXMgYm90aCBvcHRpb25zLlxuICAgIG5ld2xpbmU6ICc8YnI+JywgLy8gU3VtbWVybm90ZSdzIGRlZmF1bHQgaXMgdG8gdXNlICc8cD48YnI+PC9wPidcbiAgICBub3RTdHlsZTogJ3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO2xlZnQ6MDtyaWdodDowJywgLy8gUG9zaXRpb24gb2YgTm90aWZpY2F0aW9uXG4gICAgaWNvbjogJzxpIGNsYXNzPVwibm90ZS1pY29uXCI+W3hdPC9pPicsXG4gICAga2VlcEh0bWw6IHRydWUsIC8vIFJlbW92ZSBhbGwgSHRtbCBmb3JtYXRzXG4gICAga2VlcENsYXNzZXM6IGZhbHNlLCAvLyBSZW1vdmUgQ2xhc3Nlc1xuICAgIGtlZXBPbmx5VGFnczogWyc8YnI+JywnPGE+JywnPHA+J10sIC8vIElmIGtlZXBIdG1sIGlzIHRydWUsIHJlbW92ZSBhbGwgdGFncyBleGNlcHQgdGhlc2VcbiAgICBiYWRUYWdzOiBbJ3N0eWxlJywgJ3NjcmlwdCcsICdhcHBsZXQnLCAnZW1iZWQnLCAnbm9mcmFtZXMnLCAnbm9zY3JpcHQnLCAnaHRtbCddLCAvLyBSZW1vdmUgZnVsbCB0YWdzIHdpdGggY29udGVudHNcbiAgICBrZWVwVGFnQ29udGVudHM6IFsnc3BhbicsJ2ZvbnQnLCdzdHJvbmcnXSwgLy8gUmVtb3ZlIGZ1bGwgdGFncyB3aXRoIGNvbnRlbnRzXG4gICAgYmFkQXR0cmlidXRlczogWydkaXInLCdpZCcsJ3N0eWxlJywgJ3N0YXJ0JywnbmFtZScsJ2NsYXNzJywnYWxpZ24nLCdvbnRvdWNoc3RhcnQnLCdzaXplJywnZmFjZScsICdsYW5nJ10gLy8gUmVtb3ZlIGF0dHJpYnV0ZXMgZnJvbSByZW1haW5pbmcgdGFnc1xuICB9LFxufTtcbmNvbnN0IHN1bW1lck5vdGVDb25mID0ge1xuICBzdHlsZVdpdGhTcGFuOiBmYWxzZSxcbiAgbGFuZzogJ2VzLUVTJyxcbiAgaGVpZ2h0OiA0MDAsXG4gIGRpYWxvZ3NGYWRlOiB0cnVlICAsXG4gIHRvb2xiYXI6IFtcbiAgICBbJ3N0eWxlJywgWydib2xkJywgJ2l0YWxpYycsICd1bmRlcmxpbmUnLCAnY2xlYXInXV0sXG4gICAgWydmb250JywgWydzdHJpa2V0aHJvdWdoJywgJ3N1cGVyc2NyaXB0JywgJ3N1YnNjcmlwdCddXSxcbiAgICBbJ3BhcmEnLCBbJ3VsJywgJ29sJywgJ3BhcmFncmFwaCddXSxcbiAgICBbJ2xpbmsnLFsnc3R5bGUnXV0sXG4gICAgWydpbnNlcnQnLCBbJ2xpbmsnLCAndW5saW5rJ11dLFxuICAgIFsnc2FsdG8nLCBbJ2FydGljdWxvJywnZm90bycsJ2NvZGlnbycsJ2RvY3VtZW50bycsICdib3JyYXInXV0sXG4gICAgWyd2aWV3JyxbJ2NvZGV2aWV3J11dLFxuICAgIFsnaW5zZXJ0JywgWyd0ZW1wbGF0ZSddXVxuICBdLFxuICBwb3BvdmVyOiB7XG4gICAgaW1hZ2U6IFtcbiAgICAgIFsnY3VzdG9tJywgWydpbWFnZUF0dHJpYnV0ZXMnLCdjYXB0aW9uSXQnXV0sXG4gICAgICBbJ2ltYWdlc2l6ZScsIFsnaW1hZ2VTaXplMTAwJywgJ2ltYWdlU2l6ZTUwJywgJ2ltYWdlU2l6ZTI1J11dLFxuICAgICAgWydmbG9hdCcsIFsnZmxvYXRMZWZ0JywgJ2Zsb2F0UmlnaHQnLCAnZmxvYXROb25lJ11dLFxuICAgICAgWydyZW1vdmUnLCBbJ3JlbW92ZU1lZGlhJ11dXG4gICAgXSxcbiAgfSxcbiAgaW1hZ2VBdHRyaWJ1dGVzOntcbiAgICBpbWFnZURpYWxvZ0xheW91dDonZGVmYXVsdCcsIC8vIGRlZmF1bHR8aG9yaXpvbn
1RhbFxuICAgIGljb246JzxpIGNsYXNzPVwibm90ZS1pY29uLXBlbmNpbFwiLz4nLFxuICAgIHJlbW92ZUVtcHR5OmZhbHNlIC8vIHRydWUgPSByZW1vdmUgYXR0cmlidXRlcyB8IGZhbHNlID0gbGVhdmUgZW1wdHkgaWYgcHJlc2VudFxuICB9LFxuICBkaXNwbGF5RmllbGRzOntcbiAgICBpbWFnZUJhc2ljOnRydWUsICAvLyBzaG93L2hpZGUgVGl0bGUsIFNvdXJjZSwgQWx0IGZpZWxkc1xuICAgIGltYWdlRXh0cmE6dHJ1ZSwgLy8gc2hvdy9oaWRlIEFsdCwgQ2xhc3MsIFN0eWxlLCBSb2xlIGZpZWxkc1xuICAgIGxpbmtCYXNpYzp0cnVlLCAgIC8vIHNob3cvaGlkZSBVUkwgYW5kIFRhcmdldCBmaWVsZHMgZm9yIGxpbmtcbiAgICBsaW5rRXh0cmE6ZmFsc2UgICAvLyBzaG93L2hpZGUgQ2xhc3MsIFJlbCwgUm9sZSBmaWVsZHMgZm9yIGxpbmtcbiAgfSxcbiAgY2FwdGlvbkl0OntcbiAgICBpY29uOic8aSBjbGFzcz1cIm5vdGUtaWNvbi1wZW5jaWxcIn0vPicsIC8vIExlYXZlIGVtcHR5IG9yIGRvbid0IHNldCBmb3IgZGVmYXVsdCBJY29uLlxuICAgIGZpZ3VyZUNsYXNzOidmaWd1cmUtaW50ZXJuYScsXG4gICAgZmlnY2FwdGlvbkNsYXNzOidwaWUnLFxuICB9LFxuICBjbGVhbmVyOntcbiAgICBub3RUaW1lOiA1MDAsIC8vIFRpbWUgdG8gZGlzcGxheSBOb3RpZmljYXRpb25zLlxuICAgIGFjdGlvbjogJ2JvdGgnLCAvLyBib3RofGJ1dHRvbnxwYXN0ZSAnYnV0dG9uJyBvbmx5IGNsZWFucyB2aWEgdG9vbGJhciBidXR0b24sICdwYXN0ZScgb25seSBjbGVhbiB3aGVuIHBhc3RpbmcgY29udGVudCwgYm90aCBkb2VzIGJvdGggb3B0aW9ucy5cbiAgICBuZXdsaW5lOiAnPGJyPicsIC8vIFN1bW1lcm5vdGUncyBkZWZhdWx0IGlzIHRvIHVzZSAnPHA+PGJyPjwvcD4nXG4gICAgbm90U3R5bGU6ICdwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtsZWZ0OjA7cmlnaHQ6MCcsIC8vIFBvc2l0aW9uIG9mIE5vdGlmaWNhdGlvblxuICAgIGljb246ICc8aSBjbGFzcz1cIm5vdGUtaWNvblwiPlt4XTwvaT4nLFxuICAgIGtlZXBIdG1sOiB0cnVlLCAvLyBSZW1vdmUgYWxsIEh0bWwgZm9ybWF0c1xuICAgIGtlZXBDbGFzc2VzOiBmYWxzZSwgLy8gUmVtb3ZlIENsYXNzZXNcbiAgICBrZWVwT25seVRhZ3M6IFsnPGJyPicsJzxhPicsJzxwPiddLCAvLyBJZiBrZWVwSHRtbCBpcyB0cnVlLCByZW1vdmUgYWxsIHRhZ3MgZXhjZXB0IHRoZXNlXG4gICAgYmFkVGFnczogWydzdHlsZScsICdzY3JpcHQnLCAnYXBwbGV0JywgJ2VtYmVkJywgJ25vZnJhbWVzJywgJ25vc2NyaXB0JywgJ2h0bWwnXSwgLy8gUmVtb3ZlIGZ1bGwgdGFncyB3aXRoIGNvbnRlbnRzXG4gICAga2VlcFRhZ0NvbnRlbnRzOiBbJ3NwYW4nLCdmb250Jywnc3Ryb25nJ10sIC8vIFJlbW92ZSBmdWxsIHRhZ3Mgd2l0aCBjb250ZW50c1xuICAgIGJhZEF0dHJpYnV0ZXM6IFsnZGlyJywnaWQnLCdzdHlsZScsICdzdGFydCcsJ25hbWUnLCdjbGFzcycsJ2FsaWduJywnb250b3VjaHN0YXJ0Jywnc2l6ZScsJ2ZhY2UnLCAnbGFuZyddIC8vIFJlbW92ZSBhdHRyaWJ1dGVzIGZyb20gcmVtYWluaW5nIHRhZ3NcbiAgfSxcbiAgdGVtcGxhdGU6IHtcbiAgICBwYXRoOiAnL2pzL3N1bW1lcm5vdGUvdHBscycsXG4gICAgbGlzdDoge1xuICAgICAgJ3JlY3VhZHJvX2dlbmVyaWNvJzogJ1JlY3VhZHJvIGdlbsOpcmljbycsXG4gICAgICAncmVjdWFkcm9fZGNoYSc6ICdSZWN1YWRybyBkZXJlY2hvJyxcbiAgICAgICdyZWN1YWRyb19penEnOiAnUmVjdWFkcm8gaXpxdWllcmRvJyxcbiAgICAgICdyZWN1YWRybyc6ICdSZWN1YWRybyBcImFudGlndW9cIidcbiAgICB9XG4gIH1cbn07XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGh4OnF1aXRhci1ib2R5LW92ZXJmbG93c1wiLCAoZSkgPT4ge1xuICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYm9keVwiKS5jbGFzc0xpc3QucmVtb3ZlKFwib3ZlcmZsb3dcIik7XG59KVxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJhcnRpY3VsaXN0YTpsaW1waWFyX3VybFwiLCAoZSkgPT4ge1xuICBoaXN0b3J5LnJlcGxhY2VTdGF0ZSgnJywgZG9jdW1lbnQudGl0bGUsIHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNwbGl0KCcjJylbMF0pOyBcbn0pO1xud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJhcnRpY3VsaXN0YTptZW51XCIsIChlKSA9PiB7XG4gIHZhciB3ID0gd2luZG93LmlubmVyV2lkdGhcbiAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGhcbiAgICB8fCBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoO1xuICBpZiAodyA+IDc2OCAmJiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjbWVudS1idXItY29udGVuZWRvcicpKXtcbiAgICB2YXIgbWVudV9hZG1pbiA9IDA7XG4gICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNtZW51LWFkbWluJykpe1xuICAgICAgbWVudV9hZG1pbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNtZW51LWFkbWluJykub2Zmc2V0SGVpZ2h0O1xuICAgIH1cbiAgICB2YXIgcHVibGkgPSAwO1xuICAgIGlmICh2aXNpYmxlKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwdWJsaS1jYWJlY2VyYScpKSl7XG4gICAgICB2Y
1XIge2JvdHRvbX0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHVibGktY2FiZWNlcmEnKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgaWYgKGJvdHRvbSA+IDEpe1xuICAgICAgICBwdWJsaSA9IGJvdHRvbTtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIG1lbnVfYXJyaWJhID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI21lbnUtYXJyaWJhJykub2Zmc2V0SGVpZ2h0IC0gMTtcbiAgICB2YXIgYWJham8gPSBtZW51X2FycmliYSArIG1lbnVfYWRtaW4gKyBwdWJsaVxuXG4gICAgY29uc3QgbWVudV8xID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI21lbnUtYnVyLWNvbnRlbmVkb3InKTtcbiAgICBtZW51XzEuc3R5bGUudG9wID0gYCR7bWVudV9hcnJpYmF9cHhgO1xuICAgIG1lbnVfMS5zdHlsZS5oZWlnaHQgPSBgY2FsYygxMDB2aCAtICR7YWJham99cHgpYDtcblxuXG4gICAgY29uc3QgbWVudV9zZWNjaW9uZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubWVudS1zZWNjaW9uZXMnKTtcbiAgICBjb25zdCBtZW51X3NlY2Npb25lc19jb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIm1lbnUtc2VjY2lvbmVzLWVzY3JpdG9yaW9cIilcbiAgICBtZW51X3NlY2Npb25lc19jb250YWluZXIuYXBwZW5kQ2hpbGQobWVudV9zZWNjaW9uZXMpO1xuXG4gICAgY29uc3QgbWVudV9zZWNjaW9uZXNfaCA9IG1lbnVfc2VjY2lvbmVzLm9mZnNldEhlaWdodCAvIDI7XG4gICAgdmFyIHt0b3B9ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNlY2Npb25lcycpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG5cbiAgICBtZW51X3NlY2Npb25lc19jb250YWluZXIuc3R5bGUudG9wID0gYCR7dG9wIC0gKG1lbnVfc2VjY2lvbmVzX2gpfXB4YDtcblxuICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjbWVudS1wZXJzb25hbC1jb250ZW5lZG9yJykpe1xuICAgICAgY29uc3QgbWVudV8yID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI21lbnUtcGVyc29uYWwtY29udGVuZWRvcicpO1xuICAgICAgbWVudV8yLnN0eWxlLnRvcCA9IGAke21lbnVfYXJyaWJhfXB4YDtcbiAgICAgIG1lbnVfMi5zdHlsZS5oZWlnaHQgPSBgY2FsYygxMDB2aCAtICR7YWJham99cHgpYDtcbiAgICB9XG4gIH1cbiAgaWYgKHcgPCA3NjggJiYgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI21lbnUtYnVyLWNvbnRlbmVkb3InKSl7XG4gICAgY29uc3QgbWVudV9zZWNjaW9uZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubWVudS1zZWNjaW9uZXMnKTtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIm1lbnUtc2VjY2lvbmVzLW1vdmlsXCIpXG4gICAgICAuYXBwZW5kQ2hpbGQobWVudV9zZWNjaW9uZXMpO1xuICB9XG59KTtcblxuLy8gQmFzZSBBVURJT1MgXG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGh4OmNhbWJpYXItc2VsZWNjaW9uXCIsIChlKSA9PiB7XG4gIGlmIChhdWRpby5wYXVzZWQpIHtcbiAgICBsaXZlU29ja2V0Lmhvb2tzLkF1ZGlvUGxheWVyLmRhdG9zX2F1ZGlvKCk7IFxuICB9O1xufSlcbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGh4OnBsYXktc2VsZWNjaW9uXCIsIChlKSA9PiB7XG4gIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNlbGVjY2lvbmFyXCIpKSB7XG4gICAgbGl2ZVNvY2tldC5ob29rcy5BdWRpb1NlbGVjY2lvbmFyLm1vdW50ZWQoKTtcbiAgfVxuICBhdWRpb19vcmlnZW4gPSBcInJlY29tZW5kYWNpb25cIjtcbiAgbGl2ZVNvY2tldC5ob29rcy5BdWRpb1BsYXllci5hdWRpb19yZXByb2R1Y2lyKCk7IFxufSlcblxuZnVuY3Rpb24gc2VndW5kb3NfYV9zdHJpbmcocykge1xuICBpZiAocyA9PT0gXCJ1bmRlZmluZWRcIiB8fCBzID09IDAgfHwgaXNOYU4ocykpIHJldHVybiBcIjAwOjAwXCI7XG4gIGNvbnN0IGggPSBNYXRoLmZsb29yKHMgLyAzNjAwKVxuICBjb25zdCBtID0gTWF0aC5mbG9vcigocyAlIDM2MDApIC8gNjApXG4gIHMgPSBzICUgNjA7XG4gIHMgPSBwYXJzZUludChzKTtcbiAgcmV0dXJuIFtoLCBtID4gOSA/IG0gOiBoID8gJzAnICsgbSA6IG0gfHwgJzAnLCBzID4gOSA/IHMgOiAnMCcgKyBzXVxuICAgIC5maWx0ZXIoYSA9PiBhKVxuICAgIC5qb2luKCc6Jylcbn1cbnZhciByYWRpb2JvdF9hcGkgPSBcIndzczovL3JhZGlvLnJhZGlvYm90Lm9yZy9hcGkvbGl2ZS9ub3dwbGF5aW5nL3dlYnNvY2tldFwiXG52YXIgc29ja2V0X3JhZGlvX2JvdCA9IGZhbHNlXG5cbmxldCBhdWRpbyA9IGZhbHNlXG5sZXQgYXVkaW9fb3JpZ2VuID0gXCJyZWNvbWVuZGFjaW9uXCJcbnZhciBhdWRpb19wcm9ncmVzbyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcm9ncmVzby1hdWRpbycpO1xudmFyIGF1ZGlvX21vbWVudG8gPSAwO1xudmFyIGF1ZGlvX3Bvc2l0aW9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNhdWRpby1wb3NpdGlvblwiKTtcblxuY29uc3QgaG9va3MgPSB7XG4gIFRyYWNrRXZlbnQ6ICB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgICBpZiAodGhpcy5saXZlU29ja2V0LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhlLnRhcmdldCk7XG4gICAgICAgICAgY29uc3QgZWwgPSBlLnRhcmdldC5jbG9zZXN0KFwiW2lkXVwiKVxuICAgICAgICAgIGNvbnNvbGUubG9nKGVsKTtcblxuICAgICAgICAgIHRoaXMucHVzaEV2ZW50KFwidHJhY2tfZXZlbnRcIiwge1xuICAgICAgICAgICAgdGFnOiBlLnRhcmdldC50YWdOYW1lLFxuICAgICAgICAgICAgaWQ6IGVsLmlkLFxuICAgICAgICAgICAgcGF0aDogbG9jYXRpb24ucGF0aG5hbWVcbiAgICAgICAgICB9KS5jYXRjaCgoKSA9PiB7fSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9LFxuICAgIGRlc3Ryb3llZCgpIHtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCB0aGlzLmNsaWNrSGFuZGxlcilcbiAgICB9XG4gIH0sXG4gIFNjcm9sbFRvSW5pY2lvOiB7XG4gICAgdXBkYXRlZCgpIHtcbiAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJsaXN0YS1pbmljaW9cIilcbiAgICAgIGlmIChlbCkge1xuICAgICAgICAvL2VsLnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6IFwic21vb3RoXCIgfSlcbiAgICAgICAgY29uc3QgeSA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCArIHdpbmRvdy5zY3JvbGxZIC0gMTAwXG5cbiAgICAgICAgd2luZG93LnNjcm9sbFRvKHtcbiAgICAgICAgICB0b3A6IHksXG4gICAgICAgICAgYmVoYXZpb3I6IFwic21vb3RoXCJcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG4gI
1H0sXG4gIE1hbnRlbmVyU2Nyb2xsOiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIHRoaXMuc2Nyb2xsWCA9IHdpbmRvdy5zY3JvbGxYO1xuICAgICAgdGhpcy5zY3JvbGxZID0gd2luZG93LnNjcm9sbFk7XG4gICAgfSxcbiAgICB1cGRhdGVkKCkge1xuICAgICAgaWYgKHRoaXMuc2Nyb2xsWCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgd2luZG93LnNjcm9sbFRvKHRoaXMuc2Nyb2xsWCwgdGhpcy5zY3JvbGxZKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICB0aGlzLnNjcm9sbFggPSB3aW5kb3cuc2Nyb2xsWDtcbiAgICAgIHRoaXMuc2Nyb2xsWSA9IHdpbmRvdy5zY3JvbGxZO1xuICAgIH1cbiAgfSxcbiAgRWxlY2Npb25lc0NoYXJ0OiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIHRoaXMuY2FyZ2FyRDMoKTtcbiAgICB9LFxuICAgIGNhcmdhckQzKCkge1xuICAgICAgaWYgKHR5cGVvZiBkMyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhpcy5pbmljaWFsaXphcigpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBcbiAgICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgc2NyaXB0LnNyYyA9ICdodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9kMy82LjAuMC9kMy5taW4uanMnO1xuICAgICAgc2NyaXB0LmludGVncml0eSA9ICdzaGE1MTItOXVKQjZabUwyVWhCa1FIMlgxQitsYkVGSUR0bGF1TzBmUFVwMFJkbzZUejIxYTFhd2dTRCtGZlN5a3ZkK2dEM2M4V1Fyd1dlYUVnTWtQc0RlcDNQOHc9PSc7XG4gICAgICBzY3JpcHQuY3Jvc3
1NPcmlnaW4gPSAnYW5vbnltb3VzJztcbiAgICAgIHNjcmlwdC5yZWZlcnJlclBvbGljeSA9ICduby1yZWZlcnJlcic7XG4gICAgICBcbiAgICAgIHNjcmlwdC5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgIC8vIEZhbGxiYWNrOiBhc2VndXJhciBxdWUgRDMgZXN0w6kgZGlzcG9uaWJsZVxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuaW5pY2lhbGl6YXIoKSwgNTApO1xuICAgICAgfTtcbiAgICAgIFxuICAgICAgLy8gRmFsbGJhY2sgc2kgb25sb2FkIG5vIGZ1bmNpb25hXG4gICAgICBzY3JpcHQub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmluaWNpYWxpemFyKCksIDUwMCk7XG4gICAgICB9O1xuICAgICAgXG4gICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHNjcmlwdCk7XG4gICAgfSxcbiAgICBpbmljaWFsaXphcigpIHtcbiAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgIGRhdGE6IEpTT04ucGFyc2UodGhpcy5lbC5kYXRhc2V0LmRhdG9zIHx8ICd7fScpLFxuICAgICAgICBhbmhvOiB0aGlzLmVsLmRhdGFzZXQuYW5obyxcbiAgICAgICAgdGVycml0b3JpbzogdGhpcy5lbC5kYXRhc2V0LnRlcnJpdG9yaW8sXG4gICAgICAgIGRhdG9zQ29uc3VsdGE6IEpTT04ucGFyc2UodGhpcy5lbC5kYXRhc2V0LmRhdG9zQ29uc3VsdGEgfHwgJ3t9JylcbiAgICAgIH07XG4gICAgICB0aGlzLmRyYXdfYWxsKCk7XG4gICAgfSxcbiAgICB1cGRhdGVkKCkge1xuICAgICAgdGhpcy5zdGF0ZS5hbmhvID0gdGhpcy5lbC5kYXRhc2V0LmFuaG87XG4gICAgICB0aGlzLnN0YXRlLnRlcnJpdG9yaW8gPSB0aGlzLmVsLmRhdGFzZXQudGVycml0b3JpbztcbiAgICAgIHRoaXMuZHJhd19hbGwoKTtcbiAgICB9LFxuICAgIGdldFNpemUoaWQpIHtcbiAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgICAgaWYgKCFlbCB8fCAhZWwuY2xpZW50V2lkdGgpIHJldHVybiBudWxsO1xuICAgICAgcmV0dXJuIHsgd2lkdGg6IGVsLmNsaWVudFdpZHRoLCBoZWlnaHQ6IGVsLmNsaWVudFdpZHRoLzk1MCoyNTAgfTtcbiAgICB9LFxuICAgIHJlc3BvbnNpdmVmeShzdmcpIHtcbiAgICAgIGNvbnN0IGMgPSBkMy5zZWxlY3Qoc3ZnLm5vZGUoKS5wYXJlbnROb2RlKTtcbiAgICAgIGNvbnN0IHcgPSBwYXJzZUludChzdmcuc3R5bGUoXCJ3aWR0aFwiKSk7XG4gICAgICBjb25zdCBoID0gcGFyc2VJbnQoc3ZnLnN0eWxlKFwiaGVpZ2h0XCIpKTtcbiAgICAgIHN2Zy5hdHRyKFwidmlld0JveFwiLCBgMCAwICR7d30gJHtofWApLmF0dHIoXCJwcmVzZXJ2ZUFzcGVjdFJhdGlvXCIsIFwieE1pbllNaWQgbWVldFwiKTtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsICgpID0+IHtcbiAgICAgICAgY29uc3QgbncgPSBwYXJzZUludChjLnN0eWxlKFwid2lkdGhcIikpO1xuICAgICAgICBzdmcuYXR0cihcIndpZHRoXCIsIG53KS5hdHRyKFwiaGVpZ2h0XCIsIE1hdGgucm91bmQobncqaC93KSk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIGNyZWF0ZVN2ZyhpZCwgdywgaCkge1xuICAgICAgY29uc3QgYyA9IGQzLnNlbGVjdCgnIycraWQpOyBjLnNlbGVjdEFsbCgnKicpLnJlbW92ZSgpO1xuICAgICAgcmV0dXJuIGMuYXBwZW5kKCdzdmcnKS5hdHRyKCd3aWR0aCcsIHcpLmF0dHIoJ2hlaWdodCcsIGgpLmNhbGwodGhpcy5yZXNwb25zaXZlZnkpLmFwcGVuZCgnZycpO1xuICAgIH0sXG4gICAgY3JlYXRlRGF0b3NTdmcod2lkdGgsIGhlaWdodCl7XG4gICAgICB2Y
1XIgc2l6ZSA9IDE2O1xuICAgICAgaWYgKHdpZHRoPCA2MDApe3NpemUgPSAxM31cbiAgICAgIGlmICh3aWR0aDwgNTUwKXtzaXplID0gMTJ9XG4gICAgICBpZiAod2lkdGg8IDUwMCl7c2l6ZSA9IDEyfVxuICAgICAgaWYgKHdpZHRoPCA0NTApe3NpemUgPSAxMX1cbiAgICAgIGlmICh3aWR0aDwgNDAwKXtzaXplID0gMTB9XG4gICAgICBjb25zdCBjPWQzLnNlbGVjdCgnI2RhdG9zJyk7IGMuc2VsZWN0QWxsKCcqJykucmVtb3ZlKCk7XG4gICAgICByZXR1cm4gYy5hcHBlbmQoJ3N2ZycpLmF0dHIoJ3dpZHRoJyx3aWR0aCkuYXR0cignaGVpZ2h0JyxoZWlnaHQpXG4gICAgICAgIC5jYWxsKHRoaXMucmVzcG9uc2l2ZWZ5KS5hcHBlbmQoJ2cnKVxuICAgICAgICAuYXR0cignZm9udC1mYW1pbHknLCdzYW5zLXNlcmlmJykuYXR0cignZm9udC1zaXplJyxzaXplKS5hdHRyKCd0ZXh0LWFuY2hvcicsJ21pZGRsZScpO1xuICAgIH0sXG4gICAgY3JlYXRlU2NhbGVzKGRhdGEsIHcsIGgpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHg6IGQzLnNjYWxlQmFuZCgpLmRvbWFpbihkYXRhLm1hcChkID0+IGQuc2lnbGFzKSkucmFuZ2UoWzAsIHddKS5wYWRkaW5nKDAuMDUpLFxuICAgICAgICB5OiBkMy5zY2FsZUxpbmVhcigpLmRvbWFpbihbMCwgZDMubWF4KGRhdGEsIGQgPT4gZC5wZXJjZW50LzEwMCldKS5uaWNlKCkucmFuZ2UoW2gsIDBdKVxuICAgICAgfTtcbiAgICB9LFxuICAgIGNyZWF0ZVlTY2FsZUdsb2JhbChkYXRhLCBoZWlnaHQpIHtcbiAgICAgIHJldHVybiBkMy5zY2FsZUxpbmVhcigpLmRvbWFpbihbMCwgZDMubWF4KGRhdGEsIGQgPT4gZC5wZXJjZW50LzEwMCldKS5yYW5nZShbaGVpZ2h0LCAwXSkubmljZSgpO1xuICAgIH0sXG4gICAgZHJhd0JhcnMoc3ZnLCBkYXRhLCBzaXplLCBmcmFjLCB5U2NhbGVHbG9iYWwsIGlkKXtcbiAgICAgIGxldCBkID0gZGF0YTtcbiAgICAgIGlmKGZyYWM9PT0xKSBkID0gZGF0YS5zbGljZSgwLDUpO1xuICAgICAgaWYoZnJhYz09PTIpIGQgPSBkYXRhLnNsaWNlKDUpO1xuICAgICAgY29uc3QgcyA9IHRoaXMuY3JlYXRlU2NhbGVzKGQsIHNpemUud2lkdGgsIHNpemUuaGVpZ2h0KTtcbiAgICAgIGNvbnN0IGFuaG9fYWN0dWFsID0gdGhpcy5zdGF0ZS5kYXRvc0NvbnN1bHRhLmFuaG9fYWN0dWFsIHx8ICcyMDI2JztcbiAgICAgIGNvbnN0IGFuaG9fYW50ZXJpb3IgPSB0aGlzLnN0YXRlLmRhdG9zQ29uc3VsdGEuYW5ob19hbnRlcmlvciB8fCAnMjAyMic7XG4gICAgICBpZiAoaWQgIT09ICdncmFmaWNhXzInKSB7XG4gICAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jywgc2l6ZS53aWR0aC0xMCkuYXR0cigneScsIDQwKVxuICAgICAgICAgICAuYXR0cigndGV4dC1hbmNob3InLCdlbmQnKS5hdHRyKCdmb250LXNpemUnLDMyKS5hdHRyKCdmb250LXdlaWdodCcsJ2JvbGQnKVxuICAgICAgICAgICAudGV4dCh0aGlzLnN0YXRlLmFuaG89PT0nZWxlY2Npb25lc19hY3R1YWxlcyc/YW5ob19hY3R1YWw6YW5ob19hbnRlcmlvcik7XG4gICAgICB9XG4gICAgICBjb25zdCBnID0gc3ZnLnNlbGVjdEFsbCgnLmJhcicpLmRhdGEoZCkuZW50ZXIoKS5hcHBlbmQoJ2cnKTtcbiAgICAgIGcuYXBwZW5kKCdyZWN0JykuYXR0cignY2xhc3MnLCdiYXInKS5hdHRyKCd4Jyx4PT5zLngoeC5zaWdsYXMpKS5hdHRyKCd5Jyx5U2NhbGVHbG9iYWwoMCkpXG4gICAgICAgIC5hdHRyKCd3aWR0aCcscy54LmJhbmR3aWR0aCgpKS5hdHRyKCdoZWlnaHQnLHNpemUuaGVpZ2h0IC0geVNjYWxlR2xvYmFsKDApKVxuICAgICAgICAuYXR0cignZmlsbCcseD0+dGhpcy5jb2xvcih0aGlzLnNpZ2xhKHguc2lnbGFzKSkpLm9uKCdtb3VzZW92ZXInLHRoaXMuc2hvd1Rvb2x0aXApLm9uKCdtb3VzZW91dCcsdGhpcy5oaWRlVG9vbHRpcClcbiAgICAgICAgLnRyYW5zaXRpb24oKS5kdXJhdGlvbig4MDApLmF0dHIoJ3knLHg9PnlTY2FsZUdsb2JhbCh4LnBlcmNlbnQvMTAwKSlcbiAgICAgICAgLmF0dHIoJ2hlaWdodCcseD0+c2l6ZS5oZWlnaHQgLSB5U2NhbGVHbG9iYWwoeC5wZXJjZW50LzEwMCkpO1xuICAgICAgZy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4PT5zLngoeC5zaWdsYXMpK3MueC5iYW5kd2lkdGgoKS8yKS5hdHRyKCd5Jyx4PT55U2NhbGVHbG9iYWwoNCkpXG4gICAgICAgIC5hdHRyKCd0ZXh0LWFuY2hvcicsJ21pZGRsZScpLmF0dHIoJ2ZvbnQtd2VpZ2h0JywnYm9sZCcpLmF0dHIoJ2ZvbnQtc2l6ZScsMjYpXG4gICAgICAgIC5hdHRyKCdmaWxsJywgZCA9PiAoZC5wZXJjZW50PjY1MCk/XCIjZmZmXCI6XCIjMDAwXCIpLnRleHQoeD0+eC5lc2Nhbmhvcyk7XG4gICAgfSxcbiAgICBkcmF3UGllKGlkLCBkYXRhLCBmcmFjKXtcbiAgICAgIGNvbnN0IHNpemUgPSB0aGlzLmdldFNpemUoaWQpO1xuICAgICAgaWYoIXNpemUpIHJldHVybjtcbiAgICAgIGxldCBkID0gZGF0YTtcbiAgICAgIGNvbnN0IHRvdGFsVm90ZXMgPSBkMy5zdW0oZCwgeD0+eC52b3Rvcyk7XG4gICAgICBpZihmcmFjPT09MSkgZD1kYXRhLnNsaWNlKDAsNSk7XG4gICAgICBpZihmcmFjPT09MikgZD1kYXRhLnNsaWNlKDUpO1xuICAgICAgY29uc3Qgc3ZnID0gdGhpcy5jcmVhdGVTdmcoaWQsIHNpemUud2lkdGgsIDEwMCk7XG4gICAgICBjb25zdCBzID0gdGhpcy5jcmVhdGVTY2FsZXMoZCwgc2l6ZS53aWR0aCwgMTAwKTtcbiAgICAgIGNvbnN0IGcgPSBzdmcuc2VsZWN0QWxsKCdnLnBhcnRpZG8nKS5kYXRhKGQpLmVudGVyKCkuYXBwZW5kKCdnJykuYXR0cignY2xhc3MnLCdwYXJ0aWRvJylcbiAgICAgICAgICAuYXR0cigndHJhbnNmb3JtJyx4PT5gdHJhbnNsYXRlKCR7cy54KHguc2lnbGFzKStzLnguYmFuZHdpZHRoKCkvMn0sMClgKTtcbiAgICAgIGcuYXBwZW5kKCd0ZXh0JykuYXR0cigneScsMjApLmF0dHIoJ2ZvbnQtc2l6ZScsMTQpLmF0dHIoJ3RleHQtYW5jaG9yJywnbWlkZGxlJykuYXR0cignZm9udC13ZWlnaHQnLCdib2xkJykudGV4dCh4PT50aGlzLnNpZ2xhKHguc2lnbGFzKSk7XG4gICAgICBnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3knLDQwKS5hdHRyKCdmb250LXNpemUnLDEzKS5hdHRyKCdmb250LXdlaWdodCcsJ2JvbGQnKS5hdHRyKCd0ZXh0LWFuY2hvcicsJ21pZGRsZScpLnRleHQoeD0+KCh4LnZvdG9zL3RvdGFsVm90ZXMpKjEwMCkudG9GaXhlZCgxKSsnJScpO1xuICAgICAgZy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd5Jyw1OCkuYXR0cignZm9udC1zaXplJywxMSkuYXR0cignZmlsbCcsJyM1NTUnKS5hdHRyKCd0ZXh0LWFuY2hvcicsJ21pZGRsZScpLnRleHQoeD0+eC52b3Rvcy50b0xvY2FsZVN0cmluZygnZXMtRVMnKSk7XG4gICAgfSxcbiAgICBkcmF3X2RhdG9zKCl7XG4gICAgICBpZighdGhpcy5zdGF0ZS5kYXRhPy5bdGhpcy5zdGF0ZS5hbmhvXT8uW3RoaXMuc3RhdGUudGVycml0b3Jpb10gfHwgIXRoaXMuc3RhdGUuZGF0YT8uZWxlY2Npb25lc19hbnRlcmlvcmVzPy5bdGhpcy5zdGF0ZS50ZXJyaXRvcmlvXSkgcmV0dXJuO1xuICAgICAgY29uc3Qgc2l6ZSA9IHRoaXMuZ2V0U2l6ZSgnZGF0b3MnKTsgaWYoIXNpemUpIHJldHVybjtcbiAgICAgIGNvbnN0IHN2ZyA9IHRoaXMuY3JlYXRlRGF0b3NTdmcoc2l6ZS53aWR0aCwgMTIwKTtcbiAgICAgIGNvbnN0IGQyNiA9IHRoaXMuc3RhdGUuZGF0YS5lbGVjY2lvbmVzX2FjdHVhbGVzW3RoaXMuc3RhdGUudGVycml0b3Jpb10uZ2VuZXJhbDtcbiAgICAgIGNvbnN0IGQyMyA9IHRoaXMuc3RhdGUuZGF0YS5lbGVjY2lvbmVzX2FudGVyaW9yZXNbdGhpcy5zdGF0ZS50ZXJyaXRvcmlvXS5nZW5lcmFsO1xuICAgICAgY29uc3QgY29scz02OyBjb25zdCBjb2xXPXNpemUud2lkdGgvY29sczsgY29uc3QgeD1pPT5jb2xXKmkrY29sVy8yO1xuICAgICAgY29uc3QgeTE9MzAseTI9NjUseTM9OTU7XG4gICAgICBjb25zdCBhbmhvX2FjdHVhbCA9IHRoaXMuc3RhdGUuZGF0b3NDb25zdWx0YS5hbmhvX2FjdHVhbDtcbiAgICAgIGNvbnN0IGFuaG9fYW50ZXJpb3IgPSB0aGlzLnN0YXRlLmRhdG9zQ29uc3VsdGEuYW5ob19hbnRlcmlvcjtcbiAgICAgIHN2Zy5hcHBlbmQoJ3JlY3QnKS5hdHRyKCd4JywwKS5hdHRyKCd5Jyx5Mi0xOCkuYXR0cignd2lk
1dGgnLHNpemUud2lkdGgpLmF0dHIoJ2hlaWdodCcsMjgpLmF0dHIoJ2ZpbGwnLCcjZWVlJyk7XG4gICAgICBzdmcuYXBwZW5kKCdyZWN0JykuYXR0cigneCcsMCkuYXR0cigneScseTMtMTgpLmF0dHIoJ3dpZHRoJyxzaXplLndpZHRoKS5hdHRyKCdoZWlnaHQnLDI4KS5hdHRyKCdmaWxsJywnI2VlZScpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoMCkpLmF0dHIoJ3knLHkxKS5hdHRyKCdmb250LXdlaWdodCcsJ2JvbGQnKS50ZXh0KCcnKTtcbiAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4KDEpKS5hdHRyKCd5Jyx5MSkudGV4dCgnRXNjcnV0YWRvJyk7XG4gICAgICBzdmcuYXBwZW5kKCd0ZXh0JykuYXR0cigneCcseCgyKSkuYXR0cigneScseTEpLnRleHQoJ0Fic3RlbmNpw7NuJyk7XG4gICAgICBzdmcuYXBwZW5kKCd0ZXh0JykuYXR0cigneCcseCgzKSkuYXR0cigneScseTEpLnRleHQoJ0JsYW5jbycpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoNCkpLmF0dHIoJ3knLHkxKS50ZXh0KCdOdWxvcycpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoNSkpLmF0dHIoJ3knLHkxKS50ZXh0KCdFc2Nhw7FvcycpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoMCkpLmF0dHIoJ3knLHkyKS5hdHRyKCdmb250LXdlaWdodCcsJ2JvbGQnKS50ZXh0KGFuaG9fYWN0dWFsKTtcbiAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4KDEpKS5hdHRyKCd5Jyx5MikudGV4dChkMjYucGVyY2VudF9lc2NydXRhZG8udG9GaXhlZCgyKSsnICUnKTtcbiAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4KDIpKS5hdHRyKCd5Jyx5MikudGV4dChkMjYucGVyY2VudF9hYnN0ZW5jaW9uLnRvRml4ZWQoMikrJyAlJyk7XG4gICAgICBzdmcuYXBwZW5kKCd0ZXh0JykuYXR0cigneCcseCgzKSkuYXR0cigneScseTIpLnRleHQoZDI2LnBlcmNlbnRfYmxhbmNvLnRvRml4ZWQoMikrJyAlJyk7XG4gICAgICBzdmcuYXBwZW5kKCd0ZXh0JykuYXR0cigneCcseCg0KSkuYXR0cigneScseTIpLnRleHQoZDI2LnBlcmNlbnRfbnVsb3MudG9GaXhlZCgyKSsnICUnKTtcbiAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4KDUpKS5hdHRyKCd5Jyx5MikudGV4dChkMjYuZXNjYW5ob3MpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoMCkpLmF0dHIoJ3knLHkzKS5hdHRyKCdmb250LXdlaWdodCcsJ2JvbGQnKS50ZXh0KGFuaG9fYW50ZXJpb3IpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoMSkpLmF0dHIoJ3knLHkzKS50ZXh0KCcxMDAuMDAgJScpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoMikpLmF0dHIoJ3knLHkzKS50ZXh0KGQyMy5wZXJjZW50X2Fic3RlbmNpb24udG9GaXhlZCgyKSsnICUnKTtcbiAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4KDMpKS5hdHRyKCd5Jyx5MykudGV4dChkMjMucGVyY2VudF9ibGFuY28udG9GaXhlZCgyKSsnICUnKTtcbiAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4KDQpKS5hdHRyKCd5Jyx5MykudGV4dChkMjMucGVyY2VudF9udWxvcy50b0ZpeGVkKDIpKycgJScpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoNSkpLmF0dHIoJ3knLHkzKS50ZXh0KGQyMy5lc2Nhbmhvcyk7XG4gICAgfSxcbiAgICBzaG93VG9vbHRpcChlLCBkKXtcbiAgICAgIGNvbnN0IHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndG9vbHRpcCcpO1xuICAgICAgY29uc3QgciA9IGUudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgdC50ZXh0Q29udGVudCA9IGQuc2lnbGFzO1xuICAgICAgdC5zdHlsZS5sZWZ0ID0gci5sZWZ0K3Iud2lkdGgvMisncHgnO1xuICAgICAgdC5zdHlsZS50b3AgPSByLnRvcC0zMCsncHgnO1xuICAgICAgdC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gICAgfSxcbiAgICBoaWRlVG9vbHRpcCgpe1xuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rvb2x0aXAnKS5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG4gICAgfSxcbiAgICBkcmF3X2FsbCgpe1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuc3RhdGUuZGF0YT8uW3RoaXMuc3RhdGUuYW5ob10/Llt0aGlzLnN0YXRlLnRlcnJpdG9yaW9dPy5yZWN1ZW50b19wYXJ0aWRvcztcbiAgICAgIHRoaXMuZHJhd19kYXRvcygpO1xuICAgICAgaWYoIWRhdGEgfHwgIWRhdGEubGVuZ3RoIHx8IGRhdGFbMF0uY29kaWdvID09IFwiMDAwMFwiKXtcbiAgICAgICAgY29uc3QgYW5ob19hY3R1YWwgPSB0aGlzLnN0YXRlLmRhdG9zQ29uc3VsdGEuYW5ob19hY3R1YWwgfHwgJzIwMjYnO1xuICAgICAgICBjb25zdCBhbmhvX2FudGVyaW9yID0gdGhpcy5zdGF0ZS5kYXRvc0NvbnN1bHRhLmFuaG9fYW50ZXJpb3IgfHwgJzIwMjInO1xuICAgICAgICBjb25zdCBhbmhvID0gdGhpcy5zdGF0ZS5hbmhvID09PSAnZWxlY2Npb25lc19hY3R1YWxlcycgPyBhbmhvX2FjdHVhbCA6IGFuaG9fYW50ZXJpb3I7XG4gICAgICAgIFxuICAgICAgICBbJ2dyYWZpY2EnLCAnZ3JhZmljYV8xJywgJ2dyYWZpY2FfMiddLmZvckVhY2goKGlkKSA9PiB7XG4gICAgICAgICAgY29uc3QgcyA9IHRoaXMuZ2V0U2l6ZShpZCk7IGlmKCFzKSByZXR1cm47XG4gICAgICAgICAgY29uc3Qgc3ZnID0gdGhpcy5jcmVhdGVTdmcoaWQsIHMud2lkdGgsIHMuaGVpZ2h0KTtcbiAgICAgICAgICBzdmcuYXBwZW5kKCd0ZXh0JylcbiAgICAgICAgICAgIC5hdHRyKCd4Jywgcy53aWR0aC8yKVxuICAgICAgICAgICAgLmF0dHIoJ3knLCBzLmhlaWdodC8yKVxuICAgICAgICAgICAgLmF0dHIoJ3RleHQtYW5jaG9yJywgJ21pZGRsZScpXG4gICAgICAgICAgICAuYXR0cignZm9udC1zaXplJywgMjQpXG4gICAgICAgICAgICAuYXR0cignZm9udC13ZWlnaHQnLCAnYm9sZCcpXG4gICAgICAgICAgICAuYXR0cignZmlsbCcsICcjNjY2JylcbiAgICAgICAgICAgIC50ZXh0KGBTSU4gREFUT1MgJHthbmhvfWApO1xuICAgICAgICB9KTtcbiAgICAgICAgWydwaWUnLCAncGllXzEnLCAncGllXzInXS5mb3JFYWNoKChpZCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHMgPSB0aGlzLmdldFNpemUoaWQpOyBpZighcykgcmV0dXJuO1xuICAgICAgICAgIGNvbnN0IHN2ZyA9IHRoaXMuY3JlYXRlU3ZnKGlkLCBzLndpZHRoLCAxMDApO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICBcbiAgICAgIFsnZ3JhZmljYScsICdncmFmaWNhXzEnLCAnZ3JhZmljYV8yJ10uZm9yRWFjaCgoaWQsIGkpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IHRoaXMuZ2V0U2l6ZShpZCk7IGlmKCFzKSByZXR1cm47XG4gICAgICAgIGNvbnN0IHlTY2FsZUdsb2JhbCA9IHRoaXMuY3JlYXRlWVNjYWxlR2xvYmFsKGRhdGEsIHMuaGVpZ2h0KTtcbiAgICAgICAgdGhpcy5kcmF3QmFycy
1h0aGlzLmNyZWF0ZVN2ZyhpZCwgcy53aWR0aCwgcy5oZWlnaHQpLCBkYXRhLCBzLCBpLCB5U2NhbGVHbG9iYWwsIGlkKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5kcmF3UGllKCdwaWUnLCBkYXRhLCAwKTtcbiAgICAgIHRoaXMuZHJhd1BpZSgncGllXzEnLCBkYXRhLCAxKTtcbiAgICAgIHRoaXMuZHJhd1BpZSgncGllXzInLCBkYXRhLCAyKTtcbiAgICB9LFxuICAgIGNvbG9yKHBhcnRpZG8pe1xuICAgICAgY29uc3QgY29sb3JlcyA9IHsgXG4gICAgICAgIFwiUFNPRVwiOlwiI2RjMDYxMlwiLFxuICAgICAgICBcIlBTT0UtQVwiOlwiI2RjMDYxMlwiLFxuICAgICAgICBcIlBQXCI6XCIjMDE1NDlmXCIsXG4gICAgICAgIFwiVk9YXCI6XCIjNTNkNDAzXCIsXG4gICAgICAgIFwiQUhPUkEgUkVQw5pCTElDQVNcIjpcIiNmN2I5M2ZcIixcbiAgICAgICAgXCJBSE9SQSBSRVDDmkJMSUNBUyAoRVJDLUVIIEJJTERVLUJORy1BUkEgTcOJUylcIjpcIiNmN2I5M2ZcIixcbiAgICAgICAgXCJKVU5UU1wiOlwiIzAwQjRDNFwiLFxuICAgICAgICBcIkpVTlRTLVVFXCI6XCIjMDBCNEM0XCIsXG4gICAgICAgIFwiQ0VVU1wiOlwiIzI5N2Y0MVwiLFxuICAgICAgICBcIlBPREVNT1NcIjpcIiM3MjE1NmVcIixcbiAgICAgICAgXCJQT0RFTU9TLUlVXCI6XCIjNzIxNTZlXCIsXG4gICAgICAgIFwiUE9ERU1PUyBBTElBWkEgVkVSREVcIjpcIiM3MjE1NmVcIixcbiAgICAgICAgXCJQT0RFTU9TIC1BVlwiOlwiIzcyMTU2ZVwiLFxuICAgICAgICBcIlAtSVUtQVZcIjpcIiM3MjE1NmVcIixcbiAgICAgICAgXCJTVU1BUlwiOlwiI0JCMjY0OVwiLFxuICAgICAgICBcIkNzXCI6XCIjZmY2NDE5XCIsXG4gICAgICAgIFwiUy5BLkwuRlwiOlwiIzlGQTJCMlwiLFxuICAgICAgICBcIlNBTEZcIjpcIiM5RkEyQjJcIixcbiAgICAgICAgXCJQQUNNQVwiOlwiIzAwZDA4NFwiLFxuICAgICAgICBcIlBvckFcIjogXCIjZjhjNTY1XCIsXG4gICAgICAgIFwiQURFTEFOVEUgQU5EQUxVQ8ONQVwiOiBcIiMwMDkwNzZcIixcbiAgICAgICAgXCJBQVwiOiBcIiMwMDkwNzZcIixcbiAgICAgICAgfTtcbiAgICAgIHJldHVybiBjb2xvcmVzW3BhcnRpZG9dIHx8ICcjJytNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkqTWF0aC5wb3coMiwzMileMHhmZmZmZmYpLnRvU3RyaW5nKDE2KS5zdWJzdHIoLTYpO1xuICAgIH0sXG4gICAgc2lnbGEocGFydGlkbyl7XG4gICAgICBjb25zdCBzaWdsYXMgPSB7IFxuICAgICAgICBcIlAuUy5PLkUuXCI6XCJQU09FXCIsXG4gICAgICAgIFwiUEFSVElETyBBVVTDk05PTU9TXCI6XCJQQVwiLFxuICAgICAgICBcIlJFQ09SVEVTIENFUk9cIjpcIlJDXCIsXG4gICAgICAgIFwiQURFTEFOVEUgQU5EQUxVQ8ONQS1BTkRBTFVDSVNUQVNcIjogXCJBQS1BXCIsXG4gICAgICAgIFwiQURFTEFOVEUgQU5EQUxVQ8ONQS1BTkRBTFVDSVNUQVNcIjogXCJBQS1BXCIsXG4gICAgICAgIFwiQU5EQUxVQ0lTVEFTLVBBXCI6IFwiQS1QQVwiLFxuICAgICAgICBcIkFOREFMVUNJU1RBUyAtIFBBXCI6IFwiQS1QQVwiLFxuICAgICAgICBcIkFERUxBTlRFIEFOREFMVUPDjUFcIjogXCJBQVwiLFxuICAgICAgICBcIkFIT1JBIFJFUMOaQkxJQ0FTXCI6XCJBLlIuXCIsXCJBR1JVUEFDScOTTiBERSBFTEVDVE9SRVMgU0UgQUNBQsOTIExBIEZJRVNUQVwiOlwiQS5FLlMuQS5GXCIsXG4gICAgICAgIFwiQUhPUkEgUkVQw5pCTElDQVMgKEVSQy1FSCBCSUxEVS1CTkctQVJBIE3DiVMpXCI6XCJBLlIuXCIsXCJQT0RFTU9TIEFMSUFOWkEgVkVSREVcIjpcIlAtQVZcIixcIlBPREVNT1MgLUFWXCI6XCJQLUFWXCIsXG4gICAgICAgIFwiUE9ERU1PUy1JVS1BVlwiOlwiUC1JVS1BVlwiLFwiQ09BTElDScOTTiBBUkFHT05FU0FcIjpcIkNBXCIsXCJJVS0gTU9WSU1JRU5UTyBTVU1BUlwiOlwiSVUtTVNcIixcIkVTQ0HDkU9TIEVOIEJMQU5DT1wiOlwiRUJcIixcbiAgICAgICAgXCJNVU5ETytKVVNUT1wiOlwiTStKXCIsXCJFU1BBw5FBIFZBQ0lBREFcIjpcIkUuVi5cIixcIkNTLVTDmiBBUkFHw5NOXCI6XCJDUy1UVVwiLFwiRkUgZGUgbGFzIEpPTlNcIjpcIkZFIEpvbnNcIixcbiAgICAgICAgXCJQQ0FTLVRDLVJlY29ydGVzIENlcm9cIjpcIlBDQVMtVEMtUkNcIlxuICAgICAgfTtcbiAgICAgIHJldHVybiBzaWdsYXNbcGFydGlkb10gfHwgcGFydGlkbztcbiAgICB9LFxuICB9LFxuICBGbG93Q3VycmVudDoge1xuICAgIG1vdW50ZWQoKSB7XG4gICAgICB0aGlzLmVsLnN0eWxlLnRyYW5zaXRpb24gPSBcInRyYW5zZm9ybSAxLjJzIGVhc2UtaW4tb3V0LCBmaWxsIDAuOHNcIlxuICAgIH0sXG4gICAgdXBkYXRlZCgpIHtcbiAgICAgIGxldCB4ID0gcGFyc2VGbG9hdCh0aGlzLmVsLmRhdGFzZXQueClcbiAgICAgIGxldCB5ID0gcGFyc2VGbG9hdCh0aGlzLmVsLmRhdGFzZXQueSlcblxuICAgICAgLy8gZWZlY3RvIEJlemllci1saWtlOiBsaWdlcmEgY3VydmEgZW4gbW92aW1pZW50b1xuICAgICAgbGV0IGN4ID0geCArIChNYXRoLnJhbmRvbSgpLTAuNSkqMjBcbiAgICAgIGxldCBjeSA9IHkgKyAoTWF0aC5yYW5kb20oKS0wLjUpKjEwXG4gICAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZShcInhcIiwgY3gpXG4gICAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZShcInlcIiwgY3kpXG4gICAgfVxuICB9LFxuXG4gIEhvcml6b250YWxTY3JvbGw6IHtcbiAgICBtb3VudGVkKCkge1xuICAgICAgaWYgKHdpbmRvdy5pbm5lcldpZHRoID4gNzY4KSByZXR1cm47IC8vIOKdjCBObyBoYWNlciBuYWRhIGVuIGVzY3JpdG9yaW9cbiAgICAgIGNvbnN0IGlkID1gIyR7dGhpcy5lbC5kYXRhc2V0LmlkfWA7XG5cbiAgICAgIGNvbnN0IGVsID0gdGhpcy5lbFxuICAgICAgbGV0IGF0RW5kID0gZmFsc2VcblxuICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNjcm9sbExlZnQgPSBlbC5zY3JvbGxMZWZ0XG4gICAgICAgIGNvbnN0IHNjcm9sbFdpZHR
1oID0gZWwuc2Nyb2xsV2lkdGhcbiAgICAgICAgY29uc3QgY2xpZW50V2lkdGggPSBlbC5jbGllbnRXaWR0aFxuXG4gICAgICAgIGlmIChzY3JvbGxMZWZ0ICsgY2xpZW50V2lkdGggPj0gc2Nyb2xsV2lkdGggLSAgIDApIHtcbiAgICAgICAgICBpZiAoIWF0RW5kKSB7XG4gICAgICAgICAgICB0aGlzLnB1c2hFdmVudFRvKGlkLCBcInNjcm9sbF9lbmRcIilcbiAgICAgICAgICAgIGF0RW5kID0gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhdEVuZCA9IGZhbHNlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9LFxuICBDYXJydXNlbFRyYWNrOiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIHRoaXMucGFnZSA9IHBhcnNlSW50KHRoaXMuZWwuZGF0YXNldC5wYWdlKVxuICAgIH0sXG4gICAgdXBkYXRlZCgpIHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBwYXJzZUludCh0aGlzLmVsLmRhdGFzZXQucGFnZSlcbiAgICAgIGNvbnN0IHBlclBhZ2UgPSBwYXJzZUludCh0aGlzLmVsLmRhdGFzZXQucGVyUGFnZSlcblxuICAgICAgY29uc3QgZWxlbWVudG8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndHJhY2stc29jaWFzLW9waW5pb24nKSB8fCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndHJhY2stcmVsYWNpb25hZGFzLWxpdmUnKS5wYXJlbnROb2RlOyBcbiAgICAgIGNvbnN0IGFuY2hvX3RvdGFsX3Zpc2libGUgPSBlbGVtZW50by5vZmZzZXRXaWR0aDsgXG5cbiAgICAgIC8vY29uc3Qgb2Zmc2V0ID0gLXBhZ2UgKiBwZXJQYWdlICogaXRlbVdpZHRoXG4gICAgICBjb25zdCBvZmZzZXQgPSAtcGFnZSAqIGFuY2hvX3RvdGFsX3Zpc2libGVcbiAgICAgIGNvbnN0IHRyYWNrID0gdGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiLml0ZW1zLXRyYWNrXCIpXG5cbiAgICAgIHRoaXMucGFnZSA9IHBhZ2VcblxuICAgICAgaWYgKHRyYWNrKSB7XG4gICAgICAgIGlmICh3aW5kb3cuaW5uZXJXaWR0aCA8PSA3NjgpIHJldHVybjsgLy8g4p2MIE5vIGhhY2VyIG5hZGEgZW4gbW92aWwgIFxuICAgICAgICB0cmFjay5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlWCgke29mZnNldH1weClgXG4gICAgICB9XG4gICAgfVxuICB9LFxuICBMYXp5TG9hZEFkOiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIHZhciBtb2R1bG9fcHVibGkgPSB0aGlzLmVsLmRhdGFzZXQubmFtZVxuICAgICAgbGV0IGFscmVhZHlUcmlnZ2VyZWQgPSBmYWxzZVxuXG4gICAgICBjb25zdCBoYW5kbGVWaXNpYmxlID0gKCkgPT4ge1xuICAgICAgICAvL2lmIChhbHJlYWR5VHJpZ2dlcmVkKSByZXR1cm5cbiAgICAgICAgYWxyZWFkeVRyaWdnZXJlZCA9IHRydWVcblxuICAgICAgICAvLyBWZXJpZmljYXIgbG9ja3MgeSBlc3RhZG8gZGUgYWN0dWFsaXphY2nDs24gZGUgY29udGVuaWRvXG4gICAgICAgIGlmIChwdWJsaV9sb2NrIHx8IGNvbnRlbmlkb3VwZGF0aW5nKSB7XG4gICAgICAgICAgaWYgKCFwdWJsaV9wZW5kaWVudGVzLmluY2x1ZGVzKG1vZHVsb19wdWJsaSkpIHtcbiAgICAgICAgICAgIHB1YmxpX3BlbmRpZW50ZXMucHVzaChtb2R1bG9fcHVibGkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2Y
1XIgc2x1ZzEgPSBcIlwiO1xuICAgICAgICB2YXIgc2x1ZzIgPSBcIlwiO1xuICAgICAgICB2YXIgbG9jID0gbG9jYXRpb24ucGF0aG5hbWUuc3BsaXQoJy8nKS5zbGljZSgxKTtcbiAgICAgICAgaWYobG9jWzBdKSB7IHNsdWcxID0gbG9jWzBdIH1cbiAgICAgICAgaWYobG9jWzFdKSB7IHNsdWcyID0gbG9jWzFdIH1cbiAgICAgICAgaWYobG9jWzBdID09IFwic2luLXB1YmxpY2FyXCIpIHsgc2x1ZzEgPSBsb2NbMV07IHNsdWcyID0gbG9jWzJdfSBcblxuICAgICAgICB2YXIgbm9kbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibm9kby1jb250ZW5pZG9cIilcbiAgICAgICAgaWYgKG5vZG8pIHsgbm9kbyA9IG5vZG8uZ2V0QXR0cmlidXRlKCdkYXRhLW5vZG8nKSB9XG5cbiAgICAgICAgdGhpcy5wdXNoRXZlbnRUbyh0aGlzLmVsLCBcImFkX3Zpc2libGVcIiwgeyBcbiAgICAgICAgICBtb2R1bG86IG1vZHVsb19wdWJsaSxcbiAgICAgICAgICBzbHVnMTogc2x1ZzEsXG4gICAgICAgICAgc2x1ZzI6IHNsdWcyLFxuICAgICAgICAgIG1vYmlsOiAod2luZG93LmlubmVyV2lkdGggPiA3NjcpID8gZmFsc2UgOiB0cnVlLFxuICAgICAgICAgIG5vZG86IG5vZG8sXG4gICAgICAgICAgaXA6IGRvY3VtZW50LmJvZHkuZ2V0QXR0cmlidXRlKCdkYXRhLWlwJyksXG4gICAgICAgIH0pXG5cbiAgICAgICAgb2JzZXJ2ZXIuZGlzY29ubmVjdCgpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChbZW50cnldKSA9PiB7XG4gICAgICAgIGlmIChlbnRyeS5pc0ludGVyc2VjdGluZyB8fCBlbnRyeS5pbnRlcnNlY3Rpb25SYXRpbyA+IDApIHtcbiAgICAgICAgICBoYW5kbGVWaXNpYmxlKClcbiAgICAgICAgfVxuICAgICAgfSwgeyByb290TWFyZ2luOiBcIjIwMHB4XCIgfSlcblxuICAgICAgb2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsKTtcblxuICAgICAgLy8gY29tcHJvYmFjacOzbiBpbmljaWFsXG4gICAgICBjb25zdCByZWN0ID0gdGhpcy5lbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgY29uc3QgaW5WaWV3ID0gcmVjdC50b3AgPCB3aW5kb3cuaW5uZXJIZWlnaHQgJiYgcmVjdC5ib3R0b20gPiAwXG5cbiAgICAgIGlmIChpblZpZXcpIHtcbiAgICAgICAgaGFuZGxlVmlzaWJsZSgpXG4gICAgICB9XG5cbiAgICAgIHRoaXMuaGFuZGxlRXZlbnQoYHVwZGF0ZV9hZF8ke21vZHVsb19wdWJsaX1gLCAoYW51bmNpbykgPT4ge1xuICAgICAgICBpZiAodGhpcy5lbC5kYXRhc2V0Lm5hbWUgPT0gYW51bmNpby5tb2R1bG8pe1xuICAgICAgICAgIHZhciBtb2JpbCA9ICh3aW5kb3cuaW5uZXJXaWR0aCAgPiA3NjcpID8gZmFsc2UgOiB0cnVlO1xuXG4gICAgICAgICAgbGV0IG1vZHVsbyA9IHRoaXMuZWw7XG4gICAgICAgICAgaWYgKCFtb2R1bG8pIHJldHVybjtcblxuICAgICAgICAgIC8vIDEuIEHDsWFkaXIgY2xhc2Ugc2Vnw7puIGVsIHRpcG8gZGUgYW51bmNpb1xuICAgICAgICAgIGlmIChhbnVuY2lvLm1hcXVldGFjaW9uICYmIGFudW5jaW8ubWFxdWV0YWNpb24ubm9fcHVibGljaWRhZCA9PT0gXCJub19wdWJsaWNpZGFkXCIpIHtcbiAgICAgICAgICAgIG1vZHVsby5jbGFzc0xpc3QuYWRkKCdibG9xdWUtYWN0aXZvJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG1vZHVsby5jbGFzc0xpc3QuYWRkKCdhbnVuY2lvLWFjdGl2bycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIDIuIFZhY2lhciBlbCBjb250ZW5pZG8gZGVsIG3Ds2R1bG9cbiAgICAgICAgICBtb2R1bG8uaW5uZXJIVE1MID0gXCJcIjtcblxuICAgICAgICAgIC8vIDMuIEF0cmlidXRvIFwicGh4LXVwZGF0ZVwiXG4gICAgICAgICAgbW9kdWxvLnNldEF0dHJpYnV0ZSgncGh4LXVwZGF0ZScsICdpZ25vcmUnKTtcblxuICAgICAgICAgIC8vIDQuIFNpIGhheSBzY3JpcHQsIHVzYXIgcG9zdHNjcmliZSAoc2kgZXN0w6EgZGlzcG9uaWJsZSlcbiAgICAgICAgICBpZiAoYW51bmNpby5zY3JpcHQgJiYgYW51bmNpby5zY3JpcHQubGVuZ3RoID4gMTApIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcG9zdHNjcmliZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHBvc3RzY3JpYmUobW9kdWxvLCBhbnVuY2lvLnNjcmlwdCwge1xuICAgICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdBZCBmYWlsZWQgdG8gbG9hZDonLCBlKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJFcnJvciBhbCBpbnNlcnRhciBzY3JpcHRcIik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUud2FybihcInBvc3RzY3JpYmUgbm8gZXN0w6EgZGVmaW5pZG9cIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gNS4gU2kgaGF5IEhUTUwgcGVyc29uYWxpemFkb1xuICAgICAgICAgICAgaWYgKGFudW5jaW8uaHRtbCAmJiBhbnVuY2lvLmh0bWwubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgICAgZGl2LmNsYXNzTGlzdC5hZGQoJ2h0bWwtYW51bicpO1xuICAgICAgICAgICAgICBkaXYuaW5uZXJIVE1MID0gYW51bmNpby5odG1sO1xuICAgICAgICAgICAgICBtb2R1bG8uYXBwZW5kQ2hpbGQoZGl2KTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gNi4gU2kgbm8gaGF5IEhUTUwgbmkgc2NyaXB0LCBjb25zdHJ1aXIgZW5sYWNlIGRlIGFudW5jaW9cbiAgICAgICAgICAgICAgY29uc3QgcmVkaXJlY2Npb24gPSBhbnVuY2lvLnVybF9yZWRpcmVjY2lvbiB8fCBcImZhbHNlXCI7XG4gICAgICAgICAgICAgIGNvbnN0IGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgICAgICAgICAgIGEuZGF0YXNldC5hbnVuID0gYW51bmNpby5pZDtcbiAgICAgICAgICAgICAgYS5kYXRhc2V0LmNsaWNrID0gcmVkaXJlY2Npb247XG4gICAgICAgICAgICAgIGEuaHJlZiA9IGAvaXJfYW51bmNpby8ke2FudW5jaW8uaWR9LyR7bW9iaWx9YDtcbiAgICAgICAgICAgICAgYS50YXJnZXQgPSBcIl9ibGFua1wiO1xuICAgICAgICAgICAgICBhLnNldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbCcsICdwdWJsaWNpZGFkJyk7XG4gICAgICAgICAgICAgIGEuY2xhc3NMaXN0LmFkZCgnYW51bmNpby1saW5rJyk7XG4gICAgICAgICAgICAgIG1vZHVsby5hcHBlbmRDaGlsZChhKTtcblxuICAgICAgICAgICAgICAvLyA3LiBJbWFnZW4gbyB2aWRlb1xuICAgICAgICAgICAgICBpZiAoYW51bmNpby5pbWFnZW4pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBleHQgPSBhbnVuY2lvLmltYWdlbi5zcGxpdCgnLicpLnBvcCgpLnNwbGl0KCc/Jykuc2hpZnQoKTtcbiAgICAgICAgICAgICAgICBpZiAoZXh0ID09PSBcIm1wNFwiKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAgICAgICAgICAgICAgICB2aWRlby5jbGFzc0xpc3QuYWRkKCduby1tZXAnKTtcbiAgICAgICAgICAgICAgICAgI
1HZpZGVvLmF1dG9wbGF5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIHZpZGVvLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIHZpZGVvLmxvb3AgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgdmlkZW8uc3JjID0gYW51bmNpby5pbWFnZW47XG4gICAgICAgICAgICAgICAgICB2aWRlby5hbHQgPSBhLnRpdHVsbztcbiAgICAgICAgICAgICAgICAgIGEuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBpbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICAgICAgICAgICAgICAgIGltZy5zcmMgPSBhbnVuY2lvLmltYWdlbjtcbiAgICAgICAgICAgICAgICAgIGltZy5hbHQgPSBhbnVuY2lvLnRpdHVsbztcbiAgICAgICAgICAgICAgICAgIGEuYXBwZW5kQ2hpbGQoaW1nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyA4LiBQw614ZWwgZGUgaW1wcmVzacOzblxuICAgICAgICAgICAgICBpZiAoYW51bmNpby51cmxfaW1wcmVzaW9uKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGl4ZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICAgICAgICAgICAgICBwaXhlbC5jbGFzc0xpc3QuYWRkKCd0cmFuc3BhcmVudCcpO1xuICAgICAgICAgICAgICAgIHBpeGVsLnNyYyA9IGFudW5jaW8udXJsX2ltcHJlc2lvbi5yZXBsYWNlKFwiW3RpbWVzdGFtcF1cIiwgK25ldyBEYXRlKCkpO1xuICAgICAgICAgICAgICAgIHBpeGVsLmFsdCA9IFwiQWR2ZXJ0aXNtZW50XCI7XG4gICAgICAgICAgICAgICAgcGl4ZWwuYm9yZGVyID0gXCIwXCI7XG4gICAgICAgICAgICAgICAgcGl4ZWwuaGVpZ2h0ID0gMTtcbiAgICAgICAgICAgICAgICBwaXhlbC53aWR0aCA9IDE7XG4gICAgICAgICAgICAgICAgYS5hcHBlbmRDaGlsZChwaXhlbCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy90aGlzLmVsLmlubmVySFRNTCA9IGRhdGEuY29udGVudDtcbiAgICAgICAgfVxuICAgICAgICBwb3B1cCgpO1xuICAgICAgfSlcbiAgICB9XG4gIH0sXG4gIE1hcExpYnJlRm9ybU1hcDoge1xuICAgIG1vdW50ZWQoKSB7XG4gICAgICBpZiAoIXdpbmRvdy5tYXBsaWJyZWdsKSB7XG4gICAgICAgIFByb21pc2UuYWxsKFtcbiAgICAgICAgICB0aGlzLmxvYWRDU1MoXCJodHRwczovL3VucGtnLmNvbS9tYXBsaWJyZS1nbEAzLjMuMS9kaXN0L21hcGxpYnJlLWdsLmNzc1wiKSxcbiAgICAgICAgICB0aGlzLmxvYWRKUyhcImh0dHBzOi8vdW5wa2cuY29tL21hcGxpYnJlLWdsQDMuMy4xL2Rpc3QvbWFwbGlicmUtZ2wuanNcIilcbiAgICAgICAgXSlcbiAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLmluaXRNYXAoKSlcbiAgICAgICAgICAuY2F0Y2goKGVycikgPT4gY29uc29sZS5lcnJvcihcIkVycm9yIGxvYWRpbmcgTWFwTGlicmU6XCIsIGVycikpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5pbml0TWFwKCk7XG4gICAgICB9XG4gICAgfSxcbiAgICB1cGRhdGVkKCkge1xuICAgICAgICB0aGlzLmluaXRNYXAoKTtcbiAgICB9LFxuXG4gICAgbG9hZENTUyh1cmwpIHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBsaW5rW2hyZWY9XCIke3VybH1cIl1gKSkgcmV0dXJuIHJlc29sdmUoKTtcblxuICAgICAgICBjb25zdCBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImxpbmtcIik7XG4gICAgICAgIGxpbmsucmVsID0gXCJzdHlsZXNoZWV0XCI7XG4gICAgICAgIGxpbmsuaHJlZiA9IHVybDtcbiAgICAgICAgbGluay5vbmxvYWQgPSByZXNvbHZlO1xuICAgICAgICBsaW5rLm9uZXJyb3IgPSByZWplY3Q7XG4gICAgICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIGxvYWRKUyh1cmwpIHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBzY3JpcHRbc3JjPVwiJHt1cmx9XCJdYCkpIHJldHVybiByZXNvbHZlKCk7XG5cbiAgICAgICAgY29uc3Qgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNjcmlwdFwiKTtcbiAgICAgICAgc2NyaXB0LnNyYyA9IHVybDtcbiAgICAgICAgc2NyaXB0LmlkID0gXCJJRF9tYXBfc2NyaXB0XCI7XG4gICAgICAgIHNjcmlwdC5hc3luYyA9IHRydWU7XG4gICAgICAgIHNjcmlwdC5vbmxvYWQgPSByZXNvbHZlO1xuICAgICAgICBzY3JpcHQub25lcnJvciA9IHJlamVjdDtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGluaXRNYXAoKSB7XG5cbiAgICAgIGNvbnN0IGxhdCA9IHBhcnNlRmxvYXQodGhpcy5lbC5kYXRhc2V0LmxhdCkgfHwgMDtcbiAgICAgIGNvbnN0IGxuZyA9IHBhcnNlRmxvYXQodGhpcy5lbC5kYXRhc2V0LmxuZykgfHwgMDtcbiAgICAgIGNvbnN0IHpvb20gPSBwYXJzZUZsb2F0KHRoaXMuZWwuZGF0YXNldC56b29tKSB8fCAyO1xuXG4gICAgICB0aGlzLm1hcCA9IG5ldyBtYXBsaWJyZWdsLk1hcCh7XG4gICAgICAgIGNvbnRhaW5lcjogdGhpcy5lbCxcbiAgICAgICAgc3R5bGU6IFwiaHR0cHM6Ly9kZW1vdGlsZXMubWFwbGlicmUub3JnL3N0eWxlLmpzb25cIixcbiAgICAgICAgc3R5bGU6IFwiaHR0cHM6Ly9kZW1vdGlsZXMubWFwbGlicmUub3JnL3N0eWxlcy9vc20tYnJpZ2h0LWdsLXN0eWxlL3R5bGUuanNvblwiLFxuICAgICAgICBzdHlsZTogXCJodHRwczovL3RpbGVzLnN0YWRpYW1hcHMuY29tL3N0eWxlcy9vc21fYnJpZ2h0Lmpzb25cIixcbiAgICAgICAgY2VudGVyOiBbbG5nLCBsYXRdLFxuICAgICAgICB6b29tOiB6b29tXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5tYXAuYWRkQ29udHJvbChuZXcgbWFwbGlicmVnbC5OYXZpZ2F0aW9uQ29udHJvbCgpKTtcblxuICAgICAgLy8g8J+ntyBDcmVhciBtYXJjYWRvciBpbmljaWFsXG4gICAgICB0aGlzLm1hcmtlciA9IG5ldyBtYXBsaWJyZWdsLk1hcmtlcih7IGRyYWdnYWJsZTogdHJ1ZSB9KVxuICAgICAgICAuc2V0TG5nTGF0KFtsbmcsIGxhdF0pXG4gICAgICAgIC5hZGRUbyh0aGlzLm1hcCk7XG5cbiAgICAgIC8vIPCfm7DvuI8gQWN0dWFsaXphciBtYXJjYWRvciB5IGVudmlhciBldmVudG8gY3VhbmRvIHNlIG11ZXZlIG8gaGFjZSB6b29tXG4gICAgICB0aGlzLm1hcC5vbihcIm1vdmVlbmRcIiwgKCkgPT4gdGhpcy5oYW5kbGVNYXBNb3ZlKCkpO1xuICAgICAgdGhpcy5tYXAub24oXCJ6b29tZW5kXCIsICgpID0+IHRoaXMuaGFuZGxlTWFwTW92ZSgpKTtcbiAgICAgIHRoaXMubWFwLm9uKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgY29uc3QgeyBsbmcsIGxhdCB9ID0gZS5sbmdMYXQ7XG4gICAgICAgI
1HRoaXMubWFya2VyLnNldExuZ0xhdChbbG5nLCBsYXRdKTtcblxuICAgICAgICAvLyBFbWl0aXIgZXZlbnRvIGEgTGl2ZVZpZXcgc2kgbG8gZGVzZWFzXG4gICAgICAgIHRoaXMucHVzaEV2ZW50KFwibWFwX21vdmVkXCIsIHtcbiAgICAgICAgICBsYXQsXG4gICAgICAgICAgbG5nLFxuICAgICAgICAgIHpvb206IE1hdGgucm91bmQodGhpcy5tYXAuZ2V0Wm9vbSgpKVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBoYW5kbGVNYXBNb3ZlKCkge1xuICAgICAgY29uc3QgY2VudGVyID0gdGhpcy5tYXAuZ2V0Q2VudGVyKCk7XG4gICAgICBjb25zdCB6b29tID0gdGhpcy5tYXAuZ2V0Wm9vbSgpO1xuXG4gICAgICAvLyBNb3ZlciBlbCBtYXJjYWRvciBhbCBudWV2byBjZW50cm9cbiAgICAgIHRoaXMubWFya2VyLnNldExuZ0xhdChjZW50ZXIpO1xuXG4gICAgICAvLyBFbWl0aXIgZXZlbnRvIGEgTGl2ZVZpZXdcbiAgICAgIHRoaXMucHVzaEV2ZW50KFwibWFwX21vdmVkXCIsIHtcbiAgICAgICAgbGF0OiBjZW50ZXIubGF0LFxuICAgICAgICBsbmc6IGNlbnRlci5sbmcsXG4gICAgICAgIHpvb206IE1hdGgucm91bmQoem9vbSlcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbiAgVGFiSGlnaGxpZ2h0OiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIHRoaXMuc3RhcnRCbGlua2luZygpXG4gICAgfSxcbiAgICB1cGRhdGVkKCkge1xuICAgICAgdGhpcy5zdGFydEJsaW5raW5nKClcbiAgICB9LFxuICAgIGRlc3Ryb3llZCgpIHtcbiAgICAgIC8vIExpbXBpZXphIGRlIHNlZ3VyaWRhZFxuICAgICAgaWYgKHRoaXMuYmxpbmtJbnRlcnZhbCkge1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMuYmxpbmtJbnRlcnZhbClcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgc3RhcnRCbGlua2luZygpIHtcbiAgICAgIGlmIChkb2N1bWVudC5oYXNGb2N1cygpKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgbGV0IG9yaWdpbmFsVGl0bGUgPSBkb2N1bWVudC50aXRsZVxuICAgICAgbGV0IG5ld1RpdGxlID0gdGhpcy5lbC5kYXRhc2V0LnRpdGxlIHx8IFwiTnVldmEgYWN0dWFsaXphY2nDs25cIlxuXG4gICAgICAvLyBMaW1waWEgY3VhbHF1aWVyIGludGVydmFsbyBhbnRlcmlvclxuICAgICAgaWYgKHRoaXMuYmxpbmtJbnRlcnZhbCkge1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMuYmxpbmtJbnRlcnZhbClcbiAgICAgIH1cblxuICAgICAgY29uc3QgYmxpbmsgPSAoKSA9PiB7XG4gICAgICAgIGRvY3VtZW50LnRpdGxlID0gZG9jdW1lbnQudGl0bGUgPT09IG9yaWdpbmFsVGl0bGUgPyBuZXdUaXRsZSA6IG9yaWdpbmFsVGl0bGVcbiAgICAgIH1cblxuICAgICAgdGhpcy5ibGlua0ludGVydmFsID0gc2V0SW50ZXJ2YWwoYmxpbmssIDEwMDApXG5cbiAgICAgIC8vIERldGVuZXIgY3VhbmRvIHNlIHZ1ZWx2ZSBhIGVuZm9jYXIgbGEgcGVzdGHDsWFcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgKCkgPT4ge1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMuYmxpbmtJbnRlcnZhbClcbiAgICAgICAgZG9jdW1lbnQudGl0bGUgPSBvcmlnaW5hbFRpdGxlXG4gICAgICB9LCB7IG9uY2U6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIENvb3JkaW5hQ29udGVuaWRvOiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdjb250ZW5pZG8tYWN0dWFsaXphbmRvJywgKCkgPT4ge1xuICAgICAgICBjb250ZW5pZG91cGRhdGluZyA9IHRydWU7XG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRlbmlkby1lc3RhYmlsaXphZG8nLCAoKSA9PiB7XG4gICAgICAgIGNvbnRlbmlkb3VwZGF0aW5nID0gZmFsc2U7XG4gICAgICAgIC8vIFJlYW51ZGFyIHByb2Nlc2FtaWVudG8gZGUgcHVibGljaWRhZCBkZXNwdcOpcyBkZSBicmV2ZSBkZWxheVxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBpZiAoIXB1YmxpX2xvY2spIHtcbiAgICAgICAgICAgIHJldWJpY2FyX3B1Ymxpcyh0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIDIwMCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sXG4gIExhenlSZWxhY2lvbmFkYXM6IHtcbiAgICBtb3VudGVkKCkge1xuICAgICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIoKGVudHJpZXMsIG9ic2VydmVyKSA9PiB7XG4gICAgICAgIGVudHJpZXMuZm9yRWFjaChlbnRyeSA9PiB7XG4gICAgICAgICAgaWYgKGVudHJ5LmlzSW50ZXJzZWN0aW5nIHx8IGVudHJ5LmludGVyc2VjdGlvblJhdGlvID4gMCApIHtcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJSRUxBQ0lPTkFEQVNcIik7XG4gICAgICAgICAgICAvLyBOb3RpZmljYXIgaW5pY2lvIGRlIGFjdHVhbGl6YWNpw7NuIGRlIGNvbnRlbmlkb1xuICAgICAgICAgICAgd2luZG93LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KCdjb250ZW5pZG8tYWN0dWFsaXphbmRvJykpO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICB0aGlzLnB1c2hFdmVudChcImNhcmdhci1yZWxhY2lvbmFkYXNcIilcbiAgICAgICAgICAgIHRoaXMucHVzaEV2ZW50KFwiY2FyZ2FyLXBvcnRhZGlsbGFcIilcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gTm90aWZpY2FyIGZpbiBkZSBhY3R1YWxpemFjacOzbiBkZXNwdcOpcyBkZSBwcm9jZXNhbWllbnRvXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgd2luZG93LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KCdjb250ZW5pZG8tZXN0YWJpbGl6YWRvJykpO1xuICAgICAgICAgICAgfSwgMzAwKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgb2JzZXJ2ZXIudW5vYnNlcnZlKGVudHJ5LnRhcmdldCkgLy8gU29sbyB1bmEgdmV6XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfSwge1xuICAgICAgICByb290OiBudWxsLFxuICAgICAgICByb290TWFyZ2luOiBcIjE1MHB4XCIsIC8vIDEwMHB4IGFudGVzIGRlIGVudHJhciBlb
1iB2aXN0YVxuICAgICAgICB0aHJlc2hvbGQ6IDAuMDFcbiAgICAgIH0pXG5cbiAgICAgIG9ic2VydmVyLm9ic2VydmUodGhpcy5lbClcbiAgICB9LFxuICAgIHVwZGF0ZWQoKSB7XG4gICAgICBhcGFuaG9zX3B1YmxpX2Jsb3F1ZV90ZW1hKCk7XG4gICAgfVxuICB9LFxuICBMYXp5UG9ydGFkaWxsYToge1xuICAgIG1vdW50ZWQoKSB7XG4gICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBJbnRlcnNlY3Rpb25PYnNlcnZlcigoZW50cmllcywgb2JzZXJ2ZXIpID0+IHtcbiAgICAgICAgZW50cmllcy5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgICAgICBpZiAoZW50cnkuaXNJbnRlcnNlY3RpbmcgfHwgZW50cnkuaW50ZXJzZWN0aW9uUmF0aW8gPiAwICkge1xuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIlBPUlRBRElMTEFcIik7XG4gICAgICAgICAgICBvYnNlcnZlci51bm9ic2VydmUoZW50cnkudGFyZ2V0KSAvLyBTb2xvIHVuYSB2ZXpcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9LCB7XG4gICAgICAgIHJvb3Q6IG51bGwsXG4gICAgICAgIHJvb3RNYXJnaW46IFwiMTUwcHhcIiwgLy8gMTAwcHggYW50ZXMgZGUgZW50cmFyIGVuIHZpc3RhXG4gICAgICAgIHRocmVzaG9sZDogMC4wMVxuICAgICAgfSlcblxuICAgICAgb2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsKVxuICAgIH1cbiAgfSxcbiAgTWVudVBvc2ljaW9uOiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIGFqdXN0ZV9tZW51X21vdmlsKClcbiAgICB9LFxuICAgIHVwZGF0ZWQoKSB7XG4gICAgICBhanVzdGVfbWVudV9tb3ZpbCgpXG4gICAgfSxcbiAgfSxcbiAgQXV0b0NsZWFyRmxhc2g6IHtcbiAgICBtb3VudGVkKCkge1xuICAgICAgbGV0IGlnbm9yZWRJRHMgPSBbXCJjbGllbnQtZXJyb3JcIiwgXCJzZXJ2ZXItZXJyb3JcIl07XG4gICAgICBpZiAoaWdub3JlZElEcy5pbmNsdWRlcyh0aGlzLmVsLmlkKSkgcmV0dXJuO1xuXG4gICAgICBsZXQgaGlkZUVsZW1lbnRBZnRlciA9IDMwMDA7IC8vIG1zXG4gICAgICBsZXQgY2xlYXJGbGFzaEFmdGVyID0gaGlkZUVsZW1lbnRBZnRlciArIDUwMDsgLy8gbXNcblxuICAgICAgLy8gZmlyc3QgaGlkZSB0aGUgZWxlbWVudFxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZWwuc3R5bGUub3BhY2l0eSA9IDA7XG4gICAgICB9LCBoaWRlRWxlbWVudEFmdGVyKTtcblxuICAgICAgLy8gdGhlbiBjbGVhciB0aGUgZmxhc2hcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnB1c2hFdmVudChcImx2OmNsZWFyLWZsYXNoXCIpO1xuICAgICAgfSwgY2xlYXJGbGFzaEFmdGVyKTtcbiAgICB9LFxuICB9LFxuICBBcGFuaG9Dcm9wOiB7XG4gICAgbW91bnRlZCgpe1xuICAgICAgYXBhbmhvX2Nyb3AoKTtcbiAgICAgIGNvbnNvbGUubG9nKFwiQ1JPUFwiKTtcbiAgICB9LFxuICAgIHVwZGF0ZWQoKXtcbiAgICAgIGFwYW5ob19jcm9wKCk7XG4gICAgICBjb25zb2xlLmxvZyhcIkNST1BcIik7XG4gICAgfSxcbiAgICBiZWZvcmVVcGRhdGUoKSB7XG4gICAgfSxcbiAgICBkZXN0cm95ZWQoKSB7XG4gICAgfSxcbiAgICBkaXNjb25uZWN0ZWQoKSB7XG4gICAgfSxcbiAgICByZWNvbm5lY3RlZCgpIHtcbiAgICB9LFxuICB9LFxuICBBcGFuaG9zQXJ0aWN1bG86IHtcbiAgICBtb3VudGVkKCl7XG4gICAgICBlamVjdXRhZG9zX2VtYmViaWRvcyA9IGZhbHNlO1xuICAgICAgcmV1YmljYXJfcmVzdW1lbmVzX2FydGljdWxvKCk7XG4gICAgICBsYW56YXJfY29kaWdvc19lbWJlYmlkb3MoKTtcbiAgICAgIGFwYW5ob3NfaW1hZ2VuZXNfYXJ0aWN1bG9zKCk7XG4gICAgICAvL3JldWJpY2FyX3B1YmxpcygpO1xuICAgICAgZXNwZXJhckhhc3RhUXVlRXhpc3RhQWx0dXJhTGltaXRhZG9zKCgpID0+IHtcbiAgICAgICAgZWplY3V0YWRvc19saW1pdGFkb3MgPSBmYWxzZTtcbiAgICAgICAgbGltaXRhZG9zKCk7XG4gICAgICB9KTtcbiAgICAgIGNvcGlhcl9hY29ydGFkb3MoKTtcbiAgICAgIGxhbnphcl9zY3JpcHRzKCk7XG4gICAgICBzY3JvbGxfaW50b19pZCgpXG4gICAgICBkb2
1N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHByb2Nlc3NTY3JvbGwpO1xuICAgIH0sXG4gICAgdXBkYXRlZCgpe1xuICAgIC8vY29uc29sZS5sb2coXCJBcnRpY3VsbyBVUERBVEVEXCIpXG4gICAgICBlamVjdXRhZG9zX2VtYmViaWRvcyA9IGZhbHNlO1xuICAgICAgYXBhbmhvc19pbWFnZW5lc19hcnRpY3Vsb3MoKTtcbiAgICAgIC8vbGFuemFyX2NvZGlnb3NfZW1iZWJpZG9zKCk7XG4gICAgICByZXViaWNhcl9yZXN1bWVuZXNfYXJ0aWN1bG8oKTtcbiAgICAgIC8vcmV1YmljYXJfcHVibGlzKHRydWUpO1xuICAgICAgbGFuemFyX3NjcmlwdHMoKTtcbiAgICAgIGVqZWN1dGFkb3NfZW1iZWJpZG9zID0gdHJ1ZTtcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgcHJvY2Vzc1Njcm9sbCk7XG4gICAgICBlc3BlcmFySGFzdGFRdWVFeGlzdGFBbHR1cmFMaW1pdGFkb3MoKCkgPT4ge1xuICAgICAgICBlamVjdXRhZG9zX2xpbWl0YWRvcyA9IGZhbHNlO1xuICAgICAgICBsaW1pdGFkb3MoKTtcbiAgICAgIH0pO1xuICAgICAgYXBhbmhvc19wdWJsaV9ibG9xdWVfdGVtYSgpXG5cbiAgICB9LFxuICB9LFxuICBBcGFuaG9zQ29tZW50YXJpb3M6IHtcbiAgICBtb3VudGVkKCl7XG4gICAgfSxcbiAgICB1cGRhdGVkKCl7XG4gICAgICByZWNvcnRhcl9jb21lbnRhcmlvcygpO1xuICAgICAgc2Nyb2xsX2ludG9faWQodHJ1ZSlcbiAgICB9LFxuICB9LFxuICBTd2lwZXJHYWxlcmlhczoge1xuICAgIHVwZGF0ZWQoKXtcbiAgICAgIHN3aXBlcl9nYWxlcmlhKCk7XG4gICAgICBzd2lwZXJfZ2FsZXJpYV9tb2RhbCgpO1xuICAgIH0sXG4gICAgbW91bnRlZCgpe1xuICAgICAgc3dpcGVyX2dhbGVyaWEoKTtcbiAgICAgIHN3aXBlcl9nYWxlcmlhX21vZGFsKCk7XG4gICAgfSxcbiAgfSxcbiAgQm9ycmFyVG9vbHRpcHM6IHtcbiAgICB1cGRhdGVkKCl7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRlbXB0b29sdGlwJykuc3R5bGUuZGlzcGxheSA9ICdub25lJ1xuICAgICAgfSwgMTUwMCk7IFxuICAgIH0sXG4gICAgbW91bnRlZCgpe1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy50ZW1wdG9vbHRpcCcpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSdcbiAgICAgIH0sIDE1MDApOyBcbiAgICB9LFxuICB9LFxuICBFZGl0b3JTb2NpYXM6IHtcbiAgICB1cGRhdGVkKCl7XG4gICAgICAkKCcuc3VtbWVybm90ZScpLnN1bW1lcm5vdGUoJ2Rlc3Ryb3knKTtcbiAgICAgICQoJy5zdW1tZXJub3RlJykuc3VtbWVybm90ZShzdW1tZXJOb3RlTWluKTtcbiAgICB9LFxuICAgIG1vdW50ZWQoKXtcbiAgICAgICQoJy5zdW1tZXJub3RlJykuc3VtbWVybm90ZSgnZGVzdHJveScpO1xuICAgICAgJCgnLnN1bW1lcm5vdGUnKS5zdW1tZXJub3RlKHN1bW1lck5vdGVNaW4pO1xuICAgIH1cbiAgfSxcbiAgRWRpdG9yOiB7XG4gICAgdXBkYXRlZCgpe1xuICAgICAgJCgnLnN1bW1lcm5vdGUnKS5zdW1tZXJub3RlKCdkZXN0cm95Jyk7XG4gICAgICAkKCcuc3VtbWVybm90ZScpLnN1bW1lcm5vdGUoc3VtbWVyTm90ZUNvbmYpO1xuICAgIH0sXG4gICAgbW91bnRlZCgpe1xuICAgICAgJCgnLnN1bW1lcm5vdGUnKS5zdW1tZXJub3RlKCdkZXN0cm95Jyk7XG4gICAgICAkKCcuc3VtbWVybm90ZScpLnN1bW1lcm5vdGUoc3VtbWVyTm90ZUNvbmYpO1xuICAgIH1cbiAgfSxcbiAgRWRpdG9yTWluaW1vOiB7XG4gICAgbW91bnRlZCgpe1xuICAgICAgdGhpcy5pbml0U3VtbWVyTm90ZSgpO1xuICAgIH0sXG4gICAgdXBkYXRlZCgpe1xuICAgICAgdGhpcy5pbml0U3VtbWVyTm90ZSgpO1xuICAgIH0sXG4gICAgZGVzdHJveWVkKCl7XG4gICAgICB0aGlzLmRlc3Ryb3lTdW1tZXJOb3RlKCk7XG4gICAgfSxcbiAgICBpbml0U3VtbWVyTm90ZSgpe1xuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZWwucXVlcnlTZWxlY3RvcignLnN1bW1lcm5vdGUnKTtcbiAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgIGxldCBjb250ZW5pZG8gPSAnJztcbiAgICAgICAgaWYgKCQoZWxlbWVudCkuZGF0YSgnc3VtbWVybm90ZScpKSB7XG4gICAgICAgICAgY29udGVuaWRvID0gJChlbGVtZW50KS5zdW1tZXJub3RlKCdjb2RlJyk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgICQoZWxlbWVudCkuc3VtbWVybm90ZSgnZGVzdHJveScpO1xuICAgICAgICAkKGVsZW1lbnQpLnN1bW1lcm5vdGUoc3VtbWVyTm90ZU1pbik7XG4gICAgICAgIFxuICAgICAgICBpZiAoY29udGVuaWRvKSB7XG4gICAgICAgICAgJChlbGVtZW50KS5zdW1tZXJub3RlKCdjb2RlJywgY29udGVuaWRvKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgZGVzdHJveVN1bW1lck5vdGUoKXtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoJy5zdW1tZXJub3RlJyk7XG4gICAgICBpZiAoZWxlbWVudCAmJiAkKGVsZW1lbnQpLmRhdGEoJ3N1bW1lcm5vdGUnKSkge1xuICAgICAgICAkKGVsZW1lbnQpLnN1bW1lcm5vdGUoJ2Rlc3Ryb3knKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIE5vdGlmaWNhY2lvbmVzOiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIGNvbnN0IGhvb2sgPSB0aGlzOyBcbiAgICAgIHB1c2hCdXR0b24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtcHVzaC1idG4nKTtcbiAgICAgIGNhbmFsZXNEaXYgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY2FuYWxlcycpO1xuICAgICAgaWYgKCdzZXJ2aWNlV29ya2VyJyBpbiBuYXZpZ2F0b3IgJiYgJ1B1c2hNYW5hZ2VyJyBpbiB3aW5kb3cpIHtcbiAgICAgICAgbmF2aWdhdG9yLnNlcnZpY2VXb3JrZXIucmVnaXN0ZXIoJy9zdy5qcycpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uKHN3UmVnKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ1NlcnZpY2UgV29ya2VyIHJlZ2lzdHJhZG8nKTtcbiAgICAgICAgICBzd1JlZ2lzdHJhdGlvbiA9IHN3UmVnO1xuXG4gICAgICAgICAgaW5pdGlhbGl6ZU5vdGlmaWNhdGlvbnNVSShob29rKTtcblxuICAgICAgICAgI
1HN3UmVnaXN0cmF0aW9uLnB1c2hNYW5hZ2VyLmdldFN1YnNjcmlwdGlvbigpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbihzdWJzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgaG9vay5wdXNoRXZlbnQoXCJzdXNjcml0b1wiLCBzdWJzY3JpcHRpb24pXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZnVuY3Rpb24oZXJyb3IpIHtcbiAgICAgICAgICAvL2NvbnNvbGUuZXJyb3IoJ1NlcnZpY2UgV29ya2VyIEVycm9yJywgZXJyb3IpO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1NlcnZpY2UgV29ya2VyIEVycm9yJyApO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yLm5hbWUpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yLnN0YWNrKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCJOTyBzb3BvcnRhZG9cIik7XG4gICAgICB9XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb25saW5lJywgaGFuZGxlQ29ubmVjdGlvbik7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb2ZmbGluZScsIGhhbmRsZUNvbm5lY3Rpb24pO1xuICAgIC8qXG4gICAgICBjb25zb2xlLmxvZyhOb3RpZmljYXRpb24pO1xuICAgICAgaWYoTm90aWZpY2F0aW9uLnBlcm1pc3Npb24gPT09IFwiZGVmYXVsdFwiKSB7XG4gICAgICBjb25zb2xlLmxvZyhcInBlcm1pc28/Pz9cIik7XG5cbiAgICAgICAgTm90aWZpY2F0aW9uLnJlcXVlc3RQZXJtaXNzaW9uKCk7XG4gICAgICAgLy9zd1JlZ2lzdHJhdGlvbi5wdXNoTWFuYWdlci5nZXRTdWJzY3JpcHRpb24oKVxuICAgICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKFwicGVybWlzbyBzaS4uLi4uPz8/XCIpO1xuXG4gICAgICB9XG4gICAgKi9cbiAgICB9XG4gIH0sXG4gIENvb2tpZUhvb2s6IHtcbiAgICBtb3VudGVkKCkge1xuICAgICAgdGhpcy5oYW5kbGVFdmVudCgnY29va2llX3BvcnRhZGEnLCBhc3luYyAocGFyYW1zKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZmV0Y2goJ2FwaS9jb29raWVfcG9ydGFkYScsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ3Bvc3QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkocGFyYW1zKSxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaChlcnIpIHtcbiAgICAgICAgICBhbGVydChlcnIubWVzc2FnZSA/PyBcIkFuIGVycm9yIG9jY3VycmVkXCIpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH0sICBcbiAgQXVkaW9SYWRpb1NlbGVjY2lvbmFyOiB7XG4gICAgZGVzdHJveWVkKCkge1xuICAgIH0sXG4gICAgbW91bnRlZCgpe1xuICAgICAgLy9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcmVwcm9kdWN0b3JfcmFkaW8nKS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZvXCIpXG4gICAgICBhdWRpb19vcmlnZW4gPSBcImRpcmVjdG9cIjtcbiAgICAgIGlmIChhdWRpby5wYXVzZWQpIHtcbiAgICAgICAgbGl2ZVNvY2tldC5ob29rcy5BdWRpb1BsYXllci5kYXRvc19hdWRpbygpOyBcbiAgICAgIH07XG4gICAgICB0aGlzLmFuaGFkaXJfZXZlbnRvcygpXG4gICAgfSxcbiAgICBhbmhhZGlyX2V2ZW50b3MoKXtcbiAgICAgIHZhciB2aWV3cG9ydFdpZHRoID0gd2luZG93LmlubmVyV2lkdGggfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoO1xuICAgICAgaWYgKHZpZXdwb3J0V2lkdGggIDwgIDc2OSkge1xuICAgICAgICB2Y
1XIgaG95ID0gbmV3IERhdGUoKS5nZXREYXkoKSBcbiAgICAgICAgdGhpcy50b2dnbGVEYXkoaG95KVxuICAgICAgfVxuICAgIH0sXG4gICAgdG9nZ2xlRGF5KGRheSkge1xuICAgICAgdmFyIGRheXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImRheXNcIik7XG4gICAgICB2YXIgZ3JpZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiZ3JpZFwiKTtcbiAgICAgIHZhciBsYWJlbHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwiZGF5XCIpXG4gICAgICBzd2l0Y2ggKGRheSl7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBncmlkLnN0eWxlLnNldFByb3BlcnR5KFwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXCIsXG4gICAgICAgICAgICBcIjNlbSAxMHB4IGNhbGMoMTAwJSAtIDNlbSAtIDEwcHgpIHJlcGVhdCg2LCAwKVwiKVxuICAgICAgICAgIGRheXMuc3R5bGUuc2V0UHJvcGVydHkoXCJncmlkLXRlbXBsYXRlLWNvbHVtbnNcIixcbiAgICAgICAgICAgIFwiM2VtIDEwcHggY2FsYygxMDAlIC0gM2VtIC0gMTBweCkgcmVwZWF0KDYsIDApXCIpXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBkYXlzLnN0eWxlLnNldFByb3BlcnR5KFwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXCIsXG4gICAgICAgICAgICBcIjNlbSAxMHB4IDAgY2FsYygxMDAlIC0gM2VtIC0gMTBweCkgMCAwIDAgMCAwXCIpXG4gICAgICAgICAgZ3JpZC5zdHlsZS5zZXRQcm9wZXJ0eShcImdyaWQtdGVtcGxhdGUtY29sdW1uc1wiLFxuICAgICAgICAgICAgXCIzZW0gMTBweCAwIGNhbGMoMTAwJSAtIDNlbSAtIDEwcHgpIDAgMCAwIDAgMFwiKVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgZGF5cy5zdHlsZS5zZXRQcm9wZXJ0eShcImdyaWQtdGVtcGxhdGUtY29sdW1uc1wiLFxuICAgICAgICAgICAgXCIzZW0gMTBweCAwIDAgY2FsYygxMDAlIC0gM2VtIC0gMTBweCkgMCAwIDAgMFwiKVxuICAgICAgICAgIGdyaWQuc3R5bGUuc2V0UHJvcGVydHkoXCJncmlkLXRlbXBsYXRlLWNvbHVtbnNcIixcbiAgICAgICAgICAgIFwiM2VtIDEwcHggMCAwIGNhbGMoMTAwJSAtIDNlbSAtIDEwcHgpIDAgMCAwIDBcIilcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIGRheXMuc3R5bGUuc2V0UHJvcGVydHkoXCJncmlkLXRlbXBsYXRlLWNvbHVtbnNcIixcbiAgICAgICAgICAgIFwiM2VtIDEwcHggMCAwIDAgY2FsYygxMDAlIC0gM2VtIC0gMTBweCkgMCAwIDBcIilcbiAgICAgICAgICBncmlkLnN0eWxlLnNldFByb3BlcnR5KFwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXCIsXG4gICAgICAgICAgICBcIjNlbSAxMHB4IDAgMCAwIGNhbGMoMTAwJSAtIDNlbSAtIDEwcHgpIDAgMCAwXCIpXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNTpcbiAgICAgICAgICBkYXlzLnN0eWxlLnNldFByb3BlcnR5KFwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXCIsXG4gICAgICAgICAgICBcIjNlbSAxMHB4IDAgMCAwIDAgY2FsYygxMDAlIC0gM2VtIC0gMTBweCkgMCAwXCIpXG4gICAgICAgICAgZ3JpZC5zdHlsZS5zZXRQcm9wZXJ0eShcImdyaWQtdGVtcGxhdGUtY29sdW1uc1wiLFxuICAgICAgICAgICAgXCIzZW0gMTBweCAwIDAgMCAwIGNhbGMoMTAwJSAtIDNlbSAtIDEwcHgpIDAgMFwiKVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgZGF5cy5zdHlsZS5zZXRQcm9wZXJ0eShcImdyaWQtdGVtcGxhdGUtY29sdW1uc1wiLFxuICAgICAgICAgICAgXCIzZW0gMTBweCAwIDAgMCAwIDAgY2FsYygxMDAlIC0gM2VtIC0gMTBweCkgMFwiKVxuICAgICAgICAgIGdyaWQuc3R5bGUuc2V0UHJvcGVydHkoXCJncmlkLXRlbXBsYXRlLWNvbHVtbnNcIixcbiAgICAgICAgICAgIFwiM2VtIDEwcHggMCAwIDAgMCAwIGNhbGMoMTAwJSAtIDNlbSAtIDEwcHgpIDBcIilcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBkYXlzLnN0eWxlLnNldFByb3BlcnR5KFwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXCIsXG4gICAgICAgICAgICBcIjNlbSAxMHB4ICByZXBlYXQoNiwgMCkgY2FsYygxMDAlIC0gM2VtIC0gMTBweClcIilcbiAgICAgICAgICBncmlkLnN0eWxlLnNldFByb3BlcnR5KFwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXCIsXG4gICAgICAgICAgICBcIjNlbSAxMHB4ICByZXBlYXQoNiwgMCkgY2FsYygxMDAlIC0gM2VtIC0gMTBweClcIilcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGFiZWxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxhYmVsc1tpXS5zdHlsZS5zZXRQcm9wZXJ0eShcImhlaWdodFwiLCBcIjBweFwiKVxuICAgICAgICBsYWJlbHNbaV0uc3R5bGUuc2V0UHJvcGVydHkoXCJ2aXNpYmlsaXR5XCIsIFwiaGlkZGVuXCIpXG4gICAgICB9XG4gICAgICBsYWJlbHNbZGF5LTFdLnN0eWxlLnNldFByb3BlcnR5KFwiaGVpZ2h0XCIsIFwiYXV0b1wiKVxuICAgICAgbGFiZWxzW2RheS0xXS5zdHlsZS5zZXRQcm9wZXJ0eShcInZpc2liaWxpdHlcIiwgXCJ2aXNpYmxlXCIpXG4gICAgfVxuICB9LFxuICBMaXN0YWRvUmFkaW86IHtcbiAgICBtb3VudGVkKCl7XG4gICAgICB2Y
1XIgdyA9IHdpbmRvdy5pbm5lcldpZHRoXG4gICAgICAgIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aFxuICAgICAgICB8fCBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoO1xuXG4gICAgICBpZih3ID4gNzY4KXtcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3JlcHJvZHVjdG9yX3JhZGlvJykuY2xhc3NMaXN0LmFkZChcImFjdGl2b1wiKVxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LmFkZChcInJhZGlvXCIpXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QuYWRkKFwib3ZlcmZsb3dfbVwiKVxuICAgICAgfVxuICAgIH0sXG4gIH0sXG4gIEF1ZGlvU2VsZWNjaW9uYXI6IHtcbiAgICBkaXNjb25uZWN0ZWQoKSB7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcmVwcm9kdWN0b3JfcmFkaW8nKS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZvXCIpXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZShcInJhZGlvXCIpXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZShcIm92ZXJmbG93X21cIilcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wbGF5LXBvZGNhc3QnKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUgJztcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QucmVtb3ZlKFwib3ZlcmZsb3dcIilcbiAgICAgIGlmIChhdWRpby5wYXVzZWQpIHtcbiAgICAgICAgYXVkaW9fb3JpZ2VuID0gXCJyZWNvbWVuZGFjaW9uXCI7XG4gICAgICAgIGxpdmVTb2NrZXQuaG9va3MuQXVkaW9QbGF5ZXIuZGF0b3NfYXVkaW8oKTsgXG4gICAgICB9XG4gICAgfSxcbiAgICBkZXN0cm95ZWQoKSB7XG4gICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcmVwcm9kdWN0b3JfcmFkaW8nKS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZvXCIpXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZShcInJhZGlvXCIpXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZShcIm92ZXJmbG93X21cIilcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wbGF5LXBvZGNhc3QnKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUgJztcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QucmVtb3ZlKFwib3ZlcmZsb3dcIilcbiAgICAgIGlmIChhdWRpby5wYXVzZWQpIHtcbiAgICAgICAgYXVkaW9fb3JpZ2VuID0gXCJyZWNvbWVuZGFjaW9uXCI7XG4gICAgICAgIGxpdmVTb2NrZXQuaG9va3MuQXVkaW9QbGF5ZXIuZGF0b3NfYXVkaW8oKTsgXG4gICAgICB9XG4gICAgfSxcbiAgICB1cGRhdGVkKCl7XG4gICAgfSxcbiAgICBtb3VudGVkKCl7XG4gICAgICBjb25zdCB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKTtcbiAgICAgIGNvbnN0IGlzVGVsZWdyYW0gPSB1YS5pbmNsdWRlcygndGVsZWdyYW0nKTtcbiAgICAgIGNvbnN0IGlzTW92aWxlU2FmYXJpID0gdWEuaW5jbHVkZXMoJ21vYmlsZSBzYWZhcmknKTtcblxuICAgICAgYXVkaW9fb3JpZ2VuID0gXCJwb2RjYXN0XCI7XG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wb2RjYXN0LXRpdHVsbycpLmlubmVyVGV4dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdWRpby10aXR1bG8nKS5pbm5lclRleHQ7XG4gICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGxheS1wb2RjYXN0Jykuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGxheS1wb2RjYXN0JykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZXZlbnQpID0+IHsgdGhpcy5zZWxlY2Npb25hcigpOyB9KTtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwicG9kY2FzdC1yYWRpby1ib3RcIikuc3JjID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzZWxlY2Npb25hclwiKS5zcmM7XG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNyZXByb2R1Y3Rvcl9yYWRpbycpLmNsYXNzTGlzdC5hZGQoXCJhY3Rpdm9cIilcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QuYWRkKFwicmFkaW9cIilcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QuYWRkKFwib3ZlcmZsb3dfbVwiKVxuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpLmNsYXNzTGlzdC5yZW1vdmUoXCJvdmVyZmxvd1wiKVxuXG4gICAgICBpZiAoYXVkaW8ucGF1c2VkKSB7XG4gICAgICAgIGxpdmVTb2NrZXQuaG9va3MuQXVkaW9QbGF5ZXIuZGF0b3NfYXVkaW8oKTsgXG4gICAgICB9XG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNyZXByb2R1Y3Rvcl9yYWRpbycpLmNsYXNzTGlzdC5hZGQoXCJhY3Rpdm9cIilcbiAgICB9LFxuICAgIHNlbGVjY2lvbmFyKCkge1xuICAgICAgYXVkaW9fb3JpZ2VuID0gXCJwb2RjYXN0XCI7XG4gICAgICBsaXZlU29ja2V0Lmhvb2tzLkF1ZGlvUGxheWVyLmF1ZGlvX3JlcHJvZHVjaXIoKTsgXG4gICAgfSxcbiAgfSxcbiAgQXVkaW9QbGF5ZXI6IHtcbiAgICBtb3VudGVkKCl7XG4gICAgICAvL3BhcmEgcXVlIG5vIHNlIGN1ZWxxdWUgZWwgVGVsZWdyYW0uLi5cbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ2aXNpYmlsaXR5Y2hhbmdlXCIsICgpID0+IHtcbiAgICAgICAgaWYgKGRvY3VtZW50LmhpZGRlbikge1xuICAgICAgICAgIHdpbmRvdy5hdWRpb1BsYXlpbmdPbkhpZGUgPSBhdWRpbyAmJiAhYXVkaW8ucGF1c2VkO1xuICAgICAgICB9IGVsc2UgaWYgKHdpbmRvdy5hdWRpb1BsYXlpbmdPbkhpZGUgJiYgYXVkaW8gJiYgYXVkaW8ucGF1c2VkKSB7XG4gICAgICAgICAgYXVkaW8ucGxheSgpLmNhdGNoKCgpID0+IHt9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGxheS1idXR0b24ucGxheScpXG4gICAgICAuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZXZlbnQpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuaXNSZXN0cmljdGVkRW52KCkpIHtcbiAgICAgICAgICB0aGlzLm1vc3RyYXJBdmlzb1NhbGlkYSgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYXVkaW9fb3JpZ2VuID09IFwicG9kY2FzdFwiIHx8IGF1ZGlvX29yaWdlbiA9PSBcInJlY29tZW5kYWNpb25cIikge1xuICAgICAgICAgIHRoaXMuYXVkaW9fcmVwcm9kdWNpcigpOyBcbiAgICAgICAgfSBlbHNlICB7XG4gICAgICAgICAgdGhpcy5wbGF5X2RpcmVjdG8oKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wbGF5LWRpcmVjdG8nKVxuICAgICAgLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7IHRoaXMucGxheV9kaXJlY3RvKCk7IH0pO1xuXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGxheS1idXR0b24ucGF1c2UnKVxuICAgICAgLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7IHRoaXMucGF1c2FyKCk7IH0pO1xuXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubXV0ZS1idXR0b24ubXV0ZScpXG4gICAgICAuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZXZlbnQpID0+IHsgdGhpcy5tdXRlYXIoKTsgfSk7XG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tdXRlLWJ1dHRvbi51bm11dGUnKVxuICAgICAgLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7IHRoaXMudW5tdXRlYXIoKTsgfSk7XG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5oYWNpYS1hdHJhcycpXG4gICAgICAgIC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChldmVudCkgPT4geyB0aGlzLnBvc2ljaW9uKC0xMCk7IH0pO1xuXG4gICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcuaGFjaWEtZGVsYW50ZScpXG4gICAgICAgIC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChldmVudCkgPT4geyB0aGlzLnBvc2ljaW9uKDEwKTsgfSk7XG5cbiAgICAgIGF1ZGlvX3Bvc2l0aW9uXG4gICAgICAgIC5hZGRFdmVudExpc3RlbmVyKFwiY2hhbmdlXCIsIChldmVudCkgPT4gIHtcbiAgICAgICAgYXVkaW8uY3VycmVudFRpbWUgPSBhdWRpb19wb3NpdGlvbi52YWx1ZTtcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1vbWVudG8nKS5pbm5lclRleHQgPVxuICAgICAgICAgIHNlZ3VuZG9zX2Ffc3RyaW5nKGF1ZGlvLmN1cnJlbnRUaW1lKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5kYXRvc19hdWRpbygpO1xuICAgIH0sXG4gICAgaXNUZWxlZ3JhbSgpIHtcbiAgICAgIGNvbnN0IHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudCB8fCBcIlwiO1xuICAgICAgcmV0dXJuIC9UZWxlZ3JhbS9pLnRlc3QodWEpO1xuICAgIH0sXG4gICAgaXNXZWJWaWV3KCkge1xuICAgICAgY29uc3QgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50IHx8IFwiXCI7XG5cbiAgICAgIC8vIEFuZHJvaWQgV2ViVmlldyB0w61waWNvXG4gICAgICBjb25zdCBpc0FuZHJvaWRXZWJWaWV3ID0gL3d2fFdlYlZpZXcvaS50ZXN0KHVhKTtcblxuICAgICAgLy8gaU9TIFdlYlZpZXcgKG5vIFNhZmFyaSlcbiAgICAgIGNvbnN0IGlzSU9TV2ViVmlldyA9IC9pUGhvbmV8aVBhZC8udGVzdCh1YSkgJiYgIS9TYWZhcmkvaS50ZXN0KHVhKTtcblxuICAgICAgcmV0dXJuIGlzQW5kcm9pZFdlYlZpZXcgfHwgaXNJT1NXZWJWaWV3O1xuICAgIH0sXG4gICAgaXNSZXN0cmljdGVkRW52KCkge1xuICAgICAgLy9yZXR1cm4gdHJ1ZTtcbiAgICAgIHJldHVybiB0aGlzLmlzVGVsZWdyYW0oKSB8fCB0aGlzLmlzV2ViVmlldygpO1xuICAgIH0sXG4gICAgbW9zdHJhckF2aXNvU2FsaWRhKCkge1xuICAgICAgY29uc3QgbW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImF2aXNvLXRlbGVncmFtXCIpO1xuICAgICAgY29uc3QgbGluayA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYWJyaXItbmF2ZWdhZG9yXCIpO1xuXG4gICAgICAvLyBVUkwgYWN0dWFsXG4gICAgICBsaW5rLmhyZWYgPSB3aW5kb3cubG9jYXRpb24uaHJlZjtcblxuICAgICAgbW9kYWwuY2xhc3NMaXN0LnJlbW92ZShcImhpZGRlblwiKTtcblxuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzZWd1aXItYXF1aVwiKVxuICAgICAgICAub25jbGljayA9ICgpID0+IHtcbiAgICAgICAgICBtb2RhbC5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpO1xuXG4gICAgICAgICAgaWYgKGF1ZGlvX29yaWdlbiA9PSBcInBvZGNhc3RcIiB8fCBhdWRpb19vcmlnZW4gPT0gXCJyZWNvbWVuZGFjaW9uXCIpIHtcbiAgICAgICAgICAgIHRoaXMuYXVkaW9fcmVwcm9kdWNpcigpOyBcbiAgICAgICAgICB9IGVsc2UgIHtcbiAgICAgICAgICAgIHRoaXMucGxheV9kaXJlY3RvKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0sXG4gICAgYXVkaW9fcmVwcm9kdWNpcigpIHtcbiAgICAgIC8vIGVzdGFkbyBhY3R1YWwgYW50ZXMgZGUgY3VhbHF1aWVyIGNhbWJpb1xuICAgICAgbGV0IGlzUmVzdW1lID0gYXVkaW8gJiYgYXVkaW8uc3JjICYmIGF1ZGlvLnBhdXNlZCAmJiBhdWRpby5jdXJyZW50VGltZSA+IDA7XG5cbiAgICAgIGF1ZGlvLnBhdXNlKCk7XG4gICAgICBpZiAoYXVkaW9fb3JpZ2VuID09IFwicG9kY2FzdFwiIHx8IGF1ZGlvX29yaWdlbiA9PSBcInJlY29tZW5kYWNpb25cIikge1xuICAgICAgICB0aGlzLmNlcnJhcl9kYXRvc19kaXJlY3RvKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNvbG8gbGxhbWFyIGEgZGF0b3NfYXVkaW8oKSBwYXJhIG51ZXZhcyBzZWxlY2Npb25lc1xuICAgICAgaWYgKCFpc1Jlc3VtZSkge1xuICAgICAgICB0aGlzLmRhdG9zX2F1ZGlvKCk7XG4gICAgICB9IFxuXG4gICAgICAvLyBhc2VndXJhcm5vcyBxdWUgbGEgZHVyYWNpw7NuIGVzdMOpIGRpc3BvbmlibGVcbiAgICAgIGlmIChhdWRpby5kdXJhdGlvbikge1xuICAgICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcudGllbXBvJykuaW5uZXJUZXh0ID0gc2VndW5kb3NfYV9zdHJpbmcoYXVkaW8uZHVyYXRpb24pO1xuICAgICAgYXVkaW9fcG9zaXRpb24uc2V0QXR0cmlidXRlKFwibWF4XCIsIGF1ZGlvLmR1cmF0aW9uKTtcbiAgICAgIH1cblxuICAgICAgYXVkaW8ucGxheSgpO1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNvbl9zb25pZG8nKS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wbGF5LWJ1dHRvbi5wbGF5Jykuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wbGF5LWJ1dHRvbi5wYXVzZScpLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJztcbiAgICB9LFxuICAgIHBsYXlfZGlyZWN0bygpIHtcbiAgICAgIGF1ZGlvX29yaWdlbiA9IFwiZGlyZWN0b1wiO1xuICAgICAgdGhpcy5hdWRpb19yZXByb2R1Y2lyKCk7XG4gICAgfSxcbiAgICBwYXVzYXIoKSB7XG4gICAgICBhdWRpby5wYXVzZSgpO1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBsYXktYnV0dG9uLnBsYXknKS5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGxheS1idXR0b24ucGF1c2UnKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNvbl9zb25pZG8nKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIH0sXG4gICAgbXV0ZWFyKCkge1xuICAgICAgYXVkaW8udm9sdW1lID0gMDtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tdXRlLWJ1dHRvbi51bm11dGUnKS5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XG4gICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcubXV0ZS1idXR0b24ubXV0ZScpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY29uX3NvbmlkbycpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgfSxcbiAgICB1bm11dGVhcigpIHtcbiAgICAgIC8vYXVkaW8udm9sdW1lID0gdGhpcy5yYW5nZS52YWx1ZS8xMDA7XG4gICAgICBhdWRpby52b2x1bWUgPSA1MC8xMDA7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubXV0ZS1idXR0b24ubXV0ZScpLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJ1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm11dGUtYnV0dG9uLnVubXV0ZScpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY29uX3NvbmlkbycpLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIH0sXG4gICAgZGF0b3NfYXVkaW8oKSB7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcmVwcm9kdWN0b3JfcmFkaW8nKS5jbGFzc0xpc3QuYWRkKGF1ZGlvX29yaWdlbik7XG4gICAgICBzd2l0Y2goYXVkaW9fb3JpZ2VuKSB7XG4gICAgICAgIGNhc2UgXCJyZWNvbWVuZGFjaW9uXCI6XG4gICAgICAgICAgYXVkaW8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNlbGVjY2lvbi1yYWRpb1wiKTtcbiAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubW9kbycpLmlubmVyVGV4dCA9IFwiUmVjb21lbmRhY2nDs25cIjtcbiAgICAgICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc29uYW5kbzEnKS5pbm5lclRleHQgPSBcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zZWxlY2Npb24tdGl0dWxvJykuaW5uZXJUZXh0O1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zb25hbmRvMicpLmlubmVyVGV4dCA9IFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNlbGVjY2lvbi10ZW1hJykuaW5uZXJUZXh0O1xuICAgICAgICAgIHRoaXMuY29udHJvbF90aWVtcG8oKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJwb2RjYXN0XCI6XG4gICAgICAgICAgYXVkaW8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInBvZGNhc3QtcmFkaW8tYm90XCIpO1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tb2RvJykuaW5uZXJUZXh0ID0gXCJQb2RjYXN0XCI7XG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNvbmFuZG8xJykuaW5uZXJUZXh0ID0gXG4gICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXVkaW8tdGl0dWxvJykuaW5uZXJUZXh0O1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zb25hbmRvMicpLmlubmVyVGV4dCA9IFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2F1ZGlvLXRlbWEnKS5pbm5lclRleHQ7XG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI1JhZGlvQm90IC5pbWFnZW4nKS5pbm5lckhUTUwgPSBcIlwiO1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNSYWRpb0JvdCAuaW1hZ2VuJylcbiAgICAgICAgICAgIC5hcHBlbmRDaGlsZChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYXJ0aWN1bG8tY29udGVuaWRvIC5jYWJlY2VyYSAucmVzcG9uc2l2ZWx5LWxhenknKS5jbG9uZU5vZGUodHJ1ZSkpO1xuICAgICAgICAgIHRoaXMuY29udHJvbF90aWVtcG8oKTtcblxuXG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBvZGNhc3QtdGl0dWxvJykuaW5uZXJUZXh0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2F1ZGlvLXRpdHVsbycpLmlubmVyVGV4dDtcbiAgICAgICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGxheS1wb2RjYXN0Jykuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBsYXktcG9kY2FzdCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7IHRoaXMuc2VsZWNjaW9uYXIoKTsgfSk7XG4gICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJwb2RjYXN0LXJhZGlvLWJvdFwiKS5zcmMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNlbGVjY2lvbmFyXCIpLnNyYztcblxuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNyZXByb2R1Y3Rvcl9yYWRpbycpLmNsYXNzTGlzdC5hZGQoXCJhY3Rpdm9cIilcbiAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LmFkZChcInJhZGlvXCIpXG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpLmNsYXNzTGlzdC5hZGQoXCJvdmVyZmxvd19tXCIpXG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpLmNsYXNzTGlzdC5yZW1vdmUoXCJvdmVyZmxvd1wiKVxuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNyZXByb2R1Y3Rvcl9yYWRpbycpLmNsYXNzTGlzdC5hZGQoXCJhY3Rpdm9cIilcblxuICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDogXG4gICAgICAgICAgLy9hdWRpbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiZGlyZWN0by1yYWRpby1ib3RcIik7XG4gICAgICAgICAgLy9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubW9kbycpLmlubmVyVGV4dCA9IFwiUmFkaW8gMjRoXCI7XG4gICAgICAgICAgLy9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc29uYW5kbzEnKS5pbm5lclRleHQgPSBcIlwiO1xuICAgICAgICAgIC8vZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNvbmFuZG8yJykuaW5uZXJUZXh0ID0gXCJcIjtcbi8vXG4gICAgICAgICAgYXVkaW8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNlbGVjY2lvbi1yYWRpb1wiKTtcbiAgICAgICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcubW9kbycpLmlubmVyVGV4dCA9IFwiUmVjb21lbmRhY2nDs25cIjtcbiAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc29uYW5kbzEnKS5pbm5lclRleHQgPSBcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zZWxlY2Npb24tdGl0dWxvJykuaW5uZXJUZXh0O1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zb25hbmRvMicpLmlubmVyVGV4dCA9IFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNlbGVjY2lvbi10ZW1hJykuaW5uZXJUZXh0O1xuICAgICAgICAgIHRoaXMuY29udHJvbF90aWVtcG8oKTtcbiAgICAgIH1cblxuICAgIH0sXG4gICAgZGF0b3NfZGlyZWN0bygpe1xuICAgICAgc29ja2V0X3JhZGlvX2JvdCA9IG5ldyBXZWJTb2NrZXQocmFkaW9ib3RfYXBpKTtcbiAgICAgIHNvY2tldF9yYWRpb19ib3Qub25vcGVuID0gZnVuY3Rpb24oZSkge1xuICAgICAgICBzb2NrZXRfcmFkaW9fYm90LnNlbmQoSlNPTi5zdHJpbmdpZnkoe1wic3Vic1wiOiB7XCJzdGF0aW9uOnNhbHRvXCI6IHt9fX0pKTtcbiAgICAgIH07XG5cbiAgICAgIHNvY2tldF9yYWRpb19ib3Qub25tZXNzYWdlID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IEpTT04ucGFyc2UoZXZlbnQuZGF0YSk7XG4gICAgICAgIGNvbnN0IG5wID0gZGF0YT8ucHViPy5kYXRhPy5ucCB8fCBudWxsO1xuICAgICAgICBpZiAobnApIHtcbiAgICAgICAgICBhdWRpb19tb21lbnRvID0gbnAubm93X3BsYXlpbmcuZWxhcHNlZCAvIG5wLm5vd19wbGF5aW5nLmR1cmF0aW9uICogMTAwICsgXCIlXCJcbiAgICAgICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc29uYW5kbzEnKS5pbm5lclRleHQgPSBcbiAgICAgICAgICAgIG5wLm5vd19wbGF5aW5nLnBsYXlsaXN0LnNwbGl0KFwiIC0gXCIpWzFdIHx8IFwiQ29udGludWlkYWRcIjtcbiAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc29uYW5kbzInKS5pbm5lclRleHQgPSBcbiAgICAgICAgICAgIG5wLm5vd19wbGF5aW5nLnNvbmcudGV4dCArIFwiIHwgXCI7XG4gICAgICAgICAgYXVkaW9fcHJvZ3Jlc28uc3R5bGUuc2V0UHJvcGVydHkoXCItLXByb2dyZXNvXCIsIGF1ZGlvX21vbWVudG8pO1xuICAgICAgICAgIGF1ZGlvX3Bvc2l0aW9uLnZhbHVlID0gbnAubm93X3BsYXlpbmcuZWxhcHNlZDtcbiAgICAgICAgICBhdWRpb19wb3NpdGlvbi5zZXRBdHRyaWJ1dGUoXCJtYXhcIiwgbnAubm93X3BsYXlpbmcuZHVyYXRpb24pXG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRpZW1wbycpLmlubmVyVGV4dCA9XG4gICAgICAgICAgICBzZWd1bmRvc19hX3N0cmluZyhucC5ub3dfcGxheWluZy5kdXJhdGlvbik7XG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1vbWVudG8nKS5pbm5lclRleHQgPVxuICAgICAgICAgICAgc2VndW5kb3NfYV9zdHJpbmcobnAubm93X3BsYXlpbmcuZWxhcHNlZCk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSxcbiAgICBjZXJyYXJfZGF0b3NfZGlyZWN0bygpIHtcbiAgICAgIGlmKHNvY2tldF9yYWRpb19ib3QucmVhZHlTdGF0ZSA9PSBXZWJTb2NrZXQuT1BFTilcbiAgICAgIHNvY2tldF9yYWRpb19ib3QuY2xvc2UoKTtcbiAgICB9LFxuICAgIGNvbnRyb2xfdGllbXBvKCkge1xuICAgICAgLypcbiAgICAgIGF1ZGlvLm9ubG9hZGVkbWV0YWRhdGEgPSBmdW5jdGlvbihlKSB7XG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy50aWVtcG8nKS5pbm5lclRleHQgPVxuICAgICAgICAgIHNlZ3VuZG9zX2Ffc3RyaW5nKGF1ZGlvLmR1cmF0aW9uKTtcbiAgICAgICAgYXVkaW9fcG9zaXRpb24uc2V0QXR0cmlidXRlKFwibWF4XCIsIGF1ZGlvLmR1cmF0aW9uKVxuICAgICAgfTtcbiAgICAgIGF1ZGlvX21vbWVudG8gPSAwO1xuICAgICAgYXVkaW8uYWRkRXZlbnRMaXN0ZW5lcigndGltZXVwZGF0ZScsICgpID0+IHtcbiAgICAgICAgLy8gYWN0dWFsaXphciBwcm9ncmVzbyBVSVxuICAgICAgICBhdWRpb19wb3NpdGlvbi52YWx1ZSA9IGF1ZGlvLmN1cnJlbnRUaW1lO1xuICAgICAgICBhdWRpb19tb21lbnRvID0gYXVkaW8uY3VycmVudFRpbWUgLyBhdWRpby5kdXJhdGlvbiAqIDEwMCArIFwiJVwiO1xuICAgICAgICBhdWRpb19wcm9ncmVzby5zdHlsZS5zZXRQcm9wZXJ0eShcIi0tcHJvZ3Jlc29cIiwgYXVkaW9fbW9tZW50byk7XG4gICAgICB9KTtcbiAgICAgICovXG4gICAgICBpZiAoYXVkaW8uZHVyYXRpb24pIHtcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRpZW1wbycpLmlubmVyVGV4dCA9IHNlZ3VuZG9zX2Ffc3RyaW5nKGF1ZGlvLmR1cmF0aW9uKTtcbiAgICAgIGF1ZGlvX3Bvc2l0aW9uLnNldEF0dHJpYnV0ZShcIm1heFwiLCBhdWRpby5kdXJhdGlvbik7XG4gICAgICB9XG4gICAgICBzZXRJbnRlcnZhbCgoKSA9PiB7IFxuICAgICAgICBpZiAoIWF1ZGlvLnBhdXNlZCAmJiBhdWRpby5kdXJhdGlvbikge1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tb21lbnRvJykuaW5uZXJUZXh0ID1cbiAgICAgICAgICAgIHNlZ3VuZG9zX2Ffc3RyaW5nKGF1ZGlvLmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICBhdWRpb19tb21lbnRvID0gYXVkaW8uY3VycmVudFRpbWUgLyBhdWRpby5kdXJhdGlvbiAqIDEwMCArIFwiJVwiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1vbWVudG8nKS5pbm5lclRleHQgPSBcIjAwOjAwXCJcbiAgICAgICAgICAvL2F1ZGlvX21vbWVudG8gPSAwXG4gICAgICAgIH1cbiAgICAgICAgYXVkaW9fcG9zaXRpb24udmFsdWUgPSBhdWRpby5jdXJyZW50VGltZTtcbiAgICAgICAgYXVkaW9fcHJvZ3Jlc28uc3R5bGUuc2V0UHJvcGVydHkoXCItLXByb2dyZXNvXCIsIGF1ZGlvX21vbWVudG8pO1xuICAgICAgfSwgMTAwMCk7IFxuICAgIH0sXG4gICAgcG9zaWNpb24odCkge1xuICAgICAgIGF1ZGlvLmN1cnJlbnRUaW1lID0gYXVkaW8uY3VycmVudFRpbWUgKyB0O1xuICAgIH0sXG4gIH0sXG4gIFZpZHN0YWNrSG9vazoge1xuICAgIG1vdW50ZWQoKSB7XG4gICAgICBsZXQgY3VycmVudEVsID0gdGhpcy5lbDtcbiAgICAgIC8vY29uc29sZS5sb2coXCJWaWRzdGFja0hvb2sgbW91bnRlZFwiKTtcbiAgICAgIHZhciBwbGF5ZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdtZWRpYS1wbGF5ZXInKTtcbiAgICAgIC8vY29uc29sZS5sb2cocGxheWVyKTsgICAgICAgICAgICAgIFxuICAgIH0sXG4gICAgYmVmb3JlVXBkYXRlKCkge30sXG4gICAgdXBkYXRlZCgpIHtcbiAgICAgICAgLy9jb25zb2xlLmxvZyhcIlZpZHN0YWNrSG9vayB1cGRhdGVkXCIpO1xuICAgIH0sXG4gICAgZGVzdHJveWVkKCkge30sXG4gICAgZGlzY29ubmVjdGVkKCkge30sXG4gICAgcmVjb25uZWN0ZWQoKSB7fSxcbiAgfSxcbiAgLi4uTGl2ZVNlbGVjdFxufVxubGV0IGxpdmVTb2NrZXQgPSBuZXcgTGl2ZVNvY2tldCgnL2xpdmUnLCBTb2NrZXQsIHtcbiAgaG9va3MsXG4gIGRvbToge1xuICAgIC8vIG1ha2UgTGl2ZVZpZXcgd29yayBuaWNlbHkgd2l0aCBhbHBpbmVqc1xuICAgIG9uQmVmb3JlRWxVcGRhdGVkKGZyb20sIHRvKSB7XG4gICAgICAvL2lmIChmcm9tLl9feCkge1xuICAgICAgaWYgKGZyb20uX3hfZGF0YVN0YWNrKSB7XG4gICAgICAgIC8vd2luZG93LkFscGluZS5jbG9uZShmcm9tLl9feCwgdG8pO1xuICAgICAgICB3aW5kb3cuQWxwaW5lLmNsb25lKGZyb20sIHRvKTtcbiAgICAgIH1cbiAgICB9LFxuICB9LFxuICBwYXJhbXM6IHtfY3NyZl90b2tlbjogY3NyZlRva2VufSxcbn0pO1xuXG5mdW5jdGlvbiBlc3BlcmFySGFzdGFRdWVFeGlzdGFBbHR1cmFMaW1pdGFkb3MoY2FsbGJhY2spIHtcbiAgY29uc3QgY2hlY2sgPSAoKSA9PiB7XG4gICAgY29uc3QgZWxlbXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmxpbWl0YWRvXCIpO1xuXG4gICAgaWYgKCFlbGVtcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybi
1ByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoY2hlY2spO1xuICAgIH1cblxuICAgIC8vIEVzcGVyYXIgYSBxdWUgc2Nyb2xsSGVpZ2h0IHkgY2xpZW50SGVpZ2h0IHNlYW4gPiAwXG4gICAgY29uc3QgbGlzdG8gPSBbLi4uZWxlbXNdLmV2ZXJ5KGVsID0+IGVsLnNjcm9sbEhlaWdodCA+IDAgJiYgZWwuY2xpZW50SGVpZ2h0ID4gMCk7XG5cbiAgICBpZiAobGlzdG8pIHtcbiAgICAgIGNhbGxiYWNrKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShjaGVjayk7XG4gICAgfVxuICB9O1xuICBjaGVjaygpO1xufVxuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBoeDpwYWdlLWxvYWRpbmctc3RhcnRcIiwgXG4gIGZ1bmN0aW9uKGluZm8peyBcbiAgICBOUHJvZ3Jlc3Muc3RhcnQoKTtcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYm9keVwiKS5jbGFzc0xpc3QucmVtb3ZlKFwib3ZlcmZsb3dcIik7XG4gICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjbWVudS1idXItY29udGVuZWRvclwiKSl7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI21lbnUtYnVyLWNvbnRlbmVkb3JcIikuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2b1wiKTtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjbWVudS1idXItY29udGVuZWRvclwiKS5jbGFzc0xpc3QucmVtb3ZlKFwic2Nyb2xsLW9mZlwiKTtcbiAgICB9XG4gICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjbWVudS1wZXJzb25hbC1jb250ZW5lZG9yXCIpKXtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjbWVudS1wZXJzb25hbC1jb250ZW5lZG9yXCIpLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3Rpdm9cIik7XG4gICAgfVxuICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI21lbnUtYWRtaW5cIikpe1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNtZW51LWFkbWluXCIpLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3Rpdm9cIik7XG4gICAgfVxuICB9KVxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJwaHg6cGFnZS1sb2FkaW5nLXN0b3BcIiwgXG4gIGZ1bmN0aW9uKGluZm8peyBcbiAgICAvL2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJib2R5XCIpLmNsYXNzTGlzdC5yZW1vdmUoXCJvdmVyZmxvd19tXCIpO1xuICAgIC8vZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImJvZHlcIikuY2xhc3NMaXN0LnJlbW92ZShcInJhZGlvXCIpO1xuICAgIFxuICAgIG1vZHVsb3NfcHVibGkgPSBtb2R1bG9zX3B1YmxpX2luaWNpYWxlcztcbiAgICBjYW1iaW8oKTtcbiAgICBjYW1iaW9fYXBhbmhvcygpO1xuICAgIGFwYW5ob3NfaW1hZ2VuZXNfYXJ0aWN1bG9zKCk7XG4gICAgYXBhbmhvX2Nyb3AoKTtcbiAgICByZXViaWNhcl9wdWJsaXModHJ1ZSk7XG4gICAgTlByb2dyZXNzLmRvbmUoKTtcbiAgICByZXNwb25zaXZlbHlMYXp5LnJ1bigpO1xuICAgIHViaWNhY2lvbl9iYW5kYV9pbmZlcmlvcigpO1xuXG4gICAgc2Nyb2xsSGFuZGxlcigpO1xuICAgIGlmICgkKCcudHdpdHRlci10d2VldCcpLmxlbmd0aCkge1xuICAgICAgLy8kLmdldFNjcmlwdCgnLy9wbGF0Zm9ybS50d2l0dGVyLmNvbS93aWRnZXRzLmpzJyxmdW5jdGlvbigpe30pO1xuICAgIH07XG5cbiAgICBzY3JvbGxfaW50byA9IHRydWU7XG4gICAgLy9zY3JvbGxfaW50b19pZCgpXG4gIH1cbilcblxudmFyIHNjcm9sbF9pbnRvID0gdHJ1ZTtcbmZ1bmN0aW9uIHNjcm9sbF9pbnRvX2lkKHBhcmFyID0gZmFsc2Upe1xuICBpZihwYXJhcil7XG4gICAgaWYodHJ1ZSB8fCBzY3JvbGxfaW50byA9PT0gdHJ1ZSkge1xuICAgICAgdmFyIGlkID0gd2luZG93LmxvY2F0aW9uLmhhc2guc3Vic3RyaW5nKDEpO1xuICAgICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKSl7XG4gICAgICAgIGlmKGlkLmluY2x1ZGVzKFwiY29tZW50YXJpb1wiKSl7XG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpLmNsYXNzTGlzdC5hZGQoXCJvdmVyZmxvd1wiKVxuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNjb21lbnRhcmlvcycpLmNsYXNzTGlzdC5hZGQoXCJhY3Rpdm9cIilcbiAgICAgICAgfVxuICAgICAgICBkb2
1N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuc2Nyb2xsSW50b1ZpZXcoeyBiZWhhdmlvcjogJ3Ntb290aCcgfSk7XG4gICAgICB9XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZShcIm92ZXJmbG93LWhpZGRlblwiKVxuICAgICAgLy9oaXN0b3J5LnJlcGxhY2VTdGF0ZShudWxsLCBudWxsLCAnICcpO1xuICAgICAgLy9oaXN0b3J5LnJlcGxhY2VTdGF0ZSgnJywgZG9jdW1lbnQudGl0bGUsIHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNwbGl0KCcjJylbMF0pOyBcbiAgICAgIHNjcm9sbF9pbnRvID0gZmFsc2VcbiAgICB9XG4gIH1cbn1cbi8vIGNvbm5lY3QgaWYgdGhlcmUgYXJlIGFueSBMaXZlVmlld3Mgb24gdGhlIHBhZ2VcbmxpdmVTb2NrZXQuY29ubmVjdCgpXG5cbi8vIGV4cG9zZSBsaXZlU29ja2V0IG9uIHdpbmRvdyBmb3Igd2ViIGNvbnNvbGUgZGVidWcgbG9ncyBhbmQgbGF0ZW5jeSBzaW11bGF0aW9uOlxuLy8gPj4gbGl2ZVNvY2tldC5lbmFibGVEZWJ1ZygpXG4vL2xpdmVTb2NrZXQuZW5hYmxlRGVidWcoKVxuLy8gPj4gbGl2ZVNvY2tldC5lbmFibGVMYXRlbmN5U2ltKDEwMDApICAvLyBlbmFibGVkIGZvciBkdXJhdGlvbiBvZiBicm93c2VyIHNlc3Npb25cbi8vID4+IGxpdmVTb2NrZXQuZGlzYWJsZUxhdGVuY3lTaW0oKVxud2luZG93LmxpdmVTb2NrZXQgPSBsaXZlU29ja2V0XG4vL2NvbnNvbGUubG9nKGxpdmVTb2NrZXQpXG5cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBmdW5jdGlvbiAoKSB7XG4gIC8vYXBhbmhvc19pbWFnZW5lc19hcnRpY3Vsb3MoKTtcbiAgLy9yZXViaWNhcl9wdWJsaXMoKTsgLy9ldml0YW1vcyBwZWRpciBsYXRlcmFsZXMgYWwgcHJpbmNpcGlvXG4gIGNhbWJpb19hcGFuaG9zKCk7XG4gIC8vc29jaWFsKCk7XG4gIGFwYW5ob3NfbWVudXMoKTtcbiAgLy90cmlnZ2Vyc19tZW51c19tb2IoKTtcbiAgc2Nyb2xsSGFuZGxlcigpO1xuICAvL2xlY3R1cmFzX2N1ZW50ZW8oKTtcbiAgLy9zZXRJbnRlcnZhbChmdW5jdGlvbigpIHtyZXNwb25zaXZlbHlMYXp5LnJ1bigpOyBhcGFuaG9zX2ltYWdlbmVzX2FydGljdWxvcygpfSwgMzAwKTtcbiAgc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7cmVzcG9uc2l2ZWx5TGF6eS5ydW4oKX0sIDMwMCk7XG4gIHNldEludGVydmFsKGZ1bmN0aW9uKCkge3Njcm9sbEhhbmRsZXIoKX0sIDUwMCk7XG5cbiAgdmFyIHN3ID0gdHJ1ZTtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgZnVuY3Rpb24oKSB7XG4gICAgaWYgKHN3KSB7XG4gICAgICBzdyA9IGZhbHNlO1xuICAgICAgc2V0VGltZW91dChcbiAgICAgICAgZnVuY3Rpb24oKXtcbiAgICAgICAgICBzY3JvbGxIYW5kbGVyKCk7IFxuICAgICAgICAgIHN3ID0gdHJ1ZVxuICAgICAgICB9LCAzMDApO1xuICAgIH1cbiAgfSk7XG4gIGlmICh0eXBlb2YgICQoJy5saW5rcGRmJykuZmFuY3lib3ggPT09IFwiZnVuY3Rpb25cIikgeyBcbiAgICAkKFwiLmxpbmtwZGZcIikuZmFuY3lib3goe1xuICAgICAgdHlwZTogXCJpZnJhbWVcIlxuICAgIH0pOyBcbiAgfSBcbiAgaWYgKCQoJy5hcnRpY3Vsby5zaG93IC50d2l0dGVyLXR3ZWV0JykubGVuZ3RoIHx8ICQoJy5hcnRpY3Vsby5zZWFyY2ggLnR3aXR0ZXItdHdlZXQnKS5sZW5ndGgpe1xuICAgIC8vJC5nZXRTY3JpcHQoJy8vcGxhdGZvcm0udHdpdHRlci5jb20vd2lkZ2V0cy5qcycsZnVuY3Rpb24oKXt9KTtcbiAgfVxufSwgZmFsc2UpO1xuXG5jb25zdCBvblNjcm9sbFN0b3AgPSBjYWxsYmFjayA9PiB7XG4gIGxldCBpc1Njcm9sbGluZztcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgJ3Njcm9sbCcsXG4gICAgZSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQoaXNTY3JvbGxpbmcpO1xuICAgICAgaXNTY3JvbGxpbmcgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgIH0sIDc1MCk7XG4gICAgfSxcbiAgICBmYWxzZVxuICApO1xufTtcblxub25TY3JvbGxTdG9wKCgpID0+IHtcbiAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuYmFuZGEtcG9ydGFkYVwiKSl7XG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5iYW5kYS1wb3J0YWRhXCIpLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCJcbiAgfSBcbn0pXG5cbmZ1bmN0aW9uIHNjcm9sbEhhbmRsZXIoKXtcbiAgc3ViaXJfb19iYWphcigpO1xuICAvL3NvY2lhbCgpO1xuICBoZWFkZXJfZW5fc3RpY2t5KCk7XG4gIHZlcl9iYXJyYV9wcm9ncmVzbygpO1xuICBhcGFuaG9zX21lbnVzKCk7XG4gIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYm9keTpub3QoLmZvcm11bGFyaW8pOm5vdCguZWRpdClcIikpe1xuICAgICAgY29tcHJvYmFyX3B1YmxpX3Zpc2libGUoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhanVzdGVfbWVudV9tb3ZpbCgpe1xuICB2YXIgcG9zaWNpb24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI01lbnVQb3NpY2lvblwiKTtcbiAgcG9zaWNpb24gPSBcIi5tZW51X3pvbmFfc29jaWFzX21vYmlsIC5tX1wiICsgcG9zaWNpb24uZGF0YXNldC5wb3NpY2lvbjtcbiAgdmFyIG0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHBvc2ljaW9uKTtcbiAgaWYgKG0gJiYgIW0uY2xhc3NMaXN0LmNvbnRhaW5zKFwiYWN0aXZvXCIpKXtcbiAgICBtLmNsYXNzTGlzdC5hZGQoXCJhY3Rpdm9cIik7XG4gICAgbS5zY3JvbGxMZWZ0ID0gMjA7XG4gICAgdmFyIHggPSBtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLng7XG4gICAgaWYgKHg+MSl7XG4gICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLm1lbnVfem9uYV9zb2NpYXNfbW9iaWwgLm1lbnVfY29udGFpbmVyXCIpLnNjcm9sbExlZnQgPSB4O1xuICAgIH1cbiAgfVxufVxuXG4vLyBQVUJMSVxudmFyIGV4dHJhXzEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYXJ0aWN1bG8tY29udGVuaWRvIC5jb2wtZXh0cmEgLnB1YmxpY2lkYWRlcycpO1xudmFyIGV4dHJhXzIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucG9ydGFkYS1wb3J0YWRpbGxhIC5jb2wtZXh0cmEnKTtcblxudmFyIGxhdGVyYWxfMSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNsYXRlcmFsLTEtY29udGFpbmVyJyk7XG52YXIgbGF0ZXJhbF8yID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtMi1jb250YWluZXInKTtcbnZhciBsYXRlcmFsXzMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjbGF0ZXJhbC0zLWNvbnRhaW5lcicpO1xudmFyIGxhdGVyYWxfNCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNsYXRlcmFsLTQtY29udGFpbmVyJyk7XG52YXIgbGF0ZXJhbF81ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtNS1jb250YWluZXInKTtcblxuZnVuY3Rpb24gYWN0dWFsaXphcl9ibG9xdWVzX2FudW5jaW9zKCl7XG4gIGV4dHJhXzEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYXJ0aWN1bG8tY29udGVuaWRvIC5jb2wtZXh0cmEgLnB1YmxpY2lkYWRlcycpO1xuICBleHRyYV8yID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBvcnRhZGEtcG9ydGFkaWxsYSAuY29sLWV4dHJhJyk7XG5cbiAgbGF0ZXJhbF8xID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtMS1jb250YWluZXInKTtcbiAgbGF0ZXJhbF8yID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtMi1jb250YWluZXInKTtcbiAgbGF0ZXJhbF8zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtMy1jb250YWluZXInKTtcbiAgbGF0ZXJhbF80ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtNC1jb250YWluZXInKTtcbiAgbGF0ZXJhbF81ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtNS1jb250YWluZXInKTtcbiAgbGF0ZXJhbF81ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtNS1jb250YWluZXInKTtcbn1cblxudmFyIGFudW5jaW9zX3JldWJpY2FyID0gW1xuICBcImxhdGVyYWwtMVwiLFwibGF0ZXJhbC0yXCIsXCJjZW50cmFsLWdyYW5kZVwiLFxuICBcIm9waW5pb24tMVwiLFwib3Bpbmlvbi0yXCIsXCJvcGluaW9uLTNcIixcbiAgXCJsYXRlcmFsLTNcIixcImxhdGVyYWwtNFwiLFwiY2VudHJhbC1ncmFuZGUtMlwiLFxuICBcImJham8tMVwiLFwiYmFqby0yXCIsXCJiYWpvLTNcIixcImxhdGVyYWwtNVwiXG5dO1xuXG5mdW5jdGlvbiByZXViaWNhcl9wdWJsaXNfZXNjcml0b3Jpbygpe1xuICB2YXIgbGF0ZXJhbF8xX3AgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImxhdGVyYWwtMVwiKTtcbiAgdmFyIGxhdGVyYWxfMl9wID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJsYXRlcmFsLTJcIik7XG4gIHZhciBsYXRlcmFsXzNfcCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibGF0ZXJhbC0zXCIpO1xuICB2YXIgbGF0ZXJhbF80X3AgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImxhdGVyYWwtNFwiKTtcbiAgdmFyIGxhdGVyYWxfNV9wID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJsYXRlcmFsLTVcIik7XG4gIGxhdGVyYWxfMSAhPSBudWxsICYmIGxhdGVyYWxfMV9wICE9IG51bGwgPyBsYXRlcmFsXzEuYXBwZW5kQ2hpbGQobGF0ZXJhbF8xX3ApOiBmYWxzZTtcbiAgbGF0ZXJhbF8yICE9IG51bGwgJiYgbGF0ZXJhbF8yX3AgIT0gbnVsbCA/IGxhdGVyYWxfMi5hcHBlbmRDaGlsZChsYXRlcmFsXzJfcCk6IGZhbHNlO1xuICBsYXRlcmFsXzMgIT0gbnVsbCAmJiBsYXRlcmFsXzNfcCAhPSBudWxsID8gbGF0ZXJhbF8zLmFwcGVuZENoaWxkKGxhdGVyYWxfM19wKTogZmFsc2U7XG4gIGxhdGVyYWxfNCAhPSBudWxsICYmIGxhdGVyYWxfNF9wICE9IG51bGwgPyBsYXRlcmFsXzQuYXBwZW5kQ2hpbGQobGF0ZXJhbF80X3ApOiBmYWxzZTtcbiAgbGF0ZXJhbF81ICE9IG51bGwgJiYgbGF0ZXJhbF81X3AgIT0gbnVsbCA/IGxhdGVyYWxfNS5hcHBlbmRDaGlsZChsYXRlcmFsXzVfcCk6IGZhbHNlO1xuICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJhbnVuY2lvcy1vcGluaW9uXCIpKXtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImFudW5jaW9zLW9waW5pb25cIilcbiAgICAgIC5hcHBlbmRDaGlsZChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIm9waW5pb24tMVwiKSk7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJhbnVuY2lvcy1vcGluaW9uXCIpXG4gICAgICAuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJvcGluaW9uLTJcIikpO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYW51bmNpb3Mtb3BpbmlvblwiKVxuICAgICAgLmFwcGVuZENoaWxkKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwib3Bpbmlvbi0zXCIpKTtcbiAgfVxuICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJhbnVuY2lvcy1mb290ZXJcIikpe1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYW51bmNpb3MtZm9vdGVyXCIpXG4gICAgICAuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJiYWpvLTFcIikpO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYW51bmNpb3MtZm9vdGVyXCIpXG4gICAgICAuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJiYWpvLTJcIikpO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYW51bmNpb3MtZm9vdGVyXCIpXG4gICAgICAuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJiYWpvLTNcIikpO1xuICB9XG4gIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNlbnRyYWwtZ3JhbmRlLWNvbnRhaW5lclwiKSl7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJ
1jZW50cmFsLWdyYW5kZS1jb250YWluZXJcIilcbiAgICAgIC5hcHBlbmRDaGlsZChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNlbnRyYWwtZ3JhbmRlXCIpKTtcbiAgfVxuICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJjZW50cmFsLWdyYW5kZS0yLWNvbnRhaW5lclwiKSl7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJjZW50cmFsLWdyYW5kZS0yLWNvbnRhaW5lclwiKVxuICAgICAgLmFwcGVuZENoaWxkKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiY2VudHJhbC1ncmFuZGUtMlwiKSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmV1YmljYXJfcHVibGlzX21vYmlsKCl7XG4gIHZhciBibG9xdWVzID0gZmFsc2VcbiAgdmFyIGNvbnRlbmlkbyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjYXJ0aWN1bG8tY29udGVuaWRvIC5jb2wtY29udGVuaWRvIC5hcnRpY3Vsby10ZXh0by1jb250ZW5pZG9cIik7XG4gIHZhciBjb2JlcnR1cmEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmNvYmVydHVyYVwiKTtcbiAgLy92YXIgcG9ydGFkYSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJtYWluIC5wb3J0YWRhOm5vdCgucG9ydGFkYS1wb3J0YWRpbGxhKVwiKTtcbiAgdmFyIHBvcnRhZGEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwibWFpbiAucG9ydGFkYVwiKTtcblxuICBpZiAoY29udGVuaWRvICYmIHBvcnRhZGEpe1xuICAgIGlmIChjb2JlcnR1cmEubGVuZ3RoPjApe1xuICAgICAgYmxvcXVlcyA9IFsuLi5jb250ZW5pZG8ucXVlcnlTZWxlY3RvckFsbChcIi5jb2JlcnR1cmFcIildLmNvbmNhdChbLi4ucG9ydGFkYS5xdWVyeVNlbGVjdG9yQWxsKFwiLnJlc3VtZW5cIildKVxuICAgIH0gZWxzZSB7XG4gICAgICBibG9xdWVzID0gXG4gICAgICAgIFsuLi5jb250ZW5pZG8ucXVlcnlTZWxlY3RvckFsbChcImRpdjpub3QoLnJlc3VtZW4pOm5vdChibG9ja3F1b3RlKSBwXCIpXVxuICAgICAgICAuY29uY2F0KFsuLi5wb3J0YWRhLnF1ZXJ5U2VsZWN0b3JBbGwoXCIucmVzdW1lblwiKV0pXG4gICAgfVxuICB9XG4gIGlmICghYmxvcXVlcyAmJiBwb3J0YWRhKSB7XG4gICAgIC8vYmxvcXVlcyA9IHBvcnRhZGEucXVlcnlTZWxlY3RvckFsbChcIi5ncmlkIC5jb2x1bW5hXCIpO1xuICAgIGlmICghIGJsb3F1ZXMpe1xuICAgICAgYmxvcXVlcyA9IHBvcnRhZGEucXVlcnlTZWxlY3RvckFsbChcIi5yZXN1bWVuXCIpO1xuICAgIH1cbiAgfVxuICBpZiAoYmxvcXVlcykge1xuICAgIC8vY29uc29sZS5sb2coYmxvcXVlcylcbiAgICBhbnVuY2lvc19yZXViaWNhci5mb3JFYWNoKGZ1bmN0aW9uKGVsZW0sIGluZGljZSwgYXJyYXkpIHtcbiAgICAgIGlmIChibG9xdWVzICYmIGJsb3F1ZXNbMSsyKmluZGljZV0gJiYgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxlbSkpe1xuICAgICAgICAvL2NvbnNvbGUubG9nKGluZGljZSlcbiAgICAgICAgLy9jb25zb2xlLmxvZyhibG9xdWVzW2luZGljZV0pXG4gICAgICAgIC8vY29uc29sZS5sb2coZWxlbSlcbiAgICAgICAgYmxvcXVlc1sxKzIqaW5kaWNlXS5pbnNlcnRBZGphY2VudEVsZW1lbnQoXCJhZnRlcmVuZFwiLGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW0pKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vY29uc29sZS5sb2coXCJETkQ/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/PycnJydcIilcbiAgICAgICAgLy9jb25zb2xlLmxvZyhlbGVtKVxufVxuICAgIH0pXG4gIH1cbn1cbi8vIFZhcmlhYmxlcyBkZSBjb29yZGluYWNpw7NuIGVudHJlIHB1YmxpY2lkYWQgeSBjb250ZW5pZG9cbnZhciBwdWJsaV9sb2NrID0gZmFsc2U7ICAgICAgICAgICAvLyBFdml0YSBtYW5pcHVsYWNpw7NuIHNpbXVsdMOhbmVhXG52YXIgcHVibGlfcGVuZGllbnRlcyA9IFtdOyAgICAgICAgLy8gQW51bmNpb3MgcGVuZGllbnRlcyBkZSBwcm9jZXNhclxudmFyIGNvbnRlbmlkb3VwZGF0aW5nID0gZmFsc2U7ICAgIC8vIEluZGljYSBhY3R1YWxpemFjacOzbiBkZSBjb250ZW5pZG8gTGl2ZVZpZXdcblxudmFyIHJldWJpY2FyX2xhc19wdWJsaXMgPSB0cnVlO1xuZnVuY3Rpb24gcmV1YmljYXJfcHVibGlzKGZvcnphciA9IGZhbHNlKXtcbiAgcmV1YmljYXJfbGFzX3B1YmxpcyA9IGZvcnphciA/IHRydWUgOiByZXViaWNhcl9sYXNfcHVibGlzO1xuICBcbiAgLy8gU2kgaGF5IGNvbnRlbmlkbyBhY3R1YWxpesOhbmRvc2UgeSBubyBlcyBmb3J6YWRvLCBwYXVzYXIgZWplY3VjacOzblxuICBpZiAoY29udGVuaWRvdXBkYXRpbmcgJiYgIWZvcnphcikgcmV0dXJuO1xuICBcbiAgaWYgKHJldWJpY2FyX2xhc19wdWJsaXMgPT09IHRydWUpe1xuICAgIC8vIEVzdGFibGVjZXIgbG9jayBwYXJhIGV2aXRhciBjb25mbGljdG8gY29uIExhenlMb2FkQWRcbiAgICBpZiAoIXB1YmxpX2xvY2spIHtcbiAgICAgIHB1YmxpX2xvY2sgPSB0cnVlO1xuICAgIH1cblxuICAgIGFjdHVhbGl6YXJfYmxvcXVlc19hbnVuY2lvcygpXG5cbiAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5hcnRpY3Vsby1jb250ZW5pZG9cIikpe1xuXG4gICAgICB2Y
1XIgYW51bmNpb19ncmFuZGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNlbnRyYWwtZ3JhbmRlXCIpO1xuXG4gICAgICB2YXIgY29udGVuaWRvID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNhcnRpY3Vsby1jb250ZW5pZG8gLmNvbC1jb250ZW5pZG8gLmFydGljdWxvLXRleHRvLWNvbnRlbmlkb1wiKTtcbiAgICAgIHZhciBjb2JlcnR1cmEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmNvYmVydHVyYVwiKTtcbiAgICAgIHZhciBibG9xdWVzID0gW11cbiAgICAgIGlmIChjb250ZW5pZG8pe1xuICAgICAgICBpZiAoY29iZXJ0dXJhLmxlbmd0aD4wKXtcbiAgICAgICAgICBibG9xdWVzID0gY29udGVuaWRvLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuY29iZXJ0dXJhXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJsb3F1ZXMgPSBjb250ZW5pZG8ucXVlcnlTZWxlY3RvckFsbChcImRpdjpub3QoLnJlc3VtZW4pOm5vdChibG9ja3F1b3RlKTpub3QoLnR3aXR0ZXItdHdlZXQpIHBcIik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGJsb3F1ZSA9IE1hdGguY2VpbChibG9xdWVzLmxlbmd0aC8yKTsgXG4gICAgICAgIGlmIChibG9xdWVzLmxlbmd0aCA+IDEgJiYgYmxvcXVlID4gMyAmJiBhbnVuY2lvX2dyYW5kZSl7XG4gICAgICAgICAgYmxvcXVlc1tibG9xdWVdLmluc2VydEFkamFjZW50RWxlbWVudChcImFmdGVyZW5kXCIsYW51bmNpb19ncmFuZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCQod2luZG93KS53aWR0aCgpPDc2Nyl7IFxuICAgICAgcmV1YmljYXJfcHVibGlzX21vYmlsKCkgXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldWJpY2FyX3B1Ymxpc19lc2NyaXRvcmlvKClcbiAgICB9XG5cbiAgICBpZiAoJCh3aW5kb3cpLndpZHRoKCk+MTAyNCAmJiAhZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5nYWxlcmlhX3RvZG9fYW5jaG9cIikpeyBcbiAgICAgIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXJ0aWN1bG8tY29udGVuaWRvJykpIHtcbiAgICAgICAgdmFyIGFydGljdWxvX3RleHRvcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNhcnRpY3Vsby10ZXh0b3MgLmNvbnRlbmlkbycpO1xuICAgICAgICBcbiAgICAgICAgdmFyIGFsdHVyYV9hcnRpY3VsbyA9IDA7XG4gICAgICAgIGlmIChhcnRpY3Vsb190ZXh0b3MpIHtcbiAgICAgICAgICBhbHR1cmFfYXJ0aWN1bG8gPSBhcnRpY3Vsb190ZXh0b3Muc2Nyb2xsSGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIHZhciBhbHR1cmFfaW5mbyA9IDA7XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuaW5mby1ibG9nJykpIHtcbiAgICAgICAgICBhbHR1cmFfaW5mbyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5pbmZvLWJsb2cnKS5zY3JvbGxIZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5pbmZvLXRlbWEnKSkge1xuICAgICAgICAgIGFsdHVyYV9pbmZvID0gYWx0dXJhX2luZm8gKyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuaW5mby10ZW1hJykuc2Nyb2xsSGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIHZhciBhbHR1cmEgPSBhbHR1cmFfYXJ0aWN1bG8gLSBhbHR1cmFfaW5mbztcbiAgICAgICAgLy92YXIgc3R5bGUgPSBcImhlaWdodDogXCIrYWx0dXJhK1wicHg7IG1heC1oZWlnaHQ6IFwiK2FsdHVyYStcInB4OyBtaW4taGVpZ2h0OiBcIithbHR1cmErXCJweFwiXG4gICAgICAgIC8vdmFyIHN0eWxlID0gXCJcIjtcbiAgICAgICAgXG4gICAgICAgIGlmKGV4dHJhXzEpe1xuICAgICAgICAgIC8vZXh0cmFfMS5zZXRBdHRyaWJ1dGUoXCJzdHlsZVwiLCBzdHlsZSk7XG4gICAgICAgICAgZXh0cmFfMS5zZXRBdHRyaWJ1dGUoXCJwaHgtdXBkYXRlXCIsIFwiaWdub3JlXCIpO1xuICAgICAgICAgIGlmKGV4dHJhXzIpe2V4dHJhXzIuc2V0QXR0cmlidXRlKFwicGh4LXVwZGF0ZVwiLCBcImlnbm9yZVwiKX07XG5cbiAgICAgICAgICBpZiAoYWx0dXJhIDw9IDMwMCl7XG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwibGF0LTBcIik7XG4gICAgICAgICAgICAvLyAwIGVuIGFydGljdWxvIC8gMCArIDJcbiAgICAgICAgICAgIC8vZXh0cmFfMS5yZW1vdmUoKTtcbiAgICAgICAgICAgIC8vZXh0cmFfMS5pbm5lckhUTUwgPSBcIlwiO1xuICAgICAgICAgICAgLy9pZihsYXRlcmFsXzQpeyBsYXRlcmFsXzQucmVwbGFjZVdpdGgobGF0ZXJhbF8xKX1cbiAgICAgICAgICAgIC8vaWYobGF0ZXJhbF81KXsgbGF0ZXJhbF81LnJlcGxhY2VXaXRoKGxhdGVyYWxfMil9XG4gICAgICAgICAgICBpZihsYXRlcmFsXzQgJiYgbGF0ZXJhbF8xKXsgbGF0ZXJhbF80LmFwcGVuZENoaWxkKGxhdGVyYWxfMS5jaGlsZHJlblswXS5jbG9uZU5vZGUodHJ1ZSkpOyB9XG4gICAgICAgICAgICBpZihsYXRlcmFsXzUgJiYgbGF0ZXJhbF8yKXsgbGF0ZXJhbF81LmFwcGVuZENoaWxkKGxhdGVyYWxfMi5jaGlsZHJlblswXS5jbG9uZU5vZGUodHJ1ZSkpOyB9XG4gICAgICAgICAgICBpZihsYXRlcmFsXzEpe1xuICAgICAgICAgICAgICBsYXRlcmFsXzEuY2xhc3NMaXN0LmFkZChcImhpZGRlblwiKTtcbiAgICAgICAgICAgICAgbGF0ZXJhbF8yLmNsYXNzTGlzdC5hZGQoXCJoaWRkZW5cIik7XG4gICAgICAgICAgICAgIGxhdGVyYWxfMy5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpO1xuICAgICAgICAgICAgICBsYXRlcmFsXzQuY2xhc3NMaXN0LmFkZChcImg1MFwiKTtcbiAgICAgICAgICAgICAgbGF0ZXJhbF81LmNsYXNzTGlzdC5hZGQoXCJoNTBcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChhbHR1cmEgPiAzMDAgJiYgYWx0dXJhIDwgMTAwMCl7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcImxhdC0xXCIpO1xuICAgICAgICAgICAgLy8gMSBlbiBhcnRpY3VsbyAvIDEgKyAyXG4gICAgICAgICAgICAvL2V4dHJhXzIucmVwbGFjZUNoaWxkKGxhdGVyYWxfMixsYXRlcmFsXzQpXG4gICAgICAgICAgICAvL2V4dHJhXzIucmVwbGFjZUNoaWxkKGxhdGVyYWxfMyxsYXRlcmFsXzUpXG4gICAgICAgICAgICBpZihsYXRlcmFsXzQgJiYgbGF0ZXJhbF8yKXsgbGF0ZXJhbF80LmFwcGVuZENoaWxkKGxhdGVyYWxfMi5jaGlsZHJlblswXS5jbG9uZU5vZGUodHJ1ZSkpOyB9XG4gICAgICAgICAgICBpZihsYXRlcmFsXzUgJiYgbGF0ZXJhbF8zKXsgbGF0ZXJhbF81LmFwcGVuZENoaWxkKGxhdGVyYWxfMy5jaGlsZHJlblswXS5jbG9uZU5vZGUodHJ1ZSkpOyB9XG4gICAgICAgICAgICBpZihsYXRlcmFsXzEpe1xuICAgICAgICAgICAgICBsYXRlcmFsXzEuY2xhc3NMaXN0LmFkZChcImgxMDBcIik7XG4gICAgICAgICAgICAgIGxhdGVyYWxfMi5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpO1xuICAgICAgICAgICAgICBsYXRlcmFsXzMuY2xhc3NMaXN0LmFkZChcImhpZGRlblwiKTtcbiAgICAgICAgICAgICAgaWYobGF0ZXJhbF80KXtsYXRlcmFsXzQuY2xhc3NMaXN0LmFkZChcImg1MFwiKX07XG4gICAgICAgICAgICAgIGlmKGxhdGVyYWxfNSl7bGF0ZXJhbF81LmNsYXNzTGlzdC5hZGQoXCJoNTBcIil9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgI
1H0gZWxzZSBpZiAoYWx0dXJhID49IDEwMDAgJiYgYWx0dXJhIDwgMjUwMCl7XG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwibGF0LTJcIik7XG4gICAgICAgICAgICAvLyAyIGVuIGFydGljdWxvIC8gMiArIDJcbiAgICAgICAgICAgIC8vaWYobGF0ZXJhbF80ICYmIGxhdGVyYWxfMyl7IGxhdGVyYWxfNC5yZXBsYWNlV2l0aChsYXRlcmFsXzMpfVxuICAgICAgICAgICAgaWYobGF0ZXJhbF81ICYmIGxhdGVyYWxfNCl7IGxhdGVyYWxfNS5hcHBlbmRDaGlsZChsYXRlcmFsXzQuY2hpbGRyZW5bMF0uY2xvbmVOb2RlKHRydWUpKTsgfVxuICAgICAgICAgICAgaWYobGF0ZXJhbF80ICYmIGxhdGVyYWxfMyl7IGxhdGVyYWxfNC5hcHBlbmRDaGlsZChsYXRlcmFsXzMuY2hpbGRyZW5bMF0uY2xvbmVOb2RlKHRydWUpKTsgfVxuICAgICAgICAgICAgLy9pZihsYXRlcmFsXzUpe2xhdGVyYWxfNS5yZW1vdmUoKX1cbiAgICAgICAgICAgIGxhdGVyYWxfMS5jbGFzc0xpc3QuYWRkKFwiaDUwXCIpO1xuICAgICAgICAgICAgbGF0ZXJhbF8yLmNsYXNzTGlzdC5hZGQoXCJoNTBcIik7XG4gICAgICAgICAgICBpZihsYXRlcmFsXzMpe2xhdGVyYWxfMy5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpfTtcbiAgICAgICAgICAgIGlmKGxhdGVyYWxfNCAmJiBsYXRlcmFsXzUpe2xhdGVyYWxfNC5jbGFzc0xpc3QuYWRkKFwiaDUwXCIpfTtcbiAgICAgICAgICAgIGlmKGxhdGVyYWxfNSl7bGF0ZXJhbF81LmNsYXNzTGlzdC5hZGQoXCJoNTBcIil9O1xuICAgICAgICAgIH0gZWxzZSBpZiAoYWx0dXJhID49IDI1MDApe1xuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcImxhdC0zXCIpO1xuICAgICAgICAgICAgLy8gMyBlbiBhcnRpY3VsbyB0b2RvIC8gMyArIDJcbiAgICAgICAgICAgIGxhdGVyYWxfMS5jbGFzc0xpc3QuYWRkKFwiaDMzXCIpO1xuICAgICAgICAgICAgbGF0ZXJhbF8yLmNsYXNzTGlzdC5hZGQoXCJoMzNcIik7XG4gICAgICAgICAgICBsYXRlcmFsXzMuY2xhc3NMaXN0LmFkZChcImgzM1wiKTtcbiAgICAgICAgICAgIGlmKGxhdGVyYWxfNCl7bGF0ZXJhbF80LmNsYXNzTGlzdC5hZGQoXCJoNTBcIil9O1xuICAgICAgICAgICAgaWYobGF0ZXJhbF81KXtsYXRlcmFsXzUuY2xhc3NMaXN0LmFkZChcImg1MFwiKX07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXJ0aWN1bG8tY29udGVuaWRvJykpIHtcbiAgICAgICAgLy92YXIgc3R5bGUgPSBcIlwiXG4gICAgICAgIGlmKGV4dHJhXzEpe1xuICAgICAgICAgIC8vZXh0cmFfMS5zZXRBdHRyaWJ1dGUoXCJzdHlsZVwiLCBzdHlsZSk7XG4gICAgICAgICAgLy9leHRyYV8xLnNldEF0dHJpYnV0ZShcInBoeC11cGRhdGVcIiwgXCJpZ25vcmVcIik7XG4gICAgICAgICAgLy9leHRyYV8yLnNldEF0dHJpYnV0ZShcInBoeC11cGRhdGVcIiwgXCJpZ25vcmVcIik7XG4gICAgICAgICAgaWYobGF0ZXJhbF8xKXtcbiAgICAgICAgICAgIGxhdGVyYWxfMS5jbGFzc0xpc3QucmVtb3ZlKFwiaDMzXCIpO1xuICAgICAgICAgICAgbGF0ZXJhbF8xLmNsYXNzTGlzdC5yZW1vdmUoXCJoNTBcIik7XG4gICAgICAgICAgICBsYXRlcmFsXzEuY2xhc3NMaXN0LnJlbW92ZShcImgxMDBcIik7XG4gICAgICAgICAgICBsYXRlcmFsXzUuY2xhc3NMaXN0LnJlbW92ZShcImhpZGRlblwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYobGF0ZXJhbF8yKXtcbiAgICAgICAgICAgIGxhdGVyYWxfMi5jbGFzc0xpc3QucmVtb3ZlKFwiaDMzXCIpO1xuICAgICAgICAgICAgbGF0ZXJhbF8yLmNsYXNzTGlzdC5yZW1vdmUoXCJoNTBcIik7XG4gICAgICAgICAgICBsYXRlcmFsXzUuY2xhc3NMaXN0LnJlbW92ZShcImhpZGRlblwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYobGF0ZXJhbF8zKXtcbiAgICAgICAgICAgIGxhdGVyYWxfMy5jbGFzc0xpc3QucmVtb3ZlKFwiaDMzXCIpO1xuICAgICAgICAgICAgbGF0ZXJhbF8zLmNsYXNzTGlzdC5yZW1vdmUoXCJoNTBcIik7XG4gICAgICAgICAgICBsYXRlcmFsXzUuY2xhc3NMaXN0LnJlbW92ZShcImhpZGRlblwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYobGF0ZXJhbF80KXtcbiAgICAgICAgICAgIGxhdGVyYWxfNC5jbGFzc0xpc3QucmVtb3ZlKFwiaDUwXCIpO1xuICAgICAgICAgICAgbGF0ZXJhbF81LmNsYXNzTGlzdC5yZW1vdmUoXCJoaWRkZW5cIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmKGxhdGVyYWxfNSl7XG4gICAgICAgICAgICBsYXRlcmFsXzUuY2xhc3NMaXN0LnJlbW92ZShcImg1MFwiKTtcbiAgICAgICAgICAgIGxhdGVyYWxfNS5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZGVuXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvL2NvbnNvbGUubG9nKFwiUmV1YmljYWRhcyBwdWJsaXNcIilcbiAgICByZXViaWNhcl9sYXNfcHVibGlzID0gZmFsc2VcbiAgXG4gICAgLy8gTGliZXJhciBsb2NrIHkgcHJvY2VzYXIgYW51bmNpb3MgcGVuZGllbnRlc1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgcHVibGlfbG9jayA9IGZhbHNlO1xuICAgICAgcHJvY2VzYXJfcHVibGlfcGVuZGllbnRlcygpO1xuICAgIH0sIDEwMCk7XG4gIH1cbn1cbmZ1bmN0aW9uIGFwYW5ob3NfcHVibGlfYmxvcXVlX3RlbWEoKXtcbiAgaWYgKCQod2luZG93KS53aWR0aCgpPjc2NyAmJiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmluZm8tdGVtYVwiKSl7XG4gICAgbGV0IGggPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmluZm8tdGVtYVwiKS5vZmZzZXRIZWlnaHRcbiAgICBsZXQgaDIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnJlbGFjaW9uYWRhc1wiKS5vZmZzZXRIZWlnaHRcblxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIuaDEwMFwiKS5mb3JFYWNoKGVsID0+IHtcbiAgICAgIGVsLnN0eWxlLmhlaWdodD0gYGNhbGMoMTAwJSAtICR7aH1weCArICR7aDJ9cHgpYDtcbiAgICAgIGVsLnN0eWxlLm1pbkhlaWdodD0gYGNhbGMoMTAwJSAtICR7aH1weCArICR7aDJ9cHgpYDtcbiAgICAgIGVsLnN0eWxlLm1heEhlaWdodD0gYGNhbGMoMTAwJSAtICR7aH1weCArICR7aDJ9cHgpYDtcbiAgICB9KTtcbiAgfVxufVxuXG4vLyBGdW5jacOzbiBwYXJhIHByb2Nlc2FyIGFudW5jaW9zIHBlbmRpZW50ZXMgZGVzcHXDqXMgZGUgbGliZXJhciBsb2Nrc1xuZnVuY3Rpb24gcHJvY2VzYXJfcHVibGlfcGVuZGllbnRlcygpIHtcbiAgaWYgKHB1YmxpX3BlbmRpZW50ZXMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gIFxuICAvL2NvbnNvbGUubG9nKFwiUHJvY2VzYW5kbyBwdWJsaWNpZGFkIHBlbmRpZW50ZTpcIiwgcHVibGlfcGVuZGllbnRlcyk7XG4gIFxuICB3aGlsZSAocHVibGlfcGVuZGllbnRlcy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgbW9k
1dWxvID0gcHVibGlfcGVuZGllbnRlcy5zaGlmdCgpO1xuICAgIGNvbnN0IGVsZW1lbnRvID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgW2RhdGEtbmFtZT1cIiR7bW9kdWxvfVwiXWApO1xuICAgIFxuICAgIGlmIChlbGVtZW50byAmJiAhZWxlbWVudG8uY2xhc3NMaXN0LmNvbnRhaW5zKCdhbnVuY2lvLWFjdGl2bycpKSB7XG4gICAgICAvLyBTaW11bGFyIGV2ZW50byBkZSBpbnRlcnNlY2Npw7NuIHBhcmEgcHJvY2VzYXIgZWwgYW51bmNpb1xuICAgICAgY29uc3QgZXZlbnQgPSBuZXcgRXZlbnQoJ2ludGVyc2VjdCcpO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGV2ZW50LCAnaXNJbnRlcnNlY3RpbmcnLCB7IGdldDogKCkgPT4gdHJ1ZSB9KTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShldmVudCwgJ2ludGVyc2VjdGlvblJhdGlvJywgeyBnZXQ6ICgpID0+IDEgfSk7XG4gICAgICBcbiAgICAgIC8vIERpc3BhcmFyIG1hbnVhbG1lbnRlIGVsIHByb2Nlc2FtaWVudG9cbiAgICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChbZW50cnldKSA9PiB7XG4gICAgICAgIGlmIChlbnRyeS5pc0ludGVyc2VjdGluZykge1xuICAgICAgICAgIGVsZW1lbnRvLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KCdhZC12aXNpYmxlLXRyaWdnZXInLCB7XG4gICAgICAgICAgICBkZXRhaWw6IHsgbW9kdWxvOiBtb2R1bG8gfVxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBvYnNlcnZlci5vYnNlcnZlKGVsZW1lbnRvKTtcbiAgICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIG1vZHVsb3NfcHVibGlfaW5pY2lhbGVzID0gW1wicG9wdXBcIiwgXCJmYWxkb25cIl1cblxudmFyIG1vZHVsb3NfcHVibGkgPSBtb2R1bG9zX3B1YmxpX2luaWNpYWxlcyBcblxuZnVuY3Rpb24gY29tcHJvYmFyX3B1YmxpX3Zpc2libGUoKXtcbiAgdmFyIHB1YmxpcyA9IFtdO1xuICB2YXIgbW9kdWxvcyA9IG1vZHVsb3NfcHVibGkuc2xpY2UoMCk7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtb2R1bG9zX3B1YmxpLmxlbmd0aDsgIGkrKyl7XG4gICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG1vZHVsb3NfcHVibGlbaV0pIFxuICAgICAgJiYgdmlzaWJsZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZChtb2R1bG9zX3B1YmxpW2ldKSkpIHtcbiAgICAgIC8vY29uc29sZS5sb2coXCJWSVNJQkxFOiBcIisgbW9kdWxvc19wdWJsaVtpXSk7XG4gICAgICBwdWJsaXMucHVzaChtb2R1bG9zX3B1YmxpW2ldKTtcbiAgICAgIG1vZHVsb3MgPSBtb2R1bG9zLmZpbHRlcihpdGVtID0+IGl0ZW0gIT09IG1vZHVsb3NfcHVibGlbaV0pO1xuICAgIH1cbiAgfVxuICBpZiAocHVibGlzLmxlbmd0aD4wICl7XG4gICAgcGVkaXJfYW51bmNpb3MocHVibGlzKTsgXG4gICAgbW9kdWxvc19wdWJsaSA9IG1vZHVsb3M7XG4gIH1cbn1cblxuZnVuY3Rpb24gc29jaWFsKCl7XG4gIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcGFydGlyUHJpbmNpcGFsJykpIHtcbiAgICBpZiAodmlzaWJsZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcGFydGlyUHJpbmNpcGFsJykpIFxuICAgICAgfHwgdmlzaWJsZSgoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5iYW5uZXItYmxvZ3NcIikpKSkge1xuICAgICAgb2N1bHRhcignLmZpam8gLmNvbXBhcnRpcicpO1xuICAgIH0gZWxzZSB7XG4gICAgICBtb3N0cmFyKCcuZmlqbyAuY29tcGFydGlyJyk7XG4gICAgfVxuICAgIGlmICghdmlzaWJsZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXJ0aWN1bG8tY29udGVuaWRvJykpKSB7XG4gICAgICBvY3VsdGFyKCcuZmlqbyAuY29tcGFydGlyJyk7XG4gICAgfSBcbiAgfSBcbn1cblxuZnVuY3Rpb24gdmVyX2JhcnJhX3Byb2dyZXNvKCl7XG4gIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXJ0aWN1bG8tY29udGVuaWRvJykpIHtcbiAgICBpZiAodmlzaWJsZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhZGVyJykpKSB7XG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmhlYWRlcicpLmNsYXNzTGlzdC5yZW1vdmUoJ2hlYWRlci1vdXQnKVxuICAgIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmhlYWRlcicpLmNsYXNzTGlzdC5hZGQoJ2hlYWRlci1vdXQnKVxuICAgIH1cbiAgfSBcbn1cblxudmFyIHJlbSA9IGZ1bmN0aW9uIChjb3VudCkge1xuICB2YXIgdW5pdCA9ICQoJ2h0bWwnKS5jc3MoJ2ZvbnQtc2l6ZScpO1xuICBpZiAodHlwZW9mIGNvdW50ICE9PSAndW5kZWZpbmVkJyAmJiBjb3VudCA+IDApIHtcbiAgICByZXR1cm4gKHBhcnNlSW50KHVuaXQpICogY291bnQpO1xuICB9XG4gIGVsc2Uge1xuICAgIHJldHVybiBwYXJzZUludCh1bml0KTtcbiAgfVxufVxuXG52YXIgc2Nyb2xsUG9zID0gMDtcbnZhciBwYXJhciA9IDA7XG5mdW5jdGlvbiBzdWJpcl9vX2JhamFyKCkge1xuICB2YXIgYWN0dWFsID0gd2luZG93LnBhZ2VZT2Zmc2V0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxUb3AgfHwgMDtcbiAgdmFyIHN0aWNreV9hY3Rpdm8gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnN0aWNreS1oZWFkZXJcIikgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnN0aWNreS1oZWFkZXJcIikub2Zmc2V0SGVpZ2h0IDogMFxuICB2YXIgaCA9IHN0aWNreV9hY3Rpdm8gKyByZW0oMS4yNSkgXG4gIC8vY29uc29sZS5sb2coYWN0dWFsICtcIiBcIisgc2Nyb2xsUG9zICsgXCIgXCIgKyAoYWN0dWFsIC0gc2Nyb2xsUG9zKSlcbiAgdmFyIGRpZiA9IGFjdHVhbCAtIHNjcm9sbFBvc1xuICAvL2NvbnNvbGUubG9nKGRpZilcbiAgaWYgKGRpZiA8IC00MCkge1xuICAvL2lmIChkaWYgPCAtNDAgJiYgc3RpY2t5X2FjdGl2bykge1xuICAgIC8vY29uc29sZS5sb2coXCJVUFwiKVxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QuYWRkKCd1cCcpXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpLmNsYXNzTGlzdC5yZW1vdmUoJ2Rvd24nKVxuICAgIHBhcmFyID0gMDtcbiAgfSBlbHNlIGlmIChkaWYgPiA0MCApe1xuICAvL30gZWxzZSBpZiAoZGlmID4gNDAgfHwgc3RpY2t5X2FjdGl2byA9PSAwKXtcbiAgICAvL2NvbnNvbGUubG9nKFwiRE9XTlwiKVxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QuYWRkKCdkb3duJylcbiAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZSgndXAnKVxuICAgIHBhcmFyID0gMDtcbiAgfSBlbHNlIHtcbiAgICBpZiAocGFyYXIgPT0gMikge1xuICAgICAgLy9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LmFkZCgndXAnKVxuICAgICAgLy9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZSgnZG93bicpXG4gICAgfVxuICAgIHBhcmFyID0gcGFyYXIgKyAxO1xuICAgIC8vY29uc29sZS5sb2coXCJQQVJBXCIpXG4gIH1cblxuICB2YXIgdyA9IHdpbmRvdy5pbm5lcldpZHRoXG4gICAgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoXG4gICAgfHwgZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aDtcblxuICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi51cC1kb3duXCIpICYmIGRpZiA8IC00MCAmJiBzdGlja3lfYWN0aXZvKSB7XG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi51cC1kb3duXCIpLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCJcbiAgfSBlbHNlIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnVwLWRvd25cIikgJiYgKGRpZiA+IDQwIHx8IHN0aWNreV9hY3Rpdm8gPT0gMCkpe1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIudXAtZG93blwiKS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCJcbiAgfVxuXG4gIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmJhbmRhLXBvcnRhZGFcIikpe1xuICAgIGlmIChzdGlja3lfYWN0aXZvID09IDApe1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5iYW5kYS1wb3J0YWRhXCIpLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCJcbiAgICB9IFxuICAgIGlmIChkaWYgPiA1MCApe1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5iYW5kYS1wb3J0YWRhXCIpLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIlxuICAgIH0gZWxzZSBpZiAoZGlmIDwgLTQwICYmIHN0aWNreV9hY3Rpdm8pIHtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuYmFuZGEtcG9ydGFkYVwiKS5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiXG4gICAgfVxuICB9XG5cbiAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNtZW51LWFycmliYSAuY2FiZWNlcmFkb2JsZVwiKSkge1xuICAgIHZhciBjYWJlY2VyYV8xID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5jYWJlY2VyYV9wb3J0YWRhIC5jYWJlY2VyYWRvYmxlXCIpXG4gICAgdmFyIGNhYmVjZXJhXzIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI21lbnUtYXJyaWJhIC5jYWJlY2VyYWRvYmxlXCIpXG4gICAgdmFyIGVzY29uZGlkYSAgPSBjYWJlY2VyYV8xLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmJvdHRvbSA8IC0xMDBcbiAgICBpZiAoY2FiZWNlcmFfMSAmJiBlc2NvbmRpZGEpIHtcbiAgICAgIGNhYmVjZXJhXzIuY2xhc3NMaXN0LmFkZChcInZpc2libGUtbG9nb1wiKVxuICAgIH0gZWxzZSAge1xuICAgICAgY2FiZWNlcmFfMi5jbGFzc0xpc3QucmVtb3ZlKFwidmlzaWJsZS1sb2dvXCIpXG4gICAgfVxuICB9XG5cbiAgaWYgKHcgPCA3NjkpIHtcbiAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi51cC1kb3duLWFydGljdWxvXCIpKXtcbiAgICAgIGlmICh2aXNpYmxlKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhcnRpY3Vsby10ZXh0b3MnKSkgXG4gICAgICAgICYmICF2aXNpYmxlKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjY29tcGFydGlyUHJpbmNpcGFsIC5jb21wYXJ0aXJcIikpKSB7XG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuaGVhZGVyXCIpLmNsYXNzTGlzdC5hZGQoXCJ1cC1kb3duLWFjdGl2b1wiKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5oZWFkZXJcIikuY2xhc3NMaXN0LnJlbW92ZShcInVwLWRvd24tYWN0aXZvXCIpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIucHVibGktbGF0ZXJhbFwiKSkge1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIucHVibGktbGF0ZXJhbFwiKS5mb3JFYWNoKChsYXRlcmFsKSA9PiB7XG4gICAgICBsYXRlcmFsLnN0eWxlLnRvcCA9IGggKyBcInB4XCJcbiAgICB9KVxuICB9XG4gIHNjcm9sbFBvcyA9IGFjdHVhbCA8PSAwID8gMCA6IGFjdHVhbDtcbn07XG5cbmZ1bmN0aW9uICB1YmljYWNpb25fYmFuZGFfaW5mZXJpb3IoKSB7XG4gIHZhciB3aWR0aCA9ICQod2luZG93KS53aWR0aCgpO1xuICBjb25zdCBwb3J0YWRhX2JpID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBvcnRhZGFfYmknKTtcbiAgaWYgKHBvcnRhZGFfYmkgJiYgd2lkdGg8NzY4KXsgXG4gICAgdmFyIGxvYyA9IGxvY2F0aW9uLnBhdGhuYW1lLnNwbGl0KCcvJyk7XG4gICAgbG9jID0gbG9jLmpvaW4oXCIvXCIpO1xuICAgIGNvbnN0IGJvbGV0aW5lc19iaSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5ib2xldGluZXNfYmknKTtcbiAgICBjb25zdCBtaXNhbHRvX2JpID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1pc2FsdG9fYmknKTtcbiAgICBjb25zdCBndWFyZGFkb3NfYmkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuZ3VhcmRhZG9zX2JpJyk7XG4gICAgc3dpdGNoKGxvYykge1xuICAgICAgY2FzZSBcIi9cIjpcbiAgICAgICAgcG9ydGFkYV9iaS5jbGFzc0xpc3QuYWRkKCdhY3RpdmEnKTtcbiAgICAgICAgYm9sZXRpbmVzX2JpICYmIGJvbGV0aW5lc19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgbWlzYWx0b19iaSAmJiBtaXNhbHRvX2JpLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2YScpO1xuICAgICAgICBndWFyZGFkb3NfYmkgJiYgZ3VhcmRhZG9zX2JpLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2YScpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCIvem9uYS1zb2NpYXMvYm9sZXRpbmVzXCI6XG4gICAgICAgIHBvcnRhZGFfYmkuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZhJyk7XG4gICAgICAgIGJvbGV0aW5lc19iaSAmJiBib2xldGluZXNfYmkuY2xhc3NMaXN0LmFkZCgnYWN0aXZhJyk7XG4gICAgICAgIG1pc2FsdG9fYmkgJiYgbWlzYWx0b19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgZ3VhcmRhZG9zX2JpICYmIGd1YXJkYWRvc19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiL21pLXNhbHRvXCI6XG4gICAgICAgI
1HBvcnRhZGFfYmkuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZhJyk7XG4gICAgICAgIGJvbGV0aW5lc19iaSAmJiBib2xldGluZXNfYmkuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZhJyk7XG4gICAgICAgIG1pc2FsdG9fYmkgJiYgbWlzYWx0b19iaS5jbGFzc0xpc3QuYWRkKCdhY3RpdmEnKTtcbiAgICAgICAgZ3VhcmRhZG9zX2JpICYmIGd1YXJkYWRvc19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiL3pvbmEtc29jaWFzL2FydGljdWxvcy1ndWFyZGFkb3NcIjpcbiAgICAgICAgcG9ydGFkYV9iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgYm9sZXRpbmVzX2JpICYmIGJvbGV0aW5lc19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgbWlzYWx0b19iaSAmJiBtaXNhbHRvX2JpLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2YScpO1xuICAgICAgICBndWFyZGFkb3NfYmkgJiYgZ3VhcmRhZG9zX2JpLmNsYXNzTGlzdC5hZGQoJ2FjdGl2YScpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHBvcnRhZGFfYmkuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZhJyk7XG4gICAgICAgIGJvbGV0aW5lc19iaSAmJiBib2xldGluZXNfYmkuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZhJyk7XG4gICAgICAgIG1pc2FsdG9fYmkgJiYgbWlzYWx0b19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgZ3VhcmRhZG9zX2JpICYmIGd1YXJkYWRvc19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59O1xuZnVuY3Rpb24gcGVkaXJfYW51bmNpb3MobW9kdWxvcykge1xuICAvL2NvbnNvbGUubG9nKFwicGVkaXIgYW51bmNpb3NcIilcbiAgdmFyIHdpZHRoID0gJCh3aW5kb3cpLndpZHRoKCk7XG4gIGlmICh3aWR0aD43NjcpeyB2YXIgbW9iaWwgPSBmYWxzZTsgfSBlbHNlIHsgdmFyIG1vYmlsID0gdHJ1ZTsgfVxuICB2YXIgbG9jID0gbG9jYXRpb24ucGF0aG5hbWUuc3BsaXQoJy8nKS5zbGljZSgxKTtcbiAgY29uc3QgdWJpY2FjaW9uZXNfc2luX3B1YmxpID0gXG4gICAgW1xuICAgICAgXCJpbmZvXCIgLCBcbiAgICAgIFwibWktc2FsdG9cIiAsIFxuICAgICAgXCJ6b25hLXNvY2lhc1wiLCBcbiAgICAgIFwic3VzY3JpYmlyc2VcIiwgXG4gICAgICBcImZvcm11bGFyaW9cIiwgXG4gICAgICBcImN1ZW50YVwiLCBcbiAgICAgIFwiYXJlYS1wZXJzb25hbFwiLCBcbiAgICAgIFwiYWRtaW5cIlxuICAgIF1cbiAgaWYodWJpY2FjaW9uZXNfc2luX3B1YmxpLmluY2x1ZGVzKGxvY1swXSkgJiYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjY3NzX3pvbmFfc29jaWFzXCIpID09IG51bGwpKXtcbiAgICB2YXIgc3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuICAgIHN0eWxlLnNldEF0dHJpYnV0ZShcImlkXCIsIFwiY3NzX3pvbmFfc29jaWFzXCIpO1xuICAgIHN0eWxlLnRleHRDb250ZW50ID0gYFxuICAgICAgI3B1YmxpLWNhYmVjZXJhLFxuICAgICAgLmFudW5jaW8ge1xuICAgICAgICBkaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7XG4gICAgICB9XG4gICAgYDtcbiAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcbiAgICByZXR1cm4gdHJ1ZVxuICB9IGVsc2Uge1xuICAgIGlmICghdWJpY2FjaW9uZXNfc2luX3B1YmxpLmluY2x1ZGVzKGxvY1swXSkgJiYgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNjc3Nfem9uYV9zb2NpYXNcIikpIHtcbiAgICAgIHZhciBjc3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI2Nzc196b25hX3NvY2lhc1wiKTtcbiAgICAgIGNzcy5yZW1vdmUoKVxuICAgIH1cbiAgfVxuICB2YXIgc2x1ZyA9IFwiXCI7XG4gIGlmKGxvY1swXSkgeyBzbHVnID0gbG9jWzBdICsgJy8nfSBcbiAgaWYobG9jWzFdKSB7IHNsdWcgPSBzbHVnICsgbG9jWzFdICsgJy8nIH0gZWxzZSB7c2x1Z307XG4gIGlmKGxvY1swXSA9PSBcInNpbi1wdWJsaWNhclwiKSB7IHNsdWcgPSBsb2NbMV0gKyAnLycgKyBsb2NbMl19IFxuICB2YXIgbm9kbyA9ICQoJ2JvZHknKS5hdHRyKCdpZCcpO1xuICBpZighdWJpY2FjaW9uZXNfc2luX3B1YmxpLmluY2x1ZGVzKGxvY1swXSkpe1xuICAgICQoJ2JvZHknKS5hZGRDbGFzcygnd2FpdCcpO1xuICAgICQuYWpheCh7XG4gICAgICB1cmw6ICcvYXBpLycrIHNsdWcgKydhbnVuY2lvLycgKyBtb2R1bG9zICsgJy8nICsgbm9kbyArICcvJyArIG1vYmlsLFxuICAgICAgdHlwZSA6ICdHRVQnLFxuICAgICAgZGF0YVR5cGU6J2pzb24nLFxuICAgICAgc3VjY2VzcyA6IGZ1bmN0aW9uKGRhdGEpIHsgICAgICAgICAgICAgIFxuICAgICAgICAkKCdib2R5JykucmVtb3ZlQ2xhc3MoJ3dhaXQnKTtcbiAgICAgICAgbW9kdWxvcyA9IGRhdGEuZGF0YTtcbiAgICAgICAgJC5lYWNoKG1vZHVsb3MsZnVuY3Rpb24ocm93KXtcbiAgICAgICAgICB2Y
1XIgbW9kdWxvX3B1YmxpID0gbW9kdWxvc1tyb3ddLm1vZHVsbztcbiAgICAgICAgICB2YXIgbW9kdWxvID0gJChcIiNcIittb2R1bG9fcHVibGkpO1xuICAgICAgICAgIGlmIChtb2R1bG9zW3Jvd10ubWFxdWV0YWNpb24gJiYgbW9kdWxvc1tyb3ddLm1hcXVldGFjaW9uLm5vX3B1YmxpY2lkYWQgPT0gXCJub19wdWJsaWNpZGFkXCIpe1xuICAgICAgICAgICAgbW9kdWxvLmFkZENsYXNzKCdibG9xdWUtYWN0aXZvJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG1vZHVsby5hZGRDbGFzcygnYW51bmNpby1hY3Rpdm8nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbW9kdWxvLmVtcHR5KCk7XG4gICAgICAgICAgbW9kdWxvLmF0dHIoJ3BoeC11cGRhdGUnLFwiaWdub3JlXCIpXG4gICAgICAgICAgaWYgKG1vZHVsb3Nbcm93XS5zY3JpcHQgJiYgbW9kdWxvc1tyb3ddLnNjcmlwdC5sZW5ndGg+MTApe1xuICAgICAgICAgICAgLy8kKG1vZHVsb3Nbcm93XS5zY3JpcHQpLmFwcGVuZFRvKG1vZHVsbyk7XG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgJChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgIC8vICAgICAgICBjb25zb2xlLmxvZyhtb2R1bG9zW3Jvd10uc2NyaXB0KTtcbiAgICAgICAgICAgICAgcG9zdHNjcmliZShtb2R1bG8sbW9kdWxvc1tyb3ddLnNjcmlwdCk7XG4gICAgICAgICAgICAgIHRyeSB7IHBvc3RzY3JpYmUobW9kdWxvLG1vZHVsb3Nbcm93XS5zY3JpcHQpOyB9XG4gICAgICAgICAgICAgIGNhdGNoIChlcnIpIHsgY29uc29sZS5sb2coXCJFcnJvciBhbCBpbnNlcnRhciBzY3JpcHRcIik7fVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC8vZXZhbChtb2R1bG9zW3Jvd10uc2NyaXB0KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy9tb2R1bG8uYWRkQ2xhc3MoJ2FudW5jaW8tYWN0aXZvJyk7XG4gICAgICAgICAgICBpZiAobW9kdWxvc1tyb3ddLmh0bWwgJiYgbW9kdWxvc1tyb3ddLmh0bWwubGVuZ3RoPjEpe1xuICAgICAgICAgICAgICB2Y
1XIgZGl2ID0gXG4gICAgICAgICAgICAgICAgJCgnPGRpdi8+JykuYWRkQ2xhc3MoJ2h0bWwtYW51bicpXG4gICAgICAgICAgICAgICAgLmFwcGVuZFRvKG1vZHVsbyk7XG5cbiAgICAgICAgICAgICAgZGl2LmFwcGVuZChtb2R1bG9zW3Jvd10uaHRtbCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZiAobW9kdWxvc1tyb3ddLnVybF9yZWRpcmVjY2lvbil7XG4gICAgICAgICAgICAgICAgdmFyIHJlZGlyZWNjaW9uID0gbW9kdWxvc1tyb3ddLnVybF9yZWRpcmVjY2lvbjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVkaXJlY2Npb24gPSBcImZhbHNlXCIgXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdmFyIGEgPSAkKCc8YS8+JylcbiAgICAgICAgICAgICAgICAuYXR0cignZGF0YS1hbnVuJyxtb2R1bG9zW3Jvd10uaWQpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2RhdGEtY2xpY2snLHJlZGlyZWNjaW9uKVxuICAgICAgICAgICAgICAgIC5hdHRyKCdocmVmJyxcIi9pcl9hbnVuY2lvL1wiK21vZHVsb3Nbcm93XS5pZCsnLycgKyBtb2JpbCwpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ3RhcmdldCcsJ19ibGFuaycpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2FyaWEtbGFiZWwnLCdwdWJsaWNpZGFkJylcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ2FudW5jaW8tbGluaycpXG4gICAgICAgICAgICAgICAgLmFwcGVuZFRvKG1vZHVsbyk7XG4gICAgICAgICAgICAgIGlmIChtb2R1bG9zW3Jvd10uaW1hZ2VuKXtcbiAgICAgICAgICAgICAgICBpZihtb2R1bG9zW3Jvd10uaW1hZ2VuLnNwbGl0KCcuJykucG9wKCkuc3BsaXQoJz8nKS5zaGlmdCgpID09IFwibXA0XCIpIHsgXG4gICAgICAgICAgICAgICAgICB2Y
1XIgdmlkZW8gPSBcbiAgICAgICAgICAgICAgICAgICAgJCgnPHZpZGVvLz4nKS5hZGRDbGFzcygnbm8tbWVwJylcbiAgICAgICAgICAgICAgICAgICAgLnByb3Aoe2F1dG9wbGF5OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBtdXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgbG9vcDogdHJ1ZX0pXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdzcmMnLG1vZHVsb3Nbcm93XS5pbWFnZW4pXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdhbHQnLGRhdGEudGV4dG8pXG4gICAgICAgICAgICAgICAgICAgIC5hcHBlbmRUbyhhKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgeyBcbiAgICAgICAgICAgICAgICAgIHZhciBpbWcgPSAkKCc8aW1nLz4nKS5hZGRDbGFzcygnJylcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ3NyYycsbW9kdWxvc1tyb3ddLmltYWdlbilcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2FsdCcsZGF0YS50ZXh0bylcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2ZldGNocHJpb3JpdHknLCdoaWdodCcpXG4gICAgICAgICAgICAgICAgICAgIC5hcHBlbmRUbyhhKTtcbiAgICAgICAgICAgICAgICB9IFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChtb2R1bG9zW3Jvd10udXJsX2ltcHJlc2lvbil7XG4gICAgICAgICAgICAgICAgdmFyIHBpeGVsID0gXG4gICAgICAgICAgICAgICAgICAkKCc8aW1nLz4nKS5hZGRDbGFzcygndHJhbnNwYXJlbnQnKVxuICAgICAgICAgICAgICAgICAgLmF0dHIoJ3NyYycsbW9kdWxvc1tyb3ddLnVybF9pbXByZXNpb24ucmVwbGFjZShcIlt0aW1lc3RhbXBdXCIsICtuZXcgRGF0ZSkpXG4gICAgICAgICAgICAgICAgICAuYXR0cignYWx0JyxcIkFkdmVydGlzbWVudFwiKVxuICAgICAgICAgICAgICAgICAgLmF0dHIoJ2JvcmRlcicsXCIwXCIpXG4gICAgICAgICAgICAgICAgICAuYXR0cignaGVpZ2h0JyxcIjFcIilcbiAgICAgICAgICAgICAgICAgIC5hdHRyKCd3aWR0aCcsXCIxXCIpXG4gICAgICAgICAgICAgICAgICAuYXBwZW5kVG8oYSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBwb3B1cCgpO1xuICAgICAgfSxcbiAgICAgIGVycm9yIDogZnVuY3Rpb24ocmVxdWVzdCxlcnJvcilcbiAgICAgIHtcbiAgICAgICAgJCgnYm9keScpLnJlbW92ZUNsYXNzKCd3YWl0Jyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAkKGRvY3VtZW50KS5vbignY2xpY2snLCcuYW51bmNpby1saW5rJywgZnVuY3Rpb24oKSB7XG4gICAgdmFyIHVybCA9ICQodGhpcykuYXR0cihcImRhdGEtY2xpY2tcIik7XG4gICAgaWYgKHVybCAhPSBcImZhbHNlXCIpeyAkLmdldCh1cmwpOyB9XG4gIH0pO1xuXG59XG5cbmZ1bmN0aW9uIHBvcHVwKCkge1xuICBjb25zdCBwb3B1cCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwicG9wdXBcIik7XG4gIGlmIChwb3B1cCAmJiBwb3B1cC5jaGlsZHJlbi5sZW5ndGggIT09IDApIHtcbiAgICBzZXRUaW1lb3V0KFxuICAgICAgZnVuY3Rpb24oKXtcbiAgICAgICAgLy9jb25zdCBtb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibW9kYWwtcG9wdXBcIik7XG4vL2lmIChtb2RhbCkge1xuICAgICAgICAvLyBNb3N0cmFyIGVsIG1vZGFsIG1hbnVhbG1lbnRlIChzaW4gQm9vdHN0cmFwKVxuLy8gICAgICAgIG1vZGFsLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7ICAgICAvLyBvIHVzYSBcImZsZXhcIiBzaSB0dSBDU1MgbG8gcmVxdWllcmVcbiAvLyAgICAgICBtb2RhbC5jbGFzc0xpc3QuYWRkKFwidmlzaWJsZVwiKTsgICAgLy8gb3BjaW9uYWwsIHBvciBzaSB0aWVuZXMgYW5pbWFjaW9uZXMgQ1NTXG4gLy8gICAgIH1cbiAgICAgICAgJCgnI21vZGFsLXBvcHVwJykubW9kYWwoJ3Nob3cnKTtcbiAgICAgICAgY29uc3QgZGF5cyA9IDE7XG4gICAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICBkYXRlLnNldFRpbWUoZGF0ZS5nZXRUaW1lKCkgKyAoZGF5cyoyNCo2MCo2MCoxMDAwKSk7XG4gICAgICAgIGNvbnN0IGV4cGlyZXMgPSBcIjsgZXhwaXJlcz1cIiArIGRhdGUudG9VVENTdHJpbmcoKTtcbiAgICAgICAgY29uc3QgbmFtZSA9IFwiaGFiXCI7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gXCJzYWx0YXJpbmVzXCI7XG4gICAgICAgIGRvY3VtZW50LmNvb2tpZSA9IG5hbWUgKyBcIj1cIiArICh2YWx1ZSB8fCBcIlwiKSAgKyBleHBpcmVzICsgXCI7IHBhdGg9L1wiO1xuICAgICAgfSAsMTAwMDBcbiAgICApO1xuICAgIHBvcHVwLmlkID0gXCJwb3B1cE9GRlwiO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBlZGlyX2FydGljdWxvcyhub2RvLCB0aXBvKSB7XG4gICQoJ2JvZHknKS5hZGRDbGFzcygnd2FpdCcpO1xuICAkLmFqYXgoe1xuICAgIHVybDogJy9hcGkvbGlzdGFyLycgKyBub2RvICsgJy8nICsgdGlwbyxcbiAgICB0eXBlIDogJ0dFVCcsXG4gICAgZGF0YVR5cGU6J2pzb24nLFxuICAgIHN1Y2Nlc3MgOiBmdW5jdGlvbihkYXRhKSB7ICAgICAgICAgICAgICBcbiAgICAgICQoJ2JvZHknKS5yZW1vdmVDbGFzcygnd2FpdCcpO1xuICAgICAgZmFicmljYXJfbWVudV9zZWNjaW9uZXMoZGF0YS5kYXRhLCB0aXBvKTtcbiAgICB9LFxuICAgIGVycm9yIDogZnVuY3Rpb24ocmVxdWVzdCxlcnJvcikge1xuICAgICAgJCgnYm9keScpLnJlbW92ZUNsYXNzKCd3YWl0Jyk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gYXBhbmhvc19tZW51cygpe1xuICB2YXIgdyA9IHdpbmRvdy5pbm5lcldpZHRoXG4gICAgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoXG4gICAgfHwgZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aDtcblxuICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtZW51LWFkbWluXCIpICYmIHcgPiA3NjgpIHtcbiAgICBsZXQgaCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjbWVudS1hZG1pbiAuY29udGFpbmVyXCIpXG4gICAgICAuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgIC5oZWlnaHQ7XG4gICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYW51bmNpby1jYWJlY2VyYVwiKSkge1xuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJhbnVuY2lvLWNhYmVjZXJhXCIpXG4gICAgICAgIC5zdHlsZS5tYXJnaW5Ub3AgPSAgaDtcbiAgICB9XG4gICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJwdWJsaS1sYXRlcmFsXCIpKSB7XG4gICAgICBoID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5Q2xhc3NOYW1lKFwic2VndWltaWVudG9cIilcbiAgICAgICAgLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICAgIC5oZWlnaHQgKyBoO1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5wdWJsaS1sYXRlcmFsXCIpLmZvckVhY2goKGxhdGVyYWwpID0+IHtcbiAgICAgICAgbGF0ZXJhbC5zdHlsZS50b3AgPSBoO1xuICAgICAgfSlcbiAgICB9XG4gI
1H1cbn1cblxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnLmNvbXBhcnRpcl9saW5rJywgZnVuY3Rpb24oKSB7XG59KTtcbiQoZG9jdW1lbnQpLm9uKCdjbGljaycsJy5hbnVuY2lvIGEgb2ZmJywgZnVuY3Rpb24oKSB7XG4gIHZhciBkID0gJCh0aGlzKS5hdHRyKFwiZGF0YS1hbnVuXCIpO1xuICAkLmFqYXgoe1xuICAgIHVybDogJy9hcGkvYW51bmNpby9yZWRpcmVjY2lvbi8nICsgZCxcbiAgICB0eXBlIDogJ1BVVCcsXG4gICAgc3VjY2VzcyA6IGZ1bmN0aW9uKGRhdGEpIHsgICAgICAgICAgICAgIFxuICAgIH0sXG4gIH0pO1xufSk7XG5cbnZhciBzd2lwZXJfc2VjY2lvbiA9IFwiXCI7XG52YXIgd2lkdGggPSAkKHdpbmRvdykud2lkdGgoKTtcbmZ1bmN0aW9uIGNhbWJpbygpeyBcbiAgLy9zb2NpYWwoKTtcbiAgYXBhbmhvc19tZW51cygpO1xuICAvL3Njcm9sbEhhbmRsZXIoKTtcbiAgYXBhbmhvc19pbWFnZW5lc19hcnRpY3Vsb3MoKTtcbn1cbmZ1bmN0aW9uIGFwYW5ob19jcm9wKCl7XG4gIHZhciB3ID0gd2luZG93LmlubmVyV2lkdGhcbiAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGhcbiAgICB8fCBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoO1xuICBpZiAodz43NjggJiYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJ0YWJsZS50YWJsZSAuY3JvcFwiKSB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwidGFibGUudGFibGUgLmNyb3AyXCIpKSkge1xuICAgIHZhciB0YWJsZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJ0YWJsZS50YWJsZVwiKTtcbiAgICB2YXIgY3JvcCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJ0YWJsZS50YWJsZSAuY3JvcFwiKTtcbiAgICB2YXIgY3JvcHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwidGFibGUudGFibGUgLmNyb3AyXCIpO1xuICAgIHZhciBjcm9wMSA9IGNyb3BzWzBdO1xuICAgIHZhciBjcm9wMiA9IGNyb3BzWzFdO1xuICAgIHZhciBhbmNob19jb250ZW5lZG9yXzAgPSB0YWJsZS5wYXJlbnROb2RlLm9mZnNldFdpZHRoO1xuXG4gICAgaWYoY3JvcCl7XG4gICAgICBjcm9wLnN0eWxlLm1heFdpZHRoID0gXCIxMDAlXCI7XG4gICAgICBjcm9wLnN0eWxlLndpZHRoID0gXCIxMDAlXCI7XG4gICAgfVxuICAgIGlmKGNyb3AyKXtcbiAgICAgIGNyb3AyLnN0eWxlLm1heFdpZHRoID0gXCIxMDAlXCI7XG4gICAgICBjcm9wMi5zdHlsZS53aWR0aCA9IFwiMTAwJVwiO1xuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKGFuY2hvX2NvbnRlbmVkb3JfMClcbiAgICB2YXIgYW5jaG9fY29udGVuZWRvciA9IHRhYmxlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLng7XG4gICAgY29uc29sZS5sb2coYW5jaG9fY29udGVuZWRvcilcbiAgICB2YXIgYW5jaG9fdGFibGEgPSB0YWJsZS5vZmZzZXRXaWR0aDtcbiAgICBjb25zb2xlLmxvZyhhbmNob190YWJsYSlcblxuICAgIHZhciBhbmNob19jcm9wID0gMDtcbiAgICBpZihjcm9wKXtcbiAgICAgIGFuY2hvX2Nyb3AgPSBjcm9wLm9mZnNldFdpZHRoO1xuICAgIH1cbiAgICBpZihjcm9wMil7XG4gICAgICBhbmNob19jcm9wID0gY3JvcDIub2Zmc2V0V2lkdGggKyBjcm9wMS5vZmZzZXRXaWR0aCA7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGFuY2hvX2Nyb3ApXG4gICAgdmFyIG51ZXZvX2FuY2hvX2Nyb3AgPSBhbmNob19jb250ZW5lZG9yIC0gKGFuY2hvX3RhYmxhIC0gYW5jaG9fY3JvcCk7XG4gICAgY29uc29sZS5sb2cobnVldm9fYW5jaG9fY3JvcClcblxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJ0YWJsZS50YWJsZSAuY3JvcFwiKS5mb3JFYWNoKChjcm9wKSA9PntcbiAgICAgIGNyb3Auc3R5bGUubWF4V2lkdGggPSBgY2FsYygke251ZXZvX2FuY2hvX2Nyb3B9cHgpYDtcbiAgICAgIGNyb3Auc3R5bGUud2lkdGggPSBgY2FsYygke251ZXZvX2FuY2hvX2Nyb3B9cHggKWA7XG4gICAgfSlcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwidGFibGUudGFibGUgLmNyb3AyXCIpLmZvckVhY2goKGNyb3ApID0+e1xuICAgICAgY3JvcC5zdHlsZS5tYXhXaWR0aCA9IGBjYWxjKCR7bnVldm9fYW5jaG9fY3JvcC8yfXB4KWA7XG4gICAgICBjcm9wLnN0eWxlLndpZHRoID0gYGNhbGMoJHtudWV2b19hbmNob19jcm9wLzJ9cHggKWA7XG4gICAgfSlcbiAgICAgIHRhYmxlLnN0eWxlLm1heFdpZHRoID0gYGNhbGMoJHthbmNob19jb250ZW5lZG9yXzB9cHggLSAxLjVyZW0pYDtcbiAgICAgIHRhYmxlLnN0eWxlLndpZHRoID0gYGNhbGMoJHthbmNob19jb250ZW5lZG9yXzB9cHggLSAxLjVyZW0pYDtcbiAgfVxufVxuZnVuY3Rpb24gYXBhbmhvc19pbWFnZW5lc19hcnRpY3Vsb3MoKXtcbiAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIucmVhbCAudG9kby1lbC1hbmNob1wiKSkge1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIucmVhbCAudG9kby1lbC1hbmNob1wiKS5mb3JFYWNoKChpbWFnZW4pID0+IHtcbiAgICAgIHZhciBwcm9wID0gaW1hZ2VuLmdldEF0dHJpYnV0ZShcImRhdGEtcHJvcG9yY2lvblwiKSBcbiAgICAgIHZhciB3aWR0aCA9IGltYWdlbi5vZmZzZXRXaWR0aCBcbiAgICAgIGltYWdlbi5zdHlsZS5wYWRkaW5nQm90dG9tID0gcHJvcCp3aWR0aC8xMDAgKyBcInB4XCJcbiAgICAgIGltYWdlbi5zZXRBdHRyaWJ1dGUoJ3BoeC11cGRhdGUnLCdpZ25vcmUnKTtcbiAgICB9KVxuICB9XG5cbiAgdmFyIHcgPSB3aW5kb3cuaW5uZXJXaWR0aFxuICAgIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aFxuICAgIHx8IGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGg7XG5cbiAgaWYgKHcgPiA3NjgpIHtcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLnZlcnRpY2FsIGltZ1wiKS5mb3JFYWNoKChpbWFnZW4pID0+IHtcbiAgICAgIGltYWdlbi5wYXJlbnROb2RlLnN0eWxlLmNzc1RleHQgPSBcImNzc1RleHRcIixcIndpZHRoOiA3NSUgIWltcG9ydGFudDsgbWFyZ2luLXJpZ2h0OiAyLjVlbSAhaW1wb3J0YW50OyBtYXJnaW4tbGVmdDogLTM3JSAhaW1wb3J0YW50OyBmbG9hdDogbGVmdFwiO1xuICAgICAgLy9pbWFnZW4ubmV4dEVsZW1lbnRTaWJsaW5nLnN0eWxlLm1hcmdpbkxlZnQgPSBcIjUwJVwiO1xuICAgIH0pXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5yZWFsIC52ZXJ0aWNhbCBpbWdcIikuZm9yRWFjaCgoaW1hZ2VuKSA9PiB7XG4gICAgICB2Y
1XIgcGFkZGluZ0JvdHRvbSA9IGltYWdlbi5wYXJlbnROb2RlLnN0eWxlLnBhZGRpbmdCb3R0b20qLjYzXG4gICAgICBpbWFnZW4ucGFyZW50Tm9kZS5zdHlsZS5jc3NUZXh0ID0gYHBhZGRpbmctYm90dG9tOiAke3BhZGRpbmdCb3R0b219OyBtYXJnaW46IDAgIWltcG9ydGFudDtgO1xuICAgICAgaW1hZ2VuLnBhcmVudE5vZGUucGFyZW50Tm9kZS5zdHlsZS5jc3NUZXh0ID0gXCJtYXJnaW46IDAgMCAwIC0zNyUgIWltcG9ydGFudDsgZmxvYXQ6IGxlZnQ7IGNsZWFyOiBib3RoOyBwYWRkaW5nOiAyLjVyZW0gMi41cmVtIDAgMFwiO1xuICAgICAgLy9pbWFnZW4ucGFyZW50Tm9kZS5wYXJlbnROb2RlLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuZmlndXJlLWNhcHRpb25cIikuc3R5bGUucGFkZGluZ0xlZnQgPSBcIjUwJVwiO1xuICAgICAgaW1hZ2VuLnN0eWxlLm1hcmdpbkxlZnQgPSBcIjAgIWltcG9ydGFudFwiXG4gICAgICB2YXIgcHJvcCA9IGltYWdlbi5wYXJlbnROb2RlLmdldEF0dHJpYnV0ZShcImRhdGEtcHJvcG9yY2lvblwiKSBcbiAgICAgIHZhciB3aWR0aCA9IGltYWdlbi5wYXJlbnROb2RlLm9mZnNldFdpZHRoIFxuICAgICAgaW1hZ2VuLnBhcmVudE5vZGUuc3R5bGUucGFkZGluZ0JvdHRvbSA9IHByb3Aqd2lkdGgvMTAwICsgXCJweFwiXG4gICAgfSlcbiAgfSBlbHNlIHtcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLnZlcnRpY2FsIGltZ1wiKS5mb3JFYWNoKChpbWFnZW4pID0+IHtcbiAgICAgIGltYWdlbi5wYXJlbnROb2RlLnN0eWxlLmNzc1RleHQgPSBcImNzc1RleHRcIixcIlwiO1xuICAgIH0pXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5yZWFsIC52ZXJ0aWNhbCBpbWdcIikuZm9yRWFjaCgoaW1hZ2VuKSA9PiB7XG4gICAgICB2Y
1XIgd2lkdGggPSBpbWFnZW4ucGFyZW50Tm9kZS5vZmZzZXRXaWR0aCBcbiAgICAgIHZhciBwcm9wID0gaW1hZ2VuLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKFwiZGF0YS1wcm9wb3JjaW9uXCIpIFxuICAgICAgdmFyIHBhZGRpbmdCb3R0b20gPSB3aWR0aCAqIHByb3BcbiAgICAgIGltYWdlbi5wYXJlbnROb2RlLnN0eWxlLmNzc1RleHQgPSBgcGFkZGluZy1ib3R0b206ICR7cGFkZGluZ0JvdHRvbX07IG1hcmdpbjogMCAhaW1wb3J0YW50O2A7XG4gICAgICBpbWFnZW4ucGFyZW50Tm9kZS5wYXJlbnROb2RlLnN0eWxlLmNzc1RleHQgPSBcIlwiO1xuICAgICAgaW1hZ2VuLnN0eWxlLm1hcmdpbkxlZnQgPSBcIjAgIWltcG9ydGFudFwiXG4gICAgICBpbWFnZW4ucGFyZW50Tm9kZS5zdHlsZS5wYWRkaW5nQm90dG9tID0gcHJvcCp3aWR0aC8xMDAgKyBcInB4XCJcbiAgfSlcbiAgfVxufVxuXG52YXIgZ2FsbGVyeVRvcCA9IHt9O1xudmFyIGdhbGxlcnlUaHVtYnMgPSB7fTtcbnZhciBnYWxsZXJ5VGh1bWJzRmFrZSA9IHt9O1xuXG5mdW5jdGlvbiBzd2lwZXJfZ2FsZXJpYSgpIHtcbiAgaWYgKCQoJy5nYWxsZXJ5LXRvcCcpLmxlbmd0aCkge1xuICAgIGdhbGxlcnlUb3AgPSBuZXcgU3dpcGVyKCcuZ2FsbGVyeS10b3AnLCB7XG4gICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgc2xpZGVzUGVyR3JvdXA6IDEsXG4gICAgICBuZXh0QnV0dG9uOiAnLnN3aXBlci1idXR0b24tbmV4dCcsXG4gICAgICBwcmV2QnV0dG9uOiAnLnN3aXBlci1idXR0b24tcHJldicsXG4gICAgICBvblNsaWRlQ2hhbmdlU3RhcnQ6IGZ1bmN0aW9uKHN3aXApe1xuICAgICAgICBpZiAod2lkdGg+NzY4KXsgXG4gICAgICAgICAgdmFyIGluZGV4ID0gc3dpcC5hY3RpdmVJbmRleDtcbiAgICAgICAgICB2Y
1XIgYWN0aXZvID0gc3dpcC5zbGlkZXNbaW5kZXhdO1xuICAgICAgICAgIGdhbGxlcnlUaHVtYnMuc2xpZGVUbyhpbmRleCk7XG4gICAgICAgICAgZ2FsbGVyeVRodW1ic0Zha2Uuc2xpZGVUbyhpbmRleCk7XG4gICAgICAgICAgdmFyIHNlY2Npb24gPSBhY3Rpdm8uZ2V0QXR0cmlidXRlKCdkYXRhLXNlY2Npb24nKTtcbiAgICAgICAgICBpZiAoc2VjY2lvbiAhPSBzd2lwZXJfc2VjY2lvbikge1xuICAgICAgICAgICAgc3dpcGVyX3NlY2Npb24gPSBzZWNjaW9uO1xuICAgICAgICAgICAgdmFyIGlkX2xpbmsgPSAnI2FwYXJ0YWRvJytzZWNjaW9uO1xuICAgICAgICAgICAgdmFyIGlkX3RhYiA9ICcjYXBhcnRhZG8nK3NlY2Npb24rJy10YWInO1xuICAgICAgICAgICAgJCgnLnRhYmxpbmsnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAkKCcudGFiLXBhbmUnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAkKCcudGFiLXBhbmUnKS5yZW1vdmVDbGFzcygnc2hvdycpO1xuICAgICAgICAgICAgJChpZF9saW5rKS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAkKGlkX3RhYikuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgJChpZF9saW5rKS5hZGRDbGFzcygnc2hvdycpO1xuICAgICAgICAgICAgJChpZF90YWIpLmFkZENsYXNzKCdzaG93Jyk7XG4gICAgICAgICAgICAkKGlkX3RhYikudGFiKCdzaG93Jyk7XG4gICAgICAgICAgfSAgICAgICAgIFxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKHdpZHRoPjc2OCl7IFxuICAgICAgZ2FsbGVyeVRodW1icyA9IG5ldyBTd2lwZXIoJy5nYWxsZXJ5LXRodW1icycsIHtcbiAgICAgICAgY2VudGVyZWRTbGlkZXM6IHRydWUsXG4gICAgICAgIHNsaWRlc1BlclZpZXc6IFwiYXV0b1wiLFxuICAgICAgICBzbGlkZXNQZXJHcm91cDogMSxcbiAgICAgICAgd2F0Y2hTbGlkZXNWaXNpYmlsaXR5OiB0cnVlLFxuICAgICAgICBjZW50ZXJlZFNsaWRlczogdHJ1ZSxcbiAgICAgICAgLy90b3VjaFJhdGlvOiAwLjIsXG4gICAgICAgIHNsaWRlVG9DbGlja2VkU2xpZGU6IHRydWUsXG4gICAgICAgIC8vcGFnaW5hdGlvbjogXCIuc3dpcGVyLXBhZ2luYXRpb25cIixcbiAgICAgICAgLy9uZXh0QnV0dG9uOiAnLnN3aXBlci1idXR0b24tbmV4dDInLFxuICAgICAgICAvL3ByZXZCdXR0b246ICcuc3dpcGVyLWJ1dHRvbi1wcmV2MicsXG4gICAgICAgIC8vcGFnaW5hdGlvbkNsaWNrYWJsZTogdHJ1ZSxcbiAgICAgICAgem9vbTogZmFsc2UsXG4gICAgICAgIGdyYWJDdXJzb3I6IHRydWUsXG4gICAgICAgIG9uU2xpZGVDaGFuZ2VTdGFydDogZnVuY3Rpb24oc3dpcCl7XG4gICAgICAgICAgdmFyIGluZGV4ID0gc3dpcC5hY3RpdmVJbmRleDtcbiAgICAgICAgICBnYWxsZXJ5VG9wLnNsaWRlVG8oaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGdhbGxlcnlUaHVtYnNGYWtlID0gbmV3IFN3aXBlcignLmdhbGxlcnktdGh1bWJzLWZha2UnLCB7XG4gICAgICAgIHNsaWRlc1BlclZpZXc6IDcsXG4gICAgICAgIHNsaWRlc1Blckdyb3VwOiA3LFxuICAgICAgICBzbGlkZVRvQ2xpY2tlZFNsaWRlOiB0cnVlLFxuICAgICAgICBwYWdpbmF0aW9uOiBcIi5zd2lwZXItcGFnaW5hdGlvblwiLFxuICAgICAgICBuZXh0QnV0dG9uOiAnLnN3aXBlci1idXR0b24tbmV4dDInLFxuICAgICAgICBwcmV2QnV0dG9uOiAnLnN3aXBlci1idXR0b24tcHJldjInLFxuICAgICAgICBwYWdpbmF0aW9uQ2xpY2thYmxlOiB0cnVlLFxuICAgICAgICBvblNsaWRlQ2hhbmdlU3RhcnQ6IGZ1bmN0aW9uKHN3aXApe1xuICAgICAgICAgIHZhciBpbmRleCA9IHN3aXAuYWN0aXZlSW5kZXg7XG4gICAgICAgICAgZ2FsbGVyeVRvcC5zbGlkZVRvKGluZGV4KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGdhbGxlcnlUb3AucGFyYW1zLmNvbnRyb2wgPSBnYWxsZXJ5VGh1bWJzO1xuICAgICAgZ2FsbGVyeVRodW1icy5wYXJhbXMuY29udHJvbCA9IGdhbGxlcnlUb3A7XG4gICAgfVxuICB9XG4gIHZhciBhY2Nlc28gPSB0aGlzOyBcbiAgJChkb2N1bWVudCkub24oJ2NsaWNrJywnLnBlZGlyIC5hcnRpY3Vsby1yZXN1bWVuJywgcGVkaXJfYXJ0aWN1bG8pO1xuICAkKGRvY3VtZW50KS5vbignZGJsY2xpY2snLCcuZ2FsbGVyeS10aHVtYnMgLnN3aXBlci1zbGlkZS1hY3RpdmUnLCBwZWRpcl9hcnRpY3Vsbyk7XG4gICQoJ2FbZGF0YS10b2dnbGU9XCJ0YWJcIl0nKS5vbignc2hvd24uYnMudGFiJywgZnVuY3Rpb24gKGUpIHtcbiAgICBlLnRhcmdldCAvLyBuZXdseSBhY3RpdmF0ZWQgdGFiO1xuICAgIHZhciBpZCA9IGUudGFyZ2V0LmdldEF0dHJpYnV0ZSgnYXJpYS1jb250cm9scycpO1xuICAgIHZhciBpZF9hcnQgPSAkKCcjJytpZCsnIC5zd2lwZXItc2xpZGUnKS5maXJzdCgpLmF0dHIoJ2RhdGEtYXJ0aWN1bG8nKTtcbiAgICBlLnJlbGF0ZWRUYXJnZXQgLy8gcHJldmlvdXMgYWN0aXZlIHRhYlxuICAgIHZhciBpdGVtID0gJChcIi5nYWxsZXJ5LXRvcCAqW2RhdGEtYXJ0aWN1bG89XCIraWRfYXJ0K1wiXVwiKTtcbiAgICB2YXIgaW5kZXggPSAkKFwiLmdhbGxlcnktdG9wIC5hcnRpY3Vsby1yZXN1bWVuXCIpLmluZGV4KGl0ZW0pO1xuICAgIGlmIChpbmRleCA+IC0xICl7XG4gICAgICBnYWxsZXJ5VG9wLnNsaWRlVG8oaW5kZXgpO1xuICAgIH1cblxuICAgIHZhciBpZF9saW5rID0gJyMnK2lkO1xuICAgIHZhciBpZF90YWIgPSAnIycraWQrJy10YWInO1xuXG4gICAgJCgnLnRhYmxpbmsnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgJCgnLnRhYi1wYW5lJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICQoJy50YWItcGFuZScpLnJlbW92ZUNsYXNzKCdzaG93Jyk7XG4gICAgJChpZF9saW5rKS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgJChpZF90YWIpLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAkKGlkX2xpbmspLmFkZENsYXNzKCdzaG93Jyk7XG4gICAgJChpZF90YWIpLmFkZENsYXNzKCdzaG93Jyk7XG4gICAgJChpZF90YWIpLnRhYignc2hvdycpO1xuICB9KSBcbn1cbiQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHtcbiAgaWYgKCQoJy5zd2lwZXItc29jaWFzJykubGVuZ3RoKSB7XG4gICAgdmFyIHN3aXBlciA9IG5ldyBTd2lwZXIoJy5zd2lwZXItc29jaWFzJywge1xuICAgICAgbmV4dEJ1dHRvbjogJy5zd2lwZXItYnV0dG9uLW5leHQnLFxuICAgICAgcHJldkJ1dHRvbjogJy5zd2lwZXItYnV0dG9uLXByZXYnLFxuICAgICAgcGFnaW5hdGlvbjogXCIuc3dpcGVyLXBhZ2luYXRpb25cIixcbiAgICAgIHNwYWNlQmV0d2VlbjogMCxcbiAgICAgIHNwZWVkOiA0MDAwLFxuICAgICAgbG9vcDogdHJ1ZSxcbiAgICAgIGF1dG9wbGF5OiB7XG4gICAgICAgIGRlbGF5OiA2MDAwLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufSk7XG5mdW5jdGlvbiBzd2lwZXJfZ2FsZXJpYV9tb2RhbCgpIHtcbiAgJChcIi5tb2RhbFwiKS5vbignc2hvdy5icy5tb2RhbCcsIGZ1bmN0aW9uKGUpIHtcbiAgICBzZXRUaW
11lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCQoJy5zd2lwZXItZ2FsZXJpYScpLmxlbmd0aCkge1xuICAgICAgICB2YXIgaW1nID0gJChlLnJlbGF0ZWRUYXJnZXQpLmF0dHIoXCJkYXRhLWltZ1wiKTtcbiAgICAgICAgdmFyIHN3aXBlciA9IG5ldyBTd2lwZXIoJy5zd2lwZXItZ2FsZXJpYScsIHtcbiAgICAgICAgICBpbml0aWFsU2xpZGU6IGltZyxcbiAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgICAgIHNsaWRlc1Blckdyb3VwOiAxLFxuICAgICAgICAgIG5leHRCdXR0b246ICcuc3dpcGVyLWJ1dHRvbS1uZXh0JyxcbiAgICAgICAgICBwcmV2QnV0dG9uOiAnLnN3aXBlci1idXR0b20tcHJldicsXG4gICAgICAgICAgZWZmZWN0OiAnZmFkZScsXG4gICAgICAgICAgcGFnaW5hdGlvbjogJy5wYWdpbmF0aW9uJyxcbiAgICAgICAgICBwYWdpbmF0aW9uVHlwZTogJ2N1c3RvbScsXG4gICAgICAgICAgcGFnaW5hdGlvbkN1c3RvbVJlbmRlcjogZnVuY3Rpb24gKHN3aXBlciwgY3VycmVudCwgdG90YWwpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQgKyAnLycgKyB0b3RhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSwgNTAwKTtcbiAgfSk7XG4gICQoZG9jdW1lbnQpLm9uKCdjbGljaycsJy5vY3VsdGFyLWluZm8nLCBmdW5jdGlvbigpIHtcbiAgICB2YXIgY29scyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5zd2lwZXItZ2FsZXJpYSAuaW5mbycpO1xuICAgIGZvciAodmFyIGMgPSAwOyBjIDwgIGNvbHMubGVuZ3RoOyArK2Mpe1xuICAgICAgY29sc1tjXS5jbGFzc0xpc3QudG9nZ2xlKCdvY3VsdG8nKTtcbiAgICB9XG4gIH0pO1xufTtcbmZ1bmN0aW9uIHBlZGlyX2FydGljdWxvKCkge1xuICB2YXIgaWQgPSAkKHRoaXMpLmF0dHIoXCJkYXRhLWFydGljdWxvXCIpO1xuICAkKCdib2R5JykuYWRkQ2xhc3MoJ3dhaXQnKTtcbiAgJC5hamF4KHtcbiAgICB1cmw6ICcvYXBpX3NlY3VyL2FydGljdWxvLycgKyBpZCxcbiAgICB0eXBlIDogJ0dFVCcsXG4gICAgZGF0YVR5cGU6J2pzb24nLFxuICAgIHN1Y2Nlc3MgOiBmdW5jdGlvbihkYXRhKSB7ICAgICAgICAgICAgICBcbiAgICAgICQoJ2JvZHknKS5yZW1vdmVDbGFzcygnd2FpdCcpO1xuICAgICAgdmFyIGFydGljdWxvID0gJCgnLmFydGljdWxvLWNvbXBsZXRvJyk7XG4gICAgICBhcnRpY3Vsby5odG1sKCcnKSA7XG4gICAgICBhcnRpY3Vsby5odG1sKGRhdGEuYXJ0aWN1bG8pIDtcbiAgICAgIGNhbWJpbygpO1xuICAgICAgJCgnaHRtbCwgYm9keScpLnN0b3AoKS5hbmltYXRlKHtcbiAgICAgICAgJ3Njcm9sbFRvcCc6IGFydGljdWxvXG4gICAgICAgIC5vZmZzZXQoKS50b3AgLSAkKFwiLnNlZ3VpbWllbnRvXCIpLmhlaWdodCgpIC0gMjVcbiAgICAgIH0sIDkwMCwgJ3N3aW5nJyk7XG4gICAgfSxcbiAgICBlcnJvciA6IGZ1bmN0aW9uKHJlcXVlc3QsZXJyb3IpIHtcbiAgICAgICQoJ2JvZHknKS5yZW1vdmVDbGFzcygnd2FpdCcpO1xuICAgIH1cbiAgfSk7XG4gIHZhciBpZF90YWIgPSAkKFwiI1RhYkNvbnRlbnQgKltkYXRhLWFydGljdWxvPVwiK2lkK1wiXVwiKVxuICAgIC5wYXJlbnQoKS5wYXJlbnQoKS5wYXJlbnQoKS5wYXJlbnQoKVxuICAgIC5hdHRyKFwiaWRcIik7XG4gIHZhciBpZF9saW5rID0gJyMnK2lkX3RhYjtcbiAgaWRfdGFiID0gJyMnK2lkX3RhYisnLXRhYic7XG4gICQoJy50YWJsaW5rJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAkKCcudGFiLXBhbmUnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICQoJy50YWItcGFuZScpLnJlbW92ZUNsYXNzKCdzaG93Jyk7XG4gICQoaWRfbGluaykuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAkKGlkX3RhYikuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAkKGlkX2xpbmspLmFkZENsYXNzKCdzaG93Jyk7XG4gICQoaWRfdGFiKS5hZGRDbGFzcygnc2hvdycpO1xuICAkKGlkX3RhYikudGFiKCdzaG93Jyk7XG5cbiAgdmFyIGl0ZW0gPSAkKFwiLmdhbGxlcnktdG9wICpbZGF0YS1hcnRpY3Vsbz1cIitpZCtcIl1cIik7XG4gIHZhciBpbmRleCA9ICQoXCIuZ2FsbGVyeS10b3AgLmFydGljdWxvLXJlc3VtZW5cIikuaW5kZXgoaXRlbSk7XG4gIGdhbGxlcnlUb3Auc2xpZGVUbyhpbmRleCk7XG4gIGdhbGxlcnlUaHVtYnNGYWtlLnNsaWRlVG8oaW5kZXgpO1xufVxuJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24gKCkge1xuICBpZiAoJCgnLnN3aXBlci1lZGljaW9uLWltcHJlc2EnKS5sZW5ndGgpIHtcbiAgICB2YXIgc3dpcGVyID0gbmV3IFN3aXBlcignLnN3aXBlci1lZGljaW9uLWltcHJlc2EnLCB7XG4gICAgICBuZXh0QnV0dG9uOiAnLnN3aXBlci1lZC1uZXh0JyxcbiAgICAgIHByZXZCdXR0b246ICcuc3dpcGVyLWVkLXByZXYnLFxuICAgICAgc3BhY2VCZXR3ZWVuOiAwLFxuICAgICAgc2xpZGVzUGVyVmlldzogMSxcbiAgICAgIHNsaWRlc1Blckdyb3VwOiAxLFxuICAgIH0pO1xuICB9XG59KTtcbiQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHtcbiAgdmFyIHdpZHRoID0gJCh3aW5kb3cpLndpZHRoKCk7XG4gIGlmICh3aWR0aDw3NjgpeyBcbiAgICBpZiAoJCgnLnJlbGFjaW9uYWRhcy1PRkYgLnJlc3VtZW4nKS5sZW5ndGggPjEpIHtcbiAgICAgIHZhciBzd2lwZXIgPSBuZXcgU3dpcGVyKCcucmVsYWNpb25hZGFzIC5jb2wtbWQtOScsIHtcbiAgICAgICAgc2xpZGVDbGFzczogXCJyZXN1bWVuXCIsXG4gICAgICAgIHdyYXBwZXJDbGFzczogXCJjYXJkLWRlY2stcG9ydGFkYVwiLFxuICAgICAgICBuZXh0QnV0dG9uOiAnLnN3aXBlci1udW1lcm9zLW5leHQnLFxuICAgICAgICBwcmV2QnV0dG9uOiAnLnN3aXBlci1udW1lcm9zLXByZXYnLFxuICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgICBzbGlkZXNQZXJHcm91cDogMSxcbiAgICAgIH0pO1xuICAgIH0gXG4gICAgaWYgKCQoJy5udW1lcm8gLnJlc3RvJykubGVuZ3RoIHx8ICQoJy5zd2lwZXItbnVtZXJvcycpLmxlbmd0aCkge1xuICAgICAgdmFyIHN3aXBlciA9IG5ldyBTd2lwZXIoJy5zd2lwZXItbnVtZXJvcycsIHtcbiAgICAgICAgbmV4dEJ1dHRvbjogJy5zd2lwZXItbnVtZXJvcy1uZXh0JyxcbiAgICAgICAgcHJldkJ1dHRvbjogJy5zd2lwZXItbnVtZXJvcy1wcmV2JyxcbiAgICAgICAgc2xpZGVzUGVyVmlldzogMSxcbiAgICAgICAgc2xpZGVzUGVyR3JvdXA6IDEsXG4gICAgICB9KTtcbiAgICB9IFxuXG4gIH1cbiAgaWYgKCQoJy5zd2lwZXItbGlicm9zJykubGVuZ3RoKSB7XG4gICAgdmFyIHN3aXBlciA9IG5ldyBTd2lwZXIoJy5zd2lwZXItbGlicm9zJywge1xuICAgICAgbmV4dEJ1dHRvbjogJy5zd2lwZXItbGlicm9zLW5leHQnLFxuICAgICAgcHJldkJ1dHRvbjogJy5zd2lwZXItbGlicm9zLXByZXYnLFxuICAgICAgc2xpZGVzUGVyVmlldzogNCxcbiAgICAgIHNsaWRlc1Blckdyb3VwOiA0LFxuICAgICAgYnJlYWtwb2ludHM6IHtcbiAgICAgICAgNzY4OntcbiAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgICAgI
1HNsaWRlc1Blckdyb3VwOiAxLFxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn0pO1xuXG4vKlxuJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKXtcbiAgLy8gdG8gZmFkZSBpbiBvbiBwYWdlIGxvYWRcbiAgLy8gdG8gZmFkZSBvdXQgYmVmb3JlIHJlZGlyZWN0XG4gICQoJ2EnKS5jbGljayhmdW5jdGlvbihlKXtcbiAgICByZWRpcmVjdCA9ICQodGhpcykuYXR0cignaHJlZicpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAkKCdib2R5JykuZmFkZU91dCg0MDAsIGZ1bmN0aW9uKCl7XG4gICAgICBkb2N1bWVudC5sb2NhdGlvbi5ocmVmID0gcmVkaXJlY3RcbiAgICB9KTtcbiAgfSk7XG59KVxuXG5cblxudmFyIHRvb2x0aXBzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnJlc3VtZW4nKTtcbmZvcih2YXIgaSA9IDA7IGkgPCB0b29sdGlwcy5sZW5ndGg7IGkrKykge1xuICB0b29sdGlwc1tpXS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBmdW5jdGlvbiBmbihlKSB7XG4gICAgaWYgKGUudGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucyhcImVudHJhZGlsbGFfaG92ZXJcIikpIHtcbiAgICB2YXIgdG9vbHRpcCA9IGUudGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucyhcImVudHJhZGlsbGFfaG92ZXJcIikgP1xuICAgICAgZS50YXJnZXQgOlxuICAgICAgZS50YXJnZXQucXVlcnlTZWxlY3RvcignOnNjb3BlIC5lbnRyYWRpbGxhX2hvdmVyJyk7XG4gICAgdG9vbHRpcC5zdHlsZS5sZWZ0ID1cbiAgICAgIGUucGFnZVggKyB0b29sdGlwLmNsaWVudFdpZHRoICsgMTAgPFxuICAgICAgZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aCA/XG4gICAgICBlLnBhZ2VYICsgMTAgKyAncHgnIDpcbiAgICAgIGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGggKyA1IC0gdG9vbHRpcC5jbGllbnRXaWR0aCArICdweCc7XG4gICAgdG9vbHRpcC5zdHlsZS50b3AgPVxuICAgICAgZS5wYWdlWSArIHRvb2x0aXAuY2xpZW50SGVpZ2h0ICsgMTAgPFxuICAgICAgZG9jdW1lbnQuYm9keS5jbGllbnRIZWlnaHQgP1xuICAgICAgZS5wYWdlWSArIDEwICsgJ3B4JyA6IFxuICAgICAgZG9jdW1lbnQuYm9keS5jbGllbnRIZWlnaHQgKyA1IC0gdG9vbHRpcC5jbGllbnRIZWlnaHQgKyAncHgnO1xuICAgIH1cbiAgfSk7XG59XG4qL1xuLy9kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdET01Db250ZW50TG9hZGVkJywgZnVuY3Rpb24oKSB7XG5mdW5jdGlvbiByZWNvcnRhcl9jb21lbnRhcmlvcygpe1xuICB2YXIgbGlua0NsaWNrID0gZnVuY3Rpb24oZSkge1xuICAgIHZhciBtID0gZS5jdXJyZW50VGFyZ2V0O1xuICAgIGlmIChtLmNsYXNzTGlzdC5jb250YWlucygnbGVzcycpKSB7XG4gICAgICBtLmNsYXNzTGlzdC5yZW1vdmUoJ2xlc3MnKTtcbiAgICAgIG0uaW5uZXJIVE1MID0gbW9yZXRleHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0uY2xhc3NMaXN0LmFkZCgnbGVzcycpO1xuICAgICAgbS5pbm5lckhUTUwgPSBsZXNzdGV4dDtcbiAgICB9XG4gICAgbS5wYXJlbnROb2RlLmNsYXNzTGlzdC50b2dnbGUoJ3Zpc2libGUnKVxuICAgIC8vbS5wYXJlbnROb2RlLm5leHRTbGliaW5nLmNsYXNzTGlzdC50b2dnbGUoJ3Zpc2libGUnKVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbiAgdmFyIHNob3dDaGFyID0gMzAwOyBcbiAgdmFyIGVsbGlwc2VzdGV4dCA9IFwiLi4uXCI7XG4gIHZhciBtb3JldGV4dCA9IFwiPHN2ZyBjbGFzcz0naWNvbicgdGl0bGU9Jycgdmlld0JveD0nNzAwIDQwMCAgMTAwIDEwMCc+PHVzZSB4bGluazpocmVmPScjbWFzJz48L3VzZT48L3N2Zz5cIjtcbiAgdmFyIGxlc3N0ZXh0ID0gXCI8c3ZnIGNsYXNzPSdpY29uJyB0aXRsZT0nJyB2aWV3Qm94PSc0MDAgNzAw
1ICAxMDAgMTAwJz48dXNlIHhsaW5rOmhyZWY9JyNtZW5vcyc+PC91c2U+IDwvc3ZnPlwiO1xuICB2YXIgbW9yZXMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdjb3J0YXJfdGV4dG8nKTtcbiAgZm9yKHZhciBpID0gMDsgaSA8IG1vcmVzLmxlbmd0aDsgaSsrKXtcbiAgICB2YXIgY29udGVudCA9IG1vcmVzW2ldLmlubmVySFRNTDtcbiAgICBpZihjb250ZW50Lmxlbmd0aCA+IHNob3dDaGFyKSB7XG4gICAgICB2YXIgYyA9IGNvbnRlbnQuc3Vic3RyKDAsIHNob3dDaGFyKTtcbiAgICAgIHZhciBoID0gY29udGVudC5zdWJzdHIoc2hvd0NoYXIsIGNvbnRlbnQubGVuZ3RoIC0gc2hvd0NoYXIpOyBcbiAgICAgIHZhciBodG1sID0gJycgKyBjICsgJzxzcGFuIGNsYXNzPVwibW9yZWVsbGlwc2VzXCI+JytlbGxpcHNlc3RleHQrJyZuYnNwOzwvc3Bhbj48c3BhbiBjbGFzcz1cIm1vcmVjb250ZW50XCI+PHNwYW4+JyArIGggKyAnPC9zcGFuPjxhIGNsYXNzPVwibW9yZWxpbmtcIj4nK21vcmV0ZXh0Kyc8L2E+PC9zcGFuPic7XG4gICAgICBtb3Jlc1tpXS5pbm5lckhUTUwgPSBodG1sO1xuICAgIH1cbiAgfVxuICB2YXIgbW9yZWxpbmtzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnbW9yZWxpbmsnKTtcbiAgZm9yKHZhciBpID0gMDsgaSA8IG1vcmVsaW5rcy5sZW5ndGg7IGkrKyl7XG4gICAgbW9yZWxpbmtzW2ldLm9uY2xpY2sgPSBsaW5rQ2xpY2s7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29waWFyX2Fjb3J0YWRvcygpe1xuICB2YXIgY29waWFyX3R4dCA9IGZ1bmN0aW9uKGUpeyBcbiAgICB2YXIgZWwgPSBlLmN1cnJlbnRUYXJnZXQ7XG4gICAgdmFyIHRleHQgPSBlbC5nZXRBdHRyaWJ1dGUoXCJ0ZXh0b1wiKTtcbiAgICB2YXIgdGV4dEFyZWEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZXh0YXJlYScpO1xuICAgIHRleHRBcmVhLnNldEF0dHJpYnV0ZSgnc3R5bGUnLCd3aWR0aDoxcHg7Ym9yZGVyOjA7b3BhY2l0eTowOycpO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGV4dEFyZWEpO1xuICAgIHRleHRBcmVhLnZhbHVlID0gdGV4dDtcbiAgICB0ZXh0QXJlYS5zZWxlY3QoKTtcbiAgICBkb2N1bWVudC5leGVjQ29tbWFuZCgnY29weScpO1xuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGV4dEFyZWEpO1xuICB9XG4gIHZhciBjb3BpYXIgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwiY29waWFyXCIpXG4gIGZvcih2YXIgaSA9IDA7IGkgPCBjb3BpYXIubGVuZ3RoOyBpKyspe1xuICAgIGNvcGlhcltpXS5vbmNsaWNrID0gY29waWFyX3R4dDtcbiAgfVxuXG4gIHZhciBjb3BpYXJfYWNvcnRhZG8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNvcGlhcl9hY29ydGFkb1wiKTtcbiAgaWYgKGNvcGlhcl9hY29ydGFkbykge1xuICAgIGNvcGlhcl9hY29ydGFkby5vbmNsaWNrID0gZnVuY3Rpb24oKXtcbiAgICAgIHZhciB2YWxvciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhcnRpY3Vsb19hY29ydGFkbycpLnZhbHVlID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FydGljdWxvX2Fjb3J0YWRvJykudmFsdWUgOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXJ0aWN1bG9faWQnKS52YWx1ZTtcbiAgICAgIHZhciB0ZXh0QXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XG4gICAgICB0ZXh0QXJlYS5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywnd2lkdGg6MXB4O2JvcmRlcjowO29wYWNpdHk6MDsnKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGV4dEFyZWEpO1xuICAgICAgdGV4dEFyZWEudmFsdWUgPSBcImh0dHBzOi8vZWxzYWwudG8vXCIrdmFsb3I7XG4gICAgICB0ZXh0QXJlYS5zZWxlY3QoKTtcbiAgICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKCdjb3B5Jyk7XG4gICAgICBkb2
1N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKHRleHRBcmVhKTtcblxuICAgIH07XG4gIH1cbn1cblxuXG5cbnZhciBzZWd1bmRvcyA9IDA7XG52YXIgcmVsYWNpb25hZGFzID0gZmFsc2U7XG5mdW5jdGlvbiBwYWdpbmFfYWN0aXZhKCkge1xuICB2YXIgcmVwZXRpciA9IHRydWU7XG4gIGlmKGRvY3VtZW50LnZpc2liaWxpdHlTdGF0ZSA9PSBcInZpc2libGVcIikge1xuICAgIHNlZ3VuZG9zKys7XG4gIH1cbiAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJyZWxhY2lvbmFkYXNcIikubGVuZ3RoICYmIHZpc2libGUoZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcInJlbGFjaW9uYWRhc1wiKVswXSkpIHtcbiAgICByZWxhY2lvbmFkYXMgPSB0cnVlO1xuICB9XG4gIGlmIChzZWd1bmRvcyA+IDE1ICYmIHJlbGFjaW9uYWRhcyl7XG4gICAgLy8gYW5vdGFyXG4gICAgLy9jb25zb2xlLmxvZyhcImFub3RhclwiKVxuICAgIC8vYW5vdGFyX2xlY3R1cmEoKTtcbiAgICByZXBldGlyID0gZmFsc2U7XG4gIH1cbiAgaWYgKHJlcGV0aXIpIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7cGFnaW5hX2FjdGl2YSgpfSwgMTAwMClcbiAgfVxufVxuLy9wYWdpbmFfYWN0aXZhKClcblxuZnVuY3Rpb24gYW5vdGFyX2xlY3R1cmEoKSB7XG4gIGNvbnN0IGNzcmYgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdtZXRhW25hbWU9XCJjc3JmLXRva2VuXCJdJykuY29udGVudDtcbiAgY29uc3QgdXJsID0gXCIvYXJ0aWN1bG8vYW5vdGFyLzEyMjNcIlxuICBmZXRjaCh1cmwsIHsgbWV0aG9kOiBcIlBVVFwiLCBoZWFkZXJzOiB7ICd4LWNzcmYtdG9rZW4nOiBjc3JmIH0gfSk7XG59XG5cblxubGV0IHByb2Nlc3NTY3JvbGwgP
1SAoKSA9PiB7XG4gIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImFydGljdWxvLWNvbnRlbmlkb1wiICkpIHtcbiAgICBsZXQgZG9jRWxlbSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgXG4gICAgICBkb2NCb2R5ID0gZG9jdW1lbnQuYm9keSxcbiAgICAgIHNjcm9sbFRvcCA9IGRvY0VsZW1bJ3Njcm9sbFRvcCddIHx8IGRvY0JvZHlbJ3Njcm9sbFRvcCddLFxuICAgICAgaGVhZGVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkZXJcIilbMF0ub2Zmc2V0SGVpZ2h0LFxuICAgICAgaGFsZldpbmRvd0hlaWdodCA9IHdpbmRvdy5zY3JlZW4uaGVpZ2h0IC8gMyxcbiAgICAgIHNjcm9sbFN0b3AgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXJ0aWN1bG8tY29udGVuaWRvJykub2Zmc2V0SGVpZ2h0LFxuICAgICAgc2Nyb2xsQm90dG9tX29sZCA9IChkb2NFbGVtWydzY3JvbGxIZWlnaHQnXSB8fCBkb2NCb2R5WydzY3JvbGxIZWlnaHQnXSkgLSBzY3JvbGxTdG9wLCBcblxuICAgICAgc2Nyb2xsQm90dG9tID0gKHNjcm9sbFN0b3AgLSBoYWxmV2luZG93SGVpZ2h0KSwgXG4gICAgICBzY3JvbGxQZXJjZW50ID0gKHNjcm9sbFRvcCAtIGhlYWRlcikgLyBzY3JvbGxCb3R0b207XG4gICAgICBzY3JvbGxQZXJjZW50ID0gKHNjcm9sbFBlcmNlbnQgPCAwICkgPyAwIDogc2Nyb2xsUGVyY2VudDtcbiAgICAgIHNjcm9sbFBlcmNlbnQ9IHNjcm9sbFBlcmNlbnQgKiAxMDAgKyAnJSc7XG4gICAgXG4gICAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJwcm9ncmVzcy1iYXJcIikgJiYgc2Nyb2xsU3RvcCA+IDApIHtcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJwcm9ncmVzcy1iYXJcIikuc3R5bGUuc2V0UHJvcGVydHkoXCItLXNjcm9sbEFtb3VudFwiLCBzY3JvbGxQZXJjZW50KTsgXG4gICAgICB9XG4gIH1cbn1cblxuaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYXJ0aWN1bG8tY29udGVuaWRvXCIgKSkge1xuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHByb2Nlc3NTY3JvbGwpO1xufVxuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbF90b1wiLCAoZSkgPT4ge1xuICBlLnRhcmdldC5zY3JvbGxJbnRvVmlldygpO1xufSk7XG5cbmZ1bmN0aW9uIGhlYWRlcl9lbl9zdGlja3koKSB7XG4gIHZhciBzZW5zb3IgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnN0aWNreS1zZW5zb3JcIilcbiAgdmFyIGhlYWRlciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJoZWFkZXJcIilcbiAgdmFyIGNvbnRlbmlkbyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjY29udGVuaWRvLXByaW5jaXBhbFwiKVxuICB2YXIgdGVtYSA9IGZhbHNlO1xuICBpZiggZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5udWJlLXRlbWFcIikpIHtcbiAgICBjb250ZW5pZG8gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLm51YmUtdGVtYVwiKVxuICAgIHRlbWEgPSB0cnVlO1xuICB9XG4gIGlmKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuYXJ0aWN1bG8tY29udGVuaWRvXCIpKSB7XG4gICAgY29udGVuaWRvID0gZmFsc2VcbiAgfVxuICBpZihoZWFkZXIpe1xuICAgIHZhciBvYnNlcnZlciA9IG5ldyBJbnRlcnNlY3Rpb25PYnNlcnZlciggXG4gICAgICAoW2VdKSA9PiB7XG4gICAgICAgIGhlYWRlci5jbGFzc0xpc3QudG9nZ2xlKFwic3RpY2t5LWhlYWRlclwiLCBlLmludGVyc2VjdGlvblJhdGlvIDwgMSk7XG4gICAgICAgIHZhciB3ID0gd2luZG93LmlubmVyV2lkdGhcbiAgICAgICAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGhcbiAgICAgICAgICB8fCBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoO1xuICAgICAgICBpZiggdyA8IDc2OCAmJiBjb250ZW5pZG8gJiYgZS5pbnRlcnNlY3Rpb25SYXRpbyA8IDEpe1xuICAgICAgICAgIGNvbnRlbmlkby5zdHlsZS5wYWRkaW5nVG9wID0gYCR7aGVhZGVyLmNsaWVudEhlaWdodH1weGA7XG4gICAgICAgIH0gZWxzZSBpZiAoY29udGVuaWRvICYmICF0ZW1hKXtcbiAgICAgICAgICBjb250ZW5pZG8uc3R5bGUucGFkZGluZ1RvcCA9ICAwO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgeyB0aHJlc2hvbGQ6IFsxXSB9XG4gICAgKTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKHNlbnNvcik7XG5cbiAgfVxufVxuXG52YXIgcmV1YmljYXJfcmVzdW1lbmVzX2FydGljdWxvcyA9IGZhbHNlO1xuZnVuY3Rpb24gcmV1YmljYXJfcmVzdW1lbmVzX2FydGljdWxvKCl7XG4gIGlmKHJldWJpY2FyX3Jlc3VtZW5lc19hcnRpY3Vsb3MgPT09IGZhbHNlKXtcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbZGF0YS1hcnRpY3Vsby1yZXN1bWVuXScpXG4gICAgICAuZm9yRWFjaCgocmVzdW1lbikgPT4geyBcbiAgICAgIHZhciBpZCA9IHJlc3VtZW4uZGF0YXNldC5hcnRpY3Vsb1Jlc3VtZW47XG4gICAgICB2Y
1XIgdWJpY2FjaW9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYHViaWNhY2lvbl9hcnRpY3Vsb18ke2lkfWApO1xuICAgICAgdmFyIGFydGljdWxvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYG1vdmVyX3ViaWNhY2lvbl8ke2lkfWApO1xuICAgICAgdWJpY2FjaW9uLnJlcGxhY2VXaXRoKGFydGljdWxvKTtcbiAgICAgIHJldWJpY2FyX3Jlc3VtZW5lc19hcnRpY3Vsb3MgPSBmYWxzZVxuICAgIH0pO1xuICB9XG59XG5cbiAgXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb3JpZW50YXRpb25jaGFuZ2UnLCBjYW1iaW9fbWVkaWRhcyk7XG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGNhbWJpb19tZWRpZGFzKTtcbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBwdWJsaV92ZXJzaW9uKVxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIGNhbWJpb19tZWRpZGFzKTtcblxuZnVuY3Rpb24gY2FtYmlvX21lZGlkYXMoKXtcbiAgbWVkaWRhcygpXG4gIHB1YmxpX3ZlcnNpb25fY2FtYmlvKClcbiAgYXBhbmhvc19pbWFnZW5lc19hcnRpY3Vsb3MoKTtcbn1cblxudmFyIHB1YmxpX3ZlcnNpb25fYWN0dWFsID0gXCJcIjtcbmZ1bmN0aW9uIHB1YmxpX3ZlcnNpb24oKSB7XG4gIHZhciB3ID0gd2luZG93LmlubmVyV2lkdGhcbiAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGhcbiAgICB8fCBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoO1xuICB3IDw9IDc2OCA/IHB1YmxpX3ZlcnNpb25fYWN0dWFsID0gXCJtb2JpbFwiIDogcHVibGlfdmVyc2lvbl9hY3R1YWwgPSBcImVzY3JpdG9yaW9cIlxufVxuZnVuY3Rpb24gcHVibGlfdmVyc2lvbl9jYW1iaW8oKSB7XG4gIHZhciBhbnRlcmlvciA9IHB1YmxpX3ZlcnNpb25fYWN0dWFsXG4gIHB1YmxpX3ZlcnNpb24oKVxuICBwdWJsaV92ZXJzaW9uX2FjdHVhbCA9PSBhbnRlcmlvciA/IHRydWUgOiByZXViaWNhcl9wdWJsaXModHJ1ZSlcbn1cblxuZnVuY3Rpb24gbGFuemFyX3NjcmlwdHMoKXtcbiAgbGFuemFyX2NvZGlnb3NfZW1iZWJpZG9zKClcbiAgLy9jb25zb2xlLmxvZyhcIkxBTlpBTkRPIFNDUklQVFNTU1NcIilcbiAgdmFyIGVudHJhZGlsbGEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI2VudHJhZGlsbGEyXCIpO1xuICBpZiAoZW50cmFkaWxsYSl7XG4gICAgdmFyIGluZm9ncmFmaWEgPSBlbnRyYWRpbGxhLmlubmVySFRNTFxuXG4gICAgZW50cmFkaWxsYS5pbm5lckhUTUwgPSBcIlwiXG4gICAgaWYoaW5mb2dyYWZpYSkgcG9zdHNjcmliZShcIiNlbnRyYWRpbGxhMlwiLCBpbmZvZ3JhZmlhKVxuICB9XG5cbiAgdmFyIGZsb3VyaXNoID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5mbG91cmlzaC1lbWJlZFwiKTtcbiAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuZmxvdXJpc2gtZW1iZWQgaWZyYW1lXCIpKXtcbiAgICBmbG91cmlzaCA9IGZhbHNlXG4gIH0gZWxzZSB7XG4gICAgZmxvdXJpc2ggPSBmbG91cmlzaFxuICB9XG4gIGlmIChmbG91cmlzaCl7XG4gICAgd2luZG93LkZsb3VyaXNoTG9hZGVkID0gbnVsbFxuICAgIGNvbnN0IHNjcmlwdF9mbG91cmlzaCA9IFwiPHNjcmlwdCBzcmM9J2h0dHBzOi8vcHVibGljLmZsb3VyaXNoLnN0dWRpby9yZXNvdXJjZXMvZW1iZWQuanMnPjwvc2NyaXB0PlwiO1xuICAgIHBvc3RzY3JpYmUoXCIjVWJpY2FjaW9uU2NyaXB0c1wiLCBzY3JpcHRfZmxvdXJpc2gpXG4gICAgLy9jb25zb2xlLmxvZyhcIiEhISEhISEhISEhISEhISEhISEhXCIpXG4gIH1cbn1cblxudmFyIGVqZWN1dGFkb3NfZW1iZWJpZG9zID0gZmFsc2U7XG5mdW5jdGlvbiBsYW56YXJfY29kaWdvc19lbWJlYmlkb3MoKXtcbiAgaWYoZWplY3V0YWRvc19lbWJlYmlkb3MgPT09IGZhbHNlKXtcbiAgICBlamVjdXRhZG9zX2VtYmViaWRvcyA9IHRydWVcbiAgICB2YXIgZW1iZWRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5lbWJlZF9kYXRhXCIpO1xuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBlbWJlZHMubGVuZ3RoOyBpKyspe1xuICAgICAgdmFyIGVtYmVkID0gZW1iZWRzW2ldLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiY29kaWdvXCIpWzBdO1xuICAgICAgdmFyIGlkID0gZW1iZWRzW2ldLmdldEF0dHJpYnV0ZShcIm1vdmVfdG9cIilcbiAgICAgIC8vY29uc29sZS5sb2coXCJhcXVpIFwiKyBpZClcbiAgICAgIHZhciB0byA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcbiAgICAgIC8vY29uc29sZS5sb2codG8pXG4gICAgICAvL2NvbnNvbGUubG9nKGNvZGlnbylcbiAgICAgIHZhciBjb2RpZ28gPSBkZWNvZGVVUkkoZW1iZWQuZ2V0QXR0cmlidXRlKFwiY29kaWdvXCIpKVxuICAgICAgaWYgKHRvLmlubmVySFRNTCA9PT0gXCJcIil7XG4gICAgICAgIHRvLmlubmVySFRNTCA9IFwiPHNwYW4+PC9zcGFuPlwiXG4gICAgICAgIHBvc3RzY3JpYmUoXCIjXCIraWQsIGNvZGlnbylcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbnZhciBlamVjdXRhZG9zX2xpbWl0YWRvcyA9IGZhbHNlO1xuZnVuY3Rpb24gbGltaXRhZG9zKCl7XG4gIGlmKGVqZWN1dGFkb3NfbGltaXRhZG9zID09PSBmYWxzZSl7XG4gICAgZWplY3V0YWRvc19saW1pdGFkb3MgPSB0cnVlO1xuICAgIHZhciBsaW1pdGFkb3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmxpbWl0YWRvXCIpO1xuICAgIGxpbWl0YWRvcyA9IEFycmF5LmZyb20obGltaXRhZG9zKS5maWx0ZXIoZWwgPT4gIWVsLmNsb3Nlc3QoJy5zb2NpYXNfb3BpbmlvbicpKTtcblxuICAgIHZhciB3ID0gd2luZG93LmlubmVyV2lkdGhcbiAgICAgIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aFxuICAgICAgfHwgZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aDtcblxuICAgIGlmICh3ID4gNzY4KXtcbiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBsaW1pdGFkb3MubGVuZ3RoOyBpKyspe1xuICAgICAgICB2Y
1XIgbGltaXRhZG8gPSBsaW1pdGFkb3NbaV07XG4gICAgICAgIGxpbWl0YWRvLnBhcmVudE5vZGUuY2xhc3NMaXN0LmFkZChcImxpbWl0YXJcIilcbiAgICAgICAgaWYgKChsaW1pdGFkby5zY3JvbGxIZWlnaHQpID4gbGltaXRhZG8uY2xpZW50SGVpZ2h0IHx8IGxpbWl0YWRvLnNjcm9sbFdpZHRoID4gbGltaXRhZG8uY2xpZW50V2lkdGgpIHtcbiAgICAgICAgICBsaW1pdGFkby5wYXJlbnROb2RlLmNsYXNzTGlzdC5hZGQoXCJsaW1pdGFyXCIpO1xuICAgICAgICB9ZWxzZXtcbiAgICAgICAgICBsaW1pdGFkby5wYXJlbnROb2RlLmNsYXNzTGlzdC5yZW1vdmUoXCJsaW1pdGFyXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW1pdGFkby5zY3JvbGxIZWlnaHQgPj0gMzApIHtcbiAgICAgICAgICBsaW1pdGFkby5wYXJlbnROb2RlLmNsYXNzTGlzdC5hZGQoXCJsaW1pdGFyXCIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUlBO0FBSUE7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBRUE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7OztBQ2xEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFFQTtBQUNBLDRCQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBR0E7QUFJQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7Ozs7QUMzSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU9BO0FBQ0E7Ozs7OztBQzluREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQ
1TtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ
1UNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO
10FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBT0E7QUFDQTs7O0FDM25PQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ
10E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Q
1UFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBOzs7QUNqa0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFJQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFVQTtBQUNBO0FBTUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFLQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBR0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO
10FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQVdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBSUE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBSUE7QUFDQTtBQUdBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///17\n')},587:()=>{eval("$(document).ready(function () {\n  $(\"#articulo_user_id\").each(function () {\n    $(this).select2();\n  });\n});\n$('select#publicacion_digital_tema_id, select#articulo_publicacion_tema_id, select#publicacion_tema_id, select#articulo_tema_id, select#articulo_temas , select#tema_parents, select#foto_temas, select#multimedia_temas, select#galer
1ia_temas, select.temas').each(function () {\n  $(this).select2({\n    placeholder: 'Buscar temas',\n    minimumInputLength: 3,\n    allowClear: true,\n    cache: true,\n    ajax: {\n      delay: 250,\n      url: function (params) {\n        return '/api/temas/' + params.term;\n      },\n      dataType: 'json',\n      processResults: function (data, params) {\n        return {\n          results: data.data\n        };\n      }\n    }\n  });\n});\n$('select#search_foto_tema_id').each(function () {\n  $(this).select2({\n    placeholder: 'Buscar temas',\n    minimumInputLength: 3,\n    allowClear: true,\n    cache: true,\n    ajax: {\n      delay: 250,\n      url: function (params) {\n        return '/api/temas/' + params.term + '/todos';\n      },\n      dataType: 'json',\n      processResults: function (data, params) {\n        return {\n          results: data.data\n        };\n      }\n    }\n  });\n});\n$('select#articulo_autores, select#foto_autores, select#search_foto_autor_id, select#multimedia_autores, select#galeria_autores, select.autores').each(function () {\n  $(this).select2({\n    placeholder: 'Nombre a buscar',\n    minimumInputLength: 3,\n    allowClear: true,\n    cache: true,\n    ajax: {\n      delay: 250,\n      url: function (params) {\n        return '/api/autores/' + params.term;\n      },\n      dataType: 'json',\n      processResults: function (data, params) {\n        return {\n          results: data.data\n        };\n      }\n    }\n  });\n});\nfunction hacer_anuncios_seleccionable() {\n  $('select.anuncios').each(function (i, sel) {\n    anuncio_seleccionable(sel);\n  });\n}\nfunction anuncio_seleccionable(sel) {\n  $(sel).select2({\n    placeholder: 'Nombre a buscar',\n    minimumInputLength: 2,\n    allowClear: true,\n    cache: true,\n    ajax: {\n      delay: 250,\n      url: function (params) {\n        return '/api/anuncios/' + params.term;\n      },\n      dataType: 'json',\n      processResults: function (data, params) {\n        return {\n          results: data.data\n        };\n      }\n    }\n  });\n  $(sel).on('change', function () {\n    var titulo = $(this).find('option:selected').text();\n    $(this).parent().parent().find('.anuncio_t').val(titulo);\n  });\n}\nhacer_anuncios_seleccionable();\nfunction fotos() {\n  $('select#publicacion_foto_id, select#articulo_foto_id, select#articulo_foto_portada_id, select#doc_interno_foto_id, select#acceso_foto_id, select#formulario_fondo_id, select.foto').each(function () {\n    $(this).select2({\n      placeholder: 'Buscar foto',\n      minimumInputLength: 3,\n      allowClear: true,\n      cache: true,\n      ajax: {\n        delay: 250,\n        url: function (params) {\n          return '/api/fotos/' + params.term;\n        },\n        dataType: 'json',\n        processResults: function (data, params) {\n          return {\n            results: data.data\n          };\n        }\n      }\n    });\n  });\n}\nfotos();
1\nfunction galerias() {\n  $('select.galeria').each(function () {\n    $(this).select2({\n      placeholder: 'Buscar galería',\n      minimumInputLength: 3,\n      allowClear: true,\n      cache: true,\n      ajax: {\n        delay: 250,\n        url: function (params) {\n          return '/api/galerias/' + params.term;\n        },\n        dataType: 'json',\n        processResults: function (data, params) {\n          return {\n            results: data.data\n          };\n        }\n      }\n    });\n  });\n}\ngalerias();\nfunction multimedias() {\n  $('select.multimedia').each(function () {\n    $(this).select2({\n      placeholder: 'Buscar multimedia',\n      minimumInputLength: 3,\n      allowClear: true,\n      cache: true,\n      ajax: {\n        delay: 250,\n        url: function (params) {\n          return '/api/multimedia/' + params.term;\n        },\n        dataType: 'json',\n        processResults: function (data, params) {\n          return {\n            results: data.data\n          };\n        }\n      }\n    });\n  });\n}\nmultimedias();\n$('.articulo_s').each(function (i, sel) {\n  articulo_seleccionable(sel);\n});\nfunction hacer_articulos_seleccionables() {\n  $('.articulo_s').each(function (i, sel) {\n    articulo_seleccionable(sel);\n  });\n}\nfunction articulo_seleccionable(sel) {\n  $(sel).select2({\n    placeholder: 'Buscar artículo',\n    minimumInputLength: 3,\n    allowClear: true,\n    cache: true,\n    ajax: {\n      delay: 250,\n      url: function (params) {\n        return '/api/articulos/' + params.term;\n      },\n      dataType: 'json',\n      processResults: function (data, params) {\n        return {\n          results: data.data\n        };\n      }\n    }\n  });\n  $(sel).on('change', function () {\n    var titulo = $(this).find('option:selected').text();\n    $(this).parent().parent().find('.articulo_t').val(titulo);\n  });\n}\n;\n$('.articulo_s_todos').each(function (i, sel) {\n  articulo_seleccionable_todos(sel);\n});\nfunction hacer_articulos_todos_seleccionables() {\n  $('.articulo_s_todos').each(function (i, sel) {\n    articulo_seleccionable_todos(sel);\n  });\n}\nfunction articulo_seleccionable_todos(sel) {\n  $(sel).select2({\n    placeholder: 'Buscar artículo',\n    minimumInputLength: 3,\n    allowClear: true,\n    cache: true,\n    ajax: {\n      delay: 250,\n      url: function (params) {\n        return '/api/articulos_todos/' + params.term;\n      },\n      dataType: 'json',\n      processResults: function (data, params) {\n        return {\n          results: data.data\n        };\n      }\n    }\n  });\n  $(sel).on('change', function () {\n    var titulo = $(this).find('option:selected').text();\n    $(this).parent().parent().find('.articulo_t').val(titulo);\n  });\n}\n;\n$(document).on('click', '.anhadir_articulo_pub_digi', function (e) {\n  e.preventDefault();\n  let time = new Date().getTime();\n  let template = $(this).data(\"template\");\n  var tipo = $(this).parent().find(\".nombre\").find(\".atopame\").length;\n  if (tipo > 0) {\n    var id = $(this).parent().find(\".nombre\").find(\".atopame\").eq(0).attr(\"id\");\n    id = id.split('_')[2];\n  } else {\n    var id = $(this).parent().find(\".nombre\").find(\".atopame2\").eq(0).attr(\"id\");\n    id = id.split('_')[3];\n  }\n  var uniq_template = template.replace(/articulos\\]\\[0\\]/g, `articulos][${time}]`).replace(/colas\\]\\[0\\]/g, `colas][${id}]`).replace(/apartados\\]\\[0\\]/g, `apartados][${id}]`).replace(/articulos_0_/g, `articulos_${time}_`).replace(/colas_0_/g, `colas_${id}_`).replace(/apartados_0_/g, `apartados_${id}_`);\n  var contenedor_original = this.parentNode.querySelector(\".entradas\").cloneNode(true);\n  var articulos_original = contenedor_original.querySelectorAll(\"tr\");\n  $(this).parent().find(\".entradas\").prepend(uniq_template);\n  //$(this).parent().find(\".fila\").eq(0).before(uniq_template);\n  hacer_articulos_seleccionables();\n  hacer_articulos_todos_seleccionables();\n  var ubicacion = $('#portada_ubicacion').val();\n  $('.form-apartado-nuevo .portada_ubicacion').val(ubicacion);\n});\n// \n// Gestión de colas\n$(document).on('click', '.anhadir_articulo', function (e) {\n  e.preventDefault();\n  let time = new Date().getTime();\n  let template = $(this).data(\"template\");\n  var tipo = $(this).parent().find(\".nombre\").find(\".atopame\").length;\n  if (tipo > 0) {\n    var id = $(this).parent().find(\".nombre\").find(\".atopame\").eq(0).attr(\"id\");\n    id = id.split('_')[2];\n  } else {\n    var id = $(this).parent().find(\".nombre\").find(\".atopame2\").eq(0).attr(\"id\");\n    id = id.split('_')[3];\n  }\n  var uniq_template = template.replace(/articulos\\]\\[0\\]/g, `articulos][${time}]`).replace(/colas\\]\\[0\\]/g, `colas][${id}]`).replace(/apartados\\]\\[0\\]/g, `apartados][${id}]`).replace(/articulos_0_/g, `articulos_${time}_`).replace(/colas_0_/g, `colas_${id}_`).replace(/apartados_0_/g, `apartados_${id}_`);\n  var contenedor_original = this.parentNode.querySelector(\".entradas\").cloneNode(true);\n  var articulos_original = contenedor_original.querySelectorAll(\"tr\");\n  var elemento = $(this).parent().find(\".entradas\").prepend(uniq_template);\n\n  //$(this).parent().find(\".fila\").eq(0).before(uniq_template);\n  hacer_articulos_seleccionables();\n  hacer_articulos_todos_seleccionables();\n  var ubicacion = $('#portada_ubicacion').val();\n  $('.form-apartado-nuevo .portada_ubicacion').val(ubicacion);\n  var contenedor = this.parentNode.querySelector(\".entradas\");\n  var articulos = contenedor.querySelectorAll(\"tr\");\n  contenedor.innerHTML = \"\";\n  articulos = ordenar_array_con_fijos(articulos_original, articulos);\n  articulos.forEach(function (e, i, a) {\n    contenedor.appendChild(e);\n  });\n  normalizar_cola(contenedor);\n  ordenar_cola(contenedor);\n  normalizar_cola(contenedor);\n  botones_arriba_abajo_colas();\n});\nfunction ordenar_array_con_fijos(original, nuevo) {\n  var normales = [...nuevo].filter(e => !e.querySelector(\".chincheta .form-control\").checked);\n  var normal_i = 0;\n  var l = nuevo.length;\n  nuevo = [];\n  for (let i = 0; i < l;
1 i++) {\n    if (original[i] && original[i].querySelector(\".chincheta .form-control\").checked) {\n      nuevo[i] = original[i];\n    } else {\n      nuevo[i] = normales[normal_i];\n      ++normal_i;\n    }\n  }\n  return nuevo;\n}\nfunction ordenar_cola(contenedor) {\n  var articulos = contenedor.querySelectorAll(\"tr\");\n  articulos = Array.from(articulos).sort(function (a, b) {\n    //if (a.querySelector(\".chincheta .form-control\").checked){return - 1};\n    //if (b.querySelector(\".chincheta .form-control\").checked){return + 1};\n    a = a.querySelector(\".orden .form-control\").value;\n    b = b.querySelector(\".orden .form-control\").value;\n    return a - b;\n  });\n  //.forEach(el =>{ contenedor.appendChild(el) })\n\n  contenedor.innerHTML = \"\";\n  articulos.forEach(function (e, i, a) {\n    contenedor.appendChild(e);\n  });\n}\nfunction normalizar_cola(contenedor) {\n  var articulos = contenedor.querySelectorAll(\"tr\");\n  articulos.forEach(function (e, i, a) {\n    orden = e.querySelector(\".orden .form-control\");\n    orden.value = (i + 1) * 10;\n  });\n}\nvar arriba = function (event) {\n  event.preventDefault();\n  event.stopPropagation();\n  var orden = this.parentNode.parentNode.querySelector(\".orden .form-control\");\n  orden.value = parseInt(orden.value) - 15;\n  var contenedor = this.parentNode.parentNode.parentNode;\n  ordenar_cola(contenedor);\n  normalizar_cola(contenedor);\n};\nvar abajo = function (event) {\n  event.preventDefault();\n  event.stopPropagation();\n  var orden = this.parentNode.parentNode.querySelector(\".orden .form-control\");\n  orden.value = parseInt(orden.value) + 15;\n  var contenedor = this.parentNode.parentNode.parentNode;\n  ordenar_cola(contenedor);\n  normalizar_cola(contenedor);\n};\nfunction botones_arriba_abajo_colas() {\n  var upButtons = document.querySelectorAll('.ordenar .up');\n  var downButtons = document.querySelectorAll('.ordenar .down');\n  for (var i = 0; i < upButtons.length; i++) {\n    upButtons[i].removeEventListener('click', arriba);\n  }\n  for (var i = 0; i < downButtons.length; i++) {\n    downButtons[i].removeEventListener('click', abajo);\n  }\n  for (var i = 0; i < upButtons.length; i++) {\n    upButtons[i].addEventListener('click', arriba);\n  }\n  for (var i = 0; i < downButtons.length; i++) {\n    downButtons[i].addEventListener('click', abajo);\n  }\n}\nbotones_arriba_abajo_colas();\n$(document).on('click', '#anhadir_seccion', function (e) {\n  e.preventDefault();\n  let time = new Date().getTime();\n  let template = $(this).data(\"template\");\n  var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n  uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n  $(this).parent().after(uniq_template);\n  fotos();\n  galerias();\n  multimedias();\n});\n\n// Gestión de apartados pub digital\n$(document).on('click', '#anhadir_seccion_pub_dig', function (e) {\n  e.preventDefault();\n  let time = new Date().getTime();\n  let template = $(this).data(\"template\");\n  var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n  uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n  $(this).before(uniq_template);\n});\n$(document).on('click', '#anhadir_apartado', function (e) {\n  e.preventDefault();\n  let time = new Date().getTime();\n  let template = $(this).data(\"template\");\n  var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n  uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n  $(this).before(uniq_template);\n  $('.summernote').summernote();\n  fotos();\n  hacer_articulos_todos_seleccionables();\n  hacer_anuncios_seleccionable();\n});\n$(document).on('click', '#anhadir_foto_archivo', function (e) {\n  e.preventDefault();\n  let time = new Date().getTime();\n  let template = $(this).data(\"template\");\n  var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n  uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n  $(this).parent().before(uniq_template);\n  fotos();\n});\n// Secciones articulo\n$(document).on('click', '#anhadir_seccion_articulo', function (e) {\n  e.preventDefault();\n  let time = new Date().getTime();\n  let template = $(this).data(\"template\");\n  var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n  uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n  //$(this).parent().before(uniq_template);\n  $(this).before(uniq_template);\n  $('.summernote').summernote();\n  fotos();\n  multimedias();\n  galerias();\n});\n$(document).on('click', '#anhadir_traduccion', function (e) {\n  e.preventDefault();\n  let time = new Date().getTime();\n  let template = $(this).data(\"template\");\n  var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n  uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n  $(this).parent().before(uniq_template);\n  hacer_articulos_seleccionables();\n  hacer_articulos_todos_seleccionables();\n});\n$(document).on('click', '#anhadir_link', function (e) {\n  e.preventDefault();\n  let time = new Date().getTime();\n  let template = $(this).data(\"template\");\n  var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n  uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n  $(this).parent().before(uniq_template);\n});\n$(document).on('click', '#anhadir_menu', function (e) {\n  e.preventDefault();\n  let time = new Date().getTime();\n  let template = $(this).data(\"template\");\n  var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n  uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n  $(this).parent().before(uniq_template);\n});\n$(document).on('click', '#anhadir_comentario', function (e) {\n  e.preventDefault();\n  let time = new Date().getTime();\n  let template = $(this).data(\"template\");\n  var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n  uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n  $(this).parent().before(uniq_template);\n  cambio();\n  actualizarCSRF();\n});\n$(document).on('click', '.comentar-comentario', function (e) {\n  var comentario_id = $(this).attr('data-comentario');\n  e.preventDefault();\n  let time = new Date().getTime();\n  let template = $('#anhadir_comentario').data(\"template\");\n  var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n  uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n  $(\"#anhadir_comentario\").parent().before(uniq_template);\n  $('#comentario_comentario_id').val(comentario_id);\n  cambio();\n  actualizarCSRF();\n});\n$(document).on('click', '#anhadir_tipo', function (e) {\n  e.preventDefault();\n  let time = new Date().getTime();\n  let template = $(this).data(\"template\");\n  var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n  uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n  $(this).parent().before(uniq_template);\n  $('.summernote').summernote();\n});\nfunction cambio() {\n  if ($('#articulo-completo').length) {\n    var token = $('#articulo-completo').attr(\"data-token\");\n    $('#articulo-completo input[name=\"_csrf_token\"]').each(function () {\n      $(this).val(token);\n    });\n  }\n}\n$(document).on('click', '.borrar_seccion', function (e) {\n  e.preventDefault();\n  $(this).parent().parent().remove();\n});\n$(document).on('click', '.anular-comentario', function (e) {\n  $('.box').remove();\n});\nfunction ImagenUpdate(obj) {\n  if (!window.FileReader) {} else {\n    var reader = new FileReader();\n    var target = null;\n    reader.onload = function (e) {\n      target = e.target || e.srcElement;\n      $(obj).parent().parent().find(\".preview\").prop(\"src\", target.result);\n      $(obj).parent().parent().find(\".preview\").removeClass(\"hidden\");\n    };
1\n    reader.readAsDataURL(obj.files[0]);\n  }\n}\n;\n$(document).on('change', 'input.preview', function () {\n  ImagenUpdate(this);\n});\n\n//wysiwyg\n$(document).ready(function () {\n  if (typeof $('.summernote').summernote === \"function\") {\n    $('.summernote').summernote({\n      styleWithSpan: false,\n      lang: 'es-ES',\n      height: 400,\n      dialogsFade: true,\n      toolbar: [['style', ['bold', 'italic', 'underline', 'clear']], ['font', ['strikethrough', 'superscript', 'subscript']], ['para', ['ul', 'ol', 'paragraph']], ['link', ['style']], ['insert', ['picture', 'video', 'link', 'unlink']], ['salto', ['articulo', 'foto', 'codigo', 'borrar']], ['view', ['codeview']], ['insert', ['template']]],\n      popover: {\n        image: [['custom', ['imageAttributes', 'captionIt']], ['imagesize', ['imageSize100', 'imageSize50', 'imageSize25']], ['float', ['floatLeft', 'floatRight', 'floatNone']], ['remove', ['removeMedia']]]\n      },\n      imageAttributes: {\n        imageDialogLayout: 'default',\n        // default|horizontal\n        icon: '<i class=\"note-icon-pencil\"/>',\n        removeEmpty: false // true = remove attributes | false = leave empty if present\n      },\n      displayFields: {\n        imageBasic: true,\n        // show/hide Title, Source, Alt fields\n        imageExtra: true,\n        // show/hide Alt, Class, Style, Role fields\n        linkBasic: true,\n        // show/hide URL and Target fields for link\n        linkExtra: false // show/hide Class, Rel, Role fields for link\n      },\n      captionIt: {\n        icon: '<i class=\"note-icon-pencil\"}/>',\n        // Leave empty or don't set for default Icon.\n        figureClass: 'figure-interna',\n        figcaptionClass: 'pie'\n      },\n      cleaner: {\n        notTime: 500,\n        // Time to display Notifications.\n        action: 'both',\n        // both|button|paste 'button' only cleans via toolbar button, 'paste' only clean when pasting content, both does both options.\n        newline: '<br>',\n        // Summernote's default is to use '<p><br></p>'\n        notStyle: 'position:absolute;top:0;left:0;right:0',\n        // Position of Notification\n        icon: '<i class=\"note-icon\">[x]</i>',\n        keepHtml: true,\n        // Remove all Html formats\n        keepClasses: false,\n        // Remove Classes\n        keepOnlyTags: ['<br>', '<a>', '<p>'],\n        // If keepHtml is true, remove all tags except these\n        badTags: ['style', 'script', 'applet', 'embed', 'noframes', 'n
1oscript', 'html'],\n        // Remove full tags with contents\n        badAttributes: ['dir', 'id', 'style', 'start', 'name', 'class', 'align', 'ontouchstart'] // Remove attributes from remaining tags\n      },\n      template: {\n        path: '/js/summernote/tpls',\n        list: {\n          'recuadro_generico': 'Recuadro genérico',\n          'recuadro_dcha': 'Recuadro derecho',\n          'recuadro_izq': 'Recuadro izquierdo',\n          'recuadro': 'Recuadro \"antiguo\"'\n        }\n      }\n    });\n  }\n});\n////\n\n;\n(function ($, window, document, undefined) {\n  $.fn.doubleTapToGo = function (params) {\n    if (!('ontouchstart' in window) && !navigator.msMaxTouchPoints && !navigator.userAgent.toLowerCase().match(/windows phone os 7/i)) return false;\n    this.each(function () {\n      var curItem = false;\n      $(this).on('click', function (e) {\n        var item = $(this);\n        if (item[0] != curItem[0]) {\n          e.preventDefault();\n          curItem = item;\n        }\n      });\n      $(document).on('click touchstart MSPointerDown', function (e) {\n        var resetItem = true,\n          parents = $(e.target).parents();\n        for (var i = 0; i < parents.length; i++) if (parents[i] == curItem[0]) resetItem = false;\n        if (resetItem) curItem = false;\n      });\n    });\n    return this;\n  };\n})(jQuery, window, document);\n$('.cambiarNodoPortada ul').doubleTapToGo();\n$(\".buscar\").hover(function () {\n  $(this).find(\".form-control\").focus();\n});\n$(document).ready(function () {\n  $('.index-listados').each(function () {\n    var url = $(this).attr('data-path');\n    var total = $('.index-listados .page-link').length - 1;\n    $('.index-listados .page-link').each(function (i) {\n      $(this).attr('href', $(this).attr('href').replace(/\\/\\w*\\?+/g, url + \"?\"));\n    });\n    if (total > 11) {\n      var index = $('.index-listados .page-item').index($('.index-listados .page-item.active'));\n      var medio = Math.round(total / 2);\n      var c1 = Math.round(total / 4);\n      var c2 = Math.round(total / 4 * 3);\n      var i1 = index - 1;\n      var i2 = index + 1;\n      var array = [0, 1, total - 1, c1, medio, c2, i1, index, i2, total];\n      $('.index-listados .page-item').each(function (i) {\n        if ($.inArray(i, array) == -1) {\n          $(this).remove();\n        }\n      });\n    }\n  });\n});\nfunction enviarContactoForm(data) {\n  var XHR = new XMLHttpRequest();\n  var FD = new FormData(document.getElementById('formularioContacto'));\n  var csrf = document.querySelector(\"meta[name=csrf-token]\").content;\n  //var formData = JSON.stringify(data);\n\n  for (name in data) {\n    FD.append(name, data[name]);\n  }\n  XHR.addEventListener('load', function (event) {\n    alert('Yeah! Data sent and response loaded.');\n  });\n  XHR.addEventListener('error', function (event) {\n    alert('Oops! Something went wrong.');\n  });\n\n  //XHR.open('POST', 'https://example.com/');\n  XHR.open('POST', 'http://127.0.0.1:4000/');\n  XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n  XHR.setRequestHeader(\"X-CSRF-Token\", csrf);\n  XHR.send(FD);\n  //XHR.send( \"formulario=\"+formData );\n}\nfunction actualizarCSRF() {\n  var csrf = document.querySelector('meta[name=\"csrf-token\"]').content;\n  var inputs = document.querySelectorAll(\"input[name='_csrf_token']\");\n  for (var i = 0; i < inputs.length; ++i) {\n    inputs[i].value = csrf;\n  }\n}\n$(document).ready(function () {\n  actualizarCSRF();\n});\n$('#ComentariosCuenta').on('show.bs.modal', function (event) {\n  var button = $(event.relatedTarget);\n  var url = button.data('url');\n  var modal = $(this);\n  var q = modal.find('.con_redireccion');\n  modal.find('.con_redireccion').attr(\"href\", \"/comentar\" + url);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTg3LmpzIiwibmFtZXMiOlsiJCIsImRvY3VtZW50IiwicmVhZHkiLCJlYWNoIiwic2VsZWN0MiIsInBsYWNlaG9sZGVyIiwibWluaW11bUlucHV0TGVuZ3RoIiwiYWxsb3dDbGVhciIsImNhY2hlIiwiYWpheCIsImRlbGF5IiwidXJsIiwicGFyYW1zIiwidGVybSIsImRhdGFUeXBlIiwicHJvY2Vzc1Jlc3VsdHMiLCJkYXRhIiwicmVzdWx0cyIsImhhY2VyX2FudW5jaW9zX3NlbGVjY2lvbmFibGUiLCJpIiwic2VsIiwiYW51bmNpb19zZWxlY2Npb25hYmxlIiwib24iLCJ0aXR1bG8iLCJmaW5kIiwidGV4dCIsInBhcmVudCIsInZhbCIsImZvdG9zIiwiZ2FsZXJpYXMiLCJtdWx0aW1lZGlhcyIsImFydGljdWxvX3NlbGVjY2lvbmFibGUiLCJoYWNlcl9hcnRpY3Vsb3Nfc2VsZWNjaW9uYWJsZXMiLCJhcnRpY3Vsb19zZWxlY2Npb25hYmxlX3RvZG9zIiwiaGFjZXJfYXJ0aWN1bG9zX3RvZG9zX3NlbGVjY2lvbmFibGVzIiwiZSIsInByZXZlbn
1REZWZhdWx0IiwidGltZSIsIkRhdGUiLCJnZXRUaW1lIiwidGVtcGxhdGUiLCJ0aXBvIiwibGVuZ3RoIiwiaWQiLCJlcSIsImF0dHIiLCJzcGxpdCIsInVuaXFfdGVtcGxhdGUiLCJyZXBsYWNlIiwiY29udGVuZWRvcl9vcmlnaW5hbCIsInBhcmVudE5vZGUiLCJxdWVyeVNlbGVjdG9yIiwiY2xvbmVOb2RlIiwiYXJ0aWN1bG9zX29yaWdpbmFsIiwicXVlcnlTZWxlY3RvckFsbCIsInByZXBlbmQiLCJ1YmljYWNpb24iLCJlbGVtZW50byIsImNvbnRlbmVkb3IiLCJhcnRpY3Vsb3MiLCJpbm5lckhUTUwiLCJvcmRlbmFyX2FycmF5X2Nvbl9maWpvcyIsImZvckVhY2giLCJhIiwiYXBwZW5kQ2hpbGQiLCJub3JtYWxpemFyX2NvbGEiLCJvcmRlbmFyX2NvbGEiLCJib3RvbmVzX2FycmliYV9hYmFqb19jb2xhcyIsIm9yaWdpbmFsIiwibnVldm8iLCJub3JtYWxlcyIsImZpbHRlciIsImNoZWNrZWQiLCJub3JtYWxfaSIsImwiLCJBcnJheSIsImZyb20iLCJzb3J0IiwiYiIsInZhbHVlIiwib3JkZW4iLCJhcnJpYmEiLCJldmVudCIsInN0b3BQcm9wYWdhdGlvbiIsInBhcnNlSW50IiwiYWJham8iLCJ1cEJ1dHRvbnMiLCJkb3duQnV0dG9ucyIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJhZGRFdmVudExpc3RlbmVyIiwiYWZ0ZXIiLCJiZWZvcmUiLCJzdW1tZXJub3RlIiwiY2FtYmlvIiwiYWN0dWFsaXphckNTUkYiLCJjb21lbnRhcmlvX2lkIiwidG9rZW4iLCJyZW1vdmUiLCJJbWFnZW5VcGRhdGUiLCJvYmoiLCJ3aW5kb3ciLCJGaWxlUmVhZGVyIiwicmVhZGVyIiwidGFyZ2V0Iiwib25sb2FkIiwic3JjRWxlbWVudCIsInByb3AiLCJyZXN1bHQiLCJyZW1vdmVDbGFzcyIsInJlYWRBc0RhdGFVUkwiLCJmaWxlcyIsInN0eWxlV2l0aFNwYW4iLCJsYW5nIiwiaGVpZ2h0IiwiZGlhbG9nc0ZhZGUiLCJ0b29sYmFyIiwicG9wb3ZlciIsImltYWdlIiwiaW1hZ2VBdHRyaWJ1dGVzIiwiaW1hZ2VEaWFsb2dMYXlvdXQiLCJpY29uIiwicmVtb3ZlRW1wdHkiLCJkaXNwbGF5RmllbGRzIiwiaW1hZ2VCYXNpYyIsImltYWdlRXh0cmEiLCJsaW5rQmFzaWMiLCJsaW5rRXh0cmEiLCJjYXB0aW9uSXQiLCJmaWd1cmVDbGFzcyIsImZpZ2NhcHRpb25DbGFzcyIsImNsZWFuZXIiLCJub3RUaW1lIiwiYWN0aW9uIiwibmV3bGluZSIsIm5vdFN0eWxlIiwia2VlcEh0bWwiLCJrZWVwQ2xhc3NlcyIsImtlZXBPbmx5VGFncyIsImJhZFRhZ3MiLCJiYWRBdHRyaWJ1dGVzIiwicGF0aCIsImxpc3QiLCJ1bmRlZmluZWQiLCJmbiIsImRvdWJsZVRhcFRvR28iLCJuYXZpZ2F0b3IiLCJtc01heFRvdWNoUG9pbnRzIiwidXNlckFnZW50IiwidG9Mb3dlckNhc2UiLCJtYXRjaCIsImN1ckl0ZW0iLCJpdGVtIiwicmVzZXRJdGVtIiwicGFyZW50cyIsImpRdWVyeSIsImhvdmVyIiwiZm9jdXMiLCJ0b3RhbCIsImluZGV4IiwibWVkaW8iLCJNYXRoIiwicm91bmQiLCJjMSIsImMyIiwiaTEiLCJpMiIsImFycmF5IiwiaW5BcnJheSIsImVudmlhckNvbnRhY3RvRm9ybSIsIlhIUiIsIlhNTEh0dHBSZXF1
1ZXN0IiwiRkQiLCJGb3JtRGF0YSIsImdldEVsZW1lbnRCeUlkIiwiY3NyZiIsImNvbnRlbnQiLCJuYW1lIiwiYXBwZW5kIiwiYWxlcnQiLCJvcGVuIiwic2V0UmVxdWVzdEhlYWRlciIsInNlbmQiLCJpbnB1dHMiLCJidXR0b24iLCJyZWxhdGVkVGFyZ2V0IiwibW9kYWwiLCJxIl0sInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9mb3JtdWxhcmlvcy5qcz81ZTNlIl0sInNvdXJjZXNDb250ZW50IjpbIiQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uKCkge1xuICAkKFwiI2FydGljdWxvX3VzZXJfaWRcIikuZWFjaChmdW5jdGlvbigpIHtcbiAgICAkKHRoaXMpLnNlbGVjdDIoKTtcbiAgfSk7XG59KTtcbiQoJ3NlbGVjdCNwdWJsaWNhY2lvbl9kaWdpdGFsX3RlbWFfaWQsIHNlbGVjdCNhcnRpY3Vsb19wdWJsaWNhY2lvbl90ZW1hX2lkLCBzZWxlY3QjcHVibGljYWNpb25fdGVtYV9pZCwgc2VsZWN0I2FydGljdWxvX3RlbWFfaWQsIHNlbGVjdCNhcnRpY3Vsb190ZW1hcyAsIHNlbGVjdCN0ZW1hX3BhcmVudHMsIHNlbGVjdCNmb3RvX3RlbWFzLCBzZWxlY3QjbXVsdGltZWRpYV90ZW1hcywgc2VsZWN0I2dhbGVyaWFfdGVtYXMsIHNlbGVjdC50ZW1hcycpLmVhY2goZnVuY3Rpb24oKXtcbiAgJCh0aGlzKS5zZWxlY3QyKHtcbiAgICBwbGFjZWhvbGRlcjogJ0J1c2NhciB0ZW1hcycsXG4gICAgbWluaW11bUlucHV0TGVuZ3RoOiAzLCAgICAgICAgICAgIFxuICAgIGFsbG93Q2xlYXI6IHRydWUsXG4gICAgY2FjaGU6IHRydWUsXG4gICAgYWpheDoge1xuICAgICAgZGVsYXk6IDI1MCxcbiAgICAgIHVybDogIGZ1bmN0aW9uIChwYXJhbXMpIHtcbiAgICAgICAgcmV0dXJuICcvYXBpL3RlbWFzLycgKyBwYXJhbXMudGVybTtcbiAgICAgIH0sXG4gICAgICBkYXRhVHlwZTogJ2pzb24nLFxuICAgICAgcHJvY2Vzc1Jlc3VsdHM6IGZ1bmN0aW9uIChkYXRhLCBwYXJhbXMpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZXN1bHRzOiBkYXRhLmRhdGFcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSlcbn0pOyBcbiQoJ3NlbGVjdCNzZWFyY2hfZm90b190ZW1hX2lkJykuZWFjaChmdW5jdGlvbigpe1xuICAkKHRoaXMpLnNlbGVjdDIoe1xuICAgIHBsYWNlaG9sZGVyOiAnQnVzY2FyIHRlbWFzJyxcbiAgICBtaW5pbXVtSW5wdXRMZW5ndGg6IDMsICAgICAgICAgICAgXG4gICAgYWxsb3dDbGVhcjogdHJ1ZSxcbiAgICBjYWNoZTogdHJ1ZSxcbiAgICBhamF4OiB7XG4gICAgICBkZWxheTogMjUwLFxuICAgICAgdXJsOiAgZnVuY3Rpb24gKHBhcmFtcykge1xuICAgICAgICByZXR1cm4gJy9hcGkvdGVtYXMvJyArIHBhcmFtcy50ZXJtICsgJy90b2Rvcyc7XG4gICAgICB9LFxuICAgICAgZGF0YVR5cGU6ICdqc29uJyxcbiAgICAgIHByb2Nlc3NSZXN1bHRzOiBmdW5jdGlvbiAoZGF0YSwgcGFyYW1zKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzdWx0czogZGF0YS5kYXRhXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pXG59KTsgXG4kKCdzZWxlY3QjYXJ0aWN1bG9fYXV0b3Jlcywgc2VsZWN0I2ZvdG9fYXV0b3Jlcywgc2VsZWN0I3NlYXJjaF9mb3RvX2F1dG9yX2lkLCBzZWxlY3QjbXVsdGltZWRpYV9hdXRvcmVzLCBzZWxlY3QjZ2FsZXJpYV9hdXRvcmVzLCBzZWxlY3QuYXV0b3JlcycpLmVhY2goZnVuY3Rpb24oKXtcbiAgJCh0aGlzKS5zZWxlY3QyKHtcbiAgICBwbGFjZWhvbGRlcjogJ05vbWJyZSBhIGJ1c2NhcicsXG4gICAgbWluaW11bUlucHV0TGVuZ3RoOiAzLCAgICAgICAgICAgIFxuICAgIGFsbG93Q2xlYXI6IHRydWUsXG4gICAgY2FjaGU6IHRydWUsXG4gICAgYWpheDoge1xuICAgICAgZGVsYXk6IDI1MCxcbiAgICAgIHVybDogIGZ1bmN0aW9uIChwYXJhbXMpIHtcbiAgICAgICAgcmV0dXJuICcvYXBpL2F1dG9yZXMvJyArIHBhcmFtcy50ZXJtO1xuICAgICAgfSxcbiAgICAgIGRhdGFUeXBlOiAnanNvbicsXG4gICAgICBwcm9jZXNzUmVzdWx0czogZnVuY3Rpb24gKGRhdGEsIHBhcmFtcykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHJlc3VsdHM6IGRhdGEuZGF0YVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KVxufSk7IFxuZnVuY3Rpb24gaGFjZXJfYW51bmNpb3Nfc2VsZWNjaW9uYWJsZSgpe1xuICAkKCdzZWxlY3QuYW51bmNpb3MnKS5lYWNoKGZ1bmN0aW9uKGksIHNlbCl7YW51bmNpb19zZWxlY2Npb25hYmxlKHNlbCl9KTtcbn1cbmZ1bmN0aW9uIGFudW5jaW9fc2VsZWNjaW9uYWJsZShzZWwpIHsgICBcbiAgICAkKHNlbCkuc2VsZWN0Mih7XG4gICAgICBwbGFjZWhvbGRlcjogJ05vbWJyZSBhIGJ1c2NhcicsXG4gICAgICBtaW5pbXVtSW5wdXRMZW5ndGg6IDIsICAgICAgICAgICAgXG4gICAgICBhbGxvd0NsZWFyOiB0cnVlLFxuICAgICAgY2FjaGU6IHRydWUsXG4gICAgICBhamF4OiB7XG4gICAgICAgIGRlbGF5OiAyNTAsXG4gICAgICAgIHVybDogIGZ1bmN0aW9uIChwYXJhbXMpIHtcbiAgICAgICAgICByZXR1cm4gJy9hcGkvYW51bmNpb3MvJyArIHBhcmFtcy50ZXJtO1xuICAgICAgICB9LFxuICAgICAgICBkYXRhVHlwZTogJ2pzb24nLFxuICAgICAgICBwcm9jZXNzUmVzdWx0czogZnVuY3Rpb24gKGRhdGEsIHBhcmFtcykge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZXN1bHRzOiBkYXRhLmRhdGFcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICAkKHNlbCkub24oJ2NoYW5nZScsKGZ1bmN0aW9uKCl7XG4gICAgICB2Y
1XIgdGl0dWxvID0gJCh0aGlzKS5maW5kKCdvcHRpb246c2VsZWN0ZWQnKS50ZXh0KCk7XG4gICAgICAkKHRoaXMpLnBhcmVudCgpLnBhcmVudCgpLmZpbmQoJy5hbnVuY2lvX3QnKS52YWwodGl0dWxvKTtcbiAgICB9KSk7XG59XG5oYWNlcl9hbnVuY2lvc19zZWxlY2Npb25hYmxlKCk7XG5mdW5jdGlvbiBmb3RvcygpIHsgICBcbiAgJCgnc2VsZWN0I3B1YmxpY2FjaW9uX2ZvdG9faWQsIHNlbGVjdCNhcnRpY3Vsb19mb3RvX2lkLCBzZWxlY3QjYXJ0aWN1bG9fZm90b19wb3J0YWRhX2lkLCBzZWxlY3QjZG9jX2ludGVybm9fZm90b19pZCwgc2VsZWN0I2FjY2Vzb19mb3RvX2lkLCBzZWxlY3QjZm9ybXVsYXJpb19mb25kb19pZCwgc2VsZWN0LmZvdG8nKS5lYWNoKGZ1bmN0aW9uKCl7XG4gICAgJCh0aGlzKS5zZWxlY3QyKHtcbiAgICAgIHBsYWNlaG9sZGVyOiAnQnVzY2FyIGZvdG8nLFxuICAgICAgbWluaW11bUlucHV0TGVuZ3RoOiAzLCAgICAgICAgICAgIFxuICAgICAgYWxsb3dDbGVhcjogdHJ1ZSxcbiAgICAgIGNhY2hlOiB0cnVlLFxuICAgICAgYWpheDoge1xuICAgICAgICBkZWxheTogMjUwLFxuICAgICAgICB1cmw6ICBmdW5jdGlvbiAocGFyYW1zKSB7XG4gICAgICAgICAgcmV0dXJuICcvYXBpL2ZvdG9zLycgKyBwYXJhbXMudGVybTtcbiAgICAgICAgfSxcbiAgICAgICAgZGF0YVR5cGU6ICdqc29uJyxcbiAgICAgICAgcHJvY2Vzc1Jlc3VsdHM6IGZ1bmN0aW9uIChkYXRhLCBwYXJhbXMpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVzdWx0czogZGF0YS5kYXRhXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcbiAgfSk7XG59XG5mb3RvcygpO1xuZnVuY3Rpb24gZ2FsZXJpYXMoKSB7ICAgXG4gICQoJ3NlbGVjdC5nYWxlcmlhJykuZWFjaChmdW5jdGlvbigpe1xuICAgICQodGhpcykuc2VsZWN0Mih7XG4gICAgICBwbGFjZWhvbGRlcjogJ0J1c2NhciBnYWxlcsOtYScsXG4gICAgICBtaW5pbXVtSW5wdXRMZW5ndGg6IDMsICAgICAgICAgICAgXG4gICAgICBhbGxvd0NsZWFyOiB0cnVlLFxuICAgICAgY2FjaGU6IHRydWUsXG4gICAgICBhamF4OiB7XG4gICAgICAgIGRlbGF5OiAyNTAsXG4gICAgICAgIHVybDogIGZ1bmN0aW9uIChwYXJhbXMpIHtcbiAgICAgICAgICByZXR1cm4gJy9hcGkvZ2FsZXJpYXMvJyArIHBhcmFtcy50ZXJtO1xuICAgICAgICB9LFxuICAgICAgICBkYXRhVHlwZTogJ2pzb24nLFxuICAgICAgICBwcm9jZXNzUmVzdWx0czogZnVuY3Rpb24gKGRhdGEsIHBhcmFtcykge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZXN1bHRzOiBkYXRhLmRhdGFcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KVxuICB9KTtcbn1cbmdhbGVyaWFzKCk7XG5cbmZ1bmN0aW9uIG11bHRpbWVkaWFzKCkgeyAgIFxuICAkKCdzZWxlY3QubXVsdGltZWRpYScpLmVhY2goZnVuY3Rpb24oKXtcbiAgICAkKHRoaXMpLnNlbGVjdDIoe1xuICAgICAgcGxhY2Vob2xkZXI6ICdCdXNjYXIgbXVsdGltZWRpYScsXG4gICAgICBtaW5pbXVtSW5wdXRMZW5ndGg6IDMsICAgICAgICAgICAgXG4gICAgICBhbGxvd0NsZWFyOiB0cnVlLFxuICAgICAgY2FjaGU6IHRydWUsXG4gICAgICBhamF4OiB7XG4gICAgICAgIGRlbGF5OiAyNTAsXG4gICAgICAgIHVybDogIGZ1bmN0aW9uIChwYXJhbXMpIHtcbiAgICAgICAgICByZXR1cm4gJy9hcGkvbXVsdGltZWRpYS8nICsgcGFyYW1zLnRlcm07XG4gICAgICAgIH0sXG4gICAgICAgIGRhdGFUeXBlOiAnanNvbicsXG4gICAgICAgIHByb2Nlc3NSZXN1bHRzOiBmdW5jdGlvbiAoZGF0YSwgcGFyYW1zKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlc3VsdHM6IGRhdGEuZGF0YVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gIH0pO1xufVxubXVsdGltZWRpYXMoKTtcblxuJCgnLmFydGljdWxvX3MnKS5lYWNoKGZ1bmN0aW9uKGksIHNlbCl7YXJ0aWN1bG9fc2VsZWNjaW9uYWJsZShzZWwpfSk7XG5mdW5jdGlvbiBoYWNlcl9hcnRpY3Vsb3Nfc2VsZWNjaW9uYWJsZXMoKXtcbiAgJCgnLmFydGljdWxvX3MnKS5lYWNoKGZ1bmN0aW9uKGksIHNlbCl7YXJ0aWN1bG9fc2VsZWNjaW9uYWJsZShzZWwpfSk7XG59XG5mdW5jdGlvbiBhcnRpY3Vsb19zZWxlY2Npb25hYmxlKHNlbCl7XG4gICQoc2VsKS5zZWxlY3QyKHtcbiAgICBwbGFjZWhvbGRlcjogJ0J1c2NhciBhcnTDrWN1bG8nLFxuICAgIG1pbmltdW1JbnB1dExlbmd0aDogMywgICAgICAgICAgICBcbiAgICBhbGxvd0NsZWFyOiB0cnVlLFxuICAgIGNhY2hlOiB0cnVlLFxuICAgIGFqYXg6IHtcbiAgICAgIGRlbGF5OiAyNTAsXG4gICAgICB1cmw6ICBmdW5jdGlvbiAocGFyYW1zKSB7XG4gICAgICAgIHJldHVybiAnL2FwaS9hcnRpY3Vsb3MvJyArIHBhcmFtcy50ZXJtO1xuICAgICAgfSxcbiAgICAgIGRhdGFUeXBlOiAnanNvbicsXG4gICAgICBwcm9jZXNzUmVzdWx0czogZnVuY3Rpb24gKGRhdGEsIHBhcmFtcykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHJlc3VsdHM6IGRhdGEuZGF0YVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgJChzZWwpLm9uKCdjaGFuZ2UnLChmdW5jdGlvbigpe1xuICAgIHZhciB0aXR1bG8gPSAkKHRoaXMpLmZpbmQoJ29wdGlvbjpzZWxlY3RlZCcpLnRleHQoKTtcbiAgICAkKHRoaXMpLnBhcmVudCgpLnBhcmVudCgpLmZpbmQoJy5hcnRpY3Vsb190JykudmFsKHRpdHVsbyk7XG4gIH0pKTtcbn07XG4kKCcuYXJ0aWN1bG9fc190b2RvcycpLmVhY2goZnVuY3Rpb24oaSwgc2VsKXthcnRpY3Vsb19zZWxlY2Npb25hYmxlX3RvZG9zKHNlbCl9KTtcbmZ1bmN0aW9uIGhhY2VyX2FydGljdWxvc190b2Rvc19zZWxlY2Npb25hYmxlcygpe1xuICAkKCcuYXJ0aWN1bG9fc190b2RvcycpLmVhY2goZnVuY3Rpb24oaSwgc2VsKXthcnRpY3Vsb19zZWxlY2Npb25hYmxlX3RvZG9zKHNlbCl9KTtcbn1cbmZ1bmN0aW9uIGFydGljdWxvX3NlbGVjY2lvbmFibGVfdG9kb3Moc2VsKXtcbiAgJChzZWwpLnNlbGVjdDIoe1xuICAgIHBsYWNlaG9sZG
1VyOiAnQnVzY2FyIGFydMOtY3VsbycsXG4gICAgbWluaW11bUlucHV0TGVuZ3RoOiAzLCAgICAgICAgICAgIFxuICAgIGFsbG93Q2xlYXI6IHRydWUsXG4gICAgY2FjaGU6IHRydWUsXG4gICAgYWpheDoge1xuICAgICAgZGVsYXk6IDI1MCxcbiAgICAgIHVybDogIGZ1bmN0aW9uIChwYXJhbXMpIHtcbiAgICAgICAgcmV0dXJuICcvYXBpL2FydGljdWxvc190b2Rvcy8nICsgcGFyYW1zLnRlcm07XG4gICAgICB9LFxuICAgICAgZGF0YVR5cGU6ICdqc29uJyxcbiAgICAgIHByb2Nlc3NSZXN1bHRzOiBmdW5jdGlvbiAoZGF0YSwgcGFyYW1zKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzdWx0czogZGF0YS5kYXRhXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICAkKHNlbCkub24oJ2NoYW5nZScsKGZ1bmN0aW9uKCl7XG4gICAgdmFyIHRpdHVsbyA9ICQodGhpcykuZmluZCgnb3B0aW9uOnNlbGVjdGVkJykudGV4dCgpO1xuICAgICQodGhpcykucGFyZW50KCkucGFyZW50KCkuZmluZCgnLmFydGljdWxvX3QnKS52YWwodGl0dWxvKTtcbiAgfSkpO1xufTsgXG5cbiQoZG9jdW1lbnQpLm9uKCdjbGljaycsJy5hbmhhZGlyX2FydGljdWxvX3B1Yl9kaWdpJywgZnVuY3Rpb24oZSkge1xuICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIGxldCB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIGxldCB0ZW1wbGF0ZSA9ICQodGhpcykuZGF0YShcInRlbXBsYXRlXCIpO1xuICB2YXIgdGlwbyA9ICQodGhpcykucGFyZW50KCkuZmluZChcIi5ub21icmVcIikuZmluZChcIi5hdG9wYW1lXCIpLmxlbmd0aDtcbiAgaWYgKHRpcG8gPiAwKSB7XG4gICAgdmFyIGlkID0gJCh0aGlzKS5wYXJlbnQoKVxuICAgICAgLmZpbmQoXCIubm9tYnJlXCIpLmZpbmQoXCIuYXRvcGFtZVwiKS5lcSgwKS5hdHRyKFwiaWRcIik7XG4gICAgaWQgPSBpZC5zcGxpdCgnXycpWzJdO1xuICB9ZWxzZXtcbiAgICB2YXIgaWQgPSAkKHRoaXMpLnBhcmVudCgpXG4gICAgICAuZmluZChcIi5ub21icmVcIikuZmluZChcIi5hdG9wYW1lMlwiKS5lcSgwKS5hdHRyKFwiaWRcIik7XG4gICAgaWQgPSBpZC5zcGxpdCgnXycpWzNdO1xuICB9XG4gIHZhciB1bmlxX3RlbXBsYXRlID0gdGVtcGxhdGVcbiAgICAucmVwbGFjZSgvYXJ0aWN1bG9zXFxdXFxbMFxcXS9nLCBgYXJ0aWN1bG9zXVske3RpbWV9XWApXG4gICAgLnJlcGxhY2UoL2NvbGFzXFxdXFxbMFxcXS9nLCBgY29sYXNdWyR7aWR9XWApXG4gICAgLnJlcGxhY2UoL2FwYXJ0YWRvc1xcXVxcWzBcXF0vZywgYGFwYXJ0YWRvc11bJHtpZH1dYClcbiAgICAucmVwbGFjZSgvYXJ0aWN1bG9zXzBfL2csIGBhcnRpY3Vsb3NfJHt0aW1lfV9gKVxuICAgIC5yZXBsYWNlKC9jb2xhc18wXy9nLCBgY29sYXNfJHtpZH1fYCkgXG4gICAgLnJlcGxhY2UoL2FwYXJ0YWRvc18wXy9nLCBgYXBhcnRhZG9zXyR7aWR9X2ApOyBcbiAgdmFyIGNvbnRlbmVkb3Jfb3JpZ2luYWwgPSB0aGlzLnBhcmVudE5vZGUucXVlcnlTZWxlY3RvcihcIi5lbnRyYWRhc1wiKS5jbG9uZU5vZGUodHJ1ZSk7XG4gIHZhciBhcnRpY3Vsb3Nfb3JpZ2luYWwgPSBjb250ZW5lZG9yX29yaWdpbmFsLnF1ZXJ5U2VsZWN0b3JBbGwoXCJ0clwiKTtcbiAgJCh0aGlzKS5wYXJlbnQoKS5maW5kKFwiLmVudHJhZGFzXCIpLnByZXBlbmQodW5pcV90ZW1wbGF0ZSk7XG4gIC8vJCh0aGlzKS5wYXJlbnQoKS5maW5kKFwiLmZpbGFcIikuZXEoMCkuYmVmb3JlKHVuaXFfdGVtcGxhdGUpO1xuICBoYWNlcl9hcnRpY3Vsb3Nfc2VsZWNjaW9uYWJsZXMoKTtcbiAgaGFjZXJfYXJ0aWN1bG9zX3RvZG9zX3NlbGVjY2lvbmFibGVzKCk7XG4gIHZhciB1YmljYWNpb24gPSAkKCcjcG9ydGFkYV91YmljYWNpb24nKS52YWwoKTtcbiAgJCgnLmZvcm0tYXBhcnRhZG8tbnVldm8gLnBvcnRhZGFfdWJpY2FjaW9uJykudmFsKHViaWNhY2lvbik7XG59KVxuLy8gXG4vLyBHZXN0acOzbiBkZSBjb2xhc1xuJChkb2N1bWVudCkub24oJ2NsaWNrJywnLmFuaGFkaXJfYXJ0aWN1bG8nLCBmdW5jdGlvbihlKSB7XG4gIGUucHJldmVudERlZmF1bHQoKTtcbiAgbGV0IHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgbGV0IHRlbXBsYXRlID0gJCh0aGlzKS5kYXRhKFwidGVtcGxhdGVcIik7XG4gIHZhciB0aXBvID0gJCh0aGlzKS5wYXJlbnQoKS5maW5kKFwiLm5vbWJyZVwiKS5maW5kKFwiLmF0b3BhbWVcIikubGVuZ3RoO1xuICBpZiAodGlwbyA+IDApIHtcbiAgICB2YXIgaWQgPSAkKHRoaXMpLnBhcmVudCgpXG4gICAgICAuZmluZChcIi5ub21icmVcIikuZmluZChcIi5hdG9wYW1lXCIpLmVxKDApLmF0dHIoXCJpZFwiKTtcbiAgICBpZCA9IGlkLnNwbGl0KCdfJylbMl07XG4gIH1lbHNle1xuICAgIHZhciBpZCA9ICQodGhpcykucGFyZW50KClcbiAgICAgIC5maW5kKFwiLm5vbWJyZVwiKS5maW5kKFwiLmF0b3BhbWUyXCIpLmVxKDApLmF0dHIoXCJpZFwiKTtcbiAgICBpZCA9IGlkLnNwbGl0KCdfJylbM107XG4gIH1cbiAgdmFyIHVuaXFfdGVtcGxhdGUgPSB0ZW1wbGF0ZVxuICAgIC5yZXBsYWNlKC9hcnRpY3Vsb3NcXF1cXFswXFxdL2csIGBhcnRpY3Vsb3NdWyR7dGltZX1dYClcbiAgICAucmVwbGFjZSgvY29sYXNcXF1cXFswXFxdL2csIGBjb2xhc11bJHtpZH1dYClcbiAgICAucmVwbGFjZSgvYXBhcnRhZG9zXFxdXFxbMFxcXS9nLCBgYXBhcnRhZG9zXVske2lkfV1gKVxuICAgIC5yZXBsYWNlKC9hcnRpY3Vsb3NfMF8vZywgYGFydGljdWxvc18ke3RpbWV9X2ApXG4gICAgLnJlcGxhY2UoL2NvbGFzXzBfL2csIGBjb2xhc18ke2lkfV9gKSBcbiAgICAucmVwbGFjZSgvYXBhcnRhZG9zXzBfL2csIGBhcGFydGFkb3NfJHtpZH1fYCk7IFxuICB2YXIgY29udGVuZWRvcl9vcmlnaW5hbCA9IHRoaXMucGFyZW50Tm9kZS5xdWVyeVNlbGVjdG9yKFwiLmVud
1HJhZGFzXCIpLmNsb25lTm9kZSh0cnVlKTtcbiAgdmFyIGFydGljdWxvc19vcmlnaW5hbCA9IGNvbnRlbmVkb3Jfb3JpZ2luYWwucXVlcnlTZWxlY3RvckFsbChcInRyXCIpO1xuICB2YXIgZWxlbWVudG8gPSAkKHRoaXMpLnBhcmVudCgpLmZpbmQoXCIuZW50cmFkYXNcIikucHJlcGVuZCh1bmlxX3RlbXBsYXRlKTtcblxuICAvLyQodGhpcykucGFyZW50KCkuZmluZChcIi5maWxhXCIpLmVxKDApLmJlZm9yZSh1bmlxX3RlbXBsYXRlKTtcbiAgaGFjZXJfYXJ0aWN1bG9zX3NlbGVjY2lvbmFibGVzKCk7XG4gIGhhY2VyX2FydGljdWxvc190b2Rvc19zZWxlY2Npb25hYmxlcygpO1xuICB2YXIgdWJpY2FjaW9uID0gJCgnI3BvcnRhZGFfdWJpY2FjaW9uJykudmFsKCk7XG4gICQoJy5mb3JtLWFwYXJ0YWRvLW51ZXZvIC5wb3J0YWRhX3ViaWNhY2lvbicpLnZhbCh1YmljYWNpb24pO1xuICB2YXIgY29udGVuZWRvciA9IHRoaXMucGFyZW50Tm9kZS5xdWVyeVNlbGVjdG9yKFwiLmVudHJhZGFzXCIpO1xuICB2YXIgYXJ0aWN1bG9zID0gY29udGVuZWRvci5xdWVyeVNlbGVjdG9yQWxsKFwidHJcIik7XG4gIGNvbnRlbmVkb3IuaW5uZXJIVE1MID0gXCJcIlxuICBhcnRpY3Vsb3MgPSBvcmRlbmFyX2FycmF5X2Nvbl9maWpvcyhhcnRpY3Vsb3Nfb3JpZ2luYWwsIGFydGljdWxvcyk7XG4gIGFydGljdWxvcy5mb3JFYWNoKGZ1bmN0aW9uKGUsaSxhKXtcbiAgICAgY29udGVuZWRvci5hcHBlbmRDaGlsZChlKVxuICB9KVxuICBub3JtYWxpemFyX2NvbGEoY29udGVuZWRvcilcbiAgb3JkZW5hcl9jb2xhKGNvbnRlbmVkb3IpXG4gIG5vcm1hbGl6YXJfY29sYShjb250ZW5lZG9yKVxuICBib3RvbmVzX2FycmliYV9hYmFqb19jb2xhcygpO1xufSlcblxuZnVuY3Rpb24gb3JkZW5hcl9hcnJheV9jb25fZmlqb3Mob3JpZ2luYWwsIG51ZXZvKXtcbiAgdmFyIG5vcm1hbGVzID0gWy4uLm51ZXZvXS5maWx0ZXIoZSA9PiAhZS5xdWVyeVNlbGVjdG9yKFwiLmNoaW5jaGV0YSAuZm9ybS1jb250cm9sXCIpLmNoZWNrZWQpXG4gIHZhciBub3JtYWxfaSA9IDBcbiAgdmFyIGwgPSBudWV2by5sZW5ndGhcbiAgbnVldm8gPSBbXVxuICBmb3IgKGxldCBpID0gMDsgaSA8bDsgaSsrKSB7XG4gICAgaWYgKG9yaWdpbmFsW2ldIFxuICAgICAgICAmJiBvcmlnaW5hbFtpXS5xdWVyeVNlbGVjdG9yKFwiLmNoaW5jaGV0YSAuZm9ybS1jb250cm9sXCIpLmNoZWNrZWQpe1xuICAgICAgbnVldm9baV0gPSBvcmlnaW5hbFtpXVxuICAgIH0gZWxzZSB7XG4gICAgICBudWV2b1tpXSA9IG5vcm1hbGVzW25vcm1hbF9pXVxuICAgICAgKytub3JtYWxfaVxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVldm87XG59XG5cbmZ1bmN0aW9uIG9yZGVuYXJfY29sYShjb250ZW5lZG9yKXtcbiAgdmFyIGFydGljdWxvcyA9IGNvbnRlbmVkb3IucXVlcnlTZWxlY3RvckFsbChcInRyXCIpO1xuICBhcnRpY3Vsb3MgPSBBcnJheS5mcm9tKGFydGljdWxvcykuc29ydChmdW5jdGlvbihhLGIpe1xuICAgIC8vaWYgKGEucXVlcnlTZWxlY3RvcihcIi5jaGluY2hldGEgLmZvcm0tY29udHJvbFwiKS5jaGVja2VkKXtyZXR1cm4gLSAxfTtcbiAgICAvL2lmIChiLnF1ZXJ5U2VsZWN0b3IoXCIuY2hpbmNoZXRhIC5mb3JtLWNvbnRyb2xcIikuY2hlY2tlZCl7cmV0dXJuICsgMX07XG4gICAgYSA9IGEucXVlcnlTZWxlY3RvcihcIi5vcmRlbiAuZm9ybS1jb250cm9sXCIpLnZhbHVlO1xuICAgIGIgPSBiLnF1ZXJ5U2VsZWN0b3IoXCIub3JkZW4gLmZvcm0tY29udHJvbFwiKS52YWx1ZTtcbiAgICByZXR1cm4gIGEgLSBiXG4gIH0pXG4gICAgLy8uZm9yRWFjaChlbCA9PnsgY29udGVuZWRvci5hcHBlbmRDaGlsZChlbCkgfSlcblxuICBjb250ZW5lZG9yLmlubmVySFRNTCA9IFwiXCJcbiAgYXJ0aWN1bG9zLmZvckVhY2goZnVuY3Rpb24oZSxpLGEpe1xuICAgICBjb250ZW5lZG9yLmFwcGVuZENoaWxkKGUpXG4gIH0pXG5cbn1cbmZ1bmN0aW9uIG5vcm1hbGl6YXJfY29sYShjb250ZW5lZG9yKXtcbiAgdmFyIGFydGljdWxvcyA9IGNvbnRlbmVkb3IucXVlcnlTZWxlY3RvckFsbChcInRyXCIpO1xuICBhcnRpY3Vsb3MuZm9yRWFjaChmdW5jdGlvbihlLGksYSl7XG4gICAgb3JkZW4gPSBlLnF1ZXJ5U2VsZWN0b3IoXCIub3JkZW4gLmZvcm0tY29udHJvbFwiKVxuICAgIG9yZGVuLnZhbHVlID0gKGkrMSkqMTA7XG4gIH0pO1xufVxudmFyIGFycmliYSA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgdmFyIG9yZGVuID0gdGhpcy5wYXJlbnROb2RlLnBhcmVudE5vZGUucXVlcnlTZWxlY3RvcihcIi5vcmRlbiAuZm9ybS1jb250cm9sXCIpIFxuICAgICAgb3JkZW4udmFsdWUgPSBwYXJzZUludChvcmRlbi52YWx1ZSkgLSAxNTtcbiAgICAgIHZhciBjb250ZW5lZG9yID0gdGhpcy5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZTtcbiAgICAgIG9yZGVuYXJfY29sYShjb250ZW5lZG9yKVxuICAgICAgbm9ybWFsaXphcl9jb2xhKGNvbnRlbmVkb3IpXG5cbn1cbnZhciBhYmFqbyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgdmFyIG9yZGVuID0gdGhpcy5wYXJlbnROb2RlLnBhcmVudE5vZGUucXVlcnlTZWxlY3RvcihcIi5vcmRlbiAuZm9ybS1jb250cm9sXCIpIFxuICAgICAgb3JkZW4udmFsdWUgPSBwYXJzZUludChvcmRlbi52YWx1ZSkgKyAxNTtcbiAgICAgIHZhciBjb250ZW5lZG9yID0gdGhpcy5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZTtcbiAgICAgIG9yZGVuYXJfY29sYShjb250ZW5lZG9yKVxuICAgICAgbm9ybWFsaXphcl9jb2xhKGNvbnRlbmVkb3IpXG59XG5cbmZ1bmN0aW9uIGJvdG9uZXNfYXJyaWJhX2FiYWpvX2NvbGFzKCl7XG4gIHZhciB1cEJ1dHRvbnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcub3JkZW5hciAudXAnKTtcbiAgdmFyIGRvd25CdXR0b25zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLm9yZGVuYXIgLmRvd24nKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHVwQnV0dG9ucy5sZW5ndGg7IGkrKykge1xuICAgIHVwQnV0dG9uc1tpXS5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIGFycmliYSkgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGRvd25CdXR0b25zLmxlbmd0aDsgaSsrKSB7XG4gICAgZG93bkJ1dHRvbnNbaV0ucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhYmFqbykgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdXBCdXR0b25zLmxlbmd0aDsgaSsrKSB7XG4gICAgdXBCdXR0b25zW2ldLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXJyaWJhKTtcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGRvd25CdXR0b25zLmxlbmd0aDsgaSsrKSB7XG4gICAgZG93bkJ1dHRvbnNbaV0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhYmFqbyk7XG4gIH1cbn1cbmJvdG9uZXNfYXJyaWJhX2FiYWpvX2NvbGFzKCk7XG4kKGRvY3VtZW50KS5vbignY2xpY2snLCcjYW5oYWRpcl9zZWNjaW9uJywgZnVuY3Rpb24oZSkge1xuICBlLnByZXZlbn
1REZWZhdWx0KCk7XG4gIGxldCB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIGxldCB0ZW1wbGF0ZSA9ICQodGhpcykuZGF0YShcInRlbXBsYXRlXCIpO1xuICB2YXIgdW5pcV90ZW1wbGF0ZSA9IHRlbXBsYXRlLnJlcGxhY2UoL1xcWzBcXF0vZywgYFske3RpbWV9XWApO1xuICB1bmlxX3RlbXBsYXRlID0gdW5pcV90ZW1wbGF0ZS5yZXBsYWNlKC9fMF8vZywgYF8ke3RpbWV9X2ApO1xuICAkKHRoaXMpLnBhcmVudCgpLmFmdGVyKHVuaXFfdGVtcGxhdGUpO1xuICBmb3RvcygpO1xuICBnYWxlcmlhcygpO1xuICBtdWx0aW1lZGlhcygpO1xufSlcblxuLy8gR2VzdGnDs24gZGUgYXBhcnRhZG9zIHB1YiBkaWdpdGFsXG4kKGRvY3VtZW50KS5vbignY2xpY2snLCcjYW5oYWRpcl9zZWNjaW9uX3B1Yl9kaWcnLCBmdW5jdGlvbihlKSB7XG4gIGUucHJldmVudERlZmF1bHQoKTtcbiAgbGV0IHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgbGV0IHRlbXBsYXRlID0gJCh0aGlzKS5kYXRhKFwidGVtcGxhdGVcIik7XG4gIHZhciB1bmlxX3RlbXBsYXRlID0gdGVtcGxhdGUucmVwbGFjZSgvXFxbMFxcXS9nLCBgWyR7dGltZX1dYCk7XG4gIHVuaXFfdGVtcGxhdGUgPSB1bmlxX3RlbXBsYXRlLnJlcGxhY2UoL18wXy9nLCBgXyR7dGltZX1fYCk7XG4gICQodGhpcykuYmVmb3JlKHVuaXFfdGVtcGxhdGUpO1xufSlcbiQoZG9jdW1lbnQpLm9uKCdjbGljaycsJyNhbmhhZGlyX2FwYXJ0YWRvJywgZnVuY3Rpb24oZSkge1xuICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIGxldCB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIGxldCB0ZW1wbGF0ZSA9ICQodGhpcykuZGF0YShcInRlbXBsYXRlXCIpO1xuICB2YXIgdW5pcV90ZW1wbGF0ZSA9IHRlbXBsYXRlLnJlcGxhY2UoL1xcWzBcXF0vZywgYFske3RpbWV9XWApO1xuICB1bmlxX3RlbXBsYXRlID0gdW5pcV90ZW1wbGF0ZS5yZXBsYWNlKC9fMF8vZywgYF8ke3RpbWV9X2ApO1xuICAkKHRoaXMpLmJlZm9yZSh1bmlxX3RlbXBsYXRlKTtcbiAgJCgnLnN1bW1lcm5vdGUnKS5zdW1tZXJub3RlKCk7XG4gIGZvdG9zKCk7XG4gIGhhY2VyX2FydGljdWxvc190b2Rvc19zZWxlY2Npb25hYmxlcygpO1xuICBoYWNlcl9hbnVuY2lvc19zZWxlY2Npb25hYmxlKCk7XG59KVxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnI2FuaGFkaXJfZm90b19hcmNoaXZvJywgZnVuY3Rpb24oZSkge1xuICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIGxldCB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIGxldCB0ZW1wbGF0ZSA9ICQodGhpcykuZGF0YShcInRlbXBsYXRlXCIpO1xuICB2YXIgdW5pcV90ZW1wbGF0ZSA9IHRlbXBsYXRlLnJlcGxhY2UoL1xcWzBcXF0vZywgYFske3RpbWV9XWApO1xuICB1bmlxX3RlbXBsYXRlID0gdW5pcV90ZW1wbGF0ZS5yZXBsYWNlKC9fMF8vZywgYF8ke3RpbWV9X2ApO1xuICAkKHRoaXMpLnBhcmVudCgpLmJlZm9yZSh1bmlxX3RlbXBsYXRlKTtcbiAgZm90b3MoKTtcbn0pXG4vLyBTZWNjaW9uZXMgYXJ0aWN1bG9cbiQoZG9jdW1lbnQpLm9uKCdjbGljaycsJyNhbmhhZGlyX3NlY2Npb25fYXJ0aWN1bG8nLCBmdW5jdGlvbihlKSB7XG4gIGUucHJldmVudERlZmF1bHQoKTtcbiAgbGV0IHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgbGV0IHRlbXBsYXRlID0gJCh0aGlzKS5kYXRhKFwidGVtcGxhdGVcIik7XG4gIHZhciB1bmlxX3RlbXBsYXRlID0gdGVtcGxhdGUucmVwbGFjZSgvXFxbMFxcXS9nLCBgWyR7dGltZX1dYCk7XG4gIHVuaXFfdGVtcGxhdGUgPSB1bmlxX3RlbXBsYXRlLnJlcGxhY2UoL18wXy9nLCBgXyR7dGltZX1fYCk7XG4gIC8vJCh0aGlzKS5wYXJlbnQoKS5iZWZvcmUodW5pcV90ZW1wbGF0ZSk7XG4gICQodGhpcykuYmVmb3JlKHVuaXFfdGVtcGxhdGUpO1xuICAkKCcuc3VtbWVybm90ZScpLnN1bW1lcm5vdGUoKTtcbiAgZm90b3MoKTtcbiAgbXVsdGltZWRpYXMoKTtcbiAgZ2FsZXJpYXMoKTtcbn0pXG5cbiQoZG9jdW1lbnQpLm9uKCdjbGljaycsJyNhbmhhZGlyX3RyYWR1Y2Npb24nLCBmdW5jdGlvbihlKSB7XG4gIGUucHJldmVudERlZmF1bHQoKTtcbiAgbGV0IHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgbGV0IHRlbXBsYXRlID0gJCh0aGlzKS5kYXRhKFwidGVtcGxhdGVcIik7XG4gIHZhciB1bmlxX3RlbXBsYXRlID0gdGVtcGxhdGUucmVwbGFjZSgvXFxbMFxcXS9nLCBgWyR7dGltZX1dYCk7XG4gIHVuaXFfdGVtcGxhdGUgPSB1bmlxX3RlbXBsYXRlLnJlcGxhY2UoL18wXy9nLCBgXyR7dGltZX1fYCk7XG4gICQodGhpcykucGFyZW50KCkuYmVmb3JlKHVuaXFfdGVtcGxhdGUpO1xuICBoYWNlcl9hcnRpY3Vsb3Nfc2VsZWNjaW9uYWJsZXMoKTtcbiAgaGFjZXJfYXJ0aWN1bG9zX3RvZG9zX3NlbGVjY2lvbmFibGVzKCk7XG59KVxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnI2FuaGFkaXJfbGluaycsIGZ1bmN0aW9uKGUpIHtcbiAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICBsZXQgdGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICBsZXQgdGVtcGxhdGUgPSAkKHRoaXMpLmRhdGEoXCJ0ZW1wbGF0ZVwiKTtcbiAgdmFyIHVuaXFfdGVtcGxhdGUgPSB0ZW1wbGF0ZS5yZXBsYWNlKC9cXFswXFxdL2csIGBbJHt0aW1lfV1gKTtcbiAgdW5pcV90ZW1wbGF0ZSA9IHVuaXFfdGVtcGxhdGUucmVwbGFjZSgvXzBfL2csIGBfJHt0aW1lfV9gKTtcbiAgJCh0aGlzKS5wYXJlbnQoKS5iZWZvcmUodW5pcV90ZW1wbGF0ZSk7XG59KVxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnI2FuaGFkaXJfbWVudScsIGZ1bmN0aW9uKGUpIHtcbiAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICBsZXQgdGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICBsZXQgdGVtcGxhdGUgPSAkKHRoaXMpLmRhdGEoXCJ0ZW1wbGF0ZVwiKTtcbiAgdmFyIHVuaXFfdGVtcGxhdGUgPSB0ZW1wbGF0ZS5yZXBsYWNlKC9cXFswXFxdL2csIGBbJHt0aW1lfV1gKTtcbiAgdW5pcV90ZW1wbGF0ZSA9IHVuaXFfdGVtcGxhdGUucmVwbGFjZSgvXzBfL2csIGBfJHt0aW1lfV9gKTtcbiAgJCh0aGlzKS5wYXJlbnQoKS5iZWZvcmUodW5pcV90ZW1wbGF0ZSk7XG59KVxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnI2FuaGFkaXJfY29tZW50YXJpbycsIGZ1bmN0aW9uKGUpIHtcbiAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICBsZXQgdGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICBsZXQgdGVtcGxhdGUgPSAkKHRoaXMpLmRhdGEoXCJ0ZW1wbGF0ZVwiKTtcbiAgdmFyIHVuaXFfdGVtcGxhdGUgPSB0ZW1wbGF0ZS5yZXBsYWNlKC9cXFswXFxdL2csIGBbJHt0aW1lfV1gKTtcbiAgdW5pcV90ZW1wbGF0ZSA9IHVuaXFfdGVtcGxhdGUucmVwbGFjZSgvXzBfL2csIGBfJHt0aW1lfV9gKTtcbiAgJCh0aGlzKS5wYXJlbnQoKS5iZWZvcmUo
1dW5pcV90ZW1wbGF0ZSk7XG4gIGNhbWJpbygpO1xuICBhY3R1YWxpemFyQ1NSRigpO1xufSlcbiQoZG9jdW1lbnQpLm9uKCdjbGljaycsJy5jb21lbnRhci1jb21lbnRhcmlvJywgZnVuY3Rpb24oZSkge1xuICB2YXIgY29tZW50YXJpb19pZCA9ICQodGhpcykuYXR0cignZGF0YS1jb21lbnRhcmlvJyk7XG4gIGUucHJldmVudERlZmF1bHQoKTtcbiAgbGV0IHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgbGV0IHRlbXBsYXRlID0gJCgnI2FuaGFkaXJfY29tZW50YXJpbycpLmRhdGEoXCJ0ZW1wbGF0ZVwiKTtcbiAgdmFyIHVuaXFfdGVtcGxhdGUgPSB0ZW1wbGF0ZS5yZXBsYWNlKC9cXFswXFxdL2csIGBbJHt0aW1lfV1gKTtcbiAgdW5pcV90ZW1wbGF0ZSA9IHVuaXFfdGVtcGxhdGUucmVwbGFjZSgvXzBfL2csIGBfJHt0aW1lfV9gKTtcbiAgJChcIiNhbmhhZGlyX2NvbWVudGFyaW9cIikucGFyZW50KCkuYmVmb3JlKHVuaXFfdGVtcGxhdGUpO1xuICAkKCcjY29tZW50YXJpb19jb21lbnRhcmlvX2lkJykudmFsKGNvbWVudGFyaW9faWQpO1xuICBjYW1iaW8oKTtcbiAgYWN0dWFsaXphckNTUkYoKTtcbn0pXG4kKGRvY3VtZW50KS5vbignY2xpY2snLCcjYW5oYWRpcl90aXBvJywgZnVuY3Rpb24oZSkge1xuICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIGxldCB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIGxldCB0ZW1wbGF0ZSA9ICQodGhpcykuZGF0YShcInRlbXBsYXRlXCIpO1xuICB2YXIgdW5pcV90ZW1wbGF0ZSA9IHRlbXBsYXRlLnJlcGxhY2UoL1xcWzBcXF0vZywgYFske3RpbWV9XWApO1xuICB1bmlxX3RlbXBsYXRlID0gdW5pcV90ZW1wbGF0ZS5yZXBsYWNlKC9fMF8vZywgYF8ke3RpbWV9X2ApO1xuICAkKHRoaXMpLnBhcmVudCgpLmJlZm9yZSh1bmlxX3RlbXBsYXRlKTtcbiQoJy5zdW1tZXJub3RlJykuc3VtbWVybm90ZSgpO1xufSlcbmZ1bmN0aW9uIGNhbWJpbygpe1xuICBpZiAoJCgnI2FydGljdWxvLWNvbXBsZXRvJykubGVuZ3RoKSB7XG4gICAgdmFyIHRva2VuID0gJCgnI2FydGljdWxvLWNvbXBsZXRvJykuYXR0cihcImRhdGEtdG9rZW5cIik7XG4gICAgJCgnI2FydGljdWxvLWNvbXBsZXRvIGlucHV0W25hbWU9XCJfY3NyZl90b2tlblwiXScpLmVhY2goZnVuY3Rpb24oKXtcbiAgICAgICQodGhpcykudmFsKHRva2VuKTtcbiAgICB9KTtcbiAgfVxufVxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnLmJvcnJhcl9zZWNjaW9uJywgZnVuY3Rpb24oZSkge1xuICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICQodGhpcykucGFyZW50KCkucGFyZW50KCkucmVtb3ZlKCk7XG59KVxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnLmFudWxhci1jb21lbnRhcmlvJywgZnVuY3Rpb24oZSkge1xuICAkKCcuYm94JykucmVtb3ZlKCk7XG59KVxuXG5mdW5jdGlvbiBJbWFnZW5VcGRhdGUob2JqKSAge1xuICBpZighd2luZG93LkZpbGVSZWFkZXIpe1xuICB9IGVsc2Uge1xuICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgIHZhciB0YXJnZXQgPSBudWxsO1xuICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbihlKSB7XG4gICAgICB0YXJnZXQgPSAgZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50O1xuICAgICAgJChvYmopLnBhcmVudCgpLnBhcmVudCgpLmZpbmQoXCIucHJldmlld1wiKS5wcm9wKFwic3JjXCIsIHRhcmdldC5yZXN1bHQpO1xuICAgICAgJChvYmopLnBhcmVudCgpLnBhcmVudCgpLmZpbmQoXCIucHJldmlld1wiKS5yZW1vdmVDbGFzcyhcImhpZGRlblwiKTtcbiAgICB9O1xuICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKG9iai5maWxlc1swXSk7XG4gIH1cbn07XG4kKGRvY3VtZW50KS5vbignY2hhbmdlJywnaW5wdXQucHJldmlldycsIGZ1bmN0aW9uKCkge0ltYWdlblVwZGF0ZSh0aGlzKTt9KTtcblxuLy93eXNpd3lnXG4kKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpe1xuICBpZiAodHlwZW9mICAkKCcuc3VtbWVybm90ZScpLnN1bW1lcm5vdGUgPT09IFwiZnVuY3Rpb25cIikgeyBcbiAgJCgnLnN1bW1lcm5vdGUnKS5zdW1tZXJub3RlKHtcbiAgICBzdHlsZVdpdGhTcGFuOiBmYWxzZSxcbiAgICBsYW5nOiAnZXMtRVMnLFxuICAgIGhlaWdodDogNDAwLFxuICAgIGRpYWxvZ3NGYWRlOiB0cnVlICAsXG4gICAgdG9vbGJhcjogW1xuICAgICAgWydzdHlsZScsIFsnYm9sZCcsICdpdGFsaWMnLCAndW5kZXJsaW5lJywgJ2NsZWFyJ11dLFxuICAgICAgWydmb250JywgWydzdHJpa2V0aHJvdWdoJywgJ3N1cGVyc2NyaXB0JywgJ3N1YnNjcmlwdCddXSxcbiAgICAgIFsncGFyYScsIFsndWwnLCAnb2wnLCAncGFyYWdyYXBoJ11dLFxuICAgICAgWydsaW5rJyxbJ3N0eWxlJ11dLFxuICAgICAgWydpbnNlcnQnLCBbJ3BpY3R1cmUnLCd2aWRlbycsJ2xpbmsnLCAndW5saW5rJ11dLFxuICAgICAgWydzYWx0bycsIFsnYXJ0aWN1bG8nLCdmb3RvJywnY29kaWdvJywgJ2JvcnJhciddXSxcbiAgICAgIFsndmlldycsWydjb2RldmlldyddXSxcbiAgICAgIFsnaW5zZXJ0JywgWyd0ZW1wbGF0ZSddXVxuICAgIF0sXG4gICAgcG9wb3Zlcjoge1xuICAgICAgaW1hZ2U6IFtcbiAgICAgICAgWydjdXN0b20nLCBbJ2ltYWdlQXR0cmlidXRlcycsJ2NhcHRpb25JdCddXSxcbiAgICAgICAgWydpbWFnZXNpemUnLCBbJ2ltYWdlU2l6ZTEwMCcsICdpbWFnZVNpemU1MCcsICdpbWFnZVNpemUyNSddXSxcbiAgICAgICAgWydmbG9hdCcsIFsnZmxvYXRMZWZ0JywgJ2Zsb2F0UmlnaHQnLCAnZmxvYXROb25lJ11dLFxuICAgICAgICBbJ3JlbW92ZScsIFsncmVtb3ZlTWVkaWEnXV1cbiAgICAgIF0sXG4gICAgfSxcbiAgICBpbWFnZUF0dHJpYnV0ZXM6e1xuICAgICAgaW1hZ2VEaWFsb2dMYXlvdXQ6J2RlZmF1bHQnLCAvLyBkZWZhdWx0fGhvcml6b250YWxcbiAgICAgIGljb246JzxpIGNsYXNzPVwibm90ZS1pY29uLXBlbmNpbFwiLz4nLFxuICAgICAgcmVtb3ZlRW1wdHk6ZmFsc2UgLy8gdHJ1ZSA9IHJlbW92ZSBhdHRyaWJ1dGVzIHwgZmFsc2UgPSBsZWF2ZSBlbXB0eSBpZiBwcmVzZW50XG4gICAgfSxcbiAgICBkaXNwbGF5RmllbGRzOntcbiAgICAgIGltYWdlQmFzaWM6dHJ1ZSwgIC8vIHNob3cvaGlkZSBUaXRsZSwgU291cmNlLCBBbHQgZmllbGRzXG4gICAgICBpbWFnZUV4dHJhOnRydWUsIC8vIHNob3cvaGlkZSBBbHQsIENsYXNzLCBTdHlsZSwgUm9sZSBmaWVsZHNcbiAgICAgIGxpbmtCYXNpYzp0cnVlLCAgIC8vIHNob3cvaGlkZSBVUkwgYW5kIFRhcmdldCBmaWVsZHMgZm9yIGxpbmtcbiAgICAgIGxpbmtFeHRyYTpmYWxzZSAgIC8vIHNob3cvaGlkZSBDbGFzcywgUmVsLCBSb2xlIGZpZWxkcyBmb3IgbGlua1xuICAgIH0sXG4gICAgY2FwdGlvbkl0OntcbiAgICAgIGljb246JzxpIGNsYXNzPVwibm90ZS1pY29uLXBlbmNpbFwifS8+JywgLy8gTGVhdmUgZW1wdHkgb3IgZG9uJ3Qgc2V0IGZvciBkZWZhdWx0IEljb24uXG4gICAgICBmaWd1cmVDbGFzczonZmlndXJlLWludGVybmEnLFxuICAgICAgZmlnY2FwdGlvbkNsYXNzOidwaWUnLFxuICAgIH0sXG4gICAgY2xlYW5lcjp7XG4gICAgICBub3RUaW1lOiA1MDAsIC8vIFRpbWUgdG8gZGlzcGxheSBOb3RpZmljYXRpb25zLlxuICAgICAgYWN0aW9uOiAnYm90aCcsIC8vIGJvdGh8YnV0dG9ufHBhc3RlICdidXR0b24nIG9ubHkgY2xlYW5zIHZpYSB0b29sYmFyIGJ1dHRvbiwgJ3Bhc3RlJyBvbmx5IGNsZWFuIHdoZW4gcGFzdGluZyBjb250ZW50LCBib3RoIGRvZXMgYm90aCBvcHRpb25zLlxuICAgICAgbmV3bGluZTogJzxicj4nLCAvLyBTdW1tZXJub3RlJ3MgZGVmYXVsdCBpcyB0byB1c2UgJzxwPjxicj48L3A+J1xuICAgICAgbm90U3R5bGU6ICdwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtsZWZ0OjA7cmlnaHQ6MCcsIC8vIFBvc2l0aW9uIG9mIE5vdGlmaWNhdGlvblxuICAgICAgaWNvbjogJzxpIGNsYXNzPVwibm90ZS1pY29uXCI+W3hdPC9pPicsXG4gICAgICBrZWVwSHRtbDogdHJ1ZSwgLy8gUmVtb3ZlIGFsbCBIdG1sIGZvcm1hdHNcbiAgICAgIGtlZXBDbGFzc2VzOiBmYWxzZSwgLy8gUmVtb3ZlIENsYXNzZXNcbiAgICAgIGtlZXBPbmx5VGFnczogWyc8YnI+JywnPGE+JywnPHA+J10sIC8vIElmIGtlZXBIdG1sIGlzIHRydWUsIHJlbW92ZSBhbGwgdGFncyBleGNlcHQgdGhlc2VcbiAgICAgIGJhZFRhZ3M6IFsnc3R5bGUnLCAnc2NyaXB0JywgJ2FwcGxldCcsICdlbWJlZCcsICdub2ZyYW1lcycsICdub3NjcmlwdCcsICdodG1sJ10sIC8vIFJlbW92ZSBmdWxsIHRhZ3Mgd2l0aCBjb250ZW50c1xuICAgICAgYmFkQXR0cmlidXRlczogWydkaXInLCdpZCcsJ3N0eWxlJywgJ3N0YXJ0JywnbmFtZScsJ2NsYXNzJywnYWxpZ24nLCdvbnRvdWNoc3RhcnQnXSAvLyBSZW1vdmUgYXR0cmlidXRlcyBmcm9tIHJlbWFpbmluZyB0YWdzXG4gICAgfSxcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgcGF0aDogJy9qcy9zdW1tZXJub3RlL3RwbHMnLFxuICAgICAgbGlzdDoge1xuICAgICAgICAncmVjdWFkcm9fZ2VuZXJpY28nOiAnUmVjdWFkcm8gZ2Vuw6lyaWNvJyxcbiAgICAgICAgJ3JlY3VhZHJvX2RjaGEnOiAnUmVjdWFkcm8gZGVyZWNobycsXG4gICAgICAgICdyZWN1YWRyb19penEnOiAnUmVjdWFkcm8gaXpxdWllcmRvJyxcbiAgICAgICAgJ3JlY3VhZHJvJzogJ1JlY3VhZHJvIFwiYW50aWd1b1wiJ1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIH1cbn0pO1xuLy8vL1xuXG47KGZ1bmN0aW9uKCAkLCB3aW5kb3csIGRvY3VtZW50LCB1bmRlZmluZWQgKVxuICB7XG4gICAgJC5mbi5kb3VibGVUYXBUb0dvID0gZnVuY3Rpb24oIHBhcmFtcyApXG4gICAge1xuICAgICAgaWYoICEoICdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdyApICYmXG4gICAgICAgIC
1FuYXZpZ2F0b3IubXNNYXhUb3VjaFBvaW50cyAmJlxuICAgICAgICAgICFuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkubWF0Y2goIC93aW5kb3dzIHBob25lIG9zIDcvaSApICkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICB0aGlzLmVhY2goIGZ1bmN0aW9uKClcbiAgICAgICAge1xuICAgICAgICAgIHZhciBjdXJJdGVtID0gZmFsc2U7XG5cbiAgICAgICAgICAkKCB0aGlzICkub24oICdjbGljaycsIGZ1bmN0aW9uKCBlIClcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdmFyIGl0ZW0gPSAkKCB0aGlzICk7XG4gICAgICAgICAgICAgIGlmKCBpdGVtWyAwIF0gIT0gY3VySXRlbVsgMCBdIClcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICBjdXJJdGVtID0gaXRlbTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAkKCBkb2N1bWVudCApLm9uKCAnY2xpY2sgdG91Y2hzdGFydCBNU1BvaW50ZXJEb3duJywgZnVuY3Rpb24oIGUgKVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB2YXIgcmVzZXRJdGVtID0gdHJ1ZSxcbiAgICAgICAgICAgICAgICBwYXJlbnRzXHQgID0gJCggZS50YXJnZXQgKS5wYXJlbnRzKCk7XG5cbiAgICAgICAgICAgICAgZm9yKCB2YXIgaSA9IDA7IGkgPCBwYXJlbnRzLmxlbmd0aDsgaSsrIClcbiAgICAgICAgICAgICAgICBpZiggcGFyZW50c1sgaSBdID09IGN1ckl0ZW1bIDAgXSApXG4gICAgICAgICAgICAgICAgcmVzZXRJdGVtID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgaWYoIHJlc2V0SXRlbSApXG4gICAgICAgICAgICAgICAgY3VySXRlbSA9IGZhbHNlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgfSkoIGpRdWVyeSwgd2luZG93LCBkb2N1bWVudCApO1xuJCggJy5jYW1iaWFyTm9kb1BvcnRhZGEgdWwnICkuZG91YmxlVGFwVG9HbygpO1xuXG4kKFwiLmJ1c2NhclwiKS5ob3ZlcihmdW5jdGlvbigpe1xuICAgICQodGhpcykuZmluZChcIi5mb3JtLWNvbnRyb2xcIikuZm9jdXMoKTtcbn0pO1xuXG4kKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpIHtcbiAgJCgnLmluZGV4LWxpc3RhZG9zJykuZWFjaChcbiAgICBmdW5jdGlvbigpe1xuICAgICAgdmFyIHVybCA9ICQodGhpcykuYXR0cignZGF0YS1wYXRoJyk7XG4gICAgICB2Y
1XIgdG90YWwgPSAkKCcuaW5kZXgtbGlzdGFkb3MgLnBhZ2UtbGluaycpLmxlbmd0aCAtMTtcbiAgICAgICQoJy5pbmRleC1saXN0YWRvcyAucGFnZS1saW5rJykuZWFjaChcbiAgICAgICAgZnVuY3Rpb24oaSl7XG4gICAgICAgICAgJCh0aGlzKS5hdHRyKCdocmVmJywkKHRoaXMpLmF0dHIoJ2hyZWYnKS5yZXBsYWNlKC9cXC9cXHcqXFw/Ky9nLHVybCtcIj9cIikpO1xuICAgICAgICB9XG4gICAgICApO1xuICAgICAgaWYgKHRvdGFsPjExKXtcbiAgICAgICAgdmFyIGluZGV4ID0gJCgnLmluZGV4LWxpc3RhZG9zIC5wYWdlLWl0ZW0nKVxuICAgICAgICAgIC5pbmRleCgkKCcuaW5kZXgtbGlzdGFkb3MgLnBhZ2UtaXRlbS5hY3RpdmUnKSk7XG4gICAgICAgIHZhciBtZWRpbyA9IE1hdGgucm91bmQodG90YWwgLyAyKTtcbiAgICAgICAgdmFyIGMxID0gTWF0aC5yb3VuZCh0b3RhbCAvIDQpO1xuICAgICAgICB2YXIgYzIgPSBNYXRoLnJvdW5kKHRvdGFsIC8gNCozKTtcbiAgICAgICAgdmFyIGkxID0gaW5kZXggLSAxXG4gICAgICAgIHZhciBpMiA9IGluZGV4ICsgMTtcbiAgICAgICAgdmFyIGFycmF5ID0gWzAsMSx0b3RhbC0xLGMxLG1lZGlvLGMyLGkxLGluZGV4LGkyLHRvdGFsXTtcbiAgICAgICAgJCgnLmluZGV4LWxpc3RhZG9zIC5wYWdlLWl0ZW0nKS5lYWNoKFxuICAgICAgICAgIGZ1bmN0aW9uKGkpe1xuICAgICAgICAgICAgaWYoJC5pbkFycmF5KGksYXJyYXkpID09IC0xKXtcbiAgICAgICAgICAgICQodGhpcykucmVtb3ZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn0pO1xuZnVuY3Rpb24gZW52aWFyQ29udGFjdG9Gb3JtKGRhdGEpIHtcbiAgdmFyIFhIUiA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICB2YXIgRkQgID0gbmV3IEZvcm1EYXRhKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmb3JtdWxhcmlvQ29udGFjdG8nKSk7XG4gIHZhciBjc3JmID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIm1ldGFbbmFtZT1jc3JmLXRva2VuXVwiKS5jb250ZW50O1xuICAvL3ZhciBmb3JtRGF0YSA9IEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuXG4gIGZvcihuYW1lIGluIGRhdGEpIHtcbiAgICBGRC5hcHBlbmQobmFtZSwgZGF0YVtuYW1lXSk7XG4gIH1cblxuICBYSFIuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgYWxlcnQoJ1llYWghIERhdGEgc2VudCBhbmQgcmVzcG9uc2UgbG9hZGVkLicpO1xuICB9KTtcbiAgWEhSLmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBhbGVydCgnT29wcyEgU29tZXRoaW5nIHdlbnQgd3JvbmcuJyk7XG4gIH0pO1xuXG4gIC8vWEhSLm9wZW4oJ1BPU1QnLCAnaHR0cHM6Ly9leGFtcGxlLmNvbS8nKTtcbiAgWEhSLm9wZW4oICdQT1NUJywgJ2h0dHA6Ly8xMjcuMC4wLjE6NDAwMC8nICk7XG4gIFhIUi5zZXRSZXF1ZXN0SGVhZGVyKCAnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcgKTtcbiAgWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiWC1DU1JGLVRva2VuXCIsIGNzcmYpO1xuICBYSFIuc2VuZChGRCk7XG4gIC8vWEhSLnNlbmQoIFwiZm9ybXVsYXJpbz1cIitmb3JtRGF0YSApO1xufVxuZnVuY3Rpb24gYWN0dWFsaXphckNTUkYoKXtcbiAgdmFyIGNzcmYgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdtZXRhW25hbWU9XCJjc3JmLXRva2VuXCJdJykuY29udGVudFxuICB2YXIgaW5wdXRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcImlucHV0W25hbWU9J19jc3JmX3Rva2VuJ11cIik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgKytpKSB7XG4gICAgaW5wdXRzW2ldLnZhbHVlID0gY3NyZjtcbiAgfVxufVxuJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKSB7XG4gIGFjdHVhbGl6YXJDU1JGKCk7XG59KTtcbiQoJyNDb21lbnRhcmlvc0N1ZW50YScpLm9uKCdzaG93LmJzLm1vZGFsJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gIHZhciBidXR0b24gPSAkKGV2ZW50LnJlbGF0ZWRUYXJnZXQpO1xuICB2YXIgdXJsID0gYnV0dG9uLmRhdGEoJ3VybCcpO1xuICB2YXIgbW9kYWwgPSAkKHRoaXMpXG4gIHZhciBxID0gbW9kYWwuZmluZCgnLmNvbl9yZWRpcmVjY2lvbicpXG4gIG1vZGFsLmZpbmQoJy5jb25fcmVkaXJlY2Npb24nKS5hdHRyKFwiaHJlZlwiLCBcIi9jb21lbnRhclwiK3VybClcbn0pXG4iXSwibWFwcGluZ3MiOiJBQUFBQSxDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDQyxLQUFLLENBQUMsWUFBVztFQUMzQkYsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUNHLElBQUksQ0FBQyxZQUFXO0lBQ3JDSCxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUNJLE9BQU8sQ0FBQyxDQUFDO0VBQ25CLENBQUMsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUNGSixDQUFDLENBQUMsMlBBQTJQLENBQUMsQ0FBQ0csSUFBSSxDQUFDLFlBQVU7RUFDNVFILENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQ0ksT0FBTyxDQUFDO0lBQ2RDLFdBQVcsRUFBRSxjQUFjO0lBQzNCQyxrQkFBa0IsRUFBRSxDQUFDO0lBQ3JCQyxVQUFVLEVBQUUsSUFBSTtJQUNoQkMsS0FBSyxFQUFFLElBQUk7SUFDWEMsSUFBSSxFQUFFO01BQ0pDLEtBQUssRUFBRSxHQUFHO01BQ1ZDLEdBQUcsRUFBRyxTQUFBQSxDQUFVQyxNQUFNLEVBQUU7UUFDdEIsT0FBTyxhQUFhLEd
1BQUdBLE1BQU0sQ0FBQ0MsSUFBSTtNQUNwQyxDQUFDO01BQ0RDLFFBQVEsRUFBRSxNQUFNO01BQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7UUFDdEMsT0FBTztVQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7UUFDaEIsQ0FBQztNQUNIO0lBQ0Y7RUFDRixDQUFDLENBQUM7QUFDSixDQUFDLENBQUM7QUFDRmhCLENBQUMsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDRyxJQUFJLENBQUMsWUFBVTtFQUM3Q0gsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDSSxPQUFPLENBQUM7SUFDZEMsV0FBVyxFQUFFLGNBQWM7SUFDM0JDLGtCQUFrQixFQUFFLENBQUM7SUFDckJDLFVBQVUsRUFBRSxJQUFJO0lBQ2hCQyxLQUFLLEVBQUUsSUFBSTtJQUNYQyxJQUFJLEVBQUU7TUFDSkMsS0FBSyxFQUFFLEdBQUc7TUFDVkMsR0FBRyxFQUFHLFNBQUFBLENBQVVDLE1BQU0sRUFBRTtRQUN0QixPQUFPLGFBQWEsR0FBR0EsTUFBTSxDQUFDQyxJQUFJLEdBQUcsUUFBUTtNQUMvQyxDQUFDO01BQ0RDLFFBQVEsRUFBRSxNQUFNO01BQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7UUFDdEMsT0FBTztVQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7UUFDaEIsQ0FBQztNQUNIO0lBQ0Y7RUFDRixDQUFDLENBQUM7QUFDSixDQUFDLENBQUM7QUFDRmhCLENBQUMsQ0FBQyw4SUFBOEksQ0FBQyxDQUFDRyxJQUFJLENBQUMsWUFBVTtFQUMvSkgsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDSSxPQUFPLENBQUM7SUFDZEMsV0FBVyxFQUFFLGlCQUFpQjtJQUM5QkMsa0JBQWtCLEVBQUUsQ0FBQztJQUNyQkMsVUFBVSxFQUFFLElBQUk7SUFDaEJDLEtBQUssRUFBRSxJQUFJO0lBQ1hDLElBQUksRUFBRTtNQUNKQyxLQUFLLEVBQUUsR0FBRztNQUNWQyxHQUFHLEVBQUcsU0FBQUEsQ0FBVUMsTUFBTSxFQUFFO1FBQ3RCLE9BQU8sZUFBZSxHQUFHQSxNQUFNLENBQUNDLElBQUk7TUFDdEMsQ0FBQztNQUNEQyxRQUFRLEVBQUUsTUFBTTtNQUNoQkMsY0FBYyxFQUFFLFNBQUFBLENBQVVDLElBQUksRUFBRUosTUFBTSxFQUFFO1FBQ3RDLE9BQU87VUFDTEssT0FBTyxFQUFFRCxJQUFJLENBQUNBO1FBQ2hCLENBQUM7TUFDSDtJQUNGO0VBQ0YsQ0FBQyxDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBQ0YsU0FBU0UsNEJBQTRCQSxDQUFBLEVBQUU7RUFDckNsQixDQUFDLENBQUMsaUJBQWlCLENBQUMsQ0FBQ0csSUFBSSxDQUFDLFVBQVNnQixDQUFDLEVBQUVDLEdBQUcsRUFBQztJQUFDQyxxQkFBcUIsQ0FBQ0QsR0FBRyxDQUFDO0VBQUEsQ0FBQyxDQUFDO0FBQ3pFO0FBQ0EsU0FBU0MscUJBQXFCQSxDQUFDRCxHQUFHLEVBQUU7RUFDaENwQixDQUFDLENBQUNvQixHQUFHLENBQUMsQ0FBQ2hCLE9BQU8sQ0FBQztJQUNiQyxXQUFXLEVBQUUsaUJBQWlCO0lBQzlCQyxrQkFBa0IsRUFBRSxDQUFDO0lBQ3JCQyxVQUFVLEVBQUUsSUFBSTtJQUNoQkMsS0FBSyxFQUFFLElBQUk7SUFDWEMsSUFBSSxFQUFFO01BQ0pDLEtBQUssRUFBRSxHQUFHO01BQ1ZDLEdBQUcsRUFBRyxTQUFBQSxDQUFVQyxNQUFNLEVBQUU7UUFDdEIsT0FBTyxnQkFBZ0IsR0FBR0EsTUFBTSxDQUFDQyxJQUFJO01BQ3ZDLENBQUM7TUFDREMsUUFBUSxFQUFFLE1BQU07TUFDaEJDLGNBQWMsRUFBRSxTQUFBQSxDQUFVQyxJQUFJLEVBQUVKLE1BQU0sRUFBRTtRQUN0QyxPQUFPO1VBQ0xLLE9BQU8sRUFBRUQsSUFBSSxDQUFDQTtRQUNoQixDQUFDO01BQ0g7SUFDRjtFQUNGLENBQUMsQ0FBQztFQUNGaEIsQ0FBQyxDQUFDb0IsR0FBRyxDQUFDLENBQUNFLEVBQUUsQ0FBQyxRQUFRLEVBQUUsWUFBVTtJQUM1QixJQUFJQyxNQUFNLEdBQUd2QixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUN3QixJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQ0MsSUFBSSxDQUFDLENBQUM7SUFDbkR6QixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMwQixNQUFNLENBQUMsQ0FBQyxDQUFDQSxNQUFNLENBQUMsQ0FBQyxDQUFDRixJQUFJLENBQUMsWUFBWSxDQUFDLENBQUNHLEdBQUcsQ0FBQ0osTUFBTSxDQUFDO0VBQzFELENBQUUsQ0FBQztBQUNQO0FBQ0FMLDRCQUE0QixDQUFDLENBQUM7QUFDOUIsU0FBU1UsS0FBS0EsQ0FBQSxFQUFHO0VBQ2Y1QixDQUFDLENBQUMsa0xBQWtMLENBQUMsQ0FBQ0csSUFBSSxDQUFDLFlBQVU7SUFDbk1ILENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQ0ksT0FBTyxDQUFDO01BQ2RDLFdBQVcsRUFBRSxhQUFhO01BQzFCQyxrQkFBa0IsRUFBRSxDQUFDO01BQ3JCQyxVQUFVLEVBQUUsSUFBSTtNQUNoQkMsS0FBSyxFQUFFLElBQUk7TUFDWEMsSUFBSSxFQUFFO1FBQ0pDLEtBQUssRUFBRSxHQUFHO1FBQ1ZDLEdBQUcsRUFBRyxTQUFBQSxDQUFVQyxNQUFNLEVBQUU7VUFDdEIsT0FBTyxhQUFhLEd
1BQUdBLE1BQU0sQ0FBQ0MsSUFBSTtRQUNwQyxDQUFDO1FBQ0RDLFFBQVEsRUFBRSxNQUFNO1FBQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7VUFDdEMsT0FBTztZQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7VUFDaEIsQ0FBQztRQUNIO01BQ0Y7SUFDRixDQUFDLENBQUM7RUFDSixDQUFDLENBQUM7QUFDSjtBQUNBWSxLQUFLLENBQUMsQ0FBQztBQUNQLFNBQVNDLFFBQVFBLENBQUEsRUFBRztFQUNsQjdCLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDRyxJQUFJLENBQUMsWUFBVTtJQUNqQ0gsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDSSxPQUFPLENBQUM7TUFDZEMsV0FBVyxFQUFFLGdCQUFnQjtNQUM3QkMsa0JBQWtCLEVBQUUsQ0FBQztNQUNyQkMsVUFBVSxFQUFFLElBQUk7TUFDaEJDLEtBQUssRUFBRSxJQUFJO01BQ1hDLElBQUksRUFBRTtRQUNKQyxLQUFLLEVBQUUsR0FBRztRQUNWQyxHQUFHLEVBQUcsU0FBQUEsQ0FBVUMsTUFBTSxFQUFFO1VBQ3RCLE9BQU8sZ0JBQWdCLEdBQUdBLE1BQU0sQ0FBQ0MsSUFBSTtRQUN2QyxDQUFDO1FBQ0RDLFFBQVEsRUFBRSxNQUFNO1FBQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7VUFDdEMsT0FBTztZQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7VUFDaEIsQ0FBQztRQUNIO01BQ0Y7SUFDRixDQUFDLENBQUM7RUFDSixDQUFDLENBQUM7QUFDSjtBQUNBYSxRQUFRLENBQUMsQ0FBQztBQUVWLFNBQVNDLFdBQVdBLENBQUEsRUFBRztFQUNyQjlCLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDRyxJQUFJLENBQUMsWUFBVTtJQUNwQ0gsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDSSxPQUFPLENBQUM7TUFDZEMsV0FBVyxFQUFFLG1CQUFtQjtNQUNoQ0Msa0JBQWtCLEVBQUUsQ0FBQztNQUNyQkMsVUFBVSxFQUFFLElBQUk7TUFDaEJDLEtBQUssRUFBRSxJQUFJO01BQ1hDLElBQUksRUFBRTtRQUNKQyxLQUFLLEVBQUUsR0FBRztRQUNWQyxHQUFHLEVBQUcsU0FBQUEsQ0FBVUMsTUFBTSxFQUFFO1VBQ3RCLE9BQU8sa0JBQWtCLEdBQUdBLE1BQU0sQ0FBQ0MsSUFBSTtRQUN6QyxDQUFDO1FBQ0RDLFFBQVEsRUFBRSxNQUFNO1FBQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7VUFDdEMsT0FBTztZQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7VUFDaEIsQ0FBQztRQUNIO01BQ0Y7SUFDRixDQUFDLENBQUM7RUFDSixDQUFDLENBQUM7QUFDSjtBQUNBYyxXQUFXLENBQUMsQ0FBQztBQUViOUIsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDRyxJQUFJLENBQUMsVUFBU2dCLENBQUMsRUFBRUMsR0FBRyxFQUFDO0VBQUNXLHNCQUFzQixDQUFDWCxHQUFHLENBQUM7QUFBQSxDQUFDLENBQUM7QUFDcEUsU0FBU1ksOEJBQThCQSxDQUFBLEVBQUU7RUFDdkNoQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUNHLElBQUksQ0FBQyxVQUFTZ0IsQ0FBQyxFQUFFQyxHQUFHLEVBQUM7SUFBQ1csc0JBQXNCLENBQUNYLEdBQUcsQ0FBQztFQUFBLENBQUMsQ0FBQztBQUN0RTtBQUNBLFNBQVNXLHNCQUFzQkEsQ0FBQ1gsR0FBRyxFQUFDO0VBQ2xDcEIsQ0FBQyxDQUFDb0IsR0FBRyxDQUFDLENBQUNoQixPQUFPLENBQUM7SUFDYkMsV0FBVyxFQUFFLGlCQUFpQjtJQUM5QkMsa0JBQWtCLEVBQUUsQ0FBQztJQUNyQkMsVUFBVSxFQUFFLElBQUk7SUFDaEJDLEtBQUssRUFBRSxJQUFJO0lBQ1hDLElBQUksRUFBRTtNQUNKQyxLQUFLLEVBQUUsR0FBRztNQUNWQyxHQUFHLEVBQUcsU0FBQUEsQ0FBVUMsTUFBTSxFQUFFO1FBQ3RCLE9BQU8saUJBQWlCLEdBQUdBLE1BQU0sQ0FBQ0MsSUFBSTtNQUN4QyxDQUFDO01BQ0RDLFFBQVEsRUFBRSxNQUFNO01BQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7UUFDdEMsT0FBTztVQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7UUFDaEIsQ0FBQztNQUNIO0lBQ0Y7RUFDRixDQUFDLENBQUM7RUFDRmhCLENBQUMsQ0FBQ29CLEdBQUcsQ0FBQyxDQUFDRSxFQUFFLENBQUMsUUFBUSxFQUFFLFlBQVU7SUFDNUIsSUFBSUMsTUFBTSxHQUFHdkIsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDd0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUNDLElBQUksQ0FBQyxDQUFDO0lBQ25EekIsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ0EsTUFBTSxDQUFDLENBQUMsQ0FBQ0YsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDRyxHQUFHLENBQUNKLE1BQU0sQ0FBQztFQUMzRCxDQUFFLENBQUM7QUFDTDtBQUFDO0FBQ0R2QixDQUFDLENBQUMsbUJBQW1CLENBQUMsQ0FBQ0csSUFBSSxDQUFDLFVBQVNnQixDQUFDLEVBQUVDLEdBQUcsRUFBQztFQUFDYSw0QkFBNEIsQ0FBQ2IsR0FBRyxDQUFDO0FBQUEsQ0FBQyxDQUFDO0FBQ2hGLFNBQVNjLG9DQUFvQ0EsQ0FBQSxFQUFFO0VBQzdDbEMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUNHLElBQUksQ0FBQyxVQUFTZ0IsQ0FBQyxFQUFFQyxHQUFHLEVBQUM7SUFBQ2EsNEJBQTRCLENBQUNiLEdBQUcsQ0FBQztFQUFBLENBQUMsQ0FBQztBQUNsRjtBQUNBLFNBQVNhLDRCQUE0QkEsQ0FBQ2IsR0FBRyxFQUFDO0VBQ3hDcEIsQ0FBQyxDQUFDb0IsR0FBRyxDQUFDLENBQUNoQixPQUFPLENBQUM7SUFDYkMsV0FBVyxFQUFFLGlCQUFpQjtJQUM5QkMsa0JBQWtCLEVBQUUsQ0FBQztJQUNyQkMsVUFBVSxFQUFFLElBQUk7SUFDaEJDLEtBQUssRUFBRSxJQUFJO0lBQ1hDLElBQUksRUFBRTtNQUNKQyxLQUFLLEVBQUUsR0FBRztNQUNWQyxHQUFHLEVBQUcsU0FBQUEsQ0FBVUMsTUFBTSxFQUFFO1FBQ3RCLE9BQU8sdUJBQXVCLEdBQUdBLE1BQU0sQ0FBQ0MsSUFBSTtNQUM5QyxDQUFDO01BQ0RDLFFBQVEsRUFBRSxNQUFNO01BQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7UUFDdEMsT0FBTztVQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7UUFDaEIsQ0FBQztNQUNIO0lBQ0Y7RUFDRixDQUFDLENBQUM7RUFDRmhCLENBQUMsQ0FBQ29CLEdBQUcsQ0FBQyxDQUFDRSxFQUFFLENBQUMsUUFBUSxFQUFFLFlBQVU7SUFDNUIsSUFBSUMsTUFBTSxHQUFHdkIsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDd0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUNDLElBQUksQ0FBQyxDQUFDO0lBQ25EekIsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ0EsTUFBTSxDQUFDLENBQUMsQ0FBQ0YsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDRyxHQU
1FHLENBQUNKLE1BQU0sQ0FBQztFQUMzRCxDQUFFLENBQUM7QUFDTDtBQUFDO0FBRUR2QixDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDcUIsRUFBRSxDQUFDLE9BQU8sRUFBQyw0QkFBNEIsRUFBRSxVQUFTYSxDQUFDLEVBQUU7RUFDL0RBLENBQUMsQ0FBQ0MsY0FBYyxDQUFDLENBQUM7RUFDbEIsSUFBSUMsSUFBSSxHQUFHLElBQUlDLElBQUksQ0FBQyxDQUFDLENBQUNDLE9BQU8sQ0FBQyxDQUFDO0VBQy9CLElBQUlDLFFBQVEsR0FBR3hDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQ2dCLElBQUksQ0FBQyxVQUFVLENBQUM7RUFDdkMsSUFBSXlCLElBQUksR0FBR3pDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQzBCLE1BQU0sQ0FBQyxDQUFDLENBQUNGLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQ0EsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDa0IsTUFBTTtFQUNuRSxJQUFJRCxJQUFJLEdBQUcsQ0FBQyxFQUFFO0lBQ1osSUFBSUUsRUFBRSxHQUFHM0MsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FDdEJGLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQ0EsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDb0IsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDQyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQ3BERixFQUFFLEdBQUdBLEVBQUUsQ0FBQ0csS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztFQUN2QixDQUFDLE1BQUk7SUFDSCxJQUFJSCxFQUFFLEdBQUczQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMwQixNQUFNLENBQUMsQ0FBQyxDQUN0QkYsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDQSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUNvQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUNDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDckRGLEVBQUUsR0FBR0EsRUFBRSxDQUFDRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0VBQ3ZCO0VBQ0EsSUFBSUMsYUFBYSxHQUFHUCxRQUFRLENBQ3pCUSxPQUFPLENBQUMsbUJBQW1CLEVBQUUsY0FBY1gsSUFBSSxHQUFHLENBQUMsQ0FDbkRXLE9BQU8sQ0FBQyxlQUFlLEVBQUUsVUFBVUwsRUFBRSxHQUFHLENBQUMsQ0FDekNLLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxjQUFjTCxFQUFFLEdBQUcsQ0FBQyxDQUNqREssT0FBTyxDQUFDLGVBQWUsRUFBRSxhQUFhWCxJQUFJLEdBQUcsQ0FBQyxDQUM5Q1csT0FBTyxDQUFDLFdBQVcsRUFBRSxTQUFTTCxFQUFFLEdBQUcsQ0FBQyxDQUNwQ0ssT0FBTyxDQUFDLGVBQWUsRUFBRSxhQUFhTCxFQUFFLEdBQUcsQ0FBQztFQUMvQyxJQUFJTSxtQkFBbUIsR0FBRyxJQUFJLENBQUNDLFVBQVUsQ0FBQ0MsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDQyxTQUFTLENBQUMsSUFBSSxDQUFDO0VBQ3BGLElBQUlDLGtCQUFrQixHQUFHSixtQkFBbUIsQ0FBQ0ssZ0JBQWdCLENBQUMsSUFBSSxDQUFDO0VBQ25FdEQsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDK0IsT0FBTyxDQUFDUixhQUFhLENBQUM7RUFDekQ7RUFDQWYsOEJBQThCLENBQUMsQ0FBQztFQUNoQ0Usb0NBQW9DLENBQUMsQ0FBQztFQUN0QyxJQUFJc0IsU0FBUyxHQUFHeEQsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLENBQUMyQixHQUFHLENBQUMsQ0FBQztFQUM3QzNCLENBQUMsQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDMkIsR0FBRyxDQUFDNkIsU0FBUyxDQUFDO0FBQzdELENBQUMsQ0FBQztBQUNGO0FBQ0E7QUFDQXhELENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNxQixFQUFFLENBQUMsT0FBTyxFQUFDLG1CQUFtQixFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUN0REEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJeUIsSUFBSSxHQUFHekMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ0YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDQSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUNrQixNQUFNO0VBQ25FLElBQUlELElBQUksR0FBRyxDQUFDLEVBQUU7SUFDWixJQUFJRSxFQUFFLEdBQUczQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMwQixNQUFNLENBQUMsQ0FBQyxDQUN0QkYsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDQSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUNvQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUNDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDcERGLEVBQUUsR0FBR0EsRUFBRSxDQUFDRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0VBQ3ZCLENBQUMsTUFBSTtJQUNILElBQUlILEVBQUUsR0FBRzNDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQzBCLE1BQU0sQ0FBQyxDQUFDLENBQ3RCRixJQUFJLENBQUMsU0FBUyxDQUFDLENBQUNBLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQ29CLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQ0MsSUFBSSxDQUFDLElBQUksQ0FBQztJQUNyREYsRUFBRSxHQUFHQSxFQUFFLENBQUNHLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7RUFDdkI7RUFDQSxJQUFJQyxhQUFhLEdBQUdQLFFBQVEsQ0FDekJRLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxjQUFjWCxJQUFJLEdBQUcsQ0FBQyxDQUNuRFcsT0FBTyxDQUFDLGVBQWUsRUFBRSxVQUFVTCxFQUFFLEdBQUcsQ0FBQyxDQUN6Q0ssT0FBTyxDQUFDLG1CQUFtQixFQUFFLGNBQWNMLEVBQUUsR0FBRyxDQUFDLENBQ2pESyxPQUFPLENBQUMsZUFBZSxFQUFFLGFBQWFYLElBQUksR0FBRyxDQUFDLENBQzlDVyxPQUFPLENBQUMsV0FBVyxFQUFFLFNBQVNMLEVBQUUsR0FBRyxDQUFDLENBQ3BDSyxPQUFPLENBQUMsZUFBZSxFQUFFLGFBQWFMLEVBQUUsR0FBRyxDQUFDO0VBQy9DLElBQUlNLG1CQUFtQixHQUFHLElBQUksQ0FBQ0MsVUFBVSxDQUFDQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUNDLFNBQVMsQ0FBQyxJQUFJLENBQUM7RUFDcEYsSUFBSUMsa0JBQWtCLEdBQUdKLG1CQUFtQixDQUFDSyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUM7RUFDbkUsSUFBSUcsUUFBUSxHQUFHekQsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDK0IsT0FBTyxDQUFDUixhQU
1FhLENBQUM7O0VBRXhFO0VBQ0FmLDhCQUE4QixDQUFDLENBQUM7RUFDaENFLG9DQUFvQyxDQUFDLENBQUM7RUFDdEMsSUFBSXNCLFNBQVMsR0FBR3hELENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDMkIsR0FBRyxDQUFDLENBQUM7RUFDN0MzQixDQUFDLENBQUMseUNBQXlDLENBQUMsQ0FBQzJCLEdBQUcsQ0FBQzZCLFNBQVMsQ0FBQztFQUMzRCxJQUFJRSxVQUFVLEdBQUcsSUFBSSxDQUFDUixVQUFVLENBQUNDLGFBQWEsQ0FBQyxXQUFXLENBQUM7RUFDM0QsSUFBSVEsU0FBUyxHQUFHRCxVQUFVLENBQUNKLGdCQUFnQixDQUFDLElBQUksQ0FBQztFQUNqREksVUFBVSxDQUFDRSxTQUFTLEdBQUcsRUFBRTtFQUN6QkQsU0FBUyxHQUFHRSx1QkFBdUIsQ0FBQ1Isa0JBQWtCLEVBQUVNLFNBQVMsQ0FBQztFQUNsRUEsU0FBUyxDQUFDRyxPQUFPLENBQUMsVUFBUzNCLENBQUMsRUFBQ2hCLENBQUMsRUFBQzRDLENBQUMsRUFBQztJQUM5QkwsVUFBVSxDQUFDTSxXQUFXLENBQUM3QixDQUFDLENBQUM7RUFDNUIsQ0FBQyxDQUFDO0VBQ0Y4QixlQUFlLENBQUNQLFVBQVUsQ0FBQztFQUMzQlEsWUFBWSxDQUFDUixVQUFVLENBQUM7RUFDeEJPLGVBQWUsQ0FBQ1AsVUFBVSxDQUFDO0VBQzNCUywwQkFBMEIsQ0FBQyxDQUFDO0FBQzlCLENBQUMsQ0FBQztBQUVGLFNBQVNOLHVCQUF1QkEsQ0FBQ08sUUFBUSxFQUFFQyxLQUFLLEVBQUM7RUFDL0MsSUFBSUMsUUFBUSxHQUFHLENBQUMsR0FBR0QsS0FBSyxDQUFDLENBQUNFLE1BQU0sQ0FBQ3BDLENBQUMsSUFBSSxDQUFDQSxDQUFDLENBQUNnQixhQUFhLENBQUMsMEJBQTBCLENBQUMsQ0FBQ3FCLE9BQU8sQ0FBQztFQUMzRixJQUFJQyxRQUFRLEdBQUcsQ0FBQztFQUNoQixJQUFJQyxDQUFDLEdBQUdMLEtBQUssQ0FBQzNCLE1BQU07RUFDcEIyQixLQUFLLEdBQUcsRUFBRTtFQUNWLEtBQUssSUFBSWxELENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBRXVELENBQUMsRUFBRXZELENBQUMsRUFBRSxFQUFFO0lBQ3pCLElBQUlpRCxRQUFRLENBQUNqRCxDQUFDLENBQUMsSUFDUmlELFFBQVEsQ0FBQ2pELENBQUMsQ0FBQyxDQUFDZ0MsYUFBYSxDQUFDLDBCQUEwQixDQUFDLENBQUNxQixPQUFPLEVBQUM7TUFDbkVILEtBQUssQ0FBQ2xELENBQUMsQ0FBQyxHQUFHaUQsUUFBUSxDQUFDakQsQ0FBQyxDQUFDO0lBQ3hCLENBQUMsTUFBTTtNQUNMa0QsS0FBSyxDQUFDbEQsQ0FBQyxDQUFDLEdBQUdtRCxRQUFRLENBQUNHLFFBQVEsQ0FBQztNQUM3QixFQUFFQSxRQUFRO0lBQ1o7RUFDRjtFQUNBLE9BQU9KLEtBQUs7QUFDZDtBQUVBLFNBQVNILFlBQVlBLENBQUNSLFVBQVUsRUFBQztFQUMvQixJQUFJQyxTQUFTLEdBQUdELFVBQVUsQ0FBQ0osZ0JBQWdCLENBQUMsSUFBSSxDQUFDO0VBQ2pESyxTQUFTLEdBQUdnQixLQUFLLENBQUNDLElBQUksQ0FBQ2pCLFNBQVMsQ0FBQyxDQUFDa0IsSUFBSSxDQUFDLFVBQVNkLENBQUMsRUFBQ2UsQ0FBQyxFQUFDO0lBQ2xEO0lBQ0E7SUFDQWYsQ0FBQyxHQUFHQSxDQUFDLENBQUNaLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDNEIsS0FBSztJQUNqREQsQ0FBQyxHQUFHQSxDQUFDLENBQUMzQixhQUFhLENBQUMsc0JBQXNCLENBQUMsQ0FBQzRCLEtBQUs7SUFDakQsT0FBUWhCLENBQUMsR0FBR2UsQ0FBQztFQUNmLENBQUMsQ0FBQztFQUNBOztFQUVGcEIsVUFBVSxDQUFDRSxTQUFTLEdBQUcsRUFBRTtFQUN6QkQsU0FBUyxDQUFDRyxPQUFPLENBQUMsVUFBUzNCLENBQUMsRUFBQ2hCLENBQUMsRUFBQzRDLENBQUMsRUFBQztJQUM5QkwsVUFBVSxDQUFDTSxXQUFXLENBQUM3QixDQUFDLENBQUM7RUFDNUIsQ0FBQyxDQUFDO0FBRUo7QUFDQSxTQUFTOEIsZUFBZUEsQ0FBQ1AsVUFBVSxFQUFDO0VBQ2xDLElBQUlDLFNBQVMsR0FBR0QsVUFBVSxDQUFDSixnQkFBZ0IsQ0FBQyxJQUFJLENBQUM7RUFDakRLLFNBQVMsQ0FBQ0csT0FBTyxDQUFDLFVBQVMzQixDQUFDLEVBQUNoQixDQUFDLEVBQUM0QyxDQUFDLEVBQUM7SUFDL0JpQixLQUFLLEdBQUc3QyxDQUFDLENBQUNnQixhQUFhLENBQUMsc0JBQXNCLENBQUM7SUFDL0M2QixLQUFLLENBQUNELEtBQUssR0FBRyxDQUFDNUQsQ0FBQyxHQUFDLENBQUMsSUFBRSxFQUFFO0VBQ3hCLENBQUMsQ0FBQztBQUNKO0FBQ0EsSUFBSThELE1BQU0sR0FBRyxTQUFBQSxDQUFTQyxLQUFLLEVBQUM7RUFDMUJBLEtBQUssQ0FBQzlDLGNBQWMsQ0FBQyxDQUFDO0VBQ2xCOEMsS0FBSyxDQUFDQyxlQUFlLENBQUMsQ0FBQztFQUN2QixJQUFJSCxLQUFLLEdBQUcsSUFBSSxDQUFDOUIsVUFBVSxDQUFDQSxVQUFVLENBQUNDLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQztFQUM1RTZCLEtBQUssQ0FBQ0QsS0FBSyxHQUFHSyxRQUFRLENBQUNKLEtBQUssQ0FBQ0QsS0FBSyxDQUFDLEdBQUcsRUFBRTtFQUN4QyxJQUFJckIsVUFBVSxHQUFHLElBQUksQ0FBQ1IsVUFBVSxDQUFDQSxVQUFVLENBQUNBLFVBQVU7RUFDdERnQixZQUFZLENBQUNSLFVBQVUsQ0FBQztFQUN4Qk8sZUFBZSxDQUFDUCxVQUFVLENBQUM7QUFFakMsQ0FBQztBQUNELElBQUkyQixLQUFLLEdBQUcsU0FBQUEsQ0FBU0gsS0FBSyxFQUFDO0VBQ3pCQSxLQUFLLENBQUM5QyxjQUFjLENBQUMsQ0FBQztFQUNsQjhDLEtBQUssQ0FBQ0MsZUFBZSxDQUFDLENBQUM7RUFDdkIsSUFBSUgsS0FBSyxHQUFHLElBQUksQ0FBQzlCLFVBQVUsQ0FBQ0EsVUFBVSxDQUFDQyxhQUFhLENBQUMsc0JBQXNCLENBQUM7RUFDNUU2QixLQUFLLENBQUNELEtBQUssR0FBR0ssUUFBUSxDQUFDSixLQUFLLENBQUNELEtBQUssQ0FBQyxHQUFHLEVBQUU7RUFDeEMsSUFBSXJCLFVBQVUsR0FBRyxJQUFJLENBQUNSLFVBQVUsQ0FBQ0EsVUFBVSxDQUFDQSxVQUFVO0VBQ3REZ0IsWUFBWSxDQUFDUixVQUFVLENBQUM7RUFDeEJPLGVBQWUsQ0FBQ1AsVUFBVSxDQUFDO0FBQ2pDLENBQUM7QUFFRCxTQUFTUywwQkFBMEJBLENBQUEsRUFBRTtFQUNuQyxJQUFJbUIsU0FBUyxHQUFHckYsUUFBUSxDQUFDcUQsZ0JBQWdCLENBQUMsY0FBYyxDQUFDO0VBQ3pELElBQUlpQyxXQUFXLEdBQUd0RixRQUFRLENBQUNxRCxnQkFBZ0IsQ0FBQyxnQkFBZ0IsQ0FBQztFQUU3RCxLQUFLLElBQUluQyxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdtRSxTQUFTLENBQUM1QyxN
1QUFNLEVBQUV2QixDQUFDLEVBQUUsRUFBRTtJQUN6Q21FLFNBQVMsQ0FBQ25FLENBQUMsQ0FBQyxDQUFDcUUsbUJBQW1CLENBQUMsT0FBTyxFQUFFUCxNQUFNLENBQUM7RUFBQztFQUNwRCxLQUFLLElBQUk5RCxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdvRSxXQUFXLENBQUM3QyxNQUFNLEVBQUV2QixDQUFDLEVBQUUsRUFBRTtJQUMzQ29FLFdBQVcsQ0FBQ3BFLENBQUMsQ0FBQyxDQUFDcUUsbUJBQW1CLENBQUMsT0FBTyxFQUFFSCxLQUFLLENBQUM7RUFBQztFQUVyRCxLQUFLLElBQUlsRSxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdtRSxTQUFTLENBQUM1QyxNQUFNLEVBQUV2QixDQUFDLEVBQUUsRUFBRTtJQUN6Q21FLFNBQVMsQ0FBQ25FLENBQUMsQ0FBQyxDQUFDc0UsZ0JBQWdCLENBQUMsT0FBTyxFQUFFUixNQUFNLENBQUM7RUFDaEQ7RUFDQSxLQUFLLElBQUk5RCxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdvRSxXQUFXLENBQUM3QyxNQUFNLEVBQUV2QixDQUFDLEVBQUUsRUFBRTtJQUMzQ29FLFdBQVcsQ0FBQ3BFLENBQUMsQ0FBQyxDQUFDc0UsZ0JBQWdCLENBQUMsT0FBTyxFQUFFSixLQUFLLENBQUM7RUFDakQ7QUFDRjtBQUNBbEIsMEJBQTBCLENBQUMsQ0FBQztBQUM1Qm5FLENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNxQixFQUFFLENBQUMsT0FBTyxFQUFDLGtCQUFrQixFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUNyREEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ2dFLEtBQUssQ0FBQzNDLGFBQWEsQ0FBQztFQUNyQ25CLEtBQUssQ0FBQyxDQUFDO0VBQ1BDLFFBQVEsQ0FBQyxDQUFDO0VBQ1ZDLFdBQVcsQ0FBQyxDQUFDO0FBQ2YsQ0FBQyxDQUFDOztBQUVGO0FBQ0E5QixDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDcUIsRUFBRSxDQUFDLE9BQU8sRUFBQywwQkFBMEIsRUFBRSxVQUFTYSxDQUFDLEVBQUU7RUFDN0RBLENBQUMsQ0FBQ0MsY0FBYyxDQUFDLENBQUM7RUFDbEIsSUFBSUMsSUFBSSxHQUFHLElBQUlDLElBQUksQ0FBQyxDQUFDLENBQUNDLE9BQU8sQ0FBQyxDQUFDO0VBQy9CLElBQUlDLFFBQVEsR0FBR3hDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQ2dCLElBQUksQ0FBQyxVQUFVLENBQUM7RUFDdkMsSUFBSStCLGFBQWEsR0FBR1AsUUFBUSxDQUFDUSxPQUFPLENBQUMsUUFBUSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzNEVSxhQUFhLEdBQUdBLGFBQWEsQ0FBQ0MsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJWCxJQUFJLEdBQUcsQ0FBQztFQUMxRHJDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQzJGLE1BQU0sQ0FBQzVDLGFBQWEsQ0FBQztBQUMvQixDQUFDLENBQUM7QUFDRi9DLENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNxQixFQUFFLENBQUMsT0FBTyxFQUFDLG1CQUFtQixFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUN0REEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMkYsTUFBTSxDQUFDNUMsYUFBYSxDQUFDO0VBQzdCL0MsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDNEYsVUFBVSxDQUFDLENBQUM7RUFDN0JoRSxLQUFLLENBQUMsQ0FBQztFQUNQTSxvQ0FBb0MsQ0FBQyxDQUFDO0VBQ3RDaEIsNEJBQTRCLENBQUMsQ0FBQztBQUNoQyxDQUFDLENBQUM7QUFDRmxCLENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNxQixFQUFFLENBQUMsT0FBTyxFQUFDLHVCQUF1QixFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUMxREEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ2lFLE1BQU0sQ0FBQzVDLGFBQWEsQ0FBQztFQUN0Q25CLEtBQUssQ0FBQyxDQUFDO0FBQ1QsQ0FBQyxDQUFDO0FBQ0Y7QUFDQTVCLENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNxQixFQUFFLENBQUMsT0FBTyxFQUFDLDJCQUEyQixFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUM5REEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEO0VBQ0FyQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMyRixN
1QUFNLENBQUM1QyxhQUFhLENBQUM7RUFDN0IvQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUM0RixVQUFVLENBQUMsQ0FBQztFQUM3QmhFLEtBQUssQ0FBQyxDQUFDO0VBQ1BFLFdBQVcsQ0FBQyxDQUFDO0VBQ2JELFFBQVEsQ0FBQyxDQUFDO0FBQ1osQ0FBQyxDQUFDO0FBRUY3QixDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDcUIsRUFBRSxDQUFDLE9BQU8sRUFBQyxxQkFBcUIsRUFBRSxVQUFTYSxDQUFDLEVBQUU7RUFDeERBLENBQUMsQ0FBQ0MsY0FBYyxDQUFDLENBQUM7RUFDbEIsSUFBSUMsSUFBSSxHQUFHLElBQUlDLElBQUksQ0FBQyxDQUFDLENBQUNDLE9BQU8sQ0FBQyxDQUFDO0VBQy9CLElBQUlDLFFBQVEsR0FBR3hDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQ2dCLElBQUksQ0FBQyxVQUFVLENBQUM7RUFDdkMsSUFBSStCLGFBQWEsR0FBR1AsUUFBUSxDQUFDUSxPQUFPLENBQUMsUUFBUSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzNEVSxhQUFhLEdBQUdBLGFBQWEsQ0FBQ0MsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJWCxJQUFJLEdBQUcsQ0FBQztFQUMxRHJDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQzBCLE1BQU0sQ0FBQyxDQUFDLENBQUNpRSxNQUFNLENBQUM1QyxhQUFhLENBQUM7RUFDdENmLDhCQUE4QixDQUFDLENBQUM7RUFDaENFLG9DQUFvQyxDQUFDLENBQUM7QUFDeEMsQ0FBQyxDQUFDO0FBQ0ZsQyxDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDcUIsRUFBRSxDQUFDLE9BQU8sRUFBQyxlQUFlLEVBQUUsVUFBU2EsQ0FBQyxFQUFFO0VBQ2xEQSxDQUFDLENBQUNDLGNBQWMsQ0FBQyxDQUFDO0VBQ2xCLElBQUlDLElBQUksR0FBRyxJQUFJQyxJQUFJLENBQUMsQ0FBQyxDQUFDQyxPQUFPLENBQUMsQ0FBQztFQUMvQixJQUFJQyxRQUFRLEdBQUd4QyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUNnQixJQUFJLENBQUMsVUFBVSxDQUFDO0VBQ3ZDLElBQUkrQixhQUFhLEdBQUdQLFFBQVEsQ0FBQ1EsT0FBTyxDQUFDLFFBQVEsRUFBRSxJQUFJWCxJQUFJLEdBQUcsQ0FBQztFQUMzRFUsYUFBYSxHQUFHQSxhQUFhLENBQUNDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDMURyQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMwQixNQUFNLENBQUMsQ0FBQyxDQUFDaUUsTUFBTSxDQUFDNUMsYUFBYSxDQUFDO0FBQ3hDLENBQUMsQ0FBQztBQUNGL0MsQ0FBQyxDQUFDQyxRQUFRLENBQUMsQ0FBQ3FCLEVBQUUsQ0FBQyxPQUFPLEVBQUMsZUFBZSxFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUNsREEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ2lFLE1BQU0sQ0FBQzVDLGFBQWEsQ0FBQztBQUN4QyxDQUFDLENBQUM7QUFDRi9DLENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNxQixFQUFFLENBQUMsT0FBTyxFQUFDLHFCQUFxQixFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUN4REEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ2lFLE1BQU0sQ0FBQzVDLGFBQWEsQ0FBQztFQUN0QzhDLE1BQU0sQ0FBQyxDQUFDO0VBQ1JDLGNBQWMsQ0FBQyxDQUFDO0FBQ2xCLENBQUMsQ0FBQztBQUNGOUYsQ0FBQyxDQUFDQyxRQUFRLENBQUMsQ0FBQ3FCLEVBQUUsQ0FBQyxPQUFPLEVBQUMsc0JBQXNCLEVBQUUsVUFBU2EsQ0FBQyxFQUFFO0VBQ3pELElBQUk0RCxhQUFhLEdBQUcvRixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM2QyxJQUFJLENBQUMsaUJBQWlCLENBQUM7RUFDbkRWLENBQUMsQ0FBQ0MsY0FBYyxDQUFDLENBQUM7RUFDbEIsSUFBSUMsSUFBSSxHQUFHLElBQUlDLElBQUksQ0FBQyxDQUFDLENBQUNDLE9BQU8sQ0FBQyxDQUFDO0VBQy9CLElBQUlDLFFBQVEsR0FBR3hDLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN4RCxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLHFCQUFxQixDQUFDLENBQUMwQixNQUFNLENBQUMsQ0FBQyxDQUFDaUUsTUFBTSxDQUFDNUMsYUFBYSxDQUFDO0VBQ3ZEL0MsQ0FBQyxDQUFDLDJCQUEyQixDQUFDLENBQUMyQixHQUFHLENBQUNvRSxhQUFhLENBQUM7RUFDakRGLE1BQU0sQ0FBQyxDQUFDO0VBQ1JDLGNBQWMsQ0FBQyxDQUFDO0FBQ2xCLENBQUMsQ0FBQztBQUNGOUYsQ0FBQyxDQUFDQyxRQUFRLENBQUMsQ0FBQ3FCLEVBQUUsQ0FBQyxPQUFPLEVBQUMsZUFBZSxFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUNsREEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ2lFLE1BQU0sQ0FBQzVDLGFBQWEsQ0FBQztFQUN4Qy9DLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQzRGLFVBQVUsQ0FBQyxDQUFDO0FBQzdCLENBQUMsQ0FBQztBQUNGLFNBQVNDLE1BQU1BLENBQUEsRUFBRTtFQUNmLElBQUk3RixDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQzBDLE1BQU0sRUFBRTtJQUNsQyxJQUFJc0QsS0FBSyxHQUFHaEcsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLENBQUM2QyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQ3REN0MsQ0FBQyxDQUFDLDhDQUE4QyxDQUFDLENBQUNHLElBQUksQ0FBQyxZQUFVO01BQy9ESCxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMyQixHQUFHLENBQUNxRSxLQUFLLENBQUM7SUFDcEIsQ0FBQyxDQUFDO0VBQ0o7QUFDRjtBQUNBaEcsQ0FBQyxDQUFDQyxRQUFRLENBQUMsQ0FBQ3FCLEVBQUUsQ0FBQyxPQUFPLEVBQUMsaUJBQWlCLEVBQUUsVUFBU2EsQ0FBQyxFQUFFO0VBQ3BEQSxDQUFDLENBQUNDLGNBQWMsQ0FBQyxDQUFDO0VBQ2xCcEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ0EsTUFBTSxDQUFDLENBQUMsQ0FBQ3VFLE1BQU0sQ0FBQyxDQUFDO0FBQ3BDLENBQUMsQ0FBQztBQUNGakcsQ0FBQyxDQUFDQyxRQUFRLENBQUMsQ0FBQ3FCLEVBQUUsQ0FBQyxPQUFPLEVBQUMsb0JBQW9CLEVBQUUsVUFBU2EsQ0FBQyxFQUFFO0VBQ3ZEbkMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDaUcsTUFBTSxDQUFDLENBQUM7QUFDcEIsQ0FBQyxDQUFDO0FBRUYsU0FBU0MsWUFBWUEsQ0FBQ0MsR0FBRyxFQUFHO0VBQzFCLElBQUcsQ0FBQ0MsTUFBTSxDQUFDQyxVQUFVLEVBQUMsQ0FDdEIsQ0FBQyxNQUFNO0lBQ0wsSUFBSUMsTUFBTSxHQUFHLElBQUlELFVBQVUsQ0FBQyxDQUFDO0lBQzdCLElBQUlFLE1BQU0sR0FBRyxJQUFJO0lBQ2pCRCxNQUFNLENBQUNFLE1BQU0sR0FBRyxVQUFTckUsQ0FBQyxFQUFFO01BQzFCb0UsTUFBTSxHQUFJcEUsQ0FBQyxDQUFDb0UsTUFBTSxJQUFJcEUsQ0FBQyxDQUFDc0UsVUFBVTtNQUNsQ3pHLENBQUMsQ0FBQ21HLEdBQUcsQ0FBQyxDQUFDekUsTUFBTSxDQUFDLENBQUMsQ0FBQ0EsTUFBTSxDQUFDLENBQUMsQ0FBQ0YsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDa0YsSUFBSSxDQUFDLEtBQUssRUFBRUgsTUFBTSxDQUFDSSxNQUFNLENBQUM7T
1UFDcEUzRyxDQUFDLENBQUNtRyxHQUFHLENBQUMsQ0FBQ3pFLE1BQU0sQ0FBQyxDQUFDLENBQUNBLE1BQU0sQ0FBQyxDQUFDLENBQUNGLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQ29GLFdBQVcsQ0FBQyxRQUFRLENBQUM7SUFDakUsQ0FBQztJQUNETixNQUFNLENBQUNPLGFBQWEsQ0FBQ1YsR0FBRyxDQUFDVyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7RUFDcEM7QUFDRjtBQUFDO0FBQ0Q5RyxDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDcUIsRUFBRSxDQUFDLFFBQVEsRUFBQyxlQUFlLEVBQUUsWUFBVztFQUFDNEUsWUFBWSxDQUFDLElBQUksQ0FBQztBQUFDLENBQUMsQ0FBQzs7QUFFMUU7QUFDQWxHLENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNDLEtBQUssQ0FBQyxZQUFVO0VBQzFCLElBQUksT0FBUUYsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDNEYsVUFBVSxLQUFLLFVBQVUsRUFBRTtJQUN4RDVGLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQzRGLFVBQVUsQ0FBQztNQUMxQm1CLGFBQWEsRUFBRSxLQUFLO01BQ3BCQyxJQUFJLEVBQUUsT0FBTztNQUNiQyxNQUFNLEVBQUUsR0FBRztNQUNYQyxXQUFXLEVBQUUsSUFBSTtNQUNqQkMsT0FBTyxFQUFFLENBQ1AsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxFQUNuRCxDQUFDLE1BQU0sRUFBRSxDQUFDLGVBQWUsRUFBRSxhQUFhLEVBQUUsV0FBVyxDQUFDLENBQUMsRUFDdkQsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDLEVBQ25DLENBQUMsTUFBTSxFQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsRUFDbEIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxTQUFTLEVBQUMsT0FBTyxFQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQyxFQUNoRCxDQUFDLE9BQU8sRUFBRSxDQUFDLFVBQVUsRUFBQyxNQUFNLEVBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDLEVBQ2pELENBQUMsTUFBTSxFQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsRUFDckIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUN6QjtNQUNEQyxPQUFPLEVBQUU7UUFDUEMsS0FBSyxFQUFFLENBQ0wsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxpQkFBaUIsRUFBQyxXQUFXLENBQUMsQ0FBQyxFQUMzQyxDQUFDLFdBQVcsRUFBRSxDQUFDLGNBQWMsRUFBRSxhQUFhLEVBQUUsYUFBYSxDQUFDLENBQUMsRUFDN0QsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxXQUFXLEVBQUUsWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUFDLEVBQ25ELENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUM7TUFFL0IsQ0FBQztNQUNEQyxlQUFlLEVBQUM7UUFDZEMsaUJBQWlCLEVBQUMsU0FBUztRQUFFO1FBQzdCQyxJQUFJLEVBQUMsK0JBQStCO1FBQ3BDQyxXQUFXLEVBQUMsS0FBSyxDQUFDO01BQ3BCLENBQUM7TUFDREMsYUFBYSxFQUFDO1FBQ1pDLFVBQVUsRUFBQyxJQUFJO1FBQUc7UUFDbEJDLFVBQVUsRUFBQyxJQUFJO1FBQUU7UUFDakJDLFNBQVMsRUFBQyxJQUFJO1FBQUk7UUFDbEJDLFNBQVMsRUFBQyxLQUFLLENBQUc7TUFDcEIsQ0FBQztNQUNEQyxTQUFTLEVBQUM7UUFDUlAsSUFBSSxFQUFDLGdDQUFnQztRQUFFO1FBQ3ZDUSxXQUFXLEVBQUMsZ0JBQWdCO1FBQzVCQyxlQUFlLEVBQUM7TUFDbEIsQ0FBQztNQUNEQyxPQUFPLEVBQUM7UUFDTkMsT0FBTyxFQUFFLEdBQUc7UUFBRTtRQUNkQyxNQUFNLEVBQUUsTUFBTTtRQUFFO1FBQ2hCQyxPQUFPLEVBQUUsTUFBTTtRQUFFO1FBQ2pCQyxRQUFRLEVBQUUsd0NBQXdDO1FBQUU7UUFDcERkLElBQUksRUFBRSw4QkFBOEI7UUFDcENlLFFBQVEsRUFBRSxJQUFJO1FBQUU7UUFDaEJDLFdBQVcsRUFBRSxLQUFLO1FBQUU7UUFDcEJDLFlBQVksRUFBRSxDQUFDLE1BQU0sRUFBQyxLQUFLLEVBQUMsS0FBSyxDQUFDO1FBQUU7UUFDcENDLE9BQU8sRUFBRSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQztRQUFFO1FBQ2pGQyxhQUFhLEVBQUUsQ0FBQyxLQUFLLEVBQUMsSUFBSSxFQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUMsTUFBTSxFQUFDLE9BQU8sRUFBQyxPQUFPLEVBQUMsY0FBYyxDQUFDLENBQUM7TUFDckYsQ0FBQztNQUNEbkcsUUFBUSxFQUFFO1FBQ1JvRyxJQUFJLEVBQUUscUJBQXFCO1FBQzNCQyxJQUFJLEVBQUU7VUFDSixtQkFBbUIsRUFBRSxtQkFBbUI7VUFDeEMsZUFBZSxFQUFFLGtCQUFrQjtVQUNuQyxjQUFjLEVBQUUsb0JBQW9CO1VBQ3BDLFVBQVUsRUFBRTtRQUNkO01BQ0Y7SUFDRixDQUFDLENBQUM7RUFDRjtBQUNGLENBQUMsQ0FBQztBQUNGOztBQUVBO0FBQUMsQ0FBQyxVQUFVN0ksQ0FBQyxFQUFFb0csTUFBTSxFQUFFbkcsUUFBUSxFQUFFNkksU0FBUyxFQUN4QztFQUNFOUksQ0FBQyxDQUFDK0ksRUFBRSxDQUFDQyxhQUFhLEdBQUcsVUFBVXBJLE1BQU0sRUFDckM7SUFDRSxJQUFJLEVBQUcsY0FBYyxJQUFJd0YsTUFBTSxDQUFFLElBQy9CLENBQUM2QyxTQUFTLENBQUNDLGdCQUFnQixJQUN6QixDQUFDRCxTQUFTLENBQUNFLFNBQVMsQ0FBQ0MsV0FBVyxDQUFDLENBQUMsQ0FBQ0MsS0FBSyxDQUFFLHFCQUFzQixDQUFDLEVBQUcsT0FBTyxLQUFLO0lBRXBGLElBQUksQ0FBQ2xKLElBQUksQ0FBRSxZQUNUO01BQ0UsSUFBSW1KLE9BQU8sR0FBRyxLQUFLO01BRW5CdEosQ0FBQyxDQUFFLElBQUssQ0FBQyxDQUFDc0IsRUFBRSxDQUFFLE9BQU8sRUFBRSxVQUFVYSxDQUFDLEVBQ2hDO1FBQ0UsSUFBSW9ILElBQUksR0FBR3ZKLENBQUMsQ0FBRSxJQUFLLENBQUM7UUFDcEIsSUFBSXVKLElBQUksQ0FBRSxDQUFDLENBQUUsSUFBSUQsT0FBTyxDQUFFLENBQUMsQ0FBRSxFQUM3QjtVQUNFbkgsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztVQUNsQmtILE9BQU8sR0FBR0MsSUFBSTtRQUNoQjtNQUNGLENBQUMsQ0FBQztNQUVKdkosQ0FBQyxDQUFFQyxRQUFTLENBQUMsQ0FBQ3FCLEVBQUUsQ0FBRSxnQ0FBZ0MsRUFBRSxVQUFVYSxDQUFDLEVBQzdEO1FBQ0UsSUFBSXFILFNBQVMsR0FBRyxJQUFJO1VBQ2xCQyxPQUFPLEdBQUt6SixDQUFDLENBQUVtQyxDQUFDLENBQUNvRSxNQUFPLENBQUMsQ0FBQ2tELE9BQU8sQ0FBQyxDQUFDO1F
1BRXJDLEtBQUssSUFBSXRJLENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBR3NJLE9BQU8sQ0FBQy9HLE1BQU0sRUFBRXZCLENBQUMsRUFBRSxFQUNyQyxJQUFJc0ksT0FBTyxDQUFFdEksQ0FBQyxDQUFFLElBQUltSSxPQUFPLENBQUUsQ0FBQyxDQUFFLEVBQ2hDRSxTQUFTLEdBQUcsS0FBSztRQUVuQixJQUFJQSxTQUFTLEVBQ1hGLE9BQU8sR0FBRyxLQUFLO01BQ25CLENBQUMsQ0FBQztJQUNOLENBQUMsQ0FBQztJQUNKLE9BQU8sSUFBSTtFQUNiLENBQUM7QUFDSCxDQUFDLEVBQUdJLE1BQU0sRUFBRXRELE1BQU0sRUFBRW5HLFFBQVMsQ0FBQztBQUNoQ0QsQ0FBQyxDQUFFLHdCQUF5QixDQUFDLENBQUNnSixhQUFhLENBQUMsQ0FBQztBQUU3Q2hKLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQzJKLEtBQUssQ0FBQyxZQUFVO0VBQ3pCM0osQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDd0IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDb0ksS0FBSyxDQUFDLENBQUM7QUFDekMsQ0FBQyxDQUFDO0FBRUY1SixDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDQyxLQUFLLENBQUMsWUFBVztFQUMzQkYsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUNHLElBQUksQ0FDdkIsWUFBVTtJQUNSLElBQUlRLEdBQUcsR0FBR1gsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDNkMsSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUNuQyxJQUFJZ0gsS0FBSyxHQUFHN0osQ0FBQyxDQUFDLDRCQUE0QixDQUFDLENBQUMwQyxNQUFNLEdBQUUsQ0FBQztJQUNyRDFDLENBQUMsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDRyxJQUFJLENBQ2xDLFVBQVNnQixDQUFDLEVBQUM7TUFDVG5CLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQzZDLElBQUksQ0FBQyxNQUFNLEVBQUM3QyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM2QyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUNHLE9BQU8sQ0FBQyxXQUFXLEVBQUNyQyxHQUFHLEdBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEUsQ0FDRixDQUFDO0lBQ0QsSUFBSWtKLEtBQUssR0FBQyxFQUFFLEVBQUM7TUFDWCxJQUFJQyxLQUFLLEdBQUc5SixDQUFDLENBQUMsNEJBQTRCLENBQUMsQ0FDeEM4SixLQUFLLENBQUM5SixDQUFDLENBQUMsbUNBQW1DLENBQUMsQ0FBQztNQUNoRCxJQUFJK0osS0FBSyxHQUFHQyxJQUFJLENBQUNDLEtBQUssQ0FBQ0osS0FBSyxHQUFHLENBQUMsQ0FBQztNQUNqQyxJQUFJSyxFQUFFLEdBQUdGLElBQUksQ0FBQ0MsS0FBSyxDQUFDSixLQUFLLEdBQUcsQ0FBQyxDQUFDO01BQzlCLElBQUlNLEVBQUUsR0FBR0gsSUFBSSxDQUFDQyxLQUFLLENBQUNKLEtBQUssR0FBRyxDQUFDLEdBQUMsQ0FBQyxDQUFDO01BQ2hDLElBQUlPLEVBQUUsR0FBR04sS0FBSyxHQUFHLENBQUM7TUFDbEIsSUFBSU8sRUFBRSxHQUFHUCxLQUFLLEdBQUcsQ0FBQztNQUNsQixJQUFJUSxLQUFLLEdBQUcsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDVCxLQUFLLEdBQUMsQ0FBQyxFQUFDSyxFQUFFLEVBQUNILEtBQUssRUFBQ0ksRUFBRSxFQUFDQyxFQUFFLEVBQUNOLEtBQUssRUFBQ08sRUFBRSxFQUFDUixLQUFLLENBQUM7TUFDdkQ3SixDQUFDLENBQUMsNEJBQTRCLENBQUMsQ0FBQ0csSUFBSSxDQUNsQyxVQUFTZ0IsQ0FBQyxFQUFDO1FBQ1QsSUFBR25CLENBQUMsQ0FBQ3VLLE9BQU8sQ0FBQ3BKLENBQUMsRUFBQ21KLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFDO1VBQzVCdEssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDaUcsTUFBTSxDQUFDLENBQUM7UUFDaEI7TUFDRixDQUNGLENBQUM7SUFDSDtFQUNGLENBQ0YsQ0FBQztBQUNILENBQUMsQ0FBQztBQUNGLFNBQVN1RSxrQkFBa0JBLENBQUN4SixJQUFJLEVBQUU7RUFDaEMsSUFBSXlKLEdBQUcsR0FBRyxJQUFJQyxjQUFjLENBQUMsQ0FBQztFQUM5QixJQUFJQyxFQUFFLEdBQUksSUFBSUMsUUFBUSxDQUFDM0ssUUFBUSxDQUFDNEssY0FBYyxDQUFDLG9CQUFvQixDQUFDLENBQUM7RUFDckUsSUFBSUMsSUFBSSxHQUFHN0ssUUFBUSxDQUFDa0QsYUFBYSxDQUFDLHVCQUF1QixDQUFDLENBQUM0SCxPQUFPO0VBQ2xFOztFQUVBLEtBQUlDLElBQUksSUFBSWhLLElBQUksRUFBRTtJQUNoQjJKLEVBQUUsQ0FBQ00sTUFBTSxDQUFDRCxJQUFJLEVBQUVoSyxJQUFJLENBQUNnSyxJQUFJLENBQUMsQ0FBQztFQUM3QjtFQUVBUCxHQUFHLENBQUNoRixnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsVUFBU1AsS0FBSyxFQUFFO0lBQzNDZ0csS0FBSyxDQUFDLHNDQUFzQyxDQUFDO0VBQy9DLENBQUMsQ0FBQztFQUNGVCxHQUFHLENBQUNoRixnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsVUFBU1AsS0FBSyxFQUFFO0lBQzVDZ0csS0FBSyxDQUFDLDZCQUE2QixDQUFDO0VBQ3RDLENBQUMsQ0FBQzs7RUFFRjtFQUNBVCxHQUFHLENBQUNVLElBQUksQ0FBRSxNQUFNLEVBQUUsd0JBQXlCLENBQUM7RUFDNUNWLEdBQUcsQ0FBQ1csZ0JBQWdCLENBQUUsY0FBYyxFQUFFLG1DQUFvQyxDQUFDO0VBQzNFWCxHQUFHLENBQUNXLGdCQUFnQixDQUFFLGNBQWMsRUFBRU4sSUFBSSxDQUFDO0VBQzNDTCxHQUFHLENBQUNZLElBQUksQ0FBQ1YsRUFBRSxDQUFDO0VBQ1o7QUFDRjtBQUNBLFNBQVM3RSxjQUFjQSxDQUFBLEVBQUU7RUFDdkIsSUFBSWdGLElBQUksR0FBRzdLLFF
1BQVEsQ0FBQ2tELGFBQWEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDNEgsT0FBTztFQUNwRSxJQUFJTyxNQUFNLEdBQUdyTCxRQUFRLENBQUNxRCxnQkFBZ0IsQ0FBQywyQkFBMkIsQ0FBQztFQUNuRSxLQUFLLElBQUluQyxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdtSyxNQUFNLENBQUM1SSxNQUFNLEVBQUUsRUFBRXZCLENBQUMsRUFBRTtJQUN0Q21LLE1BQU0sQ0FBQ25LLENBQUMsQ0FBQyxDQUFDNEQsS0FBSyxHQUFHK0YsSUFBSTtFQUN4QjtBQUNGO0FBQ0E5SyxDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDQyxLQUFLLENBQUMsWUFBVztFQUMzQjRGLGNBQWMsQ0FBQyxDQUFDO0FBQ2xCLENBQUMsQ0FBQztBQUNGOUYsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLENBQUNzQixFQUFFLENBQUMsZUFBZSxFQUFFLFVBQVU0RCxLQUFLLEVBQUU7RUFDM0QsSUFBSXFHLE1BQU0sR0FBR3ZMLENBQUMsQ0FBQ2tGLEtBQUssQ0FBQ3NHLGFBQWEsQ0FBQztFQUNuQyxJQUFJN0ssR0FBRyxHQUFHNEssTUFBTSxDQUFDdkssSUFBSSxDQUFDLEtBQUssQ0FBQztFQUM1QixJQUFJeUssS0FBSyxHQUFHekwsQ0FBQyxDQUFDLElBQUksQ0FBQztFQUNuQixJQUFJMEwsQ0FBQyxHQUFHRCxLQUFLLENBQUNqSyxJQUFJLENBQUMsa0JBQWtCLENBQUM7RUFDdENpSyxLQUFLLENBQUNqSyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQ3FCLElBQUksQ0FBQyxNQUFNLEVBQUUsV0FBVyxHQUFDbEMsR0FBRyxDQUFDO0FBQzlELENBQUMsQ0FBQyIsImlnbm9yZUxpc3QiOltdfQ==\n//# sourceURL=webpack-internal:///587\n")},70:(__unused_webpack_module,__unused_webpack_exports,__webpack_require__)=>{eval("/**\n * jQuery Slugger\n *\n * This project is used to be called jQuery Slugify until I discovered slugify is already taken in `npm`.\n *\n * v1.0.4\n *\n * @author  John Lioneil Dionisio\n *\n * @param  {Object} $\n * @param  {Object} document\n * @return\n */\n(function ($, document) {\n  'use strict';\n\n  var slugify = __webpack_require__(304);\n  var slugSeparator = 'slug-separator';\n  var Slugify = {\n    init: function (options, elem) {\n      var self = this;\n      self.elem = elem;\n      self.$elem = $(elem);\n      self.options = $.extend({}, $.fn.slugger.options, options);\n      self.sluggerElement = undefined == self.$elem.data('slugger') ? self.elem : self.$elem.data('slugger');\n      self.options.target = \"\" == self.$elem.data('slugger') || undefined == self.$elem.data('slugger') ? self.options.target : self.$elem.data('slugger');\n      self.options.separator = undefined == self.$elem.data(slugSeparator) ? self.options.separator : self.$elem.data(slugSeparator);\n      self.$elem.on(self.options.bindToEvent, function (e) {\n        var $string = $(this).val();\n        $string = self.convert($string, self);\n        $(self.options.target).val($string);\n        if (self.options.debug) self.debug($string);\n      });\n      return true;\n    },\n    convert: function ($string, self) {\n      self.options.beforeConvert(self);\n      if (self.options.convertToLowerCase) {\n        $string = $string.toLowerCase();\n      }\n      if (self.options.separator !== \" \") {\n        $string = $string.replace(/ /g, this.options.separator);\n      }\n      if (!self.options.isUrlFriendly) {\n        $string = $string.replace(/[^\\w-]+/g, '');\n      }\n      $string = slugify($string);\n      self.options.afterConvert(self);\n      return $string;\n    },\n    destroy: function () {\n      this.destroy();\n      this.element.unbind(this.eventNamespace);\n      this.bindings.unbind(this.eventNamespace);\n    },\n    debug: function ($string) {\n      console.log($string);\n    }\n  };\n  $.fn.slugger = function (options, elem) {\n    var slugger = Object.create(Slugify);\n    return this.each(function () {\n      slugger.init(options, this);\n    });\n  };\n  $.fn.slugger.options = {\n    bindToEvent: 'keypress keyup',\n    target: '[name=slug]',\n    separator: '-',\n    convertToLowerCase: true,\n    isUrlFriendly: true,\n    beforeConvert: function (self) {},\n    afterConvert: function (self) {},\n    debug: false\n  };\n  jQuery('[data-slugger]').slugger();\n})(jQuery, document);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzAuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi92ZW5kb3IvanF1ZXJ5LnNsdWdnZXIuanM/MjRhZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGpRdWVyeSBTbHVnZ2VyXG4gKlxuICogVGhpcyBwcm9qZWN0IGlzIHVzZWQgdG8gYmUgY2FsbGVkIGpRdWVyeSBTbHVnaWZ5IHVudGlsIEkgZGlzY292ZXJlZCBzbHVnaWZ5IGlzIGFscmVhZHkgdGFrZW4gaW4gYG5wbWAuXG4gKlxuICogdjEuMC40XG4gKlxuICogQGF1dGhvciAgSm9obiBMaW9uZWlsIERpb25pc2lvXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSAkXG4gKiBAcGFyYW0gIHtPYmplY3R9IGRvY3VtZW50XG4gKiBAcmV0dXJuXG4gKi9cbihmdW5jdGlvbiAoJCwgZG9jdW1lbnQpIHtcblxuICAgICd1c2Ugc3RyaWN0JztcblxuICB2Y
1XIgc2x1Z2lmeSA9IHJlcXVpcmUoJ3NsdWdpZnknKVxuICAgIHZhciBzbHVnU2VwYXJhdG9yID0gJ3NsdWctc2VwYXJhdG9yJztcblxuXHR2YXIgU2x1Z2lmeSA9IHtcbiAgICAgICAgaW5pdDogZnVuY3Rpb24gKG9wdGlvbnMsIGVsZW0pIHtcbiAgICAgICAgXHR2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgICBzZWxmLmVsZW0gPSBlbGVtO1xuICAgICAgICAgICAgc2VsZi4kZWxlbSA9ICQoZWxlbSk7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMgPSAkLmV4dGVuZCgge30sICQuZm4uc2x1Z2dlci5vcHRpb25zLCBvcHRpb25zICk7XG4gICAgICAgICAgICBzZWxmLnNsdWdnZXJFbGVtZW50ID0gdW5kZWZpbmVkID09IHNlbGYuJGVsZW0uZGF0YSgnc2x1Z2dlcicpID8gc2VsZi5lbGVtIDogc2VsZi4kZWxlbS5kYXRhKCdzbHVnZ2VyJyk7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMudGFyZ2V0ID0gXCJcIiA9PSBzZWxmLiRlbGVtLmRhdGEoJ3NsdWdnZXInKSB8fCB1bmRlZmluZWQgPT0gc2VsZi4kZWxlbS5kYXRhKCdzbHVnZ2VyJykgPyBzZWxmLm9wdGlvbnMudGFyZ2V0IDogc2VsZi4kZWxlbS5kYXRhKCdzbHVnZ2VyJyk7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMuc2VwYXJhdG9yID0gdW5kZWZpbmVkID09IHNlbGYuJGVsZW0uZGF0YShzbHVnU2VwYXJhdG9yKSA/IHNlbGYub3B0aW9ucy5zZXBhcmF0b3IgOiBzZWxmLiRlbGVtLmRhdGEoc2x1Z1NlcGFyYXRvcik7XG5cbiAgICAgICAgICAgIHNlbGYuJGVsZW0ub24oc2VsZi5vcHRpb25zLmJpbmRUb0V2ZW50LCBmdW5jdGlvbiAoZSkge1xuXHQgICAgICAgICAgICB2Y
1XIgJHN0cmluZyA9ICQodGhpcykudmFsKCk7XG5cdCAgICAgICAgICAgICRzdHJpbmcgPSBzZWxmLmNvbnZlcnQoJHN0cmluZywgc2VsZik7XG5cdCAgICAgICAgICAgICQoc2VsZi5vcHRpb25zLnRhcmdldCkudmFsKCRzdHJpbmcpO1xuXG5cdCAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuZGVidWcpIHNlbGYuZGVidWcoJHN0cmluZyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICBcdHJldHVybiB0cnVlO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNvbnZlcnQ6IGZ1bmN0aW9uICgkc3RyaW5nLCBzZWxmKSB7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMuYmVmb3JlQ29udmVydChzZWxmKTtcblxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5jb252ZXJ0VG9Mb3dlckNhc2UpIHtcbiAgICAgICAgICAgICAgICAkc3RyaW5nID0gJHN0cmluZy50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnNlcGFyYXRvciAhPT0gXCIgXCIpIHtcbiAgICAgICAgICAgIFx0JHN0cmluZyA9ICRzdHJpbmcucmVwbGFjZSgvIC9nLCB0aGlzLm9wdGlvbnMuc2VwYXJhdG9yKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFzZWxmLm9wdGlvbnMuaXNVcmxGcmllbmRseSkge1xuICAgICAgICAgICAgICAgICRzdHJpbmcgPSAkc3RyaW5nLnJlcGxhY2UoL1teXFx3LV0rL2csICcnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICRzdHJpbmcgPSBzbHVnaWZ5KCRzdHJpbmcpO1xuICAgICAgICAgICAgc2VsZi5vcHRpb25zLmFmdGVyQ29udmVydChzZWxmKTtcblxuICAgICAgICAgICAgcmV0dXJuICRzdHJpbmc7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgICBcdHRoaXMuZGVzdHJveSgpO1xuICAgICAgICBcdHRoaXMuZWxlbWVudC51bmJpbmQoIHRoaXMuZXZlbnROYW1lc3BhY2UgKVxuXHRcdCAgICB0aGlzLmJpbmRpbmdzLnVuYmluZCggdGhpcy5ldmVudE5hbWVzcGFjZSApO1xuICAgICAgICB9LFxuXG4gICAgICAgIGRlYnVnOiBmdW5jdGlvbiAoJHN0cmluZykge1xuICAgICAgICBcdGNvbnNvbGUubG9nKCRzdHJpbmcpO1xuICAgICAgICB9LFxuICAgIH07XG5cbiAgICAkLmZuLnNsdWdnZXIgPSBmdW5jdGlvbiAob3B0aW9ucywgZWxlbSkge1xuICAgICAgICB2Y
1XIgc2x1Z2dlciA9IE9iamVjdC5jcmVhdGUoU2x1Z2lmeSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2x1Z2dlci5pbml0KG9wdGlvbnMsIHRoaXMpO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgJC5mbi5zbHVnZ2VyLm9wdGlvbnMgPSB7XG4gICAgICAgIGJpbmRUb0V2ZW50OiAna2V5cHJlc3Mga2V5dXAnLFxuICAgICAgICB0YXJnZXQ6ICdbbmFtZT1zbHVnXScsXG4gICAgICAgIHNlcGFyYXRvcjogJy0nLFxuXG4gICAgICAgIGNvbnZlcnRUb0xvd2VyQ2FzZTogdHJ1ZSxcbiAgICAgICAgaXNVcmxGcmllbmRseTogdHJ1ZSxcblxuICAgICAgICBiZWZvcmVDb252ZXJ0OiBmdW5jdGlvbiAoc2VsZikge30sXG4gICAgICAgIGFmdGVyQ29udmVydDogZnVuY3Rpb24gKHNlbGYpIHt9LFxuXG4gICAgICAgIGRlYnVnOiBmYWxzZSxcbiAgICB9O1xuICAgIGpRdWVyeSgnW2RhdGEtc2x1Z2dlcl0nKS5zbHVnZ2VyKCk7XG5cbn0pKGpRdWVyeSwgZG9jdW1lbnQpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///70\n")},156:function(module){eval("/**\n * @file postscribe\n * @description Asynchronously write javascript, even with document.write.\n * @version v2.0.6\n * @see {@link https://krux.github.io/postscribe}\n * @license MIT\n * @author Derek Brans\n * @copyright 2016 Krux Digital, Inc\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n  if (true) module.exports = factory();else {}\n})(this, function () {\n  return /******/function (modules) {\n    // webpackBootstrap\n    /******/ // The module cache\n    /******/\n    var installedModules = {};\n    /******/\n    /******/ // The require function\n    /******/\n    function __nested_webpack_require_811__(moduleId) {\n      /******/\n      /******/ // Check if module is in cache\n      /******/if (installedModules[moduleId]) /******/return installedModules[moduleId].exports;\n      /******/\n      /******/ // Create a new module (and put it into the cache)\n      /******/\n      var module = installedModules[moduleId] = {\n        /******/exports: {},\n        /******/id: moduleId,\n        /******/loaded: false\n        /******/\n      };\n      /******/\n      /******/ // Execute the module function\n      /******/\n      modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_811__);\n      /******/\n      /******/ // Flag the module as loaded\n      /******/\n      module.loaded = true;\n      /******/\n      /******/ // Return the exports of the module\n      /******/\n      return module.exports;\n      /******/\n    }\n    /******/\n    /******/\n    /******/ // expose the modules object (__webpack_modules__)\n    /******/\n    __nested_webpack_require_811__.m = modules;\n    /******/\n    /******/ // expose the module cache\n    /******/\n    __nested_webpack_require_811__.c = installedModules;\n    /******/\n    /******/ // __webpack_public_path__\n    /******/\n    __nested_webpack_require_811__.p = \"\";\n    /******/\n    /******/ // Load entry module and return exports\n    /******/\n    return __nested_webpack_require_811__(0);\n    /******/\n  }\n  /************************************************************************/\n  /******/([/* 0 */\n  /***/function (module, exports, __nested_webpack_require_2283__) {\n    'use strict';\n\n    var _postscribe = __nested_webpack_require_2283__(1);\n    var _postscribe2 = _interopRequireDefault(_postscribe);\n    function _interopRequireDefault(obj) {\n      return obj && obj.__esModule ? obj : {\n        'default': obj\n      };\n    }\n    module.exports = _postscribe2['default'];\n\n    /***/\n  }, /* 1 */\n  /***/function (module, exports, __nested_webpack_require_2661__) {\n    'use strict';\n\n    exports.__esModule = true;\n    var _extends = Object.assign || function (target) {\n      for (var i = 1; i < arguments.length;
1 i++) {\n        var source = arguments[i];\n        for (var key in source) {\n          if (Object.prototype.hasOwnProperty.call(source, key)) {\n            target[key] = source[key];\n          }\n        }\n      }\n      return target;\n    };\n    exports['default'] = postscribe;\n    var _writeStream = __nested_webpack_require_2661__(2);\n    var _writeStream2 = _interopRequireDefault(_writeStream);\n    var _utils = __nested_webpack_require_2661__(4);\n    var utils = _interopRequireWildcard(_utils);\n    function _interopRequireWildcard(obj) {\n      if (obj && obj.__esModule) {\n        return obj;\n      } else {\n        var newObj = {};\n        if (obj != null) {\n          for (var key in obj) {\n            if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];\n          }\n        }\n        newObj['default'] = obj;\n        return newObj;\n      }\n    }\n    function _interopRequireDefault(obj) {\n      return obj && obj.__esModule ? obj : {\n        'default': obj\n      };\n    }\n\n    /**\n     * A function that intentionally does nothing.\n     */\n    function doNothing() {}\n\n    /**\n     * Available options and defaults.\n     *\n     * @type {Object}\n     */\n    var OPTIONS = {\n      /**\n       * Called when an async script has loaded.\n       */\n      afterAsync: doNothing,\n      /**\n       * Called immediately before removing from the write queue.\n       */\n      afterDequeue: doNothing,\n      /**\n       * Called sync after a stream's first thread release.\n       */\n      afterStreamStart: doNothing,\n      /**\n       * Called after writing buffered document.write calls.\n       */\n      afterWrite: doNothing,\n      /**\n       * Allows disabling the autoFix feature of prescribe\n       */\n      autoFix: true,\n      /**\n       * Called immediately before adding to the write queue.\n       */\n      beforeEnqueue: doNothing,\n      /**\n       * Called before writing a token.\n       *\n       * @param {Object} tok The token\n       */\n      beforeWriteToken: function beforeWriteToken(tok) {\n        return tok;\n      },\n      /**\n       * Called before writing buffered document.write calls.\n       *\n       * @param {String} str The string\n       */\n      beforeWrite: function beforeWrite(str) {\n        return str;\n      },\n      /**\n       * Called when evaluation is finished.\n       */\n      done: doNothing,\n      /**\n       * Called when a write results in an error.\n       *\n       * @param {Error} e The error\n       */\n      error: function error(e) {\n        throw e;\n      },\n      /**\n       * Whether to let scripts w/ async attribute set fall out of the queue.\n       */\n      releaseAsync: false\n    };\n    var nextId = 0;\n    var queue = [];\n    var active = null;\n    function nextStream() {\n      var args = queue.shift();\n      if (args) {\n        var options = utils.last(args);\n        options.afterDequeue();\n        args.stream = runStream.apply(undefined, args);\n        options.afterStreamStart();\n      }\n    }\n    function runStream(el, html, options) {\n      active = new\n      // Expose internal classes.\n      _writeStream2['default'](el, options);\n\n      // Identify this stream.\n      active.id = nextId++;\n      active.name = options.name || active.id;\n      postscribe.streams[active.name] = active;\n\n      // Override document.write.\n      var doc = el.ownerDocument;\n      var stash = {\n        close: doc.close,\n        open: doc.open,\n        write: doc.write,\n        writeln: doc.writeln\n      };\n      function _write(str) {\n        str = options.beforeWrite(str);\n        active.write(str);\n        options.afterWrite(str);\n      }\n      _extends(doc, {\n        close: doNothing,\n        open: doNothing,\n        write: function write() {\n          for (var _len = arguments.length, str = Array(_len), _key = 0; _key < _len; _key++) {\n            str[_key] = arguments[_key];\n          }\n          return _write(str.join(''));\n        },\n        writeln: function writeln() {\n          for (var _len2 = arguments.length, str = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n            str[_key2] = arguments[_key2];\n          }\n          return _write(str.join('') + '\\n');\n        }\n      });\n\n      // Override window.onerror\n      var oldOnError = active.win.onerror || doNothing;\n\n      // This works together with the try/catch around WriteStream::insertScript\n      // In modern browsers, exceptions in tag scripts go directly to top level\n      active.win.onerror = function (msg, url, line) {\n        options.error({\n          msg: msg + ' - ' + url + ': ' + line\n        });\n        oldOnError.apply(active.win, [msg, url, line]);\n      };\n\n      // Write to the stream\n      active.write(html, function () {\n        // restore document.write\n        _extends(doc, stash);\n\n        // restore window.onerror\n        active.win.onerror = oldOnError;\n        options.done();\n        active = null;\n        nextStream();\n      });\n      return active;\n    }\n    function postscribe(el, html, options) {\n      if (utils.isFunction(options)) {\n        options = {\n          done: options\n        };\n      } else if (options === 'clear') {\n        queue = [];\n        active = null;\n        nextId = 0;\n        return;\n      }\n      options = utils.defaults(options, OPTIONS);
1\n\n      // id selector\n      if (/^#/.test(el)) {\n        el = window.document.getElementById(el.substr(1));\n      } else {\n        el = el.jquery ? el[0] : el;\n      }\n      var args = [el, html, options];\n      el.postscribe = {\n        cancel: function cancel() {\n          if (args.stream) {\n            args.stream.abort();\n          } else {\n            args[1] = doNothing;\n          }\n        }\n      };\n      options.beforeEnqueue(args);\n      queue.push(args);\n      if (!active) {\n        nextStream();\n      }\n      return el.postscribe;\n    }\n    _extends(postscribe, {\n      // Streams by name.\n      streams: {},\n      // Queue of streams.\n      queue: queue,\n      WriteStream: _writeStream2['default']\n    });\n\n    /***/\n  }, /* 2 */\n  /***/function (module, exports, __nested_webpack_require_8857__) {\n    'use strict';\n\n    exports.__esModule = true;\n    var _extends = Object.assign || function (target) {\n      for (var i = 1; i < arguments.length; i++) {\n        var source = arguments[i];\n        for (var key in source) {\n          if (Object.prototype.hasOwnProperty.call(source, key)) {\n            target[key] = source[key];\n          }\n        }\n      }\n      return target;\n    };\n    var _prescribe = __nested_webpack_require_8857__(3);\n    var _prescribe2 = _interopRequireDefault(_prescribe);\n    var _utils = __nested_webpack_require_8857__(4);\n    var utils = _interopRequireWildcard(_utils);\n    function _interopRequireWildcard(obj) {\n      if (obj && obj.__esModule) {\n        return obj;\n      } else {\n        var newObj = {};\n        if (obj != null) {\n          for (var key in obj) {\n            if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];\n          }\n        }\n        newObj['default'] = obj;\n        return newObj;\n      }\n    }\n    function _interopRequireDefault(obj) {\n      return obj && obj.__esModule ? obj : {\n        'default': obj\n      };\n    }\n    function _classCallCheck(instance, Constructor) {\n      if (!(instance instanceof Constructor)) {\n        throw new TypeError(\"Cannot call a class as a function\");\n      }\n    }\n\n    /**\n     * Turn on to debug how each chunk affected the DOM.\n     * @type {boolean}\n     */\n    var DEBUG_CHUNK = false;\n\n    /**\n     * Prefix for data attributes on DOM elements.\n     * @type {string}
1\n     */\n    var BASEATTR = 'data-ps-';\n\n    /**\n     * ID for the style proxy\n     * @type {string}\n     */\n    var PROXY_STYLE = 'ps-style';\n\n    /**\n     * ID for the script proxy\n     * @type {string}\n     */\n    var PROXY_SCRIPT = 'ps-script';\n\n    /**\n     * Get data attributes\n     *\n     * @param {Object} el The DOM element.\n     * @param {String} name The attribute name.\n     * @returns {String}\n     */\n    function getData(el, name) {\n      var attr = BASEATTR + name;\n      var val = el.getAttribute(attr);\n\n      // IE 8 returns a number if it's a number\n      return !utils.existy(val) ? val : String(val);\n    }\n\n    /**\n     * Set data attributes\n     *\n     * @param {Object} el The DOM element.\n     * @param {String} name The attribute name.\n     * @param {null|*} value The attribute value.\n     */\n    function setData(el, name) {\n      var value = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n      var attr = BASEATTR + name;\n      if (utils.existy(value) && value !== '') {\n        el.setAttribute(attr, value);\n      } else {\n        el.removeAttribute(attr);\n      }\n    }\n\n    /**\n     * Stream static html to an element, where \"static html\" denotes \"html\n     * without scripts\".\n     *\n     * This class maintains a *history of writes devoid of any attributes* or\n     * \"proxy history\".\n     *\n     * Injecting the proxy history into a temporary div has no side-effects,\n     * other than to create proxy elements for previously written elements.\n     *\n     * Given the `staticHtml` of a new write, a `tempDiv`'s innerHTML is set to\n     * `proxy_history + staticHtml`.\n     * The *structure* of `tempDiv`'s contents, (i.e., the placement of new nodes\n     * beside or inside of proxy elements), reflects the DOM structure that would\n     * have resulted if all writes had been squashed into a single write.\n     *\n     * For each descendent `node` of `tempDiv` whose parentNode is a *proxy*,\n     * `node` is appended to the corresponding *real* element within the DOM.\n     *\n     * Proxy elements are mapped to *actual* elements in the DOM by injecting a\n     * `data-id` attribute into each start tag in `staticHtml`.\n     *\n     */\n\n    var WriteStream = function () {\n      /**\n       * Constructor.\n       *\n       * @param {Object} root The root element\n       * @param {?Object} options The options\n       */\n\n      function WriteStream(root) {\n        var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n        _classCallCheck(this, WriteStream);\n        this.root = root;\n        this.options = options;\n        this.doc = root.ownerDocument;\n        this.win = this.doc.defaultView || this.doc.parentWindow;\n        this.parser = new _prescribe2['default']('', {\n          autoFix: options.autoFix\n        });\n\n        // Actual elements by id.\n        this.actuals = [root];\n\n        // Embodies the \"structure\" of what's been written so far,\n        // devoid of attributes.\n        this.proxyHistory = '';\n\n        // Create a proxy of the root element.\n        this.proxyRoot = this.doc.createElement(root.nodeName);\n        this.scriptStack = [];\n        this.writeQueue = [];\n        setData(this.proxyRoot, 'proxyof', 0);\n      }\n\n      /**\n       * Writes the given strings.\n       *\n       * @param {...String} str The strings to write\n       */\n\n      WriteStream.prototype.write = function write() {\n        var _writeQueue;\n        (_writeQueue = this.writeQueue).push.apply(_writeQueue, arguments);\n\n        // Process writes\n        // When new script gets pushed or pending this will stop\n        // because new writeQueue gets pushed\n        while (!this.deferredRemote && this.writeQueue.length) {\n          var arg = this.writeQueue.shift();\n          if (utils.isFunction(arg)) {\n            this._callFunction(arg);\n          } else {\n            this._writeImpl(arg);\n          }\n        }\n      };\n\n      /**\n       * Calls the given function.\n       *\n       * @param {Function} fn The function to call\n       * @private\n       */\n\n      WriteStream.prototype._callFunction = function _callFunction(fn) {\n        var tok = {\n          type: 'function',\n          value: fn.name || fn.toString()\n        };\n        this._onScriptStart(tok);\n        fn.call(this.win, this.doc);\n        this._onScriptDone(tok);\n      };\n\n      /**\n       * The write implementation\n       *\n       * @param {String} html The HTML to write.\n       * @private\n       */\n\n      WriteStream.prototype._writeImpl = function _writeImpl(html) {\n        this.parser.append(html);\n        var tok = void 0;\n        var script = void 0;\n        var style = void 0;\n        var tokens = [];\n\n        // stop if we see a script token\n        while ((tok = this.parser.readToken()) && !(script = utils.isScript(tok)) && !(style = utils.isStyle(tok))) {\n          tok = this.options.beforeWriteToken(tok);\n          if (tok) {\n            tokens.push(tok);\n          }\n        }\n        if (tokens.length > 0) {\n          this._writeStaticTokens(tokens);\n        }\n        if (script) {\n          this._handleScriptToken(tok);\n        }\n        if (style) {\n          this._handleStyleToken(tok);\n        }\n      };\n\n      /**\n       * Write contiguous non-script tokens (a chunk)\n       *\n       * @param {Array<Object>} tokens The tokens\n       * @returns {{tokens, raw, actual, proxy}|null}\n       * @private\n       */\n\n      WriteStream.prototype._writeStaticTokens = function _writeStaticTokens(tokens) {\
1n        var chunk = this._buildChunk(tokens);\n        if (!chunk.actual) {\n          // e.g., no tokens, or a noscript that got ignored\n          return null;\n        }\n        chunk.html = this.proxyHistory + chunk.actual;\n        this.proxyHistory += chunk.proxy;\n        this.proxyRoot.innerHTML = chunk.html;\n        if (DEBUG_CHUNK) {\n          chunk.proxyInnerHTML = this.proxyRoot.innerHTML;\n        }\n        this._walkChunk();\n        if (DEBUG_CHUNK) {\n          chunk.actualInnerHTML = this.root.innerHTML;\n        }\n        return chunk;\n      };\n\n      /**\n       * Build a chunk.\n       *\n       * @param {Array<Object>} tokens The tokens to use.\n       * @returns {{tokens: *, raw: string, actual: string, proxy: string}}\n       * @private\n       */\n\n      WriteStream.prototype._buildChunk = function _buildChunk(tokens) {\n        var nextId = this.actuals.length;\n\n        // The raw html of this chunk.\n        var raw = [];\n\n        // The html to create the nodes in the tokens (with id's injected).\n        var actual = [];\n\n        // Html that can later be used to proxy the nodes in the tokens.\n        var proxy = [];\n        var len = tokens.length;\n        for (var i = 0; i < len; i++) {\n          var tok = tokens[i];\n          var tokenRaw = tok.toString();\n          raw.push(tokenRaw);\n          if (tok.attrs) {\n            // tok.attrs <==> startTag or atomicTag or cursor\n            // Ignore noscript tags. They are atomic, so we don't have to worry about children.\n            if (!/^noscript$/i.test(tok.tagName)) {\n              var id = nextId++;\n\n              // Actual: inject id attribute: replace '>' at end of start tag with id attribute + '>'\n              actual.push(tokenRaw.replace(/(\\/?>)/, ' ' + BASEATTR + 'id=' + id + ' $1'));\n\n              // Don't proxy scripts: they have no bearing on DOM structure.\n              if (tok.attrs.id !== PROXY_SCRIPT && tok.attrs.id !== PROXY_STYLE) {\n                // Proxy: strip all attributes and inject proxyof attribute\n                proxy.push(\n                // ignore atomic tags (e.g., style): they have no \"structural\" effect\n                tok.type === 'atomicTag' ? '' : '<' + tok.tagName + ' ' + BASEATTR + 'proxyof=' + id + (tok.unary ? ' />' : '>'));\n              }\n            }\n          } else {\n            // Visit any other type of token\n            // Actual: append.\n            actual.push(tokenRaw);\n\n            // Proxy: append endTags. Ignore everything else.\n            proxy.push(tok.type === 'endTag' ? tokenRaw : '');\n          }\n        }\n        return {\n          tokens: tokens,\n          raw: raw.join(''),\n          actual: actual.join(''),\n          proxy: proxy.join('')\n        };\n      };\n\n      /**\n       * Walk the chunks.\n       *\n       * @private\n       */\n\n      WriteStream.prototype._walkChunk = function _walkChunk() {\n        var node = void 0;\n        var stack = [this.proxyRoot];\n\n        // use shift/unshift so that children are walked in document order\n        while (utils.existy(node = stack.shift())) {\n          var isElement = node.nodeType === 1;\n          var isProxy = isElement && getData(node, 'proxyof');\n\n          // Ignore proxies\n          if (!isProxy) {\n            if (isElement) {\n              // New actual element: register it and remove the the id attr.\n              this.actuals[getData(node, 'id')] = node;\n              setData(node, 'id');\n            }\n\n            // Is node's parent a proxy?\n            var parentIsProxyOf = node.parentNode && getData(node.parentNode, 'proxyof');\n            if (parentIsProxyOf) {\n              // Move node under actual parent.\n              this.actuals[parentIsProxyOf].appendChild(node);\n            }\n          }\n\n          // prepend childNodes to stack\n          stack.unshift.apply(stack, utils.toArray(node.childNodes));\n        }\n      };\n\n      /**\n       * Handles Script tokens\n       *\n       * @param {Object} tok The token\n       */\n\n      WriteStream.prototype._handleScriptToken = function _handleScriptToken(tok) {\n        var _this = this;\n        var remainder = this.parser.clear();\n        if (remainder) {\n          // Write remainder immediately behind this script.\n          this.writeQueue.unshift(remainder);\n        }\n        tok.src = tok.attrs.src || tok.attrs.SRC;\n        tok = this.options.beforeWriteToken(tok);\n        if (!tok) {\n          // User has removed this token\n          return;\n        }\n        if (tok.src && this.scriptStack.length) {\n          // Defer this script until scriptStack 
1is empty.\n          // Assumption 1: This script will not start executing until\n          // scriptStack is empty.\n          this.deferredRemote = tok;\n        } else {\n          this._onScriptStart(tok);\n        }\n\n        // Put the script node in the DOM.\n        this._writeScriptToken(tok, function () {\n          _this._onScriptDone(tok);\n        });\n      };\n\n      /**\n       * Handles style tokens\n       *\n       * @param {Object} tok The token\n       */\n\n      WriteStream.prototype._handleStyleToken = function _handleStyleToken(tok) {\n        var remainder = this.parser.clear();\n        if (remainder) {\n          // Write remainder immediately behind this style.\n          this.writeQueue.unshift(remainder);\n        }\n        tok.type = tok.attrs.type || tok.attrs.TYPE || 'text/css';\n        tok = this.options.beforeWriteToken(tok);\n        if (tok) {\n          // Put the style node in the DOM.\n          this._writeStyleToken(tok);\n        }\n        if (remainder) {\n          this.write();\n        }\n      };\n\n      /**\n       * Build a style and insert it into the DOM.\n       *\n       * @param {Object} tok The token\n       */\n\n      WriteStream.prototype._writeStyleToken = function _writeStyleToken(tok) {\n        var el = this._buildStyle(tok);\n        this._insertCursor(el, PROXY_STYLE);\n\n        // Set content\n        if (tok.content) {\n          if (el.styleSheet && !el.sheet) {\n            el.styleSheet.cssText = tok.content;\n          } else {\n            el.appendChild(this.doc.createTextNode(tok.content));\n          }\n        }\n      };\n\n      /**\n       * Build a style element from an atomic style token.\n       *\n       * @param {Object} tok The token\n       * @returns {Element}\n       */\n\n      WriteStream.prototype._buildStyle = function _buildStyle(tok) {\n        var el = this.doc.createElement(tok.tagName);\n        el.setAttribute('type', tok.type);\n\n        // Set attributes\n        utils.eachKey(tok.attrs, function (name, value) {\n          el.setAttribute(name, value);\n        });\n        return el;\n      };\n\n      /**\n       * Append a span to the stream. That span will act as a cursor\n       * (i.e. insertion point) for the element.\n       *\n       * @param {Object} el The element\n       * @param {string} which The type of proxy element\n       */\n\n      WriteStream.prototype._insertCursor = function _insertCursor(el, which) {\n        this._writeImpl('<span id=\"' + which + '\"/>');\n        var cursor = this.doc.getElementById(which);\n        if (cursor) {\n          cursor.parentNode.replaceChild(el, cursor);\n        }\n      };\n\n      /**\n       * Called when a script is started.\n       *\n       * @param {Object} tok The token\n       * @private\n       */\n\n      WriteStream.prototype._onScriptStart = function _onScriptStart(tok) {\n        tok.outerWrites = this.writeQueue;\n        this.writeQueue = [];\n        this.scriptStack.unshift(tok);\n      };\n\n      /**\n       * Called when a script is done.\n       *\n       * @param {Object} tok The token\n       * @private\n       */\n\n      WriteStream.prototype._onScriptDone = function _onScriptDone(tok) {\n        // Pop script and check nesting.\n        if (tok !== this.scriptStack[0]) {\n          this.options.error({\n            message: 'Bad script nesting or script finished twice'\n          });\n          return;\n        }\n        this.scriptStack.shift();\n\n        // Append outer writes to queue and process them.\n        this.write.apply(this, tok.outerWrites);\n\n        // Check for pending remote\n\n        // Assumption 2: if remote_script1 writes remote_script2 then\n        // the we notice remote_script1 finishes before remote_script2 starts.\n        // I think this is equivalent to assumption 1\n        if (!this.scriptStack.length && this.deferredRemote) {\n          this._onScriptStart(this.deferredRemote);\n          this.deferredRemote = null;\n        }\n      };\n\n      /**\n       * Build a script and insert it into the DOM.\n       * Done is called once script has executed.\n       *\n       * @param {Object} tok The token\n       * @param {Function} done The callback when complete\n       */\n\n      WriteStream.prototype._writeScriptToken = function _writeScriptToken(tok, done) {\n        var el = this._buildScript(tok);\n        var asyncRelease = this._shouldRelease(el);\n        var afterAsync = this.options.afterAsync;\n        if (tok.src) {\n          // Fix for attribute \"SRC\" (capitalized). IE does not recognize it.\n          el.src = tok.src;\n          this._scriptLoadHandler(el, !asyncRelease ? function () {\n            done();\n            afterAsync();\n          } : afterAsync);\n        }\n        try {\n          this._insertCursor(el, PROXY_SCRIPT);\n          if (!el.src || asyncRelease) {\n            done();\n          }\n        } catch (e) {\n          this.options.error(e);\n          done();\n        }\n      };\n\n      /**\n       * Build a script element from an atomic script token.\n       *\n       * @param {Object} tok The token\n       * @returns {Element}\n       */\n\n      WriteStream.prototype._buildScript = function _buildScript(tok) {\n        var el = this.doc.createElement(tok.tagName);\n\n        // Set attributes\n        utils.eachKey(tok.attrs, function (name, value) {\n          el.setAttribute(name, value);\n        });\n\n        // Set content\n        if (tok.content) {\n          el.text = tok.content;\n        }\n        return el;\n      };\n\n      /**\n       * Setup the script load handler on an element.\n       *\n       * @param {Object} el The element\n       * @param {Function} done The callback\n       * @private\n       */\n\n      WriteStream.prototype._scriptLoadHandler = function _scriptLoadHandler(el, done) {\n        function cleanup() {\
1n          el = el.onload = el.onreadystatechange = el.onerror = null;\n        }\n        var error = this.options.error;\n        function success() {\n          cleanup();\n          done();\n        }\n        function failure(err) {\n          cleanup();\n          error(err);\n          done();\n        }\n\n        // Set handlers\n        _extends(el, {\n          onload: function onload() {\n            return success();\n          },\n          onreadystatechange: function onreadystatechange() {\n            if (/^(loaded|complete)$/.test(el.readyState)) {\n              success();\n            }\n          },\n          onerror: function onerror() {\n            return failure({\n              message: 'remote script failed ' + el.src\n            });\n          }\n        });\n      };\n\n      /**\n       * Determines whether to release.\n       *\n       * @param {Object} el The element\n       * @returns {boolean}\n       * @private\n       */\n\n      WriteStream.prototype._shouldRelease = function _shouldRelease(el) {\n        var isScript = /^script$/i.test(el.nodeName);\n        return !isScript || !!(this.options.releaseAsync && el.src && el.hasAttribute('async'));\n      };\n      return WriteStream;\n    }();\n    exports['default'] = WriteStream;\n\n    /***/\n  }, /* 3 */\n  /***/function (module, exports, __webpack_require__) {\n    /**\n     * @file prescribe\n     * @description Tiny, forgiving HTML parser\n     * @version v1.1.1\n     * @see {@link https://github.com/krux/prescribe/}\n     * @license MIT\n     * @author Derek Brans\n     * @copyright 2016 Krux Digital, Inc\n     */\n    (function webpackUniversalModuleDefinition(root, factory) {\n      if (true) module.exports = factory();else {}\n    })(this, function () {\n      return /******/function (modules) {\n        // webpackBootstrap\n        /******/ // The module cache\n        /******/\n        var installedModules = {};\n\n        /******/ // The require function\n        /******/\n        function __nested_webpack_require_28271__(moduleId) {\n          /******/ // Check if module is in cache\n          /******/if (installedModules[moduleId]) /******/return installedModules[moduleId].exports;\n\n          /******/ // Create a new module (and put it into the cache)\n          /******/\n          var module = installedModules[moduleId] = {\n            /******/exports: {},\n            /******/id: moduleId,\n            /******/loaded: false\n            /******/\n          };\n\n          /******/ // Execute the module function\n          /******/\n          modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_28271__);\n\n          /******/ // Flag the module as loaded\n          /******/\n          module.loaded = true;\n\n          /******/ // Return the exports of the module\n          /******/\n          return module.exports;\n          /******/\n        }\n\n        /******/ // expose the modules object (__webpack_modules__)\n        /******/\n        __nested_webpack_require_28271__.m = modules;\n\n        /******/ // expose the module cache\n        /******/\n        __nested_webpack_require_28271__.c = installedModules;\n\n        /******/ // __webpack_public_path__\n        /******/\n        __nested_webpack_require_28271__.p = \"\";\n\n        /******/ // Load entry module and return exports\n        /******/\n        return __nested_webpack_require_28271__(0);\n        /******/\n      }\n      /************************************************************************/\n      /******/([/* 0 */\n      /***/function (module, exports, __nested_webpack_require_29763__) {\n        'use strict';\n\n        var _HtmlParser = __nested_webpack_require_29763__(1);\n        var _HtmlParser2 = _interopRequireDefault(_HtmlParser);\n        function _interopRequireDefault(obj) {\n          return obj && obj.__esModule ? obj : {\n            'default': obj\n          };\n        }\n        module.exports = _HtmlParser2['default'];\n\n        /***/\n      }, /* 1 */\n      /***/function (module, exports, __nested_webpack_require_30189__) {\n        'use strict';\n\n        exports.__esModule = true;\n        var _supports = __nested_webpack_require_30189__(2);\n        var supports = _interopRequireWildcard(_supports);\n        var _streamReaders = __nested_webpack_require_30189__(3);\n        var streamReaders = _interopRequireWildcard(_streamReaders);\n        var _fixedReadTokenFactory = __nested_webpack_require_30189__(6);\n        var _fixedReadTokenFactory2 = _interopRequireDefault(_fixedReadTokenFactory);\n        var _utils = __nested_webpack_require_30189__(5);\n        function _interopRequireDefault(obj) {\n          return obj && obj.__esModule ? obj : {\n            'default': obj\n          };\n        }\n        function _interopRequireWildcard(obj) {\n          if (obj && obj.__esModule) {\n            return obj;\n          } else {\n            var newObj = {};\n            if (obj != null) {\n              for (var key in obj) {\n                if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];\n              }\n            }\n            newObj['default'] = obj;\n            return newObj;\n          }\n        }\n        function _classCallCheck(instance, Constructor) {\n          if (!(instance instanceof Constructor)) {\
1n            throw new TypeError(\"Cannot call a class as a function\");\n          }\n        }\n\n        /**\n         * Detection regular expressions.\n         *\n         * Order of detection matters: detection of one can only\n         * succeed if detection of previous didn't\n        \t\t * @type {Object}\n         */\n        var detect = {\n          comment: /^\x3c!--/,\n          endTag: /^<\\//,\n          atomicTag: /^<\\s*(script|style|noscript|iframe|textarea)[\\s\\/>]/i,\n          startTag: /^</,\n          chars: /^[^<]/\n        };\n\n        /**\n         * HtmlParser provides the capability to parse HTML and return tokens\n         * representing the tags and content.\n         */\n\n        var HtmlParser = function () {\n          /**\n           * Constructor.\n           *\n           * @param {string} stream The initial parse stream contents.\n           * @param {Object} options The options\n           * @param {boolean} options.autoFix Set to true to automatically fix errors\n           */\n\n          function HtmlParser() {\n            var _this = this;\n            var stream = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];\n            var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n            _classCallCheck(this, HtmlParser);\n            this.stream = stream;\n            var fix = false;\n            var fixedTokenOptions = {};\n            for (var key in supports) {\n              if (supports.hasOwnProperty(key)) {\n                if (options.autoFix) {\n                  fixedTokenOptions[key + 'Fix'] = true; // !supports[key];\n                }\n                fix = fix || fixedTokenOptions[key + 'Fix'];\n              }\n            }\n            if (fix) {\n              this._readToken = (0, _fixedReadTokenFactory2['default'])(this, fixedTokenOptions, function () {\n                return _this._readTokenImpl();\n              });\n              this._peekToken = (0, _fixedReadTokenFactory2['default'])(this, fixedTokenOptions, function () {\n                return _this._peekTokenImpl();\n              });\n            } else {\n              this._readToken = this._readTokenImpl;\n              this._peekToken = this._peekTokenImpl;\n            }\n          }\n\n          /**\n           * Appends the given string to the parse stream.\n           *\n           * @param {string} str The string to append\n           */\n\n          HtmlParser.prototype.append = function append(str) {\n            this.stream += str;\n          };\n\n          /**\n           * Prepends the given string to the parse stream.\n           *\n           * @param {string} str The string to prepend\n           */\n\n          HtmlParser.prototype.prepend = function prepend(str) {\n            this.stream = str + this.stream;\n          };\n\n          /**\n           * The implementation of the token reading.\n           *\n           * @private\n           * @returns {?Token}\n           */\n\n          HtmlParser.prototype._readTokenImpl = function _readTokenImpl() {\n            var token = this._peekTokenImpl();\n            if (token) {\n              this.stream = this.stream.slice(token.length);\n              return token;\n            }\n          };\n\n          /**\n           * The implementation of token peeking.\n           *\n           * @returns {?Token}\n           */\n\n          HtmlParser.prototype._peekTokenImpl = function _peekTokenImpl() {\n            for (var type in detect) {\n              if (detect.hasOwnProperty(type)) {\n                if (detect[type].test(this.stream)) {\n                  var token = streamReaders[type](this.stream);\n                  if (token) {\n                    if (token.type === 'startTag' && /script|style/i.test(token.tagName)) {\n                      return null;\n                    } else {\n                      token.text = this.stream.substr(0, token.length);\n                      return token;\n                    }\n                  }\n                }\n              }\n            }\n          };\n\n          /**\n           * The public token peeking interface.  Delegates to the basic token peeking\n           * or a ver
1sion that performs fixups depending on the `autoFix` setting in\n           * options.\n           *\n           * @returns {object}\n           */\n\n          HtmlParser.prototype.peekToken = function peekToken() {\n            return this._peekToken();\n          };\n\n          /**\n           * The public token reading interface.  Delegates to the basic token reading\n           * or a version that performs fixups depending on the `autoFix` setting in\n           * options.\n           *\n           * @returns {object}\n           */\n\n          HtmlParser.prototype.readToken = function readToken() {\n            return this._readToken();\n          };\n\n          /**\n           * Read tokens and hand to the given handlers.\n           *\n           * @param {Object} handlers The handlers to use for the different tokens.\n           */\n\n          HtmlParser.prototype.readTokens = function readTokens(handlers) {\n            var tok = void 0;\n            while (tok = this.readToken()) {\n              // continue until we get an explicit \"false\" return\n              if (handlers[tok.type] && handlers[tok.type](tok) === false) {\n                return;\n              }\n            }\n          };\n\n          /**\n           * Clears the parse stream.\n           *\n           * @returns {string} The contents of the parse stream before clearing.\n           */\n\n          HtmlParser.prototype.clear = function clear() {\n            var rest = this.stream;\n            this.stream = '';\n            return rest;\n          };\n\n          /**\n           * Returns the rest of the parse stream.\n           *\n           * @returns {string} The contents of the parse stream.\n           */\n\n          HtmlParser.prototype.rest = function rest() {\n            return this.stream;\n          };\n          return HtmlParser;\n        }();\n        exports['default'] = HtmlParser;\n        HtmlParser.tokenToString = function (tok) {\n          return tok.toString();\n        };\n        HtmlParser.escapeAttributes = function (attrs) {\n          var escapedAttrs = {};\n          for (var name in attrs) {\n            if (attrs.hasOwnProperty(name)) {\n              escapedAttrs[name] = (0, _utils.escapeQuotes)(attrs[name], null);\n            }\n          }\n          return escapedAttrs;\n        };\n        HtmlParser.supports = supports;\n        for (var key in supports) {\n          if (supports.hasOwnProperty(key)) {\n            HtmlParser.browserHasFlaw = HtmlParser.browserHasFlaw || !supports[key] && key;\n          }\n        }\n\n        /***/\n      }, /* 2 */\n      /***/function (module, exports) {\n        'use strict';\n\n        exports.__esModule = true;\n        var tagSoup = false;\n        var selfClose = false;\n        var work = window.document.createElement('div');\n        try {\n          var html = '<P><I></P></I>';\n          work.innerHTML = html;\n          exports.tagSoup = tagSoup = work.innerHTML !== html;\n        } catch (e) {\n          exports.tagSoup = tagSoup = false;\n        }\n        try {\n          work.innerHTML = '<P><i><P></P></i></P>';\n          exports.selfClose = selfClose = work.childNodes.length === 2;\n        } catch (e) {\n          exports.selfClose = selfClose = false;\n        }\n        work = null;\n        exports.tagSoup = tagSoup;\n        exports.selfClose = selfClose;\n\n        /***/\n      }, /* 3 */\n      /***/function (module, exports, __nested_webpack_require_38882__) {\n        'use strict';\n\n        exports.__esModule = true;\n        var _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n          return typeof obj;\n        } : function (obj) {\n          return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj;\n        };\n        exports.comment = comment;\n        exports.chars = chars;\n        exports.startTag = startTag;\n        exports.atomicTag = atomicTag;\n        exports.endTag = endTag;\n        var _tokens = __nested_webpack_require_38882__(4);\n\n        /**\n         * Regular Expressions for parsing tags and attributes\n         *\n         * @type {Object}\n         */\n        var REGEXES = {\n          startTag: /^<([\\-A-Za-z0-9_]+)((?:\\s+[\\w\\-]+(?:\\s*=?\\s*(?:(?
1:\"[^\"]*\")|(?:'[^']*')|[^>\\s]+))?)*)\\s*(\\/?)>/,\n          endTag: /^<\\/([\\-A-Za-z0-9_]+)[^>]*>/,\n          attr: /(?:([\\-A-Za-z0-9_]+)\\s*=\\s*(?:(?:\"((?:\\\\.|[^\"])*)\")|(?:'((?:\\\\.|[^'])*)')|([^>\\s]+)))|(?:([\\-A-Za-z0-9_]+)(\\s|$)+)/g,\n          fillAttr: /^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noresize|noshade|nowrap|readonly|selected)$/i\n        };\n\n        /**\n         * Reads a comment token\n         *\n         * @param {string} stream The input stream\n         * @returns {CommentToken}\n         */\n        function comment(stream) {\n          var index = stream.indexOf('--\x3e');\n          if (index >= 0) {\n            return new _tokens.CommentToken(stream.substr(4, index - 1), index + 3);\n          }\n        }\n\n        /**\n         * Reads non-tag characters.\n         *\n         * @param {string} stream The input stream\n         * @returns {CharsToken}\n         */\n        function chars(stream) {\n          var index = stream.indexOf('<');\n          return new _tokens.CharsToken(index >= 0 ? index : stream.length);\n        }\n\n        /**\n         * Reads start tag token.\n         *\n         * @param {string} stream The input stream\n         * @returns {StartTagToken}\n         */\n        function startTag(stream) {\n          var endTagIndex = stream.indexOf('>');\n          if (endTagIndex !== -1) {\n            var match = stream.match(REGEXES.startTag);\n            if (match) {\n              var _ret = function () {\n                var attrs = {};\n                var booleanAttrs = {};\n                var rest = match[2];\n                match[2].replace(REGEXES.attr, function (match, name) {\n                  if (!(arguments[2] || arguments[3] || arguments[4] || arguments[5])) {\n                    attrs[name] = '';\n                  } else if (arguments[5]) {\n                    attrs[arguments[5]] = '';\n                    booleanAttrs[arguments[5]] = true;\n                  } else {\n                    attrs[name] = arguments[2] || arguments[3] || arguments[4] || REGEXES.fillAttr.test(name) && name || '';\n                  }\n                  rest = rest.replace(match, '');\n                });\n                return {\n                  v: new _tokens.StartTagToken(match[1], match[0].length, attrs, booleanAttrs, !!match[3], rest.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, ''))\n                };\n              }();\n              if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === \"object\") return _ret.v;\n            }\n          }\n        }\n\n        /**\n         * Reads atomic tag token.\n         *\n         * @param {string} stream The input stream\n         * @returns {AtomicTagToken}\n         */\n        function atomicTag(stream) {\n          var start = startTag(stream);\n          if (start) {\n            var rest = stream.slice(start.length);\n            // for optimization, we check first just for the end tag\n            if (rest.match(new RegExp('<\\/\\\\s*' + start.tagName + '\\\\s*>', 'i'))) {\n              // capturing the content is inefficient, so we do it inside the if\n              var match = rest.match(new RegExp('([\\\\s\\\\S]*?)<\\/\\\\s*' + start.tagName + '\\\\s*>', 'i'));\n              if (match) {\n                return new _tokens.AtomicTagToken(start.tagName, match[0].length + start.length, start.attrs, start.booleanAttrs, match[1]);\n              }\n            }\n          }\n        }\n\n        /**\n         * Reads an end tag token.\n         *\n         * @param {string} stream The input stream\n         * @returns {EndTagToken}\n         */\n        function endTag(stream) {\n          var match = stream.match(REGEXES.endTag);\n          if (match) {\n            return new _tokens.EndTagToken(match[1], match[0].length);\n          }\n        }\n\n        /***/\n      }, /* 4 */\n      /***/function (module, exports, __nested_webpack_require_43509__) {\n        'use strict';\n\n        exports.__esModule = true;\n        exports.EndTagToken = exports.AtomicTagToken = exports.StartTagToken = exports.TagToken = exports.CharsToken = exports.CommentToken = exports.Token = undefined;\n        var _utils = __nested_webpack_require_43509__(5);\n        function _classCallCheck(instance, Constructor) {\n          if (!(instance instanceof Constructor)) {\
1n            throw new TypeError(\"Cannot call a class as a function\");\n          }\n        }\n\n        /**\n         * Token is a base class for all token types parsed.  Note we don't actually\n         * use intheritance due to IE8's non-existent ES5 support.\n         */\n\n        var Token =\n        /**\n         * Constructor.\n         *\n         * @param {string} type The type of the Token.\n         * @param {Number} length The length of the Token text.\n         */\n        exports.Token = function Token(type, length) {\n          _classCallCheck(this, Token);\n          this.type = type;\n          this.length = length;\n          this.text = '';\n        };\n\n        /**\n         * CommentToken represents comment tags.\n         */\n\n        var CommentToken = exports.CommentToken = function () {\n          /**\n           * Constructor.\n           *\n           * @param {string} content The content of the comment\n           * @param {Number} length The length of the Token text.\n           */\n\n          function CommentToken(content, length) {\n            _classCallCheck(this, CommentToken);\n            this.type = 'comment';\n            this.length = length || (content ? content.length : 0);\n            this.text = '';\n            this.content = content;\n          }\n          CommentToken.prototype.toString = function toString() {\n            return '\x3c!--' + this.content;\n          };\n          return CommentToken;\n        }();\n\n        /**\n         * CharsToken represents non-tag characters.\n         */\n\n        var CharsToken = exports.CharsToken = function () {\n          /**\n           * Constructor.\n           *\n           * @param {Number} length The length of the Token text.\n           */\n\n          function CharsToken(length) {\n            _classCallCheck(this, CharsToken);\n            this.type = 'chars';\n            this.length = length;\n            this.text = '';\n          }\n          CharsToken.prototype.toString = function toString() {\n            return this.text;\n          };\n          return CharsToken;\n        }();\n\n        /**\n         * TagToken is a base class for all tag-based Tokens.\n         */\n\n        var TagToken = exports.TagToken = function () {\n          /**\n           * Constructor.\n           *\n           * @param {string} type The type of the token.\n           * @param {string} tagName The tag name.\n           * @param {Number} length The length of the Token text.\n           * @param {Object} attrs The dictionary of attributes and values\n           * @param {Object} booleanAttrs If an entry has 'true' then the attribute\n           *                              is a boolean attribute\n           */\n\n          function TagToken(type, tagName, length, attrs, booleanAttrs) {\n            _classCallCheck(this, TagToken);\n            this.type = type;\n            this.length = length;\n            this.text = '';\n            this.tagName = tagName;\n            this.attrs = attrs;\n            this.booleanAttrs = booleanAttrs;\n            this.unary = false;\n            this.html5Unary = false;\n          }\n\n          /**\n           * Formats the given token tag.\n           *\n           * @param {TagToken} tok The TagToken to format.\n           * @param {?string} [content=null] The content of the token.\n           * @returns {string} The formatted tag.\n           */\n\n          TagToken.formatTag = function formatTag(tok) {\n            var content = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];\n            var str = '<' + tok.tagName;\n            for (var key in tok.attrs) {\n              if (tok.attrs.hasOwnProperty(key)) {\n                str += ' ' + key;\n                var val = tok.attrs[key];\n                if (typeof tok.booleanAttrs === 'undefined' || typeof tok.booleanAttrs[key] === 'undefined') {\n                  str += '=\"' + (0, _utils.escapeQuotes)(val) + '\"';\n                }\n              }\n            }\n            if (tok.rest) {\n              str += ' ' + tok.rest;\n            }\n            if (tok.unary && !tok.html5Unary) {\n              str += '/>';\n            } else {\n              str += '>';\n            }\n            if (content !== undefined && content !== null) {\n              str += content + '</' + tok.tagName + '>';\n            }\n            return str;\n          };\n          return TagToken;\n        }();\n\n        /**\n         * StartTagToken represents a start token.\n         */\n\n        var StartTagToken = exports.StartTagToken = function () {\n          /**\n           * Constructor.\n           *\n           * @param {string} tagName The tag name.\n           * @param {Number} length The length of the Token text\n           * @param {Object} attrs The dictionary of attributes and values\n           * @param {Object} booleanAttrs If an entry has 'true' then the attribute\n           *                              is a boolean attribute\n           * @param {boolean} unary True if the tag is a unary tag\n           * @param {string} rest The rest of the content.\n           */\n\n          function StartTagToken(tagName, length, attrs, booleanAttrs, unary, rest) {\n            _classCallCheck(this, StartTagToken);\n            this.type = 'startTag';\n            this.length = length;\n            this.text = '';\n            this.tagName = tagName;\n            this.attrs = attrs;\n            this.booleanAttrs = booleanAttrs;\n            this.html5Unary = false;\n            this.unary = unary;\n            this.rest = rest;\n          }\n          StartTagToken.prototype.toString = function toString() {\n            return TagToken.formatTag(this);\n          };\n          return StartTagToken;\n        }();\n\n        /**\n         * AtomicTagToken represents an atomic tag.\n         */\n\n        var AtomicTagToken = exports.AtomicTagToken = function () {\n          /**\n           * Constructor.\n           *\n           * @param {string} tagName The name of the tag.\n           * @param {Number} length The length of the tag text.\n           * @param {Object} attrs The attributes.\n           * @param {Object} booleanAttrs If an entry has 'true' then the attribute\n           *                              is a boolean attribute\n           * @param {string} content The content of the tag.\n           */\n\n          function AtomicTagToken(tagName, length, attrs, booleanAttrs, content) {\n            _classCallCheck(this, AtomicTagToken);\n            this.type = 'atomicTag';\n            this.length = length;\n            this.text = '';\n            this.tagName = tagName;\n            this.attrs = attrs;\n            this.booleanAttrs = booleanAttrs;\n            this.unary = false;\n            this.html5Unary = false;\n            this.content = content;\n          }\n          AtomicTagToken.prototype.toString = function toString() {\n            return TagToken.formatTag(this, this.content);\n          };\n          return AtomicTagToken;\n        }();\n\n        /**\n         * EndTagToken represents an end tag.\n         */\n\n        var EndTagToken = exports.EndTagToken = function () {\n          /**\n           * Constructor.\n           *\n           * @param {string} tagName The name of the tag.\n           * @param {Number} length The length of the tag text.\n           */\n\n          function EndTagToken(tagName, length) {\n            _classCallCheck(this, EndTagToken);\n            this.type = 'endTag';\n            this.length = length;\n            this.text = '';\n            this.tagName = tagName;\n          }\n          EndTagToken.prototype.toString = function toString() {\n            return '</' + this.tagName + '>';\n          };\n          return EndTagToken;\n        }();\n\n        /***/\n      }
1, /* 5 */\n      /***/function (module, exports) {\n        'use strict';\n\n        exports.__esModule = true;\n        exports.escapeQuotes = escapeQuotes;\n\n        /**\n         * Escape quotes in the given value.\n         *\n         * @param {string} value The value to escape.\n         * @param {string} [defaultValue=''] The default value to return if value is falsy.\n         * @returns {string}\n         */\n        function escapeQuotes(value) {\n          var defaultValue = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];\n\n          // There's no lookback in JS, so /(^|[^\\\\])\"/ only matches the first of two `\"`s.\n          // Instead, just match anything before a double-quote and escape if it's not already escaped.\n          return !value ? defaultValue : value.replace(/([^\"]*)\"/g, function (_, prefix) {\n            return /\\\\/.test(prefix) ? prefix + '\"' : prefix + '\\\\\"';\n          });\n        }\n\n        /***/\n      }, /* 6 */\n      /***/function (module, exports) {\n        'use strict';\n\n        exports.__esModule = true;\n        exports['default'] = fixedReadTokenFactory;\n        /**\n         * Empty Elements - HTML 4.01\n         *\n         * @type {RegExp}\n         */\n        var EMPTY = /^(AREA|BASE|BASEFONT|BR|COL|FRAME|HR|IMG|INPUT|ISINDEX|LINK|META|PARAM|EMBED)$/i;\n\n        /**\n         * Elements that you can intentionally leave open (and which close themselves)\n         *\n         * @type {RegExp}\n         */\n        var CLOSESELF = /^(COLGROUP|DD|DT|LI|OPTIONS|P|TD|TFOOT|TH|THEAD|TR)$/i;\n\n        /**\n         * Corrects a token.\n         *\n         * @param {Token} tok The token to correct\n         * @returns {Token} The corrected token\n         */\n        function correct(tok) {\n          if (tok && tok.type === 'startTag') {\n            tok.unary = EMPTY.test(tok.tagName) || tok.unary;\n            tok.html5Unary = !/\\/>$/.test(tok.text);\n          }\n          return tok;\n        }\n\n        /**\n         * Peeks at the next token in the parser.\n         *\n         * @param {HtmlParser} parser The parser\n         * @param {Function} readTokenImpl The underlying readToken implementation\n         * @returns {Token} The next token\n         */\n        function peekToken(parser, readTokenImpl) {\n          var tmp = parser.stream;\n          var tok = correct(readTokenImpl());\n          parser.stream = tmp;\n          return tok;\n        }\n\n        /**\n         * Closes the last token.\n         *\n         * @param {HtmlParser} parser The parser\n         * @param {Array<Token>} stack The stack\n         */\n        function closeLast(parser, stack) {\n          var tok = stack.pop();\n\n          // prepend close tag to stream.\n          parser.prepend('</' + tok.tagName + '>');\n        }\n\n        /**\n         * Create a new token stack.\n         *\n         * @returns {Array<Token>}\n         */\n        function newStack() {\n          var stack = [];\n          stack.last = function () {\n            return this[this.length - 1];\n          };\n          stack.lastTagNameEq = function (tagName) {\n            var last = this.last();\n            return last && last.tagName && last.tagName.toUpperCase() === tagName.toUpperCase();\n          };\n          stack.containsTagName = function (tagName) {\n            for (var i = 0, tok; tok = this[i]; i++) {\n              if (tok.tagName === tagName) {\n                return true;\n              }\n            }\n            return false;\n          };\n          return stack;\n        }\n\n        /**\n         * Return a readToken implementation that fixes input.\n         *\n         * @param {HtmlParser} parser The parser\n         * @param {Object} options Options for fixing\n         * @param {boolean} options.tagSoupFix True to fix tag soup scenarios\n         * @param {boolean} options.selfCloseFix True to fix self-closing tags\n         * @param {Function} readTokenImpl The underlying readToken implementation\n         * @returns {Function}\n         */\n        function fixedReadTokenFactory(parser, options, readTokenImpl) {\n          var stack = newStack();\n          var handlers = {\n            startTag: function startTag(tok) {\n              var tagName = tok.tagName;\n              if (tagName.toUpperCase() === 'TR' && stack.lastTagNameEq('TABLE')) {\n                parser.prepend('<TBODY>');\n                prepareNextToken();\n              } else if (options.selfCloseFix && CLOSESELF.test(tagName) && stack.containsTagName(tagName)) {\
1n                if (stack.lastTagNameEq(tagName)) {\n                  closeLast(parser, stack);\n                } else {\n                  parser.prepend('</' + tok.tagName + '>');\n                  prepareNextToken();\n                }\n              } else if (!tok.unary) {\n                stack.push(tok);\n              }\n            },\n            endTag: function endTag(tok) {\n              var last = stack.last();\n              if (last) {\n                if (options.tagSoupFix && !stack.lastTagNameEq(tok.tagName)) {\n                  // cleanup tag soup\n                  closeLast(parser, stack);\n                } else {\n                  stack.pop();\n                }\n              } else if (options.tagSoupFix) {\n                // cleanup tag soup part 2: skip this token\n                readTokenImpl();\n                prepareNextToken();\n              }\n            }\n          };\n          function prepareNextToken() {\n            var tok = peekToken(parser, readTokenImpl);\n            if (tok && handlers[tok.type]) {\n              handlers[tok.type](tok);\n            }\n          }\n          return function fixedReadToken() {\n            prepareNextToken();\n            return correct(readTokenImpl());\n          };\n        }\n\n        /***/\n      }\n      /******/]);\n    });\n    ;\n\n    /***/\n  }, /* 4 */\n  /***/function (module, exports) {\n    'use strict';\n\n    exports.__esModule = true;\n    var _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n      return typeof obj;\n    } : function (obj) {\n      return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj;\n    };\n    exports.existy = existy;\n    exports.isFunction = isFunction;\n    exports.each = each;\n    exports.eachKey = eachKey;\n    exports.defaults = defaults;\n    exports.toArray = toArray;\n    exports.last = last;\n    exports.isTag = isTag;\n    exports.isScript = isScript;\n    exports.isStyle = isStyle;\n    /**\n     * Determine if the thing is not undefined and not null.\n     *\n     * @param {*} thing The thing to test\n     * @returns {boolean} True if the thing is not undefined and not null.\n     */\n    function existy(thing) {\n      return thing !== void 0 && thing !== null;\n    }\n\n    /**\n     * Is this a function?\n     *\n     * @param {*} x The variable to test\n     * @returns {boolean} True if the variable is a function\n     */\n    function isFunction(x) {\n      return 'function' === typeof x;\n    }\n\n    /**\n     * Loop over each item in an array-like value.\n     *\n     * @param {Array<*>} arr The array to loop over\n     * @param {Function} fn The function to call\n     * @param {?Object} target The object to bind to the function\n     */\n    function each(arr, fn, target) {\n      var i = void 0;\n      var len = arr && arr.length || 0;\n      for (i = 0; i < len; i++) {\n        fn.call(target, arr[i], i);\n      }\n    }\n\n    /**\n     * Loop over each key/value pair in a hash.\n     *\n     * @param {Object} obj The object\n     * @param {Function} fn The function to call\n     * @param {?Object} target The object to bind to the function\n     */\n    function eachKey(obj, fn, target) {\n      for (var key in obj) {\n        if (obj.hasOwnProperty(key)) {\n          fn.call(target, key, obj[key]);\n        }\n      }\n    }\n\n    /**\n     * Set default options where some option was not specified.\n     *\n     * @param {Object} options The destination\n     * @param {Object} _defaults The defaults\n     * @returns {Object}\n     */\n    function defaults(options, _defaults) {\n      options = options || {};\n      eachKey(_defaults, function (key, val) {\n        if (!existy(options[key])) {\n          options[key] = val;\n        }\n      });\n      return options;\n    }\n\n    /**\n     * Convert value (e.g., a NodeList) to an array.\n     *\n     * @param {*} obj The object\n     * @returns {Array<*>}\n     */\n    function toArray(obj) {\n      try {\n        return Array.prototype.slice.call(obj);\n      } catch (e) {\n        var _ret = function () {\n          var ret = [];
1\n          each(obj, function (val) {\n            ret.push(val);\n          });\n          return {\n            v: ret\n          };\n        }();\n        if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === \"object\") return _ret.v;\n      }\n    }\n\n    /**\n     * Get the last item in an array\n     *\n     * @param {Array<*>} array The array\n     * @returns {*} The last item in the array\n     */\n    function last(array) {\n      return array[array.length - 1];\n    }\n\n    /**\n     * Test if token is a script tag.\n     *\n     * @param {Object} tok The token\n     * @param {String} tag The tag name\n     * @returns {boolean} True if the token is a script tag\n     */\n    function isTag(tok, tag) {\n      return !tok || !(tok.type === 'startTag' || tok.type === 'atomicTag') || !('tagName' in tok) ? !1 : !!~tok.tagName.toLowerCase().indexOf(tag);\n    }\n\n    /**\n     * Test if token is a script tag.\n     *\n     * @param {Object} tok The token\n     * @returns {boolean} True if the token is a script tag\n     */\n    function isScript(tok) {\n      return isTag(tok, 'script');\n    }\n\n    /**\n     * Test if token is a style tag.\n     *\n     * @param {Object} tok The token\n     * @returns {boolean} True if the token is a style tag\n     */\n    function isStyle(tok) {\n      return isTag(tok, 'style');\n    }\n\n    /***/\n  }\n  /******/]);\n});\n;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTU2LmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vdmVuZG9yL3Bvc3RzY3JpYmUuanM/MThlYSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBmaWxlIHBvc3RzY3JpYmVcbiAqIEBkZXNjcmlwdGlvbiBBc3luY2hyb25vdXNseSB3cml0ZSBqYXZhc2NyaXB0LCBldmVuIHdpdGggZG9jdW1lbnQud3JpdGUuXG4gKiBAdmVyc2lvbiB2Mi4wLjZcbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8va3J1eC5naXRodWIuaW8vcG9zdHNjcmliZX1cbiAqIEBsaWNlbnNlIE1JVFxuICogQGF1dGhvciBEZXJlayBCcmFuc1xuICogQGNvcHlyaWdodCAyMDE2IEtydXggRGlnaXRhbCwgSW5jXG4gKi9cbihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcInBvc3RzY3JpYmVcIl0gPSBmYWN0b3J5KCk7XG5cdGVsc2Vcblx0XHRyb290W1wicG9zdHNjcmliZVwiXSA9IGZhY3RvcnkoKTtcbn0pKHRoaXMsIGZ1bmN0aW9uKCkge1xucmV0dXJuIC8qKioqKiovIChmdW5jdGlvbihtb2R1bGVzKSB7IC8vIHdlYnBhY2tCb290c3RyYXBcbi8qKioqKiovIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuLyoqKioqKi8gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbi8qKioqKiovIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbi8qKioqKiovIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbi8qKioqKiovIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuLyoqKioqKi8gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbi8qKioqKiovIFx0XHRcdGV4cG9ydHM6IHt9LFxuLyoqKioqKi8gXHRcdFx0aWQ6IG1vZHVsZUlkLFxuLyoqKioqKi8gXHRcdFx0bG9hZGVkOiBmYWxzZVxuLyoqKioqKi8gXHRcdH07XG4vKioqKioqL1xuLyoqKioqKi8gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuLyoqKioqKi8gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4vKioqKioqLyBcdFx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XG4vKioqKioqL1xuLyoqKioqKi8gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4vKioqKioqLyBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuLyoqKioqKi8gXHR9XG4vKioqKioqL1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO
11xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4vKioqKioqLyBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xuLyoqKioqKi8gfSlcbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKioqKioqLyAoW1xuLyogMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHRcblx0dmFyIF9wb3N0c2NyaWJlID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKTtcblx0XG5cdHZhciBfcG9zdHNjcmliZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9wb3N0c2NyaWJlKTtcblx0XG5cdGZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblx0XG5cdG1vZHVsZS5leHBvcnRzID0gX3Bvc3RzY3JpYmUyWydkZWZhdWx0J107XG5cbi8qKiovIH0sXG4vKiAxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXHRcblx0dmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblx0XG5cdGV4cG9ydHNbJ2RlZmF1bHQnXSA9IHBvc3RzY3JpYmU7XG5cdFxuXHR2YXIgX3dyaXRlU3RyZWFtID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKTtcblx0XG5cdHZhciBfd3JpdGVTdHJlYW0yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfd3JpdGVTdHJlYW0pO1xuXHRcblx0dmFyIF91dGlscyA9IF9fd2VicGFja19yZXF1aXJlX18oNCk7XG5cdFxuXHR2YXIgdXRpbHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfdXRpbHMpO1xuXHRcblx0ZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7IGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsgcmV0dXJuIG9iajsgfSBlbHNlIHsgdmFyIG5ld09iaiA9IHt9OyBpZiAob2JqICE9IG51bGwpIHsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgbmV3T2JqW2tleV0gPSBvYmpba2V5XTsgfSB9IG5ld09ialsnZGVmYXVsdCddID0gb2JqOyByZXR1cm4gbmV3T2JqOyB9IH1cblx0XG5cdGZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblx0XG5cdC8qKlxuXHQgKiBBIGZ1bmN0aW9uIHRoYXQgaW50ZW50aW9uYWxseSBkb2VzIG5vdGhpbmcuXG5cdCAqL1xuXHRmdW5jdGlvbiBkb05vdGhpbmcoKSB7fVxuXHRcblx0LyoqXG5cdCAqIEF2YWlsYWJsZSBvcHRpb25zIGFuZCBkZWZhdWx0cy5cblx0ICpcblx0ICogQHR5cGUge09iamVjdH1cblx0ICovXG5cdHZhciBPUFRJT05TID0ge1xuXHQgIC8qKlxuXHQgICAqIENhbGxlZCB3aGVuIGFuIGFzeW5jIHNjcmlwdCBoYXMgbG9hZGVkLlxuXHQgICAqL1xuXHQgIGFmdGVyQXN5bmM6IGRvTm90aGluZyxcblx0XG5cdCAgLyoqXG5cdCAgICogQ2FsbGVkIGltbWVkaWF0ZWx5IGJlZm9yZSByZW1vdmluZyBmcm9tIHRoZSB3cml0ZSBxdWV1ZS5cblx0ICAgKi9cblx0ICBhZnRlckRlcXVldWU6IGRvTm90aGluZyxcblx0XG5cdCAgLyoqXG5cdCAgICogQ2FsbGVkIHN5bmMgYWZ0ZXIgYSBzdHJlYW0ncyBmaXJzdCB0aHJlYWQgcmVsZWFzZS5cblx0ICAgKi9cblx0ICBhZnRlclN0cmVhbVN0YXJ0OiBkb05vdGhpbmcsXG5cdFxuXHQgIC8qKlxuXHQgICAqIENhbGxlZCBhZnRlciB3cml0aW5nIGJ1ZmZlcmVkIGRvY3VtZW50LndyaXRlIGNhbGxzLlxuXHQgICAqL1xuXHQgIGFmdGVyV3JpdGU6IGRvTm90aGluZyxcblx0XG5cdCAgLyoqXG5cdCAgICogQWxsb3dzIGRpc2FibGluZyB0aGUgYXV0b0ZpeCBmZWF0dXJlIG9mIHByZXNjcmliZVxuXHQgICAqL1xuXHQgIGF1dG9GaXg6IHRydWUsXG5cdFxuXHQgIC8qKlxuXHQgICAqIENhbGxlZCBpbW1lZGlhdGVseSBiZWZvcmUgYWRkaW5nIHRvIHRoZSB3cml0ZSBxdWV1ZS5cblx0ICAgKi9cblx0ICBiZWZvcmVFbnF1ZXVlOiBkb05vdGhpbmcsXG5cdFxuXHQgIC8qKlxuXHQgICAqIENhbGxlZCBiZWZvcmUgd3JpdGluZyBhIHRva2VuLlxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtPYmplY3R9IHRvayBUaGUgdG9rZW5cblx0ICAgKi9cblx0ICBiZWZvcmVXcml0ZVRva2VuOiBmdW5jdGlvbiBiZWZvcmVXcml0ZVRva2VuKHRvaykge1xuXHQgICAgcmV0dXJuIHRvaztcblx0ICB9LFxuXHRcblx0ICAvKipcblx0ICAgKiBDYWxsZWQgYmVmb3JlIHdyaXRpbmcgYnVmZmVyZWQgZG9jdW1lbnQud3JpdGUgY2FsbHMuXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFRoZSBzdHJpbmdcblx0ICAgKi9cblx0ICBiZWZvcmVXcml0ZTogZnVuY3Rpb24gYmVmb3JlV3JpdGUoc3RyKSB7XG5cdCAgICByZXR1cm4gc3RyO1xuXHQgIH0sXG5cdFxuXHQgIC8qKlxuXHQgICAqIENhbGxlZCB3aGVuIGV2YWx1YXRpb24gaXMgZmluaXNoZWQuXG5cdCAgICovXG5cdCAgZG9uZTogZG9Ob3RoaW5nLFxuXHRcblx0ICAvKipcblx0ICAgKiBDYWxsZWQgd2hlbiBhIHdyaXRlIHJlc3VsdHMgaW4gYW4gZXJyb3IuXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge0Vycm9yfSBlIFRoZSBlcnJvclxuXHQgICAqL1xuXHQgIGVycm9yOiBmdW5jdGlvbiBlcnJvcihlKSB7XG5cdCAgICB0aHJvdyBlO1xuXHQgIH0sXG5cdFxuXHRcblx0ICAvKipcblx0ICAgKiBXaGV0aGVyIHRvIGxldCBzY3JpcHRzIHcvIGFzeW5jIGF0dHJpYnV0ZSBzZXQgZmFsbCBvdXQgb2YgdGhlIHF1ZXVlLlxuXHQgICAqL1xuXHQgIHJlbGVhc2VBc3luYzogZmFsc2Vcblx0fTtcblx0XG5cdHZhciBuZXh0SWQgPSAwO1xuXHR2YXIgcXVldWUgPSBbXTtcblx0dmFyIGFjdGl2ZSA9IG51bGw7XG5cdFxuXHRmdW5jdGlvbiBuZXh0U3RyZWFtKCkge1xuXHQgIHZhciBhcmdzID0gcXVldWUuc2hpZnQoKTtcblx0ICBpZiAoYXJncykge1xuXHQgICAgdmFyIG9wdGlvbnMgPSB1dGlscy5sYXN0KGFyZ3MpO1xuXHRcblx0ICAgIG9wdGlvbnMuYWZ0ZXJEZXF1ZXVlKCk7XG5cdCAgICBhcmdzLnN0cmVhbSA9IHJ1blN0cmVhbS5hcHBseSh1bmRlZmluZWQsIGFyZ3MpO1xuXHQgICAgb3B0aW9ucy5hZnRlclN0cmVhbVN0YXJ0KCk7XG5cdCAgfVxuXHR9XG5cdFxuXHRmdW5jdGlvbiBydW5TdHJlYW0oZWwsIGh0bWwsIG9wdGlvbnMpIHtcblx0ICBhY3RpdmUgPSBuZXdcblx0ICAvLyBFeHBvc2UgaW50ZXJuYWwgY2xhc3Nlcy5cblx0ICBfd3JpdG
1VTdHJlYW0yWydkZWZhdWx0J10oZWwsIG9wdGlvbnMpO1xuXHRcblx0ICAvLyBJZGVudGlmeSB0aGlzIHN0cmVhbS5cblx0ICBhY3RpdmUuaWQgPSBuZXh0SWQrKztcblx0ICBhY3RpdmUubmFtZSA9IG9wdGlvbnMubmFtZSB8fCBhY3RpdmUuaWQ7XG5cdCAgcG9zdHNjcmliZS5zdHJlYW1zW2FjdGl2ZS5uYW1lXSA9IGFjdGl2ZTtcblx0XG5cdCAgLy8gT3ZlcnJpZGUgZG9jdW1lbnQud3JpdGUuXG5cdCAgdmFyIGRvYyA9IGVsLm93bmVyRG9jdW1lbnQ7XG5cdFxuXHQgIHZhciBzdGFzaCA9IHtcblx0ICAgIGNsb3NlOiBkb2MuY2xvc2UsXG5cdCAgICBvcGVuOiBkb2Mub3Blbixcblx0ICAgIHdyaXRlOiBkb2Mud3JpdGUsXG5cdCAgICB3cml0ZWxuOiBkb2Mud3JpdGVsblxuXHQgIH07XG5cdFxuXHQgIGZ1bmN0aW9uIF93cml0ZShzdHIpIHtcblx0ICAgIHN0ciA9IG9wdGlvbnMuYmVmb3JlV3JpdGUoc3RyKTtcblx0ICAgIGFjdGl2ZS53cml0ZShzdHIpO1xuXHQgICAgb3B0aW9ucy5hZnRlcldyaXRlKHN0cik7XG5cdCAgfVxuXHRcblx0ICBfZXh0ZW5kcyhkb2MsIHtcblx0ICAgIGNsb3NlOiBkb05vdGhpbmcsXG5cdCAgICBvcGVuOiBkb05vdGhpbmcsXG5cdCAgICB3cml0ZTogZnVuY3Rpb24gd3JpdGUoKSB7XG5cdCAgICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBzdHIgPSBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcblx0ICAgICAgICBzdHJbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG5cdCAgICAgIH1cblx0XG5cdCAgICAgIHJldHVybiBfd3JpdGUoc3RyLmpvaW4oJycpKTtcblx0ICAgIH0sXG5cdCAgICB3cml0ZWxuOiBmdW5jdGlvbiB3cml0ZWxuKCkge1xuXHQgICAgICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIHN0ciA9IEFycmF5KF9sZW4yKSwgX2tleTIgPSAwOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG5cdCAgICAgICAgc3RyW19rZXkyXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG5cdCAgICAgIH1cblx0XG5cdCAgICAgIHJldHVybiBfd3JpdGUoc3RyLmpvaW4oJycpICsgJ1xcbicpO1xuXHQgICAgfVxuXHQgIH0pO1xuXHRcblx0ICAvLyBPdmVycmlkZSB3aW5kb3cub25lcnJvclxuXHQgIHZhciBvbGRPbkVycm9yID0gYWN0aXZlLndpbi5vbmVycm9yIHx8IGRvTm90aGluZztcblx0XG5cdCAgLy8gVGhpcyB3b3JrcyB0b2dldGhlciB3aXRoIHRoZSB0cnkvY2F0Y2ggYXJvdW5kIFdyaXRlU3RyZWFtOjppbnNlcnRTY3JpcHRcblx0ICAvLyBJbiBtb2Rlcm4gYnJvd3NlcnMsIGV4Y2VwdGlvbnMgaW4gdGFnIHNjcmlwdHMgZ28gZGlyZWN0bHkgdG8gdG9wIGxldmVsXG5cdCAgYWN0aXZlLndpbi5vbmVycm9yID0gZnVuY3Rpb24gKG1zZywgdXJsLCBsaW5lKSB7XG5cdCAgICBvcHRpb25zLmVycm9yKHsgbXNnOiBtc2cgKyAnIC0gJyArIHVybCArICc6ICcgKyBsaW5lIH0pO1xuXHQgICAgb2xkT25FcnJvci5hcHBseShhY3RpdmUud2luLCBbbXNnLCB1cmwsIGxpbmVdKTtcblx0ICB9O1xuXHRcblx0ICAvLyBXcml0ZSB0byB0aGUgc3RyZWFtXG5cdCAgYWN0aXZlLndyaXRlKGh0bWwsIGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIHJlc3RvcmUgZG9jdW1lbnQud3JpdGVcblx0ICAgIF9leHRlbmRzKGRvYywgc3Rhc2gpO1xuXHRcblx0ICAgIC8vIHJlc3RvcmUgd2luZG93Lm9uZXJyb3Jcblx0ICAgIGFjdGl2ZS53aW4ub25lcnJvciA9IG9sZE9uRXJyb3I7XG5cdFxuXHQgICAgb3B0aW9ucy5kb25lKCk7XG5cdCAgICBhY3RpdmUgPSBudWxsO1xuXHQgICAgbmV4dFN0cmVhbSgpO1xuXHQgIH0pO1xuXHRcblx0ICByZXR1cm4gYWN0aXZlO1xuXHR9XG5cdFxuXHRmdW5jdGlvbiBwb3N0c2NyaWJlKGVsLCBodG1sLCBvcHRpb25zKSB7XG5cdCAgaWYgKHV0aWxzLmlzRnVuY3Rpb24ob3B0aW9ucykpIHtcblx0ICAgIG9wdGlvbnMgPSB7IGRvbmU6IG9wdGlvbnMgfTtcblx0ICB9IGVsc2UgaWYgKG9wdGlvbnMgPT09ICdjbGVhcicpIHtcblx0ICAgIHF1ZXVlID0gW107XG5cdCAgICBhY3RpdmUgPSBudWxsO1xuXHQgICAgbmV4dElkID0gMDtcblx0ICAgIHJldHVybjtcblx0ICB9XG5cdFxuXHQgIG9wdGlvbnMgPSB1dGlscy5kZWZhdWx0cyhvcHRpb25zLCBPUFRJT05TKTtcblx0XG5cdCAgLy8gaWQgc2VsZWN0b3Jcblx0ICBpZiAoL14jLy50ZXN0KGVsKSkge1xuXHQgICAgZWwgPSB3aW5kb3cuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWwuc3Vic3RyKDEpKTtcblx0ICB9IGVsc2Uge1xuXHQgICAgZWwgPSBlbC5qcXVlcnkgPyBlbFswXSA6IGVsO1xuXHQgIH1cblx0XG5cdCAgdmFyIGFyZ3MgPSBbZWwsIGh0bWwsIG9wdGlvbnNdO1xuXHRcblx0ICBlbC5wb3N0c2NyaWJlID0ge1xuXHQgICAgY2FuY2VsOiBmdW5jdGlvbiBjYW5jZWwoKSB7XG5cdCAgICAgIGlmIChhcmdzLnN0cmVhbSkge1xuXHQgICAgICAgIGFyZ3Muc3RyZWFtLmFib3J0KCk7XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgYXJnc1sxXSA9IGRvTm90aGluZztcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH07XG5cdFxuXHQgIG9wdGlvbnMuYmVmb3JlRW5xdWV1ZShhcmdzKTtcblx0ICBxdWV1ZS5wdXNoKGFyZ3MpO1xuXHRcblx0ICBpZiAoIWFjdGl2ZSkge1xuXHQgICAgbmV4dFN0cmVhbSgpO1xuXHQgIH1cblx0XG5cdCAgcmV0dXJuIGVsLnBvc3RzY3JpYmU7XG5cdH1cblx0XG5cdF9leHRlbmRzKHBvc3RzY3JpYmUsIHtcblx0ICAvLyBTdHJlYW1zIGJ5IG5hbWUuXG5cdCAgc3RyZWFtczoge30sXG5cdCAgLy8gUXVldWUgb2Ygc3RyZWFtcy5cblx0ICBxdWV1ZTogcXVldWUsIFdyaXRlU3RyZWFtOiBfd3JpdGVTdHJlYW0yWydkZWZhdWx0J11cblx0fSk7XG5cbi8qKiovIH0sXG4vKiAyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXHRcblx0dmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblx0XG5cdHZhciBfcHJlc2NyaWJlID0gX193ZWJwYWNrX3JlcXVpcmVfXygzKTtcblx0XG5cdHZhciBfcHJlc2NyaWJlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3ByZXNjcmliZSk7XG5cdFxuXHR2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTtcblx0XG5cdHZhciB1dGlscyA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF91dGlscyk7XG5cdFxuXHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChvYmopIHsgaWYgKG9iaiAmJiBvYmouX19lc01vZHVsZSkgeyByZXR1cm4gb2JqOyB9IGVsc2UgeyB2YXIgbmV3T2JqID0ge307IGlmIChvYmogIT0gbnVsbCkgeyBmb3IgKHZhciBrZXkgaW4gb2JqKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gbmV3T2JqWydkZWZhdWx0J10gPSBvYmo7IHJldHVybi
1BuZXdPYmo7IH0gfVxuXHRcblx0ZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXHRcblx0ZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblx0XG5cdC8qKlxuXHQgKiBUdXJuIG9uIHRvIGRlYnVnIGhvdyBlYWNoIGNodW5rIGFmZmVjdGVkIHRoZSBET00uXG5cdCAqIEB0eXBlIHtib29sZWFufVxuXHQgKi9cblx0dmFyIERFQlVHX0NIVU5LID0gZmFsc2U7XG5cdFxuXHQvKipcblx0ICogUHJlZml4IGZvciBkYXRhIGF0dHJpYnV0ZXMgb24gRE9NIGVsZW1lbnRzLlxuXHQgKiBAdHlwZSB7c3RyaW5nfVxuXHQgKi9cblx0dmFyIEJBU0VBVFRSID0gJ2RhdGEtcHMtJztcblx0XG5cdC8qKlxuXHQgKiBJRCBmb3IgdGhlIHN0eWxlIHByb3h5XG5cdCAqIEB0eXBlIHtzdHJpbmd9XG5cdCAqL1xuXHR2YXIgUFJPWFlfU1RZTEUgPSAncHMtc3R5bGUnO1xuXHRcblx0LyoqXG5cdCAqIElEIGZvciB0aGUgc2NyaXB0IHByb3h5XG5cdCAqIEB0eXBlIHtzdHJpbmd9XG5cdCAqL1xuXHR2YXIgUFJPWFlfU0NSSVBUID0gJ3BzLXNjcmlwdCc7XG5cdFxuXHQvKipcblx0ICogR2V0IGRhdGEgYXR0cmlidXRlc1xuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gZWwgVGhlIERPTSBlbGVtZW50LlxuXHQgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgYXR0cmlidXRlIG5hbWUuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9XG5cdCAqL1xuXHRmdW5jdGlvbiBnZXREYXRhKGVsLCBuYW1lKSB7XG5cdCAgdmFyIGF0dHIgPSBCQVNFQVRUUiArIG5hbWU7XG5cdFxuXHQgIHZhciB2YWwgPSBlbC5nZXRBdHRyaWJ1dGUoYXR0cik7XG5cdFxuXHQgIC8vIElFIDggcmV0dXJucyBhIG51bWJlciBpZiBpdCdzIGEgbnVtYmVyXG5cdCAgcmV0dXJuICF1dGlscy5leGlzdHkodmFsKSA/IHZhbCA6IFN0cmluZyh2YWwpO1xuXHR9XG5cdFxuXHQvKipcblx0ICogU2V0IGRhdGEgYXR0cmlidXRlc1xuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gZWwgVGhlIERPTSBlbGVtZW50LlxuXHQgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgYXR0cmlidXRlIG5hbWUuXG5cdCAqIEBwYXJhbSB7bnVsbHwqfSB2YWx1ZSBUaGUgYXR0cmlidXRlIHZhbHVlLlxuXHQgKi9cblx0ZnVuY3Rpb24gc2V0RGF0YShlbCwgbmFtZSkge1xuXHQgIHZhciB2YWx1ZSA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMiB8fCBhcmd1bWVudHNbMl0gPT09IHVuZGVmaW5lZCA/IG51bGwgOiBhcmd1bWVudHNbMl07XG5cdFxuXHQgIHZhciBhdHRyID0gQkFTRUFUVFIgKyBuYW1lO1xuXHRcblx0ICBpZiAodXRpbHMuZXhpc3R5KHZhbHVlKSAmJiB2YWx1ZSAhPT0gJycpIHtcblx0ICAgIGVsLnNldEF0dHJpYnV0ZShhdHRyLCB2YWx1ZSk7XG5cdCAgfSBlbHNlIHtcblx0ICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShhdHRyKTtcblx0ICB9XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBTdHJlYW0gc3RhdGljIGh0bWwgdG8gYW4gZWxlbWVudCwgd2hlcmUgXCJzdGF0aWMgaHRtbFwiIGRlbm90ZXMgXCJodG1sXG5cdCAqIHdpdGhvdXQgc2NyaXB0c1wiLlxuXHQgKlxuXHQgKiBUaGlzIGNsYXNzIG1haW50YWlucyBhICpoaXN0b3J5IG9mIHdyaXRlcyBkZXZvaWQgb2YgYW55IGF0dHJpYnV0ZXMqIG9yXG5cdCAqIFwicHJveHkgaGlzdG9yeVwiLlxuXHQgKlxuXHQgKiBJbmplY3RpbmcgdGhlIHByb3h5IGhpc3RvcnkgaW50byBhIHRlbXBvcmFyeSBkaXYgaGFzIG5vIHNpZGUtZWZmZWN0cyxcblx0ICogb3RoZXIgdGhhbiB0byBjcmVhdGUgcHJveHkgZWxlbWVudHMgZm9yIHByZXZpb3VzbHkgd3JpdHRlbiBlbGVtZW50cy5cblx0ICpcblx0ICogR2l2ZW4gdGhlIGBzdGF0aWNIdG1sYCBvZiBhIG5ldyB3cml0ZSwgYSBgdGVtcERpdmAncyBpbm5lckhUTUwgaXMgc2V0IHRvXG5cdCAqIGBwcm94eV9oaXN0b3J5ICsgc3RhdGljSHRtbGAuXG5cdCAqIFRoZSAqc3RydWN0dXJlKiBvZiBgdGVtcERpdmAncyBjb250ZW50cywgKGkuZS4sIHRoZSBwbGFjZW1lbnQgb2YgbmV3IG5vZGVzXG5cdCAqIGJlc2lkZSBvciBpbnNpZGUgb2YgcHJveHkgZWxlbWVudHMpLCByZWZsZWN0cyB0aGUgRE9NIHN0cnVjdHVyZSB0aGF0IHdvdWxkXG5cdCAqIGhhdmUgcmVzdWx0ZWQgaWYgYWxsIHdyaXRlcyBoYWQgYmVlbiBzcXVhc2hlZCBpbnRvIGEgc2luZ2xlIHdyaXRlLlxuXHQgKlxuXHQgKiBGb3IgZWFjaCBkZXNjZW5kZW50IGBub2RlYCBvZiBgdGVtcERpdmAgd2hvc2UgcGFyZW50Tm9kZSBpcyBhICpwcm94eSosXG5cdCAqIGBub2RlYCBpcyBhcHBlbmRlZCB0byB0aGUgY29ycmVzcG9uZGluZyAqcmVhbCogZWxlbWVudCB3aXRoaW4gdGhlIERPTS5cblx0ICpcblx0ICogUHJveHkgZWxlbWVudHMgYXJlIG1hcHBlZCB0byAqYWN0dWFsKiBlbGVtZW50cyBpbiB0aGUgRE9NIGJ5IGluamVjdGluZyBhXG5cdCAqIGBkYXRhLWlkYCBhdHRyaWJ1dGUgaW50byBlYWNoIHN0YXJ0IHRhZyBpbiBgc3RhdGljSHRtbGAuXG5cdCAqXG5cdCAqL1xuXHRcblx0dmFyIFdyaXRlU3RyZWFtID0gZnVuY3Rpb24gKCkge1xuXHQgIC8qKlxuXHQgICAqIENvbnN0cnVjdG9yLlxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtPYmplY3R9IHJvb3QgVGhlIHJvb3QgZWxlbWVudFxuXHQgICAqIEBwYXJhbSB7P09iamVjdH0gb3B0aW9ucyBUaGUgb3B0aW9uc1xuXHQgICAqL1xuXHRcblx0ICBmdW5jdGlvbiBXcml0ZVN0cmVhbShyb290KSB7XG5cdCAgICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMSB8fCBhcmd1bWVudHNbMV0gPT09IHVuZGVmaW5lZCA/IHt9IDogYXJndW1lbnRzWzFdO1xuXHRcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBXcml0ZVN0cmVhbSk7XG5cdFxuXHQgICAgdGhpcy5yb290ID0gcm9vdDtcblx0ICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cdCAgICB0aGlzLmRvYyA9IHJvb3Qub3duZXJEb2N1bWVudDtcblx0ICAgIHRoaXMud2luID0gdGhpcy5kb2MuZGVmYXVsdFZpZXcgfHwgdGhpcy5kb2MucGFyZW50V2luZG93O1xuXHQgICAgdGhpcy5wYXJzZXIgPSBuZXcgX3ByZXNjcmliZTJbJ2RlZmF1bHQnXSgnJywgeyBhdXRvRml4OiBvcHRpb25zLmF1dG9GaXggfSk7XG5cdFxuXHQgICAgLy8gQWN0dWFsIGVsZW1lbnRzIGJ5IGlkLlxuXHQgICAgdGhpcy5hY3R1YWxzID0gW3Jvb3RdO1xuXHRcblx0ICAgIC8vIEVtYm9kaWVzIHRoZSBcInN0cnVjdHVyZVwiIG9mIHdoYXQncyBiZWVuIHdyaXR0ZW4gc28gZmFyLFxuXHQgICAgLy8gZGV2b2lkIG9mIGF0dHJpYnV0ZXMuXG5cdCAgICB0aGlzLnByb3h5SGlzdG9yeSA9ICcnO1xuXHRcblx0ICAgIC8vIENyZWF0ZSBhIHByb3h5IG9mIHRoZSByb290IGVsZW1lbnQuXG5cdCAgICB0aGlzLnByb3h5Um9vdCA9IHRoaXMuZG9jLmNyZWF0ZUVsZW1lbnQocm9vdC5ub2RlTmFtZSk7XG5cdFxuXHQgICAgdGhpcy5zY3JpcHRTdGFjayA9IFtdO1xuXHQgICAgdGhpcy53cml0ZVF1ZXVlID0gW107XG5cdFxuXHQgICAgc2V0RGF0YSh0aGlzLnByb3h5Um9vdCwgJ3Byb3h5b2YnLCAwKTtcblx0ICB9XG5cdFxuXHQgIC8qKlxuXHQgICAqIFdyaXRlcyB0aGUgZ2l2ZW4gc3RyaW5ncy5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7Li4uU3RyaW5nfSBzdHIgVGhlIHN0cmluZ3MgdG8gd3JpdGVcblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlKCkge1xuXHQgICAgdmFyIF93cml0ZVF1ZXVlO1xuXHRcblx0ICAgIChfd3JpdG
1VRdWV1ZSA9IHRoaXMud3JpdGVRdWV1ZSkucHVzaC5hcHBseShfd3JpdGVRdWV1ZSwgYXJndW1lbnRzKTtcblx0XG5cdCAgICAvLyBQcm9jZXNzIHdyaXRlc1xuXHQgICAgLy8gV2hlbiBuZXcgc2NyaXB0IGdldHMgcHVzaGVkIG9yIHBlbmRpbmcgdGhpcyB3aWxsIHN0b3Bcblx0ICAgIC8vIGJlY2F1c2UgbmV3IHdyaXRlUXVldWUgZ2V0cyBwdXNoZWRcblx0ICAgIHdoaWxlICghdGhpcy5kZWZlcnJlZFJlbW90ZSAmJiB0aGlzLndyaXRlUXVldWUubGVuZ3RoKSB7XG5cdCAgICAgIHZhciBhcmcgPSB0aGlzLndyaXRlUXVldWUuc2hpZnQoKTtcblx0XG5cdCAgICAgIGlmICh1dGlscy5pc0Z1bmN0aW9uKGFyZykpIHtcblx0ICAgICAgICB0aGlzLl9jYWxsRnVuY3Rpb24oYXJnKTtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICB0aGlzLl93cml0ZUltcGwoYXJnKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH07XG5cdFxuXHQgIC8qKlxuXHQgICAqIENhbGxzIHRoZSBnaXZlbiBmdW5jdGlvbi5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBjYWxsXG5cdCAgICogQHByaXZhdGVcblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5fY2FsbEZ1bmN0aW9uID0gZnVuY3Rpb24gX2NhbGxGdW5jdGlvbihmbikge1xuXHQgICAgdmFyIHRvayA9IHsgdHlwZTogJ2Z1bmN0aW9uJywgdmFsdWU6IGZuLm5hbWUgfHwgZm4udG9TdHJpbmcoKSB9O1xuXHQgICAgdGhpcy5fb25TY3JpcHRTdGFydCh0b2spO1xuXHQgICAgZm4uY2FsbCh0aGlzLndpbiwgdGhpcy5kb2MpO1xuXHQgICAgdGhpcy5fb25TY3JpcHREb25lKHRvayk7XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogVGhlIHdyaXRlIGltcGxlbWVudGF0aW9uXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge1N0cmluZ30gaHRtbCBUaGUgSFRNTCB0byB3cml0ZS5cblx0ICAgKiBAcHJpdmF0ZVxuXHQgICAqL1xuXHRcblx0XG5cdCAgV3JpdGVTdHJlYW0ucHJvdG90eXBlLl93cml0ZUltcGwgPSBmdW5jdGlvbiBfd3JpdGVJbXBsKGh0bWwpIHtcblx0ICAgIHRoaXMucGFyc2VyLmFwcGVuZChodG1sKTtcblx0XG5cdCAgICB2YXIgdG9rID0gdm9pZCAwO1xuXHQgICAgdmFyIHNjcmlwdCA9IHZvaWQgMDtcblx0ICAgIHZhciBzdHlsZSA9IHZvaWQgMDtcblx0ICAgIHZhciB0b2tlbnMgPSBbXTtcblx0XG5cdCAgICAvLyBzdG9wIGlmIHdlIHNlZSBhIHNjcmlwdCB0b2tlblxuXHQgICAgd2hpbGUgKCh0b2sgPSB0aGlzLnBhcnNlci5yZWFkVG9rZW4oKSkgJiYgIShzY3JpcHQgPSB1dGlscy5pc1NjcmlwdCh0b2spKSAmJiAhKHN0eWxlID0gdXRpbHMuaXNTdHlsZSh0b2spKSkge1xuXHQgICAgICB0b2sgPSB0aGlzLm9wdGlvbnMuYmVmb3JlV3JpdGVUb2tlbih0b2spO1xuXHRcblx0ICAgICAgaWYgKHRvaykge1xuXHQgICAgICAgIHRva2Vucy5wdXNoKHRvayk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0XG5cdCAgICBpZiAodG9rZW5zLmxlbmd0aCA+IDApIHtcblx0ICAgICAgdGhpcy5fd3JpdGVTdGF0aWNUb2tlbnModG9rZW5zKTtcblx0ICAgIH1cblx0XG5cdCAgICBpZiAoc2NyaXB0KSB7XG5cdCAgICAgIHRoaXMuX2hhbmRsZVNjcmlwdFRva2VuKHRvayk7XG5cdCAgICB9XG5cdFxuXHQgICAgaWYgKHN0eWxlKSB7XG5cdCAgICAgIHRoaXMuX2hhbmRsZVN0eWxlVG9rZW4odG9rKTtcblx0ICAgIH1cblx0ICB9O1xuXHRcblx0ICAvKipcblx0ICAgKiBXcml0ZSBjb250aWd1b3VzIG5vbi1zY3JpcHQgdG9rZW5zIChhIGNodW5rKVxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fSB0b2tlbnMgVGhlIHRva2Vuc1xuXHQgICAqIEByZXR1cm5zIHt7dG9rZW5zLCByYXcsIGFjdHVhbCwgcHJveHl9fG51bGx9XG5cdCAgICogQHByaXZhdGVcblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5fd3JpdGVTdGF0aWNUb2tlbnMgPSBmdW5jdGlvbiBfd3JpdGVTdGF0aWNUb2tlbnModG9rZW5zKSB7XG5cdCAgICB2YXIgY2h1bmsgPSB0aGlzLl9idWlsZENodW5rKHRva2Vucyk7XG5cdFxuXHQgICAgaWYgKCFjaHVuay5hY3R1YWwpIHtcblx0ICAgICAgLy8gZS5nLiwgbm8gdG9rZW5zLCBvciBhIG5vc2NyaXB0IHRoYXQgZ290IGlnbm9yZWRcblx0ICAgICAgcmV0dXJuIG51bGw7XG5cdCAgICB9XG5cdFxuXHQgICAgY2h1bmsuaHRtbCA9IHRoaXMucHJveHlIaXN0b3J5ICsgY2h1bmsuYWN0dWFsO1xuXHQgICAgdGhpcy5wcm94eUhpc3RvcnkgKz0gY2h1bmsucHJveHk7XG5cdCAgICB0aGlzLnByb3h5Um9vdC5pbm5lckhUTUwgPSBjaHVuay5odG1sO1xuXHRcblx0ICAgIGlmIChERUJVR19DSFVOSykge1xuXHQgICAgICBjaHVuay5wcm94eUlubmVySFRNTCA9IHRoaXMucHJveHlSb290LmlubmVySFRNTDtcblx0ICAgIH1cblx0XG5cdCAgICB0aGlzLl93YWxrQ2h1bmsoKTtcblx0XG5cdCAgICBpZiAoREVCVUdfQ0hVTkspIHtcblx0ICAgICAgY2h1bmsuYWN0dWFsSW5uZXJIVE1MID0gdGhpcy5yb290LmlubmVySFRNTDtcblx0ICAgIH1cblx0XG5cdCAgICByZXR1cm4gY2h1bms7XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQnVpbGQgYSBjaHVuay5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gdG9rZW5zIFRoZSB0b2tlbnMgdG8gdXNlLlxuXHQgICAqIEByZXR1cm5zIHt7dG9rZW5zOiAqLCByYXc6IHN0cmluZywgYWN0dWFsOiBzdHJpbmcsIHByb3h5OiBzdHJpbmd9fVxuXHQgICAqIEBwcml2YXRlXG5cdCAgICovXG5cdFxuXHRcblx0ICBXcml0ZVN0cmVhbS5wcm90b3R5cGUuX2J1aWxkQ2h1bmsgPSBmdW5jdGlvbiBfYnVpbGRDaHVuayh0b2tlbnMpIHtcblx0ICAgIHZhciBuZXh0SWQgPSB0aGlzLmFjdHVhbHMubGVuZ3RoO1xuXHRcblx0ICAgIC8vIFRoZSByYXcgaHRtbCBvZiB0aGlzIGNodW5rLlxuXHQgICAgdmFyIHJhdyA9IFtdO1xuXHRcblx0ICAgIC8vIFRoZSBodG1sIHRvIGNyZWF0ZSB0aGUgbm9kZXMgaW4gdGhlIHRva2VucyAod2l0aCBpZCdzIGluamVjdGVkKS5cblx0ICAgIHZhciBhY3R1YWwgPSBbXTtcblx0XG5cdCAgICAvLyBIdG1sIHRoYXQgY2FuIGxhdGVyIGJlIHVzZWQgdG8gcHJveHkgdGhlIG5vZGVzIGluIHRoZSB0b2tlbnMuXG5cdCAgICB2Y
1XIgcHJveHkgPSBbXTtcblx0XG5cdCAgICB2YXIgbGVuID0gdG9rZW5zLmxlbmd0aDtcblx0ICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0ICAgICAgdmFyIHRvayA9IHRva2Vuc1tpXTtcblx0ICAgICAgdmFyIHRva2VuUmF3ID0gdG9rLnRvU3RyaW5nKCk7XG5cdFxuXHQgICAgICByYXcucHVzaCh0b2tlblJhdyk7XG5cdFxuXHQgICAgICBpZiAodG9rLmF0dHJzKSB7XG5cdCAgICAgICAgLy8gdG9rLmF0dHJzIDw9PT4gc3RhcnRUYWcgb3IgYXRvbWljVGFnIG9yIGN1cnNvclxuXHQgICAgICAgIC8vIElnbm9yZSBub3NjcmlwdCB0YWdzLiBUaGV5IGFyZSBhdG9taWMsIHNvIHdlIGRvbid0IGhhdmUgdG8gd29ycnkgYWJvdXQgY2hpbGRyZW4uXG5cdCAgICAgICAgaWYgKCEvXm5vc2NyaXB0JC9pLnRlc3QodG9rLnRhZ05hbWUpKSB7XG5cdCAgICAgICAgICB2YXIgaWQgPSBuZXh0SWQrKztcblx0XG5cdCAgICAgICAgICAvLyBBY3R1YWw6IGluamVjdCBpZCBhdHRyaWJ1dGU6IHJlcGxhY2UgJz4nIGF0IGVuZCBvZiBzdGFydCB0YWcgd2l0aCBpZCBhdHRyaWJ1dGUgKyAnPidcblx0ICAgICAgICAgIGFjdHVhbC5wdXNoKHRva2VuUmF3LnJlcGxhY2UoLyhcXC8/PikvLCAnICcgKyBCQVNFQVRUUiArICdpZD0nICsgaWQgKyAnICQxJykpO1xuXHRcblx0ICAgICAgICAgIC8vIERvbid0IHByb3h5IHNjcmlwdHM6IHRoZXkgaGF2ZSBubyBiZWFyaW5nIG9uIERPTSBzdHJ1Y3R1cmUuXG5cdCAgICAgICAgICBpZiAodG9rLmF0dHJzLmlkICE9PSBQUk9YWV9TQ1JJUFQgJiYgdG9rLmF0dHJzLmlkICE9PSBQUk9YWV9TVFlMRSkge1xuXHQgICAgICAgICAgICAvLyBQcm94eTogc3RyaXAgYWxsIGF0dHJpYnV0ZXMgYW5kIGluamVjdCBwcm94eW9mIGF0dHJpYnV0ZVxuXHQgICAgICAgICAgICBwcm94eS5wdXNoKFxuXHQgICAgICAgICAgICAvLyBpZ25vcmUgYXRvbWljIHRhZ3MgKGUuZy4sIHN0eWxlKTogdGhleSBoYXZlIG5vIFwic3RydWN0dXJhbFwiIGVmZmVjdFxuXHQgICAgICAgICAgICB0b2sudHlwZSA9PT0gJ2F0b21pY1RhZycgPyAnJyA6ICc8JyArIHRvay50YWdOYW1lICsgJyAnICsgQkFTRUFUVFIgKyAncHJveHlvZj0nICsgaWQgKyAodG9rLnVuYXJ5ID8gJyAvPicgOiAnPicpKTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgLy8gVmlzaXQgYW55IG90aGVyIHR5cGUgb2YgdG9rZW5cblx0ICAgICAgICAvLyBBY3R1YWw6IGFwcGVuZC5cblx0ICAgICAgICBhY3R1YWwucHVzaCh0b2tlblJhdyk7XG5cdFxuXHQgICAgICAgIC8vIFByb3h5OiBhcHBlbmQgZW5kVGFncy4gSWdub3JlIGV2ZXJ5dGhpbmcgZWxzZS5cblx0ICAgICAgICBwcm94eS5wdXNoKHRvay50eXBlID09PSAnZW5kVGFnJyA/IHRva2VuUmF3IDogJycpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdFxuXHQgICAgcmV0dXJuIHtcblx0ICAgICAgdG9rZW5zOiB0b2tlbnMsXG5cdCAgICAgIHJhdzogcmF3LmpvaW4oJycpLFxuXHQgICAgICBhY3R1YWw6IGFjdHVhbC5qb2luKCcnKSxcblx0ICAgICAgcHJveHk6IHByb3h5LmpvaW4oJycpXG5cdCAgICB9O1xuXHQgIH07XG5cdFxuXHQgIC8qKlxuXHQgICAqIFdhbGsgdGhlIGNodW5rcy5cblx0ICAgKlxuXHQgICAqIEBwcml2YXRlXG5cdCAgICovXG5cdFxuXHRcblx0ICBXcml0ZVN0cmVhbS5wcm90b3R5cGUuX3dhbGtDaHVuayA9IGZ1bmN0aW9uIF93YWxrQ2h1bmsoKSB7XG5cdCAgICB2YXIgbm9kZSA9IHZvaWQgMDtcblx0ICAgIHZhciBzdGFjayA9IFt0aGlzLnByb3h5Um9vdF07XG5cdFxuXHQgICAgLy8gdXNlIHNoaWZ0L3Vuc2hpZnQgc28gdGhhdCBjaGlsZHJlbiBhcmUgd2Fsa2VkIGluIGRvY3VtZW50IG9yZGVyXG5cdCAgICB3aGlsZSAodXRpbHMuZXhpc3R5KG5vZGUgPSBzdGFjay5zaGlmdCgpKSkge1xuXHQgICAgICB2YXIgaXNFbGVtZW50ID0gbm9kZS5ub2RlVHlwZSA9PT0gMTtcblx0ICAgICAgdmFyIGlzUHJveHkgPSBpc0VsZW1lbnQgJiYgZ2V0RGF0YShub2RlLCAncHJveHlvZicpO1xuXHRcblx0ICAgICAgLy8gSWdub3JlIHByb3hpZXNcblx0ICAgICAgaWYgKCFpc1Byb3h5KSB7XG5cdCAgICAgICAgaWYgKGlzRWxlbWVudCkge1xuXHQgICAgICAgICAgLy8gTmV3IGFjdHVhbCBlbGVtZW50OiByZWdpc3RlciBpdCBhbmQgcmVtb3ZlIHRoZSB0aGUgaWQgYXR0ci5cblx0ICAgICAgICAgIHRoaXMuYWN0dWFsc1tnZXREYXRhKG5vZGUsICdpZCcpXSA9IG5vZGU7XG5cdCAgICAgICAgICBzZXREYXRhKG5vZGUsICdpZCcpO1xuXHQgICAgICAgIH1cblx0XG5cdCAgICAgICAgLy8gSXMgbm9kZSdzIHBhcmVudCBhIHByb3h5P1xuXHQgICAgICAgIHZhciBwYXJlbnRJc1Byb3h5T2YgPSBub2RlLnBhcmVudE5vZGUgJiYgZ2V0RGF0YShub2RlLnBhcmVudE5vZGUsICdwcm94eW9mJyk7XG5cdCAgICAgICAgaWYgKHBhcmVudElzUHJveHlPZikge1xuXHQgICAgICAgICAgLy8gTW92ZSBub2RlIHVuZGVyIGFjdHVhbCBwYXJlbnQuXG5cdCAgICAgICAgICB0aGlzLmFjdHVhbHNbcGFyZW50SXNQcm94eU9mXS5hcHBlbmRDaGlsZChub2RlKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0XG5cdCAgICAgIC8vIHByZXBlbmQgY2hpbGROb2RlcyB0byBzdGFja1xuXHQgICAgICBzdGFjay51bnNoaWZ0LmFwcGx5KHN0YWNrLCB1dGlscy50b0FycmF5KG5vZGUuY2hpbGROb2RlcykpO1xuXHQgICAgfVxuXHQgIH07XG5cdFxuXHQgIC8qKlxuXHQgICAqIEhhbmRsZXMgU2NyaXB0IHRva2Vuc1xuXHQgICAqXG5cdCAgICogQHBhcmFtIHtPYmplY3R9IHRvayBUaGUgdG9rZW5cblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5faGFuZGxlU2NyaXB0VG9rZW4gPSBmdW5jdGlvbiBfaGFuZGxlU2NyaXB0VG9rZW4odG9rKSB7XG5cdCAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgIHZhciByZW1haW5kZXIgPSB0aGlzLnBhcnNlci5jbGVhcigpO1xuXHRcblx0ICAgIGlmIChyZW1haW5kZXIpIHtcblx0ICAgICAgLy8gV3JpdGUgcmVtYWluZGVyIGltbWVkaWF0ZWx5IGJlaGluZCB0aGlzIHNjcmlwdC5cblx0ICAgICAgdGhpcy53cml0ZVF1ZXVlLnVuc2hpZnQocmVtYWluZGVyKTtcblx0ICAgIH1cblx0XG5cdCAgICB0b2suc3JjID0gdG9rLmF0dHJzLnNyYyB8fCB0b2suYXR0cnMuU1JDO1xuXHRcblx0ICAgIHRvayA9IHRoaXMub3B0aW9ucy5iZWZvcmVXcml0ZVRva2VuKHRvayk7XG5cdCAgICBpZiAoIXRvaykge1xuXHQgICAgICAvLyBVc2VyIGhhcyByZW1vdmVkIHRoaXMgdG9rZW5cblx0ICAgICAgcmV0dXJuO1xuXHQgICAgfVxuXHRcblx0ICAgIGlmICh0b2suc3JjICYmIHRoaXMuc2NyaXB0U3RhY2subGVuZ3RoKSB7XG5cdCAgICAgIC8vIERlZmVyIHRoaXMgc2NyaXB0IHVudGlsIHNjcmlwdFN0YWNrIGlzIGVtcHR5LlxuXHQgICAgICAvLyBBc3N1bXB0aW9uIDE6IFRoaXMgc2NyaXB0IHdpbGwgbm90IHN0YXJ0IGV4ZWN1dGluZyB1bnRpbFxuXHQgICAgICAvLyBzY3JpcHRTdGFjayBpcyBlbXB0eS5cblx0ICAgICAgdGhpcy5kZWZlcnJlZFJlbW90ZSA9IHRvaztcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgI
1HRoaXMuX29uU2NyaXB0U3RhcnQodG9rKTtcblx0ICAgIH1cblx0XG5cdCAgICAvLyBQdXQgdGhlIHNjcmlwdCBub2RlIGluIHRoZSBET00uXG5cdCAgICB0aGlzLl93cml0ZVNjcmlwdFRva2VuKHRvaywgZnVuY3Rpb24gKCkge1xuXHQgICAgICBfdGhpcy5fb25TY3JpcHREb25lKHRvayk7XG5cdCAgICB9KTtcblx0ICB9O1xuXHRcblx0ICAvKipcblx0ICAgKiBIYW5kbGVzIHN0eWxlIHRva2Vuc1xuXHQgICAqXG5cdCAgICogQHBhcmFtIHtPYmplY3R9IHRvayBUaGUgdG9rZW5cblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5faGFuZGxlU3R5bGVUb2tlbiA9IGZ1bmN0aW9uIF9oYW5kbGVTdHlsZVRva2VuKHRvaykge1xuXHQgICAgdmFyIHJlbWFpbmRlciA9IHRoaXMucGFyc2VyLmNsZWFyKCk7XG5cdFxuXHQgICAgaWYgKHJlbWFpbmRlcikge1xuXHQgICAgICAvLyBXcml0ZSByZW1haW5kZXIgaW1tZWRpYXRlbHkgYmVoaW5kIHRoaXMgc3R5bGUuXG5cdCAgICAgIHRoaXMud3JpdGVRdWV1ZS51bnNoaWZ0KHJlbWFpbmRlcik7XG5cdCAgICB9XG5cdFxuXHQgICAgdG9rLnR5cGUgPSB0b2suYXR0cnMudHlwZSB8fCB0b2suYXR0cnMuVFlQRSB8fCAndGV4dC9jc3MnO1xuXHRcblx0ICAgIHRvayA9IHRoaXMub3B0aW9ucy5iZWZvcmVXcml0ZVRva2VuKHRvayk7XG5cdFxuXHQgICAgaWYgKHRvaykge1xuXHQgICAgICAvLyBQdXQgdGhlIHN0eWxlIG5vZGUgaW4gdGhlIERPTS5cblx0ICAgICAgdGhpcy5fd3JpdGVTdHlsZVRva2VuKHRvayk7XG5cdCAgICB9XG5cdFxuXHQgICAgaWYgKHJlbWFpbmRlcikge1xuXHQgICAgICB0aGlzLndyaXRlKCk7XG5cdCAgICB9XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQnVpbGQgYSBzdHlsZSBhbmQgaW5zZXJ0IGl0IGludG8gdGhlIERPTS5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7T2JqZWN0fSB0b2sgVGhlIHRva2VuXG5cdCAgICovXG5cdFxuXHRcblx0ICBXcml0ZVN0cmVhbS5wcm90b3R5cGUuX3dyaXRlU3R5bGVUb2tlbiA9IGZ1bmN0aW9uIF93cml0ZVN0eWxlVG9rZW4odG9rKSB7XG5cdCAgICB2YXIgZWwgPSB0aGlzLl9idWlsZFN0eWxlKHRvayk7XG5cdFxuXHQgICAgdGhpcy5faW5zZXJ0Q3Vyc29yKGVsLCBQUk9YWV9TVFlMRSk7XG5cdFxuXHQgICAgLy8gU2V0IGNvbnRlbnRcblx0ICAgIGlmICh0b2suY29udGVudCkge1xuXHQgICAgICBpZiAoZWwuc3R5bGVTaGVldCAmJiAhZWwuc2hlZXQpIHtcblx0ICAgICAgICBlbC5zdHlsZVNoZWV0LmNzc1RleHQgPSB0b2suY29udGVudDtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICBlbC5hcHBlbmRDaGlsZCh0aGlzLmRvYy5jcmVhdGVUZXh0Tm9kZSh0b2suY29udGVudCkpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQnVpbGQgYSBzdHlsZSBlbGVtZW50IGZyb20gYW4gYXRvbWljIHN0eWxlIHRva2VuLlxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtPYmplY3R9IHRvayBUaGUgdG9rZW5cblx0ICAgKiBAcmV0dXJucyB7RWxlbWVudH1cblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5fYnVpbGRTdHlsZSA9IGZ1bmN0aW9uIF9idWlsZFN0eWxlKHRvaykge1xuXHQgICAgdmFyIGVsID0gdGhpcy5kb2MuY3JlYXRlRWxlbWVudCh0b2sudGFnTmFtZSk7XG5cdFxuXHQgICAgZWwuc2V0QXR0cmlidXRlKCd0eXBlJywgdG9rLnR5cGUpO1xuXHRcblx0ICAgIC8vIFNldCBhdHRyaWJ1dGVzXG5cdCAgICB1dGlscy5lYWNoS2V5KHRvay5hdHRycywgZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG5cdCAgICAgIGVsLnNldEF0dHJpYnV0ZShuYW1lLCB2YWx1ZSk7XG5cdCAgICB9KTtcblx0XG5cdCAgICByZXR1cm4gZWw7XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQXBwZW5kIGEgc3BhbiB0byB0aGUgc3RyZWFtLiBUaGF0IHNwYW4gd2lsbCBhY3QgYXMgYSBjdXJzb3Jcblx0ICAgKiAoaS5lLiBpbnNlcnRpb24gcG9pbnQpIGZvciB0aGUgZWxlbWVudC5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7T2JqZWN0fSBlbCBUaGUgZWxlbWVudFxuXHQgICAqIEBwYXJhbSB7c3RyaW5nfSB3aGljaCBUaGUgdHlwZSBvZiBwcm94eSBlbGVtZW50XG5cdCAgICovXG5cdFxuXHRcblx0ICBXcml0ZVN0cmVhbS5wcm90b3R5cGUuX2luc2VydEN1cnNvciA9IGZ1bmN0aW9uIF9pbnNlcnRDdXJzb3IoZWwsIHdoaWNoKSB7XG5cdCAgICB0aGlzLl93cml0ZUltcGwoJzxzcGFuIGlkPVwiJyArIHdoaWNoICsgJ1wiLz4nKTtcblx0XG5cdCAgICB2YXIgY3Vyc29yID0gdGhpcy5kb2MuZ2V0RWxlbWVudEJ5SWQod2hpY2gpO1xuXHRcblx0ICAgIGlmIChjdXJzb3IpIHtcblx0ICAgICAgY3Vyc29yLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGVsLCBjdXJzb3IpO1xuXHQgICAgfVxuXHQgIH07XG5cdFxuXHQgIC8qKlxuXHQgICAqIENhbGxlZCB3aGVuIGEgc2NyaXB0IGlzIHN0YXJ0ZWQuXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge09iamVjdH0gdG9rIFRoZSB0b2tlblxuXHQgICAqIEBwcml2YXRlXG5cdCAgICovXG5cdFxuXHRcblx0ICBXcml0ZVN0cmVhbS5wcm90b3R5cGUuX29uU2NyaXB0U3RhcnQgPSBmdW5jdGlvbiBfb25TY3JpcHRTdGFydCh0b2spIHtcblx0ICAgIHRvay5vdXRlcldyaXRlcyA9IHRoaXMud3JpdGVRdWV1ZTtcblx0ICAgIHRoaXMud3JpdGVRdWV1ZSA9IFtdO1xuXHQgICAgdGhpcy5zY3JpcHRTdGFjay51bnNoaWZ0KHRvayk7XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQ2FsbGVkIHdoZW4gYSBzY3JpcHQgaXMgZG9uZS5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7T2JqZWN0fSB0b2sgVGhlIHRva2VuXG5cdCAgICogQHByaXZhdGVcblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5fb25TY3JpcHREb25lID0gZnVuY3Rpb24gX29uU2NyaXB0RG9uZSh0b2spIHtcblx0ICAgIC8vIFBvcCBzY3JpcHQgYW5kIGNoZWNrIG5lc3RpbmcuXG5cdCAgICBpZiAodG9rICE9PSB0aGlzLnNjcmlwdFN0YWNrWzBdKSB7XG5cdCAgICAgIHRoaXMub3B0aW9ucy5lcnJvcih7IG1lc3NhZ2U6ICdCYWQgc2NyaXB0IG5lc3Rpbmcgb3Igc2NyaXB0IGZpbmlzaGVkIHR3aWNlJyB9KTtcblx0ICAgICAgcmV0dXJuO1xuXHQgICAgfVxuXHRcblx0ICAgIHRoaXMuc2NyaXB0U3RhY2suc2hpZnQoKTtcblx0XG5cdCAgICAvLyBBcHBlbmQgb3V0ZXIgd3JpdG
1VzIHRvIHF1ZXVlIGFuZCBwcm9jZXNzIHRoZW0uXG5cdCAgICB0aGlzLndyaXRlLmFwcGx5KHRoaXMsIHRvay5vdXRlcldyaXRlcyk7XG5cdFxuXHQgICAgLy8gQ2hlY2sgZm9yIHBlbmRpbmcgcmVtb3RlXG5cdFxuXHQgICAgLy8gQXNzdW1wdGlvbiAyOiBpZiByZW1vdGVfc2NyaXB0MSB3cml0ZXMgcmVtb3RlX3NjcmlwdDIgdGhlblxuXHQgICAgLy8gdGhlIHdlIG5vdGljZSByZW1vdGVfc2NyaXB0MSBmaW5pc2hlcyBiZWZvcmUgcmVtb3RlX3NjcmlwdDIgc3RhcnRzLlxuXHQgICAgLy8gSSB0aGluayB0aGlzIGlzIGVxdWl2YWxlbnQgdG8gYXNzdW1wdGlvbiAxXG5cdCAgICBpZiAoIXRoaXMuc2NyaXB0U3RhY2subGVuZ3RoICYmIHRoaXMuZGVmZXJyZWRSZW1vdGUpIHtcblx0ICAgICAgdGhpcy5fb25TY3JpcHRTdGFydCh0aGlzLmRlZmVycmVkUmVtb3RlKTtcblx0ICAgICAgdGhpcy5kZWZlcnJlZFJlbW90ZSA9IG51bGw7XG5cdCAgICB9XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQnVpbGQgYSBzY3JpcHQgYW5kIGluc2VydCBpdCBpbnRvIHRoZSBET00uXG5cdCAgICogRG9uZSBpcyBjYWxsZWQgb25jZSBzY3JpcHQgaGFzIGV4ZWN1dGVkLlxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtPYmplY3R9IHRvayBUaGUgdG9rZW5cblx0ICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lIFRoZSBjYWxsYmFjayB3aGVuIGNvbXBsZXRlXG5cdCAgICovXG5cdFxuXHRcblx0ICBXcml0ZVN0cmVhbS5wcm90b3R5cGUuX3dyaXRlU2NyaXB0VG9rZW4gPSBmdW5jdGlvbiBfd3JpdGVTY3JpcHRUb2tlbih0b2ssIGRvbmUpIHtcblx0ICAgIHZhciBlbCA9IHRoaXMuX2J1aWxkU2NyaXB0KHRvayk7XG5cdCAgICB2YXIgYXN5bmNSZWxlYXNlID0gdGhpcy5fc2hvdWxkUmVsZWFzZShlbCk7XG5cdCAgICB2YXIgYWZ0ZXJBc3luYyA9IHRoaXMub3B0aW9ucy5hZnRlckFzeW5jO1xuXHRcblx0ICAgIGlmICh0b2suc3JjKSB7XG5cdCAgICAgIC8vIEZpeCBmb3IgYXR0cmlidXRlIFwiU1JDXCIgKGNhcGl0YWxpemVkKS4gSUUgZG9lcyBub3QgcmVjb2duaXplIGl0LlxuXHQgICAgICBlbC5zcmMgPSB0b2suc3JjO1xuXHQgICAgICB0aGlzLl9zY3JpcHRMb2FkSGFuZGxlcihlbCwgIWFzeW5jUmVsZWFzZSA/IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBkb25lKCk7XG5cdCAgICAgICAgYWZ0ZXJBc3luYygpO1xuXHQgICAgICB9IDogYWZ0ZXJBc3luYyk7XG5cdCAgICB9XG5cdFxuXHQgICAgdHJ5IHtcblx0ICAgICAgdGhpcy5faW5zZXJ0Q3Vyc29yKGVsLCBQUk9YWV9TQ1JJUFQpO1xuXHQgICAgICBpZiAoIWVsLnNyYyB8fCBhc3luY1JlbGVhc2UpIHtcblx0ICAgICAgICBkb25lKCk7XG5cdCAgICAgIH1cblx0ICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgdGhpcy5vcHRpb25zLmVycm9yKGUpO1xuXHQgICAgICBkb25lKCk7XG5cdCAgICB9XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQnVpbGQgYSBzY3JpcHQgZWxlbWVudCBmcm9tIGFuIGF0b21pYyBzY3JpcHQgdG9rZW4uXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge09iamVjdH0gdG9rIFRoZSB0b2tlblxuXHQgICAqIEByZXR1cm5zIHtFbGVtZW50fVxuXHQgICAqL1xuXHRcblx0XG5cdCAgV3JpdGVTdHJlYW0ucHJvdG90eXBlLl9idWlsZFNjcmlwdCA9IGZ1bmN0aW9uIF9idWlsZFNjcmlwdCh0b2spIHtcblx0ICAgIHZhciBlbCA9IHRoaXMuZG9jLmNyZWF0ZUVsZW1lbnQodG9rLnRhZ05hbWUpO1xuXHRcblx0ICAgIC8vIFNldCBhdHRyaWJ1dGVzXG5cdCAgICB1dGlscy5lYWNoS2V5KHRvay5hdHRycywgZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG5cdCAgICAgIGVsLnNldEF0dHJpYnV0ZShuYW1lLCB2YWx1ZSk7XG5cdCAgICB9KTtcblx0XG5cdCAgICAvLyBTZXQgY29udGVudFxuXHQgICAgaWYgKHRvay5jb250ZW50KSB7XG5cdCAgICAgIGVsLnRleHQgPSB0b2suY29udGVudDtcblx0ICAgIH1cblx0XG5cdCAgICByZXR1cm4gZWw7XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogU2V0dXAgdGhlIHNjcmlwdCBsb2FkIGhhbmRsZXIgb24gYW4gZWxlbWVudC5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7T2JqZWN0fSBlbCBUaGUgZWxlbWVudFxuXHQgICAqIEBwYXJhbSB7RnVuY3Rpb259IGRvbmUgVGhlIGNhbGxiYWNrXG5cdCAgICogQHByaXZhdGVcblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5fc2NyaXB0TG9hZEhhbmRsZXIgPSBmdW5jdGlvbiBfc2NyaXB0TG9hZEhhbmRsZXIoZWwsIGRvbmUpIHtcblx0ICAgIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG5cdCAgICAgIGVsID0gZWwub25sb2FkID0gZWwub25yZWFkeXN0YXRlY2hhbmdlID0gZWwub25lcnJvciA9IG51bGw7XG5cdCAgICB9XG5cdFxuXHQgICAgdmFyIGVycm9yID0gdGhpcy5vcHRpb25zLmVycm9yO1xuXHRcblx0ICAgIGZ1bmN0aW9uIHN1Y2Nlc3MoKSB7XG5cdCAgICAgIGNsZWFudXAoKTtcblx0ICAgICAgZG9uZSgpO1xuXHQgICAgfVxuXHRcblx0ICAgIGZ1bmN0aW9uIGZ
1haWx1cmUoZXJyKSB7XG5cdCAgICAgIGNsZWFudXAoKTtcblx0ICAgICAgZXJyb3IoZXJyKTtcblx0ICAgICAgZG9uZSgpO1xuXHQgICAgfVxuXHRcblx0ICAgIC8vIFNldCBoYW5kbGVyc1xuXHQgICAgX2V4dGVuZHMoZWwsIHtcblx0ICAgICAgb25sb2FkOiBmdW5jdGlvbiBvbmxvYWQoKSB7XG5cdCAgICAgICAgcmV0dXJuIHN1Y2Nlc3MoKTtcblx0ICAgICAgfSxcblx0XG5cdCAgICAgIG9ucmVhZHlzdGF0ZWNoYW5nZTogZnVuY3Rpb24gb25yZWFkeXN0YXRlY2hhbmdlKCkge1xuXHQgICAgICAgIGlmICgvXihsb2FkZWR8Y29tcGxldGUpJC8udGVzdChlbC5yZWFkeVN0YXRlKSkge1xuXHQgICAgICAgICAgc3VjY2VzcygpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSxcblx0XG5cdCAgICAgIG9uZXJyb3I6IGZ1bmN0aW9uIG9uZXJyb3IoKSB7XG5cdCAgICAgICAgcmV0dXJuIGZhaWx1cmUoeyBtZXNzYWdlOiAncmVtb3RlIHNjcmlwdCBmYWlsZWQgJyArIGVsLnNyYyB9KTtcblx0ICAgICAgfVxuXHQgICAgfSk7XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRvIHJlbGVhc2UuXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge09iamVjdH0gZWwgVGhlIGVsZW1lbnRcblx0ICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICAgKiBAcHJpdmF0ZVxuXHQgICAqL1xuXHRcblx0XG5cdCAgV3JpdGVTdHJlYW0ucHJvdG90eXBlLl9zaG91bGRSZWxlYXNlID0gZnVuY3Rpb24gX3Nob3VsZFJlbGVhc2UoZWwpIHtcblx0ICAgIHZhciBpc1NjcmlwdCA9IC9ec2NyaXB0JC9pLnRlc3QoZWwubm9kZU5hbWUpO1xuXHQgICAgcmV0dXJuICFpc1NjcmlwdCB8fCAhISh0aGlzLm9wdGlvbnMucmVsZWFzZUFzeW5jICYmIGVsLnNyYyAmJiBlbC5oYXNBdHRyaWJ1dGUoJ2FzeW5jJykpO1xuXHQgIH07XG5cdFxuXHQgIHJldHVybiBXcml0ZVN0cmVhbTtcblx0fSgpO1xuXHRcblx0ZXhwb3J0c1snZGVmYXVsdCddID0gV3JpdGVTdHJlYW07XG5cbi8qKiovIH0sXG4vKiAzICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvKipcblx0ICogQGZpbGUgcHJl
1c2NyaWJlXG5cdCAqIEBkZXNjcmlwdGlvbiBUaW55LCBmb3JnaXZpbmcgSFRNTCBwYXJzZXJcblx0ICogQHZlcnNpb24gdjEuMS4xXG5cdCAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9rcnV4L3ByZXNjcmliZS99XG5cdCAqIEBsaWNlbnNlIE1JVFxuXHQgKiBAYXV0aG9yIERlcmVrIEJyYW5zXG5cdCAqIEBjb3B5cmlnaHQgMjAxNiBLcnV4IERpZ2l0YWwsIEluY1xuXHQgKi9cblx0KGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0XHRpZih0cnVlKVxuXHRcdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7XG5cdFx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRcdGVsc2UgaWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKVxuXHRcdFx0ZXhwb3J0c1tcIlByZXNjcmliZVwiXSA9IGZhY3RvcnkoKTtcblx0XHRlbHNlXG5cdFx0XHRyb290W1wiUHJlc2NyaWJlXCJdID0gZmFjdG9yeSgpO1xuXHR9KSh0aGlzLCBmdW5jdGlvbigpIHtcblx0cmV0dXJuIC8qKioqKiovIChmdW5jdGlvbihtb2R1bGVzKSB7IC8vIHdlYnBhY2tCb290c3RyYXBcblx0LyoqKioqKi8gXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG5cdC8qKioqKiovIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblx0XG5cdC8qKioqKiovIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cblx0LyoqKioqKi8gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cdFxuXHQvKioqKioqLyBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdC8qKioqKiovIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcblx0LyoqKioqKi8gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG5cdFxuXHQvKioqKioqLyBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0LyoqKioqKi8gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcblx0LyoqKioqKi8gXHRcdFx0ZXhwb3J0czoge30sXG5cdC8qKioqKiovIFx0XHRcdGlkOiBtb2R1bGVJZCxcblx0LyoqKioqKi8gXHRcdFx0bG9hZGVkOiBmYWxzZVxuXHQvKioqKioqLyBcdFx0fTtcblx0XG5cdC8qKioqKiovIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0LyoqKioqKi8gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXHRcblx0LyoqKioqKi8gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcblx0LyoqKioqKi8gXHRcdG1vZHVsZS5sb2FkZWQgPSB0cnVlO1xuXHRcblx0LyoqKioqKi8gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdC8qKioqKiovIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG5cdC8qKioqKiovIFx0fVxuXHRcblx0XG5cdC8qKioqKiovIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcblx0LyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXHRcblx0LyoqKioqKi8gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuXHQvKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cdFxuXHQvKioqKioqLyBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG5cdC8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblx0XG5cdC8qKioqKiovIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG5cdC8qKioqKiovIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oMCk7XG5cdC8qKioqKiovIH0pXG5cdC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cdC8qKioqKiovIChbXG5cdC8qIDAgKi9cblx0LyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cdFxuXHRcdCd1c2Ugc3RyaWN0Jztcblx0XG5cdFx0dmFyIF9IdG1sUGFyc2VyID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKTtcblx0XG5cdFx0dmFyIF9IdG1sUGFyc2VyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0h0bWxQYXJzZXIpO1xuXHRcblx0XHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cdFxuXHRcdG1vZHVsZS5leHBvcnRzID0gX0h0bWxQYXJzZXIyWydkZWZhdWx0J107XG5cdFxuXHQvKioqLyB9LFxuXHQvKiAxICovXG5cdC8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXHRcblx0XHQndXNlIHN0cmljdCc7XG5cdFxuXHRcdGV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cdFxuXHRcdHZhciBfc3VwcG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDIpO1xuXHRcblx0XHR2YXIgc3VwcG9ydHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfc3VwcG9ydHMpO1xuXHRcblx0XHR2YXIgX3N0cmVhbVJlYWRlcnMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDMpO1xuXHRcblx0XHR2YXIgc3RyZWFtUmVhZGVycyA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF9zdHJlYW1SZWFkZXJzKTtcblx0XG5cdFx0dmFyIF9maXhlZFJlYWRUb2tlbkZhY3RvcnkgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpO1xuXHRcblx0XHR2YXIgX2ZpeGVkUmVhZFRva2VuRmFjdG9yeTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9maXhlZFJlYWRUb2tlbkZhY3RvcnkpO1xuXHRcblx0XHR2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg1KTtcblx0XG5cdFx0ZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXHRcblx0XHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChvYmopIHsgaWYgKG9iaiAmJiBvYmouX19lc01vZHVsZSkgeyByZXR1cm4gb2JqOyB9IGVsc2UgeyB2YXIgbmV3T2JqID0ge307IGlmIChvYmogIT0gbnVsbCkgeyBmb3IgKHZhciBrZXkgaW4gb2JqKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gbmV3T2JqWydkZWZhdWx0J10gPSBvYmo7IHJldHVybi
1BuZXdPYmo7IH0gfVxuXHRcblx0XHRmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXHRcblx0XHQvKipcblx0XHQgKiBEZXRlY3Rpb24gcmVndWxhciBleHByZXNzaW9ucy5cblx0XHQgKlxuXHRcdCAqIE9yZGVyIG9mIGRldGVjdGlvbiBtYXR0ZXJzOiBkZXRlY3Rpb24gb2Ygb25lIGNhbiBvbmx5XG5cdFx0ICogc3VjY2VlZCBpZiBkZXRlY3Rpb24gb2YgcHJldmlvdXMgZGlkbid0XG5cdFxuXHRcdCAqIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdFx0dmFyIGRldGVjdCA9IHtcblx0XHQgIGNvbW1lbnQ6IC9ePCEtLS8sXG5cdFx0ICBlbmRUYWc6IC9ePFxcLy8sXG5cdFx0ICBhdG9taWNUYWc6IC9ePFxccyooc2NyaXB0fHN0eWxlfG5vc2NyaXB0fGlmcmFtZXx0ZXh0YXJlYSlbXFxzXFwvPl0vaSxcblx0XHQgIHN0YXJ0VGFnOiAvXjwvLFxuXHRcdCAgY2hhcnM6IC9eW148XS9cblx0XHR9O1xuXHRcblx0XHQvKipcblx0XHQgKiBIdG1sUGFyc2VyIHByb3ZpZGVzIHRoZSBjYXBhYmlsaXR5IHRvIHBhcnNlIEhUTUwgYW5kIHJldHVybiB0b2tlbnNcblx0XHQgKiByZXByZXNlbnRpbmcgdGhlIHRhZ3MgYW5kIGNvbnRlbnQuXG5cdFx0ICovXG5cdFxuXHRcdHZhciBIdG1sUGFyc2VyID0gZnVuY3Rpb24gKCkge1xuXHRcdCAgLyoqXG5cdFx0ICAgKiBDb25zdHJ1Y3Rvci5cblx0XHQgICAqXG5cdFx0ICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyZWFtIFRoZSBpbml0aWFsIHBhcnNlIHN0cmVhbSBjb250ZW50cy5cblx0XHQgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIFRoZSBvcHRpb25zXG5cdFx0ICAgKiBAcGFyYW0ge2Jvb2xlYW59IG9wdGlvbnMuYXV0b0ZpeCBTZXQgdG8gdHJ1ZSB0byBhdXRvbWF0aWNhbGx5IGZpeCBlcnJvcnNcblx0XHQgICAqL1xuXHRcblx0XHQgIGZ1bmN0aW9uIEh0bWxQYXJzZXIoKSB7XG5cdFx0ICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHRcdCAgICB2YXIgc3RyZWFtID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gJycgOiBhcmd1bWVudHNbMF07XG5cdFx0ICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8ge30gOiBhcmd1bWVudHNbMV07XG5cdFxuXHRcdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgSHRtbFBhcnNlcik7XG5cdFxuXHRcdCAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcblx0XG5cdFx0ICAgIHZhciBmaXggPSBmYWxzZTtcblx0XHQgICAgdmFyIGZpeGVkVG9rZW5PcHRpb25zID0ge307XG5cdFxuXHRcdCAgICBmb3IgKHZhciBrZXkgaW4gc3VwcG9ydHMpIHtcblx0XHQgICAgICBpZiAoc3VwcG9ydHMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuXHRcdCAgICAgICAgaWYgKG9wdGlvbnMuYXV0b0ZpeCkge1xuXHRcdCAgICAgICAgICBmaXhlZFRva2VuT3B0aW9uc1trZXkgKyAnRml4J10gPSB0cnVlOyAvLyAhc3VwcG9ydHNba2V5XTtcblx0XHQgICAgICAgIH1cblx0XHQgICAgICAgIGZpeCA9IGZpeCB8fCBmaXhlZFRva2VuT3B0aW9uc1trZXkgKyAnRml4J107XG5cdFx0ICAgICAgfVxuXHRcdCAgICB9XG5cdFxuXHRcdCAgICBpZiAoZml4KSB7XG5cdFx0ICAgICAgdGhpcy5fcmVhZFRva2VuID0gKDAsIF9maXhlZFJlYWRUb2tlbkZhY3RvcnkyWydkZWZhdWx0J10pKHRoaXMsIGZpeGVkVG9rZW5PcHRpb25zLCBmdW5jdGlvbiAoKSB7XG5cdFx0ICAgICAgICByZXR1cm4gX3RoaXMuX3JlYWRUb2tlbkltcGwoKTtcblx0XHQgICAgICB9KTtcblx0XHQgICAgICB0aGlzLl9wZWVrVG9rZW4gPSAoMCwgX2ZpeGVkUmVhZFRva2VuRmFjdG9yeTJbJ2RlZmF1bHQnXSkodGhpcywgZml4ZWRUb2tlbk9wdGlvbnMsIGZ1bmN0aW9uICgpIHtcblx0XHQgICAgICAgIHJldHVybiBfdGhpcy5fcGVla1Rva2VuSW1wbCgpO1xuXHRcdCAgICAgIH0pO1xuXHRcdCAgICB9IGVsc2Uge1xuXHRcdCAgICAgIHRoaXMuX3JlYWRUb2tlbiA9IHRoaXMuX3JlYWRUb2tlbkltcGw7XG5cdFx0ICAgICAgdGhpcy5fcGVla1Rva2VuID0gdGhpcy5fcGVla1Rva2VuSW1wbDtcblx0XHQgICAgfVxuXHRcdCAgfVxuXHRcblx0XHQgIC8qKlxuXHRcdCAgICogQXBwZW5kcyB0aGUgZ2l2ZW4gc3RyaW5nIHRvIHRoZSBwYXJzZSBzdHJlYW0uXG5cdFx0ICAgKlxuXHRcdCAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBUaGUgc3RyaW5nIHRvIGFwcGVuZFxuXHRcdCAgICovXG5cdFxuXHRcblx0XHQgIEh0bWxQYXJzZXIucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uIGFwcGVuZChzdHIpIHtcblx0XHQgICAgdGhpcy5zdHJlYW0gKz0gc3RyO1xuXHRcdCAgfTtcblx0XG5cdFx0ICAvKipcblx0XHQgICAqIFByZXBlbmRzIHRoZSBnaXZlbiBzdHJpbmcgdG8gdGhlIHBhcnNlIHN0cmVhbS5cblx0XHQgICAqXG5cdFx0ICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFRoZSBzdHJpbmcgdG8gcHJlcGVuZFxuXHRcdCAgICovXG5cdFxuXHRcblx0XHQgIEh0bWxQYXJzZXIucHJvdG90eXBlLnByZXBlbmQgPSBmdW5jdGlvbiBwcmVwZW5kKHN0cikge1xuXHRcdCAgICB0aGlzLnN0cmVhbSA9IHN0ciArIHRoaXMuc3RyZWFtO1xuXHRcdCAgfTtcblx0XG5cdFx0ICAvKipcblx0XHQgICAqIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgdG9rZW4gcmVhZGluZy5cblx0XHQgICAqXG5cdFx0ICAgKiBAcHJpdmF0ZVxuXHRcdCAgICogQHJldHVybnMgez9Ub2tlbn1cblx0XHQgICAqL1xuXHRcblx0XG5cdFx0ICBIdG1sUGFyc2VyLnByb3RvdHlwZS5fcmVhZFRva2VuSW1wbCA9IGZ1bmN0aW9uIF9yZWFkVG9rZW5JbXBsKCkge1xuXHRcdCAgICB2YXIgdG9rZW4gPSB0aGlzLl9wZWVrVG9rZW5JbXBsKCk7XG5cdFx0ICAgIGlmICh0b2tlbikge1xuXHRcdCAgICAgIHRoaXMuc3RyZWFtID0gdGhpcy5zdHJlYW0uc2xpY2UodG9rZW4ubGVuZ3RoKTtcblx0XHQgICAgICByZXR1cm4gdG9rZW47XG5cdFx0ICAgIH1cblx0XHQgIH07XG5cdFxuXHRcdCAgLyoqXG5cdFx0ICAgKiBUaGUgaW1wbGVtZW50YXRpb24gb2YgdG9rZW4gcG
1Vla2luZy5cblx0XHQgICAqXG5cdFx0ICAgKiBAcmV0dXJucyB7P1Rva2VufVxuXHRcdCAgICovXG5cdFxuXHRcblx0XHQgIEh0bWxQYXJzZXIucHJvdG90eXBlLl9wZWVrVG9rZW5JbXBsID0gZnVuY3Rpb24gX3BlZWtUb2tlbkltcGwoKSB7XG5cdFx0ICAgIGZvciAodmFyIHR5cGUgaW4gZGV0ZWN0KSB7XG5cdFx0ICAgICAgaWYgKGRldGVjdC5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkge1xuXHRcdCAgICAgICAgaWYgKGRldGVjdFt0eXBlXS50ZXN0KHRoaXMuc3RyZWFtKSkge1xuXHRcdCAgICAgICAgICB2YXIgdG9rZW4gPSBzdHJlYW1SZWFkZXJzW3R5cGVdKHRoaXMuc3RyZWFtKTtcblx0XG5cdFx0ICAgICAgICAgIGlmICh0b2tlbikge1xuXHRcdCAgICAgICAgICAgIGlmICh0b2tlbi50eXBlID09PSAnc3RhcnRUYWcnICYmIC9zY3JpcHR8c3R5bGUvaS50ZXN0KHRva2VuLnRhZ05hbWUpKSB7XG5cdFx0ICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcblx0XHQgICAgICAgICAgICB9IGVsc2Uge1xuXHRcdCAgICAgICAgICAgICAgdG9rZW4udGV4dCA9IHRoaXMuc3RyZWFtLnN1YnN0cigwLCB0b2tlbi5sZW5ndGgpO1xuXHRcdCAgICAgICAgICAgICAgcmV0dXJuIHRva2VuO1xuXHRcdCAgICAgICAgICAgIH1cblx0XHQgICAgICAgICAgfVxuXHRcdCAgICAgICAgfVxuXHRcdCAgICAgIH1cblx0XHQgICAgfVxuXHRcdCAgfTtcblx0XG5cdFx0ICAvKipcblx0XHQgICAqIFRoZSBwdWJsaWMgdG9rZW4gcGVla2luZyBpbnRlcmZhY2UuICBEZWxlZ2F0ZXMgdG8gdGhlIGJhc2ljIHRva2VuIHBlZWtpbmdcblx0XHQgICAqIG9yIGEgdmVyc2lvbiB0aGF0IHBlcmZvcm1zIGZpeHVwcyBkZXBlbmRpbmcgb24gdGhlIGBhdXRvRml4YCBzZXR0aW5nIGluXG5cdFx0ICAgKiBvcHRpb25zLlxuXHRcdCAgICpcblx0XHQgICAqIEByZXR1cm5zIHtvYmplY3R9XG5cdFx0ICAgKi9cblx0XG5cdFxuXHRcdCAgSHRtbFBhcnNlci5wcm90b3R5cGUucGVla1Rva2VuID0gZnVuY3Rpb24gcGVla1Rva2VuKCkge1xuXHRcdCAgICByZXR1cm4gdGhpcy5fcGVla1Rva2VuKCk7XG5cdFx0ICB9O1xuXHRcblx0XHQgIC8qKlxuXHRcdCAgICogVGhlIHB1YmxpYyB0b2tlbiByZWFkaW5nIGludGVyZmFjZS4gIERlbGVnYXRlcyB0byB0aGUgYmFzaWMgdG9rZW4gcmVhZGluZ1xuXHRcdCAgICogb3IgYSB2ZXJzaW9uIHRoYXQgcGVyZm9ybXMgZml4dXBzIGRlcGVuZGluZyBvbiB0aGUgYGF1dG9GaXhgIHNldHRpbmcgaW5cblx0XHQgICAqIG9wdGlvbnMuXG5cdFx0ICAgKlxuXHRcdCAgICogQHJldHVybnMge29iamVjdH1cblx0XHQgICAqL1xuXHRcblx0XG5cdFx0ICBIdG1sUGFyc2VyLnByb3RvdHlwZS5yZWFkVG9rZW4gPSBmdW5jdGlvbiByZWFkVG9rZW4oKSB7XG5cdFx0ICAgIHJldHVybiB0aGlzLl9yZWFkVG9rZW4oKTtcblx0XHQgIH07XG5cdFxuXHRcdCAgLyoqXG5cdFx0ICAgKiBSZWFkIHRva2VucyBhbmQgaGFuZCB0byB0aGUgZ2l2ZW4gaGFuZGxlcnMuXG5cdFx0ICAgKlxuXHRcdCAgICogQHBhcmFtIHtPYmplY3R9IGhhbmRsZXJzIFRoZSBoYW5kbGVycyB0byB1c2UgZm9yIHRoZSBkaWZmZXJlbnQgdG9rZW5zLlxuXHRcdCAgICovXG5cdFxuXHRcblx0XHQgIEh0bWxQYXJzZXIucHJvdG90eXBlLnJlYWRUb2tlbnMgPSBmdW5jdGlvbiByZWFkVG9rZW5zKGhhbmRsZXJzKSB7XG5cdFx0ICAgIHZhciB0b2sgPSB2b2lkIDA7XG5cdFx0ICAgIHdoaWxlICh0b2sgPSB0aGlzLnJlYWRUb2tlbigpKSB7XG5cdFx0ICAgICAgLy8gY29udGludWUgdW50aWwgd2UgZ2V0IGFuIGV4cGxpY2l0IFwiZmFsc2VcIiByZXR1cm5cblx0XHQgICAgICBpZiAoaGFuZGxlcnNbdG9rLnR5cGVdICYmIGhhbmRsZXJzW3Rvay50eXBlXSh0b2spID09PSBmYWxzZSkge1xuXHRcdCAgICAgICAgcmV0dXJuO1xuXHRcdCAgICAgIH1cblx0XHQgICAgfVxuXHRcdCAgfTtcblx0XG5cdFx0ICAvKipcblx0XHQgICAqIENsZWFycyB0aGUgcGFyc2Ugc3RyZWFtLlxuXHRcdCAgICpcblx0XHQgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjb250ZW50cyBvZiB0aGUgcGFyc2Ugc3RyZWFtIGJlZm9yZSBjbGVhcmluZy5cblx0XHQgICAqL1xuXHRcblx0XG5cdFx0ICBIdG1sUGFyc2VyLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uIGNsZWFyKCkge1xuXHRcdCAgICB2YXIgcmVzdCA9IHRoaXMuc3RyZWFtO1xuXHRcdCAgICB0aGlzLnN0cmVhbSA9ICcnO1xuXHRcdCAgICByZXR1cm4gcmVzdDtcblx0XHQgIH07XG5cdFxuXHRcdCAgLyoqXG5cdFx0ICAgKiBSZXR1cm5zIHRoZSByZXN0IG9mIHRoZSBwYXJzZSBzdHJlYW0uXG5cdFx0ICAgKlxuXHRcdCAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGNvbnRlbnRzIG9mIHRoZSBwYXJzZSBzdHJlYW0uXG5cdFx0ICAgKi9cblx0XG5cdFxuXHRcdCAgSHRtbFBhcnNlci5wcm90b3R5cGUucmVzdCA9IGZ1bmN0aW9uIHJlc3QoKSB7XG5cdFx0ICAgIHJldHVybiB0aGlzLnN0cmVhbTtcblx0XHQgIH07XG5cdFxuXHRcdCAgcmV0dXJuIEh0bWxQYXJzZXI7XG5cdFx0fSgpO1xuXHRcblx0XHRleHBvcnRzWydkZWZhdWx0J10gPSBIdG1sUGFyc2VyO1xuXHRcblx0XG5cdFx0SHRtbFBhcnNlci50b2tlblRvU3RyaW5nID0gZnVuY3Rpb24gKHRvaykge1xuXHRcdCAgcmV0dXJuIHRvay50b1N0cmluZygpO1xuXHRcdH07XG5cdFxuXHRcdEh0bWxQYXJzZXIuZXNjYXBlQXR0cmlidXRlcyA9IGZ1bmN0aW9uIChhdHRycykge1xuXHRcdCAgdmFyIGVzY2FwZWRBdHRycyA9IHt9O1xuXHRcblx0XHQgIGZvciAodmFyIG5hbWUgaW4gYXR0cnMpIHtcblx0XHQgICAgaWYgKGF0dHJzLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG5cdFx0ICAgICAgZXNjYXBlZEF0dHJzW25hbWVdID0gKDAsIF91dGlscy5lc2NhcGVRdW90ZXMpKGF0dHJzW25hbWVdLCBudWxsKTtcblx0XHQgICAgfVxuXHRcdCAgfVxuXHRcblx0XHQgIHJldHVybiBlc2NhcGVkQXR0cnM7XG5cdFx0fTtcblx0XG5cdFx0SHRtbFBhcnNlci5zdXBwb3J0cyA9IHN1cHBvcnRzO1xuXHRcblx0XHRmb3IgKHZhciBrZXkgaW4gc3VwcG9ydHMpIHtcblx0XHQgIGlmIChzdXBwb3J0cy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0ICAgIEh0bWxQYXJzZXIuYnJvd3Nlckhhc0ZsYXcgPSBIdG1sUGFyc2VyLmJyb3dzZXJIYXNGbGF3IHx8ICFzdXBwb3J0c1trZXldICYmIGtleTtcblx0XHQgIH1cblx0XHR9XG5cdFxuXHQvKioqLyB9LFxuXHQvKiAyICovXG5cdC8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXHRcblx0XHQndXNlIHN0cmljdCc7XG5cdFxuXHRcdGV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cdFx0dmFyIHRhZ1NvdXAgPSBmYWxzZTtcblx0XHR2YXIgc2VsZkNsb3NlID0gZmFsc2U7XG5cdFxuXHRcdHZhciB3b3JrID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcblx0XHR0cnkge1xuXHRcdCAgdmFyIGh0bWwgPSAnPFA+PEk+PC9QPjwvST4nO1xuXHRcdCAgd29yay5pbm5lckhUTUwgPSBodG1sO1xuXHRcdCAgZXhwb3J0cy50YWdTb3VwID0gdGFnU291cCA9IHdvcmsuaW5uZXJIVE1MICE9PSBodG1sO1xuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHQgIGV4cG9ydHMudGFnU291cCA9IHRhZ1NvdXAgPSBmYWxzZTtcblx0XHR9XG5cdFxuXHRcdHRyeSB7XG5cdFx0ICB3b3JrLmlubmVySFRNTCA9ICc8UD48aT48UD48L1A+PC9pPjwvUD4nO1xuXHRcdCAgZXhwb3J0cy5zZWxmQ2xvc2UgPSBzZWxmQ2xvc2UgPSB3b3JrLmNoaWxkTm9kZXMubGVuZ3RoID09PSAyO1xuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHQgIGV4cG9ydHMuc2VsZkNsb3NlID0gc2VsZkNsb3NlID0gZmFsc2U7XG5cdFx0fVxuXHRcblx0XHR3b3JrID0gbnVsbDtcblx0XG5cdFx0ZXhwb3J0cy50YWdTb3VwID0gdGFnU291cDtcblx0XHRleHBvcnRzLnNlbGZDbG9zZSA9IHNlbGZDbG9zZTtcblx0XG5cdC8qKiovIH0sXG5cdC8qIDMgKi9cblx0LyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cdFxuXHRcdCd1c2Ugc3RyaWN0Jztcblx0XG5cdFx0ZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblx0XG5cdFx0dmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybi
1BvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07XG5cdFxuXHRcdGV4cG9ydHMuY29tbWVudCA9IGNvbW1lbnQ7XG5cdFx0ZXhwb3J0cy5jaGFycyA9IGNoYXJzO1xuXHRcdGV4cG9ydHMuc3RhcnRUYWcgPSBzdGFydFRhZztcblx0XHRleHBvcnRzLmF0b21pY1RhZyA9IGF0b21pY1RhZztcblx0XHRleHBvcnRzLmVuZFRhZyA9IGVuZFRhZztcblx0XG5cdFx0dmFyIF90b2tlbnMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpO1xuXHRcblx0XHQvKipcblx0XHQgKiBSZWd1bGFyIEV4cHJlc3Npb25zIGZvciBwYXJzaW5nIHRhZ3MgYW5kIGF0dHJpYnV0ZXNcblx0XHQgKlxuXHRcdCAqIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdFx0dmFyIFJFR0VYRVMgPSB7XG5cdFx0ICBzdGFydFRhZzogL148KFtcXC1BLVphLXowLTlfXSspKCg/OlxccytbXFx3XFwtXSsoPzpcXHMqPT9cXHMqKD86KD86XCJbXlwiXSpcIil8KD86J1teJ10qJyl8W14+XFxzXSspKT8pKilcXHMqKFxcLz8pPi8sXG5cdFx0ICBlbmRUYWc6IC9ePFxcLyhbXFwtQS1aYS16MC05X10rKVtePl0qPi8sXG5cdFx0ICBhdHRyOiAvKD86KFtcXC1BLVphLXowLTlfXSspXFxzKj1cXHMqKD86KD86XCIoKD86XFxcXC58W15cIl0pKilcIil8KD86JygoPzpcXFxcLnxbXiddKSopJyl8KFtePlxcc10rKSkpfCg/OihbXFwtQS1aYS16MC05X10rKShcXHN8JCkrKS9nLFxuXHRcdCAgZmlsbEF0dHI6IC9eKGNoZWNrZWR8Y29tcGFjdHxkZWNsYXJlfGRlZmVyfGRpc2FibGVkfGlzbWFwfG11bHRpcGxlfG5vaHJlZnxub3Jlc2l6ZXxub3NoYWRlfG5vd3JhcHxyZWFkb25seXxzZWxlY3RlZCkkL2lcblx0XHR9O1xuXHRcblx0XHQvKipcblx0XHQgKiBSZWFkcyBhIGNvbW1lbnQgdG9rZW5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHJlYW0gVGhlIGlucHV0IHN0cmVhbVxuXHRcdCAqIEByZXR1cm5zIHtDb21tZW50VG9rZW59XG5cdFx0ICovXG5cdFx0ZnVuY3Rpb24gY29tbWVudChzdHJlYW0pIHtcblx0XHQgIHZhciBpbmRleCA9IHN0cmVhbS5pbmRleE9mKCctLT4nKTtcblx0XHQgIGlmIChpbmRleCA+PSAwKSB7XG5cdFx0ICAgIHJldHVybiBuZXcgX3Rva2Vucy5Db21tZW50VG9rZW4oc3RyZWFtLnN1YnN0cig0LCBpbmRleCAtIDEpLCBpbmRleCArIDMpO1xuXHRcdCAgfVxuXHRcdH1cblx0XG5cdFx0LyoqXG5cdFx0ICogUmVhZHMgbm9uLXRhZyBjaGFyYWN0ZXJzLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IHN0cmVhbSBUaGUgaW5wdXQgc3RyZWFtXG5cdFx0ICogQHJldHVybnMge0NoYXJzVG9rZW59XG5cdFx0ICovXG5cdFx0ZnVuY3Rpb24gY2hhcnMoc3RyZWFtKSB7XG5cdFx0ICB2YXIgaW5kZXggPSBzdHJlYW0uaW5kZXhPZignPCcpO1xuXHRcdCAgcmV0dXJuIG5ldyBfdG9rZW5zLkNoYXJzVG9rZW4oaW5kZXggPj0gMCA/IGluZGV4IDogc3RyZWFtLmxlbmd0aCk7XG5cdFx0fVxuXHRcblx0XHQvKipcblx0XHQgKiBSZWFkcyBzdGFydCB0YWcgdG9rZW4uXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyZWFtIFRoZSBpbnB1dCBzdHJlYW1cblx0XHQgKiBAcmV0dXJucyB7U3RhcnRUYWdUb2tlbn1cblx0XHQgKi9cblx0XHRmdW5jdGlvbiBzdGFydFRhZyhzdHJlYW0pIHtcblx0XHQgIHZhciBlbmRUYWdJbmRleCA9IHN0cmVhbS5pbmRleE9mKCc+Jyk7XG5cdFx0ICBpZiAoZW5kVGFnSW5kZXggIT09IC0xKSB7XG5cdFx0ICAgIHZhciBtYXRjaCA9IHN0cmVhbS5tYXRjaChSRUdFWEVTLnN0YXJ0VGFnKTtcblx0XHQgICAgaWYgKG1hdGNoKSB7XG5cdFx0ICAgICAgdmFyIF9yZXQgPSBmdW5jdGlvbiAoKSB7XG5cdFx0ICAgICAgICB2Y
1XIgYXR0cnMgPSB7fTtcblx0XHQgICAgICAgIHZhciBib29sZWFuQXR0cnMgPSB7fTtcblx0XHQgICAgICAgIHZhciByZXN0ID0gbWF0Y2hbMl07XG5cdFxuXHRcdCAgICAgICAgbWF0Y2hbMl0ucmVwbGFjZShSRUdFWEVTLmF0dHIsIGZ1bmN0aW9uIChtYXRjaCwgbmFtZSkge1xuXHRcdCAgICAgICAgICBpZiAoIShhcmd1bWVudHNbMl0gfHwgYXJndW1lbnRzWzNdIHx8IGFyZ3VtZW50c1s0XSB8fCBhcmd1bWVudHNbNV0pKSB7XG5cdFx0ICAgICAgICAgICAgYXR0cnNbbmFtZV0gPSAnJztcblx0XHQgICAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudHNbNV0pIHtcblx0XHQgICAgICAgICAgICBhdHRyc1thcmd1bWVudHNbNV1dID0gJyc7XG5cdFx0ICAgICAgICAgICAgYm9vbGVhbkF0dHJzW2FyZ3VtZW50c1s1XV0gPSB0cnVlO1xuXHRcdCAgICAgICAgICB9IGVsc2Uge1xuXHRcdCAgICAgICAgICAgIGF0dHJzW25hbWVdID0gYXJndW1lbnRzWzJdIHx8IGFyZ3VtZW50c1szXSB8fCBhcmd1bWVudHNbNF0gfHwgUkVHRVhFUy5maWxsQXR0ci50ZXN0KG5hbWUpICYmIG5hbWUgfHwgJyc7XG5cdFx0ICAgICAgICAgIH1cblx0XG5cdFx0ICAgICAgICAgIHJlc3QgPSByZXN0LnJlcGxhY2UobWF0Y2gsICcnKTtcblx0XHQgICAgICAgIH0pO1xuXHRcblx0XHQgICAgICAgIHJldHVybiB7XG5cdFx0ICAgICAgICAgIHY6IG5ldyBfdG9rZW5zLlN0YXJ0VGFnVG9rZW4obWF0Y2hbMV0sIG1hdGNoWzBdLmxlbmd0aCwgYXR0cnMsIGJvb2xlYW5BdHRycywgISFtYXRjaFszXSwgcmVzdC5yZXBsYWNlKC9eW1xcc1xcdUZFRkZcXHhBMF0rfFtcXHNcXHVGRUZGXFx4QTBdKyQvZywgJycpKVxuXHRcdCAgICAgICAgfTtcblx0XHQgICAgICB9KCk7XG5cdFxuXHRcdCAgICAgIGlmICgodHlwZW9mIF9yZXQgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKF9yZXQpKSA9PT0gXCJvYmplY3RcIikgcmV0dXJuIF9yZXQudjtcblx0XHQgICAgfVxuXHRcdCAgfVxuXHRcdH1cblx0XG5cdFx0LyoqXG5cdFx0ICogUmVhZHMgYXRvbWljIHRhZyB0b2tlbi5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHJlYW0gVGhlIGlucHV0IHN0cmVhbVxuXHRcdCAqIEByZXR1cm5zIHtBdG9taWNUYWdUb2tlbn1cblx0XHQgKi9cblx0XHRmdW5jdGlvbiBhdG9taWNUYWcoc3RyZWFtKSB7XG5cdFx0ICB2YXIgc3RhcnQgPSBzdGFydFRhZyhzdHJlYW0pO1xuXHRcdCAgaWYgKHN0YXJ0KSB7XG5cdFx0ICAgIHZhciByZXN0ID0gc3RyZWFtLnNsaWNlKHN0YXJ0Lmxlbmd0aCk7XG5cdFx0ICAgIC8vIGZvciBvcHRpbWl6YXRpb24sIHdlIGNoZWNrIGZpcnN0IGp1c3QgZm9yIHRoZSBlbmQgdGFnXG5cdFx0ICAgIGlmIChyZXN0Lm1hdGNoKG5ldyBSZWdFeHAoJzxcXC9cXFxccyonICsgc3RhcnQudGFnTmFtZSArICdcXFxccyo+JywgJ2knKSkpIHtcblx0XHQgICAgICAvLyBjYXB0dXJpbmcgdGhlIGNvbnRlbnQgaXMgaW5lZmZpY2llbnQsIHNvIHdlIGRvIGl0IGluc2lkZSB0aGUgaWZcblx0XHQgICAgICB2YXIgbWF0Y2ggPSByZXN0Lm1hdGNoKG5ldyBSZWdFeHAoJyhbXFxcXHNcXFxcU10qPyk8XFwvXFxcXHMqJyArIHN0YXJ0LnRhZ05hbWUgKyAnXFxcXHMqPicsICdpJykpO1xuXHRcdCAgICAgIGlmIChtYXRjaCkge1xuXHRcdCAgICAgICAgcmV0dXJuIG5ldyBfdG9rZW5zLkF0b21pY1RhZ1Rva2VuKHN0YXJ0LnRhZ05hbWUsIG1hdGNoWzBdLmxlbmd0aCArIHN0YXJ0Lmxlbmd0aCwgc3RhcnQuYXR0cnMsIHN0YXJ0LmJvb2xlYW5BdHRycywgbWF0Y2hbMV0pO1xuXHRcdCAgICAgIH1cblx0XHQgICAgfVxuXHRcdCAgfVxuXHRcdH1cblx0XG5cdFx0LyoqXG5cdFx0ICogUmVhZHMgYW4gZW5kIHRhZyB0b2tlbi5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHJlYW0gVGhlIGlucHV0IHN0cmVhbVxuXHRcdCAqIEByZXR1cm5zIHtFbmRUYWdUb2tlbn1cblx0XHQgKi9cblx0XHRmdW5jdGlvbiBlbmRUYWcoc3RyZWFtKSB7XG5cdFx0ICB2YXIgbWF0Y2ggPSBzdHJlYW0ubWF0Y2goUkVHRVhFUy5lbmRUYWcpO1xuXHRcdCAgaWYgKG1hdGNoKSB7XG5cdFx0ICAgIHJldHVybiBuZXcgX3Rva2Vucy5FbmRUYWdUb2tlbihtYXRjaFsxXSwgbWF0Y2hbMF0ubGVuZ3RoKTtcblx0XHQgIH1cblx0XHR9XG5cdFxuXHQvKioqLyB9LFxuXHQvKiA0ICovXG5cdC8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXHRcblx0XHQndXNlIHN0cmljdCc7XG5cdFxuXHRcdGV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cdFx0ZXhwb3J0cy5FbmRUYWdUb2tlbiA9IGV4cG9ydHMuQXRvbWljVGFnVG9rZW4gPSBleHBvcnRzLlN0YXJ0VGFnVG9rZW4gPSBleHBvcnRzLlRhZ1Rva2VuID0gZXhwb3J0cy5DaGFyc1Rva2VuID0gZXhwb3J0cy5Db21tZW50VG9rZW4gPSBleHBvcnRzLlRva2VuID0gdW5kZWZpbmVkO1xuXHRcblx0XHR2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg1KTtcblx0XG5cdFx0ZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblx0XG5cdFx0LyoqXG5cdFx0ICogVG9rZW4gaXMgYSBiYXNlIGNsYXNzIGZvciBhbGwgdG9rZW4gdHlwZXMgcGFyc2VkLiAgTm90ZSB3ZSBkb24ndCBhY3R1YWxseVxuXHRcdCAqIHVzZSBpbnRoZXJpdGFuY2UgZHVlIHRvIElFOCdzIG5vbi1leGlzdGVudCBFUzUgc3VwcG9ydC5cblx0XHQgKi9cblx0XG5cdFx0dmFyIFRva2VuID1cblx0XHQvKipcblx0XHQgKiBDb25zdHJ1Y3Rvci5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFRoZSB0eXBlIG9mIHRoZSBUb2tlbi5cblx0XHQgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIFRva2VuIHRleHQuXG5cdFx0ICovXG5cdFx0ZXhwb3J0cy5Ub2tlbiA9IGZ1bmN0aW9uIFRva2VuKHR5cGUsIGxlbmd0aCkge1xuXHRcdCAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFRva2VuKTtcblx0XG5cdFx0ICB0aGlzLnR5cGUgPSB0eXBlO1xuXHRcdCAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XG5cdFx0ICB0aGlzLnRleHQgPSAnJztcblx0XHR9O1xuXHRcblx0XHQvKipcblx0XHQgKiBDb21tZW50VG9rZW4gcmVwcmVzZW50cyBjb21tZW50IHRhZ3MuXG5cdFx0ICovXG5cdFxuXHRcblx0XHR2YXIgQ29tbWVudFRva2VuID0gZXhwb3J0cy5Db21tZW50VG9rZW4gPSBmdW5jdGlvbiAoKSB7XG5cdFx0ICAvKipcblx0XHQgICAqIENvbnN0cnVjdG9yLlxuXHRcdCAgICpcblx0XHQgICAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50IFRoZSBjb250ZW50IG9mIHRoZSBjb21tZW50XG5cdFx0ICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIFRva2VuIHRleHQuXG5cdFx0ICAgKi9cblx0XG5cdFx0ICBmdW5jdGlvbiBDb21tZW50VG9rZW4oY29udGVudCwgbGVuZ3RoKSB7XG5cdFx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDb21tZW50VG9rZW4pO1xuXHRcblx0XHQgICAgdGhpcy50eXBlID0gJ2NvbW1lbnQnO1xuXHRcdCAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aCB8fCAoY29udGVudCA/IGNvbnRlbnQubGVuZ3RoIDogMCk7XG5cdFx0ICAgIHRoaXMudGV4dCA9ICcnO1xuXHRcdCAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50O1xuXHRcdCAgfVxuXHRcblx0XHQgIENvbW1lbnRUb2tlbi5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcblx0XHQgICAgcmV0dXJuICc8IS0tJyArIHRoaXMuY29udGVudDtcblx0XHQgIH07XG5cdFxuXHRcdCAgcmV0dXJuIENvbW1lbnRUb2tlbjtcblx0XHR9KCk7XG5cdFxuXHRcdC8qKlxuXHRcdCAqIENoYXJzVG9rZW4gcmVwcmVzZW50cyBub24tdGFnIGNoYXJhY3RlcnMuXG5cdFx0ICovXG5cdFxuXHRcblx0XHR2YXIgQ2hhcnNUb2tlbiA9IGV4cG9ydHMuQ2hhcnNUb2tlbiA9IGZ1bmN0aW9uICgpIHtcblx0XHQgIC8qKlxuXHRcdCAgICogQ29uc3RydWN0b3IuXG5cdFx0ICAgKlxuXHRcdCAgICogQHBhcmFtIHtOdW1iZXJ9IGxlbmd0aCBUaGUgbGVuZ3RoIG9mIHRoZSBUb2tlbiB0ZXh0LlxuXHRcdCAgICovXG5cdFxuXHRcdCAgZnVuY3Rpb24gQ2hhcnNUb2tlbihsZW5ndGgpIHtcblx0XHQgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIENoYXJzVG9rZW4pO1xuXHRcblx0XHQgICAgdGhpcy50eXBlID0gJ2NoYXJzJztcblx0XHQgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XG5cdFx0ICAgIHRoaXMudGV4dCA9ICcnO1xuXHRcdCAgfVxuXHRcblx0XHQgIENoYXJzVG9rZW4ucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmc
1oKSB7XG5cdFx0ICAgIHJldHVybiB0aGlzLnRleHQ7XG5cdFx0ICB9O1xuXHRcblx0XHQgIHJldHVybiBDaGFyc1Rva2VuO1xuXHRcdH0oKTtcblx0XG5cdFx0LyoqXG5cdFx0ICogVGFnVG9rZW4gaXMgYSBiYXNlIGNsYXNzIGZvciBhbGwgdGFnLWJhc2VkIFRva2Vucy5cblx0XHQgKi9cblx0XG5cdFxuXHRcdHZhciBUYWdUb2tlbiA9IGV4cG9ydHMuVGFnVG9rZW4gPSBmdW5jdGlvbiAoKSB7XG5cdFx0ICAvKipcblx0XHQgICAqIENvbnN0cnVjdG9yLlxuXHRcdCAgICpcblx0XHQgICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFRoZSB0eXBlIG9mIHRoZSB0b2tlbi5cblx0XHQgICAqIEBwYXJhbSB7c3RyaW5nfSB0YWdOYW1lIFRoZSB0YWcgbmFtZS5cblx0XHQgICAqIEBwYXJhbSB7TnVtYmVyfSBsZW5ndGggVGhlIGxlbmd0aCBvZiB0aGUgVG9rZW4gdGV4dC5cblx0XHQgICAqIEBwYXJhbSB7T2JqZWN0fSBhdHRycyBUaGUgZGljdGlvbmFyeSBvZiBhdHRyaWJ1dGVzIGFuZCB2YWx1ZXNcblx0XHQgICAqIEBwYXJhbSB7T2JqZWN0fSBib29sZWFuQXR0cnMgSWYgYW4gZW50cnkgaGFzICd0cnVlJyB0aGVuIHRoZSBhdHRyaWJ1dGVcblx0XHQgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgYSBib29sZWFuIGF0dHJpYnV0ZVxuXHRcdCAgICovXG5cdFxuXHRcdCAgZnVuY3Rpb24gVGFnVG9rZW4odHlwZSwgdGFnTmFtZSwgbGVuZ3RoLCBhdHRycywgYm9vbGVhbkF0dHJzKSB7XG5cdFx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUYWdUb2tlbik7XG5cdFxuXHRcdCAgICB0aGlzLnR5cGUgPSB0eXBlO1xuXHRcdCAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcblx0XHQgICAgdGhpcy50ZXh0ID0gJyc7XG5cdFx0ICAgIHRoaXMudGFnTmFtZSA9IHRhZ05hbWU7XG5cdFx0ICAgIHRoaXMuYXR0cnMgPSBhdHRycztcblx0XHQgICAgdGhpcy5ib29sZWFuQXR0cnMgPSBib29sZWFuQXR0cnM7XG5cdFx0ICAgIHRoaXMudW5hcnkgPSBmYWxzZTtcblx0XHQgICAgdGhpcy5odG1sNVVuYXJ5ID0gZmFsc2U7XG5cdFx0ICB9XG5cdFxuXHRcdCAgLyoqXG5cdFx0ICAgKiBGb3JtYXRzIHRoZSBnaXZlbiB0b2tlbiB0YWcuXG5cdFx0ICAgKlxuXHRcdCAgICogQHBhcmFtIHtUYWdUb2tlbn0gdG9rIFRoZSBUYWdUb2tlbiB0byBmb3JtYXQuXG5cdFx0ICAgKiBAcGFyYW0gez9zdHJpbmd9IFtjb250ZW50PW51bGxdIFRoZSBjb250ZW50IG9mIHRoZSB0b2tlbi5cblx0XHQgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBmb3JtYXR0ZWQgdGFnLlxuXHRcdCAgICovXG5cdFxuXHRcblx0XHQgIFRhZ1Rva2VuLmZvcm1hdFRhZyA9IGZ1bmN0aW9uIGZvcm1hdFRhZyh0b2spIHtcblx0XHQgICAgdmFyIGNvbnRlbnQgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyBudWxsIDogYXJndW1lbnRzWzFdO1xuXHRcblx0XHQgICAgdmFyIHN0ciA9ICc8JyArIHRvay50YWdOYW1lO1xuXHRcdCAgICBmb3IgKHZhciBrZXkgaW4gdG9rLmF0dHJzKSB7XG5cdFx0ICAgICAgaWYgKHRvay5hdHRycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0ICAgICAgICBzdHIgKz0gJyAnICsga2V5O1xuXHRcblx0XHQgICAgICAgIHZhciB2YWwgPSB0b2suYXR0cnNba2V5XTtcblx0XHQgICAgICAgIGlmICh0eXBlb2YgdG9rLmJvb2xlYW5BdHRycyA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIHRvay5ib29sZWFuQXR0cnNba2V5XSA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHQgICAgICAgICAgc3RyICs9ICc9XCInICsgKDAsIF91dGlscy5lc2NhcGVRdW90ZXMpKHZhbCkgKyAnXCInO1xuXHRcdCAgICAgICAgfVxuXHRcdCAgICAgIH1cblx0XHQgICAgfVxuXHRcblx0XHQgICAgaWYgKHRvay5yZXN0KSB7XG5cdFx0ICAgICAgc3RyICs9ICcgJyArIHRvay5yZXN0O1xuXHRcdCAgICB9XG5cdFxuXHRcdCAgICBpZiAodG9rLnVuYXJ5ICYmICF0b2suaHRtbDVVbmFyeSkge1xuXHRcdCAgICAgIHN0ciArPSAnLz4nO1xuXHRcdCAgICB9IGVsc2Uge1xuXHRcdCAgICAgIHN0ciArPSAnPic7XG5cdFx0ICAgIH1cblx0XG5cdFx0ICAgIGlmIChjb250ZW50ICE9PSB1bmRlZmluZWQgJiYgY29udGVudCAhPT0gbnVsbCkge1xuXHRcdCAgICAgIHN0ciArPSBjb250ZW50ICsgJzwvJyArIHRvay50YWdOYW1lICsgJz4nO1xuXHRcdCAgICB9XG5cdFxuXHRcdCAgICByZXR1cm4gc3RyO1xuXHRcdCAgfTtcblx0XG5cdFx0ICByZXR1cm4gVGFnVG9rZW47XG5cdFx0fSgpO1xuXHRcblx0XHQvKipcblx0XHQgKiBTdGFydFRhZ1Rva2VuIHJlcHJlc2VudHMgYSBzdGFydCB0b2tlbi5cblx0XHQgKi9cblx0XG5cdFxuXHRcdHZhciBTdGFydFRhZ1Rva2VuID0gZXhwb3J0cy5TdGFydFRhZ1Rva2VuID0gZnVuY3Rpb24gKCkge1xuXHRcdCAgLyoqXG5cdFx0ICAgKiBDb25zdHJ1Y3Rvci5cblx0XHQgICAqXG5cdFx0ICAgKiBAcGFyYW0ge3N0cmluZ30gdGFnTmFtZSBUaGUgdGFnIG5hbWUuXG5cdFx0ICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIFRva2VuIHRleHRcblx0XHQgICAqIEBwYXJhbSB7T2JqZWN0fSBhdHRycyBUaGUgZGljdGlvbmFyeSBvZiBhdHRyaWJ1dGVzIGFuZCB2YWx1ZXNcblx0XHQgICAqIEBwYXJhbSB7T2JqZWN0fSBib29sZWFuQXR0cnMgSWYgYW4gZW50cnkgaGFzICd0cnVlJyB0aGVuIHRoZSBhdHRyaWJ1dGVcblx0XHQgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgYSBib29sZWFuIGF0dHJpYnV0ZVxuXHRcdCAgICogQHBhcmFtIHtib29sZWFufSB1bmFyeSBUcnVlIGlmIHRoZSB0YWcgaXMgYSB1bmFyeSB0YWdcblx0XHQgICAqIEBwYXJhbSB7c3RyaW5nfSByZXN0IFRoZSByZXN0IG9mIHRoZSBjb250ZW50LlxuXHRcdCAgICovXG5cdFxuXHRcdCAgZnVuY3Rpb24gU3RhcnRUYWdUb2tlbih0YWdOYW1lLCBsZW5ndGgsIGF0dHJzLCBib29sZWFuQXR0cnMsIHVuYXJ5LCByZXN0KSB7XG5cdFx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTdGFydFRhZ1Rva2VuKTtcblx0XG5cdFx0ICAgIHRoaXMudHlwZSA9ICdzdGFydFRhZyc7XG5cdFx0ICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoO1xuXHRcdCAgICB0aGlzLnRleHQgPSAnJztcblx0XHQgICAgdGhpcy50YWdOYW1lID0gdGFnTmFtZTtcblx0XHQgICAgdGhpcy5hdHRycyA9IGF0dHJzO1xuXHRcdCAgICB0aGlzLmJvb2xlYW5BdHRycyA9IGJvb2xlYW5BdHRycztcblx0XHQgICAgdGhpcy5odG1sNVVuYXJ5ID0gZmFsc2U7XG5cdFx0ICAgIHRoaXMudW5hcnkgPSB1bmFyeTtcblx0XHQgICAgdGhpcy5yZXN0ID0gcmVzdDtcblx0XHQgIH1cblx0XG5cdFx0ICBTdGFydFRhZ1Rva2VuLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuXHRcdCAgICByZXR1cm4gVGFnVG9rZW4uZm9ybWF0VGFnKHRoaXMpO1xuXHRcdCAgfTtcblx0XG5cdFx0ICByZXR1cm4gU3RhcnRUYWdUb2tlbjtcblx0XHR9KCk7XG5cdFxuXHRcdC8qKlxuXHRcdCAqIEF0b21pY1RhZ1Rva2VuIHJlcHJlc2VudHMgYW4gYXRvbWljIHRhZy5cblx0XHQgKi9cblx0XG5cdFxuXHRcdHZhciBBdG9taWNUYWdUb2tlbiA9IGV4cG9ydHMuQXRvbWljVGFnVG9rZW4gPSBmdW5jdGlvbiAoKSB7XG5cdFx0ICAvKipcblx0XHQgICAqIENvbnN0cnVjdG9yLlxuXHRcdCAgICpcblx0XHQgICAqIEBwYXJhbSB7c3RyaW5nfSB0YWdOYW1lIFRoZSBuYW1lIG9mIHRoZSB0YWcuXG5cdFx0ICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIHRhZyB0ZXh0LlxuXHRcdCAgICogQHBhcmFtIHtPYmplY3R9IGF0dHJzIFRoZSBhdHRyaWJ1dGVzLlxuXHRcdCAgICogQHBhcmFtIHtPYmplY3R9IGJvb2xlYW5BdHRycyBJZiBhbiBlbnRyeSBoYXMgJ3RydWUnIHRoZW4gdGhlIGF0dHJpYnV0ZVxuXHRcdCAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBhIGJvb2xlYW4gYXR0cmlidXRlXG5cdFx0ICAgKiBAcGFyYW0ge3N0cmluZ30gY29udGVudCBUaGUgY29udGVudCBvZiB0aGUgdGFnLlxuXHRcdCAgICovXG5cdFxuXHRcdCAgZnVuY3Rpb24gQXRvbWljVGFnVG9rZW4odGFnTmFtZSwgbGVuZ3RoLCBhdHRycywgYm9vbGVhbkF0dHJzLCBjb250ZW50KSB7XG5cdFx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBBdG9taWNUYWdUb2tlbik7XG5cdFxuXHRcdCAgICB0aGlzLnR5cGUgPSAnYXRvbWljVGFnJztcblx0XHQgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XG5cdFx0ICAgIHRoaXMudGV4dCA9ICcnO1xuXHRcdCAgICB0aGlzLnRhZ05hbWUgPSB0YWdOYW1lO1xuXHRcdCAgICB0aGlzLmF0dHJzID0gYXR0cnM7XG5cdFx0ICAgIHRoaXMuYm9vbGVhbkF0dHJzID0gYm9vbGVhbkF0dHJzO1xuXHRcdCAgICB0aGlzLnVuYXJ5ID0gZmFsc2U7XG5cdFx0ICAgIHRoaXMuaHRtbDVVbmFyeSA9IGZhbHNlO1xuXHRcdCAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50O1xuXHRcdCAgfVxuXHRcblx0XHQgIEF0b21pY1RhZ1Rva2VuLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuXHRcdCAgICByZXR1cm4gVGFnVG9rZW4uZm9ybWF0VGFnKHRoaXMsIHR
1oaXMuY29udGVudCk7XG5cdFx0ICB9O1xuXHRcblx0XHQgIHJldHVybiBBdG9taWNUYWdUb2tlbjtcblx0XHR9KCk7XG5cdFxuXHRcdC8qKlxuXHRcdCAqIEVuZFRhZ1Rva2VuIHJlcHJlc2VudHMgYW4gZW5kIHRhZy5cblx0XHQgKi9cblx0XG5cdFxuXHRcdHZhciBFbmRUYWdUb2tlbiA9IGV4cG9ydHMuRW5kVGFnVG9rZW4gPSBmdW5jdGlvbiAoKSB7XG5cdFx0ICAvKipcblx0XHQgICAqIENvbnN0cnVjdG9yLlxuXHRcdCAgICpcblx0XHQgICAqIEBwYXJhbSB7c3RyaW5nfSB0YWdOYW1lIFRoZSBuYW1lIG9mIHRoZSB0YWcuXG5cdFx0ICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIHRhZyB0ZXh0LlxuXHRcdCAgICovXG5cdFxuXHRcdCAgZnVuY3Rpb24gRW5kVGFnVG9rZW4odGFnTmFtZSwgbGVuZ3RoKSB7XG5cdFx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFbmRUYWdUb2tlbik7XG5cdFxuXHRcdCAgICB0aGlzLnR5cGUgPSAnZW5kVGFnJztcblx0XHQgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XG5cdFx0ICAgIHRoaXMudGV4dCA9ICcnO1xuXHRcdCAgICB0aGlzLnRhZ05hbWUgPSB0YWdOYW1lO1xuXHRcdCAgfVxuXHRcblx0XHQgIEVuZFRhZ1Rva2VuLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuXHRcdCAgICByZXR1cm4gJzwvJyArIHRoaXMudGFnTmFtZSArICc+Jztcblx0XHQgIH07XG5cdFxuXHRcdCAgcmV0dXJuIEVuZFRhZ1Rva2VuO1xuXHRcdH0oKTtcblx0XG5cdC8qKiovIH0sXG5cdC8qIDUgKi9cblx0LyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cdFxuXHRcdCd1c2Ugc3RyaWN0Jztcblx0XG5cdFx0ZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblx0XHRleHBvcnRzLmVzY2FwZVF1b3RlcyA9IGVzY2FwZVF1b3Rlcztcblx0XG5cdFx0LyoqXG5cdFx0ICogRXNjYXBlIHF1b3RlcyBpbiB0aGUgZ2l2ZW4gdmFsdWUuXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgVGhlIHZhbHVlIHRvIGVzY2FwZS5cblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gW2RlZmF1bHRWYWx1ZT0nJ10gVGhlIGRlZmF1bHQgdmFsdWUgdG8gcmV0dXJuIGlmIHZhbHVlIGlzIGZhbHN5LlxuXHRcdCAqIEByZXR1cm5zIHtzdHJpbmd9XG5cdFx0ICovXG5cdFx0ZnVuY3Rpb24gZXNjYXBlUXVvdGVzKHZhbHVlKSB7XG5cdFx0ICB2YXIgZGVmYXVsdFZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8gJycgOiBhcmd1bWVudHNbMV07XG5cdFxuXHRcdCAgLy8gVGhlcmUncyBubyBsb29rYmFjayBpbiBKUywgc28gLyhefFteXFxcXF0pXCIvIG9ubHkgbWF0Y2hlcyB0aGUgZmlyc3Qgb2YgdHdvIGBcImBzLlxuXHRcdCAgLy8gSW5zdGVhZCwganVzdCBtYXRjaCBhbnl0aGluZyBiZWZvcmUgYSBkb3VibGUtcXVvdGUgYW5kIGVzY2FwZSBpZiBpdCdzIG5vdCBhbHJlYWR5IGVzY2FwZWQuXG5cdFx0ICByZXR1cm4gIXZhbHVlID8gZGVmYXVsdFZhbHVlIDogdmFsdWUucmVwbGFjZSgvKFteXCJdKilcIi9nLCBmdW5jdGlvbiAoXywgcHJlZml4KSB7XG5cdFx0ICAgIHJldHVybiAoL1xcXFwvLnRlc3QocHJlZml4KSA/IHByZWZpeCArICdcIicgOiBwcmVmaXggKyAnXFxcXFwiJ1xuXHRcdCAgICApO1xuXHRcdCAgfSk7XG5cdFx0fVxuXHRcblx0LyoqKi8gfSxcblx0LyogNiAqL1xuXHQvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblx0XG5cdFx0J3VzZSBzdHJpY3QnO1xuXHRcblx0XHRleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXHRcdGV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZpeGVkUmVhZFRva2VuRmFjdG9yeTtcblx0XHQvKipcblx0XHQgKiBFbXB0eSBFbGVtZW50cyAtIEhUTUwgNC4wMVxuXHRcdCAqXG5cdFx0ICogQHR5cGUge1JlZ0V4cH1cblx0XHQgKi9cblx0XHR2YXIgRU1QVFkgPSAvXihBUkVBfEJBU0V8QkFTRUZPTlR8QlJ8Q09MfEZSQU1FfEhSfElNR3xJTlBVVHxJU0lOREVYfExJTkt8TUVUQXxQQVJBTXxFTUJFRCkkL2k7XG5cdFxuXHRcdC8qKlxuXHRcdCAqIEVsZW1lbnRzIHRoYXQgeW91IGNhbiBpbnRlbnRpb25hbGx5IGxlYXZlIG9wZW4gKGFuZCB3aGljaCBjbG9zZSB0aGVtc2VsdmVzKVxuXHRcdCAqXG5cdFx0ICogQHR5cGUge1JlZ0V4cH1cblx0XHQgKi9cblx0XHR2YXIgQ0xPU0VTRUxGID0gL14oQ09MR1JPVVB8RER8RFR8TEl8T1BUSU9OU3xQfFREfFRGT09UfFRIfFRIRUFEfFRSKSQvaTtcblx0XG5cdFx0LyoqXG5cdFx0ICogQ29ycmVjdHMgYSB0b2tlbi5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7VG9rZW59IHRvayBUaGUgdG9rZW4gdG8gY29ycmVjdFxuXHRcdCAqIEByZXR1cm5zIHtUb2tlbn0gVGhlIGNvcnJlY3RlZCB0b2tlblxuXHRcdCAqL1xuXHRcdGZ1bmN0aW9uIGNvcnJlY3QodG9rKSB7XG5cdFx0ICBpZiAodG9rICYmIHRvay50eXBlID09PSAnc3RhcnRUYWcnKSB7XG5cdFx0ICAgIHRvay51bmFyeSA9IEVNUFRZLnRlc3QodG9rLnRhZ05hbWUpIHx8IHRvay51bmFyeTtcblx0XHQgICAgdG9rLmh0bWw1VW5hcnkgPSAhL1xcLz4kLy50ZXN0KHRvay50ZXh0KTtcblx0XHQgIH1cblx0XHQgIHJldHVybiB0b2s7XG5cdFx0fVxuXHRcblx0XHQvKipcblx0XHQgKiBQZWVrcyBhdCB0aGUgbmV4dCB0b2tlbiBpbiB0aGUgcGFyc2VyLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtIdG1sUGFyc2VyfSBwYXJzZXIgVGhlIHBhcnNlclxuXHRcdCAqIEBwYXJhbSB7RnVuY3Rpb259IHJlYWRUb2tlbkltcGwgVGhlIHVuZGVybHlpbmcgcmVhZFRva2VuIGltcGxlbWVudGF0aW9uXG5cdFx0ICogQHJldHVybnMge1Rva2VufSBUaGUgbmV4dCB0b2tlblxuXHRcdCAqL1xuXHRcdGZ1bmN0aW9uIHBlZWtUb2tlbihwYXJzZXIsIHJlYWRUb2tlbkltcGwpIHtcblx0XHQgIHZhciB0bXAgPSBwYXJzZXIuc3RyZWFtO1xuXHRcdCAgdmFyIHRvayA9IGNvcnJlY3QocmVhZFRva2VuSW1wbCgpKTtcblx0XHQgIHBhcnNlci5zdHJlYW0gPSB0bXA7XG5cdFx0ICByZXR1cm4gdG9rO1xuXHRcdH1cblx0XG5cdFx0LyoqXG5cdFx0ICogQ2xvc2VzIHRoZSBsYXN0IHRva2VuLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtIdG1sUGFyc2VyfSBwYXJzZXIgVGhlIHBhcnNlclxuXHRcdCAqIEBwYXJhbSB7QXJyYXk8VG9rZW4+fSBzdGFjayBUaGUgc3RhY2tcblx0XHQgKi9cblx0XHRmdW5jdGlvbiBjbG9zZUxhc3QocGFyc2VyLCBzdGFjaykge1xuXHRcdCAgdmFyIHRvayA9IHN0YWNrLnBvcCgpO1xuXHRcblx0XHQgIC8vIHByZXBlbmQgY2xvc2UgdGFnIHRvIHN0cmVhbS5cblx0XHQgIHBhcnNlci5wcmVwZW5kKCc8LycgKyB0b2sudGFnTmFtZSArICc+Jyk7XG5cdFx0fVxuXHRcblx0XHQvKipcblx0XHQgKiBDcmVhdGUgYSBuZXcgdG9rZW4gc3RhY2suXG5cdFx0ICpcblx0XHQgKiBAcmV0dXJucyB7QXJyYXk8VG9rZW4+fVxuXHRcdCAqL1xuXHRcdGZ1bmN0aW9uIG5ld1N0YWNrKCkge1xuXHRcdCAgdmFyIHN0YWNrID0gW107XG5cdFxuXHRcdCAgc3RhY2subGFzdCA9IGZ1bmN0aW9uICgpIHtcblx0XHQgICAgcmV0dXJuIHRoaXNbdGhpcy5sZW5ndGggLSAxXTtcblx0XHQgIH07XG5cdFxuXHRcdCAgc3RhY2subGFzdFRhZ05hbWVFcSA9IGZ1bmN0aW9uICh0YWdOYW1lKSB7XG5cdFx0ICAgIHZhciBsYXN0ID0gdGhpcy5sYXN0KCk7XG5cdFx0ICAgIHJldHVybi
1BsYXN0ICYmIGxhc3QudGFnTmFtZSAmJiBsYXN0LnRhZ05hbWUudG9VcHBlckNhc2UoKSA9PT0gdGFnTmFtZS50b1VwcGVyQ2FzZSgpO1xuXHRcdCAgfTtcblx0XG5cdFx0ICBzdGFjay5jb250YWluc1RhZ05hbWUgPSBmdW5jdGlvbiAodGFnTmFtZSkge1xuXHRcdCAgICBmb3IgKHZhciBpID0gMCwgdG9rOyB0b2sgPSB0aGlzW2ldOyBpKyspIHtcblx0XHQgICAgICBpZiAodG9rLnRhZ05hbWUgPT09IHRhZ05hbWUpIHtcblx0XHQgICAgICAgIHJldHVybiB0cnVlO1xuXHRcdCAgICAgIH1cblx0XHQgICAgfVxuXHRcdCAgICByZXR1cm4gZmFsc2U7XG5cdFx0ICB9O1xuXHRcblx0XHQgIHJldHVybiBzdGFjaztcblx0XHR9XG5cdFxuXHRcdC8qKlxuXHRcdCAqIFJldHVybiBhIHJlYWRUb2tlbiBpbXBsZW1lbnRhdGlvbiB0aGF0IGZpeGVzIGlucHV0LlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtIdG1sUGFyc2VyfSBwYXJzZXIgVGhlIHBhcnNlclxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIE9wdGlvbnMgZm9yIGZpeGluZ1xuXHRcdCAqIEBwYXJhbSB7Ym9vbGVhbn0gb3B0aW9ucy50YWdTb3VwRml4IFRydWUgdG8gZml4IHRhZyBzb3VwIHNjZW5hcmlvc1xuXHRcdCAqIEBwYXJhbSB7Ym9vbGVhbn0gb3B0aW9ucy5zZWxmQ2xvc2VGaXggVHJ1ZSB0byBmaXggc2VsZi1jbG9zaW5nIHRhZ3Ncblx0XHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWFkVG9rZW5JbXBsIFRoZSB1bmRlcmx5aW5nIHJlYWRUb2tlbiBpbXBsZW1lbnRhdGlvblxuXHRcdCAqIEByZXR1cm5zIHtGdW5jdGlvbn1cblx0XHQgKi9cblx0XHRmdW5jdGlvbiBmaXhlZFJlYWRUb2tlbkZhY3RvcnkocGFyc2VyLCBvcHRpb25zLCByZWFkVG9rZW5JbXBsKSB7XG5cdFx0ICB2YXIgc3RhY2sgPSBuZXdTdGFjaygpO1xuXHRcblx0XHQgIHZhciBoYW5kbGVycyA9IHtcblx0XHQgICAgc3RhcnRUYWc6IGZ1bmN0aW9uIHN0YXJ0VGFnKHRvaykge1xuXHRcdCAgICAgIHZhciB0YWdOYW1lID0gdG9rLnRhZ05hbWU7XG5cdFxuXHRcdCAgICAgIGlmICh0YWdOYW1lLnRvVXBwZXJDYXNlKCkgPT09ICdUUicgJiYgc3RhY2subGFzdFRhZ05hbWVFcSgnVEFCTEUnKSkge1xuXHRcdCAgICAgICAgcGFyc2VyLnByZXBlbmQoJzxUQk9EWT4nKTtcblx0XHQgICAgICAgIHByZXBhcmVOZXh0VG9rZW4oKTtcblx0XHQgICAgICB9IGVsc2UgaWYgKG9wdGlvbnMuc2VsZkNsb3NlRml4ICYmIENMT1NFU0VMRi50ZXN0KHRhZ05hbWUpICYmIHN0YWNrLmNvbnRhaW5zVGFnTmFtZSh0YWdOYW1lKSkge1xuXHRcdCAgICAgICAgaWYgKHN0YWNrLmxhc3RUYWdOYW1lRXEodGFnTmFtZSkpIHtcblx0XHQgICAgICAgICAgY2xvc2VMYXN0KHBhcnNlciwgc3RhY2spO1xuXHRcdCAgICAgICAgfSBlbHNlIHtcblx0XHQgICAgICAgICAgcGFyc2VyLnByZXBlbmQoJzwvJyArIHRvay50YWdOYW1lICsgJz4nKTtcblx0XHQgICAgICAgICAgcHJlcGFyZU5leHRUb2tlbigpO1xuXHRcdCAgICAgICAgfVxuXHRcdCAgICAgIH0gZWxzZSBpZiAoIXRvay51bmFyeSkge1xuXHRcdCAgICAgICAgc3RhY2sucHVzaCh0b2spO1xuXHRcdCAgICAgIH1cblx0XHQgICAgfSxcblx0XHQgICAgZW5kVGFnOiBmdW5jdGlvbiBlbmRUYWcodG9rKSB7XG5cdFx0ICAgICAgdmFyIGxhc3QgPSBzdGFjay5sYXN0KCk7XG5cdFx0ICAgICAgaWYgKGxhc3QpIHtcblx0XHQgICAgICAgIGlmIChvcHRpb25zLnRhZ1NvdXBGaXggJiYgIXN0YWNrLmxhc3RUYWdOYW1lRXEodG9rLnRhZ05hbWUpKSB7XG5cdFx0ICAgICAgICAgIC8vIGNsZWFudXAgdGFnIHNvdXBcblx0XHQgICAgICAgICAgY2xvc2VMYXN0KHBhcnNlciwgc3RhY2spO1xuXHRcdCAgICAgICAgfSBlbHNlIHtcblx0XHQgICAgICAgICAgc3RhY2sucG9wKCk7XG5cdFx0ICAgICAgICB9XG5cdFx0ICAgICAgfSBlbHNlIGlmIChvcHRpb25zLnRhZ1NvdXBGaXgpIHtcblx0XHQgICAgICAgIC8vIGNsZWFudXAgdGFnIHNvdXAgcGFydCAyOiBza2lwIHRoaXMgdG9rZW5cblx0XHQgICAgICAgIHJlYWRUb2tlbkltcGwoKTtcblx0XHQgICAgICAgIHByZXBhcmVOZXh0VG9rZW4oKTtcblx0XHQgICAgICB9XG5cdFx0ICAgIH1cblx0XHQgIH07XG5cdFxuXHRcdCAgZnVuY3Rpb24gcHJlcGFyZU5leHRUb2tlbigpIHtcblx0XHQgICAgdmFyIHRvayA9IHBlZWtUb2tlbihwYXJzZXIsIHJlYWRUb2tlbkltcGwpO1xuXHRcdCAgICBpZiAodG9rICYmIGhhbmRsZXJzW3Rvay50eXBlXSkge1xuXHRcdCAgICAgIGhhbmRsZXJzW3Rvay50eXBlXSh0b2spO1xuXHRcdCAgICB9XG5cdFx0ICB9XG5cdFxuXHRcdCAgcmV0dXJuIGZ1bmN0aW9uIGZpeGVkUmVhZFRva2VuKCkge1xuXHRcdCAgICBwcmVwYXJlTmV4dFRva2VuKCk7XG5cdFx0ICAgIHJldHVybiBjb3JyZWN0KHJlYWRUb2tlbkltcGwoKSk7XG5cdFx0ICB9O1xuXHRcdH1cblx0XG5cdC8qKiovIH1cblx0LyoqKioqKi8gXSlcblx0fSk7XG5cdDtcblxuLyoqKi8gfSxcbi8qIDQgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5cdCd1c2Ugc3RyaWN0Jztcblx0XG5cdGV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cdFxuXHR2YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiID8gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfSA6IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTtcblx0XG5cdGV4cG9ydHMuZXhpc3R5ID0gZXhpc3R5O1xuXHRleHBvcnRzLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuXHRleHBvcnRzLmVhY2ggPSBlYWNoO1xuXHRleHBvcnRzLmVhY2hLZXkgPSBlYWNoS2V5O1xuXHRleHBvcnRzLmRlZmF1bHRzID0gZGVmYXVsdHM7XG5cdGV4cG9ydHMudG9BcnJheSA9IHRvQXJyYXk7XG5cdGV4cG9ydHMubGFzdCA9IGxhc3Q7XG5cdGV4cG9ydHMuaXNUYWcgPSBpc1RhZztcblx0ZXhwb3J0cy5pc1NjcmlwdCA9IGlzU2NyaXB0O1xuXHRleHBvcnRzLmlzU3R5bGUgPSBpc1N0eWxlO1xuXHQvKipcblx0ICogRGV0ZXJtaW5lIGlmIHRoZSB0aGluZyBpcyBub3QgdW5kZWZpbmVkIGFuZCBub3QgbnVsbC5cblx0ICpcblx0ICogQHBhcmFtIHsqfSB0aGluZyBUaGUgdGhpbmcgdG8gdGVzdFxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdGhpbmcgaXMgbm90IHVuZGVmaW5lZCBhbmQgbm90IG51bGwuXG5cdCAqL1xuXHRmdW5jdGlvbiBleGlzdHkodGhpbmcpIHtcblx0ICByZXR1cm4gdGhpbmcgIT09IHZvaWQgMCAmJiB0aGluZyAhPT0gbnVsbDtcblx0fVxuXHRcblx0LyoqXG5cdCAqIElzIHRoaXMgYSBmdW5jdGlvbj9cblx0ICpcblx0ICogQHBhcmFtIHsqfSB4IFRoZSB2YXJpYWJsZSB0byB0ZXN0XG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YXJpYWJsZSBpcyBhIGZ1bmN0aW9uXG5cdCAqL1xuXHRmdW5jdGlvbiBpc0Z1bmN0aW9uKHgpIHtcblx0ICByZXR1cm4gJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIHg7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBMb29wIG92ZXIgZWFjaCBpdGVtIGluIGFuIGFycmF5LWxpa2UgdmFsdWUuXG5cdCAqXG5cdCAqIEBwYXJhbSB7QXJyYXk8Kj59IGFyciBUaGUgYXJyYXkgdG8gbG9vcCBvdmVyXG5cdCAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBjYWxsXG5cdCAqIEBwYXJhbSB7P09iamVjdH0gdGFyZ2V0IFRoZSBvYmplY3QgdG8gYmluZCB0byB0aGUgZnVuY3Rpb25cblx0ICovXG5cdGZ1bmN0aW9uIGVhY2goYXJyLCBmbiwgdGFyZ2V0KSB7XG5cdCAgdmFyIGkgPSB2b2lkIDA7XG5cdCAgdmFyIGxlbiA9IGFyciAmJiBhcnIubGVuZ3RoIHx8IDA7XG5cdCAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdCAgICBmbi5jYWxsKHRhcmdldCwgYXJyW2ldLCBpKTtcblx0ICB9XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBMb29wIG92ZXIgZWFjaCBrZXkvdmFsdWUgcGFpciBpbiBhIGhhc2guXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvYmogVGhlIG9iamVjdFxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY2FsbFxuXHQgKiBAcGFyYW0gez9PYmplY3R9IHRhcmdldCBUaGUgb2JqZWN0IHRvIGJpbmQgdG8gdGhlIGZ1bmN0aW9uXG5cdCAqL1xuXHRmdW5jdGlvbiBlYWNoS2V5KG9iaiwgZm4sIHRhcmdldCkge1xuXHQgIGZvciAodmFyIGtleSBpbiBvYmopIHtcblx0ICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuXHQgICAgICBmbi5jYWxsKHRhcmdldCwga2V5LCBvYmpba2V5XSk7XG5cdCAgICB9XG5cdCAgfVxuXHR9XG5cdFxuXHQvKipcblx0ICogU2V0IGRlZmF1bHQgb3B0aW9ucyB3aGVyZSBzb21lIG9wdGlvbiB3YXMgbm90IHNwZWNpZmllZC5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgVGhlIGRlc3RpbmF0aW9uXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBfZGVmYXVsdHMgVGhlIGRlZmF1bHRzXG5cdCAqIEByZXR1cm5zIHtPYmplY3R9XG5cdCAqL1xuXHRmdW5jdGlvbiBkZWZh
1dWx0cyhvcHRpb25zLCBfZGVmYXVsdHMpIHtcblx0ICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblx0ICBlYWNoS2V5KF9kZWZhdWx0cywgZnVuY3Rpb24gKGtleSwgdmFsKSB7XG5cdCAgICBpZiAoIWV4aXN0eShvcHRpb25zW2tleV0pKSB7XG5cdCAgICAgIG9wdGlvbnNba2V5XSA9IHZhbDtcblx0ICAgIH1cblx0ICB9KTtcblx0ICByZXR1cm4gb3B0aW9ucztcblx0fVxuXHRcblx0LyoqXG5cdCAqIENvbnZlcnQgdmFsdWUgKGUuZy4sIGEgTm9kZUxpc3QpIHRvIGFuIGFycmF5LlxuXHQgKlxuXHQgKiBAcGFyYW0geyp9IG9iaiBUaGUgb2JqZWN0XG5cdCAqIEByZXR1cm5zIHtBcnJheTwqPn1cblx0ICovXG5cdGZ1bmN0aW9uIHRvQXJyYXkob2JqKSB7XG5cdCAgdHJ5IHtcblx0ICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChvYmopO1xuXHQgIH0gY2F0Y2ggKGUpIHtcblx0ICAgIHZhciBfcmV0ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICB2YXIgcmV0ID0gW107XG5cdCAgICAgIGVhY2gob2JqLCBmdW5jdGlvbiAodmFsKSB7XG5cdCAgICAgICAgcmV0LnB1c2godmFsKTtcblx0ICAgICAgfSk7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgdjogcmV0XG5cdCAgICAgIH07XG5cdCAgICB9KCk7XG5cdFxuXHQgICAgaWYgKCh0eXBlb2YgX3JldCA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YoX3JldCkpID09PSBcIm9iamVjdFwiKSByZXR1cm4gX3JldC52O1xuXHQgIH1cblx0fVxuXHRcblx0LyoqXG5cdCAqIEdldCB0aGUgbGFzdCBpdGVtIGluIGFuIGFycmF5XG5cdCAqXG5cdCAqIEBwYXJhbSB7QXJyYXk8Kj59IGFycmF5IFRoZSBhcnJheVxuXHQgKiBAcmV0dXJucyB7Kn0gVGhlIGxhc3QgaXRlbSBpbiB0aGUgYXJyYXlcblx0ICovXG5cdGZ1bmN0aW9uIGxhc3QoYXJyYXkpIHtcblx0ICByZXR1cm4gYXJyYXlbYXJyYXkubGVuZ3RoIC0gMV07XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBUZXN0IGlmIHRva2VuIGlzIGEgc2NyaXB0IHRhZy5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R9IHRvayBUaGUgdG9rZW5cblx0ICogQHBhcmFtIHtTdHJpbmd9IHRhZyBUaGUgdGFnIG5hbWVcblx0ICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHRva2VuIGlzIGEgc2NyaXB0IHRhZ1xuXHQgKi9cblx0ZnVuY3Rpb24gaXNUYWcodG9rLCB0YWcpIHtcblx0ICByZXR1cm4gIXRvayB8fCAhKHRvay50eXBlID09PSAnc3RhcnRUYWcnIHx8IHRvay50eXBlID09PSAnYXRvbWljVGFnJykgfHwgISgndGFnTmFtZScgaW4gdG9rKSA/ICExIDogISEgfnRvay50YWdOYW1lLnRvTG93ZXJDYXNlKCkuaW5kZXhPZih0YWcpO1xuXHR9XG5cdFxuXHQvKipcblx0ICogVGVzdCBpZiB0b2tlbiBpcyBhIHNjcmlwdCB0YWcuXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB0b2sgVGhlIHRva2VuXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB0b2tlbiBpcyBhIHNjcmlwdCB0YWdcblx0ICovXG5cdGZ1bmN0aW9uIGlzU2NyaXB0KHRvaykge1xuXHQgIHJldHVybiBpc1RhZyh0b2ssICdzY3JpcHQnKTtcblx0fVxuXHRcblx0LyoqXG5cdCAqIFRlc3QgaWYgdG9rZW4gaXMgYSBzdHlsZSB0YWcuXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB0b2sgVGhlIHRva2VuXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB0b2tlbiBpcyBhIHN0eWxlIHRhZ1xuXHQgKi9cblx0ZnVuY3Rpb24gaXNTdHlsZSh0b2spIHtcblx0ICByZXR1cm4gaXNUYWcodG9rLCAnc3R5bGUnKTtcblx0fVxuXG4vKioqLyB9XG4vKioqKioqLyBdKVxufSk7XG47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wb3N0c2NyaWJlLmpzLm1hcCJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFHQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///156\n")},782:function(module){eval('/**\n * @file postscribe\n * @description Asynchronously write javascript, even with document.write.\n * @version v2.0.8\n * @see {@link https://krux.github.io/postscribe}\n * @license MIT\n * @author Derek Brans\n * @copyright 2016 Krux Digital, Inc\n */\n!function (t, e) {\n   true ? module.exports = e() : 0;\n}(this, function () {\n  return function (t) {\n    function e(n) {\
1n      if (r[n]) return r[n].exports;\n      var o = r[n] = {\n        "exports": {},\n        "id": n,\n        "loaded": !1\n      };\n      return t[n].call(o.exports, o, o.exports, e), o.loaded = !0, o.exports;\n    }\n    var r = {};\n    return e.m = t, e.c = r, e.p = "", e(0);\n  }([function (t, e, r) {\n    "use strict";\n\n    function n(t) {\n      return t && t.__esModule ? t : {\n        "default": t\n      };\n    }\n    var o = r(1),\n      i = n(o);\n    t.exports = i["default"];\n  }, function (t, e, r) {\n    "use strict";\n\n    function n(t) {\n      if (t && t.__esModule) return t;\n      var e = {};\n      if (null != t) for (var r in t) Object.prototype.hasOwnProperty.call(t, r) && (e[r] = t[r]);\n      return e["default"] = t, e;\n    }\n    function o(t) {\n      return t && t.__esModule ? t : {\n        "default": t\n      };\n    }\n    function i() {}\n    function a() {\n      var t = m.shift();\n      if (t) {\n        var e = h.last(t);\n        e.afterDequeue(), t.stream = s.apply(void 0, t), e.afterStreamStart();\n      }\n    }\n    function s(t, e, r) {\n      function n(t) {\n        t = r.beforeWrite(t), g.write(t), r.afterWrite(t);\n      }\n      g = new p["default"](t, r), g.id = y++, g.name = r.name || g.id, u.streams[g.name] = g;\n      var o = t.ownerDocument,\n        s = {\n          "close": o.close,\n          "open": o.open,\n          "write": o.write,\n          "writeln": o.writeln\n        };\n      c(o, {\n        "close": i,\n        "open": i,\n        "write": function () {\n          for (var t = arguments.length, e = Array(t), r = 0; r < t; r++) e[r] = arguments[r];\n          return n(e.join(""));\n        },\n        "writeln": function () {\n          for (var t = arguments.length, e = Array(t), r = 0; r < t; r++) e[r] = arguments[r];\n          return n(e.join("") + "\\n");\n        }\n      });\n      var l = g.win.onerror || i;\n      return g.win.onerror = function (t, e, n) {\n        r.error({\n          "msg": t + " - " + e + ": " + n\n        }), l.apply(g.win, [t, e, n]);\n      }, g.write(e, function () {\n        c(o, s), g.win.onerror = l, r.done(), g = null, a();\n      }), g;\n    }\n    function u(t, e, r) {\n      if (h.isFunction(r)) r = {\n        "done": r\n      };else if ("clear" === r) return m = [], g = null, void (y = 0);\n      r = h.defaults(r, d), t = /^#/.test(t) ? window.document.getElementById(t.substr(1)) : t.jquery ? t[0] : t;\n      var n = [t, e, r];\n      return t.postscribe = {\n        "cancel": function () {\n          n.stream ? n.stream.abort() : n[1] = i;\n        }\n      }, r.beforeEnqueue(n), m.push(n), g || a(), t.postscribe;\n    }\n    e.__esModule = !0;\n    var c = Object.assign || function (t) {\n      for (var e = 1; e < arguments.length; e++) {\n        var r = arguments[e];\n        for (var n in r) Object.prototype.hasOwnProperty.call(r, n) && (t[n] = r[n]);\n      }\n      return t;\n    };\n    e["default"] = u;\n    var l = r(2),\n      p = o(l),\n      f = r(4),\n      h = n(f),\n      d = {\n        "afterAsync": i,\n        "afterDequeue": i,\n        "afterStreamStart": i,\n        "afterWrite": i,\n        "autoFix": !0,\n        "beforeEnqueue": i,\n        "beforeWriteToken": function (t) {\n          return t;\n        },\n        "beforeWrite": function (t) {\n          return t;\n        },\n        "done": i,\n        "error": function (t) {\n          throw new Error(t.msg);\n        },\n        "releaseAsync": !1\n      },\n      y = 0,\n      m = [],\n      g = null;\n    c(u, {\n      "streams": {},\n      "queue": m,\n      "WriteStream": p["default"]\n    });\n  }, function (t, e, r) {\n    "use strict";\n\n    function n(t) {\n      if (t && t.__esModule) return t;\n      var e = {};\n      if (null != t) for (var r in t) Object.prototype.hasOwnProperty.call(t, r) && (e[r] = t[r]);\n      return e["default"] = t, e;\n    }\n    function o(t) {\n      return t && t.__esModule ? t : {\n        "default": t\n      };\n    }\n    function i(t, e) {\n      if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function");\n    }\n    function a(t, e) {\n      var r = d + e,\n        n = t.getAttribute(r);\n      return f.existy(n) ? String(n) : n;\n    }\n    function s(t, e) {\n      var r = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : null,\n        n = d + e;\n      f.existy(r) && "" !== r ? t.setAttribute(n, r) : t.removeAttribute(n);\n    }
1\n    e.__esModule = !0;\n    var u = Object.assign || function (t) {\n        for (var e = 1; e < arguments.length; e++) {\n          var r = arguments[e];\n          for (var n in r) Object.prototype.hasOwnProperty.call(r, n) && (t[n] = r[n]);\n        }\n        return t;\n      },\n      c = r(3),\n      l = o(c),\n      p = r(4),\n      f = n(p),\n      h = !1,\n      d = "data-ps-",\n      y = "ps-style",\n      m = "ps-script",\n      g = function () {\n        function t(e) {\n          var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};\n          i(this, t), this.root = e, this.options = r, this.doc = e.ownerDocument, this.win = this.doc.defaultView || this.doc.parentWindow, this.parser = new l["default"]("", {\n            "autoFix": r.autoFix\n          }), this.actuals = [e], this.proxyHistory = "", this.proxyRoot = this.doc.createElement(e.nodeName), this.scriptStack = [], this.writeQueue = [], s(this.proxyRoot, "proxyof", 0);\n        }\n        return t.prototype.write = function () {\n          var t;\n          for ((t = this.writeQueue).push.apply(t, arguments); !this.deferredRemote && this.writeQueue.length;) {\n            var e = this.writeQueue.shift();\n            f.isFunction(e) ? this._callFunction(e) : this._writeImpl(e);\n          }\n        }, t.prototype._callFunction = function (t) {\n          var e = {\n            "type": "function",\n            "value": t.name || t.toString()\n          };\n          this._onScriptStart(e), t.call(this.win, this.doc), this._onScriptDone(e);\n        }, t.prototype._writeImpl = function (t) {\n          this.parser.append(t);\n          for (var e = void 0, r = void 0, n = void 0, o = []; (e = this.parser.readToken()) && !(r = f.isScript(e)) && !(n = f.isStyle(e));) e = this.options.beforeWriteToken(e), e && o.push(e);\n          o.length > 0 && this._writeStaticTokens(o), r && this._handleScriptToken(e), n && this._handleStyleToken(e);\n        }, t.prototype._writeStaticTokens = function (t) {\n          var e = this._buildChunk(t);\n          return e.actual ? (e.html = this.proxyHistory + e.actual, this.proxyHistory += e.proxy, this.proxyRoot.innerHTML = e.html, h && (e.proxyInnerHTML = this.proxyRoot.innerHTML), this._walkChunk(), h && (e.actualInnerHTML = this.root.innerHTML), e) : null;\n        }, t.prototype._buildChunk = function (t) {\n          for (var e = this.actuals.length, r = [], n = [], o = [], i = t.length, a = 0; a < i; a++) {\n            var s = t[a],\n              u = s.toString();\n            if (r.push(u), s.attrs) {\n              if (!/^noscript$/i.test(s.tagName)) {\n                var c = e++;\n                n.push(u.replace(/(\\/?>)/, " " + d + "id=" + c + " $1")), s.attrs.id !== m && s.attrs.id !== y && o.push("atomicTag" === s.type ? "" : "<" + s.tagName + " " + d + "proxyof=" + c + (s.unary ? " />" : ">"));\n              }\n            } else n.push(u), o.push("endTag" === s.type ? u : "");\n          }\n          return {\n            "tokens": t,\n            "raw": r.join(""),\n            "actual": n.join(""),\n            "proxy": o.join("")\n          };\n        }, t.prototype._walkChunk = function () {\n          for (var t = void 0, e = [this.proxyRoot]; f.existy(t = e.shift());) {\n            var r = 1 === t.nodeType,\n              n = r && a(t, "proxyof");\n            if (!n) {\n              r && (this.actuals[a(t, "id")] = t, s(t, "id"));\n              var o = t.parentNode && a(t.parentNode, "proxyof");\n              o && this.actuals[o].appendChild(t);\n            }\n            e.unshift.apply(e, f.toArray(t.childNodes));\n          }\n        }, t.prototype._handleScriptToken = function (t) {\n          var e = this,\n            r = this.parser.clear();\n          r && this.writeQueue.unshift(r), t.src = t.attrs.src || t.attrs.SRC, t = this.options.beforeWriteToken(t), t && (t.src && this.scriptStack.length ? this.deferredRemote = t : this._onScriptStart(t), this._writeScriptToken(t, function () {\n            e._onScriptDone(t);\n          }));\n        }, t.prototype._handleStyleToken = function (t) {\n          var e = this.parser.clear();\n          e && this.writeQueue.unshift(e), t.type = t.attrs.type || t.attrs.TYPE || "text/css", t = this.options.beforeWriteToken(t), t && this._writeStyleToken(t), e && this.write();\n        }, t.prototype._writeStyleToken = function (t) {\n          var e = this._buildStyle(t);\n          this._insertCursor(e, y), t.content && (e.styleSheet && !e.sheet ? e.styleSheet.cssText = t.content : e.appendChild(this.doc.createTextNode(t.content)));\n        }, t.prototype._buildStyle = function (t) {\n          var e = this.doc.createElement(t.tagName);\n          return e.setAttribute("type", t.type), f.eachKey(t.attrs, function (t, r) {\n            e.setAttribute(t, r);\n          }), e;\n        }, t.prototype._insertCursor = function (t, e) {\n          this._writeImpl(\'<span id="\' + e + \'"/>\');\n          var r = this.doc.getElementById(e);\n          r && r.parentNode.replaceChild(t, r);\n        }, t.prototype._onScriptStart = function (t) {\n          t.outerWrites = this.writeQueue, this.writeQueue = [], this.scriptStack.unshift(t);\n        }, t.prototype._onScriptDone = function (t) {\n          return t !== this.scriptStack[0] ? void this.options.error({\n            "msg": "Bad script nesting or script finished twice"\n          }) : (this.scriptStack.shift(), this.write.apply(this, t.outerWrites), void (!this.scriptStack.length && this.deferredRemote && (this._onScriptStart(this.deferredRemote), this.deferredRemote = null)));\n        }, t.prototype._writeScriptToken = function (t, e) {\n          var r = this._buildScript(t),\n            n = this._shouldRelease(r),\n            o = this.options.afterAsync;\n          t.src && (r.src = t.src, this._scriptLoadHandler(r, n ? o : function () {\n            e(), o();\n          }));\n          try {\n            this._insertCursor(r, m), r.src && !n || e();\n          } catch (t) {\n            this.options.error(t), e();\n          }\n        }, t.prototype._buildScript = function (t) {\n          var e = this.doc.createElement(t.tagName);\n          return f.eachKey(t.attrs, function (t, r) {\n            e.setAttribute(t, r);\n          }), t.content && (e.text = t.content), e;\n        }, t.prototype._scriptLoadHandler = function (t, e) {\n          function r() {\n            t = t.onload = t.onreadystatechange = t.onerror = null;\n          }\n          function n() {\n            r(), null != e && e(), e = null;\n          }\n          function o(t) {\n            r(), a(t), null != e && e(), e = null;\n          }\n          function i(t, e) {\n            var r = t["on" + e];\n            null != r && (t["_on" + e] = r);\n          }\n          var a = this.options.error;\n          i(t, "load"), i(t, "error"), u(t, {\n            "onload": function () {\n              if (t._onload) try {\n                t._onload.apply(this, Array.prototype.slice.call(arguments, 0));\n              } catch (e) {\n                o({\n                  "msg": "onload handler failed " + e + " @ " + t.src\n                });\n              }\n              n();\n            },\n            "onerror": function () {\n              if (t._onerror) try {\n                t._onerror.apply(this, Array.prototype.slice.call(arguments, 0));\n              } catch (e) {\n                return void o({\n                  "msg": "onerror handler failed " + e + " @ " + t.src\n                });\n              }\n              o({\n                "msg": "remote script failed " + t.src\n              });\n            },\n            "onreadystatechange": function () {\n              /^(loaded|complete)$/.test(t.readyState) && n();\n            }\n          });\n        }, t.prototype._shouldRelease = function (t) {\n          var e = /^script$/i.test(t.no
1deName);\n          return !e || !!(this.options.releaseAsync && t.src && t.hasAttribute("async"));\n        }, t;\n      }();\n    e["default"] = g;\n  }, function (t, e, r) {\n    !function (e, r) {\n      t.exports = r();\n    }(this, function () {\n      return function (t) {\n        function e(n) {\n          if (r[n]) return r[n].exports;\n          var o = r[n] = {\n            "exports": {},\n            "id": n,\n            "loaded": !1\n          };\n          return t[n].call(o.exports, o, o.exports, e), o.loaded = !0, o.exports;\n        }\n        var r = {};\n        return e.m = t, e.c = r, e.p = "", e(0);\n      }([function (t, e, r) {\n        "use strict";\n\n        function n(t) {\n          return t && t.__esModule ? t : {\n            "default": t\n          };\n        }\n        var o = r(1),\n          i = n(o);\n        t.exports = i["default"];\n      }, function (t, e, r) {\n        "use strict";\n\n        function n(t) {\n          return t && t.__esModule ? t : {\n            "default": t\n          };\n        }\n        function o(t) {\n          if (t && t.__esModule) return t;\n          var e = {};\n          if (null != t) for (var r in t) Object.prototype.hasOwnProperty.call(t, r) && (e[r] = t[r]);\n          return e["default"] = t, e;\n        }\n        function i(t, e) {\n          if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function");\n        }\n        e.__esModule = !0;\n        var a = r(2),\n          s = o(a),\n          u = r(3),\n          c = o(u),\n          l = r(6),\n          p = n(l),\n          f = r(5),\n          h = {\n            "comment": /^\x3c!--/,\n            "endTag": /^<\\//,\n            "atomicTag": /^<\\s*(script|style|noscript|iframe|textarea)[\\s\\/>]/i,\n            "startTag": /^</,\n            "chars": /^[^<]/\n          },\n          d = function () {\n            function t() {\n              var e = this,\n                r = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "",\n                n = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};\n              i(this, t), this.stream = r;\n              var o = !1,\n                a = {};\n              for (var u in s) s.hasOwnProperty(u) && (n.autoFix && (a[u + "Fix"] = !0), o = o || a[u + "Fix"]);\n              o ? (this._readToken = (0, p["default"])(this, a, function () {\n                return e._readTokenImpl();\n              }), this._peekToken = (0, p["default"])(this, a, function () {\n                return e._peekTokenImpl();\n              })) : (this._readToken = this._readTokenImpl, this._peekToken = this._peekTokenImpl);\n            }\n            return t.prototype.append = function (t) {\n              this.stream += t;\n            }, t.prototype.prepend = function (t) {\n              this.stream = t + this.stream;\n            }, t.prototype._readTokenImpl = function () {\n              var t = this._peekTokenImpl();\n              if (t) return this.stream = this.stream.slice(t.length), t;\n            }, t.prototype._peekTokenImpl = function () {\n              for (var t in h) if (h.hasOwnProperty(t) && h[t].test(this.stream)) {\n                var e = c[t](this.stream);\n                if (e) return "startTag" === e.type && /script|style/i.test(e.tagName) ? null : (e.text = this.stream.substr(0, e.length), e);\n              }\n            }, t.prototype.peekToken = function () {\n              return this._peekToken();\n            }, t.prototype.readToken = function () {\n              return this._readToken();\n            }, t.prototype.readTokens = function (t) {\n              for (var e = void 0; e = this.readToken();) if (t[e.type] && t[e.type](e) === !1) return;\n            }, t.prototype.clear = function () {\n              var t = this.stream;\n              return this.stream = "", t;\n            }, t.prototype.rest = function () {\n              return this.stream;\n            }, t;\n          }();\n        e["default"] = d, d.tokenToString = function (t) {\n          return t.toString();\n        }, d.escapeAttributes = function (t) {\n          var e = {};\n          for (var r in t) t.hasOwnProperty(r) && (e[r] = (0, f.escapeQuotes)(t[r], null));\n          return e;\n        }, d.supports = s;\n        for (var y in s) s.hasOwnProperty(y) && (d.browserHasFlaw = d.browserHasFlaw || !s[y] && y);\n      }, function (t, e) {\n        "use strict";
1\n\n        e.__esModule = !0;\n        var r = !1,\n          n = !1,\n          o = window.document.createElement("div");\n        try {\n          var i = "<P><I></P></I>";\n          o.innerHTML = i, e.tagSoup = r = o.innerHTML !== i;\n        } catch (t) {\n          e.tagSoup = r = !1;\n        }\n        try {\n          o.innerHTML = "<P><i><P></P></i></P>", e.selfClose = n = 2 === o.childNodes.length;\n        } catch (t) {\n          e.selfClose = n = !1;\n        }\n        o = null, e.tagSoup = r, e.selfClose = n;\n      }, function (t, e, r) {\n        "use strict";\n\n        function n(t) {\n          var e = t.indexOf("--\x3e");\n          if (e >= 0) return new c.CommentToken(t.substr(4, e - 1), e + 3);\n        }\n        function o(t) {\n          var e = t.indexOf("<");\n          return new c.CharsToken(e >= 0 ? e : t.length);\n        }\n        function i(t) {\n          var e = t.indexOf(">");\n          if (e !== -1) {\n            var r = t.match(l.startTag);\n            if (r) {\n              var n = function () {\n                var t = {},\n                  e = {},\n                  n = r[2];\n                return r[2].replace(l.attr, function (r, o) {\n                  arguments[2] || arguments[3] || arguments[4] || arguments[5] ? arguments[5] ? (t[arguments[5]] = "", e[arguments[5]] = !0) : t[o] = arguments[2] || arguments[3] || arguments[4] || l.fillAttr.test(o) && o || "" : t[o] = "", n = n.replace(r, "");\n                }), {\n                  "v": new c.StartTagToken(r[1], r[0].length, t, e, !!r[3], n.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, ""))\n                };\n              }();\n              if ("object" === ("undefined" == typeof n ? "undefined" : u(n))) return n.v;\n            }\n          }\n        }\n        function a(t) {\n          var e = i(t);\n          if (e) {\n            var r = t.slice(e.length);\n            if (r.match(new RegExp("</\\\\s*" + e.tagName + "\\\\s*>", "i"))) {\n              var n = r.match(new RegExp("([\\\\s\\\\S]*?)</\\\\s*" + e.tagName + "\\\\s*>", "i"));\n              if (n) return new c.AtomicTagToken(e.tagName, n[0].length + e.length, e.attrs, e.booleanAttrs, n[1]);\n            }\n          }\n        }\n        function s(t) {\n          var e = t.match(l.endTag);\n          if (e) return new c.EndTagToken(e[1], e[0].length);\n        }\n        e.__esModule = !0;\n        var u = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (t) {\n          return typeof t;\n        } : function (t) {\n          return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t;\n        };\n        e.comment = n, e.chars = o, e.startTag = i, e.atomicTag = a, e.endTag = s;\n        var c = r(4),\n          l = {\n            "startTag": /^<([\\-A-Za-z0-9_]+)((?:\\s+[\\w\\-]+(?:\\s*=?\\s*(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>\\s]+))?)*)\\s*(\\/?)>/,\n            "endTag": /^<\\/([\\-A-Za-z0-9_]+)[^>]*>/,\n            "attr": /(?:([\\-A-Za-z0-9_]+)\\s*=\\s*(?:(?:"((?:\\\\.|[^"])*)")|(?:\'((?:\\\\.|[^\'])*)\')|([^>\\s]+)))|(?:([\\-A-Za-z0-9_]+)(\\s|$)+)/g,\n            "fillAttr": /^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noresize|noshade|nowrap|readonly|selected)$/i\n          };\n      }, function (t, e, r) {\n        "use strict";\n\n        function n(t, e) {\n          if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function");\n        }\n        e.__esModule = !0, e.EndTagToken = e.AtomicTagToken = e.StartTagToken = e.TagToken = e.CharsToken = e.CommentToken = e.Token = void 0;\n        var o = r(5),\n          i = (e.Token = function t(e, r) {\n            n(this, t), this.type = e, this.length = r, this.text = "";\n          }, e.CommentToken = function () {\n            function t(e, r) {\n              n(this, t), this.type = "comment", this.length = r || (e ? e.length : 0), this.text = "", this.content = e;\n            }\n            return t.prototype.toString = function () {\n              return "\x3c!--" + this.content;\n            }, t;\n          }(), e.CharsToken = function () {\n            function t(e) {\n              n(this, t), this.type = "chars", this.length = e, this.text = "";\n            }\n            return t.prototype.toString = function () {\n              return this.text;\n            }, t;\n          }(), e.TagToken = function () {\n            function t(e, r, o, i, a) {\n              n(this, t), this.type = e, this.length = o, this.text = "", this.tagName = r, this.attrs = i, this.booleanAttrs = a, this.unary = !1, this.html5Unary = !1;\n            }\n            return t.formatTag = function (t) {\n              var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : null,\n                r = "<" + t.tagName;\n              for (var n in t.attrs) if (t.attrs.hasOwnProperty(n)) {\n                r += " " + n;\n                var i = t.attrs[n];\n                "undefined" != typeof t.booleanAttrs && "undefined" != typeof t.booleanAttrs[n] || (r += \'="\' + (0, o.escapeQuotes)(i) + \'"\');\n              }\n              return t.rest && (r += " " + t.rest), r += t.unary && !t.html5Unary ? "/>" : ">", void 0 !== e && null !== e && (r += e + "</" + t.tagName + ">"), r;\n            }, t;\n          }());\n        e.StartTagToken = function () {\n          function t(e, r, o, i, a, s) {\n            n(this, t), this.type = "startTag", this.length = r, this.text = "", this.tagName = e, this.attrs = o, this.booleanAttrs = i, this.html5Unary = !1, this.unary = a, this.rest = s;\n          }\n          return t.prototype.toString = function () {\n            return i.formatTag(this);\n          }, t;\n        }(), e.AtomicTagToken = function () {\n          function t(e, r, o, i, a) {\n            n(this, t), this.type = "atomicTag", this.length = r, this.text = "", this.tagName = e, this.attrs = o, this.booleanAttrs = i, this.unary = !1, this.html5Unary = !1, this.content = a;\n          }\n          return t.prototype.toString = function () {\n            return i.formatTag(this, this.content);\n          }, t;\n        }(), e.EndTagToken = function () {\n          function t(e, r) {\n            n(this, t), this.type = "endTag", this.length = r, this.text = "", this.tagName = e;\n          }\n          return t.prototype.toString = function () {\n            return "</" + this.tagName + ">";\n          }, t;\n        }();\n      }, function (t, e) {\n        "use strict";\n\n        function r(t) {\n          var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "";\n          return t ? t.replace(/([^"]*)"/g, function (t, e) {\n            return /\\\\/.test(e) ? e + \'"\' : e + \'\\\\"\';\n          }) : e;
1\n        }\n        e.__esModule = !0, e.escapeQuotes = r;\n      }, function (t, e) {\n        "use strict";\n\n        function r(t) {\n          return t && "startTag" === t.type && (t.unary = s.test(t.tagName) || t.unary, t.html5Unary = !/\\/>$/.test(t.text)), t;\n        }\n        function n(t, e) {\n          var n = t.stream,\n            o = r(e());\n          return t.stream = n, o;\n        }\n        function o(t, e) {\n          var r = e.pop();\n          t.prepend("</" + r.tagName + ">");\n        }\n        function i() {\n          var t = [];\n          return t.last = function () {\n            return this[this.length - 1];\n          }, t.lastTagNameEq = function (t) {\n            var e = this.last();\n            return e && e.tagName && e.tagName.toUpperCase() === t.toUpperCase();\n          }, t.containsTagName = function (t) {\n            for (var e, r = 0; e = this[r]; r++) if (e.tagName === t) return !0;\n            return !1;\n          }, t;\n        }\n        function a(t, e, a) {\n          function s() {\n            var e = n(t, a);\n            e && l[e.type] && l[e.type](e);\n          }\n          var c = i(),\n            l = {\n              "startTag": function (r) {\n                var n = r.tagName;\n                "TR" === n.toUpperCase() && c.lastTagNameEq("TABLE") ? (t.prepend("<TBODY>"), s()) : e.selfCloseFix && u.test(n) && c.containsTagName(n) ? c.lastTagNameEq(n) ? o(t, c) : (t.prepend("</" + r.tagName + ">"), s()) : r.unary || c.push(r);\n              },\n              "endTag": function (r) {\n                var n = c.last();\n                n ? e.tagSoupFix && !c.lastTagNameEq(r.tagName) ? o(t, c) : c.pop() : e.tagSoupFix && (a(), s());\n              }\n            };\n          return function () {\n            return s(), r(a());\n          };\n        }\n        e.__esModule = !0, e["default"] = a;\n        var s = /^(AREA|BASE|BASEFONT|BR|COL|FRAME|HR|IMG|INPUT|ISINDEX|LINK|META|PARAM|EMBED)$/i,\n          u = /^(COLGROUP|DD|DT|LI|OPTIONS|P|TD|TFOOT|TH|THEAD|TR)$/i;\n      }]);\n    });\n  }, function (t, e) {\n    "use strict";\n\n    function r(t) {\n      return void 0 !== t && null !== t;\n    }\n    function n(t) {\n      return "function" == typeof t;\n    }\n    function o(t, e, r) {\n      var n = void 0,\n        o = t && t.length || 0;\n      for (n = 0; n < o; n++) e.call(r, t[n], n);\n    }\n    function i(t, e, r) {\n      for (var n in t) t.hasOwnProperty(n) && e.call(r, n, t[n]);\n    }\n    function a(t, e) {\n      return t = t || {}, i(e, function (e, n) {\n        r(t[e]) || (t[e] = n);\n      }), t;\n    }\n    function s(t) {\n      try {\n        return Array.prototype.slice.call(t);\n      } catch (r) {\n        var e = function () {\n          var e = [];\n          return o(t, function (t) {\n            e.push(t);\n          }), {\n            "v": e\n          };\n        }();\n        if ("object" === ("undefined" == typeof e ? "undefined" : f(e))) return e.v;\n      }\n    }\n    function u(t) {\n      return t[t.length - 1];\n    }\n    function c(t, e) {\n      return !(!t || "startTag" !== t.type && "atomicTag" !== t.type || !("tagName" in t)) && !!~t.tagName.toLowerCase().indexOf(e);\n    }\n    function l(t) {\n      return c(t, "script");\n    }\n    function p(t) {\n      return c(t, "style");\n    }\n    e.__esModule = !0;\n    var f = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (t) {\n      return typeof t;\n    } : function (t) {\n      return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t;\n    };\n    e.existy = r, e.isFunction = n, e.each = o, e.eachKey = i, e.defaults = a, e.toArray = s, e.last = u, e.isTag = c, e.isScript = l, e.isStyle = p;\n  }]);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzgyLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vdmVuZG9yL3Bvc3RzY3JpYmUubWluLmpzPzdlMTIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZmlsZSBwb3N0c2NyaWJlXG4gKiBAZGVzY3JpcHRpb24gQXN5bmNocm9ub3VzbHkgd3JpdGUgamF2YXNjcmlwdCwgZXZlbiB3aXRoIGRvY3VtZW50LndyaXRlLlxuICogQHZlcnNpb24gdjIuMC44XG4gKiBAc2VlIHtAbGluayBodHRwczovL2tydXguZ2l0aHViLmlvL3Bvc3RzY3JpYmV9XG4gKiBAbGljZW5zZSBNSVRcbiAqIEBhdXRob3IgRGVyZWsgQnJhbnNcbiAqIEBjb3B5cmlnaHQgMjAxNiBLcnV4IERpZ2l0YWwsIEluY1xuICovXG4hZnVuY3Rpb24odCxlKXtcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cyYmXCJvYmplY3RcIj09dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz1lKCk6XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShbXSxlKTpcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cz9leHBvcnRzW1wicG9zdHNjcmliZVwiXT1lKCk6dFtcInBvc3RzY3JpYmVcIl09ZSgpfSh0aGlzLGZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGUobil7aWYocltuXSlyZXR1cm4gcltuXS5leHBvcnRzO3ZhciBvPXJbbl09e1wiZXhwb3J0c1wiOnt9LFwiaWRcIjpuLFwibG9h
1ZGVkXCI6ITF9O3JldHVybiB0W25dLmNhbGwoby5leHBvcnRzLG8sby5leHBvcnRzLGUpLG8ubG9hZGVkPSEwLG8uZXhwb3J0c312YXIgcj17fTtyZXR1cm4gZS5tPXQsZS5jPXIsZS5wPVwiXCIsZSgwKX0oW2Z1bmN0aW9uKHQsZSxyKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBuKHQpe3JldHVybiB0JiZ0Ll9fZXNNb2R1bGU/dDp7XCJkZWZhdWx0XCI6dH19dmFyIG89cigxKSxpPW4obyk7dC5leHBvcnRzPWlbXCJkZWZhdWx0XCJdfSxmdW5jdGlvbih0LGUscil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbih0KXtpZih0JiZ0Ll9fZXNNb2R1bGUpcmV0dXJuIHQ7dmFyIGU9e307aWYobnVsbCE9dClmb3IodmFyIHIgaW4gdClPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxyKSYmKGVbcl09dFtyXSk7cmV0dXJuIGVbXCJkZWZhdWx0XCJdPXQsZX1mdW5jdGlvbiBvKHQpe3JldHVybiB0JiZ0Ll9fZXNNb2R1bGU/dDp7XCJkZWZhdWx0XCI6dH19ZnVuY3Rpb24gaSgpe31mdW5jdGlvbiBhKCl7dmFyIHQ9bS5zaGlmdCgpO2lmKHQpe3ZhciBlPWgubGFzdCh0KTtlLmFmdGVyRGVxdWV1ZSgpLHQuc3RyZWFtPXMuYXBwbHkodm9pZCAwLHQpLGUuYWZ0ZXJTdHJlYW1TdGFydCgpfX1mdW5jdGlvbiBzKHQsZSxyKXtmdW5jdGlvbiBuKHQpe3Q9ci5iZWZvcmVXcml0ZSh0KSxnLndyaXRlKHQpLHIuYWZ0ZXJXcml0ZSh0KX1nPW5ldyBwW1wiZGVmYXVsdFwiXSh0LHIpLGcuaWQ9eSsrLGcubmFtZT1yLm5hbWV8fGcuaWQsdS5zdHJlYW1zW2cubmFtZV09Zzt2YXIgbz10Lm93bmVyRG9jdW1lbnQscz17XCJjbG9zZVwiOm8uY2xvc2UsXCJvcGVuXCI6by5vcGVuLFwid3JpdGVcIjpvLndyaXRlLFwid3JpdGVsblwiOm8ud3JpdGVsbn07YyhvLHtcImNsb3NlXCI6aSxcIm9wZW5cIjppLFwid3JpdGVcIjpmdW5jdGlvbigpe2Zvcih2YXIgdD1hcmd1bWVudHMubGVuZ3RoLGU9QXJyYXkodCkscj0wO3I8dDtyKyspZVtyXT1hcmd1bWVudHNbcl07cmV0dXJuIG4oZS5qb2luKFwiXCIpKX0sXCJ3cml0ZWxuXCI6ZnVuY3Rpb24oKXtmb3IodmFyIHQ9YXJndW1lbnRzLmxlbmd0aCxlPUFycmF5KHQpLHI9MDtyPHQ7cisrKWVbcl09YXJndW1lbnRzW3JdO3JldHVybiBuKGUuam9pbihcIlwiKStcIlxcblwiKX19KTt2YXIgbD1nLndpbi5vbmVycm9yfHxpO3JldHVybiBnLndpbi5vbmVycm9yPWZ1bmN0aW9uKHQsZSxuKXtyLmVycm9yKHtcIm1zZ1wiOnQrXCIgLSBcIitlK1wiOiBcIitufSksbC5hcHBseShnLndpbixbdCxlLG5dKX0sZy53cml0ZShlLGZ1bmN0aW9uKCl7YyhvLHMpLGcud2luLm9uZXJyb3I9bCxyLmRvbmUoKSxnPW51bGwsYSgpfSksZ31mdW5jdGlvbiB1KHQsZSxyKXtpZihoLmlzRnVuY3Rpb24ocikpcj17XCJkb25lXCI6cn07ZWxzZSBpZihcImNsZWFyXCI9PT1yKXJldHVybiBtPVtdLGc9bnVsbCx2b2lkKHk9MCk7cj1oLmRlZmF1bHRzKHIsZCksdD0vXiMvLnRlc3QodCk/d2luZG93LmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHQuc3Vic3RyKDEpKTp0LmpxdWVyeT90WzBdOnQ7dmFyIG49W3QsZSxyXTtyZXR1cm4gdC5wb3N0c2NyaWJlPXtcImNhbmNlbFwiOmZ1bmN0aW9uKCl7bi5zdHJlYW0/bi5zdHJlYW0uYWJvcnQoKTpuWzFdPWl9fSxyLmJlZm9yZUVucXVldWUobiksbS5wdXNoKG4pLGd8fGEoKSx0LnBvc3RzY3JpYmV9ZS5fX2VzTW9kdWxlPSEwO3ZhciBjPU9iamVjdC5hc3NpZ258fGZ1bmN0aW9uKHQpe2Zvcih2YXIgZT0xO2U8YXJndW1lbnRzLmxlbmd0aDtlKyspe3ZhciByPWFyZ3VtZW50c1tlXTtmb3IodmFyIG4gaW4gcilPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocixuKSYmKHRbbl09cltuXSl9cmV0dXJuIHR9O2VbXCJkZWZhdWx0XCJdPXU7dmFyIGw9cigyKSxwPW8obCksZj1yKDQpLGg9bihmKSxkPXtcImFmdGVyQXN5bmNcIjppLFwiYWZ0ZXJEZXF1ZXVlXCI6aSxcImFmdGVyU3RyZWFtU3RhcnRcIjppLFwiYWZ0ZXJXcml0ZVwiOmksXCJhdXRvRml4XCI6ITAsXCJiZWZvcmVFbnF1ZXVlXCI6aSxcImJlZm9yZVdyaXRlVG9rZW5cIjpmdW5jdGlvbih0KXtyZXR1cm4gdH0sXCJiZWZvcmVXcml0ZVwiOmZ1bmN0aW9uKHQpe3JldHVybiB0fSxcImRvbmVcIjppLFwiZXJyb3JcIjpmdW5jdGlvbih0KXt0aHJvdyBuZXcgRXJyb3IodC5tc2cpfSxcInJlbGVhc2VBc3luY1wiOiExfSx5PTAsbT1bXSxnPW51bGw7Yyh1LHtcInN0cmVhbXNcIjp7fSxcInF1ZXVlXCI6bSxcIldyaXRlU3RyZWFtXCI6cFtcImRlZmF1bHRcIl19KX0sZnVuY3Rpb24odCxlLHIpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG4odCl7aWYodCYmdC5fX2VzTW9kdWxlKXJldHVybiB0O3ZhciBlPXt9O2lmKG51bGwhPXQpZm9yKHZhciByIGluIHQpT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQscikmJihlW3JdPXRbcl0pO3JldHVybiBlW1wiZGVmYXVsdFwiXT10LGV9ZnVuY3Rpb24gbyh0KXtyZXR1cm4gdCYmdC5fX2VzTW9kdWxlP3Q6e1wiZGVmYXVsdFwiOnR9fWZ1bmN0aW9uIGkodCxlKXtpZighKHQgaW5zdGFuY2VvZiBlKSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpfWZ1bmN0aW9uIGEodCxlKXt2YXIgcj1kK2Usbj10LmdldEF0dHJpYnV0ZShyKTtyZXR1cm4gZi5leGlzdHkobik/U3RyaW5nKG4pOm59ZnVuY3Rpb24gcyh0LGUpe3ZhciByPWFyZ3VtZW50cy5sZW5ndGg+MiYmdm9pZCAwIT09YXJndW1lbnRzWzJdP2FyZ3VtZW50c1syXTpudWxsLG49ZCtlO2YuZXhpc3R5KHIpJiZcIlwiIT09cj90LnNldEF0dHJpYnV0ZShuLHIpOnQucmVtb3ZlQXR0cmlidXRlKG4pfWUuX19lc01vZHVsZT0hMDt2YXIgdT1PYmplY3QuYXNzaWdufHxmdW5jdGlvbih0KXtmb3IodmFyIGU9MTtlPGFyZ3VtZW50cy5sZW5ndGg7ZSsrKXt2YXIgcj1hcmd1bWVudHNbZV07Zm9yKHZhciBuIGluIHIpT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHIsbikmJih0W25dPXJbbl0pfXJldHVybiB0fSxjPXIoMyksbD1vKGMpLHA9cig0KSxmPW4ocCksaD0hMSxkPVwiZGF0YS1wcy1cIix5PVwicHMtc3R5bGVcIixtPVwicHMtc2NyaXB0XCIsZz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoZSl7dmFyIHI9YXJndW1lbnRzLmxlbmd0aD4xJiZ2b2lkIDAhPT1hcmd1bWVudHNbMV0/YXJndW1lbnRzWzFdOnt9O2kodGhpcyx0KSx0aGlzLnJvb3Q9ZSx0aGlzLm9wdGlvbnM9cix0aGlzLmRvYz1lLm93bmVyRG9jdW1lbnQsdGhpcy53aW49dGhpcy5kb2MuZGVmYXVsdFZpZXd8fHRoaXMuZG9jLnBhcmVudFdpbmRvdyx0aGlzLnBhcnNlcj1uZXcgbFtcImRlZmF1bHRcIl0oXCJcIix7XCJhdXRvRml4XCI6ci5hdXRvRml4fSksdGhpcy5hY3R1YWxzPVtlXSx0aGlzLnByb3h5SGlzdG9yeT1cIlwiLHRoaXMucHJveHlSb290PXRoaXMuZG9jLmNyZWF0ZUVsZW1lbnQoZS5ub2RlTmFtZSksdGhpcy5zY3JpcHRTdGFjaz1bXSx0aGlzLndyaXRlUXVldWU9W10scyh0aGlzLnByb3h5Um9vdCxcInByb3h5b2ZcIiwwKX1yZXR1cm4gdC5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24oKXt2YXIgdDtmb3IoKHQ9dGhpcy53cml0ZVF1ZXVlKS5wdXNoLmFwcGx5KHQsYXJndW1lbnRzKTshdGhpcy5kZWZlcnJlZFJlbW90ZSYmdGhpcy53cml0ZVF1ZXVlLmxlbmd0aDspe3ZhciBlPXR
1oaXMud3JpdGVRdWV1ZS5zaGlmdCgpO2YuaXNGdW5jdGlvbihlKT90aGlzLl9jYWxsRnVuY3Rpb24oZSk6dGhpcy5fd3JpdGVJbXBsKGUpfX0sdC5wcm90b3R5cGUuX2NhbGxGdW5jdGlvbj1mdW5jdGlvbih0KXt2YXIgZT17XCJ0eXBlXCI6XCJmdW5jdGlvblwiLFwidmFsdWVcIjp0Lm5hbWV8fHQudG9TdHJpbmcoKX07dGhpcy5fb25TY3JpcHRTdGFydChlKSx0LmNhbGwodGhpcy53aW4sdGhpcy5kb2MpLHRoaXMuX29uU2NyaXB0RG9uZShlKX0sdC5wcm90b3R5cGUuX3dyaXRlSW1wbD1mdW5jdGlvbih0KXt0aGlzLnBhcnNlci5hcHBlbmQodCk7Zm9yKHZhciBlPXZvaWQgMCxyPXZvaWQgMCxuPXZvaWQgMCxvPVtdOyhlPXRoaXMucGFyc2VyLnJlYWRUb2tlbigpKSYmIShyPWYuaXNTY3JpcHQoZSkpJiYhKG49Zi5pc1N0eWxlKGUpKTspZT10aGlzLm9wdGlvbnMuYmVmb3JlV3JpdGVUb2tlbihlKSxlJiZvLnB1c2goZSk7by5sZW5ndGg+MCYmdGhpcy5fd3JpdGVTdGF0aWNUb2tlbnMobyksciYmdGhpcy5faGFuZGxlU2NyaXB0VG9rZW4oZSksbiYmdGhpcy5faGFuZGxlU3R5bGVUb2tlbihlKX0sdC5wcm90b3R5cGUuX3dyaXRlU3RhdGljVG9rZW5zPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuX2J1aWxkQ2h1bmsodCk7cmV0dXJuIGUuYWN0dWFsPyhlLmh0bWw9dGhpcy5wcm94eUhpc3RvcnkrZS5hY3R1YWwsdGhpcy5wcm94eUhpc3RvcnkrPWUucHJveHksdGhpcy5wcm94eVJvb3QuaW5uZXJIVE1MPWUuaHRtbCxoJiYoZS5wcm94eUlubmVySFRNTD10aGlzLnByb3h5Um9vdC5pbm5lckhUTUwpLHRoaXMuX3dhbGtDaHVuaygpLGgmJihlLmFjdHVhbElubmVySFRNTD10aGlzLnJvb3QuaW5uZXJIVE1MKSxlKTpudWxsfSx0LnByb3RvdHlwZS5fYnVpbGRDaHVuaz1mdW5jdGlvbih0KXtmb3IodmFyIGU9dGhpcy5hY3R1YWxzLmxlbmd0aCxyPVtdLG49W10sbz1bXSxpPXQubGVuZ3RoLGE9MDthPGk7YSsrKXt2YXIgcz10W2FdLHU9cy50b1N0cmluZygpO2lmKHIucHVzaCh1KSxzLmF0dHJzKXtpZighL15ub3NjcmlwdCQvaS50ZXN0KHMudGFnTmFtZSkpe3ZhciBjPWUrKztuLnB1c2godS5yZXBsYWNlKC8oXFwvPz4pLyxcIiBcIitkK1wiaWQ9XCIrYytcIiAkMVwiKSkscy5hdHRycy5pZCE9PW0mJnMuYXR0cnMuaWQhPT15JiZvLnB1c2goXCJhdG9taWNUYWdcIj09PXMudHlwZT9cIlwiOlwiPFwiK3MudGFnTmFtZStcIiBcIitkK1wicHJveHlvZj1cIitjKyhzLnVuYXJ5P1wiIC8+XCI6XCI+XCIpKX19ZWxzZSBuLnB1c2godSksby5wdXNoKFwiZW5kVGFnXCI9PT1zLnR5cGU/dTpcIlwiKX1yZXR1cm57XCJ0b2tlbnNcIjp0LFwicmF3XCI6ci5qb2luKFwiXCIpLFwiYWN0dWFsXCI6bi5qb2luKFwiXCIpLFwicHJveHlcIjpvLmpvaW4oXCJcIil9fSx0LnByb3RvdHlwZS5fd2Fsa0NodW5rPWZ1bmN0aW9uKCl7Zm9yKHZhciB0PXZvaWQgMCxlPVt0aGlzLnByb3h5Um9vdF07Zi5leGlzdHkodD1lLnNoaWZ0KCkpOyl7dmFyIHI9MT09PXQubm9kZVR5cGUsbj1yJiZhKHQsXCJwcm94eW9mXCIpO2lmKCFuKXtyJiYodGhpcy5hY3R1YWxzW2EodCxcImlkXCIpXT10LHModCxcImlkXCIpKTt2YXIgbz10LnBhcmVudE5vZGUmJmEodC5wYXJlbnROb2RlLFwicHJveHlvZlwiKTtvJiZ0aGlzLmFjdHVhbHNbb10uYXBwZW5kQ2hpbGQodCl9ZS51bnNoaWZ0LmFwcGx5KGUsZi50b0FycmF5KHQuY2hpbGROb2RlcykpfX0sdC5wcm90b3R5cGUuX2hhbmRsZVNjcmlwdFRva2VuPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMscj10aGlzLnBhcnNlci5jbGVhcigpO3ImJnRoaXMud3JpdGVRdWV1ZS51bnNoaWZ0KHIpLHQuc3JjPXQuYXR0cnMuc3JjfHx0LmF0dHJzLlNSQyx0PXRoaXMub3B0aW9ucy5iZWZvcmVXcml0ZVRva2VuKHQpLHQmJih0LnNyYyYmdGhpcy5zY3JpcHRTdGFjay5sZW5ndGg/dGhpcy5kZWZlcnJlZFJlbW90ZT10OnRoaXMuX29uU2NyaXB0U3RhcnQodCksdGhpcy5fd3JpdGVTY3JpcHRUb2tlbih0LGZ1bmN0aW9uKCl7ZS5fb25TY3JpcHREb25lKHQpfSkpfSx0LnByb3RvdHlwZS5faGFuZGxlU3R5bGVUb2tlbj1mdW5jdGlvbih0KXt2YXIgZT10aGlzLnBhcnNlci5jbGVhcigpO2UmJnRoaXMud3JpdGVRdWV1ZS51bnNoaWZ0KGUpLHQudHlwZT10LmF0dHJzLnR5cGV8fHQuYXR0cnMuVFlQRXx8XCJ0ZXh0L2Nzc1wiLHQ9dGhpcy5vcHRpb25zLmJlZm9yZVdyaXRlVG9rZW4odCksdCYmdGhpcy5fd3JpdGVTdHlsZVRva2VuKHQpLGUmJnRoaXMud3JpdGUoKX0sdC5wcm90b3R5cGUuX3dyaXRlU3R5bGVUb2tlbj1mdW5jdGlvbih0KXt2YXIgZT10aGlzLl9idWlsZFN0eWxlKHQpO3RoaXMuX2luc2VydEN1cnNvcihlLHkpLHQuY29udGVudCYmKGUuc3R5bGVTaGVldCYmIWUuc2hlZXQ/ZS5zdHlsZVNoZWV0LmNzc1RleHQ9dC5jb250ZW50OmUuYXBwZW5kQ2hpbGQodGhpcy5kb2MuY3JlYXRlVGV4dE5vZGUodC5jb250ZW50KSkpfSx0LnByb3RvdHlwZS5fYnVpbGRTdHlsZT1mdW5jdGlvbih0KXt2YXIgZT10aGlzLmRvYy5jcmVhdGVFbGVtZW50KHQudGFnTmFtZSk7cmV0dXJuIGUuc2V0QXR0cmlidXRlKFwidHlwZVwiLHQudHlwZSksZi5lYWNoS2V5KHQuYXR0cnMsZnVuY3Rpb24odCxyKXtlLnNldEF0dHJpYnV0ZSh0LHIpfSksZX0sdC5wcm90b3R5cGUuX2luc2VydEN1cnNvcj1mdW5jdGlvbih0LGUpe3RoaXMuX3dyaXRlSW1wbCgnPHNwYW4gaWQ9XCInK2UrJ1wiLz4nKTt2YXIgcj10aGlzLmRvYy5nZXRFbGVtZW50QnlJZChlKTtyJiZyLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKHQscil9LHQucHJvdG90eXBlLl9vblNjcmlwdFN0YXJ0PWZ1bmN0aW9uKHQpe3Qub3V0ZXJXcml0ZXM9dGhpcy53cml0ZVF1ZXVlLHRoaXMud3JpdGVRdWV1ZT1bXSx0aGlzLnNjcmlwdFN0YWNrLnVuc2hpZnQodCl9LHQucHJvdG90eXBlLl9vblNjcmlwdERvbmU9ZnVuY3Rpb24odCl7cmV0dXJuIHQhPT10aGlzLnNjcmlwdFN0YWNrWzBdP3ZvaWQgdGhpcy5vcHRpb25zLmVycm9yKHtcIm1zZ1wiOlwiQmFkIHNjcmlwdCBuZXN0aW5nIG9yIHNjcmlwdCBmaW5pc2hlZCB0d2ljZVwifSk6KHRoaXMuc2NyaXB0U3RhY2suc2hpZnQoKSx0aGlzLndyaXRlLmFwcGx5KHRoaXMsdC5vdXRlcldyaXRlcyksdm9pZCghdGhpcy5zY3JpcHRTdGFjay5sZW5ndGgmJnRoaXMuZGVmZXJyZWRSZW1vdGUmJih0aGlzLl9vblNjcmlwdFN0YXJ0KHRoaXMuZGVmZXJyZWRSZW1vdGUpLHRoaXMuZGVmZXJyZWRSZW1vdGU9bnVsbCkpKX0sdC5wcm90b3R5cGUuX3dyaXRlU2NyaXB0VG9rZW49ZnVuY3Rpb24odCxlKXt2YXIgcj10aGlzLl9idWlsZFNjcmlwdCh0KSxuPXRoaXMuX3Nob3VsZFJlbGVhc2Uociksbz10aGlzLm9wdGlvbnMuYWZ0ZXJBc3luYzt0LnNyYyYmKHIuc3JjPXQuc3JjLHRoaXMuX3NjcmlwdExvYWRIYW5kbGVyKHIsbj9vOmZ1bmN0aW9uKCl7ZSgpLG8oKX0pKTt0cnl7dGhpcy5faW5zZXJ0Q3Vyc29yKHIsbSksci5zcmMmJiFufHxlKCl9Y2F0Y2godCl7dGhpcy5vcHRpb25zLmVycm9yKHQpLGUoKX19LHQucHJvdG90eXBlLl9idWlsZFNjcmlwdD1mdW5jdGlvbih0KXt2YXIgZT10aGlzLmRvYy5jcmVhdGVFbGVtZW50KHQudGFnTmFtZSk7cmV0dXJuIGYuZWFjaEtleSh0LmF0dHJzLGZ1bmN0aW9uKHQscil7ZS5zZXRBdHRyaWJ1dGUodCxyKX0pLHQuY29udGVudCYmKGUudGV4dD10LmNvbnRlbnQpLGV9LHQucHJvdG90eXBlLl9zY3JpcHRMb2FkSGFuZGxlcj1mdW5jdGlvbih0LGUpe2Z1bmN0aW9uIHIoKXt0PXQub25sb2FkPXQub25yZWFkeXN0YXRlY2hhbmdlPXQub25lcnJvcj1udWxsfWZ1bmN0aW9uIG4oKXtyKCksbnVsbCE9ZSYmZSgpLGU9bnVsbH1mdW5jdGlvbiBvKHQpe3IoKSxhKHQpLG51bGwhPWUmJmUoKSxlPW51bGx9ZnVuY3Rpb24gaSh0LGUpe3ZhciByPXRbXCJvblwiK2VdO251bGwhPXImJih0W1wiX29uXCIrZV09cil9dmFyIGE9dGhpcy5vcHRpb25zLmVycm9yO2kodCxcImxvYWRcIiksaSh0LFwiZXJyb3JcIiksdSh0LHtcIm9ubG9hZFwiOmZ1bmN0aW9uKCl7aWYodC5fb25sb2FkKXRyeXt0Ll9vbmxvYWQuYXBwbHkodGhpcyxBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMCkpfWNhdGNoKGUpe28oe1wibXNnXCI6XCJvbmxvYWQgaGFuZGxlciBmYWlsZWQgXCIrZStcIiBAIFwiK3Quc3JjfSl9bigpfSxcIm9uZXJyb3JcIjpmdW5jdGlvbigpe2lmKHQuX29uZXJyb3IpdHJ5e3QuX29uZXJyb3IuYXBwbHkodGhpcyxBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMCkpfWNhdGNoKGUpe3JldHVybiB2b2lkIG8oe1wibXNnXCI6XCJvbmVycm9yIGhhbmRsZXIgZmFpbGVkIFwiK2UrXCIgQCBcIit0LnNyY30pfW8oe1wibXNnXCI6XCJyZW1vdGUgc2NyaXB0IGZhaWxlZCBcIit0LnNyY30pfSxcIm9ucmVhZHlzdGF0ZWNoYW5nZVwiOmZ1bmN0aW9uKCl7L14obG9hZGVkfGNvbXBsZXRlKSQvLnRlc3QodC5yZWFkeVN0YXRl
1KSYmbigpfX0pfSx0LnByb3RvdHlwZS5fc2hvdWxkUmVsZWFzZT1mdW5jdGlvbih0KXt2YXIgZT0vXnNjcmlwdCQvaS50ZXN0KHQubm9kZU5hbWUpO3JldHVybiFlfHwhISh0aGlzLm9wdGlvbnMucmVsZWFzZUFzeW5jJiZ0LnNyYyYmdC5oYXNBdHRyaWJ1dGUoXCJhc3luY1wiKSl9LHR9KCk7ZVtcImRlZmF1bHRcIl09Z30sZnVuY3Rpb24odCxlLHIpeyFmdW5jdGlvbihlLHIpe3QuZXhwb3J0cz1yKCl9KHRoaXMsZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24odCl7ZnVuY3Rpb24gZShuKXtpZihyW25dKXJldHVybiByW25dLmV4cG9ydHM7dmFyIG89cltuXT17XCJleHBvcnRzXCI6e30sXCJpZFwiOm4sXCJsb2FkZWRcIjohMX07cmV0dXJuIHRbbl0uY2FsbChvLmV4cG9ydHMsbyxvLmV4cG9ydHMsZSksby5sb2FkZWQ9ITAsby5leHBvcnRzfXZhciByPXt9O3JldHVybiBlLm09dCxlLmM9cixlLnA9XCJcIixlKDApfShbZnVuY3Rpb24odCxlLHIpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG4odCl7cmV0dXJuIHQmJnQuX19lc01vZHVsZT90OntcImRlZmF1bHRcIjp0fX12YXIgbz1yKDEpLGk9bihvKTt0LmV4cG9ydHM9aVtcImRlZmF1bHRcIl19LGZ1bmN0aW9uKHQsZSxyKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBuKHQpe3JldHVybiB0JiZ0Ll9fZXNNb2R1bGU/dDp7XCJkZWZhdWx0XCI6dH19ZnVuY3Rpb24gbyh0KXtpZih0JiZ0Ll9fZXNNb2R1bGUpcmV0dXJuIHQ7dmFyIGU9e307aWYobnVsbCE9dClmb3IodmFyIHIgaW4gdClPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxyKSYmKGVbcl09dFtyXSk7cmV0dXJuIGVbXCJkZWZhdWx0XCJdPXQsZX1mdW5jdGlvbiBpKHQsZSl7aWYoISh0IGluc3RhbmNlb2YgZSkpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKX1lLl9fZXNNb2R1bGU9ITA7dmFyIGE9cigyKSxzPW8oYSksdT1yKDMpLGM9byh1KSxsPXIoNikscD1uKGwpLGY9cig1KSxoPXtcImNvbW1lbnRcIjovXjwhLS0vLFwiZW5kVGFnXCI6L148XFwvLyxcImF0b21pY1RhZ1wiOi9ePFxccyooc2NyaXB0fHN0eWxlfG5vc2NyaXB0fGlmcmFtZXx0ZXh0YXJlYSlbXFxzXFwvPl0vaSxcInN0YXJ0VGFnXCI6L148LyxcImNoYXJzXCI6L15bXjxdL30sZD1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt2YXIgZT10aGlzLHI9YXJndW1lbnRzLmxlbmd0aD4wJiZ2b2lkIDAhPT1hcmd1bWVudHNbMF0/YXJndW1lbnRzWzBdOlwiXCIsbj1hcmd1bWVudHMubGVuZ3RoPjEmJnZvaWQgMCE9PWFyZ3VtZW50c1sxXT9hcmd1bWVudHNbMV06e307aSh0aGlzLHQpLHRoaXMuc3RyZWFtPXI7dmFyIG89ITEsYT17fTtmb3IodmFyIHUgaW4gcylzLmhhc093blByb3BlcnR5KHUpJiYobi5hdXRvRml4JiYoYVt1K1wiRml4XCJdPSEwKSxvPW98fGFbdStcIkZpeFwiXSk7bz8odGhpcy5fcmVhZFRva2VuPSgwLHBbXCJkZWZhdWx0XCJdKSh0aGlzLGEsZnVuY3Rpb24oKXtyZXR1cm4gZS5fcmVhZFRva2VuSW1wbCgpfSksdGhpcy5fcGVla1Rva2VuPSgwLHBbXCJkZWZhdWx0XCJdKSh0aGlzLGEsZnVuY3Rpb24oKXtyZXR1cm4gZS5fcGVla1Rva2VuSW1wbCgpfSkpOih0aGlzLl9yZWFkVG9rZW49dGhpcy5fcmVhZFRva2VuSW1wbCx0aGlzLl9wZWVrVG9rZW49dGhpcy5fcGVla1Rva2VuSW1wbCl9cmV0dXJuIHQucHJvdG90eXBlLmFwcGVuZD1mdW5jdGlvbih0KXt0aGlzLnN0cmVhbSs9dH0sdC5wcm90b3R5cGUucHJlcGVuZD1mdW5jdGlvbih0KXt0aGlzLnN0cmVhbT10K3RoaXMuc3RyZWFtfSx0LnByb3RvdHlwZS5fcmVhZFRva2VuSW1wbD1mdW5jdGlvbigpe3ZhciB0PXRoaXMuX3BlZWtUb2tlbkltcGwoKTtpZih0KXJldHVybiB0aGlzLnN0cmVhbT10aGlzLnN0cmVhbS5zbGljZSh0Lmxlbmd0aCksdH0sdC5wcm90b3R5cGUuX3BlZWtUb2tlbkltcGw9ZnVuY3Rpb24oKXtmb3IodmFyIHQgaW4gaClpZihoLmhhc093blByb3BlcnR5KHQpJiZoW3RdLnRlc3QodGhpcy5zdHJlYW0pKXt2YXIgZT1jW3RdKHRoaXMuc3RyZWFtKTtpZihlKXJldHVyblwic3RhcnRUYWdcIj09PWUudHlwZSYmL3NjcmlwdHxzdHlsZS9pLnRlc3QoZS50YWdOYW1lKT9udWxsOihlLnRleHQ9dGhpcy5zdHJlYW0uc3Vic3RyKDAsZS5sZW5ndGgpLGUpfX0sdC5wcm90b3R5cGUucGVla1Rva2VuPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX3BlZWtUb2tlbigpfSx0LnByb3RvdHlwZS5yZWFkVG9rZW49ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fcmVhZFRva2VuKCl9LHQucHJvdG90eXBlLnJlYWRUb2tlbnM9ZnVuY3Rpb24odCl7Zm9yKHZhciBlPXZvaWQgMDtlPXRoaXMucmVhZFRva2VuKCk7KWlmKHRbZS50eXBlXSYmdFtlLnR5cGVdKGUpPT09ITEpcmV0dXJufSx0LnByb3RvdHlwZS5jbGVhcj1mdW5jdGlvbigpe3ZhciB0PXRoaXMuc3RyZWFtO3JldHVybiB0aGlzLnN0cmVhbT1cIlwiLHR9LHQucHJvdG90eXBlLnJlc3Q9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5zdHJlYW19LHR9KCk7ZVtcImRlZmF1bHRcIl09ZCxkLnRva2VuVG9TdHJpbmc9ZnVuY3Rpb24odCl7cmV0dXJuIHQudG9TdHJpbmcoKX0sZC5lc2NhcGVBdHRyaWJ1dGVzPWZ1bmN0aW9uKHQpe3ZhciBlPXt9O2Zvcih2YXIgciBpbiB0KXQuaGFzT3duUHJvcGVydHkocikmJihlW3JdPSgwLGYuZXNjYXBlUXVvdGVzKSh0W3JdLG51bGwpKTtyZXR1cm4gZX0sZC5zdXBwb3J0cz1zO2Zvcih2YXIgeSBpbiBzKXMuaGFzT3duUHJvcGVydHkoeSkmJihkLmJyb3dzZXJIYXNGbGF3PWQuYnJvd3Nlckhhc0ZsYXd8fCFzW3ldJiZ5KX0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjtlLl9fZXNNb2R1bGU9ITA7dmFyIHI9ITEsbj0hMSxvPXdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO3RyeXt2YXIgaT1cIjxQPjxJPjwvUD48L0k+XCI7by5pbm5lckhUTUw9aSxlLnRhZ1NvdXA9cj1vLmlubmVySFRNTCE9PWl9Y2F0Y2godCl7ZS50YWdTb3VwPXI9ITF9dHJ5e28uaW5uZXJIVE1MPVwiPFA+PGk+PFA+PC9QPjwvaT48L1A+XCIsZS5zZWxmQ2xvc2U9bj0yPT09by5jaGlsZE5vZGVzLmxlbmd0aH1jYXRjaCh0KXtlLnNlbGZDbG9zZT1uPSExfW89bnVsbCxlLnRhZ1NvdXA9cixlLnNlbGZDbG9zZT1ufSxmdW5jdGlvbih0LGUscil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbih0KXt2YXIgZT10LmluZGV4T2YoXCItLT5cIik7aWYoZT49MClyZXR1cm4gbmV3IGMuQ29tbWVudFRva2VuKHQuc3Vic3RyKDQsZS0xKSxlKzMpfWZ1bmN0aW9uIG8odCl7dmFyIGU9dC5pbmRleE9mKFwiPFwiKTtyZXR1cm4gbmV3IGMuQ2h
1hcnNUb2tlbihlPj0wP2U6dC5sZW5ndGgpfWZ1bmN0aW9uIGkodCl7dmFyIGU9dC5pbmRleE9mKFwiPlwiKTtpZihlIT09LTEpe3ZhciByPXQubWF0Y2gobC5zdGFydFRhZyk7aWYocil7dmFyIG49ZnVuY3Rpb24oKXt2YXIgdD17fSxlPXt9LG49clsyXTtyZXR1cm4gclsyXS5yZXBsYWNlKGwuYXR0cixmdW5jdGlvbihyLG8pe2FyZ3VtZW50c1syXXx8YXJndW1lbnRzWzNdfHxhcmd1bWVudHNbNF18fGFyZ3VtZW50c1s1XT9hcmd1bWVudHNbNV0/KHRbYXJndW1lbnRzWzVdXT1cIlwiLGVbYXJndW1lbnRzWzVdXT0hMCk6dFtvXT1hcmd1bWVudHNbMl18fGFyZ3VtZW50c1szXXx8YXJndW1lbnRzWzRdfHxsLmZpbGxBdHRyLnRlc3QobykmJm98fFwiXCI6dFtvXT1cIlwiLG49bi5yZXBsYWNlKHIsXCJcIil9KSx7XCJ2XCI6bmV3IGMuU3RhcnRUYWdUb2tlbihyWzFdLHJbMF0ubGVuZ3RoLHQsZSwoISFyWzNdKSxuLnJlcGxhY2UoL15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nLFwiXCIpKX19KCk7aWYoXCJvYmplY3RcIj09PShcInVuZGVmaW5lZFwiPT10eXBlb2Ygbj9cInVuZGVmaW5lZFwiOnUobikpKXJldHVybiBuLnZ9fX1mdW5jdGlvbiBhKHQpe3ZhciBlPWkodCk7aWYoZSl7dmFyIHI9dC5zbGljZShlLmxlbmd0aCk7aWYoci5tYXRjaChuZXcgUmVnRXhwKFwiPC9cXFxccypcIitlLnRhZ05hbWUrXCJcXFxccyo+XCIsXCJpXCIpKSl7dmFyIG49ci5tYXRjaChuZXcgUmVnRXhwKFwiKFtcXFxcc1xcXFxTXSo/KTwvXFxcXHMqXCIrZS50YWdOYW1lK1wiXFxcXHMqPlwiLFwiaVwiKSk7aWYobilyZXR1cm4gbmV3IGMuQXRvbWljVGFnVG9rZW4oZS50YWdOYW1lLG5bMF0ubGVuZ3RoK2UubGVuZ3RoLGUuYXR0cnMsZS5ib29sZWFuQXR0cnMsblsxXSl9fX1mdW5jdGlvbiBzKHQpe3ZhciBlPXQubWF0Y2gobC5lbmRUYWcpO2lmKGUpcmV0dXJuIG5ldyBjLkVuZFRhZ1Rva2VuKGVbMV0sZVswXS5sZW5ndGgpfWUuX19lc01vZHVsZT0hMDt2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiBTeW1ib2wmJlwic3ltYm9sXCI9PXR5cGVvZiBTeW1ib2wuaXRlcmF0b3I/ZnVuY3Rpb24odCl7cmV0dXJuIHR5cGVvZiB0fTpmdW5jdGlvbih0KXtyZXR1cm4gdCYmXCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZ0LmNvbnN0cnVjdG9yPT09U3ltYm9sJiZ0IT09U3ltYm9sLnByb3RvdHlwZT9cInN5bWJvbFwiOnR5cGVvZiB0fTtlLmNvbW1lbnQ9bixlLmNoYXJzPW8sZS5zdGFydFRhZz1pLGUuYXRvbWljVGFnPWEsZS5lbmRUYWc9czt2YXIgYz1yKDQpLGw9e1wic3RhcnRUYWdcIjovXjwoW1xcLUEtWmEtejAtOV9dKykoKD86XFxzK1tcXHdcXC1dKyg/Olxccyo9P1xccyooPzooPzpcIlteXCJdKlwiKXwoPzonW14nXSonKXxbXj5cXHNdKykpPykqKVxccyooXFwvPyk+LyxcImVuZFRhZ1wiOi9ePFxcLyhbXFwtQS1aYS16MC05X10rKVtePl0qPi8sXCJhdHRyXCI6Lyg/OihbXFwtQS1aYS16MC05X10rKVxccyo9XFxzKig/Oig/OlwiKCg/OlxcXFwufFteXCJdKSopXCIpfCg/OicoKD86XFxcXC58W14nXSkqKScpfChbXj5cXHNdKykpKXwoPzooW1xcLUEtWmEtejAtOV9dKykoXFxzfCQpKykvZyxcImZpbGxBdHRyXCI6L14oY2hlY2tlZHxjb21wYWN0fGRlY2xhcmV8ZGVmZXJ8ZGlzYWJsZWR8aXNtYXB8bXVsdGlwbGV8bm9ocmVmfG5vcmVzaXplfG5vc2hhZGV8bm93cmFwfHJlYWRvbmx5fHNlbGVjdGVkKSQvaX19LGZ1bmN0aW9uKHQsZSxyKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBuKHQsZSl7aWYoISh0IGluc3RhbmNlb2YgZSkpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKX1lLl9fZXNNb2R1bGU9ITAsZS5FbmRUYWdUb2tlbj1lLkF0b21pY1RhZ1Rva2VuPWUuU3RhcnRUYWdUb2tlbj1lLlRhZ1Rva2VuPWUuQ2hhcnNUb2tlbj1lLkNvbW1lbnRUb2tlbj1lLlRva2VuPXZvaWQgMDt2YXIgbz1yKDUpLGk9KGUuVG9rZW49ZnVuY3Rpb24gdChlLHIpe24odGhpcyx0KSx0aGlzLnR5cGU9ZSx0aGlzLmxlbmd0aD1yLHRoaXMudGV4dD1cIlwifSxlLkNvbW1lbnRUb2tlbj1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoZSxyKXtuKHRoaXMsdCksdGhpcy50eXBlPVwiY29tbWVudFwiLHRoaXMubGVuZ3RoPXJ8fChlP2UubGVuZ3RoOjApLHRoaXMudGV4dD1cIlwiLHRoaXMuY29udGVudD1lfXJldHVybiB0LnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVyblwiPCEtLVwiK3RoaXMuY29udGVudH0sdH0oKSxlLkNoYXJzVG9rZW49ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KGUpe24odGhpcyx0KSx0aGlzLnR5cGU9XCJjaGFyc1wiLHRoaXMubGVuZ3RoPWUsdGhpcy50ZXh0PVwiXCJ9cmV0dXJuIHQucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGV4dH0sdH0oKSxlLlRhZ1Rva2VuPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdChlLHIsbyxpLGEpe24odGhpcyx0KSx0aGlzLnR5cGU9ZSx0aGlzLmxlbmd0aD1vLHRoaXMudGV4dD1cIlwiLHRoaXMudGFnTmFtZT1yLHRoaXMuYXR0cnM9aSx0aGlzLmJvb2xlYW5BdHRycz1hLHRoaXMudW5hcnk9ITEsdGhpcy5odG1sNVVuYXJ5PSExfXJldHVybiB0LmZvcm1hdFRhZz1mdW5jdGlvbih0KXt2YXIgZT1hcmd1bWVudHMubGVuZ3RoPjEmJnZvaWQgMCE9PWFyZ3VtZW50c1sxXT9hcmd1bWVudHNbMV06bnVsbCxyPVwiPFwiK3QudGFnTmFtZTtmb3IodmFyIG4gaW4gdC5hdHRycylpZih0LmF0dHJzLmhhc093blByb3BlcnR5KG4pKXtyKz1cIiBcIituO3ZhciBpPXQuYXR0cnNbbl07XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQuYm9vbGVhbkF0dHJzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5ib29sZWFuQXR0cnNbbl18fChyKz0nPVwiJysoMCxvLmVzY2FwZVF1b3RlcykoaSkrJ1wiJyl9cmV0dXJuIHQucmVzdCYmKHIrPVwiIFwiK3QucmVzdCkscis9dC51bmFyeSYmIXQuaHRtbDVVbmFyeT9cIi8+XCI6XCI+XCIsdm9pZCAwIT09ZSYmbnVsbCE9PWUmJihyKz1lK1wiPC9cIit0LnRhZ05hbWUrXCI+XCIpLHJ9LHR9KCkpO2UuU3RhcnRUYWdUb2tlbj1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoZSxyLG8saSxhLHMpe24odGhpcyx0KSx0aGlzLnR5cGU9XCJzdGFydFRhZ1wiLHRoaXMubGVuZ3RoPXIsdGhpcy50ZXh0PVwiXCIsdGhpcy50YWdOYW1lPWUsdGhpcy5hdHRycz1vLHRoaXMuYm9vbGVhbkF0dHJzPWksdGhpcy5odG1sNVVuYXJ5PSExLHRoaXMudW5hcnk9YSx0aGlzLnJlc3Q9c31yZXR1cm4gdC5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gaS5mb3JtYXRUYWcodGhpcyl9LHR9KCksZS5BdG9taWNUYWdUb2tlbj1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoZSxyLG8saSxhKXtuKHRoaXMsdCksdGhpcy50eXBlPVwiYXRvbWljVGFnXCIsdGhpcy5sZW5ndGg9cix0aGlzLnRleHQ9XCJcIix0aGlzLnRhZ05hbWU9ZSx0aGlzLmF0dHJzPW8sdGhpcy5ib29sZWFuQXR0cnM9aSx0aGlzLnVuYXJ5PSExLHRoaXMuaHRtbDVVbmFyeT0hMSx0aGlzLmNvbnRlbnQ9YX1yZXR1cm4gdC5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gaS5mb3JtYXRUYWcodGhpcyx0aGlzLmNvbnRlbnQpfSx0fSgpLGUuRW5kVGFnVG9rZW49ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KGUscil7bih0aGlzLHQpLHRoaXMudHlwZT1cImVuZFRhZ1wiLHRoaXMubGVuZ3RoPXIsdGhpcy50ZXh0PVwiXCIsdGhpcy50YWdOYW1lPWV9cmV0dXJuIHQucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuXCI8L1wiK3RoaXMudGFnTmFtZStcIj5cIn0sdH0oKX0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiByKHQpe3ZhciBlPWFyZ3VtZW50cy5sZW5ndGg+MSYmdm9pZCAwIT09YXJndW1lbnRzWzFdP2FyZ3VtZW50c1sxXTpcIlwiO3JldHVybiB0P3QucmVwbGFjZSgvKFteXCJdKilc
1Ii9nLGZ1bmN0aW9uKHQsZSl7cmV0dXJuL1xcXFwvLnRlc3QoZSk/ZSsnXCInOmUrJ1xcXFxcIid9KTplfWUuX19lc01vZHVsZT0hMCxlLmVzY2FwZVF1b3Rlcz1yfSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIHIodCl7cmV0dXJuIHQmJlwic3RhcnRUYWdcIj09PXQudHlwZSYmKHQudW5hcnk9cy50ZXN0KHQudGFnTmFtZSl8fHQudW5hcnksdC5odG1sNVVuYXJ5PSEvXFwvPiQvLnRlc3QodC50ZXh0KSksdH1mdW5jdGlvbiBuKHQsZSl7dmFyIG49dC5zdHJlYW0sbz1yKGUoKSk7cmV0dXJuIHQuc3RyZWFtPW4sb31mdW5jdGlvbiBvKHQsZSl7dmFyIHI9ZS5wb3AoKTt0LnByZXBlbmQoXCI8L1wiK3IudGFnTmFtZStcIj5cIil9ZnVuY3Rpb24gaSgpe3ZhciB0PVtdO3JldHVybiB0Lmxhc3Q9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc1t0aGlzLmxlbmd0aC0xXX0sdC5sYXN0VGFnTmFtZUVxPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMubGFzdCgpO3JldHVybiBlJiZlLnRhZ05hbWUmJmUudGFnTmFtZS50b1VwcGVyQ2FzZSgpPT09dC50b1VwcGVyQ2FzZSgpfSx0LmNvbnRhaW5zVGFnTmFtZT1mdW5jdGlvbih0KXtmb3IodmFyIGUscj0wO2U9dGhpc1tyXTtyKyspaWYoZS50YWdOYW1lPT09dClyZXR1cm4hMDtyZXR1cm4hMX0sdH1mdW5jdGlvbiBhKHQsZSxhKXtmdW5jdGlvbiBzKCl7dmFyIGU9bih0LGEpO2UmJmxbZS50eXBlXSYmbFtlLnR5cGVdKGUpfXZhciBjPWkoKSxsPXtcInN0YXJ0VGFnXCI6ZnVuY3Rpb24ocil7dmFyIG49ci50YWdOYW1lO1wiVFJcIj09PW4udG9VcHBlckNhc2UoKSYmYy5sYXN0VGFnTmFtZUVxKFwiVEFCTEVcIik/KHQucHJlcGVuZChcIjxUQk9EWT5cIikscygpKTplLnNlbGZDbG9zZUZpeCYmdS50ZXN0KG4pJiZjLmNvbnRhaW5zVGFnTmFtZShuKT9jLmxhc3RUYWdOYW1lRXEobik/byh0LGMpOih0LnByZXBlbmQoXCI8L1wiK3IudGFnTmFtZStcIj5cIikscygpKTpyLnVuYXJ5fHxjLnB1c2gocil9LFwiZW5kVGFnXCI6ZnVuY3Rpb24ocil7dmFyIG49Yy5sYXN0KCk7bj9lLnRhZ1NvdXBGaXgmJiFjLmxhc3RUYWdOYW1lRXEoci50YWdOYW1lKT9vKHQsYyk6Yy5wb3AoKTplLnRhZ1NvdXBGaXgmJihhKCkscygpKX19O3JldHVybiBmdW5jdGlvbigpe3JldHVybiBzKCkscihhKCkpfX1lLl9fZXNNb2R1bGU9ITAsZVtcImRlZmF1bHRcIl09YTt2YXIgcz0vXihBUkVBfEJBU0V8QkFTRUZPTlR8QlJ8Q09MfEZSQU1FfEhSfElNR3xJTlBVVHxJU0lOREVYfExJTkt8TUVUQXxQQVJBTXxFTUJFRCkkL2ksdT0vXihDT0xHUk9VUHxERHxEVHxMSXxPUFRJT05TfFB8VER8VEZPT1R8VEh8VEhFQUR8VFIpJC9pfV0pfSl9LGZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gcih0KXtyZXR1cm4gdm9pZCAwIT09dCYmbnVsbCE9PXR9ZnVuY3Rpb24gbih0KXtyZXR1cm5cImZ1bmN0aW9uXCI9PXR5cGVvZiB0fWZ1bmN0aW9uIG8odCxlLHIpe3ZhciBuPXZvaWQgMCxvPXQmJnQubGVuZ3RofHwwO2ZvcihuPTA7bj
1xvO24rKyllLmNhbGwocix0W25dLG4pfWZ1bmN0aW9uIGkodCxlLHIpe2Zvcih2YXIgbiBpbiB0KXQuaGFzT3duUHJvcGVydHkobikmJmUuY2FsbChyLG4sdFtuXSl9ZnVuY3Rpb24gYSh0LGUpe3JldHVybiB0PXR8fHt9LGkoZSxmdW5jdGlvbihlLG4pe3IodFtlXSl8fCh0W2VdPW4pfSksdH1mdW5jdGlvbiBzKHQpe3RyeXtyZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodCl9Y2F0Y2gocil7dmFyIGU9ZnVuY3Rpb24oKXt2YXIgZT1bXTtyZXR1cm4gbyh0LGZ1bmN0aW9uKHQpe2UucHVzaCh0KX0pLHtcInZcIjplfX0oKTtpZihcIm9iamVjdFwiPT09KFwidW5kZWZpbmVkXCI9PXR5cGVvZiBlP1widW5kZWZpbmVkXCI6ZihlKSkpcmV0dXJuIGUudn19ZnVuY3Rpb24gdSh0KXtyZXR1cm4gdFt0Lmxlbmd0aC0xXX1mdW5jdGlvbiBjKHQsZSl7cmV0dXJuISghdHx8XCJzdGFydFRhZ1wiIT09dC50eXBlJiZcImF0b21pY1RhZ1wiIT09dC50eXBlfHwhKFwidGFnTmFtZVwiaW4gdCkpJiYhIX50LnRhZ05hbWUudG9Mb3dlckNhc2UoKS5pbmRleE9mKGUpfWZ1bmN0aW9uIGwodCl7cmV0dXJuIGModCxcInNjcmlwdFwiKX1mdW5jdGlvbiBwKHQpe3JldHVybiBjKHQsXCJzdHlsZVwiKX1lLl9fZXNNb2R1bGU9ITA7dmFyIGY9XCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZcInN5bWJvbFwiPT10eXBlb2YgU3ltYm9sLml0ZXJhdG9yP2Z1bmN0aW9uKHQpe3JldHVybiB0eXBlb2YgdH06ZnVuY3Rpb24odCl7cmV0dXJuIHQmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmdC5jb25zdHJ1Y3Rvcj09PVN5bWJvbCYmdCE9PVN5bWJvbC5wcm90b3R5cGU/XCJzeW1ib2xcIjp0eXBlb2YgdH07ZS5leGlzdHk9cixlLmlzRnVuY3Rpb249bixlLmVhY2g9byxlLmVhY2hLZXk9aSxlLmRlZmF1bHRzPWEsZS50b0FycmF5PXMsZS5sYXN0PXUsZS5pc1RhZz1jLGUuaXNTY3JpcHQ9bCxlLmlzU3R5bGU9cH1dKX0pOyJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///782\n')},458:()=>{"use strict";eval('\n\n(function () {\n  var PolyfillEvent = eventConstructor();\n  function eventConstructor() {\n    if (typeof window.CustomEvent === "function") return window.CustomEvent;\n    // IE<=9 Support\n    function CustomEvent(event, params) {\n      params = params || {\n        bubbles: false,\n        cancelable: false,\n        detail: undefined\n      };\n      var evt = document.createEvent(\'CustomEvent\');\n      evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n      return evt;\n    }\n    CustomEvent.prototype = window.Event.prototype;\n    return CustomEvent;\n  }\n  function buildHiddenInput(name, value) {\n    var input = document.createElement("input");\n    input.type = "hidden";\n    input.name = name;\n    input.value = value;\n    return input;\n  }\n  function handleClick(element, targetModifierKey) {\n    var to = element.getAttribute("data-to"),\n      method = buildHiddenInput("_method", element.getAttribute("data-method")),\n      csrf = buildHiddenInput("_csrf_token", element.getAttribute("data-csrf")),\n      form = document.createElement("form"),\n      submit = document.createElement("input"),\n      target = element.getAttribute("target");\n    form.method = element.getAttribute("data-method") === "get" ? "get" : "post";\n    form.action = to;\n    form.style.display = "none";\n    if (target) form.target = target;else if (targetModifierKey) form.target = "_blank";\n    form.appendChild(csrf);\n    form.appendChild(method);\n    document.body.appendChild(form);\n\n    // Insert a button and click it instead of using `form.submit`\n    // because the `submit` function does not emit a `submit` event.\n    submit.type = "submit";\n    form.appendChild(submit);\n    submit.click();\n  }\n  window.addEventListener("click", function (e) {\n    var element = e.target;\n    if (e.defaultPrevented) return;\n    while (element && element.getAttribute) {\n      var phoenixLinkEvent = new PolyfillEvent(\'phoenix.link.click\', {\n        "bubbles": true,\n        "cancelable": true\n      });\n      if (!element.dispatchEvent(phoenixLinkEvent)) {\n        e.preventDefault();\n        e.stopImmediatePropagation();\n        return false;\n      }\n      if (element.getAttribute("data-method") && element.getAttribute("data-to")) {\n        handleClick(element, e.metaKey || e.shiftKey);\n        e.preventDefault();\n        return false;\n      } else {\n        element = element.parentNode;\n      }\n    }\n  }, false);\n  window.addEventListener(\'phoenix.link.click\', function (e) {\n    var message = e.target.getAttribute("data-confirm");\n    if (message && !window.confirm(message)) {\n      e.preventDefault();\n    }\n  }, false);\n})();//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDU4LmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uL2RlcHMvcGhvZW5peF9odG1sL3ByaXYvc3RhdGljL3Bob2VuaXhfaHRtbC5qcz80N2Q4Il0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBQb2x5ZmlsbEV2ZW50ID0gZXZlbnRDb25zdHJ1Y3RvcigpO1xuXG4gIGZ1bmN0aW9uIGV2ZW50Q29uc3RydWN0b3IoKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cuQ3VzdG9tRXZlbnQgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHdpbmRvdy5DdXN0b21FdmVudDtcbiAgICAvLyBJRTw9OSBTdXBwb3J0XG4gICAgZnVuY3Rpb24gQ3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcykge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHtidWJibGVzOiBmYWxzZSwgY2FuY2VsYWJsZTogZmFsc2UsIGRldGFpbDogdW5kZWZpbmVkfTtcbiAgICAgIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTtcbiAgICAgIGV2dC5pbml0Q3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcy5idWJibGVzLCBwYXJhbXMuY2FuY2VsYWJsZSwgcGFyYW1zLmRldGFpbCk7XG4gICAgICByZXR1cm4gZXZ0O1xuICAgIH1cbiAgICBDdXN0b21FdmVudC5wcm90b3R5cGUgPSB3aW5kb3cuRXZlbnQucHJvdG90eXBlO1xuICAgIHJldHVybi
1BDdXN0b21FdmVudDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1aWxkSGlkZGVuSW5wdXQobmFtZSwgdmFsdWUpIHtcbiAgICB2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gICAgaW5wdXQudHlwZSA9IFwiaGlkZGVuXCI7XG4gICAgaW5wdXQubmFtZSA9IG5hbWU7XG4gICAgaW5wdXQudmFsdWUgPSB2YWx1ZTtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVDbGljayhlbGVtZW50LCB0YXJnZXRNb2RpZmllcktleSkge1xuICAgIHZhciB0byA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS10b1wiKSxcbiAgICAgICAgbWV0aG9kID0gYnVpbGRIaWRkZW5JbnB1dChcIl9tZXRob2RcIiwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLW1ldGhvZFwiKSksXG4gICAgICAgIGNzcmYgPSBidWlsZEhpZGRlbklucHV0KFwiX2NzcmZfdG9rZW5cIiwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNzcmZcIikpLFxuICAgICAgICBmb3JtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImZvcm1cIiksXG4gICAgICAgIHN1Ym1pdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKSxcbiAgICAgICAgdGFyZ2V0ID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJ0YXJnZXRcIik7XG5cbiAgICBmb3JtLm1ldGhvZCA9IChlbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtbWV0aG9kXCIpID09PSBcImdldFwiKSA/IFwiZ2V0XCIgOiBcInBvc3RcIjtcbiAgICBmb3JtLmFjdGlvbiA9IHRvO1xuICAgIGZvcm0uc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuXG4gICAgaWYgKHRhcmdldCkgZm9ybS50YXJnZXQgPSB0YXJnZXQ7XG4gICAgZWxzZSBpZiAodGFyZ2V0TW9kaWZpZXJLZXkpIGZvcm0udGFyZ2V0ID0gXCJfYmxhbmtcIjtcblxuICAgIGZvcm0uYXBwZW5kQ2hpbGQoY3NyZik7XG4gICAgZm9ybS5hcHBlbmRDaGlsZChtZXRob2QpO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZm9ybSk7XG5cbiAgICAvLyBJbnNlcnQgYSBidXR0b24gYW5kIGNsaWNrIGl0IGluc3RlYWQgb2YgdXNpbmcgYGZvcm0uc3VibWl0YFxuICAgIC8vIGJlY2F1c2UgdGhlIGBzdWJtaXRgIGZ1bmN0aW9uIGRvZXMgbm90IGVtaXQgYSBgc3VibWl0YCBldmVudC5cbiAgICBzdWJtaXQudHlwZSA9IFwic3VibWl0XCI7XG4gICAgZm9ybS5hcHBlbmRDaGlsZChzdWJtaXQpO1xuICAgIHN1Ym1pdC5jbGljaygpO1xuICB9XG5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGVsZW1lbnQgPSBlLnRhcmdldDtcbiAgICBpZiAoZS5kZWZhdWx0UHJldmVudGVkKSByZXR1cm47XG5cbiAgICB3aGlsZSAoZWxlbWVudCAmJiBlbGVtZW50LmdldEF0dHJpYnV0ZSkge1xuICAgICAgdmFyIHBob2VuaXhMaW5rRXZlbnQgPSBuZXcgUG9seWZpbGxFdmVudCgncGhvZW5peC5saW5rLmNsaWNrJywge1xuICAgICAgICBcImJ1YmJsZXNcIjogdHJ1ZSwgXCJjYW5jZWxhYmxlXCI6IHRydWVcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoIWVsZW1lbnQuZGlzcGF0Y2hFdmVudChwaG9lbml4TGlua0V2ZW50KSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1tZXRob2RcIikgJiYgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXRvXCIpKSB7XG4gICAgICAgIGhhbmRsZUNsaWNrKGVsZW1lbnQsIGUubWV0YUtleSB8fCBlLnNoaWZ0S2V5KTtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xuICAgICAgfVxuICAgIH1cbiAgfSwgZmFsc2UpO1xuXG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdwaG9lbml4LmxpbmsuY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgIHZhciBtZXNzYWdlID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb25maXJtXCIpO1xuICAgIGlmKG1lc3NhZ2UgJiYgIXdpbmRvdy5jb25maXJtKG1lc3NhZ2UpKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9LCBmYWxzZSk7XG59KSgpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///458\n')},865:function(module,exports,__webpack_require__){eval("var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress\n * @license MIT */\n\n;(function(root, factory) {\n\n  if (true) {\n    !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :\n\t\t__WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n  } else {}\n\n}
1)(this, function() {\n  var NProgress = {};\n\n  NProgress.version = '0.2.0';\n\n  var Settings = NProgress.settings = {\n    minimum: 0.08,\n    easing: 'ease',\n    positionUsing: '',\n    speed: 200,\n    trickle: true,\n    trickleRate: 0.02,\n    trickleSpeed: 800,\n    showSpinner: true,\n    barSelector: '[role=\"bar\"]',\n    spinnerSelector: '[role=\"spinner\"]',\n    parent: 'body',\n    template: '<div class=\"bar\" role=\"bar\"><div class=\"peg\"></div></div><div class=\"spinner\" role=\"spinner\"><div class=\"spinner-icon\"></div></div>'\n  };\n\n  /**\n   * Updates configuration.\n   *\n   *     NProgress.configure({\n   *       minimum: 0.1\n   *     });\n   */\n  NProgress.configure = function(options) {\n    var key, value;\n    for (key in options) {\n      value = options[key];\n      if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value;\n    }\n\n    return this;\n  };\n\n  /**\n   * Last number.\n   */\n\n  NProgress.status = null;\n\n  /**\n   * Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.\n   *\n   *     NProgress.set(0.4);\n   *     NProgress.set(1.0);\n   */\n\n  NProgress.set = function(n) {\n    var started = NProgress.isStarted();\n\n    n = clamp(n, Settings.minimum, 1);\n    NProgress.status = (n === 1 ? null : n);\n\n    var progress = NProgress.render(!started),\n        bar      = progress.querySelector(Settings.barSelector),\n        speed    = Settings.speed,\n        ease     = Settings.easing;\n\n    progress.offsetWidth; /* Repaint */\n\n    queue(function(next) {\n      // Set positionUsing if it hasn't already been set\n      if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS();\n\n      // Add transition\n      css(bar, barPositionCSS(n, speed, ease));\n\n      if (n === 1) {\n        // Fade out\n        css(progress, { \n          transition: 'none', \n          opacity: 1 \n        });\n        progress.offsetWidth; /* Repaint */\n\n        setTimeout(function() {\n          css(progress, { \n            transition: 'all ' + speed + 'ms linear', \n            opacity: 0 \n          });\n          setTimeout(function() {\n            NProgress.remove();\n            next();\n          }, speed);\n        }, speed);\n      } else {\n        setTimeout(next, speed);\n      }\n    });\n\n    return this;\n  };\n\n  NProgress.isStarted = function() {\n    return typeof NProgress.status === 'number';\n  };\n\n  /**\n   * Shows the progress bar.\n   * This is the same as setting the status to 0%, except that it doesn't go backwards.\n   *\n   *     NProgress.start();\n   *\n   */\n  NProgress.start = function() {\n    if (!NProgress.status) NProgress.set(0);\n\n    var work = function() {\n      setTimeout(function() {\n        if (!NProgress.status) return;\n        NProgress.trickle();\n        work();\n      }, Settings.trickleSpeed);\n    };\n\n    if (Settings.trickle) work();\n\n    return this;\n  };\n\n  /**\n   * Hides the progress bar.\n   * This is the *sort of* the same as setting the status to 100%, with the\n   * difference being `done()` makes some placebo effect of some realistic motion.\n   *\n   *     NProgress.done();\n   *\n   * If `true` is passed, it will show the progress bar even if its hidden.\n   *\n   *     NProgress.done(true);\n   */\n\n  NProgress.done = function(force) {\n    if (!force && !NProgress.status) return this;\n\n    return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);\n  };\n\n  /**\n   * Increments by a random amount.\n   */\n\n  NProgress.inc = function(amount) {\n    var n = NProgress.status;\n\n    if (!n) {\n      return NProgress.start();\n    } else {\n      if (typeof amount !== 'number') {\n        amount = (1 - n) * clamp(Math.random() * n, 0.1, 0.95);\n      }\n\n      n = clamp(n + amount, 0, 0.994);\n      return NProgress.set(n);\n    }\n  };\n\n  NProgress.trickle = function() {\n    return NProgress.inc(Math.random() * Settings.trickleRate);\n  };\n\n  /**\n   * Waits for all supplied jQuery promises and\n   * increases the progress as the promises resolve.\n   *\n   * @param $promise jQUery Promise\n   */\n  (function() {\
1n    var initial = 0, current = 0;\n\n    NProgress.promise = function($promise) {\n      if (!$promise || $promise.state() === \"resolved\") {\n        return this;\n      }\n\n      if (current === 0) {\n        NProgress.start();\n      }\n\n      initial++;\n      current++;\n\n      $promise.always(function() {\n        current--;\n        if (current === 0) {\n            initial = 0;\n            NProgress.done();\n        } else {\n            NProgress.set((initial - current) / initial);\n        }\n      });\n\n      return this;\n    };\n\n  })();\n\n  /**\n   * (Internal) renders the progress bar markup based on the `template`\n   * setting.\n   */\n\n  NProgress.render = function(fromStart) {\n    if (NProgress.isRendered()) return document.getElementById('nprogress');\n\n    addClass(document.documentElement, 'nprogress-busy');\n    \n    var progress = document.createElement('div');\n    progress.id = 'nprogress';\n    progress.innerHTML = Settings.template;\n\n    var bar      = progress.querySelector(Settings.barSelector),\n        perc     = fromStart ? '-100' : toBarPerc(NProgress.status || 0),\n        parent   = document.querySelector(Settings.parent),\n        spinner;\n    \n    css(bar, {\n      transition: 'all 0 linear',\n      transform: 'translate3d(' + perc + '%,0,0)'\n    });\n\n    if (!Settings.showSpinner) {\n      spinner = progress.querySelector(Settings.spinnerSelector);\n      spinner && removeElement(spinner);\n    }\n\n    if (parent != document.body) {\n      addClass(parent, 'nprogress-custom-parent');\n    }\n\n    parent.appendChild(progress);\n    return progress;\n  };\n\n  /**\n   * Removes the element. Opposite of render().\n   */\n\n  NProgress.remove = function() {\n    removeClass(document.documentElement, 'nprogress-busy');\n    removeClass(document.querySelector(Settings.parent), 'nprogress-custom-parent');\n    var progress = document.getElementById('nprogress');\n    progress && removeElement(progress);\n  };\n\n  /**\n   * Checks if the progress bar is rendered.\n   */\n\n  NProgress.isRendered = function() {\n    return !!document.getElementById('nprogress');\n  };\n\n  /**\n   * Determine which positioning CSS rule to use.\n   */\n\n  NProgress.getPositioningCSS = function() {\n    // Sniff on document.body.style\n    var bodyStyle = document.body.style;\n\n    // Sniff prefixes\n    var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' :\n                       ('MozTransform' in bodyStyle) ? 'Moz' :\n                       ('msTransform' in bodyStyle) ? 'ms' :\n                       ('OTransform' in bodyStyle) ? 'O' : '';\n\n    if (vendorPrefix + 'Perspective' in bodyStyle) {\n      // Modern browsers with 3D support, e.g. Webkit, IE10\n      return 'translate3d';\n    } else if (vendorPrefix + 'Transform' in bodyStyle) {\n      // Browsers without 3D support, e.g. IE9\n      return 'translate';\n    } else {\n      // Browsers without translate() support, e.g. IE7-8\n      return 'margin';\n    }\n  };\n\n  /**\n   * Helpers\n   */\n\n  function clamp(n, min, max) {\n    if (n < min) return min;\n    if (n > max) return max;\n    return n;\n  }\n\n  /**\n   * (Internal) converts a percentage (`0..1`) to a bar translateX\n   * percentage (`-100%..0%`).\n   */\n\n  function toBarPerc(n) {\n    return (-1 + n) * 100;\n  }\n\n\n  /**\n   * (Internal) returns the correct CSS for changing the bar's\n   * position given an n percentage, and speed and ease from Settings\n   */\n\n  function barPositionCSS(n, speed, ease) {\n    var barCSS;\n\n    if (Settings.positionUsing === 'translate3d') {\n      barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' };\n    } else if (Settings.positionUsing === 'translate') {\n      barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' };\n    } else {\n      barCSS = { 'margin-left': toBarPerc(n)+'%' };\n    }\n\n    barCSS.transition = 'all '+speed+'ms '+ease;\n\n    return barCSS;\n  }\n\n  /**\n   * (Internal) Queues a function to be executed.\n   */\n\n  var queue = (function() {\n    var pending = [];\n    \n    function next() {\n      var fn = pending.shift();\n      if (fn) {\n        fn(next);\n      }\n    }\n\n    return function(fn) {\n      pending.push(fn);\n      if (pending.length == 1) next();\n    };\n  })();\n\n  /**\n   * (Internal) Applies css properties to an element, similar to the jQuery \n   * css method.\n   *\n   * While this helper does assist with vendor prefixed property names, it \n   * does not perform any manipulation of values prior to setting styles.\n   */\n\n  var css = (function() {\
1n    var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ],\n        cssProps    = {};\n\n    function camelCase(string) {\n      return string.replace(/^-ms-/, 'ms-').replace(/-([\\da-z])/gi, function(match, letter) {\n        return letter.toUpperCase();\n      });\n    }\n\n    function getVendorProp(name) {\n      var style = document.body.style;\n      if (name in style) return name;\n\n      var i = cssPrefixes.length,\n          capName = name.charAt(0).toUpperCase() + name.slice(1),\n          vendorName;\n      while (i--) {\n        vendorName = cssPrefixes[i] + capName;\n        if (vendorName in style) return vendorName;\n      }\n\n      return name;\n    }\n\n    function getStyleProp(name) {\n      name = camelCase(name);\n      return cssProps[name] || (cssProps[name] = getVendorProp(name));\n    }\n\n    function applyCss(element, prop, value) {\n      prop = getStyleProp(prop);\n      element.style[prop] = value;\n    }\n\n    return function(element, properties) {\n      var args = arguments,\n          prop, \n          value;\n\n      if (args.length == 2) {\n        for (prop in properties) {\n          value = properties[prop];\n          if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);\n        }\n      } else {\n        applyCss(element, args[1], args[2]);\n      }\n    }\n  })();\n\n  /**\n   * (Internal) Determines if an element or space separated list of class names contains a class name.\n   */\n\n  function hasClass(element, name) {\n    var list = typeof element == 'string' ? element : classList(element);\n    return list.indexOf(' ' + name + ' ') >= 0;\n  }\n\n  /**\n   * (Internal) Adds a class to an element.\n   */\n\n  function addClass(element, name) {\n    var oldList = classList(element),\n        newList = oldList + name;\n\n    if (hasClass(oldList, name)) return; \n\n    // Trim the opening space.\n    element.className = newList.substring(1);\n  }\n\n  /**\n   * (Internal) Removes a class from an element.\n   */\n\n  function removeClass(element, name) {\n    var oldList = classList(element),\n        newList;\n\n    if (!hasClass(element, name)) return;\n\n    // Replace the class name.\n    newList = oldList.replace(' ' + name + ' ', ' ');
1\n\n    // Trim the opening and closing spaces.\n    element.className = newList.substring(1, newList.length - 1);\n  }\n\n  /**\n   * (Internal) Gets a space separated list of the class names on the element. \n   * The list is wrapped with a single space on each end to facilitate finding \n   * matches within the list.\n   */\n\n  function classList(element) {\n    return (' ' + (element.className || '') + ' ').replace(/\\s+/gi, ' ');\n  }\n\n  /**\n   * (Internal) Removes an element from the DOM.\n   */\n\n  function removeElement(element) {\n    element && element.parentNode && element.parentNode.removeChild(element);\n  }\n\n  return NProgress;\n});\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODY1LmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL25wcm9ncmVzcy9ucHJvZ3Jlc3MuanM/MzIzZSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBOUHJvZ3Jlc3MsIChjKSAyMDEzLCAyMDE0IFJpY28gU3RhLiBDcnV6IC0gaHR0cDovL3JpY29zdGFjcnV6LmNvbS9ucHJvZ3Jlc3NcbiAqIEBsaWNlbnNlIE1JVCAqL1xuXG47KGZ1bmN0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblxuICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgZGVmaW5lKGZhY3RvcnkpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuICB9IGVsc2Uge1xuICAgIHJvb3QuTlByb2dyZXNzID0gZmFjdG9yeSgpO1xuICB9XG5cbn0pKHRoaXMsIGZ1bmN0aW9uKCkge1xuICB2YXIgTlByb2dyZXNzID0ge307XG5cbiAgTlByb2dyZXNzLnZlcnNpb24gPSAnMC4yLjAnO1xuXG4gIHZhciBTZXR0aW5ncyA9IE5Qcm9ncmVzcy5zZXR0aW5ncyA9IHtcbiAgICBtaW5pbXVtOiAwLjA4LFxuICAgIGVhc2luZzogJ2Vhc2UnLFxuICAgIHBvc2l0aW9uVXNpbmc6ICcnLFxuICAgIHNwZWVkOiAyMDAsXG4gICAgdHJpY2tsZTogdHJ1ZSxcbiAgICB0cmlja2xlUmF0ZTogMC4wMixcbiAgICB0cmlja2xlU3BlZWQ6IDgwMCxcbiAgICBzaG93U3Bpbm5lcjogdHJ1ZSxcbiAgICBiYXJTZWxlY3RvcjogJ1tyb2xlPVwiYmFyXCJdJyxcbiAgICBzcGlubmVyU2VsZWN0b3I6ICdbcm9sZT1cInNwaW5uZXJcIl0nLFxuICAgIHBhcmVudDogJ2JvZHknLFxuICAgIHRlbXBsYXRlOiAnPGRpdiBjbGFzcz1cImJhclwiIHJvbGU9XCJiYXJcIj48ZGl2IGNsYXNzPVwicGVnXCI+PC9kaXY+PC9kaXY+PGRpdiBjbGFzcz1cInNwaW5uZXJcIiByb2xlPVwic3Bpbm5lclwiPjxkaXYgY2xhc3M9XCJzcGlubmVyLWljb25cIj48L2Rpdj48L2Rpdj4nXG4gIH07XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgY29uZmlndXJhdGlvbi5cbiAgICpcbiAgICogICAgIE5Qcm9ncmVzcy5jb25maWd1cmUoe1xuICAgKiAgICAgICBtaW5pbXVtOiAwLjFcbiAgICogICAgIH0pO1xuICAgKi9cbiAgTlByb2dyZXNzLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICB2YXIga2V5LCB2YWx1ZTtcbiAgICBmb3IgKGtleSBpbiBvcHRpb25zKSB7XG4gICAgICB2YWx1ZSA9IG9wdGlvbnNba2V5XTtcbiAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMuaGFzT3duUHJvcGVydHkoa2V5KSkgU2V0dGluZ3Nba2V5XSA9IHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8qKlxuICAgKiBMYXN0IG51bWJlci5cbiAgICovXG5cbiAgTlByb2dyZXNzLnN0YXR1cyA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHByb2dyZXNzIGJhciBzdGF0dXMsIHdoZXJlIGBuYCBpcyBhIG51bWJlciBmcm9tIGAwLjBgIHRvIGAxLjBgLlxuICAgKlxuICAgKiAgICAgTlByb2dyZXNzLnNldCgwLjQpO1xuICAgKiAgICAgTlByb2dyZXNzLnNldCgxLjApO1xuICAgKi9cblxuICBOUHJvZ3Jlc3Muc2V0ID0gZnVuY3Rpb24obikge1xuICAgIHZhciBzdGFydGVkID0gTlByb2dyZXNzLmlzU3RhcnRlZCgpO1xuXG4gICAgbiA9IGNsYW1wKG4sIFNldHRpbmdzLm1pbmltdW0sIDEpO1xuICAgIE5Qcm9ncmVzcy5zdGF0dXMgPSAobiA9PT0gMSA/IG51bGwgOiBuKTtcblxuICAgIHZhciBwcm9ncmVzcyA9IE5Qcm9ncmVzcy5yZW5kZXIoIXN0YXJ0ZWQpLFxuICAgICAgICBiYXIgICAgICA9IHByb2dyZXNzLnF1ZXJ5U2VsZWN0b3IoU2V0dGluZ3MuYmFyU2VsZWN0b3IpLFxuICAgICAgICBzcGVlZCAgICA9IFNldHRpbmdzLnNwZWVkLFxuICAgICAgICBlYXNlICAgICA9IFNldHRpbmdzLmVhc2luZztcblxuICAgIHByb2dyZXNzLm9mZnNldFdpZHRoOyAvKiBSZXBhaW50ICovXG5cbiAgICBxdWV1ZShmdW5jdGlvbihuZXh0KSB7XG4gICAgICAvLyBTZXQgcG9zaXRpb25Vc2luZyBpZiBpdCBoYXNuJ3QgYWxyZWFkeSBiZWVuIHNldFxuICAgICAgaWYgKFNldHRpbmdzLnBvc2l0aW9uVXNpbmcgPT09ICcnKSBTZXR0aW5ncy5wb3NpdGlvblVzaW5nID0gTlByb2dyZXNzLmdldFBvc2l0aW9uaW5nQ1NTKCk7XG5cbiAgICAgIC8vIEFkZCB0cmFuc2l0aW9uXG4gICAgICBjc3MoYmFyLCBiYXJQb3NpdGlvbkNTUyhuLCBzcGVlZCwgZWFzZSkpO1xuXG4gICAgICBpZiAobiA9PT0gMSkge1xuICAgICAgICAvLyBGYWRlIG91dFxuICAgICAgICBjc3MocHJvZ3Jlc3MsIHsgXG4gICAgICAgICAgdHJhbnNpdGlvbjogJ25vbmUnLCBcbiAgICAgICAgICBvcGFjaXR5OiAxIFxuICAgICAgICB9KTtcbiAgICAgICAgcHJvZ3Jlc3Mub2Zmc2V0V2lkdGg7IC8qIFJlcGFpbnQgKi9cblxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGNzcyhwcm9ncmVzcywgeyBcbiAgICAgICAgICAgI
1HRyYW5zaXRpb246ICdhbGwgJyArIHNwZWVkICsgJ21zIGxpbmVhcicsIFxuICAgICAgICAgICAgb3BhY2l0eTogMCBcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgTlByb2dyZXNzLnJlbW92ZSgpO1xuICAgICAgICAgICAgbmV4dCgpO1xuICAgICAgICAgIH0sIHNwZWVkKTtcbiAgICAgICAgfSwgc3BlZWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0VGltZW91dChuZXh0LCBzcGVlZCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBOUHJvZ3Jlc3MuaXNTdGFydGVkID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBOUHJvZ3Jlc3Muc3RhdHVzID09PSAnbnVtYmVyJztcbiAgfTtcblxuICAvKipcbiAgICogU2hvd3MgdGhlIHByb2dyZXNzIGJhci5cbiAgICogVGhpcyBpcyB0aGUgc2FtZSBhcyBzZXR0aW5nIHRoZSBzdGF0dXMgdG8gMCUsIGV4Y2VwdCB0aGF0IGl0IGRvZXNuJ3QgZ28gYmFja3dhcmRzLlxuICAgKlxuICAgKiAgICAgTlByb2dyZXNzLnN0YXJ0KCk7XG4gICAqXG4gICAqL1xuICBOUHJvZ3Jlc3Muc3RhcnQgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAoIU5Qcm9ncmVzcy5zdGF0dXMpIE5Qcm9ncmVzcy5zZXQoMCk7XG5cbiAgICB2YXIgd29yayA9IGZ1bmN0aW9uKCkge1xuICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKCFOUHJvZ3Jlc3Muc3RhdHVzKSByZXR1cm47XG4gICAgICAgIE5Qcm9ncmVzcy50cmlja2xlKCk7XG4gICAgICAgIHdvcmsoKTtcbiAgICAgIH0sIFNldHRpbmdzLnRyaWNrbGVTcGVlZCk7XG4gICAgfTtcblxuICAgIGlmIChTZXR0aW5ncy50cmlja2xlKSB3b3JrKCk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvKipcbiAgICogSGlkZXMgdGhlIHByb2dyZXNzIGJhci5cbiAgICogVGhpcyBpcyB0aGUgKnNvcnQgb2YqIHRoZSBzYW1lIGFzIHNldHRpbmcgdGhlIHN0YXR1cyB0byAxMDAlLCB3aXRoIHRoZVxuICAgKiBkaWZmZXJlbmNlIGJlaW5nIGBkb25lKClgIG1ha2VzIHNvbWUgcGxhY2VibyBlZmZlY3Qgb2Ygc29tZSByZWFsaXN0aWMgbW90aW9uLlxuICAgKlxuICAgKiAgICAgTlByb2dyZXNzLmRvbmUoKTtcbiAgICpcbiAgICogSWYgYHRydWVgIGlzIHBhc3NlZCwgaXQgd2lsbCBzaG93IHRoZSBwcm9ncmVzcyBiYXIgZXZlbiBpZiBpdHMgaGlkZGVuLlxuICAgKlxuICAgKiAgICAgTlByb2dyZXNzLmRvbmUodHJ1ZSk7XG4gICAqL1xuXG4gIE5Qcm9ncmVzcy5kb25lID0gZnVuY3Rpb24oZm9yY2UpIHtcbiAgICBpZiAoIWZvcmNlICYmICFOUHJvZ3Jlc3Muc3RhdHVzKSByZXR1cm4gdGhpcztcblxuICAgIHJldHVybiBOUHJvZ3Jlc3MuaW5jKDAuMyArIDAuNSAqIE1hdGgucmFuZG9tKCkpLnNldCgxKTtcbiAgfTtcblxuICAvKipcbiAgICogSW5jcmVtZW50cyBieSBhIHJhbmRvbSBhbW91bnQuXG4gICAqL1xuXG4gIE5Qcm9ncmVzcy5pbmMgPSBmdW5jdGlvbihhbW91bnQpIHtcbiAgICB2YXIgbiA9IE5Qcm9ncmVzcy5zdGF0dXM7XG5cbiAgICBpZiAoIW4pIHtcbiAgICAgIHJldHVybiBOUHJvZ3Jlc3Muc3RhcnQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiBhbW91bnQgIT09ICdudW1iZXInKSB7XG4gICAgICAgIGFtb3VudCA9ICgxIC0gbikgKiBjbGFtcChNYXRoLnJhbmRvbSgpICogbiwgMC4xLCAwLjk1KTtcbiAgICAgIH1cblxuICAgICAgbiA9IGNsYW1wKG4gKyBhbW91bnQsIDAsIDAuOTk0KTtcbiAgICAgIHJldHVybiBOUHJvZ3Jlc3Muc2V0KG4pO1xuICAgIH1cbiAgfTtcblxuICBOUHJvZ3Jlc3MudHJpY2tsZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBOUHJvZ3Jlc3MuaW5jKE1hdGgucmFuZG9tKCkgKiBTZXR0aW5ncy50cmlja2xlUmF0ZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFdhaXRzIGZvciBhbGwgc3VwcGxpZWQgalF1ZXJ5IHByb21pc2VzIGFuZFxuICAgKiBpbmNyZWFzZXMgdGhlIHByb2dyZXNzIGFzIHRoZSBwcm9taXNlcyByZXNvbHZlLlxuICAgKlxuICAgKiBAcGFyYW0gJHByb21pc2UgalFVZXJ5IFByb21pc2VcbiAgICovXG4gIChmdW5jdGlvbigpIHtcbiAgICB2YXIgaW5pdGlhbCA9IDAsIGN1cnJlbnQgPSAwO1xuXG4gICAgTlByb2dyZXNzLnByb21pc2UgPSBmdW5jdGlvbigkcHJvbWlzZSkge1xuICAgICAgaWYgKCEkcHJvbWlzZSB8fCAkcHJvbWlzZS5zdGF0ZSgpID09PSBcInJlc29sdmVkXCIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXJyZW50ID09PSAwKSB7XG4gICAgICAgIE5Qcm9ncmVzcy5zdGFydCgpO1xuICAgICAgfVxuXG4gICAgICBpbml0aWFsKys7XG4gICAgICBjdXJyZW50Kys7XG5cbiAgICAgICRwcm9taXNlLmFsd2F5cyhmdW5jdGlvbigpIHtcbiAgICAgICAgY3VycmVudC0tO1xuICAgICAgICBpZiAoY3VycmVudCA9PT0gMCkge1xuICAgICAgICAgICAgaW5pdGlhbCA9IDA7XG4gICAgICAgICAgICBOUHJvZ3Jlc3MuZG9uZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTlByb2dyZXNzLnNldCgoaW5pdGlhbCAtIGN1cnJlbnQpIC8gaW5pdGlhbCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gIH0pKCk7XG5cbiAgLyoqXG4gICAqIChJbnRlcm5hbCkgcmVuZGVycyB0aGUgcHJvZ3Jlc3MgYmFyIG1hcmt1cCBiYXNlZCBvbiB0aGUgYHRlbXBsYXRlYFxuICAgKiBzZXR0aW5nLlxuICAgKi9cblxuICBOUHJvZ3Jlc3MucmVuZGVyID0gZnVuY3Rpb24oZnJvbVN0YXJ0KSB7XG4gICAgaWYgKE5Qcm9ncmVzcy5pc1JlbmRlcmVkKCkpIHJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbnByb2dyZXNzJyk7XG5cbiAgICBhZGRDbGFzcyhkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICducHJvZ3Jlc3MtYnVzeScpO1xuICAgIFxuICAgIHZhciBwcm9ncmVzcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHByb2dyZXNzLmlkID0gJ25wcm9ncmVzcyc7XG4gICAgcHJvZ3Jlc3MuaW5uZXJIVE1MID0gU2V0dGluZ3MudGVtcGxhdGU7XG5cbiAgICB2YXIgYmFyICAgICAgPSBwcm9ncmVzcy5xdWVyeVNlbGVjdG9yKFNldHRpbmdzLmJhclNlbGVjdG9yKSxcbiAgICAgICAgcGVyYyAgICAgPSBmcm9tU3RhcnQgPyAnLTEwMCcgOiB0b0JhclBlcmMoTlByb2dyZXNzLnN0YXR1cyB8fCAwKSxcbiAgICAgICAgcGFyZW50ICAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFNldHRpbmdzLnBhcmVudCksXG4gICAgICAgI
1HNwaW5uZXI7XG4gICAgXG4gICAgY3NzKGJhciwge1xuICAgICAgdHJhbnNpdGlvbjogJ2FsbCAwIGxpbmVhcicsXG4gICAgICB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgnICsgcGVyYyArICclLDAsMCknXG4gICAgfSk7XG5cbiAgICBpZiAoIVNldHRpbmdzLnNob3dTcGlubmVyKSB7XG4gICAgICBzcGlubmVyID0gcHJvZ3Jlc3MucXVlcnlTZWxlY3RvcihTZXR0aW5ncy5zcGlubmVyU2VsZWN0b3IpO1xuICAgICAgc3Bpbm5lciAmJiByZW1vdmVFbGVtZW50KHNwaW5uZXIpO1xuICAgIH1cblxuICAgIGlmIChwYXJlbnQgIT0gZG9jdW1lbnQuYm9keSkge1xuICAgICAgYWRkQ2xhc3MocGFyZW50LCAnbnByb2dyZXNzLWN1c3RvbS1wYXJlbnQnKTtcbiAgICB9XG5cbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQocHJvZ3Jlc3MpO1xuICAgIHJldHVybiBwcm9ncmVzcztcbiAgfTtcblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgZWxlbWVudC4gT3Bwb3NpdGUgb2YgcmVuZGVyKCkuXG4gICAqL1xuXG4gIE5Qcm9ncmVzcy5yZW1vdmUgPSBmdW5jdGlvbigpIHtcbiAgICByZW1vdmVDbGFzcyhkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICducHJvZ3Jlc3MtYnVzeScpO1xuICAgIHJlbW92ZUNsYXNzKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoU2V0dGluZ3MucGFyZW50KSwgJ25wcm9ncmVzcy1jdXN0b20tcGFyZW50Jyk7XG4gICAgdmFyIHByb2dyZXNzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25wcm9ncmVzcycpO1xuICAgIHByb2dyZXNzICYmIHJlbW92ZUVsZW1lbnQocHJvZ3Jlc3MpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIHByb2dyZXNzIGJhciBpcyByZW5kZXJlZC5cbiAgICovXG5cbiAgTlByb2dyZXNzLmlzUmVuZGVyZWQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gISFkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbnByb2dyZXNzJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIERldGVybWluZSB3aGljaCBwb3NpdGlvbmluZyBDU1MgcnVsZSB0byB1c2UuXG4gICAqL1xuXG4gIE5Qcm9ncmVzcy5nZXRQb3NpdGlvbmluZ0NTUyA9IGZ1bmN0aW9uKCkge1xuICAgIC8vIFNuaWZmIG9uIGRvY3VtZW50LmJvZHkuc3R5bGVcbiAgICB2YXIgYm9keVN0eWxlID0gZG9jdW1lbnQuYm9keS5zdHlsZTtcblxuICAgIC8vIFNuaWZmIHByZWZpeGVzXG4gICAgdmFyIHZlbmRvclByZWZpeCA9ICgnV2Via2l0VHJhbnNmb3JtJyBpbiBib2R5U3R5bGUpID8gJ1dlYmtpdCcgOlxuICAgICAgICAgICAgICAgICAgICAgICAoJ01velRyYW5zZm9ybScgaW4gYm9keVN0eWxlKSA/ICdNb3onIDpcbiAgICAgICAgICAgICAgICAgICAgICAgKCdtc1RyYW5zZm9ybScgaW4gYm9keVN0eWxlKSA/ICdtcycgOlxuICAgICAgICAgICAgICAgICAgICAgICAoJ09UcmFuc2Zvcm0nIGluIGJvZHlTdHlsZSkgPyAnTycgOiAnJztcblxuICAgIGlmICh2ZW5kb3JQcmVmaXggKyAnUGVyc3BlY3RpdmUnIGluIGJvZHlTdHlsZSkge1xuICAgICAgLy8gTW9kZXJuIGJyb3dzZXJzIHdpdGggM0Qgc3VwcG9ydCwgZS5nLiBXZWJraXQsIElFMTBcbiAgICAgIHJldHVybiAndHJhbnNsYXRlM2QnO1xuICAgIH0gZWxzZSBpZiAodmVuZG9yUHJlZml4ICsgJ1RyYW5zZm9ybScgaW4gYm9keVN0eWxlKSB7XG4gICAgICAvLyBCcm93c2VycyB3aXRob3V0IDNEIHN1cHBvcnQsIGUuZy4gSUU5XG4gICAgICByZXR1cm4gJ3RyYW5zbGF0ZSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEJyb3dzZXJzIHdpdGhvdXQgdHJhbnNsYXRlKCkgc3VwcG9ydCwgZS5nLiBJRTctOFxuICAgICAgcmV0dXJuICdtYXJnaW4nO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogSGVscGVyc1xuICAgKi9cblxuICBmdW5jdGlvbiBjbGFtcChuLCBtaW4sIG1heCkge1xuICAgIGlmIChuIDwgbWluKSByZXR1cm4gbWluO1xuICAgIGlmIChuID4gbWF4KSByZXR1cm4gbWF4O1xuICAgIHJldHVybiBuO1xuICB9XG5cbiAgLyoqXG4gICAqIChJbnRlcm5hbCkgY29udmVydHMgYSBwZXJjZW50YWdlIChgMC4uMWApIHRvIGEgYmFyIHRyYW5zbGF0ZVhcbiAgICogcGVyY2VudGFnZSAoYC0xMDAlLi4wJWApLlxuICAgKi9cblxuICBmdW5jdGlvbiB0b0JhclBlcmMobikge1xuICAgIHJldHVybiAoLTEgKyBuKSAqIDEwMDtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIChJbnRlcm5hbCkgcmV0dXJucyB0aGUgY29ycmVjdCBDU1MgZm9yIGNoYW5naW5nIHRoZSBiYXInc1xuICAgKiBwb3NpdGlvbiBnaXZlbiBhbiBuIHBlcmNlbnRhZ2UsIGFuZCBzcGVlZCBhbmQgZWFzZSBmcm9tIFNldHRpbmdzXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGJhclBvc2l0aW9uQ1NTKG4sIHNwZWVkLCBlYXNlKSB7XG4gICAgdmFyIGJhckNTUztcblxuICAgIGlmIChTZXR0aW5ncy5wb3NpdGlvblVzaW5nID09PSAndHJhbnNsYXRlM2QnKSB7XG4gICAgICBiYXJDU1MgPSB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKCcrdG9CYXJQZXJjKG4pKyclLDAsMCknIH07XG4gICAgfSBlbHNlIGlmIChTZXR0aW5ncy5wb3NpdGlvblVzaW5nID09PSAndHJhbnNsYXRlJykge1xuICAgICAgYmFyQ1NTID0geyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUoJyt0b0JhclBlcmMobikrJyUsMCknIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGJhckNTUyA9IHsgJ21hcmdpbi1sZWZ0JzogdG9CYXJQZXJjKG4pKyclJyB9O1xuICAgIH1cblxuICAgIGJhckNTUy50cmFuc2l0aW9uID0gJ2FsbCAnK3NwZWVkKydtcyAnK2Vhc2U7XG5cbiAgICByZXR1cm4gYmFyQ1NTO1xuICB9XG5cbiAgLyoqXG4gICAqIChJbnRlcm5hbCkgUXVldWVzIGEgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQuXG4gICAqL1xuXG4gIHZhciBxdWV1ZSA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgcGVuZGluZyA9IFtdO1xuICAgIFxuICAgIGZ1bmN0aW9uIG5leHQoKSB7XG4gICAgICB2Y
1XIgZm4gPSBwZW5kaW5nLnNoaWZ0KCk7XG4gICAgICBpZiAoZm4pIHtcbiAgICAgICAgZm4obmV4dCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGZuKSB7XG4gICAgICBwZW5kaW5nLnB1c2goZm4pO1xuICAgICAgaWYgKHBlbmRpbmcubGVuZ3RoID09IDEpIG5leHQoKTtcbiAgICB9O1xuICB9KSgpO1xuXG4gIC8qKlxuICAgKiAoSW50ZXJuYWwpIEFwcGxpZXMgY3NzIHByb3BlcnRpZXMgdG8gYW4gZWxlbWVudCwgc2ltaWxhciB0byB0aGUgalF1ZXJ5IFxuICAgKiBjc3MgbWV0aG9kLlxuICAgKlxuICAgKiBXaGlsZSB0aGlzIGhlbHBlciBkb2VzIGFzc2lzdCB3aXRoIHZlbmRvciBwcmVmaXhlZCBwcm9wZXJ0eSBuYW1lcywgaXQgXG4gICAqIGRvZXMgbm90IHBlcmZvcm0gYW55IG1hbmlwdWxhdGlvbiBvZiB2YWx1ZXMgcHJpb3IgdG8gc2V0dGluZyBzdHlsZXMuXG4gICAqL1xuXG4gIHZhciBjc3MgPSAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNzc1ByZWZpeGVzID0gWyAnV2Via2l0JywgJ08nLCAnTW96JywgJ21zJyBdLFxuICAgICAgICBjc3NQcm9wcyAgICA9IHt9O1xuXG4gICAgZnVuY3Rpb24gY2FtZWxDYXNlKHN0cmluZykge1xuICAgICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC9eLW1zLS8sICdtcy0nKS5yZXBsYWNlKC8tKFtcXGRhLXpdKS9naSwgZnVuY3Rpb24obWF0Y2gsIGxldHRlcikge1xuICAgICAgICByZXR1cm4gbGV0dGVyLnRvVXBwZXJDYXNlKCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRWZW5kb3JQcm9wKG5hbWUpIHtcbiAgICAgIHZhciBzdHlsZSA9IGRvY3VtZW50LmJvZHkuc3R5bGU7XG4gICAgICBpZiAobmFtZSBpbiBzdHlsZSkgcmV0dXJuIG5hbWU7XG5cbiAgICAgIHZhciBpID0gY3NzUHJlZml4ZXMubGVuZ3RoLFxuICAgICAgICAgIGNhcE5hbWUgPSBuYW1lLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgbmFtZS5zbGljZSgxKSxcbiAgICAgICAgICB2ZW5kb3JOYW1lO1xuICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICB2ZW5kb3JOYW1lID0gY3NzUHJlZml4ZXNbaV0gKyBjYXBOYW1lO1xuICAgICAgICBpZiAodmVuZG9yTmFtZSBpbiBzdHlsZSkgcmV0dXJuIHZlbmRvck5hbWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFN0eWxlUHJvcChuYW1lKSB7XG4gICAgICBuYW1lID0gY2FtZWxDYXNlKG5hbWUpO1xuICAgICAgcmV0dXJuIGNzc1Byb3BzW25hbWVdIHx8IChjc3NQcm9wc1tuYW1lXSA9IGdldFZlbmRvclByb3AobmFtZSkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFwcGx5Q3NzKGVsZW1lbnQsIHByb3AsIHZhbHVlKSB7XG4gICAgICBwcm9wID0gZ2V0U3R5bGVQcm9wKHByb3ApO1xuICAgICAgZWxlbWVudC5zdHlsZVtwcm9wXSA9IHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBwcm9wZXJ0aWVzKSB7XG4gICAgICB2Y
1XIgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAgICBwcm9wLCBcbiAgICAgICAgICB2YWx1ZTtcblxuICAgICAgaWYgKGFyZ3MubGVuZ3RoID09IDIpIHtcbiAgICAgICAgZm9yIChwcm9wIGluIHByb3BlcnRpZXMpIHtcbiAgICAgICAgICB2YWx1ZSA9IHByb3BlcnRpZXNbcHJvcF07XG4gICAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgcHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgYXBwbHlDc3MoZWxlbWVudCwgcHJvcCwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhcHBseUNzcyhlbGVtZW50LCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pKCk7XG5cbiAgLyoqXG4gICAqIChJbnRlcm5hbCkgRGV0ZXJtaW5lcyBpZiBhbiBlbGVtZW50IG9yIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIGNsYXNzIG5hbWVzIGNvbnRhaW5zIGEgY2xhc3MgbmFtZS5cbiAgICovXG5cbiAgZnVuY3Rpb24gaGFzQ2xhc3MoZWxlbWVudCwgbmFtZSkge1xuICAgIHZhciBsaXN0ID0gdHlwZW9mIGVsZW1lbnQgPT0gJ3N0cmluZycgPyBlbGVtZW50IDogY2xhc3NMaXN0KGVsZW1lbnQpO1xuICAgIHJldHVybiBsaXN0LmluZGV4T2YoJyAnICsgbmFtZSArICcgJykgPj0gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiAoSW50ZXJuYWwpIEFkZHMgYSBjbGFzcyB0byBhbiBlbGVtZW50LlxuICAgKi9cblxuICBmdW5jdGlvbiBhZGRDbGFzcyhlbGVtZW50LCBuYW1lKSB7XG4gICAgdmFyIG9sZExpc3QgPSBjbGFzc0xpc3QoZWxlbWVudCksXG4gICAgICAgIG5ld0xpc3QgPSBvbGRMaXN0ICsgbmFtZTtcblxuICAgIGlmIChoYXNDbGFzcyhvbGRMaXN0LCBuYW1lKSkgcmV0dXJuOyBcblxuICAgIC8vIFRyaW0gdGhlIG9wZW5pbmcgc3BhY2UuXG4gICAgZWxlbWVudC5jbGFzc05hbWUgPSBuZXdMaXN0LnN1YnN0cmluZygxKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAoSW50ZXJuYWwpIFJlbW92ZXMgYSBjbGFzcyBmcm9tIGFuIGVsZW1lbnQuXG4gICAqL1xuXG4gIGZ1bmN0aW9uIHJlbW92ZUNsYXNzKGVsZW1lbnQsIG5hbWUpIHtcbiAgICB2YXIgb2xkTGlzdCA9IGNsYXNzTGlzdChlbGVtZW50KSxcbiAgICAgICAgbmV3TGlzdDtcblxuICAgIGlmICghaGFzQ2xhc3MoZWxlbWVudCwgbmFtZSkpIHJldHVybjtcblxuICAgIC8vIFJlcGxhY2UgdGhlIGNsYXNzIG5hbWUuXG4gICAgbmV3TGlzdCA9IG9sZExpc3QucmVwbGFjZSgnICcgKyBuYW1lICsgJyAnLCAnICcpO1xuXG4gICAgLy8gVHJpbSB0aGUgb3BlbmluZyBhbmQgY2xvc2luZyBzcGFjZXMuXG4gICAgZWxlbWVudC5jbGFzc05hbWUgPSBuZXdMaXN0LnN1YnN0cmluZygxLCBuZXdMaXN0Lmxlbmd0aCAtIDEpO1xuICB9XG5cbiAgLyoqXG4gICAqIChJbnRlcm5hbCkgR2V0cyBhIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIHRoZSBjbGFzcyBuYW1lcyBvbiB0aGUgZWxlbWVudC4gXG4gICAqIFRoZSBsaXN0IGlzIHdyYXBwZWQgd2l0aCBhIHNpbmdsZSBzcGFjZSBvbiBlYWNoIGVuZCB0byBmYWNpbGl0YXRlIGZpbmRpbmcgXG4gICAqIG1hdGNoZXMgd2l0aGluIHRoZSBsaXN0LlxuICAgKi9cblxuICBmdW5jdGlvbiBjbGFzc0xpc3QoZWxlbWVudCkge1xuICAgIHJldHVybiAoJyAnICsgKGVsZW1lbnQuY2xhc3NOYW1lIHx8ICcnKSArICcgJykucmVwbGFjZSgvXFxzKy9naSwgJyAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAoSW50ZXJuYWwpIFJlbW92ZXMgYW4gZWxlbWVudCBmcm9tIHRoZSBET00uXG4gICAqL1xuXG4gIGZ1bmN0aW9uIHJlbW92ZUVsZW1lbnQoZWxlbWVudCkge1xuICAgIGVsZW1lbnQgJiYgZWxlbWVudC5wYXJlbnROb2RlICYmIGVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbGVtZW50KTtcbiAgfVxuXG4gIHJldHVybiBOUHJvZ3Jlc3M7XG59KTtcblxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0EsV0FJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///865\n")},304:function(module){eval('\n;(function (name, root, factory) {\n  if (true) {\n    module.exports = factory()\n    module.exports.default = factory()\n  }\n  /* istanbul ignore next */\n  else {}\n}(\'slugify\', this, function () {\n  var charMap = JSON.parse(\'{"$":"dollar","%":"percent","&":"and","<":"less",">":"greater","|":"or","¢":"cent","£":"pound","¤":"currency","¥":"yen","©":"(c)","ª":"a","®":"(r)","º":"o","À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","Þ":"TH","ß":"ss","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","þ":"th","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"
1c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"DJ","đ":"dj","Ē":"E","ē":"e","Ė":"E","ė":"e","Ę":"e","ę":"e","Ě":"E","ě":"e","Ğ":"G","ğ":"g","Ä¢":"G","Ä£":"g","Ĩ":"I","Ä©":"i","Ī":"i","Ä«":"i","Ä®":"I","į":"i","İ":"I","ı":"i","Ķ":"k","Ä·":"k","Ä»":"L","ļ":"l","Ľ":"L","ľ":"l","Ł":"L","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","Ō":"O","ō":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ş":"S","ş":"s","Å ":"S","Å¡":"s","Å¢":"T","Å£":"t","Ť":"T","Å¥":"t","Ũ":"U","Å©":"u","Ū":"u","Å«":"u","Å®":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Å´":"W","ŵ":"w","Ŷ":"Y","Å·":"y","Ÿ":"Y","Ź":"Z","ź":"z","Å»":"Z","ż":"z","Ž":"Z","ž":"z","Ə":"E","ƒ":"f","Æ ":"O","Æ¡":"o","Ư":"U","ư":"u","Lj":"LJ","lj":"lj","Nj":"NJ","nj":"nj","Ș":"S","ș":"s","Ț":"T","ț":"t","ə":"e","˚":"o","Ά":"A","Έ":"E","Ή":"H","Ί":"I","Ό":"O","Ύ":"Y","Ώ":"W","ΐ":"i","Α":"A","Β":"B","Γ":"G","Δ":"D","Ε":"E","Ζ":"Z","Η":"H","Θ":"8","Ι":"I","Κ":"K","Λ":"L","Μ":"M","Ν":"N","Ξ":"3","Ο":"O","Π":"P","Ρ":"R","Σ":"S","Τ":"T","Î¥":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ϊ":"I","Ϋ":"Y","ά":"a","έ":"e","ή":"h","ί":"i","ΰ":"y","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","π":"p","ρ":"r","ς":"s","σ":"s","τ":"t","υ":"y","φ":"f","χ":"x","ψ":"ps","ω":"w","ϊ":"i","ϋ":"y","ό":"o","ύ":"y","ώ":"w","Ё":"Yo","Ђ":"DJ","Є":"Ye","І":"I","Ї":"Yi","Ј":"J","Љ":"LJ","Њ":"NJ","Ћ":"C","Џ":"DZ","А":"A","Б":"B","В":"V","Г":"G","Д":"D","Е":"E","Ж":"Zh","З":"Z","И":"I","Й":"J","К":"K","Л":"L","М":"M","Н":"N","О":"O","П":"P","Р":"R","С":"S","Т":"T","У":"U","Ф":"F","Ð¥":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Э":"E","Ю":"Yu","Я":"Ya","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","р":"r","с":"s","т":"t","у":"u","ф":"f","х":"h","ц":"c","ч":"ch","ш":"sh","щ":"sh","ъ":"u","ы":"y","ь":"","э":"e","ю":"yu","я":"ya","ё":"yo","ђ":"dj","є":"ye","і":"i","ї":"yi","ј":"j","љ":"lj","њ":"nj","ћ":"c","ѝ":"u","џ":"dz","Ґ":"G","ґ":"g","Ғ":"GH","ғ":"gh","Қ":"KH","қ":"kh","Ò¢":"NG","Ò£":"ng","Ò®":"UE","Ò¯":"ue","Ò°":"U","Ò±":"u","Òº":"H","Ò»":"h","Ә":"AE","ә":"ae","Ó¨":"OE","Ó©":"oe","Ô±":"A","Ô²":"B","Ô³":"G","Ô´":"D","Ôµ":"E","Ô¶":"Z","Ô·":"E\\\'","Ô¸":"Y\\\'","Ô¹":"T\\\'","Ôº":"JH","Ô»":"I","Ô¼":"L","Ô½":"X","Ô¾":"C\\\'","Ô¿":"K","Հ":"H","Ձ":"D\\\'","Ղ":"GH","Ճ":"TW","Մ":"M","Յ":"Y","Ն":"N","Շ":"SH","Չ":"CH","Պ":"P","Ջ":"J","Ռ":"R\\\'","Ս":"S","Վ":"V","Տ":"T","Ր":"R","Ց":"C","Փ":"P\\\'","Ք":"Q\\\'","Օ":"O\\\'\\\'","Ֆ":"F","և":"EV","Ø¡":"a","Ø¢":"aa","Ø£":"a","ؤ":"u","Ø¥":"i","ئ":"e","ا":"a","ب":"b","Ø©":"h","ت":"t","Ø«":"th","ج":"j","Ø­":"h","Ø®":"kh","د":"d","ذ":"th","ر":"r","ز":"z","س":"s","Ø´":"sh","ص":"s","ض":"dh","Ø·":"t","ظ":"z","ع":"a","غ":"gh","ف":"f","ق":"q","ك":"k","ل":"l","م":"m","ن":"n","ه":"h","و":"w","ى":"a","ي":"y","ً":"an","ٌ":"on","ٍ":"en","َ":"a","ُ":"u","ِ":"e","ْ":"","Ù ":"0","Ù¡":"1","Ù¢":"2","Ù£":"3","Ù¤":"4","Ù¥":"5","Ù¦":"6","Ù§":"7","Ù¨":"8","Ù©":"9","Ù¾":"p","چ":"ch","ژ":"zh","Ú©":"k","Ú¯":"g","ی":"y","Û°":"0","Û±":"1","Û²":"2","Û³":"3","Û´":"4","Ûµ":"5","Û¶":"6","Û·":"7","Û¸":"8","Û¹":"9","฿":"baht","ა":"a","ბ":"b","გ":"g","დ":"d","ე":"e","ვ":"v","ზ":"z","თ":"t","ი":"i","კ":"k","ლ":"l","მ":"m","ნ":"n","ო":"o","პ":"p","ჟ":"zh","რ":"r","ს":"s","ტ":"t","უ":"u","ფ":"f","ქ":"k","ღ":"gh","ყ":"q","შ":"sh","ჩ":"ch","ც":"ts","ძ":"dz","წ":"ts","ჭ":"ch","ხ":"kh","ჯ":"j","ჰ":"h","á¹¢":"S","á¹£":"s","Ẁ":"W","ẁ":"w","Ẃ":"W","ẃ":"w","Ẅ":"W","ẅ":"w","ẞ":"SS","Ạ":"A","ạ":"a","Ả":"A","ả":"a","Ấ":"A","ấ":"a","Ầ":"A","ầ":"a","Ẩ":"A","ẩ":"a","Ẫ":"A","ẫ":"a","Ậ":"A","ậ":"a","Ắ":"A","ắ":"a","Ằ":"A","ằ":"a","Ẳ":"A","ẳ":"a","Ẵ":"A","ẵ":"a","Ặ":"A","ặ":"a","Ẹ":"E","ẹ":"e","Ẻ":"E","ẻ":"e","Ẽ":"E","ẽ":"e","Ế":"E","ế":"e","Ề":"E","ề":"e","Ể":"E","ể":"e","Ễ":"E","ễ":"e","Ệ":"E","ệ":"e","Ỉ":"I","ỉ":"i","Ị":"I","ị":"i","Ọ":"O","ọ":"o","Ỏ":"O","ỏ":"o","Ố":"O","ố":"o","Ồ":"O","ồ":"o","Ổ":"O","ổ":"o","Ỗ":"O","ỗ":"o","Ộ":"O","ộ":"o","Ớ":"O","ớ":"o","Ờ":"O","ờ":"o","Ở":"O","ở":"o","á» ":"O","ỡ":"o","Ợ":"O","ợ":"o","Ụ":"U","ụ":"u","Ủ":"U","á»§":"u","Ứ":"U","ứ":"u","Ừ":"U","ừ":"u","Ử":"U","á»­":"u","á»®":"U","ữ":"u","á»°":"U","á»±":"u","Ỳ":"Y","ỳ":"y","á»´":"Y","ỵ":"y","á»¶":"Y","á»·":"y","Ỹ":"Y","ỹ":"y","–":"-","‘":"\\\'","’":"\\\'","“":"\\\\\\"","”":"\\\\\\"","„":"\\\\\\"","†":"+","•":"*","…":"...","₠":"ecu","₢":"cruzeiro","₣":"french franc","₤":"lira","₥":"mill","₦":"naira","â
1‚§":"peseta","₨":"rupee","₩":"won","₪":"new shequel","₫":"dong","€":"euro","₭":"kip","₮":"tugrik","₯":"drachma","₰":"penny","₱":"peso","₲":"guarani","₳":"austral","₴":"hryvnia","₵":"cedi","₸":"kazakhstani tenge","₹":"indian rupee","₺":"turkish lira","₽":"russian ruble","₿":"bitcoin","℠":"sm","™":"tm","∂":"d","∆":"delta","∑":"sum","∞":"infinity","♥":"love","元":"yuan","円":"yen","ï·¼":"rial","ﻵ":"laa","ï»·":"laa","ﻹ":"lai","ï»»":"la"}\')\n  var locales = JSON.parse(\'{"bg":{"Й":"Y","Ц":"Ts","Щ":"Sht","Ъ":"A","Ь":"Y","й":"y","ц":"ts","щ":"sht","ъ":"a","ь":"y"},"de":{"Ä":"AE","ä":"ae","Ö":"OE","ö":"oe","Ü":"UE","ü":"ue","ß":"ss","%":"prozent","&":"und","|":"oder","∑":"summe","∞":"unendlich","♥":"liebe"},"es":{"%":"por ciento","&":"y","<":"menor que",">":"mayor que","|":"o","¢":"centavos","£":"libras","¤":"moneda","₣":"francos","∑":"suma","∞":"infinito","♥":"amor"},"fr":{"%":"pourcent","&":"et","<":"plus petit",">":"plus grand","|":"ou","¢":"centime","£":"livre","¤":"devise","₣":"franc","∑":"somme","∞":"infini","♥":"amour"},"pt":{"%":"porcento","&":"e","<":"menor",">":"maior","|":"ou","¢":"centavo","∑":"soma","£":"libra","∞":"infinito","♥":"amor"},"uk":{"И":"Y","и":"y","Й":"Y","й":"y","Ц":"Ts","ц":"ts","Ð¥":"Kh","х":"kh","Щ":"Shch","щ":"shch","Г":"H","г":"h"},"vi":{"Đ":"D","đ":"d"},"da":{"Ø":"OE","ø":"oe","Å":"AA","Ã¥":"aa","%":"procent","&":"og","|":"eller","$":"dollar","<":"mindre end",">":"større end"},"nb":{"&":"og","Å":"AA","Æ":"AE","Ø":"OE","Ã¥":"aa","æ":"ae","ø":"oe"},"it":{"&":"e"},"nl":{"&":"en"},"sv":{"&":"och","Å":"AA","Ä":"AE","Ö":"OE","Ã¥":"aa","ä":"ae","ö":"oe"}}\')\n\n  function replace (string, options) {\n    if (typeof string !== \'string\') {\n      throw new Error(\'slugify: string argument expected\')\n    }\n\n    options = (typeof options === \'string\')\n      ? {replacement: options}\n      : options || {}\n\n    var locale = locales[options.locale] || {}\n\n    var replacement = options.replacement === undefined ? \'-\' : options.replacement\n\n    var trim = options.trim === undefined ? true : options.trim\n\n    var slug = string.normalize().split(\'\')\n      // replace characters based on charMap\n      .reduce(function (result, ch) {\n        var appendChar = locale[ch];\n        if (appendChar === undefined) appendChar = charMap[ch];\n        if (appendChar === undefined) appendChar = ch;\n        if (appendChar === replacement) appendChar = \' \';\n        return result + appendChar\n          // remove not allowed characters\n          .replace(options.remove || /[^\\w\\s$*_+~.()\'"!\\-:@]+/g, \'\')\n      }, \'\');\n\n    if (options.strict) {\n      slug = slug.replace(/[^A-Za-z0-9\\s]/g, \'\');\n    }\n\n    if (trim) {\n      slug = slug.trim()\n    }\n\n    // Replace spaces with replacement character, treating multiple consecutive\n    // spaces as a single space.\n    slug = slug.replace(/\\s+/g, replacement);\n\n    if (options.lower) {\n      slug = slug.toLowerCase()\n    }\n\n    return slug\n  }\n\n  replace.extend = function (customMap) {\n    Object.assign(charMap, customMap)\n  }\n\n  return replace\n}))\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzA0LmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3NsdWdpZnkvc2x1Z2lmeS5qcz8zNjY2Il0sInNvdXJjZXNDb250ZW50IjpbIlxuOyhmdW5jdGlvbiAobmFtZSwgcm9vdCwgZmFjdG9yeSkge1xuICBpZiAodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KClcbiAgICBtb2R1bGUuZXhwb3J0c1snZGVmYXVsdCddID0gZmFjdG9yeSgpXG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgZGVmaW5lKGZhY3RvcnkpXG4gIH1cbiAgZWxzZSB7XG4gICAgcm9vdFtuYW1lXSA9IGZhY3RvcnkoKVxuICB9XG59KCdzbHVnaWZ5JywgdGhpcywgZnVuY3Rpb24gKCkge1xuICB2YXIgY2hhck1hcCA9IEpTT04ucGFyc2UoJ3tcIiRcIjpcImRvbGxhclwiLFwiJVwiOlwicGVyY2VudFwiLFwiJlwiOlwiYW5kXCIsXCI8XCI6XCJsZXNzXCIsXCI+XCI6XCJncmVhdGVyXCIsXCJ8XCI6XCJvclwiLFwiwqJcIjpcImNlbnRcIixcIsKjXCI6XCJwb3VuZFwiLFwiwqRcIjpcImN1cnJlbmN5XCIsXCLCpVwiOlwieWVuXCIsXCLCqVwiOlwiKGMpXCIsXCLCqlwiOlwiYVwiLFwiwq5cIjpcIihyKVwiLFwiwrpcIjpcIm9cIixcIsOAXCI6XCJBXCIsXCLDgVwiOlwiQVwiLFwiw4JcIjpcIkFcIixcIsODXCI6XCJBXCIsXCLDhFwiOlwiQVwiLFwiw4VcIjpcIkFcIixcIsOGXCI6XCJBRVwiLFwiw4dcIjpcIkNcIixcIsOIXCI6XCJFXCIsXCLDiVwiOlwiRVwiLFwiw4pcIjpcIkVcIixcIsOLXCI6XCJFXCIsXCLDjFwiOlwiSVwiLFwiw41cIjpcIklcIixcIsOOXCI6XCJJXCIsXCLDj1wiOlwiSVwiLFwiw5BcIjpcIkRcIixcIsORXCI6XCJOXCIsXCLDklwiOlwiT1wiLFwiw5NcIjpcIk9cIixcIsOUXCI6XCJPXCIsXCLDlVwiOlwiT1wiLFwiw5ZcIjpcIk9cIixcIsOYXCI6XCJPXCIsXCLDmVwiOlwiVVwiLFwiw5pcIjpcIlVcIixcIsObXCI6XCJVXCIsXCLDnFwiOlwiVVwiLFwiw51cIjpcIllcIixcIsOeXCI6XCJUSFwiLFwiw59cIjpcInNzXCIsXCLDoFwiOlwiYVwiLFwiw6FcIjpcImFcIixcIsOiXCI6XCJhXCIsXCLDo1wiOlwiYVwiLFwiw6RcIjpcImFcIixcIsOlXCI6XCJhXCIsXCLDplwiOlwiYWVcIixcIsOnXCI6XCJjXCIsXCLDqFwiOlwiZVwiLFwiw6lcIjpcImVcIixcIsOqXCI6XCJlXCIsXCLDq1wiOlwiZVwiLFwiw6xcIjpcImlcIixcIsOtXCI6XCJpXCIsXCLDrlwiOlwiaVwiLFwiw69cIjpcImlcIixcIsOwXCI6XCJkXCIsXCLDsVwiOlwiblwiLFwiw7JcIjpcIm9cIixcIsOzXCI6XCJvXCIsXCLDtFwiOlwib1wiLFwiw7VcIjpcIm9cIixcIsO2XCI6XCJvXCIsXCLDuFwiOlwib1wiLFwiw7lcIjpcInVcIixcIsO6XCI6XCJ1XCIsXCLDu1wiOlwidVwiLFwiw7xcIjpcInVcIixcIsO9XCI6XCJ5XCIsXCLDvlwiOlwidGhcIixcIsO/XCI6XCJ5XCIsXCLEgFwiOlwiQVwiLFwixIFcIjpcImFcIixcIsSCXCI6XCJBXCIsXCLEg1wiOlwiYVwiLFwixIRcIjpcIkFcIixcIsSFXCI6XCJhXCIsXCLEhlwiOlwiQ1wiLFwixIdcIjpcImNcIixcIsSMXCI6XCJDXCIsXCLEjVwiOlwiY1wiLFwixI5cIjpcIkRcIixcIsSPXCI6XCJkXCIsXCLEkFwiOlwiREpcIixcIsSRXCI6XCJkalwiLFwixJJcIjpcIkVcIixcIsSTXCI6XCJlXCIsXCLEllwiOlwiRVwiLFwixJdcIjpcImVcIixcIsSYXCI6XCJlXCIsXCLEmVwiOlwiZVwiLFwixJpcIjpcIkVcIixcIsSbXCI6XCJlXCIsXCLEnlwiOlwiR1wiLFwixJ9cIjpcImdcIixcIsSiXCI6XCJHXCIsXCLEo1wiOlwiZ1wiLFwixKhcIjpcIklcIixcIsSpXCI6XCJpXCIsXCLEqlwiOlwiaVwiLFwixKtcIjpcImlcIixcIsSuXCI6XCJJXCIsXCLEr1wiOlwiaVwiLFwixLBcIjpcIklcIixcIsSxXCI6XCJpXCIsXCLEtlwiOlwia1wiLFwixLdcIjpcImtcIixcIsS7XCI6XCJMXCIsXCLEvFwiOlwibFwiLFwixL1cIjpcIkxcIixcIsS+XCI6XCJsXCIsXCLFgVwiOlwiTFwiLFwixYJcIjpcImxcIixcIsWDXCI6XCJOXCIsXCLFhFwiOlwiblwiLFwixYVcIjpcIk5cIixcIsWGXCI6XCJuXCIsXCLFh1wiOlwiTlwiLFwixYhcIjpcIm5cIixcIsWMXCI6XCJPXCIsXCLFjVwiOlwib1wiLFwixZBcIjpcIk9cIixcIsWRXCI6XCJvXCIsXCLFklwiOlwiT0VcIixcIsWTXCI6XCJvZVwiLFwixZRcIjpcIlJcIixcIsWVXCI6XCJyXCIsXCLFmFwiOlwiUlwiLFwixZlcIjpcInJcIixcIsWaXCI6XCJTXCIsXCLFm1wiOlwic1wiLFwixZ5cIjpcIlNcIixcIsWfXCI6XCJzXCIsXCLFoFwiOlwiU1wiLFwixaFcIjpcInNcIixcIsWiXCI6XCJUXCIsXCLFo1wiOlwidFwiLFwixaRcIjpcIlRcIixcIsWlXCI6XCJ0XCIsXCLFqFwiOlwiVVwiLFwixalcIjpcInVcIixcIsWqXCI6XCJ1XCIsXCLFq1wiOlwidVwiLFwixa5cIjpcIlVcIixcIsWvXCI6XCJ1XCIsXCLFsFwiOlwiVVwiLFwixbFcIjpcInVcIixcIsWyXCI6XCJVXCIsXCLFs1wiOlwidVwiLFwixbRcIjpcIldcIixcIsW1XCI6XCJ3XCIsXCLFtlwiOlwiWVwiLFwixbdcIjpcInlcIixcIsW4XCI6XCJZXCIsXCLFuVwiOlwiWlwiLFwixbpcIjpcInpcIixcIsW7XCI6XCJaXCIsXCLFvFwiOlwielwiLFwixb
11cIjpcIlpcIixcIsW+XCI6XCJ6XCIsXCLGj1wiOlwiRVwiLFwixpJcIjpcImZcIixcIsagXCI6XCJPXCIsXCLGoVwiOlwib1wiLFwixq9cIjpcIlVcIixcIsawXCI6XCJ1XCIsXCLHiFwiOlwiTEpcIixcIseJXCI6XCJsalwiLFwix4tcIjpcIk5KXCIsXCLHjFwiOlwibmpcIixcIsiYXCI6XCJTXCIsXCLImVwiOlwic1wiLFwiyJpcIjpcIlRcIixcIsibXCI6XCJ0XCIsXCLJmVwiOlwiZVwiLFwiy5pcIjpcIm9cIixcIs6GXCI6XCJBXCIsXCLOiFwiOlwiRVwiLFwizolcIjpcIkhcIixcIs6KXCI6XCJJXCIsXCLOjFwiOlwiT1wiLFwizo5cIjpcIllcIixcIs6PXCI6XCJXXCIsXCLOkFwiOlwiaVwiLFwizpFcIjpcIkFcIixcIs6SXCI6XCJCXCIsXCLOk1wiOlwiR1wiLFwizpRcIjpcIkRcIixcIs6VXCI6XCJFXCIsXCLOllwiOlwiWlwiLFwizpdcIjpcIkhcIixcIs6YXCI6XCI4XCIsXCLOmVwiOlwiSVwiLFwizppcIjpcIktcIixcIs6bXCI6XCJMXCIsXCLOnFwiOlwiTVwiLFwizp1cIjpcIk5cIixcIs6eXCI6XCIzXCIsXCLOn1wiOlwiT1wiLFwizqBcIjpcIlBcIixcIs6hXCI6XCJSXCIsXCLOo1wiOlwiU1wiLFwizqRcIjpcIlRcIixcIs6lXCI6XCJZXCIsXCLOplwiOlwiRlwiLFwizqdcIjpcIlhcIixcIs6oXCI6XCJQU1wiLFwizqlcIjpcIldcIixcIs6qXCI6XCJJXCIsXCLOq1wiOlwiWVwiLFwizqxcIjpcImFcIixcIs6tXCI6XCJlXCIsXCLOrlwiOlwiaFwiLFwizq9cIjpcImlcIixcIs6wXCI6XCJ5XCIsXCLOsVwiOlwiYVwiLFwizrJcIjpcImJcIixcIs6zXCI6XCJnXCIsXCLOtFwiOlwiZFwiLFwizrVcIjpcImVcIixcIs62XCI6XCJ6XCIsXCLOt1wiOlwiaFwiLFwizrhcIjpcIjhcIixcIs65XCI6XCJpXCIsXCLOulwiOlwia1wiLFwizrtcIjpcImxcIixcIs68XCI6XCJtXCIsXCLOvVwiOlwiblwiLFwizr5cIjpcIjNcIixcIs6/XCI6XCJvXCIsXCLPgFwiOlwicFwiLFwiz4FcIjpcInJcIixcIs+CXCI6XCJzXCIsXCLPg1wiOlwic1wiLFwiz4RcIjpcInRcIixcIs+FXCI6XCJ5XCIsXCLPhlwiOlwiZlwiLFwiz4dcIjpcInhcIixcIs+IXCI6XCJwc1wiLFwiz4lcIjpcIndcIixcIs+KXCI6XCJpXCIsXCLPi1wiOlwieVwiLFwiz4xcIjpcIm9cIixcIs+NXCI6XCJ5XCIsXCLPjlwiOlwid1wiLFwi0IFcIjpcIllvXCIsXCLQglwiOlwiREpcIixcItCEXCI6XCJZZVwiLFwi0IZcIjpcIklcIixcItCHXCI6XCJZaVwiLFwi0IhcIjpcIkpcIixcItCJXCI6XCJMSlwiLFwi0IpcIjpcIk5KXCIsXCLQi1wiOlwiQ1wiLFwi0I9cIjpcIkRaXCIsXCLQkFwiOlwiQVwiLFwi0JFcIjpcIkJcIixcItCSXCI6XCJWXCIsXCLQk1wiOlwiR1wiLFwi0JRcIjpcIkRcIixcItCVXCI6XCJFXCIsXCLQllwiOlwiWmhcIixcItCXXCI6XCJaXCIsXCLQmFwiOlwiSVwiLFwi0JlcIjpcIkpcIixcItCaXCI6XCJLXCIsXCLQm1wiOlwiTFwiLFwi0JxcIjpcIk1cIixcItCdXCI6XCJOXCIsXCLQnlwiOlwiT1wiLFwi0J9cIjpcIlBcIixcItCgXCI6XCJSXCIsXCLQoVwiOlwiU1wiLFwi0KJcIjpcIlRcIixcItCjXCI6XCJVXCIsXCLQpFwiOlwiRlwiLFwi0KVcIjpcIkhcIixcItCmXCI6XCJDXCIsXCLQp1wiOlwiQ2hcIixcItCoXCI6XCJTaFwiLFwi0KlcIjpcIlNoXCIsXCLQqlwiOlwiVVwiLFwi0KtcIjpcIllcIixcItCsXCI6XCJcIixcItCtXCI6XCJFXCIsXCLQrlwiOlwiWXVcIixcItCvXCI6XCJZYVwiLFwi0LBcIjpcImFcIixcItCxXCI6XCJiXCIsXCLQslwiOlwidlwiLFwi0LNcIjpcImdcIixcItC0XCI6XCJkXCIsXCLQtVwiOlwiZVwiLFwi0LZcIjpcInpoXCIsXCLQt1wiOlwielwiLFwi0LhcIjpcImlcIixcItC5XCI6XCJqXCIsXCLQulwiOlwia1wiLFwi0LtcIjpcImxcIixcItC8XCI6XCJtXCIsXCLQvVwiOlwiblwiLFwi0L5cIjpcIm9cIixcItC/XCI6XCJwXCIsXCLRgFwiOlwiclwiLFwi0YFcIjpcInNcIixcItGCXCI6XCJ0XCIsXCLRg1wiOlwidVwiLFwi0YRcIjpcImZcIixcItGFXCI6XCJoXCIsXCLRhlwiOlwiY1wiLFwi0YdcIjpcImNoXCIsXCLRiFwiOlwic2hcIixcItGJXCI6XCJzaFwiLFwi0YpcIjpcInVcIixcItGLXCI6XCJ5XCIsXCLRjFwiOlwiXCIsXCLRjVwiOlwiZVwiLFwi0Y5cIjpcInl1XCIsXCLRj1wiOlwieWFcIixcItGRXCI6XCJ5b1wiLFwi0ZJcIjpcImRqXCIsXCLRlFwiOlwieWVcIixcItGWXCI6XCJpXCIsXCLRl1wiOlwieWlcIixcItGYXCI6XCJqXCIsXCLRmVwiOlwibGpcIixcItGaXCI6XCJualwiLFwi0ZtcIjpcImNcIixcItGdXCI6XCJ1XCIsXCLRn1wiOlwiZHpcIixcItKQXCI6XCJHXCIsXCLSkVwiOlwiZ1wiLFwi0pJcIjpcIkdIXCIsXCLSk1wiOlwiZ2hcIixcItKaXCI6XCJLSFwiLFwi0ptcIjpcImtoXCIsXCLSolwiOlwiTkdcIixcItKjXCI6XCJuZ1wiLFwi0q5cIjpcIlVFXCIsXCLSr1wiOlwidWVcIixcItKwXCI6XCJVXCIsXCLSsVwiOlwidVwiLFwi0rpcIjpcIkhcIixcItK7XCI6XCJoXCIsXCLTmFwiOlwiQUVcIixcItOZXCI6XCJhZVwiLFwi06hcIjpcIk9FXCIsXCLTqVwiOlwib2VcIixcItSxXCI6XCJBXCIsXCLUslwiOlwiQlwiLFwi1LNcIjpcIkdcIixcItS0XCI6XCJEXCIsXCLUtVwiOlwiRVwiLFwi1LZcIjpcIlpcIixcItS3XCI6XCJFXFwnXCIsXCLUuFwiOlwiWVxcJ1wiLFwi1LlcIjpcIlRcXCdcIixcItS6XCI6XCJKSFwiLFwi1LtcIjpcIklcIixcItS8XCI6XCJMXCIsXCLUvVwiOlwiWFwiLFwi1L5cIjpcIkNcXCdcIixcItS/XCI6XCJLXCIsXCLVgFwiOlwiSFwiLFwi1YFcIjpcIkRcXCdcIixcItWCXCI6XCJHSFwiLFwi1YNcIjpcIlRXXCIsXCLVhFwiOlwiTVwiLFwi1YVcIjpcIllcIixcItWGXCI6XCJOXCIsXCLVh1wiOlwiU0hcIixcItWJXCI6XCJDSFwiLFwi1YpcIjpcIlBcIixcItWLXCI6XCJKXCIsXCLVjFwiOlwiUlxcJ1wiLFwi1Y1cIjpcIlNcIixcItWOXCI6XCJWXCIsXCLVj1wiOlwiVFwiLFwi1ZBcIjpcIlJcIixcItWRXCI6XCJDXCIsXCLVk1wiOlwiUFxcJ1wiLFwi1ZRcIjpcIlFcXCdcIixcItWVXCI6XCJPXFwnXFwnXCIsXCLVllwiOlwiRlwiLFwi1odcIjpcIkVWXCIsXCLYoVwiOlwiYVwiLFwi2KJcIjpcImFhXCIsXCLYo1wiOlwiYVwiLFwi2KRcIjpcInVcIixcItilXCI6XCJpXCIsXCLYplwiOlwiZVwiLFwi2KdcIjpcImFcIixcItioXCI6XCJiXCIsXCLYqVwiOlwiaFwiLFwi2KpcIjpcInRcIixcItirXCI6XCJ0aFwiLFwi2KxcIjpcImpcIixcItitXCI6XCJoXCIsXCLYrlwiOlwia2hcIixcItivXCI6XCJkXCIsXCLYsFwiOlwidGhcIixcItixXCI6XCJyXCIsXCLYslwiOlwielwiLFwi2LNcIjpcInNcIixcIti0XCI6XCJzaFwiLFwi2LVcIjpcInNcIixcIti2XCI6XCJkaFwiLFwi2LdcIjpcInRcIixcIti4XCI6XCJ6XCIsXCLYuVwiOlwiYVwiLFwi2LpcIjpcImdoXCIsXCLZgVwiOlwiZlwiLFwi2YJcIjpcInFcIixcItmDXCI6XCJrXCIsXCLZhFwiOlwibFwiLFwi2YVcIjpcIm1cIixcItmGXCI6XCJuXCIsXCLZh1wiOlwiaFwiLFwi2YhcIjpcIndcIixcItmJXCI6XCJhXCIsXCLZilwiOlwieVwiLFwi2YtcIjpcImFuXCIsXCLZj
1FwiOlwib25cIixcItmNXCI6XCJlblwiLFwi2Y5cIjpcImFcIixcItmPXCI6XCJ1XCIsXCLZkFwiOlwiZVwiLFwi2ZJcIjpcIlwiLFwi2aBcIjpcIjBcIixcItmhXCI6XCIxXCIsXCLZolwiOlwiMlwiLFwi2aNcIjpcIjNcIixcItmkXCI6XCI0XCIsXCLZpVwiOlwiNVwiLFwi2aZcIjpcIjZcIixcItmnXCI6XCI3XCIsXCLZqFwiOlwiOFwiLFwi2alcIjpcIjlcIixcItm+XCI6XCJwXCIsXCLahlwiOlwiY2hcIixcItqYXCI6XCJ6aFwiLFwi2qlcIjpcImtcIixcItqvXCI6XCJnXCIsXCLbjFwiOlwieVwiLFwi27BcIjpcIjBcIixcItuxXCI6XCIxXCIsXCLbslwiOlwiMlwiLFwi27NcIjpcIjNcIixcItu0XCI6XCI0XCIsXCLbtVwiOlwiNVwiLFwi27ZcIjpcIjZcIixcItu3XCI6XCI3XCIsXCLbuFwiOlwiOFwiLFwi27lcIjpcIjlcIixcIuC4v1wiOlwiYmFodFwiLFwi4YOQXCI6XCJhXCIsXCLhg5FcIjpcImJcIixcIuGDklwiOlwiZ1wiLFwi4YOTXCI6XCJkXCIsXCLhg5RcIjpcImVcIixcIuGDlVwiOlwidlwiLFwi4YOWXCI6XCJ6XCIsXCLhg5dcIjpcInRcIixcIuGDmFwiOlwiaVwiLFwi4YOZXCI6XCJrXCIsXCLhg5pcIjpcImxcIixcIuGDm1wiOlwibVwiLFwi4YOcXCI6XCJuXCIsXCLhg51cIjpcIm9cIixcIuGDnlwiOlwicFwiLFwi4YOfXCI6XCJ6aFwiLFwi4YOgXCI6XCJyXCIsXCLhg6FcIjpcInNcIixcIuGDolwiOlwidFwiLFwi4YOjXCI6XCJ1XCIsXCLhg6RcIjpcImZcIixcIuGDpVwiOlwia1wiLFwi4YOmXCI6XCJnaFwiLFwi4YOnXCI6XCJxXCIsXCLhg6hcIjpcInNoXCIsXCLhg6lcIjpcImNoXCIsXCLhg6pcIjpcInRzXCIsXCLhg6tcIjpcImR6XCIsXCLhg6xcIjpcInRzXCIsXCLhg61cIjpcImNoXCIsXCLhg65cIjpcImtoXCIsXCLhg69cIjpcImpcIixcIuGDsFwiOlwiaFwiLFwi4bmiXCI6XCJTXCIsXCLhuaNcIjpcInNcIixcIuG6gFwiOlwiV1wiLFwi4bqBXCI6XCJ3XCIsXCLhuoJcIjpcIldcIixcIuG6g1wiOlwid1wiLFwi4bqEXCI6XCJXXCIsXCLhuoVcIjpcIndcIixcIuG6nlwiOlwiU1NcIixcIuG6oFwiOlwiQVwiLFwi4bqhXCI6XCJhXCIsXCLhuqJcIjpcIkFcIixcIuG6o1wiOlwiYVwiLFwi4bqkXCI6XCJBXCIsXCLhuqVcIjpcImFcIixcIuG6plwiOlwiQVwiLFwi4bqnXCI6XCJhXCIsXCLhuqhcIjpcIkFcIixcIuG6qVwiOlwiYVwiLFwi4bqqXCI6XCJBXCIsXCLhuqtcIjpcImFcIixcIuG6rFwiOlwiQVwiLFwi4bqtXCI6XCJhXCIsXCLhuq5cIjpcIkFcIixcIuG6r1wiOlwiYVwiLFwi4bqwXCI6XCJBXCIsXCLhurFcIjpcImFcIixcIuG6slwiOlwiQVwiLFwi4bqzXCI6XCJhXCIsXCLhurRcIjpcIkFcIixcIuG6tVwiOlwiYVwiLFwi4bq2XCI6XCJBXCIsXCLhurdcIjpcImFcIixcIuG6uFwiOlwiRVwiLFwi4bq5XCI6XCJlXCIsXCLhurpcIjpcIkVcIixcIuG6u1wiOlwiZVwiLFwi4bq8XCI6XCJFXCIsXCLhur1cIjpcImVcIixcIuG6vlwiOlwiRVwiLFwi4bq/XCI6XCJlXCIsXCLhu4BcIjpcIkVcIixcIuG7gVwiOlwiZVwiLFwi4buCXCI6XCJFXCIsXCLhu4NcIjpcImVcIixcIuG7hFwiOlwiRVwiLFwi4buFXCI6XCJlXCIsXCLhu4ZcIjpcIkVcIixcIuG7h1wiOlwiZVwiLFwi4buIXCI6XCJJXCIsXCLhu4lcIjpcImlcIixcIuG7ilwiOlwiSVwiLFwi4buLXCI6XCJpXCIsXCLhu4xcIjpcIk9cIixcIuG7jVwiOlwib1wiLFwi4buOXCI6XCJPXCIsXCLhu49cIjpcIm9cIixcIuG7kFwiOlwiT1wiLFwi4buRXCI6XCJvXCIsXCLhu5JcIjpcIk9cIixcIuG7k1wiOlwib1wiLFwi4buUXCI6XCJPXCIsXCLhu5VcIjpcIm9cIixcIuG7llwiOlwiT1wiLFwi4buXXCI6XCJvXCIsXCLhu5hcIjpcIk9cIixcIuG7mVwiOlwib1wiLFwi4buaXCI6XCJPXCIsXCLhu5tcIjpcIm9cIixcIuG7nFwiOlwiT1wiLFwi4budXCI6XCJvXCIsXCLhu55cIjpcIk9cIixcIuG7n1wiOlwib1wiLFwi4bugXCI6XCJPXCIsXCLhu6FcIjpcIm9cIixcIuG7olwiOlwiT1wiLFwi4bujXCI6XCJvXCIsXCLhu6RcIjpcIlVcIixcIuG7pVwiOlwidVwiLFwi4bumXCI6XCJVXCIsXCLhu6dcIjpcInVcIixcIuG7qFwiOlwiVVwiLFwi4bupXCI6XCJ1XCIsXCLhu6pcIjpcIlVcIixcIuG7q1wiOlwidVwiLFwi4busXCI6XCJVXCIsXCLhu61cIjpcInVcIixcIuG7rlwiOlwiVVwiLFwi4buvXCI6XCJ1XCIsXCLhu7BcIjpcIlVcIixcIuG7sVwiOlwidVwiLFwi4buyXCI6XCJZXCIsXCLhu7NcIjpcInlcIixcIuG7tFwiOlwiWVwiLFwi4bu1XCI6XCJ5XCIsXCLhu7ZcIjpcIllcIixcIuG7t1wiOlwieVwiLFwi4bu4XCI6XCJZXCIsXCLhu7lcIjpcInlcIixcIuKAk1wiOlwiLVwiLFwi4oCYXCI6XCJcXCdcIixcIuKAmVwiOlwiXFwnXCIsXCLigJxcIjpcIlxcXFxcXFwiXCIsXCLigJ1cIjpcIlxcXFxcXFwiXCIsXCLigJ5cIjpcIlxcXFxcXFwiXCIsXCLigKBcIjpcIitcIixcIuKAolwiOlwiKlwiLFwi4oCmXCI6XCIuLi5cIixcIuKCoFwiOlwiZWN1XCIsXCLigqJcIjpcImNydXplaXJvXCIsXCLigqNcIjpcImZyZW5jaCBmcmFuY1wiLFwi4oKkXCI6XCJsaXJhXCIsXCLigqVcIjpcIm1pbGxcIixcIuKCplwiOlwibmFpcmFcIixcIuKCp1wiOlwicGVzZXRhXCIsXCLigqhcIjpcInJ1cGVlXCIsXCLigqlcIjpcIndvblwiLFwi4oKqXCI6XCJuZXcgc2hlcXVlbFwiLFwi4oKrXCI6XCJkb25nXCIsXCLigqxcIjpcImV1cm9cIixcIuKCrVwiOlwia2lwXCIsXCLigq5cIjpcInR1Z3Jpa1wiLFwi4oKvXCI6XCJkcmFjaG1hXCIsXCLigrBcIjpcInBlbm55XCIsXCLigrFcIjpcInBlc29cIixcIuKCslwiOlwiZ3VhcmFuaVwiLFwi4oKzXCI6XCJhdXN0cmFsXCIsXCLigrRcIjpcImhyeXZuaWFcIixcIuKCtVwiOlwiY2VkaVwiLFwi4oK4XCI6XCJrYXpha2hzdGFuaSB0ZW5nZVwiLFwi4oK5XCI6XCJpbmRpYW4gcnVwZWVcIixcIuKCulwiOlwidHVya2lzaCBsaXJhXCIsXCLigr1cIjpcInJ1c3NpYW4gcnVibGVcIixcIuKCv1wiOlwiYml0Y29pblwiLFwi4oSgXCI6XCJzbVwiLFwi4oSiXCI6XCJ0bVwiLFwi4oiCXCI6XCJkXCIsXCLiiIZcIjpcImRlbHRhXCIsXCLiiJFcIjpcInN1bVwiLFwi4oieXCI6XCJpbmZpbml0eVwiLFwi4pmlXCI6XCJsb3ZlXCIsXCLlhYNcIjpcInl1YW5cIixcIuWGhlwiOlwieWVuXCIsXCLvt7xcIjpcInJpYWxcIixcIu+7tVwiOlwibGFhXCIsXCLvu7dcIjpcImxhYVwiLFwi77u5XCI6XCJsYWlcIixcIu+7u1wiOlwibGFcIn0nKVxuICB2YXIgbG9jYWxlcyA9IEpTT04ucGFyc2UoJ3tcImJnXCI6e1wi0JlcIjpcIllcIixcItCmXCI6XCJUc1wiLFwi0KlcIjpcIlNodFwiLFwi0KpcIjpcIkFcIixcItCsXCI6XCJZXCIsXCLQuVwiOlwieVwiLFwi0YZcIjpcInRzXCIsXCLRiVwiOlwic2h0XCIsXCLRilwiOlwiYVwiLFwi0YxcIjpcInlcIn0sXCJkZVwiOntcIsOEXCI6XCJBRVwiLFwiw6RcIjpcImFlXCIsXCLDllwiOlwiT0VcIixcIsO2XCI6XCJvZVwiLFwiw5xcIjpcIlVFXCIsXCLDvFwiOlwidWVcIixcIsOfXCI6XCJzc1wiLFwiJVwiOlwicHJvemVudFwiLFwiJlwiOlwidW5kXCIsXCJ8XCI6XCJvZGVyXCIsXCLiiJFcIjpcInN1bW1lXCIsXCLiiJ5cIjpcInVuZW5kbGljaFwiLFwi4pmlXCI6XCJsaWViZVwifSxcImVzXCI6e1wiJVwiOlwicG9yIGNpZW50b1wiLFwiJlwiOlwieVwiLFwiPFwiOlwibWVub3IgcXVlXCIsXCI+XCI6XCJtYXlvciBxdWVcIixcInxcIjpcIm9cIixcIsKiXCI6XCJjZW50YXZvc1wiLFwiwqNcIjpcImxpYnJhc1wiLFwiwqRcIjpcIm1vbmVkYVwiLFwi4oKjXCI6XCJmcmFuY29zXCIsXCLiiJFcIjpcInN1bWFcIixcIuKInlwiOlwiaW5maW5pdG9cIixcIuKZpVwiOlwiYW1vclwifSxcImZyXCI6e1wiJVwiOlwicG91cmNlbnRcIixcIiZcIjpcImV0XCIsXCI8XCI6XCJwbHVzIHBldGl0XCIsXCI+XCI6XCJwbHVzIGdyYW5kXCIsXCJ8XCI6XCJvdVwiLFwiwqJcIjpcImNlbnRpbWVcIixcIsKjXCI6XCJsaXZyZVwiLFwiwqRcIjpcImRldmlzZVwiLFwi4oKjXCI6XCJmcmFuY1wiLFwi4oiRXCI6XCJzb21tZVwiLFwi4oieXCI6XCJpbmZpbmlcIixcIuKZpVwiOlwiYW1vdXJcIn0sXCJwdFwiOntcIiVcIjpcInBvcmNlbnRvXCIsXCImXCI6XCJlXCIsXCI8XCI6XCJtZW5vclwiLFwiPlwiOlwibWFpb3JcIixcInxcIjpcIm91XCIsXCLColwiOlwiY2VudGF2b1wiLFwi4oiRXCI6XCJzb21hXCIsXCLCo1wiOlwibGlicmFcIixcIuKInlwiOlwiaW5maW5pdG9cIixcIuKZpVwiOlwiYW1vclwifSxcInVrXCI6e1wi0JhcIjpcIllcIixcItC4XCI6XCJ5XCIsXCLQmVwiOlwiWVwiLFwi0LlcIjpcInlcIixcItCmXCI6XCJUc1wiLFwi0YZcIjpcInRzXCIsXCLQpVwiOlwiS2hcIixcItGFXCI6XCJraFwiLFwi0KlcIjpcIlNoY2hcIixcItGJXCI6XCJzaGNoXCIsXCLQk1wiOlwiSFwiLFwi0LNcIjpcImhcIn0sXCJ2aVwiOntcIsSQXCI6XCJEXCIsXCLEkVwiOlwiZFwifSxcImRhXCI6e1wiw5hcIjpcIk9FXCIsXCLDuFwiOlwib2VcIixcIsOFXCI6XCJBQVwiLFwiw6VcIjpcImFhXCIsXCIlXCI6XCJwcm9jZW50XCIsXCImXCI6XCJvZ1wiLFwifFwiOlwiZWxsZXJcIixcIiRcIjpcImRvbGxhclwiLFwiPFwiOlwibWluZHJlIGVuZFwiLFwiPlwiOlwic3TDuHJyZSBlbmRcIn0sXCJuYlwiOntcIiZcIjpcIm9nXCIsXCLDhVwiOlwiQUFcIixcIsOGXCI6XCJBRVwiLFwiw5hcIjpcIk9FXCIsXCLDpVwiOlwiYWFcIixcIsOmXCI6XCJhZVwiLFwiw7hcIjpcIm9lXCJ9LFwiaXRcIjp7XCImXCI6XCJlXCJ9LFwibmxcIjp7XCImXCI6XCJlblwifSxcInN2XCI6e1wiJlwiOlwib2NoXCIsXCLDhVwiOlwiQUFcIixcIsOEXCI6XCJBRVwiLFwiw5ZcIjpcIk9FXCIsXCLDpVwiOlwiYWFcIixcIsOkXCI6XCJhZVwiLFwiw7ZcIjpcIm9lXCJ9fScpXG5cbiAgZnVuY3Rpb24gcmVwbGFjZSAoc3RyaW5nLCBvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NsdWdpZnk6IHN0cmluZyBhcmd1bWVudCBleHBlY3RlZCcpXG4gICAgfVxuXG4gICAgb3B0aW9ucyA9ICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpXG4gICAgICA/IHtyZXBsYWNlbWVudDogb3B0aW9uc31cbiAgICAgIDogb3B0aW9ucyB8fCB7fVxuXG4gICAgdmFyIGxvY2FsZSA9IGxvY2FsZXNbb3B0aW9ucy5sb2NhbGVdIHx8IHt9XG5cbiAgICB2YXIgcmVwbGFjZW1lbnQgPSBvcHRpb25zLnJlcGxhY2VtZW50ID09PSB1bmRlZmluZWQgPyAnLScgOiBvcHRpb25zLnJlcGxhY2VtZW50XG5cbiAgICB2YXIgdHJpbSA9IG9wdGlvbnMudHJpbSA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6IG9wdGlvbnMudHJpbVxuXG4gICAgdmFyIHNsdWcgPSBzdHJpbmcubm9ybWFsaXplKCkuc3BsaXQoJycpXG4gICAgICAvLyByZXBsYWNlIGNoYXJhY3RlcnMgYmFzZWQgb24gY2hhck1hcFxuICAgICAgLnJlZHVjZShmdW5jdGlvbiAocmVzdWx0LCBjaCkge1xuICAgICAgICB2Y
1XIgYXBwZW5kQ2hhciA9IGxvY2FsZVtjaF07XG4gICAgICAgIGlmIChhcHBlbmRDaGFyID09PSB1bmRlZmluZWQpIGFwcGVuZENoYXIgPSBjaGFyTWFwW2NoXTtcbiAgICAgICAgaWYgKGFwcGVuZENoYXIgPT09IHVuZGVmaW5lZCkgYXBwZW5kQ2hhciA9IGNoO1xuICAgICAgICBpZiAoYXBwZW5kQ2hhciA9PT0gcmVwbGFjZW1lbnQpIGFwcGVuZENoYXIgPSAnICc7XG4gICAgICAgIHJldHVybiByZXN1bHQgKyBhcHBlbmRDaGFyXG4gICAgICAgICAgLy8gcmVtb3ZlIG5vdCBhbGxvd2VkIGNoYXJhY3RlcnNcbiAgICAgICAgICAucmVwbGFjZShvcHRpb25zLnJlbW92ZSB8fCAvW15cXHdcXHMkKl8rfi4oKSdcIiFcXC06QF0rL2csICcnKVxuICAgICAgfSwgJycpO1xuXG4gICAgaWYgKG9wdGlvbnMuc3RyaWN0KSB7XG4gICAgICBzbHVnID0gc2x1Zy5yZXBsYWNlKC9bXkEtWmEtejAtOVxcc10vZywgJycpO1xuICAgIH1cblxuICAgIGlmICh0cmltKSB7XG4gICAgICBzbHVnID0gc2x1Zy50cmltKClcbiAgICB9XG5cbiAgICAvLyBSZXBsYWNlIHNwYWNlcyB3aXRoIHJlcGxhY2VtZW50IGNoYXJhY3RlciwgdHJlYXRpbmcgbXVsdGlwbGUgY29uc2VjdXRpdmVcbiAgICAvLyBzcGFjZXMgYXMgYSBzaW5nbGUgc3BhY2UuXG4gICAgc2x1ZyA9IHNsdWcucmVwbGFjZSgvXFxzKy9nLCByZXBsYWNlbWVudCk7XG5cbiAgICBpZiAob3B0aW9ucy5sb3dlcikge1xuICAgICAgc2x1ZyA9IHNsdWcudG9Mb3dlckNhc2UoKVxuICAgIH1cblxuICAgIHJldHVybiBzbHVnXG4gIH1cblxuICByZXBsYWNlLmV4dGVuZCA9IGZ1bmN0aW9uIChjdXN0b21NYXApIHtcbiAgICBPYmplY3QuYXNzaWduKGNoYXJNYXAsIGN1c3RvbU1hcClcbiAgfVxuXG4gIHJldHVybiByZXBsYWNlXG59KSlcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///304\n')}},__webpack_module_cache__={};function __webpack_require__(n){var t=__webpack_module_cache__[n];if(void 0!==t)return t.exports;var I=__webpack_module_cache__[n]={exports:{}};return __webpack_modules__[n].call(I.exports,I,I.exports,__webpack_require__),I.exports}__webpack_require__.n=n=>{var t=n&&n.__esModule?()=>n.default:()=>n;return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=(n,t)=>{for(var I in t)__webpack_require__.o(t,I)&&!__webpack_require__.o(n,I)&&Object.defineProperty(n,I,{enumerable:!0,get:t[I]})},__webpack_require__.o=(n,t)=>Object.prototype.hasOwnProperty.call(n,t),__webpack_require__(70),__webpack_require__(156),__webpack_require__(782);var __webpack_exports__=__webpack_require__(17)})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.